]> err.no Git - linux-2.6/commitdiff
Merge branch 'ioat-md-accel-for-linus' of git://lost.foo-projects.org/~dwillia2/git/iop
authorLinus Torvalds <torvalds@woody.linux-foundation.org>
Fri, 13 Jul 2007 17:52:27 +0000 (10:52 -0700)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Fri, 13 Jul 2007 17:52:27 +0000 (10:52 -0700)
* 'ioat-md-accel-for-linus' of git://lost.foo-projects.org/~dwillia2/git/iop: (28 commits)
  ioatdma: add the unisys "i/oat" pci vendor/device id
  ARM: Add drivers/dma to arch/arm/Kconfig
  iop3xx: surface the iop3xx DMA and AAU units to the iop-adma driver
  iop13xx: surface the iop13xx adma units to the iop-adma driver
  dmaengine: driver for the iop32x, iop33x, and iop13xx raid engines
  md: remove raid5 compute_block and compute_parity5
  md: handle_stripe5 - request io processing in raid5_run_ops
  md: handle_stripe5 - add request/completion logic for async expand ops
  md: handle_stripe5 - add request/completion logic for async read ops
  md: handle_stripe5 - add request/completion logic for async check ops
  md: handle_stripe5 - add request/completion logic for async compute ops
  md: handle_stripe5 - add request/completion logic for async write ops
  md: common infrastructure for running operations with raid5_run_ops
  md: raid5_run_ops - run stripe operations outside sh->lock
  raid5: replace custom debug PRINTKs with standard pr_debug
  raid5: refactor handle_stripe5 and handle_stripe6 (v3)
  async_tx: add the async_tx api
  xor: make 'xor_blocks' a library routine for use with async_tx
  dmaengine: make clients responsible for managing channels
  dmaengine: refactor dmaengine around dma_async_tx_descriptor
  ...

2181 files changed:
Documentation/ABI/removed/raw1394_legacy_isochronous [new file with mode: 0644]
Documentation/ABI/testing/sysfs-bus-usb
Documentation/DMA-mapping.txt
Documentation/DocBook/kernel-api.tmpl
Documentation/blackfin/kgdb.txt [new file with mode: 0644]
Documentation/block/barrier.txt
Documentation/feature-removal-schedule.txt
Documentation/firmware_class/firmware_sample_firmware_class.c
Documentation/i2c/busses/i2c-i801
Documentation/i2c/busses/i2c-piix4
Documentation/i2c/busses/i2c-taos-evm [new file with mode: 0644]
Documentation/i2c/chips/max6875
Documentation/i2c/chips/x1205 [deleted file]
Documentation/i2c/summary
Documentation/i2c/writing-clients
Documentation/i386/zero-page.txt
Documentation/ia64/aliasing-test.c
Documentation/ia64/aliasing.txt
Documentation/kernel-parameters.txt
Documentation/networking/00-INDEX
Documentation/networking/ip-sysctl.txt
Documentation/networking/l2tp.txt [new file with mode: 0644]
Documentation/networking/multiqueue.txt [new file with mode: 0644]
Documentation/networking/netdevices.txt
Documentation/networking/sk98lin.txt [deleted file]
Documentation/networking/spider_net.txt [new file with mode: 0644]
Documentation/pci.txt
Documentation/power/pci.txt
Documentation/power/swsusp.txt
Documentation/power_supply_class.txt [new file with mode: 0644]
Documentation/sched-design-CFS.txt [new file with mode: 0644]
Documentation/sysctl/vm.txt
Documentation/sysfs-rules.txt [new file with mode: 0644]
Documentation/usb/dma.txt
Documentation/usb/persist.txt [new file with mode: 0644]
MAINTAINERS
arch/alpha/Kconfig
arch/alpha/kernel/pci_iommu.c
arch/arm/Kconfig
arch/arm/boot/compressed/.gitignore
arch/arm/boot/compressed/Makefile
arch/arm/boot/compressed/head-xscale.S
arch/arm/boot/compressed/head.S
arch/arm/common/locomo.c
arch/arm/common/sa1111.c
arch/arm/common/sharpsl_pm.c
arch/arm/kernel/head-common.S
arch/arm/kernel/head.S
arch/arm/kernel/process.c
arch/arm/kernel/setup.c
arch/arm/mach-at91/board-sam9261ek.c
arch/arm/mach-at91/board-sam9263ek.c
arch/arm/mach-davinci/Makefile
arch/arm/mach-davinci/board-evm.c
arch/arm/mach-davinci/clock.c [new file with mode: 0644]
arch/arm/mach-davinci/clock.h [new file with mode: 0644]
arch/arm/mach-davinci/gpio.c [new file with mode: 0644]
arch/arm/mach-davinci/io.c
arch/arm/mach-davinci/mux.c [new file with mode: 0644]
arch/arm/mach-davinci/psc.c
arch/arm/mach-imx/generic.c
arch/arm/mach-imx/time.c
arch/arm/mach-iop13xx/tpmi.c
arch/arm/mach-ixp4xx/Kconfig
arch/arm/mach-ixp4xx/Makefile
arch/arm/mach-ixp4xx/gateway7001-pci.c [new file with mode: 0644]
arch/arm/mach-ixp4xx/gateway7001-setup.c [new file with mode: 0644]
arch/arm/mach-ixp4xx/gtwx5715-pci.c
arch/arm/mach-ixp4xx/ixdp425-setup.c
arch/arm/mach-ixp4xx/wg302v2-pci.c [new file with mode: 0644]
arch/arm/mach-ixp4xx/wg302v2-setup.c [new file with mode: 0644]
arch/arm/mach-ks8695/Makefile
arch/arm/mach-ks8695/gpio.c [new file with mode: 0644]
arch/arm/mach-pxa/clock.c
arch/arm/mach-pxa/corgi.c
arch/arm/mach-pxa/devices.h [new file with mode: 0644]
arch/arm/mach-pxa/dma.c
arch/arm/mach-pxa/generic.c
arch/arm/mach-pxa/generic.h
arch/arm/mach-pxa/idp.c
arch/arm/mach-pxa/irq.c
arch/arm/mach-pxa/lpd270.c
arch/arm/mach-pxa/lubbock.c
arch/arm/mach-pxa/mainstone.c
arch/arm/mach-pxa/pm.c
arch/arm/mach-pxa/poodle.c
arch/arm/mach-pxa/pxa25x.c
arch/arm/mach-pxa/pxa27x.c
arch/arm/mach-pxa/spitz.c
arch/arm/mach-pxa/time.c
arch/arm/mach-pxa/tosa.c
arch/arm/mach-pxa/trizeps4.c
arch/arm/mach-s3c2410/mach-bast.c
arch/arm/mach-s3c2440/mach-anubis.c
arch/arm/mach-s3c2440/mach-osiris.c
arch/arm/mach-sa1100/neponset.c
arch/arm/mach-sa1100/pm.c
arch/arm/mach-sa1100/time.c
arch/arm/mm/ioremap.c
arch/blackfin/Kconfig
arch/blackfin/Makefile
arch/blackfin/boot/Makefile
arch/blackfin/configs/BF548-EZKIT_defconfig [new file with mode: 0644]
arch/blackfin/kernel/Makefile
arch/blackfin/kernel/asm-offsets.c
arch/blackfin/kernel/bfin_dma_5xx.c
arch/blackfin/kernel/bfin_gpio.c
arch/blackfin/kernel/bfin_ksyms.c
arch/blackfin/kernel/cacheinit.c [new file with mode: 0644]
arch/blackfin/kernel/cplbinit.c [new file with mode: 0644]
arch/blackfin/kernel/dma-mapping.c
arch/blackfin/kernel/dualcore_test.c
arch/blackfin/kernel/fixed_code.S [new file with mode: 0644]
arch/blackfin/kernel/flat.c
arch/blackfin/kernel/irqchip.c
arch/blackfin/kernel/kgdb.c [new file with mode: 0644]
arch/blackfin/kernel/module.c
arch/blackfin/kernel/process.c
arch/blackfin/kernel/ptrace.c
arch/blackfin/kernel/setup.c
arch/blackfin/kernel/signal.c
arch/blackfin/kernel/sys_bfin.c
arch/blackfin/kernel/time.c
arch/blackfin/kernel/traps.c
arch/blackfin/kernel/vmlinux.lds.S
arch/blackfin/lib/strcmp.c
arch/blackfin/lib/strcpy.c
arch/blackfin/lib/strncmp.c
arch/blackfin/lib/strncpy.c
arch/blackfin/mach-bf533/Makefile
arch/blackfin/mach-bf533/boards/cm_bf533.c
arch/blackfin/mach-bf533/boards/ezkit.c
arch/blackfin/mach-bf533/boards/generic_board.c
arch/blackfin/mach-bf533/boards/stamp.c
arch/blackfin/mach-bf533/cpu.c
arch/blackfin/mach-bf533/dma.c [new file with mode: 0644]
arch/blackfin/mach-bf533/head.S
arch/blackfin/mach-bf533/ints-priority.c
arch/blackfin/mach-bf537/Makefile
arch/blackfin/mach-bf537/boards/cm_bf537.c
arch/blackfin/mach-bf537/boards/eth_mac.c
arch/blackfin/mach-bf537/boards/generic_board.c
arch/blackfin/mach-bf537/boards/pnav10.c
arch/blackfin/mach-bf537/boards/stamp.c
arch/blackfin/mach-bf537/dma.c [new file with mode: 0644]
arch/blackfin/mach-bf537/head.S
arch/blackfin/mach-bf537/ints-priority.c
arch/blackfin/mach-bf548/Kconfig [new file with mode: 0644]
arch/blackfin/mach-bf548/Makefile [new file with mode: 0644]
arch/blackfin/mach-bf548/boards/Makefile [new file with mode: 0644]
arch/blackfin/mach-bf548/boards/ezkit.c [new file with mode: 0644]
arch/blackfin/mach-bf548/boards/led.S [new file with mode: 0644]
arch/blackfin/mach-bf548/cpu.c [new file with mode: 0644]
arch/blackfin/mach-bf548/dma.c [new file with mode: 0644]
arch/blackfin/mach-bf548/gpio.c [new file with mode: 0644]
arch/blackfin/mach-bf548/head.S [new file with mode: 0644]
arch/blackfin/mach-bf548/ints-priority.c [new file with mode: 0644]
arch/blackfin/mach-bf561/Makefile
arch/blackfin/mach-bf561/boards/cm_bf561.c
arch/blackfin/mach-bf561/boards/ezkit.c
arch/blackfin/mach-bf561/boards/generic_board.c
arch/blackfin/mach-bf561/boards/tepla.c
arch/blackfin/mach-bf561/coreb.c
arch/blackfin/mach-bf561/dma.c [new file with mode: 0644]
arch/blackfin/mach-bf561/head.S
arch/blackfin/mach-bf561/ints-priority.c
arch/blackfin/mach-common/Makefile
arch/blackfin/mach-common/cacheinit.S
arch/blackfin/mach-common/cplbinfo.c
arch/blackfin/mach-common/entry.S
arch/blackfin/mach-common/interrupt.S
arch/blackfin/mach-common/ints-priority-dc.c
arch/blackfin/mach-common/ints-priority-sc.c
arch/blackfin/mach-common/pm.c
arch/blackfin/mm/blackfin_sram.c
arch/blackfin/mm/init.c
arch/blackfin/oprofile/common.c
arch/blackfin/oprofile/op_model_bf533.c
arch/blackfin/oprofile/timer_int.c
arch/i386/Kconfig.cpu
arch/i386/boot/Makefile
arch/i386/boot/a20.c [new file with mode: 0644]
arch/i386/boot/apm.c [new file with mode: 0644]
arch/i386/boot/bitops.h [new file with mode: 0644]
arch/i386/boot/boot.h [new file with mode: 0644]
arch/i386/boot/bootsect.S [deleted file]
arch/i386/boot/cmdline.c [new file with mode: 0644]
arch/i386/boot/code16gcc.h [new file with mode: 0644]
arch/i386/boot/compressed/Makefile
arch/i386/boot/compressed/head.S
arch/i386/boot/copy.S [new file with mode: 0644]
arch/i386/boot/cpu.c [new file with mode: 0644]
arch/i386/boot/cpucheck.c [new file with mode: 0644]
arch/i386/boot/edd.S [deleted file]
arch/i386/boot/edd.c [new file with mode: 0644]
arch/i386/boot/header.S [new file with mode: 0644]
arch/i386/boot/main.c [new file with mode: 0644]
arch/i386/boot/mca.c [new file with mode: 0644]
arch/i386/boot/memory.c [new file with mode: 0644]
arch/i386/boot/pm.c [new file with mode: 0644]
arch/i386/boot/pmjump.S [new file with mode: 0644]
arch/i386/boot/printf.c [new file with mode: 0644]
arch/i386/boot/setup.S [deleted file]
arch/i386/boot/setup.ld [new file with mode: 0644]
arch/i386/boot/string.c [new file with mode: 0644]
arch/i386/boot/tools/build.c
arch/i386/boot/tty.c [new file with mode: 0644]
arch/i386/boot/version.c [new file with mode: 0644]
arch/i386/boot/vesa.h [new file with mode: 0644]
arch/i386/boot/video-bios.c [new file with mode: 0644]
arch/i386/boot/video-vesa.c [new file with mode: 0644]
arch/i386/boot/video-vga.c [new file with mode: 0644]
arch/i386/boot/video.S [deleted file]
arch/i386/boot/video.c [new file with mode: 0644]
arch/i386/boot/video.h [new file with mode: 0644]
arch/i386/boot/voyager.c [new file with mode: 0644]
arch/i386/kernel/cpu/Makefile
arch/i386/kernel/cpu/addon_cpuid_features.c [new file with mode: 0644]
arch/i386/kernel/cpu/common.c
arch/i386/kernel/cpu/cpufreq/Kconfig
arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c
arch/i386/kernel/cpu/cpufreq/gx-suspmod.c
arch/i386/kernel/cpu/cpufreq/longhaul.c
arch/i386/kernel/cpu/cpufreq/longhaul.h
arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
arch/i386/kernel/cpu/proc.c
arch/i386/kernel/e820.c
arch/i386/kernel/setup.c
arch/i386/kernel/smpboot.c
arch/i386/kernel/tsc.c
arch/i386/kernel/verify_cpu.S [deleted file]
arch/i386/mach-visws/traps.c
arch/i386/pci/fixup.c
arch/ia64/Kconfig
arch/ia64/kernel/gate.S
arch/ia64/kernel/mca.c
arch/ia64/kernel/mca_asm.S
arch/ia64/kernel/mca_drv_asm.S
arch/ia64/kernel/process.c
arch/ia64/kernel/setup.c
arch/ia64/mm/tlb.c
arch/ia64/pci/pci.c
arch/ia64/sn/kernel/io_acpi_init.c
arch/ia64/sn/kernel/io_init.c
arch/ia64/sn/kernel/tiocx.c
arch/ia64/sn/pci/pcibr/pcibr_provider.c
arch/mips/Kconfig
arch/mips/Makefile
arch/mips/au1000/common/gpio.c
arch/mips/au1000/common/platform.c
arch/mips/au1000/common/setup.c
arch/mips/au1000/common/time.c
arch/mips/au1000/pb1200/board_setup.c
arch/mips/configs/atlas_defconfig
arch/mips/configs/bigsur_defconfig
arch/mips/configs/capcella_defconfig
arch/mips/configs/cobalt_defconfig
arch/mips/configs/db1000_defconfig
arch/mips/configs/db1100_defconfig
arch/mips/configs/db1200_defconfig
arch/mips/configs/db1500_defconfig
arch/mips/configs/db1550_defconfig
arch/mips/configs/ddb5477_defconfig
arch/mips/configs/decstation_defconfig
arch/mips/configs/e55_defconfig
arch/mips/configs/emma2rh_defconfig
arch/mips/configs/ev64120_defconfig [deleted file]
arch/mips/configs/excite_defconfig
arch/mips/configs/fulong_defconfig [new file with mode: 0644]
arch/mips/configs/ip22_defconfig
arch/mips/configs/ip27_defconfig
arch/mips/configs/ip32_defconfig
arch/mips/configs/jazz_defconfig
arch/mips/configs/jmr3927_defconfig
arch/mips/configs/lasat200_defconfig [deleted file]
arch/mips/configs/malta_defconfig
arch/mips/configs/mipssim_defconfig
arch/mips/configs/mpc30x_defconfig
arch/mips/configs/msp71xx_defconfig [moved from arch/mips/configs/ocelot_3_defconfig with 51% similarity]
arch/mips/configs/ocelot_c_defconfig [deleted file]
arch/mips/configs/ocelot_defconfig
arch/mips/configs/pb1100_defconfig
arch/mips/configs/pb1500_defconfig
arch/mips/configs/pb1550_defconfig
arch/mips/configs/pnx8550-jbs_defconfig
arch/mips/configs/pnx8550-stb810_defconfig
arch/mips/configs/qemu_defconfig
arch/mips/configs/rbhma4200_defconfig
arch/mips/configs/rbhma4500_defconfig
arch/mips/configs/rm200_defconfig
arch/mips/configs/sb1250-swarm_defconfig
arch/mips/configs/sead_defconfig
arch/mips/configs/tb0219_defconfig
arch/mips/configs/tb0226_defconfig
arch/mips/configs/tb0287_defconfig
arch/mips/configs/workpad_defconfig
arch/mips/configs/wrppmc_defconfig
arch/mips/configs/yosemite_defconfig
arch/mips/ddb5xxx/ddb5477/Makefile
arch/mips/ddb5xxx/ddb5477/ddb5477-platform.c [new file with mode: 0644]
arch/mips/dec/prom/console.c
arch/mips/dec/prom/init.c
arch/mips/dec/reset.c
arch/mips/defconfig
arch/mips/gt64120/ev64120/Kconfig [deleted file]
arch/mips/gt64120/ev64120/Makefile [deleted file]
arch/mips/gt64120/ev64120/irq.c [deleted file]
arch/mips/gt64120/ev64120/promcon.c [deleted file]
arch/mips/gt64120/ev64120/reset.c [deleted file]
arch/mips/gt64120/ev64120/serialGT.c [deleted file]
arch/mips/gt64120/ev64120/setup.c [deleted file]
arch/mips/gt64120/momenco_ocelot/Makefile
arch/mips/gt64120/momenco_ocelot/ocelot-platform.c [new file with mode: 0644]
arch/mips/gt64120/wrppmc/setup.c
arch/mips/jazz/Makefile
arch/mips/jazz/jazz-platform.c [new file with mode: 0644]
arch/mips/kernel/8250-platform.c [new file with mode: 0644]
arch/mips/kernel/Makefile
arch/mips/kernel/branch.c
arch/mips/kernel/cpu-probe.c
arch/mips/kernel/entry.S
arch/mips/kernel/genex.S
arch/mips/kernel/head.S
arch/mips/kernel/irq-mv6434x.c [deleted file]
arch/mips/kernel/mips-mt-fpaff.c [new file with mode: 0644]
arch/mips/kernel/mips-mt.c
arch/mips/kernel/pcspeaker.c [moved from arch/mips/kernel/i8253.c with 100% similarity]
arch/mips/kernel/proc.c
arch/mips/kernel/process.c
arch/mips/kernel/r4k_switch.S
arch/mips/kernel/setup.c
arch/mips/kernel/smp.c
arch/mips/kernel/smtc.c
arch/mips/kernel/syscall.c
arch/mips/kernel/traps.c
arch/mips/kernel/unaligned.c
arch/mips/lasat/Kconfig [deleted file]
arch/mips/lasat/Makefile [deleted file]
arch/mips/lasat/at93c.c [deleted file]
arch/mips/lasat/at93c.h [deleted file]
arch/mips/lasat/ds1603.c [deleted file]
arch/mips/lasat/ds1603.h [deleted file]
arch/mips/lasat/image/Makefile [deleted file]
arch/mips/lasat/image/head.S [deleted file]
arch/mips/lasat/image/romscript.normal [deleted file]
arch/mips/lasat/interrupt.c [deleted file]
arch/mips/lasat/lasat_board.c [deleted file]
arch/mips/lasat/lasat_models.h [deleted file]
arch/mips/lasat/picvue.c [deleted file]
arch/mips/lasat/picvue.h [deleted file]
arch/mips/lasat/picvue_proc.c [deleted file]
arch/mips/lasat/prom.c [deleted file]
arch/mips/lasat/prom.h [deleted file]
arch/mips/lasat/reset.c [deleted file]
arch/mips/lasat/setup.c [deleted file]
arch/mips/lasat/sysctl.c [deleted file]
arch/mips/lasat/sysctl.h [deleted file]
arch/mips/lemote/lm2e/Makefile [new file with mode: 0644]
arch/mips/lemote/lm2e/bonito-irq.c [new file with mode: 0644]
arch/mips/lemote/lm2e/dbg_io.c [new file with mode: 0644]
arch/mips/lemote/lm2e/irq.c [new file with mode: 0644]
arch/mips/lemote/lm2e/mem.c [new file with mode: 0644]
arch/mips/lemote/lm2e/pci.c [new file with mode: 0644]
arch/mips/lemote/lm2e/prom.c [new file with mode: 0644]
arch/mips/lemote/lm2e/reset.c [new file with mode: 0644]
arch/mips/lemote/lm2e/setup.c [new file with mode: 0644]
arch/mips/lib-32/Makefile [deleted file]
arch/mips/lib-32/dump_tlb.c [deleted file]
arch/mips/lib-32/r3k_dump_tlb.c [deleted file]
arch/mips/lib-32/watch.S [deleted file]
arch/mips/lib-64/Makefile [deleted file]
arch/mips/lib-64/dump_tlb.c [deleted file]
arch/mips/lib-64/watch.S [deleted file]
arch/mips/lib/Makefile
arch/mips/lib/dump_tlb.c [new file with mode: 0644]
arch/mips/lib/r3k_dump_tlb.c [new file with mode: 0644]
arch/mips/lib/uncached.c
arch/mips/math-emu/cp1emu.c
arch/mips/math-emu/dsemul.c
arch/mips/mips-boards/malta/Makefile
arch/mips/mips-boards/malta/malta_platform.c [new file with mode: 0644]
arch/mips/mipssim/Makefile [moved from arch/mips/mips-boards/sim/Makefile with 100% similarity]
arch/mips/mipssim/sim_cmdline.c [moved from arch/mips/mips-boards/sim/sim_cmdline.c with 100% similarity]
arch/mips/mipssim/sim_console.c [moved from arch/mips/mips-boards/sim/sim_console.c with 98% similarity]
arch/mips/mipssim/sim_int.c [new file with mode: 0644]
arch/mips/mipssim/sim_mem.c [moved from arch/mips/mips-boards/sim/sim_mem.c with 99% similarity]
arch/mips/mipssim/sim_platform.c [moved from arch/mips/mips-boards/sim/sim_platform.c with 100% similarity]
arch/mips/mipssim/sim_setup.c [moved from arch/mips/mips-boards/sim/sim_setup.c with 94% similarity]
arch/mips/mipssim/sim_smp.c [moved from arch/mips/mips-boards/sim/sim_smp.c with 89% similarity]
arch/mips/mipssim/sim_time.c [moved from arch/mips/mips-boards/sim/sim_time.c with 91% similarity]
arch/mips/mm/Makefile
arch/mips/mm/c-r4k.c
arch/mips/mm/c-sb1.c
arch/mips/mm/cache.c
arch/mips/mm/tlb-r4k.c
arch/mips/mm/tlbex.c
arch/mips/momentum/ocelot_3/Makefile [deleted file]
arch/mips/momentum/ocelot_3/irq.c [deleted file]
arch/mips/momentum/ocelot_3/platform.c [deleted file]
arch/mips/momentum/ocelot_3/prom.c [deleted file]
arch/mips/momentum/ocelot_3/reset.c [deleted file]
arch/mips/momentum/ocelot_3/setup.c [deleted file]
arch/mips/momentum/ocelot_c/Makefile [deleted file]
arch/mips/momentum/ocelot_c/cpci-irq.c [deleted file]
arch/mips/momentum/ocelot_c/dbg_io.c [deleted file]
arch/mips/momentum/ocelot_c/irq.c [deleted file]
arch/mips/momentum/ocelot_c/platform.c [deleted file]
arch/mips/momentum/ocelot_c/prom.c [deleted file]
arch/mips/momentum/ocelot_c/reset.c [deleted file]
arch/mips/momentum/ocelot_c/setup.c [deleted file]
arch/mips/momentum/ocelot_c/uart-irq.c [deleted file]
arch/mips/pci/Makefile
arch/mips/pci/fixup-atlas.c
arch/mips/pci/fixup-au1000.c
arch/mips/pci/fixup-capcella.c
arch/mips/pci/fixup-cobalt.c
arch/mips/pci/fixup-emma2rh.c
arch/mips/pci/fixup-excite.c
arch/mips/pci/fixup-ip32.c
arch/mips/pci/fixup-jmr3927.c
arch/mips/pci/fixup-lm2e.c [new file with mode: 0644]
arch/mips/pci/fixup-malta.c
arch/mips/pci/fixup-mpc30x.c
arch/mips/pci/fixup-ocelot-c.c [deleted file]
arch/mips/pci/fixup-ocelot3.c [deleted file]
arch/mips/pci/fixup-pmcmsp.c [new file with mode: 0644]
arch/mips/pci/fixup-pnx8550.c
arch/mips/pci/fixup-rbtx4927.c
arch/mips/pci/fixup-sni.c
arch/mips/pci/fixup-tb0219.c
arch/mips/pci/fixup-tb0226.c
arch/mips/pci/fixup-tb0287.c
arch/mips/pci/fixup-tx4938.c
arch/mips/pci/fixup-vr4133.c
arch/mips/pci/fixup-wrppmc.c
arch/mips/pci/fixup-yosemite.c
arch/mips/pci/ops-bonito64.c
arch/mips/pci/ops-marvell.c [deleted file]
arch/mips/pci/ops-nile4.c [deleted file]
arch/mips/pci/ops-pmcmsp.c [new file with mode: 0644]
arch/mips/pci/ops-tx4938.c
arch/mips/pci/pci-bcm1480.c
arch/mips/pci/pci-dac.c [deleted file]
arch/mips/pci/pci-ddb5477.c
arch/mips/pci/pci-ev64120.c [deleted file]
arch/mips/pci/pci-ip27.c
arch/mips/pci/pci-lasat.c [deleted file]
arch/mips/pci/pci-ocelot-c.c [deleted file]
arch/mips/pci/pci-sb1250.c
arch/mips/pci/pci.c
arch/mips/philips/pnx8550/common/platform.c
arch/mips/philips/pnx8550/common/proc.c
arch/mips/pmc-sierra/Kconfig
arch/mips/pmc-sierra/msp71xx/Makefile [new file with mode: 0644]
arch/mips/pmc-sierra/msp71xx/msp_elb.c [moved from arch/mips/momentum/ocelot_c/ocelot_c_fpga.h with 53% similarity]
arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c [new file with mode: 0644]
arch/mips/pmc-sierra/msp71xx/msp_irq.c [new file with mode: 0644]
arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c [new file with mode: 0644]
arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c [new file with mode: 0644]
arch/mips/pmc-sierra/msp71xx/msp_pci.c [moved from arch/mips/momentum/ocelot_3/ocelot_3_fpga.h with 53% similarity]
arch/mips/pmc-sierra/msp71xx/msp_prom.c [new file with mode: 0644]
arch/mips/pmc-sierra/msp71xx/msp_setup.c [new file with mode: 0644]
arch/mips/pmc-sierra/msp71xx/msp_time.c [new file with mode: 0644]
arch/mips/pmc-sierra/msp71xx/msp_usb.c [new file with mode: 0644]
arch/mips/pmc-sierra/yosemite/smp.c
arch/mips/sgi-ip22/ip22-reset.c
arch/mips/sgi-ip27/ip27-berr.c
arch/mips/sgi-ip32/ip32-platform.c
arch/mips/sgi-ip32/ip32-setup.c
arch/mips/sibyte/cfe/setup.c
arch/mips/sibyte/swarm/time.c [deleted file]
arch/mips/sni/Makefile
arch/mips/sni/a20r.c
arch/mips/sni/ds1216.c [deleted file]
arch/mips/sni/pcimt.c
arch/mips/sni/pcit.c
arch/mips/sni/rm200.c
arch/mips/sni/sniprom.c
arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
arch/mips/tx4938/common/Makefile
arch/mips/tx4938/common/rtc_rx5c348.c [deleted file]
arch/mips/tx4938/toshiba_rbtx4938/Makefile
arch/mips/tx4938/toshiba_rbtx4938/irq.c
arch/mips/tx4938/toshiba_rbtx4938/setup.c
arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c
arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c [deleted file]
arch/mips/vr41xx/common/Makefile
arch/mips/vr41xx/common/giu.c [new file with mode: 0644]
arch/mips/vr41xx/common/rtc.c [new file with mode: 0644]
arch/mips/vr41xx/common/siu.c [new file with mode: 0644]
arch/powerpc/Kconfig
arch/powerpc/kernel/pci_32.c
arch/powerpc/kernel/pci_64.c
arch/ppc/8260_io/enet.c
arch/ppc/8260_io/fcc_enet.c
arch/ppc/8xx_io/enet.c
arch/ppc/8xx_io/fec.c
arch/ppc/Kconfig
arch/ppc/kernel/pci.c
arch/ppc/syslib/mv64x60.c
arch/s390/crypto/crypt_s390.h
arch/s390/kernel/early.c
arch/s390/kernel/entry.S
arch/s390/kernel/entry64.S
arch/s390/kernel/ipl.c
arch/s390/kernel/process.c
arch/s390/kernel/smp.c
arch/s390/kernel/time.c
arch/s390/kernel/vtime.c
arch/s390/lib/Makefile
arch/sparc/Kconfig
arch/sparc/kernel/smp.c
arch/sparc64/Kconfig
arch/sparc64/kernel/pci.c
arch/sparc64/kernel/smp.c
arch/x86_64/Kconfig
arch/x86_64/boot/Makefile
arch/x86_64/boot/bootsect.S [deleted file]
arch/x86_64/boot/compressed/Makefile
arch/x86_64/boot/compressed/head.S
arch/x86_64/boot/install.sh [deleted file]
arch/x86_64/boot/mtools.conf.in [deleted file]
arch/x86_64/boot/setup.S [deleted file]
arch/x86_64/boot/tools/build.c [deleted file]
arch/x86_64/kernel/Makefile
arch/x86_64/kernel/pci-dma.c
arch/x86_64/kernel/setup.c
arch/x86_64/kernel/verify_cpu.S
block/Kconfig
block/cfq-iosched.c
block/elevator.c
block/ll_rw_blk.c
drivers/Kconfig
drivers/Makefile
drivers/acorn/block/fd1772.c
drivers/acorn/block/mfmhd.c
drivers/acpi/processor_core.c
drivers/ata/Kconfig
drivers/ata/ahci.c
drivers/ata/ata_generic.c
drivers/ata/ata_piix.c
drivers/ata/libata-acpi.c
drivers/ata/libata-core.c
drivers/ata/libata-eh.c
drivers/ata/libata-scsi.c
drivers/ata/libata-sff.c
drivers/ata/libata.h
drivers/ata/pata_ali.c
drivers/ata/pata_amd.c
drivers/ata/pata_artop.c
drivers/ata/pata_atiixp.c
drivers/ata/pata_cmd640.c
drivers/ata/pata_cmd64x.c
drivers/ata/pata_cs5520.c
drivers/ata/pata_cs5530.c
drivers/ata/pata_cs5535.c
drivers/ata/pata_cypress.c
drivers/ata/pata_efar.c
drivers/ata/pata_hpt366.c
drivers/ata/pata_hpt37x.c
drivers/ata/pata_hpt3x2n.c
drivers/ata/pata_hpt3x3.c
drivers/ata/pata_icside.c
drivers/ata/pata_it8213.c
drivers/ata/pata_it821x.c
drivers/ata/pata_ixp4xx_cf.c
drivers/ata/pata_jmicron.c
drivers/ata/pata_marvell.c
drivers/ata/pata_mpc52xx.c
drivers/ata/pata_netcell.c
drivers/ata/pata_ns87410.c
drivers/ata/pata_oldpiix.c
drivers/ata/pata_opti.c
drivers/ata/pata_optidma.c
drivers/ata/pata_pdc202xx_old.c
drivers/ata/pata_platform.c
drivers/ata/pata_radisys.c
drivers/ata/pata_rz1000.c
drivers/ata/pata_sc1200.c
drivers/ata/pata_scc.c
drivers/ata/pata_serverworks.c
drivers/ata/pata_sil680.c
drivers/ata/pata_sis.c
drivers/ata/pata_sl82c105.c
drivers/ata/pata_triflex.c
drivers/ata/pata_via.c
drivers/ata/pdc_adma.c
drivers/ata/sata_inic162x.c
drivers/ata/sata_mv.c
drivers/ata/sata_nv.c
drivers/ata/sata_promise.c
drivers/ata/sata_qstor.c
drivers/ata/sata_sil.c
drivers/ata/sata_sil24.c
drivers/ata/sata_sis.c
drivers/ata/sata_svw.c
drivers/ata/sata_sx4.c
drivers/ata/sata_uli.c
drivers/ata/sata_via.c
drivers/ata/sata_vsc.c
drivers/atm/eni.c
drivers/atm/idt77252.c
drivers/atm/iphase.c
drivers/atm/lanai.c
drivers/atm/zatm.c
drivers/base/attribute_container.c
drivers/base/base.h
drivers/base/bus.c
drivers/base/class.c
drivers/base/core.c
drivers/base/dd.c
drivers/base/devres.c
drivers/base/firmware_class.c
drivers/base/power/main.c
drivers/base/power/power.h
drivers/base/power/resume.c
drivers/base/power/runtime.c
drivers/base/power/suspend.c
drivers/base/sys.c
drivers/block/Kconfig
drivers/block/Makefile
drivers/block/acsi.c [deleted file]
drivers/block/amiflop.c
drivers/block/cciss.c
drivers/block/loop.c
drivers/block/nbd.c
drivers/block/pktcdvd.c
drivers/block/ub.c
drivers/bluetooth/hci_usb.c
drivers/bluetooth/hci_usb.h
drivers/bluetooth/hci_vhci.c
drivers/cdrom/Kconfig [deleted file]
drivers/cdrom/Makefile
drivers/cdrom/aztcd.c [deleted file]
drivers/cdrom/aztcd.h [deleted file]
drivers/cdrom/cdrom.c
drivers/cdrom/cdu31a.c [deleted file]
drivers/cdrom/cdu31a.h [deleted file]
drivers/cdrom/cm206.c [deleted file]
drivers/cdrom/cm206.h [deleted file]
drivers/cdrom/gscd.c [deleted file]
drivers/cdrom/gscd.h [deleted file]
drivers/cdrom/isp16.c [deleted file]
drivers/cdrom/isp16.h [deleted file]
drivers/cdrom/mcdx.c [deleted file]
drivers/cdrom/mcdx.h [deleted file]
drivers/cdrom/optcd.c [deleted file]
drivers/cdrom/optcd.h [deleted file]
drivers/cdrom/sbpcd.c [deleted file]
drivers/cdrom/sbpcd.h [deleted file]
drivers/cdrom/sjcd.c [deleted file]
drivers/cdrom/sjcd.h [deleted file]
drivers/cdrom/sonycd535.c [deleted file]
drivers/cdrom/sonycd535.h [deleted file]
drivers/char/Kconfig
drivers/char/agp/amd-k7-agp.c
drivers/char/agp/amd64-agp.c
drivers/char/agp/backend.c
drivers/char/ipmi/ipmi_msghandler.c
drivers/char/keyboard.c
drivers/char/mem.c
drivers/char/sx.c
drivers/char/vr41xx_giu.c
drivers/clocksource/acpi_pm.c
drivers/cpufreq/cpufreq.c
drivers/cpufreq/cpufreq_ondemand.c
drivers/cpufreq/cpufreq_stats.c
drivers/cpufreq/cpufreq_userspace.c
drivers/cpufreq/freq_table.c
drivers/firewire/fw-card.c
drivers/firewire/fw-cdev.c
drivers/firewire/fw-device.c
drivers/firewire/fw-device.h
drivers/firewire/fw-ohci.c
drivers/firewire/fw-sbp2.c
drivers/firewire/fw-topology.c
drivers/firewire/fw-topology.h
drivers/firewire/fw-transaction.h
drivers/firmware/Kconfig
drivers/firmware/Makefile
drivers/firmware/dcdbas.c
drivers/firmware/dcdbas.h
drivers/firmware/dell_rbu.c
drivers/firmware/dmi-id.c [new file with mode: 0644]
drivers/firmware/dmi_scan.c
drivers/firmware/edd.c
drivers/firmware/efivars.c
drivers/hid/Kconfig
drivers/hid/hid-core.c
drivers/hid/hid-debug.c
drivers/hid/hid-input.c
drivers/hid/usbhid/hid-core.c
drivers/hid/usbhid/hid-lgff.c
drivers/hid/usbhid/hid-pidff.c
drivers/hid/usbhid/hid-quirks.c
drivers/hid/usbhid/hid-tmff.c
drivers/hid/usbhid/hid-zpff.c
drivers/hid/usbhid/hiddev.c
drivers/hid/usbhid/usbkbd.c
drivers/i2c/algos/Kconfig
drivers/i2c/busses/Kconfig
drivers/i2c/busses/Makefile
drivers/i2c/busses/i2c-gpio.c
drivers/i2c/busses/i2c-i801.c
drivers/i2c/busses/i2c-iop3xx.c
drivers/i2c/busses/i2c-mpc.c
drivers/i2c/busses/i2c-mv64xxx.c
drivers/i2c/busses/i2c-nforce2.c
drivers/i2c/busses/i2c-piix4.c
drivers/i2c/busses/i2c-pmcmsp.c [new file with mode: 0644]
drivers/i2c/busses/i2c-powermac.c
drivers/i2c/busses/i2c-pxa.c
drivers/i2c/busses/i2c-rpx.c [deleted file]
drivers/i2c/busses/i2c-savage4.c
drivers/i2c/busses/i2c-sis5595.c
drivers/i2c/busses/i2c-taos-evm.c [new file with mode: 0644]
drivers/i2c/busses/i2c-viapro.c
drivers/i2c/busses/scx200_acb.c
drivers/i2c/chips/Kconfig
drivers/i2c/chips/Makefile
drivers/i2c/chips/ds1682.c [new file with mode: 0644]
drivers/i2c/chips/eeprom.c
drivers/i2c/chips/max6875.c
drivers/i2c/chips/tsl2550.c [new file with mode: 0644]
drivers/i2c/i2c-core.c
drivers/i2c/i2c-dev.c
drivers/ide/arm/icside.c
drivers/ide/cris/ide-cris.c
drivers/ide/ide-cd.c
drivers/ide/ide-cd.h
drivers/ide/ide-disk.c
drivers/ide/ide-dma.c
drivers/ide/ide-io.c
drivers/ide/ide-iops.c
drivers/ide/ide-probe.c
drivers/ide/ide-proc.c
drivers/ide/ide-timing.h
drivers/ide/ide.c
drivers/ide/legacy/hd.c
drivers/ide/legacy/macide.c
drivers/ide/mips/au1xxx-ide.c
drivers/ide/pci/aec62xx.c
drivers/ide/pci/alim15x3.c
drivers/ide/pci/amd74xx.c
drivers/ide/pci/atiixp.c
drivers/ide/pci/cmd64x.c
drivers/ide/pci/cs5530.c
drivers/ide/pci/cs5535.c
drivers/ide/pci/hpt366.c
drivers/ide/pci/it8213.c
drivers/ide/pci/it821x.c
drivers/ide/pci/jmicron.c
drivers/ide/pci/pdc202xx_new.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/sis5513.c
drivers/ide/pci/sl82c105.c
drivers/ide/pci/slc90e66.c
drivers/ide/pci/tc86c001.c
drivers/ide/pci/via82cxxx.c
drivers/ide/ppc/pmac.c
drivers/ieee1394/dv1394.c
drivers/ieee1394/eth1394.c
drivers/ieee1394/highlevel.c
drivers/ieee1394/highlevel.h
drivers/ieee1394/hosts.c
drivers/ieee1394/hosts.h
drivers/ieee1394/ieee1394_core.c
drivers/ieee1394/ieee1394_core.h
drivers/ieee1394/ieee1394_transactions.c
drivers/ieee1394/ieee1394_transactions.h
drivers/ieee1394/nodemgr.c
drivers/ieee1394/nodemgr.h
drivers/ieee1394/ohci1394.c
drivers/ieee1394/ohci1394.h
drivers/ieee1394/pcilynx.c
drivers/ieee1394/raw1394-private.h
drivers/ieee1394/raw1394.c
drivers/ieee1394/raw1394.h
drivers/ieee1394/sbp2.c
drivers/ieee1394/sbp2.h
drivers/ieee1394/video1394.c
drivers/infiniband/Kconfig
drivers/infiniband/core/agent.c
drivers/infiniband/core/cm.c
drivers/infiniband/core/cm_msgs.h
drivers/infiniband/core/cma.c
drivers/infiniband/core/mad.c
drivers/infiniband/core/multicast.c
drivers/infiniband/core/sa.h
drivers/infiniband/core/sa_query.c
drivers/infiniband/core/smi.c
drivers/infiniband/core/smi.h
drivers/infiniband/core/sysfs.c
drivers/infiniband/core/ucm.c
drivers/infiniband/core/umem.c
drivers/infiniband/hw/amso1100/Kconfig
drivers/infiniband/hw/cxgb3/Kconfig
drivers/infiniband/hw/cxgb3/cxio_hal.c
drivers/infiniband/hw/cxgb3/cxio_wr.h
drivers/infiniband/hw/cxgb3/iwch_cm.c
drivers/infiniband/hw/cxgb3/iwch_cm.h
drivers/infiniband/hw/cxgb3/iwch_provider.c
drivers/infiniband/hw/cxgb3/iwch_qp.c
drivers/infiniband/hw/ehca/Kconfig
drivers/infiniband/hw/ehca/ehca_av.c
drivers/infiniband/hw/ehca/ehca_classes.h
drivers/infiniband/hw/ehca/ehca_classes_pSeries.h
drivers/infiniband/hw/ehca/ehca_cq.c
drivers/infiniband/hw/ehca/ehca_hca.c
drivers/infiniband/hw/ehca/ehca_irq.c
drivers/infiniband/hw/ehca/ehca_irq.h
drivers/infiniband/hw/ehca/ehca_iverbs.h
drivers/infiniband/hw/ehca/ehca_main.c
drivers/infiniband/hw/ehca/ehca_qp.c
drivers/infiniband/hw/ehca/ehca_reqs.c
drivers/infiniband/hw/ehca/ehca_tools.h
drivers/infiniband/hw/ehca/ehca_uverbs.c
drivers/infiniband/hw/ehca/hcp_if.c
drivers/infiniband/hw/ehca/hcp_if.h
drivers/infiniband/hw/ehca/hipz_hw.h
drivers/infiniband/hw/ehca/ipz_pt_fn.h
drivers/infiniband/hw/ipath/Kconfig
drivers/infiniband/hw/ipath/ipath_common.h
drivers/infiniband/hw/ipath/ipath_cq.c
drivers/infiniband/hw/ipath/ipath_debug.h
drivers/infiniband/hw/ipath/ipath_diag.c
drivers/infiniband/hw/ipath/ipath_driver.c
drivers/infiniband/hw/ipath/ipath_eeprom.c
drivers/infiniband/hw/ipath/ipath_file_ops.c
drivers/infiniband/hw/ipath/ipath_fs.c
drivers/infiniband/hw/ipath/ipath_iba6110.c
drivers/infiniband/hw/ipath/ipath_iba6120.c
drivers/infiniband/hw/ipath/ipath_init_chip.c
drivers/infiniband/hw/ipath/ipath_intr.c
drivers/infiniband/hw/ipath/ipath_kernel.h
drivers/infiniband/hw/ipath/ipath_keys.c
drivers/infiniband/hw/ipath/ipath_layer.c
drivers/infiniband/hw/ipath/ipath_layer.h
drivers/infiniband/hw/ipath/ipath_mad.c
drivers/infiniband/hw/ipath/ipath_mmap.c
drivers/infiniband/hw/ipath/ipath_mr.c
drivers/infiniband/hw/ipath/ipath_qp.c
drivers/infiniband/hw/ipath/ipath_rc.c
drivers/infiniband/hw/ipath/ipath_registers.h
drivers/infiniband/hw/ipath/ipath_ruc.c
drivers/infiniband/hw/ipath/ipath_srq.c
drivers/infiniband/hw/ipath/ipath_stats.c
drivers/infiniband/hw/ipath/ipath_sysfs.c
drivers/infiniband/hw/ipath/ipath_uc.c
drivers/infiniband/hw/ipath/ipath_ud.c
drivers/infiniband/hw/ipath/ipath_user_pages.c
drivers/infiniband/hw/ipath/ipath_verbs.c
drivers/infiniband/hw/ipath/ipath_verbs.h
drivers/infiniband/hw/ipath/ipath_verbs_mcast.c
drivers/infiniband/hw/ipath/ipath_wc_ppc64.c
drivers/infiniband/hw/ipath/ipath_wc_x86_64.c
drivers/infiniband/hw/mlx4/Kconfig
drivers/infiniband/hw/mlx4/main.c
drivers/infiniband/hw/mlx4/mlx4_ib.h
drivers/infiniband/hw/mlx4/qp.c
drivers/infiniband/hw/mlx4/srq.c
drivers/infiniband/hw/mthca/Kconfig
drivers/infiniband/hw/mthca/mthca_allocator.c
drivers/infiniband/hw/mthca/mthca_eq.c
drivers/infiniband/ulp/ipoib/Kconfig
drivers/infiniband/ulp/ipoib/ipoib_cm.c
drivers/infiniband/ulp/ipoib/ipoib_ib.c
drivers/infiniband/ulp/iser/Kconfig
drivers/infiniband/ulp/srp/Kconfig
drivers/input/evdev.c
drivers/input/input.c
drivers/input/joydev.c
drivers/input/joystick/Kconfig
drivers/input/joystick/grip_mp.c
drivers/input/joystick/xpad.c
drivers/input/keyboard/atkbd.c
drivers/input/keyboard/pxa27x_keyboard.c
drivers/input/misc/Kconfig
drivers/input/misc/wistron_btns.c
drivers/input/mouse/Kconfig
drivers/input/mouse/Makefile
drivers/input/mouse/gpio_mouse.c [new file with mode: 0644]
drivers/input/mouse/psmouse-base.c
drivers/input/mouse/psmouse.h
drivers/input/mousedev.c
drivers/input/serio/serio_raw.c
drivers/input/tablet/aiptek.c
drivers/input/tablet/wacom.h
drivers/input/tablet/wacom_sys.c
drivers/input/tablet/wacom_wac.c
drivers/input/tablet/wacom_wac.h
drivers/input/touchscreen/Kconfig
drivers/input/touchscreen/usbtouchscreen.c
drivers/input/tsdev.c
drivers/isdn/hisax/bkm_a8.c
drivers/macintosh/windfarm_core.c
drivers/macintosh/windfarm_smu_sat.c
drivers/md/Kconfig
drivers/md/Makefile
drivers/md/dm-bio-list.h
drivers/md/dm-crypt.c
drivers/md/dm-delay.c
drivers/md/dm-exception-store.c
drivers/md/dm-io.c
drivers/md/dm-mpath-rdac.c [new file with mode: 0644]
drivers/md/dm-mpath.c
drivers/md/dm-raid1.c
drivers/md/dm-round-robin.c
drivers/md/dm-snap.c
drivers/md/dm-snap.h
drivers/md/dm.c
drivers/md/dm.h
drivers/md/kcopyd.c
drivers/media/radio/radio-gemtek-pci.c
drivers/media/video/meye.c
drivers/misc/Kconfig
drivers/misc/Makefile
drivers/misc/asus-laptop.c
drivers/misc/eeprom_93cx6.c [new file with mode: 0644]
drivers/misc/msi-laptop.c
drivers/mmc/card/Kconfig
drivers/mmc/card/block.c
drivers/mmc/card/queue.c
drivers/mmc/card/queue.h
drivers/mmc/core/Makefile
drivers/mmc/core/bus.c [new file with mode: 0644]
drivers/mmc/core/bus.h [new file with mode: 0644]
drivers/mmc/core/core.c
drivers/mmc/core/core.h
drivers/mmc/core/host.c [new file with mode: 0644]
drivers/mmc/core/host.h [new file with mode: 0644]
drivers/mmc/core/mmc.c
drivers/mmc/core/sd.c
drivers/mmc/core/sysfs.c
drivers/mmc/core/sysfs.h
drivers/mmc/host/at91_mci.c
drivers/mmc/host/pxamci.h
drivers/mmc/host/sdhci.c
drivers/mtd/devices/docprobe.c
drivers/mtd/maps/Kconfig
drivers/mtd/maps/Makefile
drivers/mtd/maps/lasat.c [deleted file]
drivers/mtd/nand/diskonchip.c
drivers/net/3c523.c
drivers/net/3c59x.c
drivers/net/7990.c
drivers/net/8139cp.c
drivers/net/8139too.c
drivers/net/8390.h
drivers/net/Kconfig
drivers/net/Makefile
drivers/net/a2065.c
drivers/net/acenic.c
drivers/net/ariadne.c
drivers/net/arm/Kconfig
drivers/net/arm/ep93xx_eth.c
drivers/net/atari_pamsnet.c
drivers/net/atl1/atl1.h
drivers/net/atl1/atl1_main.c
drivers/net/au1000_eth.c
drivers/net/ax88796.c [new file with mode: 0644]
drivers/net/b44.c
drivers/net/b44.h
drivers/net/bnx2.c
drivers/net/bnx2.h
drivers/net/bonding/bond_main.c
drivers/net/bonding/bonding.h
drivers/net/cassini.c
drivers/net/cxgb3/adapter.h
drivers/net/cxgb3/common.h
drivers/net/cxgb3/cxgb3_main.c
drivers/net/cxgb3/regs.h
drivers/net/cxgb3/sge.c
drivers/net/cxgb3/t3_hw.c
drivers/net/cxgb3/version.h
drivers/net/dl2k.c
drivers/net/dl2k.h
drivers/net/dm9000.c
drivers/net/dummy.c
drivers/net/e100.c
drivers/net/e1000/e1000_main.c
drivers/net/eepro100.c
drivers/net/ehea/ehea.h
drivers/net/ehea/ehea_hw.h
drivers/net/ehea/ehea_main.c
drivers/net/ehea/ehea_qmr.c
drivers/net/epic100.c
drivers/net/fealnx.c
drivers/net/fec.c
drivers/net/fec_8xx/Kconfig
drivers/net/forcedeth.c
drivers/net/fs_enet/Kconfig
drivers/net/gianfar.c
drivers/net/gianfar.h
drivers/net/gianfar_mii.c
drivers/net/hamachi.c
drivers/net/ibmveth.c
drivers/net/ifb.c
drivers/net/ioc3-eth.c
drivers/net/irda/kingsun-sir.c
drivers/net/irda/vlsi_ir.c
drivers/net/irda/vlsi_ir.h
drivers/net/ixp2000/ixpdev.c
drivers/net/lance.c
drivers/net/lasi_82596.c
drivers/net/lib82596.c [new file with mode: 0644]
drivers/net/macmace.c
drivers/net/mlx4/fw.c
drivers/net/mlx4/fw.h
drivers/net/mlx4/main.c
drivers/net/mlx4/mlx4.h
drivers/net/mlx4/qp.c
drivers/net/mlx4/srq.c
drivers/net/myri10ge/myri10ge.c
drivers/net/natsemi.c
drivers/net/netxen/netxen_nic.h
drivers/net/netxen/netxen_nic_main.c
drivers/net/netxen/netxen_nic_niu.c
drivers/net/ni52.c
drivers/net/ni65.c
drivers/net/pasemi_mac.c
drivers/net/pci-skeleton.c
drivers/net/pcmcia/axnet_cs.c
drivers/net/pcmcia/fmvj18x_cs.c
drivers/net/pcmcia/pcnet_cs.c
drivers/net/pcnet32.c
drivers/net/phy/Kconfig
drivers/net/phy/Makefile
drivers/net/phy/icplus.c [new file with mode: 0644]
drivers/net/phy/marvell.c
drivers/net/pppol2tp.c [new file with mode: 0644]
drivers/net/ps3_gelic_net.c [new file with mode: 0644]
drivers/net/ps3_gelic_net.h [new file with mode: 0644]
drivers/net/qla3xxx.c
drivers/net/r8169.c
drivers/net/rrunner.c
drivers/net/s2io.c
drivers/net/s2io.h
drivers/net/saa9730.c
drivers/net/sgiseeq.c
drivers/net/sis190.c
drivers/net/sis900.c
drivers/net/sk98lin/Makefile [deleted file]
drivers/net/sk98lin/h/lm80.h [deleted file]
drivers/net/sk98lin/h/skaddr.h [deleted file]
drivers/net/sk98lin/h/skcsum.h [deleted file]
drivers/net/sk98lin/h/skdebug.h [deleted file]
drivers/net/sk98lin/h/skdrv1st.h [deleted file]
drivers/net/sk98lin/h/skdrv2nd.h [deleted file]
drivers/net/sk98lin/h/skerror.h [deleted file]
drivers/net/sk98lin/h/skgedrv.h [deleted file]
drivers/net/sk98lin/h/skgehw.h [deleted file]
drivers/net/sk98lin/h/skgehwt.h [deleted file]
drivers/net/sk98lin/h/skgei2c.h [deleted file]
drivers/net/sk98lin/h/skgeinit.h [deleted file]
drivers/net/sk98lin/h/skgepnm2.h [deleted file]
drivers/net/sk98lin/h/skgepnmi.h [deleted file]
drivers/net/sk98lin/h/skgesirq.h [deleted file]
drivers/net/sk98lin/h/ski2c.h [deleted file]
drivers/net/sk98lin/h/skqueue.h [deleted file]
drivers/net/sk98lin/h/skrlmt.h [deleted file]
drivers/net/sk98lin/h/sktimer.h [deleted file]
drivers/net/sk98lin/h/sktypes.h [deleted file]
drivers/net/sk98lin/h/skversion.h [deleted file]
drivers/net/sk98lin/h/skvpd.h [deleted file]
drivers/net/sk98lin/h/xmac_ii.h [deleted file]
drivers/net/sk98lin/skaddr.c [deleted file]
drivers/net/sk98lin/skdim.c [deleted file]
drivers/net/sk98lin/skethtool.c [deleted file]
drivers/net/sk98lin/skge.c [deleted file]
drivers/net/sk98lin/skgehwt.c [deleted file]
drivers/net/sk98lin/skgeinit.c [deleted file]
drivers/net/sk98lin/skgemib.c [deleted file]
drivers/net/sk98lin/skgepnmi.c [deleted file]
drivers/net/sk98lin/skgesirq.c [deleted file]
drivers/net/sk98lin/ski2c.c [deleted file]
drivers/net/sk98lin/sklm80.c [deleted file]
drivers/net/sk98lin/skqueue.c [deleted file]
drivers/net/sk98lin/skrlmt.c [deleted file]
drivers/net/sk98lin/sktimer.c [deleted file]
drivers/net/sk98lin/skvpd.c [deleted file]
drivers/net/sk98lin/skxmac2.c [deleted file]
drivers/net/sky2.c
drivers/net/sky2.h
drivers/net/sni_82596.c [new file with mode: 0644]
drivers/net/spider_net.c
drivers/net/spider_net.h
drivers/net/starfire.c
drivers/net/sun3_82586.c
drivers/net/sun3lance.c
drivers/net/sunbmac.c
drivers/net/sundance.c
drivers/net/sunhme.c
drivers/net/sunlance.c
drivers/net/sunqe.c
drivers/net/tc35815.c
drivers/net/tg3.c
drivers/net/tg3.h
drivers/net/tlan.c
drivers/net/tokenring/3c359.c
drivers/net/tulip/Kconfig
drivers/net/tulip/de2104x.c
drivers/net/tulip/de4x5.c
drivers/net/tulip/de4x5.h
drivers/net/tulip/dmfe.c
drivers/net/tulip/interrupt.c
drivers/net/tulip/tulip_core.c
drivers/net/tulip/winbond-840.c
drivers/net/tulip/xircom_cb.c
drivers/net/tulip/xircom_tulip_cb.c
drivers/net/tun.c
drivers/net/typhoon.c
drivers/net/ucc_geth.c
drivers/net/usb/catc.c
drivers/net/usb/kaweth.c
drivers/net/usb/usbnet.c
drivers/net/usb/usbnet.h
drivers/net/via-rhine.c
drivers/net/via-velocity.c
drivers/net/wan/pc300_drv.c
drivers/net/wan/pc300too.c
drivers/net/wan/pci200syn.c
drivers/net/wireless/Kconfig
drivers/net/wireless/Makefile
drivers/net/wireless/bcm43xx/bcm43xx_main.c
drivers/net/wireless/bcm43xx/bcm43xx_phy.c
drivers/net/wireless/hostap/hostap_ap.c
drivers/net/wireless/hostap/hostap_config.h
drivers/net/wireless/hostap/hostap_cs.c
drivers/net/wireless/hostap/hostap_ioctl.c
drivers/net/wireless/hostap/hostap_main.c
drivers/net/wireless/hostap/hostap_pci.c
drivers/net/wireless/hostap/hostap_plx.c
drivers/net/wireless/prism54/islpci_hotplug.c
drivers/net/wireless/rtl8187.h [new file with mode: 0644]
drivers/net/wireless/rtl8187_dev.c [new file with mode: 0644]
drivers/net/wireless/rtl8187_rtl8225.c [new file with mode: 0644]
drivers/net/wireless/rtl8187_rtl8225.h [new file with mode: 0644]
drivers/net/wireless/rtl818x.h [new file with mode: 0644]
drivers/net/wireless/wl3501_cs.c
drivers/net/wireless/zd1211rw/Makefile
drivers/net/wireless/zd1211rw/zd_chip.c
drivers/net/wireless/zd1211rw/zd_chip.h
drivers/net/wireless/zd1211rw/zd_rf.c
drivers/net/wireless/zd1211rw/zd_rf.h
drivers/net/wireless/zd1211rw/zd_rf_al2230.c
drivers/net/wireless/zd1211rw/zd_rf_al7230b.c
drivers/net/wireless/zd1211rw/zd_rf_uw2453.c [new file with mode: 0644]
drivers/net/wireless/zd1211rw/zd_usb.c
drivers/net/yellowfin.c
drivers/parisc/pdc_stable.c
drivers/pci/Makefile
drivers/pci/hotplug/acpiphp.h
drivers/pci/hotplug/acpiphp_core.c
drivers/pci/hotplug/acpiphp_glue.c
drivers/pci/hotplug/acpiphp_ibm.c
drivers/pci/hotplug/cpci_hotplug_core.c
drivers/pci/hotplug/cpci_hotplug_pci.c
drivers/pci/hotplug/cpqphp_core.c
drivers/pci/hotplug/pciehp.h
drivers/pci/hotplug/pciehp_ctrl.c
drivers/pci/hotplug/pciehp_hpc.c
drivers/pci/pci-acpi.c
drivers/pci/pci-sysfs.c
drivers/pci/pci.c
drivers/pci/pcie/aer/Kconfig
drivers/pci/pcie/aer/Makefile
drivers/pci/pcie/aer/aerdrv.c
drivers/pci/pcie/aer/aerdrv.h
drivers/pci/pcie/aer/aerdrv_acpi.c
drivers/pci/pcie/aer/aerdrv_core.c
drivers/pci/probe.c
drivers/pci/proc.c
drivers/pci/quirks.c
drivers/pci/rom.c
drivers/pci/search.c
drivers/pci/setup-bus.c
drivers/pci/syscall.c
drivers/pcmcia/socket_sysfs.c
drivers/power/Kconfig [new file with mode: 0644]
drivers/power/Makefile [new file with mode: 0644]
drivers/power/apm_power.c [new file with mode: 0644]
drivers/power/ds2760_battery.c [new file with mode: 0644]
drivers/power/olpc_battery.c [new file with mode: 0644]
drivers/power/pda_power.c [new file with mode: 0644]
drivers/power/pmu_battery.c [new file with mode: 0644]
drivers/power/power_supply.h [new file with mode: 0644]
drivers/power/power_supply_core.c [new file with mode: 0644]
drivers/power/power_supply_leds.c [new file with mode: 0644]
drivers/power/power_supply_sysfs.c [new file with mode: 0644]
drivers/rapidio/rio-sysfs.c
drivers/rtc/rtc-ds1553.c
drivers/rtc/rtc-ds1742.c
drivers/rtc/rtc-vr41xx.c
drivers/rtc/rtc-x1205.c
drivers/s390/block/dasd_proc.c
drivers/s390/char/sclp.h
drivers/s390/char/sclp_chp.c
drivers/s390/char/sclp_info.c
drivers/s390/char/vmcp.c
drivers/s390/char/vmlogrdr.c
drivers/s390/char/zcore.c
drivers/s390/cio/chp.c
drivers/s390/cio/device_id.c
drivers/s390/crypto/ap_bus.c
drivers/s390/crypto/ap_bus.h
drivers/s390/crypto/zcrypt_cex2a.c
drivers/s390/crypto/zcrypt_pcica.c
drivers/s390/crypto/zcrypt_pcicc.c
drivers/s390/crypto/zcrypt_pcixcc.c
drivers/s390/net/qeth_sys.c
drivers/scsi/aic94xx/aic94xx_init.c
drivers/scsi/arcmsr/arcmsr_attr.c
drivers/scsi/ipr.c
drivers/scsi/ips.c
drivers/scsi/libsas/sas_expander.c
drivers/scsi/lpfc/lpfc_attr.c
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/nsp32.c
drivers/scsi/qla2xxx/qla_attr.c
drivers/scsi/qla2xxx/qla_init.c
drivers/serial/Kconfig
drivers/serial/bfin_5xx.c
drivers/serial/jsm/jsm_driver.c
drivers/serial/serial_cs.c
drivers/serial/vr41xx_siu.c
drivers/spi/at25.c
drivers/tc/zs.c
drivers/usb/Kconfig
drivers/usb/Makefile
drivers/usb/atm/cxacru.c
drivers/usb/class/cdc-acm.c
drivers/usb/class/usblp.c
drivers/usb/core/Kconfig
drivers/usb/core/config.c
drivers/usb/core/devices.c
drivers/usb/core/driver.c
drivers/usb/core/file.c
drivers/usb/core/generic.c
drivers/usb/core/hcd-pci.c
drivers/usb/core/hcd.c
drivers/usb/core/hcd.h
drivers/usb/core/hub.c
drivers/usb/core/message.c
drivers/usb/core/quirks.c
drivers/usb/core/sysfs.c
drivers/usb/core/urb.c
drivers/usb/core/usb.c
drivers/usb/core/usb.h
drivers/usb/gadget/Kconfig
drivers/usb/gadget/Makefile
drivers/usb/gadget/at91_udc.c
drivers/usb/gadget/dummy_hcd.c
drivers/usb/gadget/ether.c
drivers/usb/gadget/file_storage.c
drivers/usb/gadget/fsl_usb2_udc.c
drivers/usb/gadget/fsl_usb2_udc.h
drivers/usb/gadget/gadget_chips.h
drivers/usb/gadget/gmidi.c
drivers/usb/gadget/goku_udc.c
drivers/usb/gadget/goku_udc.h
drivers/usb/gadget/inode.c
drivers/usb/gadget/lh7a40x_udc.c
drivers/usb/gadget/m66592-udc.c [new file with mode: 0644]
drivers/usb/gadget/m66592-udc.h [new file with mode: 0644]
drivers/usb/gadget/net2280.c
drivers/usb/gadget/omap_udc.c
drivers/usb/gadget/pxa2xx_udc.c
drivers/usb/gadget/pxa2xx_udc.h
drivers/usb/gadget/rndis.c
drivers/usb/gadget/s3c2410_udc.c [new file with mode: 0644]
drivers/usb/gadget/s3c2410_udc.h [new file with mode: 0644]
drivers/usb/gadget/serial.c
drivers/usb/gadget/zero.c
drivers/usb/host/Kconfig
drivers/usb/host/Makefile
drivers/usb/host/ehci-dbg.c
drivers/usb/host/ehci-fsl.c
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-hub.c
drivers/usb/host/ehci-mem.c
drivers/usb/host/ehci-pci.c
drivers/usb/host/ehci-ppc-soc.c [new file with mode: 0644]
drivers/usb/host/ehci-ps3.c
drivers/usb/host/ehci-q.c
drivers/usb/host/ehci-sched.c
drivers/usb/host/ehci.h
drivers/usb/host/ohci-dbg.c
drivers/usb/host/ohci-hcd.c
drivers/usb/host/ohci-hub.c
drivers/usb/host/ohci-mem.c
drivers/usb/host/ohci-pci.c
drivers/usb/host/ohci-pnx4008.c
drivers/usb/host/ohci-ps3.c
drivers/usb/host/ohci.h
drivers/usb/host/r8a66597-hcd.c [new file with mode: 0644]
drivers/usb/host/r8a66597.h [new file with mode: 0644]
drivers/usb/host/uhci-hcd.c
drivers/usb/misc/adutux.c
drivers/usb/misc/auerswald.c
drivers/usb/misc/berry_charge.c
drivers/usb/misc/idmouse.c
drivers/usb/misc/iowarrior.c
drivers/usb/misc/ldusb.c
drivers/usb/misc/legousbtower.c
drivers/usb/misc/sisusbvga/sisusb.c
drivers/usb/misc/sisusbvga/sisusb_con.c
drivers/usb/misc/sisusbvga/sisusb_init.h
drivers/usb/misc/usblcd.c
drivers/usb/mon/mon_bin.c
drivers/usb/mon/mon_main.c
drivers/usb/mon/mon_text.c
drivers/usb/mon/usb_mon.h
drivers/usb/serial/Kconfig
drivers/usb/serial/Makefile
drivers/usb/serial/aircable.c
drivers/usb/serial/airprime.c
drivers/usb/serial/ark3116.c
drivers/usb/serial/belkin_sa.c
drivers/usb/serial/cyberjack.c
drivers/usb/serial/cypress_m8.c
drivers/usb/serial/digi_acceleport.c
drivers/usb/serial/empeg.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/garmin_gps.c
drivers/usb/serial/generic.c
drivers/usb/serial/io_edgeport.c
drivers/usb/serial/io_fw_down3.h
drivers/usb/serial/io_ti.c
drivers/usb/serial/io_usbvend.h
drivers/usb/serial/ipaq.c
drivers/usb/serial/ipw.c
drivers/usb/serial/ir-usb.c
drivers/usb/serial/keyspan.c
drivers/usb/serial/keyspan.h
drivers/usb/serial/keyspan_pda.c
drivers/usb/serial/keyspan_usa67msg.h [new file with mode: 0644]
drivers/usb/serial/kl5kusb105.c
drivers/usb/serial/kobil_sct.c
drivers/usb/serial/mct_u232.c
drivers/usb/serial/mct_u232.h
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 [new file with mode: 0644]
drivers/usb/serial/oti6858.h [new file with mode: 0644]
drivers/usb/serial/pl2303.c
drivers/usb/serial/safe_serial.c
drivers/usb/serial/sierra.c
drivers/usb/serial/ti_usb_3410_5052.c
drivers/usb/serial/usb-serial.c
drivers/usb/serial/visor.c
drivers/usb/serial/whiteheat.c
drivers/usb/storage/scsiglue.c
drivers/usb/storage/unusual_devs.h
drivers/usb/storage/usb.c
drivers/usb/storage/usb.h
drivers/usb/usb-skeleton.c
drivers/video/aty/radeon_base.c
drivers/video/backlight/backlight.c
drivers/video/backlight/lcd.c
drivers/video/console/Kconfig
drivers/video/kyro/STG4000InitDevice.c
drivers/video/matrox/matroxfb_base.c
drivers/video/matrox/matroxfb_crtc2.h
drivers/video/sis/sis_main.c
drivers/video/sstfb.c
drivers/video/tgafb.c
drivers/w1/slaves/Kconfig
drivers/w1/slaves/Makefile
drivers/w1/slaves/w1_ds2433.c
drivers/w1/slaves/w1_ds2760.c [new file with mode: 0644]
drivers/w1/slaves/w1_ds2760.h [new file with mode: 0644]
drivers/w1/slaves/w1_therm.c
drivers/w1/w1.c
drivers/w1/w1_family.h
drivers/zorro/zorro-sysfs.c
fs/adfs/file.c
fs/affs/file.c
fs/afs/file.c
fs/bad_inode.c
fs/bfs/file.c
fs/bio.c
fs/block_dev.c
fs/cifs/cifsfs.c
fs/coda/file.c
fs/debugfs/inode.c
fs/dlm/Makefile
fs/dlm/config.c
fs/dlm/config.h
fs/dlm/debug_fs.c
fs/dlm/dlm_internal.h
fs/dlm/lock.c
fs/dlm/lock.h
fs/dlm/lockspace.c
fs/dlm/lowcomms.c
fs/dlm/main.c
fs/dlm/member.c
fs/dlm/netlink.c [new file with mode: 0644]
fs/dlm/rcom.c
fs/dlm/recoverd.c
fs/dlm/user.c
fs/ecryptfs/file.c
fs/ecryptfs/main.c
fs/ext2/file.c
fs/ext3/file.c
fs/ext4/file.c
fs/fat/file.c
fs/fuse/file.c
fs/gfs2/Makefile
fs/gfs2/bmap.c
fs/gfs2/daemon.c
fs/gfs2/dir.c
fs/gfs2/dir.h
fs/gfs2/eattr.c
fs/gfs2/glock.c
fs/gfs2/glock.h
fs/gfs2/glops.c
fs/gfs2/incore.h
fs/gfs2/inode.c
fs/gfs2/inode.h
fs/gfs2/locking/dlm/lock.c
fs/gfs2/locking/dlm/lock_dlm.h
fs/gfs2/locking/dlm/mount.c
fs/gfs2/locking/dlm/plock.c
fs/gfs2/locking/dlm/thread.c
fs/gfs2/log.c
fs/gfs2/lops.c
fs/gfs2/lops.h
fs/gfs2/meta_io.c
fs/gfs2/meta_io.h
fs/gfs2/mount.c
fs/gfs2/ondisk.c [deleted file]
fs/gfs2/ops_address.c
fs/gfs2/ops_address.h
fs/gfs2/ops_dentry.c
fs/gfs2/ops_export.c
fs/gfs2/ops_export.h [deleted file]
fs/gfs2/ops_file.c
fs/gfs2/ops_fstype.c
fs/gfs2/ops_fstype.h
fs/gfs2/ops_inode.c
fs/gfs2/ops_super.c
fs/gfs2/ops_vm.c
fs/gfs2/quota.c
fs/gfs2/recovery.c
fs/gfs2/rgrp.c
fs/gfs2/rgrp.h
fs/gfs2/super.c
fs/gfs2/super.h
fs/gfs2/util.c
fs/hfs/inode.c
fs/hfsplus/inode.c
fs/hostfs/hostfs_kern.c
fs/hpfs/file.c
fs/jffs2/file.c
fs/jfs/endian24.h
fs/jfs/file.c
fs/jfs/jfs_debug.c
fs/jfs/jfs_debug.h
fs/jfs/jfs_dinode.h
fs/jfs/jfs_dmap.c
fs/jfs/jfs_dmap.h
fs/jfs/jfs_dtree.c
fs/jfs/jfs_dtree.h
fs/jfs/jfs_extent.c
fs/jfs/jfs_filsys.h
fs/jfs/jfs_imap.c
fs/jfs/jfs_imap.h
fs/jfs/jfs_incore.h
fs/jfs/jfs_logmgr.c
fs/jfs/jfs_logmgr.h
fs/jfs/jfs_metapage.c
fs/jfs/jfs_mount.c
fs/jfs/jfs_txnmgr.c
fs/jfs/jfs_txnmgr.h
fs/jfs/jfs_types.h
fs/jfs/jfs_umount.c
fs/jfs/jfs_xtree.c
fs/jfs/jfs_xtree.h
fs/jfs/namei.c
fs/jfs/resize.c
fs/jfs/xattr.c
fs/minix/file.c
fs/nfs/file.c
fs/nfsd/vfs.c
fs/ntfs/file.c
fs/ocfs2/cluster/masklog.c
fs/ocfs2/file.c
fs/partitions/check.c
fs/partitions/ibm.c
fs/pipe.c
fs/proc/array.c
fs/proc/base.c
fs/qnx4/file.c
fs/ramfs/file-mmu.c
fs/ramfs/file-nommu.c
fs/read_write.c
fs/reiserfs/file.c
fs/seq_file.c
fs/smbfs/file.c
fs/splice.c
fs/sysfs/bin.c
fs/sysfs/dir.c
fs/sysfs/file.c
fs/sysfs/group.c
fs/sysfs/inode.c
fs/sysfs/mount.c
fs/sysfs/symlink.c
fs/sysfs/sysfs.h
fs/sysv/file.c
fs/udf/file.c
fs/ufs/file.c
fs/xfs/linux-2.6/xfs_file.c
fs/xfs/linux-2.6/xfs_linux.h
fs/xfs/linux-2.6/xfs_lrw.c
fs/xfs/linux-2.6/xfs_lrw.h
fs/xfs/linux-2.6/xfs_vnode.h
fs/xfs/xfs_vnodeops.c
include/asm-alpha/pci.h
include/asm-arm/Kbuild
include/asm-arm/arch-at91/at91_dbgu.h
include/asm-arm/arch-at91/at91x40.h [new file with mode: 0644]
include/asm-arm/arch-at91/cpu.h
include/asm-arm/arch-at91/hardware.h
include/asm-arm/arch-at91/timex.h
include/asm-arm/arch-at91/uncompress.h
include/asm-arm/arch-davinci/clock.h [new file with mode: 0644]
include/asm-arm/arch-davinci/gpio.h [new file with mode: 0644]
include/asm-arm/arch-davinci/hardware.h
include/asm-arm/arch-davinci/mux.h [new file with mode: 0644]
include/asm-arm/arch-imx/gpio.h [new file with mode: 0644]
include/asm-arm/arch-imx/imx-regs.h
include/asm-arm/arch-ixp4xx/ixdp425.h
include/asm-arm/arch-ixp4xx/udc.h
include/asm-arm/arch-ixp4xx/uncompress.h
include/asm-arm/arch-ks8695/gpio.h [new file with mode: 0644]
include/asm-arm/arch-pxa/dma.h
include/asm-arm/arch-pxa/entry-macro.S
include/asm-arm/arch-pxa/hardware.h
include/asm-arm/arch-pxa/irqs.h
include/asm-arm/arch-pxa/pm.h
include/asm-arm/arch-pxa/pxa-regs.h
include/asm-arm/arch-pxa/udc.h
include/asm-arm/elf.h
include/asm-arm/hwcap.h [new file with mode: 0644]
include/asm-arm/pci.h
include/asm-arm/ptrace.h
include/asm-arm26/termbits.h
include/asm-avr32/termbits.h
include/asm-blackfin/Kbuild
include/asm-blackfin/bfin-global.h
include/asm-blackfin/cplbinit.h
include/asm-blackfin/fixed_code.h [new file with mode: 0644]
include/asm-blackfin/gpio.h
include/asm-blackfin/hardirq.h
include/asm-blackfin/kgdb.h [new file with mode: 0644]
include/asm-blackfin/mach-bf533/dma.h
include/asm-blackfin/mach-bf533/portmux.h [new file with mode: 0644]
include/asm-blackfin/mach-bf537/dma.h
include/asm-blackfin/mach-bf537/portmux.h [new file with mode: 0644]
include/asm-blackfin/mach-bf548/anomaly.h [new file with mode: 0644]
include/asm-blackfin/mach-bf548/bf548.h [new file with mode: 0644]
include/asm-blackfin/mach-bf548/bfin_serial_5xx.h [new file with mode: 0644]
include/asm-blackfin/mach-bf548/blackfin.h [new file with mode: 0644]
include/asm-blackfin/mach-bf548/cdefBF54x_base.h
include/asm-blackfin/mach-bf548/defBF542.h
include/asm-blackfin/mach-bf548/defBF544.h
include/asm-blackfin/mach-bf548/defBF548.h
include/asm-blackfin/mach-bf548/defBF549.h
include/asm-blackfin/mach-bf548/defBF54x_base.h
include/asm-blackfin/mach-bf548/dma.h [new file with mode: 0644]
include/asm-blackfin/mach-bf548/gpio.h [new file with mode: 0644]
include/asm-blackfin/mach-bf548/irq.h [new file with mode: 0644]
include/asm-blackfin/mach-bf548/mem_init.h [new file with mode: 0644]
include/asm-blackfin/mach-bf548/mem_map.h [new file with mode: 0644]
include/asm-blackfin/mach-bf548/portmux.h [new file with mode: 0644]
include/asm-blackfin/mach-bf561/cdefBF561.h
include/asm-blackfin/mach-bf561/dma.h
include/asm-blackfin/mach-bf561/portmux.h [new file with mode: 0644]
include/asm-blackfin/mach-common/cdef_LPBlackfin.h
include/asm-blackfin/mman.h
include/asm-blackfin/page.h
include/asm-blackfin/portmux.h [new file with mode: 0644]
include/asm-blackfin/termbits.h
include/asm-blackfin/trace.h [new file with mode: 0644]
include/asm-cris/pci.h
include/asm-cris/termbits.h
include/asm-frv/pci.h
include/asm-frv/termbits.h
include/asm-generic/bitops/sched.h
include/asm-h8300/pci.h
include/asm-h8300/termbits.h
include/asm-i386/boot.h
include/asm-i386/bootparam.h [new file with mode: 0644]
include/asm-i386/cpufeature.h
include/asm-i386/e820.h
include/asm-i386/pci.h
include/asm-i386/processor.h
include/asm-i386/required-features.h
include/asm-i386/setup.h
include/asm-ia64/mca.h
include/asm-ia64/pci.h
include/asm-ia64/sn/sn_sal.h
include/asm-ia64/termbits.h
include/asm-m32r/termbits.h
include/asm-m68k/pci.h
include/asm-m68k/termbits.h
include/asm-m68knommu/pci.h
include/asm-mips/addrspace.h
include/asm-mips/bootinfo.h
include/asm-mips/cacheops.h
include/asm-mips/compat.h
include/asm-mips/cpu-features.h
include/asm-mips/cpu.h
include/asm-mips/div64.h
include/asm-mips/gpio.h [new file with mode: 0644]
include/asm-mips/io.h
include/asm-mips/irq.h
include/asm-mips/lasat/ds1603.h [deleted file]
include/asm-mips/lasat/eeprom.h [deleted file]
include/asm-mips/lasat/head.h [deleted file]
include/asm-mips/lasat/lasat.h [deleted file]
include/asm-mips/lasat/lasatint.h [deleted file]
include/asm-mips/lasat/picvue.h [deleted file]
include/asm-mips/lasat/serial.h [deleted file]
include/asm-mips/mach-au1x00/au1xxx_gpio.h [deleted file]
include/asm-mips/mach-au1x00/au1xxx_ide.h
include/asm-mips/mach-au1x00/gpio.h [new file with mode: 0644]
include/asm-mips/mach-au1x00/ioremap.h
include/asm-mips/mach-cobalt/cobalt.h
include/asm-mips/mach-ev64120/mach-gt64120.h [deleted file]
include/asm-mips/mach-generic/gpio.h [new file with mode: 0644]
include/asm-mips/mach-generic/ioremap.h
include/asm-mips/mach-generic/spaces.h
include/asm-mips/mach-ip22/spaces.h
include/asm-mips/mach-ip27/spaces.h
include/asm-mips/mach-ip32/spaces.h [deleted file]
include/asm-mips/mach-jmr3927/ioremap.h [new file with mode: 0644]
include/asm-mips/mach-lasat/mach-gt64120.h [deleted file]
include/asm-mips/mach-lemote/dma-coherence.h [new file with mode: 0644]
include/asm-mips/mach-lemote/mc146818rtc.h [new file with mode: 0644]
include/asm-mips/mach-mips/kernel-entry-init.h [new file with mode: 0644]
include/asm-mips/mach-mipssim/cpu-feature-overrides.h [moved from include/asm-mips/mach-sim/cpu-feature-overrides.h with 100% similarity]
include/asm-mips/mach-ocelot3/cpu-feature-overrides.h [deleted file]
include/asm-mips/mach-tx49xx/ioremap.h [new file with mode: 0644]
include/asm-mips/mips-boards/bonito64.h
include/asm-mips/mipsregs.h
include/asm-mips/module.h
include/asm-mips/nile4.h [deleted file]
include/asm-mips/page.h
include/asm-mips/pci.h
include/asm-mips/pmc-sierra/msp71xx/msp_cic_int.h [new file with mode: 0644]
include/asm-mips/pmc-sierra/msp71xx/msp_int.h [new file with mode: 0644]
include/asm-mips/pmc-sierra/msp71xx/msp_pci.h [new file with mode: 0644]
include/asm-mips/pmc-sierra/msp71xx/msp_prom.h [new file with mode: 0644]
include/asm-mips/pmc-sierra/msp71xx/msp_regops.h [new file with mode: 0644]
include/asm-mips/pmc-sierra/msp71xx/msp_regs.h [new file with mode: 0644]
include/asm-mips/pmc-sierra/msp71xx/msp_slp_int.h [new file with mode: 0644]
include/asm-mips/processor.h
include/asm-mips/rtc.h [deleted file]
include/asm-mips/serial.h
include/asm-mips/smp.h
include/asm-mips/sni.h
include/asm-mips/system.h
include/asm-mips/termbits.h
include/asm-mips/tlbdebug.h
include/asm-mips/tx4938/rbtx4938.h
include/asm-mips/tx4938/spi.h
include/asm-mips/vr41xx/giu.h
include/asm-mips/vr41xx/siu.h
include/asm-mips/war.h
include/asm-mips/watch.h [deleted file]
include/asm-parisc/pci.h
include/asm-parisc/termbits.h
include/asm-powerpc/dma-mapping.h
include/asm-powerpc/pci.h
include/asm-ppc/pci.h
include/asm-s390/atomic.h
include/asm-s390/cmb.h
include/asm-s390/processor.h
include/asm-s390/sclp.h
include/asm-s390/sfp-machine.h
include/asm-s390/sfp-util.h
include/asm-s390/termbits.h
include/asm-sh/pci.h
include/asm-sh/termbits.h
include/asm-sh64/pci.h
include/asm-sparc/pci.h
include/asm-sparc64/pci.h
include/asm-v850/pci.h
include/asm-v850/rte_cb.h
include/asm-v850/termbits.h
include/asm-x86_64/alternative.h
include/asm-x86_64/boot.h
include/asm-x86_64/bootparam.h [new file with mode: 0644]
include/asm-x86_64/cpufeature.h
include/asm-x86_64/e820.h
include/asm-x86_64/pci.h
include/asm-x86_64/processor.h
include/asm-x86_64/required-features.h [new file with mode: 0644]
include/asm-x86_64/segment.h
include/asm-xtensa/pci.h
include/asm-xtensa/termbits.h
include/linux/Kbuild
include/linux/aer.h
include/linux/ata.h
include/linux/blkdev.h
include/linux/debugfs.h
include/linux/device.h
include/linux/dlm.h
include/linux/dlm_device.h
include/linux/dlm_netlink.h [new file with mode: 0644]
include/linux/dmi.h
include/linux/edd.h
include/linux/eeprom_93cx6.h [new file with mode: 0644]
include/linux/etherdevice.h
include/linux/firewire-cdev.h
include/linux/fs.h
include/linux/gfs2_ondisk.h
include/linux/gpio_mouse.h [new file with mode: 0644]
include/linux/hardirq.h
include/linux/hid.h
include/linux/i2c.h
include/linux/ide.h
include/linux/idr.h
include/linux/if_link.h
include/linux/if_ppp.h
include/linux/if_pppol2tp.h [new file with mode: 0644]
include/linux/if_pppox.h
include/linux/if_tun.h
include/linux/if_vlan.h
include/linux/input.h
include/linux/ioprio.h
include/linux/ip_mp_alg.h [deleted file]
include/linux/ipv6.h
include/linux/irda.h
include/linux/kobject.h
include/linux/ktime.h
include/linux/libata.h
include/linux/lzo.h [new file with mode: 0644]
include/linux/mlx4/device.h
include/linux/mlx4/qp.h
include/linux/mv643xx.h
include/linux/netdevice.h
include/linux/netfilter.h
include/linux/netfilter/nf_conntrack_pptp.h
include/linux/netfilter/x_tables.h
include/linux/netfilter/xt_u32.h [new file with mode: 0644]
include/linux/netfilter_ipv4/ipt_CLUSTERIP.h
include/linux/netfilter_ipv6/ip6_tables.h
include/linux/pata_platform.h
include/linux/pci.h
include/linux/pci_ids.h
include/linux/pda_power.h [new file with mode: 0644]
include/linux/pipe_fs_i.h
include/linux/pkt_cls.h
include/linux/pkt_sched.h
include/linux/pm.h
include/linux/power_supply.h [new file with mode: 0644]
include/linux/rtnetlink.h
include/linux/sched.h
include/linux/screen_info.h
include/linux/security.h
include/linux/seq_file.h
include/linux/serio.h
include/linux/skbuff.h
include/linux/socket.h
include/linux/splice.h [new file with mode: 0644]
include/linux/sunrpc/svc.h
include/linux/sysdev.h
include/linux/sysfs.h
include/linux/topology.h
include/linux/udp.h
include/linux/usb.h
include/linux/usb/Kbuild
include/linux/usb/gadgetfs.h [moved from include/linux/usb_gadgetfs.h with 74% similarity]
include/linux/usb/quirks.h
include/linux/usb/serial.h
include/linux/usb_gadget.h
include/linux/wait.h
include/net/act_api.h
include/net/addrconf.h
include/net/af_unix.h
include/net/ax88796.h [new file with mode: 0644]
include/net/bluetooth/hci.h
include/net/bluetooth/hci_core.h
include/net/bluetooth/rfcomm.h
include/net/dn.h
include/net/dst.h
include/net/flow.h
include/net/ip_fib.h
include/net/ip_mp_alg.h [deleted file]
include/net/ipv6.h
include/net/irda/irda.h
include/net/irda/irlap.h
include/net/mip6.h
include/net/netfilter/ipv4/nf_conntrack_ipv4.h
include/net/netfilter/nf_conntrack.h
include/net/netfilter/nf_conntrack_core.h
include/net/netfilter/nf_conntrack_ecache.h
include/net/netfilter/nf_conntrack_expect.h
include/net/netfilter/nf_conntrack_extend.h [new file with mode: 0644]
include/net/netfilter/nf_conntrack_helper.h
include/net/netfilter/nf_conntrack_l3proto.h
include/net/netfilter/nf_conntrack_tuple.h
include/net/netfilter/nf_nat.h
include/net/netfilter/nf_nat_core.h
include/net/netlink.h
include/net/pkt_cls.h
include/net/rawv6.h
include/net/route.h
include/net/rtnetlink.h
include/net/tipc/tipc_port.h
include/net/xfrm.h
include/pcmcia/ciscode.h
include/rdma/ib_cm.h
include/rdma/ib_mad.h
init/Kconfig
init/main.c
kernel/delayacct.c
kernel/exit.c
kernel/fork.c
kernel/module.c
kernel/params.c
kernel/posix-cpu-timers.c
kernel/relay.c
kernel/sched.c
kernel/sched_debug.c [new file with mode: 0644]
kernel/sched_fair.c [new file with mode: 0644]
kernel/sched_idletask.c [new file with mode: 0644]
kernel/sched_rt.c [new file with mode: 0644]
kernel/sched_stats.h [new file with mode: 0644]
kernel/softirq.c
kernel/sysctl.c
lib/Kconfig
lib/Kconfig.debug
lib/Makefile
lib/idr.c
lib/kobject.c
lib/lzo/Makefile [new file with mode: 0644]
lib/lzo/lzo1x_compress.c [new file with mode: 0644]
lib/lzo/lzo1x_decompress.c [new file with mode: 0644]
lib/lzo/lzodefs.h [new file with mode: 0644]
mm/filemap.c
mm/filemap_xip.c
mm/mmap.c
mm/mremap.c
mm/nommu.c
mm/shmem.c
net/802/tr.c
net/8021q/Makefile
net/8021q/vlan.c
net/8021q/vlan.h
net/8021q/vlan_dev.c
net/8021q/vlan_netlink.c [new file with mode: 0644]
net/8021q/vlanproc.c
net/Makefile
net/appletalk/aarp.c
net/appletalk/atalk_proc.c
net/atm/br2684.c
net/atm/clip.c
net/atm/lec.c
net/atm/mpoa_proc.c
net/atm/proc.c
net/ax25/af_ax25.c
net/ax25/ax25_route.c
net/ax25/ax25_uid.c
net/bluetooth/hci_conn.c
net/bluetooth/hci_core.c
net/bluetooth/hci_event.c
net/bluetooth/rfcomm/tty.c
net/bridge/br_if.c
net/bridge/br_sysfs_br.c
net/bridge/br_sysfs_if.c
net/core/dev.c
net/core/dev_mcast.c
net/core/gen_estimator.c
net/core/netpoll.c
net/core/pktgen.c
net/core/rtnetlink.c
net/core/skbuff.c
net/core/sock.c
net/dccp/ccids/ccid3.c
net/dccp/ccids/ccid3.h
net/dccp/ccids/lib/loss_interval.c
net/dccp/ccids/lib/loss_interval.h
net/dccp/dccp.h
net/dccp/ipv6.c
net/decnet/af_decnet.c
net/decnet/dn_dev.c
net/decnet/dn_neigh.c
net/decnet/dn_route.c
net/ethernet/eth.c
net/ieee80211/softmac/ieee80211softmac_module.c
net/ipv4/Kconfig
net/ipv4/Makefile
net/ipv4/af_inet.c
net/ipv4/ah4.c
net/ipv4/esp4.c
net/ipv4/fib_frontend.c
net/ipv4/fib_semantics.c
net/ipv4/ip_gre.c
net/ipv4/ip_output.c
net/ipv4/ipcomp.c
net/ipv4/ipip.c
net/ipv4/ipvs/ip_vs_app.c
net/ipv4/ipvs/ip_vs_conn.c
net/ipv4/ipvs/ip_vs_ctl.c
net/ipv4/multipath.c [deleted file]
net/ipv4/multipath_drr.c [deleted file]
net/ipv4/multipath_random.c [deleted file]
net/ipv4/multipath_rr.c [deleted file]
net/ipv4/multipath_wrandom.c [deleted file]
net/ipv4/netfilter/Kconfig
net/ipv4/netfilter/arp_tables.c
net/ipv4/netfilter/arpt_mangle.c
net/ipv4/netfilter/ip_tables.c
net/ipv4/netfilter/ipt_CLUSTERIP.c
net/ipv4/netfilter/ipt_ECN.c
net/ipv4/netfilter/ipt_LOG.c
net/ipv4/netfilter/ipt_MASQUERADE.c
net/ipv4/netfilter/ipt_NETMAP.c
net/ipv4/netfilter/ipt_REDIRECT.c
net/ipv4/netfilter/ipt_REJECT.c
net/ipv4/netfilter/ipt_SAME.c
net/ipv4/netfilter/ipt_TOS.c
net/ipv4/netfilter/ipt_TTL.c
net/ipv4/netfilter/ipt_ULOG.c
net/ipv4/netfilter/ipt_addrtype.c
net/ipv4/netfilter/ipt_ah.c
net/ipv4/netfilter/ipt_ecn.c
net/ipv4/netfilter/ipt_iprange.c
net/ipv4/netfilter/ipt_owner.c
net/ipv4/netfilter/ipt_recent.c
net/ipv4/netfilter/ipt_tos.c
net/ipv4/netfilter/ipt_ttl.c
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
net/ipv4/netfilter/nf_conntrack_proto_icmp.c
net/ipv4/netfilter/nf_nat_amanda.c
net/ipv4/netfilter/nf_nat_core.c
net/ipv4/netfilter/nf_nat_ftp.c
net/ipv4/netfilter/nf_nat_h323.c
net/ipv4/netfilter/nf_nat_helper.c
net/ipv4/netfilter/nf_nat_irc.c
net/ipv4/netfilter/nf_nat_pptp.c
net/ipv4/netfilter/nf_nat_proto_gre.c
net/ipv4/netfilter/nf_nat_rule.c
net/ipv4/netfilter/nf_nat_sip.c
net/ipv4/netfilter/nf_nat_snmp_basic.c
net/ipv4/netfilter/nf_nat_standalone.c
net/ipv4/netfilter/nf_nat_tftp.c
net/ipv4/route.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_output.c
net/ipv4/tcp_probe.c
net/ipv4/udp.c
net/ipv4/xfrm4_input.c
net/ipv4/xfrm4_tunnel.c
net/ipv6/Kconfig
net/ipv6/Makefile
net/ipv6/addrconf.c
net/ipv6/af_inet6.c
net/ipv6/ah6.c
net/ipv6/anycast.c
net/ipv6/datagram.c
net/ipv6/esp6.c
net/ipv6/exthdrs.c
net/ipv6/icmp.c
net/ipv6/ip6_flowlabel.c
net/ipv6/ip6_output.c
net/ipv6/ip6_tunnel.c
net/ipv6/ipcomp6.c
net/ipv6/ipv6_sockglue.c
net/ipv6/mcast.c
net/ipv6/mip6.c
net/ipv6/netfilter/ip6_tables.c
net/ipv6/netfilter/ip6t_HL.c
net/ipv6/netfilter/ip6t_LOG.c
net/ipv6/netfilter/ip6t_REJECT.c
net/ipv6/netfilter/ip6t_ah.c
net/ipv6/netfilter/ip6t_eui64.c
net/ipv6/netfilter/ip6t_frag.c
net/ipv6/netfilter/ip6t_hbh.c
net/ipv6/netfilter/ip6t_hl.c
net/ipv6/netfilter/ip6t_ipv6header.c
net/ipv6/netfilter/ip6t_mh.c
net/ipv6/netfilter/ip6t_owner.c
net/ipv6/netfilter/ip6t_rt.c
net/ipv6/netfilter/ip6table_mangle.c
net/ipv6/netfilter/ip6table_raw.c
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
net/ipv6/netfilter/nf_conntrack_reasm.c
net/ipv6/raw.c
net/ipv6/sit.c
net/ipv6/tcp_ipv6.c
net/ipv6/xfrm6_policy.c
net/ipv6/xfrm6_state.c
net/ipv6/xfrm6_tunnel.c
net/ipx/ipx_proc.c
net/irda/Makefile
net/irda/discovery.c
net/irda/ircomm/ircomm_core.c
net/irda/iriap.c
net/irda/irlan/irlan_common.c
net/irda/irlap.c
net/irda/irlap_frame.c
net/irda/irlmp.c
net/irda/irmod.c
net/irda/irnetlink.c [new file with mode: 0644]
net/irda/irttp.c
net/llc/llc_proc.c
net/mac80211/ieee80211_ioctl.c
net/mac80211/rc80211_simple.c
net/netfilter/Kconfig
net/netfilter/Makefile
net/netfilter/core.c
net/netfilter/nf_conntrack_amanda.c
net/netfilter/nf_conntrack_core.c
net/netfilter/nf_conntrack_ecache.c
net/netfilter/nf_conntrack_expect.c
net/netfilter/nf_conntrack_extend.c [new file with mode: 0644]
net/netfilter/nf_conntrack_ftp.c
net/netfilter/nf_conntrack_h323_asn1.c
net/netfilter/nf_conntrack_h323_main.c
net/netfilter/nf_conntrack_helper.c
net/netfilter/nf_conntrack_irc.c
net/netfilter/nf_conntrack_l3proto_generic.c
net/netfilter/nf_conntrack_netbios_ns.c
net/netfilter/nf_conntrack_netlink.c
net/netfilter/nf_conntrack_pptp.c
net/netfilter/nf_conntrack_proto_gre.c
net/netfilter/nf_conntrack_proto_sctp.c
net/netfilter/nf_conntrack_proto_tcp.c
net/netfilter/nf_conntrack_sane.c
net/netfilter/nf_conntrack_sip.c
net/netfilter/nf_conntrack_standalone.c
net/netfilter/nf_conntrack_tftp.c
net/netfilter/nf_log.c
net/netfilter/nf_queue.c
net/netfilter/nfnetlink_log.c
net/netfilter/nfnetlink_queue.c
net/netfilter/x_tables.c
net/netfilter/xt_CLASSIFY.c
net/netfilter/xt_CONNMARK.c
net/netfilter/xt_CONNSECMARK.c
net/netfilter/xt_DSCP.c
net/netfilter/xt_MARK.c
net/netfilter/xt_NFLOG.c
net/netfilter/xt_NFQUEUE.c
net/netfilter/xt_NOTRACK.c
net/netfilter/xt_SECMARK.c
net/netfilter/xt_TCPMSS.c
net/netfilter/xt_TRACE.c [new file with mode: 0644]
net/netfilter/xt_comment.c
net/netfilter/xt_connbytes.c
net/netfilter/xt_connmark.c
net/netfilter/xt_conntrack.c
net/netfilter/xt_dccp.c
net/netfilter/xt_dscp.c
net/netfilter/xt_esp.c
net/netfilter/xt_hashlimit.c
net/netfilter/xt_helper.c
net/netfilter/xt_length.c
net/netfilter/xt_limit.c
net/netfilter/xt_mac.c
net/netfilter/xt_mark.c
net/netfilter/xt_multiport.c
net/netfilter/xt_physdev.c
net/netfilter/xt_pkttype.c
net/netfilter/xt_policy.c
net/netfilter/xt_quota.c
net/netfilter/xt_realm.c
net/netfilter/xt_sctp.c
net/netfilter/xt_state.c
net/netfilter/xt_statistic.c
net/netfilter/xt_string.c
net/netfilter/xt_tcpmss.c
net/netfilter/xt_tcpudp.c
net/netfilter/xt_u32.c [new file with mode: 0644]
net/netlink/af_netlink.c
net/netlink/attr.c
net/netrom/af_netrom.c
net/netrom/nr_route.c
net/packet/af_packet.c
net/rose/af_rose.c
net/rose/rose_route.c
net/rxrpc/ar-proc.c
net/sched/Kconfig
net/sched/act_api.c
net/sched/act_gact.c
net/sched/act_ipt.c
net/sched/act_mirred.c
net/sched/act_pedit.c
net/sched/act_police.c
net/sched/act_simple.c
net/sched/cls_api.c
net/sched/cls_basic.c
net/sched/cls_fw.c
net/sched/cls_route.c
net/sched/cls_rsvp.c
net/sched/cls_rsvp6.c
net/sched/cls_tcindex.c
net/sched/cls_u32.c
net/sched/em_cmp.c
net/sched/em_meta.c
net/sched/em_nbyte.c
net/sched/em_text.c
net/sched/em_u32.c
net/sched/ematch.c
net/sched/sch_api.c
net/sched/sch_atm.c
net/sched/sch_blackhole.c
net/sched/sch_cbq.c
net/sched/sch_dsmark.c
net/sched/sch_fifo.c
net/sched/sch_generic.c
net/sched/sch_gred.c
net/sched/sch_hfsc.c
net/sched/sch_htb.c
net/sched/sch_ingress.c
net/sched/sch_netem.c
net/sched/sch_prio.c
net/sched/sch_red.c
net/sched/sch_sfq.c
net/sched/sch_tbf.c
net/sched/sch_teql.c
net/sctp/proc.c
net/sunrpc/auth_gss/svcauth_gss.c
net/sunrpc/cache.c
net/sunrpc/svc.c
net/tipc/eth_media.c
net/tipc/link.c
net/tipc/port.c
net/tipc/port.h
net/tipc/socket.c
net/unix/af_unix.c
net/unix/garbage.c
net/wanrouter/wanproc.c
net/x25/x25_proc.c
net/xfrm/xfrm_state.c
security/dummy.c
security/security.c
security/selinux/avc.c
security/selinux/hooks.c
security/selinux/include/av_perm_to_string.h
security/selinux/include/av_permissions.h
security/selinux/include/avc.h
security/selinux/include/class_to_string.h
security/selinux/include/flask.h
security/selinux/include/security.h
security/selinux/netlabel.c
security/selinux/selinuxfs.c
security/selinux/ss/policydb.c
security/selinux/ss/services.c
sound/oss/emu10k1/main.c
sound/oss/es1371.c
sound/pci/ali5451/ali5451.c
sound/pci/atiixp.c
sound/pci/atiixp_modem.c
sound/pci/au88x0/au88x0.c
sound/pci/ca0106/ca0106.h
sound/pci/ca0106/ca0106_main.c
sound/pci/emu10k1/emu10k1_main.c
sound/pci/emu10k1/emu10k1x.c
sound/pci/ens1370.c
sound/pci/fm801.c
sound/pci/via82xx.c
sound/pci/via82xx_modem.c
sound/pci/ymfpci/ymfpci_main.c
sound/ppc/beep.c

diff --git a/Documentation/ABI/removed/raw1394_legacy_isochronous b/Documentation/ABI/removed/raw1394_legacy_isochronous
new file mode 100644 (file)
index 0000000..1b62962
--- /dev/null
@@ -0,0 +1,16 @@
+What:          legacy isochronous ABI of raw1394 (1st generation iso ABI)
+Date:          June 2007 (scheduled), removed in kernel v2.6.23
+Contact:       linux1394-devel@lists.sourceforge.net
+Description:
+       The two request types RAW1394_REQ_ISO_SEND, RAW1394_REQ_ISO_LISTEN have
+       been deprecated for quite some time.  They are very inefficient as they
+       come with high interrupt load and several layers of callbacks for each
+       packet.  Because of these deficiencies, the video1394 and dv1394 drivers
+       and the 3rd-generation isochronous ABI in raw1394 (rawiso) were created.
+
+Users:
+       libraw1394 users via the long deprecated API raw1394_iso_write,
+       raw1394_start_iso_write, raw1394_start_iso_rcv, raw1394_stop_iso_rcv
+
+       libdc1394, which optionally uses these old libraw1394 calls
+       alternatively to the more efficient video1394 ABI
index f9937add033d833e869fb996565bb74ff2f5233d..9734577d171154630f49be83779863ef875d6b7e 100644 (file)
@@ -39,3 +39,16 @@ Description:
                If you want to suspend a device immediately but leave it
                free to wake up in response to I/O requests, you should
                write "0" to power/autosuspend.
+
+What:          /sys/bus/usb/devices/.../power/persist
+Date:          May 2007
+KernelVersion: 2.6.23
+Contact:       Alan Stern <stern@rowland.harvard.edu>
+Description:
+               If CONFIG_USB_PERSIST is set, then each USB device directory
+               will contain a file named power/persist.  The file holds a
+               boolean value (0 or 1) indicating whether or not the
+               "USB-Persist" facility is enabled for the device.  Since the
+               facility is inherently dangerous, it is disabled by default
+               for all devices except hubs.  For more information, see
+               Documentation/usb/persist.txt.
index 028614cdd0624291f630d3cdda899cf02335ed2b..e07f2530326b3afcbe69e77720833435e75e57d7 100644 (file)
@@ -664,109 +664,6 @@ It is that simple.
 Well, not for some odd devices.  See the next section for information
 about that.
 
-       DAC Addressing for Address Space Hungry Devices
-
-There exists a class of devices which do not mesh well with the PCI
-DMA mapping API.  By definition these "mappings" are a finite
-resource.  The number of total available mappings per bus is platform
-specific, but there will always be a reasonable amount.
-
-What is "reasonable"?  Reasonable means that networking and block I/O
-devices need not worry about using too many mappings.
-
-As an example of a problematic device, consider compute cluster cards.
-They can potentially need to access gigabytes of memory at once via
-DMA.  Dynamic mappings are unsuitable for this kind of access pattern.
-
-To this end we've provided a small API by which a device driver
-may use DAC cycles to directly address all of physical memory.
-Not all platforms support this, but most do.  It is easy to determine
-whether the platform will work properly at probe time.
-
-First, understand that there may be a SEVERE performance penalty for
-using these interfaces on some platforms.  Therefore, you MUST only
-use these interfaces if it is absolutely required.  %99 of devices can
-use the normal APIs without any problems.
-
-Note that for streaming type mappings you must either use these
-interfaces, or the dynamic mapping interfaces above.  You may not mix
-usage of both for the same device.  Such an act is illegal and is
-guaranteed to put a banana in your tailpipe.
-
-However, consistent mappings may in fact be used in conjunction with
-these interfaces.  Remember that, as defined, consistent mappings are
-always going to be SAC addressable.
-
-The first thing your driver needs to do is query the PCI platform
-layer if it is capable of handling your devices DAC addressing
-capabilities:
-
-       int pci_dac_dma_supported(struct pci_dev *hwdev, u64 mask);
-
-You may not use the following interfaces if this routine fails.
-
-Next, DMA addresses using this API are kept track of using the
-dma64_addr_t type.  It is guaranteed to be big enough to hold any
-DAC address the platform layer will give to you from the following
-routines.  If you have consistent mappings as well, you still
-use plain dma_addr_t to keep track of those.
-
-All mappings obtained here will be direct.  The mappings are not
-translated, and this is the purpose of this dialect of the DMA API.
-
-All routines work with page/offset pairs.  This is the _ONLY_ way to 
-portably refer to any piece of memory.  If you have a cpu pointer
-(which may be validly DMA'd too) you may easily obtain the page
-and offset using something like this:
-
-       struct page *page = virt_to_page(ptr);
-       unsigned long offset = offset_in_page(ptr);
-
-Here are the interfaces:
-
-       dma64_addr_t pci_dac_page_to_dma(struct pci_dev *pdev,
-                                        struct page *page,
-                                        unsigned long offset,
-                                        int direction);
-
-The DAC address for the tuple PAGE/OFFSET are returned.  The direction
-argument is the same as for pci_{map,unmap}_single().  The same rules
-for cpu/device access apply here as for the streaming mapping
-interfaces.  To reiterate:
-
-       The cpu may touch the buffer before pci_dac_page_to_dma.
-       The device may touch the buffer after pci_dac_page_to_dma
-       is made, but the cpu may NOT.
-
-When the DMA transfer is complete, invoke:
-
-       void pci_dac_dma_sync_single_for_cpu(struct pci_dev *pdev,
-                                            dma64_addr_t dma_addr,
-                                            size_t len, int direction);
-
-This must be done before the CPU looks at the buffer again.
-This interface behaves identically to pci_dma_sync_{single,sg}_for_cpu().
-
-And likewise, if you wish to let the device get back at the buffer after
-the cpu has read/written it, invoke:
-
-       void pci_dac_dma_sync_single_for_device(struct pci_dev *pdev,
-                                               dma64_addr_t dma_addr,
-                                               size_t len, int direction);
-
-before letting the device access the DMA area again.
-
-If you need to get back to the PAGE/OFFSET tuple from a dma64_addr_t
-the following interfaces are provided:
-
-       struct page *pci_dac_dma_to_page(struct pci_dev *pdev,
-                                        dma64_addr_t dma_addr);
-       unsigned long pci_dac_dma_to_offset(struct pci_dev *pdev,
-                                           dma64_addr_t dma_addr);
-
-This is possible with the DAC interfaces purely because they are
-not translated in any way.
-
                Optimizing Unmap State Space Consumption
 
 On many platforms, pci_unmap_{single,page}() is simply a nop.
index 38f88b6ae405a16606134db8aedf7a89ccf8e643..46bcff2849bddbffad2817304bbc8964b1cba6e5 100644 (file)
@@ -643,4 +643,70 @@ X!Idrivers/video/console/fonts.c
 !Edrivers/spi/spi.c
   </chapter>
 
+  <chapter id="i2c">
+     <title>I<superscript>2</superscript>C and SMBus Subsystem</title>
+
+     <para>
+       I<superscript>2</superscript>C (or without fancy typography, "I2C")
+       is an acronym for the "Inter-IC" bus, a simple bus protocol which is
+       widely used where low data rate communications suffice.
+       Since it's also a licensed trademark, some vendors use another
+       name (such as "Two-Wire Interface", TWI) for the same bus.
+       I2C only needs two signals (SCL for clock, SDA for data), conserving
+       board real estate and minimizing signal quality issues.
+       Most I2C devices use seven bit addresses, and bus speeds of up
+       to 400 kHz; there's a high speed extension (3.4 MHz) that's not yet
+       found wide use.
+       I2C is a multi-master bus; open drain signaling is used to
+       arbitrate between masters, as well as to handshake and to
+       synchronize clocks from slower clients.
+     </para>
+
+     <para>
+       The Linux I2C programming interfaces support only the master
+       side of bus interactions, not the slave side.
+       The programming interface is structured around two kinds of driver,
+       and two kinds of device.
+       An I2C "Adapter Driver" abstracts the controller hardware; it binds
+       to a physical device (perhaps a PCI device or platform_device) and
+       exposes a <structname>struct i2c_adapter</structname> representing
+       each I2C bus segment it manages.
+       On each I2C bus segment will be I2C devices represented by a
+       <structname>struct i2c_client</structname>.  Those devices will
+       be bound to a <structname>struct i2c_driver</structname>,
+       which should follow the standard Linux driver model.
+       (At this writing, a legacy model is more widely used.)
+       There are functions to perform various I2C protocol operations; at
+       this writing all such functions are usable only from task context.
+     </para>
+
+     <para>
+       The System Management Bus (SMBus) is a sibling protocol.  Most SMBus
+       systems are also I2C conformant.  The electrical constraints are
+       tighter for SMBus, and it standardizes particular protocol messages
+       and idioms.  Controllers that support I2C can also support most
+       SMBus operations, but SMBus controllers don't support all the protocol
+       options that an I2C controller will.
+       There are functions to perform various SMBus protocol operations,
+       either using I2C primitives or by issuing SMBus commands to
+       i2c_adapter devices which don't support those I2C operations.
+     </para>
+
+!Iinclude/linux/i2c.h
+!Fdrivers/i2c/i2c-boardinfo.c i2c_register_board_info
+!Edrivers/i2c/i2c-core.c
+  </chapter>
+
+  <chapter id="splice">
+      <title>splice API</title>
+  <para>)
+       splice is a method for moving blocks of data around inside the
+       kernel, without continually transferring it between the kernel
+       and user space.
+  </para>
+!Iinclude/linux/splice.h
+!Ffs/splice.c
+  </chapter>
+
+
 </book>
diff --git a/Documentation/blackfin/kgdb.txt b/Documentation/blackfin/kgdb.txt
new file mode 100644 (file)
index 0000000..84f6a48
--- /dev/null
@@ -0,0 +1,155 @@
+                       A Simple Guide to Configure KGDB
+
+                       Sonic Zhang <sonic.zhang@analog.com>
+                               Aug. 24th 2006
+
+
+This KGDB patch enables the kernel developer to do source level debugging on
+the kernel for the Blackfin architecture.  The debugging works over either the
+ethernet interface or one of the uarts.  Both software breakpoints and
+hardware breakpoints are supported in this version.
+http://docs.blackfin.uclinux.org/doku.php?id=kgdb
+
+
+2 known issues:
+1. This bug:
+       http://blackfin.uclinux.org/tracker/index.php?func=detail&aid=544&group_id=18&atid=145
+   The GDB client for Blackfin uClinux causes incorrect values of local
+   variables to be displayed when the user breaks the running of kernel in GDB.
+2. Because of a hardware bug in Blackfin 533 v1.0.3:
+       05000067 - Watchpoints (Hardware Breakpoints) are not supported
+   Hardware breakpoints cannot be set properly.
+
+
+Debug over Ethernet:
+1. Compile and install the cross platform version of gdb for blackfin, which
+   can be found at $(BINROOT)/bfin-elf-gdb.
+
+2. Apply this patch to the 2.6.x kernel.  Select the menuconfig option under
+   "Kernel hacking" -> "Kernel debugging" -> "KGDB: kernel debug with remote gdb".
+   With this selected, option "Full Symbolic/Source Debugging support" and 
+   "Compile the kernel with frame pointers" are also selected.
+
+3. Select option "KGDB: connect over (Ethernet)".  Add "kgdboe=@target-IP/,@host-IP/" to
+   the option "Compiled-in Kernel Boot Parameter" under "Kernel hacking".
+
+4. Connect minicom to the serial port and boot the kernel image.
+
+5. Configure the IP "/> ifconfig eth0 target-IP"
+
+6. Start GDB client "bfin-elf-gdb vmlinux".
+
+7. Connect to the target "(gdb) target remote udp:target-IP:6443".
+
+8. Set software breakpoint "(gdb) break sys_open".
+
+9. Continue "(gdb) c".
+
+10. Run ls in the target console "/> ls".
+
+11. Breakpoint hits. "Breakpoint 1: sys_open(..."
+
+12. Display local variables and function paramters.
+    (*) This operation gives wrong results, see known issue 1.
+
+13. Single stepping "(gdb) si".
+
+14. Remove breakpoint 1. "(gdb) del 1"
+
+15. Set hardware breakpoint "(gdb) hbreak sys_open".
+
+16. Continue "(gdb) c".
+
+17. Run ls in the target console "/> ls".
+
+18. Hardware breakpoint hits. "Breakpoint 1: sys_open(...".
+    (*) This hardware breakpoint will not be hit, see known issue 2.
+
+19. Continue "(gdb) c".
+
+20. Interrupt the target in GDB "Ctrl+C".
+
+21. Detach from the target "(gdb) detach".
+
+22. Exit GDB "(gdb) quit".
+
+
+Debug over the UART:
+
+1. Compile and install the cross platform version of gdb for blackfin, which
+   can be found at $(BINROOT)/bfin-elf-gdb.
+
+2. Apply this patch to the 2.6.x kernel.  Select the menuconfig option under
+   "Kernel hacking" -> "Kernel debugging" -> "KGDB: kernel debug with remote gdb".
+   With this selected, option "Full Symbolic/Source Debugging support" and 
+   "Compile the kernel with frame pointers" are also selected.
+
+3. Select option "KGDB: connect over (UART)".  Set "KGDB: UART port number" to be
+   a different one from the console.  Don't forget to change the mode of
+   blackfin serial driver to PIO.  Otherwise kgdb works incorrectly on UART.
+4. If you want connect to kgdb when the kernel boots, enable
+   "KGDB: Wait for gdb connection early" 
+
+5. Compile kernel.
+
+6. Connect minicom to the serial port of the console and boot the kernel image.
+
+7. Start GDB client "bfin-elf-gdb vmlinux".
+
+8. Set the baud rate in GDB "(gdb) set remotebaud 57600".
+
+9. Connect to the target on the second serial port "(gdb) target remote /dev/ttyS1".
+
+10. Set software breakpoint "(gdb) break sys_open".
+
+11. Continue "(gdb) c". 
+
+12. Run ls in the target console "/> ls". 
+
+13. A breakpoint is hit. "Breakpoint 1: sys_open(..."
+
+14. All other operations are the same as that in KGDB over Ethernet. 
+
+
+Debug over the same UART as console:
+
+1. Compile and install the cross platform version of gdb for blackfin, which
+   can be found at $(BINROOT)/bfin-elf-gdb.
+
+2. Apply this patch to the 2.6.x kernel.  Select the menuconfig option under
+   "Kernel hacking" -> "Kernel debugging" -> "KGDB: kernel debug with remote gdb".
+   With this selected, option "Full Symbolic/Source Debugging support" and 
+   "Compile the kernel with frame pointers" are also selected.
+
+3. Select option "KGDB: connect over UART".  Set "KGDB: UART port number" to console.
+   Don't forget to change the mode of blackfin serial driver to PIO.
+   Otherwise kgdb works incorrectly on UART.
+4. If you want connect to kgdb when the kernel boots, enable
+   "KGDB: Wait for gdb connection early" 
+
+5. Connect minicom to the serial port and boot the kernel image. 
+
+6. (Optional) Ask target to wait for gdb connection by entering Ctrl+A. In minicom, you should enter Ctrl+A+A.
+
+7. Start GDB client "bfin-elf-gdb vmlinux".
+
+8. Set the baud rate in GDB "(gdb) set remotebaud 57600".
+
+9. Connect to the target "(gdb) target remote /dev/ttyS0".
+
+10. Set software breakpoint "(gdb) break sys_open".
+
+11. Continue "(gdb) c". Then enter Ctrl+C twice to stop GDB connection.
+
+12. Run ls in the target console "/> ls". Dummy string can be seen on the console.
+
+13. Then connect the gdb to target again. "(gdb) target remote /dev/ttyS0".
+    Now you will find a breakpoint is hit. "Breakpoint 1: sys_open(..."
+
+14. All other operations are the same as that in KGDB over Ethernet.  The only
+    difference is that after continue command in GDB, please stop GDB
+    connection by 2 "Ctrl+C"s and connect again after breakpoints are hit or
+    Ctrl+A is entered.
index a272c3db80940bd5821e8b2f28068e3fe5d5a65b..7d279f2f5bb26b2b4b54d65f86ee165c65d97b3b 100644 (file)
@@ -82,23 +82,12 @@ including draining and flushing.
 typedef void (prepare_flush_fn)(request_queue_t *q, struct request *rq);
 
 int blk_queue_ordered(request_queue_t *q, unsigned ordered,
-                     prepare_flush_fn *prepare_flush_fn,
-                     unsigned gfp_mask);
-
-int blk_queue_ordered_locked(request_queue_t *q, unsigned ordered,
-                            prepare_flush_fn *prepare_flush_fn,
-                            unsigned gfp_mask);
-
-The only difference between the two functions is whether or not the
-caller is holding q->queue_lock on entry.  The latter expects the
-caller is holding the lock.
+                     prepare_flush_fn *prepare_flush_fn);
 
 @q                     : the queue in question
 @ordered               : the ordered mode the driver/device supports
 @prepare_flush_fn      : this function should prepare @rq such that it
                          flushes cache to physical medium when executed
-@gfp_mask              : gfp_mask used when allocating data structures
-                         for ordered processing
 
 For example, SCSI disk driver's prepare_flush_fn looks like the
 following.
@@ -106,9 +95,10 @@ following.
 static void sd_prepare_flush(request_queue_t *q, struct request *rq)
 {
        memset(rq->cmd, 0, sizeof(rq->cmd));
-       rq->flags |= REQ_BLOCK_PC;
+       rq->cmd_type = REQ_TYPE_BLOCK_PC;
        rq->timeout = SD_TIMEOUT;
        rq->cmd[0] = SYNCHRONIZE_CACHE;
+       rq->cmd_len = 10;
 }
 
 The following seven ordered modes are supported.  The following table
index 7d3f205b0ba50fddc8da631ba9fad29063239256..0599a0c7c026174dce41b5a91f431f2919d95504 100644 (file)
@@ -49,16 +49,6 @@ Who: Adrian Bunk <bunk@stusta.de>
 
 ---------------------------
 
-What:  raw1394: requests of type RAW1394_REQ_ISO_SEND, RAW1394_REQ_ISO_LISTEN
-When:  June 2007
-Why:   Deprecated in favour of the more efficient and robust rawiso interface.
-       Affected are applications which use the deprecated part of libraw1394
-       (raw1394_iso_write, raw1394_start_iso_write, raw1394_start_iso_rcv,
-       raw1394_stop_iso_rcv) or bypass libraw1394.
-Who:   Dan Dennedy <dan@dennedy.org>, Stefan Richter <stefanr@s5r6.in-berlin.de>
-
----------------------------
-
 What:  old NCR53C9x driver
 When:  October 2007
 Why:   Replaced by the much better esp_scsi driver.  Actual low-level
@@ -258,14 +248,6 @@ Who:       Len Brown <len.brown@intel.com>
 
 ---------------------------
 
-What:   sk98lin network driver
-When:   July 2007
-Why:    In kernel tree version of driver is unmaintained. Sk98lin driver
-       replaced by the skge driver. 
-Who:    Stephen Hemminger <shemminger@osdl.org>
-
----------------------------
-
 What:  Compaq touchscreen device emulation
 When:  Oct 2007
 Files: drivers/input/tsdev.c
@@ -280,25 +262,6 @@ Who:       Richard Purdie <rpurdie@rpsys.net>
 
 ---------------------------
 
-What:  Multipath cached routing support in ipv4
-When:  in 2.6.23
-Why:   Code was merged, then submitter immediately disappeared leaving
-       us with no maintainer and lots of bugs.  The code should not have
-       been merged in the first place, and many aspects of it's
-       implementation are blocking more critical core networking
-       development.  It's marked EXPERIMENTAL and no distribution
-       enables it because it cause obscure crashes due to unfixable bugs
-       (interfaces don't return errors so memory allocation can't be
-       handled, calling contexts of these interfaces make handling
-       errors impossible too because they get called after we've
-       totally commited to creating a route object, for example).
-       This problem has existed for years and no forward progress
-       has ever been made, and nobody steps up to try and salvage
-       this code, so we're going to finally just get rid of it.
-Who:   David S. Miller <davem@davemloft.net>
-
----------------------------
-
 What:  read_dev_chars(), read_conf_data{,_lpm}() (s390 common I/O layer)
 When:  December 2007
 Why:   These functions are a leftover from 2.4 times. They have several
@@ -348,3 +311,18 @@ Who:  Tejun Heo <htejun@gmail.com>
 
 ---------------------------
 
+What:  Legacy RTC drivers (under drivers/i2c/chips)
+When:  November 2007
+Why:   Obsolete. We have a RTC subsystem with better drivers.
+Who:   Jean Delvare <khali@linux-fr.org>
+
+---------------------------
+
+What:  iptables SAME target
+When:  1.1. 2008
+Files: net/ipv4/netfilter/ipt_SAME.c, include/linux/netfilter_ipv4/ipt_SAME.h
+Why:   Obsolete for multiple years now, NAT core provides the same behaviour.
+       Unfixable broken wrt. 32/64 bit cleanness.
+Who:   Patrick McHardy <kaber@trash.net>
+
+---------------------------
index 4994f1f28f8ce23bf56ec61976cbefe19c008d41..fba943aacf93e2a8b040996bf26c408ee737e1a3 100644 (file)
@@ -78,6 +78,7 @@ static CLASS_DEVICE_ATTR(loading, 0644,
                         firmware_loading_show, firmware_loading_store);
 
 static ssize_t firmware_data_read(struct kobject *kobj,
+                                 struct bin_attribute *bin_attr,
                                  char *buffer, loff_t offset, size_t count)
 {
        struct class_device *class_dev = to_class_dev(kobj);
@@ -88,6 +89,7 @@ static ssize_t firmware_data_read(struct kobject *kobj,
        return count;
 }
 static ssize_t firmware_data_write(struct kobject *kobj,
+                                  struct bin_attribute *bin_attr,
                                   char *buffer, loff_t offset, size_t count)
 {
        struct class_device *class_dev = to_class_dev(kobj);
index c34f0db78a30f9f66b22f055f92cd95ae024c6dc..fe6406f2f9a66ac9c96216c097f02b0b7b107816 100644 (file)
@@ -5,8 +5,8 @@ Supported adapters:
     '810' and '810E' chipsets)
   * Intel 82801BA (ICH2 - part of the '815E' chipset)
   * Intel 82801CA/CAM (ICH3)
-  * Intel 82801DB (ICH4) (HW PEC supported, 32 byte buffer not supported)
-  * Intel 82801EB/ER (ICH5) (HW PEC supported, 32 byte buffer not supported)
+  * Intel 82801DB (ICH4) (HW PEC supported)
+  * Intel 82801EB/ER (ICH5) (HW PEC supported)
   * Intel 6300ESB
   * Intel 82801FB/FR/FW/FRW (ICH6)
   * Intel 82801G (ICH7)
index 7cbe43fa2701dfb875a7eae69754ecb557e5c043..fa0c786a8bf5a787e6a980dd9dbeef9c283d7b41 100644 (file)
@@ -6,7 +6,7 @@ Supported adapters:
     Datasheet: Publicly available at the Intel website
   * ServerWorks OSB4, CSB5, CSB6 and HT-1000 southbridges
     Datasheet: Only available via NDA from ServerWorks
-  * ATI IXP200, IXP300, IXP400 and SB600 southbridges
+  * ATI IXP200, IXP300, IXP400, SB600 and SB700 southbridges
     Datasheet: Not publicly available
   * Standard Microsystems (SMSC) SLC90E66 (Victory66) southbridge
     Datasheet: Publicly available at the SMSC website http://www.smsc.com
diff --git a/Documentation/i2c/busses/i2c-taos-evm b/Documentation/i2c/busses/i2c-taos-evm
new file mode 100644 (file)
index 0000000..9146e33
--- /dev/null
@@ -0,0 +1,46 @@
+Kernel driver i2c-taos-evm
+
+Author: Jean Delvare <khali@linux-fr.org>
+
+This is a driver for the evaluation modules for TAOS I2C/SMBus chips.
+The modules include an SMBus master with limited capabilities, which can
+be controlled over the serial port. Virtually all evaluation modules
+are supported, but a few lines of code need to be added for each new
+module to instantiate the right I2C chip on the bus. Obviously, a driver
+for the chip in question is also needed.
+
+Currently supported devices are:
+
+* TAOS TSL2550 EVM
+
+For addtional information on TAOS products, please see
+  http://www.taosinc.com/
+
+
+Using this driver
+-----------------
+
+In order to use this driver, you'll need the serport driver, and the
+inputattach tool, which is part of the input-utils package. The following
+commands will tell the kernel that you have a TAOS EVM on the first
+serial port:
+
+# modprobe serport
+# inputattach --taos-evm /dev/ttyS0
+
+
+Technical details
+-----------------
+
+Only 4 SMBus transaction types are supported by the TAOS evaluation
+modules:
+* Receive Byte
+* Send Byte
+* Read Byte
+* Write Byte
+
+The communication protocol is text-based and pretty simple. It is
+described in a PDF document on the CD which comes with the evaluation
+module. The communication is rather slow, because the serial port has
+to operate at 1200 bps. However, I don't think this is a big concern in
+practice, as these modules are meant for evaluation and testing only.
index 96fec562a8e9020fc92a5d8c1de5676bda953cf8..a0cd8af2f40806a53ac2dc1841be8530d4e59992 100644 (file)
@@ -99,7 +99,7 @@ And then read the data
 
   or
 
-  count = i2c_smbus_read_i2c_block_data(fd, 0x84, buffer);
+  count = i2c_smbus_read_i2c_block_data(fd, 0x84, 16, buffer);
 
 The block read should read 16 bytes.
 0x84 is the block read command.
diff --git a/Documentation/i2c/chips/x1205 b/Documentation/i2c/chips/x1205
deleted file mode 100644 (file)
index 09407c9..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-Kernel driver x1205
-===================
-
-Supported chips:
-  * Xicor X1205 RTC
-    Prefix: 'x1205'
-    Addresses scanned: none
-    Datasheet: http://www.intersil.com/cda/deviceinfo/0,1477,X1205,00.html
-
-Authors:
-       Karen Spearel <kas11@tampabay.rr.com>,
-       Alessandro Zummo <a.zummo@towertech.it>
-
-Description
------------
-
-This module aims to provide complete access to the Xicor X1205 RTC.
-Recently Xicor has merged with Intersil, but the chip is
-still sold under the Xicor brand.
-
-This chip is located at address 0x6f and uses a 2-byte register addressing.
-Two bytes need to be written to read a single register, while most
-other chips just require one and take the second one as the data
-to be written. To prevent corrupting unknown chips, the user must
-explicitely set the probe parameter.
-
-example:
-
-modprobe x1205 probe=0,0x6f
-
-The module supports one more option, hctosys, which is used to set the
-software clock from the x1205. On systems where the x1205 is the
-only hardware rtc, this parameter could be used to achieve a correct
-date/time earlier in the system boot sequence.
-
-example:
-
-modprobe x1205 probe=0,0x6f hctosys=1
index aea60bf7e8f0847370e17beec79880307754a5d5..003c7319b8c7a6dbae0881ae513474eea86f727b 100644 (file)
@@ -67,7 +67,6 @@ i2c-proc: The /proc/sys/dev/sensors interface for device (client) drivers
 Algorithm drivers
 -----------------
 
-i2c-algo-8xx:    An algorithm for CPM's I2C device in Motorola 8xx processors (NOT BUILT BY DEFAULT)
 i2c-algo-bit:    A bit-banging algorithm
 i2c-algo-pcf:    A PCF 8584 style algorithm
 i2c-algo-ibm_ocp: An algorithm for the I2C device in IBM 4xx processors (NOT BUILT BY DEFAULT)
@@ -81,6 +80,5 @@ i2c-pcf-epp:     PCF8584 on a EPP parallel port (uses i2c-algo-pcf) (NOT mkpatch
 i2c-philips-par: Philips style parallel port adapter (uses i2c-algo-bit)
 i2c-adap-ibm_ocp: IBM 4xx processor I2C device (uses i2c-algo-ibm_ocp) (NOT BUILT BY DEFAULT)
 i2c-pport:       Primitive parallel port adapter (uses i2c-algo-bit)
-i2c-rpx:         RPX board Motorola 8xx I2C device (uses i2c-algo-8xx) (NOT BUILT BY DEFAULT)
 i2c-velleman:    Velleman K8000 parallel port adapter (uses i2c-algo-bit)
 
index 3d8d36b0ad1262f0a8b4c0fc2fbce21faf07d318..2c170032bf37432790be70fe2e362ba4146c42b1 100644 (file)
@@ -571,7 +571,7 @@ SMBus communication
                                         u8 command, u8 length,
                                         u8 *values);
   extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client,
-                                           u8 command, u8 *values);
+                                           u8 command, u8 length, u8 *values);
 
 These ones were removed in Linux 2.6.10 because they had no users, but could
 be added back later if needed:
index c04a421f4a7c70290aaf6d6f4eb54af701fd2ae6..75b3680c41eb835e751a242191f2439914166152 100644 (file)
@@ -37,6 +37,7 @@ Offset        Type            Description
 0x1d0  unsigned long   EFI memory descriptor map pointer
 0x1d4  unsigned long   EFI memory descriptor map size
 0x1e0  unsigned long   ALT_MEM_K, alternative mem check, in Kb
+0x1e4  unsigned long   Scratch field for the kernel setup code
 0x1e8  char            number of entries in E820MAP (below)
 0x1e9  unsigned char   number of entries in EDDBUF (below)
 0x1ea  unsigned char   number of entries in EDD_MBR_SIG_BUFFER (below)
index d485256ee1cead1c71b20610c0db3e458cbd10db..773a814d409361767da369070d2d7e5267536c16 100644 (file)
@@ -19,6 +19,7 @@
 #include <sys/mman.h>
 #include <sys/stat.h>
 #include <unistd.h>
+#include <linux/pci.h>
 
 int sum;
 
@@ -34,13 +35,19 @@ int map_mem(char *path, off_t offset, size_t length, int touch)
                return -1;
        }
 
+       if (fnmatch("/proc/bus/pci/*", path, 0) == 0) {
+               rc = ioctl(fd, PCIIOC_MMAP_IS_MEM);
+               if (rc == -1)
+                       perror("PCIIOC_MMAP_IS_MEM ioctl");
+       }
+
        addr = mmap(NULL, length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, offset);
        if (addr == MAP_FAILED)
                return 1;
 
        if (touch) {
                c = (int *) addr;
-               while (c < (int *) (offset + length))
+               while (c < (int *) (addr + length))
                        sum += *c++;
        }
 
@@ -54,7 +61,7 @@ int map_mem(char *path, off_t offset, size_t length, int touch)
        return 0;
 }
 
-int scan_sysfs(char *path, char *file, off_t offset, size_t length, int touch)
+int scan_tree(char *path, char *file, off_t offset, size_t length, int touch)
 {
        struct dirent **namelist;
        char *name, *path2;
@@ -93,7 +100,7 @@ int scan_sysfs(char *path, char *file, off_t offset, size_t length, int touch)
                } else {
                        r = lstat(path2, &buf);
                        if (r == 0 && S_ISDIR(buf.st_mode)) {
-                               rc = scan_sysfs(path2, file, offset, length, touch);
+                               rc = scan_tree(path2, file, offset, length, touch);
                                if (rc < 0)
                                        return rc;
                        }
@@ -238,10 +245,15 @@ int main()
        else
                fprintf(stderr, "FAIL: /dev/mem 0x0-0x100000 not accessible\n");
 
-       scan_sysfs("/sys/class/pci_bus", "legacy_mem", 0, 0xA0000, 1);
-       scan_sysfs("/sys/class/pci_bus", "legacy_mem", 0xA0000, 0x20000, 0);
-       scan_sysfs("/sys/class/pci_bus", "legacy_mem", 0xC0000, 0x40000, 1);
-       scan_sysfs("/sys/class/pci_bus", "legacy_mem", 0, 1024*1024, 0);
+       scan_tree("/sys/class/pci_bus", "legacy_mem", 0, 0xA0000, 1);
+       scan_tree("/sys/class/pci_bus", "legacy_mem", 0xA0000, 0x20000, 0);
+       scan_tree("/sys/class/pci_bus", "legacy_mem", 0xC0000, 0x40000, 1);
+       scan_tree("/sys/class/pci_bus", "legacy_mem", 0, 1024*1024, 0);
 
        scan_rom("/sys/devices", "rom");
+
+       scan_tree("/proc/bus/pci", "??.?", 0, 0xA0000, 1);
+       scan_tree("/proc/bus/pci", "??.?", 0xA0000, 0x20000, 0);
+       scan_tree("/proc/bus/pci", "??.?", 0xC0000, 0x40000, 1);
+       scan_tree("/proc/bus/pci", "??.?", 0, 1024*1024, 0);
 }
index 9a431a7d0f5d6c61d45687d580137f04878ca4a7..aa3e953f0f7b3f2d29e1b84f95c29ef4d088dded 100644 (file)
@@ -112,6 +112,18 @@ POTENTIAL ATTRIBUTE ALIASING CASES
 
        The /dev/mem mmap constraints apply.
 
+    mmap of /proc/bus/pci/.../??.?
+
+       This is an MMIO mmap of PCI functions, which additionally may or
+       may not be requested as using the WC attribute.
+
+       If WC is requested, and the region in kern_memmap is either WC
+       or UC, and the EFI memory map designates the region as WC, then
+       the WC mapping is allowed.
+
+       Otherwise, the user mapping must use the same attribute as the
+       kernel mapping.
+
     read/write of /dev/mem
 
        This uses copy_from_user(), which implicitly uses a kernel
index af50f9bbe68edda370017ef127d842d3d1ec97b4..4d880b3d1f35548083613a18d695d68029382c81 100644 (file)
@@ -1014,49 +1014,6 @@ and is between 256 and 4096 characters. It is defined in the file
 
        mga=            [HW,DRM]
 
-       migration_cost=
-                       [KNL,SMP] debug: override scheduler migration costs
-                       Format: <level-1-usecs>,<level-2-usecs>,...
-                       This debugging option can be used to override the
-                       default scheduler migration cost matrix. The numbers
-                       are indexed by 'CPU domain distance'.
-                       E.g. migration_cost=1000,2000,3000 on an SMT NUMA
-                       box will set up an intra-core migration cost of
-                       1 msec, an inter-core migration cost of 2 msecs,
-                       and an inter-node migration cost of 3 msecs.
-
-                       WARNING: using the wrong values here can break
-                       scheduler performance, so it's only for scheduler
-                       development purposes, not production environments.
-
-       migration_debug=
-                       [KNL,SMP] migration cost auto-detect verbosity
-                       Format=<0|1|2>
-                       If a system's migration matrix reported at bootup
-                       seems erroneous then this option can be used to
-                       increase verbosity of the detection process.
-                       We default to 0 (no extra messages), 1 will print
-                       some more information, and 2 will be really
-                       verbose (probably only useful if you also have a
-                       serial console attached to the system).
-
-       migration_factor=
-                       [KNL,SMP] multiply/divide migration costs by a factor
-                       Format=<percent>
-                       This debug option can be used to proportionally
-                       increase or decrease the auto-detected migration
-                       costs for all entries of the migration matrix.
-                       E.g. migration_factor=150 will increase migration
-                       costs by 50%. (and thus the scheduler will be less
-                       eager migrating cache-hot tasks)
-                       migration_factor=80 will decrease migration costs
-                       by 20%. (thus the scheduler will be more eager to
-                       migrate tasks)
-
-                       WARNING: using the wrong values here can break
-                       scheduler performance, so it's only for scheduler
-                       development purposes, not production environments.
-
        mousedev.tap_time=
                        [MOUSE] Maximum time between finger touching and
                        leaving touchpad surface for touch to be considered
index 153d84d281e6aa6fa8c1bb6e001d39f8660c0444..d63f480afb74c6e84f05929763446f0732e58947 100644 (file)
@@ -96,9 +96,6 @@ routing.txt
        - the new routing mechanism
 shaper.txt
        - info on the module that can shape/limit transmitted traffic.
-sk98lin.txt
-       - Marvell Yukon Chipset / SysKonnect SK-98xx compliant Gigabit
-         Ethernet Adapter family driver info
 skfp.txt
        - SysKonnect FDDI (SK-5xxx, Compaq Netelligent) driver info.
 smc9.txt
index 8f6067ea5e3e7eb26a2f8771f7d727ad5d0eb23d..32c2e9da5f3a3dd0f2c522799ffa92575f64a01e 100644 (file)
@@ -880,8 +880,7 @@ accept_redirects - BOOLEAN
 accept_source_route - INTEGER
        Accept source routing (routing extension header).
 
-       > 0: Accept routing header.
-       = 0: Accept only routing header type 2.
+       >= 0: Accept only routing header type 2.
        < 0: Do not accept routing header.
 
        Default: 0
diff --git a/Documentation/networking/l2tp.txt b/Documentation/networking/l2tp.txt
new file mode 100644 (file)
index 0000000..2451f55
--- /dev/null
@@ -0,0 +1,169 @@
+This brief document describes how to use the kernel's PPPoL2TP driver
+to provide L2TP functionality. L2TP is a protocol that tunnels one or
+more PPP sessions over a UDP tunnel. It is commonly used for VPNs
+(L2TP/IPSec) and by ISPs to tunnel subscriber PPP sessions over an IP
+network infrastructure.
+
+Design
+======
+
+The PPPoL2TP driver, drivers/net/pppol2tp.c, provides a mechanism by
+which PPP frames carried through an L2TP session are passed through
+the kernel's PPP subsystem. The standard PPP daemon, pppd, handles all
+PPP interaction with the peer. PPP network interfaces are created for
+each local PPP endpoint.
+
+The L2TP protocol http://www.faqs.org/rfcs/rfc2661.html defines L2TP
+control and data frames. L2TP control frames carry messages between
+L2TP clients/servers and are used to setup / teardown tunnels and
+sessions. An L2TP client or server is implemented in userspace and
+will use a regular UDP socket per tunnel. L2TP data frames carry PPP
+frames, which may be PPP control or PPP data. The kernel's PPP
+subsystem arranges for PPP control frames to be delivered to pppd,
+while data frames are forwarded as usual.
+
+Each tunnel and session within a tunnel is assigned a unique tunnel_id
+and session_id. These ids are carried in the L2TP header of every
+control and data packet. The pppol2tp driver uses them to lookup
+internal tunnel and/or session contexts. Zero tunnel / session ids are
+treated specially - zero ids are never assigned to tunnels or sessions
+in the network. In the driver, the tunnel context keeps a pointer to
+the tunnel UDP socket. The session context keeps a pointer to the
+PPPoL2TP socket, as well as other data that lets the driver interface
+to the kernel PPP subsystem.
+
+Note that the pppol2tp kernel driver handles only L2TP data frames;
+L2TP control frames are simply passed up to userspace in the UDP
+tunnel socket. The kernel handles all datapath aspects of the
+protocol, including data packet resequencing (if enabled).
+
+There are a number of requirements on the userspace L2TP daemon in
+order to use the pppol2tp driver.
+
+1. Use a UDP socket per tunnel.
+
+2. Create a single PPPoL2TP socket per tunnel bound to a special null
+   session id. This is used only for communicating with the driver but
+   must remain open while the tunnel is active. Opening this tunnel
+   management socket causes the driver to mark the tunnel socket as an
+   L2TP UDP encapsulation socket and flags it for use by the
+   referenced tunnel id. This hooks up the UDP receive path via
+   udp_encap_rcv() in net/ipv4/udp.c. PPP data frames are never passed
+   in this special PPPoX socket.
+
+3. Create a PPPoL2TP socket per L2TP session. This is typically done
+   by starting pppd with the pppol2tp plugin and appropriate
+   arguments. A PPPoL2TP tunnel management socket (Step 2) must be
+   created before the first PPPoL2TP session socket is created.
+
+When creating PPPoL2TP sockets, the application provides information
+to the driver about the socket in a socket connect() call. Source and
+destination tunnel and session ids are provided, as well as the file
+descriptor of a UDP socket. See struct pppol2tp_addr in
+include/linux/if_ppp.h. Note that zero tunnel / session ids are
+treated specially. When creating the per-tunnel PPPoL2TP management
+socket in Step 2 above, zero source and destination session ids are
+specified, which tells the driver to prepare the supplied UDP file
+descriptor for use as an L2TP tunnel socket.
+
+Userspace may control behavior of the tunnel or session using
+setsockopt and ioctl on the PPPoX socket. The following socket
+options are supported:-
+
+DEBUG     - bitmask of debug message categories. See below.
+SENDSEQ   - 0 => don't send packets with sequence numbers
+            1 => send packets with sequence numbers
+RECVSEQ   - 0 => receive packet sequence numbers are optional
+            1 => drop receive packets without sequence numbers
+LNSMODE   - 0 => act as LAC.
+            1 => act as LNS.
+REORDERTO - reorder timeout (in millisecs). If 0, don't try to reorder.
+
+Only the DEBUG option is supported by the special tunnel management
+PPPoX socket.
+
+In addition to the standard PPP ioctls, a PPPIOCGL2TPSTATS is provided
+to retrieve tunnel and session statistics from the kernel using the
+PPPoX socket of the appropriate tunnel or session.
+
+Debugging
+=========
+
+The driver supports a flexible debug scheme where kernel trace
+messages may be optionally enabled per tunnel and per session. Care is
+needed when debugging a live system since the messages are not
+rate-limited and a busy system could be swamped. Userspace uses
+setsockopt on the PPPoX socket to set a debug mask.
+
+The following debug mask bits are available:
+
+PPPOL2TP_MSG_DEBUG    verbose debug (if compiled in)
+PPPOL2TP_MSG_CONTROL  userspace - kernel interface
+PPPOL2TP_MSG_SEQ      sequence numbers handling
+PPPOL2TP_MSG_DATA     data packets
+
+Sample Userspace Code
+=====================
+
+1. Create tunnel management PPPoX socket
+
+        kernel_fd = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OL2TP);
+        if (kernel_fd >= 0) {
+                struct sockaddr_pppol2tp sax;
+                struct sockaddr_in const *peer_addr;
+
+                peer_addr = l2tp_tunnel_get_peer_addr(tunnel);
+                memset(&sax, 0, sizeof(sax));
+                sax.sa_family = AF_PPPOX;
+                sax.sa_protocol = PX_PROTO_OL2TP;
+                sax.pppol2tp.fd = udp_fd;       /* fd of tunnel UDP socket */
+                sax.pppol2tp.addr.sin_addr.s_addr = peer_addr->sin_addr.s_addr;
+                sax.pppol2tp.addr.sin_port = peer_addr->sin_port;
+                sax.pppol2tp.addr.sin_family = AF_INET;
+                sax.pppol2tp.s_tunnel = tunnel_id;
+                sax.pppol2tp.s_session = 0;     /* special case: mgmt socket */
+                sax.pppol2tp.d_tunnel = 0;
+                sax.pppol2tp.d_session = 0;     /* special case: mgmt socket */
+
+                if(connect(kernel_fd, (struct sockaddr *)&sax, sizeof(sax) ) < 0 ) {
+                        perror("connect failed");
+                        result = -errno;
+                        goto err;
+                }
+        }
+
+2. Create session PPPoX data socket
+
+        struct sockaddr_pppol2tp sax;
+        int fd;
+
+        /* Note, the target socket must be bound already, else it will not be ready */
+        sax.sa_family = AF_PPPOX;
+        sax.sa_protocol = PX_PROTO_OL2TP;
+        sax.pppol2tp.fd = tunnel_fd;
+        sax.pppol2tp.addr.sin_addr.s_addr = addr->sin_addr.s_addr;
+        sax.pppol2tp.addr.sin_port = addr->sin_port;
+        sax.pppol2tp.addr.sin_family = AF_INET;
+        sax.pppol2tp.s_tunnel  = tunnel_id;
+        sax.pppol2tp.s_session = session_id;
+        sax.pppol2tp.d_tunnel  = peer_tunnel_id;
+        sax.pppol2tp.d_session = peer_session_id;
+
+        /* session_fd is the fd of the session's PPPoL2TP socket.
+         * tunnel_fd is the fd of the tunnel UDP socket.
+         */
+        fd = connect(session_fd, (struct sockaddr *)&sax, sizeof(sax));
+        if (fd < 0 )    {
+                return -errno;
+        }
+        return 0;
+
+Miscellanous
+============
+
+The PPPoL2TP driver was developed as part of the OpenL2TP project by
+Katalix Systems Ltd. OpenL2TP is a full-featured L2TP client / server,
+designed from the ground up to have the L2TP datapath in the
+kernel. The project also implemented the pppol2tp plugin for pppd
+which allows pppd to use the kernel driver. Details can be found at
+http://openl2tp.sourceforge.net.
diff --git a/Documentation/networking/multiqueue.txt b/Documentation/networking/multiqueue.txt
new file mode 100644 (file)
index 0000000..00b60cc
--- /dev/null
@@ -0,0 +1,111 @@
+
+               HOWTO for multiqueue network device support
+               ===========================================
+
+Section 1: Base driver requirements for implementing multiqueue support
+Section 2: Qdisc support for multiqueue devices
+Section 3: Brief howto using PRIO or RR for multiqueue devices
+
+
+Intro: Kernel support for multiqueue devices
+---------------------------------------------------------
+
+Kernel support for multiqueue devices is only an API that is presented to the
+netdevice layer for base drivers to implement.  This feature is part of the
+core networking stack, and all network devices will be running on the
+multiqueue-aware stack.  If a base driver only has one queue, then these
+changes are transparent to that driver.
+
+
+Section 1: Base driver requirements for implementing multiqueue support
+-----------------------------------------------------------------------
+
+Base drivers are required to use the new alloc_etherdev_mq() or
+alloc_netdev_mq() functions to allocate the subqueues for the device.  The
+underlying kernel API will take care of the allocation and deallocation of
+the subqueue memory, as well as netdev configuration of where the queues
+exist in memory.
+
+The base driver will also need to manage the queues as it does the global
+netdev->queue_lock today.  Therefore base drivers should use the
+netif_{start|stop|wake}_subqueue() functions to manage each queue while the
+device is still operational.  netdev->queue_lock is still used when the device
+comes online or when it's completely shut down (unregister_netdev(), etc.).
+
+Finally, the base driver should indicate that it is a multiqueue device.  The
+feature flag NETIF_F_MULTI_QUEUE should be added to the netdev->features
+bitmap on device initialization.  Below is an example from e1000:
+
+#ifdef CONFIG_E1000_MQ
+       if ( (adapter->hw.mac.type == e1000_82571) ||
+            (adapter->hw.mac.type == e1000_82572) ||
+            (adapter->hw.mac.type == e1000_80003es2lan))
+               netdev->features |= NETIF_F_MULTI_QUEUE;
+#endif
+
+
+Section 2: Qdisc support for multiqueue devices
+-----------------------------------------------
+
+Currently two qdiscs support multiqueue devices.  A new round-robin qdisc,
+sch_rr, and sch_prio. The qdisc is responsible for classifying the skb's to
+bands and queues, and will store the queue mapping into skb->queue_mapping.
+Use this field in the base driver to determine which queue to send the skb
+to.
+
+sch_rr has been added for hardware that doesn't want scheduling policies from
+software, so it's a straight round-robin qdisc.  It uses the same syntax and
+classification priomap that sch_prio uses, so it should be intuitive to
+configure for people who've used sch_prio.
+
+The PRIO qdisc naturally plugs into a multiqueue device.  If PRIO has been
+built with NET_SCH_PRIO_MQ, then upon load, it will make sure the number of
+bands requested is equal to the number of queues on the hardware.  If they
+are equal, it sets a one-to-one mapping up between the queues and bands.  If
+they're not equal, it will not load the qdisc.  This is the same behavior
+for RR.  Once the association is made, any skb that is classified will have
+skb->queue_mapping set, which will allow the driver to properly queue skb's
+to multiple queues.
+
+
+Section 3: Brief howto using PRIO and RR for multiqueue devices
+---------------------------------------------------------------
+
+The userspace command 'tc,' part of the iproute2 package, is used to configure
+qdiscs.  To add the PRIO qdisc to your network device, assuming the device is
+called eth0, run the following command:
+
+# tc qdisc add dev eth0 root handle 1: prio bands 4 multiqueue
+
+This will create 4 bands, 0 being highest priority, and associate those bands
+to the queues on your NIC.  Assuming eth0 has 4 Tx queues, the band mapping
+would look like:
+
+band 0 => queue 0
+band 1 => queue 1
+band 2 => queue 2
+band 3 => queue 3
+
+Traffic will begin flowing through each queue if your TOS values are assigning
+traffic across the various bands.  For example, ssh traffic will always try to
+go out band 0 based on TOS -> Linux priority conversion (realtime traffic),
+so it will be sent out queue 0.  ICMP traffic (pings) fall into the "normal"
+traffic classification, which is band 1.  Therefore pings will be send out
+queue 1 on the NIC.
+
+Note the use of the multiqueue keyword.  This is only in versions of iproute2
+that support multiqueue networking devices; if this is omitted when loading
+a qdisc onto a multiqueue device, the qdisc will load and operate the same
+if it were loaded onto a single-queue device (i.e. - sends all traffic to
+queue 0).
+
+Another alternative to multiqueue band allocation can be done by using the
+multiqueue option and specify 0 bands.  If this is the case, the qdisc will
+allocate the number of bands to equal the number of queues that the device
+reports, and bring the qdisc online.
+
+The behavior of tc filters remains the same, where it will override TOS priority
+classification.
+
+
+Author: Peter P. Waskiewicz Jr. <peter.p.waskiewicz.jr@intel.com>
index ce1361f952436e6c504fd1786009f03211508513..37869295fc7092e659c0ab08a36209b253522dc0 100644 (file)
@@ -20,6 +20,30 @@ private data which gets freed when the network device is freed. If
 separately allocated data is attached to the network device
 (dev->priv) then it is up to the module exit handler to free that.
 
+MTU
+===
+Each network device has a Maximum Transfer Unit. The MTU does not
+include any link layer protocol overhead. Upper layer protocols must
+not pass a socket buffer (skb) to a device to transmit with more data
+than the mtu. The MTU does not include link layer header overhead, so
+for example on Ethernet if the standard MTU is 1500 bytes used, the
+actual skb will contain up to 1514 bytes because of the Ethernet
+header. Devices should allow for the 4 byte VLAN header as well.
+
+Segmentation Offload (GSO, TSO) is an exception to this rule.  The
+upper layer protocol may pass a large socket buffer to the device
+transmit routine, and the device will break that up into separate
+packets based on the current MTU.
+
+MTU is symmetrical and applies both to receive and transmit. A device
+must be able to receive at least the maximum size packet allowed by
+the MTU. A network device may use the MTU as mechanism to size receive
+buffers, but the device should allow packets with VLAN header. With
+standard Ethernet mtu of 1500 bytes, the device should allow up to
+1518 byte packets (1500 + 14 header + 4 tag).  The device may either:
+drop, truncate, or pass up oversize packets, but dropping oversize
+packets is preferred.
+
 
 struct net_device synchronization rules
 =======================================
@@ -43,16 +67,17 @@ dev->get_stats:
 
 dev->hard_start_xmit:
        Synchronization: netif_tx_lock spinlock.
+
        When the driver sets NETIF_F_LLTX in dev->features this will be
        called without holding netif_tx_lock. In this case the driver
        has to lock by itself when needed. It is recommended to use a try lock
-       for this and return -1 when the spin lock fails. 
+       for this and return NETDEV_TX_LOCKED when the spin lock fails.
        The locking there should also properly protect against 
-       set_multicast_list
-       Context: Process with BHs disabled or BH (timer).
-       Notes: netif_queue_stopped() is guaranteed false
-               Interrupts must be enabled when calling hard_start_xmit.
-                (Interrupts must also be enabled when enabling the BH handler.)
+       set_multicast_list.
+
+       Context: Process with BHs disabled or BH (timer),
+                will be called with interrupts disabled by netconsole.
+
        Return codes: 
        o NETDEV_TX_OK everything ok. 
        o NETDEV_TX_BUSY Cannot transmit packet, try later 
@@ -74,4 +99,5 @@ dev->poll:
        Synchronization: __LINK_STATE_RX_SCHED bit in dev->state.  See
                dev_close code and comments in net/core/dev.c for more info.
        Context: softirq
+                will be called with interrupts disabled by netconsole.
 
diff --git a/Documentation/networking/sk98lin.txt b/Documentation/networking/sk98lin.txt
deleted file mode 100644 (file)
index 8590a95..0000000
+++ /dev/null
@@ -1,568 +0,0 @@
-(C)Copyright 1999-2004 Marvell(R).
-All rights reserved
-===========================================================================
-
-sk98lin.txt created 13-Feb-2004
-
-Readme File for sk98lin v6.23
-Marvell Yukon/SysKonnect SK-98xx Gigabit Ethernet Adapter family driver for LINUX
-
-This file contains
- 1  Overview
- 2  Required Files
- 3  Installation
-    3.1  Driver Installation
-    3.2  Inclusion of adapter at system start
- 4  Driver Parameters
-    4.1  Per-Port Parameters
-    4.2  Adapter Parameters
- 5  Large Frame Support
- 6  VLAN and Link Aggregation Support (IEEE 802.1, 802.1q, 802.3ad)
- 7  Troubleshooting
-
-===========================================================================
-
-
-1  Overview
-===========
-
-The sk98lin driver supports the Marvell Yukon and SysKonnect 
-SK-98xx/SK-95xx compliant Gigabit Ethernet Adapter on Linux. It has 
-been tested with Linux on Intel/x86 machines.
-***
-
-
-2  Required Files
-=================
-
-The linux kernel source.
-No additional files required.
-***
-
-
-3  Installation
-===============
-
-It is recommended to download the latest version of the driver from the 
-SysKonnect web site www.syskonnect.com. If you have downloaded the latest
-driver, the Linux kernel has to be patched before the driver can be 
-installed. For details on how to patch a Linux kernel, refer to the 
-patch.txt file.
-
-3.1  Driver Installation
-------------------------
-
-The following steps describe the actions that are required to install
-the driver and to start it manually. These steps should be carried
-out for the initial driver setup. Once confirmed to be ok, they can
-be included in the system start.
-
-NOTE 1: To perform the following tasks you need 'root' access.
-
-NOTE 2: In case of problems, please read the section "Troubleshooting" 
-        below.
-
-The driver can either be integrated into the kernel or it can be compiled 
-as a module. Select the appropriate option during the kernel 
-configuration.
-
-Compile/use the driver as a module
-----------------------------------
-To compile the driver, go to the directory /usr/src/linux and
-execute the command "make menuconfig" or "make xconfig" and proceed as 
-follows:
-
-To integrate the driver permanently into the kernel, proceed as follows:
-
-1. Select the menu "Network device support" and then "Ethernet(1000Mbit)"
-2. Mark "Marvell Yukon Chipset / SysKonnect SK-98xx family support" 
-   with (*) 
-3. Build a new kernel when the configuration of the above options is 
-   finished.
-4. Install the new kernel.
-5. Reboot your system.
-
-To use the driver as a module, proceed as follows:
-
-1. Enable 'loadable module support' in the kernel.
-2. For automatic driver start, enable the 'Kernel module loader'.
-3. Select the menu "Network device support" and then "Ethernet(1000Mbit)"
-4. Mark "Marvell Yukon Chipset / SysKonnect SK-98xx family support" 
-   with (M)
-5. Execute the command "make modules".
-6. Execute the command "make modules_install".
-   The appropriate modules will be installed.
-7. Reboot your system.
-
-
-Load the module manually
-------------------------
-To load the module manually, proceed as follows:
-
-1. Enter "modprobe sk98lin".
-2. If a Marvell Yukon or SysKonnect SK-98xx adapter is installed in 
-   your computer and you have a /proc file system, execute the command:
-   "ls /proc/net/sk98lin/" 
-   This should produce an output containing a line with the following 
-   format:
-   eth0   eth1  ...
-   which indicates that your adapter has been found and initialized.
-   
-   NOTE 1: If you have more than one Marvell Yukon or SysKonnect SK-98xx 
-           adapter installed, the adapters will be listed as 'eth0', 
-                   'eth1', 'eth2', etc.
-                   For each adapter, repeat steps 3 and 4 below.
-
-   NOTE 2: If you have other Ethernet adapters installed, your Marvell
-           Yukon or SysKonnect SK-98xx adapter will be mapped to the 
-                   next available number, e.g. 'eth1'. The mapping is executed 
-                   automatically.
-           The module installation message (displayed either in a system
-           log file or on the console) prints a line for each adapter 
-           found containing the corresponding 'ethX'.
-
-3. Select an IP address and assign it to the respective adapter by 
-   entering:
-   ifconfig eth0 <ip-address>
-   With this command, the adapter is connected to the Ethernet. 
-   
-   SK-98xx Gigabit Ethernet Server Adapters: The yellow LED on the adapter 
-   is now active, the link status LED of the primary port is active and 
-   the link status LED of the secondary port (on dual port adapters) is 
-   blinking (if the ports are connected to a switch or hub).
-   SK-98xx V2.0 Gigabit Ethernet Adapters: The link status LED is active.
-   In addition, you will receive a status message on the console stating
-   "ethX: network connection up using port Y" and showing the selected 
-   connection parameters (x stands for the ethernet device number 
-   (0,1,2, etc), y stands for the port name (A or B)).
-
-   NOTE: If you are in doubt about IP addresses, ask your network
-         administrator for assistance.
-  
-4. Your adapter should now be fully operational.
-   Use 'ping <otherstation>' to verify the connection to other computers 
-   on your network.
-5. To check the adapter configuration view /proc/net/sk98lin/[devicename].
-   For example by executing:    
-   "cat /proc/net/sk98lin/eth0" 
-
-Unload the module
------------------
-To stop and unload the driver modules, proceed as follows:
-
-1. Execute the command "ifconfig eth0 down".
-2. Execute the command "rmmod sk98lin".
-
-3.2  Inclusion of adapter at system start
------------------------------------------
-
-Since a large number of different Linux distributions are 
-available, we are unable to describe a general installation procedure
-for the driver module.
-Because the driver is now integrated in the kernel, installation should
-be easy, using the standard mechanism of your distribution.
-Refer to the distribution's manual for installation of ethernet adapters.
-
-***
-
-4  Driver Parameters
-====================
-
-Parameters can be set at the command line after the module has been 
-loaded with the command 'modprobe'.
-In some distributions, the configuration tools are able to pass parameters
-to the driver module.
-
-If you use the kernel module loader, you can set driver parameters
-in the file /etc/modprobe.conf (or /etc/modules.conf in 2.4 or earlier).
-To set the driver parameters in this file, proceed as follows:
-
-1. Insert a line of the form :
-   options sk98lin ...
-   For "...", the same syntax is required as described for the command
-   line parameters of modprobe below.
-2. To activate the new parameters, either reboot your computer
-   or 
-   unload and reload the driver.
-   The syntax of the driver parameters is:
-
-        modprobe sk98lin parameter=value1[,value2[,value3...]]
-
-   where value1 refers to the first adapter, value2 to the second etc.
-
-NOTE: All parameters are case sensitive. Write them exactly as shown 
-      below.
-
-Example:
-Suppose you have two adapters. You want to set auto-negotiation
-on the first adapter to ON and on the second adapter to OFF.
-You also want to set DuplexCapabilities on the first adapter
-to FULL, and on the second adapter to HALF.
-Then, you must enter:
-
-        modprobe sk98lin AutoNeg_A=On,Off DupCap_A=Full,Half
-
-NOTE: The number of adapters that can be configured this way is
-      limited in the driver (file skge.c, constant SK_MAX_CARD_PARAM).
-      The current limit is 16. If you happen to install
-      more adapters, adjust this and recompile.
-
-
-4.1  Per-Port Parameters
-------------------------
-
-These settings are available for each port on the adapter.
-In the following description, '?' stands for the port for
-which you set the parameter (A or B).
-
-Speed
------
-Parameter:    Speed_?
-Values:       10, 100, 1000, Auto
-Default:      Auto
-
-This parameter is used to set the speed capabilities. It is only valid 
-for the SK-98xx V2.0 copper adapters.
-Usually, the speed is negotiated between the two ports during link 
-establishment. If this fails, a port can be forced to a specific setting
-with this parameter.
-
-Auto-Negotiation
-----------------
-Parameter:    AutoNeg_?
-Values:       On, Off, Sense
-Default:      On
-  
-The "Sense"-mode automatically detects whether the link partner supports
-auto-negotiation or not.
-
-Duplex Capabilities
--------------------
-Parameter:    DupCap_?
-Values:       Half, Full, Both
-Default:      Both
-
-This parameters is only relevant if auto-negotiation for this port is 
-not set to "Sense". If auto-negotiation is set to "On", all three values
-are possible. If it is set to "Off", only "Full" and "Half" are allowed.
-This parameter is useful if your link partner does not support all
-possible combinations.
-
-Flow Control
-------------
-Parameter:    FlowCtrl_?
-Values:       Sym, SymOrRem, LocSend, None
-Default:      SymOrRem
-
-This parameter can be used to set the flow control capabilities the 
-port reports during auto-negotiation. It can be set for each port 
-individually.
-Possible modes:
-   -- Sym      = Symmetric: both link partners are allowed to send 
-                  PAUSE frames
-   -- SymOrRem = SymmetricOrRemote: both or only remote partner 
-                  are allowed to send PAUSE frames
-   -- LocSend  = LocalSend: only local link partner is allowed 
-                  to send PAUSE frames
-   -- None     = no link partner is allowed to send PAUSE frames
-  
-NOTE: This parameter is ignored if auto-negotiation is set to "Off".
-
-Role in Master-Slave-Negotiation (1000Base-T only)
---------------------------------------------------
-Parameter:    Role_?
-Values:       Auto, Master, Slave
-Default:      Auto
-
-This parameter is only valid for the SK-9821 and SK-9822 adapters.
-For two 1000Base-T ports to communicate, one must take the role of the
-master (providing timing information), while the other must be the 
-slave. Usually, this is negotiated between the two ports during link 
-establishment. If this fails, a port can be forced to a specific setting
-with this parameter.
-
-
-4.2  Adapter Parameters
------------------------
-
-Connection Type (SK-98xx V2.0 copper adapters only)
----------------
-Parameter:    ConType
-Values:       Auto, 100FD, 100HD, 10FD, 10HD
-Default:      Auto
-
-The parameter 'ConType' is a combination of all five per-port parameters
-within one single parameter. This simplifies the configuration of both ports
-of an adapter card! The different values of this variable reflect the most 
-meaningful combinations of port parameters.
-
-The following table shows the values of 'ConType' and the corresponding
-combinations of the per-port parameters:
-
-    ConType   |  DupCap   AutoNeg   FlowCtrl   Role             Speed
-    ----------+------------------------------------------------------
-    Auto      |  Both     On        SymOrRem   Auto             Auto
-    100FD     |  Full     Off       None       Auto (ignored)   100
-    100HD     |  Half     Off       None       Auto (ignored)   100
-    10FD      |  Full     Off       None       Auto (ignored)   10
-    10HD      |  Half     Off       None       Auto (ignored)   10
-
-Stating any other port parameter together with this 'ConType' variable
-will result in a merged configuration of those settings. This due to 
-the fact, that the per-port parameters (e.g. Speed_? ) have a higher
-priority than the combined variable 'ConType'.
-
-NOTE: This parameter is always used on both ports of the adapter card.
-
-Interrupt Moderation
---------------------
-Parameter:    Moderation
-Values:       None, Static, Dynamic
-Default:      None
-
-Interrupt moderation is employed to limit the maximum number of interrupts
-the driver has to serve. That is, one or more interrupts (which indicate any
-transmit or receive packet to be processed) are queued until the driver 
-processes them. When queued interrupts are to be served, is determined by the
-'IntsPerSec' parameter, which is explained later below.
-
-Possible modes:
-
-   -- None - No interrupt moderation is applied on the adapter card. 
-      Therefore, each transmit or receive interrupt is served immediately
-      as soon as it appears on the interrupt line of the adapter card.
-
-   -- Static - Interrupt moderation is applied on the adapter card. 
-      All transmit and receive interrupts are queued until a complete
-      moderation interval ends. If such a moderation interval ends, all
-      queued interrupts are processed in one big bunch without any delay.
-      The term 'static' reflects the fact, that interrupt moderation is
-      always enabled, regardless how much network load is currently 
-      passing via a particular interface. In addition, the duration of
-      the moderation interval has a fixed length that never changes while
-      the driver is operational.
-
-   -- Dynamic - Interrupt moderation might be applied on the adapter card,
-      depending on the load of the system. If the driver detects that the
-      system load is too high, the driver tries to shield the system against 
-      too much network load by enabling interrupt moderation. If - at a later
-      time - the CPU utilization decreases again (or if the network load is 
-      negligible) the interrupt moderation will automatically be disabled.
-
-Interrupt moderation should be used when the driver has to handle one or more
-interfaces with a high network load, which - as a consequence - leads also to a
-high CPU utilization. When moderation is applied in such high network load 
-situations, CPU load might be reduced by 20-30%.
-
-NOTE: The drawback of using interrupt moderation is an increase of the round-
-trip-time (RTT), due to the queueing and serving of interrupts at dedicated
-moderation times.
-
-Interrupts per second
----------------------
-Parameter:    IntsPerSec
-Values:       30...40000 (interrupts per second)
-Default:      2000
-
-This parameter is only used if either static or dynamic interrupt moderation
-is used on a network adapter card. Using this parameter if no moderation is
-applied will lead to no action performed.
-
-This parameter determines the length of any interrupt moderation interval. 
-Assuming that static interrupt moderation is to be used, an 'IntsPerSec' 
-parameter value of 2000 will lead to an interrupt moderation interval of
-500 microseconds. 
-
-NOTE: The duration of the moderation interval is to be chosen with care.
-At first glance, selecting a very long duration (e.g. only 100 interrupts per 
-second) seems to be meaningful, but the increase of packet-processing delay 
-is tremendous. On the other hand, selecting a very short moderation time might
-compensate the use of any moderation being applied.
-
-
-Preferred Port
---------------
-Parameter:    PrefPort
-Values:       A, B
-Default:      A
-
-This is used to force the preferred port to A or B (on dual-port network 
-adapters). The preferred port is the one that is used if both are detected
-as fully functional.
-
-RLMT Mode (Redundant Link Management Technology)
-------------------------------------------------
-Parameter:    RlmtMode
-Values:       CheckLinkState,CheckLocalPort, CheckSeg, DualNet
-Default:      CheckLinkState
-
-RLMT monitors the status of the port. If the link of the active port 
-fails, RLMT switches immediately to the standby link. The virtual link is 
-maintained as long as at least one 'physical' link is up. 
-
-Possible modes:
-
-   -- CheckLinkState - Check link state only: RLMT uses the link state
-      reported by the adapter hardware for each individual port to 
-      determine whether a port can be used for all network traffic or 
-      not.
-
-   -- CheckLocalPort - In this mode, RLMT monitors the network path 
-      between the two ports of an adapter by regularly exchanging packets
-      between them. This mode requires a network configuration in which 
-      the two ports are able to "see" each other (i.e. there must not be 
-      any router between the ports).
-
-   -- CheckSeg - Check local port and segmentation: This mode supports the
-      same functions as the CheckLocalPort mode and additionally checks 
-      network segmentation between the ports. Therefore, this mode is only
-      to be used if Gigabit Ethernet switches are installed on the network
-      that have been configured to use the Spanning Tree protocol. 
-
-   -- DualNet - In this mode, ports A and B are used as separate devices. 
-      If you have a dual port adapter, port A will be configured as eth0 
-      and port B as eth1. Both ports can be used independently with 
-      distinct IP addresses. The preferred port setting is not used. 
-      RLMT is turned off.
-   
-NOTE: RLMT modes CLP and CLPSS are designed to operate in configurations 
-      where a network path between the ports on one adapter exists. 
-      Moreover, they are not designed to work where adapters are connected
-      back-to-back.
-***
-
-
-5  Large Frame Support
-======================
-
-The driver supports large frames (also called jumbo frames). Using large 
-frames can result in an improved throughput if transferring large amounts 
-of data.
-To enable large frames, set the MTU (maximum transfer unit) of the 
-interface to the desired value (up to 9000), execute the following 
-command:
-      ifconfig eth0 mtu 9000
-This will only work if you have two adapters connected back-to-back
-or if you use a switch that supports large frames. When using a switch, 
-it should be configured to allow large frames and auto-negotiation should  
-be set to OFF. The setting must be configured on all adapters that can be 
-reached by the large frames. If one adapter is not set to receive large 
-frames, it will simply drop them.
-
-You can switch back to the standard ethernet frame size by executing the 
-following command:
-      ifconfig eth0 mtu 1500
-
-To permanently configure this setting, add a script with the 'ifconfig' 
-line to the system startup sequence (named something like "S99sk98lin" 
-in /etc/rc.d/rc2.d).
-***
-
-
-6  VLAN and Link Aggregation Support (IEEE 802.1, 802.1q, 802.3ad)
-==================================================================
-
-The Marvell Yukon/SysKonnect Linux drivers are able to support VLAN and 
-Link Aggregation according to IEEE standards 802.1, 802.1q, and 802.3ad. 
-These features are only available after installation of open source 
-modules available on the Internet:
-For VLAN go to: http://www.candelatech.com/~greear/vlan.html
-For Link Aggregation go to: http://www.st.rim.or.jp/~yumo
-
-NOTE: SysKonnect GmbH does not offer any support for these open source 
-      modules and does not take the responsibility for any kind of 
-      failures or problems arising in connection with these modules.
-
-NOTE: Configuring Link Aggregation on a SysKonnect dual link adapter may 
-      cause problems when unloading the driver.
-
-
-7  Troubleshooting
-==================
-
-If any problems occur during the installation process, check the 
-following list:
-
-
-Problem:  The SK-98xx adapter cannot be found by the driver.
-Solution: In /proc/pci search for the following entry:
-             'Ethernet controller: SysKonnect SK-98xx ...'
-          If this entry exists, the SK-98xx or SK-98xx V2.0 adapter has 
-          been found by the system and should be operational.
-          If this entry does not exist or if the file '/proc/pci' is not 
-          found, there may be a hardware problem or the PCI support may 
-          not be enabled in your kernel.
-          The adapter can be checked using the diagnostics program which 
-          is available on the SysKonnect web site:
-          www.syskonnect.com
-          
-          Some COMPAQ machines have problems dealing with PCI under Linux.
-          This problem is described in the 'PCI howto' document
-          (included in some distributions or available from the
-          web, e.g. at 'www.linux.org'). 
-
-
-Problem:  Programs such as 'ifconfig' or 'route' cannot be found or the 
-          error message 'Operation not permitted' is displayed.
-Reason:   You are not logged in as user 'root'.
-Solution: Logout and login as 'root' or change to 'root' via 'su'.
-
-
-Problem:  Upon use of the command 'ping <address>' the message
-          "ping: sendto: Network is unreachable" is displayed.
-Reason:   Your route is not set correctly.
-Solution: If you are using RedHat, you probably forgot to set up the 
-          route in the 'network configuration'.
-          Check the existing routes with the 'route' command and check 
-          if an entry for 'eth0' exists, and if so, if it is set correctly.
-
-
-Problem:  The driver can be started, the adapter is connected to the 
-          network, but you cannot receive or transmit any packets; 
-          e.g. 'ping' does not work.
-Reason:   There is an incorrect route in your routing table.
-Solution: Check the routing table with the command 'route' and read the 
-          manual help pages dealing with routes (enter 'man route').
-
-NOTE: Although the 2.2.x kernel versions generate the routing entry 
-      automatically, problems of this kind may occur here as well. We've 
-      come across a situation in which the driver started correctly at 
-      system start, but after the driver has been removed and reloaded,
-      the route of the adapter's network pointed to the 'dummy0'device 
-      and had to be corrected manually.
-
-
-Problem:  Your computer should act as a router between multiple 
-          IP subnetworks (using multiple adapters), but computers in 
-          other subnetworks cannot be reached.
-Reason:   Either the router's kernel is not configured for IP forwarding 
-          or the routing table and gateway configuration of at least one 
-          computer is not working.
-
-Problem:  Upon driver start, the following error message is displayed:
-          "eth0: -- ERROR --
-          Class: internal Software error
-          Nr:    0xcc
-          Msg:   SkGeInitPort() cannot init running ports"
-Reason:   You are using a driver compiled for single processor machines 
-          on a multiprocessor machine with SMP (Symmetric MultiProcessor) 
-          kernel.
-Solution: Configure your kernel appropriately and recompile the kernel or
-          the modules.
-
-
-
-If your problem is not listed here, please contact SysKonnect's technical
-support for help (linux@syskonnect.de).
-When contacting our technical support, please ensure that the following 
-information is available:
-- System Manufacturer and HW Informations (CPU, Memory... )
-- PCI-Boards in your system
-- Distribution
-- Kernel version
-- Driver version
-***
-
-
-
-***End of Readme File***
diff --git a/Documentation/networking/spider_net.txt b/Documentation/networking/spider_net.txt
new file mode 100644 (file)
index 0000000..4b4adb8
--- /dev/null
@@ -0,0 +1,204 @@
+
+            The Spidernet Device Driver
+            ===========================
+
+Written by Linas Vepstas <linas@austin.ibm.com>
+
+Version of 7 June 2007
+
+Abstract
+========
+This document sketches the structure of portions of the spidernet
+device driver in the Linux kernel tree. The spidernet is a gigabit
+ethernet device built into the Toshiba southbridge commonly used
+in the SONY Playstation 3 and the IBM QS20 Cell blade.
+
+The Structure of the RX Ring.
+=============================
+The receive (RX) ring is a circular linked list of RX descriptors,
+together with three pointers into the ring that are used to manage its
+contents.
+
+The elements of the ring are called "descriptors" or "descrs"; they
+describe the received data. This includes a pointer to a buffer
+containing the received data, the buffer size, and various status bits.
+
+There are three primary states that a descriptor can be in: "empty",
+"full" and "not-in-use".  An "empty" or "ready" descriptor is ready
+to receive data from the hardware. A "full" descriptor has data in it,
+and is waiting to be emptied and processed by the OS. A "not-in-use"
+descriptor is neither empty or full; it is simply not ready. It may
+not even have a data buffer in it, or is otherwise unusable.
+
+During normal operation, on device startup, the OS (specifically, the
+spidernet device driver) allocates a set of RX descriptors and RX
+buffers. These are all marked "empty", ready to receive data. This
+ring is handed off to the hardware, which sequentially fills in the
+buffers, and marks them "full". The OS follows up, taking the full
+buffers, processing them, and re-marking them empty.
+
+This filling and emptying is managed by three pointers, the "head"
+and "tail" pointers, managed by the OS, and a hardware current
+descriptor pointer (GDACTDPA). The GDACTDPA points at the descr
+currently being filled. When this descr is filled, the hardware
+marks it full, and advances the GDACTDPA by one.  Thus, when there is
+flowing RX traffic, every descr behind it should be marked "full",
+and everything in front of it should be "empty".  If the hardware
+discovers that the current descr is not empty, it will signal an
+interrupt, and halt processing.
+
+The tail pointer tails or trails the hardware pointer. When the
+hardware is ahead, the tail pointer will be pointing at a "full"
+descr. The OS will process this descr, and then mark it "not-in-use",
+and advance the tail pointer.  Thus, when there is flowing RX traffic,
+all of the descrs in front of the tail pointer should be "full", and
+all of those behind it should be "not-in-use". When RX traffic is not
+flowing, then the tail pointer can catch up to the hardware pointer.
+The OS will then note that the current tail is "empty", and halt
+processing.
+
+The head pointer (somewhat mis-named) follows after the tail pointer.
+When traffic is flowing, then the head pointer will be pointing at
+a "not-in-use" descr. The OS will perform various housekeeping duties
+on this descr. This includes allocating a new data buffer and
+dma-mapping it so as to make it visible to the hardware. The OS will
+then mark the descr as "empty", ready to receive data. Thus, when there
+is flowing RX traffic, everything in front of the head pointer should
+be "not-in-use", and everything behind it should be "empty". If no
+RX traffic is flowing, then the head pointer can catch up to the tail
+pointer, at which point the OS will notice that the head descr is
+"empty", and it will halt processing.
+
+Thus, in an idle system, the GDACTDPA, tail and head pointers will
+all be pointing at the same descr, which should be "empty". All of the
+other descrs in the ring should be "empty" as well.
+
+The show_rx_chain() routine will print out the the locations of the
+GDACTDPA, tail and head pointers. It will also summarize the contents
+of the ring, starting at the tail pointer, and listing the status
+of the descrs that follow.
+
+A typical example of the output, for a nearly idle system, might be
+
+net eth1: Total number of descrs=256
+net eth1: Chain tail located at descr=20
+net eth1: Chain head is at 20
+net eth1: HW curr desc (GDACTDPA) is at 21
+net eth1: Have 1 descrs with stat=x40800101
+net eth1: HW next desc (GDACNEXTDA) is at 22
+net eth1: Last 255 descrs with stat=xa0800000
+
+In the above, the hardware has filled in one descr, number 20. Both
+head and tail are pointing at 20, because it has not yet been emptied.
+Meanwhile, hw is pointing at 21, which is free.
+
+The "Have nnn decrs" refers to the descr starting at the tail: in this
+case, nnn=1 descr, starting at descr 20. The "Last nnn descrs" refers
+to all of the rest of the descrs, from the last status change. The "nnn"
+is a count of how many descrs have exactly the same status.
+
+The status x4... corresponds to "full" and status xa... corresponds
+to "empty". The actual value printed is RXCOMST_A.
+
+In the device driver source code, a different set of names are
+used for these same concepts, so that
+
+"empty" == SPIDER_NET_DESCR_CARDOWNED == 0xa
+"full"  == SPIDER_NET_DESCR_FRAME_END == 0x4
+"not in use" == SPIDER_NET_DESCR_NOT_IN_USE == 0xf
+
+
+The RX RAM full bug/feature
+===========================
+
+As long as the OS can empty out the RX buffers at a rate faster than
+the hardware can fill them, there is no problem. If, for some reason,
+the OS fails to empty the RX ring fast enough, the hardware GDACTDPA
+pointer will catch up to the head, notice the not-empty condition,
+ad stop. However, RX packets may still continue arriving on the wire.
+The spidernet chip can save some limited number of these in local RAM.
+When this local ram fills up, the spider chip will issue an interrupt
+indicating this (GHIINT0STS will show ERRINT, and the GRMFLLINT bit
+will be set in GHIINT1STS).  When the RX ram full condition occurs,
+a certain bug/feature is triggered that has to be specially handled.
+This section describes the special handling for this condition.
+
+When the OS finally has a chance to run, it will empty out the RX ring.
+In particular, it will clear the descriptor on which the hardware had
+stopped. However, once the hardware has decided that a certain
+descriptor is invalid, it will not restart at that descriptor; instead
+it will restart at the next descr. This potentially will lead to a
+deadlock condition, as the tail pointer will be pointing at this descr,
+which, from the OS point of view, is empty; the OS will be waiting for
+this descr to be filled. However, the hardware has skipped this descr,
+and is filling the next descrs. Since the OS doesn't see this, there
+is a potential deadlock, with the OS waiting for one descr to fill,
+while the hardware is waiting for a different set of descrs to become
+empty.
+
+A call to show_rx_chain() at this point indicates the nature of the
+problem. A typical print when the network is hung shows the following:
+
+net eth1: Spider RX RAM full, incoming packets might be discarded!
+net eth1: Total number of descrs=256
+net eth1: Chain tail located at descr=255
+net eth1: Chain head is at 255
+net eth1: HW curr desc (GDACTDPA) is at 0
+net eth1: Have 1 descrs with stat=xa0800000
+net eth1: HW next desc (GDACNEXTDA) is at 1
+net eth1: Have 127 descrs with stat=x40800101
+net eth1: Have 1 descrs with stat=x40800001
+net eth1: Have 126 descrs with stat=x40800101
+net eth1: Last 1 descrs with stat=xa0800000
+
+Both the tail and head pointers are pointing at descr 255, which is
+marked xa... which is "empty". Thus, from the OS point of view, there
+is nothing to be done. In particular, there is the implicit assumption
+that everything in front of the "empty" descr must surely also be empty,
+as explained in the last section. The OS is waiting for descr 255 to
+become non-empty, which, in this case, will never happen.
+
+The HW pointer is at descr 0. This descr is marked 0x4.. or "full".
+Since its already full, the hardware can do nothing more, and thus has
+halted processing. Notice that descrs 0 through 254 are all marked
+"full", while descr 254 and 255 are empty. (The "Last 1 descrs" is
+descr 254, since tail was at 255.) Thus, the system is deadlocked,
+and there can be no forward progress; the OS thinks there's nothing
+to do, and the hardware has nowhere to put incoming data.
+
+This bug/feature is worked around with the spider_net_resync_head_ptr()
+routine. When the driver receives RX interrupts, but an examination
+of the RX chain seems to show it is empty, then it is probable that
+the hardware has skipped a descr or two (sometimes dozens under heavy
+network conditions). The spider_net_resync_head_ptr() subroutine will
+search the ring for the next full descr, and the driver will resume
+operations there.  Since this will leave "holes" in the ring, there
+is also a spider_net_resync_tail_ptr() that will skip over such holes.
+
+As of this writing, the spider_net_resync() strategy seems to work very
+well, even under heavy network loads.
+
+
+The TX ring
+===========
+The TX ring uses a low-watermark interrupt scheme to make sure that
+the TX queue is appropriately serviced for large packet sizes.
+
+For packet sizes greater than about 1KBytes, the kernel can fill
+the TX ring quicker than the device can drain it. Once the ring
+is full, the netdev is stopped. When there is room in the ring,
+the netdev needs to be reawakened, so that more TX packets are placed
+in the ring. The hardware can empty the ring about four times per jiffy,
+so its not appropriate to wait for the poll routine to refill, since
+the poll routine runs only once per jiffy.  The low-watermark mechanism
+marks a descr about 1/4th of the way from the bottom of the queue, so
+that an interrupt is generated when the descr is processed. This
+interrupt wakes up the netdev, which can then refill the queue.
+For large packets, this mechanism generates a relatively small number
+of interrupts, about 1K/sec. For smaller packets, this will drop to zero
+interrupts, as the hardware can empty the queue faster than the kernel
+can fill it.
+
+
+ ======= END OF DOCUMENT ========
+
index d38261b679053255986f380acdb91e11dabb354a..7754f5aea4e9b0bdd62280fb4f9fe88b23dce3fc 100644 (file)
@@ -113,9 +113,6 @@ initialization with a pointer to a structure describing the driver
                (Please see Documentation/power/pci.txt for descriptions
                of PCI Power Management and the related functions.)
 
-       enable_wake     Enable device to generate wake events from a low power
-                       state.
-
        shutdown        Hook into reboot_notifier_list (kernel/sys.c).
                        Intended to stop any idling DMA operations.
                        Useful for enabling wake-on-lan (NIC) or changing
@@ -299,7 +296,10 @@ If the PCI device can use the PCI Memory-Write-Invalidate transaction,
 call pci_set_mwi().  This enables the PCI_COMMAND bit for Mem-Wr-Inval
 and also ensures that the cache line size register is set correctly.
 Check the return value of pci_set_mwi() as not all architectures
-or chip-sets may support Memory-Write-Invalidate.
+or chip-sets may support Memory-Write-Invalidate.  Alternatively,
+if Mem-Wr-Inval would be nice to have but is not required, call
+pci_try_set_mwi() to have the system do its best effort at enabling
+Mem-Wr-Inval.
 
 
 3.2 Request MMIO/IOP resources
index e00b099a4b8678844edc3f91427f1a184afe8648..dd8fe43888d3e3d6449a1819c84c204a6d197fc6 100644 (file)
@@ -164,7 +164,6 @@ struct pci_driver:
 
         int  (*suspend) (struct pci_dev *dev, pm_message_t state);
         int  (*resume) (struct pci_dev *dev);
-        int  (*enable_wake) (struct pci_dev *dev, pci_power_t state, int enable);
 
 
 suspend
@@ -251,42 +250,6 @@ The driver should update the current_state field in its pci_dev structure in
 this function, except for PM-capable devices when pci_set_power_state is used.
 
 
-enable_wake
------------
-
-Usage:
-
-if (dev->driver && dev->driver->enable_wake)
-       dev->driver->enable_wake(dev,state,enable);
-
-This callback is generally only relevant for devices that support the PCI PM
-spec and have the ability to generate a PME# (Power Management Event Signal)
-to wake the system up. (However, it is possible that a device may support 
-some non-standard way of generating a wake event on sleep.)
-
-Bits 15:11 of the PMC (Power Mgmt Capabilities) Register in a device's
-PM Capabilities describe what power states the device supports generating a 
-wake event from:
-
-+------------------+
-|  Bit  |  State   |
-+------------------+
-|  11   |   D0     |
-|  12   |   D1     |
-|  13   |   D2     |
-|  14   |   D3hot  |
-|  15   |   D3cold |
-+------------------+
-
-A device can use this to enable wake events:
-
-        pci_enable_wake(dev,state,enable);
-
-Note that to enable PME# from D3cold, a value of 4 should be passed to 
-pci_enable_wake (since it uses an index into a bitmask). If a driver gets
-a request to enable wake events from D3, two calls should be made to 
-pci_enable_wake (one for both D3hot and D3cold).
-
 
 A reference implementation
 -------------------------
index 5b8d6953f05e741b6b6a3dd88e1ee0c6681f680a..152b510d1bbb5560945e3550c9b0276f7aa452ab 100644 (file)
@@ -393,6 +393,9 @@ safest thing is to unmount all filesystems on removable media (such USB,
 Firewire, CompactFlash, MMC, external SATA, or even IDE hotplug bays)
 before suspending; then remount them after resuming.
 
+There is a work-around for this problem.  For more information, see
+Documentation/usb/persist.txt.
+
 Q: I upgraded the kernel from 2.6.15 to 2.6.16. Both kernels were
 compiled with the similar configuration files. Anyway I found that
 suspend to disk (and resume) is much slower on 2.6.16 compared to
diff --git a/Documentation/power_supply_class.txt b/Documentation/power_supply_class.txt
new file mode 100644 (file)
index 0000000..9758cf4
--- /dev/null
@@ -0,0 +1,167 @@
+Linux power supply class
+========================
+
+Synopsis
+~~~~~~~~
+Power supply class used to represent battery, UPS, AC or DC power supply
+properties to user-space.
+
+It defines core set of attributes, which should be applicable to (almost)
+every power supply out there. Attributes are available via sysfs and uevent
+interfaces.
+
+Each attribute has well defined meaning, up to unit of measure used. While
+the attributes provided are believed to be universally applicable to any
+power supply, specific monitoring hardware may not be able to provide them
+all, so any of them may be skipped.
+
+Power supply class is extensible, and allows to define drivers own attributes.
+The core attribute set is subject to the standard Linux evolution (i.e.
+if it will be found that some attribute is applicable to many power supply
+types or their drivers, it can be added to the core set).
+
+It also integrates with LED framework, for the purpose of providing
+typically expected feedback of battery charging/fully charged status and
+AC/USB power supply online status. (Note that specific details of the
+indication (including whether to use it at all) are fully controllable by
+user and/or specific machine defaults, per design principles of LED
+framework).
+
+
+Attributes/properties
+~~~~~~~~~~~~~~~~~~~~~
+Power supply class has predefined set of attributes, this eliminates code
+duplication across drivers. Power supply class insist on reusing its
+predefined attributes *and* their units.
+
+So, userspace gets predictable set of attributes and their units for any
+kind of power supply, and can process/present them to a user in consistent
+manner. Results for different power supplies and machines are also directly
+comparable.
+
+See drivers/power/ds2760_battery.c and drivers/power/pda_power.c for the
+example how to declare and handle attributes.
+
+
+Units
+~~~~~
+Quoting include/linux/power_supply.h:
+
+  All voltages, currents, charges, energies, time and temperatures in ÂµV,
+  ÂµA, ÂµAh, ÂµWh, seconds and tenths of degree Celsius unless otherwise
+  stated. It's driver's job to convert its raw values to units in which
+  this class operates.
+
+
+Attributes/properties detailed
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+~ ~ ~ ~ ~ ~ ~  Charge/Energy/Capacity - how to not confuse  ~ ~ ~ ~ ~ ~ ~
+~                                                                       ~
+~ Because both "charge" (µAh) and "energy" (µWh) represents "capacity"  ~
+~ of battery, this class distinguish these terms. Don't mix them!       ~
+~                                                                       ~
+~ CHARGE_* attributes represents capacity in ÂµAh only.                  ~
+~ ENERGY_* attributes represents capacity in ÂµWh only.                  ~
+~ CAPACITY attribute represents capacity in *percents*, from 0 to 100.  ~
+~                                                                       ~
+~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+
+Postfixes:
+_AVG - *hardware* averaged value, use it if your hardware is really able to
+report averaged values.
+_NOW - momentary/instantaneous values.
+
+STATUS - this attribute represents operating status (charging, full,
+discharging (i.e. powering a load), etc.). This corresponds to
+BATTERY_STATUS_* values, as defined in battery.h.
+
+HEALTH - represents health of the battery, values corresponds to
+POWER_SUPPLY_HEALTH_*, defined in battery.h.
+
+VOLTAGE_MAX_DESIGN, VOLTAGE_MIN_DESIGN - design values for maximal and
+minimal power supply voltages. Maximal/minimal means values of voltages
+when battery considered "full"/"empty" at normal conditions. Yes, there is
+no direct relation between voltage and battery capacity, but some dumb
+batteries use voltage for very approximated calculation of capacity.
+Battery driver also can use this attribute just to inform userspace
+about maximal and minimal voltage thresholds of a given battery.
+
+CHARGE_FULL_DESIGN, CHARGE_EMPTY_DESIGN - design charge values, when
+battery considered full/empty.
+
+ENERGY_FULL_DESIGN, ENERGY_EMPTY_DESIGN - same as above but for energy.
+
+CHARGE_FULL, CHARGE_EMPTY - These attributes means "last remembered value
+of charge when battery became full/empty". It also could mean "value of
+charge when battery considered full/empty at given conditions (temperature,
+age)". I.e. these attributes represents real thresholds, not design values.
+
+ENERGY_FULL, ENERGY_EMPTY - same as above but for energy.
+
+CAPACITY - capacity in percents.
+CAPACITY_LEVEL - capacity level. This corresponds to
+POWER_SUPPLY_CAPACITY_LEVEL_*.
+
+TEMP - temperature of the power supply.
+TEMP_AMBIENT - ambient temperature.
+
+TIME_TO_EMPTY - seconds left for battery to be considered empty (i.e.
+while battery powers a load)
+TIME_TO_FULL - seconds left for battery to be considered full (i.e.
+while battery is charging)
+
+
+Battery <-> external power supply interaction
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Often power supplies are acting as supplies and supplicants at the same
+time. Batteries are good example. So, batteries usually care if they're
+externally powered or not.
+
+For that case, power supply class implements notification mechanism for
+batteries.
+
+External power supply (AC) lists supplicants (batteries) names in
+"supplied_to" struct member, and each power_supply_changed() call
+issued by external power supply will notify supplicants via
+external_power_changed callback.
+
+
+QA
+~~
+Q: Where is POWER_SUPPLY_PROP_XYZ attribute?
+A: If you cannot find attribute suitable for your driver needs, feel free
+   to add it and send patch along with your driver.
+
+   The attributes available currently are the ones currently provided by the
+   drivers written.
+
+   Good candidates to add in future: model/part#, cycle_time, manufacturer,
+   etc.
+
+
+Q: I have some very specific attribute (e.g. battery color), should I add
+   this attribute to standard ones?
+A: Most likely, no. Such attribute can be placed in the driver itself, if
+   it is useful. Of course, if the attribute in question applicable to
+   large set of batteries, provided by many drivers, and/or comes from
+   some general battery specification/standard, it may be a candidate to
+   be added to the core attribute set.
+
+
+Q: Suppose, my battery monitoring chip/firmware does not provides capacity
+   in percents, but provides charge_{now,full,empty}. Should I calculate
+   percentage capacity manually, inside the driver, and register CAPACITY
+   attribute? The same question about time_to_empty/time_to_full.
+A: Most likely, no. This class is designed to export properties which are
+   directly measurable by the specific hardware available.
+
+   Inferring not available properties using some heuristics or mathematical
+   model is not subject of work for a battery driver. Such functionality
+   should be factored out, and in fact, apm_power, the driver to serve
+   legacy APM API on top of power supply class, uses a simple heuristic of
+   approximating remaining battery capacity based on its charge, current,
+   voltage and so on. But full-fledged battery model is likely not subject
+   for kernel at all, as it would require floating point calculation to deal
+   with things like differential equations and Kalman filters. This is
+   better be handled by batteryd/libbattery, yet to be written.
diff --git a/Documentation/sched-design-CFS.txt b/Documentation/sched-design-CFS.txt
new file mode 100644 (file)
index 0000000..16feebb
--- /dev/null
@@ -0,0 +1,119 @@
+
+This is the CFS scheduler.
+
+80% of CFS's design can be summed up in a single sentence: CFS basically
+models an "ideal, precise multi-tasking CPU" on real hardware.
+
+"Ideal multi-tasking CPU" is a (non-existent  :-))  CPU that has 100%
+physical power and which can run each task at precise equal speed, in
+parallel, each at 1/nr_running speed. For example: if there are 2 tasks
+running then it runs each at 50% physical power - totally in parallel.
+
+On real hardware, we can run only a single task at once, so while that
+one task runs, the other tasks that are waiting for the CPU are at a
+disadvantage - the current task gets an unfair amount of CPU time. In
+CFS this fairness imbalance is expressed and tracked via the per-task
+p->wait_runtime (nanosec-unit) value. "wait_runtime" is the amount of
+time the task should now run on the CPU for it to become completely fair
+and balanced.
+
+( small detail: on 'ideal' hardware, the p->wait_runtime value would
+  always be zero - no task would ever get 'out of balance' from the
+  'ideal' share of CPU time. )
+
+CFS's task picking logic is based on this p->wait_runtime value and it
+is thus very simple: it always tries to run the task with the largest
+p->wait_runtime value. In other words, CFS tries to run the task with
+the 'gravest need' for more CPU time. So CFS always tries to split up
+CPU time between runnable tasks as close to 'ideal multitasking
+hardware' as possible.
+
+Most of the rest of CFS's design just falls out of this really simple
+concept, with a few add-on embellishments like nice levels,
+multiprocessing and various algorithm variants to recognize sleepers.
+
+In practice it works like this: the system runs a task a bit, and when
+the task schedules (or a scheduler tick happens) the task's CPU usage is
+'accounted for': the (small) time it just spent using the physical CPU
+is deducted from p->wait_runtime. [minus the 'fair share' it would have
+gotten anyway]. Once p->wait_runtime gets low enough so that another
+task becomes the 'leftmost task' of the time-ordered rbtree it maintains
+(plus a small amount of 'granularity' distance relative to the leftmost
+task so that we do not over-schedule tasks and trash the cache) then the
+new leftmost task is picked and the current task is preempted.
+
+The rq->fair_clock value tracks the 'CPU time a runnable task would have
+fairly gotten, had it been runnable during that time'. So by using
+rq->fair_clock values we can accurately timestamp and measure the
+'expected CPU time' a task should have gotten. All runnable tasks are
+sorted in the rbtree by the "rq->fair_clock - p->wait_runtime" key, and
+CFS picks the 'leftmost' task and sticks to it. As the system progresses
+forwards, newly woken tasks are put into the tree more and more to the
+right - slowly but surely giving a chance for every task to become the
+'leftmost task' and thus get on the CPU within a deterministic amount of
+time.
+
+Some implementation details:
+
+ - the introduction of Scheduling Classes: an extensible hierarchy of
+   scheduler modules. These modules encapsulate scheduling policy
+   details and are handled by the scheduler core without the core
+   code assuming about them too much.
+
+ - sched_fair.c implements the 'CFS desktop scheduler': it is a
+   replacement for the vanilla scheduler's SCHED_OTHER interactivity
+   code.
+
+   I'd like to give credit to Con Kolivas for the general approach here:
+   he has proven via RSDL/SD that 'fair scheduling' is possible and that
+   it results in better desktop scheduling. Kudos Con!
+
+   The CFS patch uses a completely different approach and implementation
+   from RSDL/SD. My goal was to make CFS's interactivity quality exceed
+   that of RSDL/SD, which is a high standard to meet :-) Testing
+   feedback is welcome to decide this one way or another. [ and, in any
+   case, all of SD's logic could be added via a kernel/sched_sd.c module
+   as well, if Con is interested in such an approach. ]
+
+   CFS's design is quite radical: it does not use runqueues, it uses a
+   time-ordered rbtree to build a 'timeline' of future task execution,
+   and thus has no 'array switch' artifacts (by which both the vanilla
+   scheduler and RSDL/SD are affected).
+
+   CFS uses nanosecond granularity accounting and does not rely on any
+   jiffies or other HZ detail. Thus the CFS scheduler has no notion of
+   'timeslices' and has no heuristics whatsoever. There is only one
+   central tunable:
+
+         /proc/sys/kernel/sched_granularity_ns
+
+   which can be used to tune the scheduler from 'desktop' (low
+   latencies) to 'server' (good batching) workloads. It defaults to a
+   setting suitable for desktop workloads. SCHED_BATCH is handled by the
+   CFS scheduler module too.
+
+   Due to its design, the CFS scheduler is not prone to any of the
+   'attacks' that exist today against the heuristics of the stock
+   scheduler: fiftyp.c, thud.c, chew.c, ring-test.c, massive_intr.c all
+   work fine and do not impact interactivity and produce the expected
+   behavior.
+
+   the CFS scheduler has a much stronger handling of nice levels and
+   SCHED_BATCH: both types of workloads should be isolated much more
+   agressively than under the vanilla scheduler.
+
+   ( another detail: due to nanosec accounting and timeline sorting,
+     sched_yield() support is very simple under CFS, and in fact under
+     CFS sched_yield() behaves much better than under any other
+     scheduler i have tested so far. )
+
+ - sched_rt.c implements SCHED_FIFO and SCHED_RR semantics, in a simpler
+   way than the vanilla scheduler does. It uses 100 runqueues (for all
+   100 RT priority levels, instead of 140 in the vanilla scheduler)
+   and it needs no expired array.
+
+ - reworked/sanitized SMP load-balancing: the runqueue-walking
+   assumptions are gone from the load-balancing code now, and
+   iterators of the scheduling modules are used. The balancing code got
+   quite a bit simpler as a result.
+
index 1d192565e18207188cc93b54d962dd7d5974d7bb..8cfca173d4bca46fab5c121be80d070858aaa0c6 100644 (file)
@@ -31,6 +31,7 @@ Currently, these files are in /proc/sys/vm:
 - min_unmapped_ratio
 - min_slab_ratio
 - panic_on_oom
+- mmap_min_address
 
 ==============================================================
 
@@ -216,3 +217,17 @@ above-mentioned.
 The default value is 0.
 1 and 2 are for failover of clustering. Please select either
 according to your policy of failover.
+
+==============================================================
+
+mmap_min_addr
+
+This file indicates the amount of address space  which a user process will
+be restricted from mmaping.  Since kernel null dereference bugs could
+accidentally operate based on the information in the first couple of pages
+of memory userspace processes should not be allowed to write to them.  By
+default this value is set to 0 and no protections will be enforced by the
+security module.  Setting this value to something like 64k will allow the
+vast majority of applications to work correctly and provide defense in depth
+against future potential kernel bugs.
+
diff --git a/Documentation/sysfs-rules.txt b/Documentation/sysfs-rules.txt
new file mode 100644 (file)
index 0000000..42861bb
--- /dev/null
@@ -0,0 +1,166 @@
+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 can not provide a stable interface eighter,
+it may always change along with internal kernel changes.
+
+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
+of sysfs must follow some rules to use an as abstract-as-possible way to
+access this filesystem. The current udev and HAL programs already
+implement this and users are encouraged to plug, if possible, into the
+abstractions these programs provide instead of accessing sysfs
+directly.
+
+But if you really do want or need to access sysfs directly, please follow
+the following rules and then your programs should work with future
+versions of the sysfs interface.
+
+- Do not use libsysfs
+  It makes assumptions about sysfs which are not true. Its API does not
+  offer any abstraction, it exposes all the kernel driver-core
+  implementation details in its own API. Therefore it is not better than
+  reading directories and opening the files yourself.
+  Also, it is not actively maintained, in the sense of reflecting the
+  current kernel-development. The goal of providing a stable interface
+  to sysfs has failed, it causes more problems, than it solves. It
+  violates many of the rules in this document.
+
+- sysfs is always at /sys
+  Parsing /proc/mounts is a waste of time. Other mount points are a
+  system configuration bug you should not try to solve. For test cases,
+  possibly support a SYSFS_PATH environment variable to overwrite the
+  applications behavior, but never try to search for sysfs. Never try
+  to mount it, if you are not an early boot script.
+
+- devices are only "devices"
+  There is no such thing like class-, bus-, physical devices,
+  interfaces, and such that you can rely on in userspace. Everything is
+  just simply a "device". Class-, bus-, physical, ... types are just
+  kernel implementation details, which should not be expected by
+  applications that look for devices in sysfs.
+
+  The properties of a device are:
+    o devpath (/devices/pci0000:00/0000:00:1d.1/usb2/2-2/2-2:1.0)
+      - identical to the DEVPATH value in the event sent from the kernel
+        at device creation and removal
+      - the unique key to the device at that point in time
+      - the kernels path to the device-directory without the leading
+        /sys, and always starting with with a slash
+      - all elements of a devpath must be real directories. Symlinks
+        pointing to /sys/devices must always be resolved to their real
+        target, and the target path must be used to access the device.
+        That way the devpath to the device matches the devpath of the
+        kernel used at event time.
+      - using or exposing symlink values as elements in a devpath string
+        is a bug in the application
+
+    o kernel name (sda, tty, 0000:00:1f.2, ...)
+      - a directory name, identical to the last element of the devpath
+      - applications need to handle spaces and characters like '!' in
+        the name
+
+    o subsystem (block, tty, pci, ...)
+      - simple string, never a path or a link
+      - retrieved by reading the "subsystem"-link and using only the
+        last element of the target path
+
+    o driver (tg3, ata_piix, uhci_hcd)
+      - a simple string, which may contain spaces, never a path or a
+        link
+      - it is retrieved by reading the "driver"-link and using only the
+        last element of the target path
+      - devices which do not have "driver"-link, just do not have a
+        driver; copying the driver value in a child device context, is a
+        bug in the application
+
+    o attributes
+      - the files in the device directory or files below a subdirectories
+        of the same device directory
+      - accessing attributes reached by a symlink pointing to another device,
+        like the "device"-link, is a bug in the application
+
+  Everything else is just a kernel driver-core implementation detail,
+  that should not be assumed to be stable across kernel releases.
+
+- Properties of parent devices never belong into a child device.
+  Always look at the parent devices themselves for determining device
+  context properties. If the device 'eth0' or 'sda' does not have a
+  "driver"-link, then this device does not have a driver. Its value is empty.
+  Never copy any property of the parent-device into a child-device. Parent
+  device-properties may change dynamically without any notice to the
+  child device.
+
+- Hierarchy in a single device-tree
+  There is only one valid place in sysfs where hierarchy can be examined
+  and this is below: /sys/devices.
+  It is planned, that all device directories will end up in the tree
+  below this directory.
+
+- Classification by subsystem
+  There are currently three places for classification of devices:
+  /sys/block, /sys/class and /sys/bus. It is planned that these will
+  not contain any device-directories themselves, but only flat lists of
+  symlinks pointing to the unified /sys/devices tree.
+  All three places have completely different rules on how to access
+  device information. It is planned to merge all three
+  classification-directories into one place at /sys/subsystem,
+  following the layout of the bus-directories. All buses and
+  classes, including the converted block-subsystem, will show up
+  there.
+  The devices belonging to a subsystem will create a symlink in the
+  "devices" directory at /sys/subsystem/<name>/devices.
+
+  If /sys/subsystem exists, /sys/bus, /sys/class and /sys/block can be
+  ignored. If it does not exist, you have always to scan all three
+  places, as the kernel is free to move a subsystem from one place to
+  the other, as long as the devices are still reachable by the same
+  subsystem name.
+
+  Assuming /sys/class/<subsystem> and /sys/bus/<subsystem>, or
+  /sys/block and /sys/class/block are not interchangeable, is a bug in
+  the application.
+
+- Block
+  The converted block-subsystem at /sys/class/block, or
+  /sys/subsystem/block will contain the links for disks and partitions
+  at the same level, never in a hierarchy. Assuming the block-subsytem to
+  contain only disks and not partition-devices in the same flat list is
+  a bug in the application.
+
+- "device"-link and <subsystem>:<kernel name>-links
+  Never depend on the "device"-link. The "device"-link is a workaround
+  for the old layout, where class-devices are not created in
+  /sys/devices/ like the bus-devices. If the link-resolving of a
+  device-directory does not end in /sys/devices/, you can use the
+  "device"-link to find the parent devices in /sys/devices/. That is the
+  single valid use of the "device"-link, it must never appear in any
+  path as an element. Assuming the existence of the "device"-link for
+  a device in /sys/devices/ is a bug in the application.
+  Accessing /sys/class/net/eth0/device is a bug in the application.
+
+  Never depend on the class-specific links back to the /sys/class
+  directory.  These links are also a workaround for the design mistake
+  that class-devices are not created in /sys/devices. If a device
+  directory does not contain directories for child devices, these links
+  may be used to find the child devices in /sys/class. That is the single
+  valid use of these links, they must never appear in any path as an
+  element. Assuming the existence of these links for devices which are
+  real child device directories in the /sys/devices tree, is a bug in
+  the application.
+
+  It is planned to remove all these links when when all class-device
+  directories live in /sys/devices.
+
+- Position of devices along device chain can change.
+  Never depend on a specific parent device position in the devpath,
+  or the chain of parent devices. The kernel is free to insert devices into
+  the chain. You must always request the parent device you are looking for
+  by its subsystem value. You need to walk up the chain until you find
+  the device that matches the expected subsystem. Depending on a specific
+  position of a parent device, or exposing relative paths, using "../" to
+  access the chain of parents, is a bug in the application.
+
index 62844aeba69cb4a5c37604f06d7e9de7a04d769d..e8b50b7de9d943d3efd3da6e55ebc12ce533f230 100644 (file)
@@ -32,12 +32,15 @@ ELIMINATING COPIES
 It's good to avoid making CPUs copy data needlessly.  The costs can add up,
 and effects like cache-trashing can impose subtle penalties.
 
-- When you're allocating a buffer for DMA purposes anyway, use the buffer
-  primitives.  Think of them as kmalloc and kfree that give you the right
-  kind of addresses to store in urb->transfer_buffer and urb->transfer_dma,
-  while guaranteeing that no hidden copies through DMA "bounce" buffers will
-  slow things down.  You'd also set URB_NO_TRANSFER_DMA_MAP in
-  urb->transfer_flags:
+- If you're doing lots of small data transfers from the same buffer all
+  the time, that can really burn up resources on systems which use an
+  IOMMU to manage the DMA mappings.  It can cost MUCH more to set up and
+  tear down the IOMMU mappings with each request than perform the I/O!
+
+  For those specific cases, USB has primitives to allocate less expensive
+  memory.  They work like kmalloc and kfree versions that give you the right
+  kind of addresses to store in urb->transfer_buffer and urb->transfer_dma.
+  You'd also set URB_NO_TRANSFER_DMA_MAP in urb->transfer_flags:
 
        void *usb_buffer_alloc (struct usb_device *dev, size_t size,
                int mem_flags, dma_addr_t *dma);
@@ -45,6 +48,10 @@ and effects like cache-trashing can impose subtle penalties.
        void usb_buffer_free (struct usb_device *dev, size_t size,
                void *addr, dma_addr_t dma);
 
+  Most drivers should *NOT* be using these primitives; they don't need
+  to use this type of memory ("dma-coherent"), and memory returned from
+  kmalloc() will work just fine.
+
   For control transfers you can use the buffer primitives or not for each
   of the transfer buffer and setup buffer independently.  Set the flag bits
   URB_NO_TRANSFER_DMA_MAP and URB_NO_SETUP_DMA_MAP to indicate which
@@ -54,29 +61,39 @@ and effects like cache-trashing can impose subtle penalties.
   The memory buffer returned is "dma-coherent"; sometimes you might need to
   force a consistent memory access ordering by using memory barriers.  It's
   not using a streaming DMA mapping, so it's good for small transfers on
-  systems where the I/O would otherwise tie up an IOMMU mapping.  (See
+  systems where the I/O would otherwise thrash an IOMMU mapping.  (See
   Documentation/DMA-mapping.txt for definitions of "coherent" and "streaming"
   DMA mappings.)
 
   Asking for 1/Nth of a page (as well as asking for N pages) is reasonably
   space-efficient.
 
+  On most systems the memory returned will be uncached, because the
+  semantics of dma-coherent memory require either bypassing CPU caches
+  or using cache hardware with bus-snooping support.  While x86 hardware
+  has such bus-snooping, many other systems use software to flush cache
+  lines to prevent DMA conflicts.
+
 - Devices on some EHCI controllers could handle DMA to/from high memory.
-  Driver probe() routines can notice this using a generic DMA call, then
-  tell higher level code (network, scsi, etc) about it like this:
 
-       if (dma_supported (&intf->dev, 0xffffffffffffffffULL))
-               net->features |= NETIF_F_HIGHDMA;
+  Unfortunately, the current Linux DMA infrastructure doesn't have a sane
+  way to expose these capabilities ... and in any case, HIGHMEM is mostly a
+  design wart specific to x86_32.  So your best bet is to ensure you never
+  pass a highmem buffer into a USB driver.  That's easy; it's the default
+  behavior.  Just don't override it; e.g. with NETIF_F_HIGHDMA.
 
-  That can eliminate dma bounce buffering of requests that originate (or
-  terminate) in high memory, in cases where the buffers aren't allocated
-  with usb_buffer_alloc() but instead are dma-mapped.
+  This may force your callers to do some bounce buffering, copying from
+  high memory to "normal" DMA memory.  If you can come up with a good way
+  to fix this issue (for x86_32 machines with over 1 GByte of memory),
+  feel free to submit patches.
 
 
 WORKING WITH EXISTING BUFFERS
 
 Existing buffers aren't usable for DMA without first being mapped into the
-DMA address space of the device.
+DMA address space of the device.  However, most buffers passed to your
+driver can safely be used with such DMA mapping.  (See the first section
+of DMA-mapping.txt, titled "What memory is DMA-able?")
 
 - When you're using scatterlists, you can map everything at once.  On some
   systems, this kicks in an IOMMU and turns the scatterlists into single
@@ -114,3 +131,8 @@ DMA address space of the device.
   The calls manage urb->transfer_dma for you, and set URB_NO_TRANSFER_DMA_MAP
   so that usbcore won't map or unmap the buffer.  The same goes for
   urb->setup_dma and URB_NO_SETUP_DMA_MAP for control requests.
+
+Note that several of those interfaces are currently commented out, since
+they don't have current users.  See the source code.  Other than the dmasync
+calls (where the underlying DMA primitives have changed), most of them can
+easily be commented back in if you want to use them.
diff --git a/Documentation/usb/persist.txt b/Documentation/usb/persist.txt
new file mode 100644 (file)
index 0000000..df54d64
--- /dev/null
@@ -0,0 +1,156 @@
+               USB device persistence during system suspend
+
+                  Alan Stern <stern@rowland.harvard.edu>
+
+                September 2, 2006 (Updated May 29, 2007)
+
+
+       What is the problem?
+
+According to the USB specification, when a USB bus is suspended the
+bus must continue to supply suspend current (around 1-5 mA).  This
+is so that devices can maintain their internal state and hubs can
+detect connect-change events (devices being plugged in or unplugged).
+The technical term is "power session".
+
+If a USB device's power session is interrupted then the system is
+required to behave as though the device has been unplugged.  It's a
+conservative approach; in the absence of suspend current the computer
+has no way to know what has actually happened.  Perhaps the same
+device is still attached or perhaps it was removed and a different
+device plugged into the port.  The system must assume the worst.
+
+By default, Linux behaves according to the spec.  If a USB host
+controller loses power during a system suspend, then when the system
+wakes up all the devices attached to that controller are treated as
+though they had disconnected.  This is always safe and it is the
+"officially correct" thing to do.
+
+For many sorts of devices this behavior doesn't matter in the least.
+If the kernel wants to believe that your USB keyboard was unplugged
+while the system was asleep and a new keyboard was plugged in when the
+system woke up, who cares?  It'll still work the same when you type on
+it.
+
+Unfortunately problems _can_ arise, particularly with mass-storage
+devices.  The effect is exactly the same as if the device really had
+been unplugged while the system was suspended.  If you had a mounted
+filesystem on the device, you're out of luck -- everything in that
+filesystem is now inaccessible.  This is especially annoying if your
+root filesystem was located on the device, since your system will
+instantly crash.
+
+Loss of power isn't the only mechanism to worry about.  Anything that
+interrupts a power session will have the same effect.  For example,
+even though suspend current may have been maintained while the system
+was asleep, on many systems during the initial stages of wakeup the
+firmware (i.e., the BIOS) resets the motherboard's USB host
+controllers.  Result: all the power sessions are destroyed and again
+it's as though you had unplugged all the USB devices.  Yes, it's
+entirely the BIOS's fault, but that doesn't do _you_ any good unless
+you can convince the BIOS supplier to fix the problem (lots of luck!).
+
+On many systems the USB host controllers will get reset after a
+suspend-to-RAM.  On almost all systems, no suspend current is
+available during hibernation (also known as swsusp or suspend-to-disk).
+You can check the kernel log after resuming to see if either of these
+has happened; look for lines saying "root hub lost power or was reset".
+
+In practice, people are forced to unmount any filesystems on a USB
+device before suspending.  If the root filesystem is on a USB device,
+the system can't be suspended at all.  (All right, it _can_ be
+suspended -- but it will crash as soon as it wakes up, which isn't
+much better.)
+
+
+       What is the solution?
+
+Setting CONFIG_USB_PERSIST will cause the kernel to work around these
+issues.  It enables a mode in which the core USB device data
+structures are allowed to persist across a power-session disruption.
+It works like this.  If the kernel sees that a USB host controller is
+not in the expected state during resume (i.e., if the controller was
+reset or otherwise had lost power) then it applies a persistence check
+to each of the USB devices below that controller for which the
+"persist" attribute is set.  It doesn't try to resume the device; that
+can't work once the power session is gone.  Instead it issues a USB
+port reset and then re-enumerates the device.  (This is exactly the
+same thing that happens whenever a USB device is reset.)  If the
+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.
+
+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
+you would expect.  The kernel destroys the old device structure and
+behaves as though the old device had been unplugged and a new device
+plugged in, just as it would without the CONFIG_USB_PERSIST option.
+
+The end result is that the USB device remains available and usable.
+Filesystem mounts and memory mappings are unaffected, and the world is
+now a good and happy place.
+
+Note that even when CONFIG_USB_PERSIST is set, the "persist" feature
+will be applied only to those devices for which it is enabled.  You
+can enable the feature by doing (as root):
+
+       echo 1 >/sys/bus/usb/devices/.../power/persist
+
+where the "..." should be filled in the with the device's ID.  Disable
+the feature by writing 0 instead of 1.  For hubs the feature is
+automatically and permanently enabled, so you only have to worry about
+setting it for devices where it really matters.
+
+
+       Is this the best solution?
+
+Perhaps not.  Arguably, keeping track of mounted filesystems and
+memory mappings across device disconnects should be handled by a
+centralized Logical Volume Manager.  Such a solution would allow you
+to plug in a USB flash device, create a persistent volume associated
+with it, unplug the flash device, plug it back in later, and still
+have the same persistent volume associated with the device.  As such
+it would be more far-reaching than CONFIG_USB_PERSIST.
+
+On the other hand, writing a persistent volume manager would be a big
+job and using it would require significant input from the user.  This
+solution is much quicker and easier -- and it exists now, a giant
+point in its favor!
+
+Furthermore, the USB_PERSIST option applies to _all_ USB devices, not
+just mass-storage devices.  It might turn out to be equally useful for
+other device types, such as network interfaces.
+
+
+       WARNING: Using CONFIG_USB_PERSIST can be dangerous!!
+
+When recovering an interrupted power session the kernel does its best
+to make sure the USB device hasn't been changed; that is, the same
+device is still plugged into the port as before.  But the checks
+aren't guaranteed to be 100% accurate.
+
+If you replace one USB device with another of the same type (same
+manufacturer, same IDs, and so on) there's an excellent chance the
+kernel won't detect the change.  Serial numbers and other strings are
+not compared.  In many cases it wouldn't help if they were, because
+manufacturers frequently omit serial numbers entirely in their
+devices.
+
+Furthermore it's quite possible to leave a USB device exactly the same
+while changing its media.  If you replace the flash memory card in a
+USB card reader while the system is asleep, the kernel will have no
+way to know you did it.  The kernel will assume that nothing has
+happened and will continue to use the partition tables, inodes, and
+memory mappings for the old card.
+
+If the kernel gets fooled in this way, it's almost certain to cause
+data corruption and to crash your system.  You'll have no one to blame
+but yourself.
+
+YOU HAVE BEEN WARNED!  USE AT YOUR OWN RISK!
+
+That having been said, most of the time there shouldn't be any trouble
+at all.  The "persist" feature can be extremely useful.  Make the most
+of it.
index df40a4ec87fbff098d79b52caa98f531b5b5a8f3..845fbf4478b3adc2b972617892db8fadb8177fd2 100644 (file)
@@ -315,10 +315,9 @@ M: zippel@linux-m68k.org
 S:     Maintained
 
 AGPGART DRIVER
-P:     Dave Jones
-M:     davej@codemonkey.org.uk
-W:     http://www.codemonkey.org.uk/projects/agp/
-T:     git kernel.org:/pub/scm/linux/kernel/git/davej/agpgart.git
+P:     David Airlie
+M:     airlied@linux.ie
+T:     git kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6.git
 S:     Maintained
 
 AHA152X SCSI DRIVER
@@ -371,7 +370,7 @@ P:  Tom Tucker
 M:     tom@opengridcomputing.com
 P:     Steve Wise
 M:     swise@opengridcomputing.com
-L:     openib-general@openib.org
+L:     general@lists.openfabrics.org
 S:     Maintained
 
 AOA (Apple Onboard Audio) ALSA DRIVER
@@ -1396,7 +1395,7 @@ P:        Hoang-Nam Nguyen
 M:     hnguyen@de.ibm.com
 P:     Christoph Raisch
 M:     raisch@de.ibm.com
-L:     openib-general@openib.org
+L:     general@lists.openfabrics.org
 S:     Supported
 
 EMU10K1 SOUND DRIVER
@@ -1750,8 +1749,8 @@ T:        http://www.harbaum.org/till/i2c_tiny_usb
 S:     Maintained
 
 i386 BOOT CODE
-P:     Riley H. Williams
-M:     Riley@Williams.Name
+P:     H. Peter Anvin
+M:     hpa@zytor.com
 L:     Linux-Kernel@vger.kernel.org
 S:     Maintained
 
@@ -1850,13 +1849,13 @@ M:      rolandd@cisco.com
 P:     Sean Hefty
 M:     mshefty@ichips.intel.com
 P:     Hal Rosenstock
-M:     halr@voltaire.com
-L:     openib-general@openib.org
+M:     hal.rosenstock@gmail.com 
+L:     general@lists.openfabrics.org
 W:     http://www.openib.org/
 T:     git kernel.org:/pub/scm/linux/kernel/git/roland/infiniband.git
 S:     Supported
 
-INPUT (KEYBOARD, MOUSE, JOYSTICK) DRIVERS
+INPUT (KEYBOARD, MOUSE, JOYSTICK, TOUCHSCREEN) DRIVERS
 P:     Dmitry Torokhov
 M:     dmitry.torokhov@gmail.com
 M:     dtor@mail.ru
@@ -1989,9 +1988,10 @@ M:       jjciarla@raiz.uncu.edu.ar
 S:     Maintained
 
 IPATH DRIVER:
-P:     Bryan O'Sullivan
-M:     support@pathscale.com
-L:     openib-general@openib.org
+P:     Arthur Jones
+M:     infinipath@qlogic.com
+L:     general@lists.openfabrics.org
+T:     git git://git.qlogic.com/ipath-linux-2.6
 S:     Supported
 
 IPMI SUBSYSTEM
@@ -2814,11 +2814,6 @@ P:       Kristen Carlson Accardi
 M:     kristen.c.accardi@intel.com
 S:     Supported
 
-PCI HOTPLUG COMPAQ DRIVER
-P:     Greg Kroah-Hartman
-M:     greg@kroah.com
-S:     Maintained
-
 PCIE HOTPLUG DRIVER
 P:     Kristen Carlson Accardi
 M:     kristen.c.accardi@intel.com
@@ -2903,6 +2898,11 @@ P:       Michal Ostrowski
 M:     mostrows@speakeasy.net
 S:     Maintained
 
+PPP OVER L2TP
+P:     James Chapman
+M:     jchapman@katalix.com
+S:     Maintained
+
 PREEMPTIBLE KERNEL
 P:     Robert Love
 M:     rml@tech9.net
@@ -2930,6 +2930,13 @@ M:       mikpe@it.uu.se
 L:     linux-ide@vger.kernel.org
 S:     Maintained
 
+PS3 NETWORK SUPPORT
+P:     Masakazu Mokuno
+M:     mokuno@sm.sony.co.jp
+L:     netdev@vger.kernel.org
+L:     cbe-oss-dev@ozlabs.org
+S:     Supported
+
 PS3 PLATFORM SUPPORT
 P:     Geoff Levand
 M:     geoffrey.levand@am.sony.com
@@ -3049,6 +3056,16 @@ S:       Maintained
 RISCOM8 DRIVER
 S:     Orphan
 
+RTL818X WIRELESS DRIVER
+P:     Michael Wu
+M:     flamingice@sourmilk.net
+P:     Andrea Merello
+M:     andreamrl@tiscali.it
+L:     linux-wireless@vger.kernel.org
+W:     http://linuxwireless.org/
+T:     git kernel.org:/pub/scm/linux/kernel/git/mwu/mac80211-drivers.git
+S:     Maintained
+
 S3 SAVAGE FRAMEBUFFER DRIVER
 P:     Antonino Daplas
 M:     adaplas@gmail.com
@@ -3707,12 +3724,12 @@ L:      netdev@vger.kernel.org
 W:     http://pegasus2.sourceforge.net/
 S:     Maintained
 
-USB PRINTER DRIVER
-P:     Vojtech Pavlik
-M:     vojtech@suse.cz
+USB PRINTER DRIVER (usblp)
+P:     Pete Zaitcev
+M:     zaitcev@redhat.com
 L:     linux-usb-users@lists.sourceforge.net
 L:     linux-usb-devel@lists.sourceforge.net
-S:     Maintained
+S:     Supported
 
 USB RTL8150 DRIVER
 P:     Petko Manolov
index 79c6e5a2445652679b4aafa5d647e06248fe27b2..2a85dc33907c2c66f09c3e3ce61e96ef19e23d3a 100644 (file)
@@ -327,6 +327,9 @@ config PCI_DOMAINS
        bool
        default y
 
+config PCI_SYSCALL
+       def_bool PCI
+
 config ALPHA_CORE_AGP
        bool
        depends on ALPHA_GENERIC || ALPHA_TITAN || ALPHA_MARVEL
index 28c84e55feb9b80440deda421730ff0c126e2963..6b07f89a72c70af2b4bf11d7ab5eb3653db0102c 100644 (file)
@@ -207,6 +207,10 @@ iommu_arena_free(struct pci_iommu_arena *arena, long ofs, long n)
                p[i] = 0;
 }
 \f
+/* True if the machine supports DAC addressing, and DEV can
+   make use of it given MASK.  */
+static int pci_dac_dma_supported(struct pci_dev *hwdev, u64 mask);
+
 /* Map a single buffer of the indicated size for PCI DMA in streaming
    mode.  The 32-bit PCI bus mastering address to use is returned.
    Once the device is given the dma address, the device owns this memory
@@ -897,7 +901,7 @@ iommu_unbind(struct pci_iommu_arena *arena, long pg_start, long pg_count)
 /* True if the machine supports DAC addressing, and DEV can
    make use of it given MASK.  */
 
-int
+static int
 pci_dac_dma_supported(struct pci_dev *dev, u64 mask)
 {
        dma64_addr_t dac_offset = alpha_mv.pci_dac_offset;
@@ -917,32 +921,6 @@ pci_dac_dma_supported(struct pci_dev *dev, u64 mask)
 
        return ok;
 }
-EXPORT_SYMBOL(pci_dac_dma_supported);
-
-dma64_addr_t
-pci_dac_page_to_dma(struct pci_dev *pdev, struct page *page,
-                   unsigned long offset, int direction)
-{
-       return (alpha_mv.pci_dac_offset
-               + __pa(page_address(page)) 
-               + (dma64_addr_t) offset);
-}
-EXPORT_SYMBOL(pci_dac_page_to_dma);
-
-struct page *
-pci_dac_dma_to_page(struct pci_dev *pdev, dma64_addr_t dma_addr)
-{
-       unsigned long paddr = (dma_addr & PAGE_MASK) - alpha_mv.pci_dac_offset;
-       return virt_to_page(__va(paddr));
-}
-EXPORT_SYMBOL(pci_dac_dma_to_page);
-
-unsigned long
-pci_dac_dma_to_offset(struct pci_dev *pdev, dma64_addr_t dma_addr)
-{
-       return (dma_addr & ~PAGE_MASK);
-}
-EXPORT_SYMBOL(pci_dac_dma_to_offset);
 
 /* Helper for generic DMA-mapping functions. */
 
index 0cb2d4f237e0d8e7b3432b891535e6049131ebe2..a44c6da9bf8363d21169eecb1521ef8f16144e7a 100644 (file)
@@ -241,6 +241,9 @@ config ARCH_H720X
 
 config ARCH_IMX
        bool "IMX"
+       select GENERIC_GPIO
+       select GENERIC_TIME
+       select GENERIC_CLOCKEVENTS
        help
          Support for Motorola's i.MX family of processors (MX1, MXL).
 
@@ -308,6 +311,7 @@ config ARCH_L7200
 
 config ARCH_KS8695
        bool "Micrel/Kendin KS8695"
+       select GENERIC_GPIO
        help
          Support for Micrel/Kendin KS8695 "Centaur" (ARM922T) based
          System-on-Chip devices.
@@ -384,6 +388,7 @@ config ARCH_DAVINCI
        bool "TI DaVinci"
        select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
+       select GENERIC_GPIO
        help
          Support for TI's DaVinci platform.
 
@@ -531,6 +536,9 @@ config PCI
          information about which PCI hardware does work under Linux and which
          doesn't.
 
+config PCI_SYSCALL
+       def_bool PCI
+
 # Select the host bridge type
 config PCI_HOST_VIA82C505
        bool
index aefee20cbf987abc7db39f5dc7084b0bed127b47..b15f927a5926187f90f0ba50da935c18a4a5061e 100644 (file)
@@ -1 +1,2 @@
 piggy.gz
+font.c
index adddc71316852f5001314faf10678f5fc4e3ef8d..a1f1691b67fe212f01c11a5e20f0f5fc78087fd3 100644 (file)
@@ -6,15 +6,13 @@
 
 HEAD   = head.o
 OBJS   = misc.o
-FONTC  = drivers/video/console/font_acorn_8x8.c
-
-FONT = $(addprefix ../../../../drivers/video/console/, font_acorn_8x8.o)
+FONTC  = $(srctree)/drivers/video/console/font_acorn_8x8.c
 
 #
 # Architecture dependencies
 #
 ifeq ($(CONFIG_ARCH_ACORN),y)
-OBJS           += ll_char_wr.o $(FONT)
+OBJS           += ll_char_wr.o font.o
 endif
 
 ifeq ($(CONFIG_ARCH_SHARK),y)
@@ -73,7 +71,7 @@ endif
 
 SEDFLAGS       = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/
 
-targets       := vmlinux vmlinux.lds piggy.gz piggy.o $(FONT) \
+targets       := vmlinux vmlinux.lds piggy.gz piggy.o font.o font.c \
                 head.o misc.o $(OBJS)
 EXTRA_CFLAGS  := -fpic
 EXTRA_AFLAGS  :=
@@ -105,7 +103,10 @@ $(obj)/piggy.gz: $(obj)/../Image FORCE
 
 $(obj)/piggy.o:  $(obj)/piggy.gz FORCE
 
-CFLAGS_font_acorn_8x8.o := -Dstatic=
+CFLAGS_font.o := -Dstatic=
+
+$(obj)/font.c: $(FONTC)
+       $(call cmd,shipped)
 
 $(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/arm/boot/Makefile .config
        @sed "$(SEDFLAGS)" < $< > $@
index 73c5d9e0201c47fd48b6a79194e3cb0413d5147f..236bbe5783123ceaaa3284bd7b1920007fb9f084 100644 (file)
@@ -41,11 +41,6 @@ __XScale_start:
                mov     r7, #MACH_TYPE_COTULLA_IDP
 #endif
 
-#ifdef  CONFIG_MACH_GTWX5715
-               mov     r7, #(MACH_TYPE_GTWX5715 & 0xff)
-               orr     r7, r7, #(MACH_TYPE_GTWX5715 & 0xff00)
-#endif
-
 #ifdef CONFIG_ARCH_IXP2000
                mov     r1, #-1
                mov     r0, #0xd6000000
index 680ea6ed77b89c746715f0a38c42142f52a0b4b3..d7fb5ee1637e8f25e23edcd69b7acbeca019b539 100644 (file)
@@ -436,6 +436,28 @@ __armv4_mmu_cache_on:
                mcr     p15, 0, r0, c8, c7, 0   @ flush I,D TLBs
                mov     pc, r12
 
+__armv7_mmu_cache_on:
+               mov     r12, lr
+               mrc     p15, 0, r11, c0, c1, 4  @ read ID_MMFR0
+               tst     r11, #0xf               @ VMSA
+               blne    __setup_mmu
+               mov     r0, #0
+               mcr     p15, 0, r0, c7, c10, 4  @ drain write buffer
+               tst     r11, #0xf               @ VMSA
+               mcrne   p15, 0, r0, c8, c7, 0   @ flush I,D TLBs
+               mrc     p15, 0, r0, c1, c0, 0   @ read control reg
+               orr     r0, r0, #0x5000         @ I-cache enable, RR cache replacement
+               orr     r0, r0, #0x003c         @ write buffer
+               orrne   r0, r0, #1              @ MMU enabled
+               movne   r1, #-1
+               mcrne   p15, 0, r3, c2, c0, 0   @ load page table pointer
+               mcrne   p15, 0, r1, c3, c0, 0   @ load domain access control
+               mcr     p15, 0, r0, c1, c0, 0   @ load control register
+               mrc     p15, 0, r0, c1, c0, 0   @ and read it back
+               mov     r0, #0
+               mcr     p15, 0, r0, c7, c5, 4   @ ISB
+               mov     pc, r12
+
 __arm6_mmu_cache_on:
                mov     r12, lr
                bl      __setup_mmu
@@ -622,11 +644,17 @@ proc_types:
                b       __armv4_mmu_cache_flush
 
                .word   0x0007b000              @ ARMv6
-               .word   0x0007f000
+               .word   0x000ff000
                b       __armv4_mmu_cache_on
                b       __armv4_mmu_cache_off
                b       __armv6_mmu_cache_flush
 
+               .word   0x000f0000              @ new CPU Id
+               .word   0x000f0000
+               b       __armv7_mmu_cache_on
+               b       __armv7_mmu_cache_off
+               b       __armv7_mmu_cache_flush
+
                .word   0                       @ unrecognised type
                .word   0
                mov     pc, lr
@@ -674,6 +702,16 @@ __armv4_mmu_cache_off:
                mcr     p15, 0, r0, c8, c7      @ invalidate whole TLB v4
                mov     pc, lr
 
+__armv7_mmu_cache_off:
+               mrc     p15, 0, r0, c1, c0
+               bic     r0, r0, #0x000d
+               mcr     p15, 0, r0, c1, c0      @ turn MMU and cache off
+               mov     r12, lr
+               bl      __armv7_mmu_cache_flush
+               mov     r0, #0
+               mcr     p15, 0, r0, c8, c7, 0   @ invalidate whole TLB
+               mov     pc, r12
+
 __arm6_mmu_cache_off:
                mov     r0, #0x00000030         @ ARM6 control reg.
                b       __armv3_mmu_cache_off
@@ -730,6 +768,59 @@ __armv6_mmu_cache_flush:
                mcr     p15, 0, r1, c7, c10, 4  @ drain WB
                mov     pc, lr
 
+__armv7_mmu_cache_flush:
+               mrc     p15, 0, r10, c0, c1, 5  @ read ID_MMFR1
+               tst     r10, #0xf << 16         @ hierarchical cache (ARMv7)
+               beq     hierarchical
+               mov     r10, #0
+               mcr     p15, 0, r10, c7, c14, 0 @ clean+invalidate D
+               b       iflush
+hierarchical:
+               stmfd   sp!, {r0-r5, r7, r9-r11}
+               mrc     p15, 1, r0, c0, c0, 1   @ read clidr
+               ands    r3, r0, #0x7000000      @ extract loc from clidr
+               mov     r3, r3, lsr #23         @ left align loc bit field
+               beq     finished                @ if loc is 0, then no need to clean
+               mov     r10, #0                 @ start clean at cache level 0
+loop1:
+               add     r2, r10, r10, lsr #1    @ work out 3x current cache level
+               mov     r1, r0, lsr r2          @ extract cache type bits from clidr
+               and     r1, r1, #7              @ mask of the bits for current cache only
+               cmp     r1, #2                  @ see what cache we have at this level
+               blt     skip                    @ skip if no cache, or just i-cache
+               mcr     p15, 2, r10, c0, c0, 0  @ select current cache level in cssr
+               mcr     p15, 0, r10, c7, c5, 4  @ isb to sych the new cssr&csidr
+               mrc     p15, 1, r1, c0, c0, 0   @ read the new csidr
+               and     r2, r1, #7              @ extract the length of the cache lines
+               add     r2, r2, #4              @ add 4 (line length offset)
+               ldr     r4, =0x3ff
+               ands    r4, r4, r1, lsr #3      @ find maximum number on the way size
+               .word   0xe16f5f14              @ clz r5, r4 - find bit position of way size increment
+               ldr     r7, =0x7fff
+               ands    r7, r7, r1, lsr #13     @ extract max number of the index size
+loop2:
+               mov     r9, r4                  @ create working copy of max way size
+loop3:
+               orr     r11, r10, r9, lsl r5    @ factor way and cache number into r11
+               orr     r11, r11, r7, lsl r2    @ factor index number into r11
+               mcr     p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
+               subs    r9, r9, #1              @ decrement the way
+               bge     loop3
+               subs    r7, r7, #1              @ decrement the index
+               bge     loop2
+skip:
+               add     r10, r10, #2            @ increment cache number
+               cmp     r3, r10
+               bgt     loop1
+finished:
+               mov     r10, #0                 @ swith back to cache level 0
+               mcr     p15, 2, r10, c0, c0, 0  @ select current cache level in cssr
+               ldmfd   sp!, {r0-r5, r7, r9-r11}
+iflush:
+               mcr     p15, 0, r10, c7, c5, 0  @ invalidate I+BTB
+               mcr     p15, 0, r10, c7, c10, 4 @ drain WB
+               mov     pc, lr
+
 __armv4_mmu_cache_flush:
                mov     r2, #64*1024            @ default: 32K dcache size (*2)
                mov     r11, #32                @ default: 32 byte line size
index cfe6f4650bc9fffc836136ecc9ee61d7b5ca0a9c..ae21755872ed2c8e8d6ad4bdaef3207d1fcb09f9 100644 (file)
@@ -60,6 +60,9 @@ struct locomo {
        unsigned int irq;
        spinlock_t lock;
        void __iomem *base;
+#ifdef CONFIG_PM
+       void *saved_state;
+#endif
 };
 
 struct locomo_dev_info {
@@ -565,7 +568,7 @@ static int locomo_suspend(struct platform_device *dev, pm_message_t state)
        if (!save)
                return -ENOMEM;
 
-       dev->dev.power.saved_state = (void *) save;
+       lchip->saved_state = save;
 
        spin_lock_irqsave(&lchip->lock, flags);
 
@@ -605,8 +608,8 @@ static int locomo_resume(struct platform_device *dev)
        struct locomo_save_data *save;
        unsigned long r;
        unsigned long flags;
-       
-       save = (struct locomo_save_data *) dev->dev.power.saved_state;
+
+       save = lchip->saved_state;
        if (!save)
                return 0;
 
@@ -628,6 +631,8 @@ static int locomo_resume(struct platform_device *dev)
        locomo_writel(0x1, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KCMD);
 
        spin_unlock_irqrestore(&lchip->lock, flags);
+
+       lchip->saved_state = NULL;
        kfree(save);
 
        return 0;
index 798bbfccafb74d8d0a6be4b8b5c453add992c7ce..eb06d0b2cb747344c47fb1395d6f2b6fecf080d9 100644 (file)
@@ -51,6 +51,9 @@ struct sa1111 {
        int             irq;
        spinlock_t      lock;
        void __iomem    *base;
+#ifdef CONFIG_PM
+       void            *saved_state;
+#endif
 };
 
 /*
@@ -822,7 +825,7 @@ static int sa1111_suspend(struct platform_device *dev, pm_message_t state)
        save = kmalloc(sizeof(struct sa1111_save_data), GFP_KERNEL);
        if (!save)
                return -ENOMEM;
-       dev->dev.power.saved_state = save;
+       sachip->saved_state = save;
 
        spin_lock_irqsave(&sachip->lock, flags);
 
@@ -878,7 +881,7 @@ static int sa1111_resume(struct platform_device *dev)
        unsigned long flags, id;
        void __iomem *base;
 
-       save = (struct sa1111_save_data *)dev->dev.power.saved_state;
+       save = sachip->saved_state;
        if (!save)
                return 0;
 
@@ -923,7 +926,7 @@ static int sa1111_resume(struct platform_device *dev)
 
        spin_unlock_irqrestore(&sachip->lock, flags);
 
-       dev->dev.power.saved_state = NULL;
+       sachip->saved_state = NULL;
        kfree(save);
 
        return 0;
@@ -958,8 +961,8 @@ static int sa1111_remove(struct platform_device *pdev)
                platform_set_drvdata(pdev, NULL);
 
 #ifdef CONFIG_PM
-               kfree(pdev->dev.power.saved_state);
-               pdev->dev.power.saved_state = NULL;
+               kfree(sachip->saved_state);
+               sachip->saved_state = NULL;
 #endif
        }
 
index 3bf3a927ae22fbb4d09586ce0d55f88bb5f5dcd9..111a7fa5debee4ace5a39f1aa5c50b2ab3927683 100644 (file)
@@ -766,9 +766,7 @@ static void sharpsl_apm_get_power_status(struct apm_power_info *info)
 }
 
 static struct pm_ops sharpsl_pm_ops = {
-       .prepare        = pxa_pm_prepare,
        .enter          = corgi_pxa_pm_enter,
-       .finish         = pxa_pm_finish,
        .valid          = pm_valid_only_mem,
 };
 
index a52da0ddb43d01b26821c4e6c98f59bbe92d4f84..024a9cf469b47d6e841da0147e3c02355268ca81 100644 (file)
@@ -20,7 +20,8 @@ __switch_data:
        .long   _end                            @ r7
        .long   processor_id                    @ r4
        .long   __machine_arch_type             @ r5
-       .long   cr_alignment                    @ r6
+       .long   __atags_pointer                 @ r6
+       .long   cr_alignment                    @ r7
        .long   init_thread_union + THREAD_START_SP @ sp
 
 /*
@@ -29,6 +30,7 @@ __switch_data:
  *
  *  r0  = cp#15 control register
  *  r1  = machine ID
+ *  r2  = atags pointer
  *  r9  = processor ID
  */
        .type   __mmap_switched, %function
@@ -47,11 +49,12 @@ __mmap_switched:
        strcc   fp, [r6],#4
        bcc     1b
 
-       ldmia   r3, {r4, r5, r6, sp}
+       ldmia   r3, {r4, r5, r6, r7, sp}
        str     r9, [r4]                        @ Save processor ID
        str     r1, [r5]                        @ Save machine type
+       str     r2, [r6]                        @ Save atags pointer
        bic     r4, r0, #CR_A                   @ Clear 'A' bit
-       stmia   r6, {r0, r4}                    @ Save control register values
+       stmia   r7, {r0, r4}                    @ Save control register values
        b       start_kernel
 
 /*
@@ -215,3 +218,34 @@ ENTRY(lookup_machine_type)
        bl      __lookup_machine_type
        mov     r0, r5
        ldmfd   sp!, {r4 - r6, pc}
+
+/* Determine validity of the r2 atags pointer.  The heuristic requires
+ * that the pointer be aligned, in the first 16k of physical RAM and
+ * that the ATAG_CORE marker is first and present.  Future revisions
+ * of this function may be more lenient with the physical address and
+ * may also be able to move the ATAGS block if necessary.
+ *
+ * r8  = machinfo
+ *
+ * Returns:
+ *  r2 either valid atags pointer, or zero
+ *  r5, r6 corrupted
+ */
+
+       .type   __vet_atags, %function
+__vet_atags:
+       tst     r2, #0x3                        @ aligned?
+       bne     1f
+
+       ldr     r5, [r2, #0]                    @ is first tag ATAG_CORE?
+       subs    r5, r5, #ATAG_CORE_SIZE
+       bne     1f
+       ldr     r5, [r2, #4]
+       ldr     r6, =ATAG_CORE
+       cmp     r5, r6
+       bne     1f
+
+       mov     pc, lr                          @ atag pointer is ok
+
+1:     mov     r2, #0
+       mov     pc, lr
index 41f98b4ba2ee256d5998a514dd20bcf250bad577..7898cbc9861a9d484d655079c66b3f1e76dccd0b 100644 (file)
 #define KERNEL_RAM_VADDR       (PAGE_OFFSET + TEXT_OFFSET)
 #define KERNEL_RAM_PADDR       (PHYS_OFFSET + TEXT_OFFSET)
 
+#define ATAG_CORE 0x54410001
+#define ATAG_CORE_SIZE ((2*4 + 3*4) >> 2)
+
+
 /*
  * swapper_pg_dir is the virtual address of the initial page table.
  * We place the page tables 16K below KERNEL_RAM_VADDR.  Therefore, we must
@@ -61,7 +65,7 @@
  *
  * This is normally called from the decompressor code.  The requirements
  * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0,
- * r1 = machine nr.
+ * r1 = machine nr, r2 = atags pointer.
  *
  * This code is mostly position independent, so if you link the kernel at
  * 0xc0008000, you call this at __pa(0xc0008000).
@@ -85,6 +89,7 @@ ENTRY(stext)
        bl      __lookup_machine_type           @ r5=machinfo
        movs    r8, r5                          @ invalid machine (r5=0)?
        beq     __error_a                       @ yes, error 'a'
+       bl      __vet_atags
        bl      __create_page_tables
 
        /*
index 842361777d4e63782a96535c6c50cfbf3faedd19..93b7f8e22dcc1b3b69aa424c60d0a91bed19f772 100644 (file)
@@ -44,6 +44,10 @@ static const char *processor_modes[] = {
   "UK8_32" , "UK9_32" , "UK10_32", "UND_32" , "UK12_32", "UK13_32", "UK14_32", "SYS_32"
 };
 
+static const char *isa_modes[] = {
+  "ARM" , "Thumb" , "Jazelle", "ThumbEE"
+};
+
 extern void setup_mm_for_reboot(char mode);
 
 static volatile int hlt_counter;
@@ -230,11 +234,11 @@ void __show_regs(struct pt_regs *regs)
        buf[3] = flags & PSR_V_BIT ? 'V' : 'v';
        buf[4] = '\0';
 
-       printk("Flags: %s  IRQs o%s  FIQs o%s  Mode %s%s  Segment %s\n",
+       printk("Flags: %s  IRQs o%s  FIQs o%s  Mode %s  ISA %s  Segment %s\n",
                buf, interrupts_enabled(regs) ? "n" : "ff",
                fast_interrupts_enabled(regs) ? "n" : "ff",
                processor_modes[processor_mode(regs)],
-               thumb_mode(regs) ? " (T)" : "",
+               isa_modes[isa_mode(regs)],
                get_fs() == get_ds() ? "kernel" : "user");
 #ifdef CONFIG_CPU_CP15
        {
index 650eac1bc0a6f2b5d3e10d382012c8e4850f56f0..5be2e987b8435b047bf168128364e3736eda30f4 100644 (file)
@@ -63,6 +63,8 @@ unsigned int processor_id;
 unsigned int __machine_arch_type;
 EXPORT_SYMBOL(__machine_arch_type);
 
+unsigned int __atags_pointer __initdata;
+
 unsigned int system_rev;
 EXPORT_SYMBOL(system_rev);
 
@@ -780,7 +782,9 @@ void __init setup_arch(char **cmdline_p)
        if (mdesc->soft_reboot)
                reboot_setup("s");
 
-       if (mdesc->boot_params)
+       if (__atags_pointer)
+               tags = phys_to_virt(__atags_pointer);
+       else if (mdesc->boot_params)
                tags = phys_to_virt(mdesc->boot_params);
 
        /*
index 26ca8ab3f62a7dc3df8f620178cf2695614ce44e..42e172cb0f49bfe2d0e40d9382d574234f712f3e 100644 (file)
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
 #include <linux/dm9000.h>
+#include <linux/fb.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+
+#include <video/atmel_lcdc.h>
 
 #include <asm/hardware.h>
 #include <asm/setup.h>
@@ -271,6 +276,127 @@ static struct spi_board_info ek_spi_devices[] = {
 };
 
 
+/*
+ * LCD Controller
+ */
+#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
+static struct fb_videomode at91_tft_vga_modes[] = {
+       {
+               .name           = "TX09D50VM1CCA @ 60",
+               .refresh        = 60,
+               .xres           = 240,          .yres           = 320,
+               .pixclock       = KHZ2PICOS(4965),
+
+               .left_margin    = 1,            .right_margin   = 33,
+               .upper_margin   = 1,            .lower_margin   = 0,
+               .hsync_len      = 5,            .vsync_len      = 1,
+
+               .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+               .vmode          = FB_VMODE_NONINTERLACED,
+       },
+};
+
+static struct fb_monspecs at91fb_default_monspecs = {
+       .manufacturer   = "HIT",
+       .monitor        = "TX09D50VM1CCA",
+
+       .modedb         = at91_tft_vga_modes,
+       .modedb_len     = ARRAY_SIZE(at91_tft_vga_modes),
+       .hfmin          = 15000,
+       .hfmax          = 64000,
+       .vfmin          = 50,
+       .vfmax          = 150,
+};
+
+#define AT91SAM9261_DEFAULT_LCDCON2    (ATMEL_LCDC_MEMOR_LITTLE \
+                                       | ATMEL_LCDC_DISTYPE_TFT    \
+                                       | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE)
+
+static void at91_lcdc_power_control(int on)
+{
+       if (on)
+               at91_set_gpio_value(AT91_PIN_PA12, 0);  /* power up */
+       else
+               at91_set_gpio_value(AT91_PIN_PA12, 1);  /* power down */
+}
+
+/* Driver datas */
+static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
+       .default_bpp                    = 16,
+       .default_dmacon                 = ATMEL_LCDC_DMAEN,
+       .default_lcdcon2                = AT91SAM9261_DEFAULT_LCDCON2,
+       .default_monspecs               = &at91fb_default_monspecs,
+       .atmel_lcdfb_power_control      = at91_lcdc_power_control,
+       .guard_time                     = 1,
+};
+
+#else
+static struct atmel_lcdfb_info __initdata ek_lcdc_data;
+#endif
+
+
+/*
+ * GPIO Buttons
+ */
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button ek_buttons[] = {
+       {
+               .gpio           = AT91_PIN_PA27,
+               .keycode        = BTN_0,
+               .desc           = "Button 0",
+               .active_low     = 1,
+       },
+       {
+               .gpio           = AT91_PIN_PA26,
+               .keycode        = BTN_1,
+               .desc           = "Button 1",
+               .active_low     = 1,
+       },
+       {
+               .gpio           = AT91_PIN_PA25,
+               .keycode        = BTN_2,
+               .desc           = "Button 2",
+               .active_low     = 1,
+       },
+       {
+               .gpio           = AT91_PIN_PA24,
+               .keycode        = BTN_3,
+               .desc           = "Button 3",
+               .active_low     = 1,
+       }
+};
+
+static struct gpio_keys_platform_data ek_button_data = {
+       .buttons        = ek_buttons,
+       .nbuttons       = ARRAY_SIZE(ek_buttons),
+};
+
+static struct platform_device ek_button_device = {
+       .name           = "gpio-keys",
+       .id             = -1,
+       .num_resources  = 0,
+       .dev            = {
+               .platform_data  = &ek_button_data,
+       }
+};
+
+static void __init ek_add_device_buttons(void)
+{
+       at91_set_gpio_input(AT91_PIN_PB27, 0);  /* btn0 */
+       at91_set_deglitch(AT91_PIN_PB27, 1);
+       at91_set_gpio_input(AT91_PIN_PB26, 0);  /* btn1 */
+       at91_set_deglitch(AT91_PIN_PB26, 1);
+       at91_set_gpio_input(AT91_PIN_PB25, 0);  /* btn2 */
+       at91_set_deglitch(AT91_PIN_PB25, 1);
+       at91_set_gpio_input(AT91_PIN_PB24, 0);  /* btn3 */
+       at91_set_deglitch(AT91_PIN_PB24, 1);
+
+       platform_device_register(&ek_button_device);
+}
+#else
+static void __init ek_add_device_buttons(void) {}
+#endif
+
 static void __init ek_board_init(void)
 {
        /* Serial */
@@ -296,6 +422,10 @@ static void __init ek_board_init(void)
        /* MMC */
        at91_add_device_mmc(0, &ek_mmc_data);
 #endif
+       /* LCD Controller */
+       at91_add_device_lcdc(&ek_lcdc_data);
+       /* Push Buttons */
+       ek_add_device_buttons();
 }
 
 MACHINE_START(AT91SAM9261EK, "Atmel AT91SAM9261-EK")
index c164c8e58ae6a037cdfbbf4b9b5a9842b9b094e2..2a1cc73390b79cd88943d7718c3fd3454d3c65fa 100644 (file)
@@ -26,6 +26,9 @@
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
+#include <linux/fb.h>
+
+#include <video/atmel_lcdc.h>
 
 #include <asm/hardware.h>
 #include <asm/setup.h>
@@ -201,6 +204,65 @@ static struct at91_nand_data __initdata ek_nand_data = {
 };
 
 
+/*
+ * LCD Controller
+ */
+#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
+static struct fb_videomode at91_tft_vga_modes[] = {
+       {
+               .name           = "TX09D50VM1CCA @ 60",
+               .refresh        = 60,
+               .xres           = 240,          .yres           = 320,
+               .pixclock       = KHZ2PICOS(4965),
+
+               .left_margin    = 1,            .right_margin   = 33,
+               .upper_margin   = 1,            .lower_margin   = 0,
+               .hsync_len      = 5,            .vsync_len      = 1,
+
+               .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+               .vmode          = FB_VMODE_NONINTERLACED,
+       },
+};
+
+static struct fb_monspecs at91fb_default_monspecs = {
+       .manufacturer   = "HIT",
+       .monitor        = "TX09D70VM1CCA",
+
+       .modedb         = at91_tft_vga_modes,
+       .modedb_len     = ARRAY_SIZE(at91_tft_vga_modes),
+       .hfmin          = 15000,
+       .hfmax          = 64000,
+       .vfmin          = 50,
+       .vfmax          = 150,
+};
+
+#define AT91SAM9263_DEFAULT_LCDCON2    (ATMEL_LCDC_MEMOR_LITTLE \
+                                       | ATMEL_LCDC_DISTYPE_TFT    \
+                                       | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE)
+
+static void at91_lcdc_power_control(int on)
+{
+       if (on)
+               at91_set_gpio_value(AT91_PIN_PD12, 0);  /* power up */
+       else
+               at91_set_gpio_value(AT91_PIN_PD12, 1);  /* power down */
+}
+
+/* Driver datas */
+static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
+       .default_bpp                    = 16,
+       .default_dmacon                 = ATMEL_LCDC_DMAEN,
+       .default_lcdcon2                = AT91SAM9263_DEFAULT_LCDCON2,
+       .default_monspecs               = &at91fb_default_monspecs,
+       .atmel_lcdfb_power_control      = at91_lcdc_power_control,
+       .guard_time                     = 1,
+};
+
+#else
+static struct atmel_lcdfb_info __initdata ek_lcdc_data;
+#endif
+
+
 /*
  * AC97
  */
@@ -230,6 +292,8 @@ static void __init ek_board_init(void)
        at91_add_device_nand(&ek_nand_data);
        /* I2C */
        at91_add_device_i2c();
+       /* LCD Controller */
+       at91_add_device_lcdc(&ek_lcdc_data);
        /* AC97 */
        at91_add_device_ac97(&ek_ac97_data);
 }
index a8f88cd299056ae1b52a673b2dd1b69b11de5ca0..99ac2e55774dcdf1c9b316ec9972a5d267765f89 100644 (file)
@@ -4,7 +4,8 @@
 #
 
 # Common objects
-obj-y                  := time.o irq.o serial.o io.o id.o psc.o
+obj-y                  := time.o irq.o clock.o serial.o io.o id.o psc.o \
+                          gpio.o mux.o
 
 # Board specific
 obj-$(CONFIG_MACH_DAVINCI_EVM)  += board-evm.o
index 633c12e43044528084b2275daf69143a1a0967b5..9e4024c4965f09a0ff24f71dc81df925bb93ed37 100644 (file)
@@ -32,6 +32,7 @@
 void __init davinci_psc_init(void);
 void __init davinci_irq_init(void);
 void __init davinci_map_common_io(void);
+void __init davinci_init_common_hw(void);
 
 /* NOR Flash base address set to CS0 by default */
 #define NOR_FLASH_PHYS 0x02000000
@@ -116,6 +117,7 @@ static __init void davinci_evm_init(void)
 
 static __init void davinci_evm_irq_init(void)
 {
+       davinci_init_common_hw();
        davinci_irq_init();
 }
 
diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c
new file mode 100644 (file)
index 0000000..139ceaa
--- /dev/null
@@ -0,0 +1,323 @@
+/*
+ * TI DaVinci clock config file
+ *
+ * Copyright (C) 2006 Texas Instruments.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+#include <asm/arch/psc.h>
+#include "clock.h"
+
+/* PLL/Reset register offsets */
+#define PLLM           0x110
+
+static LIST_HEAD(clocks);
+static DEFINE_MUTEX(clocks_mutex);
+static DEFINE_SPINLOCK(clockfw_lock);
+
+static unsigned int commonrate;
+static unsigned int armrate;
+static unsigned int fixedrate = 27000000;      /* 27 MHZ */
+
+extern void davinci_psc_config(unsigned int domain, unsigned int id, char enable);
+
+/*
+ * Returns a clock. Note that we first try to use device id on the bus
+ * and clock name. If this fails, we try to use clock name only.
+ */
+struct clk *clk_get(struct device *dev, const char *id)
+{
+       struct clk *p, *clk = ERR_PTR(-ENOENT);
+       int idno;
+
+       if (dev == NULL || dev->bus != &platform_bus_type)
+               idno = -1;
+       else
+               idno = to_platform_device(dev)->id;
+
+       mutex_lock(&clocks_mutex);
+
+       list_for_each_entry(p, &clocks, node) {
+               if (p->id == idno &&
+                   strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
+                       clk = p;
+                       goto found;
+               }
+       }
+
+       list_for_each_entry(p, &clocks, node) {
+               if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
+                       clk = p;
+                       break;
+               }
+       }
+
+found:
+       mutex_unlock(&clocks_mutex);
+
+       return clk;
+}
+EXPORT_SYMBOL(clk_get);
+
+void clk_put(struct clk *clk)
+{
+       if (clk && !IS_ERR(clk))
+               module_put(clk->owner);
+}
+EXPORT_SYMBOL(clk_put);
+
+static int __clk_enable(struct clk *clk)
+{
+       if (clk->flags & ALWAYS_ENABLED)
+               return 0;
+
+       davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, clk->lpsc, 1);
+       return 0;
+}
+
+static void __clk_disable(struct clk *clk)
+{
+       if (clk->usecount)
+               return;
+
+       davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, clk->lpsc, 0);
+}
+
+int clk_enable(struct clk *clk)
+{
+       unsigned long flags;
+       int ret = 0;
+
+       if (clk == NULL || IS_ERR(clk))
+               return -EINVAL;
+
+       if (clk->usecount++ == 0) {
+               spin_lock_irqsave(&clockfw_lock, flags);
+               ret = __clk_enable(clk);
+               spin_unlock_irqrestore(&clockfw_lock, flags);
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+       unsigned long flags;
+
+       if (clk == NULL || IS_ERR(clk))
+               return;
+
+       if (clk->usecount > 0 && !(--clk->usecount)) {
+               spin_lock_irqsave(&clockfw_lock, flags);
+               __clk_disable(clk);
+               spin_unlock_irqrestore(&clockfw_lock, flags);
+       }
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+       if (clk == NULL || IS_ERR(clk))
+               return -EINVAL;
+
+       return *(clk->rate);
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+       if (clk == NULL || IS_ERR(clk))
+               return -EINVAL;
+
+       return *(clk->rate);
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+       if (clk == NULL || IS_ERR(clk))
+               return -EINVAL;
+
+       /* changing the clk rate is not supported */
+       return -EINVAL;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+int clk_register(struct clk *clk)
+{
+       if (clk == NULL || IS_ERR(clk))
+               return -EINVAL;
+
+       mutex_lock(&clocks_mutex);
+       list_add(&clk->node, &clocks);
+       mutex_unlock(&clocks_mutex);
+
+       return 0;
+}
+EXPORT_SYMBOL(clk_register);
+
+void clk_unregister(struct clk *clk)
+{
+       if (clk == NULL || IS_ERR(clk))
+               return;
+
+       mutex_lock(&clocks_mutex);
+       list_del(&clk->node);
+       mutex_unlock(&clocks_mutex);
+}
+EXPORT_SYMBOL(clk_unregister);
+
+static struct clk davinci_clks[] = {
+       {
+               .name = "ARMCLK",
+               .rate = &armrate,
+               .lpsc = -1,
+               .flags = ALWAYS_ENABLED,
+       },
+       {
+               .name = "UART",
+               .rate = &fixedrate,
+               .lpsc = DAVINCI_LPSC_UART0,
+       },
+       {
+               .name = "EMACCLK",
+               .rate = &commonrate,
+               .lpsc = DAVINCI_LPSC_EMAC_WRAPPER,
+       },
+       {
+               .name = "I2CCLK",
+               .rate = &fixedrate,
+               .lpsc = DAVINCI_LPSC_I2C,
+       },
+       {
+               .name = "IDECLK",
+               .rate = &commonrate,
+               .lpsc = DAVINCI_LPSC_ATA,
+       },
+       {
+               .name = "McBSPCLK",
+               .rate = &commonrate,
+               .lpsc = DAVINCI_LPSC_McBSP,
+       },
+       {
+               .name = "MMCSDCLK",
+               .rate = &commonrate,
+               .lpsc = DAVINCI_LPSC_MMC_SD,
+       },
+       {
+               .name = "SPICLK",
+               .rate = &commonrate,
+               .lpsc = DAVINCI_LPSC_SPI,
+       },
+       {
+               .name = "gpio",
+               .rate = &commonrate,
+               .lpsc = DAVINCI_LPSC_GPIO,
+       },
+       {
+               .name = "AEMIFCLK",
+               .rate = &commonrate,
+               .lpsc = DAVINCI_LPSC_AEMIF,
+               .usecount = 1,
+       }
+};
+
+int __init davinci_clk_init(void)
+{
+       struct clk *clkp;
+       int count = 0;
+       u32 pll_mult;
+
+       pll_mult = davinci_readl(DAVINCI_PLL_CNTRL0_BASE + PLLM);
+       commonrate = ((pll_mult + 1) * 27000000) / 6;
+       armrate = ((pll_mult + 1) * 27000000) / 2;
+
+       for (clkp = davinci_clks; count < ARRAY_SIZE(davinci_clks);
+            count++, clkp++) {
+               clk_register(clkp);
+
+               /* Turn on clocks that have been enabled in the
+                * table above */
+               if (clkp->usecount)
+                       clk_enable(clkp);
+       }
+
+       return 0;
+}
+
+#ifdef CONFIG_PROC_FS
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+
+static void *davinci_ck_start(struct seq_file *m, loff_t *pos)
+{
+       return *pos < 1 ? (void *)1 : NULL;
+}
+
+static void *davinci_ck_next(struct seq_file *m, void *v, loff_t *pos)
+{
+       ++*pos;
+       return NULL;
+}
+
+static void davinci_ck_stop(struct seq_file *m, void *v)
+{
+}
+
+static int davinci_ck_show(struct seq_file *m, void *v)
+{
+       struct clk *cp;
+
+       list_for_each_entry(cp, &clocks, node)
+               seq_printf(m,"%s %d %d\n", cp->name, *(cp->rate), cp->usecount);
+
+       return 0;
+}
+
+static struct seq_operations davinci_ck_op = {
+       .start  = davinci_ck_start,
+       .next   = davinci_ck_next,
+       .stop   = davinci_ck_stop,
+       .show   = davinci_ck_show
+};
+
+static int davinci_ck_open(struct inode *inode, struct file *file)
+{
+       return seq_open(file, &davinci_ck_op);
+}
+
+static struct file_operations proc_davinci_ck_operations = {
+       .open           = davinci_ck_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
+static int __init davinci_ck_proc_init(void)
+{
+       struct proc_dir_entry *entry;
+
+       entry = create_proc_entry("davinci_clocks", 0, NULL);
+       if (entry)
+               entry->proc_fops = &proc_davinci_ck_operations;
+       return 0;
+
+}
+__initcall(davinci_ck_proc_init);
+#endif /* CONFIG_DEBUG_PROC_FS */
diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h
new file mode 100644 (file)
index 0000000..ed47079
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * TI DaVinci clock definitions
+ *
+ * Copyright (C) 2006 Texas Instruments.
+ *
+ * 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 __ARCH_ARM_DAVINCI_CLOCK_H
+#define __ARCH_ARM_DAVINCI_CLOCK_H
+
+struct clk {
+       struct list_head        node;
+       struct module           *owner;
+       const char              *name;
+       unsigned int            *rate;
+       int                     id;
+       __s8                    usecount;
+       __u8                    flags;
+       __u8                    lpsc;
+};
+
+/* Clock flags */
+#define RATE_CKCTL             1
+#define RATE_FIXED             2
+#define RATE_PROPAGATES                4
+#define VIRTUAL_CLOCK          8
+#define ALWAYS_ENABLED         16
+#define ENABLE_REG_32BIT       32
+
+#endif
diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c
new file mode 100644 (file)
index 0000000..9c67886
--- /dev/null
@@ -0,0 +1,286 @@
+/*
+ * TI DaVinci GPIO Support
+ *
+ * Copyright (c) 2006 David Brownell
+ * Copyright (c) 2007, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/bitops.h>
+
+#include <asm/arch/irqs.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/gpio.h>
+
+#include <asm/mach/irq.h>
+
+static DEFINE_SPINLOCK(gpio_lock);
+static DECLARE_BITMAP(gpio_in_use, DAVINCI_N_GPIO);
+
+int gpio_request(unsigned gpio, const char *tag)
+{
+       if (gpio >= DAVINCI_N_GPIO)
+               return -EINVAL;
+
+       if (test_and_set_bit(gpio, gpio_in_use))
+               return -EBUSY;
+
+       return 0;
+}
+EXPORT_SYMBOL(gpio_request);
+
+void gpio_free(unsigned gpio)
+{
+       if (gpio >= DAVINCI_N_GPIO)
+               return;
+
+       clear_bit(gpio, gpio_in_use);
+}
+EXPORT_SYMBOL(gpio_free);
+
+/* create a non-inlined version */
+static struct gpio_controller *__iomem gpio2controller(unsigned gpio)
+{
+       return __gpio_to_controller(gpio);
+}
+
+/*
+ * Assuming the pin is muxed as a gpio output, set its output value.
+ */
+void __gpio_set(unsigned gpio, int value)
+{
+       struct gpio_controller *__iomem g = gpio2controller(gpio);
+
+       __raw_writel(__gpio_mask(gpio), value ? &g->set_data : &g->clr_data);
+}
+EXPORT_SYMBOL(__gpio_set);
+
+
+/*
+ * Read the pin's value (works even if it's set up as output);
+ * returns zero/nonzero.
+ *
+ * Note that changes are synched to the GPIO clock, so reading values back
+ * right after you've set them may give old values.
+ */
+int __gpio_get(unsigned gpio)
+{
+       struct gpio_controller *__iomem g = gpio2controller(gpio);
+
+       return !!(__gpio_mask(gpio) & __raw_readl(&g->in_data));
+}
+EXPORT_SYMBOL(__gpio_get);
+
+
+/*--------------------------------------------------------------------------*/
+
+/*
+ * board setup code *MUST* set PINMUX0 and PINMUX1 as
+ * needed, and enable the GPIO clock.
+ */
+
+int gpio_direction_input(unsigned gpio)
+{
+       struct gpio_controller *__iomem g = gpio2controller(gpio);
+       u32 temp;
+       u32 mask;
+
+       if (!g)
+               return -EINVAL;
+
+       spin_lock(&gpio_lock);
+       mask = __gpio_mask(gpio);
+       temp = __raw_readl(&g->dir);
+       temp |= mask;
+       __raw_writel(temp, &g->dir);
+       spin_unlock(&gpio_lock);
+       return 0;
+}
+EXPORT_SYMBOL(gpio_direction_input);
+
+int gpio_direction_output(unsigned gpio, int value)
+{
+       struct gpio_controller *__iomem g = gpio2controller(gpio);
+       u32 temp;
+       u32 mask;
+
+       if (!g)
+               return -EINVAL;
+
+       spin_lock(&gpio_lock);
+       mask = __gpio_mask(gpio);
+       temp = __raw_readl(&g->dir);
+       temp &= ~mask;
+       __raw_writel(mask, value ? &g->set_data : &g->clr_data);
+       __raw_writel(temp, &g->dir);
+       spin_unlock(&gpio_lock);
+       return 0;
+}
+EXPORT_SYMBOL(gpio_direction_output);
+
+/*
+ * We expect irqs will normally be set up as input pins, but they can also be
+ * used as output pins ... which is convenient for testing.
+ *
+ * NOTE:  GPIO0..GPIO7 also have direct INTC hookups, which work in addition
+ * to their GPIOBNK0 irq (but with a bit less overhead).  But we don't have
+ * a good way to hook those up ...
+ *
+ * All those INTC hookups (GPIO0..GPIO7 plus five IRQ banks) can also
+ * serve as EDMA event triggers.
+ */
+
+static void gpio_irq_disable(unsigned irq)
+{
+       struct gpio_controller *__iomem g = get_irq_chip_data(irq);
+       u32 mask = __gpio_mask(irq_to_gpio(irq));
+
+       __raw_writel(mask, &g->clr_falling);
+       __raw_writel(mask, &g->clr_rising);
+}
+
+static void gpio_irq_enable(unsigned irq)
+{
+       struct gpio_controller *__iomem g = get_irq_chip_data(irq);
+       u32 mask = __gpio_mask(irq_to_gpio(irq));
+
+       if (irq_desc[irq].status & IRQ_TYPE_EDGE_FALLING)
+               __raw_writel(mask, &g->set_falling);
+       if (irq_desc[irq].status & IRQ_TYPE_EDGE_RISING)
+               __raw_writel(mask, &g->set_rising);
+}
+
+static int gpio_irq_type(unsigned irq, unsigned trigger)
+{
+       struct gpio_controller *__iomem g = get_irq_chip_data(irq);
+       u32 mask = __gpio_mask(irq_to_gpio(irq));
+
+       if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
+               return -EINVAL;
+
+       irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK;
+       irq_desc[irq].status |= trigger;
+
+       __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_FALLING)
+                    ? &g->set_falling : &g->clr_falling);
+       __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_RISING)
+                    ? &g->set_rising : &g->clr_rising);
+       return 0;
+}
+
+static struct irq_chip gpio_irqchip = {
+       .name           = "GPIO",
+       .enable         = gpio_irq_enable,
+       .disable        = gpio_irq_disable,
+       .set_type       = gpio_irq_type,
+};
+
+static void
+gpio_irq_handler(unsigned irq, struct irq_desc *desc)
+{
+       struct gpio_controller *__iomem g = get_irq_chip_data(irq);
+       u32 mask = 0xffff;
+
+       /* we only care about one bank */
+       if (irq & 1)
+               mask <<= 16;
+
+       /* temporarily mask (level sensitive) parent IRQ */
+       desc->chip->ack(irq);
+       while (1) {
+               u32             status;
+               struct irq_desc *gpio;
+               int             n;
+               int             res;
+
+               /* ack any irqs */
+               status = __raw_readl(&g->intstat) & mask;
+               if (!status)
+                       break;
+               __raw_writel(status, &g->intstat);
+               if (irq & 1)
+                       status >>= 16;
+
+               /* now demux them to the right lowlevel handler */
+               n = (int)get_irq_data(irq);
+               gpio = &irq_desc[n];
+               while (status) {
+                       res = ffs(status);
+                       n += res;
+                       gpio += res;
+                       desc_handle_irq(n - 1, gpio - 1);
+                       status >>= res;
+               }
+       }
+       desc->chip->unmask(irq);
+       /* now it may re-trigger */
+}
+
+/*
+ * NOTE:  for suspend/resume, probably best to make a sysdev (and class)
+ * with its suspend/resume calls hooking into the results of the set_wake()
+ * calls ... so if no gpios are wakeup events the clock can be disabled,
+ * with outputs left at previously set levels, and so that VDD3P3V.IOPWDN0
+ * can be set appropriately for GPIOV33 pins.
+ */
+
+static int __init davinci_gpio_irq_setup(void)
+{
+       unsigned        gpio, irq, bank;
+       struct clk      *clk;
+
+       clk = clk_get(NULL, "gpio");
+       if (IS_ERR(clk)) {
+               printk(KERN_ERR "Error %ld getting gpio clock?\n",
+                      PTR_ERR(clk));
+               return 0;
+       }
+
+       clk_enable(clk);
+
+       for (gpio = 0, irq = gpio_to_irq(0), bank = IRQ_GPIOBNK0;
+            gpio < DAVINCI_N_GPIO; bank++) {
+               struct gpio_controller  *__iomem g = gpio2controller(gpio);
+               unsigned                i;
+
+               __raw_writel(~0, &g->clr_falling);
+               __raw_writel(~0, &g->clr_rising);
+
+               /* set up all irqs in this bank */
+               set_irq_chained_handler(bank, gpio_irq_handler);
+               set_irq_chip_data(bank, g);
+               set_irq_data(bank, (void *)irq);
+
+               for (i = 0; i < 16 && gpio < DAVINCI_N_GPIO;
+                    i++, irq++, gpio++) {
+                       set_irq_chip(irq, &gpio_irqchip);
+                       set_irq_chip_data(irq, g);
+                       set_irq_handler(irq, handle_simple_irq);
+                       set_irq_flags(irq, IRQF_VALID);
+               }
+       }
+
+       /* BINTEN -- per-bank interrupt enable. genirq would also let these
+        * bits be set/cleared dynamically.
+        */
+       __raw_writel(0x1f, (void *__iomem)
+                    IO_ADDRESS(DAVINCI_GPIO_BASE + 0x08));
+
+       printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0));
+
+       return 0;
+}
+
+arch_initcall(davinci_gpio_irq_setup);
index 87fae6fb6ecf9b5d5447dce953a99aa42ab7c9d8..47787ff84a6ad19f9fd9ab455e9cc4d1762bdbfd 100644 (file)
@@ -17,6 +17,7 @@
 #include <asm/memory.h>
 
 #include <asm/mach/map.h>
+#include <asm/arch/clock.h>
 
 extern void davinci_check_revision(void);
 
@@ -49,3 +50,8 @@ void __init davinci_map_common_io(void)
         */
        davinci_check_revision();
 }
+
+void __init davinci_init_common_hw(void)
+{
+       davinci_clk_init();
+}
diff --git a/arch/arm/mach-davinci/mux.c b/arch/arm/mach-davinci/mux.c
new file mode 100644 (file)
index 0000000..92d26bd
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * DaVinci pin multiplexing configurations
+ *
+ * Author: Vladimir Barinov, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * 2007 (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.
+ */
+#include <linux/io.h>
+#include <linux/spinlock.h>
+
+#include <asm/hardware.h>
+
+#include <asm/arch/mux.h>
+
+/* System control register offsets */
+#define PINMUX0         0x00
+#define PINMUX1         0x04
+
+static DEFINE_SPINLOCK(mux_lock);
+
+void davinci_mux_peripheral(unsigned int mux, unsigned int enable)
+{
+       u32 pinmux, muxreg = PINMUX0;
+
+       if (mux >= DAVINCI_MUX_LEVEL2) {
+               muxreg = PINMUX1;
+               mux -= DAVINCI_MUX_LEVEL2;
+       }
+
+       spin_lock(&mux_lock);
+       pinmux = davinci_readl(DAVINCI_SYSTEM_MODULE_BASE + muxreg);
+       if (enable)
+               pinmux |= (1 << mux);
+       else
+               pinmux &= ~(1 << mux);
+       davinci_writel(pinmux, DAVINCI_SYSTEM_MODULE_BASE + muxreg);
+       spin_unlock(&mux_lock);
+}
index e1b0050283a681f78b2061d594be2a91c7be30bb..1334416559ad264cf3fd3f69ed68a8333cb56303 100644 (file)
 #include <asm/io.h>
 #include <asm/hardware.h>
 #include <asm/arch/psc.h>
+#include <asm/arch/mux.h>
 
-#define PTCMD       __REG(0x01C41120)
-#define PDSTAT      __REG(0x01C41200)
-#define PDCTL1      __REG(0x01C41304)
-#define EPCPR       __REG(0x01C41070)
-#define PTSTAT      __REG(0x01C41128)
+/* PSC register offsets */
+#define EPCPR          0x070
+#define PTCMD          0x120
+#define PTSTAT         0x128
+#define PDSTAT         0x200
+#define PDCTL1         0x304
+#define MDSTAT         0x800
+#define MDCTL          0xA00
 
-#define MDSTAT      IO_ADDRESS(0x01C41800)
-#define MDCTL       IO_ADDRESS(0x01C41A00)
-
-#define PINMUX0             __REG(0x01c40000)
-#define PINMUX1             __REG(0x01c40004)
-#define VDD3P3V_PWDN __REG(0x01C40048)
+/* System control register offsets */
+#define VDD3P3V_PWDN   0x48
 
 static void davinci_psc_mux(unsigned int id)
 {
        switch (id) {
        case DAVINCI_LPSC_ATA:
-               PINMUX0 |= (1 << 17) | (1 << 16);
+               davinci_mux_peripheral(DAVINCI_MUX_HDIREN, 1);
+               davinci_mux_peripheral(DAVINCI_MUX_ATAEN, 1);
                break;
        case DAVINCI_LPSC_MMC_SD:
                /* VDD power manupulations are done in U-Boot for CPMAC
                 * so applies to MMC as well
                 */
                /*Set up the pull regiter for MMC */
-               VDD3P3V_PWDN = 0x0;
-               PINMUX1 &= (~(1 << 9));
+               davinci_writel(0, DAVINCI_SYSTEM_MODULE_BASE + VDD3P3V_PWDN);
+               davinci_mux_peripheral(DAVINCI_MUX_MSTK, 0);
                break;
        case DAVINCI_LPSC_I2C:
-               PINMUX1 |= (1 << 7);
+               davinci_mux_peripheral(DAVINCI_MUX_I2C, 1);
                break;
        case DAVINCI_LPSC_McBSP:
-               PINMUX1 |= (1 << 10);
+               davinci_mux_peripheral(DAVINCI_MUX_ASP, 1);
                break;
        default:
                break;
@@ -67,33 +68,59 @@ static void davinci_psc_mux(unsigned int id)
 /* Enable or disable a PSC domain */
 void davinci_psc_config(unsigned int domain, unsigned int id, char enable)
 {
-       volatile unsigned int *mdstat = (unsigned int *)((int)MDSTAT + 4 * id);
-       volatile unsigned int *mdctl = (unsigned int *)((int)MDCTL + 4 * id);
+       u32 epcpr, ptcmd, ptstat, pdstat, pdctl1, mdstat, mdctl, mdstat_mask;
 
        if (id < 0)
                return;
 
+       mdctl = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + MDCTL + 4 * id);
        if (enable)
-               *mdctl |= 0x00000003;   /* Enable Module */
+               mdctl |= 0x00000003;    /* Enable Module */
        else
-               *mdctl &= 0xFFFFFFF2;   /* Disable Module */
+               mdctl &= 0xFFFFFFF2;    /* Disable Module */
+       davinci_writel(mdctl, DAVINCI_PWR_SLEEP_CNTRL_BASE + MDCTL + 4 * id);
+
+       pdstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + PDSTAT);
+       if ((pdstat & 0x00000001) == 0) {
+               pdctl1 = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1);
+               pdctl1 |= 0x1;
+               davinci_writel(pdctl1, DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1);
+
+               ptcmd = 1 << domain;
+               davinci_writel(ptcmd, DAVINCI_PWR_SLEEP_CNTRL_BASE + PTCMD);
 
-       if ((PDSTAT & 0x00000001) == 0) {
-               PDCTL1 |= 0x1;
-               PTCMD = (1 << domain);
-               while ((((EPCPR >> domain) & 1) == 0));
+               do {
+                       epcpr = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE +
+                                             EPCPR);
+               } while ((((epcpr >> domain) & 1) == 0));
 
-               PDCTL1 |= 0x100;
-               while (!(((PTSTAT >> domain) & 1) == 0));
+               pdctl1 = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1);
+               pdctl1 |= 0x100;
+               davinci_writel(pdctl1, DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1);
+
+               do {
+                       ptstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE +
+                                              PTSTAT);
+               } while (!(((ptstat >> domain) & 1) == 0));
        } else {
-               PTCMD = (1 << domain);
-               while (!(((PTSTAT >> domain) & 1) == 0));
+               ptcmd = 1 << domain;
+               davinci_writel(ptcmd, DAVINCI_PWR_SLEEP_CNTRL_BASE + PTCMD);
+
+               do {
+                       ptstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE +
+                                              PTSTAT);
+               } while (!(((ptstat >> domain) & 1) == 0));
        }
 
        if (enable)
-               while (!((*mdstat & 0x0000001F) == 0x3));
+               mdstat_mask = 0x3;
        else
-               while (!((*mdstat & 0x0000001F) == 0x2));
+               mdstat_mask = 0x2;
+
+       do {
+               mdstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE +
+                                      MDSTAT + 4 * id);
+       } while (!((mdstat & 0x0000001F) == mdstat_mask));
 
        if (enable)
                davinci_psc_mux(id);
index 1c474cf709ca9b4a4241a112fceba2c1560244ea..a58b678006dff1ce50ef7ccaa86ffc1cc0b9fe1a 100644 (file)
 #include <linux/module.h>
 #include <linux/string.h>
 
+#include <asm/errno.h>
 #include <asm/arch/imxfb.h>
 #include <asm/hardware.h>
 #include <asm/arch/imx-regs.h>
 
 #include <asm/mach/map.h>
 #include <asm/arch/mmc.h>
+#include <asm/arch/gpio.h>
+
+unsigned long imx_gpio_alloc_map[(GPIO_PORT_MAX + 1) * 32 / BITS_PER_LONG];
 
 void imx_gpio_mode(int gpio_mode)
 {
@@ -95,6 +99,120 @@ void imx_gpio_mode(int gpio_mode)
 
 EXPORT_SYMBOL(imx_gpio_mode);
 
+int imx_gpio_request(unsigned gpio, const char *label)
+{
+       if(gpio >= (GPIO_PORT_MAX + 1) * 32)
+               printk(KERN_ERR "imx_gpio: Attempt to request nonexistent GPIO %d for \"%s\"\n",
+                       gpio, label ? label : "?");
+               return -EINVAL;
+
+       if(test_and_set_bit(gpio, imx_gpio_alloc_map)) {
+               printk(KERN_ERR "imx_gpio: GPIO %d already used. Allocation for \"%s\" failed\n",
+                       gpio, label ? label : "?");
+               return -EBUSY;
+       }
+
+       return 0;
+}
+
+EXPORT_SYMBOL(imx_gpio_request);
+
+void imx_gpio_free(unsigned gpio)
+{
+       if(gpio >= (GPIO_PORT_MAX + 1) * 32)
+               return;
+
+       clear_bit(gpio, imx_gpio_alloc_map);
+}
+
+EXPORT_SYMBOL(imx_gpio_free);
+
+int imx_gpio_direction_input(unsigned gpio)
+{
+       imx_gpio_mode(gpio| GPIO_IN);
+       return 0;
+}
+
+EXPORT_SYMBOL(imx_gpio_direction_input);
+
+int imx_gpio_direction_output(unsigned gpio, int value)
+{
+       imx_gpio_set_value(gpio, value);
+       imx_gpio_mode(gpio| GPIO_OUT);
+       return 0;
+}
+
+EXPORT_SYMBOL(imx_gpio_direction_output);
+
+int imx_gpio_setup_multiple_pins(const int *pin_list, unsigned count,
+                               int alloc_mode, const char *label)
+{
+       const int *p = pin_list;
+       int i;
+       unsigned gpio;
+       unsigned mode;
+
+       for (i = 0; i < count; i++) {
+               gpio = *p & (GPIO_PIN_MASK | GPIO_PORT_MASK);
+               mode = *p & ~(GPIO_PIN_MASK | GPIO_PORT_MASK);
+
+               if (gpio >= (GPIO_PORT_MAX + 1) * 32)
+                       goto setup_error;
+
+               if (alloc_mode & IMX_GPIO_ALLOC_MODE_RELEASE)
+                       imx_gpio_free(gpio);
+               else if (!(alloc_mode & IMX_GPIO_ALLOC_MODE_NO_ALLOC))
+                       if (imx_gpio_request(gpio, label))
+                               if (!(alloc_mode & IMX_GPIO_ALLOC_MODE_TRY_ALLOC))
+                                       goto setup_error;
+
+               if (!(alloc_mode & (IMX_GPIO_ALLOC_MODE_ALLOC_ONLY |
+                                   IMX_GPIO_ALLOC_MODE_RELEASE)))
+                       imx_gpio_mode(gpio | mode);
+
+               p++;
+       }
+       return 0;
+
+setup_error:
+       if(alloc_mode & (IMX_GPIO_ALLOC_MODE_NO_ALLOC |
+                        IMX_GPIO_ALLOC_MODE_TRY_ALLOC))
+               return -EINVAL;
+
+       while (p != pin_list) {
+               p--;
+               gpio = *p & (GPIO_PIN_MASK | GPIO_PORT_MASK);
+               imx_gpio_free(gpio);
+       }
+
+       return -EINVAL;
+}
+
+EXPORT_SYMBOL(imx_gpio_setup_multiple_pins);
+
+void __imx_gpio_set_value(unsigned gpio, int value)
+{
+       imx_gpio_set_value_inline(gpio, value);
+}
+
+EXPORT_SYMBOL(__imx_gpio_set_value);
+
+int imx_gpio_to_irq(unsigned gpio)
+{
+       return IRQ_GPIOA(0) + gpio;
+}
+
+EXPORT_SYMBOL(imx_gpio_to_irq);
+
+int imx_irq_to_gpio(unsigned irq)
+{
+       if (irq < IRQ_GPIOA(0))
+               return -EINVAL;
+       return irq - IRQ_GPIOA(0);
+}
+
+EXPORT_SYMBOL(imx_irq_to_gpio);
+
 /*
  *  get the system pll clock in Hz
  *
index 6960a9d042175d824d080c38cb8e35b21148ef69..010f6fa984a65e7f05262fa5ec70edda8ee8b34b 100644 (file)
@@ -3,6 +3,7 @@
  *
  *  Copyright (C) 2000-2001 Deep Blue Solutions
  *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ *  Copyright (C) 2006-2007 Pavel Pisa (ppisa@pikron.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
@@ -15,6 +16,7 @@
 #include <linux/irq.h>
 #include <linux/time.h>
 #include <linux/clocksource.h>
+#include <linux/clockchips.h>
 
 #include <asm/hardware.h>
 #include <asm/io.h>
@@ -25,7 +27,8 @@
 /* Use timer 1 as system timer */
 #define TIMER_BASE IMX_TIM1_BASE
 
-static unsigned long evt_diff;
+static struct clock_event_device clockevent_imx;
+static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
 
 /*
  * IRQ handler for the timer
@@ -33,25 +36,20 @@ static unsigned long evt_diff;
 static irqreturn_t
 imx_timer_interrupt(int irq, void *dev_id)
 {
+       struct clock_event_device *evt = &clockevent_imx;
        uint32_t tstat;
+       irqreturn_t ret = IRQ_NONE;
 
        /* clear the interrupt */
        tstat = IMX_TSTAT(TIMER_BASE);
        IMX_TSTAT(TIMER_BASE) = 0;
 
        if (tstat & TSTAT_COMP) {
-               do {
-
-                       write_seqlock(&xtime_lock);
-                       timer_tick();
-                       write_sequnlock(&xtime_lock);
-                       IMX_TCMP(TIMER_BASE) += evt_diff;
-
-               } while (unlikely((int32_t)(IMX_TCMP(TIMER_BASE)
-                                       - IMX_TCN(TIMER_BASE)) < 0));
+               evt->event_handler(evt);
+               ret = IRQ_HANDLED;
        }
 
-       return IRQ_HANDLED;
+       return ret;
 }
 
 static struct irqaction imx_timer_irq = {
@@ -70,10 +68,8 @@ static void __init imx_timer_hardware_init(void)
         */
        IMX_TCTL(TIMER_BASE) = 0;
        IMX_TPRER(TIMER_BASE) = 0;
-       IMX_TCMP(TIMER_BASE) = LATCH - 1;
 
-       IMX_TCTL(TIMER_BASE) = TCTL_FRR | TCTL_CLK_PCLK1 | TCTL_IRQEN | TCTL_TEN;
-       evt_diff = LATCH;
+       IMX_TCTL(TIMER_BASE) = TCTL_FRR | TCTL_CLK_PCLK1 | TCTL_TEN;
 }
 
 cycle_t imx_get_cycles(void)
@@ -99,11 +95,108 @@ static int __init imx_clocksource_init(void)
        return 0;
 }
 
+static int imx_set_next_event(unsigned long evt,
+                                 struct clock_event_device *unused)
+{
+       unsigned long tcmp;
+
+       tcmp = IMX_TCN(TIMER_BASE) + evt;
+       IMX_TCMP(TIMER_BASE) = tcmp;
+
+       return (int32_t)(tcmp - IMX_TCN(TIMER_BASE)) < 0 ? -ETIME : 0;
+}
+
+#ifdef DEBUG
+static const char *clock_event_mode_label[]={
+       [CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC",
+       [CLOCK_EVT_MODE_ONESHOT]  = "CLOCK_EVT_MODE_ONESHOT",
+       [CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN",
+       [CLOCK_EVT_MODE_UNUSED]   = "CLOCK_EVT_MODE_UNUSED"
+};
+#endif /*DEBUG*/
+
+static void imx_set_mode(enum clock_event_mode mode, struct clock_event_device *evt)
+{
+       unsigned long flags;
+
+       /*
+        * The timer interrupt generation is disabled at least
+        * for enough time to call imx_set_next_event()
+        */
+       local_irq_save(flags);
+       /* Disable interrupt in GPT module */
+       IMX_TCTL(TIMER_BASE) &= ~TCTL_IRQEN;
+       if (mode != clockevent_mode) {
+               /* Set event time into far-far future */
+               IMX_TCMP(TIMER_BASE) = IMX_TCN(TIMER_BASE) - 3;
+               /* Clear pending interrupt */
+               IMX_TSTAT(TIMER_BASE) &= ~TSTAT_COMP;
+       }
+
+#ifdef DEBUG
+       printk(KERN_INFO "imx_set_mode: changing mode from %s to %s\n",
+               clock_event_mode_label[clockevent_mode], clock_event_mode_label[mode]);
+#endif /*DEBUG*/
+
+       /* Remember timer mode */
+       clockevent_mode = mode;
+       local_irq_restore(flags);
+
+       switch (mode) {
+       case CLOCK_EVT_MODE_PERIODIC:
+               printk(KERN_ERR "imx_set_mode: Periodic mode is not supported for i.MX\n");
+               break;
+       case CLOCK_EVT_MODE_ONESHOT:
+               /*
+                * Do not put overhead of interrupt enable/disable into
+                * imx_set_next_event(), the core has about 4 minutes
+                * to call imx_set_next_event() or shutdown clock after
+                * mode switching
+                */
+               local_irq_save(flags);
+               IMX_TCTL(TIMER_BASE) |= TCTL_IRQEN;
+               local_irq_restore(flags);
+               break;
+       case CLOCK_EVT_MODE_SHUTDOWN:
+       case CLOCK_EVT_MODE_UNUSED:
+               /* Left event sources disabled, no more interrupts appears */
+               break;
+       }
+}
+
+static struct clock_event_device clockevent_imx = {
+       .name           = "imx_timer1",
+       .features       = CLOCK_EVT_FEAT_ONESHOT,
+       .shift          = 32,
+       .set_mode       = imx_set_mode,
+       .set_next_event = imx_set_next_event,
+       .rating         = 200,
+};
+
+static int __init imx_clockevent_init(void)
+{
+       clockevent_imx.mult = div_sc(imx_get_perclk1(), NSEC_PER_SEC,
+                                       clockevent_imx.shift);
+       clockevent_imx.max_delta_ns =
+               clockevent_delta2ns(0xfffffffe, &clockevent_imx);
+       clockevent_imx.min_delta_ns =
+               clockevent_delta2ns(0xf, &clockevent_imx);
+
+       clockevent_imx.cpumask = cpumask_of_cpu(0);
+
+       clockevents_register_device(&clockevent_imx);
+
+       return 0;
+}
+
+
 static void __init imx_timer_init(void)
 {
        imx_timer_hardware_init();
        imx_clocksource_init();
 
+       imx_clockevent_init();
+
        /*
         * Make irqs happen for the system timer
         */
index d3dc278213da10892934032db9f75c241182a918..2476347ea62f13b5119a28e1fd6f185d76a8ad8f 100644 (file)
 #define IOP13XX_TPMI_MMR(dev)  IOP13XX_REG_ADDR32_PHYS(0x48000 + (dev << 12))
 #define IOP13XX_TPMI_MEM(dev)  IOP13XX_REG_ADDR32_PHYS(0x60000 + (dev << 13))
 #define IOP13XX_TPMI_CTRL(dev) IOP13XX_REG_ADDR32_PHYS(0x50000 + (dev << 10))
+#define IOP13XX_TPMI_IOP_CTRL(dev) (IOP13XX_TPMI_CTRL(dev) + 0x2000)
 #define IOP13XX_TPMI_MMR_SIZE      (SZ_4K - 1)
 #define IOP13XX_TPMI_MEM_SIZE      (255)
 #define IOP13XX_TPMI_MEM_CTRL      (SZ_1K - 1)
 #define IOP13XX_TPMI_RESOURCE_MMR  0
 #define IOP13XX_TPMI_RESOURCE_MEM  1
 #define IOP13XX_TPMI_RESOURCE_CTRL 2
-#define IOP13XX_TPMI_RESOURCE_IRQ  3
+#define IOP13XX_TPMI_RESOURCE_IOP_CTRL 3
+#define IOP13XX_TPMI_RESOURCE_IRQ  4
 
 static struct resource iop13xx_tpmi_0_resources[] = {
        [IOP13XX_TPMI_RESOURCE_MMR] = {
@@ -53,6 +55,11 @@ static struct resource iop13xx_tpmi_0_resources[] = {
                .end = IOP13XX_TPMI_CTRL(0) + IOP13XX_TPMI_MEM_CTRL,
                .flags = IORESOURCE_MEM,
        },
+       [IOP13XX_TPMI_RESOURCE_IOP_CTRL] = {
+               .start = IOP13XX_TPMI_IOP_CTRL(0),
+               .end = IOP13XX_TPMI_IOP_CTRL(0) + IOP13XX_TPMI_MEM_CTRL,
+               .flags = IORESOURCE_MEM,
+       },
        [IOP13XX_TPMI_RESOURCE_IRQ] = {
                .start = IRQ_IOP13XX_TPMI0_OUT,
                .end = IRQ_IOP13XX_TPMI0_OUT,
@@ -76,6 +83,11 @@ static struct resource iop13xx_tpmi_1_resources[] = {
                .end = IOP13XX_TPMI_CTRL(1) + IOP13XX_TPMI_MEM_CTRL,
                .flags = IORESOURCE_MEM,
        },
+       [IOP13XX_TPMI_RESOURCE_IOP_CTRL] = {
+               .start = IOP13XX_TPMI_IOP_CTRL(1),
+               .end = IOP13XX_TPMI_IOP_CTRL(1) + IOP13XX_TPMI_MEM_CTRL,
+               .flags = IORESOURCE_MEM,
+       },
        [IOP13XX_TPMI_RESOURCE_IRQ] = {
                .start = IRQ_IOP13XX_TPMI1_OUT,
                .end = IRQ_IOP13XX_TPMI1_OUT,
@@ -99,6 +111,11 @@ static struct resource iop13xx_tpmi_2_resources[] = {
                .end = IOP13XX_TPMI_CTRL(2) + IOP13XX_TPMI_MEM_CTRL,
                .flags = IORESOURCE_MEM,
        },
+       [IOP13XX_TPMI_RESOURCE_IOP_CTRL] = {
+               .start = IOP13XX_TPMI_IOP_CTRL(2),
+               .end = IOP13XX_TPMI_IOP_CTRL(2) + IOP13XX_TPMI_MEM_CTRL,
+               .flags = IORESOURCE_MEM,
+       },
        [IOP13XX_TPMI_RESOURCE_IRQ] = {
                .start = IRQ_IOP13XX_TPMI2_OUT,
                .end = IRQ_IOP13XX_TPMI2_OUT,
@@ -122,6 +139,11 @@ static struct resource iop13xx_tpmi_3_resources[] = {
                .end = IOP13XX_TPMI_CTRL(3) + IOP13XX_TPMI_MEM_CTRL,
                .flags = IORESOURCE_MEM,
        },
+       [IOP13XX_TPMI_RESOURCE_IOP_CTRL] = {
+               .start = IOP13XX_TPMI_IOP_CTRL(3),
+               .end = IOP13XX_TPMI_IOP_CTRL(3) + IOP13XX_TPMI_MEM_CTRL,
+               .flags = IORESOURCE_MEM,
+       },
        [IOP13XX_TPMI_RESOURCE_IRQ] = {
                .start = IRQ_IOP13XX_TPMI3_OUT,
                .end = IRQ_IOP13XX_TPMI3_OUT,
@@ -133,7 +155,7 @@ u64 iop13xx_tpmi_mask = DMA_64BIT_MASK;
 static struct platform_device iop13xx_tpmi_0_device = {
        .name = "iop-tpmi",
        .id = 0,
-       .num_resources = 4,
+       .num_resources = ARRAY_SIZE(iop13xx_tpmi_0_resources),
        .resource = iop13xx_tpmi_0_resources,
        .dev = {
                .dma_mask          = &iop13xx_tpmi_mask,
@@ -144,7 +166,7 @@ static struct platform_device iop13xx_tpmi_0_device = {
 static struct platform_device iop13xx_tpmi_1_device = {
        .name = "iop-tpmi",
        .id = 1,
-       .num_resources = 4,
+       .num_resources = ARRAY_SIZE(iop13xx_tpmi_1_resources),
        .resource = iop13xx_tpmi_1_resources,
        .dev = {
                .dma_mask          = &iop13xx_tpmi_mask,
@@ -155,7 +177,7 @@ static struct platform_device iop13xx_tpmi_1_device = {
 static struct platform_device iop13xx_tpmi_2_device = {
        .name = "iop-tpmi",
        .id = 2,
-       .num_resources = 4,
+       .num_resources = ARRAY_SIZE(iop13xx_tpmi_2_resources),
        .resource = iop13xx_tpmi_2_resources,
        .dev = {
                .dma_mask          = &iop13xx_tpmi_mask,
@@ -166,7 +188,7 @@ static struct platform_device iop13xx_tpmi_2_device = {
 static struct platform_device iop13xx_tpmi_3_device = {
        .name = "iop-tpmi",
        .id = 3,
-       .num_resources = 4,
+       .num_resources = ARRAY_SIZE(iop13xx_tpmi_3_resources),
        .resource = iop13xx_tpmi_3_resources,
        .dev = {
                .dma_mask          = &iop13xx_tpmi_mask,
index 060909870b505b582ee4a2ee684cdd9ddd311e67..61b2dfcb89d623dd401cd8226ec2d66bbf939690 100644 (file)
@@ -41,6 +41,22 @@ config ARCH_ADI_COYOTE
          Engineering Coyote Gateway Reference Platform. For more
          information on this platform, see <file:Documentation/arm/IXP4xx>.
 
+config MACH_GATEWAY7001
+       bool "Gateway 7001"
+       select PCI
+       help
+         Say 'Y' here if you want your kernel to support Gateway's
+         7001 Access Point. For more information on this platform,
+         see http://openwrt.org
+
+config MACH_WG302V2
+       bool "Netgear WG302 v2 / WAG302 v2"
+       select PCI
+       help
+         Say 'Y' here if you want your kernel to support Netgear's
+         WG302 v2 or WAG302 v2 Access Points. For more information
+         on this platform, see http://openwrt.org
+
 config ARCH_IXDP425
        bool "IXDP425"
        help
index 3b87c47e06cf893d6a74aa9fc161afdac6e426bf..77e00ade558589297aaa425558958a66a61fbffb 100644 (file)
@@ -13,6 +13,8 @@ obj-pci-$(CONFIG_MACH_GTWX5715)               += gtwx5715-pci.o
 obj-pci-$(CONFIG_MACH_NSLU2)           += nslu2-pci.o
 obj-pci-$(CONFIG_MACH_NAS100D)         += nas100d-pci.o
 obj-pci-$(CONFIG_MACH_DSMG600)         += dsmg600-pci.o
+obj-pci-$(CONFIG_MACH_GATEWAY7001)     += gateway7001-pci.o
+obj-pci-$(CONFIG_MACH_WG302V2)         += wg302v2-pci.o
 
 obj-y  += common.o
 
@@ -24,5 +26,7 @@ obj-$(CONFIG_MACH_GTWX5715)   += gtwx5715-setup.o
 obj-$(CONFIG_MACH_NSLU2)       += nslu2-setup.o nslu2-power.o
 obj-$(CONFIG_MACH_NAS100D)     += nas100d-setup.o nas100d-power.o
 obj-$(CONFIG_MACH_DSMG600)      += dsmg600-setup.o dsmg600-power.o
+obj-$(CONFIG_MACH_GATEWAY7001) += gateway7001-setup.o
+obj-$(CONFIG_MACH_WG302V2)     += wg302v2-setup.o
 
 obj-$(CONFIG_PCI)              += $(obj-pci-$(CONFIG_PCI)) common-pci.o
diff --git a/arch/arm/mach-ixp4xx/gateway7001-pci.c b/arch/arm/mach-ixp4xx/gateway7001-pci.c
new file mode 100644 (file)
index 0000000..6abf568
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * arch/arch/mach-ixp4xx/gateway7001-pci.c
+ *
+ * PCI setup routines for Gateway 7001
+ *
+ * Copyright (C) 2007 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * based on coyote-pci.c:
+ *     Copyright (C) 2002 Jungo Software Technologies.
+ *     Copyright (C) 2003 MontaVista Softwrae, Inc.
+ *
+ * Maintainer: Imre Kaloz <kaloz@openwrt.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/pci.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+
+#include <asm/mach/pci.h>
+
+void __init gateway7001_pci_preinit(void)
+{
+       set_irq_type(IRQ_IXP4XX_GPIO10, IRQT_LOW);
+       set_irq_type(IRQ_IXP4XX_GPIO11, IRQT_LOW);
+
+       ixp4xx_pci_preinit();
+}
+
+static int __init gateway7001_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+       if (slot == 1)
+               return IRQ_IXP4XX_GPIO11;
+       else if (slot == 2)
+               return IRQ_IXP4XX_GPIO10;
+       else return -1;
+}
+
+struct hw_pci gateway7001_pci __initdata = {
+       .nr_controllers = 1,
+       .preinit =        gateway7001_pci_preinit,
+       .swizzle =        pci_std_swizzle,
+       .setup =          ixp4xx_setup,
+       .scan =           ixp4xx_scan_bus,
+       .map_irq =        gateway7001_map_irq,
+};
+
+int __init gateway7001_pci_init(void)
+{
+       if (machine_is_gateway7001())
+               pci_common_init(&gateway7001_pci);
+       return 0;
+}
+
+subsys_initcall(gateway7001_pci_init);
diff --git a/arch/arm/mach-ixp4xx/gateway7001-setup.c b/arch/arm/mach-ixp4xx/gateway7001-setup.c
new file mode 100644 (file)
index 0000000..3787683
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * arch/arm/mach-ixp4xx/gateway7001-setup.c
+ *
+ * Board setup for the Gateway 7001 board
+ *
+ * Copyright (C) 2007 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * based on coyote-setup.c:
+ *      Copyright (C) 2003-2005 MontaVista Software, Inc.
+ *
+ * Author: Imre Kaloz <Kaloz@openwrt.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/serial_8250.h>
+#include <linux/slab.h>
+
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+
+static struct flash_platform_data gateway7001_flash_data = {
+       .map_name       = "cfi_probe",
+       .width          = 2,
+};
+
+static struct resource gateway7001_flash_resource = {
+       .flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device gateway7001_flash = {
+       .name           = "IXP4XX-Flash",
+       .id             = 0,
+       .dev            = {
+               .platform_data = &gateway7001_flash_data,
+       },
+       .num_resources  = 1,
+       .resource       = &gateway7001_flash_resource,
+};
+
+static struct resource gateway7001_uart_resource = {
+       .start  = IXP4XX_UART2_BASE_PHYS,
+       .end    = IXP4XX_UART2_BASE_PHYS + 0x0fff,
+       .flags  = IORESOURCE_MEM,
+};
+
+static struct plat_serial8250_port gateway7001_uart_data[] = {
+       {
+               .mapbase        = IXP4XX_UART2_BASE_PHYS,
+               .membase        = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
+               .irq            = IRQ_IXP4XX_UART2,
+               .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+               .iotype         = UPIO_MEM,
+               .regshift       = 2,
+               .uartclk        = IXP4XX_UART_XTAL,
+       },
+       { },
+};
+
+static struct platform_device gateway7001_uart = {
+       .name           = "serial8250",
+       .id             = PLAT8250_DEV_PLATFORM,
+       .dev                    = {
+               .platform_data  = gateway7001_uart_data,
+       },
+       .num_resources  = 1,
+       .resource       = &gateway7001_uart_resource,
+};
+
+static struct platform_device *gateway7001_devices[] __initdata = {
+       &gateway7001_flash,
+       &gateway7001_uart
+};
+
+static void __init gateway7001_init(void)
+{
+       ixp4xx_sys_init();
+
+       gateway7001_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
+       gateway7001_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_32M - 1;
+
+       *IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE;
+       *IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0;
+
+       platform_add_devices(gateway7001_devices, ARRAY_SIZE(gateway7001_devices));
+}
+
+#ifdef CONFIG_MACH_GATEWAY7001
+MACHINE_START(GATEWAY7001, "Gateway 7001 AP")
+       /* Maintainer: Imre Kaloz <kaloz@openwrt.org> */
+       .phys_io        = IXP4XX_PERIPHERAL_BASE_PHYS,
+       .io_pg_offst    = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
+       .map_io         = ixp4xx_map_io,
+       .init_irq       = ixp4xx_init_irq,
+       .timer          = &ixp4xx_timer,
+       .boot_params    = 0x0100,
+       .init_machine   = gateway7001_init,
+MACHINE_END
+#endif
index a66484b63d36b12b0dccd06770b3b3a9d2931a7a..0d5a42455820322c804d046233e7563826d66106 100644 (file)
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/irq.h>
+
 #include <asm/mach-types.h>
 #include <asm/hardware.h>
-#include <asm/irq.h>
 #include <asm/arch/gtwx5715.h>
 #include <asm/mach/pci.h>
 
-extern void ixp4xx_pci_preinit(void);
-extern int ixp4xx_setup(int nr, struct pci_sys_data *sys);
-extern struct pci_bus *ixp4xx_scan_bus(int nr, struct pci_sys_data *sys);
-
-
 /*
  * The exact GPIO pins and IRQs are defined in arch-ixp4xx/gtwx5715.h
  * Slot 0 isn't actually populated with a card connector but
index ec4f07950ec62745b300ae45e12c965434510048..d5008d8fc9a5af2eb24b85ff804410e4469f2ece 100644 (file)
 #include <linux/tty.h>
 #include <linux/serial_8250.h>
 #include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
 
 #include <asm/types.h>
 #include <asm/setup.h>
@@ -24,6 +28,7 @@
 #include <asm/irq.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
+#include <asm/delay.h>
 
 static struct flash_platform_data ixdp425_flash_data = {
        .map_name       = "cfi_probe",
@@ -44,6 +49,77 @@ static struct platform_device ixdp425_flash = {
        .resource       = &ixdp425_flash_resource,
 };
 
+#if defined(CONFIG_MTD_NAND_PLATFORM) || \
+    defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
+
+#ifdef CONFIG_MTD_PARTITIONS
+const char *part_probes[] = { "cmdlinepart", NULL };
+
+static struct mtd_partition ixdp425_partitions[] = {
+       {
+               .name   = "ixp400 NAND FS 0",
+               .offset = 0,
+               .size   = SZ_8M
+       }, {
+               .name   = "ixp400 NAND FS 1",
+               .offset = MTDPART_OFS_APPEND,
+               .size   = MTDPART_SIZ_FULL
+       },
+};
+#endif
+
+static void
+ixdp425_flash_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+       struct nand_chip *this = mtd->priv;
+       int offset = (int)this->priv;
+
+       if (ctrl & NAND_CTRL_CHANGE) {
+               if (ctrl & NAND_NCE) {
+                       gpio_line_set(IXDP425_NAND_NCE_PIN, IXP4XX_GPIO_LOW);
+                       udelay(5);
+               } else
+                       gpio_line_set(IXDP425_NAND_NCE_PIN, IXP4XX_GPIO_HIGH);
+
+               offset = (ctrl & NAND_CLE) ? IXDP425_NAND_CMD_BYTE : 0;
+               offset |= (ctrl & NAND_ALE) ? IXDP425_NAND_ADDR_BYTE : 0;
+               this->priv = (void *)offset;
+       }
+
+       if (cmd != NAND_CMD_NONE)
+               writeb(cmd, this->IO_ADDR_W + offset);
+}
+
+static struct platform_nand_data ixdp425_flash_nand_data = {
+       .chip = {
+               .chip_delay             = 30,
+               .options                = NAND_NO_AUTOINCR,
+#ifdef CONFIG_MTD_PARTITIONS
+               .part_probe_types       = part_probes,
+               .partitions             = ixdp425_partitions,
+               .nr_partitions          = ARRAY_SIZE(ixdp425_partitions),
+#endif
+       },
+       .ctrl = {
+               .cmd_ctrl               = ixdp425_flash_nand_cmd_ctrl
+       }
+};
+
+static struct resource ixdp425_flash_nand_resource = {
+       .flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device ixdp425_flash_nand = {
+       .name           = "gen_nand",
+       .id             = -1,
+       .dev            = {
+               .platform_data = &ixdp425_flash_nand_data,
+       },
+       .num_resources  = 1,
+       .resource       = &ixdp425_flash_nand_resource,
+};
+#endif /* CONFIG_MTD_NAND_PLATFORM */
+
 static struct ixp4xx_i2c_pins ixdp425_i2c_gpio_pins = {
        .sda_pin        = IXDP425_SDA_PIN,
        .scl_pin        = IXDP425_SCL_PIN,
@@ -104,6 +180,10 @@ static struct platform_device ixdp425_uart = {
 static struct platform_device *ixdp425_devices[] __initdata = {
        &ixdp425_i2c_controller,
        &ixdp425_flash,
+#if defined(CONFIG_MTD_NAND_PLATFORM) || \
+    defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
+       &ixdp425_flash_nand,
+#endif
        &ixdp425_uart
 };
 
@@ -115,6 +195,22 @@ static void __init ixdp425_init(void)
        ixdp425_flash_resource.end =
                IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
 
+#if defined(CONFIG_MTD_NAND_PLATFORM) || \
+    defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
+       ixdp425_flash_nand_resource.start = IXP4XX_EXP_BUS_BASE(3),
+       ixdp425_flash_nand_resource.end   = IXP4XX_EXP_BUS_BASE(3) + 0x10 - 1;
+
+       gpio_line_config(IXDP425_NAND_NCE_PIN, IXP4XX_GPIO_OUT);
+
+       /* Configure expansion bus for NAND Flash */
+       *IXP4XX_EXP_CS3 = IXP4XX_EXP_BUS_CS_EN |
+                         IXP4XX_EXP_BUS_STROBE_T(1) |  /* extend by 1 clock */
+                         IXP4XX_EXP_BUS_CYCLES(0) |    /* Intel cycles */
+                         IXP4XX_EXP_BUS_SIZE(0) |      /* 512bytes addr space*/
+                         IXP4XX_EXP_BUS_WR_EN |
+                         IXP4XX_EXP_BUS_BYTE_EN;       /* 8 bit data bus */
+#endif
+
        if (cpu_is_ixp43x()) {
                ixdp425_uart.num_resources = 1;
                ixdp425_uart_data[1].flags = 0;
diff --git a/arch/arm/mach-ixp4xx/wg302v2-pci.c b/arch/arm/mach-ixp4xx/wg302v2-pci.c
new file mode 100644 (file)
index 0000000..6588f2c
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * arch/arch/mach-ixp4xx/wg302v2-pci.c
+ *
+ * PCI setup routines for the Netgear WG302 v2 and WAG302 v2
+ *
+ * Copyright (C) 2007 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * based on coyote-pci.c:
+ *     Copyright (C) 2002 Jungo Software Technologies.
+ *     Copyright (C) 2003 MontaVista Software, Inc.
+ *
+ * Maintainer: Imre Kaloz <kaloz@openwrt.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/pci.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+
+#include <asm/mach/pci.h>
+
+void __init wg302v2_pci_preinit(void)
+{
+       set_irq_type(IRQ_IXP4XX_GPIO8, IRQT_LOW);
+       set_irq_type(IRQ_IXP4XX_GPIO9, IRQT_LOW);
+
+       ixp4xx_pci_preinit();
+}
+
+static int __init wg302v2_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+       if (slot == 1)
+               return IRQ_IXP4XX_GPIO8;
+       else if (slot == 2)
+               return IRQ_IXP4XX_GPIO9;
+       else return -1;
+}
+
+struct hw_pci wg302v2_pci __initdata = {
+       .nr_controllers = 1,
+       .preinit =        wg302v2_pci_preinit,
+       .swizzle =        pci_std_swizzle,
+       .setup =          ixp4xx_setup,
+       .scan =           ixp4xx_scan_bus,
+       .map_irq =        wg302v2_map_irq,
+};
+
+int __init wg302v2_pci_init(void)
+{
+       if (machine_is_wg302v2())
+               pci_common_init(&wg302v2_pci);
+       return 0;
+}
+
+subsys_initcall(wg302v2_pci_init);
diff --git a/arch/arm/mach-ixp4xx/wg302v2-setup.c b/arch/arm/mach-ixp4xx/wg302v2-setup.c
new file mode 100644 (file)
index 0000000..f7e09ad
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * arch/arm/mach-ixp4xx/wg302-setup.c
+ *
+ * Board setup for the Netgear WG302 v2 and WAG302 v2
+ *
+ * Copyright (C) 2007 Imre Kaloz <Kaloz@openwrt.org>
+ *
+ * based on coyote-setup.c:
+ *      Copyright (C) 2003-2005 MontaVista Software, Inc.
+ *
+ * Author: Imre Kaloz <kaloz@openwrt.org>
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/serial_8250.h>
+#include <linux/slab.h>
+
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+
+static struct flash_platform_data wg302v2_flash_data = {
+       .map_name       = "cfi_probe",
+       .width          = 2,
+};
+
+static struct resource wg302v2_flash_resource = {
+       .flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device wg302v2_flash = {
+       .name           = "IXP4XX-Flash",
+       .id             = 0,
+       .dev            = {
+               .platform_data = &wg302v2_flash_data,
+       },
+       .num_resources  = 1,
+       .resource       = &wg302v2_flash_resource,
+};
+
+static struct resource wg302v2_uart_resource = {
+       .start  = IXP4XX_UART2_BASE_PHYS,
+       .end    = IXP4XX_UART2_BASE_PHYS + 0x0fff,
+       .flags  = IORESOURCE_MEM,
+};
+
+static struct plat_serial8250_port wg302v2_uart_data[] = {
+       {
+               .mapbase        = IXP4XX_UART2_BASE_PHYS,
+               .membase        = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
+               .irq            = IRQ_IXP4XX_UART2,
+               .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+               .iotype         = UPIO_MEM,
+               .regshift       = 2,
+               .uartclk        = IXP4XX_UART_XTAL,
+       },
+       { },
+};
+
+static struct platform_device wg302v2_uart = {
+       .name           = "serial8250",
+       .id             = PLAT8250_DEV_PLATFORM,
+       .dev                    = {
+               .platform_data  = wg302v2_uart_data,
+       },
+       .num_resources  = 1,
+       .resource       = &wg302v2_uart_resource,
+};
+
+static struct platform_device *wg302v2_devices[] __initdata = {
+       &wg302v2_flash,
+       &wg302v2_uart,
+};
+
+static void __init wg302v2_init(void)
+{
+       ixp4xx_sys_init();
+
+       wg302v2_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
+       wg302v2_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_32M - 1;
+
+       *IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE;
+       *IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0;
+
+       platform_add_devices(wg302v2_devices, ARRAY_SIZE(wg302v2_devices));
+}
+
+#ifdef CONFIG_MACH_WG302V2
+MACHINE_START(WG302V2, "Netgear WG302 v2 / WAG302 v2")
+       /* Maintainer: Imre Kaloz <kaloz@openwrt.org> */
+       .phys_io        = IXP4XX_PERIPHERAL_BASE_PHYS,
+       .io_pg_offst    = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
+       .map_io         = ixp4xx_map_io,
+       .init_irq       = ixp4xx_init_irq,
+       .timer          = &ixp4xx_timer,
+       .boot_params    = 0x0100,
+       .init_machine   = wg302v2_init,
+MACHINE_END
+#endif
index 56b7d337333a6fa43412c2b627ce18d35049625e..2a07a281fa8ae927f9957575f4c448a81bad8815 100644 (file)
@@ -3,7 +3,7 @@
 # Makefile for KS8695 architecture support
 #
 
-obj-y                          := cpu.o irq.o time.o devices.o
+obj-y                          := cpu.o irq.o time.o gpio.o devices.o
 obj-m                          :=
 obj-n                          :=
 obj-                           :=
diff --git a/arch/arm/mach-ks8695/gpio.c b/arch/arm/mach-ks8695/gpio.c
new file mode 100644 (file)
index 0000000..b1aa3cb
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ * arch/arm/mach-ks8695/gpio.c
+ *
+ * Copyright (C) 2006 Andrew Victor
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/module.h>
+
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/gpio.h>
+
+/*
+ * Configure a GPIO line for either GPIO function, or its internal
+ * function (Interrupt, Timer, etc).
+ */
+static void __init_or_module ks8695_gpio_mode(unsigned int pin, short gpio)
+{
+       unsigned int enable[] = { IOPC_IOEINT0EN, IOPC_IOEINT1EN, IOPC_IOEINT2EN, IOPC_IOEINT3EN, IOPC_IOTIM0EN, IOPC_IOTIM1EN };
+       unsigned long x, flags;
+
+       if (pin > KS8695_GPIO_5)        /* only GPIO 0..5 have internal functions */
+               return;
+
+       local_irq_save(flags);
+
+       x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPC);
+       if (gpio)                       /* GPIO: set bit to 0 */
+               x &= ~enable[pin];
+       else                            /* Internal function: set bit to 1 */
+               x |= enable[pin];
+       __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPC);
+
+       local_irq_restore(flags);
+}
+
+
+static unsigned short gpio_irq[] = { KS8695_IRQ_EXTERN0, KS8695_IRQ_EXTERN1, KS8695_IRQ_EXTERN2, KS8695_IRQ_EXTERN3 };
+
+/*
+ * Configure GPIO pin as external interrupt source.
+ */
+int __init_or_module ks8695_gpio_interrupt(unsigned int pin, unsigned int type)
+{
+       unsigned long x, flags;
+
+       if (pin > KS8695_GPIO_3)        /* only GPIO 0..3 can generate IRQ */
+               return -EINVAL;
+
+       local_irq_save(flags);
+
+       /* set pin as input */
+       x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM);
+       x &= ~IOPM_(pin);
+       __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPM);
+
+       local_irq_restore(flags);
+
+       /* Set IRQ triggering type */
+       set_irq_type(gpio_irq[pin], type);
+
+       /* enable interrupt mode */
+       ks8695_gpio_mode(pin, 0);
+
+       return 0;
+}
+EXPORT_SYMBOL(ks8695_gpio_interrupt);
+
+
+
+/* .... Generic GPIO interface .............................................. */
+
+/*
+ * Configure the GPIO line as an input.
+ */
+int __init_or_module gpio_direction_input(unsigned int pin)
+{
+       unsigned long x, flags;
+
+       if (pin > KS8695_GPIO_15)
+               return -EINVAL;
+
+       /* set pin to GPIO mode */
+       ks8695_gpio_mode(pin, 1);
+
+       local_irq_save(flags);
+
+       /* set pin as input */
+       x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM);
+       x &= ~IOPM_(pin);
+       __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPM);
+
+       local_irq_restore(flags);
+
+       return 0;
+}
+EXPORT_SYMBOL(gpio_direction_input);
+
+
+/*
+ * Configure the GPIO line as an output, with default state.
+ */
+int __init_or_module gpio_direction_output(unsigned int pin, unsigned int state)
+{
+       unsigned long x, flags;
+
+       if (pin > KS8695_GPIO_15)
+               return -EINVAL;
+
+       /* set pin to GPIO mode */
+       ks8695_gpio_mode(pin, 1);
+
+       local_irq_save(flags);
+
+       /* set line state */
+       x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD);
+       if (state)
+               x |= (1 << pin);
+       else
+               x &= ~(1 << pin);
+       __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPD);
+
+       /* set pin as output */
+       x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM);
+       x |= IOPM_(pin);
+       __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPM);
+
+       local_irq_restore(flags);
+
+       return 0;
+}
+EXPORT_SYMBOL(gpio_direction_output);
+
+
+/*
+ * Set the state of an output GPIO line.
+ */
+void gpio_set_value(unsigned int pin, unsigned int state)
+{
+       unsigned long x, flags;
+
+       if (pin > KS8695_GPIO_15)
+               return;
+
+       local_irq_save(flags);
+
+       /* set output line state */
+       x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD);
+       if (state)
+               x |= (1 << pin);
+       else
+               x &= ~(1 << pin);
+       __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPD);
+
+       local_irq_restore(flags);
+}
+EXPORT_SYMBOL(gpio_set_value);
+
+
+/*
+ * Read the state of a GPIO line.
+ */
+int gpio_get_value(unsigned int pin)
+{
+       unsigned long x;
+
+       if (pin > KS8695_GPIO_15)
+               return -EINVAL;
+
+       x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD);
+       return (x & (1 << pin)) != 0;
+}
+EXPORT_SYMBOL(gpio_get_value);
+
+
+/*
+ * Map GPIO line to IRQ number.
+ */
+int gpio_to_irq(unsigned int pin)
+{
+       if (pin > KS8695_GPIO_3)        /* only GPIO 0..3 can generate IRQ */
+               return -EINVAL;
+
+       return gpio_irq[pin];
+}
+EXPORT_SYMBOL(gpio_to_irq);
+
+
+/*
+ * Map IRQ number to GPIO line.
+ */
+int irq_to_gpio(unsigned int irq)
+{
+       if ((irq < KS8695_IRQ_EXTERN0) || (irq > KS8695_IRQ_EXTERN3))
+               return -EINVAL;
+
+       return (irq - KS8695_IRQ_EXTERN0);
+}
+EXPORT_SYMBOL(irq_to_gpio);
index 8f7c90a0593bce2ccf20669b1268703e8c4f4003..34a31caa6f9d6a83cbc379014fdbe8b88ccd7395 100644 (file)
@@ -12,7 +12,6 @@
 
 #include <asm/arch/pxa-regs.h>
 #include <asm/hardware.h>
-#include <asm/semaphore.h>
 
 struct clk {
        struct list_head        node;
@@ -25,21 +24,21 @@ struct clk {
 };
 
 static LIST_HEAD(clocks);
-static DECLARE_MUTEX(clocks_sem);
+static DEFINE_MUTEX(clocks_mutex);
 static DEFINE_SPINLOCK(clocks_lock);
 
 struct clk *clk_get(struct device *dev, const char *id)
 {
        struct clk *p, *clk = ERR_PTR(-ENOENT);
 
-       down(&clocks_sem);
+       mutex_lock(&clocks_mutex);
        list_for_each_entry(p, &clocks, node) {
                if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
                        clk = p;
                        break;
                }
        }
-       up(&clocks_sem);
+       mutex_unlock(&clocks_mutex);
 
        return clk;
 }
@@ -101,18 +100,18 @@ static struct clk clk_gpio27 = {
 
 int clk_register(struct clk *clk)
 {
-       down(&clocks_sem);
+       mutex_lock(&clocks_mutex);
        list_add(&clk->node, &clocks);
-       up(&clocks_sem);
+       mutex_unlock(&clocks_mutex);
        return 0;
 }
 EXPORT_SYMBOL(clk_register);
 
 void clk_unregister(struct clk *clk)
 {
-       down(&clocks_sem);
+       mutex_lock(&clocks_mutex);
        list_del(&clk->node);
-       up(&clocks_sem);
+       mutex_unlock(&clocks_mutex);
 }
 EXPORT_SYMBOL(clk_unregister);
 
index a1a900d16665fc8f58d6431306d1d4df0011dbee..aab27297b3c60da5937852e50a05cd70a27da5b8 100644 (file)
@@ -44,6 +44,7 @@
 #include <asm/hardware/scoop.h>
 
 #include "generic.h"
+#include "devices.h"
 #include "sharpsl.h"
 
 
@@ -368,7 +369,7 @@ MACHINE_START(CORGI, "SHARP Corgi")
        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
        .fixup          = fixup_corgi,
        .map_io         = pxa_map_io,
-       .init_irq       = pxa_init_irq,
+       .init_irq       = pxa25x_init_irq,
        .init_machine   = corgi_init,
        .timer          = &pxa_timer,
 MACHINE_END
@@ -380,7 +381,7 @@ MACHINE_START(SHEPHERD, "SHARP Shepherd")
        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
        .fixup          = fixup_corgi,
        .map_io         = pxa_map_io,
-       .init_irq       = pxa_init_irq,
+       .init_irq       = pxa25x_init_irq,
        .init_machine   = corgi_init,
        .timer          = &pxa_timer,
 MACHINE_END
@@ -392,7 +393,7 @@ MACHINE_START(HUSKY, "SHARP Husky")
        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
        .fixup          = fixup_corgi,
        .map_io         = pxa_map_io,
-       .init_irq       = pxa_init_irq,
+       .init_irq       = pxa25x_init_irq,
        .init_machine   = corgi_init,
        .timer          = &pxa_timer,
 MACHINE_END
diff --git a/arch/arm/mach-pxa/devices.h b/arch/arm/mach-pxa/devices.h
new file mode 100644 (file)
index 0000000..9a6faff
--- /dev/null
@@ -0,0 +1,11 @@
+extern struct platform_device pxamci_device;
+extern struct platform_device pxaudc_device;
+extern struct platform_device pxafb_device;
+extern struct platform_device ffuart_device;
+extern struct platform_device btuart_device;
+extern struct platform_device stuart_device;
+extern struct platform_device hwuart_device;
+extern struct platform_device pxai2c_device;
+extern struct platform_device pxai2s_device;
+extern struct platform_device pxaficp_device;
+extern struct platform_device pxartc_device;
index 4440babe7b97595dabe3330082ffd8aad9b6d674..93c4f31f127faa053dcd555f5fe7aa66fb5aee34 100644 (file)
 
 #include <asm/arch/pxa-regs.h>
 
-static struct dma_channel {
+struct dma_channel {
        char *name;
+       pxa_dma_prio prio;
        void (*irq_handler)(int, void *);
        void *data;
-} dma_channels[PXA_DMA_CHANNELS];
+};
 
+static struct dma_channel *dma_channels;
+static int num_dma_channels;
 
 int pxa_request_dma (char *name, pxa_dma_prio prio,
                         void (*irq_handler)(int, void *),
@@ -47,8 +50,9 @@ int pxa_request_dma (char *name, pxa_dma_prio prio,
 
        do {
                /* try grabbing a DMA channel with the requested priority */
-               pxa_for_each_dma_prio (i, prio) {
-                       if (!dma_channels[i].name) {
+               for (i = 0; i < num_dma_channels; i++) {
+                       if ((dma_channels[i].prio == prio) &&
+                           !dma_channels[i].name) {
                                found = 1;
                                break;
                        }
@@ -91,7 +95,7 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
 {
        int i, dint = DINT;
 
-       for (i = 0; i < PXA_DMA_CHANNELS; i++) {
+       for (i = 0; i < num_dma_channels; i++) {
                if (dint & (1 << i)) {
                        struct dma_channel *channel = &dma_channels[i];
                        if (channel->name && channel->irq_handler) {
@@ -109,18 +113,32 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-static int __init pxa_dma_init (void)
+int __init pxa_init_dma(int num_ch)
 {
-       int ret;
+       int i, ret;
 
-       ret = request_irq (IRQ_DMA, dma_irq_handler, 0, "DMA", NULL);
-       if (ret)
+       dma_channels = kzalloc(sizeof(struct dma_channel) * num_ch, GFP_KERNEL);
+       if (dma_channels == NULL)
+               return -ENOMEM;
+
+       ret = request_irq(IRQ_DMA, dma_irq_handler, IRQF_DISABLED, "DMA", NULL);
+       if (ret) {
                printk (KERN_CRIT "Wow!  Can't register IRQ for DMA\n");
-       return ret;
-}
+               kfree(dma_channels);
+               return ret;
+       }
 
-arch_initcall(pxa_dma_init);
+       /* dma channel priorities on pxa2xx processors:
+        * ch 0 - 3,  16 - 19  <--> (0) DMA_PRIO_HIGH
+        * ch 4 - 7,  20 - 23  <--> (1) DMA_PRIO_MEDIUM
+        * ch 8 - 15, 24 - 31  <--> (2) DMA_PRIO_LOW
+        */
+       for (i = 0; i < num_ch; i++)
+               dma_channels[i].prio = min((i & 0xf) >> 2, DMA_PRIO_LOW);
+
+       num_dma_channels = num_ch;
+       return 0;
+}
 
 EXPORT_SYMBOL(pxa_request_dma);
 EXPORT_SYMBOL(pxa_free_dma);
-
index 64b08b744f9f3fd12bcd06169e949b09881b39b8..296539b6359ca43af779f59e5fa078351c14195b 100644 (file)
@@ -43,6 +43,7 @@
 #include <asm/arch/irda.h>
 #include <asm/arch/i2c.h>
 
+#include "devices.h"
 #include "generic.h"
 
 /*
@@ -242,7 +243,7 @@ static struct resource pxamci_resources[] = {
 
 static u64 pxamci_dmamask = 0xffffffffUL;
 
-static struct platform_device pxamci_device = {
+struct platform_device pxamci_device = {
        .name           = "pxa2xx-mci",
        .id             = -1,
        .dev            = {
@@ -281,7 +282,7 @@ static struct resource pxa2xx_udc_resources[] = {
 
 static u64 udc_dma_mask = ~(u32)0;
 
-static struct platform_device udc_device = {
+struct platform_device pxaudc_device = {
        .name           = "pxa2xx-udc",
        .id             = -1,
        .resource       = pxa2xx_udc_resources,
@@ -307,7 +308,7 @@ static struct resource pxafb_resources[] = {
 
 static u64 fb_dma_mask = ~(u64)0;
 
-static struct platform_device pxafb_device = {
+struct platform_device pxafb_device = {
        .name           = "pxa2xx-fb",
        .id             = -1,
        .dev            = {
@@ -328,24 +329,24 @@ void __init set_pxa_fb_parent(struct device *parent_dev)
        pxafb_device.dev.parent = parent_dev;
 }
 
-static struct platform_device ffuart_device = {
+struct platform_device ffuart_device = {
        .name           = "pxa2xx-uart",
        .id             = 0,
 };
-static struct platform_device btuart_device = {
+struct platform_device btuart_device = {
        .name           = "pxa2xx-uart",
        .id             = 1,
 };
-static struct platform_device stuart_device = {
+struct platform_device stuart_device = {
        .name           = "pxa2xx-uart",
        .id             = 2,
 };
-static struct platform_device hwuart_device = {
+struct platform_device hwuart_device = {
        .name           = "pxa2xx-uart",
        .id             = 3,
 };
 
-static struct resource i2c_resources[] = {
+static struct resource pxai2c_resources[] = {
        {
                .start  = 0x40301680,
                .end    = 0x403016a3,
@@ -357,40 +358,19 @@ static struct resource i2c_resources[] = {
        },
 };
 
-static struct platform_device i2c_device = {
+struct platform_device pxai2c_device = {
        .name           = "pxa2xx-i2c",
        .id             = 0,
-       .resource       = i2c_resources,
-       .num_resources  = ARRAY_SIZE(i2c_resources),
+       .resource       = pxai2c_resources,
+       .num_resources  = ARRAY_SIZE(pxai2c_resources),
 };
 
-#ifdef CONFIG_PXA27x
-static struct resource i2c_power_resources[] = {
-       {
-               .start  = 0x40f00180,
-               .end    = 0x40f001a3,
-               .flags  = IORESOURCE_MEM,
-       }, {
-               .start  = IRQ_PWRI2C,
-               .end    = IRQ_PWRI2C,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device i2c_power_device = {
-       .name           = "pxa2xx-i2c",
-       .id             = 1,
-       .resource       = i2c_power_resources,
-       .num_resources  = ARRAY_SIZE(i2c_resources),
-};
-#endif
-
 void __init pxa_set_i2c_info(struct i2c_pxa_platform_data *info)
 {
-       i2c_device.dev.platform_data = info;
+       pxai2c_device.dev.platform_data = info;
 }
 
-static struct resource i2s_resources[] = {
+static struct resource pxai2s_resources[] = {
        {
                .start  = 0x40400000,
                .end    = 0x40400083,
@@ -402,16 +382,16 @@ static struct resource i2s_resources[] = {
        },
 };
 
-static struct platform_device i2s_device = {
+struct platform_device pxai2s_device = {
        .name           = "pxa2xx-i2s",
        .id             = -1,
-       .resource       = i2s_resources,
-       .num_resources  = ARRAY_SIZE(i2s_resources),
+       .resource       = pxai2s_resources,
+       .num_resources  = ARRAY_SIZE(pxai2s_resources),
 };
 
 static u64 pxaficp_dmamask = ~(u32)0;
 
-static struct platform_device pxaficp_device = {
+struct platform_device pxaficp_device = {
        .name           = "pxa2xx-ir",
        .id             = -1,
        .dev            = {
@@ -425,42 +405,7 @@ void __init pxa_set_ficp_info(struct pxaficp_platform_data *info)
        pxaficp_device.dev.platform_data = info;
 }
 
-static struct platform_device pxartc_device = {
+struct platform_device pxartc_device = {
        .name           = "sa1100-rtc",
        .id             = -1,
 };
-
-static struct platform_device *devices[] __initdata = {
-       &pxamci_device,
-       &udc_device,
-       &pxafb_device,
-       &ffuart_device,
-       &btuart_device,
-       &stuart_device,
-       &pxaficp_device,
-       &i2c_device,
-#ifdef CONFIG_PXA27x
-       &i2c_power_device,
-#endif
-       &i2s_device,
-       &pxartc_device,
-};
-
-static int __init pxa_init(void)
-{
-       int cpuid, ret;
-
-       ret = platform_add_devices(devices, ARRAY_SIZE(devices));
-       if (ret)
-               return ret;
-
-       /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */
-       cpuid = read_cpuid(CPUID_ID);
-       if (((cpuid >> 4) & 0xfff) == 0x2d0 ||
-           ((cpuid >> 4) & 0xfff) == 0x290)
-               ret = platform_device_register(&hwuart_device);
-
-       return ret;
-}
-
-subsys_initcall(pxa_init);
index e54a8dd63c17df1a5b2d12bb0fe2de306390ee18..91ab2ad8b34b78020da69be0bc71c5597c529ab4 100644 (file)
 struct sys_timer;
 
 extern struct sys_timer pxa_timer;
+extern void __init pxa_init_irq_low(void);
+extern void __init pxa_init_irq_high(void);
+extern void __init pxa_init_irq_gpio(int gpio_nr);
+extern void __init pxa25x_init_irq(void);
+extern void __init pxa27x_init_irq(void);
 extern void __init pxa_map_io(void);
-extern void __init pxa_init_irq(void);
 
 extern unsigned int get_clk_frequency_khz(int info);
 
index 64df44043a654f88826edd7e2e65470d41bdf455..465108da285103be616ecfd8f13f9f5d302bcb63 100644 (file)
@@ -38,6 +38,7 @@
 #include <asm/arch/mmc.h>
 
 #include "generic.h"
+#include "devices.h"
 
 /* TODO:
  * - add pxa2xx_audio_ops_t device structure
@@ -152,7 +153,7 @@ static void __init idp_init(void)
 static void __init idp_init_irq(void)
 {
 
-       pxa_init_irq();
+       pxa25x_init_irq();
 
        set_irq_type(TOUCH_PANEL_IRQ, TOUCH_PANEL_IRQ_EDGE);
 }
index 4619d5fe606c2bad027ee2bf023f6c045d3ab882..4b867b0789d54c8a9e463e08fbce0cf1f239db61 100644 (file)
 
 static void pxa_mask_low_irq(unsigned int irq)
 {
-       ICMR &= ~(1 << (irq + PXA_IRQ_SKIP));
+       ICMR &= ~(1 << irq);
 }
 
 static void pxa_unmask_low_irq(unsigned int irq)
 {
-       ICMR |= (1 << (irq + PXA_IRQ_SKIP));
+       ICMR |= (1 << irq);
 }
 
 static int pxa_set_wake(unsigned int irq, unsigned int on)
@@ -67,7 +67,27 @@ static struct irq_chip pxa_internal_chip_low = {
        .set_wake       = pxa_set_wake,
 };
 
-#if PXA_INTERNAL_IRQS > 32
+void __init pxa_init_irq_low(void)
+{
+       int irq;
+
+       /* disable all IRQs */
+       ICMR = 0;
+
+       /* all IRQs are IRQ, not FIQ */
+       ICLR = 0;
+
+       /* only unmasked interrupts kick us out of idle */
+       ICCR = 1;
+
+       for (irq = PXA_IRQ(0); irq <= PXA_IRQ(31); irq++) {
+               set_irq_chip(irq, &pxa_internal_chip_low);
+               set_irq_handler(irq, handle_level_irq);
+               set_irq_flags(irq, IRQF_VALID);
+       }
+}
+
+#ifdef CONFIG_PXA27x
 
 /*
  * This is for the second set of internal IRQs as found on the PXA27x.
@@ -75,12 +95,12 @@ static struct irq_chip pxa_internal_chip_low = {
 
 static void pxa_mask_high_irq(unsigned int irq)
 {
-       ICMR2 &= ~(1 << (irq - 32 + PXA_IRQ_SKIP));
+       ICMR2 &= ~(1 << (irq - 32));
 }
 
 static void pxa_unmask_high_irq(unsigned int irq)
 {
-       ICMR2 |= (1 << (irq - 32 + PXA_IRQ_SKIP));
+       ICMR2 |= (1 << (irq - 32));
 }
 
 static struct irq_chip pxa_internal_chip_high = {
@@ -90,6 +110,19 @@ static struct irq_chip pxa_internal_chip_high = {
        .unmask         = pxa_unmask_high_irq,
 };
 
+void __init pxa_init_irq_high(void)
+{
+       int irq;
+
+       ICMR2 = 0;
+       ICLR2 = 0;
+
+       for (irq = PXA_IRQ(32); irq < PXA_IRQ(64); irq++) {
+               set_irq_chip(irq, &pxa_internal_chip_high);
+               set_irq_handler(irq, handle_level_irq);
+               set_irq_flags(irq, IRQF_VALID);
+       }
+}
 #endif
 
 /* Note that if an input/irq line ever gets changed to an output during
@@ -217,7 +250,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
        do {
                loop = 0;
 
-               mask = GEDR0 & ~3;
+               mask = GEDR0 & GPIO_IRQ_mask[0] & ~3;
                if (mask) {
                        GEDR0 = mask;
                        irq = IRQ_GPIO(2);
@@ -233,7 +266,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
                        loop = 1;
                }
 
-               mask = GEDR1;
+               mask = GEDR1 & GPIO_IRQ_mask[1];
                if (mask) {
                        GEDR1 = mask;
                        irq = IRQ_GPIO(32);
@@ -248,7 +281,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
                        loop = 1;
                }
 
-               mask = GEDR2;
+               mask = GEDR2 & GPIO_IRQ_mask[2];
                if (mask) {
                        GEDR2 = mask;
                        irq = IRQ_GPIO(64);
@@ -263,8 +296,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
                        loop = 1;
                }
 
-#if PXA_LAST_GPIO >= 96
-               mask = GEDR3;
+               mask = GEDR3 & GPIO_IRQ_mask[3];
                if (mask) {
                        GEDR3 = mask;
                        irq = IRQ_GPIO(96);
@@ -278,7 +310,6 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
                        } while (mask);
                        loop = 1;
                }
-#endif
        } while (loop);
 }
 
@@ -314,64 +345,27 @@ static struct irq_chip pxa_muxed_gpio_chip = {
        .set_wake       = pxa_set_gpio_wake,
 };
 
-
-void __init pxa_init_irq(void)
+void __init pxa_init_irq_gpio(int gpio_nr)
 {
-       int irq;
-
-       /* disable all IRQs */
-       ICMR = 0;
-
-       /* all IRQs are IRQ, not FIQ */
-       ICLR = 0;
+       int irq, i;
 
        /* clear all GPIO edge detects */
-       GFER0 = 0;
-       GFER1 = 0;
-       GFER2 = 0;
-       GRER0 = 0;
-       GRER1 = 0;
-       GRER2 = 0;
-       GEDR0 = GEDR0;
-       GEDR1 = GEDR1;
-       GEDR2 = GEDR2;
-
-#ifdef CONFIG_PXA27x
-       /* And similarly for the extra regs on the PXA27x */
-       ICMR2 = 0;
-       ICLR2 = 0;
-       GFER3 = 0;
-       GRER3 = 0;
-       GEDR3 = GEDR3;
-#endif
-
-       /* only unmasked interrupts kick us out of idle */
-       ICCR = 1;
+       for (i = 0; i < gpio_nr; i += 32) {
+               GFER(i) = 0;
+               GRER(i) = 0;
+               GEDR(i) = GEDR(i);
+       }
 
        /* GPIO 0 and 1 must have their mask bit always set */
        GPIO_IRQ_mask[0] = 3;
 
-       for (irq = PXA_IRQ(PXA_IRQ_SKIP); irq <= PXA_IRQ(31); irq++) {
-               set_irq_chip(irq, &pxa_internal_chip_low);
-               set_irq_handler(irq, handle_level_irq);
-               set_irq_flags(irq, IRQF_VALID);
-       }
-
-#if PXA_INTERNAL_IRQS > 32
-       for (irq = PXA_IRQ(32); irq < PXA_IRQ(PXA_INTERNAL_IRQS); irq++) {
-               set_irq_chip(irq, &pxa_internal_chip_high);
-               set_irq_handler(irq, handle_level_irq);
-               set_irq_flags(irq, IRQF_VALID);
-       }
-#endif
-
        for (irq = IRQ_GPIO0; irq <= IRQ_GPIO1; irq++) {
                set_irq_chip(irq, &pxa_low_gpio_chip);
                set_irq_handler(irq, handle_edge_irq);
                set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
        }
 
-       for (irq = IRQ_GPIO(2); irq <= IRQ_GPIO(PXA_LAST_GPIO); irq++) {
+       for (irq = IRQ_GPIO(2); irq <= IRQ_GPIO(gpio_nr); irq++) {
                set_irq_chip(irq, &pxa_muxed_gpio_chip);
                set_irq_handler(irq, handle_edge_irq);
                set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
index e3097664ffe136e9cdb2f1386ca5174797030f3a..26116440a7c927648d7b8a3e493bdf042cab3beb 100644 (file)
@@ -46,6 +46,7 @@
 #include <asm/arch/ohci.h>
 
 #include "generic.h"
+#include "devices.h"
 
 
 static unsigned int lpd270_irq_enabled;
@@ -97,7 +98,7 @@ static void __init lpd270_init_irq(void)
 {
        int irq;
 
-       pxa_init_irq();
+       pxa27x_init_irq();
 
        __raw_writew(0, LPD270_INT_MASK);
        __raw_writew(0, LPD270_INT_STATUS);
index 6377b2e29ff07df44eca47f01fd8e283baa8717f..e70048fd00a53e28f08667a4331aad4c0258ea28 100644 (file)
@@ -48,6 +48,7 @@
 #include <asm/arch/mmc.h>
 
 #include "generic.h"
+#include "devices.h"
 
 
 #define LUB_MISC_WR            __LUB_REG(LUBBOCK_FPGA_PHYS + 0x080)
@@ -103,7 +104,7 @@ static void __init lubbock_init_irq(void)
 {
        int irq;
 
-       pxa_init_irq();
+       pxa25x_init_irq();
 
        /* setup extra lubbock irqs */
        for (irq = LUBBOCK_IRQ(0); irq <= LUBBOCK_LAST_IRQ; irq++) {
index ed99a81b98f3e563905caba6db9283cd876ab2d9..b02c79c7e6a3c7d7bf972d0d200eae6e680bee63 100644 (file)
@@ -46,6 +46,7 @@
 #include <asm/arch/ohci.h>
 
 #include "generic.h"
+#include "devices.h"
 
 
 static unsigned long mainstone_irq_enabled;
@@ -89,7 +90,7 @@ static void __init mainstone_init_irq(void)
 {
        int irq;
 
-       pxa_init_irq();
+       pxa27x_init_irq();
 
        /* setup extra Mainstone irqs */
        for(irq = MAINSTONE_IRQ(0); irq <= MAINSTONE_IRQ(15); irq++) {
index 6bf15ae73848efc667689d28661944e00a84d167..e66dbc26add1f1f8291e4461b3b2f9a000e86d3c 100644 (file)
@@ -77,7 +77,6 @@ int pxa_pm_enter(suspend_state_t state)
 {
        unsigned long sleep_save[SLEEP_SAVE_SIZE];
        unsigned long checksum = 0;
-       struct timespec delta, rtc;
        int i;
        extern void pxa_cpu_pm_enter(suspend_state_t state);
 
@@ -87,11 +86,6 @@ int pxa_pm_enter(suspend_state_t state)
                iwmmxt_task_disable(NULL);
 #endif
 
-       /* preserve current time */
-       rtc.tv_sec = RCNR;
-       rtc.tv_nsec = 0;
-       save_time_delta(&delta, &rtc);
-
        SAVE(GPLR0); SAVE(GPLR1); SAVE(GPLR2);
        SAVE(GPDR0); SAVE(GPDR1); SAVE(GPDR2);
        SAVE(GRER0); SAVE(GRER1); SAVE(GRER2);
@@ -183,10 +177,6 @@ int pxa_pm_enter(suspend_state_t state)
 
        RESTORE(PSTR);
 
-       /* restore current time */
-       rtc.tv_sec = RCNR;
-       restore_time_delta(&delta, &rtc);
-
 #ifdef DEBUG
        printk(KERN_DEBUG "*** made it back from resume\n");
 #endif
@@ -200,40 +190,3 @@ unsigned long sleep_phys_sp(void *sp)
 {
        return virt_to_phys(sp);
 }
-
-/*
- * Called after processes are frozen, but before we shut down devices.
- */
-int pxa_pm_prepare(suspend_state_t state)
-{
-       extern int pxa_cpu_pm_prepare(suspend_state_t state);
-
-       return pxa_cpu_pm_prepare(state);
-}
-
-EXPORT_SYMBOL_GPL(pxa_pm_prepare);
-
-/*
- * Called after devices are re-setup, but before processes are thawed.
- */
-int pxa_pm_finish(suspend_state_t state)
-{
-       return 0;
-}
-
-EXPORT_SYMBOL_GPL(pxa_pm_finish);
-
-static struct pm_ops pxa_pm_ops = {
-       .prepare        = pxa_pm_prepare,
-       .enter          = pxa_pm_enter,
-       .finish         = pxa_pm_finish,
-       .valid          = pm_valid_only_mem,
-};
-
-static int __init pxa_pm_init(void)
-{
-       pm_set_ops(&pxa_pm_ops);
-       return 0;
-}
-
-device_initcall(pxa_pm_init);
index 34fb80b37023090147e43c1870591f6a829f6758..655668d4d0e9936a0eb925fa1b8d292ecde31a0f 100644 (file)
@@ -45,6 +45,7 @@
 #include <asm/mach/sharpsl_param.h>
 
 #include "generic.h"
+#include "devices.h"
 #include "sharpsl.h"
 
 static struct resource poodle_scoop_resources[] = {
@@ -412,7 +413,7 @@ MACHINE_START(POODLE, "SHARP Poodle")
        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
        .fixup          = fixup_poodle,
        .map_io         = pxa_map_io,
-       .init_irq       = pxa_init_irq,
+       .init_irq       = pxa25x_init_irq,
        .timer          = &pxa_timer,
        .init_machine   = poodle_init,
 MACHINE_END
index c1f21739bf714a435dc7b3df21c3fc2c488e152b..f36ca448338e380ff76cef2764193a7d83e4949c 100644 (file)
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/platform_device.h>
 #include <linux/pm.h>
 
 #include <asm/hardware.h>
+#include <asm/arch/irqs.h>
 #include <asm/arch/pxa-regs.h>
+#include <asm/arch/pm.h>
+#include <asm/arch/dma.h>
 
 #include "generic.h"
+#include "devices.h"
 
 /*
  * Various clock factors driven by the CCCR register.
@@ -105,18 +110,6 @@ EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
 
 #ifdef CONFIG_PM
 
-int pxa_cpu_pm_prepare(suspend_state_t state)
-{
-       switch (state) {
-       case PM_SUSPEND_MEM:
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
 void pxa_cpu_pm_enter(suspend_state_t state)
 {
        extern void pxa_cpu_suspend(unsigned int);
@@ -133,4 +126,49 @@ void pxa_cpu_pm_enter(suspend_state_t state)
        }
 }
 
+static struct pm_ops pxa25x_pm_ops = {
+       .enter          = pxa_pm_enter,
+       .valid          = pm_valid_only_mem,
+};
+#endif
+
+void __init pxa25x_init_irq(void)
+{
+       pxa_init_irq_low();
+       pxa_init_irq_gpio(85);
+}
+
+static struct platform_device *pxa25x_devices[] __initdata = {
+       &pxamci_device,
+       &pxaudc_device,
+       &pxafb_device,
+       &ffuart_device,
+       &btuart_device,
+       &stuart_device,
+       &pxai2c_device,
+       &pxai2s_device,
+       &pxaficp_device,
+       &pxartc_device,
+};
+
+static int __init pxa25x_init(void)
+{
+       int ret = 0;
+
+       if (cpu_is_pxa21x() || cpu_is_pxa25x()) {
+               if ((ret = pxa_init_dma(16)))
+                       return ret;
+#ifdef CONFIG_PM
+               pm_set_ops(&pxa25x_pm_ops);
 #endif
+               ret = platform_add_devices(pxa25x_devices,
+                                          ARRAY_SIZE(pxa25x_devices));
+       }
+       /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */
+       if (cpu_is_pxa25x())
+               ret = platform_device_register(&hwuart_device);
+
+       return ret;
+}
+
+subsys_initcall(pxa25x_init);
index 1939acc3f9f7f6cdbd21e9d4fbc07ed55230686a..aa5bb02c897bd331c59ce29b1bcbc10c2be83e81 100644 (file)
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
+#include <asm/arch/irqs.h>
 #include <asm/arch/pxa-regs.h>
 #include <asm/arch/ohci.h>
+#include <asm/arch/pm.h>
+#include <asm/arch/dma.h>
 
 #include "generic.h"
+#include "devices.h"
 
 /* Crystal clock: 13MHz */
 #define BASE_CLK       13000000
@@ -122,17 +126,6 @@ EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
 
 #ifdef CONFIG_PM
 
-int pxa_cpu_pm_prepare(suspend_state_t state)
-{
-       switch (state) {
-       case PM_SUSPEND_MEM:
-       case PM_SUSPEND_STANDBY:
-               return 0;
-       default:
-               return -EINVAL;
-       }
-}
-
 void pxa_cpu_pm_enter(suspend_state_t state)
 {
        extern void pxa_cpu_standby(void);
@@ -162,6 +155,15 @@ void pxa_cpu_pm_enter(suspend_state_t state)
        }
 }
 
+static int pxa27x_pm_valid(suspend_state_t state)
+{
+       return state == PM_SUSPEND_MEM || state == PM_SUSPEND_STANDBY;
+}
+
+static struct pm_ops pxa27x_pm_ops = {
+       .enter          = pxa_pm_enter,
+       .valid          = pxa27x_pm_valid,
+};
 #endif
 
 /*
@@ -183,7 +185,7 @@ static struct resource pxa27x_ohci_resources[] = {
        },
 };
 
-static struct platform_device ohci_device = {
+static struct platform_device pxaohci_device = {
        .name           = "pxa27x-ohci",
        .id             = -1,
        .dev            = {
@@ -196,16 +198,62 @@ static struct platform_device ohci_device = {
 
 void __init pxa_set_ohci_info(struct pxaohci_platform_data *info)
 {
-       ohci_device.dev.platform_data = info;
+       pxaohci_device.dev.platform_data = info;
 }
 
+static struct resource i2c_power_resources[] = {
+       {
+               .start  = 0x40f00180,
+               .end    = 0x40f001a3,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .start  = IRQ_PWRI2C,
+               .end    = IRQ_PWRI2C,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device pxai2c_power_device = {
+       .name           = "pxa2xx-i2c",
+       .id             = 1,
+       .resource       = i2c_power_resources,
+       .num_resources  = ARRAY_SIZE(i2c_power_resources),
+};
+
 static struct platform_device *devices[] __initdata = {
-       &ohci_device,
+       &pxamci_device,
+       &pxaudc_device,
+       &pxafb_device,
+       &ffuart_device,
+       &btuart_device,
+       &stuart_device,
+       &pxai2c_device,
+       &pxai2c_power_device,
+       &pxai2s_device,
+       &pxaficp_device,
+       &pxartc_device,
+       &pxaohci_device,
 };
 
+void __init pxa27x_init_irq(void)
+{
+       pxa_init_irq_low();
+       pxa_init_irq_high();
+       pxa_init_irq_gpio(128);
+}
+
 static int __init pxa27x_init(void)
 {
-       return platform_add_devices(devices, ARRAY_SIZE(devices));
+       int ret = 0;
+       if (cpu_is_pxa27x()) {
+               if ((ret = pxa_init_dma(32)))
+                       return ret;
+#ifdef CONFIG_PM
+               pm_set_ops(&pxa27x_pm_ops);
+#endif
+               ret = platform_add_devices(devices, ARRAY_SIZE(devices));
+       }
+       return ret;
 }
 
 subsys_initcall(pxa27x_init);
index 3cbac63bed3c0b952db4c2af7149da2f6926c07d..bae47e145de83e01eefaf1b6fd2b05a0265f6f7a 100644 (file)
@@ -48,6 +48,7 @@
 #include <asm/hardware/scoop.h>
 
 #include "generic.h"
+#include "devices.h"
 #include "sharpsl.h"
 
 /*
@@ -560,7 +561,7 @@ MACHINE_START(SPITZ, "SHARP Spitz")
        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
        .fixup          = fixup_spitz,
        .map_io         = pxa_map_io,
-       .init_irq       = pxa_init_irq,
+       .init_irq       = pxa27x_init_irq,
        .init_machine   = spitz_init,
        .timer          = &pxa_timer,
 MACHINE_END
@@ -572,7 +573,7 @@ MACHINE_START(BORZOI, "SHARP Borzoi")
        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
        .fixup          = fixup_spitz,
        .map_io         = pxa_map_io,
-       .init_irq       = pxa_init_irq,
+       .init_irq       = pxa27x_init_irq,
        .init_machine   = spitz_init,
        .timer          = &pxa_timer,
 MACHINE_END
@@ -584,7 +585,7 @@ MACHINE_START(AKITA, "SHARP Akita")
        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
        .fixup          = fixup_spitz,
        .map_io         = pxa_map_io,
-       .init_irq       = pxa_init_irq,
+       .init_irq       = pxa27x_init_irq,
        .init_machine   = akita_init,
        .timer          = &pxa_timer,
 MACHINE_END
index 5248abe334d23f6966ea63f2c0a8462f69878261..6f91fd2d061ab0b9dc5062d5db3c551e03f6198e 100644 (file)
 #include <asm/arch/pxa-regs.h>
 
 
-static inline unsigned long pxa_get_rtc_time(void)
-{
-       return RCNR;
-}
-
 static int pxa_set_rtc(void)
 {
        unsigned long current_time = xtime.tv_sec;
@@ -122,10 +117,6 @@ static void __init pxa_timer_init(void)
 
        set_rtc = pxa_set_rtc;
 
-       tv.tv_nsec = 0;
-       tv.tv_sec = pxa_get_rtc_time();
-       do_settimeofday(&tv);
-
        OIER = 0;               /* disable any timer interrupts */
        OSSR = 0xf;             /* clear status on all timers */
        setup_irq(IRQ_OST0, &pxa_timer_irq);
index 72738771fb57cbf05495fa784f80c50215c52f92..240fd042083da10e6639f36c2b33dec5c2b8f895 100644 (file)
@@ -42,7 +42,7 @@
 #include <asm/mach/sharpsl_param.h>
 
 #include "generic.h"
-
+#include "devices.h"
 
 /*
  * SCOOP Device
@@ -332,7 +332,7 @@ MACHINE_START(TOSA, "SHARP Tosa")
        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
        .fixup          = fixup_tosa,
        .map_io         = pxa_map_io,
-       .init_irq       = pxa_init_irq,
+       .init_irq       = pxa25x_init_irq,
        .init_machine   = tosa_init,
        .timer          = &pxa_timer,
 MACHINE_END
index 28c79bd0a3a0da9c7fd741c24534e3cf62fc7e4c..e4ba43bdf85d9756123e13bd105b1024ef42a240 100644 (file)
@@ -49,6 +49,7 @@
 #include <asm/arch/ohci.h>
 
 #include "generic.h"
+#include "devices.h"
 
 /********************************************************************************************
  * ONBOARD FLASH
@@ -503,7 +504,7 @@ MACHINE_START(TRIZEPS4, "Keith und Koep Trizeps IV module")
        .boot_params    = TRIZEPS4_SDRAM_BASE + 0x100,
        .init_machine   = trizeps4_init,
        .map_io         = trizeps4_map_io,
-       .init_irq       = pxa_init_irq,
+       .init_irq       = pxa27x_init_irq,
        .timer          = &pxa_timer,
 MACHINE_END
 
index f01de807b72fd0c30f4d42dc297cf39cb207d779..8b52ea95d4f68523f72782aee1c8ca368a7ddb35 100644 (file)
@@ -20,6 +20,8 @@
 #include <linux/platform_device.h>
 #include <linux/dm9000.h>
 
+#include <net/ax88796.h>
+
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
@@ -409,6 +411,61 @@ static struct s3c2410_platform_i2c bast_i2c_info = {
        .max_freq       = 130*1000,
 };
 
+/* Asix AX88796 10/100 ethernet controller */
+
+static struct ax_plat_data bast_asix_platdata = {
+       .flags          = AXFLG_MAC_FROMDEV,
+       .wordlength     = 2,
+       .dcr_val        = 0x48,
+       .rcr_val        = 0x40,
+};
+
+static struct resource bast_asix_resource[] = {
+       [0] = {
+               .start = S3C2410_CS5 + BAST_PA_ASIXNET,
+               .end   = S3C2410_CS5 + BAST_PA_ASIXNET + (0x18 * 0x20) - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = S3C2410_CS5 + BAST_PA_ASIXNET + (0x1f * 0x20),
+               .end   = S3C2410_CS5 + BAST_PA_ASIXNET + (0x1f * 0x20),
+               .flags = IORESOURCE_MEM,
+       },
+       [2] = {
+               .start = IRQ_ASIX,
+               .end   = IRQ_ASIX,
+               .flags = IORESOURCE_IRQ
+       }
+};
+
+static struct platform_device bast_device_asix = {
+       .name           = "ax88796",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(bast_asix_resource),
+       .resource       = bast_asix_resource,
+       .dev            = {
+               .platform_data = &bast_asix_platdata
+       }
+};
+
+/* Asix AX88796 10/100 ethernet controller parallel port */
+
+static struct resource bast_asixpp_resource[] = {
+       [0] = {
+               .start = S3C2410_CS5 + BAST_PA_ASIXNET + (0x18 * 0x20),
+               .end   = S3C2410_CS5 + BAST_PA_ASIXNET + (0x1b * 0x20) - 1,
+               .flags = IORESOURCE_MEM,
+       }
+};
+
+static struct platform_device bast_device_axpp = {
+       .name           = "ax88796-pp",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(bast_asixpp_resource),
+       .resource       = bast_asixpp_resource,
+};
+
+/* LCD/VGA controller */
 
 static struct s3c2410fb_mach_info __initdata bast_lcd_info = {
        .width          = 640,
@@ -453,6 +510,8 @@ static struct platform_device *bast_devices[] __initdata = {
        &s3c_device_nand,
        &bast_device_nor,
        &bast_device_dm9k,
+       &bast_device_asix,
+       &bast_device_axpp,
        &bast_sio,
 };
 
index bff7ddd06a5288e7ed764c5fcef27444142c03dc..29c163d300d4cc9f78a4f35654e3559b92497efc 100644 (file)
@@ -18,6 +18,9 @@
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
 
+#include <linux/sm501.h>
+#include <linux/sm501-regs.h>
+
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
@@ -42,6 +45,8 @@
 #include <linux/mtd/nand_ecc.h>
 #include <linux/mtd/partitions.h>
 
+#include <net/ax88796.h>
+
 #include <asm/plat-s3c24xx/clock.h>
 #include <asm/plat-s3c24xx/devs.h>
 #include <asm/plat-s3c24xx/cpu.h>
@@ -153,6 +158,29 @@ static struct mtd_partition anubis_default_nand_part[] = {
        }
 };
 
+static struct mtd_partition anubis_default_nand_part_large[] = {
+       [0] = {
+               .name   = "Boot Agent",
+               .size   = SZ_128K,
+               .offset = 0,
+       },
+       [1] = {
+               .name   = "/boot",
+               .size   = SZ_4M - SZ_128K,
+               .offset = SZ_128K,
+       },
+       [2] = {
+               .name   = "user1",
+               .offset = SZ_4M,
+               .size   = SZ_32M - SZ_4M,
+       },
+       [3] = {
+               .name   = "user2",
+               .offset = SZ_32M,
+               .size   = MTDPART_SIZ_FULL,
+       }
+};
+
 /* the Anubis has 3 selectable slots for nand-flash, the two
  * on-board chip areas, as well as the external slot.
  *
@@ -260,6 +288,104 @@ static struct platform_device anubis_device_ide1 = {
        .resource       = anubis_ide1_resource,
 };
 
+/* Asix AX88796 10/100 ethernet controller */
+
+static struct ax_plat_data anubis_asix_platdata = {
+       .flags          = AXFLG_MAC_FROMDEV,
+       .wordlength     = 2,
+       .dcr_val        = 0x48,
+       .rcr_val        = 0x40,
+};
+
+static struct resource anubis_asix_resource[] = {
+       [0] = {
+               .start = S3C2410_CS5,
+               .end   = S3C2410_CS5 + (0x20 * 0x20) -1,
+               .flags = IORESOURCE_MEM
+       },
+       [1] = {
+               .start = IRQ_ASIX,
+               .end   = IRQ_ASIX,
+               .flags = IORESOURCE_IRQ
+       }
+};
+
+static struct platform_device anubis_device_asix = {
+       .name           = "ax88796",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(anubis_asix_resource),
+       .resource       = anubis_asix_resource,
+       .dev            = {
+               .platform_data = &anubis_asix_platdata,
+       }
+};
+
+/* SM501 */
+
+static struct resource anubis_sm501_resource[] = {
+       [0] = {
+               .start  = S3C2410_CS2,
+               .end    = S3C2410_CS2 + SZ_8M,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = S3C2410_CS2 + SZ_64M - SZ_2M,
+               .end    = S3C2410_CS2 + SZ_64M - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [2] = {
+               .start  = IRQ_EINT0,
+               .end    = IRQ_EINT0,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct sm501_initdata anubis_sm501_initdata = {
+       .gpio_high      = {
+               .set    = 0x3F000000,           /* 24bit panel */
+               .mask   = 0x0,
+       },
+       .misc_timing    = {
+               .set    = 0x010100,             /* SDRAM timing */
+               .mask   = 0x1F1F00,
+       },
+       .misc_control   = {
+               .set    = SM501_MISC_PNL_24BIT,
+               .mask   = 0,
+       },
+
+       /* set the SDRAM and bus clocks */
+       .mclk           = 72 * MHZ,
+       .m1xclk         = 144 * MHZ,
+};
+
+static struct sm501_platdata_gpio_i2c anubis_sm501_gpio_i2c[] = {
+       [0] = {
+               .pin_scl        = 44,
+               .pin_sda        = 45,
+       },
+       [1] = {
+               .pin_scl        = 40,
+               .pin_sda        = 41,
+       },
+};
+
+static struct sm501_platdata anubis_sm501_platdata = {
+       .init           = &anubis_sm501_initdata,
+       .gpio_i2c       = anubis_sm501_gpio_i2c,
+       .gpio_i2c_nr    = ARRAY_SIZE(anubis_sm501_gpio_i2c),
+};
+
+static struct platform_device anubis_device_sm501 = {
+       .name           = "sm501",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(anubis_sm501_resource),
+       .resource       = anubis_sm501_resource,
+       .dev            = {
+               .platform_data = &anubis_sm501_platdata,
+       },
+};
+
 /* Standard Anubis devices */
 
 static struct platform_device *anubis_devices[] __initdata = {
@@ -271,6 +397,8 @@ static struct platform_device *anubis_devices[] __initdata = {
        &s3c_device_nand,
        &anubis_device_ide0,
        &anubis_device_ide1,
+       &anubis_device_asix,
+       &anubis_device_sm501,
 };
 
 static struct clk *anubis_clocks[] = {
@@ -304,8 +432,17 @@ static void __init anubis_map_io(void)
        s3c24xx_init_clocks(0);
        s3c24xx_init_uarts(anubis_uartcfgs, ARRAY_SIZE(anubis_uartcfgs));
 
-       /* ensure that the GPIO is setup */
-       s3c2410_gpio_setpin(S3C2410_GPA0, 1);
+       /* check for the newer revision boards with large page nand */
+
+       if ((__raw_readb(ANUBIS_VA_IDREG) & ANUBIS_IDREG_REVMASK) >= 4) {
+               printk(KERN_INFO "ANUBIS-B detected (revision %d)\n",
+                      __raw_readb(ANUBIS_VA_IDREG) & ANUBIS_IDREG_REVMASK);
+               anubis_nand_sets[0].partitions = anubis_default_nand_part_large;
+               anubis_nand_sets[0].nr_partitions = ARRAY_SIZE(anubis_default_nand_part_large);
+       } else {
+               /* ensure that the GPIO is setup */
+               s3c2410_gpio_setpin(S3C2410_GPA0, 1);
+       }
 }
 
 static void __init anubis_init(void)
index 15811601f03db435a5cb7f54db6ee88a340876c4..89f4c9c5777b324ca4f603f4fdeb5ed6dabb2473 100644 (file)
@@ -166,6 +166,29 @@ static struct mtd_partition osiris_default_nand_part[] = {
        }
 };
 
+static struct mtd_partition osiris_default_nand_part_large[] = {
+       [0] = {
+               .name   = "Boot Agent",
+               .size   = SZ_128K,
+               .offset = 0,
+       },
+       [1] = {
+               .name   = "/boot",
+               .size   = SZ_4M - SZ_128K,
+               .offset = SZ_128K,
+       },
+       [2] = {
+               .name   = "user1",
+               .offset = SZ_4M,
+               .size   = SZ_32M - SZ_4M,
+       },
+       [3] = {
+               .name   = "user2",
+               .offset = SZ_32M,
+               .size   = MTDPART_SIZ_FULL,
+       }
+};
+
 /* the Osiris has 3 selectable slots for nand-flash, the two
  * on-board chip areas, as well as the external slot.
  *
@@ -322,14 +345,23 @@ static void __init osiris_map_io(void)
        s3c24xx_init_clocks(0);
        s3c24xx_init_uarts(osiris_uartcfgs, ARRAY_SIZE(osiris_uartcfgs));
 
+       /* check for the newer revision boards with large page nand */
+
+       if ((__raw_readb(OSIRIS_VA_IDREG) & OSIRIS_ID_REVMASK) >= 4) {
+               printk(KERN_INFO "OSIRIS-B detected (revision %d)\n",
+                      __raw_readb(OSIRIS_VA_IDREG) & OSIRIS_ID_REVMASK);
+               osiris_nand_sets[0].partitions = osiris_default_nand_part_large;
+               osiris_nand_sets[0].nr_partitions = ARRAY_SIZE(osiris_default_nand_part_large);
+       } else {
+               /* write-protect line to the NAND */
+               s3c2410_gpio_setpin(S3C2410_GPA0, 1);
+       }
+
        /* fix bus configuration (nBE settings wrong on ABLE pre v2.20) */
 
        local_irq_save(flags);
        __raw_writel(__raw_readl(S3C2410_BWSCON) | S3C2410_BWSCON_ST1 | S3C2410_BWSCON_ST2 | S3C2410_BWSCON_ST3 | S3C2410_BWSCON_ST4 | S3C2410_BWSCON_ST5, S3C2410_BWSCON);
        local_irq_restore(flags);
-
-       /* write-protect line to the NAND */
-       s3c2410_gpio_setpin(S3C2410_GPA0, 1);
 }
 
 static void __init osiris_init(void)
index 4cbf9468f654c970b226262c7e1d4a481436f9c5..3a0a1ee2542d05535c860f3d0cadb78e0a9a736d 100644 (file)
@@ -185,28 +185,21 @@ static int __devinit neponset_probe(struct platform_device *dev)
 /*
  * LDM power management.
  */
+static unsigned int neponset_saved_state;
+
 static int neponset_suspend(struct platform_device *dev, pm_message_t state)
 {
        /*
         * Save state.
         */
-       if (!dev->dev.power.saved_state)
-               dev->dev.power.saved_state = kmalloc(sizeof(unsigned int), GFP_KERNEL);
-       if (!dev->dev.power.saved_state)
-               return -ENOMEM;
-
-       *(unsigned int *)dev->dev.power.saved_state = NCR_0;
+       neponset_saved_state = NCR_0;
 
        return 0;
 }
 
 static int neponset_resume(struct platform_device *dev)
 {
-       if (dev->dev.power.saved_state) {
-               NCR_0 = *(unsigned int *)dev->dev.power.saved_state;
-               kfree(dev->dev.power.saved_state);
-               dev->dev.power.saved_state = NULL;
-       }
+       NCR_0 = neponset_saved_state;
 
        return 0;
 }
index d674cf3431567c88bdf5181ef99a7ab17c04fb36..01a37d3c0727de0c631dcbcd5e9c5378433c2946 100644 (file)
@@ -57,12 +57,7 @@ enum {       SLEEP_SAVE_SP = 0,
 static int sa11x0_pm_enter(suspend_state_t state)
 {
        unsigned long gpio, sleep_save[SLEEP_SAVE_SIZE];
-       struct timespec delta, rtc;
 
-       /* preserve current time */
-       rtc.tv_sec = RCNR;
-       rtc.tv_nsec = 0;
-       save_time_delta(&delta, &rtc);
        gpio = GPLR;
 
        /* save vital registers */
@@ -119,10 +114,6 @@ static int sa11x0_pm_enter(suspend_state_t state)
         */
        PSSR = PSSR_PH;
 
-       /* restore current time */
-       rtc.tv_sec = RCNR;
-       restore_time_delta(&delta, &rtc);
-
        return 0;
 }
 
index 29cb0c1604ab896c719c86be3b147cbf1b1a737d..fdf7b016e7adeadfa5652ae9779803209eba3d91 100644 (file)
 #define RTC_DEF_DIVIDER                (32768 - 1)
 #define RTC_DEF_TRIM            0
 
-static unsigned long __init sa1100_get_rtc_time(void)
-{
-       /*
-        * According to the manual we should be able to let RTTR be zero
-        * and then a default divisor for a 32.768KHz clock is used.
-        * Apparently this doesn't work, at least for my SA1110 rev 5.
-        * If the clock divider is uninitialized then reset it to the
-        * default value to get the 1Hz clock.
-        */
-       if (RTTR == 0) {
-               RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16);
-               printk(KERN_WARNING "Warning: uninitialized Real Time Clock\n");
-               /* The current RTC value probably doesn't make sense either */
-               RCNR = 0;
-               return 0;
-       }
-       return RCNR;
-}
-
 static int sa1100_set_rtc(void)
 {
        unsigned long current_time = xtime.tv_sec;
@@ -117,15 +98,10 @@ static struct irqaction sa1100_timer_irq = {
 
 static void __init sa1100_timer_init(void)
 {
-       struct timespec tv;
        unsigned long flags;
 
        set_rtc = sa1100_set_rtc;
 
-       tv.tv_nsec = 0;
-       tv.tv_sec = sa1100_get_rtc_time();
-       do_settimeofday(&tv);
-
        OIER = 0;               /* disable any timer interrupts */
        OSSR = 0xf;             /* clear status on all timers */
        setup_irq(IRQ_OST0, &sa1100_timer_irq);
index f3ade18862aaa8fd8e63488bc3eee36253c4e0f7..75952779ce1991f68114dcbeef6a188c4c47d027 100644 (file)
@@ -280,7 +280,10 @@ __arm_ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size,
        if (!type)
                return NULL;
 
-       size = PAGE_ALIGN(size);
+       /*
+        * Page align the mapping size, taking account of any offset.
+        */
+       size = PAGE_ALIGN(offset + size);
 
        area = get_vm_area(size, VM_IOREMAP);
        if (!area)
@@ -325,11 +328,6 @@ __arm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype)
        if (!size || last_addr < phys_addr)
                return NULL;
 
-       /*
-        * Page align the mapping size
-        */
-       size = PAGE_ALIGN(last_addr + 1) - phys_addr;
-
        return __arm_ioremap_pfn(pfn, offset, size, mtype);
 }
 EXPORT_SYMBOL(__arm_ioremap);
index d98bafcaca59a3a88b47ad3dbde222f67ae18982..017defaa525b2b8981889437824df7ae4220c246 100644 (file)
@@ -71,6 +71,7 @@ config GENERIC_CALIBRATE_DELAY
 
 config IRQCHIP_DEMUX_GPIO
        bool
+       depends on (BF53x || BF561 || BF54x)
        default y
 
 source "init/Kconfig"
@@ -114,6 +115,26 @@ config BF537
        help
          BF537 Processor Support.
 
+config BF542
+       bool "BF542"
+       help
+         BF542 Processor Support.
+
+config BF544
+       bool "BF544"
+       help
+         BF544 Processor Support.
+
+config BF548
+       bool "BF548"
+       help
+         BF548 Processor Support.
+
+config BF549
+       bool "BF549"
+       help
+         BF549 Processor Support.
+
 config BF561
        bool "BF561"
        help
@@ -125,6 +146,11 @@ choice
        prompt "Silicon Rev"
        default BF_REV_0_2 if BF537
        default BF_REV_0_3 if BF533
+       default BF_REV_0_0 if BF549
+
+config BF_REV_0_0
+       bool "0.0"
+       depends on (BF549)
 
 config BF_REV_0_2
        bool "0.2"
@@ -150,6 +176,16 @@ config BF_REV_NONE
 
 endchoice
 
+config BF53x
+       bool
+       depends on (BF531 || BF532 || BF533 || BF534 || BF536 || BF537)
+       default y
+
+config BF54x
+       bool
+       depends on (BF542 || BF544 || BF548 || BF549)
+       default y
+
 config BFIN_DUAL_CORE
        bool
        depends on (BF561)
@@ -198,6 +234,12 @@ config BFIN537_BLUETECHNIX_CM
        help
          CM-BF537 support for EVAL- and DEV-Board.
 
+config BFIN548_EZKIT
+       bool "BF548-EZKIT"
+       depends on (BF548 || BF549)
+         help
+         BFIN548-EZKIT board Support.
+
 config BFIN561_BLUETECHNIX_CM
        bool "Bluetechnix CM-BF561"
        depends on (BF561)
@@ -265,6 +307,7 @@ config BFIN_SHARED_FLASH_ENET
 source "arch/blackfin/mach-bf533/Kconfig"
 source "arch/blackfin/mach-bf561/Kconfig"
 source "arch/blackfin/mach-bf537/Kconfig"
+source "arch/blackfin/mach-bf548/Kconfig"
 
 menu "Board customizations"
 
@@ -497,7 +540,8 @@ config IP_CHECKSUM_L1
 
 config CACHELINE_ALIGNED_L1
        bool "Locate cacheline_aligned data to L1 Data Memory"
-       default y
+       default y if !BF54x
+       default n if BF54x
        depends on !BF531
        help
          If enabled cacheline_anligned data is linked
@@ -541,9 +585,17 @@ endchoice
 
 source "mm/Kconfig"
 
+config LARGE_ALLOCS
+       bool "Allow allocating large blocks (> 1MB) of memory"
+       help
+         Allow the slab memory allocator to keep chains for very large
+         memory sizes - upto 32MB. You may need this if your system has
+         a lot of RAM, and you need to able to allocate very large
+         contiguous chunks. If unsure, say N.
+
 config BFIN_DMA_5XX
        bool "Enable DMA Support"
-       depends on (BF533 || BF532 || BF531 || BF537 || BF536 || BF534 || BF561)
+       depends on (BF533 || BF532 || BF531 || BF537 || BF536 || BF534 || BF561 || BF54x)
        default y
        help
          DMA driver for BF5xx.
@@ -686,6 +738,7 @@ config C_AMCKEN
 
 config C_CDPRIO
        bool "DMA has priority over core for ext. accesses"
+       depends on !BF54x
        default n
 
 config C_B0PEN
@@ -839,7 +892,7 @@ endchoice
 
 endmenu
 
-if (BF537 || BF533)
+if (BF537 || BF533 || BF54x)
 
 menu "CPU Frequency scaling"
 
index 6971a4418dfe5886083427c07031fc1e554d5f28..1b75672dfc8f8800484463b326f623d6b8bde412 100644 (file)
@@ -24,6 +24,8 @@ machine-$(CONFIG_BF533) := bf533
 machine-$(CONFIG_BF534) := bf537
 machine-$(CONFIG_BF536) := bf537
 machine-$(CONFIG_BF537) := bf537
+machine-$(CONFIG_BF548) := bf548
+machine-$(CONFIG_BF549) := bf548
 machine-$(CONFIG_BF561) := bf561
 MACHINE := $(machine-y)
 export MACHINE
index 49e8098d4c212b7635e30e86070bc4fa151d357e..8cd33560e8179922b34f454ffddcdc8e911d24cb 100644 (file)
@@ -13,7 +13,8 @@ extra-y += vmlinux.bin vmlinux.gz
 
 quiet_cmd_uimage = UIMAGE  $@
       cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A $(ARCH) -O linux -T kernel \
-                   -C gzip -a $(CONFIG_BOOT_LOAD) -e $(CONFIG_BOOT_LOAD) -n 'Linux-$(KERNELRELEASE)' \
+                   -C gzip -n 'Linux-$(KERNELRELEASE)' -a $(CONFIG_BOOT_LOAD) \
+                   -e $(shell $(NM) vmlinux | awk '$$NF == "__start" {print $$1}') \
                    -d $< $@
 
 $(obj)/vmlinux.bin: vmlinux FORCE
diff --git a/arch/blackfin/configs/BF548-EZKIT_defconfig b/arch/blackfin/configs/BF548-EZKIT_defconfig
new file mode 100644 (file)
index 0000000..ac8390f
--- /dev/null
@@ -0,0 +1,1100 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.21.5
+#
+# CONFIG_MMU is not set
+# CONFIG_FPU is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_BLACKFIN=y
+CONFIG_ZONE_DMA=y
+CONFIG_BFIN=y
+CONFIG_SEMAPHORE_SLEEPERS=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+# CONFIG_GENERIC_TIME is not set
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_FORCE_MAX_ZONEORDER=14
+CONFIG_IRQCHIP_DEMUX_GPIO=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=3
+# CONFIG_NP2 is not set
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
+CONFIG_TINY_SHMEM=y
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+
+#
+# Blackfin Processor Options
+#
+
+#
+# Processor and Board Settings
+#
+# CONFIG_BF531 is not set
+# CONFIG_BF532 is not set
+# CONFIG_BF533 is not set
+# CONFIG_BF534 is not set
+# CONFIG_BF536 is not set
+# CONFIG_BF537 is not set
+# CONFIG_BF542 is not set
+# CONFIG_BF544 is not set
+# CONFIG_BF548 is not set
+CONFIG_BF549=y
+# CONFIG_BF561 is not set
+CONFIG_BF_REV_0_0=y
+# CONFIG_BF_REV_0_2 is not set
+# CONFIG_BF_REV_0_3 is not set
+# CONFIG_BF_REV_0_4 is not set
+# CONFIG_BF_REV_0_5 is not set
+# CONFIG_BF_REV_ANY is not set
+# CONFIG_BF_REV_NONE is not set
+CONFIG_BF54x=y
+CONFIG_BFIN_SINGLE_CORE=y
+# CONFIG_BFIN533_EZKIT is not set
+# CONFIG_BFIN533_STAMP is not set
+# CONFIG_BFIN537_STAMP is not set
+# CONFIG_BFIN533_BLUETECHNIX_CM is not set
+# CONFIG_BFIN537_BLUETECHNIX_CM is not set
+CONFIG_BFIN548_EZKIT=y
+# CONFIG_BFIN561_BLUETECHNIX_CM is not set
+# CONFIG_BFIN561_EZKIT is not set
+# CONFIG_BFIN561_TEPLA is not set
+# CONFIG_PNAV10 is not set
+# CONFIG_GENERIC_BOARD is not set
+CONFIG_IRQ_PLL_WAKEUP=7
+CONFIG_IRQ_TIMER0=11
+CONFIG_IRQ_TIMER1=11
+CONFIG_IRQ_TIMER2=11
+CONFIG_IRQ_TIMER3=11
+CONFIG_IRQ_TIMER4=11
+CONFIG_IRQ_TIMER5=11
+CONFIG_IRQ_TIMER6=11
+CONFIG_IRQ_TIMER7=11
+CONFIG_IRQ_TIMER8=11
+CONFIG_IRQ_TIMER9=11
+CONFIG_IRQ_TIMER10=11
+CONFIG_IRQ_RTC=8
+CONFIG_IRQ_SPORT0_RX=9
+CONFIG_IRQ_SPORT0_TX=9
+CONFIG_IRQ_SPORT1_RX=9
+CONFIG_IRQ_SPORT1_TX=9
+CONFIG_IRQ_UART0_RX=10
+CONFIG_IRQ_UART0_TX=10
+CONFIG_IRQ_UART1_RX=10
+CONFIG_IRQ_UART1_TX=10
+
+#
+# BF548 Specific Configuration
+#
+
+#
+# Interrupt Priority Assignment
+#
+
+#
+# Priority
+#
+CONFIG_IRQ_DMAC0_ERR=7
+CONFIG_IRQ_EPPI0_ERR=7
+CONFIG_IRQ_SPORT0_ERR=7
+CONFIG_IRQ_SPORT1_ERR=7
+CONFIG_IRQ_SPI0_ERR=7
+CONFIG_IRQ_UART0_ERR=7
+CONFIG_IRQ_EPPI0=8
+CONFIG_IRQ_SPI0=10
+CONFIG_IRQ_PINT0=12
+CONFIG_IRQ_PINT1=12
+CONFIG_IRQ_MDMAS0=13
+CONFIG_IRQ_MDMAS1=13
+CONFIG_IRQ_WATCHDOG=13
+CONFIG_IRQ_DMAC1_ERR=7
+CONFIG_IRQ_SPORT2_ERR=7
+CONFIG_IRQ_SPORT3_ERR=7
+CONFIG_IRQ_MXVR_DATA=7
+CONFIG_IRQ_SPI1_ERR=7
+CONFIG_IRQ_SPI2_ERR=7
+CONFIG_IRQ_UART1_ERR=7
+CONFIG_IRQ_UART2_ERR=7
+CONFIG_IRQ_CAN0_ERR=7
+CONFIG_IRQ_SPORT2_RX=9
+CONFIG_IRQ_SPORT2_TX=9
+CONFIG_IRQ_SPORT3_RX=9
+CONFIG_IRQ_SPORT3_TX=9
+CONFIG_IRQ_EPPI1=9
+CONFIG_IRQ_EPPI2=9
+CONFIG_IRQ_SPI1=10
+CONFIG_IRQ_SPI2=10
+CONFIG_IRQ_ATAPI_RX=10
+CONFIG_IRQ_ATAPI_TX=10
+CONFIG_IRQ_TWI0=11
+CONFIG_IRQ_TWI1=11
+CONFIG_IRQ_CAN0_RX=11
+CONFIG_IRQ_CAN0_TX=11
+CONFIG_IRQ_MDMAS2=13
+CONFIG_IRQ_MDMAS3=13
+CONFIG_IRQ_MXVR_ERR=11
+CONFIG_IRQ_MXVR_MSG=11
+CONFIG_IRQ_MXVR_PKT=11
+CONFIG_IRQ_EPPI1_ERR=7
+CONFIG_IRQ_EPPI2_ERR=7
+CONFIG_IRQ_UART3_ERR=7
+CONFIG_IRQ_HOST_ERR=7
+CONFIG_IRQ_PIXC_ERR=7
+CONFIG_IRQ_NFC_ERR=7
+CONFIG_IRQ_ATAPI_ERR=7
+CONFIG_IRQ_CAN1_ERR=7
+CONFIG_IRQ_HS_DMA_ERR=7
+CONFIG_IRQ_PIXC_IN0=8
+CONFIG_IRQ_PIXC_IN1=8
+CONFIG_IRQ_PIXC_OUT=8
+CONFIG_IRQ_SDH=8
+CONFIG_IRQ_CNT=8
+CONFIG_IRQ_KEY=8
+CONFIG_IRQ_CAN1_RX=11
+CONFIG_IRQ_CAN1_TX=11
+CONFIG_IRQ_SDH_MASK0=11
+CONFIG_IRQ_SDH_MASK1=11
+CONFIG_IRQ_USB_INT0=11
+CONFIG_IRQ_USB_INT1=11
+CONFIG_IRQ_USB_INT2=11
+CONFIG_IRQ_USB_DMA=11
+CONFIG_IRQ_OTPSEC=11
+CONFIG_IRQ_PINT2=11
+CONFIG_IRQ_PINT3=11
+
+#
+# Board customizations
+#
+# CONFIG_CMDLINE_BOOL is not set
+
+#
+# Board Setup
+#
+CONFIG_CLKIN_HZ=25000000
+CONFIG_MEM_SIZE=64
+CONFIG_MEM_ADD_WIDTH=10
+CONFIG_BOOT_LOAD=0x1000
+
+#
+# Blackfin Kernel Optimizations
+#
+
+#
+# Timer Tick
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+
+#
+# Memory Optimizations
+#
+CONFIG_I_ENTRY_L1=y
+CONFIG_EXCPT_IRQ_SYSC_L1=y
+CONFIG_DO_IRQ_L1=y
+CONFIG_CORE_TIMER_IRQ_L1=y
+CONFIG_IDLE_L1=y
+CONFIG_SCHEDULE_L1=y
+CONFIG_ARITHMETIC_OPS_L1=y
+CONFIG_ACCESS_OK_L1=y
+CONFIG_MEMSET_L1=y
+CONFIG_MEMCPY_L1=y
+CONFIG_SYS_BFIN_SPINLOCK_L1=y
+# CONFIG_IP_CHECKSUM_L1 is not set
+CONFIG_CACHELINE_ALIGNED_L1=y
+# CONFIG_SYSCALL_TAB_L1 is not set
+# CONFIG_CPLB_SWITCH_TAB_L1 is not set
+CONFIG_RAMKERNEL=y
+# CONFIG_ROMKERNEL is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_LARGE_ALLOCS=y
+CONFIG_BFIN_DMA_5XX=y
+# CONFIG_DMA_UNCACHED_2M is not set
+CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_NONE is not set
+
+#
+# Cache Support
+#
+CONFIG_BLKFIN_CACHE=y
+CONFIG_BLKFIN_DCACHE=y
+# CONFIG_BLKFIN_DCACHE_BANKA is not set
+# CONFIG_BLKFIN_CACHE_LOCK is not set
+# CONFIG_BLKFIN_WB is not set
+CONFIG_BLKFIN_WT=y
+CONFIG_L1_MAX_PIECE=16
+
+#
+# Clock Settings
+#
+# CONFIG_BFIN_KERNEL_CLOCK is not set
+
+#
+# Asynchonous Memory Configuration
+#
+
+#
+# EBIU_AMBCTL Global Control
+#
+CONFIG_C_AMCKEN=y
+CONFIG_C_CDPRIO=y
+# CONFIG_C_AMBEN is not set
+# CONFIG_C_AMBEN_B0 is not set
+# CONFIG_C_AMBEN_B0_B1 is not set
+# CONFIG_C_AMBEN_B0_B1_B2 is not set
+CONFIG_C_AMBEN_ALL=y
+
+#
+# EBIU_AMBCTL Control
+#
+CONFIG_BANK_0=0x7BB0
+CONFIG_BANK_1=0x7BB0
+CONFIG_BANK_2=0x7BB0
+CONFIG_BANK_3=0x99B3
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+# CONFIG_PCI is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF_FDPIC=y
+CONFIG_BINFMT_FLAT=y
+CONFIG_BINFMT_ZFLAT=y
+# CONFIG_BINFMT_SHARED_FLAT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+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_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 is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETLABEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+# CONFIG_MTD_CHAR is not set
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_RAM=y
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_BF5xx is not set
+CONFIG_MTD_UCLINUX=y
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# 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
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNPACPI is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# Misc devices
+#
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_SMC91X is not set
+# CONFIG_SMSC911X is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_UINPUT is not set
+# CONFIG_BF53X_PFBUTTONS is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_AD9960 is not set
+# CONFIG_SPI_ADC_BF533 is not set
+# CONFIG_BF5xx_PFLAGS is not set
+# CONFIG_BF5xx_PPIFCD is not set
+# CONFIG_BF5xx_TIMERS is not set
+# CONFIG_BF5xx_PPI is not set
+# CONFIG_BFIN_SPORT is not set
+# CONFIG_BFIN_TIMER_LATENCY is not set
+# CONFIG_BF5xx_FBDMA is not set
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_BFIN=y
+CONFIG_SERIAL_BFIN_CONSOLE=y
+# CONFIG_SERIAL_BFIN_DMA is not set
+CONFIG_SERIAL_BFIN_PIO=y
+# CONFIG_SERIAL_BFIN_UART0 is not set
+CONFIG_SERIAL_BFIN_UART1=y
+# CONFIG_BFIN_UART1_CTSRTS is not set
+# CONFIG_SERIAL_BFIN_UART2 is not set
+# CONFIG_SERIAL_BFIN_UART3 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_BFIN_SPORT is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# CAN, the car bus and industrial fieldbus
+#
+# CONFIG_CAN4LINUX is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+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
+
+#
+# RTC drivers
+#
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_TEST is not set
+# CONFIG_RTC_DRV_V3020 is not set
+CONFIG_RTC_DRV_BFIN=y
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
+# PBX support
+#
+# CONFIG_PBX is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+# CONFIG_EXT2_FS_POSIX_ACL is not set
+# CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# 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_YAFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_NFS_FS is not set
+# CONFIG_NFSD is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS 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 is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+CONFIG_FRAME_POINTER=y
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+CONFIG_DEBUG_HWERR=y
+# CONFIG_DEBUG_ICACHE_CHECK is not set
+# CONFIG_DEBUG_KERNEL_START is not set
+# CONFIG_DEBUG_SERIAL_EARLY_INIT is not set
+CONFIG_DEBUG_HUNT_FOR_ZERO=y
+# CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set
+CONFIG_CPLB_INFO=y
+CONFIG_ACCESS_CHECK=y
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+CONFIG_SECURITY=y
+# CONFIG_SECURITY_NETWORK is not set
+CONFIG_SECURITY_CAPABILITIES=y
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
index f3b7d2f9d49c38b3ba4a444d21049df0958bb43e..f429ebc3a9613ff8d263a4d46cbba4cdb01aa108 100644 (file)
@@ -6,9 +6,12 @@ extra-y := init_task.o vmlinux.lds
 
 obj-y := \
        entry.o process.o bfin_ksyms.o ptrace.o setup.o signal.o \
-       sys_bfin.o time.o traps.o irqchip.o dma-mapping.o bfin_gpio.o \
-       flat.o
+       sys_bfin.o time.o traps.o irqchip.o dma-mapping.o flat.o \
+       fixed_code.o cplbinit.o cacheinit.o
 
+obj-$(CONFIG_BF53x)                 += bfin_gpio.o
+obj-$(CONFIG_BF561)                 += bfin_gpio.o
 obj-$(CONFIG_MODULES)                += module.o
 obj-$(CONFIG_BFIN_DMA_5XX)           += bfin_dma_5xx.o
 obj-$(CONFIG_DUAL_CORE_TEST_MODULE)  += dualcore_test.o
+obj-$(CONFIG_KGDB)                   += kgdb.o
index e455f4504509518c9791163fd05d20d443434735..b56b2741cdea6746c0a445408c5d40f40786fec5 100644 (file)
 #include <linux/kernel_stat.h>
 #include <linux/ptrace.h>
 #include <linux/hardirq.h>
-#include <asm/irq.h>
-#include <asm/thread_info.h>
+#include <linux/irq.h>
+#include <linux/thread_info.h>
 
-#define DEFINE(sym, val) \
-        asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+#define DEFINE(sym, val) asm volatile("\n->" #sym " %0 " #val : : "i" (val))
 
 int main(void)
 {
index 069a896a8f260e67c7354066b6c05020811383cc..7cf02f02a1dbed0243cfda428d9768687f0ab808 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/kernel.h>
 #include <linux/param.h>
 
+#include <asm/blackfin.h>
 #include <asm/dma.h>
 #include <asm/cacheflush.h>
 
 ***************************************************************************/
 
 static struct dma_channel dma_ch[MAX_BLACKFIN_DMA_CHANNEL];
-#if defined (CONFIG_BF561)
-static struct dma_register *base_addr[MAX_BLACKFIN_DMA_CHANNEL] = {
-       (struct dma_register *) DMA1_0_NEXT_DESC_PTR,
-       (struct dma_register *) DMA1_1_NEXT_DESC_PTR,
-       (struct dma_register *) DMA1_2_NEXT_DESC_PTR,
-       (struct dma_register *) DMA1_3_NEXT_DESC_PTR,
-       (struct dma_register *) DMA1_4_NEXT_DESC_PTR,
-       (struct dma_register *) DMA1_5_NEXT_DESC_PTR,
-       (struct dma_register *) DMA1_6_NEXT_DESC_PTR,
-       (struct dma_register *) DMA1_7_NEXT_DESC_PTR,
-       (struct dma_register *) DMA1_8_NEXT_DESC_PTR,
-       (struct dma_register *) DMA1_9_NEXT_DESC_PTR,
-       (struct dma_register *) DMA1_10_NEXT_DESC_PTR,
-       (struct dma_register *) DMA1_11_NEXT_DESC_PTR,
-       (struct dma_register *) DMA2_0_NEXT_DESC_PTR,
-       (struct dma_register *) DMA2_1_NEXT_DESC_PTR,
-       (struct dma_register *) DMA2_2_NEXT_DESC_PTR,
-       (struct dma_register *) DMA2_3_NEXT_DESC_PTR,
-       (struct dma_register *) DMA2_4_NEXT_DESC_PTR,
-       (struct dma_register *) DMA2_5_NEXT_DESC_PTR,
-       (struct dma_register *) DMA2_6_NEXT_DESC_PTR,
-       (struct dma_register *) DMA2_7_NEXT_DESC_PTR,
-       (struct dma_register *) DMA2_8_NEXT_DESC_PTR,
-       (struct dma_register *) DMA2_9_NEXT_DESC_PTR,
-       (struct dma_register *) DMA2_10_NEXT_DESC_PTR,
-       (struct dma_register *) DMA2_11_NEXT_DESC_PTR,
-       (struct dma_register *) MDMA1_D0_NEXT_DESC_PTR,
-       (struct dma_register *) MDMA1_S0_NEXT_DESC_PTR,
-       (struct dma_register *) MDMA1_D1_NEXT_DESC_PTR,
-       (struct dma_register *) MDMA1_S1_NEXT_DESC_PTR,
-       (struct dma_register *) MDMA2_D0_NEXT_DESC_PTR,
-       (struct dma_register *) MDMA2_S0_NEXT_DESC_PTR,
-       (struct dma_register *) MDMA2_D1_NEXT_DESC_PTR,
-       (struct dma_register *) MDMA2_S1_NEXT_DESC_PTR,
-       (struct dma_register *) IMDMA_D0_NEXT_DESC_PTR,
-       (struct dma_register *) IMDMA_S0_NEXT_DESC_PTR,
-       (struct dma_register *) IMDMA_D1_NEXT_DESC_PTR,
-       (struct dma_register *) IMDMA_S1_NEXT_DESC_PTR,
-};
-#else
-static struct dma_register *base_addr[MAX_BLACKFIN_DMA_CHANNEL] = {
-       (struct dma_register *) DMA0_NEXT_DESC_PTR,
-       (struct dma_register *) DMA1_NEXT_DESC_PTR,
-       (struct dma_register *) DMA2_NEXT_DESC_PTR,
-       (struct dma_register *) DMA3_NEXT_DESC_PTR,
-       (struct dma_register *) DMA4_NEXT_DESC_PTR,
-       (struct dma_register *) DMA5_NEXT_DESC_PTR,
-       (struct dma_register *) DMA6_NEXT_DESC_PTR,
-       (struct dma_register *) DMA7_NEXT_DESC_PTR,
-#if (defined(CONFIG_BF537) || defined(CONFIG_BF534) || defined(CONFIG_BF536))
-       (struct dma_register *) DMA8_NEXT_DESC_PTR,
-       (struct dma_register *) DMA9_NEXT_DESC_PTR,
-       (struct dma_register *) DMA10_NEXT_DESC_PTR,
-       (struct dma_register *) DMA11_NEXT_DESC_PTR,
-#endif
-       (struct dma_register *) MDMA_D0_NEXT_DESC_PTR,
-       (struct dma_register *) MDMA_S0_NEXT_DESC_PTR,
-       (struct dma_register *) MDMA_D1_NEXT_DESC_PTR,
-       (struct dma_register *) MDMA_S1_NEXT_DESC_PTR,
-};
-#endif
 
 /*------------------------------------------------------------------------------
  *       Set the Buffer Clear bit in the Configuration register of specific DMA
@@ -138,149 +78,6 @@ static int __init blackfin_dma_init(void)
 
 arch_initcall(blackfin_dma_init);
 
-/*
- *     Form the channel find the irq number for that channel.
- */
-#if !defined(CONFIG_BF561)
-
-static int bf533_channel2irq(unsigned int channel)
-{
-       int ret_irq = -1;
-
-       switch (channel) {
-       case CH_PPI:
-               ret_irq = IRQ_PPI;
-               break;
-
-#if (defined(CONFIG_BF537) || defined(CONFIG_BF534) || defined(CONFIG_BF536))
-       case CH_EMAC_RX:
-               ret_irq = IRQ_MAC_RX;
-               break;
-
-       case CH_EMAC_TX:
-               ret_irq = IRQ_MAC_TX;
-               break;
-
-       case CH_UART1_RX:
-               ret_irq = IRQ_UART1_RX;
-               break;
-
-       case CH_UART1_TX:
-               ret_irq = IRQ_UART1_TX;
-               break;
-#endif
-
-       case CH_SPORT0_RX:
-               ret_irq = IRQ_SPORT0_RX;
-               break;
-
-       case CH_SPORT0_TX:
-               ret_irq = IRQ_SPORT0_TX;
-               break;
-
-       case CH_SPORT1_RX:
-               ret_irq = IRQ_SPORT1_RX;
-               break;
-
-       case CH_SPORT1_TX:
-               ret_irq = IRQ_SPORT1_TX;
-               break;
-
-       case CH_SPI:
-               ret_irq = IRQ_SPI;
-               break;
-
-       case CH_UART_RX:
-               ret_irq = IRQ_UART_RX;
-               break;
-
-       case CH_UART_TX:
-               ret_irq = IRQ_UART_TX;
-               break;
-
-       case CH_MEM_STREAM0_SRC:
-       case CH_MEM_STREAM0_DEST:
-               ret_irq = IRQ_MEM_DMA0;
-               break;
-
-       case CH_MEM_STREAM1_SRC:
-       case CH_MEM_STREAM1_DEST:
-               ret_irq = IRQ_MEM_DMA1;
-               break;
-       }
-       return ret_irq;
-}
-
-# define channel2irq(channel) bf533_channel2irq(channel)
-
-#else
-
-static int bf561_channel2irq(unsigned int channel)
-{
-       int ret_irq = -1;
-
-       switch (channel) {
-       case CH_PPI0:
-               ret_irq = IRQ_PPI0;
-               break;
-       case CH_PPI1:
-               ret_irq = IRQ_PPI1;
-               break;
-       case CH_SPORT0_RX:
-               ret_irq = IRQ_SPORT0_RX;
-               break;
-       case CH_SPORT0_TX:
-               ret_irq = IRQ_SPORT0_TX;
-               break;
-       case CH_SPORT1_RX:
-               ret_irq = IRQ_SPORT1_RX;
-               break;
-       case CH_SPORT1_TX:
-               ret_irq = IRQ_SPORT1_TX;
-               break;
-       case CH_SPI:
-               ret_irq = IRQ_SPI;
-               break;
-       case CH_UART_RX:
-               ret_irq = IRQ_UART_RX;
-               break;
-       case CH_UART_TX:
-               ret_irq = IRQ_UART_TX;
-               break;
-
-       case CH_MEM_STREAM0_SRC:
-       case CH_MEM_STREAM0_DEST:
-               ret_irq = IRQ_MEM_DMA0;
-               break;
-       case CH_MEM_STREAM1_SRC:
-       case CH_MEM_STREAM1_DEST:
-               ret_irq = IRQ_MEM_DMA1;
-               break;
-       case CH_MEM_STREAM2_SRC:
-       case CH_MEM_STREAM2_DEST:
-               ret_irq = IRQ_MEM_DMA2;
-               break;
-       case CH_MEM_STREAM3_SRC:
-       case CH_MEM_STREAM3_DEST:
-               ret_irq = IRQ_MEM_DMA3;
-               break;
-
-       case CH_IMEM_STREAM0_SRC:
-       case CH_IMEM_STREAM0_DEST:
-               ret_irq = IRQ_IMEM_DMA0;
-               break;
-       case CH_IMEM_STREAM1_SRC:
-       case CH_IMEM_STREAM1_DEST:
-               ret_irq = IRQ_IMEM_DMA1;
-               break;
-       }
-       return ret_irq;
-}
-
-# define channel2irq(channel) bf561_channel2irq(channel)
-
-#endif
-
 /*------------------------------------------------------------------------------
  *     Request the specific DMA channel from the system.
  *-----------------------------------------------------------------------------*/
@@ -535,7 +332,7 @@ set_bfin_dma_config(char direction, char flow_mode,
 }
 EXPORT_SYMBOL(set_bfin_dma_config);
 
-void set_dma_sg(unsigned int channel, struct dmasg * sg, int nr_sg)
+void set_dma_sg(unsigned int channel, struct dmasg *sg, int nr_sg)
 {
        BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
               && channel < MAX_BLACKFIN_DMA_CHANNEL));
@@ -604,7 +401,7 @@ static void *__dma_memcpy(void *dest, const void *src, size_t size)
 
        if (size <= 0)
                return NULL;
-       
+
        local_irq_save(flags);
 
        if ((unsigned long)src < memory_end)
@@ -748,7 +545,6 @@ void *dma_memcpy(void *dest, const void *src, size_t size)
        addr = __dma_memcpy(dest+bulk, src+bulk, rest);
        return addr;
 }
-
 EXPORT_SYMBOL(dma_memcpy);
 
 void *safe_dma_memcpy(void *dest, const void *src, size_t size)
@@ -761,14 +557,13 @@ EXPORT_SYMBOL(safe_dma_memcpy);
 
 void dma_outsb(void __iomem *addr, const void *buf, unsigned short len)
 {
-
        unsigned long flags;
-       
+
        local_irq_save(flags);
-       
-       blackfin_dcache_flush_range((unsigned int)buf,(unsigned int)(buf) + len);
 
-       bfin_write_MDMA_D0_START_ADDR(addr);
+       blackfin_dcache_flush_range((unsigned int)buf, (unsigned int)(buf) + len);
+
+       bfin_write_MDMA_D0_START_ADDR(addr);
        bfin_write_MDMA_D0_X_COUNT(len);
        bfin_write_MDMA_D0_X_MODIFY(0);
        bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
@@ -796,9 +591,9 @@ EXPORT_SYMBOL(dma_outsb);
 void dma_insb(const void __iomem *addr, void *buf, unsigned short len)
 {
        unsigned long flags;
-               
+
        local_irq_save(flags);
-       bfin_write_MDMA_D0_START_ADDR(buf);
+       bfin_write_MDMA_D0_START_ADDR(buf);
        bfin_write_MDMA_D0_X_COUNT(len);
        bfin_write_MDMA_D0_X_MODIFY(1);
        bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
@@ -827,12 +622,12 @@ EXPORT_SYMBOL(dma_insb);
 void dma_outsw(void __iomem *addr, const void  *buf, unsigned short len)
 {
        unsigned long flags;
-       
+
        local_irq_save(flags);
-               
-       blackfin_dcache_flush_range((unsigned int)buf,(unsigned int)(buf) + len);
 
-       bfin_write_MDMA_D0_START_ADDR(addr);
+       blackfin_dcache_flush_range((unsigned int)buf, (unsigned int)(buf) + len);
+
+       bfin_write_MDMA_D0_START_ADDR(addr);
        bfin_write_MDMA_D0_X_COUNT(len);
        bfin_write_MDMA_D0_X_MODIFY(0);
        bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
@@ -859,10 +654,10 @@ EXPORT_SYMBOL(dma_outsw);
 void dma_insw(const void __iomem *addr, void *buf, unsigned short len)
 {
        unsigned long flags;
-               
+
        local_irq_save(flags);
-       
-       bfin_write_MDMA_D0_START_ADDR(buf);
+
+       bfin_write_MDMA_D0_START_ADDR(buf);
        bfin_write_MDMA_D0_X_COUNT(len);
        bfin_write_MDMA_D0_X_MODIFY(2);
        bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
@@ -891,12 +686,12 @@ EXPORT_SYMBOL(dma_insw);
 void dma_outsl(void __iomem *addr, const void *buf, unsigned short len)
 {
        unsigned long flags;
-       
+
        local_irq_save(flags);
-       
-       blackfin_dcache_flush_range((unsigned int)buf,(unsigned int)(buf) + len);
 
-       bfin_write_MDMA_D0_START_ADDR(addr);
+       blackfin_dcache_flush_range((unsigned int)buf, (unsigned int)(buf) + len);
+
+       bfin_write_MDMA_D0_START_ADDR(addr);
        bfin_write_MDMA_D0_X_COUNT(len);
        bfin_write_MDMA_D0_X_MODIFY(0);
        bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
@@ -923,10 +718,10 @@ EXPORT_SYMBOL(dma_outsl);
 void dma_insl(const void __iomem *addr, void *buf, unsigned short len)
 {
        unsigned long flags;
-       
+
        local_irq_save(flags);
-       
-       bfin_write_MDMA_D0_START_ADDR(buf);
+
+       bfin_write_MDMA_D0_START_ADDR(buf);
        bfin_write_MDMA_D0_X_COUNT(len);
        bfin_write_MDMA_D0_X_MODIFY(4);
        bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
index bb1f4fb2467c119251d2b14417998500f6de4827..bafcfa52142ba0731f5caf3ecc71e672d7678285 100644 (file)
@@ -162,7 +162,7 @@ static void port_setup(unsigned short gpio, unsigned short usage)
 
 static void default_gpio(unsigned short gpio)
 {
-       unsigned short bank,bitmask;
+       unsigned short bank, bitmask;
 
        bank = gpio_bank(gpio);
        bitmask = gpio_bit(gpio);
@@ -183,7 +183,7 @@ static int __init bfin_gpio_init(void)
 
        printk(KERN_INFO "Blackfin GPIO Controller\n");
 
-       for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=GPIO_BANKSIZE)
+       for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE)
                reserved_map[gpio_bank(i)] = 0;
 
 #if defined(BF537_FAMILY) && (defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE))
@@ -478,7 +478,7 @@ u32 gpio_pm_setup(void)
        u32 sic_iwr = 0;
        u16 bank, mask, i, gpio;
 
-       for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=GPIO_BANKSIZE) {
+       for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
                mask = wakeup_map[gpio_bank(i)];
                bank = gpio_bank(i);
 
@@ -522,12 +522,11 @@ u32 gpio_pm_setup(void)
                return IWR_ENABLE_ALL;
 }
 
-
 void gpio_pm_restore(void)
 {
        u16 bank, mask, i;
 
-       for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=GPIO_BANKSIZE) {
+       for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
                mask = wakeup_map[gpio_bank(i)];
                bank = gpio_bank(i);
 
@@ -591,7 +590,6 @@ int gpio_request(unsigned short gpio, const char *label)
 }
 EXPORT_SYMBOL(gpio_request);
 
-
 void gpio_free(unsigned short gpio)
 {
        unsigned long flags;
@@ -616,7 +614,6 @@ void gpio_free(unsigned short gpio)
 }
 EXPORT_SYMBOL(gpio_free);
 
-
 void gpio_direction_input(unsigned short gpio)
 {
        unsigned long flags;
index f64ecb638fab1a8b7d9169e317b8cdc3dc5cb947..70455949cfd207f91475d100d6f8787574b37ab2 100644 (file)
  */
 
 #include <linux/module.h>
-#include <asm/irq.h>
+#include <linux/irq.h>
+#include <linux/uaccess.h>
+
 #include <asm/checksum.h>
 #include <asm/cacheflush.h>
-#include <asm/uaccess.h>
 
 /* platform dependent support */
 
diff --git a/arch/blackfin/kernel/cacheinit.c b/arch/blackfin/kernel/cacheinit.c
new file mode 100644 (file)
index 0000000..4d41a40
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ *               Copyright 2004-2007 Analog Devices Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/cpu.h>
+
+#include <asm/cacheflush.h>
+#include <asm/blackfin.h>
+#include <asm/cplbinit.h>
+
+#if defined(CONFIG_BLKFIN_CACHE)
+void bfin_icache_init(void)
+{
+       unsigned long *table = icplb_table;
+       unsigned long ctrl;
+       int i;
+
+       for (i = 0; i < MAX_CPLBS; i++) {
+               unsigned long addr = *table++;
+               unsigned long data = *table++;
+               if (addr == (unsigned long)-1)
+                       break;
+               bfin_write32(ICPLB_ADDR0 + i * 4, addr);
+               bfin_write32(ICPLB_DATA0 + i * 4, data);
+       }
+       ctrl = bfin_read_IMEM_CONTROL();
+       ctrl |= IMC | ENICPLB;
+       bfin_write_IMEM_CONTROL(ctrl);
+}
+#endif
+
+#if defined(CONFIG_BLKFIN_DCACHE)
+void bfin_dcache_init(void)
+{
+       unsigned long *table = dcplb_table;
+       unsigned long ctrl;
+       int i;
+
+       for (i = 0; i < MAX_CPLBS; i++) {
+               unsigned long addr = *table++;
+               unsigned long data = *table++;
+               if (addr == (unsigned long)-1)
+                       break;
+               bfin_write32(DCPLB_ADDR0 + i * 4, addr);
+               bfin_write32(DCPLB_DATA0 + i * 4, data);
+       }
+       ctrl = bfin_read_DMEM_CONTROL();
+       ctrl |= DMEM_CNTR;
+       bfin_write_DMEM_CONTROL(ctrl);
+}
+#endif
diff --git a/arch/blackfin/kernel/cplbinit.c b/arch/blackfin/kernel/cplbinit.c
new file mode 100644 (file)
index 0000000..bbdb403
--- /dev/null
@@ -0,0 +1,433 @@
+/*
+ * Blackfin CPLB initialization
+ *
+ *               Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <linux/module.h>
+
+#include <asm/blackfin.h>
+#include <asm/cplbinit.h>
+
+u_long icplb_table[MAX_CPLBS+1];
+u_long dcplb_table[MAX_CPLBS+1];
+
+#ifdef CONFIG_CPLB_SWITCH_TAB_L1
+u_long ipdt_table[MAX_SWITCH_I_CPLBS+1]__attribute__((l1_data));
+u_long dpdt_table[MAX_SWITCH_D_CPLBS+1]__attribute__((l1_data));
+
+#ifdef CONFIG_CPLB_INFO
+u_long ipdt_swapcount_table[MAX_SWITCH_I_CPLBS]__attribute__((l1_data));
+u_long dpdt_swapcount_table[MAX_SWITCH_D_CPLBS]__attribute__((l1_data));
+#endif /* CONFIG_CPLB_INFO */
+
+#else
+
+u_long ipdt_table[MAX_SWITCH_I_CPLBS+1];
+u_long dpdt_table[MAX_SWITCH_D_CPLBS+1];
+
+#ifdef CONFIG_CPLB_INFO
+u_long ipdt_swapcount_table[MAX_SWITCH_I_CPLBS];
+u_long dpdt_swapcount_table[MAX_SWITCH_D_CPLBS];
+#endif /* CONFIG_CPLB_INFO */
+
+#endif /*CONFIG_CPLB_SWITCH_TAB_L1*/
+
+struct s_cplb {
+       struct cplb_tab init_i;
+       struct cplb_tab init_d;
+       struct cplb_tab switch_i;
+       struct cplb_tab switch_d;
+};
+
+#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE)
+static struct cplb_desc cplb_data[] = {
+       {
+               .start = 0,
+               .end = SIZE_1K,
+               .psize = SIZE_1K,
+               .attr = INITIAL_T | SWITCH_T | I_CPLB | D_CPLB,
+               .i_conf = SDRAM_OOPS,
+               .d_conf = SDRAM_OOPS,
+#if defined(CONFIG_DEBUG_HUNT_FOR_ZERO)
+               .valid = 1,
+#else
+               .valid = 0,
+#endif
+               .name = "ZERO Pointer Saveguard",
+       },
+       {
+               .start = L1_CODE_START,
+               .end = L1_CODE_START + L1_CODE_LENGTH,
+               .psize = SIZE_4M,
+               .attr = INITIAL_T | SWITCH_T | I_CPLB,
+               .i_conf = L1_IMEMORY,
+               .d_conf = 0,
+               .valid = 1,
+               .name = "L1 I-Memory",
+       },
+       {
+               .start = L1_DATA_A_START,
+               .end = L1_DATA_B_START + L1_DATA_B_LENGTH,
+               .psize = SIZE_4M,
+               .attr = INITIAL_T | SWITCH_T | D_CPLB,
+               .i_conf = 0,
+               .d_conf = L1_DMEMORY,
+#if ((L1_DATA_A_LENGTH > 0) || (L1_DATA_B_LENGTH > 0))
+               .valid = 1,
+#else
+               .valid = 0,
+#endif
+               .name = "L1 D-Memory",
+       },
+       {
+               .start = 0,
+               .end = 0,  /* dynamic */
+               .psize = 0,
+               .attr = INITIAL_T | SWITCH_T | I_CPLB | D_CPLB,
+               .i_conf =  SDRAM_IGENERIC,
+               .d_conf =  SDRAM_DGENERIC,
+               .valid = 1,
+               .name = "SDRAM Kernel",
+       },
+       {
+               .start = 0, /* dynamic */
+               .end = 0, /* dynamic */
+               .psize = 0,
+               .attr = INITIAL_T | SWITCH_T | D_CPLB,
+               .i_conf =  SDRAM_IGENERIC,
+               .d_conf =  SDRAM_DNON_CHBL,
+               .valid = 1,
+               .name = "SDRAM RAM MTD",
+       },
+       {
+               .start = 0, /* dynamic */
+               .end = 0,   /* dynamic */
+               .psize = SIZE_1M,
+               .attr = INITIAL_T | SWITCH_T | D_CPLB,
+               .d_conf = SDRAM_DNON_CHBL,
+               .valid = 1,
+               .name = "SDRAM Uncached DMA ZONE",
+       },
+       {
+               .start = 0, /* dynamic */
+               .end = 0, /* dynamic */
+               .psize = 0,
+               .attr = SWITCH_T | D_CPLB,
+               .i_conf = 0, /* dynamic */
+               .d_conf = 0, /* dynamic */
+               .valid = 1,
+               .name = "SDRAM Reserved Memory",
+       },
+       {
+               .start = ASYNC_BANK0_BASE,
+               .end = ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE,
+               .psize = 0,
+               .attr = SWITCH_T | D_CPLB,
+               .d_conf = SDRAM_EBIU,
+               .valid = 1,
+               .name = "ASYNC Memory",
+       },
+       {
+#if defined(CONFIG_BF561)
+               .start = L2_SRAM,
+               .end = L2_SRAM_END,
+               .psize = SIZE_1M,
+               .attr = SWITCH_T | D_CPLB,
+               .i_conf = L2_MEMORY,
+               .d_conf = L2_MEMORY,
+               .valid = 1,
+#else
+               .valid = 0,
+#endif
+               .name = "L2 Memory",
+       }
+};
+
+static u16 __init lock_kernel_check(u32 start, u32 end)
+{
+       if ((start <= (u32) _stext && end >= (u32) _end)
+           || (start >= (u32) _stext && end <= (u32) _end))
+               return IN_KERNEL;
+       return 0;
+}
+
+static unsigned short __init
+fill_cplbtab(struct cplb_tab *table,
+            unsigned long start, unsigned long end,
+            unsigned long block_size, unsigned long cplb_data)
+{
+       int i;
+
+       switch (block_size) {
+       case SIZE_4M:
+               i = 3;
+               break;
+       case SIZE_1M:
+               i = 2;
+               break;
+       case SIZE_4K:
+               i = 1;
+               break;
+       case SIZE_1K:
+       default:
+               i = 0;
+               break;
+       }
+
+       cplb_data = (cplb_data & ~(3 << 16)) | (i << 16);
+
+       while ((start < end) && (table->pos < table->size)) {
+
+               table->tab[table->pos++] = start;
+
+               if (lock_kernel_check(start, start + block_size) == IN_KERNEL)
+                       table->tab[table->pos++] =
+                           cplb_data | CPLB_LOCK | CPLB_DIRTY;
+               else
+                       table->tab[table->pos++] = cplb_data;
+
+               start += block_size;
+       }
+       return 0;
+}
+
+static unsigned short __init
+close_cplbtab(struct cplb_tab *table)
+{
+
+       while (table->pos < table->size) {
+
+               table->tab[table->pos++] = 0;
+               table->tab[table->pos++] = 0; /* !CPLB_VALID */
+       }
+       return 0;
+}
+
+/* helper function */
+static void __fill_code_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_end)
+{
+       if (cplb_data[i].psize) {
+               fill_cplbtab(t,
+                               cplb_data[i].start,
+                               cplb_data[i].end,
+                               cplb_data[i].psize,
+                               cplb_data[i].i_conf);
+       } else {
+#if (defined(CONFIG_BLKFIN_CACHE) && defined(ANOMALY_05000263))
+               if (i == SDRAM_KERN) {
+                       fill_cplbtab(t,
+                                       cplb_data[i].start,
+                                       cplb_data[i].end,
+                                       SIZE_4M,
+                                       cplb_data[i].i_conf);
+               } else
+#endif
+               {
+                       fill_cplbtab(t,
+                                       cplb_data[i].start,
+                                       a_start,
+                                       SIZE_1M,
+                                       cplb_data[i].i_conf);
+                       fill_cplbtab(t,
+                                       a_start,
+                                       a_end,
+                                       SIZE_4M,
+                                       cplb_data[i].i_conf);
+                       fill_cplbtab(t, a_end,
+                                       cplb_data[i].end,
+                                       SIZE_1M,
+                                       cplb_data[i].i_conf);
+               }
+       }
+}
+
+static void __fill_data_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_end)
+{
+       if (cplb_data[i].psize) {
+               fill_cplbtab(t,
+                               cplb_data[i].start,
+                               cplb_data[i].end,
+                               cplb_data[i].psize,
+                               cplb_data[i].d_conf);
+       } else {
+               fill_cplbtab(t,
+                               cplb_data[i].start,
+                               a_start, SIZE_1M,
+                               cplb_data[i].d_conf);
+               fill_cplbtab(t, a_start,
+                               a_end, SIZE_4M,
+                               cplb_data[i].d_conf);
+               fill_cplbtab(t, a_end,
+                               cplb_data[i].end,
+                               SIZE_1M,
+                               cplb_data[i].d_conf);
+       }
+}
+
+void __init generate_cpl_tables(void)
+{
+
+       u16 i, j, process;
+       u32 a_start, a_end, as, ae, as_1m;
+
+       struct cplb_tab *t_i = NULL;
+       struct cplb_tab *t_d = NULL;
+       struct s_cplb cplb;
+
+       cplb.init_i.size = MAX_CPLBS;
+       cplb.init_d.size = MAX_CPLBS;
+       cplb.switch_i.size = MAX_SWITCH_I_CPLBS;
+       cplb.switch_d.size = MAX_SWITCH_D_CPLBS;
+
+       cplb.init_i.pos = 0;
+       cplb.init_d.pos = 0;
+       cplb.switch_i.pos = 0;
+       cplb.switch_d.pos = 0;
+
+       cplb.init_i.tab = icplb_table;
+       cplb.init_d.tab = dcplb_table;
+       cplb.switch_i.tab = ipdt_table;
+       cplb.switch_d.tab = dpdt_table;
+
+       cplb_data[SDRAM_KERN].end = memory_end;
+
+#ifdef CONFIG_MTD_UCLINUX
+       cplb_data[SDRAM_RAM_MTD].start = memory_mtd_start;
+       cplb_data[SDRAM_RAM_MTD].end = memory_mtd_start + mtd_size;
+       cplb_data[SDRAM_RAM_MTD].valid = mtd_size > 0;
+# if defined(CONFIG_ROMFS_FS)
+       cplb_data[SDRAM_RAM_MTD].attr |= I_CPLB;
+
+       /*
+        * The ROMFS_FS size is often not multiple of 1MB.
+        * This can cause multiple CPLB sets covering the same memory area.
+        * This will then cause multiple CPLB hit exceptions.
+        * Workaround: We ensure a contiguous memory area by extending the kernel
+        * memory section over the mtd section.
+        * For ROMFS_FS memory must be covered with ICPLBs anyways.
+        * So there is no difference between kernel and mtd memory setup.
+        */
+
+       cplb_data[SDRAM_KERN].end = memory_mtd_start + mtd_size;;
+       cplb_data[SDRAM_RAM_MTD].valid = 0;
+
+# endif
+#else
+       cplb_data[SDRAM_RAM_MTD].valid = 0;
+#endif
+
+       cplb_data[SDRAM_DMAZ].start = _ramend - DMA_UNCACHED_REGION;
+       cplb_data[SDRAM_DMAZ].end = _ramend;
+
+       cplb_data[RES_MEM].start = _ramend;
+       cplb_data[RES_MEM].end = physical_mem_end;
+
+       if (reserved_mem_dcache_on)
+               cplb_data[RES_MEM].d_conf = SDRAM_DGENERIC;
+       else
+               cplb_data[RES_MEM].d_conf = SDRAM_DNON_CHBL;
+
+       if (reserved_mem_icache_on)
+               cplb_data[RES_MEM].i_conf = SDRAM_IGENERIC;
+       else
+               cplb_data[RES_MEM].i_conf = SDRAM_INON_CHBL;
+
+       for (i = ZERO_P; i <= L2_MEM; i++) {
+               if (!cplb_data[i].valid)
+                       continue;
+
+               as_1m = cplb_data[i].start % SIZE_1M;
+
+               /* We need to make sure all sections are properly 1M aligned
+                * However between Kernel Memory and the Kernel mtd section, depending on the
+                * rootfs size, there can be overlapping memory areas.
+                */
+
+               if (as_1m && i != L1I_MEM && i != L1D_MEM) {
+#ifdef CONFIG_MTD_UCLINUX
+                       if (i == SDRAM_RAM_MTD) {
+                               if ((cplb_data[SDRAM_KERN].end + 1) > cplb_data[SDRAM_RAM_MTD].start)
+                                       cplb_data[SDRAM_RAM_MTD].start = (cplb_data[i].start & (-2*SIZE_1M)) + SIZE_1M;
+                               else
+                                       cplb_data[SDRAM_RAM_MTD].start = (cplb_data[i].start & (-2*SIZE_1M));
+                       } else
+#endif
+                               printk(KERN_WARNING "Unaligned Start of %s at 0x%X\n",
+                                      cplb_data[i].name, cplb_data[i].start);
+               }
+
+               as = cplb_data[i].start % SIZE_4M;
+               ae = cplb_data[i].end % SIZE_4M;
+
+               if (as)
+                       a_start = cplb_data[i].start + (SIZE_4M - (as));
+               else
+                       a_start = cplb_data[i].start;
+
+               a_end = cplb_data[i].end - ae;
+
+               for (j = INITIAL_T; j <= SWITCH_T; j++) {
+
+                       switch (j) {
+                       case INITIAL_T:
+                               if (cplb_data[i].attr & INITIAL_T) {
+                                       t_i = &cplb.init_i;
+                                       t_d = &cplb.init_d;
+                                       process = 1;
+                               } else
+                                       process = 0;
+                               break;
+                       case SWITCH_T:
+                               if (cplb_data[i].attr & SWITCH_T) {
+                                       t_i = &cplb.switch_i;
+                                       t_d = &cplb.switch_d;
+                                       process = 1;
+                               } else
+                                       process = 0;
+                               break;
+                       default:
+                                       process = 0;
+                               break;
+                       }
+
+                       if (!process)
+                               continue;
+                       if (cplb_data[i].attr & I_CPLB)
+                               __fill_code_cplbtab(t_i, i, a_start, a_end);
+
+                       if (cplb_data[i].attr & D_CPLB)
+                               __fill_data_cplbtab(t_d, i, a_start, a_end);
+               }
+       }
+
+/* close tables */
+
+       close_cplbtab(&cplb.init_i);
+       close_cplbtab(&cplb.init_d);
+
+       cplb.init_i.tab[cplb.init_i.pos] = -1;
+       cplb.init_d.tab[cplb.init_d.pos] = -1;
+       cplb.switch_i.tab[cplb.switch_i.pos] = -1;
+       cplb.switch_d.tab[cplb.switch_d.pos] = -1;
+
+}
+
+#endif
+
index 539eb24e062fbc17c3ea3e12f4b3763cb1572940..ea48d5b13f11469a18faebbd15461def98ef5d23 100644 (file)
@@ -34,8 +34,8 @@
 #include <linux/spinlock.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
+#include <linux/io.h>
 #include <asm/cacheflush.h>
-#include <asm/io.h>
 #include <asm/bfin-global.h>
 
 static spinlock_t dma_page_lock;
@@ -159,10 +159,13 @@ dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 
        BUG_ON(direction == DMA_NONE);
 
-       for (i = 0; i < nents; i++)
-               invalidate_dcache_range(sg_dma_address(&sg[i]),
-                                       sg_dma_address(&sg[i]) +
-                                       sg_dma_len(&sg[i]));
+       for (i = 0; i < nents; i++, sg++) {
+               sg->dma_address = page_address(sg->page) + sg->offset;
+
+               invalidate_dcache_range(sg_dma_address(sg),
+                                       sg_dma_address(sg) +
+                                       sg_dma_len(sg));
+       }
 
        return nents;
 }
index 8b89c99f9dfa386ff99133773147bc60425339e0..0fcba74840b7ae157ead33a94ded8219a37c165b 100644 (file)
 #include <linux/init.h>
 #include <linux/module.h>
 
-static int *testarg = (int*)0xfeb00000;
+static int *testarg = (int *)0xfeb00000;
 
 static int test_init(void)
 {
        *testarg = 1;
-       printk("Dual core test module inserted: set testarg = [%d]\n @ [%p]\n",
+       printk(KERN_INFO "Dual core test module inserted: set testarg = [%d]\n @ [%p]\n",
               *testarg, testarg);
        return 0;
 }
 
 static void test_exit(void)
 {
-       printk("Dual core test module removed: testarg = [%d]\n", *testarg);
+       printk(KERN_INFO "Dual core test module removed: testarg = [%d]\n", *testarg);
 }
 
 module_init(test_init);
diff --git a/arch/blackfin/kernel/fixed_code.S b/arch/blackfin/kernel/fixed_code.S
new file mode 100644 (file)
index 0000000..d8b1ebc
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * This file contains sequences of code that will be copied to a
+ * fixed location, defined in <asm/atomic_seq.h>.  The interrupt
+ * handlers ensure that these sequences appear to be atomic when
+ * executed from userspace.
+ * These are aligned to 16 bytes, so that we have some space to replace
+ * these sequences with something else (e.g. kernel traps if we ever do
+ * BF561 SMP).
+ */
+#include <linux/linkage.h>
+#include <linux/unistd.h>
+#include <asm/entry.h>
+
+.text
+ENTRY(_fixed_code_start)
+
+.align 16
+ENTRY(_sigreturn_stub)
+       P0 = __NR_rt_sigreturn;
+       EXCPT 0;
+       /* Speculative execution paranoia.  */
+0:     JUMP.S 0b;
+ENDPROC (_sigreturn_stub)
+
+.align 16
+       /*
+        * Atomic swap, 8 bit.
+        * Inputs:      P0: memory address to use
+        *              R1: value to store
+        * Output:      R0: old contents of the memory address, zero extended.
+        */
+ENTRY(_atomic_xchg32)
+       R0 = [P0];
+       [P0] = R1;
+       rts;
+ENDPROC (_atomic_xchg32)
+
+.align 16
+       /*
+        * Compare and swap, 32 bit.
+        * Inputs:      P0: memory address to use
+        *              R1: compare value
+        *              R2: new value to store
+        * The new value is stored if the contents of the memory
+        * address is equal to the compare value.
+        * Output:      R0: old contents of the memory address.
+        */
+ENTRY(_atomic_cas32)
+       R0 = [P0];
+       CC = R0 == R1;
+       IF !CC JUMP 1f;
+       [P0] = R2;
+1:
+       rts;
+ENDPROC (_atomic_cas32)
+
+.align 16
+       /*
+        * Atomic add, 32 bit.
+        * Inputs:      P0: memory address to use
+        *              R0: value to add
+        * Outputs:     R0: new contents of the memory address.
+        *              R1: previous contents of the memory address.
+        */
+ENTRY(_atomic_add32)
+       R1 = [P0];
+       R0 = R1 + R0;
+       [P0] = R0;
+       rts;
+ENDPROC (_atomic_add32)
+
+.align 16
+       /*
+        * Atomic sub, 32 bit.
+        * Inputs:      P0: memory address to use
+        *              R0: value to subtract
+        * Outputs:     R0: new contents of the memory address.
+        *              R1: previous contents of the memory address.
+        */
+ENTRY(_atomic_sub32)
+       R1 = [P0];
+       R0 = R1 - R0;
+       [P0] = R0;
+       rts;
+ENDPROC (_atomic_sub32)
+
+.align 16
+       /*
+        * Atomic ior, 32 bit.
+        * Inputs:      P0: memory address to use
+        *              R0: value to ior
+        * Outputs:     R0: new contents of the memory address.
+        *              R1: previous contents of the memory address.
+        */
+ENTRY(_atomic_ior32)
+       R1 = [P0];
+       R0 = R1 | R0;
+       [P0] = R0;
+       rts;
+ENDPROC (_atomic_ior32)
+
+.align 16
+       /*
+        * Atomic ior, 32 bit.
+        * Inputs:      P0: memory address to use
+        *              R0: value to ior
+        * Outputs:     R0: new contents of the memory address.
+        *              R1: previous contents of the memory address.
+        */
+ENTRY(_atomic_and32)
+       R1 = [P0];
+       R0 = R1 & R0;
+       [P0] = R0;
+       rts;
+ENDPROC (_atomic_ior32)
+
+.align 16
+       /*
+        * Atomic ior, 32 bit.
+        * Inputs:      P0: memory address to use
+        *              R0: value to ior
+        * Outputs:     R0: new contents of the memory address.
+        *              R1: previous contents of the memory address.
+        */
+ENTRY(_atomic_xor32)
+       R1 = [P0];
+       R0 = R1 ^ R0;
+       [P0] = R0;
+       rts;
+ENDPROC (_atomic_ior32)
+
+ENTRY(_fixed_code_end)
index a92587b628b570feca2940c9e882b164797db946..d188b24305364e4e348a592a2075734a8204a7e2 100644 (file)
@@ -36,24 +36,22 @@ unsigned long bfin_get_addr_from_rp(unsigned long *ptr,
        unsigned long val;
 
        switch (type) {
-               case FLAT_BFIN_RELOC_TYPE_16_BIT:
-               case FLAT_BFIN_RELOC_TYPE_16H_BIT:
-                       usptr = (unsigned short *)ptr;
-                       pr_debug("*usptr = %x", get_unaligned(usptr));
-                       val = get_unaligned(usptr);
-                       val += *persistent;
-                       break;
+       case FLAT_BFIN_RELOC_TYPE_16_BIT:
+       case FLAT_BFIN_RELOC_TYPE_16H_BIT:
+               usptr = (unsigned short *)ptr;
+               pr_debug("*usptr = %x", get_unaligned(usptr));
+               val = get_unaligned(usptr);
+               val += *persistent;
+               break;
 
-               case FLAT_BFIN_RELOC_TYPE_32_BIT:
-                       pr_debug("*ptr = %lx", get_unaligned(ptr));
-                       val = get_unaligned(ptr);
-                       break;
+       case FLAT_BFIN_RELOC_TYPE_32_BIT:
+               pr_debug("*ptr = %lx", get_unaligned(ptr));
+               val = get_unaligned(ptr);
+               break;
 
-               default:
-                       pr_debug("BINFMT_FLAT: Unknown relocation type %x\n",
-                               type);
-
-                       return 0;
+       default:
+               pr_debug("BINFMT_FLAT: Unknown relocation type %x\n", type);
+               return 0;
        }
 
        /*
@@ -81,21 +79,20 @@ void bfin_put_addr_at_rp(unsigned long *ptr, unsigned long addr,
        int type = (relval >> 26) & 7;
 
        switch (type) {
-               case FLAT_BFIN_RELOC_TYPE_16_BIT:
-                       put_unaligned(addr, usptr);
-                       pr_debug("new value %x at %p", get_unaligned(usptr),
-                               usptr);
-                       break;
+       case FLAT_BFIN_RELOC_TYPE_16_BIT:
+               put_unaligned(addr, usptr);
+               pr_debug("new value %x at %p", get_unaligned(usptr), usptr);
+               break;
 
-               case FLAT_BFIN_RELOC_TYPE_16H_BIT:
-                       put_unaligned(addr >> 16, usptr);
-                       pr_debug("new value %x", get_unaligned(usptr));
-                       break;
+       case FLAT_BFIN_RELOC_TYPE_16H_BIT:
+               put_unaligned(addr >> 16, usptr);
+               pr_debug("new value %x", get_unaligned(usptr));
+               break;
 
-               case FLAT_BFIN_RELOC_TYPE_32_BIT:
-                       put_unaligned(addr, ptr);
-                       pr_debug("new ptr =%lx", get_unaligned(ptr));
-                       break;
+       case FLAT_BFIN_RELOC_TYPE_32_BIT:
+               put_unaligned(addr, ptr);
+               pr_debug("new ptr =%lx", get_unaligned(ptr));
+               break;
        }
 }
 EXPORT_SYMBOL(bfin_put_addr_at_rp);
index 80996a1a94ca9996edb9dccde1925c398490cd8b..1fc001c7abdac10b22be68d12b89c6be3638a69f 100644 (file)
@@ -82,7 +82,7 @@ int show_interrupts(struct seq_file *p, void *v)
                        seq_printf(p, ", %s", action->name);
 
                seq_putc(p, '\n');
            unlock:
+ unlock:
                spin_unlock_irqrestore(&irq_desc[i].lock, flags);
        } else if (i == NR_IRQS) {
                seq_printf(p, "Err: %10lu\n", irq_err_count);
diff --git a/arch/blackfin/kernel/kgdb.c b/arch/blackfin/kernel/kgdb.c
new file mode 100644 (file)
index 0000000..a9c1551
--- /dev/null
@@ -0,0 +1,421 @@
+/*
+ * File:         arch/blackfin/kernel/kgdb.c
+ * Based on:
+ * Author:       Sonic Zhang
+ *
+ * Created:
+ * Description:
+ *
+ * Rev:          $Id: kgdb_bfin_linux-2.6.x.patch 4934 2007-02-13 09:32:11Z sonicz $
+ *
+ * Modified:
+ *               Copyright 2005-2006 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/ptrace.h>              /* for linux pt_regs struct */
+#include <linux/kgdb.h>
+#include <linux/console.h>
+#include <linux/init.h>
+#include <linux/debugger.h>
+#include <linux/errno.h>
+#include <linux/irq.h>
+#include <asm/system.h>
+#include <asm/traps.h>
+#include <asm/blackfin.h>
+
+/* Put the error code here just in case the user cares.  */
+int gdb_bf533errcode;
+/* Likewise, the vector number here (since GDB only gets the signal
+   number through the usual means, and that's not very specific).  */
+int gdb_bf533vector = -1;
+
+#if KGDB_MAX_NO_CPUS != 8
+#error change the definition of slavecpulocks
+#endif
+
+void regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
+{
+       gdb_regs[BFIN_R0] = regs->r0;
+       gdb_regs[BFIN_R1] = regs->r1;
+       gdb_regs[BFIN_R2] = regs->r2;
+       gdb_regs[BFIN_R3] = regs->r3;
+       gdb_regs[BFIN_R4] = regs->r4;
+       gdb_regs[BFIN_R5] = regs->r5;
+       gdb_regs[BFIN_R6] = regs->r6;
+       gdb_regs[BFIN_R7] = regs->r7;
+       gdb_regs[BFIN_P0] = regs->p0;
+       gdb_regs[BFIN_P1] = regs->p1;
+       gdb_regs[BFIN_P2] = regs->p2;
+       gdb_regs[BFIN_P3] = regs->p3;
+       gdb_regs[BFIN_P4] = regs->p4;
+       gdb_regs[BFIN_P5] = regs->p5;
+       gdb_regs[BFIN_SP] = regs->reserved;
+       gdb_regs[BFIN_FP] = regs->fp;
+       gdb_regs[BFIN_I0] = regs->i0;
+       gdb_regs[BFIN_I1] = regs->i1;
+       gdb_regs[BFIN_I2] = regs->i2;
+       gdb_regs[BFIN_I3] = regs->i3;
+       gdb_regs[BFIN_M0] = regs->m0;
+       gdb_regs[BFIN_M1] = regs->m1;
+       gdb_regs[BFIN_M2] = regs->m2;
+       gdb_regs[BFIN_M3] = regs->m3;
+       gdb_regs[BFIN_B0] = regs->b0;
+       gdb_regs[BFIN_B1] = regs->b1;
+       gdb_regs[BFIN_B2] = regs->b2;
+       gdb_regs[BFIN_B3] = regs->b3;
+       gdb_regs[BFIN_L0] = regs->l0;
+       gdb_regs[BFIN_L1] = regs->l1;
+       gdb_regs[BFIN_L2] = regs->l2;
+       gdb_regs[BFIN_L3] = regs->l3;
+       gdb_regs[BFIN_A0_DOT_X] = regs->a0x;
+       gdb_regs[BFIN_A0_DOT_W] = regs->a0w;
+       gdb_regs[BFIN_A1_DOT_X] = regs->a1x;
+       gdb_regs[BFIN_A1_DOT_W] = regs->a1w;
+       gdb_regs[BFIN_ASTAT] = regs->astat;
+       gdb_regs[BFIN_RETS] = regs->rets;
+       gdb_regs[BFIN_LC0] = regs->lc0;
+       gdb_regs[BFIN_LT0] = regs->lt0;
+       gdb_regs[BFIN_LB0] = regs->lb0;
+       gdb_regs[BFIN_LC1] = regs->lc1;
+       gdb_regs[BFIN_LT1] = regs->lt1;
+       gdb_regs[BFIN_LB1] = regs->lb1;
+       gdb_regs[BFIN_CYCLES] = 0;
+       gdb_regs[BFIN_CYCLES2] = 0;
+       gdb_regs[BFIN_USP] = regs->usp;
+       gdb_regs[BFIN_SEQSTAT] = regs->seqstat;
+       gdb_regs[BFIN_SYSCFG] = regs->syscfg;
+       gdb_regs[BFIN_RETI] = regs->pc;
+       gdb_regs[BFIN_RETX] = regs->retx;
+       gdb_regs[BFIN_RETN] = regs->retn;
+       gdb_regs[BFIN_RETE] = regs->rete;
+       gdb_regs[BFIN_PC] = regs->pc;
+       gdb_regs[BFIN_CC] = 0;
+       gdb_regs[BFIN_EXTRA1] = 0;
+       gdb_regs[BFIN_EXTRA2] = 0;
+       gdb_regs[BFIN_EXTRA3] = 0;
+       gdb_regs[BFIN_IPEND] = regs->ipend;
+}
+
+/*
+ * Extracts ebp, esp and eip values understandable by gdb from the values
+ * saved by switch_to.
+ * thread.esp points to ebp. flags and ebp are pushed in switch_to hence esp
+ * prior to entering switch_to is 8 greater then the value that is saved.
+ * If switch_to changes, change following code appropriately.
+ */
+void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
+{
+       gdb_regs[BFIN_SP] = p->thread.ksp;
+       gdb_regs[BFIN_PC] = p->thread.pc;
+       gdb_regs[BFIN_SEQSTAT] = p->thread.seqstat;
+}
+
+void gdb_regs_to_regs(unsigned long *gdb_regs, struct pt_regs *regs)
+{
+       regs->r0 = gdb_regs[BFIN_R0];
+       regs->r1 = gdb_regs[BFIN_R1];
+       regs->r2 = gdb_regs[BFIN_R2];
+       regs->r3 = gdb_regs[BFIN_R3];
+       regs->r4 = gdb_regs[BFIN_R4];
+       regs->r5 = gdb_regs[BFIN_R5];
+       regs->r6 = gdb_regs[BFIN_R6];
+       regs->r7 = gdb_regs[BFIN_R7];
+       regs->p0 = gdb_regs[BFIN_P0];
+       regs->p1 = gdb_regs[BFIN_P1];
+       regs->p2 = gdb_regs[BFIN_P2];
+       regs->p3 = gdb_regs[BFIN_P3];
+       regs->p4 = gdb_regs[BFIN_P4];
+       regs->p5 = gdb_regs[BFIN_P5];
+       regs->fp = gdb_regs[BFIN_FP];
+       regs->i0 = gdb_regs[BFIN_I0];
+       regs->i1 = gdb_regs[BFIN_I1];
+       regs->i2 = gdb_regs[BFIN_I2];
+       regs->i3 = gdb_regs[BFIN_I3];
+       regs->m0 = gdb_regs[BFIN_M0];
+       regs->m1 = gdb_regs[BFIN_M1];
+       regs->m2 = gdb_regs[BFIN_M2];
+       regs->m3 = gdb_regs[BFIN_M3];
+       regs->b0 = gdb_regs[BFIN_B0];
+       regs->b1 = gdb_regs[BFIN_B1];
+       regs->b2 = gdb_regs[BFIN_B2];
+       regs->b3 = gdb_regs[BFIN_B3];
+       regs->l0 = gdb_regs[BFIN_L0];
+       regs->l1 = gdb_regs[BFIN_L1];
+       regs->l2 = gdb_regs[BFIN_L2];
+       regs->l3 = gdb_regs[BFIN_L3];
+       regs->a0x = gdb_regs[BFIN_A0_DOT_X];
+       regs->a0w = gdb_regs[BFIN_A0_DOT_W];
+       regs->a1x = gdb_regs[BFIN_A1_DOT_X];
+       regs->a1w = gdb_regs[BFIN_A1_DOT_W];
+       regs->rets = gdb_regs[BFIN_RETS];
+       regs->lc0 = gdb_regs[BFIN_LC0];
+       regs->lt0 = gdb_regs[BFIN_LT0];
+       regs->lb0 = gdb_regs[BFIN_LB0];
+       regs->lc1 = gdb_regs[BFIN_LC1];
+       regs->lt1 = gdb_regs[BFIN_LT1];
+       regs->lb1 = gdb_regs[BFIN_LB1];
+       regs->usp = gdb_regs[BFIN_USP];
+       regs->syscfg = gdb_regs[BFIN_SYSCFG];
+       regs->retx = gdb_regs[BFIN_PC];
+       regs->retn = gdb_regs[BFIN_RETN];
+       regs->rete = gdb_regs[BFIN_RETE];
+       regs->pc = gdb_regs[BFIN_PC];
+
+#if 0                          /* can't change these */
+       regs->astat = gdb_regs[BFIN_ASTAT];
+       regs->seqstat = gdb_regs[BFIN_SEQSTAT];
+       regs->ipend = gdb_regs[BFIN_IPEND];
+#endif
+}
+
+struct hw_breakpoint {
+       unsigned int occupied:1;
+       unsigned int skip:1;
+       unsigned int enabled:1;
+       unsigned int type:1;
+       unsigned int dataacc:2;
+       unsigned short count;
+       unsigned int addr;
+} breakinfo[HW_BREAKPOINT_NUM];
+
+int kgdb_arch_init(void)
+{
+       kgdb_remove_all_hw_break();
+       return 0;
+}
+
+int kgdb_set_hw_break(unsigned long addr)
+{
+       int breakno;
+       for (breakno = 0; breakno < HW_BREAKPOINT_NUM; breakno++)
+               if (!breakinfo[breakno].occupied) {
+                       breakinfo[breakno].occupied = 1;
+                       breakinfo[breakno].enabled = 1;
+                       breakinfo[breakno].type = 1;
+                       breakinfo[breakno].addr = addr;
+                       return 0;
+               }
+
+       return -ENOSPC;
+}
+
+int kgdb_remove_hw_break(unsigned long addr)
+{
+       int breakno;
+       for (breakno = 0; breakno < HW_BREAKPOINT_NUM; breakno++)
+               if (breakinfo[breakno].addr == addr)
+                       memset(&(breakinfo[breakno]), 0, sizeof(struct hw_breakpoint));
+
+       return 0;
+}
+
+void kgdb_remove_all_hw_break(void)
+{
+       memset(breakinfo, 0, sizeof(struct hw_breakpoint)*8);
+}
+
+/*
+void kgdb_show_info(void)
+{
+       printk(KERN_DEBUG "hwd: wpia0=0x%x, wpiacnt0=%d, wpiactl=0x%x, wpstat=0x%x\n",
+               bfin_read_WPIA0(), bfin_read_WPIACNT0(),
+               bfin_read_WPIACTL(), bfin_read_WPSTAT());
+}
+*/
+
+void kgdb_correct_hw_break(void)
+{
+       int breakno;
+       int correctit;
+       uint32_t wpdactl = bfin_read_WPDACTL();
+
+       correctit = 0;
+       for (breakno = 0; breakno < HW_BREAKPOINT_NUM; breakno++) {
+               if (breakinfo[breakno].type == 1) {
+                       switch (breakno) {
+                       case 0:
+                               if (breakinfo[breakno].enabled && !(wpdactl & WPIAEN0)) {
+                                       correctit = 1;
+                                       wpdactl &= ~(WPIREN01|EMUSW0);
+                                       wpdactl |= WPIAEN0|WPICNTEN0;
+                                       bfin_write_WPIA0(breakinfo[breakno].addr);
+                                       bfin_write_WPIACNT0(breakinfo[breakno].skip);
+                               } else if (!breakinfo[breakno].enabled && (wpdactl & WPIAEN0)) {
+                                       correctit = 1;
+                                       wpdactl &= ~WPIAEN0;
+                               }
+                               break;
+
+                       case 1:
+                               if (breakinfo[breakno].enabled && !(wpdactl & WPIAEN1)) {
+                                       correctit = 1;
+                                       wpdactl &= ~(WPIREN01|EMUSW1);
+                                       wpdactl |= WPIAEN1|WPICNTEN1;
+                                       bfin_write_WPIA1(breakinfo[breakno].addr);
+                                       bfin_write_WPIACNT1(breakinfo[breakno].skip);
+                               } else if (!breakinfo[breakno].enabled && (wpdactl & WPIAEN1)) {
+                                       correctit = 1;
+                                       wpdactl &= ~WPIAEN1;
+                               }
+                               break;
+
+                       case 2:
+                               if (breakinfo[breakno].enabled && !(wpdactl & WPIAEN2)) {
+                                       correctit = 1;
+                                       wpdactl &= ~(WPIREN23|EMUSW2);
+                                       wpdactl |= WPIAEN2|WPICNTEN2;
+                                       bfin_write_WPIA2(breakinfo[breakno].addr);
+                                       bfin_write_WPIACNT2(breakinfo[breakno].skip);
+                               } else if (!breakinfo[breakno].enabled && (wpdactl & WPIAEN2)) {
+                                       correctit = 1;
+                                       wpdactl &= ~WPIAEN2;
+                               }
+                               break;
+
+                       case 3:
+                               if (breakinfo[breakno].enabled && !(wpdactl & WPIAEN3)) {
+                                       correctit = 1;
+                                       wpdactl &= ~(WPIREN23|EMUSW3);
+                                       wpdactl |= WPIAEN3|WPICNTEN3;
+                                       bfin_write_WPIA3(breakinfo[breakno].addr);
+                                       bfin_write_WPIACNT3(breakinfo[breakno].skip);
+                               } else if (!breakinfo[breakno].enabled && (wpdactl & WPIAEN3)) {
+                                       correctit = 1;
+                                       wpdactl &= ~WPIAEN3;
+                               }
+                               break;
+                       case 4:
+                               if (breakinfo[breakno].enabled && !(wpdactl & WPIAEN4)) {
+                                       correctit = 1;
+                                       wpdactl &= ~(WPIREN45|EMUSW4);
+                                       wpdactl |= WPIAEN4|WPICNTEN4;
+                                       bfin_write_WPIA4(breakinfo[breakno].addr);
+                                       bfin_write_WPIACNT4(breakinfo[breakno].skip);
+                               } else if (!breakinfo[breakno].enabled && (wpdactl & WPIAEN4)) {
+                                       correctit = 1;
+                                       wpdactl &= ~WPIAEN4;
+                               }
+                               break;
+                       case 5:
+                               if (breakinfo[breakno].enabled && !(wpdactl & WPIAEN5)) {
+                                       correctit = 1;
+                                       wpdactl &= ~(WPIREN45|EMUSW5);
+                                       wpdactl |= WPIAEN5|WPICNTEN5;
+                                       bfin_write_WPIA5(breakinfo[breakno].addr);
+                                       bfin_write_WPIACNT5(breakinfo[breakno].skip);
+                               } else if (!breakinfo[breakno].enabled && (wpdactl & WPIAEN5)) {
+                                       correctit = 1;
+                                       wpdactl &= ~WPIAEN5;
+                               }
+                               break;
+                       }
+               }
+       }
+       if (correctit) {
+               wpdactl &= ~WPAND;
+               wpdactl |= WPPWR;
+               /*printk("correct_hw_break: wpdactl=0x%x\n", wpdactl);*/
+               bfin_write_WPDACTL(wpdactl);
+               CSYNC();
+               /*kgdb_show_info();*/
+       }
+}
+
+void kgdb_disable_hw_debug(struct pt_regs *regs)
+{
+       /* Disable hardware debugging while we are in kgdb */
+       bfin_write_WPIACTL(bfin_read_WPIACTL() & ~0x1);
+       CSYNC();
+}
+
+void kgdb_post_master_code(struct pt_regs *regs, int eVector, int err_code)
+{
+       /* Master processor is completely in the debugger */
+       gdb_bf533vector = eVector;
+       gdb_bf533errcode = err_code;
+}
+
+int kgdb_arch_handle_exception(int exceptionVector, int signo,
+                              int err_code, char *remcom_in_buffer,
+                              char *remcom_out_buffer,
+                              struct pt_regs *linux_regs)
+{
+       long addr;
+       long breakno;
+       char *ptr;
+       int newPC;
+       int wp_status;
+
+       switch (remcom_in_buffer[0]) {
+       case 'c':
+       case 's':
+               if (kgdb_contthread && kgdb_contthread != current) {
+                       strcpy(remcom_out_buffer, "E00");
+                       break;
+               }
+
+               kgdb_contthread = NULL;
+
+               /* try to read optional parameter, pc unchanged if no parm */
+               ptr = &remcom_in_buffer[1];
+               if (kgdb_hex2long(&ptr, &addr)) {
+                       linux_regs->retx = addr;
+               }
+               newPC = linux_regs->retx;
+
+               /* clear the trace bit */
+               linux_regs->syscfg &= 0xfffffffe;
+
+               /* set the trace bit if we're stepping */
+               if (remcom_in_buffer[0] == 's') {
+                       linux_regs->syscfg |= 0x1;
+                       debugger_step = 1;
+               }
+
+               wp_status = bfin_read_WPSTAT();
+               CSYNC();
+
+               if (exceptionVector == VEC_WATCH) {
+                       for (breakno = 0; breakno < 6; ++breakno) {
+                               if (wp_status & (1 << breakno)) {
+                                       breakinfo->skip = 1;
+                                       break;
+                               }
+                       }
+               }
+               kgdb_correct_hw_break();
+
+               bfin_write_WPSTAT(0);
+
+               return 0;
+       }                       /* switch */
+       return -1;              /* this means that we do not want to exit from the handler */
+}
+
+struct kgdb_arch arch_kgdb_ops = {
+       .gdb_bpt_instr = {0xa1},
+       .flags = KGDB_HW_BREAKPOINT,
+};
index 372f756f1ad9cf4d0d717af332b988ecd51e294d..8b9fe29d03f4f4a02c91f3a2585b703bfa7b3bc9 100644 (file)
@@ -165,8 +165,8 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs,
 
        for (s = sechdrs; s < sechdrs_end; ++s) {
                if ((strcmp(".l1.text", secstrings + s->sh_name) == 0) ||
-                       ((strcmp(".text", secstrings + s->sh_name)==0) &&
-                        (hdr->e_flags & FLG_CODE_IN_L1) && (s->sh_size > 0))) {
+                   ((strcmp(".text", secstrings + s->sh_name) == 0) &&
+                    (hdr->e_flags & FLG_CODE_IN_L1) && (s->sh_size > 0))) {
                        mod->arch.text_l1 = s;
                        dest = l1_inst_sram_alloc(s->sh_size);
                        if (dest == NULL) {
@@ -179,9 +179,9 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs,
                        s->sh_flags &= ~SHF_ALLOC;
                        s->sh_addr = (unsigned long)dest;
                }
-               if ((strcmp(".l1.data", secstrings + s->sh_name) == 0)||
-                       ((strcmp(".data", secstrings + s->sh_name)==0) &&
-                        (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) {
+               if ((strcmp(".l1.data", secstrings + s->sh_name) == 0) ||
+                   ((strcmp(".data", secstrings + s->sh_name) == 0) &&
+                    (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) {
                        mod->arch.data_a_l1 = s;
                        dest = l1_data_sram_alloc(s->sh_size);
                        if (dest == NULL) {
@@ -195,8 +195,8 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs,
                        s->sh_addr = (unsigned long)dest;
                }
                if (strcmp(".l1.bss", secstrings + s->sh_name) == 0 ||
-                       ((strcmp(".bss", secstrings + s->sh_name)==0) &&
-                        (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) {
+                   ((strcmp(".bss", secstrings + s->sh_name) == 0) &&
+                    (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) {
                        mod->arch.bss_a_l1 = s;
                        dest = l1_data_sram_alloc(s->sh_size);
                        if (dest == NULL) {
@@ -326,7 +326,7 @@ apply_relocate_add(Elf_Shdr * sechdrs, const char *strtab,
                        pr_debug("before %x after %x\n", *location16,
                                       (value & 0xffff));
                        tmp = (value & 0xffff);
-                       if((unsigned long)location16 >= L1_CODE_START) {
+                       if ((unsigned long)location16 >= L1_CODE_START) {
                                dma_memcpy(location16, &tmp, 2);
                        } else
                                *location16 = tmp;
@@ -335,7 +335,7 @@ apply_relocate_add(Elf_Shdr * sechdrs, const char *strtab,
                        pr_debug("before %x after %x\n", *location16,
                                       ((value >> 16) & 0xffff));
                        tmp = ((value >> 16) & 0xffff);
-                       if((unsigned long)location16 >= L1_CODE_START) {
+                       if ((unsigned long)location16 >= L1_CODE_START) {
                                dma_memcpy(location16, &tmp, 2);
                        } else
                                *location16 = tmp;
@@ -404,8 +404,8 @@ module_finalize(const Elf_Ehdr * hdr,
                        continue;
 
                if ((sechdrs[i].sh_type == SHT_RELA) &&
-                   ((strcmp(".rela.l1.text", secstrings + sechdrs[i].sh_name) == 0)||
-                       ((strcmp(".rela.text", secstrings + sechdrs[i].sh_name) == 0) &&
+                   ((strcmp(".rela.l1.text", secstrings + sechdrs[i].sh_name) == 0) ||
+                   ((strcmp(".rela.text", secstrings + sechdrs[i].sh_name) == 0) &&
                         (hdr->e_flags & FLG_CODE_IN_L1)))) {
                        apply_relocate_add((Elf_Shdr *) sechdrs, strtab,
                                           symindex, i, mod);
@@ -417,13 +417,13 @@ module_finalize(const Elf_Ehdr * hdr,
 void module_arch_cleanup(struct module *mod)
 {
        if ((mod->arch.text_l1) && (mod->arch.text_l1->sh_addr))
-               l1_inst_sram_free((void*)mod->arch.text_l1->sh_addr);
+               l1_inst_sram_free((void *)mod->arch.text_l1->sh_addr);
        if ((mod->arch.data_a_l1) && (mod->arch.data_a_l1->sh_addr))
-               l1_data_sram_free((void*)mod->arch.data_a_l1->sh_addr);
+               l1_data_sram_free((void *)mod->arch.data_a_l1->sh_addr);
        if ((mod->arch.bss_a_l1) && (mod->arch.bss_a_l1->sh_addr))
-               l1_data_sram_free((void*)mod->arch.bss_a_l1->sh_addr);
+               l1_data_sram_free((void *)mod->arch.bss_a_l1->sh_addr);
        if ((mod->arch.data_b_l1) && (mod->arch.data_b_l1->sh_addr))
-               l1_data_B_sram_free((void*)mod->arch.data_b_l1->sh_addr);
+               l1_data_B_sram_free((void *)mod->arch.data_b_l1->sh_addr);
        if ((mod->arch.bss_b_l1) && (mod->arch.bss_b_l1->sh_addr))
-               l1_data_B_sram_free((void*)mod->arch.bss_b_l1->sh_addr);
+               l1_data_B_sram_free((void *)mod->arch.bss_b_l1->sh_addr);
 }
index 3eff7439d8d3f0e3a5bd542a307491f85a96a287..5a51dd6ab28095966fac101dc229fb600934765f 100644 (file)
 #include <linux/unistd.h>
 #include <linux/user.h>
 #include <linux/a.out.h>
+#include <linux/uaccess.h>
 
 #include <asm/blackfin.h>
-#include <asm/uaccess.h>
+#include <asm/fixed_code.h>
 
 #define        LED_ON  0
 #define        LED_OFF 1
@@ -173,8 +174,8 @@ void show_regs(struct pt_regs *regs)
        printk(KERN_NOTICE "R4: %08lx  R5: %08lx  R6: %08lx  R7: %08lx\n",
               regs->r4, regs->r5, regs->r6, regs->r7);
 
-       if (!(regs->ipend))
-               printk("USP: %08lx\n", rdusp());
+       if (!regs->ipend)
+               printk(KERN_NOTICE "USP: %08lx\n", rdusp());
 }
 
 /* Fill in the fpu structure for a core dump.  */
@@ -322,7 +323,7 @@ asmlinkage int sys_execve(char *name, char **argv, char **envp)
                goto out;
        error = do_execve(filename, argv, envp, regs);
        putname(filename);
     out:
+ out:
        unlock_kernel();
        return error;
 }
@@ -350,13 +351,77 @@ unsigned long get_wchan(struct task_struct *p)
        return 0;
 }
 
+void finish_atomic_sections (struct pt_regs *regs)
+{
+       if (regs->pc < ATOMIC_SEQS_START || regs->pc >= ATOMIC_SEQS_END)
+               return;
+
+       switch (regs->pc) {
+       case ATOMIC_XCHG32 + 2:
+               put_user(regs->r1, (int *)regs->p0);
+               regs->pc += 2;
+               break;
+
+       case ATOMIC_CAS32 + 2:
+       case ATOMIC_CAS32 + 4:
+               if (regs->r0 == regs->r1)
+                       put_user(regs->r2, (int *)regs->p0);
+               regs->pc = ATOMIC_CAS32 + 8;
+               break;
+       case ATOMIC_CAS32 + 6:
+               put_user(regs->r2, (int *)regs->p0);
+               regs->pc += 2;
+               break;
+
+       case ATOMIC_ADD32 + 2:
+               regs->r0 = regs->r1 + regs->r0;
+               /* fall through */
+       case ATOMIC_ADD32 + 4:
+               put_user(regs->r0, (int *)regs->p0);
+               regs->pc = ATOMIC_ADD32 + 6;
+               break;
+
+       case ATOMIC_SUB32 + 2:
+               regs->r0 = regs->r1 - regs->r0;
+               /* fall through */
+       case ATOMIC_SUB32 + 4:
+               put_user(regs->r0, (int *)regs->p0);
+               regs->pc = ATOMIC_SUB32 + 6;
+               break;
+
+       case ATOMIC_IOR32 + 2:
+               regs->r0 = regs->r1 | regs->r0;
+               /* fall through */
+       case ATOMIC_IOR32 + 4:
+               put_user(regs->r0, (int *)regs->p0);
+               regs->pc = ATOMIC_IOR32 + 6;
+               break;
+
+       case ATOMIC_AND32 + 2:
+               regs->r0 = regs->r1 & regs->r0;
+               /* fall through */
+       case ATOMIC_AND32 + 4:
+               put_user(regs->r0, (int *)regs->p0);
+               regs->pc = ATOMIC_AND32 + 6;
+               break;
+
+       case ATOMIC_XOR32 + 2:
+               regs->r0 = regs->r1 ^ regs->r0;
+               /* fall through */
+       case ATOMIC_XOR32 + 4:
+               put_user(regs->r0, (int *)regs->p0);
+               regs->pc = ATOMIC_XOR32 + 6;
+               break;
+       }
+}
+
 #if defined(CONFIG_ACCESS_CHECK)
 int _access_ok(unsigned long addr, unsigned long size)
 {
 
        if (addr > (addr + size))
                return 0;
-       if (segment_eq(get_fs(),KERNEL_DS))
+       if (segment_eq(get_fs(), KERNEL_DS))
                return 1;
 #ifdef CONFIG_MTD_UCLINUX
        if (addr >= memory_start && (addr + size) <= memory_end)
index e718bb4a1ef027fdc050f51d4303cbe11a8905d0..ed800c7456dd004a9863e2643a8a4aac720d2c9b 100644 (file)
@@ -36,8 +36,8 @@
 #include <linux/ptrace.h>
 #include <linux/user.h>
 #include <linux/signal.h>
+#include <linux/uaccess.h>
 
-#include <asm/uaccess.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
@@ -122,7 +122,7 @@ static inline long get_reg(struct task_struct *task, int regno)
 static inline int
 put_reg(struct task_struct *task, int regno, unsigned long data)
 {
-       char * reg_ptr;
+       char *reg_ptr;
 
        struct pt_regs *regs =
            (struct pt_regs *)((unsigned long)task_stack_page(task) +
@@ -146,7 +146,7 @@ put_reg(struct task_struct *task, int regno, unsigned long data)
                break;
        default:
                if (regno <= 216)
-                       *(long *)(reg_ptr + regno) = data;
+                       *(long *)(reg_ptr + regno) = data;
        }
        return 0;
 }
index 83060f98d15d265cfcfbc50f657743f7e99255c4..f59dcee7bae3da76723a3432866fa08d8b7d9f0a 100644 (file)
@@ -42,6 +42,7 @@
 #include <asm/cacheflush.h>
 #include <asm/blackfin.h>
 #include <asm/cplbinit.h>
+#include <asm/fixed_code.h>
 
 u16 _bfin_swrst;
 
@@ -63,10 +64,6 @@ EXPORT_SYMBOL(mtd_size);
 
 char __initdata command_line[COMMAND_LINE_SIZE];
 
-#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE)
-static void generate_cpl_tables(void);
-#endif
-
 void __init bf53x_cache_init(void)
 {
 #if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE)
@@ -197,6 +194,17 @@ void __init setup_arch(char **cmdline_p)
        /* this give a chance to get printk() working before crash. */
 #endif
 
+       printk(KERN_INFO "Hardware Trace ");
+       if (bfin_read_TBUFCTL() & 0x1 )
+               printk("Active ");
+       else
+               printk("Off ");
+       if (bfin_read_TBUFCTL() & 0x2)
+               printk("and Enabled\n");
+       else
+       printk("and Disabled\n");
+
+
 #if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH)
        /* we need to initialize the Flashrom device here since we might
         * do things with flash early on in the boot
@@ -354,15 +362,15 @@ void __init setup_arch(char **cmdline_p)
               , _stext, _etext,
               __start_rodata, __end_rodata,
               _sdata, _edata,
-              (void*)&init_thread_union, (void*)((int)(&init_thread_union) + 0x2000),
+              (void *)&init_thread_union, (void *)((int)(&init_thread_union) + 0x2000),
               __init_begin, __init_end,
               __bss_start, __bss_stop,
-              (void*)_ramstart, (void*)memory_end
+              (void *)_ramstart, (void *)memory_end
 #ifdef CONFIG_MTD_UCLINUX
-              , (void*)memory_mtd_start, (void*)(memory_mtd_start + mtd_size)
+              , (void *)memory_mtd_start, (void *)(memory_mtd_start + mtd_size)
 #endif
 #if DMA_UNCACHED_REGION > 0
-              , (void*)(_ramend - DMA_UNCACHED_REGION), (void*)(_ramend)
+              , (void *)(_ramend - DMA_UNCACHED_REGION), (void *)(_ramend)
 #endif
               );
 
@@ -388,11 +396,11 @@ void __init setup_arch(char **cmdline_p)
        /* check the size of the l1 area */
        l1_length = _etext_l1 - _stext_l1;
        if (l1_length > L1_CODE_LENGTH)
-               panic("L1 memory overflow\n");
+               panic("L1 code memory overflow\n");
 
        l1_length = _ebss_l1 - _sdata_l1;
        if (l1_length > L1_DATA_A_LENGTH)
-               panic("L1 memory overflow\n");
+               panic("L1 data memory overflow\n");
 
 #ifdef BF561_FAMILY
        _bfin_swrst = bfin_read_SICA_SWRST();
@@ -400,10 +408,28 @@ void __init setup_arch(char **cmdline_p)
        _bfin_swrst = bfin_read_SWRST();
 #endif
 
-       bf53x_cache_init();
+       /* Copy atomic sequences to their fixed location, and sanity check that
+          these locations are the ones that we advertise to userspace.  */
+       memcpy((void *)FIXED_CODE_START, &fixed_code_start,
+              FIXED_CODE_END - FIXED_CODE_START);
+       BUG_ON((char *)&sigreturn_stub - (char *)&fixed_code_start
+              != SIGRETURN_STUB - FIXED_CODE_START);
+       BUG_ON((char *)&atomic_xchg32 - (char *)&fixed_code_start
+              != ATOMIC_XCHG32 - FIXED_CODE_START);
+       BUG_ON((char *)&atomic_cas32 - (char *)&fixed_code_start
+              != ATOMIC_CAS32 - FIXED_CODE_START);
+       BUG_ON((char *)&atomic_add32 - (char *)&fixed_code_start
+              != ATOMIC_ADD32 - FIXED_CODE_START);
+       BUG_ON((char *)&atomic_sub32 - (char *)&fixed_code_start
+              != ATOMIC_SUB32 - FIXED_CODE_START);
+       BUG_ON((char *)&atomic_ior32 - (char *)&fixed_code_start
+              != ATOMIC_IOR32 - FIXED_CODE_START);
+       BUG_ON((char *)&atomic_and32 - (char *)&fixed_code_start
+              != ATOMIC_AND32 - FIXED_CODE_START);
+       BUG_ON((char *)&atomic_xor32 - (char *)&fixed_code_start
+              != ATOMIC_XOR32 - FIXED_CODE_START);
 
-       printk(KERN_INFO "Hardware Trace Enabled\n");
-       bfin_write_TBUFCTL(0x03);
+       bf53x_cache_init();
 }
 
 static int __init topology_init(void)
@@ -421,286 +447,6 @@ static int __init topology_init(void)
 
 subsys_initcall(topology_init);
 
-#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE)
-static u16 __init lock_kernel_check(u32 start, u32 end)
-{
-       if ((start <= (u32) _stext && end >= (u32) _end)
-           || (start >= (u32) _stext && end <= (u32) _end))
-               return IN_KERNEL;
-       return 0;
-}
-
-static unsigned short __init
-fill_cplbtab(struct cplb_tab *table,
-            unsigned long start, unsigned long end,
-            unsigned long block_size, unsigned long cplb_data)
-{
-       int i;
-
-       switch (block_size) {
-       case SIZE_4M:
-               i = 3;
-               break;
-       case SIZE_1M:
-               i = 2;
-               break;
-       case SIZE_4K:
-               i = 1;
-               break;
-       case SIZE_1K:
-       default:
-               i = 0;
-               break;
-       }
-
-       cplb_data = (cplb_data & ~(3 << 16)) | (i << 16);
-
-       while ((start < end) && (table->pos < table->size)) {
-
-               table->tab[table->pos++] = start;
-
-               if (lock_kernel_check(start, start + block_size) == IN_KERNEL)
-                       table->tab[table->pos++] =
-                           cplb_data | CPLB_LOCK | CPLB_DIRTY;
-               else
-                       table->tab[table->pos++] = cplb_data;
-
-               start += block_size;
-       }
-       return 0;
-}
-
-static unsigned short __init
-close_cplbtab(struct cplb_tab *table)
-{
-
-       while (table->pos < table->size) {
-
-               table->tab[table->pos++] = 0;
-               table->tab[table->pos++] = 0; /* !CPLB_VALID */
-       }
-       return 0;
-}
-
-/* helper function */
-static void __fill_code_cplbtab(struct cplb_tab *t, int i,
-                               u32 a_start, u32 a_end)
-{
-       if (cplb_data[i].psize) {
-               fill_cplbtab(t,
-                               cplb_data[i].start,
-                               cplb_data[i].end,
-                               cplb_data[i].psize,
-                               cplb_data[i].i_conf);
-       } else {
-#if (defined(CONFIG_BLKFIN_CACHE) && defined(ANOMALY_05000263))
-               if (i == SDRAM_KERN) {
-                       fill_cplbtab(t,
-                                       cplb_data[i].start,
-                                       cplb_data[i].end,
-                                       SIZE_4M,
-                                       cplb_data[i].i_conf);
-               } else {
-#endif
-                       fill_cplbtab(t,
-                                       cplb_data[i].start,
-                                       a_start,
-                                       SIZE_1M,
-                                       cplb_data[i].i_conf);
-                       fill_cplbtab(t,
-                                       a_start,
-                                       a_end,
-                                       SIZE_4M,
-                                       cplb_data[i].i_conf);
-                       fill_cplbtab(t, a_end,
-                                       cplb_data[i].end,
-                                       SIZE_1M,
-                                       cplb_data[i].i_conf);
-               }
-       }
-}
-
-static void __fill_data_cplbtab(struct cplb_tab *t, int i,
-                               u32 a_start, u32 a_end)
-{
-       if (cplb_data[i].psize) {
-               fill_cplbtab(t,
-                               cplb_data[i].start,
-                               cplb_data[i].end,
-                               cplb_data[i].psize,
-                               cplb_data[i].d_conf);
-       } else {
-               fill_cplbtab(t,
-                               cplb_data[i].start,
-                               a_start, SIZE_1M,
-                               cplb_data[i].d_conf);
-               fill_cplbtab(t, a_start,
-                               a_end, SIZE_4M,
-                               cplb_data[i].d_conf);
-               fill_cplbtab(t, a_end,
-                               cplb_data[i].end,
-                               SIZE_1M,
-                               cplb_data[i].d_conf);
-       }
-}
-static void __init generate_cpl_tables(void)
-{
-
-       u16 i, j, process;
-       u32 a_start, a_end, as, ae, as_1m;
-
-       struct cplb_tab *t_i = NULL;
-       struct cplb_tab *t_d = NULL;
-       struct s_cplb cplb;
-
-       cplb.init_i.size = MAX_CPLBS;
-       cplb.init_d.size = MAX_CPLBS;
-       cplb.switch_i.size = MAX_SWITCH_I_CPLBS;
-       cplb.switch_d.size = MAX_SWITCH_D_CPLBS;
-
-       cplb.init_i.pos = 0;
-       cplb.init_d.pos = 0;
-       cplb.switch_i.pos = 0;
-       cplb.switch_d.pos = 0;
-
-       cplb.init_i.tab = icplb_table;
-       cplb.init_d.tab = dcplb_table;
-       cplb.switch_i.tab = ipdt_table;
-       cplb.switch_d.tab = dpdt_table;
-
-       cplb_data[SDRAM_KERN].end = memory_end;
-
-#ifdef CONFIG_MTD_UCLINUX
-       cplb_data[SDRAM_RAM_MTD].start = memory_mtd_start;
-       cplb_data[SDRAM_RAM_MTD].end = memory_mtd_start + mtd_size;
-       cplb_data[SDRAM_RAM_MTD].valid = mtd_size > 0;
-# if defined(CONFIG_ROMFS_FS)
-       cplb_data[SDRAM_RAM_MTD].attr |= I_CPLB;
-
-       /*
-        * The ROMFS_FS size is often not multiple of 1MB.
-        * This can cause multiple CPLB sets covering the same memory area.
-        * This will then cause multiple CPLB hit exceptions.
-        * Workaround: We ensure a contiguous memory area by extending the kernel
-        * memory section over the mtd section.
-        * For ROMFS_FS memory must be covered with ICPLBs anyways.
-        * So there is no difference between kernel and mtd memory setup.
-        */
-
-       cplb_data[SDRAM_KERN].end = memory_mtd_start + mtd_size;;
-       cplb_data[SDRAM_RAM_MTD].valid = 0;
-
-# endif
-#else
-       cplb_data[SDRAM_RAM_MTD].valid = 0;
-#endif
-
-       cplb_data[SDRAM_DMAZ].start = _ramend - DMA_UNCACHED_REGION;
-       cplb_data[SDRAM_DMAZ].end = _ramend;
-
-       cplb_data[RES_MEM].start = _ramend;
-       cplb_data[RES_MEM].end = physical_mem_end;
-
-       if (reserved_mem_dcache_on)
-               cplb_data[RES_MEM].d_conf = SDRAM_DGENERIC;
-       else
-               cplb_data[RES_MEM].d_conf = SDRAM_DNON_CHBL;
-
-       if (reserved_mem_icache_on)
-               cplb_data[RES_MEM].i_conf = SDRAM_IGENERIC;
-       else
-               cplb_data[RES_MEM].i_conf = SDRAM_INON_CHBL;
-
-       for (i = ZERO_P; i <= L2_MEM; i++) {
-               if (!cplb_data[i].valid)
-                       continue;
-
-               as_1m = cplb_data[i].start % SIZE_1M;
-
-               /*
-                * We need to make sure all sections are properly 1M aligned
-                * However between Kernel Memory and the Kernel mtd section,
-                * depending on the rootfs size, there can be overlapping
-                * memory areas.
-                */
-
-               if (as_1m && i != L1I_MEM && i != L1D_MEM) {
-#ifdef CONFIG_MTD_UCLINUX
-                       if (i == SDRAM_RAM_MTD) {
-                               if ((cplb_data[SDRAM_KERN].end + 1) >
-                                               cplb_data[SDRAM_RAM_MTD].start)
-                                       cplb_data[SDRAM_RAM_MTD].start =
-                                               (cplb_data[i].start &
-                                                (-2*SIZE_1M)) + SIZE_1M;
-                               else
-                                       cplb_data[SDRAM_RAM_MTD].start =
-                                               (cplb_data[i].start &
-                                                (-2*SIZE_1M));
-                       } else
-#endif
-                               printk(KERN_WARNING
-                                       "Unaligned Start of %s at 0x%X\n",
-                                       cplb_data[i].name, cplb_data[i].start);
-               }
-
-               as = cplb_data[i].start % SIZE_4M;
-               ae = cplb_data[i].end % SIZE_4M;
-
-               if (as)
-                       a_start = cplb_data[i].start + (SIZE_4M - (as));
-               else
-                       a_start = cplb_data[i].start;
-
-               a_end = cplb_data[i].end - ae;
-
-               for (j = INITIAL_T; j <= SWITCH_T; j++) {
-
-                       switch (j) {
-                       case INITIAL_T:
-                               if (cplb_data[i].attr & INITIAL_T) {
-                                       t_i = &cplb.init_i;
-                                       t_d = &cplb.init_d;
-                                       process = 1;
-                               } else
-                                       process = 0;
-                               break;
-                       case SWITCH_T:
-                               if (cplb_data[i].attr & SWITCH_T) {
-                                       t_i = &cplb.switch_i;
-                                       t_d = &cplb.switch_d;
-                                       process = 1;
-                               } else
-                                       process = 0;
-                               break;
-                       default:
-                                       process = 0;
-                               break;
-                       }
-
-                       if (!process)
-                               continue;
-                       if (cplb_data[i].attr & I_CPLB)
-                               __fill_code_cplbtab(t_i, i, a_start, a_end);
-
-                       if (cplb_data[i].attr & D_CPLB)
-                               __fill_data_cplbtab(t_d, i, a_start, a_end);
-               }
-       }
-
-/* close tables */
-
-       close_cplbtab(&cplb.init_i);
-       close_cplbtab(&cplb.init_d);
-
-       cplb.init_i.tab[cplb.init_i.pos] = -1;
-       cplb.init_d.tab[cplb.init_d.pos] = -1;
-       cplb.switch_i.tab[cplb.switch_i.pos] = -1;
-       cplb.switch_d.tab[cplb.switch_d.pos] = -1;
-
-}
-
-#endif
-
 static u_long get_vco(void)
 {
        u_long msel;
@@ -730,7 +476,6 @@ u_long get_cclk(void)
                return get_vco() / ssel;
        return get_vco() >> csel;
 }
-
 EXPORT_SYMBOL(get_cclk);
 
 /* Get the System clock */
@@ -749,7 +494,6 @@ u_long get_sclk(void)
 
        return get_vco() / ssel;
 }
-
 EXPORT_SYMBOL(get_sclk);
 
 /*
@@ -804,23 +548,23 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                seq_printf(m, "D-CACHE:\tOFF\n");
 
 
-       switch(bfin_read_DMEM_CONTROL() & (1 << DMC0_P | 1 << DMC1_P)) {
-               case ACACHE_BSRAM:
-                       seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tSRAM\n");
-                       dcache_size = 16;
-                       dsup_banks = 1;
-                       break;
-               case ACACHE_BCACHE:
-                       seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tCACHE\n");
-                       dcache_size = 32;
-                       dsup_banks = 2;
-                       break;
-               case ASRAM_BSRAM:
-                       seq_printf(m, "DBANK-A:\tSRAM\n" "DBANK-B:\tSRAM\n");
-                       dcache_size = 0;
-                       dsup_banks = 0;
-                       break;
-               default:
+       switch (bfin_read_DMEM_CONTROL() & (1 << DMC0_P | 1 << DMC1_P)) {
+       case ACACHE_BSRAM:
+               seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tSRAM\n");
+               dcache_size = 16;
+               dsup_banks = 1;
+               break;
+       case ACACHE_BCACHE:
+               seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tCACHE\n");
+               dcache_size = 32;
+               dsup_banks = 2;
+               break;
+       case ASRAM_BSRAM:
+               seq_printf(m, "DBANK-A:\tSRAM\n" "DBANK-B:\tSRAM\n");
+               dcache_size = 0;
+               dsup_banks = 0;
+               break;
+       default:
                break;
        }
 
index 316e65c3439d48cb084facd9783ed217928a73e4..5564c9588aa807bd3c0384c9b5256e205b1cd7bd 100644 (file)
@@ -34,8 +34,8 @@
 #include <linux/personality.h>
 #include <linux/binfmts.h>
 #include <linux/freezer.h>
+#include <linux/uaccess.h>
 
-#include <asm/uaccess.h>
 #include <asm/cacheflush.h>
 #include <asm/ucontext.h>
 
@@ -124,7 +124,7 @@ asmlinkage int do_rt_sigreturn(unsigned long __unused)
 
        return r0;
 
     badframe:
+ badframe:
        force_sig(SIGSEGV, current);
        return 0;
 }
@@ -239,7 +239,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info,
 
        return 0;
 
     give_sigsegv:
+ give_sigsegv:
        if (sig == SIGSEGV)
                ka->sa.sa_handler = SIG_DFL;
        force_sig(SIGSEGV, current);
@@ -263,7 +263,7 @@ handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
                }
                /* fallthrough */
        case -ERESTARTNOINTR:
            do_restart:
+ do_restart:
                regs->p0 = regs->orig_p0;
                regs->r0 = regs->orig_r0;
                regs->pc -= 2;
@@ -341,7 +341,7 @@ asmlinkage void do_signal(struct pt_regs *regs)
                return;
        }
 
-no_signal:
+ no_signal:
        /* Did we come from a system call? */
        if (regs->orig_p0 >= 0)
                /* Restart the system call - no handlers present */
index f436e6743f5a0f60b657f22f08991e015e69d36e..f5e1ae3d1705958dceb302addac289613e489120 100644 (file)
 #include <linux/syscalls.h>
 #include <linux/mman.h>
 #include <linux/file.h>
+#include <linux/uaccess.h>
+#include <linux/ipc.h>
+#include <linux/unistd.h>
 
 #include <asm/cacheflush.h>
-#include <asm/uaccess.h>
-#include <asm/ipc.h>
 #include <asm/dma.h>
-#include <asm/unistd.h>
 
 /*
  * sys_pipe() is the normal C calling standard for creating
@@ -83,7 +83,7 @@ do_mmap2(unsigned long addr, unsigned long len,
 
        if (file)
                fput(file);
     out:
+ out:
        return error;
 }
 
index f578176b6d9240080aca1dc5061e92878635b9e1..beef057bd1dc74d0451acec312c7657cfd21ebf3 100644 (file)
@@ -87,7 +87,7 @@ void __init init_leds(void)
 static inline void do_leds(void)
 {
        static unsigned int count = 50;
-       static int flag = 0;
+       static int flag;
        unsigned short tmp = 0;
 
        if (--count == 0) {
@@ -200,7 +200,7 @@ irqreturn_t timer_interrupt(int irq, void *dummy)__attribute__((l1_text));
 irqreturn_t timer_interrupt(int irq, void *dummy)
 {
        /* last time the cmos clock got updated */
-       static long last_rtc_update = 0;
+       static long last_rtc_update;
 
        write_seqlock(&xtime_lock);
 
index 56058b0b6d4a604954938c5f1964e4e58d2f66cc..3909f5b3553679ac1b6215b95e31f856aa34b2dd 100644 (file)
  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/kallsyms.h>
 #include <asm/traps.h>
 #include <asm/cacheflush.h>
 #include <asm/blackfin.h>
-#include <asm/uaccess.h>
 #include <asm/irq_handler.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/kallsyms.h>
+#include <asm/trace.h>
 
 #ifdef CONFIG_KGDB
 # include <linux/debugger.h>
@@ -76,7 +76,7 @@ static int printk_address(unsigned long address)
                if (!modname)
                        modname = delim = "";
                return printk("<0x%p> { %s%s%s%s + 0x%lx }",
-                             (void*)address, delim, modname, delim, symname,
+                             (void *)address, delim, modname, delim, symname,
                              (unsigned long)offset);
 
        }
@@ -119,7 +119,7 @@ static int printk_address(unsigned long address)
 
                                write_unlock_irq(&tasklist_lock);
                                return printk("<0x%p> [ %s + 0x%lx ]",
-                                             (void*)address, name, offset);
+                                             (void *)address, name, offset);
                        }
 
                        vml = vml->next;
@@ -128,19 +128,9 @@ static int printk_address(unsigned long address)
        write_unlock_irq(&tasklist_lock);
 
        /* we were unable to find this address anywhere */
-       return printk("[<0x%p>]", (void*)address);
+       return printk("[<0x%p>]", (void *)address);
 }
 
-#define trace_buffer_save(x) \
-       do { \
-               (x) = bfin_read_TBUFCTL(); \
-               bfin_write_TBUFCTL((x) & ~TBUFEN); \
-       } while (0)
-#define trace_buffer_restore(x) \
-       do { \
-               bfin_write_TBUFCTL((x));        \
-       } while (0)
-
 asmlinkage void trap_c(struct pt_regs *fp)
 {
        int j, sig = 0;
@@ -203,15 +193,14 @@ asmlinkage void trap_c(struct pt_regs *fp)
 #else
        /* 0x02 - User Defined, Caught by default */
 #endif
-       /* 0x03  - Atomic test and set */
+       /* 0x03 - User Defined, userspace stack overflow */
        case VEC_EXCPT03:
                info.si_code = SEGV_STACKFLOW;
                sig = SIGSEGV;
                printk(KERN_EMERG EXC_0x03);
                CHK_DEBUGGER_TRAP();
                break;
-       /* 0x04 - spinlock - handled by _ex_spinlock,
-               getting here is an error */
+       /* 0x04 - User Defined, Caught by default */
        /* 0x05 - User Defined, Caught by default */
        /* 0x06 - User Defined, Caught by default */
        /* 0x07 - User Defined, Caught by default */
@@ -547,29 +536,28 @@ void dump_bfin_regs(struct pt_regs *fp, void *retaddr)
                printk(KERN_EMERG "TEXT = 0x%p-0x%p  DATA = 0x%p-0x%p\n"
                       KERN_EMERG "BSS = 0x%p-0x%p   USER-STACK = 0x%p\n"
                       KERN_EMERG "\n",
-                      (void*)current->mm->start_code,
-                      (void*)current->mm->end_code,
-                      (void*)current->mm->start_data,
-                      (void*)current->mm->end_data,
-                      (void*)current->mm->end_data,
-                      (void*)current->mm->brk,
-                      (void*)current->mm->start_stack);
+                      (void *)current->mm->start_code,
+                      (void *)current->mm->end_code,
+                      (void *)current->mm->start_data,
+                      (void *)current->mm->end_data,
+                      (void *)current->mm->end_data,
+                      (void *)current->mm->brk,
+                      (void *)current->mm->start_stack);
        }
 
        printk(KERN_EMERG "return address: [0x%p]; contents of:", retaddr);
-       if (retaddr != 0 && retaddr <= (void*)physical_mem_end
+       if (retaddr != 0 && retaddr <= (void *)physical_mem_end
 #if L1_CODE_LENGTH != 0
            /* FIXME: Copy the code out of L1 Instruction SRAM through dma
               memcpy.  */
-           && !(retaddr >= (void*)L1_CODE_START
-                && retaddr < (void*)(L1_CODE_START + L1_CODE_LENGTH))
+           && !(retaddr >= (void *)L1_CODE_START
+                && retaddr < (void *)(L1_CODE_START + L1_CODE_LENGTH))
 #endif
        ) {
                int i = ((unsigned int)retaddr & 0xFFFFFFF0) - 32;
                unsigned short x = 0;
-               for (; i < ((unsigned int)retaddr & 0xFFFFFFF0 ) + 32 ;
-                       i += 2) {
-                       if ( !(i & 0xF) )
+               for (; i < ((unsigned int)retaddr & 0xFFFFFFF0) + 32; i += 2) {
+                       if (!(i & 0xF))
                                printk(KERN_EMERG "\n" KERN_EMERG
                                        "0x%08x: ", i);
 
@@ -588,7 +576,7 @@ void dump_bfin_regs(struct pt_regs *fp, void *retaddr)
                                        " The rest of this error"
                                        " is meanless\n");
 #endif
-                       if ( i == (unsigned int)retaddr )
+                       if (i == (unsigned int)retaddr)
                                printk("[%04x]", x);
                        else
                                printk(" %04x ", x);
@@ -681,8 +669,8 @@ void panic_cplb_error(int cplb_panic, struct pt_regs *fp)
                break;
        }
 
-       printk(KERN_EMERG "DCPLB_FAULT_ADDR=%p\n", (void*)bfin_read_DCPLB_FAULT_ADDR());
-       printk(KERN_EMERG "ICPLB_FAULT_ADDR=%p\n", (void*)bfin_read_ICPLB_FAULT_ADDR());
+       printk(KERN_EMERG "DCPLB_FAULT_ADDR=%p\n", (void *)bfin_read_DCPLB_FAULT_ADDR());
+       printk(KERN_EMERG "ICPLB_FAULT_ADDR=%p\n", (void *)bfin_read_ICPLB_FAULT_ADDR());
        dump_bfin_regs(fp, (void *)fp->retx);
        dump_stack();
        panic("Unrecoverable event\n");
index 1ef1e36b3957d95690efddea5416d52c58755975..d06f860f47900a5b6e09edf4b6629b6c9908c9e7 100644 (file)
@@ -31,6 +31,7 @@
 
 #include <asm-generic/vmlinux.lds.h>
 #include <asm/mem_map.h>
+#include <asm/page.h>
 
 OUTPUT_FORMAT("elf32-bfin")
 ENTRY(__start)
@@ -63,8 +64,8 @@ SECTIONS
 
        .data :
        {
+               . = ALIGN(PAGE_SIZE);
                __sdata = .;
-               . = ALIGN(0x2000);
                *(.data.init_task)
                DATA_DATA
                CONSTRUCTORS
@@ -72,14 +73,14 @@ SECTIONS
                . = ALIGN(32);
                *(.data.cacheline_aligned)
 
-               . = ALIGN(0x2000);
+               . = ALIGN(PAGE_SIZE);
                __edata = .;
        }
 
+       . = ALIGN(PAGE_SIZE);
        ___init_begin = .;
        .init :
        {
-               . = ALIGN(4096);
                __sinittext = .;
                *(.init.text)
                __einittext = .;
@@ -152,9 +153,10 @@ SECTIONS
                __ebss_b_l1 = .;
        }
 
-       ___init_end = LOADADDR(.data_b_l1) + SIZEOF(.data_b_l1);
+       . = LOADADDR(.data_b_l1) + SIZEOF(.data_b_l1);
+       ___init_end = ALIGN(PAGE_SIZE);
 
-       .bss LOADADDR(.data_b_l1) + SIZEOF(.data_b_l1) :
+       .bss ___init_end :
        {
                . = ALIGN(4);
                ___bss_start = .;
index 2ad47c4254ba579ea423a0011cb1a26736fadc8d..4eeefd86907f0ff460f04768b6eaf2c90b97bb52 100644 (file)
@@ -6,6 +6,5 @@
 
 int strcmp(const char *dest, const char *src)
 {
-               return __inline_strcmp(dest, src);
+       return __inline_strcmp(dest, src);
 }
-
index 4dc835a8a19b080bc9e91d935e8630c8f8849e37..534589db725619797bb44c51fe296ea8fbea9bde 100644 (file)
@@ -6,6 +6,5 @@
 
 char *strcpy(char *dest, const char *src)
 {
-               return __inline_strcpy(dest, src);
+       return __inline_strcpy(dest, src);
 }
-
index 947bcfe3f3bba630e3b0d4f294c4b31d0355a6c2..d791f120bff7388252f3add58d20aade76cc03b2 100644 (file)
@@ -6,6 +6,5 @@
 
 int strncmp(const char *cs, const char *ct, size_t count)
 {
-               return __inline_strncmp(cs, ct, count);
+       return __inline_strncmp(cs, ct, count);
 }
-
index 77a9b2e950977bcb7d5fe213015dceef1308eb05..1fecb5c71ffb21ec581d157b81ef2d2d8776bc8c 100644 (file)
@@ -6,6 +6,5 @@
 
 char *strncpy(char *dest, const char *src, size_t n)
 {
-               return __inline_strncpy(dest, src, n);
+       return __inline_strncpy(dest, src, n);
 }
-
index 76d2c2b8579a7dbedea91ec7fc360bf264d73daf..8cce1736360d3b8904df3acc9be3fa8a709588e2 100644 (file)
@@ -4,6 +4,6 @@
 
 extra-y := head.o
 
-obj-y := ints-priority.o
+obj-y := ints-priority.o dma.o
 
-obj-$(CONFIG_CPU_FREQ_BF533) += cpu.o
+obj-$(CONFIG_CPU_FREQ)   += cpu.o
index edd31ce4f8d2d62fccad4aede373b70c4fafc6fa..4545f363e641d9f1aafd3d9dbcaa19a3a00ba53f 100644 (file)
@@ -34,7 +34,7 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
 #include <linux/usb_isp1362.h>
-#include <asm/irq.h>
+#include <linux/irq.h>
 #include <asm/bfin5xx_spi.h>
 
 /*
@@ -51,11 +51,11 @@ static struct mtd_partition bfin_spi_flash_partitions[] = {
                .size = 0x00020000,
                .offset = 0,
                .mask_flags = MTD_CAP_ROM
-       },{
+       }, {
                .name = "kernel",
                .size = 0xe0000,
                .offset = 0x20000
-       },{
+       }, {
                .name = "file system",
                .size = 0x700000,
                .offset = 0x00100000,
@@ -98,7 +98,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
                .platform_data = &bfin_spi_flash_data,
                .controller_data = &spi_flash_chip_info,
                .mode = SPI_MODE_3,
-       },{
+       }, {
                .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
                .max_speed_hz = 6250000,     /* max spi clock (SCK) speed in HZ */
                .bus_num = 1,               /* Framework bus number */
@@ -145,7 +145,7 @@ static struct resource smc91x_resources[] = {
                .start = 0x20200300,
                .end = 0x20200300 + 16,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = IRQ_PF0,
                .end = IRQ_PF0,
                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -194,11 +194,11 @@ static struct resource isp1362_hcd_resources[] = {
                .start = 0x20308000,
                .end = 0x20308000,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = 0x20308004,
                .end = 0x20308004,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = IRQ_PF4,
                .end = IRQ_PF4,
                .flags = IORESOURCE_IRQ,
index 0b522d95160d4d189d19e2146ac1f3933b9b0649..0000b8f1239c5030a6b3e56cfd1b7ab907a18632 100644 (file)
@@ -35,7 +35,7 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
 #include <linux/usb_isp1362.h>
-#include <asm/irq.h>
+#include <linux/irq.h>
 #include <asm/bfin5xx_spi.h>
 
 /*
@@ -61,7 +61,7 @@ static struct resource smc91x_resources[] = {
                .start = 0x20310300,
                .end = 0x20310300 + 16,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = IRQ_PF9,
                .end = IRQ_PF9,
                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -85,11 +85,11 @@ static struct mtd_partition bfin_spi_flash_partitions[] = {
                .size = 0x00020000,
                .offset = 0,
                .mask_flags = MTD_CAP_ROM
-       },{
+       }, {
                .name = "kernel",
                .size = 0xe0000,
                .offset = 0x20000
-       },{
+       }, {
                .name = "file system",
                .size = 0x700000,
                .offset = 0x00100000,
index c0f43ccfbfb5320b2281125b1f1e4d8f9c0f2aca..9bc1f0d0ab508692f12791840ea9d30efd68a77c 100644 (file)
@@ -30,7 +30,7 @@
 
 #include <linux/device.h>
 #include <linux/platform_device.h>
-#include <asm/irq.h>
+#include <linux/irq.h>
 
 /*
  * Name the Board for the /proc/cpuinfo
@@ -53,11 +53,11 @@ static struct resource smc91x_resources[] = {
                .start = 0x20300300,
                .end = 0x20300300 + 16,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = IRQ_PROG_INTB,
                .end = IRQ_PROG_INTB,
                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
-       },{
+       }, {
                /*
                 *  denotes the flag pin and is used directly if
                 *  CONFIG_IRQCHIP_DEMUX_GPIO is defined.
index 9a472fe15833ea25883fc0ac236275a7431a9f58..a9143c4cbdcd110d3f88ddb697e04cab015e6e19 100644 (file)
@@ -37,7 +37,7 @@
 #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
 #include <linux/usb_isp1362.h>
 #endif
-#include <asm/irq.h>
+#include <linux/irq.h>
 #include <asm/bfin5xx_spi.h>
 
 /*
@@ -62,7 +62,7 @@ static struct resource smc91x_resources[] = {
                .start = 0x20300300,
                .end = 0x20300300 + 16,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = IRQ_PF7,
                .end = IRQ_PF7,
                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -83,7 +83,7 @@ static struct resource net2272_bfin_resources[] = {
                .start = 0x20300000,
                .end = 0x20300000 + 0x100,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = IRQ_PF10,
                .end = IRQ_PF10,
                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -108,11 +108,11 @@ static struct mtd_partition bfin_spi_flash_partitions[] = {
                .size = 0x00020000,
                .offset = 0,
                .mask_flags = MTD_CAP_ROM
-       },{
+       }, {
                .name = "kernel",
                .size = 0xe0000,
                .offset = 0x20000
-       },{
+       }, {
                .name = "file system",
                .size = 0x700000,
                .offset = 0x00100000,
@@ -229,19 +229,19 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 
 #if defined(CONFIG_PBX)
        {
-               .modalias       = "fxs-spi",
-               .max_speed_hz   = 12500000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num        = 1,
-               .chip_select    = 3,
-               .controller_data= &spi_si3xxx_chip_info,
+               .modalias = "fxs-spi",
+               .max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num = 1,
+               .chip_select = 3,
+               .controller_data = &spi_si3xxx_chip_info,
                .mode = SPI_MODE_3,
        },
        {
-               .modalias       = "fxo-spi",
-               .max_speed_hz   = 12500000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num        = 1,
-               .chip_select    = 2,
-               .controller_data= &spi_si3xxx_chip_info,
+               .modalias = "fxo-spi",
+               .max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num = 1,
+               .chip_select = 2,
+               .controller_data = &spi_si3xxx_chip_info,
                .mode = SPI_MODE_3,
        },
 #endif
index 99547c4c290ebf73f73a6a7fa0a65996556550a3..6fd9cfd0a31bd1a330f89a1c803ca749abffa67b 100644 (file)
@@ -79,8 +79,7 @@ static int bf533_target(struct cpufreq_policy *policy,
        int i;
 
        struct cpufreq_freqs freqs;
-       if (cpufreq_frequency_table_target
-           (policy, bf533_freq_table, target_freq, relation, &index))
+       if (cpufreq_frequency_table_target(policy, bf533_freq_table, target_freq, relation, &index))
                return -EINVAL;
        cclk_mhz = bf533_freq_table[index].frequency;
        vco_mhz = bf533_freq_table[index].index;
diff --git a/arch/blackfin/mach-bf533/dma.c b/arch/blackfin/mach-bf533/dma.c
new file mode 100644 (file)
index 0000000..6c909cf
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * File:         arch/blackfin/mach-bf533/dma.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:  This file contains the simple DMA Implementation for Blackfin
+ *
+ * Modified:
+ *               Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <asm/blackfin.h>
+#include <asm/dma.h>
+
+struct dma_register *base_addr[MAX_BLACKFIN_DMA_CHANNEL] = {
+       (struct dma_register *) DMA0_NEXT_DESC_PTR,
+       (struct dma_register *) DMA1_NEXT_DESC_PTR,
+       (struct dma_register *) DMA2_NEXT_DESC_PTR,
+       (struct dma_register *) DMA3_NEXT_DESC_PTR,
+       (struct dma_register *) DMA4_NEXT_DESC_PTR,
+       (struct dma_register *) DMA5_NEXT_DESC_PTR,
+       (struct dma_register *) DMA6_NEXT_DESC_PTR,
+       (struct dma_register *) DMA7_NEXT_DESC_PTR,
+       (struct dma_register *) MDMA_D0_NEXT_DESC_PTR,
+       (struct dma_register *) MDMA_S0_NEXT_DESC_PTR,
+       (struct dma_register *) MDMA_D1_NEXT_DESC_PTR,
+       (struct dma_register *) MDMA_S1_NEXT_DESC_PTR,
+};
+
+int channel2irq(unsigned int channel)
+{
+       int ret_irq = -1;
+
+       switch (channel) {
+       case CH_PPI:
+               ret_irq = IRQ_PPI;
+               break;
+
+       case CH_SPORT0_RX:
+               ret_irq = IRQ_SPORT0_RX;
+               break;
+
+       case CH_SPORT0_TX:
+               ret_irq = IRQ_SPORT0_TX;
+               break;
+
+       case CH_SPORT1_RX:
+               ret_irq = IRQ_SPORT1_RX;
+               break;
+
+       case CH_SPORT1_TX:
+               ret_irq = IRQ_SPORT1_TX;
+               break;
+
+       case CH_SPI:
+               ret_irq = IRQ_SPI;
+               break;
+
+       case CH_UART_RX:
+               ret_irq = IRQ_UART_RX;
+               break;
+
+       case CH_UART_TX:
+               ret_irq = IRQ_UART_TX;
+               break;
+
+       case CH_MEM_STREAM0_SRC:
+       case CH_MEM_STREAM0_DEST:
+               ret_irq = IRQ_MEM_DMA0;
+               break;
+
+       case CH_MEM_STREAM1_SRC:
+       case CH_MEM_STREAM1_DEST:
+               ret_irq = IRQ_MEM_DMA1;
+               break;
+       }
+       return ret_irq;
+}
index 7e2aa8d0f44f624c35df56197fb2943812bdb113..7dd0e9c3a936402e4e9470677114b8155eababbe 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 #include <asm/blackfin.h>
+#include <asm/trace.h>
 #if CONFIG_BFIN_KERNEL_CLOCK
 #include <asm/mach/mem_init.h>
 #endif
@@ -96,6 +97,10 @@ ENTRY(__start)
        M2 = r0;
        M3 = r0;
 
+       trace_buffer_start(p0,r0);
+       P0 = R1;
+       R0 = R1;
+
 #if CONFIG_DEBUG_KERNEL_START
 
 /*
index a3e1789167beec2c60ad1d17f19b6a2c393480a1..7d79e0f9503deb989f33a1df82e3906c02b76a21 100644 (file)
@@ -28,8 +28,8 @@
  */
 
 #include <linux/module.h>
+#include <linux/irq.h>
 #include <asm/blackfin.h>
-#include <asm/irq.h>
 
 void program_IAR(void)
 {
index f32d44215bb7fbd6bf74f0e9d20affc1db3c7de6..7e7c9c8ac5b263ac02f3aaa58ff349ed3060ee55 100644 (file)
@@ -4,6 +4,6 @@
 
 extra-y := head.o
 
-obj-y := ints-priority.o
+obj-y := ints-priority.o dma.o
 
 obj-$(CONFIG_CPU_FREQ)   += cpu.o
index 6a60618a78ecf9efa71d5ed35f66a55e24ea04ba..a8f947b727542fc2705107c515fe76556179fdaa 100644 (file)
@@ -35,7 +35,7 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
 #include <linux/usb_isp1362.h>
-#include <asm/irq.h>
+#include <linux/irq.h>
 #include <asm/bfin5xx_spi.h>
 
 /*
@@ -53,11 +53,11 @@ static struct mtd_partition bfin_spi_flash_partitions[] = {
                .size = 0x00020000,
                .offset = 0,
                .mask_flags = MTD_CAP_ROM
-       },{
+       }, {
                .name = "kernel",
                .size = 0xe0000,
                .offset = 0x20000
-       },{
+       }, {
                .name = "file system",
                .size = 0x700000,
                .offset = 0x00100000,
@@ -202,7 +202,7 @@ static struct resource smc91x_resources[] = {
                .start = 0x20200300,
                .end = 0x20200300 + 16,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = IRQ_PF14,
                .end = IRQ_PF14,
                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -223,11 +223,11 @@ static struct resource isp1362_hcd_resources[] = {
                .start = 0x20308000,
                .end = 0x20308000,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = 0x20308004,
                .end = 0x20308004,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = IRQ_PG15,
                .end = IRQ_PG15,
                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -262,7 +262,7 @@ static struct resource net2272_bfin_resources[] = {
                .start = 0x20200000,
                .end = 0x20200000 + 0x100,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = IRQ_PF7,
                .end = IRQ_PF7,
                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -283,7 +283,7 @@ static struct resource bfin_uart_resources[] = {
                .start = 0xFFC00400,
                .end = 0xFFC004FF,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = 0xFFC02000,
                .end = 0xFFC020FF,
                .flags = IORESOURCE_MEM,
index e129a08d63de61330ad5677ba28cb71e81a788a3..a725cc8a92903100d371aacd928ec5623dec4970 100644 (file)
@@ -20,8 +20,7 @@
 #include <linux/module.h>
 #include <asm/blackfin.h>
 
-#if    defined(CONFIG_GENERIC_BOARD) \
-       || defined(CONFIG_BFIN537_STAMP)
+#if    defined(CONFIG_GENERIC_BOARD) || defined(CONFIG_BFIN537_STAMP)
 
 /*
  * Currently the MAC address is saved in Flash by U-Boot
@@ -43,7 +42,7 @@ void get_bf537_ether_addr(char *addr)
  */
 void get_bf537_ether_addr(char *addr)
 {
-       printk(KERN_WARNING "%s: No valid Ethernet MAC address found\n",__FILE__);
+       printk(KERN_WARNING "%s: No valid Ethernet MAC address found\n", __FILE__);
 }
 
 #endif
index fd57e7439e0fa7347429e12906fc5a96c6cf6ba0..648d984e98d6ce45b536a9a92b06a8c8e4333e5e 100644 (file)
@@ -35,9 +35,9 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
 #include <linux/usb_isp1362.h>
-#include <asm/irq.h>
-#include <asm/bfin5xx_spi.h>
+#include <linux/irq.h>
 #include <linux/usb_sl811.h>
+#include <asm/bfin5xx_spi.h>
 
 /*
  * Name the Board for the /proc/cpuinfo
@@ -54,19 +54,19 @@ static struct resource bfin_pcmcia_cf_resources[] = {
                .start = 0x20310000, /* IO PORT */
                .end = 0x20312000,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = 0x20311000, /* Attribute Memory */
                .end = 0x20311FFF,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = IRQ_PROG_INTA,
                .end = IRQ_PROG_INTA,
                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
-       },{
+       }, {
                .start = IRQ_PF4,
                .end = IRQ_PF4,
                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
-       },{
+       }, {
                .start = 6, /* Card Detect PF6 */
                .end = 6,
                .flags = IORESOURCE_IRQ,
@@ -95,11 +95,11 @@ static struct resource smc91x_resources[] = {
                .start = 0x20300300,
                .end = 0x20300300 + 16,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = IRQ_PROG_INTB,
                .end = IRQ_PROG_INTB,
                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
-       },{
+       }, {
                /*
                 *  denotes the flag pin and is used directly if
                 *  CONFIG_IRQCHIP_DEMUX_GPIO is defined.
@@ -123,15 +123,15 @@ static struct resource sl811_hcd_resources[] = {
                .start = 0x20340000,
                .end = 0x20340000,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = 0x20340004,
                .end = 0x20340004,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = IRQ_PROG_INTA,
                .end = IRQ_PROG_INTA,
                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
-       },{
+       }, {
                .start = IRQ_PF0 + CONFIG_USB_SL811_BFIN_GPIO,
                .end = IRQ_PF0 + CONFIG_USB_SL811_BFIN_GPIO,
                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -179,15 +179,15 @@ static struct resource isp1362_hcd_resources[] = {
                .start = 0x20360000,
                .end = 0x20360000,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = 0x20360004,
                .end = 0x20360004,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = IRQ_PROG_INTA,
                .end = IRQ_PROG_INTA,
                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
-       },{
+       }, {
                .start = IRQ_PF0 + CONFIG_USB_ISP1362_BFIN_GPIO,
                .end = IRQ_PF0 + CONFIG_USB_ISP1362_BFIN_GPIO,
                .flags = IORESOURCE_IRQ,
@@ -228,7 +228,7 @@ static struct resource net2272_bfin_resources[] = {
                .start = 0x20300000,
                .end = 0x20300000 + 0x100,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = IRQ_PF7,
                .end = IRQ_PF7,
                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -253,11 +253,11 @@ static struct mtd_partition bfin_spi_flash_partitions[] = {
                .size = 0x00020000,
                .offset = 0,
                .mask_flags = MTD_CAP_ROM
-       },{
+       }, {
                .name = "kernel",
                .size = 0xe0000,
                .offset = 0x20000
-       },{
+       }, {
                .name = "file system",
                .size = 0x700000,
                .offset = 0x00100000,
@@ -375,7 +375,7 @@ static struct resource bfin_uart_resources[] = {
                .start = 0xFFC00400,
                .end = 0xFFC004FF,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = 0xFFC02000,
                .end = 0xFFC020FF,
                .flags = IORESOURCE_MEM,
index 8aaf76dfce80831b0f5d71aa5d8ad1b8c672be9c..8806f1230f2da480c4a3b8e055466985fa0e4698 100644 (file)
@@ -37,7 +37,7 @@
 #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
 #include <linux/usb_isp1362.h>
 #endif
-#include <asm/irq.h>
+#include <linux/irq.h>
 #include <asm/bfin5xx_spi.h>
 #include <linux/usb_sl811.h>
 
@@ -58,15 +58,15 @@ static struct resource bfin_pcmcia_cf_resources[] = {
                .start = 0x20310000, /* IO PORT */
                .end = 0x20312000,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = 0x20311000, /* Attribute Memory */
                .end = 0x20311FFF,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = IRQ_PF4,
                .end = IRQ_PF4,
                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
-       },{
+       }, {
                .start = 6, /* Card Detect PF6 */
                .end = 6,
                .flags = IORESOURCE_IRQ,
@@ -95,7 +95,7 @@ static struct resource smc91x_resources[] = {
                .start = 0x20300300,
                .end = 0x20300300 + 16,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
 
                .start = IRQ_PF7,
                .end = IRQ_PF7,
@@ -116,11 +116,11 @@ static struct resource sl811_hcd_resources[] = {
                .start = 0x20340000,
                .end = 0x20340000,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = 0x20340004,
                .end = 0x20340004,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = CONFIG_USB_SL811_BFIN_IRQ,
                .end = CONFIG_USB_SL811_BFIN_IRQ,
                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -167,11 +167,11 @@ static struct resource isp1362_hcd_resources[] = {
                .start = 0x20360000,
                .end = 0x20360000,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = 0x20360004,
                .end = 0x20360004,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ,
                .end = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ,
                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -212,7 +212,7 @@ static struct resource net2272_bfin_resources[] = {
                .start = 0x20300000,
                .end = 0x20300000 + 0x100,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = IRQ_PF7,
                .end = IRQ_PF7,
                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -238,11 +238,11 @@ static struct mtd_partition bfin_spi_flash_partitions[] = {
                .size = 0x00020000,
                .offset = 0,
                .mask_flags = MTD_CAP_ROM
-       },{
+       }, {
                .name = "kernel",
                .size = 0xe0000,
                .offset = 0x20000
-       },{
+       }, {
                .name = "file system",
                .size = 0x700000,
                .offset = 0x00100000,
@@ -294,16 +294,6 @@ static struct bfin5xx_spi_chip spi_mmc_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_PBX)
-static struct bfin5xx_spi_chip spi_si3xxx_chip_info = {
-       .ctl_reg        = 0x4, /* send zero */
-       .enable_dma     = 0,
-       .bits_per_word  = 8,
-       .cs_change_per_word = 1,
-};
-#endif
-
-
 #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
 static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
        .cs_change_per_word = 1,
@@ -392,24 +382,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
                .mode = SPI_MODE_3,
        },
 #endif
-#if defined(CONFIG_PBX)
-       {
-               .modalias       = "fxs-spi",
-               .max_speed_hz   = 12500000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num        = 1,
-               .chip_select    = 3,
-               .controller_data= &spi_si3xxx_chip_info,
-               .mode = SPI_MODE_3,
-       },
-       {
-               .modalias       = "fxo-spi",
-               .max_speed_hz   = 12500000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num        = 1,
-               .chip_select    = 2,
-               .controller_data= &spi_si3xxx_chip_info,
-               .mode = SPI_MODE_3,
-       },
-#endif
 #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
 {
        .modalias               = "ad7877",
@@ -451,7 +423,7 @@ static struct resource bfin_uart_resources[] = {
                .start = 0xFFC00400,
                .end = 0xFFC004FF,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = 0xFFC02000,
                .end = 0xFFC020FF,
                .flags = IORESOURCE_MEM,
index 3a29b4d15f252b79b329ee92bcceeaa2bd3abaae..9c43d775651088f219f948c80f0f9f9432014232 100644 (file)
 #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
 #include <linux/usb_isp1362.h>
 #endif
-#include <asm/irq.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
-#include <asm/bfin5xx_spi.h>
 #include <linux/usb_sl811.h>
-
+#include <asm/bfin5xx_spi.h>
 #include <linux/spi/ad7877.h>
 
 /*
@@ -85,7 +83,7 @@ static struct platform_device *bfin_isp1761_devices[] = {
 
 int __init bfin_isp1761_init(void)
 {
-       unsigned int num_devices=ARRAY_SIZE(bfin_isp1761_devices);
+       unsigned int num_devices = ARRAY_SIZE(bfin_isp1761_devices);
 
        printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
        set_irq_type(ISP1761_IRQ, IRQF_TRIGGER_FALLING);
@@ -107,15 +105,15 @@ static struct resource bfin_pcmcia_cf_resources[] = {
                .start = 0x20310000, /* IO PORT */
                .end = 0x20312000,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = 0x20311000, /* Attribute Memory */
                .end = 0x20311FFF,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = IRQ_PF4,
                .end = IRQ_PF4,
                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
-       },{
+       }, {
                .start = 6, /* Card Detect PF6 */
                .end = 6,
                .flags = IORESOURCE_IRQ,
@@ -144,7 +142,7 @@ static struct resource smc91x_resources[] = {
                .start = 0x20300300,
                .end = 0x20300300 + 16,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
 
                .start = IRQ_PF7,
                .end = IRQ_PF7,
@@ -159,17 +157,39 @@ static struct platform_device smc91x_device = {
 };
 #endif
 
+#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
+static struct resource dm9000_resources[] = {
+       [0] = {
+               .start  = 0x203FB800,
+               .end    = 0x203FB800 + 8,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_PF9,
+               .end    = IRQ_PF9,
+               .flags  = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE),
+       },
+};
+
+static struct platform_device dm9000_device = {
+       .name           = "dm9000",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(dm9000_resources),
+       .resource       = dm9000_resources,
+};
+#endif
+
 #if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
 static struct resource sl811_hcd_resources[] = {
        {
                .start = 0x20340000,
                .end = 0x20340000,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = 0x20340004,
                .end = 0x20340004,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = CONFIG_USB_SL811_BFIN_IRQ,
                .end = CONFIG_USB_SL811_BFIN_IRQ,
                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -216,11 +236,11 @@ static struct resource isp1362_hcd_resources[] = {
                .start = 0x20360000,
                .end = 0x20360000,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = 0x20360004,
                .end = 0x20360004,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ,
                .end = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ,
                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -261,7 +281,7 @@ static struct resource net2272_bfin_resources[] = {
                .start = 0x20300000,
                .end = 0x20300000 + 0x100,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = IRQ_PF7,
                .end = IRQ_PF7,
                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -287,11 +307,11 @@ static struct mtd_partition bfin_spi_flash_partitions[] = {
                .size = 0x00020000,
                .offset = 0,
                .mask_flags = MTD_CAP_ROM
-       },{
+       }, {
                .name = "kernel",
                .size = 0xe0000,
                .offset = 0x20000
-       },{
+       }, {
                .name = "file system",
                .size = 0x700000,
                .offset = 0x00100000,
@@ -361,7 +381,6 @@ static struct bfin5xx_spi_chip ad5304_chip_info = {
 
 #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
 static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
-//     .cs_change_per_word = 1,
        .enable_dma = 0,
        .bits_per_word = 16,
 };
@@ -449,19 +468,19 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 #endif
 #if defined(CONFIG_PBX)
        {
-               .modalias       = "fxs-spi",
-               .max_speed_hz   = 12500000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num        = 1,
-               .chip_select    = 3,
-               .controller_data= &spi_si3xxx_chip_info,
+               .modalias = "fxs-spi",
+               .max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num = 1,
+               .chip_select = 3,
+               .controller_data = &spi_si3xxx_chip_info,
                .mode = SPI_MODE_3,
        },
        {
-               .modalias       = "fxo-spi",
-               .max_speed_hz   = 12500000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num        = 1,
-               .chip_select    = 2,
-               .controller_data= &spi_si3xxx_chip_info,
+               .modalias = "fxo-spi",
+               .max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num = 1,
+               .chip_select = 2,
+               .controller_data = &spi_si3xxx_chip_info,
                .mode = SPI_MODE_3,
        },
 #endif
@@ -516,7 +535,7 @@ static struct resource bfin_uart_resources[] = {
                .start = 0xFFC00400,
                .end = 0xFFC004FF,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = 0xFFC02000,
                .end = 0xFFC020FF,
                .flags = IORESOURCE_MEM,
@@ -571,6 +590,10 @@ static struct platform_device *stamp_devices[] __initdata = {
        &smc91x_device,
 #endif
 
+#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
+       &dm9000_device,
+#endif
+
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
        &bfin_mac_device,
 #endif
diff --git a/arch/blackfin/mach-bf537/dma.c b/arch/blackfin/mach-bf537/dma.c
new file mode 100644 (file)
index 0000000..706cb97
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * File:         arch/blackfin/mach-bf537/dma.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:  This file contains the simple DMA Implementation for Blackfin
+ *
+ * Modified:
+ *               Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <asm/blackfin.h>
+#include <asm/dma.h>
+
+struct dma_register *base_addr[MAX_BLACKFIN_DMA_CHANNEL] = {
+       (struct dma_register *) DMA0_NEXT_DESC_PTR,
+       (struct dma_register *) DMA1_NEXT_DESC_PTR,
+       (struct dma_register *) DMA2_NEXT_DESC_PTR,
+       (struct dma_register *) DMA3_NEXT_DESC_PTR,
+       (struct dma_register *) DMA4_NEXT_DESC_PTR,
+       (struct dma_register *) DMA5_NEXT_DESC_PTR,
+       (struct dma_register *) DMA6_NEXT_DESC_PTR,
+       (struct dma_register *) DMA7_NEXT_DESC_PTR,
+       (struct dma_register *) DMA8_NEXT_DESC_PTR,
+       (struct dma_register *) DMA9_NEXT_DESC_PTR,
+       (struct dma_register *) DMA10_NEXT_DESC_PTR,
+       (struct dma_register *) DMA11_NEXT_DESC_PTR,
+       (struct dma_register *) MDMA_D0_NEXT_DESC_PTR,
+       (struct dma_register *) MDMA_S0_NEXT_DESC_PTR,
+       (struct dma_register *) MDMA_D1_NEXT_DESC_PTR,
+       (struct dma_register *) MDMA_S1_NEXT_DESC_PTR,
+};
+
+int channel2irq(unsigned int channel)
+{
+       int ret_irq = -1;
+
+       switch (channel) {
+       case CH_PPI:
+               ret_irq = IRQ_PPI;
+               break;
+
+       case CH_EMAC_RX:
+               ret_irq = IRQ_MAC_RX;
+               break;
+
+       case CH_EMAC_TX:
+               ret_irq = IRQ_MAC_TX;
+               break;
+
+       case CH_UART1_RX:
+               ret_irq = IRQ_UART1_RX;
+               break;
+
+       case CH_UART1_TX:
+               ret_irq = IRQ_UART1_TX;
+               break;
+
+       case CH_SPORT0_RX:
+               ret_irq = IRQ_SPORT0_RX;
+               break;
+
+       case CH_SPORT0_TX:
+               ret_irq = IRQ_SPORT0_TX;
+               break;
+
+       case CH_SPORT1_RX:
+               ret_irq = IRQ_SPORT1_RX;
+               break;
+
+       case CH_SPORT1_TX:
+               ret_irq = IRQ_SPORT1_TX;
+               break;
+
+       case CH_SPI:
+               ret_irq = IRQ_SPI;
+               break;
+
+       case CH_UART_RX:
+               ret_irq = IRQ_UART_RX;
+               break;
+
+       case CH_UART_TX:
+               ret_irq = IRQ_UART_TX;
+               break;
+
+       case CH_MEM_STREAM0_SRC:
+       case CH_MEM_STREAM0_DEST:
+               ret_irq = IRQ_MEM_DMA0;
+               break;
+
+       case CH_MEM_STREAM1_SRC:
+       case CH_MEM_STREAM1_DEST:
+               ret_irq = IRQ_MEM_DMA1;
+               break;
+       }
+       return ret_irq;
+}
index 7d902bbd860fa652ce26722a899d5d277b86ac0c..429c8a1019dab0de10bc9e7dfdc2f1392994cc42 100644 (file)
@@ -30,6 +30,8 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 #include <asm/blackfin.h>
+#include <asm/trace.h>
+
 #if CONFIG_BFIN_KERNEL_CLOCK
 #include <asm/mach/mem_init.h>
 #endif
@@ -93,6 +95,10 @@ ENTRY(__start)
        M2 = r0;
        M3 = r0;
 
+       trace_buffer_start(p0,r0);
+       P0 = R1;
+       R0 = R1;
+
        /* Turn off the icache */
        p0.l = (IMEM_CONTROL & 0xFFFF);
        p0.h = (IMEM_CONTROL >> 16);
index 2dbf3df465d193ba085f09504ac0b96aee9732a5..a8b915f202ec8870162b2822bc79057e1e38a8b1 100644 (file)
@@ -28,8 +28,8 @@
  */
 
 #include <linux/module.h>
+#include <linux/irq.h>
 #include <asm/blackfin.h>
-#include <asm/irq.h>
 
 void program_IAR(void)
 {
diff --git a/arch/blackfin/mach-bf548/Kconfig b/arch/blackfin/mach-bf548/Kconfig
new file mode 100644 (file)
index 0000000..e78b03d
--- /dev/null
@@ -0,0 +1,316 @@
+if (BF54x)
+
+menu "BF548 Specific Configuration"
+
+comment "Interrupt Priority Assignment"
+menu "Priority"
+
+config IRQ_PLL_WAKEUP
+       int "IRQ_PLL_WAKEUP"
+       default 7
+config IRQ_DMAC0_ERR
+       int "IRQ_DMAC0_ERR"
+       default 7
+config IRQ_EPPI0_ERR
+       int "IRQ_EPPI0_ERR"
+       default 7
+config IRQ_SPORT0_ERR
+       int "IRQ_SPORT0_ERR"
+       default 7
+config IRQ_SPORT1_ERR
+       int "IRQ_SPORT1_ERR"
+       default 7
+config IRQ_SPI0_ERR
+       int "IRQ_SPI0_ERR"
+       default 7
+config IRQ_UART0_ERR
+       int "IRQ_UART0_ERR"
+       default 7
+config IRQ_RTC
+       int "IRQ_RTC"
+       default 8
+config IRQ_EPPI0
+       int "IRQ_EPPI0"
+       default 8
+config IRQ_SPORT0_RX
+       int "IRQ_SPORT0_RX"
+       default 9
+config IRQ_SPORT0_TX
+       int "IRQ_SPORT0_TX"
+       default 9
+config IRQ_SPORT1_RX
+       int "IRQ_SPORT1_RX"
+       default 9
+config IRQ_SPORT1_TX
+       int "IRQ_SPORT1_TX"
+       default 9
+config IRQ_SPI0
+       int "IRQ_SPI0"
+       default 10
+config IRQ_UART0_RX
+       int "IRQ_UART0_RX"
+       default 10
+config IRQ_UART0_TX
+       int "IRQ_UART0_TX"
+       default 10
+config IRQ_TIMER8
+       int "IRQ_TIMER8"
+       default 11
+config IRQ_TIMER9
+       int "IRQ_TIMER9"
+       default 11
+config IRQ_TIMER10
+       int "IRQ_TIMER10"
+       default 11
+config IRQ_PINT0
+       int "IRQ_PINT0"
+       default 12
+config IRQ_PINT1
+       int "IRQ_PINT0"
+       default 12
+config IRQ_MDMAS0
+       int "IRQ_MDMAS0"
+       default 13
+config IRQ_MDMAS1
+       int "IRQ_DMDMAS1"
+       default 13
+config IRQ_WATCHDOG
+       int "IRQ_WATCHDOG"
+       default 13
+config IRQ_DMAC1_ERR
+       int "IRQ_DMAC1_ERR"
+       default 7
+config IRQ_SPORT2_ERR
+       int "IRQ_SPORT2_ERR"
+       default 7
+config IRQ_SPORT3_ERR
+       int "IRQ_SPORT3_ERR"
+       default 7
+config IRQ_MXVR_DATA
+       int "IRQ MXVR Data"
+       default 7
+config IRQ_SPI1_ERR
+       int "IRQ_SPI1_ERR"
+       default 7
+config IRQ_SPI2_ERR
+       int "IRQ_SPI2_ERR"
+       default 7
+config IRQ_UART1_ERR
+       int "IRQ_UART1_ERR"
+       default 7
+config IRQ_UART2_ERR
+       int "IRQ_UART2_ERR"
+       default 7
+config IRQ_CAN0_ERR
+       int "IRQ_CAN0_ERR"
+       default 7
+config IRQ_SPORT2_RX
+       int "IRQ_SPORT2_RX"
+       default 9
+config IRQ_SPORT2_TX
+       int "IRQ_SPORT2_TX"
+       default 9
+config IRQ_SPORT3_RX
+       int "IRQ_SPORT3_RX"
+       default 9
+config IRQ_SPORT3_TX
+       int "IRQ_SPORT3_TX"
+       default 9
+config IRQ_EPPI1
+       int "IRQ_EPPI1"
+       default 9
+config IRQ_EPPI2
+       int "IRQ_EPPI2"
+       default 9
+config IRQ_SPI1
+       int "IRQ_SPI1"
+       default 10
+config IRQ_SPI2
+       int "IRQ_SPI2"
+       default 10
+config IRQ_UART1_RX
+       int "IRQ_UART1_RX"
+       default 10
+config IRQ_UART1_TX
+       int "IRQ_UART1_TX"
+       default 10
+config IRQ_ATAPI_RX
+       int "IRQ_ATAPI_RX"
+       default 10
+config IRQ_ATAPI_TX
+       int "IRQ_ATAPI_TX"
+       default 10
+config IRQ_TWI0
+       int "IRQ_TWI0"
+       default 11
+config IRQ_TWI1
+       int "IRQ_TWI1"
+       default 11
+config IRQ_CAN0_RX
+       int "IRQ_CAN_RX"
+       default 11
+config IRQ_CAN0_TX
+       int "IRQ_CAN_TX"
+       default 11
+config IRQ_MDMAS2
+       int "IRQ_MDMAS2"
+       default 13
+config IRQ_MDMAS3
+       int "IRQ_DMMAS3"
+       default 13
+config IRQ_MXVR_ERR
+       int "IRQ_MXVR_ERR"
+       default 11
+config IRQ_MXVR_MSG
+       int "IRQ_MXVR_MSG"
+       default 11
+config IRQ_MXVR_PKT
+       int "IRQ_MXVR_PKT"
+       default 11
+config IRQ_EPPI1_ERR
+       int "IRQ_EPPI1_ERR"
+       default 7
+config IRQ_EPPI2_ERR
+       int "IRQ_EPPI2_ERR"
+       default 7
+config IRQ_UART3_ERR
+       int "IRQ_UART3_ERR"
+       default 7
+config IRQ_HOST_ERR
+       int "IRQ_HOST_ERR"
+       default 7
+config IRQ_PIXC_ERR
+       int "IRQ_PIXC_ERR"
+       default 7
+config IRQ_NFC_ERR
+       int "IRQ_NFC_ERR"
+       default 7
+config IRQ_ATAPI_ERR
+       int "IRQ_ATAPI_ERR"
+       default 7
+config IRQ_CAN1_ERR
+       int "IRQ_CAN1_ERR"
+       default 7
+config IRQ_HS_DMA_ERR
+       int "IRQ Handshake DMA Status"
+       default 7
+config IRQ_PIXC_IN0
+       int "IRQ PIXC IN0"
+       default 8
+config IRQ_PIXC_IN1
+       int "IRQ PIXC IN1"
+       default 8
+config IRQ_PIXC_OUT
+       int "IRQ PIXC OUT"
+       default 8
+config IRQ_SDH
+       int "IRQ SDH"
+       default 8
+config IRQ_CNT
+       int "IRQ CNT"
+       default 8
+config IRQ_KEY
+       int "IRQ KEY"
+       default 8
+config IRQ_CAN1_RX
+       int "IRQ CAN1 RX"
+       default 11
+config IRQ_CAN1_TX
+       int "IRQ_CAN1_TX"
+       default 11
+config IRQ_SDH_MASK0
+       int "IRQ_SDH_MASK0"
+       default 11
+config IRQ_SDH_MASK1
+       int "IRQ_SDH_MASK1"
+       default 11
+config IRQ_USB_INT0
+       int "IRQ USB INT0"
+       default 11
+config IRQ_USB_INT1
+       int "IRQ USB INT1"
+       default 11
+config IRQ_USB_INT2
+       int "IRQ USB INT2"
+       default 11
+config IRQ_USB_DMA
+       int "IRQ USB DMA"
+       default 11
+config IRQ_OTPSEC
+       int "IRQ OPTSEC"
+       default 11
+config IRQ_TIMER0
+       int "IRQ_TIMER0"
+       default 11
+config IRQ_TIMER1
+       int "IRQ_TIMER1"
+       default 11
+config IRQ_TIMER2
+       int "IRQ_TIMER2"
+       default 11
+config IRQ_TIMER3
+       int "IRQ_TIMER3"
+       default 11
+config IRQ_TIMER4
+       int "IRQ_TIMER4"
+       default 11
+config IRQ_TIMER5
+       int "IRQ_TIMER5"
+       default 11
+config IRQ_TIMER6
+       int "IRQ_TIMER6"
+       default 11
+config IRQ_TIMER7
+       int "IRQ_TIMER7"
+       default 11
+config IRQ_PINT2
+       int "IRQ_PIN2"
+       default 11
+config IRQ_PINT3
+       int "IRQ_PIN3"
+       default 11
+
+       help
+         Enter the priority numbers between 7-13 ONLY.  Others are Reserved.
+         This applies to all the above.  It is not recommended to assign the
+         highest priority number 7 to UART or any other device.
+
+endmenu
+
+comment "Pin Interrupt to Port Assignment"
+menu "Assignment"
+
+config PINTx_REASSIGN
+       bool "Reprogram PINT Assignment"
+       default n
+       help
+         The interrupt assignment registers controls the pin-to-interrupt
+         assignment in a byte-wide manner. Each option allows you to select
+         a set of pins (High/Low Byte) of an specific Port being mapped
+         to one of the four PIN Interrupts IRQ_PINTx.
+
+         You shouldn't change any of these unless you know exactly what you're doing.
+         Please consult the Blackfin BF54x Processor Hardware Reference Manual.
+
+config PINT0_ASSIGN
+       hex "PINT0_ASSIGN"
+       depends on PINTx_REASSIGN
+       default 0x00000101
+config PINT1_ASSIGN
+       hex "PINT1_ASSIGN"
+       depends on PINTx_REASSIGN
+       default 0x01010000
+config PINT2_ASSIGN
+       hex "PINT2_ASSIGN"
+       depends on PINTx_REASSIGN
+       default 0x00000101
+config PINT3_ASSIGN
+       hex "PINT3_ASSIGN"
+       depends on PINTx_REASSIGN
+       default 0x02020303
+
+endmenu
+
+endmenu
+
+endif
diff --git a/arch/blackfin/mach-bf548/Makefile b/arch/blackfin/mach-bf548/Makefile
new file mode 100644 (file)
index 0000000..060ad78
--- /dev/null
@@ -0,0 +1,9 @@
+#
+# arch/blackfin/mach-bf537/Makefile
+#
+
+extra-y := head.o
+
+obj-y := ints-priority.o dma.o gpio.o
+
+obj-$(CONFIG_CPU_FREQ)   += cpu.o
diff --git a/arch/blackfin/mach-bf548/boards/Makefile b/arch/blackfin/mach-bf548/boards/Makefile
new file mode 100644 (file)
index 0000000..486e07c
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# arch/blackfin/mach-bf548/boards/Makefile
+#
+
+obj-$(CONFIG_BFIN548_EZKIT)            += ezkit.o led.o
diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c
new file mode 100644 (file)
index 0000000..96ad95f
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * File:         arch/blackfin/mach-bf548/boards/ezkit.c
+ * Based on:     arch/blackfin/mach-bf537/boards/ezkit.c
+ * Author:       Aidan Williams <aidan@nicta.com.au>
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ *               Copyright 2005 National ICT Australia (NICTA)
+ *               Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/irq.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <asm/bfin5xx_spi.h>
+
+/*
+ * Name the Board for the /proc/cpuinfo
+ */
+char *bfin_board_name = "ADSP-BF548-EZKIT";
+
+/*
+ *  Driver needs to know address, irq and flag pin.
+ */
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+static struct platform_device rtc_device = {
+       .name = "rtc-bfin",
+       .id   = -1,
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       {
+               .start = 0xFFC00400,
+               .end = 0xFFC004FF,
+               .flags = IORESOURCE_MEM,
+       },
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+       {
+               .start = 0xFFC02000,
+               .end = 0xFFC020FF,
+               .flags = IORESOURCE_MEM,
+       },
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART2
+       {
+               .start = 0xFFC02100,
+               .end = 0xFFC021FF,
+               .flags = IORESOURCE_MEM,
+       },
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART3
+       {
+               .start = 0xFFC03100,
+               .end = 0xFFC031FF,
+       },
+#endif
+};
+
+static struct platform_device bfin_uart_device = {
+       .name = "bfin-uart",
+       .id = 1,
+       .num_resources = ARRAY_SIZE(bfin_uart_resources),
+       .resource = bfin_uart_resources,
+};
+#endif
+
+static struct platform_device *ezkit_devices[] __initdata = {
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+       &rtc_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+       &bfin_uart_device,
+#endif
+};
+
+static int __init stamp_init(void)
+{
+       printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
+       platform_add_devices(ezkit_devices, ARRAY_SIZE(ezkit_devices));
+       return 0;
+}
+
+arch_initcall(stamp_init);
diff --git a/arch/blackfin/mach-bf548/boards/led.S b/arch/blackfin/mach-bf548/boards/led.S
new file mode 100644 (file)
index 0000000..f47daf3
--- /dev/null
@@ -0,0 +1,172 @@
+/****************************************************
+ * LED1 ---- PG6        LED2 ---- PG7               *
+ * LED3 ---- PG8        LED4 ---- PG9               *
+ * LED5 ---- PG10       LED6 ---- PG11              *
+ ****************************************************/
+
+#include <linux/linkage.h>
+#include <asm/blackfin.h>
+
+/* All functions in this file save the registers they uses.
+   So there is no need to save any registers before calling them.  */
+
+       .text;
+
+/* Initialize LEDs.  */
+
+ENTRY(_led_init)
+       LINK 0;
+       [--SP] = P0;
+       [--SP] = R0;
+       [--SP] = R1;
+       [--SP] = R2;
+       R1 = (PG6|PG7|PG8|PG9|PG10|PG11)(Z);
+       R2 = ~R1;
+
+       P0.H = hi(PORTG_FER);
+       P0.L = lo(PORTG_FER);
+       R0 = W[P0](Z);
+       SSYNC;
+       R0 = R0 & R2;
+       W[P0] = R0.L;
+       SSYNC;
+
+       P0.H = hi(PORTG_DIR_SET);
+       P0.L = lo(PORTG_DIR_SET);
+       W[P0] = R1.L;
+       SSYNC;
+
+       P0.H = hi(PORTG_INEN);
+       P0.L = lo(PORTG_INEN);
+       R0 = W[P0](Z);
+       SSYNC;
+       R0 = R0 & R2;
+       W[P0] = R0.L;
+       SSYNC;
+
+       R2 = [SP++];
+       R1 = [SP++];
+       R0 = [SP++];
+       P0 = [SP++];
+       RTS;
+       .size   _led_init, .-_led_init
+
+/* Set one LED on. Leave other LEDs unchanged.
+   It expects the LED number passed through R0.  */
+
+ENTRY(_led_on)
+       LINK 0;
+       [--SP] = P0;
+       [--SP] = R1;
+       CALL _led_init;
+       R1 = 1;
+       R0 += 5;
+       R1 <<= R0;
+       P0.H = hi(PORTG_SET);
+       P0.L = lo(PORTG_SET);
+       W[P0] = R1.L;
+       SSYNC;
+       R1 = [SP++];
+       P0 = [SP++];
+       UNLINK;
+       RTS;
+       .size   _led_on, .-_led_on
+
+/* Set one LED off. Leave other LEDs unchanged.  */
+
+ENTRY(_led_off)
+       LINK 0;
+       [--SP] = P0;
+       [--SP] = R1;
+       CALL _led_init;
+       R1 = 1;
+       R0 += 5;
+       R1 <<= R0;
+       P0.H = hi(PORTG_CLEAR);
+       P0.L = lo(PORTG_CLEAR);
+       W[P0] = R1.L;
+       SSYNC;
+       R1 = [SP++];
+       P0 = [SP++];
+       UNLINK;
+       RTS;
+       .size   _led_off, .-_led_off
+
+/* Toggle one LED. Leave other LEDs unchanged.  */
+
+ENTRY(_led_toggle)
+       LINK 0;
+       [--SP] = P0;
+       [--SP] = R1;
+       CALL _led_init;
+       R1 = 1;
+       R0 += 5;
+       R1 <<= R0;
+       P0.H = hi(PORTG);
+       P0.L = lo(PORTG);
+       R0 = W[P0](Z);
+       SSYNC;
+       R0 = R0 ^ R1;
+       W[P0] = R0.L;
+       SSYNC;
+       R1 = [SP++];
+       P0 = [SP++];
+       UNLINK;
+       RTS;
+       .size   _led_toggle, .-_led_toggle
+
+/* Display the number using LEDs in binary format.  */
+
+ENTRY(_led_disp_num)
+       LINK 0;
+       [--SP] = P0;
+       [--SP] = R1;
+       [--SP] = R2;
+       CALL _led_init;
+       R1 = 0x3f(X);
+       R0 = R0 & R1;
+       R2 = 6(X);
+       R0 <<= R2;
+       R1 <<= R2;
+       P0.H = hi(PORTG);
+       P0.L = lo(PORTG);
+       R2 = W[P0](Z);
+       SSYNC;
+       R1 = ~R1;
+       R2 = R2 & R1;
+       R2 = R2 | R0;
+       W[P0] = R2.L;
+       SSYNC;
+       R2 = [SP++];
+       R1 = [SP++];
+       P0 = [SP++];
+       UNLINK;
+       RTS;
+       .size   _led_disp_num, .-_led_disp_num
+
+/* Toggle the number using LEDs in binary format.  */
+
+ENTRY(_led_toggle_num)
+       LINK 0;
+       [--SP] = P0;
+       [--SP] = R1;
+       [--SP] = R2;
+       CALL _led_init;
+       R1 = 0x3f(X);
+       R0 = R0 & R1;
+       R1 = 6(X);
+       R0 <<= R1;
+       P0.H = hi(PORTG);
+       P0.L = lo(PORTG);
+       R1 = W[P0](Z);
+       SSYNC;
+       R1 = R1 ^ R0;
+       W[P0] = R1.L;
+       SSYNC;
+       R2 = [SP++];
+       R1 = [SP++];
+       P0 = [SP++];
+       UNLINK;
+       RTS;
+       .size   _led_toggle_num, .-_led_toggle_num
+
diff --git a/arch/blackfin/mach-bf548/cpu.c b/arch/blackfin/mach-bf548/cpu.c
new file mode 100644 (file)
index 0000000..4298a3c
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * File:         arch/blackfin/mach-bf548/cpu.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:  clock scaling for the bf54x
+ *
+ * Modified:
+ *               Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <asm/dpmc.h>
+#include <linux/fs.h>
+#include <asm/bfin-global.h>
+
+/* CONFIG_CLKIN_HZ=25000000 */
+#define VCO5 (CONFIG_CLKIN_HZ*45)
+#define VCO4 (CONFIG_CLKIN_HZ*36)
+#define VCO3 (CONFIG_CLKIN_HZ*27)
+#define VCO2 (CONFIG_CLKIN_HZ*18)
+#define VCO1 (CONFIG_CLKIN_HZ*9)
+#define VCO(x) VCO##x
+
+#define MFREQ(x) {VCO(x),VCO(x)/4},{VCO(x),VCO(x)/2},{VCO(x),VCO(x)}
+/* frequency */
+static struct cpufreq_frequency_table bf548_freq_table[] = {
+       MFREQ(1),
+       MFREQ(3),
+       {VCO4, VCO4 / 2}, {VCO4, VCO4},
+       MFREQ(5),
+       {0, CPUFREQ_TABLE_END},
+};
+
+/*
+ * dpmc_fops->ioctl()
+ * static int dpmc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+ */
+static int bf548_getfreq(unsigned int cpu)
+{
+       unsigned long cclk_mhz;
+
+       /* The driver only support single cpu */
+       if (cpu == 0)
+               dpmc_fops.ioctl(NULL, NULL, IOCTL_GET_CORECLOCK, &cclk_mhz);
+       else
+               cclk_mhz = -1;
+
+       return cclk_mhz;
+}
+
+static int bf548_target(struct cpufreq_policy *policy,
+                           unsigned int target_freq, unsigned int relation)
+{
+       unsigned long cclk_mhz;
+       unsigned long vco_mhz;
+       unsigned long flags;
+       unsigned int index;
+       struct cpufreq_freqs freqs;
+
+       if (cpufreq_frequency_table_target(policy, bf548_freq_table, target_freq, relation, &index))
+               return -EINVAL;
+
+       cclk_mhz = bf548_freq_table[index].frequency;
+       vco_mhz = bf548_freq_table[index].index;
+
+       dpmc_fops.ioctl(NULL, NULL, IOCTL_CHANGE_FREQUENCY, &vco_mhz);
+       freqs.old = bf548_getfreq(0);
+       freqs.new = cclk_mhz;
+       freqs.cpu = 0;
+
+       pr_debug("cclk begin change to cclk %d,vco=%d,index=%d,target=%d,oldfreq=%d\n",
+                cclk_mhz, vco_mhz, index, target_freq, freqs.old);
+
+       cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+       local_irq_save(flags);
+       dpmc_fops.ioctl(NULL, NULL, IOCTL_SET_CCLK, &cclk_mhz);
+       local_irq_restore(flags);
+       cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+       vco_mhz = get_vco();
+       cclk_mhz = get_cclk();
+       return 0;
+}
+
+/* make sure that only the "userspace" governor is run -- anything else wouldn't make sense on
+ * this platform, anyway.
+ */
+static int bf548_verify_speed(struct cpufreq_policy *policy)
+{
+       return cpufreq_frequency_table_verify(policy, &bf548_freq_table);
+}
+
+static int __init __bf548_cpu_init(struct cpufreq_policy *policy)
+{
+       if (policy->cpu != 0)
+               return -EINVAL;
+
+       policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+
+       policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+       /*Now ,only support one cpu */
+       policy->cur = bf548_getfreq(0);
+       cpufreq_frequency_table_get_attr(bf548_freq_table, policy->cpu);
+       return cpufreq_frequency_table_cpuinfo(policy, bf548_freq_table);
+}
+
+static struct freq_attr *bf548_freq_attr[] = {
+       &cpufreq_freq_attr_scaling_available_freqs,
+       NULL,
+};
+
+static struct cpufreq_driver bf548_driver = {
+       .verify = bf548_verify_speed,
+       .target = bf548_target,
+       .get = bf548_getfreq,
+       .init = __bf548_cpu_init,
+       .name = "bf548",
+       .owner = THIS_MODULE,
+       .attr = bf548_freq_attr,
+};
+
+static int __init bf548_cpu_init(void)
+{
+       return cpufreq_register_driver(&bf548_driver);
+}
+
+static void __exit bf548_cpu_exit(void)
+{
+       cpufreq_unregister_driver(&bf548_driver);
+}
+
+MODULE_AUTHOR("Mickael Kang");
+MODULE_DESCRIPTION("cpufreq driver for BF548 CPU");
+MODULE_LICENSE("GPL");
+
+module_init(bf548_cpu_init);
+module_exit(bf548_cpu_exit);
diff --git a/arch/blackfin/mach-bf548/dma.c b/arch/blackfin/mach-bf548/dma.c
new file mode 100644 (file)
index 0000000..a818411
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * File:         arch/blackfin/mach-bf561/dma.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:  This file contains the simple DMA Implementation for Blackfin
+ *
+ * Modified:
+ *               Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <asm/blackfin.h>
+#include <asm/dma.h>
+
+ struct dma_register *base_addr[MAX_BLACKFIN_DMA_CHANNEL] = {
+       (struct dma_register *) DMA0_NEXT_DESC_PTR,
+       (struct dma_register *) DMA1_NEXT_DESC_PTR,
+       (struct dma_register *) DMA2_NEXT_DESC_PTR,
+       (struct dma_register *) DMA3_NEXT_DESC_PTR,
+       (struct dma_register *) DMA4_NEXT_DESC_PTR,
+       (struct dma_register *) DMA5_NEXT_DESC_PTR,
+       (struct dma_register *) DMA6_NEXT_DESC_PTR,
+       (struct dma_register *) DMA7_NEXT_DESC_PTR,
+       (struct dma_register *) DMA8_NEXT_DESC_PTR,
+       (struct dma_register *) DMA9_NEXT_DESC_PTR,
+       (struct dma_register *) DMA10_NEXT_DESC_PTR,
+       (struct dma_register *) DMA11_NEXT_DESC_PTR,
+       (struct dma_register *) DMA12_NEXT_DESC_PTR,
+       (struct dma_register *) DMA13_NEXT_DESC_PTR,
+       (struct dma_register *) DMA14_NEXT_DESC_PTR,
+       (struct dma_register *) DMA15_NEXT_DESC_PTR,
+       (struct dma_register *) DMA16_NEXT_DESC_PTR,
+       (struct dma_register *) DMA17_NEXT_DESC_PTR,
+       (struct dma_register *) DMA18_NEXT_DESC_PTR,
+       (struct dma_register *) DMA19_NEXT_DESC_PTR,
+       (struct dma_register *) DMA20_NEXT_DESC_PTR,
+       (struct dma_register *) DMA21_NEXT_DESC_PTR,
+       (struct dma_register *) DMA22_NEXT_DESC_PTR,
+       (struct dma_register *) DMA23_NEXT_DESC_PTR,
+       (struct dma_register *) MDMA_D0_NEXT_DESC_PTR,
+       (struct dma_register *) MDMA_S0_NEXT_DESC_PTR,
+       (struct dma_register *) MDMA_D1_NEXT_DESC_PTR,
+       (struct dma_register *) MDMA_S1_NEXT_DESC_PTR,
+       (struct dma_register *) MDMA_D2_NEXT_DESC_PTR,
+       (struct dma_register *) MDMA_S2_NEXT_DESC_PTR,
+       (struct dma_register *) MDMA_D3_NEXT_DESC_PTR,
+       (struct dma_register *) MDMA_S3_NEXT_DESC_PTR,
+};
+
+int channel2irq(unsigned int channel)
+{
+       int ret_irq = -1;
+
+       switch (channel) {
+       case CH_SPORT0_RX:
+               ret_irq = IRQ_SPORT0_RX;
+               break;
+       case CH_SPORT0_TX:
+               ret_irq = IRQ_SPORT0_TX;
+               break;
+       case CH_SPORT1_RX:
+               ret_irq = IRQ_SPORT1_RX;
+               break;
+       case CH_SPORT1_TX:
+               ret_irq = IRQ_SPORT1_TX;
+       case CH_SPI0:
+               ret_irq = IRQ_SPI0;
+               break;
+       case CH_SPI1:
+               ret_irq = IRQ_SPI1;
+               break;
+       case CH_UART0_RX:
+               ret_irq = IRQ_UART_RX;
+               break;
+       case CH_UART0_TX:
+               ret_irq = IRQ_UART_TX;
+               break;
+       case CH_UART1_RX:
+               ret_irq = IRQ_UART_RX;
+               break;
+       case CH_UART1_TX:
+               ret_irq = IRQ_UART_TX;
+               break;
+       case CH_EPPI0:
+               ret_irq = IRQ_EPPI0;
+               break;
+       case CH_EPPI1:
+               ret_irq = IRQ_EPPI1;
+               break;
+       case CH_EPPI2:
+               ret_irq = IRQ_EPPI2;
+               break;
+       case CH_PIXC_IMAGE:
+               ret_irq = IRQ_PIXC_IN0;
+               break;
+       case CH_PIXC_OVERLAY:
+               ret_irq = IRQ_PIXC_IN1;
+               break;
+       case CH_PIXC_OUTPUT:
+               ret_irq = IRQ_PIXC_OUT;
+               break;
+       case CH_SPORT2_RX:
+               ret_irq = IRQ_SPORT2_RX;
+               break;
+       case CH_SPORT2_TX:
+               ret_irq = IRQ_SPORT2_TX;
+               break;
+       case CH_SPORT3_RX:
+               ret_irq = IRQ_SPORT3_RX;
+               break;
+       case CH_SPORT3_TX:
+               ret_irq = IRQ_SPORT3_TX;
+               break;
+       case CH_SDH:
+               ret_irq = IRQ_SDH;
+               break;
+       case CH_SPI2:
+               ret_irq = IRQ_SPI2;
+               break;
+       case CH_MEM_STREAM0_SRC:
+       case CH_MEM_STREAM0_DEST:
+               ret_irq = IRQ_MDMAS0;
+               break;
+       case CH_MEM_STREAM1_SRC:
+       case CH_MEM_STREAM1_DEST:
+               ret_irq = IRQ_MDMAS1;
+               break;
+       case CH_MEM_STREAM2_SRC:
+       case CH_MEM_STREAM2_DEST:
+               ret_irq = IRQ_MDMAS2;
+               break;
+       case CH_MEM_STREAM3_SRC:
+       case CH_MEM_STREAM3_DEST:
+               ret_irq = IRQ_MDMAS3;
+               break;
+       }
+       return ret_irq;
+}
diff --git a/arch/blackfin/mach-bf548/gpio.c b/arch/blackfin/mach-bf548/gpio.c
new file mode 100644 (file)
index 0000000..0da5f00
--- /dev/null
@@ -0,0 +1,323 @@
+/*
+ * File:         arch/blackfin/mach-bf548/gpio.c
+ * Based on:
+ * Author:       Michael Hennerich (hennerich@blackfin.uclinux.org)
+ *
+ * Created:
+ * Description:  GPIO Abstraction Layer
+ *
+ * Modified:
+ *               Copyright 2007 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/module.h>
+#include <linux/err.h>
+#include <asm/blackfin.h>
+#include <asm/gpio.h>
+#include <asm/portmux.h>
+#include <linux/irq.h>
+
+static struct gpio_port_t *gpio_array[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
+       (struct gpio_port_t *)PORTA_FER,
+       (struct gpio_port_t *)PORTB_FER,
+       (struct gpio_port_t *)PORTC_FER,
+       (struct gpio_port_t *)PORTD_FER,
+       (struct gpio_port_t *)PORTE_FER,
+       (struct gpio_port_t *)PORTF_FER,
+       (struct gpio_port_t *)PORTG_FER,
+       (struct gpio_port_t *)PORTH_FER,
+       (struct gpio_port_t *)PORTI_FER,
+       (struct gpio_port_t *)PORTJ_FER,
+};
+
+static unsigned short reserved_gpio_map[gpio_bank(MAX_BLACKFIN_GPIOS)];
+static unsigned short reserved_peri_map[gpio_bank(MAX_BLACKFIN_GPIOS)];
+
+inline int check_gpio(unsigned short gpio)
+{
+       if (gpio == GPIO_PB15 || gpio == GPIO_PC14 || gpio == GPIO_PC15
+           || gpio == GPIO_PH14 || gpio == GPIO_PH15
+           || gpio == GPIO_PJ14 || gpio == GPIO_PJ15
+           || gpio > MAX_BLACKFIN_GPIOS)
+               return -EINVAL;
+       return 0;
+}
+
+inline void portmux_setup(unsigned short portno, unsigned short function)
+{
+       u32 pmux;
+
+       pmux = gpio_array[gpio_bank(portno)]->port_mux;
+
+       pmux &= ~(0x3 << (2 * gpio_sub_n(portno)));
+       pmux |= (function & 0x3) << (2 * gpio_sub_n(portno));
+
+       gpio_array[gpio_bank(portno)]->port_mux = pmux;
+
+}
+
+inline u16 get_portmux(unsigned short portno)
+{
+       u32 pmux;
+
+       pmux = gpio_array[gpio_bank(portno)]->port_mux;
+
+       return (pmux >> (2 * gpio_sub_n(portno)) & 0x3);
+
+}
+
+static void port_setup(unsigned short gpio, unsigned short usage)
+{
+       if (usage == GPIO_USAGE) {
+               if (gpio_array[gpio_bank(gpio)]->port_fer & gpio_bit(gpio))
+                       printk(KERN_WARNING
+                              "bfin-gpio: Possible Conflict with Peripheral "
+                              "usage and GPIO %d detected!\n", gpio);
+               gpio_array[gpio_bank(gpio)]->port_fer &= ~gpio_bit(gpio);
+       } else
+               gpio_array[gpio_bank(gpio)]->port_fer |= gpio_bit(gpio);
+       SSYNC();
+}
+
+static int __init bfin_gpio_init(void)
+{
+       printk(KERN_INFO "Blackfin GPIO Controller\n");
+
+       return 0;
+}
+
+arch_initcall(bfin_gpio_init);
+
+int peripheral_request(unsigned short per, const char *label)
+{
+       unsigned long flags;
+       unsigned short ident = P_IDENT(per);
+
+       if (!(per & P_DEFINED))
+               return -ENODEV;
+
+       if (check_gpio(ident) < 0)
+               return -EINVAL;
+
+       local_irq_save(flags);
+
+       if (unlikely(reserved_gpio_map[gpio_bank(ident)] & gpio_bit(ident))) {
+               printk(KERN_ERR
+                      "%s: Peripheral %d is already reserved as GPIO!\n",
+                      __FUNCTION__, per);
+               dump_stack();
+               local_irq_restore(flags);
+               return -EBUSY;
+       }
+
+       if (unlikely(reserved_peri_map[gpio_bank(ident)] & gpio_bit(ident))) {
+
+               u16 funct = get_portmux(ident);
+
+               if (!((per & P_MAYSHARE) && (funct == P_FUNCT2MUX(per)))) {
+                       printk(KERN_ERR
+                              "%s: Peripheral %d is already reserved!\n",
+                              __FUNCTION__, per);
+                       dump_stack();
+                       local_irq_restore(flags);
+                       return -EBUSY;
+               }
+       }
+
+       reserved_peri_map[gpio_bank(ident)] |= gpio_bit(ident);
+
+       portmux_setup(ident, P_FUNCT2MUX(per));
+       port_setup(ident, PERIPHERAL_USAGE);
+
+       local_irq_restore(flags);
+
+       return 0;
+}
+EXPORT_SYMBOL(peripheral_request);
+
+int peripheral_request_list(unsigned short per[], const char *label)
+{
+
+       u16 cnt;
+       int ret;
+
+       for (cnt = 0; per[cnt] != 0; cnt++) {
+               ret = peripheral_request(per[cnt], label);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(peripheral_request_list);
+
+void peripheral_free(unsigned short per)
+{
+       unsigned long flags;
+       unsigned short ident = P_IDENT(per);
+
+       if (!(per & P_DEFINED))
+               return;
+
+       if (check_gpio(ident) < 0)
+               return;
+
+       local_irq_save(flags);
+
+       if (unlikely(!(reserved_peri_map[gpio_bank(ident)] & gpio_bit(ident)))) {
+               printk(KERN_ERR "bfin-gpio: Peripheral %d wasn't reserved!\n", per);
+               dump_stack();
+               local_irq_restore(flags);
+               return;
+       }
+
+       if (!(per & P_MAYSHARE)) {
+               port_setup(ident, GPIO_USAGE);
+       }
+
+       reserved_peri_map[gpio_bank(ident)] &= ~gpio_bit(ident);
+
+       local_irq_restore(flags);
+}
+EXPORT_SYMBOL(peripheral_free);
+
+void peripheral_free_list(unsigned short per[])
+{
+       u16 cnt;
+
+       for (cnt = 0; per[cnt] != 0; cnt++) {
+               peripheral_free(per[cnt]);
+       }
+
+}
+EXPORT_SYMBOL(peripheral_free_list);
+
+/***********************************************************
+*
+* FUNCTIONS: Blackfin GPIO Driver
+*
+* INPUTS/OUTPUTS:
+* gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS
+*
+*
+* DESCRIPTION: Blackfin GPIO Driver API
+*
+* CAUTION:
+*************************************************************
+* MODIFICATION HISTORY :
+**************************************************************/
+
+int gpio_request(unsigned short gpio, const char *label)
+{
+       unsigned long flags;
+
+       if (check_gpio(gpio) < 0)
+               return -EINVAL;
+
+       local_irq_save(flags);
+
+       if (unlikely(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
+               printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved!\n", gpio);
+               dump_stack();
+               local_irq_restore(flags);
+               return -EBUSY;
+       }
+
+       if (unlikely(reserved_peri_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
+               printk(KERN_ERR
+                      "bfin-gpio: GPIO %d is already reserved as Peripheral!\n", gpio);
+               dump_stack();
+               local_irq_restore(flags);
+               return -EBUSY;
+       }
+
+       reserved_gpio_map[gpio_bank(gpio)] |= gpio_bit(gpio);
+
+       local_irq_restore(flags);
+
+       port_setup(gpio, GPIO_USAGE);
+
+       return 0;
+}
+EXPORT_SYMBOL(gpio_request);
+
+void gpio_free(unsigned short gpio)
+{
+       unsigned long flags;
+
+       if (check_gpio(gpio) < 0)
+               return;
+
+       local_irq_save(flags);
+
+       if (unlikely(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)))) {
+               printk(KERN_ERR "bfin-gpio: GPIO %d wasn't reserved!\n", gpio);
+               dump_stack();
+               local_irq_restore(flags);
+               return;
+       }
+
+       reserved_gpio_map[gpio_bank(gpio)] &= ~gpio_bit(gpio);
+
+       local_irq_restore(flags);
+}
+EXPORT_SYMBOL(gpio_free);
+
+void gpio_direction_input(unsigned short gpio)
+{
+       unsigned long flags;
+
+       BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
+
+       local_irq_save(flags);
+       gpio_array[gpio_bank(gpio)]->port_dir_clear = gpio_bit(gpio);
+       gpio_array[gpio_bank(gpio)]->port_inen |= gpio_bit(gpio);
+       local_irq_restore(flags);
+}
+EXPORT_SYMBOL(gpio_direction_input);
+
+void gpio_direction_output(unsigned short gpio)
+{
+       unsigned long flags;
+
+       BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
+
+       local_irq_save(flags);
+       gpio_array[gpio_bank(gpio)]->port_inen &= ~gpio_bit(gpio);
+       gpio_array[gpio_bank(gpio)]->port_dir_set = gpio_bit(gpio);
+       local_irq_restore(flags);
+}
+EXPORT_SYMBOL(gpio_direction_output);
+
+void gpio_set_value(unsigned short gpio, unsigned short arg)
+{
+       if (arg)
+               gpio_array[gpio_bank(gpio)]->port_set = gpio_bit(gpio);
+       else
+               gpio_array[gpio_bank(gpio)]->port_clear = gpio_bit(gpio);
+
+}
+EXPORT_SYMBOL(gpio_set_value);
+
+unsigned short gpio_get_value(unsigned short gpio)
+{
+       return (1 & (gpio_array[gpio_bank(gpio)]->port_data >> gpio_sub_n(gpio)));
+}
+EXPORT_SYMBOL(gpio_get_value);
diff --git a/arch/blackfin/mach-bf548/head.S b/arch/blackfin/mach-bf548/head.S
new file mode 100644 (file)
index 0000000..06751ae
--- /dev/null
@@ -0,0 +1,512 @@
+/*
+ * File:         arch/blackfin/mach-bf548/head.S
+ * Based on:     arch/blackfin/mach-bf537/head.S
+ * Author:       Jeff Dionne <jeff@uclinux.org> COPYRIGHT 1998 D. Jeff Dionne
+ *
+ * Created:      1998
+ * Description:  Startup code for Blackfin BF548
+ *
+ * Modified:
+ *               Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/linkage.h>
+#include <asm/blackfin.h>
+#include <asm/trace.h>
+#if CONFIG_BFIN_KERNEL_CLOCK
+#include <asm/mach/mem_init.h>
+#endif
+
+.global __rambase
+.global __ramstart
+.global __ramend
+.extern ___bss_stop
+.extern ___bss_start
+.extern _bf53x_relocate_l1_mem
+
+#define INITIAL_STACK   0xFFB01000
+
+.text
+
+ENTRY(__start)
+ENTRY(__stext)
+       /* R0: argument of command line string, passed from uboot, save it */
+       R7 = R0;
+       /* Set the SYSCFG register */
+       R0 = 0x36;
+       SYSCFG = R0;   /*Enable Cycle Counter and Nesting Of Interrupts(3rd Bit)*/
+       R0 = 0;
+
+       /* Clear Out All the data and pointer  Registers*/
+       R1 = R0;
+       R2 = R0;
+       R3 = R0;
+       R4 = R0;
+       R5 = R0;
+       R6 = R0;
+
+       P0 = R0;
+       P1 = R0;
+       P2 = R0;
+       P3 = R0;
+       P4 = R0;
+       P5 = R0;
+
+       LC0 = r0;
+       LC1 = r0;
+       L0 = r0;
+       L1 = r0;
+       L2 = r0;
+       L3 = r0;
+
+       /* Clear Out All the DAG Registers*/
+       B0 = r0;
+       B1 = r0;
+       B2 = r0;
+       B3 = r0;
+
+       I0 = r0;
+       I1 = r0;
+       I2 = r0;
+       I3 = r0;
+
+       M0 = r0;
+       M1 = r0;
+       M2 = r0;
+       M3 = r0;
+
+       trace_buffer_start(p0,r0);
+       P0 = R1;
+       R0 = R1;
+
+       /* Turn off the icache */
+       p0.l = (IMEM_CONTROL & 0xFFFF);
+       p0.h = (IMEM_CONTROL >> 16);
+       R1 = [p0];
+       R0 = ~ENICPLB;
+       R0 = R0 & R1;
+       [p0] = R0;
+       SSYNC;
+
+       /* Turn off the dcache */
+       p0.l = (DMEM_CONTROL & 0xFFFF);
+       p0.h = (DMEM_CONTROL >> 16);
+       R1 = [p0];
+       R0 = ~ENDCPLB;
+       R0 = R0 & R1;
+       [p0] = R0;
+       SSYNC;
+
+       /* Initialize stack pointer */
+       SP.L = LO(INITIAL_STACK);
+       SP.H = HI(INITIAL_STACK);
+       FP = SP;
+       USP = SP;
+
+       /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */
+       call _bf53x_relocate_l1_mem;
+#if CONFIG_BFIN_KERNEL_CLOCK
+       call _start_dma_code;
+#endif
+       /* Code for initializing Async memory banks */
+
+       p2.h = hi(EBIU_AMBCTL1);
+       p2.l = lo(EBIU_AMBCTL1);
+       r0.h = hi(AMBCTL1VAL);
+       r0.l = lo(AMBCTL1VAL);
+       [p2] = r0;
+       ssync;
+
+       p2.h = hi(EBIU_AMBCTL0);
+       p2.l = lo(EBIU_AMBCTL0);
+       r0.h = hi(AMBCTL0VAL);
+       r0.l = lo(AMBCTL0VAL);
+       [p2] = r0;
+       ssync;
+
+       p2.h = hi(EBIU_AMGCTL);
+       p2.l = lo(EBIU_AMGCTL);
+       r0 = AMGCTLVAL;
+       w[p2] = r0;
+       ssync;
+
+       /* This section keeps the processor in supervisor mode
+        * during kernel boot.  Switches to user mode at end of boot.
+        * See page 3-9 of Hardware Reference manual for documentation.
+        */
+
+       /* EVT15 = _real_start */
+
+       p0.l = lo(EVT15);
+       p0.h = hi(EVT15);
+       p1.l = _real_start;
+       p1.h = _real_start;
+       [p0] = p1;
+       csync;
+
+       p0.l = lo(IMASK);
+       p0.h = hi(IMASK);
+       p1.l = IMASK_IVG15;
+       p1.h = 0x0;
+       [p0] = p1;
+       csync;
+
+       raise 15;
+       p0.l = .LWAIT_HERE;
+       p0.h = .LWAIT_HERE;
+       reti = p0;
+#if defined (ANOMALY_05000281)
+       nop;
+       nop;
+       nop;
+#endif
+       rti;
+
+.LWAIT_HERE:
+       jump .LWAIT_HERE;
+
+ENTRY(_real_start)
+       [ -- sp ] = reti;
+       p0.l = lo(WDOG_CTL);
+       p0.h = hi(WDOG_CTL);
+       r0 = 0xAD6(z);
+       w[p0] = r0;     /* watchdog off for now */
+       ssync;
+
+       /* Code update for BSS size == 0
+        * Zero out the bss region.
+        */
+
+       p1.l = ___bss_start;
+       p1.h = ___bss_start;
+       p2.l = ___bss_stop;
+       p2.h = ___bss_stop;
+       r0 = 0;
+       p2 -= p1;
+       lsetup (.L_clear_bss, .L_clear_bss ) lc0 = p2;
+.L_clear_bss:
+       B[p1++] = r0;
+
+       /* In case there is a NULL pointer reference
+        * Zero out region before stext
+        */
+
+       p1.l = 0x0;
+       p1.h = 0x0;
+       r0.l = __stext;
+       r0.h = __stext;
+       r0 = r0 >> 1;
+       p2 = r0;
+       r0 = 0;
+       lsetup (.L_clear_zero, .L_clear_zero ) lc0 = p2;
+.L_clear_zero:
+       W[p1++] = r0;
+
+       /* pass the uboot arguments to the global value command line */
+       R0 = R7;
+       call _cmdline_init;
+
+       p1.l = __rambase;
+       p1.h = __rambase;
+       r0.l = __sdata;
+       r0.h = __sdata;
+       [p1] = r0;
+
+       p1.l = __ramstart;
+       p1.h = __ramstart;
+       p3.l = ___bss_stop;
+       p3.h = ___bss_stop;
+
+       r1 = p3;
+       [p1] = r1;
+
+
+       /*
+        *  load the current thread pointer and stack
+        */
+       r1.l = _init_thread_union;
+       r1.h = _init_thread_union;
+
+       r2.l = 0x2000;
+       r2.h = 0x0000;
+       r1 = r1 + r2;
+       sp = r1;
+       usp = sp;
+       fp = sp;
+       call _start_kernel;
+.L_exit:
+       jump.s  .L_exit;
+
+.section .l1.text
+#if CONFIG_BFIN_KERNEL_CLOCK
+ENTRY(_start_dma_code)
+
+       /* Enable PHY CLK buffer output */
+       p0.h = hi(VR_CTL);
+       p0.l = lo(VR_CTL);
+       r0.l = w[p0];
+       bitset(r0, 14);
+       w[p0] = r0.l;
+       ssync;
+
+       p0.h = hi(SIC_IWR);
+       p0.l = lo(SIC_IWR);
+       r0.l = 0x1;
+       r0.h = 0x0;
+       [p0] = r0;
+       SSYNC;
+
+       /*
+        *  Set PLL_CTL
+        *   - [14:09] = MSEL[5:0] : CLKIN / VCO multiplication factors
+        *   - [8]     = BYPASS    : BYPASS the PLL, run CLKIN into CCLK/SCLK
+        *   - [7]     = output delay (add 200ps of delay to mem signals)
+        *   - [6]     = input delay (add 200ps of input delay to mem signals)
+        *   - [5]     = PDWN      : 1=All Clocks off
+        *   - [3]     = STOPCK    : 1=Core Clock off
+        *   - [1]     = PLL_OFF   : 1=Disable Power to PLL
+        *   - [0]     = DF        : 1=Pass CLKIN/2 to PLL / 0=Pass CLKIN to PLL
+        *   all other bits set to zero
+        */
+
+       p0.h = hi(PLL_LOCKCNT);
+       p0.l = lo(PLL_LOCKCNT);
+       r0 = 0x300(Z);
+       w[p0] = r0.l;
+       ssync;
+
+       P2.H = hi(EBIU_SDGCTL);
+       P2.L = lo(EBIU_SDGCTL);
+       R0 = [P2];
+       BITSET (R0, 24);
+       [P2] = R0;
+       SSYNC;
+
+       r0 = CONFIG_VCO_MULT & 63;       /* Load the VCO multiplier         */
+       r0 = r0 << 9;                    /* Shift it over,                  */
+       r1 = CLKIN_HALF;                 /* Do we need to divide CLKIN by 2?*/
+       r0 = r1 | r0;
+       r1 = PLL_BYPASS;                 /* Bypass the PLL?                 */
+       r1 = r1 << 8;                    /* Shift it over                   */
+       r0 = r1 | r0;                    /* add them all together           */
+
+       p0.h = hi(PLL_CTL);
+       p0.l = lo(PLL_CTL);              /* Load the address                */
+       cli r2;                          /* Disable interrupts              */
+       ssync;
+       w[p0] = r0.l;                    /* Set the value                   */
+       idle;                            /* Wait for the PLL to stablize    */
+       sti r2;                          /* Enable interrupts               */
+
+.Lcheck_again:
+       p0.h = hi(PLL_STAT);
+       p0.l = lo(PLL_STAT);
+       R0 = W[P0](Z);
+       CC = BITTST(R0,5);
+       if ! CC jump .Lcheck_again;
+
+       /* Configure SCLK & CCLK Dividers */
+       r0 = (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV);
+       p0.h = hi(PLL_DIV);
+       p0.l = lo(PLL_DIV);
+       w[p0] = r0.l;
+       ssync;
+
+       p0.l = lo(EBIU_SDRRC);
+       p0.h = hi(EBIU_SDRRC);
+       r0 = mem_SDRRC;
+       w[p0] = r0.l;
+       ssync;
+
+       p0.l = (EBIU_SDBCTL & 0xFFFF);
+       p0.h = (EBIU_SDBCTL >> 16);     /* SDRAM Memory Bank Control Register */
+       r0 = mem_SDBCTL;
+       w[p0] = r0.l;
+       ssync;
+
+       P2.H = hi(EBIU_SDGCTL);
+       P2.L = lo(EBIU_SDGCTL);
+       R0 = [P2];
+       BITCLR (R0, 24);
+       p0.h = hi(EBIU_SDSTAT);
+       p0.l = lo(EBIU_SDSTAT);
+       r2.l = w[p0];
+       cc = bittst(r2,3);
+       if !cc jump .Lskip;
+       NOP;
+       BITSET (R0, 23);
+.Lskip:
+       [P2] = R0;
+       SSYNC;
+
+       R0.L = lo(mem_SDGCTL);
+       R0.H = hi(mem_SDGCTL);
+       R1 = [p2];
+       R1 = R1 | R0;
+       [P2] = R1;
+       SSYNC;
+
+       p0.h = hi(SIC_IWR);
+       p0.l = lo(SIC_IWR);
+       r0.l = lo(IWR_ENABLE_ALL);
+       r0.h = hi(IWR_ENABLE_ALL);
+       [p0] = r0;
+       SSYNC;
+
+       RTS;
+#endif /* CONFIG_BFIN_KERNEL_CLOCK */
+
+ENTRY(_bfin_reset)
+       /* No more interrupts to be handled*/
+       CLI R6;
+       SSYNC;
+
+#if defined(CONFIG_MTD_M25P80)
+/*
+ * The following code fix the SPI flash reboot issue,
+ * /CS signal of the chip which is using PF10 return to GPIO mode
+ */
+       p0.h = hi(PORTF_FER);
+       p0.l = lo(PORTF_FER);
+       r0.l = 0x0000;
+       w[p0] = r0.l;
+       SSYNC;
+
+/* /CS return to high */
+       p0.h = hi(PORTFIO);
+       p0.l = lo(PORTFIO);
+       r0.l = 0xFFFF;
+       w[p0] = r0.l;
+       SSYNC;
+
+/* Delay some time, This is necessary */
+       r1.h = 0;
+       r1.l = 0x400;
+       p1   = r1;
+       lsetup (_delay_lab1,_delay_lab1_end ) lc1 = p1;
+_delay_lab1:
+       r0.h = 0;
+       r0.l = 0x8000;
+       p0   = r0;
+       lsetup (_delay_lab0,_delay_lab0_end ) lc0 = p0;
+_delay_lab0:
+       nop;
+_delay_lab0_end:
+       nop;
+_delay_lab1_end:
+       nop;
+#endif
+
+       /* Clear the bits 13-15 in SWRST if they werent cleared */
+       p0.h = hi(SWRST);
+       p0.l = lo(SWRST);
+       csync;
+       r0.l = w[p0];
+
+       /* Clear the IMASK register */
+       p0.h = hi(IMASK);
+       p0.l = lo(IMASK);
+       r0 = 0x0;
+       [p0] = r0;
+
+       /* Clear the ILAT register */
+       p0.h = hi(ILAT);
+       p0.l = lo(ILAT);
+       r0 = [p0];
+       [p0] = r0;
+       SSYNC;
+
+       /* Disable the WDOG TIMER */
+       p0.h = hi(WDOG_CTL);
+       p0.l = lo(WDOG_CTL);
+       r0.l = 0xAD6;
+       w[p0] = r0.l;
+       SSYNC;
+
+       /* Clear the sticky bit incase it is already set */
+       p0.h = hi(WDOG_CTL);
+       p0.l = lo(WDOG_CTL);
+       r0.l = 0x8AD6;
+       w[p0] = r0.l;
+       SSYNC;
+
+       /* Program the count value */
+       R0.l = 0x100;
+       R0.h = 0x0;
+       P0.h = hi(WDOG_CNT);
+       P0.l = lo(WDOG_CNT);
+       [P0] = R0;
+       SSYNC;
+
+       /* Program WDOG_STAT if necessary */
+       P0.h = hi(WDOG_CTL);
+       P0.l = lo(WDOG_CTL);
+       R0 = W[P0](Z);
+       CC = BITTST(R0,1);
+       if !CC JUMP .LWRITESTAT;
+       CC = BITTST(R0,2);
+       if !CC JUMP .LWRITESTAT;
+       JUMP .LSKIP_WRITE;
+
+.LWRITESTAT:
+       /* When watch dog timer is enabled,
+        * a write to STAT will load the contents of CNT to STAT
+        */
+       R0 = 0x0000(z);
+       P0.h = hi(WDOG_STAT);
+       P0.l = lo(WDOG_STAT)
+       [P0] = R0;
+       SSYNC;
+
+.LSKIP_WRITE:
+       /* Enable the reset event */
+       P0.h = hi(WDOG_CTL);
+       P0.l = lo(WDOG_CTL);
+       R0 = W[P0](Z);
+       BITCLR(R0,1);
+       BITCLR(R0,2);
+       W[P0] = R0.L;
+       SSYNC;
+       NOP;
+
+       /* Enable the wdog counter */
+       R0 = W[P0](Z);
+       BITCLR(R0,4);
+       W[P0] = R0.L;
+       SSYNC;
+
+       IDLE;
+
+       RTS;
+
+.data
+
+/*
+ * Set up the usable of RAM stuff. Size of RAM is determined then
+ * an initial stack set up at the end.
+ */
+
+.align 4
+__rambase:
+.long   0
+__ramstart:
+.long   0
+__ramend:
+.long   0
diff --git a/arch/blackfin/mach-bf548/ints-priority.c b/arch/blackfin/mach-bf548/ints-priority.c
new file mode 100644 (file)
index 0000000..cb0ebac
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * File:         arch/blackfin/mach-bf537/ints-priority.c
+ * Based on:     arch/blackfin/mach-bf533/ints-priority.c
+ * Author:       Michael Hennerich
+ *
+ * Created:
+ * Description:  Set up the interupt priorities
+ *
+ * Modified:
+ *               Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/module.h>
+#include <linux/irq.h>
+#include <asm/blackfin.h>
+
+void program_IAR(void)
+{
+       /* Program the IAR0 Register with the configured priority */
+       bfin_write_SIC_IAR0(((CONFIG_IRQ_PLL_WAKEUP - 7) << IRQ_PLL_WAKEUP_POS) |
+                           ((CONFIG_IRQ_DMAC0_ERR - 7) << IRQ_DMAC0_ERR_POS) |
+                           ((CONFIG_IRQ_EPPI0_ERR - 7) << IRQ_EPPI0_ERR_POS) |
+                           ((CONFIG_IRQ_SPORT0_ERR - 7) << IRQ_SPORT0_ERR_POS) |
+                           ((CONFIG_IRQ_SPORT1_ERR - 7) << IRQ_SPORT1_ERR_POS) |
+                           ((CONFIG_IRQ_SPI0_ERR - 7) << IRQ_SPI0_ERR_POS) |
+                           ((CONFIG_IRQ_UART0_ERR - 7) << IRQ_UART0_ERR_POS) |
+                           ((CONFIG_IRQ_RTC - 7) << IRQ_RTC_POS));
+
+       bfin_write_SIC_IAR1(((CONFIG_IRQ_EPPI0 - 7) << IRQ_EPPI0_POS) |
+                           ((CONFIG_IRQ_SPORT0_RX - 7) << IRQ_SPORT0_RX_POS) |
+                           ((CONFIG_IRQ_SPORT0_TX - 7) << IRQ_SPORT0_TX_POS) |
+                           ((CONFIG_IRQ_SPORT1_RX - 7) << IRQ_SPORT1_RX_POS) |
+                           ((CONFIG_IRQ_SPORT1_TX - 7) << IRQ_SPORT1_TX_POS) |
+                           ((CONFIG_IRQ_SPI0 - 7) << IRQ_SPI0_POS) |
+                           ((CONFIG_IRQ_UART0_RX - 7) << IRQ_UART0_RX_POS) |
+                           ((CONFIG_IRQ_UART0_TX - 7) << IRQ_UART0_TX_POS));
+
+       bfin_write_SIC_IAR2(((CONFIG_IRQ_TIMER8 - 7) << IRQ_TIMER8_POS) |
+                           ((CONFIG_IRQ_TIMER9 - 7) << IRQ_TIMER9_POS) |
+                           ((CONFIG_IRQ_PINT0 - 7) << IRQ_PINT0_POS) |
+                           ((CONFIG_IRQ_PINT1 - 7) << IRQ_PINT1_POS) |
+                           ((CONFIG_IRQ_MDMAS0 - 7) << IRQ_MDMAS0_POS) |
+                           ((CONFIG_IRQ_MDMAS1 - 7) << IRQ_MDMAS1_POS) |
+                           ((CONFIG_IRQ_WATCHDOG - 7) << IRQ_WATCHDOG_POS));
+
+       bfin_write_SIC_IAR3(((CONFIG_IRQ_DMAC1_ERR - 7) << IRQ_DMAC1_ERR_POS) |
+                           ((CONFIG_IRQ_SPORT2_ERR - 7) << IRQ_SPORT2_ERR_POS) |
+                           ((CONFIG_IRQ_SPORT3_ERR - 7) << IRQ_SPORT3_ERR_POS) |
+                           ((CONFIG_IRQ_MXVR_DATA - 7) << IRQ_MXVR_DATA_POS) |
+                           ((CONFIG_IRQ_SPI1_ERR - 7) << IRQ_SPI1_ERR_POS) |
+                           ((CONFIG_IRQ_SPI2_ERR - 7) << IRQ_SPI2_ERR_POS) |
+                           ((CONFIG_IRQ_UART1_ERR - 7) << IRQ_UART1_ERR_POS) |
+                           ((CONFIG_IRQ_UART2_ERR - 7) << IRQ_UART2_ERR_POS));
+
+       bfin_write_SIC_IAR4(((CONFIG_IRQ_CAN0_ERR - 7) << IRQ_CAN0_ERR_POS) |
+                           ((CONFIG_IRQ_SPORT2_RX - 7) << IRQ_SPORT2_RX_POS) |
+                           ((CONFIG_IRQ_SPORT2_TX - 7) << IRQ_SPORT2_TX_POS) |
+                           ((CONFIG_IRQ_SPORT3_RX - 7) << IRQ_SPORT3_RX_POS) |
+                           ((CONFIG_IRQ_SPORT3_TX - 7) << IRQ_SPORT3_TX_POS) |
+                           ((CONFIG_IRQ_EPPI1 - 7) << IRQ_EPPI1_POS) |
+                           ((CONFIG_IRQ_EPPI2 - 7) << IRQ_EPPI2_POS) |
+                           ((CONFIG_IRQ_SPI1 - 7) << IRQ_SPI1_POS));
+
+       bfin_write_SIC_IAR5(((CONFIG_IRQ_SPI2 - 7) << IRQ_SPI2_POS) |
+                           ((CONFIG_IRQ_UART1_RX - 7) << IRQ_UART1_RX_POS) |
+                           ((CONFIG_IRQ_UART1_TX - 7) << IRQ_UART1_TX_POS) |
+                           ((CONFIG_IRQ_ATAPI_RX - 7) << IRQ_ATAPI_RX_POS) |
+                           ((CONFIG_IRQ_ATAPI_TX - 7) << IRQ_ATAPI_TX_POS) |
+                           ((CONFIG_IRQ_TWI0 - 7) << IRQ_TWI0_POS) |
+                           ((CONFIG_IRQ_TWI1 - 7) << IRQ_TWI1_POS) |
+                           ((CONFIG_IRQ_CAN0_RX - 7) << IRQ_CAN0_RX_POS));
+
+       bfin_write_SIC_IAR6(((CONFIG_IRQ_CAN0_TX - 7) << IRQ_CAN0_TX_POS) |
+                           ((CONFIG_IRQ_MDMAS2 - 7) << IRQ_MDMAS2_POS) |
+                           ((CONFIG_IRQ_MDMAS3 - 7) << IRQ_MDMAS3_POS) |
+                           ((CONFIG_IRQ_MXVR_ERR - 7) << IRQ_MXVR_ERR_POS) |
+                           ((CONFIG_IRQ_MXVR_MSG - 7) << IRQ_MXVR_MSG_POS) |
+                           ((CONFIG_IRQ_MXVR_PKT - 7) << IRQ_MXVR_PKT_POS) |
+                           ((CONFIG_IRQ_EPPI1_ERR - 7) << IRQ_EPPI1_ERR_POS) |
+                           ((CONFIG_IRQ_EPPI2_ERR - 7) << IRQ_EPPI2_ERR_POS));
+
+       bfin_write_SIC_IAR7(((CONFIG_IRQ_UART3_ERR - 7) << IRQ_UART3_ERR_POS) |
+                           ((CONFIG_IRQ_HOST_ERR - 7) << IRQ_HOST_ERR_POS) |
+                           ((CONFIG_IRQ_PIXC_ERR - 7) << IRQ_PIXC_ERR_POS) |
+                           ((CONFIG_IRQ_NFC_ERR - 7) << IRQ_NFC_ERR_POS) |
+                           ((CONFIG_IRQ_ATAPI_ERR - 7) << IRQ_ATAPI_ERR_POS) |
+                           ((CONFIG_IRQ_CAN1_ERR - 7) << IRQ_CAN1_ERR_POS) |
+                           ((CONFIG_IRQ_HS_DMA_ERR - 7) << IRQ_HS_DMA_ERR_POS));
+
+       bfin_write_SIC_IAR8(((CONFIG_IRQ_PIXC_IN0 - 7) << IRQ_PIXC_IN1_POS) |
+                           ((CONFIG_IRQ_PIXC_IN1 - 7) << IRQ_PIXC_IN1_POS) |
+                           ((CONFIG_IRQ_PIXC_OUT - 7) << IRQ_PIXC_OUT_POS) |
+                           ((CONFIG_IRQ_SDH - 7) << IRQ_SDH_POS) |
+                           ((CONFIG_IRQ_CNT - 7) << IRQ_CNT_POS) |
+                           ((CONFIG_IRQ_KEY - 7) << IRQ_KEY_POS) |
+                           ((CONFIG_IRQ_CAN1_RX - 7) << IRQ_CAN1_RX_POS) |
+                           ((CONFIG_IRQ_CAN1_TX - 7) << IRQ_CAN1_TX_POS));
+
+       bfin_write_SIC_IAR9(((CONFIG_IRQ_SDH_MASK0 - 7) << IRQ_SDH_MASK0_POS) |
+                           ((CONFIG_IRQ_SDH_MASK1 - 7) << IRQ_SDH_MASK1_POS) |
+                           ((CONFIG_IRQ_USB_INT0 - 7) << IRQ_USB_INT0_POS) |
+                           ((CONFIG_IRQ_USB_INT1 - 7) << IRQ_USB_INT1_POS) |
+                           ((CONFIG_IRQ_USB_INT2 - 7) << IRQ_USB_INT2_POS) |
+                           ((CONFIG_IRQ_USB_DMA - 7) << IRQ_USB_DMA_POS) |
+                           ((CONFIG_IRQ_OTPSEC - 7) << IRQ_OTPSEC_POS));
+
+       bfin_write_SIC_IAR10(((CONFIG_IRQ_TIMER0 - 7) << IRQ_TIMER0_POS) |
+                            ((CONFIG_IRQ_TIMER1 - 7) << IRQ_TIMER1_POS));
+
+       bfin_write_SIC_IAR11(((CONFIG_IRQ_TIMER2 - 7) << IRQ_TIMER2_POS) |
+                            ((CONFIG_IRQ_TIMER3 - 7) << IRQ_TIMER3_POS) |
+                            ((CONFIG_IRQ_TIMER4 - 7) << IRQ_TIMER4_POS) |
+                            ((CONFIG_IRQ_TIMER5 - 7) << IRQ_TIMER5_POS) |
+                            ((CONFIG_IRQ_TIMER6 - 7) << IRQ_TIMER6_POS) |
+                            ((CONFIG_IRQ_TIMER7 - 7) << IRQ_TIMER7_POS) |
+                            ((CONFIG_IRQ_PINT2 - 7) << IRQ_PINT2_POS) |
+                            ((CONFIG_IRQ_PINT3 - 7) << IRQ_PINT3_POS));
+
+       SSYNC();
+}
index 57f475a5516140a5a3ae7bb9109f380f06c524ef..f39235a55783b98c9e040ba92f9848f8282037fe 100644 (file)
@@ -4,6 +4,6 @@
 
 extra-y := head.o
 
-obj-y := ints-priority.o
+obj-y := ints-priority.o dma.o
 
 obj-$(CONFIG_BF561_COREB) += coreb.o
index 3dc5c042048cec307c4cb44bc81e09238b9a0108..5b2b544529a19c49a919f0fb2e57f6b55f9c3eb3 100644 (file)
@@ -34,7 +34,7 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
 #include <linux/usb_isp1362.h>
-#include <asm/irq.h>
+#include <linux/irq.h>
 #include <asm/bfin5xx_spi.h>
 
 /*
@@ -52,11 +52,11 @@ static struct mtd_partition bfin_spi_flash_partitions[] = {
                .size = 0x00020000,
                .offset = 0,
                .mask_flags = MTD_CAP_ROM
-       },{
+       }, {
                .name = "kernel",
                .size = 0xe0000,
                .offset = 0x20000
-       },{
+       }, {
                .name = "file system",
                .size = 0x700000,
                .offset = 0x00100000,
@@ -186,7 +186,7 @@ static struct resource smc91x_resources[] = {
                .start = 0x28000300,
                .end = 0x28000300 + 16,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = IRQ_PF0,
                .end = IRQ_PF0,
                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -206,11 +206,11 @@ static struct resource isp1362_hcd_resources[] = {
                .start = 0x24008000,
                .end = 0x24008000,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = 0x24008004,
                .end = 0x24008004,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = IRQ_PF47,
                .end = IRQ_PF47,
                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -241,25 +241,25 @@ static struct platform_device isp1362_hcd_device = {
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
 static struct resource bfin_uart_resources[] = {
-        {
-                .start = 0xFFC00400,
-                .end = 0xFFC004FF,
-                .flags = IORESOURCE_MEM,
-        },
+       {
+               .start = 0xFFC00400,
+               .end = 0xFFC004FF,
+               .flags = IORESOURCE_MEM,
+       },
 };
 
 static struct platform_device bfin_uart_device = {
-        .name = "bfin-uart",
-        .id = 1,
-        .num_resources = ARRAY_SIZE(bfin_uart_resources),
-        .resource = bfin_uart_resources,
+       .name = "bfin-uart",
+       .id = 1,
+       .num_resources = ARRAY_SIZE(bfin_uart_resources),
+       .resource = bfin_uart_resources,
 };
 #endif
 
 static struct platform_device *cm_bf561_devices[] __initdata = {
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-        &bfin_uart_device,
+       &bfin_uart_device,
 #endif
 
 #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
index 9720b5c307ab58c82c0d5b55342b3769b959d52c..724191da20a249a8f1f66c60cfba7b190f5f6074 100644 (file)
 #include <linux/device.h>
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
-#include <asm/irq.h>
-#include <asm/bfin5xx_spi.h>
-#include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <asm/bfin5xx_spi.h>
 
 /*
  * Name the Board for the /proc/cpuinfo
@@ -45,13 +44,13 @@ char *bfin_board_name = "ADDS-BF561-EZKIT";
 
 #if defined(CONFIG_USB_ISP1760_HCD) || defined(CONFIG_USB_ISP1760_HCD_MODULE)
 static struct resource bfin_isp1761_resources[] = {
-       [0] = {
+       {
                .name   = "isp1761-regs",
                .start  = ISP1761_BASE + 0x00000000,
                .end    = ISP1761_BASE + 0x000fffff,
                .flags  = IORESOURCE_MEM,
        },
-       [1] = {
+       {
                .start  = ISP1761_IRQ,
                .end    = ISP1761_IRQ,
                .flags  = IORESOURCE_IRQ,
@@ -71,7 +70,7 @@ static struct platform_device *bfin_isp1761_devices[] = {
 
 int __init bfin_isp1761_init(void)
 {
-       unsigned int num_devices=ARRAY_SIZE(bfin_isp1761_devices);
+       unsigned int num_devices = ARRAY_SIZE(bfin_isp1761_devices);
 
        printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
        set_irq_type(ISP1761_IRQ, IRQF_TRIGGER_FALLING);
@@ -98,7 +97,7 @@ static struct resource smc91x_resources[] = {
                .start = 0x2C010300,
                .end = 0x2C010300 + 16,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
 
                .start = IRQ_PF9,
                .end = IRQ_PF9,
@@ -116,18 +115,18 @@ static struct platform_device smc91x_device = {
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
 static struct resource bfin_uart_resources[] = {
-        {
-                .start = 0xFFC00400,
-                .end = 0xFFC004FF,
-                .flags = IORESOURCE_MEM,
-        },
+       {
+               .start = 0xFFC00400,
+               .end = 0xFFC004FF,
+               .flags = IORESOURCE_MEM,
+       },
 };
 
 static struct platform_device bfin_uart_device = {
-        .name = "bfin-uart",
-        .id = 1,
-        .num_resources = ARRAY_SIZE(bfin_uart_resources),
-        .resource = bfin_uart_resources,
+       .name = "bfin-uart",
+       .id = 1,
+       .num_resources = ARRAY_SIZE(bfin_uart_resources),
+       .resource = bfin_uart_resources,
 };
 #endif
 
@@ -176,7 +175,7 @@ static struct platform_device *ezkit_devices[] __initdata = {
        &spi_bfin_master_device,
 #endif
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-        &bfin_uart_device,
+       &bfin_uart_device,
 #endif
 };
 
index 585ecdd2f6a5889c2a1478bcdbc7298d69cb35a1..4dfea5da674c9acf37968a2c4a1d250756ffffe5 100644 (file)
@@ -30,7 +30,7 @@
 
 #include <linux/device.h>
 #include <linux/platform_device.h>
-#include <asm/irq.h>
+#include <linux/irq.h>
 
 char *bfin_board_name = "UNKNOWN BOARD";
 
@@ -43,11 +43,11 @@ static struct resource smc91x_resources[] = {
                .start = 0x2C010300,
                .end = 0x2C010300 + 16,
                .flags = IORESOURCE_MEM,
-       },{
+       }, {
                .start = IRQ_PROG_INTB,
                .end = IRQ_PROG_INTB,
                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
-       },{
+       }, {
                /*
                 *  denotes the flag pin and is used directly if
                 *  CONFIG_IRQCHIP_DEMUX_GPIO is defined.
index db308c7ccabbf4dd5014b6542bf5dbb23f395c8e..c442eb23db5ea26916156362d7f38392b5d6e946 100644 (file)
@@ -14,7 +14,7 @@
 
 #include <linux/device.h>
 #include <linux/platform_device.h>
-#include <asm/irq.h>
+#include <linux/irq.h>
 
 char *bfin_board_name = "Tepla-BF561";
 
@@ -26,11 +26,11 @@ static struct resource smc91x_resources[] = {
                .start  = 0x2C000300,
                .end    = 0x2C000320,
                .flags  = IORESOURCE_MEM,
-       },{
+       }, {
                .start  = IRQ_PROG_INTB,
                .end    = IRQ_PROG_INTB,
                .flags  = IORESOURCE_IRQ|IORESOURCE_IRQ_HIGHLEVEL,
-       },{
+       }, {
                /*
                 *  denotes the flag pin and is used directly if
                 *  CONFIG_IRQCHIP_DEMUX_GPIO is defined.
index b28582fe083cc698637f130bbfa2f0716697a8fa..5d1d21b4c2a74c3528fb2701e868ae030ca637df 100644 (file)
@@ -32,8 +32,8 @@
 #include <linux/device.h>
 #include <linux/ioport.h>
 #include <linux/module.h>
+#include <linux/uaccess.h>
 #include <asm/dma.h>
-#include <asm/uaccess.h>
 
 #define MODULE_VER             "v0.1"
 
@@ -202,7 +202,7 @@ static int coreb_open(struct inode *inode, struct file *file)
        spin_unlock_irq(&coreb_lock);
        return 0;
 
     out_busy:
+ out_busy:
        spin_unlock_irq(&coreb_lock);
        return -EBUSY;
 }
@@ -365,19 +365,19 @@ int __init bf561_coreb_init(void)
        printk(KERN_INFO "BF561 Core B driver %s initialized.\n", MODULE_VER);
        return 0;
 
     release_dma_src:
+ release_dma_src:
        free_dma(CH_MEM_STREAM2_SRC);
     release_dma_dest:
+ release_dma_dest:
        free_dma(CH_MEM_STREAM2_DEST);
     release_data_a_sram:
+ release_data_a_sram:
        release_mem_region(0xff400000, 0x8000);
     release_data_b_sram:
+ release_data_b_sram:
        release_mem_region(0xff500000, 0x8000);
     release_instruction_b_sram:
+ release_instruction_b_sram:
        release_mem_region(0xff610000, 0x4000);
     release_instruction_a_sram:
+ release_instruction_a_sram:
        release_mem_region(0xff600000, 0x4000);
     exit:
+ exit:
        return -ENOMEM;
 }
 
diff --git a/arch/blackfin/mach-bf561/dma.c b/arch/blackfin/mach-bf561/dma.c
new file mode 100644 (file)
index 0000000..89c65bb
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * File:         arch/blackfin/mach-bf561/dma.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:  This file contains the simple DMA Implementation for Blackfin
+ *
+ * Modified:
+ *               Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <asm/blackfin.h>
+#include <asm/dma.h>
+
+struct dma_register *base_addr[MAX_BLACKFIN_DMA_CHANNEL] = {
+       (struct dma_register *) DMA1_0_NEXT_DESC_PTR,
+       (struct dma_register *) DMA1_1_NEXT_DESC_PTR,
+       (struct dma_register *) DMA1_2_NEXT_DESC_PTR,
+       (struct dma_register *) DMA1_3_NEXT_DESC_PTR,
+       (struct dma_register *) DMA1_4_NEXT_DESC_PTR,
+       (struct dma_register *) DMA1_5_NEXT_DESC_PTR,
+       (struct dma_register *) DMA1_6_NEXT_DESC_PTR,
+       (struct dma_register *) DMA1_7_NEXT_DESC_PTR,
+       (struct dma_register *) DMA1_8_NEXT_DESC_PTR,
+       (struct dma_register *) DMA1_9_NEXT_DESC_PTR,
+       (struct dma_register *) DMA1_10_NEXT_DESC_PTR,
+       (struct dma_register *) DMA1_11_NEXT_DESC_PTR,
+       (struct dma_register *) DMA2_0_NEXT_DESC_PTR,
+       (struct dma_register *) DMA2_1_NEXT_DESC_PTR,
+       (struct dma_register *) DMA2_2_NEXT_DESC_PTR,
+       (struct dma_register *) DMA2_3_NEXT_DESC_PTR,
+       (struct dma_register *) DMA2_4_NEXT_DESC_PTR,
+       (struct dma_register *) DMA2_5_NEXT_DESC_PTR,
+       (struct dma_register *) DMA2_6_NEXT_DESC_PTR,
+       (struct dma_register *) DMA2_7_NEXT_DESC_PTR,
+       (struct dma_register *) DMA2_8_NEXT_DESC_PTR,
+       (struct dma_register *) DMA2_9_NEXT_DESC_PTR,
+       (struct dma_register *) DMA2_10_NEXT_DESC_PTR,
+       (struct dma_register *) DMA2_11_NEXT_DESC_PTR,
+       (struct dma_register *) MDMA1_D0_NEXT_DESC_PTR,
+       (struct dma_register *) MDMA1_S0_NEXT_DESC_PTR,
+       (struct dma_register *) MDMA1_D1_NEXT_DESC_PTR,
+       (struct dma_register *) MDMA1_S1_NEXT_DESC_PTR,
+       (struct dma_register *) MDMA2_D0_NEXT_DESC_PTR,
+       (struct dma_register *) MDMA2_S0_NEXT_DESC_PTR,
+       (struct dma_register *) MDMA2_D1_NEXT_DESC_PTR,
+       (struct dma_register *) MDMA2_S1_NEXT_DESC_PTR,
+       (struct dma_register *) IMDMA_D0_NEXT_DESC_PTR,
+       (struct dma_register *) IMDMA_S0_NEXT_DESC_PTR,
+       (struct dma_register *) IMDMA_D1_NEXT_DESC_PTR,
+       (struct dma_register *) IMDMA_S1_NEXT_DESC_PTR,
+};
+
+int channel2irq(unsigned int channel)
+{
+       int ret_irq = -1;
+
+       switch (channel) {
+       case CH_PPI0:
+               ret_irq = IRQ_PPI0;
+               break;
+       case CH_PPI1:
+               ret_irq = IRQ_PPI1;
+               break;
+       case CH_SPORT0_RX:
+               ret_irq = IRQ_SPORT0_RX;
+               break;
+       case CH_SPORT0_TX:
+               ret_irq = IRQ_SPORT0_TX;
+               break;
+       case CH_SPORT1_RX:
+               ret_irq = IRQ_SPORT1_RX;
+               break;
+       case CH_SPORT1_TX:
+               ret_irq = IRQ_SPORT1_TX;
+               break;
+       case CH_SPI:
+               ret_irq = IRQ_SPI;
+               break;
+       case CH_UART_RX:
+               ret_irq = IRQ_UART_RX;
+               break;
+       case CH_UART_TX:
+               ret_irq = IRQ_UART_TX;
+               break;
+
+       case CH_MEM_STREAM0_SRC:
+       case CH_MEM_STREAM0_DEST:
+               ret_irq = IRQ_MEM_DMA0;
+               break;
+       case CH_MEM_STREAM1_SRC:
+       case CH_MEM_STREAM1_DEST:
+               ret_irq = IRQ_MEM_DMA1;
+               break;
+       case CH_MEM_STREAM2_SRC:
+       case CH_MEM_STREAM2_DEST:
+               ret_irq = IRQ_MEM_DMA2;
+               break;
+       case CH_MEM_STREAM3_SRC:
+       case CH_MEM_STREAM3_DEST:
+               ret_irq = IRQ_MEM_DMA3;
+               break;
+
+       case CH_IMEM_STREAM0_SRC:
+       case CH_IMEM_STREAM0_DEST:
+               ret_irq = IRQ_IMEM_DMA0;
+               break;
+       case CH_IMEM_STREAM1_SRC:
+       case CH_IMEM_STREAM1_DEST:
+               ret_irq = IRQ_IMEM_DMA1;
+               break;
+       }
+       return ret_irq;
+}
index 31cbc75c85cfdac9507445bc873f0e158e6008a8..2f08bcb2dded5158cd0270011ebab21415390496 100644 (file)
@@ -30,6 +30,8 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 #include <asm/blackfin.h>
+#include <asm/trace.h>
+
 #if CONFIG_BFIN_KERNEL_CLOCK
 #include <asm/mach/mem_init.h>
 #endif
@@ -93,6 +95,10 @@ ENTRY(__start)
        M2 = r0;
        M3 = r0;
 
+       trace_buffer_start(p0,r0);
+       P0 = R1;
+       R0 = R1;
+
        /* Turn off the icache */
        p0.l = (IMEM_CONTROL & 0xFFFF);
        p0.h = (IMEM_CONTROL >> 16);
index 86e3b0ee93f426994498c330210e2232939b488a..09b541b0f7c20c284cb1d549e88a205b82b97d06 100644 (file)
@@ -28,8 +28,8 @@
  */
 
 #include <linux/module.h>
+#include <linux/irq.h>
 #include <asm/blackfin.h>
-#include <asm/irq.h>
 
 void program_IAR(void)
 {
index d3a49073d19615c18dae78078f6f08563893f4ee..0279ede70392fb40d0403044eff8bdd8fd487791 100644 (file)
@@ -4,9 +4,9 @@
 
 obj-y := \
        cache.o cacheinit.o cplbhdlr.o cplbmgr.o entry.o \
-       interrupt.o lock.o dpmc.o irqpanic.o
+       interrupt.o lock.o irqpanic.o
 
 obj-$(CONFIG_CPLB_INFO)          += cplbinfo.o
 obj-$(CONFIG_BFIN_SINGLE_CORE)   += ints-priority-sc.o
 obj-$(CONFIG_BFIN_DUAL_CORE)     += ints-priority-dc.o
-obj-$(CONFIG_PM)                 += pm.o
+obj-$(CONFIG_PM)                 += pm.o dpmc.o
index 7924a90d9658ef900d04aa390ec9f13a514b68fb..9d475623b7243f2069528de67cc291cda01ae9fb 100644 (file)
 
 .text
 
+#ifdef ANOMALY_05000125
 #if defined(CONFIG_BLKFIN_CACHE)
-ENTRY(_bfin_icache_init)
+ENTRY(_bfin_write_IMEM_CONTROL)
 
-       /* Initialize Instruction CPLBS */
-
-       I0.L = (ICPLB_ADDR0 & 0xFFFF);
-       I0.H = (ICPLB_ADDR0 >> 16);
-
-       I1.L = (ICPLB_DATA0 & 0xFFFF);
-       I1.H = (ICPLB_DATA0 >> 16);
-
-       I2.L = _icplb_table;
-       I2.H = _icplb_table;
-
-       r1 = -1;        /* end point comparison */
-       r3 = 15;        /* max counter */
-
-/* read entries from table */
-
-.Lread_iaddr:
-       R0 = [I2++];
-       CC = R0 == R1;
-       IF CC JUMP .Lidone;
-       [I0++] = R0;
-
-.Lread_idata:
-       R2 = [I2++];
-       [I1++] = R2;
-       R3 = R3 + R1;
-       CC = R3 == R1;
-       IF !CC JUMP .Lread_iaddr;
-
-.Lidone:
        /* Enable Instruction Cache */
        P0.l = (IMEM_CONTROL & 0xFFFF);
        P0.h = (IMEM_CONTROL >> 16);
-       R1 = [P0];
-       R0 = (IMC | ENICPLB);
-       R0 = R0 | R1;
 
        /* Anomaly 05000125 */
-       CLI R2;
+       CLI R1;
        SSYNC;          /* SSYNC required before writing to IMEM_CONTROL. */
        .align 8;
        [P0] = R0;
        SSYNC;
-       STI R2;
+       STI R1;
        RTS;
 
-ENDPROC(_bfin_icache_init)
+ENDPROC(_bfin_write_IMEM_CONTROL)
 #endif
 
 #if defined(CONFIG_BLKFIN_DCACHE)
-ENTRY(_bfin_dcache_init)
-
-       /* Initialize Data CPLBS */
-
-       I0.L = (DCPLB_ADDR0 & 0xFFFF);
-       I0.H = (DCPLB_ADDR0 >> 16);
-
-       I1.L = (DCPLB_DATA0 & 0xFFFF);
-       I1.H = (DCPLB_DATA0 >> 16);
-
-       I2.L = _dcplb_table;
-       I2.H = _dcplb_table;
-
-       R1 = -1;        /* end point comparison */
-       R3 = 15;        /* max counter */
-
-       /* read entries from table */
-.Lread_daddr:
-       R0 = [I2++];
-       cc = R0 == R1;
-       IF CC JUMP .Lddone;
-       [I0++] = R0;
-
-.Lread_ddata:
-       R2 = [I2++];
-       [I1++] = R2;
-       R3 = R3 + R1;
-       CC = R3 == R1;
-       IF !CC JUMP .Lread_daddr;
-.Lddone:
-       P0.L = (DMEM_CONTROL & 0xFFFF);
-       P0.H = (DMEM_CONTROL >> 16);
-       R1 = [P0];
-
-       R0 = DMEM_CNTR;
-
-       R0 = R0 | R1;
-       /* Anomaly 05000125 */
-       CLI R2;
+ENTRY(_bfin_write_DMEM_CONTROL)
+       CLI R1;
        SSYNC;          /* SSYNC required before writing to DMEM_CONTROL. */
        .align 8;
        [P0] = R0;
        SSYNC;
-       STI R2;
+       STI R1;
        RTS;
 
-ENDPROC(_bfin_dcache_init)
+ENDPROC(_bfin_write_DMEM_CONTROL)
+#endif
+
 #endif
index caa9623e6bd6d578903e8411f6c607dcd8789779..785ca981697105973a8079fde7ecddde7179274e 100644 (file)
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/proc_fs.h>
+#include <linux/uaccess.h>
 
 #include <asm/current.h>
-#include <asm/uaccess.h>
 #include <asm/system.h>
-
 #include <asm/cplb.h>
 #include <asm/blackfin.h>
 
@@ -92,8 +91,7 @@ static char *cplb_print_entry(char *buf, int type)
        } else
                buf += sprintf(buf, "Data CPLB entry:\n");
 
-       buf += sprintf(buf, "Address\t\tData\tSize\tValid\tLocked\tSwapin\
-\tiCount\toCount\n");
+       buf += sprintf(buf, "Address\t\tData\tSize\tValid\tLocked\tSwapin\n\tiCount\toCount\n");
 
        while (*p_addr != 0xffffffff) {
                entry = cplb_find_entry(cplb_addr, cplb_data, *p_addr, *p_data);
@@ -144,8 +142,7 @@ static int cplbinfo_proc_output(char *buf)
 
        p = buf;
 
-       p += sprintf(p,
-                    "------------------ CPLB Information ------------------\n\n");
+       p += sprintf(p, "------------------ CPLB Information ------------------\n\n");
 
        if (bfin_read_IMEM_CONTROL() & ENICPLB)
                p = cplb_print_entry(p, CPLB_I);
@@ -191,9 +188,9 @@ static int __init cplbinfo_init(void)
 {
        struct proc_dir_entry *entry;
 
-       if ((entry = create_proc_entry("cplbinfo", 0, NULL)) == NULL) {
+       entry = create_proc_entry("cplbinfo", 0, NULL);
+       if (!entry)
                return -ENOMEM;
-       }
 
        entry->read_proc = cplbinfo_read_proc;
        entry->write_proc = cplbinfo_write_proc;
index 40045b1386ad888d608fd80d02de1dbb5341ecd8..d61bba98fb548b8baf63980e11aca302902419d4 100644 (file)
 
 
 #include <linux/linkage.h>
+#include <linux/unistd.h>
 #include <asm/blackfin.h>
-#include <asm/unistd.h>
 #include <asm/errno.h>
 #include <asm/thread_info.h>  /* TIF_NEED_RESCHED */
 #include <asm/asm-offsets.h>
+#include <asm/trace.h>
 
 #include <asm/mach-common/context.S>
 
-#ifdef CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE
-       /*
-        * TODO: this should be proper save/restore, but for now
-        * we'll just cheat and use 0x1/0x13
-        */
-# define DEBUG_START_HWTRACE \
-       P5.l = LO(TBUFCTL); \
-       P5.h = HI(TBUFCTL); \
-       R7 = 0x13; \
-       [P5] = R7;
-# define DEBUG_STOP_HWTRACE \
-       P5.l = LO(TBUFCTL); \
-       P5.h = HI(TBUFCTL); \
-       R7 = 0x01; \
-       [P5] = R7;
-#else
-# define DEBUG_START_HWTRACE
-# define DEBUG_STOP_HWTRACE
-#endif
-
 #ifdef CONFIG_EXCPT_IRQ_SYSC_L1
 .section .l1.text
 #else
@@ -110,25 +91,14 @@ ENTRY(_ex_icplb)
        ASTAT = [sp++];
        SAVE_ALL_SYS
        call __cplb_hdr;
-       DEBUG_START_HWTRACE
+       DEBUG_START_HWTRACE(p5, r7)
        RESTORE_ALL_SYS
        SP = RETN;
        rtx;
 ENDPROC(_ex_icplb)
 
-ENTRY(_ex_spinlock)
-       /* Transform this into a syscall - twiddle the syscall vector.  */
-       p5.l = lo(EVT15);
-       p5.h = hi(EVT15);
-       r7.l = _spinlock_bh;
-       r7.h = _spinlock_bh;
-       [p5] = r7;
-       csync;
-       /* Fall through.  */
-ENDPROC(_ex_spinlock)
-
 ENTRY(_ex_syscall)
-       DEBUG_START_HWTRACE
+       DEBUG_START_HWTRACE(p5, r7)
        (R7:6,P5:4) = [sp++];
        ASTAT = [sp++];
        raise 15;               /* invoked by TRAP #0, for sys call */
@@ -136,26 +106,6 @@ ENTRY(_ex_syscall)
        rtx
 ENDPROC(_ex_syscall)
 
-ENTRY(_spinlock_bh)
-       SAVE_ALL_SYS
-       /* To end up here, vector 15 was changed - so we have to change it
-        * back.
-        */
-       p0.l = lo(EVT15);
-       p0.h = hi(EVT15);
-       p1.l = _evt_system_call;
-       p1.h = _evt_system_call;
-       [p0] = p1;
-       csync;
-       r0 = [sp + PT_R0];
-       sp += -12;
-       call _sys_bfin_spinlock;
-       sp += 12;
-       [SP + PT_R0] = R0;
-       RESTORE_ALL_SYS
-       rti;
-ENDPROC(_spinlock_bh)
-
 ENTRY(_ex_soft_bp)
        r7 = retx;
        r7 += -2;
@@ -186,7 +136,7 @@ ENTRY(_ex_single_step)
        if !cc jump _ex_trap_c;
 
 _return_from_exception:
-       DEBUG_START_HWTRACE
+       DEBUG_START_HWTRACE(p5, r7)
 #ifdef ANOMALY_05000257
        R7=LC0;
        LC0=R7;
@@ -208,7 +158,7 @@ ENTRY(_handle_bad_cplb)
         * need to make a CPLB exception look like a normal exception
         */
 
-       DEBUG_START_HWTRACE
+       DEBUG_START_HWTRACE(p5, r7)
        RESTORE_ALL_SYS
        [--sp] = ASTAT;
        [--sp] = (R7:6, P5:4);
@@ -251,7 +201,7 @@ ENTRY(_ex_trap_c)
        R6 = SEQSTAT;
        [P5] = R6;
 
-       DEBUG_START_HWTRACE
+       DEBUG_START_HWTRACE(p5, r7)
        (R7:6,P5:4) = [sp++];
        ASTAT = [sp++];
        SP = RETN;
@@ -335,7 +285,7 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/
        /* Try to deal with syscalls quickly.  */
        [--sp] = ASTAT;
        [--sp] = (R7:6, P5:4);
-       DEBUG_STOP_HWTRACE
+       DEBUG_STOP_HWTRACE(p5, r7)
        r7 = SEQSTAT;           /* reason code is in bit 5:0 */
        r6.l = lo(SEQSTAT_EXCAUSE);
        r6.h = hi(SEQSTAT_EXCAUSE);
@@ -741,6 +691,10 @@ _schedule_and_signal_from_int:
        r0 = [p0];
        sti r0;
 
+       r0 = sp;
+       sp += -12;
+       call _finish_atomic_sections;
+       sp += 12;
        jump.s .Lresume_userspace;
 
 _schedule_and_signal:
@@ -790,14 +744,14 @@ ENDPROC(_init_exception_buff)
 ALIGN
 _extable:
        /* entry for each EXCAUSE[5:0]
-        * This table bmust be in sync with the table in ./kernel/traps.c
+        * This table must be in sync with the table in ./kernel/traps.c
         * EXCPT instruction can provide 4 bits of EXCAUSE, allowing 16 to be user defined
         */
        .long _ex_syscall;      /* 0x00 - User Defined - Linux Syscall */
        .long _ex_soft_bp       /* 0x01 - User Defined - Software breakpoint */
        .long _ex_trap_c        /* 0x02 - User Defined */
-       .long _ex_trap_c        /* 0x03 - User Defined  - Atomic test and set service */
-       .long _ex_spinlock      /* 0x04 - User Defined */
+       .long _ex_trap_c        /* 0x03 - User Defined - userspace stack overflow */
+       .long _ex_trap_c        /* 0x04 - User Defined */
        .long _ex_trap_c        /* 0x05 - User Defined */
        .long _ex_trap_c        /* 0x06 - User Defined */
        .long _ex_trap_c        /* 0x07 - User Defined */
index 8be548e061bff73a82b98659e500ddadd29abbc2..203e20709163811021e98131d2747b32e189c3a1 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/linkage.h>
 #include <asm/entry.h>
 #include <asm/asm-offsets.h>
+#include <asm/trace.h>
 
 #include <asm/mach-common/context.S>
 
@@ -170,10 +171,9 @@ ENTRY(_evt_ivhw)
        r7.l = W[p5];
 1:
 #endif
-       p0.l = lo(TBUFCTL);
-       p0.h = hi(TBUFCTL);
-       r0 = 1;
-       [p0] = r0;
+
+       trace_buffer_stop(p0, r0);
+
        r0 = IRQ_HWERR;
        r1 = sp;
 
index 80943bbd37c202f8d1a58b8a6d5f3bdc15074ab3..6b9fd03ce8355135b7227b9073d2249690aff766 100644 (file)
@@ -183,7 +183,7 @@ static void bf561_gpio_ack_irq(unsigned int irq)
 {
        u16 gpionr = irq - IRQ_PF0;
 
-       if(gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) {
+       if (gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) {
                set_gpio_data(gpionr, 0);
                SSYNC();
        }
@@ -193,7 +193,7 @@ static void bf561_gpio_mask_ack_irq(unsigned int irq)
 {
        u16 gpionr = irq - IRQ_PF0;
 
-       if(gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) {
+       if (gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) {
                set_gpio_data(gpionr, 0);
                SSYNC();
        }
@@ -222,7 +222,7 @@ static unsigned int bf561_gpio_irq_startup(unsigned int irq)
        if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
 
                ret = gpio_request(gpionr, NULL);
-               if(ret)
+               if (ret)
                        return ret;
 
        }
@@ -262,7 +262,7 @@ static int bf561_gpio_irq_type(unsigned int irq, unsigned int type)
                if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
 
                        ret = gpio_request(gpionr, NULL);
-                       if(ret)
+                       if (ret)
                                return ret;
 
                }
@@ -371,6 +371,9 @@ int __init init_arch_irq(void)
        bfin_write_SICA_IMASK1(SIC_UNMASK_ALL);
        SSYNC();
 
+       bfin_write_SICA_IWR0(IWR_ENABLE_ALL);
+       bfin_write_SICA_IWR1(IWR_ENABLE_ALL);
+
        local_irq_disable();
 
        init_exception_buff();
@@ -393,7 +396,7 @@ int __init init_arch_irq(void)
        bfin_write_EVT15(evt_system_call);
        CSYNC();
 
-       for (irq = 0; irq < SYS_IRQS; irq++) {
+       for (irq = 0; irq <= SYS_IRQS; irq++) {
                if (irq <= IRQ_CORETMR)
                        set_irq_chip(irq, &bf561_core_irqchip);
                else
index 2cfc7d5aec5cafba6846f4a4cc9bb489e726fe7e..28a878c3577a00d78e280b137e09be5124c4351d 100644 (file)
@@ -13,7 +13,7 @@
  *               2002 Arcturus Networks Inc. MaTed <mated@sympatico.ca>
  *               2003 Metrowerks/Motorola
  *               2003 Bas Vermeulen <bas@buyways.nl>
- *               Copyright 2004-2006 Analog Devices Inc.
+ *               Copyright 2004-2007 Analog Devices Inc.
  *
  * Bugs:         Enter bugs at http://blackfin.uclinux.org/
  *
@@ -65,9 +65,9 @@ atomic_t num_spurious;
 
 struct ivgx {
        /* irq number for request_irq, available in mach-bf533/irq.h */
-       int irqno;
+       unsigned int irqno;
        /* corresponding bit in the SIC_ISR register */
-       int isrflag;
+       unsigned int isrflag;
 } ivg_table[NR_PERI_INTS];
 
 struct ivg_slice {
@@ -88,17 +88,16 @@ static void __init search_IAR(void)
        for (ivg = 0; ivg <= IVG13 - IVG7; ivg++) {
                int irqn;
 
-               ivg7_13[ivg].istop = ivg7_13[ivg].ifirst =
-                   &ivg_table[irq_pos];
+               ivg7_13[ivg].istop = ivg7_13[ivg].ifirst = &ivg_table[irq_pos];
 
                for (irqn = 0; irqn < NR_PERI_INTS; irqn++) {
                        int iar_shift = (irqn & 7) * 4;
                        if (ivg ==
                            (0xf &
-                            bfin_read32((unsigned long *) SIC_IAR0 +
+                            bfin_read32((unsigned long *)SIC_IAR0 +
                                         (irqn >> 3)) >> iar_shift)) {
                                ivg_table[irq_pos].irqno = IVG7 + irqn;
-                               ivg_table[irq_pos].isrflag = 1 << irqn;
+                               ivg_table[irq_pos].isrflag = 1 << (irqn % 32);
                                ivg7_13[ivg].istop++;
                                irq_pos++;
                        }
@@ -141,15 +140,31 @@ static void bfin_core_unmask_irq(unsigned int irq)
 
 static void bfin_internal_mask_irq(unsigned int irq)
 {
+#ifndef CONFIG_BF54x
        bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() &
                             ~(1 << (irq - (IRQ_CORETMR + 1))));
+#else
+       unsigned mask_bank, mask_bit;
+       mask_bank = (irq - (IRQ_CORETMR + 1)) / 32;
+       mask_bit = (irq - (IRQ_CORETMR + 1)) % 32;
+       bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) &
+                            ~(1 << mask_bit));
+#endif
        SSYNC();
 }
 
 static void bfin_internal_unmask_irq(unsigned int irq)
 {
+#ifndef CONFIG_BF54x
        bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() |
                             (1 << (irq - (IRQ_CORETMR + 1))));
+#else
+       unsigned mask_bank, mask_bit;
+       mask_bank = (irq - (IRQ_CORETMR + 1)) / 32;
+       mask_bit = (irq - (IRQ_CORETMR + 1)) % 32;
+       bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) |
+                            (1 << mask_bit));
+#endif
        SSYNC();
 }
 
@@ -206,7 +221,7 @@ static struct irq_chip bfin_generic_error_irqchip = {
 };
 
 static void bfin_demux_error_irq(unsigned int int_err_irq,
-                                 struct irq_desc *intb_desc)
+                                struct irq_desc *intb_desc)
 {
        int irq = 0;
 
@@ -270,8 +285,8 @@ static void bfin_demux_error_irq(unsigned int int_err_irq,
                        }
 
                        pr_debug("IRQ %d:"
-                               " MASKED PERIPHERAL ERROR INTERRUPT ASSERTED\n",
-                               irq);
+                                " MASKED PERIPHERAL ERROR INTERRUPT ASSERTED\n",
+                                irq);
                }
        } else
                printk(KERN_ERR
@@ -279,11 +294,10 @@ static void bfin_demux_error_irq(unsigned int int_err_irq,
                       " INTERRUPT ASSERTED BUT NO SOURCE FOUND\n",
                       __FUNCTION__, __FILE__, __LINE__);
 
-
 }
 #endif                         /* BF537_GENERIC_ERROR_INT_DEMUX */
 
-#ifdef CONFIG_IRQCHIP_DEMUX_GPIO
+#if defined(CONFIG_IRQCHIP_DEMUX_GPIO) && !defined(CONFIG_BF54x)
 
 static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)];
 static unsigned short gpio_edge_triggered[gpio_bank(MAX_BLACKFIN_GPIOS)];
@@ -361,8 +375,7 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
        }
 
        if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING |
-                   IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW))
-       {
+                   IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
                if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
                        ret = gpio_request(gpionr, NULL);
                        if (ret)
@@ -407,7 +420,6 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
        return 0;
 }
 
-
 static struct irq_chip bfin_gpio_irqchip = {
        .ack = bfin_gpio_ack_irq,
        .mask = bfin_gpio_mask_irq,
@@ -419,20 +431,20 @@ static struct irq_chip bfin_gpio_irqchip = {
 };
 
 static void bfin_demux_gpio_irq(unsigned int intb_irq,
-                                struct irq_desc *intb_desc)
+                               struct irq_desc *intb_desc)
 {
        u16 i;
+       struct irq_desc *desc;
 
-       for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=16) {
+       for (i = 0; i < MAX_BLACKFIN_GPIOS; i += 16) {
                int irq = IRQ_PF0 + i;
                int flag_d = get_gpiop_data(i);
                int mask =
-                       flag_d & (gpio_enabled[gpio_bank(i)] &
-                             get_gpiop_maska(i));
+                   flag_d & (gpio_enabled[gpio_bank(i)] & get_gpiop_maska(i));
 
                while (mask) {
                        if (mask & 1) {
-                               struct irq_desc *desc = irq_desc + irq;
+                               desc = irq_desc + irq;
                                desc->handle_irq(irq, desc);
                        }
                        irq++;
@@ -441,6 +453,264 @@ static void bfin_demux_gpio_irq(unsigned int intb_irq,
        }
 }
 
+#else                          /* CONFIG_IRQCHIP_DEMUX_GPIO */
+
+#define NR_PINT_SYS_IRQS       4
+#define NR_PINT_BITS           32
+#define NR_PINTS               160
+#define IRQ_NOT_AVAIL          0xFF
+
+#define PINT_2_BANK(x)         ((x) >> 5)
+#define PINT_2_BIT(x)          ((x) & 0x1F)
+#define PINT_BIT(x)            (1 << (PINT_2_BIT(x)))
+
+static unsigned char irq2pint_lut[NR_PINTS];
+static unsigned char pint2irq_lut[NR_PINT_SYS_IRQS * NR_PINT_BITS];
+
+struct pin_int_t {
+       unsigned int mask_set;
+       unsigned int mask_clear;
+       unsigned int request;
+       unsigned int assign;
+       unsigned int edge_set;
+       unsigned int edge_clear;
+       unsigned int invert_set;
+       unsigned int invert_clear;
+       unsigned int pinstate;
+       unsigned int latch;
+};
+
+static struct pin_int_t *pint[NR_PINT_SYS_IRQS] = {
+       (struct pin_int_t *)PINT0_MASK_SET,
+       (struct pin_int_t *)PINT1_MASK_SET,
+       (struct pin_int_t *)PINT2_MASK_SET,
+       (struct pin_int_t *)PINT3_MASK_SET,
+};
+
+unsigned short get_irq_base(u8 bank, u8 bmap)
+{
+
+       u16 irq_base;
+
+       if (bank < 2) {         /*PA-PB */
+               irq_base = IRQ_PA0 + bmap * 16;
+       } else {                /*PC-PJ */
+               irq_base = IRQ_PC0 + bmap * 16;
+       }
+
+       return irq_base;
+
+}
+
+       /* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */
+void init_pint_lut(void)
+{
+       u16 bank, bit, irq_base, bit_pos;
+       u32 pint_assign;
+       u8 bmap;
+
+       memset(irq2pint_lut, IRQ_NOT_AVAIL, sizeof(irq2pint_lut));
+
+       for (bank = 0; bank < NR_PINT_SYS_IRQS; bank++) {
+
+               pint_assign = pint[bank]->assign;
+
+               for (bit = 0; bit < NR_PINT_BITS; bit++) {
+
+                       bmap = (pint_assign >> ((bit / 8) * 8)) & 0xFF;
+
+                       irq_base = get_irq_base(bank, bmap);
+
+                       irq_base += (bit % 8) + ((bit / 8) & 1 ? 8 : 0);
+                       bit_pos = bit + bank * NR_PINT_BITS;
+
+                       pint2irq_lut[bit_pos] = irq_base - SYS_IRQS;
+                       irq2pint_lut[irq_base - SYS_IRQS] = bit_pos;
+
+               }
+
+       }
+
+}
+
+static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)];
+
+static void bfin_gpio_ack_irq(unsigned int irq)
+{
+       u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
+
+       pint[PINT_2_BANK(pint_val)]->request = PINT_BIT(pint_val);
+       SSYNC();
+}
+
+static void bfin_gpio_mask_ack_irq(unsigned int irq)
+{
+       u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
+       u32 pintbit = PINT_BIT(pint_val);
+       u8 bank = PINT_2_BANK(pint_val);
+
+       pint[bank]->request = pintbit;
+       pint[bank]->mask_clear = pintbit;
+       SSYNC();
+}
+
+static void bfin_gpio_mask_irq(unsigned int irq)
+{
+       u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
+
+       pint[PINT_2_BANK(pint_val)]->mask_clear = PINT_BIT(pint_val);
+       SSYNC();
+}
+
+static void bfin_gpio_unmask_irq(unsigned int irq)
+{
+       u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
+       u32 pintbit = PINT_BIT(pint_val);
+       u8 bank = PINT_2_BANK(pint_val);
+
+       pint[bank]->request = pintbit;
+       pint[bank]->mask_set = pintbit;
+       SSYNC();
+}
+
+static unsigned int bfin_gpio_irq_startup(unsigned int irq)
+{
+       unsigned int ret;
+       u16 gpionr = irq - IRQ_PA0;
+       u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
+
+       if (pint_val == IRQ_NOT_AVAIL)
+               return -ENODEV;
+
+       if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
+               ret = gpio_request(gpionr, NULL);
+               if (ret)
+                       return ret;
+       }
+
+       gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr);
+       bfin_gpio_unmask_irq(irq);
+
+       return ret;
+}
+
+static void bfin_gpio_irq_shutdown(unsigned int irq)
+{
+       bfin_gpio_mask_irq(irq);
+       gpio_free(irq - IRQ_PA0);
+       gpio_enabled[gpio_bank(irq - IRQ_PA0)] &= ~gpio_bit(irq - IRQ_PA0);
+}
+
+static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
+{
+
+       unsigned int ret;
+       u16 gpionr = irq - IRQ_PA0;
+       u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
+       u32 pintbit = PINT_BIT(pint_val);
+       u8 bank = PINT_2_BANK(pint_val);
+
+       if (pint_val == IRQ_NOT_AVAIL)
+               return -ENODEV;
+
+       if (type == IRQ_TYPE_PROBE) {
+               /* only probe unenabled GPIO interrupt lines */
+               if (gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))
+                       return 0;
+               type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
+       }
+
+       if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING |
+                   IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
+               if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
+                       ret = gpio_request(gpionr, NULL);
+                       if (ret)
+                               return ret;
+               }
+
+               gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr);
+       } else {
+               gpio_enabled[gpio_bank(gpionr)] &= ~gpio_bit(gpionr);
+               return 0;
+       }
+
+       gpio_direction_input(gpionr);
+
+       if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
+               pint[bank]->edge_set = pintbit;
+       } else {
+               pint[bank]->edge_clear = pintbit;
+       }
+
+       if ((type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW)))
+               pint[bank]->invert_set = pintbit;       /* low or falling edge denoted by one */
+       else
+               pint[bank]->invert_set = pintbit;       /* high or rising edge denoted by zero */
+
+       if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
+               pint[bank]->invert_set = pintbit;
+       else
+               pint[bank]->invert_set = pintbit;
+
+       SSYNC();
+
+       if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
+               set_irq_handler(irq, handle_edge_irq);
+       else
+               set_irq_handler(irq, handle_level_irq);
+
+       return 0;
+}
+
+static struct irq_chip bfin_gpio_irqchip = {
+       .ack = bfin_gpio_ack_irq,
+       .mask = bfin_gpio_mask_irq,
+       .mask_ack = bfin_gpio_mask_ack_irq,
+       .unmask = bfin_gpio_unmask_irq,
+       .set_type = bfin_gpio_irq_type,
+       .startup = bfin_gpio_irq_startup,
+       .shutdown = bfin_gpio_irq_shutdown
+};
+
+static void bfin_demux_gpio_irq(unsigned int intb_irq,
+                               struct irq_desc *intb_desc)
+{
+       u8 bank, pint_val;
+       u32 request, irq;
+       struct irq_desc *desc;
+
+       switch (intb_irq) {
+       case IRQ_PINT0:
+               bank = 0;
+               break;
+       case IRQ_PINT2:
+               bank = 2;
+               break;
+       case IRQ_PINT3:
+               bank = 3;
+               break;
+       case IRQ_PINT1:
+               bank = 1;
+               break;
+       default:
+               return;
+       }
+
+       pint_val = bank * NR_PINT_BITS;
+
+       request = pint[bank]->request;
+
+       while (request) {
+               if (request & 1) {
+                       irq = pint2irq_lut[pint_val] + SYS_IRQS;
+                       desc = irq_desc + irq;
+                       desc->handle_irq(irq, desc);
+               }
+               pint_val++;
+               request >>= 1;
+       }
+
+}
 #endif                         /* CONFIG_IRQCHIP_DEMUX_GPIO */
 
 /*
@@ -452,7 +722,18 @@ int __init init_arch_irq(void)
        int irq;
        unsigned long ilat = 0;
        /*  Disable all the peripheral intrs  - page 4-29 HW Ref manual */
+#ifdef CONFIG_BF54x
+       bfin_write_SIC_IMASK0(SIC_UNMASK_ALL);
+       bfin_write_SIC_IMASK1(SIC_UNMASK_ALL);
+       bfin_write_SIC_IMASK2(SIC_UNMASK_ALL);
+       bfin_write_SIC_IWR0(IWR_ENABLE_ALL);
+       bfin_write_SIC_IWR1(IWR_ENABLE_ALL);
+       bfin_write_SIC_IWR2(IWR_ENABLE_ALL);
+#else
        bfin_write_SIC_IMASK(SIC_UNMASK_ALL);
+       bfin_write_SIC_IWR(IWR_ENABLE_ALL);
+#endif
+
        SSYNC();
 
        local_irq_disable();
@@ -475,7 +756,18 @@ int __init init_arch_irq(void)
        bfin_write_EVT15(evt_system_call);
        CSYNC();
 
-       for (irq = 0; irq < SYS_IRQS; irq++) {
+#if defined(CONFIG_IRQCHIP_DEMUX_GPIO) && defined(CONFIG_BF54x)
+#ifdef CONFIG_PINTx_REASSIGN
+       pint[0]->assign = CONFIG_PINT0_ASSIGN;
+       pint[1]->assign = CONFIG_PINT1_ASSIGN;
+       pint[2]->assign = CONFIG_PINT2_ASSIGN;
+       pint[3]->assign = CONFIG_PINT3_ASSIGN;
+#endif
+       /* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */
+       init_pint_lut();
+#endif
+
+       for (irq = 0; irq <= SYS_IRQS; irq++) {
                if (irq <= IRQ_CORETMR)
                        set_irq_chip(irq, &bfin_core_irqchip);
                else
@@ -484,20 +776,42 @@ int __init init_arch_irq(void)
                if (irq != IRQ_GENERIC_ERROR) {
 #endif
 
+                       switch (irq) {
 #ifdef CONFIG_IRQCHIP_DEMUX_GPIO
-                       if ((irq != IRQ_PROG_INTA) /*PORT F & G MASK_A Interrupt*/
-# if defined(BF537_FAMILY) && !(defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE))
-                               && (irq != IRQ_MAC_RX) /*PORT H MASK_A Interrupt*/
-# endif
-                           ) {
+#ifndef CONFIG_BF54x
+                       case IRQ_PROG_INTA:
+                               set_irq_chained_handler(irq,
+                                                       bfin_demux_gpio_irq);
+                               break;
+#if defined(BF537_FAMILY) && !(defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE))
+                       case IRQ_MAC_RX:
+                               set_irq_chained_handler(irq,
+                                                       bfin_demux_gpio_irq);
+                               break;
 #endif
-                               set_irq_handler(irq, handle_simple_irq);
-#ifdef CONFIG_IRQCHIP_DEMUX_GPIO
-                       } else {
+#else
+                       case IRQ_PINT0:
                                set_irq_chained_handler(irq,
                                                        bfin_demux_gpio_irq);
-                       }
+                               break;
+                       case IRQ_PINT1:
+                               set_irq_chained_handler(irq,
+                                                       bfin_demux_gpio_irq);
+                               break;
+                       case IRQ_PINT2:
+                               set_irq_chained_handler(irq,
+                                                       bfin_demux_gpio_irq);
+                               break;
+                       case IRQ_PINT3:
+                               set_irq_chained_handler(irq,
+                                                       bfin_demux_gpio_irq);
+                               break;
+#endif                         /*CONFIG_BF54x */
 #endif
+                       default:
+                               set_irq_handler(irq, handle_simple_irq);
+                               break;
+                       }
 
 #ifdef BF537_GENERIC_ERROR_INT_DEMUX
                } else {
@@ -513,7 +827,11 @@ int __init init_arch_irq(void)
 #endif
 
 #ifdef CONFIG_IRQCHIP_DEMUX_GPIO
+#ifndef CONFIG_BF54x
        for (irq = IRQ_PF0; irq < NR_IRQS; irq++) {
+#else
+       for (irq = IRQ_PA0; irq < NR_IRQS; irq++) {
+#endif
                set_irq_chip(irq, &bfin_gpio_irqchip);
                /* if configured as edge, then will be changed to do_edge_IRQ */
                set_irq_handler(irq, handle_level_irq);
@@ -526,8 +844,7 @@ int __init init_arch_irq(void)
        bfin_write_ILAT(ilat);
        CSYNC();
 
-       printk(KERN_INFO
-              "Configuring Blackfin Priority Driven Interrupts\n");
+       printk(KERN_INFO "Configuring Blackfin Priority Driven Interrupts\n");
        /* IMASK=xxx is equivalent to STI xx or irq_flags=xx,
         * local_irq_enable()
         */
@@ -538,14 +855,13 @@ int __init init_arch_irq(void)
        /* Enable interrupts IVG7-15 */
        irq_flags = irq_flags | IMASK_IVG15 |
            IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 |
-           IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 |
-           IMASK_IVGHW;
+           IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW;
 
        return 0;
 }
 
 #ifdef CONFIG_DO_IRQ_L1
-void do_irq(int vec, struct pt_regs *fp)__attribute__((l1_text));
+void do_irq(int vec, struct pt_regs *fp) __attribute__((l1_text));
 #endif
 
 void do_irq(int vec, struct pt_regs *fp)
@@ -555,8 +871,24 @@ void do_irq(int vec, struct pt_regs *fp)
        } else {
                struct ivgx *ivg = ivg7_13[vec - IVG7].ifirst;
                struct ivgx *ivg_stop = ivg7_13[vec - IVG7].istop;
-               unsigned long sic_status;
+#ifdef CONFIG_BF54x
+               unsigned long sic_status[3];
 
+               SSYNC();
+               sic_status[0] = bfin_read_SIC_ISR(0) & bfin_read_SIC_IMASK(0);
+               sic_status[1] = bfin_read_SIC_ISR(1) & bfin_read_SIC_IMASK(1);
+               sic_status[2] = bfin_read_SIC_ISR(2) & bfin_read_SIC_IMASK(2);
+
+               for (;; ivg++) {
+                       if (ivg >= ivg_stop) {
+                               atomic_inc(&num_spurious);
+                               return;
+                       }
+                       if (sic_status[(ivg->irqno - IVG7) / 32] & ivg->isrflag)
+                               break;
+               }
+#else
+               unsigned long sic_status;
                SSYNC();
                sic_status = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR();
 
@@ -567,6 +899,7 @@ void do_irq(int vec, struct pt_regs *fp)
                        } else if (sic_status & ivg->isrflag)
                                break;
                }
+#endif
                vec = ivg->irqno;
        }
        asm_do_IRQ(vec, fp);
index 150ef5d088dcfedcdf0bb1d5a5922582c25c3f08..1772d8d2c1a7c30ea4b885afe794deac6a68481e 100644 (file)
 #include <linux/pm.h>
 #include <linux/sched.h>
 #include <linux/proc_fs.h>
+#include <linux/io.h>
+#include <linux/irq.h>
 
-#include <asm/io.h>
 #include <asm/dpmc.h>
-#include <asm/irq.h>
 #include <asm/gpio.h>
 
 #ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_H
index 68107924639ecd8bade350354e9a29d2500d939b..16c6169ed01bbe3357931d184d9532e5ac4649ab 100644 (file)
@@ -87,7 +87,7 @@ void __init l1sram_init(void)
               L1_SCRATCH_LENGTH >> 10);
 
        memset(&l1_ssram, 0x00, sizeof(l1_ssram));
-       l1_ssram[0].paddr = (void*)L1_SCRATCH_START;
+       l1_ssram[0].paddr = (void *)L1_SCRATCH_START;
        l1_ssram[0].size = L1_SCRATCH_LENGTH;
        l1_ssram[0].flag = SRAM_SLT_FREE;
 
@@ -126,7 +126,7 @@ void __init l1_inst_sram_init(void)
 {
 #if L1_CODE_LENGTH != 0
        memset(&l1_inst_sram, 0x00, sizeof(l1_inst_sram));
-       l1_inst_sram[0].paddr = (void*)L1_CODE_START + (_etext_l1 - _stext_l1);
+       l1_inst_sram[0].paddr = (void *)L1_CODE_START + (_etext_l1 - _stext_l1);
        l1_inst_sram[0].size = L1_CODE_LENGTH - (_etext_l1 - _stext_l1);
        l1_inst_sram[0].flag = SRAM_SLT_FREE;
 
index 570356dbe02843a144c486e5d4c94d892c076fd8..68459cc052a142ac14df1545c0c3fe86ec88428f 100644 (file)
@@ -29,8 +29,8 @@
 
 #include <linux/swap.h>
 #include <linux/bootmem.h>
+#include <linux/uaccess.h>
 #include <asm/bfin-global.h>
-#include <asm/uaccess.h>
 #include <asm/l1layout.h>
 #include "blackfin_sram.h"
 
@@ -168,42 +168,31 @@ void __init mem_init(void)
        }
 }
 
-#ifdef CONFIG_BLK_DEV_INITRD
-void __init free_initrd_mem(unsigned long start, unsigned long end)
+static __init void free_init_pages(const char *what, unsigned long begin, unsigned long end)
 {
-       int pages = 0;
-       for (; start < end; start += PAGE_SIZE) {
-               ClearPageReserved(virt_to_page(start));
-               init_page_count(virt_to_page(start));
-               free_page(start);
+       unsigned long addr;
+       /* next to check that the page we free is not a partial page */
+       for (addr = begin; addr + PAGE_SIZE <= end; addr += PAGE_SIZE) {
+               ClearPageReserved(virt_to_page(addr));
+               init_page_count(virt_to_page(addr));
+               free_page(addr);
                totalram_pages++;
-               pages++;
        }
-       printk(KERN_NOTICE "Freeing initrd memory: %dk freed\n", pages);
+       printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10);
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+void __init free_initrd_mem(unsigned long start, unsigned long end)
+{
+       free_init_pages("initrd memory", start, end);
 }
 #endif
 
 void __init free_initmem(void)
 {
 #ifdef CONFIG_RAMKERNEL
-       unsigned long addr;
-       /*
-        *      the following code should be cool even if these sections
-        *      are not page aligned.
-        */
-       addr = PAGE_ALIGN((unsigned long)(__init_begin));
-       /* next to check that the page we free is not a partial page */
-       for (; addr + PAGE_SIZE < (unsigned long)(__init_end);
-            addr += PAGE_SIZE) {
-               ClearPageReserved(virt_to_page(addr));
-               init_page_count(virt_to_page(addr));
-               free_page(addr);
-               totalram_pages++;
-       }
-       printk(KERN_NOTICE
-              "Freeing unused kernel memory: %ldk freed (0x%x - 0x%x)\n",
-              (addr - PAGE_ALIGN((long)__init_begin)) >> 10,
-              (int)(PAGE_ALIGN((unsigned long)(__init_begin))),
-              (int)(addr - PAGE_SIZE));
+       free_init_pages("unused kernel memory",
+                       (unsigned long)(&__init_begin),
+                       (unsigned long)(&__init_end));
 #endif
 }
index 009a1700c854fd5b09be02a3ae37d6440a9ea8da..cb8b8d5af34fa450f1c58273d10acf71428eff2b 100644 (file)
 #include <linux/smp.h>
 #include <linux/errno.h>
 #include <linux/mutex.h>
+#include <linux/ptrace.h>
+#include <linux/irq.h>
+#include <linux/io.h>
 
-#include <asm/ptrace.h>
 #include <asm/system.h>
 #include <asm/blackfin.h>
-#include <asm/irq.h>
-#include <asm/io.h>
 
 #include "op_blackfin.h"
 
index b7a20a006b4921cc6d7cbb224412bb8d39c0f83b..872dffe3362360f6eb1e46e4d9d53961d04c359e 100644 (file)
 #include <linux/init.h>
 #include <linux/smp.h>
 #include <linux/interrupt.h>
-#include <asm/ptrace.h>
+#include <linux/ptrace.h>
+#include <linux/irq.h>
+#include <linux/io.h>
 #include <asm/system.h>
 #include <asm/processor.h>
 #include <asm/blackfin.h>
-#include <asm/irq.h>
-#include <asm/io.h>
 
 #include "op_blackfin.h"
 
index 8fba16c846c9b6ea3d7711529a647f22c2bc5200..6c6f8606af4ceefcfd0dd0b81b25f9c60835808b 100644 (file)
@@ -31,8 +31,7 @@
 #include <linux/smp.h>
 #include <linux/irq.h>
 #include <linux/oprofile.h>
-
-#include <asm/ptrace.h>
+#include <linux/ptrace.h>
 
 static void enable_sys_timer0()
 {
index 5c95ceb7f1225515ab3ad200a8f1e7a278a2ee18..9cbe76c3aa359763c6650aa4a57d97c16ee5d4e4 100644 (file)
@@ -344,8 +344,8 @@ config X86_CMOV
        depends on (MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7)
        default y
 
-config X86_MINIMUM_CPU_MODEL
+config X86_MINIMUM_CPU_FAMILY
        int
-       default "4" if X86_XADD || X86_CMPXCHG || X86_BSWAP
-       default "0"
+       default "4" if X86_XADD || X86_CMPXCHG || X86_BSWAP || X86_WP_WORKS_OK
+       default "3"
 
index bfbc32098a4a8ed33237915b9991e96ac001bd75..08678a0a3d191a8a197763bc35202d0c79765b33 100644 (file)
@@ -25,27 +25,56 @@ SVGA_MODE := -DSVGA_MODE=NORMAL_VGA
 
 #RAMDISK := -DRAMDISK=512
 
-targets                := vmlinux.bin bootsect bootsect.o \
-                  setup setup.o zImage bzImage
+targets                := vmlinux.bin setup.bin setup.elf zImage bzImage
 subdir-        := compressed
 
+setup-y                += a20.o apm.o cmdline.o copy.o cpu.o cpucheck.o edd.o
+setup-y                += header.o main.o mca.o memory.o pm.o pmjump.o
+setup-y                += printf.o string.o tty.o video.o version.o voyager.o
+
+# The link order of the video-*.o modules can matter.  In particular,
+# video-vga.o *must* be listed first, followed by video-vesa.o.
+# Hardware-specific drivers should follow in the order they should be
+# probed, and video-bios.o should typically be last.
+setup-y                += video-vga.o
+setup-y                += video-vesa.o
+setup-y                += video-bios.o
+
 hostprogs-y    := tools/build
 
 HOSTCFLAGS_build.o := $(LINUXINCLUDE)
 
 # ---------------------------------------------------------------------------
 
+# How to compile the 16-bit code.  Note we always compile for -march=i386,
+# that way we can complain to the user if the CPU is insufficient.
+cflags-i386   := 
+cflags-x86_64 := -m32
+CFLAGS         := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
+                  $(cflags-$(ARCH)) \
+                  -Wall -Wstrict-prototypes \
+                  -march=i386 -mregparm=3 \
+                  -include $(srctree)/$(src)/code16gcc.h \
+                  -fno-strict-aliasing -fomit-frame-pointer \
+                  $(call cc-option, -ffreestanding) \
+                  $(call cc-option, -fno-toplevel-reorder,\
+                       $(call cc-option, -fno-unit-at-a-time)) \
+                  $(call cc-option, -fno-stack-protector) \
+                  $(call cc-option, -mpreferred-stack-boundary=2)
+AFLAGS         := $(CFLAGS) -D__ASSEMBLY__
+
 $(obj)/zImage:  IMAGE_OFFSET := 0x1000
 $(obj)/zImage:  EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK)
 $(obj)/bzImage: IMAGE_OFFSET := 0x100000
+$(obj)/bzImage: EXTRA_CFLAGS := -D__BIG_KERNEL__
 $(obj)/bzImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__
 $(obj)/bzImage: BUILDFLAGS   := -b
 
 quiet_cmd_image = BUILD   $@
-cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/bootsect $(obj)/setup \
+cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/setup.bin \
            $(obj)/vmlinux.bin $(ROOT_DEV) > $@
 
-$(obj)/zImage $(obj)/bzImage: $(obj)/bootsect $(obj)/setup \
+$(obj)/zImage $(obj)/bzImage: $(obj)/setup.bin \
                              $(obj)/vmlinux.bin $(obj)/tools/build FORCE
        $(call if_changed,image)
        @echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
@@ -53,12 +82,17 @@ $(obj)/zImage $(obj)/bzImage: $(obj)/bootsect $(obj)/setup \
 $(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE
        $(call if_changed,objcopy)
 
-LDFLAGS_bootsect := -Ttext 0x0 -s --oformat binary
-LDFLAGS_setup   := -Ttext 0x0 -s --oformat binary -e begtext
+SETUP_OBJS = $(addprefix $(obj)/,$(setup-y))
 
-$(obj)/setup $(obj)/bootsect: %: %.o FORCE
+LDFLAGS_setup.elf      := -T
+$(obj)/setup.elf: $(src)/setup.ld $(SETUP_OBJS) FORCE
        $(call if_changed,ld)
 
+OBJCOPYFLAGS_setup.bin := -O binary
+
+$(obj)/setup.bin: $(obj)/setup.elf FORCE
+       $(call if_changed,objcopy)
+
 $(obj)/compressed/vmlinux: FORCE
        $(Q)$(MAKE) $(build)=$(obj)/compressed IMAGE_OFFSET=$(IMAGE_OFFSET) $@
 
diff --git a/arch/i386/boot/a20.c b/arch/i386/boot/a20.c
new file mode 100644 (file)
index 0000000..31348d0
--- /dev/null
@@ -0,0 +1,161 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/a20.c
+ *
+ * Enable A20 gate (return -1 on failure)
+ */
+
+#include "boot.h"
+
+#define MAX_8042_LOOPS 100000
+
+static int empty_8042(void)
+{
+       u8 status;
+       int loops = MAX_8042_LOOPS;
+
+       while (loops--) {
+               io_delay();
+
+               status = inb(0x64);
+               if (status & 1) {
+                       /* Read and discard input data */
+                       io_delay();
+                       (void)inb(0x60);
+               } else if (!(status & 2)) {
+                       /* Buffers empty, finished! */
+                       return 0;
+               }
+       }
+
+       return -1;
+}
+
+/* Returns nonzero if the A20 line is enabled.  The memory address
+   used as a test is the int $0x80 vector, which should be safe. */
+
+#define A20_TEST_ADDR  (4*0x80)
+#define A20_TEST_SHORT  32
+#define A20_TEST_LONG  2097152 /* 2^21 */
+
+static int a20_test(int loops)
+{
+       int ok = 0;
+       int saved, ctr;
+
+       set_fs(0x0000);
+       set_gs(0xffff);
+
+       saved = ctr = rdfs32(A20_TEST_ADDR);
+
+       while (loops--) {
+               wrfs32(++ctr, A20_TEST_ADDR);
+               io_delay();     /* Serialize and make delay constant */
+               ok = rdgs32(A20_TEST_ADDR+0x10) ^ ctr;
+               if (ok)
+                       break;
+       }
+
+       wrfs32(saved, A20_TEST_ADDR);
+       return ok;
+}
+
+/* Quick test to see if A20 is already enabled */
+static int a20_test_short(void)
+{
+       return a20_test(A20_TEST_SHORT);
+}
+
+/* Longer test that actually waits for A20 to come on line; this
+   is useful when dealing with the KBC or other slow external circuitry. */
+static int a20_test_long(void)
+{
+       return a20_test(A20_TEST_LONG);
+}
+
+static void enable_a20_bios(void)
+{
+       asm volatile("pushfl; int $0x15; popfl"
+                    : : "a" ((u16)0x2401));
+}
+
+static void enable_a20_kbc(void)
+{
+       empty_8042();
+
+       outb(0xd1, 0x64);       /* Command write */
+       empty_8042();
+
+       outb(0xdf, 0x60);       /* A20 on */
+       empty_8042();
+}
+
+static void enable_a20_fast(void)
+{
+       u8 port_a;
+
+       port_a = inb(0x92);     /* Configuration port A */
+       port_a |=  0x02;        /* Enable A20 */
+       port_a &= ~0x01;        /* Do not reset machine */
+       outb(port_a, 0x92);
+}
+
+/*
+ * Actual routine to enable A20; return 0 on ok, -1 on failure
+ */
+
+#define A20_ENABLE_LOOPS 255   /* Number of times to try */
+
+int enable_a20(void)
+{
+       int loops = A20_ENABLE_LOOPS;
+
+#if defined(CONFIG_X86_ELAN)
+       /* Elan croaks if we try to touch the KBC */
+       enable_a20_fast();
+       while (!a20_test_long())
+               ;
+       return 0;
+#elif defined(CONFIG_X86_VOYAGER)
+       /* On Voyager, a20_test() is unsafe? */
+       enable_a20_kbc();
+       return 0;
+#else
+       while (loops--) {
+               /* First, check to see if A20 is already enabled
+                  (legacy free, etc.) */
+               if (a20_test_short())
+                       return 0;
+
+               /* Next, try the BIOS (INT 0x15, AX=0x2401) */
+               enable_a20_bios();
+               if (a20_test_short())
+                       return 0;
+
+               /* Try enabling A20 through the keyboard controller */
+               empty_8042();
+               if (a20_test_short())
+                       return 0; /* BIOS worked, but with delayed reaction */
+
+               enable_a20_kbc();
+               if (a20_test_long())
+                       return 0;
+
+               /* Finally, try enabling the "fast A20 gate" */
+               enable_a20_fast();
+               if (a20_test_long())
+                       return 0;
+       }
+
+       return -1;
+#endif
+}
diff --git a/arch/i386/boot/apm.c b/arch/i386/boot/apm.c
new file mode 100644 (file)
index 0000000..a34087c
--- /dev/null
@@ -0,0 +1,97 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   Original APM BIOS checking by Stephen Rothwell, May 1994
+ *   (sfr@canb.auug.org.au)
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/apm.c
+ *
+ * Get APM BIOS information
+ */
+
+#include "boot.h"
+
+#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
+
+int query_apm_bios(void)
+{
+       u16 ax, bx, cx, dx, di;
+       u32 ebx, esi;
+       u8 err;
+
+       /* APM BIOS installation check */
+       ax = 0x5300;
+       bx = cx = 0;
+       asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %0"
+                    : "=d" (err), "+a" (ax), "+b" (bx), "+c" (cx)
+                    : : "esi", "edi");
+
+       if (err)
+               return -1;              /* No APM BIOS */
+
+       if (bx != 0x504d)       /* "PM" signature */
+               return -1;
+
+       if (cx & 0x02)          /* 32 bits supported? */
+               return -1;
+
+       /* Disconnect first, just in case */
+       ax = 0x5304;
+       asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp"
+                    : "+a" (ax)
+                    : : "ebx", "ecx", "edx", "esi", "edi");
+
+       /* Paranoia */
+       ebx = esi = 0;
+       cx = dx = di = 0;
+
+       /* 32-bit connect */
+       asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %6"
+                    : "=a" (ax), "+b" (ebx), "+c" (cx), "+d" (dx),
+                      "+S" (esi), "+D" (di), "=m" (err)
+                    : "a" (0x5303));
+
+       boot_params.apm_bios_info.cseg = ax;
+       boot_params.apm_bios_info.offset = ebx;
+       boot_params.apm_bios_info.cseg_16 = cx;
+       boot_params.apm_bios_info.dseg = dx;
+       boot_params.apm_bios_info.cseg_len = (u16)esi;
+       boot_params.apm_bios_info.cseg_16_len = esi >> 16;
+       boot_params.apm_bios_info.dseg_len = di;
+
+       if (err)
+               return -1;
+
+       /* Redo the installation check as the 32-bit connect;
+          some BIOSes return different flags this way... */
+
+       ax = 0x5300;
+       bx = cx = 0;
+       asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %0"
+                    : "=d" (err), "+a" (ax), "+b" (bx), "+c" (cx)
+                    : : "esi", "edi");
+
+       if (err || bx != 0x504d) {
+               /* Failure with 32-bit connect, try to disconect and ignore */
+               ax = 0x5304;
+               bx = 0;
+               asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp"
+                            : "+a" (ax), "+b" (bx)
+                            : : "ecx", "edx", "esi", "edi");
+               return -1;
+       }
+
+       boot_params.apm_bios_info.version = ax;
+       boot_params.apm_bios_info.flags = cx;
+       return 0;
+}
+
+#endif
diff --git a/arch/i386/boot/bitops.h b/arch/i386/boot/bitops.h
new file mode 100644 (file)
index 0000000..8dcc8dc
--- /dev/null
@@ -0,0 +1,45 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/bitops.h
+ *
+ * Very simple bitops for the boot code.
+ */
+
+#ifndef BOOT_BITOPS_H
+#define BOOT_BITOPS_H
+#define _LINUX_BITOPS_H                /* Inhibit inclusion of <linux/bitops.h> */
+
+static inline int constant_test_bit(int nr, const void *addr)
+{
+       const u32 *p = (const u32 *)addr;
+       return ((1UL << (nr & 31)) & (p[nr >> 5])) != 0;
+}
+static inline int variable_test_bit(int nr, const void *addr)
+{
+       u8 v;
+       const u32 *p = (const u32 *)addr;
+
+       asm("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
+       return v;
+}
+
+#define test_bit(nr,addr) \
+(__builtin_constant_p(nr) ? \
+ constant_test_bit((nr),(addr)) : \
+ variable_test_bit((nr),(addr)))
+
+static inline void set_bit(int nr, void *addr)
+{
+       asm("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
+}
+
+#endif /* BOOT_BITOPS_H */
diff --git a/arch/i386/boot/boot.h b/arch/i386/boot/boot.h
new file mode 100644 (file)
index 0000000..0329c4f
--- /dev/null
@@ -0,0 +1,296 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/boot.h
+ *
+ * Header file for the real-mode kernel code
+ */
+
+#ifndef BOOT_BOOT_H
+#define BOOT_BOOT_H
+
+#ifndef __ASSEMBLY__
+
+#include <stdarg.h>
+#include <linux/types.h>
+#include <linux/edd.h>
+#include <asm/boot.h>
+#include <asm/bootparam.h>
+
+/* Useful macros */
+#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
+
+extern struct setup_header hdr;
+extern struct boot_params boot_params;
+
+/* Basic port I/O */
+static inline void outb(u8 v, u16 port)
+{
+       asm volatile("outb %0,%1" : : "a" (v), "dN" (port));
+}
+static inline u8 inb(u16 port)
+{
+       u8 v;
+       asm volatile("inb %1,%0" : "=a" (v) : "dN" (port));
+       return v;
+}
+
+static inline void outw(u16 v, u16 port)
+{
+       asm volatile("outw %0,%1" : : "a" (v), "dN" (port));
+}
+static inline u16 inw(u16 port)
+{
+       u16 v;
+       asm volatile("inw %1,%0" : "=a" (v) : "dN" (port));
+       return v;
+}
+
+static inline void outl(u32 v, u16 port)
+{
+       asm volatile("outl %0,%1" : : "a" (v), "dn" (port));
+}
+static inline u32 inl(u32 port)
+{
+       u32 v;
+       asm volatile("inl %1,%0" : "=a" (v) : "dN" (port));
+       return v;
+}
+
+static inline void io_delay(void)
+{
+       const u16 DELAY_PORT = 0x80;
+       asm volatile("outb %%al,%0" : : "dN" (DELAY_PORT));
+}
+
+/* These functions are used to reference data in other segments. */
+
+static inline u16 ds(void)
+{
+       u16 seg;
+       asm("movw %%ds,%0" : "=rm" (seg));
+       return seg;
+}
+
+static inline void set_fs(u16 seg)
+{
+       asm volatile("movw %0,%%fs" : : "rm" (seg));
+}
+static inline u16 fs(void)
+{
+       u16 seg;
+       asm("movw %%fs,%0" : "=rm" (seg));
+       return seg;
+}
+
+static inline void set_gs(u16 seg)
+{
+       asm volatile("movw %0,%%gs" : : "rm" (seg));
+}
+static inline u16 gs(void)
+{
+       u16 seg;
+       asm("movw %%gs,%0" : "=rm" (seg));
+       return seg;
+}
+
+typedef unsigned int addr_t;
+
+static inline u8 rdfs8(addr_t addr)
+{
+       u8 v;
+       asm("movb %%fs:%1,%0" : "=r" (v) : "m" (*(u8 *)addr));
+       return v;
+}
+static inline u16 rdfs16(addr_t addr)
+{
+       u16 v;
+       asm("movw %%fs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr));
+       return v;
+}
+static inline u32 rdfs32(addr_t addr)
+{
+       u32 v;
+       asm("movl %%fs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr));
+       return v;
+}
+
+static inline void wrfs8(u8 v, addr_t addr)
+{
+       asm volatile("movb %1,%%fs:%0" : "+m" (*(u8 *)addr) : "r" (v));
+}
+static inline void wrfs16(u16 v, addr_t addr)
+{
+       asm volatile("movw %1,%%fs:%0" : "+m" (*(u16 *)addr) : "r" (v));
+}
+static inline void wrfs32(u32 v, addr_t addr)
+{
+       asm volatile("movl %1,%%fs:%0" : "+m" (*(u32 *)addr) : "r" (v));
+}
+
+static inline u8 rdgs8(addr_t addr)
+{
+       u8 v;
+       asm("movb %%gs:%1,%0" : "=r" (v) : "m" (*(u8 *)addr));
+       return v;
+}
+static inline u16 rdgs16(addr_t addr)
+{
+       u16 v;
+       asm("movw %%gs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr));
+       return v;
+}
+static inline u32 rdgs32(addr_t addr)
+{
+       u32 v;
+       asm("movl %%gs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr));
+       return v;
+}
+
+static inline void wrgs8(u8 v, addr_t addr)
+{
+       asm volatile("movb %1,%%gs:%0" : "+m" (*(u8 *)addr) : "r" (v));
+}
+static inline void wrgs16(u16 v, addr_t addr)
+{
+       asm volatile("movw %1,%%gs:%0" : "+m" (*(u16 *)addr) : "r" (v));
+}
+static inline void wrgs32(u32 v, addr_t addr)
+{
+       asm volatile("movl %1,%%gs:%0" : "+m" (*(u32 *)addr) : "r" (v));
+}
+
+/* Note: these only return true/false, not a signed return value! */
+static inline int memcmp(const void *s1, const void *s2, size_t len)
+{
+       u8 diff;
+       asm("repe; cmpsb; setnz %0"
+           : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
+       return diff;
+}
+
+static inline int memcmp_fs(const void *s1, addr_t s2, size_t len)
+{
+       u8 diff;
+       asm("fs; repe; cmpsb; setnz %0"
+           : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
+       return diff;
+}
+static inline int memcmp_gs(const void *s1, addr_t s2, size_t len)
+{
+       u8 diff;
+       asm("gs; repe; cmpsb; setnz %0"
+           : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
+       return diff;
+}
+
+static inline int isdigit(int ch)
+{
+       return (ch >= '0') && (ch <= '9');
+}
+
+/* Heap -- available for dynamic lists. */
+#define STACK_SIZE     512     /* Minimum number of bytes for stack */
+
+extern char _end[];
+extern char *HEAP;
+extern char *heap_end;
+#define RESET_HEAP() ((void *)( HEAP = _end ))
+static inline char *__get_heap(size_t s, size_t a, size_t n)
+{
+       char *tmp;
+
+       HEAP = (char *)(((size_t)HEAP+(a-1)) & ~(a-1));
+       tmp = HEAP;
+       HEAP += s*n;
+       return tmp;
+}
+#define GET_HEAP(type, n) \
+       ((type *)__get_heap(sizeof(type),__alignof__(type),(n)))
+
+static inline int heap_free(void)
+{
+       return heap_end-HEAP;
+}
+
+/* copy.S */
+
+void copy_to_fs(addr_t dst, void *src, size_t len);
+void *copy_from_fs(void *dst, addr_t src, size_t len);
+void copy_to_gs(addr_t dst, void *src, size_t len);
+void *copy_from_gs(void *dst, addr_t src, size_t len);
+void *memcpy(void *dst, void *src, size_t len);
+void *memset(void *dst, int c, size_t len);
+
+#define memcpy(d,s,l) __builtin_memcpy(d,s,l)
+#define memset(d,c,l) __builtin_memset(d,c,l)
+
+/* a20.c */
+int enable_a20(void);
+
+/* apm.c */
+int query_apm_bios(void);
+
+/* cmdline.c */
+int cmdline_find_option(const char *option, char *buffer, int bufsize);
+
+/* cpu.c, cpucheck.c */
+int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr);
+int validate_cpu(void);
+
+/* edd.c */
+void query_edd(void);
+
+/* header.S */
+void __attribute__((noreturn)) die(void);
+
+/* mca.c */
+int query_mca(void);
+
+/* memory.c */
+int detect_memory(void);
+
+/* pm.c */
+void __attribute__((noreturn)) go_to_protected_mode(void);
+
+/* pmjump.S */
+void __attribute__((noreturn))
+       protected_mode_jump(u32 entrypoint, u32 bootparams);
+
+/* printf.c */
+int sprintf(char *buf, const char *fmt, ...);
+int vsprintf(char *buf, const char *fmt, va_list args);
+int printf(const char *fmt, ...);
+
+/* string.c */
+int strcmp(const char *str1, const char *str2);
+size_t strnlen(const char *s, size_t maxlen);
+unsigned int atou(const char *s);
+
+/* tty.c */
+void puts(const char *);
+void putchar(int);
+int getchar(void);
+void kbd_flush(void);
+int getchar_timeout(void);
+
+/* video.c */
+void set_video(void);
+
+/* video-vesa.c */
+void vesa_store_edid(void);
+
+/* voyager.c */
+int query_voyager(void);
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* BOOT_BOOT_H */
diff --git a/arch/i386/boot/bootsect.S b/arch/i386/boot/bootsect.S
deleted file mode 100644 (file)
index 011b7a4..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- *     bootsect.S              Copyright (C) 1991, 1992 Linus Torvalds
- *
- *     modified by Drew Eckhardt
- *     modified by Bruce Evans (bde)
- *     modified by Chris Noe (May 1999) (as86 -> gas)
- *     gutted by H. Peter Anvin (Jan 2003)
- *
- * BIG FAT NOTE: We're in real mode using 64k segments.  Therefore segment
- * addresses must be multiplied by 16 to obtain their respective linear
- * addresses. To avoid confusion, linear addresses are written using leading
- * hex while segment addresses are written as segment:offset.
- *
- */
-
-#include <asm/boot.h>
-
-SETUPSECTS     = 4                     /* default nr of setup-sectors */
-BOOTSEG                = 0x07C0                /* original address of boot-sector */
-INITSEG                = DEF_INITSEG           /* we move boot here - out of the way */
-SETUPSEG       = DEF_SETUPSEG          /* setup starts here */
-SYSSEG         = DEF_SYSSEG            /* system loaded at 0x10000 (65536) */
-SYSSIZE                = DEF_SYSSIZE           /* system size: # of 16-byte clicks */
-                                       /* to be loaded */
-ROOT_DEV       = 0                     /* ROOT_DEV is now written by "build" */
-SWAP_DEV       = 0                     /* SWAP_DEV is now written by "build" */
-
-#ifndef SVGA_MODE
-#define SVGA_MODE ASK_VGA
-#endif
-
-#ifndef RAMDISK
-#define RAMDISK 0
-#endif
-
-#ifndef ROOT_RDONLY
-#define ROOT_RDONLY 1
-#endif
-
-.code16
-.text
-
-.global _start
-_start:
-
-       # Normalize the start address
-       jmpl    $BOOTSEG, $start2
-
-start2:
-       movw    %cs, %ax
-       movw    %ax, %ds
-       movw    %ax, %es
-       movw    %ax, %ss
-       movw    $0x7c00, %sp
-       sti
-       cld
-
-       movw    $bugger_off_msg, %si
-
-msg_loop:
-       lodsb
-       andb    %al, %al
-       jz      die
-       movb    $0xe, %ah
-       movw    $7, %bx
-       int     $0x10
-       jmp     msg_loop
-
-die:
-       # Allow the user to press a key, then reboot
-       xorw    %ax, %ax
-       int     $0x16
-       int     $0x19
-
-       # int 0x19 should never return.  In case it does anyway,
-       # invoke the BIOS reset code...
-       ljmp    $0xf000,$0xfff0
-
-
-bugger_off_msg:
-       .ascii  "Direct booting from floppy is no longer supported.\r\n"
-       .ascii  "Please use a boot loader program instead.\r\n"
-       .ascii  "\n"
-       .ascii  "Remove disk and press any key to reboot . . .\r\n"
-       .byte   0
-
-
-       # Kernel attributes; used by setup
-
-       .org 497
-setup_sects:   .byte SETUPSECTS
-root_flags:    .word ROOT_RDONLY
-syssize:       .word SYSSIZE
-swap_dev:      .word SWAP_DEV
-ram_size:      .word RAMDISK
-vid_mode:      .word SVGA_MODE
-root_dev:      .word ROOT_DEV
-boot_flag:     .word 0xAA55
diff --git a/arch/i386/boot/cmdline.c b/arch/i386/boot/cmdline.c
new file mode 100644 (file)
index 0000000..34bb778
--- /dev/null
@@ -0,0 +1,97 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/cmdline.c
+ *
+ * Simple command-line parser for early boot.
+ */
+
+#include "boot.h"
+
+static inline int myisspace(u8 c)
+{
+       return c <= ' ';        /* Close enough approximation */
+}
+
+/*
+ * Find a non-boolean option, that is, "option=argument".  In accordance
+ * with standard Linux practice, if this option is repeated, this returns
+ * the last instance on the command line.
+ *
+ * Returns the length of the argument (regardless of if it was
+ * truncated to fit in the buffer), or -1 on not found.
+ */
+int cmdline_find_option(const char *option, char *buffer, int bufsize)
+{
+       u32 cmdline_ptr = boot_params.hdr.cmd_line_ptr;
+       addr_t cptr;
+       char c;
+       int len = -1;
+       const char *opptr = NULL;
+       char *bufptr = buffer;
+       enum {
+               st_wordstart,   /* Start of word/after whitespace */
+               st_wordcmp,     /* Comparing this word */
+               st_wordskip,    /* Miscompare, skip */
+               st_bufcpy       /* Copying this to buffer */
+       } state = st_wordstart;
+
+       if (!cmdline_ptr || cmdline_ptr >= 0x100000)
+               return -1;      /* No command line, or inaccessible */
+
+       cptr = cmdline_ptr & 0xf;
+       set_fs(cmdline_ptr >> 4);
+
+       while (cptr < 0x10000 && (c = rdfs8(cptr++))) {
+               switch (state) {
+               case st_wordstart:
+                       if (myisspace(c))
+                               break;
+
+                       /* else */
+                       state = st_wordcmp;
+                       opptr = option;
+                       /* fall through */
+
+               case st_wordcmp:
+                       if (c == '=' && !*opptr) {
+                               len = 0;
+                               bufptr = buffer;
+                               state = st_bufcpy;
+                       } else if (myisspace(c)) {
+                               state = st_wordstart;
+                       } else if (c != *opptr++) {
+                               state = st_wordskip;
+                       }
+                       break;
+
+               case st_wordskip:
+                       if (myisspace(c))
+                               state = st_wordstart;
+                       break;
+
+               case st_bufcpy:
+                       if (myisspace(c)) {
+                               state = st_wordstart;
+                       } else {
+                               if (len < bufsize-1)
+                                       *bufptr++ = c;
+                               len++;
+                       }
+                       break;
+               }
+       }
+
+       if (bufsize)
+               *bufptr = '\0';
+
+       return len;
+}
diff --git a/arch/i386/boot/code16gcc.h b/arch/i386/boot/code16gcc.h
new file mode 100644 (file)
index 0000000..3bd8480
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * code16gcc.h
+ *
+ * This file is -include'd when compiling 16-bit C code.
+ * Note: this asm() needs to be emitted before gcc omits any code.
+ * Depending on gcc version, this requires -fno-unit-at-a-time or
+ * -fno-toplevel-reorder.
+ *
+ * Hopefully gcc will eventually have a real -m16 option so we can
+ * drop this hack long term.
+ */
+
+#ifndef __ASSEMBLY__
+asm(".code16gcc");
+#endif
index a661217f33ec4eeba811cb9d987f626f5f7c3838..189fa1dbefcc27ece79bac59fc2d11b83d09e38f 100644 (file)
@@ -9,9 +9,14 @@ targets                := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o \
 EXTRA_AFLAGS   := -traditional
 
 LDFLAGS_vmlinux := -T
-CFLAGS_misc.o += -fPIC
 hostprogs-y    := relocs
 
+CFLAGS  := -m32 -D__KERNEL__ $(LINUX_INCLUDE) -O2 \
+          -fno-strict-aliasing -fPIC \
+          $(call cc-option,-ffreestanding) \
+          $(call cc-option,-fno-stack-protector)
+LDFLAGS := -m elf_i386
+
 $(obj)/vmlinux: $(src)/vmlinux.lds $(obj)/head.o $(obj)/misc.o $(obj)/piggy.o FORCE
        $(call if_changed,ld)
        @:
index 3517a32aaf4152a67098f70dc43e1f43f16d5851..f35ea2237522c0267139af7666e2875b571dd4b4 100644 (file)
@@ -45,10 +45,10 @@ startup_32:
  * at and where we were actually loaded at.  This can only be done
  * with a short local call on x86.  Nothing  else will tell us what
  * address we are running at.  The reserved chunk of the real-mode
- * data at 0x34-0x3f are used as the stack for this calculation.
- * Only 4 bytes are needed.
+ * data at 0x1e4 (defined as a scratch field) are used as the stack
+ * for this calculation. Only 4 bytes are needed.
  */
-       leal 0x40(%esi), %esp
+       leal (0x1e4+4)(%esi), %esp
        call 1f
 1:     popl %ebp
        subl $1b, %ebp
diff --git a/arch/i386/boot/copy.S b/arch/i386/boot/copy.S
new file mode 100644 (file)
index 0000000..ef127e5
--- /dev/null
@@ -0,0 +1,101 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/copy.S
+ *
+ * Memory copy routines
+ */
+
+       .code16gcc
+       .text
+
+       .globl  memcpy
+       .type   memcpy, @function
+memcpy:
+       pushw   %si
+       pushw   %di
+       movw    %ax, %di
+       movw    %dx, %si
+       pushw   %cx
+       shrw    $2, %cx
+       rep; movsl
+       popw    %cx
+       andw    $3, %cx
+       rep; movsb
+       popw    %di
+       popw    %si
+       ret
+       .size   memcpy, .-memcpy
+
+       .globl  memset
+       .type   memset, @function
+memset:
+       pushw   %di
+       movw    %ax, %di
+       movzbl  %dl, %eax
+       imull   $0x01010101,%eax
+       pushw   %cx
+       shrw    $2, %cx
+       rep; stosl
+       popw    %cx
+       andw    $3, %cx
+       rep; stosb
+       popw    %di
+       ret
+       .size   memset, .-memset
+
+       .globl  copy_from_fs
+       .type   copy_from_fs, @function
+copy_from_fs:
+       pushw   %ds
+       pushw   %fs
+       popw    %ds
+       call    memcpy
+       popw    %ds
+       ret
+       .size   copy_from_fs, .-copy_from_fs
+
+       .globl  copy_to_fs
+       .type   copy_to_fs, @function
+copy_to_fs:
+       pushw   %es
+       pushw   %fs
+       popw    %es
+       call    memcpy
+       popw    %es
+       ret
+       .size   copy_to_fs, .-copy_to_fs
+
+#if 0 /* Not currently used, but can be enabled as needed */
+
+       .globl  copy_from_gs
+       .type   copy_from_gs, @function
+copy_from_gs:
+       pushw   %ds
+       pushw   %gs
+       popw    %ds
+       call    memcpy
+       popw    %ds
+       ret
+       .size   copy_from_gs, .-copy_from_gs
+       .globl  copy_to_gs
+
+       .type   copy_to_gs, @function
+copy_to_gs:
+       pushw   %es
+       pushw   %gs
+       popw    %es
+       call    memcpy
+       popw    %es
+       ret
+       .size   copy_to_gs, .-copy_to_gs
+
+#endif
diff --git a/arch/i386/boot/cpu.c b/arch/i386/boot/cpu.c
new file mode 100644 (file)
index 0000000..2a5c32d
--- /dev/null
@@ -0,0 +1,69 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/cpu.c
+ *
+ * Check for obligatory CPU features and abort if the features are not
+ * present.
+ */
+
+#include "boot.h"
+#include "bitops.h"
+#include <asm/cpufeature.h>
+
+static char *cpu_name(int level)
+{
+       static char buf[6];
+
+       if (level == 64) {
+               return "x86-64";
+       } else {
+               sprintf(buf, "i%d86", level);
+               return buf;
+       }
+}
+
+int validate_cpu(void)
+{
+       u32 *err_flags;
+       int cpu_level, req_level;
+
+       check_cpu(&cpu_level, &req_level, &err_flags);
+
+       if (cpu_level < req_level) {
+               printf("This kernel requires an %s CPU, ",
+                      cpu_name(req_level));
+               printf("but only detected an %s CPU.\n",
+                      cpu_name(cpu_level));
+               return -1;
+       }
+
+       if (err_flags) {
+               int i, j;
+               puts("This kernel requires the following features "
+                    "not present on the CPU:\n");
+
+               for (i = 0; i < NCAPINTS; i++) {
+                       u32 e = err_flags[i];
+
+                       for (j = 0; j < 32; j++) {
+                               if (e & 1)
+                                       printf("%d:%d ", i, j);
+
+                               e >>= 1;
+                       }
+               }
+               putchar('\n');
+               return -1;
+       } else {
+               return 0;
+       }
+}
diff --git a/arch/i386/boot/cpucheck.c b/arch/i386/boot/cpucheck.c
new file mode 100644 (file)
index 0000000..8b0f447
--- /dev/null
@@ -0,0 +1,267 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/cpucheck.c
+ *
+ * Check for obligatory CPU features and abort if the features are not
+ * present.  This code should be compilable as 16-, 32- or 64-bit
+ * code, so be very careful with types and inline assembly.
+ *
+ * This code should not contain any messages; that requires an
+ * additional wrapper.
+ *
+ * As written, this code is not safe for inclusion into the kernel
+ * proper (after FPU initialization, in particular).
+ */
+
+#ifdef _SETUP
+# include "boot.h"
+# include "bitops.h"
+#endif
+#include <linux/types.h>
+#include <asm/cpufeature.h>
+#include <asm/processor-flags.h>
+#include <asm/required-features.h>
+#include <asm/msr-index.h>
+
+struct cpu_features {
+       int level;              /* Family, or 64 for x86-64 */
+       int model;
+       u32 flags[NCAPINTS];
+};
+
+static struct cpu_features cpu;
+static u32 cpu_vendor[3];
+static u32 err_flags[NCAPINTS];
+
+#ifdef CONFIG_X86_64
+static const int req_level = 64;
+#elif defined(CONFIG_X86_MINIMUM_CPU_FAMILY)
+static const int req_level = CONFIG_X86_MINIMUM_CPU_FAMILY;
+#else
+static const int req_level = 3;
+#endif
+
+static const u32 req_flags[NCAPINTS] =
+{
+       REQUIRED_MASK0,
+       REQUIRED_MASK1,
+       REQUIRED_MASK2,
+       REQUIRED_MASK3,
+       REQUIRED_MASK4,
+       REQUIRED_MASK5,
+       REQUIRED_MASK6,
+       REQUIRED_MASK7,
+};
+
+#define A32(a,b,c,d) (((d) << 24)+((c) << 16)+((b) << 8)+(a))
+
+static int is_amd(void)
+{
+       return cpu_vendor[0] == A32('A','u','t','h') &&
+              cpu_vendor[1] == A32('e','n','t','i') &&
+              cpu_vendor[2] == A32('c','A','M','D');
+}
+
+static int is_centaur(void)
+{
+       return cpu_vendor[0] == A32('C','e','n','t') &&
+              cpu_vendor[1] == A32('a','u','r','H') &&
+              cpu_vendor[2] == A32('a','u','l','s');
+}
+
+static int is_transmeta(void)
+{
+       return cpu_vendor[0] == A32('G','e','n','u') &&
+              cpu_vendor[1] == A32('i','n','e','T') &&
+              cpu_vendor[2] == A32('M','x','8','6');
+}
+
+static int has_fpu(void)
+{
+       u16 fcw = -1, fsw = -1;
+       u32 cr0;
+
+       asm("movl %%cr0,%0" : "=r" (cr0));
+       if (cr0 & (X86_CR0_EM|X86_CR0_TS)) {
+               cr0 &= ~(X86_CR0_EM|X86_CR0_TS);
+               asm volatile("movl %0,%%cr0" : : "r" (cr0));
+       }
+
+       asm("fninit ; fnstsw %0 ; fnstcw %1" : "+m" (fsw), "+m" (fcw));
+
+       return fsw == 0 && (fcw & 0x103f) == 0x003f;
+}
+
+static int has_eflag(u32 mask)
+{
+       u32 f0, f1;
+
+       asm("pushfl ; "
+           "pushfl ; "
+           "popl %0 ; "
+           "movl %0,%1 ; "
+           "xorl %2,%1 ; "
+           "pushl %1 ; "
+           "popfl ; "
+           "pushfl ; "
+           "popl %1 ; "
+           "popfl"
+           : "=r" (f0), "=r" (f1)
+           : "g" (mask));
+
+       return !!((f0^f1) & mask);
+}
+
+static void get_flags(void)
+{
+       u32 max_intel_level, max_amd_level;
+       u32 tfms;
+
+       if (has_fpu())
+               set_bit(X86_FEATURE_FPU, cpu.flags);
+
+       if (has_eflag(X86_EFLAGS_ID)) {
+               asm("cpuid"
+                   : "=a" (max_intel_level),
+                     "=b" (cpu_vendor[0]),
+                     "=d" (cpu_vendor[1]),
+                     "=c" (cpu_vendor[2])
+                   : "a" (0));
+
+               if (max_intel_level >= 0x00000001 &&
+                   max_intel_level <= 0x0000ffff) {
+                       asm("cpuid"
+                           : "=a" (tfms),
+                             "=c" (cpu.flags[4]),
+                             "=d" (cpu.flags[0])
+                           : "a" (0x00000001)
+                           : "ebx");
+                       cpu.level = (tfms >> 8) & 15;
+                       cpu.model = (tfms >> 4) & 15;
+                       if (cpu.level >= 6)
+                               cpu.model += ((tfms >> 16) & 0xf) << 4;
+               }
+
+               asm("cpuid"
+                   : "=a" (max_amd_level)
+                   : "a" (0x80000000)
+                   : "ebx", "ecx", "edx");
+
+               if (max_amd_level >= 0x80000001 &&
+                   max_amd_level <= 0x8000ffff) {
+                       u32 eax = 0x80000001;
+                       asm("cpuid"
+                           : "+a" (eax),
+                             "=c" (cpu.flags[6]),
+                             "=d" (cpu.flags[1])
+                           : : "ebx");
+               }
+       }
+}
+
+/* Returns a bitmask of which words we have error bits in */
+static int check_flags(void)
+{
+       u32 err;
+       int i;
+
+       err = 0;
+       for (i = 0; i < NCAPINTS; i++) {
+               err_flags[i] = req_flags[i] & ~cpu.flags[i];
+               if (err_flags[i])
+                       err |= 1 << i;
+       }
+
+       return err;
+}
+
+/*
+ * Returns -1 on error.
+ *
+ * *cpu_level is set to the current CPU level; *req_level to the required
+ * level.  x86-64 is considered level 64 for this purpose.
+ *
+ * *err_flags_ptr is set to the flags error array if there are flags missing.
+ */
+int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr)
+{
+       int err;
+
+       memset(&cpu.flags, 0, sizeof cpu.flags);
+       cpu.level = 3;
+
+       if (has_eflag(X86_EFLAGS_AC))
+               cpu.level = 4;
+
+       get_flags();
+       err = check_flags();
+
+       if (test_bit(X86_FEATURE_LM, cpu.flags))
+               cpu.level = 64;
+
+       if (err == 0x01 &&
+           !(err_flags[0] &
+             ~((1 << X86_FEATURE_XMM)|(1 << X86_FEATURE_XMM2))) &&
+           is_amd()) {
+               /* If this is an AMD and we're only missing SSE+SSE2, try to
+                  turn them on */
+
+               u32 ecx = MSR_K7_HWCR;
+               u32 eax, edx;
+
+               asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
+               eax &= ~(1 << 15);
+               asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
+
+               get_flags();    /* Make sure it really did something */
+               err = check_flags();
+       } else if (err == 0x01 &&
+                  !(err_flags[0] & ~(1 << X86_FEATURE_CX8)) &&
+                  is_centaur() && cpu.model >= 6) {
+               /* If this is a VIA C3, we might have to enable CX8
+                  explicitly */
+
+               u32 ecx = MSR_VIA_FCR;
+               u32 eax, edx;
+
+               asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
+               eax |= (1<<1)|(1<<7);
+               asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
+
+               set_bit(X86_FEATURE_CX8, cpu.flags);
+               err = check_flags();
+       } else if (err == 0x01 && is_transmeta()) {
+               /* Transmeta might have masked feature bits in word 0 */
+
+               u32 ecx = 0x80860004;
+               u32 eax, edx;
+               u32 level = 1;
+
+               asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
+               asm("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
+               asm("cpuid"
+                   : "+a" (level), "=d" (cpu.flags[0])
+                   : : "ecx", "ebx");
+               asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
+
+               err = check_flags();
+       }
+
+       if (err_flags_ptr)
+               *err_flags_ptr = err ? err_flags : NULL;
+       if (cpu_level_ptr)
+               *cpu_level_ptr = cpu.level;
+       if (req_level_ptr)
+               *req_level_ptr = req_level;
+
+       return (cpu.level < req_level || err) ? -1 : 0;
+}
diff --git a/arch/i386/boot/edd.S b/arch/i386/boot/edd.S
deleted file mode 100644 (file)
index 3432136..0000000
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * BIOS Enhanced Disk Drive support
- * Copyright (C) 2002, 2003, 2004 Dell, Inc.
- * by Matt Domsch <Matt_Domsch@dell.com> October 2002
- * conformant to T13 Committee www.t13.org
- *   projects 1572D, 1484D, 1386D, 1226DT
- * disk signature read by Matt Domsch <Matt_Domsch@dell.com>
- *     and Andrew Wilks <Andrew_Wilks@dell.com> September 2003, June 2004
- * legacy CHS retrieval by Patrick J. LoPresti <patl@users.sourceforge.net>
- *      March 2004
- * Command line option parsing, Matt Domsch, November 2004
- */
-
-#include <linux/edd.h>
-#include <asm/setup.h>
-
-#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
-
-# It is assumed that %ds == INITSEG here
-
-       movb    $0, (EDD_MBR_SIG_NR_BUF)
-       movb    $0, (EDDNR)
-
-# Check the command line for options:
-# edd=of  disables EDD completely  (edd=off)
-# edd=sk  skips the MBR test    (edd=skipmbr)
-# edd=on  re-enables EDD (edd=on)
-
-       pushl   %esi
-       movw    $edd_mbr_sig_start, %di # Default to edd=on
-
-       movl    %cs:(cmd_line_ptr), %esi
-       andl    %esi, %esi
-       jz      old_cl                  # Old boot protocol?
-
-# Convert to a real-mode pointer in fs:si
-       movl    %esi, %eax
-       shrl    $4, %eax
-       movw    %ax, %fs
-       andw    $0xf, %si
-       jmp     have_cl_pointer
-
-# Old-style boot protocol?
-old_cl:
-       push    %ds                     # aka INITSEG
-       pop     %fs
-
-       cmpw    $0xa33f, (0x20)
-       jne     done_cl                 # No command line at all?
-       movw    (0x22), %si             # Pointer relative to INITSEG
-
-# fs:si has the pointer to the command line now
-have_cl_pointer:
-
-# Loop through kernel command line one byte at a time.  Just in
-# case the loader is buggy and failed to null-terminate the command line
-# terminate if we get close enough to the end of the segment that we
-# cannot fit "edd=XX"...
-cl_atspace:
-       cmpw    $-5, %si                # Watch for segment wraparound
-       jae     done_cl
-       movl    %fs:(%si), %eax
-       andb    %al, %al                # End of line?
-       jz      done_cl
-       cmpl    $EDD_CL_EQUALS, %eax
-       jz      found_edd_equals
-       cmpb    $0x20, %al              # <= space consider whitespace
-       ja      cl_skipword
-       incw    %si
-       jmp     cl_atspace
-
-cl_skipword:
-       cmpw    $-5, %si                # Watch for segment wraparound
-       jae     done_cl
-       movb    %fs:(%si), %al          # End of string?
-       andb    %al, %al
-       jz      done_cl
-       cmpb    $0x20, %al
-       jbe     cl_atspace
-       incw    %si
-       jmp     cl_skipword
-
-found_edd_equals:
-# only looking at first two characters after equals
-# late overrides early on the command line, so keep going after finding something
-       movw    %fs:4(%si), %ax
-       cmpw    $EDD_CL_OFF, %ax        # edd=of
-       je      do_edd_off
-       cmpw    $EDD_CL_SKIP, %ax       # edd=sk
-       je      do_edd_skipmbr
-       cmpw    $EDD_CL_ON, %ax         # edd=on
-       je      do_edd_on
-       jmp     cl_skipword
-do_edd_skipmbr:
-       movw    $edd_start, %di
-       jmp     cl_skipword
-do_edd_off:
-       movw    $edd_done, %di
-       jmp     cl_skipword
-do_edd_on:
-       movw    $edd_mbr_sig_start, %di
-       jmp     cl_skipword
-
-done_cl:
-       popl    %esi
-       jmpw    *%di
-
-# Read the first sector of each BIOS disk device and store the 4-byte signature
-edd_mbr_sig_start:
-       movb    $0x80, %dl                      # from device 80
-       movw    $EDD_MBR_SIG_BUF, %bx           # store buffer ptr in bx
-edd_mbr_sig_read:
-       movl    $0xFFFFFFFF, %eax
-       movl    %eax, (%bx)                     # assume failure
-       pushw   %bx
-       movb    $READ_SECTORS, %ah
-       movb    $1, %al                         # read 1 sector
-       movb    $0, %dh                         # at head 0
-       movw    $1, %cx                         # cylinder 0, sector 0
-       pushw   %es
-       pushw   %ds
-       popw    %es
-       movw    $EDDBUF, %bx                    # disk's data goes into EDDBUF
-       pushw   %dx             # work around buggy BIOSes
-       stc                     # work around buggy BIOSes
-       int     $0x13
-       sti                     # work around buggy BIOSes
-       popw    %dx
-       popw    %es
-       popw    %bx
-       jc      edd_mbr_sig_done                # on failure, we're done.
-       cmpb    $0, %ah         # some BIOSes do not set CF
-       jne     edd_mbr_sig_done                # on failure, we're done.
-       movl    (EDDBUF+EDD_MBR_SIG_OFFSET), %eax # read sig out of the MBR
-       movl    %eax, (%bx)                     # store success
-       incb    (EDD_MBR_SIG_NR_BUF)            # note that we stored something
-       incb    %dl                             # increment to next device
-       addw    $4, %bx                         # increment sig buffer ptr
-       cmpb    $EDD_MBR_SIG_MAX, (EDD_MBR_SIG_NR_BUF)  # Out of space?
-       jb      edd_mbr_sig_read                # keep looping
-edd_mbr_sig_done:
-
-# Do the BIOS Enhanced Disk Drive calls
-# This consists of two calls:
-#    int 13h ah=41h "Check Extensions Present"
-#    int 13h ah=48h "Get Device Parameters"
-#    int 13h ah=08h "Legacy Get Device Parameters"
-#
-# A buffer of size EDDMAXNR*(EDDEXTSIZE+EDDPARMSIZE) is reserved for our use
-# in the boot_params at EDDBUF.  The first four bytes of which are
-# used to store the device number, interface support map and version
-# results from fn41.  The next four bytes are used to store the legacy
-# cylinders, heads, and sectors from fn08. The following 74 bytes are used to
-# store the results from fn48.  Starting from device 80h, fn41, then fn48
-# are called and their results stored in EDDBUF+n*(EDDEXTSIZE+EDDPARMIZE).
-# Then the pointer is incremented to store the data for the next call.
-# This repeats until either a device doesn't exist, or until EDDMAXNR
-# devices have been stored.
-# The one tricky part is that ds:si always points EDDEXTSIZE bytes into
-# the structure, and the fn41 and fn08 results are stored at offsets
-# from there.  This removes the need to increment the pointer for
-# every store, and leaves it ready for the fn48 call.
-# A second one-byte buffer, EDDNR, in the boot_params stores
-# the number of BIOS devices which exist, up to EDDMAXNR.
-# In setup.c, copy_edd() stores both boot_params buffers away
-# for later use, as they would get overwritten otherwise.
-# This code is sensitive to the size of the structs in edd.h
-edd_start:
-                                               # %ds points to the bootsector
-                                                       # result buffer for fn48
-       movw    $EDDBUF+EDDEXTSIZE, %si         # in ds:si, fn41 results
-                                               # kept just before that
-       movb    $0x80, %dl                      # BIOS device 0x80
-
-edd_check_ext:
-       movb    $CHECKEXTENSIONSPRESENT, %ah    # Function 41
-       movw    $EDDMAGIC1, %bx                 # magic
-       int     $0x13                           # make the call
-       jc      edd_done                        # no more BIOS devices
-
-       cmpw    $EDDMAGIC2, %bx                 # is magic right?
-       jne     edd_next                        # nope, next...
-
-       movb    %dl, %ds:-8(%si)                # store device number
-       movb    %ah, %ds:-7(%si)                # store version
-       movw    %cx, %ds:-6(%si)                # store extensions
-       incb    (EDDNR)                         # note that we stored something
-
-edd_get_device_params:
-       movw    $EDDPARMSIZE, %ds:(%si)         # put size
-       movw    $0x0, %ds:2(%si)                # work around buggy BIOSes
-       movb    $GETDEVICEPARAMETERS, %ah       # Function 48
-       int     $0x13                           # make the call
-                                               # Don't check for fail return
-                                               # it doesn't matter.
-edd_get_legacy_chs:
-       xorw    %ax, %ax
-       movw    %ax, %ds:-4(%si)
-       movw    %ax, %ds:-2(%si)
-        # Ralf Brown's Interrupt List says to set ES:DI to
-       # 0000h:0000h "to guard against BIOS bugs"
-       pushw   %es
-       movw    %ax, %es
-       movw    %ax, %di
-       pushw   %dx                             # legacy call clobbers %dl
-       movb    $LEGACYGETDEVICEPARAMETERS, %ah # Function 08
-       int     $0x13                           # make the call
-       jc      edd_legacy_done                 # failed
-       movb    %cl, %al                        # Low 6 bits are max
-       andb    $0x3F, %al                      #   sector number
-       movb    %al, %ds:-1(%si)                # Record max sect
-       movb    %dh, %ds:-2(%si)                # Record max head number
-       movb    %ch, %al                        # Low 8 bits of max cyl
-       shr     $6, %cl
-       movb    %cl, %ah                        # High 2 bits of max cyl
-       movw    %ax, %ds:-4(%si)
-
-edd_legacy_done:
-       popw    %dx
-       popw    %es
-       movw    %si, %ax                        # increment si
-       addw    $EDDPARMSIZE+EDDEXTSIZE, %ax
-       movw    %ax, %si
-
-edd_next:
-       incb    %dl                             # increment to next device
-       cmpb    $EDDMAXNR, (EDDNR)              # Out of space?
-       jb      edd_check_ext                   # keep looping
-
-edd_done:
-#endif
diff --git a/arch/i386/boot/edd.c b/arch/i386/boot/edd.c
new file mode 100644 (file)
index 0000000..25a2824
--- /dev/null
@@ -0,0 +1,196 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/edd.c
+ *
+ * Get EDD BIOS disk information
+ */
+
+#include "boot.h"
+#include <linux/edd.h>
+
+#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
+
+struct edd_dapa {
+       u8      pkt_size;
+       u8      rsvd;
+       u16     sector_cnt;
+       u16     buf_off, buf_seg;
+       u64     lba;
+       u64     buf_lin_addr;
+};
+
+/*
+ * Read the MBR (first sector) from a specific device.
+ */
+static int read_mbr(u8 devno, void *buf)
+{
+       struct edd_dapa dapa;
+       u16 ax, bx, cx, dx, si;
+
+       memset(&dapa, 0, sizeof dapa);
+       dapa.pkt_size = sizeof(dapa);
+       dapa.sector_cnt = 1;
+       dapa.buf_off = (size_t)buf;
+       dapa.buf_seg = ds();
+       /* dapa.lba = 0; */
+
+       ax = 0x4200;            /* Extended Read */
+       si = (size_t)&dapa;
+       dx = devno;
+       asm("pushfl; stc; int $0x13; setc %%al; popfl"
+           : "+a" (ax), "+S" (si), "+d" (dx)
+           : "m" (dapa)
+           : "ebx", "ecx", "edi", "memory");
+
+       if (!(u8)ax)
+               return 0;       /* OK */
+
+       ax = 0x0201;            /* Legacy Read, one sector */
+       cx = 0x0001;            /* Sector 0-0-1 */
+       dx = devno;
+       bx = (size_t)buf;
+       asm("pushfl; stc; int $0x13; setc %%al; popfl"
+           : "+a" (ax), "+c" (cx), "+d" (dx), "+b" (bx)
+           : : "esi", "edi", "memory");
+
+       return -(u8)ax;         /* 0 or -1 */
+}
+
+static u32 read_mbr_sig(u8 devno, struct edd_info *ei)
+{
+       int sector_size;
+       char *mbrbuf_ptr, *mbrbuf_end;
+       u32 mbrsig;
+       u32 buf_base, mbr_base;
+       extern char _end[];
+       static char mbr_buf[1024];
+
+       sector_size = ei->params.bytes_per_sector;
+       if (!sector_size)
+               sector_size = 512; /* Best available guess */
+
+       buf_base = (ds() << 4) + (u32)&_end;
+       mbr_base = (buf_base+sector_size-1) & ~(sector_size-1);
+       mbrbuf_ptr = mbr_buf + (mbr_base-buf_base);
+       mbrbuf_end = mbrbuf_ptr + sector_size;
+
+       if (!(boot_params.hdr.loadflags & CAN_USE_HEAP))
+               return 0;
+       if (mbrbuf_end > (char *)(size_t)boot_params.hdr.heap_end_ptr)
+               return 0;
+
+       if (read_mbr(devno, mbrbuf_ptr))
+               return 0;
+
+       mbrsig = *(u32 *)&mbrbuf_ptr[EDD_MBR_SIG_OFFSET];
+       return mbrsig;
+}
+
+static int get_edd_info(u8 devno, struct edd_info *ei)
+{
+       u16 ax, bx, cx, dx, di;
+
+       memset(ei, 0, sizeof *ei);
+
+       /* Check Extensions Present */
+
+       ax = 0x4100;
+       bx = EDDMAGIC1;
+       dx = devno;
+       asm("pushfl; stc; int $0x13; setc %%al; popfl"
+           : "+a" (ax), "+b" (bx), "=c" (cx), "+d" (dx)
+           : : "esi", "edi");
+
+       if ((u8)ax)
+               return -1;      /* No extended information */
+
+       if (bx != EDDMAGIC2)
+               return -1;
+
+       ei->device  = devno;
+       ei->version = ax >> 8;  /* EDD version number */
+       ei->interface_support = cx; /* EDD functionality subsets */
+
+       /* Extended Get Device Parameters */
+
+       ei->params.length = sizeof(ei->params);
+       ax = 0x4800;
+       dx = devno;
+       asm("pushfl; int $0x13; popfl"
+           : "+a" (ax), "+d" (dx)
+           : "S" (&ei->params)
+           : "ebx", "ecx", "edi");
+
+       /* Get legacy CHS parameters */
+
+       /* Ralf Brown recommends setting ES:DI to 0:0 */
+       ax = 0x0800;
+       dx = devno;
+       di = 0;
+       asm("pushw %%es; "
+           "movw %%di,%%es; "
+           "pushfl; stc; int $0x13; setc %%al; popfl; "
+           "popw %%es"
+           : "+a" (ax), "=b" (bx), "=c" (cx), "+d" (dx), "+D" (di)
+           : : "esi");
+
+       if ((u8)ax == 0) {
+               ei->legacy_max_cylinder = (cx >> 8) + ((cx & 0xc0) << 2);
+               ei->legacy_max_head = dx >> 8;
+               ei->legacy_sectors_per_track = cx & 0x3f;
+       }
+
+       return 0;
+}
+
+void query_edd(void)
+{
+       char eddarg[8];
+       int do_mbr = 1;
+       int do_edd = 1;
+       int devno;
+       struct edd_info ei, *edp;
+
+       if (cmdline_find_option("edd", eddarg, sizeof eddarg) > 0) {
+               if (!strcmp(eddarg, "skipmbr") || !strcmp(eddarg, "skip"))
+                       do_mbr = 0;
+               else if (!strcmp(eddarg, "off"))
+                       do_edd = 0;
+       }
+
+       edp = (struct edd_info *)boot_params.eddbuf;
+
+       if (!do_edd)
+               return;
+
+       for (devno = 0x80; devno < 0x80+EDD_MBR_SIG_MAX; devno++) {
+               /*
+                * Scan the BIOS-supported hard disks and query EDD
+                * information...
+                */
+               get_edd_info(devno, &ei);
+
+               if (boot_params.eddbuf_entries < EDDMAXNR) {
+                       memcpy(edp, &ei, sizeof ei);
+                       edp++;
+                       boot_params.eddbuf_entries++;
+               }
+
+               if (do_mbr) {
+                       u32 mbr_sig;
+                       mbr_sig = read_mbr_sig(devno, &ei);
+                       boot_params.edd_mbr_sig_buffer[devno-0x80] = mbr_sig;
+               }
+       }
+}
+
+#endif
diff --git a/arch/i386/boot/header.S b/arch/i386/boot/header.S
new file mode 100644 (file)
index 0000000..6b9923f
--- /dev/null
@@ -0,0 +1,283 @@
+/*
+ *     header.S
+ *
+ *     Copyright (C) 1991, 1992 Linus Torvalds
+ *
+ *     Based on bootsect.S and setup.S
+ *     modified by more people than can be counted
+ *
+ *     Rewritten as a common file by H. Peter Anvin (Apr 2007)
+ *
+ * BIG FAT NOTE: We're in real mode using 64k segments.  Therefore segment
+ * addresses must be multiplied by 16 to obtain their respective linear
+ * addresses. To avoid confusion, linear addresses are written using leading
+ * hex while segment addresses are written as segment:offset.
+ *
+ */
+
+#include <asm/segment.h>
+#include <linux/utsrelease.h>
+#include <asm/boot.h>
+#include <asm/e820.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+#include "boot.h"
+
+SETUPSECTS     = 4                     /* default nr of setup-sectors */
+BOOTSEG                = 0x07C0                /* original address of boot-sector */
+SYSSEG         = DEF_SYSSEG            /* system loaded at 0x10000 (65536) */
+SYSSIZE                = DEF_SYSSIZE           /* system size: # of 16-byte clicks */
+                                       /* to be loaded */
+ROOT_DEV       = 0                     /* ROOT_DEV is now written by "build" */
+SWAP_DEV       = 0                     /* SWAP_DEV is now written by "build" */
+
+#ifndef SVGA_MODE
+#define SVGA_MODE ASK_VGA
+#endif
+
+#ifndef RAMDISK
+#define RAMDISK 0
+#endif
+
+#ifndef ROOT_RDONLY
+#define ROOT_RDONLY 1
+#endif
+
+       .code16
+       .section ".bstext", "ax"
+
+       .global bootsect_start
+bootsect_start:
+
+       # Normalize the start address
+       ljmp    $BOOTSEG, $start2
+
+start2:
+       movw    %cs, %ax
+       movw    %ax, %ds
+       movw    %ax, %es
+       movw    %ax, %ss
+       xorw    %sp, %sp
+       sti
+       cld
+
+       movw    $bugger_off_msg, %si
+
+msg_loop:
+       lodsb
+       andb    %al, %al
+       jz      bs_die
+       movb    $0xe, %ah
+       movw    $7, %bx
+       int     $0x10
+       jmp     msg_loop
+
+bs_die:
+       # Allow the user to press a key, then reboot
+       xorw    %ax, %ax
+       int     $0x16
+       int     $0x19
+
+       # int 0x19 should never return.  In case it does anyway,
+       # invoke the BIOS reset code...
+       ljmp    $0xf000,$0xfff0
+
+       .section ".bsdata", "a"
+bugger_off_msg:
+       .ascii  "Direct booting from floppy is no longer supported.\r\n"
+       .ascii  "Please use a boot loader program instead.\r\n"
+       .ascii  "\n"
+       .ascii  "Remove disk and press any key to reboot . . .\r\n"
+       .byte   0
+
+
+       # Kernel attributes; used by setup.  This is part 1 of the
+       # header, from the old boot sector.
+
+       .section ".header", "a"
+       .globl  hdr
+hdr:
+setup_sects:   .byte SETUPSECTS
+root_flags:    .word ROOT_RDONLY
+syssize:       .long SYSSIZE
+ram_size:      .word RAMDISK
+vid_mode:      .word SVGA_MODE
+root_dev:      .word ROOT_DEV
+boot_flag:     .word 0xAA55
+
+       # offset 512, entry point
+
+       .globl  _start
+_start:
+               # Explicitly enter this as bytes, or the assembler
+               # tries to generate a 3-byte jump here, which causes
+               # everything else to push off to the wrong offset.
+               .byte   0xeb            # short (2-byte) jump
+               .byte   start_of_setup-1f
+1:
+
+       # Part 2 of the header, from the old setup.S
+
+               .ascii  "HdrS"          # header signature
+               .word   0x0206          # header version number (>= 0x0105)
+                                       # or else old loadlin-1.5 will fail)
+               .globl realmode_swtch
+realmode_swtch:        .word   0, 0            # default_switch, SETUPSEG
+start_sys_seg: .word   SYSSEG
+               .word   kernel_version-512 # pointing to kernel version string
+                                       # above section of header is compatible
+                                       # with loadlin-1.5 (header v1.5). Don't
+                                       # change it.
+
+type_of_loader:        .byte   0               # = 0, old one (LILO, Loadlin,
+                                       #      Bootlin, SYSLX, bootsect...)
+                                       # See Documentation/i386/boot.txt for
+                                       # assigned ids
+
+# flags, unused bits must be zero (RFU) bit within loadflags
+loadflags:
+LOADED_HIGH    = 1                     # If set, the kernel is loaded high
+CAN_USE_HEAP   = 0x80                  # If set, the loader also has set
+                                       # heap_end_ptr to tell how much
+                                       # space behind setup.S can be used for
+                                       # heap purposes.
+                                       # Only the loader knows what is free
+#ifndef __BIG_KERNEL__
+               .byte   0
+#else
+               .byte   LOADED_HIGH
+#endif
+
+setup_move_size: .word  0x8000         # size to move, when setup is not
+                                       # loaded at 0x90000. We will move setup
+                                       # to 0x90000 then just before jumping
+                                       # into the kernel. However, only the
+                                       # loader knows how much data behind
+                                       # us also needs to be loaded.
+
+code32_start:                          # here loaders can put a different
+                                       # start address for 32-bit code.
+#ifndef __BIG_KERNEL__
+               .long   0x1000          #   0x1000 = default for zImage
+#else
+               .long   0x100000        # 0x100000 = default for big kernel
+#endif
+
+ramdisk_image: .long   0               # address of loaded ramdisk image
+                                       # Here the loader puts the 32-bit
+                                       # address where it loaded the image.
+                                       # This only will be read by the kernel.
+
+ramdisk_size:  .long   0               # its size in bytes
+
+bootsect_kludge:
+               .long   0               # obsolete
+
+heap_end_ptr:  .word   _end+1024       # (Header version 0x0201 or later)
+                                       # space from here (exclusive) down to
+                                       # end of setup code can be used by setup
+                                       # for local heap purposes.
+
+pad1:          .word   0
+cmd_line_ptr:  .long   0               # (Header version 0x0202 or later)
+                                       # If nonzero, a 32-bit pointer
+                                       # to the kernel command line.
+                                       # The command line should be
+                                       # located between the start of
+                                       # setup and the end of low
+                                       # memory (0xa0000), or it may
+                                       # get overwritten before it
+                                       # gets read.  If this field is
+                                       # used, there is no longer
+                                       # anything magical about the
+                                       # 0x90000 segment; the setup
+                                       # can be located anywhere in
+                                       # low memory 0x10000 or higher.
+
+ramdisk_max:   .long (-__PAGE_OFFSET-(512 << 20)-1) & 0x7fffffff
+                                       # (Header version 0x0203 or later)
+                                       # The highest safe address for
+                                       # the contents of an initrd
+
+kernel_alignment:  .long CONFIG_PHYSICAL_ALIGN #physical addr alignment
+                                               #required for protected mode
+                                               #kernel
+#ifdef CONFIG_RELOCATABLE
+relocatable_kernel:    .byte 1
+#else
+relocatable_kernel:    .byte 0
+#endif
+pad2:                  .byte 0
+pad3:                  .word 0
+
+cmdline_size:   .long   COMMAND_LINE_SIZE-1     #length of the command line,
+                                                #added with boot protocol
+                                                #version 2.06
+
+# End of setup header #####################################################
+
+       .section ".inittext", "ax"
+start_of_setup:
+#ifdef SAFE_RESET_DISK_CONTROLLER
+# Reset the disk controller.
+       movw    $0x0000, %ax            # Reset disk controller
+       movb    $0x80, %dl              # All disks
+       int     $0x13
+#endif
+
+# We will have entired with %cs = %ds+0x20, normalize %cs so
+# it is on par with the other segments.
+       pushw   %ds
+       pushw   $setup2
+       lretw
+
+setup2:
+# Force %es = %ds
+       movw    %ds, %ax
+       movw    %ax, %es
+       cld
+
+# Stack paranoia: align the stack and make sure it is good
+# for both 16- and 32-bit references.  In particular, if we
+# were meant to have been using the full 16-bit segment, the
+# caller might have set %sp to zero, which breaks %esp-based
+# references.
+       andw    $~3, %sp        # dword align (might as well...)
+       jnz     1f
+       movw    $0xfffc, %sp    # Make sure we're not zero
+1:     movzwl  %sp, %esp       # Clear upper half of %esp
+       sti
+
+# Check signature at end of setup
+       cmpl    $0x5a5aaa55, setup_sig
+       jne     setup_bad
+
+# Zero the bss
+       movw    $__bss_start, %di
+       movw    $_end+3, %cx
+       xorl    %eax, %eax
+       subw    %di, %cx
+       shrw    $2, %cx
+       rep; stosl
+
+# Jump to C code (should not return)
+       calll   main
+
+# Setup corrupt somehow...
+setup_bad:
+       movl    $setup_corrupt, %eax
+       calll   puts
+       # Fall through...
+
+       .globl  die
+       .type   die, @function
+die:
+       hlt
+       jmp     die
+
+       .size   die, .-due
+
+       .section ".initdata", "a"
+setup_corrupt:
+       .byte   7
+       .string "No setup signature found..."
diff --git a/arch/i386/boot/main.c b/arch/i386/boot/main.c
new file mode 100644 (file)
index 0000000..7f01f96
--- /dev/null
@@ -0,0 +1,161 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/main.c
+ *
+ * Main module for the real-mode kernel code
+ */
+
+#include "boot.h"
+
+struct boot_params boot_params __attribute__((aligned(16)));
+
+char *HEAP = _end;
+char *heap_end = _end;         /* Default end of heap = no heap */
+
+/*
+ * Copy the header into the boot parameter block.  Since this
+ * screws up the old-style command line protocol, adjust by
+ * filling in the new-style command line pointer instead.
+ */
+#define OLD_CL_MAGIC   0xA33F
+#define OLD_CL_ADDRESS 0x20
+
+static void copy_boot_params(void)
+{
+       struct old_cmdline {
+               u16 cl_magic;
+               u16 cl_offset;
+       };
+       const struct old_cmdline * const oldcmd =
+               (const struct old_cmdline *)OLD_CL_ADDRESS;
+
+       BUILD_BUG_ON(sizeof boot_params != 4096);
+       memcpy(&boot_params.hdr, &hdr, sizeof hdr);
+
+       if (!boot_params.hdr.cmd_line_ptr &&
+           oldcmd->cl_magic == OLD_CL_MAGIC) {
+               /* Old-style command line protocol. */
+               u16 cmdline_seg;
+
+               /* Figure out if the command line falls in the region
+                  of memory that an old kernel would have copied up
+                  to 0x90000... */
+               if (oldcmd->cl_offset < boot_params.hdr.setup_move_size)
+                       cmdline_seg = ds();
+               else
+                       cmdline_seg = 0x9000;
+
+               boot_params.hdr.cmd_line_ptr =
+                       (cmdline_seg << 4) + oldcmd->cl_offset;
+       }
+}
+
+/*
+ * Set the keyboard repeat rate to maximum.  Unclear why this
+ * is done here; this might be possible to kill off as stale code.
+ */
+static void keyboard_set_repeat(void)
+{
+       u16 ax = 0x0305;
+       u16 bx = 0;
+       asm volatile("int $0x16"
+                    : "+a" (ax), "+b" (bx)
+                    : : "ecx", "edx", "esi", "edi");
+}
+
+/*
+ * Get Intel SpeedStep IST information.
+ */
+static void query_speedstep_ist(void)
+{
+       asm("int $0x15"
+           : "=a" (boot_params.speedstep_info[0]),
+             "=b" (boot_params.speedstep_info[1]),
+             "=c" (boot_params.speedstep_info[2]),
+             "=d" (boot_params.speedstep_info[3])
+           : "a" (0x0000e980),  /* IST Support */
+             "d" (0x47534943)); /* Request value */
+}
+
+/*
+ * Tell the BIOS what CPU mode we intend to run in.
+ */
+static void set_bios_mode(void)
+{
+#ifdef CONFIG_X86_64
+       u32 eax, ebx;
+
+       eax = 0xec00;
+       ebx = 2;
+       asm volatile("int $0x15"
+                    : "+a" (eax), "+b" (ebx)
+                    : : "ecx", "edx", "esi", "edi");
+#endif
+}
+
+void main(void)
+{
+       /* First, copy the boot header into the "zeropage" */
+       copy_boot_params();
+
+       /* End of heap check */
+       if (boot_params.hdr.loadflags & CAN_USE_HEAP) {
+               heap_end = (char *)(boot_params.hdr.heap_end_ptr
+                                   +0x200-STACK_SIZE);
+       } else {
+               /* Boot protocol 2.00 only, no heap available */
+               puts("WARNING: Ancient bootloader, some functionality "
+                    "may be limited!\n");
+       }
+
+       /* Make sure we have all the proper CPU support */
+       if (validate_cpu()) {
+               puts("Unable to boot - please use a kernel appropriate "
+                    "for your CPU.\n");
+               die();
+       }
+
+       /* Tell the BIOS what CPU mode we intend to run in. */
+       set_bios_mode();
+
+       /* Detect memory layout */
+       detect_memory();
+
+       /* Set keyboard repeat rate (why?) */
+       keyboard_set_repeat();
+
+       /* Set the video mode */
+       set_video();
+
+       /* Query MCA information */
+       query_mca();
+
+       /* Voyager */
+#ifdef CONFIG_X86_VOYAGER
+       query_voyager();
+#endif
+
+       /* Query SpeedStep IST information */
+       query_speedstep_ist();
+
+       /* Query APM information */
+#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
+       query_apm_bios();
+#endif
+
+       /* Query EDD information */
+#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
+       query_edd();
+#endif
+       /* Do the last things and invoke protected mode */
+       go_to_protected_mode();
+}
diff --git a/arch/i386/boot/mca.c b/arch/i386/boot/mca.c
new file mode 100644 (file)
index 0000000..9b68bd1
--- /dev/null
@@ -0,0 +1,43 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/mca.c
+ *
+ * Get the MCA system description table
+ */
+
+#include "boot.h"
+
+int query_mca(void)
+{
+       u8 err;
+       u16 es, bx, len;
+
+       asm("pushw %%es ; "
+           "int $0x15 ; "
+           "setc %0 ; "
+           "movw %%es, %1 ; "
+           "popw %%es"
+           : "=acdSDm" (err), "=acdSDm" (es), "=b" (bx)
+           : "a" (0xc000));
+
+       if (err)
+               return -1;      /* No MCA present */
+
+       set_fs(es);
+       len = rdfs16(bx);
+
+       if (len > sizeof(boot_params.sys_desc_table))
+               len = sizeof(boot_params.sys_desc_table);
+
+       copy_from_fs(&boot_params.sys_desc_table, bx, len);
+       return 0;
+}
diff --git a/arch/i386/boot/memory.c b/arch/i386/boot/memory.c
new file mode 100644 (file)
index 0000000..1a2e62d
--- /dev/null
@@ -0,0 +1,99 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/memory.c
+ *
+ * Memory detection code
+ */
+
+#include "boot.h"
+
+#define SMAP   0x534d4150      /* ASCII "SMAP" */
+
+static int detect_memory_e820(void)
+{
+       u32 next = 0;
+       u32 size, id;
+       u8 err;
+       struct e820entry *desc = boot_params.e820_map;
+
+       do {
+               size = sizeof(struct e820entry);
+               id = SMAP;
+               asm("int $0x15; setc %0"
+                   : "=am" (err), "+b" (next), "+d" (id), "+c" (size),
+                     "=m" (*desc)
+                   : "D" (desc), "a" (0xe820));
+
+               if (err || id != SMAP)
+                       break;
+
+               boot_params.e820_entries++;
+               desc++;
+       } while (next && boot_params.e820_entries < E820MAX);
+
+       return boot_params.e820_entries;
+}
+
+static int detect_memory_e801(void)
+{
+       u16 ax, bx, cx, dx;
+       u8 err;
+
+       bx = cx = dx = 0;
+       ax = 0xe801;
+       asm("stc; int $0x15; setc %0"
+           : "=m" (err), "+a" (ax), "+b" (bx), "+c" (cx), "+d" (dx));
+
+       if (err)
+               return -1;
+
+       /* Do we really need to do this? */
+       if (cx || dx) {
+               ax = cx;
+               bx = dx;
+       }
+
+       if (ax > 15*1024)
+               return -1;      /* Bogus! */
+
+       /* This ignores memory above 16MB if we have a memory hole
+          there.  If someone actually finds a machine with a memory
+          hole at 16MB and no support for 0E820h they should probably
+          generate a fake e820 map. */
+       boot_params.alt_mem_k = (ax == 15*1024) ? (dx << 6)+ax : ax;
+
+       return 0;
+}
+
+static int detect_memory_88(void)
+{
+       u16 ax;
+       u8 err;
+
+       ax = 0x8800;
+       asm("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
+
+       boot_params.screen_info.ext_mem_k = ax;
+
+       return -err;
+}
+
+int detect_memory(void)
+{
+       if (detect_memory_e820() > 0)
+               return 0;
+
+       if (!detect_memory_e801())
+               return 0;
+
+       return detect_memory_88();
+}
diff --git a/arch/i386/boot/pm.c b/arch/i386/boot/pm.c
new file mode 100644 (file)
index 0000000..3fa53e1
--- /dev/null
@@ -0,0 +1,170 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/pm.c
+ *
+ * Prepare the machine for transition to protected mode.
+ */
+
+#include "boot.h"
+#include <asm/segment.h>
+
+/*
+ * Invoke the realmode switch hook if present; otherwise
+ * disable all interrupts.
+ */
+static void realmode_switch_hook(void)
+{
+       if (boot_params.hdr.realmode_swtch) {
+               asm volatile("lcallw *%0"
+                            : : "m" (boot_params.hdr.realmode_swtch)
+                            : "eax", "ebx", "ecx", "edx");
+       } else {
+               asm volatile("cli");
+               outb(0x80, 0x70); /* Disable NMI */
+               io_delay();
+       }
+}
+
+/*
+ * A zImage kernel is loaded at 0x10000 but wants to run at 0x1000.
+ * A bzImage kernel is loaded and runs at 0x100000.
+ */
+static void move_kernel_around(void)
+{
+       /* Note: rely on the compile-time option here rather than
+          the LOADED_HIGH flag.  The Qemu kernel loader unconditionally
+          sets the loadflags to zero. */
+#ifndef __BIG_KERNEL__
+       u16 dst_seg, src_seg;
+       u32 syssize;
+
+       dst_seg =  0x1000 >> 4;
+       src_seg = 0x10000 >> 4;
+       syssize = boot_params.hdr.syssize; /* Size in 16-byte paragraphs */
+
+       while (syssize) {
+               int paras  = (syssize >= 0x1000) ? 0x1000 : syssize;
+               int dwords = paras << 2;
+
+               asm volatile("pushw %%es ; "
+                            "pushw %%ds ; "
+                            "movw %1,%%es ; "
+                            "movw %2,%%ds ; "
+                            "xorw %%di,%%di ; "
+                            "xorw %%si,%%si ; "
+                            "rep;movsl ; "
+                            "popw %%ds ; "
+                            "popw %%es"
+                            : "+c" (dwords)
+                            : "rm" (dst_seg), "rm" (src_seg)
+                            : "esi", "edi");
+
+               syssize -= paras;
+               dst_seg += paras;
+               src_seg += paras;
+       }
+#endif
+}
+
+/*
+ * Disable all interrupts at the legacy PIC.
+ */
+static void mask_all_interrupts(void)
+{
+       outb(0xff, 0xa1);       /* Mask all interrupts on the seconday PIC */
+       io_delay();
+       outb(0xfb, 0x21);       /* Mask all but cascade on the primary PIC */
+       io_delay();
+}
+
+/*
+ * Reset IGNNE# if asserted in the FPU.
+ */
+static void reset_coprocessor(void)
+{
+       outb(0, 0xf0);
+       io_delay();
+       outb(0, 0xf1);
+       io_delay();
+}
+
+/*
+ * Set up the GDT
+ */
+#define GDT_ENTRY(flags,base,limit)            \
+       (((u64)(base & 0xff000000) << 32) |     \
+        ((u64)flags << 40) |                   \
+        ((u64)(limit & 0x00ff0000) << 32) |    \
+        ((u64)(base & 0x00ffff00) << 16) |     \
+        ((u64)(limit & 0x0000ffff)))
+
+struct gdt_ptr {
+       u16 len;
+       u32 ptr;
+} __attribute__((packed));
+
+static void setup_gdt(void)
+{
+       /* There are machines which are known to not boot with the GDT
+          being 8-byte unaligned.  Intel recommends 16 byte alignment. */
+       static const u64 boot_gdt[] __attribute__((aligned(16))) = {
+               /* CS: code, read/execute, 4 GB, base 0 */
+               [GDT_ENTRY_BOOT_CS] = GDT_ENTRY(0xc09b, 0, 0xfffff),
+               /* DS: data, read/write, 4 GB, base 0 */
+               [GDT_ENTRY_BOOT_DS] = GDT_ENTRY(0xc093, 0, 0xfffff),
+       };
+       struct gdt_ptr gdt;
+
+       gdt.len = sizeof(boot_gdt)-1;
+       gdt.ptr = (u32)&boot_gdt + (ds() << 4);
+
+       asm volatile("lgdtl %0" : : "m" (gdt));
+}
+
+/*
+ * Set up the IDT
+ */
+static void setup_idt(void)
+{
+       static const struct gdt_ptr null_idt = {0, 0};
+       asm volatile("lidtl %0" : : "m" (null_idt));
+}
+
+/*
+ * Actual invocation sequence
+ */
+void go_to_protected_mode(void)
+{
+       /* Hook before leaving real mode, also disables interrupts */
+       realmode_switch_hook();
+
+       /* Move the kernel/setup to their final resting places */
+       move_kernel_around();
+
+       /* Enable the A20 gate */
+       if (enable_a20()) {
+               puts("A20 gate not responding, unable to boot...\n");
+               die();
+       }
+
+       /* Reset coprocessor (IGNNE#) */
+       reset_coprocessor();
+
+       /* Mask all interrupts in the PIC */
+       mask_all_interrupts();
+
+       /* Actual transition to protected mode... */
+       setup_idt();
+       setup_gdt();
+       protected_mode_jump(boot_params.hdr.code32_start,
+                           (u32)&boot_params + (ds() << 4));
+}
diff --git a/arch/i386/boot/pmjump.S b/arch/i386/boot/pmjump.S
new file mode 100644 (file)
index 0000000..2e55923
--- /dev/null
@@ -0,0 +1,54 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/pmjump.S
+ *
+ * The actual transition into protected mode
+ */
+
+#include <asm/boot.h>
+#include <asm/segment.h>
+
+       .text
+
+       .globl  protected_mode_jump
+       .type   protected_mode_jump, @function
+
+       .code16
+
+/*
+ * void protected_mode_jump(u32 entrypoint, u32 bootparams);
+ */
+protected_mode_jump:
+       xorl    %ebx, %ebx              # Flag to indicate this is a boot
+       movl    %edx, %esi              # Pointer to boot_params table
+       movl    %eax, 2f                # Patch ljmpl instruction
+       jmp     1f                      # Short jump to flush instruction q.
+
+1:
+       movw    $__BOOT_DS, %cx
+
+       movl    %cr0, %edx
+       orb     $1, %dl                 # Protected mode (PE) bit
+       movl    %edx, %cr0
+
+       movw    %cx, %ds
+       movw    %cx, %es
+       movw    %cx, %fs
+       movw    %cx, %gs
+       movw    %cx, %ss
+
+       # Jump to the 32-bit entrypoint
+       .byte   0x66, 0xea              # ljmpl opcode
+2:     .long   0                       # offset
+       .word   __BOOT_CS               # segment
+
+       .size   protected_mode_jump, .-protected_mode_jump
diff --git a/arch/i386/boot/printf.c b/arch/i386/boot/printf.c
new file mode 100644 (file)
index 0000000..1a09f93
--- /dev/null
@@ -0,0 +1,307 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/printf.c
+ *
+ * Oh, it's a waste of space, but oh-so-yummy for debugging.  This
+ * version of printf() does not include 64-bit support.  "Live with
+ * it."
+ *
+ */
+
+#include "boot.h"
+
+static int skip_atoi(const char **s)
+{
+       int i = 0;
+
+       while (isdigit(**s))
+               i = i * 10 + *((*s)++) - '0';
+       return i;
+}
+
+#define ZEROPAD        1               /* pad with zero */
+#define SIGN   2               /* unsigned/signed long */
+#define PLUS   4               /* show plus */
+#define SPACE  8               /* space if plus */
+#define LEFT   16              /* left justified */
+#define SPECIAL        32              /* 0x */
+#define LARGE  64              /* use 'ABCDEF' instead of 'abcdef' */
+
+#define do_div(n,base) ({ \
+int __res; \
+__res = ((unsigned long) n) % (unsigned) base; \
+n = ((unsigned long) n) / (unsigned) base; \
+__res; })
+
+static char *number(char *str, long num, int base, int size, int precision,
+                   int type)
+{
+       char c, sign, tmp[66];
+       const char *digits = "0123456789abcdefghijklmnopqrstuvwxyz";
+       int i;
+
+       if (type & LARGE)
+               digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+       if (type & LEFT)
+               type &= ~ZEROPAD;
+       if (base < 2 || base > 36)
+               return 0;
+       c = (type & ZEROPAD) ? '0' : ' ';
+       sign = 0;
+       if (type & SIGN) {
+               if (num < 0) {
+                       sign = '-';
+                       num = -num;
+                       size--;
+               } else if (type & PLUS) {
+                       sign = '+';
+                       size--;
+               } else if (type & SPACE) {
+                       sign = ' ';
+                       size--;
+               }
+       }
+       if (type & SPECIAL) {
+               if (base == 16)
+                       size -= 2;
+               else if (base == 8)
+                       size--;
+       }
+       i = 0;
+       if (num == 0)
+               tmp[i++] = '0';
+       else
+               while (num != 0)
+                       tmp[i++] = digits[do_div(num, base)];
+       if (i > precision)
+               precision = i;
+       size -= precision;
+       if (!(type & (ZEROPAD + LEFT)))
+               while (size-- > 0)
+                       *str++ = ' ';
+       if (sign)
+               *str++ = sign;
+       if (type & SPECIAL) {
+               if (base == 8)
+                       *str++ = '0';
+               else if (base == 16) {
+                       *str++ = '0';
+                       *str++ = digits[33];
+               }
+       }
+       if (!(type & LEFT))
+               while (size-- > 0)
+                       *str++ = c;
+       while (i < precision--)
+               *str++ = '0';
+       while (i-- > 0)
+               *str++ = tmp[i];
+       while (size-- > 0)
+               *str++ = ' ';
+       return str;
+}
+
+int vsprintf(char *buf, const char *fmt, va_list args)
+{
+       int len;
+       unsigned long num;
+       int i, base;
+       char *str;
+       const char *s;
+
+       int flags;              /* flags to number() */
+
+       int field_width;        /* width of output field */
+       int precision;          /* min. # of digits for integers; max
+                                  number of chars for from string */
+       int qualifier;          /* 'h', 'l', or 'L' for integer fields */
+
+       for (str = buf; *fmt; ++fmt) {
+               if (*fmt != '%') {
+                       *str++ = *fmt;
+                       continue;
+               }
+
+               /* process flags */
+               flags = 0;
+             repeat:
+               ++fmt;          /* this also skips first '%' */
+               switch (*fmt) {
+               case '-':
+                       flags |= LEFT;
+                       goto repeat;
+               case '+':
+                       flags |= PLUS;
+                       goto repeat;
+               case ' ':
+                       flags |= SPACE;
+                       goto repeat;
+               case '#':
+                       flags |= SPECIAL;
+                       goto repeat;
+               case '0':
+                       flags |= ZEROPAD;
+                       goto repeat;
+               }
+
+               /* get field width */
+               field_width = -1;
+               if (isdigit(*fmt))
+                       field_width = skip_atoi(&fmt);
+               else if (*fmt == '*') {
+                       ++fmt;
+                       /* it's the next argument */
+                       field_width = va_arg(args, int);
+                       if (field_width < 0) {
+                               field_width = -field_width;
+                               flags |= LEFT;
+                       }
+               }
+
+               /* get the precision */
+               precision = -1;
+               if (*fmt == '.') {
+                       ++fmt;
+                       if (isdigit(*fmt))
+                               precision = skip_atoi(&fmt);
+                       else if (*fmt == '*') {
+                               ++fmt;
+                               /* it's the next argument */
+                               precision = va_arg(args, int);
+                       }
+                       if (precision < 0)
+                               precision = 0;
+               }
+
+               /* get the conversion qualifier */
+               qualifier = -1;
+               if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') {
+                       qualifier = *fmt;
+                       ++fmt;
+               }
+
+               /* default base */
+               base = 10;
+
+               switch (*fmt) {
+               case 'c':
+                       if (!(flags & LEFT))
+                               while (--field_width > 0)
+                                       *str++ = ' ';
+                       *str++ = (unsigned char)va_arg(args, int);
+                       while (--field_width > 0)
+                               *str++ = ' ';
+                       continue;
+
+               case 's':
+                       s = va_arg(args, char *);
+                       len = strnlen(s, precision);
+
+                       if (!(flags & LEFT))
+                               while (len < field_width--)
+                                       *str++ = ' ';
+                       for (i = 0; i < len; ++i)
+                               *str++ = *s++;
+                       while (len < field_width--)
+                               *str++ = ' ';
+                       continue;
+
+               case 'p':
+                       if (field_width == -1) {
+                               field_width = 2 * sizeof(void *);
+                               flags |= ZEROPAD;
+                       }
+                       str = number(str,
+                                    (unsigned long)va_arg(args, void *), 16,
+                                    field_width, precision, flags);
+                       continue;
+
+               case 'n':
+                       if (qualifier == 'l') {
+                               long *ip = va_arg(args, long *);
+                               *ip = (str - buf);
+                       } else {
+                               int *ip = va_arg(args, int *);
+                               *ip = (str - buf);
+                       }
+                       continue;
+
+               case '%':
+                       *str++ = '%';
+                       continue;
+
+                       /* integer number formats - set up the flags and "break" */
+               case 'o':
+                       base = 8;
+                       break;
+
+               case 'X':
+                       flags |= LARGE;
+               case 'x':
+                       base = 16;
+                       break;
+
+               case 'd':
+               case 'i':
+                       flags |= SIGN;
+               case 'u':
+                       break;
+
+               default:
+                       *str++ = '%';
+                       if (*fmt)
+                               *str++ = *fmt;
+                       else
+                               --fmt;
+                       continue;
+               }
+               if (qualifier == 'l')
+                       num = va_arg(args, unsigned long);
+               else if (qualifier == 'h') {
+                       num = (unsigned short)va_arg(args, int);
+                       if (flags & SIGN)
+                               num = (short)num;
+               } else if (flags & SIGN)
+                       num = va_arg(args, int);
+               else
+                       num = va_arg(args, unsigned int);
+               str = number(str, num, base, field_width, precision, flags);
+       }
+       *str = '\0';
+       return str - buf;
+}
+
+int sprintf(char *buf, const char *fmt, ...)
+{
+       va_list args;
+       int i;
+
+       va_start(args, fmt);
+       i = vsprintf(buf, fmt, args);
+       va_end(args);
+       return i;
+}
+
+int printf(const char *fmt, ...)
+{
+       char printf_buf[1024];
+       va_list args;
+       int printed;
+
+       va_start(args, fmt);
+       printed = vsprintf(printf_buf, fmt, args);
+       va_end(args);
+
+       puts(printf_buf);
+
+       return printed;
+}
diff --git a/arch/i386/boot/setup.S b/arch/i386/boot/setup.S
deleted file mode 100644 (file)
index 6dbcc95..0000000
+++ /dev/null
@@ -1,1075 +0,0 @@
-/*
- *     setup.S         Copyright (C) 1991, 1992 Linus Torvalds
- *
- * setup.s is responsible for getting the system data from the BIOS,
- * and putting them into the appropriate places in system memory.
- * both setup.s and system has been loaded by the bootblock.
- *
- * This code asks the bios for memory/disk/other parameters, and
- * puts them in a "safe" place: 0x90000-0x901FF, ie where the
- * boot-block used to be. It is then up to the protected mode
- * system to read them from there before the area is overwritten
- * for buffer-blocks.
- *
- * Move PS/2 aux init code to psaux.c
- * (troyer@saifr00.cfsat.Honeywell.COM) 03Oct92
- *
- * some changes and additional features by Christoph Niemann,
- * March 1993/June 1994 (Christoph.Niemann@linux.org)
- *
- * add APM BIOS checking by Stephen Rothwell, May 1994
- * (sfr@canb.auug.org.au)
- *
- * High load stuff, initrd support and position independency
- * by Hans Lermen & Werner Almesberger, February 1996
- * <lermen@elserv.ffm.fgan.de>, <almesber@lrc.epfl.ch>
- *
- * Video handling moved to video.S by Martin Mares, March 1996
- * <mj@k332.feld.cvut.cz>
- *
- * Extended memory detection scheme retwiddled by orc@pell.chi.il.us (david
- * parsons) to avoid loadlin confusion, July 1997
- *
- * Transcribed from Intel (as86) -> AT&T (gas) by Chris Noe, May 1999.
- * <stiker@northlink.com>
- *
- * Fix to work around buggy BIOSes which don't use carry bit correctly
- * and/or report extended memory in CX/DX for e801h memory size detection 
- * call.  As a result the kernel got wrong figures.  The int15/e801h docs
- * from Ralf Brown interrupt list seem to indicate AX/BX should be used
- * anyway.  So to avoid breaking many machines (presumably there was a reason
- * to orginally use CX/DX instead of AX/BX), we do a kludge to see
- * if CX/DX have been changed in the e801 call and if so use AX/BX .
- * Michael Miller, April 2001 <michaelm@mjmm.org>
- *
- * New A20 code ported from SYSLINUX by H. Peter Anvin. AMD Elan bugfixes
- * by Robert Schwebel, December 2001 <robert@schwebel.de>
- */
-
-#include <asm/segment.h>
-#include <linux/utsrelease.h>
-#include <linux/compile.h>
-#include <asm/boot.h>
-#include <asm/e820.h>
-#include <asm/page.h>
-#include <asm/setup.h>
-       
-/* Signature words to ensure LILO loaded us right */
-#define SIG1   0xAA55
-#define SIG2   0x5A5A
-
-INITSEG  = DEF_INITSEG         # 0x9000, we move boot here, out of the way
-SYSSEG   = DEF_SYSSEG          # 0x1000, system loaded at 0x10000 (65536).
-SETUPSEG = DEF_SETUPSEG                # 0x9020, this is the current segment
-                               # ... and the former contents of CS
-
-DELTA_INITSEG = SETUPSEG - INITSEG     # 0x0020
-
-.code16
-.globl begtext, begdata, begbss, endtext, enddata, endbss
-
-.text
-begtext:
-.data
-begdata:
-.bss
-begbss:
-.text
-
-start:
-       jmp     trampoline
-
-# This is the setup header, and it must start at %cs:2 (old 0x9020:2)
-
-               .ascii  "HdrS"          # header signature
-               .word   0x0206          # header version number (>= 0x0105)
-                                       # or else old loadlin-1.5 will fail)
-realmode_swtch:        .word   0, 0            # default_switch, SETUPSEG
-start_sys_seg: .word   SYSSEG
-               .word   kernel_version  # pointing to kernel version string
-                                       # above section of header is compatible
-                                       # with loadlin-1.5 (header v1.5). Don't
-                                       # change it.
-
-type_of_loader:        .byte   0               # = 0, old one (LILO, Loadlin,
-                                       #      Bootlin, SYSLX, bootsect...)
-                                       # See Documentation/i386/boot.txt for
-                                       # assigned ids
-       
-# flags, unused bits must be zero (RFU) bit within loadflags
-loadflags:
-LOADED_HIGH    = 1                     # If set, the kernel is loaded high
-CAN_USE_HEAP   = 0x80                  # If set, the loader also has set
-                                       # heap_end_ptr to tell how much
-                                       # space behind setup.S can be used for
-                                       # heap purposes.
-                                       # Only the loader knows what is free
-#ifndef __BIG_KERNEL__
-               .byte   0
-#else
-               .byte   LOADED_HIGH
-#endif
-
-setup_move_size: .word  0x8000         # size to move, when setup is not
-                                       # loaded at 0x90000. We will move setup 
-                                       # to 0x90000 then just before jumping
-                                       # into the kernel. However, only the
-                                       # loader knows how much data behind
-                                       # us also needs to be loaded.
-
-code32_start:                          # here loaders can put a different
-                                       # start address for 32-bit code.
-#ifndef __BIG_KERNEL__
-               .long   0x1000          #   0x1000 = default for zImage
-#else
-               .long   0x100000        # 0x100000 = default for big kernel
-#endif
-
-ramdisk_image: .long   0               # address of loaded ramdisk image
-                                       # Here the loader puts the 32-bit
-                                       # address where it loaded the image.
-                                       # This only will be read by the kernel.
-
-ramdisk_size:  .long   0               # its size in bytes
-
-bootsect_kludge:
-               .long   0               # obsolete
-
-heap_end_ptr:  .word   modelist+1024   # (Header version 0x0201 or later)
-                                       # space from here (exclusive) down to
-                                       # end of setup code can be used by setup
-                                       # for local heap purposes.
-
-pad1:          .word   0
-cmd_line_ptr:  .long 0                 # (Header version 0x0202 or later)
-                                       # If nonzero, a 32-bit pointer
-                                       # to the kernel command line.
-                                       # The command line should be
-                                       # located between the start of
-                                       # setup and the end of low
-                                       # memory (0xa0000), or it may
-                                       # get overwritten before it
-                                       # gets read.  If this field is
-                                       # used, there is no longer
-                                       # anything magical about the
-                                       # 0x90000 segment; the setup
-                                       # can be located anywhere in
-                                       # low memory 0x10000 or higher.
-
-ramdisk_max:   .long (-__PAGE_OFFSET-(512 << 20)-1) & 0x7fffffff
-                                       # (Header version 0x0203 or later)
-                                       # The highest safe address for
-                                       # the contents of an initrd
-
-kernel_alignment:  .long CONFIG_PHYSICAL_ALIGN         #physical addr alignment
-                                               #required for protected mode
-                                               #kernel
-#ifdef CONFIG_RELOCATABLE
-relocatable_kernel:    .byte 1
-#else
-relocatable_kernel:    .byte 0
-#endif
-pad2:                  .byte 0
-pad3:                  .word 0
-
-cmdline_size:   .long   COMMAND_LINE_SIZE-1     #length of the command line,
-                                                #added with boot protocol
-                                                #version 2.06
-
-trampoline:    call    start_of_setup
-               .align 16
-                                       # The offset at this point is 0x240
-               .space  (0xeff-0x240+1) # E820 & EDD space (ending at 0xeff)
-# End of setup header #####################################################
-
-start_of_setup:
-# Bootlin depends on this being done early
-       movw    $0x01500, %ax
-       movb    $0x81, %dl
-       int     $0x13
-
-#ifdef SAFE_RESET_DISK_CONTROLLER
-# Reset the disk controller.
-       movw    $0x0000, %ax
-       movb    $0x80, %dl
-       int     $0x13
-#endif
-
-# Set %ds = %cs, we know that SETUPSEG = %cs at this point
-       movw    %cs, %ax                # aka SETUPSEG
-       movw    %ax, %ds
-# Check signature at end of setup
-       cmpw    $SIG1, setup_sig1
-       jne     bad_sig
-
-       cmpw    $SIG2, setup_sig2
-       jne     bad_sig
-
-       jmp     good_sig1
-
-# Routine to print asciiz string at ds:si
-prtstr:
-       lodsb
-       andb    %al, %al
-       jz      fin
-
-       call    prtchr
-       jmp     prtstr
-
-fin:   ret
-
-# Space printing
-prtsp2:        call    prtspc          # Print double space
-prtspc:        movb    $0x20, %al      # Print single space (note: fall-thru)
-
-# Part of above routine, this one just prints ascii al
-prtchr:        pushw   %ax
-       pushw   %cx
-       movw    $7,%bx
-       movw    $0x01, %cx
-       movb    $0x0e, %ah
-       int     $0x10
-       popw    %cx
-       popw    %ax
-       ret
-
-beep:  movb    $0x07, %al
-       jmp     prtchr
-       
-no_sig_mess: .string   "No setup signature found ..."
-
-good_sig1:
-       jmp     good_sig
-
-# We now have to find the rest of the setup code/data
-bad_sig:
-       movw    %cs, %ax                        # SETUPSEG
-       subw    $DELTA_INITSEG, %ax             # INITSEG
-       movw    %ax, %ds
-       xorb    %bh, %bh
-       movb    (497), %bl                      # get setup sect from bootsect
-       subw    $4, %bx                         # LILO loads 4 sectors of setup
-       shlw    $8, %bx                         # convert to words (1sect=2^8 words)
-       movw    %bx, %cx
-       shrw    $3, %bx                         # convert to segment
-       addw    $SYSSEG, %bx
-       movw    %bx, %cs:start_sys_seg
-# Move rest of setup code/data to here
-       movw    $2048, %di                      # four sectors loaded by LILO
-       subw    %si, %si
-       pushw   %cs
-       popw    %es
-       movw    $SYSSEG, %ax
-       movw    %ax, %ds
-       rep
-       movsw
-       movw    %cs, %ax                        # aka SETUPSEG
-       movw    %ax, %ds
-       cmpw    $SIG1, setup_sig1
-       jne     no_sig
-
-       cmpw    $SIG2, setup_sig2
-       jne     no_sig
-
-       jmp     good_sig
-
-no_sig:
-       lea     no_sig_mess, %si
-       call    prtstr
-
-no_sig_loop:
-       hlt
-       jmp     no_sig_loop
-
-good_sig:
-       movw    %cs, %ax                        # aka SETUPSEG
-       subw    $DELTA_INITSEG, %ax             # aka INITSEG
-       movw    %ax, %ds
-# Check if an old loader tries to load a big-kernel
-       testb   $LOADED_HIGH, %cs:loadflags     # Do we have a big kernel?
-       jz      loader_ok                       # No, no danger for old loaders.
-
-       cmpb    $0, %cs:type_of_loader          # Do we have a loader that
-                                               # can deal with us?
-       jnz     loader_ok                       # Yes, continue.
-
-       pushw   %cs                             # No, we have an old loader,
-       popw    %ds                             # die. 
-       lea     loader_panic_mess, %si
-       call    prtstr
-
-       jmp     no_sig_loop
-
-loader_panic_mess: .string "Wrong loader, giving up..."
-
-# check minimum cpuid
-# we do this here because it is the last place we can actually
-# show a user visible error message. Later the video modus
-# might be already messed up.
-loader_ok:
-       call verify_cpu
-       testl  %eax,%eax
-       jz      cpu_ok
-       movw    %cs,%ax         # aka SETUPSEG
-       movw    %ax,%ds
-       lea     cpu_panic_mess,%si
-       call    prtstr
-1:     jmp     1b
-
-cpu_panic_mess:
-       .asciz  "PANIC: CPU too old for this kernel."
-
-#include "../kernel/verify_cpu.S"
-
-cpu_ok:
-# Get memory size (extended mem, kB)
-
-       xorl    %eax, %eax
-       movl    %eax, (0x1e0)
-#ifndef STANDARD_MEMORY_BIOS_CALL
-       movb    %al, (E820NR)
-# Try three different memory detection schemes.  First, try
-# e820h, which lets us assemble a memory map, then try e801h,
-# which returns a 32-bit memory size, and finally 88h, which
-# returns 0-64m
-
-# method E820H:
-# the memory map from hell.  e820h returns memory classified into
-# a whole bunch of different types, and allows memory holes and
-# everything.  We scan through this memory map and build a list
-# of the first 32 memory areas, which we return at [E820MAP].
-# This is documented at http://www.acpi.info/, in the ACPI 2.0 specification.
-
-#define SMAP  0x534d4150
-
-meme820:
-       xorl    %ebx, %ebx                      # continuation counter
-       movw    $E820MAP, %di                   # point into the whitelist
-                                               # so we can have the bios
-                                               # directly write into it.
-
-jmpe820:
-       movl    $0x0000e820, %eax               # e820, upper word zeroed
-       movl    $SMAP, %edx                     # ascii 'SMAP'
-       movl    $20, %ecx                       # size of the e820rec
-       pushw   %ds                             # data record.
-       popw    %es
-       int     $0x15                           # make the call
-       jc      bail820                         # fall to e801 if it fails
-
-       cmpl    $SMAP, %eax                     # check the return is `SMAP'
-       jne     bail820                         # fall to e801 if it fails
-
-#      cmpl    $1, 16(%di)                     # is this usable memory?
-#      jne     again820
-
-       # If this is usable memory, we save it by simply advancing %di by
-       # sizeof(e820rec).
-       #
-good820:
-       movb    (E820NR), %al                   # up to 128 entries
-       cmpb    $E820MAX, %al
-       jae     bail820
-
-       incb    (E820NR)
-       movw    %di, %ax
-       addw    $20, %ax
-       movw    %ax, %di
-again820:
-       cmpl    $0, %ebx                        # check to see if
-       jne     jmpe820                         # %ebx is set to EOF
-bail820:
-
-
-# method E801H:
-# memory size is in 1k chunksizes, to avoid confusing loadlin.
-# we store the 0xe801 memory size in a completely different place,
-# because it will most likely be longer than 16 bits.
-# (use 1e0 because that's what Larry Augustine uses in his
-# alternative new memory detection scheme, and it's sensible
-# to write everything into the same place.)
-
-meme801:
-       stc                                     # fix to work around buggy
-       xorw    %cx,%cx                         # BIOSes which don't clear/set
-       xorw    %dx,%dx                         # carry on pass/error of
-                                               # e801h memory size call
-                                               # or merely pass cx,dx though
-                                               # without changing them.
-       movw    $0xe801, %ax
-       int     $0x15
-       jc      mem88
-
-       cmpw    $0x0, %cx                       # Kludge to handle BIOSes
-       jne     e801usecxdx                     # which report their extended
-       cmpw    $0x0, %dx                       # memory in AX/BX rather than
-       jne     e801usecxdx                     # CX/DX.  The spec I have read
-       movw    %ax, %cx                        # seems to indicate AX/BX 
-       movw    %bx, %dx                        # are more reasonable anyway...
-
-e801usecxdx:
-       andl    $0xffff, %edx                   # clear sign extend
-       shll    $6, %edx                        # and go from 64k to 1k chunks
-       movl    %edx, (0x1e0)                   # store extended memory size
-       andl    $0xffff, %ecx                   # clear sign extend
-       addl    %ecx, (0x1e0)                   # and add lower memory into
-                                               # total size.
-
-# Ye Olde Traditional Methode.  Returns the memory size (up to 16mb or
-# 64mb, depending on the bios) in ax.
-mem88:
-
-#endif
-       movb    $0x88, %ah
-       int     $0x15
-       movw    %ax, (2)
-
-# Set the keyboard repeat rate to the max
-       movw    $0x0305, %ax
-       xorw    %bx, %bx
-       int     $0x16
-
-# Check for video adapter and its parameters and allow the
-# user to browse video modes.
-       call    video                           # NOTE: we need %ds pointing
-                                               # to bootsector
-
-# Get hd0 data...
-       xorw    %ax, %ax
-       movw    %ax, %ds
-       ldsw    (4 * 0x41), %si
-       movw    %cs, %ax                        # aka SETUPSEG
-       subw    $DELTA_INITSEG, %ax             # aka INITSEG
-       pushw   %ax
-       movw    %ax, %es
-       movw    $0x0080, %di
-       movw    $0x10, %cx
-       pushw   %cx
-       cld
-       rep
-       movsb
-# Get hd1 data...
-       xorw    %ax, %ax
-       movw    %ax, %ds
-       ldsw    (4 * 0x46), %si
-       popw    %cx
-       popw    %es
-       movw    $0x0090, %di
-       rep
-       movsb
-# Check that there IS a hd1 :-)
-       movw    $0x01500, %ax
-       movb    $0x81, %dl
-       int     $0x13
-       jc      no_disk1
-       
-       cmpb    $3, %ah
-       je      is_disk1
-
-no_disk1:
-       movw    %cs, %ax                        # aka SETUPSEG
-       subw    $DELTA_INITSEG, %ax             # aka INITSEG
-       movw    %ax, %es
-       movw    $0x0090, %di
-       movw    $0x10, %cx
-       xorw    %ax, %ax
-       cld
-       rep
-       stosb
-is_disk1:
-# check for Micro Channel (MCA) bus
-       movw    %cs, %ax                        # aka SETUPSEG
-       subw    $DELTA_INITSEG, %ax             # aka INITSEG
-       movw    %ax, %ds
-       xorw    %ax, %ax
-       movw    %ax, (0xa0)                     # set table length to 0
-       movb    $0xc0, %ah
-       stc
-       int     $0x15                           # moves feature table to es:bx
-       jc      no_mca
-
-       pushw   %ds
-       movw    %es, %ax
-       movw    %ax, %ds
-       movw    %cs, %ax                        # aka SETUPSEG
-       subw    $DELTA_INITSEG, %ax             # aka INITSEG
-       movw    %ax, %es
-       movw    %bx, %si
-       movw    $0xa0, %di
-       movw    (%si), %cx
-       addw    $2, %cx                         # table length is a short
-       cmpw    $0x10, %cx
-       jc      sysdesc_ok
-
-       movw    $0x10, %cx                      # we keep only first 16 bytes
-sysdesc_ok:
-       rep
-       movsb
-       popw    %ds
-no_mca:
-#ifdef CONFIG_X86_VOYAGER
-       movb    $0xff, 0x40     # flag on config found
-       movb    $0xc0, %al
-       mov     $0xff, %ah
-       int     $0x15           # put voyager config info at es:di
-       jc      no_voyager
-       movw    $0x40, %si      # place voyager info in apm table
-       cld
-       movw    $7, %cx
-voyager_rep:
-       movb    %es:(%di), %al
-       movb    %al,(%si)
-       incw    %di
-       incw    %si
-       decw    %cx
-       jnz     voyager_rep
-no_voyager:    
-#endif
-# Check for PS/2 pointing device
-       movw    %cs, %ax                        # aka SETUPSEG
-       subw    $DELTA_INITSEG, %ax             # aka INITSEG
-       movw    %ax, %ds
-       movb    $0, (0x1ff)                     # default is no pointing device
-       int     $0x11                           # int 0x11: equipment list
-       testb   $0x04, %al                      # check if mouse installed
-       jz      no_psmouse
-
-       movb    $0xAA, (0x1ff)                  # device present
-no_psmouse:
-
-#if defined(CONFIG_X86_SPEEDSTEP_SMI) || defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE)
-       movl    $0x0000E980, %eax               # IST Support 
-       movl    $0x47534943, %edx               # Request value
-       int     $0x15
-
-       movl    %eax, (96)
-       movl    %ebx, (100)
-       movl    %ecx, (104)
-       movl    %edx, (108)
-#endif
-
-#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
-# Then check for an APM BIOS...
-                                               # %ds points to the bootsector
-       movw    $0, 0x40                        # version = 0 means no APM BIOS
-       movw    $0x05300, %ax                   # APM BIOS installation check
-       xorw    %bx, %bx
-       int     $0x15
-       jc      done_apm_bios                   # Nope, no APM BIOS
-       
-       cmpw    $0x0504d, %bx                   # Check for "PM" signature
-       jne     done_apm_bios                   # No signature, no APM BIOS
-
-       andw    $0x02, %cx                      # Is 32 bit supported?
-       je      done_apm_bios                   # No 32-bit, no (good) APM BIOS
-
-       movw    $0x05304, %ax                   # Disconnect first just in case
-       xorw    %bx, %bx
-       int     $0x15                           # ignore return code
-       movw    $0x05303, %ax                   # 32 bit connect
-       xorl    %ebx, %ebx
-       xorw    %cx, %cx                        # paranoia :-)
-       xorw    %dx, %dx                        #   ...
-       xorl    %esi, %esi                      #   ...
-       xorw    %di, %di                        #   ...
-       int     $0x15
-       jc      no_32_apm_bios                  # Ack, error. 
-
-       movw    %ax,  (66)                      # BIOS code segment
-       movl    %ebx, (68)                      # BIOS entry point offset
-       movw    %cx,  (72)                      # BIOS 16 bit code segment
-       movw    %dx,  (74)                      # BIOS data segment
-       movl    %esi, (78)                      # BIOS code segment lengths
-       movw    %di,  (82)                      # BIOS data segment length
-# Redo the installation check as the 32 bit connect
-# modifies the flags returned on some BIOSs
-       movw    $0x05300, %ax                   # APM BIOS installation check
-       xorw    %bx, %bx
-       xorw    %cx, %cx                        # paranoia
-       int     $0x15
-       jc      apm_disconnect                  # error -> shouldn't happen
-
-       cmpw    $0x0504d, %bx                   # check for "PM" signature
-       jne     apm_disconnect                  # no sig -> shouldn't happen
-
-       movw    %ax, (64)                       # record the APM BIOS version
-       movw    %cx, (76)                       # and flags
-       jmp     done_apm_bios
-
-apm_disconnect:                                        # Tidy up
-       movw    $0x05304, %ax                   # Disconnect
-       xorw    %bx, %bx
-       int     $0x15                           # ignore return code
-
-       jmp     done_apm_bios
-
-no_32_apm_bios:
-       andw    $0xfffd, (76)                   # remove 32 bit support bit
-done_apm_bios:
-#endif
-
-#include "edd.S"
-
-# Now we want to move to protected mode ...
-       cmpw    $0, %cs:realmode_swtch
-       jz      rmodeswtch_normal
-
-       lcall   *%cs:realmode_swtch
-
-       jmp     rmodeswtch_end
-
-rmodeswtch_normal:
-        pushw  %cs
-       call    default_switch
-
-rmodeswtch_end:
-# Now we move the system to its rightful place ... but we check if we have a
-# big-kernel. In that case we *must* not move it ...
-       testb   $LOADED_HIGH, %cs:loadflags
-       jz      do_move0                        # .. then we have a normal low
-                                               # loaded zImage
-                                               # .. or else we have a high
-                                               # loaded bzImage
-       jmp     end_move                        # ... and we skip moving
-
-do_move0:
-       movw    $0x100, %ax                     # start of destination segment
-       movw    %cs, %bp                        # aka SETUPSEG
-       subw    $DELTA_INITSEG, %bp             # aka INITSEG
-       movw    %cs:start_sys_seg, %bx          # start of source segment
-       cld
-do_move:
-       movw    %ax, %es                        # destination segment
-       incb    %ah                             # instead of add ax,#0x100
-       movw    %bx, %ds                        # source segment
-       addw    $0x100, %bx
-       subw    %di, %di
-       subw    %si, %si
-       movw    $0x800, %cx
-       rep
-       movsw
-       cmpw    %bp, %bx                        # assume start_sys_seg > 0x200,
-                                               # so we will perhaps read one
-                                               # page more than needed, but
-                                               # never overwrite INITSEG
-                                               # because destination is a
-                                               # minimum one page below source
-       jb      do_move
-
-end_move:
-# then we load the segment descriptors
-       movw    %cs, %ax                        # aka SETUPSEG
-       movw    %ax, %ds
-               
-# Check whether we need to be downward compatible with version <=201
-       cmpl    $0, cmd_line_ptr
-       jne     end_move_self           # loader uses version >=202 features
-       cmpb    $0x20, type_of_loader
-       je      end_move_self           # bootsect loader, we know of it
-
-# Boot loader doesnt support boot protocol version 2.02.
-# If we have our code not at 0x90000, we need to move it there now.
-# We also then need to move the params behind it (commandline)
-# Because we would overwrite the code on the current IP, we move
-# it in two steps, jumping high after the first one.
-       movw    %cs, %ax
-       cmpw    $SETUPSEG, %ax
-       je      end_move_self
-
-       cli                                     # make sure we really have
-                                               # interrupts disabled !
-                                               # because after this the stack
-                                               # should not be used
-       subw    $DELTA_INITSEG, %ax             # aka INITSEG
-       movw    %ss, %dx
-       cmpw    %ax, %dx
-       jb      move_self_1
-
-       addw    $INITSEG, %dx
-       subw    %ax, %dx                        # this will go into %ss after
-                                               # the move
-move_self_1:
-       movw    %ax, %ds
-       movw    $INITSEG, %ax                   # real INITSEG
-       movw    %ax, %es
-       movw    %cs:setup_move_size, %cx
-       std                                     # we have to move up, so we use
-                                               # direction down because the
-                                               # areas may overlap
-       movw    %cx, %di
-       decw    %di
-       movw    %di, %si
-       subw    $move_self_here+0x200, %cx
-       rep
-       movsb
-       ljmp    $SETUPSEG, $move_self_here
-
-move_self_here:
-       movw    $move_self_here+0x200, %cx
-       rep
-       movsb
-       movw    $SETUPSEG, %ax
-       movw    %ax, %ds
-       movw    %dx, %ss
-end_move_self:                                 # now we are at the right place
-
-#
-# Enable A20.  This is at the very best an annoying procedure.
-# A20 code ported from SYSLINUX 1.52-1.63 by H. Peter Anvin.
-# AMD Elan bug fix by Robert Schwebel.
-#
-
-#if defined(CONFIG_X86_ELAN)
-       movb $0x02, %al                 # alternate A20 gate
-       outb %al, $0x92                 # this works on SC410/SC520
-a20_elan_wait:
-       call a20_test
-       jz a20_elan_wait
-       jmp a20_done
-#endif
-
-
-A20_TEST_LOOPS         =  32           # Iterations per wait
-A20_ENABLE_LOOPS       = 255           # Total loops to try            
-
-
-#ifndef CONFIG_X86_VOYAGER
-a20_try_loop:
-
-       # First, see if we are on a system with no A20 gate.
-a20_none:
-       call    a20_test
-       jnz     a20_done
-
-       # Next, try the BIOS (INT 0x15, AX=0x2401)
-a20_bios:
-       movw    $0x2401, %ax
-       pushfl                                  # Be paranoid about flags
-       int     $0x15
-       popfl
-
-       call    a20_test
-       jnz     a20_done
-
-       # Try enabling A20 through the keyboard controller
-#endif /* CONFIG_X86_VOYAGER */
-a20_kbc:
-       call    empty_8042
-
-#ifndef CONFIG_X86_VOYAGER
-       call    a20_test                        # Just in case the BIOS worked
-       jnz     a20_done                        # but had a delayed reaction.
-#endif
-
-       movb    $0xD1, %al                      # command write
-       outb    %al, $0x64
-       call    empty_8042
-
-       movb    $0xDF, %al                      # A20 on
-       outb    %al, $0x60
-       call    empty_8042
-
-#ifndef CONFIG_X86_VOYAGER
-       # Wait until a20 really *is* enabled; it can take a fair amount of
-       # time on certain systems; Toshiba Tecras are known to have this
-       # problem.
-a20_kbc_wait:
-       xorw    %cx, %cx
-a20_kbc_wait_loop:
-       call    a20_test
-       jnz     a20_done
-       loop    a20_kbc_wait_loop
-
-       # Final attempt: use "configuration port A"
-a20_fast:
-       inb     $0x92, %al                      # Configuration Port A
-       orb     $0x02, %al                      # "fast A20" version
-       andb    $0xFE, %al                      # don't accidentally reset
-       outb    %al, $0x92
-
-       # Wait for configuration port A to take effect
-a20_fast_wait:
-       xorw    %cx, %cx
-a20_fast_wait_loop:
-       call    a20_test
-       jnz     a20_done
-       loop    a20_fast_wait_loop
-
-       # A20 is still not responding.  Try frobbing it again.
-       # 
-       decb    (a20_tries)
-       jnz     a20_try_loop
-       
-       movw    $a20_err_msg, %si
-       call    prtstr
-
-a20_die:
-       hlt
-       jmp     a20_die
-
-a20_tries:
-       .byte   A20_ENABLE_LOOPS
-
-a20_err_msg:
-       .ascii  "linux: fatal error: A20 gate not responding!"
-       .byte   13, 10, 0
-
-       # If we get here, all is good
-a20_done:
-
-#endif /* CONFIG_X86_VOYAGER */
-# set up gdt and idt and 32bit start address
-       lidt    idt_48                          # load idt with 0,0
-       xorl    %eax, %eax                      # Compute gdt_base
-       movw    %ds, %ax                        # (Convert %ds:gdt to a linear ptr)
-       shll    $4, %eax
-       addl    %eax, code32
-       addl    $gdt, %eax
-       movl    %eax, (gdt_48+2)
-       lgdt    gdt_48                          # load gdt with whatever is
-                                               # appropriate
-
-# make sure any possible coprocessor is properly reset..
-       xorw    %ax, %ax
-       outb    %al, $0xf0
-       call    delay
-
-       outb    %al, $0xf1
-       call    delay
-
-# well, that went ok, I hope. Now we mask all interrupts - the rest
-# is done in init_IRQ().
-       movb    $0xFF, %al                      # mask all interrupts for now
-       outb    %al, $0xA1
-       call    delay
-       
-       movb    $0xFB, %al                      # mask all irq's but irq2 which
-       outb    %al, $0x21                      # is cascaded
-
-# Well, that certainly wasn't fun :-(. Hopefully it works, and we don't
-# need no steenking BIOS anyway (except for the initial loading :-).
-# The BIOS-routine wants lots of unnecessary data, and it's less
-# "interesting" anyway. This is how REAL programmers do it.
-#
-# Well, now's the time to actually move into protected mode. To make
-# things as simple as possible, we do no register set-up or anything,
-# we let the gnu-compiled 32-bit programs do that. We just jump to
-# absolute address 0x1000 (or the loader supplied one),
-# in 32-bit protected mode.
-#
-# Note that the short jump isn't strictly needed, although there are
-# reasons why it might be a good idea. It won't hurt in any case.
-       movw    $1, %ax                         # protected mode (PE) bit
-       lmsw    %ax                             # This is it!
-       jmp     flush_instr
-
-flush_instr:
-       xorw    %bx, %bx                        # Flag to indicate a boot
-       xorl    %esi, %esi                      # Pointer to real-mode code
-       movw    %cs, %si
-       subw    $DELTA_INITSEG, %si
-       shll    $4, %esi                        # Convert to 32-bit pointer
-
-# jump to startup_32 in arch/i386/boot/compressed/head.S
-#      
-# NOTE: For high loaded big kernels we need a
-#      jmpi    0x100000,__BOOT_CS
-#
-#      but we yet haven't reloaded the CS register, so the default size 
-#      of the target offset still is 16 bit.
-#      However, using an operand prefix (0x66), the CPU will properly
-#      take our 48 bit far pointer. (INTeL 80386 Programmer's Reference
-#      Manual, Mixing 16-bit and 32-bit code, page 16-6)
-
-       .byte 0x66, 0xea                        # prefix + jmpi-opcode
-code32:        .long   startup_32                      # will be set to %cs+startup_32
-       .word   __BOOT_CS
-.code32
-startup_32:
-       movl $(__BOOT_DS), %eax
-       movl %eax, %ds
-       movl %eax, %es
-       movl %eax, %fs
-       movl %eax, %gs
-       movl %eax, %ss
-
-       xorl %eax, %eax
-1:     incl %eax                               # check that A20 really IS enabled
-       movl %eax, 0x00000000                   # loop forever if it isn't
-       cmpl %eax, 0x00100000
-       je 1b
-
-       # Jump to the 32bit entry point
-       jmpl *(code32_start - start + (DELTA_INITSEG << 4))(%esi)
-.code16
-
-# Here's a bunch of information about your current kernel..
-kernel_version:        .ascii  UTS_RELEASE
-               .ascii  " ("
-               .ascii  LINUX_COMPILE_BY
-               .ascii  "@"
-               .ascii  LINUX_COMPILE_HOST
-               .ascii  ") "
-               .ascii  UTS_VERSION
-               .byte   0
-
-# This is the default real mode switch routine.
-# to be called just before protected mode transition
-default_switch:
-       cli                                     # no interrupts allowed !
-       movb    $0x80, %al                      # disable NMI for bootup
-                                               # sequence
-       outb    %al, $0x70
-       lret
-
-
-#ifndef CONFIG_X86_VOYAGER
-# This routine tests whether or not A20 is enabled.  If so, it
-# exits with zf = 0.
-#
-# The memory address used, 0x200, is the int $0x80 vector, which
-# should be safe.
-
-A20_TEST_ADDR = 4*0x80
-
-a20_test:
-       pushw   %cx
-       pushw   %ax
-       xorw    %cx, %cx
-       movw    %cx, %fs                        # Low memory
-       decw    %cx
-       movw    %cx, %gs                        # High memory area
-       movw    $A20_TEST_LOOPS, %cx
-       movw    %fs:(A20_TEST_ADDR), %ax
-       pushw   %ax
-a20_test_wait:
-       incw    %ax
-       movw    %ax, %fs:(A20_TEST_ADDR)
-       call    delay                           # Serialize and make delay constant
-       cmpw    %gs:(A20_TEST_ADDR+0x10), %ax
-       loope   a20_test_wait
-
-       popw    %fs:(A20_TEST_ADDR)
-       popw    %ax
-       popw    %cx
-       ret     
-
-#endif /* CONFIG_X86_VOYAGER */
-
-# This routine checks that the keyboard command queue is empty
-# (after emptying the output buffers)
-#
-# Some machines have delusions that the keyboard buffer is always full
-# with no keyboard attached...
-#
-# If there is no keyboard controller, we will usually get 0xff
-# to all the reads.  With each IO taking a microsecond and
-# a timeout of 100,000 iterations, this can take about half a
-# second ("delay" == outb to port 0x80). That should be ok,
-# and should also be plenty of time for a real keyboard controller
-# to empty.
-#
-
-empty_8042:
-       pushl   %ecx
-       movl    $100000, %ecx
-
-empty_8042_loop:
-       decl    %ecx
-       jz      empty_8042_end_loop
-
-       call    delay
-
-       inb     $0x64, %al                      # 8042 status port
-       testb   $1, %al                         # output buffer?
-       jz      no_output
-
-       call    delay
-       inb     $0x60, %al                      # read it
-       jmp     empty_8042_loop
-
-no_output:
-       testb   $2, %al                         # is input buffer full?
-       jnz     empty_8042_loop                 # yes - loop
-empty_8042_end_loop:
-       popl    %ecx
-       ret
-
-# Read the cmos clock. Return the seconds in al
-gettime:
-       pushw   %cx
-       movb    $0x02, %ah
-       int     $0x1a
-       movb    %dh, %al                        # %dh contains the seconds
-       andb    $0x0f, %al
-       movb    %dh, %ah
-       movb    $0x04, %cl
-       shrb    %cl, %ah
-       aad
-       popw    %cx
-       ret
-
-# Delay is needed after doing I/O
-delay:
-       outb    %al,$0x80
-       ret
-
-# Descriptor tables
-#
-# NOTE: The intel manual says gdt should be sixteen bytes aligned for
-# efficiency reasons.  However, there are machines which are known not
-# to boot with misaligned GDTs, so alter this at your peril!  If you alter
-# GDT_ENTRY_BOOT_CS (in asm/segment.h) remember to leave at least two
-# empty GDT entries (one for NULL and one reserved).
-#
-# NOTE:        On some CPUs, the GDT must be 8 byte aligned.  This is
-# true for the Voyager Quad CPU card which will not boot without
-# This directive.  16 byte aligment is recommended by intel.
-#
-       .align 16
-gdt:
-       .fill GDT_ENTRY_BOOT_CS,8,0
-
-       .word   0xFFFF                          # 4Gb - (0x100000*0x1000 = 4Gb)
-       .word   0                               # base address = 0
-       .word   0x9A00                          # code read/exec
-       .word   0x00CF                          # granularity = 4096, 386
-                                               #  (+5th nibble of limit)
-
-       .word   0xFFFF                          # 4Gb - (0x100000*0x1000 = 4Gb)
-       .word   0                               # base address = 0
-       .word   0x9200                          # data read/write
-       .word   0x00CF                          # granularity = 4096, 386
-                                               #  (+5th nibble of limit)
-gdt_end:
-       .align  4
-       
-       .word   0                               # alignment byte
-idt_48:
-       .word   0                               # idt limit = 0
-       .word   0, 0                            # idt base = 0L
-
-       .word   0                               # alignment byte
-gdt_48:
-       .word   gdt_end - gdt - 1               # gdt limit
-       .word   0, 0                            # gdt base (filled in later)
-
-# Include video setup & detection code
-
-#include "video.S"
-
-# Setup signature -- must be last
-setup_sig1:    .word   SIG1
-setup_sig2:    .word   SIG2
-
-# After this point, there is some free space which is used by the video mode
-# handling code to store the temporary mode table (not used by the kernel).
-
-modelist:
-
-.text
-endtext:
-.data
-enddata:
-.bss
-endbss:
diff --git a/arch/i386/boot/setup.ld b/arch/i386/boot/setup.ld
new file mode 100644 (file)
index 0000000..df9234b
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * setup.ld
+ *
+ * Linker script for the i386 setup code
+ */
+OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
+OUTPUT_ARCH(i386)
+ENTRY(_start)
+
+SECTIONS
+{
+       . = 0;
+       .bstext         : { *(.bstext) }
+       .bsdata         : { *(.bsdata) }
+
+       . = 497;
+       .header         : { *(.header) }
+       .inittext       : { *(.inittext) }
+       .initdata       : { *(.initdata) }
+       .text           : { *(.text*) }
+
+       . = ALIGN(16);
+       .rodata         : { *(.rodata*) }
+
+       .videocards     : {
+               video_cards = .;
+               *(.videocards)
+               video_cards_end = .;
+       }
+
+       . = ALIGN(16);
+       .data           : { *(.data*) }
+
+       .signature      : {
+               setup_sig = .;
+               LONG(0x5a5aaa55)
+       }
+
+
+       . = ALIGN(16);
+       .bss            :
+       {
+               __bss_start = .;
+               *(.bss)
+               __bss_end = .;
+       }
+       . = ALIGN(16);
+       _end = .;
+
+       /DISCARD/ : { *(.note*) }
+
+       . = ASSERT(_end <= 0x8000, "Setup too big!");
+       . = ASSERT(hdr == 0x1f1, "The setup header has the wrong offset!");
+}
diff --git a/arch/i386/boot/string.c b/arch/i386/boot/string.c
new file mode 100644 (file)
index 0000000..481a220
--- /dev/null
@@ -0,0 +1,52 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/string.c
+ *
+ * Very basic string functions
+ */
+
+#include "boot.h"
+
+int strcmp(const char *str1, const char *str2)
+{
+       const unsigned char *s1 = (const unsigned char *)str1;
+       const unsigned char *s2 = (const unsigned char *)str2;
+       int delta = 0;
+
+       while (*s1 || *s2) {
+               delta = *s2 - *s1;
+               if (delta)
+                       return delta;
+               s1++;
+               s2++;
+       }
+       return 0;
+}
+
+size_t strnlen(const char *s, size_t maxlen)
+{
+       const char *es = s;
+       while (*es && maxlen) {
+               es++;
+               maxlen--;
+       }
+
+       return (es - s);
+}
+
+unsigned int atou(const char *s)
+{
+       unsigned int i = 0;
+       while (isdigit(*s))
+               i = i * 10 + (*s++ - '0');
+       return i;
+}
index 05798419a6a93f25be4f347d2eea5e6f04e5ddf6..886f47d8a48883a4c3154ab8ffa3ea77f94f9ad9 100644 (file)
@@ -1,13 +1,12 @@
 /*
  *  Copyright (C) 1991, 1992  Linus Torvalds
  *  Copyright (C) 1997 Martin Mares
+ *  Copyright (C) 2007 H. Peter Anvin
  */
 
 /*
  * This file builds a disk-image from three different files:
  *
- * - bootsect: compatibility mbr which prints an error message if
- *             someone tries to boot the kernel directly.
  * - setup: 8086 machine code, sets up system parm
  * - system: 80386 code for actual system
  *
@@ -21,6 +20,7 @@
  * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
  * Cross compiling fixes by Gertjan van Wingerde, July 1996
  * Rewritten by Martin Mares, April 1997
+ * Substantially overhauled by H. Peter Anvin, April 2007
  */
 
 #include <stdio.h>
 #include <sys/sysmacros.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include <sys/mman.h>
 #include <asm/boot.h>
 
-typedef unsigned char byte;
-typedef unsigned short word;
-typedef unsigned long u32;
+typedef unsigned char  u8;
+typedef unsigned short u16;
+typedef unsigned long  u32;
 
 #define DEFAULT_MAJOR_ROOT 0
 #define DEFAULT_MINOR_ROOT 0
 
-/* Minimal number of setup sectors (see also bootsect.S) */
-#define SETUP_SECTS 4
+/* Minimal number of setup sectors */
+#define SETUP_SECT_MIN 5
+#define SETUP_SECT_MAX 64
 
-byte buf[1024];
-int fd;
+/* This must be large enough to hold the entire setup */
+u8 buf[SETUP_SECT_MAX*512];
 int is_big_kernel;
 
-void die(const char * str, ...)
+static void die(const char * str, ...)
 {
        va_list args;
        va_start(args, str);
@@ -57,15 +59,9 @@ void die(const char * str, ...)
        exit(1);
 }
 
-void file_open(const char *name)
+static void usage(void)
 {
-       if ((fd = open(name, O_RDONLY, 0)) < 0)
-               die("Unable to open `%s': %m", name);
-}
-
-void usage(void)
-{
-       die("Usage: build [-b] bootsect setup system [rootdev] [> image]");
+       die("Usage: build [-b] setup system [rootdev] [> image]");
 }
 
 int main(int argc, char ** argv)
@@ -73,27 +69,30 @@ int main(int argc, char ** argv)
        unsigned int i, sz, setup_sectors;
        int c;
        u32 sys_size;
-       byte major_root, minor_root;
+       u8 major_root, minor_root;
        struct stat sb;
+       FILE *file;
+       int fd;
+       void *kernel;
 
        if (argc > 2 && !strcmp(argv[1], "-b"))
          {
            is_big_kernel = 1;
            argc--, argv++;
          }
-       if ((argc < 4) || (argc > 5))
+       if ((argc < 3) || (argc > 4))
                usage();
-       if (argc > 4) {
-               if (!strcmp(argv[4], "CURRENT")) {
+       if (argc > 3) {
+               if (!strcmp(argv[3], "CURRENT")) {
                        if (stat("/", &sb)) {
                                perror("/");
                                die("Couldn't stat /");
                        }
                        major_root = major(sb.st_dev);
                        minor_root = minor(sb.st_dev);
-               } else if (strcmp(argv[4], "FLOPPY")) {
-                       if (stat(argv[4], &sb)) {
-                               perror(argv[4]);
+               } else if (strcmp(argv[3], "FLOPPY")) {
+                       if (stat(argv[3], &sb)) {
+                               perror(argv[3]);
                                die("Couldn't stat root device.");
                        }
                        major_root = major(sb.st_rdev);
@@ -108,79 +107,62 @@ int main(int argc, char ** argv)
        }
        fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root);
 
-       file_open(argv[1]);
-       i = read(fd, buf, sizeof(buf));
-       fprintf(stderr,"Boot sector %d bytes.\n",i);
-       if (i != 512)
-               die("Boot block must be exactly 512 bytes");
+       /* Copy the setup code */
+       file = fopen(argv[1], "r");
+       if (!file)
+               die("Unable to open `%s': %m", argv[1]);
+       c = fread(buf, 1, sizeof(buf), file);
+       if (ferror(file))
+               die("read-error on `setup'");
+       if (c < 1024)
+               die("The setup must be at least 1024 bytes");
        if (buf[510] != 0x55 || buf[511] != 0xaa)
                die("Boot block hasn't got boot flag (0xAA55)");
+       fclose(file);
+
+       /* Pad unused space with zeros */
+       setup_sectors = (c + 511) / 512;
+       if (setup_sectors < SETUP_SECT_MIN)
+               setup_sectors = SETUP_SECT_MIN;
+       i = setup_sectors*512;
+       memset(buf+c, 0, i-c);
+
+       /* Set the default root device */
        buf[508] = minor_root;
        buf[509] = major_root;
-       if (write(1, buf, 512) != 512)
-               die("Write call failed");
-       close (fd);
-
-       file_open(argv[2]);                                 /* Copy the setup code */
-       for (i=0 ; (c=read(fd, buf, sizeof(buf)))>0 ; i+=c )
-               if (write(1, buf, c) != c)
-                       die("Write call failed");
-       if (c != 0)
-               die("read-error on `setup'");
-       close (fd);
-
-       setup_sectors = (i + 511) / 512;        /* Pad unused space with zeros */
-       /* for compatibility with ancient versions of LILO. */
-       if (setup_sectors < SETUP_SECTS)
-               setup_sectors = SETUP_SECTS;
-       fprintf(stderr, "Setup is %d bytes.\n", i);
-       memset(buf, 0, sizeof(buf));
-       while (i < setup_sectors * 512) {
-               c = setup_sectors * 512 - i;
-               if (c > sizeof(buf))
-                       c = sizeof(buf);
-               if (write(1, buf, c) != c)
-                       die("Write call failed");
-               i += c;
-       }
 
-       file_open(argv[3]);
-       if (fstat (fd, &sb))
-               die("Unable to stat `%s': %m", argv[3]);
+       fprintf(stderr, "Setup is %d bytes (padded to %d bytes).\n", c, i);
+
+       /* Open and stat the kernel file */
+       fd = open(argv[2], O_RDONLY);
+       if (fd < 0)
+               die("Unable to open `%s': %m", argv[2]);
+       if (fstat(fd, &sb))
+               die("Unable to stat `%s': %m", argv[2]);
        sz = sb.st_size;
-       fprintf (stderr, "System is %d kB\n", sz/1024);
+       fprintf (stderr, "System is %d kB\n", (sz+1023)/1024);
+       kernel = mmap(NULL, sz, PROT_READ, MAP_SHARED, fd, 0);
+       if (kernel == MAP_FAILED)
+               die("Unable to mmap '%s': %m", argv[2]);
        sys_size = (sz + 15) / 16;
        if (!is_big_kernel && sys_size > DEF_SYSSIZE)
                die("System is too big. Try using bzImage or modules.");
-       while (sz > 0) {
-               int l, n;
-
-               l = (sz > sizeof(buf)) ? sizeof(buf) : sz;
-               if ((n=read(fd, buf, l)) != l) {
-                       if (n < 0)
-                               die("Error reading %s: %m", argv[3]);
-                       else
-                               die("%s: Unexpected EOF", argv[3]);
-               }
-               if (write(1, buf, l) != l)
-                       die("Write failed");
-               sz -= l;
-       }
+
+       /* Patch the setup code with the appropriate size parameters */
+       buf[0x1f1] = setup_sectors-1;
+       buf[0x1f4] = sys_size;
+       buf[0x1f5] = sys_size >> 8;
+       buf[0x1f6] = sys_size >> 16;
+       buf[0x1f7] = sys_size >> 24;
+
+       if (fwrite(buf, 1, i, stdout) != i)
+               die("Writing setup failed");
+
+       /* Copy the kernel code */
+       if (fwrite(kernel, 1, sz, stdout) != sz)
+               die("Writing kernel failed");
        close(fd);
 
-       if (lseek(1, 497, SEEK_SET) != 497)                 /* Write sizes to the bootsector */
-               die("Output: seek failed");
-       buf[0] = setup_sectors;
-       if (write(1, buf, 1) != 1)
-               die("Write of setup sector count failed");
-       if (lseek(1, 500, SEEK_SET) != 500)
-               die("Output: seek failed");
-       buf[0] = (sys_size & 0xff);
-       buf[1] = ((sys_size >> 8) & 0xff);
-       buf[2] = ((sys_size >> 16) & 0xff);
-       buf[3] = ((sys_size >> 24) & 0xff);
-       if (write(1, buf, 4) != 4)
-               die("Write of image length failed");
-
-       return 0;                                           /* Everything is OK */
+       /* Everything is OK */
+       return 0;
 }
diff --git a/arch/i386/boot/tty.c b/arch/i386/boot/tty.c
new file mode 100644 (file)
index 0000000..a8db787
--- /dev/null
@@ -0,0 +1,112 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/tty.c
+ *
+ * Very simple screen I/O
+ * XXX: Probably should add very simple serial I/O?
+ */
+
+#include "boot.h"
+
+/*
+ * These functions are in .inittext so they can be used to signal
+ * error during initialization.
+ */
+
+void __attribute__((section(".inittext"))) putchar(int ch)
+{
+       unsigned char c = ch;
+
+       if (c == '\n')
+               putchar('\r');  /* \n -> \r\n */
+
+       /* int $0x10 is known to have bugs involving touching registers
+          it shouldn't.  Be extra conservative... */
+       asm volatile("pushal; int $0x10; popal"
+                    : : "b" (0x0007), "c" (0x0001), "a" (0x0e00|ch));
+}
+
+void __attribute__((section(".inittext"))) puts(const char *str)
+{
+       int n = 0;
+       while (*str) {
+               putchar(*str++);
+               n++;
+       }
+}
+
+/*
+ * Read the CMOS clock through the BIOS, and return the
+ * seconds in BCD.
+ */
+
+static u8 gettime(void)
+{
+       u16 ax = 0x0200;
+       u16 cx, dx;
+
+       asm("int $0x1a"
+           : "+a" (ax), "=c" (cx), "=d" (dx)
+           : : "ebx", "esi", "edi");
+
+       return dx >> 8;
+}
+
+/*
+ * Read from the keyboard
+ */
+int getchar(void)
+{
+       u16 ax = 0;
+       asm("int $0x16" : "+a" (ax));
+
+       return ax & 0xff;
+}
+
+static int kbd_pending(void)
+{
+       u8 pending;
+       asm("int $0x16; setnz %0"
+           : "=rm" (pending)
+           : "a" (0x0100));
+       return pending;
+}
+
+void kbd_flush(void)
+{
+       for (;;) {
+               if (!kbd_pending())
+                       break;
+               getchar();
+       }
+}
+
+int getchar_timeout(void)
+{
+       int cnt = 30;
+       int t0, t1;
+
+       t0 = gettime();
+
+       while (cnt) {
+               if (kbd_pending())
+                       return getchar();
+
+               t1 = gettime();
+               if (t0 != t1) {
+                       cnt--;
+                       t0 = t1;
+               }
+       }
+
+       return 0;               /* Timeout! */
+}
diff --git a/arch/i386/boot/version.c b/arch/i386/boot/version.c
new file mode 100644 (file)
index 0000000..c61462f
--- /dev/null
@@ -0,0 +1,23 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/version.c
+ *
+ * Kernel version string
+ */
+
+#include "boot.h"
+#include <linux/utsrelease.h>
+#include <linux/compile.h>
+
+const char kernel_version[] =
+       UTS_RELEASE " (" LINUX_COMPILE_BY "@" LINUX_COMPILE_HOST ") "
+       UTS_VERSION;
diff --git a/arch/i386/boot/vesa.h b/arch/i386/boot/vesa.h
new file mode 100644 (file)
index 0000000..ff5b73c
--- /dev/null
@@ -0,0 +1,79 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 1999-2007 H. Peter Anvin - All Rights Reserved
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
+ *   Boston MA 02111-1307, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef BOOT_VESA_H
+#define BOOT_VESA_H
+
+typedef struct {
+       u16 off, seg;
+} far_ptr;
+
+/* VESA General Information table */
+struct vesa_general_info {
+       u32 signature;          /* 0 Magic number = "VESA" */
+       u16 version;            /* 4 */
+       far_ptr vendor_string;  /* 6 */
+       u32 capabilities;       /* 10 */
+       far_ptr video_mode_ptr; /* 14 */
+       u16 total_memory;       /* 18 */
+
+       u16 oem_software_rev;   /* 20 */
+       far_ptr oem_vendor_name_ptr;    /* 22 */
+       far_ptr oem_product_name_ptr;   /* 26 */
+       far_ptr oem_product_rev_ptr;    /* 30 */
+
+       u8 reserved[222];       /* 34 */
+       u8 oem_data[256];       /* 256 */
+} __attribute__ ((packed));
+
+#define VESA_MAGIC ('V' + ('E' << 8) + ('S' << 16) + ('A' << 24))
+#define VBE2_MAGIC ('V' + ('B' << 8) + ('E' << 16) + ('2' << 24))
+
+struct vesa_mode_info {
+       u16 mode_attr;          /* 0 */
+       u8 win_attr[2];         /* 2 */
+       u16 win_grain;          /* 4 */
+       u16 win_size;           /* 6 */
+       u16 win_seg[2];         /* 8 */
+       far_ptr win_scheme;     /* 12 */
+       u16 logical_scan;       /* 16 */
+
+       u16 h_res;              /* 18 */
+       u16 v_res;              /* 20 */
+       u8 char_width;          /* 22 */
+       u8 char_height;         /* 23 */
+       u8 memory_planes;       /* 24 */
+       u8 bpp;                 /* 25 */
+       u8 banks;               /* 26 */
+       u8 memory_layout;       /* 27 */
+       u8 bank_size;           /* 28 */
+       u8 image_planes;        /* 29 */
+       u8 page_function;       /* 30 */
+
+       u8 rmask;               /* 31 */
+       u8 rpos;                /* 32 */
+       u8 gmask;               /* 33 */
+       u8 gpos;                /* 34 */
+       u8 bmask;               /* 35 */
+       u8 bpos;                /* 36 */
+       u8 resv_mask;           /* 37 */
+       u8 resv_pos;            /* 38 */
+       u8 dcm_info;            /* 39 */
+
+       u32 lfb_ptr;            /* 40 Linear frame buffer address */
+       u32 offscreen_ptr;      /* 44 Offscreen memory address */
+       u16 offscreen_size;     /* 48 */
+
+       u8 reserved[206];       /* 50 */
+} __attribute__ ((packed));
+
+#endif                         /* LIB_SYS_VESA_H */
diff --git a/arch/i386/boot/video-bios.c b/arch/i386/boot/video-bios.c
new file mode 100644 (file)
index 0000000..afea46c
--- /dev/null
@@ -0,0 +1,125 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/video-bios.c
+ *
+ * Standard video BIOS modes
+ *
+ * We have two options for this; silent and scanned.
+ */
+
+#include "boot.h"
+#include "video.h"
+
+__videocard video_bios;
+
+/* Set a conventional BIOS mode */
+static int set_bios_mode(u8 mode);
+
+static int bios_set_mode(struct mode_info *mi)
+{
+       return set_bios_mode(mi->mode - VIDEO_FIRST_BIOS);
+}
+
+static int set_bios_mode(u8 mode)
+{
+       u16 ax;
+       u8 new_mode;
+
+       ax = mode;              /* AH=0x00 Set Video Mode */
+       asm volatile(INT10
+                    : "+a" (ax)
+                    : : "ebx", "ecx", "edx", "esi", "edi");
+
+       ax = 0x0f00;            /* Get Current Video Mode */
+       asm volatile(INT10
+                    : "+a" (ax)
+                    : : "ebx", "ecx", "edx", "esi", "edi");
+
+       do_restore = 1;         /* Assume video contents was lost */
+       new_mode = ax & 0x7f;   /* Not all BIOSes are clean with the top bit */
+
+       if (new_mode == mode)
+               return 0;       /* Mode change OK */
+
+       if (new_mode != boot_params.screen_info.orig_video_mode) {
+               /* Mode setting failed, but we didn't end up where we
+                  started.  That's bad.  Try to revert to the original
+                  video mode. */
+               ax = boot_params.screen_info.orig_video_mode;
+               asm volatile(INT10
+                            : "+a" (ax)
+                            : : "ebx", "ecx", "edx", "esi", "edi");
+       }
+       return -1;
+}
+
+static int bios_probe(void)
+{
+       u8 mode;
+       u8 saved_mode = boot_params.screen_info.orig_video_mode;
+       u16 crtc;
+       struct mode_info *mi;
+       int nmodes = 0;
+
+       if (adapter != ADAPTER_EGA && adapter != ADAPTER_VGA)
+               return 0;
+
+       set_fs(0);
+       crtc = vga_crtc();
+
+       video_bios.modes = GET_HEAP(struct mode_info, 0);
+
+       for (mode = 0x14; mode <= 0x7f; mode++) {
+               if (heap_free() < sizeof(struct mode_info))
+                       break;
+
+               if (mode_defined(VIDEO_FIRST_BIOS+mode))
+                       continue;
+
+               if (set_bios_mode(mode))
+                       continue;
+
+               /* Try to verify that it's a text mode. */
+
+               /* Attribute Controller: make graphics controller disabled */
+               if (in_idx(0x3c0, 0x10) & 0x01)
+                       continue;
+
+               /* Graphics Controller: verify Alpha addressing enabled */
+               if (in_idx(0x3ce, 0x06) & 0x01)
+                       continue;
+
+               /* CRTC cursor location low should be zero(?) */
+               if (in_idx(crtc, 0x0f))
+                       continue;
+
+               mi = GET_HEAP(struct mode_info, 1);
+               mi->mode = VIDEO_FIRST_BIOS+mode;
+               mi->x = rdfs16(0x44a);
+               mi->y = rdfs8(0x484)+1;
+               nmodes++;
+       }
+
+       set_bios_mode(saved_mode);
+
+       return nmodes;
+}
+
+__videocard video_bios =
+{
+       .card_name      = "BIOS (scanned)",
+       .probe          = bios_probe,
+       .set_mode       = bios_set_mode,
+       .unsafe         = 1,
+       .xmode_first    = VIDEO_FIRST_BIOS,
+       .xmode_n        = 0x80,
+};
diff --git a/arch/i386/boot/video-vesa.c b/arch/i386/boot/video-vesa.c
new file mode 100644 (file)
index 0000000..e6aa9eb
--- /dev/null
@@ -0,0 +1,284 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/video-vesa.c
+ *
+ * VESA text modes
+ */
+
+#include "boot.h"
+#include "video.h"
+#include "vesa.h"
+
+/* VESA information */
+static struct vesa_general_info vginfo;
+static struct vesa_mode_info vminfo;
+
+__videocard video_vesa;
+
+static void vesa_store_mode_params_graphics(void);
+
+static int vesa_probe(void)
+{
+#if defined(CONFIG_VIDEO_VESA) || defined(CONFIG_FIRMWARE_EDID)
+       u16 ax;
+       u16 mode;
+       addr_t mode_ptr;
+       struct mode_info *mi;
+       int nmodes = 0;
+
+       video_vesa.modes = GET_HEAP(struct mode_info, 0);
+
+       vginfo.signature = VBE2_MAGIC;
+
+       /* Optimistically assume a VESA BIOS is register-clean... */
+       ax = 0x4f00;
+       asm("int $0x10" : "+a" (ax), "=m" (vginfo) : "D" (&vginfo));
+
+       if (ax != 0x004f ||
+           vginfo.signature != VESA_MAGIC ||
+           vginfo.version < 0x0102)
+               return 0;       /* Not present */
+#endif /* CONFIG_VIDEO_VESA || CONFIG_FIRMWARE_EDID */
+#ifdef CONFIG_VIDEO_VESA
+       set_fs(vginfo.video_mode_ptr.seg);
+       mode_ptr = vginfo.video_mode_ptr.off;
+
+       while ((mode = rdfs16(mode_ptr)) != 0xffff) {
+               mode_ptr += 2;
+
+               if (heap_free() < sizeof(struct mode_info))
+                       break;  /* Heap full, can't save mode info */
+
+               if (mode & ~0x1ff)
+                       continue;
+
+               memset(&vminfo, 0, sizeof vminfo); /* Just in case... */
+
+               ax = 0x4f01;
+               asm("int $0x10"
+                   : "+a" (ax), "=m" (vminfo)
+                   : "c" (mode), "D" (&vminfo));
+
+               if (ax != 0x004f)
+                       continue;
+
+               if ((vminfo.mode_attr & 0x15) == 0x05) {
+                       /* Text Mode, TTY BIOS supported,
+                          supported by hardware */
+                       mi = GET_HEAP(struct mode_info, 1);
+                       mi->mode = mode + VIDEO_FIRST_VESA;
+                       mi->x    = vminfo.h_res;
+                       mi->y    = vminfo.v_res;
+                       nmodes++;
+               } else if ((vminfo.mode_attr & 0x99) == 0x99) {
+#ifdef CONFIG_FB
+                       /* Graphics mode, color, linear frame buffer
+                          supported -- register the mode but hide from
+                          the menu.  Only do this if framebuffer is
+                          configured, however, otherwise the user will
+                          be left without a screen. */
+                       mi = GET_HEAP(struct mode_info, 1);
+                       mi->mode = mode + VIDEO_FIRST_VESA;
+                       mi->x = mi->y = 0;
+                       nmodes++;
+#endif
+               }
+       }
+
+       return nmodes;
+#else
+       return 0;
+#endif /* CONFIG_VIDEO_VESA */
+}
+
+static int vesa_set_mode(struct mode_info *mode)
+{
+       u16 ax;
+       int is_graphic;
+       u16 vesa_mode = mode->mode - VIDEO_FIRST_VESA;
+
+       memset(&vminfo, 0, sizeof vminfo); /* Just in case... */
+
+       ax = 0x4f01;
+       asm("int $0x10"
+           : "+a" (ax), "=m" (vminfo)
+           : "c" (vesa_mode), "D" (&vminfo));
+
+       if (ax != 0x004f)
+               return -1;
+
+       if ((vminfo.mode_attr & 0x15) == 0x05) {
+               /* It's a supported text mode */
+               is_graphic = 0;
+       } else if ((vminfo.mode_attr & 0x99) == 0x99) {
+               /* It's a graphics mode with linear frame buffer */
+               is_graphic = 1;
+               vesa_mode |= 0x4000; /* Request linear frame buffer */
+       } else {
+               return -1;      /* Invalid mode */
+       }
+
+
+       ax = 0x4f02;
+       asm volatile("int $0x10"
+                    : "+a" (ax)
+                    : "b" (vesa_mode), "D" (0));
+
+       if (ax != 0x004f)
+               return -1;
+
+       graphic_mode = is_graphic;
+       if (!is_graphic) {
+               /* Text mode */
+               force_x = mode->x;
+               force_y = mode->y;
+               do_restore = 1;
+       } else {
+               /* Graphics mode */
+               vesa_store_mode_params_graphics();
+       }
+
+       return 0;
+}
+
+
+/* Switch DAC to 8-bit mode */
+static void vesa_dac_set_8bits(void)
+{
+       u8 dac_size = 6;
+
+       /* If possible, switch the DAC to 8-bit mode */
+       if (vginfo.capabilities & 1) {
+               u16 ax, bx;
+
+               ax = 0x4f08;
+               bx = 0x0800;
+               asm volatile(INT10
+                            : "+a" (ax), "+b" (bx)
+                            : : "ecx", "edx", "esi", "edi");
+
+               if (ax == 0x004f)
+                       dac_size = bx >> 8;
+       }
+
+       /* Set the color sizes to the DAC size, and offsets to 0 */
+       boot_params.screen_info.red_size = dac_size;
+       boot_params.screen_info.green_size = dac_size;
+       boot_params.screen_info.blue_size = dac_size;
+       boot_params.screen_info.rsvd_size = dac_size;
+
+       boot_params.screen_info.red_pos = 0;
+       boot_params.screen_info.green_pos = 0;
+       boot_params.screen_info.blue_pos = 0;
+       boot_params.screen_info.rsvd_pos = 0;
+}
+
+/* Save the VESA protected mode info */
+static void vesa_store_pm_info(void)
+{
+       u16 ax, bx, di, es;
+
+       ax = 0x4f0a;
+       bx = di = 0;
+       asm("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
+           : "=d" (es), "+a" (ax), "+b" (bx), "+D" (di)
+           : : "ecx", "esi");
+
+       if (ax != 0x004f)
+               return;
+
+       boot_params.screen_info.vesapm_seg = es;
+       boot_params.screen_info.vesapm_off = di;
+}
+
+/*
+ * Save video mode parameters for graphics mode
+ */
+static void vesa_store_mode_params_graphics(void)
+{
+       /* Tell the kernel we're in VESA graphics mode */
+       boot_params.screen_info.orig_video_isVGA = 0x23;
+
+       /* Mode parameters */
+       boot_params.screen_info.vesa_attributes = vminfo.mode_attr;
+       boot_params.screen_info.lfb_linelength = vminfo.logical_scan;
+       boot_params.screen_info.lfb_width = vminfo.h_res;
+       boot_params.screen_info.lfb_height = vminfo.v_res;
+       boot_params.screen_info.lfb_depth = vminfo.bpp;
+       boot_params.screen_info.pages = vminfo.image_planes;
+       boot_params.screen_info.lfb_base = vminfo.lfb_ptr;
+       memcpy(&boot_params.screen_info.red_size,
+              &vminfo.rmask, 8);
+
+       /* General parameters */
+       boot_params.screen_info.lfb_size = vginfo.total_memory;
+
+       if (vminfo.bpp <= 8)
+               vesa_dac_set_8bits();
+
+       vesa_store_pm_info();
+}
+
+/*
+ * Save EDID information for the kernel; this is invoked, separately,
+ * after mode-setting.
+ */
+void vesa_store_edid(void)
+{
+#ifdef CONFIG_FIRMWARE_EDID
+       u16 ax, bx, cx, dx, di;
+
+       /* Apparently used as a nonsense token... */
+       memset(&boot_params.edid_info, 0x13, sizeof boot_params.edid_info);
+
+       if (vginfo.version < 0x0200)
+               return;         /* EDID requires VBE 2.0+ */
+
+       ax = 0x4f15;            /* VBE DDC */
+       bx = 0x0000;            /* Report DDC capabilities */
+       cx = 0;                 /* Controller 0 */
+       di = 0;                 /* ES:DI must be 0 by spec */
+
+       /* Note: The VBE DDC spec is different from the main VESA spec;
+          we genuinely have to assume all registers are destroyed here. */
+
+       asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
+           : "+a" (ax), "+b" (bx)
+           :  "c" (cx), "D" (di)
+           : "esi");
+
+       if (ax != 0x004f)
+               return;         /* No EDID */
+
+       /* BH = time in seconds to transfer EDD information */
+       /* BL = DDC level supported */
+
+       ax = 0x4f15;            /* VBE DDC */
+       bx = 0x0001;            /* Read EDID */
+       cx = 0;                 /* Controller 0 */
+       dx = 0;                 /* EDID block number */
+       di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */
+       asm(INT10
+           : "+a" (ax), "+b" (bx), "+d" (dx)
+           : "c" (cx), "D" (di)
+           : "esi");
+#endif /* CONFIG_FIRMWARE_EDID */
+}
+
+__videocard video_vesa =
+{
+       .card_name      = "VESA",
+       .probe          = vesa_probe,
+       .set_mode       = vesa_set_mode,
+       .xmode_first    = VIDEO_FIRST_VESA,
+       .xmode_n        = 0x200,
+};
diff --git a/arch/i386/boot/video-vga.c b/arch/i386/boot/video-vga.c
new file mode 100644 (file)
index 0000000..700d09a
--- /dev/null
@@ -0,0 +1,260 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/video-vga.c
+ *
+ * Common all-VGA modes
+ */
+
+#include "boot.h"
+#include "video.h"
+
+static struct mode_info vga_modes[] = {
+       { VIDEO_80x25,  80, 25 },
+       { VIDEO_8POINT, 80, 50 },
+       { VIDEO_80x43,  80, 43 },
+       { VIDEO_80x28,  80, 28 },
+       { VIDEO_80x30,  80, 30 },
+       { VIDEO_80x34,  80, 34 },
+       { VIDEO_80x60,  80, 60 },
+};
+
+static struct mode_info ega_modes[] = {
+       { VIDEO_80x25,  80, 25 },
+       { VIDEO_8POINT, 80, 43 },
+};
+
+static struct mode_info cga_modes[] = {
+       { VIDEO_80x25,  80, 25 },
+};
+
+__videocard video_vga;
+
+/* Set basic 80x25 mode */
+static u8 vga_set_basic_mode(void)
+{
+       u16 ax;
+       u8 rows;
+       u8 mode;
+
+#ifdef CONFIG_VIDEO_400_HACK
+       if (adapter >= ADAPTER_VGA) {
+               asm(INT10
+                   : : "a" (0x1202), "b" (0x0030)
+                   : "ecx", "edx", "esi", "edi");
+       }
+#endif
+
+       ax = 0x0f00;
+       asm(INT10
+           : "+a" (ax)
+           : : "ebx", "ecx", "edx", "esi", "edi");
+
+       mode = (u8)ax;
+
+       set_fs(0);
+       rows = rdfs8(0x484);    /* rows minus one */
+
+#ifndef CONFIG_VIDEO_400_HACK
+       if ((ax == 0x5003 || ax == 0x5007) &&
+           (rows == 0 || rows == 24))
+               return mode;
+#endif
+
+       if (mode != 3 && mode != 7)
+               mode = 3;
+
+       /* Set the mode */
+       asm volatile(INT10
+                    : : "a" (mode)
+                    : "ebx", "ecx", "edx", "esi", "edi");
+       do_restore = 1;
+       return mode;
+}
+
+static void vga_set_8font(void)
+{
+       /* Set 8x8 font - 80x43 on EGA, 80x50 on VGA */
+
+       /* Set 8x8 font */
+       asm volatile(INT10 : : "a" (0x1112), "b" (0));
+
+       /* Use alternate print screen */
+       asm volatile(INT10 : : "a" (0x1200), "b" (0x20));
+
+       /* Turn off cursor emulation */
+       asm volatile(INT10 : : "a" (0x1201), "b" (0x34));
+
+       /* Cursor is scan lines 6-7 */
+       asm volatile(INT10 : : "a" (0x0100), "c" (0x0607));
+}
+
+static void vga_set_14font(void)
+{
+       /* Set 9x14 font - 80x28 on VGA */
+
+       /* Set 9x14 font */
+       asm volatile(INT10 : : "a" (0x1111), "b" (0));
+
+       /* Turn off cursor emulation */
+       asm volatile(INT10 : : "a" (0x1201), "b" (0x34));
+
+       /* Cursor is scan lines 11-12 */
+       asm volatile(INT10 : : "a" (0x0100), "c" (0x0b0c));
+}
+
+static void vga_set_80x43(void)
+{
+       /* Set 80x43 mode on VGA (not EGA) */
+
+       /* Set 350 scans */
+       asm volatile(INT10 : : "a" (0x1201), "b" (0x30));
+
+       /* Reset video mode */
+       asm volatile(INT10 : : "a" (0x0003));
+
+       vga_set_8font();
+}
+
+/* I/O address of the VGA CRTC */
+u16 vga_crtc(void)
+{
+       return (inb(0x3cc) & 1) ? 0x3d4 : 0x3b4;
+}
+
+static void vga_set_480_scanlines(int end)
+{
+       u16 crtc;
+       u8  csel;
+
+       crtc = vga_crtc();
+
+       out_idx(0x0c, crtc, 0x11); /* Vertical sync end, unlock CR0-7 */
+       out_idx(0x0b, crtc, 0x06); /* Vertical total */
+       out_idx(0x3e, crtc, 0x07); /* Vertical overflow */
+       out_idx(0xea, crtc, 0x10); /* Vertical sync start */
+       out_idx(end, crtc, 0x12); /* Vertical display end */
+       out_idx(0xe7, crtc, 0x15); /* Vertical blank start */
+       out_idx(0x04, crtc, 0x16); /* Vertical blank end */
+       csel = inb(0x3cc);
+       csel &= 0x0d;
+       csel |= 0xe2;
+       outb(csel, 0x3cc);
+}
+
+static void vga_set_80x30(void)
+{
+       vga_set_480_scanlines(0xdf);
+}
+
+static void vga_set_80x34(void)
+{
+       vga_set_14font();
+       vga_set_480_scanlines(0xdb);
+}
+
+static void vga_set_80x60(void)
+{
+       vga_set_8font();
+       vga_set_480_scanlines(0xdf);
+}
+
+static int vga_set_mode(struct mode_info *mode)
+{
+       /* Set the basic mode */
+       vga_set_basic_mode();
+
+       /* Override a possibly broken BIOS */
+       force_x = mode->x;
+       force_y = mode->y;
+
+       switch (mode->mode) {
+       case VIDEO_80x25:
+               break;
+       case VIDEO_8POINT:
+               vga_set_8font();
+               break;
+       case VIDEO_80x43:
+               vga_set_80x43();
+               break;
+       case VIDEO_80x28:
+               vga_set_14font();
+               break;
+       case VIDEO_80x30:
+               vga_set_80x30();
+               break;
+       case VIDEO_80x34:
+               vga_set_80x34();
+               break;
+       case VIDEO_80x60:
+               vga_set_80x60();
+               break;
+       }
+
+       return 0;
+}
+
+/*
+ * Note: this probe includes basic information required by all
+ * systems.  It should be executed first, by making sure
+ * video-vga.c is listed first in the Makefile.
+ */
+static int vga_probe(void)
+{
+       static const char *card_name[] = {
+               "CGA/MDA/HGC", "EGA", "VGA"
+       };
+       static struct mode_info *mode_lists[] = {
+               cga_modes,
+               ega_modes,
+               vga_modes,
+       };
+       static int mode_count[] = {
+               sizeof(cga_modes)/sizeof(struct mode_info),
+               sizeof(ega_modes)/sizeof(struct mode_info),
+               sizeof(vga_modes)/sizeof(struct mode_info),
+       };
+       u8 vga_flag;
+
+       asm(INT10
+           : "=b" (boot_params.screen_info.orig_video_ega_bx)
+           : "a" (0x1200), "b" (0x10) /* Check EGA/VGA */
+           : "ecx", "edx", "esi", "edi");
+
+       /* If we have MDA/CGA/HGC then BL will be unchanged at 0x10 */
+       if ((u8)boot_params.screen_info.orig_video_ega_bx != 0x10) {
+               /* EGA/VGA */
+               asm(INT10
+                   : "=a" (vga_flag)
+                   : "a" (0x1a00)
+                   : "ebx", "ecx", "edx", "esi", "edi");
+
+               if (vga_flag == 0x1a) {
+                       adapter = ADAPTER_VGA;
+                       boot_params.screen_info.orig_video_isVGA = 1;
+               } else {
+                       adapter = ADAPTER_EGA;
+               }
+       } else {
+               adapter = ADAPTER_CGA;
+       }
+
+       video_vga.modes = mode_lists[adapter];
+       video_vga.card_name = card_name[adapter];
+       return mode_count[adapter];
+}
+
+__videocard video_vga =
+{
+       .card_name      = "VGA",
+       .probe          = vga_probe,
+       .set_mode       = vga_set_mode,
+};
diff --git a/arch/i386/boot/video.S b/arch/i386/boot/video.S
deleted file mode 100644 (file)
index 8143c95..0000000
+++ /dev/null
@@ -1,2043 +0,0 @@
-/*     video.S
- *
- *     Display adapter & video mode setup, version 2.13 (14-May-99)
- *
- *     Copyright (C) 1995 -- 1998 Martin Mares <mj@ucw.cz>
- *     Based on the original setup.S code (C) Linus Torvalds and Mats Anderson
- *
- *     Rewritten to use GNU 'as' by Chris Noe <stiker@northlink.com> May 1999
- *
- *     For further information, look at Documentation/svga.txt.
- *
- */
-
-/* Enable autodetection of SVGA adapters and modes. */
-#undef CONFIG_VIDEO_SVGA
-
-/* Enable autodetection of VESA modes */
-#define CONFIG_VIDEO_VESA
-
-/* Enable compacting of mode table */
-#define CONFIG_VIDEO_COMPACT
-
-/* Retain screen contents when switching modes */
-#define CONFIG_VIDEO_RETAIN
-
-/* Enable local mode list */
-#undef CONFIG_VIDEO_LOCAL
-
-/* Force 400 scan lines for standard modes (hack to fix bad BIOS behaviour */
-#undef CONFIG_VIDEO_400_HACK
-
-/* Hack that lets you force specific BIOS mode ID and specific dimensions */
-#undef CONFIG_VIDEO_GFX_HACK
-#define VIDEO_GFX_BIOS_AX 0x4f02       /* 800x600 on ThinkPad */
-#define VIDEO_GFX_BIOS_BX 0x0102
-#define VIDEO_GFX_DUMMY_RESOLUTION 0x6425      /* 100x37 */
-
-/* This code uses an extended set of video mode numbers. These include:
- * Aliases for standard modes
- *     NORMAL_VGA (-1)
- *     EXTENDED_VGA (-2)
- *     ASK_VGA (-3)
- * Video modes numbered by menu position -- NOT RECOMMENDED because of lack
- * of compatibility when extending the table. These are between 0x00 and 0xff.
- */
-#define VIDEO_FIRST_MENU 0x0000
-
-/* Standard BIOS video modes (BIOS number + 0x0100) */
-#define VIDEO_FIRST_BIOS 0x0100
-
-/* VESA BIOS video modes (VESA number + 0x0200) */
-#define VIDEO_FIRST_VESA 0x0200
-
-/* Video7 special modes (BIOS number + 0x0900) */
-#define VIDEO_FIRST_V7 0x0900
-
-/* Special video modes */
-#define VIDEO_FIRST_SPECIAL 0x0f00
-#define VIDEO_80x25 0x0f00
-#define VIDEO_8POINT 0x0f01
-#define VIDEO_80x43 0x0f02
-#define VIDEO_80x28 0x0f03
-#define VIDEO_CURRENT_MODE 0x0f04
-#define VIDEO_80x30 0x0f05
-#define VIDEO_80x34 0x0f06
-#define VIDEO_80x60 0x0f07
-#define VIDEO_GFX_HACK 0x0f08
-#define VIDEO_LAST_SPECIAL 0x0f09
-
-/* Video modes given by resolution */
-#define VIDEO_FIRST_RESOLUTION 0x1000
-
-/* The "recalculate timings" flag */
-#define VIDEO_RECALC 0x8000
-
-/* Positions of various video parameters passed to the kernel */
-/* (see also include/linux/tty.h) */
-#define PARAM_CURSOR_POS       0x00
-#define PARAM_VIDEO_PAGE       0x04
-#define PARAM_VIDEO_MODE       0x06
-#define PARAM_VIDEO_COLS       0x07
-#define PARAM_VIDEO_EGA_BX     0x0a
-#define PARAM_VIDEO_LINES      0x0e
-#define PARAM_HAVE_VGA         0x0f
-#define PARAM_FONT_POINTS      0x10
-
-#define PARAM_LFB_WIDTH                0x12
-#define PARAM_LFB_HEIGHT       0x14
-#define PARAM_LFB_DEPTH                0x16
-#define PARAM_LFB_BASE         0x18
-#define PARAM_LFB_SIZE         0x1c
-#define PARAM_LFB_LINELENGTH   0x24
-#define PARAM_LFB_COLORS       0x26
-#define PARAM_VESAPM_SEG       0x2e
-#define PARAM_VESAPM_OFF       0x30
-#define PARAM_LFB_PAGES                0x32
-#define PARAM_VESA_ATTRIB      0x34
-#define PARAM_CAPABILITIES     0x36
-
-/* Define DO_STORE according to CONFIG_VIDEO_RETAIN */
-#ifdef CONFIG_VIDEO_RETAIN
-#define DO_STORE call store_screen
-#else
-#define DO_STORE
-#endif /* CONFIG_VIDEO_RETAIN */
-
-# This is the main entry point called by setup.S
-# %ds *must* be pointing to the bootsector
-video: pushw   %ds             # We use different segments
-       pushw   %ds             # FS contains original DS
-       popw    %fs
-       pushw   %cs             # DS is equal to CS
-       popw    %ds
-       pushw   %cs             # ES is equal to CS
-       popw    %es
-       xorw    %ax, %ax
-       movw    %ax, %gs        # GS is zero
-       cld
-       call    basic_detect    # Basic adapter type testing (EGA/VGA/MDA/CGA)
-#ifdef CONFIG_VIDEO_SELECT
-       movw    %fs:(0x01fa), %ax               # User selected video mode
-       cmpw    $ASK_VGA, %ax                   # Bring up the menu
-       jz      vid2
-
-       call    mode_set                        # Set the mode
-       jc      vid1
-
-       leaw    badmdt, %si                     # Invalid mode ID
-       call    prtstr
-vid2:  call    mode_menu
-vid1:
-#ifdef CONFIG_VIDEO_RETAIN
-       call    restore_screen                  # Restore screen contents
-#endif /* CONFIG_VIDEO_RETAIN */
-       call    store_edid
-#endif /* CONFIG_VIDEO_SELECT */
-       call    mode_params                     # Store mode parameters
-       popw    %ds                             # Restore original DS
-       ret
-
-# Detect if we have CGA, MDA, EGA or VGA and pass it to the kernel.
-basic_detect:
-       movb    $0, %fs:(PARAM_HAVE_VGA)
-       movb    $0x12, %ah      # Check EGA/VGA
-       movb    $0x10, %bl
-       int     $0x10
-       movw    %bx, %fs:(PARAM_VIDEO_EGA_BX)   # Identifies EGA to the kernel
-       cmpb    $0x10, %bl                      # No, it's a CGA/MDA/HGA card.
-       je      basret
-
-       incb    adapter
-       movw    $0x1a00, %ax                    # Check EGA or VGA?
-       int     $0x10
-       cmpb    $0x1a, %al                      # 1a means VGA...
-       jne     basret                          # anything else is EGA.
-       
-       incb    %fs:(PARAM_HAVE_VGA)            # We've detected a VGA
-       incb    adapter
-basret:        ret
-
-# Store the video mode parameters for later usage by the kernel.
-# This is done by asking the BIOS except for the rows/columns
-# parameters in the default 80x25 mode -- these are set directly,
-# because some very obscure BIOSes supply insane values.
-mode_params:
-#ifdef CONFIG_VIDEO_SELECT
-       cmpb    $0, graphic_mode
-       jnz     mopar_gr
-#endif
-       movb    $0x03, %ah                      # Read cursor position
-       xorb    %bh, %bh
-       int     $0x10
-       movw    %dx, %fs:(PARAM_CURSOR_POS)
-       movb    $0x0f, %ah                      # Read page/mode/width
-       int     $0x10
-       movw    %bx, %fs:(PARAM_VIDEO_PAGE)
-       movw    %ax, %fs:(PARAM_VIDEO_MODE)     # Video mode and screen width
-       cmpb    $0x7, %al                       # MDA/HGA => segment differs
-       jnz     mopar0
-
-       movw    $0xb000, video_segment
-mopar0: movw   %gs:(0x485), %ax                # Font size
-       movw    %ax, %fs:(PARAM_FONT_POINTS)    # (valid only on EGA/VGA)
-       movw    force_size, %ax                 # Forced size?
-       orw     %ax, %ax
-       jz      mopar1
-
-       movb    %ah, %fs:(PARAM_VIDEO_COLS)
-       movb    %al, %fs:(PARAM_VIDEO_LINES)
-       ret
-
-mopar1:        movb    $25, %al
-       cmpb    $0, adapter                     # If we are on CGA/MDA/HGA, the
-       jz      mopar2                          # screen must have 25 lines.
-
-       movb    %gs:(0x484), %al                # On EGA/VGA, use the EGA+ BIOS
-       incb    %al                             # location of max lines.
-mopar2: movb   %al, %fs:(PARAM_VIDEO_LINES)
-       ret
-
-#ifdef CONFIG_VIDEO_SELECT
-# Fetching of VESA frame buffer parameters
-mopar_gr:
-       leaw    modelist+1024, %di
-       movb    $0x23, %fs:(PARAM_HAVE_VGA)
-       movw    16(%di), %ax
-       movw    %ax, %fs:(PARAM_LFB_LINELENGTH)
-       movw    18(%di), %ax
-       movw    %ax, %fs:(PARAM_LFB_WIDTH)
-       movw    20(%di), %ax
-       movw    %ax, %fs:(PARAM_LFB_HEIGHT)
-       movb    25(%di), %al
-       movb    $0, %ah
-       movw    %ax, %fs:(PARAM_LFB_DEPTH)
-       movb    29(%di), %al    
-       movb    $0, %ah
-       movw    %ax, %fs:(PARAM_LFB_PAGES)
-       movl    40(%di), %eax
-       movl    %eax, %fs:(PARAM_LFB_BASE)
-       movl    31(%di), %eax
-       movl    %eax, %fs:(PARAM_LFB_COLORS)
-       movl    35(%di), %eax
-       movl    %eax, %fs:(PARAM_LFB_COLORS+4)
-       movw    0(%di), %ax
-       movw    %ax, %fs:(PARAM_VESA_ATTRIB)
-
-# get video mem size
-       leaw    modelist+1024, %di
-       movw    $0x4f00, %ax
-       int     $0x10
-       xorl    %eax, %eax
-       movw    18(%di), %ax
-       movl    %eax, %fs:(PARAM_LFB_SIZE)
-
-# store mode capabilities
-       movl 10(%di), %eax
-       movl %eax, %fs:(PARAM_CAPABILITIES)
-
-# switching the DAC to 8-bit is for <= 8 bpp only
-       movw    %fs:(PARAM_LFB_DEPTH), %ax
-       cmpw    $8, %ax
-       jg      dac_done
-
-# get DAC switching capability
-       xorl    %eax, %eax
-       movb    10(%di), %al
-       testb   $1, %al
-       jz      dac_set
-
-# attempt to switch DAC to 8-bit
-       movw    $0x4f08, %ax
-       movw    $0x0800, %bx
-       int     $0x10
-       cmpw    $0x004f, %ax
-       jne     dac_set
-       movb    %bh, dac_size           # store actual DAC size
-
-dac_set:
-# set color size to DAC size
-       movb    dac_size, %al
-       movb    %al, %fs:(PARAM_LFB_COLORS+0)
-       movb    %al, %fs:(PARAM_LFB_COLORS+2)
-       movb    %al, %fs:(PARAM_LFB_COLORS+4)
-       movb    %al, %fs:(PARAM_LFB_COLORS+6)
-
-# set color offsets to 0
-       movb    $0, %fs:(PARAM_LFB_COLORS+1)
-       movb    $0, %fs:(PARAM_LFB_COLORS+3)
-       movb    $0, %fs:(PARAM_LFB_COLORS+5)
-       movb    $0, %fs:(PARAM_LFB_COLORS+7)
-
-dac_done:
-# get protected mode interface informations
-       movw    $0x4f0a, %ax
-       xorw    %bx, %bx
-       xorw    %di, %di
-       int     $0x10
-       cmp     $0x004f, %ax
-       jnz     no_pm
-
-       movw    %es, %fs:(PARAM_VESAPM_SEG)
-       movw    %di, %fs:(PARAM_VESAPM_OFF)
-no_pm: ret
-
-# The video mode menu
-mode_menu:
-       leaw    keymsg, %si                     # "Return/Space/Timeout" message
-       call    prtstr
-       call    flush
-nokey: call    getkt
-
-       cmpb    $0x0d, %al                      # ENTER ?
-       je      listm                           # yes - manual mode selection
-
-       cmpb    $0x20, %al                      # SPACE ?
-       je      defmd1                          # no - repeat
-
-       call    beep
-       jmp     nokey
-
-defmd1:        ret                                     # No mode chosen? Default 80x25
-
-listm: call    mode_table                      # List mode table
-listm0:        leaw    name_bann, %si                  # Print adapter name
-       call    prtstr
-       movw    card_name, %si
-       orw     %si, %si
-       jnz     an2
-
-       movb    adapter, %al
-       leaw    old_name, %si
-       orb     %al, %al
-       jz      an1
-
-       leaw    ega_name, %si
-       decb    %al
-       jz      an1
-
-       leaw    vga_name, %si
-       jmp     an1
-
-an2:   call    prtstr
-       leaw    svga_name, %si
-an1:   call    prtstr
-       leaw    listhdr, %si                    # Table header
-       call    prtstr
-       movb    $0x30, %dl                      # DL holds mode number
-       leaw    modelist, %si
-lm1:   cmpw    $ASK_VGA, (%si)                 # End?
-       jz      lm2
-
-       movb    %dl, %al                        # Menu selection number
-       call    prtchr
-       call    prtsp2
-       lodsw
-       call    prthw                           # Mode ID
-       call    prtsp2
-       movb    0x1(%si), %al
-       call    prtdec                          # Rows
-       movb    $0x78, %al                      # the letter 'x'
-       call    prtchr
-       lodsw
-       call    prtdec                          # Columns
-       movb    $0x0d, %al                      # New line
-       call    prtchr
-       movb    $0x0a, %al
-       call    prtchr
-       incb    %dl                             # Next character
-       cmpb    $0x3a, %dl
-       jnz     lm1
-
-       movb    $0x61, %dl
-       jmp     lm1
-
-lm2:   leaw    prompt, %si                     # Mode prompt
-       call    prtstr
-       leaw    edit_buf, %di                   # Editor buffer
-lm3:   call    getkey
-       cmpb    $0x0d, %al                      # Enter?
-       jz      lment
-
-       cmpb    $0x08, %al                      # Backspace?
-       jz      lmbs
-
-       cmpb    $0x20, %al                      # Printable?
-       jc      lm3
-
-       cmpw    $edit_buf+4, %di                # Enough space?
-       jz      lm3
-
-       stosb
-       call    prtchr
-       jmp     lm3
-
-lmbs:  cmpw    $edit_buf, %di                  # Backspace
-       jz      lm3
-
-       decw    %di
-       movb    $0x08, %al
-       call    prtchr
-       call    prtspc
-       movb    $0x08, %al
-       call    prtchr
-       jmp     lm3
-       
-lment: movb    $0, (%di)
-       leaw    crlft, %si
-       call    prtstr
-       leaw    edit_buf, %si
-       cmpb    $0, (%si)                       # Empty string = default mode
-       jz      lmdef
-
-       cmpb    $0, 1(%si)                      # One character = menu selection
-       jz      mnusel
-
-       cmpw    $0x6373, (%si)                  # "scan" => mode scanning
-       jnz     lmhx
-
-       cmpw    $0x6e61, 2(%si)
-       jz      lmscan
-
-lmhx:  xorw    %bx, %bx                        # Else => mode ID in hex
-lmhex: lodsb
-       orb     %al, %al
-       jz      lmuse1
-
-       subb    $0x30, %al
-       jc      lmbad
-
-       cmpb    $10, %al
-       jc      lmhx1
-
-       subb    $7, %al
-       andb    $0xdf, %al
-       cmpb    $10, %al
-       jc      lmbad
-
-       cmpb    $16, %al
-       jnc     lmbad
-
-lmhx1: shlw    $4, %bx
-       orb     %al, %bl
-       jmp     lmhex
-
-lmuse1:        movw    %bx, %ax
-       jmp     lmuse
-
-mnusel:        lodsb                                   # Menu selection
-       xorb    %ah, %ah
-       subb    $0x30, %al
-       jc      lmbad
-
-       cmpb    $10, %al
-       jc      lmuse
-       
-       cmpb    $0x61-0x30, %al
-       jc      lmbad
-       
-       subb    $0x61-0x30-10, %al
-       cmpb    $36, %al
-       jnc     lmbad
-
-lmuse: call    mode_set
-       jc      lmdef
-
-lmbad: leaw    unknt, %si
-       call    prtstr
-       jmp     lm2
-lmscan:        cmpb    $0, adapter                     # Scanning only on EGA/VGA
-       jz      lmbad
-
-       movw    $0, mt_end                      # Scanning of modes is
-       movb    $1, scanning                    # done as new autodetection.
-       call    mode_table
-       jmp     listm0
-lmdef: ret
-
-# Additional parts of mode_set... (relative jumps, you know)
-setv7:                                         # Video7 extended modes
-       DO_STORE
-       subb    $VIDEO_FIRST_V7>>8, %bh
-       movw    $0x6f05, %ax
-       int     $0x10
-       stc
-       ret
-
-_setrec:       jmp     setrec                  # Ugly...
-_set_80x25:    jmp     set_80x25
-
-# Aliases for backward compatibility.
-setalias:
-       movw    $VIDEO_80x25, %ax
-       incw    %bx
-       jz      mode_set
-
-       movb    $VIDEO_8POINT-VIDEO_FIRST_SPECIAL, %al
-       incw    %bx
-       jnz     setbad                          # Fall-through!
-
-# Setting of user mode (AX=mode ID) => CF=success
-mode_set:
-       movw    %ax, %fs:(0x01fa)               # Store mode for use in acpi_wakeup.S
-       movw    %ax, %bx
-       cmpb    $0xff, %ah
-       jz      setalias
-
-       testb   $VIDEO_RECALC>>8, %ah
-       jnz     _setrec
-
-       cmpb    $VIDEO_FIRST_RESOLUTION>>8, %ah
-       jnc     setres
-       
-       cmpb    $VIDEO_FIRST_SPECIAL>>8, %ah
-       jz      setspc
-       
-       cmpb    $VIDEO_FIRST_V7>>8, %ah
-       jz      setv7
-       
-       cmpb    $VIDEO_FIRST_VESA>>8, %ah
-       jnc     check_vesa
-       
-       orb     %ah, %ah
-       jz      setmenu
-       
-       decb    %ah
-       jz      setbios
-
-setbad:        clc
-       movb    $0, do_restore                  # The screen needn't be restored
-       ret
-
-setvesa:
-       DO_STORE
-       subb    $VIDEO_FIRST_VESA>>8, %bh
-       movw    $0x4f02, %ax                    # VESA BIOS mode set call
-       int     $0x10
-       cmpw    $0x004f, %ax                    # AL=4f if implemented
-       jnz     setbad                          # AH=0 if OK
-
-       stc
-       ret
-
-setbios:
-       DO_STORE
-       int     $0x10                           # Standard BIOS mode set call
-       pushw   %bx
-       movb    $0x0f, %ah                      # Check if really set
-       int     $0x10
-       popw    %bx
-       cmpb    %bl, %al
-       jnz     setbad
-       
-       stc
-       ret
-
-setspc:        xorb    %bh, %bh                        # Set special mode
-       cmpb    $VIDEO_LAST_SPECIAL-VIDEO_FIRST_SPECIAL, %bl
-       jnc     setbad
-       
-       addw    %bx, %bx
-       jmp     *spec_inits(%bx)
-
-setmenu:
-       orb     %al, %al                        # 80x25 is an exception
-       jz      _set_80x25
-       
-       pushw   %bx                             # Set mode chosen from menu
-       call    mode_table                      # Build the mode table
-       popw    %ax
-       shlw    $2, %ax
-       addw    %ax, %si
-       cmpw    %di, %si
-       jnc     setbad
-       
-       movw    (%si), %ax                      # Fetch mode ID
-_m_s:  jmp     mode_set
-
-setres:        pushw   %bx                             # Set mode chosen by resolution
-       call    mode_table
-       popw    %bx
-       xchgb   %bl, %bh
-setr1: lodsw
-       cmpw    $ASK_VGA, %ax                   # End of the list?
-       jz      setbad
-       
-       lodsw
-       cmpw    %bx, %ax
-       jnz     setr1
-       
-       movw    -4(%si), %ax                    # Fetch mode ID
-       jmp     _m_s
-
-check_vesa:
-#ifdef CONFIG_FIRMWARE_EDID
-       leaw    modelist+1024, %di
-       movw    $0x4f00, %ax
-       int     $0x10
-       cmpw    $0x004f, %ax
-       jnz     setbad
-
-       movw    4(%di), %ax
-       movw    %ax, vbe_version
-#endif
-       leaw    modelist+1024, %di
-       subb    $VIDEO_FIRST_VESA>>8, %bh
-       movw    %bx, %cx                        # Get mode information structure
-       movw    $0x4f01, %ax
-       int     $0x10
-       addb    $VIDEO_FIRST_VESA>>8, %bh
-       cmpw    $0x004f, %ax
-       jnz     setbad
-
-       movb    (%di), %al                      # Check capabilities.
-       andb    $0x19, %al
-       cmpb    $0x09, %al
-       jz      setvesa                         # This is a text mode
-
-       movb    (%di), %al                      # Check capabilities.
-       andb    $0x99, %al
-       cmpb    $0x99, %al
-       jnz     _setbad                         # Doh! No linear frame buffer.
-
-       subb    $VIDEO_FIRST_VESA>>8, %bh
-       orw     $0x4000, %bx                    # Use linear frame buffer
-       movw    $0x4f02, %ax                    # VESA BIOS mode set call
-       int     $0x10
-       cmpw    $0x004f, %ax                    # AL=4f if implemented
-       jnz     _setbad                         # AH=0 if OK
-
-       movb    $1, graphic_mode                # flag graphic mode
-       movb    $0, do_restore                  # no screen restore
-       stc
-       ret
-
-_setbad:       jmp     setbad                  # Ugly...
-
-# Recalculate vertical display end registers -- this fixes various
-# inconsistencies of extended modes on many adapters. Called when
-# the VIDEO_RECALC flag is set in the mode ID.
-
-setrec:        subb    $VIDEO_RECALC>>8, %ah           # Set the base mode
-       call    mode_set
-       jnc     rct3
-
-       movw    %gs:(0x485), %ax                # Font size in pixels
-       movb    %gs:(0x484), %bl                # Number of rows
-       incb    %bl
-       mulb    %bl                             # Number of visible
-       decw    %ax                             # scan lines - 1
-       movw    $0x3d4, %dx
-       movw    %ax, %bx
-       movb    $0x12, %al                      # Lower 8 bits
-       movb    %bl, %ah
-       outw    %ax, %dx
-       movb    $0x07, %al              # Bits 8 and 9 in the overflow register
-       call    inidx
-       xchgb   %al, %ah
-       andb    $0xbd, %ah
-       shrb    %bh
-       jnc     rct1
-       orb     $0x02, %ah
-rct1:  shrb    %bh
-       jnc     rct2
-       orb     $0x40, %ah
-rct2:  movb    $0x07, %al
-       outw    %ax, %dx
-       stc
-rct3:  ret
-
-# Table of routines for setting of the special modes.
-spec_inits:
-       .word   set_80x25
-       .word   set_8pixel
-       .word   set_80x43
-       .word   set_80x28
-       .word   set_current
-       .word   set_80x30
-       .word   set_80x34
-       .word   set_80x60
-       .word   set_gfx
-
-# Set the 80x25 mode. If already set, do nothing.
-set_80x25:
-       movw    $0x5019, force_size             # Override possibly broken BIOS
-use_80x25:
-#ifdef CONFIG_VIDEO_400_HACK
-       movw    $0x1202, %ax                    # Force 400 scan lines
-       movb    $0x30, %bl
-       int     $0x10
-#else
-       movb    $0x0f, %ah                      # Get current mode ID
-       int     $0x10
-       cmpw    $0x5007, %ax    # Mode 7 (80x25 mono) is the only one available
-       jz      st80            # on CGA/MDA/HGA and is also available on EGAM
-
-       cmpw    $0x5003, %ax    # Unknown mode, force 80x25 color
-       jnz     force3
-
-st80:  cmpb    $0, adapter     # CGA/MDA/HGA => mode 3/7 is always 80x25
-       jz      set80
-
-       movb    %gs:(0x0484), %al       # This is EGA+ -- beware of 80x50 etc.
-       orb     %al, %al                # Some buggy BIOS'es set 0 rows
-       jz      set80
-       
-       cmpb    $24, %al                # It's hopefully correct
-       jz      set80
-#endif /* CONFIG_VIDEO_400_HACK */
-force3:        DO_STORE
-       movw    $0x0003, %ax                    # Forced set
-       int     $0x10
-set80: stc
-       ret
-
-# Set the 80x50/80x43 8-pixel mode. Simple BIOS calls.
-set_8pixel:
-       DO_STORE
-       call    use_80x25                       # The base is 80x25
-set_8pt:
-       movw    $0x1112, %ax                    # Use 8x8 font
-       xorb    %bl, %bl
-       int     $0x10
-       movw    $0x1200, %ax                    # Use alternate print screen
-       movb    $0x20, %bl
-       int     $0x10
-       movw    $0x1201, %ax                    # Turn off cursor emulation
-       movb    $0x34, %bl
-       int     $0x10
-       movb    $0x01, %ah                      # Define cursor scan lines 6-7
-       movw    $0x0607, %cx
-       int     $0x10
-set_current:
-       stc
-       ret
-
-# Set the 80x28 mode. This mode works on all VGA's, because it's a standard
-# 80x25 mode with 14-point fonts instead of 16-point.
-set_80x28:
-       DO_STORE
-       call    use_80x25                       # The base is 80x25
-set14: movw    $0x1111, %ax                    # Use 9x14 font
-       xorb    %bl, %bl
-       int     $0x10
-       movb    $0x01, %ah                      # Define cursor scan lines 11-12
-       movw    $0x0b0c, %cx
-       int     $0x10
-       stc
-       ret
-
-# Set the 80x43 mode. This mode is works on all VGA's.
-# It's a 350-scanline mode with 8-pixel font.
-set_80x43:
-       DO_STORE
-       movw    $0x1201, %ax                    # Set 350 scans
-       movb    $0x30, %bl
-       int     $0x10
-       movw    $0x0003, %ax                    # Reset video mode
-       int     $0x10
-       jmp     set_8pt                         # Use 8-pixel font
-
-# Set the 80x30 mode (all VGA's). 480 scanlines, 16-pixel font.
-set_80x30:
-       call    use_80x25                       # Start with real 80x25
-       DO_STORE
-       movw    $0x3cc, %dx                     # Get CRTC port
-       inb     %dx, %al
-       movb    $0xd4, %dl
-       rorb    %al                             # Mono or color?
-       jc      set48a
-
-       movb    $0xb4, %dl
-set48a:        movw    $0x0c11, %ax            # Vertical sync end (also unlocks CR0-7)
-       call    outidx
-       movw    $0x0b06, %ax                    # Vertical total
-       call    outidx
-       movw    $0x3e07, %ax                    # (Vertical) overflow
-       call    outidx
-       movw    $0xea10, %ax                    # Vertical sync start
-       call    outidx
-       movw    $0xdf12, %ax                    # Vertical display end
-       call    outidx
-       movw    $0xe715, %ax                    # Vertical blank start
-       call    outidx
-       movw    $0x0416, %ax                    # Vertical blank end
-       call    outidx
-       pushw   %dx
-       movb    $0xcc, %dl                      # Misc output register (read)
-       inb     %dx, %al
-       movb    $0xc2, %dl                      # (write)
-       andb    $0x0d, %al      # Preserve clock select bits and color bit
-       orb     $0xe2, %al                      # Set correct sync polarity
-       outb    %al, %dx
-       popw    %dx
-       movw    $0x501e, force_size
-       stc                                     # That's all.
-       ret
-
-# Set the 80x34 mode (all VGA's). 480 scans, 14-pixel font.
-set_80x34:
-       call    set_80x30                       # Set 480 scans
-       call    set14                           # And 14-pt font
-       movw    $0xdb12, %ax                    # VGA vertical display end
-       movw    $0x5022, force_size
-setvde:        call    outidx
-       stc
-       ret
-
-# Set the 80x60 mode (all VGA's). 480 scans, 8-pixel font.
-set_80x60:
-       call    set_80x30                       # Set 480 scans
-       call    set_8pt                         # And 8-pt font
-       movw    $0xdf12, %ax                    # VGA vertical display end
-       movw    $0x503c, force_size
-       jmp     setvde
-
-# Special hack for ThinkPad graphics
-set_gfx:
-#ifdef CONFIG_VIDEO_GFX_HACK
-       movw    $VIDEO_GFX_BIOS_AX, %ax
-       movw    $VIDEO_GFX_BIOS_BX, %bx
-       int     $0x10
-       movw    $VIDEO_GFX_DUMMY_RESOLUTION, force_size
-       stc
-#endif
-       ret
-
-#ifdef CONFIG_VIDEO_RETAIN
-
-# Store screen contents to temporary buffer.
-store_screen:
-       cmpb    $0, do_restore                  # Already stored?
-       jnz     stsr
-
-       testb   $CAN_USE_HEAP, loadflags        # Have we space for storing?
-       jz      stsr
-       
-       pushw   %ax
-       pushw   %bx
-       pushw   force_size                      # Don't force specific size
-       movw    $0, force_size
-       call    mode_params                     # Obtain params of current mode
-       popw    force_size
-       movb    %fs:(PARAM_VIDEO_LINES), %ah
-       movb    %fs:(PARAM_VIDEO_COLS), %al
-       movw    %ax, %bx                        # BX=dimensions
-       mulb    %ah
-       movw    %ax, %cx                        # CX=number of characters
-       addw    %ax, %ax                        # Calculate image size
-       addw    $modelist+1024+4, %ax
-       cmpw    heap_end_ptr, %ax
-       jnc     sts1                            # Unfortunately, out of memory
-
-       movw    %fs:(PARAM_CURSOR_POS), %ax     # Store mode params
-       leaw    modelist+1024, %di
-       stosw
-       movw    %bx, %ax
-       stosw
-       pushw   %ds                             # Store the screen
-       movw    video_segment, %ds
-       xorw    %si, %si
-       rep
-       movsw
-       popw    %ds
-       incb    do_restore                      # Screen will be restored later
-sts1:  popw    %bx
-       popw    %ax
-stsr:  ret
-
-# Restore screen contents from temporary buffer.
-restore_screen:
-       cmpb    $0, do_restore                  # Has the screen been stored?
-       jz      res1
-
-       call    mode_params                     # Get parameters of current mode
-       movb    %fs:(PARAM_VIDEO_LINES), %cl
-       movb    %fs:(PARAM_VIDEO_COLS), %ch
-       leaw    modelist+1024, %si              # Screen buffer
-       lodsw                                   # Set cursor position
-       movw    %ax, %dx
-       cmpb    %cl, %dh
-       jc      res2
-       
-       movb    %cl, %dh
-       decb    %dh
-res2:  cmpb    %ch, %dl
-       jc      res3
-       
-       movb    %ch, %dl
-       decb    %dl
-res3:  movb    $0x02, %ah
-       movb    $0x00, %bh
-       int     $0x10
-       lodsw                                   # Display size
-       movb    %ah, %dl                        # DL=number of lines
-       movb    $0, %ah                         # BX=phys. length of orig. line
-       movw    %ax, %bx
-       cmpb    %cl, %dl                        # Too many?
-       jc      res4
-
-       pushw   %ax
-       movb    %dl, %al
-       subb    %cl, %al
-       mulb    %bl
-       addw    %ax, %si
-       addw    %ax, %si
-       popw    %ax
-       movb    %cl, %dl
-res4:  cmpb    %ch, %al                        # Too wide?
-       jc      res5
-       
-       movb    %ch, %al                        # AX=width of src. line
-res5:  movb    $0, %cl
-       xchgb   %ch, %cl
-       movw    %cx, %bp                        # BP=width of dest. line
-       pushw   %es
-       movw    video_segment, %es
-       xorw    %di, %di                        # Move the data
-       addw    %bx, %bx                        # Convert BX and BP to _bytes_
-       addw    %bp, %bp
-res6:  pushw   %si
-       pushw   %di
-       movw    %ax, %cx
-       rep
-       movsw
-       popw    %di
-       popw    %si
-       addw    %bp, %di
-       addw    %bx, %si
-       decb    %dl
-       jnz     res6
-       
-       popw    %es                             # Done
-res1:  ret
-#endif /* CONFIG_VIDEO_RETAIN */
-
-# Write to indexed VGA register (AL=index, AH=data, DX=index reg. port)
-outidx:        outb    %al, %dx
-       pushw   %ax
-       movb    %ah, %al
-       incw    %dx
-       outb    %al, %dx
-       decw    %dx
-       popw    %ax
-       ret
-
-# Build the table of video modes (stored after the setup.S code at the
-# `modelist' label. Each video mode record looks like:
-#      .word   MODE-ID         (our special mode ID (see above))
-#      .byte   rows            (number of rows)
-#      .byte   columns         (number of columns)
-# Returns address of the end of the table in DI, the end is marked
-# with a ASK_VGA ID.
-mode_table:
-       movw    mt_end, %di                     # Already filled?
-       orw     %di, %di
-       jnz     mtab1x
-       
-       leaw    modelist, %di                   # Store standard modes:
-       movl    $VIDEO_80x25 + 0x50190000, %eax # The 80x25 mode (ALL)
-       stosl
-       movb    adapter, %al                    # CGA/MDA/HGA -- no more modes
-       orb     %al, %al
-       jz      mtabe
-       
-       decb    %al
-       jnz     mtabv
-       
-       movl    $VIDEO_8POINT + 0x502b0000, %eax        # The 80x43 EGA mode
-       stosl
-       jmp     mtabe
-
-mtab1x:        jmp     mtab1
-
-mtabv: leaw    vga_modes, %si                  # All modes for std VGA
-       movw    $vga_modes_end-vga_modes, %cx
-       rep     # I'm unable to use movsw as I don't know how to store a half
-       movsb   # of the expression above to cx without using explicit shr.
-
-       cmpb    $0, scanning                    # Mode scan requested?
-       jz      mscan1
-       
-       call    mode_scan
-mscan1:
-
-#ifdef CONFIG_VIDEO_LOCAL
-       call    local_modes
-#endif /* CONFIG_VIDEO_LOCAL */
-
-#ifdef CONFIG_VIDEO_VESA
-       call    vesa_modes                      # Detect VESA VGA modes
-#endif /* CONFIG_VIDEO_VESA */
-
-#ifdef CONFIG_VIDEO_SVGA
-       cmpb    $0, scanning                    # Bypass when scanning
-       jnz     mscan2
-       
-       call    svga_modes                      # Detect SVGA cards & modes
-mscan2:
-#endif /* CONFIG_VIDEO_SVGA */
-
-mtabe:
-
-#ifdef CONFIG_VIDEO_COMPACT
-       leaw    modelist, %si
-       movw    %di, %dx
-       movw    %si, %di
-cmt1:  cmpw    %dx, %si                        # Scan all modes
-       jz      cmt2
-
-       leaw    modelist, %bx                   # Find in previous entries
-       movw    2(%si), %cx
-cmt3:  cmpw    %bx, %si
-       jz      cmt4
-
-       cmpw    2(%bx), %cx                     # Found => don't copy this entry
-       jz      cmt5
-
-       addw    $4, %bx
-       jmp     cmt3
-
-cmt4:  movsl                                   # Copy entry
-       jmp     cmt1
-
-cmt5:  addw    $4, %si                         # Skip entry
-       jmp     cmt1
-
-cmt2:
-#endif /* CONFIG_VIDEO_COMPACT */
-
-       movw    $ASK_VGA, (%di)                 # End marker
-       movw    %di, mt_end
-mtab1: leaw    modelist, %si                   # SI=mode list, DI=list end
-ret0:  ret
-
-# Modes usable on all standard VGAs
-vga_modes:
-       .word   VIDEO_8POINT
-       .word   0x5032                          # 80x50
-       .word   VIDEO_80x43
-       .word   0x502b                          # 80x43
-       .word   VIDEO_80x28
-       .word   0x501c                          # 80x28
-       .word   VIDEO_80x30
-       .word   0x501e                          # 80x30
-       .word   VIDEO_80x34
-       .word   0x5022                          # 80x34
-       .word   VIDEO_80x60
-       .word   0x503c                          # 80x60
-#ifdef CONFIG_VIDEO_GFX_HACK
-       .word   VIDEO_GFX_HACK
-       .word   VIDEO_GFX_DUMMY_RESOLUTION
-#endif
-
-vga_modes_end:
-# Detect VESA modes.
-
-#ifdef CONFIG_VIDEO_VESA
-vesa_modes:
-       cmpb    $2, adapter                     # VGA only
-       jnz     ret0
-
-       movw    %di, %bp                        # BP=original mode table end
-       addw    $0x200, %di                     # Buffer space
-       movw    $0x4f00, %ax                    # VESA Get card info call
-       int     $0x10
-       movw    %bp, %di
-       cmpw    $0x004f, %ax                    # Successful?
-       jnz     ret0
-       
-       cmpw    $0x4556, 0x200(%di)
-       jnz     ret0
-       
-       cmpw    $0x4153, 0x202(%di)
-       jnz     ret0
-       
-       movw    $vesa_name, card_name           # Set name to "VESA VGA"
-       pushw   %gs
-       lgsw    0x20e(%di), %si                 # GS:SI=mode list
-       movw    $128, %cx                       # Iteration limit
-vesa1:
-# gas version 2.9.1, using BFD version 2.9.1.0.23 buggers the next inst.
-# XXX: lodsw   %gs:(%si), %ax                  # Get next mode in the list
-       gs; lodsw
-       cmpw    $0xffff, %ax                    # End of the table?
-       jz      vesar
-       
-       cmpw    $0x0080, %ax                    # Check validity of mode ID
-       jc      vesa2
-       
-       orb     %ah, %ah                # Valid IDs: 0x0000-0x007f/0x0100-0x07ff
-       jz      vesan                   # Certain BIOSes report 0x80-0xff!
-
-       cmpw    $0x0800, %ax
-       jnc     vesae
-
-vesa2: pushw   %cx
-       movw    %ax, %cx                        # Get mode information structure
-       movw    $0x4f01, %ax
-       int     $0x10
-       movw    %cx, %bx                        # BX=mode number
-       addb    $VIDEO_FIRST_VESA>>8, %bh
-       popw    %cx
-       cmpw    $0x004f, %ax
-       jnz     vesan                   # Don't report errors (buggy BIOSES)
-
-       movb    (%di), %al                      # Check capabilities. We require
-       andb    $0x19, %al                      # a color text mode.
-       cmpb    $0x09, %al
-       jnz     vesan
-       
-       cmpw    $0xb800, 8(%di)         # Standard video memory address required
-       jnz     vesan
-
-       testb   $2, (%di)                       # Mode characteristics supplied?
-       movw    %bx, (%di)                      # Store mode number
-       jz      vesa3
-       
-       xorw    %dx, %dx
-       movw    0x12(%di), %bx                  # Width
-       orb     %bh, %bh
-       jnz     vesan
-       
-       movb    %bl, 0x3(%di)
-       movw    0x14(%di), %ax                  # Height
-       orb     %ah, %ah
-       jnz     vesan
-       
-       movb    %al, 2(%di)
-       mulb    %bl
-       cmpw    $8193, %ax              # Small enough for Linux console driver?
-       jnc     vesan
-
-       jmp     vesaok
-
-vesa3: subw    $0x8108, %bx    # This mode has no detailed info specified,
-       jc      vesan           # so it must be a standard VESA mode.
-
-       cmpw    $5, %bx
-       jnc     vesan
-
-       movw    vesa_text_mode_table(%bx), %ax
-       movw    %ax, 2(%di)
-vesaok:        addw    $4, %di                         # The mode is valid. Store it.
-vesan: loop    vesa1                   # Next mode. Limit exceeded => error
-vesae: leaw    vesaer, %si
-       call    prtstr
-       movw    %bp, %di                        # Discard already found modes.
-vesar: popw    %gs
-       ret
-
-# Dimensions of standard VESA text modes
-vesa_text_mode_table:
-       .byte   60, 80                          # 0108
-       .byte   25, 132                         # 0109
-       .byte   43, 132                         # 010A
-       .byte   50, 132                         # 010B
-       .byte   60, 132                         # 010C
-#endif /* CONFIG_VIDEO_VESA */
-
-# Scan for video modes. A bit dirty, but should work.
-mode_scan:
-       movw    $0x0100, %cx                    # Start with mode 0
-scm1:  movb    $0, %ah                         # Test the mode
-       movb    %cl, %al
-       int     $0x10
-       movb    $0x0f, %ah
-       int     $0x10
-       cmpb    %cl, %al
-       jnz     scm2                            # Mode not set
-
-       movw    $0x3c0, %dx                     # Test if it's a text mode
-       movb    $0x10, %al                      # Mode bits
-       call    inidx
-       andb    $0x03, %al
-       jnz     scm2
-       
-       movb    $0xce, %dl                      # Another set of mode bits
-       movb    $0x06, %al
-       call    inidx
-       shrb    %al
-       jc      scm2
-       
-       movb    $0xd4, %dl                      # Cursor location
-       movb    $0x0f, %al
-       call    inidx
-       orb     %al, %al
-       jnz     scm2
-       
-       movw    %cx, %ax                        # Ok, store the mode
-       stosw
-       movb    %gs:(0x484), %al                # Number of rows
-       incb    %al
-       stosb
-       movw    %gs:(0x44a), %ax                # Number of columns
-       stosb
-scm2:  incb    %cl
-       jns     scm1
-       
-       movw    $0x0003, %ax                    # Return back to mode 3
-       int     $0x10
-       ret
-
-tstidx:        outw    %ax, %dx                        # OUT DX,AX and inidx
-inidx: outb    %al, %dx                        # Read from indexed VGA register
-       incw    %dx                     # AL=index, DX=index reg port -> AL=data
-       inb     %dx, %al
-       decw    %dx
-       ret
-
-# Try to detect type of SVGA card and supply (usually approximate) video
-# mode table for it.
-
-#ifdef CONFIG_VIDEO_SVGA
-svga_modes:
-       leaw    svga_table, %si                 # Test all known SVGA adapters
-dosvga:        lodsw
-       movw    %ax, %bp                        # Default mode table
-       orw     %ax, %ax
-       jz      didsv1
-
-       lodsw                                   # Pointer to test routine
-       pushw   %si
-       pushw   %di
-       pushw   %es
-       movw    $0xc000, %bx
-       movw    %bx, %es
-       call    *%ax                            # Call test routine
-       popw    %es
-       popw    %di
-       popw    %si
-       orw     %bp, %bp
-       jz      dosvga
-       
-       movw    %bp, %si                        # Found, copy the modes
-       movb    svga_prefix, %ah
-cpsvga:        lodsb
-       orb     %al, %al
-       jz      didsv
-       
-       stosw
-       movsw
-       jmp     cpsvga
-
-didsv: movw    %si, card_name                  # Store pointer to card name
-didsv1:        ret
-
-# Table of all known SVGA cards. For each card, we store a pointer to
-# a table of video modes supported by the card and a pointer to a routine
-# used for testing of presence of the card. The video mode table is always
-# followed by the name of the card or the chipset.
-svga_table:
-       .word   ati_md, ati_test
-       .word   oak_md, oak_test
-       .word   paradise_md, paradise_test
-       .word   realtek_md, realtek_test
-       .word   s3_md, s3_test
-       .word   chips_md, chips_test
-       .word   video7_md, video7_test
-       .word   cirrus5_md, cirrus5_test
-       .word   cirrus6_md, cirrus6_test
-       .word   cirrus1_md, cirrus1_test
-       .word   ahead_md, ahead_test
-       .word   everex_md, everex_test
-       .word   genoa_md, genoa_test
-       .word   trident_md, trident_test
-       .word   tseng_md, tseng_test
-       .word   0
-
-# Test routines and mode tables:
-
-# S3 - The test algorithm was taken from the SuperProbe package
-# for XFree86 1.2.1. Report bugs to Christoph.Niemann@linux.org
-s3_test:
-       movw    $0x0f35, %cx    # we store some constants in cl/ch
-       movw    $0x03d4, %dx
-       movb    $0x38, %al
-       call    inidx
-       movb    %al, %bh        # store current CRT-register 0x38
-       movw    $0x0038, %ax
-       call    outidx          # disable writing to special regs
-       movb    %cl, %al        # check whether we can write special reg 0x35
-       call    inidx
-       movb    %al, %bl        # save the current value of CRT reg 0x35
-       andb    $0xf0, %al      # clear bits 0-3
-       movb    %al, %ah
-       movb    %cl, %al        # and write it to CRT reg 0x35
-       call    outidx
-       call    inidx           # now read it back
-       andb    %ch, %al        # clear the upper 4 bits
-       jz      s3_2            # the first test failed. But we have a
-
-       movb    %bl, %ah        # second chance
-       movb    %cl, %al
-       call    outidx
-       jmp     s3_1            # do the other tests
-
-s3_2:  movw    %cx, %ax        # load ah with 0xf and al with 0x35
-       orb     %bl, %ah        # set the upper 4 bits of ah with the orig value
-       call    outidx          # write ...
-       call    inidx           # ... and reread 
-       andb    %cl, %al        # turn off the upper 4 bits
-       pushw   %ax
-       movb    %bl, %ah        # restore old value in register 0x35
-       movb    %cl, %al
-       call    outidx
-       popw    %ax
-       cmpb    %ch, %al        # setting lower 4 bits was successful => bad
-       je      no_s3           # writing is allowed => this is not an S3
-
-s3_1:  movw    $0x4838, %ax    # allow writing to special regs by putting
-       call    outidx          # magic number into CRT-register 0x38
-       movb    %cl, %al        # check whether we can write special reg 0x35
-       call    inidx
-       movb    %al, %bl
-       andb    $0xf0, %al
-       movb    %al, %ah
-       movb    %cl, %al
-       call    outidx
-       call    inidx
-       andb    %ch, %al
-       jnz     no_s3           # no, we can't write => no S3
-
-       movw    %cx, %ax
-       orb     %bl, %ah
-       call    outidx
-       call    inidx
-       andb    %ch, %al
-       pushw   %ax
-       movb    %bl, %ah        # restore old value in register 0x35
-       movb    %cl, %al
-       call    outidx
-       popw    %ax
-       cmpb    %ch, %al
-       jne     no_s31          # writing not possible => no S3
-       movb    $0x30, %al
-       call    inidx           # now get the S3 id ...
-       leaw    idS3, %di
-       movw    $0x10, %cx
-       repne
-       scasb
-       je      no_s31
-
-       movb    %bh, %ah
-       movb    $0x38, %al
-       jmp     s3rest
-
-no_s3: movb    $0x35, %al      # restore CRT register 0x35
-       movb    %bl, %ah
-       call    outidx
-no_s31:        xorw    %bp, %bp        # Detection failed
-s3rest:        movb    %bh, %ah
-       movb    $0x38, %al      # restore old value of CRT register 0x38
-       jmp     outidx
-
-idS3:  .byte   0x81, 0x82, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95
-       .byte   0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa8, 0xb0
-
-s3_md: .byte   0x54, 0x2b, 0x84
-       .byte   0x55, 0x19, 0x84
-       .byte   0
-       .ascii  "S3"
-       .byte   0
-
-# ATI cards.
-ati_test:
-       leaw    idati, %si
-       movw    $0x31, %di
-       movw    $0x09, %cx
-       repe
-       cmpsb
-       je      atiok
-
-       xorw    %bp, %bp
-atiok: ret
-
-idati: .ascii  "761295520"
-
-ati_md:        .byte   0x23, 0x19, 0x84
-       .byte   0x33, 0x2c, 0x84
-       .byte   0x22, 0x1e, 0x64
-       .byte   0x21, 0x19, 0x64
-       .byte   0x58, 0x21, 0x50
-       .byte   0x5b, 0x1e, 0x50
-       .byte   0
-       .ascii  "ATI"
-       .byte   0
-
-# AHEAD
-ahead_test:
-       movw    $0x200f, %ax
-       movw    $0x3ce, %dx
-       outw    %ax, %dx
-       incw    %dx
-       inb     %dx, %al
-       cmpb    $0x20, %al
-       je      isahed
-
-       cmpb    $0x21, %al
-       je      isahed
-       
-       xorw    %bp, %bp
-isahed:        ret
-
-ahead_md:
-       .byte   0x22, 0x2c, 0x84
-       .byte   0x23, 0x19, 0x84
-       .byte   0x24, 0x1c, 0x84
-       .byte   0x2f, 0x32, 0xa0
-       .byte   0x32, 0x22, 0x50
-       .byte   0x34, 0x42, 0x50
-       .byte   0
-       .ascii  "Ahead"
-       .byte   0
-
-# Chips & Tech.
-chips_test:
-       movw    $0x3c3, %dx
-       inb     %dx, %al
-       orb     $0x10, %al
-       outb    %al, %dx
-       movw    $0x104, %dx
-       inb     %dx, %al
-       movb    %al, %bl
-       movw    $0x3c3, %dx
-       inb     %dx, %al
-       andb    $0xef, %al
-       outb    %al, %dx
-       cmpb    $0xa5, %bl
-       je      cantok
-       
-       xorw    %bp, %bp
-cantok:        ret
-
-chips_md:
-       .byte   0x60, 0x19, 0x84
-       .byte   0x61, 0x32, 0x84
-       .byte   0
-       .ascii  "Chips & Technologies"
-       .byte   0
-
-# Cirrus Logic 5X0
-cirrus1_test:
-       movw    $0x3d4, %dx
-       movb    $0x0c, %al
-       outb    %al, %dx
-       incw    %dx
-       inb     %dx, %al
-       movb    %al, %bl
-       xorb    %al, %al
-       outb    %al, %dx
-       decw    %dx
-       movb    $0x1f, %al
-       outb    %al, %dx
-       incw    %dx
-       inb     %dx, %al
-       movb    %al, %bh
-       xorb    %ah, %ah
-       shlb    $4, %al
-       movw    %ax, %cx
-       movb    %bh, %al
-       shrb    $4, %al
-       addw    %ax, %cx
-       shlw    $8, %cx
-       addw    $6, %cx
-       movw    %cx, %ax
-       movw    $0x3c4, %dx
-       outw    %ax, %dx
-       incw    %dx
-       inb     %dx, %al
-       andb    %al, %al
-       jnz     nocirr
-       
-       movb    %bh, %al
-       outb    %al, %dx
-       inb     %dx, %al
-       cmpb    $0x01, %al
-       je      iscirr
-
-nocirr:        xorw    %bp, %bp
-iscirr: movw   $0x3d4, %dx
-       movb    %bl, %al
-       xorb    %ah, %ah
-       shlw    $8, %ax
-       addw    $0x0c, %ax
-       outw    %ax, %dx
-       ret
-
-cirrus1_md:
-       .byte   0x1f, 0x19, 0x84
-       .byte   0x20, 0x2c, 0x84
-       .byte   0x22, 0x1e, 0x84
-       .byte   0x31, 0x25, 0x64
-       .byte   0
-       .ascii  "Cirrus Logic 5X0"
-       .byte   0
-
-# Cirrus Logic 54XX
-cirrus5_test:
-       movw    $0x3c4, %dx
-       movb    $6, %al
-       call    inidx
-       movb    %al, %bl                        # BL=backup
-       movw    $6, %ax
-       call    tstidx
-       cmpb    $0x0f, %al
-       jne     c5fail
-       
-       movw    $0x1206, %ax
-       call    tstidx
-       cmpb    $0x12, %al
-       jne     c5fail
-       
-       movb    $0x1e, %al
-       call    inidx
-       movb    %al, %bh
-       movb    %bh, %ah
-       andb    $0xc0, %ah
-       movb    $0x1e, %al
-       call    tstidx
-       andb    $0x3f, %al
-       jne     c5xx
-       
-       movb    $0x1e, %al
-       movb    %bh, %ah
-       orb     $0x3f, %ah
-       call    tstidx
-       xorb    $0x3f, %al
-       andb    $0x3f, %al
-c5xx:  pushf
-       movb    $0x1e, %al
-       movb    %bh, %ah
-       outw    %ax, %dx
-       popf
-       je      c5done
-
-c5fail:        xorw    %bp, %bp
-c5done:        movb    $6, %al
-       movb    %bl, %ah
-       outw    %ax, %dx
-       ret
-
-cirrus5_md:
-       .byte   0x14, 0x19, 0x84
-       .byte   0x54, 0x2b, 0x84
-       .byte   0
-       .ascii  "Cirrus Logic 54XX"
-       .byte   0
-
-# Cirrus Logic 64XX -- no known extra modes, but must be identified, because
-# it's misidentified by the Ahead test.
-cirrus6_test:
-       movw    $0x3ce, %dx
-       movb    $0x0a, %al
-       call    inidx
-       movb    %al, %bl        # BL=backup
-       movw    $0xce0a, %ax
-       call    tstidx
-       orb     %al, %al
-       jne     c2fail
-       
-       movw    $0xec0a, %ax
-       call    tstidx
-       cmpb    $0x01, %al
-       jne     c2fail
-       
-       movb    $0xaa, %al
-       call    inidx           # 4X, 5X, 7X and 8X are valid 64XX chip ID's. 
-       shrb    $4, %al
-       subb    $4, %al
-       jz      c6done
-       
-       decb    %al
-       jz      c6done
-       
-       subb    $2, %al
-       jz      c6done
-       
-       decb    %al
-       jz      c6done
-       
-c2fail:        xorw    %bp, %bp
-c6done:        movb    $0x0a, %al
-       movb    %bl, %ah
-       outw    %ax, %dx
-       ret
-
-cirrus6_md:
-       .byte   0
-       .ascii  "Cirrus Logic 64XX"
-       .byte   0
-
-# Everex / Trident
-everex_test:
-       movw    $0x7000, %ax
-       xorw    %bx, %bx
-       int     $0x10
-       cmpb    $0x70, %al
-       jne     noevrx
-       
-       shrw    $4, %dx
-       cmpw    $0x678, %dx
-       je      evtrid
-       
-       cmpw    $0x236, %dx
-       jne     evrxok
-
-evtrid:        leaw    trident_md, %bp
-evrxok:        ret
-
-noevrx:        xorw    %bp, %bp
-       ret
-
-everex_md:
-       .byte   0x03, 0x22, 0x50
-       .byte   0x04, 0x3c, 0x50
-       .byte   0x07, 0x2b, 0x64
-       .byte   0x08, 0x4b, 0x64
-       .byte   0x0a, 0x19, 0x84
-       .byte   0x0b, 0x2c, 0x84
-       .byte   0x16, 0x1e, 0x50
-       .byte   0x18, 0x1b, 0x64
-       .byte   0x21, 0x40, 0xa0
-       .byte   0x40, 0x1e, 0x84
-       .byte   0
-       .ascii  "Everex/Trident"
-       .byte   0
-
-# Genoa.
-genoa_test:
-       leaw    idgenoa, %si                    # Check Genoa 'clues'
-       xorw    %ax, %ax
-       movb    %es:(0x37), %al
-       movw    %ax, %di
-       movw    $0x04, %cx
-       decw    %si
-       decw    %di
-l1:    incw    %si
-       incw    %di
-       movb    (%si), %al
-       testb   %al, %al
-       jz      l2
-
-       cmpb    %es:(%di), %al
-l2:    loope   l1
-       orw     %cx, %cx
-       je      isgen
-       
-       xorw    %bp, %bp
-isgen: ret
-
-idgenoa: .byte 0x77, 0x00, 0x99, 0x66
-
-genoa_md:
-       .byte   0x58, 0x20, 0x50
-       .byte   0x5a, 0x2a, 0x64
-       .byte   0x60, 0x19, 0x84
-       .byte   0x61, 0x1d, 0x84
-       .byte   0x62, 0x20, 0x84
-       .byte   0x63, 0x2c, 0x84
-       .byte   0x64, 0x3c, 0x84
-       .byte   0x6b, 0x4f, 0x64
-       .byte   0x72, 0x3c, 0x50
-       .byte   0x74, 0x42, 0x50
-       .byte   0x78, 0x4b, 0x64
-       .byte   0
-       .ascii  "Genoa"
-       .byte   0
-
-# OAK
-oak_test:
-       leaw    idoakvga, %si
-       movw    $0x08, %di
-       movw    $0x08, %cx
-       repe
-       cmpsb
-       je      isoak
-       
-       xorw    %bp, %bp
-isoak: ret
-
-idoakvga: .ascii  "OAK VGA "
-
-oak_md: .byte  0x4e, 0x3c, 0x50
-       .byte   0x4f, 0x3c, 0x84
-       .byte   0x50, 0x19, 0x84
-       .byte   0x51, 0x2b, 0x84
-       .byte   0
-       .ascii  "OAK"
-       .byte   0
-
-# WD Paradise.
-paradise_test:
-       leaw    idparadise, %si
-       movw    $0x7d, %di
-       movw    $0x04, %cx
-       repe
-       cmpsb
-       je      ispara
-       
-       xorw    %bp, %bp
-ispara:        ret
-
-idparadise:    .ascii  "VGA="
-
-paradise_md:
-       .byte   0x41, 0x22, 0x50
-       .byte   0x47, 0x1c, 0x84
-       .byte   0x55, 0x19, 0x84
-       .byte   0x54, 0x2c, 0x84
-       .byte   0
-       .ascii  "Paradise"
-       .byte   0
-
-# Trident.
-trident_test:
-       movw    $0x3c4, %dx
-       movb    $0x0e, %al
-       outb    %al, %dx
-       incw    %dx
-       inb     %dx, %al
-       xchgb   %al, %ah
-       xorb    %al, %al
-       outb    %al, %dx
-       inb     %dx, %al
-       xchgb   %ah, %al
-       movb    %al, %bl        # Strange thing ... in the book this wasn't
-       andb    $0x02, %bl      # necessary but it worked on my card which
-       jz      setb2           # is a trident. Without it the screen goes
-                               # blurred ...
-       andb    $0xfd, %al
-       jmp     clrb2           
-
-setb2: orb     $0x02, %al      
-clrb2: outb    %al, %dx
-       andb    $0x0f, %ah
-       cmpb    $0x02, %ah
-       je      istrid
-
-       xorw    %bp, %bp
-istrid:        ret
-
-trident_md:
-       .byte   0x50, 0x1e, 0x50
-       .byte   0x51, 0x2b, 0x50
-       .byte   0x52, 0x3c, 0x50
-       .byte   0x57, 0x19, 0x84
-       .byte   0x58, 0x1e, 0x84
-       .byte   0x59, 0x2b, 0x84
-       .byte   0x5a, 0x3c, 0x84
-       .byte   0
-       .ascii  "Trident"
-       .byte   0
-
-# Tseng.
-tseng_test:
-       movw    $0x3cd, %dx
-       inb     %dx, %al        # Could things be this simple ! :-)
-       movb    %al, %bl
-       movb    $0x55, %al
-       outb    %al, %dx
-       inb     %dx, %al
-       movb    %al, %ah
-       movb    %bl, %al
-       outb    %al, %dx
-       cmpb    $0x55, %ah
-       je      istsen
-
-isnot: xorw    %bp, %bp
-istsen:        ret
-
-tseng_md:
-       .byte   0x26, 0x3c, 0x50
-       .byte   0x2a, 0x28, 0x64
-       .byte   0x23, 0x19, 0x84
-       .byte   0x24, 0x1c, 0x84
-       .byte   0x22, 0x2c, 0x84
-       .byte   0x21, 0x3c, 0x84
-       .byte   0
-       .ascii  "Tseng"
-       .byte   0
-
-# Video7.
-video7_test:
-       movw    $0x3cc, %dx
-       inb     %dx, %al
-       movw    $0x3b4, %dx
-       andb    $0x01, %al
-       jz      even7
-
-       movw    $0x3d4, %dx
-even7: movb    $0x0c, %al
-       outb    %al, %dx
-       incw    %dx
-       inb     %dx, %al
-       movb    %al, %bl
-       movb    $0x55, %al
-       outb    %al, %dx
-       inb     %dx, %al
-       decw    %dx
-       movb    $0x1f, %al
-       outb    %al, %dx
-       incw    %dx
-       inb     %dx, %al
-       movb    %al, %bh
-       decw    %dx
-       movb    $0x0c, %al
-       outb    %al, %dx
-       incw    %dx
-       movb    %bl, %al
-       outb    %al, %dx
-       movb    $0x55, %al
-       xorb    $0xea, %al
-       cmpb    %bh, %al
-       jne     isnot
-       
-       movb    $VIDEO_FIRST_V7>>8, svga_prefix # Use special mode switching
-       ret
-
-video7_md:
-       .byte   0x40, 0x2b, 0x50
-       .byte   0x43, 0x3c, 0x50
-       .byte   0x44, 0x3c, 0x64
-       .byte   0x41, 0x19, 0x84
-       .byte   0x42, 0x2c, 0x84
-       .byte   0x45, 0x1c, 0x84
-       .byte   0
-       .ascii  "Video 7"
-       .byte   0
-
-# Realtek VGA
-realtek_test:
-       leaw    idrtvga, %si
-       movw    $0x45, %di
-       movw    $0x0b, %cx
-       repe
-       cmpsb
-       je      isrt
-       
-       xorw    %bp, %bp
-isrt:  ret
-
-idrtvga:       .ascii  "REALTEK VGA"
-
-realtek_md:
-       .byte   0x1a, 0x3c, 0x50
-       .byte   0x1b, 0x19, 0x84
-       .byte   0x1c, 0x1e, 0x84
-       .byte   0x1d, 0x2b, 0x84
-       .byte   0x1e, 0x3c, 0x84
-       .byte   0
-       .ascii  "REALTEK"
-       .byte   0
-
-#endif /* CONFIG_VIDEO_SVGA */
-
-# User-defined local mode table (VGA only)
-#ifdef CONFIG_VIDEO_LOCAL
-local_modes:
-       leaw    local_mode_table, %si
-locm1: lodsw
-       orw     %ax, %ax
-       jz      locm2
-       
-       stosw
-       movsw
-       jmp     locm1
-
-locm2: ret
-
-# This is the table of local video modes which can be supplied manually
-# by the user. Each entry consists of mode ID (word) and dimensions
-# (byte for column count and another byte for row count). These modes
-# are placed before all SVGA and VESA modes and override them if table
-# compacting is enabled. The table must end with a zero word followed
-# by NUL-terminated video adapter name.
-local_mode_table:
-       .word   0x0100                          # Example: 40x25
-       .byte   25,40
-       .word   0
-       .ascii  "Local"
-       .byte   0
-#endif /* CONFIG_VIDEO_LOCAL */
-
-# Read a key and return the ASCII code in al, scan code in ah
-getkey:        xorb    %ah, %ah
-       int     $0x16
-       ret
-
-# Read a key with a timeout of 30 seconds.
-# The hardware clock is used to get the time.
-getkt: call    gettime
-       addb    $30, %al                        # Wait 30 seconds
-       cmpb    $60, %al
-       jl      lminute
-
-       subb    $60, %al
-lminute:
-       movb    %al, %cl
-again: movb    $0x01, %ah
-       int     $0x16
-       jnz     getkey                          # key pressed, so get it
-
-       call    gettime
-       cmpb    %cl, %al
-       jne     again
-
-       movb    $0x20, %al                      # timeout, return `space'
-       ret
-
-# Flush the keyboard buffer
-flush: movb    $0x01, %ah
-       int     $0x16
-       jz      empty
-       
-       xorb    %ah, %ah
-       int     $0x16
-       jmp     flush
-
-empty: ret
-
-# Print hexadecimal number.
-prthw: pushw   %ax
-       movb    %ah, %al
-       call    prthb
-       popw    %ax
-prthb: pushw   %ax
-       shrb    $4, %al
-       call    prthn
-       popw    %ax
-       andb    $0x0f, %al
-prthn: cmpb    $0x0a, %al
-       jc      prth1
-
-       addb    $0x07, %al
-prth1: addb    $0x30, %al
-       jmp     prtchr
-
-# Print decimal number in al
-prtdec:        pushw   %ax
-       pushw   %cx
-       xorb    %ah, %ah
-       movb    $0x0a, %cl
-       idivb   %cl
-       cmpb    $0x09, %al
-       jbe     lt100
-
-       call    prtdec
-       jmp     skip10
-
-lt100: addb    $0x30, %al
-       call    prtchr
-skip10:        movb    %ah, %al
-       addb    $0x30, %al
-       call    prtchr  
-       popw    %cx
-       popw    %ax
-       ret
-
-store_edid:
-#ifdef CONFIG_FIRMWARE_EDID
-       pushw   %es                             # just save all registers
-       pushw   %ax
-       pushw   %bx
-       pushw   %cx
-       pushw   %dx
-       pushw   %di
-
-       pushw   %fs
-       popw    %es
-
-       movl    $0x13131313, %eax               # memset block with 0x13
-       movw    $32, %cx
-       movw    $0x140, %di
-       cld
-       rep
-       stosl
-
-       cmpw    $0x0200, vbe_version            # only do EDID on >= VBE2.0
-       jl      no_edid
-
-       pushw   %es                             # save ES
-       xorw    %di, %di                        # Report Capability
-       pushw   %di
-       popw    %es                             # ES:DI must be 0:0
-       movw    $0x4f15, %ax
-       xorw    %bx, %bx
-       xorw    %cx, %cx
-       int     $0x10
-       popw    %es                             # restore ES
-
-       cmpb    $0x00, %ah                      # call successful
-       jne     no_edid
-
-       cmpb    $0x4f, %al                      # function supported
-       jne     no_edid
-
-       movw    $0x4f15, %ax                    # do VBE/DDC
-       movw    $0x01, %bx
-       movw    $0x00, %cx
-       movw    $0x00, %dx
-       movw    $0x140, %di
-       int     $0x10
-
-no_edid:
-       popw    %di                             # restore all registers
-       popw    %dx
-       popw    %cx
-       popw    %bx
-       popw    %ax
-       popw    %es
-#endif
-       ret
-
-# VIDEO_SELECT-only variables
-mt_end:                .word   0       # End of video mode table if built
-edit_buf:      .space  6       # Line editor buffer
-card_name:     .word   0       # Pointer to adapter name
-scanning:      .byte   0       # Performing mode scan
-do_restore:    .byte   0       # Screen contents altered during mode change
-svga_prefix:   .byte   VIDEO_FIRST_BIOS>>8     # Default prefix for BIOS modes
-graphic_mode:  .byte   0       # Graphic mode with a linear frame buffer
-dac_size:      .byte   6       # DAC bit depth
-vbe_version:   .word   0       # VBE bios version
-
-# Status messages
-keymsg:                .ascii  "Press <RETURN> to see video modes available, "
-               .ascii  "<SPACE> to continue or wait 30 secs"
-               .byte   0x0d, 0x0a, 0
-
-listhdr:       .byte   0x0d, 0x0a
-               .ascii  "Mode:    COLSxROWS:"
-
-crlft:         .byte   0x0d, 0x0a, 0
-
-prompt:                .byte   0x0d, 0x0a
-               .asciz  "Enter mode number or `scan': "
-
-unknt:         .asciz  "Unknown mode ID. Try again."
-
-badmdt:                .ascii  "You passed an undefined mode number."
-               .byte   0x0d, 0x0a, 0
-
-vesaer:                .ascii  "Error: Scanning of VESA modes failed. Please "
-               .ascii  "report to <mj@ucw.cz>."
-               .byte   0x0d, 0x0a, 0
-
-old_name:      .asciz  "CGA/MDA/HGA"
-
-ega_name:      .asciz  "EGA"
-
-svga_name:     .ascii  " "
-
-vga_name:      .asciz  "VGA"
-
-vesa_name:     .asciz  "VESA"
-
-name_bann:     .asciz  "Video adapter: "
-#endif /* CONFIG_VIDEO_SELECT */
-
-# Other variables:
-adapter:       .byte   0       # Video adapter: 0=CGA/MDA/HGA,1=EGA,2=VGA
-video_segment: .word   0xb800  # Video memory segment
-force_size:    .word   0       # Use this size instead of the one in BIOS vars
diff --git a/arch/i386/boot/video.c b/arch/i386/boot/video.c
new file mode 100644 (file)
index 0000000..3bb3573
--- /dev/null
@@ -0,0 +1,456 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/video.c
+ *
+ * Select video mode
+ */
+
+#include "boot.h"
+#include "video.h"
+#include "vesa.h"
+
+/*
+ * Mode list variables
+ */
+static struct card_info cards[];    /* List of cards to probe for */
+
+/*
+ * Common variables
+ */
+int adapter;                   /* 0=CGA/MDA/HGC, 1=EGA, 2=VGA+ */
+u16 video_segment;
+int force_x, force_y;  /* Don't query the BIOS for cols/rows */
+
+int do_restore = 0;    /* Screen contents changed during mode flip */
+int graphic_mode;      /* Graphic mode with linear frame buffer */
+
+static void store_cursor_position(void)
+{
+       u16 curpos;
+       u16 ax, bx;
+
+       ax = 0x0300;
+       bx = 0;
+       asm(INT10
+           : "=d" (curpos), "+a" (ax), "+b" (bx)
+           : : "ecx", "esi", "edi");
+
+       boot_params.screen_info.orig_x = curpos;
+       boot_params.screen_info.orig_y = curpos >> 8;
+}
+
+static void store_video_mode(void)
+{
+       u16 ax, page;
+
+       /* N.B.: the saving of the video page here is a bit silly,
+          since we pretty much assume page 0 everywhere. */
+       ax = 0x0f00;
+       asm(INT10
+           : "+a" (ax), "=b" (page)
+           : : "ecx", "edx", "esi", "edi");
+
+       /* Not all BIOSes are clean with respect to the top bit */
+       boot_params.screen_info.orig_video_mode = ax & 0x7f;
+       boot_params.screen_info.orig_video_page = page;
+}
+
+/*
+ * Store the video mode parameters for later usage by the kernel.
+ * This is done by asking the BIOS except for the rows/columns
+ * parameters in the default 80x25 mode -- these are set directly,
+ * because some very obscure BIOSes supply insane values.
+ */
+static void store_mode_params(void)
+{
+       u16 font_size;
+       int x, y;
+
+       /* For graphics mode, it is up to the mode-setting driver
+          (currently only video-vesa.c) to store the parameters */
+       if (graphic_mode)
+               return;
+
+       store_cursor_position();
+       store_video_mode();
+
+       if (boot_params.screen_info.orig_video_mode == 0x07) {
+               /* MDA, HGC, or VGA in monochrome mode */
+               video_segment = 0xb000;
+       } else {
+               /* CGA, EGA, VGA and so forth */
+               video_segment = 0xb800;
+       }
+
+       set_fs(0);
+       font_size = rdfs16(0x485); /* Font size, BIOS area */
+       boot_params.screen_info.orig_video_points = font_size;
+
+       x = rdfs16(0x44a);
+       y = (adapter == ADAPTER_CGA) ? 25 : rdfs8(0x484)+1;
+
+       if (force_x)
+               x = force_x;
+       if (force_y)
+               y = force_y;
+
+       boot_params.screen_info.orig_video_cols  = x;
+       boot_params.screen_info.orig_video_lines = y;
+}
+
+/* Probe the video drivers and have them generate their mode lists. */
+static void probe_cards(int unsafe)
+{
+       struct card_info *card;
+       static u8 probed[2];
+
+       if (probed[unsafe])
+               return;
+
+       probed[unsafe] = 1;
+
+       for (card = video_cards; card < video_cards_end; card++) {
+               if (card->unsafe == unsafe) {
+                       if (card->probe)
+                               card->nmodes = card->probe();
+                       else
+                               card->nmodes = 0;
+               }
+       }
+}
+
+/* Test if a mode is defined */
+int mode_defined(u16 mode)
+{
+       struct card_info *card;
+       struct mode_info *mi;
+       int i;
+
+       for (card = video_cards; card < video_cards_end; card++) {
+               mi = card->modes;
+               for (i = 0; i < card->nmodes; i++, mi++) {
+                       if (mi->mode == mode)
+                               return 1;
+               }
+       }
+
+       return 0;
+}
+
+/* Set mode (without recalc) */
+static int raw_set_mode(u16 mode)
+{
+       int nmode, i;
+       struct card_info *card;
+       struct mode_info *mi;
+
+       /* Drop the recalc bit if set */
+       mode &= ~VIDEO_RECALC;
+
+       /* Scan for mode based on fixed ID, position, or resolution */
+       nmode = 0;
+       for (card = video_cards; card < video_cards_end; card++) {
+               mi = card->modes;
+               for (i = 0; i < card->nmodes; i++, mi++) {
+                       int visible = mi->x || mi->y;
+
+                       if ((mode == nmode && visible) ||
+                           mode == mi->mode ||
+                           mode == (mi->y << 8)+mi->x)
+                               return card->set_mode(mi);
+
+                       if (visible)
+                               nmode++;
+               }
+       }
+
+       /* Nothing found?  Is it an "exceptional" (unprobed) mode? */
+       for (card = video_cards; card < video_cards_end; card++) {
+               if (mode >= card->xmode_first &&
+                   mode < card->xmode_first+card->xmode_n) {
+                       struct mode_info mix;
+                       mix.mode = mode;
+                       mix.x = mix.y = 0;
+                       return card->set_mode(&mix);
+               }
+       }
+
+       /* Otherwise, failure... */
+       return -1;
+}
+
+/*
+ * Recalculate the vertical video cutoff (hack!)
+ */
+static void vga_recalc_vertical(void)
+{
+       unsigned int font_size, rows;
+       u16 crtc;
+       u8 ov;
+
+       set_fs(0);
+       font_size = rdfs8(0x485); /* BIOS: font size (pixels) */
+       rows = force_y ? force_y : rdfs8(0x484)+1; /* Text rows */
+
+       rows *= font_size;      /* Visible scan lines */
+       rows--;                 /* ... minus one */
+
+       crtc = vga_crtc();
+
+       out_idx((u8)rows, crtc, 0x12); /* Lower height register */
+       ov = in_idx(crtc, 0x07); /* Overflow register */
+       ov &= 0xbd;
+       ov |= (rows >> (8-1)) & 0x02;
+       ov |= (rows >> (9-6)) & 0x40;
+       out_idx(ov, crtc, 0x07);
+}
+
+/* Set mode (with recalc if specified) */
+static int set_mode(u16 mode)
+{
+       int rv;
+
+       /* Very special mode numbers... */
+       if (mode == VIDEO_CURRENT_MODE)
+               return 0;       /* Nothing to do... */
+       else if (mode == NORMAL_VGA)
+               mode = VIDEO_80x25;
+       else if (mode == EXTENDED_VGA)
+               mode = VIDEO_8POINT;
+
+       rv = raw_set_mode(mode);
+       if (rv)
+               return rv;
+
+       if (mode & VIDEO_RECALC)
+               vga_recalc_vertical();
+
+       return 0;
+}
+
+static unsigned int get_entry(void)
+{
+       char entry_buf[4];
+       int i, len = 0;
+       int key;
+       unsigned int v;
+
+       do {
+               key = getchar();
+
+               if (key == '\b') {
+                       if (len > 0) {
+                               puts("\b \b");
+                               len--;
+                       }
+               } else if ((key >= '0' && key <= '9') ||
+                          (key >= 'A' && key <= 'Z') ||
+                          (key >= 'a' && key <= 'z')) {
+                       if (len < sizeof entry_buf) {
+                               entry_buf[len++] = key;
+                               putchar(key);
+                       }
+               }
+       } while (key != '\r');
+       putchar('\n');
+
+       if (len == 0)
+               return VIDEO_CURRENT_MODE; /* Default */
+
+       v = 0;
+       for (i = 0; i < len; i++) {
+               v <<= 4;
+               key = entry_buf[i] | 0x20;
+               v += (key > '9') ? key-'a'+10 : key-'0';
+       }
+
+       return v;
+}
+
+static void display_menu(void)
+{
+       struct card_info *card;
+       struct mode_info *mi;
+       char ch;
+       int i;
+
+       puts("Mode:    COLSxROWS:\n");
+
+       ch = '0';
+       for (card = video_cards; card < video_cards_end; card++) {
+               mi = card->modes;
+               for (i = 0; i < card->nmodes; i++, mi++) {
+                       int visible = mi->x && mi->y;
+                       u16 mode_id = mi->mode ? mi->mode :
+                               (mi->y << 8)+mi->x;
+
+                       if (!visible)
+                               continue; /* Hidden mode */
+
+                       printf("%c  %04X  %3dx%-3d  %s\n",
+                              ch, mode_id, mi->x, mi->y, card->card_name);
+
+                       if (ch == '9')
+                               ch = 'a';
+                       else if (ch == 'z' || ch == ' ')
+                               ch = ' '; /* Out of keys... */
+                       else
+                               ch++;
+               }
+       }
+}
+
+#define H(x)   ((x)-'a'+10)
+#define SCAN   ((H('s')<<12)+(H('c')<<8)+(H('a')<<4)+H('n'))
+
+static unsigned int mode_menu(void)
+{
+       int key;
+       unsigned int sel;
+
+       puts("Press <ENTER> to see video modes available, "
+            "<SPACE> to continue, or wait 30 sec\n");
+
+       kbd_flush();
+       while (1) {
+               key = getchar_timeout();
+               if (key == ' ' || key == 0)
+                       return VIDEO_CURRENT_MODE; /* Default */
+               if (key == '\r')
+                       break;
+               putchar('\a');  /* Beep! */
+       }
+
+
+       for (;;) {
+               display_menu();
+
+               puts("Enter a video mode or \"scan\" to scan for "
+                    "additional modes: ");
+               sel = get_entry();
+               if (sel != SCAN)
+                       return sel;
+
+               probe_cards(1);
+       }
+}
+
+#ifdef CONFIG_VIDEO_RETAIN
+/* Save screen content to the heap */
+struct saved_screen {
+       int x, y;
+       int curx, cury;
+       u16 *data;
+} saved;
+
+static void save_screen(void)
+{
+       /* Should be called after store_mode_params() */
+       saved.x = boot_params.screen_info.orig_video_cols;
+       saved.y = boot_params.screen_info.orig_video_lines;
+       saved.curx = boot_params.screen_info.orig_x;
+       saved.cury = boot_params.screen_info.orig_y;
+
+       if (heap_free() < saved.x*saved.y*sizeof(u16)+512)
+               return;         /* Not enough heap to save the screen */
+
+       saved.data = GET_HEAP(u16, saved.x*saved.y);
+
+       set_fs(video_segment);
+       copy_from_fs(saved.data, 0, saved.x*saved.y*sizeof(u16));
+}
+
+static void restore_screen(void)
+{
+       /* Should be called after store_mode_params() */
+       int xs = boot_params.screen_info.orig_video_cols;
+       int ys = boot_params.screen_info.orig_video_lines;
+       int y;
+       addr_t dst = 0;
+       u16 *src = saved.data;
+       u16 ax, bx, dx;
+
+       if (graphic_mode)
+               return;         /* Can't restore onto a graphic mode */
+
+       if (!src)
+               return;         /* No saved screen contents */
+
+       /* Restore screen contents */
+
+       set_fs(video_segment);
+       for (y = 0; y < ys; y++) {
+               int npad;
+
+               if (y < saved.y) {
+                       int copy = (xs < saved.x) ? xs : saved.x;
+                       copy_to_fs(dst, src, copy*sizeof(u16));
+                       dst += copy*sizeof(u16);
+                       src += saved.x;
+                       npad = (xs < saved.x) ? 0 : xs-saved.x;
+               } else {
+                       npad = xs;
+               }
+
+               /* Writes "npad" blank characters to
+                  video_segment:dst and advances dst */
+               asm volatile("pushw %%es ; "
+                            "movw %2,%%es ; "
+                            "shrw %%cx ; "
+                            "jnc 1f ; "
+                            "stosw \n\t"
+                            "1: rep;stosl ; "
+                            "popw %%es"
+                            : "+D" (dst), "+c" (npad)
+                            : "bdSm" (video_segment),
+                              "a" (0x07200720));
+       }
+
+       /* Restore cursor position */
+       ax = 0x0200;            /* Set cursor position */
+       bx = 0;                 /* Page number (<< 8) */
+       dx = (saved.cury << 8)+saved.curx;
+       asm volatile(INT10
+                    : "+a" (ax), "+b" (bx), "+d" (dx)
+                    : : "ecx", "esi", "edi");
+}
+#else
+#define save_screen()          ((void)0)
+#define restore_screen()       ((void)0)
+#endif
+
+void set_video(void)
+{
+       u16 mode = boot_params.hdr.vid_mode;
+
+       RESET_HEAP();
+
+       store_mode_params();
+       save_screen();
+       probe_cards(0);
+
+       for (;;) {
+               if (mode == ASK_VGA)
+                       mode = mode_menu();
+
+               if (!set_mode(mode))
+                       break;
+
+               printf("Undefined video mode number: %x\n", mode);
+               mode = ASK_VGA;
+       }
+       vesa_store_edid();
+       store_mode_params();
+
+       if (do_restore)
+               restore_screen();
+}
diff --git a/arch/i386/boot/video.h b/arch/i386/boot/video.h
new file mode 100644 (file)
index 0000000..29eca17
--- /dev/null
@@ -0,0 +1,145 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/video.h
+ *
+ * Header file for the real-mode video probing code
+ */
+
+#ifndef BOOT_VIDEO_H
+#define BOOT_VIDEO_H
+
+#include <linux/types.h>
+
+/* Enable autodetection of SVGA adapters and modes. */
+#undef CONFIG_VIDEO_SVGA
+
+/* Enable autodetection of VESA modes */
+#define CONFIG_VIDEO_VESA
+
+/* Retain screen contents when switching modes */
+#define CONFIG_VIDEO_RETAIN
+
+/* Force 400 scan lines for standard modes (hack to fix bad BIOS behaviour */
+#undef CONFIG_VIDEO_400_HACK
+
+/* This code uses an extended set of video mode numbers. These include:
+ * Aliases for standard modes
+ *      NORMAL_VGA (-1)
+ *      EXTENDED_VGA (-2)
+ *      ASK_VGA (-3)
+ * Video modes numbered by menu position -- NOT RECOMMENDED because of lack
+ * of compatibility when extending the table. These are between 0x00 and 0xff.
+ */
+#define VIDEO_FIRST_MENU 0x0000
+
+/* Standard BIOS video modes (BIOS number + 0x0100) */
+#define VIDEO_FIRST_BIOS 0x0100
+
+/* VESA BIOS video modes (VESA number + 0x0200) */
+#define VIDEO_FIRST_VESA 0x0200
+
+/* Video7 special modes (BIOS number + 0x0900) */
+#define VIDEO_FIRST_V7 0x0900
+
+/* Special video modes */
+#define VIDEO_FIRST_SPECIAL 0x0f00
+#define VIDEO_80x25 0x0f00
+#define VIDEO_8POINT 0x0f01
+#define VIDEO_80x43 0x0f02
+#define VIDEO_80x28 0x0f03
+#define VIDEO_CURRENT_MODE 0x0f04
+#define VIDEO_80x30 0x0f05
+#define VIDEO_80x34 0x0f06
+#define VIDEO_80x60 0x0f07
+#define VIDEO_GFX_HACK 0x0f08
+#define VIDEO_LAST_SPECIAL 0x0f09
+
+/* Video modes given by resolution */
+#define VIDEO_FIRST_RESOLUTION 0x1000
+
+/* The "recalculate timings" flag */
+#define VIDEO_RECALC 0x8000
+
+/* Define DO_STORE according to CONFIG_VIDEO_RETAIN */
+#ifdef CONFIG_VIDEO_RETAIN
+void store_screen(void);
+#define DO_STORE() store_screen()
+#else
+#define DO_STORE() ((void)0)
+#endif /* CONFIG_VIDEO_RETAIN */
+
+/*
+ * Mode table structures
+ */
+
+struct mode_info {
+       u16 mode;               /* Mode number (vga= style) */
+       u8  x, y;               /* Width, height */
+};
+
+struct card_info {
+       const char *card_name;
+       int (*set_mode)(struct mode_info *mode);
+       int (*probe)(void);
+       struct mode_info *modes;
+       int nmodes;             /* Number of probed modes so far */
+       int unsafe;             /* Probing is unsafe, only do after "scan" */
+       u16 xmode_first;        /* Unprobed modes to try to call anyway */
+       u16 xmode_n;            /* Size of unprobed mode range */
+};
+
+#define __videocard struct card_info __attribute__((section(".videocards")))
+extern struct card_info video_cards[], video_cards_end[];
+
+int mode_defined(u16 mode);    /* video.c */
+
+/* Basic video information */
+#define ADAPTER_CGA    0       /* CGA/MDA/HGC */
+#define ADAPTER_EGA    1
+#define ADAPTER_VGA    2
+
+extern int adapter;
+extern u16 video_segment;
+extern int force_x, force_y;   /* Don't query the BIOS for cols/rows */
+extern int do_restore;         /* Restore screen contents */
+extern int graphic_mode;       /* Graphics mode with linear frame buffer */
+
+/*
+ * int $0x10 is notorious for touching registers it shouldn't.
+ * gcc doesn't like %ebp being clobbered, so define it as a push/pop
+ * sequence here.
+ */
+#define INT10 "pushl %%ebp; int $0x10; popl %%ebp"
+
+/* Accessing VGA indexed registers */
+static inline u8 in_idx(u16 port, u8 index)
+{
+       outb(index, port);
+       return inb(port+1);
+}
+
+static inline void out_idx(u8 v, u16 port, u8 index)
+{
+       outw(index+(v << 8), port);
+}
+
+/* Writes a value to an indexed port and then reads the port again */
+static inline u8 tst_idx(u8 v, u16 port, u8 index)
+{
+       out_idx(port, index, v);
+       return in_idx(port, index);
+}
+
+/* Get the I/O port of the VGA CRTC */
+u16 vga_crtc(void);            /* video-vga.c */
+
+#endif /* BOOT_VIDEO_H */
diff --git a/arch/i386/boot/voyager.c b/arch/i386/boot/voyager.c
new file mode 100644 (file)
index 0000000..9221614
--- /dev/null
@@ -0,0 +1,46 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/voyager.c
+ *
+ * Get the Voyager config information
+ */
+
+#include "boot.h"
+
+#ifdef CONFIG_X86_VOYAGER
+
+int query_voyager(void)
+{
+       u8 err;
+       u16 es, di;
+       /* Abuse the apm_bios_info area for this */
+       u8 *data_ptr = (u8 *)&boot_params.apm_bios_info;
+
+       data_ptr[0] = 0xff;     /* Flag on config not found(?) */
+
+       asm("pushw %%es ; "
+           "int $0x15 ; "
+           "setc %0 ; "
+           "movw %%es, %1 ; "
+           "popw %%es"
+           : "=qm" (err), "=rm" (es), "=D" (di)
+           : "a" (0xffc0));
+
+       if (err)
+               return -1;      /* Not Voyager */
+
+       set_fs(es);
+       copy_from_fs(data_ptr, di, 7);  /* Table is 7 bytes apparently */
+       return 0;
+}
+
+#endif /* CONFIG_X86_VOYAGER */
index 74f27a463db088dbccce3293a9904d7c1c646f55..0b6a8551e9e222167c44fbb8e6bd63bd0d10141c 100644 (file)
@@ -8,7 +8,7 @@ obj-y   +=      amd.o
 obj-y  +=      cyrix.o
 obj-y  +=      centaur.o
 obj-y  +=      transmeta.o
-obj-y  +=      intel.o intel_cacheinfo.o
+obj-y  +=      intel.o intel_cacheinfo.o addon_cpuid_features.o
 obj-y  +=      rise.o
 obj-y  +=      nexgen.o
 obj-y  +=      umc.o
diff --git a/arch/i386/kernel/cpu/addon_cpuid_features.c b/arch/i386/kernel/cpu/addon_cpuid_features.c
new file mode 100644 (file)
index 0000000..3e91d3e
--- /dev/null
@@ -0,0 +1,50 @@
+
+/*
+ *     Routines to indentify additional cpu features that are scattered in
+ *     cpuid space.
+ */
+
+#include <linux/cpu.h>
+
+#include <asm/processor.h>
+
+struct cpuid_bit {
+       u16 feature;
+       u8 reg;
+       u8 bit;
+       u32 level;
+};
+
+enum cpuid_regs {
+       CR_EAX = 0,
+       CR_ECX,
+       CR_EDX,
+       CR_EBX
+};
+
+void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c)
+{
+       u32 max_level;
+       u32 regs[4];
+       const struct cpuid_bit *cb;
+
+       static const struct cpuid_bit cpuid_bits[] = {
+               { X86_FEATURE_IDA, CR_EAX, 1, 0x00000006 },
+               { 0, 0, 0, 0 }
+       };
+
+       for (cb = cpuid_bits; cb->feature; cb++) {
+
+               /* Verify that the level is valid */
+               max_level = cpuid_eax(cb->level & 0xffff0000);
+               if (max_level < cb->level ||
+                   max_level > (cb->level | 0xffff))
+                       continue;
+
+               cpuid(cb->level, &regs[CR_EAX], &regs[CR_EBX],
+                       &regs[CR_ECX], &regs[CR_EDX]);
+
+               if (regs[cb->reg] & (1 << cb->bit))
+                       set_bit(cb->feature, c->x86_capability);
+       }
+}
index 794d593c47eb078acf6cf435023aabbbfef65ce1..e5419a9dec885e1d1135f1f46279e3388039a71f 100644 (file)
@@ -353,6 +353,8 @@ static void __cpuinit generic_identify(struct cpuinfo_x86 * c)
                        if ( xlvl >= 0x80000004 )
                                get_model_name(c); /* Default name */
                }
+
+               init_scattered_cpuid_features(c);
        }
 
        early_intel_workaround(c);
index e912aae9473cb449480cde7a60e68b70347a6b71..e77754ca94b48eadaf04915d9febfc84cc46d5be 100644 (file)
@@ -90,10 +90,17 @@ config X86_POWERNOW_K8
          If in doubt, say N.
 
 config X86_POWERNOW_K8_ACPI
-       bool
-       depends on X86_POWERNOW_K8 && ACPI_PROCESSOR
-       depends on !(X86_POWERNOW_K8 = y && ACPI_PROCESSOR = m)
+       bool "ACPI Support"
+       select ACPI_PROCESSOR
+       depends on X86_POWERNOW_K8
        default y
+       help
+         This provides access to the K8s Processor Performance States via ACPI.
+         This driver is probably required for CPUFreq to work with multi-socket and
+         SMP systems.  It is not required on at least some single-socket yet
+         multi-core systems, even if SMP is enabled.
+
+         It is safe to say Y here.
 
 config X86_GX_SUSPMOD
        tristate "Cyrix MediaGX/NatSemi Geode Suspend Modulation"
index 10baa3501ed336c37b5d9a5662ce99484c48d651..18c8b67ea3a75ce4b5d740e1eb8a68b3cda46915 100644 (file)
@@ -167,11 +167,13 @@ static void do_drv_read(struct drv_cmd *cmd)
 
 static void do_drv_write(struct drv_cmd *cmd)
 {
-       u32 h = 0;
+       u32 lo, hi;
 
        switch (cmd->type) {
        case SYSTEM_INTEL_MSR_CAPABLE:
-               wrmsr(cmd->addr.msr.reg, cmd->val, h);
+               rdmsr(cmd->addr.msr.reg, lo, hi);
+               lo = (lo & ~INTEL_MSR_RANGE) | (cmd->val & INTEL_MSR_RANGE);
+               wrmsr(cmd->addr.msr.reg, lo, hi);
                break;
        case SYSTEM_IO_CAPABLE:
                acpi_os_write_port((acpi_io_address)cmd->addr.io.port,
@@ -372,7 +374,6 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy,
        struct cpufreq_freqs freqs;
        cpumask_t online_policy_cpus;
        struct drv_cmd cmd;
-       unsigned int msr;
        unsigned int next_state = 0; /* Index into freq_table */
        unsigned int next_perf_state = 0; /* Index into perf table */
        unsigned int i;
@@ -417,11 +418,7 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy,
        case SYSTEM_INTEL_MSR_CAPABLE:
                cmd.type = SYSTEM_INTEL_MSR_CAPABLE;
                cmd.addr.msr.reg = MSR_IA32_PERF_CTL;
-               msr =
-                   (u32) perf->states[next_perf_state].
-                   control & INTEL_MSR_RANGE;
-               cmd.val = get_cur_val(online_policy_cpus);
-               cmd.val = (cmd.val & ~INTEL_MSR_RANGE) | msr;
+               cmd.val = (u32) perf->states[next_perf_state].control;
                break;
        case SYSTEM_IO_CAPABLE:
                cmd.type = SYSTEM_IO_CAPABLE;
index 0d49d73d1b711274387f6f23988415073774bc78..66acd5039918350d16819cbf41457053f021fe56 100644 (file)
@@ -391,8 +391,6 @@ static struct cpufreq_driver nforce2_driver = {
  */
 static unsigned int nforce2_detect_chipset(void)
 {
-       u8 revision;
-
        nforce2_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_NVIDIA,
                                        PCI_DEVICE_ID_NVIDIA_NFORCE2,
                                        PCI_ANY_ID, PCI_ANY_ID, NULL);
@@ -400,10 +398,8 @@ static unsigned int nforce2_detect_chipset(void)
        if (nforce2_chipset_dev == NULL)
                return -ENODEV;
 
-       pci_read_config_byte(nforce2_chipset_dev, PCI_REVISION_ID, &revision);
-
        printk(KERN_INFO "cpufreq: Detected nForce2 chipset revision %X\n",
-              revision);
+              nforce2_chipset_dev->revision);
        printk(KERN_INFO
               "cpufreq: FSB changing is maybe unstable and can lead to crashes and data loss.\n");
 
index 6667e9cceb9fd8c3dbfe5d75a93008b27111a997..194144539a6f34ccddd67e4e7f3393b68e5fecba 100644 (file)
@@ -115,7 +115,6 @@ struct gxfreq_params {
        u8 pci_suscfg;
        u8 pci_pmer1;
        u8 pci_pmer2;
-       u8 pci_rev;
        struct pci_dev *cs55x0;
 };
 
@@ -276,7 +275,7 @@ static void gx_set_cpuspeed(unsigned int khz)
                        pci_write_config_byte(gx_params->cs55x0, PCI_VIDTC, 100);/* typical 50 to 100ms */
                        pci_write_config_byte(gx_params->cs55x0, PCI_PMER1, pmer1);
 
-                       if (gx_params->pci_rev < 0x10) {   /* CS5530(rev 1.2, 1.3) */
+                       if (gx_params->cs55x0->revision < 0x10) {   /* CS5530(rev 1.2, 1.3) */
                                suscfg = gx_params->pci_suscfg | SUSMOD;
                        } else {                           /* CS5530A,B.. */
                                suscfg = gx_params->pci_suscfg | SUSMOD | PWRSVE;
@@ -471,7 +470,6 @@ static int __init cpufreq_gx_init(void)
        pci_read_config_byte(params->cs55x0, PCI_PMER2, &(params->pci_pmer2));
        pci_read_config_byte(params->cs55x0, PCI_MODON, &(params->on_duration));
        pci_read_config_byte(params->cs55x0, PCI_MODOFF, &(params->off_duration));
-       pci_read_config_byte(params->cs55x0, PCI_REVISION_ID, &params->pci_rev);
 
        if ((ret = cpufreq_register_driver(&gx_suspmod_driver))) {
                kfree(params);
index a3df9c039bd4221ecb3e80fdda4e71a8b4d9581d..8eca59d4c8f4c7a937b9d27694c0e413401072d5 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/string.h>
+#include <linux/delay.h>
 
 #include <asm/msr.h>
 #include <asm/timex.h>
@@ -55,7 +56,6 @@
 /* Flags */
 #define USE_ACPI_C3            (1 << 1)
 #define USE_NORTHBRIDGE                (1 << 2)
-#define USE_VT8235             (1 << 3)
 
 static int cpu_model;
 static unsigned int numscales=16;
@@ -63,19 +63,15 @@ static unsigned int fsb;
 
 static const struct mV_pos *vrm_mV_table;
 static const unsigned char *mV_vrm_table;
-struct f_msr {
-       u8 vrm;
-       u8 pos;
-};
-static struct f_msr f_msr_table[32];
 
 static unsigned int highest_speed, lowest_speed; /* kHz */
 static unsigned int minmult, maxmult;
 static int can_scale_voltage;
 static struct acpi_processor *pr = NULL;
 static struct acpi_processor_cx *cx = NULL;
+static u32 acpi_regs_addr;
 static u8 longhaul_flags;
-static u8 longhaul_pos;
+static unsigned int longhaul_index;
 
 /* Module parameters */
 static int scale_voltage;
@@ -144,7 +140,7 @@ static void do_longhaul1(unsigned int clock_ratio_index)
        rdmsrl(MSR_VIA_BCR2, bcr2.val);
        /* Enable software clock multiplier */
        bcr2.bits.ESOFTBF = 1;
-       bcr2.bits.CLOCKMUL = clock_ratio_index;
+       bcr2.bits.CLOCKMUL = clock_ratio_index & 0xff;
 
        /* Sync to timer tick */
        safe_halt();
@@ -163,14 +159,12 @@ static void do_longhaul1(unsigned int clock_ratio_index)
 
 /* For processor with Longhaul MSR */
 
-static void do_powersaver(int cx_address, unsigned int clock_ratio_index)
+static void do_powersaver(int cx_address, unsigned int clock_ratio_index,
+                         unsigned int dir)
 {
        union msr_longhaul longhaul;
-       u8 dest_pos;
        u32 t;
 
-       dest_pos = f_msr_table[clock_ratio_index].pos;
-
        rdmsrl(MSR_VIA_LONGHAUL, longhaul.val);
        /* Setup new frequency */
        longhaul.bits.RevisionKey = longhaul.bits.RevisionID;
@@ -178,11 +172,11 @@ static void do_powersaver(int cx_address, unsigned int clock_ratio_index)
        longhaul.bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4;
        /* Setup new voltage */
        if (can_scale_voltage)
-               longhaul.bits.SoftVID = f_msr_table[clock_ratio_index].vrm;
+               longhaul.bits.SoftVID = (clock_ratio_index >> 8) & 0x1f;
        /* Sync to timer tick */
        safe_halt();
        /* Raise voltage if necessary */
-       if (can_scale_voltage && longhaul_pos < dest_pos) {
+       if (can_scale_voltage && dir) {
                longhaul.bits.EnableSoftVID = 1;
                wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
                /* Change voltage */
@@ -199,7 +193,6 @@ static void do_powersaver(int cx_address, unsigned int clock_ratio_index)
                }
                longhaul.bits.EnableSoftVID = 0;
                wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
-               longhaul_pos = dest_pos;
        }
 
        /* Change frequency on next halt or sleep */
@@ -220,7 +213,7 @@ static void do_powersaver(int cx_address, unsigned int clock_ratio_index)
        wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
 
        /* Reduce voltage if necessary */
-       if (can_scale_voltage && longhaul_pos > dest_pos) {
+       if (can_scale_voltage && !dir) {
                longhaul.bits.EnableSoftVID = 1;
                wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
                /* Change voltage */
@@ -237,7 +230,6 @@ static void do_powersaver(int cx_address, unsigned int clock_ratio_index)
                }
                longhaul.bits.EnableSoftVID = 0;
                wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
-               longhaul_pos = dest_pos;
        }
 }
 
@@ -248,25 +240,28 @@ static void do_powersaver(int cx_address, unsigned int clock_ratio_index)
  * Sets a new clock ratio.
  */
 
-static void longhaul_setstate(unsigned int clock_ratio_index)
+static void longhaul_setstate(unsigned int table_index)
 {
+       unsigned int clock_ratio_index;
        int speed, mult;
        struct cpufreq_freqs freqs;
-       static unsigned int old_ratio=-1;
        unsigned long flags;
        unsigned int pic1_mask, pic2_mask;
+       u16 bm_status = 0;
+       u32 bm_timeout = 1000;
+       unsigned int dir = 0;
 
-       if (old_ratio == clock_ratio_index)
-               return;
-       old_ratio = clock_ratio_index;
-
-       mult = clock_ratio[clock_ratio_index];
+       clock_ratio_index = longhaul_table[table_index].index;
+       /* Safety precautions */
+       mult = clock_ratio[clock_ratio_index & 0x1f];
        if (mult == -1)
                return;
-
        speed = calc_speed(mult);
        if ((speed > highest_speed) || (speed < lowest_speed))
                return;
+       /* Voltage transition before frequency transition? */
+       if (can_scale_voltage && longhaul_index < table_index)
+               dir = 1;
 
        freqs.old = calc_speed(longhaul_get_cpu_mult());
        freqs.new = speed;
@@ -285,11 +280,24 @@ static void longhaul_setstate(unsigned int clock_ratio_index)
        outb(0xFF,0xA1);        /* Overkill */
        outb(0xFE,0x21);        /* TMR0 only */
 
+       /* Wait while PCI bus is busy. */
+       if (acpi_regs_addr && (longhaul_flags & USE_NORTHBRIDGE
+           || ((pr != NULL) && pr->flags.bm_control))) {
+               bm_status = inw(acpi_regs_addr);
+               bm_status &= 1 << 4;
+               while (bm_status && bm_timeout) {
+                       outw(1 << 4, acpi_regs_addr);
+                       bm_timeout--;
+                       bm_status = inw(acpi_regs_addr);
+                       bm_status &= 1 << 4;
+               }
+       }
+
        if (longhaul_flags & USE_NORTHBRIDGE) {
                /* Disable AGP and PCI arbiters */
                outb(3, 0x22);
        } else if ((pr != NULL) && pr->flags.bm_control) {
-               /* Disable bus master arbitration */
+               /* Disable bus master arbitration */
                acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
        }
        switch (longhaul_version) {
@@ -314,9 +322,9 @@ static void longhaul_setstate(unsigned int clock_ratio_index)
                if (longhaul_flags & USE_ACPI_C3) {
                        /* Don't allow wakeup */
                        acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
-                       do_powersaver(cx->address, clock_ratio_index);
+                       do_powersaver(cx->address, clock_ratio_index, dir);
                } else {
-                       do_powersaver(0, clock_ratio_index);
+                       do_powersaver(0, clock_ratio_index, dir);
                }
                break;
        }
@@ -336,6 +344,9 @@ static void longhaul_setstate(unsigned int clock_ratio_index)
 
        freqs.new = calc_speed(longhaul_get_cpu_mult());
        cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+       if (!bm_timeout)
+               printk(KERN_INFO PFX "Warning: Timeout while waiting for idle PCI bus.\n");
 }
 
 /*
@@ -369,7 +380,8 @@ static int guess_fsb(int mult)
 
 static int __init longhaul_get_ranges(void)
 {
-       unsigned int j, k = 0;
+       unsigned int i, j, k = 0;
+       unsigned int ratio;
        int mult;
 
        /* Get current frequency */
@@ -423,8 +435,7 @@ static int __init longhaul_get_ranges(void)
        if(!longhaul_table)
                return -ENOMEM;
 
-       for (j=0; j < numscales; j++) {
-               unsigned int ratio;
+       for (j = 0; j < numscales; j++) {
                ratio = clock_ratio[j];
                if (ratio == -1)
                        continue;
@@ -434,13 +445,41 @@ static int __init longhaul_get_ranges(void)
                longhaul_table[k].index = j;
                k++;
        }
+       if (k <= 1) {
+               kfree(longhaul_table);
+               return -ENODEV;
+       }
+       /* Sort */
+       for (j = 0; j < k - 1; j++) {
+               unsigned int min_f, min_i;
+               min_f = longhaul_table[j].frequency;
+               min_i = j;
+               for (i = j + 1; i < k; i++) {
+                       if (longhaul_table[i].frequency < min_f) {
+                               min_f = longhaul_table[i].frequency;
+                               min_i = i;
+                       }
+               }
+               if (min_i != j) {
+                       unsigned int temp;
+                       temp = longhaul_table[j].frequency;
+                       longhaul_table[j].frequency = longhaul_table[min_i].frequency;
+                       longhaul_table[min_i].frequency = temp;
+                       temp = longhaul_table[j].index;
+                       longhaul_table[j].index = longhaul_table[min_i].index;
+                       longhaul_table[min_i].index = temp;
+               }
+       }
 
        longhaul_table[k].frequency = CPUFREQ_TABLE_END;
-       if (!k) {
-               kfree (longhaul_table);
-               return -EINVAL;
-       }
 
+       /* Find index we are running on */
+       for (j = 0; j < k; j++) {
+               if (clock_ratio[longhaul_table[j].index & 0x1f] == mult) {
+                       longhaul_index = j;
+                       break;
+               }
+       }
        return 0;
 }
 
@@ -448,7 +487,7 @@ static int __init longhaul_get_ranges(void)
 static void __init longhaul_setup_voltagescaling(void)
 {
        union msr_longhaul longhaul;
-       struct mV_pos minvid, maxvid;
+       struct mV_pos minvid, maxvid, vid;
        unsigned int j, speed, pos, kHz_step, numvscales;
        int min_vid_speed;
 
@@ -459,11 +498,11 @@ static void __init longhaul_setup_voltagescaling(void)
        }
 
        if (!longhaul.bits.VRMRev) {
-               printk (KERN_INFO PFX "VRM 8.5\n");
+               printk(KERN_INFO PFX "VRM 8.5\n");
                vrm_mV_table = &vrm85_mV[0];
                mV_vrm_table = &mV_vrm85[0];
        } else {
-               printk (KERN_INFO PFX "Mobile VRM\n");
+               printk(KERN_INFO PFX "Mobile VRM\n");
                if (cpu_model < CPU_NEHEMIAH)
                        return;
                vrm_mV_table = &mobilevrm_mV[0];
@@ -523,7 +562,6 @@ static void __init longhaul_setup_voltagescaling(void)
        /* Calculate kHz for one voltage step */
        kHz_step = (highest_speed - min_vid_speed) / numvscales;
 
-
        j = 0;
        while (longhaul_table[j].frequency != CPUFREQ_TABLE_END) {
                speed = longhaul_table[j].frequency;
@@ -531,15 +569,14 @@ static void __init longhaul_setup_voltagescaling(void)
                        pos = (speed - min_vid_speed) / kHz_step + minvid.pos;
                else
                        pos = minvid.pos;
-               f_msr_table[longhaul_table[j].index].vrm = mV_vrm_table[pos];
-               f_msr_table[longhaul_table[j].index].pos = pos;
+               longhaul_table[j].index |= mV_vrm_table[pos] << 8;
+               vid = vrm_mV_table[mV_vrm_table[pos]];
+               printk(KERN_INFO PFX "f: %d kHz, index: %d, vid: %d mV\n", speed, j, vid.mV);
                j++;
        }
 
-       longhaul_pos = maxvid.pos;
        can_scale_voltage = 1;
-       printk(KERN_INFO PFX "Voltage scaling enabled. "
-               "Use of \"conservative\" governor is highly recommended.\n");
+       printk(KERN_INFO PFX "Voltage scaling enabled.\n");
 }
 
 
@@ -553,15 +590,44 @@ static int longhaul_target(struct cpufreq_policy *policy,
                            unsigned int target_freq, unsigned int relation)
 {
        unsigned int table_index = 0;
-       unsigned int new_clock_ratio = 0;
+       unsigned int i;
+       unsigned int dir = 0;
+       u8 vid, current_vid;
 
        if (cpufreq_frequency_table_target(policy, longhaul_table, target_freq, relation, &table_index))
                return -EINVAL;
 
-       new_clock_ratio = longhaul_table[table_index].index & 0xFF;
-
-       longhaul_setstate(new_clock_ratio);
+       /* Don't set same frequency again */
+       if (longhaul_index == table_index)
+               return 0;
 
+       if (!can_scale_voltage)
+               longhaul_setstate(table_index);
+       else {
+               /* On test system voltage transitions exceeding single
+                * step up or down were turning motherboard off. Both
+                * "ondemand" and "userspace" are unsafe. C7 is doing
+                * this in hardware, C3 is old and we need to do this
+                * in software. */
+               i = longhaul_index;
+               current_vid = (longhaul_table[longhaul_index].index >> 8) & 0x1f;
+               if (table_index > longhaul_index)
+                       dir = 1;
+               while (i != table_index) {
+                       vid = (longhaul_table[i].index >> 8) & 0x1f;
+                       if (vid != current_vid) {
+                               longhaul_setstate(i);
+                               current_vid = vid;
+                               msleep(200);
+                       }
+                       if (dir)
+                               i++;
+                       else
+                               i--;
+               }
+               longhaul_setstate(table_index);
+       }
+       longhaul_index = table_index;
        return 0;
 }
 
@@ -590,11 +656,10 @@ static acpi_status longhaul_walk_callback(acpi_handle obj_handle,
 static int enable_arbiter_disable(void)
 {
        struct pci_dev *dev;
-       int status;
+       int status = 1;
        int reg;
        u8 pci_cmd;
 
-       status = 1;
        /* Find PLE133 host bridge */
        reg = 0x78;
        dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8601_0,
@@ -627,13 +692,17 @@ static int enable_arbiter_disable(void)
        return 0;
 }
 
-static int longhaul_setup_vt8235(void)
+static int longhaul_setup_southbridge(void)
 {
        struct pci_dev *dev;
        u8 pci_cmd;
 
        /* Find VT8235 southbridge */
        dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, NULL);
+       if (dev == NULL)
+       /* Find VT8237 southbridge */
+               dev = pci_get_device(PCI_VENDOR_ID_VIA,
+                                    PCI_DEVICE_ID_VIA_8237, NULL);
        if (dev != NULL) {
                /* Set transition time to max */
                pci_read_config_byte(dev, 0xec, &pci_cmd);
@@ -645,6 +714,14 @@ static int longhaul_setup_vt8235(void)
                pci_read_config_byte(dev, 0xe5, &pci_cmd);
                pci_cmd |= 1 << 7;
                pci_write_config_byte(dev, 0xe5, pci_cmd);
+               /* Get address of ACPI registers block*/
+               pci_read_config_byte(dev, 0x81, &pci_cmd);
+               if (pci_cmd & 1 << 7) {
+                       pci_read_config_dword(dev, 0x88, &acpi_regs_addr);
+                       acpi_regs_addr &= 0xff00;
+                       printk(KERN_INFO PFX "ACPI I/O at 0x%x\n", acpi_regs_addr);
+               }
+
                pci_dev_put(dev);
                return 1;
        }
@@ -657,7 +734,6 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
        char *cpuname=NULL;
        int ret;
        u32 lo, hi;
-       int vt8235_present;
 
        /* Check what we have on this motherboard */
        switch (c->x86_model) {
@@ -755,7 +831,7 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
        };
 
        /* Doesn't hurt */
-       vt8235_present = longhaul_setup_vt8235();
+       longhaul_setup_southbridge();
 
        /* Find ACPI data for processor */
        acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
@@ -765,35 +841,26 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
        /* Check ACPI support for C3 state */
        if (pr != NULL && longhaul_version == TYPE_POWERSAVER) {
                cx = &pr->power.states[ACPI_STATE_C3];
-               if (cx->address > 0 && cx->latency <= 1000) {
+               if (cx->address > 0 && cx->latency <= 1000)
                        longhaul_flags |= USE_ACPI_C3;
-                       goto print_support_type;
-               }
        }
        /* Check if northbridge is friendly */
-       if (enable_arbiter_disable()) {
+       if (enable_arbiter_disable())
                longhaul_flags |= USE_NORTHBRIDGE;
-               goto print_support_type;
-       }
-       /* Use VT8235 southbridge if present */
-       if (longhaul_version == TYPE_POWERSAVER && vt8235_present) {
-               longhaul_flags |= USE_VT8235;
-               goto print_support_type;
-       }
+
        /* Check ACPI support for bus master arbiter disable */
-       if ((pr == NULL) || !(pr->flags.bm_control)) {
+       if (!(longhaul_flags & USE_ACPI_C3
+            || longhaul_flags & USE_NORTHBRIDGE)
+           && ((pr == NULL) || !(pr->flags.bm_control))) {
                printk(KERN_ERR PFX
                        "No ACPI support. Unsupported northbridge.\n");
                return -ENODEV;
        }
 
-print_support_type:
        if (longhaul_flags & USE_NORTHBRIDGE)
-               printk (KERN_INFO PFX "Using northbridge support.\n");
-       else if (longhaul_flags & USE_VT8235)
-               printk (KERN_INFO PFX "Using VT8235 support.\n");
-       else
-               printk (KERN_INFO PFX "Using ACPI support.\n");
+               printk(KERN_INFO PFX "Using northbridge support.\n");
+       if (longhaul_flags & USE_ACPI_C3)
+               printk(KERN_INFO PFX "Using ACPI support.\n");
 
        ret = longhaul_get_ranges();
        if (ret != 0)
index 102548f128422ffba612cbc7d9ed5efe949f3cd0..4fcc320997dfd5b9462d21f9282ca2bdcb0c85f0 100644 (file)
@@ -180,7 +180,7 @@ static const int __initdata ezrat_clock_ratio[32] = {
 
        -1,  /* 0000 -> RESERVED (10.0x) */
        110, /* 0001 -> 11.0x */
-       120, /* 0010 -> 12.0x */
+       -1, /* 0010 -> 12.0x */
        -1,  /* 0011 -> RESERVED (9.0x)*/
        105, /* 0100 -> 10.5x */
        115, /* 0101 -> 11.5x */
@@ -237,7 +237,7 @@ static const int __initdata ezrat_eblcr[32] = {
 
 static const int __initdata  nehemiah_clock_ratio[32] = {
        100, /* 0000 -> 10.0x */
-       160, /* 0001 -> 16.0x */
+       -1, /* 0001 -> 16.0x */
        40,  /* 0010 ->  4.0x */
        90,  /* 0011 ->  9.0x */
        95,  /* 0100 ->  9.5x */
@@ -252,10 +252,10 @@ static const int __initdata  nehemiah_clock_ratio[32] = {
        75,  /* 1101 ->  7.5x */
        85,  /* 1110 ->  8.5x */
        120, /* 1111 -> 12.0x */
-       100, /* 0000 -> 10.0x */
+       -1, /* 0000 -> 10.0x */
        110, /* 0001 -> 11.0x */
-       120, /* 0010 -> 12.0x */
-       90,  /* 0011 ->  9.0x */
+       -1, /* 0010 -> 12.0x */
+       -1,  /* 0011 ->  9.0x */
        105, /* 0100 -> 10.5x */
        115, /* 0101 -> 11.5x */
        125, /* 0110 -> 12.5x */
@@ -267,7 +267,7 @@ static const int __initdata  nehemiah_clock_ratio[32] = {
        145, /* 1100 -> 14.5x */
        155, /* 1101 -> 15.5x */
        -1,  /* 1110 -> RESERVED (13.0x) */
-       120, /* 1111 -> 12.0x */
+       -1, /* 1111 -> 12.0x */
 };
 
 static const int __initdata nehemiah_eblcr[32] = {
index 698f980eb4438855ced62e38d3030d4f354e0290..a5b2346faf1fd2bba8d01bcbedb2253f4d3529cb 100644 (file)
@@ -205,7 +205,6 @@ static unsigned int speedstep_detect_chipset (void)
                 * host brige. Abort on these systems.
                 */
                static struct pci_dev *hostbridge;
-               u8 rev = 0;
 
                hostbridge  = pci_get_subsys(PCI_VENDOR_ID_INTEL,
                              PCI_DEVICE_ID_INTEL_82815_MC,
@@ -216,8 +215,7 @@ static unsigned int speedstep_detect_chipset (void)
                if (!hostbridge)
                        return 2; /* 2-M */
 
-               pci_read_config_byte(hostbridge, PCI_REVISION_ID, &rev);
-               if (rev < 5) {
+               if (hostbridge->revision < 5) {
                        dprintk("hostbridge does not support speedstep\n");
                        speedstep_chipset_dev = NULL;
                        pci_dev_put(hostbridge);
index 89d91e6cc97213849d87db7f537e0798a4fb968e..1e31b6caffb1651def36e96acf4cd06e4df48d4e 100644 (file)
@@ -29,7 +29,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL,
                NULL, NULL, NULL, "mp", "nx", NULL, "mmxext", NULL,
-               NULL, "fxsr_opt", "pdpe1gb", "rdtscp", NULL, "lm", "3dnowext", "3dnow",
+               NULL, "fxsr_opt", "pdpe1gb", "rdtscp", NULL, "lm",
+               "3dnowext", "3dnow",
 
                /* Transmeta-defined */
                "recovery", "longrun", NULL, "lrti", NULL, NULL, NULL, NULL,
@@ -40,8 +41,9 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                /* Other (Linux-defined) */
                "cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr",
                NULL, NULL, NULL, NULL,
-               "constant_tsc", "up", NULL, NULL, NULL, NULL, NULL, NULL,
-               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+               "constant_tsc", "up", NULL, "arch_perfmon",
+               "pebs", "bts", NULL, "sync_rdtsc",
+               "rep_good", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
                /* Intel-defined (#2) */
@@ -57,9 +59,16 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
                /* AMD-defined (#2) */
-               "lahf_lm", "cmp_legacy", "svm", "extapic", "cr8legacy", "abm",
-               "sse4a", "misalignsse",
-               "3dnowprefetch", "osvw", "ibs", NULL, NULL, NULL, NULL, NULL,
+               "lahf_lm", "cmp_legacy", "svm", "extapic", "cr8_legacy",
+               "altmovcr8", "abm", "sse4a",
+               "misalignsse", "3dnowprefetch",
+               "osvw", "ibs", NULL, NULL, NULL, NULL,
+               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+               /* Auxiliary (Linux-defined) */
+               "ida", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
        };
index 9645bb51f76a38c01a8c250d087ee46de44ceb0c..fc822a46897a720de02dd29d9a286c92c8e9e605 100644 (file)
@@ -734,7 +734,7 @@ void __init print_memory_map(char *who)
                case E820_NVS:
                                printk("(ACPI NVS)\n");
                                break;
-               default:        printk("type %lu\n", e820.map[i].type);
+               default:        printk("type %u\n", e820.map[i].type);
                                break;
                }
        }
index 698c24fe482eef9085fd380233b9364333581c14..2d61e65eeb504164318c0c9e0b839b2a52808e2b 100644 (file)
@@ -102,19 +102,10 @@ static unsigned int highmem_pages = -1;
 /*
  * Setup options
  */
-struct drive_info_struct { char dummy[32]; } drive_info;
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || \
-    defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)
-EXPORT_SYMBOL(drive_info);
-#endif
 struct screen_info screen_info;
 EXPORT_SYMBOL(screen_info);
 struct apm_info apm_info;
 EXPORT_SYMBOL(apm_info);
-struct sys_desc_table_struct {
-       unsigned short length;
-       unsigned char table[0];
-};
 struct edid_info edid_info;
 EXPORT_SYMBOL_GPL(edid_info);
 struct ist_info ist_info;
@@ -134,7 +125,7 @@ unsigned long saved_videomode;
 
 static char __initdata command_line[COMMAND_LINE_SIZE];
 
-unsigned char __initdata boot_params[PARAM_SIZE];
+struct boot_params __initdata boot_params;
 
 #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
 struct edd edd;
@@ -528,7 +519,6 @@ void __init setup_arch(char **cmdline_p)
 #endif
 
        ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
-       drive_info = DRIVE_INFO;
        screen_info = SCREEN_INFO;
        edid_info = EDID_INFO;
        apm_info.bios = APM_BIOS_INFO;
index 88baed1e7e83a1469ecc33f1ed5e6e1c17a00af4..0b2954534b8e71f3216f23a7ae8c933e0bc48d7c 100644 (file)
@@ -941,17 +941,6 @@ exit:
 }
 #endif
 
-static void smp_tune_scheduling(void)
-{
-       if (cpu_khz) {
-               /* cache size in kB */
-               long cachesize = boot_cpu_data.x86_cache_size;
-
-               if (cachesize > 0)
-                       max_cache_size = cachesize * 1024;
-       }
-}
-
 /*
  * Cycle through the processors sending APIC IPIs to boot each.
  */
@@ -980,7 +969,6 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
        x86_cpu_to_apicid[0] = boot_cpu_physical_apicid;
 
        current_thread_info()->cpu = 0;
-       smp_tune_scheduling();
 
        set_cpu_sibling_map(0);
 
index f64b81f3033bcba88ff47d268e8819b93d938e47..ea63a30ca3e88daa1bca2975f3c9f98812d7dffc 100644 (file)
@@ -4,6 +4,7 @@
  * See comments there for proper credits.
  */
 
+#include <linux/sched.h>
 #include <linux/clocksource.h>
 #include <linux/workqueue.h>
 #include <linux/cpufreq.h>
@@ -106,8 +107,13 @@ unsigned long long sched_clock(void)
 
        /*
         * Fall back to jiffies if there's no TSC available:
+        * ( But note that we still use it if the TSC is marked
+        *   unstable. We do this because unlike Time Of Day,
+        *   the scheduler clock tolerates small errors and it's
+        *   very important for it to be as fast as the platform
+        *   can achive it. )
         */
-       if (unlikely(!tsc_enabled))
+       if (unlikely(!tsc_enabled && !tsc_unstable))
                /* No locking but a rare wrong value is not a big deal: */
                return (jiffies_64 - INITIAL_JIFFIES) * (1000000000 / HZ);
 
@@ -277,6 +283,7 @@ static struct clocksource clocksource_tsc = {
 
 void mark_tsc_unstable(char *reason)
 {
+       sched_clock_unstable_event();
        if (!tsc_unstable) {
                tsc_unstable = 1;
                tsc_enabled = 0;
diff --git a/arch/i386/kernel/verify_cpu.S b/arch/i386/kernel/verify_cpu.S
deleted file mode 100644 (file)
index f1d1eac..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-/* Check if CPU has some minimum CPUID bits
-   This runs in 16bit mode so that the caller can still use the BIOS
-   to output errors on the screen */
-#include <asm/cpufeature.h>
-#include <asm/msr.h>
-
-verify_cpu:
-       pushfl                          # Save caller passed flags
-       pushl   $0                      # Kill any dangerous flags
-       popfl
-
-#if CONFIG_X86_MINIMUM_CPU_MODEL >= 4
-       pushfl
-       pop     %eax
-       orl     $(1<<18),%eax           # try setting AC
-       push    %eax
-       popfl
-       pushfl
-       popl    %eax
-       testl   $(1<<18),%eax
-       jz      bad
-#endif
-#if REQUIRED_MASK1 != 0
-       pushfl                          # standard way to check for cpuid
-       popl    %eax
-       movl    %eax,%ebx
-       xorl    $0x200000,%eax
-       pushl   %eax
-       popfl
-       pushfl
-       popl    %eax
-       cmpl    %eax,%ebx
-       pushfl                          # standard way to check for cpuid
-       popl    %eax
-       movl    %eax,%ebx
-       xorl    $0x200000,%eax
-       pushl   %eax
-       popfl
-       pushfl
-       popl    %eax
-       cmpl    %eax,%ebx
-       jz      bad                     # REQUIRED_MASK1 != 0 requires CPUID
-
-       movl    $0x0,%eax               # See if cpuid 1 is implemented
-       cpuid
-       cmpl    $0x1,%eax
-       jb      bad                     # no cpuid 1
-
-#if REQUIRED_MASK1 & NEED_CMPXCHG64
-       /* Some VIA C3s need magic MSRs to enable CX64. Do this here */
-       cmpl    $0x746e6543,%ebx        # Cent
-       jne     1f
-       cmpl    $0x48727561,%edx        # aurH
-       jne     1f
-       cmpl    $0x736c7561,%ecx        # auls
-       jne     1f
-       movl    $1,%eax                 # check model
-       cpuid
-       movl    %eax,%ebx
-       shr     $8,%ebx
-       andl    $0xf,%ebx
-       cmp     $6,%ebx                 # check family == 6
-       jne     1f
-       shr     $4,%eax
-       andl    $0xf,%eax
-       cmpl    $6,%eax                 # check model >= 6
-       jb      1f
-       # assume models >= 6 all support this MSR
-       movl    $MSR_VIA_FCR,%ecx
-       rdmsr
-       orl     $((1<<1)|(1<<7)),%eax   # enable CMPXCHG64 and PGE
-       wrmsr
-1:
-#endif
-       movl    $0x1,%eax               # Does the cpu have what it takes
-       cpuid
-
-#if CONFIG_X86_MINIMUM_CPU_MODEL > 4
-#error add proper model checking here
-#endif
-
-       andl    $REQUIRED_MASK1,%edx
-       xorl    $REQUIRED_MASK1,%edx
-       jnz     bad
-#endif /* REQUIRED_MASK1 */
-
-       popfl
-       xor     %eax,%eax
-       ret
-
-bad:
-       popfl
-       movl    $1,%eax
-       ret
index 5199bd03254a58b0359f6efc6968db0daa369154..843b67acf43b9e43e194d577c0814b0319502e24 100644 (file)
@@ -23,13 +23,13 @@ static __init void lithium_init(void)
        set_fixmap(FIX_LI_PCIB, LI_PCI_B_PHYS);
 
        if ((li_pcia_read16(PCI_VENDOR_ID) != PCI_VENDOR_ID_SGI) ||
-           (li_pcia_read16(PCI_DEVICE_ID) != PCI_VENDOR_ID_SGI_LITHIUM)) {
+           (li_pcia_read16(PCI_DEVICE_ID) != PCI_DEVICE_ID_SGI_LITHIUM)) {
                printk(KERN_EMERG "Lithium hostbridge %c not found\n", 'A');
                panic("This machine is not SGI Visual Workstation 320/540");
        }
 
        if ((li_pcib_read16(PCI_VENDOR_ID) != PCI_VENDOR_ID_SGI) ||
-           (li_pcib_read16(PCI_DEVICE_ID) != PCI_VENDOR_ID_SGI_LITHIUM)) {
+           (li_pcib_read16(PCI_DEVICE_ID) != PCI_DEVICE_ID_SGI_LITHIUM)) {
                printk(KERN_EMERG "Lithium hostbridge %c not found\n", 'B');
                panic("This machine is not SGI Visual Workstation 320/540");
        }
index b95b42950ed447d2774fe2aac9e6e66830d91960..e7306dbf6c4273be26008c28cfc0c2fe5a7bc7bd 100644 (file)
@@ -118,12 +118,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, pci
 static void pci_fixup_via_northbridge_bug(struct pci_dev *d)
 {
        u8 v;
-       u8 revision;
        int where = 0x55;
        int mask = 0x1f; /* clear bits 5, 6, 7 by default */
 
-       pci_read_config_byte(d, PCI_REVISION_ID, &revision);
-
        if (d->device == PCI_DEVICE_ID_VIA_8367_0) {
                /* fix pci bus latency issues resulted by NB bios error
                   it appears on bug free^Wreduced kt266x's bios forces
@@ -133,8 +130,8 @@ static void pci_fixup_via_northbridge_bug(struct pci_dev *d)
                where = 0x95; /* the memory write queue timer register is 
                                different for the KT266x's: 0x95 not 0x55 */
        } else if (d->device == PCI_DEVICE_ID_VIA_8363_0 &&
-                       (revision == VIA_8363_KL133_REVISION_ID || 
-                       revision == VIA_8363_KM133_REVISION_ID)) {
+                       (d->revision == VIA_8363_KL133_REVISION_ID ||
+                       d->revision == VIA_8363_KM133_REVISION_ID)) {
                        mask = 0x3f; /* clear only bits 6 and 7; clearing bit 5
                                        causes screen corruption on the KL133/KM133 */
        }
@@ -142,7 +139,7 @@ static void pci_fixup_via_northbridge_bug(struct pci_dev *d)
        pci_read_config_byte(d, where, &v);
        if (v & ~mask) {
                printk(KERN_WARNING "Disabling VIA memory write queue (PCI ID %04x, rev %02x): [%02x] %02x & %02x -> %02x\n", \
-                       d->device, revision, where, v, mask, v & mask);
+                       d->device, d->revision, where, v, mask, v & mask);
                v &= mask;
                pci_write_config_byte(d, where, v);
        }
index de1bff6599690c89d9f4f290edcb167e70d79b82..db9ddff958416bd8e189cb0006f60a5fd9cbe4ce 100644 (file)
@@ -520,8 +520,10 @@ config PCI
          here unless you are using a simulator without PCI support.
 
 config PCI_DOMAINS
-       bool
-       default PCI
+       def_bool PCI
+
+config PCI_SYSCALL
+       def_bool PCI
 
 source "drivers/pci/pcie/Kconfig"
 
index 3274850cf2722f07726582c3d133f5c14229d475..74b1ccce4e848187f59df741e944d3edf054f444 100644 (file)
@@ -30,6 +30,7 @@
        .previous
 #define BRL_COND_FSYS_BUBBLE_DOWN(pr)                  \
 [1:](pr)brl.cond.sptk 0;                               \
+       ;;                                              \
        .xdata4 ".data.patch.brl_fsys_bubble_down", 1b-.
 
 GLOBAL_ENTRY(__kernel_syscall_via_break)
index 1ead5ea6c5ce71afaf259eb6629abc8f65a0c11e..4b5daa3cc0feab6723764d67a7c221e74e5b3eb3 100644 (file)
@@ -57,6 +57,9 @@
  *
  * 2006-09-15 Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
  *           Add printing support for MCA/INIT.
+ *
+ * 2007-04-27 Russ Anderson <rja@sgi.com>
+ *           Support multiple cpus going through OS_MCA in the same event.
  */
 #include <linux/types.h>
 #include <linux/init.h>
@@ -96,7 +99,6 @@
 #endif
 
 /* Used by mca_asm.S */
-u32                            ia64_mca_serialize;
 DEFINE_PER_CPU(u64, ia64_mca_data); /* == __per_cpu_mca[smp_processor_id()] */
 DEFINE_PER_CPU(u64, ia64_mca_per_cpu_pte); /* PTE to map per-CPU area */
 DEFINE_PER_CPU(u64, ia64_mca_pal_pte);     /* PTE to map PAL code */
@@ -963,11 +965,12 @@ ia64_mca_modify_original_stack(struct pt_regs *regs,
                goto no_mod;
        }
 
+       if (r13 != sos->prev_IA64_KR_CURRENT) {
+               msg = "inconsistent previous current and r13";
+               goto no_mod;
+       }
+
        if (!mca_recover_range(ms->pmsa_iip)) {
-               if (r13 != sos->prev_IA64_KR_CURRENT) {
-                       msg = "inconsistent previous current and r13";
-                       goto no_mod;
-               }
                if ((r12 - r13) >= KERNEL_STACK_SIZE) {
                        msg = "inconsistent r12 and r13";
                        goto no_mod;
@@ -1187,6 +1190,13 @@ all_in:
  *     further MCA logging is enabled by clearing logs.
  *     Monarch also has the duty of sending wakeup-IPIs to pull the
  *     slave processors out of rendezvous spinloop.
+ *
+ *     If multiple processors call into OS_MCA, the first will become
+ *     the monarch.  Subsequent cpus will be recorded in the mca_cpu
+ *     bitmask.  After the first monarch has processed its MCA, it
+ *     will wake up the next cpu in the mca_cpu bitmask and then go
+ *     into the rendezvous loop.  When all processors have serviced
+ *     their MCA, the last monarch frees up the rest of the processors.
  */
 void
 ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
@@ -1196,16 +1206,32 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
        struct task_struct *previous_current;
        struct ia64_mca_notify_die nd =
                { .sos = sos, .monarch_cpu = &monarch_cpu };
+       static atomic_t mca_count;
+       static cpumask_t mca_cpu;
 
+       if (atomic_add_return(1, &mca_count) == 1) {
+               monarch_cpu = cpu;
+               sos->monarch = 1;
+       } else {
+               cpu_set(cpu, mca_cpu);
+               sos->monarch = 0;
+       }
        mprintk(KERN_INFO "Entered OS MCA handler. PSP=%lx cpu=%d "
                "monarch=%ld\n", sos->proc_state_param, cpu, sos->monarch);
 
        previous_current = ia64_mca_modify_original_stack(regs, sw, sos, "MCA");
-       monarch_cpu = cpu;
+
        if (notify_die(DIE_MCA_MONARCH_ENTER, "MCA", regs, (long)&nd, 0, 0)
                        == NOTIFY_STOP)
                ia64_mca_spin(__FUNCTION__);
-       ia64_wait_for_slaves(cpu, "MCA");
+       if (sos->monarch) {
+               ia64_wait_for_slaves(cpu, "MCA");
+       } else {
+               ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_CONCURRENT_MCA;
+               while (cpu_isset(cpu, mca_cpu))
+                       cpu_relax();    /* spin until monarch wakes us */
+               ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE;
+        }
 
        /* Wakeup all the processors which are spinning in the rendezvous loop.
         * They will leave SAL, then spin in the OS with interrupts disabled
@@ -1244,6 +1270,26 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
                        == NOTIFY_STOP)
                ia64_mca_spin(__FUNCTION__);
 
+
+       if (atomic_dec_return(&mca_count) > 0) {
+               int i;
+
+               /* wake up the next monarch cpu,
+                * and put this cpu in the rendez loop.
+                */
+               ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_CONCURRENT_MCA;
+               for_each_online_cpu(i) {
+                       if (cpu_isset(i, mca_cpu)) {
+                               monarch_cpu = i;
+                               cpu_clear(i, mca_cpu);  /* wake next cpu */
+                               while (monarch_cpu != -1)
+                                       cpu_relax();    /* spin until last cpu leaves */
+                               ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE;
+                               set_curr_task(cpu, previous_current);
+                               return;
+                       }
+               }
+       }
        set_curr_task(cpu, previous_current);
        monarch_cpu = -1;
 }
index 8c9c26aa6ae092e130f93a4076025d17a297ab92..0f5965fcdf85133fbf0c455f714dcbea091eea2d 100644 (file)
@@ -133,14 +133,6 @@ ia64_do_tlb_purge:
 //StartMain////////////////////////////////////////////////////////////////////
 
 ia64_os_mca_dispatch:
-       // Serialize all MCA processing
-       mov     r3=1;;
-       LOAD_PHYSICAL(p0,r2,ia64_mca_serialize);;
-ia64_os_mca_spin:
-       xchg4   r4=[r2],r3;;
-       cmp.ne  p6,p0=r4,r0
-(p6)   br ia64_os_mca_spin
-
        mov r3=IA64_MCA_CPU_MCA_STACK_OFFSET    // use the MCA stack
        LOAD_PHYSICAL(p0,r2,1f)                 // return address
        mov r19=1                               // All MCA events are treated as monarch (for now)
@@ -291,10 +283,6 @@ END(ia64_os_mca_virtual_begin)
 
        mov             b0=r12                  // SAL_CHECK return address
 
-       // release lock
-       LOAD_PHYSICAL(p0,r3,ia64_mca_serialize);;
-       st4.rel         [r3]=r0
-
        br              b0
 
 //EndMain//////////////////////////////////////////////////////////////////////
index f2d4900751ba9375dc8a7afa5cec7c1f2573f5d4..3bccb06c8d216cc1439c0f0081e6bacce2668035 100644 (file)
@@ -40,7 +40,11 @@ GLOBAL_ENTRY(mca_handler_bhhook)
        mov     b6=loc1
        ;;
        mov     loc1=rp
-       ssm     psr.i | psr.ic
+       ssm     psr.ic
+       ;;
+       srlz.i
+       ;;
+       ssm     psr.i
        br.call.sptk.many rp=b6         // does not return ...
        ;;
        mov     ar.pfs=loc0
index af73b8dfde282c0c91f84b3f8da062327d18a069..fa40cba433500df6e7288903eeab205ce283f54d 100644 (file)
@@ -513,7 +513,8 @@ copy_thread (int nr, unsigned long clone_flags,
 static void
 do_copy_task_regs (struct task_struct *task, struct unw_frame_info *info, void *arg)
 {
-       unsigned long mask, sp, nat_bits = 0, ip, ar_rnat, urbs_end, cfm;
+       unsigned long mask, sp, nat_bits = 0, ar_rnat, urbs_end, cfm;
+       unsigned long uninitialized_var(ip);    /* GCC be quiet */
        elf_greg_t *dst = arg;
        struct pt_regs *pt;
        char nat;
index eaa6a24bc0b6e61b284d38aef67fa2db6e31f1c2..188fb73c68456e3e2f1bd70e8f947b1b0754f869 100644 (file)
@@ -805,7 +805,6 @@ static void __cpuinit
 get_max_cacheline_size (void)
 {
        unsigned long line_size, max = 1;
-       unsigned int cache_size = 0;
        u64 l, levels, unique_caches;
         pal_cache_config_info_t cci;
         s64 status;
@@ -835,8 +834,6 @@ get_max_cacheline_size (void)
                line_size = 1 << cci.pcci_line_size;
                if (line_size > max)
                        max = line_size;
-               if (cache_size < cci.pcci_cache_size)
-                       cache_size = cci.pcci_cache_size;
                if (!cci.pcci_unified) {
                        status = ia64_pal_cache_config_info(l,
                                                    /* cache_type (instruction)= */ 1,
@@ -853,9 +850,6 @@ get_max_cacheline_size (void)
                        ia64_i_cache_stride_shift = cci.pcci_stride;
        }
   out:
-#ifdef CONFIG_SMP
-       max_cache_size = max(max_cache_size, cache_size);
-#endif
        if (max > ia64_max_cacheline_size)
                ia64_max_cacheline_size = max;
 }
index fa4e6d4810f3cc2c1c8e6c74fd431e79fe53a350..1682fc639038e79f64e5a1e1cb96ad846e843035 100644 (file)
@@ -175,7 +175,7 @@ EXPORT_SYMBOL(flush_tlb_range);
 void __devinit
 ia64_tlb_init (void)
 {
-       ia64_ptce_info_t ptce_info;
+       ia64_ptce_info_t uninitialized_var(ptce_info); /* GCC be quiet */
        unsigned long tr_pgbits;
        long status;
 
index 73696b4a2eed42caafc4d7414f8ae38c6c3a6922..07d0e92742c8ee604585a526668fd0f0baac8d60 100644 (file)
@@ -591,6 +591,9 @@ int
 pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma,
                     enum pci_mmap_state mmap_state, int write_combine)
 {
+       unsigned long size = vma->vm_end - vma->vm_start;
+       pgprot_t prot;
+
        /*
         * I/O space cannot be accessed via normal processor loads and
         * stores on this platform.
@@ -604,15 +607,24 @@ pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma,
                 */
                return -EINVAL;
 
+       if (!valid_mmap_phys_addr_range(vma->vm_pgoff, size))
+               return -EINVAL;
+
+       prot = phys_mem_access_prot(NULL, vma->vm_pgoff, size,
+                                   vma->vm_page_prot);
+
        /*
-        * Leave vm_pgoff as-is, the PCI space address is the physical
-        * address on this platform.
+        * If the user requested WC, the kernel uses UC or WC for this region,
+        * and the chipset supports WC, we can use WC. Otherwise, we have to
+        * use the same attribute the kernel uses.
         */
-       if (write_combine && efi_range_is_wc(vma->vm_start,
-                                            vma->vm_end - vma->vm_start))
+       if (write_combine &&
+           ((pgprot_val(prot) & _PAGE_MA_MASK) == _PAGE_MA_UC ||
+            (pgprot_val(prot) & _PAGE_MA_MASK) == _PAGE_MA_WC) &&
+           efi_range_is_wc(vma->vm_start, vma->vm_end - vma->vm_start))
                vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
        else
-               vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+               vma->vm_page_prot = prot;
 
        if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
                             vma->vm_end - vma->vm_start, vma->vm_page_prot))
index c6216f454ffb5ee81d2246bb05361a073ff51268..3c7178f5dce82bad1492cbc006579db7f18ad98e 100644 (file)
@@ -418,7 +418,7 @@ sn_acpi_slot_fixup(struct pci_dev *dev)
        void __iomem *addr;
        struct pcidev_info *pcidev_info = NULL;
        struct sn_irq_info *sn_irq_info = NULL;
-       size_t size;
+       size_t image_size, size;
 
        if (sn_acpi_get_pcidev_info(dev, &pcidev_info, &sn_irq_info)) {
                panic("%s:  Failure obtaining pcidev_info for %s\n",
@@ -428,17 +428,16 @@ sn_acpi_slot_fixup(struct pci_dev *dev)
        if (pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE]) {
                /*
                 * A valid ROM image exists and has been shadowed by the
-                * PROM. Setup the pci_dev ROM resource to point to
-                * the shadowed copy.
+                * PROM. Setup the pci_dev ROM resource with the address
+                * of the shadowed copy, and the actual length of the ROM image.
                 */
-               size = dev->resource[PCI_ROM_RESOURCE].end -
-                               dev->resource[PCI_ROM_RESOURCE].start;
-               addr =
-                    ioremap(pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE],
-                            size);
+               size = pci_resource_len(dev, PCI_ROM_RESOURCE);
+               addr = ioremap(pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE],
+                              size);
+               image_size = pci_get_rom_size(addr, size);
                dev->resource[PCI_ROM_RESOURCE].start = (unsigned long) addr;
                dev->resource[PCI_ROM_RESOURCE].end =
-                                               (unsigned long) addr + size;
+                                       (unsigned long) addr + image_size - 1;
                dev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_BIOS_COPY;
        }
        sn_pci_fixup_slot(dev, pcidev_info, sn_irq_info);
index 6b10e5d284883380a284a1d2616e1aa2ec834fd2..906b93674b7604e236099c42f68cd8228a1876ed 100644 (file)
@@ -259,9 +259,23 @@ sn_io_slot_fixup(struct pci_dev *dev)
                        insert_resource(&ioport_resource, &dev->resource[idx]);
                else
                        insert_resource(&iomem_resource, &dev->resource[idx]);
-               /* If ROM, mark as shadowed in PROM */
-               if (idx == PCI_ROM_RESOURCE)
-                       dev->resource[idx].flags |= IORESOURCE_ROM_BIOS_COPY;
+               /*
+                * If ROM, set the actual ROM image size, and mark as
+                * shadowed in PROM.
+                */
+               if (idx == PCI_ROM_RESOURCE) {
+                       size_t image_size;
+                       void __iomem *rom;
+
+                       rom = ioremap(pci_resource_start(dev, PCI_ROM_RESOURCE),
+                                     size + 1);
+                       image_size = pci_get_rom_size(rom, size + 1);
+                       dev->resource[PCI_ROM_RESOURCE].end =
+                               dev->resource[PCI_ROM_RESOURCE].start +
+                               image_size - 1;
+                       dev->resource[PCI_ROM_RESOURCE].flags |=
+                                                IORESOURCE_ROM_BIOS_COPY;
+               }
        }
        /* Create a pci_window in the pci_controller struct for
         * each device resource.
index 493380b2c05fd1b6756ad9edb711c4992125f5e7..5a289e4de8383eb7f286ed99fe7d0d1c80c36df5 100644 (file)
@@ -369,7 +369,7 @@ static void tio_corelet_reset(nasid_t nasid, int corelet)
 
 static int is_fpga_tio(int nasid, int *bt)
 {
-       u16 ioboard_type;
+       u16 uninitialized_var(ioboard_type);    /* GCC be quiet */
        s64 rc;
 
        rc = ia64_sn_sysctl_ioboard_get(nasid, &ioboard_type);
index b42bfcae6f911108f364473ae7e3d7a7fcf80b26..42485ad50ceb3aeea3de6312ae22785cf0a994f7 100644 (file)
@@ -80,7 +80,7 @@ static int sal_pcibr_error_interrupt(struct pcibus_info *soft)
 u16 sn_ioboard_to_pci_bus(struct pci_bus *pci_bus)
 {
        s64 rc;
-       u16 ioboard;
+       u16 uninitialized_var(ioboard);         /* GCC be quiet */
        nasid_t nasid = NASID_GET(SN_PCIBUS_BUSSOFT(pci_bus)->bs_base);
 
        rc = ia64_sn_sysctl_ioboard_get(nasid, &ioboard);
index 73455389257afa3f4bcb4341aa83947aa7e93e50..5c863bcd5614e4076d4417e294458e4bbd5cae8f 100644 (file)
@@ -15,6 +15,29 @@ choice
        prompt "System type"
        default SGI_IP22
 
+config LEMOTE_FULONG
+       bool "Lemote Fulong mini-PC"
+       select ARCH_SPARSEMEM_ENABLE
+       select SYS_HAS_CPU_LOONGSON2
+       select DMA_NONCOHERENT
+       select BOOT_ELF32
+       select BOARD_SCACHE
+       select HAVE_STD_PC_SERIAL_PORT
+       select HW_HAS_PCI
+       select I8259
+       select ISA
+       select IRQ_CPU
+       select SYS_SUPPORTS_32BIT_KERNEL
+       select SYS_SUPPORTS_64BIT_KERNEL
+       select SYS_SUPPORTS_LITTLE_ENDIAN
+       select SYS_SUPPORTS_HIGHMEM
+       select SYS_HAS_EARLY_PRINTK
+       select GENERIC_HARDIRQS_NO__DO_IRQ
+       select CPU_HAS_WB
+       help
+         Lemote Fulong mini-PC board based on the Chinese Loongson-2E CPU and
+         an FPGA northbridge
+
 config MACH_ALCHEMY
        bool "Alchemy processor based machines"
 
@@ -63,7 +86,7 @@ config MACH_DECSTATION
        bool "DECstations"
        select BOOT_ELF32
        select DMA_NONCOHERENT
-       select SYS_HAS_EARLY_PRINTK
+       select NO_IOPORT
        select IRQ_CPU
        select SYS_HAS_CPU_R3000
        select SYS_HAS_CPU_R4X00
@@ -88,33 +111,15 @@ config MACH_DECSTATION
 
          otherwise choose R3000.
 
-config MIPS_EV64120
-       bool "Galileo EV64120 Evaluation board (EXPERIMENTAL)"
-       depends on EXPERIMENTAL
-       select DMA_NONCOHERENT
-       select HW_HAS_PCI
-       select PCI_GT64XXX_PCI0
-       select SYS_HAS_CPU_R5000
-       select SYS_SUPPORTS_32BIT_KERNEL
-       select SYS_SUPPORTS_64BIT_KERNEL
-       select SYS_SUPPORTS_BIG_ENDIAN
-       select SYS_SUPPORTS_KGDB
-       help
-         This is an evaluation board based on the Galileo GT-64120
-         single-chip system controller that contains a MIPS R5000 compatible
-         core running at 75/100MHz.  Their website is located at
-         <http://www.marvell.com/>.  Say Y here if you wish to build a
-         kernel for this platform.
-
 config MACH_JAZZ
        bool "Jazz family of machines"
        select ARC
        select ARC32
        select ARCH_MAY_HAVE_PC_FDC
        select GENERIC_ISA_DMA
-       select I8253
        select I8259
        select ISA
+       select PCSPEAKER
        select SYS_HAS_CPU_R4X00
        select SYS_SUPPORTS_32BIT_KERNEL
        select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
@@ -126,20 +131,6 @@ config MACH_JAZZ
         Members include the Acer PICA, MIPS Magnum 4000, MIPS Millenium and
         Olivetti M700-10 workstations.
 
-config LASAT
-       bool "LASAT Networks platforms"
-       select DMA_NONCOHERENT
-       select SYS_HAS_EARLY_PRINTK
-       select HW_HAS_PCI
-       select PCI_GT64XXX_PCI0
-       select MIPS_NILE4
-       select R5000_CPU_SCACHE
-       select SYS_HAS_CPU_R5000
-       select SYS_SUPPORTS_32BIT_KERNEL
-       select SYS_SUPPORTS_64BIT_KERNEL if BROKEN
-       select SYS_SUPPORTS_LITTLE_ENDIAN
-       select GENERIC_HARDIRQS_NO__DO_IRQ
-
 config MIPS_ATLAS
        bool "MIPS Atlas board"
        select BOOT_ELF32
@@ -173,7 +164,6 @@ config MIPS_MALTA
        bool "MIPS Malta board"
        select ARCH_MAY_HAVE_PC_FDC
        select BOOT_ELF32
-       select HAVE_STD_PC_SERIAL_PORT
        select DMA_NONCOHERENT
        select GENERIC_ISA_DMA
        select IRQ_CPU
@@ -246,11 +236,13 @@ config MIPS_SIM
        select DMA_NONCOHERENT
        select SYS_HAS_EARLY_PRINTK
        select IRQ_CPU
+       select BOOT_RAW
        select SYS_HAS_CPU_MIPS32_R1
        select SYS_HAS_CPU_MIPS32_R2
        select SYS_HAS_EARLY_PRINTK
        select SYS_SUPPORTS_32BIT_KERNEL
        select SYS_SUPPORTS_BIG_ENDIAN
+       select SYS_SUPPORTS_MULTITHREADING
        select SYS_SUPPORTS_LITTLE_ENDIAN
        help
          This option enables support for MIPS Technologies MIPSsim software
@@ -274,43 +266,6 @@ config MOMENCO_OCELOT
          The Ocelot is a MIPS-based Single Board Computer (SBC) made by
          Momentum Computer <http://www.momenco.com/>.
 
-config MOMENCO_OCELOT_3
-       bool "Momentum Ocelot-3 board"
-       select BOOT_ELF32
-       select DMA_NONCOHERENT
-       select HW_HAS_PCI
-       select IRQ_CPU
-       select IRQ_CPU_RM7K
-       select IRQ_MV64340
-       select PCI_MARVELL
-       select RM7000_CPU_SCACHE
-       select SWAP_IO_SPACE
-       select SYS_HAS_CPU_RM9000
-       select SYS_SUPPORTS_32BIT_KERNEL
-       select SYS_SUPPORTS_64BIT_KERNEL
-       select SYS_SUPPORTS_BIG_ENDIAN
-       help
-         The Ocelot-3 is based off Discovery III System Controller and
-         PMC-Sierra Rm79000 core.
-
-config MOMENCO_OCELOT_C
-       bool "Momentum Ocelot-C board"
-       select DMA_NONCOHERENT
-       select HW_HAS_PCI
-       select IRQ_CPU
-       select IRQ_MV64340
-       select PCI_MARVELL
-       select RM7000_CPU_SCACHE
-       select SWAP_IO_SPACE
-       select SYS_HAS_CPU_RM7000
-       select SYS_SUPPORTS_32BIT_KERNEL
-       select SYS_SUPPORTS_64BIT_KERNEL
-       select SYS_SUPPORTS_BIG_ENDIAN
-       select GENERIC_HARDIRQS_NO__DO_IRQ
-       help
-         The Ocelot is a MIPS-based Single Board Computer (SBC) made by
-         Momentum Computer <http://www.momenco.com/>.
-
 config PNX8550_JBS
        bool "Philips PNX8550 based JBS board"
        select PNX8550
@@ -346,6 +301,27 @@ config MACH_VR41XX
        select SYS_HAS_CPU_VR41XX
        select GENERIC_HARDIRQS_NO__DO_IRQ
 
+config PMC_MSP
+       bool "PMC-Sierra MSP chipsets"
+       depends on EXPERIMENTAL
+       select DMA_NONCOHERENT
+       select SWAP_IO_SPACE
+       select NO_EXCEPT_FILL
+       select BOOT_RAW
+       select SYS_HAS_CPU_MIPS32_R1
+       select SYS_HAS_CPU_MIPS32_R2
+       select SYS_SUPPORTS_32BIT_KERNEL
+       select SYS_SUPPORTS_BIG_ENDIAN
+       select SYS_SUPPORTS_KGDB
+       select IRQ_CPU
+       select SERIAL_8250
+       select SERIAL_8250_CONSOLE
+       help
+         This adds support for the PMC-Sierra family of Multi-Service
+         Processor System-On-A-Chips.  These parts include a number
+         of integrated peripherals, interfaces and DSPs in addition to
+         a variety of MIPS cores.
+
 config PMC_YOSEMITE
        bool "PMC-Sierra Yosemite eval board"
        select DMA_COHERENT
@@ -371,9 +347,9 @@ config QEMU
        select DMA_COHERENT
        select GENERIC_ISA_DMA
        select HAVE_STD_PC_SERIAL_PORT
-       select I8253
        select I8259
        select ISA
+       select PCSPEAKER
        select SWAP_IO_SPACE
        select SYS_HAS_CPU_MIPS32_R1
        select SYS_SUPPORTS_32BIT_KERNEL
@@ -450,8 +426,7 @@ config SGI_IP27
          here.
 
 config SGI_IP32
-       bool "SGI IP32 (O2) (EXPERIMENTAL)"
-       depends on EXPERIMENTAL
+       bool "SGI IP32 (O2)"
        select ARC
        select ARC32
        select BOOT_ELF32
@@ -587,9 +562,9 @@ config SNI_RM
        select HW_HAS_EISA
        select HW_HAS_PCI
        select IRQ_CPU
-       select I8253
        select I8259
        select ISA
+       select PCSPEAKER
        select SWAP_IO_SPACE if CPU_BIG_ENDIAN
        select SYS_HAS_CPU_R4X00
        select SYS_HAS_CPU_R5000
@@ -652,6 +627,7 @@ config TOSHIBA_RBTX4938
        select SYS_SUPPORTS_BIG_ENDIAN
        select SYS_SUPPORTS_KGDB
        select GENERIC_HARDIRQS_NO__DO_IRQ
+       select GENERIC_GPIO
        help
          This Toshiba board is based on the TX4938 processor. Say Y here to
          support this machine type
@@ -660,9 +636,7 @@ endchoice
 
 source "arch/mips/au1000/Kconfig"
 source "arch/mips/ddb5xxx/Kconfig"
-source "arch/mips/gt64120/ev64120/Kconfig"
 source "arch/mips/jazz/Kconfig"
-source "arch/mips/lasat/Kconfig"
 source "arch/mips/pmc-sierra/Kconfig"
 source "arch/mips/sgi-ip27/Kconfig"
 source "arch/mips/sibyte/Kconfig"
@@ -721,6 +695,9 @@ config ARC
 config ARCH_MAY_HAVE_PC_FDC
        bool
 
+config BOOT_RAW
+       bool
+
 config DMA_COHERENT
        bool
 
@@ -768,16 +745,19 @@ config MIPS_BONITO64
 config MIPS_MSC
        bool
 
-config MIPS_NILE4
-       bool
-
 config MIPS_DISABLE_OBSOLETE_IDE
        bool
 
+config NO_IOPORT
+       def_bool n
+
 config GENERIC_ISA_DMA_SUPPORT_BROKEN
        bool
        select ZONE_DMA
 
+config GENERIC_GPIO
+       bool
+
 #
 # Endianess selection.  Sufficiently obscure so many users don't know what to
 # answer,so we try hard to limit the available choices.  Also the use of a
@@ -821,7 +801,10 @@ config IRQ_CPU_RM7K
 config IRQ_CPU_RM9K
        bool
 
-config IRQ_MV64340
+config IRQ_MSP_SLP
+       bool
+
+config IRQ_MSP_CIC
        bool
 
 config DDB5XXX_COMMON
@@ -834,6 +817,9 @@ config MIPS_BOARDS_GEN
 config PCI_GT64XXX_PCI0
        bool
 
+config NO_EXCEPT_FILL
+       bool
+
 config MIPS_TX3927
        bool
        select HAS_TXX9_SERIAL
@@ -841,14 +827,6 @@ config MIPS_TX3927
 config MIPS_RM9122
        bool
        select SERIAL_RM9000
-       select GPI_RM9000
-       select WDT_RM9000
-
-config PCI_MARVELL
-       bool
-
-config SERIAL_RM9000
-       bool
 
 config PNX8550
        bool
@@ -863,6 +841,7 @@ config SOC_PNX8550
        select SYS_SUPPORTS_32BIT_KERNEL
        select GENERIC_HARDIRQS_NO__DO_IRQ
        select SYS_SUPPORTS_KGDB
+       select GENERIC_GPIO
 
 config SWAP_IO_SPACE
        bool
@@ -875,31 +854,17 @@ config EMMA2RH
 config SERIAL_RM9000
        bool
 
-config GPI_RM9000
-       bool
-
-config WDT_RM9000
-       bool
-
 #
 # Unfortunately not all GT64120 systems run the chip at the same clock.
 # As the user for the clock rate and try to minimize the available options.
 #
 choice
        prompt "Galileo Chip Clock"
-       #default SYSCLK_83 if MIPS_EV64120
-       depends on MIPS_EV64120 || MOMENCO_OCELOT
-       default SYSCLK_83 if MIPS_EV64120
+       depends on MOMENCO_OCELOT
        default SYSCLK_100 if MOMENCO_OCELOT
 
-config SYSCLK_75
-       bool "75" if MIPS_EV64120
-
-config SYSCLK_83
-       bool "83.3" if MIPS_EV64120
-
 config SYSCLK_100
-       bool "100" if MIPS_EV64120 || MOMENCO_OCELOT
+       bool "100" if MOMENCO_OCELOT
 
 endchoice
 
@@ -911,8 +876,9 @@ config BOOT_ELF32
 
 config MIPS_L1_CACHE_SHIFT
        int
-       default "4" if MACH_DECSTATION || SNI_RM
-       default "7" if SGI_IP27
+       default "4" if MACH_DECSTATION
+       default "7" if SGI_IP27 || SNI_RM
+       default "4" if PMC_MSP4200_EVAL
        default "5"
 
 config HAVE_STD_PC_SERIAL_PORT
@@ -944,6 +910,16 @@ choice
        prompt "CPU type"
        default CPU_R4X00
 
+config CPU_LOONGSON2
+       bool "Loongson 2"
+       depends on SYS_HAS_CPU_LOONGSON2
+       select CPU_SUPPORTS_32BIT_KERNEL
+       select CPU_SUPPORTS_64BIT_KERNEL
+       select CPU_SUPPORTS_HIGHMEM
+       help
+         The Loongson 2E processor implements the MIPS III instruction set
+         with many extensions.
+
 config CPU_MIPS32_R1
        bool "MIPS32 Release 1"
        depends on SYS_HAS_CPU_MIPS32_R1
@@ -1154,6 +1130,9 @@ config CPU_SB1
 
 endchoice
 
+config SYS_HAS_CPU_LOONGSON2
+       bool
+
 config SYS_HAS_CPU_MIPS32_R1
        bool
 
@@ -1425,6 +1404,19 @@ config MIPS_MT_SMTC_INSTANT_REPLAY
          it off), but ensures that IPIs are handled promptly even under
          heavy I/O interrupt load.
 
+config MIPS_MT_SMTC_IM_BACKSTOP
+       bool "Use per-TC register bits as backstop for inhibited IM bits"
+       depends on MIPS_MT_SMTC
+       default y
+       help
+         To support multiple TC microthreads acting as "CPUs" within
+         a VPE, VPE-wide interrupt mask bits must be specially manipulated
+         during interrupt handling. To support legacy drivers and interrupt
+         controller management code, SMTC has a "backstop" to track and
+         if necessary restore the interrupt mask. This has some performance
+         impact on interrupt service overhead. Disable it only if you know
+         what you are doing.
+
 config MIPS_VPE_LOADER_TOM
        bool "Load VPE program into memory hidden from linux"
        depends on MIPS_VPE_LOADER
@@ -1488,6 +1480,15 @@ config CPU_HAS_SMARTMIPS
 config CPU_HAS_WB
        bool
 
+config 64BIT_CONTEXT
+       bool "Save 64bit integer registers"
+       depends on 32BIT && CPU_LOONGSON2
+       help
+         Loongson2 CPU is 64bit , when used in 32BIT mode, its integer
+         registers can still be accessed as 64bit, mainly for multimedia
+         instructions. We must have all 64bit save/restored to make sure
+         those instructions to get correct result.
+
 #
 # Vectored interrupt mode is an R2 feature
 #
@@ -1863,7 +1864,7 @@ config MMU
        bool
        default y
 
-config I8253
+config PCSPEAKER
        bool
 
 source "drivers/pcmcia/Kconfig"
index f450066b62419e8efd26e6224bd6ef23e7a5f155..20d19c9b776137821d2f74ab7cee3551ce97bb0a 100644 (file)
@@ -118,6 +118,7 @@ cflags-$(CONFIG_CPU_R4300)  += -march=r4300 -Wa,--trap
 cflags-$(CONFIG_CPU_VR41XX)    += -march=r4100 -Wa,--trap
 cflags-$(CONFIG_CPU_R4X00)     += -march=r4600 -Wa,--trap
 cflags-$(CONFIG_CPU_TX49XX)    += -march=r4600 -Wa,--trap
+cflags-$(CONFIG_CPU_LOONGSON2) += -march=r4600 -Wa,--trap
 cflags-$(CONFIG_CPU_MIPS32_R1) += $(call cc-option,-march=mips32,-mips32 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \
                        -Wa,-mips32 -Wa,--trap
 cflags-$(CONFIG_CPU_MIPS32_R2) += $(call cc-option,-march=mips32r2,-mips32r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \
@@ -282,14 +283,6 @@ libs-$(CONFIG_MACH_DECSTATION)     += arch/mips/dec/prom/
 load-$(CONFIG_MACH_DECSTATION) += 0xffffffff80040000
 CLEAN_FILES                    += drivers/tc/lk201-map.c
 
-#
-# Galileo EV64120 Board
-#
-core-$(CONFIG_MIPS_EV64120)    += arch/mips/gt64120/ev64120/
-core-$(CONFIG_MIPS_EV64120)    += arch/mips/gt64120/common/
-cflags-$(CONFIG_MIPS_EV64120)  += -Iinclude/asm-mips/mach-ev64120
-load-$(CONFIG_MIPS_EV64120)    += 0xffffffff80100000
-
 #
 # Wind River PPMC Board (4KC + GT64120)
 #
@@ -297,6 +290,13 @@ core-$(CONFIG_WR_PPMC)             += arch/mips/gt64120/wrppmc/
 cflags-$(CONFIG_WR_PPMC)               += -Iinclude/asm-mips/mach-wrppmc
 load-$(CONFIG_WR_PPMC)         += 0xffffffff80100000
 
+#
+# lemote fulong mini-PC board
+#
+core-$(CONFIG_LEMOTE_FULONG) +=arch/mips/lemote/lm2e/
+load-$(CONFIG_LEMOTE_FULONG) +=0xffffffff80100000
+cflags-$(CONFIG_LEMOTE_FULONG) += -Iinclude/asm-mips/mach-lemote
+
 #
 # For all MIPS, Inc. eval boards
 #
@@ -327,7 +327,7 @@ load-$(CONFIG_MIPS_SEAD)    += 0xffffffff80100000
 #
 # MIPS SIM
 #
-core-$(CONFIG_MIPS_SIM)                += arch/mips/mips-boards/sim/
+core-$(CONFIG_MIPS_SIM)                += arch/mips/mipssim/
 cflags-$(CONFIG_MIPS_SIM)      += -Iinclude/asm-mips/mach-sim
 load-$(CONFIG_MIPS_SIM)                += 0x80100000
 
@@ -343,12 +343,12 @@ cflags-$(CONFIG_MOMENCO_OCELOT)   += -Iinclude/asm-mips/mach-ocelot
 load-$(CONFIG_MOMENCO_OCELOT)  += 0xffffffff80100000
 
 #
-# Momentum Ocelot-C and -CS boards
+# PMC-Sierra MSP SOCs
 #
-# The Ocelot-C[S] setup.o must be linked early - it does the ioremap() for the
-# mips_io_port_base.
-core-$(CONFIG_MOMENCO_OCELOT_C)        += arch/mips/momentum/ocelot_c/
-load-$(CONFIG_MOMENCO_OCELOT_C)        += 0xffffffff80100000
+core-$(CONFIG_PMC_MSP)         += arch/mips/pmc-sierra/msp71xx/
+cflags-$(CONFIG_PMC_MSP)       += -Iinclude/asm-mips/pmc-sierra/msp71xx \
+                                       -mno-branch-likely
+load-$(CONFIG_PMC_MSP)         += 0xffffffff80100000
 
 #
 # PMC-Sierra Yosemite
@@ -364,13 +364,6 @@ core-$(CONFIG_QEMU)                += arch/mips/qemu/
 cflags-$(CONFIG_QEMU)          += -Iinclude/asm-mips/mach-qemu
 load-$(CONFIG_QEMU)            += 0xffffffff80010000
 
-#
-# Momentum Ocelot-3
-#
-core-$(CONFIG_MOMENCO_OCELOT_3)        += arch/mips/momentum/ocelot_3/
-cflags-$(CONFIG_MOMENCO_OCELOT_3)      += -Iinclude/asm-mips/mach-ocelot3
-load-$(CONFIG_MOMENCO_OCELOT_3)        += 0xffffffff80100000
-
 #
 # Basler eXcite
 #
@@ -389,10 +382,6 @@ core-$(CONFIG_DDB5XXX_COMMON)      += arch/mips/ddb5xxx/common/
 core-$(CONFIG_DDB5477)         += arch/mips/ddb5xxx/ddb5477/
 load-$(CONFIG_DDB5477)         += 0xffffffff80100000
 
-core-$(CONFIG_LASAT)           += arch/mips/lasat/
-cflags-$(CONFIG_LASAT)         += -Iinclude/asm-mips/mach-lasat
-load-$(CONFIG_LASAT)           += 0xffffffff80000000
-
 #
 # Common VR41xx
 #
@@ -580,6 +569,7 @@ load-$(CONFIG_TOSHIBA_JMR3927)      += 0xffffffff80050000
 #
 core-$(CONFIG_TOSHIBA_RBTX4927)        += arch/mips/tx4927/toshiba_rbtx4927/
 core-$(CONFIG_TOSHIBA_RBTX4927)        += arch/mips/tx4927/common/
+cflags-$(CONFIG_TOSHIBA_RBTX4927) += -Iinclude/asm-mips/mach-tx49xx
 load-$(CONFIG_TOSHIBA_RBTX4927)        += 0xffffffff80020000
 
 #
@@ -587,6 +577,7 @@ load-$(CONFIG_TOSHIBA_RBTX4927)     += 0xffffffff80020000
 #
 core-$(CONFIG_TOSHIBA_RBTX4938) += arch/mips/tx4938/toshiba_rbtx4938/
 core-$(CONFIG_TOSHIBA_RBTX4938) += arch/mips/tx4938/common/
+cflags-$(CONFIG_TOSHIBA_RBTX4938) += -Iinclude/asm-mips/mach-tx49xx
 load-$(CONFIG_TOSHIBA_RBTX4938) += 0xffffffff80100000
 
 cflags-y                       += -Iinclude/asm-mips/mach-generic
@@ -603,7 +594,8 @@ JIFFIES                     = jiffies_64
 endif
 
 AFLAGS         += $(cflags-y)
-CFLAGS         += $(cflags-y)
+CFLAGS         += $(cflags-y) \
+                       -D"VMLINUX_LOAD_ADDRESS=$(load-y)"
 
 LDFLAGS                        += -m $(ld-emul)
 
@@ -633,18 +625,11 @@ CPPFLAGS_vmlinux.lds := \
 head-y := arch/mips/kernel/head.o arch/mips/kernel/init_task.o
 
 libs-y                 += arch/mips/lib/
-libs-$(CONFIG_32BIT)   += arch/mips/lib-32/
-libs-$(CONFIG_64BIT)   += arch/mips/lib-64/
 
 core-y                 += arch/mips/kernel/ arch/mips/mm/ arch/mips/math-emu/
 
 drivers-$(CONFIG_OPROFILE)     += arch/mips/oprofile/
 
-ifdef CONFIG_LASAT
-rom.bin rom.sw: vmlinux
-       $(Q)$(MAKE) $(build)=arch/mips/lasat/image $@
-endif
-
 #
 # Some machines like the Indy need 32-bit ELF binaries for booting purposes.
 # Other need ECOFF, so we build a 32-bit ELF binary for them which we then
@@ -702,32 +687,19 @@ vmlinux.srec: $(vmlinux-32)
 CLEAN_FILES += vmlinux.ecoff \
               vmlinux.srec
 
+archprepare:
+ifdef CONFIG_MIPS32_N32
+       @echo '  Checking missing-syscalls for N32'
+       $(Q)$(MAKE) $(build)=. missing-syscalls EXTRA_CFLAGS="-mabi=n32"
+endif
+ifdef CONFIG_MIPS32_O32
+       @echo '  Checking missing-syscalls for O32'
+       $(Q)$(MAKE) $(build)=. missing-syscalls EXTRA_CFLAGS="-mabi=32"
+endif
+
 archclean:
        @$(MAKE) $(clean)=arch/mips/boot
-       @$(MAKE) $(clean)=arch/mips/lasat
 
 CLEAN_FILES += vmlinux.32 \
               vmlinux.64 \
               vmlinux.ecoff
-
-quiet_cmd_syscalls_n32 = CALL-N32 $<
-      cmd_syscalls_n32 = $(CONFIG_SHELL) $< $(CC) $(c_flags) -mabi=n32
-
-quiet_cmd_syscalls_o32 = CALL-O32 $<
-      cmd_syscalls_o32 = $(CONFIG_SHELL) $< $(CC) $(c_flags) -mabi=32
-
-PHONY += missing-syscalls-n32 missing-syscalls-o32
-
-missing-syscalls-n32: scripts/checksyscalls.sh FORCE
-       $(call cmd,syscalls_n32)
-
-missing-syscalls-o32: scripts/checksyscalls.sh FORCE
-       $(call cmd,syscalls_o32)
-
-archprepare:
-ifdef CONFIG_MIPS32_N32
-       $(Q)$(MAKE) $(build)=arch/mips missing-syscalls-n32
-endif
-ifdef CONFIG_MIPS32_O32
-       $(Q)$(MAKE) $(build)=arch/mips missing-syscalls-o32
-endif
index ce55297dcb8c57e261cb6e7320e5c4d911f82b2c..7abe420994390461ffb9d059475f6e5fb7defcce 100644 (file)
@@ -1,4 +1,7 @@
 /*
+ *  Copyright (C) 2007, OpenWrt.org, Florian Fainelli <florian@openwrt.org>
+ *     Architecture specific GPIO support
+ *
  *  This program is free software; you can redistribute         it and/or modify it
  *  under  the terms of         the GNU General  Public License as published by the
  *  Free Software Foundation;  either version 2 of the License, or (at your
  *  You 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.
+ *
+ *  Notes :
+ *     au1000 SoC have only one GPIO line : GPIO1
+ *     others have a second one : GPIO2
  */
+
+#include <linux/autoconf.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/types.h>
 #include <linux/module.h>
-#include <au1000.h>
-#include <au1xxx_gpio.h>
+
+#include <asm/addrspace.h>
+
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/gpio.h>
 
 #define gpio1 sys
 #if !defined(CONFIG_SOC_AU1000)
-static AU1X00_GPIO2 * const gpio2 = (AU1X00_GPIO2 *)GPIO2_BASE;
 
-#define GPIO2_OUTPUT_ENABLE_MASK 0x00010000
+static struct au1x00_gpio2 *const gpio2 = (struct au1x00_gpio2 *) GPIO2_BASE;
+#define GPIO2_OUTPUT_ENABLE_MASK       0x00010000
 
-int au1xxx_gpio2_read(int signal)
+static int au1xxx_gpio2_read(unsigned gpio)
 {
-       signal -= 200;
-/*     gpio2->dir &= ~(0x01 << signal);                                                //Set GPIO to input */
-       return ((gpio2->pinstate >> signal) & 0x01);
+       gpio -= AU1XXX_GPIO_BASE;
+       return ((gpio2->pinstate >> gpio) & 0x01);
 }
 
-void au1xxx_gpio2_write(int signal, int value)
+static void au1xxx_gpio2_write(unsigned gpio, int value)
 {
-       signal -= 200;
+       gpio -= AU1XXX_GPIO_BASE;
 
-       gpio2->output = (GPIO2_OUTPUT_ENABLE_MASK << signal) |
-               (value << signal);
+       gpio2->output = (GPIO2_OUTPUT_ENABLE_MASK << gpio) | (value << gpio);
 }
 
-void au1xxx_gpio2_tristate(int signal)
+static int au1xxx_gpio2_direction_input(unsigned gpio)
 {
-       signal -= 200;
-       gpio2->dir &= ~(0x01 << signal);        /* Set GPIO to input */
+       gpio -= AU1XXX_GPIO_BASE;
+       gpio2->dir &= ~(0x01 << gpio);
+       return 0;
 }
-#endif
 
-int au1xxx_gpio1_read(int signal)
+static int au1xxx_gpio2_direction_output(unsigned gpio, int value)
+{
+       gpio -= AU1XXX_GPIO_BASE;
+       gpio2->dir = (0x01 << gpio) | (value << gpio);
+       return 0;
+}
+
+#endif /* !defined(CONFIG_SOC_AU1000) */
+
+static int au1xxx_gpio1_read(unsigned gpio)
 {
-/*     gpio1->trioutclr |= (0x01 << signal); */
-       return ((gpio1->pinstaterd >> signal) & 0x01);
+       return ((gpio1->pinstaterd >> gpio) & 0x01);
 }
 
-void au1xxx_gpio1_write(int signal, int value)
+static void au1xxx_gpio1_write(unsigned gpio, int value)
 {
-       if(value)
-               gpio1->outputset = (0x01 << signal);
+       if (value)
+               gpio1->outputset = (0x01 << gpio);
        else
-               gpio1->outputclr = (0x01 << signal);    /* Output a Zero */
+               /* Output a zero */
+               gpio1->outputclr = (0x01 << gpio);
 }
 
-void au1xxx_gpio1_tristate(int signal)
+static int au1xxx_gpio1_direction_input(unsigned gpio)
 {
-       gpio1->trioutclr = (0x01 << signal);            /* Tristate signal */
+       gpio1->pininputen = (0x01 << gpio);
+       return 0;
 }
 
+static int au1xxx_gpio1_direction_output(unsigned gpio, int value)
+{
+       gpio1->trioutclr = (0x01 & gpio);
+       return 0;
+}
 
-int au1xxx_gpio_read(int signal)
+int au1xxx_gpio_get_value(unsigned gpio)
 {
-       if(signal >= 200)
+       if (gpio >= AU1XXX_GPIO_BASE)
 #if defined(CONFIG_SOC_AU1000)
                return 0;
 #else
-               return au1xxx_gpio2_read(signal);
+               return au1xxx_gpio2_read(gpio);
 #endif
        else
-               return au1xxx_gpio1_read(signal);
+               return au1xxx_gpio1_read(gpio);
 }
 
-void au1xxx_gpio_write(int signal, int value)
+EXPORT_SYMBOL(au1xxx_gpio_get_value);
+
+void au1xxx_gpio_set_value(unsigned gpio, int value)
 {
-       if(signal >= 200)
+       if (gpio >= AU1XXX_GPIO_BASE)
 #if defined(CONFIG_SOC_AU1000)
                ;
 #else
-               au1xxx_gpio2_write(signal, value);
+               au1xxx_gpio2_write(gpio, value);
 #endif
        else
-               au1xxx_gpio1_write(signal, value);
+               au1xxx_gpio1_write(gpio, value);
 }
 
-void au1xxx_gpio_tristate(int signal)
+EXPORT_SYMBOL(au1xxx_gpio_set_value);
+
+int au1xxx_gpio_direction_input(unsigned gpio)
 {
-       if(signal >= 200)
+       if (gpio >= AU1XXX_GPIO_BASE)
 #if defined(CONFIG_SOC_AU1000)
                ;
 #else
-               au1xxx_gpio2_tristate(signal);
+               return au1xxx_gpio2_direction_input(gpio);
 #endif
        else
-               au1xxx_gpio1_tristate(signal);
+               return au1xxx_gpio1_direction_input(gpio);
 }
 
-void au1xxx_gpio1_set_inputs(void)
+EXPORT_SYMBOL(au1xxx_gpio_direction_input);
+
+int au1xxx_gpio_direction_output(unsigned gpio, int value)
 {
-       gpio1->pininputen = 0;
+       if (gpio >= AU1XXX_GPIO_BASE)
+#if defined(CONFIG_SOC_AU1000)
+               ;
+#else
+               return au1xxx_gpio2_direction_output(gpio, value);
+#endif
+       else
+               return au1xxx_gpio1_direction_output(gpio, value);
 }
 
-EXPORT_SYMBOL(au1xxx_gpio1_set_inputs);
-EXPORT_SYMBOL(au1xxx_gpio_tristate);
-EXPORT_SYMBOL(au1xxx_gpio_write);
-EXPORT_SYMBOL(au1xxx_gpio_read);
+EXPORT_SYMBOL(au1xxx_gpio_direction_output);
index 8fd203d4a339bd2a9f2626e9375432b6432793ae..d51e18fb789b5bd2396617c2b9181cfe1912e019 100644 (file)
@@ -289,7 +289,7 @@ static struct platform_device *au1xxx_platform_devices[] __initdata = {
 #endif
 };
 
-int au1xxx_platform_init(void)
+int __init au1xxx_platform_init(void)
 {
        return platform_add_devices(au1xxx_platform_devices, ARRAY_SIZE(au1xxx_platform_devices));
 }
index 13fe187f35d67542a1bfa93acf4544d949ee7261..a95b377731965d9070787f3227530e17535306ac 100644 (file)
@@ -100,18 +100,9 @@ void __init plat_mem_setup(void)
         argptr = prom_getcmdline();
         /* default panel */
         /*strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");*/
-#ifdef CONFIG_MIPS_HYDROGEN3
-         strcat(argptr, " video=au1100fb:panel:Hydrogen_3_NEC_panel_320x240,nohwcursor");
-#endif
     }
 #endif
 
-#ifdef CONFIG_FB_XPERT98
-       if ((argptr = strstr(argptr, "video=")) == NULL) {
-               argptr = prom_getcmdline();
-               strcat(argptr, " video=atyfb:1024x768-8@70");
-       }
-#endif
 
 #if defined(CONFIG_SOUND_AU1X00) && !defined(CONFIG_SOC_AU1000)
        /* au1000 does not support vra, au1500 and au1100 do */
index fa1c62f055156a509e2b6e5aeed75f0d7b67fa70..8fc29982d700bdc68c7a399b8561bfe0d1c4755a 100644 (file)
@@ -203,11 +203,7 @@ wakeup_counter0_set(int ticks)
 /* I haven't found anyone that doesn't use a 12 MHz source clock,
  * but just in case.....
  */
-#ifdef CONFIG_AU1000_SRC_CLK
-#define AU1000_SRC_CLK CONFIG_AU1000_SRC_CLK
-#else
 #define AU1000_SRC_CLK 12000000
-#endif
 
 /*
  * We read the real processor speed from the PLL.  This is important
@@ -247,33 +243,8 @@ unsigned long cal_r4koff(void)
                au_writel (0, SYS_TOYWRITE);
                while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S);
 
-#if defined(CONFIG_AU1000_USE32K)
-               {
-                       unsigned long start, end, count;
-
-                       start = au_readl(SYS_RTCREAD);
-                       start += 2;
-                       /* wait for the beginning of a new tick
-                       */
-                       while (au_readl(SYS_RTCREAD) < start);
-
-                       /* Start r4k counter.
-                       */
-                       write_c0_count(0);
-
-                       /* Wait 0.5 seconds.
-                       */
-                       end = start + (32768 / trim_divide)/2;
-
-                       while (end > au_readl(SYS_RTCREAD));
-
-                       count = read_c0_count();
-                       cpu_speed = count * 2;
-               }
-#else
                cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) *
                        AU1000_SRC_CLK;
-#endif
        }
        else {
                /* The 32KHz oscillator isn't running, so assume there
index 043302b7fe589d7eabc873d7d5172c05c6473381..eea2092bde8dfe801fb06fac0b4251c108dad153 100644 (file)
@@ -131,14 +131,7 @@ void __init board_setup(void)
        /* The Pb1200 development board uses external MUX for PSC0 to
        support SMB/SPI. bcsr->resets bit 12: 0=SMB 1=SPI
        */
-#if defined(CONFIG_AU1XXX_PSC_SPI) && defined(CONFIG_I2C_AU1550)
-       #error I2C and SPI are mutually exclusive. Both are physically connected to PSC0.\
-                       Refer to Pb1200/Db1200 documentation.
-#elif defined( CONFIG_AU1XXX_PSC_SPI )
-       bcsr->resets |= BCSR_RESETS_PCS0MUX;
-       /*Hard Coding Value to enable Temp Sensors [bit 14] Value for SOC Au1200. Pls refer documentation*/
-         bcsr->resets =0x900f;
-#elif defined( CONFIG_I2C_AU1550 )
+#ifdef CONFIG_I2C_AU1550
        bcsr->resets &= (~BCSR_RESETS_PCS0MUX);
 #endif
        au_sync();
index 39e251300c64fb9c89aca7bac7168413e64bb226..129e2c961fecdfeac1c42b1a48462dabf627d57c 100644 (file)
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 CONFIG_MIPS_ATLAS=y
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_MIPS_ATLAS=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
index 4713a13211cea616982671fc5c9778678c35a398..dc3e1bf4e42edbf04af8015503c2091cf1017a85 100644 (file)
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
index 5e7ae56b1f3c45d2a31f1075964c88158f1ec2e3..4c7031222e64d42b440557a0212048d9a6e05e0d 100644 (file)
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
index 631b2138ad6842399079f742a7bafd7a96b82e99..c8c05785a86d19a605e306b661a360a6f77b2331 100644 (file)
@@ -1,44 +1,24 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.21-rc7
-# Wed Apr 18 14:25:45 2007
+# Linux kernel version: 2.6.22-rc2
+# Fri May 25 11:17:29 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
-CONFIG_ZONE_DMA=y
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-# CONFIG_MIPS_PB1500 is not set
-# CONFIG_MIPS_PB1550 is not set
-# CONFIG_MIPS_PB1200 is not set
-# CONFIG_MIPS_DB1000 is not set
-# CONFIG_MIPS_DB1100 is not set
-# CONFIG_MIPS_DB1500 is not set
-# CONFIG_MIPS_DB1550 is not set
-# CONFIG_MIPS_DB1200 is not set
-# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MACH_ALCHEMY is not set
 # CONFIG_BASLER_EXCITE is not set
 CONFIG_MIPS_COBALT=y
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
 # CONFIG_WR_PPMC is not set
 # CONFIG_MIPS_SIM is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
@@ -138,7 +118,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=1
+CONFIG_ZONE_DMA_FLAG=0
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -178,6 +158,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
 # CONFIG_BLK_DEV_INITRD is not set
@@ -193,14 +174,19 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 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_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -233,16 +219,13 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 #
 CONFIG_HW_HAS_PCI=y
 CONFIG_PCI=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_MMU=y
 
 #
 # PCCARD (PCMCIA/CardBus) support
 #
 # CONFIG_PCCARD is not set
-
-#
-# PCI Hotplug Support
-#
 # CONFIG_HOTPLUG_PCI is not set
 
 #
@@ -268,7 +251,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -300,11 +282,11 @@ CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
-CONFIG_TCP_MD5SIG=y
+# CONFIG_TCP_MD5SIG is not set
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
-CONFIG_NETWORK_SECMARK=y
+# CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 
 #
@@ -345,13 +327,16 @@ CONFIG_NETWORK_SECMARK=y
 # CONFIG_HAMRADIO is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
-CONFIG_IEEE80211=y
-# CONFIG_IEEE80211_DEBUG is not set
-CONFIG_IEEE80211_CRYPT_WEP=y
-CONFIG_IEEE80211_CRYPT_CCMP=y
-CONFIG_IEEE80211_SOFTMAC=y
-# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
-CONFIG_WIRELESS_EXT=y
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
 
 #
 # Device Drivers
@@ -370,10 +355,6 @@ CONFIG_FW_LOADER=y
 #
 CONFIG_CONNECTOR=y
 CONFIG_PROC_EVENTS=y
-
-#
-# Memory Technology Devices (MTD)
-#
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
 # CONFIG_MTD_CONCAT is not set
@@ -418,7 +399,6 @@ CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
@@ -445,16 +425,13 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=0
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
 # CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
 
 #
-# OneNAND Flash Device Drivers
+# UBI - Unsorted block images
 #
-# CONFIG_MTD_ONENAND is not set
+# CONFIG_MTD_UBI is not set
 
 #
 # Parallel port support
@@ -479,87 +456,145 @@ CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_RAM is not set
-CONFIG_CDROM_PKTCDVD=y
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
-CONFIG_ATA_OVER_ETH=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
 
 #
 # Misc devices
 #
-CONFIG_SGI_IOC4=y
+# CONFIG_PHANTOM is not set
+# CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=y
-CONFIG_IDE_MAX_HWIFS=4
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_BLK_DEV_IDECD is not set
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=y
-CONFIG_BLK_DEV_IDEPCI=y
-# CONFIG_IDEPCI_SHARE_IRQ is not set
-# CONFIG_BLK_DEV_OFFBOARD is not set
-# CONFIG_BLK_DEV_GENERIC is not set
-# CONFIG_BLK_DEV_OPTI621 is not set
-CONFIG_BLK_DEV_IDEDMA_PCI=y
-# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
-# CONFIG_IDEDMA_ONLYDISK is not set
-# CONFIG_BLK_DEV_AEC62XX is not set
-# CONFIG_BLK_DEV_ALI15X3 is not set
-# CONFIG_BLK_DEV_AMD74XX is not set
-# CONFIG_BLK_DEV_CMD64X is not set
-# CONFIG_BLK_DEV_TRIFLEX is not set
-# CONFIG_BLK_DEV_CY82C693 is not set
-# CONFIG_BLK_DEV_CS5520 is not set
-# CONFIG_BLK_DEV_CS5530 is not set
-# CONFIG_BLK_DEV_HPT34X is not set
-# CONFIG_BLK_DEV_HPT366 is not set
-# CONFIG_BLK_DEV_JMICRON is not set
-# CONFIG_BLK_DEV_SC1200 is not set
-# CONFIG_BLK_DEV_PIIX is not set
-CONFIG_BLK_DEV_IT8213=y
-# 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_SLC90E66 is not set
-# CONFIG_BLK_DEV_TRM290 is not set
-CONFIG_BLK_DEV_VIA82CXXX=y
-CONFIG_BLK_DEV_TC86C001=y
-# CONFIG_IDE_ARM is not set
-CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_IDEDMA_IVB is not set
-# CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLINK is not set
+# CONFIG_IDE is not set
 
 #
 # SCSI device support
 #
 CONFIG_RAID_ATTRS=y
-# CONFIG_SCSI is not set
+CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
 # CONFIG_SCSI_NETLINK is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
-# CONFIG_ATA is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_DPT_I2O 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_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_ESP_CORE is not set
+# CONFIG_SCSI_SRP is not set
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SVW is not set
+# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
+# CONFIG_PDC_ADMA is not set
+# 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_SIL24 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 is not set
+# 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_IT821X is not set
+# CONFIG_PATA_IT8213 is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MARVELL is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC_OLD 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=y
+# CONFIG_PATA_WINBOND is not set
+# CONFIG_PATA_PLATFORM is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -570,10 +605,14 @@ CONFIG_RAID_ATTRS=y
 # Fusion MPT device support
 #
 # CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
 
 #
 # IEEE 1394 (FireWire) support
 #
+# CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
 
 #
@@ -594,24 +633,7 @@ CONFIG_NETDEVICES=y
 # ARCnet devices
 #
 # CONFIG_ARCNET is not set
-
-#
-# PHY device support
-#
-CONFIG_PHYLIB=y
-
-#
-# MII PHY device drivers
-#
-CONFIG_MARVELL_PHY=y
-CONFIG_DAVICOM_PHY=y
-CONFIG_QSEMI_PHY=y
-CONFIG_LXT_PHY=y
-CONFIG_CICADA_PHY=y
-CONFIG_VITESSE_PHY=y
-CONFIG_SMSC_PHY=y
-# CONFIG_BROADCOM_PHY is not set
-# CONFIG_FIXED_PHY is not set
+# CONFIG_PHYLIB is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -639,35 +661,8 @@ CONFIG_TULIP=y
 # CONFIG_ULI526X is not set
 # CONFIG_HP100 is not set
 # CONFIG_NET_PCI is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SIS190 is not set
-# CONFIG_SKGE is not set
-# CONFIG_SKY2 is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_BNX2 is not set
-CONFIG_QLA3XXX=y
-# CONFIG_ATL1 is not set
-
-#
-# Ethernet (10000 Mbit)
-#
-# CONFIG_CHELSIO_T1 is not set
-CONFIG_CHELSIO_T3=y
-# CONFIG_IXGB is not set
-# CONFIG_S2IO is not set
-# CONFIG_MYRI10GE is not set
-CONFIG_NETXEN_NIC=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
 
 #
 # Token Ring devices
@@ -675,18 +670,16 @@ CONFIG_NETXEN_NIC=y
 # CONFIG_TR is not set
 
 #
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
+# Wireless LAN
 #
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
@@ -711,10 +704,7 @@ CONFIG_INPUT=y
 #
 # Userland interfaces
 #
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_MOUSEDEV is not set
 # CONFIG_INPUT_JOYDEV is not set
 # CONFIG_INPUT_TSDEV is not set
 # CONFIG_INPUT_EVDEV is not set
@@ -726,18 +716,23 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_KEYBOARD is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_PCSPKR is not set
+CONFIG_INPUT_COBALT_BTNS=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 is not set
+CONFIG_INPUT_POLLDEV=y
 
 #
 # Hardware I/O ports
 #
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=y
+# CONFIG_SERIO is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -754,7 +749,7 @@ CONFIG_VT_HW_CONSOLE_BINDING=y
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_PCI=y
+# CONFIG_SERIAL_8250_PCI is not set
 CONFIG_SERIAL_8250_NR_UARTS=4
 CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
@@ -773,16 +768,11 @@ CONFIG_LEGACY_PTY_COUNT=256
 # IPMI
 #
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
 # CONFIG_WATCHDOG is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_RTC is not set
 # CONFIG_GEN_RTC is not set
 CONFIG_COBALT_LCD=y
-# CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_DRM is not set
@@ -792,10 +782,7 @@ CONFIG_COBALT_LCD=y
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
+CONFIG_DEVPORT=y
 # CONFIG_I2C is not set
 
 #
@@ -808,12 +795,7 @@ CONFIG_COBALT_LCD=y
 # Dallas's 1-wire bus
 #
 # CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
 # CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
 
 #
 # Multifunction device drivers
@@ -824,16 +806,19 @@ CONFIG_COBALT_LCD=y
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
 
 #
-# Digital Video Broadcasting Devices
+# Graphics support
 #
-# CONFIG_DVB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
-# Graphics support
+# Display device support
 #
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
 # CONFIG_FB is not set
 
 #
@@ -868,10 +853,6 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
 # CONFIG_MMC is not set
 
 #
@@ -912,17 +893,29 @@ 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
 
 #
-# RTC drivers
+# I2C RTC drivers
+#
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
 #
 CONFIG_RTC_DRV_CMOS=y
 # CONFIG_RTC_DRV_DS1553 is not set
 # CONFIG_RTC_DRV_DS1742 is not set
 # CONFIG_RTC_DRV_M48T86 is not set
-# CONFIG_RTC_DRV_TEST is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
+#
+# on-CPU RTC drivers
+#
+
 #
 # DMA Engine support
 #
@@ -936,14 +929,6 @@ CONFIG_RTC_DRV_CMOS=y
 # DMA Devices
 #
 
-#
-# Auxiliary Display support
-#
-
-#
-# Virtualization
-#
-
 #
 # File systems
 #
@@ -952,8 +937,13 @@ CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_POSIX_ACL=y
 CONFIG_EXT2_FS_SECURITY=y
 # CONFIG_EXT2_FS_XIP is not set
-# CONFIG_EXT3_FS is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
 # 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
@@ -969,7 +959,7 @@ CONFIG_INOTIFY_USER=y
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
-CONFIG_FUSE_FS=y
+# CONFIG_FUSE_FS is not set
 CONFIG_GENERIC_ACL=y
 
 #
@@ -1003,7 +993,6 @@ CONFIG_CONFIGFS_FS=y
 #
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
-# CONFIG_ECRYPT_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
@@ -1021,13 +1010,23 @@ CONFIG_CONFIGFS_FS=y
 # Network File Systems
 #
 CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
 # CONFIG_NFS_V4 is not set
 # CONFIG_NFS_DIRECTIO is not set
-# CONFIG_NFSD is not set
+CONFIG_NFSD=y
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+# CONFIG_NFSD_V4 is not set
+CONFIG_NFSD_TCP=y
 CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
+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 is not set
@@ -1051,10 +1050,7 @@ CONFIG_MSDOS_PARTITION=y
 #
 # Distributed Lock Manager
 #
-CONFIG_DLM=y
-CONFIG_DLM_TCP=y
-# CONFIG_DLM_SCTP is not set
-# CONFIG_DLM_DEBUG is not set
+# CONFIG_DLM is not set
 
 #
 # Profiling support
@@ -1072,72 +1068,30 @@ CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 
 #
 # Security options
 #
-CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 
 #
 # Cryptographic options
 #
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_BLKCIPHER=y
-CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_MANAGER=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_XCBC=y
-CONFIG_CRYPTO_NULL=y
-CONFIG_CRYPTO_MD4=y
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_SHA1=y
-CONFIG_CRYPTO_SHA256=y
-CONFIG_CRYPTO_SHA512=y
-CONFIG_CRYPTO_WP512=y
-CONFIG_CRYPTO_TGR192=y
-CONFIG_CRYPTO_GF128MUL=y
-CONFIG_CRYPTO_ECB=y
-CONFIG_CRYPTO_CBC=y
-CONFIG_CRYPTO_PCBC=y
-CONFIG_CRYPTO_LRW=y
-CONFIG_CRYPTO_DES=y
-CONFIG_CRYPTO_FCRYPT=y
-CONFIG_CRYPTO_BLOWFISH=y
-CONFIG_CRYPTO_TWOFISH=y
-CONFIG_CRYPTO_TWOFISH_COMMON=y
-CONFIG_CRYPTO_SERPENT=y
-CONFIG_CRYPTO_AES=y
-CONFIG_CRYPTO_CAST5=y
-CONFIG_CRYPTO_CAST6=y
-CONFIG_CRYPTO_TEA=y
-CONFIG_CRYPTO_ARC4=y
-CONFIG_CRYPTO_KHAZAD=y
-CONFIG_CRYPTO_ANUBIS=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_MICHAEL_MIC=y
-CONFIG_CRYPTO_CRC32C=y
-CONFIG_CRYPTO_CAMELLIA=y
-
-#
-# Hardware crypto devices
-#
+# CONFIG_CRYPTO is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
-CONFIG_CRC16=y
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
 CONFIG_LIBCRC32C=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
 CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
index 10f6af43753d8fdcf5c926e491ee0e1495b3592c..ec60beb888b2baa820d8172d4219b331654e6833 100644 (file)
@@ -26,9 +26,7 @@ CONFIG_MIPS_DB1000=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -36,8 +34,6 @@ CONFIG_MIPS_DB1000=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
index 4b0862927748a57c83e8804cd2c1922952a9daf1..f3c25f08bfad1ba352d46fe83bc94a43fafccc65 100644 (file)
@@ -26,9 +26,7 @@ CONFIG_MIPS_DB1100=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -36,8 +34,6 @@ CONFIG_MIPS_DB1100=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
index 820659e810dcbf09a910e8e67e50e3954bb8d845..6d400befbaccd1d696c9f0dca2e1a5a6e55276d1 100644 (file)
@@ -26,9 +26,7 @@ CONFIG_MIPS_DB1200=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -36,8 +34,6 @@ CONFIG_MIPS_DB1200=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
index 4050b9b91bcba6008ed399412dd77f80e8364bd0..82aea6e088239885fdd32db7fdf6cdf5ef10ddbf 100644 (file)
@@ -26,9 +26,7 @@ CONFIG_MIPS_DB1500=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -36,8 +34,6 @@ CONFIG_MIPS_DB1500=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
index 7b3519058ab825f23166ded48de487cf81dd7a1f..82697714a9e3e4beaa48023ea37ae1e802a148f8 100644 (file)
@@ -26,9 +26,7 @@ CONFIG_MIPS_DB1550=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -36,8 +34,6 @@ CONFIG_MIPS_DB1550=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
index 5b502a2013fb81d752df5c7a5f9f72480027bb33..a42ab9ae7d4b9252f4e76312463fc4590e30aec3 100644 (file)
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
index 4bbdab078ff19ebb8af3f1aa4d41f0552e5dacab..d6e3fffbc80da3c67ebaca1462532cd7e02b5921 100644 (file)
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 CONFIG_MACH_DECSTATION=y
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_MACH_DECSTATION=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
index b5714a6a5398950b77c11d9776847827490f4dd3..78f5004fb721fe916cbe5711b5a971496a3e3781 100644 (file)
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
index 2e3e155b4c55d173b8c46c16be8e0e7bc938d344..b29bff0f56c39737088a341c4fdf9db0b9459e8f 100644 (file)
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/ev64120_defconfig b/arch/mips/configs/ev64120_defconfig
deleted file mode 100644 (file)
index c10e4e0..0000000
+++ /dev/null
@@ -1,985 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20
-# Tue Feb 20 21:47:30 2007
-#
-CONFIG_MIPS=y
-
-#
-# Machine selection
-#
-CONFIG_ZONE_DMA=y
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-# CONFIG_MIPS_PB1500 is not set
-# CONFIG_MIPS_PB1550 is not set
-# CONFIG_MIPS_PB1200 is not set
-# CONFIG_MIPS_DB1000 is not set
-# CONFIG_MIPS_DB1100 is not set
-# CONFIG_MIPS_DB1500 is not set
-# CONFIG_MIPS_DB1550 is not set
-# CONFIG_MIPS_DB1200 is not set
-# CONFIG_MIPS_MIRAGE is not set
-# CONFIG_BASLER_EXCITE is not set
-# CONFIG_MIPS_COBALT is not set
-# CONFIG_MACH_DECSTATION is not set
-CONFIG_MIPS_EV64120=y
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
-# CONFIG_MIPS_ATLAS is not set
-# CONFIG_MIPS_MALTA is not set
-# CONFIG_MIPS_SEAD is not set
-# CONFIG_WR_PPMC is not set
-# CONFIG_MIPS_SIM is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_JBS is not set
-# CONFIG_PNX8550_STB810 is not set
-# CONFIG_DDB5477 is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_PMC_YOSEMITE is not set
-# CONFIG_QEMU is not set
-# CONFIG_MARKEINS is not set
-# CONFIG_SGI_IP22 is not set
-# CONFIG_SGI_IP27 is not set
-# CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_BIGSUR is not set
-# CONFIG_SIBYTE_SWARM is not set
-# CONFIG_SIBYTE_SENTOSA is not set
-# CONFIG_SIBYTE_RHONE is not set
-# CONFIG_SIBYTE_CARMEL is not set
-# CONFIG_SIBYTE_PTSWARM is not set
-# CONFIG_SIBYTE_LITTLESUR is not set
-# CONFIG_SIBYTE_CRHINE is not set
-# CONFIG_SIBYTE_CRHONE is not set
-# CONFIG_SNI_RM is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
-# CONFIG_TOSHIBA_RBTX4927 is not set
-# CONFIG_TOSHIBA_RBTX4938 is not set
-# CONFIG_EVB_PCI1 is not set
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
-CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_TIME=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
-CONFIG_DMA_NONCOHERENT=y
-CONFIG_DMA_NEED_PCI_MAP_STATE=y
-CONFIG_CPU_BIG_ENDIAN=y
-# CONFIG_CPU_LITTLE_ENDIAN is not set
-CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
-CONFIG_MIPS_GT64120=y
-# CONFIG_SYSCLK_75 is not set
-# CONFIG_SYSCLK_83 is not set
-CONFIG_SYSCLK_100=y
-CONFIG_MIPS_L1_CACHE_SHIFT=5
-
-#
-# CPU selection
-#
-# CONFIG_CPU_MIPS32_R1 is not set
-# CONFIG_CPU_MIPS32_R2 is not set
-# CONFIG_CPU_MIPS64_R1 is not set
-# CONFIG_CPU_MIPS64_R2 is not set
-# CONFIG_CPU_R3000 is not set
-# CONFIG_CPU_TX39XX is not set
-# CONFIG_CPU_VR41XX is not set
-# CONFIG_CPU_R4300 is not set
-# CONFIG_CPU_R4X00 is not set
-# CONFIG_CPU_TX49XX is not set
-CONFIG_CPU_R5000=y
-# CONFIG_CPU_R5432 is not set
-# CONFIG_CPU_R6000 is not set
-# CONFIG_CPU_NEVADA is not set
-# CONFIG_CPU_R8000 is not set
-# CONFIG_CPU_R10000 is not set
-# CONFIG_CPU_RM7000 is not set
-# CONFIG_CPU_RM9000 is not set
-# CONFIG_CPU_SB1 is not set
-CONFIG_SYS_HAS_CPU_R5000=y
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
-
-#
-# Kernel type
-#
-CONFIG_32BIT=y
-# CONFIG_64BIT is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_8KB is not set
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
-CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMP is not set
-# CONFIG_MIPS_MT_SMTC is not set
-# CONFIG_MIPS_VPE_LOADER is not set
-# CONFIG_64BIT_PHYS_ADDR is not set
-CONFIG_CPU_HAS_LLSC=y
-CONFIG_CPU_HAS_SYNC=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_ARCH_FLATMEM_ENABLE=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_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=1
-# CONFIG_HZ_48 is not set
-# CONFIG_HZ_100 is not set
-# CONFIG_HZ_128 is not set
-# CONFIG_HZ_250 is not set
-# CONFIG_HZ_256 is not set
-CONFIG_HZ_1000=y
-# CONFIG_HZ_1024 is not set
-CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_HZ=1000
-CONFIG_PREEMPT_NONE=y
-# CONFIG_PREEMPT_VOLUNTARY is not set
-# CONFIG_PREEMPT is not set
-# CONFIG_KEXEC is not set
-CONFIG_LOCKDEP_SUPPORT=y
-CONFIG_STACKTRACE_SUPPORT=y
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_IPC_NS is not set
-CONFIG_SYSVIPC_SYSCTL=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_TASKSTATS is not set
-# CONFIG_UTS_NS is not set
-# CONFIG_AUDIT is not set
-# CONFIG_IKCONFIG is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_RELAY=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
-CONFIG_EMBEDDED=y
-CONFIG_SYSCTL_SYSCALL=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_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_SHMEM=y
-CONFIG_SLAB=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-# CONFIG_KMOD is not set
-
-#
-# Block layer
-#
-CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
-# Bus options (PCI, PCMCIA, EISA, ISA, TC)
-#
-CONFIG_HW_HAS_PCI=y
-CONFIG_PCI=y
-CONFIG_MMU=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-# CONFIG_PCCARD is not set
-
-#
-# PCI Hotplug Support
-#
-# CONFIG_HOTPLUG_PCI is not set
-
-#
-# Executable file formats
-#
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
-CONFIG_TRAD_SIGNALS=y
-
-#
-# Power management options
-#
-CONFIG_PM=y
-# CONFIG_PM_LEGACY is not set
-# CONFIG_PM_DEBUG is not set
-# CONFIG_PM_SYSFS_DEPRECATED is not set
-
-#
-# Networking
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-# CONFIG_NETDEBUG is not set
-# CONFIG_PACKET is not set
-CONFIG_UNIX=y
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-# CONFIG_XFRM_SUB_POLICY is not set
-CONFIG_XFRM_MIGRATE=y
-CONFIG_NET_KEY=y
-CONFIG_NET_KEY_MIGRATE=y
-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 is not set
-# CONFIG_IP_PNP_BOOTP is not set
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_XFRM_TUNNEL is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_INET_XFRM_MODE_TRANSPORT=m
-CONFIG_INET_XFRM_MODE_TUNNEL=m
-CONFIG_INET_XFRM_MODE_BEET=m
-CONFIG_INET_DIAG=y
-CONFIG_INET_TCP_DIAG=y
-# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_CUBIC=y
-CONFIG_DEFAULT_TCP_CONG="cubic"
-CONFIG_TCP_MD5SIG=y
-# CONFIG_IPV6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
-CONFIG_NETWORK_SECMARK=y
-# CONFIG_NETFILTER is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
-# CONFIG_TIPC is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-CONFIG_IEEE80211=m
-# CONFIG_IEEE80211_DEBUG is not set
-CONFIG_IEEE80211_CRYPT_WEP=m
-CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_SOFTMAC=m
-# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
-CONFIG_WIRELESS_EXT=y
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
-# CONFIG_SYS_HYPERVISOR is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
-CONFIG_CONNECTOR=m
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-# CONFIG_PNPACPI is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-# CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_SX8 is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
-CONFIG_ATA_OVER_ETH=m
-
-#
-# Misc devices
-#
-CONFIG_SGI_IOC4=m
-# CONFIG_TIFM_CORE is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-# CONFIG_IDE is not set
-
-#
-# SCSI device support
-#
-CONFIG_RAID_ATTRS=m
-# CONFIG_SCSI is not set
-# CONFIG_SCSI_NETLINK is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
-# CONFIG_ATA is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-# CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-
-#
-# PHY device support
-#
-CONFIG_PHYLIB=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 is not set
-# CONFIG_FIXED_PHY is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_CASSINI is not set
-# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_DM9000 is not set
-
-#
-# Tulip family network device support
-#
-# CONFIG_NET_TULIP is not set
-# CONFIG_HP100 is not set
-# CONFIG_NET_PCI is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SIS190 is not set
-# CONFIG_SKGE is not set
-# CONFIG_SKY2 is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_BNX2 is not set
-CONFIG_QLA3XXX=m
-# CONFIG_ATL1 is not set
-
-#
-# Ethernet (10000 Mbit)
-#
-# CONFIG_CHELSIO_T1 is not set
-CONFIG_CHELSIO_T3=m
-# CONFIG_IXGB is not set
-# CONFIG_S2IO is not set
-# CONFIG_MYRI10GE is not set
-CONFIG_NETXEN_NIC=m
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-CONFIG_PPP=y
-# CONFIG_PPP_MULTILINK is not set
-# CONFIG_PPP_FILTER is not set
-CONFIG_PPP_ASYNC=y
-# CONFIG_PPP_SYNC_TTY is not set
-# CONFIG_PPP_DEFLATE is not set
-# CONFIG_PPP_BSDCOMP is not set
-CONFIG_PPP_MPPE=m
-# CONFIG_PPPOE is not set
-# CONFIG_SLIP is not set
-CONFIG_SLHC=y
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
-# CONFIG_PHONE is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input Device Drivers
-#
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Hardware I/O ports
-#
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-# CONFIG_GAMEPORT is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-CONFIG_VT_HW_CONSOLE_BINDING=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_PCI=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-# CONFIG_SERIAL_8250_EXTENDED is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_HW_RANDOM is not set
-# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-# CONFIG_DRM is not set
-# CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
-# CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# SPI support
-#
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
-
-#
-# Dallas's 1-wire bus
-#
-# CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
-# CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-
-#
-# Graphics support
-#
-# CONFIG_FIRMWARE_EDID is not set
-# CONFIG_FB is not set
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# HID Devices
-#
-# CONFIG_HID is not set
-
-#
-# USB support
-#
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
-CONFIG_USB_ARCH_HAS_EHCI=y
-# CONFIG_USB is not set
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
-#
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-
-#
-# LED devices
-#
-# CONFIG_NEW_LEDS is not set
-
-#
-# LED drivers
-#
-
-#
-# LED Triggers
-#
-
-#
-# InfiniBand support
-#
-# CONFIG_INFINIBAND is not set
-
-#
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
-#
-
-#
-# Real Time Clock
-#
-# CONFIG_RTC_CLASS is not set
-
-#
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
-
-#
-# Auxiliary Display support
-#
-
-#
-# Virtualization
-#
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT2_FS_XIP is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_EXT4DEV_FS is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_GFS2_FS is not set
-# CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_INOTIFY=y
-CONFIG_INOTIFY_USER=y
-# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-CONFIG_FUSE_FS=m
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_KCORE=y
-CONFIG_PROC_SYSCTL=y
-CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
-# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-CONFIG_CONFIGFS_FS=m
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_ECRYPT_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_CRAMFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
-# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-# CONFIG_NFSD is not set
-CONFIG_ROOT_NFS=y
-CONFIG_LOCKD=y
-CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=y
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
-# CONFIG_NLS is not set
-
-#
-# Distributed Lock Manager
-#
-CONFIG_DLM=m
-CONFIG_DLM_TCP=y
-# CONFIG_DLM_SCTP is not set
-# CONFIG_DLM_DEBUG is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
-#
-# Kernel hacking
-#
-CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-# CONFIG_PRINTK_TIME is not set
-CONFIG_ENABLE_MUST_CHECK=y
-# 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_LOG_BUF_SHIFT=14
-CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs rw nfsroot=192.168.1.1:/mnt/disk2/fs.gal ip=192.168.1.211:192.168.1.1:::gt::"
-CONFIG_SYS_SUPPORTS_KGDB=y
-
-#
-# Security options
-#
-CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_BLKCIPHER=m
-CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_MANAGER=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_SHA1=m
-CONFIG_CRYPTO_SHA256=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_GF128MUL=m
-CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_CBC=m
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_DES=m
-CONFIG_CRYPTO_FCRYPT=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_TWOFISH_COMMON=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_AES=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_CRC32C=m
-CONFIG_CRYPTO_CAMELLIA=m
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Hardware crypto devices
-#
-
-#
-# Library routines
-#
-CONFIG_BITREVERSE=m
-CONFIG_CRC_CCITT=y
-CONFIG_CRC16=m
-CONFIG_CRC32=m
-CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=m
-CONFIG_ZLIB_DEFLATE=m
-CONFIG_PLIST=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
index 460d7a26a8ba43a815c5ca14d539d934557f341c..69810592aa6b28e4870eeeeb3fbdbf2c63b4602b 100644 (file)
@@ -26,9 +26,7 @@ CONFIG_BASLER_EXCITE=y
 # CONFIG_BASLER_EXCITE_PROTOTYPE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -36,8 +34,6 @@ CONFIG_BASLER_EXCITE=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/fulong_defconfig b/arch/mips/configs/fulong_defconfig
new file mode 100644 (file)
index 0000000..6ab94d8
--- /dev/null
@@ -0,0 +1,1765 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.22-rc4
+# Mon Jun 11 00:23:51 2007
+#
+CONFIG_MIPS=y
+
+#
+# Machine selection
+#
+CONFIG_LEMOTE_FULONG=y
+# CONFIG_MACH_ALCHEMY is not set
+# CONFIG_BASLER_EXCITE is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_WR_PPMC is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
+# CONFIG_MARKEINS is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SNI_RM is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+CONFIG_I8259=y
+# CONFIG_NO_IOPORT is not set
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_IRQ_CPU=y
+CONFIG_BOOT_ELF32=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+CONFIG_CPU_LOONGSON2=y
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_LOONGSON2=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+# CONFIG_32BIT is not set
+CONFIG_64BIT=y
+# CONFIG_PAGE_SIZE_4KB is not set
+# CONFIG_PAGE_SIZE_8KB is not set
+CONFIG_PAGE_SIZE_16KB=y
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_BOARD_SCACHE=y
+CONFIG_MIPS_MT_DISABLED=y
+# CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
+# CONFIG_MIPS_VPE_LOADER is not set
+CONFIG_CPU_HAS_WB=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_SYS_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=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=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_RESOURCES_64BIT=y
+CONFIG_ZONE_DMA_FLAG=0
+# CONFIG_HZ_48 is not set
+# CONFIG_HZ_100 is not set
+# CONFIG_HZ_128 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_256 is not set
+# CONFIG_HZ_1000 is not set
+# CONFIG_HZ_1024 is not set
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_HZ=250
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION="lm32"
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=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_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_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_BLK_DEV_IO_TRACE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_ISA=y
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+# CONFIG_BUILD_ELF64 is not set
+CONFIG_MIPS32_COMPAT=y
+CONFIG_COMPAT=y
+CONFIG_SYSVIPC_COMPAT=y
+CONFIG_MIPS32_O32=y
+CONFIG_MIPS32_N32=y
+CONFIG_BINFMT_ELF32=y
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
+# 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_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_BEET=y
+# 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 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+# CONFIG_NF_CONNTRACK_ENABLED is not set
+# CONFIG_NF_CONNTRACK is not set
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+# 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 is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
+CONFIG_NETFILTER_XT_MATCH_ESP=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_POLICY is not set
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_IPRANGE=m
+CONFIG_IP_NF_MATCH_TOS=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_OWNER=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_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+CONFIG_NET_CLS_ROUTE=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_EXT=y
+# CONFIG_MAC80211 is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+# CONFIG_IEEE80211_CRYPT_CCMP is not set
+# CONFIG_IEEE80211_CRYPT_TKIP is not set
+# CONFIG_IEEE80211_SOFTMAC is not set
+# CONFIG_RFKILL is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=m
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_PARTITIONS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLKDEVS=m
+CONFIG_MTD_BLOCK=m
+# 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
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_GEOMETRY is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_OTP is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI_STAA=m
+CONFIG_MTD_CFI_UTIL=m
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=m
+CONFIG_MTD_PHYSMAP_START=0x1fc00000
+CONFIG_MTD_PHYSMAP_LEN=0x80000
+CONFIG_MTD_PHYSMAP_BANKWIDTH=1
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_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
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNP is not set
+# CONFIG_PNPACPI is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=m
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+CONFIG_ATA_OVER_ETH=m
+
+#
+# Misc devices
+#
+# CONFIG_PHANTOM is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+# CONFIG_BLINK is not set
+CONFIG_IDE=y
+CONFIG_IDE_MAX_HWIFS=4
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+CONFIG_BLK_DEV_IDESCSI=y
+CONFIG_IDE_TASK_IOCTL=y
+CONFIG_IDE_PROC_FS=y
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+CONFIG_IDEPCI_PCIBUS_ORDER=y
+# 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_IDEDMA_FORCED is not set
+# CONFIG_IDEDMA_ONLYDISK is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_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_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+CONFIG_BLK_DEV_VIA82CXXX=y
+# CONFIG_BLK_DEV_TC86C001 is not set
+# CONFIG_IDE_ARM is not set
+# CONFIG_IDE_CHIPSETS is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
+# 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 is not set
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX 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_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_FUTURE_DOMAIN 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_NCR53C406A is not set
+# CONFIG_SCSI_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PSI240I 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_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
+# CONFIG_ATA is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# 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 is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_DM9000 is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_AC3200 is not set
+# CONFIG_APRICOT is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TC35815 is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_E100 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+CONFIG_8139TOO=y
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_OLD_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_SC92031 is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+CONFIG_NETDEV_10000=y
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
+# CONFIG_MLX4_CORE is not set
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 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_MII is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI 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=m
+CONFIG_PPPOE=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLHC=m
+CONFIG_SLIP_SMART=y
+CONFIG_SLIP_MODE_SLIP6=y
+CONFIG_NET_FC=y
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_FF_MEMLESS=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=m
+# 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_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=y
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_INPORT is not set
+# CONFIG_MOUSE_LOGIBM is not set
+# CONFIG_MOUSE_PC110PAD is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW 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_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=y
+CONFIG_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=m
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_ELEKTOR is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 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_STUB is not set
+# CONFIG_I2C_TINY_USB is not set
+# CONFIG_I2C_VIA is not set
+CONFIG_I2C_VIAPRO=m
+# CONFIG_I2C_VOODOO3 is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+# CONFIG_HWMON is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_VIDEO_V4L2=y
+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_BT848 is not set
+# CONFIG_VIDEO_PMS 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_VIDEO_STRADIS is not set
+# CONFIG_VIDEO_SAA7134 is not set
+# CONFIG_VIDEO_MXB is not set
+# CONFIG_VIDEO_DPC is not set
+# CONFIG_VIDEO_HEXIUM_ORION is not set
+# CONFIG_VIDEO_HEXIUM_GEMINI is not set
+# CONFIG_VIDEO_CX88 is not set
+# CONFIG_VIDEO_IVTV is not set
+# CONFIG_VIDEO_CAFE_CCIC is not set
+CONFIG_V4L_USB_DRIVERS=y
+# CONFIG_VIDEO_PVRUSB2 is not set
+# CONFIG_VIDEO_EM28XX is not set
+# CONFIG_VIDEO_USBVISION is not set
+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 is not set
+# CONFIG_USB_W9968CF is not set
+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 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 is not set
+# CONFIG_RADIO_MAXIRADIO is not set
+# CONFIG_RADIO_MAESTRO is not set
+# CONFIG_RADIO_SF16FMI is not set
+# CONFIG_RADIO_SF16FMR2 is not set
+# CONFIG_RADIO_TERRATEC is not set
+# CONFIG_RADIO_TRUST is not set
+# CONFIG_RADIO_TYPHOON is not set
+# CONFIG_RADIO_ZOLTRIX is not set
+# CONFIG_USB_DSBR is not set
+# CONFIG_DVB_CORE is not set
+CONFIG_DAB=y
+# CONFIG_USB_DABUSB is not set
+
+#
+# Graphics support
+#
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=m
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE 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_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_SYS_FOPS is not set
+CONFIG_FB_DEFERRED_IO=y
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+CONFIG_FB_BACKLIGHT=y
+CONFIG_FB_MODE_HELPERS=y
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+CONFIG_FB_RADEON=y
+# CONFIG_FB_RADEON_I2C is not set
+CONFIG_FB_RADEON_BACKLIGHT=y
+# CONFIG_FB_RADEON_DEBUG is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_SMIVGX is not set
+# CONFIG_FB_VT8623 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_MDA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_LOGO is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=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_RTCTIMER=m
+CONFIG_SND_SEQ_RTCTIMER_DEFAULT=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_MPU401_UART=m
+CONFIG_SND_AC97_CODEC=m
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_VIRMIDI is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# PCI devices
+#
+# CONFIG_SND_AD1889 is not set
+# CONFIG_SND_ALS300 is not set
+# CONFIG_SND_ALI5451 is not set
+# CONFIG_SND_ATIIXP is not set
+# CONFIG_SND_ATIIXP_MODEM is not set
+# CONFIG_SND_AU8810 is not set
+# CONFIG_SND_AU8820 is not set
+# CONFIG_SND_AU8830 is not set
+# CONFIG_SND_AZT3328 is not set
+# CONFIG_SND_BT87X is not set
+# CONFIG_SND_CA0106 is not set
+# CONFIG_SND_CMIPCI is not set
+# CONFIG_SND_CS4281 is not set
+# CONFIG_SND_CS46XX is not set
+# CONFIG_SND_DARLA20 is not set
+# CONFIG_SND_GINA20 is not set
+# CONFIG_SND_LAYLA20 is not set
+# CONFIG_SND_DARLA24 is not set
+# CONFIG_SND_GINA24 is not set
+# CONFIG_SND_LAYLA24 is not set
+# CONFIG_SND_MONA is not set
+# CONFIG_SND_MIA is not set
+# CONFIG_SND_ECHO3G is not set
+# CONFIG_SND_INDIGO is not set
+# CONFIG_SND_INDIGOIO is not set
+# CONFIG_SND_INDIGODJ is not set
+# CONFIG_SND_EMU10K1 is not set
+# CONFIG_SND_EMU10K1X is not set
+# CONFIG_SND_ENS1370 is not set
+# CONFIG_SND_ENS1371 is not set
+# CONFIG_SND_ES1938 is not set
+# CONFIG_SND_ES1968 is not set
+# CONFIG_SND_FM801 is not set
+# CONFIG_SND_HDA_INTEL is not set
+# CONFIG_SND_HDSP is not set
+# CONFIG_SND_HDSPM is not set
+# CONFIG_SND_ICE1712 is not set
+# CONFIG_SND_ICE1724 is not set
+# CONFIG_SND_INTEL8X0 is not set
+# CONFIG_SND_INTEL8X0M is not set
+# CONFIG_SND_KORG1212 is not set
+# CONFIG_SND_MAESTRO3 is not set
+# CONFIG_SND_MIXART is not set
+# CONFIG_SND_NM256 is not set
+# CONFIG_SND_PCXHR is not set
+# CONFIG_SND_RIPTIDE is not set
+# CONFIG_SND_RME32 is not set
+# CONFIG_SND_RME96 is not set
+# CONFIG_SND_RME9652 is not set
+# CONFIG_SND_SONICVIBES is not set
+# CONFIG_SND_TRIDENT is not set
+CONFIG_SND_VIA82XX=m
+# CONFIG_SND_VIA82XX_MODEM is not set
+# CONFIG_SND_VX222 is not set
+# CONFIG_SND_YMFPCI is not set
+# CONFIG_SND_AC97_POWER_SAVE is not set
+
+#
+# ALSA MIPS 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 is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=m
+
+#
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=m
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+CONFIG_USB_HIDDEV=y
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# 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
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_SPLIT_ISO=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set
+# CONFIG_USB_ISP116X_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_UHCI_HCD=m
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=y
+CONFIG_USB_PRINTER=y
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+CONFIG_USB_LIBUSUAL=y
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_MON is not set
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_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_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+CONFIG_EXT2_FS_XIP=y
+CONFIG_FS_XIP=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_REISERFS_FS_XATTR is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=y
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+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=936
+CONFIG_FAT_DEFAULT_IOCHARSET="utf8"
+CONFIG_NTFS_FS=m
+# CONFIG_NTFS_DEBUG is not set
+CONFIG_NTFS_RW=y
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=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_RAMFS=y
+# 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 is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=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 is not set
+CONFIG_RPCSEC_GSS_KRB5=m
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_SMB_NLS_REMOTE="cp936"
+CONFIG_CIFS=m
+CONFIG_CIFS_STATS=y
+CONFIG_CIFS_STATS2=y
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+CONFIG_CIFS_DEBUG2=y
+CONFIG_CIFS_EXPERIMENTAL=y
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+CONFIG_NLS_CODEPAGE_936=y
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
+
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
+# Profiling support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+# 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_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_DES=m
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+CONFIG_CRYPTO_ARC4=m
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+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 7ec618f3c8b9060e25876c215193f55a4414e7ad..405c9f505a77cea181ab644806eba8f0516b7d85 100644 (file)
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
index 9ddc3eff479391179d7740a3d234967575d361ca..a9dcbcf563cb6d89a44eaedc449de3ad288f0c33 100644 (file)
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
index 8fc18809d5ffe18a9b15c3342c0bb45bd49b7af5..a040459bec11f04d75b70767888b2ce3ab8194dd 100644 (file)
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
index 9331cb0a19b1731a7ad439392c0d6eb8e91d0b17..8a0b4ac5283df2c9c0e951db2b3385e3c06e0300 100644 (file)
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 CONFIG_MACH_JAZZ=y
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_MACH_JAZZ=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
@@ -245,7 +241,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 #
 CONFIG_ISA=y
 CONFIG_MMU=y
-CONFIG_I8253=y
+CONFIG_PCSPEAKER=y
 
 #
 # PCCARD (PCMCIA/CardBus) support
index 1b364cf69140886f7da5fdf73ebfcf46de4033d1..9a25e770abd82810db718eaf88d6fa70fb04c7c3 100644 (file)
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/lasat200_defconfig b/arch/mips/configs/lasat200_defconfig
deleted file mode 100644 (file)
index fd4272c..0000000
+++ /dev/null
@@ -1,1118 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20
-# Tue Feb 20 21:47:34 2007
-#
-CONFIG_MIPS=y
-
-#
-# Machine selection
-#
-CONFIG_ZONE_DMA=y
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-# CONFIG_MIPS_PB1500 is not set
-# CONFIG_MIPS_PB1550 is not set
-# CONFIG_MIPS_PB1200 is not set
-# CONFIG_MIPS_DB1000 is not set
-# CONFIG_MIPS_DB1100 is not set
-# CONFIG_MIPS_DB1500 is not set
-# CONFIG_MIPS_DB1550 is not set
-# CONFIG_MIPS_DB1200 is not set
-# CONFIG_MIPS_MIRAGE is not set
-# CONFIG_BASLER_EXCITE is not set
-# CONFIG_MIPS_COBALT is not set
-# CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
-# CONFIG_MACH_JAZZ is not set
-CONFIG_LASAT=y
-# CONFIG_MIPS_ATLAS is not set
-# CONFIG_MIPS_MALTA is not set
-# CONFIG_MIPS_SEAD is not set
-# CONFIG_WR_PPMC is not set
-# CONFIG_MIPS_SIM is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_JBS is not set
-# CONFIG_PNX8550_STB810 is not set
-# CONFIG_DDB5477 is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_PMC_YOSEMITE is not set
-# CONFIG_QEMU is not set
-# CONFIG_MARKEINS is not set
-# CONFIG_SGI_IP22 is not set
-# CONFIG_SGI_IP27 is not set
-# CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_BIGSUR is not set
-# CONFIG_SIBYTE_SWARM is not set
-# CONFIG_SIBYTE_SENTOSA is not set
-# CONFIG_SIBYTE_RHONE is not set
-# CONFIG_SIBYTE_CARMEL is not set
-# CONFIG_SIBYTE_PTSWARM is not set
-# CONFIG_SIBYTE_LITTLESUR is not set
-# CONFIG_SIBYTE_CRHINE is not set
-# CONFIG_SIBYTE_CRHONE is not set
-# CONFIG_SNI_RM is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
-# CONFIG_TOSHIBA_RBTX4927 is not set
-# CONFIG_TOSHIBA_RBTX4938 is not set
-CONFIG_PICVUE=y
-CONFIG_PICVUE_PROC=y
-CONFIG_DS1603=y
-CONFIG_LASAT_SYSCTL=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
-CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_TIME=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_DMA_NONCOHERENT=y
-CONFIG_DMA_NEED_PCI_MAP_STATE=y
-CONFIG_MIPS_NILE4=y
-# CONFIG_CPU_BIG_ENDIAN is not set
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
-CONFIG_MIPS_GT64120=y
-CONFIG_MIPS_L1_CACHE_SHIFT=5
-
-#
-# CPU selection
-#
-# CONFIG_CPU_MIPS32_R1 is not set
-# CONFIG_CPU_MIPS32_R2 is not set
-# CONFIG_CPU_MIPS64_R1 is not set
-# CONFIG_CPU_MIPS64_R2 is not set
-# CONFIG_CPU_R3000 is not set
-# CONFIG_CPU_TX39XX is not set
-# CONFIG_CPU_VR41XX is not set
-# CONFIG_CPU_R4300 is not set
-# CONFIG_CPU_R4X00 is not set
-# CONFIG_CPU_TX49XX is not set
-CONFIG_CPU_R5000=y
-# CONFIG_CPU_R5432 is not set
-# CONFIG_CPU_R6000 is not set
-# CONFIG_CPU_NEVADA is not set
-# CONFIG_CPU_R8000 is not set
-# CONFIG_CPU_R10000 is not set
-# CONFIG_CPU_RM7000 is not set
-# CONFIG_CPU_RM9000 is not set
-# CONFIG_CPU_SB1 is not set
-CONFIG_SYS_HAS_CPU_R5000=y
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
-
-#
-# Kernel type
-#
-CONFIG_32BIT=y
-# CONFIG_64BIT is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_8KB is not set
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
-CONFIG_BOARD_SCACHE=y
-CONFIG_R5000_CPU_SCACHE=y
-CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMP is not set
-# CONFIG_MIPS_MT_SMTC is not set
-# CONFIG_MIPS_VPE_LOADER is not set
-# CONFIG_64BIT_PHYS_ADDR is not set
-CONFIG_CPU_HAS_LLSC=y
-CONFIG_CPU_HAS_SYNC=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_ARCH_FLATMEM_ENABLE=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_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=1
-# CONFIG_HZ_48 is not set
-# CONFIG_HZ_100 is not set
-# CONFIG_HZ_128 is not set
-# CONFIG_HZ_250 is not set
-# CONFIG_HZ_256 is not set
-CONFIG_HZ_1000=y
-# CONFIG_HZ_1024 is not set
-CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_HZ=1000
-CONFIG_PREEMPT_NONE=y
-# CONFIG_PREEMPT_VOLUNTARY is not set
-# CONFIG_PREEMPT is not set
-# CONFIG_KEXEC is not set
-CONFIG_LOCKDEP_SUPPORT=y
-CONFIG_STACKTRACE_SUPPORT=y
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_IPC_NS is not set
-CONFIG_SYSVIPC_SYSCTL=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_TASKSTATS is not set
-# CONFIG_UTS_NS is not set
-# CONFIG_AUDIT is not set
-# CONFIG_IKCONFIG is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_RELAY=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
-CONFIG_EMBEDDED=y
-CONFIG_SYSCTL_SYSCALL=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_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_SHMEM=y
-CONFIG_SLAB=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
-CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
-# Bus options (PCI, PCMCIA, EISA, ISA, TC)
-#
-CONFIG_HW_HAS_PCI=y
-CONFIG_PCI=y
-CONFIG_MMU=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-# CONFIG_PCCARD is not set
-
-#
-# PCI Hotplug Support
-#
-# CONFIG_HOTPLUG_PCI is not set
-
-#
-# Executable file formats
-#
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
-CONFIG_TRAD_SIGNALS=y
-
-#
-# Power management options
-#
-CONFIG_PM=y
-# CONFIG_PM_LEGACY is not set
-# CONFIG_PM_DEBUG is not set
-# CONFIG_PM_SYSFS_DEPRECATED is not set
-
-#
-# Networking
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-# CONFIG_NETDEBUG is not set
-# CONFIG_PACKET is not set
-CONFIG_UNIX=y
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-# CONFIG_XFRM_SUB_POLICY is not set
-CONFIG_XFRM_MIGRATE=y
-CONFIG_NET_KEY=y
-CONFIG_NET_KEY_MIGRATE=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_FIB_HASH=y
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_XFRM_TUNNEL is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_INET_XFRM_MODE_TRANSPORT=m
-CONFIG_INET_XFRM_MODE_TUNNEL=m
-CONFIG_INET_XFRM_MODE_BEET=m
-CONFIG_INET_DIAG=y
-CONFIG_INET_TCP_DIAG=y
-# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_CUBIC=y
-CONFIG_DEFAULT_TCP_CONG="cubic"
-CONFIG_TCP_MD5SIG=y
-# CONFIG_IPV6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
-CONFIG_NETWORK_SECMARK=y
-# CONFIG_NETFILTER is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
-# CONFIG_TIPC is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-CONFIG_IEEE80211=m
-# CONFIG_IEEE80211_DEBUG is not set
-CONFIG_IEEE80211_CRYPT_WEP=m
-CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_SOFTMAC=m
-# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
-CONFIG_WIRELESS_EXT=y
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
-# CONFIG_SYS_HYPERVISOR is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
-CONFIG_CONNECTOR=m
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG is not set
-# CONFIG_MTD_CONCAT is not set
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_CMDLINE_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLKDEVS=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-# CONFIG_RFD_FTL is not set
-# CONFIG_SSFDC is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_GEN_PROBE=y
-# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-# CONFIG_MTD_CFI_INTELEXT is not set
-CONFIG_MTD_CFI_AMDSTD=y
-# CONFIG_MTD_CFI_STAA is not set
-CONFIG_MTD_CFI_UTIL=y
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PHYSMAP is not set
-CONFIG_MTD_LASAT=y
-# CONFIG_MTD_PLATRAM is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_PMC551 is not set
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_PHRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLOCK2MTD is not set
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
-# CONFIG_MTD_NAND is not set
-
-#
-# OneNAND Flash Device Drivers
-#
-# CONFIG_MTD_ONENAND is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-# CONFIG_PNPACPI is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-# CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_SX8 is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
-CONFIG_ATA_OVER_ETH=m
-
-#
-# Misc devices
-#
-CONFIG_SGI_IOC4=m
-# CONFIG_TIFM_CORE is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=y
-CONFIG_IDE_MAX_HWIFS=4
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-CONFIG_IDEDISK_MULTI_MODE=y
-# CONFIG_BLK_DEV_IDECD is not set
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=y
-CONFIG_BLK_DEV_IDEPCI=y
-# CONFIG_IDEPCI_SHARE_IRQ is not set
-# CONFIG_BLK_DEV_OFFBOARD is not set
-CONFIG_BLK_DEV_GENERIC=y
-# CONFIG_BLK_DEV_OPTI621 is not set
-CONFIG_BLK_DEV_IDEDMA_PCI=y
-# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
-CONFIG_IDEDMA_PCI_AUTO=y
-# CONFIG_IDEDMA_ONLYDISK is not set
-# CONFIG_BLK_DEV_AEC62XX is not set
-# CONFIG_BLK_DEV_ALI15X3 is not set
-# CONFIG_BLK_DEV_AMD74XX is not set
-CONFIG_BLK_DEV_CMD64X=y
-# 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=m
-# 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_SLC90E66 is not set
-# CONFIG_BLK_DEV_TRM290 is not set
-# CONFIG_BLK_DEV_VIA82CXXX is not set
-CONFIG_BLK_DEV_TC86C001=m
-# CONFIG_IDE_ARM is not set
-CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_IDEDMA_IVB is not set
-CONFIG_IDEDMA_AUTO=y
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI device support
-#
-CONFIG_RAID_ATTRS=m
-# CONFIG_SCSI is not set
-# CONFIG_SCSI_NETLINK is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
-# CONFIG_ATA is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-# CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-
-#
-# PHY device support
-#
-CONFIG_PHYLIB=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 is not set
-# CONFIG_FIXED_PHY is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_CASSINI is not set
-# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_DM9000 is not set
-
-#
-# Tulip family network device support
-#
-# CONFIG_NET_TULIP is not set
-# CONFIG_HP100 is not set
-# CONFIG_NET_PCI is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SIS190 is not set
-# CONFIG_SKGE is not set
-# CONFIG_SKY2 is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_BNX2 is not set
-CONFIG_QLA3XXX=m
-# CONFIG_ATL1 is not set
-
-#
-# Ethernet (10000 Mbit)
-#
-# CONFIG_CHELSIO_T1 is not set
-CONFIG_CHELSIO_T3=m
-# CONFIG_IXGB is not set
-# CONFIG_S2IO is not set
-# CONFIG_MYRI10GE is not set
-CONFIG_NETXEN_NIC=m
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
-# CONFIG_PHONE is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input Device Drivers
-#
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Hardware I/O ports
-#
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-# CONFIG_GAMEPORT is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-CONFIG_VT_HW_CONSOLE_BINDING=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_PCI=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-# CONFIG_SERIAL_8250_EXTENDED is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_HW_RANDOM is not set
-# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-# CONFIG_DRM is not set
-# CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
-# CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# SPI support
-#
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
-
-#
-# Dallas's 1-wire bus
-#
-# CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
-# CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-
-#
-# Graphics support
-#
-# CONFIG_FIRMWARE_EDID is not set
-# CONFIG_FB is not set
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# HID Devices
-#
-# CONFIG_HID is not set
-
-#
-# USB support
-#
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
-CONFIG_USB_ARCH_HAS_EHCI=y
-# CONFIG_USB is not set
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
-#
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-
-#
-# LED devices
-#
-# CONFIG_NEW_LEDS is not set
-
-#
-# LED drivers
-#
-
-#
-# LED Triggers
-#
-
-#
-# InfiniBand support
-#
-# CONFIG_INFINIBAND is not set
-
-#
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
-#
-
-#
-# Real Time Clock
-#
-# CONFIG_RTC_CLASS is not set
-
-#
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
-
-#
-# Auxiliary Display support
-#
-
-#
-# Virtualization
-#
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT2_FS_XIP is not set
-CONFIG_EXT3_FS=y
-CONFIG_EXT3_FS_XATTR=y
-# CONFIG_EXT3_FS_POSIX_ACL is not set
-CONFIG_EXT3_FS_SECURITY=y
-# 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
-CONFIG_FS_POSIX_ACL=y
-# CONFIG_XFS_FS is not set
-# CONFIG_GFS2_FS is not set
-# CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_INOTIFY=y
-CONFIG_INOTIFY_USER=y
-# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-CONFIG_FUSE_FS=m
-CONFIG_GENERIC_ACL=y
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_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_RAMFS=y
-CONFIG_CONFIGFS_FS=m
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_ECRYPT_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 is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-# CONFIG_NFS_V3_ACL is not set
-# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-# CONFIG_NFSD is not set
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=y
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
-# CONFIG_NLS is not set
-
-#
-# Distributed Lock Manager
-#
-CONFIG_DLM=m
-CONFIG_DLM_TCP=y
-# CONFIG_DLM_SCTP is not set
-# CONFIG_DLM_DEBUG is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
-#
-# Kernel hacking
-#
-CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-# CONFIG_PRINTK_TIME is not set
-CONFIG_ENABLE_MUST_CHECK=y
-# 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_LOG_BUF_SHIFT=14
-CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE=""
-
-#
-# Security options
-#
-CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_BLKCIPHER=m
-CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_MANAGER=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_SHA1=m
-CONFIG_CRYPTO_SHA256=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_GF128MUL=m
-CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_CBC=m
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_DES=m
-CONFIG_CRYPTO_FCRYPT=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_TWOFISH_COMMON=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_AES=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_CRC32C=m
-CONFIG_CRYPTO_CAMELLIA=m
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Hardware crypto devices
-#
-
-#
-# Library routines
-#
-CONFIG_BITREVERSE=y
-# CONFIG_CRC_CCITT is not set
-CONFIG_CRC16=m
-CONFIG_CRC32=y
-CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=m
-CONFIG_ZLIB_DEFLATE=m
-CONFIG_PLIST=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
index 1f64d7632a0377c11cab145a01c5426e2c3ff704..546cb243fd09af64255ca9ea51db2b9d9f86ffb4 100644 (file)
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 CONFIG_MIPS_MALTA=y
 # CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_MIPS_MALTA=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
index a2db5c201216afafba86d9300378974b3bd1d404..6abad6f883132511646012b577c384bd2918ea2a 100644 (file)
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
 CONFIG_MIPS_SIM=y
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
@@ -496,36 +492,23 @@ CONFIG_NETDEVICES=y
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
-
-#
-# PHY device support
-#
+# CONFIG_PHYLIB is not set
 
 #
 # Ethernet (10 or 100Mbit)
 #
-# CONFIG_NET_ETHERNET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+CONFIG_MIPS_SIM_NET=y
+# CONFIG_DM9000 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
 
 #
-# Wan interfaces
+# Wireless LAN
 #
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
index ad5c0bf87b2b296f1c4b2e07dc3cb8300961dcc5..4981ce425d82c60159b4a93c095b2b81044b4fb9 100644 (file)
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
similarity index 51%
rename from arch/mips/configs/ocelot_3_defconfig
rename to arch/mips/configs/msp71xx_defconfig
index 28547313ce139c1bc8dbe5f34a89137fa8c5963d..adca5f7ba533976c2d16b9868017844158e61af8 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20
-# Tue Feb 20 21:47:35 2007
+# Linux kernel version: 2.6.21-rc4
+# Thu Apr 26 18:11:29 2007
 #
 CONFIG_MIPS=y
 
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -35,14 +33,13 @@ CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-CONFIG_MOMENCO_OCELOT_3=y
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
+CONFIG_PMC_MSP=y
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_QEMU is not set
 # CONFIG_MARKEINS is not set
@@ -62,6 +59,16 @@ CONFIG_MOMENCO_OCELOT_3=y
 # CONFIG_TOSHIBA_JMR3927 is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_PMC_MSP4200_EVAL is not set
+# CONFIG_PMC_MSP4200_GW is not set
+# CONFIG_PMC_MSP7120_EVAL is not set
+CONFIG_PMC_MSP7120_GW=y
+# CONFIG_PMC_MSP7120_FPGA is not set
+
+#
+# Options for PMC-Sierra MSP chipsets
+#
+CONFIG_PMC_MSP_EMBEDDED_ROOTFS=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
@@ -71,24 +78,24 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 # CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
+CONFIG_BOOT_RAW=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_NO_EXCEPT_FILL=y
 CONFIG_CPU_BIG_ENDIAN=y
 # CONFIG_CPU_LITTLE_ENDIAN is not set
 CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
 CONFIG_IRQ_CPU=y
-CONFIG_IRQ_CPU_RM7K=y
-CONFIG_IRQ_MV64340=y
-CONFIG_PCI_MARVELL=y
+CONFIG_IRQ_MSP_CIC=y
+CONFIG_MSP_USB=y
 CONFIG_SWAP_IO_SPACE=y
-CONFIG_BOOT_ELF32=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
 
 #
 # CPU selection
 #
 # CONFIG_CPU_MIPS32_R1 is not set
-# CONFIG_CPU_MIPS32_R2 is not set
+CONFIG_CPU_MIPS32_R2=y
 # CONFIG_CPU_MIPS64_R1 is not set
 # CONFIG_CPU_MIPS64_R2 is not set
 # CONFIG_CPU_R3000 is not set
@@ -104,14 +111,14 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
 # CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
 # CONFIG_CPU_RM7000 is not set
-CONFIG_CPU_RM9000=y
+# CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
-CONFIG_SYS_HAS_CPU_RM9000=y
-CONFIG_WEAK_ORDERING=y
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_SYS_HAS_CPU_MIPS32_R2=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR2=y
 CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
 
 #
 # Kernel type
@@ -122,13 +129,12 @@ CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
-CONFIG_BOARD_SCACHE=y
-CONFIG_RM7000_CPU_SCACHE=y
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
+CONFIG_SYS_SUPPORTS_MULTITHREADING=y
 # CONFIG_64BIT_PHYS_ADDR is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
@@ -149,15 +155,16 @@ CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
-# CONFIG_HZ_250 is not set
+CONFIG_HZ_250=y
 # CONFIG_HZ_256 is not set
-CONFIG_HZ_1000=y
+# CONFIG_HZ_1000 is not set
 # CONFIG_HZ_1024 is not set
 CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_HZ=1000
-CONFIG_PREEMPT_NONE=y
+CONFIG_HZ=250
+# CONFIG_PREEMPT_NONE is not set
 # CONFIG_PREEMPT_VOLUNTARY is not set
-# CONFIG_PREEMPT is not set
+CONFIG_PREEMPT=y
+# CONFIG_PREEMPT_BKL is not set
 # CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -168,14 +175,15 @@ CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 #
 CONFIG_EXPERIMENTAL=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
 #
-CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION="-pmc"
 CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
+# CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
 # CONFIG_IPC_NS is not set
 CONFIG_SYSVIPC_SYSCTL=y
@@ -184,15 +192,16 @@ CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_TASKSTATS is not set
 # CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
+# CONFIG_IKCONFIG is not set
 CONFIG_SYSFS_DEPRECATED=y
-CONFIG_RELAY=y
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
@@ -201,11 +210,11 @@ CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-CONFIG_SHMEM=y
+# CONFIG_SHMEM is not set
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
+CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
 
@@ -232,8 +241,8 @@ CONFIG_BLOCK=y
 #
 CONFIG_IOSCHED_NOOP=y
 CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
 CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
@@ -245,6 +254,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 #
 CONFIG_HW_HAS_PCI=y
 CONFIG_PCI=y
+# CONFIG_PCI_DEBUG is not set
 CONFIG_MMU=y
 
 #
@@ -267,10 +277,7 @@ CONFIG_TRAD_SIGNALS=y
 #
 # Power management options
 #
-CONFIG_PM=y
-# CONFIG_PM_LEGACY is not set
-# CONFIG_PM_DEBUG is not set
-# CONFIG_PM_SYSFS_DEPRECATED is not set
+# CONFIG_PM is not set
 
 #
 # Networking
@@ -281,17 +288,16 @@ CONFIG_NET=y
 # Networking options
 #
 # CONFIG_NETDEBUG is not set
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
+# CONFIG_PACKET is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
+CONFIG_XFRM_USER=y
 # CONFIG_XFRM_SUB_POLICY is not set
-CONFIG_XFRM_MIGRATE=y
+# CONFIG_XFRM_MIGRATE is not set
 CONFIG_NET_KEY=y
-CONFIG_NET_KEY_MIGRATE=y
+# CONFIG_NET_KEY_MIGRATE is not set
 CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
+CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
 CONFIG_IP_FIB_HASH=y
 CONFIG_IP_PNP=y
@@ -300,122 +306,92 @@ CONFIG_IP_PNP_BOOTP=y
 # CONFIG_IP_PNP_RARP is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
 # CONFIG_ARPD is not set
 # CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_XFRM_TUNNEL is not set
-CONFIG_INET_TUNNEL=m
-CONFIG_INET_XFRM_MODE_TRANSPORT=m
-CONFIG_INET_XFRM_MODE_TUNNEL=m
-CONFIG_INET_XFRM_MODE_BEET=m
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_XFRM_TUNNEL=y
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
-CONFIG_TCP_MD5SIG=y
+# CONFIG_TCP_MD5SIG is not set
 
 #
 # IP: Virtual Server Configuration
 #
 # CONFIG_IP_VS is not set
-CONFIG_IPV6=m
-# CONFIG_IPV6_PRIVACY is not set
-CONFIG_IPV6_ROUTER_PREF=y
-CONFIG_IPV6_ROUTE_INFO=y
-# CONFIG_INET6_AH is not set
-# CONFIG_INET6_ESP is not set
-# CONFIG_INET6_IPCOMP is not set
-CONFIG_IPV6_MIP6=y
+# CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
-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_TUNNEL is not set
-CONFIG_IPV6_MULTIPLE_TABLES=y
-CONFIG_IPV6_SUBTREES=y
-CONFIG_NETWORK_SECMARK=y
+# CONFIG_NETWORK_SECMARK is not set
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
 
 #
 # Core Netfilter Configuration
 #
-CONFIG_NETFILTER_NETLINK=m
-CONFIG_NETFILTER_NETLINK_QUEUE=m
-CONFIG_NETFILTER_NETLINK_LOG=m
-CONFIG_NF_CONNTRACK_ENABLED=m
-CONFIG_NF_CONNTRACK_SUPPORT=y
-# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set
-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_GRE=m
-CONFIG_NF_CT_PROTO_SCTP=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 is not set
-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_MARK=m
-CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
-CONFIG_NETFILTER_XT_TARGET_NFLOG=m
-CONFIG_NETFILTER_XT_TARGET_SECMARK=m
-CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
-CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
-CONFIG_NETFILTER_XT_MATCH_COMMENT=m
-CONFIG_NETFILTER_XT_MATCH_CONNBYTES=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_LENGTH=m
-CONFIG_NETFILTER_XT_MATCH_LIMIT=m
-CONFIG_NETFILTER_XT_MATCH_MAC=m
-CONFIG_NETFILTER_XT_MATCH_MARK=m
-CONFIG_NETFILTER_XT_MATCH_POLICY=m
-CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
-CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
-CONFIG_NETFILTER_XT_MATCH_QUOTA=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_HASHLIMIT=m
+# CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NF_CONNTRACK_ENABLED is not set
+CONFIG_NETFILTER_XTABLES=y
+# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
+# CONFIG_NETFILTER_XT_TARGET_MARK is not set
+# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
+# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
+# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
+# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
+# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
+# CONFIG_NETFILTER_XT_MATCH_ESP is not set
+# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
+# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_MAC is not set
+# CONFIG_NETFILTER_XT_MATCH_MARK is not set
+# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
+# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
+# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set
+# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
+# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
+# CONFIG_NETFILTER_XT_MATCH_REALM is not set
+# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
+# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
+# CONFIG_NETFILTER_XT_MATCH_STRING is not set
+# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
+# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
 
 #
 # IP: Netfilter Configuration
 #
-CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 # CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
+CONFIG_IP_NF_IPTABLES=y
+# CONFIG_IP_NF_MATCH_IPRANGE is not set
+# CONFIG_IP_NF_MATCH_TOS is not set
+# CONFIG_IP_NF_MATCH_RECENT is not set
+# CONFIG_IP_NF_MATCH_ECN is not set
+# CONFIG_IP_NF_MATCH_AH is not set
+# CONFIG_IP_NF_MATCH_TTL is not set
+# CONFIG_IP_NF_MATCH_OWNER is not set
+# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+# CONFIG_IP_NF_TARGET_LOG is not set
+# CONFIG_IP_NF_TARGET_ULOG is not set
+# CONFIG_IP_NF_MANGLE is not set
+# CONFIG_IP_NF_RAW is not set
 # CONFIG_IP_NF_ARPTABLES is not set
 
 #
-# IPv6: Netfilter Configuration (EXPERIMENTAL)
+# Bridge: Netfilter Configuration
 #
-CONFIG_NF_CONNTRACK_IPV6=m
-# CONFIG_IP6_NF_QUEUE is not set
-# CONFIG_IP6_NF_IPTABLES is not set
+# CONFIG_BRIDGE_NF_EBTABLES is not set
 
 #
 # DCCP Configuration (EXPERIMENTAL)
@@ -432,9 +408,10 @@ CONFIG_NF_CONNTRACK_IPV6=m
 #
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
+CONFIG_BRIDGE=y
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
+CONFIG_LLC=y
 # CONFIG_LLC2 is not set
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
@@ -447,7 +424,6 @@ CONFIG_NF_CONNTRACK_IPV6=m
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-CONFIG_NET_CLS_ROUTE=y
 
 #
 # Network testing
@@ -456,14 +432,8 @@ CONFIG_NET_CLS_ROUTE=y
 # CONFIG_HAMRADIO is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
-CONFIG_IEEE80211=m
-# CONFIG_IEEE80211_DEBUG is not set
-CONFIG_IEEE80211_CRYPT_WEP=m
-CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_SOFTMAC=m
-# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
+# CONFIG_IEEE80211 is not set
 CONFIG_WIRELESS_EXT=y
-CONFIG_FIB_RULES=y
 
 #
 # Device Drivers
@@ -473,19 +443,101 @@ CONFIG_FIB_RULES=y
 # Generic Driver Options
 #
 CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
 # CONFIG_SYS_HYPERVISOR is not set
 
 #
 # Connector - unified userspace <-> kernelspace linker
 #
-CONFIG_CONNECTOR=m
+# CONFIG_CONNECTOR is not set
 
 #
 # Memory Technology Devices (MTD)
 #
-# CONFIG_MTD is not set
+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
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+CONFIG_MTD_RAM=y
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_PMC_MSP_EVM=y
+CONFIG_MSP_FLASH_MAP_LIMIT_32M=y
+CONFIG_MSP_FLASH_MAP_LIMIT=0x02000000
+CONFIG_MTD_PMC_MSP_RAMROOT=y
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
 
 #
 # Parallel port support
@@ -505,19 +557,21 @@ CONFIG_CONNECTOR=m
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD 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=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_CDROM_PKTCDVD is not set
-CONFIG_ATA_OVER_ETH=m
+# CONFIG_ATA_OVER_ETH is not set
 
 #
 # Misc devices
 #
-CONFIG_SGI_IOC4=m
+# CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
 
 #
@@ -528,16 +582,16 @@ CONFIG_SGI_IOC4=m
 #
 # SCSI device support
 #
-CONFIG_RAID_ATTRS=m
-CONFIG_SCSI=m
-CONFIG_SCSI_TGT=m
-CONFIG_SCSI_NETLINK=y
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
 #
 # SCSI support type (disk, tape, CD-ROM)
 #
-# CONFIG_BLK_DEV_SD is not set
+CONFIG_BLK_DEV_SD=y
 # CONFIG_CHR_DEV_ST is not set
 # CONFIG_CHR_DEV_OSST is not set
 # CONFIG_BLK_DEV_SR is not set
@@ -550,22 +604,21 @@ CONFIG_SCSI_PROC_FS=y
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
-CONFIG_SCSI_SCAN_ASYNC=y
+# CONFIG_SCSI_SCAN_ASYNC is not set
 
 #
 # SCSI Transports
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
-CONFIG_SCSI_FC_ATTRS=m
-CONFIG_SCSI_ISCSI_ATTRS=m
-CONFIG_SCSI_SAS_ATTRS=m
-CONFIG_SCSI_SAS_LIBSAS=m
-# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
+# 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
 
 #
 # SCSI low-level drivers
 #
-CONFIG_ISCSI_TCP=m
+# CONFIG_ISCSI_TCP is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 # CONFIG_SCSI_3W_9XXX is not set
 # CONFIG_SCSI_ACARD is not set
@@ -573,8 +626,7 @@ CONFIG_ISCSI_TCP=m
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
-CONFIG_SCSI_AIC94XX=m
-# CONFIG_AIC94XX_DEBUG is not set
+# CONFIG_SCSI_AIC94XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
@@ -630,10 +682,10 @@ CONFIG_SCSI_AIC94XX=m
 # Network device support
 #
 CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
+CONFIG_DUMMY=y
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
-CONFIG_TUN=m
+# CONFIG_TUN is not set
 
 #
 # ARCnet devices
@@ -643,26 +695,16 @@ CONFIG_TUN=m
 #
 # PHY device support
 #
-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 is not set
-# CONFIG_FIXED_PHY is not set
+# CONFIG_PHYLIB is not set
 
 #
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
+CONFIG_MSPETH=y
+CONFIG_MSPETH_NAPI=y
+# CONFIG_MSPETH_SKB_RECYCLE is not set
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
@@ -674,26 +716,7 @@ CONFIG_MII=y
 #
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
-CONFIG_NET_PCI=y
-# CONFIG_PCNET32 is not set
-# CONFIG_AMD8111_ETH is not set
-# CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_B44 is not set
-# CONFIG_FORCEDETH is not set
-# CONFIG_DGRS is not set
-# CONFIG_EEPRO100 is not set
-CONFIG_E100=y
-# CONFIG_FEALNX is not set
-# CONFIG_NATSEMI is not set
-# CONFIG_NE2K_PCI is not set
-# CONFIG_8139CP is not set
-# CONFIG_8139TOO is not set
-# CONFIG_SIS900 is not set
-# CONFIG_EPIC100 is not set
-# CONFIG_SUNDANCE is not set
-# CONFIG_TLAN is not set
-# CONFIG_VIA_RHINE is not set
-# CONFIG_SC92031 is not set
+# CONFIG_NET_PCI is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -709,22 +732,20 @@ CONFIG_E100=y
 # CONFIG_SKGE is not set
 # CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
-# CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
-CONFIG_MV643XX_ETH=y
-CONFIG_QLA3XXX=m
+# CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
-CONFIG_CHELSIO_T3=m
+# CONFIG_CHELSIO_T3 is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
-CONFIG_NETXEN_NIC=m
+# CONFIG_NETXEN_NIC is not set
 
 #
 # Token Ring devices
@@ -734,7 +755,29 @@ CONFIG_NETXEN_NIC=m
 #
 # Wireless LAN (non-hamradio)
 #
-# CONFIG_NET_RADIO is not set
+CONFIG_NET_RADIO=y
+# CONFIG_NET_WIRELESS_RTNETLINK is not set
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
+# CONFIG_HERMES is not set
+# CONFIG_ATMEL is not set
+
+#
+# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+#
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
+CONFIG_NET_WIRELESS=y
 
 #
 # Wan interfaces
@@ -742,17 +785,17 @@ CONFIG_NETXEN_NIC=m
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
-CONFIG_PPP=m
+CONFIG_PPP=y
 # CONFIG_PPP_MULTILINK is not set
 # CONFIG_PPP_FILTER is not set
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_ASYNC is not set
+# CONFIG_PPP_SYNC_TTY is not set
+# CONFIG_PPP_DEFLATE is not set
 # CONFIG_PPP_BSDCOMP is not set
-CONFIG_PPP_MPPE=m
-CONFIG_PPPOE=m
+# CONFIG_PPP_MPPE is not set
+# CONFIG_PPPOE is not set
 # CONFIG_SLIP is not set
-CONFIG_SLHC=m
+CONFIG_SLHC=y
 # CONFIG_NET_FC is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
@@ -796,31 +839,24 @@ CONFIG_INPUT=y
 #
 # Hardware I/O ports
 #
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-# CONFIG_SERIO_RAW is not set
+# 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=y
+# CONFIG_VT is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_PMCMSP_GPIO=y
 
 #
 # Serial drivers
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_PCI=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_PCI is not set
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
@@ -830,8 +866,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_LEGACY_PTYS is not set
 
 #
 # IPMI
@@ -843,7 +878,8 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # CONFIG_WATCHDOG is not set
 # CONFIG_HW_RANDOM is not set
-CONFIG_RTC=y
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -858,7 +894,58 @@ CONFIG_RTC=y
 #
 # I2C support
 #
-# CONFIG_I2C is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PASEMI is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 is not set
+# CONFIG_I2C_PCA_ISA is not set
+CONFIG_I2C_PMCMSP=y
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+CONFIG_PMCTWILED=y
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
 
 #
 # SPI support
@@ -874,8 +961,57 @@ CONFIG_RTC=y
 #
 # Hardware Monitoring support
 #
-# CONFIG_HWMON is not set
+CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_VT8231 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
 
 #
 # Multimedia devices
@@ -886,62 +1022,13 @@ CONFIG_RTC=y
 # Digital Video Broadcasting Devices
 #
 # CONFIG_DVB is not set
+# CONFIG_USB_DABUSB is not set
 
 #
 # Graphics support
 #
-# CONFIG_FIRMWARE_EDID is not set
-CONFIG_FB=y
-# CONFIG_FB_CFB_FILLRECT is not set
-# CONFIG_FB_CFB_COPYAREA is not set
-# CONFIG_FB_CFB_IMAGEBLIT 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=y
-# CONFIG_FB_TILEBLITTING is not set
-# CONFIG_FB_CIRRUS is not set
-# CONFIG_FB_PM2 is not set
-# CONFIG_FB_CYBER2000 is not set
-# CONFIG_FB_ASILIANT is not set
-# CONFIG_FB_IMSTT is not set
-# CONFIG_FB_S1D13XXX is not set
-# CONFIG_FB_NVIDIA is not set
-# CONFIG_FB_RIVA is not set
-# CONFIG_FB_MATROX is not set
-# CONFIG_FB_RADEON is not set
-# CONFIG_FB_ATY128 is not set
-# CONFIG_FB_ATY is not set
-# CONFIG_FB_S3 is not set
-# CONFIG_FB_SAVAGE is not set
-# CONFIG_FB_SIS is not set
-# CONFIG_FB_NEOMAGIC is not set
-# CONFIG_FB_KYRO is not set
-# CONFIG_FB_3DFX is not set
-# CONFIG_FB_VOODOO1 is not set
-# CONFIG_FB_SMIVGX is not set
-# CONFIG_FB_TRIDENT is not set
-# CONFIG_FB_VIRTUAL is not set
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
-# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
-# CONFIG_FONTS is not set
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
-
-#
-# Logo configuration
-#
-CONFIG_LOGO=y
-CONFIG_LOGO_LINUX_MONO=y
-CONFIG_LOGO_LINUX_VGA16=y
-CONFIG_LOGO_LINUX_CLUT224=y
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_FB is not set
 
 #
 # Sound
@@ -960,12 +1047,133 @@ CONFIG_HID=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB_ARCH_HAS_EHCI=y
-# CONFIG_USB is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_SPLIT_ISO is not set
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
 
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_TOUCHSCREEN is not set
+# CONFIG_USB_YEALINK is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_ATI_REMOTE2 is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+# CONFIG_USB_GTCO is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET_MII is not set
+# CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_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_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
 #
 # USB Gadget Support
 #
@@ -1030,37 +1238,22 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 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_EXT3_FS is not set
 # CONFIG_EXT4DEV_FS is not set
-CONFIG_JBD=m
-# CONFIG_JBD_DEBUG is not set
-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 is not set
+# CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-CONFIG_FS_POSIX_ACL=y
-CONFIG_XFS_FS=m
-# CONFIG_XFS_QUOTA is not set
-# CONFIG_XFS_SECURITY is not set
-# CONFIG_XFS_POSIX_ACL is not set
-# CONFIG_XFS_RT is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
-CONFIG_INOTIFY=y
-CONFIG_INOTIFY_USER=y
+# CONFIG_INOTIFY is not set
 # CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-CONFIG_AUTOFS_FS=y
-CONFIG_AUTOFS4_FS=m
-CONFIG_FUSE_FS=m
-CONFIG_GENERIC_ACL=y
+# CONFIG_DNOTIFY is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -1071,22 +1264,25 @@ CONFIG_GENERIC_ACL=y
 #
 # DOS/FAT/NT Filesystems
 #
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+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_KCORE=y
+# CONFIG_PROC_KCORE is not set
 CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-CONFIG_CONFIGFS_FS=m
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -1097,8 +1293,21 @@ CONFIG_CONFIGFS_FS=m
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
-CONFIG_EFS_FS=y
-CONFIG_CRAMFS=y
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_CRAMFS is not set
+CONFIG_SQUASHFS=y
+CONFIG_SQUASHFS_EMBEDDED=y
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+CONFIG_SQUASHFS_VMALLOC=y
 # CONFIG_VXFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
@@ -1108,26 +1317,9 @@ CONFIG_CRAMFS=y
 #
 # Network File Systems
 #
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-# CONFIG_NFS_V3_ACL is not set
-# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
-# CONFIG_NFSD_V3_ACL is not set
-# CONFIG_NFSD_V4 is not set
-# CONFIG_NFSD_TCP is not set
-CONFIG_ROOT_NFS=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=y
-CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=y
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
-CONFIG_SMB_FS=m
-# CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_NFS_FS is not set
+# CONFIG_NFSD is not set
+# CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1143,9 +1335,9 @@ CONFIG_MSDOS_PARTITION=y
 #
 # Native Language Support
 #
-CONFIG_NLS=m
+CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="iso8859-1"
-# CONFIG_NLS_CODEPAGE_437 is not set
+CONFIG_NLS_CODEPAGE_437=y
 # CONFIG_NLS_CODEPAGE_737 is not set
 # CONFIG_NLS_CODEPAGE_775 is not set
 # CONFIG_NLS_CODEPAGE_850 is not set
@@ -1169,7 +1361,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # CONFIG_NLS_CODEPAGE_1250 is not set
 # CONFIG_NLS_CODEPAGE_1251 is not set
 # CONFIG_NLS_ASCII is not set
-# CONFIG_NLS_ISO8859_1 is not set
+CONFIG_NLS_ISO8859_1=y
 # CONFIG_NLS_ISO8859_2 is not set
 # CONFIG_NLS_ISO8859_3 is not set
 # CONFIG_NLS_ISO8859_4 is not set
@@ -1187,10 +1379,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 #
 # Distributed Lock Manager
 #
-CONFIG_DLM=m
-CONFIG_DLM_TCP=y
-# CONFIG_DLM_SCTP is not set
-# CONFIG_DLM_DEBUG is not set
+# CONFIG_DLM is not set
 
 #
 # Profiling support
@@ -1203,14 +1392,40 @@ CONFIG_DLM_TCP=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 CONFIG_ENABLE_MUST_CHECK=y
-# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_MAGIC_SYSRQ=y
 # 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_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
 CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_DEBUG_PREEMPT=y
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
 CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE="ip=any root=nfs"
+CONFIG_CMDLINE=""
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_KGDB is not set
+CONFIG_SYS_SUPPORTS_KGDB=y
+# CONFIG_RUNTIME_DEBUG is not set
+# CONFIG_MIPS_UNCACHED is not set
 
 #
 # Security options
@@ -1223,41 +1438,40 @@ CONFIG_CMDLINE="ip=any root=nfs"
 #
 CONFIG_CRYPTO=y
 CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_BLKCIPHER=y
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_MD4=m
+# CONFIG_CRYPTO_XCBC is not set
+CONFIG_CRYPTO_NULL=y
+# CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_SHA1=m
-CONFIG_CRYPTO_SHA256=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_GF128MUL=m
-CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_CBC=m
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_DES=m
-CONFIG_CRYPTO_FCRYPT=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_TWOFISH_COMMON=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_AES=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_CRC32C=m
-CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_SHA1=y
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_ECB is not set
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
 # CONFIG_CRYPTO_TEST is not set
 
 #
@@ -1268,16 +1482,12 @@ CONFIG_CRYPTO_CAMELLIA=m
 # Library routines
 #
 CONFIG_BITREVERSE=y
-CONFIG_CRC_CCITT=m
-CONFIG_CRC16=m
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
 CONFIG_CRC32=y
-CONFIG_LIBCRC32C=m
+# CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=m
-CONFIG_TEXTSEARCH=y
-CONFIG_TEXTSEARCH_KMP=m
-CONFIG_TEXTSEARCH_BM=m
-CONFIG_TEXTSEARCH_FSM=m
+CONFIG_ZLIB_DEFLATE=y
 CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/ocelot_c_defconfig b/arch/mips/configs/ocelot_c_defconfig
deleted file mode 100644 (file)
index 82ff6fc..0000000
+++ /dev/null
@@ -1,982 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20
-# Tue Feb 20 21:47:36 2007
-#
-CONFIG_MIPS=y
-
-#
-# Machine selection
-#
-CONFIG_ZONE_DMA=y
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-# CONFIG_MIPS_PB1500 is not set
-# CONFIG_MIPS_PB1550 is not set
-# CONFIG_MIPS_PB1200 is not set
-# CONFIG_MIPS_DB1000 is not set
-# CONFIG_MIPS_DB1100 is not set
-# CONFIG_MIPS_DB1500 is not set
-# CONFIG_MIPS_DB1550 is not set
-# CONFIG_MIPS_DB1200 is not set
-# CONFIG_MIPS_MIRAGE is not set
-# CONFIG_BASLER_EXCITE is not set
-# CONFIG_MIPS_COBALT is not set
-# CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
-# CONFIG_MIPS_ATLAS is not set
-# CONFIG_MIPS_MALTA is not set
-# CONFIG_MIPS_SEAD is not set
-# CONFIG_WR_PPMC is not set
-# CONFIG_MIPS_SIM is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-CONFIG_MOMENCO_OCELOT_C=y
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_JBS is not set
-# CONFIG_PNX8550_STB810 is not set
-# CONFIG_DDB5477 is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_PMC_YOSEMITE is not set
-# CONFIG_QEMU is not set
-# CONFIG_MARKEINS is not set
-# CONFIG_SGI_IP22 is not set
-# CONFIG_SGI_IP27 is not set
-# CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_BIGSUR is not set
-# CONFIG_SIBYTE_SWARM is not set
-# CONFIG_SIBYTE_SENTOSA is not set
-# CONFIG_SIBYTE_RHONE is not set
-# CONFIG_SIBYTE_CARMEL is not set
-# CONFIG_SIBYTE_PTSWARM is not set
-# CONFIG_SIBYTE_LITTLESUR is not set
-# CONFIG_SIBYTE_CRHINE is not set
-# CONFIG_SIBYTE_CRHONE is not set
-# CONFIG_SNI_RM is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
-# CONFIG_TOSHIBA_RBTX4927 is not set
-# CONFIG_TOSHIBA_RBTX4938 is not set
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
-CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_TIME=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_DMA_NONCOHERENT=y
-CONFIG_DMA_NEED_PCI_MAP_STATE=y
-CONFIG_CPU_BIG_ENDIAN=y
-# CONFIG_CPU_LITTLE_ENDIAN is not set
-CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
-CONFIG_IRQ_CPU=y
-CONFIG_IRQ_MV64340=y
-CONFIG_PCI_MARVELL=y
-CONFIG_SWAP_IO_SPACE=y
-CONFIG_MIPS_L1_CACHE_SHIFT=5
-
-#
-# CPU selection
-#
-# CONFIG_CPU_MIPS32_R1 is not set
-# CONFIG_CPU_MIPS32_R2 is not set
-# CONFIG_CPU_MIPS64_R1 is not set
-# CONFIG_CPU_MIPS64_R2 is not set
-# CONFIG_CPU_R3000 is not set
-# CONFIG_CPU_TX39XX is not set
-# CONFIG_CPU_VR41XX is not set
-# CONFIG_CPU_R4300 is not set
-# CONFIG_CPU_R4X00 is not set
-# CONFIG_CPU_TX49XX is not set
-# CONFIG_CPU_R5000 is not set
-# CONFIG_CPU_R5432 is not set
-# CONFIG_CPU_R6000 is not set
-# CONFIG_CPU_NEVADA is not set
-# CONFIG_CPU_R8000 is not set
-# CONFIG_CPU_R10000 is not set
-CONFIG_CPU_RM7000=y
-# CONFIG_CPU_RM9000 is not set
-# CONFIG_CPU_SB1 is not set
-CONFIG_SYS_HAS_CPU_RM7000=y
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
-
-#
-# Kernel type
-#
-# CONFIG_32BIT is not set
-CONFIG_64BIT=y
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_8KB is not set
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
-CONFIG_BOARD_SCACHE=y
-CONFIG_RM7000_CPU_SCACHE=y
-CONFIG_CPU_HAS_PREFETCH=y
-CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMP is not set
-# CONFIG_MIPS_MT_SMTC is not set
-# CONFIG_MIPS_VPE_LOADER is not set
-CONFIG_CPU_HAS_LLSC=y
-CONFIG_CPU_HAS_SYNC=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_CPU_SUPPORTS_HIGHMEM=y
-CONFIG_ARCH_FLATMEM_ENABLE=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_SPLIT_PTLOCK_CPUS=4
-CONFIG_RESOURCES_64BIT=y
-CONFIG_ZONE_DMA_FLAG=1
-# CONFIG_HZ_48 is not set
-# CONFIG_HZ_100 is not set
-# CONFIG_HZ_128 is not set
-# CONFIG_HZ_250 is not set
-# CONFIG_HZ_256 is not set
-CONFIG_HZ_1000=y
-# CONFIG_HZ_1024 is not set
-CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_HZ=1000
-CONFIG_PREEMPT_NONE=y
-# CONFIG_PREEMPT_VOLUNTARY is not set
-# CONFIG_PREEMPT is not set
-# CONFIG_KEXEC is not set
-CONFIG_LOCKDEP_SUPPORT=y
-CONFIG_STACKTRACE_SUPPORT=y
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_IPC_NS is not set
-CONFIG_SYSVIPC_SYSCTL=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_TASKSTATS is not set
-# CONFIG_UTS_NS is not set
-# CONFIG_AUDIT is not set
-# CONFIG_IKCONFIG is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_RELAY=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
-CONFIG_EMBEDDED=y
-CONFIG_SYSCTL_SYSCALL=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_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_SHMEM=y
-CONFIG_SLAB=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
-# CONFIG_MODULES is not set
-
-#
-# Block layer
-#
-CONFIG_BLOCK=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
-# Bus options (PCI, PCMCIA, EISA, ISA, TC)
-#
-CONFIG_HW_HAS_PCI=y
-CONFIG_PCI=y
-CONFIG_MMU=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-# CONFIG_PCCARD is not set
-
-#
-# PCI Hotplug Support
-#
-# CONFIG_HOTPLUG_PCI is not set
-
-#
-# Executable file formats
-#
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
-# CONFIG_BUILD_ELF64 is not set
-CONFIG_MIPS32_COMPAT=y
-CONFIG_COMPAT=y
-CONFIG_SYSVIPC_COMPAT=y
-CONFIG_MIPS32_O32=y
-CONFIG_MIPS32_N32=y
-CONFIG_BINFMT_ELF32=y
-
-#
-# Power management options
-#
-CONFIG_PM=y
-# CONFIG_PM_LEGACY is not set
-# CONFIG_PM_DEBUG is not set
-# CONFIG_PM_SYSFS_DEPRECATED is not set
-
-#
-# Networking
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-# CONFIG_NETDEBUG is not set
-# CONFIG_PACKET is not set
-CONFIG_UNIX=y
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=y
-# CONFIG_XFRM_SUB_POLICY is not set
-CONFIG_XFRM_MIGRATE=y
-CONFIG_NET_KEY=y
-CONFIG_NET_KEY_MIGRATE=y
-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 is not set
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_XFRM_TUNNEL is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_INET_XFRM_MODE_TRANSPORT=y
-CONFIG_INET_XFRM_MODE_TUNNEL=y
-CONFIG_INET_XFRM_MODE_BEET=y
-CONFIG_INET_DIAG=y
-CONFIG_INET_TCP_DIAG=y
-# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_CUBIC=y
-CONFIG_DEFAULT_TCP_CONG="cubic"
-CONFIG_TCP_MD5SIG=y
-# CONFIG_IPV6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
-CONFIG_NETWORK_SECMARK=y
-# CONFIG_NETFILTER is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
-# CONFIG_TIPC is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-CONFIG_IEEE80211=y
-# CONFIG_IEEE80211_DEBUG is not set
-CONFIG_IEEE80211_CRYPT_WEP=y
-CONFIG_IEEE80211_CRYPT_CCMP=y
-CONFIG_IEEE80211_SOFTMAC=y
-# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
-CONFIG_WIRELESS_EXT=y
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=y
-# CONFIG_SYS_HYPERVISOR is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
-CONFIG_CONNECTOR=y
-CONFIG_PROC_EVENTS=y
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-# CONFIG_PNPACPI is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-# CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_SX8 is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_CDROM_PKTCDVD=y
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
-CONFIG_ATA_OVER_ETH=y
-
-#
-# Misc devices
-#
-CONFIG_SGI_IOC4=y
-# CONFIG_TIFM_CORE is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-# CONFIG_IDE is not set
-
-#
-# SCSI device support
-#
-CONFIG_RAID_ATTRS=y
-# CONFIG_SCSI is not set
-# CONFIG_SCSI_NETLINK is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
-# CONFIG_ATA is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-# CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-
-#
-# PHY device support
-#
-CONFIG_PHYLIB=y
-
-#
-# MII PHY device drivers
-#
-CONFIG_MARVELL_PHY=y
-CONFIG_DAVICOM_PHY=y
-CONFIG_QSEMI_PHY=y
-CONFIG_LXT_PHY=y
-CONFIG_CICADA_PHY=y
-CONFIG_VITESSE_PHY=y
-CONFIG_SMSC_PHY=y
-# CONFIG_BROADCOM_PHY is not set
-# CONFIG_FIXED_PHY is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_CASSINI is not set
-# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_DM9000 is not set
-
-#
-# Tulip family network device support
-#
-# CONFIG_NET_TULIP is not set
-# CONFIG_HP100 is not set
-# CONFIG_NET_PCI is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SIS190 is not set
-# CONFIG_SKGE is not set
-# CONFIG_SKY2 is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_BNX2 is not set
-# CONFIG_MV643XX_ETH is not set
-CONFIG_QLA3XXX=y
-# CONFIG_ATL1 is not set
-
-#
-# Ethernet (10000 Mbit)
-#
-# CONFIG_CHELSIO_T1 is not set
-CONFIG_CHELSIO_T3=y
-# CONFIG_IXGB is not set
-# CONFIG_S2IO is not set
-# CONFIG_MYRI10GE is not set
-CONFIG_NETXEN_NIC=y
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
-# CONFIG_PHONE is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input Device Drivers
-#
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Hardware I/O ports
-#
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=y
-# CONFIG_GAMEPORT is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-CONFIG_VT_HW_CONSOLE_BINDING=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_PCI=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-# CONFIG_SERIAL_8250_EXTENDED is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_HW_RANDOM is not set
-# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-# CONFIG_DRM is not set
-# CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
-# CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# SPI support
-#
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
-
-#
-# Dallas's 1-wire bus
-#
-# CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
-# CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-
-#
-# Graphics support
-#
-# CONFIG_FIRMWARE_EDID is not set
-# CONFIG_FB is not set
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# HID Devices
-#
-# CONFIG_HID is not set
-
-#
-# USB support
-#
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
-CONFIG_USB_ARCH_HAS_EHCI=y
-# CONFIG_USB is not set
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
-#
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-
-#
-# LED devices
-#
-# CONFIG_NEW_LEDS is not set
-
-#
-# LED drivers
-#
-
-#
-# LED Triggers
-#
-
-#
-# InfiniBand support
-#
-# CONFIG_INFINIBAND is not set
-
-#
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
-#
-
-#
-# Real Time Clock
-#
-# CONFIG_RTC_CLASS is not set
-
-#
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
-
-#
-# Auxiliary Display support
-#
-
-#
-# Virtualization
-#
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT2_FS_XIP is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_EXT4DEV_FS is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-CONFIG_FS_POSIX_ACL=y
-# CONFIG_XFS_FS is not set
-# CONFIG_GFS2_FS is not set
-# CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_INOTIFY=y
-CONFIG_INOTIFY_USER=y
-# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-CONFIG_FUSE_FS=y
-CONFIG_GENERIC_ACL=y
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_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_RAMFS=y
-CONFIG_CONFIGFS_FS=y
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_ECRYPT_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_CRAMFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
-# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-CONFIG_NFSD=y
-# CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_TCP is not set
-CONFIG_ROOT_NFS=y
-CONFIG_LOCKD=y
-CONFIG_EXPORTFS=y
-CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=y
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
-# CONFIG_NLS is not set
-
-#
-# Distributed Lock Manager
-#
-CONFIG_DLM=y
-CONFIG_DLM_TCP=y
-# CONFIG_DLM_SCTP is not set
-# CONFIG_DLM_DEBUG is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
-#
-# Kernel hacking
-#
-CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-# CONFIG_PRINTK_TIME is not set
-CONFIG_ENABLE_MUST_CHECK=y
-# 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_LOG_BUF_SHIFT=14
-CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE=""
-
-#
-# Security options
-#
-CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_BLKCIPHER=y
-CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_MANAGER=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_XCBC=y
-CONFIG_CRYPTO_NULL=y
-CONFIG_CRYPTO_MD4=y
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_SHA1=y
-CONFIG_CRYPTO_SHA256=y
-CONFIG_CRYPTO_SHA512=y
-CONFIG_CRYPTO_WP512=y
-CONFIG_CRYPTO_TGR192=y
-CONFIG_CRYPTO_GF128MUL=y
-CONFIG_CRYPTO_ECB=y
-CONFIG_CRYPTO_CBC=y
-CONFIG_CRYPTO_PCBC=y
-CONFIG_CRYPTO_LRW=y
-CONFIG_CRYPTO_DES=y
-CONFIG_CRYPTO_FCRYPT=y
-CONFIG_CRYPTO_BLOWFISH=y
-CONFIG_CRYPTO_TWOFISH=y
-CONFIG_CRYPTO_TWOFISH_COMMON=y
-CONFIG_CRYPTO_SERPENT=y
-CONFIG_CRYPTO_AES=y
-CONFIG_CRYPTO_CAST5=y
-CONFIG_CRYPTO_CAST6=y
-CONFIG_CRYPTO_TEA=y
-CONFIG_CRYPTO_ARC4=y
-CONFIG_CRYPTO_KHAZAD=y
-CONFIG_CRYPTO_ANUBIS=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_MICHAEL_MIC=y
-CONFIG_CRYPTO_CRC32C=y
-CONFIG_CRYPTO_CAMELLIA=y
-
-#
-# Hardware crypto devices
-#
-
-#
-# Library routines
-#
-CONFIG_BITREVERSE=y
-# CONFIG_CRC_CCITT is not set
-CONFIG_CRC16=y
-CONFIG_CRC32=y
-CONFIG_LIBCRC32C=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
index 15a027e00eec46c0c637f7bbc019173d00a2e513..e1db1fb80cd0855061e17e5b4ae70baaee4639b0 100644 (file)
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 CONFIG_MOMENCO_OCELOT=y
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
index 37d696c64541c38cd0c8e416eae0f1f75cf2ced0..0028aef0af9d06992e2a64bc4e5f0122e547ddd7 100644 (file)
@@ -26,9 +26,7 @@ CONFIG_MIPS_PB1100=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -36,8 +34,6 @@ CONFIG_MIPS_PB1100=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
index b11f0e8b605966c9d35da963dd8c31e5c705c5d4..8a1d5888739c8c90363936a6e98d86d1e1a3279a 100644 (file)
@@ -26,9 +26,7 @@ CONFIG_MIPS_PB1500=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -36,8 +34,6 @@ CONFIG_MIPS_PB1500=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
index 2927f38f4907251b4cc817e06861b9640acded10..5581ad2ca411b6fac7e06c7014726239e184b24c 100644 (file)
@@ -26,9 +26,7 @@ CONFIG_MIPS_PB1550=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -36,8 +34,6 @@ CONFIG_MIPS_PB1550=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
index fae16c5ec5211c789573f374731d4a79158fca11..821c1cee5639a83c0966a5227af3617d342b11e3 100644 (file)
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 CONFIG_PNX8550_JBS=y
index cd821e52181d109c20c947a72e3250f01f4554ac..0e8bd92b38cf27af12e6bb1863f4b337d58641d6 100644 (file)
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
index 8e8d0315795473a34a3cce9b19b2f88d0124099e..703de002e37213eb0cb62dcdec353fb55e272d55 100644 (file)
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
@@ -225,7 +221,7 @@ CONFIG_DEFAULT_IOSCHED="noop"
 #
 CONFIG_ISA=y
 CONFIG_MMU=y
-CONFIG_I8253=y
+CONFIG_PCSPEAKER=y
 
 #
 # PCCARD (PCMCIA/CardBus) support
index 35d64260917e2d5045b44018d4b80f9a90789bac..20a38526d4830ce949d283de9cf43bc53bdfeef8 100644 (file)
@@ -24,17 +24,13 @@ CONFIG_MIPS=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
 # CONFIG_WR_PPMC is not set
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
index 41011f770a67dbd71c9085b331b704993daf32b2..5dbb250f71c7e2ed1b0ef10fab93b19c0c586e23 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20
-# Tue Feb 20 21:47:39 2007
+# Linux kernel version: 2.6.22-rc5
+# Fri Jun 22 21:39:45 2007
 #
 CONFIG_MIPS=y
 
@@ -9,40 +9,23 @@ CONFIG_MIPS=y
 # Machine selection
 #
 CONFIG_ZONE_DMA=y
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-# CONFIG_MIPS_PB1500 is not set
-# CONFIG_MIPS_PB1550 is not set
-# CONFIG_MIPS_PB1200 is not set
-# CONFIG_MIPS_DB1000 is not set
-# CONFIG_MIPS_DB1100 is not set
-# CONFIG_MIPS_DB1500 is not set
-# CONFIG_MIPS_DB1550 is not set
-# CONFIG_MIPS_DB1200 is not set
-# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_LEMOTE_FULONG is not set
+# CONFIG_MACH_ALCHEMY is not set
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
 # CONFIG_WR_PPMC is not set
 # CONFIG_MIPS_SIM is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_MSP is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_QEMU is not set
 # CONFIG_MARKEINS is not set
@@ -82,6 +65,8 @@ CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_I8259=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_GPIO=y
 # CONFIG_CPU_BIG_ENDIAN is not set
 CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
@@ -93,6 +78,7 @@ CONFIG_HAVE_STD_PC_SERIAL_PORT=y
 #
 # CPU selection
 #
+# CONFIG_CPU_LOONGSON2 is not set
 # CONFIG_CPU_MIPS32_R1 is not set
 # CONFIG_CPU_MIPS32_R2 is not set
 # CONFIG_CPU_MIPS64_R1 is not set
@@ -149,12 +135,12 @@ CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
-# CONFIG_HZ_250 is not set
+CONFIG_HZ_250=y
 # CONFIG_HZ_256 is not set
-CONFIG_HZ_1000=y
+# CONFIG_HZ_1000 is not set
 # CONFIG_HZ_1024 is not set
 CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_HZ=1000
+CONFIG_HZ=250
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
@@ -186,28 +172,35 @@ CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
 CONFIG_SYSFS_DEPRECATED=y
-CONFIG_RELAY=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_HOTPLUG=y
+# CONFIG_HOTPLUG is not set
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 # CONFIG_FUTEX is not set
+CONFIG_ANON_INODES=y
 # CONFIG_EPOLL is not set
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
-CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -244,17 +237,12 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 #
 CONFIG_HW_HAS_PCI=y
 CONFIG_PCI=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_MMU=y
 
 #
 # PCCARD (PCMCIA/CardBus) support
 #
-# CONFIG_PCCARD is not set
-
-#
-# PCI Hotplug Support
-#
-# CONFIG_HOTPLUG_PCI is not set
 
 #
 # Executable file formats
@@ -266,10 +254,7 @@ CONFIG_TRAD_SIGNALS=y
 #
 # Power management options
 #
-CONFIG_PM=y
-# CONFIG_PM_LEGACY is not set
-# CONFIG_PM_DEBUG is not set
-# CONFIG_PM_SYSFS_DEPRECATED is not set
+# CONFIG_PM is not set
 
 #
 # Networking
@@ -279,14 +264,9 @@ CONFIG_NET=y
 #
 # Networking options
 #
-# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-CONFIG_XFRM_MIGRATE=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
@@ -294,7 +274,7 @@ CONFIG_IP_MULTICAST=y
 CONFIG_IP_FIB_HASH=y
 CONFIG_IP_PNP=y
 # CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_BOOTP is not set
 # CONFIG_IP_PNP_RARP is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
@@ -305,130 +285,23 @@ CONFIG_IP_PNP_BOOTP=y
 # 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=m
-CONFIG_INET_XFRM_MODE_TUNNEL=m
-CONFIG_INET_XFRM_MODE_BEET=m
+# CONFIG_INET_TUNNEL is not set
+# 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_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
-CONFIG_TCP_MD5SIG=y
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-CONFIG_IPV6=m
-# CONFIG_IPV6_PRIVACY is not set
-CONFIG_IPV6_ROUTER_PREF=y
-CONFIG_IPV6_ROUTE_INFO=y
-# CONFIG_INET6_AH is not set
-# CONFIG_INET6_ESP is not set
-# CONFIG_INET6_IPCOMP is not set
-CONFIG_IPV6_MIP6=y
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
-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_TUNNEL is not set
-CONFIG_IPV6_MULTIPLE_TABLES=y
-CONFIG_IPV6_SUBTREES=y
-CONFIG_NETWORK_SECMARK=y
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# Core Netfilter Configuration
-#
-CONFIG_NETFILTER_NETLINK=m
-CONFIG_NETFILTER_NETLINK_QUEUE=m
-CONFIG_NETFILTER_NETLINK_LOG=m
-CONFIG_NF_CONNTRACK_ENABLED=m
-CONFIG_NF_CONNTRACK_SUPPORT=y
-# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set
-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_GRE=m
-CONFIG_NF_CT_PROTO_SCTP=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 is not set
-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_MARK=m
-CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
-CONFIG_NETFILTER_XT_TARGET_NFLOG=m
-CONFIG_NETFILTER_XT_TARGET_SECMARK=m
-CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
-CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
-CONFIG_NETFILTER_XT_MATCH_COMMENT=m
-CONFIG_NETFILTER_XT_MATCH_CONNBYTES=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_LENGTH=m
-CONFIG_NETFILTER_XT_MATCH_LIMIT=m
-CONFIG_NETFILTER_XT_MATCH_MAC=m
-CONFIG_NETFILTER_XT_MATCH_MARK=m
-# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
-CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
-CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
-CONFIG_NETFILTER_XT_MATCH_QUOTA=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_HASHLIMIT=m
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_NF_CONNTRACK_PROC_COMPAT=y
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-
-#
-# IPv6: Netfilter Configuration (EXPERIMENTAL)
-#
-CONFIG_NF_CONNTRACK_IPV6=m
-# CONFIG_IP6_NF_QUEUE is not set
-# CONFIG_IP6_NF_IPTABLES is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -446,7 +319,6 @@ CONFIG_NF_CONNTRACK_IPV6=m
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-CONFIG_NET_CLS_ROUTE=y
 
 #
 # Network testing
@@ -455,15 +327,16 @@ CONFIG_NET_CLS_ROUTE=y
 # CONFIG_HAMRADIO is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT 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_IEEE80211_SOFTMAC=m
-# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
-CONFIG_WIRELESS_EXT=y
-CONFIG_FIB_RULES=y
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
 
 #
 # Device Drivers
@@ -474,94 +347,13 @@ CONFIG_FIB_RULES=y
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
 # CONFIG_SYS_HYPERVISOR is not set
 
 #
 # Connector - unified userspace <-> kernelspace linker
 #
-CONFIG_CONNECTOR=m
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG is not set
-# CONFIG_MTD_CONCAT is not set
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_CMDLINE_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLKDEVS=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-# CONFIG_RFD_FTL is not set
-# CONFIG_SSFDC is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_GEN_PROBE=y
-# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_CFI_AMDSTD=y
-# CONFIG_MTD_CFI_STAA is not set
-CONFIG_MTD_CFI_UTIL=y
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_PLATRAM is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_PMC551 is not set
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_PHRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLOCK2MTD is not set
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
-# CONFIG_MTD_NAND is not set
-
-#
-# OneNAND Flash Device Drivers
-#
-# CONFIG_MTD_ONENAND is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
 
 #
 # Parallel port support
@@ -583,93 +375,30 @@ CONFIG_MTD_CFI_UTIL=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
-CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
-# CONFIG_BLK_DEV_UB is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=8192
 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
 
 #
 # Misc devices
 #
-CONFIG_SGI_IOC4=m
+# CONFIG_PHANTOM is not set
+# CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=y
-CONFIG_IDE_MAX_HWIFS=4
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-CONFIG_BLK_DEV_IDECD=y
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=y
-CONFIG_BLK_DEV_IDEPCI=y
-CONFIG_IDEPCI_SHARE_IRQ=y
-# CONFIG_BLK_DEV_OFFBOARD is not set
-# CONFIG_BLK_DEV_GENERIC is not set
-# CONFIG_BLK_DEV_OPTI621 is not set
-CONFIG_BLK_DEV_IDEDMA_PCI=y
-# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
-# CONFIG_IDEDMA_PCI_AUTO is not set
-# CONFIG_BLK_DEV_AEC62XX is not set
-# CONFIG_BLK_DEV_ALI15X3 is not set
-# CONFIG_BLK_DEV_AMD74XX is not set
-# CONFIG_BLK_DEV_CMD64X is not set
-# CONFIG_BLK_DEV_TRIFLEX is not set
-# CONFIG_BLK_DEV_CY82C693 is not set
-# CONFIG_BLK_DEV_CS5520 is not set
-# CONFIG_BLK_DEV_CS5530 is not set
-# CONFIG_BLK_DEV_HPT34X is not set
-# CONFIG_BLK_DEV_HPT366 is not set
-# CONFIG_BLK_DEV_JMICRON is not set
-# CONFIG_BLK_DEV_SC1200 is not set
-# CONFIG_BLK_DEV_PIIX is not set
-CONFIG_BLK_DEV_IT8213=m
-# 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_SLC90E66 is not set
-# CONFIG_BLK_DEV_TRM290 is not set
-# CONFIG_BLK_DEV_VIA82CXXX is not set
-CONFIG_BLK_DEV_TC86C001=m
-# CONFIG_IDE_ARM is not set
-CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_IDEDMA_IVB is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLINK is not set
+# CONFIG_IDE is not set
 
 #
 # SCSI device support
 #
-CONFIG_RAID_ATTRS=m
+# CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_NETLINK is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
 # CONFIG_ATA is not set
 
 #
@@ -685,6 +414,7 @@ CONFIG_RAID_ATTRS=m
 #
 # IEEE 1394 (FireWire) support
 #
+# CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
 
 #
@@ -699,36 +429,15 @@ CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
-CONFIG_TUN=m
-
-#
-# ARCnet devices
-#
+# CONFIG_TUN is not set
 # CONFIG_ARCNET is not set
-
-#
-# PHY device support
-#
-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 is not set
-# CONFIG_FIXED_PHY is not set
+# CONFIG_PHYLIB is not set
 
 #
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
+CONFIG_MII=y
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
@@ -747,6 +456,7 @@ CONFIG_NET_PCI=y
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
+CONFIG_TC35815=y
 # CONFIG_DGRS is not set
 # CONFIG_EEPRO100 is not set
 # CONFIG_E100 is not set
@@ -761,91 +471,20 @@ CONFIG_NET_PCI=y
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_SC92031 is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SIS190 is not set
-# CONFIG_SKGE is not set
-# CONFIG_SKY2 is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_VIA_VELOCITY is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_BNX2 is not set
-CONFIG_QLA3XXX=m
-# CONFIG_ATL1 is not set
-
-#
-# Ethernet (10000 Mbit)
-#
-# CONFIG_CHELSIO_T1 is not set
-CONFIG_CHELSIO_T3=m
-# CONFIG_IXGB is not set
-# CONFIG_S2IO is not set
-# CONFIG_MYRI10GE is not set
-CONFIG_NETXEN_NIC=m
-
-#
-# Token Ring devices
-#
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
 
 #
-# Wireless LAN (non-hamradio)
-#
-CONFIG_NET_RADIO=y
-# CONFIG_NET_WIRELESS_RTNETLINK is not set
-
-#
-# Obsolete Wireless cards support (pre-802.11)
-#
-# CONFIG_STRIP is not set
-
-#
-# Wireless 802.11b ISA/PCI cards support
-#
-# CONFIG_IPW2100 is not set
-CONFIG_IPW2200=m
-# CONFIG_IPW2200_MONITOR is not set
-# CONFIG_IPW2200_QOS is not set
-# CONFIG_IPW2200_DEBUG is not set
-# CONFIG_HERMES is not set
-# CONFIG_ATMEL is not set
-
-#
-# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
-#
-# CONFIG_PRISM54 is not set
-# CONFIG_USB_ZD1201 is not set
-# CONFIG_HOSTAP is not set
-# CONFIG_BCM43XX is not set
-# CONFIG_ZD1211RW is not set
-CONFIG_NET_WIRELESS=y
-
-#
-# Wan interfaces
+# Wireless LAN
 #
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
-CONFIG_PPP=m
-CONFIG_PPP_MULTILINK=y
-# CONFIG_PPP_FILTER is not set
-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_PPP is not set
 # CONFIG_SLIP is not set
-CONFIG_SLHC=m
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
@@ -864,57 +503,18 @@ CONFIG_SLHC=m
 #
 # Input device support
 #
-CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
-CONFIG_INPUT_EVDEV=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_INPUT_MOUSE=y
-CONFIG_MOUSE_PS2=y
-# CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_VSXXXAA is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
+# CONFIG_INPUT is not set
 
 #
 # Hardware I/O ports
 #
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_PCIPS2 is not set
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
+# 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=y
+# CONFIG_VT is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -926,11 +526,12 @@ CONFIG_VT_HW_CONSOLE_BINDING=y
 # Non-8250 serial port support
 #
 CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_TXX9=y
 CONFIG_HAS_TXX9_SERIAL=y
 CONFIG_SERIAL_TXX9_NR_UARTS=6
-# CONFIG_SERIAL_TXX9_CONSOLE is not set
-# CONFIG_SERIAL_TXX9_STDSERIAL is not set
+CONFIG_SERIAL_TXX9_CONSOLE=y
+CONFIG_SERIAL_TXX9_STDSERIAL=y
 # CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
@@ -940,15 +541,10 @@ CONFIG_LEGACY_PTY_COUNT=256
 # IPMI
 #
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
 # CONFIG_WATCHDOG is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_RTC is not set
 # CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_DRM is not set
@@ -958,108 +554,61 @@ CONFIG_LEGACY_PTY_COUNT=256
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
 
 #
-# I2C support
+# SPI Master Controller Drivers
 #
-# CONFIG_I2C is not set
+# CONFIG_SPI_BITBANG is not set
+CONFIG_SPI_TXX9=y
 
 #
-# SPI support
+# SPI Protocol Masters
 #
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
+CONFIG_SPI_AT25=y
+# CONFIG_SPI_SPIDEV is not set
 
 #
 # Dallas's 1-wire bus
 #
 # CONFIG_W1 is not set
+# CONFIG_HWMON is not set
 
 #
-# Hardware Monitoring support
+# Multifunction device drivers
 #
-CONFIG_HWMON=y
-# CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_ABITUGURU is not set
-# CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_PC87427 is not set
-# CONFIG_SENSORS_VT1211 is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_MFD_SM501 is not set
 
 #
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-# CONFIG_USB_DABUSB is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
 
 #
 # Graphics support
 #
-# CONFIG_FIRMWARE_EDID is not set
-CONFIG_FB=y
-CONFIG_FB_CFB_FILLRECT=y
-CONFIG_FB_CFB_COPYAREA=y
-CONFIG_FB_CFB_IMAGEBLIT=y
-# 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
-# CONFIG_FB_CIRRUS is not set
-# CONFIG_FB_PM2 is not set
-# CONFIG_FB_CYBER2000 is not set
-# CONFIG_FB_ASILIANT is not set
-# CONFIG_FB_IMSTT is not set
-# CONFIG_FB_S1D13XXX is not set
-# CONFIG_FB_NVIDIA is not set
-# CONFIG_FB_RIVA is not set
-# CONFIG_FB_MATROX is not set
-# CONFIG_FB_RADEON is not set
-# CONFIG_FB_ATY128 is not set
-CONFIG_FB_ATY=y
-CONFIG_FB_ATY_CT=y
-# CONFIG_FB_ATY_GENERIC_LCD is not set
-# CONFIG_FB_ATY_GX is not set
-# CONFIG_FB_S3 is not set
-# CONFIG_FB_SAVAGE is not set
-# CONFIG_FB_SIS is not set
-# CONFIG_FB_NEOMAGIC is not set
-# CONFIG_FB_KYRO is not set
-# CONFIG_FB_3DFX is not set
-# CONFIG_FB_VOODOO1 is not set
-# CONFIG_FB_SMIVGX is not set
-# CONFIG_FB_TRIDENT is not set
-# CONFIG_FB_VIRTUAL is not set
-
-#
-# Console display driver support
-#
-CONFIG_VGA_CONSOLE=y
-# CONFIG_VGACON_SOFT_SCROLLBACK is not set
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_FRAMEBUFFER_CONSOLE is not set
-
-#
-# Logo configuration
-#
-# CONFIG_LOGO is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
-# Sound
+# Display device support
 #
-# CONFIG_SOUND is not set
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_FB is not set
 
 #
-# HID Devices
+# Sound
 #
-CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
+# CONFIG_SOUND is not set
 
 #
 # USB support
@@ -1067,148 +616,80 @@ CONFIG_HID=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB_ARCH_HAS_EHCI=y
-CONFIG_USB=y
-# CONFIG_USB_DEBUG is not set
-
-#
-# Miscellaneous USB options
-#
-# CONFIG_USB_DEVICEFS is not set
-# CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_SUSPEND is not set
-# CONFIG_USB_OTG is not set
-
-#
-# USB Host Controller Drivers
-#
-# CONFIG_USB_EHCI_HCD is not set
-# CONFIG_USB_ISP116X_HCD is not set
-# CONFIG_USB_OHCI_HCD is not set
-# CONFIG_USB_UHCI_HCD is not set
-# CONFIG_USB_SL811_HCD is not set
-
-#
-# USB Device Class drivers
-#
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
+# CONFIG_USB 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 Input Devices
-#
-CONFIG_USB_HID=y
-# CONFIG_USB_HIDINPUT_POWERBOOK is not set
-# CONFIG_HID_FF is not set
-CONFIG_USB_HIDDEV=y
-# CONFIG_USB_AIPTEK is not set
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_ACECAD is not set
-# CONFIG_USB_KBTAB is not set
-# CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_TOUCHSCREEN is not set
-CONFIG_USB_YEALINK=m
-# CONFIG_USB_XPAD is not set
-# CONFIG_USB_ATI_REMOTE is not set
-# CONFIG_USB_ATI_REMOTE2 is not set
-# CONFIG_USB_KEYSPAN_REMOTE is not set
-# CONFIG_USB_APPLETOUCH is not set
-# CONFIG_USB_GTCO is not set
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_MDC800 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_MII is not set
-# CONFIG_USB_USBNET is not set
-CONFIG_USB_MON=y
-
-#
-# USB port drivers
+# USB Gadget Support
 #
+# CONFIG_USB_GADGET is not set
+# CONFIG_MMC is not set
 
 #
-# USB Serial Converter support
+# LED devices
 #
-# CONFIG_USB_SERIAL is not set
+# CONFIG_NEW_LEDS is not set
 
 #
-# USB Miscellaneous drivers
+# LED 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
 
 #
-# USB DSL modem support
+# LED Triggers
 #
 
 #
-# USB Gadget Support
+# InfiniBand support
 #
-# CONFIG_USB_GADGET is not set
+# CONFIG_INFINIBAND is not set
 
 #
-# MMC/SD Card support
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
 #
-# CONFIG_MMC is not set
 
 #
-# LED devices
+# Real Time Clock
 #
-# CONFIG_NEW_LEDS 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
 
 #
-# LED drivers
+# RTC interfaces
 #
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+# CONFIG_RTC_DRV_TEST is not set
 
 #
-# LED Triggers
+# I2C RTC drivers
 #
 
 #
-# InfiniBand support
+# SPI RTC drivers
 #
-# CONFIG_INFINIBAND is not set
+CONFIG_RTC_DRV_RS5C348=y
+# CONFIG_RTC_DRV_MAX6902 is not set
 
 #
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+# Platform RTC drivers
 #
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_V3020 is not set
 
 #
-# Real Time Clock
+# on-CPU RTC drivers
 #
-# CONFIG_RTC_CLASS is not set
 
 #
 # DMA Engine support
@@ -1223,39 +704,16 @@ CONFIG_USB_MON=y
 # DMA Devices
 #
 
-#
-# Auxiliary Display support
-#
-
-#
-# Virtualization
-#
-
 #
 # 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_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
 # CONFIG_EXT4DEV_FS is not set
-CONFIG_JBD=m
-# CONFIG_JBD_DEBUG is not set
-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 is not set
+# CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
-CONFIG_XFS_FS=m
-# CONFIG_XFS_QUOTA is not set
-# CONFIG_XFS_SECURITY is not set
-# CONFIG_XFS_POSIX_ACL is not set
-# CONFIG_XFS_RT is not set
+# CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
@@ -1265,26 +723,21 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 # CONFIG_DNOTIFY is not set
 # CONFIG_AUTOFS_FS is not set
-CONFIG_AUTOFS4_FS=m
-CONFIG_FUSE_FS=m
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
 CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
 #
-CONFIG_ISO9660_FS=y
-# CONFIG_JOLIET is not set
-# CONFIG_ZISOFS is not set
+# CONFIG_ISO9660_FS is not set
 # CONFIG_UDF_FS is not set
 
 #
 # DOS/FAT/NT Filesystems
 #
-CONFIG_FAT_FS=y
 # CONFIG_MSDOS_FS is not set
-CONFIG_VFAT_FS=y
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_VFAT_FS is not set
 # CONFIG_NTFS_FS is not set
 
 #
@@ -1298,7 +751,7 @@ CONFIG_TMPFS=y
 CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-CONFIG_CONFIGFS_FS=m
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -1310,16 +763,7 @@ CONFIG_CONFIGFS_FS=m
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-CONFIG_JFFS2_FS_WRITEBUFFER=y
-# CONFIG_JFFS2_SUMMARY is not set
-# CONFIG_JFFS2_FS_XATTR is not set
-# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
-CONFIG_JFFS2_ZLIB=y
-CONFIG_JFFS2_RTIME=y
-# CONFIG_JFFS2_RUBIN is not set
-CONFIG_CRAMFS=y
+# CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
@@ -1334,19 +778,16 @@ CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
 # CONFIG_NFS_DIRECTIO is not set
-CONFIG_NFSD=m
-# CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_TCP is not set
+# CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=m
 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_SMB_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1362,54 +803,12 @@ CONFIG_MSDOS_PARTITION=y
 #
 # Native Language Support
 #
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="iso8859-1"
-# CONFIG_NLS_CODEPAGE_437 is not set
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_ASCII is not set
-# CONFIG_NLS_ISO8859_1 is not set
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
+# CONFIG_NLS is not set
 
 #
 # Distributed Lock Manager
 #
-CONFIG_DLM=m
-CONFIG_DLM_TCP=y
-# CONFIG_DLM_SCTP is not set
-# CONFIG_DLM_DEBUG is not set
+# CONFIG_DLM is not set
 
 #
 # Profiling support
@@ -1427,7 +826,6 @@ CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 CONFIG_SYS_SUPPORTS_KGDB=y
@@ -1441,62 +839,17 @@ CONFIG_SYS_SUPPORTS_KGDB=y
 #
 # Cryptographic options
 #
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_BLKCIPHER=m
-CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_MANAGER=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_SHA1=m
-CONFIG_CRYPTO_SHA256=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_GF128MUL=m
-CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_CBC=m
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_DES=m
-CONFIG_CRYPTO_FCRYPT=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_TWOFISH_COMMON=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_AES=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_CRC32C=m
-CONFIG_CRYPTO_CAMELLIA=m
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Hardware crypto devices
-#
+# CONFIG_CRYPTO is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
-CONFIG_CRC_CCITT=m
-CONFIG_CRC16=m
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
-CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_TEXTSEARCH=y
-CONFIG_TEXTSEARCH_KMP=m
-CONFIG_TEXTSEARCH_BM=m
-CONFIG_TEXTSEARCH_FSM=m
+# CONFIG_LIBCRC32C is not set
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
index 5593cde9f74c2790ee7bfc50c933ba6446315fbd..a5dc5cb97aae69d92f70a699761cbed4d78578b9 100644 (file)
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
@@ -255,7 +251,7 @@ CONFIG_PCI=y
 CONFIG_ISA=y
 # CONFIG_EISA is not set
 CONFIG_MMU=y
-CONFIG_I8253=y
+CONFIG_PCSPEAKER=y
 
 #
 # PCCARD (PCMCIA/CardBus) support
index 6c4f09a381e2bcb4083695ff165d36c24ba760d9..98a91409225811b25486540f121421c896435cfc 100644 (file)
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
index 988b9cdef01fe020520c1fac4a4faf35c9babc30..69c08b24c82af37b9d443f56591a8c9e293ad1e9 100644 (file)
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 CONFIG_MIPS_SEAD=y
@@ -35,8 +33,6 @@ CONFIG_MIPS_SEAD=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
index 8b1675c07ec439f0bcd52f3be6e3faddf43f4a00..5d4fc0e4f72916e633473a784662920cc773639f 100644 (file)
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
index b5be8b74d89669f763f7f6317f80ee975386f99f..1b92b48de0511dfaf120e86b711bec728c88fda7 100644 (file)
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
index 8bb6be4342b6d511eb44189b0606fd6c4894cab5..5b77c7a5d83aec7f1e24d00505bcd3bd61e1f232 100644 (file)
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
index 8f019ffcc71be1c5e49cf76e21965dc426d7d7c3..94a4f94a8b244f4c64818454f1b1cf10af6bd817 100644 (file)
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
index 52b48c0715d3ee93fddfeca9a2cbd84605a7a748..e38bd9b0eadc2dd909240114605915f4fa9daa41 100644 (file)
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_WR_PPMC=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
index 6824606309e5a81affcf5d2d25a87215ecf051a6..f342d8c887b800729fd5b6f4bb301798c593f7c9 100644 (file)
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
@@ -596,8 +592,6 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_WATCHDOG is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_RTC is not set
-CONFIG_GEN_RTC=y
-CONFIG_GEN_RTC_X=y
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
index 23fd3b81fe1ad7f22748ebfd05f016170da7a1e0..4864b8a659c7d1cb9d846c18519760517157d2a2 100644 (file)
@@ -2,7 +2,8 @@
 # Makefile for NEC DDB-Vrc5477 board
 #
 
-obj-y                  += irq.o irq_5477.o setup.o lcd44780.o
+obj-y                  += ddb5477-platform.o irq.o irq_5477.o setup.o \
+                          lcd44780.o
 
 obj-$(CONFIG_RUNTIME_DEBUG)    += debug.o
 obj-$(CONFIG_KGDB)             += kgdb_io.o
diff --git a/arch/mips/ddb5xxx/ddb5477/ddb5477-platform.c b/arch/mips/ddb5xxx/ddb5477/ddb5477-platform.c
new file mode 100644 (file)
index 0000000..c16020a
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org)
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/serial_8250.h>
+
+#include <asm/ddb5xxx/ddb5477.h>
+
+#define DDB_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP)
+
+#define DDB5477_PORT(base, int)                                                \
+{                                                                      \
+       .mapbase        = base,                                         \
+       .irq            = int,                                          \
+       .uartclk        = 1843200,                                      \
+       .iotype         = UPIO_MEM,                                     \
+       .flags          = DDB_UART_FLAGS,                               \
+       .regshift       = 3,                                            \
+}
+
+static struct plat_serial8250_port uart8250_data[] = {
+       DDB5477_PORT(0xbfa04200, VRC5477_IRQ_UART0),
+       DDB5477_PORT(0xbfa04240, VRC5477_IRQ_UART1),
+       { },
+};
+
+static struct platform_device uart8250_device = {
+       .name                   = "serial8250",
+       .id                     = PLAT8250_DEV_PLATFORM,
+       .dev                    = {
+               .platform_data  = uart8250_data,
+       },
+};
+
+static int __init uart8250_init(void)
+{
+       return platform_device_register(&uart8250_device);
+}
+
+module_init(uart8250_init);
+
+MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("8250 UART probe driver for the NEC DDB5477");
index 65419bf32441be996b689a28790a1a610dcc8d37..078e1a12421d736896f670c4019d7fc879b17395 100644 (file)
@@ -3,7 +3,7 @@
  *
  *     DECstation PROM-based early console support.
  *
- *     Copyright (C) 2004  Maciej W. Rozycki
+ *     Copyright (C) 2004, 2007  Maciej W. Rozycki
  *
  *     This program is free software; you can redistribute it and/or
  *     modify it under the terms of the GNU General Public License
 #include <linux/console.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/string.h>
 
 #include <asm/dec/prom.h>
 
-void prom_putchar(char c)
+static void __init prom_console_write(struct console *con, const char *s,
+                                     unsigned int c)
 {
-       char s[2];
+       char buf[81];
+       unsigned int chunk = sizeof(buf) - 1;
 
-       s[0] = c;
-       s[1] = '\0';
+       while (c > 0) {
+               if (chunk > c)
+                       chunk = c;
+               memcpy(buf, s, chunk);
+               buf[chunk] = '\0';
+               prom_printf("%s", buf);
+               s += chunk;
+               c -= chunk;
+       }
+}
+
+static struct console promcons __initdata = {
+       .name   = "prom",
+       .write  = prom_console_write,
+       .flags  = CON_BOOT | CON_PRINTBUFFER,
+       .index  = -1,
+};
 
-       prom_printf( s);
+void __init register_prom_console(void)
+{
+       register_console(&promcons);
 }
index a217aafe59f6aa9e2d61bf78239fdc64e8e128a4..808c182fd3fafb8d8855ea2ee46c6f7067a34ff5 100644 (file)
@@ -86,7 +86,7 @@ void __init which_prom(s32 magic, s32 *prom_vec)
 
 void __init prom_init(void)
 {
-       extern void ATTRIB_NORET dec_machine_halt(void);
+       extern void dec_machine_halt(void);
        static char cpu_msg[] __initdata =
                "Sorry, this kernel is compiled for a wrong CPU type!\n";
        s32 argc = fw_arg0;
@@ -103,6 +103,9 @@ void __init prom_init(void)
        if (prom_is_rex(magic))
                rex_clear_cache();
 
+       /* Register the early console.  */
+       register_prom_console();
+
        /* Were we compiled with the right CPU option? */
 #if defined(CONFIG_CPU_R3000)
        if ((current_cpu_data.cputype == CPU_R4000SC) ||
index 56397227adb09d20a8a031c0c40ac07c925f2d57..c15a879046e5ca906809a61c4612a2627f6b6663 100644 (file)
@@ -9,26 +9,26 @@
 
 #include <asm/addrspace.h>
 
-typedef void ATTRIB_NORET (* noret_func_t)(void);
+typedef void __noreturn (* noret_func_t)(void);
 
-static inline void ATTRIB_NORET back_to_prom(void)
+static inline void __noreturn back_to_prom(void)
 {
        noret_func_t func = (void *)CKSEG1ADDR(0x1fc00000);
 
        func();
 }
 
-void ATTRIB_NORET dec_machine_restart(char *command)
+void __noreturn dec_machine_restart(char *command)
 {
        back_to_prom();
 }
 
-void ATTRIB_NORET dec_machine_halt(void)
+void __noreturn dec_machine_halt(void)
 {
        back_to_prom();
 }
 
-void ATTRIB_NORET dec_machine_power_off(void)
+void __noreturn dec_machine_power_off(void)
 {
     /* DECstations don't have a software power switch */
        back_to_prom();
index 41211f8b77384c0e3409aab920c444349f860aa7..b3b6e58058f680bd9c72ed7c0234830b0fa2527a 100644 (file)
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_SIM is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/gt64120/ev64120/Kconfig b/arch/mips/gt64120/ev64120/Kconfig
deleted file mode 100644 (file)
index d691762..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-config EVB_PCI1
-       bool "Enable Second PCI (PCI1)"
-       depends on MIPS_EV64120
diff --git a/arch/mips/gt64120/ev64120/Makefile b/arch/mips/gt64120/ev64120/Makefile
deleted file mode 100644 (file)
index 323b2ce..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#
-#  Copyright 2000 RidgeRun, Inc.
-#  Author: RidgeRun, Inc.
-#      glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
-#
-# Makefile for the Galileo EV64120 board.
-#
-
-obj-y  += irq.o promcon.o reset.o serialGT.o setup.o
diff --git a/arch/mips/gt64120/ev64120/irq.c b/arch/mips/gt64120/ev64120/irq.c
deleted file mode 100644 (file)
index 64e4c80..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * BRIEF MODULE DESCRIPTION
- * Code to handle irqs on GT64120A boards
- *  Derived from mips/orion and Cort <cort@fsmlabs.com>
- *
- * Copyright (C) 2000 RidgeRun, Inc.
- * Author: RidgeRun, Inc.
- *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/kernel_stat.h>
-#include <linux/module.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/timex.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/bitops.h>
-#include <asm/bootinfo.h>
-#include <asm/io.h>
-#include <asm/mipsregs.h>
-#include <asm/system.h>
-#include <asm/gt64120.h>
-
-asmlinkage void plat_irq_dispatch(void)
-{
-       unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
-
-       if (pending & STATUSF_IP4)              /* int2 hardware line (timer) */
-               do_IRQ(4);
-       else if (pending & STATUSF_IP2)         /* int0 hardware line */
-               do_IRQ(GT_INTA);
-       else if (pending & STATUSF_IP5)         /* int3 hardware line */
-               do_IRQ(GT_INTD);
-       else if (pending & STATUSF_IP6)         /* int4 hardware line */
-               do_IRQ(6);
-       else if (pending & STATUSF_IP7)         /* compare int */
-               do_IRQ(7);
-       else
-               spurious_interrupt();
-}
-
-static void disable_ev64120_irq(unsigned int irq_nr)
-{
-       if (irq_nr >= 8) {      // All PCI interrupts are on line 5 or 2
-               clear_c0_status(9 << 10);
-       } else {
-               clear_c0_status(1 << (irq_nr + 8));
-       }
-}
-
-static void enable_ev64120_irq(unsigned int irq_nr)
-{
-       if (irq_nr >= 8)        // All PCI interrupts are on line 5 or 2
-               set_c0_status(9 << 10);
-       else
-               set_c0_status(1 << (irq_nr + 8));
-}
-
-static void end_ev64120_irq(unsigned int irq)
-{
-       if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-               enable_ev64120_irq(irq);
-}
-
-static struct irq_chip ev64120_irq_type = {
-       .name           = "EV64120",
-       .ack            = disable_ev64120_irq,
-       .mask           = disable_ev64120_irq,
-       .mask_ack       = disable_ev64120_irq,
-       .unmask         = enable_ev64120_irq,
-       .end            = end_ev64120_irq,
-};
-
-void gt64120_irq_setup(void)
-{
-       /*
-        * Clear all of the interrupts while we change the able around a bit.
-        */
-       clear_c0_status(ST0_IM);
-
-       /*
-        * Enable timer.  Other interrupts will be enabled as they are
-        * registered.
-        */
-       set_c0_status(IE_IRQ2);
-}
-
-void __init arch_init_irq(void)
-{
-       gt64120_irq_setup();
-}
diff --git a/arch/mips/gt64120/ev64120/promcon.c b/arch/mips/gt64120/ev64120/promcon.c
deleted file mode 100644 (file)
index 6e0ecfe..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Wrap-around code for a console using the
- * SGI PROM io-routines.
- *
- * Copyright (c) 1999 Ulf Carlsson
- *
- * Derived from DECstation promcon.c
- * Copyright (c) 1998 Harald Koerfgen
- */
-#include <linux/tty.h>
-#include <linux/init.h>
-#include <linux/console.h>
-
-static void prom_console_write(struct console *co, const char *s,
-                              unsigned count)
-{
-       extern int CONSOLE_CHANNEL;     // The default serial port
-       unsigned i;
-
-       for (i = 0; i < count; i++) {
-               if (*s == 10)
-                       serial_putc(CONSOLE_CHANNEL, 13);
-               serial_putc(CONSOLE_CHANNEL, *s++);
-       }
-}
-
-static struct console sercons = {
-    .name      = "ttyS",
-    .write     = prom_console_write,
-    .flags     = CON_PRINTBUFFER,
-    .index     = -1,
-};
-
-/*
- *    Register console.
- */
-
-static int gal_serial_console_init(void)
-{
-       //  serial_init();
-       //serial_set(115200);
-
-       register_console(&sercons);
-
-       return 0;
-}
-
-console_initcall(gal_serial_console_init);
diff --git a/arch/mips/gt64120/ev64120/reset.c b/arch/mips/gt64120/ev64120/reset.c
deleted file mode 100644 (file)
index 7b9f5e5..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1997 Ralf Baechle
- */
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/processor.h>
-#include <asm/reboot.h>
-#include <asm/system.h>
-
-void galileo_machine_restart(char *command)
-{
-       *(volatile char *) 0xbc000000 = 0x0f;
-       /*
-        * Ouch, we're still alive ... This time we take the silver bullet ...
-        * ... and find that we leave the hardware in a state in which the
-        * kernel in the flush locks up somewhen during of after the PCI
-        * detection stuff.
-        */
-       set_c0_status(ST0_BEV | ST0_ERL);
-       change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
-       flush_cache_all();
-       write_c0_wired(0);
-       __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
-}
-
-void galileo_machine_halt(void)
-{
-       printk(KERN_NOTICE "You can safely turn off the power\n");
-       while (1)
-               __asm__(".set\tmips3\n\t"
-                       "wait\n\t"
-                       ".set\tmips0");
-
-}
-
-void galileo_machine_power_off(void)
-{
-       galileo_machine_halt();
-}
diff --git a/arch/mips/gt64120/ev64120/serialGT.c b/arch/mips/gt64120/ev64120/serialGT.c
deleted file mode 100644 (file)
index 8f0d835..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * serialGT.c
- *
- * BRIEF MODULE DESCRIPTION
- *  Low Level Serial Port control for use
- *  with the Galileo EVB64120A MIPS eval board and
- *  its on board two channel 16552 Uart.
- *
- * Copyright (C) 2000 RidgeRun, Inc.
- * Author: RidgeRun, Inc.
- *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-// Note:
-//   Serial CHANNELS - 0 is the bottom connector of evb64120A.
-//                       (The one that maps to the "B" channel of the
-//                       board's uart)
-//                     1 is the top connector of evb64120A.
-//                       (The one that maps to the "A" channel of the
-//                       board's uart)
-int DEBUG_CHANNEL = 0;         // See Note Above
-int CONSOLE_CHANNEL = 1;       // See Note Above
-
-#define DUART 0xBD000000       /* Base address of Uart. */
-#define CHANNELOFFSET 0x20     /* DUART+CHANNELOFFSET gets you to the ChanA
-                                  register set of the 16552 Uart device.
-                                  DUART+0 gets you to the ChanB register set.
-                                */
-#define DUART_DELTA 0x4
-#define FIFO_ENABLE 0x07
-#define INT_ENABLE  0x04       /* default interrupt mask */
-
-#define RBR 0x00
-#define THR 0x00
-#define DLL 0x00
-#define IER 0x01
-#define DLM 0x01
-#define IIR 0x02
-#define FCR 0x02
-#define LCR 0x03
-#define MCR 0x04
-#define LSR 0x05
-#define MSR 0x06
-#define SCR 0x07
-
-#define LCR_DLAB 0x80
-#define XTAL 1843200
-#define LSR_THRE 0x20
-#define LSR_BI   0x10
-#define LSR_DR   0x01
-#define MCR_LOOP 0x10
-#define ACCESS_DELAY 0x10000
-
-/******************************
- Routine:
- Description:
- ******************************/
-int inreg(int channel, int reg)
-{
-       int val;
-       val =
-           *((volatile unsigned char *) DUART +
-             (channel * CHANNELOFFSET) + (reg * DUART_DELTA));
-       return val;
-}
-
-/******************************
- Routine:
- Description:
- ******************************/
-void outreg(int channel, int reg, unsigned char val)
-{
-       *((volatile unsigned char *) DUART + (channel * CHANNELOFFSET)
-         + (reg * DUART_DELTA)) = val;
-}
-
-/******************************
- Routine:
- Description:
-   Initialize the device driver.
- ******************************/
-void serial_init(int channel)
-{
-       /*
-        * Configure active port, (CHANNELOFFSET already set.)
-        *
-        * Set 8 bits, 1 stop bit, no parity.
-        *
-        * LCR<7>       0       divisor latch access bit
-        * LCR<6>       0       break control (1=send break)
-        * LCR<5>       0       stick parity (0=space, 1=mark)
-        * LCR<4>       0       parity even (0=odd, 1=even)
-        * LCR<3>       0       parity enable (1=enabled)
-        * LCR<2>       0       # stop bits (0=1, 1=1.5)
-        * LCR<1:0>     11      bits per character(00=5, 01=6, 10=7, 11=8)
-        */
-       outreg(channel, LCR, 0x3);
-
-       outreg(channel, FCR, FIFO_ENABLE);      /* Enable the FIFO */
-
-       outreg(channel, IER, INT_ENABLE);       /* Enable appropriate interrupts */
-}
-
-/******************************
- Routine:
- Description:
-   Set the baud rate.
- ******************************/
-void serial_set(int channel, unsigned long baud)
-{
-       unsigned char sav_lcr;
-
-       /*
-        * Enable access to the divisor latches by setting DLAB in LCR.
-        *
-        */
-       sav_lcr = inreg(channel, LCR);
-
-#if 0
-       /*
-        * Set baud rate
-        */
-       outreg(channel, LCR, LCR_DLAB | sav_lcr);
-       //  outreg(DLL,(XTAL/(16*2*(baud))-2));
-       outreg(channel, DLL, XTAL / (16 * baud));
-       //  outreg(DLM,(XTAL/(16*2*(baud))-2)>>8);
-       outreg(channel, DLM, (XTAL / (16 * baud)) >> 8);
-#else
-       /*
-        * Note: Set baud rate, hardcoded here for rate of 115200
-        * since became unsure of above "baud rate" algorithm (??).
-        */
-       outreg(channel, LCR, 0x83);
-       outreg(channel, DLM, 0x00);     // See note above
-       outreg(channel, DLL, 0x02);     // See note above.
-       outreg(channel, LCR, 0x03);
-#endif
-
-       /*
-        * Restore line control register
-        */
-       outreg(channel, LCR, sav_lcr);
-}
-
-
-/******************************
- Routine:
- Description:
-   Transmit a character.
- ******************************/
-void serial_putc(int channel, int c)
-{
-       while ((inreg(channel, LSR) & LSR_THRE) == 0);
-       outreg(channel, THR, c);
-}
-
-/******************************
- Routine:
- Description:
-    Read a received character if one is
-    available.  Return -1 otherwise.
- ******************************/
-int serial_getc(int channel)
-{
-       if (inreg(channel, LSR) & LSR_DR) {
-               return inreg(channel, RBR);
-       }
-       return -1;
-}
-
-/******************************
- Routine:
- Description:
-   Used by embedded gdb client. (example; gdb-stub.c)
- ******************************/
-char getDebugChar()
-{
-       int val;
-       while ((val = serial_getc(DEBUG_CHANNEL)) == -1);       // loop until we get a character in.
-       return (char) val;
-}
-
-/******************************
- Routine:
- Description:
-   Used by embedded gdb target. (example; gdb-stub.c)
- ******************************/
-void putDebugChar(char c)
-{
-       serial_putc(DEBUG_CHANNEL, (int) c);
-}
diff --git a/arch/mips/gt64120/ev64120/setup.c b/arch/mips/gt64120/ev64120/setup.c
deleted file mode 100644 (file)
index 477848c..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2000 RidgeRun, Inc.
- * Author: RidgeRun, Inc.
- *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/swap.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/timex.h>
-#include <linux/pm.h>
-
-#include <asm/bootinfo.h>
-#include <asm/page.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/pci.h>
-#include <asm/processor.h>
-#include <asm/time.h>
-#include <asm/reboot.h>
-#include <asm/traps.h>
-#include <linux/bootmem.h>
-
-unsigned long gt64120_base = KSEG1ADDR(0x14000000);
-
-/* These functions are used for rebooting or halting the machine*/
-extern void galileo_machine_restart(char *command);
-extern void galileo_machine_halt(void);
-extern void galileo_machine_power_off(void);
-/*
- *This structure holds pointers to the pci configuration space accesses
- *and interrupts allocating routine for device over the PCI
- */
-extern struct pci_ops galileo_pci_ops;
-
-void __init prom_free_prom_memory(void)
-{
-}
-
-/*
- * Initializes basic routines and structures pointers, memory size (as
- * given by the bios and saves the command line.
- */
-
-void __init plat_mem_setup(void)
-{
-       _machine_restart = galileo_machine_restart;
-       _machine_halt = galileo_machine_halt;
-       pm_power_off = galileo_machine_power_off;
-
-       set_io_port_base(KSEG1);
-}
-
-const char *get_system_type(void)
-{
-       return "Galileo EV64120A";
-}
-
-/*
- * Kernel arguments passed by the firmware
- *
- * $a0 - nothing
- * $a1 - holds a pointer to the eprom parameters
- * $a2 - nothing
- */
-
-void __init prom_init(void)
-{
-       mips_machgroup = MACH_GROUP_GALILEO;
-       mips_machtype = MACH_EV64120A;
-
-       add_memory_region(0, 32 << 20, BOOT_MEM_RAM);
-}
index 9f9a33fc76b918094aabb9e2a672e366adc8b69a..1df5fe23c642fbe524a30ac794e607ebcde0eab1 100644 (file)
@@ -2,6 +2,6 @@
 # Makefile for Momentum's Ocelot board.
 #
 
-obj-y                  += irq.o prom.o reset.o setup.o
+obj-y                  += irq.o ocelot-platform.o prom.o reset.o setup.o
 
 obj-$(CONFIG_KGDB)     += dbg_io.o
diff --git a/arch/mips/gt64120/momenco_ocelot/ocelot-platform.c b/arch/mips/gt64120/momenco_ocelot/ocelot-platform.c
new file mode 100644 (file)
index 0000000..81d9031
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org)
+ *
+ * A NS16552 DUART with a 20MHz crystal.
+ *
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/serial_8250.h>
+
+#define OCELOT_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP)
+
+static struct plat_serial8250_port uart8250_data[] = {
+       {
+               .mapbase        = 0xe0001020,
+               .irq            = 4,
+               .uartclk        = 20000000,
+               .iotype         = UPIO_MEM,
+               .flags          = OCELOT_UART_FLAGS,
+               .regshift       = 2,
+       },
+       { },
+};
+
+static struct platform_device uart8250_device = {
+       .name                   = "serial8250",
+       .id                     = PLAT8250_DEV_PLATFORM,
+       .dev                    = {
+               .platform_data  = uart8250_data,
+       },
+};
+
+static int __init uart8250_init(void)
+{
+       return platform_device_register(&uart8250_device);
+}
+
+module_init(uart8250_init);
+
+MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("8250 UART probe driver for the Momenco Ocelot");
index 121188d5ec4a3ee90660bf4c6c557001cd46afec..ea965529e5e06600893fd4a2fbadcce9aa67e072 100644 (file)
@@ -158,8 +158,8 @@ const char *get_system_type(void)
  */
 void __init prom_init(void)
 {
-       mips_machgroup = MACH_GROUP_GALILEO;
-       mips_machtype = MACH_EV64120A;
+       mips_machgroup = MACH_GROUP_WINDRIVER;
+       mips_machtype = MACH_WRPPMC;
 
        add_memory_region(WRPPMC_SDRAM_SCS0_BASE, WRPPMC_SDRAM_SCS0_SIZE, BOOT_MEM_RAM);
        add_memory_region(WRPPMC_BOOTROM_BASE, WRPPMC_BOOTROM_SIZE, BOOT_MEM_ROM_DATA);
index dd9d99bfcf7a2d5cf6535740f2a7cb1594aa2e58..ae4c402b500421f4877d22aae1249dc4e22fa07d 100644 (file)
@@ -2,4 +2,4 @@
 # Makefile for the Jazz family specific parts of the kernel
 #
 
-obj-y          := irq.o jazzdma.o reset.o setup.o
+obj-y          := irq.o jazzdma.o jazz-platform.o reset.o setup.o
diff --git a/arch/mips/jazz/jazz-platform.c b/arch/mips/jazz/jazz-platform.c
new file mode 100644 (file)
index 0000000..fd73670
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org)
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/serial_8250.h>
+
+#include <asm/jazz.h>
+
+/*
+ * Confusion ...  It seems the original Microsoft Jazz machine used to have a
+ * 4.096MHz clock for its UART while the MIPS Magnum and Millenium systems
+ * had 8MHz.  The Olivetti M700-10 and the Acer PICA have 1.8432MHz like PCs.
+ */
+#ifdef CONFIG_OLIVETTI_M700
+#define JAZZ_BASE_BAUD 1843200
+#else
+#define JAZZ_BASE_BAUD 8000000 /* 3072000 */
+#endif
+
+#define JAZZ_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP)
+
+#define JAZZ_PORT(base, int)                                           \
+{                                                                      \
+       .mapbase        = base,                                         \
+       .irq            = int,                                          \
+       .uartclk        = JAZZ_BASE_BAUD,                               \
+       .iotype         = UPIO_MEM,                                     \
+       .flags          = JAZZ_UART_FLAGS,                              \
+       .regshift       = 0,                                            \
+}
+
+static struct plat_serial8250_port uart8250_data[] = {
+       JAZZ_PORT(JAZZ_SERIAL1_BASE, JAZZ_SERIAL1_IRQ),
+       JAZZ_PORT(JAZZ_SERIAL2_BASE, JAZZ_SERIAL2_IRQ),
+       { },
+};
+
+static struct platform_device uart8250_device = {
+       .name                   = "serial8250",
+       .id                     = PLAT8250_DEV_PLATFORM,
+       .dev                    = {
+               .platform_data  = uart8250_data,
+       },
+};
+
+static int __init uart8250_init(void)
+{
+       return platform_device_register(&uart8250_device);
+}
+
+module_init(uart8250_init);
+
+MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("8250 UART probe driver for the Jazz family");
diff --git a/arch/mips/kernel/8250-platform.c b/arch/mips/kernel/8250-platform.c
new file mode 100644 (file)
index 0000000..cbf3fe2
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org)
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/serial_8250.h>
+
+#define PORT(base, int)                                                        \
+{                                                                      \
+       .iobase         = base,                                         \
+       .irq            = int,                                          \
+       .uartclk        = 1843200,                                      \
+       .iotype         = UPIO_PORT,                                    \
+       .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,            \
+       .regshift       = 0,                                            \
+}
+
+static struct plat_serial8250_port uart8250_data[] = {
+       PORT(0x3F8, 4),
+       PORT(0x2F8, 3),
+       PORT(0x3E8, 4),
+       PORT(0x2E8, 3),
+       { },
+};
+
+static struct platform_device uart8250_device = {
+       .name                   = "serial8250",
+       .id                     = PLAT8250_DEV_PLATFORM,
+       .dev                    = {
+               .platform_data  = uart8250_data,
+       },
+};
+
+static int __init uart8250_init(void)
+{
+       return platform_device_register(&uart8250_device);
+}
+
+module_init(uart8250_init);
+
+MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Generic 8250 UART probe driver");
index 49246264cc7c66a0386bb44733dbc79396006b1e..5c8085b6d7ab944d1e0efbcc70ba270eaa2bafe4 100644 (file)
@@ -14,14 +14,15 @@ binfmt_irix-objs    := irixelf.o irixinv.o irixioctl.o irixsig.o    \
 obj-$(CONFIG_STACKTRACE)       += stacktrace.o
 obj-$(CONFIG_MODULES)          += mips_ksyms.o module.o
 
+obj-$(CONFIG_CPU_LOONGSON2)    += r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_MIPS32)       += r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_MIPS64)       += r4k_fpu.o r4k_switch.o
 obj-$(CONFIG_CPU_R3000)                += r2300_fpu.o r2300_switch.o
-obj-$(CONFIG_CPU_TX39XX)       += r2300_fpu.o r2300_switch.o
-obj-$(CONFIG_CPU_TX49XX)       += r4k_fpu.o r4k_switch.o
 obj-$(CONFIG_CPU_R4000)                += r4k_fpu.o r4k_switch.o
-obj-$(CONFIG_CPU_VR41XX)       += r4k_fpu.o r4k_switch.o
 obj-$(CONFIG_CPU_R4300)                += r4k_fpu.o r4k_switch.o
 obj-$(CONFIG_CPU_R4X00)                += r4k_fpu.o r4k_switch.o
 obj-$(CONFIG_CPU_R5000)                += r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_R6000)                += r6000_fpu.o r4k_switch.o
 obj-$(CONFIG_CPU_R5432)                += r4k_fpu.o r4k_switch.o
 obj-$(CONFIG_CPU_R8000)                += r4k_fpu.o r4k_switch.o
 obj-$(CONFIG_CPU_RM7000)       += r4k_fpu.o r4k_switch.o
@@ -29,13 +30,14 @@ obj-$(CONFIG_CPU_RM9000)    += r4k_fpu.o r4k_switch.o
 obj-$(CONFIG_CPU_NEVADA)       += r4k_fpu.o r4k_switch.o
 obj-$(CONFIG_CPU_R10000)       += r4k_fpu.o r4k_switch.o
 obj-$(CONFIG_CPU_SB1)          += r4k_fpu.o r4k_switch.o
-obj-$(CONFIG_CPU_MIPS32)       += r4k_fpu.o r4k_switch.o
-obj-$(CONFIG_CPU_MIPS64)       += r4k_fpu.o r4k_switch.o
-obj-$(CONFIG_CPU_R6000)                += r6000_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_TX39XX)       += r2300_fpu.o r2300_switch.o
+obj-$(CONFIG_CPU_TX49XX)       += r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_VR41XX)       += r4k_fpu.o r4k_switch.o
 
 obj-$(CONFIG_SMP)              += smp.o
 
 obj-$(CONFIG_MIPS_MT)          += mips-mt.o
+obj-$(CONFIG_MIPS_MT_FPAFF)    += mips-mt-fpaff.o
 obj-$(CONFIG_MIPS_MT_SMTC)     += smtc.o smtc-asm.o smtc-proc.o
 obj-$(CONFIG_MIPS_MT_SMP)      += smp-mt.o
 
@@ -47,7 +49,6 @@ obj-$(CONFIG_I8259)           += i8259.o
 obj-$(CONFIG_IRQ_CPU)          += irq_cpu.o
 obj-$(CONFIG_IRQ_CPU_RM7K)     += irq-rm7000.o
 obj-$(CONFIG_IRQ_CPU_RM9K)     += irq-rm9000.o
-obj-$(CONFIG_IRQ_MV64340)      += irq-mv6434x.o
 obj-$(CONFIG_MIPS_BOARDS_GEN)  += irq-msc01.o
 
 obj-$(CONFIG_32BIT)            += scall32-o32.o
@@ -62,9 +63,11 @@ obj-$(CONFIG_PROC_FS)                += proc.o
 
 obj-$(CONFIG_64BIT)            += cpu-bugs64.o
 
-obj-$(CONFIG_I8253)            += i8253.o
+obj-$(CONFIG_PCSPEAKER)                += pcspeaker.o
 
 obj-$(CONFIG_KEXEC)            += machine_kexec.o relocate_kernel.o
 obj-$(CONFIG_EARLY_PRINTK)     += early_printk.o
 
 CFLAGS_cpu-bugs64.o    = $(shell if $(CC) $(CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi)
+
+obj-$(CONFIG_HAVE_STD_PC_SERIAL_PORT)  += 8250-platform.o
index 76fd3f22c76624363d94b7e4b870d0e798ff282d..6b5df8bfab85d0a97b503ad2ca441ff37d4c21d0 100644 (file)
@@ -22,7 +22,8 @@
  */
 int __compute_return_epc(struct pt_regs *regs)
 {
-       unsigned int *addr, bit, fcr31, dspcontrol;
+       unsigned int __user *addr;
+       unsigned int bit, fcr31, dspcontrol;
        long epc;
        union mips_instruction insn;
 
@@ -33,7 +34,7 @@ int __compute_return_epc(struct pt_regs *regs)
        /*
         * Read the instruction
         */
-       addr = (unsigned int *) epc;
+       addr = (unsigned int __user *) epc;
        if (__get_user(insn.word, addr)) {
                force_sig(SIGSEGV, current);
                return -EFAULT;
index b12eeee0e9748f841d85de87dfe2f7a7c3503d69..c6b8b074a81aa65fad1fa9d0ce3aede09bff8ef5 100644 (file)
@@ -186,9 +186,29 @@ static inline void check_wait(void)
        }
 }
 
+static inline void check_errata(void)
+{
+       struct cpuinfo_mips *c = &current_cpu_data;
+
+       switch (c->cputype) {
+       case CPU_34K:
+               /*
+                * Erratum "RPS May Cause Incorrect Instruction Execution"
+                * This code only handles VPE0, any SMP/SMTC/RTOS code
+                * making use of VPE1 will be responsable for that VPE.
+                */
+               if ((c->processor_id & PRID_REV_MASK) <= PRID_REV_34K_V1_0_2)
+                       write_c0_config7(read_c0_config7() | MIPS_CONF7_RPS);
+               break;
+       default:
+               break;
+       }
+}
+
 void __init check_bugs32(void)
 {
        check_wait();
+       check_errata();
 }
 
 /*
@@ -485,6 +505,14 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c)
                             MIPS_CPU_LLSC;
                c->tlbsize = 64;
                break;
+       case PRID_IMP_LOONGSON2:
+               c->cputype = CPU_LOONGSON2;
+               c->isa_level = MIPS_CPU_ISA_III;
+               c->options = R4K_OPTS |
+                            MIPS_CPU_FPU | MIPS_CPU_LLSC |
+                            MIPS_CPU_32FPR;
+               c->tlbsize = 64;
+               break;
        }
 }
 
@@ -588,6 +616,8 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c)
                c->options |= MIPS_CPU_VEIC;
        if (config3 & MIPS_CONF3_MT)
                c->ases |= MIPS_ASE_MIPSMT;
+       if (config3 & MIPS_CONF3_ULRI)
+               c->options |= MIPS_CPU_ULRI;
 
        return config3 & MIPS_CONF_M;
 }
index 686249c5c328a34c105e1c50d458b71effa033f7..e29598ae939d21b7d8e7442300a8741ce612f24a 100644 (file)
@@ -84,6 +84,7 @@ FEXPORT(restore_all)                  # restore full frame
        LONG_S  sp, TI_REGS($28)
        jal     deferred_smtc_ipi
        LONG_S  s0, TI_REGS($28)
+#ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP
 /* Re-arm any temporarily masked interrupts not explicitly "acked" */
        mfc0    v0, CP0_TCSTATUS
        ori     v1, v0, TCSTATUS_IXMT
@@ -110,6 +111,7 @@ FEXPORT(restore_all)                        # restore full frame
        _ehb
        xor     t0, t0, t3
        mtc0    t0, CP0_TCCONTEXT
+#endif /* CONFIG_MIPS_MT_SMTC_IM_BACKSTOP */
 #endif /* CONFIG_MIPS_MT_SMTC */
        .set    noat
        RESTORE_TEMP
index 297bd56c23471facbd75cbb31b460707c5bf13ba..c0f19d638b986c4f5be93b801a90b4e6717c6419 100644 (file)
@@ -243,9 +243,11 @@ NESTED(except_vec_vi_handler, 0, sp)
         */
        mfc0    t1, CP0_STATUS
        and     t0, a0, t1
+#ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP
        mfc0    t2, CP0_TCCONTEXT
        or      t0, t0, t2
        mtc0    t0, CP0_TCCONTEXT
+#endif /* CONFIG_MIPS_MT_SMTC_IM_BACKSTOP */
        xor     t1, t1, t0
        mtc0    t1, CP0_STATUS
        _ehb
index 6f57ca44291f98a445eeb99b294a67ada0d02a35..f78538eceef77c903bf393b20256ce7b2a5552a7 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/init.h>
 #include <linux/threads.h>
 
+#include <asm/addrspace.h>
 #include <asm/asm.h>
 #include <asm/asmmacro.h>
 #include <asm/irqflags.h>
 #endif
        .endm
 
+#ifndef CONFIG_NO_EXCEPT_FILL
        /*
         * Reserved space for exception handlers.
         * Necessary for machines which link their kernels at KSEG0.
         */
        .fill   0x400
+#endif
 
 EXPORT(stext)                                  # used for profiling
 EXPORT(_stext)
 
-#ifdef CONFIG_MIPS_SIM
+#ifdef CONFIG_BOOT_RAW
        /*
         * Give us a fighting chance of running if execution beings at the
         * kernel load address.  This is needed because this platform does
         * not have a ELF loader yet.
         */
-       j       kernel_entry
-#endif
        __INIT
+#endif
 
 NESTED(kernel_entry, 16, sp)                   # kernel entry point
 
@@ -197,9 +199,7 @@ NESTED(kernel_entry, 16, sp)                        # kernel entry point
        j               start_kernel
        END(kernel_entry)
 
-#ifdef CONFIG_QEMU
        __INIT
-#endif
 
 #ifdef CONFIG_SMP
 /*
diff --git a/arch/mips/kernel/irq-mv6434x.c b/arch/mips/kernel/irq-mv6434x.c
deleted file mode 100644 (file)
index 3dd5618..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright 2002 Momentum Computer
- * Author: mdharm@momenco.com
- * Copyright (C) 2004, 06 Ralf Baechle <ralf@linux-mips.org>
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/kernel_stat.h>
-#include <linux/mv643xx.h>
-#include <linux/sched.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/marvell.h>
-
-static unsigned int irq_base;
-
-static inline int ls1bit32(unsigned int x)
-{
-       int b = 31, s;
-
-       s = 16; if (x << 16 == 0) s = 0; b -= s; x <<= s;
-       s =  8; if (x <<  8 == 0) s = 0; b -= s; x <<= s;
-       s =  4; if (x <<  4 == 0) s = 0; b -= s; x <<= s;
-       s =  2; if (x <<  2 == 0) s = 0; b -= s; x <<= s;
-       s =  1; if (x <<  1 == 0) s = 0; b -= s;
-
-        return b;
-}
-
-/* mask off an interrupt -- 1 is enable, 0 is disable */
-static inline void mask_mv64340_irq(unsigned int irq)
-{
-       uint32_t value;
-
-       if (irq < (irq_base + 32)) {
-               value = MV_READ(MV64340_INTERRUPT0_MASK_0_LOW);
-               value &= ~(1 << (irq - irq_base));
-               MV_WRITE(MV64340_INTERRUPT0_MASK_0_LOW, value);
-       } else {
-               value = MV_READ(MV64340_INTERRUPT0_MASK_0_HIGH);
-               value &= ~(1 << (irq - irq_base - 32));
-               MV_WRITE(MV64340_INTERRUPT0_MASK_0_HIGH, value);
-       }
-}
-
-/* unmask an interrupt -- 1 is enable, 0 is disable */
-static inline void unmask_mv64340_irq(unsigned int irq)
-{
-       uint32_t value;
-
-       if (irq < (irq_base + 32)) {
-               value = MV_READ(MV64340_INTERRUPT0_MASK_0_LOW);
-               value |= 1 << (irq - irq_base);
-               MV_WRITE(MV64340_INTERRUPT0_MASK_0_LOW, value);
-       } else {
-               value = MV_READ(MV64340_INTERRUPT0_MASK_0_HIGH);
-               value |= 1 << (irq - irq_base - 32);
-               MV_WRITE(MV64340_INTERRUPT0_MASK_0_HIGH, value);
-       }
-}
-
-/*
- * Interrupt handler for interrupts coming from the Marvell chip.
- * It could be built in ethernet ports etc...
- */
-void ll_mv64340_irq(void)
-{
-       unsigned int irq_src_low, irq_src_high;
-       unsigned int irq_mask_low, irq_mask_high;
-
-       /* read the interrupt status registers */
-       irq_mask_low = MV_READ(MV64340_INTERRUPT0_MASK_0_LOW);
-       irq_mask_high = MV_READ(MV64340_INTERRUPT0_MASK_0_HIGH);
-       irq_src_low = MV_READ(MV64340_MAIN_INTERRUPT_CAUSE_LOW);
-       irq_src_high = MV_READ(MV64340_MAIN_INTERRUPT_CAUSE_HIGH);
-
-       /* mask for just the interrupts we want */
-       irq_src_low &= irq_mask_low;
-       irq_src_high &= irq_mask_high;
-
-       if (irq_src_low)
-               do_IRQ(ls1bit32(irq_src_low) + irq_base);
-       else
-               do_IRQ(ls1bit32(irq_src_high) + irq_base + 32);
-}
-
-struct irq_chip mv64340_irq_type = {
-       .name = "MV-64340",
-       .ack = mask_mv64340_irq,
-       .mask = mask_mv64340_irq,
-       .mask_ack = mask_mv64340_irq,
-       .unmask = unmask_mv64340_irq,
-};
-
-void __init mv64340_irq_init(unsigned int base)
-{
-       int i;
-
-       for (i = base; i < base + 64; i++)
-               set_irq_chip_and_handler(i, &mv64340_irq_type,
-                                        handle_level_irq);
-
-       irq_base = base;
-}
diff --git a/arch/mips/kernel/mips-mt-fpaff.c b/arch/mips/kernel/mips-mt-fpaff.c
new file mode 100644 (file)
index 0000000..ede5d73
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * General MIPS MT support routines, usable in AP/SP, SMVP, or SMTC kernels
+ * Copyright (C) 2005 Mips Technologies, Inc
+ */
+#include <linux/cpu.h>
+#include <linux/cpumask.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/security.h>
+#include <linux/types.h>
+#include <asm/uaccess.h>
+
+/*
+ * CPU mask used to set process affinity for MT VPEs/TCs with FPUs
+ */
+cpumask_t mt_fpu_cpumask;
+
+static int fpaff_threshold = -1;
+unsigned long mt_fpemul_threshold = 0;
+
+/*
+ * Replacement functions for the sys_sched_setaffinity() and
+ * sys_sched_getaffinity() system calls, so that we can integrate
+ * FPU affinity with the user's requested processor affinity.
+ * This code is 98% identical with the sys_sched_setaffinity()
+ * and sys_sched_getaffinity() system calls, and should be
+ * updated when kernel/sched.c changes.
+ */
+
+/*
+ * find_process_by_pid - find a process with a matching PID value.
+ * used in sys_sched_set/getaffinity() in kernel/sched.c, so
+ * cloned here.
+ */
+static inline struct task_struct *find_process_by_pid(pid_t pid)
+{
+       return pid ? find_task_by_pid(pid) : current;
+}
+
+
+/*
+ * mipsmt_sys_sched_setaffinity - set the cpu affinity of a process
+ */
+asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len,
+                                     unsigned long __user *user_mask_ptr)
+{
+       cpumask_t new_mask;
+       cpumask_t effective_mask;
+       int retval;
+       struct task_struct *p;
+
+       if (len < sizeof(new_mask))
+               return -EINVAL;
+
+       if (copy_from_user(&new_mask, user_mask_ptr, sizeof(new_mask)))
+               return -EFAULT;
+
+       lock_cpu_hotplug();
+       read_lock(&tasklist_lock);
+
+       p = find_process_by_pid(pid);
+       if (!p) {
+               read_unlock(&tasklist_lock);
+               unlock_cpu_hotplug();
+               return -ESRCH;
+       }
+
+       /*
+        * It is not safe to call set_cpus_allowed with the
+        * tasklist_lock held.  We will bump the task_struct's
+        * usage count and drop tasklist_lock before invoking
+        * set_cpus_allowed.
+        */
+       get_task_struct(p);
+
+       retval = -EPERM;
+       if ((current->euid != p->euid) && (current->euid != p->uid) &&
+                       !capable(CAP_SYS_NICE)) {
+               read_unlock(&tasklist_lock);
+               goto out_unlock;
+       }
+
+       retval = security_task_setscheduler(p, 0, NULL);
+       if (retval)
+               goto out_unlock;
+
+       /* Record new user-specified CPU set for future reference */
+       p->thread.user_cpus_allowed = new_mask;
+
+       /* Unlock the task list */
+       read_unlock(&tasklist_lock);
+
+       /* Compute new global allowed CPU set if necessary */
+       if ((p->thread.mflags & MF_FPUBOUND)
+       && cpus_intersects(new_mask, mt_fpu_cpumask)) {
+               cpus_and(effective_mask, new_mask, mt_fpu_cpumask);
+               retval = set_cpus_allowed(p, effective_mask);
+       } else {
+               p->thread.mflags &= ~MF_FPUBOUND;
+               retval = set_cpus_allowed(p, new_mask);
+       }
+
+
+out_unlock:
+       put_task_struct(p);
+       unlock_cpu_hotplug();
+       return retval;
+}
+
+/*
+ * mipsmt_sys_sched_getaffinity - get the cpu affinity of a process
+ */
+asmlinkage long mipsmt_sys_sched_getaffinity(pid_t pid, unsigned int len,
+                                     unsigned long __user *user_mask_ptr)
+{
+       unsigned int real_len;
+       cpumask_t mask;
+       int retval;
+       struct task_struct *p;
+
+       real_len = sizeof(mask);
+       if (len < real_len)
+               return -EINVAL;
+
+       lock_cpu_hotplug();
+       read_lock(&tasklist_lock);
+
+       retval = -ESRCH;
+       p = find_process_by_pid(pid);
+       if (!p)
+               goto out_unlock;
+       retval = security_task_getscheduler(p);
+       if (retval)
+               goto out_unlock;
+
+       cpus_and(mask, p->thread.user_cpus_allowed, cpu_possible_map);
+
+out_unlock:
+       read_unlock(&tasklist_lock);
+       unlock_cpu_hotplug();
+       if (retval)
+               return retval;
+       if (copy_to_user(user_mask_ptr, &mask, real_len))
+               return -EFAULT;
+       return real_len;
+}
+
+
+static int __init fpaff_thresh(char *str)
+{
+       get_option(&str, &fpaff_threshold);
+       return 1;
+}
+__setup("fpaff=", fpaff_thresh);
+
+/*
+ * FPU Use Factor empirically derived from experiments on 34K
+ */
+#define FPUSEFACTOR 333
+
+static __init int mt_fp_affinity_init(void)
+{
+       if (fpaff_threshold >= 0) {
+               mt_fpemul_threshold = fpaff_threshold;
+       } else {
+               mt_fpemul_threshold =
+                       (FPUSEFACTOR * (loops_per_jiffy/(500000/HZ))) / HZ;
+       }
+       printk(KERN_DEBUG "FPU Affinity set after %ld emulations\n",
+              mt_fpemul_threshold);
+
+       return 0;
+}
+arch_initcall(mt_fp_affinity_init);
index ba01800b601874d4a224c2752d8682dd1c606853..1a7d89231299f23dc6aaffff47e8fdbe86b3a42e 100644 (file)
@@ -6,7 +6,6 @@
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/cpumask.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/security.h>
 #include <asm/r4kcache.h>
 #include <asm/cacheflush.h>
 
-/*
- * CPU mask used to set process affinity for MT VPEs/TCs with FPUs
- */
-
-cpumask_t mt_fpu_cpumask;
-
-#ifdef CONFIG_MIPS_MT_FPAFF
-
-#include <linux/cpu.h>
-#include <linux/delay.h>
-#include <asm/uaccess.h>
-
-unsigned long mt_fpemul_threshold = 0;
-
-/*
- * Replacement functions for the sys_sched_setaffinity() and
- * sys_sched_getaffinity() system calls, so that we can integrate
- * FPU affinity with the user's requested processor affinity.
- * This code is 98% identical with the sys_sched_setaffinity()
- * and sys_sched_getaffinity() system calls, and should be
- * updated when kernel/sched.c changes.
- */
-
-/*
- * find_process_by_pid - find a process with a matching PID value.
- * used in sys_sched_set/getaffinity() in kernel/sched.c, so
- * cloned here.
- */
-static inline struct task_struct *find_process_by_pid(pid_t pid)
-{
-       return pid ? find_task_by_pid(pid) : current;
-}
-
-
-/*
- * mipsmt_sys_sched_setaffinity - set the cpu affinity of a process
- */
-asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len,
-                                     unsigned long __user *user_mask_ptr)
-{
-       cpumask_t new_mask;
-       cpumask_t effective_mask;
-       int retval;
-       struct task_struct *p;
-
-       if (len < sizeof(new_mask))
-               return -EINVAL;
-
-       if (copy_from_user(&new_mask, user_mask_ptr, sizeof(new_mask)))
-               return -EFAULT;
-
-       lock_cpu_hotplug();
-       read_lock(&tasklist_lock);
-
-       p = find_process_by_pid(pid);
-       if (!p) {
-               read_unlock(&tasklist_lock);
-               unlock_cpu_hotplug();
-               return -ESRCH;
-       }
-
-       /*
-        * It is not safe to call set_cpus_allowed with the
-        * tasklist_lock held.  We will bump the task_struct's
-        * usage count and drop tasklist_lock before invoking
-        * set_cpus_allowed.
-        */
-       get_task_struct(p);
-
-       retval = -EPERM;
-       if ((current->euid != p->euid) && (current->euid != p->uid) &&
-                       !capable(CAP_SYS_NICE)) {
-               read_unlock(&tasklist_lock);
-               goto out_unlock;
-       }
-
-       retval = security_task_setscheduler(p, 0, NULL);
-       if (retval)
-               goto out_unlock;
-
-       /* Record new user-specified CPU set for future reference */
-       p->thread.user_cpus_allowed = new_mask;
-
-       /* Unlock the task list */
-       read_unlock(&tasklist_lock);
-
-       /* Compute new global allowed CPU set if necessary */
-       if( (p->thread.mflags & MF_FPUBOUND)
-       && cpus_intersects(new_mask, mt_fpu_cpumask)) {
-               cpus_and(effective_mask, new_mask, mt_fpu_cpumask);
-               retval = set_cpus_allowed(p, effective_mask);
-       } else {
-               p->thread.mflags &= ~MF_FPUBOUND;
-               retval = set_cpus_allowed(p, new_mask);
-       }
-
-
-out_unlock:
-       put_task_struct(p);
-       unlock_cpu_hotplug();
-       return retval;
-}
-
-/*
- * mipsmt_sys_sched_getaffinity - get the cpu affinity of a process
- */
-asmlinkage long mipsmt_sys_sched_getaffinity(pid_t pid, unsigned int len,
-                                     unsigned long __user *user_mask_ptr)
-{
-       unsigned int real_len;
-       cpumask_t mask;
-       int retval;
-       struct task_struct *p;
-
-       real_len = sizeof(mask);
-       if (len < real_len)
-               return -EINVAL;
-
-       lock_cpu_hotplug();
-       read_lock(&tasklist_lock);
-
-       retval = -ESRCH;
-       p = find_process_by_pid(pid);
-       if (!p)
-               goto out_unlock;
-       retval = security_task_getscheduler(p);
-       if (retval)
-               goto out_unlock;
-
-       cpus_and(mask, p->thread.user_cpus_allowed, cpu_possible_map);
-
-out_unlock:
-       read_unlock(&tasklist_lock);
-       unlock_cpu_hotplug();
-       if (retval)
-               return retval;
-       if (copy_to_user(user_mask_ptr, &mask, real_len))
-               return -EFAULT;
-       return real_len;
-}
-
-#endif /* CONFIG_MIPS_MT_FPAFF */
-
 /*
  * Dump new MIPS MT state for the core. Does not leave TCs halted.
  * Takes an argument which taken to be a pre-call MVPControl value.
@@ -195,27 +51,31 @@ void mips_mt_regdump(unsigned long mvpctl)
        nvpe = ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1;
        ntc = ((mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1;
        printk("-- per-VPE State --\n");
-       for(i = 0; i < nvpe; i++) {
-           for(tc = 0; tc < ntc; tc++) {
+       for (i = 0; i < nvpe; i++) {
+               for (tc = 0; tc < ntc; tc++) {
                        settc(tc);
-               if((read_tc_c0_tcbind() & TCBIND_CURVPE) == i) {
-                   printk("  VPE %d\n", i);
-                   printk("   VPEControl : %08lx\n", read_vpe_c0_vpecontrol());
-                   printk("   VPEConf0 : %08lx\n", read_vpe_c0_vpeconf0());
-                   printk("   VPE%d.Status : %08lx\n",
-                               i, read_vpe_c0_status());
-                   printk("   VPE%d.EPC : %08lx\n", i, read_vpe_c0_epc());
-                   printk("   VPE%d.Cause : %08lx\n", i, read_vpe_c0_cause());
-                   printk("   VPE%d.Config7 : %08lx\n",
-                               i, read_vpe_c0_config7());
-                   break; /* Next VPE */
+                       if ((read_tc_c0_tcbind() & TCBIND_CURVPE) == i) {
+                               printk("  VPE %d\n", i);
+                               printk("   VPEControl : %08lx\n",
+                                      read_vpe_c0_vpecontrol());
+                               printk("   VPEConf0 : %08lx\n",
+                                      read_vpe_c0_vpeconf0());
+                               printk("   VPE%d.Status : %08lx\n",
+                                      i, read_vpe_c0_status());
+                               printk("   VPE%d.EPC : %08lx\n",
+                                      i, read_vpe_c0_epc());
+                               printk("   VPE%d.Cause : %08lx\n",
+                                      i, read_vpe_c0_cause());
+                               printk("   VPE%d.Config7 : %08lx\n",
+                                      i, read_vpe_c0_config7());
+                               break; /* Next VPE */
+                       }
                }
-           }
        }
        printk("-- per-TC State --\n");
-       for(tc = 0; tc < ntc; tc++) {
+       for (tc = 0; tc < ntc; tc++) {
                settc(tc);
-               if(read_tc_c0_tcbind() == read_c0_tcbind()) {
+               if (read_tc_c0_tcbind() == read_c0_tcbind()) {
                        /* Are we dumping ourself?  */
                        haltval = 0; /* Then we're not halted, and mustn't be */
                        tcstatval = flags; /* And pre-dump TCStatus is flags */
@@ -310,17 +170,6 @@ static int __init ndflush(char *s)
        return 1;
 }
 __setup("ndflush=", ndflush);
-#ifdef CONFIG_MIPS_MT_FPAFF
-static int fpaff_threshold = -1;
-
-static int __init fpaff_thresh(char *str)
-{
-       get_option(&str, &fpaff_threshold);
-       return 1;
-}
-
-__setup("fpaff=", fpaff_thresh);
-#endif /* CONFIG_MIPS_MT_FPAFF */
 
 static unsigned int itc_base = 0;
 
@@ -376,20 +225,6 @@ void mips_mt_set_cpuoptions(void)
        if (mt_n_dflushes != 1)
                printk("D-Cache Flushes Repeated %d times\n", mt_n_dflushes);
 
-#ifdef CONFIG_MIPS_MT_FPAFF
-       /* FPU Use Factor empirically derived from experiments on 34K */
-#define FPUSEFACTOR 333
-
-       if (fpaff_threshold >= 0) {
-               mt_fpemul_threshold = fpaff_threshold;
-       } else {
-               mt_fpemul_threshold =
-                       (FPUSEFACTOR * (loops_per_jiffy/(500000/HZ))) / HZ;
-       }
-       printk("FPU Affinity set after %ld emulations\n",
-                       mt_fpemul_threshold);
-#endif /* CONFIG_MIPS_MT_FPAFF */
-
        if (itc_base != 0) {
                /*
                 * Configure ITC mapping.  This code is very
index 5ddc2e9deecf3cfa042976c33b9b932c7d27edbe..ec04f5a1a5eadf2078962f682960108845b270ed 100644 (file)
@@ -14,7 +14,6 @@
 #include <asm/cpu-features.h>
 #include <asm/mipsregs.h>
 #include <asm/processor.h>
-#include <asm/watch.h>
 
 unsigned int vced_count, vcei_count;
 
@@ -84,6 +83,7 @@ static const char *cpu_name[] = {
        [CPU_VR4181A]   = "NEC VR4181A",
        [CPU_SR71000]   = "Sandcraft SR71000",
        [CPU_PR4450]    = "Philips PR4450",
+       [CPU_LOONGSON2] = "ICT Loongson-2",
 };
 
 
index 6bdfb5a9fa1a465ee9ec15193999780cea1b8d16..8f4cf27c7157e634cd7b4b226410868352a81862 100644 (file)
@@ -46,7 +46,7 @@
  * power and have a low exit latency (ie sit in a loop waiting for somebody to
  * say that they'd like to reschedule)
  */
-ATTRIB_NORET void cpu_idle(void)
+void __noreturn cpu_idle(void)
 {
        /* endless idle loop with no priority at all */
        while (1) {
@@ -213,7 +213,7 @@ int dump_task_fpu (struct task_struct *t, elf_fpregset_t *fpr)
 /*
  * Create a kernel thread
  */
-static ATTRIB_NORET void kernel_thread_helper(void *arg, int (*fn)(void *))
+static void __noreturn kernel_thread_helper(void *arg, int (*fn)(void *))
 {
        do_exit(fn(arg));
 }
index 06729596812f744581cce609938fee82d36d25cc..d9bfae53c43f92c5a400301bb02bfb3c05bfad92 100644 (file)
        move    $28, a2
        cpu_restore_nonscratch a1
 
-#if (_THREAD_SIZE - 32) < 0x10000
-       PTR_ADDIU       t0, $28, _THREAD_SIZE - 32
-#else
-       PTR_LI          t0, _THREAD_SIZE - 32
-       PTR_ADDU        t0, $28
-#endif
+       PTR_ADDU        t0, $28, _THREAD_SIZE - 32
        set_saved_sp    t0, t1, t2
 #ifdef CONFIG_MIPS_MT_SMTC
        /* Read-modify-writes of Status must be atomic on a VPE */
index 4975da0bfb634cdf52ebffbfe2bffe68da61ace0..316685fca0592b555acaa46f3b2cdda49c39357a 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/highmem.h>
 #include <linux/console.h>
 #include <linux/pfn.h>
+#include <linux/debugfs.h>
 
 #include <asm/addrspace.h>
 #include <asm/bootinfo.h>
@@ -574,3 +575,18 @@ __setup("nodsp", dsp_disable);
 
 unsigned long kernelsp[NR_CPUS];
 unsigned long fw_arg0, fw_arg1, fw_arg2, fw_arg3;
+
+#ifdef CONFIG_DEBUG_FS
+struct dentry *mips_debugfs_dir;
+static int __init debugfs_mips(void)
+{
+       struct dentry *d;
+
+       d = debugfs_create_dir("mips", NULL);
+       if (IS_ERR(d))
+               return PTR_ERR(d);
+       mips_debugfs_dir = d;
+       return 0;
+}
+arch_initcall(debugfs_mips);
+#endif
index 67edfa7ed93a643d4a59af04d9a6c98a8d1ca12f..be7362bc2c9a6ef7340bf811d1260dd09cd5cef4 100644 (file)
@@ -51,18 +51,8 @@ int __cpu_logical_map[NR_CPUS];              /* Map logical to physical */
 EXPORT_SYMBOL(phys_cpu_present_map);
 EXPORT_SYMBOL(cpu_online_map);
 
-/* This happens early in bootup, can't really do it better */
-static void smp_tune_scheduling (void)
-{
-       struct cache_desc *cd = &current_cpu_data.scache;
-       unsigned long cachesize = cd->linesz * cd->sets * cd->ways;
-
-       if (cachesize > max_cache_size)
-               max_cache_size = cachesize;
-}
-
 extern void __init calibrate_delay(void);
-extern ATTRIB_NORET void cpu_idle(void);
+extern void cpu_idle(void);
 
 /*
  * First C code run on the secondary CPUs after being started up by
@@ -228,7 +218,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
 {
        init_new_context(current, &init_mm);
        current_thread_info()->cpu = 0;
-       smp_tune_scheduling();
        plat_prepare_cpus(max_cpus);
 #ifndef CONFIG_HOTPLUG_CPU
        cpu_present_map = cpu_possible_map;
index 046b03b1705ab5177f0c2f8bf8ce5ef8d48f0c05..342d873b2ecc8bf6185a1137777408af54a42cc2 100644 (file)
@@ -1104,7 +1104,7 @@ void smtc_idle_loop_hook(void)
        mtflags = dmt();
        pdb_msg = &id_ho_db_msg[0];
        im = read_c0_status();
-       vpe = cpu_data[smp_processor_id()].vpe_id;
+       vpe = current_cpu_data.vpe_id;
        for (bit = 0; bit < 8; bit++) {
                /*
                 * In current prototype, I/O interrupts
index 9dd5a2df8eac344c7701b2b7dab734c30d25d770..b947c61c0cc817f3d154f15c05d33d9fb27bdbae 100644 (file)
@@ -272,9 +272,8 @@ asmlinkage int sys_set_thread_area(unsigned long addr)
        struct thread_info *ti = task_thread_info(current);
 
        ti->tp_value = addr;
-
-       /* If some future MIPS implementation has this register in hardware,
-        * we will need to update it here (and in context switches).  */
+       if (cpu_has_userlocal)
+               write_c0_userlocal(addr);
 
        return 0;
 }
index 3ea7863c4519c5d19b80d3466b06f19031e8358a..37c562c4c8176f3dfe8dd88251ef1899b42b2ccf 100644 (file)
@@ -39,7 +39,6 @@
 #include <asm/traps.h>
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
-#include <asm/watch.h>
 #include <asm/types.h>
 #include <asm/stacktrace.h>
 
@@ -70,6 +69,7 @@ extern asmlinkage void handle_reserved(void);
 extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
        struct mips_fpu_struct *ctx, int has_fpu);
 
+void (*board_watchpoint_handler)(struct pt_regs *regs);
 void (*board_be_init)(void);
 int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
 void (*board_nmi_handler_setup)(void);
@@ -131,7 +131,7 @@ static void show_stacktrace(struct task_struct *task, struct pt_regs *regs)
        const int field = 2 * sizeof(unsigned long);
        long stackdata;
        int i;
-       unsigned long *sp = (unsigned long *)regs->regs[29];
+       unsigned long __user *sp = (unsigned long __user *)regs->regs[29];
 
        printk("Stack :");
        i = 0;
@@ -187,7 +187,7 @@ void dump_stack(void)
 
 EXPORT_SYMBOL(dump_stack);
 
-void show_code(unsigned int *pc)
+static void show_code(unsigned int __user *pc)
 {
        long i;
 
@@ -305,13 +305,13 @@ void show_registers(struct pt_regs *regs)
        printk("Process %s (pid: %d, threadinfo=%p, task=%p)\n",
                current->comm, current->pid, current_thread_info(), current);
        show_stacktrace(current, regs);
-       show_code((unsigned int *) regs->cp0_epc);
+       show_code((unsigned int __user *) regs->cp0_epc);
        printk("\n");
 }
 
 static DEFINE_SPINLOCK(die_lock);
 
-NORET_TYPE void ATTRIB_NORET die(const char * str, struct pt_regs * regs)
+void __noreturn die(const char * str, struct pt_regs * regs)
 {
        static int die_counter;
 #ifdef CONFIG_MIPS_MT_SMTC
@@ -373,7 +373,7 @@ asmlinkage void do_be(struct pt_regs *regs)
                action = MIPS_BE_FIXUP;
 
        if (board_be_handler)
-               action = board_be_handler(regs, fixup != 0);
+               action = board_be_handler(regs, fixup != NULL);
 
        switch (action) {
        case MIPS_BE_DISCARD:
@@ -753,6 +753,33 @@ asmlinkage void do_ri(struct pt_regs *regs)
        force_sig(SIGILL, current);
 }
 
+/*
+ * MIPS MT processors may have fewer FPU contexts than CPU threads. If we've
+ * emulated more than some threshold number of instructions, force migration to
+ * a "CPU" that has FP support.
+ */
+static void mt_ase_fp_affinity(void)
+{
+#ifdef CONFIG_MIPS_MT_FPAFF
+       if (mt_fpemul_threshold > 0 &&
+            ((current->thread.emulated_fp++ > mt_fpemul_threshold))) {
+               /*
+                * If there's no FPU present, or if the application has already
+                * restricted the allowed set to exclude any CPUs with FPUs,
+                * we'll skip the procedure.
+                */
+               if (cpus_intersects(current->cpus_allowed, mt_fpu_cpumask)) {
+                       cpumask_t tmask;
+
+                       cpus_and(tmask, current->thread.user_cpus_allowed,
+                                mt_fpu_cpumask);
+                       set_cpus_allowed(current, tmask);
+                       current->thread.mflags |= MF_FPUBOUND;
+               }
+       }
+#endif /* CONFIG_MIPS_MT_FPAFF */
+}
+
 asmlinkage void do_cpu(struct pt_regs *regs)
 {
        unsigned int cpid;
@@ -786,36 +813,8 @@ asmlinkage void do_cpu(struct pt_regs *regs)
                                                &current->thread.fpu, 0);
                        if (sig)
                                force_sig(sig, current);
-#ifdef CONFIG_MIPS_MT_FPAFF
-                       else {
-                       /*
-                        * MIPS MT processors may have fewer FPU contexts
-                        * than CPU threads. If we've emulated more than
-                        * some threshold number of instructions, force
-                        * migration to a "CPU" that has FP support.
-                        */
-                        if(mt_fpemul_threshold > 0
-                        && ((current->thread.emulated_fp++
-                           > mt_fpemul_threshold))) {
-                         /*
-                          * If there's no FPU present, or if the
-                          * application has already restricted
-                          * the allowed set to exclude any CPUs
-                          * with FPUs, we'll skip the procedure.
-                          */
-                         if (cpus_intersects(current->cpus_allowed,
-                                               mt_fpu_cpumask)) {
-                           cpumask_t tmask;
-
-                           cpus_and(tmask,
-                                       current->thread.user_cpus_allowed,
-                                       mt_fpu_cpumask);
-                           set_cpus_allowed(current, tmask);
-                           current->thread.mflags |= MF_FPUBOUND;
-                         }
-                        }
-                       }
-#endif /* CONFIG_MIPS_MT_FPAFF */
+                       else
+                               mt_ase_fp_affinity();
                }
 
                return;
@@ -835,6 +834,11 @@ asmlinkage void do_mdmx(struct pt_regs *regs)
 
 asmlinkage void do_watch(struct pt_regs *regs)
 {
+       if (board_watchpoint_handler) {
+               (*board_watchpoint_handler)(regs);
+               return;
+       }
+
        /*
         * We use the watch exception where available to detect stack
         * overflows.
@@ -861,7 +865,7 @@ asmlinkage void do_mcheck(struct pt_regs *regs)
                dump_tlb_all();
        }
 
-       show_code((unsigned int *) regs->cp0_epc);
+       show_code((unsigned int __user *) regs->cp0_epc);
 
        /*
         * Some chips may have other causes of machine check (e.g. SB1
@@ -1343,7 +1347,14 @@ void __init per_cpu_trap_init(void)
                set_c0_status(ST0_MX);
 
 #ifdef CONFIG_CPU_MIPSR2
-       write_c0_hwrena (0x0000000f); /* Allow rdhwr to all registers */
+       if (cpu_has_mips_r2) {
+               unsigned int enable = 0x0000000f;
+
+               if (cpu_has_userlocal)
+                       enable |= (1 << 29);
+
+               write_c0_hwrena(enable);
+       }
 #endif
 
 #ifdef CONFIG_MIPS_MT_SMTC
index 18c4a3c45a31c0df2da34693a349209e2b70cf22..8b9c34ffae184fecf7fe720eaa0b596305194fe9 100644 (file)
@@ -77,6 +77,7 @@
 #include <linux/signal.h>
 #include <linux/smp.h>
 #include <linux/sched.h>
+#include <linux/debugfs.h>
 #include <asm/asm.h>
 #include <asm/branch.h>
 #include <asm/byteorder.h>
 #define STR(x)  __STR(x)
 #define __STR(x)  #x
 
-#ifdef CONFIG_PROC_FS
-unsigned long unaligned_instructions;
+enum {
+       UNALIGNED_ACTION_QUIET,
+       UNALIGNED_ACTION_SIGNAL,
+       UNALIGNED_ACTION_SHOW,
+};
+#ifdef CONFIG_DEBUG_FS
+static u32 unaligned_instructions;
+static u32 unaligned_action;
+#else
+#define unaligned_action UNALIGNED_ACTION_QUIET
 #endif
+extern void show_registers(struct pt_regs *regs);
 
 static inline int emulate_load_store_insn(struct pt_regs *regs,
        void __user *addr, unsigned int __user *pc,
@@ -459,7 +469,7 @@ static inline int emulate_load_store_insn(struct pt_regs *regs,
                goto sigill;
        }
 
-#ifdef CONFIG_PROC_FS
+#ifdef CONFIG_DEBUG_FS
        unaligned_instructions++;
 #endif
 
@@ -516,6 +526,10 @@ asmlinkage void do_ade(struct pt_regs *regs)
        pc = (unsigned int __user *) exception_epc(regs);
        if (user_mode(regs) && (current->thread.mflags & MF_FIXADE) == 0)
                goto sigbus;
+       if (unaligned_action == UNALIGNED_ACTION_SIGNAL)
+               goto sigbus;
+       else if (unaligned_action == UNALIGNED_ACTION_SHOW)
+               show_registers(regs);
 
        /*
         * Do branch emulation only if we didn't forward the exception.
@@ -546,3 +560,24 @@ sigbus:
         * XXX On return from the signal handler we should advance the epc
         */
 }
+
+#ifdef CONFIG_DEBUG_FS
+extern struct dentry *mips_debugfs_dir;
+static int __init debugfs_unaligned(void)
+{
+       struct dentry *d;
+
+       if (!mips_debugfs_dir)
+               return -ENODEV;
+       d = debugfs_create_u32("unaligned_instructions", S_IRUGO,
+                              mips_debugfs_dir, &unaligned_instructions);
+       if (IS_ERR(d))
+               return PTR_ERR(d);
+       d = debugfs_create_u32("unaligned_action", S_IRUGO | S_IWUSR,
+                              mips_debugfs_dir, &unaligned_action);
+       if (IS_ERR(d))
+               return PTR_ERR(d);
+       return 0;
+}
+__initcall(debugfs_unaligned);
+#endif
diff --git a/arch/mips/lasat/Kconfig b/arch/mips/lasat/Kconfig
deleted file mode 100644 (file)
index 1d2ee8a..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-config PICVUE
-       tristate "PICVUE LCD display driver"
-       depends on LASAT
-
-config PICVUE_PROC
-       tristate "PICVUE LCD display driver /proc interface"
-       depends on PICVUE
-
-config DS1603
-       bool "DS1603 RTC driver"
-       depends on LASAT
-
-config LASAT_SYSCTL
-       bool "LASAT sysctl interface"
-       depends on LASAT
diff --git a/arch/mips/lasat/Makefile b/arch/mips/lasat/Makefile
deleted file mode 100644 (file)
index 99f5046..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#
-# Makefile for the LASAT specific kernel interface routines under Linux.
-#
-
-obj-y                          += reset.o setup.o prom.o lasat_board.o \
-                                  at93c.o interrupt.o
-
-obj-$(CONFIG_LASAT_SYSCTL)     += sysctl.o
-obj-$(CONFIG_DS1603)           += ds1603.o
-obj-$(CONFIG_PICVUE)           += picvue.o
-obj-$(CONFIG_PICVUE_PROC)      += picvue_proc.o
-
-clean:
-       make -C image clean
diff --git a/arch/mips/lasat/at93c.c b/arch/mips/lasat/at93c.c
deleted file mode 100644 (file)
index ca26e55..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Atmel AT93C46 serial eeprom driver
- *
- * Brian Murphy <brian.murphy@eicon.com>
- *
- */
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <asm/lasat/lasat.h>
-#include <linux/module.h>
-#include <linux/init.h>
-
-#include "at93c.h"
-
-#define AT93C_ADDR_SHIFT       7
-#define AT93C_ADDR_MAX         ((1 << AT93C_ADDR_SHIFT) - 1)
-#define AT93C_RCMD             (0x6 << AT93C_ADDR_SHIFT)
-#define AT93C_WCMD             (0x5 << AT93C_ADDR_SHIFT)
-#define AT93C_WENCMD           0x260
-#define AT93C_WDSCMD           0x200
-
-struct at93c_defs *at93c;
-
-static void at93c_reg_write(u32 val)
-{
-       *at93c->reg = val;
-}
-
-static u32 at93c_reg_read(void)
-{
-       u32 tmp = *at93c->reg;
-       return tmp;
-}
-
-static u32 at93c_datareg_read(void)
-{
-       u32 tmp = *at93c->rdata_reg;
-       return tmp;
-}
-
-static void at93c_cycle_clk(u32 data)
-{
-       at93c_reg_write(data | at93c->clk);
-       lasat_ndelay(250);
-       at93c_reg_write(data & ~at93c->clk);
-       lasat_ndelay(250);
-}
-
-static void at93c_write_databit(u8 bit)
-{
-       u32 data = at93c_reg_read();
-       if (bit)
-               data |= 1 << at93c->wdata_shift;
-       else
-               data &= ~(1 << at93c->wdata_shift);
-
-       at93c_reg_write(data);
-       lasat_ndelay(100);
-       at93c_cycle_clk(data);
-}
-
-static unsigned int at93c_read_databit(void)
-{
-       u32 data;
-
-       at93c_cycle_clk(at93c_reg_read());
-       data = (at93c_datareg_read() >> at93c->rdata_shift) & 1;
-       return data;
-}
-
-static u8 at93c_read_byte(void)
-{
-       int i;
-       u8 data = 0;
-
-       for (i = 0; i<=7; i++) {
-               data <<= 1;
-               data |= at93c_read_databit();
-       }
-       return data;
-}
-
-static void at93c_write_bits(u32 data, int size)
-{
-       int i;
-       int shift = size - 1;
-       u32 mask = (1 << shift);
-
-       for (i = 0; i < size; i++) {
-               at93c_write_databit((data & mask) >> shift);
-               data <<= 1;
-       }
-}
-
-static void at93c_init_op(void)
-{
-       at93c_reg_write((at93c_reg_read() | at93c->cs) & ~at93c->clk & ~(1 << at93c->rdata_shift));
-       lasat_ndelay(50);
-}
-
-static void at93c_end_op(void)
-{
-       at93c_reg_write(at93c_reg_read() & ~at93c->cs);
-       lasat_ndelay(250);
-}
-
-static void at93c_wait(void)
-{
-       at93c_init_op();
-       while (!at93c_read_databit())
-               ;
-       at93c_end_op();
-};
-
-static void at93c_disable_wp(void)
-{
-       at93c_init_op();
-       at93c_write_bits(AT93C_WENCMD, 10);
-       at93c_end_op();
-}
-
-static void at93c_enable_wp(void)
-{
-       at93c_init_op();
-       at93c_write_bits(AT93C_WDSCMD, 10);
-       at93c_end_op();
-}
-
-u8 at93c_read(u8 addr)
-{
-       u8 byte;
-       at93c_init_op();
-       at93c_write_bits((addr & AT93C_ADDR_MAX)|AT93C_RCMD, 10);
-       byte = at93c_read_byte();
-       at93c_end_op();
-       return byte;
-}
-
-void at93c_write(u8 addr, u8 data)
-{
-       at93c_disable_wp();
-       at93c_init_op();
-       at93c_write_bits((addr & AT93C_ADDR_MAX)|AT93C_WCMD, 10);
-       at93c_write_bits(data, 8);
-       at93c_end_op();
-       at93c_wait();
-       at93c_enable_wp();
-}
diff --git a/arch/mips/lasat/at93c.h b/arch/mips/lasat/at93c.h
deleted file mode 100644 (file)
index cfe2f99..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Atmel AT93C46 serial eeprom driver
- *
- * Brian Murphy <brian.murphy@eicon.com>
- *
- */
-
-extern struct at93c_defs {
-       volatile u32 *reg;
-       volatile u32 *rdata_reg;
-       int rdata_shift;
-       int wdata_shift;
-       u32 cs;
-       u32 clk;
-} *at93c;
-
-u8 at93c_read(u8 addr);
-void at93c_write(u8 addr, u8 data);
diff --git a/arch/mips/lasat/ds1603.c b/arch/mips/lasat/ds1603.c
deleted file mode 100644 (file)
index 7dced67..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Dallas Semiconductors 1603 RTC driver
- *
- * Brian Murphy <brian@murphy.dk>
- *
- */
-#include <linux/kernel.h>
-#include <asm/lasat/lasat.h>
-#include <linux/delay.h>
-#include <asm/lasat/ds1603.h>
-#include <asm/time.h>
-
-#include "ds1603.h"
-
-#define READ_TIME_CMD 0x81
-#define SET_TIME_CMD 0x80
-#define TRIMMER_SET_CMD 0xC0
-#define TRIMMER_VALUE_MASK 0x38
-#define TRIMMER_SHIFT 3
-
-struct ds_defs *ds1603 = NULL;
-
-/* HW specific register functions */
-static void rtc_reg_write(unsigned long val)
-{
-       *ds1603->reg = val;
-}
-
-static unsigned long rtc_reg_read(void)
-{
-       unsigned long tmp = *ds1603->reg;
-       return tmp;
-}
-
-static unsigned long rtc_datareg_read(void)
-{
-       unsigned long tmp = *ds1603->data_reg;
-       return tmp;
-}
-
-static void rtc_nrst_high(void)
-{
-       rtc_reg_write(rtc_reg_read() | ds1603->rst);
-}
-
-static void rtc_nrst_low(void)
-{
-       rtc_reg_write(rtc_reg_read() & ~ds1603->rst);
-}
-
-static void rtc_cycle_clock(unsigned long data)
-{
-       data |= ds1603->clk;
-       rtc_reg_write(data);
-       lasat_ndelay(250);
-       if (ds1603->data_reversed)
-               data &= ~ds1603->data;
-       else
-               data |= ds1603->data;
-       data &= ~ds1603->clk;
-       rtc_reg_write(data);
-       lasat_ndelay(250 + ds1603->huge_delay);
-}
-
-static void rtc_write_databit(unsigned int bit)
-{
-       unsigned long data = rtc_reg_read();
-       if (ds1603->data_reversed)
-               bit = !bit;
-       if (bit)
-               data |= ds1603->data;
-       else
-               data &= ~ds1603->data;
-
-       rtc_reg_write(data);
-       lasat_ndelay(50 + ds1603->huge_delay);
-       rtc_cycle_clock(data);
-}
-
-static unsigned int rtc_read_databit(void)
-{
-       unsigned int data;
-
-       data = (rtc_datareg_read() & (1 << ds1603->data_read_shift))
-               >> ds1603->data_read_shift;
-       rtc_cycle_clock(rtc_reg_read());
-       return data;
-}
-
-static void rtc_write_byte(unsigned int byte)
-{
-       int i;
-
-       for (i = 0; i<=7; i++) {
-               rtc_write_databit(byte & 1L);
-               byte >>= 1;
-       }
-}
-
-static void rtc_write_word(unsigned long word)
-{
-       int i;
-
-       for (i = 0; i<=31; i++) {
-               rtc_write_databit(word & 1L);
-               word >>= 1;
-       }
-}
-
-static unsigned long rtc_read_word(void)
-{
-       int i;
-       unsigned long word = 0;
-       unsigned long shift = 0;
-
-       for (i = 0; i<=31; i++) {
-               word |= rtc_read_databit() << shift;
-               shift++;
-       }
-       return word;
-}
-
-static void rtc_init_op(void)
-{
-       rtc_nrst_high();
-
-       rtc_reg_write(rtc_reg_read() & ~ds1603->clk);
-
-       lasat_ndelay(50);
-}
-
-static void rtc_end_op(void)
-{
-       rtc_nrst_low();
-       lasat_ndelay(1000);
-}
-
-/* interface */
-unsigned long ds1603_read(void)
-{
-       unsigned long word;
-       unsigned long flags;
-
-       spin_lock_irqsave(&rtc_lock, flags);
-       rtc_init_op();
-       rtc_write_byte(READ_TIME_CMD);
-       word = rtc_read_word();
-       rtc_end_op();
-       spin_unlock_irqrestore(&rtc_lock, flags);
-       return word;
-}
-
-int ds1603_set(unsigned long time)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&rtc_lock, flags);
-       rtc_init_op();
-       rtc_write_byte(SET_TIME_CMD);
-       rtc_write_word(time);
-       rtc_end_op();
-       spin_unlock_irqrestore(&rtc_lock, flags);
-
-       return 0;
-}
-
-void ds1603_set_trimmer(unsigned int trimval)
-{
-       rtc_init_op();
-       rtc_write_byte(((trimval << TRIMMER_SHIFT) & TRIMMER_VALUE_MASK)
-                       | (TRIMMER_SET_CMD));
-       rtc_end_op();
-}
-
-void ds1603_disable(void)
-{
-       ds1603_set_trimmer(TRIMMER_DISABLE_RTC);
-}
-
-void ds1603_enable(void)
-{
-       ds1603_set_trimmer(TRIMMER_DEFAULT);
-}
diff --git a/arch/mips/lasat/ds1603.h b/arch/mips/lasat/ds1603.h
deleted file mode 100644 (file)
index c2e5c76..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Dallas Semiconductors 1603 RTC driver
- *
- * Brian Murphy <brian@murphy.dk>
- *
- */
-#ifndef __DS1603_H
-#define __DS1603_H
-
-struct ds_defs {
-       volatile u32 *reg;
-       volatile u32 *data_reg;
-       u32 rst;
-       u32 clk;
-       u32 data;
-       u32 data_read_shift;
-       char data_reversed;
-       u32 huge_delay;
-};
-
-extern struct ds_defs *ds1603;
-
-unsigned long ds1603_read(void);
-int ds1603_set(unsigned long);
-void ds1603_set_trimmer(unsigned int);
-void ds1603_enable(void);
-void ds1603_disable(void);
-void ds1603_init(struct ds_defs *);
-
-#define TRIMMER_DEFAULT        3
-#define TRIMMER_DISABLE_RTC 0
-
-#endif
diff --git a/arch/mips/lasat/image/Makefile b/arch/mips/lasat/image/Makefile
deleted file mode 100644 (file)
index 35ecd64..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-#
-# MAKEFILE FOR THE MIPS LINUX BOOTLOADER AND ROM DEBUGGER
-#
-# i-data Networks
-#
-# Author: Thomas Horsten <thh@i-data.com>
-#
-
-ifndef Version
- Version = "$(USER)-test"
-endif
-
-MKLASATIMG = mklasatimg
-MKLASATIMG_ARCH = mq2,mqpro,sp100,sp200
-KERNEL_IMAGE = $(TOPDIR)/vmlinux
-KERNEL_START = $(shell $(NM) $(KERNEL_IMAGE) | grep " _text" | cut -f1 -d\ )
-KERNEL_ENTRY = $(shell $(NM) $(KERNEL_IMAGE) | grep kernel_entry | cut -f1 -d\ )
-
-LDSCRIPT= -L$(obj) -Tromscript.normal
-
-HEAD_DEFINES := -D_kernel_start=0x$(KERNEL_START) \
-               -D_kernel_entry=0x$(KERNEL_ENTRY) \
-               -D VERSION="\"$(Version)\"" \
-               -D TIMESTAMP=$(shell date +%s)
-
-$(obj)/head.o: $(obj)/head.S $(KERNEL_IMAGE)
-       $(CC) -fno-pic $(HEAD_DEFINES) -I$(TOPDIR)/include -c -o $@ $<
-
-OBJECTS = head.o kImage.o
-
-rom.sw:        $(obj)/rom.sw
-
-$(obj)/rom.sw: $(obj)/rom.bin
-       $(MKLASATIMG) -o $@ -k $^ -m $(MKLASATIMG_ARCH)
-
-$(obj)/rom.bin: $(obj)/rom
-       $(OBJCOPY) -O binary -S $^ $@
-
-# Rule to make the bootloader
-$(obj)/rom: $(addprefix $(obj)/,$(OBJECTS))
-       $(LD) $(LDFLAGS) $(LDSCRIPT) -o $@ $^
-
-$(obj)/%.o: $(obj)/%.gz
-       $(LD) -r -o $@ -b binary $<
-
-$(obj)/%.gz: $(obj)/%.bin
-       gzip -cf -9 $< > $@
-
-$(obj)/kImage.bin: $(KERNEL_IMAGE)
-       $(OBJCOPY) -O binary -S $^ $@
-
-clean:
-       rm -f rom rom.bin rom.sw kImage.bin kImage.o
diff --git a/arch/mips/lasat/image/head.S b/arch/mips/lasat/image/head.S
deleted file mode 100644 (file)
index efb95f2..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-#include <asm/lasat/head.h>
-
-       .text
-       .section .text.start, "ax"
-       .set noreorder
-       .set mips3
-
-       /* Magic words identifying a software image */
-       .word   LASAT_K_MAGIC0_VAL
-       .word   LASAT_K_MAGIC1_VAL
-
-       /* Image header version */
-       .word   0x00000002
-
-       /* image start and size */
-       .word   _image_start
-       .word   _image_size
-
-       /* start of kernel and entrypoint in uncompressed image */
-       .word   _kernel_start
-       .word   _kernel_entry
-
-       /* Here we have room for future flags */
-
-       .org    0x40
-reldate:
-       .word   TIMESTAMP
-
-       .org    0x50
-release:
-       .string VERSION
diff --git a/arch/mips/lasat/image/romscript.normal b/arch/mips/lasat/image/romscript.normal
deleted file mode 100644 (file)
index 988f8ad..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-OUTPUT_ARCH(mips)
-
-SECTIONS
-{
-  .text :
-  {
-    *(.text.start)
-  }
-
-  /* Data in ROM */
-
-  .data ALIGN(0x10) :
-  {
-    *(.data)
-  }
-  _image_start = ADDR(.data);
-  _image_size = SIZEOF(.data);
-
-  .other :
-  {
-    *(.*)
-  }
-}
diff --git a/arch/mips/lasat/interrupt.c b/arch/mips/lasat/interrupt.c
deleted file mode 100644 (file)
index 9a622b9..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You 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.
- *
- * Routines for generic manipulation of the interrupts found on the
- * Lasat boards.
- */
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/kernel_stat.h>
-
-#include <asm/bootinfo.h>
-#include <asm/irq.h>
-#include <asm/lasat/lasatint.h>
-#include <asm/time.h>
-#include <asm/gdb-stub.h>
-
-static volatile int *lasat_int_status = NULL;
-static volatile int *lasat_int_mask = NULL;
-static volatile int lasat_int_mask_shift;
-
-void disable_lasat_irq(unsigned int irq_nr)
-{
-       *lasat_int_mask &= ~(1 << irq_nr) << lasat_int_mask_shift;
-}
-
-void enable_lasat_irq(unsigned int irq_nr)
-{
-       *lasat_int_mask |= (1 << irq_nr) << lasat_int_mask_shift;
-}
-
-static struct irq_chip lasat_irq_type = {
-       .name = "Lasat",
-       .ack = disable_lasat_irq,
-       .mask = disable_lasat_irq,
-       .mask_ack = disable_lasat_irq,
-       .unmask = enable_lasat_irq,
-};
-
-static inline int ls1bit32(unsigned int x)
-{
-       int b = 31, s;
-
-       s = 16; if (x << 16 == 0) s = 0; b -= s; x <<= s;
-       s =  8; if (x <<  8 == 0) s = 0; b -= s; x <<= s;
-       s =  4; if (x <<  4 == 0) s = 0; b -= s; x <<= s;
-       s =  2; if (x <<  2 == 0) s = 0; b -= s; x <<= s;
-       s =  1; if (x <<  1 == 0) s = 0; b -= s;
-
-       return b;
-}
-
-static unsigned long (* get_int_status)(void);
-
-static unsigned long get_int_status_100(void)
-{
-       return *lasat_int_status & *lasat_int_mask;
-}
-
-static unsigned long get_int_status_200(void)
-{
-       unsigned long int_status;
-
-       int_status = *lasat_int_status;
-       int_status &= (int_status >> LASATINT_MASK_SHIFT_200) & 0xffff;
-       return int_status;
-}
-
-asmlinkage void plat_irq_dispatch(void)
-{
-       unsigned long int_status;
-       unsigned int cause = read_c0_cause();
-       int irq;
-
-       if (cause & CAUSEF_IP7) {       /* R4000 count / compare IRQ */
-               ll_timer_interrupt(7);
-               return;
-       }
-
-       int_status = get_int_status();
-
-       /* if int_status == 0, then the interrupt has already been cleared */
-       if (int_status) {
-               irq = ls1bit32(int_status);
-
-               do_IRQ(irq);
-       }
-}
-
-void __init arch_init_irq(void)
-{
-       int i;
-
-       switch (mips_machtype) {
-       case MACH_LASAT_100:
-               lasat_int_status = (void *)LASAT_INT_STATUS_REG_100;
-               lasat_int_mask = (void *)LASAT_INT_MASK_REG_100;
-               lasat_int_mask_shift = LASATINT_MASK_SHIFT_100;
-               get_int_status = get_int_status_100;
-               *lasat_int_mask = 0;
-               break;
-       case MACH_LASAT_200:
-               lasat_int_status = (void *)LASAT_INT_STATUS_REG_200;
-               lasat_int_mask = (void *)LASAT_INT_MASK_REG_200;
-               lasat_int_mask_shift = LASATINT_MASK_SHIFT_200;
-               get_int_status = get_int_status_200;
-               *lasat_int_mask &= 0xffff;
-               break;
-       default:
-               panic("arch_init_irq: mips_machtype incorrect");
-       }
-
-       for (i = 0; i <= LASATINT_END; i++)
-               set_irq_chip_and_handler(i, &lasat_irq_type, handle_level_irq);
-}
diff --git a/arch/mips/lasat/lasat_board.c b/arch/mips/lasat/lasat_board.c
deleted file mode 100644 (file)
index fbe9a87..0000000
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Thomas Horsten <thh@lasat.com>
- * Copyright (C) 2000 LASAT Networks A/S.
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You 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.
- *
- * Routines specific to the LASAT boards
- */
-#include <linux/types.h>
-#include <linux/crc32.h>
-#include <asm/lasat/lasat.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/ctype.h>
-#include <asm/bootinfo.h>
-#include <asm/addrspace.h>
-#include "at93c.h"
-/* New model description table */
-#include "lasat_models.h"
-
-#define EEPROM_CRC(data, len) (~0 ^ crc32(~0, data, len))
-
-struct lasat_info lasat_board_info;
-
-void update_bcastaddr(void);
-
-int EEPROMRead(unsigned int pos, unsigned char *data, int len)
-{
-       int i;
-
-       for (i=0; i<len; i++)
-               *data++ = at93c_read(pos++);
-
-       return 0;
-}
-int EEPROMWrite(unsigned int pos, unsigned char *data, int len)
-{
-       int i;
-
-       for (i=0; i<len; i++)
-               at93c_write(pos++, *data++);
-
-       return 0;
-}
-
-static void init_flash_sizes(void)
-{
-       int i;
-       unsigned long *lb = lasat_board_info.li_flashpart_base;
-       unsigned long *ls = lasat_board_info.li_flashpart_size;
-
-       ls[LASAT_MTD_BOOTLOADER] = 0x40000;
-       ls[LASAT_MTD_SERVICE] = 0xC0000;
-       ls[LASAT_MTD_NORMAL] = 0x100000;
-
-       if (mips_machtype == MACH_LASAT_100) {
-               lasat_board_info.li_flash_base = 0x1e000000;
-
-               lb[LASAT_MTD_BOOTLOADER] = 0x1e400000;
-
-               if (lasat_board_info.li_flash_size > 0x200000) {
-                       ls[LASAT_MTD_CONFIG] = 0x100000;
-                       ls[LASAT_MTD_FS] = 0x500000;
-               }
-       } else {
-               lasat_board_info.li_flash_base = 0x10000000;
-
-               if (lasat_board_info.li_flash_size < 0x1000000) {
-                       lb[LASAT_MTD_BOOTLOADER] = 0x10000000;
-                       ls[LASAT_MTD_CONFIG] = 0x100000;
-                       if (lasat_board_info.li_flash_size >= 0x400000) {
-                               ls[LASAT_MTD_FS] = lasat_board_info.li_flash_size - 0x300000;
-                       }
-               }
-       }
-
-       for (i = 1; i < LASAT_MTD_LAST; i++)
-               lb[i] = lb[i-1] + ls[i-1];
-}
-
-int lasat_init_board_info(void)
-{
-       int c;
-       unsigned long crc;
-       unsigned long cfg0, cfg1;
-       const product_info_t   *ppi;
-       int i_n_base_models = N_BASE_MODELS;
-       const char * const * i_txt_base_models = txt_base_models;
-       int i_n_prids = N_PRIDS;
-
-       memset(&lasat_board_info, 0, sizeof(lasat_board_info));
-
-       /* First read the EEPROM info */
-       EEPROMRead(0, (unsigned char *)&lasat_board_info.li_eeprom_info,
-                  sizeof(struct lasat_eeprom_struct));
-
-       /* Check the CRC */
-       crc = EEPROM_CRC((unsigned char *)(&lasat_board_info.li_eeprom_info),
-                   sizeof(struct lasat_eeprom_struct) - 4);
-
-       if (crc != lasat_board_info.li_eeprom_info.crc32) {
-               printk(KERN_WARNING "WARNING...\nWARNING...\nEEPROM CRC does "
-                      "not match calculated, attempting to soldier on...\n");
-       }
-
-       if (lasat_board_info.li_eeprom_info.version != LASAT_EEPROM_VERSION) {
-               printk(KERN_WARNING "WARNING...\nWARNING...\nEEPROM version "
-                      "%d, wanted version %d, attempting to soldier on...\n",
-                      (unsigned int)lasat_board_info.li_eeprom_info.version,
-                      LASAT_EEPROM_VERSION);
-       }
-
-       cfg0 = lasat_board_info.li_eeprom_info.cfg[0];
-       cfg1 = lasat_board_info.li_eeprom_info.cfg[1];
-
-       if ( LASAT_W0_DSCTYPE(cfg0) != 1) {
-               printk(KERN_WARNING "WARNING...\nWARNING...\n"
-                      "Invalid configuration read from EEPROM, attempting to "
-                      "soldier on...");
-       }
-       /* We have a valid configuration */
-
-       switch (LASAT_W0_SDRAMBANKSZ(cfg0)) {
-       case 0:
-               lasat_board_info.li_memsize = 0x0800000;
-               break;
-       case 1:
-               lasat_board_info.li_memsize = 0x1000000;
-               break;
-       case 2:
-               lasat_board_info.li_memsize = 0x2000000;
-               break;
-       case 3:
-               lasat_board_info.li_memsize = 0x4000000;
-               break;
-       case 4:
-               lasat_board_info.li_memsize = 0x8000000;
-               break;
-       default:
-               lasat_board_info.li_memsize = 0;
-       }
-
-       switch (LASAT_W0_SDRAMBANKS(cfg0)) {
-       case 0:
-               break;
-       case 1:
-               lasat_board_info.li_memsize *= 2;
-               break;
-       default:
-               break;
-       }
-
-       switch (LASAT_W0_BUSSPEED(cfg0)) {
-       case 0x0:
-               lasat_board_info.li_bus_hz = 60000000;
-               break;
-       case 0x1:
-               lasat_board_info.li_bus_hz = 66000000;
-               break;
-       case 0x2:
-               lasat_board_info.li_bus_hz = 66666667;
-               break;
-       case 0x3:
-               lasat_board_info.li_bus_hz = 80000000;
-               break;
-       case 0x4:
-               lasat_board_info.li_bus_hz = 83333333;
-               break;
-       case 0x5:
-               lasat_board_info.li_bus_hz = 100000000;
-               break;
-       }
-
-       switch (LASAT_W0_CPUCLK(cfg0)) {
-       case 0x0:
-               lasat_board_info.li_cpu_hz =
-                       lasat_board_info.li_bus_hz;
-               break;
-       case 0x1:
-               lasat_board_info.li_cpu_hz =
-                       lasat_board_info.li_bus_hz +
-                       (lasat_board_info.li_bus_hz >> 1);
-               break;
-       case 0x2:
-               lasat_board_info.li_cpu_hz =
-                       lasat_board_info.li_bus_hz +
-                       lasat_board_info.li_bus_hz;
-               break;
-       case 0x3:
-               lasat_board_info.li_cpu_hz =
-                       lasat_board_info.li_bus_hz +
-                       lasat_board_info.li_bus_hz +
-                       (lasat_board_info.li_bus_hz >> 1);
-               break;
-       case 0x4:
-               lasat_board_info.li_cpu_hz =
-                       lasat_board_info.li_bus_hz +
-                       lasat_board_info.li_bus_hz +
-                       lasat_board_info.li_bus_hz;
-               break;
-       }
-
-       /* Flash size */
-       switch (LASAT_W1_FLASHSIZE(cfg1)) {
-       case 0:
-               lasat_board_info.li_flash_size = 0x200000;
-               break;
-       case 1:
-               lasat_board_info.li_flash_size = 0x400000;
-               break;
-       case 2:
-               lasat_board_info.li_flash_size = 0x800000;
-               break;
-       case 3:
-               lasat_board_info.li_flash_size = 0x1000000;
-               break;
-       case 4:
-               lasat_board_info.li_flash_size = 0x2000000;
-               break;
-       }
-
-       init_flash_sizes();
-
-       lasat_board_info.li_bmid = LASAT_W0_BMID(cfg0);
-       lasat_board_info.li_prid = lasat_board_info.li_eeprom_info.prid;
-       if (lasat_board_info.li_prid == 0xffff || lasat_board_info.li_prid == 0)
-               lasat_board_info.li_prid = lasat_board_info.li_bmid;
-
-       /* Base model stuff */
-       if (lasat_board_info.li_bmid > i_n_base_models)
-               lasat_board_info.li_bmid = i_n_base_models;
-       strcpy(lasat_board_info.li_bmstr, i_txt_base_models[lasat_board_info.li_bmid]);
-
-       /* Product ID dependent values */
-       c = lasat_board_info.li_prid;
-       if (c >= i_n_prids) {
-               strcpy(lasat_board_info.li_namestr, "Unknown Model");
-               strcpy(lasat_board_info.li_typestr, "Unknown Type");
-       } else {
-               ppi = &vendor_info_table[0].vi_product_info[c];
-               strcpy(lasat_board_info.li_namestr, ppi->pi_name);
-               if (ppi->pi_type)
-                       strcpy(lasat_board_info.li_typestr, ppi->pi_type);
-               else
-                       sprintf(lasat_board_info.li_typestr, "%d",10*c);
-       }
-
-#if defined(CONFIG_INET) && defined(CONFIG_SYSCTL)
-       update_bcastaddr();
-#endif
-
-       return 0;
-}
-
-void lasat_write_eeprom_info(void)
-{
-       unsigned long crc;
-
-       /* Generate the CRC */
-       crc = EEPROM_CRC((unsigned char *)(&lasat_board_info.li_eeprom_info),
-                   sizeof(struct lasat_eeprom_struct) - 4);
-       lasat_board_info.li_eeprom_info.crc32 = crc;
-
-       /* Write the EEPROM info */
-       EEPROMWrite(0, (unsigned char *)&lasat_board_info.li_eeprom_info,
-                   sizeof(struct lasat_eeprom_struct));
-}
-
diff --git a/arch/mips/lasat/lasat_models.h b/arch/mips/lasat/lasat_models.h
deleted file mode 100644 (file)
index ae0c5d0..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Model description tables
- */
-
-typedef struct product_info_t {
-       const char     *pi_name;
-       const char     *pi_type;
-} product_info_t;
-
-typedef struct vendor_info_t {
-       const char     *vi_name;
-       const product_info_t *vi_product_info;
-} vendor_info_t;
-
-/*
- * Base models
- */
-static const char * const txt_base_models[] = {
-  "MQ 2", "MQ Pro", "SP 25", "SP 50", "SP 100", "SP 5000", "SP 7000", "SP 1000", "Unknown"
-};
-#define N_BASE_MODELS (sizeof(txt_base_models)/sizeof(char*)-1)
-
-/*
- * Eicon Networks
- */
-static const char txt_en_mq[] = "Masquerade";
-static const char txt_en_sp[] = "Safepipe";
-
-static const product_info_t product_info_eicon[] = {
-  { txt_en_mq, "II"   }, /*  0 */
-  { txt_en_mq, "Pro"  }, /*  1 */
-  { txt_en_sp, "25"   }, /*  2 */
-  { txt_en_sp, "50"   }, /*  3 */
-  { txt_en_sp, "100"  }, /*  4 */
-  { txt_en_sp, "5000" }, /*  5 */
-  { txt_en_sp, "7000" }, /*  6 */
-  { txt_en_sp, "30"   }, /*  7 */
-  { txt_en_sp, "5100" }, /*  8 */
-  { txt_en_sp, "7100" }, /*  9 */
-  { txt_en_sp, "1110" }, /* 10 */
-  { txt_en_sp, "3020" }, /* 11 */
-  { txt_en_sp, "3030" }, /* 12 */
-  { txt_en_sp, "5020" }, /* 13 */
-  { txt_en_sp, "5030" }, /* 14 */
-  { txt_en_sp, "1120" }, /* 15 */
-  { txt_en_sp, "1130" }, /* 16 */
-  { txt_en_sp, "6010" }, /* 17 */
-  { txt_en_sp, "6110" }, /* 18 */
-  { txt_en_sp, "6210" }, /* 19 */
-  { txt_en_sp, "1020" }, /* 20 */
-  { txt_en_sp, "1040" }, /* 21 */
-  { txt_en_sp, "1050" }, /* 22 */
-  { txt_en_sp, "1060" }, /* 23 */
-};
-#define N_PRIDS (sizeof(product_info_eicon)/sizeof(product_info_t))
-
-/*
- * The vendor table
- */
-static vendor_info_t const vendor_info_table[] = {
-  { "Eicon Networks",  product_info_eicon   },
-};
-#define N_VENDORS (sizeof(vendor_info_table)/sizeof(vendor_info_t))
diff --git a/arch/mips/lasat/picvue.c b/arch/mips/lasat/picvue.c
deleted file mode 100644 (file)
index 9ae82c3..0000000
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Picvue PVC160206 display driver
- *
- * Brian Murphy <brian@murphy.dk>
- *
- */
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <asm/bootinfo.h>
-#include <asm/lasat/lasat.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-
-#include "picvue.h"
-
-#define PVC_BUSY               0x80
-#define PVC_NLINES             2
-#define PVC_DISPMEM            80
-#define PVC_LINELEN            PVC_DISPMEM / PVC_NLINES
-
-struct pvc_defs *picvue = NULL;
-
-DECLARE_MUTEX(pvc_sem);
-
-static void pvc_reg_write(u32 val)
-{
-       *picvue->reg = val;
-}
-
-static u32 pvc_reg_read(void)
-{
-       u32 tmp = *picvue->reg;
-       return tmp;
-}
-
-static void pvc_write_byte(u32 data, u8 byte)
-{
-       data |= picvue->e;
-       pvc_reg_write(data);
-       data &= ~picvue->data_mask;
-       data |= byte << picvue->data_shift;
-       pvc_reg_write(data);
-       ndelay(220);
-       pvc_reg_write(data & ~picvue->e);
-       ndelay(220);
-}
-
-static u8 pvc_read_byte(u32 data)
-{
-       u8 byte;
-
-       data |= picvue->e;
-       pvc_reg_write(data);
-       ndelay(220);
-       byte = (pvc_reg_read() & picvue->data_mask) >> picvue->data_shift;
-       data &= ~picvue->e;
-       pvc_reg_write(data);
-       ndelay(220);
-       return byte;
-}
-
-static u8 pvc_read_data(void)
-{
-       u32 data = pvc_reg_read();
-       u8 byte;
-       data |= picvue->rw;
-       data &= ~picvue->rs;
-       pvc_reg_write(data);
-       ndelay(40);
-       byte = pvc_read_byte(data);
-       data |= picvue->rs;
-       pvc_reg_write(data);
-       return byte;
-}
-
-#define TIMEOUT 1000
-static int pvc_wait(void)
-{
-       int i = TIMEOUT;
-       int err = 0;
-
-       while ((pvc_read_data() & PVC_BUSY) && i)
-               i--;
-       if (i == 0)
-               err = -ETIME;
-
-       return err;
-}
-
-#define MODE_INST 0
-#define MODE_DATA 1
-static void pvc_write(u8 byte, int mode)
-{
-       u32 data = pvc_reg_read();
-       data &= ~picvue->rw;
-       if (mode == MODE_DATA)
-               data |= picvue->rs;
-       else
-               data &= ~picvue->rs;
-       pvc_reg_write(data);
-       ndelay(40);
-       pvc_write_byte(data, byte);
-       if (mode == MODE_DATA)
-               data &= ~picvue->rs;
-       else
-               data |= picvue->rs;
-       pvc_reg_write(data);
-       pvc_wait();
-}
-
-void pvc_write_string(const unsigned char *str, u8 addr, int line)
-{
-       int i = 0;
-
-       if (line > 0 && (PVC_NLINES > 1))
-               addr += 0x40 * line;
-       pvc_write(0x80 | addr, MODE_INST);
-
-       while (*str != 0 && i < PVC_LINELEN) {
-               pvc_write(*str++, MODE_DATA);
-               i++;
-       }
-}
-
-void pvc_write_string_centered(const unsigned char *str, int line)
-{
-       int len = strlen(str);
-       u8 addr;
-
-       if (len > PVC_VISIBLE_CHARS)
-               addr = 0;
-       else
-               addr = (PVC_VISIBLE_CHARS - strlen(str))/2;
-
-       pvc_write_string(str, addr, line);
-}
-
-void pvc_dump_string(const unsigned char *str)
-{
-       int len = strlen(str);
-
-       pvc_write_string(str, 0, 0);
-       if (len > PVC_VISIBLE_CHARS)
-               pvc_write_string(&str[PVC_VISIBLE_CHARS], 0, 1);
-}
-
-#define BM_SIZE                        8
-#define MAX_PROGRAMMABLE_CHARS 8
-int pvc_program_cg(int charnum, u8 bitmap[BM_SIZE])
-{
-       int i;
-       int addr;
-
-       if (charnum > MAX_PROGRAMMABLE_CHARS)
-               return -ENOENT;
-
-       addr = charnum * 8;
-       pvc_write(0x40 | addr, MODE_INST);
-
-       for (i=0; i<BM_SIZE; i++)
-               pvc_write(bitmap[i], MODE_DATA);
-       return 0;
-}
-
-#define FUNC_SET_CMD   0x20
-#define  EIGHT_BYTE    (1 << 4)
-#define  FOUR_BYTE     0
-#define  TWO_LINES     (1 << 3)
-#define  ONE_LINE      0
-#define  LARGE_FONT    (1 << 2)
-#define  SMALL_FONT    0
-static void pvc_funcset(u8 cmd)
-{
-       pvc_write(FUNC_SET_CMD | (cmd & (EIGHT_BYTE|TWO_LINES|LARGE_FONT)), MODE_INST);
-}
-
-#define ENTRYMODE_CMD          0x4
-#define  AUTO_INC              (1 << 1)
-#define  AUTO_DEC              0
-#define  CURSOR_FOLLOWS_DISP   (1 << 0)
-static void pvc_entrymode(u8 cmd)
-{
-       pvc_write(ENTRYMODE_CMD | (cmd & (AUTO_INC|CURSOR_FOLLOWS_DISP)), MODE_INST);
-}
-
-#define DISP_CNT_CMD   0x08
-#define  DISP_OFF      0
-#define  DISP_ON       (1 << 2)
-#define  CUR_ON                (1 << 1)
-#define  CUR_BLINK     (1 << 0)
-void pvc_dispcnt(u8 cmd)
-{
-       pvc_write(DISP_CNT_CMD | (cmd & (DISP_ON|CUR_ON|CUR_BLINK)), MODE_INST);
-}
-
-#define MOVE_CMD       0x10
-#define  DISPLAY       (1 << 3)
-#define  CURSOR                0
-#define  RIGHT         (1 << 2)
-#define  LEFT          0
-void pvc_move(u8 cmd)
-{
-       pvc_write(MOVE_CMD | (cmd & (DISPLAY|RIGHT)), MODE_INST);
-}
-
-#define CLEAR_CMD      0x1
-void pvc_clear(void)
-{
-       pvc_write(CLEAR_CMD, MODE_INST);
-}
-
-#define HOME_CMD       0x2
-void pvc_home(void)
-{
-       pvc_write(HOME_CMD, MODE_INST);
-}
-
-int pvc_init(void)
-{
-       u8 cmd = EIGHT_BYTE;
-
-       if (PVC_NLINES == 2)
-               cmd |= (SMALL_FONT|TWO_LINES);
-       else
-               cmd |= (LARGE_FONT|ONE_LINE);
-       pvc_funcset(cmd);
-       pvc_dispcnt(DISP_ON);
-       pvc_entrymode(AUTO_INC);
-
-       pvc_clear();
-       pvc_write_string_centered("Display", 0);
-       pvc_write_string_centered("Initialized", 1);
-
-       return 0;
-}
-
-module_init(pvc_init);
-MODULE_LICENSE("GPL");
diff --git a/arch/mips/lasat/picvue.h b/arch/mips/lasat/picvue.h
deleted file mode 100644 (file)
index 2a96bf9..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Picvue PVC160206 display driver
- *
- * Brian Murphy <brian.murphy@eicon.com>
- *
- */
-#include <asm/semaphore.h>
-
-struct pvc_defs {
-       volatile u32 *reg;
-       u32 data_shift;
-       u32 data_mask;
-       u32 e;
-       u32 rw;
-       u32 rs;
-};
-
-extern struct pvc_defs *picvue;
-
-#define PVC_NLINES             2
-#define PVC_DISPMEM            80
-#define PVC_LINELEN            PVC_DISPMEM / PVC_NLINES
-#define PVC_VISIBLE_CHARS      16
-
-void pvc_write_string(const unsigned char *str, u8 addr, int line);
-void pvc_write_string_centered(const unsigned char *str, int line);
-void pvc_dump_string(const unsigned char *str);
-
-#define BM_SIZE                        8
-#define MAX_PROGRAMMABLE_CHARS 8
-int pvc_program_cg(int charnum, u8 bitmap[BM_SIZE]);
-
-void pvc_dispcnt(u8 cmd);
-#define  DISP_OFF      0
-#define  DISP_ON       (1 << 2)
-#define  CUR_ON                (1 << 1)
-#define  CUR_BLINK     (1 << 0)
-
-void pvc_move(u8 cmd);
-#define  DISPLAY       (1 << 3)
-#define  CURSOR                0
-#define  RIGHT         (1 << 2)
-#define  LEFT          0
-
-void pvc_clear(void);
-void pvc_home(void);
-
-extern struct semaphore pvc_sem;
diff --git a/arch/mips/lasat/picvue_proc.c b/arch/mips/lasat/picvue_proc.c
deleted file mode 100644 (file)
index cce7cdd..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Picvue PVC160206 display driver
- *
- * Brian Murphy <brian.murphy@eicon.com>
- *
- */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-
-#include <linux/proc_fs.h>
-#include <linux/interrupt.h>
-
-#include <linux/timer.h>
-
-#include "picvue.h"
-
-static char pvc_lines[PVC_NLINES][PVC_LINELEN+1];
-static int pvc_linedata[PVC_NLINES];
-static struct proc_dir_entry *pvc_display_dir;
-static char *pvc_linename[PVC_NLINES] = {"line1", "line2"};
-#define DISPLAY_DIR_NAME "display"
-static int scroll_dir = 0, scroll_interval = 0;
-
-static struct timer_list timer;
-
-static void pvc_display(unsigned long data) {
-       int i;
-
-       pvc_clear();
-       for (i=0; i<PVC_NLINES; i++)
-               pvc_write_string(pvc_lines[i], 0, i);
-}
-
-static DECLARE_TASKLET(pvc_display_tasklet, &pvc_display, 0);
-
-static int pvc_proc_read_line(char *page, char **start,
-                             off_t off, int count,
-                             int *eof, void *data)
-{
-        char *origpage = page;
-       int lineno = *(int *)data;
-
-       if (lineno < 0 || lineno > PVC_NLINES) {
-               printk("proc_read_line: invalid lineno %d\n", lineno);
-               return 0;
-       }
-
-       down(&pvc_sem);
-        page += sprintf(page, "%s\n", pvc_lines[lineno]);
-       up(&pvc_sem);
-
-        return page - origpage;
-}
-
-static int pvc_proc_write_line(struct file *file, const char *buffer,
-                           unsigned long count, void *data)
-{
-        int origcount = count;
-       int lineno = *(int *)data;
-
-       if (lineno < 0 || lineno > PVC_NLINES) {
-               printk("proc_write_line: invalid lineno %d\n", lineno);
-               return origcount;
-       }
-
-       if (count > PVC_LINELEN)
-               count = PVC_LINELEN;
-
-       if (buffer[count-1] == '\n')
-               count--;
-
-       down(&pvc_sem);
-       strncpy(pvc_lines[lineno], buffer, count);
-       pvc_lines[lineno][count] = '\0';
-       up(&pvc_sem);
-
-       tasklet_schedule(&pvc_display_tasklet);
-
-        return origcount;
-}
-
-static int pvc_proc_write_scroll(struct file *file, const char *buffer,
-                           unsigned long count, void *data)
-{
-        int origcount = count;
-       int cmd = simple_strtol(buffer, NULL, 10);
-
-       down(&pvc_sem);
-       if (scroll_interval != 0)
-               del_timer(&timer);
-
-       if (cmd == 0) {
-               scroll_dir = 0;
-               scroll_interval = 0;
-       } else {
-               if (cmd < 0) {
-                       scroll_dir = -1;
-                       scroll_interval = -cmd;
-               } else {
-                       scroll_dir = 1;
-                       scroll_interval = cmd;
-               }
-               add_timer(&timer);
-       }
-       up(&pvc_sem);
-
-        return origcount;
-}
-
-static int pvc_proc_read_scroll(char *page, char **start,
-                             off_t off, int count,
-                             int *eof, void *data)
-{
-        char *origpage = page;
-
-       down(&pvc_sem);
-        page += sprintf(page, "%d\n", scroll_dir * scroll_interval);
-       up(&pvc_sem);
-
-        return page - origpage;
-}
-
-
-void pvc_proc_timerfunc(unsigned long data)
-{
-       if (scroll_dir < 0)
-               pvc_move(DISPLAY|RIGHT);
-       else if (scroll_dir > 0)
-               pvc_move(DISPLAY|LEFT);
-
-       timer.expires = jiffies + scroll_interval;
-       add_timer(&timer);
-}
-
-static void pvc_proc_cleanup(void)
-{
-       int i;
-       for (i=0; i<PVC_NLINES; i++)
-               remove_proc_entry(pvc_linename[i], pvc_display_dir);
-       remove_proc_entry("scroll", pvc_display_dir);
-       remove_proc_entry(DISPLAY_DIR_NAME, NULL);
-
-       del_timer(&timer);
-}
-
-static int __init pvc_proc_init(void)
-{
-       struct proc_dir_entry *proc_entry;
-       int i;
-
-       pvc_display_dir = proc_mkdir(DISPLAY_DIR_NAME, NULL);
-       if (pvc_display_dir == NULL)
-               goto error;
-
-       for (i=0; i<PVC_NLINES; i++) {
-               strcpy(pvc_lines[i], "");
-               pvc_linedata[i] = i;
-       }
-       for (i=0; i<PVC_NLINES; i++) {
-               proc_entry = create_proc_entry(pvc_linename[i], 0644, pvc_display_dir);
-               if (proc_entry == NULL)
-                       goto error;
-               proc_entry->read_proc = pvc_proc_read_line;
-               proc_entry->write_proc = pvc_proc_write_line;
-               proc_entry->data = &pvc_linedata[i];
-       }
-       proc_entry = create_proc_entry("scroll", 0644, pvc_display_dir);
-       if (proc_entry == NULL)
-               goto error;
-       proc_entry->write_proc = pvc_proc_write_scroll;
-       proc_entry->read_proc = pvc_proc_read_scroll;
-
-       init_timer(&timer);
-       timer.function = pvc_proc_timerfunc;
-
-       return 0;
-error:
-       pvc_proc_cleanup();
-       return -ENOMEM;
-}
-
-module_init(pvc_proc_init);
-module_exit(pvc_proc_cleanup);
-MODULE_LICENSE("GPL");
diff --git a/arch/mips/lasat/prom.c b/arch/mips/lasat/prom.c
deleted file mode 100644 (file)
index 812c6ac..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * PROM interface routines.
- */
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/ctype.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/bootmem.h>
-#include <linux/ioport.h>
-#include <asm/bootinfo.h>
-#include <asm/lasat/lasat.h>
-#include <asm/cpu.h>
-
-#include "at93c.h"
-#include <asm/lasat/eeprom.h>
-#include "prom.h"
-
-#define RESET_VECTOR   0xbfc00000
-#define PROM_JUMP_TABLE_ENTRY(n) (*((u32 *)(RESET_VECTOR + 0x20) + n))
-#define PROM_DISPLAY_ADDR      PROM_JUMP_TABLE_ENTRY(0)
-#define PROM_PUTC_ADDR         PROM_JUMP_TABLE_ENTRY(1)
-#define PROM_MONITOR_ADDR      PROM_JUMP_TABLE_ENTRY(2)
-
-static void null_prom_display(const char *string, int pos, int clear)
-{
-}
-
-static void null_prom_monitor(void)
-{
-}
-
-static void null_prom_putc(char c)
-{
-}
-
-/* these are functions provided by the bootloader */
-static void (* __prom_putc)(char c) = null_prom_putc;
-
-void prom_putchar(char c)
-{
-       __prom_putc(c);
-}
-
-void (* prom_display)(const char *string, int pos, int clear) =
-               null_prom_display;
-void (* prom_monitor)(void) = null_prom_monitor;
-
-unsigned int lasat_ndelay_divider;
-
-static void setup_prom_vectors(void)
-{
-       u32 version = *(u32 *)(RESET_VECTOR + 0x90);
-
-       if (version >= 307) {
-               prom_display = (void *)PROM_DISPLAY_ADDR;
-               __prom_putc = (void *)PROM_PUTC_ADDR;
-               prom_monitor = (void *)PROM_MONITOR_ADDR;
-       }
-       printk("prom vectors set up\n");
-}
-
-static struct at93c_defs at93c_defs[N_MACHTYPES] = {
-       {(void *)AT93C_REG_100, (void *)AT93C_RDATA_REG_100, AT93C_RDATA_SHIFT_100,
-       AT93C_WDATA_SHIFT_100, AT93C_CS_M_100, AT93C_CLK_M_100},
-       {(void *)AT93C_REG_200, (void *)AT93C_RDATA_REG_200, AT93C_RDATA_SHIFT_200,
-       AT93C_WDATA_SHIFT_200, AT93C_CS_M_200, AT93C_CLK_M_200},
-};
-
-void __init prom_init(void)
-{
-       int argc = fw_arg0;
-       char **argv = (char **) fw_arg1;
-
-       setup_prom_vectors();
-
-       if (current_cpu_data.cputype == CPU_R5000) {
-               printk("LASAT 200 board\n");
-               mips_machtype = MACH_LASAT_200;
-                lasat_ndelay_divider = LASAT_200_DIVIDER;
-        } else {
-               printk("LASAT 100 board\n");
-               mips_machtype = MACH_LASAT_100;
-                lasat_ndelay_divider = LASAT_100_DIVIDER;
-        }
-
-       at93c = &at93c_defs[mips_machtype];
-
-       lasat_init_board_info();                /* Read info from EEPROM */
-
-       mips_machgroup = MACH_GROUP_LASAT;
-
-       /* Get the command line */
-       if (argc > 0) {
-               strncpy(arcs_cmdline, argv[0], CL_SIZE-1);
-               arcs_cmdline[CL_SIZE-1] = '\0';
-       }
-
-       /* Set the I/O base address */
-       set_io_port_base(KSEG1);
-
-       /* Set memory regions */
-       ioport_resource.start = 0;
-       ioport_resource.end = 0xffffffff;       /* Wrong, fixme.  */
-
-       add_memory_region(0, lasat_board_info.li_memsize, BOOT_MEM_RAM);
-}
-
-void __init prom_free_prom_memory(void)
-{
-}
-
-const char *get_system_type(void)
-{
-       return lasat_board_info.li_bmstr;
-}
diff --git a/arch/mips/lasat/prom.h b/arch/mips/lasat/prom.h
deleted file mode 100644 (file)
index 019d45f..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-#ifndef PROM_H
-#define PROM_H
-extern void (* prom_display)(const char *string, int pos, int clear);
-extern void (* prom_monitor)(void);
-#endif
diff --git a/arch/mips/lasat/reset.c b/arch/mips/lasat/reset.c
deleted file mode 100644 (file)
index 9e22acf..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Thomas Horsten <thh@lasat.com>
- * Copyright (C) 2000 LASAT Networks A/S.
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You 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.
- *
- * Reset the LASAT board.
- */
-#include <linux/kernel.h>
-#include <linux/pm.h>
-
-#include <asm/reboot.h>
-#include <asm/system.h>
-#include <asm/lasat/lasat.h>
-
-#include "picvue.h"
-#include "prom.h"
-
-static void lasat_machine_restart(char *command);
-static void lasat_machine_halt(void);
-
-/* Used to set machine to boot in service mode via /proc interface */
-int lasat_boot_to_service = 0;
-
-static void lasat_machine_restart(char *command)
-{
-       local_irq_disable();
-
-       if (lasat_boot_to_service) {
-               printk("machine_restart: Rebooting to service mode\n");
-               *(volatile unsigned int *)0xa0000024 = 0xdeadbeef;
-               *(volatile unsigned int *)0xa00000fc = 0xfedeabba;
-       }
-       *lasat_misc->reset_reg = 0xbedead;
-       for (;;) ;
-}
-
-#define MESSAGE "System halted"
-static void lasat_machine_halt(void)
-{
-       local_irq_disable();
-
-       /* Disable interrupts and loop forever */
-       printk(KERN_NOTICE MESSAGE "\n");
-#ifdef CONFIG_PICVUE
-       pvc_clear();
-       pvc_write_string(MESSAGE, 0, 0);
-#endif
-       prom_monitor();
-       for (;;) ;
-}
-
-void lasat_reboot_setup(void)
-{
-       _machine_restart = lasat_machine_restart;
-       _machine_halt = lasat_machine_halt;
-       pm_power_off = lasat_machine_halt;
-}
diff --git a/arch/mips/lasat/setup.c b/arch/mips/lasat/setup.c
deleted file mode 100644 (file)
index 488007f..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 1999 MIPS Technologies, Inc.  All rights reserved.
- *
- * Thomas Horsten <thh@lasat.com>
- * Copyright (C) 2000 LASAT Networks A/S.
- *
- * Brian Murphy <brian@murphy.dk>
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You 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.
- *
- * Lasat specific setup.
- */
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/pci.h>
-#include <linux/interrupt.h>
-#include <linux/tty.h>
-#include <linux/serial.h>
-#include <linux/serial_core.h>
-
-#include <asm/time.h>
-#include <asm/cpu.h>
-#include <asm/bootinfo.h>
-#include <asm/irq.h>
-#include <asm/lasat/lasat.h>
-#include <asm/lasat/serial.h>
-
-#ifdef CONFIG_PICVUE
-#include <linux/notifier.h>
-#endif
-
-#include "ds1603.h"
-#include <asm/lasat/ds1603.h>
-#include <asm/lasat/picvue.h>
-#include <asm/lasat/eeprom.h>
-
-#include "prom.h"
-
-int lasat_command_line = 0;
-void lasatint_init(void);
-
-extern void lasat_reboot_setup(void);
-extern void pcisetup(void);
-extern void edhac_init(void *, void *, void *);
-extern void addrflt_init(void);
-
-struct lasat_misc lasat_misc_info[N_MACHTYPES] = {
-       {(void *)KSEG1ADDR(0x1c840000), (void *)KSEG1ADDR(0x1c800000), 2},
-       {(void *)KSEG1ADDR(0x11080000), (void *)KSEG1ADDR(0x11000000), 6}
-};
-
-struct lasat_misc *lasat_misc = NULL;
-
-#ifdef CONFIG_DS1603
-static struct ds_defs ds_defs[N_MACHTYPES] = {
-       { (void *)DS1603_REG_100, (void *)DS1603_REG_100,
-               DS1603_RST_100, DS1603_CLK_100, DS1603_DATA_100,
-               DS1603_DATA_SHIFT_100, 0, 0 },
-       { (void *)DS1603_REG_200, (void *)DS1603_DATA_REG_200,
-               DS1603_RST_200, DS1603_CLK_200, DS1603_DATA_200,
-               DS1603_DATA_READ_SHIFT_200, 1, 2000 }
-};
-#endif
-
-#ifdef CONFIG_PICVUE
-#include "picvue.h"
-static struct pvc_defs pvc_defs[N_MACHTYPES] = {
-       { (void *)PVC_REG_100, PVC_DATA_SHIFT_100, PVC_DATA_M_100,
-               PVC_E_100, PVC_RW_100, PVC_RS_100 },
-       { (void *)PVC_REG_200, PVC_DATA_SHIFT_200, PVC_DATA_M_200,
-               PVC_E_200, PVC_RW_200, PVC_RS_200 }
-};
-#endif
-
-static int lasat_panic_display(struct notifier_block *this,
-                            unsigned long event, void *ptr)
-{
-#ifdef CONFIG_PICVUE
-       unsigned char *string = ptr;
-       if (string == NULL)
-               string = "Kernel Panic";
-       pvc_dump_string(string);
-#endif
-       return NOTIFY_DONE;
-}
-
-static int lasat_panic_prom_monitor(struct notifier_block *this,
-                            unsigned long event, void *ptr)
-{
-       prom_monitor();
-       return NOTIFY_DONE;
-}
-
-static struct notifier_block lasat_panic_block[] =
-{
-       { lasat_panic_display, NULL, INT_MAX },
-       { lasat_panic_prom_monitor, NULL, INT_MIN }
-};
-
-static void lasat_time_init(void)
-{
-       mips_hpt_frequency = lasat_board_info.li_cpu_hz / 2;
-}
-
-void __init plat_timer_setup(struct irqaction *irq)
-{
-       change_c0_status(ST0_IM, IE_IRQ0 | IE_IRQ5);
-}
-
-#define DYNAMIC_SERIAL_INIT
-#ifdef DYNAMIC_SERIAL_INIT
-void __init serial_init(void)
-{
-#ifdef CONFIG_SERIAL_8250
-       struct uart_port s;
-
-       memset(&s, 0, sizeof(s));
-
-       s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
-       s.iotype = UPIO_MEM;
-
-       if (mips_machtype == MACH_LASAT_100) {
-               s.uartclk = LASAT_BASE_BAUD_100 * 16;
-               s.irq = LASATINT_UART_100;
-               s.regshift = LASAT_UART_REGS_SHIFT_100;
-               s.membase = (char *)KSEG1ADDR(LASAT_UART_REGS_BASE_100);
-       } else {
-               s.uartclk = LASAT_BASE_BAUD_200 * 16;
-               s.irq = LASATINT_UART_200;
-               s.regshift = LASAT_UART_REGS_SHIFT_200;
-               s.membase = (char *)KSEG1ADDR(LASAT_UART_REGS_BASE_200);
-       }
-
-       if (early_serial_setup(&s) != 0)
-               printk(KERN_ERR "Serial setup failed!\n");
-#endif
-}
-#endif
-
-void __init plat_mem_setup(void)
-{
-       int i;
-       lasat_misc  = &lasat_misc_info[mips_machtype];
-#ifdef CONFIG_PICVUE
-       picvue = &pvc_defs[mips_machtype];
-#endif
-
-       /* Set up panic notifier */
-       for (i = 0; i < sizeof(lasat_panic_block) / sizeof(struct notifier_block); i++)
-               atomic_notifier_chain_register(&panic_notifier_list,
-                               &lasat_panic_block[i]);
-
-       lasat_reboot_setup();
-
-       board_time_init = lasat_time_init;
-
-#ifdef CONFIG_DS1603
-       ds1603 = &ds_defs[mips_machtype];
-       rtc_mips_get_time = ds1603_read;
-       rtc_mips_set_time = ds1603_set;
-#endif
-
-#ifdef DYNAMIC_SERIAL_INIT
-       serial_init();
-#endif
-       /* Switch from prom exception handler to normal mode */
-       change_c0_status(ST0_BEV,0);
-
-       pr_info("Lasat specific initialization complete\n");
-}
diff --git a/arch/mips/lasat/sysctl.c b/arch/mips/lasat/sysctl.c
deleted file mode 100644 (file)
index 699ab18..0000000
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- * Thomas Horsten <thh@lasat.com>
- * Copyright (C) 2000 LASAT Networks A/S.
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You 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.
- *
- * Routines specific to the LASAT boards
- */
-#include <linux/types.h>
-#include <asm/lasat/lasat.h>
-
-#include <linux/module.h>
-#include <linux/sysctl.h>
-#include <linux/stddef.h>
-#include <linux/init.h>
-#include <linux/fs.h>
-#include <linux/ctype.h>
-#include <linux/string.h>
-#include <linux/net.h>
-#include <linux/inet.h>
-#include <linux/mutex.h>
-#include <asm/uaccess.h>
-
-#include "sysctl.h"
-#include "ds1603.h"
-
-static DEFINE_MUTEX(lasat_info_mutex);
-
-/* Strategy function to write EEPROM after changing string entry */
-int sysctl_lasatstring(ctl_table *table, int *name, int nlen,
-               void *oldval, size_t *oldlenp,
-               void *newval, size_t newlen)
-{
-       int r;
-       mutex_lock(&lasat_info_mutex);
-       r = sysctl_string(table, name,
-                         nlen, oldval, oldlenp, newval, newlen);
-       if (r < 0) {
-               mutex_unlock(&lasat_info_mutex);
-               return r;
-       }
-       if (newval && newlen) {
-               lasat_write_eeprom_info();
-       }
-       mutex_unlock(&lasat_info_mutex);
-       return 1;
-}
-
-
-/* And the same for proc */
-int proc_dolasatstring(ctl_table *table, int write, struct file *filp,
-                      void *buffer, size_t *lenp, loff_t *ppos)
-{
-       int r;
-       mutex_lock(&lasat_info_mutex);
-       r = proc_dostring(table, write, filp, buffer, lenp, ppos);
-       if ( (!write) || r) {
-               mutex_unlock(&lasat_info_mutex);
-               return r;
-       }
-       lasat_write_eeprom_info();
-       mutex_unlock(&lasat_info_mutex);
-       return 0;
-}
-
-/* proc function to write EEPROM after changing int entry */
-int proc_dolasatint(ctl_table *table, int write, struct file *filp,
-                      void *buffer, size_t *lenp, loff_t *ppos)
-{
-       int r;
-       mutex_lock(&lasat_info_mutex);
-       r = proc_dointvec(table, write, filp, buffer, lenp, ppos);
-       if ( (!write) || r) {
-               mutex_unlock(&lasat_info_mutex);
-               return r;
-       }
-       lasat_write_eeprom_info();
-       mutex_unlock(&lasat_info_mutex);
-       return 0;
-}
-
-static int rtctmp;
-
-#ifdef CONFIG_DS1603
-/* proc function to read/write RealTime Clock */
-int proc_dolasatrtc(ctl_table *table, int write, struct file *filp,
-                      void *buffer, size_t *lenp, loff_t *ppos)
-{
-       int r;
-       mutex_lock(&lasat_info_mutex);
-       if (!write) {
-               rtctmp = ds1603_read();
-               /* check for time < 0 and set to 0 */
-               if (rtctmp < 0)
-                       rtctmp = 0;
-       }
-       r = proc_dointvec(table, write, filp, buffer, lenp, ppos);
-       if ( (!write) || r) {
-               mutex_unlock(&lasat_info_mutex);
-               return r;
-       }
-       ds1603_set(rtctmp);
-       mutex_unlock(&lasat_info_mutex);
-       return 0;
-}
-#endif
-
-/* Sysctl for setting the IP addresses */
-int sysctl_lasat_intvec(ctl_table *table, int *name, int nlen,
-                   void *oldval, size_t *oldlenp,
-                   void *newval, size_t newlen)
-{
-       int r;
-       mutex_lock(&lasat_info_mutex);
-       r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen);
-       if (r < 0) {
-               mutex_unlock(&lasat_info_mutex);
-               return r;
-       }
-       if (newval && newlen) {
-               lasat_write_eeprom_info();
-       }
-       mutex_unlock(&lasat_info_mutex);
-       return 1;
-}
-
-#ifdef CONFIG_DS1603
-/* Same for RTC */
-int sysctl_lasat_rtc(ctl_table *table, int *name, int nlen,
-                   void *oldval, size_t *oldlenp,
-                   void *newval, size_t newlen)
-{
-       int r;
-       mutex_lock(&lasat_info_mutex);
-       rtctmp = ds1603_read();
-       if (rtctmp < 0)
-               rtctmp = 0;
-       r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen);
-       if (r < 0) {
-               mutex_unlock(&lasat_info_mutex);
-               return r;
-       }
-       if (newval && newlen) {
-               ds1603_set(rtctmp);
-       }
-       mutex_unlock(&lasat_info_mutex);
-       return 1;
-}
-#endif
-
-#ifdef CONFIG_INET
-static char lasat_bcastaddr[16];
-
-void update_bcastaddr(void)
-{
-       unsigned int ip;
-
-       ip = (lasat_board_info.li_eeprom_info.ipaddr &
-               lasat_board_info.li_eeprom_info.netmask) |
-               ~lasat_board_info.li_eeprom_info.netmask;
-
-       sprintf(lasat_bcastaddr, "%d.%d.%d.%d",
-                       (ip      ) & 0xff,
-                       (ip >>  8) & 0xff,
-                       (ip >> 16) & 0xff,
-                       (ip >> 24) & 0xff);
-}
-
-static char proc_lasat_ipbuf[32];
-/* Parsing of IP address */
-int proc_lasat_ip(ctl_table *table, int write, struct file *filp,
-                      void *buffer, size_t *lenp, loff_t *ppos)
-{
-       int len;
-        unsigned int ip;
-       char *p, c;
-
-       if (!table->data || !table->maxlen || !*lenp ||
-           (*ppos && !write)) {
-               *lenp = 0;
-               return 0;
-       }
-
-       mutex_lock(&lasat_info_mutex);
-       if (write) {
-               len = 0;
-               p = buffer;
-               while (len < *lenp) {
-                       if(get_user(c, p++)) {
-                               mutex_unlock(&lasat_info_mutex);
-                               return -EFAULT;
-                       }
-                       if (c == 0 || c == '\n')
-                               break;
-                       len++;
-               }
-               if (len >= sizeof(proc_lasat_ipbuf)-1)
-                       len = sizeof(proc_lasat_ipbuf) - 1;
-               if (copy_from_user(proc_lasat_ipbuf, buffer, len))
-               {
-                       mutex_unlock(&lasat_info_mutex);
-                       return -EFAULT;
-               }
-               proc_lasat_ipbuf[len] = 0;
-               *ppos += *lenp;
-               /* Now see if we can convert it to a valid IP */
-               ip = in_aton(proc_lasat_ipbuf);
-               *(unsigned int *)(table->data) = ip;
-               lasat_write_eeprom_info();
-       } else {
-               ip = *(unsigned int *)(table->data);
-               sprintf(proc_lasat_ipbuf, "%d.%d.%d.%d",
-                       (ip      ) & 0xff,
-                       (ip >>  8) & 0xff,
-                       (ip >> 16) & 0xff,
-                       (ip >> 24) & 0xff);
-               len = strlen(proc_lasat_ipbuf);
-               if (len > *lenp)
-                       len = *lenp;
-               if (len)
-                       if(copy_to_user(buffer, proc_lasat_ipbuf, len)) {
-                               mutex_unlock(&lasat_info_mutex);
-                               return -EFAULT;
-                       }
-               if (len < *lenp) {
-                       if(put_user('\n', ((char *) buffer) + len)) {
-                               mutex_unlock(&lasat_info_mutex);
-                               return -EFAULT;
-                       }
-                       len++;
-               }
-               *lenp = len;
-               *ppos += len;
-       }
-       update_bcastaddr();
-       mutex_unlock(&lasat_info_mutex);
-       return 0;
-}
-#endif /* defined(CONFIG_INET) */
-
-static int sysctl_lasat_eeprom_value(ctl_table *table, int *name, int nlen,
-                                    void *oldval, size_t *oldlenp,
-                                    void *newval, size_t newlen)
-{
-       int r;
-
-       mutex_lock(&lasat_info_mutex);
-       r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen);
-       if (r < 0) {
-               mutex_unlock(&lasat_info_mutex);
-               return r;
-       }
-
-       if (newval && newlen)
-       {
-               if (name && *name == LASAT_PRID)
-                       lasat_board_info.li_eeprom_info.prid = *(int*)newval;
-
-               lasat_write_eeprom_info();
-               lasat_init_board_info();
-       }
-       mutex_unlock(&lasat_info_mutex);
-
-       return 0;
-}
-
-int proc_lasat_eeprom_value(ctl_table *table, int write, struct file *filp,
-                      void *buffer, size_t *lenp, loff_t *ppos)
-{
-       int r;
-       mutex_lock(&lasat_info_mutex);
-       r = proc_dointvec(table, write, filp, buffer, lenp, ppos);
-       if ( (!write) || r) {
-               mutex_unlock(&lasat_info_mutex);
-               return r;
-       }
-       if (filp && filp->f_path.dentry)
-       {
-               if (!strcmp(filp->f_path.dentry->d_name.name, "prid"))
-                       lasat_board_info.li_eeprom_info.prid = lasat_board_info.li_prid;
-               if (!strcmp(filp->f_path.dentry->d_name.name, "debugaccess"))
-                       lasat_board_info.li_eeprom_info.debugaccess = lasat_board_info.li_debugaccess;
-       }
-       lasat_write_eeprom_info();
-       mutex_unlock(&lasat_info_mutex);
-       return 0;
-}
-
-extern int lasat_boot_to_service;
-
-#ifdef CONFIG_SYSCTL
-
-static ctl_table lasat_table[] = {
-       {
-               .ctl_name       = CTL_UNNUMBERED,
-               .procname       = "cpu-hz",
-               .data           = &lasat_board_info.li_cpu_hz,
-               .maxlen         = sizeof(int),
-               .mode           = 0444,
-               .proc_handler   = &proc_dointvec,
-               .strategy       = &sysctl_intvec
-       },
-       {
-               .ctl_name       = CTL_UNNUMBERED,
-               .procname       = "bus-hz",
-               .data           = &lasat_board_info.li_bus_hz,
-               .maxlen         = sizeof(int),
-               .mode           = 0444,
-               .proc_handler   = &proc_dointvec,
-               .strategy       = &sysctl_intvec
-       },
-       {
-               .ctl_name       = CTL_UNNUMBERED,
-               .procname       = "bmid",
-               .data           = &lasat_board_info.li_bmid,
-               .maxlen         = sizeof(int),
-               .mode           = 0444,
-               .proc_handler   = &proc_dointvec,
-               .strategy       = &sysctl_intvec
-       },
-       {
-               .ctl_name       = CTL_UNNUMBERED,
-               .procname       = "prid",
-               .data           = &lasat_board_info.li_prid,
-               .maxlen         = sizeof(int),
-               .mode           = 0644,
-               .proc_handler   = &proc_lasat_eeprom_value,
-               .strategy       = &sysctl_lasat_eeprom_value
-       },
-#ifdef CONFIG_INET
-       {
-               .ctl_name       = CTL_UNNUMBERED,
-               .procname       = "ipaddr",
-               .data           = &lasat_board_info.li_eeprom_info.ipaddr,
-               .maxlen         = sizeof(int),
-               .mode           = 0644,
-               .proc_handler   = &proc_lasat_ip,
-               .strategy       = &sysctl_lasat_intvec
-       },
-       {
-               .ctl_name       = LASAT_NETMASK,
-               .procname       = "netmask",
-               .data           = &lasat_board_info.li_eeprom_info.netmask,
-               .maxlen         = sizeof(int),
-               .mode           = 0644,
-               .proc_handler   = &proc_lasat_ip,
-               .strategy       = &sysctl_lasat_intvec
-       },
-       {
-               .ctl_name       = CTL_UNNUMBERED,
-               .procname       = "bcastaddr",
-               .data           = &lasat_bcastaddr,
-               .maxlen         = sizeof(lasat_bcastaddr),
-               .mode           = 0600,
-               .proc_handler   = &proc_dostring,
-               .strategy       = &sysctl_string
-       },
-#endif
-       {
-               .ctl_name       = CTL_UNNUMBERED,
-               .procname       = "passwd_hash",
-               .data           = &lasat_board_info.li_eeprom_info.passwd_hash,
-               .maxlen         = sizeof(lasat_board_info.li_eeprom_info.passwd_hash),
-               .mode           = 0600,
-               .proc_handler   = &proc_dolasatstring,
-               .strategy       = &sysctl_lasatstring
-       },
-       {
-               .ctl_name       = CTL_UNNUMBERED,
-               .procname       = "boot-service",
-               .data           = &lasat_boot_to_service,
-               .maxlen         = sizeof(int),
-               .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
-               .strategy       = &sysctl_intvec
-       },
-#ifdef CONFIG_DS1603
-       {
-               .ctl_name       = CTL_UNNUMBERED,
-               .procname       = "rtc",
-               .data           = &rtctmp,
-               .maxlen         = sizeof(int),
-               .mode           = 0644,
-               .proc_handler   = &proc_dolasatrtc,
-               .strategy       = &sysctl_lasat_rtc
-       },
-#endif
-       {
-               .ctl_name       = CTL_UNNUMBERED,
-               .procname       = "namestr",
-               .data           = &lasat_board_info.li_namestr,
-               .maxlen         = sizeof(lasat_board_info.li_namestr),
-               .mode           = 0444,
-               .proc_handler   =  &proc_dostring,
-               .strategy       = &sysctl_string
-       },
-       {
-               .ctl_name       = CTL_UNNUMBERED,
-               .procname       = "typestr",
-               .data           = &lasat_board_info.li_typestr,
-               .maxlen         = sizeof(lasat_board_info.li_typestr),
-               .mode           = 0444,
-               .proc_handler   = &proc_dostring,
-               .strategy       = &sysctl_string
-       },
-       {}
-};
-
-static ctl_table lasat_root_table[] = {
-       {
-               .ctl_name       = CTL_UNNUMBERED,
-               .procname       = "lasat",
-               .mode           =  0555,
-               .child          = lasat_table
-       },
-       {}
-};
-
-static int __init lasat_register_sysctl(void)
-{
-       struct ctl_table_header *lasat_table_header;
-
-       lasat_table_header =
-               register_sysctl_table(lasat_root_table);
-
-       return 0;
-}
-
-__initcall(lasat_register_sysctl);
-#endif /* CONFIG_SYSCTL */
diff --git a/arch/mips/lasat/sysctl.h b/arch/mips/lasat/sysctl.h
deleted file mode 100644 (file)
index 4d139d2..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * LASAT sysctl values
- */
-
-#ifndef _LASAT_SYSCTL_H
-#define _LASAT_SYSCTL_H
-
-/* /proc/sys/lasat */
-enum {
-       LASAT_CPU_HZ=1,
-       LASAT_BUS_HZ,
-       LASAT_MODEL,
-       LASAT_PRID,
-       LASAT_IPADDR,
-       LASAT_NETMASK,
-       LASAT_BCAST,
-       LASAT_PASSWORD,
-       LASAT_SBOOT,
-       LASAT_RTC,
-       LASAT_NAMESTR,
-       LASAT_TYPESTR,
-};
-
-#endif /* _LASAT_SYSCTL_H */
diff --git a/arch/mips/lemote/lm2e/Makefile b/arch/mips/lemote/lm2e/Makefile
new file mode 100644 (file)
index 0000000..fb1b48c
--- /dev/null
@@ -0,0 +1,7 @@
+#
+# Makefile for Lemote Fulong mini-PC board.
+#
+
+obj-y += setup.o prom.o reset.o irq.o pci.o bonito-irq.o dbg_io.o mem.o
+EXTRA_AFLAGS := $(CFLAGS)
+
diff --git a/arch/mips/lemote/lm2e/bonito-irq.c b/arch/mips/lemote/lm2e/bonito-irq.c
new file mode 100644 (file)
index 0000000..8fc3bce
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org)
+ *
+ * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include <asm/mips-boards/bonito64.h>
+
+
+static inline void bonito_irq_enable(unsigned int irq)
+{
+       BONITO_INTENSET = (1 << (irq - BONITO_IRQ_BASE));
+       mmiowb();
+}
+
+static inline void bonito_irq_disable(unsigned int irq)
+{
+       BONITO_INTENCLR = (1 << (irq - BONITO_IRQ_BASE));
+       mmiowb();
+}
+
+static struct irq_chip bonito_irq_type = {
+       .name   = "bonito_irq",
+       .ack    = bonito_irq_disable,
+       .mask   = bonito_irq_disable,
+       .mask_ack = bonito_irq_disable,
+       .unmask = bonito_irq_enable,
+};
+
+static struct irqaction dma_timeout_irqaction = {
+       .handler        = no_action,
+       .name           = "dma_timeout",
+};
+
+void bonito_irq_init(void)
+{
+       u32 i;
+
+       for (i = BONITO_IRQ_BASE; i < BONITO_IRQ_BASE + 32; i++) {
+               set_irq_chip_and_handler(i, &bonito_irq_type, handle_level_irq);
+       }
+
+       setup_irq(BONITO_IRQ_BASE + 10, &dma_timeout_irqaction);
+}
diff --git a/arch/mips/lemote/lm2e/dbg_io.c b/arch/mips/lemote/lm2e/dbg_io.c
new file mode 100644 (file)
index 0000000..6c95da3
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org)
+ *
+ * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include <asm/serial.h>
+
+#define         UART16550_BAUD_2400             2400
+#define         UART16550_BAUD_4800             4800
+#define         UART16550_BAUD_9600             9600
+#define         UART16550_BAUD_19200            19200
+#define         UART16550_BAUD_38400            38400
+#define         UART16550_BAUD_57600            57600
+#define         UART16550_BAUD_115200           115200
+
+#define         UART16550_PARITY_NONE           0
+#define         UART16550_PARITY_ODD            0x08
+#define         UART16550_PARITY_EVEN           0x18
+#define         UART16550_PARITY_MARK           0x28
+#define         UART16550_PARITY_SPACE          0x38
+
+#define         UART16550_DATA_5BIT             0x0
+#define         UART16550_DATA_6BIT             0x1
+#define         UART16550_DATA_7BIT             0x2
+#define         UART16550_DATA_8BIT             0x3
+
+#define         UART16550_STOP_1BIT             0x0
+#define         UART16550_STOP_2BIT             0x4
+
+/* ----------------------------------------------------- */
+
+/* === CONFIG === */
+#ifdef CONFIG_64BIT
+#define         BASE                    (0xffffffffbfd003f8)
+#else
+#define         BASE                    (0xbfd003f8)
+#endif
+
+#define         MAX_BAUD                BASE_BAUD
+/* === END OF CONFIG === */
+
+#define         REG_OFFSET              1
+
+/* register offset */
+#define         OFS_RCV_BUFFER          0
+#define         OFS_TRANS_HOLD          0
+#define         OFS_SEND_BUFFER         0
+#define         OFS_INTR_ENABLE         (1*REG_OFFSET)
+#define         OFS_INTR_ID             (2*REG_OFFSET)
+#define         OFS_DATA_FORMAT         (3*REG_OFFSET)
+#define         OFS_LINE_CONTROL        (3*REG_OFFSET)
+#define         OFS_MODEM_CONTROL       (4*REG_OFFSET)
+#define         OFS_RS232_OUTPUT        (4*REG_OFFSET)
+#define         OFS_LINE_STATUS         (5*REG_OFFSET)
+#define         OFS_MODEM_STATUS        (6*REG_OFFSET)
+#define         OFS_RS232_INPUT         (6*REG_OFFSET)
+#define         OFS_SCRATCH_PAD         (7*REG_OFFSET)
+
+#define         OFS_DIVISOR_LSB         (0*REG_OFFSET)
+#define         OFS_DIVISOR_MSB         (1*REG_OFFSET)
+
+/* memory-mapped read/write of the port */
+#define         UART16550_READ(y)      readb((char *)BASE + (y))
+#define         UART16550_WRITE(y, z)  writeb(z, (char *)BASE + (y))
+
+void debugInit(u32 baud, u8 data, u8 parity, u8 stop)
+{
+       u32 divisor;
+
+       /* disable interrupts */
+       UART16550_WRITE(OFS_INTR_ENABLE, 0);
+
+       /* set up buad rate */
+       /* set DIAB bit */
+       UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
+
+       /* set divisor */
+       divisor = MAX_BAUD / baud;
+       UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
+       UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8);
+
+       /* clear DIAB bit */
+       UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
+
+       /* set data format */
+       UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
+}
+
+static int remoteDebugInitialized;
+
+u8 getDebugChar(void)
+{
+       if (!remoteDebugInitialized) {
+               remoteDebugInitialized = 1;
+               debugInit(UART16550_BAUD_115200,
+                         UART16550_DATA_8BIT,
+                         UART16550_PARITY_NONE, UART16550_STOP_1BIT);
+       }
+
+       while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0) ;
+       return UART16550_READ(OFS_RCV_BUFFER);
+}
+
+int putDebugChar(u8 byte)
+{
+       if (!remoteDebugInitialized) {
+               remoteDebugInitialized = 1;
+               /*
+                  debugInit(UART16550_BAUD_115200,
+                  UART16550_DATA_8BIT,
+                  UART16550_PARITY_NONE, UART16550_STOP_1BIT); */
+       }
+
+       while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0) ;
+       UART16550_WRITE(OFS_SEND_BUFFER, byte);
+       return 1;
+}
diff --git a/arch/mips/lemote/lm2e/irq.c b/arch/mips/lemote/lm2e/irq.c
new file mode 100644 (file)
index 0000000..05693bc
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/i8259.h>
+#include <asm/mipsregs.h>
+#include <asm/mips-boards/bonito64.h>
+
+
+/*
+ * the first level int-handler will jump here if it is a bonito irq
+ */
+static void bonito_irqdispatch(void)
+{
+       u32 int_status;
+       int i;
+
+       /* workaround the IO dma problem: let cpu looping to allow DMA finish */
+       int_status = BONITO_INTISR;
+       if (int_status & (1 << 10)) {
+               while (int_status & (1 << 10)) {
+                       udelay(1);
+                       int_status = BONITO_INTISR;
+               }
+       }
+
+       /* Get pending sources, masked by current enables */
+       int_status = BONITO_INTISR & BONITO_INTEN;
+
+       if (int_status != 0) {
+               i = __ffs(int_status);
+               int_status &= ~(1 << i);
+               do_IRQ(BONITO_IRQ_BASE + i);
+       }
+}
+
+static void i8259_irqdispatch(void)
+{
+       int irq;
+
+       irq = i8259_irq();
+       if (irq >= 0) {
+               do_IRQ(irq);
+       } else {
+               spurious_interrupt();
+       }
+
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+       unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
+
+       if (pending & CAUSEF_IP7) {
+               do_IRQ(MIPS_CPU_IRQ_BASE + 7);
+       } else if (pending & CAUSEF_IP5) {
+               i8259_irqdispatch();
+       } else if (pending & CAUSEF_IP2) {
+               bonito_irqdispatch();
+       } else {
+               spurious_interrupt();
+       }
+}
+
+static struct irqaction cascade_irqaction = {
+       .handler = no_action,
+       .mask = CPU_MASK_NONE,
+       .name = "cascade",
+};
+
+void __init arch_init_irq(void)
+{
+       extern void bonito_irq_init(void);
+
+       /*
+        * Clear all of the interrupts while we change the able around a bit.
+        * int-handler is not on bootstrap
+        */
+       clear_c0_status(ST0_IM | ST0_BEV);
+       local_irq_disable();
+
+       /* most bonito irq should be level triggered */
+       BONITO_INTEDGE = BONITO_ICU_SYSTEMERR | BONITO_ICU_MASTERERR |
+               BONITO_ICU_RETRYERR | BONITO_ICU_MBOXES;
+       BONITO_INTSTEER = 0;
+
+       /*
+        * Mask out all interrupt by writing "1" to all bit position in
+        * the interrupt reset reg.
+        */
+       BONITO_INTENCLR = ~0;
+
+       /* init all controller
+        *   0-15         ------> i8259 interrupt
+        *   16-23        ------> mips cpu interrupt
+        *   32-63        ------> bonito irq
+        */
+
+       /* Sets the first-level interrupt dispatcher. */
+       mips_cpu_irq_init();
+       init_i8259_irqs();
+       bonito_irq_init();
+
+       /*
+       printk("GPIODATA=%x, GPIOIE=%x\n", BONITO_GPIODATA, BONITO_GPIOIE);
+       printk("INTEN=%x, INTSET=%x, INTCLR=%x, INTISR=%x\n",
+                       BONITO_INTEN, BONITO_INTENSET,
+                       BONITO_INTENCLR, BONITO_INTISR);
+       */
+
+       /* bonito irq at IP2 */
+       setup_irq(MIPS_CPU_IRQ_BASE + 2, &cascade_irqaction);
+       /* 8259 irq at IP5 */
+       setup_irq(MIPS_CPU_IRQ_BASE + 5, &cascade_irqaction);
+
+}
diff --git a/arch/mips/lemote/lm2e/mem.c b/arch/mips/lemote/lm2e/mem.c
new file mode 100644 (file)
index 0000000..16cd215
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the 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/fs.h>
+#include <linux/fcntl.h>
+#include <linux/mm.h>
+
+/* override of arch/mips/mm/cache.c: __uncached_access */
+int __uncached_access(struct file *file, unsigned long addr)
+{
+       if (file->f_flags & O_SYNC)
+               return 1;
+
+       /*
+        * On the Lemote Loongson 2e system, the peripheral registers
+        * reside between 0x1000:0000 and 0x2000:0000.
+        */
+       return addr >= __pa(high_memory) ||
+               ((addr >= 0x10000000) && (addr < 0x20000000));
+}
diff --git a/arch/mips/lemote/lm2e/pci.c b/arch/mips/lemote/lm2e/pci.c
new file mode 100644 (file)
index 0000000..1ade1ce
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * pci.c
+ *
+ * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <asm/mips-boards/bonito64.h>
+
+extern struct pci_ops bonito64_pci_ops;
+
+static struct resource loongson2e_pci_mem_resource = {
+       .name   = "LOONGSON2E PCI MEM",
+       .start  = 0x14000000UL,
+       .end    = 0x1fffffffUL,
+       .flags  = IORESOURCE_MEM,
+};
+
+static struct resource loongson2e_pci_io_resource = {
+       .name   = "LOONGSON2E PCI IO MEM",
+       .start  = 0x00004000UL,
+       .end    = IO_SPACE_LIMIT,
+       .flags  = IORESOURCE_IO,
+};
+
+static struct pci_controller  loongson2e_pci_controller = {
+       .pci_ops        = &bonito64_pci_ops,
+       .io_resource    = &loongson2e_pci_io_resource,
+       .mem_resource   = &loongson2e_pci_mem_resource,
+       .mem_offset     = 0x00000000UL,
+       .io_offset      = 0x00000000UL,
+};
+
+static void __init ict_pcimap(void)
+{
+       /*
+        * local to PCI mapping: [256M,512M] -> [256M,512M]; differ from PMON
+        *
+        * CPU address space [256M,448M] is window for accessing pci space
+        * we set pcimap_lo[0,1,2] to map it to pci space [256M,448M]
+        * pcimap: bit18,pcimap_2; bit[17-12],lo2;bit[11-6],lo1;bit[5-0],lo0
+        */
+       /* 1,00 0110 ,0001 01,00 0000 */
+       BONITO_PCIMAP = 0x46140;
+
+       /* 1, 00 0010, 0000,01, 00 0000 */
+       /* BONITO_PCIMAP = 0x42040; */
+
+       /*
+        * PCI to local mapping: [2G,2G+256M] -> [0,256M]
+        */
+       BONITO_PCIBASE0 = 0x80000000;
+       BONITO_PCIBASE1 = 0x00800000;
+       BONITO_PCIBASE2 = 0x90000000;
+
+}
+
+static int __init pcibios_init(void)
+{
+       extern int pci_probe_only;
+       pci_probe_only = 0;
+
+       ict_pcimap();
+       register_pci_controller(&loongson2e_pci_controller);
+
+       return 0;
+}
+
+arch_initcall(pcibios_init);
diff --git a/arch/mips/lemote/lm2e/prom.c b/arch/mips/lemote/lm2e/prom.c
new file mode 100644 (file)
index 0000000..67312d7
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * Based on Ocelot Linux port, which is
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * Copyright 2003 ICT CAS
+ * Author: Michael Guo <guoyi@ict.ac.cn>
+ *
+ * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+
+extern unsigned long bus_clock;
+extern unsigned long cpu_clock;
+extern unsigned int memsize, highmemsize;
+extern int putDebugChar(unsigned char byte);
+
+static int argc;
+/* pmon passes arguments in 32bit pointers */
+static int *arg;
+static int *env;
+
+const char *get_system_type(void)
+{
+       return "lemote-fulong";
+}
+
+void __init prom_init_cmdline(void)
+{
+       int i;
+       long l;
+
+       /* arg[0] is "g", the rest is boot parameters */
+       arcs_cmdline[0] = '\0';
+       for (i = 1; i < argc; i++) {
+               l = (long)arg[i];
+               if (strlen(arcs_cmdline) + strlen(((char *)l) + 1)
+                   >= sizeof(arcs_cmdline))
+                       break;
+               strcat(arcs_cmdline, ((char *)l));
+               strcat(arcs_cmdline, " ");
+       }
+}
+
+void __init prom_init(void)
+{
+       long l;
+       argc = fw_arg0;
+       arg = (int *)fw_arg1;
+       env = (int *)fw_arg2;
+
+       mips_machgroup = MACH_GROUP_LEMOTE;
+       mips_machtype = MACH_LEMOTE_FULONG;
+
+       prom_init_cmdline();
+
+       if ((strstr(arcs_cmdline, "console=")) == NULL)
+               strcat(arcs_cmdline, " console=ttyS0,115200");
+       if ((strstr(arcs_cmdline, "root=")) == NULL)
+               strcat(arcs_cmdline, " root=/dev/hda1");
+
+#define parse_even_earlier(res, option, p)                             \
+do {                                                                   \
+       if (strncmp(option, (char *)p, strlen(option)) == 0)            \
+               res = simple_strtol((char *)p + strlen(option"="),      \
+                                   NULL, 10);                          \
+} while (0)
+
+       l = (long)*env;
+       while (l != 0) {
+               parse_even_earlier(bus_clock, "busclock", l);
+               parse_even_earlier(cpu_clock, "cpuclock", l);
+               parse_even_earlier(memsize, "memsize", l);
+               parse_even_earlier(highmemsize, "highmemsize", l);
+               env++;
+               l = (long)*env;
+       }
+       if (memsize == 0)
+               memsize = 256;
+
+       pr_info("busclock=%ld, cpuclock=%ld,memsize=%d,highmemsize=%d\n",
+              bus_clock, cpu_clock, memsize, highmemsize);
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
+
+void prom_putchar(char c)
+{
+       putDebugChar(c);
+}
diff --git a/arch/mips/lemote/lm2e/reset.c b/arch/mips/lemote/lm2e/reset.c
new file mode 100644 (file)
index 0000000..099387a
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ */
+#include <linux/pm.h>
+
+#include <asm/reboot.h>
+
+static void loongson2e_restart(char *command)
+{
+#ifdef CONFIG_32BIT
+       *(unsigned long *)0xbfe00104 &= ~(1 << 2);
+       *(unsigned long *)0xbfe00104 |= (1 << 2);
+#else
+       *(unsigned long *)0xffffffffbfe00104 &= ~(1 << 2);
+       *(unsigned long *)0xffffffffbfe00104 |= (1 << 2);
+#endif
+       __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
+}
+
+static void loongson2e_halt(void)
+{
+       while (1) ;
+}
+
+static void loongson2e_power_off(void)
+{
+       loongson2e_halt();
+}
+
+void mips_reboot_setup(void)
+{
+       _machine_restart = loongson2e_restart;
+       _machine_halt = loongson2e_halt;
+       pm_power_off = loongson2e_power_off;
+}
diff --git a/arch/mips/lemote/lm2e/setup.c b/arch/mips/lemote/lm2e/setup.c
new file mode 100644 (file)
index 0000000..0e4d1fa
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ * setup.c - board dependent boot routines
+ *
+ * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <linux/bootmem.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/mc146818rtc.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/tty.h>
+#include <linux/types.h>
+
+#include <asm/bootinfo.h>
+#include <asm/mc146818-time.h>
+#include <asm/time.h>
+#include <asm/wbflush.h>
+
+#ifdef CONFIG_VT
+#include <linux/console.h>
+#include <linux/screen_info.h>
+#endif
+
+extern void mips_reboot_setup(void);
+
+#ifdef CONFIG_64BIT
+#define PTR_PAD(p) ((0xffffffff00000000)|((unsigned long long)(p)))
+#else
+#define PTR_PAD(p) (p)
+#endif
+
+unsigned long cpu_clock;
+unsigned long bus_clock;
+unsigned int memsize;
+unsigned int highmemsize = 0;
+
+void __init plat_timer_setup(struct irqaction *irq)
+{
+       setup_irq(MIPS_CPU_IRQ_BASE + 7, irq);
+}
+
+static void __init loongson2e_time_init(void)
+{
+       /* setup mips r4k timer */
+       mips_hpt_frequency = cpu_clock / 2;
+}
+
+static unsigned long __init mips_rtc_get_time(void)
+{
+       return mc146818_get_cmos_time();
+}
+
+void (*__wbflush)(void);
+EXPORT_SYMBOL(__wbflush);
+
+static void wbflush_loongson2e(void)
+{
+       asm(".set\tpush\n\t"
+           ".set\tnoreorder\n\t"
+           ".set mips3\n\t"
+           "sync\n\t"
+           "nop\n\t"
+           ".set\tpop\n\t"
+           ".set mips0\n\t");
+}
+
+void __init plat_mem_setup(void)
+{
+       set_io_port_base(PTR_PAD(0xbfd00000));
+
+       mips_reboot_setup();
+
+       board_time_init = loongson2e_time_init;
+       rtc_mips_get_time = mips_rtc_get_time;
+
+       __wbflush = wbflush_loongson2e;
+
+       add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM);
+#ifdef CONFIG_64BIT
+       if (highmemsize > 0) {
+               add_memory_region(0x20000000, highmemsize << 20, BOOT_MEM_RAM);
+       }
+#endif
+
+#ifdef CONFIG_VT
+#if defined(CONFIG_VGA_CONSOLE)
+       conswitchp = &vga_con;
+
+       screen_info = (struct screen_info) {
+               0, 25,          /* orig-x, orig-y */
+                   0,          /* unused */
+                   0,          /* orig-video-page */
+                   0,          /* orig-video-mode */
+                   80,         /* orig-video-cols */
+                   0, 0, 0,    /* ega_ax, ega_bx, ega_cx */
+                   25,         /* orig-video-lines */
+                   VIDEO_TYPE_VGAC,    /* orig-video-isVGA */
+                   16          /* orig-video-points */
+       };
+#elif defined(CONFIG_DUMMY_CONSOLE)
+       conswitchp = &dummy_con;
+#endif
+#endif
+
+}
diff --git a/arch/mips/lib-32/Makefile b/arch/mips/lib-32/Makefile
deleted file mode 100644 (file)
index 8b94d4c..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Makefile for MIPS-specific library files..
-#
-
-lib-y  += watch.o
-
-obj-$(CONFIG_CPU_MIPS32)       += dump_tlb.o
-obj-$(CONFIG_CPU_MIPS64)       += dump_tlb.o
-obj-$(CONFIG_CPU_NEVADA)       += dump_tlb.o
-obj-$(CONFIG_CPU_R10000)       += dump_tlb.o
-obj-$(CONFIG_CPU_R3000)                += r3k_dump_tlb.o
-obj-$(CONFIG_CPU_R4300)                += dump_tlb.o
-obj-$(CONFIG_CPU_R4X00)                += dump_tlb.o
-obj-$(CONFIG_CPU_R5000)                += dump_tlb.o
-obj-$(CONFIG_CPU_R5432)                += dump_tlb.o
-obj-$(CONFIG_CPU_R6000)                +=
-obj-$(CONFIG_CPU_R8000)                +=
-obj-$(CONFIG_CPU_RM7000)       += dump_tlb.o
-obj-$(CONFIG_CPU_RM9000)       += dump_tlb.o
-obj-$(CONFIG_CPU_SB1)          += dump_tlb.o
-obj-$(CONFIG_CPU_TX39XX)       += r3k_dump_tlb.o
-obj-$(CONFIG_CPU_TX49XX)       += dump_tlb.o
-obj-$(CONFIG_CPU_VR41XX)       += dump_tlb.o
diff --git a/arch/mips/lib-32/dump_tlb.c b/arch/mips/lib-32/dump_tlb.c
deleted file mode 100644 (file)
index 6a68deb..0000000
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Dump R4x00 TLB for debugging purposes.
- *
- * Copyright (C) 1994, 1995 by Waldorf Electronics, written by Ralf Baechle.
- * Copyright (C) 1999 by Silicon Graphics, Inc.
- */
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-
-#include <asm/bootinfo.h>
-#include <asm/cachectl.h>
-#include <asm/cpu.h>
-#include <asm/mipsregs.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-
-static inline const char *msk2str(unsigned int mask)
-{
-       switch (mask) {
-       case PM_4K:
-               return "4kb";
-       case PM_16K:
-               return "16kb";
-       case PM_64K:
-               return "64kb";
-       case PM_256K:
-               return "256kb";
-#ifndef CONFIG_CPU_VR41XX
-       case PM_1M:
-               return "1Mb";
-       case PM_4M:
-               return "4Mb";
-       case PM_16M:
-               return "16Mb";
-       case PM_64M:
-               return "64Mb";
-       case PM_256M:
-               return "256Mb";
-#endif
-       }
-
-       return "unknown";
-}
-
-#define BARRIER()                                      \
-       __asm__ __volatile__(                           \
-               ".set\tnoreorder\n\t"                   \
-               "nop;nop;nop;nop;nop;nop;nop\n\t"       \
-               ".set\treorder");
-
-void dump_tlb(int first, int last)
-{
-       unsigned int pagemask, c0, c1, asid;
-       unsigned long long entrylo0, entrylo1;
-       unsigned long entryhi;
-       int i;
-
-       asid = read_c0_entryhi() & 0xff;
-
-       printk("\n");
-       for (i = first; i <= last; i++) {
-               write_c0_index(i);
-               BARRIER();
-               tlb_read();
-               BARRIER();
-               pagemask = read_c0_pagemask();
-               entryhi = read_c0_entryhi();
-               entrylo0 = read_c0_entrylo0();
-               entrylo1 = read_c0_entrylo1();
-
-               /* Unused entries have a virtual address in KSEG0.  */
-               if ((entryhi & 0xf0000000) != 0x80000000
-                   && (entryhi & 0xff) == asid) {
-                       /*
-                        * Only print entries in use
-                        */
-                       printk("Index: %2d pgmask=%s ", i, msk2str(pagemask));
-
-                       c0 = (entrylo0 >> 3) & 7;
-                       c1 = (entrylo1 >> 3) & 7;
-
-                       printk("va=%08lx asid=%02lx\n",
-                              (entryhi & 0xffffe000), (entryhi & 0xff));
-                       printk("\t\t\t[pa=%08Lx c=%d d=%d v=%d g=%Ld]\n",
-                              (entrylo0 << 6) & PAGE_MASK, c0,
-                              (entrylo0 & 4) ? 1 : 0,
-                              (entrylo0 & 2) ? 1 : 0, (entrylo0 & 1));
-                       printk("\t\t\t[pa=%08Lx c=%d d=%d v=%d g=%Ld]\n",
-                              (entrylo1 << 6) & PAGE_MASK, c1,
-                              (entrylo1 & 4) ? 1 : 0,
-                              (entrylo1 & 2) ? 1 : 0, (entrylo1 & 1));
-                       printk("\n");
-               }
-       }
-
-       write_c0_entryhi(asid);
-}
-
-void dump_tlb_all(void)
-{
-       dump_tlb(0, current_cpu_data.tlbsize - 1);
-}
-
-void dump_tlb_wired(void)
-{
-       int wired;
-
-       wired = read_c0_wired();
-       printk("Wired: %d", wired);
-       dump_tlb(0, read_c0_wired());
-}
-
-void dump_tlb_addr(unsigned long addr)
-{
-       unsigned int flags, oldpid;
-       int index;
-
-       local_irq_save(flags);
-       oldpid = read_c0_entryhi() & 0xff;
-       BARRIER();
-       write_c0_entryhi((addr & PAGE_MASK) | oldpid);
-       BARRIER();
-       tlb_probe();
-       BARRIER();
-       index = read_c0_index();
-       write_c0_entryhi(oldpid);
-       local_irq_restore(flags);
-
-       if (index < 0) {
-               printk("No entry for address 0x%08lx in TLB\n", addr);
-               return;
-       }
-
-       printk("Entry %d maps address 0x%08lx\n", index, addr);
-       dump_tlb(index, index);
-}
-
-void dump_tlb_nonwired(void)
-{
-       dump_tlb(read_c0_wired(), current_cpu_data.tlbsize - 1);
-}
-
-void dump_list_process(struct task_struct *t, void *address)
-{
-       pgd_t *page_dir, *pgd;
-       pud_t *pud;
-       pmd_t *pmd;
-       pte_t *pte, page;
-       unsigned long addr, val;
-
-       addr = (unsigned long) address;
-
-       printk("Addr                 == %08lx\n", addr);
-       printk("task                 == %8p\n", t);
-       printk("task->mm             == %8p\n", t->mm);
-       //printk("tasks->mm.pgd        == %08x\n", (unsigned int) t->mm->pgd);
-
-       if (addr > KSEG0) {
-               page_dir = pgd_offset_k(0);
-               pgd = pgd_offset_k(addr);
-       } else if (t->mm) {
-               page_dir = pgd_offset(t->mm, 0);
-               pgd = pgd_offset(t->mm, addr);
-       } else {
-               printk("Current thread has no mm\n");
-               return;
-       }
-       printk("page_dir == %08x\n", (unsigned int) page_dir);
-       printk("pgd == %08x, ", (unsigned int) pgd);
-       pud = pud_offset(pgd, addr);
-       printk("pud == %08x, ", (unsigned int) pud);
-
-       pmd = pmd_offset(pud, addr);
-       printk("pmd == %08x, ", (unsigned int) pmd);
-
-       pte = pte_offset(pmd, addr);
-       printk("pte == %08x, ", (unsigned int) pte);
-
-       page = *pte;
-#ifdef CONFIG_64BIT_PHYS_ADDR
-       printk("page == %08Lx\n", pte_val(page));
-#else
-       printk("page == %08lx\n", pte_val(page));
-#endif
-
-       val = pte_val(page);
-       if (val & _PAGE_PRESENT)
-               printk("present ");
-       if (val & _PAGE_READ)
-               printk("read ");
-       if (val & _PAGE_WRITE)
-               printk("write ");
-       if (val & _PAGE_ACCESSED)
-               printk("accessed ");
-       if (val & _PAGE_MODIFIED)
-               printk("modified ");
-       if (val & _PAGE_R4KBUG)
-               printk("r4kbug ");
-       if (val & _PAGE_GLOBAL)
-               printk("global ");
-       if (val & _PAGE_VALID)
-               printk("valid ");
-       printk("\n");
-}
-
-void dump_list_current(void *address)
-{
-       dump_list_process(current, address);
-}
-
-unsigned int vtop(void *address)
-{
-       pgd_t *pgd;
-       pud_t *pud;
-       pmd_t *pmd;
-       pte_t *pte;
-       unsigned int addr, paddr;
-
-       addr = (unsigned long) address;
-       pgd = pgd_offset(current->mm, addr);
-       pud = pud_offset(pgd, addr);
-       pmd = pmd_offset(pud, addr);
-       pte = pte_offset(pmd, addr);
-       paddr = (KSEG1 | (unsigned int) pte_val(*pte)) & PAGE_MASK;
-       paddr |= (addr & ~PAGE_MASK);
-
-       return paddr;
-}
-
-void dump16(unsigned long *p)
-{
-       int i;
-
-       for (i = 0; i < 8; i++) {
-               printk("*%08lx == %08lx, ", (unsigned long) p, *p);
-               p++;
-               printk("*%08lx == %08lx\n", (unsigned long) p, *p);
-               p++;
-       }
-}
diff --git a/arch/mips/lib-32/r3k_dump_tlb.c b/arch/mips/lib-32/r3k_dump_tlb.c
deleted file mode 100644 (file)
index 4f2cb74..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Dump R3000 TLB for debugging purposes.
- *
- * Copyright (C) 1994, 1995 by Waldorf Electronics, written by Ralf Baechle.
- * Copyright (C) 1999 by Silicon Graphics, Inc.
- * Copyright (C) 1999 by Harald Koerfgen
- */
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-
-#include <asm/bootinfo.h>
-#include <asm/cachectl.h>
-#include <asm/cpu.h>
-#include <asm/mipsregs.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-
-extern int r3k_have_wired_reg; /* defined in tlb-r3k.c */
-
-void dump_tlb(int first, int last)
-{
-       int     i;
-       unsigned int asid;
-       unsigned long entryhi, entrylo0;
-
-       asid = read_c0_entryhi() & 0xfc0;
-
-       for (i = first; i <= last; i++) {
-               write_c0_index(i<<8);
-               __asm__ __volatile__(
-                       ".set\tnoreorder\n\t"
-                       "tlbr\n\t"
-                       "nop\n\t"
-                       ".set\treorder");
-               entryhi  = read_c0_entryhi();
-               entrylo0 = read_c0_entrylo0();
-
-               /* Unused entries have a virtual address of KSEG0.  */
-               if ((entryhi & 0xffffe000) != 0x80000000
-                   && (entryhi & 0xfc0) == asid) {
-                       /*
-                        * Only print entries in use
-                        */
-                       printk("Index: %2d ", i);
-
-                       printk("va=%08lx asid=%08lx"
-                              "  [pa=%06lx n=%d d=%d v=%d g=%d]",
-                              (entryhi & 0xffffe000),
-                              entryhi & 0xfc0,
-                              entrylo0 & PAGE_MASK,
-                              (entrylo0 & (1 << 11)) ? 1 : 0,
-                              (entrylo0 & (1 << 10)) ? 1 : 0,
-                              (entrylo0 & (1 << 9)) ? 1 : 0,
-                              (entrylo0 & (1 << 8)) ? 1 : 0);
-               }
-       }
-       printk("\n");
-
-       write_c0_entryhi(asid);
-}
-
-void dump_tlb_all(void)
-{
-       dump_tlb(0, current_cpu_data.tlbsize - 1);
-}
-
-void dump_tlb_wired(void)
-{
-       int wired = r3k_have_wired_reg ? read_c0_wired() : 8;
-
-       printk("Wired: %d", wired);
-       dump_tlb(0, wired - 1);
-}
-
-void dump_tlb_addr(unsigned long addr)
-{
-       unsigned long flags, oldpid;
-       int index;
-
-       local_irq_save(flags);
-       oldpid = read_c0_entryhi() & 0xff;
-       write_c0_entryhi((addr & PAGE_MASK) | oldpid);
-       tlb_probe();
-       index = read_c0_index();
-       write_c0_entryhi(oldpid);
-       local_irq_restore(flags);
-
-       if (index < 0) {
-               printk("No entry for address 0x%08lx in TLB\n", addr);
-               return;
-       }
-
-       printk("Entry %d maps address 0x%08lx\n", index, addr);
-       dump_tlb(index, index);
-}
-
-void dump_tlb_nonwired(void)
-{
-       int wired = r3k_have_wired_reg ? read_c0_wired() : 8;
-       dump_tlb(wired, current_cpu_data.tlbsize - 1);
-}
-
-void dump_list_process(struct task_struct *t, void *address)
-{
-       pgd_t   *page_dir, *pgd;
-       pud_t   *pud;
-       pmd_t   *pmd;
-       pte_t   *pte, page;
-       unsigned int addr;
-       unsigned long val;
-
-       addr = (unsigned int) address;
-
-       printk("Addr                 == %08x\n", addr);
-       printk("tasks->mm.pgd        == %08x\n", (unsigned int) t->mm->pgd);
-
-       page_dir = pgd_offset(t->mm, 0);
-       printk("page_dir == %08x\n", (unsigned int) page_dir);
-
-       pgd = pgd_offset(t->mm, addr);
-       printk("pgd == %08x, ", (unsigned int) pgd);
-
-       pud = pud_offset(pgd, addr);
-       printk("pud == %08x, ", (unsigned int) pud);
-
-       pmd = pmd_offset(pud, addr);
-       printk("pmd == %08x, ", (unsigned int) pmd);
-
-       pte = pte_offset(pmd, addr);
-       printk("pte == %08x, ", (unsigned int) pte);
-
-       page = *pte;
-       printk("page == %08x\n", (unsigned int) pte_val(page));
-
-       val = pte_val(page);
-       if (val & _PAGE_PRESENT) printk("present ");
-       if (val & _PAGE_READ) printk("read ");
-       if (val & _PAGE_WRITE) printk("write ");
-       if (val & _PAGE_ACCESSED) printk("accessed ");
-       if (val & _PAGE_MODIFIED) printk("modified ");
-       if (val & _PAGE_GLOBAL) printk("global ");
-       if (val & _PAGE_VALID) printk("valid ");
-       printk("\n");
-}
-
-void dump_list_current(void *address)
-{
-       dump_list_process(current, address);
-}
-
-unsigned int vtop(void *address)
-{
-       pgd_t   *pgd;
-       pud_t   *pud;
-       pmd_t   *pmd;
-       pte_t   *pte;
-       unsigned int addr, paddr;
-
-       addr = (unsigned long) address;
-       pgd = pgd_offset(current->mm, addr);
-       pud = pud_offset(pgd, addr);
-       pmd = pmd_offset(pud, addr);
-       pte = pte_offset(pmd, addr);
-       paddr = (KSEG1 | (unsigned int) pte_val(*pte)) & PAGE_MASK;
-       paddr |= (addr & ~PAGE_MASK);
-
-       return paddr;
-}
-
-void dump16(unsigned long *p)
-{
-       int i;
-
-       for (i = 0; i < 8; i++) {
-               printk("*%08lx == %08lx, ", (unsigned long)p, *p);
-               p++;
-               printk("*%08lx == %08lx\n", (unsigned long)p, *p);
-               p++;
-       }
-}
diff --git a/arch/mips/lib-32/watch.S b/arch/mips/lib-32/watch.S
deleted file mode 100644 (file)
index 808b3af..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Kernel debug stuff to use the Watch registers.
- * Useful to find stack overflows, dangling pointers etc.
- *
- * Copyright (C) 1995, 1996, 1999 by Ralf Baechle
- */
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/regdef.h>
-
-               .set    noreorder
-/*
- * Parameter: a0 - logic address to watch
- *                 Currently only KSEG0 addresses are allowed!
- *            a1 - set bit #1 to trap on load references
- *                     bit #0 to trap on store references
- * Results  : none
- */
-               LEAF(__watch_set)
-               li      t0, 0x80000000
-               subu    a0, t0
-               ori     a0, 7
-               xori    a0, 7
-               or      a0, a1
-               mtc0    a0, CP0_WATCHLO
-               sw      a0, watch_savelo
-
-               jr      ra
-                mtc0   zero, CP0_WATCHHI
-               END(__watch_set)
-
-/*
- * Parameter: none
- * Results  : none
- */
-               LEAF(__watch_clear)
-               jr      ra
-                mtc0   zero, CP0_WATCHLO
-               END(__watch_clear)
-
-/*
- * Parameter: none
- * Results  : none
- */
-               LEAF(__watch_reenable)
-               lw      t0, watch_savelo
-               jr      ra
-                mtc0   t0, CP0_WATCHLO
-               END(__watch_reenable)
-
-/*
- * Saved value of the c0_watchlo register for watch_reenable()
- */
-               .data
-watch_savelo:  .word   0
-               .text
diff --git a/arch/mips/lib-64/Makefile b/arch/mips/lib-64/Makefile
deleted file mode 100644 (file)
index 8b94d4c..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Makefile for MIPS-specific library files..
-#
-
-lib-y  += watch.o
-
-obj-$(CONFIG_CPU_MIPS32)       += dump_tlb.o
-obj-$(CONFIG_CPU_MIPS64)       += dump_tlb.o
-obj-$(CONFIG_CPU_NEVADA)       += dump_tlb.o
-obj-$(CONFIG_CPU_R10000)       += dump_tlb.o
-obj-$(CONFIG_CPU_R3000)                += r3k_dump_tlb.o
-obj-$(CONFIG_CPU_R4300)                += dump_tlb.o
-obj-$(CONFIG_CPU_R4X00)                += dump_tlb.o
-obj-$(CONFIG_CPU_R5000)                += dump_tlb.o
-obj-$(CONFIG_CPU_R5432)                += dump_tlb.o
-obj-$(CONFIG_CPU_R6000)                +=
-obj-$(CONFIG_CPU_R8000)                +=
-obj-$(CONFIG_CPU_RM7000)       += dump_tlb.o
-obj-$(CONFIG_CPU_RM9000)       += dump_tlb.o
-obj-$(CONFIG_CPU_SB1)          += dump_tlb.o
-obj-$(CONFIG_CPU_TX39XX)       += r3k_dump_tlb.o
-obj-$(CONFIG_CPU_TX49XX)       += dump_tlb.o
-obj-$(CONFIG_CPU_VR41XX)       += dump_tlb.o
diff --git a/arch/mips/lib-64/dump_tlb.c b/arch/mips/lib-64/dump_tlb.c
deleted file mode 100644 (file)
index 594df1a..0000000
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Dump R4x00 TLB for debugging purposes.
- *
- * Copyright (C) 1994, 1995 by Waldorf Electronics, written by Ralf Baechle.
- * Copyright (C) 1999 by Silicon Graphics, Inc.
- */
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-
-#include <asm/bootinfo.h>
-#include <asm/cachectl.h>
-#include <asm/cpu.h>
-#include <asm/mipsregs.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-
-static inline const char *msk2str(unsigned int mask)
-{
-       switch (mask) {
-       case PM_4K:     return "4kb";
-       case PM_16K:    return "16kb";
-       case PM_64K:    return "64kb";
-       case PM_256K:   return "256kb";
-#ifndef CONFIG_CPU_VR41XX
-       case PM_1M:     return "1Mb";
-       case PM_4M:     return "4Mb";
-       case PM_16M:    return "16Mb";
-       case PM_64M:    return "64Mb";
-       case PM_256M:   return "256Mb";
-#endif
-       }
-
-       return "unknown";
-}
-
-#define BARRIER()                                      \
-       __asm__ __volatile__(                           \
-               ".set\tnoreorder\n\t"                   \
-               "nop;nop;nop;nop;nop;nop;nop\n\t"       \
-               ".set\treorder");
-
-void dump_tlb(int first, int last)
-{
-       unsigned long s_entryhi, entryhi, entrylo0, entrylo1, asid;
-       unsigned int s_index, pagemask, c0, c1, i;
-
-       s_entryhi = read_c0_entryhi();
-       s_index = read_c0_index();
-       asid = s_entryhi & 0xff;
-
-       for (i = first; i <= last; i++) {
-               write_c0_index(i);
-               BARRIER();
-               tlb_read();
-               BARRIER();
-               pagemask = read_c0_pagemask();
-               entryhi  = read_c0_entryhi();
-               entrylo0 = read_c0_entrylo0();
-               entrylo1 = read_c0_entrylo1();
-
-               /* Unused entries have a virtual address of CKSEG0.  */
-               if ((entryhi & ~0x1ffffUL) != CKSEG0
-                   && (entryhi & 0xff) == asid) {
-                       /*
-                        * Only print entries in use
-                        */
-                       printk("Index: %2d pgmask=%s ", i, msk2str(pagemask));
-
-                       c0 = (entrylo0 >> 3) & 7;
-                       c1 = (entrylo1 >> 3) & 7;
-
-                       printk("va=%011lx asid=%02lx\n",
-                              (entryhi & ~0x1fffUL),
-                              entryhi & 0xff);
-                       printk("\t[pa=%011lx c=%d d=%d v=%d g=%ld] ",
-                              (entrylo0 << 6) & PAGE_MASK, c0,
-                              (entrylo0 & 4) ? 1 : 0,
-                              (entrylo0 & 2) ? 1 : 0,
-                              (entrylo0 & 1));
-                       printk("[pa=%011lx c=%d d=%d v=%d g=%ld]\n",
-                              (entrylo1 << 6) & PAGE_MASK, c1,
-                              (entrylo1 & 4) ? 1 : 0,
-                              (entrylo1 & 2) ? 1 : 0,
-                              (entrylo1 & 1));
-               }
-       }
-       printk("\n");
-
-       write_c0_entryhi(s_entryhi);
-       write_c0_index(s_index);
-}
-
-void dump_tlb_all(void)
-{
-       dump_tlb(0, current_cpu_data.tlbsize - 1);
-}
-
-void dump_tlb_wired(void)
-{
-       int     wired;
-
-       wired = read_c0_wired();
-       printk("Wired: %d", wired);
-       dump_tlb(0, read_c0_wired());
-}
-
-void dump_tlb_addr(unsigned long addr)
-{
-       unsigned int flags, oldpid;
-       int index;
-
-       local_irq_save(flags);
-       oldpid = read_c0_entryhi() & 0xff;
-       BARRIER();
-       write_c0_entryhi((addr & PAGE_MASK) | oldpid);
-       BARRIER();
-       tlb_probe();
-       BARRIER();
-       index = read_c0_index();
-       write_c0_entryhi(oldpid);
-       local_irq_restore(flags);
-
-       if (index < 0) {
-               printk("No entry for address 0x%08lx in TLB\n", addr);
-               return;
-       }
-
-       printk("Entry %d maps address 0x%08lx\n", index, addr);
-       dump_tlb(index, index);
-}
-
-void dump_tlb_nonwired(void)
-{
-       dump_tlb(read_c0_wired(), current_cpu_data.tlbsize - 1);
-}
-
-void dump_list_process(struct task_struct *t, void *address)
-{
-       pgd_t   *page_dir, *pgd;
-       pud_t   *pud;
-       pmd_t   *pmd;
-       pte_t   *pte, page;
-       unsigned long addr, val;
-
-       addr = (unsigned long) address;
-
-       printk("Addr                 == %08lx\n", addr);
-       printk("tasks->mm.pgd        == %08lx\n", (unsigned long) t->mm->pgd);
-
-       page_dir = pgd_offset(t->mm, 0UL);
-       printk("page_dir == %016lx\n", (unsigned long) page_dir);
-
-       pgd = pgd_offset(t->mm, addr);
-       printk("pgd == %016lx\n", (unsigned long) pgd);
-
-       pud = pud_offset(pgd, addr);
-       printk("pud == %016lx\n", (unsigned long) pud);
-
-       pmd = pmd_offset(pud, addr);
-       printk("pmd == %016lx\n", (unsigned long) pmd);
-
-       pte = pte_offset(pmd, addr);
-       printk("pte == %016lx\n", (unsigned long) pte);
-
-       page = *pte;
-       printk("page == %08lx\n", pte_val(page));
-
-       val = pte_val(page);
-       if (val & _PAGE_PRESENT) printk("present ");
-       if (val & _PAGE_READ) printk("read ");
-       if (val & _PAGE_WRITE) printk("write ");
-       if (val & _PAGE_ACCESSED) printk("accessed ");
-       if (val & _PAGE_MODIFIED) printk("modified ");
-       if (val & _PAGE_R4KBUG) printk("r4kbug ");
-       if (val & _PAGE_GLOBAL) printk("global ");
-       if (val & _PAGE_VALID) printk("valid ");
-       printk("\n");
-}
-
-void dump_list_current(void *address)
-{
-       dump_list_process(current, address);
-}
-
-unsigned long vtop(void *address)
-{
-       pgd_t   *pgd;
-       pud_t   *pud;
-       pmd_t   *pmd;
-       pte_t   *pte;
-       unsigned long addr, paddr;
-
-       addr = (unsigned long) address;
-       pgd = pgd_offset(current->mm, addr);
-       pud = pud_offset(pgd, addr);
-       pmd = pmd_offset(pud, addr);
-       pte = pte_offset(pmd, addr);
-       paddr = (CKSEG1 | (unsigned int) pte_val(*pte)) & PAGE_MASK;
-       paddr |= (addr & ~PAGE_MASK);
-
-       return paddr;
-}
-
-void dump16(unsigned long *p)
-{
-       int i;
-
-       for (i = 0; i < 8; i++) {
-               printk("*%08lx == %08lx, ", (unsigned long)p, *p);
-               p++;
-               printk("*%08lx == %08lx\n", (unsigned long)p, *p);
-               p++;
-       }
-}
diff --git a/arch/mips/lib-64/watch.S b/arch/mips/lib-64/watch.S
deleted file mode 100644 (file)
index f914340..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Kernel debug stuff to use the Watch registers.
- * Useful to find stack overflows, dangling pointers etc.
- *
- * Copyright (C) 1995, 1996, 1999, 2001 by Ralf Baechle
- */
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/regdef.h>
-
-               .set    noreorder
-/*
- * Parameter: a0 - physical address to watch
- *            a1 - set bit #1 to trap on load references
- *                     bit #0 to trap on store references
- * Results  : none
- */
-               LEAF(__watch_set)
-               ori     a0, 7
-               xori    a0, 7
-               or      a0, a1
-               mtc0    a0, CP0_WATCHLO
-               sd      a0, watch_savelo
-               dsrl32  a0, a0, 0
-
-               jr      ra
-                mtc0   zero, CP0_WATCHHI
-               END(__watch_set)
-
-/*
- * Parameter: none
- * Results  : none
- */
-               LEAF(__watch_clear)
-               jr      ra
-                mtc0   zero, CP0_WATCHLO
-               END(__watch_clear)
-
-/*
- * Parameter: none
- * Results  : none
- */
-               LEAF(__watch_reenable)
-               ld      t0, watch_savelo
-               jr      ra
-                mtc0   t0, CP0_WATCHLO
-               END(__watch_reenable)
-
-/*
- * Saved value of the c0_watchlo register for watch_reenable()
- */
-               .local  watch_savelo
-               .comm   watch_savelo, 8, 8
index 1c1aa9f92f6c0ebbbd7781009e03002304c5a364..91ed1eb331020f0f1ba5c4e718ffa975ef9a9330 100644 (file)
@@ -8,5 +8,24 @@ lib-y  += csum_partial.o memcpy.o memcpy-inatomic.o memset.o strlen_user.o \
 obj-y                  += iomap.o
 obj-$(CONFIG_PCI)      += iomap-pci.o
 
+obj-$(CONFIG_CPU_LOONGSON2)    += dump_tlb.o
+obj-$(CONFIG_CPU_MIPS32)       += dump_tlb.o
+obj-$(CONFIG_CPU_MIPS64)       += dump_tlb.o
+obj-$(CONFIG_CPU_NEVADA)       += dump_tlb.o
+obj-$(CONFIG_CPU_R10000)       += dump_tlb.o
+obj-$(CONFIG_CPU_R3000)                += r3k_dump_tlb.o
+obj-$(CONFIG_CPU_R4300)                += dump_tlb.o
+obj-$(CONFIG_CPU_R4X00)                += dump_tlb.o
+obj-$(CONFIG_CPU_R5000)                += dump_tlb.o
+obj-$(CONFIG_CPU_R5432)                += dump_tlb.o
+obj-$(CONFIG_CPU_R6000)                +=
+obj-$(CONFIG_CPU_R8000)                +=
+obj-$(CONFIG_CPU_RM7000)       += dump_tlb.o
+obj-$(CONFIG_CPU_RM9000)       += dump_tlb.o
+obj-$(CONFIG_CPU_SB1)          += dump_tlb.o
+obj-$(CONFIG_CPU_TX39XX)       += r3k_dump_tlb.o
+obj-$(CONFIG_CPU_TX49XX)       += dump_tlb.o
+obj-$(CONFIG_CPU_VR41XX)       += dump_tlb.o
+
 # libgcc-style stuff needed in the kernel
 obj-y += ashldi3.o ashrdi3.o lshrdi3.o ucmpdi2.o
diff --git a/arch/mips/lib/dump_tlb.c b/arch/mips/lib/dump_tlb.c
new file mode 100644 (file)
index 0000000..465ff0e
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * Dump R4x00 TLB for debugging purposes.
+ *
+ * Copyright (C) 1994, 1995 by Waldorf Electronics, written by Ralf Baechle.
+ * Copyright (C) 1999 by Silicon Graphics, Inc.
+ */
+#include <linux/kernel.h>
+#include <linux/mm.h>
+
+#include <asm/mipsregs.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/tlbdebug.h>
+
+static inline const char *msk2str(unsigned int mask)
+{
+       switch (mask) {
+       case PM_4K:     return "4kb";
+       case PM_16K:    return "16kb";
+       case PM_64K:    return "64kb";
+       case PM_256K:   return "256kb";
+#ifndef CONFIG_CPU_VR41XX
+       case PM_1M:     return "1Mb";
+       case PM_4M:     return "4Mb";
+       case PM_16M:    return "16Mb";
+       case PM_64M:    return "64Mb";
+       case PM_256M:   return "256Mb";
+#endif
+       }
+       return "";
+}
+
+#define BARRIER()                                      \
+       __asm__ __volatile__(                           \
+               ".set\tnoreorder\n\t"                   \
+               "nop;nop;nop;nop;nop;nop;nop\n\t"       \
+               ".set\treorder");
+
+static void dump_tlb(int first, int last)
+{
+       unsigned long s_entryhi, entryhi, asid;
+       unsigned long long entrylo0, entrylo1;
+       unsigned int s_index, pagemask, c0, c1, i;
+
+       s_entryhi = read_c0_entryhi();
+       s_index = read_c0_index();
+       asid = s_entryhi & 0xff;
+
+       for (i = first; i <= last; i++) {
+               write_c0_index(i);
+               BARRIER();
+               tlb_read();
+               BARRIER();
+               pagemask = read_c0_pagemask();
+               entryhi  = read_c0_entryhi();
+               entrylo0 = read_c0_entrylo0();
+               entrylo1 = read_c0_entrylo1();
+
+               /* Unused entries have a virtual address of CKSEG0.  */
+               if ((entryhi & ~0x1ffffUL) != CKSEG0
+                   && (entryhi & 0xff) == asid) {
+#ifdef CONFIG_32BIT
+                       int width = 8;
+#else
+                       int width = 11;
+#endif
+                       /*
+                        * Only print entries in use
+                        */
+                       printk("Index: %2d pgmask=%s ", i, msk2str(pagemask));
+
+                       c0 = (entrylo0 >> 3) & 7;
+                       c1 = (entrylo1 >> 3) & 7;
+
+                       printk("va=%0*lx asid=%02lx\n",
+                              width, (entryhi & ~0x1fffUL),
+                              entryhi & 0xff);
+                       printk("\t[pa=%0*llx c=%d d=%d v=%d g=%d] ",
+                              width,
+                              (entrylo0 << 6) & PAGE_MASK, c0,
+                              (entrylo0 & 4) ? 1 : 0,
+                              (entrylo0 & 2) ? 1 : 0,
+                              (entrylo0 & 1) ? 1 : 0);
+                       printk("[pa=%0*llx c=%d d=%d v=%d g=%d]\n",
+                              width,
+                              (entrylo1 << 6) & PAGE_MASK, c1,
+                              (entrylo1 & 4) ? 1 : 0,
+                              (entrylo1 & 2) ? 1 : 0,
+                              (entrylo1 & 1) ? 1 : 0);
+               }
+       }
+       printk("\n");
+
+       write_c0_entryhi(s_entryhi);
+       write_c0_index(s_index);
+}
+
+void dump_tlb_all(void)
+{
+       dump_tlb(0, current_cpu_data.tlbsize - 1);
+}
diff --git a/arch/mips/lib/r3k_dump_tlb.c b/arch/mips/lib/r3k_dump_tlb.c
new file mode 100644 (file)
index 0000000..9cee907
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Dump R3000 TLB for debugging purposes.
+ *
+ * Copyright (C) 1994, 1995 by Waldorf Electronics, written by Ralf Baechle.
+ * Copyright (C) 1999 by Silicon Graphics, Inc.
+ * Copyright (C) 1999 by Harald Koerfgen
+ */
+#include <linux/kernel.h>
+#include <linux/mm.h>
+
+#include <asm/mipsregs.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/tlbdebug.h>
+
+extern int r3k_have_wired_reg; /* defined in tlb-r3k.c */
+
+static void dump_tlb(int first, int last)
+{
+       int     i;
+       unsigned int asid;
+       unsigned long entryhi, entrylo0;
+
+       asid = read_c0_entryhi() & 0xfc0;
+
+       for (i = first; i <= last; i++) {
+               write_c0_index(i<<8);
+               __asm__ __volatile__(
+                       ".set\tnoreorder\n\t"
+                       "tlbr\n\t"
+                       "nop\n\t"
+                       ".set\treorder");
+               entryhi  = read_c0_entryhi();
+               entrylo0 = read_c0_entrylo0();
+
+               /* Unused entries have a virtual address of KSEG0.  */
+               if ((entryhi & 0xffffe000) != 0x80000000
+                   && (entryhi & 0xfc0) == asid) {
+                       /*
+                        * Only print entries in use
+                        */
+                       printk("Index: %2d ", i);
+
+                       printk("va=%08lx asid=%08lx"
+                              "  [pa=%06lx n=%d d=%d v=%d g=%d]",
+                              (entryhi & 0xffffe000),
+                              entryhi & 0xfc0,
+                              entrylo0 & PAGE_MASK,
+                              (entrylo0 & (1 << 11)) ? 1 : 0,
+                              (entrylo0 & (1 << 10)) ? 1 : 0,
+                              (entrylo0 & (1 << 9)) ? 1 : 0,
+                              (entrylo0 & (1 << 8)) ? 1 : 0);
+               }
+       }
+       printk("\n");
+
+       write_c0_entryhi(asid);
+}
+
+void dump_tlb_all(void)
+{
+       dump_tlb(0, current_cpu_data.tlbsize - 1);
+}
index 2388f7f3ffde9c2bffd45744f9f8adaacfd10048..58d14f4d9349c3f8b9890c56551c02f8f35737d4 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <asm/addrspace.h>
 #include <asm/bug.h>
+#include <asm/cacheflush.h>
 
 #ifndef CKSEG2
 #define CKSEG2 CKSSEG
index 80531b35cd61e315382e2d036eaff313e94973f8..17419e11ecad761e2db48990c91997a51b27d2a3 100644 (file)
@@ -35,6 +35,7 @@
  * better performance by compiling with -msoft-float!
  */
 #include <linux/sched.h>
+#include <linux/debugfs.h>
 
 #include <asm/inst.h>
 #include <asm/bootinfo.h>
@@ -204,7 +205,7 @@ static int isBranchInstr(mips_instruction * i)
 static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
 {
        mips_instruction ir;
-       void * emulpc, *contpc;
+       unsigned long emulpc, contpc;
        unsigned int cond;
 
        if (get_user(ir, (mips_instruction __user *) xcp->cp0_epc)) {
@@ -229,7 +230,7 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
                 * Linux MIPS branch emulator operates on context, updating the
                 * cp0_epc.
                 */
-               emulpc = (void *) (xcp->cp0_epc + 4);   /* Snapshot emulation target */
+               emulpc = xcp->cp0_epc + 4;      /* Snapshot emulation target */
 
                if (__compute_return_epc(xcp)) {
 #ifdef CP1DBG
@@ -243,12 +244,12 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
                        return SIGBUS;
                }
                /* __compute_return_epc() will have updated cp0_epc */
-               contpc = (void *)  xcp->cp0_epc;
+               contpc = xcp->cp0_epc;
                /* In order not to confuse ptrace() et al, tweak context */
-               xcp->cp0_epc = (unsigned long) emulpc - 4;
+               xcp->cp0_epc = emulpc - 4;
        } else {
-               emulpc = (void *)  xcp->cp0_epc;
-               contpc = (void *) (xcp->cp0_epc + 4);
+               emulpc = xcp->cp0_epc;
+               contpc = xcp->cp0_epc + 4;
        }
 
       emul:
@@ -426,8 +427,7 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
                                 * instruction
                                 */
                                xcp->cp0_epc += 4;
-                               contpc = (void *)
-                                       (xcp->cp0_epc +
+                               contpc = (xcp->cp0_epc +
                                        (MIPSInst_SIMM(ir) << 2));
 
                                if (get_user(ir,
@@ -461,7 +461,7 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
                                 * Single step the non-cp1
                                 * instruction in the dslot
                                 */
-                               return mips_dsemul(xcp, ir, (unsigned long) contpc);
+                               return mips_dsemul(xcp, ir, contpc);
                        }
                        else {
                                /* branch not taken */
@@ -520,7 +520,7 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
        }
 
        /* we did it !! */
-       xcp->cp0_epc = (unsigned long) contpc;
+       xcp->cp0_epc = contpc;
        xcp->cp0_cause &= ~CAUSEF_BD;
 
        return 0;
@@ -1277,3 +1277,36 @@ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
 
        return sig;
 }
+
+#ifdef CONFIG_DEBUG_FS
+extern struct dentry *mips_debugfs_dir;
+static int __init debugfs_fpuemu(void)
+{
+       struct dentry *d, *dir;
+       int i;
+       static struct {
+               const char *name;
+               unsigned int *v;
+       } vars[] __initdata = {
+               { "emulated", &fpuemustats.emulated },
+               { "loads",    &fpuemustats.loads },
+               { "stores",   &fpuemustats.stores },
+               { "cp1ops",   &fpuemustats.cp1ops },
+               { "cp1xops",  &fpuemustats.cp1xops },
+               { "errors",   &fpuemustats.errors },
+       };
+
+       if (!mips_debugfs_dir)
+               return -ENODEV;
+       dir = debugfs_create_dir("fpuemustats", mips_debugfs_dir);
+       if (IS_ERR(dir))
+               return PTR_ERR(dir);
+       for (i = 0; i < ARRAY_SIZE(vars); i++) {
+               d = debugfs_create_u32(vars[i].name, S_IRUGO, dir, vars[i].v);
+               if (IS_ERR(d))
+                       return PTR_ERR(d);
+       }
+       return 0;
+}
+__initcall(debugfs_fpuemu);
+#endif
index ea6ba7248489598e7376768abeef38d7a0fce632..653e325849e417d0ca2f9d646f2c850b5ffc8ec0 100644 (file)
@@ -54,8 +54,7 @@ struct emuframe {
 int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
 {
        extern asmlinkage void handle_dsemulret(void);
-       mips_instruction *dsemul_insns;
-       struct emuframe *fr;
+       struct emuframe __user *fr;
        int err;
 
        if (ir == 0) {          /* a nop is easy */
@@ -87,8 +86,8 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
         */
 
        /* Ensure that the two instructions are in the same cache line */
-       dsemul_insns = (mips_instruction *) ((regs->regs[29] - sizeof(struct emuframe)) & ~0x7);
-       fr = (struct emuframe *) dsemul_insns;
+       fr = (struct emuframe __user *)
+               ((regs->regs[29] - sizeof(struct emuframe)) & ~0x7);
 
        /* Verify that the stack pointer is not competely insane */
        if (unlikely(!access_ok(VERIFY_WRITE, fr, sizeof(struct emuframe))))
@@ -113,12 +112,13 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
 
 int do_dsemulret(struct pt_regs *xcp)
 {
-       struct emuframe *fr;
+       struct emuframe __user *fr;
        unsigned long epc;
        u32 insn, cookie;
        int err = 0;
 
-       fr = (struct emuframe *) (xcp->cp0_epc - sizeof(mips_instruction));
+       fr = (struct emuframe __user *)
+               (xcp->cp0_epc - sizeof(mips_instruction));
 
        /*
         * If we can't even access the area, something is very wrong, but we'll
index 377d9e8f250a31f717cf908ea5160c7c781d919e..a242b0fc377d07d18de9868e608917be9aa6736b 100644 (file)
@@ -19,6 +19,7 @@
 # under Linux.
 #
 
-obj-y := malta_int.o malta_setup.o
+obj-y := malta_int.o malta_platform.o malta_setup.o
+
 obj-$(CONFIG_MTD) += malta_mtd.o
 obj-$(CONFIG_MIPS_MT_SMTC) += malta_smtc.o
diff --git a/arch/mips/mips-boards/malta/malta_platform.c b/arch/mips/mips-boards/malta/malta_platform.c
new file mode 100644 (file)
index 0000000..83b9bab
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2007 MIPS Technologies, Inc.
+ *   written by Ralf Baechle (ralf@linux-mips.org)
+ *
+ * Probe driver for the Malta's UART ports:
+ *
+ *   o 2 ports in the SMC SuperIO
+ *   o 1 port in the CBUS UART, a discrete 16550 which normally is only used
+ *     for bringups.
+ *
+ * We don't use 8250_platform.c on Malta as it would result in the CBUS
+ * UART becoming ttyS0.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/serial_8250.h>
+
+#define SMC_PORT(base, int)                                            \
+{                                                                      \
+       .iobase         = base,                                         \
+       .irq            = int,                                          \
+       .uartclk        = 1843200,                                      \
+       .iotype         = UPIO_PORT,                                    \
+       .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,            \
+       .regshift       = 0,                                            \
+}
+
+#define CBUS_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP)
+
+static struct plat_serial8250_port uart8250_data[] = {
+       SMC_PORT(0x3F8, 4),
+       SMC_PORT(0x2F8, 3),
+       {
+               .mapbase        = 0x1f000900,   /* The CBUS UART */
+               .irq            = MIPS_CPU_IRQ_BASE + 2,
+               .uartclk        = 3686400,      /* Twice the usual clk! */
+               .iotype         = UPIO_MEM32,
+               .flags          = CBUS_UART_FLAGS,
+               .regshift       = 3,
+       },
+       { },
+};
+
+static struct platform_device uart8250_device = {
+       .name                   = "serial8250",
+       .id                     = PLAT8250_DEV_PLATFORM2,
+       .dev                    = {
+               .platform_data  = uart8250_data,
+       },
+};
+
+static int __init uart8250_init(void)
+{
+       return platform_device_register(&uart8250_device);
+}
+
+module_init(uart8250_init);
+
+MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("8250 UART probe driver for the Malta CBUS UART");
similarity index 98%
rename from arch/mips/mips-boards/sim/sim_console.c
rename to arch/mips/mipssim/sim_console.c
index de595a9ccb27578bb507ecc8875dc7533f67ec14..a2f41672cd5d7945b1237156d05ac31fafc7b757 100644 (file)
@@ -18,8 +18,8 @@
  *   written by Ralf Baechle
  */
 #include <linux/init.h>
+#include <linux/io.h>
 #include <linux/serial_reg.h>
-#include <asm/io.h>
 
 static inline unsigned int serial_in(int offset)
 {
diff --git a/arch/mips/mipssim/sim_int.c b/arch/mips/mipssim/sim_int.c
new file mode 100644 (file)
index 0000000..5cbc350
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 1999, 2005 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You 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/sched.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <asm/mips-boards/simint.h>
+#include <asm/irq_cpu.h>
+
+static inline int clz(unsigned long x)
+{
+       __asm__ (
+       "       .set    push                                    \n"
+       "       .set    mips32                                  \n"
+       "       clz     %0, %1                                  \n"
+       "       .set    pop                                     \n"
+       : "=r" (x)
+       : "r" (x));
+
+       return x;
+}
+
+/*
+ * Version of ffs that only looks at bits 12..15.
+ */
+static inline unsigned int irq_ffs(unsigned int pending)
+{
+#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
+       return -clz(pending) + 31 - CAUSEB_IP;
+#else
+       unsigned int a0 = 7;
+       unsigned int t0;
+
+       t0 = s0 & 0xf000;
+       t0 = t0 < 1;
+       t0 = t0 << 2;
+       a0 = a0 - t0;
+       s0 = s0 << t0;
+
+       t0 = s0 & 0xc000;
+       t0 = t0 < 1;
+       t0 = t0 << 1;
+       a0 = a0 - t0;
+       s0 = s0 << t0;
+
+       t0 = s0 & 0x8000;
+       t0 = t0 < 1;
+       /* t0 = t0 << 2; */
+       a0 = a0 - t0;
+       /* s0 = s0 << t0; */
+
+       return a0;
+#endif
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+       unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
+       int irq;
+
+       irq = irq_ffs(pending);
+
+       if (irq > 0)
+               do_IRQ(MIPS_CPU_IRQ_BASE + irq);
+       else
+               spurious_interrupt();
+}
+
+void __init arch_init_irq(void)
+{
+       mips_cpu_irq_init();
+}
similarity index 99%
rename from arch/mips/mips-boards/sim/sim_mem.c
rename to arch/mips/mipssim/sim_mem.c
index e408ef0bcd6e4af27f89ce3aba9df885a5b9dcaf..2312483eb838aa6bb3335a8eee59e15bff026b38 100644 (file)
@@ -95,7 +95,7 @@ void __init prom_meminit(void)
                size = p->size;
 
                add_memory_region(base, size, type);
-                p++;
+               p++;
        }
 }
 
similarity index 94%
rename from arch/mips/mips-boards/sim/sim_setup.c
rename to arch/mips/mipssim/sim_setup.c
index b705f09e57c311a8b6fc64fea54776a1dbd21626..60e66906be659089d4b5e07d19f30be8a5c13d64 100644 (file)
 #include <linux/init.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/irq.h>
 #include <linux/ioport.h>
+#include <linux/serial.h>
 #include <linux/tty.h>
 #include <linux/serial.h>
 #include <linux/serial_core.h>
 
 #include <asm/cpu.h>
 #include <asm/bootinfo.h>
-#include <asm/irq.h>
 #include <asm/mips-boards/generic.h>
 #include <asm/mips-boards/prom.h>
-#include <asm/serial.h>
-#include <asm/io.h>
 #include <asm/time.h>
 #include <asm/mips-boards/sim.h>
 #include <asm/mips-boards/simint.h>
@@ -62,7 +62,7 @@ void __init plat_mem_setup(void)
 #endif
 }
 
-void prom_init(void)
+void __init prom_init(void)
 {
        set_io_port_base(0xbfd00000);
 
@@ -84,7 +84,7 @@ static void __init serial_init(void)
        /* hardware int 4 - the serial int, is CPU int 6
         but poll for now */
        s.irq =  0;
-       s.uartclk = BASE_BAUD * 16;
+       s.uartclk = 1843200;
        s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
        s.iotype = UPIO_PORT;
        s.regshift = 0;
similarity index 89%
rename from arch/mips/mips-boards/sim/sim_smp.c
rename to arch/mips/mipssim/sim_smp.c
index cb47863ecf10bd915be6aa517064d1ae7a0739ac..38fa807b99f98e9d9a243db7633d5969c45a15d7 100644 (file)
 #include <linux/sched.h>
 #include <linux/cpumask.h>
 #include <linux/interrupt.h>
+#include <linux/smp.h>
+
 #include <asm/atomic.h>
 #include <asm/cpu.h>
 #include <asm/processor.h>
 #include <asm/system.h>
-#include <asm/hardirq.h>
 #include <asm/mmu_context.h>
-#include <asm/smp.h>
 #ifdef CONFIG_MIPS_MT_SMTC
 #include <asm/smtc_ipi.h>
 #endif /* CONFIG_MIPS_MT_SMTC */
@@ -73,11 +73,19 @@ void prom_init_secondary(void)
 #endif /* CONFIG_MIPS_MT_SMTC */
 }
 
+void plat_smp_setup(void)
+{
+#ifdef CONFIG_MIPS_MT_SMTC
+       if (read_c0_config3() & (1 << 2))
+               mipsmt_build_cpu_map(0);
+#endif /* CONFIG_MIPS_MT_SMTC */
+}
+
 /*
  * Platform SMP pre-initialization
  */
 
-void prom_prepare_cpus(unsigned int max_cpus)
+void plat_prepare_cpus(unsigned int max_cpus)
 {
 #ifdef CONFIG_MIPS_MT_SMTC
        /*
@@ -85,8 +93,8 @@ void prom_prepare_cpus(unsigned int max_cpus)
         * but it may be multithreaded.
         */
 
-       if (read_c0_config3() & (1<<2)) {
-               mipsmt_prepare_cpus(max_cpus);
+       if (read_c0_config3() & (1 << 2)) {
+               mipsmt_prepare_cpus();
        }
 #endif /* CONFIG_MIPS_MT_SMTC */
 }
similarity index 91%
rename from arch/mips/mips-boards/sim/sim_time.c
rename to arch/mips/mipssim/sim_time.c
index 7224ffe31d36188b97ea1d6832e9acfed79a33b9..a0f5a5dca1b20bfbd97b1dbe89587327561e544e 100644 (file)
@@ -5,10 +5,9 @@
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/mc146818rtc.h>
+#include <linux/smp.h>
 #include <linux/timex.h>
 
-#include <asm/mipsregs.h>
-#include <asm/ptrace.h>
 #include <asm/hardirq.h>
 #include <asm/div64.h>
 #include <asm/cpu.h>
@@ -16,7 +15,6 @@
 #include <asm/irq.h>
 #include <asm/mc146818-time.h>
 #include <asm/msc01_ic.h>
-#include <asm/smp.h>
 
 #include <asm/mips-boards/generic.h>
 #include <asm/mips-boards/prom.h>
@@ -37,8 +35,7 @@ irqreturn_t sim_timer_interrupt(int irq, void *dev_id)
 #ifndef CONFIG_MIPS_MT_SMTC
        if (cpu == 0) {
                timer_interrupt(irq, dev_id);
-       }
-       else {
+       } else {
                /* Everyone else needs to reset the timer int here as
                   ll_local_timer_interrupt doesn't */
                /*
@@ -76,8 +73,10 @@ irqreturn_t sim_timer_interrupt(int irq, void *dev_id)
        irq_enable_hazard();
        evpe(vpflags);
 
-       if(cpu_data[cpu].vpe_id == 0) timer_interrupt(irq, dev_id);
-       else write_c0_compare (read_c0_count() + ( mips_hpt_frequency/HZ));
+       if (cpu_data[cpu].vpe_id == 0)
+               timer_interrupt(irq, dev_id);
+       else
+               write_c0_compare (read_c0_count() + ( mips_hpt_frequency/HZ));
        smtc_timer_broadcast(cpu_data[cpu].vpe_id);
 
 #endif /* CONFIG_MIPS_MT_SMTC */
@@ -85,7 +84,8 @@ irqreturn_t sim_timer_interrupt(int irq, void *dev_id)
        /*
         * every CPU should do profiling and process accounting
         */
-       local_timer_interrupt (irq, dev_id);
+       local_timer_interrupt (irq, dev_id);
+
        return IRQ_HANDLED;
 #else
        return timer_interrupt (irq, dev_id);
@@ -152,17 +152,15 @@ void __init sim_time_init(void)
 
        local_irq_save(flags);
 
-
-        /* Set Data mode - binary. */
+       /* Set Data mode - binary. */
        CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);
 
-
        est_freq = estimate_cpu_frequency ();
 
-       printk("CPU frequency %d.%02d MHz\n", est_freq/1000000,
-              (est_freq%1000000)*100/1000000);
+       printk(KERN_INFO "CPU frequency %d.%02d MHz\n", est_freq / 1000000,
+              (est_freq % 1000000) * 100 / 1000000);
 
-        cpu_khz = est_freq / 1000;
+       cpu_khz = est_freq / 1000;
 
        local_irq_restore(flags);
 }
@@ -180,8 +178,7 @@ void __init plat_timer_setup(struct irqaction *irq)
        if (cpu_has_veic) {
                set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch);
                mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR;
-       }
-       else {
+       } else {
                if (cpu_has_vint)
                        set_vi_handler(cp0_compare_irq, mips_timer_dispatch);
                mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
index 293697b156036ba35188d4ee94a58b50fe6d9e22..19a0e544c4e97e8bad041ffa68088ec565bbb30c 100644 (file)
@@ -9,6 +9,7 @@ obj-$(CONFIG_32BIT)             += ioremap.o pgtable-32.o
 obj-$(CONFIG_64BIT)            += pgtable-64.o
 obj-$(CONFIG_HIGHMEM)          += highmem.o
 
+obj-$(CONFIG_CPU_LOONGSON2)    += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
 obj-$(CONFIG_CPU_MIPS32)       += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
 obj-$(CONFIG_CPU_MIPS64)       += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
 obj-$(CONFIG_CPU_NEVADA)       += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
index df04a315d8309d7303813338e9f6f46406288434..be96231dccb60508ba6a6cda2f1b5479625434a6 100644 (file)
@@ -335,6 +335,10 @@ static void r4k_flush_cache_all(void)
 
 static inline void local_r4k___flush_cache_all(void * args)
 {
+#if defined(CONFIG_CPU_LOONGSON2)
+       r4k_blast_scache();
+       return;
+#endif
        r4k_blast_dcache();
        r4k_blast_icache();
 
@@ -848,6 +852,24 @@ static void __init probe_pcache(void)
                c->options |= MIPS_CPU_PREFETCH;
                break;
 
+       case CPU_LOONGSON2:
+               icache_size = 1 << (12 + ((config & CONF_IC) >> 9));
+               c->icache.linesz = 16 << ((config & CONF_IB) >> 5);
+               if (prid & 0x3)
+                       c->icache.ways = 4;
+               else
+                       c->icache.ways = 2;
+               c->icache.waybit = 0;
+
+               dcache_size = 1 << (12 + ((config & CONF_DC) >> 6));
+               c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
+               if (prid & 0x3)
+                       c->dcache.ways = 4;
+               else
+                       c->dcache.ways = 2;
+               c->dcache.waybit = 0;
+               break;
+
        default:
                if (!(config & MIPS_CONF_M))
                        panic("Don't know how to probe P-caches on this cpu.");
@@ -963,6 +985,14 @@ static void __init probe_pcache(void)
                break;
        }
 
+#ifdef  CONFIG_CPU_LOONGSON2
+       /*
+        * LOONGSON2 has 4 way icache, but when using indexed cache op,
+        * one op will act on all 4 ways
+        */
+       c->icache.ways = 1;
+#endif
+
        printk("Primary instruction cache %ldkB, %s, %s, linesize %d bytes.\n",
               icache_size >> 10,
               cpu_has_vtag_icache ? "virtually tagged" : "physically tagged",
@@ -1036,6 +1066,24 @@ static int __init probe_scache(void)
        return 1;
 }
 
+#if defined(CONFIG_CPU_LOONGSON2)
+static void __init loongson2_sc_init(void)
+{
+       struct cpuinfo_mips *c = &current_cpu_data;
+
+       scache_size = 512*1024;
+       c->scache.linesz = 32;
+       c->scache.ways = 4;
+       c->scache.waybit = 0;
+       c->scache.waysize = scache_size / (c->scache.ways);
+       c->scache.sets = scache_size / (c->scache.linesz * c->scache.ways);
+       pr_info("Unified secondary cache %ldkB %s, linesize %d bytes.\n",
+              scache_size >> 10, way_string[c->scache.ways], c->scache.linesz);
+
+       c->options |= MIPS_CPU_INCLUSIVE_CACHES;
+}
+#endif
+
 extern int r5k_sc_init(void);
 extern int rm7k_sc_init(void);
 extern int mips_sc_init(void);
@@ -1085,6 +1133,12 @@ static void __init setup_scache(void)
 #endif
                return;
 
+#if defined(CONFIG_CPU_LOONGSON2)
+       case CPU_LOONGSON2:
+               loongson2_sc_init();
+               return;
+#endif
+
        default:
                if (c->isa_level == MIPS_CPU_ISA_M32R1 ||
                    c->isa_level == MIPS_CPU_ISA_M32R2 ||
index 9ea460b16bda3e3e2b25614621bd332093e14982..6f9bd7fbd481031ef45923ed98d11b02f611608b 100644 (file)
@@ -476,7 +476,7 @@ static __init void probe_cache_sizes(void)
  * memory management function pointers, as well as initialize
  * the caches and tlbs
  */
-void sb1_cache_init(void)
+void __init sb1_cache_init(void)
 {
        extern char except_vec2_sb1;
 
index abf99b1eba136b3742ff10b791c45f8d0684ed4f..81f925a9a731bbb20980ce13793f163932224ea1 100644 (file)
@@ -6,6 +6,8 @@
  * Copyright (C) 1994 - 2003, 07 by Ralf Baechle (ralf@linux-mips.org)
  * Copyright (C) 2007 MIPS Technologies, Inc.
  */
+#include <linux/fs.h>
+#include <linux/fcntl.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -164,3 +166,11 @@ void __init cpu_cache_init(void)
 
        panic(cache_panic);
 }
+
+int __weak __uncached_access(struct file *file, unsigned long addr)
+{
+       if (file->f_flags & O_SYNC)
+               return 1;
+
+       return addr >= __pa(high_memory);
+}
index 65160d4984d9352234f493824479747da20cbdda..dcd6913dc1ff2696d64bb29198169af9ad86d1c1 100644 (file)
@@ -48,6 +48,22 @@ extern void build_tlb_refill_handler(void);
 
 #endif /* CONFIG_MIPS_MT_SMTC */
 
+#if defined(CONFIG_CPU_LOONGSON2)
+/*
+ * LOONGSON2 has a 4 entry itlb which is a subset of dtlb,
+ * unfortrunately, itlb is not totally transparent to software.
+ */
+#define FLUSH_ITLB write_c0_diag(4);
+
+#define FLUSH_ITLB_VM(vma) { if ((vma)->vm_flags & VM_EXEC)  write_c0_diag(4); }
+
+#else
+
+#define FLUSH_ITLB
+#define FLUSH_ITLB_VM(vma)
+
+#endif
+
 void local_flush_tlb_all(void)
 {
        unsigned long flags;
@@ -73,6 +89,7 @@ void local_flush_tlb_all(void)
        }
        tlbw_use_hazard();
        write_c0_entryhi(old_ctx);
+       FLUSH_ITLB;
        EXIT_CRITICAL(flags);
 }
 
@@ -136,6 +153,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
                } else {
                        drop_mmu_context(mm, cpu);
                }
+               FLUSH_ITLB;
                EXIT_CRITICAL(flags);
        }
 }
@@ -178,6 +196,7 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
        } else {
                local_flush_tlb_all();
        }
+       FLUSH_ITLB;
        EXIT_CRITICAL(flags);
 }
 
@@ -210,6 +229,7 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
 
        finish:
                write_c0_entryhi(oldpid);
+               FLUSH_ITLB_VM(vma);
                EXIT_CRITICAL(flags);
        }
 }
@@ -241,7 +261,7 @@ void local_flush_tlb_one(unsigned long page)
                tlbw_use_hazard();
        }
        write_c0_entryhi(oldpid);
-
+       FLUSH_ITLB;
        EXIT_CRITICAL(flags);
 }
 
@@ -293,6 +313,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
        else
                tlb_write_indexed();
        tlbw_use_hazard();
+       FLUSH_ITLB_VM(vma);
        EXIT_CRITICAL(flags);
 }
 
index e7149290d1cb9ede4f97eeeefd2e2089c79e76a3..4ec0964b8394b141f5870198e33c01499a96c345 100644 (file)
@@ -893,6 +893,7 @@ static __init void build_tlb_write_entry(u32 **p, struct label **l,
        case CPU_4KSC:
        case CPU_20KC:
        case CPU_25KF:
+       case CPU_LOONGSON2:
                tlbw(p);
                break;
 
@@ -1276,7 +1277,8 @@ static void __init build_r4000_tlb_refill_handler(void)
         * need three, with the second nop'ed and the third being
         * unused.
         */
-#ifdef CONFIG_32BIT
+       /* Loongson2 ebase is different than r4k, we have more space */
+#if defined(CONFIG_32BIT) || defined(CONFIG_CPU_LOONGSON2)
        if ((p - tlb_handler) > 64)
                panic("TLB refill handler space exceeded");
 #else
@@ -1289,7 +1291,7 @@ static void __init build_r4000_tlb_refill_handler(void)
        /*
         * Now fold the handler in the TLB refill handler space.
         */
-#ifdef CONFIG_32BIT
+#if defined(CONFIG_32BIT) || defined(CONFIG_CPU_LOONGSON2)
        f = final_handler;
        /* Simplest case, just copy the handler. */
        copy_handler(relocs, labels, tlb_handler, p, f);
@@ -1336,7 +1338,7 @@ static void __init build_r4000_tlb_refill_handler(void)
                final_len);
 
        f = final_handler;
-#ifdef CONFIG_64BIT
+#if defined(CONFIG_64BIT) && !defined(CONFIG_CPU_LOONGSON2)
        if (final_len > 32)
                final_len = 64;
        else
diff --git a/arch/mips/momentum/ocelot_3/Makefile b/arch/mips/momentum/ocelot_3/Makefile
deleted file mode 100644 (file)
index d5a090a..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#
-# Makefile for Momentum Computer's Ocelot-3 board.
-#
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-obj-y   += irq.o platform.o prom.o reset.o setup.o
diff --git a/arch/mips/momentum/ocelot_3/irq.c b/arch/mips/momentum/ocelot_3/irq.c
deleted file mode 100644 (file)
index 3862d1d..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2000 RidgeRun, Inc.
- * Author: RidgeRun, Inc.
- *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
- *
- * Copyright 2001 MontaVista Software Inc.
- * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
- * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org)
- *
- * Copyright 2004 PMC-Sierra
- * Author: Manish Lachwani (lachwani@pmc-sierra.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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *  Copyright (C) 2004 MontaVista Software Inc.
- *  Author: Manish Lachwani, mlachwani@mvista.com
- *
- */
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/kernel_stat.h>
-#include <linux/module.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/timex.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <asm/bitops.h>
-#include <asm/bootinfo.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/mipsregs.h>
-#include <asm/system.h>
-
-static struct irqaction cascade_mv64340 = {
-       no_action, IRQF_DISABLED, CPU_MASK_NONE, "MV64340-Cascade", NULL, NULL
-};
-
-void __init arch_init_irq(void)
-{
-       /*
-        * Clear all of the interrupts while we change the able around a bit.
-        * int-handler is not on bootstrap
-        */
-       clear_c0_status(ST0_IM | ST0_BEV);
-
-       rm7k_cpu_irq_init();
-
-       /* set up the cascading interrupts */
-       setup_irq(8, &cascade_mv64340);         /* unmask intControl IM8, IRQ 9 */
-       mv64340_irq_init(16);
-
-       set_c0_status(ST0_IM); /* IE in the status register */
-
-}
-
-asmlinkage void plat_irq_dispatch(void)
-{
-       unsigned int pending = read_c0_cause() & read_c0_status();
-
-       if (pending & STATUSF_IP0)
-               do_IRQ(0);
-       else if (pending & STATUSF_IP1)
-               do_IRQ(1);
-       else if (pending & STATUSF_IP2)
-               do_IRQ(2);
-       else if (pending & STATUSF_IP3)
-               do_IRQ(3);
-       else if (pending & STATUSF_IP4)
-               do_IRQ(4);
-       else if (pending & STATUSF_IP5)
-               do_IRQ(5);
-       else if (pending & STATUSF_IP6)
-               do_IRQ(6);
-       else if (pending & STATUSF_IP7)
-               do_IRQ(7);
-       else {
-               /*
-                * Now look at the extended interrupts
-                */
-               pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16;
-
-               if (pending & STATUSF_IP8)
-                       ll_mv64340_irq();
-               else
-                       spurious_interrupt();
-       }
-}
diff --git a/arch/mips/momentum/ocelot_3/platform.c b/arch/mips/momentum/ocelot_3/platform.c
deleted file mode 100644 (file)
index 44e4c3f..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-#include <linux/delay.h>
-#include <linux/if_ether.h>
-#include <linux/ioport.h>
-#include <linux/mv643xx.h>
-#include <linux/platform_device.h>
-
-#include "ocelot_3_fpga.h"
-
-#if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE)
-
-static struct resource mv643xx_eth_shared_resources[] = {
-       [0] = {
-               .name   = "ethernet shared base",
-               .start  = 0xf1000000 + MV643XX_ETH_SHARED_REGS,
-               .end    = 0xf1000000 + MV643XX_ETH_SHARED_REGS +
-                                      MV643XX_ETH_SHARED_REGS_SIZE - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-};
-
-static struct platform_device mv643xx_eth_shared_device = {
-       .name           = MV643XX_ETH_SHARED_NAME,
-       .id             = 0,
-       .num_resources  = ARRAY_SIZE(mv643xx_eth_shared_resources),
-       .resource       = mv643xx_eth_shared_resources,
-};
-
-#define MV_SRAM_BASE                   0xfe000000UL
-#define MV_SRAM_SIZE                   (256 * 1024)
-
-#define MV_SRAM_RXRING_SIZE            (MV_SRAM_SIZE / 4)
-#define MV_SRAM_TXRING_SIZE            (MV_SRAM_SIZE / 4)
-
-#define MV_SRAM_BASE_ETH0              MV_SRAM_BASE
-#define MV_SRAM_BASE_ETH1              (MV_SRAM_BASE + (MV_SRAM_SIZE / 2))
-
-#define MV64x60_IRQ_ETH_0 48
-#define MV64x60_IRQ_ETH_1 49
-#define MV64x60_IRQ_ETH_2 50
-
-static struct resource mv64x60_eth0_resources[] = {
-       [0] = {
-               .name   = "eth0 irq",
-               .start  = MV64x60_IRQ_ETH_0,
-               .end    = MV64x60_IRQ_ETH_0,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct mv643xx_eth_platform_data eth0_pd = {
-       .port_number    = 0,
-
-       .tx_sram_addr   = MV_SRAM_BASE_ETH0,
-       .tx_sram_size   = MV_SRAM_TXRING_SIZE,
-       .tx_queue_size  = MV_SRAM_TXRING_SIZE / 16,
-
-       .rx_sram_addr   = MV_SRAM_BASE_ETH0 + MV_SRAM_TXRING_SIZE,
-       .rx_sram_size   = MV_SRAM_RXRING_SIZE,
-       .rx_queue_size  = MV_SRAM_RXRING_SIZE / 16,
-};
-
-static struct platform_device eth0_device = {
-       .name           = MV643XX_ETH_NAME,
-       .id             = 0,
-       .num_resources  = ARRAY_SIZE(mv64x60_eth0_resources),
-       .resource       = mv64x60_eth0_resources,
-       .dev = {
-               .platform_data = &eth0_pd,
-       },
-};
-
-static struct resource mv64x60_eth1_resources[] = {
-       [0] = {
-               .name   = "eth1 irq",
-               .start  = MV64x60_IRQ_ETH_1,
-               .end    = MV64x60_IRQ_ETH_1,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct mv643xx_eth_platform_data eth1_pd = {
-       .port_number    = 1,
-
-       .tx_sram_addr   = MV_SRAM_BASE_ETH1,
-       .tx_sram_size   = MV_SRAM_TXRING_SIZE,
-       .tx_queue_size  = MV_SRAM_TXRING_SIZE / 16,
-
-       .rx_sram_addr   = MV_SRAM_BASE_ETH1 + MV_SRAM_TXRING_SIZE,
-       .rx_sram_size   = MV_SRAM_RXRING_SIZE,
-       .rx_queue_size  = MV_SRAM_RXRING_SIZE / 16,
-};
-
-static struct platform_device eth1_device = {
-       .name           = MV643XX_ETH_NAME,
-       .id             = 1,
-       .num_resources  = ARRAY_SIZE(mv64x60_eth1_resources),
-       .resource       = mv64x60_eth1_resources,
-       .dev = {
-               .platform_data = &eth1_pd,
-       },
-};
-
-static struct resource mv64x60_eth2_resources[] = {
-       [0] = {
-               .name   = "eth2 irq",
-               .start  = MV64x60_IRQ_ETH_2,
-               .end    = MV64x60_IRQ_ETH_2,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct mv643xx_eth_platform_data eth2_pd = {
-       .port_number    = 2,
-};
-
-static struct platform_device eth2_device = {
-       .name           = MV643XX_ETH_NAME,
-       .id             = 2,
-       .num_resources  = ARRAY_SIZE(mv64x60_eth2_resources),
-       .resource       = mv64x60_eth2_resources,
-       .dev = {
-               .platform_data = &eth2_pd,
-       },
-};
-
-static struct platform_device *mv643xx_eth_pd_devs[] __initdata = {
-       &mv643xx_eth_shared_device,
-       &eth0_device,
-       &eth1_device,
-       &eth2_device,
-};
-
-static u8 __init exchange_bit(u8 val, u8 cs)
-{
-       /* place the data */
-       OCELOT_FPGA_WRITE((val << 2) | cs, EEPROM_MODE);
-       udelay(1);
-
-       /* turn the clock on */
-       OCELOT_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE);
-       udelay(1);
-
-       /* turn the clock off and read-strobe */
-       OCELOT_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE);
-
-       /* return the data */
-       return (OCELOT_FPGA_READ(EEPROM_MODE) >> 3) & 0x1;
-}
-
-static void __init get_mac(char dest[6])
-{
-       u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-       int i,j;
-
-       for (i = 0; i < 12; i++)
-               exchange_bit(read_opcode[i], 1);
-
-       for (j = 0; j < 6; j++) {
-               dest[j] = 0;
-               for (i = 0; i < 8; i++) {
-                       dest[j] <<= 1;
-                       dest[j] |= exchange_bit(0, 1);
-               }
-       }
-
-       /* turn off CS */
-       exchange_bit(0,0);
-}
-
-/*
- * Copy and increment ethernet MAC address by a small value.
- *
- * This is useful for systems where the only one MAC address is stored in
- * non-volatile memory for multiple ports.
- */
-static inline void eth_mac_add(unsigned char *dst, unsigned char *src,
-       unsigned int add)
-{
-       int i;
-
-       BUG_ON(add >= 256);
-
-       for (i = ETH_ALEN; i >= 0; i--) {
-               dst[i] = src[i] + add;
-               add = dst[i] < src[i];          /* compute carry */
-       }
-
-       WARN_ON(add);
-}
-
-static int __init mv643xx_eth_add_pds(void)
-{
-       unsigned char mac[ETH_ALEN];
-       int ret;
-
-       get_mac(mac);
-       eth_mac_add(eth0_pd.mac_addr, mac, 0);
-       eth_mac_add(eth1_pd.mac_addr, mac, 1);
-       eth_mac_add(eth2_pd.mac_addr, mac, 2);
-       ret = platform_add_devices(mv643xx_eth_pd_devs,
-                       ARRAY_SIZE(mv643xx_eth_pd_devs));
-
-       return ret;
-}
-
-device_initcall(mv643xx_eth_add_pds);
-
-#endif /* defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) */
diff --git a/arch/mips/momentum/ocelot_3/prom.c b/arch/mips/momentum/ocelot_3/prom.c
deleted file mode 100644 (file)
index 8e02df6..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright 2002 Momentum Computer Inc.
- * Author: Matthew Dharm <mdharm@momenco.com>
- *
- * Louis Hamilton, Red Hat, Inc.
- *   hamilton@redhat.com  [MIPS64 modifications]
- *
- * Copyright 2004 PMC-Sierra
- * Author: Manish Lachwani (lachwani@pmc-sierra.com)
- *
- * Based on Ocelot Linux port, which is
- * Copyright 2001 MontaVista Software Inc.
- * Author: jsun@mvista.com or jsun@junsun.net
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- *
- * Copyright (C) 2004 MontaVista Software Inc.
- * Author: Manish Lachwani, mlachwani@mvista.com
- *
- */
-#include <linux/init.h>
-#include <linux/bootmem.h>
-#include <linux/mv643xx.h>
-
-#include <asm/addrspace.h>
-#include <asm/bootinfo.h>
-#include <asm/pmon.h>
-#include "ocelot_3_fpga.h"
-
-struct callvectors* debug_vectors;
-extern unsigned long marvell_base;
-extern unsigned long cpu_clock;
-
-const char *get_system_type(void)
-{
-       return "Momentum Ocelot-3";
-}
-
-#ifdef CONFIG_64BIT
-
-unsigned long signext(unsigned long addr)
-{
-       addr &= 0xffffffff;
-       return (unsigned long)((int)addr);
-}
-
-void *get_arg(unsigned long args, int arc)
-{
-       unsigned long ul;
-       unsigned char *puc, uc;
-
-       args += (arc * 4);
-       ul = (unsigned long)signext(args);
-       puc = (unsigned char *)ul;
-       if (puc == 0)
-               return (void *)0;
-
-#ifdef CONFIG_CPU_LITTLE_ENDIAN
-       uc = *puc++;
-       ul = (unsigned long)uc;
-       uc = *puc++;
-       ul |= (((unsigned long)uc) << 8);
-       uc = *puc++;
-       ul |= (((unsigned long)uc) << 16);
-       uc = *puc++;
-       ul |= (((unsigned long)uc) << 24);
-#else  /* CONFIG_CPU_LITTLE_ENDIAN */
-       uc = *puc++;
-       ul = ((unsigned long)uc) << 24;
-       uc = *puc++;
-       ul |= (((unsigned long)uc) << 16);
-       uc = *puc++;
-       ul |= (((unsigned long)uc) << 8);
-       uc = *puc++;
-       ul |= ((unsigned long)uc);
-#endif  /* CONFIG_CPU_LITTLE_ENDIAN */
-       ul = signext(ul);
-       return (void *)ul;
-}
-
-char *arg64(unsigned long addrin, int arg_index)
-{
-       unsigned long args;
-       char *p;
-
-       args = signext(addrin);
-       p = (char *)get_arg(args, arg_index);
-
-       return p;
-}
-#endif  /* CONFIG_64BIT */
-
-void __init prom_init(void)
-{
-       int argc = fw_arg0;
-       char **arg = (char **) fw_arg1;
-       char **env = (char **) fw_arg2;
-       struct callvectors *cv = (struct callvectors *) fw_arg3;
-       int i;
-
-#ifdef CONFIG_64BIT
-       char *ptr;
-       printk("prom_init - MIPS64\n");
-
-       /* save the PROM vectors for debugging use */
-       debug_vectors = (struct callvectors *)signext((unsigned long)cv);
-
-       /* arg[0] is "g", the rest is boot parameters */
-       arcs_cmdline[0] = '\0';
-
-       for (i = 1; i < argc; i++) {
-               ptr = (char *)arg64((unsigned long)arg, i);
-               if ((strlen(arcs_cmdline) + strlen(ptr) + 1) >=
-                   sizeof(arcs_cmdline))
-                       break;
-               strcat(arcs_cmdline, ptr);
-               strcat(arcs_cmdline, " ");
-       }
-       i = 0;
-
-       while (1) {
-               ptr = (char *)arg64((unsigned long)env, i);
-               if (! ptr)
-                       break;
-
-               if (strncmp("gtbase", ptr, strlen("gtbase")) == 0) {
-                       marvell_base = simple_strtol(ptr + strlen("gtbase="),
-                                                       NULL, 16);
-
-                       if ((marvell_base & 0xffffffff00000000) == 0)
-                               marvell_base |= 0xffffffff00000000;
-
-                       printk("marvell_base set to 0x%016lx\n", marvell_base);
-               }
-               if (strncmp("cpuclock", ptr, strlen("cpuclock")) == 0) {
-                       cpu_clock = simple_strtol(ptr + strlen("cpuclock="),
-                                                       NULL, 10);
-                       printk("cpu_clock set to %d\n", cpu_clock);
-               }
-               i++;
-       }
-       printk("arcs_cmdline: %s\n", arcs_cmdline);
-
-#else   /* CONFIG_64BIT */
-
-       /* save the PROM vectors for debugging use */
-       debug_vectors = cv;
-
-       /* arg[0] is "g", the rest is boot parameters */
-       arcs_cmdline[0] = '\0';
-       for (i = 1; i < argc; i++) {
-               if (strlen(arcs_cmdline) + strlen(arg[i] + 1)
-                   >= sizeof(arcs_cmdline))
-                       break;
-               strcat(arcs_cmdline, arg[i]);
-               strcat(arcs_cmdline, " ");
-       }
-
-       while (*env) {
-               if (strncmp("gtbase", *env, strlen("gtbase")) == 0) {
-                       marvell_base = simple_strtol(*env + strlen("gtbase="),
-                                                       NULL, 16);
-               }
-               if (strncmp("cpuclock", *env, strlen("cpuclock")) == 0) {
-                       cpu_clock = simple_strtol(*env + strlen("cpuclock="),
-                                                       NULL, 10);
-               }
-               env++;
-       }
-#endif /* CONFIG_64BIT */
-
-       mips_machgroup = MACH_GROUP_MOMENCO;
-       mips_machtype = MACH_MOMENCO_OCELOT_3;
-
-#ifndef CONFIG_64BIT
-       debug_vectors->printf("Booting Linux kernel...\n");
-#endif
-}
-
-void __init prom_free_prom_memory(void)
-{
-}
-
-void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
-{
-}
diff --git a/arch/mips/momentum/ocelot_3/reset.c b/arch/mips/momentum/ocelot_3/reset.c
deleted file mode 100644 (file)
index 9d86d24..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- *
- * Copyright (C) 1997, 01, 05 Ralf Baechle
- * Copyright 2001 MontaVista Software Inc.
- * Author: jsun@mvista.com or jsun@junsun.net
- *
- * Copyright (C) 2002 Momentum Computer Inc.
- * Author: Matthew Dharm <mdharm@momenco.com>
- *
- * Louis Hamilton, Red Hat, Inc.
- * hamilton@redhat.com  [MIPS64 modifications]
- *
- * Copyright 2004 PMC-Sierra
- * Author: Manish Lachwani (lachwani@pmc-sierra.com)
- *
- * Copyright (C) 2004 MontaVista Software Inc.
- * Author: Manish Lachwani, mlachwani@mvista.com
- */
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/delay.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/processor.h>
-#include <asm/reboot.h>
-#include <asm/system.h>
-
-void momenco_ocelot_restart(char *command)
-{
-       /* base address of timekeeper portion of part */
-       void *nvram = (void *) 0xfc807000L;
-
-       /* Ask the NVRAM/RTC/watchdog chip to assert reset in 1/16 second */
-       writeb(0x84, nvram + 0xff7);
-
-       /* wait for the watchdog to go off */
-       mdelay(100+(1000/16));
-
-       /* if the watchdog fails for some reason, let people know */
-       printk(KERN_NOTICE "Watchdog reset failed\n");
-}
-
-void momenco_ocelot_halt(void)
-{
-       printk(KERN_NOTICE "\n** You can safely turn off the power\n");
-       while (1)
-               __asm__(".set\tmips3\n\t"
-                       "wait\n\t"
-                       ".set\tmips0");
-}
-
-void momenco_ocelot_power_off(void)
-{
-       momenco_ocelot_halt();
-}
diff --git a/arch/mips/momentum/ocelot_3/setup.c b/arch/mips/momentum/ocelot_3/setup.c
deleted file mode 100644 (file)
index ff0829f..0000000
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
- * setup.c
- *
- * BRIEF MODULE DESCRIPTION
- * Momentum Computer Ocelot-3 board dependent boot routines
- *
- * Copyright (C) 1996, 1997, 01, 05 - 06  Ralf Baechle
- * Copyright (C) 2000 RidgeRun, Inc.
- * Copyright (C) 2001 Red Hat, Inc.
- * Copyright (C) 2002 Momentum Computer
- *
- * Author: Matthew Dharm, Momentum Computer
- *   mdharm@momenco.com
- *
- * Louis Hamilton, Red Hat, Inc.
- *   hamilton@redhat.com  [MIPS64 modifications]
- *
- * Author: RidgeRun, Inc.
- *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
- *
- * Copyright 2001 MontaVista Software Inc.
- * Author: jsun@mvista.com or jsun@junsun.net
- *
- * Copyright 2004 PMC-Sierra
- * Author: Manish Lachwani (lachwani@pmc-sierra.com)
- *
- * Copyright (C) 2004 MontaVista Software Inc.
- * Author: Manish Lachwani, mlachwani@mvista.com
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/mc146818rtc.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/timex.h>
-#include <linux/bootmem.h>
-#include <linux/mv643xx.h>
-#include <linux/pm.h>
-#include <linux/bcd.h>
-
-#include <asm/time.h>
-#include <asm/page.h>
-#include <asm/bootinfo.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/pci.h>
-#include <asm/processor.h>
-#include <asm/reboot.h>
-#include <asm/mc146818rtc.h>
-#include <asm/tlbflush.h>
-#include "ocelot_3_fpga.h"
-
-/* Marvell Discovery Register Base */
-unsigned long marvell_base = (signed)0xf4000000;
-
-/* CPU clock */
-unsigned long cpu_clock;
-
-/* RTC/NVRAM */
-unsigned char* rtc_base = (unsigned char*)(signed)0xfc800000;
-
-/* FPGA Base */
-unsigned long ocelot_fpga_base = (signed)0xfc000000;
-
-/* Serial base */
-unsigned long uart_base = (signed)0xfd000000;
-
-/*
- * Marvell Discovery SRAM. This is one place where Ethernet
- * Tx and Rx descriptors can be placed to improve performance
- */
-extern unsigned long mv64340_sram_base;
-
-/* These functions are used for rebooting or halting the machine*/
-extern void momenco_ocelot_restart(char *command);
-extern void momenco_ocelot_halt(void);
-extern void momenco_ocelot_power_off(void);
-
-void momenco_time_init(void);
-static char reset_reason;
-
-void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
-                    unsigned long entryhi, unsigned long pagemask);
-
-static inline unsigned long ENTRYLO(unsigned long paddr)
-{
-       return ((paddr & PAGE_MASK) |
-               (_PAGE_PRESENT | __READABLE | __WRITEABLE | _PAGE_GLOBAL |
-               _CACHE_UNCACHED)) >> 6;
-}
-
-void __init bus_error_init(void)
-{
-       /* nothing */
-}
-
-/*
- * setup code for a handoff from a version 2 PMON 2000 PROM
- */
-void setup_wired_tlb_entries(void)
-{
-       write_c0_wired(0);
-       local_flush_tlb_all();
-
-       /* marvell and extra space */
-       add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000), (signed)0xf4000000, PM_64K);
-
-       /* fpga, rtc, and uart */
-       add_wired_entry(ENTRYLO(0xfc000000), ENTRYLO(0xfd000000), (signed)0xfc000000, PM_16M);
-}
-
-unsigned long m48t37y_get_time(void)
-{
-       unsigned int year, month, day, hour, min, sec;
-       unsigned long flags;
-
-       spin_lock_irqsave(&rtc_lock, flags);
-       /* stop the update */
-       rtc_base[0x7ff8] = 0x40;
-
-       year = BCD2BIN(rtc_base[0x7fff]);
-       year += BCD2BIN(rtc_base[0x7ff1]) * 100;
-
-       month = BCD2BIN(rtc_base[0x7ffe]);
-
-       day = BCD2BIN(rtc_base[0x7ffd]);
-
-       hour = BCD2BIN(rtc_base[0x7ffb]);
-       min = BCD2BIN(rtc_base[0x7ffa]);
-       sec = BCD2BIN(rtc_base[0x7ff9]);
-
-       /* start the update */
-       rtc_base[0x7ff8] = 0x00;
-       spin_unlock_irqrestore(&rtc_lock, flags);
-
-       return mktime(year, month, day, hour, min, sec);
-}
-
-int m48t37y_set_time(unsigned long sec)
-{
-       struct rtc_time tm;
-       unsigned long flags;
-
-       /* convert to a more useful format -- note months count from 0 */
-       to_tm(sec, &tm);
-       tm.tm_mon += 1;
-
-       spin_lock_irqsave(&rtc_lock, flags);
-       /* enable writing */
-       rtc_base[0x7ff8] = 0x80;
-
-       /* year */
-       rtc_base[0x7fff] = BIN2BCD(tm.tm_year % 100);
-       rtc_base[0x7ff1] = BIN2BCD(tm.tm_year / 100);
-
-       /* month */
-       rtc_base[0x7ffe] = BIN2BCD(tm.tm_mon);
-
-       /* day */
-       rtc_base[0x7ffd] = BIN2BCD(tm.tm_mday);
-
-       /* hour/min/sec */
-       rtc_base[0x7ffb] = BIN2BCD(tm.tm_hour);
-       rtc_base[0x7ffa] = BIN2BCD(tm.tm_min);
-       rtc_base[0x7ff9] = BIN2BCD(tm.tm_sec);
-
-       /* day of week -- not really used, but let's keep it up-to-date */
-       rtc_base[0x7ffc] = BIN2BCD(tm.tm_wday + 1);
-
-       /* disable writing */
-       rtc_base[0x7ff8] = 0x00;
-       spin_unlock_irqrestore(&rtc_lock, flags);
-
-       return 0;
-}
-
-void __init plat_timer_setup(struct irqaction *irq)
-{
-       setup_irq(7, irq);      /* Timer interrupt, unmask status IM7 */
-}
-
-void momenco_time_init(void)
-{
-       setup_wired_tlb_entries();
-
-       /*
-        * Ocelot-3 board has been built with both
-        * the Rm7900 and the Rm7065C
-        */
-       mips_hpt_frequency = cpu_clock / 2;
-
-       rtc_mips_get_time = m48t37y_get_time;
-       rtc_mips_set_time = m48t37y_set_time;
-}
-
-/*
- * PCI Support for Ocelot-3
- */
-
-/* Bus #0 IO and MEM space */
-#define        OCELOT_3_PCI_IO_0_START         0xe0000000
-#define        OCELOT_3_PCI_IO_0_SIZE          0x08000000
-#define        OCELOT_3_PCI_MEM_0_START        0xc0000000
-#define        OCELOT_3_PCI_MEM_0_SIZE         0x10000000
-
-/* Bus #1 IO and MEM space */
-#define        OCELOT_3_PCI_IO_1_START         0xe8000000
-#define        OCELOT_3_PCI_IO_1_SIZE          0x08000000
-#define        OCELOT_3_PCI_MEM_1_START        0xd0000000
-#define        OCELOT_3_PCI_MEM_1_SIZE         0x10000000
-
-static struct resource mv_pci_io_mem0_resource = {
-       .name   = "MV64340 PCI0 IO MEM",
-       .start  = OCELOT_3_PCI_IO_0_START,
-       .end    = OCELOT_3_PCI_IO_0_START + OCELOT_3_PCI_IO_0_SIZE - 1,
-       .flags  = IORESOURCE_IO,
-};
-
-static struct resource mv_pci_io_mem1_resource = {
-       .name   = "MV64340 PCI1 IO MEM",
-       .start  = OCELOT_3_PCI_IO_1_START,
-       .end    = OCELOT_3_PCI_IO_1_START + OCELOT_3_PCI_IO_1_SIZE - 1,
-       .flags  = IORESOURCE_IO,
-};
-
-static struct resource mv_pci_mem0_resource = {
-       .name   = "MV64340 PCI0 MEM",
-       .start  = OCELOT_3_PCI_MEM_0_START,
-       .end    = OCELOT_3_PCI_MEM_0_START + OCELOT_3_PCI_MEM_0_SIZE - 1,
-       .flags  = IORESOURCE_MEM,
-};
-
-static struct resource mv_pci_mem1_resource = {
-       .name   = "MV64340 PCI1 MEM",
-       .start  = OCELOT_3_PCI_MEM_1_START,
-       .end    = OCELOT_3_PCI_MEM_1_START + OCELOT_3_PCI_MEM_1_SIZE - 1,
-       .flags  = IORESOURCE_MEM,
-};
-
-static struct mv_pci_controller mv_bus0_controller = {
-       .pcic = {
-                .pci_ops       = &mv_pci_ops,
-                .mem_resource  = &mv_pci_mem0_resource,
-                .io_resource   = &mv_pci_io_mem0_resource,
-       },
-       .config_addr    = MV64340_PCI_0_CONFIG_ADDR,
-       .config_vreg    = MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG,
-};
-
-static struct mv_pci_controller mv_bus1_controller = {
-       .pcic = {
-                .pci_ops       = &mv_pci_ops,
-                .mem_resource  = &mv_pci_mem1_resource,
-                .io_resource   = &mv_pci_io_mem1_resource,
-       },
-       .config_addr    = MV64340_PCI_1_CONFIG_ADDR,
-       .config_vreg    = MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG,
-};
-
-static __init int __init ja_pci_init(void)
-{
-       uint32_t enable;
-       extern int pci_probe_only;
-
-       /* PMON will assign PCI resources */
-       pci_probe_only = 1;
-
-       enable = ~MV_READ(MV64340_BASE_ADDR_ENABLE);
-       /*
-        * We require at least one enabled I/O or PCI memory window or we
-        * will ignore this PCI bus.  We ignore PCI windows 1, 2 and 3.
-        */
-       if (enable & (0x01 <<  9) || enable & (0x01 << 10))
-               register_pci_controller(&mv_bus0_controller.pcic);
-
-       if (enable & (0x01 << 14) || enable & (0x01 << 15))
-               register_pci_controller(&mv_bus1_controller.pcic);
-
-       ioport_resource.end = OCELOT_3_PCI_IO_0_START + OCELOT_3_PCI_IO_0_SIZE +
-                                       OCELOT_3_PCI_IO_1_SIZE - 1;
-
-       iomem_resource.end = OCELOT_3_PCI_MEM_0_START + OCELOT_3_PCI_MEM_0_SIZE +
-                                       OCELOT_3_PCI_MEM_1_SIZE - 1;
-
-       set_io_port_base(OCELOT_3_PCI_IO_0_START); /* mips_io_port_base */
-
-       return 0;
-}
-
-arch_initcall(ja_pci_init);
-
-void __init plat_mem_setup(void)
-{
-       unsigned int tmpword;
-
-       board_time_init = momenco_time_init;
-
-       _machine_restart = momenco_ocelot_restart;
-       _machine_halt = momenco_ocelot_halt;
-       pm_power_off = momenco_ocelot_power_off;
-
-       /* Wired TLB entries */
-       setup_wired_tlb_entries();
-
-       /* shut down ethernet ports, just to be sure our memory doesn't get
-        * corrupted by random ethernet traffic.
-        */
-       MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(0), 0xff << 8);
-       MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(1), 0xff << 8);
-       MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(0), 0xff << 8);
-       MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(1), 0xff << 8);
-       do {}
-         while (MV_READ(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(0)) & 0xff);
-       do {}
-         while (MV_READ(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(1)) & 0xff);
-       do {}
-         while (MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(0)) & 0xff);
-       do {}
-         while (MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(1)) & 0xff);
-       MV_WRITE(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(0),
-                MV_READ(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(0)) & ~1);
-       MV_WRITE(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(1),
-                MV_READ(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(1)) & ~1);
-
-       /* Turn off the Bit-Error LED */
-       OCELOT_FPGA_WRITE(0x80, CLR);
-
-       tmpword = OCELOT_FPGA_READ(BOARDREV);
-       if (tmpword < 26)
-               printk("Momenco Ocelot-3: Board Assembly Rev. %c\n",
-                       'A'+tmpword);
-       else
-               printk("Momenco Ocelot-3: Board Assembly Revision #0x%x\n",
-                       tmpword);
-
-       tmpword = OCELOT_FPGA_READ(FPGA_REV);
-       printk("FPGA Rev: %d.%d\n", tmpword>>4, tmpword&15);
-       tmpword = OCELOT_FPGA_READ(RESET_STATUS);
-       printk("Reset reason: 0x%x\n", tmpword);
-       switch (tmpword) {
-               case 0x1:
-                       printk("  - Power-up reset\n");
-                       break;
-               case 0x2:
-                       printk("  - Push-button reset\n");
-                       break;
-               case 0x4:
-                       printk("  - cPCI bus reset\n");
-                       break;
-               case 0x8:
-                       printk("  - Watchdog reset\n");
-                       break;
-               case 0x10:
-                       printk("  - Software reset\n");
-                       break;
-               default:
-                       printk("  - Unknown reset cause\n");
-       }
-       reset_reason = tmpword;
-       OCELOT_FPGA_WRITE(0xff, RESET_STATUS);
-
-       tmpword = OCELOT_FPGA_READ(CPCI_ID);
-       printk("cPCI ID register: 0x%02x\n", tmpword);
-       printk("  - Slot number: %d\n", tmpword & 0x1f);
-       printk("  - PCI bus present: %s\n", tmpword & 0x40 ? "yes" : "no");
-       printk("  - System Slot: %s\n", tmpword & 0x20 ? "yes" : "no");
-
-       tmpword = OCELOT_FPGA_READ(BOARD_STATUS);
-       printk("Board Status register: 0x%02x\n", tmpword);
-       printk("  - User jumper: %s\n", (tmpword & 0x80)?"installed":"absent");
-       printk("  - Boot flash write jumper: %s\n", (tmpword&0x40)?"installed":"absent");
-       printk("  - L3 cache size: %d MB\n", (1<<((tmpword&12) >> 2))&~1);
-
-       /* Support for 128 MB memory */
-       add_memory_region(0x0, 0x08000000, BOOT_MEM_RAM);
-}
diff --git a/arch/mips/momentum/ocelot_c/Makefile b/arch/mips/momentum/ocelot_c/Makefile
deleted file mode 100644 (file)
index d69161a..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#
-# Makefile for Momentum Computer's Ocelot-C and -CS boards.
-#
-
-obj-y                  += cpci-irq.o irq.o platform.o prom.o reset.o \
-                          setup.o uart-irq.o
-
-obj-$(CONFIG_KGDB)     += dbg_io.o
diff --git a/arch/mips/momentum/ocelot_c/cpci-irq.c b/arch/mips/momentum/ocelot_c/cpci-irq.c
deleted file mode 100644 (file)
index 186a140..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright 2002 Momentum Computer
- * Author: mdharm@momenco.com
- *
- * arch/mips/momentum/ocelot_c/cpci-irq.c
- *     Interrupt routines for cpci.  Interrupt numbers are assigned from
- *     CPCI_IRQ_BASE to CPCI_IRQ_BASE+8 (8 interrupt sources).
- *
- * Note that the high-level software will need to be careful about using
- * these interrupts.  If this board is asserting a cPCI interrupt, it will
- * also see the asserted interrupt.  Care must be taken to avoid an
- * interrupt flood.
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/kernel_stat.h>
-#include <asm/io.h>
-#include "ocelot_c_fpga.h"
-
-#define CPCI_IRQ_BASE  8
-
-static inline int ls1bit8(unsigned int x)
-{
-        int b = 7, s;
-
-        s =  4; if (((unsigned char)(x <<  4)) == 0) s = 0; b -= s; x <<= s;
-        s =  2; if (((unsigned char)(x <<  2)) == 0) s = 0; b -= s; x <<= s;
-        s =  1; if (((unsigned char)(x <<  1)) == 0) s = 0; b -= s;
-
-        return b;
-}
-
-/* mask off an interrupt -- 0 is enable, 1 is disable */
-static inline void mask_cpci_irq(unsigned int irq)
-{
-       uint32_t value;
-
-       value = OCELOT_FPGA_READ(INTMASK);
-       value |= 1 << (irq - CPCI_IRQ_BASE);
-       OCELOT_FPGA_WRITE(value, INTMASK);
-
-       /* read the value back to assure that it's really been written */
-       value = OCELOT_FPGA_READ(INTMASK);
-}
-
-/* unmask an interrupt -- 0 is enable, 1 is disable */
-static inline void unmask_cpci_irq(unsigned int irq)
-{
-       uint32_t value;
-
-       value = OCELOT_FPGA_READ(INTMASK);
-       value &= ~(1 << (irq - CPCI_IRQ_BASE));
-       OCELOT_FPGA_WRITE(value, INTMASK);
-
-       /* read the value back to assure that it's really been written */
-       value = OCELOT_FPGA_READ(INTMASK);
-}
-
-/*
- * Interrupt handler for interrupts coming from the FPGA chip.
- * It could be built in ethernet ports etc...
- */
-void ll_cpci_irq(void)
-{
-       unsigned int irq_src, irq_mask;
-
-       /* read the interrupt status registers */
-       irq_src = OCELOT_FPGA_READ(INTSTAT);
-       irq_mask = OCELOT_FPGA_READ(INTMASK);
-
-       /* mask for just the interrupts we want */
-       irq_src &= ~irq_mask;
-
-       do_IRQ(ls1bit8(irq_src) + CPCI_IRQ_BASE);
-}
-
-struct irq_chip cpci_irq_type = {
-       .name = "CPCI/FPGA",
-       .ack = mask_cpci_irq,
-       .mask = mask_cpci_irq,
-       .mask_ack = mask_cpci_irq,
-       .unmask = unmask_cpci_irq,
-};
-
-void cpci_irq_init(void)
-{
-       int i;
-
-       for (i = CPCI_IRQ_BASE; i < (CPCI_IRQ_BASE + 8); i++)
-               set_irq_chip_and_handler(i, &cpci_irq_type, handle_level_irq);
-}
diff --git a/arch/mips/momentum/ocelot_c/dbg_io.c b/arch/mips/momentum/ocelot_c/dbg_io.c
deleted file mode 100644 (file)
index 32d6fb4..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-
-#include <asm/serial.h> /* For the serial port location and base baud */
-
-/* --- CONFIG --- */
-
-typedef unsigned char uint8;
-typedef unsigned int uint32;
-
-/* --- END OF CONFIG --- */
-
-#define         UART16550_BAUD_2400             2400
-#define         UART16550_BAUD_4800             4800
-#define         UART16550_BAUD_9600             9600
-#define         UART16550_BAUD_19200            19200
-#define         UART16550_BAUD_38400            38400
-#define         UART16550_BAUD_57600            57600
-#define         UART16550_BAUD_115200           115200
-
-#define         UART16550_PARITY_NONE           0
-#define         UART16550_PARITY_ODD            0x08
-#define         UART16550_PARITY_EVEN           0x18
-#define         UART16550_PARITY_MARK           0x28
-#define         UART16550_PARITY_SPACE          0x38
-
-#define         UART16550_DATA_5BIT             0x0
-#define         UART16550_DATA_6BIT             0x1
-#define         UART16550_DATA_7BIT             0x2
-#define         UART16550_DATA_8BIT             0x3
-
-#define         UART16550_STOP_1BIT             0x0
-#define         UART16550_STOP_2BIT             0x4
-
-/* ----------------------------------------------------- */
-
-/* === CONFIG === */
-
-/* [jsun] we use the second serial port for kdb */
-#define         BASE                    OCELOT_SERIAL1_BASE
-#define         MAX_BAUD                OCELOT_BASE_BAUD
-
-/* === END OF CONFIG === */
-
-#define         REG_OFFSET              4
-
-/* register offset */
-#define         OFS_RCV_BUFFER          0
-#define         OFS_TRANS_HOLD          0
-#define         OFS_SEND_BUFFER         0
-#define         OFS_INTR_ENABLE         (1*REG_OFFSET)
-#define         OFS_INTR_ID             (2*REG_OFFSET)
-#define         OFS_DATA_FORMAT         (3*REG_OFFSET)
-#define         OFS_LINE_CONTROL        (3*REG_OFFSET)
-#define         OFS_MODEM_CONTROL       (4*REG_OFFSET)
-#define         OFS_RS232_OUTPUT        (4*REG_OFFSET)
-#define         OFS_LINE_STATUS         (5*REG_OFFSET)
-#define         OFS_MODEM_STATUS        (6*REG_OFFSET)
-#define         OFS_RS232_INPUT         (6*REG_OFFSET)
-#define         OFS_SCRATCH_PAD         (7*REG_OFFSET)
-
-#define         OFS_DIVISOR_LSB         (0*REG_OFFSET)
-#define         OFS_DIVISOR_MSB         (1*REG_OFFSET)
-
-
-/* memory-mapped read/write of the port */
-#define         UART16550_READ(y)    (*((volatile uint8*)(BASE + y)))
-#define         UART16550_WRITE(y, z)  ((*((volatile uint8*)(BASE + y))) = z)
-
-void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
-{
-       /* disable interrupts */
-       UART16550_WRITE(OFS_INTR_ENABLE, 0);
-
-       /* set up baud rate */
-       {
-               uint32 divisor;
-
-               /* set DIAB bit */
-               UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
-
-               /* set divisor */
-               divisor = MAX_BAUD / baud;
-               UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
-               UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8);
-
-               /* clear DIAB bit */
-               UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
-       }
-
-       /* set data format */
-       UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
-}
-
-static int remoteDebugInitialized = 0;
-
-uint8 getDebugChar(void)
-{
-       if (!remoteDebugInitialized) {
-               remoteDebugInitialized = 1;
-               debugInit(UART16550_BAUD_38400,
-                         UART16550_DATA_8BIT,
-                         UART16550_PARITY_NONE, UART16550_STOP_1BIT);
-       }
-
-       while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0);
-       return UART16550_READ(OFS_RCV_BUFFER);
-}
-
-
-int putDebugChar(uint8 byte)
-{
-       if (!remoteDebugInitialized) {
-               remoteDebugInitialized = 1;
-               debugInit(UART16550_BAUD_38400,
-                         UART16550_DATA_8BIT,
-                         UART16550_PARITY_NONE, UART16550_STOP_1BIT);
-       }
-
-       while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0);
-       UART16550_WRITE(OFS_SEND_BUFFER, byte);
-       return 1;
-}
diff --git a/arch/mips/momentum/ocelot_c/irq.c b/arch/mips/momentum/ocelot_c/irq.c
deleted file mode 100644 (file)
index 844d566..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2000 RidgeRun, Inc.
- * Author: RidgeRun, Inc.
- *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
- *
- * Copyright 2001 MontaVista Software Inc.
- * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
- * Copyright (C) 2000, 01, 05 Ralf Baechle (ralf@linux-mips.org)
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/kernel_stat.h>
-#include <linux/module.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/timex.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/bitops.h>
-#include <linux/mv643xx.h>
-#include <asm/bootinfo.h>
-#include <asm/io.h>
-#include <asm/irq_cpu.h>
-#include <asm/mipsregs.h>
-#include <asm/system.h>
-
-extern void uart_irq_init(void);
-extern void cpci_irq_init(void);
-
-static struct irqaction cascade_fpga = {
-       no_action, IRQF_DISABLED, CPU_MASK_NONE, "cascade via FPGA", NULL, NULL
-};
-
-static struct irqaction cascade_mv64340 = {
-       no_action, IRQF_DISABLED, CPU_MASK_NONE, "cascade via MV64340", NULL, NULL
-};
-
-extern void ll_uart_irq(void);
-extern void ll_cpci_irq(void);
-
-asmlinkage void plat_irq_dispatch(void)
-{
-       unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
-
-       if (pending & STATUSF_IP0)
-               do_IRQ(0);
-       else if (pending & STATUSF_IP1)
-               do_IRQ(1);
-       else if (pending & STATUSF_IP2)
-               do_IRQ(2);
-       else if (pending & STATUSF_IP3)
-               ll_uart_irq();
-       else if (pending & STATUSF_IP4)
-               do_IRQ(4);
-       else if (pending & STATUSF_IP5)
-               ll_cpci_irq();
-       else if (pending & STATUSF_IP6)
-               ll_mv64340_irq();
-       else if (pending & STATUSF_IP7)
-               do_IRQ(7);
-       else
-               spurious_interrupt();
-}
-
-void __init arch_init_irq(void)
-{
-       /*
-        * Clear all of the interrupts while we change the able around a bit.
-        * int-handler is not on bootstrap
-        */
-       clear_c0_status(ST0_IM);
-
-       mips_cpu_irq_init();
-
-       /* set up the cascading interrupts */
-       setup_irq(3, &cascade_fpga);
-       setup_irq(5, &cascade_fpga);
-       setup_irq(6, &cascade_mv64340);
-
-       mv64340_irq_init(16);
-       uart_irq_init();
-       cpci_irq_init();
-}
diff --git a/arch/mips/momentum/ocelot_c/platform.c b/arch/mips/momentum/ocelot_c/platform.c
deleted file mode 100644 (file)
index 7780aa0..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-#include <linux/delay.h>
-#include <linux/if_ether.h>
-#include <linux/ioport.h>
-#include <linux/mv643xx.h>
-#include <linux/platform_device.h>
-
-#include "ocelot_c_fpga.h"
-
-#if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE)
-
-static struct resource mv643xx_eth_shared_resources[] = {
-       [0] = {
-               .name   = "ethernet shared base",
-               .start  = 0xf1000000 + MV643XX_ETH_SHARED_REGS,
-               .end    = 0xf1000000 + MV643XX_ETH_SHARED_REGS +
-                                      MV643XX_ETH_SHARED_REGS_SIZE - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-};
-
-static struct platform_device mv643xx_eth_shared_device = {
-       .name           = MV643XX_ETH_SHARED_NAME,
-       .id             = 0,
-       .num_resources  = ARRAY_SIZE(mv643xx_eth_shared_resources),
-       .resource       = mv643xx_eth_shared_resources,
-};
-
-#define MV_SRAM_BASE                   0xfe000000UL
-#define MV_SRAM_SIZE                   (256 * 1024)
-
-#define MV_SRAM_RXRING_SIZE            (MV_SRAM_SIZE / 4)
-#define MV_SRAM_TXRING_SIZE            (MV_SRAM_SIZE / 4)
-
-#define MV_SRAM_BASE_ETH0              MV_SRAM_BASE
-#define MV_SRAM_BASE_ETH1              (MV_SRAM_BASE + (MV_SRAM_SIZE / 2))
-
-#define MV64x60_IRQ_ETH_0 48
-#define MV64x60_IRQ_ETH_1 49
-
-static struct resource mv64x60_eth0_resources[] = {
-       [0] = {
-               .name   = "eth0 irq",
-               .start  = MV64x60_IRQ_ETH_0,
-               .end    = MV64x60_IRQ_ETH_0,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct mv643xx_eth_platform_data eth0_pd = {
-       .port_number    = 0,
-
-       .tx_sram_addr   = MV_SRAM_BASE_ETH0,
-       .tx_sram_size   = MV_SRAM_TXRING_SIZE,
-       .tx_queue_size  = MV_SRAM_TXRING_SIZE / 16,
-
-       .rx_sram_addr   = MV_SRAM_BASE_ETH0 + MV_SRAM_TXRING_SIZE,
-       .rx_sram_size   = MV_SRAM_RXRING_SIZE,
-       .rx_queue_size  = MV_SRAM_RXRING_SIZE / 16,
-};
-
-static struct platform_device eth0_device = {
-       .name           = MV643XX_ETH_NAME,
-       .id             = 0,
-       .num_resources  = ARRAY_SIZE(mv64x60_eth0_resources),
-       .resource       = mv64x60_eth0_resources,
-       .dev = {
-               .platform_data = &eth0_pd,
-       },
-};
-
-static struct resource mv64x60_eth1_resources[] = {
-       [0] = {
-               .name   = "eth1 irq",
-               .start  = MV64x60_IRQ_ETH_1,
-               .end    = MV64x60_IRQ_ETH_1,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct mv643xx_eth_platform_data eth1_pd = {
-       .port_number    = 1,
-
-       .tx_sram_addr   = MV_SRAM_BASE_ETH1,
-       .tx_sram_size   = MV_SRAM_TXRING_SIZE,
-       .tx_queue_size  = MV_SRAM_TXRING_SIZE / 16,
-
-       .rx_sram_addr   = MV_SRAM_BASE_ETH1 + MV_SRAM_TXRING_SIZE,
-       .rx_sram_size   = MV_SRAM_RXRING_SIZE,
-       .rx_queue_size  = MV_SRAM_RXRING_SIZE / 16,
-};
-
-static struct platform_device eth1_device = {
-       .name           = MV643XX_ETH_NAME,
-       .id             = 1,
-       .num_resources  = ARRAY_SIZE(mv64x60_eth1_resources),
-       .resource       = mv64x60_eth1_resources,
-       .dev = {
-               .platform_data = &eth1_pd,
-       },
-};
-
-static struct platform_device *mv643xx_eth_pd_devs[] __initdata = {
-       &mv643xx_eth_shared_device,
-       &eth0_device,
-       &eth1_device,
-       /* The third port is not wired up on the Ocelot C */
-};
-
-static u8 __init exchange_bit(u8 val, u8 cs)
-{
-       /* place the data */
-       OCELOT_FPGA_WRITE((val << 2) | cs, EEPROM_MODE);
-       udelay(1);
-
-       /* turn the clock on */
-       OCELOT_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE);
-       udelay(1);
-
-       /* turn the clock off and read-strobe */
-       OCELOT_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE);
-
-       /* return the data */
-       return (OCELOT_FPGA_READ(EEPROM_MODE) >> 3) & 0x1;
-}
-
-static void __init get_mac(char dest[6])
-{
-       u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-       int i,j;
-
-       for (i = 0; i < 12; i++)
-               exchange_bit(read_opcode[i], 1);
-
-       for (j = 0; j < 6; j++) {
-               dest[j] = 0;
-               for (i = 0; i < 8; i++) {
-                       dest[j] <<= 1;
-                       dest[j] |= exchange_bit(0, 1);
-               }
-       }
-
-       /* turn off CS */
-       exchange_bit(0,0);
-}
-
-/*
- * Copy and increment ethernet MAC address by a small value.
- *
- * This is useful for systems where the only one MAC address is stored in
- * non-volatile memory for multiple ports.
- */
-static inline void eth_mac_add(unsigned char *dst, unsigned char *src,
-       unsigned int add)
-{
-       int i;
-
-       BUG_ON(add >= 256);
-
-       for (i = ETH_ALEN; i >= 0; i--) {
-               dst[i] = src[i] + add;
-               add = dst[i] < src[i];          /* compute carry */
-       }
-
-       WARN_ON(add);
-}
-
-static int __init mv643xx_eth_add_pds(void)
-{
-       unsigned char mac[ETH_ALEN];
-       int ret;
-
-       get_mac(mac);
-       eth_mac_add(eth0_pd.mac_addr, mac, 0);
-       eth_mac_add(eth1_pd.mac_addr, mac, 1);
-       ret = platform_add_devices(mv643xx_eth_pd_devs,
-                       ARRAY_SIZE(mv643xx_eth_pd_devs));
-
-       return ret;
-}
-
-device_initcall(mv643xx_eth_add_pds);
-
-#endif /* defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) */
diff --git a/arch/mips/momentum/ocelot_c/prom.c b/arch/mips/momentum/ocelot_c/prom.c
deleted file mode 100644 (file)
index b689cee..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright 2002 Momentum Computer Inc.
- * Author: Matthew Dharm <mdharm@momenco.com>
- *
- * Louis Hamilton, Red Hat, Inc.
- *   hamilton@redhat.com  [MIPS64 modifications]
- *
- * Based on Ocelot Linux port, which is
- * Copyright 2001 MontaVista Software Inc.
- * Author: jsun@mvista.com or jsun@junsun.net
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/bootmem.h>
-#include <linux/mv643xx.h>
-
-#include <asm/addrspace.h>
-#include <asm/bootinfo.h>
-#include <asm/pmon.h>
-
-#include "ocelot_c_fpga.h"
-
-struct callvectors* debug_vectors;
-
-extern unsigned long marvell_base;
-extern unsigned int cpu_clock;
-
-const char *get_system_type(void)
-{
-#ifdef CONFIG_CPU_SR71000
-       return "Momentum Ocelot-CS";
-#else
-       return "Momentum Ocelot-C";
-#endif
-}
-
-#ifdef CONFIG_64BIT
-
-unsigned long signext(unsigned long addr)
-{
-  addr &= 0xffffffff;
-  return (unsigned long)((int)addr);
-}
-
-void *get_arg(unsigned long args, int arc)
-{
-  unsigned long ul;
-  unsigned char *puc, uc;
-
-  args += (arc * 4);
-  ul = (unsigned long)signext(args);
-  puc = (unsigned char *)ul;
-  if (puc == 0)
-    return (void *)0;
-
-#ifdef CONFIG_CPU_LITTLE_ENDIAN
-  uc = *puc++;
-  ul = (unsigned long)uc;
-  uc = *puc++;
-  ul |= (((unsigned long)uc) << 8);
-  uc = *puc++;
-  ul |= (((unsigned long)uc) << 16);
-  uc = *puc++;
-  ul |= (((unsigned long)uc) << 24);
-#else  /* CONFIG_CPU_LITTLE_ENDIAN */
-  uc = *puc++;
-  ul = ((unsigned long)uc) << 24;
-  uc = *puc++;
-  ul |= (((unsigned long)uc) << 16);
-  uc = *puc++;
-  ul |= (((unsigned long)uc) << 8);
-  uc = *puc++;
-  ul |= ((unsigned long)uc);
-#endif  /* CONFIG_CPU_LITTLE_ENDIAN */
-  ul = signext(ul);
-  return (void *)ul;
-}
-
-char *arg64(unsigned long addrin, int arg_index)
-{
-  unsigned long args;
-  char *p;
-  args = signext(addrin);
-  p = (char *)get_arg(args, arg_index);
-  return p;
-}
-#endif  /* CONFIG_64BIT */
-
-
-void __init prom_init(void)
-{
-       int argc = fw_arg0;
-       char **arg = (char **) fw_arg1;
-       char **env = (char **) fw_arg2;
-       struct callvectors *cv = (struct callvectors *) fw_arg3;
-       int i;
-
-#ifdef CONFIG_64BIT
-       char *ptr;
-
-       printk("prom_init - MIPS64\n");
-       /* save the PROM vectors for debugging use */
-       debug_vectors = (struct callvectors *)signext((unsigned long)cv);
-
-       /* arg[0] is "g", the rest is boot parameters */
-       arcs_cmdline[0] = '\0';
-
-       for (i = 1; i < argc; i++) {
-               ptr = (char *)arg64((unsigned long)arg, i);
-               if ((strlen(arcs_cmdline) + strlen(ptr) + 1) >=
-                   sizeof(arcs_cmdline))
-                       break;
-               strcat(arcs_cmdline, ptr);
-               strcat(arcs_cmdline, " ");
-       }
-       i = 0;
-       while (1) {
-               ptr = (char *)arg64((unsigned long)env, i);
-               if (! ptr)
-                       break;
-
-               if (strncmp("gtbase", ptr, strlen("gtbase")) == 0) {
-                       marvell_base = simple_strtol(ptr + strlen("gtbase="),
-                                                       NULL, 16);
-
-                       if ((marvell_base & 0xffffffff00000000) == 0)
-                               marvell_base |= 0xffffffff00000000;
-
-                       printk("marvell_base set to 0x%016lx\n", marvell_base);
-               }
-               if (strncmp("cpuclock", ptr, strlen("cpuclock")) == 0) {
-                       cpu_clock = simple_strtol(ptr + strlen("cpuclock="),
-                                                       NULL, 10);
-                       printk("cpu_clock set to %d\n", cpu_clock);
-               }
-               i++;
-       }
-       printk("arcs_cmdline: %s\n", arcs_cmdline);
-
-#else   /* CONFIG_64BIT */
-       /* save the PROM vectors for debugging use */
-       debug_vectors = cv;
-
-       /* arg[0] is "g", the rest is boot parameters */
-       arcs_cmdline[0] = '\0';
-       for (i = 1; i < argc; i++) {
-               if (strlen(arcs_cmdline) + strlen(arg[i] + 1)
-                   >= sizeof(arcs_cmdline))
-                       break;
-               strcat(arcs_cmdline, arg[i]);
-               strcat(arcs_cmdline, " ");
-       }
-
-       while (*env) {
-               if (strncmp("gtbase", *env, strlen("gtbase")) == 0) {
-                       marvell_base = simple_strtol(*env + strlen("gtbase="),
-                                                       NULL, 16);
-               }
-               if (strncmp("cpuclock", *env, strlen("cpuclock")) == 0) {
-                       cpu_clock = simple_strtol(*env + strlen("cpuclock="),
-                                                       NULL, 10);
-               }
-               env++;
-       }
-#endif /* CONFIG_64BIT */
-
-       mips_machgroup = MACH_GROUP_MOMENCO;
-       mips_machtype = MACH_MOMENCO_OCELOT_C;
-
-#ifndef CONFIG_64BIT
-       debug_vectors->printf("Booting Linux kernel...\n");
-#endif
-}
-
-void __init prom_free_prom_memory(void)
-{
-}
diff --git a/arch/mips/momentum/ocelot_c/reset.c b/arch/mips/momentum/ocelot_c/reset.c
deleted file mode 100644 (file)
index 3fdcb64..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- *
- * Copyright (C) 1997, 2001 Ralf Baechle
- * Copyright 2001 MontaVista Software Inc.
- * Author: jsun@mvista.com or jsun@junsun.net
- *
- * Copyright (C) 2002 Momentum Computer Inc.
- * Author: Matthew Dharm <mdharm@momenco.com>
- *
- * Louis Hamilton, Red Hat, Inc.
- * hamilton@redhat.com  [MIPS64 modifications]
- */
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/processor.h>
-#include <asm/reboot.h>
-#include <asm/system.h>
-#include <linux/delay.h>
-
-void momenco_ocelot_restart(char *command)
-{
-       /* base address of timekeeper portion of part */
-       void *nvram = (void *)
-#ifdef CONFIG_64BIT
-               0xfffffffffc807000;
-#else
-               0xfc807000;
-#endif
-
-       /* Ask the NVRAM/RTC/watchdog chip to assert reset in 1/16 second */
-       writeb(0x84, nvram + 0xff7);
-
-       /* wait for the watchdog to go off */
-       mdelay(100+(1000/16));
-
-       /* if the watchdog fails for some reason, let people know */
-       printk(KERN_NOTICE "Watchdog reset failed\n");
-}
-
-void momenco_ocelot_halt(void)
-{
-       printk(KERN_NOTICE "\n** You can safely turn off the power\n");
-       while (1)
-               __asm__(".set\tmips3\n\t"
-                       "wait\n\t"
-                       ".set\tmips0");
-}
-
-void momenco_ocelot_power_off(void)
-{
-       momenco_ocelot_halt();
-}
diff --git a/arch/mips/momentum/ocelot_c/setup.c b/arch/mips/momentum/ocelot_c/setup.c
deleted file mode 100644 (file)
index 0b6b233..0000000
+++ /dev/null
@@ -1,362 +0,0 @@
-/*
- * BRIEF MODULE DESCRIPTION
- * Momentum Computer Ocelot-C and -CS board dependent boot routines
- *
- * Copyright (C) 1996, 1997, 2001  Ralf Baechle
- * Copyright (C) 2000 RidgeRun, Inc.
- * Copyright (C) 2001 Red Hat, Inc.
- * Copyright (C) 2002 Momentum Computer
- *
- * Author: Matthew Dharm, Momentum Computer
- *   mdharm@momenco.com
- *
- * Louis Hamilton, Red Hat, Inc.
- *   hamilton@redhat.com  [MIPS64 modifications]
- *
- * Author: RidgeRun, Inc.
- *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
- *
- * Copyright 2001 MontaVista Software Inc.
- * Author: jsun@mvista.com or jsun@junsun.net
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-#include <linux/bcd.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/swap.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/pm.h>
-#include <linux/timex.h>
-#include <linux/vmalloc.h>
-#include <linux/mv643xx.h>
-
-#include <asm/time.h>
-#include <asm/bootinfo.h>
-#include <asm/page.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/pci.h>
-#include <asm/processor.h>
-#include <asm/reboot.h>
-#include <asm/marvell.h>
-#include <linux/bootmem.h>
-#include <linux/blkdev.h>
-#include "ocelot_c_fpga.h"
-
-unsigned long marvell_base;
-unsigned int cpu_clock;
-
-/* These functions are used for rebooting or halting the machine*/
-extern void momenco_ocelot_restart(char *command);
-extern void momenco_ocelot_halt(void);
-extern void momenco_ocelot_power_off(void);
-
-void momenco_time_init(void);
-
-static char reset_reason;
-
-void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, unsigned long entryhi, unsigned long pagemask);
-
-static unsigned long ENTRYLO(unsigned long paddr)
-{
-       return ((paddr & PAGE_MASK) |
-              (_PAGE_PRESENT | __READABLE | __WRITEABLE | _PAGE_GLOBAL |
-               _CACHE_UNCACHED)) >> 6;
-}
-
-/* setup code for a handoff from a version 2 PMON 2000 PROM */
-void PMON_v2_setup(void)
-{
-       /* Some wired TLB entries for the MV64340 and perhiperals. The
-          MV64340 is going to be hit on every IRQ anyway - there's
-          absolutely no point in letting it be a random TLB entry, as
-          it'll just cause needless churning of the TLB. And we use
-          the other half for the serial port, which is just a PITA
-          otherwise :)
-
-               Device                  Physical        Virtual
-               MV64340 Internal Regs   0xf4000000      0xf4000000
-               Ocelot-C[S] PLD (CS0)   0xfc000000      0xfc000000
-               NVRAM (CS1)             0xfc800000      0xfc800000
-               UARTs (CS2)             0xfd000000      0xfd000000
-               Internal SRAM           0xfe000000      0xfe000000
-               M-Systems DOC (CS3)     0xff000000      0xff000000
-       */
-  printk("PMON_v2_setup\n");
-
-#ifdef CONFIG_64BIT
-       /* marvell and extra space */
-       add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000), 0xfffffffff4000000, PM_64K);
-       /* fpga, rtc, and uart */
-       add_wired_entry(ENTRYLO(0xfc000000), ENTRYLO(0xfd000000), 0xfffffffffc000000, PM_16M);
-       /* m-sys and internal SRAM */
-       add_wired_entry(ENTRYLO(0xfe000000), ENTRYLO(0xff000000), 0xfffffffffe000000, PM_16M);
-
-       marvell_base = 0xfffffffff4000000;
-#else
-       /* marvell and extra space */
-       add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000), 0xf4000000, PM_64K);
-       /* fpga, rtc, and uart */
-       add_wired_entry(ENTRYLO(0xfc000000), ENTRYLO(0xfd000000), 0xfc000000, PM_16M);
-       /* m-sys and internal SRAM */
-       add_wired_entry(ENTRYLO(0xfe000000), ENTRYLO(0xff000000), 0xfe000000, PM_16M);
-
-       marvell_base = 0xf4000000;
-#endif
-}
-
-unsigned long m48t37y_get_time(void)
-{
-#ifdef CONFIG_64BIT
-       unsigned char *rtc_base = (unsigned char*)0xfffffffffc800000;
-#else
-       unsigned char* rtc_base = (unsigned char*)0xfc800000;
-#endif
-       unsigned int year, month, day, hour, min, sec;
-       unsigned long flags;
-
-       spin_lock_irqsave(&rtc_lock, flags);
-       /* stop the update */
-       rtc_base[0x7ff8] = 0x40;
-
-       year = BCD2BIN(rtc_base[0x7fff]);
-       year += BCD2BIN(rtc_base[0x7ff1]) * 100;
-
-       month = BCD2BIN(rtc_base[0x7ffe]);
-
-       day = BCD2BIN(rtc_base[0x7ffd]);
-
-       hour = BCD2BIN(rtc_base[0x7ffb]);
-       min = BCD2BIN(rtc_base[0x7ffa]);
-       sec = BCD2BIN(rtc_base[0x7ff9]);
-
-       /* start the update */
-       rtc_base[0x7ff8] = 0x00;
-       spin_unlock_irqrestore(&rtc_lock, flags);
-
-       return mktime(year, month, day, hour, min, sec);
-}
-
-int m48t37y_set_time(unsigned long sec)
-{
-#ifdef CONFIG_64BIT
-       unsigned char* rtc_base = (unsigned char*)0xfffffffffc800000;
-#else
-       unsigned char* rtc_base = (unsigned char*)0xfc800000;
-#endif
-       struct rtc_time tm;
-       unsigned long flags;
-
-       /* convert to a more useful format -- note months count from 0 */
-       to_tm(sec, &tm);
-       tm.tm_mon += 1;
-
-       spin_lock_irqsave(&rtc_lock, flags);
-       /* enable writing */
-       rtc_base[0x7ff8] = 0x80;
-
-       /* year */
-       rtc_base[0x7fff] = BIN2BCD(tm.tm_year % 100);
-       rtc_base[0x7ff1] = BIN2BCD(tm.tm_year / 100);
-
-       /* month */
-       rtc_base[0x7ffe] = BIN2BCD(tm.tm_mon);
-
-       /* day */
-       rtc_base[0x7ffd] = BIN2BCD(tm.tm_mday);
-
-       /* hour/min/sec */
-       rtc_base[0x7ffb] = BIN2BCD(tm.tm_hour);
-       rtc_base[0x7ffa] = BIN2BCD(tm.tm_min);
-       rtc_base[0x7ff9] = BIN2BCD(tm.tm_sec);
-
-       /* day of week -- not really used, but let's keep it up-to-date */
-       rtc_base[0x7ffc] = BIN2BCD(tm.tm_wday + 1);
-
-       /* disable writing */
-       rtc_base[0x7ff8] = 0x00;
-       spin_unlock_irqrestore(&rtc_lock, flags);
-
-       return 0;
-}
-
-void __init plat_timer_setup(struct irqaction *irq)
-{
-       setup_irq(7, irq);
-}
-
-void momenco_time_init(void)
-{
-#ifdef CONFIG_CPU_SR71000
-       mips_hpt_frequency = cpu_clock;
-#elif defined(CONFIG_CPU_RM7000)
-       mips_hpt_frequency = cpu_clock / 2;
-#else
-#error Unknown CPU for this board
-#endif
-       printk("momenco_time_init cpu_clock=%d\n", cpu_clock);
-
-       rtc_mips_get_time = m48t37y_get_time;
-       rtc_mips_set_time = m48t37y_set_time;
-}
-
-void __init plat_mem_setup(void)
-{
-       unsigned int tmpword;
-
-       board_time_init = momenco_time_init;
-
-       _machine_restart = momenco_ocelot_restart;
-       _machine_halt = momenco_ocelot_halt;
-       pm_power_off = momenco_ocelot_power_off;
-
-       /*
-        * initrd_start = (unsigned long)ocelot_initrd_start;
-        * initrd_end = (unsigned long)ocelot_initrd_start + (ulong)ocelot_initrd_size;
-        * initrd_below_start_ok = 1;
-        */
-
-       /* do handoff reconfiguration */
-       PMON_v2_setup();
-
-       /* shut down ethernet ports, just to be sure our memory doesn't get
-        * corrupted by random ethernet traffic.
-        */
-       MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(0), 0xff << 8);
-       MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(1), 0xff << 8);
-       MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(0), 0xff << 8);
-       MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(1), 0xff << 8);
-       do {}
-         while (MV_READ(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(0)) & 0xff);
-       do {}
-         while (MV_READ(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(1)) & 0xff);
-       do {}
-         while (MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(0)) & 0xff);
-       do {}
-         while (MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(1)) & 0xff);
-       MV_WRITE(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(0),
-                MV_READ(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(0)) & ~1);
-       MV_WRITE(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(1),
-                MV_READ(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(1)) & ~1);
-
-       /* Turn off the Bit-Error LED */
-       OCELOT_FPGA_WRITE(0x80, CLR);
-
-       tmpword = OCELOT_FPGA_READ(BOARDREV);
-#ifdef CONFIG_CPU_SR71000
-       if (tmpword < 26)
-               printk("Momenco Ocelot-CS: Board Assembly Rev. %c\n",
-                       'A'+tmpword);
-       else
-               printk("Momenco Ocelot-CS: Board Assembly Revision #0x%x\n",
-                       tmpword);
-#else
-       if (tmpword < 26)
-               printk("Momenco Ocelot-C: Board Assembly Rev. %c\n",
-                       'A'+tmpword);
-       else
-               printk("Momenco Ocelot-C: Board Assembly Revision #0x%x\n",
-                       tmpword);
-#endif
-
-       tmpword = OCELOT_FPGA_READ(FPGA_REV);
-       printk("FPGA Rev: %d.%d\n", tmpword>>4, tmpword&15);
-       tmpword = OCELOT_FPGA_READ(RESET_STATUS);
-       printk("Reset reason: 0x%x\n", tmpword);
-       switch (tmpword) {
-               case 0x1:
-                       printk("  - Power-up reset\n");
-                       break;
-               case 0x2:
-                       printk("  - Push-button reset\n");
-                       break;
-               case 0x4:
-                       printk("  - cPCI bus reset\n");
-                       break;
-               case 0x8:
-                       printk("  - Watchdog reset\n");
-                       break;
-               case 0x10:
-                       printk("  - Software reset\n");
-                       break;
-               default:
-                       printk("  - Unknown reset cause\n");
-       }
-       reset_reason = tmpword;
-       OCELOT_FPGA_WRITE(0xff, RESET_STATUS);
-
-       tmpword = OCELOT_FPGA_READ(CPCI_ID);
-       printk("cPCI ID register: 0x%02x\n", tmpword);
-       printk("  - Slot number: %d\n", tmpword & 0x1f);
-       printk("  - PCI bus present: %s\n", tmpword & 0x40 ? "yes" : "no");
-       printk("  - System Slot: %s\n", tmpword & 0x20 ? "yes" : "no");
-
-       tmpword = OCELOT_FPGA_READ(BOARD_STATUS);
-       printk("Board Status register: 0x%02x\n", tmpword);
-       printk("  - User jumper: %s\n", (tmpword & 0x80)?"installed":"absent");
-       printk("  - Boot flash write jumper: %s\n", (tmpword&0x40)?"installed":"absent");
-       printk("  - L3 Cache size: %d MiB\n", (1<<((tmpword&12) >> 2))&~1);
-       printk("  - SDRAM size: %d MiB\n", 1<<(6+(tmpword&3)));
-
-       switch(tmpword &3) {
-       case 3:
-               /* 512MiB */
-               add_memory_region(0x0, 0x200<<20, BOOT_MEM_RAM);
-               break;
-       case 2:
-               /* 256MiB */
-               add_memory_region(0x0, 0x100<<20, BOOT_MEM_RAM);
-               break;
-       case 1:
-               /* 128MiB */
-               add_memory_region(0x0,  0x80<<20, BOOT_MEM_RAM);
-               break;
-       case 0:
-               /* 1GiB -- needs CONFIG_HIGHMEM */
-               add_memory_region(0x0, 0x400<<20, BOOT_MEM_RAM);
-               break;
-       }
-}
-
-/*
- * This needs to be one of the first initcalls, because no I/O port access
- * can work before this
- */
-static int io_base_ioremap(void)
-{
-       void __iomem * io_remap_range = ioremap(0xc0000000UL, 0x10000);
-
-       if (!io_remap_range)
-               panic("Could not ioremap I/O port range");
-
-       set_io_port_base((unsigned long) io_remap_range);
-
-       return 0;
-}
-
-module_init(io_base_ioremap);
diff --git a/arch/mips/momentum/ocelot_c/uart-irq.c b/arch/mips/momentum/ocelot_c/uart-irq.c
deleted file mode 100644 (file)
index de1a31e..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright 2002 Momentum Computer
- * Author: mdharm@momenco.com
- *
- * arch/mips/momentum/ocelot_c/uart-irq.c
- *     Interrupt routines for UARTs.  Interrupt numbers are assigned from
- *     80 to 81 (2 interrupt sources).
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/kernel_stat.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include "ocelot_c_fpga.h"
-
-static inline int ls1bit8(unsigned int x)
-{
-        int b = 7, s;
-
-        s =  4; if (((unsigned char)(x << 4)) == 0) s = 0; b -= s; x <<= s;
-        s =  2; if (((unsigned char)(x << 2)) == 0) s = 0; b -= s; x <<= s;
-        s =  1; if (((unsigned char)(x << 1)) == 0) s = 0; b -= s;
-
-        return b;
-}
-
-/* mask off an interrupt -- 0 is enable, 1 is disable */
-static inline void mask_uart_irq(unsigned int irq)
-{
-       uint8_t value;
-
-       value = OCELOT_FPGA_READ(UART_INTMASK);
-       value |= 1 << (irq - 74);
-       OCELOT_FPGA_WRITE(value, UART_INTMASK);
-
-       /* read the value back to assure that it's really been written */
-       value = OCELOT_FPGA_READ(UART_INTMASK);
-}
-
-/* unmask an interrupt -- 0 is enable, 1 is disable */
-static inline void unmask_uart_irq(unsigned int irq)
-{
-       uint8_t value;
-
-       value = OCELOT_FPGA_READ(UART_INTMASK);
-       value &= ~(1 << (irq - 74));
-       OCELOT_FPGA_WRITE(value, UART_INTMASK);
-
-       /* read the value back to assure that it's really been written */
-       value = OCELOT_FPGA_READ(UART_INTMASK);
-}
-
-/*
- * Interrupt handler for interrupts coming from the FPGA chip.
- */
-void ll_uart_irq(void)
-{
-       unsigned int irq_src, irq_mask;
-
-       /* read the interrupt status registers */
-       irq_src = OCELOT_FPGA_READ(UART_INTSTAT);
-       irq_mask = OCELOT_FPGA_READ(UART_INTMASK);
-
-       /* mask for just the interrupts we want */
-       irq_src &= ~irq_mask;
-
-       do_IRQ(ls1bit8(irq_src) + 74);
-}
-
-struct irq_chip uart_irq_type = {
-       .name = "UART/FPGA",
-       .ack = mask_uart_irq,
-       .mask = mask_uart_irq,
-       .mask_ack = mask_uart_irq,
-       .unmask = unmask_uart_irq,
-};
-
-void uart_irq_init(void)
-{
-       set_irq_chip_and_handler(80, &uart_irq_type, handle_level_irq);
-       set_irq_chip_and_handler(81, &uart_irq_type, handle_level_irq);
-}
index aba3dbf47eda8efebc11d3b81383e680f69aff9b..c58bd3d036f4528e5f379844932aa1e6f84cb6f1 100644 (file)
@@ -2,16 +2,14 @@
 # Makefile for the PCI specific kernel interface routines under Linux.
 #
 
-obj-y                          += pci.o pci-dac.o
+obj-y                          += pci.o
 
 #
 # PCI bus host bridge specific code
 #
 obj-$(CONFIG_MIPS_BONITO64)    += ops-bonito64.o
 obj-$(CONFIG_PCI_GT64XXX_PCI0) += ops-gt64xxx_pci0.o
-obj-$(CONFIG_PCI_MARVELL)      += ops-marvell.o
 obj-$(CONFIG_MIPS_MSC)         += ops-msc.o
-obj-$(CONFIG_MIPS_NILE4)       += ops-nile4.o
 obj-$(CONFIG_MIPS_TX3927)      += ops-tx3927.o
 obj-$(CONFIG_PCI_VR41XX)       += ops-vr41xx.o pci-vr41xx.o
 obj-$(CONFIG_NEC_CMBVR4133)    += fixup-vr4133.o
@@ -22,17 +20,17 @@ obj-$(CONFIG_MARKEINS)              += ops-emma2rh.o pci-emma2rh.o fixup-emma2rh.o
 #
 obj-$(CONFIG_BASLER_EXCITE)    += ops-titan.o pci-excite.o fixup-excite.o
 obj-$(CONFIG_DDB5477)          += fixup-ddb5477.o pci-ddb5477.o ops-ddb5477.o
-obj-$(CONFIG_LASAT)            += pci-lasat.o
 obj-$(CONFIG_MIPS_ATLAS)       += fixup-atlas.o
 obj-$(CONFIG_MIPS_COBALT)      += fixup-cobalt.o
-obj-$(CONFIG_MIPS_EV64120)     += pci-ev64120.o
 obj-$(CONFIG_SOC_AU1500)       += fixup-au1000.o ops-au1000.o
 obj-$(CONFIG_SOC_AU1550)       += fixup-au1000.o ops-au1000.o
 obj-$(CONFIG_SOC_PNX8550)      += fixup-pnx8550.o ops-pnx8550.o
+obj-$(CONFIG_LEMOTE_FULONG)    += fixup-lm2e.o ops-bonito64.o
 obj-$(CONFIG_MIPS_MALTA)       += fixup-malta.o
 obj-$(CONFIG_MOMENCO_OCELOT)   += fixup-ocelot.o pci-ocelot.o
-obj-$(CONFIG_MOMENCO_OCELOT_3) += fixup-ocelot3.o
-obj-$(CONFIG_MOMENCO_OCELOT_C) += fixup-ocelot-c.o pci-ocelot-c.o
+obj-$(CONFIG_PMC_MSP7120_GW)   += fixup-pmcmsp.o ops-pmcmsp.o
+obj-$(CONFIG_PMC_MSP7120_EVAL) += fixup-pmcmsp.o ops-pmcmsp.o
+obj-$(CONFIG_PMC_MSP7120_FPGA) += fixup-pmcmsp.o ops-pmcmsp.o
 obj-$(CONFIG_PMC_YOSEMITE)     += fixup-yosemite.o ops-titan.o ops-titan-ht.o \
                                   pci-yosemite.o
 obj-$(CONFIG_SGI_IP27)         += ops-bridge.o pci-ip27.o
index c6cd6e9cdfbc8d4b29dc804f173e8cfbc8de596a..45224fd2c7babf3ff4303eebfb5a02479ff9befb 100644 (file)
@@ -58,7 +58,7 @@ static char irq_tab[][5] __initdata = {
        {0,     0,      0,      0,      0 }     /* 21: Unused */
 };
 
-int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
        return irq_tab[slot][pin];
 }
index c2f8304fe55b966767c82302774b691033014caf..ca0276c8070aeeb94f738d59a3edddcae4bd6d68 100644 (file)
@@ -35,7 +35,7 @@
 
 extern char irq_tab_alchemy[][5];
 
-int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
        return irq_tab_alchemy[slot][pin];
 }
index 1e530751936ceafc142b379614b9cd136522e1d2..1416bca6d1a3f8962bd23e76d34d0668c703d767 100644 (file)
@@ -38,7 +38,7 @@ static char irq_tab_capcella[][5] __initdata = {
  [14] = { -1, INTA, INTB, INTC, INTD }
 };
 
-int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
        return irq_tab_capcella[slot][pin];
 }
index d57ffd7242ca1210755019e3c458e9397bc50b28..76b4f0ffb1e5f7a276829c19e5903536856e1523 100644 (file)
@@ -58,8 +58,6 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1,
 
 static void qube_raq_galileo_fixup(struct pci_dev *dev)
 {
-       unsigned short galileo_id;
-
        if (dev->devfn != PCI_DEVFN(0, 0))
                return;
 
@@ -84,16 +82,14 @@ static void qube_raq_galileo_fixup(struct pci_dev *dev)
         * Therefore we must set the disconnect/retry cycle values to
         * something sensible when using the new Galileo.
         */
-       pci_read_config_word(dev, PCI_REVISION_ID, &galileo_id);
-       galileo_id &= 0xff;     /* mask off class info */
 
-       printk(KERN_INFO "Galileo: revision %u\n", galileo_id);
+       printk(KERN_INFO "Galileo: revision %u\n", dev->revision);
 
 #if 0
-       if (galileo_id >= 0x10) {
+       if (dev->revision >= 0x10) {
                /* New Galileo, assumes PCI stop line to VIA is connected. */
                GT_WRITE(GT_PCI0_TOR_OFS, 0x4020);
-       } else if (galileo_id == 0x1 || galileo_id == 0x2)
+       } else if (dev->revision == 0x1 || dev->revision == 0x2)
 #endif
        {
                signed int timeo;
@@ -161,7 +157,7 @@ static char irq_tab_raq2[] __initdata = {
   [COBALT_PCICONF_ETH1]    = COBALT_ETH1_IRQ
 };
 
-int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
        if (cobalt_board_id < COBALT_BRD_ID_QUBE2)
                return irq_tab_qube1[slot];
index 7abcfd175d43d3eb9f40db583b65e3a7c31ecb27..a2705895561d983f54e48f52594f1594e4166cd3 100644 (file)
@@ -89,7 +89,7 @@ static void __devinit emma2rh_pci_host_fixup(struct pci_dev *dev)
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_EMMA2RH,
                         emma2rh_pci_host_fixup);
 
-int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
        return irq_map[slot][pin];
 }
index 1da696d43f006816e6f8c02400e85d8906210593..cd64d9f177c4c796d3dc811379dbd737289baa31 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/pci.h>
 #include <excite.h>
 
-int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
        if (pin == 0)
                return -1;
index 3e66b0aa63ca5096c7b63d97e07952516234e600..190fffd08d3e495a1cd42e6e0ebbdd2e3081045a 100644 (file)
@@ -39,7 +39,7 @@ static char irq_tab_mace[][5] __initdata = {
  * irqs.  I suppose a device without a pin A will thank us for doing it
  * right if there exists such a broken piece of crap.
  */
-int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
        return irq_tab_mace[slot][pin];
 }
index 73d18503517c716c937f9577fc76801ef5985de6..e974394be7bc271b4e18e35130e3328ed1a73c7e 100644 (file)
@@ -33,7 +33,7 @@
 
 #include <asm/jmr3927/jmr3927.h>
 
-int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
        unsigned char irq = pin;
 
diff --git a/arch/mips/pci/fixup-lm2e.c b/arch/mips/pci/fixup-lm2e.c
new file mode 100644 (file)
index 0000000..e18ae4f
--- /dev/null
@@ -0,0 +1,242 @@
+/*
+ * fixup-lm2e.c
+ *
+ * Copyright (C) 2004 ICT CAS
+ * Author: Li xiaoyu, ICT CAS
+ *   lixy@ict.ac.cn
+ *
+ * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <asm/mips-boards/bonito64.h>
+
+/* South bridge slot number is set by the pci probe process */
+static u8 sb_slot = 5;
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+       int irq = 0;
+
+       if (slot == sb_slot) {
+               switch (PCI_FUNC(dev->devfn)) {
+               case 2:
+                       irq = 10;
+                       break;
+               case 3:
+                       irq = 11;
+                       break;
+               case 5:
+                       irq = 9;
+                       break;
+               }
+       } else {
+               irq = BONITO_IRQ_BASE + 25 + pin;
+       }
+       return irq;
+
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+       return 0;
+}
+
+static void __init loongson2e_nec_fixup(struct pci_dev *pdev)
+{
+       unsigned int val;
+
+       /* Configues port 1, 2, 3, 4 to be validate*/
+       pci_read_config_dword(pdev, 0xe0, &val);
+       pci_write_config_dword(pdev, 0xe0, (val & ~7) | 0x4);
+
+       /* System clock is 48-MHz Oscillator. */
+       pci_write_config_dword(pdev, 0xe4, 1 << 5);
+}
+
+static void __init loongson2e_686b_func0_fixup(struct pci_dev *pdev)
+{
+       unsigned char c;
+
+       sb_slot = PCI_SLOT(pdev->devfn);
+
+       printk(KERN_INFO "via686b fix: ISA bridge\n");
+
+       /*  Enable I/O Recovery time */
+       pci_write_config_byte(pdev, 0x40, 0x08);
+
+       /*  Enable ISA refresh */
+       pci_write_config_byte(pdev, 0x41, 0x01);
+
+       /*  disable ISA line buffer */
+       pci_write_config_byte(pdev, 0x45, 0x00);
+
+       /*  Gate INTR, and flush line buffer */
+       pci_write_config_byte(pdev, 0x46, 0xe0);
+
+       /*  Disable PCI Delay Transaction, Enable EISA ports 4D0/4D1. */
+       /* pci_write_config_byte(pdev, 0x47, 0x20); */
+
+       /*
+        *  enable PCI Delay Transaction, Enable EISA ports 4D0/4D1.
+        *  enable time-out timer
+        */
+       pci_write_config_byte(pdev, 0x47, 0xe6);
+
+       /*
+        * enable level trigger on pci irqs: 9,10,11,13
+        * important! without this PCI interrupts won't work
+        */
+       outb(0x2e, 0x4d1);
+
+       /*  512 K PCI Decode */
+       pci_write_config_byte(pdev, 0x48, 0x01);
+
+       /*  Wait for PGNT before grant to ISA Master/DMA */
+       pci_write_config_byte(pdev, 0x4a, 0x84);
+
+       /*
+        * Plug'n'Play
+        *
+        *  Parallel DRQ 3, Floppy DRQ 2 (default)
+        */
+       pci_write_config_byte(pdev, 0x50, 0x0e);
+
+       /*
+        * IRQ Routing for Floppy and Parallel port
+        *
+        *  IRQ 6 for floppy, IRQ 7 for parallel port
+        */
+       pci_write_config_byte(pdev, 0x51, 0x76);
+
+       /* IRQ Routing for serial ports (take IRQ 3 and 4) */
+       pci_write_config_byte(pdev, 0x52, 0x34);
+
+       /*  All IRQ's level triggered. */
+       pci_write_config_byte(pdev, 0x54, 0x00);
+
+       /* route PIRQA-D irq */
+       pci_write_config_byte(pdev, 0x55, 0x90);        /* bit 7-4, PIRQA */
+       pci_write_config_byte(pdev, 0x56, 0xba);        /* bit 7-4, PIRQC; */
+                                                       /* 3-0, PIRQB */
+       pci_write_config_byte(pdev, 0x57, 0xd0);        /* bit 7-4, PIRQD */
+
+       /* enable function 5/6, audio/modem */
+       pci_read_config_byte(pdev, 0x85, &c);
+       c &= ~(0x3 << 2);
+       pci_write_config_byte(pdev, 0x85, c);
+
+       printk(KERN_INFO"via686b fix: ISA bridge done\n");
+}
+
+static void __init loongson2e_686b_func1_fixup(struct pci_dev *pdev)
+{
+       printk(KERN_INFO"via686b fix: IDE\n");
+
+       /* Modify IDE controller setup */
+       pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 48);
+       pci_write_config_byte(pdev, PCI_COMMAND,
+                             PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+                             PCI_COMMAND_MASTER);
+       pci_write_config_byte(pdev, 0x40, 0x0b);
+       /* legacy mode */
+       pci_write_config_byte(pdev, 0x42, 0x09);
+
+#if 1/* play safe, otherwise we may see notebook's usb keyboard lockup */
+       /* disable read prefetch/write post buffers */
+       pci_write_config_byte(pdev, 0x41, 0x02);
+
+       /* use 3/4 as fifo thresh hold  */
+       pci_write_config_byte(pdev, 0x43, 0x0a);
+       pci_write_config_byte(pdev, 0x44, 0x00);
+
+       pci_write_config_byte(pdev, 0x45, 0x00);
+#else
+       pci_write_config_byte(pdev, 0x41, 0xc2);
+       pci_write_config_byte(pdev, 0x43, 0x35);
+       pci_write_config_byte(pdev, 0x44, 0x1c);
+
+       pci_write_config_byte(pdev, 0x45, 0x10);
+#endif
+
+       printk(KERN_INFO"via686b fix: IDE done\n");
+}
+
+static void __init loongson2e_686b_func2_fixup(struct pci_dev *pdev)
+{
+       /* irq routing */
+       pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, 10);
+}
+
+static void __init loongson2e_686b_func3_fixup(struct pci_dev *pdev)
+{
+       /* irq routing */
+       pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, 11);
+}
+
+static void __init loongson2e_686b_func5_fixup(struct pci_dev *pdev)
+{
+       unsigned int val;
+       unsigned char c;
+
+       /* enable IO */
+       pci_write_config_byte(pdev, PCI_COMMAND,
+                             PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+                             PCI_COMMAND_MASTER);
+       pci_read_config_dword(pdev, 0x4, &val);
+       pci_write_config_dword(pdev, 0x4, val | 1);
+
+       /* route ac97 IRQ */
+       pci_write_config_byte(pdev, 0x3c, 9);
+
+       pci_read_config_byte(pdev, 0x8, &c);
+
+       /* link control: enable link & SGD PCM output */
+       pci_write_config_byte(pdev, 0x41, 0xcc);
+
+       /* disable game port, FM, midi, sb, enable write to reg2c-2f */
+       pci_write_config_byte(pdev, 0x42, 0x20);
+
+       /* we are using Avance logic codec */
+       pci_write_config_word(pdev, 0x2c, 0x1005);
+       pci_write_config_word(pdev, 0x2e, 0x4710);
+       pci_read_config_dword(pdev, 0x2c, &val);
+
+       pci_write_config_byte(pdev, 0x42, 0x0);
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686,
+                        loongson2e_686b_func0_fixup);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1,
+                        loongson2e_686b_func1_fixup);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2,
+                        loongson2e_686b_func2_fixup);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3,
+                        loongson2e_686b_func3_fixup);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5,
+                        loongson2e_686b_func5_fixup);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB,
+                        loongson2e_nec_fixup);
index bf2c41d1e9c53858601c8161204f022cc9fdb7c6..0f48498bc231b074f1ec8b401e9660b29bf37e5c 100644 (file)
@@ -36,7 +36,7 @@ static char irq_tab[][5] __initdata = {
        {0,     PCID,   PCIA,   PCIB,   PCIC }  /* 21: PCI Slot 4 */
 };
 
-int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
        int virq;
        virq = irq_tab[slot][pin];
index 3c9ae41f7517333bd23f7db276e64a5d7d0f4db0..5911596257222dec18a807e3fdae132ac2548a50 100644 (file)
@@ -34,7 +34,7 @@ static const int irq_tab_mpc30x[] __initdata = {
  [29] = MQ200_IRQ,
 };
 
-int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
        if (slot == 30)
                return internal_func_irqs[PCI_FUNC(dev->devfn)];
diff --git a/arch/mips/pci/fixup-ocelot-c.c b/arch/mips/pci/fixup-ocelot-c.c
deleted file mode 100644 (file)
index d454948..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2002 Momentum Computer Inc.
- * Author: Matthew Dharm <mdharm@momenco.com>
- *
- * Based on work for the Linux port to the Ocelot board, which is
- * Copyright 2001 MontaVista Software Inc.
- * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
- *
- * arch/mips/momentum/ocelot_g/pci.c
- *     Board-specific PCI routines for mv64340 controller.
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the 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/types.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-
-int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
-{
-       int bus = dev->bus->number;
-
-       if (bus == 0 && slot == 1)
-               return 2;       /* PCI-X A */
-       if (bus == 1 && slot == 1)
-               return 12;      /* PCI-X B */
-       if (bus == 1 && slot == 2)
-               return 4;       /* PCI B */
-
-return 0;
-       panic("Whooops in pcibios_map_irq");
-}
-
-/* Do platform specific device initialization at pci_enable_device() time */
-int pcibios_plat_dev_init(struct pci_dev *dev)
-{
-       return 0;
-}
diff --git a/arch/mips/pci/fixup-ocelot3.c b/arch/mips/pci/fixup-ocelot3.c
deleted file mode 100644 (file)
index ececc03..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2004 Montavista Software Inc.
- * Author: Manish Lachwani (mlachwani@mvista.com)
- *
- * Looking at the schematics for the Ocelot-3 board, there are
- * two PCI busses and each bus has two PCI slots.
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <asm/mipsregs.h>
-
-/*
- * Do platform specific device initialization at
- * pci_enable_device() time
- */
-int pcibios_plat_dev_init(struct pci_dev *dev)
-{
-       return 0;
-}
-
-int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
-{
-       int bus = dev->bus->number;
-
-       if (bus == 0 && slot == 1)
-               return 2;       /* PCI-X A */
-       if (bus == 0 && slot == 2)
-               return 3;       /* PCI-X B */
-       if (bus == 1 && slot == 1)
-               return 4;       /* PCI A */
-       if (bus == 1 && slot == 2)
-               return 5;       /* PCI B */
-
-return 0;
-       panic("Whooops in pcibios_map_irq");
-}
diff --git a/arch/mips/pci/fixup-pmcmsp.c b/arch/mips/pci/fixup-pmcmsp.c
new file mode 100644 (file)
index 0000000..0026121
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ * PMC-Sierra MSP board specific pci fixups.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Copyright 2005-2007 PMC-Sierra, Inc
+ *
+ * Author: MontaVista Software, Inc.
+ *             ppopov@mvista.com or source@mvista.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifdef CONFIG_PCI
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/byteorder.h>
+
+#include <msp_pci.h>
+#include <msp_cic_int.h>
+
+/* PCI interrupt pins */
+#define IRQ4   MSP_INT_EXT4
+#define IRQ5   MSP_INT_EXT5
+#define IRQ6   MSP_INT_EXT6
+
+#if defined(CONFIG_PMC_MSP7120_GW)
+/* Garibaldi Board IRQ wiring to PCI slots */
+static char irq_tab[][5] __initdata = {
+       /* INTA    INTB    INTC    INTD */
+       {0,     0,      0,      0,      0 },    /*    (AD[0]): Unused */
+       {0,     0,      0,      0,      0 },    /*    (AD[1]): Unused */
+       {0,     0,      0,      0,      0 },    /*    (AD[2]): Unused */
+       {0,     0,      0,      0,      0 },    /*    (AD[3]): Unused */
+       {0,     0,      0,      0,      0 },    /*    (AD[4]): Unused */
+       {0,     0,      0,      0,      0 },    /*    (AD[5]): Unused */
+       {0,     0,      0,      0,      0 },    /*    (AD[6]): Unused */
+       {0,     0,      0,      0,      0 },    /*    (AD[7]): Unused */
+       {0,     0,      0,      0,      0 },    /*    (AD[8]): Unused */
+       {0,     0,      0,      0,      0 },    /*    (AD[9]): Unused */
+       {0,     0,      0,      0,      0 },    /*  0 (AD[10]): Unused */
+       {0,     0,      0,      0,      0 },    /*  1 (AD[11]): Unused */
+       {0,     0,      0,      0,      0 },    /*  2 (AD[12]): Unused */
+       {0,     0,      0,      0,      0 },    /*  3 (AD[13]): Unused */
+       {0,     0,      0,      0,      0 },    /*  4 (AD[14]): Unused */
+       {0,     0,      0,      0,      0 },    /*  5 (AD[15]): Unused */
+       {0,     0,      0,      0,      0 },    /*  6 (AD[16]): Unused */
+       {0,     0,      0,      0,      0 },    /*  7 (AD[17]): Unused */
+       {0,     0,      0,      0,      0 },    /*  8 (AD[18]): Unused */
+       {0,     0,      0,      0,      0 },    /*  9 (AD[19]): Unused */
+       {0,     0,      0,      0,      0 },    /* 10 (AD[20]): Unused */
+       {0,     0,      0,      0,      0 },    /* 11 (AD[21]): Unused */
+       {0,     0,      0,      0,      0 },    /* 12 (AD[22]): Unused */
+       {0,     0,      0,      0,      0 },    /* 13 (AD[23]): Unused */
+       {0,     0,      0,      0,      0 },    /* 14 (AD[24]): Unused */
+       {0,     0,      0,      0,      0 },    /* 15 (AD[25]): Unused */
+       {0,     0,      0,      0,      0 },    /* 16 (AD[26]): Unused */
+       {0,     0,      0,      0,      0 },    /* 17 (AD[27]): Unused */
+       {0,     IRQ4,   IRQ4,   0,      0 },    /* 18 (AD[28]): slot 0 */
+       {0,     0,      0,      0,      0 },    /* 19 (AD[29]): Unused */
+       {0,     IRQ5,   IRQ5,   0,      0 },    /* 20 (AD[30]): slot 1 */
+       {0,     IRQ6,   IRQ6,   0,      0 }     /* 21 (AD[31]): slot 2 */
+};
+
+#elif defined(CONFIG_PMC_MSP7120_EVAL)
+
+/* MSP7120 Eval Board IRQ wiring to PCI slots */
+static char irq_tab[][5] __initdata = {
+       /* INTA    INTB    INTC    INTD */
+       {0,     0,      0,      0,      0 },    /*    (AD[0]): Unused */
+       {0,     0,      0,      0,      0 },    /*    (AD[1]): Unused */
+       {0,     0,      0,      0,      0 },    /*    (AD[2]): Unused */
+       {0,     0,      0,      0,      0 },    /*    (AD[3]): Unused */
+       {0,     0,      0,      0,      0 },    /*    (AD[4]): Unused */
+       {0,     0,      0,      0,      0 },    /*    (AD[5]): Unused */
+       {0,     0,      0,      0,      0 },    /*    (AD[6]): Unused */
+       {0,     0,      0,      0,      0 },    /*    (AD[7]): Unused */
+       {0,     0,      0,      0,      0 },    /*    (AD[8]): Unused */
+       {0,     0,      0,      0,      0 },    /*    (AD[9]): Unused */
+       {0,     0,      0,      0,      0 },    /*  0 (AD[10]): Unused */
+       {0,     0,      0,      0,      0 },    /*  1 (AD[11]): Unused */
+       {0,     0,      0,      0,      0 },    /*  2 (AD[12]): Unused */
+       {0,     0,      0,      0,      0 },    /*  3 (AD[13]): Unused */
+       {0,     0,      0,      0,      0 },    /*  4 (AD[14]): Unused */
+       {0,     0,      0,      0,      0 },    /*  5 (AD[15]): Unused */
+       {0,     IRQ6,   IRQ6,   0,      0 },    /*  6 (AD[16]): slot 3 (mini) */
+       {0,     IRQ5,   IRQ5,   0,      0 },    /*  7 (AD[17]): slot 2 (mini) */
+       {0,     IRQ4,   IRQ4,   IRQ4,   IRQ4},  /*  8 (AD[18]): slot 0 (PCI) */
+       {0,     IRQ5,   IRQ5,   IRQ5,   IRQ5},  /*  9 (AD[19]): slot 1 (PCI) */
+       {0,     0,      0,      0,      0 },    /* 10 (AD[20]): Unused */
+       {0,     0,      0,      0,      0 },    /* 11 (AD[21]): Unused */
+       {0,     0,      0,      0,      0 },    /* 12 (AD[22]): Unused */
+       {0,     0,      0,      0,      0 },    /* 13 (AD[23]): Unused */
+       {0,     0,      0,      0,      0 },    /* 14 (AD[24]): Unused */
+       {0,     0,      0,      0,      0 },    /* 15 (AD[25]): Unused */
+       {0,     0,      0,      0,      0 },    /* 16 (AD[26]): Unused */
+       {0,     0,      0,      0,      0 },    /* 17 (AD[27]): Unused */
+       {0,     0,      0,      0,      0 },    /* 18 (AD[28]): Unused */
+       {0,     0,      0,      0,      0 },    /* 19 (AD[29]): Unused */
+       {0,     0,      0,      0,      0 },    /* 20 (AD[30]): Unused */
+       {0,     0,      0,      0,      0 }     /* 21 (AD[31]): Unused */
+};
+
+#else
+
+/* Unknown board -- don't assign any IRQs */
+static char irq_tab[][5] __initdata = {
+       /* INTA    INTB    INTC    INTD */
+       {0,     0,      0,      0,      0 },    /*    (AD[0]): Unused */
+       {0,     0,      0,      0,      0 },    /*    (AD[1]): Unused */
+       {0,     0,      0,      0,      0 },    /*    (AD[2]): Unused */
+       {0,     0,      0,      0,      0 },    /*    (AD[3]): Unused */
+       {0,     0,      0,      0,      0 },    /*    (AD[4]): Unused */
+       {0,     0,      0,      0,      0 },    /*    (AD[5]): Unused */
+       {0,     0,      0,      0,      0 },    /*    (AD[6]): Unused */
+       {0,     0,      0,      0,      0 },    /*    (AD[7]): Unused */
+       {0,     0,      0,      0,      0 },    /*    (AD[8]): Unused */
+       {0,     0,      0,      0,      0 },    /*    (AD[9]): Unused */
+       {0,     0,      0,      0,      0 },    /*  0 (AD[10]): Unused */
+       {0,     0,      0,      0,      0 },    /*  1 (AD[11]): Unused */
+       {0,     0,      0,      0,      0 },    /*  2 (AD[12]): Unused */
+       {0,     0,      0,      0,      0 },    /*  3 (AD[13]): Unused */
+       {0,     0,      0,      0,      0 },    /*  4 (AD[14]): Unused */
+       {0,     0,      0,      0,      0 },    /*  5 (AD[15]): Unused */
+       {0,     0,      0,      0,      0 },    /*  6 (AD[16]): Unused */
+       {0,     0,      0,      0,      0 },    /*  7 (AD[17]): Unused */
+       {0,     0,      0,      0,      0 },    /*  8 (AD[18]): Unused */
+       {0,     0,      0,      0,      0 },    /*  9 (AD[19]): Unused */
+       {0,     0,      0,      0,      0 },    /* 10 (AD[20]): Unused */
+       {0,     0,      0,      0,      0 },    /* 11 (AD[21]): Unused */
+       {0,     0,      0,      0,      0 },    /* 12 (AD[22]): Unused */
+       {0,     0,      0,      0,      0 },    /* 13 (AD[23]): Unused */
+       {0,     0,      0,      0,      0 },    /* 14 (AD[24]): Unused */
+       {0,     0,      0,      0,      0 },    /* 15 (AD[25]): Unused */
+       {0,     0,      0,      0,      0 },    /* 16 (AD[26]): Unused */
+       {0,     0,      0,      0,      0 },    /* 17 (AD[27]): Unused */
+       {0,     0,      0,      0,      0 },    /* 18 (AD[28]): Unused */
+       {0,     0,      0,      0,      0 },    /* 19 (AD[29]): Unused */
+       {0,     0,      0,      0,      0 },    /* 20 (AD[30]): Unused */
+       {0,     0,      0,      0,      0 }     /* 21 (AD[31]): Unused */
+};
+#endif
+
+/*****************************************************************************
+ *
+ *  FUNCTION: pcibios_plat_dev_init
+ *  _________________________________________________________________________
+ *
+ *  DESCRIPTION: Perform platform specific device initialization at
+ *               pci_enable_device() time.
+ *               None are needed for the MSP7120 PCI Controller.
+ *
+ *  INPUTS:      dev     - structure describing the PCI device
+ *
+ *  OUTPUTS:     none
+ *
+ *  RETURNS:     PCIBIOS_SUCCESSFUL
+ *
+ ****************************************************************************/
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+       return PCIBIOS_SUCCESSFUL;
+}
+
+/*****************************************************************************
+ *
+ *  FUNCTION: pcibios_map_irq
+ *  _________________________________________________________________________
+ *
+ *  DESCRIPTION: Perform board supplied PCI IRQ mapping routine.
+ *
+ *  INPUTS:      dev     - unused
+ *               slot    - PCI slot. Identified by which bit of the AD[] bus
+ *                         drives the IDSEL line. AD[10] is 0, AD[31] is
+ *                         slot 21.
+ *               pin     - numbered using the scheme of the PCI_INTERRUPT_PIN
+ *                         field of the config header.
+ *
+ *  OUTPUTS:     none
+ *
+ *  RETURNS:     IRQ number
+ *
+ ****************************************************************************/
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+#if !defined(CONFIG_PMC_MSP7120_GW) && !defined(CONFIG_PMC_MSP7120_EVAL)
+       printk(KERN_WARNING "PCI: unknown board, no PCI IRQs assigned.\n");
+#endif
+       printk(KERN_WARNING "PCI: irq_tab returned %d for slot=%d pin=%d\n",
+               irq_tab[slot][pin], slot, pin);
+
+       return irq_tab[slot][pin];
+}
+
+#endif /* CONFIG_PCI */
index 50546dab66893106b1671508b3fe11db0e39fb62..96857ac63bf560f9a38932791b216795ac9f0bca 100644 (file)
@@ -45,7 +45,7 @@ void __init pcibios_fixup(void)
        /* nothing to do here */
 }
 
-int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
        return pnx8550_irq_tab[slot][pin];
 }
index ceeb1860895ad67f5b57d817fd89885d7acf0978..3cdbecb8e7144cb8a1ba5997076251c9a05f9139 100644 (file)
@@ -119,7 +119,7 @@ int pci_get_irq(struct pci_dev *dev, int pin)
        return irq;
 }
 
-int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
        unsigned char irq;
 
index 36e5fb1b3786b7c17a3202f8b6457aef9f642096..a45bedd17233ce36b5959c3e533ddd24f41b4dc5 100644 (file)
@@ -120,7 +120,7 @@ static inline int is_rm300_revd(void)
        return (csmsr & 0xa0) == 0x20;
 }
 
-int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
        switch (sni_brd_type) {
        case SNI_BRD_PCI_TOWER:
index 734f2b71e164cfee76f2849efc0a60e5ea654475..720a2b720c5c5a30f3c46c76b7c813e82028f56f 100644 (file)
@@ -23,7 +23,7 @@
 
 #include <asm/vr41xx/tb0219.h>
 
-int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
        int irq = -1;
 
index c9e7cb4361a19eb5e91bb848a72f168da7702d19..e3eedf4bf9bd088567074cd3dc12df6f28fac811 100644 (file)
@@ -23,7 +23,7 @@
 #include <asm/vr41xx/giu.h>
 #include <asm/vr41xx/tb0226.h>
 
-int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
        int irq = -1;
 
index fbe6bcb2819977433eb2e05cfc712ef537c97f1c..267ab3dc3d421420cde426812bf71ce6d661acaa 100644 (file)
@@ -22,7 +22,7 @@
 
 #include <asm/vr41xx/tb0287.h>
 
-int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
        unsigned char bus;
        int irq = -1;
index f455520ada88ddcab68a98991ae2b885ab76c24d..2485f47dfe6fec88fee4829389c6ed3805f778a4 100644 (file)
@@ -69,7 +69,7 @@ int pci_get_irq(struct pci_dev *dev, int pin)
        return irq;
 }
 
-int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
        unsigned char irq = 0;
 
index a8d9d22b13dfffcd6178b151bf71d9ce2374478f..de5e5f6bbf4c94dfd323ca292eb28781d1f28ef0 100644 (file)
@@ -169,7 +169,7 @@ void i8259_init(void)
 }
 #endif
 
-int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
        extern int pci_probe_only;
        pci_probe_only = 1;
index 3357c1300bb123cc1869a939bed0d527bacc257b..3d277549d5dfa1ccf620730e582868d34de8939d 100644 (file)
@@ -25,7 +25,7 @@ static char pci_irq_tab[PCI_SLOT_MAXNR][5] __initdata = {
        [6] = {0, WRPPMC_PCI_INTA_IRQ, 0, 0, 0},
 };
 
-int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
        return pci_irq_tab[slot][pin];
 }
index 81d77a587a513207c67d4143aa299ceb745c4382..fdafb13a793b94d506b6410f766002d0fdbef32d 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 
-int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
        if (pin == 0)
                return -1;
index dc35270b65a2ffae16dd9ef9e955882543444997..f742c51acf0d0506a18d3784ecbf87fec371a175 100644 (file)
 #define PCI_ACCESS_READ  0
 #define PCI_ACCESS_WRITE 1
 
-/*
- *  PCI configuration cycle AD bus definition
- */
-/* Type 0 */
-#define PCI_CFG_TYPE0_REG_SHF           0
-#define PCI_CFG_TYPE0_FUNC_SHF          8
+#ifdef CONFIG_LEMOTE_FULONG
+#define CFG_SPACE_REG(offset) (void *)CKSEG1ADDR(BONITO_PCICFG_BASE | (offset))
+#define ID_SEL_BEGIN 11
+#else
+#define CFG_SPACE_REG(offset) (void *)CKSEG1ADDR(_pcictrl_bonito_pcicfg + (offset))
+#define ID_SEL_BEGIN 10
+#endif
+#define MAX_DEV_NUM (31 - ID_SEL_BEGIN)
 
-/* Type 1 */
-#define PCI_CFG_TYPE1_REG_SHF           0
-#define PCI_CFG_TYPE1_FUNC_SHF          8
-#define PCI_CFG_TYPE1_DEV_SHF           11
-#define PCI_CFG_TYPE1_BUS_SHF           16
 
 static int bonito64_pcibios_config_access(unsigned char access_type,
                                      struct pci_bus *bus,
                                      unsigned int devfn, int where,
                                      u32 * data)
 {
-       unsigned char busnum = bus->number;
+       u32 busnum = bus->number;
+       u32 addr, type;
        u32 dummy;
-       u64 pci_addr;
-
-       /* Algorithmics Bonito64 system controller. */
+       void *addrp;
+       int device = PCI_SLOT(devfn);
+       int function = PCI_FUNC(devfn);
+       int reg = where & ~3;
 
-       if ((busnum == 0) && (PCI_SLOT(devfn) > 21)) {
-               /* We number bus 0 devices from 0..21 */
-               return -1;
-       }
-
-       /* Clear cause register bits */
-       BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR |
-                         BONITO_PCICMD_MTABORT_CLR);
-
-       /*
-        * Setup pattern to be used as PCI "address" for
-        * Type 0 cycle
-        */
        if (busnum == 0) {
-               /* IDSEL */
-               pci_addr = (u64) 1 << (PCI_SLOT(devfn) + 10);
-       } else {
-               /* Bus number */
-               pci_addr = busnum << PCI_CFG_TYPE1_BUS_SHF;
-
-               /* Device number */
-               pci_addr |=
-                   PCI_SLOT(devfn) << PCI_CFG_TYPE1_DEV_SHF;
-       }
-
-       /* Function (same for Type 0/1) */
-       pci_addr |= PCI_FUNC(devfn) << PCI_CFG_TYPE0_FUNC_SHF;
-
-       /* Register number (same for Type 0/1) */
-       pci_addr |= (where & ~0x3) << PCI_CFG_TYPE0_REG_SHF;
+               /* Type 0 configuration for onboard PCI bus */
+               if (device > MAX_DEV_NUM)
+                       return -1;
 
-       if (busnum == 0) {
-               /* Type 0 */
-               BONITO_PCIMAP_CFG = pci_addr >> 16;
+               addr = (1 << (device + ID_SEL_BEGIN)) | (function << 8) | reg;
+               type = 0;
        } else {
-               /* Type 1 */
-               BONITO_PCIMAP_CFG = (pci_addr >> 16) | 0x10000;
+               /* Type 1 configuration for offboard PCI bus */
+               addr = (busnum << 16) | (device << 11) | (function << 8) | reg;
+               type = 0x10000;
        }
 
-       pci_addr &= 0xffff;
+       /* Clear aborts */
+       BONITO_PCICMD |= BONITO_PCICMD_MABORT_CLR | BONITO_PCICMD_MTABORT_CLR;
+
+       BONITO_PCIMAP_CFG = (addr >> 16) | type;
 
        /* Flush Bonito register block */
        dummy = BONITO_PCIMAP_CFG;
-       iob();          /* sync */
+       mmiowb();
 
-       /* Perform access */
+       addrp = CFG_SPACE_REG(addr & 0xffff);
        if (access_type == PCI_ACCESS_WRITE) {
-               *(volatile u32 *) (_pcictrl_bonito_pcicfg + (u32)pci_addr) = *(u32 *) data;
-
+               writel(cpu_to_le32(*data), addrp);
+#ifndef CONFIG_LEMOTE_FULONG
                /* Wait till done */
                while (BONITO_PCIMSTAT & 0xF);
+#endif
        } else {
-               *(u32 *) data = *(volatile u32 *) (_pcictrl_bonito_pcicfg + (u32)pci_addr);
+               *data = le32_to_cpu(readl(addrp));
        }
 
        /* Detect Master/Target abort */
@@ -121,6 +98,7 @@ static int bonito64_pcibios_config_access(unsigned char access_type,
        }
 
        return 0;
+
 }
 
 
diff --git a/arch/mips/pci/ops-marvell.c b/arch/mips/pci/ops-marvell.c
deleted file mode 100644 (file)
index 1ac5c59..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2003, 2004 Ralf Baechle (ralf@linux-mips.org)
- */
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-
-#include <asm/marvell.h>
-
-static int mv_read_config(struct pci_bus *bus, unsigned int devfn,
-       int where, int size, u32 * val)
-{
-       struct mv_pci_controller *mvbc = bus->sysdata;
-       unsigned long address_reg, data_reg;
-       u32 address;
-
-       address_reg = mvbc->config_addr;
-       data_reg = mvbc->config_vreg;
-
-       /* Accessing device 31 crashes those Marvells.  Since years.
-          Will they ever make sane controllers ... */
-       if (PCI_SLOT(devfn) == 31)
-               return PCIBIOS_DEVICE_NOT_FOUND;
-
-       address = (bus->number << 16) | (devfn << 8) |
-                 (where & 0xfc) | 0x80000000;
-
-       /* start the configuration cycle */
-       MV_WRITE(address_reg, address);
-
-       switch (size) {
-       case 1:
-               *val = MV_READ_8(data_reg + (where & 0x3));
-               break;
-
-       case 2:
-               *val = MV_READ_16(data_reg + (where & 0x3));
-               break;
-
-       case 4:
-               *val = MV_READ(data_reg);
-               break;
-       }
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int mv_write_config(struct pci_bus *bus, unsigned int devfn,
-       int where, int size, u32 val)
-{
-       struct mv_pci_controller *mvbc = bus->sysdata;
-       unsigned long address_reg, data_reg;
-       u32 address;
-
-       address_reg = mvbc->config_addr;
-       data_reg = mvbc->config_vreg;
-
-       /* Accessing device 31 crashes those Marvells.  Since years.
-          Will they ever make sane controllers ... */
-       if (PCI_SLOT(devfn) == 31)
-               return PCIBIOS_DEVICE_NOT_FOUND;
-
-       address = (bus->number << 16) | (devfn << 8) |
-                 (where & 0xfc) | 0x80000000;
-
-       /* start the configuration cycle */
-       MV_WRITE(address_reg, address);
-
-       switch (size) {
-       case 1:
-               MV_WRITE_8(data_reg + (where & 0x3), val);
-               break;
-
-       case 2:
-               MV_WRITE_16(data_reg + (where & 0x3), val);
-               break;
-
-       case 4:
-               MV_WRITE(data_reg, val);
-               break;
-       }
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-struct pci_ops mv_pci_ops = {
-       .read   = mv_read_config,
-       .write  = mv_write_config
-};
diff --git a/arch/mips/pci/ops-nile4.c b/arch/mips/pci/ops-nile4.c
deleted file mode 100644 (file)
index a8d38dc..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <asm/bootinfo.h>
-
-#include <asm/lasat/lasat.h>
-#include <asm/gt64120.h>
-#include <asm/nile4.h>
-
-#define PCI_ACCESS_READ  0
-#define PCI_ACCESS_WRITE 1
-
-#define LO(reg) (reg / 4)
-#define HI(reg) (reg / 4 + 1)
-
-volatile unsigned long *const vrc_pciregs = (void *) Vrc5074_BASE;
-
-static DEFINE_SPINLOCK(nile4_pci_lock);
-
-static int nile4_pcibios_config_access(unsigned char access_type,
-       struct pci_bus *bus, unsigned int devfn, int where, u32 * val)
-{
-       unsigned char busnum = bus->number;
-       u32 adr, mask, err;
-
-       if ((busnum == 0) && (PCI_SLOT(devfn) > 8))
-               /* The addressing scheme chosen leaves room for just
-                * 8 devices on the first busnum (besides the PCI
-                * controller itself) */
-               return PCIBIOS_DEVICE_NOT_FOUND;
-
-       if ((busnum == 0) && (devfn == PCI_DEVFN(0, 0))) {
-               /* Access controller registers directly */
-               if (access_type == PCI_ACCESS_WRITE) {
-                       vrc_pciregs[(0x200 + where) >> 2] = *val;
-               } else {
-                       *val = vrc_pciregs[(0x200 + where) >> 2];
-               }
-               return PCIBIOS_SUCCESSFUL;
-       }
-
-       /* Temporarily map PCI Window 1 to config space */
-       mask = vrc_pciregs[LO(NILE4_PCIINIT1)];
-       vrc_pciregs[LO(NILE4_PCIINIT1)] = 0x0000001a | (busnum ? 0x200 : 0);
-
-       /* Clear PCI Error register. This also clears the Error Type
-        * bits in the Control register */
-       vrc_pciregs[LO(NILE4_PCIERR)] = 0;
-       vrc_pciregs[HI(NILE4_PCIERR)] = 0;
-
-       /* Setup address */
-       if (busnum == 0)
-               adr =
-                   KSEG1ADDR(PCI_WINDOW1) +
-                   ((1 << (PCI_SLOT(devfn) + 15)) | (PCI_FUNC(devfn) << 8)
-                    | (where & ~3));
-       else
-               adr = KSEG1ADDR(PCI_WINDOW1) | (busnum << 16) | (devfn << 8) |
-                     (where & ~3);
-
-       if (access_type == PCI_ACCESS_WRITE)
-               *(u32 *) adr = *val;
-       else
-               *val = *(u32 *) adr;
-
-       /* Check for master or target abort */
-       err = (vrc_pciregs[HI(NILE4_PCICTRL)] >> 5) & 0x7;
-
-       /* Restore PCI Window 1 */
-       vrc_pciregs[LO(NILE4_PCIINIT1)] = mask;
-
-       if (err)
-               return PCIBIOS_DEVICE_NOT_FOUND;
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int nile4_pcibios_read(struct pci_bus *bus, unsigned int devfn,
-       int where, int size, u32 * val)
-{
-       unsigned long flags;
-       u32 data = 0;
-       int err;
-
-       if ((size == 2) && (where & 1))
-               return PCIBIOS_BAD_REGISTER_NUMBER;
-       else if ((size == 4) && (where & 3))
-               return PCIBIOS_BAD_REGISTER_NUMBER;
-
-       spin_lock_irqsave(&nile4_pci_lock, flags);
-       err = nile4_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where,
-                                       &data);
-       spin_unlock_irqrestore(&nile4_pci_lock, flags);
-
-       if (err)
-               return err;
-
-       if (size == 1)
-               *val = (data >> ((where & 3) << 3)) & 0xff;
-       else if (size == 2)
-               *val = (data >> ((where & 3) << 3)) & 0xffff;
-       else
-               *val = data;
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int nile4_pcibios_write(struct pci_bus *bus, unsigned int devfn,
-       int where, int size, u32 val)
-{
-       unsigned long flags;
-       u32 data = 0;
-       int err;
-
-       if ((size == 2) && (where & 1))
-               return PCIBIOS_BAD_REGISTER_NUMBER;
-       else if ((size == 4) && (where & 3))
-               return PCIBIOS_BAD_REGISTER_NUMBER;
-
-       spin_lock_irqsave(&nile4_pci_lock, flags);
-       err = nile4_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where,
-                                         &data);
-       spin_unlock_irqrestore(&nile4_pci_lock, flags);
-
-       if (err)
-               return err;
-
-       if (size == 1)
-               data = (data & ~(0xff << ((where & 3) << 3))) |
-                   (val << ((where & 3) << 3));
-       else if (size == 2)
-               data = (data & ~(0xffff << ((where & 3) << 3))) |
-                   (val << ((where & 3) << 3));
-       else
-               data = val;
-
-       if (nile4_pcibios_config_access
-           (PCI_ACCESS_WRITE, bus, devfn, where, &data))
-               return -1;
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-struct pci_ops nile4_pci_ops = {
-       .read = nile4_pcibios_read,
-       .write = nile4_pcibios_write,
-};
diff --git a/arch/mips/pci/ops-pmcmsp.c b/arch/mips/pci/ops-pmcmsp.c
new file mode 100644 (file)
index 0000000..09fa007
--- /dev/null
@@ -0,0 +1,994 @@
+/*
+ * PMC-Sierra MSP board specific pci_ops
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Copyright 2005-2007 PMC-Sierra, Inc
+ *
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * Much of the code is derived from the original DDB5074 port by
+ * Geert Uytterhoeven <geert@sonycom.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+#define PCI_COUNTERS   1
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+
+#if defined(CONFIG_PROC_FS) && defined(PCI_COUNTERS)
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#endif /* CONFIG_PROC_FS && PCI_COUNTERS */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/byteorder.h>
+#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
+#include <asm/mipsmtregs.h>
+#endif
+
+#include <msp_prom.h>
+#include <msp_cic_int.h>
+#include <msp_pci.h>
+#include <msp_regs.h>
+#include <msp_regops.h>
+
+#define PCI_ACCESS_READ                0
+#define PCI_ACCESS_WRITE       1
+
+#if defined(CONFIG_PROC_FS) && defined(PCI_COUNTERS)
+static char proc_init;
+extern struct proc_dir_entry *proc_bus_pci_dir;
+unsigned int pci_int_count[32];
+
+static void pci_proc_init(void);
+
+/*****************************************************************************
+ *
+ *  FUNCTION: read_msp_pci_counts
+ *  _________________________________________________________________________
+ *
+ *  DESCRIPTION: Prints the count of how many times each PCI
+ *               interrupt has asserted. Can be invoked by the
+ *               /proc filesystem.
+ *
+ *  INPUTS:      page    - part of STDOUT calculation
+ *               off     - part of STDOUT calculation
+ *               count   - part of STDOUT calculation
+ *               data    - unused
+ *
+ *  OUTPUTS:     start   - new start location
+ *               eof     - end of file pointer
+ *
+ *  RETURNS:     len     - STDOUT length
+ *
+ ****************************************************************************/
+static int read_msp_pci_counts(char *page, char **start, off_t off,
+                               int count, int *eof, void *data)
+{
+       int i;
+       int len = 0;
+       unsigned int intcount, total = 0;
+
+       for (i = 0; i < 32; ++i) {
+               intcount = pci_int_count[i];
+               if (intcount != 0) {
+                       len += sprintf(page + len, "[%d] = %u\n", i, intcount);
+                       total += intcount;
+               }
+       }
+
+       len += sprintf(page + len, "total = %u\n", total);
+       if (len <= off+count)
+               *eof = 1;
+
+       *start = page + off;
+       len -= off;
+       if (len > count)
+               len = count;
+       if (len < 0)
+               len = 0;
+
+       return len;
+}
+
+/*****************************************************************************
+ *
+ *  FUNCTION: gen_pci_cfg_wr
+ *  _________________________________________________________________________
+ *
+ *  DESCRIPTION: Generates a configuration write cycle for debug purposes.
+ *               The IDSEL line asserted and location and data written are
+ *               immaterial. Just want to be able to prove that a
+ *               configuration write can be correctly generated on the
+ *               PCI bus.  Intent is that this function by invocable from
+ *               the /proc filesystem.
+ *
+ *  INPUTS:      page    - part of STDOUT calculation
+ *               off     - part of STDOUT calculation
+ *               count   - part of STDOUT calculation
+ *               data    - unused
+ *
+ *  OUTPUTS:     start   - new start location
+ *               eof     - end of file pointer
+ *
+ *  RETURNS:     len     - STDOUT length
+ *
+ ****************************************************************************/
+static int gen_pci_cfg_wr(char *page, char **start, off_t off,
+                               int count, int *eof, void *data)
+{
+       unsigned char where = 0; /* Write to static Device/Vendor ID */
+       unsigned char bus_num = 0; /* Bus 0 */
+       unsigned char dev_fn = 0xF; /* Arbitrary device number */
+       u32 wr_data = 0xFF00AA00; /* Arbitrary data */
+       struct msp_pci_regs *preg = (void *)PCI_BASE_REG;
+       int len = 0;
+       unsigned long value;
+       int intr;
+
+       len += sprintf(page + len, "PMC MSP PCI: Beginning\n");
+
+       if (proc_init == 0) {
+               pci_proc_init();
+               proc_init = ~0;
+       }
+
+       len += sprintf(page + len, "PMC MSP PCI: Before Cfg Wr\n");
+
+       /*
+        * Generate PCI Configuration Write Cycle
+        */
+
+       /* Clear cause register bits */
+       preg->if_status = ~(BPCI_IFSTATUS_BC0F | BPCI_IFSTATUS_BC1F);
+
+       /* Setup address that is to appear on PCI bus */
+       preg->config_addr = BPCI_CFGADDR_ENABLE |
+               (bus_num << BPCI_CFGADDR_BUSNUM_SHF) |
+               (dev_fn << BPCI_CFGADDR_FUNCTNUM_SHF) |
+               (where & 0xFC);
+
+       value = cpu_to_le32(wr_data);
+
+       /* Launch the PCI configuration write cycle */
+       *PCI_CONFIG_SPACE_REG = value;
+
+       /*
+        * Check if the PCI configuration cycle (rd or wr) succeeded, by
+        * checking the status bits for errors like master or target abort.
+        */
+       intr = preg->if_status;
+
+       len += sprintf(page + len, "PMC MSP PCI: After Cfg Wr\n");
+
+       /* Handle STDOUT calculations */
+       if (len <= off+count)
+               *eof = 1;
+       *start = page + off;
+       len -= off;
+       if (len > count)
+               len = count;
+       if (len < 0)
+               len = 0;
+
+       return len;
+}
+
+/*****************************************************************************
+ *
+ *  FUNCTION: pci_proc_init
+ *  _________________________________________________________________________
+ *
+ *  DESCRIPTION: Create entries in the /proc filesystem for debug access.
+ *
+ *  INPUTS:      none
+ *
+ *  OUTPUTS:     none
+ *
+ *  RETURNS:     none
+ *
+ ****************************************************************************/
+static void pci_proc_init(void)
+{
+       create_proc_read_entry("pmc_msp_pci_rd_cnt", 0, NULL,
+                               read_msp_pci_counts, NULL);
+       create_proc_read_entry("pmc_msp_pci_cfg_wr", 0, NULL,
+                               gen_pci_cfg_wr, NULL);
+}
+#endif /* CONFIG_PROC_FS && PCI_COUNTERS */
+
+spinlock_t bpci_lock = SPIN_LOCK_UNLOCKED;
+
+/*****************************************************************************
+ *
+ *  STRUCT: pci_io_resource
+ *  _________________________________________________________________________
+ *
+ *  DESCRIPTION: Defines the address range that pciauto() will use to
+ *               assign to the I/O BARs of PCI devices.
+ *
+ *               Use the start and end addresses of the MSP7120 PCI Host
+ *               Controller I/O space, in the form that they appear on the
+ *               PCI bus AFTER MSP7120 has performed address translation.
+ *
+ *               For I/O accesses, MSP7120 ignores OATRAN and maps I/O
+ *               accesses into the bottom 0xFFF region of address space,
+ *               so that is the range to put into the pci_io_resource
+ *               struct.
+ *
+ *               In MSP4200, the start address was 0x04 instead of the
+ *              expected 0x00. Will just assume there was a good reason
+ *              for this!
+ *
+ *  NOTES:       Linux, by default, will assign I/O space to the lowest
+ *               region of address space. Since MSP7120 and Linux,
+ *               by default, have no offset in between how they map, the
+ *               io_offset element of pci_controller struct should be set
+ *               to zero.
+ *  ELEMENTS:
+ *    name       - String used for a meaningful name.
+ *
+ *    start      - Start address of MSP7120's I/O space, as MSP7120 presents
+ *                 the address on the PCI bus.
+ *
+ *    end        - End address of MSP7120's I/O space, as MSP7120 presents
+ *                 the address on the PCI bus.
+ *
+ *    flags      - Attributes indicating the type of resource. In this case,
+ *                 indicate I/O space.
+ *
+ ****************************************************************************/
+static struct resource pci_io_resource = {
+       .name   = "pci IO space",
+       .start  = 0x04,
+       .end    = 0x0FFF,
+       .flags  = IORESOURCE_IO /* I/O space */
+};
+
+/*****************************************************************************
+ *
+ *  STRUCT: pci_mem_resource
+ *  _________________________________________________________________________
+ *
+ *  DESCRIPTION: Defines the address range that pciauto() will use to
+ *               assign to the memory BARs of PCI devices.
+ *
+ *               The .start and .end values are dependent upon how address
+ *               translation is performed by the OATRAN regiser.
+ *
+ *               The values to use for .start and .end are the values
+ *               in the form they appear on the PCI bus AFTER MSP7120 has
+ *               performed OATRAN address translation.
+ *
+ *  ELEMENTS:
+ *    name       - String used for a meaningful name.
+ *
+ *    start      - Start address of MSP7120's memory space, as MSP7120 presents
+ *                 the address on the PCI bus.
+ *
+ *    end        - End address of MSP7120's memory space, as MSP7120 presents
+ *                 the address on the PCI bus.
+ *
+ *    flags      - Attributes indicating the type of resource. In this case,
+ *                 indicate memory space.
+ *
+ ****************************************************************************/
+static struct resource pci_mem_resource = {
+       .name   = "pci memory space",
+       .start  = MSP_PCI_SPACE_BASE,
+       .end    = MSP_PCI_SPACE_END,
+       .flags  = IORESOURCE_MEM         /* memory space */
+};
+
+/*****************************************************************************
+ *
+ *  FUNCTION: bpci_interrupt
+ *  _________________________________________________________________________
+ *
+ *  DESCRIPTION: PCI status interrupt handler. Updates the count of how
+ *               many times each status bit has been set, then clears
+ *               the status bits. If the appropriate macros are defined,
+ *               these counts can be viewed via the /proc filesystem.
+ *
+ *  INPUTS:      irq     - unused
+ *               dev_id  - unused
+ *               pt_regs - unused
+ *
+ *  OUTPUTS:     none
+ *
+ *  RETURNS:     PCIBIOS_SUCCESSFUL  - success
+ *
+ ****************************************************************************/
+static int bpci_interrupt(int irq, void *dev_id)
+{
+       struct msp_pci_regs *preg = (void *)PCI_BASE_REG;
+       unsigned int stat = preg->if_status;
+
+#if defined(CONFIG_PROC_FS) && defined(PCI_COUNTERS)
+       int i;
+       for (i = 0; i < 32; ++i) {
+               if ((1 << i) & stat)
+                       ++pci_int_count[i];
+       }
+#endif /* PROC_FS && PCI_COUNTERS */
+
+       /* printk("PCI ISR: Status=%08X\n", stat); */
+
+       /* write to clear all asserted interrupts */
+       preg->if_status = stat;
+
+       return PCIBIOS_SUCCESSFUL;
+}
+
+/*****************************************************************************
+ *
+ *  FUNCTION: msp_pcibios_config_access
+ *  _________________________________________________________________________
+ *
+ *  DESCRIPTION: Performs a PCI configuration access (rd or wr), then
+ *               checks that the access succeeded by querying MSP7120's
+ *               PCI status bits.
+ *
+ *  INPUTS:
+ *               access_type  - kind of PCI configuration cycle to perform
+ *                              (read or write). Legal values are
+ *                              PCI_ACCESS_WRITE and PCI_ACCESS_READ.
+ *
+ *               bus          - pointer to the bus number of the device to
+ *                              be targetted for the configuration cycle.
+ *                              The only element of the pci_bus structure
+ *                              used is bus->number. This argument determines
+ *                              if the configuration access will be Type 0 or
+ *                              Type 1. Since MSP7120 assumes itself to be the
+ *                              PCI Host, any non-zero bus->number generates
+ *                              a Type 1 access.
+ *
+ *               devfn        - this is an 8-bit field. The lower three bits
+ *                              specify the function number of the device to
+ *                              be targetted for the configuration cycle, with
+ *                              all three-bit combinations being legal. The
+ *                              upper five bits specify the device number,
+ *                              with legal values being 10 to 31.
+ *
+ *               where        - address within the Configuration Header
+ *                              space to access.
+ *
+ *               data         - for write accesses, contains the data to
+ *                              write.
+ *
+ *  OUTPUTS:
+ *               data         - for read accesses, contains the value read.
+ *
+ *  RETURNS:     PCIBIOS_SUCCESSFUL  - success
+ *               -1                  - access failure
+ *
+ ****************************************************************************/
+int msp_pcibios_config_access(unsigned char access_type,
+                               struct pci_bus *bus,
+                               unsigned int devfn,
+                               unsigned char where,
+                               u32 *data)
+{
+       struct msp_pci_regs *preg = (void *)PCI_BASE_REG;
+       unsigned char bus_num = bus->number;
+       unsigned char dev_fn = (unsigned char)devfn;
+       unsigned long flags;
+       unsigned long intr;
+       unsigned long value;
+       static char pciirqflag;
+#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
+       unsigned int    vpe_status;
+#endif
+
+#if defined(CONFIG_PROC_FS) && defined(PCI_COUNTERS)
+       if (proc_init == 0) {
+               pci_proc_init();
+               proc_init = ~0;
+       }
+#endif /* CONFIG_PROC_FS && PCI_COUNTERS */
+
+       /*
+        * Just the first time this function invokes, allocate
+        * an interrupt line for PCI host status interrupts. The
+        * allocation assigns an interrupt handler to the interrupt.
+        */
+       if (pciirqflag == 0) {
+               request_irq(MSP_INT_PCI,/* Hardcoded internal MSP7120 wiring */
+                               bpci_interrupt,
+                               SA_SHIRQ | SA_INTERRUPT,
+                               "PMC MSP PCI Host",
+                               preg);
+               pciirqflag = ~0;
+       }
+
+#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
+       local_irq_save(flags);
+       vpe_status = dvpe();
+#else
+       spin_lock_irqsave(&bpci_lock, flags);
+#endif
+
+       /*
+        * Clear PCI cause register bits.
+        *
+        * In Polo, the PCI Host had a dedicated DMA called the
+        * Block Copy (not to be confused with the general purpose Block
+        * Copy Engine block). There appear to have been special interrupts
+        * for this Block Copy, called Block Copy 0 Fault (BC0F) and
+        * Block Copy 1 Fault (BC1F). MSP4200 and MSP7120 don't have this
+        * dedicated Block Copy block, so these two interrupts are now
+        * marked reserved. In case the  Block Copy is resurrected in a
+        * future design, maintain the code that treats these two interrupts
+        * specially.
+        *
+        * Write to clear all interrupts in the PCI status register, aside
+        * from BC0F and BC1F.
+        */
+       preg->if_status = ~(BPCI_IFSTATUS_BC0F | BPCI_IFSTATUS_BC1F);
+
+       /* Setup address that is to appear on PCI bus */
+       preg->config_addr = BPCI_CFGADDR_ENABLE |
+               (bus_num << BPCI_CFGADDR_BUSNUM_SHF) |
+               (dev_fn << BPCI_CFGADDR_FUNCTNUM_SHF) |
+               (where & 0xFC);
+
+       /* IF access is a PCI configuration write */
+       if (access_type == PCI_ACCESS_WRITE) {
+               value = cpu_to_le32(*data);
+               *PCI_CONFIG_SPACE_REG = value;
+       } else {
+               /* ELSE access is a PCI configuration read */
+               value = le32_to_cpu(*PCI_CONFIG_SPACE_REG);
+               *data = value;
+       }
+
+       /*
+        * Check if the PCI configuration cycle (rd or wr) succeeded, by
+        * checking the status bits for errors like master or target abort.
+        */
+       intr = preg->if_status;
+
+       /* Clear config access */
+       preg->config_addr = 0;
+
+       /* IF error occurred */
+       if (intr & ~(BPCI_IFSTATUS_BC0F | BPCI_IFSTATUS_BC1F)) {
+               /* Clear status bits */
+               preg->if_status = ~(BPCI_IFSTATUS_BC0F | BPCI_IFSTATUS_BC1F);
+
+#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
+               evpe(vpe_status);
+               local_irq_restore(flags);
+#else
+               spin_unlock_irqrestore(&bpci_lock, flags);
+#endif
+
+               return -1;
+       }
+
+#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
+       evpe(vpe_status);
+       local_irq_restore(flags);
+#else
+       spin_unlock_irqrestore(&bpci_lock, flags);
+#endif
+
+       return PCIBIOS_SUCCESSFUL;
+}
+
+/*****************************************************************************
+ *
+ *  FUNCTION: msp_pcibios_read_config_byte
+ *  _________________________________________________________________________
+ *
+ *  DESCRIPTION: Read a byte from PCI configuration address spac
+ *               Since the hardware can't address 8 bit chunks
+ *               directly, read a 32-bit chunk, then mask off extraneous
+ *               bits.
+ *
+ *  INPUTS       bus    - structure containing attributes for the PCI bus
+ *                        that the read is destined for.
+ *               devfn  - device/function combination that the read is
+ *                        destined for.
+ *               where  - register within the Configuration Header space
+ *                        to access.
+ *
+ *  OUTPUTS      val    - read data
+ *
+ *  RETURNS:     PCIBIOS_SUCCESSFUL  - success
+ *               -1                  - read access failure
+ *
+ ****************************************************************************/
+static int
+msp_pcibios_read_config_byte(struct pci_bus *bus,
+                               unsigned int devfn,
+                               int where,
+                               u32 *val)
+{
+       u32 data = 0;
+
+       /*
+        * If the config access did not complete normally (e.g., underwent
+        * master abort) do the PCI compliant thing, which is to supply an
+        * all ones value.
+        */
+       if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
+                                       where, &data)) {
+               *val = 0xFFFFFFFF;
+               return -1;
+       }
+
+       *val = (data >> ((where & 3) << 3)) & 0x0ff;
+
+       return PCIBIOS_SUCCESSFUL;
+}
+
+/*****************************************************************************
+ *
+ *  FUNCTION: msp_pcibios_read_config_word
+ *  _________________________________________________________________________
+ *
+ *  DESCRIPTION: Read a word (16 bits) from PCI configuration address space.
+ *               Since the hardware can't address 16 bit chunks
+ *               directly, read a 32-bit chunk, then mask off extraneous
+ *               bits.
+ *
+ *  INPUTS       bus    - structure containing attributes for the PCI bus
+ *                        that the read is destined for.
+ *               devfn  - device/function combination that the read is
+ *                        destined for.
+ *               where  - register within the Configuration Header space
+ *                        to access.
+ *
+ *  OUTPUTS      val    - read data
+ *
+ *  RETURNS:     PCIBIOS_SUCCESSFUL           - success
+ *               PCIBIOS_BAD_REGISTER_NUMBER  - bad register address
+ *               -1                           - read access failure
+ *
+ ****************************************************************************/
+static int
+msp_pcibios_read_config_word(struct pci_bus *bus,
+                               unsigned int devfn,
+                               int where,
+                               u32 *val)
+{
+       u32 data = 0;
+
+       /* if (where & 1) */    /* Commented out non-compliant code.
+                                * Should allow word access to configuration
+                                * registers, with only exception being when
+                                * the word access would wrap around into
+                                * the next dword.
+                                */
+       if ((where & 3) == 3) {
+               *val = 0xFFFFFFFF;
+               return PCIBIOS_BAD_REGISTER_NUMBER;
+       }
+
+       /*
+        * If the config access did not complete normally (e.g., underwent
+        * master abort) do the PCI compliant thing, which is to supply an
+        * all ones value.
+        */
+       if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
+                                       where, &data)) {
+               *val = 0xFFFFFFFF;
+               return -1;
+       }
+
+       *val = (data >> ((where & 3) << 3)) & 0x0ffff;
+
+       return PCIBIOS_SUCCESSFUL;
+}
+
+/*****************************************************************************
+ *
+ *  FUNCTION: msp_pcibios_read_config_dword
+ *  _________________________________________________________________________
+ *
+ *  DESCRIPTION: Read a double word (32 bits) from PCI configuration
+ *               address space.
+ *
+ *  INPUTS       bus    - structure containing attributes for the PCI bus
+ *                        that the read is destined for.
+ *               devfn  - device/function combination that the read is
+ *                        destined for.
+ *               where  - register within the Configuration Header space
+ *                        to access.
+ *
+ *  OUTPUTS      val    - read data
+ *
+ *  RETURNS:     PCIBIOS_SUCCESSFUL           - success
+ *               PCIBIOS_BAD_REGISTER_NUMBER  - bad register address
+ *               -1                           - read access failure
+ *
+ ****************************************************************************/
+static int
+msp_pcibios_read_config_dword(struct pci_bus *bus,
+                               unsigned int devfn,
+                               int where,
+                               u32 *val)
+{
+       u32 data = 0;
+
+       /* Address must be dword aligned. */
+       if (where & 3) {
+               *val = 0xFFFFFFFF;
+               return PCIBIOS_BAD_REGISTER_NUMBER;
+       }
+
+       /*
+        * If the config access did not complete normally (e.g., underwent
+        * master abort) do the PCI compliant thing, which is to supply an
+        * all ones value.
+        */
+       if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
+                                       where, &data)) {
+               *val = 0xFFFFFFFF;
+               return -1;
+       }
+
+       *val = data;
+
+       return PCIBIOS_SUCCESSFUL;
+}
+
+/*****************************************************************************
+ *
+ *  FUNCTION: msp_pcibios_write_config_byte
+ *  _________________________________________________________________________
+ *
+ *  DESCRIPTION: Write a byte to PCI configuration address space.
+ *               Since the hardware can't address 8 bit chunks
+ *               directly, a read-modify-write is performed.
+ *
+ *  INPUTS       bus    - structure containing attributes for the PCI bus
+ *                        that the write is destined for.
+ *               devfn  - device/function combination that the write is
+ *                        destined for.
+ *               where  - register within the Configuration Header space
+ *                        to access.
+ *               val    - value to write
+ *
+ *  OUTPUTS      none
+ *
+ *  RETURNS:     PCIBIOS_SUCCESSFUL  - success
+ *               -1                  - write access failure
+ *
+ ****************************************************************************/
+static int
+msp_pcibios_write_config_byte(struct pci_bus *bus,
+                               unsigned int devfn,
+                               int where,
+                               u8 val)
+{
+       u32 data = 0;
+
+       /* read config space */
+       if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
+                                       where, &data))
+               return -1;
+
+       /* modify the byte within the dword */
+       data = (data & ~(0xff << ((where & 3) << 3))) |
+                       (val << ((where & 3) << 3));
+
+       /* write back the full dword */
+       if (msp_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn,
+                                       where, &data))
+               return -1;
+
+       return PCIBIOS_SUCCESSFUL;
+}
+
+/*****************************************************************************
+ *
+ *  FUNCTION: msp_pcibios_write_config_word
+ *  _________________________________________________________________________
+ *
+ *  DESCRIPTION: Write a word (16-bits) to PCI configuration address space.
+ *               Since the hardware can't address 16 bit chunks
+ *               directly, a read-modify-write is performed.
+ *
+ *  INPUTS       bus    - structure containing attributes for the PCI bus
+ *                        that the write is destined for.
+ *               devfn  - device/function combination that the write is
+ *                        destined for.
+ *               where  - register within the Configuration Header space
+ *                        to access.
+ *               val    - value to write
+ *
+ *  OUTPUTS      none
+ *
+ *  RETURNS:     PCIBIOS_SUCCESSFUL           - success
+ *               PCIBIOS_BAD_REGISTER_NUMBER  - bad register address
+ *               -1                           - write access failure
+ *
+ ****************************************************************************/
+static int
+msp_pcibios_write_config_word(struct pci_bus *bus,
+                               unsigned int devfn,
+                               int where,
+                               u16 val)
+{
+       u32 data = 0;
+
+       /* Fixed non-compliance: if (where & 1) */
+       if ((where & 3) == 3)
+               return PCIBIOS_BAD_REGISTER_NUMBER;
+
+       /* read config space */
+       if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
+                                       where, &data))
+               return -1;
+
+       /* modify the word within the dword */
+       data = (data & ~(0xffff << ((where & 3) << 3))) |
+                       (val << ((where & 3) << 3));
+
+       /* write back the full dword */
+       if (msp_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn,
+                                       where, &data))
+               return -1;
+
+       return PCIBIOS_SUCCESSFUL;
+}
+
+/*****************************************************************************
+ *
+ *  FUNCTION: msp_pcibios_write_config_dword
+ *  _________________________________________________________________________
+ *
+ *  DESCRIPTION: Write a double word (32-bits) to PCI configuration address
+ *               space.
+ *
+ *  INPUTS       bus    - structure containing attributes for the PCI bus
+ *                        that the write is destined for.
+ *               devfn  - device/function combination that the write is
+ *                        destined for.
+ *               where  - register within the Configuration Header space
+ *                        to access.
+ *               val    - value to write
+ *
+ *  OUTPUTS      none
+ *
+ *  RETURNS:     PCIBIOS_SUCCESSFUL           - success
+ *               PCIBIOS_BAD_REGISTER_NUMBER  - bad register address
+ *               -1                           - write access failure
+ *
+ ****************************************************************************/
+static int
+msp_pcibios_write_config_dword(struct pci_bus *bus,
+                               unsigned int devfn,
+                               int where,
+                               u32 val)
+{
+       /* check that address is dword aligned */
+       if (where & 3)
+               return PCIBIOS_BAD_REGISTER_NUMBER;
+
+       /* perform write */
+       if (msp_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn,
+                                       where, &val))
+               return -1;
+
+       return PCIBIOS_SUCCESSFUL;
+}
+
+/*****************************************************************************
+ *
+ *  FUNCTION: msp_pcibios_read_config
+ *  _________________________________________________________________________
+ *
+ *  DESCRIPTION: Interface the PCI configuration read request with
+ *               the appropriate function, based on how many bytes
+ *               the read request is.
+ *
+ *  INPUTS       bus    - structure containing attributes for the PCI bus
+ *                        that the write is destined for.
+ *               devfn  - device/function combination that the write is
+ *                        destined for.
+ *               where  - register within the Configuration Header space
+ *                        to access.
+ *               size   - in units of bytes, should be 1, 2, or 4.
+ *
+ *  OUTPUTS      val    - value read, with any extraneous bytes masked
+ *                        to zero.
+ *
+ *  RETURNS:     PCIBIOS_SUCCESSFUL   - success
+ *               -1                   - failure
+ *
+ ****************************************************************************/
+int
+msp_pcibios_read_config(struct pci_bus *bus,
+                       unsigned int    devfn,
+                       int where,
+                       int size,
+                       u32 *val)
+{
+       if (size == 1) {
+               if (msp_pcibios_read_config_byte(bus, devfn, where, val)) {
+                       return -1;
+               }
+       } else if (size == 2) {
+               if (msp_pcibios_read_config_word(bus, devfn, where, val)) {
+                       return -1;
+               }
+       } else if (size == 4) {
+               if (msp_pcibios_read_config_dword(bus, devfn, where, val)) {
+                       return -1;
+               }
+       } else {
+               *val = 0xFFFFFFFF;
+               return -1;
+       }
+
+       return PCIBIOS_SUCCESSFUL;
+}
+
+/*****************************************************************************
+ *
+ *  FUNCTION: msp_pcibios_write_config
+ *  _________________________________________________________________________
+ *
+ *  DESCRIPTION: Interface the PCI configuration write request with
+ *               the appropriate function, based on how many bytes
+ *               the read request is.
+ *
+ *  INPUTS       bus    - structure containing attributes for the PCI bus
+ *                        that the write is destined for.
+ *               devfn  - device/function combination that the write is
+ *                        destined for.
+ *               where  - register within the Configuration Header space
+ *                        to access.
+ *               size   - in units of bytes, should be 1, 2, or 4.
+ *               val    - value to write
+ *
+ *  OUTPUTS:     none
+ *
+ *  RETURNS:     PCIBIOS_SUCCESSFUL   - success
+ *               -1                   - failure
+ *
+ ****************************************************************************/
+int
+msp_pcibios_write_config(struct pci_bus *bus,
+                       unsigned int devfn,
+                       int where,
+                       int size,
+                       u32 val)
+{
+       if (size == 1) {
+               if (msp_pcibios_write_config_byte(bus, devfn,
+                                               where, (u8)(0xFF & val))) {
+                       return -1;
+               }
+       } else if (size == 2) {
+               if (msp_pcibios_write_config_word(bus, devfn,
+                                               where, (u16)(0xFFFF & val))) {
+                       return -1;
+               }
+       } else if (size == 4) {
+               if (msp_pcibios_write_config_dword(bus, devfn, where, val)) {
+                       return -1;
+               }
+       } else {
+               return -1;
+       }
+
+       return PCIBIOS_SUCCESSFUL;
+}
+
+/*****************************************************************************
+ *
+ *  STRUCTURE: msp_pci_ops
+ *  _________________________________________________________________________
+ *
+ *  DESCRIPTION: structure to abstract the hardware specific PCI
+ *               configuration accesses.
+ *
+ *  ELEMENTS:
+ *    read      - function for Linux to generate PCI Configuration reads.
+ *    write     - function for Linux to generate PCI Configuration writes.
+ *
+ ****************************************************************************/
+struct pci_ops msp_pci_ops = {
+       .read = msp_pcibios_read_config,
+       .write = msp_pcibios_write_config
+};
+
+/*****************************************************************************
+ *
+ *  STRUCTURE: msp_pci_controller
+ *  _________________________________________________________________________
+ *
+ *  Describes the attributes of the MSP7120 PCI Host Controller
+ *
+ *  ELEMENTS:
+ *    pci_ops      - abstracts the hardware specific PCI configuration
+ *                   accesses.
+ *
+ *    mem_resource - address range pciauto() uses to assign to PCI device
+ *                   memory BARs.
+ *
+ *    mem_offset   - offset between how MSP7120 outbound PCI memory
+ *                   transaction addresses appear on the PCI bus and how Linux
+ *                   wants to configure memory BARs of the PCI devices.
+ *                   MSP7120 does nothing funky, so just set to zero.
+ *
+ *    io_resource  - address range pciauto() uses to assign to PCI device
+ *                   I/O BARs.
+ *
+ *    io_offset    - offset between how MSP7120 outbound PCI I/O
+ *                   transaction addresses appear on the PCI bus and how
+ *                   Linux defaults to configure I/O BARs of the PCI devices.
+ *                   MSP7120 maps outbound I/O accesses into the bottom
+ *                   bottom 4K of PCI address space (and ignores OATRAN).
+ *                   Since the Linux default is to configure I/O BARs to the
+ *                   bottom 4K, no special offset is needed. Just set to zero.
+ *
+ ****************************************************************************/
+static struct pci_controller msp_pci_controller = {
+       .pci_ops        = &msp_pci_ops,
+       .mem_resource   = &pci_mem_resource,
+       .mem_offset     = 0,
+       .io_resource    = &pci_io_resource,
+       .io_offset      = 0
+};
+
+/*****************************************************************************
+ *
+ *  FUNCTION: msp_pci_init
+ *  _________________________________________________________________________
+ *
+ *  DESCRIPTION: Initialize the PCI Host Controller and register it with
+ *               Linux so Linux can seize control of the PCI bus.
+ *
+ ****************************************************************************/
+void __init msp_pci_init(void)
+{
+       struct msp_pci_regs *preg = (void *)PCI_BASE_REG;
+       u32 id;
+
+       /* Extract Device ID */
+       id = read_reg32(PCI_JTAG_DEVID_REG, 0xFFFF) >> 12;
+
+       /* Check if JTAG ID identifies MSP7120 */
+       if (!MSP_HAS_PCI(id)) {
+               printk(KERN_WARNING "PCI: No PCI; id reads as %x\n", id);
+               goto no_pci;
+       }
+
+       /*
+        * Enable flushing of the PCI-SDRAM queue upon a read
+        * of the SDRAM's Memory Configuration Register.
+        */
+       *(unsigned long *)QFLUSH_REG_1 = 3;
+
+       /* Configure PCI Host Controller. */
+       preg->if_status = ~0;           /* Clear cause register bits */
+       preg->config_addr = 0;          /* Clear config access */
+       preg->oatran    = MSP_PCI_OATRAN; /* PCI outbound addr translation */
+       preg->if_mask   = 0xF8BF87C0;   /* Enable all PCI status interrupts */
+
+       /* configure so inb(), outb(), and family are functional */
+       set_io_port_base(MSP_PCI_IOSPACE_BASE);
+
+       /* Tell Linux the details of the MSP7120 PCI Host Controller */
+       register_pci_controller(&msp_pci_controller);
+
+       return;
+
+no_pci:
+       /* Disable PCI channel */
+       printk(KERN_WARNING "PCI: no host PCI bus detected\n");
+}
index 4450070845153341476cb4a8eb0fa97ff56cc53b..a450c4062031cc2e002e96a0e20a41eece0e3adf 100644 (file)
@@ -46,50 +46,63 @@ struct resource tx4938_pcic1_pci_mem_resource = {
        .flags  = IORESOURCE_MEM
 };
 
-static int mkaddr(int bus, int dev_fn, int where, int *flagsp)
+static int mkaddr(int bus, int dev_fn, int where,
+                 struct tx4938_pcic_reg *pcicptr)
 {
        if (bus > 0) {
                /* Type 1 configuration */
-               tx4938_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
+               pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
                    ((dev_fn & 0xff) << 0x08) | (where & 0xfc) | 1;
        } else {
                if (dev_fn >= PCI_DEVFN(TX4938_PCIC_MAX_DEVNU, 0))
                        return -1;
 
                /* Type 0 configuration */
-               tx4938_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
+               pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
                    ((dev_fn & 0xff) << 0x08) | (where & 0xfc);
        }
        /* clear M_ABORT and Disable M_ABORT Int. */
-       tx4938_pcicptr->pcistatus =
-           (tx4938_pcicptr->pcistatus & 0x0000ffff) |
+       pcicptr->pcistatus =
+           (pcicptr->pcistatus & 0x0000ffff) |
            (PCI_STATUS_REC_MASTER_ABORT << 16);
-       tx4938_pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT;
+       pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT;
 
        return 0;
 }
 
-static int check_abort(int flags)
+static int check_abort(struct tx4938_pcic_reg *pcicptr)
 {
        int code = PCIBIOS_SUCCESSFUL;
        /* wait write cycle completion before checking error status */
-       while (tx4938_pcicptr->pcicstatus & TX4938_PCIC_PCICSTATUS_IWB)
+       while (pcicptr->pcicstatus & TX4938_PCIC_PCICSTATUS_IWB)
                                ;
-       if (tx4938_pcicptr->pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) {
-               tx4938_pcicptr->pcistatus =
-                   (tx4938_pcicptr->
+       if (pcicptr->pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) {
+               pcicptr->pcistatus =
+                   (pcicptr->
                     pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT
                                                << 16);
-               tx4938_pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT;
+               pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT;
                code = PCIBIOS_DEVICE_NOT_FOUND;
        }
        return code;
 }
 
+extern struct pci_controller tx4938_pci_controller[];
+extern struct tx4938_pcic_reg *get_tx4938_pcicptr(int ch);
+
+static struct tx4938_pcic_reg *pci_bus_to_pcicptr(struct pci_bus *bus)
+{
+       struct pci_controller *channel = bus->sysdata;
+       return get_tx4938_pcicptr(channel - &tx4938_pci_controller[0]);
+}
+
 static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn,
                                        int where, int size, u32 * val)
 {
-       int flags, retval, dev, busno, func;
+       int retval, dev, busno, func;
+       struct tx4938_pcic_reg *pcicptr = pci_bus_to_pcicptr(bus);
+       void __iomem *cfgdata =
+               (void __iomem *)(unsigned long)&pcicptr->g2pcfgdata;
 
        dev = PCI_SLOT(devfn);
        func = PCI_FUNC(devfn);
@@ -101,32 +114,32 @@ static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn,
                busno = 0;
        }
 
-       if (mkaddr(busno, devfn, where, &flags))
+       if (mkaddr(busno, devfn, where, pcicptr))
                return -1;
 
        switch (size) {
        case 1:
-               *val = *(volatile u8 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata |
 #ifdef __BIG_ENDIAN
-                             ((where & 3) ^ 3));
+               cfgdata += (where & 3) ^ 3;
 #else
-                             (where & 3));
+               cfgdata += where & 3;
 #endif
+               *val = __raw_readb(cfgdata);
                break;
        case 2:
-               *val = *(volatile u16 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata |
 #ifdef __BIG_ENDIAN
-                               ((where & 3) ^ 2));
+               cfgdata += (where & 2) ^ 2;
 #else
-                               (where & 3));
+               cfgdata += where & 2;
 #endif
+               *val = __raw_readw(cfgdata);
                break;
        case 4:
-               *val = tx4938_pcicptr->g2pcfgdata;
+               *val = __raw_readl(cfgdata);
                break;
        }
 
-       retval = check_abort(flags);
+       retval = check_abort(pcicptr);
        if (retval == PCIBIOS_DEVICE_NOT_FOUND)
                *val = 0xffffffff;
 
@@ -136,7 +149,10 @@ static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn,
 static int tx4938_pcibios_write_config(struct pci_bus *bus, unsigned int devfn, int where,
                                                int size, u32 val)
 {
-       int flags, dev, busno, func;
+       int dev, busno, func;
+       struct tx4938_pcic_reg *pcicptr = pci_bus_to_pcicptr(bus);
+       void __iomem *cfgdata =
+               (void __iomem *)(unsigned long)&pcicptr->g2pcfgdata;
 
        busno = bus->number;
        dev = PCI_SLOT(devfn);
@@ -149,32 +165,32 @@ static int tx4938_pcibios_write_config(struct pci_bus *bus, unsigned int devfn,
                busno = 0;
        }
 
-       if (mkaddr(busno, devfn, where, &flags))
+       if (mkaddr(busno, devfn, where, pcicptr))
                return -1;
 
        switch (size) {
        case 1:
-               *(volatile u8 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata |
 #ifdef __BIG_ENDIAN
-                         ((where & 3) ^ 3)) = val;
+               cfgdata += (where & 3) ^ 3;
 #else
-                         (where & 3)) = val;
+               cfgdata += where & 3;
 #endif
+               __raw_writeb(val, cfgdata);
                break;
        case 2:
-               *(volatile u16 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata |
 #ifdef __BIG_ENDIAN
-                       ((where & 0x3) ^ 0x2)) = val;
+               cfgdata += (where & 2) ^ 2;
 #else
-                       (where & 3)) = val;
+               cfgdata += where & 2;
 #endif
+               __raw_writew(val, cfgdata);
                break;
        case 4:
-               tx4938_pcicptr->g2pcfgdata = val;
+               __raw_writel(val, cfgdata);
                break;
        }
 
-       return check_abort(flags);
+       return check_abort(pcicptr);
 }
 
 struct pci_ops tx4938_pci_ops = {
index d7b9e1349f6d6302582af3b99731f8a20cb09a7e..2b4e30c7d105eb8dd3d83ec6f4739ea5f87300f3 100644 (file)
@@ -74,8 +74,9 @@ static inline void WRITECFG32(u32 addr, u32 data)
        *(u32 *)(cfg_space + (addr & ~3)) = data;
 }
 
-int pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
+       This is b0rked.
        return dev->irq;
 }
 
diff --git a/arch/mips/pci/pci-dac.c b/arch/mips/pci/pci-dac.c
deleted file mode 100644 (file)
index 0f0ea1b..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000  Ani Joshi <ajoshi@unixbox.com>
- * Copyright (C) 2000, 2001, 06  Ralf Baechle <ralf@linux-mips.org>
- * swiped from i386, and cloned for MIPS by Geert, polished by Ralf.
- */
-
-#include <linux/types.h>
-#include <linux/dma-mapping.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/string.h>
-
-#include <asm/cache.h>
-#include <asm/io.h>
-
-#include <dma-coherence.h>
-
-#include <linux/pci.h>
-
-dma64_addr_t pci_dac_page_to_dma(struct pci_dev *pdev,
-       struct page *page, unsigned long offset, int direction)
-{
-       struct device *dev = &pdev->dev;
-
-       BUG_ON(direction == DMA_NONE);
-
-       if (!plat_device_is_coherent(dev)) {
-               unsigned long addr;
-
-               addr = (unsigned long) page_address(page) + offset;
-               dma_cache_wback_inv(addr, PAGE_SIZE);
-       }
-
-       return plat_map_dma_mem_page(dev, page) + offset;
-}
-
-EXPORT_SYMBOL(pci_dac_page_to_dma);
-
-struct page *pci_dac_dma_to_page(struct pci_dev *pdev,
-       dma64_addr_t dma_addr)
-{
-       return pfn_to_page(plat_dma_addr_to_phys(dma_addr) >> PAGE_SHIFT);
-}
-
-EXPORT_SYMBOL(pci_dac_dma_to_page);
-
-unsigned long pci_dac_dma_to_offset(struct pci_dev *pdev,
-       dma64_addr_t dma_addr)
-{
-       return dma_addr & ~PAGE_MASK;
-}
-
-EXPORT_SYMBOL(pci_dac_dma_to_offset);
-
-void pci_dac_dma_sync_single_for_cpu(struct pci_dev *pdev,
-       dma64_addr_t dma_addr, size_t len, int direction)
-{
-       BUG_ON(direction == PCI_DMA_NONE);
-
-       if (!plat_device_is_coherent(&pdev->dev))
-               dma_cache_wback_inv(dma_addr + PAGE_OFFSET, len);
-}
-
-EXPORT_SYMBOL(pci_dac_dma_sync_single_for_cpu);
-
-void pci_dac_dma_sync_single_for_device(struct pci_dev *pdev,
-       dma64_addr_t dma_addr, size_t len, int direction)
-{
-       BUG_ON(direction == PCI_DMA_NONE);
-
-       if (!plat_device_is_coherent(&pdev->dev))
-               dma_cache_wback_inv(dma_addr + PAGE_OFFSET, len);
-}
-
-EXPORT_SYMBOL(pci_dac_dma_sync_single_for_device);
index d071bc375b11a90efa8b375e16c4a7053c373200..7363e187784212def21c4e1031822bae8ec65819 100644 (file)
@@ -131,7 +131,7 @@ static unsigned char rockhopperII_irq_map[MAX_SLOT_NUM] = {
        /* SLOT: 20, AD:31 */ VRC5477_IRQ_IOPCI_INTA, /* vrc5477 usb host */
 };
 
-int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
        int slot_num;
        unsigned char *slot_irq_map;
diff --git a/arch/mips/pci/pci-ev64120.c b/arch/mips/pci/pci-ev64120.c
deleted file mode 100644 (file)
index a84f594..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-#include <linux/pci.h>
-#include <asm/irq.h>
-
-int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
-{
-       int irq;
-
-       if (!pin)
-               return 0;
-
-       irq = allocate_irqno();
-       if (irq < 0)
-               return 0;
-
-       return irq;
-}
-
-/* Do platform specific device initialization at pci_enable_device() time */
-int pcibios_plat_dev_init(struct pci_dev *dev)
-{
-       return 0;
-}
index 405ce0152739eee2547090c60bf6f35f7ee6ad71..a322543ac34e257223f66cb4f3bd684c60eb9537 100644 (file)
@@ -134,7 +134,7 @@ int __init bridge_probe(nasid_t nasid, int widget_id, int masterwid)
  * A given PCI device, in general, should be able to intr any of the cpus
  * on any one of the hubs connected to its xbow.
  */
-int __devinit pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+int __devinit pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
        struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus);
        int irq = bc->pci_int[slot];
diff --git a/arch/mips/pci/pci-lasat.c b/arch/mips/pci/pci-lasat.c
deleted file mode 100644 (file)
index 985784a..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000, 2001, 04 Keith M Wesolowski
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/types.h>
-#include <asm/bootinfo.h>
-
-extern struct pci_ops nile4_pci_ops;
-extern struct pci_ops gt64xxx_pci0_ops;
-static struct resource lasat_pci_mem_resource = {
-       .name   = "LASAT PCI MEM",
-       .start  = 0x18000000,
-       .end    = 0x19ffffff,
-       .flags  = IORESOURCE_MEM,
-};
-
-static struct resource lasat_pci_io_resource = {
-       .name   = "LASAT PCI IO",
-       .start  = 0x1a000000,
-       .end    = 0x1bffffff,
-       .flags  = IORESOURCE_IO,
-};
-
-static struct pci_controller lasat_pci_controller = {
-       .mem_resource   = &lasat_pci_mem_resource,
-       .io_resource    = &lasat_pci_io_resource,
-};
-
-static int __init lasat_pci_setup(void)
-{
-       printk("PCI: starting\n");
-
-       switch (mips_machtype) {
-       case MACH_LASAT_100:
-                lasat_pci_controller.pci_ops = &gt64xxx_pci0_ops;
-                break;
-       case MACH_LASAT_200:
-                lasat_pci_controller.pci_ops = &nile4_pci_ops;
-                break;
-       default:
-                panic("pcibios_init: mips_machtype incorrect");
-        }
-
-       register_pci_controller(&lasat_pci_controller);
-
-       return 0;
-}
-
-arch_initcall(lasat_pci_setup);
-
-#define LASATINT_ETH1   0
-#define LASATINT_ETH0   1
-#define LASATINT_HDC    2
-#define LASATINT_COMP   3
-#define LASATINT_HDLC   4
-#define LASATINT_PCIA   5
-#define LASATINT_PCIB   6
-#define LASATINT_PCIC   7
-#define LASATINT_PCID   8
-
-int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
-{
-       switch (slot) {
-       case 1:
-       case 2:
-       case 3:
-               return LASATINT_PCIA + (((slot-1) + (pin-1)) % 4);
-       case 4:
-               return LASATINT_ETH1;   /* Ethernet 1 (LAN 2) */
-       case 5:
-               return LASATINT_ETH0;   /* Ethernet 0 (LAN 1) */
-       case 6:
-               return LASATINT_HDC;    /* IDE controller */
-       default:
-               return 0xff;            /* Illegal */
-       }
-
-       return -1;
-}
-
-/* Do platform specific device initialization at pci_enable_device() time */
-int pcibios_plat_dev_init(struct pci_dev *dev)
-{
-       return 0;
-}
diff --git a/arch/mips/pci/pci-ocelot-c.c b/arch/mips/pci/pci-ocelot-c.c
deleted file mode 100644 (file)
index 027759f..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2004, 06 by Ralf Baechle (ralf@linux-mips.org)
- */
-
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/mv643xx.h>
-
-#include <linux/init.h>
-
-#include <asm/marvell.h>
-
-/*
- * We assume the address ranges have already been setup appropriately by
- * the firmware.  PMON in case of the Ocelot C does that.
- */
-static struct resource mv_pci_io_mem0_resource = {
-       .name   = "MV64340 PCI0 IO MEM",
-       .flags  = IORESOURCE_IO
-};
-
-static struct resource mv_pci_mem0_resource = {
-       .name   = "MV64340 PCI0 MEM",
-       .flags  = IORESOURCE_MEM
-};
-
-static struct mv_pci_controller mv_bus0_controller = {
-       .pcic = {
-               .pci_ops        = &mv_pci_ops,
-               .mem_resource   = &mv_pci_mem0_resource,
-               .io_resource    = &mv_pci_io_mem0_resource,
-       },
-       .config_addr    = MV64340_PCI_0_CONFIG_ADDR,
-       .config_vreg    = MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG,
-};
-
-static uint32_t mv_io_base, mv_io_size;
-
-static void mv64340_pci0_init(void)
-{
-       uint32_t mem0_base, mem0_size;
-       uint32_t io_base, io_size;
-
-       io_base = MV_READ(MV64340_PCI_0_IO_BASE_ADDR) << 16;
-       io_size = (MV_READ(MV64340_PCI_0_IO_SIZE) + 1) << 16;
-       mem0_base = MV_READ(MV64340_PCI_0_MEMORY0_BASE_ADDR) << 16;
-       mem0_size = (MV_READ(MV64340_PCI_0_MEMORY0_SIZE) + 1) << 16;
-
-       mv_pci_io_mem0_resource.start           = 0;
-       mv_pci_io_mem0_resource.end             = io_size - 1;
-       mv_pci_mem0_resource.start              = mem0_base;
-       mv_pci_mem0_resource.end                = mem0_base + mem0_size - 1;
-       mv_bus0_controller.pcic.mem_offset      = mem0_base;
-       mv_bus0_controller.pcic.io_offset       = 0;
-
-       ioport_resource.end             = io_size - 1;
-
-       register_pci_controller(&mv_bus0_controller.pcic);
-
-       mv_io_base = io_base;
-       mv_io_size = io_size;
-}
-
-static struct resource mv_pci_io_mem1_resource = {
-       .name   = "MV64340 PCI1 IO MEM",
-       .flags  = IORESOURCE_IO
-};
-
-static struct resource mv_pci_mem1_resource = {
-       .name   = "MV64340 PCI1 MEM",
-       .flags  = IORESOURCE_MEM
-};
-
-static struct mv_pci_controller mv_bus1_controller = {
-       .pcic = {
-               .pci_ops        = &mv_pci_ops,
-               .mem_resource   = &mv_pci_mem1_resource,
-               .io_resource    = &mv_pci_io_mem1_resource,
-       },
-       .config_addr    = MV64340_PCI_1_CONFIG_ADDR,
-       .config_vreg    = MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG,
-};
-
-static __init void mv64340_pci1_init(void)
-{
-       uint32_t mem0_base, mem0_size;
-       uint32_t io_base, io_size;
-
-       io_base = MV_READ(MV64340_PCI_1_IO_BASE_ADDR) << 16;
-       io_size = (MV_READ(MV64340_PCI_1_IO_SIZE) + 1) << 16;
-       mem0_base = MV_READ(MV64340_PCI_1_MEMORY0_BASE_ADDR) << 16;
-       mem0_size = (MV_READ(MV64340_PCI_1_MEMORY0_SIZE) + 1) << 16;
-
-       /*
-        * Here we assume the I/O window of second bus to be contiguous with
-        * the first.  A gap is no problem but would waste address space for
-        * remapping the port space.
-        */
-       mv_pci_io_mem1_resource.start           = mv_io_size;
-       mv_pci_io_mem1_resource.end             = mv_io_size + io_size - 1;
-       mv_pci_mem1_resource.start              = mem0_base;
-       mv_pci_mem1_resource.end                = mem0_base + mem0_size - 1;
-       mv_bus1_controller.pcic.mem_offset      = mem0_base;
-       mv_bus1_controller.pcic.io_offset       = 0;
-
-       ioport_resource.end             = io_base + io_size -mv_io_base - 1;
-
-       register_pci_controller(&mv_bus1_controller.pcic);
-
-       mv_io_size = io_base + io_size - mv_io_base;
-}
-
-static __init int __init ocelot_c_pci_init(void)
-{
-       unsigned long io_v_base;
-       uint32_t enable;
-
-       enable = ~MV_READ(MV64340_BASE_ADDR_ENABLE);
-
-       /*
-        * We require at least one enabled I/O or PCI memory window or we
-        * will ignore this PCI bus.  We ignore PCI windows 1, 2 and 3.
-        */
-       if (enable & (0x01 <<  9) || enable & (0x01 << 10))
-               mv64340_pci0_init();
-
-       if (enable & (0x01 << 14) || enable & (0x01 << 15))
-               mv64340_pci1_init();
-
-       if (mv_io_size) {
-               io_v_base = (unsigned long) ioremap(mv_io_base, mv_io_size);
-               if (!io_v_base)
-                       panic("Could not ioremap I/O port range");
-
-               set_io_port_base(io_v_base);
-       }
-
-       return 0;
-}
-
-arch_initcall(ocelot_c_pci_init);
index 75c1246ced5f26a37c391fa93f8ef7a4ec554dbe..c1ac6493155ec3efcd7746ee7d3f0066b73f5981 100644 (file)
@@ -84,7 +84,7 @@ static inline void WRITECFG32(u32 addr, u32 data)
        *(u32 *) (cfg_space + (addr & ~3)) = data;
 }
 
-int pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
        return dev->irq;
 }
index 8108231f2e20909ed0057a792a4f3265827fac8f..99d8f4fd3ff4956878a925c214c3eb3e9e60832e 100644 (file)
@@ -269,7 +269,7 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus)
        }
 
        for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
-               struct pci_dev *dev = pci_dev_b(ln);
+               dev = pci_dev_b(ln);
 
                if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
                        pcibios_fixup_device_resources(dev, bus);
index d43f56e2cd7887b1adea9cbae07996b59e3951c6..c839436bd012915aa787eadec4097143a5391f70 100644 (file)
@@ -123,7 +123,7 @@ static struct platform_device *pnx8550_platform_devices[] __initdata = {
        &pnx8550_uart_device,
 };
 
-int pnx8550_platform_init(void)
+static int __init pnx8550_platform_init(void)
 {
        return platform_add_devices(pnx8550_platform_devices,
                                    ARRAY_SIZE(pnx8550_platform_devices));
index 3f097558ef1365df5b3f1d62343744322e731782..92311e95b700d8d58de239ddfe0f32732a77a683 100644 (file)
@@ -78,29 +78,33 @@ static int pnx8550_proc_init( void )
 {
 
        // Create /proc/pnx8550
-        pnx8550_dir = create_proc_entry("pnx8550", S_IFDIR|S_IRUGO, NULL);
+        pnx8550_dir = proc_mkdir("pnx8550", NULL);
         if (!pnx8550_dir) {
                 printk(KERN_ERR "Can't create pnx8550 proc dir\n");
                 return -1;
         }
 
        // Create /proc/pnx8550/timers
-        pnx8550_timers = create_proc_entry("timers", S_IFREG|S_IRUGO, pnx8550_dir );
-        if (pnx8550_timers){
-                pnx8550_timers->read_proc = pnx8550_timers_read;
-        }
-        else {
+        pnx8550_timers = create_proc_read_entry(
+               "timers",
+               0,
+               pnx8550_dir,
+               pnx8550_timers_read,
+               NULL);
+
+        if (!pnx8550_timers)
                 printk(KERN_ERR "Can't create pnx8550 timers proc file\n");
-        }
 
        // Create /proc/pnx8550/registers
-        pnx8550_registers = create_proc_entry("registers", S_IFREG|S_IRUGO, pnx8550_dir );
-        if (pnx8550_registers){
-                pnx8550_registers->read_proc = pnx8550_registers_read;
-        }
-        else {
+        pnx8550_registers = create_proc_read_entry(
+               "registers",
+               0,
+               pnx8550_dir,
+               pnx8550_registers_read,
+               NULL);
+
+        if (!pnx8550_registers)
                 printk(KERN_ERR "Can't create pnx8550 registers proc file\n");
-        }
 
        return 0;
 }
index 24d514c9dff98a3970d969d7ac747cefcc26ebc7..abbd0bbfabd7ba9e93452727eb5a4f397244d625 100644 (file)
@@ -1,3 +1,49 @@
+choice
+       prompt "PMC-Sierra MSP SOC type"
+       depends on PMC_MSP
+
+config PMC_MSP4200_EVAL
+       bool "PMC-Sierra MSP4200 Eval Board"
+       select IRQ_MSP_SLP
+       select HW_HAS_PCI
+
+config PMC_MSP4200_GW
+       bool "PMC-Sierra MSP4200 VoIP Gateway"
+       select IRQ_MSP_SLP
+       select HW_HAS_PCI
+
+config PMC_MSP7120_EVAL
+       bool "PMC-Sierra MSP7120 Eval Board"
+       select SYS_SUPPORTS_MULTITHREADING
+       select IRQ_MSP_CIC
+       select HW_HAS_PCI
+
+config PMC_MSP7120_GW
+       bool "PMC-Sierra MSP7120 Residential Gateway"
+       select SYS_SUPPORTS_MULTITHREADING
+       select IRQ_MSP_CIC
+       select HW_HAS_PCI
+
+config PMC_MSP7120_FPGA
+       bool "PMC-Sierra MSP7120 FPGA"
+       select SYS_SUPPORTS_MULTITHREADING
+       select IRQ_MSP_CIC
+       select HW_HAS_PCI
+
+endchoice
+
+menu "Options for PMC-Sierra MSP chipsets"
+       depends on PMC_MSP
+
+config PMC_MSP_EMBEDDED_ROOTFS
+       bool "Root filesystem embedded in kernel image"
+       select MTD
+       select MTD_BLOCK
+       select MTD_PMC_MSP_RAMROOT
+       select MTD_RAM
+
+endmenu
+
 config HYPERTRANSPORT
        bool "Hypertransport Support for PMC-Sierra Yosemite"
        depends on PMC_YOSEMITE
diff --git a/arch/mips/pmc-sierra/msp71xx/Makefile b/arch/mips/pmc-sierra/msp71xx/Makefile
new file mode 100644 (file)
index 0000000..4bba79c
--- /dev/null
@@ -0,0 +1,11 @@
+#
+# Makefile for the PMC-Sierra MSP SOCs
+#
+obj-y += msp_prom.o msp_setup.o msp_irq.o \
+        msp_time.o msp_serial.o msp_elb.o
+obj-$(CONFIG_PMC_MSP7120_GW) += msp_hwbutton.o
+obj-$(CONFIG_IRQ_MSP_SLP) += msp_irq_slp.o
+obj-$(CONFIG_IRQ_MSP_CIC) += msp_irq_cic.o
+obj-$(CONFIG_PCI) += msp_pci.o
+obj-$(CONFIG_MSPETH) += msp_eth.o
+obj-$(CONFIG_USB_MSP71XX) += msp_usb.o
similarity index 53%
rename from arch/mips/momentum/ocelot_c/ocelot_c_fpga.h
rename to arch/mips/pmc-sierra/msp71xx/msp_elb.c
index f0f5581dcb50065b06bf1e6d2991bbda8fbaca76..3e96410072164aa16bc95228a3cd220c4a93d144 100644 (file)
@@ -1,7 +1,9 @@
 /*
- * Ocelot-C Board Register Definitions
+ * Sets up the proper Chip Select configuration registers.  It is assumed that
+ * PMON sets up the ADDR and MASK registers properly.
  *
- * (C) 2002 Momentum Computer Inc.
+ * Copyright 2005-2006 PMC-Sierra, Inc.
+ * Author: Marc St-Jean, Marc_St-Jean@pmc-sierra.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
  *  You 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.
- *
- *  Louis Hamilton, Red Hat, Inc.
- *    hamilton@redhat.com  [MIPS64 modifications]
  */
 
-#ifndef __OCELOT_C_FPGA_H__
-#define __OCELOT_C_FPGA_H__
-
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <msp_regs.h>
 
-#ifdef CONFIG_64BIT
-#define OCELOT_C_CS0_ADDR       (0xfffffffffc000000)
-#else
-#define OCELOT_C_CS0_ADDR               (0xfc000000)
+static int __init msp_elb_setup(void)
+{
+#if defined(CONFIG_PMC_MSP7120_GW) \
+ || defined(CONFIG_PMC_MSP7120_EVAL)
+       /*
+        * Force all CNFG to be identical and equal to CS0,
+        * according to OPS doc
+        */
+       *CS1_CNFG_REG = *CS2_CNFG_REG = *CS3_CNFG_REG = *CS0_CNFG_REG;
 #endif
+       return 0;
+}
 
-#define OCELOT_C_REG_BOARDREV          0x0
-#define OCELOT_C_REG_FPGA_REV          0x1
-#define OCELOT_C_REG_FPGA_TYPE         0x2
-#define OCELOT_C_REG_RESET_STATUS      0x3
-#define OCELOT_C_REG_BOARD_STATUS      0x4
-#define OCELOT_C_REG_CPCI_ID           0x5
-#define OCELOT_C_REG_SET               0x6
-#define OCELOT_C_REG_CLR               0x7
-#define OCELOT_C_REG_EEPROM_MODE       0x9
-#define OCELOT_C_REG_INTMASK           0xa
-#define OCELOT_C_REG_INTSTAT           0xb
-#define OCELOT_C_REG_UART_INTMASK      0xc
-#define OCELOT_C_REG_UART_INTSTAT      0xd
-#define OCELOT_C_REG_INTSET            0xe
-#define OCELOT_C_REG_INTCLR            0xf
-
-#define __FPGA_REG_TO_ADDR(reg)                                                \
-       ((void *) OCELOT_C_CS0_ADDR + OCELOT_C_REG_##reg)
-#define OCELOT_FPGA_WRITE(x, reg) writeb(x, __FPGA_REG_TO_ADDR(reg))
-#define OCELOT_FPGA_READ(reg) readb(__FPGA_REG_TO_ADDR(reg))
-
-#endif
+subsys_initcall(msp_elb_setup);
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c b/arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c
new file mode 100644 (file)
index 0000000..6fa8572
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * Sets up interrupt handlers for various hardware switches which are
+ * connected to interrupt lines.
+ *
+ * Copyright 2005-2207 PMC-Sierra, Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+
+#include <msp_int.h>
+#include <msp_regs.h>
+#include <msp_regops.h>
+#ifdef CONFIG_PMCTWILED
+#include <msp_led_macros.h>
+#endif
+
+/* For hwbutton_interrupt->initial_state */
+#define HWBUTTON_HI    0x1
+#define HWBUTTON_LO    0x2
+
+/*
+ * This struct describes a hardware button
+ */
+struct hwbutton_interrupt {
+       char *name;                     /* Name of button */
+       int irq;                        /* Actual LINUX IRQ */
+       int eirq;                       /* Extended IRQ number (0-7) */
+       int initial_state;              /* The "normal" state of the switch */
+       void (*handle_hi)(void *);      /* Handler: switch input has gone HI */
+       void (*handle_lo)(void *);      /* Handler: switch input has gone LO */
+       void *data;                     /* Optional data to pass to handler */
+};
+
+#ifdef CONFIG_PMC_MSP7120_GW
+extern void msp_restart(char *);
+
+static void softreset_push(void *data)
+{
+       printk(KERN_WARNING "SOFTRESET switch was pushed\n");
+
+       /*
+        * In the future you could move this to the release handler,
+        * timing the difference between the 'push' and 'release', and only
+        * doing this ungraceful restart if the button has been down for
+        * a certain amount of time; otherwise doing a graceful restart.
+        */
+
+       msp_restart(NULL);
+}
+
+static void softreset_release(void *data)
+{
+       printk(KERN_WARNING "SOFTRESET switch was released\n");
+
+       /* Do nothing */
+}
+
+static void standby_on(void *data)
+{
+       printk(KERN_WARNING "STANDBY switch was set to ON (not implemented)\n");
+
+       /* TODO: Put board in standby mode */
+#ifdef CONFIG_PMCTWILED
+       msp_led_turn_off(MSP_LED_PWRSTANDBY_GREEN);
+       msp_led_turn_on(MSP_LED_PWRSTANDBY_RED);
+#endif
+}
+
+static void standby_off(void *data)
+{
+       printk(KERN_WARNING
+               "STANDBY switch was set to OFF (not implemented)\n");
+
+       /* TODO: Take out of standby mode */
+#ifdef CONFIG_PMCTWILED
+       msp_led_turn_on(MSP_LED_PWRSTANDBY_GREEN);
+       msp_led_turn_off(MSP_LED_PWRSTANDBY_RED);
+#endif
+}
+
+static struct hwbutton_interrupt softreset_sw = {
+       .name = "Softreset button",
+       .irq = MSP_INT_EXT0,
+       .eirq = 0,
+       .initial_state = HWBUTTON_HI,
+       .handle_hi = softreset_release,
+       .handle_lo = softreset_push,
+       .data = NULL,
+};
+
+static struct hwbutton_interrupt standby_sw = {
+       .name = "Standby switch",
+       .irq = MSP_INT_EXT1,
+       .eirq = 1,
+       .initial_state = HWBUTTON_HI,
+       .handle_hi = standby_off,
+       .handle_lo = standby_on,
+       .data = NULL,
+};
+#endif /* CONFIG_PMC_MSP7120_GW */
+
+static irqreturn_t hwbutton_handler(int irq, void *data)
+{
+       struct hwbutton_interrupt *hirq = data;
+       unsigned long cic_ext = *CIC_EXT_CFG_REG;
+
+       if (irq != hirq->irq)
+               return IRQ_NONE;
+
+       if (CIC_EXT_IS_ACTIVE_HI(cic_ext, hirq->eirq)) {
+               /* Interrupt: pin is now HI */
+               CIC_EXT_SET_ACTIVE_LO(cic_ext, hirq->eirq);
+               hirq->handle_hi(hirq->data);
+       } else {
+               /* Interrupt: pin is now LO */
+               CIC_EXT_SET_ACTIVE_HI(cic_ext, hirq->eirq);
+               hirq->handle_lo(hirq->data);
+       }
+
+       /*
+        * Invert the POLARITY of this level interrupt to ack the interrupt
+        * Thus next state change will invoke the opposite message
+        */
+       *CIC_EXT_CFG_REG = cic_ext;
+
+       return IRQ_HANDLED;
+}
+
+static int msp_hwbutton_register(struct hwbutton_interrupt *hirq)
+{
+       unsigned long cic_ext;
+
+       if (hirq->handle_hi == NULL || hirq->handle_lo == NULL)
+               return -EINVAL;
+
+       cic_ext = *CIC_EXT_CFG_REG;
+       CIC_EXT_SET_TRIGGER_LEVEL(cic_ext, hirq->eirq);
+       if (hirq->initial_state == HWBUTTON_HI)
+               CIC_EXT_SET_ACTIVE_LO(cic_ext, hirq->eirq);
+       else
+               CIC_EXT_SET_ACTIVE_HI(cic_ext, hirq->eirq);
+       *CIC_EXT_CFG_REG = cic_ext;
+
+       return request_irq(hirq->irq, hwbutton_handler, SA_INTERRUPT,
+                               hirq->name, (void *)hirq);
+}
+
+static int __init msp_hwbutton_setup(void)
+{
+#ifdef CONFIG_PMC_MSP7120_GW
+       msp_hwbutton_register(&softreset_sw);
+       msp_hwbutton_register(&standby_sw);
+#endif
+       return 0;
+}
+
+subsys_initcall(msp_hwbutton_setup);
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_irq.c b/arch/mips/pmc-sierra/msp71xx/msp_irq.c
new file mode 100644 (file)
index 0000000..734d598
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * IRQ vector handles
+ *
+ * Copyright (C) 1995, 1996, 1997, 2003 by Ralf Baechle
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/time.h>
+
+#include <asm/irq_cpu.h>
+
+#include <msp_int.h>
+
+extern void msp_int_handle(void);
+
+/* SLP bases systems */
+extern void msp_slp_irq_init(void);
+extern void msp_slp_irq_dispatch(void);
+
+/* CIC based systems */
+extern void msp_cic_irq_init(void);
+extern void msp_cic_irq_dispatch(void);
+
+/*
+ * The PMC-Sierra MSP interrupts are arranged in a 3 level cascaded
+ * hierarchical system.  The first level are the direct MIPS interrupts
+ * and are assigned the interrupt range 0-7.  The second level is the SLM
+ * interrupt controller and is assigned the range 8-39.  The third level
+ * comprises the Peripherial block, the PCI block, the PCI MSI block and
+ * the SLP.  The PCI interrupts and the SLP errors are handled by the
+ * relevant subsystems so the core interrupt code needs only concern
+ * itself with the Peripheral block.  These are assigned interrupts in
+ * the range 40-71.
+ */
+
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+{
+       u32 pending;
+
+       pending = read_c0_status() & read_c0_cause();
+
+       /*
+        * jump to the correct interrupt routine
+        * These are arranged in priority order and the timer
+        * comes first!
+        */
+
+#ifdef CONFIG_IRQ_MSP_CIC      /* break out the CIC stuff for now */
+       if (pending & C_IRQ4)   /* do the peripherals first, that's the timer */
+               msp_cic_irq_dispatch();
+
+       else if (pending & C_IRQ0)
+               do_IRQ(MSP_INT_MAC0);
+
+       else if (pending & C_IRQ1)
+               do_IRQ(MSP_INT_MAC1);
+
+       else if (pending & C_IRQ2)
+               do_IRQ(MSP_INT_USB);
+
+       else if (pending & C_IRQ3)
+               do_IRQ(MSP_INT_SAR);
+
+       else if (pending & C_IRQ5)
+               do_IRQ(MSP_INT_SEC);
+
+#else
+       if (pending & C_IRQ5)
+               do_IRQ(MSP_INT_TIMER);
+
+       else if (pending & C_IRQ0)
+               do_IRQ(MSP_INT_MAC0);
+
+       else if (pending & C_IRQ1)
+               do_IRQ(MSP_INT_MAC1);
+
+       else if (pending & C_IRQ3)
+               do_IRQ(MSP_INT_VE);
+
+       else if (pending & C_IRQ4)
+               msp_slp_irq_dispatch();
+#endif
+
+       else if (pending & C_SW0)       /* do software after hardware */
+               do_IRQ(MSP_INT_SW0);
+
+       else if (pending & C_SW1)
+               do_IRQ(MSP_INT_SW1);
+}
+
+static struct irqaction cascade_msp = {
+       .handler = no_action,
+       .name    = "MSP cascade"
+};
+
+
+void __init arch_init_irq(void)
+{
+       /* initialize the 1st-level CPU based interrupt controller */
+       mips_cpu_irq_init();
+
+#ifdef CONFIG_IRQ_MSP_CIC
+       msp_cic_irq_init();
+
+       /* setup the cascaded interrupts */
+       setup_irq(MSP_INT_CIC, &cascade_msp);
+       setup_irq(MSP_INT_PER, &cascade_msp);
+#else
+       /* setup the 2nd-level SLP register based interrupt controller */
+       msp_slp_irq_init();
+
+       /* setup the cascaded SLP/PER interrupts */
+       setup_irq(MSP_INT_SLP, &cascade_msp);
+       setup_irq(MSP_INT_PER, &cascade_msp);
+#endif
+}
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c b/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c
new file mode 100644 (file)
index 0000000..5175357
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * This file define the irq handler for MSP SLM subsystem interrupts.
+ *
+ * Copyright 2005-2007 PMC-Sierra, Inc, derived from irq_cpu.c
+ * Author: Andrew Hughes, Andrew_Hughes@pmc-sierra.com
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/bitops.h>
+
+#include <asm/system.h>
+
+#include <msp_cic_int.h>
+#include <msp_regs.h>
+
+/*
+ * NOTE: We are only enabling support for VPE0 right now.
+ */
+
+static inline void unmask_msp_cic_irq(unsigned int irq)
+{
+
+       /* check for PER interrupt range */
+       if (irq < MSP_PER_INTBASE)
+               *CIC_VPE0_MSK_REG |= (1 << (irq - MSP_CIC_INTBASE));
+       else
+               *PER_INT_MSK_REG |= (1 << (irq - MSP_PER_INTBASE));
+}
+
+static inline void mask_msp_cic_irq(unsigned int irq)
+{
+       /* check for PER interrupt range */
+       if (irq < MSP_PER_INTBASE)
+               *CIC_VPE0_MSK_REG &= ~(1 << (irq - MSP_CIC_INTBASE));
+       else
+               *PER_INT_MSK_REG &= ~(1 << (irq - MSP_PER_INTBASE));
+}
+
+/*
+ * While we ack the interrupt interrupts are disabled and thus we don't need
+ * to deal with concurrency issues.  Same for msp_cic_irq_end.
+ */
+static inline void ack_msp_cic_irq(unsigned int irq)
+{
+       mask_msp_cic_irq(irq);
+
+       /*
+        * only really necessary for 18, 16-14 and sometimes 3:0 (since
+        * these can be edge sensitive) but it doesn't hurt for the others.
+        */
+
+       /* check for PER interrupt range */
+       if (irq < MSP_PER_INTBASE)
+               *CIC_STS_REG = (1 << (irq - MSP_CIC_INTBASE));
+       else
+               *PER_INT_STS_REG = (1 << (irq - MSP_PER_INTBASE));
+}
+
+static struct irq_chip msp_cic_irq_controller = {
+       .name = "MSP_CIC",
+       .ack = ack_msp_cic_irq,
+       .mask = ack_msp_cic_irq,
+       .mask_ack = ack_msp_cic_irq,
+       .unmask = unmask_msp_cic_irq,
+};
+
+
+void __init msp_cic_irq_init(void)
+{
+       int i;
+
+       /* Mask/clear interrupts. */
+       *CIC_VPE0_MSK_REG = 0x00000000;
+       *PER_INT_MSK_REG  = 0x00000000;
+       *CIC_STS_REG      = 0xFFFFFFFF;
+       *PER_INT_STS_REG  = 0xFFFFFFFF;
+
+#if defined(CONFIG_PMC_MSP7120_GW) || \
+    defined(CONFIG_PMC_MSP7120_EVAL)
+       /*
+        * The MSP7120 RG and EVBD boards use IRQ[6:4] for PCI.
+        * These inputs map to EXT_INT_POL[6:4] inside the CIC.
+        * They are to be active low, level sensitive.
+        */
+       *CIC_EXT_CFG_REG &= 0xFFFF8F8F;
+#endif
+
+       /* initialize all the IRQ descriptors */
+       for (i = MSP_CIC_INTBASE; i < MSP_PER_INTBASE + 32; i++)
+               set_irq_chip_and_handler(i, &msp_cic_irq_controller,
+                                        handle_level_irq);
+}
+
+void msp_cic_irq_dispatch(void)
+{
+       u32 pending;
+       int intbase;
+
+       intbase = MSP_CIC_INTBASE;
+       pending = *CIC_STS_REG & *CIC_VPE0_MSK_REG;
+
+       /* check for PER interrupt */
+       if (pending == (1 << (MSP_INT_PER - MSP_CIC_INTBASE))) {
+               intbase = MSP_PER_INTBASE;
+               pending = *PER_INT_STS_REG & *PER_INT_MSK_REG;
+       }
+
+       /* check for spurious interrupt */
+       if (pending == 0x00000000) {
+               printk(KERN_ERR
+                       "Spurious %s interrupt? status %08x, mask %08x\n",
+                       (intbase == MSP_CIC_INTBASE) ? "CIC" : "PER",
+                       (intbase == MSP_CIC_INTBASE) ?
+                               *CIC_STS_REG : *PER_INT_STS_REG,
+                       (intbase == MSP_CIC_INTBASE) ?
+                               *CIC_VPE0_MSK_REG : *PER_INT_MSK_REG);
+               return;
+       }
+
+       /* check for the timer and dispatch it first */
+       if ((intbase == MSP_CIC_INTBASE) &&
+           (pending & (1 << (MSP_INT_VPE0_TIMER - MSP_CIC_INTBASE))))
+               do_IRQ(MSP_INT_VPE0_TIMER);
+       else
+               do_IRQ(ffs(pending) + intbase - 1);
+}
+
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c b/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c
new file mode 100644 (file)
index 0000000..f5f1b8d
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * This file define the irq handler for MSP SLM subsystem interrupts.
+ *
+ * Copyright 2005-2006 PMC-Sierra, Inc, derived from irq_cpu.c
+ * Author: Andrew Hughes, Andrew_Hughes@pmc-sierra.com
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/bitops.h>
+
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+
+#include <msp_slp_int.h>
+#include <msp_regs.h>
+
+static inline void unmask_msp_slp_irq(unsigned int irq)
+{
+       /* check for PER interrupt range */
+       if (irq < MSP_PER_INTBASE)
+               *SLP_INT_MSK_REG |= (1 << (irq - MSP_SLP_INTBASE));
+       else
+               *PER_INT_MSK_REG |= (1 << (irq - MSP_PER_INTBASE));
+}
+
+static inline void mask_msp_slp_irq(unsigned int irq)
+{
+       /* check for PER interrupt range */
+       if (irq < MSP_PER_INTBASE)
+               *SLP_INT_MSK_REG &= ~(1 << (irq - MSP_SLP_INTBASE));
+       else
+               *PER_INT_MSK_REG &= ~(1 << (irq - MSP_PER_INTBASE));
+}
+
+/*
+ * While we ack the interrupt interrupts are disabled and thus we don't need
+ * to deal with concurrency issues.  Same for msp_slp_irq_end.
+ */
+static inline void ack_msp_slp_irq(unsigned int irq)
+{
+       mask_slp_irq(irq);
+
+       /*
+        * only really necessary for 18, 16-14 and sometimes 3:0 (since
+        * these can be edge sensitive) but it doesn't hurt  for the others.
+        */
+
+       /* check for PER interrupt range */
+       if (irq < MSP_PER_INTBASE)
+               *SLP_INT_STS_REG = (1 << (irq - MSP_SLP_INTBASE));
+       else
+               *PER_INT_STS_REG = (1 << (irq - MSP_PER_INTBASE));
+}
+
+static struct irq_chip msp_slp_irq_controller = {
+       .name = "MSP_SLP",
+       .ack = ack_msp_slp_irq,
+       .mask = ack_msp_slp_irq,
+       .mask_ack = ack_msp_slp_irq,
+       .unmask = unmask_msp_slp_irq,
+};
+
+void __init msp_slp_irq_init(void)
+{
+       int i;
+
+       /* Mask/clear interrupts. */
+       *SLP_INT_MSK_REG = 0x00000000;
+       *PER_INT_MSK_REG = 0x00000000;
+       *SLP_INT_STS_REG = 0xFFFFFFFF;
+       *PER_INT_STS_REG = 0xFFFFFFFF;
+
+       /* initialize all the IRQ descriptors */
+       for (i = MSP_SLP_INTBASE; i < MSP_PER_INTBASE + 32; i++)
+               set_irq_chip_and_handler(i, &msp_slp_irq_controller
+                                        handle_level_irq);
+}
+
+void msp_slp_irq_dispatch(void)
+{
+       u32 pending;
+       int intbase;
+
+       intbase = MSP_SLP_INTBASE;
+       pending = *SLP_INT_STS_REG & *SLP_INT_MSK_REG;
+
+       /* check for PER interrupt */
+       if (pending == (1 << (MSP_INT_PER - MSP_SLP_INTBASE))) {
+               intbase = MSP_PER_INTBASE;
+               pending = *PER_INT_STS_REG & *PER_INT_MSK_REG;
+       }
+
+       /* check for spurious interrupt */
+       if (pending == 0x00000000) {
+               printk(KERN_ERR "Spurious %s interrupt?\n",
+                       (intbase == MSP_SLP_INTBASE) ? "SLP" : "PER");
+               return;
+       }
+
+       /* dispatch the irq */
+       do_IRQ(ffs(pending) + intbase - 1);
+}
similarity index 53%
rename from arch/mips/momentum/ocelot_3/ocelot_3_fpga.h
rename to arch/mips/pmc-sierra/msp71xx/msp_pci.c
index 5710a9029f1c2f22504172795f07ccd90256db36..f764fe7748d6fb9376f251bf2ad4ba02c0bd742c 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * Ocelot-3 Board Register Definitions
+ * The setup file for PCI related hardware on PMC-Sierra MSP processors.
  *
- * (C) 2002 Momentum Computer Inc.
+ * Copyright 2005-2006 PMC-Sierra, 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
  *  You 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.
- *
- *  Louis Hamilton, Red Hat, Inc.
- *    hamilton@redhat.com  [MIPS64 modifications]
- *
- * Copyright (C) 2004 MontaVista Software Inc.
- * Author: Manish Lachwani, mlachwani@mvista.com
  */
 
-#ifndef __OCELOT_3_FPGA_H__
-#define __OCELOT_3_FPGA_H__
-
-#define OCELOT_3_REG_BOARDREV          0x0
-#define OCELOT_3_REG_FPGA_REV          0x1
-#define OCELOT_3_REG_FPGA_TYPE         0x2
-#define OCELOT_3_REG_RESET_STATUS      0x3
-#define OCELOT_3_REG_BOARD_STATUS      0x4
-#define OCELOT_3_REG_CPCI_ID           0x5
-#define OCELOT_3_REG_SET               0x6
-#define OCELOT_3_REG_CLR               0x7
-#define OCELOT_3_REG_EEPROM_MODE       0x9
-#define OCELOT_3_REG_INTMASK           0xa
-#define OCELOT_3_REG_INTSTAT           0xb
-#define OCELOT_3_REG_UART_INTMASK      0xc
-#define OCELOT_3_REG_UART_INTSTAT      0xd
-#define OCELOT_3_REG_INTSET            0xe
-#define OCELOT_3_REG_INTCLR            0xf
-
-extern unsigned long ocelot_fpga_base;
-
-#define __FPGA_REG_TO_ADDR(reg)                                                \
-       ((void *) ocelot_fpga_base + OCELOT_3_REG_##reg)
-#define OCELOT_FPGA_WRITE(x, reg) writeb(x, __FPGA_REG_TO_ADDR(reg))
-#define OCELOT_FPGA_READ(reg) readb(__FPGA_REG_TO_ADDR(reg))
+#include <linux/init.h>
+
+#include <msp_prom.h>
+#include <msp_regs.h>
+
+extern void msp_pci_init(void);
 
+static int __init msp_pci_setup(void)
+{
+#if 0 /* Linux 2.6 initialization code to be completed */
+       if (getdeviceid() & DEV_ID_SINGLE_PC) {
+               /* If single card mode */
+               slmRegs *sreg = (slmRegs *) SREG_BASE;
+
+               sreg->single_pc_enable = SINGLE_PCCARD;
+       }
 #endif
+
+       msp_pci_init();
+
+       return 0;
+}
+
+subsys_initcall(msp_pci_setup);
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_prom.c b/arch/mips/pmc-sierra/msp71xx/msp_prom.c
new file mode 100644 (file)
index 0000000..e5bd548
--- /dev/null
@@ -0,0 +1,566 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *    PROM library initialisation code, assuming a version of
+ *    pmon is the boot code.
+ *
+ * Copyright 2000,2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *             ppopov@mvista.com or source@mvista.com
+ *
+ * This file was derived from Carsten Langgaard's
+ * arch/mips/mips-boards/xx files.
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#ifdef CONFIG_CRAMFS
+#include <linux/cramfs_fs.h>
+#endif
+#ifdef CONFIG_SQUASHFS
+#include <linux/squashfs_fs.h>
+#endif
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <asm-generic/sections.h>
+#include <asm/page.h>
+
+#include <msp_prom.h>
+#include <msp_regs.h>
+
+/* global PROM environment variables and pointers */
+int prom_argc;
+char **prom_argv, **prom_envp;
+int *prom_vec;
+
+/* debug flag */
+int init_debug = 1;
+
+/* memory blocks */
+struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS];
+
+/* default feature sets */
+static char msp_default_features[] =
+#if defined(CONFIG_PMC_MSP4200_EVAL) \
+ || defined(CONFIG_PMC_MSP4200_GW)
+       "ERER";
+#elif defined(CONFIG_PMC_MSP7120_EVAL) \
+ || defined(CONFIG_PMC_MSP7120_GW)
+       "EMEMSP";
+#elif defined(CONFIG_PMC_MSP7120_FPGA)
+       "EMEM";
+#endif
+
+/* conversion functions */
+static inline unsigned char str2hexnum(unsigned char c)
+{
+       if (c >= '0' && c <= '9')
+               return c - '0';
+       if (c >= 'a' && c <= 'f')
+               return c - 'a' + 10;
+       return 0; /* foo */
+}
+
+static inline int str2eaddr(unsigned char *ea, unsigned char *str)
+{
+       int index = 0;
+       unsigned char num = 0;
+
+       while (*str != '\0') {
+               if ((*str == '.') || (*str == ':')) {
+                       ea[index++] = num;
+                       num = 0;
+                       str++;
+               } else {
+                       num = num << 4;
+                       num |= str2hexnum(*str++);
+               }
+       }
+
+       if (index == 5) {
+               ea[index++] = num;
+               return 0;
+       } else
+               return -1;
+}
+EXPORT_SYMBOL(str2eaddr);
+
+static inline unsigned long str2hex(unsigned char *str)
+{
+       int value = 0;
+
+       while (*str) {
+               value = value << 4;
+               value |= str2hexnum(*str++);
+       }
+
+       return value;
+}
+
+/* function to query the system information */
+const char *get_system_type(void)
+{
+#if defined(CONFIG_PMC_MSP4200_EVAL)
+       return "PMC-Sierra MSP4200 Eval Board";
+#elif defined(CONFIG_PMC_MSP4200_GW)
+       return "PMC-Sierra MSP4200 VoIP Gateway";
+#elif defined(CONFIG_PMC_MSP7120_EVAL)
+       return "PMC-Sierra MSP7120 Eval Board";
+#elif defined(CONFIG_PMC_MSP7120_GW)
+       return "PMC-Sierra MSP7120 Residential Gateway";
+#elif defined(CONFIG_PMC_MSP7120_FPGA)
+       return "PMC-Sierra MSP7120 FPGA";
+#else
+       #error "What is the type of *your* MSP?"
+#endif
+}
+
+int get_ethernet_addr(char *ethaddr_name, char *ethernet_addr)
+{
+       char *ethaddr_str;
+
+       ethaddr_str = prom_getenv(ethaddr_name);
+       if (!ethaddr_str) {
+               printk(KERN_WARNING "%s not set in boot prom\n", ethaddr_name);
+               return -1;
+       }
+
+       if (str2eaddr(ethernet_addr, ethaddr_str) == -1) {
+               printk(KERN_WARNING "%s badly formatted-<%s>\n",
+                       ethaddr_name, ethaddr_str);
+               return -1;
+       }
+
+       if (init_debug > 1) {
+               int i;
+               printk(KERN_DEBUG "get_ethernet_addr: for %s ", ethaddr_name);
+               for (i = 0; i < 5; i++)
+                       printk(KERN_DEBUG "%02x:",
+                               (unsigned char)*(ethernet_addr+i));
+               printk(KERN_DEBUG "%02x\n", *(ethernet_addr+i));
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(get_ethernet_addr);
+
+static char *get_features(void)
+{
+       char *feature = prom_getenv(FEATURES);
+
+       if (feature == NULL) {
+               /* default features based on MACHINE_TYPE */
+               feature = msp_default_features;
+       }
+
+       return feature;
+}
+
+static char test_feature(char c)
+{
+       char *feature = get_features();
+
+       while (*feature) {
+               if (*feature++ == c)
+                       return *feature;
+               feature++;
+       }
+
+       return FEATURE_NOEXIST;
+}
+
+unsigned long get_deviceid(void)
+{
+       char *deviceid = prom_getenv(DEVICEID);
+
+       if (deviceid == NULL)
+               return *DEV_ID_REG;
+       else
+               return str2hex(deviceid);
+}
+
+char identify_pci(void)
+{
+       return test_feature(PCI_KEY);
+}
+EXPORT_SYMBOL(identify_pci);
+
+char identify_pcimux(void)
+{
+       return test_feature(PCIMUX_KEY);
+}
+
+char identify_sec(void)
+{
+       return test_feature(SEC_KEY);
+}
+EXPORT_SYMBOL(identify_sec);
+
+char identify_spad(void)
+{
+       return test_feature(SPAD_KEY);
+}
+EXPORT_SYMBOL(identify_spad);
+
+char identify_tdm(void)
+{
+       return test_feature(TDM_KEY);
+}
+EXPORT_SYMBOL(identify_tdm);
+
+char identify_zsp(void)
+{
+       return test_feature(ZSP_KEY);
+}
+EXPORT_SYMBOL(identify_zsp);
+
+static char identify_enetfeature(char key, unsigned long interface_num)
+{
+       char *feature = get_features();
+
+       while (*feature) {
+               if (*feature++ == key && interface_num-- == 0)
+                       return *feature;
+               feature++;
+       }
+
+       return FEATURE_NOEXIST;
+}
+
+char identify_enet(unsigned long interface_num)
+{
+       return identify_enetfeature(ENET_KEY, interface_num);
+}
+EXPORT_SYMBOL(identify_enet);
+
+char identify_enetTxD(unsigned long interface_num)
+{
+       return identify_enetfeature(ENETTXD_KEY, interface_num);
+}
+EXPORT_SYMBOL(identify_enetTxD);
+
+unsigned long identify_family(void)
+{
+       unsigned long deviceid;
+
+       deviceid = get_deviceid();
+
+       return deviceid & CPU_DEVID_FAMILY;
+}
+EXPORT_SYMBOL(identify_family);
+
+unsigned long identify_revision(void)
+{
+       unsigned long deviceid;
+
+       deviceid = get_deviceid();
+
+       return deviceid & CPU_DEVID_REVISION;
+}
+EXPORT_SYMBOL(identify_revision);
+
+/* PROM environment functions */
+char *prom_getenv(char *env_name)
+{
+       /*
+        * Return a pointer to the given environment variable.  prom_envp
+        * points to a null terminated array of pointers to variables.
+        * Environment variables are stored in the form of "memsize=64"
+        */
+
+       char **var = prom_envp;
+       int i = strlen(env_name);
+
+       while (*var) {
+               if (strncmp(env_name, *var, i) == 0) {
+                       return (*var + strlen(env_name) + 1);
+               }
+               var++;
+       }
+
+       return NULL;
+}
+
+/* PROM commandline functions */
+char *prom_getcmdline(void)
+{
+       return &(arcs_cmdline[0]);
+}
+EXPORT_SYMBOL(prom_getcmdline);
+
+void  __init prom_init_cmdline(void)
+{
+       char *cp;
+       int actr;
+
+       actr = 1; /* Always ignore argv[0] */
+
+       cp = &(arcs_cmdline[0]);
+       while (actr < prom_argc) {
+               strcpy(cp, prom_argv[actr]);
+               cp += strlen(prom_argv[actr]);
+               *cp++ = ' ';
+               actr++;
+       }
+       if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
+               --cp;
+       *cp = '\0';
+}
+
+/* memory allocation functions */
+static int __init prom_memtype_classify(unsigned int type)
+{
+       switch (type) {
+       case yamon_free:
+               return BOOT_MEM_RAM;
+       case yamon_prom:
+               return BOOT_MEM_ROM_DATA;
+       default:
+               return BOOT_MEM_RESERVED;
+       }
+}
+
+void __init prom_meminit(void)
+{
+       struct prom_pmemblock *p;
+
+       p = prom_getmdesc();
+
+       while (p->size) {
+               long type;
+               unsigned long base, size;
+
+               type = prom_memtype_classify(p->type);
+               base = p->base;
+               size = p->size;
+
+               add_memory_region(base, size, type);
+               p++;
+       }
+}
+
+void __init prom_free_prom_memory(void)
+{
+       int     argc;
+       char    **argv;
+       char    **envp;
+       char    *ptr;
+       int     len = 0;
+       int     i;
+       unsigned long addr;
+
+       /*
+        * preserve environment variables and command line from pmon/bbload
+        * first preserve the command line
+        */
+       for (argc = 0; argc < prom_argc; argc++) {
+               len += sizeof(char *);                  /* length of pointer */
+               len += strlen(prom_argv[argc]) + 1;     /* length of string */
+       }
+       len += sizeof(char *);          /* plus length of null pointer */
+
+       argv = kmalloc(len, GFP_KERNEL);
+       ptr = (char *) &argv[prom_argc + 1];    /* strings follow array */
+
+       for (argc = 0; argc < prom_argc; argc++) {
+               argv[argc] = ptr;
+               strcpy(ptr, prom_argv[argc]);
+               ptr += strlen(prom_argv[argc]) + 1;
+       }
+       argv[prom_argc] = NULL;         /* end array with null pointer */
+       prom_argv = argv;
+
+       /* next preserve the environment variables */
+       len = 0;
+       i = 0;
+       for (envp = prom_envp; *envp != NULL; envp++) {
+               i++;            /* count number of environment variables */
+               len += sizeof(char *);          /* length of pointer */
+               len += strlen(*envp) + 1;       /* length of string */
+       }
+       len += sizeof(char *);          /* plus length of null pointer */
+
+       envp = kmalloc(len, GFP_KERNEL);
+       ptr = (char *) &envp[i+1];
+
+       for (argc = 0; argc < i; argc++) {
+               envp[argc] = ptr;
+               strcpy(ptr, prom_envp[argc]);
+               ptr += strlen(prom_envp[argc]) + 1;
+       }
+       envp[i] = NULL;                 /* end array with null pointer */
+       prom_envp = envp;
+
+       for (i = 0; i < boot_mem_map.nr_map; i++) {
+               if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
+                       continue;
+
+               addr = boot_mem_map.map[i].addr;
+               free_init_pages("prom memory",
+                               addr, addr + boot_mem_map.map[i].size);
+       }
+}
+
+struct prom_pmemblock *__init prom_getmdesc(void)
+{
+       static char     memsz_env[] __initdata = "memsize";
+       static char     heaptop_env[] __initdata = "heaptop";
+       char            *str;
+       unsigned int    memsize;
+       unsigned int    heaptop;
+#ifdef CONFIG_MTD_PMC_MSP_RAMROOT
+       void            *ramroot_start;
+       unsigned long   ramroot_size;
+#endif
+       int i;
+
+       str = prom_getenv(memsz_env);
+       if (!str) {
+               ppfinit("memsize not set in boot prom, "
+                       "set to default (32Mb)\n");
+               memsize = 0x02000000;
+       } else {
+               memsize = simple_strtol(str, NULL, 0);
+
+               if (memsize == 0) {
+                       /* if memsize is a bad size, use reasonable default */
+                       memsize = 0x02000000;
+               }
+
+               /* convert to physical address (removing caching bits, etc) */
+               memsize = CPHYSADDR(memsize);
+       }
+
+       str = prom_getenv(heaptop_env);
+       if (!str) {
+               heaptop = CPHYSADDR((u32)&_text);
+               ppfinit("heaptop not set in boot prom, "
+                       "set to default 0x%08x\n", heaptop);
+       } else {
+               heaptop = simple_strtol(str, NULL, 16);
+               if (heaptop == 0) {
+                       /* heaptop conversion bad, might have 0xValue */
+                       heaptop = simple_strtol(str, NULL, 0);
+
+                       if (heaptop == 0) {
+                               /* heaptop still bad, use reasonable default */
+                               heaptop = CPHYSADDR((u32)&_text);
+                       }
+               }
+
+               /* convert to physical address (removing caching bits, etc) */
+               heaptop = CPHYSADDR((u32)heaptop);
+       }
+
+       /* the base region */
+       i = 0;
+       mdesc[i].type = BOOT_MEM_RESERVED;
+       mdesc[i].base = 0x00000000;
+       mdesc[i].size = PAGE_ALIGN(0x300 + 0x80);
+               /* jtag interrupt vector + sizeof vector */
+
+       /* PMON data */
+       if (heaptop > mdesc[i].base + mdesc[i].size) {
+               i++;                    /* 1 */
+               mdesc[i].type = BOOT_MEM_ROM_DATA;
+               mdesc[i].base = mdesc[i-1].base + mdesc[i-1].size;
+               mdesc[i].size = heaptop - mdesc[i].base;
+       }
+
+       /* end of PMON data to start of kernel -- probably zero .. */
+       if (heaptop != CPHYSADDR((u32)_text)) {
+               i++;    /* 2 */
+               mdesc[i].type = BOOT_MEM_RAM;
+               mdesc[i].base = heaptop;
+               mdesc[i].size = CPHYSADDR((u32)_text) - mdesc[i].base;
+       }
+
+       /*  kernel proper */
+       i++;                    /* 3 */
+       mdesc[i].type = BOOT_MEM_RESERVED;
+       mdesc[i].base = CPHYSADDR((u32)_text);
+#ifdef CONFIG_MTD_PMC_MSP_RAMROOT
+       if (get_ramroot(&ramroot_start, &ramroot_size)) {
+               /*
+                * Rootfs in RAM -- follows kernel
+                * Combine rootfs image with kernel block so a
+                * page (4k) isn't wasted between memory blocks
+                */
+               mdesc[i].size = CPHYSADDR(PAGE_ALIGN(
+                       (u32)ramroot_start + ramroot_size)) - mdesc[i].base;
+       } else
+#endif
+               mdesc[i].size = CPHYSADDR(PAGE_ALIGN(
+                       (u32)_end)) - mdesc[i].base;
+
+       /* Remainder of RAM -- under memsize */
+       i++;                    /* 5 */
+       mdesc[i].type = yamon_free;
+       mdesc[i].base = mdesc[i-1].base + mdesc[i-1].size;
+       mdesc[i].size = memsize - mdesc[i].base;
+
+       return &mdesc[0];
+}
+
+/* rootfs functions */
+#ifdef CONFIG_MTD_PMC_MSP_RAMROOT
+bool get_ramroot(void **start, unsigned long *size)
+{
+       extern char _end[];
+
+       /* Check for start following the end of the kernel */
+       void *check_start = (void *)_end;
+
+       /* Check for supported rootfs types */
+#ifdef CONFIG_CRAMFS
+       if (*(__u32 *)check_start == CRAMFS_MAGIC) {
+               /* Get CRAMFS size */
+               *start = check_start;
+               *size = PAGE_ALIGN(((struct cramfs_super *)
+                                  check_start)->size);
+
+               return true;
+       }
+#endif
+#ifdef CONFIG_SQUASHFS
+       if (*((unsigned int *)check_start) == SQUASHFS_MAGIC) {
+               /* Get SQUASHFS size */
+               *start = check_start;
+               *size = PAGE_ALIGN(((struct squashfs_super_block *)
+                                  check_start)->bytes_used);
+
+               return true;
+       }
+#endif
+
+       return false;
+}
+EXPORT_SYMBOL(get_ramroot);
+#endif
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_setup.c b/arch/mips/pmc-sierra/msp71xx/msp_setup.c
new file mode 100644 (file)
index 0000000..8f69b78
--- /dev/null
@@ -0,0 +1,256 @@
+/*
+ * The generic setup file for PMC-Sierra MSP processors
+ *
+ * Copyright 2005-2007 PMC-Sierra, Inc,
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <asm/bootinfo.h>
+#include <asm/cacheflush.h>
+#include <asm/r4kcache.h>
+#include <asm/reboot.h>
+#include <asm/time.h>
+
+#include <msp_prom.h>
+#include <msp_regs.h>
+
+#if defined(CONFIG_PMC_MSP7120_GW)
+#include <msp_regops.h>
+#include <msp_gpio.h>
+#define MSP_BOARD_RESET_GPIO   9
+#endif
+
+extern void msp_timer_init(void);
+extern void msp_serial_setup(void);
+extern void pmctwiled_setup(void);
+
+#if defined(CONFIG_PMC_MSP7120_EVAL) || \
+    defined(CONFIG_PMC_MSP7120_GW) || \
+    defined(CONFIG_PMC_MSP7120_FPGA)
+/*
+ * Performs the reset for MSP7120-based boards
+ */
+void msp7120_reset(void)
+{
+       void *start, *end, *iptr;
+       register int i;
+
+       /* Diasble all interrupts */
+       local_irq_disable();
+#ifdef CONFIG_SYS_SUPPORTS_MULTITHREADING
+       dvpe();
+#endif
+
+       /* Cache the reset code of this function */
+       __asm__ __volatile__ (
+               "       .set    push                            \n"
+               "       .set    mips3                           \n"
+               "       la      %0,startpoint                   \n"
+               "       la      %1,endpoint                     \n"
+               "       .set    pop                             \n"
+               : "=r" (start), "=r" (end)
+               :
+       );
+
+       for (iptr = (void *)((unsigned int)start & ~(L1_CACHE_BYTES - 1));
+            iptr < end; iptr += L1_CACHE_BYTES)
+               cache_op(Fill, iptr);
+
+       __asm__ __volatile__ (
+               "startpoint:                                    \n"
+       );
+
+       /* Put the DDRC into self-refresh mode */
+       DDRC_INDIRECT_WRITE(DDRC_CTL(10), 0xb, 1 << 16);
+
+       /*
+        * IMPORTANT!
+        * DO NOT do anything from here on out that might even
+        * think about fetching from RAM - i.e., don't call any
+        * non-inlined functions, and be VERY sure that any inline
+        * functions you do call do NOT access any sort of RAM
+        * anywhere!
+        */
+
+       /* Wait a bit for the DDRC to settle */
+       for (i = 0; i < 100000000; i++);
+
+#if defined(CONFIG_PMC_MSP7120_GW)
+       /*
+        * Set GPIO 9 HI, (tied to board reset logic)
+        * GPIO 9 is the 4th GPIO of register 3
+        *
+        * NOTE: We cannot use the higher-level msp_gpio_mode()/out()
+        * as GPIO char driver may not be enabled and it would look up
+        * data inRAM!
+        */
+       set_value_reg32(GPIO_CFG3_REG,
+                       basic_mode_mask(MSP_BOARD_RESET_GPIO),
+                       basic_mode(MSP_GPIO_OUTPUT, MSP_BOARD_RESET_GPIO));
+       set_reg32(GPIO_DATA3_REG,
+                       basic_data_mask(MSP_BOARD_RESET_GPIO));
+
+       /*
+        * In case GPIO9 doesn't reset the board (jumper configurable!)
+        * fallback to device reset below.
+        */
+#endif
+       /* Set bit 1 of the MSP7120 reset register */
+       *RST_SET_REG = 0x00000001;
+
+       __asm__ __volatile__ (
+               "endpoint:                                      \n"
+       );
+}
+#endif
+
+void msp_restart(char *command)
+{
+       printk(KERN_WARNING "Now rebooting .......\n");
+
+#if defined(CONFIG_PMC_MSP7120_EVAL) || \
+    defined(CONFIG_PMC_MSP7120_GW) || \
+    defined(CONFIG_PMC_MSP7120_FPGA)
+       msp7120_reset();
+#else
+       /* No chip-specific reset code, just jump to the ROM reset vector */
+       set_c0_status(ST0_BEV | ST0_ERL);
+       change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
+       flush_cache_all();
+       write_c0_wired(0);
+
+       __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
+#endif
+}
+
+void msp_halt(void)
+{
+       printk(KERN_WARNING "\n** You can safely turn off the power\n");
+       while (1)
+               /* If possible call official function to get CPU WARs */
+               if (cpu_wait)
+                       (*cpu_wait)();
+               else
+                       __asm__(".set\tmips3\n\t" "wait\n\t" ".set\tmips0");
+}
+
+void msp_power_off(void)
+{
+       msp_halt();
+}
+
+void __init plat_mem_setup(void)
+{
+       _machine_restart = msp_restart;
+       _machine_halt = msp_halt;
+       pm_power_off = msp_power_off;
+
+       board_time_init = msp_timer_init;
+}
+
+void __init prom_init(void)
+{
+       unsigned long family;
+       unsigned long revision;
+
+       prom_argc = fw_arg0;
+       prom_argv = (char **)fw_arg1;
+       prom_envp = (char **)fw_arg2;
+
+       /*
+        * Someday we can use this with PMON2000 to get a
+        * platform call prom routines for output etc. without
+        * having to use grody hacks.  For now it's unused.
+        *
+        * struct callvectors *cv = (struct callvectors *) fw_arg3;
+        */
+       family = identify_family();
+       revision = identify_revision();
+
+       switch (family) {
+       case FAMILY_FPGA:
+               if (FPGA_IS_MSP4200(revision)) {
+                       /* Old-style revision ID */
+                       mips_machgroup = MACH_GROUP_MSP;
+                       mips_machtype = MACH_MSP4200_FPGA;
+               } else {
+                       mips_machgroup = MACH_GROUP_MSP;
+                       mips_machtype = MACH_MSP_OTHER;
+               }
+               break;
+
+       case FAMILY_MSP4200:
+               mips_machgroup = MACH_GROUP_MSP;
+#if defined(CONFIG_PMC_MSP4200_EVAL)
+               mips_machtype  = MACH_MSP4200_EVAL;
+#elif defined(CONFIG_PMC_MSP4200_GW)
+               mips_machtype  = MACH_MSP4200_GW;
+#else
+               mips_machtype = MACH_MSP_OTHER;
+#endif
+               break;
+
+       case FAMILY_MSP4200_FPGA:
+               mips_machgroup = MACH_GROUP_MSP;
+               mips_machtype  = MACH_MSP4200_FPGA;
+               break;
+
+       case FAMILY_MSP7100:
+               mips_machgroup = MACH_GROUP_MSP;
+#if defined(CONFIG_PMC_MSP7120_EVAL)
+               mips_machtype = MACH_MSP7120_EVAL;
+#elif defined(CONFIG_PMC_MSP7120_GW)
+               mips_machtype = MACH_MSP7120_GW;
+#else
+               mips_machtype = MACH_MSP_OTHER;
+#endif
+               break;
+
+       case FAMILY_MSP7100_FPGA:
+               mips_machgroup = MACH_GROUP_MSP;
+               mips_machtype  = MACH_MSP7120_FPGA;
+               break;
+
+       default:
+               /* we don't recognize the machine */
+               mips_machgroup = MACH_GROUP_UNKNOWN;
+               mips_machtype  = MACH_UNKNOWN;
+               break;
+       }
+
+       /* make sure we have the right initialization routine - sanity */
+       if (mips_machgroup != MACH_GROUP_MSP) {
+               ppfinit("Unknown machine group in a "
+                       "MSP initialization routine\n");
+               panic("***Bogosity factor five***, exiting\n");
+       }
+
+       prom_init_cmdline();
+
+       prom_meminit();
+
+       /*
+        * Sub-system setup follows.
+        * Setup functions can  either be called here or using the
+        * subsys_initcall mechanism (i.e. see msp_pci_setup). The
+        * order in which they are called can be changed by using the
+        * link order in arch/mips/pmc-sierra/msp71xx/Makefile.
+        *
+        * NOTE: Please keep sub-system specific initialization code
+        * in separate specific files.
+        */
+       msp_serial_setup();
+
+#ifdef CONFIG_PMCTWILED
+       /*
+        * Setup LED states before the subsys_initcall loads other
+        * dependant drivers/modules.
+        */
+       pmctwiled_setup();
+#endif
+}
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_time.c b/arch/mips/pmc-sierra/msp71xx/msp_time.c
new file mode 100644 (file)
index 0000000..2a2beac
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Setting up the clock on MSP SOCs.  No RTC typically.
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You 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/kernel_stat.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/module.h>
+#include <linux/ptrace.h>
+
+#include <asm/mipsregs.h>
+#include <asm/time.h>
+
+#include <msp_prom.h>
+#include <msp_int.h>
+#include <msp_regs.h>
+
+void __init msp_timer_init(void)
+{
+       char    *endp, *s;
+       unsigned long cpu_rate = 0;
+
+       if (cpu_rate == 0) {
+               s = prom_getenv("clkfreqhz");
+               cpu_rate = simple_strtoul(s, &endp, 10);
+               if (endp != NULL && *endp != 0) {
+                       printk(KERN_ERR
+                               "Clock rate in Hz parse error: %s\n", s);
+                       cpu_rate = 0;
+               }
+       }
+
+       if (cpu_rate == 0) {
+               s = prom_getenv("clkfreq");
+               cpu_rate = 1000 * simple_strtoul(s, &endp, 10);
+               if (endp != NULL && *endp != 0) {
+                       printk(KERN_ERR
+                               "Clock rate in MHz parse error: %s\n", s);
+                       cpu_rate = 0;
+               }
+       }
+
+       if (cpu_rate == 0) {
+#if defined(CONFIG_PMC_MSP7120_EVAL) \
+ || defined(CONFIG_PMC_MSP7120_GW)
+               cpu_rate = 400000000;
+#elif defined(CONFIG_PMC_MSP7120_FPGA)
+               cpu_rate = 25000000;
+#else
+               cpu_rate = 150000000;
+#endif
+               printk(KERN_ERR
+                       "Failed to determine CPU clock rate, "
+                       "assuming %ld hz ...\n", cpu_rate);
+       }
+
+       printk(KERN_WARNING "Clock rate set to %ld\n", cpu_rate);
+
+       /* timer frequency is 1/2 clock rate */
+       mips_hpt_frequency = cpu_rate/2;
+}
+
+
+void __init plat_timer_setup(struct irqaction *irq)
+{
+#ifdef CONFIG_IRQ_MSP_CIC
+       /* we are using the vpe0 counter for timer interrupts */
+       setup_irq(MSP_INT_VPE0_TIMER, irq);
+#else
+       /* we are using the mips counter for timer interrupts */
+       setup_irq(MSP_INT_TIMER, irq);
+#endif
+}
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_usb.c b/arch/mips/pmc-sierra/msp71xx/msp_usb.c
new file mode 100644 (file)
index 0000000..21f9c70
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * The setup file for USB related hardware on PMC-Sierra MSP processors.
+ *
+ * Copyright 2006-2007 PMC-Sierra, Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+
+#include <asm/mipsregs.h>
+
+#include <msp_regs.h>
+#include <msp_int.h>
+#include <msp_prom.h>
+
+#if defined(CONFIG_USB_EHCI_HCD)
+static struct resource msp_usbhost_resources [] = {
+       [0] = {
+               .start  = MSP_USB_BASE_START,
+               .end    = MSP_USB_BASE_END,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = MSP_INT_USB,
+               .end    = MSP_INT_USB,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static u64 msp_usbhost_dma_mask = DMA_32BIT_MASK;
+
+static struct platform_device msp_usbhost_device = {
+       .name   = "pmcmsp-ehci",
+       .id     = 0,
+       .dev    = {
+               .dma_mask = &msp_usbhost_dma_mask,
+               .coherent_dma_mask = DMA_32BIT_MASK,
+       },
+       .num_resources  = ARRAY_SIZE (msp_usbhost_resources),
+       .resource       = msp_usbhost_resources,
+};
+#endif /* CONFIG_USB_EHCI_HCD */
+
+#if defined(CONFIG_USB_GADGET)
+static struct resource msp_usbdev_resources [] = {
+       [0] = {
+               .start  = MSP_USB_BASE,
+               .end    = MSP_USB_BASE_END,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = MSP_INT_USB,
+               .end    = MSP_INT_USB,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static u64 msp_usbdev_dma_mask = DMA_32BIT_MASK;
+
+static struct platform_device msp_usbdev_device = {
+       .name   = "msp71xx_udc",
+       .id     = 0,
+       .dev    = {
+               .dma_mask = &msp_usbdev_dma_mask,
+               .coherent_dma_mask = DMA_32BIT_MASK,
+       },
+       .num_resources  = ARRAY_SIZE (msp_usbdev_resources),
+       .resource       = msp_usbdev_resources,
+};
+#endif /* CONFIG_USB_GADGET */
+
+#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_GADGET)
+static struct platform_device *msp_devs[1];
+#endif
+
+
+static int __init msp_usb_setup(void)
+{
+#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_GADGET)
+       char *strp;
+       char envstr[32];
+       unsigned int val = 0;
+       int result = 0;
+
+       /*
+        * construct environment name usbmode
+        * set usbmode <host/device> as pmon environment var
+        */
+       snprintf((char *)&envstr[0], sizeof(envstr), "usbmode");
+
+#if defined(CONFIG_USB_EHCI_HCD)
+       /* default to host mode */
+       val = 1;
+#endif
+
+       /* get environment string */
+       strp = prom_getenv((char *)&envstr[0]);
+       if (strp) {
+               if (!strcmp(strp, "device"))
+                       val = 0;
+       }
+
+       if (val) {
+#if defined(CONFIG_USB_EHCI_HCD)
+               /* get host mode device */
+               msp_devs[0] = &msp_usbhost_device;
+               ppfinit("platform add USB HOST done %s.\n",
+                           msp_devs[0]->name);
+
+               result = platform_add_devices(msp_devs, ARRAY_SIZE (msp_devs));
+#endif /* CONFIG_USB_EHCI_HCD */
+       }
+#if defined(CONFIG_USB_GADGET)
+       else {
+               /* get device mode structure */
+               msp_devs[0] = &msp_usbdev_device;
+               ppfinit("platform add USB DEVICE done %s.\n",
+                           msp_devs[0]->name);
+
+               result = platform_add_devices(msp_devs, ARRAY_SIZE (msp_devs));
+       }
+#endif /* CONFIG_USB_GADGET */
+#endif /* CONFIG_USB_EHCI_HCD || CONFIG_USB_GADGET */
+
+       return result;
+}
+
+subsys_initcall(msp_usb_setup);
index 305491e74dbe2b9134c1b55ee18cd0edbaa10d06..d83c4ada14f33565833bbb3603b40e502920ef0c 100644 (file)
@@ -77,7 +77,7 @@ void __init plat_prepare_cpus(unsigned int max_cpus)
  * stack so the first thing we do is throw away that stuff and load useful
  * values into the registers ...
  */
-void prom_boot_secondary(int cpu, struct task_struct *idle)
+void __init prom_boot_secondary(int cpu, struct task_struct *idle)
 {
        unsigned long gp = (unsigned long) task_thread_info(idle);
        unsigned long sp = __KSTK_TOS(idle);
index 66df5ac8f089b27ed0bc257ec4c0c02fe158abde..63afd7e44428ddfd054f3a94ee8ffc0ae4cfdcbe 100644 (file)
@@ -46,7 +46,7 @@ static struct timer_list power_timer, blink_timer, debounce_timer, volume_timer;
 
 static int machine_state;
 
-static void ATTRIB_NORET sgi_machine_power_off(void)
+static void __noreturn sgi_machine_power_off(void)
 {
        unsigned int tmp;
 
@@ -68,7 +68,7 @@ static void ATTRIB_NORET sgi_machine_power_off(void)
        }
 }
 
-static void ATTRIB_NORET sgi_machine_restart(char *command)
+static void __noreturn sgi_machine_restart(char *command)
 {
        if (machine_state & MACHINE_SHUTTING_DOWN)
                sgi_machine_power_off();
@@ -76,7 +76,7 @@ static void ATTRIB_NORET sgi_machine_restart(char *command)
        while (1);
 }
 
-static void ATTRIB_NORET sgi_machine_halt(void)
+static void __noreturn sgi_machine_halt(void)
 {
        if (machine_state & MACHINE_SHUTTING_DOWN)
                sgi_machine_power_off();
index ce907eda221b6b91e395029b30d8eabc4dbe5bd2..123141ab21a24a8eb5aad1e7701db8cec6923d33 100644 (file)
@@ -21,7 +21,6 @@
 #include <asm/traps.h>
 #include <asm/uaccess.h>
 
-extern void dump_tlb_addr(unsigned long addr);
 extern void dump_tlb_all(void);
 
 static void dump_hub_information(unsigned long errst0, unsigned long errst1)
index 120b15932caf035ec813e950a897f63c3fa9df14..ba3697ee7ff65ecc70bf15f30653fa54a5cc63b9 100644 (file)
@@ -1,5 +1,53 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org)
+ */
+#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+
+#include <asm/ip32/mace.h>
+#include <asm/ip32/ip32_ints.h>
+
+/*
+ * .iobase isn't a constant (in the sense of C) so we fill it in at runtime.
+ */
+#define MACE_PORT(int)                                                 \
+{                                                                      \
+       .irq            = int,                                          \
+       .uartclk        = 1843200,                                      \
+       .iotype         = UPIO_MEM,                                     \
+       .flags          = UPF_SKIP_TEST,                                \
+       .regshift       = 8,                                            \
+}
+
+static struct plat_serial8250_port uart8250_data[] = {
+       MACE_PORT(MACEISA_SERIAL1_IRQ),
+       MACE_PORT(MACEISA_SERIAL2_IRQ),
+       { },
+};
+
+static struct platform_device uart8250_device = {
+       .name                   = "serial8250",
+       .id                     = PLAT8250_DEV_PLATFORM,
+       .dev                    = {
+               .platform_data  = uart8250_data,
+       },
+};
+
+static int __init uart8250_init(void)
+{
+       uart8250_data[0].iobase = (unsigned long) &mace->isa.serial1;
+       uart8250_data[1].iobase = (unsigned long) &mace->isa.serial1;
+
+       return platform_device_register(&uart8250_device);
+}
+
+device_initcall(uart8250_init);
 
 static __init int meth_devinit(void)
 {
@@ -18,3 +66,7 @@ static __init int meth_devinit(void)
 }
 
 device_initcall(meth_devinit);
+
+MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("8250 UART probe driver for SGI IP32 aka O2");
index 57708fe28bd7aa573af4292d7a1669b575b9a69d..bbba066cb405c608de9a19020c276d21d1f87f1e 100644 (file)
@@ -62,12 +62,6 @@ static inline void str2eaddr(unsigned char *ea, unsigned char *str)
 }
 #endif
 
-#ifdef CONFIG_SERIAL_8250
-#include <linux/tty.h>
-#include <linux/serial.h>
-#include <linux/serial_core.h>
-#endif /* CONFIG_SERIAL_8250 */
-
 /* An arbitrary time; this can be decreased if reliability looks good */
 #define WAIT_MS 10
 
@@ -96,36 +90,6 @@ void __init plat_mem_setup(void)
 
        board_time_init = ip32_time_init;
 
-#ifdef CONFIG_SERIAL_8250
-       {
-               static struct uart_port o2_serial[2];
-
-               memset(o2_serial, 0, sizeof(o2_serial));
-               o2_serial[0].type       = PORT_16550A;
-               o2_serial[0].line       = 0;
-               o2_serial[0].irq        = MACEISA_SERIAL1_IRQ;
-               o2_serial[0].flags      = UPF_SKIP_TEST;
-               o2_serial[0].uartclk    = 1843200;
-               o2_serial[0].iotype     = UPIO_MEM;
-               o2_serial[0].membase    = (char *)&mace->isa.serial1;
-               o2_serial[0].fifosize   = 14;
-                /* How much to shift register offset by. Each UART register
-                * is replicated over 256 byte space */
-               o2_serial[0].regshift   = 8;
-               o2_serial[1].type       = PORT_16550A;
-               o2_serial[1].line       = 1;
-               o2_serial[1].irq        = MACEISA_SERIAL2_IRQ;
-               o2_serial[1].flags      = UPF_SKIP_TEST;
-               o2_serial[1].uartclk    = 1843200;
-               o2_serial[1].iotype     = UPIO_MEM;
-               o2_serial[1].membase    = (char *)&mace->isa.serial2;
-               o2_serial[1].fifosize   = 14;
-               o2_serial[1].regshift   = 8;
-
-               early_serial_setup(&o2_serial[0]);
-               early_serial_setup(&o2_serial[1]);
-       }
-#endif
 #ifdef CONFIG_SGI_O2MACE_ETH
        {
                char *mac = ArcGetEnvironmentVariable("eaddr");
index ae4a92c3e529bf8cfd09d5cbbd19508d95776292..51898dd1304a85ad95f76665b3ee69b88368c306 100644 (file)
@@ -62,7 +62,7 @@ extern unsigned long initrd_start, initrd_end;
 extern int kgdb_port;
 #endif
 
-static void ATTRIB_NORET cfe_linux_exit(void *arg)
+static void __noreturn cfe_linux_exit(void *arg)
 {
        int warm = *(int *)arg;
 
@@ -83,14 +83,14 @@ static void ATTRIB_NORET cfe_linux_exit(void *arg)
        while (1);
 }
 
-static void ATTRIB_NORET cfe_linux_restart(char *command)
+static void __noreturn cfe_linux_restart(char *command)
 {
        static const int zero;
 
        cfe_linux_exit((void *)&zero);
 }
 
-static void ATTRIB_NORET cfe_linux_halt(void)
+static void __noreturn cfe_linux_halt(void)
 {
        static const int one = 1;
 
diff --git a/arch/mips/sibyte/swarm/time.c b/arch/mips/sibyte/swarm/time.c
deleted file mode 100644 (file)
index 97c73c7..0000000
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright (C) 2000, 2001 Broadcom 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.
- */
-
-/*
- * Time routines for the swarm board.  We pass all the hard stuff
- * through to the sb1250 handling code.  Only thing we really keep
- * track of here is what time of day we think it is.  And we don't
- * really even do a good job of that...
- */
-
-
-#include <linux/bcd.h>
-#include <linux/init.h>
-#include <linux/time.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <asm/system.h>
-#include <asm/addrspace.h>
-#include <asm/io.h>
-
-#include <asm/sibyte/sb1250.h>
-#include <asm/sibyte/sb1250_regs.h>
-#include <asm/sibyte/sb1250_smbus.h>
-
-static unsigned long long sec_bias = 0;
-static unsigned int usec_bias = 0;
-
-/* Xicor 1241 definitions */
-
-/*
- * Register bits
- */
-
-#define X1241REG_SR_BAT        0x80            /* currently on battery power */
-#define X1241REG_SR_RWEL 0x04          /* r/w latch is enabled, can write RTC */
-#define X1241REG_SR_WEL 0x02           /* r/w latch is unlocked, can enable r/w now */
-#define X1241REG_SR_RTCF 0x01          /* clock failed */
-#define X1241REG_BL_BP2 0x80           /* block protect 2 */
-#define X1241REG_BL_BP1 0x40           /* block protect 1 */
-#define X1241REG_BL_BP0 0x20           /* block protect 0 */
-#define X1241REG_BL_WD1        0x10
-#define X1241REG_BL_WD0        0x08
-#define X1241REG_HR_MIL 0x80           /* military time format */
-
-/*
- * Register numbers
- */
-
-#define X1241REG_BL    0x10            /* block protect bits */
-#define X1241REG_INT   0x11            /*  */
-#define X1241REG_SC    0x30            /* Seconds */
-#define X1241REG_MN    0x31            /* Minutes */
-#define X1241REG_HR    0x32            /* Hours */
-#define X1241REG_DT    0x33            /* Day of month */
-#define X1241REG_MO    0x34            /* Month */
-#define X1241REG_YR    0x35            /* Year */
-#define X1241REG_DW    0x36            /* Day of Week */
-#define X1241REG_Y2K   0x37            /* Year 2K */
-#define X1241REG_SR    0x3F            /* Status register */
-
-#define X1241_CCR_ADDRESS      0x6F
-
-#define SMB_CSR(reg) (IOADDR(A_SMB_REGISTER(1, reg)))
-
-static int xicor_read(uint8_t addr)
-{
-        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
-                ;
-
-       __raw_writeq((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD));
-       __raw_writeq(addr & 0xff, SMB_CSR(R_SMB_DATA));
-       __raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE,
-                    SMB_CSR(R_SMB_START));
-
-        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
-                ;
-
-       __raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE,
-                    SMB_CSR(R_SMB_START));
-
-        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
-                ;
-
-        if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
-                /* Clear error bit by writing a 1 */
-                __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
-                return -1;
-        }
-
-       return (__raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
-}
-
-static int xicor_write(uint8_t addr, int b)
-{
-        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
-                ;
-
-       __raw_writeq(addr, SMB_CSR(R_SMB_CMD));
-       __raw_writeq((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA));
-       __raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE,
-                    SMB_CSR(R_SMB_START));
-
-        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
-                ;
-
-        if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
-                /* Clear error bit by writing a 1 */
-                __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
-                return -1;
-        } else {
-               return 0;
-       }
-}
-
-/*
- * In order to set the CMOS clock precisely, set_rtc_mmss has to be
- * called 500 ms after the second nowtime has started, because when
- * nowtime is written into the registers of the CMOS clock, it will
- * jump to the next second precisely 500 ms later. Check the Motorola
- * MC146818A or Dallas DS12887 data sheet for details.
- *
- * BUG: This routine does not handle hour overflow properly; it just
- *      sets the minutes. Usually you'll only notice that after reboot!
- */
-int set_rtc_mmss(unsigned long nowtime)
-{
-       int retval = 0;
-       int real_seconds, real_minutes, cmos_minutes;
-
-       cmos_minutes = xicor_read(X1241REG_MN);
-       cmos_minutes = BCD2BIN(cmos_minutes);
-
-       /*
-        * since we're only adjusting minutes and seconds,
-        * don't interfere with hour overflow. This avoids
-        * messing with unknown time zones but requires your
-        * RTC not to be off by more than 15 minutes
-        */
-       real_seconds = nowtime % 60;
-       real_minutes = nowtime / 60;
-       if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
-               real_minutes += 30;             /* correct for half hour time zone */
-       real_minutes %= 60;
-
-       /* unlock writes to the CCR */
-       xicor_write(X1241REG_SR, X1241REG_SR_WEL);
-       xicor_write(X1241REG_SR, X1241REG_SR_WEL | X1241REG_SR_RWEL);
-
-       if (abs(real_minutes - cmos_minutes) < 30) {
-               real_seconds = BIN2BCD(real_seconds);
-               real_minutes = BIN2BCD(real_minutes);
-               xicor_write(X1241REG_SC, real_seconds);
-               xicor_write(X1241REG_MN, real_minutes);
-       } else {
-               printk(KERN_WARNING
-                      "set_rtc_mmss: can't update from %d to %d\n",
-                      cmos_minutes, real_minutes);
-               retval = -1;
-       }
-
-       xicor_write(X1241REG_SR, 0);
-
-       printk("set_rtc_mmss: %02d:%02d\n", real_minutes, real_seconds);
-
-       return retval;
-}
-
-static unsigned long __init get_swarm_time(void)
-{
-       unsigned int year, mon, day, hour, min, sec, y2k;
-
-       sec = xicor_read(X1241REG_SC);
-       min = xicor_read(X1241REG_MN);
-       hour = xicor_read(X1241REG_HR);
-
-       if (hour & X1241REG_HR_MIL) {
-               hour &= 0x3f;
-       } else {
-               if (hour & 0x20)
-                       hour = (hour & 0xf) + 0x12;
-       }
-
-       sec = BCD2BIN(sec);
-       min = BCD2BIN(min);
-       hour = BCD2BIN(hour);
-
-       day = xicor_read(X1241REG_DT);
-       mon = xicor_read(X1241REG_MO);
-       year = xicor_read(X1241REG_YR);
-       y2k = xicor_read(X1241REG_Y2K);
-
-       day = BCD2BIN(day);
-       mon = BCD2BIN(mon);
-       year = BCD2BIN(year);
-       y2k = BCD2BIN(y2k);
-
-       year += (y2k * 100);
-
-       return mktime(year, mon, day, hour, min, sec);
-}
-
-/*
- *  Bring up the timer at 100 Hz.
- */
-void __init swarm_time_init(void)
-{
-       unsigned int flags;
-       int status;
-
-       /* Set up the scd general purpose timer 0 to cpu 0 */
-       sb1250_time_init();
-
-       /* Establish communication with the Xicor 1241 RTC */
-       /* XXXKW how do I share the SMBus with the I2C subsystem? */
-
-       __raw_writeq(K_SMB_FREQ_400KHZ, SMB_CSR(R_SMB_FREQ));
-       __raw_writeq(0, SMB_CSR(R_SMB_CONTROL));
-
-       if ((status = xicor_read(X1241REG_SR_RTCF)) < 0) {
-               printk("x1241: couldn't detect on SWARM SMBus 1\n");
-       } else {
-               if (status & X1241REG_SR_RTCF)
-                       printk("x1241: battery failed -- time is probably wrong\n");
-               write_seqlock_irqsave(&xtime_lock, flags);
-               xtime.tv_sec = get_swarm_time();
-               xtime.tv_nsec = 0;
-               write_sequnlock_irqrestore(&xtime_lock, flags);
-       }
-}
index e5777b7e2bc9507555535647a4aa8a5c80f8c027..471418e4f446a4abc77dcd906bc93f52b554e66d 100644 (file)
@@ -2,5 +2,5 @@
 # Makefile for the SNI specific part of the kernel
 #
 
-obj-y += irq.o reset.o setup.o ds1216.o a20r.o rm200.o pcimt.o pcit.o time.o
+obj-y += irq.o reset.o setup.o a20r.o rm200.o pcimt.o pcit.o time.o
 obj-$(CONFIG_CPU_BIG_ENDIAN) += sniprom.o
index 31ab80f1befabeb3a4e34b01ad08a28212303918..acc9ba76c1a9f2611596931b5b1c1b13ccd27fe4 100644 (file)
@@ -15,7 +15,6 @@
 
 #include <asm/sni.h>
 #include <asm/time.h>
-#include <asm/ds1216.h>
 
 #define PORT(_base,_irq)                               \
        {                                               \
@@ -40,20 +39,34 @@ static struct platform_device a20r_serial8250_device = {
        },
 };
 
+static struct resource a20r_ds1216_rsrc[] = {
+        {
+                .start = 0x1c081ffc,
+                .end   = 0x1c081fff,
+                .flags = IORESOURCE_MEM
+        }
+};
+
+static struct platform_device a20r_ds1216_device = {
+        .name           = "rtc-ds1216",
+        .num_resources  = ARRAY_SIZE(a20r_ds1216_rsrc),
+        .resource       = a20r_ds1216_rsrc
+};
+
 static struct resource snirm_82596_rsrc[] = {
        {
-               .start = 0xb8000000,
-               .end   = 0xb8000004,
+               .start = 0x18000000,
+               .end   = 0x18000004,
                .flags = IORESOURCE_MEM
        },
        {
-               .start = 0xb8010000,
-               .end   = 0xb8010004,
+               .start = 0x18010000,
+               .end   = 0x18010004,
                .flags = IORESOURCE_MEM
        },
        {
-               .start = 0xbff00000,
-               .end   = 0xbff00020,
+               .start = 0x1ff00000,
+               .end   = 0x1ff00020,
                .flags = IORESOURCE_MEM
        },
        {
@@ -74,8 +87,8 @@ static struct platform_device snirm_82596_pdev = {
 
 static struct resource snirm_53c710_rsrc[] = {
        {
-               .start = 0xb9000000,
-               .end   = 0xb90fffff,
+               .start = 0x19000000,
+               .end   = 0x190fffff,
                .flags = IORESOURCE_MEM
        },
        {
@@ -93,8 +106,8 @@ static struct platform_device snirm_53c710_pdev = {
 
 static struct resource sc26xx_rsrc[] = {
        {
-               .start = 0xbc070000,
-               .end   = 0xbc0700ff,
+               .start = 0x1c070000,
+               .end   = 0x1c0700ff,
                .flags = IORESOURCE_MEM
        },
        {
@@ -205,8 +218,7 @@ void __init sni_a20r_irq_init(void)
 
 void sni_a20r_init(void)
 {
-       ds1216_base = (volatile unsigned char *) SNI_DS1216_A20R_BASE;
-       rtc_mips_get_time = ds1216_get_cmos_time;
+       /* FIXME, remove if not needed */
 }
 
 static int __init snirm_a20r_setup_devinit(void)
@@ -218,6 +230,7 @@ static int __init snirm_a20r_setup_devinit(void)
                platform_device_register(&snirm_53c710_pdev);
                platform_device_register(&sc26xx_pdev);
                platform_device_register(&a20r_serial8250_device);
+               platform_device_register(&a20r_ds1216_device);
                break;
        }
 
diff --git a/arch/mips/sni/ds1216.c b/arch/mips/sni/ds1216.c
deleted file mode 100644 (file)
index 1d92732..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-
-#include <linux/bcd.h>
-#include <linux/time.h>
-
-#include <asm/ds1216.h>
-
-volatile unsigned char *ds1216_base;
-
-/*
- * Read the 64 bit we'd like to have - It a series
- * of 64 bits showing up in the LSB of the base register.
- *
- */
-static unsigned char *ds1216_read(void)
-{
-       static unsigned char    rdbuf[8];
-       unsigned char           c;
-       int                     i, j;
-
-       for (i = 0; i < 8; i++) {
-               c = 0x0;
-               for (j = 0; j < 8; j++) {
-                       c |= (*ds1216_base & 0x1) << j;
-               }
-               rdbuf[i] = c;
-       }
-
-       return rdbuf;
-}
-
-static void ds1216_switch_ds_to_clock(void)
-{
-       unsigned char magic[] = {
-               0xc5, 0x3a, 0xa3, 0x5c, 0xc5, 0x3a, 0xa3, 0x5c
-       };
-       int i,j,c;
-
-       /* Reset magic pointer */
-       c = *ds1216_base;
-
-       /* Write 64 bit magic to DS1216 */
-       for (i = 0; i < 8; i++) {
-               c = magic[i];
-               for (j = 0; j < 8; j++) {
-                       *ds1216_base = c;
-                       c = c >> 1;
-               }
-       }
-}
-
-unsigned long ds1216_get_cmos_time(void)
-{
-       unsigned char   *rdbuf;
-       unsigned int    year, month, date, hour, min, sec;
-
-       ds1216_switch_ds_to_clock();
-       rdbuf = ds1216_read();
-
-       sec = BCD2BIN(DS1216_SEC(rdbuf));
-       min = BCD2BIN(DS1216_MIN(rdbuf));
-       hour = BCD2BIN(DS1216_HOUR(rdbuf));
-       date = BCD2BIN(DS1216_DATE(rdbuf));
-       month = BCD2BIN(DS1216_MONTH(rdbuf));
-       year = BCD2BIN(DS1216_YEAR(rdbuf));
-
-       if (DS1216_1224(rdbuf) && DS1216_AMPM(rdbuf))
-               hour+=12;
-
-       if (year < 70)
-               year += 2000;
-       else
-               year += 1900;
-
-       return mktime(year, month, date, hour, min, sec);
-}
-
-int ds1216_set_rtc_mmss(unsigned long nowtime)
-{
-       printk("ds1216_set_rtc_mmss called but not implemented\n");
-       return -1;
-}
index 97b234361b4d0afa8d5c0b64434c2bf07a253292..44b1ae62aa4ac0ed4aef2534fbd2185478f3da1e 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/pci.h>
 #include <linux/serial_8250.h>
 
-#include <asm/mc146818-time.h>
 #include <asm/sni.h>
 #include <asm/time.h>
 #include <asm/i8259.h>
@@ -90,6 +89,26 @@ static struct platform_device pcimt_serial8250_device = {
        },
 };
 
+static struct resource pcimt_cmos_rsrc[] = {
+        {
+                .start = 0x70,
+                .end   = 0x71,
+                .flags = IORESOURCE_IO
+        },
+        {
+                .start = 8,
+                .end   = 8,
+                .flags = IORESOURCE_IRQ
+        }
+};
+
+static struct platform_device pcimt_cmos_device = {
+        .name           = "rtc_cmos",
+        .num_resources  = ARRAY_SIZE(pcimt_cmos_rsrc),
+        .resource       = pcimt_cmos_rsrc
+};
+
+
 static struct resource sni_io_resource = {
        .start  = 0x00000000UL,
        .end    = 0x03bfffffUL,
@@ -290,12 +309,10 @@ void __init sni_pcimt_irq_init(void)
        change_c0_status(ST0_IM, IE_IRQ1|IE_IRQ3);
 }
 
-void sni_pcimt_init(void)
+void __init sni_pcimt_init(void)
 {
        sni_pcimt_detect();
        sni_pcimt_sc_init();
-       rtc_mips_get_time = mc146818_get_cmos_time;
-       rtc_mips_set_time = mc146818_set_rtc_mmss;
        board_time_init = sni_cpu_time_init;
        ioport_resource.end = sni_io_resource.end;
 #ifdef CONFIG_PCI
@@ -312,6 +329,7 @@ static int __init snirm_pcimt_setup_devinit(void)
        case SNI_BRD_PCI_DESKTOP:
        case SNI_BRD_PCI_MTOWER_CPLUS:
                platform_device_register(&pcimt_serial8250_device);
+               platform_device_register(&pcimt_cmos_device);
                break;
        }
 
index 00d151f4d121875a4ef6b2dbd40ab1c57e4c8f61..2480c478dcbdc7b44e5a80fa054ec2ef227ab2dc 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/pci.h>
 #include <linux/serial_8250.h>
 
-#include <asm/mc146818-time.h>
 #include <asm/sni.h>
 #include <asm/time.h>
 #include <asm/irq_cpu.h>
@@ -58,6 +57,25 @@ static struct platform_device pcit_cplus_serial8250_device = {
        },
 };
 
+static struct resource pcit_cmos_rsrc[] = {
+        {
+                .start = 0x70,
+                .end   = 0x71,
+                .flags = IORESOURCE_IO
+        },
+        {
+                .start = 8,
+                .end   = 8,
+                .flags = IORESOURCE_IRQ
+        }
+};
+
+static struct platform_device pcit_cmos_device = {
+        .name           = "rtc_cmos",
+        .num_resources  = ARRAY_SIZE(pcit_cmos_rsrc),
+        .resource       = pcit_cmos_rsrc
+};
+
 static struct resource sni_io_resource = {
        .start  = 0x00000000UL,
        .end    = 0x03bfffffUL,
@@ -243,10 +261,8 @@ void __init sni_pcit_cplus_irq_init(void)
        setup_irq (MIPS_CPU_IRQ_BASE + 3, &sni_isa_irq);
 }
 
-void sni_pcit_init(void)
+void __init sni_pcit_init(void)
 {
-       rtc_mips_get_time = mc146818_get_cmos_time;
-       rtc_mips_set_time = mc146818_set_rtc_mmss;
        board_time_init = sni_cpu_time_init;
        ioport_resource.end = sni_io_resource.end;
 #ifdef CONFIG_PCI
@@ -261,10 +277,12 @@ static int __init snirm_pcit_setup_devinit(void)
        switch (sni_brd_type) {
        case SNI_BRD_PCI_TOWER:
                platform_device_register(&pcit_serial8250_device);
+               platform_device_register(&pcit_cmos_device);
                break;
 
        case SNI_BRD_PCI_TOWER_CPLUS:
                platform_device_register(&pcit_cplus_serial8250_device);
+               platform_device_register(&pcit_cmos_device);
                break;
        }
        return 0;
index b82ff129f5ead20d452f8f76d6ea3a6b90a9d1fb..28a11d8605cece9d2425b9a3a8aaed954c9d07ac 100644 (file)
@@ -15,7 +15,6 @@
 
 #include <asm/sni.h>
 #include <asm/time.h>
-#include <asm/ds1216.h>
 #include <asm/irq_cpu.h>
 
 #define PORT(_base,_irq)                               \
@@ -41,20 +40,34 @@ static struct platform_device rm200_serial8250_device = {
        },
 };
 
+static struct resource rm200_ds1216_rsrc[] = {
+        {
+                .start = 0x1cd41ffc,
+                .end   = 0x1cd41fff,
+                .flags = IORESOURCE_MEM
+        }
+};
+
+static struct platform_device rm200_ds1216_device = {
+        .name           = "rtc-ds1216",
+        .num_resources  = ARRAY_SIZE(rm200_ds1216_rsrc),
+        .resource       = rm200_ds1216_rsrc
+};
+
 static struct resource snirm_82596_rm200_rsrc[] = {
        {
-               .start = 0xb8000000,
-               .end   = 0xb80fffff,
+               .start = 0x18000000,
+               .end   = 0x180fffff,
                .flags = IORESOURCE_MEM
        },
        {
-               .start = 0xbb000000,
-               .end   = 0xbb000004,
+               .start = 0x1b000000,
+               .end   = 0x1b000004,
                .flags = IORESOURCE_MEM
        },
        {
-               .start = 0xbff00000,
-               .end   = 0xbff00020,
+               .start = 0x1ff00000,
+               .end   = 0x1ff00020,
                .flags = IORESOURCE_MEM
        },
        {
@@ -75,8 +88,8 @@ static struct platform_device snirm_82596_rm200_pdev = {
 
 static struct resource snirm_53c710_rm200_rsrc[] = {
        {
-               .start = 0xb9000000,
-               .end   = 0xb90fffff,
+               .start = 0x19000000,
+               .end   = 0x190fffff,
                .flags = IORESOURCE_MEM
        },
        {
@@ -96,6 +109,7 @@ static int __init snirm_setup_devinit(void)
 {
        if (sni_brd_type == SNI_BRD_RM200) {
                platform_device_register(&rm200_serial8250_device);
+               platform_device_register(&rm200_ds1216_device);
                platform_device_register(&snirm_82596_rm200_pdev);
                platform_device_register(&snirm_53c710_rm200_pdev);
        }
@@ -176,11 +190,9 @@ void __init sni_rm200_irq_init(void)
        setup_irq (SNI_RM200_INT_START + 0, &sni_isa_irq);
 }
 
-void sni_rm200_init(void)
+void __init sni_rm200_init(void)
 {
        set_io_port_base(SNI_PORT_BASE + 0x02000000);
        ioport_resource.end += 0x02000000;
-       ds1216_base = (volatile unsigned char *) SNI_DS1216_RM200_BASE;
-       rtc_mips_get_time = ds1216_get_cmos_time;
        board_time_init = sni_cpu_time_init;
 }
index 643366eb854a6de81cfb9abd4a86cd2da5193fe2..00a03a6e8f58a21486f69b80ce8428ad339b1c7d 100644 (file)
@@ -146,7 +146,10 @@ static void __init sni_console_setup(void)
                }
                if (baud)
                        strcpy(options, baud);
-               add_preferred_console("ttyS", port, baud ? options : NULL);
+               if (strncmp (cdev, "tty552", 6) == 0)
+                       add_preferred_console("ttyS", port, baud ? options : NULL);
+               else
+                       add_preferred_console("ttySC", port, baud ? options : NULL);
        }
 }
 
index a0c11efeaeeb9dd24658c114b5c46fa66bf26e70..40c7c3eeafaf2e740fe0e633aa8e82e8135f6123 100644 (file)
@@ -138,7 +138,6 @@ extern void toshiba_rbtx4927_irq_setup(void);
 char *prom_getcmdline(void);
 
 #ifdef CONFIG_PCI
-#define CONFIG_TX4927BUG_WORKAROUND
 #undef TX4927_SUPPORT_COMMAND_IO
 #undef  TX4927_SUPPORT_PCI_66
 int tx4927_cpu_clock = 100000000;      /* 100MHz */
@@ -669,15 +668,7 @@ void tx4927_pci_setup(void)
 
        /* PCI->GB mappings (MEM 16MB) -not used */
        tx4927_pcicptr->p2gm1plbase = 0xffffffff;
-#ifdef CONFIG_TX4927BUG_WORKAROUND
-       /*
-        * TX4927-PCIC-BUG: P2GM1PUBASE must be 0
-        * if P2GM0PUBASE was 0.
-        */
-       tx4927_pcicptr->p2gm1pubase = 0;
-#else
        tx4927_pcicptr->p2gm1pubase = 0xffffffff;
-#endif
        tx4927_pcicptr->p2gmgbase[1] = 0;
 
        /* PCI->GB mappings (MEM 1MB) -not used */
@@ -910,16 +901,6 @@ void __init toshiba_rbtx4927_setup(void)
        if (tx4927_ccfg_toeon)
                tx4927_ccfgptr->ccfg |= TX4927_CCFG_TOE;
 
-       /* SDRAMC fixup */
-#ifdef CONFIG_TX4927BUG_WORKAROUND
-       /*
-        * TX4927-BUG: INF 01-01-18/ BUG 01-01-22
-        * G-bus timeout error detection is incorrect
-        */
-       if (tx4927_ccfg_toeon)
-               tx4927_sdramcptr->tr |= 0x02000000;     /* RCD:3tck */
-#endif
-
        tx4927_pci_setup();
        if (tx4927_using_backplane == 1)
                printk("backplane board IS installed\n");
index 2033ae77f6321c305489294d7a4aba939e4a835d..83cda518f20401e0295fe83c70c5a9b2d495475c 100644 (file)
@@ -6,6 +6,6 @@
 # unless it's something special (ie not a .c file).
 #
 
-obj-y  += prom.o setup.o irq.o rtc_rx5c348.o
+obj-y  += prom.o setup.o irq.o
 obj-$(CONFIG_KGDB) += dbgio.o
 
diff --git a/arch/mips/tx4938/common/rtc_rx5c348.c b/arch/mips/tx4938/common/rtc_rx5c348.c
deleted file mode 100644 (file)
index 07f782f..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * RTC routines for RICOH Rx5C348 SPI chip.
- * Copyright (C) 2000-2001 Toshiba Corporation
- *
- * 2003-2005 (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.
- *
- * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/rtc.h>
-#include <linux/time.h>
-#include <linux/bcd.h>
-#include <asm/time.h>
-#include <asm/tx4938/spi.h>
-
-#define        EPOCH           2000
-
-/* registers */
-#define Rx5C348_REG_SECOND     0
-#define Rx5C348_REG_MINUTE     1
-#define Rx5C348_REG_HOUR       2
-#define Rx5C348_REG_WEEK       3
-#define Rx5C348_REG_DAY        4
-#define Rx5C348_REG_MONTH      5
-#define Rx5C348_REG_YEAR       6
-#define Rx5C348_REG_ADJUST     7
-#define Rx5C348_REG_ALARM_W_MIN        8
-#define Rx5C348_REG_ALARM_W_HOUR       9
-#define Rx5C348_REG_ALARM_W_WEEK       10
-#define Rx5C348_REG_ALARM_D_MIN        11
-#define Rx5C348_REG_ALARM_D_HOUR       12
-#define Rx5C348_REG_CTL1       14
-#define Rx5C348_REG_CTL2       15
-
-/* register bits */
-#define Rx5C348_BIT_PM 0x20    /* REG_HOUR */
-#define Rx5C348_BIT_Y2K        0x80    /* REG_MONTH */
-#define Rx5C348_BIT_24H        0x20    /* REG_CTL1 */
-#define Rx5C348_BIT_XSTP       0x10    /* REG_CTL2 */
-
-/* commands */
-#define Rx5C348_CMD_W(addr)    (((addr) << 4) | 0x08)  /* single write */
-#define Rx5C348_CMD_R(addr)    (((addr) << 4) | 0x0c)  /* single read */
-#define Rx5C348_CMD_MW(addr)   (((addr) << 4) | 0x00)  /* burst write */
-#define Rx5C348_CMD_MR(addr)   (((addr) << 4) | 0x04)  /* burst read */
-
-static struct spi_dev_desc srtc_dev_desc = {
-       .baud           = 1000000,      /* 1.0Mbps @ Vdd 2.0V */
-       .tcss           = 31,
-       .tcsh           = 1,
-       .tcsr           = 62,
-       /* 31us for Tcss (62us for Tcsr) is required for carry operation) */
-       .byteorder      = 1,            /* MSB-First */
-       .polarity       = 0,            /* High-Active */
-       .phase          = 1,            /* Shift-Then-Sample */
-
-};
-static int srtc_chipid;
-static int srtc_24h;
-
-static inline int
-spi_rtc_io(unsigned char *inbuf, unsigned char *outbuf, unsigned int count)
-{
-       unsigned char *inbufs[1], *outbufs[1];
-       unsigned int incounts[2], outcounts[2];
-       inbufs[0] = inbuf;
-       incounts[0] = count;
-       incounts[1] = 0;
-       outbufs[0] = outbuf;
-       outcounts[0] = count;
-       outcounts[1] = 0;
-       return txx9_spi_io(srtc_chipid, &srtc_dev_desc,
-                          inbufs, incounts, outbufs, outcounts, 0);
-}
-
-/* RTC-dependent code for time.c */
-
-static int
-rtc_rx5c348_set_time(unsigned long t)
-{
-       unsigned char inbuf[8];
-       struct rtc_time tm;
-       u8 year, month, day, hour, minute, second, century;
-
-       /* convert */
-       to_tm(t, &tm);
-
-       year = tm.tm_year % 100;
-       month = tm.tm_mon+1;    /* tm_mon starts from 0 to 11 */
-       day = tm.tm_mday;
-       hour = tm.tm_hour;
-       minute = tm.tm_min;
-       second = tm.tm_sec;
-       century = tm.tm_year / 100;
-
-       inbuf[0] = Rx5C348_CMD_MW(Rx5C348_REG_SECOND);
-       BIN_TO_BCD(second);
-       inbuf[1] = second;
-       BIN_TO_BCD(minute);
-       inbuf[2] = minute;
-
-       if (srtc_24h) {
-               BIN_TO_BCD(hour);
-               inbuf[3] = hour;
-       } else {
-               /* hour 0 is AM12, noon is PM12 */
-               inbuf[3] = 0;
-               if (hour >= 12)
-                       inbuf[3] = Rx5C348_BIT_PM;
-               hour = (hour + 11) % 12 + 1;
-               BIN_TO_BCD(hour);
-               inbuf[3] |= hour;
-       }
-       inbuf[4] = 0;   /* ignore week */
-       BIN_TO_BCD(day);
-       inbuf[5] = day;
-       BIN_TO_BCD(month);
-       inbuf[6] = month;
-       if (century >= 20)
-               inbuf[6] |= Rx5C348_BIT_Y2K;
-       BIN_TO_BCD(year);
-       inbuf[7] = year;
-       /* write in one transfer to avoid data inconsistency */
-       return spi_rtc_io(inbuf, NULL, 8);
-}
-
-static unsigned long
-rtc_rx5c348_get_time(void)
-{
-       unsigned char inbuf[8], outbuf[8];
-       unsigned int year, month, day, hour, minute, second;
-
-       inbuf[0] = Rx5C348_CMD_MR(Rx5C348_REG_SECOND);
-       memset(inbuf + 1, 0, 7);
-       /* read in one transfer to avoid data inconsistency */
-       if (spi_rtc_io(inbuf, outbuf, 8))
-               return 0;
-       second = outbuf[1];
-       BCD_TO_BIN(second);
-       minute = outbuf[2];
-       BCD_TO_BIN(minute);
-       if (srtc_24h) {
-               hour = outbuf[3];
-               BCD_TO_BIN(hour);
-       } else {
-               hour = outbuf[3] & ~Rx5C348_BIT_PM;
-               BCD_TO_BIN(hour);
-               hour %= 12;
-               if (outbuf[3] & Rx5C348_BIT_PM)
-                       hour += 12;
-       }
-       day = outbuf[5];
-       BCD_TO_BIN(day);
-       month = outbuf[6] & ~Rx5C348_BIT_Y2K;
-       BCD_TO_BIN(month);
-       year = outbuf[7];
-       BCD_TO_BIN(year);
-       year += EPOCH;
-
-       return mktime(year, month, day, hour, minute, second);
-}
-
-void __init
-rtc_rx5c348_init(int chipid)
-{
-       unsigned char inbuf[2], outbuf[2];
-       srtc_chipid = chipid;
-       /* turn on RTC if it is not on */
-       inbuf[0] = Rx5C348_CMD_R(Rx5C348_REG_CTL2);
-       inbuf[1] = 0;
-       spi_rtc_io(inbuf, outbuf, 2);
-       if (outbuf[1] & Rx5C348_BIT_XSTP) {
-               inbuf[0] = Rx5C348_CMD_W(Rx5C348_REG_CTL2);
-               inbuf[1] = 0;
-               spi_rtc_io(inbuf, NULL, 2);
-       }
-
-       inbuf[0] = Rx5C348_CMD_R(Rx5C348_REG_CTL1);
-       inbuf[1] = 0;
-       spi_rtc_io(inbuf, outbuf, 2);
-       if (outbuf[1] & Rx5C348_BIT_24H)
-               srtc_24h = 1;
-
-       /* set the function pointers */
-       rtc_mips_get_time = rtc_rx5c348_get_time;
-       rtc_mips_set_time = rtc_rx5c348_set_time;
-}
index 226941279d75946a5657ee61a176d218428967fb..10c94e62bf5be355c9832e76855e473a5f2291b5 100644 (file)
@@ -6,4 +6,4 @@
 # unless it's something special (ie not a .c file).
 #
 
-obj-y  += prom.o setup.o irq.o spi_eeprom.o spi_txx9.o
+obj-y  += prom.o setup.o irq.o spi_eeprom.o
index 2e96dbb248b120f60fe02c7216b2f08e155764d2..91aea7aff515d02a9be23c60dc26542dd9befd54 100644 (file)
@@ -165,8 +165,6 @@ toshiba_rbtx4938_irq_ioc_disable(unsigned int irq)
        TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB);
 }
 
-extern void __init txx9_spi_irqinit(int irc_irq);
-
 void __init arch_init_irq(void)
 {
        extern void tx4938_irq_init(void);
@@ -185,9 +183,5 @@ void __init arch_init_irq(void)
        /* Onboard 10M Ether: High Active */
        TX4938_WR(TX4938_MKA(TX4938_IRC_IRDM0), 0x00000040);
 
-       if (tx4938_ccfgptr->pcfg & TX4938_PCFG_SPI_SEL) {
-               txx9_spi_irqinit(RBTX4938_IRQ_IRC_SPI);
-        }
-
        wbflush();
 }
index f5d1ce739fcc48b6eb1442e1cf87f610a7655066..6ed39a5aea7262b0e9941818234e0b7cfc712771 100644 (file)
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/ioport.h>
-#include <linux/proc_fs.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/console.h>
 #include <linux/pci.h>
 #include <linux/pm.h>
 #include <linux/platform_device.h>
+#include <linux/clk.h>
 
 #include <asm/wbflush.h>
 #include <asm/reboot.h>
@@ -35,6 +35,9 @@
 #include <linux/serial.h>
 #include <linux/serial_core.h>
 #endif
+#include <linux/spi/spi.h>
+#include <asm/tx4938/spi.h>
+#include <asm/gpio.h>
 
 extern void rbtx4938_time_init(void) __init;
 extern char * __init prom_getcmdline(void);
@@ -349,7 +352,7 @@ static struct pci_dev *fake_pci_dev(struct pci_controller *hose,
        static struct pci_dev dev;
        static struct pci_bus bus;
 
-       dev.sysdata = (void *)hose;
+       dev.sysdata = bus.sysdata = hose;
        dev.devfn = devfn;
        bus.number = busnr;
        bus.ops = hose->pci_ops;
@@ -382,8 +385,10 @@ int txboard_pci66_check(struct pci_controller *hose, int top_bus, int current_bu
        printk("PCI: Checking 66MHz capabilities...\n");
 
        for (pci_devfn=devfn_start; pci_devfn<devfn_stop; pci_devfn++) {
-               early_read_config_word(hose, top_bus, current_bus, pci_devfn,
-                                      PCI_VENDOR_ID, &vid);
+               if (early_read_config_word(hose, top_bus, current_bus,
+                                          pci_devfn, PCI_VENDOR_ID,
+                                          &vid) != PCIBIOS_SUCCESSFUL)
+                       continue;
 
                if (vid == 0xffff) continue;
 
@@ -460,7 +465,6 @@ static int __init tx4938_pcibios_init(void)
        int extarb = !(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIXARB);
 
        PCIBIOS_MIN_IO = 0x00001000UL;
-       PCIBIOS_MIN_MEM = 0x01000000UL;
 
        mem_base[0] = txboard_request_phys_region_shrink(&mem_size[0]);
        io_base[0] = txboard_request_phys_region_shrink(&io_size[0]);
@@ -574,82 +578,43 @@ arch_initcall(tx4938_pcibios_init);
 #define        SEEPROM3_CS     1       /* IOC */
 #define        SRTC_CS 2       /* IOC */
 
-static int rbtx4938_spi_cs_func(int chipid, int on)
-{
-       unsigned char bit;
-       switch (chipid) {
-       case RBTX4938_SEEPROM1_CHIPID:
-               if (on)
-                       tx4938_pioptr->dout &= ~(1 << SEEPROM1_CS);
-               else
-                       tx4938_pioptr->dout |= (1 << SEEPROM1_CS);
-               return 0;
-               break;
-       case RBTX4938_SEEPROM2_CHIPID:
-               bit = (1 << SEEPROM2_CS);
-               break;
-       case RBTX4938_SEEPROM3_CHIPID:
-               bit = (1 << SEEPROM3_CS);
-               break;
-       case RBTX4938_SRTC_CHIPID:
-               bit = (1 << SRTC_CS);
-               break;
-       default:
-               return -ENODEV;
-       }
-       /* bit1,2,4 are low active, bit3 is high active */
-       *rbtx4938_spics_ptr =
-               (*rbtx4938_spics_ptr & ~bit) |
-               ((on ? (bit ^ 0x0b) : ~(bit ^ 0x0b)) & bit);
-       return 0;
-}
-
 #ifdef CONFIG_PCI
-extern int spi_eeprom_read(int chipid, int address, unsigned char *buf, int len);
-
-int rbtx4938_get_tx4938_ethaddr(struct pci_dev *dev, unsigned char *addr)
+static int __init rbtx4938_ethaddr_init(void)
 {
-       struct pci_controller *channel = (struct pci_controller *)dev->bus->sysdata;
-       static unsigned char dat[17];
-       static int read_dat = 0;
-       int ch = 0;
+       unsigned char dat[17];
+       unsigned char sum;
+       int i;
 
-       if (channel != &tx4938_pci_controller[1])
-               return -ENODEV;
-       /* TX4938 PCIC1 */
-       switch (PCI_SLOT(dev->devfn)) {
-       case TX4938_PCIC_IDSEL_AD_TO_SLOT(31):
-               ch = 0;
-               break;
-       case TX4938_PCIC_IDSEL_AD_TO_SLOT(30):
-               ch = 1;
-               break;
-       default:
+       /* 0-3: "MAC\0", 4-9:eth0, 10-15:eth1, 16:sum */
+       if (spi_eeprom_read(SEEPROM1_CS, 0, dat, sizeof(dat))) {
+               printk(KERN_ERR "seeprom: read error.\n");
                return -ENODEV;
+       } else {
+               if (strcmp(dat, "MAC") != 0)
+                       printk(KERN_WARNING "seeprom: bad signature.\n");
+               for (i = 0, sum = 0; i < sizeof(dat); i++)
+                       sum += dat[i];
+               if (sum)
+                       printk(KERN_WARNING "seeprom: bad checksum.\n");
        }
-       if (!read_dat) {
-               unsigned char sum;
-               int i;
-               read_dat = 1;
-               /* 0-3: "MAC\0", 4-9:eth0, 10-15:eth1, 16:sum */
-               if (spi_eeprom_read(RBTX4938_SEEPROM1_CHIPID,
-                                   0, dat, sizeof(dat))) {
-                       printk(KERN_ERR "seeprom: read error.\n");
-               } else {
-                       if (strcmp(dat, "MAC") != 0)
-                               printk(KERN_WARNING "seeprom: bad signature.\n");
-                       for (i = 0, sum = 0; i < sizeof(dat); i++)
-                               sum += dat[i];
-                       if (sum)
-                               printk(KERN_WARNING "seeprom: bad checksum.\n");
-               }
+       for (i = 0; i < 2; i++) {
+               unsigned int slot = TX4938_PCIC_IDSEL_AD_TO_SLOT(31 - i);
+               unsigned int id = (1 << 8) | PCI_DEVFN(slot, 0); /* bus 1 */
+               struct platform_device *pdev;
+               if (!(tx4938_ccfgptr->pcfg &
+                     (i ? TX4938_PCFG_ETH1_SEL : TX4938_PCFG_ETH0_SEL)))
+                       continue;
+               pdev = platform_device_alloc("tc35815-mac", id);
+               if (!pdev ||
+                   platform_device_add_data(pdev, &dat[4 + 6 * i], 6) ||
+                   platform_device_add(pdev))
+                       platform_device_put(pdev);
        }
-       memcpy(addr, &dat[4 + 6 * ch], 6);
        return 0;
 }
+device_initcall(rbtx4938_ethaddr_init);
 #endif /* CONFIG_PCI */
 
-extern void __init txx9_spi_init(unsigned long base, int (*cs_func)(int chipid, int on));
 static void __init rbtx4938_spi_setup(void)
 {
        /* set SPI_SEL */
@@ -657,7 +622,6 @@ static void __init rbtx4938_spi_setup(void)
        /* chip selects for SPI devices */
        tx4938_pioptr->dout |= (1 << SEEPROM1_CS);
        tx4938_pioptr->dir |= (1 << SEEPROM1_CS);
-       txx9_spi_init(TX4938_SPI_REG, rbtx4938_spi_cs_func);
 }
 
 static struct resource rbtx4938_fpga_resource;
@@ -896,10 +860,8 @@ void tx4938_report_pcic_status(void)
 /* We use onchip r4k counter or TMR timer as our system wide timer
  * interrupt running at 100HZ. */
 
-extern void __init rtc_rx5c348_init(int chipid);
 void __init rbtx4938_time_init(void)
 {
-       rtc_rx5c348_init(RBTX4938_SRTC_CHIPID);
        mips_hpt_frequency = txx9_cpu_clock / 2;
 }
 
@@ -1016,29 +978,6 @@ void __init toshiba_rbtx4938_setup(void)
               *rbtx4938_dipsw_ptr, *rbtx4938_bdipsw_ptr);
 }
 
-#ifdef CONFIG_PROC_FS
-extern void spi_eeprom_proc_create(struct proc_dir_entry *dir, int chipid);
-static int __init tx4938_spi_proc_setup(void)
-{
-       struct proc_dir_entry *tx4938_spi_eeprom_dir;
-
-       tx4938_spi_eeprom_dir = proc_mkdir("spi_eeprom", 0);
-
-       if (!tx4938_spi_eeprom_dir)
-               return -ENOMEM;
-
-       /* don't allow user access to RBTX4938_SEEPROM1_CHIPID
-        * as it contains eth0 and eth1 MAC addresses
-        */
-       spi_eeprom_proc_create(tx4938_spi_eeprom_dir, RBTX4938_SEEPROM2_CHIPID);
-       spi_eeprom_proc_create(tx4938_spi_eeprom_dir, RBTX4938_SEEPROM3_CHIPID);
-
-       return 0;
-}
-
-__initcall(tx4938_spi_proc_setup);
-#endif
-
 static int __init rbtx4938_ne_init(void)
 {
        struct resource res[] = {
@@ -1057,3 +996,176 @@ static int __init rbtx4938_ne_init(void)
        return IS_ERR(dev) ? PTR_ERR(dev) : 0;
 }
 device_initcall(rbtx4938_ne_init);
+
+/* GPIO support */
+
+static DEFINE_SPINLOCK(rbtx4938_spi_gpio_lock);
+
+static void rbtx4938_spi_gpio_set(unsigned gpio, int value)
+{
+       u8 val;
+       unsigned long flags;
+       gpio -= 16;
+       spin_lock_irqsave(&rbtx4938_spi_gpio_lock, flags);
+       val = *rbtx4938_spics_ptr;
+       if (value)
+               val |= 1 << gpio;
+       else
+               val &= ~(1 << gpio);
+       *rbtx4938_spics_ptr = val;
+       mmiowb();
+       spin_unlock_irqrestore(&rbtx4938_spi_gpio_lock, flags);
+}
+
+static int rbtx4938_spi_gpio_dir_out(unsigned gpio, int value)
+{
+       rbtx4938_spi_gpio_set(gpio, value);
+       return 0;
+}
+
+static DEFINE_SPINLOCK(tx4938_gpio_lock);
+
+static int tx4938_gpio_get(unsigned gpio)
+{
+       return tx4938_pioptr->din & (1 << gpio);
+}
+
+static void tx4938_gpio_set_raw(unsigned gpio, int value)
+{
+       u32 val;
+       val = tx4938_pioptr->dout;
+       if (value)
+               val |= 1 << gpio;
+       else
+               val &= ~(1 << gpio);
+       tx4938_pioptr->dout = val;
+}
+
+static void tx4938_gpio_set(unsigned gpio, int value)
+{
+       unsigned long flags;
+       spin_lock_irqsave(&tx4938_gpio_lock, flags);
+       tx4938_gpio_set_raw(gpio, value);
+       mmiowb();
+       spin_unlock_irqrestore(&tx4938_gpio_lock, flags);
+}
+
+static int tx4938_gpio_dir_in(unsigned gpio)
+{
+       spin_lock_irq(&tx4938_gpio_lock);
+       tx4938_pioptr->dir &= ~(1 << gpio);
+       mmiowb();
+       spin_unlock_irq(&tx4938_gpio_lock);
+       return 0;
+}
+
+static int tx4938_gpio_dir_out(unsigned int gpio, int value)
+{
+       spin_lock_irq(&tx4938_gpio_lock);
+       tx4938_gpio_set_raw(gpio, value);
+       tx4938_pioptr->dir |= 1 << gpio;
+       mmiowb();
+       spin_unlock_irq(&tx4938_gpio_lock);
+       return 0;
+}
+
+int gpio_direction_input(unsigned gpio)
+{
+       if (gpio < 16)
+               return tx4938_gpio_dir_in(gpio);
+       return -EINVAL;
+}
+
+int gpio_direction_output(unsigned gpio, int value)
+{
+       if (gpio < 16)
+               return tx4938_gpio_dir_out(gpio, value);
+       if (gpio < 16 + 3)
+               return rbtx4938_spi_gpio_dir_out(gpio, value);
+       return -EINVAL;
+}
+
+int gpio_get_value(unsigned gpio)
+{
+       if (gpio < 16)
+               return tx4938_gpio_get(gpio);
+       return 0;
+}
+
+void gpio_set_value(unsigned gpio, int value)
+{
+       if (gpio < 16)
+               tx4938_gpio_set(gpio, value);
+       else
+               rbtx4938_spi_gpio_set(gpio, value);
+}
+
+/* SPI support */
+
+static void __init txx9_spi_init(unsigned long base, int irq)
+{
+       struct resource res[] = {
+               {
+                       .start  = base,
+                       .end    = base + 0x20 - 1,
+                       .flags  = IORESOURCE_MEM,
+                       .parent = &tx4938_reg_resource,
+               }, {
+                       .start  = irq,
+                       .flags  = IORESOURCE_IRQ,
+               },
+       };
+       platform_device_register_simple("txx9spi", 0,
+                                       res, ARRAY_SIZE(res));
+}
+
+static int __init rbtx4938_spi_init(void)
+{
+       struct spi_board_info srtc_info = {
+               .modalias = "rs5c348",
+               .max_speed_hz = 1000000, /* 1.0Mbps @ Vdd 2.0V */
+               .bus_num = 0,
+               .chip_select = 16 + SRTC_CS,
+               /* Mode 1 (High-Active, Shift-Then-Sample), High Avtive CS  */
+               .mode = SPI_MODE_1 | SPI_CS_HIGH,
+       };
+       spi_register_board_info(&srtc_info, 1);
+       spi_eeprom_register(SEEPROM1_CS);
+       spi_eeprom_register(16 + SEEPROM2_CS);
+       spi_eeprom_register(16 + SEEPROM3_CS);
+       txx9_spi_init(TX4938_SPI_REG & 0xfffffffffULL, RBTX4938_IRQ_IRC_SPI);
+       return 0;
+}
+arch_initcall(rbtx4938_spi_init);
+
+/* Minimum CLK support */
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+       if (!strcmp(id, "spi-baseclk"))
+               return (struct clk *)(txx9_gbus_clock / 2 / 4);
+       return ERR_PTR(-ENOENT);
+}
+EXPORT_SYMBOL(clk_get);
+
+int clk_enable(struct clk *clk)
+{
+       return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+       return (unsigned long)clk;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+void clk_put(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_put);
index 89596e62f9096cf5f9313c6d87e121bc58afaa5c..4d6b4ade5e8cd208ffcbde8df3583c9b09556f7c 100644 (file)
  * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
  */
 #include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/proc_fs.h>
-#include <linux/spinlock.h>
+#include <linux/device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/eeprom.h>
 #include <asm/tx4938/spi.h>
-#include <asm/tx4938/tx4938.h>
 
-/* ATMEL 250x0 instructions */
-#define        ATMEL_WREN      0x06
-#define        ATMEL_WRDI      0x04
-#define ATMEL_RDSR     0x05
-#define ATMEL_WRSR     0x01
-#define        ATMEL_READ      0x03
-#define        ATMEL_WRITE     0x02
+#define AT250X0_PAGE_SIZE      8
 
-#define ATMEL_SR_BSY   0x01
-#define ATMEL_SR_WEN   0x02
-#define ATMEL_SR_BP0   0x04
-#define ATMEL_SR_BP1   0x08
-
-DEFINE_SPINLOCK(spi_eeprom_lock);
-
-static struct spi_dev_desc seeprom_dev_desc = {
-       .baud           = 1500000,      /* 1.5Mbps */
-       .tcss           = 1,
-       .tcsh           = 1,
-       .tcsr           = 1,
-       .byteorder      = 1,            /* MSB-First */
-       .polarity       = 0,            /* High-Active */
-       .phase          = 0,            /* Sample-Then-Shift */
-
-};
-static inline int
-spi_eeprom_io(int chipid,
-             unsigned char **inbufs, unsigned int *incounts,
-             unsigned char **outbufs, unsigned int *outcounts)
-{
-       return txx9_spi_io(chipid, &seeprom_dev_desc,
-                          inbufs, incounts, outbufs, outcounts, 0);
-}
-
-int spi_eeprom_write_enable(int chipid, int enable)
+/* register board information for at25 driver */
+int __init spi_eeprom_register(int chipid)
 {
-       unsigned char inbuf[1];
-       unsigned char *inbufs[1];
-       unsigned int incounts[2];
-       unsigned long flags;
-       int stat;
-       inbuf[0] = enable ? ATMEL_WREN : ATMEL_WRDI;
-       inbufs[0] = inbuf;
-       incounts[0] = sizeof(inbuf);
-       incounts[1] = 0;
-       spin_lock_irqsave(&spi_eeprom_lock, flags);
-       stat = spi_eeprom_io(chipid, inbufs, incounts, NULL, NULL);
-       spin_unlock_irqrestore(&spi_eeprom_lock, flags);
-       return stat;
-}
-
-static int spi_eeprom_read_status_nolock(int chipid)
-{
-       unsigned char inbuf[2], outbuf[2];
-       unsigned char *inbufs[1], *outbufs[1];
-       unsigned int incounts[2], outcounts[2];
-       int stat;
-       inbuf[0] = ATMEL_RDSR;
-       inbuf[1] = 0;
-       inbufs[0] = inbuf;
-       incounts[0] = sizeof(inbuf);
-       incounts[1] = 0;
-       outbufs[0] = outbuf;
-       outcounts[0] = sizeof(outbuf);
-       outcounts[1] = 0;
-       stat = spi_eeprom_io(chipid, inbufs, incounts, outbufs, outcounts);
-       if (stat < 0)
-               return stat;
-       return outbuf[1];
+       static struct spi_eeprom eeprom = {
+               .name = "at250x0",
+               .byte_len = 128,
+               .page_size = AT250X0_PAGE_SIZE,
+               .flags = EE_ADDR1,
+       };
+       struct spi_board_info info = {
+               .modalias = "at25",
+               .max_speed_hz = 1500000,        /* 1.5Mbps */
+               .bus_num = 0,
+               .chip_select = chipid,
+               .platform_data = &eeprom,
+               /* Mode 0: High-Active, Sample-Then-Shift */
+       };
+
+       return spi_register_board_info(&info, 1);
 }
 
-int spi_eeprom_read_status(int chipid)
-{
-       unsigned long flags;
-       int stat;
-       spin_lock_irqsave(&spi_eeprom_lock, flags);
-       stat = spi_eeprom_read_status_nolock(chipid);
-       spin_unlock_irqrestore(&spi_eeprom_lock, flags);
-       return stat;
-}
+/* simple temporary spi driver to provide early access to seeprom. */
 
-int spi_eeprom_read(int chipid, int address, unsigned char *buf, int len)
-{
-       unsigned char inbuf[2];
-       unsigned char *inbufs[2], *outbufs[2];
-       unsigned int incounts[2], outcounts[3];
-       unsigned long flags;
-       int stat;
-       inbuf[0] = ATMEL_READ;
-       inbuf[1] = address;
-       inbufs[0] = inbuf;
-       inbufs[1] = NULL;
-       incounts[0] = sizeof(inbuf);
-       incounts[1] = 0;
-       outbufs[0] = NULL;
-       outbufs[1] = buf;
-       outcounts[0] = 2;
-       outcounts[1] = len;
-       outcounts[2] = 0;
-       spin_lock_irqsave(&spi_eeprom_lock, flags);
-       stat = spi_eeprom_io(chipid, inbufs, incounts, outbufs, outcounts);
-       spin_unlock_irqrestore(&spi_eeprom_lock, flags);
-       return stat;
-}
+static struct read_param {
+       int chipid;
+       int address;
+       unsigned char *buf;
+       int len;
+} *read_param;
 
-int spi_eeprom_write(int chipid, int address, unsigned char *buf, int len)
+static int __init early_seeprom_probe(struct spi_device *spi)
 {
-       unsigned char inbuf[2];
-       unsigned char *inbufs[2];
-       unsigned int incounts[3];
-       unsigned long flags;
-       int i, stat;
-
-       if (address / 8 != (address + len - 1) / 8)
-               return -EINVAL;
-       stat = spi_eeprom_write_enable(chipid, 1);
-       if (stat < 0)
-               return stat;
-       stat = spi_eeprom_read_status(chipid);
-       if (stat < 0)
-               return stat;
-       if (!(stat & ATMEL_SR_WEN))
-               return -EPERM;
-
-       inbuf[0] = ATMEL_WRITE;
-       inbuf[1] = address;
-       inbufs[0] = inbuf;
-       inbufs[1] = buf;
-       incounts[0] = sizeof(inbuf);
-       incounts[1] = len;
-       incounts[2] = 0;
-       spin_lock_irqsave(&spi_eeprom_lock, flags);
-       stat = spi_eeprom_io(chipid, inbufs, incounts, NULL, NULL);
-       if (stat < 0)
-               goto unlock_return;
-
-       /* write start.  max 10ms */
-       for (i = 10; i > 0; i--) {
-               int stat = spi_eeprom_read_status_nolock(chipid);
-               if (stat < 0)
-                       goto unlock_return;
-               if (!(stat & ATMEL_SR_BSY))
-                       break;
-               mdelay(1);
+       int stat = 0;
+       u8 cmd[2];
+       int len = read_param->len;
+       char *buf = read_param->buf;
+       int address = read_param->address;
+
+       dev_info(&spi->dev, "spiclk %u KHz.\n",
+                (spi->max_speed_hz + 500) / 1000);
+       if (read_param->chipid != spi->chip_select)
+               return -ENODEV;
+       while (len > 0) {
+               /* spi_write_then_read can only work with small chunk */
+               int c = len < AT250X0_PAGE_SIZE ? len : AT250X0_PAGE_SIZE;
+               cmd[0] = 0x03;  /* AT25_READ */
+               cmd[1] = address;
+               stat = spi_write_then_read(spi, cmd, sizeof(cmd), buf, c);
+               buf += c;
+               len -= c;
+               address += c;
        }
-       spin_unlock_irqrestore(&spi_eeprom_lock, flags);
-       if (i == 0)
-               return -EIO;
-       return len;
- unlock_return:
-       spin_unlock_irqrestore(&spi_eeprom_lock, flags);
        return stat;
 }
 
-#ifdef CONFIG_PROC_FS
-#define MAX_SIZE       0x80    /* for ATMEL 25010 */
-static int spi_eeprom_read_proc(char *page, char **start, off_t off,
-                               int count, int *eof, void *data)
-{
-       unsigned int size = MAX_SIZE;
-       if (spi_eeprom_read((int)data, 0, (unsigned char *)page, size) < 0)
-               size = 0;
-       return size;
-}
-
-static int spi_eeprom_write_proc(struct file *file, const char *buffer,
-                                unsigned long count, void *data)
-{
-       unsigned int size = MAX_SIZE;
-       int i;
-       if (file->f_pos >= size)
-               return -EIO;
-       if (file->f_pos + count > size)
-               count = size - file->f_pos;
-       for (i = 0; i < count; i += 8) {
-               int len = count - i < 8 ? count - i : 8;
-               if (spi_eeprom_write((int)data, file->f_pos,
-                                    (unsigned char *)buffer, len) < 0) {
-                       count = -EIO;
-                       break;
-               }
-               buffer += len;
-               file->f_pos += len;
-       }
-       return count;
-}
+static struct spi_driver early_seeprom_driver __initdata = {
+       .driver = {
+               .name   = "at25",
+               .owner  = THIS_MODULE,
+       },
+       .probe  = early_seeprom_probe,
+};
 
-__init void spi_eeprom_proc_create(struct proc_dir_entry *dir, int chipid)
+int __init spi_eeprom_read(int chipid, int address,
+                          unsigned char *buf, int len)
 {
-       struct proc_dir_entry *entry;
-       char name[128];
-       sprintf(name, "seeprom-%d", chipid);
-       entry = create_proc_entry(name, 0600, dir);
-       if (entry) {
-               entry->read_proc = spi_eeprom_read_proc;
-               entry->write_proc = spi_eeprom_write_proc;
-               entry->data = (void *)chipid;
-       }
+       int ret;
+       struct read_param param = {
+               .chipid = chipid,
+               .address = address,
+               .buf = buf,
+               .len = len
+       };
+
+       read_param = &param;
+       ret = spi_register_driver(&early_seeprom_driver);
+       if (!ret)
+               spi_unregister_driver(&early_seeprom_driver);
+       return ret;
 }
-#endif /* CONFIG_PROC_FS */
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c b/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c
deleted file mode 100644 (file)
index 08b20cd..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * linux/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c
- * Copyright (C) 2000-2001 Toshiba Corporation
- *
- * 2003-2005 (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.
- *
- * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
- */
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/wait.h>
-#include <asm/tx4938/spi.h>
-#include <asm/tx4938/tx4938.h>
-
-static int (*txx9_spi_cs_func)(int chipid, int on);
-static DEFINE_SPINLOCK(txx9_spi_lock);
-
-extern unsigned int txx9_gbus_clock;
-
-#define SPI_FIFO_SIZE  4
-
-void __init txx9_spi_init(unsigned long base, int (*cs_func)(int chipid, int on))
-{
-       txx9_spi_cs_func = cs_func;
-       /* enter config mode */
-       tx4938_spiptr->mcr = TXx9_SPMCR_CONFIG | TXx9_SPMCR_BCLR;
-}
-
-static DECLARE_WAIT_QUEUE_HEAD(txx9_spi_wait);
-
-static irqreturn_t txx9_spi_interrupt(int irq, void *dev_id)
-{
-       /* disable rx intr */
-       tx4938_spiptr->cr0 &= ~TXx9_SPCR0_RBSIE;
-       wake_up(&txx9_spi_wait);
-
-       return IRQ_HANDLED;
-}
-
-static struct irqaction txx9_spi_action = {
-       .handler        = txx9_spi_interrupt,
-       .name           = "spi",
-};
-
-void __init txx9_spi_irqinit(int irc_irq)
-{
-       setup_irq(irc_irq, &txx9_spi_action);
-}
-
-int txx9_spi_io(int chipid, struct spi_dev_desc *desc,
-               unsigned char **inbufs, unsigned int *incounts,
-               unsigned char **outbufs, unsigned int *outcounts,
-               int cansleep)
-{
-       unsigned int incount, outcount;
-       unsigned char *inp, *outp;
-       int ret;
-       unsigned long flags;
-
-       spin_lock_irqsave(&txx9_spi_lock, flags);
-       if ((tx4938_spiptr->mcr & TXx9_SPMCR_OPMODE) == TXx9_SPMCR_ACTIVE) {
-               spin_unlock_irqrestore(&txx9_spi_lock, flags);
-               return -EBUSY;
-       }
-       /* enter config mode */
-       tx4938_spiptr->mcr = TXx9_SPMCR_CONFIG | TXx9_SPMCR_BCLR;
-       tx4938_spiptr->cr0 =
-               (desc->byteorder ? TXx9_SPCR0_SBOS : 0) |
-               (desc->polarity ? TXx9_SPCR0_SPOL : 0) |
-               (desc->phase ? TXx9_SPCR0_SPHA : 0) |
-               0x08;
-       tx4938_spiptr->cr1 =
-               (((TXX9_IMCLK + desc->baud) / (2 * desc->baud) - 1) << 8) |
-               0x08 /* 8 bit only */;
-       /* enter active mode */
-       tx4938_spiptr->mcr = TXx9_SPMCR_ACTIVE;
-       spin_unlock_irqrestore(&txx9_spi_lock, flags);
-
-       /* CS ON */
-       if ((ret = txx9_spi_cs_func(chipid, 1)) < 0) {
-               spin_unlock_irqrestore(&txx9_spi_lock, flags);
-               return ret;
-       }
-       udelay(desc->tcss);
-
-       /* do scatter IO */
-       inp = inbufs ? *inbufs : NULL;
-       outp = outbufs ? *outbufs : NULL;
-       incount = 0;
-       outcount = 0;
-       while (1) {
-               unsigned char data;
-               unsigned int count;
-               int i;
-               if (!incount) {
-                       incount = incounts ? *incounts++ : 0;
-                       inp = (incount && inbufs) ? *inbufs++ : NULL;
-               }
-               if (!outcount) {
-                       outcount = outcounts ? *outcounts++ : 0;
-                       outp = (outcount && outbufs) ? *outbufs++ : NULL;
-               }
-               if (!inp && !outp)
-                       break;
-               count = SPI_FIFO_SIZE;
-               if (incount)
-                       count = min(count, incount);
-               if (outcount)
-                       count = min(count, outcount);
-
-               /* now tx must be idle... */
-               while (!(tx4938_spiptr->sr & TXx9_SPSR_SIDLE))
-                       ;
-
-               tx4938_spiptr->cr0 =
-                       (tx4938_spiptr->cr0 & ~TXx9_SPCR0_RXIFL_MASK) |
-                       ((count - 1) << 12);
-               if (cansleep) {
-                       /* enable rx intr */
-                       tx4938_spiptr->cr0 |= TXx9_SPCR0_RBSIE;
-               }
-               /* send */
-               for (i = 0; i < count; i++)
-                       tx4938_spiptr->dr = inp ? *inp++ : 0;
-               /* wait all rx data */
-               if (cansleep) {
-                       wait_event(txx9_spi_wait,
-                                  tx4938_spiptr->sr & TXx9_SPSR_SRRDY);
-               } else {
-                       while (!(tx4938_spiptr->sr & TXx9_SPSR_RBSI))
-                               ;
-               }
-               /* receive */
-               for (i = 0; i < count; i++) {
-                       data = tx4938_spiptr->dr;
-                       if (outp)
-                               *outp++ = data;
-               }
-               if (incount)
-                       incount -= count;
-               if (outcount)
-                       outcount -= count;
-       }
-
-       /* CS OFF */
-       udelay(desc->tcsh);
-       txx9_spi_cs_func(chipid, 0);
-       udelay(desc->tcsr);
-
-       spin_lock_irqsave(&txx9_spi_lock, flags);
-       /* enter config mode */
-       tx4938_spiptr->mcr = TXx9_SPMCR_CONFIG | TXx9_SPMCR_BCLR;
-       spin_unlock_irqrestore(&txx9_spi_lock, flags);
-
-       return 0;
-}
index f842783acd863bc4cdc300bddad3921eb3fd16ab..d0d84ec8d63de98428e612484b651a3c2211e554 100644 (file)
@@ -2,4 +2,4 @@
 # Makefile for common code of the NEC VR4100 series.
 #
 
-obj-y  += bcu.o cmu.o icu.o init.o irq.o pmu.o type.o
+obj-y  += bcu.o cmu.o giu.o icu.o init.o irq.o pmu.o rtc.o siu.o type.o
diff --git a/arch/mips/vr41xx/common/giu.c b/arch/mips/vr41xx/common/giu.c
new file mode 100644 (file)
index 0000000..d21f6f2
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ *  NEC VR4100 series GIU platform device.
+ *
+ *  Copyright (C) 2007  Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You 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/errno.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+
+#include <asm/cpu.h>
+#include <asm/vr41xx/giu.h>
+#include <asm/vr41xx/irq.h>
+
+static struct resource giu_50pins_pullupdown_resource[] __initdata = {
+       {
+               .start  = 0x0b000100,
+               .end    = 0x0b00011f,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .start  = 0x0b0002e0,
+               .end    = 0x0b0002e3,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .start  = GIUINT_IRQ,
+               .end    = GIUINT_IRQ,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct resource giu_36pins_resource[] __initdata = {
+       {
+               .start  = 0x0f000140,
+               .end    = 0x0f00015f,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .start  = GIUINT_IRQ,
+               .end    = GIUINT_IRQ,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct resource giu_48pins_resource[] __initdata = {
+       {
+               .start  = 0x0f000140,
+               .end    = 0x0f000167,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .start  = GIUINT_IRQ,
+               .end    = GIUINT_IRQ,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static int __init vr41xx_giu_add(void)
+{
+       struct platform_device *pdev;
+       struct resource *res;
+       unsigned int num;
+       int retval;
+
+       pdev = platform_device_alloc("GIU", -1);
+       if (!pdev)
+               return -ENOMEM;
+
+       switch (current_cpu_data.cputype) {
+       case CPU_VR4111:
+       case CPU_VR4121:
+               pdev->id = GPIO_50PINS_PULLUPDOWN;
+               res = giu_50pins_pullupdown_resource;
+               num = ARRAY_SIZE(giu_50pins_pullupdown_resource);
+               break;
+       case CPU_VR4122:
+       case CPU_VR4131:
+               pdev->id = GPIO_36PINS;
+               res = giu_36pins_resource;
+               num = ARRAY_SIZE(giu_36pins_resource);
+               break;
+       case CPU_VR4133:
+               pdev->id = GPIO_48PINS_EDGE_SELECT;
+               res = giu_48pins_resource;
+               num = ARRAY_SIZE(giu_48pins_resource);
+               break;
+       default:
+               retval = -ENODEV;
+               goto err_free_device;
+       }
+
+       retval = platform_device_add_resources(pdev, res, num);
+       if (retval)
+               goto err_free_device;
+
+       retval = platform_device_add(pdev);
+       if (retval)
+               goto err_free_device;
+
+       return 0;
+
+err_free_device:
+       platform_device_put(pdev);
+
+       return retval;
+}
+device_initcall(vr41xx_giu_add);
diff --git a/arch/mips/vr41xx/common/rtc.c b/arch/mips/vr41xx/common/rtc.c
new file mode 100644 (file)
index 0000000..cce605b
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ *  NEC VR4100 series RTC platform device.
+ *
+ *  Copyright (C) 2007  Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You 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/errno.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+
+#include <asm/cpu.h>
+#include <asm/vr41xx/irq.h>
+
+static struct resource rtc_type1_resource[] __initdata = {
+       {
+               .start  = 0x0b0000c0,
+               .end    = 0x0b0000df,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .start  = 0x0b0001c0,
+               .end    = 0x0b0001df,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .start  = ELAPSEDTIME_IRQ,
+               .end    = ELAPSEDTIME_IRQ,
+               .flags  = IORESOURCE_IRQ,
+       },
+       {
+               .start  = RTCLONG1_IRQ,
+               .end    = RTCLONG1_IRQ,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct resource rtc_type2_resource[] __initdata = {
+       {
+               .start  = 0x0f000100,
+               .end    = 0x0f00011f,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .start  = 0x0f000120,
+               .end    = 0x0f00013f,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .start  = ELAPSEDTIME_IRQ,
+               .end    = ELAPSEDTIME_IRQ,
+               .flags  = IORESOURCE_IRQ,
+       },
+       {
+               .start  = RTCLONG1_IRQ,
+               .end    = RTCLONG1_IRQ,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static int __init vr41xx_rtc_add(void)
+{
+       struct platform_device *pdev;
+       struct resource *res;
+       unsigned int num;
+       int retval;
+
+       pdev = platform_device_alloc("RTC", -1);
+       if (!pdev)
+               return -ENOMEM;
+
+       switch (current_cpu_data.cputype) {
+       case CPU_VR4111:
+       case CPU_VR4121:
+               res = rtc_type1_resource;
+               num = ARRAY_SIZE(rtc_type1_resource);
+               break;
+       case CPU_VR4122:
+       case CPU_VR4131:
+       case CPU_VR4133:
+               res = rtc_type2_resource;
+               num = ARRAY_SIZE(rtc_type2_resource);
+               break;
+       default:
+               retval = -ENODEV;
+               goto err_free_device;
+       }
+
+       retval = platform_device_add_resources(pdev, res, num);
+       if (retval)
+               goto err_free_device;
+
+       retval = platform_device_add(pdev);
+       if (retval)
+               goto err_free_device;
+
+       return 0;
+
+err_free_device:
+       platform_device_put(pdev);
+
+       return retval;
+}
+device_initcall(vr41xx_rtc_add);
diff --git a/arch/mips/vr41xx/common/siu.c b/arch/mips/vr41xx/common/siu.c
new file mode 100644 (file)
index 0000000..a1e7741
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ *  NEC VR4100 series SIU platform device.
+ *
+ *  Copyright (C) 2007  Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You 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/errno.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+
+#include <asm/cpu.h>
+#include <asm/vr41xx/siu.h>
+
+static unsigned int siu_type1_ports[SIU_PORTS_MAX] __initdata = {
+       PORT_VR41XX_SIU,
+       PORT_UNKNOWN,
+};
+
+static struct resource siu_type1_resource[] __initdata = {
+       {
+               .start  = 0x0c000000,
+               .end    = 0x0c00000a,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .start  = SIU_IRQ,
+               .end    = SIU_IRQ,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static unsigned int siu_type2_ports[SIU_PORTS_MAX] __initdata = {
+       PORT_VR41XX_SIU,
+       PORT_VR41XX_DSIU,
+};
+
+static struct resource siu_type2_resource[] __initdata = {
+       {
+               .start  = 0x0f000800,
+               .end    = 0x0f00080a,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .start  = 0x0f000820,
+               .end    = 0x0f000829,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .start  = SIU_IRQ,
+               .end    = SIU_IRQ,
+               .flags  = IORESOURCE_IRQ,
+       },
+       {
+               .start  = DSIU_IRQ,
+               .end    = DSIU_IRQ,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static int __init vr41xx_siu_add(void)
+{
+       struct platform_device *pdev;
+       struct resource *res;
+       unsigned int num;
+       int retval;
+
+       pdev = platform_device_alloc("SIU", -1);
+       if (!pdev)
+               return -ENOMEM;
+
+       switch (current_cpu_data.cputype) {
+       case CPU_VR4111:
+       case CPU_VR4121:
+               pdev->dev.platform_data = siu_type1_ports;
+               res = siu_type1_resource;
+               num = ARRAY_SIZE(siu_type1_resource);
+               break;
+       case CPU_VR4122:
+       case CPU_VR4131:
+       case CPU_VR4133:
+               pdev->dev.platform_data = siu_type2_ports;
+               res = siu_type2_resource;
+               num = ARRAY_SIZE(siu_type2_resource);
+               break;
+       default:
+               retval = -ENODEV;
+               goto err_free_device;
+       }
+
+       retval = platform_device_add_resources(pdev, res, num);
+       if (retval)
+               goto err_free_device;
+
+       retval = platform_device_add(pdev);
+       if (retval)
+               goto err_free_device;
+
+       return 0;
+
+err_free_device:
+       platform_device_put(pdev);
+
+       return retval;
+}
+device_initcall(vr41xx_siu_add);
index 5eaeafd30bdfe2710b7e35f325fee9692b751d44..6beee32144c02e45456c5e8c037e8630b1b6f7bb 100644 (file)
@@ -698,8 +698,10 @@ config PCI
          infrastructure code to support PCI bus devices.
 
 config PCI_DOMAINS
-       bool
-       default PCI
+       def_bool PCI
+
+config PCI_SYSCALL
+       def_bool PCI
 
 config PCI_QSPAN
        bool "QSpan PCI"
index e66064b5093a2496ad2e03e9ebd1212ba98ad72b..86982112b0ddb7e39c301aa1ee30202b12b88bbf 100644 (file)
@@ -1047,10 +1047,10 @@ void pcibios_make_OF_bus_map(void)
 #endif /* CONFIG_PPC_OF */
 
 /* Add sysfs properties */
-void pcibios_add_platform_entries(struct pci_dev *pdev)
+int pcibios_add_platform_entries(struct pci_dev *pdev)
 {
 #ifdef CONFIG_PPC_OF
-       device_create_file(&pdev->dev, &dev_attr_devspec);
+       return device_create_file(&pdev->dev, &dev_attr_devspec);
 #endif /* CONFIG_PPC_OF */
 }
 
index 249cca27a9b84ade58c94020534a8aa8a018ee83..e3009a43ac56ed117b553fab9f071593142205bb 100644 (file)
@@ -367,8 +367,10 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
        sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus),
                dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));
        dev->class = get_int_prop(node, "class-code", 0);
+       dev->revision = get_int_prop(node, "revision-id", 0);
 
        DBG("    class: 0x%x\n", dev->class);
+       DBG("    revision: 0x%x\n", dev->revision);
 
        dev->current_state = 4;         /* unknown power state */
        dev->error_state = pci_channel_io_normal;
@@ -876,9 +878,9 @@ static ssize_t pci_show_devspec(struct device *dev,
 }
 static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL);
 
-void pcibios_add_platform_entries(struct pci_dev *pdev)
+int pcibios_add_platform_entries(struct pci_dev *pdev)
 {
-       device_create_file(&pdev->dev, &dev_attr_devspec);
+       return device_create_file(&pdev->dev, &dev_attr_devspec);
 }
 
 #define ISA_SPACE_MASK 0x1
index 4c0a7d732f699113cb9baddf44b37f675d61b794..615b6583d9b01084831bd8eea5ed00aecf9ab30b 100644 (file)
@@ -477,9 +477,9 @@ for (;;) {
                }
                else {
                        skb_put(skb,pkt_len-4); /* Make room */
-                       eth_copy_and_sum(skb,
+                       skb_copy_to_linear_data(skb,
                                (unsigned char *)__va(bdp->cbd_bufaddr),
-                               pkt_len-4, 0);
+                               pkt_len-4);
                        skb->protocol=eth_type_trans(skb,dev);
                        netif_rx(skb);
                }
index cab395da25da533f8947739cf37473f5d4433e0c..6f3ed6a72e0be3a2c895485824ff8c8ec842e54f 100644 (file)
@@ -734,9 +734,9 @@ for (;;) {
                }
                else {
                        skb_put(skb,pkt_len);   /* Make room */
-                       eth_copy_and_sum(skb,
+                       skb_copy_to_linear_data(skb,
                                (unsigned char *)__va(bdp->cbd_bufaddr),
-                               pkt_len, 0);
+                               pkt_len);
                        skb->protocol=eth_type_trans(skb,dev);
                        netif_rx(skb);
                }
index e58288e143698c17657cc7521bc0f754dbc33a02..703d47eee4362206e308f57f5d02015a3d0a7464 100644 (file)
@@ -506,9 +506,9 @@ for (;;) {
                }
                else {
                        skb_put(skb,pkt_len-4); /* Make room */
-                       eth_copy_and_sum(skb,
+                       skb_copy_to_linear_data(skb,
                                cep->rx_vaddr[bdp - cep->rx_bd_base],
-                               pkt_len-4, 0);
+                               pkt_len-4);
                        skb->protocol=eth_type_trans(skb,dev);
                        netif_rx(skb);
                }
index d38335d2d710d3d2344d6a154eba7471aaed3ed6..0288279be9aad8d22ff1a7406eca2a67781833ec 100644 (file)
@@ -725,7 +725,7 @@ while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) {
                fep->stats.rx_dropped++;
        } else {
                skb_put(skb,pkt_len-4); /* Make room */
-               eth_copy_and_sum(skb, data, pkt_len-4, 0);
+               skb_copy_to_linear_data(skb, data, pkt_len-4);
                skb->protocol=eth_type_trans(skb,dev);
                netif_rx(skb);
        }
index ccce2a4a1522f574b49dacf261108a4b43068f09..6bdeeb70b157856a00b6ce22c397a74abeb0d803 100644 (file)
@@ -1237,8 +1237,10 @@ config PCI
          infrastructure code to support PCI bus devices.
 
 config PCI_DOMAINS
-       bool
-       default PCI
+       def_bool PCI
+
+config PCI_SYSCALL
+       def_bool PCI
 
 config MPC83xx_PCI2
        bool "Support for 2nd PCI host controller"
index 5e723c4c2571b0a3dc886032a92681a9927b9d7c..c2ec13bea006aa5e9c63c0683808a2e68d0f8c44 100644 (file)
@@ -633,12 +633,6 @@ void pcibios_make_OF_bus_map(void)
 {
 }
 
-/* Add sysfs properties */
-void pcibios_add_platform_entries(struct pci_dev *pdev)
-{
-}
-
-
 static int __init
 pcibios_init(void)
 {
index 8485a68cd4753ade53df7dcce6771b44d02d9387..032f4b7f42257c7566fee56e084bd88ed6f5bc23 100644 (file)
@@ -2415,7 +2415,6 @@ static struct bin_attribute mv64xxx_hs_reg_attr = { /* Hotswap register */
        .attr = {
                .name = "hs_reg",
                .mode = S_IRUGO | S_IWUSR,
-               .owner = THIS_MODULE,
        },
        .size  = VAL_LEN_MAX,
        .read  = mv64xxx_hs_reg_read,
index 2775d2618332d1a593e2aed4b3fb976b59a9d86a..95f5160df27f0f3c12d9a9c978a07c77d5e724d9 100644 (file)
@@ -24,7 +24,7 @@
 #define CRYPT_S390_PRIORITY 300
 #define CRYPT_S390_COMPOSITE_PRIORITY 400
 
-/* s930 cryptographic operations */
+/* s390 cryptographic operations */
 enum crypt_s390_operations {
        CRYPT_S390_KM   = 0x0100,
        CRYPT_S390_KMC  = 0x0200,
index 50538e5456183194b08d60d81d73b84cfa448983..e6289ee74ecd400bcfaf606d8f9585191225462f 100644 (file)
@@ -171,37 +171,6 @@ static inline int memory_fast_detect(void)
 }
 #endif
 
-#define ADDR2G (1UL << 31)
-
-static noinline __init unsigned long sclp_memory_detect(void)
-{
-       struct sclp_readinfo_sccb *sccb;
-       unsigned long long memsize;
-
-       sccb = &s390_readinfo_sccb;
-
-       if (sccb->header.response_code != 0x10)
-               return 0;
-
-       if (sccb->rnsize)
-               memsize = sccb->rnsize << 20;
-       else
-               memsize = sccb->rnsize2 << 20;
-       if (sccb->rnmax)
-               memsize *= sccb->rnmax;
-       else
-               memsize *= sccb->rnmax2;
-#ifndef CONFIG_64BIT
-       /*
-        * Can't deal with more than 2G in 31 bit addressing mode, so
-        * limit the value in order to avoid strange side effects.
-        */
-       if (memsize > ADDR2G)
-               memsize = ADDR2G;
-#endif
-       return (unsigned long) memsize;
-}
-
 static inline __init unsigned long __tprot(unsigned long addr)
 {
        int cc = -1;
@@ -218,6 +187,7 @@ static inline __init unsigned long __tprot(unsigned long addr)
 
 /* Checking memory in 128KB increments. */
 #define CHUNK_INCR     (1UL << 17)
+#define ADDR2G         (1UL << 31)
 
 static noinline __init void find_memory_chunks(unsigned long memsize)
 {
@@ -293,7 +263,7 @@ static noinline __init void setup_lowcore_early(void)
  */
 void __init startup_init(void)
 {
-       unsigned long memsize;
+       unsigned long long memsize;
 
        ipl_save_parameters();
        clear_bss_section();
@@ -305,8 +275,17 @@ void __init startup_init(void)
        sort_main_extable();
        setup_lowcore_early();
        sclp_readinfo_early();
+       sclp_facilities_detect();
        memsize = sclp_memory_detect();
+#ifndef CONFIG_64BIT
+       /*
+        * Can't deal with more than 2G in 31 bit addressing mode, so
+        * limit the value in order to avoid strange side effects.
+        */
+       if (memsize > ADDR2G)
+               memsize = ADDR2G;
+#endif
        if (memory_fast_detect() < 0)
-               find_memory_chunks(memsize);
+               find_memory_chunks((unsigned long) memsize);
        lockdep_on();
 }
index 6234c6978a1f040cd07113a4a9a22d357a430b52..bc7ff3658c3d4a4bb5bcf2db392abeecc7191d74 100644 (file)
@@ -107,6 +107,11 @@ STACK_SIZE  = 1 << STACK_SHIFT
        l       %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13
        .endm
 
+       .macro  SAVE_ALL_SVC psworg,savearea
+       la      %r12,\psworg
+       l       %r15,__LC_KERNEL_STACK  # problem state -> load ksp
+       .endm
+
        .macro  SAVE_ALL_SYNC psworg,savearea
        la      %r12,\psworg
        tm      \psworg+1,0x01          # test problem state bit
@@ -218,7 +223,7 @@ system_call:
        STORE_TIMER __LC_SYNC_ENTER_TIMER
 sysc_saveall:
        SAVE_ALL_BASE __LC_SAVE_AREA
-       SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
+       SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
        CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
        lh      %r7,0x8a          # get svc number from lowcore
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
index 685f11faa4bcfbd3e19c428dd778b5c86c87efe8..2a7b1304418ba6ab8da72e923b8c99abb004d84f 100644 (file)
@@ -99,6 +99,11 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \
        larl    %r13,system_call
        .endm
 
+       .macro  SAVE_ALL_SVC psworg,savearea
+       la      %r12,\psworg
+       lg      %r15,__LC_KERNEL_STACK  # problem state -> load ksp
+       .endm
+
        .macro  SAVE_ALL_SYNC psworg,savearea
        la      %r12,\psworg
        tm      \psworg+1,0x01          # test problem state bit
@@ -207,7 +212,7 @@ system_call:
        STORE_TIMER __LC_SYNC_ENTER_TIMER
 sysc_saveall:
        SAVE_ALL_BASE __LC_SAVE_AREA
-       SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
+       SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
        CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
        llgh    %r7,__LC_SVC_INT_CODE   # get svc number from lowcore
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
index 367caf92ea78afbc9715c9e7f0534424647d3741..9a13b24ee1ab2e751715ce014823d22a60828b54 100644 (file)
 
 #define IPL_PARM_BLOCK_VERSION 0
 
-#define SCCB_VALID (s390_readinfo_sccb.header.response_code == 0x10)
-#define SCCB_LOADPARM (&s390_readinfo_sccb.loadparm)
-#define SCCB_FLAG (s390_readinfo_sccb.flags)
-
 #define IPL_UNKNOWN_STR                "unknown"
 #define IPL_CCW_STR            "ccw"
 #define IPL_FCP_STR            "fcp"
@@ -146,6 +142,8 @@ static struct ipl_parameter_block *dump_block_ccw;
 
 static enum shutdown_action on_panic_action = SHUTDOWN_STOP;
 
+static struct sclp_ipl_info sclp_ipl_info;
+
 int diag308(unsigned long subcode, void *addr)
 {
        register unsigned long _addr asm("0") = (unsigned long) addr;
@@ -314,7 +312,6 @@ static struct bin_attribute ipl_parameter_attr = {
        .attr = {
                .name = "binary_parameter",
                .mode = S_IRUGO,
-               .owner = THIS_MODULE,
        },
        .size = PAGE_SIZE,
        .read = &ipl_parameter_read,
@@ -338,7 +335,6 @@ static struct bin_attribute ipl_scp_data_attr = {
        .attr = {
                .name = "scp_data",
                .mode = S_IRUGO,
-               .owner = THIS_MODULE,
        },
        .size = PAGE_SIZE,
        .read = &ipl_scp_data_read,
@@ -375,9 +371,9 @@ static ssize_t ipl_ccw_loadparm_show(struct kset *kset, char *page)
 {
        char loadparm[LOADPARM_LEN + 1] = {};
 
-       if (!SCCB_VALID)
+       if (!sclp_ipl_info.is_valid)
                return sprintf(page, "#unknown#\n");
-       memcpy(loadparm, SCCB_LOADPARM, LOADPARM_LEN);
+       memcpy(loadparm, &sclp_ipl_info.loadparm, LOADPARM_LEN);
        EBCASC(loadparm, LOADPARM_LEN);
        strstrip(loadparm);
        return sprintf(page, "%s\n", loadparm);
@@ -910,9 +906,9 @@ static int __init reipl_ccw_init(void)
        reipl_block_ccw->hdr.blk0_len = IPL_PARM_BLK0_CCW_LEN;
        reipl_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW;
        /* check if read scp info worked and set loadparm */
-       if (SCCB_VALID)
+       if (sclp_ipl_info.is_valid)
                memcpy(reipl_block_ccw->ipl_info.ccw.load_param,
-                      SCCB_LOADPARM, LOADPARM_LEN);
+                      &sclp_ipl_info.loadparm, LOADPARM_LEN);
        else
                /* read scp info failed: set empty loadparm (EBCDIC blanks) */
                memset(reipl_block_ccw->ipl_info.ccw.load_param, 0x40,
@@ -1007,7 +1003,7 @@ static int __init dump_fcp_init(void)
 {
        int rc;
 
-       if(!(SCCB_FLAG & 0x2) || !SCCB_VALID)
+       if (!sclp_ipl_info.has_dump)
                return 0; /* LDIPL DUMP is not installed */
        if (!diag308_set_works)
                return 0;
@@ -1088,6 +1084,7 @@ static int __init s390_ipl_init(void)
 {
        int rc;
 
+       sclp_get_ipl_info(&sclp_ipl_info);
        reipl_probe();
        rc = ipl_init();
        if (rc)
index eb43c3b31269c64fe7da6f04f8a99bc53c82d2b2..441975b796fb03d901cef8a63dc3414a3a2b508c 100644 (file)
@@ -93,8 +93,8 @@ void do_monitor_call(struct pt_regs *regs, long interruption_code)
        /* disable monitor call class 0 */
        __ctl_clear_bit(8, 15);
 
-       atomic_notifier_call_chain(&idle_chain, CPU_NOT_IDLE,
-                           (void *)(long) smp_processor_id());
+       atomic_notifier_call_chain(&idle_chain, S390_CPU_NOT_IDLE,
+                                  (void *)(long) smp_processor_id());
 }
 
 extern void s390_handle_mcck(void);
@@ -115,7 +115,7 @@ static void default_idle(void)
        }
 
        rc = atomic_notifier_call_chain(&idle_chain,
-                       CPU_IDLE, (void *)(long) cpu);
+                                       S390_CPU_IDLE, (void *)(long) cpu);
        if (rc != NOTIFY_OK && rc != NOTIFY_DONE)
                BUG();
        if (rc != NOTIFY_OK) {
index 8ff2feaf9b00357996efe466410da5181f70ce39..182c085ae4ddd94e11d462d9b918152669bb6f1d 100644 (file)
@@ -410,58 +410,40 @@ EXPORT_SYMBOL(smp_ctl_clear_bit);
 unsigned int zfcpdump_prefix_array[NR_CPUS + 1] \
        __attribute__((__section__(".data")));
 
-static void __init smp_get_save_areas(void)
+static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu)
 {
-       unsigned int cpu, cpu_num, rc;
-       __u16 boot_cpu_addr;
-
        if (ipl_info.type != IPL_TYPE_FCP_DUMP)
                return;
-       boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr;
-       cpu_num = 1;
-       for (cpu = 0; cpu <= 65535; cpu++) {
-               if ((u16) cpu == boot_cpu_addr)
-                       continue;
-               __cpu_logical_map[1] = (__u16) cpu;
-               if (signal_processor(1, sigp_sense) == sigp_not_operational)
-                       continue;
-               if (cpu_num >= NR_CPUS) {
-                       printk("WARNING: Registers for cpu %i are not "
-                              "saved, since dump kernel was compiled with"
-                              "NR_CPUS=%i!\n", cpu_num, NR_CPUS);
-                       continue;
-               }
-               zfcpdump_save_areas[cpu_num] =
-                       alloc_bootmem(sizeof(union save_area));
-               while (1) {
-                       rc = signal_processor(1, sigp_stop_and_store_status);
-                       if (rc != sigp_busy)
-                               break;
-                       cpu_relax();
-               }
-               memcpy(zfcpdump_save_areas[cpu_num],
-                      (void *)(unsigned long) store_prefix() +
-                      SAVE_AREA_BASE, SAVE_AREA_SIZE);
-#ifdef __s390x__
-               /* copy original prefix register */
-               zfcpdump_save_areas[cpu_num]->s390x.pref_reg =
-                       zfcpdump_prefix_array[cpu_num];
-#endif
-               cpu_num++;
+       if (cpu >= NR_CPUS) {
+               printk(KERN_WARNING "Registers for cpu %i not saved since dump "
+                      "kernel was compiled with NR_CPUS=%i\n", cpu, NR_CPUS);
+               return;
        }
+       zfcpdump_save_areas[cpu] = alloc_bootmem(sizeof(union save_area));
+       __cpu_logical_map[1] = (__u16) phy_cpu;
+       while (signal_processor(1, sigp_stop_and_store_status) == sigp_busy)
+               cpu_relax();
+       memcpy(zfcpdump_save_areas[cpu],
+              (void *)(unsigned long) store_prefix() + SAVE_AREA_BASE,
+              SAVE_AREA_SIZE);
+#ifdef CONFIG_64BIT
+       /* copy original prefix register */
+       zfcpdump_save_areas[cpu]->s390x.pref_reg = zfcpdump_prefix_array[cpu];
+#endif
 }
 
 union save_area *zfcpdump_save_areas[NR_CPUS + 1];
 EXPORT_SYMBOL_GPL(zfcpdump_save_areas);
 
 #else
-#define smp_get_save_areas() do { } while (0)
-#endif
+
+static inline void smp_get_save_area(unsigned int cpu, unsigned int phy_cpu) { }
+
+#endif /* CONFIG_ZFCPDUMP || CONFIG_ZFCPDUMP_MODULE */
 
 /*
  * Lets check how many CPUs we have.
  */
-
 static unsigned int __init smp_count_cpus(void)
 {
        unsigned int cpu, num_cpus;
@@ -470,7 +452,6 @@ static unsigned int __init smp_count_cpus(void)
        /*
         * cpu 0 is the boot cpu. See smp_prepare_boot_cpu.
         */
-
        boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr;
        current_thread_info()->cpu = 0;
        num_cpus = 1;
@@ -480,12 +461,11 @@ static unsigned int __init smp_count_cpus(void)
                __cpu_logical_map[1] = (__u16) cpu;
                if (signal_processor(1, sigp_sense) == sigp_not_operational)
                        continue;
+               smp_get_save_area(num_cpus, cpu);
                num_cpus++;
        }
-
        printk("Detected %d CPU's\n", (int) num_cpus);
        printk("Boot cpu address %2X\n", boot_cpu_addr);
-
        return num_cpus;
 }
 
@@ -606,7 +586,6 @@ void __init smp_setup_cpu_possible_map(void)
 {
        unsigned int phy_cpus, pos_cpus, cpu;
 
-       smp_get_save_areas();
        phy_cpus = smp_count_cpus();
        pos_cpus = min(phy_cpus + additional_cpus, (unsigned int) NR_CPUS);
 
index 9c2872a7cca723f163ec91783ebf85315883d8ed..48dae49bc1ec474ffe80f3eed427a610f48d48bf 100644 (file)
@@ -226,10 +226,10 @@ static int nohz_idle_notify(struct notifier_block *self,
                            unsigned long action, void *hcpu)
 {
        switch (action) {
-       case CPU_IDLE:
+       case S390_CPU_IDLE:
                stop_hz_timer();
                break;
-       case CPU_NOT_IDLE:
+       case S390_CPU_NOT_IDLE:
                start_hz_timer();
                break;
        }
index 1e1a6ee2cac174b163aa8684eb70a92b5e64ff37..b6ed143e8597156d181437cab5519afe2062012d 100644 (file)
@@ -545,10 +545,10 @@ static int vtimer_idle_notify(struct notifier_block *self,
                              unsigned long action, void *hcpu)
 {
        switch (action) {
-       case CPU_IDLE:
+       case S390_CPU_IDLE:
                stop_cpu_timer();
                break;
-       case CPU_NOT_IDLE:
+       case S390_CPU_NOT_IDLE:
                start_cpu_timer();
                break;
        }
index 59aea65ce99fc0845e88c540d7866b736cd28146..52084436ab69726252e894d5ecdcecbbb6580c24 100644 (file)
@@ -4,7 +4,7 @@
 
 EXTRA_AFLAGS := -traditional
 
-lib-y += delay.o string.o uaccess_std.o uaccess_pt.o qrnnd.o
-obj-$(CONFIG_32BIT) += div64.o
+lib-y += delay.o string.o uaccess_std.o uaccess_pt.o
+obj-$(CONFIG_32BIT) += div64.o qrnnd.o
 lib-$(CONFIG_64BIT) += uaccess_mvcos.o
 lib-$(CONFIG_SMP) += spinlock.o
index fbcc00c6c06ea6dff4c0706ac86a5806b1b63b4e..8567cc901942be09a40178388919afea7fdc1d4c 100644 (file)
@@ -210,6 +210,9 @@ config PCI
          CP-1200, JavaEngine-1, Corona, Red October, and Serengeti SGSC.
          All of these platforms are extremely obscure, so say N if unsure.
 
+config PCI_SYSCALL
+       def_bool PCI
+
 source "drivers/pci/Kconfig"
 
 endif
index 4d9ad59031bb244f3df459338f9e5b9d6c9a6235..4fea3ac7bff08d1b13cd4e54f2d2be6b08198d1a 100644 (file)
@@ -68,16 +68,6 @@ void __cpuinit smp_store_cpu_info(int id)
        cpu_data(id).prom_node = cpu_node;
        cpu_data(id).mid = cpu_get_hwmid(cpu_node);
 
-       /* this is required to tune the scheduler correctly */
-       /* is it possible to have CPUs with different cache sizes? */
-       if (id == boot_cpu_id) {
-               int cache_line,cache_nlines;
-               cache_line = 0x20;
-               cache_line = prom_getintdefault(cpu_node, "ecache-line-size", cache_line);
-               cache_nlines = 0x8000;
-               cache_nlines = prom_getintdefault(cpu_node, "ecache-nlines", cache_nlines);
-               max_cache_size = cache_line * cache_nlines;
-       }
        if (cpu_data(id).mid < 0)
                panic("No MID found for CPU%d at node 0x%08d", id, cpu_node);
 }
index 89a1b469b93df149b21c1c65c5d1723d36e97e09..6566d13db04fec3c5417cde60c0295319f405c9f 100644 (file)
@@ -320,8 +320,10 @@ config PCI
          doesn't.
 
 config PCI_DOMAINS
-       bool
-       default PCI
+       def_bool PCI
+
+config PCI_SYSCALL
+       def_bool PCI
 
 source "drivers/pci/Kconfig"
 
index 81f4a5ea05f7ab948e307daa1853f53d1b554fbd..55ad1b899bb8e945a3e049d09ef13e5e1fd167a5 100644 (file)
@@ -448,6 +448,7 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
                 */
                pci_read_config_dword(dev, PCI_CLASS_REVISION, &class);
                dev->class = class >> 8;
+               dev->revision = class & 0xff;
 
                sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus),
                        dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));
index 4dcd7d0b60f2d8abb8e8ad7630df207cfc39ad21..40e40f968d61abd9ef8192aeb1a6f2a9b318c7e7 100644 (file)
@@ -1163,32 +1163,6 @@ int setup_profiling_timer(unsigned int multiplier)
        return -EINVAL;
 }
 
-static void __init smp_tune_scheduling(void)
-{
-       unsigned int smallest = ~0U;
-       int i;
-
-       for (i = 0; i < NR_CPUS; i++) {
-               unsigned int val = cpu_data(i).ecache_size;
-
-               if (val && val < smallest)
-                       smallest = val;
-       }
-
-       /* Any value less than 256K is nonsense.  */
-       if (smallest < (256U * 1024U))
-               smallest = 256 * 1024;
-
-       max_cache_size = smallest;
-
-       if (smallest < 1U * 1024U * 1024U)
-               printk(KERN_INFO "Using max_cache_size of %uKB\n",
-                      smallest / 1024U);
-       else
-               printk(KERN_INFO "Using max_cache_size of %uMB\n",
-                      smallest / 1024U / 1024U);
-}
-
 /* Constrain the number of cpus to max_cpus.  */
 void __init smp_prepare_cpus(unsigned int max_cpus)
 {
@@ -1206,7 +1180,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
        }
 
        cpu_data(boot_cpu_id).udelay_val = loops_per_jiffy;
-       smp_tune_scheduling();
 }
 
 void __devinit smp_prepare_boot_cpu(void)
index 5ce94430c019cfe90bb647082d0c63e41e0c09e5..8bdd25ac15425d40f3bb7340f87a5dd70ddc140d 100644 (file)
@@ -427,6 +427,10 @@ config NR_CPUS
          This is purely to save memory - each supported CPU requires
          memory in the static kernel configuration.
 
+config PHYSICAL_ALIGN
+       hex
+       default "0x200000"
+
 config HOTPLUG_CPU
        bool "Support for suspend on SMP and hot-pluggable CPUs (EXPERIMENTAL)"
        depends on SMP && HOTPLUG && EXPERIMENTAL
index ee6f6505f95f98d14d087066a64d154de8893f01..67096389de1f1f7d1323f9ef6bead27e284c742c 100644 (file)
@@ -1,135 +1,9 @@
 #
 # arch/x86_64/boot/Makefile
 #
-# This file is subject to the terms and conditions of the GNU General Public
-# License.  See the file "COPYING" in the main directory of this archive
-# for more details.
-#
-# Copyright (C) 1994 by Linus Torvalds
-#
-
-# ROOT_DEV specifies the default root-device when making the image.
-# This can be either FLOPPY, CURRENT, /dev/xxxx or empty, in which case
-# the default of FLOPPY is used by 'build'.
-
-ROOT_DEV := CURRENT
-
-# If you want to preset the SVGA mode, uncomment the next line and
-# set SVGA_MODE to whatever number you want.
-# Set it to -DSVGA_MODE=NORMAL_VGA if you just want the EGA/VGA mode.
-# The number is the same as you would ordinarily press at bootup.
-
-SVGA_MODE := -DSVGA_MODE=NORMAL_VGA
-
-# If you want the RAM disk device, define this to be the size in blocks.
-
-#RAMDISK := -DRAMDISK=512
-
-targets                := vmlinux.bin bootsect bootsect.o \
-                  setup setup.o bzImage mtools.conf
-
-EXTRA_CFLAGS := -m32
-
-hostprogs-y    := tools/build
-HOST_EXTRACFLAGS += $(LINUXINCLUDE)
-subdir-                := compressed/  #Let make clean descend in compressed/
-# ---------------------------------------------------------------------------
-
-$(obj)/bzImage: IMAGE_OFFSET := 0x100000
-$(obj)/bzImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__
-$(obj)/bzImage: BUILDFLAGS   := -b
-
-quiet_cmd_image = BUILD   $@
-cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/bootsect $(obj)/setup \
-           $(obj)/vmlinux.bin $(ROOT_DEV) > $@
-
-$(obj)/bzImage: $(obj)/bootsect $(obj)/setup \
-                             $(obj)/vmlinux.bin $(obj)/tools/build FORCE
-       $(call if_changed,image)
-       @echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
-
-$(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE
-       $(call if_changed,objcopy)
-
-LDFLAGS_bootsect := -Ttext 0x0 -s --oformat binary
-LDFLAGS_setup   := -Ttext 0x0 -s --oformat binary -e begtext
-
-$(obj)/setup $(obj)/bootsect: %: %.o FORCE
-       $(call if_changed,ld)
-
-$(obj)/compressed/vmlinux: FORCE
-       $(Q)$(MAKE) $(build)=$(obj)/compressed IMAGE_OFFSET=$(IMAGE_OFFSET) $@
-
-# Set this if you want to pass append arguments to the zdisk/fdimage/isoimage kernel
-FDARGS = 
-# Set this if you want an initrd included with the zdisk/fdimage/isoimage kernel
-FDINITRD =
-
-image_cmdline = default linux $(FDARGS) $(if $(FDINITRD),initrd=initrd.img,)
-
-$(obj)/mtools.conf: $(src)/mtools.conf.in
-       sed -e 's|@OBJ@|$(obj)|g' < $< > $@
-
-# This requires write access to /dev/fd0
-zdisk: $(BOOTIMAGE) $(obj)/mtools.conf
-       MTOOLSRC=$(obj)/mtools.conf mformat a:                  ; sync
-       syslinux /dev/fd0                                       ; sync
-       echo '$(image_cmdline)' | \
-               MTOOLSRC=$(obj)/mtools.conf mcopy - a:syslinux.cfg
-       if [ -f '$(FDINITRD)' ] ; then \
-               MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' a:initrd.img ; \
-       fi
-       MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) a:linux  ; sync
-
-# These require being root or having syslinux 2.02 or higher installed
-fdimage fdimage144: $(BOOTIMAGE) $(obj)/mtools.conf
-       dd if=/dev/zero of=$(obj)/fdimage bs=1024 count=1440
-       MTOOLSRC=$(obj)/mtools.conf mformat v:                  ; sync
-       syslinux $(obj)/fdimage                                 ; sync
-       echo '$(image_cmdline)' | \
-               MTOOLSRC=$(obj)/mtools.conf mcopy - v:syslinux.cfg
-       if [ -f '$(FDINITRD)' ] ; then \
-               MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' v:initrd.img ; \
-       fi
-       MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) v:linux  ; sync
-
-fdimage288: $(BOOTIMAGE) $(obj)/mtools.conf
-       dd if=/dev/zero of=$(obj)/fdimage bs=1024 count=2880
-       MTOOLSRC=$(obj)/mtools.conf mformat w:                  ; sync
-       syslinux $(obj)/fdimage                                 ; sync
-       echo '$(image_cmdline)' | \
-               MTOOLSRC=$(obj)/mtools.conf mcopy - w:syslinux.cfg
-       if [ -f '$(FDINITRD)' ] ; then \
-               MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' w:initrd.img ; \
-       fi
-       MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) w:linux  ; sync
-
-isoimage: $(BOOTIMAGE)
-       -rm -rf $(obj)/isoimage
-       mkdir $(obj)/isoimage
-       for i in lib lib64 share end ; do \
-               if [ -f /usr/$$i/syslinux/isolinux.bin ] ; then \
-                       cp /usr/$$i/syslinux/isolinux.bin $(obj)/isoimage ; \
-                       break ; \
-               fi ; \
-               if [ $$i = end ] ; then exit 1 ; fi ; \
-       done
-       cp $(BOOTIMAGE) $(obj)/isoimage/linux
-       echo '$(image_cmdline)' > $(obj)/isoimage/isolinux.cfg
-       if [ -f '$(FDINITRD)' ] ; then \
-               cp '$(FDINITRD)' $(obj)/isoimage/initrd.img ; \
-       fi
-       mkisofs -J -r -o $(obj)/image.iso -b isolinux.bin -c boot.cat \
-               -no-emul-boot -boot-load-size 4 -boot-info-table \
-               $(obj)/isoimage
-       rm -rf $(obj)/isoimage
-
-zlilo: $(BOOTIMAGE)
-       if [ -f $(INSTALL_PATH)/vmlinuz ]; then mv $(INSTALL_PATH)/vmlinuz $(INSTALL_PATH)/vmlinuz.old; fi
-       if [ -f $(INSTALL_PATH)/System.map ]; then mv $(INSTALL_PATH)/System.map $(INSTALL_PATH)/System.old; fi
-       cat $(BOOTIMAGE) > $(INSTALL_PATH)/vmlinuz
-       cp System.map $(INSTALL_PATH)/
-       if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
+# The actual boot code is shared with i386 including the Makefile.
+# So tell kbuild that we fetch the code from i386 and include the
+# Makefile from i386 too.
 
-install:
-       sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $(BOOTIMAGE) System.map "$(INSTALL_PATH)"
+src := arch/i386/boot
+include $(src)/Makefile
diff --git a/arch/x86_64/boot/bootsect.S b/arch/x86_64/boot/bootsect.S
deleted file mode 100644 (file)
index 011b7a4..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- *     bootsect.S              Copyright (C) 1991, 1992 Linus Torvalds
- *
- *     modified by Drew Eckhardt
- *     modified by Bruce Evans (bde)
- *     modified by Chris Noe (May 1999) (as86 -> gas)
- *     gutted by H. Peter Anvin (Jan 2003)
- *
- * BIG FAT NOTE: We're in real mode using 64k segments.  Therefore segment
- * addresses must be multiplied by 16 to obtain their respective linear
- * addresses. To avoid confusion, linear addresses are written using leading
- * hex while segment addresses are written as segment:offset.
- *
- */
-
-#include <asm/boot.h>
-
-SETUPSECTS     = 4                     /* default nr of setup-sectors */
-BOOTSEG                = 0x07C0                /* original address of boot-sector */
-INITSEG                = DEF_INITSEG           /* we move boot here - out of the way */
-SETUPSEG       = DEF_SETUPSEG          /* setup starts here */
-SYSSEG         = DEF_SYSSEG            /* system loaded at 0x10000 (65536) */
-SYSSIZE                = DEF_SYSSIZE           /* system size: # of 16-byte clicks */
-                                       /* to be loaded */
-ROOT_DEV       = 0                     /* ROOT_DEV is now written by "build" */
-SWAP_DEV       = 0                     /* SWAP_DEV is now written by "build" */
-
-#ifndef SVGA_MODE
-#define SVGA_MODE ASK_VGA
-#endif
-
-#ifndef RAMDISK
-#define RAMDISK 0
-#endif
-
-#ifndef ROOT_RDONLY
-#define ROOT_RDONLY 1
-#endif
-
-.code16
-.text
-
-.global _start
-_start:
-
-       # Normalize the start address
-       jmpl    $BOOTSEG, $start2
-
-start2:
-       movw    %cs, %ax
-       movw    %ax, %ds
-       movw    %ax, %es
-       movw    %ax, %ss
-       movw    $0x7c00, %sp
-       sti
-       cld
-
-       movw    $bugger_off_msg, %si
-
-msg_loop:
-       lodsb
-       andb    %al, %al
-       jz      die
-       movb    $0xe, %ah
-       movw    $7, %bx
-       int     $0x10
-       jmp     msg_loop
-
-die:
-       # Allow the user to press a key, then reboot
-       xorw    %ax, %ax
-       int     $0x16
-       int     $0x19
-
-       # int 0x19 should never return.  In case it does anyway,
-       # invoke the BIOS reset code...
-       ljmp    $0xf000,$0xfff0
-
-
-bugger_off_msg:
-       .ascii  "Direct booting from floppy is no longer supported.\r\n"
-       .ascii  "Please use a boot loader program instead.\r\n"
-       .ascii  "\n"
-       .ascii  "Remove disk and press any key to reboot . . .\r\n"
-       .byte   0
-
-
-       # Kernel attributes; used by setup
-
-       .org 497
-setup_sects:   .byte SETUPSECTS
-root_flags:    .word ROOT_RDONLY
-syssize:       .word SYSSIZE
-swap_dev:      .word SWAP_DEV
-ram_size:      .word RAMDISK
-vid_mode:      .word SVGA_MODE
-root_dev:      .word ROOT_DEV
-boot_flag:     .word 0xAA55
index 705a3e33d7e176009cc8fb135620f80d88821dd8..c9f2da7496c14d738b0c8453dd835dd70db9cf96 100644 (file)
@@ -7,11 +7,12 @@
 #
 
 targets                := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o
-EXTRA_AFLAGS   := -traditional
 
-# cannot use EXTRA_CFLAGS because base CFLAGS contains -mkernel which conflicts with
-# -m32
-CFLAGS := -m64 -D__KERNEL__ -Iinclude -O2  -fno-strict-aliasing -fPIC -mcmodel=small -fno-builtin
+CFLAGS := -m64 -D__KERNEL__ $(LINUXINCLUDE) -O2  \
+         -fno-strict-aliasing -fPIC -mcmodel=small \
+          $(call cc-option, -ffreestanding) \
+          $(call cc-option, -fno-stack-protector)
+AFLAGS  := $(CFLAGS) -D__ASSEMBLY__
 LDFLAGS := -m elf_x86_64
 
 LDFLAGS_vmlinux := -T
index f9d5692a0106e4c0ee311d034bd5eb0ef7702e3b..1312bfaff306866319fcbb8dec3caf06f933c0d1 100644 (file)
@@ -46,10 +46,10 @@ startup_32:
  * at and where we were actually loaded at.  This can only be done
  * with a short local call on x86.  Nothing  else will tell us what
  * address we are running at.  The reserved chunk of the real-mode
- * data at 0x34-0x3f are used as the stack for this calculation.
- * Only 4 bytes are needed.
+ * data at 0x1e4 (defined as a scratch field) are used as the stack
+ * for this calculation. Only 4 bytes are needed.
  */
-       leal    0x40(%esi), %esp
+       leal    (0x1e4+4)(%esi), %esp
        call    1f
 1:     popl    %ebp
        subl    $1b, %ebp
diff --git a/arch/x86_64/boot/install.sh b/arch/x86_64/boot/install.sh
deleted file mode 100644 (file)
index baaa236..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-. $srctree/arch/i386/boot/install.sh
diff --git a/arch/x86_64/boot/mtools.conf.in b/arch/x86_64/boot/mtools.conf.in
deleted file mode 100644 (file)
index efd6d24..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# mtools configuration file for "make (b)zdisk"
-#
-
-# Actual floppy drive
-drive a:
-  file="/dev/fd0"
-
-# 1.44 MB floppy disk image
-drive v:
-  file="@OBJ@/fdimage" cylinders=80 heads=2 sectors=18 filter
-
-# 2.88 MB floppy disk image (mostly for virtual uses)
-drive w:
-  file="@OBJ@/fdimage" cylinders=80 heads=2 sectors=36 filter
-
-
diff --git a/arch/x86_64/boot/setup.S b/arch/x86_64/boot/setup.S
deleted file mode 100644 (file)
index e9e33f9..0000000
+++ /dev/null
@@ -1,826 +0,0 @@
-/*
- *     setup.S         Copyright (C) 1991, 1992 Linus Torvalds
- *
- * setup.s is responsible for getting the system data from the BIOS,
- * and putting them into the appropriate places in system memory.
- * both setup.s and system has been loaded by the bootblock.
- *
- * This code asks the bios for memory/disk/other parameters, and
- * puts them in a "safe" place: 0x90000-0x901FF, ie where the
- * boot-block used to be. It is then up to the protected mode
- * system to read them from there before the area is overwritten
- * for buffer-blocks.
- *
- * Move PS/2 aux init code to psaux.c
- * (troyer@saifr00.cfsat.Honeywell.COM) 03Oct92
- *
- * some changes and additional features by Christoph Niemann,
- * March 1993/June 1994 (Christoph.Niemann@linux.org)
- *
- * add APM BIOS checking by Stephen Rothwell, May 1994
- * (sfr@canb.auug.org.au)
- *
- * High load stuff, initrd support and position independency
- * by Hans Lermen & Werner Almesberger, February 1996
- * <lermen@elserv.ffm.fgan.de>, <almesber@lrc.epfl.ch>
- *
- * Video handling moved to video.S by Martin Mares, March 1996
- * <mj@k332.feld.cvut.cz>
- *
- * Extended memory detection scheme retwiddled by orc@pell.chi.il.us (david
- * parsons) to avoid loadlin confusion, July 1997
- *
- * Transcribed from Intel (as86) -> AT&T (gas) by Chris Noe, May 1999.
- * <stiker@northlink.com>
- *
- * Fix to work around buggy BIOSes which don't use carry bit correctly
- * and/or report extended memory in CX/DX for e801h memory size detection 
- * call.  As a result the kernel got wrong figures.  The int15/e801h docs
- * from Ralf Brown interrupt list seem to indicate AX/BX should be used
- * anyway.  So to avoid breaking many machines (presumably there was a reason
- * to orginally use CX/DX instead of AX/BX), we do a kludge to see
- * if CX/DX have been changed in the e801 call and if so use AX/BX .
- * Michael Miller, April 2001 <michaelm@mjmm.org>
- *
- * Added long mode checking and SSE force. March 2003, Andi Kleen.             
- */
-
-#include <asm/segment.h>
-#include <linux/utsrelease.h>
-#include <linux/compile.h>
-#include <asm/boot.h>
-#include <asm/e820.h>
-#include <asm/page.h>
-#include <asm/setup.h>
-
-/* Signature words to ensure LILO loaded us right */
-#define SIG1   0xAA55
-#define SIG2   0x5A5A
-
-INITSEG  = DEF_INITSEG         # 0x9000, we move boot here, out of the way
-SYSSEG   = DEF_SYSSEG          # 0x1000, system loaded at 0x10000 (65536).
-SETUPSEG = DEF_SETUPSEG                # 0x9020, this is the current segment
-                               # ... and the former contents of CS
-
-DELTA_INITSEG = SETUPSEG - INITSEG     # 0x0020
-
-.code16
-.globl begtext, begdata, begbss, endtext, enddata, endbss
-
-.text
-begtext:
-.data
-begdata:
-.bss
-begbss:
-.text
-
-start:
-       jmp     trampoline
-
-# This is the setup header, and it must start at %cs:2 (old 0x9020:2)
-
-               .ascii  "HdrS"          # header signature
-               .word   0x0206          # header version number (>= 0x0105)
-                                       # or else old loadlin-1.5 will fail)
-realmode_swtch:        .word   0, 0            # default_switch, SETUPSEG
-start_sys_seg: .word   SYSSEG
-               .word   kernel_version  # pointing to kernel version string
-                                       # above section of header is compatible
-                                       # with loadlin-1.5 (header v1.5). Don't
-                                       # change it.
-
-type_of_loader:        .byte   0               # = 0, old one (LILO, Loadlin,
-                                       #      Bootlin, SYSLX, bootsect...)
-                                       # See Documentation/i386/boot.txt for
-                                       # assigned ids
-       
-# flags, unused bits must be zero (RFU) bit within loadflags
-loadflags:
-LOADED_HIGH    = 1                     # If set, the kernel is loaded high
-CAN_USE_HEAP   = 0x80                  # If set, the loader also has set
-                                       # heap_end_ptr to tell how much
-                                       # space behind setup.S can be used for
-                                       # heap purposes.
-                                       # Only the loader knows what is free
-#ifndef __BIG_KERNEL__
-               .byte   0
-#else
-               .byte   LOADED_HIGH
-#endif
-
-setup_move_size: .word  0x8000         # size to move, when setup is not
-                                       # loaded at 0x90000. We will move setup 
-                                       # to 0x90000 then just before jumping
-                                       # into the kernel. However, only the
-                                       # loader knows how much data behind
-                                       # us also needs to be loaded.
-
-code32_start:                          # here loaders can put a different
-                                       # start address for 32-bit code.
-#ifndef __BIG_KERNEL__
-               .long   0x1000          #   0x1000 = default for zImage
-#else
-               .long   0x100000        # 0x100000 = default for big kernel
-#endif
-
-ramdisk_image: .long   0               # address of loaded ramdisk image
-                                       # Here the loader puts the 32-bit
-                                       # address where it loaded the image.
-                                       # This only will be read by the kernel.
-
-ramdisk_size:  .long   0               # its size in bytes
-
-bootsect_kludge:
-               .long   0               # obsolete
-
-heap_end_ptr:  .word   modelist+1024   # (Header version 0x0201 or later)
-                                       # space from here (exclusive) down to
-                                       # end of setup code can be used by setup
-                                       # for local heap purposes.
-
-pad1:          .word   0
-cmd_line_ptr:  .long 0                 # (Header version 0x0202 or later)
-                                       # If nonzero, a 32-bit pointer
-                                       # to the kernel command line.
-                                       # The command line should be
-                                       # located between the start of
-                                       # setup and the end of low
-                                       # memory (0xa0000), or it may
-                                       # get overwritten before it
-                                       # gets read.  If this field is
-                                       # used, there is no longer
-                                       # anything magical about the
-                                       # 0x90000 segment; the setup
-                                       # can be located anywhere in
-                                       # low memory 0x10000 or higher.
-
-ramdisk_max:   .long 0xffffffff
-kernel_alignment:  .long 0x200000       # physical addr alignment required for
-                                       # protected mode relocatable kernel
-#ifdef CONFIG_RELOCATABLE
-relocatable_kernel:    .byte 1
-#else
-relocatable_kernel:    .byte 0
-#endif
-pad2:                  .byte 0
-pad3:                  .word 0
-
-cmdline_size:   .long   COMMAND_LINE_SIZE-1     #length of the command line,
-                                                #added with boot protocol
-                                                #version 2.06
-
-trampoline:    call    start_of_setup
-               .align 16
-                                       # The offset at this point is 0x240
-               .space  (0xeff-0x240+1) # E820 & EDD space (ending at 0xeff)
-# End of setup header #####################################################
-
-start_of_setup:
-# Bootlin depends on this being done early
-       movw    $0x01500, %ax
-       movb    $0x81, %dl
-       int     $0x13
-
-#ifdef SAFE_RESET_DISK_CONTROLLER
-# Reset the disk controller.
-       movw    $0x0000, %ax
-       movb    $0x80, %dl
-       int     $0x13
-#endif
-
-# Set %ds = %cs, we know that SETUPSEG = %cs at this point
-       movw    %cs, %ax                # aka SETUPSEG
-       movw    %ax, %ds
-# Check signature at end of setup
-       cmpw    $SIG1, setup_sig1
-       jne     bad_sig
-
-       cmpw    $SIG2, setup_sig2
-       jne     bad_sig
-
-       jmp     good_sig1
-
-# Routine to print asciiz string at ds:si
-prtstr:
-       lodsb
-       andb    %al, %al
-       jz      fin
-
-       call    prtchr
-       jmp     prtstr
-
-fin:   ret
-
-# Space printing
-prtsp2:        call    prtspc          # Print double space
-prtspc:        movb    $0x20, %al      # Print single space (note: fall-thru)
-
-prtchr:        
-       pushw   %ax
-       pushw   %cx
-       movw    $0007,%bx
-       movw    $0x01, %cx
-       movb    $0x0e, %ah
-       int     $0x10
-       popw    %cx
-       popw    %ax
-       ret
-
-beep:  movb    $0x07, %al
-       jmp     prtchr
-       
-no_sig_mess: .string   "No setup signature found ..."
-
-good_sig1:
-       jmp     good_sig
-
-# We now have to find the rest of the setup code/data
-bad_sig:
-       movw    %cs, %ax                        # SETUPSEG
-       subw    $DELTA_INITSEG, %ax             # INITSEG
-       movw    %ax, %ds
-       xorb    %bh, %bh
-       movb    (497), %bl                      # get setup sect from bootsect
-       subw    $4, %bx                         # LILO loads 4 sectors of setup
-       shlw    $8, %bx                         # convert to words (1sect=2^8 words)
-       movw    %bx, %cx
-       shrw    $3, %bx                         # convert to segment
-       addw    $SYSSEG, %bx
-       movw    %bx, %cs:start_sys_seg
-# Move rest of setup code/data to here
-       movw    $2048, %di                      # four sectors loaded by LILO
-       subw    %si, %si
-       movw    %cs, %ax                        # aka SETUPSEG
-       movw    %ax, %es
-       movw    $SYSSEG, %ax
-       movw    %ax, %ds
-       rep
-       movsw
-       movw    %cs, %ax                        # aka SETUPSEG
-       movw    %ax, %ds
-       cmpw    $SIG1, setup_sig1
-       jne     no_sig
-
-       cmpw    $SIG2, setup_sig2
-       jne     no_sig
-
-       jmp     good_sig
-
-no_sig:
-       lea     no_sig_mess, %si
-       call    prtstr
-
-no_sig_loop:
-       jmp     no_sig_loop
-
-good_sig:
-       movw    %cs, %ax                        # aka SETUPSEG
-       subw    $DELTA_INITSEG, %ax             # aka INITSEG
-       movw    %ax, %ds
-# Check if an old loader tries to load a big-kernel
-       testb   $LOADED_HIGH, %cs:loadflags     # Do we have a big kernel?
-       jz      loader_ok                       # No, no danger for old loaders.
-
-       cmpb    $0, %cs:type_of_loader          # Do we have a loader that
-                                               # can deal with us?
-       jnz     loader_ok                       # Yes, continue.
-
-       pushw   %cs                             # No, we have an old loader,
-       popw    %ds                             # die. 
-       lea     loader_panic_mess, %si
-       call    prtstr
-
-       jmp     no_sig_loop
-
-loader_panic_mess: .string "Wrong loader, giving up..."
-
-loader_ok:
-       /* check for long mode. */
-       /* we have to do this before the VESA setup, otherwise the user
-          can't see the error message. */
-       
-       pushw   %ds
-       movw    %cs,%ax
-       movw    %ax,%ds
-       
-       call verify_cpu
-       testl %eax,%eax
-       jz sse_ok
-
-no_longmode:
-       call    beep
-       lea     long_mode_panic,%si
-       call    prtstr
-no_longmode_loop:              
-       jmp     no_longmode_loop
-long_mode_panic:
-       .string "Your CPU does not support long mode. Use a 32bit distribution."
-       .byte 0
-
-#include "../kernel/verify_cpu.S"
-sse_ok:
-       popw    %ds
-       
-# tell BIOS we want to go to long mode
-       movl  $0xec00,%eax      # declare target operating mode
-       movl  $2,%ebx           # long mode
-       int $0x15                       
-       
-# Get memory size (extended mem, kB)
-
-       xorl    %eax, %eax
-       movl    %eax, (0x1e0)
-#ifndef STANDARD_MEMORY_BIOS_CALL
-       movb    %al, (E820NR)
-# Try three different memory detection schemes.  First, try
-# e820h, which lets us assemble a memory map, then try e801h,
-# which returns a 32-bit memory size, and finally 88h, which
-# returns 0-64m
-
-# method E820H:
-# the memory map from hell.  e820h returns memory classified into
-# a whole bunch of different types, and allows memory holes and
-# everything.  We scan through this memory map and build a list
-# of the first 32 memory areas, which we return at [E820MAP].
-# This is documented at http://www.acpi.info/, in the ACPI 2.0 specification.
-
-#define SMAP  0x534d4150
-
-meme820:
-       xorl    %ebx, %ebx                      # continuation counter
-       movw    $E820MAP, %di                   # point into the whitelist
-                                               # so we can have the bios
-                                               # directly write into it.
-
-jmpe820:
-       movl    $0x0000e820, %eax               # e820, upper word zeroed
-       movl    $SMAP, %edx                     # ascii 'SMAP'
-       movl    $20, %ecx                       # size of the e820rec
-       pushw   %ds                             # data record.
-       popw    %es
-       int     $0x15                           # make the call
-       jc      bail820                         # fall to e801 if it fails
-
-       cmpl    $SMAP, %eax                     # check the return is `SMAP'
-       jne     bail820                         # fall to e801 if it fails
-
-#      cmpl    $1, 16(%di)                     # is this usable memory?
-#      jne     again820
-
-       # If this is usable memory, we save it by simply advancing %di by
-       # sizeof(e820rec).
-       #
-good820:
-       movb    (E820NR), %al                   # up to 128 entries
-       cmpb    $E820MAX, %al
-       jae     bail820
-
-       incb    (E820NR)
-       movw    %di, %ax
-       addw    $20, %ax
-       movw    %ax, %di
-again820:
-       cmpl    $0, %ebx                        # check to see if
-       jne     jmpe820                         # %ebx is set to EOF
-bail820:
-
-
-# method E801H:
-# memory size is in 1k chunksizes, to avoid confusing loadlin.
-# we store the 0xe801 memory size in a completely different place,
-# because it will most likely be longer than 16 bits.
-# (use 1e0 because that's what Larry Augustine uses in his
-# alternative new memory detection scheme, and it's sensible
-# to write everything into the same place.)
-
-meme801:
-       stc                                     # fix to work around buggy
-       xorw    %cx,%cx                         # BIOSes which don't clear/set
-       xorw    %dx,%dx                         # carry on pass/error of
-                                               # e801h memory size call
-                                               # or merely pass cx,dx though
-                                               # without changing them.
-       movw    $0xe801, %ax
-       int     $0x15
-       jc      mem88
-
-       cmpw    $0x0, %cx                       # Kludge to handle BIOSes
-       jne     e801usecxdx                     # which report their extended
-       cmpw    $0x0, %dx                       # memory in AX/BX rather than
-       jne     e801usecxdx                     # CX/DX.  The spec I have read
-       movw    %ax, %cx                        # seems to indicate AX/BX 
-       movw    %bx, %dx                        # are more reasonable anyway...
-
-e801usecxdx:
-       andl    $0xffff, %edx                   # clear sign extend
-       shll    $6, %edx                        # and go from 64k to 1k chunks
-       movl    %edx, (0x1e0)                   # store extended memory size
-       andl    $0xffff, %ecx                   # clear sign extend
-       addl    %ecx, (0x1e0)                   # and add lower memory into
-                                               # total size.
-
-# Ye Olde Traditional Methode.  Returns the memory size (up to 16mb or
-# 64mb, depending on the bios) in ax.
-mem88:
-
-#endif
-       movb    $0x88, %ah
-       int     $0x15
-       movw    %ax, (2)
-
-# Set the keyboard repeat rate to the max
-       movw    $0x0305, %ax
-       xorw    %bx, %bx
-       int     $0x16
-
-# Check for video adapter and its parameters and allow the
-# user to browse video modes.
-       call    video                           # NOTE: we need %ds pointing
-                                               # to bootsector
-
-# Get hd0 data...
-       xorw    %ax, %ax
-       movw    %ax, %ds
-       ldsw    (4 * 0x41), %si
-       movw    %cs, %ax                        # aka SETUPSEG
-       subw    $DELTA_INITSEG, %ax             # aka INITSEG
-       pushw   %ax
-       movw    %ax, %es
-       movw    $0x0080, %di
-       movw    $0x10, %cx
-       pushw   %cx
-       cld
-       rep
-       movsb
-# Get hd1 data...
-       xorw    %ax, %ax
-       movw    %ax, %ds
-       ldsw    (4 * 0x46), %si
-       popw    %cx
-       popw    %es
-       movw    $0x0090, %di
-       rep
-       movsb
-# Check that there IS a hd1 :-)
-       movw    $0x01500, %ax
-       movb    $0x81, %dl
-       int     $0x13
-       jc      no_disk1
-       
-       cmpb    $3, %ah
-       je      is_disk1
-
-no_disk1:
-       movw    %cs, %ax                        # aka SETUPSEG
-       subw    $DELTA_INITSEG, %ax             # aka INITSEG
-       movw    %ax, %es
-       movw    $0x0090, %di
-       movw    $0x10, %cx
-       xorw    %ax, %ax
-       cld
-       rep
-       stosb
-is_disk1:
-
-# Check for PS/2 pointing device
-       movw    %cs, %ax                        # aka SETUPSEG
-       subw    $DELTA_INITSEG, %ax             # aka INITSEG
-       movw    %ax, %ds
-       movb    $0, (0x1ff)                     # default is no pointing device
-       int     $0x11                           # int 0x11: equipment list
-       testb   $0x04, %al                      # check if mouse installed
-       jz      no_psmouse
-
-       movb    $0xAA, (0x1ff)                  # device present
-no_psmouse:
-
-#include "../../i386/boot/edd.S"
-
-# Now we want to move to protected mode ...
-       cmpw    $0, %cs:realmode_swtch
-       jz      rmodeswtch_normal
-
-       lcall   *%cs:realmode_swtch
-
-       jmp     rmodeswtch_end
-
-rmodeswtch_normal:
-        pushw  %cs
-       call    default_switch
-
-rmodeswtch_end:
-# we get the code32 start address and modify the below 'jmpi'
-# (loader may have changed it)
-       movl    %cs:code32_start, %eax
-       movl    %eax, %cs:code32
-
-# Now we move the system to its rightful place ... but we check if we have a
-# big-kernel. In that case we *must* not move it ...
-       testb   $LOADED_HIGH, %cs:loadflags
-       jz      do_move0                        # .. then we have a normal low
-                                               # loaded zImage
-                                               # .. or else we have a high
-                                               # loaded bzImage
-       jmp     end_move                        # ... and we skip moving
-
-do_move0:
-       movw    $0x100, %ax                     # start of destination segment
-       movw    %cs, %bp                        # aka SETUPSEG
-       subw    $DELTA_INITSEG, %bp             # aka INITSEG
-       movw    %cs:start_sys_seg, %bx          # start of source segment
-       cld
-do_move:
-       movw    %ax, %es                        # destination segment
-       incb    %ah                             # instead of add ax,#0x100
-       movw    %bx, %ds                        # source segment
-       addw    $0x100, %bx
-       subw    %di, %di
-       subw    %si, %si
-       movw    $0x800, %cx
-       rep
-       movsw
-       cmpw    %bp, %bx                        # assume start_sys_seg > 0x200,
-                                               # so we will perhaps read one
-                                               # page more than needed, but
-                                               # never overwrite INITSEG
-                                               # because destination is a
-                                               # minimum one page below source
-       jb      do_move
-
-end_move:
-# then we load the segment descriptors
-       movw    %cs, %ax                        # aka SETUPSEG
-       movw    %ax, %ds
-               
-# Check whether we need to be downward compatible with version <=201
-       cmpl    $0, cmd_line_ptr
-       jne     end_move_self           # loader uses version >=202 features
-       cmpb    $0x20, type_of_loader
-       je      end_move_self           # bootsect loader, we know of it
-
-# Boot loader doesnt support boot protocol version 2.02.
-# If we have our code not at 0x90000, we need to move it there now.
-# We also then need to move the params behind it (commandline)
-# Because we would overwrite the code on the current IP, we move
-# it in two steps, jumping high after the first one.
-       movw    %cs, %ax
-       cmpw    $SETUPSEG, %ax
-       je      end_move_self
-
-       cli                                     # make sure we really have
-                                               # interrupts disabled !
-                                               # because after this the stack
-                                               # should not be used
-       subw    $DELTA_INITSEG, %ax             # aka INITSEG
-       movw    %ss, %dx
-       cmpw    %ax, %dx
-       jb      move_self_1
-
-       addw    $INITSEG, %dx
-       subw    %ax, %dx                        # this will go into %ss after
-                                               # the move
-move_self_1:
-       movw    %ax, %ds
-       movw    $INITSEG, %ax                   # real INITSEG
-       movw    %ax, %es
-       movw    %cs:setup_move_size, %cx
-       std                                     # we have to move up, so we use
-                                               # direction down because the
-                                               # areas may overlap
-       movw    %cx, %di
-       decw    %di
-       movw    %di, %si
-       subw    $move_self_here+0x200, %cx
-       rep
-       movsb
-       ljmp    $SETUPSEG, $move_self_here
-
-move_self_here:
-       movw    $move_self_here+0x200, %cx
-       rep
-       movsb
-       movw    $SETUPSEG, %ax
-       movw    %ax, %ds
-       movw    %dx, %ss
-end_move_self:                                 # now we are at the right place
-       lidt    idt_48                          # load idt with 0,0
-       xorl    %eax, %eax                      # Compute gdt_base
-       movw    %ds, %ax                        # (Convert %ds:gdt to a linear ptr)
-       shll    $4, %eax
-       addl    $gdt, %eax
-       movl    %eax, (gdt_48+2)
-       lgdt    gdt_48                          # load gdt with whatever is
-                                               # appropriate
-
-# that was painless, now we enable a20
-       call    empty_8042
-
-       movb    $0xD1, %al                      # command write
-       outb    %al, $0x64
-       call    empty_8042
-
-       movb    $0xDF, %al                      # A20 on
-       outb    %al, $0x60
-       call    empty_8042
-
-#
-#      You must preserve the other bits here. Otherwise embarrasing things
-#      like laptops powering off on boot happen. Corrected version by Kira
-#      Brown from Linux 2.2
-#
-       inb     $0x92, %al                      # 
-       orb     $02, %al                        # "fast A20" version
-       outb    %al, $0x92                      # some chips have only this
-
-# wait until a20 really *is* enabled; it can take a fair amount of
-# time on certain systems; Toshiba Tecras are known to have this
-# problem.  The memory location used here (0x200) is the int 0x80
-# vector, which should be safe to use.
-
-       xorw    %ax, %ax                        # segment 0x0000
-       movw    %ax, %fs
-       decw    %ax                             # segment 0xffff (HMA)
-       movw    %ax, %gs
-a20_wait:
-       incw    %ax                             # unused memory location <0xfff0
-       movw    %ax, %fs:(0x200)                # we use the "int 0x80" vector
-       cmpw    %gs:(0x210), %ax                # and its corresponding HMA addr
-       je      a20_wait                        # loop until no longer aliased
-
-# make sure any possible coprocessor is properly reset..
-       xorw    %ax, %ax
-       outb    %al, $0xf0
-       call    delay
-
-       outb    %al, $0xf1
-       call    delay
-
-# well, that went ok, I hope. Now we mask all interrupts - the rest
-# is done in init_IRQ().
-       movb    $0xFF, %al                      # mask all interrupts for now
-       outb    %al, $0xA1
-       call    delay
-       
-       movb    $0xFB, %al                      # mask all irq's but irq2 which
-       outb    %al, $0x21                      # is cascaded
-
-# Well, that certainly wasn't fun :-(. Hopefully it works, and we don't
-# need no steenking BIOS anyway (except for the initial loading :-).
-# The BIOS-routine wants lots of unnecessary data, and it's less
-# "interesting" anyway. This is how REAL programmers do it.
-#
-# Well, now's the time to actually move into protected mode. To make
-# things as simple as possible, we do no register set-up or anything,
-# we let the gnu-compiled 32-bit programs do that. We just jump to
-# absolute address 0x1000 (or the loader supplied one),
-# in 32-bit protected mode.
-#
-# Note that the short jump isn't strictly needed, although there are
-# reasons why it might be a good idea. It won't hurt in any case.
-       movw    $1, %ax                         # protected mode (PE) bit
-       lmsw    %ax                             # This is it!
-       jmp     flush_instr
-
-flush_instr:
-       xorw    %bx, %bx                        # Flag to indicate a boot
-       xorl    %esi, %esi                      # Pointer to real-mode code
-       movw    %cs, %si
-       subw    $DELTA_INITSEG, %si
-       shll    $4, %esi                        # Convert to 32-bit pointer
-# NOTE: For high loaded big kernels we need a
-#      jmpi    0x100000,__KERNEL_CS
-#
-#      but we yet haven't reloaded the CS register, so the default size 
-#      of the target offset still is 16 bit.
-#      However, using an operand prefix (0x66), the CPU will properly
-#      take our 48 bit far pointer. (INTeL 80386 Programmer's Reference
-#      Manual, Mixing 16-bit and 32-bit code, page 16-6)
-
-       .byte 0x66, 0xea                        # prefix + jmpi-opcode
-code32:        .long   0x1000                          # will be set to 0x100000
-                                               # for big kernels
-       .word   __KERNEL_CS
-
-# Here's a bunch of information about your current kernel..
-kernel_version:        .ascii  UTS_RELEASE
-               .ascii  " ("
-               .ascii  LINUX_COMPILE_BY
-               .ascii  "@"
-               .ascii  LINUX_COMPILE_HOST
-               .ascii  ") "
-               .ascii  UTS_VERSION
-               .byte   0
-
-# This is the default real mode switch routine.
-# to be called just before protected mode transition
-default_switch:
-       cli                                     # no interrupts allowed !
-       movb    $0x80, %al                      # disable NMI for bootup
-                                               # sequence
-       outb    %al, $0x70
-       lret
-
-
-# This routine checks that the keyboard command queue is empty
-# (after emptying the output buffers)
-#
-# Some machines have delusions that the keyboard buffer is always full
-# with no keyboard attached...
-#
-# If there is no keyboard controller, we will usually get 0xff
-# to all the reads.  With each IO taking a microsecond and
-# a timeout of 100,000 iterations, this can take about half a
-# second ("delay" == outb to port 0x80). That should be ok,
-# and should also be plenty of time for a real keyboard controller
-# to empty.
-#
-
-empty_8042:
-       pushl   %ecx
-       movl    $100000, %ecx
-
-empty_8042_loop:
-       decl    %ecx
-       jz      empty_8042_end_loop
-
-       call    delay
-
-       inb     $0x64, %al                      # 8042 status port
-       testb   $1, %al                         # output buffer?
-       jz      no_output
-
-       call    delay
-       inb     $0x60, %al                      # read it
-       jmp     empty_8042_loop
-
-no_output:
-       testb   $2, %al                         # is input buffer full?
-       jnz     empty_8042_loop                 # yes - loop
-empty_8042_end_loop:
-       popl    %ecx
-       ret
-
-# Read the cmos clock. Return the seconds in al
-gettime:
-       pushw   %cx
-       movb    $0x02, %ah
-       int     $0x1a
-       movb    %dh, %al                        # %dh contains the seconds
-       andb    $0x0f, %al
-       movb    %dh, %ah
-       movb    $0x04, %cl
-       shrb    %cl, %ah
-       aad
-       popw    %cx
-       ret
-
-# Delay is needed after doing I/O
-delay:
-       outb    %al,$0x80
-       ret
-
-# Descriptor tables
-gdt:
-       .word   0, 0, 0, 0                      # dummy
-
-       .word   0, 0, 0, 0                      # unused
-
-       .word   0xFFFF                          # 4Gb - (0x100000*0x1000 = 4Gb)
-       .word   0                               # base address = 0
-       .word   0x9A00                          # code read/exec
-       .word   0x00CF                          # granularity = 4096, 386
-                                               #  (+5th nibble of limit)
-
-       .word   0xFFFF                          # 4Gb - (0x100000*0x1000 = 4Gb)
-       .word   0                               # base address = 0
-       .word   0x9200                          # data read/write
-       .word   0x00CF                          # granularity = 4096, 386
-                                               #  (+5th nibble of limit)
-gdt_end:
-idt_48:
-       .word   0                               # idt limit = 0
-       .word   0, 0                            # idt base = 0L
-gdt_48:
-       .word   gdt_end-gdt-1                   # gdt limit
-       .word   0, 0                            # gdt base (filled in later)
-
-# Include video setup & detection code
-
-#include "../../i386/boot/video.S"
-
-# Setup signature -- must be last
-setup_sig1:    .word   SIG1
-setup_sig2:    .word   SIG2
-
-# After this point, there is some free space which is used by the video mode
-# handling code to store the temporary mode table (not used by the kernel).
-
-modelist:
-
-.text
-endtext:
-.data
-enddata:
-.bss
-endbss:
diff --git a/arch/x86_64/boot/tools/build.c b/arch/x86_64/boot/tools/build.c
deleted file mode 100644 (file)
index eae8669..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- *  Copyright (C) 1991, 1992  Linus Torvalds
- *  Copyright (C) 1997 Martin Mares
- */
-
-/*
- * This file builds a disk-image from three different files:
- *
- * - bootsect: compatibility mbr which prints an error message if
- *             someone tries to boot the kernel directly.
- * - setup: 8086 machine code, sets up system parm
- * - system: 80386 code for actual system
- *
- * It does some checking that all files are of the correct type, and
- * just writes the result to stdout, removing headers and padding to
- * the right amount. It also writes some system data to stderr.
- */
-
-/*
- * Changes by tytso to allow root device specification
- * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
- * Cross compiling fixes by Gertjan van Wingerde, July 1996
- * Rewritten by Martin Mares, April 1997
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/sysmacros.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <asm/boot.h>
-
-typedef unsigned char byte;
-typedef unsigned short word;
-typedef unsigned long u32;
-
-#define DEFAULT_MAJOR_ROOT 0
-#define DEFAULT_MINOR_ROOT 0
-
-/* Minimal number of setup sectors (see also bootsect.S) */
-#define SETUP_SECTS 4
-
-byte buf[1024];
-int fd;
-int is_big_kernel;
-
-void die(const char * str, ...)
-{
-       va_list args;
-       va_start(args, str);
-       vfprintf(stderr, str, args);
-       fputc('\n', stderr);
-       exit(1);
-}
-
-void file_open(const char *name)
-{
-       if ((fd = open(name, O_RDONLY, 0)) < 0)
-               die("Unable to open `%s': %m", name);
-}
-
-void usage(void)
-{
-       die("Usage: build [-b] bootsect setup system [rootdev] [> image]");
-}
-
-int main(int argc, char ** argv)
-{
-       unsigned int i, c, sz, setup_sectors;
-       u32 sys_size;
-       byte major_root, minor_root;
-       struct stat sb;
-
-       if (argc > 2 && !strcmp(argv[1], "-b"))
-         {
-           is_big_kernel = 1;
-           argc--, argv++;
-         }
-       if ((argc < 4) || (argc > 5))
-               usage();
-       if (argc > 4) {
-               if (!strcmp(argv[4], "CURRENT")) {
-                       if (stat("/", &sb)) {
-                               perror("/");
-                               die("Couldn't stat /");
-                       }
-                       major_root = major(sb.st_dev);
-                       minor_root = minor(sb.st_dev);
-               } else if (strcmp(argv[4], "FLOPPY")) {
-                       if (stat(argv[4], &sb)) {
-                               perror(argv[4]);
-                               die("Couldn't stat root device.");
-                       }
-                       major_root = major(sb.st_rdev);
-                       minor_root = minor(sb.st_rdev);
-               } else {
-                       major_root = 0;
-                       minor_root = 0;
-               }
-       } else {
-               major_root = DEFAULT_MAJOR_ROOT;
-               minor_root = DEFAULT_MINOR_ROOT;
-       }
-       fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root);
-
-       file_open(argv[1]);
-       i = read(fd, buf, sizeof(buf));
-       fprintf(stderr,"Boot sector %d bytes.\n",i);
-       if (i != 512)
-               die("Boot block must be exactly 512 bytes");
-       if (buf[510] != 0x55 || buf[511] != 0xaa)
-               die("Boot block hasn't got boot flag (0xAA55)");
-       buf[508] = minor_root;
-       buf[509] = major_root;
-       if (write(1, buf, 512) != 512)
-               die("Write call failed");
-       close (fd);
-
-       file_open(argv[2]);                                 /* Copy the setup code */
-       for (i=0 ; (c=read(fd, buf, sizeof(buf)))>0 ; i+=c )
-               if (write(1, buf, c) != c)
-                       die("Write call failed");
-       if (c != 0)
-               die("read-error on `setup'");
-       close (fd);
-
-       setup_sectors = (i + 511) / 512;        /* Pad unused space with zeros */
-       /* for compatibility with ancient versions of LILO. */
-       if (setup_sectors < SETUP_SECTS)
-               setup_sectors = SETUP_SECTS;
-       fprintf(stderr, "Setup is %d bytes.\n", i);
-       memset(buf, 0, sizeof(buf));
-       while (i < setup_sectors * 512) {
-               c = setup_sectors * 512 - i;
-               if (c > sizeof(buf))
-                       c = sizeof(buf);
-               if (write(1, buf, c) != c)
-                       die("Write call failed");
-               i += c;
-       }
-
-       file_open(argv[3]);
-       if (fstat (fd, &sb))
-               die("Unable to stat `%s': %m", argv[3]);
-       sz = sb.st_size;
-       fprintf (stderr, "System is %d kB\n", sz/1024);
-       sys_size = (sz + 15) / 16;
-       if (!is_big_kernel && sys_size > DEF_SYSSIZE)
-               die("System is too big. Try using bzImage or modules.");
-       while (sz > 0) {
-               int l, n;
-
-               l = (sz > sizeof(buf)) ? sizeof(buf) : sz;
-               if ((n=read(fd, buf, l)) != l) {
-                       if (n < 0)
-                               die("Error reading %s: %m", argv[3]);
-                       else
-                               die("%s: Unexpected EOF", argv[3]);
-               }
-               if (write(1, buf, l) != l)
-                       die("Write failed");
-               sz -= l;
-       }
-       close(fd);
-
-       if (lseek(1, 497, SEEK_SET) != 497)                 /* Write sizes to the bootsector */
-               die("Output: seek failed");
-       buf[0] = setup_sectors;
-       if (write(1, buf, 1) != 1)
-               die("Write of setup sector count failed");
-       if (lseek(1, 500, SEEK_SET) != 500)
-               die("Output: seek failed");
-       buf[0] = (sys_size & 0xff);
-       buf[1] = ((sys_size >> 8) & 0xff);
-       buf[2] = ((sys_size >> 16) & 0xff);
-       buf[3] = ((sys_size >> 24) & 0xff);
-       if (write(1, buf, 4) != 4)
-               die("Write of image length failed");
-
-       return 0;                                           /* Everything is OK */
-}
index de1de8a2fd84669e4643585e5119fa7d2e2db594..47f1dc30bf565625c86d96ff4862e685f2a72615 100644 (file)
@@ -44,6 +44,7 @@ obj-$(CONFIG_PCI)             += early-quirks.o
 
 obj-y                          += topology.o
 obj-y                          += intel_cacheinfo.o
+obj-y                          += addon_cpuid_features.o
 obj-y                          += pcspeaker.o
 
 CFLAGS_vsyscall.o              := $(PROFILING) -g0
@@ -55,6 +56,7 @@ cpuid-$(subst m,y,$(CONFIG_X86_CPUID))  += ../../i386/kernel/cpuid.o
 topology-y                     += ../../i386/kernel/topology.o
 microcode-$(subst m,y,$(CONFIG_MICROCODE))  += ../../i386/kernel/microcode.o
 intel_cacheinfo-y              += ../../i386/kernel/cpu/intel_cacheinfo.o
+addon_cpuid_features-y         += ../../i386/kernel/cpu/addon_cpuid_features.o
 quirks-y                       += ../../i386/kernel/quirks.o
 i8237-y                                += ../../i386/kernel/i8237.o
 msr-$(subst m,y,$(CONFIG_X86_MSR))  += ../../i386/kernel/msr.o
index 9f80aad3fe2da40096633bdb0a689f7f0452eb96..90f6315d02d42c062a57d0453b3ab58326a1e6a7 100644 (file)
@@ -22,8 +22,7 @@ EXPORT_SYMBOL(bad_dma_address);
 int iommu_bio_merge __read_mostly = 0;
 EXPORT_SYMBOL(iommu_bio_merge);
 
-int iommu_sac_force __read_mostly = 0;
-EXPORT_SYMBOL(iommu_sac_force);
+static int iommu_sac_force __read_mostly = 0;
 
 int no_iommu __read_mostly;
 #ifdef CONFIG_IOMMU_DEBUG
index eb6524f3ac29b00482800421ed615b674ee453de..33ef718f8cb5ee1e5cbf08c5644a25b592f685ea 100644 (file)
@@ -846,6 +846,8 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
                        c->x86_capability[2] = cpuid_edx(0x80860001);
        }
 
+       init_scattered_cpuid_features(c);
+
        c->apicid = phys_pkg_id(0);
 
        /*
@@ -931,7 +933,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
                "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
                "pat", "pse36", "pn", "clflush", NULL, "dts", "acpi", "mmx",
-               "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", NULL,
+               "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe",
 
                /* AMD-defined */
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -947,10 +949,11 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
                /* Other (Linux-defined) */
-               "cxmmx", NULL, "cyrix_arr", "centaur_mcr", NULL,
-               "constant_tsc", NULL, NULL,
-               "up", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+               "cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr",
+               NULL, NULL, NULL, NULL,
+               "constant_tsc", "up", NULL, "arch_perfmon",
+               "pebs", "bts", NULL, "sync_rdtsc",
+               "rep_good", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
                /* Intel-defined (#2) */
@@ -961,7 +964,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 
                /* VIA/Cyrix/Centaur-defined */
                NULL, NULL, "rng", "rng_en", NULL, NULL, "ace", "ace_en",
-               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+               "ace2", "ace2_en", "phe", "phe_en", "pmm", "pmm_en", NULL, NULL,
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
@@ -972,6 +975,12 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                "osvw", "ibs", NULL, NULL, NULL, NULL,
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+               /* Auxiliary (Linux-defined) */
+               "ida", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
        };
        static char *x86_power_flags[] = { 
                "ts",   /* temperature sensor */
index e035f5948199d356a7740d95ac55f21c299594b9..45b6f8a975a152b1e1a9466cd9c64fa61d1a3020 100644 (file)
@@ -37,20 +37,6 @@ verify_cpu:
        pushl   $0                      # Kill any dangerous flags
        popfl
 
-       /* minimum CPUID flags for x86-64 as defined by AMD */
-#define M(x) (1<<(x))
-#define M2(a,b) M(a)|M(b)
-#define M4(a,b,c,d) M(a)|M(b)|M(c)|M(d)
-
-#define SSE_MASK \
-       (M2(X86_FEATURE_XMM,X86_FEATURE_XMM2))
-#define REQUIRED_MASK1 \
-       (M4(X86_FEATURE_FPU,X86_FEATURE_PSE,X86_FEATURE_TSC,X86_FEATURE_MSR)|\
-        M4(X86_FEATURE_PAE,X86_FEATURE_CX8,X86_FEATURE_PGE,X86_FEATURE_CMOV)|\
-        M(X86_FEATURE_FXSR))
-#define REQUIRED_MASK2 \
-       (M(X86_FEATURE_LM - 32))
-
        pushfl                          # standard way to check for cpuid
        popl    %eax
        movl    %eax,%ebx
@@ -79,8 +65,8 @@ verify_cpu:
 verify_cpu_noamd:
        movl    $0x1,%eax               # Does the cpu have what it takes
        cpuid
-       andl    $REQUIRED_MASK1,%edx
-       xorl    $REQUIRED_MASK1,%edx
+       andl    $REQUIRED_MASK0,%edx
+       xorl    $REQUIRED_MASK0,%edx
        jnz     verify_cpu_no_longmode
 
        movl    $0x80000000,%eax        # See if extended cpuid is implemented
@@ -90,8 +76,8 @@ verify_cpu_noamd:
 
        movl    $0x80000001,%eax        # Does the cpu have what it takes
        cpuid
-       andl    $REQUIRED_MASK2,%edx
-       xorl    $REQUIRED_MASK2,%edx
+       andl    $REQUIRED_MASK1,%edx
+       xorl    $REQUIRED_MASK1,%edx
        jnz     verify_cpu_no_longmode
 
 verify_cpu_sse_test:
index a50f481116477e9552c82db45f728bc067dbbbbd..285935134bcd02cedf51cd1330ea1460aca4ca14 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Block layer core configuration
 #
-config BLOCK
+menuconfig BLOCK
        bool "Enable the block layer" if EMBEDDED
        default y
        help
@@ -49,6 +49,6 @@ config LSF
 
          If unsure, say Y.
 
-endif
+endif # BLOCK
 
 source block/Kconfig.iosched
index baef5fc7cff8b5ca3d184e3d48efdd4be7376203..e0aa4dad67424ae45bfa93150f14c1856f75140e 100644 (file)
@@ -92,6 +92,8 @@ struct cfq_data {
        struct cfq_queue *active_queue;
        struct cfq_io_context *active_cic;
 
+       struct cfq_queue *async_cfqq[IOPRIO_BE_NR];
+
        struct timer_list idle_class_timer;
 
        sector_t last_position;
@@ -1351,8 +1353,8 @@ static void cfq_ioc_set_ioprio(struct io_context *ioc)
 }
 
 static struct cfq_queue *
-cfq_get_queue(struct cfq_data *cfqd, int is_sync, struct task_struct *tsk,
-             gfp_t gfp_mask)
+cfq_find_alloc_queue(struct cfq_data *cfqd, int is_sync,
+                    struct task_struct *tsk, gfp_t gfp_mask)
 {
        struct cfq_queue *cfqq, *new_cfqq = NULL;
        struct cfq_io_context *cic;
@@ -1405,12 +1407,35 @@ retry:
        if (new_cfqq)
                kmem_cache_free(cfq_pool, new_cfqq);
 
-       atomic_inc(&cfqq->ref);
 out:
        WARN_ON((gfp_mask & __GFP_WAIT) && !cfqq);
        return cfqq;
 }
 
+static struct cfq_queue *
+cfq_get_queue(struct cfq_data *cfqd, int is_sync, struct task_struct *tsk,
+             gfp_t gfp_mask)
+{
+       const int ioprio = task_ioprio(tsk);
+       struct cfq_queue *cfqq = NULL;
+
+       if (!is_sync)
+               cfqq = cfqd->async_cfqq[ioprio];
+       if (!cfqq)
+               cfqq = cfq_find_alloc_queue(cfqd, is_sync, tsk, gfp_mask);
+
+       /*
+        * pin the queue now that it's allocated, scheduler exit will prune it
+        */
+       if (!is_sync && !cfqd->async_cfqq[ioprio]) {
+               atomic_inc(&cfqq->ref);
+               cfqd->async_cfqq[ioprio] = cfqq;
+       }
+
+       atomic_inc(&cfqq->ref);
+       return cfqq;
+}
+
 /*
  * We drop cfq io contexts lazily, so we may find a dead one.
  */
@@ -2019,6 +2044,7 @@ static void cfq_exit_queue(elevator_t *e)
 {
        struct cfq_data *cfqd = e->elevator_data;
        request_queue_t *q = cfqd->queue;
+       int i;
 
        cfq_shutdown_timer_wq(cfqd);
 
@@ -2035,6 +2061,13 @@ static void cfq_exit_queue(elevator_t *e)
                __cfq_exit_single_io_context(cfqd, cic);
        }
 
+       /*
+        * Put the async queues
+        */
+       for (i = 0; i < IOPRIO_BE_NR; i++)
+               if (cfqd->async_cfqq[i])        
+                       cfq_put_queue(cfqd->async_cfqq[i]);
+
        spin_unlock_irq(q->queue_lock);
 
        cfq_shutdown_timer_wq(cfqd);
index ce866eb75f6a997692cf4874dfe1ee8ceda216e8..4769a25d7037a555c4f700d34a9b6d5411391959 100644 (file)
@@ -112,12 +112,8 @@ static inline int elv_try_merge(struct request *__rq, struct bio *bio)
 static struct elevator_type *elevator_find(const char *name)
 {
        struct elevator_type *e;
-       struct list_head *entry;
-
-       list_for_each(entry, &elv_list) {
-
-               e = list_entry(entry, struct elevator_type, list);
 
+       list_for_each_entry(e, &elv_list, list) {
                if (!strcmp(e->elevator_name, name))
                        return e;
        }
@@ -1116,14 +1112,11 @@ ssize_t elv_iosched_show(request_queue_t *q, char *name)
 {
        elevator_t *e = q->elevator;
        struct elevator_type *elv = e->elevator_type;
-       struct list_head *entry;
+       struct elevator_type *__e;
        int len = 0;
 
        spin_lock(&elv_list_lock);
-       list_for_each(entry, &elv_list) {
-               struct elevator_type *__e;
-
-               __e = list_entry(entry, struct elevator_type, list);
+       list_for_each_entry(__e, &elv_list, list) {
                if (!strcmp(elv->elevator_name, __e->elevator_name))
                        len += sprintf(name+len, "[%s] ", elv->elevator_name);
                else
index c99b463548592239044f6e71aea571abd99a7307..ef42bb2b12b6dd89b0edc1734485e66147920759 100644 (file)
@@ -527,8 +527,6 @@ int blk_do_ordered(request_queue_t *q, struct request **rqp)
 static int flush_dry_bio_endio(struct bio *bio, unsigned int bytes, int error)
 {
        request_queue_t *q = bio->bi_private;
-       struct bio_vec *bvec;
-       int i;
 
        /*
         * This is dry run, restore bio_sector and size.  We'll finish
@@ -540,13 +538,6 @@ static int flush_dry_bio_endio(struct bio *bio, unsigned int bytes, int error)
        if (bio->bi_size)
                return 1;
 
-       /* Rewind bvec's */
-       bio->bi_idx = 0;
-       bio_for_each_segment(bvec, bio, i) {
-               bvec->bv_len += bvec->bv_offset;
-               bvec->bv_offset = 0;
-       }
-
        /* Reset bio */
        set_bit(BIO_UPTODATE, &bio->bi_flags);
        bio->bi_size = q->bi_size;
@@ -1304,9 +1295,9 @@ static int blk_hw_contig_segment(request_queue_t *q, struct bio *bio,
        if (unlikely(!bio_flagged(nxt, BIO_SEG_VALID)))
                blk_recount_segments(q, nxt);
        if (!BIOVEC_VIRT_MERGEABLE(__BVEC_END(bio), __BVEC_START(nxt)) ||
-           BIOVEC_VIRT_OVERSIZE(bio->bi_hw_front_size + bio->bi_hw_back_size))
+           BIOVEC_VIRT_OVERSIZE(bio->bi_hw_back_size + nxt->bi_hw_front_size))
                return 0;
-       if (bio->bi_size + nxt->bi_size > q->max_segment_size)
+       if (bio->bi_hw_back_size + nxt->bi_hw_front_size > q->max_segment_size)
                return 0;
 
        return 1;
index 050323fd79e9ae78f4f528ce260e08a8ec89f38b..7916f4b86d23c31eae93fbabde3a9cad6eb3dc90 100644 (file)
@@ -24,8 +24,6 @@ source "drivers/scsi/Kconfig"
 
 source "drivers/ata/Kconfig"
 
-source "drivers/cdrom/Kconfig"
-
 source "drivers/md/Kconfig"
 
 source "drivers/message/fusion/Kconfig"
@@ -54,6 +52,8 @@ source "drivers/spi/Kconfig"
 
 source "drivers/w1/Kconfig"
 
+source "drivers/power/Kconfig"
+
 source "drivers/hwmon/Kconfig"
 
 source "drivers/mfd/Kconfig"
index adad2f3d438a07929ca9842ac96fb8b3d4dac329..503d82569449f2e8eeb9884cd0ddd46919dd5a83 100644 (file)
@@ -61,6 +61,7 @@ obj-$(CONFIG_I2O)             += message/
 obj-$(CONFIG_RTC_LIB)          += rtc/
 obj-y                          += i2c/
 obj-$(CONFIG_W1)               += w1/
+obj-$(CONFIG_POWER_SUPPLY)     += power/
 obj-$(CONFIG_HWMON)            += hwmon/
 obj-$(CONFIG_PHONE)            += telephony/
 obj-$(CONFIG_MD)               += md/
index 674bf81c6e660040ab8d0136ecebd4e9f84aad66..423ed08fb6f74b8c8ac7c9c9c3d9fbcf22d380c0 100644 (file)
@@ -1246,7 +1246,7 @@ repeat:
        del_timer(&motor_off_timer);
 
        ReqCnt = 0;
-       ReqCmd = CURRENT->cmd;
+       ReqCmd = rq_data_dir(CURRENT);
        ReqBlock = CURRENT->sector;
        ReqBuffer = CURRENT->buffer;
        setup_req_params(drive);
index 689a4c3542babc00e385699fe1caf4b02c0f9103..d85520f78e68bcd7ce4c9df214493643cf171bf5 100644 (file)
@@ -439,7 +439,7 @@ static void mfm_rw_intr(void)
           a choice of command end or some data which is ready to be collected */
        /* I think we have to transfer data while the interrupt line is on and its
           not any other type of interrupt */
-       if (CURRENT->cmd == WRITE) {
+       if (rq_data_dir(CURRENT) == WRITE) {
                extern void hdc63463_writedma(void);
                if ((hdc63463_dataleft <= 0) && (!(mfm_status & STAT_CED))) {
                        printk("mfm_rw_intr: Apparent DMA write request when no more to DMA\n");
@@ -799,7 +799,7 @@ static void issue_request(unsigned int block, unsigned int nsect,
        raw_cmd.head = start_head;
        raw_cmd.cylinder = track / p->heads;
        raw_cmd.cmdtype = CURRENT->cmd;
-       raw_cmd.cmdcode = CURRENT->cmd == WRITE ? CMD_WD : CMD_RD;
+       raw_cmd.cmdcode = rq_data_dir(CURRENT) == WRITE ? CMD_WD : CMD_RD;
        raw_cmd.cmddata[0] = dev + 1;   /* DAG: +1 to get US */
        raw_cmd.cmddata[1] = raw_cmd.head;
        raw_cmd.cmddata[2] = raw_cmd.cylinder >> 8;
@@ -830,7 +830,7 @@ static void issue_request(unsigned int block, unsigned int nsect,
        hdc63463_dataleft = nsect * 256;        /* Better way? */
 
        DBG("mfm%c: %sing: CHS=%d/%d/%d, sectors=%d, buffer=0x%08lx (%p)\n",
-            raw_cmd.dev + 'a', (CURRENT->cmd == READ) ? "read" : "writ",
+            raw_cmd.dev + 'a', rq_data_dir(CURRENT) == READ ? "read" : "writ",
                       raw_cmd.cylinder,
                       raw_cmd.head,
            raw_cmd.sector, nsect, (unsigned long) Copy_buffer, CURRENT);
@@ -917,13 +917,6 @@ static void mfm_request(void)
 
                DBG("mfm_request: block after offset=%d\n", block);
 
-               if (CURRENT->cmd != READ && CURRENT->cmd != WRITE) {
-                       printk("unknown mfm-command %d\n", CURRENT->cmd);
-                       end_request(CURRENT, 0);
-                       Busy = 0;
-                       printk("mfm: continue 4\n");
-                       continue;
-               }
                issue_request(block, nsect, CURRENT);
 
                break;
index f7de02a6f497a5d61752dff2a413a7c7b4c9f43a..e1ca86dfdd661fa2a53fbf78d3207296795ea165 100644 (file)
@@ -115,7 +115,6 @@ struct acpi_processor_errata errata __read_mostly;
 
 static int acpi_processor_errata_piix4(struct pci_dev *dev)
 {
-       u8 rev = 0;
        u8 value1 = 0;
        u8 value2 = 0;
 
@@ -127,9 +126,7 @@ static int acpi_processor_errata_piix4(struct pci_dev *dev)
         * Note that 'dev' references the PIIX4 ACPI Controller.
         */
 
-       pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
-
-       switch (rev) {
+       switch (dev->revision) {
        case 0:
                ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 A-step\n"));
                break;
@@ -147,7 +144,7 @@ static int acpi_processor_errata_piix4(struct pci_dev *dev)
                break;
        }
 
-       switch (rev) {
+       switch (dev->revision) {
 
        case 0:         /* PIIX4 A-step */
        case 1:         /* PIIX4 B-step */
index 4ad8675f5a160175e61229220340d4dc0a353037..d8046a113c371ce0dc820f113fbbbb51261fbfcb 100644 (file)
@@ -309,7 +309,7 @@ config PATA_HPT3X2N
          If unsure, say N.
 
 config PATA_HPT3X3
-       tristate "HPT 343/363 PATA support (Experimental)"
+       tristate "HPT 343/363 PATA support"
        depends on PCI
        help
          This option enables support for the HPT 343/363
@@ -317,6 +317,14 @@ config PATA_HPT3X3
 
          If unsure, say N.
 
+config PATA_HPT3X3_DMA
+       bool "HPT 343/363 DMA support (Experimental)"
+       depends on PATA_HPT3X3
+       help
+         This option enables DMA support for the HPT343/363
+         controllers. Enable with care as there are still some
+         problems with DMA on this chipset.
+
 config PATA_ISAPNP
        tristate "ISA Plug and Play PATA support (Experimental)"
        depends on EXPERIMENTAL && ISAPNP
index ca5229d24d8ed8f0692b64afed88d8e14cfbac33..11e4eb9f304e92bd97498313c6600a3e7dceffe8 100644 (file)
@@ -46,7 +46,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME       "ahci"
-#define DRV_VERSION    "2.2"
+#define DRV_VERSION    "2.3"
 
 
 enum {
@@ -54,7 +54,7 @@ enum {
        AHCI_MAX_PORTS          = 32,
        AHCI_MAX_SG             = 168, /* hardware max is 64K */
        AHCI_DMA_BOUNDARY       = 0xffffffff,
-       AHCI_USE_CLUSTERING     = 0,
+       AHCI_USE_CLUSTERING     = 1,
        AHCI_MAX_CMDS           = 32,
        AHCI_CMD_SZ             = 32,
        AHCI_CMD_SLOT_SZ        = AHCI_MAX_CMDS * AHCI_CMD_SZ,
@@ -81,6 +81,7 @@ enum {
        board_ahci_vt8251       = 2,
        board_ahci_ign_iferr    = 3,
        board_ahci_sb600        = 4,
+       board_ahci_mv           = 5,
 
        /* global controller registers */
        HOST_CAP                = 0x00, /* host capabilities */
@@ -171,6 +172,8 @@ enum {
        AHCI_FLAG_HONOR_PI              = (1 << 26), /* honor PORTS_IMPL */
        AHCI_FLAG_IGN_SERR_INTERNAL     = (1 << 27), /* ignore SERR_INTERNAL */
        AHCI_FLAG_32BIT_ONLY            = (1 << 28), /* force 32bit */
+       AHCI_FLAG_MV_PATA               = (1 << 29), /* PATA port */
+       AHCI_FLAG_NO_MSI                = (1 << 30), /* no PCI MSI */
 
        AHCI_FLAG_COMMON                = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
                                          ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
@@ -228,9 +231,12 @@ static void ahci_thaw(struct ata_port *ap);
 static void ahci_error_handler(struct ata_port *ap);
 static void ahci_vt8251_error_handler(struct ata_port *ap);
 static void ahci_post_internal_cmd(struct ata_queued_cmd *qc);
+static int ahci_port_resume(struct ata_port *ap);
+static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc, void *cmd_tbl);
+static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag,
+                              u32 opts);
 #ifdef CONFIG_PM
 static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg);
-static int ahci_port_resume(struct ata_port *ap);
 static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
 static int ahci_pci_device_resume(struct pci_dev *pdev);
 #endif
@@ -327,14 +333,14 @@ static const struct ata_port_info ahci_port_info[] = {
        {
                .flags          = AHCI_FLAG_COMMON,
                .pio_mask       = 0x1f, /* pio0-4 */
-               .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
+               .udma_mask      = ATA_UDMA6,
                .port_ops       = &ahci_ops,
        },
        /* board_ahci_pi */
        {
                .flags          = AHCI_FLAG_COMMON | AHCI_FLAG_HONOR_PI,
                .pio_mask       = 0x1f, /* pio0-4 */
-               .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
+               .udma_mask      = ATA_UDMA6,
                .port_ops       = &ahci_ops,
        },
        /* board_ahci_vt8251 */
@@ -342,14 +348,14 @@ static const struct ata_port_info ahci_port_info[] = {
                .flags          = AHCI_FLAG_COMMON | ATA_FLAG_HRST_TO_RESUME |
                                  AHCI_FLAG_NO_NCQ,
                .pio_mask       = 0x1f, /* pio0-4 */
-               .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
+               .udma_mask      = ATA_UDMA6,
                .port_ops       = &ahci_vt8251_ops,
        },
        /* board_ahci_ign_iferr */
        {
                .flags          = AHCI_FLAG_COMMON | AHCI_FLAG_IGN_IRQ_IF_ERR,
                .pio_mask       = 0x1f, /* pio0-4 */
-               .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
+               .udma_mask      = ATA_UDMA6,
                .port_ops       = &ahci_ops,
        },
        /* board_ahci_sb600 */
@@ -358,7 +364,19 @@ static const struct ata_port_info ahci_port_info[] = {
                                  AHCI_FLAG_IGN_SERR_INTERNAL |
                                  AHCI_FLAG_32BIT_ONLY,
                .pio_mask       = 0x1f, /* pio0-4 */
-               .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
+               .udma_mask      = ATA_UDMA6,
+               .port_ops       = &ahci_ops,
+       },
+       /* board_ahci_mv */
+       {
+               .sht            = &ahci_sht,
+               .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+                                 ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
+                                 ATA_FLAG_SKIP_D2H_BSY | AHCI_FLAG_HONOR_PI |
+                                 AHCI_FLAG_NO_NCQ | AHCI_FLAG_NO_MSI |
+                                 AHCI_FLAG_MV_PATA,
+               .pio_mask       = 0x1f, /* pio0-4 */
+               .udma_mask      = ATA_UDMA6,
                .port_ops       = &ahci_ops,
        },
 };
@@ -456,6 +474,9 @@ static const struct pci_device_id ahci_pci_tbl[] = {
        { PCI_VDEVICE(SI, 0x1185), board_ahci }, /* SiS 966 */
        { PCI_VDEVICE(SI, 0x0186), board_ahci }, /* SiS 968 */
 
+       /* Marvell */
+       { PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv },        /* 6145 */
+
        /* Generic, PCI class code for AHCI */
        { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
          PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci },
@@ -481,11 +502,17 @@ static inline int ahci_nr_ports(u32 cap)
        return (cap & 0x1f) + 1;
 }
 
-static inline void __iomem *ahci_port_base(struct ata_port *ap)
+static inline void __iomem *__ahci_port_base(struct ata_host *host,
+                                            unsigned int port_no)
 {
-       void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
+       void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
+
+       return mmio + 0x100 + (port_no * 0x80);
+}
 
-       return mmio + 0x100 + (ap->port_no * 0x80);
+static inline void __iomem *ahci_port_base(struct ata_port *ap)
+{
+       return __ahci_port_base(ap->host, ap->port_no);
 }
 
 /**
@@ -535,6 +562,20 @@ static void ahci_save_initial_config(struct pci_dev *pdev,
                hpriv->saved_port_map = port_map;
        }
 
+       /*
+        * Temporary Marvell 6145 hack: PATA port presence
+        * is asserted through the standard AHCI port
+        * presence register, as bit 4 (counting from 0)
+        */
+       if (pi->flags & AHCI_FLAG_MV_PATA) {
+               dev_printk(KERN_ERR, &pdev->dev,
+                          "MV_AHCI HACK: port_map %x -> %x\n",
+                          hpriv->port_map,
+                          hpriv->port_map & 0xf);
+
+               port_map &= 0xf;
+       }
+
        /* cross check port_map and cap.n_ports */
        if (pi->flags & AHCI_FLAG_HONOR_PI) {
                u32 tmp_port_map = port_map;
@@ -740,7 +781,7 @@ static void ahci_power_down(struct ata_port *ap)
 }
 #endif
 
-static void ahci_init_port(struct ata_port *ap)
+static void ahci_start_port(struct ata_port *ap)
 {
        /* enable FIS reception */
        ahci_start_fis_rx(ap);
@@ -814,39 +855,62 @@ static int ahci_reset_controller(struct ata_host *host)
        return 0;
 }
 
+static void ahci_port_init(struct pci_dev *pdev, struct ata_port *ap,
+                          int port_no, void __iomem *mmio,
+                          void __iomem *port_mmio)
+{
+       const char *emsg = NULL;
+       int rc;
+       u32 tmp;
+
+       /* make sure port is not active */
+       rc = ahci_deinit_port(ap, &emsg);
+       if (rc)
+               dev_printk(KERN_WARNING, &pdev->dev,
+                          "%s (%d)\n", emsg, rc);
+
+       /* clear SError */
+       tmp = readl(port_mmio + PORT_SCR_ERR);
+       VPRINTK("PORT_SCR_ERR 0x%x\n", tmp);
+       writel(tmp, port_mmio + PORT_SCR_ERR);
+
+       /* clear port IRQ */
+       tmp = readl(port_mmio + PORT_IRQ_STAT);
+       VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp);
+       if (tmp)
+               writel(tmp, port_mmio + PORT_IRQ_STAT);
+
+       writel(1 << port_no, mmio + HOST_IRQ_STAT);
+}
+
 static void ahci_init_controller(struct ata_host *host)
 {
        struct pci_dev *pdev = to_pci_dev(host->dev);
        void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
-       int i, rc;
+       int i;
+       void __iomem *port_mmio;
        u32 tmp;
 
-       for (i = 0; i < host->n_ports; i++) {
-               struct ata_port *ap = host->ports[i];
-               void __iomem *port_mmio = ahci_port_base(ap);
-               const char *emsg = NULL;
-
-               if (ata_port_is_dummy(ap))
-                       continue;
-
-               /* make sure port is not active */
-               rc = ahci_deinit_port(ap, &emsg);
-               if (rc)
-                       dev_printk(KERN_WARNING, &pdev->dev,
-                                  "%s (%d)\n", emsg, rc);
+       if (host->ports[0]->flags & AHCI_FLAG_MV_PATA) {
+               port_mmio = __ahci_port_base(host, 4);
 
-               /* clear SError */
-               tmp = readl(port_mmio + PORT_SCR_ERR);
-               VPRINTK("PORT_SCR_ERR 0x%x\n", tmp);
-               writel(tmp, port_mmio + PORT_SCR_ERR);
+               writel(0, port_mmio + PORT_IRQ_MASK);
 
                /* clear port IRQ */
                tmp = readl(port_mmio + PORT_IRQ_STAT);
                VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp);
                if (tmp)
                        writel(tmp, port_mmio + PORT_IRQ_STAT);
+       }
 
-               writel(1 << i, mmio + HOST_IRQ_STAT);
+       for (i = 0; i < host->n_ports; i++) {
+               struct ata_port *ap = host->ports[i];
+
+               port_mmio = ahci_port_base(ap);
+               if (ata_port_is_dummy(ap))
+                       continue;
+
+               ahci_port_init(pdev, ap, i, mmio, port_mmio);
        }
 
        tmp = readl(mmio + HOST_CTL);
@@ -1232,7 +1296,7 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)
                ata_port_abort(ap);
 }
 
-static void ahci_host_intr(struct ata_port *ap)
+static void ahci_port_intr(struct ata_port *ap)
 {
        void __iomem *port_mmio = ap->ioaddr.cmd_addr;
        struct ata_eh_info *ehi = &ap->eh_info;
@@ -1358,7 +1422,7 @@ static irqreturn_t ahci_interrupt(int irq, void *dev_instance)
 
                ap = host->ports[i];
                if (ap) {
-                       ahci_host_intr(ap);
+                       ahci_port_intr(ap);
                        VPRINTK("port %u\n", i);
                } else {
                        VPRINTK("port %u (no irq)\n", i);
@@ -1466,7 +1530,7 @@ static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg)
                ahci_power_down(ap);
        else {
                ata_port_printk(ap, KERN_ERR, "%s (%d)\n", emsg, rc);
-               ahci_init_port(ap);
+               ahci_start_port(ap);
        }
 
        return rc;
@@ -1475,7 +1539,7 @@ static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg)
 static int ahci_port_resume(struct ata_port *ap)
 {
        ahci_power_up(ap);
-       ahci_init_port(ap);
+       ahci_start_port(ap);
 
        return 0;
 }
@@ -1573,13 +1637,8 @@ static int ahci_port_start(struct ata_port *ap)
 
        ap->private_data = pp;
 
-       /* power up port */
-       ahci_power_up(ap);
-
-       /* initialize port */
-       ahci_init_port(ap);
-
-       return 0;
+       /* engage engines, captain */
+       return ahci_port_resume(ap);
 }
 
 static void ahci_port_stop(struct ata_port *ap)
@@ -1724,7 +1783,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (rc)
                return rc;
 
-       if (pci_enable_msi(pdev))
+       if ((pi.flags & AHCI_FLAG_NO_MSI) || pci_enable_msi(pdev))
                pci_intx(pdev, 1);
 
        hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
@@ -1745,14 +1804,18 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        host->private_data = hpriv;
 
        for (i = 0; i < host->n_ports; i++) {
-               if (hpriv->port_map & (1 << i)) {
-                       struct ata_port *ap = host->ports[i];
-                       void __iomem *port_mmio = ahci_port_base(ap);
+               struct ata_port *ap = host->ports[i];
+               void __iomem *port_mmio = ahci_port_base(ap);
 
+               /* standard SATA port setup */
+               if (hpriv->port_map & (1 << i)) {
                        ap->ioaddr.cmd_addr = port_mmio;
                        ap->ioaddr.scr_addr = port_mmio + PORT_SCR;
-               } else
-                       host->ports[i]->ops = &ata_dummy_port_ops;
+               }
+
+               /* disabled/not-implemented port */
+               else
+                       ap->ops = &ata_dummy_port_ops;
        }
 
        /* initialize adapter */
index 4c6e95c95e4a7a5715d1e2053e18eb07bda6d998..430fcf4f9ef3be67d98e6896607f1554b9e1926c 100644 (file)
@@ -143,10 +143,10 @@ static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id
        u16 command;
        static const struct ata_port_info info = {
                .sht = &generic_sht,
-               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
-               .udma_mask = 0x3f,
+               .udma_mask = ATA_UDMA5,
                .port_ops = &generic_port_ops
        };
        const struct ata_port_info *ppi[] = { &info, NULL };
index 9c07b88631be6d50635d292d67fa632996c57e4f..d9fa329fd157741f12b83be996e8b7d419052044 100644 (file)
@@ -200,6 +200,8 @@ static const struct pci_device_id piix_pci_tbl[] = {
        /* ICH7/7-R (i945, i975) UDMA 100*/
        { 0x8086, 0x27DF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_133 },
        { 0x8086, 0x269E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
+       /* ICH8 Mobile PATA Controller */
+       { 0x8086, 0x2850, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
 
        /* NOTE: The following PCI ids must be kept in sync with the
         * list in drivers/pci/quirks.c.
@@ -412,7 +414,7 @@ static const struct piix_map_db ich6m_map_db = {
         */
        .map = {
                /* PM   PS   SM   SS       MAP */
-               {  P0,  P2,  RV,  RV }, /* 00b */
+               {  P0,  P2,  NA,  NA }, /* 00b */
                { IDE, IDE,  P1,  P3 }, /* 01b */
                {  P0,  P2, IDE, IDE }, /* 10b */
                {  RV,  RV,  RV,  RV },
@@ -495,7 +497,7 @@ static struct ata_port_info piix_port_info[] = {
                .flags          = PIIX_SATA_FLAGS,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma0-2 */
-               .udma_mask      = 0x7f, /* udma0-6 */
+               .udma_mask      = ATA_UDMA6,
                .port_ops       = &piix_sata_ops,
        },
 
@@ -505,7 +507,7 @@ static struct ata_port_info piix_port_info[] = {
                .flags          = PIIX_SATA_FLAGS | PIIX_FLAG_SCR,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma0-2 */
-               .udma_mask      = 0x7f, /* udma0-6 */
+               .udma_mask      = ATA_UDMA6,
                .port_ops       = &piix_sata_ops,
        },
 
@@ -516,7 +518,7 @@ static struct ata_port_info piix_port_info[] = {
                                  PIIX_FLAG_AHCI,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma0-2 */
-               .udma_mask      = 0x7f, /* udma0-6 */
+               .udma_mask      = ATA_UDMA6,
                .port_ops       = &piix_sata_ops,
        },
 
@@ -527,7 +529,7 @@ static struct ata_port_info piix_port_info[] = {
                                  PIIX_FLAG_AHCI,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma0-2 */
-               .udma_mask      = 0x7f, /* udma0-6 */
+               .udma_mask      = ATA_UDMA6,
                .port_ops       = &piix_sata_ops,
        },
 
@@ -538,7 +540,7 @@ static struct ata_port_info piix_port_info[] = {
                                  PIIX_FLAG_AHCI,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma0-2 */
-               .udma_mask      = 0x7f, /* udma0-6 */
+               .udma_mask      = ATA_UDMA6,
                .port_ops       = &piix_sata_ops,
        },
 
@@ -685,8 +687,14 @@ static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev)
        if (adev->class == ATA_DEV_ATA)
                control |= 4;   /* PPE enable */
 
+       /* PIO configuration clears DTE unconditionally.  It will be
+        * programmed in set_dmamode which is guaranteed to be called
+        * after set_piomode if any DMA mode is available.
+        */
        pci_read_config_word(dev, master_port, &master_data);
        if (is_slave) {
+               /* clear TIME1|IE1|PPE1|DTE1 */
+               master_data &= 0xff0f;
                /* Enable SITRE (seperate slave timing register) */
                master_data |= 0x4000;
                /* enable PPE1, IE1 and TIME1 as needed */
@@ -694,12 +702,14 @@ static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev)
                pci_read_config_byte(dev, slave_port, &slave_data);
                slave_data &= (ap->port_no ? 0x0f : 0xf0);
                /* Load the timing nibble for this slave */
-               slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) << (ap->port_no ? 4 : 0);
+               slave_data |= ((timings[pio][0] << 2) | timings[pio][1])
+                                               << (ap->port_no ? 4 : 0);
        } else {
-               /* Master keeps the bits in a different format */
-               master_data &= 0xccf8;
+               /* clear ISP|RCT|TIME0|IE0|PPE0|DTE0 */
+               master_data &= 0xccf0;
                /* Enable PPE, IE and TIME as appropriate */
                master_data |= control;
+               /* load ISP and RCT */
                master_data |=
                        (timings[pio][0] << 12) |
                        (timings[pio][1] << 8);
@@ -816,7 +826,7 @@ static void do_pata_set_dmamode (struct ata_port *ap, struct ata_device *adev, i
                        master_data &= 0xFF4F;  /* Mask out IORDY|TIME1|DMAONLY */
                        master_data |= control << 4;
                        pci_read_config_byte(dev, 0x44, &slave_data);
-                       slave_data &= (0x0F + 0xE1 * ap->port_no);
+                       slave_data &= (ap->port_no ? 0x0f : 0xf0);
                        /* Load the matching timing */
                        slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) << (ap->port_no ? 4 : 0);
                        pci_write_config_byte(dev, 0x44, slave_data);
@@ -828,8 +838,11 @@ static void do_pata_set_dmamode (struct ata_port *ap, struct ata_device *adev, i
                                (timings[pio][0] << 12) |
                                (timings[pio][1] << 8);
                }
-               udma_enable &= ~(1 << devid);
-               pci_write_config_word(dev, master_port, master_data);
+
+               if (ap->udma_mask) {
+                       udma_enable &= ~(1 << devid);
+                       pci_write_config_word(dev, master_port, master_data);
+               }
        }
        /* Don't scribble on 0x48 if the controller does not support UDMA */
        if (ap->udma_mask)
@@ -915,20 +928,18 @@ static int __devinit piix_check_450nx_errata(struct pci_dev *ata_dev)
 {
        struct pci_dev *pdev = NULL;
        u16 cfg;
-       u8 rev;
        int no_piix_dma = 0;
 
        while((pdev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, pdev)) != NULL)
        {
                /* Look for 450NX PXB. Check for problem configurations
                   A PCI quirk checks bit 6 already */
-               pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
                pci_read_config_word(pdev, 0x41, &cfg);
                /* Only on the original revision: IDE DMA can hang */
-               if (rev == 0x00)
+               if (pdev->revision == 0x00)
                        no_piix_dma = 1;
                /* On all revisions below 5 PXB bus lock must be disabled for IDE */
-               else if (cfg & (1<<14) && rev < 5)
+               else if (cfg & (1<<14) && pdev->revision < 5)
                        no_piix_dma = 2;
        }
        if (no_piix_dma)
index 02236739b40f73787dfbd5cb40204117dd44be6f..c059f78ad944dc18a3372f63a49a14b4b0179441 100644 (file)
 #include <acpi/acmacros.h>
 #include <acpi/actypes.h>
 
-#define SATA_ROOT_PORT(x)      (((x) >> 16) & 0xffff)
-#define SATA_PORT_NUMBER(x)    ((x) & 0xffff)  /* or NO_PORT_MULT */
 #define NO_PORT_MULT           0xffff
-#define SATA_ADR_RSVD          0xffffffff
+#define SATA_ADR(root,pmp)     (((root) << 16) | (pmp))
 
 #define REGS_PER_GTF           7
-struct taskfile_array {
-       u8      tfa[REGS_PER_GTF];      /* regs. 0x1f1 - 0x1f7 */
-};
+struct ata_acpi_gtf {
+       u8      tf[REGS_PER_GTF];       /* regs. 0x1f1 - 0x1f7 */
+} __packed;
 
 /*
  *     Helper - belongs in the PCI layer somewhere eventually
@@ -42,237 +40,173 @@ static int is_pci_dev(struct device *dev)
        return (dev->bus == &pci_bus_type);
 }
 
+static void ata_acpi_associate_sata_port(struct ata_port *ap)
+{
+       acpi_integer adr = SATA_ADR(ap->port_no, NO_PORT_MULT);
+
+       ap->device->acpi_handle = acpi_get_child(ap->host->acpi_handle, adr);
+}
+
+static void ata_acpi_associate_ide_port(struct ata_port *ap)
+{
+       int max_devices, i;
+
+       ap->acpi_handle = acpi_get_child(ap->host->acpi_handle, ap->port_no);
+       if (!ap->acpi_handle)
+               return;
+
+       max_devices = 1;
+       if (ap->flags & ATA_FLAG_SLAVE_POSS)
+               max_devices++;
+
+       for (i = 0; i < max_devices; i++) {
+               struct ata_device *dev = &ap->device[i];
+
+               dev->acpi_handle = acpi_get_child(ap->acpi_handle, i);
+       }
+}
+
 /**
- * sata_get_dev_handle - finds acpi_handle and PCI device.function
- * @dev: device to locate
- * @handle: returned acpi_handle for @dev
- * @pcidevfn: return PCI device.func for @dev
+ * ata_acpi_associate - associate ATA host with ACPI objects
+ * @host: target ATA host
+ *
+ * Look up ACPI objects associated with @host and initialize
+ * acpi_handle fields of @host, its ports and devices accordingly.
  *
- * This function is somewhat SATA-specific.  Or at least the
- * PATA & SATA versions of this function are different,
- * so it's not entirely generic code.
+ * LOCKING:
+ * EH context.
  *
- * Returns 0 on success, <0 on error.
+ * RETURNS:
+ * 0 on success, -errno on failure.
  */
-static int sata_get_dev_handle(struct device *dev, acpi_handle *handle,
-                                       acpi_integer *pcidevfn)
+void ata_acpi_associate(struct ata_host *host)
 {
-       struct pci_dev  *pci_dev;
-       acpi_integer    addr;
-
-       if (!is_pci_dev(dev))
-               return -ENODEV;
-
-       pci_dev = to_pci_dev(dev);      /* NOTE: PCI-specific */
-       /* Please refer to the ACPI spec for the syntax of _ADR. */
-       addr = (PCI_SLOT(pci_dev->devfn) << 16) | PCI_FUNC(pci_dev->devfn);
-       *pcidevfn = addr;
-       *handle = acpi_get_child(DEVICE_ACPI_HANDLE(dev->parent), addr);
-       if (!*handle)
-               return -ENODEV;
-       return 0;
+       int i;
+
+       if (!is_pci_dev(host->dev) || libata_noacpi)
+               return;
+
+       host->acpi_handle = DEVICE_ACPI_HANDLE(host->dev);
+       if (!host->acpi_handle)
+               return;
+
+       for (i = 0; i < host->n_ports; i++) {
+               struct ata_port *ap = host->ports[i];
+
+               if (host->ports[0]->flags & ATA_FLAG_ACPI_SATA)
+                       ata_acpi_associate_sata_port(ap);
+               else
+                       ata_acpi_associate_ide_port(ap);
+       }
 }
 
 /**
- * pata_get_dev_handle - finds acpi_handle and PCI device.function
- * @dev: device to locate
- * @handle: returned acpi_handle for @dev
- * @pcidevfn: return PCI device.func for @dev
+ * ata_acpi_gtm - execute _GTM
+ * @ap: target ATA port
+ * @gtm: out parameter for _GTM result
+ *
+ * Evaluate _GTM and store the result in @gtm.
  *
- * The PATA and SATA versions of this function are different.
+ * LOCKING:
+ * EH context.
  *
- * Returns 0 on success, <0 on error.
+ * RETURNS:
+ * 0 on success, -ENOENT if _GTM doesn't exist, -errno on failure.
  */
-static int pata_get_dev_handle(struct device *dev, acpi_handle *handle,
-                               acpi_integer *pcidevfn)
+static int ata_acpi_gtm(const struct ata_port *ap, struct ata_acpi_gtm *gtm)
 {
-       unsigned int bus, devnum, func;
-       acpi_integer addr;
-       acpi_handle dev_handle, parent_handle;
-       struct acpi_buffer buffer = {.length = ACPI_ALLOCATE_BUFFER,
-                                       .pointer = NULL};
+       struct acpi_buffer output = { .length = ACPI_ALLOCATE_BUFFER };
+       union acpi_object *out_obj;
        acpi_status status;
-       struct acpi_device_info *dinfo = NULL;
-       int ret = -ENODEV;
-       struct pci_dev *pdev;
-
-       if (!is_pci_dev(dev))
-               return -ENODEV;
-
-       pdev = to_pci_dev(dev);
-
-       bus = pdev->bus->number;
-       devnum = PCI_SLOT(pdev->devfn);
-       func = PCI_FUNC(pdev->devfn);
-
-       dev_handle = DEVICE_ACPI_HANDLE(dev);
-       parent_handle = DEVICE_ACPI_HANDLE(dev->parent);
-
-       status = acpi_get_object_info(parent_handle, &buffer);
-       if (ACPI_FAILURE(status))
-               goto err;
-
-       dinfo = buffer.pointer;
-       if (dinfo && (dinfo->valid & ACPI_VALID_ADR) &&
-           dinfo->address == bus) {
-               /* ACPI spec for _ADR for PCI bus: */
-               addr = (acpi_integer)(devnum << 16 | func);
-               *pcidevfn = addr;
-               *handle = dev_handle;
-       } else {
-               goto err;
+       int rc = 0;
+
+       status = acpi_evaluate_object(ap->acpi_handle, "_GTM", NULL, &output);
+
+       rc = -ENOENT;
+       if (status == AE_NOT_FOUND)
+               goto out_free;
+
+       rc = -EINVAL;
+       if (ACPI_FAILURE(status)) {
+               ata_port_printk(ap, KERN_ERR,
+                               "ACPI get timing mode failed (AE 0x%x)\n",
+                               status);
+               goto out_free;
        }
 
-       if (!*handle)
-               goto err;
-       ret = 0;
-err:
-       kfree(dinfo);
-       return ret;
-}
+       out_obj = output.pointer;
+       if (out_obj->type != ACPI_TYPE_BUFFER) {
+               ata_port_printk(ap, KERN_WARNING,
+                               "_GTM returned unexpected object type 0x%x\n",
+                               out_obj->type);
 
-struct walk_info {             /* can be trimmed some */
-       struct device   *dev;
-       struct acpi_device *adev;
-       acpi_handle     handle;
-       acpi_integer    pcidevfn;
-       unsigned int    drivenum;
-       acpi_handle     obj_handle;
-       struct ata_port *ataport;
-       struct ata_device *atadev;
-       u32             sata_adr;
-       int             status;
-       char            basepath[ACPI_PATHNAME_MAX];
-       int             basepath_len;
-};
-
-static acpi_status get_devices(acpi_handle handle,
-                               u32 level, void *context, void **return_value)
-{
-       acpi_status             status;
-       struct walk_info        *winfo = context;
-       struct acpi_buffer      namebuf = {ACPI_ALLOCATE_BUFFER, NULL};
-       char                    *pathname;
-       struct acpi_buffer      buffer;
-       struct acpi_device_info *dinfo;
-
-       status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &namebuf);
-       if (status)
-               goto ret;
-       pathname = namebuf.pointer;
-
-       buffer.length = ACPI_ALLOCATE_BUFFER;
-       buffer.pointer = NULL;
-       status = acpi_get_object_info(handle, &buffer);
-       if (ACPI_FAILURE(status))
-               goto out2;
-
-       dinfo = buffer.pointer;
-
-       /* find full device path name for pcidevfn */
-       if (dinfo && (dinfo->valid & ACPI_VALID_ADR) &&
-           dinfo->address == winfo->pcidevfn) {
-               if (ata_msg_probe(winfo->ataport))
-                       ata_dev_printk(winfo->atadev, KERN_DEBUG,
-                               ":%s: matches pcidevfn (0x%llx)\n",
-                               pathname, winfo->pcidevfn);
-               strlcpy(winfo->basepath, pathname,
-                       sizeof(winfo->basepath));
-               winfo->basepath_len = strlen(pathname);
-               goto out;
+               goto out_free;
        }
 
-       /* if basepath is not yet known, ignore this object */
-       if (!winfo->basepath_len)
-               goto out;
-
-       /* if this object is in scope of basepath, maybe use it */
-       if (strncmp(pathname, winfo->basepath,
-           winfo->basepath_len) == 0) {
-               if (!(dinfo->valid & ACPI_VALID_ADR))
-                       goto out;
-               if (ata_msg_probe(winfo->ataport))
-                       ata_dev_printk(winfo->atadev, KERN_DEBUG,
-                               "GOT ONE: (%s) root_port = 0x%llx,"
-                               " port_num = 0x%llx\n", pathname,
-                               SATA_ROOT_PORT(dinfo->address),
-                               SATA_PORT_NUMBER(dinfo->address));
-               /* heuristics: */
-               if (SATA_PORT_NUMBER(dinfo->address) != NO_PORT_MULT)
-                       if (ata_msg_probe(winfo->ataport))
-                               ata_dev_printk(winfo->atadev,
-                                       KERN_DEBUG, "warning: don't"
-                                       " know how to handle SATA port"
-                                       " multiplier\n");
-               if (SATA_ROOT_PORT(dinfo->address) ==
-                       winfo->ataport->port_no &&
-                   SATA_PORT_NUMBER(dinfo->address) == NO_PORT_MULT) {
-                       if (ata_msg_probe(winfo->ataport))
-                               ata_dev_printk(winfo->atadev,
-                                       KERN_DEBUG,
-                                       "THIS ^^^^^ is the requested"
-                                       " SATA drive (handle = 0x%p)\n",
-                                       handle);
-                       winfo->sata_adr = dinfo->address;
-                       winfo->obj_handle = handle;
-               }
+       if (out_obj->buffer.length != sizeof(struct ata_acpi_gtm)) {
+               ata_port_printk(ap, KERN_ERR,
+                               "_GTM returned invalid length %d\n",
+                               out_obj->buffer.length);
+               goto out_free;
        }
-out:
-       kfree(dinfo);
-out2:
-       kfree(pathname);
 
-ret:
-       return status;
+       memcpy(gtm, out_obj->buffer.pointer, sizeof(struct ata_acpi_gtm));
+       rc = 0;
+ out_free:
+       kfree(output.pointer);
+       return rc;
 }
 
-/* Get the SATA drive _ADR object. */
-static int get_sata_adr(struct device *dev, acpi_handle handle,
-                       acpi_integer pcidevfn, unsigned int drive,
-                       struct ata_port *ap,
-                       struct ata_device *atadev, u32 *dev_adr)
+/**
+ * ata_acpi_stm - execute _STM
+ * @ap: target ATA port
+ * @stm: timing parameter to _STM
+ *
+ * Evaluate _STM with timing parameter @stm.
+ *
+ * LOCKING:
+ * EH context.
+ *
+ * RETURNS:
+ * 0 on success, -ENOENT if _STM doesn't exist, -errno on failure.
+ */
+static int ata_acpi_stm(const struct ata_port *ap, struct ata_acpi_gtm *stm)
 {
-       acpi_status     status;
-       struct walk_info *winfo;
-       int             err = -ENOMEM;
-
-       winfo = kzalloc(sizeof(struct walk_info), GFP_KERNEL);
-       if (!winfo)
-               goto out;
-
-       winfo->dev = dev;
-       winfo->atadev = atadev;
-       winfo->ataport = ap;
-       if (acpi_bus_get_device(handle, &winfo->adev) < 0)
-               if (ata_msg_probe(ap))
-                       ata_dev_printk(winfo->atadev, KERN_DEBUG,
-                               "acpi_bus_get_device failed\n");
-       winfo->handle = handle;
-       winfo->pcidevfn = pcidevfn;
-       winfo->drivenum = drive;
+       acpi_status status;
+       struct acpi_object_list         input;
+       union acpi_object               in_params[3];
 
-       status = acpi_get_devices(NULL, get_devices, winfo, NULL);
+       in_params[0].type = ACPI_TYPE_BUFFER;
+       in_params[0].buffer.length = sizeof(struct ata_acpi_gtm);
+       in_params[0].buffer.pointer = (u8 *)stm;
+       /* Buffers for id may need byteswapping ? */
+       in_params[1].type = ACPI_TYPE_BUFFER;
+       in_params[1].buffer.length = 512;
+       in_params[1].buffer.pointer = (u8 *)ap->device[0].id;
+       in_params[2].type = ACPI_TYPE_BUFFER;
+       in_params[2].buffer.length = 512;
+       in_params[2].buffer.pointer = (u8 *)ap->device[1].id;
+
+       input.count = 3;
+       input.pointer = in_params;
+
+       status = acpi_evaluate_object(ap->acpi_handle, "_STM", &input, NULL);
+
+       if (status == AE_NOT_FOUND)
+               return -ENOENT;
        if (ACPI_FAILURE(status)) {
-               if (ata_msg_probe(ap))
-                       ata_dev_printk(winfo->atadev, KERN_DEBUG,
-                               "%s: acpi_get_devices failed\n",
-                               __FUNCTION__);
-               err = -ENODEV;
-       } else {
-               *dev_adr = winfo->sata_adr;
-               atadev->obj_handle = winfo->obj_handle;
-               err = 0;
+               ata_port_printk(ap, KERN_ERR,
+                       "ACPI set timing mode failed (status=0x%x)\n", status);
+               return -EINVAL;
        }
-       kfree(winfo);
-out:
-       return err;
+       return 0;
 }
 
 /**
- * do_drive_get_GTF - get the drive bootup default taskfile settings
+ * ata_dev_get_GTF - get the drive bootup default taskfile settings
  * @dev: target ATA device
- * @gtf_length: number of bytes of _GTF data returned at @gtf_address
- * @gtf_address: buffer containing _GTF taskfile arrays
+ * @gtf: output parameter for buffer containing _GTF taskfile arrays
+ * @ptr_to_free: pointer which should be freed
  *
  * This applies to both PATA and SATA drives.
  *
@@ -282,121 +216,41 @@ out:
  * The <variable number> is not known in advance, so have ACPI-CA
  * allocate the buffer as needed and return it, then free it later.
  *
- * The returned @gtf_length and @gtf_address are only valid if the
- * function return value is 0.
+ * LOCKING:
+ * EH context.
+ *
+ * RETURNS:
+ * Number of taskfiles on success, 0 if _GTF doesn't exist or doesn't
+ * contain valid data.  -errno on other errors.
  */
-static int do_drive_get_GTF(struct ata_device *dev, unsigned int *gtf_length,
-                           unsigned long *gtf_address, unsigned long *obj_loc)
+static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf,
+                          void **ptr_to_free)
 {
        struct ata_port *ap = dev->ap;
        acpi_status status;
-       acpi_handle dev_handle = NULL;
-       acpi_handle chan_handle, drive_handle;
-       acpi_integer pcidevfn = 0;
-       u32 dev_adr;
        struct acpi_buffer output;
        union acpi_object *out_obj;
-       struct device *gdev = ap->host->dev;
-       int err = -ENODEV;
+       int rc = 0;
 
-       *gtf_length = 0;
-       *gtf_address = 0UL;
-       *obj_loc = 0UL;
-
-       if (libata_noacpi)
-               return 0;
+       /* set up output buffer */
+       output.length = ACPI_ALLOCATE_BUFFER;
+       output.pointer = NULL;  /* ACPI-CA sets this; save/free it later */
 
        if (ata_msg_probe(ap))
                ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER: port#: %d\n",
                               __FUNCTION__, ap->port_no);
 
-       if (!ata_dev_enabled(dev) || (ap->flags & ATA_FLAG_DISABLED)) {
-               if (ata_msg_probe(ap))
-                       ata_dev_printk(dev, KERN_DEBUG, "%s: ERR: "
-                               "ata_dev_present: %d, PORT_DISABLED: %lu\n",
-                               __FUNCTION__, ata_dev_enabled(dev),
-                               ap->flags & ATA_FLAG_DISABLED);
-               goto out;
-       }
-
-       /* Don't continue if device has no _ADR method.
-        * _GTF is intended for known motherboard devices. */
-       if (!(ap->flags & ATA_FLAG_ACPI_SATA)) {
-               err = pata_get_dev_handle(gdev, &dev_handle, &pcidevfn);
-               if (err < 0) {
-                       if (ata_msg_probe(ap))
-                               ata_dev_printk(dev, KERN_DEBUG,
-                                       "%s: pata_get_dev_handle failed (%d)\n",
-                                       __FUNCTION__, err);
-                       goto out;
-               }
-       } else {
-               err = sata_get_dev_handle(gdev, &dev_handle, &pcidevfn);
-               if (err < 0) {
-                       if (ata_msg_probe(ap))
-                               ata_dev_printk(dev, KERN_DEBUG,
-                                       "%s: sata_get_dev_handle failed (%d\n",
-                                       __FUNCTION__, err);
-                       goto out;
-               }
-       }
-
-       /* Get this drive's _ADR info. if not already known. */
-       if (!dev->obj_handle) {
-               if (!(ap->flags & ATA_FLAG_ACPI_SATA)) {
-                       /* get child objects of dev_handle == channel objects,
-                        * + _their_ children == drive objects */
-                       /* channel is ap->port_no */
-                       chan_handle = acpi_get_child(dev_handle,
-                                               ap->port_no);
-                       if (ata_msg_probe(ap))
-                               ata_dev_printk(dev, KERN_DEBUG,
-                                       "%s: chan adr=%d: chan_handle=0x%p\n",
-                                       __FUNCTION__, ap->port_no,
-                                       chan_handle);
-                       if (!chan_handle) {
-                               err = -ENODEV;
-                               goto out;
-                       }
-                       /* TBD: could also check ACPI object VALID bits */
-                       drive_handle = acpi_get_child(chan_handle, dev->devno);
-                       if (!drive_handle) {
-                               err = -ENODEV;
-                               goto out;
-                       }
-                       dev_adr = dev->devno;
-                       dev->obj_handle = drive_handle;
-               } else {        /* for SATA mode */
-                       dev_adr = SATA_ADR_RSVD;
-                       err = get_sata_adr(gdev, dev_handle, pcidevfn, 0,
-                                       ap, dev, &dev_adr);
-               }
-               if (err < 0 || dev_adr == SATA_ADR_RSVD ||
-                   !dev->obj_handle) {
-                       if (ata_msg_probe(ap))
-                               ata_dev_printk(dev, KERN_DEBUG,
-                                       "%s: get_sata/pata_adr failed: "
-                                       "err=%d, dev_adr=%u, obj_handle=0x%p\n",
-                                       __FUNCTION__, err, dev_adr,
-                                       dev->obj_handle);
-                       goto out;
-               }
-       }
-
-       /* Setting up output buffer */
-       output.length = ACPI_ALLOCATE_BUFFER;
-       output.pointer = NULL;  /* ACPI-CA sets this; save/free it later */
-
        /* _GTF has no input parameters */
-       err = -EIO;
-       status = acpi_evaluate_object(dev->obj_handle, "_GTF",
-                                       NULL, &output);
+       status = acpi_evaluate_object(dev->acpi_handle, "_GTF", NULL, &output);
+
        if (ACPI_FAILURE(status)) {
-               if (ata_msg_probe(ap))
-                       ata_dev_printk(dev, KERN_DEBUG,
-                               "%s: Run _GTF error: status = 0x%x\n",
-                               __FUNCTION__, status);
-               goto out;
+               if (status != AE_NOT_FOUND) {
+                       ata_dev_printk(dev, KERN_WARNING,
+                                      "_GTF evaluation failed (AE 0x%x)\n",
+                                      status);
+                       rc = -EIO;
+               }
+               goto out_free;
        }
 
        if (!output.length || !output.pointer) {
@@ -406,43 +260,39 @@ static int do_drive_get_GTF(struct ata_device *dev, unsigned int *gtf_length,
                                __FUNCTION__,
                                (unsigned long long)output.length,
                                output.pointer);
-               kfree(output.pointer);
-               goto out;
+               goto out_free;
        }
 
        out_obj = output.pointer;
        if (out_obj->type != ACPI_TYPE_BUFFER) {
-               kfree(output.pointer);
-               if (ata_msg_probe(ap))
-                       ata_dev_printk(dev, KERN_DEBUG, "%s: Run _GTF: "
-                               "error: expected object type of "
-                               " ACPI_TYPE_BUFFER, got 0x%x\n",
-                               __FUNCTION__, out_obj->type);
-               err = -ENOENT;
-               goto out;
+               ata_dev_printk(dev, KERN_WARNING,
+                              "_GTF unexpected object type 0x%x\n",
+                              out_obj->type);
+               rc = -EINVAL;
+               goto out_free;
        }
 
-       if (!out_obj->buffer.length || !out_obj->buffer.pointer ||
-           out_obj->buffer.length % REGS_PER_GTF) {
-               if (ata_msg_drv(ap))
-                       ata_dev_printk(dev, KERN_ERR,
-                               "%s: unexpected GTF length (%d) or addr (0x%p)\n",
-                               __FUNCTION__, out_obj->buffer.length,
-                               out_obj->buffer.pointer);
-               err = -ENOENT;
-               goto out;
+       if (out_obj->buffer.length % REGS_PER_GTF) {
+               ata_dev_printk(dev, KERN_WARNING,
+                              "unexpected _GTF length (%d)\n",
+                              out_obj->buffer.length);
+               rc = -EINVAL;
+               goto out_free;
        }
 
-       *gtf_length = out_obj->buffer.length;
-       *gtf_address = (unsigned long)out_obj->buffer.pointer;
-       *obj_loc = (unsigned long)out_obj;
+       *ptr_to_free = out_obj;
+       *gtf = (void *)out_obj->buffer.pointer;
+       rc = out_obj->buffer.length / REGS_PER_GTF;
+
        if (ata_msg_probe(ap))
                ata_dev_printk(dev, KERN_DEBUG, "%s: returning "
-                       "gtf_length=%d, gtf_address=0x%lx, obj_loc=0x%lx\n",
-                       __FUNCTION__, *gtf_length, *gtf_address, *obj_loc);
-       err = 0;
-out:
-       return err;
+                       "gtf=%p, gtf_count=%d, ptr_to_free=%p\n",
+                       __FUNCTION__, *gtf, rc, *ptr_to_free);
+       return rc;
+
+ out_free:
+       kfree(output.pointer);
+       return rc;
 }
 
 /**
@@ -461,154 +311,99 @@ out:
  * function also waits for idle after writing control and before
  * writing the remaining registers.
  *
- * LOCKING: TBD:
- * Inherited from caller.
+ * LOCKING:
+ * EH context.
+ *
+ * RETURNS:
+ * 0 on success, -errno on failure.
  */
-static void taskfile_load_raw(struct ata_device *dev,
-                             const struct taskfile_array *gtf)
+static int taskfile_load_raw(struct ata_device *dev,
+                             const struct ata_acpi_gtf *gtf)
 {
        struct ata_port *ap = dev->ap;
-       struct ata_taskfile tf;
-       unsigned int err;
+       struct ata_taskfile tf, rtf;
+       unsigned int err_mask;
 
-       if (ata_msg_probe(ap))
-               ata_dev_printk(dev, KERN_DEBUG, "%s: (0x1f1-1f7): hex: "
-                       "%02x %02x %02x %02x %02x %02x %02x\n",
-                       __FUNCTION__,
-                       gtf->tfa[0], gtf->tfa[1], gtf->tfa[2],
-                       gtf->tfa[3], gtf->tfa[4], gtf->tfa[5], gtf->tfa[6]);
-
-       if ((gtf->tfa[0] == 0) && (gtf->tfa[1] == 0) && (gtf->tfa[2] == 0)
-           && (gtf->tfa[3] == 0) && (gtf->tfa[4] == 0) && (gtf->tfa[5] == 0)
-           && (gtf->tfa[6] == 0))
-               return;
+       if ((gtf->tf[0] == 0) && (gtf->tf[1] == 0) && (gtf->tf[2] == 0)
+           && (gtf->tf[3] == 0) && (gtf->tf[4] == 0) && (gtf->tf[5] == 0)
+           && (gtf->tf[6] == 0))
+               return 0;
 
        ata_tf_init(dev, &tf);
 
        /* convert gtf to tf */
        tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; /* TBD */
        tf.protocol = ATA_PROT_NODATA;
-       tf.feature = gtf->tfa[0];       /* 0x1f1 */
-       tf.nsect   = gtf->tfa[1];       /* 0x1f2 */
-       tf.lbal    = gtf->tfa[2];       /* 0x1f3 */
-       tf.lbam    = gtf->tfa[3];       /* 0x1f4 */
-       tf.lbah    = gtf->tfa[4];       /* 0x1f5 */
-       tf.device  = gtf->tfa[5];       /* 0x1f6 */
-       tf.command = gtf->tfa[6];       /* 0x1f7 */
-
-       err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
-       if (err && ata_msg_probe(ap))
-               ata_dev_printk(dev, KERN_ERR,
-                       "%s: ata_exec_internal failed: %u\n",
-                       __FUNCTION__, err);
-}
-
-/**
- * do_drive_set_taskfiles - write the drive taskfile settings from _GTF
- * @dev: target ATA device
- * @gtf_length: total number of bytes of _GTF taskfiles
- * @gtf_address: location of _GTF taskfile arrays
- *
- * This applies to both PATA and SATA drives.
- *
- * Write {gtf_address, length gtf_length} in groups of
- * REGS_PER_GTF bytes.
- */
-static int do_drive_set_taskfiles(struct ata_device *dev,
-                                 unsigned int gtf_length,
-                                 unsigned long gtf_address)
-{
-       struct ata_port *ap = dev->ap;
-       int err = -ENODEV;
-       int gtf_count = gtf_length / REGS_PER_GTF;
-       int ix;
-       struct taskfile_array   *gtf;
+       tf.feature = gtf->tf[0];        /* 0x1f1 */
+       tf.nsect   = gtf->tf[1];        /* 0x1f2 */
+       tf.lbal    = gtf->tf[2];        /* 0x1f3 */
+       tf.lbam    = gtf->tf[3];        /* 0x1f4 */
+       tf.lbah    = gtf->tf[4];        /* 0x1f5 */
+       tf.device  = gtf->tf[5];        /* 0x1f6 */
+       tf.command = gtf->tf[6];        /* 0x1f7 */
 
        if (ata_msg_probe(ap))
-               ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER: port#: %d\n",
-                              __FUNCTION__, ap->port_no);
-
-       if (libata_noacpi || !(ap->flags & ATA_FLAG_ACPI_SATA))
-               return 0;
-
-       if (!ata_dev_enabled(dev) || (ap->flags & ATA_FLAG_DISABLED))
-               goto out;
-       if (!gtf_count)         /* shouldn't be here */
-               goto out;
-
-       if (gtf_length % REGS_PER_GTF) {
-               if (ata_msg_drv(ap))
-                       ata_dev_printk(dev, KERN_ERR,
-                               "%s: unexpected GTF length (%d)\n",
-                               __FUNCTION__, gtf_length);
-               goto out;
-       }
-
-       for (ix = 0; ix < gtf_count; ix++) {
-               gtf = (struct taskfile_array *)
-                       (gtf_address + ix * REGS_PER_GTF);
-
-               /* send all TaskFile registers (0x1f1-0x1f7) *in*that*order* */
-               taskfile_load_raw(dev, gtf);
+               ata_dev_printk(dev, KERN_DEBUG, "executing ACPI cmd "
+                              "%02x/%02x:%02x:%02x:%02x:%02x:%02x\n",
+                              tf.command, tf.feature, tf.nsect,
+                              tf.lbal, tf.lbam, tf.lbah, tf.device);
+
+       rtf = tf;
+       err_mask = ata_exec_internal(dev, &rtf, NULL, DMA_NONE, NULL, 0);
+       if (err_mask) {
+               ata_dev_printk(dev, KERN_ERR,
+                       "ACPI cmd %02x/%02x:%02x:%02x:%02x:%02x:%02x failed "
+                       "(Emask=0x%x Stat=0x%02x Err=0x%02x)\n",
+                       tf.command, tf.feature, tf.nsect, tf.lbal, tf.lbam,
+                       tf.lbah, tf.device, err_mask, rtf.command, rtf.feature);
+               return -EIO;
        }
 
-       err = 0;
-out:
-       return err;
+       return 0;
 }
 
 /**
  * ata_acpi_exec_tfs - get then write drive taskfile settings
- * @ap: the ata_port for the drive
+ * @dev: target ATA device
  *
- * This applies to both PATA and SATA drives.
+ * Evaluate _GTF and excute returned taskfiles.
+ *
+ * LOCKING:
+ * EH context.
+ *
+ * RETURNS:
+ * Number of executed taskfiles on success, 0 if _GTF doesn't exist or
+ * doesn't contain valid data.  -errno on other errors.
  */
-int ata_acpi_exec_tfs(struct ata_port *ap)
+static int ata_acpi_exec_tfs(struct ata_device *dev)
 {
-       int ix;
-       int ret = 0;
-       unsigned int gtf_length;
-       unsigned long gtf_address;
-       unsigned long obj_loc;
-
-       if (libata_noacpi)
-               return 0;
-       /*
-        * TBD - implement PATA support.  For now,
-        * we should not run GTF on PATA devices since some
-        * PATA require execution of GTM/STM before GTF.
-        */
-       if (!(ap->flags & ATA_FLAG_ACPI_SATA))
-               return 0;
-
-       for (ix = 0; ix < ATA_MAX_DEVICES; ix++) {
-               struct ata_device *dev = &ap->device[ix];
-
-               if (!ata_dev_enabled(dev))
-                       continue;
-
-               ret = do_drive_get_GTF(dev, &gtf_length, &gtf_address,
-                                      &obj_loc);
-               if (ret < 0) {
-                       if (ata_msg_probe(ap))
-                               ata_port_printk(ap, KERN_DEBUG,
-                                       "%s: get_GTF error (%d)\n",
-                                       __FUNCTION__, ret);
-                       break;
-               }
-
-               ret = do_drive_set_taskfiles(dev, gtf_length, gtf_address);
-               kfree((void *)obj_loc);
-               if (ret < 0) {
-                       if (ata_msg_probe(ap))
-                               ata_port_printk(ap, KERN_DEBUG,
-                                       "%s: set_taskfiles error (%d)\n",
-                                       __FUNCTION__, ret);
-                       break;
-               }
+       struct ata_acpi_gtf *gtf = NULL;
+       void *ptr_to_free = NULL;
+       int gtf_count, i, rc;
+
+       /* get taskfiles */
+       rc = ata_dev_get_GTF(dev, &gtf, &ptr_to_free);
+       if (rc < 0)
+               return rc;
+       gtf_count = rc;
+
+       /* execute them */
+       for (i = 0, rc = 0; i < gtf_count; i++) {
+               int tmp;
+
+               /* ACPI errors are eventually ignored.  Run till the
+                * end even after errors.
+                */
+               tmp = taskfile_load_raw(dev, gtf++);
+               if (!rc)
+                       rc = tmp;
        }
 
-       return ret;
+       kfree(ptr_to_free);
+
+       if (rc == 0)
+               return gtf_count;
+       return rc;
 }
 
 /**
@@ -620,62 +415,25 @@ int ata_acpi_exec_tfs(struct ata_port *ap)
  * ATM this function never returns a failure.  It is an optional
  * method and if it fails for whatever reason, we should still
  * just keep going.
+ *
+ * LOCKING:
+ * EH context.
+ *
+ * RETURNS:
+ * 0 on success, -errno on failure.
  */
-int ata_acpi_push_id(struct ata_device *dev)
+static int ata_acpi_push_id(struct ata_device *dev)
 {
        struct ata_port *ap = dev->ap;
-       acpi_handle handle;
-       acpi_integer pcidevfn;
        int err;
-       struct device *gdev = ap->host->dev;
-       u32 dev_adr;
        acpi_status status;
        struct acpi_object_list input;
        union acpi_object in_params[1];
 
-       if (libata_noacpi)
-               return 0;
-
        if (ata_msg_probe(ap))
                ata_dev_printk(dev, KERN_DEBUG, "%s: ix = %d, port#: %d\n",
                               __FUNCTION__, dev->devno, ap->port_no);
 
-       /* Don't continue if not a SATA device. */
-       if (!(ap->flags & ATA_FLAG_ACPI_SATA)) {
-               if (ata_msg_probe(ap))
-                       ata_dev_printk(dev, KERN_DEBUG,
-                               "%s: Not a SATA device\n", __FUNCTION__);
-               goto out;
-       }
-
-       /* Don't continue if device has no _ADR method.
-        * _SDD is intended for known motherboard devices. */
-       err = sata_get_dev_handle(gdev, &handle, &pcidevfn);
-       if (err < 0) {
-               if (ata_msg_probe(ap))
-                       ata_dev_printk(dev, KERN_DEBUG,
-                               "%s: sata_get_dev_handle failed (%d\n",
-                               __FUNCTION__, err);
-               goto out;
-       }
-
-       /* Get this drive's _ADR info, if not already known */
-       if (!dev->obj_handle) {
-               dev_adr = SATA_ADR_RSVD;
-               err = get_sata_adr(gdev, handle, pcidevfn, dev->devno, ap, dev,
-                                       &dev_adr);
-               if (err < 0 || dev_adr == SATA_ADR_RSVD ||
-                       !dev->obj_handle) {
-                       if (ata_msg_probe(ap))
-                               ata_dev_printk(dev, KERN_DEBUG,
-                                       "%s: get_sata_adr failed: "
-                                       "err=%d, dev_adr=%u, obj_handle=0x%p\n",
-                                       __FUNCTION__, err, dev_adr,
-                                       dev->obj_handle);
-                       goto out;
-               }
-       }
-
        /* Give the drive Identify data to the drive via the _SDD method */
        /* _SDD: set up input parameters */
        input.count = 1;
@@ -687,20 +445,150 @@ int ata_acpi_push_id(struct ata_device *dev)
 
        /* It's OK for _SDD to be missing too. */
        swap_buf_le16(dev->id, ATA_ID_WORDS);
-       status = acpi_evaluate_object(dev->obj_handle, "_SDD", &input, NULL);
+       status = acpi_evaluate_object(dev->acpi_handle, "_SDD", &input, NULL);
        swap_buf_le16(dev->id, ATA_ID_WORDS);
 
        err = ACPI_FAILURE(status) ? -EIO : 0;
-       if (err < 0) {
-               if (ata_msg_probe(ap))
-                       ata_dev_printk(dev, KERN_DEBUG,
-                                      "%s _SDD error: status = 0x%x\n",
-                                      __FUNCTION__, status);
+       if (err < 0)
+               ata_dev_printk(dev, KERN_WARNING,
+                              "ACPI _SDD failed (AE 0x%x)\n", status);
+
+       return err;
+}
+
+/**
+ * ata_acpi_on_suspend - ATA ACPI hook called on suspend
+ * @ap: target ATA port
+ *
+ * This function is called when @ap is about to be suspended.  All
+ * devices are already put to sleep but the port_suspend() callback
+ * hasn't been executed yet.  Error return from this function aborts
+ * suspend.
+ *
+ * LOCKING:
+ * EH context.
+ *
+ * RETURNS:
+ * 0 on success, -errno on failure.
+ */
+int ata_acpi_on_suspend(struct ata_port *ap)
+{
+       unsigned long flags;
+       int rc;
+
+       /* proceed iff per-port acpi_handle is valid */
+       if (!ap->acpi_handle)
+               return 0;
+       BUG_ON(ap->flags & ATA_FLAG_ACPI_SATA);
+
+       /* store timing parameters */
+       rc = ata_acpi_gtm(ap, &ap->acpi_gtm);
+
+       spin_lock_irqsave(ap->lock, flags);
+       if (rc == 0)
+               ap->pflags |= ATA_PFLAG_GTM_VALID;
+       else
+               ap->pflags &= ~ATA_PFLAG_GTM_VALID;
+       spin_unlock_irqrestore(ap->lock, flags);
+
+       if (rc == -ENOENT)
+               rc = 0;
+       return rc;
+}
+
+/**
+ * ata_acpi_on_resume - ATA ACPI hook called on resume
+ * @ap: target ATA port
+ *
+ * This function is called when @ap is resumed - right after port
+ * itself is resumed but before any EH action is taken.
+ *
+ * LOCKING:
+ * EH context.
+ */
+void ata_acpi_on_resume(struct ata_port *ap)
+{
+       int i;
+
+       if (ap->acpi_handle && (ap->pflags & ATA_PFLAG_GTM_VALID)) {
+               BUG_ON(ap->flags & ATA_FLAG_ACPI_SATA);
+
+               /* restore timing parameters */
+               ata_acpi_stm(ap, &ap->acpi_gtm);
        }
 
-       /* always return success */
-out:
-       return 0;
+       /* schedule _GTF */
+       for (i = 0; i < ATA_MAX_DEVICES; i++)
+               ap->device[i].flags |= ATA_DFLAG_ACPI_PENDING;
 }
 
+/**
+ * ata_acpi_on_devcfg - ATA ACPI hook called on device donfiguration
+ * @dev: target ATA device
+ *
+ * This function is called when @dev is about to be configured.
+ * IDENTIFY data might have been modified after this hook is run.
+ *
+ * LOCKING:
+ * EH context.
+ *
+ * RETURNS:
+ * Positive number if IDENTIFY data needs to be refreshed, 0 if not,
+ * -errno on failure.
+ */
+int ata_acpi_on_devcfg(struct ata_device *dev)
+{
+       struct ata_port *ap = dev->ap;
+       struct ata_eh_context *ehc = &ap->eh_context;
+       int acpi_sata = ap->flags & ATA_FLAG_ACPI_SATA;
+       int rc;
+
+       if (!dev->acpi_handle)
+               return 0;
+
+       /* do we need to do _GTF? */
+       if (!(dev->flags & ATA_DFLAG_ACPI_PENDING) &&
+           !(acpi_sata && (ehc->i.flags & ATA_EHI_DID_HARDRESET)))
+               return 0;
+
+       /* do _SDD if SATA */
+       if (acpi_sata) {
+               rc = ata_acpi_push_id(dev);
+               if (rc)
+                       goto acpi_err;
+       }
+
+       /* do _GTF */
+       rc = ata_acpi_exec_tfs(dev);
+       if (rc < 0)
+               goto acpi_err;
+
+       dev->flags &= ~ATA_DFLAG_ACPI_PENDING;
+
+       /* refresh IDENTIFY page if any _GTF command has been executed */
+       if (rc > 0) {
+               rc = ata_dev_reread_id(dev, 0);
+               if (rc < 0) {
+                       ata_dev_printk(dev, KERN_ERR, "failed to IDENTIFY "
+                                      "after ACPI commands\n");
+                       return rc;
+               }
+       }
 
+       return 0;
+
+ acpi_err:
+       /* let EH retry on the first failure, disable ACPI on the second */
+       if (dev->flags & ATA_DFLAG_ACPI_FAILED) {
+               ata_dev_printk(dev, KERN_WARNING, "ACPI on devcfg failed the "
+                              "second time, disabling (errno=%d)\n", rc);
+
+               dev->acpi_handle = NULL;
+
+               /* if port is working, request IDENTIFY reload and continue */
+               if (!(ap->pflags & ATA_PFLAG_FROZEN))
+                       rc = 1;
+       }
+       dev->flags |= ATA_DFLAG_ACPI_FAILED;
+       return rc;
+}
index 981b397cb46b1af4f7840b3d434d296f18d1e18c..88e2dd0983b536cc31c3dfd6d44ffafa1f2854fc 100644 (file)
@@ -71,6 +71,7 @@ static unsigned int ata_dev_init_params(struct ata_device *dev,
                                        u16 heads, u16 sectors);
 static unsigned int ata_dev_set_xfermode(struct ata_device *dev);
 static void ata_dev_xfermask(struct ata_device *dev);
+static unsigned long ata_dev_blacklisted(const struct ata_device *dev);
 
 unsigned int ata_print_id = 1;
 static struct workqueue_struct *ata_wq;
@@ -1283,18 +1284,11 @@ static unsigned int ata_id_xfermask(const u16 *id)
 void ata_port_queue_task(struct ata_port *ap, work_func_t fn, void *data,
                         unsigned long delay)
 {
-       int rc;
-
-       if (ap->pflags & ATA_PFLAG_FLUSH_PORT_TASK)
-               return;
-
        PREPARE_DELAYED_WORK(&ap->port_task, fn);
        ap->port_task_data = data;
 
-       rc = queue_delayed_work(ata_wq, &ap->port_task, delay);
-
-       /* rc == 0 means that another user is using port task */
-       WARN_ON(rc == 0);
+       /* may fail if ata_port_flush_task() in progress */
+       queue_delayed_work(ata_wq, &ap->port_task, delay);
 }
 
 /**
@@ -1309,32 +1303,9 @@ void ata_port_queue_task(struct ata_port *ap, work_func_t fn, void *data,
  */
 void ata_port_flush_task(struct ata_port *ap)
 {
-       unsigned long flags;
-
        DPRINTK("ENTER\n");
 
-       spin_lock_irqsave(ap->lock, flags);
-       ap->pflags |= ATA_PFLAG_FLUSH_PORT_TASK;
-       spin_unlock_irqrestore(ap->lock, flags);
-
-       DPRINTK("flush #1\n");
-       cancel_work_sync(&ap->port_task.work); /* akpm: seems unneeded */
-
-       /*
-        * At this point, if a task is running, it's guaranteed to see
-        * the FLUSH flag; thus, it will never queue pio tasks again.
-        * Cancel and flush.
-        */
-       if (!cancel_delayed_work(&ap->port_task)) {
-               if (ata_msg_ctl(ap))
-                       ata_port_printk(ap, KERN_DEBUG, "%s: flush #2\n",
-                                       __FUNCTION__);
-               cancel_work_sync(&ap->port_task.work);
-       }
-
-       spin_lock_irqsave(ap->lock, flags);
-       ap->pflags &= ~ATA_PFLAG_FLUSH_PORT_TASK;
-       spin_unlock_irqrestore(ap->lock, flags);
+       cancel_rearming_delayed_work(&ap->port_task);
 
        if (ata_msg_ctl(ap))
                ata_port_printk(ap, KERN_DEBUG, "%s: EXIT\n", __FUNCTION__);
@@ -1814,7 +1785,7 @@ static void ata_dev_config_ncq(struct ata_device *dev,
                desc[0] = '\0';
                return;
        }
-       if (ata_device_blacklisted(dev) & ATA_HORKAGE_NONCQ) {
+       if (dev->horkage & ATA_HORKAGE_NONCQ) {
                snprintf(desc, desc_sz, "NCQ (not used)");
                return;
        }
@@ -1845,7 +1816,8 @@ static void ata_dev_config_ncq(struct ata_device *dev,
 int ata_dev_configure(struct ata_device *dev)
 {
        struct ata_port *ap = dev->ap;
-       int print_info = ap->eh_context.i.flags & ATA_EHI_PRINTINFO;
+       struct ata_eh_context *ehc = &ap->eh_context;
+       int print_info = ehc->i.flags & ATA_EHI_PRINTINFO;
        const u16 *id = dev->id;
        unsigned int xfer_mask;
        char revbuf[7];         /* XYZ-99\0 */
@@ -1862,15 +1834,13 @@ int ata_dev_configure(struct ata_device *dev)
        if (ata_msg_probe(ap))
                ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __FUNCTION__);
 
-       /* set _SDD */
-       rc = ata_acpi_push_id(dev);
-       if (rc) {
-               ata_dev_printk(dev, KERN_WARNING, "failed to set _SDD(%d)\n",
-                       rc);
-       }
+       /* set horkage */
+       dev->horkage |= ata_dev_blacklisted(dev);
 
-       /* retrieve and execute the ATA task file of _GTF */
-       ata_acpi_exec_tfs(ap);
+       /* let ACPI work its magic */
+       rc = ata_acpi_on_devcfg(dev);
+       if (rc)
+               return rc;
 
        /* print device capabilities */
        if (ata_msg_probe(ap))
@@ -2042,7 +2012,7 @@ int ata_dev_configure(struct ata_device *dev)
                dev->max_sectors = ATA_MAX_SECTORS;
        }
 
-       if (ata_device_blacklisted(dev) & ATA_HORKAGE_MAX_SEC_128)
+       if (dev->horkage & ATA_HORKAGE_MAX_SEC_128)
                dev->max_sectors = min_t(unsigned int, ATA_MAX_SECTORS_128,
                                         dev->max_sectors);
 
@@ -3194,9 +3164,6 @@ void ata_bus_reset(struct ata_port *ap)
        if ((slave_possible) && (err != 0x81))
                ap->device[1].class = ata_dev_try_classify(ap, 1, &err);
 
-       /* re-enable interrupts */
-       ap->ops->irq_on(ap);
-
        /* is double-select really necessary? */
        if (ap->device[1].class != ATA_DEV_NONE)
                ap->ops->dev_select(ap, 1);
@@ -3359,7 +3326,7 @@ int ata_std_prereset(struct ata_port *ap, unsigned long deadline)
                return 0;
 
        /* if SATA, resume phy */
-       if (ap->cbl == ATA_CBL_SATA) {
+       if (ap->flags & ATA_FLAG_SATA) {
                rc = sata_phy_resume(ap, timing, deadline);
                /* whine about phy resume failure but proceed */
                if (rc && rc != -EOPNOTSUPP)
@@ -3581,10 +3548,6 @@ void ata_std_postreset(struct ata_port *ap, unsigned int *classes)
        if (sata_scr_read(ap, SCR_ERROR, &serror) == 0)
                sata_scr_write(ap, SCR_ERROR, serror);
 
-       /* re-enable interrupts */
-       if (!ap->ops->error_handler)
-               ap->ops->irq_on(ap);
-
        /* is double-select really necessary? */
        if (classes[0] != ATA_DEV_NONE)
                ap->ops->dev_select(ap, 1);
@@ -3774,6 +3737,8 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
        { "SAMSUNG CD-ROM SN-124","N001",       ATA_HORKAGE_NODMA },
        { "Seagate STT20000A", NULL,            ATA_HORKAGE_NODMA },
        { "IOMEGA  ZIP 250       ATAPI", NULL,  ATA_HORKAGE_NODMA }, /* temporary fix */
+       { "IOMEGA  ZIP 250       ATAPI       Floppy",
+                               NULL,           ATA_HORKAGE_NODMA },
 
        /* Weird ATAPI devices */
        { "TORiSAN DVD-ROM DRD-N216", NULL,     ATA_HORKAGE_MAX_SEC_128 },
@@ -3787,7 +3752,10 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
        { "FUJITSU MHT2060BH",  NULL,           ATA_HORKAGE_NONCQ },
        /* NCQ is broken */
        { "Maxtor 6L250S0",     "BANC1G10",     ATA_HORKAGE_NONCQ },
+       { "Maxtor 6B200M0",     "BANC1BM0",     ATA_HORKAGE_NONCQ },
        { "Maxtor 6B200M0",     "BANC1B10",     ATA_HORKAGE_NONCQ },
+       { "HITACHI HDS7250SASUN500G 0621KTAWSD", "K2AOAJ0AHITACHI",
+        ATA_HORKAGE_NONCQ },
        /* NCQ hard hangs device under heavier load, needs hard power cycle */
        { "Maxtor 6B250S0",     "BANC1B70",     ATA_HORKAGE_NONCQ },
        /* Blacklist entries taken from Silicon Image 3124/3132
@@ -3800,6 +3768,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
        { "HTS541612J9SA00",    "SBDIC7JP",     ATA_HORKAGE_NONCQ, },
        { "Hitachi HTS541616J9SA00", "SB4OC70P", ATA_HORKAGE_NONCQ, },
        { "WDC WD740ADFD-00NLR1", NULL,         ATA_HORKAGE_NONCQ, },
+       { "FUJITSU MHV2080BH",  "00840028",     ATA_HORKAGE_NONCQ, },
 
        /* Devices with NCQ limits */
 
@@ -3807,7 +3776,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
        { }
 };
 
-unsigned long ata_device_blacklisted(const struct ata_device *dev)
+static unsigned long ata_dev_blacklisted(const struct ata_device *dev)
 {
        unsigned char model_num[ATA_ID_PROD_LEN + 1];
        unsigned char model_rev[ATA_ID_FW_REV_LEN + 1];
@@ -3837,7 +3806,7 @@ static int ata_dma_blacklisted(const struct ata_device *dev)
        if ((dev->ap->flags & ATA_FLAG_PIO_POLLING) &&
            (dev->flags & ATA_DFLAG_CDB_INTR))
                return 1;
-       return (ata_device_blacklisted(dev) & ATA_HORKAGE_NODMA) ? 1 : 0;
+       return (dev->horkage & ATA_HORKAGE_NODMA) ? 1 : 0;
 }
 
 /**
@@ -4106,6 +4075,68 @@ static void ata_fill_sg(struct ata_queued_cmd *qc)
                ap->prd[idx - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT);
 }
 
+/**
+ *     ata_fill_sg_dumb - Fill PCI IDE PRD table
+ *     @qc: Metadata associated with taskfile to be transferred
+ *
+ *     Fill PCI IDE PRD (scatter-gather) table with segments
+ *     associated with the current disk command. Perform the fill
+ *     so that we avoid writing any length 64K records for
+ *     controllers that don't follow the spec.
+ *
+ *     LOCKING:
+ *     spin_lock_irqsave(host lock)
+ *
+ */
+static void ata_fill_sg_dumb(struct ata_queued_cmd *qc)
+{
+       struct ata_port *ap = qc->ap;
+       struct scatterlist *sg;
+       unsigned int idx;
+
+       WARN_ON(qc->__sg == NULL);
+       WARN_ON(qc->n_elem == 0 && qc->pad_len == 0);
+
+       idx = 0;
+       ata_for_each_sg(sg, qc) {
+               u32 addr, offset;
+               u32 sg_len, len, blen;
+
+               /* determine if physical DMA addr spans 64K boundary.
+                * Note h/w doesn't support 64-bit, so we unconditionally
+                * truncate dma_addr_t to u32.
+                */
+               addr = (u32) sg_dma_address(sg);
+               sg_len = sg_dma_len(sg);
+
+               while (sg_len) {
+                       offset = addr & 0xffff;
+                       len = sg_len;
+                       if ((offset + sg_len) > 0x10000)
+                               len = 0x10000 - offset;
+
+                       blen = len & 0xffff;
+                       ap->prd[idx].addr = cpu_to_le32(addr);
+                       if (blen == 0) {
+                          /* Some PATA chipsets like the CS5530 can't
+                             cope with 0x0000 meaning 64K as the spec says */
+                               ap->prd[idx].flags_len = cpu_to_le32(0x8000);
+                               blen = 0x8000;
+                               ap->prd[++idx].addr = cpu_to_le32(addr + 0x8000);
+                       }
+                       ap->prd[idx].flags_len = cpu_to_le32(blen);
+                       VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", idx, addr, len);
+
+                       idx++;
+                       sg_len -= len;
+                       addr += len;
+               }
+       }
+
+       if (idx)
+               ap->prd[idx - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT);
+}
+
 /**
  *     ata_check_atapi_dma - Check whether ATAPI DMA can be supported
  *     @qc: Metadata associated with taskfile to check
@@ -4153,6 +4184,23 @@ void ata_qc_prep(struct ata_queued_cmd *qc)
        ata_fill_sg(qc);
 }
 
+/**
+ *     ata_dumb_qc_prep - Prepare taskfile for submission
+ *     @qc: Metadata associated with taskfile to be prepared
+ *
+ *     Prepare ATA taskfile for submission.
+ *
+ *     LOCKING:
+ *     spin_lock_irqsave(host lock)
+ */
+void ata_dumb_qc_prep(struct ata_queued_cmd *qc)
+{
+       if (!(qc->flags & ATA_QCFLAG_DMAMAP))
+               return;
+
+       ata_fill_sg_dumb(qc);
+}
+
 void ata_noop_qc_prep(struct ata_queued_cmd *qc) { }
 
 /**
@@ -5660,7 +5708,7 @@ irqreturn_t ata_interrupt (int irq, void *dev_instance)
  */
 int sata_scr_valid(struct ata_port *ap)
 {
-       return ap->cbl == ATA_CBL_SATA && ap->ops->scr_read;
+       return (ap->flags & ATA_FLAG_SATA) && ap->ops->scr_read;
 }
 
 /**
@@ -6293,6 +6341,9 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
        if (rc)
                return rc;
 
+       /* associate with ACPI nodes */
+       ata_acpi_associate(host);
+
        /* set cable, sata_spd_limit and report */
        for (i = 0; i < host->n_ports; i++) {
                struct ata_port *ap = host->ports[i];
@@ -6324,7 +6375,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
                if (!ata_port_is_dummy(ap))
                        ata_port_printk(ap, KERN_INFO, "%cATA max %s cmd 0x%p "
                                        "ctl 0x%p bmdma 0x%p irq %d\n",
-                                       ap->cbl == ATA_CBL_SATA ? 'S' : 'P',
+                                       (ap->flags & ATA_FLAG_SATA) ? 'S' : 'P',
                                        ata_mode_string(xfer_mask),
                                        ap->ioaddr.cmd_addr,
                                        ap->ioaddr.ctl_addr,
@@ -6479,13 +6530,7 @@ void ata_port_detach(struct ata_port *ap)
        spin_unlock_irqrestore(ap->lock, flags);
 
        ata_port_wait_eh(ap);
-
-       /* Flush hotplug task.  The sequence is similar to
-        * ata_port_flush_task().
-        */
-       cancel_work_sync(&ap->hotplug_task.work); /* akpm: why? */
-       cancel_delayed_work(&ap->hotplug_task);
-       cancel_work_sync(&ap->hotplug_task.work);
+       cancel_rearming_delayed_work(&ap->hotplug_task);
 
  skip_eh:
        /* remove the associated SCSI host */
@@ -6822,6 +6867,7 @@ EXPORT_SYMBOL_GPL(ata_do_set_mode);
 EXPORT_SYMBOL_GPL(ata_data_xfer);
 EXPORT_SYMBOL_GPL(ata_data_xfer_noirq);
 EXPORT_SYMBOL_GPL(ata_qc_prep);
+EXPORT_SYMBOL_GPL(ata_dumb_qc_prep);
 EXPORT_SYMBOL_GPL(ata_noop_qc_prep);
 EXPORT_SYMBOL_GPL(ata_bmdma_setup);
 EXPORT_SYMBOL_GPL(ata_bmdma_start);
@@ -6873,7 +6919,6 @@ EXPORT_SYMBOL_GPL(ata_host_resume);
 EXPORT_SYMBOL_GPL(ata_id_string);
 EXPORT_SYMBOL_GPL(ata_id_c_string);
 EXPORT_SYMBOL_GPL(ata_id_to_dma_mode);
-EXPORT_SYMBOL_GPL(ata_device_blacklisted);
 EXPORT_SYMBOL_GPL(ata_scsi_simulate);
 
 EXPORT_SYMBOL_GPL(ata_pio_need_iordy);
@@ -6882,9 +6927,9 @@ EXPORT_SYMBOL_GPL(ata_timing_merge);
 
 #ifdef CONFIG_PCI
 EXPORT_SYMBOL_GPL(pci_test_config_bits);
-EXPORT_SYMBOL_GPL(ata_pci_init_native_host);
+EXPORT_SYMBOL_GPL(ata_pci_init_sff_host);
 EXPORT_SYMBOL_GPL(ata_pci_init_bmdma);
-EXPORT_SYMBOL_GPL(ata_pci_prepare_native_host);
+EXPORT_SYMBOL_GPL(ata_pci_prepare_sff_host);
 EXPORT_SYMBOL_GPL(ata_pci_init_one);
 EXPORT_SYMBOL_GPL(ata_pci_remove_one);
 #ifdef CONFIG_PM
index f7582c9c320e029aa916912646ec48f0991c6467..9aa62a0754f6946349a4c72d142f2f68eec0077e 100644 (file)
@@ -1897,6 +1897,57 @@ static int ata_eh_skip_recovery(struct ata_port *ap)
        return 1;
 }
 
+static void ata_eh_handle_dev_fail(struct ata_device *dev, int err)
+{
+       struct ata_port *ap = dev->ap;
+       struct ata_eh_context *ehc = &ap->eh_context;
+
+       ehc->tries[dev->devno]--;
+
+       switch (err) {
+       case -ENODEV:
+               /* device missing or wrong IDENTIFY data, schedule probing */
+               ehc->i.probe_mask |= (1 << dev->devno);
+       case -EINVAL:
+               /* give it just one more chance */
+               ehc->tries[dev->devno] = min(ehc->tries[dev->devno], 1);
+       case -EIO:
+               if (ehc->tries[dev->devno] == 1) {
+                       /* This is the last chance, better to slow
+                        * down than lose it.
+                        */
+                       sata_down_spd_limit(ap);
+                       ata_down_xfermask_limit(dev, ATA_DNXFER_PIO);
+               }
+       }
+
+       if (ata_dev_enabled(dev) && !ehc->tries[dev->devno]) {
+               /* disable device if it has used up all its chances */
+               ata_dev_disable(dev);
+
+               /* detach if offline */
+               if (ata_port_offline(ap))
+                       ata_eh_detach_dev(dev);
+
+               /* probe if requested */
+               if ((ehc->i.probe_mask & (1 << dev->devno)) &&
+                   !(ehc->did_probe_mask & (1 << dev->devno))) {
+                       ata_eh_detach_dev(dev);
+                       ata_dev_init(dev);
+
+                       ehc->tries[dev->devno] = ATA_EH_DEV_TRIES;
+                       ehc->did_probe_mask |= (1 << dev->devno);
+                       ehc->i.action |= ATA_EH_SOFTRESET;
+               }
+       } else {
+               /* soft didn't work?  be haaaaard */
+               if (ehc->i.flags & ATA_EHI_DID_RESET)
+                       ehc->i.action |= ATA_EH_HARDRESET;
+               else
+                       ehc->i.action |= ATA_EH_SOFTRESET;
+       }
+}
+
 /**
  *     ata_eh_recover - recover host port after error
  *     @ap: host port to recover
@@ -1997,50 +2048,7 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
        goto out;
 
  dev_fail:
-       ehc->tries[dev->devno]--;
-
-       switch (rc) {
-       case -ENODEV:
-               /* device missing or wrong IDENTIFY data, schedule probing */
-               ehc->i.probe_mask |= (1 << dev->devno);
-       case -EINVAL:
-               /* give it just one more chance */
-               ehc->tries[dev->devno] = min(ehc->tries[dev->devno], 1);
-       case -EIO:
-               if (ehc->tries[dev->devno] == 1) {
-                       /* This is the last chance, better to slow
-                        * down than lose it.
-                        */
-                       sata_down_spd_limit(ap);
-                       ata_down_xfermask_limit(dev, ATA_DNXFER_PIO);
-               }
-       }
-
-       if (ata_dev_enabled(dev) && !ehc->tries[dev->devno]) {
-               /* disable device if it has used up all its chances */
-               ata_dev_disable(dev);
-
-               /* detach if offline */
-               if (ata_port_offline(ap))
-                       ata_eh_detach_dev(dev);
-
-               /* probe if requested */
-               if ((ehc->i.probe_mask & (1 << dev->devno)) &&
-                   !(ehc->did_probe_mask & (1 << dev->devno))) {
-                       ata_eh_detach_dev(dev);
-                       ata_dev_init(dev);
-
-                       ehc->tries[dev->devno] = ATA_EH_DEV_TRIES;
-                       ehc->did_probe_mask |= (1 << dev->devno);
-                       ehc->i.action |= ATA_EH_SOFTRESET;
-               }
-       } else {
-               /* soft didn't work?  be haaaaard */
-               if (ehc->i.flags & ATA_EHI_DID_RESET)
-                       ehc->i.action |= ATA_EH_HARDRESET;
-               else
-                       ehc->i.action |= ATA_EH_SOFTRESET;
-       }
+       ata_eh_handle_dev_fail(dev, rc);
 
        if (ata_port_nr_enabled(ap)) {
                ata_port_printk(ap, KERN_WARNING, "failed to recover some "
@@ -2154,19 +2162,25 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap)
 
        WARN_ON(ap->pflags & ATA_PFLAG_SUSPENDED);
 
+       /* tell ACPI we're suspending */
+       rc = ata_acpi_on_suspend(ap);
+       if (rc)
+               goto out;
+
        /* suspend */
        ata_eh_freeze_port(ap);
 
        if (ap->ops->port_suspend)
                rc = ap->ops->port_suspend(ap, ap->pm_mesg);
 
+ out:
        /* report result */
        spin_lock_irqsave(ap->lock, flags);
 
        ap->pflags &= ~ATA_PFLAG_PM_PENDING;
        if (rc == 0)
                ap->pflags |= ATA_PFLAG_SUSPENDED;
-       else
+       else if (ap->pflags & ATA_PFLAG_FROZEN)
                ata_port_schedule_eh(ap);
 
        if (ap->pm_result) {
@@ -2207,6 +2221,9 @@ static void ata_eh_handle_port_resume(struct ata_port *ap)
        if (ap->ops->port_resume)
                rc = ap->ops->port_resume(ap);
 
+       /* tell ACPI that we're resuming */
+       ata_acpi_on_resume(ap);
+
        /* report result */
        spin_lock_irqsave(ap->lock, flags);
        ap->pflags &= ~(ATA_PFLAG_PM_PENDING | ATA_PFLAG_SUSPENDED);
index 4ddf00c8c5f5d977bfb71286d8f3e6f025e750f4..cfde22da07ac9aa3537e22b88935c4f56bf57e70 100644 (file)
@@ -2620,7 +2620,7 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
                        ata_dev_printk(dev, KERN_WARNING,
                                       "invalid multi_count %u ignored\n",
                                       multi_count);
-       }       
+       }
 
        /* READ/WRITE LONG use a non-standard sect_size */
        qc->sect_size = ATA_SECT_SIZE;
index fa1c22c7b38fef986e0029c139a471e53667459b..ca7d2245d6840b2580141ceae2b81542366a3d6e 100644 (file)
@@ -604,13 +604,17 @@ int ata_pci_init_bmdma(struct ata_host *host)
 }
 
 /**
- *     ata_pci_init_native_host - acquire native ATA resources and init host
+ *     ata_pci_init_sff_host - acquire native PCI ATA resources and init host
  *     @host: target ATA host
  *
  *     Acquire native PCI ATA resources for @host and initialize the
  *     first two ports of @host accordingly.  Ports marked dummy are
  *     skipped and allocation failure makes the port dummy.
  *
+ *     Note that native PCI resources are valid even for legacy hosts
+ *     as we fix up pdev resources array early in boot, so this
+ *     function can be used for both native and legacy SFF hosts.
+ *
  *     LOCKING:
  *     Inherited from calling layer (may sleep).
  *
@@ -618,7 +622,7 @@ int ata_pci_init_bmdma(struct ata_host *host)
  *     0 if at least one port is initialized, -ENODEV if no port is
  *     available.
  */
-int ata_pci_init_native_host(struct ata_host *host)
+int ata_pci_init_sff_host(struct ata_host *host)
 {
        struct device *gdev = host->dev;
        struct pci_dev *pdev = to_pci_dev(gdev);
@@ -673,7 +677,7 @@ int ata_pci_init_native_host(struct ata_host *host)
 }
 
 /**
- *     ata_pci_prepare_native_host - helper to prepare native PCI ATA host
+ *     ata_pci_prepare_sff_host - helper to prepare native PCI ATA host
  *     @pdev: target PCI device
  *     @ppi: array of port_info, must be enough for two ports
  *     @r_host: out argument for the initialized ATA host
@@ -687,9 +691,9 @@ int ata_pci_init_native_host(struct ata_host *host)
  *     RETURNS:
  *     0 on success, -errno otherwise.
  */
-int ata_pci_prepare_native_host(struct pci_dev *pdev,
-                               const struct ata_port_info * const * ppi,
-                               struct ata_host **r_host)
+int ata_pci_prepare_sff_host(struct pci_dev *pdev,
+                            const struct ata_port_info * const * ppi,
+                            struct ata_host **r_host)
 {
        struct ata_host *host;
        int rc;
@@ -705,7 +709,7 @@ int ata_pci_prepare_native_host(struct pci_dev *pdev,
                goto err_out;
        }
 
-       rc = ata_pci_init_native_host(host);
+       rc = ata_pci_init_sff_host(host);
        if (rc)
                goto err_out;
 
@@ -730,221 +734,6 @@ int ata_pci_prepare_native_host(struct pci_dev *pdev,
        return rc;
 }
 
-struct ata_legacy_devres {
-       unsigned int    mask;
-       unsigned long   cmd_port[2];
-       void __iomem *  cmd_addr[2];
-       void __iomem *  ctl_addr[2];
-       unsigned int    irq[2];
-       void *          irq_dev_id[2];
-};
-
-static void ata_legacy_free_irqs(struct ata_legacy_devres *legacy_dr)
-{
-       int i;
-
-       for (i = 0; i < 2; i++) {
-               if (!legacy_dr->irq[i])
-                       continue;
-
-               free_irq(legacy_dr->irq[i], legacy_dr->irq_dev_id[i]);
-               legacy_dr->irq[i] = 0;
-               legacy_dr->irq_dev_id[i] = NULL;
-       }
-}
-
-static void ata_legacy_release(struct device *gdev, void *res)
-{
-       struct ata_legacy_devres *this = res;
-       int i;
-
-       ata_legacy_free_irqs(this);
-
-       for (i = 0; i < 2; i++) {
-               if (this->cmd_addr[i])
-                       ioport_unmap(this->cmd_addr[i]);
-               if (this->ctl_addr[i])
-                       ioport_unmap(this->ctl_addr[i]);
-               if (this->cmd_port[i])
-                       release_region(this->cmd_port[i], 8);
-       }
-}
-
-static int ata_init_legacy_port(struct ata_port *ap,
-                               struct ata_legacy_devres *legacy_dr)
-{
-       struct ata_host *host = ap->host;
-       int port_no = ap->port_no;
-       unsigned long cmd_port, ctl_port;
-
-       if (port_no == 0) {
-               cmd_port = ATA_PRIMARY_CMD;
-               ctl_port = ATA_PRIMARY_CTL;
-       } else {
-               cmd_port = ATA_SECONDARY_CMD;
-               ctl_port = ATA_SECONDARY_CTL;
-       }
-
-       /* request cmd_port */
-       if (request_region(cmd_port, 8, "libata"))
-               legacy_dr->cmd_port[port_no] = cmd_port;
-       else {
-               dev_printk(KERN_WARNING, host->dev,
-                          "0x%0lX IDE port busy\n", cmd_port);
-               return -EBUSY;
-       }
-
-       /* iomap cmd and ctl ports */
-       legacy_dr->cmd_addr[port_no] = ioport_map(cmd_port, 8);
-       legacy_dr->ctl_addr[port_no] = ioport_map(ctl_port, 1);
-       if (!legacy_dr->cmd_addr[port_no] || !legacy_dr->ctl_addr[port_no]) {
-               dev_printk(KERN_WARNING, host->dev,
-                          "failed to map cmd/ctl ports\n");
-               return -ENOMEM;
-       }
-
-       /* init IO addresses */
-       ap->ioaddr.cmd_addr = legacy_dr->cmd_addr[port_no];
-       ap->ioaddr.altstatus_addr = legacy_dr->ctl_addr[port_no];
-       ap->ioaddr.ctl_addr = legacy_dr->ctl_addr[port_no];
-       ata_std_ports(&ap->ioaddr);
-
-       return 0;
-}
-
-/**
- *     ata_init_legacy_host - acquire legacy ATA resources and init ATA host
- *     @host: target ATA host
- *     @was_busy: out parameter, indicates whether any port was busy
- *
- *     Acquire legacy ATA resources for the first two ports of @host
- *     and initialize it accordingly.  Ports marked dummy are skipped
- *     and resource acquistion failure makes the port dummy.
- *
- *     LOCKING:
- *     Inherited from calling layer (may sleep).
- *
- *     RETURNS:
- *     0 if at least one port is initialized, -ENODEV if no port is
- *     available.
- */
-static int ata_init_legacy_host(struct ata_host *host, int *was_busy)
-{
-       struct device *gdev = host->dev;
-       struct ata_legacy_devres *legacy_dr;
-       int i, rc;
-
-       if (!devres_open_group(gdev, NULL, GFP_KERNEL))
-               return -ENOMEM;
-
-       rc = -ENOMEM;
-       legacy_dr = devres_alloc(ata_legacy_release, sizeof(*legacy_dr),
-                                GFP_KERNEL);
-       if (!legacy_dr)
-               goto err_out;
-       devres_add(gdev, legacy_dr);
-
-       for (i = 0; i < 2; i++) {
-               if (ata_port_is_dummy(host->ports[i]))
-                       continue;
-
-               rc = ata_init_legacy_port(host->ports[i], legacy_dr);
-               if (rc == 0)
-                       legacy_dr->mask |= 1 << i;
-               else {
-                       if (rc == -EBUSY)
-                               (*was_busy)++;
-                       host->ports[i]->ops = &ata_dummy_port_ops;
-               }
-       }
-
-       if (!legacy_dr->mask) {
-               dev_printk(KERN_ERR, gdev, "no available legacy port\n");
-               return -ENODEV;
-       }
-
-       devres_remove_group(gdev, NULL);
-       return 0;
-
- err_out:
-       devres_release_group(gdev, NULL);
-       return rc;
-}
-
-/**
- *     ata_request_legacy_irqs - request legacy ATA IRQs
- *     @host: target ATA host
- *     @handler: array of IRQ handlers
- *     @irq_flags: array of IRQ flags
- *     @dev_id: array of IRQ dev_ids
- *
- *     Request legacy IRQs for non-dummy legacy ports in @host.  All
- *     IRQ parameters are passed as array to allow ports to have
- *     separate IRQ handlers.
- *
- *     LOCKING:
- *     Inherited from calling layer (may sleep).
- *
- *     RETURNS:
- *     0 on success, -errno otherwise.
- */
-static int ata_request_legacy_irqs(struct ata_host *host,
-                                  irq_handler_t const *handler,
-                                  const unsigned int *irq_flags,
-                                  void * const *dev_id)
-{
-       struct device *gdev = host->dev;
-       struct ata_legacy_devres *legacy_dr;
-       int i, rc;
-
-       legacy_dr = devres_find(host->dev, ata_legacy_release, NULL, NULL);
-       BUG_ON(!legacy_dr);
-
-       for (i = 0; i < 2; i++) {
-               unsigned int irq;
-
-               /* FIXME: ATA_*_IRQ() should take generic device not pci_dev */
-               if (i == 0)
-                       irq = ATA_PRIMARY_IRQ(to_pci_dev(gdev));
-               else
-                       irq = ATA_SECONDARY_IRQ(to_pci_dev(gdev));
-
-               if (!(legacy_dr->mask & (1 << i)))
-                       continue;
-
-               if (!handler[i]) {
-                       dev_printk(KERN_ERR, gdev,
-                                  "NULL handler specified for port %d\n", i);
-                       rc = -EINVAL;
-                       goto err_out;
-               }
-
-               rc = request_irq(irq, handler[i], irq_flags[i], DRV_NAME,
-                                dev_id[i]);
-               if (rc) {
-                       dev_printk(KERN_ERR, gdev,
-                               "irq %u request failed (errno=%d)\n", irq, rc);
-                       goto err_out;
-               }
-
-               /* record irq allocation in legacy_dr */
-               legacy_dr->irq[i] = irq;
-               legacy_dr->irq_dev_id[i] = dev_id[i];
-
-               /* only used to print info */
-               if (i == 0)
-                       host->irq = irq;
-               else
-                       host->irq2 = irq;
-       }
-
-       return 0;
-
- err_out:
-       ata_legacy_free_irqs(legacy_dr);
-       return rc;
-}
-
 /**
  *     ata_pci_init_one - Initialize/register PCI IDE host controller
  *     @pdev: Controller to be initialized
@@ -1029,35 +818,11 @@ int ata_pci_init_one(struct pci_dev *pdev,
 #endif
        }
 
-       /* alloc and init host */
-       host = ata_host_alloc_pinfo(dev, ppi, 2);
-       if (!host) {
-               dev_printk(KERN_ERR, &pdev->dev,
-                          "failed to allocate ATA host\n");
-               rc = -ENOMEM;
+       /* prepare host */
+       rc = ata_pci_prepare_sff_host(pdev, ppi, &host);
+       if (rc)
                goto err_out;
-       }
 
-       if (!legacy_mode) {
-               rc = ata_pci_init_native_host(host);
-               if (rc)
-                       goto err_out;
-       } else {
-               int was_busy = 0;
-
-               rc = ata_init_legacy_host(host, &was_busy);
-               if (was_busy)
-                       pcim_pin_device(pdev);
-               if (rc)
-                       goto err_out;
-
-               /* request respective PCI regions, may fail */
-               rc = pci_request_region(pdev, 1, DRV_NAME);
-               rc = pci_request_region(pdev, 3, DRV_NAME);
-       }
-
-       /* init BMDMA, may fail */
-       ata_pci_init_bmdma(host);
        pci_set_master(pdev);
 
        /* start host and request IRQ */
@@ -1068,17 +833,28 @@ int ata_pci_init_one(struct pci_dev *pdev,
        if (!legacy_mode) {
                rc = devm_request_irq(dev, pdev->irq, pi->port_ops->irq_handler,
                                      IRQF_SHARED, DRV_NAME, host);
+               if (rc)
+                       goto err_out;
                host->irq = pdev->irq;
        } else {
-               irq_handler_t handler[2] = { host->ops->irq_handler,
-                                            host->ops->irq_handler };
-               unsigned int irq_flags[2] = { IRQF_SHARED, IRQF_SHARED };
-               void *dev_id[2] = { host, host };
+               if (!ata_port_is_dummy(host->ports[0])) {
+                       host->irq = ATA_PRIMARY_IRQ(pdev);
+                       rc = devm_request_irq(dev, host->irq,
+                                             pi->port_ops->irq_handler,
+                                             IRQF_SHARED, DRV_NAME, host);
+                       if (rc)
+                               goto err_out;
+               }
 
-               rc = ata_request_legacy_irqs(host, handler, irq_flags, dev_id);
+               if (!ata_port_is_dummy(host->ports[1])) {
+                       host->irq2 = ATA_SECONDARY_IRQ(pdev);
+                       rc = devm_request_irq(dev, host->irq2,
+                                             pi->port_ops->irq_handler,
+                                             IRQF_SHARED, DRV_NAME, host);
+                       if (rc)
+                               goto err_out;
+               }
        }
-       if (rc)
-               goto err_out;
 
        /* register */
        rc = ata_host_register(host, pi->sht);
index 5e246665842055e6b71b1dc023a21fcb6e623547..ba17fc5f2e998a1601993494cafc2b1d766c9468 100644 (file)
@@ -98,17 +98,15 @@ extern struct ata_port *ata_port_alloc(struct ata_host *host);
 
 /* libata-acpi.c */
 #ifdef CONFIG_ATA_ACPI
-extern int ata_acpi_exec_tfs(struct ata_port *ap);
-extern int ata_acpi_push_id(struct ata_device *dev);
+extern void ata_acpi_associate(struct ata_host *host);
+extern int ata_acpi_on_suspend(struct ata_port *ap);
+extern void ata_acpi_on_resume(struct ata_port *ap);
+extern int ata_acpi_on_devcfg(struct ata_device *adev);
 #else
-static inline int ata_acpi_exec_tfs(struct ata_port *ap)
-{
-       return 0;
-}
-static inline int ata_acpi_push_id(struct ata_device *dev)
-{
-       return 0;
-}
+static inline void ata_acpi_associate(struct ata_host *host) { }
+static inline int ata_acpi_on_suspend(struct ata_port *ap) { return 0; }
+static inline void ata_acpi_on_resume(struct ata_port *ap) { }
+static inline int ata_acpi_on_devcfg(struct ata_device *adev) { return 0; }
 #endif
 
 /* libata-scsi.c */
index 75e95bdbe02fec28c84183cdcedcd6be942d8eb0..010436795d202768ab1da333f6484a28f4ea6d54 100644 (file)
@@ -455,23 +455,21 @@ static struct ata_port_operations ali_c5_port_ops = {
 
 static void ali_init_chipset(struct pci_dev *pdev)
 {
-       u8 rev, tmp;
+       u8 tmp;
        struct pci_dev *north, *isa_bridge;
 
-       pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
-
        /*
         * The chipset revision selects the driver operations and
         * mode data.
         */
 
-       if (rev >= 0x20 && rev < 0xC2) {
+       if (pdev->revision >= 0x20 && pdev->revision < 0xC2) {
                /* 1543-E/F, 1543C-C, 1543C-D, 1543C-E */
                pci_read_config_byte(pdev, 0x4B, &tmp);
                /* Clear CD-ROM DMA write bit */
                tmp &= 0x7F;
                pci_write_config_byte(pdev, 0x4B, tmp);
-       } else if (rev >= 0xC2) {
+       } else if (pdev->revision >= 0xC2) {
                /* Enable cable detection logic */
                pci_read_config_byte(pdev, 0x4B, &tmp);
                pci_write_config_byte(pdev, 0x4B, tmp | 0x08);
@@ -483,21 +481,21 @@ static void ali_init_chipset(struct pci_dev *pdev)
                /* Configure the ALi bridge logic. For non ALi rely on BIOS.
                   Set the south bridge enable bit */
                pci_read_config_byte(isa_bridge, 0x79, &tmp);
-               if (rev == 0xC2)
+               if (pdev->revision == 0xC2)
                        pci_write_config_byte(isa_bridge, 0x79, tmp | 0x04);
-               else if (rev > 0xC2 && rev < 0xC5)
+               else if (pdev->revision > 0xC2 && pdev->revision < 0xC5)
                        pci_write_config_byte(isa_bridge, 0x79, tmp | 0x02);
        }
-       if (rev >= 0x20) {
+       if (pdev->revision >= 0x20) {
                /*
                 * CD_ROM DMA on (0x53 bit 0). Enable this even if we want
                 * to use PIO. 0x53 bit 1 (rev 20 only) - enable FIFO control
                 * via 0x54/55.
                 */
                pci_read_config_byte(pdev, 0x53, &tmp);
-               if (rev <= 0x20)
+               if (pdev->revision <= 0x20)
                        tmp &= ~0x02;
-               if (rev >= 0xc7)
+               if (pdev->revision >= 0xc7)
                        tmp |= 0x03;
                else
                        tmp |= 0x01;    /* CD_ROM enable for DMA */
@@ -520,14 +518,14 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 {
        static const struct ata_port_info info_early = {
                .sht = &ali_sht,
-               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .port_ops = &ali_early_port_ops
        };
        /* Revision 0x20 added DMA */
        static const struct ata_port_info info_20 = {
                .sht = &ali_sht,
-               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48,
+               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
                .port_ops = &ali_20_port_ops
@@ -535,7 +533,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
        /* Revision 0x20 with support logic added UDMA */
        static const struct ata_port_info info_20_udma = {
                .sht = &ali_sht,
-               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48,
+               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
                .udma_mask = 0x07,      /* UDMA33 */
@@ -544,60 +542,58 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
        /* Revision 0xC2 adds UDMA66 */
        static const struct ata_port_info info_c2 = {
                .sht = &ali_sht,
-               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48,
+               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
-               .udma_mask = 0x1f,
+               .udma_mask = ATA_UDMA4,
                .port_ops = &ali_c2_port_ops
        };
        /* Revision 0xC3 is UDMA66 for now */
        static const struct ata_port_info info_c3 = {
                .sht = &ali_sht,
-               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48,
+               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
-               .udma_mask = 0x1f,
+               .udma_mask = ATA_UDMA4,
                .port_ops = &ali_c2_port_ops
        };
        /* Revision 0xC4 is UDMA100 */
        static const struct ata_port_info info_c4 = {
                .sht = &ali_sht,
-               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48,
+               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
-               .udma_mask = 0x3f,
+               .udma_mask = ATA_UDMA5,
                .port_ops = &ali_c2_port_ops
        };
        /* Revision 0xC5 is UDMA133 with LBA48 DMA */
        static const struct ata_port_info info_c5 = {
                .sht = &ali_sht,
-               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
-               .udma_mask = 0x7f,
+               .udma_mask = ATA_UDMA6,
                .port_ops = &ali_c5_port_ops
        };
 
        const struct ata_port_info *ppi[] = { NULL, NULL };
-       u8 rev, tmp;
+       u8 tmp;
        struct pci_dev *isa_bridge;
 
-       pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
-
        /*
         * The chipset revision selects the driver operations and
         * mode data.
         */
 
-       if (rev < 0x20) {
+       if (pdev->revision < 0x20) {
                ppi[0] = &info_early;
-       } else if (rev < 0xC2) {
+       } else if (pdev->revision < 0xC2) {
                ppi[0] = &info_20;
-       } else if (rev == 0xC2) {
+       } else if (pdev->revision == 0xC2) {
                ppi[0] = &info_c2;
-       } else if (rev == 0xC3) {
+       } else if (pdev->revision == 0xC3) {
                ppi[0] = &info_c3;
-       } else if (rev == 0xC4) {
+       } else if (pdev->revision == 0xC4) {
                ppi[0] = &info_c4;
        } else
                ppi[0] = &info_c5;
@@ -605,7 +601,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
        ali_init_chipset(pdev);
 
        isa_bridge = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);
-       if (isa_bridge && rev >= 0x20 && rev < 0xC2) {
+       if (isa_bridge && pdev->revision >= 0x20 && pdev->revision < 0xC2) {
                /* Are we paired with a UDMA capable chip */
                pci_read_config_byte(isa_bridge, 0x5E, &tmp);
                if ((tmp & 0x1E) == 0x12)
index a16f629b7b384518b8eebfccc7cc4ea9178f39c2..b09facad63e17a0f4dac7e64f854b39592899cb0 100644 (file)
@@ -541,7 +541,7 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
        static const struct ata_port_info info[10] = {
                {       /* 0: AMD 7401 */
                        .sht = &amd_sht,
-                       .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+                       .flags = ATA_FLAG_SLAVE_POSS,
                        .pio_mask = 0x1f,
                        .mwdma_mask = 0x07,     /* No SWDMA */
                        .udma_mask = 0x07,      /* UDMA 33 */
@@ -549,91 +549,89 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                },
                {       /* 1: Early AMD7409 - no swdma */
                        .sht = &amd_sht,
-                       .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+                       .flags = ATA_FLAG_SLAVE_POSS,
                        .pio_mask = 0x1f,
                        .mwdma_mask = 0x07,
-                       .udma_mask = 0x1f,      /* UDMA 66 */
+                       .udma_mask = ATA_UDMA4, /* UDMA 66 */
                        .port_ops = &amd66_port_ops
                },
                {       /* 2: AMD 7409, no swdma errata */
                        .sht = &amd_sht,
-                       .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+                       .flags = ATA_FLAG_SLAVE_POSS,
                        .pio_mask = 0x1f,
                        .mwdma_mask = 0x07,
-                       .udma_mask = 0x1f,      /* UDMA 66 */
+                       .udma_mask = ATA_UDMA4, /* UDMA 66 */
                        .port_ops = &amd66_port_ops
                },
                {       /* 3: AMD 7411 */
                        .sht = &amd_sht,
-                       .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+                       .flags = ATA_FLAG_SLAVE_POSS,
                        .pio_mask = 0x1f,
                        .mwdma_mask = 0x07,
-                       .udma_mask = 0x3f,      /* UDMA 100 */
+                       .udma_mask = ATA_UDMA5, /* UDMA 100 */
                        .port_ops = &amd100_port_ops
                },
                {       /* 4: AMD 7441 */
                        .sht = &amd_sht,
-                       .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+                       .flags = ATA_FLAG_SLAVE_POSS,
                        .pio_mask = 0x1f,
                        .mwdma_mask = 0x07,
-                       .udma_mask = 0x3f,      /* UDMA 100 */
+                       .udma_mask = ATA_UDMA5, /* UDMA 100 */
                        .port_ops = &amd100_port_ops
                },
                {       /* 5: AMD 8111*/
                        .sht = &amd_sht,
-                       .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+                       .flags = ATA_FLAG_SLAVE_POSS,
                        .pio_mask = 0x1f,
                        .mwdma_mask = 0x07,
-                       .udma_mask = 0x7f,      /* UDMA 133, no swdma */
+                       .udma_mask = ATA_UDMA6, /* UDMA 133, no swdma */
                        .port_ops = &amd133_port_ops
                },
                {       /* 6: AMD 8111 UDMA 100 (Serenade) */
                        .sht = &amd_sht,
-                       .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+                       .flags = ATA_FLAG_SLAVE_POSS,
                        .pio_mask = 0x1f,
                        .mwdma_mask = 0x07,
-                       .udma_mask = 0x3f,      /* UDMA 100, no swdma */
+                       .udma_mask = ATA_UDMA5, /* UDMA 100, no swdma */
                        .port_ops = &amd133_port_ops
                },
                {       /* 7: Nvidia Nforce */
                        .sht = &amd_sht,
-                       .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+                       .flags = ATA_FLAG_SLAVE_POSS,
                        .pio_mask = 0x1f,
                        .mwdma_mask = 0x07,
-                       .udma_mask = 0x3f,      /* UDMA 100 */
+                       .udma_mask = ATA_UDMA5, /* UDMA 100 */
                        .port_ops = &nv100_port_ops
                },
                {       /* 8: Nvidia Nforce2 and later */
                        .sht = &amd_sht,
-                       .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+                       .flags = ATA_FLAG_SLAVE_POSS,
                        .pio_mask = 0x1f,
                        .mwdma_mask = 0x07,
-                       .udma_mask = 0x7f,      /* UDMA 133, no swdma */
+                       .udma_mask = ATA_UDMA6, /* UDMA 133, no swdma */
                        .port_ops = &nv133_port_ops
                },
                {       /* 9: AMD CS5536 (Geode companion) */
                        .sht = &amd_sht,
-                       .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+                       .flags = ATA_FLAG_SLAVE_POSS,
                        .pio_mask = 0x1f,
                        .mwdma_mask = 0x07,
-                       .udma_mask = 0x3f,      /* UDMA 100 */
+                       .udma_mask = ATA_UDMA5, /* UDMA 100 */
                        .port_ops = &amd100_port_ops
                }
        };
        const struct ata_port_info *ppi[] = { NULL, NULL };
        static int printed_version;
        int type = id->driver_data;
-       u8 rev;
        u8 fifo;
 
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
-       pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
        pci_read_config_byte(pdev, 0x41, &fifo);
 
        /* Check for AMD7409 without swdma errata and if found adjust type */
-       if (type == 1 && rev > 0x7)
+       if (type == 1 && pdev->revision > 0x7)
                type = 2;
 
        /* Check for AMD7411 */
index 03b6ddd2abd246ab3ad427c756fe98894e84c5b0..ce589d96ca424f3083564dc9f193eef0717501f2 100644 (file)
@@ -416,7 +416,7 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
        static int printed_version;
        static const struct ata_port_info info_6210 = {
                .sht            = &artop_sht,
-               .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+               .flags          = ATA_FLAG_SLAVE_POSS,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma0-2 */
                .udma_mask      = ATA_UDMA2,
@@ -424,7 +424,7 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
        };
        static const struct ata_port_info info_626x = {
                .sht            = &artop_sht,
-               .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+               .flags          = ATA_FLAG_SLAVE_POSS,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma0-2 */
                .udma_mask      = ATA_UDMA4,
@@ -432,7 +432,7 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
        };
        static const struct ata_port_info info_626x_fast = {
                .sht            = &artop_sht,
-               .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+               .flags          = ATA_FLAG_SLAVE_POSS,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma0-2 */
                .udma_mask      = ATA_UDMA5,
index 844914681a2ab545f05eb468aafcda747f900b2a..80509be49e7acb0b18cb3c2c94e54aa42e55843e 100644 (file)
@@ -270,7 +270,7 @@ static int atiixp_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
        static const struct ata_port_info info = {
                .sht = &atiixp_sht,
-               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x06,     /* No MWDMA0 support */
                .udma_mask = 0x3F,
@@ -285,6 +285,7 @@ static const struct pci_device_id atiixp[] = {
        { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP300_IDE), },
        { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP400_IDE), },
        { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP600_IDE), },
+       { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP700_IDE), },
 
        { },
 };
index 31cbf8daa299846c702516792a2fe6f20d7dc34b..0feb5ae8c4867fe48be92e2f784ba80df19ff392 100644 (file)
@@ -251,7 +251,7 @@ static int cmd640_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 {
        static const struct ata_port_info info = {
                .sht = &cmd640_sht,
-               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .port_ops = &cmd640_port_ops
        };
index 320a5b10aa98ef3b76582453bc1087819e7165a3..dc443e7dc37c07ee0c138ef475853564d00af6c9 100644 (file)
@@ -380,21 +380,21 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
        static const struct ata_port_info cmd_info[6] = {
                {       /* CMD 643 - no UDMA */
                        .sht = &cmd64x_sht,
-                       .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+                       .flags = ATA_FLAG_SLAVE_POSS,
                        .pio_mask = 0x1f,
                        .mwdma_mask = 0x07,
                        .port_ops = &cmd64x_port_ops
                },
                {       /* CMD 646 with broken UDMA */
                        .sht = &cmd64x_sht,
-                       .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+                       .flags = ATA_FLAG_SLAVE_POSS,
                        .pio_mask = 0x1f,
                        .mwdma_mask = 0x07,
                        .port_ops = &cmd64x_port_ops
                },
                {       /* CMD 646 with working UDMA */
                        .sht = &cmd64x_sht,
-                       .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+                       .flags = ATA_FLAG_SLAVE_POSS,
                        .pio_mask = 0x1f,
                        .mwdma_mask = 0x07,
                        .udma_mask = ATA_UDMA1,
@@ -402,14 +402,14 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                },
                {       /* CMD 646 rev 1  */
                        .sht = &cmd64x_sht,
-                       .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+                       .flags = ATA_FLAG_SLAVE_POSS,
                        .pio_mask = 0x1f,
                        .mwdma_mask = 0x07,
                        .port_ops = &cmd646r1_port_ops
                },
                {       /* CMD 648 */
                        .sht = &cmd64x_sht,
-                       .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+                       .flags = ATA_FLAG_SLAVE_POSS,
                        .pio_mask = 0x1f,
                        .mwdma_mask = 0x07,
                        .udma_mask = ATA_UDMA2,
@@ -417,7 +417,7 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                },
                {       /* CMD 649 */
                        .sht = &cmd64x_sht,
-                       .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+                       .flags = ATA_FLAG_SLAVE_POSS,
                        .pio_mask = 0x1f,
                        .mwdma_mask = 0x07,
                        .udma_mask = ATA_UDMA3,
index 00cf0134079cbed13f1dca350968cc7630633bbb..6bf037d82b5aa9b0a324c37c4c627bc32b38ff27 100644 (file)
@@ -146,7 +146,7 @@ static struct scsi_host_template cs5520_sht = {
        .queuecommand           = ata_scsi_queuecmd,
        .can_queue              = ATA_DEF_QUEUE,
        .this_id                = ATA_SHT_THIS_ID,
-       .sg_tablesize           = LIBATA_MAX_PRD,
+       .sg_tablesize           = LIBATA_DUMB_MAX_PRD,
        .cmd_per_lun            = ATA_SHT_CMD_PER_LUN,
        .emulated               = ATA_SHT_EMULATED,
        .use_clustering         = ATA_SHT_USE_CLUSTERING,
@@ -178,7 +178,7 @@ static struct ata_port_operations cs5520_port_ops = {
        .bmdma_start            = ata_bmdma_start,
        .bmdma_stop             = ata_bmdma_stop,
        .bmdma_status           = ata_bmdma_status,
-       .qc_prep                = ata_qc_prep,
+       .qc_prep                = ata_dumb_qc_prep,
        .qc_issue               = ata_qc_issue_prot,
        .data_xfer              = ata_data_xfer,
 
index 848f0309bf038dcf0be656afbc8882dbea8da2aa..68f150a1e2f480b42d42ca88895563ba6a91fa16 100644 (file)
@@ -167,7 +167,7 @@ static struct scsi_host_template cs5530_sht = {
        .queuecommand           = ata_scsi_queuecmd,
        .can_queue              = ATA_DEF_QUEUE,
        .this_id                = ATA_SHT_THIS_ID,
-       .sg_tablesize           = LIBATA_MAX_PRD,
+       .sg_tablesize           = LIBATA_DUMB_MAX_PRD,
        .cmd_per_lun            = ATA_SHT_CMD_PER_LUN,
        .emulated               = ATA_SHT_EMULATED,
        .use_clustering         = ATA_SHT_USE_CLUSTERING,
@@ -201,7 +201,7 @@ static struct ata_port_operations cs5530_port_ops = {
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
        .cable_detect   = ata_cable_40wire,
 
-       .qc_prep        = ata_qc_prep,
+       .qc_prep        = ata_dumb_qc_prep,
        .qc_issue       = cs5530_qc_issue_prot,
 
        .data_xfer      = ata_data_xfer,
@@ -266,7 +266,7 @@ static int cs5530_init_chip(void)
        }
 
        pci_set_master(cs5530_0);
-       pci_set_mwi(cs5530_0);
+       pci_try_set_mwi(cs5530_0);
 
        /*
         * Set PCI CacheLineSize to 16-bytes:
@@ -337,7 +337,7 @@ static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 {
        static const struct ata_port_info info = {
                .sht = &cs5530_sht,
-               .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
                .udma_mask = 0x07,
@@ -346,7 +346,7 @@ static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
        /* The docking connector doesn't do UDMA, and it seems not MWDMA */
        static const struct ata_port_info info_palmax_secondary = {
                .sht = &cs5530_sht,
-               .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .port_ops = &cs5530_port_ops
        };
index aa3256fb9f7ab961bf50031ae67077f9d235c6f8..360b6f32e17ec2ca06cf5b748c3c8c170d71fbe6 100644 (file)
@@ -225,10 +225,10 @@ static int cs5535_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
        static const struct ata_port_info info = {
                .sht = &cs5535_sht,
-               .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
-               .udma_mask = 0x1f,
+               .udma_mask = ATA_UDMA4,
                .port_ops = &cs5535_port_ops
        };
        const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info };
index d41a7691dd8ea634c55dd990eeead1dfb1ff28f0..6cbc8778bf4f2fd2766f1ae837d88216820afcfd 100644 (file)
@@ -167,7 +167,7 @@ static int cy82c693_init_one(struct pci_dev *pdev, const struct pci_device_id *i
 {
        static const struct ata_port_info info = {
                .sht = &cy82c693_sht,
-               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
                .port_ops = &cy82c693_port_ops
index 079248a9b4604c49a017e253ac016f854f68e2d2..c8ba59c5611429749b0fc06779acc12e592254bd 100644 (file)
@@ -303,7 +303,7 @@ static int efar_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        static int printed_version;
        static const struct ata_port_info info = {
                .sht            = &efar_sht,
-               .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+               .flags          = ATA_FLAG_SLAVE_POSS,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma1-2 */
                .udma_mask      = 0x0f, /* UDMA 66 */
index 0c9cb60907117ed5b794d72b0d3558970de61d38..6f7d34ad19ef34152e966434c577c1cb69c88a3e 100644 (file)
@@ -393,10 +393,10 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
        static const struct ata_port_info info_hpt366 = {
                .sht = &hpt36x_sht,
-               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
-               .udma_mask = 0x1f,
+               .udma_mask = ATA_UDMA4,
                .port_ops = &hpt366_port_ops
        };
        struct ata_port_info info = info_hpt366;
index a8c0cbeca399352323d0fea5b01a9ec906484239..b0af65aadde3a9d48e84490bce15c89b9153f1fa 100644 (file)
@@ -889,25 +889,25 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
        /* HPT370 - UDMA100 */
        static const struct ata_port_info info_hpt370 = {
                .sht = &hpt37x_sht,
-               .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
-               .udma_mask = 0x3f,
+               .udma_mask = ATA_UDMA5,
                .port_ops = &hpt370_port_ops
        };
        /* HPT370A - UDMA100 */
        static const struct ata_port_info info_hpt370a = {
                .sht = &hpt37x_sht,
-               .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
-               .udma_mask = 0x3f,
+               .udma_mask = ATA_UDMA5,
                .port_ops = &hpt370a_port_ops
        };
        /* HPT370 - UDMA100 */
        static const struct ata_port_info info_hpt370_33 = {
                .sht = &hpt37x_sht,
-               .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
                .udma_mask = 0x0f,
@@ -916,7 +916,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
        /* HPT370A - UDMA100 */
        static const struct ata_port_info info_hpt370a_33 = {
                .sht = &hpt37x_sht,
-               .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
                .udma_mask = 0x0f,
@@ -925,19 +925,19 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
        /* HPT371, 372 and friends - UDMA133 */
        static const struct ata_port_info info_hpt372 = {
                .sht = &hpt37x_sht,
-               .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
-               .udma_mask = 0x7f,
+               .udma_mask = ATA_UDMA6,
                .port_ops = &hpt372_port_ops
        };
        /* HPT374 - UDMA100 */
        static const struct ata_port_info info_hpt374 = {
                .sht = &hpt37x_sht,
-               .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
-               .udma_mask = 0x3f,
+               .udma_mask = ATA_UDMA5,
                .port_ops = &hpt374_port_ops
        };
 
index e947433cb37dd3177b902557aad23ea7d52686f8..aa29cde09f8bbd594022f23a1e7803b6adfc5d87 100644 (file)
@@ -490,10 +490,10 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
        /* HPT372N and friends - UDMA133 */
        static const struct ata_port_info info = {
                .sht = &hpt3x2n_sht,
-               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
-               .udma_mask = 0x7f,
+               .udma_mask = ATA_UDMA6,
                .port_ops = &hpt3x2n_port_ops
        };
        struct ata_port_info port = info;
index 8ce5e23a5f75d3961186b21f0a081b389542924e..be0f05efac6d1c93a87628b37d1a3d62afc9ad4e 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME       "pata_hpt3x3"
-#define DRV_VERSION    "0.4.3"
+#define DRV_VERSION    "0.5.3"
 
 /**
  *     hpt3x3_set_piomode              -       PIO setup
@@ -52,6 +52,7 @@ static void hpt3x3_set_piomode(struct ata_port *ap, struct ata_device *adev)
        pci_write_config_dword(pdev, 0x48, r2);
 }
 
+#if defined(CONFIG_PATA_HPT3X3_DMA)
 /**
  *     hpt3x3_set_dmamode              -       DMA timing setup
  *     @ap: ATA interface
@@ -59,6 +60,9 @@ static void hpt3x3_set_piomode(struct ata_port *ap, struct ata_device *adev)
  *
  *     Set up the channel for MWDMA or UDMA modes. Much the same as with
  *     PIO, load the mode number and then set MWDMA or UDMA flag.
+ *
+ *     0x44 : bit 0-2 master mode, 3-5 slave mode, etc
+ *     0x48 : bit 4/0 DMA/UDMA bit 5/1 for slave etc
  */
 
 static void hpt3x3_set_dmamode(struct ata_port *ap, struct ata_device *adev)
@@ -76,13 +80,26 @@ static void hpt3x3_set_dmamode(struct ata_port *ap, struct ata_device *adev)
        r2 &= ~(0x11 << dn);    /* Clear MWDMA and UDMA bits */
 
        if (adev->dma_mode >= XFER_UDMA_0)
-               r2 |= 0x01 << dn;       /* Ultra mode */
+               r2 |= (0x10 << dn);     /* Ultra mode */
        else
-               r2 |= 0x10 << dn;       /* MWDMA */
+               r2 |= (0x01 << dn);     /* MWDMA */
 
        pci_write_config_dword(pdev, 0x44, r1);
        pci_write_config_dword(pdev, 0x48, r2);
 }
+#endif /* CONFIG_PATA_HPT3X3_DMA */
+
+/**
+ *     hpt3x3_atapi_dma        -       ATAPI DMA check
+ *     @qc: Queued command
+ *
+ *     Just say no - we don't do ATAPI DMA
+ */
+
+static int hpt3x3_atapi_dma(struct ata_queued_cmd *qc)
+{
+       return 1;
+}
 
 static struct scsi_host_template hpt3x3_sht = {
        .module                 = THIS_MODULE,
@@ -105,7 +122,9 @@ static struct scsi_host_template hpt3x3_sht = {
 static struct ata_port_operations hpt3x3_port_ops = {
        .port_disable   = ata_port_disable,
        .set_piomode    = hpt3x3_set_piomode,
+#if defined(CONFIG_PATA_HPT3X3_DMA)
        .set_dmamode    = hpt3x3_set_dmamode,
+#endif
        .mode_filter    = ata_pci_default_filter,
 
        .tf_load        = ata_tf_load,
@@ -124,6 +143,7 @@ static struct ata_port_operations hpt3x3_port_ops = {
        .bmdma_start    = ata_bmdma_start,
        .bmdma_stop     = ata_bmdma_stop,
        .bmdma_status   = ata_bmdma_status,
+       .check_atapi_dma= hpt3x3_atapi_dma,
 
        .qc_prep        = ata_qc_prep,
        .qc_issue       = ata_qc_issue_prot,
@@ -158,32 +178,79 @@ static void hpt3x3_init_chipset(struct pci_dev *dev)
                pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20);
 }
 
-
 /**
  *     hpt3x3_init_one         -       Initialise an HPT343/363
- *     @dev: PCI device
+ *     @pdev: PCI device
  *     @id: Entry in match table
  *
- *     Perform basic initialisation. The chip has a quirk that it won't
- *     function unless it is at XX00. The old ATA driver touched this up
- *     but we leave it for pci quirks to do properly.
+ *     Perform basic initialisation. We set the device up so we access all
+ *     ports via BAR4. This is neccessary to work around errata.
  */
 
-static int hpt3x3_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+static int hpt3x3_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 {
+       static int printed_version;
        static const struct ata_port_info info = {
                .sht = &hpt3x3_sht,
-               .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
+#if defined(CONFIG_PATA_HPT3X3_DMA)
+               /* Further debug needed */
                .mwdma_mask = 0x07,
                .udma_mask = 0x07,
+#endif
                .port_ops = &hpt3x3_port_ops
        };
+       /* Register offsets of taskfiles in BAR4 area */
+       static const u8 offset_cmd[2] = { 0x20, 0x28 };
+       static const u8 offset_ctl[2] = { 0x36, 0x3E };
        const struct ata_port_info *ppi[] = { &info, NULL };
-
-       hpt3x3_init_chipset(dev);
-       /* Now kick off ATA set up */
-       return ata_pci_init_one(dev, ppi);
+       struct ata_host *host;
+       int i, rc;
+       void __iomem *base;
+
+       hpt3x3_init_chipset(pdev);
+
+       if (!printed_version++)
+               dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
+
+       host = ata_host_alloc_pinfo(&pdev->dev, ppi, 2);
+       if (!host)
+               return -ENOMEM;
+       /* acquire resources and fill host */
+       rc = pcim_enable_device(pdev);
+       if (rc)
+               return rc;
+
+       /* Everything is relative to BAR4 if we set up this way */
+       rc = pcim_iomap_regions(pdev, 1 << 4, DRV_NAME);
+       if (rc == -EBUSY)
+               pcim_pin_device(pdev);
+       if (rc)
+               return rc;
+       host->iomap = pcim_iomap_table(pdev);
+       rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
+       if (rc)
+               return rc;
+       rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
+       if (rc)
+               return rc;
+
+       base = host->iomap[4];  /* Bus mastering base */
+
+       for (i = 0; i < host->n_ports; i++) {
+               struct ata_ioports *ioaddr = &host->ports[i]->ioaddr;
+
+               ioaddr->cmd_addr = base + offset_cmd[i];
+               ioaddr->altstatus_addr =
+               ioaddr->ctl_addr = base + offset_ctl[i];
+               ioaddr->scr_addr = NULL;
+               ata_std_ports(ioaddr);
+               ioaddr->bmdma_addr = base + 8 * i;
+       }
+       pci_set_master(pdev);
+       return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED,
+                                &hpt3x3_sht);
 }
 
 #ifdef CONFIG_PM
index c791a46df461f3d5de48839cf2c898390c7c8cfe..321d98b0bed299a1a73e738e9d40bc308af80ef0 100644 (file)
@@ -530,7 +530,7 @@ static int __devinit pata_icside_add_ports(struct pata_icside_info *info)
 
                ap->pio_mask = 0x1f;
                ap->mwdma_mask = info->mwdma_mask;
-               ap->flags |= ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST;
+               ap->flags |= ATA_FLAG_SLAVE_POSS;
                ap->ops = &pata_icside_port_ops;
 
                pata_icside_setup_ioaddr(&ap->ioaddr, info->base, info->port[i]);
index 95b0bb61788b03285748a6c742a697df0048540d..b8af55e8915695a45538522092e1f387ce9ce483 100644 (file)
@@ -313,10 +313,10 @@ static int it8213_init_one (struct pci_dev *pdev, const struct pci_device_id *en
        static int printed_version;
        static const struct ata_port_info info = {
                .sht            = &it8213_sht,
-               .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+               .flags          = ATA_FLAG_SLAVE_POSS,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma0-2 */
-               .udma_mask      = 0x1f, /* UDMA 100 */
+               .udma_mask      = ATA_UDMA4, /* FIXME: want UDMA 100? */
                .port_ops       = &it8213_ops,
        };
        /* Current IT8213 stuff is single port */
index 12c6e08cc4d1ed2d525886c428038181871e7e4b..430673be1df7560aea3d4be5c9f85e1c53fb0ceb 100644 (file)
@@ -587,8 +587,7 @@ static int it821x_port_start(struct ata_port *ap)
        itdev->want[1][1] = ATA_ANY;
        itdev->last_device = -1;
 
-       pci_read_config_byte(pdev, PCI_REVISION_ID, &conf);
-       if (conf == 0x10) {
+       if (pdev->revision == 0x11) {
                itdev->timing10 = 1;
                /* Need to disable ATAPI DMA for this case */
                if (!itdev->smart)
@@ -714,17 +713,17 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 
        static const struct ata_port_info info_smart = {
                .sht = &it821x_sht,
-               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
                .port_ops = &it821x_smart_port_ops
        };
        static const struct ata_port_info info_passthru = {
                .sht = &it821x_sht,
-               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
-               .udma_mask = 0x7f,
+               .udma_mask = ATA_UDMA6,
                .port_ops = &it821x_passthru_port_ops
        };
 
index 8d2bc1e9e871883bdb8c1fc505b989c142fd6c21..4ca7fd6118d50f6d52a1b7c464d1266614282b2d 100644 (file)
@@ -1,13 +1,14 @@
 /*
  * ixp4xx PATA/Compact Flash driver
- * Copyright (c) 2006 Tower Technologies
+ * Copyright (C) 2006-07 Tower Technologies
  * Author: Alessandro Zummo <a.zummo@towertech.it>
  *
  * An ATA driver to handle a Compact Flash connected
  * to the ixp4xx expansion bus in TrueIDE mode. The CF
  * must have it chip selects connected to two CS lines
- * on the ixp4xx. The interrupt line is optional, if not
- * specified the driver will run in polling mode.
+ * on the ixp4xx. In the irq is not available, you might
+ * want to modify both this driver and libata to run in
+ * polling mode.
  *
  * 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
@@ -23,7 +24,7 @@
 #include <scsi/scsi_host.h>
 
 #define DRV_NAME       "pata_ixp4xx_cf"
-#define DRV_VERSION    "0.1.3"
+#define DRV_VERSION    "0.2"
 
 static int ixp4xx_set_mode(struct ata_port *ap, struct ata_device **error)
 {
@@ -42,13 +43,6 @@ static int ixp4xx_set_mode(struct ata_port *ap, struct ata_device **error)
        return 0;
 }
 
-static void ixp4xx_phy_reset(struct ata_port *ap)
-{
-       ap->cbl = ATA_CBL_PATA40;
-       ata_port_probe(ap);
-       ata_bus_reset(ap);
-}
-
 static void ixp4xx_mmio_data_xfer(struct ata_device *adev, unsigned char *buf,
                                unsigned int buflen, int write_data)
 {
@@ -56,7 +50,7 @@ static void ixp4xx_mmio_data_xfer(struct ata_device *adev, unsigned char *buf,
        unsigned int words = buflen >> 1;
        u16 *buf16 = (u16 *) buf;
        struct ata_port *ap = adev->ap;
-       void __iomem *mmio = (void __iomem *)ap->ioaddr.data_addr;
+       void __iomem *mmio = ap->ioaddr.data_addr;
        struct ixp4xx_pata_data *data = ap->host->dev->platform_data;
 
        /* set the expansion bus in 16bit mode and restore
@@ -92,10 +86,6 @@ static void ixp4xx_mmio_data_xfer(struct ata_device *adev, unsigned char *buf,
        *data->cs0_cfg |= 0x01;
 }
 
-static void ixp4xx_irq_clear(struct ata_port *ap)
-{
-}
-
 static struct scsi_host_template ixp4xx_sht = {
        .module                 = THIS_MODULE,
        .name                   = DRV_NAME,
@@ -115,29 +105,32 @@ static struct scsi_host_template ixp4xx_sht = {
 };
 
 static struct ata_port_operations ixp4xx_port_ops = {
-       .set_mode       = ixp4xx_set_mode,
-       .mode_filter    = ata_pci_default_filter,
-
-       .port_disable   = ata_port_disable,
-       .tf_load        = ata_tf_load,
-       .tf_read        = ata_tf_read,
-       .check_status   = ata_check_status,
-       .exec_command   = ata_exec_command,
-       .dev_select     = ata_std_dev_select,
-
-       .qc_prep        = ata_qc_prep,
-       .qc_issue       = ata_qc_issue_prot,
-       .eng_timeout    = ata_eng_timeout,
-       .data_xfer      = ixp4xx_mmio_data_xfer,
-       .cable_detect   = ata_cable_40wire,
-
-       .irq_clear      = ixp4xx_irq_clear,
-       .irq_on         = ata_irq_on,
-       .irq_ack        = ata_irq_ack,
-
-       .port_start     = ata_port_start,
-
-       .phy_reset      = ixp4xx_phy_reset,
+       .set_mode               = ixp4xx_set_mode,
+       .mode_filter            = ata_pci_default_filter,
+
+       .port_disable           = ata_port_disable,
+       .tf_load                = ata_tf_load,
+       .tf_read                = ata_tf_read,
+       .exec_command           = ata_exec_command,
+       .check_status           = ata_check_status,
+       .dev_select             = ata_std_dev_select,
+
+       .freeze                 = ata_bmdma_freeze,
+       .thaw                   = ata_bmdma_thaw,
+       .error_handler          = ata_bmdma_error_handler,
+       .post_internal_cmd      = ata_bmdma_post_internal_cmd,
+
+       .qc_prep                = ata_qc_prep,
+       .qc_issue               = ata_qc_issue_prot,
+       .data_xfer              = ixp4xx_mmio_data_xfer,
+       .cable_detect           = ata_cable_40wire,
+
+       .irq_handler            = ata_interrupt,
+       .irq_clear              = ata_bmdma_irq_clear,
+       .irq_on                 = ata_irq_on,
+       .irq_ack                = ata_dummy_irq_ack,
+
+       .port_start             = ata_port_start,
 };
 
 static void ixp4xx_setup_port(struct ata_ioports *ioaddr,
@@ -178,7 +171,6 @@ static __devinit int ixp4xx_pata_probe(struct platform_device *pdev)
        struct ata_host *host;
        struct ata_port *ap;
        struct ixp4xx_pata_data *data = pdev->dev.platform_data;
-       int rc;
 
        cs0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        cs1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
@@ -211,10 +203,6 @@ static __devinit int ixp4xx_pata_probe(struct platform_device *pdev)
        ap->pio_mask = 0x1f; /* PIO4 */
        ap->flags |= ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY | ATA_FLAG_NO_ATAPI;
 
-       /* run in polling mode if no irq has been assigned */
-       if (!irq)
-               ap->flags |= ATA_FLAG_PIO_POLLING;
-
        ixp4xx_setup_port(&ap->ioaddr, data);
 
        dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
index 2af7ff8256ca87ea8cb9239328911c000fc92b51..4d67f238eee25ddf5f0e6ee917f7b8b0141de9b3 100644 (file)
@@ -193,11 +193,11 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i
 {
        static const struct ata_port_info info = {
                .sht            = &jmicron_sht,
-               .flags  = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+               .flags  = ATA_FLAG_SLAVE_POSS,
 
                .pio_mask       = 0x1f,
                .mwdma_mask     = 0x07,
-               .udma_mask      = 0x3f,
+               .udma_mask      = ATA_UDMA5,
 
                .port_ops       = &jmicron_ops,
        };
index edbfe0dbbf7824188be84e2d41d3bfe8ed230eb6..87594c04d3a371d7ce69c24a0b8c018455e2f8c2 100644 (file)
@@ -163,22 +163,22 @@ static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *i
 {
        static const struct ata_port_info info = {
                .sht            = &marvell_sht,
-               .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+               .flags          = ATA_FLAG_SLAVE_POSS,
 
                .pio_mask       = 0x1f,
                .mwdma_mask     = 0x07,
-               .udma_mask      = 0x3f,
+               .udma_mask      = ATA_UDMA5,
 
                .port_ops       = &marvell_ops,
        };
        static const struct ata_port_info info_sata = {
                .sht            = &marvell_sht,
                /* Slave possible as its magically mapped not real */
-               .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+               .flags          = ATA_FLAG_SLAVE_POSS,
 
                .pio_mask       = 0x1f,
                .mwdma_mask     = 0x07,
-               .udma_mask      = 0x7f,
+               .udma_mask      = ATA_UDMA6,
 
                .port_ops       = &marvell_ops,
        };
index 368fac7d168be3cbb79a4ea1c6fa032360b1804c..182e83c9047b2bed550b82194c2daabd522437be 100644 (file)
@@ -467,13 +467,27 @@ mpc52xx_ata_remove(struct of_device *op)
 static int
 mpc52xx_ata_suspend(struct of_device *op, pm_message_t state)
 {
-       return 0;       /* FIXME : What to do here ? */
+       struct ata_host *host = dev_get_drvdata(&op->dev);
+
+       return ata_host_suspend(host, state);
 }
 
 static int
 mpc52xx_ata_resume(struct of_device *op)
 {
-       return 0;       /* FIXME : What to do here ? */
+       struct ata_host *host = dev_get_drvdata(&op->dev);
+       struct mpc52xx_ata_priv *priv = host->private_data;
+       int rv;
+
+       rv = mpc52xx_ata_hw_init(priv);
+       if (rv) {
+               printk(KERN_ERR DRV_NAME ": Error during HW init\n");
+               return rv;
+       }
+
+       ata_host_resume(host);
+
+       return 0;
 }
 
 #endif
index 81f563458666b62d550df914d9547399f0a8b698..40eb574828bf759b1b8a103c8431305819197e2e 100644 (file)
@@ -94,12 +94,12 @@ static int netcell_init_one (struct pci_dev *pdev, const struct pci_device_id *e
        static int printed_version;
        static const struct ata_port_info info = {
                .sht            = &netcell_sht,
-               .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+               .flags          = ATA_FLAG_SLAVE_POSS,
                /* Actually we don't really care about these as the
                   firmware deals with it */
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma0-2 */
-               .udma_mask      = 0x3f, /* UDMA 133 */
+               .udma_mask      = ATA_UDMA5, /* UDMA 133 */
                .port_ops       = &netcell_ops,
        };
        const struct ata_port_info *port_info[] = { &info, NULL };
index ea70ec744879bbc1bc1cb8ec854d2ed5f7c1e5c6..2f5d714ebfc4d5c7c844e2405e0ccb6b4bf3d193 100644 (file)
@@ -193,7 +193,7 @@ static int ns87410_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
        static const struct ata_port_info info = {
                .sht = &ns87410_sht,
-               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x0F,
                .port_ops = &ns87410_port_ops
        };
index 29c23ddd65504d8256ba44400cb321bd59c28882..091a70a0ef1cf0cd391e16e83568cf01103b7dad 100644 (file)
@@ -291,7 +291,7 @@ static int oldpiix_init_one (struct pci_dev *pdev, const struct pci_device_id *e
        static int printed_version;
        static const struct ata_port_info info = {
                .sht            = &oldpiix_sht,
-               .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+               .flags          = ATA_FLAG_SLAVE_POSS,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma1-2 */
                .port_ops       = &oldpiix_pata_ops,
index 1c44653e1e0653751a07075ac68f324f34ae83e7..458bf67f766fd246cf89539f13bc54b175322e13 100644 (file)
@@ -218,7 +218,7 @@ static int opti_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
        static const struct ata_port_info info = {
                .sht = &opti_sht,
-               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .port_ops = &opti_port_ops
        };
index 3093b02286ce93289a0bffd9934300b17472b734..f89bdfde16d067469528557f0036dbaf5304a65e 100644 (file)
@@ -484,14 +484,14 @@ static int optidma_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
        static const struct ata_port_info info_82c700 = {
                .sht = &optidma_sht,
-               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
                .port_ops = &optidma_port_ops
        };
        static const struct ata_port_info info_82c700_udma = {
                .sht = &optidma_sht,
-               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
                .udma_mask = 0x07,
index d277246b7337ace170887c2607dc7ed14d73cd75..92447bed5e7716f615b423672bf0e52e524ce1f9 100644 (file)
@@ -320,7 +320,7 @@ static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id
        static const struct ata_port_info info[3] = {
                {
                        .sht = &pdc202xx_sht,
-                       .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+                       .flags = ATA_FLAG_SLAVE_POSS,
                        .pio_mask = 0x1f,
                        .mwdma_mask = 0x07,
                        .udma_mask = ATA_UDMA2,
@@ -328,7 +328,7 @@ static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id
                },
                {
                        .sht = &pdc202xx_sht,
-                       .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+                       .flags = ATA_FLAG_SLAVE_POSS,
                        .pio_mask = 0x1f,
                        .mwdma_mask = 0x07,
                        .udma_mask = ATA_UDMA4,
@@ -336,7 +336,7 @@ static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id
                },
                {
                        .sht = &pdc202xx_sht,
-                       .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+                       .flags = ATA_FLAG_SLAVE_POSS,
                        .pio_mask = 0x1f,
                        .mwdma_mask = 0x07,
                        .udma_mask = ATA_UDMA5,
index cbb7866940d6e5eeba77363f54a9ef764c5d9550..79f841bca593defac6f1e1926145f92a36a59d06 100644 (file)
@@ -139,6 +139,7 @@ static int __devinit pata_platform_probe(struct platform_device *pdev)
        struct resource *io_res, *ctl_res;
        struct ata_host *host;
        struct ata_port *ap;
+       struct pata_platform_info *pp_info;
        unsigned int mmio;
 
        /*
@@ -208,11 +209,12 @@ static int __devinit pata_platform_probe(struct platform_device *pdev)
 
        ap->ioaddr.altstatus_addr = ap->ioaddr.ctl_addr;
 
-       pata_platform_setup_port(&ap->ioaddr, pdev->dev.platform_data);
+       pp_info = (struct pata_platform_info *)(pdev->dev.platform_data);
+       pata_platform_setup_port(&ap->ioaddr, pp_info);
 
        /* activate */
        return ata_host_activate(host, platform_get_irq(pdev, 0), ata_interrupt,
-                                0, &pata_platform_sht);
+                                pp_info->irq_flags, &pata_platform_sht);
 }
 
 /**
index ba96b54f5b873660c82ef3e997a038e5afc88410..7d1aabed422db6bd11c45c6f951171bed7a2c564 100644 (file)
@@ -257,7 +257,7 @@ static int radisys_init_one (struct pci_dev *pdev, const struct pci_device_id *e
        static int printed_version;
        static const struct ata_port_info info = {
                .sht            = &radisys_sht,
-               .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+               .flags          = ATA_FLAG_SLAVE_POSS,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma1-2 */
                .udma_mask      = 0x14, /* UDMA33/66 only */
index a3488b41ad26a638750eb978d78fde02f6b0792c..7632fcb070ca8b1a85562fb0aee9ed2e1bdbfc35 100644 (file)
@@ -133,7 +133,7 @@ static int rz1000_init_one (struct pci_dev *pdev, const struct pci_device_id *en
        static int printed_version;
        static const struct ata_port_info info = {
                .sht = &rz1000_sht,
-               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .port_ops = &rz1000_port_ops
        };
index 1233063ab9a8dc568404314dcec12995fc8cbe02..b8b2d11e4180c29f13a7f30303c628f49bd23a85 100644 (file)
@@ -185,7 +185,7 @@ static struct scsi_host_template sc1200_sht = {
        .queuecommand           = ata_scsi_queuecmd,
        .can_queue              = ATA_DEF_QUEUE,
        .this_id                = ATA_SHT_THIS_ID,
-       .sg_tablesize           = LIBATA_MAX_PRD,
+       .sg_tablesize           = LIBATA_DUMB_MAX_PRD,
        .cmd_per_lun            = ATA_SHT_CMD_PER_LUN,
        .emulated               = ATA_SHT_EMULATED,
        .use_clustering         = ATA_SHT_USE_CLUSTERING,
@@ -219,7 +219,7 @@ static struct ata_port_operations sc1200_port_ops = {
        .bmdma_stop     = ata_bmdma_stop,
        .bmdma_status   = ata_bmdma_status,
 
-       .qc_prep        = ata_qc_prep,
+       .qc_prep        = ata_dumb_qc_prep,
        .qc_issue       = sc1200_qc_issue_prot,
 
        .data_xfer      = ata_data_xfer,
@@ -245,7 +245,7 @@ static int sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
        static const struct ata_port_info info = {
                .sht = &sc1200_sht,
-               .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
                .udma_mask = 0x07,
index 61502bc7bf1d4bcf06a74fc2452371eb0da21aa8..c55667e0eb65a5978f2b786707afad88f5c30e6e 100644 (file)
@@ -238,6 +238,12 @@ static void scc_set_dmamode (struct ata_port *ap, struct ata_device *adev)
        else
                offset = 0;     /* 100MHz */
 
+       /* errata A308 workaround: limit ATAPI UDMA mode to UDMA4 */
+       if (adev->class == ATA_DEV_ATAPI && speed > XFER_UDMA_4) {
+               printk(KERN_INFO "%s: limit ATAPI UDMA to UDMA4\n", DRV_NAME);
+               speed = XFER_UDMA_4;
+       }
+
        if (speed >= XFER_UDMA_0)
                idx = speed - XFER_UDMA_0;
        else
@@ -724,22 +730,36 @@ static void scc_bmdma_stop (struct ata_queued_cmd *qc)
 
 static u8 scc_bmdma_status (struct ata_port *ap)
 {
-       u8 host_stat;
        void __iomem *mmio = ap->ioaddr.bmdma_addr;
-
-       host_stat = in_be32(mmio + SCC_DMA_STATUS);
-
-       /* Workaround for PTERADD: emulate DMA_INTR when
-        * - IDE_STATUS[ERR] = 1
-        * - INT_STATUS[INTRQ] = 1
-        * - DMA_STATUS[IORACTA] = 1
-        */
-       if (!(host_stat & ATA_DMA_INTR)) {
-               u32 int_status = in_be32(mmio + SCC_DMA_INTST);
-               if (ata_altstatus(ap) & ATA_ERR &&
-                   int_status & INTSTS_INTRQ &&
-                   host_stat & ATA_DMA_ACTIVE)
-                       host_stat |= ATA_DMA_INTR;
+       u8 host_stat = in_be32(mmio + SCC_DMA_STATUS);
+       u32 int_status = in_be32(mmio + SCC_DMA_INTST);
+       struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag);
+       static int retry = 0;
+
+       /* return if IOS_SS is cleared */
+       if (!(in_be32(mmio + SCC_DMA_CMD) & ATA_DMA_START))
+               return host_stat;
+
+       /* errata A252,A308 workaround: Step4 */
+       if (ata_altstatus(ap) & ATA_ERR && int_status & INTSTS_INTRQ)
+               return (host_stat | ATA_DMA_INTR);
+
+       /* errata A308 workaround Step5 */
+       if (int_status & INTSTS_IOIRQS) {
+               host_stat |= ATA_DMA_INTR;
+
+               /* We don't check ATAPI DMA because it is limited to UDMA4 */
+               if ((qc->tf.protocol == ATA_PROT_DMA &&
+                    qc->dev->xfer_mode > XFER_UDMA_4)) {
+                       if (!(int_status & INTSTS_ACTEINT)) {
+                               printk(KERN_WARNING "ata%u: data lost occurred. (ACTEINT==0, retry:%d)\n",
+                                      ap->print_id, retry);
+                               host_stat |= ATA_DMA_ERR;
+                               if (retry++)
+                                       ap->udma_mask >>= 1;
+                       } else
+                               retry = 0;
+               }
        }
 
        return host_stat;
@@ -892,10 +912,6 @@ static void scc_std_postreset (struct ata_port *ap, unsigned int *classes)
 {
        DPRINTK("ENTER\n");
 
-       /* re-enable interrupts */
-       if (!ap->ops->error_handler)
-               ap->ops->irq_on(ap);
-
        /* is double-select really necessary? */
        if (classes[0] != ATA_DEV_NONE)
                ap->ops->dev_select(ap, 1);
index 1e8f421963c7259dada806d741e9a0d42d2626d8..89691541fe5936f9e2c51a8c27dc2b6b0dffafb9 100644 (file)
@@ -410,11 +410,8 @@ static int serverworks_fixup_osb4(struct pci_dev *pdev)
 
 static int serverworks_fixup_csb(struct pci_dev *pdev)
 {
-       u8 rev;
        u8 btr;
 
-       pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
-
        /* Third Channel Test */
        if (!(PCI_FUNC(pdev->devfn) & 1)) {
                struct pci_dev * findev = NULL;
@@ -456,7 +453,7 @@ static int serverworks_fixup_csb(struct pci_dev *pdev)
        if (!(PCI_FUNC(pdev->devfn) & 1))
                btr |= 0x2;
        else
-               btr |= (rev >= SVWKS_CSB5_REVISION_NEW) ? 0x3 : 0x2;
+               btr |= (pdev->revision >= SVWKS_CSB5_REVISION_NEW) ? 0x3 : 0x2;
        pci_write_config_byte(pdev, 0x5A, btr);
 
        return btr;
@@ -478,31 +475,31 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id
        static const struct ata_port_info info[4] = {
                { /* OSB4 */
                        .sht = &serverworks_sht,
-                       .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+                       .flags = ATA_FLAG_SLAVE_POSS,
                        .pio_mask = 0x1f,
                        .mwdma_mask = 0x07,
                        .udma_mask = 0x07,
                        .port_ops = &serverworks_osb4_port_ops
                }, { /* OSB4 no UDMA */
                        .sht = &serverworks_sht,
-                       .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+                       .flags = ATA_FLAG_SLAVE_POSS,
                        .pio_mask = 0x1f,
                        .mwdma_mask = 0x07,
                        .udma_mask = 0x00,
                        .port_ops = &serverworks_osb4_port_ops
                }, { /* CSB5 */
                        .sht = &serverworks_sht,
-                       .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+                       .flags = ATA_FLAG_SLAVE_POSS,
                        .pio_mask = 0x1f,
                        .mwdma_mask = 0x07,
-                       .udma_mask = 0x1f,
+                       .udma_mask = ATA_UDMA4,
                        .port_ops = &serverworks_csb_port_ops
                }, { /* CSB5 - later revisions*/
                        .sht = &serverworks_sht,
-                       .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+                       .flags = ATA_FLAG_SLAVE_POSS,
                        .pio_mask = 0x1f,
                        .mwdma_mask = 0x07,
-                       .udma_mask = 0x3f,
+                       .udma_mask = ATA_UDMA5,
                        .port_ops = &serverworks_csb_port_ops
                }
        };
index 440e2cb6ee753dc4912707940943ddb9271ef567..b0cd52d6e3fbc996b5c63e6d02c21c9b5b32aa18 100644 (file)
@@ -35,6 +35,8 @@
 #define DRV_NAME "pata_sil680"
 #define DRV_VERSION "0.4.6"
 
+#define SIL680_MMIO_BAR                5
+
 /**
  *     sil680_selreg           -       return register base
  *     @hwif: interface
@@ -293,8 +295,8 @@ static u8 sil680_init_chip(struct pci_dev *pdev)
 
        pci_read_config_byte(pdev, 0x8A, &tmpbyte);
 
-       printk(KERN_INFO "sil680: BA5_EN = %d clock = %02X\n",
-                       tmpbyte & 1, tmpbyte & 0x30);
+       dev_dbg(&pdev->dev, "sil680: BA5_EN = %d clock = %02X\n",
+               tmpbyte & 1, tmpbyte & 0x30);
 
        switch(tmpbyte & 0x30) {
                case 0x00:
@@ -315,8 +317,8 @@ static u8 sil680_init_chip(struct pci_dev *pdev)
        }
 
        pci_read_config_byte(pdev,   0x8A, &tmpbyte);
-       printk(KERN_INFO "sil680: BA5_EN = %d clock = %02X\n",
-                       tmpbyte & 1, tmpbyte & 0x30);
+       dev_dbg(&pdev->dev, "sil680: BA5_EN = %d clock = %02X\n",
+               tmpbyte & 1, tmpbyte & 0x30);
 
        pci_write_config_byte(pdev,  0xA1, 0x72);
        pci_write_config_word(pdev,  0xA2, 0x328A);
@@ -339,22 +341,23 @@ static u8 sil680_init_chip(struct pci_dev *pdev)
        return tmpbyte & 0x30;
 }
 
-static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
+static int __devinit sil680_init_one(struct pci_dev *pdev,
+                                    const struct pci_device_id *id)
 {
        static const struct ata_port_info info = {
                .sht = &sil680_sht,
-               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
-               .udma_mask = 0x7f,
+               .udma_mask = ATA_UDMA6,
                .port_ops = &sil680_port_ops
        };
        static const struct ata_port_info info_slow = {
                .sht = &sil680_sht,
-               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
-               .udma_mask = 0x3f,
+               .udma_mask = ATA_UDMA5,
                .port_ops = &sil680_port_ops
        };
        const struct ata_port_info *ppi[] = { &info, NULL };
index cfe4ec6eb3d5d9955a1ac850dd22696a2711401d..9a829a7cbc60c11b14606327c2cb940868a675fc 100644 (file)
@@ -149,6 +149,9 @@ static int sis_pre_reset(struct ata_port *ap, unsigned long deadline)
        if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->port_no]))
                return -ENOENT;
 
+       /* Clear the FIFO settings. We can't enable the FIFO until
+          we know we are poking at a disk */
+       pci_write_config_byte(pdev, 0x4B, 0);
        return ata_std_prereset(ap, deadline);
 }
 
@@ -732,7 +735,7 @@ static const struct ata_port_operations sis_old_ops = {
 
 static const struct ata_port_info sis_info = {
        .sht            = &sis_sht,
-       .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+       .flags          = ATA_FLAG_SLAVE_POSS,
        .pio_mask       = 0x1f, /* pio0-4 */
        .mwdma_mask     = 0x07,
        .udma_mask      = 0,
@@ -740,7 +743,7 @@ static const struct ata_port_info sis_info = {
 };
 static const struct ata_port_info sis_info33 = {
        .sht            = &sis_sht,
-       .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+       .flags          = ATA_FLAG_SLAVE_POSS,
        .pio_mask       = 0x1f, /* pio0-4 */
        .mwdma_mask     = 0x07,
        .udma_mask      = ATA_UDMA2,    /* UDMA 33 */
@@ -748,28 +751,28 @@ static const struct ata_port_info sis_info33 = {
 };
 static const struct ata_port_info sis_info66 = {
        .sht            = &sis_sht,
-       .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+       .flags          = ATA_FLAG_SLAVE_POSS,
        .pio_mask       = 0x1f, /* pio0-4 */
        .udma_mask      = ATA_UDMA4,    /* UDMA 66 */
        .port_ops       = &sis_66_ops,
 };
 static const struct ata_port_info sis_info100 = {
        .sht            = &sis_sht,
-       .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+       .flags          = ATA_FLAG_SLAVE_POSS,
        .pio_mask       = 0x1f, /* pio0-4 */
        .udma_mask      = ATA_UDMA5,
        .port_ops       = &sis_100_ops,
 };
 static const struct ata_port_info sis_info100_early = {
        .sht            = &sis_sht,
-       .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+       .flags          = ATA_FLAG_SLAVE_POSS,
        .udma_mask      = ATA_UDMA5,
        .pio_mask       = 0x1f, /* pio0-4 */
        .port_ops       = &sis_66_ops,
 };
 static const struct ata_port_info sis_info133 = {
        .sht            = &sis_sht,
-       .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+       .flags          = ATA_FLAG_SLAVE_POSS,
        .pio_mask       = 0x1f, /* pio0-4 */
        .udma_mask      = ATA_UDMA6,
        .port_ops       = &sis_133_ops,
@@ -783,7 +786,7 @@ const struct ata_port_info sis_info133_for_sata = {
 };
 static const struct ata_port_info sis_info133_early = {
        .sht            = &sis_sht,
-       .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+       .flags          = ATA_FLAG_SLAVE_POSS,
        .pio_mask       = 0x1f, /* pio0-4 */
        .udma_mask      = ATA_UDMA6,
        .port_ops       = &sis_133_early_ops,
@@ -928,9 +931,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
                if (host != NULL) {
                        chipset = sets;                 /* Match found */
                        if (sets->device == 0x630) {    /* SIS630 */
-                               u8 host_rev;
-                               pci_read_config_byte(host, PCI_REVISION_ID, &host_rev);
-                               if (host_rev >= 0x30)   /* 630 ET */
+                               if (host->revision >= 0x30)     /* 630 ET */
                                        chipset = &sis100_early;
                        }
                        break;
@@ -974,7 +975,6 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
                u16 trueid;
                u8 prefctl;
                u8 idecfg;
-               u8 sbrev;
 
                /* Try the second unmasking technique */
                pci_read_config_byte(pdev, 0x4a, &idecfg);
@@ -987,11 +987,10 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
                        lpc_bridge = pci_get_slot(pdev->bus, 0x10); /* Bus 0 Dev 2 Fn 0 */
                        if (lpc_bridge == NULL)
                                break;
-                       pci_read_config_byte(lpc_bridge, PCI_REVISION_ID, &sbrev);
                        pci_read_config_byte(pdev, 0x49, &prefctl);
                        pci_dev_put(lpc_bridge);
 
-                       if (sbrev == 0x10 && (prefctl & 0x80)) {
+                       if (lpc_bridge->revision == 0x10 && (prefctl & 0x80)) {
                                chipset = &sis133_early;
                                break;
                        }
index e5aaec43694d284e504051a354445d3d87c02d56..8c2813aa6cdb39b6c52cdfe0a15e70364991b985 100644 (file)
@@ -270,7 +270,6 @@ static struct ata_port_operations sl82c105_port_ops = {
 static int sl82c105_bridge_revision(struct pci_dev *pdev)
 {
        struct pci_dev *bridge;
-       u8 rev;
 
        /*
         * The bridge should be part of the same device, but function 0.
@@ -292,10 +291,8 @@ static int sl82c105_bridge_revision(struct pci_dev *pdev)
        /*
         * We need to find function 0's revision, not function 1
         */
-       pci_read_config_byte(bridge, PCI_REVISION_ID, &rev);
-
        pci_dev_put(bridge);
-       return rev;
+       return bridge->revision;
 }
 
 
@@ -303,14 +300,14 @@ static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id
 {
        static const struct ata_port_info info_dma = {
                .sht = &sl82c105_sht,
-               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
                .port_ops = &sl82c105_port_ops
        };
        static const struct ata_port_info info_early = {
                .sht = &sl82c105_sht,
-               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .port_ops = &sl82c105_port_ops
        };
index b1d3076dfe5103cd56ffb57df39985c45e5c83a9..af21f443db6e4e080226aaa12ce11ea6f4e69280 100644 (file)
@@ -235,7 +235,7 @@ static int triflex_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
        static const struct ata_port_info info = {
                .sht = &triflex_sht,
-               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+               .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
                .port_ops = &triflex_port_ops
index 63eca299c62bce1a80c0446c9ec277075d8c839b..f645fe22cd1e7c6fb47df6591f7be1a12fc54114 100644 (file)
@@ -471,7 +471,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
-               .udma_mask = 0x7,
+               .udma_mask = ATA_UDMA2,
                .port_ops = &via_port_ops
        };
        /* VIA UDMA 66 devices */
@@ -480,7 +480,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
-               .udma_mask = 0x1f,
+               .udma_mask = ATA_UDMA4,
                .port_ops = &via_port_ops
        };
        /* VIA UDMA 100 devices */
@@ -489,7 +489,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
-               .udma_mask = 0x3f,
+               .udma_mask = ATA_UDMA5,
                .port_ops = &via_port_ops
        };
        /* UDMA133 with bad AST (All current 133) */
@@ -498,7 +498,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
-               .udma_mask = 0x7f,      /* FIXME: should check north bridge */
+               .udma_mask = ATA_UDMA6, /* FIXME: should check north bridge */
                .port_ops = &via_port_ops
        };
        struct ata_port_info type;
@@ -506,7 +506,6 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
        struct pci_dev *isa = NULL;
        const struct via_isa_bridge *config;
        static int printed_version;
-       u8 t;
        u8 enable;
        u32 timing;
 
@@ -520,9 +519,8 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                        !!(config->flags & VIA_BAD_ID),
                        config->id, NULL))) {
 
-                       pci_read_config_byte(isa, PCI_REVISION_ID, &t);
-                       if (t >= config->rev_min &&
-                           t <= config->rev_max)
+                       if (isa->revision >= config->rev_min &&
+                           isa->revision <= config->rev_max)
                                break;
                        pci_dev_put(isa);
                }
index f12c2b6ac08e97be67b747136e951b6177b67b47..bec1de594de8b0b4678ac49099bd6ef41a263041 100644 (file)
@@ -145,32 +145,32 @@ static struct scsi_host_template adma_ata_sht = {
        .name                   = DRV_NAME,
        .ioctl                  = ata_scsi_ioctl,
        .queuecommand           = ata_scsi_queuecmd,
+       .slave_configure        = ata_scsi_slave_config,
+       .slave_destroy          = ata_scsi_slave_destroy,
+       .bios_param             = ata_std_bios_param,
+       .proc_name              = DRV_NAME,
        .can_queue              = ATA_DEF_QUEUE,
        .this_id                = ATA_SHT_THIS_ID,
        .sg_tablesize           = LIBATA_MAX_PRD,
+       .dma_boundary           = ADMA_DMA_BOUNDARY,
        .cmd_per_lun            = ATA_SHT_CMD_PER_LUN,
-       .emulated               = ATA_SHT_EMULATED,
        .use_clustering         = ENABLE_CLUSTERING,
-       .proc_name              = DRV_NAME,
-       .dma_boundary           = ADMA_DMA_BOUNDARY,
-       .slave_configure        = ata_scsi_slave_config,
-       .slave_destroy          = ata_scsi_slave_destroy,
-       .bios_param             = ata_std_bios_param,
+       .emulated               = ATA_SHT_EMULATED,
 };
 
 static const struct ata_port_operations adma_ata_ops = {
        .port_disable           = ata_port_disable,
        .tf_load                = ata_tf_load,
        .tf_read                = ata_tf_read,
-       .check_status           = ata_check_status,
-       .check_atapi_dma        = adma_check_atapi_dma,
        .exec_command           = ata_exec_command,
+       .check_status           = ata_check_status,
        .dev_select             = ata_std_dev_select,
        .phy_reset              = adma_phy_reset,
+       .check_atapi_dma        = adma_check_atapi_dma,
+       .data_xfer              = ata_data_xfer,
        .qc_prep                = adma_qc_prep,
        .qc_issue               = adma_qc_issue,
        .eng_timeout            = adma_eng_timeout,
-       .data_xfer              = ata_data_xfer,
        .irq_clear              = adma_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
@@ -188,7 +188,7 @@ static struct ata_port_info adma_port_info[] = {
                                  ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO |
                                  ATA_FLAG_PIO_POLLING,
                .pio_mask       = 0x10, /* pio4 */
-               .udma_mask      = 0x1f, /* udma0-4 */
+               .udma_mask      = ATA_UDMA4,
                .port_ops       = &adma_ata_ops,
        },
 };
index dc3bbce046766b871b2b7ad581d6efc2530d34d9..3de183461c3c42a9f46c1500fe32b4e8c4610ffa 100644 (file)
@@ -192,7 +192,7 @@ static void inic_reset_port(void __iomem *port_base)
 
 static u32 inic_scr_read(struct ata_port *ap, unsigned sc_reg)
 {
-       void __iomem *scr_addr = (void __iomem *)ap->ioaddr.scr_addr;
+       void __iomem *scr_addr = ap->ioaddr.scr_addr;
        void __iomem *addr;
        u32 val;
 
@@ -210,7 +210,7 @@ static u32 inic_scr_read(struct ata_port *ap, unsigned sc_reg)
 
 static void inic_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val)
 {
-       void __iomem *scr_addr = (void __iomem *)ap->ioaddr.scr_addr;
+       void __iomem *scr_addr = ap->ioaddr.scr_addr;
        void __iomem *addr;
 
        if (unlikely(sc_reg >= ARRAY_SIZE(scr_map)))
@@ -594,7 +594,7 @@ static struct ata_port_info inic_port_info = {
        .flags                  = ATA_FLAG_SATA | ATA_FLAG_PIO_DMA,
        .pio_mask               = 0x1f, /* pio0-4 */
        .mwdma_mask             = 0x07, /* mwdma0-2 */
-       .udma_mask              = 0x7f, /* udma0-6 */
+       .udma_mask              = ATA_UDMA6,
        .port_ops               = &inic_port_ops
 };
 
index 590f2f92b4e0e51f47bb1ab14b952266de0bde6d..5d576435fcccddd5fe0498c57c90c058e436de65 100644 (file)
   I distinctly remember a couple workarounds (one related to PCI-X)
   are still needed.
 
-  2) Convert to LibATA new EH.  Required for hotplug, NCQ, and sane
-  probing/error handling in general.  MUST HAVE.
-
-  3) Add hotplug support (easy, once new-EH support appears)
-
   4) Add NCQ support (easy to intermediate, once new-EH support appears)
 
   5) Investigate problems with PCI Message Signalled Interrupts (MSI).
@@ -108,8 +103,6 @@ enum {
        MV_SATAHC_ARBTR_REG_SZ  = MV_MINOR_REG_AREA_SZ,         /* arbiter */
        MV_PORT_REG_SZ          = MV_MINOR_REG_AREA_SZ,
 
-       MV_USE_Q_DEPTH          = ATA_DEF_QUEUE,
-
        MV_MAX_Q_DEPTH          = 32,
        MV_MAX_Q_DEPTH_MASK     = MV_MAX_Q_DEPTH - 1,
 
@@ -133,18 +126,22 @@ enum {
        /* Host Flags */
        MV_FLAG_DUAL_HC         = (1 << 30),  /* two SATA Host Controllers */
        MV_FLAG_IRQ_COALESCE    = (1 << 29),  /* IRQ coalescing capability */
-       MV_COMMON_FLAGS         = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-                                  ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
-                                  ATA_FLAG_NO_ATAPI | ATA_FLAG_PIO_POLLING),
+       MV_COMMON_FLAGS         = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+                                 ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI |
+                                 ATA_FLAG_PIO_POLLING,
        MV_6XXX_FLAGS           = MV_FLAG_IRQ_COALESCE,
 
        CRQB_FLAG_READ          = (1 << 0),
        CRQB_TAG_SHIFT          = 1,
+       CRQB_IOID_SHIFT         = 6,    /* CRQB Gen-II/IIE IO Id shift */
+       CRQB_HOSTQ_SHIFT        = 17,   /* CRQB Gen-II/IIE HostQueTag shift */
        CRQB_CMD_ADDR_SHIFT     = 8,
        CRQB_CMD_CS             = (0x2 << 11),
        CRQB_CMD_LAST           = (1 << 15),
 
        CRPB_FLAG_STATUS_SHIFT  = 8,
+       CRPB_IOID_SHIFT_6       = 5,    /* CRPB Gen-II IO Id shift */
+       CRPB_IOID_SHIFT_7       = 7,    /* CRPB Gen-IIE IO Id shift */
 
        EPRD_FLAG_END_OF_TBL    = (1 << 31),
 
@@ -236,8 +233,10 @@ enum {
        EDMA_ERR_DEV_DCON       = (1 << 3),
        EDMA_ERR_DEV_CON        = (1 << 4),
        EDMA_ERR_SERR           = (1 << 5),
-       EDMA_ERR_SELF_DIS       = (1 << 7),
+       EDMA_ERR_SELF_DIS       = (1 << 7),     /* Gen II/IIE self-disable */
+       EDMA_ERR_SELF_DIS_5     = (1 << 8),     /* Gen I self-disable */
        EDMA_ERR_BIST_ASYNC     = (1 << 8),
+       EDMA_ERR_TRANS_IRQ_7    = (1 << 8),     /* Gen IIE transprt layer irq */
        EDMA_ERR_CRBQ_PAR       = (1 << 9),
        EDMA_ERR_CRPB_PAR       = (1 << 10),
        EDMA_ERR_INTRL_PAR      = (1 << 11),
@@ -248,13 +247,33 @@ enum {
        EDMA_ERR_LNK_CTRL_TX    = (0x1f << 21),
        EDMA_ERR_LNK_DATA_TX    = (0x1f << 26),
        EDMA_ERR_TRANS_PROTO    = (1 << 31),
-       EDMA_ERR_FATAL          = (EDMA_ERR_D_PAR | EDMA_ERR_PRD_PAR |
-                                  EDMA_ERR_DEV_DCON | EDMA_ERR_CRBQ_PAR |
-                                  EDMA_ERR_CRPB_PAR | EDMA_ERR_INTRL_PAR |
-                                  EDMA_ERR_IORDY | EDMA_ERR_LNK_CTRL_RX_2 |
-                                  EDMA_ERR_LNK_DATA_RX |
-                                  EDMA_ERR_LNK_DATA_TX |
-                                  EDMA_ERR_TRANS_PROTO),
+       EDMA_ERR_OVERRUN_5      = (1 << 5),
+       EDMA_ERR_UNDERRUN_5     = (1 << 6),
+       EDMA_EH_FREEZE          = EDMA_ERR_D_PAR |
+                                 EDMA_ERR_PRD_PAR |
+                                 EDMA_ERR_DEV_DCON |
+                                 EDMA_ERR_DEV_CON |
+                                 EDMA_ERR_SERR |
+                                 EDMA_ERR_SELF_DIS |
+                                 EDMA_ERR_CRBQ_PAR |
+                                 EDMA_ERR_CRPB_PAR |
+                                 EDMA_ERR_INTRL_PAR |
+                                 EDMA_ERR_IORDY |
+                                 EDMA_ERR_LNK_CTRL_RX_2 |
+                                 EDMA_ERR_LNK_DATA_RX |
+                                 EDMA_ERR_LNK_DATA_TX |
+                                 EDMA_ERR_TRANS_PROTO,
+       EDMA_EH_FREEZE_5        = EDMA_ERR_D_PAR |
+                                 EDMA_ERR_PRD_PAR |
+                                 EDMA_ERR_DEV_DCON |
+                                 EDMA_ERR_DEV_CON |
+                                 EDMA_ERR_OVERRUN_5 |
+                                 EDMA_ERR_UNDERRUN_5 |
+                                 EDMA_ERR_SELF_DIS_5 |
+                                 EDMA_ERR_CRBQ_PAR |
+                                 EDMA_ERR_CRPB_PAR |
+                                 EDMA_ERR_INTRL_PAR |
+                                 EDMA_ERR_IORDY,
 
        EDMA_REQ_Q_BASE_HI_OFS  = 0x10,
        EDMA_REQ_Q_IN_PTR_OFS   = 0x14,         /* also contains BASE_LO */
@@ -282,18 +301,18 @@ enum {
        MV_HP_ERRATA_60X1B2     = (1 << 3),
        MV_HP_ERRATA_60X1C0     = (1 << 4),
        MV_HP_ERRATA_XX42A0     = (1 << 5),
-       MV_HP_50XX              = (1 << 6),
-       MV_HP_GEN_IIE           = (1 << 7),
+       MV_HP_GEN_I             = (1 << 6),
+       MV_HP_GEN_II            = (1 << 7),
+       MV_HP_GEN_IIE           = (1 << 8),
 
        /* Port private flags (pp_flags) */
        MV_PP_FLAG_EDMA_EN      = (1 << 0),
        MV_PP_FLAG_EDMA_DS_ACT  = (1 << 1),
+       MV_PP_FLAG_HAD_A_RESET  = (1 << 2),
 };
 
-#define IS_50XX(hpriv) ((hpriv)->hp_flags & MV_HP_50XX)
-#define IS_60XX(hpriv) (((hpriv)->hp_flags & MV_HP_50XX) == 0)
-#define IS_GEN_I(hpriv) IS_50XX(hpriv)
-#define IS_GEN_II(hpriv) IS_60XX(hpriv)
+#define IS_GEN_I(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_I)
+#define IS_GEN_II(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_II)
 #define IS_GEN_IIE(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_IIE)
 
 enum {
@@ -352,6 +371,10 @@ struct mv_port_priv {
        dma_addr_t              crpb_dma;
        struct mv_sg            *sg_tbl;
        dma_addr_t              sg_tbl_dma;
+
+       unsigned int            req_idx;
+       unsigned int            resp_idx;
+
        u32                     pp_flags;
 };
 
@@ -384,14 +407,15 @@ static u32 mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in);
 static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val);
 static u32 mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in);
 static void mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val);
-static void mv_phy_reset(struct ata_port *ap);
-static void __mv_phy_reset(struct ata_port *ap, int can_sleep);
 static int mv_port_start(struct ata_port *ap);
 static void mv_port_stop(struct ata_port *ap);
 static void mv_qc_prep(struct ata_queued_cmd *qc);
 static void mv_qc_prep_iie(struct ata_queued_cmd *qc);
 static unsigned int mv_qc_issue(struct ata_queued_cmd *qc);
-static void mv_eng_timeout(struct ata_port *ap);
+static void mv_error_handler(struct ata_port *ap);
+static void mv_post_int_cmd(struct ata_queued_cmd *qc);
+static void mv_eh_freeze(struct ata_port *ap);
+static void mv_eh_thaw(struct ata_port *ap);
 static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
 
 static void mv5_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio,
@@ -415,14 +439,31 @@ static void mv6_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio);
 static void mv_reset_pci_bus(struct pci_dev *pdev, void __iomem *mmio);
 static void mv_channel_reset(struct mv_host_priv *hpriv, void __iomem *mmio,
                             unsigned int port_no);
-static void mv_stop_and_reset(struct ata_port *ap);
 
-static struct scsi_host_template mv_sht = {
+static struct scsi_host_template mv5_sht = {
+       .module                 = THIS_MODULE,
+       .name                   = DRV_NAME,
+       .ioctl                  = ata_scsi_ioctl,
+       .queuecommand           = ata_scsi_queuecmd,
+       .can_queue              = ATA_DEF_QUEUE,
+       .this_id                = ATA_SHT_THIS_ID,
+       .sg_tablesize           = MV_MAX_SG_CT,
+       .cmd_per_lun            = ATA_SHT_CMD_PER_LUN,
+       .emulated               = ATA_SHT_EMULATED,
+       .use_clustering         = 1,
+       .proc_name              = DRV_NAME,
+       .dma_boundary           = MV_DMA_BOUNDARY,
+       .slave_configure        = ata_scsi_slave_config,
+       .slave_destroy          = ata_scsi_slave_destroy,
+       .bios_param             = ata_std_bios_param,
+};
+
+static struct scsi_host_template mv6_sht = {
        .module                 = THIS_MODULE,
        .name                   = DRV_NAME,
        .ioctl                  = ata_scsi_ioctl,
        .queuecommand           = ata_scsi_queuecmd,
-       .can_queue              = MV_USE_Q_DEPTH,
+       .can_queue              = ATA_DEF_QUEUE,
        .this_id                = ATA_SHT_THIS_ID,
        .sg_tablesize           = MV_MAX_SG_CT,
        .cmd_per_lun            = ATA_SHT_CMD_PER_LUN,
@@ -444,19 +485,21 @@ static const struct ata_port_operations mv5_ops = {
        .exec_command           = ata_exec_command,
        .dev_select             = ata_std_dev_select,
 
-       .phy_reset              = mv_phy_reset,
        .cable_detect           = ata_cable_sata,
 
        .qc_prep                = mv_qc_prep,
        .qc_issue               = mv_qc_issue,
        .data_xfer              = ata_data_xfer,
 
-       .eng_timeout            = mv_eng_timeout,
-
        .irq_clear              = mv_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
 
+       .error_handler          = mv_error_handler,
+       .post_internal_cmd      = mv_post_int_cmd,
+       .freeze                 = mv_eh_freeze,
+       .thaw                   = mv_eh_thaw,
+
        .scr_read               = mv5_scr_read,
        .scr_write              = mv5_scr_write,
 
@@ -473,19 +516,21 @@ static const struct ata_port_operations mv6_ops = {
        .exec_command           = ata_exec_command,
        .dev_select             = ata_std_dev_select,
 
-       .phy_reset              = mv_phy_reset,
        .cable_detect           = ata_cable_sata,
 
        .qc_prep                = mv_qc_prep,
        .qc_issue               = mv_qc_issue,
        .data_xfer              = ata_data_xfer,
 
-       .eng_timeout            = mv_eng_timeout,
-
        .irq_clear              = mv_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
 
+       .error_handler          = mv_error_handler,
+       .post_internal_cmd      = mv_post_int_cmd,
+       .freeze                 = mv_eh_freeze,
+       .thaw                   = mv_eh_thaw,
+
        .scr_read               = mv_scr_read,
        .scr_write              = mv_scr_write,
 
@@ -502,19 +547,21 @@ static const struct ata_port_operations mv_iie_ops = {
        .exec_command           = ata_exec_command,
        .dev_select             = ata_std_dev_select,
 
-       .phy_reset              = mv_phy_reset,
        .cable_detect           = ata_cable_sata,
 
        .qc_prep                = mv_qc_prep_iie,
        .qc_issue               = mv_qc_issue,
        .data_xfer              = ata_data_xfer,
 
-       .eng_timeout            = mv_eng_timeout,
-
        .irq_clear              = mv_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
 
+       .error_handler          = mv_error_handler,
+       .post_internal_cmd      = mv_post_int_cmd,
+       .freeze                 = mv_eh_freeze,
+       .thaw                   = mv_eh_thaw,
+
        .scr_read               = mv_scr_read,
        .scr_write              = mv_scr_write,
 
@@ -526,44 +573,44 @@ static const struct ata_port_info mv_port_info[] = {
        {  /* chip_504x */
                .flags          = MV_COMMON_FLAGS,
                .pio_mask       = 0x1f, /* pio0-4 */
-               .udma_mask      = 0x7f, /* udma0-6 */
+               .udma_mask      = ATA_UDMA6,
                .port_ops       = &mv5_ops,
        },
        {  /* chip_508x */
-               .flags          = (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC),
+               .flags          = MV_COMMON_FLAGS | MV_FLAG_DUAL_HC,
                .pio_mask       = 0x1f, /* pio0-4 */
-               .udma_mask      = 0x7f, /* udma0-6 */
+               .udma_mask      = ATA_UDMA6,
                .port_ops       = &mv5_ops,
        },
        {  /* chip_5080 */
-               .flags          = (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC),
+               .flags          = MV_COMMON_FLAGS | MV_FLAG_DUAL_HC,
                .pio_mask       = 0x1f, /* pio0-4 */
-               .udma_mask      = 0x7f, /* udma0-6 */
+               .udma_mask      = ATA_UDMA6,
                .port_ops       = &mv5_ops,
        },
        {  /* chip_604x */
-               .flags          = (MV_COMMON_FLAGS | MV_6XXX_FLAGS),
+               .flags          = MV_COMMON_FLAGS | MV_6XXX_FLAGS,
                .pio_mask       = 0x1f, /* pio0-4 */
-               .udma_mask      = 0x7f, /* udma0-6 */
+               .udma_mask      = ATA_UDMA6,
                .port_ops       = &mv6_ops,
        },
        {  /* chip_608x */
-               .flags          = (MV_COMMON_FLAGS | MV_6XXX_FLAGS |
-                                  MV_FLAG_DUAL_HC),
+               .flags          = MV_COMMON_FLAGS | MV_6XXX_FLAGS |
+                                 MV_FLAG_DUAL_HC,
                .pio_mask       = 0x1f, /* pio0-4 */
-               .udma_mask      = 0x7f, /* udma0-6 */
+               .udma_mask      = ATA_UDMA6,
                .port_ops       = &mv6_ops,
        },
        {  /* chip_6042 */
-               .flags          = (MV_COMMON_FLAGS | MV_6XXX_FLAGS),
+               .flags          = MV_COMMON_FLAGS | MV_6XXX_FLAGS,
                .pio_mask       = 0x1f, /* pio0-4 */
-               .udma_mask      = 0x7f, /* udma0-6 */
+               .udma_mask      = ATA_UDMA6,
                .port_ops       = &mv_iie_ops,
        },
        {  /* chip_7042 */
-               .flags          = (MV_COMMON_FLAGS | MV_6XXX_FLAGS),
+               .flags          = MV_COMMON_FLAGS | MV_6XXX_FLAGS,
                .pio_mask       = 0x1f, /* pio0-4 */
-               .udma_mask      = 0x7f, /* udma0-6 */
+               .udma_mask      = ATA_UDMA6,
                .port_ops       = &mv_iie_ops,
        },
 };
@@ -709,6 +756,46 @@ static void mv_irq_clear(struct ata_port *ap)
 {
 }
 
+static void mv_set_edma_ptrs(void __iomem *port_mmio,
+                            struct mv_host_priv *hpriv,
+                            struct mv_port_priv *pp)
+{
+       u32 index;
+
+       /*
+        * initialize request queue
+        */
+       index = (pp->req_idx & MV_MAX_Q_DEPTH_MASK) << EDMA_REQ_Q_PTR_SHIFT;
+
+       WARN_ON(pp->crqb_dma & 0x3ff);
+       writel((pp->crqb_dma >> 16) >> 16, port_mmio + EDMA_REQ_Q_BASE_HI_OFS);
+       writelfl((pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK) | index,
+                port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
+
+       if (hpriv->hp_flags & MV_HP_ERRATA_XX42A0)
+               writelfl((pp->crqb_dma & 0xffffffff) | index,
+                        port_mmio + EDMA_REQ_Q_OUT_PTR_OFS);
+       else
+               writelfl(index, port_mmio + EDMA_REQ_Q_OUT_PTR_OFS);
+
+       /*
+        * initialize response queue
+        */
+       index = (pp->resp_idx & MV_MAX_Q_DEPTH_MASK) << EDMA_RSP_Q_PTR_SHIFT;
+
+       WARN_ON(pp->crpb_dma & 0xff);
+       writel((pp->crpb_dma >> 16) >> 16, port_mmio + EDMA_RSP_Q_BASE_HI_OFS);
+
+       if (hpriv->hp_flags & MV_HP_ERRATA_XX42A0)
+               writelfl((pp->crpb_dma & 0xffffffff) | index,
+                        port_mmio + EDMA_RSP_Q_IN_PTR_OFS);
+       else
+               writelfl(index, port_mmio + EDMA_RSP_Q_IN_PTR_OFS);
+
+       writelfl((pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK) | index,
+                port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
+}
+
 /**
  *      mv_start_dma - Enable eDMA engine
  *      @base: port base address
@@ -720,9 +807,15 @@ static void mv_irq_clear(struct ata_port *ap)
  *      LOCKING:
  *      Inherited from caller.
  */
-static void mv_start_dma(void __iomem *base, struct mv_port_priv *pp)
+static void mv_start_dma(void __iomem *base, struct mv_host_priv *hpriv,
+                        struct mv_port_priv *pp)
 {
-       if (!(MV_PP_FLAG_EDMA_EN & pp->pp_flags)) {
+       if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN)) {
+               /* clear EDMA event indicators, if any */
+               writelfl(0, base + EDMA_ERR_IRQ_CAUSE_OFS);
+
+               mv_set_edma_ptrs(base, hpriv, pp);
+
                writelfl(EDMA_EN, base + EDMA_CMD_OFS);
                pp->pp_flags |= MV_PP_FLAG_EDMA_EN;
        }
@@ -739,14 +832,14 @@ static void mv_start_dma(void __iomem *base, struct mv_port_priv *pp)
  *      LOCKING:
  *      Inherited from caller.
  */
-static void mv_stop_dma(struct ata_port *ap)
+static int mv_stop_dma(struct ata_port *ap)
 {
        void __iomem *port_mmio = mv_ap_base(ap);
        struct mv_port_priv *pp = ap->private_data;
        u32 reg;
-       int i;
+       int i, err = 0;
 
-       if (MV_PP_FLAG_EDMA_EN & pp->pp_flags) {
+       if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) {
                /* Disable EDMA if active.   The disable bit auto clears.
                 */
                writelfl(EDMA_DS, port_mmio + EDMA_CMD_OFS);
@@ -758,16 +851,18 @@ static void mv_stop_dma(struct ata_port *ap)
        /* now properly wait for the eDMA to stop */
        for (i = 1000; i > 0; i--) {
                reg = readl(port_mmio + EDMA_CMD_OFS);
-               if (!(EDMA_EN & reg)) {
+               if (!(reg & EDMA_EN))
                        break;
-               }
+
                udelay(100);
        }
 
-       if (EDMA_EN & reg) {
+       if (reg & EDMA_EN) {
                ata_port_printk(ap, KERN_ERR, "Unable to stop eDMA\n");
-               /* FIXME: Consider doing a reset here to recover */
+               err = -EIO;
        }
+
+       return err;
 }
 
 #ifdef ATA_DEBUG
@@ -884,12 +979,13 @@ static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val)
                writelfl(val, mv_ap_base(ap) + ofs);
 }
 
-static void mv_edma_cfg(struct mv_host_priv *hpriv, void __iomem *port_mmio)
+static void mv_edma_cfg(struct ata_port *ap, struct mv_host_priv *hpriv,
+                       void __iomem *port_mmio)
 {
        u32 cfg = readl(port_mmio + EDMA_CFG_OFS);
 
        /* set up non-NCQ EDMA configuration */
-       cfg &= ~(1 << 9);       /* disable equeue */
+       cfg &= ~(1 << 9);       /* disable eQue */
 
        if (IS_GEN_I(hpriv)) {
                cfg &= ~0x1f;           /* clear queue depth */
@@ -909,7 +1005,7 @@ static void mv_edma_cfg(struct mv_host_priv *hpriv, void __iomem *port_mmio)
                cfg |= (1 << 18);       /* enab early completion */
                cfg |= (1 << 17);       /* enab cut-through (dis stor&forwrd) */
                cfg &= ~(1 << 16);      /* dis FIS-based switching (for now) */
-               cfg &= ~(EDMA_CFG_NCQ | EDMA_CFG_NCQ_GO_ON_ERR); /* clear NCQ */
+               cfg &= ~(EDMA_CFG_NCQ); /* clear NCQ */
        }
 
        writelfl(cfg, port_mmio + EDMA_CFG_OFS);
@@ -971,28 +1067,9 @@ static int mv_port_start(struct ata_port *ap)
        pp->sg_tbl = mem;
        pp->sg_tbl_dma = mem_dma;
 
-       mv_edma_cfg(hpriv, port_mmio);
+       mv_edma_cfg(ap, hpriv, port_mmio);
 
-       writel((pp->crqb_dma >> 16) >> 16, port_mmio + EDMA_REQ_Q_BASE_HI_OFS);
-       writelfl(pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK,
-                port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
-
-       if (hpriv->hp_flags & MV_HP_ERRATA_XX42A0)
-               writelfl(pp->crqb_dma & 0xffffffff,
-                        port_mmio + EDMA_REQ_Q_OUT_PTR_OFS);
-       else
-               writelfl(0, port_mmio + EDMA_REQ_Q_OUT_PTR_OFS);
-
-       writel((pp->crpb_dma >> 16) >> 16, port_mmio + EDMA_RSP_Q_BASE_HI_OFS);
-
-       if (hpriv->hp_flags & MV_HP_ERRATA_XX42A0)
-               writelfl(pp->crpb_dma & 0xffffffff,
-                        port_mmio + EDMA_RSP_Q_IN_PTR_OFS);
-       else
-               writelfl(0, port_mmio + EDMA_RSP_Q_IN_PTR_OFS);
-
-       writelfl(pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK,
-                port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
+       mv_set_edma_ptrs(port_mmio, hpriv, pp);
 
        /* Don't turn on EDMA here...do it before DMA commands only.  Else
         * we'll be unable to send non-data, PIO, etc due to restricted access
@@ -1055,11 +1132,6 @@ static unsigned int mv_fill_sg(struct ata_queued_cmd *qc)
        return n_sg;
 }
 
-static inline unsigned mv_inc_q_index(unsigned index)
-{
-       return (index + 1) & MV_MAX_Q_DEPTH_MASK;
-}
-
 static inline void mv_crqb_pack_cmd(__le16 *cmdw, u8 data, u8 addr, unsigned last)
 {
        u16 tmp = data | (addr << CRQB_CMD_ADDR_SHIFT) | CRQB_CMD_CS |
@@ -1088,7 +1160,7 @@ static void mv_qc_prep(struct ata_queued_cmd *qc)
        u16 flags = 0;
        unsigned in_index;
 
-       if (ATA_PROT_DMA != qc->tf.protocol)
+       if (qc->tf.protocol != ATA_PROT_DMA)
                return;
 
        /* Fill in command request block
@@ -1097,10 +1169,10 @@ static void mv_qc_prep(struct ata_queued_cmd *qc)
                flags |= CRQB_FLAG_READ;
        WARN_ON(MV_MAX_Q_DEPTH <= qc->tag);
        flags |= qc->tag << CRQB_TAG_SHIFT;
+       flags |= qc->tag << CRQB_IOID_SHIFT;    /* 50xx appears to ignore this*/
 
-       /* get current queue index from hardware */
-       in_index = (readl(mv_ap_base(ap) + EDMA_REQ_Q_IN_PTR_OFS)
-                       >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK;
+       /* get current queue index from software */
+       in_index = pp->req_idx & MV_MAX_Q_DEPTH_MASK;
 
        pp->crqb[in_index].sg_addr =
                cpu_to_le32(pp->sg_tbl_dma & 0xffffffff);
@@ -1180,7 +1252,7 @@ static void mv_qc_prep_iie(struct ata_queued_cmd *qc)
        unsigned in_index;
        u32 flags = 0;
 
-       if (ATA_PROT_DMA != qc->tf.protocol)
+       if (qc->tf.protocol != ATA_PROT_DMA)
                return;
 
        /* Fill in Gen IIE command request block
@@ -1190,10 +1262,11 @@ static void mv_qc_prep_iie(struct ata_queued_cmd *qc)
 
        WARN_ON(MV_MAX_Q_DEPTH <= qc->tag);
        flags |= qc->tag << CRQB_TAG_SHIFT;
+       flags |= qc->tag << CRQB_IOID_SHIFT;    /* "I/O Id" is -really-
+                                                  what we use as our tag */
 
-       /* get current queue index from hardware */
-       in_index = (readl(mv_ap_base(ap) + EDMA_REQ_Q_IN_PTR_OFS)
-                       >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK;
+       /* get current queue index from software */
+       in_index = pp->req_idx & MV_MAX_Q_DEPTH_MASK;
 
        crqb = (struct mv_crqb_iie *) &pp->crqb[in_index];
        crqb->addr = cpu_to_le32(pp->sg_tbl_dma & 0xffffffff);
@@ -1241,82 +1314,40 @@ static void mv_qc_prep_iie(struct ata_queued_cmd *qc)
  */
 static unsigned int mv_qc_issue(struct ata_queued_cmd *qc)
 {
-       void __iomem *port_mmio = mv_ap_base(qc->ap);
-       struct mv_port_priv *pp = qc->ap->private_data;
-       unsigned in_index;
-       u32 in_ptr;
+       struct ata_port *ap = qc->ap;
+       void __iomem *port_mmio = mv_ap_base(ap);
+       struct mv_port_priv *pp = ap->private_data;
+       struct mv_host_priv *hpriv = ap->host->private_data;
+       u32 in_index;
 
-       if (ATA_PROT_DMA != qc->tf.protocol) {
+       if (qc->tf.protocol != ATA_PROT_DMA) {
                /* We're about to send a non-EDMA capable command to the
                 * port.  Turn off EDMA so there won't be problems accessing
                 * shadow block, etc registers.
                 */
-               mv_stop_dma(qc->ap);
+               mv_stop_dma(ap);
                return ata_qc_issue_prot(qc);
        }
 
-       in_ptr   = readl(port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
-       in_index = (in_ptr >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK;
+       mv_start_dma(port_mmio, hpriv, pp);
+
+       in_index = pp->req_idx & MV_MAX_Q_DEPTH_MASK;
 
        /* until we do queuing, the queue should be empty at this point */
        WARN_ON(in_index != ((readl(port_mmio + EDMA_REQ_Q_OUT_PTR_OFS)
                >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK));
 
-       in_index = mv_inc_q_index(in_index);    /* now incr producer index */
+       pp->req_idx++;
 
-       mv_start_dma(port_mmio, pp);
+       in_index = (pp->req_idx & MV_MAX_Q_DEPTH_MASK) << EDMA_REQ_Q_PTR_SHIFT;
 
        /* and write the request in pointer to kick the EDMA to life */
-       in_ptr &= EDMA_REQ_Q_BASE_LO_MASK;
-       in_ptr |= in_index << EDMA_REQ_Q_PTR_SHIFT;
-       writelfl(in_ptr, port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
+       writelfl((pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK) | in_index,
+                port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
 
        return 0;
 }
 
-/**
- *      mv_get_crpb_status - get status from most recently completed cmd
- *      @ap: ATA channel to manipulate
- *
- *      This routine is for use when the port is in DMA mode, when it
- *      will be using the CRPB (command response block) method of
- *      returning command completion information.  We check indices
- *      are good, grab status, and bump the response consumer index to
- *      prove that we're up to date.
- *
- *      LOCKING:
- *      Inherited from caller.
- */
-static u8 mv_get_crpb_status(struct ata_port *ap)
-{
-       void __iomem *port_mmio = mv_ap_base(ap);
-       struct mv_port_priv *pp = ap->private_data;
-       unsigned out_index;
-       u32 out_ptr;
-       u8 ata_status;
-
-       out_ptr   = readl(port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
-       out_index = (out_ptr >> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK;
-
-       ata_status = le16_to_cpu(pp->crpb[out_index].flags)
-                                       >> CRPB_FLAG_STATUS_SHIFT;
-
-       /* increment our consumer index... */
-       out_index = mv_inc_q_index(out_index);
-
-       /* and, until we do NCQ, there should only be 1 CRPB waiting */
-       WARN_ON(out_index != ((readl(port_mmio + EDMA_RSP_Q_IN_PTR_OFS)
-               >> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK));
-
-       /* write out our inc'd consumer index so EDMA knows we're caught up */
-       out_ptr &= EDMA_RSP_Q_BASE_LO_MASK;
-       out_ptr |= out_index << EDMA_RSP_Q_PTR_SHIFT;
-       writelfl(out_ptr, port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
-
-       /* Return ATA status register for completed CRPB */
-       return ata_status;
-}
-
 /**
  *      mv_err_intr - Handle error interrupts on the port
  *      @ap: ATA channel to manipulate
@@ -1331,30 +1362,191 @@ static u8 mv_get_crpb_status(struct ata_port *ap)
  *      LOCKING:
  *      Inherited from caller.
  */
-static void mv_err_intr(struct ata_port *ap, int reset_allowed)
+static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
 {
        void __iomem *port_mmio = mv_ap_base(ap);
-       u32 edma_err_cause, serr = 0;
+       u32 edma_err_cause, eh_freeze_mask, serr = 0;
+       struct mv_port_priv *pp = ap->private_data;
+       struct mv_host_priv *hpriv = ap->host->private_data;
+       unsigned int edma_enabled = (pp->pp_flags & MV_PP_FLAG_EDMA_EN);
+       unsigned int action = 0, err_mask = 0;
+       struct ata_eh_info *ehi = &ap->eh_info;
 
-       edma_err_cause = readl(port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
+       ata_ehi_clear_desc(ehi);
 
-       if (EDMA_ERR_SERR & edma_err_cause) {
+       if (!edma_enabled) {
+               /* just a guess: do we need to do this? should we
+                * expand this, and do it in all cases?
+                */
                sata_scr_read(ap, SCR_ERROR, &serr);
                sata_scr_write_flush(ap, SCR_ERROR, serr);
        }
-       if (EDMA_ERR_SELF_DIS & edma_err_cause) {
-               struct mv_port_priv *pp = ap->private_data;
-               pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
+
+       edma_err_cause = readl(port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
+
+       ata_ehi_push_desc(ehi, "edma_err 0x%08x", edma_err_cause);
+
+       /*
+        * all generations share these EDMA error cause bits
+        */
+
+       if (edma_err_cause & EDMA_ERR_DEV)
+               err_mask |= AC_ERR_DEV;
+       if (edma_err_cause & (EDMA_ERR_D_PAR | EDMA_ERR_PRD_PAR |
+                       EDMA_ERR_CRBQ_PAR | EDMA_ERR_CRPB_PAR |
+                       EDMA_ERR_INTRL_PAR)) {
+               err_mask |= AC_ERR_ATA_BUS;
+               action |= ATA_EH_HARDRESET;
+               ata_ehi_push_desc(ehi, ", parity error");
+       }
+       if (edma_err_cause & (EDMA_ERR_DEV_DCON | EDMA_ERR_DEV_CON)) {
+               ata_ehi_hotplugged(ehi);
+               ata_ehi_push_desc(ehi, edma_err_cause & EDMA_ERR_DEV_DCON ?
+                       ", dev disconnect" : ", dev connect");
+       }
+
+       if (IS_GEN_I(hpriv)) {
+               eh_freeze_mask = EDMA_EH_FREEZE_5;
+
+               if (edma_err_cause & EDMA_ERR_SELF_DIS_5) {
+                       struct mv_port_priv *pp = ap->private_data;
+                       pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
+                       ata_ehi_push_desc(ehi, ", EDMA self-disable");
+               }
+       } else {
+               eh_freeze_mask = EDMA_EH_FREEZE;
+
+               if (edma_err_cause & EDMA_ERR_SELF_DIS) {
+                       struct mv_port_priv *pp = ap->private_data;
+                       pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
+                       ata_ehi_push_desc(ehi, ", EDMA self-disable");
+               }
+
+               if (edma_err_cause & EDMA_ERR_SERR) {
+                       sata_scr_read(ap, SCR_ERROR, &serr);
+                       sata_scr_write_flush(ap, SCR_ERROR, serr);
+                       err_mask = AC_ERR_ATA_BUS;
+                       action |= ATA_EH_HARDRESET;
+               }
        }
-       DPRINTK(KERN_ERR "ata%u: port error; EDMA err cause: 0x%08x "
-               "SERR: 0x%08x\n", ap->print_id, edma_err_cause, serr);
 
        /* Clear EDMA now that SERR cleanup done */
        writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
 
-       /* check for fatal here and recover if needed */
-       if (reset_allowed && (EDMA_ERR_FATAL & edma_err_cause))
-               mv_stop_and_reset(ap);
+       if (!err_mask) {
+               err_mask = AC_ERR_OTHER;
+               action |= ATA_EH_HARDRESET;
+       }
+
+       ehi->serror |= serr;
+       ehi->action |= action;
+
+       if (qc)
+               qc->err_mask |= err_mask;
+       else
+               ehi->err_mask |= err_mask;
+
+       if (edma_err_cause & eh_freeze_mask)
+               ata_port_freeze(ap);
+       else
+               ata_port_abort(ap);
+}
+
+static void mv_intr_pio(struct ata_port *ap)
+{
+       struct ata_queued_cmd *qc;
+       u8 ata_status;
+
+       /* ignore spurious intr if drive still BUSY */
+       ata_status = readb(ap->ioaddr.status_addr);
+       if (unlikely(ata_status & ATA_BUSY))
+               return;
+
+       /* get active ATA command */
+       qc = ata_qc_from_tag(ap, ap->active_tag);
+       if (unlikely(!qc))                      /* no active tag */
+               return;
+       if (qc->tf.flags & ATA_TFLAG_POLLING)   /* polling; we don't own qc */
+               return;
+
+       /* and finally, complete the ATA command */
+       qc->err_mask |= ac_err_mask(ata_status);
+       ata_qc_complete(qc);
+}
+
+static void mv_intr_edma(struct ata_port *ap)
+{
+       void __iomem *port_mmio = mv_ap_base(ap);
+       struct mv_host_priv *hpriv = ap->host->private_data;
+       struct mv_port_priv *pp = ap->private_data;
+       struct ata_queued_cmd *qc;
+       u32 out_index, in_index;
+       bool work_done = false;
+
+       /* get h/w response queue pointer */
+       in_index = (readl(port_mmio + EDMA_RSP_Q_IN_PTR_OFS)
+                       >> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK;
+
+       while (1) {
+               u16 status;
+
+               /* get s/w response queue last-read pointer, and compare */
+               out_index = pp->resp_idx & MV_MAX_Q_DEPTH_MASK;
+               if (in_index == out_index)
+                       break;
+
+                
+               /* 50xx: get active ATA command */
+               if (IS_GEN_I(hpriv)) 
+                       qc = ata_qc_from_tag(ap, ap->active_tag);
+
+               /* 60xx: get active ATA command via tag, to enable support
+                * for queueing.  this works transparently for queued and
+                * non-queued modes.
+                */
+               else {
+                       unsigned int tag;
+
+                       if (IS_GEN_II(hpriv))
+                               tag = (le16_to_cpu(pp->crpb[out_index].id)
+                                       >> CRPB_IOID_SHIFT_6) & 0x3f;
+                       else
+                               tag = (le16_to_cpu(pp->crpb[out_index].id)
+                                       >> CRPB_IOID_SHIFT_7) & 0x3f;
+
+                       qc = ata_qc_from_tag(ap, tag);
+               }
+
+               /* lower 8 bits of status are EDMA_ERR_IRQ_CAUSE_OFS
+                * bits (WARNING: might not necessarily be associated
+                * with this command), which -should- be clear
+                * if all is well
+                */
+               status = le16_to_cpu(pp->crpb[out_index].flags);
+               if (unlikely(status & 0xff)) {
+                       mv_err_intr(ap, qc);
+                       return;
+               }
+
+               /* and finally, complete the ATA command */
+               if (qc) {
+                       qc->err_mask |=
+                               ac_err_mask(status >> CRPB_FLAG_STATUS_SHIFT);
+                       ata_qc_complete(qc);
+               }
+
+               /* advance software response queue pointer, to 
+                * indicate (after the loop completes) to hardware
+                * that we have consumed a response queue entry.
+                */
+               work_done = true;
+               pp->resp_idx++;
+       }
+
+       if (work_done)
+               writelfl((pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK) |
+                        (out_index << EDMA_RSP_Q_PTR_SHIFT),
+                        port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
 }
 
 /**
@@ -1377,10 +1569,8 @@ static void mv_host_intr(struct ata_host *host, u32 relevant, unsigned int hc)
 {
        void __iomem *mmio = host->iomap[MV_PRIMARY_BAR];
        void __iomem *hc_mmio = mv_hc_base(mmio, hc);
-       struct ata_queued_cmd *qc;
        u32 hc_irq_cause;
-       int shift, port, port0, hard_port, handled;
-       unsigned int err_mask;
+       int port, port0;
 
        if (hc == 0)
                port0 = 0;
@@ -1389,79 +1579,95 @@ static void mv_host_intr(struct ata_host *host, u32 relevant, unsigned int hc)
 
        /* we'll need the HC success int register in most cases */
        hc_irq_cause = readl(hc_mmio + HC_IRQ_CAUSE_OFS);
-       if (hc_irq_cause)
-               writelfl(~hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
+       if (!hc_irq_cause)
+               return;
+
+       writelfl(~hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
 
        VPRINTK("ENTER, hc%u relevant=0x%08x HC IRQ cause=0x%08x\n",
                hc,relevant,hc_irq_cause);
 
        for (port = port0; port < port0 + MV_PORTS_PER_HC; port++) {
-               u8 ata_status = 0;
                struct ata_port *ap = host->ports[port];
                struct mv_port_priv *pp = ap->private_data;
+               int have_err_bits, hard_port, shift;
+
+               if ((!ap) || (ap->flags & ATA_FLAG_DISABLED))
+                       continue;
+
+               shift = port << 1;              /* (port * 2) */
+               if (port >= MV_PORTS_PER_HC) {
+                       shift++;        /* skip bit 8 in the HC Main IRQ reg */
+               }
+               have_err_bits = ((PORT0_ERR << shift) & relevant);
+
+               if (unlikely(have_err_bits)) {
+                       struct ata_queued_cmd *qc;
+
+                       qc = ata_qc_from_tag(ap, ap->active_tag);
+                       if (qc && (qc->tf.flags & ATA_TFLAG_POLLING))
+                               continue;
+
+                       mv_err_intr(ap, qc);
+                       continue;
+               }
 
                hard_port = mv_hardport_from_port(port); /* range 0..3 */
-               handled = 0;    /* ensure ata_status is set if handled++ */
 
-               /* Note that DEV_IRQ might happen spuriously during EDMA,
-                * and should be ignored in such cases.
-                * The cause of this is still under investigation.
-                */
                if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) {
-                       /* EDMA: check for response queue interrupt */
-                       if ((CRPB_DMA_DONE << hard_port) & hc_irq_cause) {
-                               ata_status = mv_get_crpb_status(ap);
-                               handled = 1;
-                       }
+                       if ((CRPB_DMA_DONE << hard_port) & hc_irq_cause)
+                               mv_intr_edma(ap);
                } else {
-                       /* PIO: check for device (drive) interrupt */
-                       if ((DEV_IRQ << hard_port) & hc_irq_cause) {
-                               ata_status = readb(ap->ioaddr.status_addr);
-                               handled = 1;
-                               /* ignore spurious intr if drive still BUSY */
-                               if (ata_status & ATA_BUSY) {
-                                       ata_status = 0;
-                                       handled = 0;
-                               }
-                       }
+                       if ((DEV_IRQ << hard_port) & hc_irq_cause)
+                               mv_intr_pio(ap);
                }
+       }
+       VPRINTK("EXIT\n");
+}
 
-               if (ap && (ap->flags & ATA_FLAG_DISABLED))
-                       continue;
+static void mv_pci_error(struct ata_host *host, void __iomem *mmio)
+{
+       struct ata_port *ap;
+       struct ata_queued_cmd *qc;
+       struct ata_eh_info *ehi;
+       unsigned int i, err_mask, printed = 0;
+       u32 err_cause;
 
-               err_mask = ac_err_mask(ata_status);
+       err_cause = readl(mmio + PCI_IRQ_CAUSE_OFS);
 
-               shift = port << 1;              /* (port * 2) */
-               if (port >= MV_PORTS_PER_HC) {
-                       shift++;        /* skip bit 8 in the HC Main IRQ reg */
-               }
-               if ((PORT0_ERR << shift) & relevant) {
-                       mv_err_intr(ap, 1);
-                       err_mask |= AC_ERR_OTHER;
-                       handled = 1;
-               }
+       dev_printk(KERN_ERR, host->dev, "PCI ERROR; PCI IRQ cause=0x%08x\n",
+                  err_cause);
 
-               if (handled) {
+       DPRINTK("All regs @ PCI error\n");
+       mv_dump_all_regs(mmio, -1, to_pci_dev(host->dev));
+
+       writelfl(0, mmio + PCI_IRQ_CAUSE_OFS);
+
+       for (i = 0; i < host->n_ports; i++) {
+               ap = host->ports[i];
+               if (!ata_port_offline(ap)) {
+                       ehi = &ap->eh_info;
+                       ata_ehi_clear_desc(ehi);
+                       if (!printed++)
+                               ata_ehi_push_desc(ehi,
+                                       "PCI err cause 0x%08x", err_cause);
+                       err_mask = AC_ERR_HOST_BUS;
+                       ehi->action = ATA_EH_HARDRESET;
                        qc = ata_qc_from_tag(ap, ap->active_tag);
-                       if (qc && (qc->flags & ATA_QCFLAG_ACTIVE)) {
-                               VPRINTK("port %u IRQ found for qc, "
-                                       "ata_status 0x%x\n", port,ata_status);
-                               /* mark qc status appropriately */
-                               if (!(qc->tf.flags & ATA_TFLAG_POLLING)) {
-                                       qc->err_mask |= err_mask;
-                                       ata_qc_complete(qc);
-                               }
-                       }
+                       if (qc)
+                               qc->err_mask |= err_mask;
+                       else
+                               ehi->err_mask |= err_mask;
+
+                       ata_port_freeze(ap);
                }
        }
-       VPRINTK("EXIT\n");
 }
 
 /**
- *      mv_interrupt -
+ *      mv_interrupt - Main interrupt event handler
  *      @irq: unused
  *      @dev_instance: private data; in this case the host structure
- *      @regs: unused
  *
  *      Read the read only register to determine if any host
  *      controllers have pending interrupts.  If so, call lower level
@@ -1477,7 +1683,6 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance)
        struct ata_host *host = dev_instance;
        unsigned int hc, handled = 0, n_hcs;
        void __iomem *mmio = host->iomap[MV_PRIMARY_BAR];
-       struct mv_host_priv *hpriv;
        u32 irq_stat;
 
        irq_stat = readl(mmio + HC_MAIN_IRQ_CAUSE_OFS);
@@ -1491,34 +1696,21 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance)
        n_hcs = mv_get_hc_count(host->ports[0]->flags);
        spin_lock(&host->lock);
 
+       if (unlikely(irq_stat & PCI_ERR)) {
+               mv_pci_error(host, mmio);
+               handled = 1;
+               goto out_unlock;        /* skip all other HC irq handling */
+       }
+
        for (hc = 0; hc < n_hcs; hc++) {
                u32 relevant = irq_stat & (HC0_IRQ_PEND << (hc * HC_SHIFT));
                if (relevant) {
                        mv_host_intr(host, relevant, hc);
-                       handled++;
-               }
-       }
-
-       hpriv = host->private_data;
-       if (IS_60XX(hpriv)) {
-               /* deal with the interrupt coalescing bits */
-               if (irq_stat & (TRAN_LO_DONE | TRAN_HI_DONE | PORTS_0_7_COAL_DONE)) {
-                       writelfl(0, mmio + MV_IRQ_COAL_CAUSE_LO);
-                       writelfl(0, mmio + MV_IRQ_COAL_CAUSE_HI);
-                       writelfl(0, mmio + MV_IRQ_COAL_CAUSE);
+                       handled = 1;
                }
        }
 
-       if (PCI_ERR & irq_stat) {
-               printk(KERN_ERR DRV_NAME ": PCI ERROR; PCI IRQ cause=0x%08x\n",
-                      readl(mmio + PCI_IRQ_CAUSE_OFS));
-
-               DPRINTK("All regs @ PCI error\n");
-               mv_dump_all_regs(mmio, -1, to_pci_dev(host->dev));
-
-               writelfl(0, mmio + PCI_IRQ_CAUSE_OFS);
-               handled++;
-       }
+out_unlock:
        spin_unlock(&host->lock);
 
        return IRQ_RETVAL(handled);
@@ -1573,12 +1765,9 @@ static void mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val)
 
 static void mv5_reset_bus(struct pci_dev *pdev, void __iomem *mmio)
 {
-       u8 rev_id;
        int early_5080;
 
-       pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id);
-
-       early_5080 = (pdev->device == 0x5080) && (rev_id == 0);
+       early_5080 = (pdev->device == 0x5080) && (pdev->revision == 0);
 
        if (!early_5080) {
                u32 tmp = readl(mmio + MV_PCI_EXP_ROM_BAR_CTL);
@@ -1907,7 +2096,7 @@ static void mv_channel_reset(struct mv_host_priv *hpriv, void __iomem *mmio,
 
        writelfl(ATA_RST, port_mmio + EDMA_CMD_OFS);
 
-       if (IS_60XX(hpriv)) {
+       if (IS_GEN_II(hpriv)) {
                u32 ifctl = readl(port_mmio + SATA_INTERFACE_CTL);
                ifctl |= (1 << 7);              /* enable gen2i speed */
                ifctl = (ifctl & 0xfff) | 0x9b1000; /* from chip spec */
@@ -1923,32 +2112,12 @@ static void mv_channel_reset(struct mv_host_priv *hpriv, void __iomem *mmio,
 
        hpriv->ops->phy_errata(hpriv, mmio, port_no);
 
-       if (IS_50XX(hpriv))
+       if (IS_GEN_I(hpriv))
                mdelay(1);
 }
 
-static void mv_stop_and_reset(struct ata_port *ap)
-{
-       struct mv_host_priv *hpriv = ap->host->private_data;
-       void __iomem *mmio = ap->host->iomap[MV_PRIMARY_BAR];
-
-       mv_stop_dma(ap);
-
-       mv_channel_reset(hpriv, mmio, ap->port_no);
-
-       __mv_phy_reset(ap, 0);
-}
-
-static inline void __msleep(unsigned int msec, int can_sleep)
-{
-       if (can_sleep)
-               msleep(msec);
-       else
-               mdelay(msec);
-}
-
 /**
- *      __mv_phy_reset - Perform eDMA reset followed by COMRESET
+ *      mv_phy_reset - Perform eDMA reset followed by COMRESET
  *      @ap: ATA channel to manipulate
  *
  *      Part of this is taken from __sata_phy_reset and modified to
@@ -1958,14 +2127,12 @@ static inline void __msleep(unsigned int msec, int can_sleep)
  *      Inherited from caller.  This is coded to safe to call at
  *      interrupt level, i.e. it does not sleep.
  */
-static void __mv_phy_reset(struct ata_port *ap, int can_sleep)
+static void mv_phy_reset(struct ata_port *ap, unsigned int *class,
+                        unsigned long deadline)
 {
        struct mv_port_priv *pp = ap->private_data;
        struct mv_host_priv *hpriv = ap->host->private_data;
        void __iomem *port_mmio = mv_ap_base(ap);
-       struct ata_taskfile tf;
-       struct ata_device *dev = &ap->device[0];
-       unsigned long timeout;
        int retry = 5;
        u32 sstatus;
 
@@ -1978,22 +2145,21 @@ static void __mv_phy_reset(struct ata_port *ap, int can_sleep)
        /* Issue COMRESET via SControl */
 comreset_retry:
        sata_scr_write_flush(ap, SCR_CONTROL, 0x301);
-       __msleep(1, can_sleep);
+       msleep(1);
 
        sata_scr_write_flush(ap, SCR_CONTROL, 0x300);
-       __msleep(20, can_sleep);
+       msleep(20);
 
-       timeout = jiffies + msecs_to_jiffies(200);
        do {
                sata_scr_read(ap, SCR_STATUS, &sstatus);
                if (((sstatus & 0x3) == 3) || ((sstatus & 0x3) == 0))
                        break;
 
-               __msleep(1, can_sleep);
-       } while (time_before(jiffies, timeout));
+               msleep(1);
+       } while (time_before(jiffies, deadline));
 
        /* work around errata */
-       if (IS_60XX(hpriv) &&
+       if (IS_GEN_II(hpriv) &&
            (sstatus != 0x0) && (sstatus != 0x113) && (sstatus != 0x123) &&
            (retry-- > 0))
                goto comreset_retry;
@@ -2002,13 +2168,8 @@ comreset_retry:
                "SCtrl 0x%08x\n", mv_scr_read(ap, SCR_STATUS),
                mv_scr_read(ap, SCR_ERROR), mv_scr_read(ap, SCR_CONTROL));
 
-       if (ata_port_online(ap)) {
-               ata_port_probe(ap);
-       } else {
-               sata_scr_read(ap, SCR_STATUS, &sstatus);
-               ata_port_printk(ap, KERN_INFO,
-                               "no device found (phy stat %08x)\n", sstatus);
-               ata_port_disable(ap);
+       if (ata_port_offline(ap)) {
+               *class = ATA_DEV_NONE;
                return;
        }
 
@@ -2022,68 +2183,152 @@ comreset_retry:
                u8 drv_stat = ata_check_status(ap);
                if ((drv_stat != 0x80) && (drv_stat != 0x7f))
                        break;
-               __msleep(500, can_sleep);
+               msleep(500);
                if (retry-- <= 0)
                        break;
+               if (time_after(jiffies, deadline))
+                       break;
        }
 
-       tf.lbah = readb(ap->ioaddr.lbah_addr);
-       tf.lbam = readb(ap->ioaddr.lbam_addr);
-       tf.lbal = readb(ap->ioaddr.lbal_addr);
-       tf.nsect = readb(ap->ioaddr.nsect_addr);
+       /* FIXME: if we passed the deadline, the following
+        * code probably produces an invalid result
+        */
 
-       dev->class = ata_dev_classify(&tf);
-       if (!ata_dev_enabled(dev)) {
-               VPRINTK("Port disabled post-sig: No device present.\n");
-               ata_port_disable(ap);
-       }
+       /* finally, read device signature from TF registers */
+       *class = ata_dev_try_classify(ap, 0, NULL);
 
        writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
 
-       pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
+       WARN_ON(pp->pp_flags & MV_PP_FLAG_EDMA_EN);
 
        VPRINTK("EXIT\n");
 }
 
-static void mv_phy_reset(struct ata_port *ap)
+static int mv_prereset(struct ata_port *ap, unsigned long deadline)
 {
-       __mv_phy_reset(ap, 1);
+       struct mv_port_priv *pp = ap->private_data;
+       struct ata_eh_context *ehc = &ap->eh_context;
+       int rc;
+       
+       rc = mv_stop_dma(ap);
+       if (rc)
+               ehc->i.action |= ATA_EH_HARDRESET;
+
+       if (!(pp->pp_flags & MV_PP_FLAG_HAD_A_RESET)) {
+               pp->pp_flags |= MV_PP_FLAG_HAD_A_RESET;
+               ehc->i.action |= ATA_EH_HARDRESET;
+       }
+
+       /* if we're about to do hardreset, nothing more to do */
+       if (ehc->i.action & ATA_EH_HARDRESET)
+               return 0;
+
+       if (ata_port_online(ap))
+               rc = ata_wait_ready(ap, deadline);
+       else
+               rc = -ENODEV;
+
+       return rc;
 }
 
-/**
- *      mv_eng_timeout - Routine called by libata when SCSI times out I/O
- *      @ap: ATA channel to manipulate
- *
- *      Intent is to clear all pending error conditions, reset the
- *      chip/bus, fail the command, and move on.
- *
- *      LOCKING:
- *      This routine holds the host lock while failing the command.
- */
-static void mv_eng_timeout(struct ata_port *ap)
+static int mv_hardreset(struct ata_port *ap, unsigned int *class,
+                       unsigned long deadline)
 {
+       struct mv_host_priv *hpriv = ap->host->private_data;
        void __iomem *mmio = ap->host->iomap[MV_PRIMARY_BAR];
-       struct ata_queued_cmd *qc;
-       unsigned long flags;
 
-       ata_port_printk(ap, KERN_ERR, "Entering mv_eng_timeout\n");
-       DPRINTK("All regs @ start of eng_timeout\n");
-       mv_dump_all_regs(mmio, ap->port_no, to_pci_dev(ap->host->dev));
+       mv_stop_dma(ap);
 
-       qc = ata_qc_from_tag(ap, ap->active_tag);
-        printk(KERN_ERR "mmio_base %p ap %p qc %p scsi_cmnd %p &cmnd %p\n",
-              mmio, ap, qc, qc->scsicmd, &qc->scsicmd->cmnd);
+       mv_channel_reset(hpriv, mmio, ap->port_no);
 
-       spin_lock_irqsave(&ap->host->lock, flags);
-       mv_err_intr(ap, 0);
-       mv_stop_and_reset(ap);
-       spin_unlock_irqrestore(&ap->host->lock, flags);
+       mv_phy_reset(ap, class, deadline);
+
+       return 0;
+}
+
+static void mv_postreset(struct ata_port *ap, unsigned int *classes)
+{
+       u32 serr;
+
+       /* print link status */
+       sata_print_link_status(ap);
+
+       /* clear SError */
+       sata_scr_read(ap, SCR_ERROR, &serr);
+       sata_scr_write_flush(ap, SCR_ERROR, serr);
 
-       WARN_ON(!(qc->flags & ATA_QCFLAG_ACTIVE));
-       if (qc->flags & ATA_QCFLAG_ACTIVE) {
-               qc->err_mask |= AC_ERR_TIMEOUT;
-               ata_eh_qc_complete(qc);
+       /* bail out if no device is present */
+       if (classes[0] == ATA_DEV_NONE && classes[1] == ATA_DEV_NONE) {
+               DPRINTK("EXIT, no device\n");
+               return;
        }
+
+       /* set up device control */
+       iowrite8(ap->ctl, ap->ioaddr.ctl_addr);
+}
+
+static void mv_error_handler(struct ata_port *ap)
+{
+       ata_do_eh(ap, mv_prereset, ata_std_softreset,
+                 mv_hardreset, mv_postreset);
+}
+
+static void mv_post_int_cmd(struct ata_queued_cmd *qc)
+{
+       mv_stop_dma(qc->ap);
+}
+
+static void mv_eh_freeze(struct ata_port *ap)
+{
+       void __iomem *mmio = ap->host->iomap[MV_PRIMARY_BAR];
+       unsigned int hc = (ap->port_no > 3) ? 1 : 0;
+       u32 tmp, mask;
+       unsigned int shift;
+
+       /* FIXME: handle coalescing completion events properly */
+
+       shift = ap->port_no * 2;
+       if (hc > 0)
+               shift++;
+
+       mask = 0x3 << shift;
+
+       /* disable assertion of portN err, done events */
+       tmp = readl(mmio + HC_MAIN_IRQ_MASK_OFS);
+       writelfl(tmp & ~mask, mmio + HC_MAIN_IRQ_MASK_OFS);
+}
+
+static void mv_eh_thaw(struct ata_port *ap)
+{
+       void __iomem *mmio = ap->host->iomap[MV_PRIMARY_BAR];
+       unsigned int hc = (ap->port_no > 3) ? 1 : 0;
+       void __iomem *hc_mmio = mv_hc_base(mmio, hc);
+       void __iomem *port_mmio = mv_ap_base(ap);
+       u32 tmp, mask, hc_irq_cause;
+       unsigned int shift, hc_port_no = ap->port_no;
+
+       /* FIXME: handle coalescing completion events properly */
+
+       shift = ap->port_no * 2;
+       if (hc > 0) {
+               shift++;
+               hc_port_no -= 4;
+       }
+
+       mask = 0x3 << shift;
+
+       /* clear EDMA errors on this port */
+       writel(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
+
+       /* clear pending irq events */
+       hc_irq_cause = readl(hc_mmio + HC_IRQ_CAUSE_OFS);
+       hc_irq_cause &= ~(1 << hc_port_no);     /* clear CRPB-done */
+       hc_irq_cause &= ~(1 << (hc_port_no + 8)); /* clear Device int */
+       writel(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
+
+       /* enable assertion of portN err, done events */
+       tmp = readl(mmio + HC_MAIN_IRQ_MASK_OFS);
+       writelfl(tmp | mask, mmio + HC_MAIN_IRQ_MASK_OFS);
 }
 
 /**
@@ -2139,17 +2384,14 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
 {
        struct pci_dev *pdev = to_pci_dev(host->dev);
        struct mv_host_priv *hpriv = host->private_data;
-       u8 rev_id;
        u32 hp_flags = hpriv->hp_flags;
 
-       pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id);
-
        switch(board_idx) {
        case chip_5080:
                hpriv->ops = &mv5xxx_ops;
-               hp_flags |= MV_HP_50XX;
+               hp_flags |= MV_HP_GEN_I;
 
-               switch (rev_id) {
+               switch (pdev->revision) {
                case 0x1:
                        hp_flags |= MV_HP_ERRATA_50XXB0;
                        break;
@@ -2167,9 +2409,9 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
        case chip_504x:
        case chip_508x:
                hpriv->ops = &mv5xxx_ops;
-               hp_flags |= MV_HP_50XX;
+               hp_flags |= MV_HP_GEN_I;
 
-               switch (rev_id) {
+               switch (pdev->revision) {
                case 0x0:
                        hp_flags |= MV_HP_ERRATA_50XXB0;
                        break;
@@ -2187,8 +2429,9 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
        case chip_604x:
        case chip_608x:
                hpriv->ops = &mv6xxx_ops;
+               hp_flags |= MV_HP_GEN_II;
 
-               switch (rev_id) {
+               switch (pdev->revision) {
                case 0x7:
                        hp_flags |= MV_HP_ERRATA_60X1B2;
                        break;
@@ -2206,10 +2449,9 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
        case chip_7042:
        case chip_6042:
                hpriv->ops = &mv6xxx_ops;
-
                hp_flags |= MV_HP_GEN_IIE;
 
-               switch (rev_id) {
+               switch (pdev->revision) {
                case 0x0:
                        hp_flags |= MV_HP_ERRATA_XX42A0;
                        break;
@@ -2273,7 +2515,7 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx)
        hpriv->ops->enable_leds(hpriv, mmio);
 
        for (port = 0; port < host->n_ports; port++) {
-               if (IS_60XX(hpriv)) {
+               if (IS_GEN_II(hpriv)) {
                        void __iomem *port_mmio = mv_port_base(mmio, port);
 
                        u32 ifctl = readl(port_mmio + SATA_INTERFACE_CTL);
@@ -2308,7 +2550,7 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx)
        /* and unmask interrupt generation for host regs */
        writelfl(PCI_UNMASK_ALL_IRQS, mmio + PCI_IRQ_MASK_OFS);
 
-       if (IS_50XX(hpriv))
+       if (IS_GEN_I(hpriv))
                writelfl(~HC_MAIN_MASKED_IRQS_5, mmio + HC_MAIN_IRQ_MASK_OFS);
        else
                writelfl(~HC_MAIN_MASKED_IRQS, mmio + HC_MAIN_IRQ_MASK_OFS);
@@ -2337,25 +2579,32 @@ static void mv_print_info(struct ata_host *host)
 {
        struct pci_dev *pdev = to_pci_dev(host->dev);
        struct mv_host_priv *hpriv = host->private_data;
-       u8 rev_id, scc;
-       const char *scc_s;
+       u8 scc;
+       const char *scc_s, *gen;
 
        /* Use this to determine the HW stepping of the chip so we know
         * what errata to workaround
         */
-       pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id);
-
        pci_read_config_byte(pdev, PCI_CLASS_DEVICE, &scc);
        if (scc == 0)
                scc_s = "SCSI";
        else if (scc == 0x01)
                scc_s = "RAID";
        else
-               scc_s = "unknown";
+               scc_s = "?";
+
+       if (IS_GEN_I(hpriv))
+               gen = "I";
+       else if (IS_GEN_II(hpriv))
+               gen = "II";
+       else if (IS_GEN_IIE(hpriv))
+               gen = "IIE";
+       else
+               gen = "?";
 
        dev_printk(KERN_INFO, &pdev->dev,
-              "%u slots %u ports %s mode IRQ via %s\n",
-              (unsigned)MV_MAX_Q_DEPTH, host->n_ports,
+              "Gen-%s %u slots %u ports %s mode IRQ via %s\n",
+              gen, (unsigned)MV_MAX_Q_DEPTH, host->n_ports,
               scc_s, (MV_HP_FLAG_MSI & hpriv->hp_flags) ? "MSI" : "INTx");
 }
 
@@ -2417,8 +2666,9 @@ static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        mv_print_info(host);
 
        pci_set_master(pdev);
+       pci_set_mwi(pdev);
        return ata_host_activate(host, pdev->irq, mv_interrupt, IRQF_SHARED,
-                                &mv_sht);
+                                IS_GEN_I(hpriv) ? &mv5_sht : &mv6_sht);
 }
 
 static int __init mv_init(void)
index b2656867c64711075e77478bf6186f9cd0b81b57..db81e3efa5ec4f03c3d8ab7888a07bd632cb3589 100644 (file)
@@ -1560,7 +1560,7 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        }
 
        ppi[0] = &nv_port_info[type];
-       rc = ata_pci_prepare_native_host(pdev, ppi, &host);
+       rc = ata_pci_prepare_sff_host(pdev, ppi, &host);
        if (rc)
                return rc;
 
index 6dc0b011a6b7c5a10febc2a0242c5dc431939a23..d2fcb9a6bec2a024ef4a2dcbb9369cf592618d31 100644 (file)
@@ -45,8 +45,7 @@
 #include "sata_promise.h"
 
 #define DRV_NAME       "sata_promise"
-#define DRV_VERSION    "2.07"
-
+#define DRV_VERSION    "2.09"
 
 enum {
        PDC_MAX_PORTS           = 4,
@@ -94,7 +93,7 @@ enum {
        board_20319             = 2,    /* FastTrak S150 TX4 */
        board_20619             = 3,    /* FastTrak TX4000 */
        board_2057x             = 4,    /* SATAII150 Tx2plus */
-       board_2057x_pata        = 5,    /* SATAII150 Tx2plus */
+       board_2057x_pata        = 5,    /* SATAII150 Tx2plus PATA port */
        board_40518             = 6,    /* SATAII150 Tx4 */
 
        PDC_HAS_PATA            = (1 << 1), /* PDC20375/20575 has PATA */
@@ -124,7 +123,6 @@ enum {
        PDC_FLAG_4_PORTS        = (1 << 26), /* 4 ports */
 };
 
-
 struct pdc_port_priv {
        u8                      *pkt;
        dma_addr_t              pkt_dma;
@@ -252,7 +250,7 @@ static const struct ata_port_info pdc_port_info[] = {
                                  PDC_FLAG_SATA_PATA,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma0-2 */
-               .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
+               .udma_mask      = ATA_UDMA6,
                .port_ops       = &pdc_old_sata_ops,
        },
 
@@ -261,7 +259,7 @@ static const struct ata_port_info pdc_port_info[] = {
                .flags          = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma0-2 */
-               .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
+               .udma_mask      = ATA_UDMA6,
                .port_ops       = &pdc_pata_ops,
        },
 
@@ -271,7 +269,7 @@ static const struct ata_port_info pdc_port_info[] = {
                                  PDC_FLAG_4_PORTS,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma0-2 */
-               .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
+               .udma_mask      = ATA_UDMA6,
                .port_ops       = &pdc_old_sata_ops,
        },
 
@@ -281,7 +279,7 @@ static const struct ata_port_info pdc_port_info[] = {
                                  PDC_FLAG_4_PORTS,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma0-2 */
-               .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
+               .udma_mask      = ATA_UDMA6,
                .port_ops       = &pdc_pata_ops,
        },
 
@@ -291,7 +289,7 @@ static const struct ata_port_info pdc_port_info[] = {
                                  PDC_FLAG_GEN_II | PDC_FLAG_SATA_PATA,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma0-2 */
-               .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
+               .udma_mask      = ATA_UDMA6,
                .port_ops       = &pdc_sata_ops,
        },
 
@@ -301,7 +299,7 @@ static const struct ata_port_info pdc_port_info[] = {
                                  PDC_FLAG_GEN_II,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma0-2 */
-               .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
+               .udma_mask      = ATA_UDMA6,
                .port_ops       = &pdc_pata_ops,
        },
 
@@ -311,7 +309,7 @@ static const struct ata_port_info pdc_port_info[] = {
                                  PDC_FLAG_GEN_II | PDC_FLAG_4_PORTS,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma0-2 */
-               .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
+               .udma_mask      = ATA_UDMA6,
                .port_ops       = &pdc_sata_ops,
        },
 };
@@ -340,7 +338,6 @@ static const struct pci_device_id pdc_ata_pci_tbl[] = {
        { }     /* terminate list */
 };
 
-
 static struct pci_driver pdc_ata_pci_driver = {
        .name                   = DRV_NAME,
        .id_table               = pdc_ata_pci_tbl,
@@ -348,7 +345,6 @@ static struct pci_driver pdc_ata_pci_driver = {
        .remove                 = ata_pci_remove_one,
 };
 
-
 static int pdc_common_port_start(struct ata_port *ap)
 {
        struct device *dev = ap->host->dev;
@@ -382,7 +378,7 @@ static int pdc_sata_port_start(struct ata_port *ap)
 
        /* fix up PHYMODE4 align timing */
        if (ap->flags & PDC_FLAG_GEN_II) {
-               void __iomem *mmio = (void __iomem *) ap->ioaddr.scr_addr;
+               void __iomem *mmio = ap->ioaddr.scr_addr;
                unsigned int tmp;
 
                tmp = readl(mmio + 0x014);
@@ -418,7 +414,7 @@ static void pdc_reset_port(struct ata_port *ap)
 static int pdc_pata_cable_detect(struct ata_port *ap)
 {
        u8 tmp;
-       void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr + PDC_CTLSTAT + 0x03;
+       void __iomem *mmio = ap->ioaddr.cmd_addr + PDC_CTLSTAT + 0x03;
 
        tmp = readb(mmio);
        if (tmp & 0x01)
@@ -438,7 +434,6 @@ static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
        return readl(ap->ioaddr.scr_addr + (sc_reg * 4));
 }
 
-
 static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg,
                               u32 val)
 {
@@ -573,7 +568,7 @@ static void pdc_qc_prep(struct ata_queued_cmd *qc)
 
 static void pdc_freeze(struct ata_port *ap)
 {
-       void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr;
+       void __iomem *mmio = ap->ioaddr.cmd_addr;
        u32 tmp;
 
        tmp = readl(mmio + PDC_CTLSTAT);
@@ -585,7 +580,7 @@ static void pdc_freeze(struct ata_port *ap)
 
 static void pdc_thaw(struct ata_port *ap)
 {
-       void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr;
+       void __iomem *mmio = ap->ioaddr.cmd_addr;
        u32 tmp;
 
        /* clear IRQ */
@@ -657,8 +652,8 @@ static void pdc_error_intr(struct ata_port *ap, struct ata_queued_cmd *qc,
        ata_port_abort(ap);
 }
 
-static inline unsigned int pdc_host_intr( struct ata_port *ap,
-                                          struct ata_queued_cmd *qc)
+static inline unsigned int pdc_host_intr(struct ata_port *ap,
+                                        struct ata_queued_cmd *qc)
 {
        unsigned int handled = 0;
        void __iomem *port_mmio = ap->ioaddr.cmd_addr;
@@ -685,10 +680,10 @@ static inline unsigned int pdc_host_intr( struct ata_port *ap,
                handled = 1;
                break;
 
-        default:
+       default:
                ap->stats.idle_irq++;
                break;
-        }
+       }
 
        return handled;
 }
@@ -701,6 +696,18 @@ static void pdc_irq_clear(struct ata_port *ap)
        readl(mmio + PDC_INT_SEQMASK);
 }
 
+static inline int pdc_is_sataii_tx4(unsigned long flags)
+{
+       const unsigned long mask = PDC_FLAG_GEN_II | PDC_FLAG_4_PORTS;
+       return (flags & mask) == mask;
+}
+
+static inline unsigned int pdc_port_no_to_ata_no(unsigned int port_no, int is_sataii_tx4)
+{
+       static const unsigned char sataii_tx4_port_remap[4] = { 3, 1, 0, 2};
+       return is_sataii_tx4 ? sataii_tx4_port_remap[port_no] : port_no;
+}
+
 static irqreturn_t pdc_interrupt (int irq, void *dev_instance)
 {
        struct ata_host *host = dev_instance;
@@ -709,6 +716,9 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance)
        unsigned int i, tmp;
        unsigned int handled = 0;
        void __iomem *mmio_base;
+       unsigned int hotplug_offset, ata_no;
+       u32 hotplug_status;
+       int is_sataii_tx4;
 
        VPRINTK("ENTER\n");
 
@@ -719,10 +729,20 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance)
 
        mmio_base = host->iomap[PDC_MMIO_BAR];
 
+       /* read and clear hotplug flags for all ports */
+       if (host->ports[0]->flags & PDC_FLAG_GEN_II)
+               hotplug_offset = PDC2_SATA_PLUG_CSR;
+       else
+               hotplug_offset = PDC_SATA_PLUG_CSR;
+       hotplug_status = readl(mmio_base + hotplug_offset);
+       if (hotplug_status & 0xff)
+               writel(hotplug_status | 0xff, mmio_base + hotplug_offset);
+       hotplug_status &= 0xff; /* clear uninteresting bits */
+
        /* reading should also clear interrupts */
        mask = readl(mmio_base + PDC_INT_SEQMASK);
 
-       if (mask == 0xffffffff) {
+       if (mask == 0xffffffff && hotplug_status == 0) {
                VPRINTK("QUICK EXIT 2\n");
                return IRQ_NONE;
        }
@@ -730,16 +750,34 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance)
        spin_lock(&host->lock);
 
        mask &= 0xffff;         /* only 16 tags possible */
-       if (!mask) {
+       if (mask == 0 && hotplug_status == 0) {
                VPRINTK("QUICK EXIT 3\n");
                goto done_irq;
        }
 
        writel(mask, mmio_base + PDC_INT_SEQMASK);
 
+       is_sataii_tx4 = pdc_is_sataii_tx4(host->ports[0]->flags);
+
        for (i = 0; i < host->n_ports; i++) {
                VPRINTK("port %u\n", i);
                ap = host->ports[i];
+
+               /* check for a plug or unplug event */
+               ata_no = pdc_port_no_to_ata_no(i, is_sataii_tx4);
+               tmp = hotplug_status & (0x11 << ata_no);
+               if (tmp && ap &&
+                   !(ap->flags & ATA_FLAG_DISABLED)) {
+                       struct ata_eh_info *ehi = &ap->eh_info;
+                       ata_ehi_clear_desc(ehi);
+                       ata_ehi_hotplugged(ehi);
+                       ata_ehi_push_desc(ehi, "hotplug_status %#x", tmp);
+                       ata_port_freeze(ap);
+                       ++handled;
+                       continue;
+               }
+
+               /* check for a packet interrupt */
                tmp = mask & (1 << (i + 1));
                if (tmp && ap &&
                    !(ap->flags & ATA_FLAG_DISABLED)) {
@@ -807,7 +845,6 @@ static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
        ata_tf_load(ap, tf);
 }
 
-
 static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
 {
        WARN_ON (tf->protocol == ATA_PROT_DMA ||
@@ -867,7 +904,6 @@ static void pdc_ata_setup_port(struct ata_port *ap,
        ap->ioaddr.scr_addr             = scr_addr;
 }
 
-
 static void pdc_host_init(struct ata_host *host)
 {
        void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
@@ -897,9 +933,9 @@ static void pdc_host_init(struct ata_host *host)
        tmp = readl(mmio + hotplug_offset);
        writel(tmp | 0xff, mmio + hotplug_offset);
 
-       /* mask plug/unplug ints */
+       /* unmask plug/unplug ints */
        tmp = readl(mmio + hotplug_offset);
-       writel(tmp 0xff0000, mmio + hotplug_offset);
+       writel(tmp & ~0xff0000, mmio + hotplug_offset);
 
        /* don't initialise TBG or SLEW on 2nd generation chips */
        if (is_gen2)
@@ -955,10 +991,8 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
 
        if (pi->flags & PDC_FLAG_SATA_PATA) {
                u8 tmp = readb(base + PDC_FLASH_CTL+1);
-               if (!(tmp & 0x80)) {
+               if (!(tmp & 0x80))
                        ppi[n_ports++] = pi + 1;
-                       dev_printk(KERN_INFO, &pdev->dev, "PATA port found\n");
-               }
        }
 
        host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
@@ -968,22 +1002,12 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
        }
        host->iomap = pcim_iomap_table(pdev);
 
-       is_sataii_tx4 = 0;
-       if ((pi->flags & (PDC_FLAG_GEN_II|PDC_FLAG_4_PORTS)) == (PDC_FLAG_GEN_II|PDC_FLAG_4_PORTS)) {
-               is_sataii_tx4 = 1;
-               dev_printk(KERN_INFO, &pdev->dev, "applying SATAII TX4 port numbering workaround\n");
-       }
+       is_sataii_tx4 = pdc_is_sataii_tx4(pi->flags);
        for (i = 0; i < host->n_ports; i++) {
-               static const unsigned char sataii_tx4_port_remap[4] = { 3, 1, 0, 2};
-               int ata_nr;
-
-               ata_nr = i;
-               if (is_sataii_tx4)
-                       ata_nr = sataii_tx4_port_remap[i];
-
+               unsigned int ata_no = pdc_port_no_to_ata_no(i, is_sataii_tx4);
                pdc_ata_setup_port(host->ports[i],
-                                  base + 0x200 + ata_nr * 0x80,
-                                  base + 0x400 + ata_nr * 0x100);
+                                  base + 0x200 + ata_no * 0x80,
+                                  base + 0x400 + ata_no * 0x100);
        }
 
        /* initialize adapter */
@@ -1002,19 +1026,16 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
                                 &pdc_ata_sht);
 }
 
-
 static int __init pdc_ata_init(void)
 {
        return pci_register_driver(&pdc_ata_pci_driver);
 }
 
-
 static void __exit pdc_ata_exit(void)
 {
        pci_unregister_driver(&pdc_ata_pci_driver);
 }
 
-
 MODULE_AUTHOR("Jeff Garzik");
 MODULE_DESCRIPTION("Promise ATA TX2/TX4/TX4000 low-level driver");
 MODULE_LICENSE("GPL");
index 6688ccb66320900563045e5e0d917c42bdf47b5c..9ab554da89bfd89301521a8deb1ec17306b0ff3f 100644 (file)
@@ -176,7 +176,7 @@ static const struct ata_port_info qs_port_info[] = {
                                  //FIXME ATA_FLAG_SRST |
                                  ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING,
                .pio_mask       = 0x10, /* pio4 */
-               .udma_mask      = 0x7f, /* udma0-6 */
+               .udma_mask      = ATA_UDMA6,
                .port_ops       = &qs_ata_ops,
        },
 };
index a3b339bcf3cf2d1a3787a6b541e4046644896559..2a86dc4598d04b479e1d2654f256ee49656a393b 100644 (file)
@@ -218,7 +218,7 @@ static const struct ata_port_info sil_port_info[] = {
                .flags          = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE,
                .pio_mask       = 0x1f,                 /* pio0-4 */
                .mwdma_mask     = 0x07,                 /* mwdma0-2 */
-               .udma_mask      = 0x3f,                 /* udma0-5 */
+               .udma_mask      = ATA_UDMA5,
                .port_ops       = &sil_ops,
        },
        /* sil_3112_no_sata_irq */
@@ -227,7 +227,7 @@ static const struct ata_port_info sil_port_info[] = {
                                  SIL_FLAG_NO_SATA_IRQ,
                .pio_mask       = 0x1f,                 /* pio0-4 */
                .mwdma_mask     = 0x07,                 /* mwdma0-2 */
-               .udma_mask      = 0x3f,                 /* udma0-5 */
+               .udma_mask      = ATA_UDMA5,
                .port_ops       = &sil_ops,
        },
        /* sil_3512 */
@@ -235,7 +235,7 @@ static const struct ata_port_info sil_port_info[] = {
                .flags          = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT,
                .pio_mask       = 0x1f,                 /* pio0-4 */
                .mwdma_mask     = 0x07,                 /* mwdma0-2 */
-               .udma_mask      = 0x3f,                 /* udma0-5 */
+               .udma_mask      = ATA_UDMA5,
                .port_ops       = &sil_ops,
        },
        /* sil_3114 */
@@ -243,7 +243,7 @@ static const struct ata_port_info sil_port_info[] = {
                .flags          = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT,
                .pio_mask       = 0x1f,                 /* pio0-4 */
                .mwdma_mask     = 0x07,                 /* mwdma0-2 */
-               .udma_mask      = 0x3f,                 /* udma0-5 */
+               .udma_mask      = ATA_UDMA5,
                .port_ops       = &sil_ops,
        },
 };
@@ -262,8 +262,9 @@ static const struct {
        unsigned long sfis_cfg; /* SATA FIS reception config register */
 } sil_port[] = {
        /* port 0 ... */
-       { 0x80, 0x8A, 0x00, 0x10, 0x40, 0x100, 0x148, 0xb4, 0x14c },
-       { 0xC0, 0xCA, 0x08, 0x18, 0x44, 0x180, 0x1c8, 0xf4, 0x1cc },
+       /*   tf    ctl  bmdma  bmdma2  fifo    scr   sien   mode   sfis */
+       {  0x80,  0x8A,   0x0,  0x10,  0x40, 0x100, 0x148,  0xb4, 0x14c },
+       {  0xC0,  0xCA,   0x8,  0x18,  0x44, 0x180, 0x1c8,  0xf4, 0x1cc },
        { 0x280, 0x28A, 0x200, 0x210, 0x240, 0x300, 0x348, 0x2b4, 0x34c },
        { 0x2C0, 0x2CA, 0x208, 0x218, 0x244, 0x380, 0x3c8, 0x2f4, 0x3cc },
        /* ... port 3 */
index 0ddfae9911cdf1aa7c8a98946afcabf84d49bff3..ac43a30ebe2925095e330a9dbc26347e83dddbcf 100644 (file)
@@ -426,7 +426,7 @@ static const struct ata_port_info sil24_port_info[] = {
                                  SIL24_FLAG_PCIX_IRQ_WOC,
                .pio_mask       = 0x1f,                 /* pio0-4 */
                .mwdma_mask     = 0x07,                 /* mwdma0-2 */
-               .udma_mask      = 0x3f,                 /* udma0-5 */
+               .udma_mask      = ATA_UDMA5,            /* udma0-5 */
                .port_ops       = &sil24_ops,
        },
        /* sil_3132 */
@@ -434,7 +434,7 @@ static const struct ata_port_info sil24_port_info[] = {
                .flags          = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(2),
                .pio_mask       = 0x1f,                 /* pio0-4 */
                .mwdma_mask     = 0x07,                 /* mwdma0-2 */
-               .udma_mask      = 0x3f,                 /* udma0-5 */
+               .udma_mask      = ATA_UDMA5,            /* udma0-5 */
                .port_ops       = &sil24_ops,
        },
        /* sil_3131/sil_3531 */
@@ -442,7 +442,7 @@ static const struct ata_port_info sil24_port_info[] = {
                .flags          = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(1),
                .pio_mask       = 0x1f,                 /* pio0-4 */
                .mwdma_mask     = 0x07,                 /* mwdma0-2 */
-               .udma_mask      = 0x3f,                 /* udma0-5 */
+               .udma_mask      = ATA_UDMA5,            /* udma0-5 */
                .port_ops       = &sil24_ops,
        },
 };
@@ -888,7 +888,7 @@ static irqreturn_t sil24_interrupt(int irq, void *dev_instance)
                if (status & (1 << i)) {
                        struct ata_port *ap = host->ports[i];
                        if (ap && !(ap->flags & ATA_FLAG_DISABLED)) {
-                               sil24_host_intr(host->ports[i]);
+                               sil24_host_intr(ap);
                                handled++;
                        } else
                                printk(KERN_ERR DRV_NAME
index f111c984a359f50da823b50284c31ddb9d557fb6..33716b00c6b7ec1de843a36772303a035e52ed31 100644 (file)
@@ -133,7 +133,7 @@ static const struct ata_port_info sis_port_info = {
        .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
        .pio_mask       = 0x1f,
        .mwdma_mask     = 0x7,
-       .udma_mask      = 0x7f,
+       .udma_mask      = ATA_UDMA6,
        .port_ops       = &sis_ops,
 };
 
@@ -334,7 +334,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
                break;
        }
 
-       rc = ata_pci_prepare_native_host(pdev, ppi, &host);
+       rc = ata_pci_prepare_sff_host(pdev, ppi, &host);
        if (rc)
                return rc;
 
index bcb2cd8b063d763df844109350a4e6f9e91d2811..63fe99afd59f3a782cb45a869fcbc36c96cde9ad 100644 (file)
@@ -107,7 +107,7 @@ static u32 k2_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
 {
        if (sc_reg > SCR_CONTROL)
                return 0xffffffffU;
-       return readl((void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
+       return readl(ap->ioaddr.scr_addr + (sc_reg * 4));
 }
 
 
@@ -116,7 +116,7 @@ static void k2_sata_scr_write (struct ata_port *ap, unsigned int sc_reg,
 {
        if (sc_reg > SCR_CONTROL)
                return;
-       writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
+       writel(val, ap->ioaddr.scr_addr + (sc_reg * 4));
 }
 
 
@@ -197,7 +197,8 @@ static void k2_bmdma_setup_mmio (struct ata_queued_cmd *qc)
        struct ata_port *ap = qc->ap;
        unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
        u8 dmactl;
-       void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr;
+       void __iomem *mmio = ap->ioaddr.bmdma_addr;
+
        /* load PRD table addr. */
        mb();   /* make sure PRD table writes are visible to controller */
        writel(ap->prd_dma, mmio + ATA_DMA_TABLE_OFS);
@@ -225,7 +226,7 @@ static void k2_bmdma_setup_mmio (struct ata_queued_cmd *qc)
 static void k2_bmdma_start_mmio (struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
-       void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr;
+       void __iomem *mmio = ap->ioaddr.bmdma_addr;
        u8 dmactl;
 
        /* start host DMA transaction */
@@ -253,7 +254,7 @@ static void k2_bmdma_start_mmio (struct ata_queued_cmd *qc)
 
 static u8 k2_stat_check_status(struct ata_port *ap)
 {
-               return readl((void __iomem *) ap->ioaddr.status_addr);
+               return readl(ap->ioaddr.status_addr);
 }
 
 #ifdef CONFIG_PPC_OF
@@ -360,7 +361,7 @@ static const struct ata_port_info k2_port_info[] = {
                                  ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA,
                .pio_mask       = 0x1f,
                .mwdma_mask     = 0x07,
-               .udma_mask      = 0x7f,
+               .udma_mask      = ATA_UDMA6,
                .port_ops       = &k2_sata_ops,
        },
        /* board_svw8 */
@@ -370,7 +371,7 @@ static const struct ata_port_info k2_port_info[] = {
                                  K2_FLAG_SATA_8_PORTS,
                .pio_mask       = 0x1f,
                .mwdma_mask     = 0x07,
-               .udma_mask      = 0x7f,
+               .udma_mask      = ATA_UDMA6,
                .port_ops       = &k2_sata_ops,
        },
 };
index 2d14f3d56d92d25e0e618c901ffc4ec9ccd7d730..5193bd8647baa34288d1fbed7fcbd700118766a3 100644 (file)
  *
  */
 
+/*
+       Theory of operation
+       -------------------
+
+       The SX4 (PDC20621) chip features a single Host DMA (HDMA) copy
+       engine, DIMM memory, and four ATA engines (one per SATA port).
+       Data is copied to/from DIMM memory by the HDMA engine, before
+       handing off to one (or more) of the ATA engines.  The ATA
+       engines operate solely on DIMM memory.
+
+       The SX4 behaves like a PATA chip, with no SATA controls or
+       knowledge whatsoever, leading to the presumption that
+       PATA<->SATA bridges exist on SX4 boards, external to the
+       PDC20621 chip itself.
+
+       The chip is quite capable, supporting an XOR engine and linked
+       hardware commands (permits a string to transactions to be
+       submitted and waited-on as a single unit), and an optional
+       microprocessor.
+
+       The limiting factor is largely software.  This Linux driver was
+       written to multiplex the single HDMA engine to copy disk
+       transactions into a fixed DIMM memory space, from where an ATA
+       engine takes over.  As a result, each WRITE looks like this:
+
+               submit HDMA packet to hardware
+               hardware copies data from system memory to DIMM
+               hardware raises interrupt
+
+               submit ATA packet to hardware
+               hardware executes ATA WRITE command, w/ data in DIMM
+               hardware raises interrupt
+       
+       and each READ looks like this:
+
+               submit ATA packet to hardware
+               hardware executes ATA READ command, w/ data in DIMM
+               hardware raises interrupt
+       
+               submit HDMA packet to hardware
+               hardware copies data from DIMM to system memory
+               hardware raises interrupt
+
+       This is a very slow, lock-step way of doing things that can
+       certainly be improved by motivated kernel hackers.
+
+ */
+
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pci.h>
@@ -58,6 +106,8 @@ enum {
        PDC_INT_SEQMASK         = 0x40, /* Mask of asserted SEQ INTs */
        PDC_HDMA_CTLSTAT        = 0x12C, /* Host DMA control / status */
 
+       PDC_CTLSTAT             = 0x60, /* IDEn control / status */
+
        PDC_20621_SEQCTL        = 0x400,
        PDC_20621_SEQMASK       = 0x480,
        PDC_20621_GENERAL_CTL   = 0x484,
@@ -87,48 +137,60 @@ enum {
 
        board_20621             = 0,    /* FastTrak S150 SX4 */
 
-       PDC_RESET               = (1 << 11), /* HDMA reset */
+       PDC_MASK_INT            = (1 << 10), /* HDMA/ATA mask int */
+       PDC_RESET               = (1 << 11), /* HDMA/ATA reset */
+       PDC_DMA_ENABLE          = (1 << 7),  /* DMA start/stop */
 
        PDC_MAX_HDMA            = 32,
        PDC_HDMA_Q_MASK         = (PDC_MAX_HDMA - 1),
 
-       PDC_DIMM0_SPD_DEV_ADDRESS     = 0x50,
-       PDC_DIMM1_SPD_DEV_ADDRESS     = 0x51,
-       PDC_MAX_DIMM_MODULE           = 0x02,
-       PDC_I2C_CONTROL_OFFSET        = 0x48,
-       PDC_I2C_ADDR_DATA_OFFSET      = 0x4C,
-       PDC_DIMM0_CONTROL_OFFSET      = 0x80,
-       PDC_DIMM1_CONTROL_OFFSET      = 0x84,
-       PDC_SDRAM_CONTROL_OFFSET      = 0x88,
-       PDC_I2C_WRITE                 = 0x00000000,
-       PDC_I2C_READ                  = 0x00000040,
-       PDC_I2C_START                 = 0x00000080,
-       PDC_I2C_MASK_INT              = 0x00000020,
-       PDC_I2C_COMPLETE              = 0x00010000,
-       PDC_I2C_NO_ACK                = 0x00100000,
-       PDC_DIMM_SPD_SUBADDRESS_START = 0x00,
-       PDC_DIMM_SPD_SUBADDRESS_END   = 0x7F,
-       PDC_DIMM_SPD_ROW_NUM          = 3,
-       PDC_DIMM_SPD_COLUMN_NUM       = 4,
-       PDC_DIMM_SPD_MODULE_ROW       = 5,
-       PDC_DIMM_SPD_TYPE             = 11,
-       PDC_DIMM_SPD_FRESH_RATE       = 12,
-       PDC_DIMM_SPD_BANK_NUM         = 17,
-       PDC_DIMM_SPD_CAS_LATENCY      = 18,
-       PDC_DIMM_SPD_ATTRIBUTE        = 21,
-       PDC_DIMM_SPD_ROW_PRE_CHARGE   = 27,
-       PDC_DIMM_SPD_ROW_ACTIVE_DELAY = 28,
-       PDC_DIMM_SPD_RAS_CAS_DELAY    = 29,
-       PDC_DIMM_SPD_ACTIVE_PRECHARGE = 30,
-       PDC_DIMM_SPD_SYSTEM_FREQ      = 126,
-       PDC_CTL_STATUS                = 0x08,
-       PDC_DIMM_WINDOW_CTLR          = 0x0C,
-       PDC_TIME_CONTROL              = 0x3C,
-       PDC_TIME_PERIOD               = 0x40,
-       PDC_TIME_COUNTER              = 0x44,
-       PDC_GENERAL_CTLR              = 0x484,
-       PCI_PLL_INIT                  = 0x8A531824,
-       PCI_X_TCOUNT                  = 0xEE1E5CFF
+       PDC_DIMM0_SPD_DEV_ADDRESS       = 0x50,
+       PDC_DIMM1_SPD_DEV_ADDRESS       = 0x51,
+       PDC_I2C_CONTROL                 = 0x48,
+       PDC_I2C_ADDR_DATA               = 0x4C,
+       PDC_DIMM0_CONTROL               = 0x80,
+       PDC_DIMM1_CONTROL               = 0x84,
+       PDC_SDRAM_CONTROL               = 0x88,
+       PDC_I2C_WRITE                   = 0,            /* master -> slave */
+       PDC_I2C_READ                    = (1 << 6),     /* master <- slave */
+       PDC_I2C_START                   = (1 << 7),     /* start I2C proto */
+       PDC_I2C_MASK_INT                = (1 << 5),     /* mask I2C interrupt */
+       PDC_I2C_COMPLETE                = (1 << 16),    /* I2C normal compl. */
+       PDC_I2C_NO_ACK                  = (1 << 20),    /* slave no-ack addr */
+       PDC_DIMM_SPD_SUBADDRESS_START   = 0x00,
+       PDC_DIMM_SPD_SUBADDRESS_END     = 0x7F,
+       PDC_DIMM_SPD_ROW_NUM            = 3,
+       PDC_DIMM_SPD_COLUMN_NUM         = 4,
+       PDC_DIMM_SPD_MODULE_ROW         = 5,
+       PDC_DIMM_SPD_TYPE               = 11,
+       PDC_DIMM_SPD_FRESH_RATE         = 12,
+       PDC_DIMM_SPD_BANK_NUM           = 17,
+       PDC_DIMM_SPD_CAS_LATENCY        = 18,
+       PDC_DIMM_SPD_ATTRIBUTE          = 21,
+       PDC_DIMM_SPD_ROW_PRE_CHARGE     = 27,
+       PDC_DIMM_SPD_ROW_ACTIVE_DELAY   = 28,
+       PDC_DIMM_SPD_RAS_CAS_DELAY      = 29,
+       PDC_DIMM_SPD_ACTIVE_PRECHARGE   = 30,
+       PDC_DIMM_SPD_SYSTEM_FREQ        = 126,
+       PDC_CTL_STATUS                  = 0x08,
+       PDC_DIMM_WINDOW_CTLR            = 0x0C,
+       PDC_TIME_CONTROL                = 0x3C,
+       PDC_TIME_PERIOD                 = 0x40,
+       PDC_TIME_COUNTER                = 0x44,
+       PDC_GENERAL_CTLR                = 0x484,
+       PCI_PLL_INIT                    = 0x8A531824,
+       PCI_X_TCOUNT                    = 0xEE1E5CFF,
+
+       /* PDC_TIME_CONTROL bits */
+       PDC_TIMER_BUZZER                = (1 << 10),
+       PDC_TIMER_MODE_PERIODIC         = 0,            /* bits 9:8 == 00 */
+       PDC_TIMER_MODE_ONCE             = (1 << 8),     /* bits 9:8 == 01 */
+       PDC_TIMER_ENABLE                = (1 << 7),
+       PDC_TIMER_MASK_INT              = (1 << 5),
+       PDC_TIMER_SEQ_MASK              = 0x1f,         /* SEQ ID for timer */
+       PDC_TIMER_DEFAULT               = PDC_TIMER_MODE_ONCE |
+                                         PDC_TIMER_ENABLE |
+                                         PDC_TIMER_MASK_INT,
 };
 
 
@@ -217,7 +279,7 @@ static const struct ata_port_info pdc_port_info[] = {
                                  ATA_FLAG_NO_ATAPI | ATA_FLAG_PIO_POLLING,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma0-2 */
-               .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
+               .udma_mask      = ATA_UDMA6,
                .port_ops       = &pdc_20621_ops,
        },
 
@@ -999,17 +1061,17 @@ static unsigned int pdc20621_i2c_read(struct ata_host *host, u32 device,
        i2creg |= subaddr << 16;
 
        /* Set the device and subaddress */
-       writel(i2creg, mmio + PDC_I2C_ADDR_DATA_OFFSET);
-       readl(mmio + PDC_I2C_ADDR_DATA_OFFSET);
+       writel(i2creg, mmio + PDC_I2C_ADDR_DATA);
+       readl(mmio + PDC_I2C_ADDR_DATA);
 
        /* Write Control to perform read operation, mask int */
        writel(PDC_I2C_READ | PDC_I2C_START | PDC_I2C_MASK_INT,
-              mmio + PDC_I2C_CONTROL_OFFSET);
+              mmio + PDC_I2C_CONTROL);
 
        for (count = 0; count <= 1000; count ++) {
-               status = readl(mmio + PDC_I2C_CONTROL_OFFSET);
+               status = readl(mmio + PDC_I2C_CONTROL);
                if (status & PDC_I2C_COMPLETE) {
-                       status = readl(mmio + PDC_I2C_ADDR_DATA_OFFSET);
+                       status = readl(mmio + PDC_I2C_ADDR_DATA);
                        break;
                } else if (count == 1000)
                        return 0;
@@ -1099,8 +1161,8 @@ static int pdc20621_prog_dimm0(struct ata_host *host)
        data |= (((size / 16) - 1) << 16);
        data |= (0 << 23);
        data |= 8;
-       writel(data, mmio + PDC_DIMM0_CONTROL_OFFSET);
-       readl(mmio + PDC_DIMM0_CONTROL_OFFSET);
+       writel(data, mmio + PDC_DIMM0_CONTROL);
+       readl(mmio + PDC_DIMM0_CONTROL);
        return size;
 }
 
@@ -1122,27 +1184,27 @@ static unsigned int pdc20621_prog_dimm_global(struct ata_host *host)
        */
 
        data = 0x022259F1;
-       writel(data, mmio + PDC_SDRAM_CONTROL_OFFSET);
-       readl(mmio + PDC_SDRAM_CONTROL_OFFSET);
+       writel(data, mmio + PDC_SDRAM_CONTROL);
+       readl(mmio + PDC_SDRAM_CONTROL);
 
        /* Turn on for ECC */
        pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS,
                          PDC_DIMM_SPD_TYPE, &spd0);
        if (spd0 == 0x02) {
                data |= (0x01 << 16);
-               writel(data, mmio + PDC_SDRAM_CONTROL_OFFSET);
-               readl(mmio + PDC_SDRAM_CONTROL_OFFSET);
+               writel(data, mmio + PDC_SDRAM_CONTROL);
+               readl(mmio + PDC_SDRAM_CONTROL);
                printk(KERN_ERR "Local DIMM ECC Enabled\n");
        }
 
        /* DIMM Initialization Select/Enable (bit 18/19) */
        data &= (~(1<<18));
        data |= (1<<19);
-       writel(data, mmio + PDC_SDRAM_CONTROL_OFFSET);
+       writel(data, mmio + PDC_SDRAM_CONTROL);
 
        error = 1;
        for (i = 1; i <= 10; i++) {   /* polling ~5 secs */
-               data = readl(mmio + PDC_SDRAM_CONTROL_OFFSET);
+               data = readl(mmio + PDC_SDRAM_CONTROL);
                if (!(data & (1<<19))) {
                        error = 0;
                        break;
@@ -1176,7 +1238,7 @@ static unsigned int pdc20621_dimm_init(struct ata_host *host)
        VPRINTK("Time Period Register (0x40): 0x%x\n", time_period);
 
        /* Enable timer */
-       writel(0x00001a0, mmio + PDC_TIME_CONTROL);
+       writel(PDC_TIMER_DEFAULT, mmio + PDC_TIME_CONTROL);
        readl(mmio + PDC_TIME_CONTROL);
 
        /* Wait 3 seconds */
index 6815de7cca799bc569d194da33495605c95d0c90..b52f83ab056ac30256ef2b9c6d75831fdf9efc52 100644 (file)
@@ -129,7 +129,7 @@ static const struct ata_port_info uli_port_info = {
        .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
                          ATA_FLAG_IGN_SIMPLEX,
        .pio_mask       = 0x1f,         /* pio0-4 */
-       .udma_mask      = 0x7f,         /* udma0-6 */
+       .udma_mask      = ATA_UDMA6,
        .port_ops       = &uli_ops,
 };
 
@@ -213,7 +213,7 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        host->private_data = hpriv;
 
        /* the first two ports are standard SFF */
-       rc = ata_pci_init_native_host(host);
+       rc = ata_pci_init_sff_host(host);
        if (rc)
                return rc;
 
index e8b90e7b42ddcfa56e5253941bc33532258aeed0..c4124475f754f101fc427a63934901d59de9083b 100644 (file)
@@ -223,7 +223,7 @@ static const struct ata_port_info vt6420_port_info = {
        .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
        .pio_mask       = 0x1f,
        .mwdma_mask     = 0x07,
-       .udma_mask      = 0x7f,
+       .udma_mask      = ATA_UDMA6,
        .port_ops       = &vt6420_sata_ops,
 };
 
@@ -231,7 +231,7 @@ static struct ata_port_info vt6421_sport_info = {
        .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
        .pio_mask       = 0x1f,
        .mwdma_mask     = 0x07,
-       .udma_mask      = 0x7f,
+       .udma_mask      = ATA_UDMA6,
        .port_ops       = &vt6421_sata_ops,
 };
 
@@ -239,7 +239,7 @@ static struct ata_port_info vt6421_pport_info = {
        .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_LEGACY,
        .pio_mask       = 0x1f,
        .mwdma_mask     = 0,
-       .udma_mask      = 0x7f,
+       .udma_mask      = ATA_UDMA6,
        .port_ops       = &vt6421_pata_ops,
 };
 
@@ -303,9 +303,7 @@ static int vt6420_prereset(struct ata_port *ap, unsigned long deadline)
        if (!(ap->pflags & ATA_PFLAG_LOADING))
                goto skip_scr;
 
-       /* Resume phy.  This is the old resume sequence from
-        * __sata_phy_reset().
-        */
+       /* Resume phy.  This is the old SATA resume sequence */
        svia_scr_write(ap, SCR_CONTROL, 0x300);
        svia_scr_read(ap, SCR_CONTROL); /* flush */
 
@@ -414,7 +412,7 @@ static int vt6420_prepare_host(struct pci_dev *pdev, struct ata_host **r_host)
        struct ata_host *host;
        int rc;
 
-       rc = ata_pci_prepare_native_host(pdev, ppi, &host);
+       rc = ata_pci_prepare_sff_host(pdev, ppi, &host);
        if (rc)
                return rc;
        *r_host = host;
index 81330175fc8982543789628a4c443819792f14ce..1b5d81faa10248c740694adcdc4e62c83c1363dd 100644 (file)
@@ -371,7 +371,7 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d
                                  ATA_FLAG_MMIO,
                .pio_mask       = 0x1f,
                .mwdma_mask     = 0x07,
-               .udma_mask      = 0x7f,
+               .udma_mask      = ATA_UDMA6,
                .port_ops       = &vsc_sata_ops,
        };
        const struct ata_port_info *ppi[] = { &pi, NULL };
index 0d3a38b1cb0b221db91c2e3d27aad589b8d1dac4..77637e780d4150eee9713b7117e0fd0adcdb1573 100644 (file)
@@ -1704,7 +1704,6 @@ static int __devinit eni_do_init(struct atm_dev *dev)
        struct pci_dev *pci_dev;
        unsigned long real_base;
        void __iomem *base;
-       unsigned char revision;
        int error,i,last;
 
        DPRINTK(">eni_init\n");
@@ -1715,12 +1714,6 @@ static int __devinit eni_do_init(struct atm_dev *dev)
        pci_dev = eni_dev->pci_dev;
        real_base = pci_resource_start(pci_dev, 0);
        eni_dev->irq = pci_dev->irq;
-       error = pci_read_config_byte(pci_dev,PCI_REVISION_ID,&revision);
-       if (error) {
-               printk(KERN_ERR DEV_LABEL "(itf %d): init error 0x%02x\n",
-                   dev->number,error);
-               return -EINVAL;
-       }
        if ((error = pci_write_config_word(pci_dev,PCI_COMMAND,
            PCI_COMMAND_MEMORY |
            (eni_dev->asic ? PCI_COMMAND_PARITY | PCI_COMMAND_SERR : 0)))) {
@@ -1729,7 +1722,7 @@ static int __devinit eni_do_init(struct atm_dev *dev)
                return -EIO;
        }
        printk(KERN_NOTICE DEV_LABEL "(itf %d): rev.%d,base=0x%lx,irq=%d,",
-           dev->number,revision,real_base,eni_dev->irq);
+           dev->number,pci_dev->revision,real_base,eni_dev->irq);
        if (!(base = ioremap_nocache(real_base,MAP_MAX_SIZE))) {
                printk("\n");
                printk(KERN_ERR DEV_LABEL "(itf %d): can't set up page "
index 3800bc0cb2efe8d9016f54fd19e007096cda1842..8f995ce8d73b460a7fb88e25d70d05298477a483 100644 (file)
@@ -3679,7 +3679,6 @@ idt77252_init_one(struct pci_dev *pcidev, const struct pci_device_id *id)
        unsigned long membase, srambase;
        struct idt77252_dev *card;
        struct atm_dev *dev;
-       ushort revision = 0;
        int i, err;
 
 
@@ -3688,19 +3687,13 @@ idt77252_init_one(struct pci_dev *pcidev, const struct pci_device_id *id)
                return err;
        }
 
-       if (pci_read_config_word(pcidev, PCI_REVISION_ID, &revision)) {
-               printk("idt77252-%d: can't read PCI_REVISION_ID\n", index);
-               err = -ENODEV;
-               goto err_out_disable_pdev;
-       }
-
        card = kzalloc(sizeof(struct idt77252_dev), GFP_KERNEL);
        if (!card) {
                printk("idt77252-%d: can't allocate private data\n", index);
                err = -ENOMEM;
                goto err_out_disable_pdev;
        }
-       card->revision = revision;
+       card->revision = pcidev->revision;
        card->index = index;
        card->pcidev = pcidev;
        sprintf(card->name, "idt77252-%d", card->index);
@@ -3762,8 +3755,8 @@ idt77252_init_one(struct pci_dev *pcidev, const struct pci_device_id *id)
        }
 
        printk("%s: ABR SAR (Rev %c): MEM %08lx SRAM %08lx [%u KB]\n",
-              card->name, ((revision > 1) && (revision < 25)) ?
-              'A' + revision - 1 : '?', membase, srambase,
+              card->name, ((card->revision > 1) && (card->revision < 25)) ?
+              'A' + card->revision - 1 : '?', membase, srambase,
               card->sramsize / 1024);
 
        if (init_card(dev)) {
index bb7ef570514cd660e2a200af09647bbebd97a416..a3b605a0ca17a47e106359e4299d5db2e70515df 100644 (file)
@@ -2290,7 +2290,6 @@ static int __devinit ia_init(struct atm_dev *dev)
        unsigned long real_base;
        void __iomem *base;
        unsigned short command;  
-       unsigned char revision;  
        int error, i; 
          
        /* The device has been identified and registered. Now we read   
@@ -2305,16 +2304,14 @@ static int __devinit ia_init(struct atm_dev *dev)
        real_base = pci_resource_start (iadev->pci, 0);
        iadev->irq = iadev->pci->irq;
                  
-       if ((error = pci_read_config_word(iadev->pci, PCI_COMMAND,&command))   
-                   || (error = pci_read_config_byte(iadev->pci,   
-                               PCI_REVISION_ID,&revision)))   
-       {  
+       error = pci_read_config_word(iadev->pci, PCI_COMMAND, &command);
+       if (error) {
                printk(KERN_ERR DEV_LABEL "(itf %d): init error 0x%x\n",  
                                dev->number,error);  
                return -EINVAL;  
        }  
        IF_INIT(printk(DEV_LABEL "(itf %d): rev.%d,realbase=0x%lx,irq=%d\n",  
-                       dev->number, revision, real_base, iadev->irq);)  
+                       dev->number, iadev->pci->revision, real_base, iadev->irq);)
          
        /* find mapping size of board */  
          
@@ -2353,7 +2350,7 @@ static int __devinit ia_init(struct atm_dev *dev)
                return error;  
        }  
        IF_INIT(printk(DEV_LABEL " (itf %d): rev.%d,base=%p,irq=%d\n",  
-                       dev->number, revision, base, iadev->irq);)  
+                       dev->number, iadev->pci->revision, base, iadev->irq);)
          
        /* filling the iphase dev structure */  
        iadev->mem = iadev->pci_map_size /2;  
index 09f477d4237a5f553d711748dab5ff953f3255b3..0e2c1ae650e7f9b4cfeb15342bd9a26ea9bfbf1d 100644 (file)
@@ -246,8 +246,8 @@ struct lanai_vcc {
 };
 
 enum lanai_type {
-       lanai2  = PCI_VENDOR_ID_EF_ATM_LANAI2,
-       lanaihb = PCI_VENDOR_ID_EF_ATM_LANAIHB
+       lanai2  = PCI_DEVICE_ID_EF_ATM_LANAI2,
+       lanaihb = PCI_DEVICE_ID_EF_ATM_LANAIHB
 };
 
 struct lanai_dev_stats {
@@ -293,7 +293,6 @@ struct lanai_dev {
        struct atm_vcc *cbrvcc;
        int number;
        int board_rev;
-       u8 pci_revision;
 /* TODO - look at race conditions with maintence of conf1/conf2 */
 /* TODO - transmit locking: should we use _irq not _irqsave? */
 /* TODO - organize above in some rational fashion (see <asm/cache.h>) */
@@ -1969,14 +1968,6 @@ static int __devinit lanai_pci_start(struct lanai_dev *lanai)
                    "(itf %d): No suitable DMA available.\n", lanai->number);
                return -EBUSY;
        }
-       /* Get the pci revision byte */
-       result = pci_read_config_byte(pci, PCI_REVISION_ID,
-           &lanai->pci_revision);
-       if (result != PCIBIOS_SUCCESSFUL) {
-               printk(KERN_ERR DEV_LABEL "(itf %d): can't read "
-                   "PCI_REVISION_ID: %d\n", lanai->number, result);
-               return -EINVAL;
-       }
        result = pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &w);
        if (result != PCIBIOS_SUCCESSFUL) {
                printk(KERN_ERR DEV_LABEL "(itf %d): can't read "
@@ -2254,7 +2245,7 @@ static int __devinit lanai_dev_open(struct atm_dev *atmdev)
        lanai_timed_poll_start(lanai);
        printk(KERN_NOTICE DEV_LABEL "(itf %d): rev.%d, base=0x%lx, irq=%u "
            "(%02X-%02X-%02X-%02X-%02X-%02X)\n", lanai->number,
-           (int) lanai->pci_revision, (unsigned long) lanai->base,
+           (int) lanai->pci->revision, (unsigned long) lanai->base,
            lanai->pci->irq,
            atmdev->esi[0], atmdev->esi[1], atmdev->esi[2],
            atmdev->esi[3], atmdev->esi[4], atmdev->esi[5]);
@@ -2491,7 +2482,7 @@ static int lanai_proc_read(struct atm_dev *atmdev, loff_t *pos, char *page)
                    (unsigned int) lanai->magicno, lanai->num_vci);
        if (left-- == 0)
                return sprintf(page, "revision: board=%d, pci_if=%d\n",
-                   lanai->board_rev, (int) lanai->pci_revision);
+                   lanai->board_rev, (int) lanai->pci->revision);
        if (left-- == 0)
                return sprintf(page, "EEPROM ESI: "
                    "%02X:%02X:%02X:%02X:%02X:%02X\n",
@@ -2631,14 +2622,8 @@ static int __devinit lanai_init_one(struct pci_dev *pci,
 }
 
 static struct pci_device_id lanai_pci_tbl[] = {
-       {
-               PCI_VENDOR_ID_EF, PCI_VENDOR_ID_EF_ATM_LANAI2,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0
-       },
-       {
-               PCI_VENDOR_ID_EF, PCI_VENDOR_ID_EF_ATM_LANAIHB,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0
-       },
+       { PCI_VDEVICE(EF, PCI_DEVICE_ID_EF_ATM_LANAI2) },
+       { PCI_VDEVICE(EF, PCI_DEVICE_ID_EF_ATM_LANAIHB) },
        { 0, }  /* terminal entry */
 };
 MODULE_DEVICE_TABLE(pci, lanai_pci_tbl);
index 2ad2527cf5b324d47568e1411dd186ec5ea984ba..020a87a476c813945d1f1f1ffc55c398704dc502 100644 (file)
@@ -1182,7 +1182,6 @@ static int __devinit zatm_init(struct atm_dev *dev)
        struct zatm_dev *zatm_dev;
        struct pci_dev *pci_dev;
        unsigned short command;
-       unsigned char revision;
        int error,i,last;
        unsigned long t0,t1,t2;
 
@@ -1192,8 +1191,7 @@ static int __devinit zatm_init(struct atm_dev *dev)
        pci_dev = zatm_dev->pci_dev;
        zatm_dev->base = pci_resource_start(pci_dev, 0);
        zatm_dev->irq = pci_dev->irq;
-       if ((error = pci_read_config_word(pci_dev,PCI_COMMAND,&command)) ||
-           (error = pci_read_config_byte(pci_dev,PCI_REVISION_ID,&revision))) {
+       if ((error = pci_read_config_word(pci_dev,PCI_COMMAND,&command))) {
                printk(KERN_ERR DEV_LABEL "(itf %d): init error 0x%02x\n",
                    dev->number,error);
                return -EINVAL;
@@ -1206,7 +1204,7 @@ static int __devinit zatm_init(struct atm_dev *dev)
        }
        eprom_get_esi(dev);
        printk(KERN_NOTICE DEV_LABEL "(itf %d): rev.%d,base=0x%x,irq=%d,",
-           dev->number,revision,zatm_dev->base,zatm_dev->irq);
+           dev->number,pci_dev->revision,zatm_dev->base,zatm_dev->irq);
        /* reset uPD98401 */
        zout(0,SWR);
        while (!(zin(GSR) & uPD98401_INT_IND));
index 1ec0654665cfd97098aabcb54e16e66ac8e1aa0b..7370d7cf59888050d374d7a48a03185a06f0df7c 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/slab.h>
 #include <linux/list.h>
 #include <linux/module.h>
+#include <linux/mutex.h>
 
 #include "base.h"
 
index 5512d84452f2d9a5c0bd9df4e4f06599b4e5aacf..47eb02d9f1afdc30489a9520ae44ba334a4bd9ea 100644 (file)
@@ -44,6 +44,6 @@ struct class_device_attribute *to_class_dev_attr(struct attribute *_attr)
 
 extern char *make_class_name(const char *name, struct kobject *kobj);
 
-extern void devres_release_all(struct device *dev);
+extern int devres_release_all(struct device *dev);
 
 extern struct kset devices_subsys;
index dca734819e50cc670439f22806eac6198e8c29eb..61c67526a656c29d05a1a1e93bba6f4e86872a14 100644 (file)
@@ -138,12 +138,24 @@ void bus_remove_file(struct bus_type * bus, struct bus_attribute * attr)
        }
 }
 
-static struct kobj_type ktype_bus = {
+static struct kobj_type bus_ktype = {
        .sysfs_ops      = &bus_sysfs_ops,
+};
+
+static int bus_uevent_filter(struct kset *kset, struct kobject *kobj)
+{
+       struct kobj_type *ktype = get_ktype(kobj);
 
+       if (ktype == &bus_ktype)
+               return 1;
+       return 0;
+}
+
+static struct kset_uevent_ops bus_uevent_ops = {
+       .filter = bus_uevent_filter,
 };
 
-static decl_subsys(bus, &ktype_bus, NULL);
+static decl_subsys(bus, &bus_ktype, &bus_uevent_ops);
 
 
 #ifdef CONFIG_HOTPLUG
@@ -562,7 +574,6 @@ static int add_probe_files(struct bus_type *bus)
 
        bus->drivers_probe_attr.attr.name = "drivers_probe";
        bus->drivers_probe_attr.attr.mode = S_IWUSR;
-       bus->drivers_probe_attr.attr.owner = bus->owner;
        bus->drivers_probe_attr.store = store_drivers_probe;
        retval = bus_create_file(bus, &bus->drivers_probe_attr);
        if (retval)
@@ -570,7 +581,6 @@ static int add_probe_files(struct bus_type *bus)
 
        bus->drivers_autoprobe_attr.attr.name = "drivers_autoprobe";
        bus->drivers_autoprobe_attr.attr.mode = S_IWUSR | S_IRUGO;
-       bus->drivers_autoprobe_attr.attr.owner = bus->owner;
        bus->drivers_autoprobe_attr.show = show_drivers_autoprobe;
        bus->drivers_autoprobe_attr.store = store_drivers_autoprobe;
        retval = bus_create_file(bus, &bus->drivers_autoprobe_attr);
@@ -610,7 +620,8 @@ int bus_add_driver(struct device_driver *drv)
        if (error)
                goto out_put_bus;
        drv->kobj.kset = &bus->drivers;
-       if ((error = kobject_register(&drv->kobj)))
+       error = kobject_register(&drv->kobj);
+       if (error)
                goto out_put_bus;
 
        if (drv->bus->drivers_autoprobe) {
@@ -760,7 +771,8 @@ static int bus_add_attrs(struct bus_type * bus)
 
        if (bus->bus_attrs) {
                for (i = 0; attr_name(bus->bus_attrs[i]); i++) {
-                       if ((error = bus_create_file(bus,&bus->bus_attrs[i])))
+                       error = bus_create_file(bus,&bus->bus_attrs[i]);
+                       if (error)
                                goto Err;
                }
        }
index 8c506dbe39138bc11b8901944a81461c5a424e79..4d2222618b780f47dfa54e40246dbd9e4c8bdcc7 100644 (file)
@@ -312,9 +312,6 @@ static void class_dev_release(struct kobject * kobj)
 
        pr_debug("device class '%s': release.\n", cd->class_id);
 
-       kfree(cd->devt_attr);
-       cd->devt_attr = NULL;
-
        if (cd->release)
                cd->release(cd);
        else if (cls->release)
@@ -547,6 +544,9 @@ static ssize_t show_dev(struct class_device *class_dev, char *buf)
        return print_dev_t(buf, class_dev->devt);
 }
 
+static struct class_device_attribute class_devt_attr =
+       __ATTR(dev, S_IRUGO, show_dev, NULL);
+
 static ssize_t store_uevent(struct class_device *class_dev,
                            const char *buf, size_t count)
 {
@@ -554,6 +554,9 @@ static ssize_t store_uevent(struct class_device *class_dev,
        return count;
 }
 
+static struct class_device_attribute class_uevent_attr =
+       __ATTR(uevent, S_IWUSR, NULL, store_uevent);
+
 void class_device_initialize(struct class_device *class_dev)
 {
        kobj_set_kset_s(class_dev, class_obj_subsys);
@@ -603,32 +606,15 @@ int class_device_add(struct class_device *class_dev)
                                  &parent_class->subsys.kobj, "subsystem");
        if (error)
                goto out3;
-       class_dev->uevent_attr.attr.name = "uevent";
-       class_dev->uevent_attr.attr.mode = S_IWUSR;
-       class_dev->uevent_attr.attr.owner = parent_class->owner;
-       class_dev->uevent_attr.store = store_uevent;
-       error = class_device_create_file(class_dev, &class_dev->uevent_attr);
+
+       error = class_device_create_file(class_dev, &class_uevent_attr);
        if (error)
                goto out3;
 
        if (MAJOR(class_dev->devt)) {
-               struct class_device_attribute *attr;
-               attr = kzalloc(sizeof(*attr), GFP_KERNEL);
-               if (!attr) {
-                       error = -ENOMEM;
-                       goto out4;
-               }
-               attr->attr.name = "dev";
-               attr->attr.mode = S_IRUGO;
-               attr->attr.owner = parent_class->owner;
-               attr->show = show_dev;
-               error = class_device_create_file(class_dev, attr);
-               if (error) {
-                       kfree(attr);
+               error = class_device_create_file(class_dev, &class_devt_attr);
+               if (error)
                        goto out4;
-               }
-
-               class_dev->devt_attr = attr;
        }
 
        error = class_device_add_attrs(class_dev);
@@ -671,10 +657,10 @@ int class_device_add(struct class_device *class_dev)
  out6:
        class_device_remove_attrs(class_dev);
  out5:
-       if (class_dev->devt_attr)
-               class_device_remove_file(class_dev, class_dev->devt_attr);
+       if (MAJOR(class_dev->devt))
+               class_device_remove_file(class_dev, &class_devt_attr);
  out4:
-       class_device_remove_file(class_dev, &class_dev->uevent_attr);
+       class_device_remove_file(class_dev, &class_uevent_attr);
  out3:
        kobject_del(&class_dev->kobj);
  out2:
@@ -774,9 +760,9 @@ void class_device_del(struct class_device *class_dev)
                sysfs_remove_link(&class_dev->kobj, "device");
        }
        sysfs_remove_link(&class_dev->kobj, "subsystem");
-       class_device_remove_file(class_dev, &class_dev->uevent_attr);
-       if (class_dev->devt_attr)
-               class_device_remove_file(class_dev, class_dev->devt_attr);
+       class_device_remove_file(class_dev, &class_uevent_attr);
+       if (MAJOR(class_dev->devt))
+               class_device_remove_file(class_dev, &class_devt_attr);
        class_device_remove_attrs(class_dev);
        class_device_remove_groups(class_dev);
 
index dd40d78a023dd1f2fde9712ac7700d5ade4893cf..0455aa78fa135cb04529efb281386d25423b2970 100644 (file)
@@ -310,6 +310,9 @@ static ssize_t store_uevent(struct device *dev, struct device_attribute *attr,
        return count;
 }
 
+static struct device_attribute uevent_attr =
+       __ATTR(uevent, S_IRUGO | S_IWUSR, show_uevent, store_uevent);
+
 static int device_add_attributes(struct device *dev,
                                 struct device_attribute *attrs)
 {
@@ -423,6 +426,9 @@ static ssize_t show_dev(struct device *dev, struct device_attribute *attr,
        return print_dev_t(buf, dev->devt);
 }
 
+static struct device_attribute devt_attr =
+       __ATTR(dev, S_IRUGO, show_dev, NULL);
+
 /*
  *     devices_subsys - structure to be registered with kobject core.
  */
@@ -681,35 +687,14 @@ int device_add(struct device *dev)
                blocking_notifier_call_chain(&dev->bus->bus_notifier,
                                             BUS_NOTIFY_ADD_DEVICE, dev);
 
-       dev->uevent_attr.attr.name = "uevent";
-       dev->uevent_attr.attr.mode = S_IRUGO | S_IWUSR;
-       if (dev->driver)
-               dev->uevent_attr.attr.owner = dev->driver->owner;
-       dev->uevent_attr.store = store_uevent;
-       dev->uevent_attr.show = show_uevent;
-       error = device_create_file(dev, &dev->uevent_attr);
+       error = device_create_file(dev, &uevent_attr);
        if (error)
                goto attrError;
 
        if (MAJOR(dev->devt)) {
-               struct device_attribute *attr;
-               attr = kzalloc(sizeof(*attr), GFP_KERNEL);
-               if (!attr) {
-                       error = -ENOMEM;
-                       goto ueventattrError;
-               }
-               attr->attr.name = "dev";
-               attr->attr.mode = S_IRUGO;
-               if (dev->driver)
-                       attr->attr.owner = dev->driver->owner;
-               attr->show = show_dev;
-               error = device_create_file(dev, attr);
-               if (error) {
-                       kfree(attr);
+               error = device_create_file(dev, &devt_attr);
+               if (error)
                        goto ueventattrError;
-               }
-
-               dev->devt_attr = attr;
        }
 
        if (dev->class) {
@@ -733,11 +718,14 @@ int device_add(struct device *dev)
                }
        }
 
-       if ((error = device_add_attrs(dev)))
+       error = device_add_attrs(dev);
+       if (error)
                goto AttrsError;
-       if ((error = device_pm_add(dev)))
+       error = device_pm_add(dev);
+       if (error)
                goto PMError;
-       if ((error = bus_add_device(dev)))
+       error = bus_add_device(dev);
+       if (error)
                goto BusError;
        kobject_uevent(&dev->kobj, KOBJ_ADD);
        bus_attach_device(dev);
@@ -767,10 +755,8 @@ int device_add(struct device *dev)
                                             BUS_NOTIFY_DEL_DEVICE, dev);
        device_remove_attrs(dev);
  AttrsError:
-       if (dev->devt_attr) {
-               device_remove_file(dev, dev->devt_attr);
-               kfree(dev->devt_attr);
-       }
+       if (MAJOR(dev->devt))
+               device_remove_file(dev, &devt_attr);
 
        if (dev->class) {
                sysfs_remove_link(&dev->kobj, "subsystem");
@@ -792,7 +778,7 @@ int device_add(struct device *dev)
                }
        }
  ueventattrError:
-       device_remove_file(dev, &dev->uevent_attr);
+       device_remove_file(dev, &uevent_attr);
  attrError:
        kobject_uevent(&dev->kobj, KOBJ_REMOVE);
        kobject_del(&dev->kobj);
@@ -869,10 +855,8 @@ void device_del(struct device * dev)
 
        if (parent)
                klist_del(&dev->knode_parent);
-       if (dev->devt_attr) {
-               device_remove_file(dev, dev->devt_attr);
-               kfree(dev->devt_attr);
-       }
+       if (MAJOR(dev->devt))
+               device_remove_file(dev, &devt_attr);
        if (dev->class) {
                sysfs_remove_link(&dev->kobj, "subsystem");
                /* If this is not a "fake" compatible device, remove the
@@ -926,7 +910,7 @@ void device_del(struct device * dev)
                        up(&dev->class->sem);
                }
        }
-       device_remove_file(dev, &dev->uevent_attr);
+       device_remove_file(dev, &uevent_attr);
        device_remove_attrs(dev);
        bus_remove_device(dev);
 
index b0088b0efecdd1e5395e4104d23d0fe34dbb9a0d..7ac474db88c525f46a0846810ca5f384fa07b104 100644 (file)
@@ -281,24 +281,16 @@ int driver_attach(struct device_driver * drv)
        return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
 }
 
-/**
- *     device_release_driver - manually detach device from driver.
- *     @dev:   device.
- *
- *     Manually detach device from driver.
- *
+/*
  *     __device_release_driver() must be called with @dev->sem held.
- *     When called for a USB interface, @dev->parent->sem must be held
- *     as well.
+ *     When called for a USB interface, @dev->parent->sem must be held as well.
  */
-
 static void __device_release_driver(struct device * dev)
 {
        struct device_driver * drv;
 
-       drv = dev->driver;
+       drv = get_driver(dev->driver);
        if (drv) {
-               get_driver(drv);
                driver_sysfs_remove(dev);
                sysfs_remove_link(&dev->kobj, "driver");
                klist_remove(&dev->knode_driver);
@@ -318,6 +310,13 @@ static void __device_release_driver(struct device * dev)
        }
 }
 
+/**
+ *     device_release_driver - manually detach device from driver.
+ *     @dev:   device.
+ *
+ *     Manually detach device from driver.
+ *     When called for a USB interface, @dev->parent->sem must be held.
+ */
 void device_release_driver(struct device * dev)
 {
        /*
index e1c0730a3b995d246ad965330854e768f746ab65..e8beb8e5b6264232dbfc0ea2dc7ae95d76f5af64 100644 (file)
@@ -10,6 +10,8 @@
 #include <linux/device.h>
 #include <linux/module.h>
 
+#include "base.h"
+
 struct devres_node {
        struct list_head                entry;
        dr_release_t                    release;
index 89a5f4a5491391e2270069090f43c6e82b6ef601..53f0ee6f301663db0ff4b87b5500b39bcd74744b 100644 (file)
@@ -175,7 +175,7 @@ static ssize_t firmware_loading_store(struct device *dev,
 static DEVICE_ATTR(loading, 0644, firmware_loading_show, firmware_loading_store);
 
 static ssize_t
-firmware_data_read(struct kobject *kobj,
+firmware_data_read(struct kobject *kobj, struct bin_attribute *bin_attr,
                   char *buffer, loff_t offset, size_t count)
 {
        struct device *dev = to_dev(kobj);
@@ -240,7 +240,7 @@ fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
  *     the driver as a firmware image.
  **/
 static ssize_t
-firmware_data_write(struct kobject *kobj,
+firmware_data_write(struct kobject *kobj, struct bin_attribute *bin_attr,
                    char *buffer, loff_t offset, size_t count)
 {
        struct device *dev = to_dev(kobj);
@@ -271,7 +271,7 @@ out:
 }
 
 static struct bin_attribute firmware_attr_data_tmpl = {
-       .attr = {.name = "data", .mode = 0644, .owner = THIS_MODULE},
+       .attr = {.name = "data", .mode = 0644},
        .size = 0,
        .read = firmware_data_read,
        .write = firmware_data_write,
index 05dc8764e7650170ceabfd9c7f0fc8223afd33ce..eb9f38d0aa58f3d13928923627d66512e3255c38 100644 (file)
  */
 
 #include <linux/device.h>
+#include <linux/mutex.h>
+
 #include "power.h"
 
 LIST_HEAD(dpm_active);
 LIST_HEAD(dpm_off);
 LIST_HEAD(dpm_off_irq);
 
-DECLARE_MUTEX(dpm_sem);
-DECLARE_MUTEX(dpm_list_sem);
+DEFINE_MUTEX(dpm_mtx);
+DEFINE_MUTEX(dpm_list_mtx);
 
 int (*platform_enable_wakeup)(struct device *dev, int is_on);
 
-
-/**
- *     device_pm_set_parent - Specify power dependency.
- *     @dev:           Device who needs power.
- *     @parent:        Device that supplies power.
- *
- *     This function is used to manually describe a power-dependency
- *     relationship. It may be used to specify a transversal relationship
- *     (where the power supplier is not the physical (or electrical)
- *     ancestor of a specific device.
- *     The effect of this is that the supplier will not be powered down
- *     before the power dependent.
- */
-
-void device_pm_set_parent(struct device * dev, struct device * parent)
-{
-       put_device(dev->power.pm_parent);
-       dev->power.pm_parent = get_device(parent);
-}
-EXPORT_SYMBOL_GPL(device_pm_set_parent);
-
-int device_pm_add(struct device * dev)
+int device_pm_add(struct device *dev)
 {
        int error;
 
        pr_debug("PM: Adding info for %s:%s\n",
                 dev->bus ? dev->bus->name : "No Bus",
                 kobject_name(&dev->kobj));
-       down(&dpm_list_sem);
+       mutex_lock(&dpm_list_mtx);
        list_add_tail(&dev->power.entry, &dpm_active);
-       device_pm_set_parent(dev, dev->parent);
-       if ((error = dpm_sysfs_add(dev)))
+       error = dpm_sysfs_add(dev);
+       if (error)
                list_del(&dev->power.entry);
-       up(&dpm_list_sem);
+       mutex_unlock(&dpm_list_mtx);
        return error;
 }
 
-void device_pm_remove(struct device * dev)
+void device_pm_remove(struct device *dev)
 {
        pr_debug("PM: Removing info for %s:%s\n",
                 dev->bus ? dev->bus->name : "No Bus",
                 kobject_name(&dev->kobj));
-       down(&dpm_list_sem);
+       mutex_lock(&dpm_list_mtx);
        dpm_sysfs_remove(dev);
-       put_device(dev->power.pm_parent);
        list_del_init(&dev->power.entry);
-       up(&dpm_list_sem);
+       mutex_unlock(&dpm_list_mtx);
 }
 
 
index fb3d35a9e101582563b357848617cd7539e65e3a..2760f25b3ac5794a3e4557b28266c8354af740f6 100644 (file)
@@ -14,12 +14,12 @@ extern void device_shutdown(void);
 /*
  * Used to synchronize global power management operations.
  */
-extern struct semaphore dpm_sem;
+extern struct mutex dpm_mtx;
 
 /*
  * Used to serialize changes to the dpm_* lists.
  */
-extern struct semaphore dpm_list_sem;
+extern struct mutex dpm_list_mtx;
 
 /*
  * The PM lists.
index a2c64188d7133fc95c31343592039f7ace18a64b..00fd84ae6e66f955855f39286b66632c50b0e3dc 100644 (file)
@@ -29,14 +29,6 @@ int resume_device(struct device * dev)
 
        down(&dev->sem);
 
-       if (dev->power.pm_parent
-                       && dev->power.pm_parent->power.power_state.event) {
-               dev_err(dev, "PM: resume from %d, parent %s still %d\n",
-                       dev->power.power_state.event,
-                       dev->power.pm_parent->bus_id,
-                       dev->power.pm_parent->power.power_state.event);
-       }
-
        if (dev->bus && dev->bus->resume) {
                dev_dbg(dev,"resuming\n");
                error = dev->bus->resume(dev);
@@ -80,7 +72,7 @@ static int resume_device_early(struct device * dev)
  */
 void dpm_resume(void)
 {
-       down(&dpm_list_sem);
+       mutex_lock(&dpm_list_mtx);
        while(!list_empty(&dpm_off)) {
                struct list_head * entry = dpm_off.next;
                struct device * dev = to_device(entry);
@@ -88,13 +80,12 @@ void dpm_resume(void)
                get_device(dev);
                list_move_tail(entry, &dpm_active);
 
-               up(&dpm_list_sem);
-               if (!dev->power.prev_state.event)
-                       resume_device(dev);
-               down(&dpm_list_sem);
+               mutex_unlock(&dpm_list_mtx);
+               resume_device(dev);
+               mutex_lock(&dpm_list_mtx);
                put_device(dev);
        }
-       up(&dpm_list_sem);
+       mutex_unlock(&dpm_list_mtx);
 }
 
 
@@ -108,9 +99,9 @@ void dpm_resume(void)
 void device_resume(void)
 {
        might_sleep();
-       down(&dpm_sem);
+       mutex_lock(&dpm_mtx);
        dpm_resume();
-       up(&dpm_sem);
+       mutex_unlock(&dpm_mtx);
 }
 
 EXPORT_SYMBOL_GPL(device_resume);
index 96370ec1d673fc3d07a2a03b496980517891c304..df6174d858664288dc93fb34c36c23bfe8faed29 100644 (file)
@@ -32,9 +32,9 @@ static void runtime_resume(struct device * dev)
 
 void dpm_runtime_resume(struct device * dev)
 {
-       down(&dpm_sem);
+       mutex_lock(&dpm_mtx);
        runtime_resume(dev);
-       up(&dpm_sem);
+       mutex_unlock(&dpm_mtx);
 }
 EXPORT_SYMBOL(dpm_runtime_resume);
 
@@ -49,7 +49,7 @@ int dpm_runtime_suspend(struct device * dev, pm_message_t state)
 {
        int error = 0;
 
-       down(&dpm_sem);
+       mutex_lock(&dpm_mtx);
        if (dev->power.power_state.event == state.event)
                goto Done;
 
@@ -59,7 +59,7 @@ int dpm_runtime_suspend(struct device * dev, pm_message_t state)
        if (!(error = suspend_device(dev, state)))
                dev->power.power_state = state;
  Done:
-       up(&dpm_sem);
+       mutex_unlock(&dpm_mtx);
        return error;
 }
 EXPORT_SYMBOL(dpm_runtime_suspend);
@@ -78,8 +78,8 @@ EXPORT_SYMBOL(dpm_runtime_suspend);
  */
 void dpm_set_power_state(struct device * dev, pm_message_t state)
 {
-       down(&dpm_sem);
+       mutex_lock(&dpm_mtx);
        dev->power.power_state = state;
-       up(&dpm_sem);
+       mutex_unlock(&dpm_mtx);
 }
 #endif  /*  0  */
index 42d2b86ba7652944917a2b40a31d70e485a60622..26df9b231737de51c0541567553704cac4381d70 100644 (file)
@@ -40,6 +40,14 @@ static inline char *suspend_verb(u32 event)
 }
 
 
+static void
+suspend_device_dbg(struct device *dev, pm_message_t state, char *info)
+{
+       dev_dbg(dev, "%s%s%s\n", info, suspend_verb(state.event),
+               ((state.event == PM_EVENT_SUSPEND) && device_may_wakeup(dev)) ?
+               ", may wakeup" : "");
+}
+
 /**
  *     suspend_device - Save state of one device.
  *     @dev:   Device.
@@ -55,49 +63,21 @@ int suspend_device(struct device * dev, pm_message_t state)
                dev_dbg(dev, "PM: suspend %d-->%d\n",
                        dev->power.power_state.event, state.event);
        }
-       if (dev->power.pm_parent
-                       && dev->power.pm_parent->power.power_state.event) {
-               dev_err(dev,
-                       "PM: suspend %d->%d, parent %s already %d\n",
-                       dev->power.power_state.event, state.event,
-                       dev->power.pm_parent->bus_id,
-                       dev->power.pm_parent->power.power_state.event);
-       }
-
-       dev->power.prev_state = dev->power.power_state;
 
-       if (dev->class && dev->class->suspend && !dev->power.power_state.event) {
-               dev_dbg(dev, "class %s%s\n",
-                       suspend_verb(state.event),
-                       ((state.event == PM_EVENT_SUSPEND)
-                                       && device_may_wakeup(dev))
-                               ? ", may wakeup"
-                               : ""
-                       );
+       if (dev->class && dev->class->suspend) {
+               suspend_device_dbg(dev, state, "class ");
                error = dev->class->suspend(dev, state);
                suspend_report_result(dev->class->suspend, error);
        }
 
-       if (!error && dev->type && dev->type->suspend && !dev->power.power_state.event) {
-               dev_dbg(dev, "%s%s\n",
-                       suspend_verb(state.event),
-                       ((state.event == PM_EVENT_SUSPEND)
-                                       && device_may_wakeup(dev))
-                               ? ", may wakeup"
-                               : ""
-                       );
+       if (!error && dev->type && dev->type->suspend) {
+               suspend_device_dbg(dev, state, "type ");
                error = dev->type->suspend(dev, state);
                suspend_report_result(dev->type->suspend, error);
        }
 
-       if (!error && dev->bus && dev->bus->suspend && !dev->power.power_state.event) {
-               dev_dbg(dev, "%s%s\n",
-                       suspend_verb(state.event),
-                       ((state.event == PM_EVENT_SUSPEND)
-                                       && device_may_wakeup(dev))
-                               ? ", may wakeup"
-                               : ""
-                       );
+       if (!error && dev->bus && dev->bus->suspend) {
+               suspend_device_dbg(dev, state, "");
                error = dev->bus->suspend(dev, state);
                suspend_report_result(dev->bus->suspend, error);
        }
@@ -108,21 +88,15 @@ int suspend_device(struct device * dev, pm_message_t state)
 
 /*
  * This is called with interrupts off, only a single CPU
- * running. We can't do down() on a semaphore (and we don't
+ * running. We can't acquire a mutex or semaphore (and we don't
  * need the protection)
  */
 static int suspend_device_late(struct device *dev, pm_message_t state)
 {
        int error = 0;
 
-       if (dev->bus && dev->bus->suspend_late && !dev->power.power_state.event) {
-               dev_dbg(dev, "LATE %s%s\n",
-                       suspend_verb(state.event),
-                       ((state.event == PM_EVENT_SUSPEND)
-                                       && device_may_wakeup(dev))
-                               ? ", may wakeup"
-                               : ""
-                       );
+       if (dev->bus && dev->bus->suspend_late) {
+               suspend_device_dbg(dev, state, "LATE ");
                error = dev->bus->suspend_late(dev, state);
                suspend_report_result(dev->bus->suspend_late, error);
        }
@@ -153,18 +127,18 @@ int device_suspend(pm_message_t state)
        int error = 0;
 
        might_sleep();
-       down(&dpm_sem);
-       down(&dpm_list_sem);
+       mutex_lock(&dpm_mtx);
+       mutex_lock(&dpm_list_mtx);
        while (!list_empty(&dpm_active) && error == 0) {
                struct list_head * entry = dpm_active.prev;
                struct device * dev = to_device(entry);
 
                get_device(dev);
-               up(&dpm_list_sem);
+               mutex_unlock(&dpm_list_mtx);
 
                error = suspend_device(dev, state);
 
-               down(&dpm_list_sem);
+               mutex_lock(&dpm_list_mtx);
 
                /* Check if the device got removed */
                if (!list_empty(&dev->power.entry)) {
@@ -179,11 +153,11 @@ int device_suspend(pm_message_t state)
                                error == -EAGAIN ? " (please convert to suspend_late)" : "");
                put_device(dev);
        }
-       up(&dpm_list_sem);
+       mutex_unlock(&dpm_list_mtx);
        if (error)
                dpm_resume();
 
-       up(&dpm_sem);
+       mutex_unlock(&dpm_mtx);
        return error;
 }
 
index 29f1291966c17a55d8f063eeabbd715b647a1254..18febe26caa1c3640fc9d4df27e6a66775b4665f 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/string.h>
 #include <linux/pm.h>
 #include <linux/device.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
 
 #include "base.h"
 
@@ -155,7 +155,7 @@ EXPORT_SYMBOL_GPL(sysdev_class_unregister);
 
 
 static LIST_HEAD(sysdev_drivers);
-static DECLARE_MUTEX(sysdev_drivers_lock);
+static DEFINE_MUTEX(sysdev_drivers_lock);
 
 /**
  *     sysdev_driver_register - Register auxillary driver
@@ -172,7 +172,7 @@ static DECLARE_MUTEX(sysdev_drivers_lock);
 int sysdev_driver_register(struct sysdev_class * cls,
                           struct sysdev_driver * drv)
 {
-       down(&sysdev_drivers_lock);
+       mutex_lock(&sysdev_drivers_lock);
        if (cls && kset_get(&cls->kset)) {
                list_add_tail(&drv->entry, &cls->drivers);
 
@@ -184,7 +184,7 @@ int sysdev_driver_register(struct sysdev_class * cls,
                }
        } else
                list_add_tail(&drv->entry, &sysdev_drivers);
-       up(&sysdev_drivers_lock);
+       mutex_unlock(&sysdev_drivers_lock);
        return 0;
 }
 
@@ -197,7 +197,7 @@ int sysdev_driver_register(struct sysdev_class * cls,
 void sysdev_driver_unregister(struct sysdev_class * cls,
                              struct sysdev_driver * drv)
 {
-       down(&sysdev_drivers_lock);
+       mutex_lock(&sysdev_drivers_lock);
        list_del_init(&drv->entry);
        if (cls) {
                if (drv->remove) {
@@ -207,7 +207,7 @@ void sysdev_driver_unregister(struct sysdev_class * cls,
                }
                kset_put(&cls->kset);
        }
-       up(&sysdev_drivers_lock);
+       mutex_unlock(&sysdev_drivers_lock);
 }
 
 EXPORT_SYMBOL_GPL(sysdev_driver_register);
@@ -246,7 +246,7 @@ int sysdev_register(struct sys_device * sysdev)
        if (!error) {
                struct sysdev_driver * drv;
 
-               down(&sysdev_drivers_lock);
+               mutex_lock(&sysdev_drivers_lock);
                /* Generic notification is implicit, because it's that
                 * code that should have called us.
                 */
@@ -262,7 +262,7 @@ int sysdev_register(struct sys_device * sysdev)
                        if (drv->add)
                                drv->add(sysdev);
                }
-               up(&sysdev_drivers_lock);
+               mutex_unlock(&sysdev_drivers_lock);
        }
        return error;
 }
@@ -271,7 +271,7 @@ void sysdev_unregister(struct sys_device * sysdev)
 {
        struct sysdev_driver * drv;
 
-       down(&sysdev_drivers_lock);
+       mutex_lock(&sysdev_drivers_lock);
        list_for_each_entry(drv, &sysdev_drivers, entry) {
                if (drv->remove)
                        drv->remove(sysdev);
@@ -281,7 +281,7 @@ void sysdev_unregister(struct sys_device * sysdev)
                if (drv->remove)
                        drv->remove(sysdev);
        }
-       up(&sysdev_drivers_lock);
+       mutex_unlock(&sysdev_drivers_lock);
 
        kobject_unregister(&sysdev->kobj);
 }
@@ -308,7 +308,7 @@ void sysdev_shutdown(void)
 
        pr_debug("Shutting Down System Devices\n");
 
-       down(&sysdev_drivers_lock);
+       mutex_lock(&sysdev_drivers_lock);
        list_for_each_entry_reverse(cls, &system_subsys.list,
                                    kset.kobj.entry) {
                struct sys_device * sysdev;
@@ -337,7 +337,7 @@ void sysdev_shutdown(void)
                                cls->shutdown(sysdev);
                }
        }
-       up(&sysdev_drivers_lock);
+       mutex_unlock(&sysdev_drivers_lock);
 }
 
 static void __sysdev_resume(struct sys_device *dev)
index b4c8319138b29fbd762941ae74b4cbcc7d441cd3..6e23af1ecbdb3fca4600bf3fafecce4126ba7f3a 100644 (file)
@@ -2,9 +2,12 @@
 # Block device driver configuration
 #
 
-if BLOCK
+menuconfig BLK_DEV
+       bool "Block devices"
+       depends on BLOCK
+       default y
 
-menu "Block devices"
+if BLK_DEV
 
 config BLK_DEV_FD
        tristate "Normal floppy disk support"
@@ -56,40 +59,9 @@ config AMIGA_Z2RAM
          To compile this driver as a module, choose M here: the
          module will be called z2ram.
 
-config ATARI_ACSI
-       tristate "Atari ACSI support"
-       depends on ATARI && BROKEN
-       ---help---
-         This enables support for the Atari ACSI interface. The driver
-         supports hard disks and CD-ROMs, which have 512-byte sectors, or can
-         be switched to that mode. Due to the ACSI command format, only disks
-         up to 1 GB are supported. Special support for certain ACSI to SCSI
-         adapters, which could relax that, isn't included yet. The ACSI
-         driver is also the basis for certain other drivers for devices
-         attached to the ACSI bus: Atari SLM laser printer, BioNet-100
-         Ethernet, and PAMsNet Ethernet. If you want to use one of these
-         devices, you need ACSI support, too.
-
-         To compile this driver as a module, choose M here: the
-         module will be called acsi.
-
-comment "Some devices (e.g. CD jukebox) support multiple LUNs"
-       depends on ATARI && ATARI_ACSI
-
-config ACSI_MULTI_LUN
-       bool "Probe all LUNs on each ACSI device"
-       depends on ATARI_ACSI
-       help
-         If you have a ACSI device that supports more than one LUN (Logical
-         Unit Number), e.g. a CD jukebox, you should say Y here so that all
-         will be found by the ACSI driver. An ACSI device with multiple LUNs
-         acts logically like multiple ACSI devices. The vast majority of ACSI
-         devices have only one LUN, and so most people can say N here and
-         should in fact do so, because it is safer.
-
 config ATARI_SLM
        tristate "Atari SLM laser printer support"
-       depends on ATARI && ATARI_ACSI!=n
+       depends on ATARI
        help
          If you have an Atari SLM laser printer, say Y to include support for
          it in the kernel. Otherwise, say N. This driver is also available as
@@ -453,6 +425,4 @@ config ATA_OVER_ETH
 
 source "drivers/s390/block/Kconfig"
 
-endmenu
-
-endif
+endif # BLK_DEV
index dd88e33c1eb108ccd6d56a24dcb75eea8bca41f7..e5f98acc5d523ec622724bae6da15ac3be37912f 100644 (file)
@@ -9,7 +9,6 @@ obj-$(CONFIG_MAC_FLOPPY)        += swim3.o
 obj-$(CONFIG_BLK_DEV_FD)       += floppy.o
 obj-$(CONFIG_AMIGA_FLOPPY)     += amiflop.o
 obj-$(CONFIG_ATARI_FLOPPY)     += ataflop.o
-obj-$(CONFIG_ATARI_ACSI)       += acsi.o
 obj-$(CONFIG_ATARI_SLM)                += acsi_slm.o
 obj-$(CONFIG_AMIGA_Z2RAM)      += z2ram.o
 obj-$(CONFIG_BLK_DEV_RAM)      += rd.o
diff --git a/drivers/block/acsi.c b/drivers/block/acsi.c
deleted file mode 100644 (file)
index e3d9152..0000000
+++ /dev/null
@@ -1,1825 +0,0 @@
-/*
- * acsi.c -- Device driver for Atari ACSI hard disks
- *
- * Copyright 1994 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
- *
- * Some parts are based on hd.c by Linus Torvalds
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file COPYING in the main directory of this archive for
- * more details.
- *
- */
-
-/*
- * Still to in this file:
- *  - If a command ends with an error status (!= 0), the following
- *    REQUEST SENSE commands (4 to fill the ST-DMA FIFO) are done by
- *    polling the _IRQ signal (not interrupt-driven). This should be
- *    avoided in future because it takes up a non-neglectible time in
- *    the interrupt service routine while interrupts are disabled.
- *    Maybe a timer interrupt will get lost :-(
- */
-
-/*
- * General notes:
- *
- *  - All ACSI devices (disks, CD-ROMs, ...) use major number 28.
- *    Minors are organized like it is with SCSI: The upper 4 bits
- *    identify the device, the lower 4 bits the partition.
- *    The device numbers (the upper 4 bits) are given in the same
- *    order as the devices are found on the bus.
- *  - Up to 8 LUNs are supported for each target (if CONFIG_ACSI_MULTI_LUN
- *    is defined), but only a total of 16 devices (due to minor
- *    numbers...). Note that Atari allows only a maximum of 4 targets
- *    (i.e. controllers, not devices) on the ACSI bus!
- *  - A optimizing scheme similar to SCSI scatter-gather is implemented.
- *  - Removable media are supported. After a medium change to device
- *    is reinitialized (partition check etc.). Also, if the device
- *    knows the PREVENT/ALLOW MEDIUM REMOVAL command, the door should
- *    be locked and unlocked when mounting the first or unmounting the
- *    last filesystem on the device. The code is untested, because I
- *    don't have a removable hard disk.
- *
- */
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/timer.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/genhd.h>
-#include <linux/delay.h>
-#include <linux/mm.h>
-#include <linux/major.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <scsi/scsi.h> /* for SCSI_IOCTL_GET_IDLUN */
-#include <scsi/scsi_ioctl.h>
-#include <linux/hdreg.h> /* for HDIO_GETGEO */
-#include <linux/blkpg.h>
-#include <linux/buffer_head.h>
-#include <linux/blkdev.h>
-
-#include <asm/setup.h>
-#include <asm/pgtable.h>
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#include <asm/atarihw.h>
-#include <asm/atariints.h>
-#include <asm/atari_acsi.h>
-#include <asm/atari_stdma.h>
-#include <asm/atari_stram.h>
-
-static void (*do_acsi)(void) = NULL;
-static struct request_queue *acsi_queue;
-#define QUEUE (acsi_queue)
-#define CURRENT elv_next_request(acsi_queue)
-
-#define DEBUG
-#undef DEBUG_DETECT
-#undef NO_WRITE
-
-#define MAX_ERRORS                     8       /* Max read/write errors/sector */
-#define MAX_LUN                                8       /* Max LUNs per target */
-#define MAX_DEV                                16
-
-#define ACSI_BUFFER_SIZE                       (16*1024) /* "normal" ACSI buffer size */
-#define ACSI_BUFFER_MINSIZE                    (2048)    /* min. buf size if ext. DMA */
-#define ACSI_BUFFER_SIZE_ORDER         2                 /* order size for above */
-#define ACSI_BUFFER_MINSIZE_ORDER      0                 /* order size for above */
-#define ACSI_BUFFER_SECTORS    (ACSI_BUFFER_SIZE/512)
-
-#define ACSI_BUFFER_ORDER \
-       (ATARIHW_PRESENT(EXTD_DMA) ? \
-        ACSI_BUFFER_MINSIZE_ORDER : \
-        ACSI_BUFFER_SIZE_ORDER)
-
-#define ACSI_TIMEOUT           (4*HZ)
-
-/* minimum delay between two commands */
-
-#define COMMAND_DELAY 500
-
-typedef enum {
-       NONE, HARDDISK, CDROM
-} ACSI_TYPE;
-
-struct acsi_info_struct {
-       ACSI_TYPE               type;                   /* type of device */
-       unsigned                target;                 /* target number */
-       unsigned                lun;                    /* LUN in target controller */
-       unsigned                removable : 1;  /* Flag for removable media */
-       unsigned                read_only : 1;  /* Flag for read only devices */
-       unsigned                old_atari_disk : 1; /* Is an old Atari disk       */
-       unsigned                changed : 1;    /* Medium has been changed */
-       unsigned long   size;                   /* #blocks */
-       int access_count;
-} acsi_info[MAX_DEV];
-
-/*
- *     SENSE KEYS
- */
-
-#define NO_SENSE               0x00
-#define RECOVERED_ERROR        0x01
-#define NOT_READY              0x02
-#define MEDIUM_ERROR           0x03
-#define HARDWARE_ERROR         0x04
-#define ILLEGAL_REQUEST        0x05
-#define UNIT_ATTENTION         0x06
-#define DATA_PROTECT           0x07
-#define BLANK_CHECK            0x08
-#define COPY_ABORTED           0x0a
-#define ABORTED_COMMAND        0x0b
-#define VOLUME_OVERFLOW        0x0d
-#define MISCOMPARE             0x0e
-
-
-/*
- *     DEVICE TYPES
- */
-
-#define TYPE_DISK      0x00
-#define TYPE_TAPE      0x01
-#define TYPE_WORM      0x04
-#define TYPE_ROM       0x05
-#define TYPE_MOD       0x07
-#define TYPE_NO_LUN    0x7f
-
-/* The data returned by MODE SENSE differ between the old Atari
- * hard disks and SCSI disks connected to ACSI. In the following, both
- * formats are defined and some macros to operate on them potably.
- */
-
-typedef struct {
-       unsigned long   dummy[2];
-       unsigned long   sector_size;
-       unsigned char   format_code;
-#define ATARI_SENSE_FORMAT_FIX 1       
-#define ATARI_SENSE_FORMAT_CHNG        2
-       unsigned char   cylinders_h;
-       unsigned char   cylinders_l;
-       unsigned char   heads;
-       unsigned char   reduced_h;
-       unsigned char   reduced_l;
-       unsigned char   precomp_h;
-       unsigned char   precomp_l;
-       unsigned char   landing_zone;
-       unsigned char   steprate;
-       unsigned char   type;
-#define ATARI_SENSE_TYPE_FIXCHNG_MASK          4
-#define ATARI_SENSE_TYPE_SOFTHARD_MASK         8
-#define ATARI_SENSE_TYPE_FIX                           4
-#define ATARI_SENSE_TYPE_CHNG                          0
-#define ATARI_SENSE_TYPE_SOFT                          0
-#define ATARI_SENSE_TYPE_HARD                          8
-       unsigned char   sectors;
-} ATARI_SENSE_DATA;
-
-#define ATARI_CAPACITY(sd) \
-       (((int)((sd).cylinders_h<<8)|(sd).cylinders_l) * \
-        (sd).heads * (sd).sectors)
-
-
-typedef struct {
-       unsigned char   dummy1;
-       unsigned char   medium_type;
-       unsigned char   dummy2;
-       unsigned char   descriptor_size;
-       unsigned long   block_count;
-       unsigned long   sector_size;
-       /* Page 0 data */
-       unsigned char   page_code;
-       unsigned char   page_size;
-       unsigned char   page_flags;
-       unsigned char   qualifier;
-} SCSI_SENSE_DATA;
-
-#define SCSI_CAPACITY(sd)      ((sd).block_count & 0xffffff)
-
-
-typedef union {
-       ATARI_SENSE_DATA        atari;
-       SCSI_SENSE_DATA         scsi;
-} SENSE_DATA;
-
-#define SENSE_TYPE_UNKNOWN     0
-#define SENSE_TYPE_ATARI       1
-#define SENSE_TYPE_SCSI                2
-
-#define SENSE_TYPE(sd)                                                                         \
-       (((sd).atari.dummy[0] == 8 &&                                                   \
-         ((sd).atari.format_code == 1 ||                                               \
-          (sd).atari.format_code == 2)) ? SENSE_TYPE_ATARI :   \
-        ((sd).scsi.dummy1 >= 11) ? SENSE_TYPE_SCSI :                   \
-        SENSE_TYPE_UNKNOWN)
-        
-#define CAPACITY(sd)                                                   \
-       (SENSE_TYPE(sd) == SENSE_TYPE_ATARI ?           \
-        ATARI_CAPACITY((sd).atari) :                           \
-        SCSI_CAPACITY((sd).scsi))
-
-#define SECTOR_SIZE(sd)                                                        \
-       (SENSE_TYPE(sd) == SENSE_TYPE_ATARI ?           \
-        (sd).atari.sector_size :                                       \
-        (sd).scsi.sector_size & 0xffffff)
-
-/* Default size if capacity cannot be determined (1 GByte) */
-#define        DEFAULT_SIZE    0x1fffff
-
-#define CARTRCH_STAT(aip,buf)                                          \
-       (aip->old_atari_disk ?                                          \
-        (((buf)[0] & 0x7f) == 0x28) :                                  \
-        ((((buf)[0] & 0x70) == 0x70) ?                                 \
-         (((buf)[2] & 0x0f) == 0x06) :                                 \
-         (((buf)[0] & 0x0f) == 0x06)))                                 \
-
-/* These two are also exported to other drivers that work on the ACSI bus and
- * need an ST-RAM buffer. */
-char                   *acsi_buffer;
-unsigned long  phys_acsi_buffer;
-
-static int NDevices;
-
-static int                             CurrentNReq;
-static int                             CurrentNSect;
-static char                            *CurrentBuffer;
-
-static DEFINE_SPINLOCK(acsi_lock);
-
-
-#define SET_TIMER()    mod_timer(&acsi_timer, jiffies + ACSI_TIMEOUT)
-#define CLEAR_TIMER()  del_timer(&acsi_timer)
-
-static unsigned long   STramMask;
-#define STRAM_ADDR(a)  (((a) & STramMask) == 0)
-
-
-
-/* ACSI commands */
-
-static char tur_cmd[6]        = { 0x00, 0, 0, 0, 0, 0 };
-static char modesense_cmd[6]  = { 0x1a, 0, 0, 0, 24, 0 };
-static char modeselect_cmd[6] = { 0x15, 0, 0, 0, 12, 0 };
-static char inquiry_cmd[6]    = { 0x12, 0, 0, 0,255, 0 };
-static char reqsense_cmd[6]   = { 0x03, 0, 0, 0, 4, 0 };
-static char read_cmd[6]       = { 0x08, 0, 0, 0, 0, 0 };
-static char write_cmd[6]      = { 0x0a, 0, 0, 0, 0, 0 };
-static char pa_med_rem_cmd[6] = { 0x1e, 0, 0, 0, 0, 0 };
-
-#define CMDSET_TARG_LUN(cmd,targ,lun)                  \
-    do {                                               \
-               cmd[0] = (cmd[0] & ~0xe0) | (targ)<<5;  \
-               cmd[1] = (cmd[1] & ~0xe0) | (lun)<<5;   \
-       } while(0)
-
-#define CMDSET_BLOCK(cmd,blk)                                          \
-    do {                                                                                       \
-               unsigned long __blk = (blk);                            \
-               cmd[3] = __blk; __blk >>= 8;                            \
-               cmd[2] = __blk; __blk >>= 8;                            \
-               cmd[1] = (cmd[1] & 0xe0) | (__blk & 0x1f);      \
-       } while(0)
-
-#define CMDSET_LEN(cmd,len)                                            \
-       do {                                                                            \
-               cmd[4] = (len);                                                 \
-       } while(0)
-
-/* ACSI errors (from REQUEST SENSE); There are two tables, one for the
- * old Atari disks and one for SCSI on ACSI disks.
- */
-
-struct acsi_error {
-       unsigned char   code;
-       const char              *text;
-} atari_acsi_errors[] = {
-       { 0x00, "No error (??)" },
-       { 0x01, "No index pulses" },
-       { 0x02, "Seek not complete" },
-       { 0x03, "Write fault" },
-       { 0x04, "Drive not ready" },
-       { 0x06, "No Track 00 signal" },
-       { 0x10, "ECC error in ID field" },
-       { 0x11, "Uncorrectable data error" },
-       { 0x12, "ID field address mark not found" },
-       { 0x13, "Data field address mark not found" },
-       { 0x14, "Record not found" },
-       { 0x15, "Seek error" },
-       { 0x18, "Data check in no retry mode" },
-       { 0x19, "ECC error during verify" },
-       { 0x1a, "Access to bad block" },
-       { 0x1c, "Unformatted or bad format" },
-       { 0x20, "Invalid command" },
-       { 0x21, "Invalid block address" },
-       { 0x23, "Volume overflow" },
-       { 0x24, "Invalid argument" },
-       { 0x25, "Invalid drive number" },
-       { 0x26, "Byte zero parity check" },
-       { 0x28, "Cartride changed" },
-       { 0x2c, "Error count overflow" },
-       { 0x30, "Controller selftest failed" }
-},
-
-       scsi_acsi_errors[] = {
-       { 0x00, "No error (??)" },
-       { 0x01, "Recovered error" },
-       { 0x02, "Drive not ready" },
-       { 0x03, "Uncorrectable medium error" },
-       { 0x04, "Hardware error" },
-       { 0x05, "Illegal request" },
-       { 0x06, "Unit attention (Reset or cartridge changed)" },
-       { 0x07, "Data protection" },
-       { 0x08, "Blank check" },
-       { 0x0b, "Aborted Command" },
-       { 0x0d, "Volume overflow" }
-};
-
-
-
-/***************************** Prototypes *****************************/
-
-static int acsicmd_dma( const char *cmd, char *buffer, int blocks, int
-                        rwflag, int enable);
-static int acsi_reqsense( char *buffer, int targ, int lun);
-static void acsi_print_error(const unsigned char *errblk, struct acsi_info_struct *aip);
-static irqreturn_t acsi_interrupt (int irq, void *data);
-static void unexpected_acsi_interrupt( void );
-static void bad_rw_intr( void );
-static void read_intr( void );
-static void write_intr( void);
-static void acsi_times_out( unsigned long dummy );
-static void copy_to_acsibuffer( void );
-static void copy_from_acsibuffer( void );
-static void do_end_requests( void );
-static void do_acsi_request( request_queue_t * );
-static void redo_acsi_request( void );
-static int acsi_ioctl( struct inode *inode, struct file *file, unsigned int
-                       cmd, unsigned long arg );
-static int acsi_open( struct inode * inode, struct file * filp );
-static int acsi_release( struct inode * inode, struct file * file );
-static void acsi_prevent_removal(struct acsi_info_struct *aip, int flag );
-static int acsi_change_blk_size( int target, int lun);
-static int acsi_mode_sense( int target, int lun, SENSE_DATA *sd );
-static int acsi_revalidate (struct gendisk *disk);
-
-/************************* End of Prototypes **************************/
-
-
-DEFINE_TIMER(acsi_timer, acsi_times_out, 0, 0);
-
-
-#ifdef CONFIG_ATARI_SLM
-
-extern int attach_slm( int target, int lun );
-extern int slm_init( void );
-
-#endif
-
-
-\f
-/***********************************************************************
- *
- *   ACSI primitives
- *
- **********************************************************************/
-
-
-/*
- * The following two functions wait for _IRQ to become Low or High,
- * resp., with a timeout. The 'timeout' parameter is in jiffies
- * (10ms).
- * If the functions are called with timer interrupts on (int level <
- * 6), the timeout is based on the 'jiffies' variable to provide exact
- * timeouts for device probing etc.
- * If interrupts are disabled, the number of tries is based on the
- * 'loops_per_jiffy' variable. A rough estimation is sufficient here...
- */
-
-#define INT_LEVEL                                                                                                      \
-       ({      unsigned __sr;                                                                                          \
-               __asm__ __volatile__ ( "movew   %/sr,%0" : "=dm" (__sr) );      \
-               (__sr >> 8) & 7;                                                                                        \
-       })
-
-int acsi_wait_for_IRQ( unsigned timeout )
-
-{
-       if (INT_LEVEL < 6) {
-               unsigned long maxjif = jiffies + timeout;
-               while (time_before(jiffies, maxjif))
-                       if (!(mfp.par_dt_reg & 0x20)) return( 1 );
-       }
-       else {
-               long tries = loops_per_jiffy / 8 * timeout;
-               while( --tries >= 0 )
-                       if (!(mfp.par_dt_reg & 0x20)) return( 1 );
-       }               
-       return( 0 ); /* timeout! */
-}
-
-
-int acsi_wait_for_noIRQ( unsigned timeout )
-
-{
-       if (INT_LEVEL < 6) {
-               unsigned long maxjif = jiffies + timeout;
-               while (time_before(jiffies, maxjif))
-                       if (mfp.par_dt_reg & 0x20) return( 1 );
-       }
-       else {
-               long tries = loops_per_jiffy * timeout / 8;
-               while( tries-- >= 0 )
-                       if (mfp.par_dt_reg & 0x20) return( 1 );
-       }               
-       return( 0 ); /* timeout! */
-}
-
-static struct timeval start_time;
-
-void
-acsi_delay_start(void)
-{
-       do_gettimeofday(&start_time);
-}
-
-/* wait from acsi_delay_start to now usec (<1E6) usec */
-
-void
-acsi_delay_end(long usec)
-{
-       struct timeval end_time;
-       long deltau,deltas;
-       do_gettimeofday(&end_time);
-       deltau=end_time.tv_usec - start_time.tv_usec;
-       deltas=end_time.tv_sec - start_time.tv_sec;
-       if (deltas > 1 || deltas < 0)
-               return;
-       if (deltas > 0)
-               deltau += 1000*1000;
-       if (deltau >= usec)
-               return;
-       udelay(usec-deltau);
-}
-
-/* acsicmd_dma() sends an ACSI command and sets up the DMA to transfer
- * 'blocks' blocks of 512 bytes from/to 'buffer'.
- * Because the _IRQ signal is used for handshaking the command bytes,
- * the ACSI interrupt has to be disabled in this function. If the end
- * of the operation should be signalled by a real interrupt, it has to be
- * reenabled afterwards.
- */
-
-static int acsicmd_dma( const char *cmd, char *buffer, int blocks, int rwflag, int enable)
-
-{      unsigned long   flags, paddr;
-       int                             i;
-
-#ifdef NO_WRITE
-       if (rwflag || *cmd == 0x0a) {
-               printk( "ACSI: Write commands disabled!\n" );
-               return( 0 );
-       }
-#endif
-       
-       rwflag = rwflag ? 0x100 : 0;
-       paddr = virt_to_phys( buffer );
-
-       acsi_delay_end(COMMAND_DELAY);
-       DISABLE_IRQ();
-
-       local_irq_save(flags);
-       /* Low on A1 */
-       dma_wd.dma_mode_status = 0x88 | rwflag;
-       MFPDELAY();
-
-       /* set DMA address */
-       dma_wd.dma_lo = (unsigned char)paddr;
-       paddr >>= 8;
-       MFPDELAY();
-       dma_wd.dma_md = (unsigned char)paddr;
-       paddr >>= 8;
-       MFPDELAY();
-       if (ATARIHW_PRESENT(EXTD_DMA))
-               st_dma_ext_dmahi = (unsigned short)paddr;
-       else
-               dma_wd.dma_hi = (unsigned char)paddr;
-       MFPDELAY();
-       local_irq_restore(flags);
-
-       /* send the command bytes except the last */
-       for( i = 0; i < 5; ++i ) {
-               DMA_LONG_WRITE( *cmd++, 0x8a | rwflag );
-               udelay(20);
-               if (!acsi_wait_for_IRQ( HZ/2 )) return( 0 ); /* timeout */
-       }
-
-       /* Clear FIFO and switch DMA to correct direction */  
-       dma_wd.dma_mode_status = 0x92 | (rwflag ^ 0x100);  
-       MFPDELAY();
-       dma_wd.dma_mode_status = 0x92 | rwflag;
-       MFPDELAY();
-
-       /* How many sectors for DMA */
-       dma_wd.fdc_acces_seccount = blocks;
-       MFPDELAY();
-       
-       /* send last command byte */
-       dma_wd.dma_mode_status = 0x8a | rwflag;
-       MFPDELAY();
-       DMA_LONG_WRITE( *cmd++, 0x0a | rwflag );
-       if (enable)
-               ENABLE_IRQ();
-       udelay(80);
-
-       return( 1 );
-}
-
-
-/*
- * acsicmd_nodma() sends an ACSI command that requires no DMA.
- */
-
-int acsicmd_nodma( const char *cmd, int enable)
-
-{      int     i;
-
-       acsi_delay_end(COMMAND_DELAY);
-       DISABLE_IRQ();
-
-       /* send first command byte */
-       dma_wd.dma_mode_status = 0x88;
-       MFPDELAY();
-       DMA_LONG_WRITE( *cmd++, 0x8a );
-       udelay(20);
-       if (!acsi_wait_for_IRQ( HZ/2 )) return( 0 ); /* timeout */
-
-       /* send the intermediate command bytes */
-       for( i = 0; i < 4; ++i ) {
-               DMA_LONG_WRITE( *cmd++, 0x8a );
-               udelay(20);
-               if (!acsi_wait_for_IRQ( HZ/2 )) return( 0 ); /* timeout */
-       }
-
-       /* send last command byte */
-       DMA_LONG_WRITE( *cmd++, 0x0a );
-       if (enable)
-               ENABLE_IRQ();
-       udelay(80);
-       
-       return( 1 );
-       /* Note that the ACSI interrupt is still disabled after this
-        * function. If you want to get the IRQ delivered, enable it manually!
-        */
-}
-
-
-static int acsi_reqsense( char *buffer, int targ, int lun)
-
-{
-       CMDSET_TARG_LUN( reqsense_cmd, targ, lun);
-       if (!acsicmd_dma( reqsense_cmd, buffer, 1, 0, 0 )) return( 0 );
-       if (!acsi_wait_for_IRQ( 10 )) return( 0 );
-       acsi_getstatus();
-       if (!acsicmd_nodma( reqsense_cmd, 0 )) return( 0 );
-       if (!acsi_wait_for_IRQ( 10 )) return( 0 );
-       acsi_getstatus();
-       if (!acsicmd_nodma( reqsense_cmd, 0 )) return( 0 );
-       if (!acsi_wait_for_IRQ( 10 )) return( 0 );
-       acsi_getstatus();
-       if (!acsicmd_nodma( reqsense_cmd, 0 )) return( 0 );
-       if (!acsi_wait_for_IRQ( 10 )) return( 0 );
-       acsi_getstatus();
-       dma_cache_maintenance( virt_to_phys(buffer), 16, 0 );
-       
-       return( 1 );
-}      
-
-
-/*
- * ACSI status phase: get the status byte from the bus
- *
- * I've seen several times that a 0xff status is read, propably due to
- * a timing error. In this case, the procedure is repeated after the
- * next _IRQ edge.
- */
-
-int acsi_getstatus( void )
-
-{      int     status;
-
-       DISABLE_IRQ();
-       for(;;) {
-               if (!acsi_wait_for_IRQ( 100 )) {
-                       acsi_delay_start();
-                       return( -1 );
-               }
-               dma_wd.dma_mode_status = 0x8a;
-               MFPDELAY();
-               status = dma_wd.fdc_acces_seccount;
-               if (status != 0xff) break;
-#ifdef DEBUG
-               printk("ACSI: skipping 0xff status byte\n" );
-#endif
-               udelay(40);
-               acsi_wait_for_noIRQ( 20 );
-       }
-       dma_wd.dma_mode_status = 0x80;
-       udelay(40);
-       acsi_wait_for_noIRQ( 20 );
-
-       acsi_delay_start();
-       return( status & 0x1f ); /* mask of the device# */
-}
-
-
-#if (defined(CONFIG_ATARI_SLM) || defined(CONFIG_ATARI_SLM_MODULE))
-
-/* Receive data in an extended status phase. Needed by SLM printer. */
-
-int acsi_extstatus( char *buffer, int cnt )
-
-{      int     status;
-
-       DISABLE_IRQ();
-       udelay(80);
-       while( cnt-- > 0 ) {
-               if (!acsi_wait_for_IRQ( 40 )) return( 0 );
-               dma_wd.dma_mode_status = 0x8a;
-               MFPDELAY();
-               status = dma_wd.fdc_acces_seccount;
-               MFPDELAY();
-               *buffer++ = status & 0xff;
-               udelay(40);
-       }
-       return( 1 );
-}
-
-
-/* Finish an extended status phase */
-
-void acsi_end_extstatus( void )
-
-{
-       dma_wd.dma_mode_status = 0x80;
-       udelay(40);
-       acsi_wait_for_noIRQ( 20 );
-       acsi_delay_start();
-}
-
-
-/* Send data in an extended command phase */
-
-int acsi_extcmd( unsigned char *buffer, int cnt )
-
-{
-       while( cnt-- > 0 ) {
-               DMA_LONG_WRITE( *buffer++, 0x8a );
-               udelay(20);
-               if (!acsi_wait_for_IRQ( HZ/2 )) return( 0 ); /* timeout */
-       }
-       return( 1 );
-}
-
-#endif
-
-
-static void acsi_print_error(const unsigned char *errblk, struct acsi_info_struct *aip)
-
-{      int atari_err, i, errcode;
-       struct acsi_error *arr;
-
-       atari_err = aip->old_atari_disk;
-       if (atari_err)
-               errcode = errblk[0] & 0x7f;
-       else
-               if ((errblk[0] & 0x70) == 0x70)
-                       errcode = errblk[2] & 0x0f;
-               else
-                       errcode = errblk[0] & 0x0f;
-       
-       printk( KERN_ERR "ACSI error 0x%02x", errcode );
-
-       if (errblk[0] & 0x80)
-               printk( " for sector %d",
-                               ((errblk[1] & 0x1f) << 16) |
-                               (errblk[2] << 8) | errblk[0] );
-
-       arr = atari_err ? atari_acsi_errors : scsi_acsi_errors;
-       i = atari_err ? sizeof(atari_acsi_errors)/sizeof(*atari_acsi_errors) :
-                           sizeof(scsi_acsi_errors)/sizeof(*scsi_acsi_errors);
-       
-       for( --i; i >= 0; --i )
-               if (arr[i].code == errcode) break;
-       if (i >= 0)
-               printk( ": %s\n", arr[i].text );
-}
-
-/*******************************************************************
- *
- * ACSI interrupt routine
- *   Test, if this is a ACSI interrupt and call the irq handler
- *   Otherwise ignore this interrupt.
- *
- *******************************************************************/
-
-static irqreturn_t acsi_interrupt(int irq, void *data )
-
-{      void (*acsi_irq_handler)(void) = do_acsi;
-
-       do_acsi = NULL;
-       CLEAR_TIMER();
-
-       if (!acsi_irq_handler)
-               acsi_irq_handler = unexpected_acsi_interrupt;
-       acsi_irq_handler();
-       return IRQ_HANDLED;
-}
-
-
-/******************************************************************
- *
- * The Interrupt handlers
- *
- *******************************************************************/
-
-
-static void unexpected_acsi_interrupt( void )
-
-{
-       printk( KERN_WARNING "Unexpected ACSI interrupt\n" );
-}
-
-
-/* This function is called in case of errors. Because we cannot reset
- * the ACSI bus or a single device, there is no other choice than
- * retrying several times :-(
- */
-
-static void bad_rw_intr( void )
-
-{
-       if (!CURRENT)
-               return;
-
-       if (++CURRENT->errors >= MAX_ERRORS)
-               end_request(CURRENT, 0);
-       /* Otherwise just retry */
-}
-
-
-static void read_intr( void )
-
-{      int             status;
-       
-       status = acsi_getstatus();
-       if (status != 0) {
-               struct gendisk *disk = CURRENT->rq_disk;
-               struct acsi_info_struct *aip = disk->private_data;
-               printk(KERN_ERR "%s: ", disk->disk_name);
-               if (!acsi_reqsense(acsi_buffer, aip->target, aip->lun))
-                       printk( "ACSI error and REQUEST SENSE failed (status=0x%02x)\n", status );
-               else {
-                       acsi_print_error(acsi_buffer, aip);
-                       if (CARTRCH_STAT(aip, acsi_buffer))
-                               aip->changed = 1;
-               }
-               ENABLE_IRQ();
-               bad_rw_intr();
-               redo_acsi_request();
-               return;
-       }
-
-       dma_cache_maintenance( virt_to_phys(CurrentBuffer), CurrentNSect*512, 0 );
-       if (CurrentBuffer == acsi_buffer)
-               copy_from_acsibuffer();
-
-       do_end_requests();
-       redo_acsi_request();
-}
-
-
-static void write_intr(void)
-
-{      int     status;
-
-       status = acsi_getstatus();
-       if (status != 0) {
-               struct gendisk *disk = CURRENT->rq_disk;
-               struct acsi_info_struct *aip = disk->private_data;
-               printk( KERN_ERR "%s: ", disk->disk_name);
-               if (!acsi_reqsense( acsi_buffer, aip->target, aip->lun))
-                       printk( "ACSI error and REQUEST SENSE failed (status=0x%02x)\n", status );
-               else {
-                       acsi_print_error(acsi_buffer, aip);
-                       if (CARTRCH_STAT(aip, acsi_buffer))
-                               aip->changed = 1;
-               }
-               bad_rw_intr();
-               redo_acsi_request();
-               return;
-       }
-
-       do_end_requests();
-       redo_acsi_request();
-}
-
-
-static void acsi_times_out( unsigned long dummy )
-
-{
-       DISABLE_IRQ();
-       if (!do_acsi) return;
-
-       do_acsi = NULL;
-       printk( KERN_ERR "ACSI timeout\n" );
-       if (!CURRENT)
-           return;
-       if (++CURRENT->errors >= MAX_ERRORS) {
-#ifdef DEBUG
-               printk( KERN_ERR "ACSI: too many errors.\n" );
-#endif
-               end_request(CURRENT, 0);
-       }
-
-       redo_acsi_request();
-}
-
-
-\f
-/***********************************************************************
- *
- *  Scatter-gather utility functions
- *
- ***********************************************************************/
-
-
-static void copy_to_acsibuffer( void )
-
-{      int                                     i;
-       char                            *src, *dst;
-       struct buffer_head      *bh;
-       
-       src = CURRENT->buffer;
-       dst = acsi_buffer;
-       bh = CURRENT->bh;
-
-       if (!bh)
-               memcpy( dst, src, CurrentNSect*512 );
-       else
-               for( i = 0; i < CurrentNReq; ++i ) {
-                       memcpy( dst, src, bh->b_size );
-                       dst += bh->b_size;
-                       if ((bh = bh->b_reqnext))
-                               src = bh->b_data;
-               }
-}
-
-
-static void copy_from_acsibuffer( void )
-
-{      int                                     i;
-       char                            *src, *dst;
-       struct buffer_head      *bh;
-       
-       dst = CURRENT->buffer;
-       src = acsi_buffer;
-       bh = CURRENT->bh;
-
-       if (!bh)
-               memcpy( dst, src, CurrentNSect*512 );
-       else
-               for( i = 0; i < CurrentNReq; ++i ) {
-                       memcpy( dst, src, bh->b_size );
-                       src += bh->b_size;
-                       if ((bh = bh->b_reqnext))
-                               dst = bh->b_data;
-               }
-}
-
-
-static void do_end_requests( void )
-
-{      int             i, n;
-
-       if (!CURRENT->bh) {
-               CURRENT->nr_sectors -= CurrentNSect;
-               CURRENT->current_nr_sectors -= CurrentNSect;
-               CURRENT->sector += CurrentNSect;
-               if (CURRENT->nr_sectors == 0)
-                       end_request(CURRENT, 1);
-       }
-       else {
-               for( i = 0; i < CurrentNReq; ++i ) {
-                       n = CURRENT->bh->b_size >> 9;
-                       CURRENT->nr_sectors -= n;
-                       CURRENT->current_nr_sectors -= n;
-                       CURRENT->sector += n;
-                       end_request(CURRENT, 1);
-               }
-       }
-}
-
-
-
-\f
-/***********************************************************************
- *
- *  do_acsi_request and friends
- *
- ***********************************************************************/
-
-static void do_acsi_request( request_queue_t * q )
-
-{
-       stdma_lock( acsi_interrupt, NULL );
-       redo_acsi_request();
-}
-
-
-static void redo_acsi_request( void )
-{
-       unsigned                        block, target, lun, nsect;
-       char                            *buffer;
-       unsigned long           pbuffer;
-       struct buffer_head      *bh;
-       struct gendisk *disk;
-       struct acsi_info_struct *aip;
-
-  repeat:
-       CLEAR_TIMER();
-
-       if (do_acsi)
-               return;
-
-       if (!CURRENT) {
-               do_acsi = NULL;
-               ENABLE_IRQ();
-               stdma_release();
-               return;
-       }
-
-       disk = CURRENT->rq_disk;
-       aip = disk->private_data;
-       if (CURRENT->bh) {
-               if (!CURRENT->bh && !buffer_locked(CURRENT->bh))
-                       panic("ACSI: block not locked");
-       }
-
-       block = CURRENT->sector;
-       if (block+CURRENT->nr_sectors >= get_capacity(disk)) {
-#ifdef DEBUG
-               printk( "%s: attempted access for blocks %d...%ld past end of device at block %ld.\n",
-                      disk->disk_name,
-                      block, block + CURRENT->nr_sectors - 1,
-                      get_capacity(disk));
-#endif
-               end_request(CURRENT, 0);
-               goto repeat;
-       }
-       if (aip->changed) {
-               printk( KERN_NOTICE "%s: request denied because cartridge has "
-                               "been changed.\n", disk->disk_name);
-               end_request(CURRENT, 0);
-               goto repeat;
-       }
-       
-       target = aip->target;
-       lun    = aip->lun;
-
-       /* Find out how many sectors should be transferred from/to
-        * consecutive buffers and thus can be done with a single command.
-        */
-       buffer      = CURRENT->buffer;
-       pbuffer     = virt_to_phys(buffer);
-       nsect       = CURRENT->current_nr_sectors;
-       CurrentNReq = 1;
-
-       if ((bh = CURRENT->bh) && bh != CURRENT->bhtail) {
-               if (!STRAM_ADDR(pbuffer)) {
-                       /* If transfer is done via the ACSI buffer anyway, we can
-                        * assemble as much bh's as fit in the buffer.
-                        */
-                       while( (bh = bh->b_reqnext) ) {
-                               if (nsect + (bh->b_size>>9) > ACSI_BUFFER_SECTORS) break;
-                               nsect += bh->b_size >> 9;
-                               ++CurrentNReq;
-                               if (bh == CURRENT->bhtail) break;
-                       }
-                       buffer = acsi_buffer;
-                       pbuffer = phys_acsi_buffer;
-               }
-               else {
-                       unsigned long pendadr, pnewadr;
-                       pendadr = pbuffer + nsect*512;
-                       while( (bh = bh->b_reqnext) ) {
-                               pnewadr = virt_to_phys(bh->b_data);
-                               if (!STRAM_ADDR(pnewadr) || pendadr != pnewadr) break;
-                               nsect += bh->b_size >> 9;
-                               pendadr = pnewadr + bh->b_size;
-                               ++CurrentNReq;
-                               if (bh == CURRENT->bhtail) break;
-                       }
-               }
-       }
-       else {
-               if (!STRAM_ADDR(pbuffer)) {
-                       buffer = acsi_buffer;
-                       pbuffer = phys_acsi_buffer;
-                       if (nsect > ACSI_BUFFER_SECTORS)
-                               nsect = ACSI_BUFFER_SECTORS;
-               }
-       }
-       CurrentBuffer = buffer;
-       CurrentNSect  = nsect;
-
-       if (rq_data_dir(CURRENT) == WRITE) {
-               CMDSET_TARG_LUN( write_cmd, target, lun );
-               CMDSET_BLOCK( write_cmd, block );
-               CMDSET_LEN( write_cmd, nsect );
-               if (buffer == acsi_buffer)
-                       copy_to_acsibuffer();
-               dma_cache_maintenance( pbuffer, nsect*512, 1 );
-               do_acsi = write_intr;
-               if (!acsicmd_dma( write_cmd, buffer, nsect, 1, 1)) {
-                       do_acsi = NULL;
-                       printk( KERN_ERR "ACSI (write): Timeout in command block\n" );
-                       bad_rw_intr();
-                       goto repeat;
-               }
-               SET_TIMER();
-               return;
-       }
-       if (rq_data_dir(CURRENT) == READ) {
-               CMDSET_TARG_LUN( read_cmd, target, lun );
-               CMDSET_BLOCK( read_cmd, block );
-               CMDSET_LEN( read_cmd, nsect );
-               do_acsi = read_intr;
-               if (!acsicmd_dma( read_cmd, buffer, nsect, 0, 1)) {
-                       do_acsi = NULL;
-                       printk( KERN_ERR "ACSI (read): Timeout in command block\n" );
-                       bad_rw_intr();
-                       goto repeat;
-               }
-               SET_TIMER();
-               return;
-       }
-       panic("unknown ACSI command");
-}
-
-
-\f
-/***********************************************************************
- *
- *  Misc functions: ioctl, open, release, check_change, ...
- *
- ***********************************************************************/
-
-static int acsi_getgeo(struct block_device *bdev, struct hd_geometry *geo)
-{
-       struct acsi_info_struct *aip = bdev->bd_disk->private_data;
-
-       /*
-        * Just fake some geometry here, it's nonsense anyway
-        * To make it easy, use Adaptec's usual 64/32 mapping
-        */
-       geo->heads = 64;
-       geo->sectors = 32;
-       geo->cylinders = aip->size >> 11;
-       return 0;
-}
-
-static int acsi_ioctl( struct inode *inode, struct file *file,
-                                          unsigned int cmd, unsigned long arg )
-{
-       struct gendisk *disk = inode->i_bdev->bd_disk;
-       struct acsi_info_struct *aip = disk->private_data;
-       switch (cmd) {
-         case SCSI_IOCTL_GET_IDLUN:
-               /* SCSI compatible GET_IDLUN call to get target's ID and LUN number */
-               put_user( aip->target | (aip->lun << 8),
-                                 &((Scsi_Idlun *) arg)->dev_id );
-               put_user( 0, &((Scsi_Idlun *) arg)->host_unique_id );
-               return 0;
-         default:
-               return -EINVAL;
-       }
-}
-
-
-/*
- * Open a device, check for read-only and lock the medium if it is
- * removable.
- *
- * Changes by Martin Rogge, 9th Aug 1995:
- * Check whether check_disk_change (and therefore revalidate_acsidisk)
- * was successful. They fail when there is no medium in the drive.
- *
- * The problem of media being changed during an operation can be 
- * ignored because of the prevent_removal code.
- *
- * Added check for the validity of the device number.
- *
- */
-
-static int acsi_open( struct inode * inode, struct file * filp )
-{
-       struct gendisk *disk = inode->i_bdev->bd_disk;
-       struct acsi_info_struct *aip = disk->private_data;
-
-       if (aip->access_count == 0 && aip->removable) {
-#if 0
-               aip->changed = 1;       /* safety first */
-#endif
-               check_disk_change( inode->i_bdev );
-               if (aip->changed)       /* revalidate was not successful (no medium) */
-                       return -ENXIO;
-               acsi_prevent_removal(aip, 1);
-       }
-       aip->access_count++;
-
-       if (filp && filp->f_mode) {
-               check_disk_change( inode->i_bdev );
-               if (filp->f_mode & 2) {
-                       if (aip->read_only) {
-                               acsi_release( inode, filp );
-                               return -EROFS;
-                       }
-               }
-       }
-
-       return 0;
-}
-
-/*
- * Releasing a block device means we sync() it, so that it can safely
- * be forgotten about...
- */
-
-static int acsi_release( struct inode * inode, struct file * file )
-{
-       struct gendisk *disk = inode->i_bdev->bd_disk;
-       struct acsi_info_struct *aip = disk->private_data;
-       if (--aip->access_count == 0 && aip->removable)
-               acsi_prevent_removal(aip, 0);
-       return( 0 );
-}
-
-/*
- * Prevent or allow a media change for removable devices.
- */
-
-static void acsi_prevent_removal(struct acsi_info_struct *aip, int flag)
-{
-       stdma_lock( NULL, NULL );
-       
-       CMDSET_TARG_LUN(pa_med_rem_cmd, aip->target, aip->lun);
-       CMDSET_LEN( pa_med_rem_cmd, flag );
-       
-       if (acsicmd_nodma(pa_med_rem_cmd, 0) && acsi_wait_for_IRQ(3*HZ))
-               acsi_getstatus();
-       /* Do not report errors -- some devices may not know this command. */
-
-       ENABLE_IRQ();
-       stdma_release();
-}
-
-static int acsi_media_change(struct gendisk *disk)
-{
-       struct acsi_info_struct *aip = disk->private_data;
-
-       if (!aip->removable) 
-               return 0;
-
-       if (aip->changed)
-               /* We can be sure that the medium has been changed -- REQUEST
-                * SENSE has reported this earlier.
-                */
-               return 1;
-
-       /* If the flag isn't set, make a test by reading block 0.
-        * If errors happen, it seems to be better to say "changed"...
-        */
-       stdma_lock( NULL, NULL );
-       CMDSET_TARG_LUN(read_cmd, aip->target, aip->lun);
-       CMDSET_BLOCK( read_cmd, 0 );
-       CMDSET_LEN( read_cmd, 1 );
-       if (acsicmd_dma(read_cmd, acsi_buffer, 1, 0, 0) &&
-           acsi_wait_for_IRQ(3*HZ)) {
-               if (acsi_getstatus()) {
-                       if (acsi_reqsense(acsi_buffer, aip->target, aip->lun)) {
-                               if (CARTRCH_STAT(aip, acsi_buffer))
-                                       aip->changed = 1;
-                       }
-                       else {
-                               printk( KERN_ERR "%s: REQUEST SENSE failed in test for "
-                                      "medium change; assuming a change\n", disk->disk_name );
-                               aip->changed = 1;
-                       }
-               }
-       }
-       else {
-               printk( KERN_ERR "%s: Test for medium changed timed out; "
-                               "assuming a change\n", disk->disk_name);
-               aip->changed = 1;
-       }
-       ENABLE_IRQ();
-       stdma_release();
-
-       /* Now, after reading a block, the changed status is surely valid. */
-       return aip->changed;
-}
-
-
-static int acsi_change_blk_size( int target, int lun)
-
-{      int i;
-
-       for (i=0; i<12; i++)
-               acsi_buffer[i] = 0;
-
-       acsi_buffer[3] = 8;
-       acsi_buffer[10] = 2;
-       CMDSET_TARG_LUN( modeselect_cmd, target, lun);
-
-       if (!acsicmd_dma( modeselect_cmd, acsi_buffer, 1,1,0) ||
-               !acsi_wait_for_IRQ( 3*HZ ) ||
-               acsi_getstatus() != 0 ) {
-               return(0);
-       }
-       return(1);
-}
-
-
-static int acsi_mode_sense( int target, int lun, SENSE_DATA *sd )
-
-{
-       int page;
-
-       CMDSET_TARG_LUN( modesense_cmd, target, lun );
-       for (page=0; page<4; page++) {
-               modesense_cmd[2] = page;
-               if (!acsicmd_dma( modesense_cmd, acsi_buffer, 1, 0, 0 ) ||
-                   !acsi_wait_for_IRQ( 3*HZ ) ||
-                   acsi_getstatus())
-                       continue;
-
-               /* read twice to jump over the second 16-byte border! */
-               udelay(300);
-               if (acsi_wait_for_noIRQ( 20 ) &&
-                   acsicmd_nodma( modesense_cmd, 0 ) &&
-                   acsi_wait_for_IRQ( 3*HZ ) &&
-                   acsi_getstatus() == 0)
-                       break;
-       }
-       if (page == 4) {
-               return(0);
-       }
-
-       dma_cache_maintenance( phys_acsi_buffer, sizeof(SENSE_DATA), 0 );
-       *sd = *(SENSE_DATA *)acsi_buffer;
-
-       /* Validity check, depending on type of data */
-       
-       switch( SENSE_TYPE(*sd) ) {
-
-         case SENSE_TYPE_ATARI:
-               if (CAPACITY(*sd) == 0)
-                       goto invalid_sense;
-               break;
-
-         case SENSE_TYPE_SCSI:
-               if (sd->scsi.descriptor_size != 8)
-                       goto invalid_sense;
-               break;
-
-         case SENSE_TYPE_UNKNOWN:
-
-               printk( KERN_ERR "ACSI target %d, lun %d: Cannot interpret "
-                               "sense data\n", target, lun ); 
-               
-         invalid_sense:
-
-#ifdef DEBUG
-               {       int i;
-               printk( "Mode sense data for ACSI target %d, lun %d seem not valid:",
-                               target, lun );
-               for( i = 0; i < sizeof(SENSE_DATA); ++i )
-                       printk( "%02x ", (unsigned char)acsi_buffer[i] );
-               printk( "\n" );
-               }
-#endif
-               return( 0 );
-       }
-               
-       return( 1 );
-}
-
-
-
-/*******************************************************************
- *
- *  Initialization
- *
- ********************************************************************/
-
-
-extern struct block_device_operations acsi_fops;
-
-static struct gendisk *acsi_gendisk[MAX_DEV];
-
-#define MAX_SCSI_DEVICE_CODE 10
-
-static const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE] =
-{
- "Direct-Access    ",
- "Sequential-Access",
- "Printer          ",
- "Processor        ",
- "WORM             ",
- "CD-ROM           ",
- "Scanner          ",
- "Optical Device   ",
- "Medium Changer   ",
- "Communications   "
-};
-
-static void print_inquiry(unsigned char *data)
-{
-       int i;
-
-       printk(KERN_INFO "  Vendor: ");
-       for (i = 8; i < 16; i++)
-               {
-               if (data[i] >= 0x20 && i < data[4] + 5)
-                       printk("%c", data[i]);
-               else
-                       printk(" ");
-               }
-
-       printk("  Model: ");
-       for (i = 16; i < 32; i++)
-               {
-               if (data[i] >= 0x20 && i < data[4] + 5)
-                       printk("%c", data[i]);
-               else
-                       printk(" ");
-               }
-
-       printk("  Rev: ");
-       for (i = 32; i < 36; i++)
-               {
-               if (data[i] >= 0x20 && i < data[4] + 5)
-                       printk("%c", data[i]);
-               else
-                       printk(" ");
-               }
-
-       printk("\n");
-
-       i = data[0] & 0x1f;
-
-       printk(KERN_INFO "  Type:   %s ", (i < MAX_SCSI_DEVICE_CODE
-                                                                          ? scsi_device_types[i]
-                                                                          : "Unknown          "));
-       printk("                 ANSI SCSI revision: %02x", data[2] & 0x07);
-       if ((data[2] & 0x07) == 1 && (data[3] & 0x0f) == 1)
-         printk(" CCS\n");
-       else
-         printk("\n");
-}
-
-
-/* 
- * Changes by Martin Rogge, 9th Aug 1995: 
- * acsi_devinit has been taken out of acsi_geninit, because it needs 
- * to be called from revalidate_acsidisk. The result of request sense 
- * is now checked for DRIVE NOT READY.
- *
- * The structure *aip is only valid when acsi_devinit returns 
- * DEV_SUPPORTED. 
- *
- */
-       
-#define DEV_NONE       0
-#define DEV_UNKNOWN    1
-#define DEV_SUPPORTED  2
-#define DEV_SLM                3
-
-static int acsi_devinit(struct acsi_info_struct *aip)
-{
-       int status, got_inquiry;
-       SENSE_DATA sense;
-       unsigned char reqsense, extsense;
-
-       /*****************************************************************/
-       /* Do a TEST UNIT READY command to test the presence of a device */
-       /*****************************************************************/
-
-       CMDSET_TARG_LUN(tur_cmd, aip->target, aip->lun);
-       if (!acsicmd_nodma(tur_cmd, 0)) {
-               /* timed out -> no device here */
-#ifdef DEBUG_DETECT
-               printk("target %d lun %d: timeout\n", aip->target, aip->lun);
-#endif
-               return DEV_NONE;
-       }
-               
-       /*************************/
-       /* Read the ACSI status. */
-       /*************************/
-
-       status = acsi_getstatus();
-       if (status) {
-               if (status == 0x12) {
-                       /* The SLM printer should be the only device that
-                        * responds with the error code in the status byte. In
-                        * correct status bytes, bit 4 is never set.
-                        */
-                       printk( KERN_INFO "Detected SLM printer at id %d lun %d\n",
-                              aip->target, aip->lun);
-                       return DEV_SLM;
-               }
-               /* ignore CHECK CONDITION, since some devices send a
-                  UNIT ATTENTION */
-               if ((status & 0x1e) != 0x2) {
-#ifdef DEBUG_DETECT
-                       printk("target %d lun %d: status %d\n",
-                              aip->target, aip->lun, status);
-#endif
-                       return DEV_UNKNOWN;
-               }
-       }
-
-       /*******************************/
-       /* Do a REQUEST SENSE command. */
-       /*******************************/
-
-       if (!acsi_reqsense(acsi_buffer, aip->target, aip->lun)) {
-               printk( KERN_WARNING "acsi_reqsense failed\n");
-               acsi_buffer[0] = 0;
-               acsi_buffer[2] = UNIT_ATTENTION;
-       }
-       reqsense = acsi_buffer[0];
-       extsense = acsi_buffer[2] & 0xf;
-       if (status) {
-               if ((reqsense & 0x70) == 0x70) {        /* extended sense */
-                       if (extsense != UNIT_ATTENTION &&
-                           extsense != NOT_READY) {
-#ifdef DEBUG_DETECT
-                               printk("target %d lun %d: extended sense %d\n",
-                                      aip->target, aip->lun, extsense);
-#endif
-                               return DEV_UNKNOWN;
-                       }
-               }
-               else {
-                       if (reqsense & 0x7f) {
-#ifdef DEBUG_DETECT
-                               printk("target %d lun %d: sense %d\n",
-                                      aip->target, aip->lun, reqsense);
-#endif
-                               return DEV_UNKNOWN;
-                       }
-               }
-       }
-       else 
-               if (reqsense == 0x4) {  /* SH204 Bug workaround */
-#ifdef DEBUG_DETECT
-                       printk("target %d lun %d status=0 sense=4\n",
-                              aip->target, aip->lun);
-#endif
-                       return DEV_UNKNOWN;
-               }
-
-       /***********************************************************/
-       /* Do an INQUIRY command to get more infos on this device. */
-       /***********************************************************/
-
-       /* Assume default values */
-       aip->removable = 1;
-       aip->read_only = 0;
-       aip->old_atari_disk = 0;
-       aip->changed = (extsense == NOT_READY); /* medium inserted? */
-       aip->size = DEFAULT_SIZE;
-       got_inquiry = 0;
-       /* Fake inquiry result for old atari disks */
-       memcpy(acsi_buffer, "\000\000\001\000    Adaptec 40xx"
-              "                    ", 40);
-       CMDSET_TARG_LUN(inquiry_cmd, aip->target, aip->lun);
-       if (acsicmd_dma(inquiry_cmd, acsi_buffer, 1, 0, 0) &&
-           acsi_getstatus() == 0) {
-               acsicmd_nodma(inquiry_cmd, 0);
-               acsi_getstatus();
-               dma_cache_maintenance( phys_acsi_buffer, 256, 0 );
-               got_inquiry = 1;
-               aip->removable = !!(acsi_buffer[1] & 0x80);
-       }
-       if (aip->type == NONE)  /* only at boot time */
-               print_inquiry(acsi_buffer);
-       switch(acsi_buffer[0]) {
-         case TYPE_DISK:
-               aip->type = HARDDISK;
-               break;
-         case TYPE_ROM:
-               aip->type = CDROM;
-               aip->read_only = 1;
-               break;
-         default:
-               return DEV_UNKNOWN;
-       }
-       /****************************/
-       /* Do a MODE SENSE command. */
-       /****************************/
-
-       if (!acsi_mode_sense(aip->target, aip->lun, &sense)) {
-               printk( KERN_WARNING "No mode sense data.\n" );
-               return DEV_UNKNOWN;
-       }
-       if ((SECTOR_SIZE(sense) != 512) &&
-           ((aip->type != CDROM) ||
-            !acsi_change_blk_size(aip->target, aip->lun) ||
-            !acsi_mode_sense(aip->target, aip->lun, &sense) ||
-            (SECTOR_SIZE(sense) != 512))) {
-               printk( KERN_WARNING "Sector size != 512 not supported.\n" );
-               return DEV_UNKNOWN;
-       }
-       /* There are disks out there that claim to have 0 sectors... */
-       if (CAPACITY(sense))
-               aip->size = CAPACITY(sense);    /* else keep DEFAULT_SIZE */
-       if (!got_inquiry && SENSE_TYPE(sense) == SENSE_TYPE_ATARI) {
-               /* If INQUIRY failed and the sense data suggest an old
-                * Atari disk (SH20x, Megafile), the disk is not removable
-                */
-               aip->removable = 0;
-               aip->old_atari_disk = 1;
-       }
-       
-       /******************/
-       /* We've done it. */
-       /******************/
-       
-       return DEV_SUPPORTED;
-}
-
-EXPORT_SYMBOL(acsi_delay_start);
-EXPORT_SYMBOL(acsi_delay_end);
-EXPORT_SYMBOL(acsi_wait_for_IRQ);
-EXPORT_SYMBOL(acsi_wait_for_noIRQ);
-EXPORT_SYMBOL(acsicmd_nodma);
-EXPORT_SYMBOL(acsi_getstatus);
-EXPORT_SYMBOL(acsi_buffer);
-EXPORT_SYMBOL(phys_acsi_buffer);
-
-#ifdef CONFIG_ATARI_SLM_MODULE
-void acsi_attach_SLMs( int (*attach_func)( int, int ) );
-
-EXPORT_SYMBOL(acsi_extstatus);
-EXPORT_SYMBOL(acsi_end_extstatus);
-EXPORT_SYMBOL(acsi_extcmd);
-EXPORT_SYMBOL(acsi_attach_SLMs);
-
-/* to remember IDs of SLM devices, SLM module is loaded later
- * (index is target#, contents is lun#, -1 means "no SLM") */
-int SLM_devices[8];
-#endif
-
-static struct block_device_operations acsi_fops = {
-       .owner          = THIS_MODULE,
-       .open           = acsi_open,
-       .release        = acsi_release,
-       .ioctl          = acsi_ioctl,
-       .getgeo         = acsi_getgeo,
-       .media_changed  = acsi_media_change,
-       .revalidate_disk= acsi_revalidate,
-};
-
-#ifdef CONFIG_ATARI_SLM_MODULE
-/* call attach_slm() for each device that is a printer; needed for init of SLM
- * driver as a module, since it's not yet present if acsi.c is inited and thus
- * the bus gets scanned. */
-void acsi_attach_SLMs( int (*attach_func)( int, int ) )
-{
-       int i, n = 0;
-
-       for( i = 0; i < 8; ++i )
-               if (SLM_devices[i] >= 0)
-                       n += (*attach_func)( i, SLM_devices[i] );
-       printk( KERN_INFO "Found %d SLM printer(s) total.\n", n );
-}
-#endif /* CONFIG_ATARI_SLM_MODULE */
-
-
-int acsi_init( void )
-{
-       int err = 0;
-       int i, target, lun;
-       struct acsi_info_struct *aip;
-#ifdef CONFIG_ATARI_SLM
-       int n_slm = 0;
-#endif
-       if (!MACH_IS_ATARI || !ATARIHW_PRESENT(ACSI))
-               return 0;
-       if (register_blkdev(ACSI_MAJOR, "ad")) {
-               err = -EBUSY;
-               goto out1;
-       }
-       if (!(acsi_buffer =
-                 (char *)atari_stram_alloc(ACSI_BUFFER_SIZE, "acsi"))) {
-               err = -ENOMEM;
-               printk( KERN_ERR "Unable to get ACSI ST-Ram buffer.\n" );
-               goto out2;
-       }
-       phys_acsi_buffer = virt_to_phys( acsi_buffer );
-       STramMask = ATARIHW_PRESENT(EXTD_DMA) ? 0x00000000 : 0xff000000;
-       
-       acsi_queue = blk_init_queue(do_acsi_request, &acsi_lock);
-       if (!acsi_queue) {
-               err = -ENOMEM;
-               goto out2a;
-       }
-#ifdef CONFIG_ATARI_SLM
-       err = slm_init();
-#endif
-       if (err)
-               goto out3;
-
-       printk( KERN_INFO "Probing ACSI devices:\n" );
-       NDevices = 0;
-#ifdef CONFIG_ATARI_SLM_MODULE
-       for( i = 0; i < 8; ++i )
-               SLM_devices[i] = -1;
-#endif
-       stdma_lock(NULL, NULL);
-
-       for (target = 0; target < 8 && NDevices < MAX_DEV; ++target) {
-               lun = 0;
-               do {
-                       aip = &acsi_info[NDevices];
-                       aip->type = NONE;
-                       aip->target = target;
-                       aip->lun = lun;
-                       i = acsi_devinit(aip);
-                       switch (i) {
-                         case DEV_SUPPORTED:
-                               printk( KERN_INFO "Detected ");
-                               switch (aip->type) {
-                                 case HARDDISK:
-                                       printk("disk");
-                                       break;
-                                 case CDROM:
-                                       printk("cdrom");
-                                       break;
-                                 default:
-                               }
-                               printk(" ad%c at id %d lun %d ",
-                                      'a' + NDevices, target, lun);
-                               if (aip->removable) 
-                                       printk("(removable) ");
-                               if (aip->read_only) 
-                                       printk("(read-only) ");
-                               if (aip->size == DEFAULT_SIZE)
-                                       printk(" unkown size, using default ");
-                               printk("%ld MByte\n",
-                                      (aip->size*512+1024*1024/2)/(1024*1024));
-                               NDevices++;
-                               break;
-                         case DEV_SLM:
-#ifdef CONFIG_ATARI_SLM
-                               n_slm += attach_slm( target, lun );
-                               break;
-#endif
-#ifdef CONFIG_ATARI_SLM_MODULE
-                               SLM_devices[target] = lun;
-                               break;
-#endif
-                               /* neither of the above: fall through to unknown device */
-                         case DEV_UNKNOWN:
-                               printk( KERN_INFO "Detected unsupported device at "
-                                               "id %d lun %d\n", target, lun);
-                               break;
-                       }
-               }
-#ifdef CONFIG_ACSI_MULTI_LUN
-               while (i != DEV_NONE && ++lun < MAX_LUN);
-#else
-               while (0);
-#endif
-       }
-
-       /* reenable interrupt */
-       ENABLE_IRQ();
-       stdma_release();
-
-#ifndef CONFIG_ATARI_SLM
-       printk( KERN_INFO "Found %d ACSI device(s) total.\n", NDevices );
-#else
-       printk( KERN_INFO "Found %d ACSI device(s) and %d SLM printer(s) total.\n",
-                       NDevices, n_slm );
-#endif
-       err = -ENOMEM;
-       for( i = 0; i < NDevices; ++i ) {
-               acsi_gendisk[i] = alloc_disk(16);
-               if (!acsi_gendisk[i])
-                       goto out4;
-       }
-
-       for( i = 0; i < NDevices; ++i ) {
-               struct gendisk *disk = acsi_gendisk[i];
-               sprintf(disk->disk_name, "ad%c", 'a'+i);
-               aip = &acsi_info[NDevices];
-               disk->major = ACSI_MAJOR;
-               disk->first_minor = i << 4;
-               if (acsi_info[i].type != HARDDISK)
-                       disk->minors = 1;
-               disk->fops = &acsi_fops;
-               disk->private_data = &acsi_info[i];
-               set_capacity(disk, acsi_info[i].size);
-               disk->queue = acsi_queue;
-               add_disk(disk);
-       }
-       return 0;
-out4:
-       while (i--)
-               put_disk(acsi_gendisk[i]);
-out3:
-       blk_cleanup_queue(acsi_queue);
-out2a:
-       atari_stram_free( acsi_buffer );
-out2:
-       unregister_blkdev( ACSI_MAJOR, "ad" );
-out1:
-       return err;
-}
-
-
-#ifdef MODULE
-
-MODULE_LICENSE("GPL");
-
-int init_module(void)
-{
-       int err;
-
-       if ((err = acsi_init()))
-               return( err );
-       printk( KERN_INFO "ACSI driver loaded as module.\n");
-       return( 0 );
-}
-
-void cleanup_module(void)
-{
-       int i;
-       del_timer( &acsi_timer );
-       blk_cleanup_queue(acsi_queue);
-       atari_stram_free( acsi_buffer );
-
-       if (unregister_blkdev( ACSI_MAJOR, "ad" ) != 0)
-               printk( KERN_ERR "acsi: cleanup_module failed\n");
-
-       for (i = 0; i < NDevices; i++) {
-               del_gendisk(acsi_gendisk[i]);
-               put_disk(acsi_gendisk[i]);
-       }
-}
-#endif
-
-/*
- * This routine is called to flush all partitions and partition tables
- * for a changed scsi disk, and then re-read the new partition table.
- * If we are revalidating a disk because of a media change, then we
- * enter with usage == 0.  If we are using an ioctl, we automatically have
- * usage == 1 (we need an open channel to use an ioctl :-), so this
- * is our limit.
- *
- * Changes by Martin Rogge, 9th Aug 1995: 
- * got cd-roms to work by calling acsi_devinit. There are only two problems:
- * First, if there is no medium inserted, the status will remain "changed".
- * That is no problem at all, but our design of three-valued logic (medium
- * changed, medium not changed, no medium inserted).
- * Secondly the check could fail completely and the drive could deliver
- * nonsensical data, which could mess up the acsi_info[] structure. In
- * that case we try to make the entry safe.
- *
- */
-
-static int acsi_revalidate(struct gendisk *disk)
-{
-       struct acsi_info_struct *aip = disk->private_data;
-       stdma_lock( NULL, NULL );
-       if (acsi_devinit(aip) != DEV_SUPPORTED) {
-               printk( KERN_ERR "ACSI: revalidate failed for target %d lun %d\n",
-                      aip->target, aip->lun);
-               aip->size = 0;
-               aip->read_only = 1;
-               aip->removable = 1;
-               aip->changed = 1; /* next acsi_open will try again... */
-       }
-
-       ENABLE_IRQ();
-       stdma_release();
-       set_capacity(disk, aip->size);
-       return 0;
-}
index 27a139025cedaf677124a67d21a54447b621f500..6ce8b897e2623f025de20994a8f02a11eee2e8f2 100644 (file)
@@ -1363,7 +1363,7 @@ static void redo_fd_request(void)
 #ifdef DEBUG
                printk("fd: sector %ld + %d requested for %s\n",
                       CURRENT->sector,cnt,
-                      (CURRENT->cmd==READ)?"read":"write");
+                      (rq_data_dir(CURRENT) == READ) ? "read" : "write");
 #endif
                block = CURRENT->sector + cnt;
                if ((int)block > floppy->blocks) {
index 5acc6c44aeadd1a57908ad3d63001df665496561..0fcad430474ecaf0700e760f6acd0a0de2628093 100644 (file)
@@ -87,6 +87,7 @@ static const struct pci_device_id cciss_pci_device_id[] = {
        {PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSD,     0x103C, 0x3214},
        {PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSD,     0x103C, 0x3215},
        {PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSC,     0x103C, 0x3237},
+       {PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSC,     0x103C, 0x323D},
        {PCI_VENDOR_ID_HP,     PCI_ANY_ID,      PCI_ANY_ID, PCI_ANY_ID,
                PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0},
        {0,}
@@ -119,6 +120,7 @@ static struct board_type products[] = {
        {0x3214103C, "Smart Array E200i", &SA5_access, 120},
        {0x3215103C, "Smart Array E200i", &SA5_access, 120},
        {0x3237103C, "Smart Array E500", &SA5_access, 512},
+       {0x323D103C, "Smart Array P700m", &SA5_access, 512},
        {0xFFFF103C, "Unknown Smart Array", &SA5_access, 120},
 };
 
index 0ed5470d25339674a5c449feab66f5505db5f3c2..4503290da4078c2916bafdc8af301fac333f5349 100644 (file)
@@ -74,6 +74,7 @@
 #include <linux/highmem.h>
 #include <linux/gfp.h>
 #include <linux/kthread.h>
+#include <linux/splice.h>
 
 #include <asm/uaccess.h>
 
@@ -401,50 +402,73 @@ struct lo_read_data {
 };
 
 static int
-lo_read_actor(read_descriptor_t *desc, struct page *page,
-             unsigned long offset, unsigned long size)
+lo_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
+               struct splice_desc *sd)
 {
-       unsigned long count = desc->count;
-       struct lo_read_data *p = desc->arg.data;
+       struct lo_read_data *p = sd->u.data;
        struct loop_device *lo = p->lo;
+       struct page *page = buf->page;
        sector_t IV;
+       size_t size;
+       int ret;
 
-       IV = ((sector_t) page->index << (PAGE_CACHE_SHIFT - 9))+(offset >> 9);
+       ret = buf->ops->confirm(pipe, buf);
+       if (unlikely(ret))
+               return ret;
 
-       if (size > count)
-               size = count;
+       IV = ((sector_t) page->index << (PAGE_CACHE_SHIFT - 9)) +
+                                                       (buf->offset >> 9);
+       size = sd->len;
+       if (size > p->bsize)
+               size = p->bsize;
 
-       if (lo_do_transfer(lo, READ, page, offset, p->page, p->offset, size, IV)) {
-               size = 0;
+       if (lo_do_transfer(lo, READ, page, buf->offset, p->page, p->offset, size, IV)) {
                printk(KERN_ERR "loop: transfer error block %ld\n",
                       page->index);
-               desc->error = -EINVAL;
+               size = -EINVAL;
        }
 
        flush_dcache_page(p->page);
 
-       desc->count = count - size;
-       desc->written += size;
-       p->offset += size;
+       if (size > 0)
+               p->offset += size;
+
        return size;
 }
 
+static int
+lo_direct_splice_actor(struct pipe_inode_info *pipe, struct splice_desc *sd)
+{
+       return __splice_from_pipe(pipe, sd, lo_splice_actor);
+}
+
 static int
 do_lo_receive(struct loop_device *lo,
              struct bio_vec *bvec, int bsize, loff_t pos)
 {
        struct lo_read_data cookie;
+       struct splice_desc sd;
        struct file *file;
-       int retval;
+       long retval;
 
        cookie.lo = lo;
        cookie.page = bvec->bv_page;
        cookie.offset = bvec->bv_offset;
        cookie.bsize = bsize;
+
+       sd.len = 0;
+       sd.total_len = bvec->bv_len;
+       sd.flags = 0;
+       sd.pos = pos;
+       sd.u.data = &cookie;
+
        file = lo->lo_backing_file;
-       retval = file->f_op->sendfile(file, &pos, bvec->bv_len,
-                       lo_read_actor, &cookie);
-       return (retval < 0)? retval: 0;
+       retval = splice_direct_to_actor(file, &sd, lo_direct_splice_actor);
+
+       if (retval < 0)
+               return retval;
+
+       return 0;
 }
 
 static int
@@ -679,8 +703,8 @@ static int loop_change_fd(struct loop_device *lo, struct file *lo_file,
        if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode))
                goto out_putf;
 
-       /* new backing store needs to support loop (eg sendfile) */
-       if (!inode->i_fop->sendfile)
+       /* new backing store needs to support loop (eg splice_read) */
+       if (!inode->i_fop->splice_read)
                goto out_putf;
 
        /* size of the new backing store needs to be the same */
@@ -760,7 +784,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
                 * If we can't read - sorry. If we only can't write - well,
                 * it's going to be read-only.
                 */
-               if (!file->f_op->sendfile)
+               if (!file->f_op->splice_read)
                        goto out_putf;
                if (aops->prepare_write && aops->commit_write)
                        lo_flags |= LO_FLAGS_USE_AOPS;
index 069ae39a9cd9023eb62d9115f2885383c2df86ef..c575fb1d585f1131714a6658cc1b823404140cfd 100644 (file)
@@ -416,7 +416,7 @@ static void nbd_clear_que(struct nbd_device *lo)
 /*
  * We always wait for result of write, for now. It would be nice to make it optional
  * in future
- * if ((req->cmd == WRITE) && (lo->flags & NBD_WRITE_NOCHK)) 
+ * if ((rq_data_dir(req) == WRITE) && (lo->flags & NBD_WRITE_NOCHK))
  *   { printk( "Warning: Ignoring result!\n"); nbd_end_request( req ); }
  */
 
index f1b9dd7d47d62c00868acdba0927d68a0c8777e0..ce64e86d6ffbb9d4205a96f0e189dec7519632ca 100644 (file)
@@ -146,8 +146,7 @@ static void pkt_kobj_release(struct kobject *kobj)
  **********************************************************/
 
 #define DEF_ATTR(_obj,_name,_mode) \
-       static struct attribute _obj = { \
-               .name = _name, .owner = THIS_MODULE, .mode = _mode }
+       static struct attribute _obj = { .name = _name, .mode = _mode }
 
 /**********************************************************
   /sys/class/pktcdvd/pktcdvd[0-7]/
index 746a118a9b52ba1792b28861605902534290d1d4..18c8b6c0db20239ae3095c2547a13cbab66dff5c 100644 (file)
@@ -1547,10 +1547,8 @@ static void ub_reset_enter(struct ub_dev *sc, int try)
 #endif
 
 #if 0 /* We let them stop themselves. */
-       struct list_head *p;
        struct ub_lun *lun;
-       list_for_each(p, &sc->luns) {
-               lun = list_entry(p, struct ub_lun, link);
+       list_for_each_entry(lun, &sc->luns, link) {
                blk_stop_queue(lun->disk->queue);
        }
 #endif
@@ -1562,7 +1560,6 @@ static void ub_reset_task(struct work_struct *work)
 {
        struct ub_dev *sc = container_of(work, struct ub_dev, reset_work);
        unsigned long flags;
-       struct list_head *p;
        struct ub_lun *lun;
        int lkr, rc;
 
@@ -1608,8 +1605,7 @@ static void ub_reset_task(struct work_struct *work)
        spin_lock_irqsave(sc->lock, flags);
        sc->reset = 0;
        tasklet_schedule(&sc->tasklet);
-       list_for_each(p, &sc->luns) {
-               lun = list_entry(p, struct ub_lun, link);
+       list_for_each_entry(lun, &sc->luns, link) {
                blk_start_queue(lun->disk->queue);
        }
        wake_up(&sc->reset_wait);
@@ -2348,7 +2344,6 @@ err_alloc:
 static void ub_disconnect(struct usb_interface *intf)
 {
        struct ub_dev *sc = usb_get_intfdata(intf);
-       struct list_head *p;
        struct ub_lun *lun;
        unsigned long flags;
 
@@ -2403,8 +2398,7 @@ static void ub_disconnect(struct usb_interface *intf)
        /*
         * Unregister the upper layer.
         */
-       list_for_each (p, &sc->luns) {
-               lun = list_entry(p, struct ub_lun, link);
+       list_for_each_entry(lun, &sc->luns, link) {
                del_gendisk(lun->disk);
                /*
                 * I wish I could do:
index 7e04dd69f60976abc4a203acd7dc3d04e25bd3f3..59b054810ed05878db71ef2aa2867bd0cfdd88a5 100644 (file)
@@ -199,7 +199,6 @@ static void hci_usb_tx_complete(struct urb *urb);
 #define __pending_q(husb, type)   (&husb->pending_q[type-1])
 #define __completed_q(husb, type) (&husb->completed_q[type-1])
 #define __transmit_q(husb, type)  (&husb->transmit_q[type-1])
-#define __reassembly(husb, type)  (husb->reassembly[type-1])
 
 static inline struct _urb *__get_completed(struct hci_usb *husb, int type)
 {
@@ -429,12 +428,6 @@ static void hci_usb_unlink_urbs(struct hci_usb *husb)
                        kfree(urb->transfer_buffer);
                        _urb_free(_urb);
                }
-
-               /* Release reassembly buffers */
-               if (husb->reassembly[i]) {
-                       kfree_skb(husb->reassembly[i]);
-                       husb->reassembly[i] = NULL;
-               }
        }
 }
 
@@ -671,83 +664,6 @@ static int hci_usb_send_frame(struct sk_buff *skb)
        return 0;
 }
 
-static inline int __recv_frame(struct hci_usb *husb, int type, void *data, int count)
-{
-       BT_DBG("%s type %d data %p count %d", husb->hdev->name, type, data, count);
-
-       husb->hdev->stat.byte_rx += count;
-
-       while (count) {
-               struct sk_buff *skb = __reassembly(husb, type);
-               struct { int expect; } *scb;
-               int len = 0;
-       
-               if (!skb) {
-                       /* Start of the frame */
-
-                       switch (type) {
-                       case HCI_EVENT_PKT:
-                               if (count >= HCI_EVENT_HDR_SIZE) {
-                                       struct hci_event_hdr *h = data;
-                                       len = HCI_EVENT_HDR_SIZE + h->plen;
-                               } else
-                                       return -EILSEQ;
-                               break;
-
-                       case HCI_ACLDATA_PKT:
-                               if (count >= HCI_ACL_HDR_SIZE) {
-                                       struct hci_acl_hdr *h = data;
-                                       len = HCI_ACL_HDR_SIZE + __le16_to_cpu(h->dlen);
-                               } else
-                                       return -EILSEQ;
-                               break;
-#ifdef CONFIG_BT_HCIUSB_SCO
-                       case HCI_SCODATA_PKT:
-                               if (count >= HCI_SCO_HDR_SIZE) {
-                                       struct hci_sco_hdr *h = data;
-                                       len = HCI_SCO_HDR_SIZE + h->dlen;
-                               } else
-                                       return -EILSEQ;
-                               break;
-#endif
-                       }
-                       BT_DBG("new packet len %d", len);
-
-                       skb = bt_skb_alloc(len, GFP_ATOMIC);
-                       if (!skb) {
-                               BT_ERR("%s no memory for the packet", husb->hdev->name);
-                               return -ENOMEM;
-                       }
-                       skb->dev = (void *) husb->hdev;
-                       bt_cb(skb)->pkt_type = type;
-       
-                       __reassembly(husb, type) = skb;
-
-                       scb = (void *) skb->cb;
-                       scb->expect = len;
-               } else {
-                       /* Continuation */
-                       scb = (void *) skb->cb;
-                       len = scb->expect;
-               }
-
-               len = min(len, count);
-               
-               memcpy(skb_put(skb, len), data, len);
-
-               scb->expect -= len;
-               if (!scb->expect) {
-                       /* Complete frame */
-                       __reassembly(husb, type) = NULL;
-                       bt_cb(skb)->pkt_type = type;
-                       hci_recv_frame(skb);
-               }
-
-               count -= len; data += len;
-       }
-       return 0;
-}
-
 static void hci_usb_rx_complete(struct urb *urb)
 {
        struct _urb *_urb = container_of(urb, struct _urb, urb);
@@ -776,7 +692,7 @@ static void hci_usb_rx_complete(struct urb *urb)
                                        urb->iso_frame_desc[i].actual_length);
        
                        if (!urb->iso_frame_desc[i].status)
-                               __recv_frame(husb, _urb->type, 
+                               hci_recv_fragment(husb->hdev, _urb->type, 
                                        urb->transfer_buffer + urb->iso_frame_desc[i].offset,
                                        urb->iso_frame_desc[i].actual_length);
                }
@@ -784,7 +700,7 @@ static void hci_usb_rx_complete(struct urb *urb)
                ;
 #endif
        } else {
-               err = __recv_frame(husb, _urb->type, urb->transfer_buffer, count);
+               err = hci_recv_fragment(husb->hdev, _urb->type, urb->transfer_buffer, count);
                if (err < 0) { 
                        BT_ERR("%s corrupted packet: type %d count %d",
                                        husb->hdev->name, _urb->type, count);
index 963fc55cdc85766225be38492551a0f3a1857f87..56cd3a92ceca8c94228ca1ae06579088632a45bb 100644 (file)
@@ -102,9 +102,9 @@ struct hci_usb {
        struct hci_dev          *hdev;
 
        unsigned long           state;
-       
+
        struct usb_device       *udev;
-       
+
        struct usb_host_endpoint        *bulk_in_ep;
        struct usb_host_endpoint        *bulk_out_ep;
        struct usb_host_endpoint        *intr_in_ep;
@@ -116,7 +116,6 @@ struct hci_usb {
        __u8                    ctrl_req;
 
        struct sk_buff_head     transmit_q[4];
-       struct sk_buff          *reassembly[4];         /* Reassembly buffers */
 
        rwlock_t                completion_lock;
 
index b71a5ccc587f984d11707d6e557d0e77fccb1d92..0638730a4a19636b7e9db504959725ada6f29895 100644 (file)
@@ -180,11 +180,6 @@ static inline ssize_t vhci_put_user(struct vhci_data *data,
        return total;
 }
 
-static loff_t vhci_llseek(struct file *file, loff_t offset, int origin)
-{
-       return -ESPIPE;
-}
-
 static ssize_t vhci_read(struct file *file,
                                char __user *buf, size_t count, loff_t *pos)
 {
@@ -334,7 +329,6 @@ static int vhci_fasync(int fd, struct file *file, int on)
 
 static const struct file_operations vhci_fops = {
        .owner          = THIS_MODULE,
-       .llseek         = vhci_llseek,
        .read           = vhci_read,
        .write          = vhci_write,
        .poll           = vhci_poll,
diff --git a/drivers/cdrom/Kconfig b/drivers/cdrom/Kconfig
deleted file mode 100644 (file)
index 4b12e90..0000000
+++ /dev/null
@@ -1,213 +0,0 @@
-#
-# CDROM driver configuration
-#
-
-menu "Old CD-ROM drivers (not SCSI, not IDE)"
-       depends on ISA && BLOCK
-
-config CD_NO_IDESCSI
-       bool "Support non-SCSI/IDE/ATAPI CDROM drives"
-       ---help---
-         If you have a CD-ROM drive that is neither SCSI nor IDE/ATAPI, say Y
-         here, otherwise N. Read the CD-ROM-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         Note that the answer to this question doesn't directly affect the
-         kernel: saying N will just cause the configurator to skip all
-         the questions about these CD-ROM drives. If you are unsure what you
-         have, say Y and find out whether you have one of the following
-         drives.
-
-         For each of these drivers, a <file:Documentation/cdrom/{driver_name}>
-         exists. Especially in cases where you do not know exactly which kind
-         of drive you have you should read there. Most of these drivers use a
-         file drivers/cdrom/{driver_name}.h where you can define your
-         interface parameters and switch some internal goodies.
-
-         To compile these CD-ROM drivers as a module, choose M instead of Y.
-
-         If you want to use any of these CD-ROM drivers, you also have to
-         answer Y or M to "ISO 9660 CD-ROM file system support" below (this
-         answer will get "defaulted" for you if you enable any of the Linux
-         CD-ROM drivers).
-
-config AZTCD
-       tristate "Aztech/Orchid/Okano/Wearnes/TXC/CyDROM  CDROM support"
-       depends on CD_NO_IDESCSI
-       ---help---
-         This is your driver if you have an Aztech CDA268-01A, Orchid
-         CD-3110, Okano or Wearnes CDD110, Conrad TXC, or CyCD-ROM CR520 or
-         CR540 CD-ROM drive.  This driver -- just like all these CD-ROM
-         drivers -- is NOT for CD-ROM drives with IDE/ATAPI interfaces, such
-         as Aztech CDA269-031SE. Please read the file
-         <file:Documentation/cdrom/aztcd>.
-
-         If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM
-         file system support" below, because that's the file system used on
-         CD-ROMs.
-
-         To compile this driver as a module, choose M here: the
-         module will be called aztcd.
-
-config GSCD
-       tristate "Goldstar R420 CDROM support"
-       depends on CD_NO_IDESCSI
-       ---help---
-         If this is your CD-ROM drive, say Y here.  As described in the file
-         <file:Documentation/cdrom/gscd>, you might have to change a setting
-         in the file <file:drivers/cdrom/gscd.h> before compiling the
-         kernel.  Please read the file <file:Documentation/cdrom/gscd>.
-
-         If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM
-         file system support" below, because that's the file system used on
-         CD-ROMs.
-
-         To compile this driver as a module, choose M here: the
-         module will be called gscd.
-
-config SBPCD
-       tristate "Matsushita/Panasonic/Creative, Longshine, TEAC CDROM support"
-       depends on CD_NO_IDESCSI && BROKEN_ON_SMP
-       ---help---
-         This driver supports most of the drives which use the Panasonic or
-         Sound Blaster interface.  Please read the file
-         <file:Documentation/cdrom/sbpcd>.
-
-         The Matsushita CR-521, CR-522, CR-523, CR-562, CR-563 drives
-         (sometimes labeled "Creative"), the Creative Labs CD200, the
-         Longshine LCS-7260, the "IBM External ISA CD-ROM" (in fact a CR-56x
-         model), the TEAC CD-55A fall under this category.  Some other
-         "electrically compatible" drives (Vertos, Genoa, some Funai models)
-         are currently not supported; for the Sanyo H94A drive currently a
-         separate driver (asked later) is responsible.  Most drives have a
-         uniquely shaped faceplate, with a caddyless motorized drawer, but
-         without external brand markings.  The older CR-52x drives have a
-         caddy and manual loading/eject, but still no external markings.  The
-         driver is able to do an extended auto-probing for interface
-         addresses and drive types; this can help to find facts in cases you
-         are not sure, but can consume some time during the boot process if
-         none of the supported drives gets found.  Once your drive got found,
-         you should enter the reported parameters into
-         <file:drivers/cdrom/sbpcd.h> and set "DISTRIBUTION 0" there.
-
-         This driver can support up to four CD-ROM controller cards, and each
-         card can support up to four CD-ROM drives; if you say Y here, you
-         will be asked how many controller cards you have.  If compiled as a
-         module, only one controller card (but with up to four drives) is
-         usable.
-
-         If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM
-         file system support" below, because that's the file system used on
-         CD-ROMs.
-
-         To compile this driver as a module, choose M here: the
-         module will be called sbpcd.
-
-config MCDX
-       tristate "Mitsumi CDROM support"
-       depends on CD_NO_IDESCSI
-       ---help---
-         Use this driver if you want to be able to use your Mitsumi LU-005,
-         FX-001 or FX-001D CD-ROM drive.
-
-         Please read the file <file:Documentation/cdrom/mcdx>.
-
-         If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM
-         file system support" below, because that's the file system used on
-         CD-ROMs.
-
-         To compile this driver as a module, choose M here: the
-         module will be called mcdx.
-
-config OPTCD
-       tristate "Optics Storage DOLPHIN 8000AT CDROM support"
-       depends on CD_NO_IDESCSI
-       ---help---
-         This is the driver for the 'DOLPHIN' drive with a 34-pin Sony
-         compatible interface. It also works with the Lasermate CR328A. If
-         you have one of those, say Y. This driver does not work for the
-         Optics Storage 8001 drive; use the IDE-ATAPI CD-ROM driver for that
-         one. Please read the file <file:Documentation/cdrom/optcd>.
-
-         If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM
-         file system support" below, because that's the file system used on
-         CD-ROMs.
-
-         To compile this driver as a module, choose M here: the
-         module will be called optcd.
-
-config CM206
-       tristate "Philips/LMS CM206 CDROM support"
-       depends on CD_NO_IDESCSI && BROKEN_ON_SMP
-       ---help---
-         If you have a Philips/LMS CD-ROM drive cm206 in combination with a
-         cm260 host adapter card, say Y here. Please also read the file
-         <file:Documentation/cdrom/cm206>.
-
-         If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM
-         file system support" below, because that's the file system used on
-         CD-ROMs.
-
-         To compile this driver as a module, choose M here: the
-         module will be called cm206.
-
-config SJCD
-       tristate "Sanyo CDR-H94A CDROM support"
-       depends on CD_NO_IDESCSI
-       help
-         If this is your CD-ROM drive, say Y here and read the file
-         <file:Documentation/cdrom/sjcd>. You should then also say Y or M to
-         "ISO 9660 CD-ROM file system support" below, because that's the
-         file system used on CD-ROMs.
-
-         To compile this driver as a module, choose M here: the
-         module will be called sjcd.
-
-config ISP16_CDI
-       tristate "ISP16/MAD16/Mozart soft configurable cdrom interface support"
-       depends on CD_NO_IDESCSI
-       ---help---
-         These are sound cards with built-in cdrom interfaces using the OPTi
-         82C928 or 82C929 chips. Say Y here to have them detected and
-         possibly configured at boot time. In addition, You'll have to say Y
-         to a driver for the particular cdrom drive you have attached to the
-         card. Read <file:Documentation/cdrom/isp16> for details.
-
-         To compile this driver as a module, choose M here: the
-         module will be called isp16.
-
-config CDU31A
-       tristate "Sony CDU31A/CDU33A CDROM support"
-       depends on CD_NO_IDESCSI && BROKEN_ON_SMP
-       ---help---
-         These CD-ROM drives have a spring-pop-out caddyless drawer, and a
-         rectangular green LED centered beneath it.  NOTE: these CD-ROM
-         drives will not be auto detected by the kernel at boot time; you
-         have to provide the interface address as an option to the kernel at
-         boot time as described in <file:Documentation/cdrom/cdu31a> or fill
-         in your parameters into <file:drivers/cdrom/cdu31a.c>.  Try "man
-         bootparam" or see the documentation of your boot loader (lilo or
-         loadlin) about how to pass options to the kernel.
-
-         If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM
-         file system support" below, because that's the file system used on
-         CD-ROMs.
-
-         To compile this driver as a module, choose M here: the
-         module will be called cdu31a.
-
-config CDU535
-       tristate "Sony CDU535 CDROM support"
-       depends on CD_NO_IDESCSI
-       ---help---
-         This is the driver for the older Sony CDU-535 and CDU-531 CD-ROM
-         drives. Please read the file <file:Documentation/cdrom/sonycd535>.
-
-         If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM
-         file system support" below, because that's the file system used on
-         CD-ROMs.
-
-         To compile this driver as a module, choose M here: the
-         module will be called sonycd535.
-
-endmenu
index d1d1e5a4be73b846dc9df2a5efde9fcf1928405c..774c180a4e11c66fedb272218d591b859a219ee0 100644 (file)
@@ -10,14 +10,4 @@ obj-$(CONFIG_BLK_DEV_SR)     +=              cdrom.o
 obj-$(CONFIG_PARIDE_PCD)       +=              cdrom.o
 obj-$(CONFIG_CDROM_PKTCDVD)    +=              cdrom.o
 
-obj-$(CONFIG_AZTCD)            += aztcd.o
-obj-$(CONFIG_CDU31A)           += cdu31a.o     cdrom.o
-obj-$(CONFIG_CM206)            += cm206.o      cdrom.o
-obj-$(CONFIG_GSCD)             += gscd.o
-obj-$(CONFIG_ISP16_CDI)                += isp16.o
-obj-$(CONFIG_MCDX)             += mcdx.o       cdrom.o
-obj-$(CONFIG_OPTCD)            += optcd.o
-obj-$(CONFIG_SBPCD)            += sbpcd.o      cdrom.o
-obj-$(CONFIG_SJCD)             += sjcd.o
-obj-$(CONFIG_CDU535)           += sonycd535.o
 obj-$(CONFIG_VIOCD)            += viocd.o      cdrom.o
diff --git a/drivers/cdrom/aztcd.c b/drivers/cdrom/aztcd.c
deleted file mode 100644 (file)
index 1f9fb7a..0000000
+++ /dev/null
@@ -1,2492 +0,0 @@
-#define AZT_VERSION "2.60"
-
-/*      $Id: aztcd.c,v 2.60 1997/11/29 09:51:19 root Exp root $
-       linux/drivers/block/aztcd.c - Aztech CD268 CDROM driver
-
-       Copyright (C) 1994-98 Werner Zimmermann(Werner.Zimmermann@fht-esslingen.de)
-
-       based on Mitsumi CDROM driver by  Martin Hariss and preworks by
-       Eberhard Moenkeberg; contains contributions by Joe Nardone and Robby 
-       Schirmer.
-
-       This program is free software; you can redistribute 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.
-
-       HISTORY
-       V0.0    Adaption to Aztech CD268-01A Version 1.3
-               Version is PRE_ALPHA, unresolved points:
-               1. I use busy wait instead of timer wait in STEN_LOW,DTEN_LOW
-                  thus driver causes CPU overhead and is very slow 
-               2. could not find a way to stop the drive, when it is
-                  in data read mode, therefore I had to set
-                  msf.end.min/sec/frame to 0:0:1 (in azt_poll); so only one
-                  frame can be read in sequence, this is also the reason for
-               3. getting 'timeout in state 4' messages, but nevertheless
-                  it works
-               W.Zimmermann, Oct. 31, 1994
-       V0.1    Version is ALPHA, problems #2 and #3 resolved.  
-               W.Zimmermann, Nov. 3, 1994
-       V0.2    Modification to some comments, debugging aids for partial test
-               with Borland C under DOS eliminated. Timer interrupt wait 
-               STEN_LOW_WAIT additionally to busy wait for STEN_LOW implemented; 
-               use it only for the 'slow' commands (ACMD_GET_Q_CHANNEL, ACMD_
-               SEEK_TO_LEAD_IN), all other commands are so 'fast', that busy 
-               waiting seems better to me than interrupt rescheduling.
-               Besides that, when used in the wrong place, STEN_LOW_WAIT causes
-               kernel panic.
-               In function aztPlay command ACMD_PLAY_AUDIO added, should make
-               audio functions work. The Aztech drive needs different commands
-               to read data tracks and play audio tracks.
-               W.Zimmermann, Nov. 8, 1994
-       V0.3    Recognition of missing drive during boot up improved (speeded up).
-               W.Zimmermann, Nov. 13, 1994
-       V0.35   Rewrote the control mechanism in azt_poll (formerly mcd_poll) 
-               including removal of all 'goto' commands. :-); 
-               J. Nardone, Nov. 14, 1994
-       V0.4    Renamed variables and constants to 'azt' instead of 'mcd'; had
-               to make some "compatibility" defines in azt.h; please note,
-               that the source file was renamed to azt.c, the include file to
-               azt.h                
-               Speeded up drive recognition during init (will be a little bit 
-               slower than before if no drive is installed!); suggested by
-               Robby Schirmer.
-               read_count declared volatile and set to AZT_BUF_SIZ to make
-               drive faster (now 300kB/sec, was 60kB/sec before, measured
-               by 'time dd if=/dev/cdrom of=/dev/null bs=2048 count=4096';
-               different AZT_BUF_SIZes were test, above 16 no further im-
-               provement seems to be possible; suggested by E.Moenkeberg.
-               W.Zimmermann, Nov. 18, 1994
-       V0.42   Included getAztStatus command in GetQChannelInfo() to allow
-               reading Q-channel info on audio disks, if drive is stopped, 
-               and some other bug fixes in the audio stuff, suggested by 
-               Robby Schirmer.
-               Added more ioctls (reading data in mode 1 and mode 2).
-               Completely removed the old azt_poll() routine.
-               Detection of ORCHID CDS-3110 in aztcd_init implemented.
-               Additional debugging aids (see the readme file).
-               W.Zimmermann, Dec. 9, 1994  
-       V0.50   Autodetection of drives implemented.
-               W.Zimmermann, Dec. 12, 1994
-       V0.52   Prepared for including in the standard kernel, renamed most
-               variables to contain 'azt', included autoconf.h
-               W.Zimmermann, Dec. 16, 1994        
-       V0.6    Version for being included in the standard Linux kernel.
-               Renamed source and header file to aztcd.c and aztcd.h
-               W.Zimmermann, Dec. 24, 1994
-       V0.7    Changed VERIFY_READ to VERIFY_WRITE in aztcd_ioctl, case
-               CDROMREADMODE1 and CDROMREADMODE2; bug fix in the ioctl,
-               which causes kernel crashes when playing audio, changed 
-               include-files (config.h instead of autoconf.h, removed
-               delay.h)
-               W.Zimmermann, Jan. 8, 1995
-       V0.72   Some more modifications for adaption to the standard kernel.
-               W.Zimmermann, Jan. 16, 1995
-        V0.80   aztcd is now part of the standard kernel since version 1.1.83.
-                Modified the SET_TIMER and CLEAR_TIMER macros to comply with
-                the new timer scheme.
-                W.Zimmermann, Jan. 21, 1995
-        V0.90   Included CDROMVOLCTRL, but with my Aztech drive I can only turn
-                the channels on and off. If it works better with your drive, 
-                please mail me. Also implemented ACMD_CLOSE for CDROMSTART.
-                W.Zimmermann, Jan. 24, 1995
-        V1.00   Implemented close and lock tray commands. Patches supplied by
-               Frank Racis        
-                Added support for loadable MODULEs, so aztcd can now also be
-                loaded by insmod and removed by rmmod during run time
-                Werner Zimmermann, Mar. 24, 95
-        V1.10   Implemented soundcard configuration for Orchid CDS-3110 drives
-                connected to Soundwave32 cards. Release for LST 2.1.
-                (still experimental)
-                Werner Zimmermann, May 8, 95
-        V1.20   Implemented limited support for DOSEMU0.60's cdrom.c. Now it works, but
-                sometimes DOSEMU may hang for 30 seconds or so. A fully functional ver-
-                sion needs an update of Dosemu0.60's cdrom.c, which will come with the 
-                next revision of Dosemu.
-                Also Soundwave32 support now works.
-                Werner Zimmermann, May 22, 95
-       V1.30   Auto-eject feature. Inspired by Franc Racis (racis@psu.edu)
-               Werner Zimmermann, July 4, 95
-       V1.40   Started multisession support. Implementation copied from mcdx.c
-               by Heiko Schlittermann. Not tested yet.
-               Werner Zimmermann, July 15, 95
-        V1.50   Implementation of ioctl CDROMRESET, continued multisession, began
-                XA, but still untested. Heavy modifications to drive status de-
-                tection.
-                Werner Zimmermann, July 25, 95
-        V1.60   XA support now should work. Speeded up drive recognition in cases, 
-                where no drive is installed.
-                Werner Zimmermann, August 8, 1995
-        V1.70   Multisession support now is completed, but there is still not 
-                enough testing done. If you can test it, please contact me. For
-                details please read Documentation/cdrom/aztcd
-                Werner Zimmermann, August 19, 1995
-        V1.80   Modification to suit the new kernel boot procedure introduced
-                with kernel 1.3.33. Will definitely not work with older kernels.
-                Programming done by Linus himself.
-                Werner Zimmermann, October 11, 1995
-       V1.90   Support for Conrad TXC drives, thank's to Jochen Kunz and Olaf Kaluza.
-               Werner Zimmermann, October 21, 1995
-        V2.00   Changed #include "blk.h" to <linux/blk.h> as the directory
-                structure was changed. README.aztcd is now /usr/src/docu-
-                mentation/cdrom/aztcd
-                Werner Zimmermann, November 10, 95
-        V2.10   Started to modify azt_poll to prevent reading beyond end of
-                tracks.
-                Werner Zimmermann, December 3, 95
-        V2.20   Changed some comments
-                Werner Zimmermann, April 1, 96
-        V2.30   Implemented support for CyCDROM CR520, CR940, Code for CR520 
-               delivered by H.Berger with preworks by E.Moenkeberg.
-                Werner Zimmermann, April 29, 96
-        V2.40   Reorganized the placement of functions in the source code file
-                to reflect the layered approach; did not actually change code
-                Werner Zimmermann, May 1, 96
-        V2.50   Heiko Eissfeldt suggested to remove some VERIFY_READs in 
-                aztcd_ioctl; check_aztcd_media_change modified 
-                Werner Zimmermann, May 16, 96       
-       V2.60   Implemented Auto-Probing; made changes for kernel's 2.1.xx blocksize
-                Adaption to linux kernel > 2.1.0
-               Werner Zimmermann, Nov 29, 97
-               
-        November 1999 -- Make kernel-parameter implementation work with 2.3.x 
-                        Removed init_module & cleanup_module in favor of 
-                        module_init & module_exit.
-                        Torben Mathiasen <tmm@image.dk>
-*/
-
-#include <linux/blkdev.h>
-#include "aztcd.h"
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/mm.h>
-#include <linux/timer.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/cdrom.h>
-#include <linux/ioport.h>
-#include <linux/string.h>
-#include <linux/major.h>
-
-#include <linux/init.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-
-#include <asm/uaccess.h>
-
-/*###########################################################################
-  Defines
-  ###########################################################################
-*/
-
-#define MAJOR_NR AZTECH_CDROM_MAJOR
-#define QUEUE (azt_queue)
-#define CURRENT elv_next_request(azt_queue)
-#define SET_TIMER(func, jifs)   delay_timer.expires = jiffies + (jifs); \
-                                delay_timer.function = (void *) (func); \
-                                add_timer(&delay_timer);
-
-#define CLEAR_TIMER             del_timer(&delay_timer);
-
-#define RETURNM(message,value) {printk("aztcd: Warning: %s failed\n",message);\
-                                return value;}
-#define RETURN(message)        {printk("aztcd: Warning: %s failed\n",message);\
-                                return;}
-
-/* Macros to switch the IDE-interface to the slave device and back to the master*/
-#define SWITCH_IDE_SLAVE  outb_p(0xa0,azt_port+6); \
-                         outb_p(0x10,azt_port+6); \
-                         outb_p(0x00,azt_port+7); \
-                         outb_p(0x10,azt_port+6);
-#define SWITCH_IDE_MASTER outb_p(0xa0,azt_port+6);
-
-
-#if 0
-#define AZT_TEST
-#define AZT_TEST1              /* <int-..> */
-#define AZT_TEST2              /* do_aztcd_request */
-#define AZT_TEST3              /* AZT_S_state */
-#define AZT_TEST4              /* QUICK_LOOP-counter */
-#define AZT_TEST5              /* port(1) state */
-#define AZT_DEBUG
-#define AZT_DEBUG_MULTISESSION
-#endif
-
-static struct request_queue *azt_queue;
-
-static int current_valid(void)
-{
-        return CURRENT &&
-               CURRENT->cmd == READ &&
-               CURRENT->sector != -1;
-}
-
-#define AFL_STATUSorDATA (AFL_STATUS | AFL_DATA)
-#define AZT_BUF_SIZ 16
-
-#define READ_TIMEOUT 3000
-
-#define azt_port aztcd         /*needed for the modutils */
-
-/*##########################################################################
-  Type Definitions
-  ##########################################################################
-*/
-enum azt_state_e { AZT_S_IDLE, /* 0 */
-       AZT_S_START,            /* 1 */
-       AZT_S_MODE,             /* 2 */
-       AZT_S_READ,             /* 3 */
-       AZT_S_DATA,             /* 4 */
-       AZT_S_STOP,             /* 5 */
-       AZT_S_STOPPING          /* 6 */
-};
-enum azt_read_modes { AZT_MODE_0,      /*read mode for audio disks, not supported by Aztech firmware */
-       AZT_MODE_1,             /*read mode for normal CD-ROMs */
-       AZT_MODE_2              /*read mode for XA CD-ROMs */
-};
-
-/*##########################################################################
-  Global Variables
-  ##########################################################################
-*/
-static int aztPresent = 0;
-
-static volatile int azt_transfer_is_active = 0;
-
-static char azt_buf[CD_FRAMESIZE_RAW * AZT_BUF_SIZ];   /*buffer for block size conversion */
-#if AZT_PRIVATE_IOCTLS
-static char buf[CD_FRAMESIZE_RAW];     /*separate buffer for the ioctls */
-#endif
-
-static volatile int azt_buf_bn[AZT_BUF_SIZ], azt_next_bn;
-static volatile int azt_buf_in, azt_buf_out = -1;
-static volatile int azt_error = 0;
-static int azt_open_count = 0;
-static volatile enum azt_state_e azt_state = AZT_S_IDLE;
-#ifdef AZT_TEST3
-static volatile enum azt_state_e azt_state_old = AZT_S_STOP;
-static volatile int azt_st_old = 0;
-#endif
-static volatile enum azt_read_modes azt_read_mode = AZT_MODE_1;
-
-static int azt_mode = -1;
-static volatile int azt_read_count = 1;
-
-static int azt_port = AZT_BASE_ADDR;
-
-module_param(azt_port, int, 0);
-
-static int azt_port_auto[16] = AZT_BASE_AUTO;
-
-static char azt_cont = 0;
-static char azt_init_end = 0;
-static char azt_auto_eject = AZT_AUTO_EJECT;
-
-static int AztTimeout, AztTries;
-static DECLARE_WAIT_QUEUE_HEAD(azt_waitq);
-static DEFINE_TIMER(delay_timer, NULL, 0, 0);
-
-static struct azt_DiskInfo DiskInfo;
-static struct azt_Toc Toc[MAX_TRACKS];
-static struct azt_Play_msf azt_Play;
-
-static int aztAudioStatus = CDROM_AUDIO_NO_STATUS;
-static char aztDiskChanged = 1;
-static char aztTocUpToDate = 0;
-
-static unsigned char aztIndatum;
-static unsigned long aztTimeOutCount;
-static int aztCmd = 0;
-
-static DEFINE_SPINLOCK(aztSpin);
-
-/*###########################################################################
-   Function Prototypes
-  ###########################################################################
-*/
-/* CDROM Drive Low Level I/O Functions */
-static void aztStatTimer(void);
-
-/* CDROM Drive Command Functions */
-static int aztGetDiskInfo(void);
-#if AZT_MULTISESSION
-static int aztGetMultiDiskInfo(void);
-#endif
-static int aztGetToc(int multi);
-
-/* Kernel Interface Functions */
-static int check_aztcd_media_change(struct gendisk *disk);
-static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
-                      unsigned long arg);
-static int aztcd_open(struct inode *ip, struct file *fp);
-static int aztcd_release(struct inode *inode, struct file *file);
-
-static struct block_device_operations azt_fops = {
-       .owner          = THIS_MODULE,
-       .open           = aztcd_open,
-       .release        = aztcd_release,
-       .ioctl          = aztcd_ioctl,
-       .media_changed  = check_aztcd_media_change,
-};
-
-/* Aztcd State Machine: Controls Drive Operating State */
-static void azt_poll(void);
-
-/* Miscellaneous support functions */
-static void azt_hsg2msf(long hsg, struct msf *msf);
-static long azt_msf2hsg(struct msf *mp);
-static void azt_bin2bcd(unsigned char *p);
-static int azt_bcd2bin(unsigned char bcd);
-
-/*##########################################################################
-  CDROM Drive Low Level I/O Functions
-  ##########################################################################
-*/
-/* Macros for the drive hardware interface handshake, these macros use
-   busy waiting */
-/* Wait for OP_OK = drive answers with AFL_OP_OK after receiving a command*/
-# define OP_OK op_ok()
-static void op_ok(void)
-{
-       aztTimeOutCount = 0;
-       do {
-               aztIndatum = inb(DATA_PORT);
-               aztTimeOutCount++;
-               if (aztTimeOutCount >= AZT_TIMEOUT) {
-                       printk("aztcd: Error Wait OP_OK\n");
-                       break;
-               }
-       } while (aztIndatum != AFL_OP_OK);
-}
-
-/* Wait for PA_OK = drive answers with AFL_PA_OK after receiving parameters*/
-#if 0
-# define PA_OK pa_ok()
-static void pa_ok(void)
-{
-       aztTimeOutCount = 0;
-       do {
-               aztIndatum = inb(DATA_PORT);
-               aztTimeOutCount++;
-               if (aztTimeOutCount >= AZT_TIMEOUT) {
-                       printk("aztcd: Error Wait PA_OK\n");
-                       break;
-               }
-       } while (aztIndatum != AFL_PA_OK);
-}
-#endif
-
-/* Wait for STEN=Low = handshake signal 'AFL_.._OK available or command executed*/
-# define STEN_LOW  sten_low()
-static void sten_low(void)
-{
-       aztTimeOutCount = 0;
-       do {
-               aztIndatum = inb(STATUS_PORT);
-               aztTimeOutCount++;
-               if (aztTimeOutCount >= AZT_TIMEOUT) {
-                       if (azt_init_end)
-                               printk
-                                   ("aztcd: Error Wait STEN_LOW commands:%x\n",
-                                    aztCmd);
-                       break;
-               }
-       } while (aztIndatum & AFL_STATUS);
-}
-
-/* Wait for DTEN=Low = handshake signal 'Data available'*/
-# define DTEN_LOW dten_low()
-static void dten_low(void)
-{
-       aztTimeOutCount = 0;
-       do {
-               aztIndatum = inb(STATUS_PORT);
-               aztTimeOutCount++;
-               if (aztTimeOutCount >= AZT_TIMEOUT) {
-                       printk("aztcd: Error Wait DTEN_OK\n");
-                       break;
-               }
-       } while (aztIndatum & AFL_DATA);
-}
-
-/* 
- * Macro for timer wait on STEN=Low, should only be used for 'slow' commands;
- * may cause kernel panic when used in the wrong place
-*/
-#define STEN_LOW_WAIT   statusAzt()
-static void statusAzt(void)
-{
-       AztTimeout = AZT_STATUS_DELAY;
-       SET_TIMER(aztStatTimer, HZ / 100);
-       sleep_on(&azt_waitq);
-       if (AztTimeout <= 0)
-               printk("aztcd: Error Wait STEN_LOW_WAIT command:%x\n",
-                      aztCmd);
-       return;
-}
-
-static void aztStatTimer(void)
-{
-       if (!(inb(STATUS_PORT) & AFL_STATUS)) {
-               wake_up(&azt_waitq);
-               return;
-       }
-       AztTimeout--;
-       if (AztTimeout <= 0) {
-               wake_up(&azt_waitq);
-               printk("aztcd: Error aztStatTimer: Timeout\n");
-               return;
-       }
-       SET_TIMER(aztStatTimer, HZ / 100);
-}
-
-/*##########################################################################
-  CDROM Drive Command Functions
-  ##########################################################################
-*/
-/* 
- * Send a single command, return -1 on error, else 0
-*/
-static int aztSendCmd(int cmd)
-{
-       unsigned char data;
-       int retry;
-
-#ifdef AZT_DEBUG
-       printk("aztcd: Executing command %x\n", cmd);
-#endif
-
-       if ((azt_port == 0x1f0) || (azt_port == 0x170))
-               SWITCH_IDE_SLAVE;       /*switch IDE interface to slave configuration */
-
-       aztCmd = cmd;
-       outb(POLLED, MODE_PORT);
-       do {
-               if (inb(STATUS_PORT) & AFL_STATUS)
-                       break;
-               inb(DATA_PORT); /* if status left from last command, read and */
-       } while (1);            /* discard it */
-       do {
-               if (inb(STATUS_PORT) & AFL_DATA)
-                       break;
-               inb(DATA_PORT); /* if data left from last command, read and */
-       } while (1);            /* discard it */
-       for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
-               outb((unsigned char) cmd, CMD_PORT);
-               STEN_LOW;
-               data = inb(DATA_PORT);
-               if (data == AFL_OP_OK) {
-                       return 0;
-               }               /*OP_OK? */
-               if (data == AFL_OP_ERR) {
-                       STEN_LOW;
-                       data = inb(DATA_PORT);
-                       printk
-                           ("### Error 1 aztcd: aztSendCmd %x  Error Code %x\n",
-                            cmd, data);
-               }
-       }
-       if (retry >= AZT_RETRY_ATTEMPTS) {
-               printk("### Error 2 aztcd: aztSendCmd %x \n", cmd);
-               azt_error = 0xA5;
-       }
-       RETURNM("aztSendCmd", -1);
-}
-
-/*
- * Send a play or read command to the drive, return -1 on error, else 0
-*/
-static int sendAztCmd(int cmd, struct azt_Play_msf *params)
-{
-       unsigned char data;
-       int retry;
-
-#ifdef AZT_DEBUG
-       printk("aztcd: play start=%02x:%02x:%02x  end=%02x:%02x:%02x\n",
-              params->start.min, params->start.sec, params->start.frame,
-              params->end.min, params->end.sec, params->end.frame);
-#endif
-       for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
-               aztSendCmd(cmd);
-               outb(params->start.min, CMD_PORT);
-               outb(params->start.sec, CMD_PORT);
-               outb(params->start.frame, CMD_PORT);
-               outb(params->end.min, CMD_PORT);
-               outb(params->end.sec, CMD_PORT);
-               outb(params->end.frame, CMD_PORT);
-               STEN_LOW;
-               data = inb(DATA_PORT);
-               if (data == AFL_PA_OK) {
-                       return 0;
-               }               /*PA_OK ? */
-               if (data == AFL_PA_ERR) {
-                       STEN_LOW;
-                       data = inb(DATA_PORT);
-                       printk
-                           ("### Error 1 aztcd: sendAztCmd %x  Error Code %x\n",
-                            cmd, data);
-               }
-       }
-       if (retry >= AZT_RETRY_ATTEMPTS) {
-               printk("### Error 2 aztcd: sendAztCmd %x\n ", cmd);
-               azt_error = 0xA5;
-       }
-       RETURNM("sendAztCmd", -1);
-}
-
-/*
- * Send a seek command to the drive, return -1 on error, else 0
-*/
-static int aztSeek(struct azt_Play_msf *params)
-{
-       unsigned char data;
-       int retry;
-
-#ifdef AZT_DEBUG
-       printk("aztcd: aztSeek %02x:%02x:%02x\n",
-              params->start.min, params->start.sec, params->start.frame);
-#endif
-       for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
-               aztSendCmd(ACMD_SEEK);
-               outb(params->start.min, CMD_PORT);
-               outb(params->start.sec, CMD_PORT);
-               outb(params->start.frame, CMD_PORT);
-               STEN_LOW;
-               data = inb(DATA_PORT);
-               if (data == AFL_PA_OK) {
-                       return 0;
-               }               /*PA_OK ? */
-               if (data == AFL_PA_ERR) {
-                       STEN_LOW;
-                       data = inb(DATA_PORT);
-                       printk("### Error 1 aztcd: aztSeek\n");
-               }
-       }
-       if (retry >= AZT_RETRY_ATTEMPTS) {
-               printk("### Error 2 aztcd: aztSeek\n ");
-               azt_error = 0xA5;
-       }
-       RETURNM("aztSeek", -1);
-}
-
-/* Send a Set Disk Type command
-   does not seem to work with Aztech drives, behavior is completely indepen-
-   dent on which mode is set ???
-*/
-static int aztSetDiskType(int type)
-{
-       unsigned char data;
-       int retry;
-
-#ifdef AZT_DEBUG
-       printk("aztcd: set disk type command: type= %i\n", type);
-#endif
-       for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
-               aztSendCmd(ACMD_SET_DISK_TYPE);
-               outb(type, CMD_PORT);
-               STEN_LOW;
-               data = inb(DATA_PORT);
-               if (data == AFL_PA_OK) {        /*PA_OK ? */
-                       azt_read_mode = type;
-                       return 0;
-               }
-               if (data == AFL_PA_ERR) {
-                       STEN_LOW;
-                       data = inb(DATA_PORT);
-                       printk
-                           ("### Error 1 aztcd: aztSetDiskType %x Error Code %x\n",
-                            type, data);
-               }
-       }
-       if (retry >= AZT_RETRY_ATTEMPTS) {
-               printk("### Error 2 aztcd: aztSetDiskType %x\n ", type);
-               azt_error = 0xA5;
-       }
-       RETURNM("aztSetDiskType", -1);
-}
-
-
-/* used in azt_poll to poll the status, expects another program to issue a 
- * ACMD_GET_STATUS directly before 
- */
-static int aztStatus(void)
-{
-       int st;
-/*     int i;
-
-       i = inb(STATUS_PORT) & AFL_STATUS;    is STEN=0?    ???
-       if (!i)
-*/ STEN_LOW;
-       if (aztTimeOutCount < AZT_TIMEOUT) {
-               st = inb(DATA_PORT) & 0xFF;
-               return st;
-       } else
-               RETURNM("aztStatus", -1);
-}
-
-/*
- * Get the drive status
- */
-static int getAztStatus(void)
-{
-       int st;
-
-       if (aztSendCmd(ACMD_GET_STATUS))
-               RETURNM("getAztStatus 1", -1);
-       STEN_LOW;
-       st = inb(DATA_PORT) & 0xFF;
-#ifdef AZT_DEBUG
-       printk("aztcd: Status = %x\n", st);
-#endif
-       if ((st == 0xFF) || (st & AST_CMD_CHECK)) {
-               printk
-                   ("aztcd: AST_CMD_CHECK error or no status available\n");
-               return -1;
-       }
-
-       if (((st & AST_MODE_BITS) != AST_BUSY)
-           && (aztAudioStatus == CDROM_AUDIO_PLAY))
-               /* XXX might be an error? look at q-channel? */
-               aztAudioStatus = CDROM_AUDIO_COMPLETED;
-
-       if ((st & AST_DSK_CHG) || (st & AST_NOT_READY)) {
-               aztDiskChanged = 1;
-               aztTocUpToDate = 0;
-               aztAudioStatus = CDROM_AUDIO_NO_STATUS;
-       }
-       return st;
-}
-
-
-/*
- * Send a 'Play' command and get the status.  Use only from the top half.
- */
-static int aztPlay(struct azt_Play_msf *arg)
-{
-       if (sendAztCmd(ACMD_PLAY_AUDIO, arg) < 0)
-               RETURNM("aztPlay", -1);
-       return 0;
-}
-
-/*
- * Subroutines to automatically close the door (tray) and 
- * lock it closed when the cd is mounted.  Leave the tray
- * locking as an option
- */
-static void aztCloseDoor(void)
-{
-       aztSendCmd(ACMD_CLOSE);
-       STEN_LOW;
-       return;
-}
-
-static void aztLockDoor(void)
-{
-#if AZT_ALLOW_TRAY_LOCK
-       aztSendCmd(ACMD_LOCK);
-       STEN_LOW;
-#endif
-       return;
-}
-
-static void aztUnlockDoor(void)
-{
-#if AZT_ALLOW_TRAY_LOCK
-       aztSendCmd(ACMD_UNLOCK);
-       STEN_LOW;
-#endif
-       return;
-}
-
-/*
- * Read a value from the drive.  Should return quickly, so a busy wait
- * is used to avoid excessive rescheduling. The read command itself must
- * be issued with aztSendCmd() directly before
- */
-static int aztGetValue(unsigned char *result)
-{
-       int s;
-
-       STEN_LOW;
-       if (aztTimeOutCount >= AZT_TIMEOUT) {
-               printk("aztcd: aztGetValue timeout\n");
-               return -1;
-       }
-       s = inb(DATA_PORT) & 0xFF;
-       *result = (unsigned char) s;
-       return 0;
-}
-
-/*
- * Read the current Q-channel info.  Also used for reading the
- * table of contents.
- */
-static int aztGetQChannelInfo(struct azt_Toc *qp)
-{
-       unsigned char notUsed;
-       int st;
-
-#ifdef AZT_DEBUG
-       printk("aztcd: starting aztGetQChannelInfo  Time:%li\n", jiffies);
-#endif
-       if ((st = getAztStatus()) == -1)
-               RETURNM("aztGetQChannelInfo 1", -1);
-       if (aztSendCmd(ACMD_GET_Q_CHANNEL))
-               RETURNM("aztGetQChannelInfo 2", -1);
-       /*STEN_LOW_WAIT; ??? Dosemu0.60's cdrom.c does not like STEN_LOW_WAIT here */
-       if (aztGetValue(&notUsed))
-               RETURNM("aztGetQChannelInfo 3", -1);    /*??? Nullbyte einlesen */
-       if ((st & AST_MODE_BITS) == AST_INITIAL) {
-               qp->ctrl_addr = 0;      /* when audio stop ACMD_GET_Q_CHANNEL returns */
-               qp->track = 0;  /* only one byte with Aztech drives */
-               qp->pointIndex = 0;
-               qp->trackTime.min = 0;
-               qp->trackTime.sec = 0;
-               qp->trackTime.frame = 0;
-               qp->diskTime.min = 0;
-               qp->diskTime.sec = 0;
-               qp->diskTime.frame = 0;
-               return 0;
-       } else {
-               if (aztGetValue(&qp->ctrl_addr) < 0)
-                       RETURNM("aztGetQChannelInfo 4", -1);
-               if (aztGetValue(&qp->track) < 0)
-                       RETURNM("aztGetQChannelInfo 4", -1);
-               if (aztGetValue(&qp->pointIndex) < 0)
-                       RETURNM("aztGetQChannelInfo 4", -1);
-               if (aztGetValue(&qp->trackTime.min) < 0)
-                       RETURNM("aztGetQChannelInfo 4", -1);
-               if (aztGetValue(&qp->trackTime.sec) < 0)
-                       RETURNM("aztGetQChannelInfo 4", -1);
-               if (aztGetValue(&qp->trackTime.frame) < 0)
-                       RETURNM("aztGetQChannelInfo 4", -1);
-               if (aztGetValue(&notUsed) < 0)
-                       RETURNM("aztGetQChannelInfo 4", -1);
-               if (aztGetValue(&qp->diskTime.min) < 0)
-                       RETURNM("aztGetQChannelInfo 4", -1);
-               if (aztGetValue(&qp->diskTime.sec) < 0)
-                       RETURNM("aztGetQChannelInfo 4", -1);
-               if (aztGetValue(&qp->diskTime.frame) < 0)
-                       RETURNM("aztGetQChannelInfo 4", -1);
-       }
-#ifdef AZT_DEBUG
-       printk("aztcd: exiting aztGetQChannelInfo  Time:%li\n", jiffies);
-#endif
-       return 0;
-}
-
-/*
- * Read the table of contents (TOC) and TOC header if necessary
- */
-static int aztUpdateToc(void)
-{
-       int st;
-
-#ifdef AZT_DEBUG
-       printk("aztcd: starting aztUpdateToc  Time:%li\n", jiffies);
-#endif
-       if (aztTocUpToDate)
-               return 0;
-
-       if (aztGetDiskInfo() < 0)
-               return -EIO;
-
-       if (aztGetToc(0) < 0)
-               return -EIO;
-
-       /*audio disk detection
-          with my Aztech drive there is no audio status bit, so I use the copy
-          protection bit of the first track. If this track is copy protected 
-          (copy bit = 0), I assume, it's an audio  disk. Strange, but works ??? */
-       if (!(Toc[DiskInfo.first].ctrl_addr & 0x40))
-               DiskInfo.audio = 1;
-       else
-               DiskInfo.audio = 0;
-
-       /* XA detection */
-       if (!DiskInfo.audio) {
-               azt_Play.start.min = 0; /*XA detection only seems to work */
-               azt_Play.start.sec = 2; /*when we play a track */
-               azt_Play.start.frame = 0;
-               azt_Play.end.min = 0;
-               azt_Play.end.sec = 0;
-               azt_Play.end.frame = 1;
-               if (sendAztCmd(ACMD_PLAY_READ, &azt_Play))
-                       return -1;
-               DTEN_LOW;
-               for (st = 0; st < CD_FRAMESIZE; st++)
-                       inb(DATA_PORT);
-       }
-       DiskInfo.xa = getAztStatus() & AST_MODE;
-       if (DiskInfo.xa) {
-               printk
-                   ("aztcd: XA support experimental - mail results to Werner.Zimmermann@fht-esslingen.de\n");
-       }
-
-       /*multisession detection
-          support for multisession CDs is done automatically with Aztech drives,
-          we don't have to take care about TOC redirection; if we want the isofs
-          to take care about redirection, we have to set AZT_MULTISESSION to 1 */
-       DiskInfo.multi = 0;
-#if AZT_MULTISESSION
-       if (DiskInfo.xa) {
-               aztGetMultiDiskInfo();  /*here Disk.Info.multi is set */
-       }
-#endif
-       if (DiskInfo.multi) {
-               DiskInfo.lastSession.min = Toc[DiskInfo.next].diskTime.min;
-               DiskInfo.lastSession.sec = Toc[DiskInfo.next].diskTime.sec;
-               DiskInfo.lastSession.frame =
-                   Toc[DiskInfo.next].diskTime.frame;
-               printk("aztcd: Multisession support experimental\n");
-       } else {
-               DiskInfo.lastSession.min =
-                   Toc[DiskInfo.first].diskTime.min;
-               DiskInfo.lastSession.sec =
-                   Toc[DiskInfo.first].diskTime.sec;
-               DiskInfo.lastSession.frame =
-                   Toc[DiskInfo.first].diskTime.frame;
-       }
-
-       aztTocUpToDate = 1;
-#ifdef AZT_DEBUG
-       printk("aztcd: exiting aztUpdateToc  Time:%li\n", jiffies);
-#endif
-       return 0;
-}
-
-
-/* Read the table of contents header, i.e. no. of tracks and start of first 
- * track
- */
-static int aztGetDiskInfo(void)
-{
-       int limit;
-       unsigned char test;
-       struct azt_Toc qInfo;
-
-#ifdef AZT_DEBUG
-       printk("aztcd: starting aztGetDiskInfo  Time:%li\n", jiffies);
-#endif
-       if (aztSendCmd(ACMD_SEEK_TO_LEADIN))
-               RETURNM("aztGetDiskInfo 1", -1);
-       STEN_LOW_WAIT;
-       test = 0;
-       for (limit = 300; limit > 0; limit--) {
-               if (aztGetQChannelInfo(&qInfo) < 0)
-                       RETURNM("aztGetDiskInfo 2", -1);
-               if (qInfo.pointIndex == 0xA0) { /*Number of FirstTrack */
-                       DiskInfo.first = qInfo.diskTime.min;
-                       DiskInfo.first = azt_bcd2bin(DiskInfo.first);
-                       test = test | 0x01;
-               }
-               if (qInfo.pointIndex == 0xA1) { /*Number of LastTrack */
-                       DiskInfo.last = qInfo.diskTime.min;
-                       DiskInfo.last = azt_bcd2bin(DiskInfo.last);
-                       test = test | 0x02;
-               }
-               if (qInfo.pointIndex == 0xA2) { /*DiskLength */
-                       DiskInfo.diskLength.min = qInfo.diskTime.min;
-                       DiskInfo.diskLength.sec = qInfo.diskTime.sec;
-                       DiskInfo.diskLength.frame = qInfo.diskTime.frame;
-                       test = test | 0x04;
-               }
-               if ((qInfo.pointIndex == DiskInfo.first) && (test & 0x01)) {    /*StartTime of First Track */
-                       DiskInfo.firstTrack.min = qInfo.diskTime.min;
-                       DiskInfo.firstTrack.sec = qInfo.diskTime.sec;
-                       DiskInfo.firstTrack.frame = qInfo.diskTime.frame;
-                       test = test | 0x08;
-               }
-               if (test == 0x0F)
-                       break;
-       }
-#ifdef AZT_DEBUG
-       printk("aztcd: exiting aztGetDiskInfo  Time:%li\n", jiffies);
-       printk
-           ("Disk Info: first %d last %d length %02X:%02X.%02X dez  first %02X:%02X.%02X dez\n",
-            DiskInfo.first, DiskInfo.last, DiskInfo.diskLength.min,
-            DiskInfo.diskLength.sec, DiskInfo.diskLength.frame,
-            DiskInfo.firstTrack.min, DiskInfo.firstTrack.sec,
-            DiskInfo.firstTrack.frame);
-#endif
-       if (test != 0x0F)
-               return -1;
-       return 0;
-}
-
-#if AZT_MULTISESSION
-/*
- * Get Multisession Disk Info
- */
-static int aztGetMultiDiskInfo(void)
-{
-       int limit, k = 5;
-       unsigned char test;
-       struct azt_Toc qInfo;
-
-#ifdef AZT_DEBUG
-       printk("aztcd: starting aztGetMultiDiskInfo\n");
-#endif
-
-       do {
-               azt_Play.start.min = Toc[DiskInfo.last + 1].diskTime.min;
-               azt_Play.start.sec = Toc[DiskInfo.last + 1].diskTime.sec;
-               azt_Play.start.frame =
-                   Toc[DiskInfo.last + 1].diskTime.frame;
-               test = 0;
-
-               for (limit = 30; limit > 0; limit--) {  /*Seek for LeadIn of next session */
-                       if (aztSeek(&azt_Play))
-                               RETURNM("aztGetMultiDiskInfo 1", -1);
-                       if (aztGetQChannelInfo(&qInfo) < 0)
-                               RETURNM("aztGetMultiDiskInfo 2", -1);
-                       if ((qInfo.track == 0) && (qInfo.pointIndex))
-                               break;  /*LeadIn found */
-                       if ((azt_Play.start.sec += 10) > 59) {
-                               azt_Play.start.sec = 0;
-                               azt_Play.start.min++;
-                       }
-               }
-               if (!limit)
-                       break;  /*Check, if a leadin track was found, if not we're
-                                  at the end of the disk */
-#ifdef AZT_DEBUG_MULTISESSION
-               printk("leadin found track %d  pointIndex %x  limit %d\n",
-                      qInfo.track, qInfo.pointIndex, limit);
-#endif
-               for (limit = 300; limit > 0; limit--) {
-                       if (++azt_Play.start.frame > 74) {
-                               azt_Play.start.frame = 0;
-                               if (azt_Play.start.sec > 59) {
-                                       azt_Play.start.sec = 0;
-                                       azt_Play.start.min++;
-                               }
-                       }
-                       if (aztSeek(&azt_Play))
-                               RETURNM("aztGetMultiDiskInfo 3", -1);
-                       if (aztGetQChannelInfo(&qInfo) < 0)
-                               RETURNM("aztGetMultiDiskInfo 4", -1);
-                       if (qInfo.pointIndex == 0xA0) { /*Number of NextTrack */
-                               DiskInfo.next = qInfo.diskTime.min;
-                               DiskInfo.next = azt_bcd2bin(DiskInfo.next);
-                               test = test | 0x01;
-                       }
-                       if (qInfo.pointIndex == 0xA1) { /*Number of LastTrack */
-                               DiskInfo.last = qInfo.diskTime.min;
-                               DiskInfo.last = azt_bcd2bin(DiskInfo.last);
-                               test = test | 0x02;
-                       }
-                       if (qInfo.pointIndex == 0xA2) { /*DiskLength */
-                               DiskInfo.diskLength.min =
-                                   qInfo.diskTime.min;
-                               DiskInfo.diskLength.sec =
-                                   qInfo.diskTime.sec;
-                               DiskInfo.diskLength.frame =
-                                   qInfo.diskTime.frame;
-                               test = test | 0x04;
-                       }
-                       if ((qInfo.pointIndex == DiskInfo.next) && (test & 0x01)) {     /*StartTime of Next Track */
-                               DiskInfo.nextSession.min =
-                                   qInfo.diskTime.min;
-                               DiskInfo.nextSession.sec =
-                                   qInfo.diskTime.sec;
-                               DiskInfo.nextSession.frame =
-                                   qInfo.diskTime.frame;
-                               test = test | 0x08;
-                       }
-                       if (test == 0x0F)
-                               break;
-               }
-#ifdef AZT_DEBUG_MULTISESSION
-               printk
-                   ("MultiDisk Info: first %d next %d last %d length %02x:%02x.%02x dez  first %02x:%02x.%02x dez  next %02x:%02x.%02x dez\n",
-                    DiskInfo.first, DiskInfo.next, DiskInfo.last,
-                    DiskInfo.diskLength.min, DiskInfo.diskLength.sec,
-                    DiskInfo.diskLength.frame, DiskInfo.firstTrack.min,
-                    DiskInfo.firstTrack.sec, DiskInfo.firstTrack.frame,
-                    DiskInfo.nextSession.min, DiskInfo.nextSession.sec,
-                    DiskInfo.nextSession.frame);
-#endif
-               if (test != 0x0F)
-                       break;
-               else
-                       DiskInfo.multi = 1;     /*found TOC of more than one session */
-               aztGetToc(1);
-       } while (--k);
-
-#ifdef AZT_DEBUG
-       printk("aztcd: exiting aztGetMultiDiskInfo  Time:%li\n", jiffies);
-#endif
-       return 0;
-}
-#endif
-
-/*
- * Read the table of contents (TOC)
- */
-static int aztGetToc(int multi)
-{
-       int i, px;
-       int limit;
-       struct azt_Toc qInfo;
-
-#ifdef AZT_DEBUG
-       printk("aztcd: starting aztGetToc  Time:%li\n", jiffies);
-#endif
-       if (!multi) {
-               for (i = 0; i < MAX_TRACKS; i++)
-                       Toc[i].pointIndex = 0;
-               i = DiskInfo.last + 3;
-       } else {
-               for (i = DiskInfo.next; i < MAX_TRACKS; i++)
-                       Toc[i].pointIndex = 0;
-               i = DiskInfo.last + 4 - DiskInfo.next;
-       }
-
-/*Is there a good reason to stop motor before TOC read?
-  if (aztSendCmd(ACMD_STOP)) RETURNM("aztGetToc 1",-1);
-      STEN_LOW_WAIT;
-*/
-
-       if (!multi) {
-               azt_mode = 0x05;
-               if (aztSendCmd(ACMD_SEEK_TO_LEADIN))
-                       RETURNM("aztGetToc 2", -1);
-               STEN_LOW_WAIT;
-       }
-       for (limit = 300; limit > 0; limit--) {
-               if (multi) {
-                       if (++azt_Play.start.sec > 59) {
-                               azt_Play.start.sec = 0;
-                               azt_Play.start.min++;
-                       }
-                       if (aztSeek(&azt_Play))
-                               RETURNM("aztGetToc 3", -1);
-               }
-               if (aztGetQChannelInfo(&qInfo) < 0)
-                       break;
-
-               px = azt_bcd2bin(qInfo.pointIndex);
-
-               if (px > 0 && px < MAX_TRACKS && qInfo.track == 0)
-                       if (Toc[px].pointIndex == 0) {
-                               Toc[px] = qInfo;
-                               i--;
-                       }
-
-               if (i <= 0)
-                       break;
-       }
-
-       Toc[DiskInfo.last + 1].diskTime = DiskInfo.diskLength;
-       Toc[DiskInfo.last].trackTime = DiskInfo.diskLength;
-
-#ifdef AZT_DEBUG_MULTISESSION
-       printk("aztcd: exiting aztGetToc\n");
-       for (i = 1; i <= DiskInfo.last + 1; i++)
-               printk
-                   ("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X dez  %02X:%02X.%02X dez\n",
-                    i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
-                    Toc[i].trackTime.min, Toc[i].trackTime.sec,
-                    Toc[i].trackTime.frame, Toc[i].diskTime.min,
-                    Toc[i].diskTime.sec, Toc[i].diskTime.frame);
-       for (i = 100; i < 103; i++)
-               printk
-                   ("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X dez  %02X:%02X.%02X dez\n",
-                    i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
-                    Toc[i].trackTime.min, Toc[i].trackTime.sec,
-                    Toc[i].trackTime.frame, Toc[i].diskTime.min,
-                    Toc[i].diskTime.sec, Toc[i].diskTime.frame);
-#endif
-
-       return limit > 0 ? 0 : -1;
-}
-
-
-/*##########################################################################
-  Kernel Interface Functions
-  ##########################################################################
-*/
-
-#ifndef MODULE
-static int __init aztcd_setup(char *str)
-{
-       int ints[4];
-
-       (void) get_options(str, ARRAY_SIZE(ints), ints);
-
-       if (ints[0] > 0)
-               azt_port = ints[1];
-       if (ints[1] > 1)
-               azt_cont = ints[2];
-       return 1;
-}
-
-__setup("aztcd=", aztcd_setup);
-
-#endif                         /* !MODULE */
-
-/* 
- * Checking if the media has been changed
-*/
-static int check_aztcd_media_change(struct gendisk *disk)
-{
-       if (aztDiskChanged) {   /* disk changed */
-               aztDiskChanged = 0;
-               return 1;
-       } else
-               return 0;       /* no change */
-}
-
-/*
- * Kernel IO-controls
-*/
-static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
-                      unsigned long arg)
-{
-       int i;
-       struct azt_Toc qInfo;
-       struct cdrom_ti ti;
-       struct cdrom_tochdr tocHdr;
-       struct cdrom_msf msf;
-       struct cdrom_tocentry entry;
-       struct azt_Toc *tocPtr;
-       struct cdrom_subchnl subchnl;
-       struct cdrom_volctrl volctrl;
-       void __user *argp = (void __user *)arg;
-
-#ifdef AZT_DEBUG
-       printk("aztcd: starting aztcd_ioctl - Command:%x   Time: %li\n",
-              cmd, jiffies);
-       printk("aztcd Status %x\n", getAztStatus());
-#endif
-       if (!ip)
-               RETURNM("aztcd_ioctl 1", -EINVAL);
-       if (getAztStatus() < 0)
-               RETURNM("aztcd_ioctl 2", -EIO);
-       if ((!aztTocUpToDate) || (aztDiskChanged)) {
-               if ((i = aztUpdateToc()) < 0)
-                       RETURNM("aztcd_ioctl 3", i);    /* error reading TOC */
-       }
-
-       switch (cmd) {
-       case CDROMSTART:        /* Spin up the drive. Don't know, what to do,
-                                  at least close the tray */
-#if AZT_PRIVATE_IOCTLS
-               if (aztSendCmd(ACMD_CLOSE))
-                       RETURNM("aztcd_ioctl 4", -1);
-               STEN_LOW_WAIT;
-#endif
-               break;
-       case CDROMSTOP: /* Spin down the drive */
-               if (aztSendCmd(ACMD_STOP))
-                       RETURNM("aztcd_ioctl 5", -1);
-               STEN_LOW_WAIT;
-               /* should we do anything if it fails? */
-               aztAudioStatus = CDROM_AUDIO_NO_STATUS;
-               break;
-       case CDROMPAUSE:        /* Pause the drive */
-               if (aztAudioStatus != CDROM_AUDIO_PLAY)
-                       return -EINVAL;
-
-               if (aztGetQChannelInfo(&qInfo) < 0) {   /* didn't get q channel info */
-                       aztAudioStatus = CDROM_AUDIO_NO_STATUS;
-                       RETURNM("aztcd_ioctl 7", 0);
-               }
-               azt_Play.start = qInfo.diskTime;        /* remember restart point */
-
-               if (aztSendCmd(ACMD_PAUSE))
-                       RETURNM("aztcd_ioctl 8", -1);
-               STEN_LOW_WAIT;
-               aztAudioStatus = CDROM_AUDIO_PAUSED;
-               break;
-       case CDROMRESUME:       /* Play it again, Sam */
-               if (aztAudioStatus != CDROM_AUDIO_PAUSED)
-                       return -EINVAL;
-               /* restart the drive at the saved position. */
-               i = aztPlay(&azt_Play);
-               if (i < 0) {
-                       aztAudioStatus = CDROM_AUDIO_ERROR;
-                       return -EIO;
-               }
-               aztAudioStatus = CDROM_AUDIO_PLAY;
-               break;
-       case CDROMMULTISESSION: /*multisession support -- experimental */
-               {
-                       struct cdrom_multisession ms;
-#ifdef AZT_DEBUG
-                       printk("aztcd ioctl MULTISESSION\n");
-#endif
-                       if (copy_from_user(&ms, argp,
-                            sizeof(struct cdrom_multisession)))
-                               return -EFAULT;
-                       if (ms.addr_format == CDROM_MSF) {
-                               ms.addr.msf.minute =
-                                   azt_bcd2bin(DiskInfo.lastSession.min);
-                               ms.addr.msf.second =
-                                   azt_bcd2bin(DiskInfo.lastSession.sec);
-                               ms.addr.msf.frame =
-                                   azt_bcd2bin(DiskInfo.lastSession.
-                                               frame);
-                       } else if (ms.addr_format == CDROM_LBA)
-                               ms.addr.lba =
-                                   azt_msf2hsg(&DiskInfo.lastSession);
-                       else
-                               return -EINVAL;
-                       ms.xa_flag = DiskInfo.xa;
-                       if (copy_to_user(argp, &ms,
-                            sizeof(struct cdrom_multisession)))
-                               return -EFAULT;
-#ifdef AZT_DEBUG
-                       if (ms.addr_format == CDROM_MSF)
-                               printk
-                                   ("aztcd multisession xa:%d, msf:%02x:%02x.%02x [%02x:%02x.%02x])\n",
-                                    ms.xa_flag, ms.addr.msf.minute,
-                                    ms.addr.msf.second, ms.addr.msf.frame,
-                                    DiskInfo.lastSession.min,
-                                    DiskInfo.lastSession.sec,
-                                    DiskInfo.lastSession.frame);
-                       else
-                               printk
-                                   ("aztcd multisession %d, lba:0x%08x [%02x:%02x.%02x])\n",
-                                    ms.xa_flag, ms.addr.lba,
-                                    DiskInfo.lastSession.min,
-                                    DiskInfo.lastSession.sec,
-                                    DiskInfo.lastSession.frame);
-#endif
-                       return 0;
-               }
-       case CDROMPLAYTRKIND:   /* Play a track.  This currently ignores index. */
-               if (copy_from_user(&ti, argp, sizeof ti))
-                       return -EFAULT;
-               if (ti.cdti_trk0 < DiskInfo.first
-                   || ti.cdti_trk0 > DiskInfo.last
-                   || ti.cdti_trk1 < ti.cdti_trk0) {
-                       return -EINVAL;
-               }
-               if (ti.cdti_trk1 > DiskInfo.last)
-                       ti.cdti_trk1 = DiskInfo.last;
-               azt_Play.start = Toc[ti.cdti_trk0].diskTime;
-               azt_Play.end = Toc[ti.cdti_trk1 + 1].diskTime;
-#ifdef AZT_DEBUG
-               printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
-                      azt_Play.start.min, azt_Play.start.sec,
-                      azt_Play.start.frame, azt_Play.end.min,
-                      azt_Play.end.sec, azt_Play.end.frame);
-#endif
-               i = aztPlay(&azt_Play);
-               if (i < 0) {
-                       aztAudioStatus = CDROM_AUDIO_ERROR;
-                       return -EIO;
-               }
-               aztAudioStatus = CDROM_AUDIO_PLAY;
-               break;
-       case CDROMPLAYMSF:      /* Play starting at the given MSF address. */
-/*              if (aztAudioStatus == CDROM_AUDIO_PLAY) 
-               { if (aztSendCmd(ACMD_STOP)) RETURNM("aztcd_ioctl 9",-1);
-                 STEN_LOW;
-                 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
-               }
-*/
-               if (copy_from_user(&msf, argp, sizeof msf))
-                       return -EFAULT;
-               /* convert to bcd */
-               azt_bin2bcd(&msf.cdmsf_min0);
-               azt_bin2bcd(&msf.cdmsf_sec0);
-               azt_bin2bcd(&msf.cdmsf_frame0);
-               azt_bin2bcd(&msf.cdmsf_min1);
-               azt_bin2bcd(&msf.cdmsf_sec1);
-               azt_bin2bcd(&msf.cdmsf_frame1);
-               azt_Play.start.min = msf.cdmsf_min0;
-               azt_Play.start.sec = msf.cdmsf_sec0;
-               azt_Play.start.frame = msf.cdmsf_frame0;
-               azt_Play.end.min = msf.cdmsf_min1;
-               azt_Play.end.sec = msf.cdmsf_sec1;
-               azt_Play.end.frame = msf.cdmsf_frame1;
-#ifdef AZT_DEBUG
-               printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
-                      azt_Play.start.min, azt_Play.start.sec,
-                      azt_Play.start.frame, azt_Play.end.min,
-                      azt_Play.end.sec, azt_Play.end.frame);
-#endif
-               i = aztPlay(&azt_Play);
-               if (i < 0) {
-                       aztAudioStatus = CDROM_AUDIO_ERROR;
-                       return -EIO;
-               }
-               aztAudioStatus = CDROM_AUDIO_PLAY;
-               break;
-
-       case CDROMREADTOCHDR:   /* Read the table of contents header */
-               tocHdr.cdth_trk0 = DiskInfo.first;
-               tocHdr.cdth_trk1 = DiskInfo.last;
-               if (copy_to_user(argp, &tocHdr, sizeof tocHdr))
-                       return -EFAULT;
-               break;
-       case CDROMREADTOCENTRY: /* Read an entry in the table of contents */
-               if (copy_from_user(&entry, argp, sizeof entry))
-                       return -EFAULT;
-               if ((!aztTocUpToDate) || aztDiskChanged)
-                       aztUpdateToc();
-               if (entry.cdte_track == CDROM_LEADOUT)
-                       tocPtr = &Toc[DiskInfo.last + 1];
-               else if (entry.cdte_track > DiskInfo.last
-                        || entry.cdte_track < DiskInfo.first) {
-                       return -EINVAL;
-               } else
-                       tocPtr = &Toc[entry.cdte_track];
-               entry.cdte_adr = tocPtr->ctrl_addr;
-               entry.cdte_ctrl = tocPtr->ctrl_addr >> 4;
-               if (entry.cdte_format == CDROM_LBA)
-                       entry.cdte_addr.lba =
-                           azt_msf2hsg(&tocPtr->diskTime);
-               else if (entry.cdte_format == CDROM_MSF) {
-                       entry.cdte_addr.msf.minute =
-                           azt_bcd2bin(tocPtr->diskTime.min);
-                       entry.cdte_addr.msf.second =
-                           azt_bcd2bin(tocPtr->diskTime.sec);
-                       entry.cdte_addr.msf.frame =
-                           azt_bcd2bin(tocPtr->diskTime.frame);
-               } else {
-                       return -EINVAL;
-               }
-               if (copy_to_user(argp, &entry, sizeof entry))
-                       return -EFAULT;
-               break;
-       case CDROMSUBCHNL:      /* Get subchannel info */
-               if (copy_from_user
-                   (&subchnl, argp, sizeof(struct cdrom_subchnl)))
-                       return -EFAULT;
-               if (aztGetQChannelInfo(&qInfo) < 0) {
-#ifdef AZT_DEBUG
-                       printk
-                           ("aztcd: exiting aztcd_ioctl - Error 3 - Command:%x\n",
-                            cmd);
-#endif
-                       return -EIO;
-               }
-               subchnl.cdsc_audiostatus = aztAudioStatus;
-               subchnl.cdsc_adr = qInfo.ctrl_addr;
-               subchnl.cdsc_ctrl = qInfo.ctrl_addr >> 4;
-               subchnl.cdsc_trk = azt_bcd2bin(qInfo.track);
-               subchnl.cdsc_ind = azt_bcd2bin(qInfo.pointIndex);
-               if (subchnl.cdsc_format == CDROM_LBA) {
-                       subchnl.cdsc_absaddr.lba =
-                           azt_msf2hsg(&qInfo.diskTime);
-                       subchnl.cdsc_reladdr.lba =
-                           azt_msf2hsg(&qInfo.trackTime);
-               } else {        /*default */
-                       subchnl.cdsc_format = CDROM_MSF;
-                       subchnl.cdsc_absaddr.msf.minute =
-                           azt_bcd2bin(qInfo.diskTime.min);
-                       subchnl.cdsc_absaddr.msf.second =
-                           azt_bcd2bin(qInfo.diskTime.sec);
-                       subchnl.cdsc_absaddr.msf.frame =
-                           azt_bcd2bin(qInfo.diskTime.frame);
-                       subchnl.cdsc_reladdr.msf.minute =
-                           azt_bcd2bin(qInfo.trackTime.min);
-                       subchnl.cdsc_reladdr.msf.second =
-                           azt_bcd2bin(qInfo.trackTime.sec);
-                       subchnl.cdsc_reladdr.msf.frame =
-                           azt_bcd2bin(qInfo.trackTime.frame);
-               }
-               if (copy_to_user(argp, &subchnl, sizeof(struct cdrom_subchnl)))
-                       return -EFAULT;
-               break;
-       case CDROMVOLCTRL:      /* Volume control 
-                                  * With my Aztech CD268-01A volume control does not work, I can only
-                                  turn the channels on (any value !=0) or off (value==0). Maybe it
-                                  works better with your drive */
-               if (copy_from_user(&volctrl, argp, sizeof(volctrl)))
-                       return -EFAULT;
-               azt_Play.start.min = 0x21;
-               azt_Play.start.sec = 0x84;
-               azt_Play.start.frame = volctrl.channel0;
-               azt_Play.end.min = volctrl.channel1;
-               azt_Play.end.sec = volctrl.channel2;
-               azt_Play.end.frame = volctrl.channel3;
-               sendAztCmd(ACMD_SET_VOLUME, &azt_Play);
-               STEN_LOW_WAIT;
-               break;
-       case CDROMEJECT:
-               aztUnlockDoor();        /* Assume user knows what they're doing */
-               /* all drives can at least stop! */
-               if (aztAudioStatus == CDROM_AUDIO_PLAY) {
-                       if (aztSendCmd(ACMD_STOP))
-                               RETURNM("azt_ioctl 10", -1);
-                       STEN_LOW_WAIT;
-               }
-               if (aztSendCmd(ACMD_EJECT))
-                       RETURNM("azt_ioctl 11", -1);
-               STEN_LOW_WAIT;
-               aztAudioStatus = CDROM_AUDIO_NO_STATUS;
-               break;
-       case CDROMEJECT_SW:
-               azt_auto_eject = (char) arg;
-               break;
-       case CDROMRESET:
-               outb(ACMD_SOFT_RESET, CMD_PORT);        /*send reset */
-               STEN_LOW;
-               if (inb(DATA_PORT) != AFL_OP_OK) {      /*OP_OK? */
-                       printk
-                           ("aztcd: AZTECH CD-ROM drive does not respond\n");
-               }
-               break;
-/*Take care, the following code is not compatible with other CD-ROM drivers,
-  use it at your own risk with cdplay.c. Set AZT_PRIVATE_IOCTLS to 0 in aztcd.h,
-  if you do not want to use it!
-*/
-#if AZT_PRIVATE_IOCTLS
-       case CDROMREADCOOKED:   /*read data in mode 1 (2048 Bytes) */
-       case CDROMREADRAW:      /*read data in mode 2 (2336 Bytes) */
-               {
-                       if (copy_from_user(&msf, argp, sizeof msf))
-                               return -EFAULT;
-                       /* convert to bcd */
-                       azt_bin2bcd(&msf.cdmsf_min0);
-                       azt_bin2bcd(&msf.cdmsf_sec0);
-                       azt_bin2bcd(&msf.cdmsf_frame0);
-                       msf.cdmsf_min1 = 0;
-                       msf.cdmsf_sec1 = 0;
-                       msf.cdmsf_frame1 = 1;   /*read only one frame */
-                       azt_Play.start.min = msf.cdmsf_min0;
-                       azt_Play.start.sec = msf.cdmsf_sec0;
-                       azt_Play.start.frame = msf.cdmsf_frame0;
-                       azt_Play.end.min = msf.cdmsf_min1;
-                       azt_Play.end.sec = msf.cdmsf_sec1;
-                       azt_Play.end.frame = msf.cdmsf_frame1;
-                       if (cmd == CDROMREADRAW) {
-                               if (DiskInfo.xa) {
-                                       return -1;      /*XA Disks can't be read raw */
-                               } else {
-                                       if (sendAztCmd(ACMD_PLAY_READ_RAW, &azt_Play))
-                                               return -1;
-                                       DTEN_LOW;
-                                       insb(DATA_PORT, buf, CD_FRAMESIZE_RAW);
-                                       if (copy_to_user(argp, &buf, CD_FRAMESIZE_RAW))
-                                               return -EFAULT;
-                               }
-                       } else
-                               /*CDROMREADCOOKED*/ {
-                               if (sendAztCmd(ACMD_PLAY_READ, &azt_Play))
-                                       return -1;
-                               DTEN_LOW;
-                               insb(DATA_PORT, buf, CD_FRAMESIZE);
-                               if (copy_to_user(argp, &buf, CD_FRAMESIZE))
-                                       return -EFAULT;
-                               }
-               }
-               break;
-       case CDROMSEEK: /*seek msf address */
-               if (copy_from_user(&msf, argp, sizeof msf))
-                       return -EFAULT;
-               /* convert to bcd */
-               azt_bin2bcd(&msf.cdmsf_min0);
-               azt_bin2bcd(&msf.cdmsf_sec0);
-               azt_bin2bcd(&msf.cdmsf_frame0);
-               azt_Play.start.min = msf.cdmsf_min0;
-               azt_Play.start.sec = msf.cdmsf_sec0;
-               azt_Play.start.frame = msf.cdmsf_frame0;
-               if (aztSeek(&azt_Play))
-                       return -1;
-               break;
-#endif                         /*end of incompatible code */
-       case CDROMREADMODE1:    /*set read data in mode 1 */
-               return aztSetDiskType(AZT_MODE_1);
-       case CDROMREADMODE2:    /*set read data in mode 2 */
-               return aztSetDiskType(AZT_MODE_2);
-       default:
-               return -EINVAL;
-       }
-#ifdef AZT_DEBUG
-       printk("aztcd: exiting aztcd_ioctl Command:%x  Time:%li\n", cmd,
-              jiffies);
-#endif
-       return 0;
-}
-
-/*
- * Take care of the different block sizes between cdrom and Linux.
- * When Linux gets variable block sizes this will probably go away.
- */
-static void azt_transfer(void)
-{
-#ifdef AZT_TEST
-       printk("aztcd: executing azt_transfer Time:%li\n", jiffies);
-#endif
-       if (!current_valid())
-               return;
-
-       while (CURRENT->nr_sectors) {
-               int bn = CURRENT->sector / 4;
-               int i;
-               for (i = 0; i < AZT_BUF_SIZ && azt_buf_bn[i] != bn; ++i);
-               if (i < AZT_BUF_SIZ) {
-                       int offs = (i * 4 + (CURRENT->sector & 3)) * 512;
-                       int nr_sectors = 4 - (CURRENT->sector & 3);
-                       if (azt_buf_out != i) {
-                               azt_buf_out = i;
-                               if (azt_buf_bn[i] != bn) {
-                                       azt_buf_out = -1;
-                                       continue;
-                               }
-                       }
-                       if (nr_sectors > CURRENT->nr_sectors)
-                           nr_sectors = CURRENT->nr_sectors;
-                       memcpy(CURRENT->buffer, azt_buf + offs,
-                               nr_sectors * 512);
-                       CURRENT->nr_sectors -= nr_sectors;
-                       CURRENT->sector += nr_sectors;
-                       CURRENT->buffer += nr_sectors * 512;
-               } else {
-                       azt_buf_out = -1;
-                       break;
-               }
-       }
-}
-
-static void do_aztcd_request(request_queue_t * q)
-{
-#ifdef AZT_TEST
-       printk(" do_aztcd_request(%ld+%ld) Time:%li\n", CURRENT->sector,
-              CURRENT->nr_sectors, jiffies);
-#endif
-       if (DiskInfo.audio) {
-               printk("aztcd: Error, tried to mount an Audio CD\n");
-               end_request(CURRENT, 0);
-               return;
-       }
-       azt_transfer_is_active = 1;
-       while (current_valid()) {
-               azt_transfer();
-               if (CURRENT->nr_sectors == 0) {
-                       end_request(CURRENT, 1);
-               } else {
-                       azt_buf_out = -1;       /* Want to read a block not in buffer */
-                       if (azt_state == AZT_S_IDLE) {
-                               if ((!aztTocUpToDate) || aztDiskChanged) {
-                                       if (aztUpdateToc() < 0) {
-                                               while (current_valid())
-                                                       end_request(CURRENT, 0);
-                                               break;
-                                       }
-                               }
-                               azt_state = AZT_S_START;
-                               AztTries = 5;
-                               SET_TIMER(azt_poll, HZ / 100);
-                       }
-                       break;
-               }
-       }
-       azt_transfer_is_active = 0;
-#ifdef AZT_TEST2
-       printk
-           ("azt_next_bn:%x  azt_buf_in:%x azt_buf_out:%x  azt_buf_bn:%x\n",
-            azt_next_bn, azt_buf_in, azt_buf_out, azt_buf_bn[azt_buf_in]);
-       printk(" do_aztcd_request ends  Time:%li\n", jiffies);
-#endif
-}
-
-
-static void azt_invalidate_buffers(void)
-{
-       int i;
-
-#ifdef AZT_DEBUG
-       printk("aztcd: executing azt_invalidate_buffers\n");
-#endif
-       for (i = 0; i < AZT_BUF_SIZ; ++i)
-               azt_buf_bn[i] = -1;
-       azt_buf_out = -1;
-}
-
-/*
- * Open the device special file.  Check that a disk is in.
- */
-static int aztcd_open(struct inode *ip, struct file *fp)
-{
-       int st;
-
-#ifdef AZT_DEBUG
-       printk("aztcd: starting aztcd_open\n");
-#endif
-
-       if (aztPresent == 0)
-               return -ENXIO;  /* no hardware */
-
-       if (!azt_open_count && azt_state == AZT_S_IDLE) {
-               azt_invalidate_buffers();
-
-               st = getAztStatus();    /* check drive status */
-               if (st == -1)
-                       goto err_out;   /* drive doesn't respond */
-
-               if (st & AST_DOOR_OPEN) {       /* close door, then get the status again. */
-                       printk("aztcd: Door Open?\n");
-                       aztCloseDoor();
-                       st = getAztStatus();
-               }
-
-               if ((st & AST_NOT_READY) || (st & AST_DSK_CHG)) {       /*no disk in drive or changed */
-                       printk
-                           ("aztcd: Disk Changed or No Disk in Drive?\n");
-                       aztTocUpToDate = 0;
-               }
-               if (aztUpdateToc())
-                       goto err_out;
-
-       }
-       ++azt_open_count;
-       aztLockDoor();
-
-#ifdef AZT_DEBUG
-       printk("aztcd: exiting aztcd_open\n");
-#endif
-       return 0;
-
-      err_out:
-       return -EIO;
-}
-
-
-/*
- * On close, we flush all azt blocks from the buffer cache.
- */
-static int aztcd_release(struct inode *inode, struct file *file)
-{
-#ifdef AZT_DEBUG
-       printk("aztcd: executing aztcd_release\n");
-       printk("inode: %p, device: %s    file: %p\n", inode,
-              inode->i_bdev->bd_disk->disk_name, file);
-#endif
-       if (!--azt_open_count) {
-               azt_invalidate_buffers();
-               aztUnlockDoor();
-               if (azt_auto_eject)
-                       aztSendCmd(ACMD_EJECT);
-               CLEAR_TIMER;
-       }
-       return 0;
-}
-
-static struct gendisk *azt_disk;
-
-/*
- * Test for presence of drive and initialize it.  Called at boot time.
- */
-
-static int __init aztcd_init(void)
-{
-       long int count, max_count;
-       unsigned char result[50];
-       int st;
-       void* status = NULL;
-       int i = 0;
-       int ret = 0;
-
-       if (azt_port == 0) {
-               printk(KERN_INFO "aztcd: no Aztech CD-ROM Initialization");
-               return -EIO;
-       }
-
-       printk(KERN_INFO "aztcd: AZTECH, ORCHID, OKANO, WEARNES, TXC, CyDROM "
-              "CD-ROM Driver\n");
-       printk(KERN_INFO "aztcd: (C) 1994-98 W.Zimmermann\n");
-       if (azt_port == -1) {
-               printk
-                   ("aztcd: DriverVersion=%s For IDE/ATAPI-drives use ide-cd.c\n",
-                    AZT_VERSION);
-       } else
-               printk
-                   ("aztcd: DriverVersion=%s BaseAddress=0x%x  For IDE/ATAPI-drives use ide-cd.c\n",
-                    AZT_VERSION, azt_port);
-       printk(KERN_INFO "aztcd: If you have problems, read /usr/src/linux/"
-              "Documentation/cdrom/aztcd\n");
-
-
-#ifdef AZT_SW32                        /*CDROM connected to Soundwave32 card */
-       if ((0xFF00 & inw(AZT_SW32_ID_REG)) != 0x4500) {
-               printk
-                   ("aztcd: no Soundwave32 card detected at base:%x init:%x config:%x id:%x\n",
-                    AZT_SW32_BASE_ADDR, AZT_SW32_INIT,
-                    AZT_SW32_CONFIG_REG, AZT_SW32_ID_REG);
-               return -EIO;
-       } else {
-               printk(KERN_INFO
-                      "aztcd: Soundwave32 card detected at %x  Version %x\n",
-                      AZT_SW32_BASE_ADDR, inw(AZT_SW32_ID_REG));
-               outw(AZT_SW32_INIT, AZT_SW32_CONFIG_REG);
-               for (count = 0; count < 10000; count++);        /*delay a bit */
-       }
-#endif
-
-       /* check for presence of drive */
-
-       if (azt_port == -1) {   /* autoprobing for proprietary interface  */
-               for (i = 0; (azt_port_auto[i] != 0) && (i < 16); i++) {
-                       azt_port = azt_port_auto[i];
-                       printk(KERN_INFO "aztcd: Autoprobing BaseAddress=0x%x"
-                              "\n", azt_port);
-                        /*proprietary interfaces need 4 bytes */
-                       if (!request_region(azt_port, 4, "aztcd")) {
-                               continue;
-                       }
-                       outb(POLLED, MODE_PORT);
-                       inb(CMD_PORT);
-                       inb(CMD_PORT);
-                       outb(ACMD_GET_VERSION, CMD_PORT);       /*Try to get version info */
-
-                       aztTimeOutCount = 0;
-                       do {
-                               aztIndatum = inb(STATUS_PORT);
-                               aztTimeOutCount++;
-                               if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
-                                       break;
-                       } while (aztIndatum & AFL_STATUS);
-                       if (inb(DATA_PORT) == AFL_OP_OK) { /* OK drive found */
-                               break;
-                       }
-                       else {  /* Drive not found on this port - try next one */
-                               release_region(azt_port, 4);
-                       }
-               }
-               if ((i == 16) || (azt_port_auto[i] == 0)) {
-                       printk(KERN_INFO "aztcd: no AZTECH CD-ROM drive found\n");
-                       return -EIO;
-               }
-       } else {                /* no autoprobing */
-               if ((azt_port == 0x1f0) || (azt_port == 0x170))
-                       status = request_region(azt_port, 8, "aztcd");  /*IDE-interfaces need 8 bytes */
-               else
-                       status = request_region(azt_port, 4, "aztcd");  /*proprietary interfaces need 4 bytes */
-               if (!status) {
-                       printk(KERN_WARNING "aztcd: conflict, I/O port (%X) "
-                              "already used\n", azt_port);
-                       return -EIO;
-               }
-
-               if ((azt_port == 0x1f0) || (azt_port == 0x170))
-                       SWITCH_IDE_SLAVE;       /*switch IDE interface to slave configuration */
-
-               outb(POLLED, MODE_PORT);
-               inb(CMD_PORT);
-               inb(CMD_PORT);
-               outb(ACMD_GET_VERSION, CMD_PORT);       /*Try to get version info */
-
-               aztTimeOutCount = 0;
-               do {
-                       aztIndatum = inb(STATUS_PORT);
-                       aztTimeOutCount++;
-                       if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
-                               break;
-               } while (aztIndatum & AFL_STATUS);
-
-               if (inb(DATA_PORT) != AFL_OP_OK) {      /*OP_OK? If not, reset and try again */
-#ifndef MODULE
-                       if (azt_cont != 0x79) {
-                               printk(KERN_WARNING "aztcd: no AZTECH CD-ROM "
-                                      "drive found-Try boot parameter aztcd="
-                                      "<BaseAddress>,0x79\n");
-                               ret = -EIO;
-                               goto err_out;
-                       }
-#else
-                       if (0) {
-                       }
-#endif
-                       else {
-                               printk(KERN_INFO "aztcd: drive reset - "
-                                      "please wait\n");
-                               for (count = 0; count < 50; count++) {
-                                       inb(STATUS_PORT);       /*removing all data from earlier tries */
-                                       inb(DATA_PORT);
-                               }
-                               outb(POLLED, MODE_PORT);
-                               inb(CMD_PORT);
-                               inb(CMD_PORT);
-                               getAztStatus(); /*trap errors */
-                               outb(ACMD_SOFT_RESET, CMD_PORT);        /*send reset */
-                               STEN_LOW;
-                               if (inb(DATA_PORT) != AFL_OP_OK) {      /*OP_OK? */
-                                       printk(KERN_WARNING "aztcd: no AZTECH "
-                                              "CD-ROM drive found\n");
-                                       ret = -EIO;
-                                       goto err_out;
-                               }
-
-                               for (count = 0; count < AZT_TIMEOUT;
-                                    count++)
-                                       barrier();      /* Stop gcc 2.96 being smart */
-                               /* use udelay(), damnit -- AV */
-
-                               if ((st = getAztStatus()) == -1) {
-                                       printk(KERN_WARNING "aztcd: Drive Status"
-                                              " Error Status=%x\n", st);
-                                       ret = -EIO;
-                                       goto err_out;
-                               }
-#ifdef AZT_DEBUG
-                               printk(KERN_DEBUG "aztcd: Status = %x\n", st);
-#endif
-                               outb(POLLED, MODE_PORT);
-                               inb(CMD_PORT);
-                               inb(CMD_PORT);
-                               outb(ACMD_GET_VERSION, CMD_PORT);       /*GetVersion */
-                               STEN_LOW;
-                               OP_OK;
-                       }
-               }
-       }
-
-       azt_init_end = 1;
-       STEN_LOW;
-       result[0] = inb(DATA_PORT);     /*reading in a null byte??? */
-       for (count = 1; count < 50; count++) {  /*Reading version string */
-               aztTimeOutCount = 0;    /*here we must implement STEN_LOW differently */
-               do {
-                       aztIndatum = inb(STATUS_PORT);  /*because we want to exit by timeout */
-                       aztTimeOutCount++;
-                       if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
-                               break;
-               } while (aztIndatum & AFL_STATUS);
-               if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
-                       break;  /*all chars read? */
-               result[count] = inb(DATA_PORT);
-       }
-       if (count > 30)
-               max_count = 30; /*print max.30 chars of the version string */
-       else
-               max_count = count;
-       printk(KERN_INFO "aztcd: FirmwareVersion=");
-       for (count = 1; count < max_count; count++)
-               printk("%c", result[count]);
-       printk("<<>> ");
-
-       if ((result[1] == 'A') && (result[2] == 'Z') && (result[3] == 'T')) {
-               printk("AZTECH drive detected\n");
-       /*AZTECH*/}
-               else if ((result[2] == 'C') && (result[3] == 'D')
-                        && (result[4] == 'D')) {
-               printk("ORCHID or WEARNES drive detected\n");   /*ORCHID or WEARNES */
-       } else if ((result[1] == 0x03) && (result[2] == '5')) {
-               printk("TXC or CyCDROM drive detected\n");      /*Conrad TXC, CyCDROM */
-       } else {                /*OTHERS or none */
-               printk("\nunknown drive or firmware version detected\n");
-               printk
-                   ("aztcd may not run stable, if you want to try anyhow,\n");
-               printk("boot with: aztcd=<BaseAddress>,0x79\n");
-               if ((azt_cont != 0x79)) {
-                       printk("aztcd: FirmwareVersion=");
-                       for (count = 1; count < 5; count++)
-                               printk("%c", result[count]);
-                       printk("<<>> ");
-                       printk("Aborted\n");
-                       ret = -EIO;
-                       goto err_out;
-               }
-       }
-       azt_disk = alloc_disk(1);
-       if (!azt_disk)
-               goto err_out;
-
-       if (register_blkdev(MAJOR_NR, "aztcd")) {
-               ret = -EIO;
-               goto err_out2;
-       }
-
-       azt_queue = blk_init_queue(do_aztcd_request, &aztSpin);
-       if (!azt_queue) {
-               ret = -ENOMEM;
-               goto err_out3;
-       }
-
-       blk_queue_hardsect_size(azt_queue, 2048);
-       azt_disk->major = MAJOR_NR;
-       azt_disk->first_minor = 0;
-       azt_disk->fops = &azt_fops;
-       sprintf(azt_disk->disk_name, "aztcd");
-       azt_disk->queue = azt_queue;
-       add_disk(azt_disk);
-       azt_invalidate_buffers();
-       aztPresent = 1;
-       aztCloseDoor();
-       return 0;
-err_out3:
-       unregister_blkdev(MAJOR_NR, "aztcd");
-err_out2:
-       put_disk(azt_disk);
-err_out:
-       if ((azt_port == 0x1f0) || (azt_port == 0x170)) {
-               SWITCH_IDE_MASTER;
-               release_region(azt_port, 8);    /*IDE-interface */
-       } else
-               release_region(azt_port, 4);    /*proprietary interface */
-       return ret;
-
-}
-
-static void __exit aztcd_exit(void)
-{
-       del_gendisk(azt_disk);
-       put_disk(azt_disk);
-       if ((unregister_blkdev(MAJOR_NR, "aztcd") == -EINVAL)) {
-               printk("What's that: can't unregister aztcd\n");
-               return;
-       }
-       blk_cleanup_queue(azt_queue);
-       if ((azt_port == 0x1f0) || (azt_port == 0x170)) {
-               SWITCH_IDE_MASTER;
-               release_region(azt_port, 8);    /*IDE-interface */
-       } else
-               release_region(azt_port, 4);    /*proprietary interface */
-       printk(KERN_INFO "aztcd module released.\n");
-}
-
-module_init(aztcd_init);
-module_exit(aztcd_exit);
-
-/*##########################################################################
-  Aztcd State Machine: Controls Drive Operating State
-  ##########################################################################
-*/
-static void azt_poll(void)
-{
-       int st = 0;
-       int loop_ctl = 1;
-       int skip = 0;
-
-       if (azt_error) {
-               if (aztSendCmd(ACMD_GET_ERROR))
-                       RETURN("azt_poll 1");
-               STEN_LOW;
-               azt_error = inb(DATA_PORT) & 0xFF;
-               printk("aztcd: I/O error 0x%02x\n", azt_error);
-               azt_invalidate_buffers();
-#ifdef WARN_IF_READ_FAILURE
-               if (AztTries == 5)
-                       printk
-                           ("aztcd: Read of Block %d Failed - Maybe Audio Disk?\n",
-                            azt_next_bn);
-#endif
-               if (!AztTries--) {
-                       printk
-                           ("aztcd: Read of Block %d Failed, Maybe Audio Disk? Giving up\n",
-                            azt_next_bn);
-                       if (azt_transfer_is_active) {
-                               AztTries = 0;
-                               loop_ctl = 0;
-                       }
-                       if (current_valid())
-                               end_request(CURRENT, 0);
-                       AztTries = 5;
-               }
-               azt_error = 0;
-               azt_state = AZT_S_STOP;
-       }
-
-       while (loop_ctl) {
-               loop_ctl = 0;   /* each case must flip this back to 1 if we want
-                                  to come back up here */
-               switch (azt_state) {
-
-               case AZT_S_IDLE:
-#ifdef AZT_TEST3
-                       if (azt_state != azt_state_old) {
-                               azt_state_old = azt_state;
-                               printk("AZT_S_IDLE\n");
-                       }
-#endif
-                       return;
-
-               case AZT_S_START:
-#ifdef AZT_TEST3
-                       if (azt_state != azt_state_old) {
-                               azt_state_old = azt_state;
-                               printk("AZT_S_START\n");
-                       }
-#endif
-                       if (aztSendCmd(ACMD_GET_STATUS))
-                               RETURN("azt_poll 2");   /*result will be checked by aztStatus() */
-                       azt_state =
-                           azt_mode == 1 ? AZT_S_READ : AZT_S_MODE;
-                       AztTimeout = 3000;
-                       break;
-
-               case AZT_S_MODE:
-#ifdef AZT_TEST3
-                       if (azt_state != azt_state_old) {
-                               azt_state_old = azt_state;
-                               printk("AZT_S_MODE\n");
-                       }
-#endif
-                       if (!skip) {
-                               if ((st = aztStatus()) != -1) {
-                                       if ((st & AST_DSK_CHG)
-                                           || (st & AST_NOT_READY)) {
-                                               aztDiskChanged = 1;
-                                               aztTocUpToDate = 0;
-                                               azt_invalidate_buffers();
-                                               end_request(CURRENT, 0);
-                                               printk
-                                                   ("aztcd: Disk Changed or Not Ready 1 - Unmount Disk!\n");
-                                       }
-                               } else
-                                       break;
-                       }
-                       skip = 0;
-
-                       if ((st & AST_DOOR_OPEN) || (st & AST_NOT_READY)) {
-                               aztDiskChanged = 1;
-                               aztTocUpToDate = 0;
-                               printk
-                                   ("aztcd: Disk Changed or Not Ready 2 - Unmount Disk!\n");
-                               end_request(CURRENT, 0);
-                               printk((st & AST_DOOR_OPEN) ?
-                                      "aztcd: door open\n" :
-                                      "aztcd: disk removed\n");
-                               if (azt_transfer_is_active) {
-                                       azt_state = AZT_S_START;
-                                       loop_ctl = 1;   /* goto immediately */
-                                       break;
-                               }
-                               azt_state = AZT_S_IDLE;
-                               while (current_valid())
-                                       end_request(CURRENT, 0);
-                               return;
-                       }
-
-/*       if (aztSendCmd(ACMD_SET_MODE)) RETURN("azt_poll 3");
-         outb(0x01, DATA_PORT);
-         PA_OK;
-         STEN_LOW;
-*/
-                       if (aztSendCmd(ACMD_GET_STATUS))
-                               RETURN("azt_poll 4");
-                       STEN_LOW;
-                       azt_mode = 1;
-                       azt_state = AZT_S_READ;
-                       AztTimeout = 3000;
-
-                       break;
-
-
-               case AZT_S_READ:
-#ifdef AZT_TEST3
-                       if (azt_state != azt_state_old) {
-                               azt_state_old = azt_state;
-                               printk("AZT_S_READ\n");
-                       }
-#endif
-                       if (!skip) {
-                               if ((st = aztStatus()) != -1) {
-                                       if ((st & AST_DSK_CHG)
-                                           || (st & AST_NOT_READY)) {
-                                               aztDiskChanged = 1;
-                                               aztTocUpToDate = 0;
-                                               azt_invalidate_buffers();
-                                               printk
-                                                   ("aztcd: Disk Changed or Not Ready 3 - Unmount Disk!\n");
-                                               end_request(CURRENT, 0);
-                                       }
-                               } else
-                                       break;
-                       }
-
-                       skip = 0;
-                       if ((st & AST_DOOR_OPEN) || (st & AST_NOT_READY)) {
-                               aztDiskChanged = 1;
-                               aztTocUpToDate = 0;
-                               printk((st & AST_DOOR_OPEN) ?
-                                      "aztcd: door open\n" :
-                                      "aztcd: disk removed\n");
-                               if (azt_transfer_is_active) {
-                                       azt_state = AZT_S_START;
-                                       loop_ctl = 1;
-                                       break;
-                               }
-                               azt_state = AZT_S_IDLE;
-                               while (current_valid())
-                                       end_request(CURRENT, 0);
-                               return;
-                       }
-
-                       if (current_valid()) {
-                               struct azt_Play_msf msf;
-                               int i;
-                               azt_next_bn = CURRENT->sector / 4;
-                               azt_hsg2msf(azt_next_bn, &msf.start);
-                               i = 0;
-                               /* find out in which track we are */
-                               while (azt_msf2hsg(&msf.start) >
-                                      azt_msf2hsg(&Toc[++i].trackTime)) {
-                               };
-                               if (azt_msf2hsg(&msf.start) <
-                                   azt_msf2hsg(&Toc[i].trackTime) -
-                                   AZT_BUF_SIZ) {
-                                       azt_read_count = AZT_BUF_SIZ;   /*fast, because we read ahead */
-                                       /*azt_read_count=CURRENT->nr_sectors;    slow, no read ahead */
-                               } else  /* don't read beyond end of track */
-#if AZT_MULTISESSION
-                               {
-                                       azt_read_count =
-                                           (azt_msf2hsg(&Toc[i].trackTime)
-                                            / 4) * 4 -
-                                           azt_msf2hsg(&msf.start);
-                                       if (azt_read_count < 0)
-                                               azt_read_count = 0;
-                                       if (azt_read_count > AZT_BUF_SIZ)
-                                               azt_read_count =
-                                                   AZT_BUF_SIZ;
-                                       printk
-                                           ("aztcd: warning - trying to read beyond end of track\n");
-/*               printk("%i %i %li %li\n",i,azt_read_count,azt_msf2hsg(&msf.start),azt_msf2hsg(&Toc[i].trackTime));
-*/ }
-#else
-                               {
-                                       azt_read_count = AZT_BUF_SIZ;
-                               }
-#endif
-                               msf.end.min = 0;
-                               msf.end.sec = 0;
-                               msf.end.frame = azt_read_count; /*Mitsumi here reads 0xffffff sectors */
-#ifdef AZT_TEST3
-                               printk
-                                   ("---reading msf-address %x:%x:%x  %x:%x:%x\n",
-                                    msf.start.min, msf.start.sec,
-                                    msf.start.frame, msf.end.min,
-                                    msf.end.sec, msf.end.frame);
-                               printk
-                                   ("azt_next_bn:%x  azt_buf_in:%x azt_buf_out:%x  azt_buf_bn:%x\n",
-                                    azt_next_bn, azt_buf_in, azt_buf_out,
-                                    azt_buf_bn[azt_buf_in]);
-#endif
-                               if (azt_read_mode == AZT_MODE_2) {
-                                       sendAztCmd(ACMD_PLAY_READ_RAW, &msf);   /*XA disks in raw mode */
-                               } else {
-                                       sendAztCmd(ACMD_PLAY_READ, &msf);       /*others in cooked mode */
-                               }
-                               azt_state = AZT_S_DATA;
-                               AztTimeout = READ_TIMEOUT;
-                       } else {
-                               azt_state = AZT_S_STOP;
-                               loop_ctl = 1;
-                               break;
-                       }
-
-                       break;
-
-
-               case AZT_S_DATA:
-#ifdef AZT_TEST3
-                       if (azt_state != azt_state_old) {
-                               azt_state_old = azt_state;
-                               printk("AZT_S_DATA\n");
-                       }
-#endif
-
-                       st = inb(STATUS_PORT) & AFL_STATUSorDATA;
-
-                       switch (st) {
-
-                       case AFL_DATA:
-#ifdef AZT_TEST3
-                               if (st != azt_st_old) {
-                                       azt_st_old = st;
-                                       printk("---AFL_DATA st:%x\n", st);
-                               }
-#endif
-                               if (!AztTries--) {
-                                       printk
-                                           ("aztcd: Read of Block %d Failed, Maybe Audio Disk ? Giving up\n",
-                                            azt_next_bn);
-                                       if (azt_transfer_is_active) {
-                                               AztTries = 0;
-                                               break;
-                                       }
-                                       if (current_valid())
-                                               end_request(CURRENT, 0);
-                                       AztTries = 5;
-                               }
-                               azt_state = AZT_S_START;
-                               AztTimeout = READ_TIMEOUT;
-                               loop_ctl = 1;
-                               break;
-
-                       case AFL_STATUSorDATA:
-#ifdef AZT_TEST3
-                               if (st != azt_st_old) {
-                                       azt_st_old = st;
-                                       printk
-                                           ("---AFL_STATUSorDATA st:%x\n",
-                                            st);
-                               }
-#endif
-                               break;
-
-                       default:
-#ifdef AZT_TEST3
-                               if (st != azt_st_old) {
-                                       azt_st_old = st;
-                                       printk("---default: st:%x\n", st);
-                               }
-#endif
-                               AztTries = 5;
-                               if (!current_valid() && azt_buf_in == azt_buf_out) {
-                                       azt_state = AZT_S_STOP;
-                                       loop_ctl = 1;
-                                       break;
-                               }
-                               if (azt_read_count <= 0)
-                                       printk
-                                           ("aztcd: warning - try to read 0 frames\n");
-                               while (azt_read_count) {        /*??? fast read ahead loop */
-                                       azt_buf_bn[azt_buf_in] = -1;
-                                       DTEN_LOW;       /*??? unsolved problem, very
-                                                          seldom we get timeouts
-                                                          here, don't now the real
-                                                          reason. With my drive this
-                                                          sometimes also happens with
-                                                          Aztech's original driver under
-                                                          DOS. Is it a hardware bug? 
-                                                          I tried to recover from such
-                                                          situations here. Zimmermann */
-                                       if (aztTimeOutCount >= AZT_TIMEOUT) {
-                                               printk
-                                                   ("read_count:%d CURRENT->nr_sectors:%ld azt_buf_in:%d\n",
-                                                    azt_read_count,
-                                                    CURRENT->nr_sectors,
-                                                    azt_buf_in);
-                                               printk
-                                                   ("azt_transfer_is_active:%x\n",
-                                                    azt_transfer_is_active);
-                                               azt_read_count = 0;
-                                               azt_state = AZT_S_STOP;
-                                               loop_ctl = 1;
-                                               end_request(CURRENT, 1);        /*should we have here (1) or (0)? */
-                                       } else {
-                                               if (azt_read_mode ==
-                                                   AZT_MODE_2) {
-                                                       insb(DATA_PORT,
-                                                            azt_buf +
-                                                            CD_FRAMESIZE_RAW
-                                                            * azt_buf_in,
-                                                            CD_FRAMESIZE_RAW);
-                                               } else {
-                                                       insb(DATA_PORT,
-                                                            azt_buf +
-                                                            CD_FRAMESIZE *
-                                                            azt_buf_in,
-                                                            CD_FRAMESIZE);
-                                               }
-                                               azt_read_count--;
-#ifdef AZT_TEST3
-                                               printk
-                                                   ("AZT_S_DATA; ---I've read data- read_count: %d\n",
-                                                    azt_read_count);
-                                               printk
-                                                   ("azt_next_bn:%d  azt_buf_in:%d azt_buf_out:%d  azt_buf_bn:%d\n",
-                                                    azt_next_bn,
-                                                    azt_buf_in,
-                                                    azt_buf_out,
-                                                    azt_buf_bn
-                                                    [azt_buf_in]);
-#endif
-                                               azt_buf_bn[azt_buf_in] =
-                                                   azt_next_bn++;
-                                               if (azt_buf_out == -1)
-                                                       azt_buf_out =
-                                                           azt_buf_in;
-                                               azt_buf_in =
-                                                   azt_buf_in + 1 ==
-                                                   AZT_BUF_SIZ ? 0 :
-                                                   azt_buf_in + 1;
-                                       }
-                               }
-                               if (!azt_transfer_is_active) {
-                                       while (current_valid()) {
-                                               azt_transfer();
-                                               if (CURRENT->nr_sectors ==
-                                                   0)
-                                                       end_request(CURRENT, 1);
-                                               else
-                                                       break;
-                                       }
-                               }
-
-                               if (current_valid()
-                                   && (CURRENT->sector / 4 < azt_next_bn
-                                       || CURRENT->sector / 4 >
-                                       azt_next_bn + AZT_BUF_SIZ)) {
-                                       azt_state = AZT_S_STOP;
-                                       loop_ctl = 1;
-                                       break;
-                               }
-                               AztTimeout = READ_TIMEOUT;
-                               if (azt_read_count == 0) {
-                                       azt_state = AZT_S_STOP;
-                                       loop_ctl = 1;
-                                       break;
-                               }
-                               break;
-                       }
-                       break;
-
-
-               case AZT_S_STOP:
-#ifdef AZT_TEST3
-                       if (azt_state != azt_state_old) {
-                               azt_state_old = azt_state;
-                               printk("AZT_S_STOP\n");
-                       }
-#endif
-                       if (azt_read_count != 0)
-                               printk("aztcd: discard data=%x frames\n",
-                                      azt_read_count);
-                       while (azt_read_count != 0) {
-                               int i;
-                               if (!(inb(STATUS_PORT) & AFL_DATA)) {
-                                       if (azt_read_mode == AZT_MODE_2)
-                                               for (i = 0;
-                                                    i < CD_FRAMESIZE_RAW;
-                                                    i++)
-                                                       inb(DATA_PORT);
-                                       else
-                                               for (i = 0;
-                                                    i < CD_FRAMESIZE; i++)
-                                                       inb(DATA_PORT);
-                               }
-                               azt_read_count--;
-                       }
-                       if (aztSendCmd(ACMD_GET_STATUS))
-                               RETURN("azt_poll 5");
-                       azt_state = AZT_S_STOPPING;
-                       AztTimeout = 1000;
-                       break;
-
-               case AZT_S_STOPPING:
-#ifdef AZT_TEST3
-                       if (azt_state != azt_state_old) {
-                               azt_state_old = azt_state;
-                               printk("AZT_S_STOPPING\n");
-                       }
-#endif
-
-                       if ((st = aztStatus()) == -1 && AztTimeout)
-                               break;
-
-                       if ((st != -1)
-                           && ((st & AST_DSK_CHG)
-                               || (st & AST_NOT_READY))) {
-                               aztDiskChanged = 1;
-                               aztTocUpToDate = 0;
-                               azt_invalidate_buffers();
-                               printk
-                                   ("aztcd: Disk Changed or Not Ready 4 - Unmount Disk!\n");
-                               end_request(CURRENT, 0);
-                       }
-
-#ifdef AZT_TEST3
-                       printk("CURRENT_VALID %d azt_mode %d\n",
-                              current_valid(), azt_mode);
-#endif
-
-                       if (current_valid()) {
-                               if (st != -1) {
-                                       if (azt_mode == 1) {
-                                               azt_state = AZT_S_READ;
-                                               loop_ctl = 1;
-                                               skip = 1;
-                                               break;
-                                       } else {
-                                               azt_state = AZT_S_MODE;
-                                               loop_ctl = 1;
-                                               skip = 1;
-                                               break;
-                                       }
-                               } else {
-                                       azt_state = AZT_S_START;
-                                       AztTimeout = 1;
-                               }
-                       } else {
-                               azt_state = AZT_S_IDLE;
-                               return;
-                       }
-                       break;
-
-               default:
-                       printk("aztcd: invalid state %d\n", azt_state);
-                       return;
-               }               /* case */
-       }                       /* while */
-
-
-       if (!AztTimeout--) {
-               printk("aztcd: timeout in state %d\n", azt_state);
-               azt_state = AZT_S_STOP;
-               if (aztSendCmd(ACMD_STOP))
-                       RETURN("azt_poll 6");
-               STEN_LOW_WAIT;
-       };
-
-       SET_TIMER(azt_poll, HZ / 100);
-}
-
-
-/*###########################################################################
- * Miscellaneous support functions
-  ###########################################################################
-*/
-static void azt_hsg2msf(long hsg, struct msf *msf)
-{
-       hsg += 150;
-       msf->min = hsg / 4500;
-       hsg %= 4500;
-       msf->sec = hsg / 75;
-       msf->frame = hsg % 75;
-#ifdef AZT_DEBUG
-       if (msf->min >= 70)
-               printk("aztcd: Error hsg2msf address Minutes\n");
-       if (msf->sec >= 60)
-               printk("aztcd: Error hsg2msf address Seconds\n");
-       if (msf->frame >= 75)
-               printk("aztcd: Error hsg2msf address Frames\n");
-#endif
-       azt_bin2bcd(&msf->min); /* convert to BCD */
-       azt_bin2bcd(&msf->sec);
-       azt_bin2bcd(&msf->frame);
-}
-
-static long azt_msf2hsg(struct msf *mp)
-{
-       return azt_bcd2bin(mp->frame) + azt_bcd2bin(mp->sec) * 75
-           + azt_bcd2bin(mp->min) * 4500 - CD_MSF_OFFSET;
-}
-
-static void azt_bin2bcd(unsigned char *p)
-{
-       int u, t;
-
-       u = *p % 10;
-       t = *p / 10;
-       *p = u | (t << 4);
-}
-
-static int azt_bcd2bin(unsigned char bcd)
-{
-       return (bcd >> 4) * 10 + (bcd & 0xF);
-}
-
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_BLOCKDEV_MAJOR(AZTECH_CDROM_MAJOR);
diff --git a/drivers/cdrom/aztcd.h b/drivers/cdrom/aztcd.h
deleted file mode 100644 (file)
index 057501e..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-/* $Id: aztcd.h,v 2.60 1997/11/29 09:51:22 root Exp root $
- *
- * Definitions for a AztechCD268 CD-ROM interface
- *     Copyright (C) 1994-98  Werner Zimmermann
- *
- *     based on Mitsumi CDROM driver by Martin Harriss
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You 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.
- *
- *  History:   W.Zimmermann adaption to Aztech CD268-01A Version 1.3
- *             October 1994 Email: Werner.Zimmermann@fht-esslingen.de
- */
-
-/* *** change this to set the I/O port address of your CD-ROM drive,
-       set to '-1', if you want autoprobing */
-#define AZT_BASE_ADDR          -1
-
-/* list of autoprobing addresses (not more than 15), last value must be 0x000
-   Note: Autoprobing is only enabled, if AZT_BASE_ADDR is set to '-1' ! */
-#define AZT_BASE_AUTO          { 0x320, 0x300, 0x310, 0x330, 0x000 }
-
-/* Uncomment this, if your CDROM is connected to a Soundwave32-soundcard
-   and configure AZT_BASE_ADDR and AZT_SW32_BASE_ADDR */
-/*#define AZT_SW32 1
-*/
-
-#ifdef AZT_SW32 
-#define AZT_SW32_BASE_ADDR      0x220  /*I/O port base address of your soundcard*/
-#endif
-
-/* Set this to 1, if you want your tray to be locked, set to 0 to prevent tray 
-   from locking */
-#define AZT_ALLOW_TRAY_LOCK    1
-
-/*Set this to 1 to allow auto-eject when unmounting a disk, set to 0, if you 
-  don't want the auto-eject feature*/
-#define AZT_AUTO_EJECT          0
-
-/*Set this to 1, if you want to use incompatible ioctls for reading in raw and
-  cooked mode */
-#define AZT_PRIVATE_IOCTLS      1
-
-/*Set this to 1, if you want multisession support by the ISO fs. Even if you set 
-  this value to '0' you can use multisession CDs. In that case the drive's firm-
-  ware will do the appropriate redirection automatically. The CD will then look
-  like a single session CD (but nevertheless all data may be read). Please read 
-  chapter '5.1 Multisession support' in README.aztcd for details. Normally it's 
-  uncritical to leave this setting untouched */
-#define AZT_MULTISESSION        1
-
-/*Uncomment this, if you are using a linux kernel version prior to 2.1.0 */
-/*#define AZT_KERNEL_PRIOR_2_1 */
-
-/*---------------------------------------------------------------------------*/
-/*-----nothing to be configured for normal applications below this line------*/
-
-
-/* Increase this if you get lots of timeouts; if you get kernel panic, replace
-   STEN_LOW_WAIT by STEN_LOW in the source code */
-#define AZT_STATUS_DELAY       400       /*for timer wait, STEN_LOW_WAIT*/
-#define AZT_TIMEOUT            8000000   /*for busy wait STEN_LOW, DTEN_LOW*/
-#define AZT_FAST_TIMEOUT       10000     /*for reading the version string*/
-
-/* number of times to retry a command before giving up */
-#define AZT_RETRY_ATTEMPTS     3
-
-/* port access macros */
-#define CMD_PORT               azt_port
-#define DATA_PORT              azt_port
-#define STATUS_PORT            azt_port+1
-#define MODE_PORT              azt_port+2
-#ifdef  AZT_SW32                
- #define AZT_SW32_INIT          (unsigned int) (0xFF00 & (AZT_BASE_ADDR*16))
- #define AZT_SW32_CONFIG_REG    AZT_SW32_BASE_ADDR+0x16  /*Soundwave32 Config. Register*/
- #define AZT_SW32_ID_REG        AZT_SW32_BASE_ADDR+0x04  /*Soundwave32 ID Version Register*/
-#endif
-
-/* status bits */
-#define AST_CMD_CHECK          0x80            /* 1 = command error */
-#define AST_DOOR_OPEN          0x40            /* 1 = door is open */
-#define AST_NOT_READY          0x20            /* 1 = no disk in the drive */
-#define AST_DSK_CHG            0x02            /* 1 = disk removed or changed */
-#define AST_MODE                0x01            /* 0=MODE1, 1=MODE2 */
-#define AST_MODE_BITS          0x1C            /* Mode Bits */
-#define AST_INITIAL            0x0C            /* initial, only valid ... */
-#define AST_BUSY               0x04            /* now playing, only valid
-                                                  in combination with mode
-                                                  bits */
-/* flag bits */
-#define AFL_DATA               0x02            /* data available if low */
-#define AFL_STATUS             0x04            /* status available if low */
-#define AFL_OP_OK              0x01            /* OP_OK command correct*/
-#define AFL_PA_OK              0x02            /* PA_OK parameter correct*/
-#define AFL_OP_ERR             0x05            /* error in command*/
-#define AFL_PA_ERR             0x06            /* error in parameters*/
-#define POLLED                 0x04            /* polled mode */
-
-/* commands */
-#define ACMD_SOFT_RESET                0x10            /* reset drive */
-#define ACMD_PLAY_READ         0x20            /* read data track in cooked mode */
-#define ACMD_PLAY_READ_RAW      0x21           /* reading in raw mode*/
-#define ACMD_SEEK               0x30            /* seek msf address*/
-#define ACMD_SEEK_TO_LEADIN     0x31           /* seek to leadin track*/
-#define ACMD_GET_ERROR         0x40            /* get error code */
-#define ACMD_GET_STATUS                0x41            /* get status */
-#define ACMD_GET_Q_CHANNEL      0x50           /* read info from q channel */
-#define ACMD_EJECT             0x60            /* eject/open tray */
-#define ACMD_CLOSE              0x61            /* close tray */
-#define ACMD_LOCK              0x71            /* lock tray closed */
-#define ACMD_UNLOCK            0x72            /* unlock tray */
-#define ACMD_PAUSE             0x80            /* pause */
-#define ACMD_STOP              0x81            /* stop play */
-#define ACMD_PLAY_AUDIO                0x90            /* play audio track */
-#define ACMD_SET_VOLUME                0x93            /* set audio level */
-#define ACMD_GET_VERSION       0xA0            /* get firmware version */
-#define ACMD_SET_DISK_TYPE     0xA1            /* set disk data mode */
-
-#define MAX_TRACKS             104
-
-struct msf {
-       unsigned char   min;
-       unsigned char   sec;
-       unsigned char   frame;
-};
-
-struct azt_Play_msf {
-       struct msf      start;
-       struct msf      end;
-};
-
-struct azt_DiskInfo {
-       unsigned char   first;
-        unsigned char   next;
-       unsigned char   last;
-       struct msf      diskLength;
-       struct msf      firstTrack;
-        unsigned char   multi;
-        struct msf      nextSession;
-        struct msf      lastSession;
-        unsigned char   xa;
-        unsigned char   audio;
-};
-
-struct azt_Toc {
-       unsigned char   ctrl_addr;
-       unsigned char   track;
-       unsigned char   pointIndex;
-       struct msf      trackTime;
-       struct msf      diskTime;
-};
index 3625a05bc3d33fbd78c97d1a6a04ac03b596822d..aa5468f487ba3d9e55172a52587a5257d85d2e48 100644 (file)
@@ -302,7 +302,7 @@ module_param(lockdoor, bool, 0);
 module_param(check_media_type, bool, 0);
 module_param(mrw_format_restart, bool, 0);
 
-static DEFINE_SPINLOCK(cdrom_lock);
+static DEFINE_MUTEX(cdrom_mutex);
 
 static const char *mrw_format_status[] = {
        "not mrw",
@@ -438,10 +438,10 @@ int register_cdrom(struct cdrom_device_info *cdi)
                cdo->generic_packet = cdrom_dummy_generic_packet;
 
        cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" registered\n", cdi->name);
-       spin_lock(&cdrom_lock);
+       mutex_lock(&cdrom_mutex);
        cdi->next = topCdromPtr;        
        topCdromPtr = cdi;
-       spin_unlock(&cdrom_lock);
+       mutex_unlock(&cdrom_mutex);
        return 0;
 }
 #undef ENSURE
@@ -452,7 +452,7 @@ int unregister_cdrom(struct cdrom_device_info *unreg)
        cdinfo(CD_OPEN, "entering unregister_cdrom\n"); 
 
        prev = NULL;
-       spin_lock(&cdrom_lock);
+       mutex_lock(&cdrom_mutex);
        cdi = topCdromPtr;
        while (cdi && cdi != unreg) {
                prev = cdi;
@@ -460,7 +460,7 @@ int unregister_cdrom(struct cdrom_device_info *unreg)
        }
 
        if (cdi == NULL) {
-               spin_unlock(&cdrom_lock);
+               mutex_unlock(&cdrom_mutex);
                return -2;
        }
        if (prev)
@@ -468,7 +468,7 @@ int unregister_cdrom(struct cdrom_device_info *unreg)
        else
                topCdromPtr = cdi->next;
 
-       spin_unlock(&cdrom_lock);
+       mutex_unlock(&cdrom_mutex);
 
        if (cdi->exit)
                cdi->exit(cdi);
@@ -3289,103 +3289,137 @@ static struct cdrom_sysctl_settings {
        int     check;                  /* check media type */
 } cdrom_sysctl_settings;
 
+enum cdrom_print_option {
+       CTL_NAME,
+       CTL_SPEED,
+       CTL_SLOTS,
+       CTL_CAPABILITY
+};
+
+static int cdrom_print_info(const char *header, int val, char *info,
+                               int *pos, enum cdrom_print_option option)
+{
+       const int max_size = sizeof(cdrom_sysctl_settings.info);
+       struct cdrom_device_info *cdi;
+       int ret;
+
+       ret = scnprintf(info + *pos, max_size - *pos, header);
+       if (!ret)
+               return 1;
+
+       *pos += ret;
+
+       for (cdi = topCdromPtr; cdi; cdi = cdi->next) {
+               switch (option) {
+               case CTL_NAME:
+                       ret = scnprintf(info + *pos, max_size - *pos,
+                                       "\t%s", cdi->name);
+                       break;
+               case CTL_SPEED:
+                       ret = scnprintf(info + *pos, max_size - *pos,
+                                       "\t%d", cdi->speed);
+                       break;
+               case CTL_SLOTS:
+                       ret = scnprintf(info + *pos, max_size - *pos,
+                                       "\t%d", cdi->capacity);
+                       break;
+               case CTL_CAPABILITY:
+                       ret = scnprintf(info + *pos, max_size - *pos,
+                                       "\t%d", CDROM_CAN(val) != 0);
+                       break;
+               default:
+                       printk(KERN_INFO "cdrom: invalid option%d\n", option);
+                       return 1;
+               }
+               if (!ret)
+                       return 1;
+               *pos += ret;
+       }
+
+       return 0;
+}
+
 static int cdrom_sysctl_info(ctl_table *ctl, int write, struct file * filp,
                            void __user *buffer, size_t *lenp, loff_t *ppos)
 {
-        int pos;
-       struct cdrom_device_info *cdi;
+       int pos;
        char *info = cdrom_sysctl_settings.info;
+       const int max_size = sizeof(cdrom_sysctl_settings.info);
        
        if (!*lenp || (*ppos && !write)) {
                *lenp = 0;
                return 0;
        }
 
+       mutex_lock(&cdrom_mutex);
+
        pos = sprintf(info, "CD-ROM information, " VERSION "\n");
        
-       pos += sprintf(info+pos, "\ndrive name:\t");
-       for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
-           pos += sprintf(info+pos, "\t%s", cdi->name);
-
-       pos += sprintf(info+pos, "\ndrive speed:\t");
-       for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
-           pos += sprintf(info+pos, "\t%d", cdi->speed);
-
-       pos += sprintf(info+pos, "\ndrive # of slots:");
-       for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
-           pos += sprintf(info+pos, "\t%d", cdi->capacity);
-
-       pos += sprintf(info+pos, "\nCan close tray:\t");
-       for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
-           pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_CLOSE_TRAY) != 0);
-
-       pos += sprintf(info+pos, "\nCan open tray:\t");
-       for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
-           pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_OPEN_TRAY) != 0);
-
-       pos += sprintf(info+pos, "\nCan lock tray:\t");
-       for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
-           pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_LOCK) != 0);
-
-       pos += sprintf(info+pos, "\nCan change speed:");
-       for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
-           pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_SELECT_SPEED) != 0);
-
-       pos += sprintf(info+pos, "\nCan select disk:");
-       for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
-           pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_SELECT_DISC) != 0);
-
-       pos += sprintf(info+pos, "\nCan read multisession:");
-       for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
-           pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_MULTI_SESSION) != 0);
-
-       pos += sprintf(info+pos, "\nCan read MCN:\t");
-       for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
-           pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_MCN) != 0);
-
-       pos += sprintf(info+pos, "\nReports media changed:");
-       for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
-           pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_MEDIA_CHANGED) != 0);
-
-       pos += sprintf(info+pos, "\nCan play audio:\t");
-       for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
-           pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_PLAY_AUDIO) != 0);
-
-       pos += sprintf(info+pos, "\nCan write CD-R:\t");
-       for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
-           pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_CD_R) != 0);
-
-       pos += sprintf(info+pos, "\nCan write CD-RW:");
-       for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
-           pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_CD_RW) != 0);
-
-       pos += sprintf(info+pos, "\nCan read DVD:\t");
-       for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
-           pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_DVD) != 0);
-
-       pos += sprintf(info+pos, "\nCan write DVD-R:");
-       for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
-           pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_DVD_R) != 0);
-
-       pos += sprintf(info+pos, "\nCan write DVD-RAM:");
-       for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
-           pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_DVD_RAM) != 0);
-
-       pos += sprintf(info+pos, "\nCan read MRW:\t");
-       for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
-           pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_MRW) != 0);
-
-       pos += sprintf(info+pos, "\nCan write MRW:\t");
-       for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
-           pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_MRW_W) != 0);
-
-       pos += sprintf(info+pos, "\nCan write RAM:\t");
-       for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
-           pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_RAM) != 0);
-
-       strcpy(info+pos,"\n\n");
-               
-        return proc_dostring(ctl, write, filp, buffer, lenp, ppos);
+       if (cdrom_print_info("\ndrive name:\t", 0, info, &pos, CTL_NAME))
+               goto done;
+       if (cdrom_print_info("\ndrive speed:\t", 0, info, &pos, CTL_SPEED))
+               goto done;
+       if (cdrom_print_info("\ndrive # of slots:", 0, info, &pos, CTL_SLOTS))
+               goto done;
+       if (cdrom_print_info("\nCan close tray:\t",
+                               CDC_CLOSE_TRAY, info, &pos, CTL_CAPABILITY))
+               goto done;
+       if (cdrom_print_info("\nCan open tray:\t",
+                               CDC_OPEN_TRAY, info, &pos, CTL_CAPABILITY))
+               goto done;
+       if (cdrom_print_info("\nCan lock tray:\t",
+                               CDC_LOCK, info, &pos, CTL_CAPABILITY))
+               goto done;
+       if (cdrom_print_info("\nCan change speed:",
+                               CDC_SELECT_SPEED, info, &pos, CTL_CAPABILITY))
+               goto done;
+       if (cdrom_print_info("\nCan select disk:",
+                               CDC_SELECT_DISC, info, &pos, CTL_CAPABILITY))
+               goto done;
+       if (cdrom_print_info("\nCan read multisession:",
+                               CDC_MULTI_SESSION, info, &pos, CTL_CAPABILITY))
+               goto done;
+       if (cdrom_print_info("\nCan read MCN:\t",
+                               CDC_MCN, info, &pos, CTL_CAPABILITY))
+               goto done;
+       if (cdrom_print_info("\nReports media changed:",
+                               CDC_MEDIA_CHANGED, info, &pos, CTL_CAPABILITY))
+               goto done;
+       if (cdrom_print_info("\nCan play audio:\t",
+                               CDC_PLAY_AUDIO, info, &pos, CTL_CAPABILITY))
+               goto done;
+       if (cdrom_print_info("\nCan write CD-R:\t",
+                               CDC_CD_R, info, &pos, CTL_CAPABILITY))
+               goto done;
+       if (cdrom_print_info("\nCan write CD-RW:",
+                               CDC_CD_RW, info, &pos, CTL_CAPABILITY))
+               goto done;
+       if (cdrom_print_info("\nCan read DVD:\t",
+                               CDC_DVD, info, &pos, CTL_CAPABILITY))
+               goto done;
+       if (cdrom_print_info("\nCan write DVD-R:",
+                               CDC_DVD_R, info, &pos, CTL_CAPABILITY))
+               goto done;
+       if (cdrom_print_info("\nCan write DVD-RAM:",
+                               CDC_DVD_RAM, info, &pos, CTL_CAPABILITY))
+               goto done;
+       if (cdrom_print_info("\nCan read MRW:\t",
+                               CDC_MRW, info, &pos, CTL_CAPABILITY))
+               goto done;
+       if (cdrom_print_info("\nCan write MRW:\t",
+                               CDC_MRW_W, info, &pos, CTL_CAPABILITY))
+               goto done;
+       if (cdrom_print_info("\nCan write RAM:\t",
+                               CDC_RAM, info, &pos, CTL_CAPABILITY))
+               goto done;
+       if (!scnprintf(info + pos, max_size - pos, "\n\n"))
+               goto done;
+doit:
+       mutex_unlock(&cdrom_mutex);
+       return proc_dostring(ctl, write, filp, buffer, lenp, ppos);
+done:
+       printk(KERN_INFO "cdrom: info buffer too small\n");
+       goto doit;
 }
 
 /* Unfortunately, per device settings are not implemented through
diff --git a/drivers/cdrom/cdu31a.c b/drivers/cdrom/cdu31a.c
deleted file mode 100644 (file)
index 2157c58..0000000
+++ /dev/null
@@ -1,3251 +0,0 @@
-/*
-* Sony CDU-31A CDROM interface device driver.
-*
-* Corey Minyard (minyard@wf-rch.cirr.com)
-*
-* Colossians 3:17
-*
-*  See Documentation/cdrom/cdu31a for additional details about this driver.
-* 
-* The Sony interface device driver handles Sony interface CDROM
-* drives and provides a complete block-level interface as well as an
-* ioctl() interface compatible with the Sun (as specified in
-* include/linux/cdrom.h).  With this interface, CDROMs can be
-* accessed and standard audio CDs can be played back normally.
-*
-* WARNING -    All autoprobes have been removed from the driver.
-*              You MUST configure the CDU31A via a LILO config
-*              at boot time or in lilo.conf.  I have the
-*              following in my lilo.conf:
-*
-*                append="cdu31a=0x1f88,0,PAS"
-*
-*              The first number is the I/O base address of the
-*              card.  The second is the interrupt (0 means none).
- *             The third should be "PAS" if on a Pro-Audio
- *             spectrum, or nothing if on something else.
- *
- * This interface is (unfortunately) a polled interface.  This is
- * because most Sony interfaces are set up with DMA and interrupts
- * disables.  Some (like mine) do not even have the capability to
- * handle interrupts or DMA.  For this reason you will see a lot of
- * the following:
- *
- *   retry_count = jiffies+ SONY_JIFFIES_TIMEOUT;
- *   while (time_before(jiffies, retry_count) && (! <some condition to wait for))
- *   {
- *      while (handle_sony_cd_attention())
- *         ;
- *
- *      sony_sleep();
- *   }
- *   if (the condition not met)
- *   {
- *      return an error;
- *   }
- *
- * This ugly hack waits for something to happen, sleeping a little
- * between every try.  it also handles attentions, which are
- * asynchronous events from the drive informing the driver that a disk
- * has been inserted, removed, etc.
- *
- * NEWS FLASH - The driver now supports interrupts but they are
- * turned off by default.  Use of interrupts is highly encouraged, it
- * cuts CPU usage down to a reasonable level.  I had DMA in for a while
- * but PC DMA is just too slow.  Better to just insb() it.
- *
- * One thing about these drives: They talk in MSF (Minute Second Frame) format.
- * There are 75 frames a second, 60 seconds a minute, and up to 75 minutes on a
- * disk.  The funny thing is that these are sent to the drive in BCD, but the
- * interface wants to see them in decimal.  A lot of conversion goes on.
- *
- * DRIVER SPECIAL FEATURES
- * -----------------------
- *
- * This section describes features beyond the normal audio and CD-ROM
- * functions of the drive.
- *
- * XA compatibility
- *
- * The driver should support XA disks for both the CDU31A and CDU33A.
- * It does this transparently, the using program doesn't need to set it.
- *
- * Multi-Session
- *
- * A multi-session disk looks just like a normal disk to the user.
- * Just mount one normally, and all the data should be there.
- * A special thanks to Koen for help with this!
- * 
- * Raw sector I/O
- *
- * Using the CDROMREADAUDIO it is possible to read raw audio and data
- * tracks.  Both operations return 2352 bytes per sector.  On the data
- * tracks, the first 12 bytes is not returned by the drive and the value
- * of that data is indeterminate.
- *
- *
- *  Copyright (C) 1993  Corey Minyard
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You 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.
- *
- * TODO: 
- *       CDs with form1 and form2 sectors cause problems
- *       with current read-ahead strategy.
- *
- * Credits:
- *    Heiko Eissfeldt <heiko@colossus.escape.de>
- *         For finding abug in the return of the track numbers.
- *         TOC processing redone for proper multisession support.
- *
- *
- *  It probably a little late to be adding a history, but I guess I
- *  will start.
- *
- *  10/24/95 - Added support for disabling the eject button when the
- *             drive is open.  Note that there is a small problem
- *             still here, if the eject button is pushed while the
- *             drive light is flashing, the drive will return a bad
- *             status and be reset.  It recovers, though.
- *
- *  03/07/97 - Fixed a problem with timers.
- *
- *
- *  18 Spetember 1997 -- Ported to Uniform CD-ROM driver by 
- *                 Heiko Eissfeldt <heiko@colossus.escape.de> with additional
- *                 changes by Erik Andersen <andersee@debian.org>
- *
- *  24 January 1998 -- Removed the scd_disc_status() function, which was now
- *                     just dead code left over from the port.
- *                          Erik Andersen <andersee@debian.org>
- *
- *  16 July 1998 -- Drive donated to Erik Andersen by John Kodis
- *                   <kodis@jagunet.com>.  Work begun on fixing driver to
- *                   work under 2.1.X.  Added temporary extra printks
- *                   which seem to slow it down enough to work.
- *
- *  9 November 1999 -- Make kernel-parameter implementation work with 2.3.x 
- *                    Removed init_module & cleanup_module in favor of 
- *                    module_init & module_exit.
- *                    Torben Mathiasen <tmm@image.dk>
- *
- * 22 October 2004 -- Make the driver work in 2.6.X
- *                   Added workaround to fix hard lockups on eject
- *                   Fixed door locking problem after mounting empty drive
- *                   Set double-speed drives to double speed by default
- *                   Removed all readahead things - not needed anymore
- *                     Ondrej Zary <rainbow@rainbow-software.org>
-*/
-
-#define DEBUG 1
-
-#include <linux/major.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/hdreg.h>
-#include <linux/genhd.h>
-#include <linux/ioport.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/cdrom.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/dma.h>
-
-#include "cdu31a.h"
-
-#define MAJOR_NR CDU31A_CDROM_MAJOR
-#include <linux/blkdev.h>
-
-#define CDU31A_MAX_CONSECUTIVE_ATTENTIONS 10
-
-#define PFX "CDU31A: "
-
-/*
-** Edit the following data to change interrupts, DMA channels, etc.
-** Default is polled and no DMA.  DMA is not recommended for double-speed
-** drives.
-*/
-static struct {
-       unsigned short base;    /* I/O Base Address */
-       short int_num;          /* Interrupt Number (-1 means scan for it,
-                                  0 means don't use) */
-} cdu31a_addresses[] __initdata = {
-       {0}
-};
-
-static int handle_sony_cd_attention(void);
-static int read_subcode(void);
-static void sony_get_toc(void);
-static int scd_spinup(void);
-/*static int scd_open(struct inode *inode, struct file *filp);*/
-static int scd_open(struct cdrom_device_info *, int);
-static void do_sony_cd_cmd(unsigned char cmd,
-                          unsigned char *params,
-                          unsigned int num_params,
-                          unsigned char *result_buffer,
-                          unsigned int *result_size);
-static void size_to_buf(unsigned int size, unsigned char *buf);
-
-/* Parameters for the read-ahead. */
-static unsigned int sony_next_block;   /* Next 512 byte block offset */
-static unsigned int sony_blocks_left = 0;      /* Number of 512 byte blocks left
-                                                  in the current read command. */
-
-
-/* The base I/O address of the Sony Interface.  This is a variable (not a
-   #define) so it can be easily changed via some future ioctl() */
-static unsigned int cdu31a_port = 0;
-module_param(cdu31a_port, uint, 0);
-
-/*
- * The following are I/O addresses of the various registers for the drive.  The
- * comment for the base address also applies here.
- */
-static volatile unsigned short sony_cd_cmd_reg;
-static volatile unsigned short sony_cd_param_reg;
-static volatile unsigned short sony_cd_write_reg;
-static volatile unsigned short sony_cd_control_reg;
-static volatile unsigned short sony_cd_status_reg;
-static volatile unsigned short sony_cd_result_reg;
-static volatile unsigned short sony_cd_read_reg;
-static volatile unsigned short sony_cd_fifost_reg;
-
-static struct request_queue *cdu31a_queue;
-static DEFINE_SPINLOCK(cdu31a_lock); /* queue lock */
-
-static int sony_spun_up = 0;   /* Has the drive been spun up? */
-
-static int sony_speed = 0;     /* Last wanted speed */
-
-static int sony_xa_mode = 0;   /* Is an XA disk in the drive
-                                  and the drive a CDU31A? */
-
-static int sony_raw_data_mode = 1;     /* 1 if data tracks, 0 if audio.
-                                          For raw data reads. */
-
-static unsigned int sony_usage = 0;    /* How many processes have the
-                                          drive open. */
-
-static int sony_pas_init = 0;  /* Initialize the Pro-Audio
-                                  Spectrum card? */
-
-static struct s_sony_session_toc single_toc;   /* Holds the
-                                                  table of
-                                                  contents. */
-
-static struct s_all_sessions_toc sony_toc;     /* entries gathered from all
-                                                  sessions */
-
-static int sony_toc_read = 0;  /* Has the TOC been read for
-                                  the drive? */
-
-static struct s_sony_subcode last_sony_subcode;        /* Points to the last
-                                                  subcode address read */
-
-static DECLARE_MUTEX(sony_sem);                /* Semaphore for drive hardware access */
-
-static int is_double_speed = 0;        /* does the drive support double speed ? */
-
-static int is_auto_eject = 1;  /* Door has been locked? 1=No/0=Yes */
-
-/*
- * The audio status uses the values from read subchannel data as specified
- * in include/linux/cdrom.h.
- */
-static volatile int sony_audio_status = CDROM_AUDIO_NO_STATUS;
-
-/*
- * The following are a hack for pausing and resuming audio play.  The drive
- * does not work as I would expect it, if you stop it then start it again,
- * the drive seeks back to the beginning and starts over.  This holds the
- * position during a pause so a resume can restart it.  It uses the
- * audio status variable above to tell if it is paused.
- */
-static unsigned volatile char cur_pos_msf[3] = { 0, 0, 0 };
-static unsigned volatile char final_pos_msf[3] = { 0, 0, 0 };
-
-/* What IRQ is the drive using?  0 if none. */
-static int cdu31a_irq = 0;
-module_param(cdu31a_irq, int, 0);
-
-/* The interrupt handler will wake this queue up when it gets an
-   interrupts. */
-static DECLARE_WAIT_QUEUE_HEAD(cdu31a_irq_wait);
-static int irq_flag = 0;
-
-static int curr_control_reg = 0;       /* Current value of the control register */
-
-/* A disk changed variable.  When a disk change is detected, it will
-   all be set to TRUE.  As the upper layers ask for disk_changed status
-   it will be cleared. */
-static char disk_changed;
-
-/* This was readahead_buffer once... Now it's used only for audio reads */
-static char audio_buffer[CD_FRAMESIZE_RAW];
-
-/* Used to time a short period to abort an operation after the
-   drive has been idle for a while.  This keeps the light on
-   the drive from flashing for very long. */
-static struct timer_list cdu31a_abort_timer;
-
-/* Marks if the timeout has started an abort read.  This is used
-   on entry to the drive to tell the code to read out the status
-   from the abort read. */
-static int abort_read_started = 0;
-
-/*
- * Uniform cdrom interface function
- * report back, if disc has changed from time of last request.
- */
-static int scd_media_changed(struct cdrom_device_info *cdi, int disc_nr)
-{
-       int retval;
-
-       retval = disk_changed;
-       disk_changed = 0;
-
-       return retval;
-}
-
-/*
- * Uniform cdrom interface function
- * report back, if drive is ready
- */
-static int scd_drive_status(struct cdrom_device_info *cdi, int slot_nr)
-{
-       if (CDSL_CURRENT != slot_nr)
-               /* we have no changer support */
-               return -EINVAL;
-       if (sony_spun_up)
-               return CDS_DISC_OK;
-       if (down_interruptible(&sony_sem))
-               return -ERESTARTSYS;
-       if (scd_spinup() == 0)
-               sony_spun_up = 1;
-       up(&sony_sem);
-       return sony_spun_up ? CDS_DISC_OK : CDS_DRIVE_NOT_READY;
-}
-
-static inline void enable_interrupts(void)
-{
-       curr_control_reg |= (SONY_ATTN_INT_EN_BIT
-                            | SONY_RES_RDY_INT_EN_BIT
-                            | SONY_DATA_RDY_INT_EN_BIT);
-       outb(curr_control_reg, sony_cd_control_reg);
-}
-
-static inline void disable_interrupts(void)
-{
-       curr_control_reg &= ~(SONY_ATTN_INT_EN_BIT
-                             | SONY_RES_RDY_INT_EN_BIT
-                             | SONY_DATA_RDY_INT_EN_BIT);
-       outb(curr_control_reg, sony_cd_control_reg);
-}
-
-/*
- * Wait a little while (used for polling the drive).  If in initialization,
- * setting a timeout doesn't work, so just loop for a while.
- */
-static inline void sony_sleep(void)
-{
-       if (cdu31a_irq <= 0) {
-               yield();
-       } else {                /* Interrupt driven */
-               DEFINE_WAIT(w);
-               int first = 1;
-
-               while (1) {
-                       prepare_to_wait(&cdu31a_irq_wait, &w,
-                                       TASK_INTERRUPTIBLE);
-                       if (first) {
-                               enable_interrupts();
-                               first = 0;
-                       }
-
-                       if (irq_flag != 0)
-                               break;
-                       if (!signal_pending(current)) {
-                               schedule();
-                               continue;
-                       } else
-                               disable_interrupts();
-                       break;
-               }
-               finish_wait(&cdu31a_irq_wait, &w);
-               irq_flag = 0;
-       }
-}
-
-
-/*
- * The following are convenience routine to read various status and set
- * various conditions in the drive.
- */
-static inline int is_attention(void)
-{
-       return (inb(sony_cd_status_reg) & SONY_ATTN_BIT) != 0;
-}
-
-static inline int is_busy(void)
-{
-       return (inb(sony_cd_status_reg) & SONY_BUSY_BIT) != 0;
-}
-
-static inline int is_data_ready(void)
-{
-       return (inb(sony_cd_status_reg) & SONY_DATA_RDY_BIT) != 0;
-}
-
-static inline int is_data_requested(void)
-{
-       return (inb(sony_cd_status_reg) & SONY_DATA_REQUEST_BIT) != 0;
-}
-
-static inline int is_result_ready(void)
-{
-       return (inb(sony_cd_status_reg) & SONY_RES_RDY_BIT) != 0;
-}
-
-static inline int is_param_write_rdy(void)
-{
-       return (inb(sony_cd_fifost_reg) & SONY_PARAM_WRITE_RDY_BIT) != 0;
-}
-
-static inline int is_result_reg_not_empty(void)
-{
-       return (inb(sony_cd_fifost_reg) & SONY_RES_REG_NOT_EMP_BIT) != 0;
-}
-
-static inline void reset_drive(void)
-{
-       curr_control_reg = 0;
-       sony_toc_read = 0;
-       outb(SONY_DRIVE_RESET_BIT, sony_cd_control_reg);
-}
-
-/*
- * Uniform cdrom interface function
- * reset drive and return when it is ready
- */
-static int scd_reset(struct cdrom_device_info *cdi)
-{
-       unsigned long retry_count;
-
-       if (down_interruptible(&sony_sem))
-               return -ERESTARTSYS;
-       reset_drive();
-
-       retry_count = jiffies + SONY_RESET_TIMEOUT;
-       while (time_before(jiffies, retry_count) && (!is_attention())) {
-               sony_sleep();
-       }
-
-       up(&sony_sem);
-       return 0;
-}
-
-static inline void clear_attention(void)
-{
-       outb(curr_control_reg | SONY_ATTN_CLR_BIT, sony_cd_control_reg);
-}
-
-static inline void clear_result_ready(void)
-{
-       outb(curr_control_reg | SONY_RES_RDY_CLR_BIT, sony_cd_control_reg);
-}
-
-static inline void clear_data_ready(void)
-{
-       outb(curr_control_reg | SONY_DATA_RDY_CLR_BIT,
-            sony_cd_control_reg);
-}
-
-static inline void clear_param_reg(void)
-{
-       outb(curr_control_reg | SONY_PARAM_CLR_BIT, sony_cd_control_reg);
-}
-
-static inline unsigned char read_status_register(void)
-{
-       return inb(sony_cd_status_reg);
-}
-
-static inline unsigned char read_result_register(void)
-{
-       return inb(sony_cd_result_reg);
-}
-
-static inline unsigned char read_data_register(void)
-{
-       return inb(sony_cd_read_reg);
-}
-
-static inline void write_param(unsigned char param)
-{
-       outb(param, sony_cd_param_reg);
-}
-
-static inline void write_cmd(unsigned char cmd)
-{
-       outb(curr_control_reg | SONY_RES_RDY_INT_EN_BIT,
-            sony_cd_control_reg);
-       outb(cmd, sony_cd_cmd_reg);
-}
-
-static irqreturn_t cdu31a_interrupt(int irq, void *dev_id)
-{
-       unsigned char val;
-
-       if (abort_read_started) {
-               /* We might be waiting for an abort to finish.  Don't
-                  disable interrupts yet, though, because we handle
-                  this one here. */
-               /* Clear out the result registers. */
-               while (is_result_reg_not_empty()) {
-                       val = read_result_register();
-               }
-               clear_data_ready();
-               clear_result_ready();
-
-               /* Clear out the data */
-               while (is_data_requested()) {
-                       val = read_data_register();
-               }
-               abort_read_started = 0;
-
-               /* If something was waiting, wake it up now. */
-               if (waitqueue_active(&cdu31a_irq_wait)) {
-                       disable_interrupts();
-                       irq_flag = 1;
-                       wake_up_interruptible(&cdu31a_irq_wait);
-               }
-       } else if (waitqueue_active(&cdu31a_irq_wait)) {
-               disable_interrupts();
-               irq_flag = 1;
-               wake_up_interruptible(&cdu31a_irq_wait);
-       } else {
-               disable_interrupts();
-               printk(KERN_NOTICE PFX
-                               "Got an interrupt but nothing was waiting\n");
-       }
-       return IRQ_HANDLED;
-}
-
-/*
- * give more verbose error messages
- */
-static unsigned char *translate_error(unsigned char err_code)
-{
-       static unsigned char errbuf[80];
-
-       switch (err_code) {
-               case 0x10: return "illegal command ";
-               case 0x11: return "illegal parameter ";
-
-               case 0x20: return "not loaded ";
-               case 0x21: return "no disc ";
-               case 0x22: return "not spinning ";
-               case 0x23: return "spinning ";
-               case 0x25: return "spindle servo ";
-               case 0x26: return "focus servo ";
-               case 0x29: return "eject mechanism ";
-               case 0x2a: return "audio playing ";
-               case 0x2c: return "emergency eject ";
-
-               case 0x30: return "focus ";
-               case 0x31: return "frame sync ";
-               case 0x32: return "subcode address ";
-               case 0x33: return "block sync ";
-               case 0x34: return "header address ";
-
-               case 0x40: return "illegal track read ";
-               case 0x41: return "mode 0 read ";
-               case 0x42: return "illegal mode read ";
-               case 0x43: return "illegal block size read ";
-               case 0x44: return "mode read ";
-               case 0x45: return "form read ";
-               case 0x46: return "leadout read ";
-               case 0x47: return "buffer overrun ";
-
-               case 0x53: return "unrecoverable CIRC ";
-               case 0x57: return "unrecoverable LECC ";
-
-               case 0x60: return "no TOC ";
-               case 0x61: return "invalid subcode data ";
-               case 0x63: return "focus on TOC read ";
-               case 0x64: return "frame sync on TOC read ";
-               case 0x65: return "TOC data ";
-
-               case 0x70: return "hardware failure ";
-               case 0x91: return "leadin ";
-               case 0x92: return "leadout ";
-               case 0x93: return "data track ";
-       }
-       sprintf(errbuf, "unknown 0x%02x ", err_code);
-       return errbuf;
-}
-
-/*
- * Set the drive parameters so the drive will auto-spin-up when a
- * disk is inserted.
- */
-static void set_drive_params(int want_doublespeed)
-{
-       unsigned char res_reg[12];
-       unsigned int res_size;
-       unsigned char params[3];
-
-
-       params[0] = SONY_SD_AUTO_SPIN_DOWN_TIME;
-       params[1] = 0x00;       /* Never spin down the drive. */
-       do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
-                      params, 2, res_reg, &res_size);
-       if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
-               printk(KERN_NOTICE PFX
-                       "Unable to set spin-down time: 0x%2.2x\n", res_reg[1]);
-       }
-
-       params[0] = SONY_SD_MECH_CONTROL;
-       params[1] = SONY_AUTO_SPIN_UP_BIT;      /* Set auto spin up */
-
-       if (is_auto_eject)
-               params[1] |= SONY_AUTO_EJECT_BIT;
-
-       if (is_double_speed && want_doublespeed) {
-               params[1] |= SONY_DOUBLE_SPEED_BIT;     /* Set the drive to double speed if 
-                                                          possible */
-       }
-       do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
-                      params, 2, res_reg, &res_size);
-       if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
-               printk(KERN_NOTICE PFX "Unable to set mechanical "
-                               "parameters: 0x%2.2x\n", res_reg[1]);
-       }
-}
-
-/*
- * Uniform cdrom interface function
- * select reading speed for data access
- */
-static int scd_select_speed(struct cdrom_device_info *cdi, int speed)
-{
-       if (speed == 0)
-               sony_speed = 1;
-       else
-               sony_speed = speed - 1;
-
-       if (down_interruptible(&sony_sem))
-               return -ERESTARTSYS;
-       set_drive_params(sony_speed);
-       up(&sony_sem);
-       return 0;
-}
-
-/*
- * Uniform cdrom interface function
- * lock or unlock eject button
- */
-static int scd_lock_door(struct cdrom_device_info *cdi, int lock)
-{
-       if (lock == 0) {
-               is_auto_eject = 1;
-       } else {
-               is_auto_eject = 0;
-       }
-       if (down_interruptible(&sony_sem))
-               return -ERESTARTSYS;
-       set_drive_params(sony_speed);
-       up(&sony_sem);
-       return 0;
-}
-
-/*
- * This code will reset the drive and attempt to restore sane parameters.
- */
-static void restart_on_error(void)
-{
-       unsigned char res_reg[12];
-       unsigned int res_size;
-       unsigned long retry_count;
-
-
-       printk(KERN_NOTICE PFX "Resetting drive on error\n");
-       reset_drive();
-       retry_count = jiffies + SONY_RESET_TIMEOUT;
-       while (time_before(jiffies, retry_count) && (!is_attention())) {
-               sony_sleep();
-       }
-       set_drive_params(sony_speed);
-       do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
-       if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
-               printk(KERN_NOTICE PFX "Unable to spin up drive: 0x%2.2x\n",
-                      res_reg[1]);
-       }
-
-       msleep(2000);
-
-       sony_get_toc();
-}
-
-/*
- * This routine writes data to the parameter register.  Since this should
- * happen fairly fast, it is polled with no OS waits between.
- */
-static int write_params(unsigned char *params, int num_params)
-{
-       unsigned int retry_count;
-
-
-       retry_count = SONY_READY_RETRIES;
-       while ((retry_count > 0) && (!is_param_write_rdy())) {
-               retry_count--;
-       }
-       if (!is_param_write_rdy()) {
-               return -EIO;
-       }
-
-       while (num_params > 0) {
-               write_param(*params);
-               params++;
-               num_params--;
-       }
-
-       return 0;
-}
-
-
-/*
- * The following reads data from the command result register.  It is a
- * fairly complex routine, all status info flows back through this
- * interface.  The algorithm is stolen directly from the flowcharts in
- * the drive manual.
- */
-static void
-get_result(unsigned char *result_buffer, unsigned int *result_size)
-{
-       unsigned char a, b;
-       int i;
-       unsigned long retry_count;
-
-
-       while (handle_sony_cd_attention());
-       /* Wait for the result data to be ready */
-       retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
-       while (time_before(jiffies, retry_count)
-              && (is_busy() || (!(is_result_ready())))) {
-               sony_sleep();
-
-               while (handle_sony_cd_attention());
-       }
-       if (is_busy() || (!(is_result_ready()))) {
-               pr_debug(PFX "timeout out %d\n", __LINE__);
-               result_buffer[0] = 0x20;
-               result_buffer[1] = SONY_TIMEOUT_OP_ERR;
-               *result_size = 2;
-               return;
-       }
-
-       /*
-        * Get the first two bytes.  This determines what else needs
-        * to be done.
-        */
-       clear_result_ready();
-       a = read_result_register();
-       *result_buffer = a;
-       result_buffer++;
-
-       /* Check for block error status result. */
-       if ((a & 0xf0) == 0x50) {
-               *result_size = 1;
-               return;
-       }
-
-       b = read_result_register();
-       *result_buffer = b;
-       result_buffer++;
-       *result_size = 2;
-
-       /*
-        * 0x20 means an error occurred.  Byte 2 will have the error code.
-        * Otherwise, the command succeeded, byte 2 will have the count of
-        * how many more status bytes are coming.
-        *
-        * The result register can be read 10 bytes at a time, a wait for
-        * result ready to be asserted must be done between every 10 bytes.
-        */
-       if ((a & 0xf0) != 0x20) {
-               if (b > 8) {
-                       for (i = 0; i < 8; i++) {
-                               *result_buffer = read_result_register();
-                               result_buffer++;
-                               (*result_size)++;
-                       }
-                       b = b - 8;
-
-                       while (b > 10) {
-                               retry_count = SONY_READY_RETRIES;
-                               while ((retry_count > 0)
-                                      && (!is_result_ready())) {
-                                       retry_count--;
-                               }
-                               if (!is_result_ready()) {
-                                       pr_debug(PFX "timeout out %d\n",
-                                              __LINE__);
-                                       result_buffer[0] = 0x20;
-                                       result_buffer[1] =
-                                           SONY_TIMEOUT_OP_ERR;
-                                       *result_size = 2;
-                                       return;
-                               }
-
-                               clear_result_ready();
-
-                               for (i = 0; i < 10; i++) {
-                                       *result_buffer =
-                                           read_result_register();
-                                       result_buffer++;
-                                       (*result_size)++;
-                               }
-                               b = b - 10;
-                       }
-
-                       if (b > 0) {
-                               retry_count = SONY_READY_RETRIES;
-                               while ((retry_count > 0)
-                                      && (!is_result_ready())) {
-                                       retry_count--;
-                               }
-                               if (!is_result_ready()) {
-                                       pr_debug(PFX "timeout out %d\n",
-                                              __LINE__);
-                                       result_buffer[0] = 0x20;
-                                       result_buffer[1] =
-                                           SONY_TIMEOUT_OP_ERR;
-                                       *result_size = 2;
-                                       return;
-                               }
-                       }
-               }
-
-               while (b > 0) {
-                       *result_buffer = read_result_register();
-                       result_buffer++;
-                       (*result_size)++;
-                       b--;
-               }
-       }
-}
-
-/*
- * Do a command that does not involve data transfer.  This routine must
- * be re-entrant from the same task to support being called from the
- * data operation code when an error occurs.
- */
-static void
-do_sony_cd_cmd(unsigned char cmd,
-              unsigned char *params,
-              unsigned int num_params,
-              unsigned char *result_buffer, unsigned int *result_size)
-{
-       unsigned long retry_count;
-       int num_retries = 0;
-
-retry_cd_operation:
-
-       while (handle_sony_cd_attention());
-
-       retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
-       while (time_before(jiffies, retry_count) && (is_busy())) {
-               sony_sleep();
-
-               while (handle_sony_cd_attention());
-       }
-       if (is_busy()) {
-               pr_debug(PFX "timeout out %d\n", __LINE__);
-               result_buffer[0] = 0x20;
-               result_buffer[1] = SONY_TIMEOUT_OP_ERR;
-               *result_size = 2;
-       } else {
-               clear_result_ready();
-               clear_param_reg();
-
-               write_params(params, num_params);
-               write_cmd(cmd);
-
-               get_result(result_buffer, result_size);
-       }
-
-       if (((result_buffer[0] & 0xf0) == 0x20)
-           && (num_retries < MAX_CDU31A_RETRIES)) {
-               num_retries++;
-               msleep(100);
-               goto retry_cd_operation;
-       }
-}
-
-
-/*
- * Handle an attention from the drive.  This will return 1 if it found one
- * or 0 if not (if one is found, the caller might want to call again).
- *
- * This routine counts the number of consecutive times it is called
- * (since this is always called from a while loop until it returns
- * a 0), and returns a 0 if it happens too many times.  This will help
- * prevent a lockup.
- */
-static int handle_sony_cd_attention(void)
-{
-       unsigned char atten_code;
-       static int num_consecutive_attentions = 0;
-       volatile int val;
-
-
-#if 0
-       pr_debug(PFX "Entering %s\n", __FUNCTION__);
-#endif
-       if (is_attention()) {
-               if (num_consecutive_attentions >
-                   CDU31A_MAX_CONSECUTIVE_ATTENTIONS) {
-                       printk(KERN_NOTICE PFX "Too many consecutive "
-                               "attentions: %d\n", num_consecutive_attentions);
-                       num_consecutive_attentions = 0;
-                       pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__,
-                              __LINE__);
-                       return 0;
-               }
-
-               clear_attention();
-               atten_code = read_result_register();
-
-               switch (atten_code) {
-                       /* Someone changed the CD.  Mark it as changed */
-               case SONY_MECH_LOADED_ATTN:
-                       disk_changed = 1;
-                       sony_toc_read = 0;
-                       sony_audio_status = CDROM_AUDIO_NO_STATUS;
-                       sony_blocks_left = 0;
-                       break;
-
-               case SONY_SPIN_DOWN_COMPLETE_ATTN:
-                       /* Mark the disk as spun down. */
-                       sony_spun_up = 0;
-                       break;
-
-               case SONY_AUDIO_PLAY_DONE_ATTN:
-                       sony_audio_status = CDROM_AUDIO_COMPLETED;
-                       read_subcode();
-                       break;
-
-               case SONY_EJECT_PUSHED_ATTN:
-                       if (is_auto_eject) {
-                               sony_audio_status = CDROM_AUDIO_INVALID;
-                       }
-                       break;
-
-               case SONY_LEAD_IN_ERR_ATTN:
-               case SONY_LEAD_OUT_ERR_ATTN:
-               case SONY_DATA_TRACK_ERR_ATTN:
-               case SONY_AUDIO_PLAYBACK_ERR_ATTN:
-                       sony_audio_status = CDROM_AUDIO_ERROR;
-                       break;
-               }
-
-               num_consecutive_attentions++;
-               pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
-               return 1;
-       } else if (abort_read_started) {
-               while (is_result_reg_not_empty()) {
-                       val = read_result_register();
-               }
-               clear_data_ready();
-               clear_result_ready();
-               /* Clear out the data */
-               while (is_data_requested()) {
-                       val = read_data_register();
-               }
-               abort_read_started = 0;
-               pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
-               return 1;
-       }
-
-       num_consecutive_attentions = 0;
-#if 0
-       pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
-#endif
-       return 0;
-}
-
-
-/* Convert from an integer 0-99 to BCD */
-static inline unsigned int int_to_bcd(unsigned int val)
-{
-       int retval;
-
-
-       retval = (val / 10) << 4;
-       retval = retval | val % 10;
-       return retval;
-}
-
-
-/* Convert from BCD to an integer from 0-99 */
-static unsigned int bcd_to_int(unsigned int bcd)
-{
-       return (((bcd >> 4) & 0x0f) * 10) + (bcd & 0x0f);
-}
-
-
-/*
- * Convert a logical sector value (like the OS would want to use for
- * a block device) to an MSF format.
- */
-static void log_to_msf(unsigned int log, unsigned char *msf)
-{
-       log = log + LOG_START_OFFSET;
-       msf[0] = int_to_bcd(log / 4500);
-       log = log % 4500;
-       msf[1] = int_to_bcd(log / 75);
-       msf[2] = int_to_bcd(log % 75);
-}
-
-
-/*
- * Convert an MSF format to a logical sector.
- */
-static unsigned int msf_to_log(unsigned char *msf)
-{
-       unsigned int log;
-
-
-       log = msf[2];
-       log += msf[1] * 75;
-       log += msf[0] * 4500;
-       log = log - LOG_START_OFFSET;
-
-       return log;
-}
-
-
-/*
- * Take in integer size value and put it into a buffer like
- * the drive would want to see a number-of-sector value.
- */
-static void size_to_buf(unsigned int size, unsigned char *buf)
-{
-       buf[0] = size / 65536;
-       size = size % 65536;
-       buf[1] = size / 256;
-       buf[2] = size % 256;
-}
-
-/* Starts a read operation. Returns 0 on success and 1 on failure. 
-   The read operation used here allows multiple sequential sectors 
-   to be read and status returned for each sector.  The driver will
-   read the output one at a time as the requests come and abort the
-   operation if the requested sector is not the next one from the
-   drive. */
-static int
-start_request(unsigned int sector, unsigned int nsect)
-{
-       unsigned char params[6];
-       unsigned long retry_count;
-
-
-       pr_debug(PFX "Entering %s\n", __FUNCTION__);
-       log_to_msf(sector, params);
-       size_to_buf(nsect, &params[3]);
-
-       /*
-        * Clear any outstanding attentions and wait for the drive to
-        * complete any pending operations.
-        */
-       while (handle_sony_cd_attention());
-
-       retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
-       while (time_before(jiffies, retry_count) && (is_busy())) {
-               sony_sleep();
-
-               while (handle_sony_cd_attention());
-       }
-
-       if (is_busy()) {
-               printk(KERN_NOTICE PFX "Timeout while waiting "
-                               "to issue command\n");
-               pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
-               return 1;
-       } else {
-               /* Issue the command */
-               clear_result_ready();
-               clear_param_reg();
-
-               write_params(params, 6);
-               write_cmd(SONY_READ_BLKERR_STAT_CMD);
-
-               sony_blocks_left = nsect * 4;
-               sony_next_block = sector * 4;
-               pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
-               return 0;
-       }
-       pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
-}
-
-/* Abort a pending read operation.  Clear all the drive status variables. */
-static void abort_read(void)
-{
-       unsigned char result_reg[2];
-       int result_size;
-       volatile int val;
-
-
-       do_sony_cd_cmd(SONY_ABORT_CMD, NULL, 0, result_reg, &result_size);
-       if ((result_reg[0] & 0xf0) == 0x20) {
-               printk(KERN_ERR PFX "Aborting read, %s error\n",
-                      translate_error(result_reg[1]));
-       }
-
-       while (is_result_reg_not_empty()) {
-               val = read_result_register();
-       }
-       clear_data_ready();
-       clear_result_ready();
-       /* Clear out the data */
-       while (is_data_requested()) {
-               val = read_data_register();
-       }
-
-       sony_blocks_left = 0;
-}
-
-/* Called when the timer times out.  This will abort the
-   pending read operation. */
-static void handle_abort_timeout(unsigned long data)
-{
-       pr_debug(PFX "Entering %s\n", __FUNCTION__);
-       /* If it is in use, ignore it. */
-       if (down_trylock(&sony_sem) == 0) {
-               /* We can't use abort_read(), because it will sleep
-                  or schedule in the timer interrupt.  Just start
-                  the operation, finish it on the next access to
-                  the drive. */
-               clear_result_ready();
-               clear_param_reg();
-               write_cmd(SONY_ABORT_CMD);
-
-               sony_blocks_left = 0;
-               abort_read_started = 1;
-               up(&sony_sem);
-       }
-       pr_debug(PFX "Leaving %s\n", __FUNCTION__);
-}
-
-/* Actually get one sector of data from the drive. */
-static void
-input_data_sector(char *buffer)
-{
-       pr_debug(PFX "Entering %s\n", __FUNCTION__);
-
-       /* If an XA disk on a CDU31A, skip the first 12 bytes of data from
-          the disk.  The real data is after that. We can use audio_buffer. */
-       if (sony_xa_mode)
-               insb(sony_cd_read_reg, audio_buffer, CD_XA_HEAD);
-
-       clear_data_ready();
-
-       insb(sony_cd_read_reg, buffer, 2048);
-
-       /* If an XA disk, we have to clear out the rest of the unused
-          error correction data. We can use audio_buffer for that. */
-       if (sony_xa_mode)
-               insb(sony_cd_read_reg, audio_buffer, CD_XA_TAIL);
-
-       pr_debug(PFX "Leaving %s\n", __FUNCTION__);
-}
-
-/* read data from the drive.  Note the nsect must be <= 4. */
-static void
-read_data_block(char *buffer,
-               unsigned int block,
-               unsigned int nblocks,
-               unsigned char res_reg[], int *res_size)
-{
-       unsigned long retry_count;
-
-       pr_debug(PFX "Entering %s\n", __FUNCTION__);
-
-       res_reg[0] = 0;
-       res_reg[1] = 0;
-       *res_size = 0;
-
-       /* Wait for the drive to tell us we have something */
-       retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
-       while (time_before(jiffies, retry_count) && !(is_data_ready())) {
-               while (handle_sony_cd_attention());
-
-               sony_sleep();
-       }
-       if (!(is_data_ready())) {
-               if (is_result_ready()) {
-                       get_result(res_reg, res_size);
-                       if ((res_reg[0] & 0xf0) != 0x20) {
-                               printk(KERN_NOTICE PFX "Got result that should"
-                                       " have been error: %d\n", res_reg[0]);
-                               res_reg[0] = 0x20;
-                               res_reg[1] = SONY_BAD_DATA_ERR;
-                               *res_size = 2;
-                       }
-                       abort_read();
-               } else {
-                       pr_debug(PFX "timeout out %d\n", __LINE__);
-                       res_reg[0] = 0x20;
-                       res_reg[1] = SONY_TIMEOUT_OP_ERR;
-                       *res_size = 2;
-                       abort_read();
-               }
-       } else {
-               input_data_sector(buffer);
-               sony_blocks_left -= nblocks;
-               sony_next_block += nblocks;
-
-               /* Wait for the status from the drive. */
-               retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
-               while (time_before(jiffies, retry_count)
-                      && !(is_result_ready())) {
-                       while (handle_sony_cd_attention());
-
-                       sony_sleep();
-               }
-
-               if (!is_result_ready()) {
-                       pr_debug(PFX "timeout out %d\n", __LINE__);
-                       res_reg[0] = 0x20;
-                       res_reg[1] = SONY_TIMEOUT_OP_ERR;
-                       *res_size = 2;
-                       abort_read();
-               } else {
-                       get_result(res_reg, res_size);
-
-                       /* If we got a buffer status, handle that. */
-                       if ((res_reg[0] & 0xf0) == 0x50) {
-
-                               if ((res_reg[0] ==
-                                    SONY_NO_CIRC_ERR_BLK_STAT)
-                                   || (res_reg[0] ==
-                                       SONY_NO_LECC_ERR_BLK_STAT)
-                                   || (res_reg[0] ==
-                                       SONY_RECOV_LECC_ERR_BLK_STAT)) {
-                                       /* nothing here */
-                               } else {
-                                       printk(KERN_ERR PFX "Data block "
-                                               "error: 0x%x\n", res_reg[0]);
-                                       res_reg[0] = 0x20;
-                                       res_reg[1] = SONY_BAD_DATA_ERR;
-                                       *res_size = 2;
-                               }
-
-                               /* Final transfer is done for read command, get final result. */
-                               if (sony_blocks_left == 0) {
-                                       get_result(res_reg, res_size);
-                               }
-                       } else if ((res_reg[0] & 0xf0) != 0x20) {
-                               /* The drive gave me bad status, I don't know what to do.
-                                  Reset the driver and return an error. */
-                               printk(KERN_ERR PFX "Invalid block "
-                                       "status: 0x%x\n", res_reg[0]);
-                               restart_on_error();
-                               res_reg[0] = 0x20;
-                               res_reg[1] = SONY_BAD_DATA_ERR;
-                               *res_size = 2;
-                       }
-               }
-       }
-       pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
-}
-
-
-/*
- * The OS calls this to perform a read or write operation to the drive.
- * Write obviously fail.  Reads to a read ahead of sony_buffer_size
- * bytes to help speed operations.  This especially helps since the OS
- * uses 1024 byte blocks and the drive uses 2048 byte blocks.  Since most
- * data access on a CD is done sequentially, this saves a lot of operations.
- */
-static void do_cdu31a_request(request_queue_t * q)
-{
-       struct request *req;
-       int block, nblock, num_retries;
-       unsigned char res_reg[12];
-       unsigned int res_size;
-
-       pr_debug(PFX "Entering %s\n", __FUNCTION__);
-
-       spin_unlock_irq(q->queue_lock);
-       if (down_interruptible(&sony_sem)) {
-               spin_lock_irq(q->queue_lock);
-               return;
-       }
-
-       /* Get drive status before doing anything. */
-       while (handle_sony_cd_attention());
-
-       /* Make sure we have a valid TOC. */
-       sony_get_toc();
-
-
-       /* Make sure the timer is cancelled. */
-       del_timer(&cdu31a_abort_timer);
-
-       while (1) {
-               /*
-                * The beginning here is stolen from the hard disk driver.  I hope
-                * it's right.
-                */
-               req = elv_next_request(q);
-               if (!req)
-                       goto end_do_cdu31a_request;
-
-               if (!sony_spun_up)
-                       scd_spinup();
-
-               block = req->sector;
-               nblock = req->nr_sectors;
-               pr_debug(PFX "request at block %d, length %d blocks\n",
-                       block, nblock);
-               if (!sony_toc_read) {
-                       printk(KERN_NOTICE PFX "TOC not read\n");
-                       end_request(req, 0);
-                       continue;
-               }
-
-               /* WTF??? */
-               if (!blk_fs_request(req)) {
-                       end_request(req, 0);
-                       continue;
-               }
-               if (rq_data_dir(req) == WRITE) {
-                       end_request(req, 0);
-                       continue;
-               }
-
-               /*
-                * If the block address is invalid or the request goes beyond the end of
-                * the media, return an error.
-                */
-               if (((block + nblock) / 4) >= sony_toc.lead_out_start_lba) {
-                       printk(KERN_NOTICE PFX "Request past end of media\n");
-                       end_request(req, 0);
-                       continue;
-               }
-
-               if (nblock > 4)
-                       nblock = 4;
-               num_retries = 0;
-
-       try_read_again:
-               while (handle_sony_cd_attention());
-
-               if (!sony_toc_read) {
-                       printk(KERN_NOTICE PFX "TOC not read\n");
-                       end_request(req, 0);
-                       continue;
-               }
-
-               /* If no data is left to be read from the drive, start the
-                  next request. */
-               if (sony_blocks_left == 0) {
-                       if (start_request(block / 4, nblock / 4)) {
-                               end_request(req, 0);
-                               continue;
-                       }
-               }
-               /* If the requested block is not the next one waiting in
-                  the driver, abort the current operation and start a
-                  new one. */
-               else if (block != sony_next_block) {
-                       pr_debug(PFX "Read for block %d, expected %d\n",
-                                block, sony_next_block);
-                       abort_read();
-                       if (!sony_toc_read) {
-                               printk(KERN_NOTICE PFX "TOC not read\n");
-                               end_request(req, 0);
-                               continue;
-                       }
-                       if (start_request(block / 4, nblock / 4)) {
-                               printk(KERN_NOTICE PFX "start request failed\n");
-                               end_request(req, 0);
-                               continue;
-                       }
-               }
-
-               read_data_block(req->buffer, block, nblock, res_reg, &res_size);
-
-               if (res_reg[0] != 0x20) {
-                       if (!end_that_request_first(req, 1, nblock)) {
-                               spin_lock_irq(q->queue_lock);
-                               blkdev_dequeue_request(req);
-                               end_that_request_last(req, 1);
-                               spin_unlock_irq(q->queue_lock);
-                       }
-                       continue;
-               }
-
-               if (num_retries > MAX_CDU31A_RETRIES) {
-                       end_request(req, 0);
-                       continue;
-               }
-
-               num_retries++;
-               if (res_reg[1] == SONY_NOT_SPIN_ERR) {
-                       do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
-                                       &res_size);
-               } else {
-                       printk(KERN_NOTICE PFX "%s error for block %d, nblock %d\n",
-                                translate_error(res_reg[1]), block, nblock);
-               }
-               goto try_read_again;
-       }
-      end_do_cdu31a_request:
-#if 0
-       /* After finished, cancel any pending operations. */
-       abort_read();
-#else
-       /* Start a timer to time out after a while to disable
-          the read. */
-       cdu31a_abort_timer.expires = jiffies + 2 * HZ;  /* Wait 2 seconds */
-       add_timer(&cdu31a_abort_timer);
-#endif
-
-       up(&sony_sem);
-       spin_lock_irq(q->queue_lock);
-       pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
-}
-
-
-/*
- * Read the table of contents from the drive and set up TOC if
- * successful.
- */
-static void sony_get_toc(void)
-{
-       unsigned char res_reg[2];
-       unsigned int res_size;
-       unsigned char parms[1];
-       int session;
-       int num_spin_ups;
-       int totaltracks = 0;
-       int mint = 99;
-       int maxt = 0;
-
-       pr_debug(PFX "Entering %s\n", __FUNCTION__);
-
-       num_spin_ups = 0;
-       if (!sony_toc_read) {
-             respinup_on_gettoc:
-               /* Ignore the result, since it might error if spinning already. */
-               do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
-                              &res_size);
-
-               do_sony_cd_cmd(SONY_READ_TOC_CMD, NULL, 0, res_reg,
-                              &res_size);
-
-               /* The drive sometimes returns error 0.  I don't know why, but ignore
-                  it.  It seems to mean the drive has already done the operation. */
-               if ((res_size < 2)
-                   || ((res_reg[0] != 0) && (res_reg[1] != 0))) {
-                       /* If the drive is already playing, it's ok.  */
-                       if ((res_reg[1] == SONY_AUDIO_PLAYING_ERR)
-                           || (res_reg[1] == 0)) {
-                               goto gettoc_drive_spinning;
-                       }
-
-                       /* If the drive says it is not spun up (even though we just did it!)
-                          then retry the operation at least a few times. */
-                       if ((res_reg[1] == SONY_NOT_SPIN_ERR)
-                           && (num_spin_ups < MAX_CDU31A_RETRIES)) {
-                               num_spin_ups++;
-                               goto respinup_on_gettoc;
-                       }
-
-                       printk("cdu31a: Error reading TOC: %x %s\n",
-                              res_reg[0], translate_error(res_reg[1]));
-                       return;
-               }
-
-             gettoc_drive_spinning:
-
-               /* The idea here is we keep asking for sessions until the command
-                  fails.  Then we know what the last valid session on the disk is.
-                  No need to check session 0, since session 0 is the same as session
-                  1; the command returns different information if you give it 0. 
-                */
-#if DEBUG
-               memset(&sony_toc, 0x0e, sizeof(sony_toc));
-               memset(&single_toc, 0x0f, sizeof(single_toc));
-#endif
-               session = 1;
-               while (1) {
-/* This seems to slow things down enough to make it work.  This
- * appears to be a problem in do_sony_cd_cmd.  This printk seems 
- * to address the symptoms...  -Erik */
-                       pr_debug(PFX "Trying session %d\n", session);
-                       parms[0] = session;
-                       do_sony_cd_cmd(SONY_READ_TOC_SPEC_CMD,
-                                      parms, 1, res_reg, &res_size);
-
-                       pr_debug(PFX "%2.2x %2.2x\n", res_reg[0], res_reg[1]);
-
-                       if ((res_size < 2)
-                           || ((res_reg[0] & 0xf0) == 0x20)) {
-                               /* An error reading the TOC, this must be past the last session. */
-                               if (session == 1)
-                                       printk
-                                           ("Yikes! Couldn't read any sessions!");
-                               break;
-                       }
-                       pr_debug(PFX "Reading session %d\n", session);
-
-                       parms[0] = session;
-                       do_sony_cd_cmd(SONY_REQ_TOC_DATA_SPEC_CMD,
-                                      parms,
-                                      1,
-                                      (unsigned char *) &single_toc,
-                                      &res_size);
-                       if ((res_size < 2)
-                           || ((single_toc.exec_status[0] & 0xf0) ==
-                               0x20)) {
-                               printk(KERN_ERR PFX "Error reading "
-                                               "session %d: %x %s\n",
-                                    session, single_toc.exec_status[0],
-                                    translate_error(single_toc.
-                                                    exec_status[1]));
-                               /* An error reading the TOC.  Return without sony_toc_read
-                                  set. */
-                               return;
-                       }
-                       pr_debug(PFX "add0 %01x, con0 %01x, poi0 %02x, "
-                                       "1st trk %d, dsktyp %x, dum0 %x\n",
-                            single_toc.address0, single_toc.control0,
-                            single_toc.point0,
-                            bcd_to_int(single_toc.first_track_num),
-                            single_toc.disk_type, single_toc.dummy0);
-                       pr_debug(PFX "add1 %01x, con1 %01x, poi1 %02x, "
-                                       "lst trk %d, dummy1 %x, dum2 %x\n",
-                            single_toc.address1, single_toc.control1,
-                            single_toc.point1,
-                            bcd_to_int(single_toc.last_track_num),
-                            single_toc.dummy1, single_toc.dummy2);
-                       pr_debug(PFX "add2 %01x, con2 %01x, poi2 %02x "
-                               "leadout start min %d, sec %d, frame %d\n",
-                            single_toc.address2, single_toc.control2,
-                            single_toc.point2,
-                            bcd_to_int(single_toc.lead_out_start_msf[0]),
-                            bcd_to_int(single_toc.lead_out_start_msf[1]),
-                            bcd_to_int(single_toc.lead_out_start_msf[2]));
-                       if (res_size > 18 && single_toc.pointb0 > 0xaf)
-                               pr_debug(PFX "addb0 %01x, conb0 %01x, poib0 %02x, nextsession min %d, sec %d, frame %d\n"
-                                    "#mode5_ptrs %02d, max_start_outer_leadout_msf min %d, sec %d, frame %d\n",
-                                    single_toc.addressb0,
-                                    single_toc.controlb0,
-                                    single_toc.pointb0,
-                                    bcd_to_int(single_toc.
-                                               next_poss_prog_area_msf
-                                               [0]),
-                                    bcd_to_int(single_toc.
-                                               next_poss_prog_area_msf
-                                               [1]),
-                                    bcd_to_int(single_toc.
-                                               next_poss_prog_area_msf
-                                               [2]),
-                                    single_toc.num_mode_5_pointers,
-                                    bcd_to_int(single_toc.
-                                               max_start_outer_leadout_msf
-                                               [0]),
-                                    bcd_to_int(single_toc.
-                                               max_start_outer_leadout_msf
-                                               [1]),
-                                    bcd_to_int(single_toc.
-                                               max_start_outer_leadout_msf
-                                               [2]));
-                       if (res_size > 27 && single_toc.pointb1 > 0xaf)
-                               pr_debug(PFX "addb1 %01x, conb1 %01x, poib1 %02x, %x %x %x %x #skipint_ptrs %d, #skiptrkassign %d %x\n",
-                                    single_toc.addressb1,
-                                    single_toc.controlb1,
-                                    single_toc.pointb1,
-                                    single_toc.dummyb0_1[0],
-                                    single_toc.dummyb0_1[1],
-                                    single_toc.dummyb0_1[2],
-                                    single_toc.dummyb0_1[3],
-                                    single_toc.num_skip_interval_pointers,
-                                    single_toc.num_skip_track_assignments,
-                                    single_toc.dummyb0_2);
-                       if (res_size > 36 && single_toc.pointb2 > 0xaf)
-                               pr_debug(PFX "addb2 %01x, conb2 %01x, poib2 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
-                                    single_toc.addressb2,
-                                    single_toc.controlb2,
-                                    single_toc.pointb2,
-                                    single_toc.tracksb2[0],
-                                    single_toc.tracksb2[1],
-                                    single_toc.tracksb2[2],
-                                    single_toc.tracksb2[3],
-                                    single_toc.tracksb2[4],
-                                    single_toc.tracksb2[5],
-                                    single_toc.tracksb2[6]);
-                       if (res_size > 45 && single_toc.pointb3 > 0xaf)
-                               pr_debug(PFX "addb3 %01x, conb3 %01x, poib3 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
-                                    single_toc.addressb3,
-                                    single_toc.controlb3,
-                                    single_toc.pointb3,
-                                    single_toc.tracksb3[0],
-                                    single_toc.tracksb3[1],
-                                    single_toc.tracksb3[2],
-                                    single_toc.tracksb3[3],
-                                    single_toc.tracksb3[4],
-                                    single_toc.tracksb3[5],
-                                    single_toc.tracksb3[6]);
-                       if (res_size > 54 && single_toc.pointb4 > 0xaf)
-                               pr_debug(PFX "addb4 %01x, conb4 %01x, poib4 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
-                                    single_toc.addressb4,
-                                    single_toc.controlb4,
-                                    single_toc.pointb4,
-                                    single_toc.tracksb4[0],
-                                    single_toc.tracksb4[1],
-                                    single_toc.tracksb4[2],
-                                    single_toc.tracksb4[3],
-                                    single_toc.tracksb4[4],
-                                    single_toc.tracksb4[5],
-                                    single_toc.tracksb4[6]);
-                       if (res_size > 63 && single_toc.pointc0 > 0xaf)
-                               pr_debug(PFX "addc0 %01x, conc0 %01x, poic0 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
-                                    single_toc.addressc0,
-                                    single_toc.controlc0,
-                                    single_toc.pointc0,
-                                    single_toc.dummyc0[0],
-                                    single_toc.dummyc0[1],
-                                    single_toc.dummyc0[2],
-                                    single_toc.dummyc0[3],
-                                    single_toc.dummyc0[4],
-                                    single_toc.dummyc0[5],
-                                    single_toc.dummyc0[6]);
-#undef DEBUG
-#define DEBUG 0
-
-                       sony_toc.lead_out_start_msf[0] =
-                           bcd_to_int(single_toc.lead_out_start_msf[0]);
-                       sony_toc.lead_out_start_msf[1] =
-                           bcd_to_int(single_toc.lead_out_start_msf[1]);
-                       sony_toc.lead_out_start_msf[2] =
-                           bcd_to_int(single_toc.lead_out_start_msf[2]);
-                       sony_toc.lead_out_start_lba =
-                           single_toc.lead_out_start_lba =
-                           msf_to_log(sony_toc.lead_out_start_msf);
-
-                       /* For points that do not exist, move the data over them
-                          to the right location. */
-                       if (single_toc.pointb0 != 0xb0) {
-                               memmove(((char *) &single_toc) + 27,
-                                       ((char *) &single_toc) + 18,
-                                       res_size - 18);
-                               res_size += 9;
-                       } else if (res_size > 18) {
-                               sony_toc.lead_out_start_msf[0] =
-                                   bcd_to_int(single_toc.
-                                              max_start_outer_leadout_msf
-                                              [0]);
-                               sony_toc.lead_out_start_msf[1] =
-                                   bcd_to_int(single_toc.
-                                              max_start_outer_leadout_msf
-                                              [1]);
-                               sony_toc.lead_out_start_msf[2] =
-                                   bcd_to_int(single_toc.
-                                              max_start_outer_leadout_msf
-                                              [2]);
-                               sony_toc.lead_out_start_lba =
-                                   msf_to_log(sony_toc.
-                                              lead_out_start_msf);
-                       }
-                       if (single_toc.pointb1 != 0xb1) {
-                               memmove(((char *) &single_toc) + 36,
-                                       ((char *) &single_toc) + 27,
-                                       res_size - 27);
-                               res_size += 9;
-                       }
-                       if (single_toc.pointb2 != 0xb2) {
-                               memmove(((char *) &single_toc) + 45,
-                                       ((char *) &single_toc) + 36,
-                                       res_size - 36);
-                               res_size += 9;
-                       }
-                       if (single_toc.pointb3 != 0xb3) {
-                               memmove(((char *) &single_toc) + 54,
-                                       ((char *) &single_toc) + 45,
-                                       res_size - 45);
-                               res_size += 9;
-                       }
-                       if (single_toc.pointb4 != 0xb4) {
-                               memmove(((char *) &single_toc) + 63,
-                                       ((char *) &single_toc) + 54,
-                                       res_size - 54);
-                               res_size += 9;
-                       }
-                       if (single_toc.pointc0 != 0xc0) {
-                               memmove(((char *) &single_toc) + 72,
-                                       ((char *) &single_toc) + 63,
-                                       res_size - 63);
-                               res_size += 9;
-                       }
-#if DEBUG
-                       printk(PRINT_INFO PFX "start track lba %u,  "
-                                       "leadout start lba %u\n",
-                            single_toc.start_track_lba,
-                            single_toc.lead_out_start_lba);
-                       {
-                               int i;
-                               for (i = 0;
-                                    i <
-                                    1 +
-                                    bcd_to_int(single_toc.last_track_num)
-                                    -
-                                    bcd_to_int(single_toc.
-                                               first_track_num); i++) {
-                                       printk(KERN_INFO PFX "trk %02d: add 0x%01x, con 0x%01x,  track %02d, start min %02d, sec %02d, frame %02d\n",
-                                            i,
-                                            single_toc.tracks[i].address,
-                                            single_toc.tracks[i].control,
-                                            bcd_to_int(single_toc.
-                                                       tracks[i].track),
-                                            bcd_to_int(single_toc.
-                                                       tracks[i].
-                                                       track_start_msf
-                                                       [0]),
-                                            bcd_to_int(single_toc.
-                                                       tracks[i].
-                                                       track_start_msf
-                                                       [1]),
-                                            bcd_to_int(single_toc.
-                                                       tracks[i].
-                                                       track_start_msf
-                                                       [2]));
-                                       if (mint >
-                                           bcd_to_int(single_toc.
-                                                      tracks[i].track))
-                                               mint =
-                                                   bcd_to_int(single_toc.
-                                                              tracks[i].
-                                                              track);
-                                       if (maxt <
-                                           bcd_to_int(single_toc.
-                                                      tracks[i].track))
-                                               maxt =
-                                                   bcd_to_int(single_toc.
-                                                              tracks[i].
-                                                              track);
-                               }
-                               printk(KERN_INFO PFX "min track number %d,  "
-                                               "max track number %d\n",
-                                    mint, maxt);
-                       }
-#endif
-
-                       /* prepare a special table of contents for a CD-I disc. They don't have one. */
-                       if (single_toc.disk_type == 0x10 &&
-                           single_toc.first_track_num == 2 &&
-                           single_toc.last_track_num == 2 /* CD-I */ ) {
-                               sony_toc.tracks[totaltracks].address = 1;
-                               sony_toc.tracks[totaltracks].control = 4;       /* force data tracks */
-                               sony_toc.tracks[totaltracks].track = 1;
-                               sony_toc.tracks[totaltracks].
-                                   track_start_msf[0] = 0;
-                               sony_toc.tracks[totaltracks].
-                                   track_start_msf[1] = 2;
-                               sony_toc.tracks[totaltracks].
-                                   track_start_msf[2] = 0;
-                               mint = maxt = 1;
-                               totaltracks++;
-                       } else
-                               /* gather track entries from this session */
-                       {
-                               int i;
-                               for (i = 0;
-                                    i <
-                                    1 +
-                                    bcd_to_int(single_toc.last_track_num)
-                                    -
-                                    bcd_to_int(single_toc.
-                                               first_track_num);
-                                    i++, totaltracks++) {
-                                       sony_toc.tracks[totaltracks].
-                                           address =
-                                           single_toc.tracks[i].address;
-                                       sony_toc.tracks[totaltracks].
-                                           control =
-                                           single_toc.tracks[i].control;
-                                       sony_toc.tracks[totaltracks].
-                                           track =
-                                           bcd_to_int(single_toc.
-                                                      tracks[i].track);
-                                       sony_toc.tracks[totaltracks].
-                                           track_start_msf[0] =
-                                           bcd_to_int(single_toc.
-                                                      tracks[i].
-                                                      track_start_msf[0]);
-                                       sony_toc.tracks[totaltracks].
-                                           track_start_msf[1] =
-                                           bcd_to_int(single_toc.
-                                                      tracks[i].
-                                                      track_start_msf[1]);
-                                       sony_toc.tracks[totaltracks].
-                                           track_start_msf[2] =
-                                           bcd_to_int(single_toc.
-                                                      tracks[i].
-                                                      track_start_msf[2]);
-                                       if (i == 0)
-                                               single_toc.
-                                                   start_track_lba =
-                                                   msf_to_log(sony_toc.
-                                                              tracks
-                                                              [totaltracks].
-                                                              track_start_msf);
-                                       if (mint >
-                                           sony_toc.tracks[totaltracks].
-                                           track)
-                                               mint =
-                                                   sony_toc.
-                                                   tracks[totaltracks].
-                                                   track;
-                                       if (maxt <
-                                           sony_toc.tracks[totaltracks].
-                                           track)
-                                               maxt =
-                                                   sony_toc.
-                                                   tracks[totaltracks].
-                                                   track;
-                               }
-                       }
-                       sony_toc.first_track_num = mint;
-                       sony_toc.last_track_num = maxt;
-                       /* Disk type of last session wins. For example:
-                          CD-Extra has disk type 0 for the first session, so
-                          a dumb HiFi CD player thinks it is a plain audio CD.
-                          We are interested in the disk type of the last session,
-                          which is 0x20 (XA) for CD-Extra, so we can access the
-                          data track ... */
-                       sony_toc.disk_type = single_toc.disk_type;
-                       sony_toc.sessions = session;
-
-                       /* don't believe everything :-) */
-                       if (session == 1)
-                               single_toc.start_track_lba = 0;
-                       sony_toc.start_track_lba =
-                           single_toc.start_track_lba;
-
-                       if (session > 1 && single_toc.pointb0 == 0xb0 &&
-                           sony_toc.lead_out_start_lba ==
-                           single_toc.lead_out_start_lba) {
-                               break;
-                       }
-
-                       /* Let's not get carried away... */
-                       if (session > 40) {
-                               printk(KERN_NOTICE PFX "too many sessions: "
-                                               "%d\n", session);
-                               break;
-                       }
-                       session++;
-               }
-               sony_toc.track_entries = totaltracks;
-               /* add one entry for the LAST track with track number CDROM_LEADOUT */
-               sony_toc.tracks[totaltracks].address = single_toc.address2;
-               sony_toc.tracks[totaltracks].control = single_toc.control2;
-               sony_toc.tracks[totaltracks].track = CDROM_LEADOUT;
-               sony_toc.tracks[totaltracks].track_start_msf[0] =
-                   sony_toc.lead_out_start_msf[0];
-               sony_toc.tracks[totaltracks].track_start_msf[1] =
-                   sony_toc.lead_out_start_msf[1];
-               sony_toc.tracks[totaltracks].track_start_msf[2] =
-                   sony_toc.lead_out_start_msf[2];
-
-               sony_toc_read = 1;
-
-               pr_debug(PFX "Disk session %d, start track: %d, "
-                               "stop track: %d\n",
-                    session, single_toc.start_track_lba,
-                    single_toc.lead_out_start_lba);
-       }
-       pr_debug(PFX "Leaving %s\n", __FUNCTION__);
-}
-
-
-/*
- * Uniform cdrom interface function
- * return multisession offset and sector information
- */
-static int scd_get_last_session(struct cdrom_device_info *cdi,
-                               struct cdrom_multisession *ms_info)
-{
-       if (ms_info == NULL)
-               return 1;
-
-       if (!sony_toc_read) {
-               if (down_interruptible(&sony_sem))
-                       return -ERESTARTSYS;
-               sony_get_toc();
-               up(&sony_sem);
-       }
-
-       ms_info->addr_format = CDROM_LBA;
-       ms_info->addr.lba = sony_toc.start_track_lba;
-       ms_info->xa_flag = sony_toc.disk_type == SONY_XA_DISK_TYPE ||
-           sony_toc.disk_type == 0x10 /* CDI */ ;
-
-       return 0;
-}
-
-/*
- * Search for a specific track in the table of contents.
- */
-static int find_track(int track)
-{
-       int i;
-
-       for (i = 0; i <= sony_toc.track_entries; i++) {
-               if (sony_toc.tracks[i].track == track) {
-                       return i;
-               }
-       }
-
-       return -1;
-}
-
-
-/*
- * Read the subcode and put it in last_sony_subcode for future use.
- */
-static int read_subcode(void)
-{
-       unsigned int res_size;
-
-
-       do_sony_cd_cmd(SONY_REQ_SUBCODE_ADDRESS_CMD,
-                      NULL,
-                      0, (unsigned char *) &last_sony_subcode, &res_size);
-       if ((res_size < 2)
-           || ((last_sony_subcode.exec_status[0] & 0xf0) == 0x20)) {
-               printk(KERN_ERR PFX "Sony CDROM error %s (read_subcode)\n",
-                      translate_error(last_sony_subcode.exec_status[1]));
-               return -EIO;
-       }
-
-       last_sony_subcode.track_num =
-           bcd_to_int(last_sony_subcode.track_num);
-       last_sony_subcode.index_num =
-           bcd_to_int(last_sony_subcode.index_num);
-       last_sony_subcode.abs_msf[0] =
-           bcd_to_int(last_sony_subcode.abs_msf[0]);
-       last_sony_subcode.abs_msf[1] =
-           bcd_to_int(last_sony_subcode.abs_msf[1]);
-       last_sony_subcode.abs_msf[2] =
-           bcd_to_int(last_sony_subcode.abs_msf[2]);
-
-       last_sony_subcode.rel_msf[0] =
-           bcd_to_int(last_sony_subcode.rel_msf[0]);
-       last_sony_subcode.rel_msf[1] =
-           bcd_to_int(last_sony_subcode.rel_msf[1]);
-       last_sony_subcode.rel_msf[2] =
-           bcd_to_int(last_sony_subcode.rel_msf[2]);
-       return 0;
-}
-
-/*
- * Uniform cdrom interface function
- * return the media catalog number found on some older audio cds
- */
-static int
-scd_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
-{
-       unsigned char resbuffer[2 + 14];
-       unsigned char *mcnp = mcn->medium_catalog_number;
-       unsigned char *resp = resbuffer + 3;
-       unsigned int res_size;
-
-       memset(mcn->medium_catalog_number, 0, 14);
-       if (down_interruptible(&sony_sem))
-               return -ERESTARTSYS;
-       do_sony_cd_cmd(SONY_REQ_UPC_EAN_CMD,
-                      NULL, 0, resbuffer, &res_size);
-       up(&sony_sem);
-       if ((res_size < 2) || ((resbuffer[0] & 0xf0) == 0x20));
-       else {
-               /* packed bcd to single ASCII digits */
-               *mcnp++ = (*resp >> 4) + '0';
-               *mcnp++ = (*resp++ & 0x0f) + '0';
-               *mcnp++ = (*resp >> 4) + '0';
-               *mcnp++ = (*resp++ & 0x0f) + '0';
-               *mcnp++ = (*resp >> 4) + '0';
-               *mcnp++ = (*resp++ & 0x0f) + '0';
-               *mcnp++ = (*resp >> 4) + '0';
-               *mcnp++ = (*resp++ & 0x0f) + '0';
-               *mcnp++ = (*resp >> 4) + '0';
-               *mcnp++ = (*resp++ & 0x0f) + '0';
-               *mcnp++ = (*resp >> 4) + '0';
-               *mcnp++ = (*resp++ & 0x0f) + '0';
-               *mcnp++ = (*resp >> 4) + '0';
-       }
-       *mcnp = '\0';
-       return 0;
-}
-
-
-/*
- * Get the subchannel info like the CDROMSUBCHNL command wants to see it.  If
- * the drive is playing, the subchannel needs to be read (since it would be
- * changing).  If the drive is paused or completed, the subcode information has
- * already been stored, just use that.  The ioctl call wants things in decimal
- * (not BCD), so all the conversions are done.
- */
-static int sony_get_subchnl_info(struct cdrom_subchnl *schi)
-{
-       /* Get attention stuff */
-       while (handle_sony_cd_attention());
-
-       sony_get_toc();
-       if (!sony_toc_read) {
-               return -EIO;
-       }
-
-       switch (sony_audio_status) {
-       case CDROM_AUDIO_NO_STATUS:
-       case CDROM_AUDIO_PLAY:
-               if (read_subcode() < 0) {
-                       return -EIO;
-               }
-               break;
-
-       case CDROM_AUDIO_PAUSED:
-       case CDROM_AUDIO_COMPLETED:
-               break;
-
-#if 0
-       case CDROM_AUDIO_NO_STATUS:
-               schi->cdsc_audiostatus = sony_audio_status;
-               return 0;
-               break;
-#endif
-       case CDROM_AUDIO_INVALID:
-       case CDROM_AUDIO_ERROR:
-       default:
-               return -EIO;
-       }
-
-       schi->cdsc_audiostatus = sony_audio_status;
-       schi->cdsc_adr = last_sony_subcode.address;
-       schi->cdsc_ctrl = last_sony_subcode.control;
-       schi->cdsc_trk = last_sony_subcode.track_num;
-       schi->cdsc_ind = last_sony_subcode.index_num;
-       if (schi->cdsc_format == CDROM_MSF) {
-               schi->cdsc_absaddr.msf.minute =
-                   last_sony_subcode.abs_msf[0];
-               schi->cdsc_absaddr.msf.second =
-                   last_sony_subcode.abs_msf[1];
-               schi->cdsc_absaddr.msf.frame =
-                   last_sony_subcode.abs_msf[2];
-
-               schi->cdsc_reladdr.msf.minute =
-                   last_sony_subcode.rel_msf[0];
-               schi->cdsc_reladdr.msf.second =
-                   last_sony_subcode.rel_msf[1];
-               schi->cdsc_reladdr.msf.frame =
-                   last_sony_subcode.rel_msf[2];
-       } else if (schi->cdsc_format == CDROM_LBA) {
-               schi->cdsc_absaddr.lba =
-                   msf_to_log(last_sony_subcode.abs_msf);
-               schi->cdsc_reladdr.lba =
-                   msf_to_log(last_sony_subcode.rel_msf);
-       }
-
-       return 0;
-}
-
-/* Get audio data from the drive.  This is fairly complex because I
-   am looking for status and data at the same time, but if I get status
-   then I just look for data.  I need to get the status immediately so
-   the switch from audio to data tracks will happen quickly. */
-static void
-read_audio_data(char *buffer, unsigned char res_reg[], int *res_size)
-{
-       unsigned long retry_count;
-       int result_read;
-
-
-       res_reg[0] = 0;
-       res_reg[1] = 0;
-       *res_size = 0;
-       result_read = 0;
-
-       /* Wait for the drive to tell us we have something */
-       retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
-      continue_read_audio_wait:
-       while (time_before(jiffies, retry_count) && !(is_data_ready())
-              && !(is_result_ready() || result_read)) {
-               while (handle_sony_cd_attention());
-
-               sony_sleep();
-       }
-       if (!(is_data_ready())) {
-               if (is_result_ready() && !result_read) {
-                       get_result(res_reg, res_size);
-
-                       /* Read block status and continue waiting for data. */
-                       if ((res_reg[0] & 0xf0) == 0x50) {
-                               result_read = 1;
-                               goto continue_read_audio_wait;
-                       }
-                       /* Invalid data from the drive.  Shut down the operation. */
-                       else if ((res_reg[0] & 0xf0) != 0x20) {
-                               printk(KERN_WARNING PFX "Got result that "
-                                               "should have been error: %d\n",
-                                    res_reg[0]);
-                               res_reg[0] = 0x20;
-                               res_reg[1] = SONY_BAD_DATA_ERR;
-                               *res_size = 2;
-                       }
-                       abort_read();
-               } else {
-                       pr_debug(PFX "timeout out %d\n", __LINE__);
-                       res_reg[0] = 0x20;
-                       res_reg[1] = SONY_TIMEOUT_OP_ERR;
-                       *res_size = 2;
-                       abort_read();
-               }
-       } else {
-               clear_data_ready();
-
-               /* If data block, then get 2340 bytes offset by 12. */
-               if (sony_raw_data_mode) {
-                       insb(sony_cd_read_reg, buffer + CD_XA_HEAD,
-                            CD_FRAMESIZE_RAW1);
-               } else {
-                       /* Audio gets the whole 2352 bytes. */
-                       insb(sony_cd_read_reg, buffer, CD_FRAMESIZE_RAW);
-               }
-
-               /* If I haven't already gotten the result, get it now. */
-               if (!result_read) {
-                       /* Wait for the drive to tell us we have something */
-                       retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
-                       while (time_before(jiffies, retry_count)
-                              && !(is_result_ready())) {
-                               while (handle_sony_cd_attention());
-
-                               sony_sleep();
-                       }
-
-                       if (!is_result_ready()) {
-                               pr_debug(PFX "timeout out %d\n", __LINE__);
-                               res_reg[0] = 0x20;
-                               res_reg[1] = SONY_TIMEOUT_OP_ERR;
-                               *res_size = 2;
-                               abort_read();
-                               return;
-                       } else {
-                               get_result(res_reg, res_size);
-                       }
-               }
-
-               if ((res_reg[0] & 0xf0) == 0x50) {
-                       if ((res_reg[0] == SONY_NO_CIRC_ERR_BLK_STAT)
-                           || (res_reg[0] == SONY_NO_LECC_ERR_BLK_STAT)
-                           || (res_reg[0] == SONY_RECOV_LECC_ERR_BLK_STAT)
-                           || (res_reg[0] == SONY_NO_ERR_DETECTION_STAT)) {
-                               /* Ok, nothing to do. */
-                       } else {
-                               printk(KERN_ERR PFX "Data block error: 0x%x\n",
-                                      res_reg[0]);
-                               res_reg[0] = 0x20;
-                               res_reg[1] = SONY_BAD_DATA_ERR;
-                               *res_size = 2;
-                       }
-               } else if ((res_reg[0] & 0xf0) != 0x20) {
-                       /* The drive gave me bad status, I don't know what to do.
-                          Reset the driver and return an error. */
-                       printk(KERN_NOTICE PFX "Invalid block status: 0x%x\n",
-                              res_reg[0]);
-                       restart_on_error();
-                       res_reg[0] = 0x20;
-                       res_reg[1] = SONY_BAD_DATA_ERR;
-                       *res_size = 2;
-               }
-       }
-}
-
-/* Perform a raw data read.  This will automatically detect the
-   track type and read the proper data (audio or data). */
-static int read_audio(struct cdrom_read_audio *ra)
-{
-       int retval;
-       unsigned char params[2];
-       unsigned char res_reg[12];
-       unsigned int res_size;
-       unsigned int cframe;
-
-       if (down_interruptible(&sony_sem))
-               return -ERESTARTSYS;
-       if (!sony_spun_up)
-               scd_spinup();
-
-       /* Set the drive to do raw operations. */
-       params[0] = SONY_SD_DECODE_PARAM;
-       params[1] = 0x06 | sony_raw_data_mode;
-       do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
-                      params, 2, res_reg, &res_size);
-       if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
-               printk(KERN_ERR PFX "Unable to set decode params: 0x%2.2x\n",
-                      res_reg[1]);
-               retval = -EIO;
-               goto out_up;
-       }
-
-       /* From here down, we have to goto exit_read_audio instead of returning
-          because the drive parameters have to be set back to data before
-          return. */
-
-       retval = 0;
-       if (start_request(ra->addr.lba, ra->nframes)) {
-               retval = -EIO;
-               goto exit_read_audio;
-       }
-
-       /* For every requested frame. */
-       cframe = 0;
-       while (cframe < ra->nframes) {
-               read_audio_data(audio_buffer, res_reg, &res_size);
-               if ((res_reg[0] & 0xf0) == 0x20) {
-                       if (res_reg[1] == SONY_BAD_DATA_ERR) {
-                               printk(KERN_ERR PFX "Data error on audio "
-                                               "sector %d\n",
-                                    ra->addr.lba + cframe);
-                       } else if (res_reg[1] == SONY_ILL_TRACK_R_ERR) {
-                               /* Illegal track type, change track types and start over. */
-                               sony_raw_data_mode =
-                                   (sony_raw_data_mode) ? 0 : 1;
-
-                               /* Set the drive mode. */
-                               params[0] = SONY_SD_DECODE_PARAM;
-                               params[1] = 0x06 | sony_raw_data_mode;
-                               do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
-                                              params,
-                                              2, res_reg, &res_size);
-                               if ((res_size < 2)
-                                   || ((res_reg[0] & 0xf0) == 0x20)) {
-                                       printk(KERN_ERR PFX "Unable to set "
-                                               "decode params: 0x%2.2x\n",
-                                            res_reg[1]);
-                                       retval = -EIO;
-                                       goto exit_read_audio;
-                               }
-
-                               /* Restart the request on the current frame. */
-                               if (start_request
-                                   (ra->addr.lba + cframe,
-                                    ra->nframes - cframe)) {
-                                       retval = -EIO;
-                                       goto exit_read_audio;
-                               }
-
-                               /* Don't go back to the top because don't want to get into
-                                  and infinite loop.  A lot of code gets duplicated, but
-                                  that's no big deal, I don't guess. */
-                               read_audio_data(audio_buffer, res_reg,
-                                               &res_size);
-                               if ((res_reg[0] & 0xf0) == 0x20) {
-                                       if (res_reg[1] ==
-                                           SONY_BAD_DATA_ERR) {
-                                               printk(KERN_ERR PFX "Data error"
-                                                       " on audio sector %d\n",
-                                                    ra->addr.lba +
-                                                    cframe);
-                                       } else {
-                                               printk(KERN_ERR PFX "Error reading audio data on sector %d: %s\n",
-                                                    ra->addr.lba + cframe,
-                                                    translate_error
-                                                    (res_reg[1]));
-                                               retval = -EIO;
-                                               goto exit_read_audio;
-                                       }
-                               } else if (copy_to_user(ra->buf +
-                                                              (CD_FRAMESIZE_RAW
-                                                               * cframe),
-                                                       audio_buffer,
-                                                       CD_FRAMESIZE_RAW)) {
-                                       retval = -EFAULT;
-                                       goto exit_read_audio;
-                               }
-                       } else {
-                               printk(KERN_ERR PFX "Error reading audio "
-                                               "data on sector %d: %s\n",
-                                    ra->addr.lba + cframe,
-                                    translate_error(res_reg[1]));
-                               retval = -EIO;
-                               goto exit_read_audio;
-                       }
-               } else if (copy_to_user(ra->buf + (CD_FRAMESIZE_RAW * cframe),
-                                       (char *)audio_buffer,
-                                       CD_FRAMESIZE_RAW)) {
-                       retval = -EFAULT;
-                       goto exit_read_audio;
-               }
-
-               cframe++;
-       }
-
-       get_result(res_reg, &res_size);
-       if ((res_reg[0] & 0xf0) == 0x20) {
-               printk(KERN_ERR PFX "Error return from audio read: %s\n",
-                      translate_error(res_reg[1]));
-               retval = -EIO;
-               goto exit_read_audio;
-       }
-
-      exit_read_audio:
-
-       /* Set the drive mode back to the proper one for the disk. */
-       params[0] = SONY_SD_DECODE_PARAM;
-       if (!sony_xa_mode) {
-               params[1] = 0x0f;
-       } else {
-               params[1] = 0x07;
-       }
-       do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
-                      params, 2, res_reg, &res_size);
-       if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
-               printk(KERN_ERR PFX "Unable to reset decode params: 0x%2.2x\n",
-                      res_reg[1]);
-               retval = -EIO;
-       }
-
- out_up:
-       up(&sony_sem);
-
-       return retval;
-}
-
-static int
-do_sony_cd_cmd_chk(const char *name,
-                  unsigned char cmd,
-                  unsigned char *params,
-                  unsigned int num_params,
-                  unsigned char *result_buffer, unsigned int *result_size)
-{
-       do_sony_cd_cmd(cmd, params, num_params, result_buffer,
-                      result_size);
-       if ((*result_size < 2) || ((result_buffer[0] & 0xf0) == 0x20)) {
-               printk(KERN_ERR PFX "Error %s (CDROM%s)\n",
-                      translate_error(result_buffer[1]), name);
-               return -EIO;
-       }
-       return 0;
-}
-
-/*
- * Uniform cdrom interface function
- * open the tray
- */
-static int scd_tray_move(struct cdrom_device_info *cdi, int position)
-{
-       int retval;
-
-       if (down_interruptible(&sony_sem))
-               return -ERESTARTSYS;
-       if (position == 1 /* open tray */ ) {
-               unsigned char res_reg[12];
-               unsigned int res_size;
-
-               do_sony_cd_cmd(SONY_AUDIO_STOP_CMD, NULL, 0, res_reg,
-                              &res_size);
-               do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg,
-                              &res_size);
-
-               sony_audio_status = CDROM_AUDIO_INVALID;
-               retval = do_sony_cd_cmd_chk("EJECT", SONY_EJECT_CMD, NULL, 0,
-                                         res_reg, &res_size);
-       } else {
-               if (0 == scd_spinup())
-                       sony_spun_up = 1;
-               retval = 0;
-       }
-       up(&sony_sem);
-       return retval;
-}
-
-/*
- * The big ugly ioctl handler.
- */
-static int scd_audio_ioctl(struct cdrom_device_info *cdi,
-                          unsigned int cmd, void *arg)
-{
-       unsigned char res_reg[12];
-       unsigned int res_size;
-       unsigned char params[7];
-       int i, retval;
-
-       if (down_interruptible(&sony_sem))
-               return -ERESTARTSYS;
-       switch (cmd) {
-       case CDROMSTART:        /* Spin up the drive */
-               retval = do_sony_cd_cmd_chk("START", SONY_SPIN_UP_CMD, NULL,
-                                         0, res_reg, &res_size);
-               break;
-
-       case CDROMSTOP: /* Spin down the drive */
-               do_sony_cd_cmd(SONY_AUDIO_STOP_CMD, NULL, 0, res_reg,
-                              &res_size);
-
-               /*
-                * Spin the drive down, ignoring the error if the disk was
-                * already not spinning.
-                */
-               sony_audio_status = CDROM_AUDIO_NO_STATUS;
-               retval = do_sony_cd_cmd_chk("STOP", SONY_SPIN_DOWN_CMD, NULL,
-                                         0, res_reg, &res_size);
-               break;
-
-       case CDROMPAUSE:        /* Pause the drive */
-               if (do_sony_cd_cmd_chk
-                   ("PAUSE", SONY_AUDIO_STOP_CMD, NULL, 0, res_reg,
-                    &res_size)) {
-                       retval = -EIO;
-                       break;
-               }
-               /* Get the current position and save it for resuming */
-               if (read_subcode() < 0) {
-                       retval = -EIO;
-                       break;
-               }
-               cur_pos_msf[0] = last_sony_subcode.abs_msf[0];
-               cur_pos_msf[1] = last_sony_subcode.abs_msf[1];
-               cur_pos_msf[2] = last_sony_subcode.abs_msf[2];
-               sony_audio_status = CDROM_AUDIO_PAUSED;
-               retval = 0;
-               break;
-
-       case CDROMRESUME:       /* Start the drive after being paused */
-               if (sony_audio_status != CDROM_AUDIO_PAUSED) {
-                       retval = -EINVAL;
-                       break;
-               }
-
-               do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
-                              &res_size);
-
-               /* Start the drive at the saved position. */
-               params[1] = int_to_bcd(cur_pos_msf[0]);
-               params[2] = int_to_bcd(cur_pos_msf[1]);
-               params[3] = int_to_bcd(cur_pos_msf[2]);
-               params[4] = int_to_bcd(final_pos_msf[0]);
-               params[5] = int_to_bcd(final_pos_msf[1]);
-               params[6] = int_to_bcd(final_pos_msf[2]);
-               params[0] = 0x03;
-               if (do_sony_cd_cmd_chk
-                   ("RESUME", SONY_AUDIO_PLAYBACK_CMD, params, 7, res_reg,
-                    &res_size) < 0) {
-                       retval = -EIO;
-                       break;
-               }
-               sony_audio_status = CDROM_AUDIO_PLAY;
-               retval = 0;
-               break;
-
-       case CDROMPLAYMSF:      /* Play starting at the given MSF address. */
-               do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
-                              &res_size);
-
-               /* The parameters are given in int, must be converted */
-               for (i = 1; i < 7; i++) {
-                       params[i] =
-                           int_to_bcd(((unsigned char *) arg)[i - 1]);
-               }
-               params[0] = 0x03;
-               if (do_sony_cd_cmd_chk
-                   ("PLAYMSF", SONY_AUDIO_PLAYBACK_CMD, params, 7,
-                    res_reg, &res_size) < 0) {
-                       retval = -EIO;
-                       break;
-               }
-
-               /* Save the final position for pauses and resumes */
-               final_pos_msf[0] = bcd_to_int(params[4]);
-               final_pos_msf[1] = bcd_to_int(params[5]);
-               final_pos_msf[2] = bcd_to_int(params[6]);
-               sony_audio_status = CDROM_AUDIO_PLAY;
-               retval = 0;
-               break;
-
-       case CDROMREADTOCHDR:   /* Read the table of contents header */
-               {
-                       struct cdrom_tochdr *hdr;
-
-                       sony_get_toc();
-                       if (!sony_toc_read) {
-                               retval = -EIO;
-                               break;
-                       }
-
-                       hdr = (struct cdrom_tochdr *) arg;
-                       hdr->cdth_trk0 = sony_toc.first_track_num;
-                       hdr->cdth_trk1 = sony_toc.last_track_num;
-               }
-               retval = 0;
-               break;
-
-       case CDROMREADTOCENTRY: /* Read a given table of contents entry */
-               {
-                       struct cdrom_tocentry *entry;
-                       int track_idx;
-                       unsigned char *msf_val = NULL;
-
-                       sony_get_toc();
-                       if (!sony_toc_read) {
-                               retval = -EIO;
-                               break;
-                       }
-
-                       entry = (struct cdrom_tocentry *) arg;
-
-                       track_idx = find_track(entry->cdte_track);
-                       if (track_idx < 0) {
-                               retval = -EINVAL;
-                               break;
-                       }
-
-                       entry->cdte_adr =
-                           sony_toc.tracks[track_idx].address;
-                       entry->cdte_ctrl =
-                           sony_toc.tracks[track_idx].control;
-                       msf_val =
-                           sony_toc.tracks[track_idx].track_start_msf;
-
-                       /* Logical buffer address or MSF format requested? */
-                       if (entry->cdte_format == CDROM_LBA) {
-                               entry->cdte_addr.lba = msf_to_log(msf_val);
-                       } else if (entry->cdte_format == CDROM_MSF) {
-                               entry->cdte_addr.msf.minute = *msf_val;
-                               entry->cdte_addr.msf.second =
-                                   *(msf_val + 1);
-                               entry->cdte_addr.msf.frame =
-                                   *(msf_val + 2);
-                       }
-               }
-               retval = 0;
-               break;
-
-       case CDROMPLAYTRKIND:   /* Play a track.  This currently ignores index. */
-               {
-                       struct cdrom_ti *ti = (struct cdrom_ti *) arg;
-                       int track_idx;
-
-                       sony_get_toc();
-                       if (!sony_toc_read) {
-                               retval = -EIO;
-                               break;
-                       }
-
-                       if ((ti->cdti_trk0 < sony_toc.first_track_num)
-                           || (ti->cdti_trk0 > sony_toc.last_track_num)
-                           || (ti->cdti_trk1 < ti->cdti_trk0)) {
-                               retval = -EINVAL;
-                               break;
-                       }
-
-                       track_idx = find_track(ti->cdti_trk0);
-                       if (track_idx < 0) {
-                               retval = -EINVAL;
-                               break;
-                       }
-                       params[1] =
-                           int_to_bcd(sony_toc.tracks[track_idx].
-                                      track_start_msf[0]);
-                       params[2] =
-                           int_to_bcd(sony_toc.tracks[track_idx].
-                                      track_start_msf[1]);
-                       params[3] =
-                           int_to_bcd(sony_toc.tracks[track_idx].
-                                      track_start_msf[2]);
-
-                       /*
-                        * If we want to stop after the last track, use the lead-out
-                        * MSF to do that.
-                        */
-                       if (ti->cdti_trk1 >= sony_toc.last_track_num) {
-                               track_idx = find_track(CDROM_LEADOUT);
-                       } else {
-                               track_idx = find_track(ti->cdti_trk1 + 1);
-                       }
-                       if (track_idx < 0) {
-                               retval = -EINVAL;
-                               break;
-                       }
-                       params[4] =
-                           int_to_bcd(sony_toc.tracks[track_idx].
-                                      track_start_msf[0]);
-                       params[5] =
-                           int_to_bcd(sony_toc.tracks[track_idx].
-                                      track_start_msf[1]);
-                       params[6] =
-                           int_to_bcd(sony_toc.tracks[track_idx].
-                                      track_start_msf[2]);
-                       params[0] = 0x03;
-
-                       do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
-                                      &res_size);
-
-                       do_sony_cd_cmd(SONY_AUDIO_PLAYBACK_CMD, params, 7,
-                                      res_reg, &res_size);
-
-                       if ((res_size < 2)
-                           || ((res_reg[0] & 0xf0) == 0x20)) {
-                               printk(KERN_ERR PFX
-                                       "Params: %x %x %x %x %x %x %x\n",
-                                      params[0], params[1], params[2],
-                                      params[3], params[4], params[5],
-                                      params[6]);
-                               printk(KERN_ERR PFX
-                                       "Error %s (CDROMPLAYTRKIND)\n",
-                                    translate_error(res_reg[1]));
-                               retval = -EIO;
-                               break;
-                       }
-
-                       /* Save the final position for pauses and resumes */
-                       final_pos_msf[0] = bcd_to_int(params[4]);
-                       final_pos_msf[1] = bcd_to_int(params[5]);
-                       final_pos_msf[2] = bcd_to_int(params[6]);
-                       sony_audio_status = CDROM_AUDIO_PLAY;
-                       retval = 0;
-                       break;
-               }
-
-       case CDROMVOLCTRL:      /* Volume control.  What volume does this change, anyway? */
-               {
-                       struct cdrom_volctrl *volctrl =
-                           (struct cdrom_volctrl *) arg;
-
-                       params[0] = SONY_SD_AUDIO_VOLUME;
-                       params[1] = volctrl->channel0;
-                       params[2] = volctrl->channel1;
-                       retval = do_sony_cd_cmd_chk("VOLCTRL",
-                                                 SONY_SET_DRIVE_PARAM_CMD,
-                                                 params, 3, res_reg,
-                                                 &res_size);
-                       break;
-               }
-       case CDROMSUBCHNL:      /* Get subchannel info */
-               retval = sony_get_subchnl_info((struct cdrom_subchnl *) arg);
-               break;
-
-       default:
-               retval = -EINVAL;
-               break;
-       }
-       up(&sony_sem);
-       return retval;
-}
-
-static int scd_read_audio(struct cdrom_device_info *cdi,
-                        unsigned int cmd, unsigned long arg)
-{
-       void __user *argp = (void __user *)arg;
-       int retval;
-
-       if (down_interruptible(&sony_sem))
-               return -ERESTARTSYS;
-       switch (cmd) {
-       case CDROMREADAUDIO:    /* Read 2352 byte audio tracks and 2340 byte
-                                  raw data tracks. */
-               {
-                       struct cdrom_read_audio ra;
-
-
-                       sony_get_toc();
-                       if (!sony_toc_read) {
-                               retval = -EIO;
-                               break;
-                       }
-
-                       if (copy_from_user(&ra, argp, sizeof(ra))) {
-                               retval = -EFAULT;
-                               break;
-                       }
-
-                       if (ra.nframes == 0) {
-                               retval = 0;
-                               break;
-                       }
-
-                       if (!access_ok(VERIFY_WRITE, ra.buf,
-                                       CD_FRAMESIZE_RAW * ra.nframes))
-                               return -EFAULT;
-
-                       if (ra.addr_format == CDROM_LBA) {
-                               if ((ra.addr.lba >=
-                                    sony_toc.lead_out_start_lba)
-                                   || (ra.addr.lba + ra.nframes >=
-                                       sony_toc.lead_out_start_lba)) {
-                                       retval = -EINVAL;
-                                       break;
-                               }
-                       } else if (ra.addr_format == CDROM_MSF) {
-                               if ((ra.addr.msf.minute >= 75)
-                                   || (ra.addr.msf.second >= 60)
-                                   || (ra.addr.msf.frame >= 75)) {
-                                       retval = -EINVAL;
-                                       break;
-                               }
-
-                               ra.addr.lba = ((ra.addr.msf.minute * 4500)
-                                              + (ra.addr.msf.second * 75)
-                                              + ra.addr.msf.frame);
-                               if ((ra.addr.lba >=
-                                    sony_toc.lead_out_start_lba)
-                                   || (ra.addr.lba + ra.nframes >=
-                                       sony_toc.lead_out_start_lba)) {
-                                       retval = -EINVAL;
-                                       break;
-                               }
-
-                               /* I know, this can go negative on an unsigned.  However,
-                                  the first thing done to the data is to add this value,
-                                  so this should compensate and allow direct msf access. */
-                               ra.addr.lba -= LOG_START_OFFSET;
-                       } else {
-                               retval = -EINVAL;
-                               break;
-                       }
-
-                       retval = read_audio(&ra);
-                       break;
-               }
-               retval = 0;
-               break;
-
-       default:
-               retval = -EINVAL;
-       }
-       up(&sony_sem);
-       return retval;
-}
-
-static int scd_spinup(void)
-{
-       unsigned char res_reg[12];
-       unsigned int res_size;
-       int num_spin_ups;
-
-       num_spin_ups = 0;
-
-      respinup_on_open:
-       do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
-
-       /* The drive sometimes returns error 0.  I don't know why, but ignore
-          it.  It seems to mean the drive has already done the operation. */
-       if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0))) {
-               printk(KERN_ERR PFX "%s error (scd_open, spin up)\n",
-                      translate_error(res_reg[1]));
-               return 1;
-       }
-
-       do_sony_cd_cmd(SONY_READ_TOC_CMD, NULL, 0, res_reg, &res_size);
-
-       /* The drive sometimes returns error 0.  I don't know why, but ignore
-          it.  It seems to mean the drive has already done the operation. */
-       if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0))) {
-               /* If the drive is already playing, it's ok.  */
-               if ((res_reg[1] == SONY_AUDIO_PLAYING_ERR)
-                   || (res_reg[1] == 0)) {
-                       return 0;
-               }
-
-               /* If the drive says it is not spun up (even though we just did it!)
-                  then retry the operation at least a few times. */
-               if ((res_reg[1] == SONY_NOT_SPIN_ERR)
-                   && (num_spin_ups < MAX_CDU31A_RETRIES)) {
-                       num_spin_ups++;
-                       goto respinup_on_open;
-               }
-
-               printk(KERN_ERR PFX "Error %s (scd_open, read toc)\n",
-                      translate_error(res_reg[1]));
-               do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg,
-                              &res_size);
-               return 1;
-       }
-       return 0;
-}
-
-/*
- * Open the drive for operations.  Spin the drive up and read the table of
- * contents if these have not already been done.
- */
-static int scd_open(struct cdrom_device_info *cdi, int purpose)
-{
-       unsigned char res_reg[12];
-       unsigned int res_size;
-       unsigned char params[2];
-
-       if (purpose == 1) {
-               /* Open for IOCTLs only - no media check */
-               sony_usage++;
-               return 0;
-       }
-
-       if (sony_usage == 0) {
-               if (scd_spinup() != 0)
-                       return -EIO;
-               sony_get_toc();
-               if (!sony_toc_read) {
-                       do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0,
-                                      res_reg, &res_size);
-                       return -EIO;
-               }
-
-               /* For XA on the CDU31A only, we have to do special reads.
-                  The CDU33A handles XA automagically. */
-               /* if (   (sony_toc.disk_type == SONY_XA_DISK_TYPE) */
-               if ((sony_toc.disk_type != 0x00)
-                   && (!is_double_speed)) {
-                       params[0] = SONY_SD_DECODE_PARAM;
-                       params[1] = 0x07;
-                       do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
-                                      params, 2, res_reg, &res_size);
-                       if ((res_size < 2)
-                           || ((res_reg[0] & 0xf0) == 0x20)) {
-                               printk(KERN_WARNING PFX "Unable to set "
-                                       "XA params: 0x%2.2x\n", res_reg[1]);
-                       }
-                       sony_xa_mode = 1;
-               }
-               /* A non-XA disk.  Set the parms back if necessary. */
-               else if (sony_xa_mode) {
-                       params[0] = SONY_SD_DECODE_PARAM;
-                       params[1] = 0x0f;
-                       do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
-                                      params, 2, res_reg, &res_size);
-                       if ((res_size < 2)
-                           || ((res_reg[0] & 0xf0) == 0x20)) {
-                               printk(KERN_WARNING PFX "Unable to reset "
-                                       "XA params: 0x%2.2x\n", res_reg[1]);
-                       }
-                       sony_xa_mode = 0;
-               }
-
-               sony_spun_up = 1;
-       }
-
-       sony_usage++;
-
-       return 0;
-}
-
-
-/*
- * Close the drive.  Spin it down if no task is using it.  The spin
- * down will fail if playing audio, so audio play is OK.
- */
-static void scd_release(struct cdrom_device_info *cdi)
-{
-       if (sony_usage == 1) {
-               unsigned char res_reg[12];
-               unsigned int res_size;
-
-               do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg,
-                              &res_size);
-
-               sony_spun_up = 0;
-       }
-       sony_usage--;
-}
-
-static struct cdrom_device_ops scd_dops = {
-       .open                   = scd_open,
-       .release                = scd_release,
-       .drive_status           = scd_drive_status,
-       .media_changed          = scd_media_changed,
-       .tray_move              = scd_tray_move,
-       .lock_door              = scd_lock_door,
-       .select_speed           = scd_select_speed,
-       .get_last_session       = scd_get_last_session,
-       .get_mcn                = scd_get_mcn,
-       .reset                  = scd_reset,
-       .audio_ioctl            = scd_audio_ioctl,
-       .capability             = CDC_OPEN_TRAY | CDC_CLOSE_TRAY | CDC_LOCK |
-                                 CDC_SELECT_SPEED | CDC_MULTI_SESSION |
-                                 CDC_MCN | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO |
-                                 CDC_RESET | CDC_DRIVE_STATUS,
-       .n_minors               = 1,
-};
-
-static struct cdrom_device_info scd_info = {
-       .ops            = &scd_dops,
-       .speed          = 2,
-       .capacity       = 1,
-       .name           = "cdu31a"
-};
-
-static int scd_block_open(struct inode *inode, struct file *file)
-{
-       return cdrom_open(&scd_info, inode, file);
-}
-
-static int scd_block_release(struct inode *inode, struct file *file)
-{
-       return cdrom_release(&scd_info, file);
-}
-
-static int scd_block_ioctl(struct inode *inode, struct file *file,
-                               unsigned cmd, unsigned long arg)
-{
-       int retval;
-
-       /* The eject and close commands should be handled by Uniform CD-ROM
-        * driver - but I always got hard lockup instead of eject
-        * until I put this here.
-        */
-       switch (cmd) {
-               case CDROMEJECT:
-                       scd_lock_door(&scd_info, 0);
-                       retval = scd_tray_move(&scd_info, 1);
-                       break;
-               case CDROMCLOSETRAY:
-                       retval = scd_tray_move(&scd_info, 0);
-                       break;
-               case CDROMREADAUDIO:
-                       retval = scd_read_audio(&scd_info, CDROMREADAUDIO, arg);
-                       break;
-               default:
-                       retval = cdrom_ioctl(file, &scd_info, inode, cmd, arg);
-       }
-       return retval;
-}
-
-static int scd_block_media_changed(struct gendisk *disk)
-{
-       return cdrom_media_changed(&scd_info);
-}
-
-static struct block_device_operations scd_bdops =
-{
-       .owner          = THIS_MODULE,
-       .open           = scd_block_open,
-       .release        = scd_block_release,
-       .ioctl          = scd_block_ioctl,
-       .media_changed  = scd_block_media_changed,
-};
-
-static struct gendisk *scd_gendisk;
-
-/* The different types of disc loading mechanisms supported */
-static char *load_mech[] __initdata =
-    { "caddy", "tray", "pop-up", "unknown" };
-
-static int __init
-get_drive_configuration(unsigned short base_io,
-                       unsigned char res_reg[], unsigned int *res_size)
-{
-       unsigned long retry_count;
-
-
-       if (!request_region(base_io, 4, "cdu31a"))
-               return 0;
-
-       /* Set the base address */
-       cdu31a_port = base_io;
-
-       /* Set up all the register locations */
-       sony_cd_cmd_reg = cdu31a_port + SONY_CMD_REG_OFFSET;
-       sony_cd_param_reg = cdu31a_port + SONY_PARAM_REG_OFFSET;
-       sony_cd_write_reg = cdu31a_port + SONY_WRITE_REG_OFFSET;
-       sony_cd_control_reg = cdu31a_port + SONY_CONTROL_REG_OFFSET;
-       sony_cd_status_reg = cdu31a_port + SONY_STATUS_REG_OFFSET;
-       sony_cd_result_reg = cdu31a_port + SONY_RESULT_REG_OFFSET;
-       sony_cd_read_reg = cdu31a_port + SONY_READ_REG_OFFSET;
-       sony_cd_fifost_reg = cdu31a_port + SONY_FIFOST_REG_OFFSET;
-
-       /*
-        * Check to see if anything exists at the status register location.
-        * I don't know if this is a good way to check, but it seems to work
-        * ok for me.
-        */
-       if (read_status_register() != 0xff) {
-               /*
-                * Reset the drive and wait for attention from it (to say it's reset).
-                * If you don't wait, the next operation will probably fail.
-                */
-               reset_drive();
-               retry_count = jiffies + SONY_RESET_TIMEOUT;
-               while (time_before(jiffies, retry_count)
-                      && (!is_attention())) {
-                       sony_sleep();
-               }
-
-#if 0
-               /* If attention is never seen probably not a CDU31a present */
-               if (!is_attention()) {
-                       res_reg[0] = 0x20;
-                       goto out_err;
-               }
-#endif
-
-               /*
-                * Get the drive configuration.
-                */
-               do_sony_cd_cmd(SONY_REQ_DRIVE_CONFIG_CMD,
-                              NULL,
-                              0, (unsigned char *) res_reg, res_size);
-               if (*res_size <= 2 || (res_reg[0] & 0xf0) != 0)
-                       goto out_err;
-               return 1;
-       }
-
-       /* Return an error */
-       res_reg[0] = 0x20;
-out_err:
-       release_region(cdu31a_port, 4);
-       cdu31a_port = 0;
-       return 0;
-}
-
-#ifndef MODULE
-/*
- * Set up base I/O and interrupts, called from main.c.
- */
-
-static int __init cdu31a_setup(char *strings)
-{
-       int ints[4];
-
-       (void) get_options(strings, ARRAY_SIZE(ints), ints);
-
-       if (ints[0] > 0) {
-               cdu31a_port = ints[1];
-       }
-       if (ints[0] > 1) {
-               cdu31a_irq = ints[2];
-       }
-       if ((strings != NULL) && (*strings != '\0')) {
-               if (strcmp(strings, "PAS") == 0) {
-                       sony_pas_init = 1;
-               } else {
-                       printk(KERN_NOTICE PFX "Unknown interface type: %s\n",
-                              strings);
-               }
-       }
-
-       return 1;
-}
-
-__setup("cdu31a=", cdu31a_setup);
-
-#endif
-
-/*
- * Initialize the driver.
- */
-int __init cdu31a_init(void)
-{
-       struct s_sony_drive_config drive_config;
-       struct gendisk *disk;
-       int deficiency = 0;
-       unsigned int res_size;
-       char msg[255];
-       char buf[40];
-       int i;
-       int tmp_irq;
-
-       /*
-        * According to Alex Freed (freed@europa.orion.adobe.com), this is
-        * required for the Fusion CD-16 package.  If the sound driver is
-        * loaded, it should work fine, but just in case...
-        *
-        * The following turn on the CD-ROM interface for a Fusion CD-16.
-        */
-       if (sony_pas_init) {
-               outb(0xbc, 0x9a01);
-               outb(0xe2, 0x9a01);
-       }
-
-       /* Setting the base I/O address to 0xffff will disable it. */
-       if (cdu31a_port == 0xffff)
-               goto errout3;
-
-       if (cdu31a_port != 0) {
-               /* Need IRQ 0 because we can't sleep here. */
-               tmp_irq = cdu31a_irq;
-               cdu31a_irq = 0;
-               if (!get_drive_configuration(cdu31a_port,
-                                           drive_config.exec_status,
-                                           &res_size))
-                       goto errout3;
-               cdu31a_irq = tmp_irq;
-       } else {
-               cdu31a_irq = 0;
-               for (i = 0; cdu31a_addresses[i].base; i++) {
-                       if (get_drive_configuration(cdu31a_addresses[i].base,
-                                                    drive_config.exec_status,
-                                                    &res_size)) {
-                               cdu31a_irq = cdu31a_addresses[i].int_num;
-                               break;
-                       }
-               }
-               if (!cdu31a_port)
-                       goto errout3;
-       }
-
-       if (register_blkdev(MAJOR_NR, "cdu31a"))
-               goto errout2;
-
-       disk = alloc_disk(1);
-       if (!disk)
-               goto errout1;
-       disk->major = MAJOR_NR;
-       disk->first_minor = 0;
-       sprintf(disk->disk_name, "cdu31a");
-       disk->fops = &scd_bdops;
-       disk->flags = GENHD_FL_CD;
-
-       if (SONY_HWC_DOUBLE_SPEED(drive_config))
-               is_double_speed = 1;
-
-       tmp_irq = cdu31a_irq;   /* Need IRQ 0 because we can't sleep here. */
-       cdu31a_irq = 0;
-
-       sony_speed = is_double_speed; /* Set 2X drives to 2X by default */
-       set_drive_params(sony_speed);
-
-       cdu31a_irq = tmp_irq;
-
-       if (cdu31a_irq > 0) {
-               if (request_irq
-                   (cdu31a_irq, cdu31a_interrupt, IRQF_DISABLED,
-                    "cdu31a", NULL)) {
-                       printk(KERN_WARNING PFX "Unable to grab IRQ%d for "
-                                       "the CDU31A driver\n", cdu31a_irq);
-                       cdu31a_irq = 0;
-               }
-       }
-
-       sprintf(msg, "Sony I/F CDROM : %8.8s %16.16s %8.8s\n",
-               drive_config.vendor_id,
-               drive_config.product_id,
-               drive_config.product_rev_level);
-       sprintf(buf, "  Capabilities: %s",
-               load_mech[SONY_HWC_GET_LOAD_MECH(drive_config)]);
-       strcat(msg, buf);
-       if (SONY_HWC_AUDIO_PLAYBACK(drive_config))
-               strcat(msg, ", audio");
-       else
-               deficiency |= CDC_PLAY_AUDIO;
-       if (SONY_HWC_EJECT(drive_config))
-               strcat(msg, ", eject");
-       else
-               deficiency |= CDC_OPEN_TRAY;
-       if (SONY_HWC_LED_SUPPORT(drive_config))
-               strcat(msg, ", LED");
-       if (SONY_HWC_ELECTRIC_VOLUME(drive_config))
-               strcat(msg, ", elec. Vol");
-       if (SONY_HWC_ELECTRIC_VOLUME_CTL(drive_config))
-               strcat(msg, ", sep. Vol");
-       if (is_double_speed)
-               strcat(msg, ", double speed");
-       else
-               deficiency |= CDC_SELECT_SPEED;
-       if (cdu31a_irq > 0) {
-               sprintf(buf, ", irq %d", cdu31a_irq);
-               strcat(msg, buf);
-       }
-       strcat(msg, "\n");
-       printk(KERN_INFO PFX "%s",msg);
-
-       cdu31a_queue = blk_init_queue(do_cdu31a_request, &cdu31a_lock);
-       if (!cdu31a_queue)
-               goto errout0;
-       blk_queue_hardsect_size(cdu31a_queue, 2048);
-
-       init_timer(&cdu31a_abort_timer);
-       cdu31a_abort_timer.function = handle_abort_timeout;
-
-       scd_info.mask = deficiency;
-       scd_gendisk = disk;
-       if (register_cdrom(&scd_info))
-               goto err;
-       disk->queue = cdu31a_queue;
-       add_disk(disk);
-
-       disk_changed = 1;
-       return 0;
-
-err:
-       blk_cleanup_queue(cdu31a_queue);
-errout0:
-       if (cdu31a_irq)
-               free_irq(cdu31a_irq, NULL);
-       printk(KERN_ERR PFX "Unable to register with Uniform cdrom driver\n");
-       put_disk(disk);
-errout1:
-       if (unregister_blkdev(MAJOR_NR, "cdu31a")) {
-               printk(KERN_WARNING PFX "Can't unregister block device\n");
-       }
-errout2:
-       release_region(cdu31a_port, 4);
-errout3:
-       return -EIO;
-}
-
-
-static void __exit cdu31a_exit(void)
-{
-       del_gendisk(scd_gendisk);
-       put_disk(scd_gendisk);
-       if (unregister_cdrom(&scd_info)) {
-               printk(KERN_WARNING PFX "Can't unregister from Uniform "
-                               "cdrom driver\n");
-               return;
-       }
-       if ((unregister_blkdev(MAJOR_NR, "cdu31a") == -EINVAL)) {
-               printk(KERN_WARNING PFX "Can't unregister\n");
-               return;
-       }
-
-       blk_cleanup_queue(cdu31a_queue);
-
-       if (cdu31a_irq > 0)
-               free_irq(cdu31a_irq, NULL);
-
-       release_region(cdu31a_port, 4);
-       printk(KERN_INFO PFX "module released.\n");
-}
-
-#ifdef MODULE
-module_init(cdu31a_init);
-#endif
-module_exit(cdu31a_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_BLOCKDEV_MAJOR(CDU31A_CDROM_MAJOR);
diff --git a/drivers/cdrom/cdu31a.h b/drivers/cdrom/cdu31a.h
deleted file mode 100644 (file)
index 61d4768..0000000
+++ /dev/null
@@ -1,411 +0,0 @@
-/*
- * Definitions for a Sony interface CDROM drive.
- *
- * Corey Minyard (minyard@wf-rch.cirr.com)
- *
- *  Copyright (C) 1993  Corey Minyard
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You 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.
- *
- */
-
-/*
- * General defines.
- */
-#define SONY_XA_DISK_TYPE 0x20
-
-/*
- * Offsets (from the base address) and bits for the various write registers
- * of the drive.
- */
-#define SONY_CMD_REG_OFFSET     0
-#define SONY_PARAM_REG_OFFSET   1
-#define SONY_WRITE_REG_OFFSET   2
-#define SONY_CONTROL_REG_OFFSET 3
-#       define SONY_ATTN_CLR_BIT        0x01
-#       define SONY_RES_RDY_CLR_BIT     0x02
-#       define SONY_DATA_RDY_CLR_BIT    0x04
-#       define SONY_ATTN_INT_EN_BIT     0x08
-#       define SONY_RES_RDY_INT_EN_BIT  0x10
-#       define SONY_DATA_RDY_INT_EN_BIT 0x20
-#       define SONY_PARAM_CLR_BIT       0x40
-#       define SONY_DRIVE_RESET_BIT     0x80
-
-/*
- * Offsets (from the base address) and bits for the various read registers
- * of the drive.
- */
-#define SONY_STATUS_REG_OFFSET  0
-#       define SONY_ATTN_BIT            0x01
-#       define SONY_RES_RDY_BIT         0x02
-#       define SONY_DATA_RDY_BIT        0x04
-#       define SONY_ATTN_INT_ST_BIT     0x08
-#       define SONY_RES_RDY_INT_ST_BIT  0x10
-#       define SONY_DATA_RDY_INT_ST_BIT 0x20
-#       define SONY_DATA_REQUEST_BIT    0x40
-#       define SONY_BUSY_BIT            0x80
-#define SONY_RESULT_REG_OFFSET  1
-#define SONY_READ_REG_OFFSET    2
-#define SONY_FIFOST_REG_OFFSET  3
-#       define SONY_PARAM_WRITE_RDY_BIT 0x01
-#       define SONY_PARAM_REG_EMPTY_BIT 0x02
-#       define SONY_RES_REG_NOT_EMP_BIT 0x04
-#       define SONY_RES_REG_FULL_BIT    0x08
-
-#define LOG_START_OFFSET        150     /* Offset of first logical sector */
-
-#define SONY_DETECT_TIMEOUT    (8*HZ/10) /* Maximum amount of time
-                                           that drive detection code
-                                           will wait for response
-                                           from drive (in 1/100th's
-                                           of seconds). */
-#define SONY_JIFFIES_TIMEOUT    (10*HZ)        /* Maximum number of times the
-                                           drive will wait/try for an
-                                           operation */
-#define SONY_RESET_TIMEOUT      HZ     /* Maximum number of times the
-                                           drive will wait/try a reset
-                                           operation */
-#define SONY_READY_RETRIES      20000   /* How many times to retry a
-                                           spin waiting for a register
-                                           to come ready */
-
-#define MAX_CDU31A_RETRIES      3       /* How many times to retry an
-                                           operation */
-
-/* Commands to request or set drive control parameters and disc information */
-#define SONY_REQ_DRIVE_CONFIG_CMD       0x00    /* Returns s_sony_drive_config */
-#define SONY_REQ_DRIVE_MODE_CMD         0x01
-#define SONY_REQ_DRIVE_PARAM_CMD        0x02
-#define SONY_REQ_MECH_STATUS_CMD        0x03
-#define SONY_REQ_AUDIO_STATUS_CMD       0x04
-#define SONY_SET_DRIVE_PARAM_CMD        0x10
-#define SONY_REQ_TOC_DATA_CMD           0x20    /* Returns s_sony_toc */
-#define SONY_REQ_SUBCODE_ADDRESS_CMD    0x21    /* Returns s_sony_subcode */
-#define SONY_REQ_UPC_EAN_CMD            0x22
-#define SONY_REQ_ISRC_CMD               0x23
-#define SONY_REQ_TOC_DATA_SPEC_CMD      0x24    /* Returns s_sony_session_toc */
-
-/* Commands to request information from the drive */
-#define SONY_READ_TOC_CMD               0x30    /* let the drive firmware grab the TOC */
-#define SONY_SEEK_CMD                   0x31
-#define SONY_READ_CMD                   0x32
-#define SONY_READ_BLKERR_STAT_CMD       0x34
-#define SONY_ABORT_CMD                  0x35
-#define SONY_READ_TOC_SPEC_CMD          0x36
-
-/* Commands to control audio */
-#define SONY_AUDIO_PLAYBACK_CMD         0x40
-#define SONY_AUDIO_STOP_CMD             0x41
-#define SONY_AUDIO_SCAN_CMD             0x42
-
-/* Miscellaneous control commands */
-#define SONY_EJECT_CMD                  0x50
-#define SONY_SPIN_UP_CMD                0x51
-#define SONY_SPIN_DOWN_CMD              0x52
-
-/* Diagnostic commands */
-#define SONY_WRITE_BUFFER_CMD           0x60
-#define SONY_READ_BUFFER_CMD            0x61
-#define SONY_DIAGNOSTICS_CMD            0x62
-
-
-/*
- * The following are command parameters for the set drive parameter command
- */
-#define SONY_SD_DECODE_PARAM            0x00
-#define SONY_SD_INTERFACE_PARAM         0x01
-#define SONY_SD_BUFFERING_PARAM         0x02
-#define SONY_SD_AUDIO_PARAM             0x03
-#define SONY_SD_AUDIO_VOLUME            0x04
-#define SONY_SD_MECH_CONTROL            0x05
-#define SONY_SD_AUTO_SPIN_DOWN_TIME     0x06
-
-/*
- * The following are parameter bits for the mechanical control command
- */
-#define SONY_AUTO_SPIN_UP_BIT           0x01
-#define SONY_AUTO_EJECT_BIT             0x02
-#define SONY_DOUBLE_SPEED_BIT           0x04
-
-/*
- * The following extract information from the drive configuration about
- * the drive itself.
- */
-#define SONY_HWC_GET_LOAD_MECH(c)       (c.hw_config[0] & 0x03)
-#define SONY_HWC_EJECT(c)               (c.hw_config[0] & 0x04)
-#define SONY_HWC_LED_SUPPORT(c)         (c.hw_config[0] & 0x08)
-#define SONY_HWC_DOUBLE_SPEED(c)        (c.hw_config[0] & 0x10)
-#define SONY_HWC_GET_BUF_MEM_SIZE(c)    ((c.hw_config[0] & 0xc0) >> 6)
-#define SONY_HWC_AUDIO_PLAYBACK(c)      (c.hw_config[1] & 0x01)
-#define SONY_HWC_ELECTRIC_VOLUME(c)     (c.hw_config[1] & 0x02)
-#define SONY_HWC_ELECTRIC_VOLUME_CTL(c) (c.hw_config[1] & 0x04)
-
-#define SONY_HWC_CADDY_LOAD_MECH        0x00
-#define SONY_HWC_TRAY_LOAD_MECH         0x01
-#define SONY_HWC_POPUP_LOAD_MECH        0x02
-#define SONY_HWC_UNKWN_LOAD_MECH        0x03
-
-#define SONY_HWC_8KB_BUFFER             0x00
-#define SONY_HWC_32KB_BUFFER            0x01
-#define SONY_HWC_64KB_BUFFER            0x02
-#define SONY_HWC_UNKWN_BUFFER           0x03
-
-/*
- * This is the complete status returned from the drive configuration request
- * command.
- */
-struct s_sony_drive_config
-{
-   unsigned char exec_status[2];
-   char vendor_id[8];
-   char product_id[16];
-   char product_rev_level[8];
-   unsigned char hw_config[2];
-};
-
-/* The following is returned from the request subcode address command */
-struct s_sony_subcode
-{
-   unsigned char exec_status[2];
-   unsigned char address        :4;
-   unsigned char control        :4;
-   unsigned char track_num;
-   unsigned char index_num;
-   unsigned char rel_msf[3];
-   unsigned char reserved1;
-   unsigned char abs_msf[3];
-};
-
-#define MAX_TRACKS 100 /* The maximum tracks a disk may have. */
-/*
- * The following is returned from the request TOC (Table Of Contents) command.
- * (last_track_num-first_track_num+1) values are valid in tracks.
- */
-struct s_sony_toc
-{
-   unsigned char exec_status[2];
-   unsigned char address0       :4;
-   unsigned char control0       :4;
-   unsigned char point0;
-   unsigned char first_track_num;
-   unsigned char disk_type;
-   unsigned char dummy0;
-   unsigned char address1       :4;
-   unsigned char control1       :4;
-   unsigned char point1;
-   unsigned char last_track_num;
-   unsigned char dummy1;
-   unsigned char dummy2;
-   unsigned char address2       :4;
-   unsigned char control2       :4;
-   unsigned char point2;
-   unsigned char lead_out_start_msf[3];
-   struct
-   {
-      unsigned char address     :4;
-      unsigned char control     :4;
-      unsigned char track;
-      unsigned char track_start_msf[3];
-   } tracks[MAX_TRACKS];
-
-   unsigned int lead_out_start_lba;
-};
-
-struct s_sony_session_toc
-{
-   unsigned char exec_status[2];
-   unsigned char session_number;
-   unsigned char address0       :4;
-   unsigned char control0       :4;
-   unsigned char point0;
-   unsigned char first_track_num;
-   unsigned char disk_type;
-   unsigned char dummy0;
-   unsigned char address1       :4;
-   unsigned char control1       :4;
-   unsigned char point1;
-   unsigned char last_track_num;
-   unsigned char dummy1;
-   unsigned char dummy2;
-   unsigned char address2       :4;
-   unsigned char control2       :4;
-   unsigned char point2;
-   unsigned char lead_out_start_msf[3];
-   unsigned char addressb0      :4;
-   unsigned char controlb0      :4;
-   unsigned char pointb0;
-   unsigned char next_poss_prog_area_msf[3];
-   unsigned char num_mode_5_pointers;
-   unsigned char max_start_outer_leadout_msf[3];
-   unsigned char addressb1      :4;
-   unsigned char controlb1      :4;
-   unsigned char pointb1;
-   unsigned char dummyb0_1[4];
-   unsigned char num_skip_interval_pointers;
-   unsigned char num_skip_track_assignments;
-   unsigned char dummyb0_2;
-   unsigned char addressb2      :4;
-   unsigned char controlb2      :4;
-   unsigned char pointb2;
-   unsigned char tracksb2[7];
-   unsigned char addressb3      :4;
-   unsigned char controlb3      :4;
-   unsigned char pointb3;
-   unsigned char tracksb3[7];
-   unsigned char addressb4      :4;
-   unsigned char controlb4      :4;
-   unsigned char pointb4;
-   unsigned char tracksb4[7];
-   unsigned char addressc0      :4;
-   unsigned char controlc0      :4;
-   unsigned char pointc0;
-   unsigned char dummyc0[7];
-   struct
-   {
-      unsigned char address     :4;
-      unsigned char control     :4;
-      unsigned char track;
-      unsigned char track_start_msf[3];
-   } tracks[MAX_TRACKS];
-
-   unsigned int start_track_lba;
-   unsigned int lead_out_start_lba;
-   unsigned int mint;
-   unsigned int maxt;
-};
-
-struct s_all_sessions_toc
-{
-   unsigned char sessions;
-   unsigned int track_entries;
-   unsigned char first_track_num;
-   unsigned char last_track_num;
-   unsigned char disk_type;
-   unsigned char lead_out_start_msf[3];
-   struct
-   {
-      unsigned char address     :4;
-      unsigned char control     :4;
-      unsigned char track;
-      unsigned char track_start_msf[3];
-   } tracks[MAX_TRACKS];
-
-   unsigned int start_track_lba;
-   unsigned int lead_out_start_lba;
-};
-
-
-/*
- * The following are errors returned from the drive.
- */
-
-/* Command error group */
-#define SONY_ILL_CMD_ERR                0x10
-#define SONY_ILL_PARAM_ERR              0x11
-
-/* Mechanism group */
-#define SONY_NOT_LOAD_ERR               0x20
-#define SONY_NO_DISK_ERR                0x21
-#define SONY_NOT_SPIN_ERR               0x22
-#define SONY_SPIN_ERR                   0x23
-#define SONY_SPINDLE_SERVO_ERR          0x25
-#define SONY_FOCUS_SERVO_ERR            0x26
-#define SONY_EJECT_MECH_ERR             0x29
-#define SONY_AUDIO_PLAYING_ERR          0x2a
-#define SONY_EMERGENCY_EJECT_ERR        0x2c
-
-/* Seek error group */
-#define SONY_FOCUS_ERR                  0x30
-#define SONY_FRAME_SYNC_ERR             0x31
-#define SONY_SUBCODE_ADDR_ERR           0x32
-#define SONY_BLOCK_SYNC_ERR             0x33
-#define SONY_HEADER_ADDR_ERR            0x34
-
-/* Read error group */
-#define SONY_ILL_TRACK_R_ERR            0x40
-#define SONY_MODE_0_R_ERR               0x41
-#define SONY_ILL_MODE_R_ERR             0x42
-#define SONY_ILL_BLOCK_SIZE_R_ERR       0x43
-#define SONY_MODE_R_ERR                 0x44
-#define SONY_FORM_R_ERR                 0x45
-#define SONY_LEAD_OUT_R_ERR             0x46
-#define SONY_BUFFER_OVERRUN_R_ERR       0x47
-
-/* Data error group */
-#define SONY_UNREC_CIRC_ERR             0x53
-#define SONY_UNREC_LECC_ERR             0x57
-
-/* Subcode error group */
-#define SONY_NO_TOC_ERR                 0x60
-#define SONY_SUBCODE_DATA_NVAL_ERR      0x61
-#define SONY_FOCUS_ON_TOC_READ_ERR      0x63
-#define SONY_FRAME_SYNC_ON_TOC_READ_ERR 0x64
-#define SONY_TOC_DATA_ERR               0x65
-
-/* Hardware failure group */
-#define SONY_HW_FAILURE_ERR             0x70
-#define SONY_LEAD_IN_A_ERR              0x91
-#define SONY_LEAD_OUT_A_ERR             0x92
-#define SONY_DATA_TRACK_A_ERR           0x93
-
-/*
- * The following are returned from the Read With Block Error Status command.
- * They are not errors but information (Errors from the 0x5x group above may
- * also be returned
- */
-#define SONY_NO_CIRC_ERR_BLK_STAT       0x50
-#define SONY_NO_LECC_ERR_BLK_STAT       0x54
-#define SONY_RECOV_LECC_ERR_BLK_STAT    0x55
-#define SONY_NO_ERR_DETECTION_STAT      0x59
-
-/* 
- * The following is not an error returned by the drive, but by the code
- * that talks to the drive.  It is returned because of a timeout.
- */
-#define SONY_TIMEOUT_OP_ERR             0x01
-#define SONY_SIGNAL_OP_ERR              0x02
-#define SONY_BAD_DATA_ERR               0x03
-
-
-/*
- * The following are attention code for asynchronous events from the drive.
- */
-
-/* Standard attention group */
-#define SONY_EMER_EJECT_ATTN            0x2c
-#define SONY_HW_FAILURE_ATTN            0x70
-#define SONY_MECH_LOADED_ATTN           0x80
-#define SONY_EJECT_PUSHED_ATTN          0x81
-
-/* Audio attention group */
-#define SONY_AUDIO_PLAY_DONE_ATTN       0x90
-#define SONY_LEAD_IN_ERR_ATTN           0x91
-#define SONY_LEAD_OUT_ERR_ATTN          0x92
-#define SONY_DATA_TRACK_ERR_ATTN        0x93
-#define SONY_AUDIO_PLAYBACK_ERR_ATTN    0x94
-
-/* Auto spin up group */
-#define SONY_SPIN_UP_COMPLETE_ATTN      0x24
-#define SONY_SPINDLE_SERVO_ERR_ATTN     0x25
-#define SONY_FOCUS_SERVO_ERR_ATTN       0x26
-#define SONY_TOC_READ_DONE_ATTN         0x62
-#define SONY_FOCUS_ON_TOC_READ_ERR_ATTN 0x63
-#define SONY_SYNC_ON_TOC_READ_ERR_ATTN  0x65
-
-/* Auto eject group */
-#define SONY_SPIN_DOWN_COMPLETE_ATTN    0x27
-#define SONY_EJECT_COMPLETE_ATTN        0x28
-#define SONY_EJECT_MECH_ERR_ATTN        0x29
diff --git a/drivers/cdrom/cm206.c b/drivers/cdrom/cm206.c
deleted file mode 100644 (file)
index 2301311..0000000
+++ /dev/null
@@ -1,1594 +0,0 @@
-/* cm206.c. A linux-driver for the cm206 cdrom player with cm260 adapter card.
-   Copyright (c) 1995--1997 David A. van Leeuwen.
-   $Id: cm206.c,v 1.5 1997/12/26 11:02:51 david Exp $
-   
-     This program is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published by
-     the Free Software Foundation; either version 2 of the License, or
-     (at your option) any later version.
-     
-     This program is distributed in the hope that it will be useful,
-     but WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-     GNU General Public License for more details.
-     
-     You 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.
-
-History:
- Started 25 jan 1994. Waiting for documentation...
- 22 feb 1995: 0.1a first reasonably safe polling driver.
-             Two major bugs, one in read_sector and one in 
-             do_cm206_request, happened to cancel!
- 25 feb 1995: 0.2a first reasonable interrupt driven version of above.
-              uart writes are still done in polling mode. 
- 25 feb 1995: 0.21a writes also in interrupt mode, still some
-             small bugs to be found... Larger buffer. 
-  2 mrt 1995: 0.22 Bug found (cd-> nowhere, interrupt was called in
-              initialization), read_ahead of 16. Timeouts implemented.
-             unclear if they do something...
-  7 mrt 1995: 0.23 Start of background read-ahead.
- 18 mrt 1995: 0.24 Working background read-ahead. (still problems)
- 26 mrt 1995: 0.25 Multi-session ioctl added (kernel v1.2).
-              Statistics implemented, though separate stats206.h.
-             Accessible through ioctl 0x1000 (just a number).
-             Hard to choose between v1.2 development and 1.1.75.
-             Bottom-half doesn't work with 1.2...
-             0.25a: fixed... typo. Still problems...
-  1 apr 1995: 0.26 Module support added. Most bugs found. Use kernel 1.2.n.
-  5 apr 1995: 0.27 Auto-probe for the adapter card base address.
-              Auto-probe for the adaptor card irq line.
-  7 apr 1995: 0.28 Added lilo setup support for base address and irq.
-              Use major number 32 (not in this source), officially
-             assigned to this driver.
-  9 apr 1995: 0.29 Added very limited audio support. Toc_header, stop, pause,
-              resume, eject. Play_track ignores track info, because we can't 
-             read a table-of-contents entry. Toc_entry is implemented
-             as a `placebo' function: always returns start of disc. 
-  3 may 1995: 0.30 Audio support completed. The get_toc_entry function
-              is implemented as a binary search. 
- 15 may 1995: 0.31 More work on audio stuff. Workman is not easy to 
-              satisfy; changed binary search into linear search.
-             Auto-probe for base address somewhat relaxed.
-  1 jun 1995: 0.32 Removed probe_irq_on/off for module version.
- 10 jun 1995: 0.33 Workman still behaves funny, but you should be
-              able to eject and substitute another disc.
-
- An adaptation of 0.33 is included in linux-1.3.7 by Eberhard Moenkeberg
-
- 18 jul 1995: 0.34 Patch by Heiko Eissfeldt included, mainly considering 
-              verify_area's in the ioctls. Some bugs introduced by 
-             EM considering the base port and irq fixed. 
-
- 18 dec 1995: 0.35 Add some code for error checking... no luck...
-
- We jump to reach our goal: version 1.0 in the next stable linux kernel.
-
- 19 mar 1996: 0.95 Different implementation of CDROM_GET_UPC, on
-             request of Thomas Quinot. 
- 25 mar 1996: 0.96 Interpretation of opening with O_WRONLY or O_RDWR:
-             open only for ioctl operation, e.g., for operation of
-             tray etc.
- 4 apr 1996:  0.97 First implementation of layer between VFS and cdrom
-              driver, a generic interface. Much of the functionality
-             of cm206_open() and cm206_ioctl() is transferred to a
-             new file cdrom.c and its header ucdrom.h. 
-
-             Upgrade to Linux kernel 1.3.78. 
-
- 11 apr 1996  0.98 Upgrade to Linux kernel 1.3.85
-              More code moved to cdrom.c
-             0.99 Some more small changes to decrease number
-             of oopses at module load; 
- 27 jul 1996  0.100 Many hours of debugging, kernel change from 1.2.13
-             to 2.0.7 seems to have introduced some weird behavior
-             in (interruptible_)sleep_on(&cd->data): the process
-             seems to be woken without any explicit wake_up in my own
-             code. Patch to try 100x in case such untriggered wake_up's 
-             occur. 
-
- 28 jul 1996  0.101 Rewriting of the code that receives the command echo,
-             using a fifo to store echoed bytes. 
-
-             Branch from 0.99:
-             0.99.1.0 Update to kernel release 2.0.10 dev_t -> kdev_t
-             (emoenke) various typos found by others.  extra
-             module-load oops protection.
-             0.99.1.1 Initialization constant cdrom_dops.speed
-             changed from float (2.0) to int (2); Cli()-sti() pair
-             around cm260_reset() in module initialization code.
-             0.99.1.2 Changes literally as proposed by Scott Snyder
-             <snyder@d0sgif.fnal.gov> for the 2.1 kernel line, which
-             have to do mainly with the poor minor support i had. The
-             major new concept is to change a cdrom driver's
-             operations struct from the capabilities struct. This
-             reflects the fact that there is one major for a driver,
-             whilst there can be many minors whith completely
-             different capabilities.
-
-             0.99.1.3 More changes for operations/info separation.
-
-             0.99.1.4 Added speed selection (someone had to do this
-             first).
-
-  23 jan 1997 0.99.1.5 MODULE_PARMS call added.
-
-  23 jan 1997 0.100.1.2--0.100.1.5 following similar lines as 
-             0.99.1.1--0.99.1.5. I get too many complaints about the
-             drive making read errors. What't wrong with the 2.0+
-             kernel line? Why get i (and othe cm206 owners) weird
-             results? Why were things good in the good old 1.1--1.2 
-             era? Why don't i throw away the drive?
-
- 2 feb 1997   0.102 Added `volatile' to values in cm206_struct. Seems to 
-             reduce many of the problems. Rewrote polling routines
-             to use fixed delays between polls. 
-             0.103 Changed printk behavior. 
-             0.104 Added a 0.100 -> 0.100.1.1 change
-
-11 feb 1997   0.105 Allow auto_probe during module load, disable
-              with module option "auto_probe=0". Moved some debugging
-             statements to lower priority. Implemented select_speed()
-             function. 
-
-13 feb 1997   1.0 Final version for 2.0 kernel line. 
-
-             All following changes will be for the 2.1 kernel line. 
-
-15 feb 1997   1.1 Keep up with kernel 2.1.26, merge in changes from 
-              cdrom.c 0.100.1.1--1.0. Add some more MODULE_PARMS. 
-
-14 sep 1997   1.2 Upgrade to Linux 2.1.55.  Added blksize_size[], patch
-              sent by James Bottomley <James.Bottomley@columbiasc.ncr.com>.
-
-21 dec 1997   1.4 Upgrade to Linux 2.1.72.  
-
-24 jan 1998   Removed the cm206_disc_status() function, as it was now dead
-              code.  The Uniform CDROM driver now provides this functionality.
-             
-9 Nov. 1999   Make kernel-parameter implementation work with 2.3.x 
-             Removed init_module & cleanup_module in favor of 
-             module_init & module_exit.
-             Torben Mathiasen <tmm@image.dk>
- * 
- * Parts of the code are based upon lmscd.c written by Kai Petzke,
- * sbpcd.c written by Eberhard Moenkeberg, and mcd.c by Martin
- * Harriss, but any off-the-shelf dynamic programming algorithm won't
- * be able to find them.
- *
- * The cm206 drive interface and the cm260 adapter card seem to be 
- * sufficiently different from their cm205/cm250 counterparts
- * in order to write a complete new driver.
- * 
- * I call all routines connected to the Linux kernel something
- * with `cm206' in it, as this stuff is too series-dependent. 
- * 
- * Currently, my limited knowledge is based on:
- * - The Linux Kernel Hacker's guide, v. 0.5, by Michael K. Johnson
- * - Linux Kernel Programmierung, by Michael Beck and others
- * - Philips/LMS cm206 and cm226 product specification
- * - Philips/LMS cm260 product specification
- *
- * David van Leeuwen, david@tm.tno.nl.  */
-#define REVISION "$Revision: 1.5 $"
-
-#include <linux/module.h>
-
-#include <linux/errno.h>       /* These include what we really need */
-#include <linux/delay.h>
-#include <linux/string.h>
-#include <linux/interrupt.h>
-#include <linux/timer.h>
-#include <linux/cdrom.h>
-#include <linux/ioport.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-
-/* #include <linux/ucdrom.h> */
-
-#include <asm/io.h>
-
-#define MAJOR_NR CM206_CDROM_MAJOR
-
-#include <linux/blkdev.h>
-
-#undef DEBUG
-#define STATISTICS             /* record times and frequencies of events */
-#define AUTO_PROBE_MODULE
-#define USE_INSW
-
-#include "cm206.h"
-
-/* This variable defines whether or not to probe for adapter base port 
-   address and interrupt request. It can be overridden by the boot 
-   parameter `auto'.
-*/
-static int auto_probe = 1;     /* Yes, why not? */
-
-static int cm206_base = CM206_BASE;
-static int cm206_irq = CM206_IRQ;
-#ifdef MODULE
-static int cm206[2] = { 0, 0 };        /* for compatible `insmod' parameter passing */
-module_param_array(cm206, int, NULL, 0);       /* base,irq or irq,base */
-#endif
-
-module_param(cm206_base, int, 0);      /* base */
-module_param(cm206_irq, int, 0);       /* irq */
-module_param(auto_probe, bool, 0);     /* auto probe base and irq */
-MODULE_LICENSE("GPL");
-
-#define POLLOOP 100            /* milliseconds */
-#define READ_AHEAD 1           /* defines private buffer, waste! */
-#define BACK_AHEAD 1           /* defines adapter-read ahead */
-#define DATA_TIMEOUT (3*HZ)    /* measured in jiffies (10 ms) */
-#define UART_TIMEOUT (5*HZ/100)
-#define DSB_TIMEOUT (7*HZ)     /* time for the slowest command to finish */
-#define UR_SIZE 4              /* uart receive buffer fifo size */
-
-#define LINUX_BLOCK_SIZE 512   /* WHERE is this defined? */
-#define RAW_SECTOR_SIZE 2352   /* ok, is also defined in cdrom.h */
-#define ISO_SECTOR_SIZE 2048
-#define BLOCKS_ISO (ISO_SECTOR_SIZE/LINUX_BLOCK_SIZE)  /* 4 */
-#define CD_SYNC_HEAD 16                /* CD_SYNC + CD_HEAD */
-
-#ifdef STATISTICS              /* keep track of errors in counters */
-#define stats(i) { ++cd->stats[st_ ## i]; \
-                    cd->last_stat[st_ ## i] = cd->stat_counter++; \
-                }
-#else
-#define stats(i) (void) 0;
-#endif
-
-#define Debug(a) {printk (KERN_DEBUG); printk a;}
-#ifdef DEBUG
-#define debug(a) Debug(a)
-#else
-#define debug(a) (void) 0;
-#endif
-
-typedef unsigned char uch;     /* 8-bits */
-typedef unsigned short ush;    /* 16-bits */
-
-struct toc_struct {            /* private copy of Table of Contents */
-       uch track, fsm[3], q0;
-};
-
-struct cm206_struct {
-       volatile ush intr_ds;   /* data status read on last interrupt */
-       volatile ush intr_ls;   /* uart line status read on last interrupt */
-       volatile uch ur[UR_SIZE];       /* uart receive buffer fifo */
-       volatile uch ur_w, ur_r;        /* write/read buffer index */
-       volatile uch dsb, cc;   /* drive status byte and condition (error) code */
-       int command;            /* command to be written to the uart */
-       int openfiles;
-       ush sector[READ_AHEAD * RAW_SECTOR_SIZE / 2];   /* buffered cd-sector */
-       int sector_first, sector_last;  /* range of these sectors */
-       wait_queue_head_t uart; /* wait queues for interrupt */
-       wait_queue_head_t data;
-       struct timer_list timer;        /* time-out */
-       char timed_out;
-       signed char max_sectors;        /* number of sectors that fit in adapter mem */
-       char wait_back;         /* we're waiting for a background-read */
-       char background;        /* is a read going on in the background? */
-       int adapter_first;      /* if so, that's the starting sector */
-       int adapter_last;
-       char fifo_overflowed;
-       uch disc_status[7];     /* result of get_disc_status command */
-#ifdef STATISTICS
-       int stats[NR_STATS];
-       int last_stat[NR_STATS];        /* `time' at which stat was stat */
-       int stat_counter;
-#endif
-       struct toc_struct toc[101];     /* The whole table of contents + lead-out */
-       uch q[10];              /* Last read q-channel info */
-       uch audio_status[5];    /* last read position on pause */
-       uch media_changed;      /* record if media changed */
-};
-
-#define DISC_STATUS cd->disc_status[0]
-#define FIRST_TRACK cd->disc_status[1]
-#define LAST_TRACK cd->disc_status[2]
-#define PAUSED cd->audio_status[0]     /* misuse this memory byte! */
-#define PLAY_TO cd->toc[0]     /* toc[0] records end-time in play */
-
-static struct cm206_struct *cd;        /* the main memory structure */
-static struct request_queue *cm206_queue;
-static DEFINE_SPINLOCK(cm206_lock);
-
-/* First, we define some polling functions. These are actually
-   only being used in the initialization. */
-
-static void send_command_polled(int command)
-{
-       int loop = POLLOOP;
-       while (!(inw(r_line_status) & ls_transmitter_buffer_empty)
-              && loop > 0) {
-               mdelay(1);      /* one millisec delay */
-               --loop;
-       }
-       outw(command, r_uart_transmit);
-}
-
-static uch receive_echo_polled(void)
-{
-       int loop = POLLOOP;
-       while (!(inw(r_line_status) & ls_receive_buffer_full) && loop > 0) {
-               mdelay(1);
-               --loop;
-       }
-       return ((uch) inw(r_uart_receive));
-}
-
-static uch send_receive_polled(int command)
-{
-       send_command_polled(command);
-       return receive_echo_polled();
-}
-
-static inline void clear_ur(void)
-{
-       if (cd->ur_r != cd->ur_w) {
-               debug(("Deleting bytes from fifo:"));
-               for (; cd->ur_r != cd->ur_w;
-                    cd->ur_r++, cd->ur_r %= UR_SIZE)
-                       debug((" 0x%x", cd->ur[cd->ur_r]));
-               debug(("\n"));
-       }
-}
-
-static struct tasklet_struct cm206_tasklet;
-
-/* The interrupt handler. When the cm260 generates an interrupt, very
-   much care has to be taken in reading out the registers in the right
-   order; in case of a receive_buffer_full interrupt, first the
-   uart_receive must be read, and then the line status again to
-   de-assert the interrupt line. It took me a couple of hours to find
-   this out:-( 
-
-   The function reset_cm206 appears to cause an interrupt, because
-   pulling up the INIT line clears both the uart-write-buffer /and/
-   the uart-write-buffer-empty mask. We call this a `lost interrupt,'
-   as there seems so reason for this to happen.
-*/
-
-static irqreturn_t cm206_interrupt(int sig, void *dev_id)
-{
-       volatile ush fool;
-       cd->intr_ds = inw(r_data_status);       /* resets data_ready, data_error,
-                                                  crc_error, sync_error, toc_ready 
-                                                  interrupts */
-       cd->intr_ls = inw(r_line_status);       /* resets overrun bit */
-       debug(("Intr, 0x%x 0x%x, %d\n", cd->intr_ds, cd->intr_ls,
-              cd->background));
-       if (cd->intr_ls & ls_attention)
-               stats(attention);
-       /* receive buffer full? */
-       if (cd->intr_ls & ls_receive_buffer_full) {
-               cd->ur[cd->ur_w] = inb(r_uart_receive); /* get order right! */
-               cd->intr_ls = inw(r_line_status);       /* resets rbf interrupt */
-               debug(("receiving #%d: 0x%x\n", cd->ur_w,
-                      cd->ur[cd->ur_w]));
-               cd->ur_w++;
-               cd->ur_w %= UR_SIZE;
-               if (cd->ur_w == cd->ur_r)
-                       debug(("cd->ur overflow!\n"));
-               if (waitqueue_active(&cd->uart) && cd->background < 2) {
-                       del_timer(&cd->timer);
-                       wake_up_interruptible(&cd->uart);
-               }
-       }
-       /* data ready in fifo? */
-       else if (cd->intr_ds & ds_data_ready) {
-               if (cd->background)
-                       ++cd->adapter_last;
-               if (waitqueue_active(&cd->data)
-                   && (cd->wait_back || !cd->background)) {
-                       del_timer(&cd->timer);
-                       wake_up_interruptible(&cd->data);
-               }
-               stats(data_ready);
-       }
-       /* ready to issue a write command? */
-       else if (cd->command && cd->intr_ls & ls_transmitter_buffer_empty) {
-               outw(dc_normal | (inw(r_data_status) & 0x7f),
-                    r_data_control);
-               outw(cd->command, r_uart_transmit);
-               cd->command = 0;
-               if (!cd->background)
-                       wake_up_interruptible(&cd->uart);
-       }
-       /* now treat errors (at least, identify them for debugging) */
-       else if (cd->intr_ds & ds_fifo_overflow) {
-               debug(("Fifo overflow at sectors 0x%x\n",
-                      cd->sector_first));
-               fool = inw(r_fifo_output_buffer);       /* de-assert the interrupt */
-               cd->fifo_overflowed = 1;        /* signal one word less should be read */
-               stats(fifo_overflow);
-       } else if (cd->intr_ds & ds_data_error) {
-               debug(("Data error at sector 0x%x\n", cd->sector_first));
-               stats(data_error);
-       } else if (cd->intr_ds & ds_crc_error) {
-               debug(("CRC error at sector 0x%x\n", cd->sector_first));
-               stats(crc_error);
-       } else if (cd->intr_ds & ds_sync_error) {
-               debug(("Sync at sector 0x%x\n", cd->sector_first));
-               stats(sync_error);
-       } else if (cd->intr_ds & ds_toc_ready) {
-               /* do something appropriate */
-       }
-       /* couldn't see why this interrupt, maybe due to init */
-       else {
-               outw(dc_normal | READ_AHEAD, r_data_control);
-               stats(lost_intr);
-       }
-       if (cd->background
-           && (cd->adapter_last - cd->adapter_first == cd->max_sectors
-               || cd->fifo_overflowed))
-               tasklet_schedule(&cm206_tasklet);       /* issue a stop read command */
-       stats(interrupt);
-       return IRQ_HANDLED;
-}
-
-/* we have put the address of the wait queue in who */
-static void cm206_timeout(unsigned long who)
-{
-       cd->timed_out = 1;
-       debug(("Timing out\n"));
-       wake_up_interruptible((wait_queue_head_t *) who);
-}
-
-/* This function returns 1 if a timeout occurred, 0 if an interrupt
-   happened */
-static int sleep_or_timeout(wait_queue_head_t * wait, int timeout)
-{
-       cd->timed_out = 0;
-       init_timer(&cd->timer);
-       cd->timer.data = (unsigned long) wait;
-       cd->timer.expires = jiffies + timeout;
-       add_timer(&cd->timer);
-       debug(("going to sleep\n"));
-       interruptible_sleep_on(wait);
-       del_timer(&cd->timer);
-       if (cd->timed_out) {
-               cd->timed_out = 0;
-               return 1;
-       } else
-               return 0;
-}
-
-static void send_command(int command)
-{
-       debug(("Sending 0x%x\n", command));
-       if (!(inw(r_line_status) & ls_transmitter_buffer_empty)) {
-               cd->command = command;
-               cli();          /* don't interrupt before sleep */
-               outw(dc_mask_sync_error | dc_no_stop_on_error |
-                    (inw(r_data_status) & 0x7f), r_data_control);
-               /* interrupt routine sends command */
-               if (sleep_or_timeout(&cd->uart, UART_TIMEOUT)) {
-                       debug(("Time out on write-buffer\n"));
-                       stats(write_timeout);
-                       outw(command, r_uart_transmit);
-               }
-               debug(("Write commmand delayed\n"));
-       } else
-               outw(command, r_uart_transmit);
-}
-
-static uch receive_byte(int timeout)
-{
-       uch ret;
-       cli();
-       debug(("cli\n"));
-       ret = cd->ur[cd->ur_r];
-       if (cd->ur_r != cd->ur_w) {
-               sti();
-               debug(("returning #%d: 0x%x\n", cd->ur_r,
-                      cd->ur[cd->ur_r]));
-               cd->ur_r++;
-               cd->ur_r %= UR_SIZE;
-               return ret;
-       } else if (sleep_or_timeout(&cd->uart, timeout)) {      /* does sti() */
-               debug(("Time out on receive-buffer\n"));
-#ifdef STATISTICS
-               if (timeout == UART_TIMEOUT)
-                       stats(receive_timeout)  /* no `;'! */
-                           else
-                       stats(dsb_timeout);
-#endif
-               return 0xda;
-       }
-       ret = cd->ur[cd->ur_r];
-       debug(("slept; returning #%d: 0x%x\n", cd->ur_r,
-              cd->ur[cd->ur_r]));
-       cd->ur_r++;
-       cd->ur_r %= UR_SIZE;
-       return ret;
-}
-
-static inline uch receive_echo(void)
-{
-       return receive_byte(UART_TIMEOUT);
-}
-
-static inline uch send_receive(int command)
-{
-       send_command(command);
-       return receive_echo();
-}
-
-static inline uch wait_dsb(void)
-{
-       return receive_byte(DSB_TIMEOUT);
-}
-
-static int type_0_command(int command, int expect_dsb)
-{
-       int e;
-       clear_ur();
-       if (command != (e = send_receive(command))) {
-               debug(("command 0x%x echoed as 0x%x\n", command, e));
-               stats(echo);
-               return -1;
-       }
-       if (expect_dsb) {
-               cd->dsb = wait_dsb();   /* wait for command to finish */
-       }
-       return 0;
-}
-
-static int type_1_command(int command, int bytes, uch * status)
-{                              /* returns info */
-       int i;
-       if (type_0_command(command, 0))
-               return -1;
-       for (i = 0; i < bytes; i++)
-               status[i] = send_receive(c_gimme);
-       return 0;
-}
-
-/* This function resets the adapter card. We'd better not do this too
- * often, because it tends to generate `lost interrupts.' */
-static void reset_cm260(void)
-{
-       outw(dc_normal | dc_initialize | READ_AHEAD, r_data_control);
-       udelay(10);             /* 3.3 mu sec minimum */
-       outw(dc_normal | READ_AHEAD, r_data_control);
-}
-
-/* fsm: frame-sec-min from linear address; one of many */
-static void fsm(int lba, uch * fsm)
-{
-       fsm[0] = lba % 75;
-       lba /= 75;
-       lba += 2;
-       fsm[1] = lba % 60;
-       fsm[2] = lba / 60;
-}
-
-static inline int fsm2lba(uch * fsm)
-{
-       return fsm[0] + 75 * (fsm[1] - 2 + 60 * fsm[2]);
-}
-
-static inline int f_s_m2lba(uch f, uch s, uch m)
-{
-       return f + 75 * (s - 2 + 60 * m);
-}
-
-static int start_read(int start)
-{
-       uch read_sector[4] = { c_read_data, };
-       int i, e;
-
-       fsm(start, &read_sector[1]);
-       clear_ur();
-       for (i = 0; i < 4; i++)
-               if (read_sector[i] != (e = send_receive(read_sector[i]))) {
-                       debug(("read_sector: %x echoes %x\n",
-                              read_sector[i], e));
-                       stats(echo);
-                       if (e == 0xff) {        /* this seems to happen often */
-                               e = receive_echo();
-                               debug(("Second try %x\n", e));
-                               if (e != read_sector[i])
-                                       return -1;
-                       }
-               }
-       return 0;
-}
-
-static int stop_read(void)
-{
-       int e;
-       type_0_command(c_stop, 0);
-       if ((e = receive_echo()) != 0xff) {
-               debug(("c_stop didn't send 0xff, but 0x%x\n", e));
-               stats(stop_0xff);
-               return -1;
-       }
-       return 0;
-}
-
-/* This function starts to read sectors in adapter memory, the
-   interrupt routine should stop the read. In fact, the bottom_half
-   routine takes care of this. Set a flag `background' in the cd
-   struct to indicate the process. */
-
-static int read_background(int start, int reading)
-{
-       if (cd->background)
-               return -1;      /* can't do twice */
-       outw(dc_normal | BACK_AHEAD, r_data_control);
-       if (!reading && start_read(start))
-               return -2;
-       cd->adapter_first = cd->adapter_last = start;
-       cd->background = 1;     /* flag a read is going on */
-       return 0;
-}
-
-#ifdef USE_INSW
-#define transport_data insw
-#else
-/* this routine implements insw(,,). There was a time i had the
-   impression that there would be any difference in error-behaviour. */
-void transport_data(int port, ush * dest, int count)
-{
-       int i;
-       ush *d;
-       for (i = 0, d = dest; i < count; i++, d++)
-               *d = inw(port);
-}
-#endif
-
-
-#define MAX_TRIES 100
-static int read_sector(int start)
-{
-       int tries = 0;
-       if (cd->background) {
-               cd->background = 0;
-               cd->adapter_last = -1;  /* invalidate adapter memory */
-               stop_read();
-       }
-       cd->fifo_overflowed = 0;
-       reset_cm260();          /* empty fifo etc. */
-       if (start_read(start))
-               return -1;
-       do {
-               if (sleep_or_timeout(&cd->data, DATA_TIMEOUT)) {
-                       debug(("Read timed out sector 0x%x\n", start));
-                       stats(read_timeout);
-                       stop_read();
-                       return -3;
-               }
-               tries++;
-       } while (cd->intr_ds & ds_fifo_empty && tries < MAX_TRIES);
-       if (tries > 1)
-               debug(("Took me some tries\n"))
-                   else
-       if (tries == MAX_TRIES)
-               debug(("MAX_TRIES tries for read sector\n"));
-       transport_data(r_fifo_output_buffer, cd->sector,
-                      READ_AHEAD * RAW_SECTOR_SIZE / 2);
-       if (read_background(start + READ_AHEAD, 1))
-               stats(read_background);
-       cd->sector_first = start;
-       cd->sector_last = start + READ_AHEAD;
-       stats(read_restarted);
-       return 0;
-}
-
-/* The function of bottom-half is to send a stop command to the drive
-   This isn't easy because the routine is not `owned' by any process;
-   we can't go to sleep! The variable cd->background gives the status:
-   0 no read pending
-   1 a read is pending
-   2 c_stop waits for write_buffer_empty
-   3 c_stop waits for receive_buffer_full: echo
-   4 c_stop waits for receive_buffer_full: 0xff
-*/
-
-static void cm206_tasklet_func(unsigned long ignore)
-{
-       debug(("bh: %d\n", cd->background));
-       switch (cd->background) {
-       case 1:
-               stats(bh);
-               if (!(cd->intr_ls & ls_transmitter_buffer_empty)) {
-                       cd->command = c_stop;
-                       outw(dc_mask_sync_error | dc_no_stop_on_error |
-                            (inw(r_data_status) & 0x7f), r_data_control);
-                       cd->background = 2;
-                       break;  /* we'd better not time-out here! */
-               } else
-                       outw(c_stop, r_uart_transmit);
-               /* fall into case 2: */
-       case 2:
-               /* the write has been satisfied by interrupt routine */
-               cd->background = 3;
-               break;
-       case 3:
-               if (cd->ur_r != cd->ur_w) {
-                       if (cd->ur[cd->ur_r] != c_stop) {
-                               debug(("cm206_bh: c_stop echoed 0x%x\n",
-                                      cd->ur[cd->ur_r]));
-                               stats(echo);
-                       }
-                       cd->ur_r++;
-                       cd->ur_r %= UR_SIZE;
-               }
-               cd->background++;
-               break;
-       case 4:
-               if (cd->ur_r != cd->ur_w) {
-                       if (cd->ur[cd->ur_r] != 0xff) {
-                               debug(("cm206_bh: c_stop reacted with 0x%x\n", cd->ur[cd->ur_r]));
-                               stats(stop_0xff);
-                       }
-                       cd->ur_r++;
-                       cd->ur_r %= UR_SIZE;
-               }
-               cd->background = 0;
-       }
-}
-
-static DECLARE_TASKLET(cm206_tasklet, cm206_tasklet_func, 0);
-
-/* This command clears the dsb_possible_media_change flag, so we must 
- * retain it.
- */
-static void get_drive_status(void)
-{
-       uch status[2];
-       type_1_command(c_drive_status, 2, status);      /* this might be done faster */
-       cd->dsb = status[0];
-       cd->cc = status[1];
-       cd->media_changed |=
-           !!(cd->dsb & (dsb_possible_media_change |
-                         dsb_drive_not_ready | dsb_tray_not_closed));
-}
-
-static void get_disc_status(void)
-{
-       if (type_1_command(c_disc_status, 7, cd->disc_status)) {
-               debug(("get_disc_status: error\n"));
-       }
-}
-
-/* The new open. The real opening strategy is defined in cdrom.c. */
-
-static int cm206_open(struct cdrom_device_info *cdi, int purpose)
-{
-       if (!cd->openfiles) {   /* reset only first time */
-               cd->background = 0;
-               reset_cm260();
-               cd->adapter_last = -1;  /* invalidate adapter memory */
-               cd->sector_last = -1;
-       }
-       ++cd->openfiles;
-       stats(open);
-       return 0;
-}
-
-static void cm206_release(struct cdrom_device_info *cdi)
-{
-       if (cd->openfiles == 1) {
-               if (cd->background) {
-                       cd->background = 0;
-                       stop_read();
-               }
-               cd->sector_last = -1;   /* Make our internal buffer invalid */
-               FIRST_TRACK = 0;        /* No valid disc status */
-       }
-       --cd->openfiles;
-}
-
-/* Empty buffer empties $sectors$ sectors of the adapter card buffer,
- * and then reads a sector in kernel memory.  */
-static void empty_buffer(int sectors)
-{
-       while (sectors >= 0) {
-               transport_data(r_fifo_output_buffer,
-                              cd->sector + cd->fifo_overflowed,
-                              RAW_SECTOR_SIZE / 2 - cd->fifo_overflowed);
-               --sectors;
-               ++cd->adapter_first;    /* update the current adapter sector */
-               cd->fifo_overflowed = 0;        /* reset overflow bit */
-               stats(sector_transferred);
-       }
-       cd->sector_first = cd->adapter_first - 1;
-       cd->sector_last = cd->adapter_first;    /* update the buffer sector */
-}
-
-/* try_adapter. This function determines if the requested sector is
-   in adapter memory, or will appear there soon. Returns 0 upon
-   success */
-static int try_adapter(int sector)
-{
-       if (cd->adapter_first <= sector && sector < cd->adapter_last) {
-               /* sector is in adapter memory */
-               empty_buffer(sector - cd->adapter_first);
-               return 0;
-       } else if (cd->background == 1 && cd->adapter_first <= sector
-                  && sector < cd->adapter_first + cd->max_sectors) {
-               /* a read is going on, we can wait for it */
-               cd->wait_back = 1;
-               while (sector >= cd->adapter_last) {
-                       if (sleep_or_timeout(&cd->data, DATA_TIMEOUT)) {
-                               debug(("Timed out during background wait: %d %d %d %d\n", sector, cd->adapter_last, cd->adapter_first, cd->background));
-                               stats(back_read_timeout);
-                               cd->wait_back = 0;
-                               return -1;
-                       }
-               }
-               cd->wait_back = 0;
-               empty_buffer(sector - cd->adapter_first);
-               return 0;
-       } else
-               return -2;
-}
-
-/* This is not a very smart implementation. We could optimize for 
-   consecutive block numbers. I'm not convinced this would really
-   bring down the processor load. */
-static void do_cm206_request(request_queue_t * q)
-{
-       long int i, cd_sec_no;
-       int quarter, error;
-       uch *source, *dest;
-       struct request *req;
-
-       while (1) {     /* repeat until all requests have been satisfied */
-               req = elv_next_request(q);
-               if (!req)
-                       return;
-
-               if (req->cmd != READ) {
-                       debug(("Non-read command %d on cdrom\n", req->cmd));
-                       end_request(req, 0);
-                       continue;
-               }
-               spin_unlock_irq(q->queue_lock);
-               error = 0;
-               for (i = 0; i < req->nr_sectors; i++) {
-                       int e1, e2;
-                       cd_sec_no = (req->sector + i) / BLOCKS_ISO;     /* 4 times 512 bytes */
-                       quarter = (req->sector + i) % BLOCKS_ISO;
-                       dest = req->buffer + i * LINUX_BLOCK_SIZE;
-                       /* is already in buffer memory? */
-                       if (cd->sector_first <= cd_sec_no
-                           && cd_sec_no < cd->sector_last) {
-                               source =
-                                   ((uch *) cd->sector) + 16 +
-                                   quarter * LINUX_BLOCK_SIZE +
-                                   (cd_sec_no -
-                                    cd->sector_first) * RAW_SECTOR_SIZE;
-                               memcpy(dest, source, LINUX_BLOCK_SIZE);
-                       } else if (!(e1 = try_adapter(cd_sec_no)) ||
-                                  !(e2 = read_sector(cd_sec_no))) {
-                               source =
-                                   ((uch *) cd->sector) + 16 +
-                                   quarter * LINUX_BLOCK_SIZE;
-                               memcpy(dest, source, LINUX_BLOCK_SIZE);
-                       } else {
-                               error = 1;
-                               debug(("cm206_request: %d %d\n", e1, e2));
-                       }
-               }
-               spin_lock_irq(q->queue_lock);
-               end_request(req, !error);
-       }
-}
-
-/* Audio support. I've tried very hard, but the cm206 drive doesn't 
-   seem to have a get_toc (table-of-contents) function, while i'm
-   pretty sure it must read the toc upon disc insertion. Therefore
-   this function has been implemented through a binary search 
-   strategy. All track starts that happen to be found are stored in
-   cd->toc[], for future use. 
-
-   I've spent a whole day on a bug that only shows under Workman---
-   I don't get it. Tried everything, nothing works. If workman asks
-   for track# 0xaa, it'll get the wrong time back. Any other program
-   receives the correct value. I'm stymied.
-*/
-
-/* seek seeks to address lba. It does wait to arrive there. */
-static void seek(int lba)
-{
-       int i;
-       uch seek_command[4] = { c_seek, };
-
-       fsm(lba, &seek_command[1]);
-       for (i = 0; i < 4; i++)
-               type_0_command(seek_command[i], 0);
-       cd->dsb = wait_dsb();
-}
-
-static uch bcdbin(unsigned char bcd)
-{                              /* stolen from mcd.c! */
-       return (bcd >> 4) * 10 + (bcd & 0xf);
-}
-
-static inline uch normalize_track(uch track)
-{
-       if (track < 1)
-               return 1;
-       if (track > LAST_TRACK)
-               return LAST_TRACK + 1;
-       return track;
-}
-
-/* This function does a binary search for track start. It records all
- * tracks seen in the process. Input $track$ must be between 1 and
- * #-of-tracks+1.  Note that the start of the disc must be in toc[1].fsm. 
- */
-static int get_toc_lba(uch track)
-{
-       int max = 74 * 60 * 75 - 150, min = fsm2lba(cd->toc[1].fsm);
-       int i, lba, l, old_lba = 0;
-       uch *q = cd->q;
-       uch ct;                 /* current track */
-       int binary = 0;
-       const int skip = 3 * 60 * 75;   /* 3 minutes */
-
-       for (i = track; i > 0; i--)
-               if (cd->toc[i].track) {
-                       min = fsm2lba(cd->toc[i].fsm);
-                       break;
-               }
-       lba = min + skip;
-       do {
-               seek(lba);
-               type_1_command(c_read_current_q, 10, q);
-               ct = normalize_track(q[1]);
-               if (!cd->toc[ct].track) {
-                       l = q[9] - bcdbin(q[5]) + 75 * (q[8] -
-                                                       bcdbin(q[4]) - 2 +
-                                                       60 * (q[7] -
-                                                             bcdbin(q
-                                                                    [3])));
-                       cd->toc[ct].track = q[1];       /* lead out still 0xaa */
-                       fsm(l, cd->toc[ct].fsm);
-                       cd->toc[ct].q0 = q[0];  /* contains adr and ctrl info */
-                       if (ct == track)
-                               return l;
-               }
-               old_lba = lba;
-               if (binary) {
-                       if (ct < track)
-                               min = lba;
-                       else
-                               max = lba;
-                       lba = (min + max) / 2;
-               } else {
-                       if (ct < track)
-                               lba += skip;
-                       else {
-                               binary = 1;
-                               max = lba;
-                               min = lba - skip;
-                               lba = (min + max) / 2;
-                       }
-               }
-       } while (lba != old_lba);
-       return lba;
-}
-
-static void update_toc_entry(uch track)
-{
-       track = normalize_track(track);
-       if (!cd->toc[track].track)
-               get_toc_lba(track);
-}
-
-/* return 0 upon success */
-static int read_toc_header(struct cdrom_tochdr *hp)
-{
-       if (!FIRST_TRACK)
-               get_disc_status();
-       if (hp) {
-               int i;
-               hp->cdth_trk0 = FIRST_TRACK;
-               hp->cdth_trk1 = LAST_TRACK;
-               /* fill in first track position */
-               for (i = 0; i < 3; i++)
-                       cd->toc[1].fsm[i] = cd->disc_status[3 + i];
-               update_toc_entry(LAST_TRACK + 1);       /* find most entries */
-               return 0;
-       }
-       return -1;
-}
-
-static void play_from_to_msf(struct cdrom_msf *msfp)
-{
-       uch play_command[] = { c_play,
-               msfp->cdmsf_frame0, msfp->cdmsf_sec0, msfp->cdmsf_min0,
-               msfp->cdmsf_frame1, msfp->cdmsf_sec1, msfp->cdmsf_min1, 2,
-                   2
-       };
-       int i;
-       for (i = 0; i < 9; i++)
-               type_0_command(play_command[i], 0);
-       for (i = 0; i < 3; i++)
-               PLAY_TO.fsm[i] = play_command[i + 4];
-       PLAY_TO.track = 0;      /* say no track end */
-       cd->dsb = wait_dsb();
-}
-
-static void play_from_to_track(int from, int to)
-{
-       uch play_command[8] = { c_play, };
-       int i;
-
-       if (from == 0) {        /* continue paused play */
-               for (i = 0; i < 3; i++) {
-                       play_command[i + 1] = cd->audio_status[i + 2];
-                       play_command[i + 4] = PLAY_TO.fsm[i];
-               }
-       } else {
-               update_toc_entry(from);
-               update_toc_entry(to + 1);
-               for (i = 0; i < 3; i++) {
-                       play_command[i + 1] = cd->toc[from].fsm[i];
-                       PLAY_TO.fsm[i] = play_command[i + 4] =
-                           cd->toc[to + 1].fsm[i];
-               }
-               PLAY_TO.track = to;
-       }
-       for (i = 0; i < 7; i++)
-               type_0_command(play_command[i], 0);
-       for (i = 0; i < 2; i++)
-               type_0_command(0x2, 0); /* volume */
-       cd->dsb = wait_dsb();
-}
-
-static int get_current_q(struct cdrom_subchnl *qp)
-{
-       int i;
-       uch *q = cd->q;
-       if (type_1_command(c_read_current_q, 10, q))
-               return 0;
-/*  q[0] = bcdbin(q[0]); Don't think so! */
-       for (i = 2; i < 6; i++)
-               q[i] = bcdbin(q[i]);
-       qp->cdsc_adr = q[0] & 0xf;
-       qp->cdsc_ctrl = q[0] >> 4;      /* from mcd.c */
-       qp->cdsc_trk = q[1];
-       qp->cdsc_ind = q[2];
-       if (qp->cdsc_format == CDROM_MSF) {
-               qp->cdsc_reladdr.msf.minute = q[3];
-               qp->cdsc_reladdr.msf.second = q[4];
-               qp->cdsc_reladdr.msf.frame = q[5];
-               qp->cdsc_absaddr.msf.minute = q[7];
-               qp->cdsc_absaddr.msf.second = q[8];
-               qp->cdsc_absaddr.msf.frame = q[9];
-       } else {
-               qp->cdsc_reladdr.lba = f_s_m2lba(q[5], q[4], q[3]);
-               qp->cdsc_absaddr.lba = f_s_m2lba(q[9], q[8], q[7]);
-       }
-       get_drive_status();
-       if (cd->dsb & dsb_play_in_progress)
-               qp->cdsc_audiostatus = CDROM_AUDIO_PLAY;
-       else if (PAUSED)
-               qp->cdsc_audiostatus = CDROM_AUDIO_PAUSED;
-       else
-               qp->cdsc_audiostatus = CDROM_AUDIO_NO_STATUS;
-       return 0;
-}
-
-static void invalidate_toc(void)
-{
-       memset(cd->toc, 0, sizeof(cd->toc));
-       memset(cd->disc_status, 0, sizeof(cd->disc_status));
-}
-
-/* cdrom.c guarantees that cdte_format == CDROM_MSF */
-static void get_toc_entry(struct cdrom_tocentry *ep)
-{
-       uch track = normalize_track(ep->cdte_track);
-       update_toc_entry(track);
-       ep->cdte_addr.msf.frame = cd->toc[track].fsm[0];
-       ep->cdte_addr.msf.second = cd->toc[track].fsm[1];
-       ep->cdte_addr.msf.minute = cd->toc[track].fsm[2];
-       ep->cdte_adr = cd->toc[track].q0 & 0xf;
-       ep->cdte_ctrl = cd->toc[track].q0 >> 4;
-       ep->cdte_datamode = 0;
-}
-
-/* Audio ioctl.  Ioctl commands connected to audio are in such an
- * idiosyncratic i/o format, that we leave these untouched. Return 0
- * upon success. Memory checking has been done by cdrom_ioctl(), the
- * calling function, as well as LBA/MSF sanitization.
-*/
-static int cm206_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
-                            void *arg)
-{
-       switch (cmd) {
-       case CDROMREADTOCHDR:
-               return read_toc_header((struct cdrom_tochdr *) arg);
-       case CDROMREADTOCENTRY:
-               get_toc_entry((struct cdrom_tocentry *) arg);
-               return 0;
-       case CDROMPLAYMSF:
-               play_from_to_msf((struct cdrom_msf *) arg);
-               return 0;
-       case CDROMPLAYTRKIND:   /* admittedly, not particularly beautiful */
-               play_from_to_track(((struct cdrom_ti *) arg)->cdti_trk0,
-                                  ((struct cdrom_ti *) arg)->cdti_trk1);
-               return 0;
-       case CDROMSTOP:
-               PAUSED = 0;
-               if (cd->dsb & dsb_play_in_progress)
-                       return type_0_command(c_stop, 1);
-               else
-                       return 0;
-       case CDROMPAUSE:
-               get_drive_status();
-               if (cd->dsb & dsb_play_in_progress) {
-                       type_0_command(c_stop, 1);
-                       type_1_command(c_audio_status, 5,
-                                      cd->audio_status);
-                       PAUSED = 1;     /* say we're paused */
-               }
-               return 0;
-       case CDROMRESUME:
-               if (PAUSED)
-                       play_from_to_track(0, 0);
-               PAUSED = 0;
-               return 0;
-       case CDROMSTART:
-       case CDROMVOLCTRL:
-               return 0;
-       case CDROMSUBCHNL:
-               return get_current_q((struct cdrom_subchnl *) arg);
-       default:
-               return -EINVAL;
-       }
-}
-
-static int cm206_media_changed(struct cdrom_device_info *cdi, int disc_nr)
-{
-       if (cd != NULL) {
-               int r;
-               get_drive_status();     /* ensure cd->media_changed OK */
-               r = cd->media_changed;
-               cd->media_changed = 0;  /* clear bit */
-               return r;
-       } else
-               return -EIO;
-}
-
-/* The new generic cdrom support. Routines should be concise, most of
-   the logic should be in cdrom.c */
-
-
-/* controls tray movement */
-static int cm206_tray_move(struct cdrom_device_info *cdi, int position)
-{
-       if (position) {         /* 1: eject */
-               type_0_command(c_open_tray, 1);
-               invalidate_toc();
-       } else
-               type_0_command(c_close_tray, 1);        /* 0: close */
-       return 0;
-}
-
-/* gives current state of the drive */
-static int cm206_drive_status(struct cdrom_device_info *cdi, int slot_nr)
-{
-       get_drive_status();
-       if (cd->dsb & dsb_tray_not_closed)
-               return CDS_TRAY_OPEN;
-       if (!(cd->dsb & dsb_disc_present))
-               return CDS_NO_DISC;
-       if (cd->dsb & dsb_drive_not_ready)
-               return CDS_DRIVE_NOT_READY;
-       return CDS_DISC_OK;
-}
-
-/* locks or unlocks door lock==1: lock; return 0 upon success */
-static int cm206_lock_door(struct cdrom_device_info *cdi, int lock)
-{
-       uch command = (lock) ? c_lock_tray : c_unlock_tray;
-       type_0_command(command, 1);     /* wait and get dsb */
-       /* the logic calculates the success, 0 means successful */
-       return lock ^ ((cd->dsb & dsb_tray_locked) != 0);
-}
-
-/* Although a session start should be in LBA format, we return it in 
-   MSF format because it is slightly easier, and the new generic ioctl
-   will take care of the necessary conversion. */
-static int cm206_get_last_session(struct cdrom_device_info *cdi,
-                                 struct cdrom_multisession *mssp)
-{
-       if (!FIRST_TRACK)
-               get_disc_status();
-       if (mssp != NULL) {
-               if (DISC_STATUS & cds_multi_session) {  /* multi-session */
-                       mssp->addr.msf.frame = cd->disc_status[3];
-                       mssp->addr.msf.second = cd->disc_status[4];
-                       mssp->addr.msf.minute = cd->disc_status[5];
-                       mssp->addr_format = CDROM_MSF;
-                       mssp->xa_flag = 1;
-               } else {
-                       mssp->xa_flag = 0;
-               }
-               return 1;
-       }
-       return 0;
-}
-
-static int cm206_get_upc(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
-{
-       uch upc[10];
-       char *ret = mcn->medium_catalog_number;
-       int i;
-
-       if (type_1_command(c_read_upc, 10, upc))
-               return -EIO;
-       for (i = 0; i < 13; i++) {
-               int w = i / 2 + 1, r = i % 2;
-               if (r)
-                       ret[i] = 0x30 | (upc[w] & 0x0f);
-               else
-                       ret[i] = 0x30 | ((upc[w] >> 4) & 0x0f);
-       }
-       ret[13] = '\0';
-       return 0;
-}
-
-static int cm206_reset(struct cdrom_device_info *cdi)
-{
-       stop_read();
-       reset_cm260();
-       outw(dc_normal | dc_break | READ_AHEAD, r_data_control);
-       mdelay(1);              /* 750 musec minimum */
-       outw(dc_normal | READ_AHEAD, r_data_control);
-       cd->sector_last = -1;   /* flag no data buffered */
-       cd->adapter_last = -1;
-       invalidate_toc();
-       return 0;
-}
-
-static int cm206_select_speed(struct cdrom_device_info *cdi, int speed)
-{
-       int r;
-       switch (speed) {
-       case 0:
-               r = type_0_command(c_auto_mode, 1);
-               break;
-       case 1:
-               r = type_0_command(c_force_1x, 1);
-               break;
-       case 2:
-               r = type_0_command(c_force_2x, 1);
-               break;
-       default:
-               return -1;
-       }
-       if (r < 0)
-               return r;
-       else
-               return 1;
-}
-
-static struct cdrom_device_ops cm206_dops = {
-       .open                   = cm206_open,
-       .release                = cm206_release,
-       .drive_status           = cm206_drive_status,
-       .media_changed          = cm206_media_changed,
-       .tray_move              = cm206_tray_move,
-       .lock_door              = cm206_lock_door,
-       .select_speed           = cm206_select_speed,
-       .get_last_session       = cm206_get_last_session,
-       .get_mcn                = cm206_get_upc,
-       .reset                  = cm206_reset,
-       .audio_ioctl            = cm206_audio_ioctl,
-       .capability             = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
-                                 CDC_MULTI_SESSION | CDC_MEDIA_CHANGED |
-                                 CDC_MCN | CDC_PLAY_AUDIO | CDC_SELECT_SPEED |
-                                 CDC_DRIVE_STATUS,
-       .n_minors               = 1,
-};
-
-
-static struct cdrom_device_info cm206_info = {
-       .ops            = &cm206_dops,
-       .speed          = 2,
-       .capacity       = 1,
-       .name           = "cm206",
-};
-
-static int cm206_block_open(struct inode *inode, struct file *file)
-{
-       return cdrom_open(&cm206_info, inode, file);
-}
-
-static int cm206_block_release(struct inode *inode, struct file *file)
-{
-       return cdrom_release(&cm206_info, file);
-}
-
-static int cm206_block_ioctl(struct inode *inode, struct file *file,
-                               unsigned cmd, unsigned long arg)
-{
-       switch (cmd) {
-#ifdef STATISTICS
-       case CM206CTL_GET_STAT:
-               if (arg >= NR_STATS)
-                       return -EINVAL;
-               return cd->stats[arg];
-       case CM206CTL_GET_LAST_STAT:
-               if (arg >= NR_STATS)
-                       return -EINVAL;
-               return cd->last_stat[arg];
-#endif
-       default:
-               break;
-       }
-
-       return cdrom_ioctl(file, &cm206_info, inode, cmd, arg);
-}
-
-static int cm206_block_media_changed(struct gendisk *disk)
-{
-       return cdrom_media_changed(&cm206_info);
-}
-
-static struct block_device_operations cm206_bdops =
-{
-       .owner          = THIS_MODULE,
-       .open           = cm206_block_open,
-       .release        = cm206_block_release,
-       .ioctl          = cm206_block_ioctl,
-       .media_changed  = cm206_block_media_changed,
-};
-
-static struct gendisk *cm206_gendisk;
-
-/* This function probes for the adapter card. It returns the base
-   address if it has found the adapter card. One can specify a base 
-   port to probe specifically, or 0 which means span all possible
-   bases. 
-
-   Linus says it is too dangerous to use writes for probing, so we
-   stick with pure reads for a while. Hope that 8 possible ranges,
-   request_region, 15 bits of one port and 6 of another make things
-   likely enough to accept the region on the first hit...
- */
-static int __init probe_base_port(int base)
-{
-       int b = 0x300, e = 0x370;       /* this is the range of start addresses */
-       volatile int fool, i;
-
-       if (base)
-               b = e = base;
-       for (base = b; base <= e; base += 0x10) {
-               if (!request_region(base, 0x10,"cm206"))
-                       continue;
-               for (i = 0; i < 3; i++)
-                       fool = inw(base + 2);   /* empty possibly uart_receive_buffer */
-               if ((inw(base + 6) & 0xffef) != 0x0001 ||       /* line_status */
-                   (inw(base) & 0xad00) != 0)  { /* data status */
-                       release_region(base,0x10);
-                       continue;
-               }
-               return (base);
-       }
-       return 0;
-}
-
-#if !defined(MODULE) || defined(AUTO_PROBE_MODULE)
-/* Probe for irq# nr. If nr==0, probe for all possible irq's. */
-static int __init probe_irq(int nr)
-{
-       int irqs, irq;
-       outw(dc_normal | READ_AHEAD, r_data_control);   /* disable irq-generation */
-       sti();
-       irqs = probe_irq_on();
-       reset_cm260();          /* causes interrupt */
-       udelay(100);            /* wait for it */
-       irq = probe_irq_off(irqs);
-       outw(dc_normal | READ_AHEAD, r_data_control);   /* services interrupt */
-       if (nr && irq != nr && irq > 0)
-               return 0;       /* wrong interrupt happened */
-       else
-               return irq;
-}
-#endif
-
-int __init cm206_init(void)
-{
-       uch e = 0;
-       long int size = sizeof(struct cm206_struct);
-       struct gendisk *disk;
-
-       printk(KERN_INFO "cm206 cdrom driver " REVISION);
-       cm206_base = probe_base_port(auto_probe ? 0 : cm206_base);
-       if (!cm206_base) {
-               printk(" can't find adapter!\n");
-               return -EIO;
-       }
-       printk(" adapter at 0x%x", cm206_base);
-       cd = kmalloc(size, GFP_KERNEL);
-       if (!cd)
-               goto out_base;
-       /* Now we have found the adaptor card, try to reset it. As we have
-        * found out earlier, this process generates an interrupt as well,
-        * so we might just exploit that fact for irq probing! */
-#if !defined(MODULE) || defined(AUTO_PROBE_MODULE)
-       cm206_irq = probe_irq(auto_probe ? 0 : cm206_irq);
-       if (cm206_irq <= 0) {
-               printk("can't find IRQ!\n");
-               goto out_probe;
-       } else
-               printk(" IRQ %d found\n", cm206_irq);
-#else
-       cli();
-       reset_cm260();
-       /* Now, the problem here is that reset_cm260 can generate an
-          interrupt. It seems that this can cause a kernel oops some time
-          later. So we wait a while and `service' this interrupt. */
-       mdelay(1);
-       outw(dc_normal | READ_AHEAD, r_data_control);
-       sti();
-       printk(" using IRQ %d\n", cm206_irq);
-#endif
-       if (send_receive_polled(c_drive_configuration) !=
-           c_drive_configuration) {
-               printk(KERN_INFO " drive not there\n");
-               goto out_probe;
-       }
-       e = send_receive_polled(c_gimme);
-       printk(KERN_INFO "Firmware revision %d", e & dcf_revision_code);
-       if (e & dcf_transfer_rate)
-               printk(" double");
-       else
-               printk(" single");
-       printk(" speed drive");
-       if (e & dcf_motorized_tray)
-               printk(", motorized tray");
-       if (request_irq(cm206_irq, cm206_interrupt, 0, "cm206", NULL)) {
-               printk("\nUnable to reserve IRQ---aborted\n");
-               goto out_probe;
-       }
-       printk(".\n");
-
-       if (register_blkdev(MAJOR_NR, "cm206"))
-               goto out_blkdev;
-
-       disk = alloc_disk(1);
-       if (!disk)
-               goto out_disk;
-       disk->major = MAJOR_NR;
-       disk->first_minor = 0;
-       sprintf(disk->disk_name, "cm206cd");
-       disk->fops = &cm206_bdops;
-       disk->flags = GENHD_FL_CD;
-       cm206_gendisk = disk;
-       if (register_cdrom(&cm206_info) != 0) {
-               printk(KERN_INFO "Cannot register for cdrom %d!\n", MAJOR_NR);
-               goto out_cdrom;
-       }
-       cm206_queue = blk_init_queue(do_cm206_request, &cm206_lock);
-       if (!cm206_queue)
-               goto out_queue;
-               
-       blk_queue_hardsect_size(cm206_queue, 2048);
-       disk->queue = cm206_queue;
-       add_disk(disk);
-
-       memset(cd, 0, sizeof(*cd));     /* give'm some reasonable value */
-       cd->sector_last = -1;   /* flag no data buffered */
-       cd->adapter_last = -1;
-       init_timer(&cd->timer);
-       cd->timer.function = cm206_timeout;
-       cd->max_sectors = (inw(r_data_status) & ds_ram_size) ? 24 : 97;
-       printk(KERN_INFO "%d kB adapter memory available, "
-              " %ld bytes kernel memory used.\n", cd->max_sectors * 2,
-              size);
-       return 0;
-
-out_queue:
-       unregister_cdrom(&cm206_info);
-out_cdrom:
-       put_disk(disk);
-out_disk:
-       unregister_blkdev(MAJOR_NR, "cm206");
-out_blkdev:
-       free_irq(cm206_irq, NULL);
-out_probe:
-       kfree(cd);
-out_base:
-       release_region(cm206_base, 16);
-       return -EIO;
-}
-
-#ifdef MODULE
-
-
-static void __init parse_options(void)
-{
-       int i;
-       for (i = 0; i < 2; i++) {
-               if (0x300 <= cm206[i] && i <= 0x370
-                   && cm206[i] % 0x10 == 0) {
-                       cm206_base = cm206[i];
-                       auto_probe = 0;
-               } else if (3 <= cm206[i] && cm206[i] <= 15) {
-                       cm206_irq = cm206[i];
-                       auto_probe = 0;
-               }
-       }
-}
-
-static int __init __cm206_init(void)
-{
-       parse_options();
-#if !defined(AUTO_PROBE_MODULE)
-       auto_probe = 0;
-#endif
-       return cm206_init();
-}
-
-static void __exit cm206_exit(void)
-{
-       del_gendisk(cm206_gendisk);
-       put_disk(cm206_gendisk);
-       if (unregister_cdrom(&cm206_info)) {
-               printk("Can't unregister cdrom cm206\n");
-               return;
-       }
-       if (unregister_blkdev(MAJOR_NR, "cm206")) {
-               printk("Can't unregister major cm206\n");
-               return;
-       }
-       blk_cleanup_queue(cm206_queue);
-       free_irq(cm206_irq, NULL);
-       kfree(cd);
-       release_region(cm206_base, 16);
-       printk(KERN_INFO "cm206 removed\n");
-}
-
-module_init(__cm206_init);
-module_exit(cm206_exit);
-
-#else                          /* !MODULE */
-
-/* This setup function accepts either `auto' or numbers in the range
- * 3--11 (for irq) or 0x300--0x370 (for base port) or both. */
-
-static int __init cm206_setup(char *s)
-{
-       int i, p[4];
-
-       (void) get_options(s, ARRAY_SIZE(p), p);
-
-       if (!strcmp(s, "auto"))
-               auto_probe = 1;
-       for (i = 1; i <= p[0]; i++) {
-               if (0x300 <= p[i] && i <= 0x370 && p[i] % 0x10 == 0) {
-                       cm206_base = p[i];
-                       auto_probe = 0;
-               } else if (3 <= p[i] && p[i] <= 15) {
-                       cm206_irq = p[i];
-                       auto_probe = 0;
-               }
-       }
-       return 1;
-}
-
-__setup("cm206=", cm206_setup);
-
-#endif                         /* !MODULE */
-MODULE_ALIAS_BLOCKDEV_MAJOR(CM206_CDROM_MAJOR);
-
diff --git a/drivers/cdrom/cm206.h b/drivers/cdrom/cm206.h
deleted file mode 100644 (file)
index 0ae51c1..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-/* cm206.h Header file for cm206.c.
-   Copyright (c) 1995 David van Leeuwen 
-*/
-
-#ifndef LINUX_CM206_H
-#define LINUX_CM206_H
-
-#include <linux/ioctl.h>
-
-/* First, the cm260 stuff */
-/* The ports and irq used. Although CM206_BASE and CM206_IRQ are defined
-   below, the values are not used unless autoprobing is turned off and 
-   no LILO boot options or module command line options are given. Change
-   these values to your own as last resort if autoprobing and options
-   don't work. */
-
-#define CM206_BASE 0x340
-#define CM206_IRQ 11
-
-#define r_data_status (cm206_base)
-#define r_uart_receive (cm206_base+0x2)
-#define r_fifo_output_buffer (cm206_base+0x4)
-#define r_line_status (cm206_base+0x6)
-#define r_data_control (cm206_base+0x8)
-#define r_uart_transmit (cm206_base+0xa)
-#define r_test_clock (cm206_base+0xc)
-#define r_test_control (cm206_base+0xe)
-
-/* the data_status flags */
-#define ds_ram_size 0x4000
-#define ds_toc_ready 0x2000
-#define ds_fifo_empty 0x1000
-#define ds_sync_error 0x800
-#define ds_crc_error 0x400
-#define ds_data_error 0x200
-#define ds_fifo_overflow 0x100
-#define ds_data_ready 0x80
-
-/* the line_status flags */
-#define ls_attention 0x10
-#define ls_parity_error 0x8
-#define ls_overrun 0x4
-#define ls_receive_buffer_full 0x2
-#define ls_transmitter_buffer_empty 0x1
-
-/* the data control register flags */
-#define dc_read_q_channel 0x4000
-#define dc_mask_sync_error 0x2000
-#define dc_toc_enable 0x1000
-#define dc_no_stop_on_error 0x800
-#define dc_break 0x400
-#define dc_initialize 0x200
-#define dc_mask_transmit_ready 0x100
-#define dc_flag_enable 0x80
-
-/* Define the default data control register flags here */
-#define dc_normal (dc_mask_sync_error | dc_no_stop_on_error | \
-                  dc_mask_transmit_ready)
-
-/* now some constants related to the cm206 */
-/* another drive status byte, echoed by the cm206 on most commands */
-
-#define dsb_error_condition 0x1
-#define dsb_play_in_progress 0x4
-#define dsb_possible_media_change 0x8
-#define dsb_disc_present 0x10
-#define dsb_drive_not_ready 0x20
-#define dsb_tray_locked 0x40
-#define dsb_tray_not_closed 0x80
-
-#define dsb_not_useful (dsb_drive_not_ready | dsb_tray_not_closed)
-
-/* the cm206 command set */
-
-#define c_close_tray 0
-#define c_lock_tray 0x01
-#define c_unlock_tray 0x04
-#define c_open_tray 0x05
-#define c_seek 0x10
-#define c_read_data 0x20
-#define c_force_1x 0x21
-#define c_force_2x 0x22
-#define c_auto_mode 0x23
-#define c_play 0x30
-#define c_set_audio_mode 0x31
-#define c_read_current_q 0x41
-#define c_stream_q 0x42
-#define c_drive_status 0x50
-#define c_disc_status 0x51
-#define c_audio_status 0x52
-#define c_drive_configuration 0x53
-#define c_read_upc 0x60
-#define c_stop 0x70
-#define c_calc_checksum 0xe5
-
-#define c_gimme 0xf8
-
-/* finally, the (error) condition that the drive can be in      *
- * OK, this is not always an error, but let's prefix it with e_ */
-
-#define e_none 0
-#define e_illegal_command 0x01
-#define e_sync 0x02
-#define e_seek 0x03
-#define e_parity 0x04
-#define e_focus 0x05
-#define e_header_sync 0x06
-#define e_code_incompatibility 0x07
-#define e_reset_done 0x08
-#define e_bad_parameter 0x09
-#define e_radial 0x0a
-#define e_sub_code 0x0b
-#define e_no_data_track 0x0c
-#define e_scan 0x0d
-#define e_tray_open 0x0f
-#define e_no_disc 0x10
-#define e_tray stalled 0x11
-
-/* drive configuration masks */
-
-#define dcf_revision_code 0x7
-#define dcf_transfer_rate 0x60
-#define dcf_motorized_tray 0x80
-
-/* disc status byte */
-
-#define cds_multi_session 0x2
-#define cds_all_audio 0x8
-#define cds_xa_mode 0xf0
-
-/* finally some ioctls for the driver */
-
-#define CM206CTL_GET_STAT _IO( 0x20, 0 )
-#define CM206CTL_GET_LAST_STAT _IO( 0x20, 1 )
-
-#ifdef STATISTICS
-
-/* This is an ugly way to guarantee that the names of the statistics
- * are the same in the code and in the diagnostics program.  */
-
-#ifdef __KERNEL__
-#define x(a) st_ ## a
-#define y enum
-#else
-#define x(a) #a
-#define y char * stats_name[] = 
-#endif
-
-y {x(interrupt), x(data_ready), x(fifo_overflow), x(data_error),
-     x(crc_error), x(sync_error), x(lost_intr), x(echo),
-     x(write_timeout), x(receive_timeout), x(read_timeout),
-     x(dsb_timeout), x(stop_0xff), x(back_read_timeout),
-     x(sector_transferred), x(read_restarted), x(read_background),
-     x(bh), x(open), x(ioctl_multisession), x(attention)
-#ifdef __KERNEL__
-     , x(last_entry)
-#endif
- };
-
-#ifdef __KERNEL__
-#define NR_STATS st_last_entry
-#else
-#define NR_STATS (sizeof(stats_name)/sizeof(char*))
-#endif
-
-#undef y
-#undef x
-
-#endif /* STATISTICS */
-
-#endif /* LINUX_CM206_H */
diff --git a/drivers/cdrom/gscd.c b/drivers/cdrom/gscd.c
deleted file mode 100644 (file)
index b3ab6e9..0000000
+++ /dev/null
@@ -1,1029 +0,0 @@
-#define GSCD_VERSION "0.4a Oliver Raupach <raupach@nwfs1.rz.fh-hannover.de>"
-
-/*
-       linux/drivers/block/gscd.c - GoldStar R420 CDROM driver
-
-        Copyright (C) 1995  Oliver Raupach <raupach@nwfs1.rz.fh-hannover.de>
-        based upon pre-works by   Eberhard Moenkeberg <emoenke@gwdg.de>
-        
-
-        For all kind of other information about the GoldStar CDROM
-        and this Linux device driver I installed a WWW-URL:
-        http://linux.rz.fh-hannover.de/~raupach        
-
-
-             If you are the editor of a Linux CD, you should
-             enable gscd.c within your boot floppy kernel and
-             send me one of your CDs for free.
-
-
-        --------------------------------------------------------------------
-       This program is free software; you can redistribute 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.
-       
-       --------------------------------------------------------------------
-       
-       9 November 1999 -- Make kernel-parameter implementation work with 2.3.x 
-                          Removed init_module & cleanup_module in favor of 
-                          module_init & module_exit.
-                          Torben Mathiasen <tmm@image.dk>
-
-*/
-
-/* These settings are for various debug-level. Leave they untouched ... */
-#define  NO_GSCD_DEBUG
-#define  NO_IOCTL_DEBUG
-#define  NO_MODULE_DEBUG
-#define  NO_FUTURE_WORK
-/*------------------------*/
-
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/timer.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
-#include <linux/kernel.h>
-#include <linux/cdrom.h>
-#include <linux/ioport.h>
-#include <linux/major.h>
-#include <linux/string.h>
-#include <linux/init.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-
-#define MAJOR_NR GOLDSTAR_CDROM_MAJOR
-#include <linux/blkdev.h>
-#include "gscd.h"
-
-static int gscdPresent = 0;
-
-static unsigned char gscd_buf[2048];   /* buffer for block size conversion */
-static int gscd_bn = -1;
-static short gscd_port = GSCD_BASE_ADDR;
-module_param_named(gscd, gscd_port, short, 0);
-
-/* Kommt spaeter vielleicht noch mal dran ...
- *    static DECLARE_WAIT_QUEUE_HEAD(gscd_waitq);
- */
-
-static void gscd_read_cmd(struct request *req);
-static void gscd_hsg2msf(long hsg, struct msf *msf);
-static void gscd_bin2bcd(unsigned char *p);
-
-/* Schnittstellen zum Kern/FS */
-
-static void __do_gscd_request(unsigned long dummy);
-static int gscd_ioctl(struct inode *, struct file *, unsigned int,
-                     unsigned long);
-static int gscd_open(struct inode *, struct file *);
-static int gscd_release(struct inode *, struct file *);
-static int check_gscd_med_chg(struct gendisk *disk);
-
-/*      GoldStar Funktionen    */
-
-static void cmd_out(int, char *, char *, int);
-static void cmd_status(void);
-static void init_cd_drive(int);
-
-static int get_status(void);
-static void clear_Audio(void);
-static void cc_invalidate(void);
-
-/* some things for the next version */
-#ifdef FUTURE_WORK
-static void update_state(void);
-static long gscd_msf2hsg(struct msf *mp);
-static int gscd_bcd2bin(unsigned char bcd);
-#endif
-
-
-/*      lo-level cmd-Funktionen    */
-
-static void cmd_info_in(char *, int);
-static void cmd_end(void);
-static void cmd_read_b(char *, int, int);
-static void cmd_read_w(char *, int, int);
-static int cmd_unit_alive(void);
-static void cmd_write_cmd(char *);
-
-
-/*      GoldStar Variablen     */
-
-static int curr_drv_state;
-static int drv_states[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-static int drv_mode;
-static int disk_state;
-static int speed;
-static int ndrives;
-
-static unsigned char drv_num_read;
-static unsigned char f_dsk_valid;
-static unsigned char current_drive;
-static unsigned char f_drv_ok;
-
-
-static char f_AudioPlay;
-static char f_AudioPause;
-static int AudioStart_m;
-static int AudioStart_f;
-static int AudioEnd_m;
-static int AudioEnd_f;
-
-static DEFINE_TIMER(gscd_timer, NULL, 0, 0);
-static DEFINE_SPINLOCK(gscd_lock);
-static struct request_queue *gscd_queue;
-
-static struct block_device_operations gscd_fops = {
-       .owner          = THIS_MODULE,
-       .open           = gscd_open,
-       .release        = gscd_release,
-       .ioctl          = gscd_ioctl,
-       .media_changed  = check_gscd_med_chg,
-};
-
-/* 
- * Checking if the media has been changed
- * (not yet implemented)
- */
-static int check_gscd_med_chg(struct gendisk *disk)
-{
-#ifdef GSCD_DEBUG
-       printk("gscd: check_med_change\n");
-#endif
-       return 0;
-}
-
-
-#ifndef MODULE
-/* Using new interface for kernel-parameters */
-
-static int __init gscd_setup(char *str)
-{
-       int ints[2];
-       (void) get_options(str, ARRAY_SIZE(ints), ints);
-
-       if (ints[0] > 0) {
-               gscd_port = ints[1];
-       }
-       return 1;
-}
-
-__setup("gscd=", gscd_setup);
-
-#endif
-
-static int gscd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
-                     unsigned long arg)
-{
-       unsigned char to_do[10];
-       unsigned char dummy;
-
-
-       switch (cmd) {
-       case CDROMSTART:        /* Spin up the drive */
-               /* Don't think we can do this.  Even if we could,
-                * I think the drive times out and stops after a while
-                * anyway.  For now, ignore it.
-                */
-               return 0;
-
-       case CDROMRESUME:       /* keine Ahnung was das ist */
-               return 0;
-
-
-       case CDROMEJECT:
-               cmd_status();
-               to_do[0] = CMD_TRAY_CTL;
-               cmd_out(TYPE_INFO, (char *) &to_do, (char *) &dummy, 0);
-
-               return 0;
-
-       default:
-               return -EINVAL;
-       }
-
-}
-
-
-/*
- * Take care of the different block sizes between cdrom and Linux.
- * When Linux gets variable block sizes this will probably go away.
- */
-
-static void gscd_transfer(struct request *req)
-{
-       while (req->nr_sectors > 0 && gscd_bn == req->sector / 4) {
-               long offs = (req->sector & 3) * 512;
-               memcpy(req->buffer, gscd_buf + offs, 512);
-               req->nr_sectors--;
-               req->sector++;
-               req->buffer += 512;
-       }
-}
-
-
-/*
- * I/O request routine called from Linux kernel.
- */
-
-static void do_gscd_request(request_queue_t * q)
-{
-       __do_gscd_request(0);
-}
-
-static void __do_gscd_request(unsigned long dummy)
-{
-       struct request *req;
-       unsigned int block;
-       unsigned int nsect;
-
-repeat:
-       req = elv_next_request(gscd_queue);
-       if (!req)
-               return;
-
-       block = req->sector;
-       nsect = req->nr_sectors;
-
-       if (req->sector == -1)
-               goto out;
-
-       if (req->cmd != READ) {
-               printk("GSCD: bad cmd %u\n", rq_data_dir(req));
-               end_request(req, 0);
-               goto repeat;
-       }
-
-       gscd_transfer(req);
-
-       /* if we satisfied the request from the buffer, we're done. */
-
-       if (req->nr_sectors == 0) {
-               end_request(req, 1);
-               goto repeat;
-       }
-#ifdef GSCD_DEBUG
-       printk("GSCD: block %d, nsect %d\n", block, nsect);
-#endif
-       gscd_read_cmd(req);
-out:
-       return;
-}
-
-
-
-/*
- * Check the result of the set-mode command.  On success, send the
- * read-data command.
- */
-
-static void gscd_read_cmd(struct request *req)
-{
-       long block;
-       struct gscd_Play_msf gscdcmd;
-       char cmd[] = { CMD_READ, 0x80, 0, 0, 0, 0, 1 }; /* cmd mode M-S-F secth sectl */
-
-       cmd_status();
-       if (disk_state & (ST_NO_DISK | ST_DOOR_OPEN)) {
-               printk("GSCD: no disk or door open\n");
-               end_request(req, 0);
-       } else {
-               if (disk_state & ST_INVALID) {
-                       printk("GSCD: disk invalid\n");
-                       end_request(req, 0);
-               } else {
-                       gscd_bn = -1;   /* purge our buffer */
-                       block = req->sector / 4;
-                       gscd_hsg2msf(block, &gscdcmd.start);    /* cvt to msf format */
-
-                       cmd[2] = gscdcmd.start.min;
-                       cmd[3] = gscdcmd.start.sec;
-                       cmd[4] = gscdcmd.start.frame;
-
-#ifdef GSCD_DEBUG
-                       printk("GSCD: read msf %d:%d:%d\n", cmd[2], cmd[3],
-                              cmd[4]);
-#endif
-                       cmd_out(TYPE_DATA, (char *) &cmd,
-                               (char *) &gscd_buf[0], 1);
-
-                       gscd_bn = req->sector / 4;
-                       gscd_transfer(req);
-                       end_request(req, 1);
-               }
-       }
-       SET_TIMER(__do_gscd_request, 1);
-}
-
-
-/*
- * Open the device special file.  Check that a disk is in.
- */
-
-static int gscd_open(struct inode *ip, struct file *fp)
-{
-       int st;
-
-#ifdef GSCD_DEBUG
-       printk("GSCD: open\n");
-#endif
-
-       if (gscdPresent == 0)
-               return -ENXIO;  /* no hardware */
-
-       get_status();
-       st = disk_state & (ST_NO_DISK | ST_DOOR_OPEN);
-       if (st) {
-               printk("GSCD: no disk or door open\n");
-               return -ENXIO;
-       }
-
-/*     if (updateToc() < 0)
-               return -EIO;
-*/
-
-       return 0;
-}
-
-
-/*
- * On close, we flush all gscd blocks from the buffer cache.
- */
-
-static int gscd_release(struct inode *inode, struct file *file)
-{
-
-#ifdef GSCD_DEBUG
-       printk("GSCD: release\n");
-#endif
-
-       gscd_bn = -1;
-
-       return 0;
-}
-
-
-static int get_status(void)
-{
-       int status;
-
-       cmd_status();
-       status = disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01);
-
-       if (status == (ST_x08 | ST_x04 | ST_INVALID | ST_x01)) {
-               cc_invalidate();
-               return 1;
-       } else {
-               return 0;
-       }
-}
-
-
-static void cc_invalidate(void)
-{
-       drv_num_read = 0xFF;
-       f_dsk_valid = 0xFF;
-       current_drive = 0xFF;
-       f_drv_ok = 0xFF;
-
-       clear_Audio();
-
-}
-
-static void clear_Audio(void)
-{
-
-       f_AudioPlay = 0;
-       f_AudioPause = 0;
-       AudioStart_m = 0;
-       AudioStart_f = 0;
-       AudioEnd_m = 0;
-       AudioEnd_f = 0;
-
-}
-
-/*
- *   waiting ?  
- */
-
-static int wait_drv_ready(void)
-{
-       int found, read;
-
-       do {
-               found = inb(GSCDPORT(0));
-               found &= 0x0f;
-               read = inb(GSCDPORT(0));
-               read &= 0x0f;
-       } while (read != found);
-
-#ifdef GSCD_DEBUG
-       printk("Wait for: %d\n", read);
-#endif
-
-       return read;
-}
-
-static void cc_Ident(char *respons)
-{
-       char to_do[] = { CMD_IDENT, 0, 0 };
-
-       cmd_out(TYPE_INFO, (char *) &to_do, (char *) respons, (int) 0x1E);
-
-}
-
-static void cc_SetSpeed(void)
-{
-       char to_do[] = { CMD_SETSPEED, 0, 0 };
-       char dummy;
-
-       if (speed > 0) {
-               to_do[1] = speed & 0x0F;
-               cmd_out(TYPE_INFO, (char *) &to_do, (char *) &dummy, 0);
-       }
-}
-
-static void cc_Reset(void)
-{
-       char to_do[] = { CMD_RESET, 0 };
-       char dummy;
-
-       cmd_out(TYPE_INFO, (char *) &to_do, (char *) &dummy, 0);
-}
-
-static void cmd_status(void)
-{
-       char to_do[] = { CMD_STATUS, 0 };
-       char dummy;
-
-       cmd_out(TYPE_INFO, (char *) &to_do, (char *) &dummy, 0);
-
-#ifdef GSCD_DEBUG
-       printk("GSCD: Status: %d\n", disk_state);
-#endif
-
-}
-
-static void cmd_out(int cmd_type, char *cmd, char *respo_buf, int respo_count)
-{
-       int result;
-
-
-       result = wait_drv_ready();
-       if (result != drv_mode) {
-               unsigned long test_loops = 0xFFFF;
-               int i, dummy;
-
-               outb(curr_drv_state, GSCDPORT(0));
-
-               /* LOCLOOP_170 */
-               do {
-                       result = wait_drv_ready();
-                       test_loops--;
-               } while ((result != drv_mode) && (test_loops > 0));
-
-               if (result != drv_mode) {
-                       disk_state = ST_x08 | ST_x04 | ST_INVALID;
-                       return;
-               }
-
-               /* ...and waiting */
-               for (i = 1, dummy = 1; i < 0xFFFF; i++) {
-                       dummy *= i;
-               }
-       }
-
-       /* LOC_172 */
-       /* check the unit */
-       /* and wake it up */
-       if (cmd_unit_alive() != 0x08) {
-               /* LOC_174 */
-               /* game over for this unit */
-               disk_state = ST_x08 | ST_x04 | ST_INVALID;
-               return;
-       }
-
-       /* LOC_176 */
-#ifdef GSCD_DEBUG
-       printk("LOC_176 ");
-#endif
-       if (drv_mode == 0x09) {
-               /* magic... */
-               printk("GSCD: magic ...\n");
-               outb(result, GSCDPORT(2));
-       }
-
-       /* write the command to the drive */
-       cmd_write_cmd(cmd);
-
-       /* LOC_178 */
-       for (;;) {
-               result = wait_drv_ready();
-               if (result != drv_mode) {
-                       /* LOC_179 */
-                       if (result == 0x04) {   /* Mode 4 */
-                               /* LOC_205 */
-#ifdef GSCD_DEBUG
-                               printk("LOC_205 ");
-#endif
-                               disk_state = inb(GSCDPORT(2));
-
-                               do {
-                                       result = wait_drv_ready();
-                               } while (result != drv_mode);
-                               return;
-
-                       } else {
-                               if (result == 0x06) {   /* Mode 6 */
-                                       /* LOC_181 */
-#ifdef GSCD_DEBUG
-                                       printk("LOC_181 ");
-#endif
-
-                                       if (cmd_type == TYPE_DATA) {
-                                               /* read data */
-                                               /* LOC_184 */
-                                               if (drv_mode == 9) {
-                                                       /* read the data to the buffer (word) */
-
-                                                       /* (*(cmd+1))?(CD_FRAMESIZE/2):(CD_FRAMESIZE_RAW/2) */
-                                                       cmd_read_w
-                                                           (respo_buf,
-                                                            respo_count,
-                                                            CD_FRAMESIZE /
-                                                            2);
-                                                       return;
-                                               } else {
-                                                       /* read the data to the buffer (byte) */
-
-                                                       /* (*(cmd+1))?(CD_FRAMESIZE):(CD_FRAMESIZE_RAW)    */
-                                                       cmd_read_b
-                                                           (respo_buf,
-                                                            respo_count,
-                                                            CD_FRAMESIZE);
-                                                       return;
-                                               }
-                                       } else {
-                                               /* read the info to the buffer */
-                                               cmd_info_in(respo_buf,
-                                                           respo_count);
-                                               return;
-                                       }
-
-                                       return;
-                               }
-                       }
-
-               } else {
-                       disk_state = ST_x08 | ST_x04 | ST_INVALID;
-                       return;
-               }
-       }                       /* for (;;) */
-
-
-#ifdef GSCD_DEBUG
-       printk("\n");
-#endif
-}
-
-
-static void cmd_write_cmd(char *pstr)
-{
-       int i, j;
-
-       /* LOC_177 */
-#ifdef GSCD_DEBUG
-       printk("LOC_177 ");
-#endif
-
-       /* calculate the number of parameter */
-       j = *pstr & 0x0F;
-
-       /* shift it out */
-       for (i = 0; i < j; i++) {
-               outb(*pstr, GSCDPORT(2));
-               pstr++;
-       }
-}
-
-
-static int cmd_unit_alive(void)
-{
-       int result;
-       unsigned long max_test_loops;
-
-
-       /* LOC_172 */
-#ifdef GSCD_DEBUG
-       printk("LOC_172 ");
-#endif
-
-       outb(curr_drv_state, GSCDPORT(0));
-       max_test_loops = 0xFFFF;
-
-       do {
-               result = wait_drv_ready();
-               max_test_loops--;
-       } while ((result != 0x08) && (max_test_loops > 0));
-
-       return result;
-}
-
-
-static void cmd_info_in(char *pb, int count)
-{
-       int result;
-       char read;
-
-
-       /* read info */
-       /* LOC_182 */
-#ifdef GSCD_DEBUG
-       printk("LOC_182 ");
-#endif
-
-       do {
-               read = inb(GSCDPORT(2));
-               if (count > 0) {
-                       *pb = read;
-                       pb++;
-                       count--;
-               }
-
-               /* LOC_183 */
-               do {
-                       result = wait_drv_ready();
-               } while (result == 0x0E);
-       } while (result == 6);
-
-       cmd_end();
-       return;
-}
-
-
-static void cmd_read_b(char *pb, int count, int size)
-{
-       int result;
-       int i;
-
-
-       /* LOC_188 */
-       /* LOC_189 */
-#ifdef GSCD_DEBUG
-       printk("LOC_189 ");
-#endif
-
-       do {
-               do {
-                       result = wait_drv_ready();
-               } while (result != 6 || result == 0x0E);
-
-               if (result != 6) {
-                       cmd_end();
-                       return;
-               }
-#ifdef GSCD_DEBUG
-               printk("LOC_191 ");
-#endif
-
-               for (i = 0; i < size; i++) {
-                       *pb = inb(GSCDPORT(2));
-                       pb++;
-               }
-               count--;
-       } while (count > 0);
-
-       cmd_end();
-       return;
-}
-
-
-static void cmd_end(void)
-{
-       int result;
-
-
-       /* LOC_204 */
-#ifdef GSCD_DEBUG
-       printk("LOC_204 ");
-#endif
-
-       do {
-               result = wait_drv_ready();
-               if (result == drv_mode) {
-                       return;
-               }
-       } while (result != 4);
-
-       /* LOC_205 */
-#ifdef GSCD_DEBUG
-       printk("LOC_205 ");
-#endif
-
-       disk_state = inb(GSCDPORT(2));
-
-       do {
-               result = wait_drv_ready();
-       } while (result != drv_mode);
-       return;
-
-}
-
-
-static void cmd_read_w(char *pb, int count, int size)
-{
-       int result;
-       int i;
-
-
-#ifdef GSCD_DEBUG
-       printk("LOC_185 ");
-#endif
-
-       do {
-               /* LOC_185 */
-               do {
-                       result = wait_drv_ready();
-               } while (result != 6 || result == 0x0E);
-
-               if (result != 6) {
-                       cmd_end();
-                       return;
-               }
-
-               for (i = 0; i < size; i++) {
-                       /* na, hier muss ich noch mal drueber nachdenken */
-                       *pb = inw(GSCDPORT(2));
-                       pb++;
-               }
-               count--;
-       } while (count > 0);
-
-       cmd_end();
-       return;
-}
-
-static int __init find_drives(void)
-{
-       int *pdrv;
-       int drvnum;
-       int subdrv;
-       int i;
-
-       speed = 0;
-       pdrv = (int *) &drv_states;
-       curr_drv_state = 0xFE;
-       subdrv = 0;
-       drvnum = 0;
-
-       for (i = 0; i < 8; i++) {
-               subdrv++;
-               cmd_status();
-               disk_state &= ST_x08 | ST_x04 | ST_INVALID | ST_x01;
-               if (disk_state != (ST_x08 | ST_x04 | ST_INVALID)) {
-                       /* LOC_240 */
-                       *pdrv = curr_drv_state;
-                       init_cd_drive(drvnum);
-                       pdrv++;
-                       drvnum++;
-               } else {
-                       if (subdrv < 2) {
-                               continue;
-                       } else {
-                               subdrv = 0;
-                       }
-               }
-
-/*       curr_drv_state<<1;         <-- das geht irgendwie nicht */
-/* muss heissen:    curr_drv_state <<= 1; (ist ja Wert-Zuweisung) */
-               curr_drv_state *= 2;
-               curr_drv_state |= 1;
-#ifdef GSCD_DEBUG
-               printk("DriveState: %d\n", curr_drv_state);
-#endif
-       }
-
-       ndrives = drvnum;
-       return drvnum;
-}
-
-static void __init init_cd_drive(int num)
-{
-       char resp[50];
-       int i;
-
-       printk("GSCD: init unit %d\n", num);
-       cc_Ident((char *) &resp);
-
-       printk("GSCD: identification: ");
-       for (i = 0; i < 0x1E; i++) {
-               printk("%c", resp[i]);
-       }
-       printk("\n");
-
-       cc_SetSpeed();
-
-}
-
-#ifdef FUTURE_WORK
-/* return_done */
-static void update_state(void)
-{
-       unsigned int AX;
-
-
-       if ((disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01)) == 0) {
-               if (disk_state == (ST_x08 | ST_x04 | ST_INVALID)) {
-                       AX = ST_INVALID;
-               }
-
-               if ((disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01))
-                   == 0) {
-                       invalidate();
-                       f_drv_ok = 0;
-               }
-
-               AX |= 0x8000;
-       }
-
-       if (disk_state & ST_PLAYING) {
-               AX |= 0x200;
-       }
-
-       AX |= 0x100;
-       /* pkt_esbx = AX; */
-
-       disk_state = 0;
-
-}
-#endif
-
-static struct gendisk *gscd_disk;
-
-static void __exit gscd_exit(void)
-{
-       CLEAR_TIMER;
-
-       del_gendisk(gscd_disk);
-       put_disk(gscd_disk);
-       if ((unregister_blkdev(MAJOR_NR, "gscd") == -EINVAL)) {
-               printk("What's that: can't unregister GoldStar-module\n");
-               return;
-       }
-       blk_cleanup_queue(gscd_queue);
-       release_region(gscd_port, GSCD_IO_EXTENT);
-       printk(KERN_INFO "GoldStar-module released.\n");
-}
-
-/* This is the common initialisation for the GoldStar drive. */
-/* It is called at boot time AND for module init.           */
-static int __init gscd_init(void)
-{
-       int i;
-       int result;
-       int ret=0;
-
-       printk(KERN_INFO "GSCD: version %s\n", GSCD_VERSION);
-       printk(KERN_INFO
-              "GSCD: Trying to detect a Goldstar R420 CD-ROM drive at 0x%X.\n",
-              gscd_port);
-
-       if (!request_region(gscd_port, GSCD_IO_EXTENT, "gscd")) {
-               printk(KERN_WARNING "GSCD: Init failed, I/O port (%X) already"
-                      " in use.\n", gscd_port);
-               return -EIO;
-       }
-
-
-       /* check for card */
-       result = wait_drv_ready();
-       if (result == 0x09) {
-               printk(KERN_WARNING "GSCD: DMA kann ich noch nicht!\n");
-               ret = -EIO;
-               goto err_out1;
-       }
-
-       if (result == 0x0b) {
-               drv_mode = result;
-               i = find_drives();
-               if (i == 0) {
-                       printk(KERN_WARNING "GSCD: GoldStar CD-ROM Drive is"
-                              " not found.\n");
-                       ret = -EIO;
-                       goto err_out1;
-               }
-       }
-
-       if ((result != 0x0b) && (result != 0x09)) {
-               printk(KERN_WARNING "GSCD: GoldStar Interface Adapter does not "
-                      "exist or H/W error\n");
-               ret = -EIO;
-               goto err_out1;
-       }
-
-       /* reset all drives */
-       i = 0;
-       while (drv_states[i] != 0) {
-               curr_drv_state = drv_states[i];
-               printk(KERN_INFO "GSCD: Reset unit %d ... ", i);
-               cc_Reset();
-               printk("done\n");
-               i++;
-       }
-
-       gscd_disk = alloc_disk(1);
-       if (!gscd_disk)
-               goto err_out1;
-       gscd_disk->major = MAJOR_NR;
-       gscd_disk->first_minor = 0;
-       gscd_disk->fops = &gscd_fops;
-       sprintf(gscd_disk->disk_name, "gscd");
-
-       if (register_blkdev(MAJOR_NR, "gscd")) {
-               ret = -EIO;
-               goto err_out2;
-       }
-
-       gscd_queue = blk_init_queue(do_gscd_request, &gscd_lock);
-       if (!gscd_queue) {
-               ret = -ENOMEM;
-               goto err_out3;
-       }
-
-       disk_state = 0;
-       gscdPresent = 1;
-
-       gscd_disk->queue = gscd_queue;
-       add_disk(gscd_disk);
-
-       printk(KERN_INFO "GSCD: GoldStar CD-ROM Drive found.\n");
-       return 0;
-
-err_out3:
-       unregister_blkdev(MAJOR_NR, "gscd");
-err_out2:
-       put_disk(gscd_disk);
-err_out1:
-       release_region(gscd_port, GSCD_IO_EXTENT);
-       return ret;
-}
-
-static void gscd_hsg2msf(long hsg, struct msf *msf)
-{
-       hsg += CD_MSF_OFFSET;
-       msf->min = hsg / (CD_FRAMES * CD_SECS);
-       hsg %= CD_FRAMES * CD_SECS;
-       msf->sec = hsg / CD_FRAMES;
-       msf->frame = hsg % CD_FRAMES;
-
-       gscd_bin2bcd(&msf->min);        /* convert to BCD */
-       gscd_bin2bcd(&msf->sec);
-       gscd_bin2bcd(&msf->frame);
-}
-
-
-static void gscd_bin2bcd(unsigned char *p)
-{
-       int u, t;
-
-       u = *p % 10;
-       t = *p / 10;
-       *p = u | (t << 4);
-}
-
-
-#ifdef FUTURE_WORK
-static long gscd_msf2hsg(struct msf *mp)
-{
-       return gscd_bcd2bin(mp->frame)
-           + gscd_bcd2bin(mp->sec) * CD_FRAMES
-           + gscd_bcd2bin(mp->min) * CD_FRAMES * CD_SECS - CD_MSF_OFFSET;
-}
-
-static int gscd_bcd2bin(unsigned char bcd)
-{
-       return (bcd >> 4) * 10 + (bcd & 0xF);
-}
-#endif
-
-MODULE_AUTHOR("Oliver Raupach <raupach@nwfs1.rz.fh-hannover.de>");
-MODULE_LICENSE("GPL");
-module_init(gscd_init);
-module_exit(gscd_exit);
-MODULE_ALIAS_BLOCKDEV_MAJOR(GOLDSTAR_CDROM_MAJOR);
diff --git a/drivers/cdrom/gscd.h b/drivers/cdrom/gscd.h
deleted file mode 100644 (file)
index a41e64b..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Definitions for a GoldStar R420 CD-ROM interface
- *
- *   Copyright (C) 1995  Oliver Raupach <raupach@nwfs1.rz.fh-hannover.de>
- *                       Eberhard Moenkeberg <emoenke@gwdg.de>
- *
- *  Published under the GPL.
- *
- */
-
-
-/* The Interface Card default address is 0x340. This will work for most
-   applications. Address selection is accomplished by jumpers PN801-1 to
-   PN801-4 on the GoldStar Interface Card.
-   Appropriate settings are: 0x300, 0x310, 0x320, 0x330, 0x340, 0x350, 0x360
-   0x370, 0x380, 0x390, 0x3A0, 0x3B0, 0x3C0, 0x3D0, 0x3E0, 0x3F0             */
-
-/* insert here the I/O port address and extent */
-#define GSCD_BASE_ADDR         0x340
-#define GSCD_IO_EXTENT          4
-
-
-/************** nothing to set up below here *********************/
-
-/* port access macro */
-#define GSCDPORT(x)            (gscd_port + (x))
-
-/*
- * commands
- * the lower nibble holds the command length
- */
-#define CMD_STATUS     0x01
-#define CMD_READSUBQ   0x02 /* 1: ?, 2: UPC, 5: ? */
-#define CMD_SEEK       0x05 /* read_mode M-S-F */
-#define CMD_READ       0x07 /* read_mode M-S-F nsec_h nsec_l */
-#define CMD_RESET      0x11
-#define CMD_SETMODE    0x15
-#define CMD_PLAY       0x17 /* M-S-F M-S-F */
-#define CMD_LOCK_CTL   0x22 /* 0: unlock, 1: lock */
-#define CMD_IDENT      0x31
-#define CMD_SETSPEED   0x32 /* 0: auto */ /* ??? */
-#define CMD_GETMODE    0x41
-#define CMD_PAUSE      0x51
-#define CMD_READTOC    0x61
-#define CMD_DISKINFO   0x71
-#define CMD_TRAY_CTL   0x81
-
-/*
- * disk_state:
- */
-#define ST_PLAYING     0x80
-#define ST_UNLOCKED    0x40
-#define ST_NO_DISK     0x20
-#define ST_DOOR_OPEN   0x10
-#define ST_x08  0x08
-#define ST_x04 0x04
-#define ST_INVALID     0x02
-#define ST_x01 0x01
-
-/*
- * cmd_type:
- */
-#define TYPE_INFO      0x01
-#define TYPE_DATA      0x02
-
-/*
- * read_mode:
- */
-#define MOD_POLLED     0x80
-#define MOD_x08        0x08
-#define MOD_RAW        0x04
-
-#define READ_DATA(port, buf, nr) insb(port, buf, nr)
-
-#define SET_TIMER(func, jifs) \
-       ((mod_timer(&gscd_timer, jiffies + jifs)), \
-       (gscd_timer.function = func))
-
-#define CLEAR_TIMER            del_timer_sync(&gscd_timer)
-
-#define MAX_TRACKS             104
-
-struct msf {
-       unsigned char   min;
-       unsigned char   sec;
-       unsigned char   frame;
-};
-
-struct gscd_Play_msf {
-       struct msf      start;
-       struct msf      end;
-};
-
-struct gscd_DiskInfo {
-       unsigned char   first;
-       unsigned char   last;
-       struct msf      diskLength;
-       struct msf      firstTrack;
-};
-
-struct gscd_Toc {
-       unsigned char   ctrl_addr;
-       unsigned char   track;
-       unsigned char   pointIndex;
-       struct msf      trackTime;
-       struct msf      diskTime;
-};
-
diff --git a/drivers/cdrom/isp16.c b/drivers/cdrom/isp16.c
deleted file mode 100644 (file)
index db0fd9a..0000000
+++ /dev/null
@@ -1,374 +0,0 @@
-/* -- ISP16 cdrom detection and configuration
- *
- *    Copyright (c) 1995,1996 Eric van der Maarel <H.T.M.v.d.Maarel@marin.nl>
- *
- *    Version 0.6
- *
- *    History:
- *    0.5 First release.
- *        Was included in the sjcd and optcd cdrom drivers.
- *    0.6 First "stand-alone" version.
- *        Removed sound configuration.
- *        Added "module" support.
- *
- *      9 November 1999 -- Make kernel-parameter implementation work with 2.3.x 
- *                        Removed init_module & cleanup_module in favor of 
- *                        module_init & module_exit.
- *                        Torben Mathiasen <tmm@image.dk>
- *
- *     19 June 2004     -- check_region() converted to request_region()
- *                         and return statement cleanups.
- *                          - Jesper Juhl
- *
- *    Detect cdrom interface on ISP16 sound card.
- *    Configure cdrom interface.
- *
- *    Algorithm for the card with OPTi 82C928 taken
- *    from the CDSETUP.SYS driver for MSDOS,
- *    by OPTi Computers, version 2.03.
- *    Algorithm for the card with OPTi 82C929 as communicated
- *    to me by Vadim Model and Leo Spiekman.
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You 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.
- *
- */
-
-#define ISP16_VERSION_MAJOR 0
-#define ISP16_VERSION_MINOR 6
-
-#include <linux/module.h>
-
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <asm/io.h>
-#include "isp16.h"
-
-static short isp16_detect(void);
-static short isp16_c928__detect(void);
-static short isp16_c929__detect(void);
-static short isp16_cdi_config(int base, u_char drive_type, int irq,
-                             int dma);
-static short isp16_type;       /* dependent on type of interface card */
-static u_char isp16_ctrl;
-static u_short isp16_enable_port;
-
-static int isp16_cdrom_base = ISP16_CDROM_IO_BASE;
-static int isp16_cdrom_irq = ISP16_CDROM_IRQ;
-static int isp16_cdrom_dma = ISP16_CDROM_DMA;
-static char *isp16_cdrom_type = ISP16_CDROM_TYPE;
-
-module_param(isp16_cdrom_base, int, 0);
-module_param(isp16_cdrom_irq, int, 0);
-module_param(isp16_cdrom_dma, int, 0);
-module_param(isp16_cdrom_type, charp, 0);
-
-#define ISP16_IN(p) (outb(isp16_ctrl,ISP16_CTRL_PORT), inb(p))
-#define ISP16_OUT(p,b) (outb(isp16_ctrl,ISP16_CTRL_PORT), outb(b,p))
-
-#ifndef MODULE
-
-static int
-__init isp16_setup(char *str)
-{
-       int ints[4];
-
-       (void) get_options(str, ARRAY_SIZE(ints), ints);
-       if (ints[0] > 0)
-               isp16_cdrom_base = ints[1];
-       if (ints[0] > 1)
-               isp16_cdrom_irq = ints[2];
-       if (ints[0] > 2)
-               isp16_cdrom_dma = ints[3];
-       if (str)
-               isp16_cdrom_type = str;
-
-       return 1;
-}
-
-__setup("isp16=", isp16_setup);
-
-#endif                         /* MODULE */
-
-/*
- *  ISP16 initialisation.
- *
- */
-static int __init isp16_init(void)
-{
-       u_char expected_drive;
-
-       printk(KERN_INFO
-              "ISP16: configuration cdrom interface, version %d.%d.\n",
-              ISP16_VERSION_MAJOR, ISP16_VERSION_MINOR);
-
-       if (!strcmp(isp16_cdrom_type, "noisp16")) {
-               printk("ISP16: no cdrom interface configured.\n");
-               return 0;
-       }
-
-       if (!request_region(ISP16_IO_BASE, ISP16_IO_SIZE, "isp16")) {
-               printk("ISP16: i/o ports already in use.\n");
-               goto out;
-       }
-
-       if ((isp16_type = isp16_detect()) < 0) {
-               printk("ISP16: no cdrom interface found.\n");
-               goto cleanup_out;
-       }
-
-       printk(KERN_INFO
-              "ISP16: cdrom interface (with OPTi 82C92%d chip) detected.\n",
-              (isp16_type == 2) ? 9 : 8);
-
-       if (!strcmp(isp16_cdrom_type, "Sanyo"))
-               expected_drive =
-                   (isp16_type ? ISP16_SANYO1 : ISP16_SANYO0);
-       else if (!strcmp(isp16_cdrom_type, "Sony"))
-               expected_drive = ISP16_SONY;
-       else if (!strcmp(isp16_cdrom_type, "Panasonic"))
-               expected_drive =
-                   (isp16_type ? ISP16_PANASONIC1 : ISP16_PANASONIC0);
-       else if (!strcmp(isp16_cdrom_type, "Mitsumi"))
-               expected_drive = ISP16_MITSUMI;
-       else {
-               printk("ISP16: %s not supported by cdrom interface.\n",
-                      isp16_cdrom_type);
-               goto cleanup_out;
-       }
-
-       if (isp16_cdi_config(isp16_cdrom_base, expected_drive,
-                            isp16_cdrom_irq, isp16_cdrom_dma) < 0) {
-               printk
-                   ("ISP16: cdrom interface has not been properly configured.\n");
-               goto cleanup_out;
-       }
-       printk(KERN_INFO
-              "ISP16: cdrom interface set up with io base 0x%03X, irq %d, dma %d,"
-              " type %s.\n", isp16_cdrom_base, isp16_cdrom_irq,
-              isp16_cdrom_dma, isp16_cdrom_type);
-       return 0;
-
-cleanup_out:
-       release_region(ISP16_IO_BASE, ISP16_IO_SIZE);
-out:
-       return -EIO;
-}
-
-static short __init isp16_detect(void)
-{
-
-       if (isp16_c929__detect() >= 0)
-               return 2;
-       else
-               return (isp16_c928__detect());
-}
-
-static short __init isp16_c928__detect(void)
-{
-       u_char ctrl;
-       u_char enable_cdrom;
-       u_char io;
-       short i = -1;
-
-       isp16_ctrl = ISP16_C928__CTRL;
-       isp16_enable_port = ISP16_C928__ENABLE_PORT;
-
-       /* read' and write' are a special read and write, respectively */
-
-       /* read' ISP16_CTRL_PORT, clear last two bits and write' back the result */
-       ctrl = ISP16_IN(ISP16_CTRL_PORT) & 0xFC;
-       ISP16_OUT(ISP16_CTRL_PORT, ctrl);
-
-       /* read' 3,4 and 5-bit from the cdrom enable port */
-       enable_cdrom = ISP16_IN(ISP16_C928__ENABLE_PORT) & 0x38;
-
-       if (!(enable_cdrom & 0x20)) {   /* 5-bit not set */
-               /* read' last 2 bits of ISP16_IO_SET_PORT */
-               io = ISP16_IN(ISP16_IO_SET_PORT) & 0x03;
-               if (((io & 0x01) << 1) == (io & 0x02)) {        /* bits are the same */
-                       if (io == 0) {  /* ...the same and 0 */
-                               i = 0;
-                               enable_cdrom |= 0x20;
-                       } else {        /* ...the same and 1 *//* my card, first time 'round */
-                               i = 1;
-                               enable_cdrom |= 0x28;
-                       }
-                       ISP16_OUT(ISP16_C928__ENABLE_PORT, enable_cdrom);
-               } else {        /* bits are not the same */
-                       ISP16_OUT(ISP16_CTRL_PORT, ctrl);
-                       return i;       /* -> not detected: possibly incorrect conclusion */
-               }
-       } else if (enable_cdrom == 0x20)
-               i = 0;
-       else if (enable_cdrom == 0x28)  /* my card, already initialised */
-               i = 1;
-
-       ISP16_OUT(ISP16_CTRL_PORT, ctrl);
-
-       return i;
-}
-
-static short __init isp16_c929__detect(void)
-{
-       u_char ctrl;
-       u_char tmp;
-
-       isp16_ctrl = ISP16_C929__CTRL;
-       isp16_enable_port = ISP16_C929__ENABLE_PORT;
-
-       /* read' and write' are a special read and write, respectively */
-
-       /* read' ISP16_CTRL_PORT and save */
-       ctrl = ISP16_IN(ISP16_CTRL_PORT);
-
-       /* write' zero to the ctrl port and get response */
-       ISP16_OUT(ISP16_CTRL_PORT, 0);
-       tmp = ISP16_IN(ISP16_CTRL_PORT);
-
-       if (tmp != 2)           /* isp16 with 82C929 not detected */
-               return -1;
-
-       /* restore ctrl port value */
-       ISP16_OUT(ISP16_CTRL_PORT, ctrl);
-
-       return 2;
-}
-
-static short __init
-isp16_cdi_config(int base, u_char drive_type, int irq, int dma)
-{
-       u_char base_code;
-       u_char irq_code;
-       u_char dma_code;
-       u_char i;
-
-       if ((drive_type == ISP16_MITSUMI) && (dma != 0))
-               printk("ISP16: Mitsumi cdrom drive has no dma support.\n");
-
-       switch (base) {
-       case 0x340:
-               base_code = ISP16_BASE_340;
-               break;
-       case 0x330:
-               base_code = ISP16_BASE_330;
-               break;
-       case 0x360:
-               base_code = ISP16_BASE_360;
-               break;
-       case 0x320:
-               base_code = ISP16_BASE_320;
-               break;
-       default:
-               printk
-                   ("ISP16: base address 0x%03X not supported by cdrom interface.\n",
-                    base);
-               return -1;
-       }
-       switch (irq) {
-       case 0:
-               irq_code = ISP16_IRQ_X;
-               break;          /* disable irq */
-       case 5:
-               irq_code = ISP16_IRQ_5;
-               printk("ISP16: irq 5 shouldn't be used by cdrom interface,"
-                      " due to possible conflicts with the sound card.\n");
-               break;
-       case 7:
-               irq_code = ISP16_IRQ_7;
-               printk("ISP16: irq 7 shouldn't be used by cdrom interface,"
-                      " due to possible conflicts with the sound card.\n");
-               break;
-       case 3:
-               irq_code = ISP16_IRQ_3;
-               break;
-       case 9:
-               irq_code = ISP16_IRQ_9;
-               break;
-       case 10:
-               irq_code = ISP16_IRQ_10;
-               break;
-       case 11:
-               irq_code = ISP16_IRQ_11;
-               break;
-       default:
-               printk("ISP16: irq %d not supported by cdrom interface.\n",
-                      irq);
-               return -1;
-       }
-       switch (dma) {
-       case 0:
-               dma_code = ISP16_DMA_X;
-               break;          /* disable dma */
-       case 1:
-               printk("ISP16: dma 1 cannot be used by cdrom interface,"
-                      " due to conflict with the sound card.\n");
-               return -1;
-               break;
-       case 3:
-               dma_code = ISP16_DMA_3;
-               break;
-       case 5:
-               dma_code = ISP16_DMA_5;
-               break;
-       case 6:
-               dma_code = ISP16_DMA_6;
-               break;
-       case 7:
-               dma_code = ISP16_DMA_7;
-               break;
-       default:
-               printk("ISP16: dma %d not supported by cdrom interface.\n",
-                      dma);
-               return -1;
-       }
-
-       if (drive_type != ISP16_SONY && drive_type != ISP16_PANASONIC0 &&
-           drive_type != ISP16_PANASONIC1 && drive_type != ISP16_SANYO0 &&
-           drive_type != ISP16_SANYO1 && drive_type != ISP16_MITSUMI &&
-           drive_type != ISP16_DRIVE_X) {
-               printk
-                   ("ISP16: drive type (code 0x%02X) not supported by cdrom"
-                    " interface.\n", drive_type);
-               return -1;
-       }
-
-       /* set type of interface */
-       i = ISP16_IN(ISP16_DRIVE_SET_PORT) & ISP16_DRIVE_SET_MASK;      /* clear some bits */
-       ISP16_OUT(ISP16_DRIVE_SET_PORT, i | drive_type);
-
-       /* enable cdrom on interface with 82C929 chip */
-       if (isp16_type > 1)
-               ISP16_OUT(isp16_enable_port, ISP16_ENABLE_CDROM);
-
-       /* set base address, irq and dma */
-       i = ISP16_IN(ISP16_IO_SET_PORT) & ISP16_IO_SET_MASK;    /* keep some bits */
-       ISP16_OUT(ISP16_IO_SET_PORT, i | base_code | irq_code | dma_code);
-
-       return 0;
-}
-
-static void __exit isp16_exit(void)
-{
-       release_region(ISP16_IO_BASE, ISP16_IO_SIZE);
-       printk(KERN_INFO "ISP16: module released.\n");
-}
-
-module_init(isp16_init);
-module_exit(isp16_exit);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/cdrom/isp16.h b/drivers/cdrom/isp16.h
deleted file mode 100644 (file)
index 5bd22c8..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/* -- isp16.h
- *
- *  Header for detection and initialisation of cdrom interface (only) on
- *  ISP16 (MAD16, Mozart) sound card.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You 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.
- *
- */
-
-/* These are the default values */
-#define ISP16_CDROM_TYPE "Sanyo"
-#define ISP16_CDROM_IO_BASE 0x340
-#define ISP16_CDROM_IRQ 0
-#define ISP16_CDROM_DMA 0
-
-/* Some (Media)Magic */
-/* define types of drive the interface on an ISP16 card may be looking at */
-#define ISP16_DRIVE_X 0x00
-#define ISP16_SONY  0x02
-#define ISP16_PANASONIC0 0x02
-#define ISP16_SANYO0 0x02
-#define ISP16_MITSUMI  0x04
-#define ISP16_PANASONIC1 0x06
-#define ISP16_SANYO1 0x06
-#define ISP16_DRIVE_NOT_USED 0x08  /* not used */
-#define ISP16_DRIVE_SET_MASK 0xF1  /* don't change 0-bit or 4-7-bits*/
-/* ...for port */
-#define ISP16_DRIVE_SET_PORT 0xF8D
-/* set io parameters */
-#define ISP16_BASE_340  0x00
-#define ISP16_BASE_330  0x40
-#define ISP16_BASE_360  0x80
-#define ISP16_BASE_320  0xC0
-#define ISP16_IRQ_X  0x00
-#define ISP16_IRQ_5  0x04  /* shouldn't be used to avoid sound card conflicts */
-#define ISP16_IRQ_7  0x08  /* shouldn't be used to avoid sound card conflicts */
-#define ISP16_IRQ_3  0x0C
-#define ISP16_IRQ_9  0x10
-#define ISP16_IRQ_10  0x14
-#define ISP16_IRQ_11  0x18
-#define ISP16_DMA_X  0x03
-#define ISP16_DMA_3  0x00
-#define ISP16_DMA_5  0x00
-#define ISP16_DMA_6  0x01
-#define ISP16_DMA_7  0x02
-#define ISP16_IO_SET_MASK  0x20  /* don't change 5-bit */
-/* ...for port */
-#define ISP16_IO_SET_PORT  0xF8E
-/* enable the card */
-#define ISP16_C928__ENABLE_PORT  0xF90  /* ISP16 with OPTi 82C928 chip */
-#define ISP16_C929__ENABLE_PORT  0xF91  /* ISP16 with OPTi 82C929 chip */
-#define ISP16_ENABLE_CDROM  0x80  /* seven bit */
-
-/* the magic stuff */
-#define ISP16_CTRL_PORT  0xF8F
-#define ISP16_C928__CTRL  0xE2  /* ISP16 with OPTi 82C928 chip */
-#define ISP16_C929__CTRL  0xE3  /* ISP16 with OPTi 82C929 chip */
-
-#define ISP16_IO_BASE 0xF8D
-#define ISP16_IO_SIZE 5  /* ports used from 0xF8D up to 0xF91 */
diff --git a/drivers/cdrom/mcdx.c b/drivers/cdrom/mcdx.c
deleted file mode 100644 (file)
index 4310cc8..0000000
+++ /dev/null
@@ -1,1943 +0,0 @@
-/*
- * The Mitsumi CDROM interface
- * Copyright (C) 1995 1996 Heiko Schlittermann <heiko@lotte.sax.de>
- * VERSION: 2.14(hs)
- *
- * ... anyway, I'm back again, thanks to Marcin, he adopted
- * large portions of my code (at least the parts containing
- * my main thoughts ...)
- *
- ****************** H E L P *********************************
- * If you ever plan to update your CD ROM drive and perhaps
- * want to sell or simply give away your Mitsumi FX-001[DS]
- * -- Please --
- * mail me (heiko@lotte.sax.de).  When my last drive goes
- * ballistic no more driver support will be available from me!
- *************************************************************
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.  If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Thanks to
- *  The Linux Community at all and ...
- *  Martin Harriss (he wrote the first Mitsumi Driver)
- *  Eberhard Moenkeberg (he gave me much support and the initial kick)
- *  Bernd Huebner, Ruediger Helsch (Unifix-Software GmbH, they
- *      improved the original driver)
- *  Jon Tombs, Bjorn Ekwall (module support)
- *  Daniel v. Mosnenck (he sent me the Technical and Programming Reference)
- *  Gerd Knorr (he lent me his PhotoCD)
- *  Nils Faerber and Roger E. Wolff (extensively tested the LU portion)
- *  Andreas Kies (testing the mysterious hang-ups)
- *  Heiko Eissfeldt (VERIFY_READ/WRITE)
- *  Marcin Dalecki (improved performance, shortened code)
- *  ... somebody forgotten?
- *
- *  9 November 1999 -- Make kernel-parameter implementation work with 2.3.x 
- *                    Removed init_module & cleanup_module in favor of 
- *                    module_init & module_exit.
- *                    Torben Mathiasen <tmm@image.dk>
- */
-
-
-#ifdef RCS
-static const char *mcdx_c_version
-    = "$Id: mcdx.c,v 1.21 1997/01/26 07:12:59 davem Exp $";
-#endif
-
-#include <linux/module.h>
-
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/cdrom.h>
-#include <linux/ioport.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <asm/io.h>
-#include <asm/current.h>
-#include <asm/uaccess.h>
-
-#include <linux/major.h>
-#define MAJOR_NR MITSUMI_X_CDROM_MAJOR
-#include <linux/blkdev.h>
-
-#include "mcdx.h"
-
-#ifndef HZ
-#error HZ not defined
-#endif
-
-#define xwarn(fmt, args...) printk(KERN_WARNING MCDX " " fmt, ## args)
-
-#if !MCDX_QUIET
-#define xinfo(fmt, args...) printk(KERN_INFO MCDX " " fmt, ## args)
-#else
-#define xinfo(fmt, args...) { ; }
-#endif
-
-#if MCDX_DEBUG
-#define xtrace(lvl, fmt, args...) \
-               { if (lvl > 0) \
-                       { printk(KERN_DEBUG MCDX ":: " fmt, ## args); } }
-#define xdebug(fmt, args...) printk(KERN_DEBUG MCDX ":: " fmt, ## args)
-#else
-#define xtrace(lvl, fmt, args...) { ; }
-#define xdebug(fmt, args...) { ; }
-#endif
-
-/* CONSTANTS *******************************************************/
-
-/* Following are the number of sectors we _request_ from the drive
-   every time an access outside the already requested range is done.
-   The _direct_ size is the number of sectors we're allowed to skip
-   directly (performing a read instead of requesting the new sector
-   needed */
-static const int REQUEST_SIZE = 800;   /* should be less then 255 * 4 */
-static const int DIRECT_SIZE = 400;    /* should be less then REQUEST_SIZE */
-
-enum drivemodes { TOC, DATA, RAW, COOKED };
-enum datamodes { MODE0, MODE1, MODE2 };
-enum resetmodes { SOFT, HARD };
-
-static const int SINGLE = 0x01;                /* single speed drive (FX001S, LU) */
-static const int DOUBLE = 0x02;                /* double speed drive (FX001D, ..? */
-static const int DOOR = 0x04;          /* door locking capability */
-static const int MULTI = 0x08;         /* multi session capability */
-
-static const unsigned char READ1X = 0xc0;
-static const unsigned char READ2X = 0xc1;
-
-
-/* DECLARATIONS ****************************************************/
-struct s_subqcode {
-       unsigned char control;
-       unsigned char tno;
-       unsigned char index;
-       struct cdrom_msf0 tt;
-       struct cdrom_msf0 dt;
-};
-
-struct s_diskinfo {
-       unsigned int n_first;
-       unsigned int n_last;
-       struct cdrom_msf0 msf_leadout;
-       struct cdrom_msf0 msf_first;
-};
-
-struct s_multi {
-       unsigned char multi;
-       struct cdrom_msf0 msf_last;
-};
-
-struct s_version {
-       unsigned char code;
-       unsigned char ver;
-};
-
-/* Per drive/controller stuff **************************************/
-
-struct s_drive_stuff {
-       /* waitqueues */
-       wait_queue_head_t busyq;
-       wait_queue_head_t lockq;
-       wait_queue_head_t sleepq;
-
-       /* flags */
-       volatile int introk;    /* status of last irq operation */
-       volatile int busy;      /* drive performs an operation */
-       volatile int lock;      /* exclusive usage */
-
-       /* cd infos */
-       struct s_diskinfo di;
-       struct s_multi multi;
-       struct s_subqcode *toc; /* first entry of the toc array */
-       struct s_subqcode start;
-       struct s_subqcode stop;
-       int xa;                 /* 1 if xa disk */
-       int audio;              /* 1 if audio disk */
-       int audiostatus;
-
-       /* `buffer' control */
-       volatile int valid;     /* pending, ..., values are valid */
-       volatile int pending;   /* next sector to be read */
-       volatile int low_border;        /* first sector not to be skipped direct */
-       volatile int high_border;       /* first sector `out of area' */
-#ifdef AK2
-       volatile int int_err;
-#endif                         /* AK2 */
-
-       /* adds and odds */
-       unsigned wreg_data;     /* w data */
-       unsigned wreg_reset;    /* w hardware reset */
-       unsigned wreg_hcon;     /* w hardware conf */
-       unsigned wreg_chn;      /* w channel */
-       unsigned rreg_data;     /* r data */
-       unsigned rreg_status;   /* r status */
-
-       int irq;                /* irq used by this drive */
-       int present;            /* drive present and its capabilities */
-       unsigned char readcmd;  /* read cmd depends on single/double speed */
-       unsigned char playcmd;  /* play should always be single speed */
-       unsigned int xxx;       /* set if changed, reset while open */
-       unsigned int yyy;       /* set if changed, reset by media_changed */
-       int users;              /* keeps track of open/close */
-       int lastsector;         /* last block accessible */
-       int status;             /* last operation's error / status */
-       int readerrs;           /* # of blocks read w/o error */
-       struct cdrom_device_info info;
-       struct gendisk *disk;
-};
-
-
-/* Prototypes ******************************************************/
-
-/*     The following prototypes are already declared elsewhere.  They are
-       repeated here to show what's going on.  And to sense, if they're
-       changed elsewhere. */
-
-static int mcdx_init(void);
-
-static int mcdx_block_open(struct inode *inode, struct file *file)
-{
-       struct s_drive_stuff *p = inode->i_bdev->bd_disk->private_data;
-       return cdrom_open(&p->info, inode, file);
-}
-
-static int mcdx_block_release(struct inode *inode, struct file *file)
-{
-       struct s_drive_stuff *p = inode->i_bdev->bd_disk->private_data;
-       return cdrom_release(&p->info, file);
-}
-
-static int mcdx_block_ioctl(struct inode *inode, struct file *file,
-                               unsigned cmd, unsigned long arg)
-{
-       struct s_drive_stuff *p = inode->i_bdev->bd_disk->private_data;
-       return cdrom_ioctl(file, &p->info, inode, cmd, arg);
-}
-
-static int mcdx_block_media_changed(struct gendisk *disk)
-{
-       struct s_drive_stuff *p = disk->private_data;
-       return cdrom_media_changed(&p->info);
-}
-
-static struct block_device_operations mcdx_bdops =
-{
-       .owner          = THIS_MODULE,
-       .open           = mcdx_block_open,
-       .release        = mcdx_block_release,
-       .ioctl          = mcdx_block_ioctl,
-       .media_changed  = mcdx_block_media_changed,
-};
-
-
-/*     Indirect exported functions. These functions are exported by their
-       addresses, such as mcdx_open and mcdx_close in the
-       structure mcdx_dops. */
-
-/* exported by file_ops */
-static int mcdx_open(struct cdrom_device_info *cdi, int purpose);
-static void mcdx_close(struct cdrom_device_info *cdi);
-static int mcdx_media_changed(struct cdrom_device_info *cdi, int disc_nr);
-static int mcdx_tray_move(struct cdrom_device_info *cdi, int position);
-static int mcdx_lockdoor(struct cdrom_device_info *cdi, int lock);
-static int mcdx_audio_ioctl(struct cdrom_device_info *cdi,
-                           unsigned int cmd, void *arg);
-
-/* misc internal support functions */
-static void log2msf(unsigned int, struct cdrom_msf0 *);
-static unsigned int msf2log(const struct cdrom_msf0 *);
-static unsigned int uint2bcd(unsigned int);
-static unsigned int bcd2uint(unsigned char);
-static unsigned port(int *);
-static int irq(int *);
-static void mcdx_delay(struct s_drive_stuff *, long jifs);
-static int mcdx_transfer(struct s_drive_stuff *, char *buf, int sector,
-                        int nr_sectors);
-static int mcdx_xfer(struct s_drive_stuff *, char *buf, int sector,
-                    int nr_sectors);
-
-static int mcdx_config(struct s_drive_stuff *, int);
-static int mcdx_requestversion(struct s_drive_stuff *, struct s_version *,
-                              int);
-static int mcdx_stop(struct s_drive_stuff *, int);
-static int mcdx_hold(struct s_drive_stuff *, int);
-static int mcdx_reset(struct s_drive_stuff *, enum resetmodes, int);
-static int mcdx_setdrivemode(struct s_drive_stuff *, enum drivemodes, int);
-static int mcdx_setdatamode(struct s_drive_stuff *, enum datamodes, int);
-static int mcdx_requestsubqcode(struct s_drive_stuff *,
-                               struct s_subqcode *, int);
-static int mcdx_requestmultidiskinfo(struct s_drive_stuff *,
-                                    struct s_multi *, int);
-static int mcdx_requesttocdata(struct s_drive_stuff *, struct s_diskinfo *,
-                              int);
-static int mcdx_getstatus(struct s_drive_stuff *, int);
-static int mcdx_getval(struct s_drive_stuff *, int to, int delay, char *);
-static int mcdx_talk(struct s_drive_stuff *,
-                    const unsigned char *cmd, size_t,
-                    void *buffer, size_t size, unsigned int timeout, int);
-static int mcdx_readtoc(struct s_drive_stuff *);
-static int mcdx_playtrk(struct s_drive_stuff *, const struct cdrom_ti *);
-static int mcdx_playmsf(struct s_drive_stuff *, const struct cdrom_msf *);
-static int mcdx_setattentuator(struct s_drive_stuff *,
-                              struct cdrom_volctrl *, int);
-
-/* static variables ************************************************/
-
-static int mcdx_drive_map[][2] = MCDX_DRIVEMAP;
-static struct s_drive_stuff *mcdx_stuffp[MCDX_NDRIVES];
-static DEFINE_SPINLOCK(mcdx_lock);
-static struct request_queue *mcdx_queue;
-
-/* You can only set the first two pairs, from old MODULE_PARM code.  */
-static int mcdx_set(const char *val, struct kernel_param *kp)
-{
-       get_options((char *)val, 4, (int *)mcdx_drive_map);
-       return 0;
-}
-module_param_call(mcdx, mcdx_set, NULL, NULL, 0);
-
-static struct cdrom_device_ops mcdx_dops = {
-       .open           = mcdx_open,
-       .release        = mcdx_close,
-       .media_changed  = mcdx_media_changed,
-       .tray_move      = mcdx_tray_move,
-       .lock_door      = mcdx_lockdoor,
-       .audio_ioctl    = mcdx_audio_ioctl,
-       .capability     = CDC_OPEN_TRAY | CDC_LOCK | CDC_MEDIA_CHANGED |
-                         CDC_PLAY_AUDIO | CDC_DRIVE_STATUS,
-};
-
-/* KERNEL INTERFACE FUNCTIONS **************************************/
-
-
-static int mcdx_audio_ioctl(struct cdrom_device_info *cdi,
-                           unsigned int cmd, void *arg)
-{
-       struct s_drive_stuff *stuffp = cdi->handle;
-
-       if (!stuffp->present)
-               return -ENXIO;
-
-       if (stuffp->xxx) {
-               if (-1 == mcdx_requesttocdata(stuffp, &stuffp->di, 1)) {
-                       stuffp->lastsector = -1;
-               } else {
-                       stuffp->lastsector = (CD_FRAMESIZE / 512)
-                           * msf2log(&stuffp->di.msf_leadout) - 1;
-               }
-
-               if (stuffp->toc) {
-                       kfree(stuffp->toc);
-                       stuffp->toc = NULL;
-                       if (-1 == mcdx_readtoc(stuffp))
-                               return -1;
-               }
-
-               stuffp->xxx = 0;
-       }
-
-       switch (cmd) {
-       case CDROMSTART:{
-                       xtrace(IOCTL, "ioctl() START\n");
-                       /* Spin up the drive.  Don't think we can do this.
-                          * For now, ignore it.
-                        */
-                       return 0;
-               }
-
-       case CDROMSTOP:{
-                       xtrace(IOCTL, "ioctl() STOP\n");
-                       stuffp->audiostatus = CDROM_AUDIO_INVALID;
-                       if (-1 == mcdx_stop(stuffp, 1))
-                               return -EIO;
-                       return 0;
-               }
-
-       case CDROMPLAYTRKIND:{
-                       struct cdrom_ti *ti = (struct cdrom_ti *) arg;
-
-                       xtrace(IOCTL, "ioctl() PLAYTRKIND\n");
-                       if ((ti->cdti_trk0 < stuffp->di.n_first)
-                           || (ti->cdti_trk0 > stuffp->di.n_last)
-                           || (ti->cdti_trk1 < stuffp->di.n_first))
-                               return -EINVAL;
-                       if (ti->cdti_trk1 > stuffp->di.n_last)
-                               ti->cdti_trk1 = stuffp->di.n_last;
-                       xtrace(PLAYTRK, "ioctl() track %d to %d\n",
-                              ti->cdti_trk0, ti->cdti_trk1);
-                       return mcdx_playtrk(stuffp, ti);
-               }
-
-       case CDROMPLAYMSF:{
-                       struct cdrom_msf *msf = (struct cdrom_msf *) arg;
-
-                       xtrace(IOCTL, "ioctl() PLAYMSF\n");
-
-                       if ((stuffp->audiostatus == CDROM_AUDIO_PLAY)
-                           && (-1 == mcdx_hold(stuffp, 1)))
-                               return -EIO;
-
-                       msf->cdmsf_min0 = uint2bcd(msf->cdmsf_min0);
-                       msf->cdmsf_sec0 = uint2bcd(msf->cdmsf_sec0);
-                       msf->cdmsf_frame0 = uint2bcd(msf->cdmsf_frame0);
-
-                       msf->cdmsf_min1 = uint2bcd(msf->cdmsf_min1);
-                       msf->cdmsf_sec1 = uint2bcd(msf->cdmsf_sec1);
-                       msf->cdmsf_frame1 = uint2bcd(msf->cdmsf_frame1);
-
-                       stuffp->stop.dt.minute = msf->cdmsf_min1;
-                       stuffp->stop.dt.second = msf->cdmsf_sec1;
-                       stuffp->stop.dt.frame = msf->cdmsf_frame1;
-
-                       return mcdx_playmsf(stuffp, msf);
-               }
-
-       case CDROMRESUME:{
-                       xtrace(IOCTL, "ioctl() RESUME\n");
-                       return mcdx_playtrk(stuffp, NULL);
-               }
-
-       case CDROMREADTOCENTRY:{
-                       struct cdrom_tocentry *entry =
-                           (struct cdrom_tocentry *) arg;
-                       struct s_subqcode *tp = NULL;
-                       xtrace(IOCTL, "ioctl() READTOCENTRY\n");
-
-                       if (-1 == mcdx_readtoc(stuffp))
-                               return -1;
-                       if (entry->cdte_track == CDROM_LEADOUT)
-                               tp = &stuffp->toc[stuffp->di.n_last -
-                                                 stuffp->di.n_first + 1];
-                       else if (entry->cdte_track > stuffp->di.n_last
-                                || entry->cdte_track < stuffp->di.n_first)
-                               return -EINVAL;
-                       else
-                               tp = &stuffp->toc[entry->cdte_track -
-                                                 stuffp->di.n_first];
-
-                       if (NULL == tp)
-                               return -EIO;
-                       entry->cdte_adr = tp->control;
-                       entry->cdte_ctrl = tp->control >> 4;
-                       /* Always return stuff in MSF, and let the Uniform cdrom driver
-                          worry about what the user actually wants */
-                       entry->cdte_addr.msf.minute =
-                           bcd2uint(tp->dt.minute);
-                       entry->cdte_addr.msf.second =
-                           bcd2uint(tp->dt.second);
-                       entry->cdte_addr.msf.frame =
-                           bcd2uint(tp->dt.frame);
-                       return 0;
-               }
-
-       case CDROMSUBCHNL:{
-                       struct cdrom_subchnl *sub =
-                           (struct cdrom_subchnl *) arg;
-                       struct s_subqcode q;
-
-                       xtrace(IOCTL, "ioctl() SUBCHNL\n");
-
-                       if (-1 == mcdx_requestsubqcode(stuffp, &q, 2))
-                               return -EIO;
-
-                       xtrace(SUBCHNL, "audiostatus: %x\n",
-                              stuffp->audiostatus);
-                       sub->cdsc_audiostatus = stuffp->audiostatus;
-                       sub->cdsc_adr = q.control;
-                       sub->cdsc_ctrl = q.control >> 4;
-                       sub->cdsc_trk = bcd2uint(q.tno);
-                       sub->cdsc_ind = bcd2uint(q.index);
-
-                       xtrace(SUBCHNL, "trk %d, ind %d\n",
-                              sub->cdsc_trk, sub->cdsc_ind);
-                       /* Always return stuff in MSF, and let the Uniform cdrom driver
-                          worry about what the user actually wants */
-                       sub->cdsc_absaddr.msf.minute =
-                           bcd2uint(q.dt.minute);
-                       sub->cdsc_absaddr.msf.second =
-                           bcd2uint(q.dt.second);
-                       sub->cdsc_absaddr.msf.frame = bcd2uint(q.dt.frame);
-                       sub->cdsc_reladdr.msf.minute =
-                           bcd2uint(q.tt.minute);
-                       sub->cdsc_reladdr.msf.second =
-                           bcd2uint(q.tt.second);
-                       sub->cdsc_reladdr.msf.frame = bcd2uint(q.tt.frame);
-                       xtrace(SUBCHNL,
-                              "msf: abs %02d:%02d:%02d, rel %02d:%02d:%02d\n",
-                              sub->cdsc_absaddr.msf.minute,
-                              sub->cdsc_absaddr.msf.second,
-                              sub->cdsc_absaddr.msf.frame,
-                              sub->cdsc_reladdr.msf.minute,
-                              sub->cdsc_reladdr.msf.second,
-                              sub->cdsc_reladdr.msf.frame);
-
-                       return 0;
-               }
-
-       case CDROMREADTOCHDR:{
-                       struct cdrom_tochdr *toc =
-                           (struct cdrom_tochdr *) arg;
-
-                       xtrace(IOCTL, "ioctl() READTOCHDR\n");
-                       toc->cdth_trk0 = stuffp->di.n_first;
-                       toc->cdth_trk1 = stuffp->di.n_last;
-                       xtrace(TOCHDR,
-                              "ioctl() track0 = %d, track1 = %d\n",
-                              stuffp->di.n_first, stuffp->di.n_last);
-                       return 0;
-               }
-
-       case CDROMPAUSE:{
-                       xtrace(IOCTL, "ioctl() PAUSE\n");
-                       if (stuffp->audiostatus != CDROM_AUDIO_PLAY)
-                               return -EINVAL;
-                       if (-1 == mcdx_stop(stuffp, 1))
-                               return -EIO;
-                       stuffp->audiostatus = CDROM_AUDIO_PAUSED;
-                       if (-1 ==
-                           mcdx_requestsubqcode(stuffp, &stuffp->start,
-                                                1))
-                               return -EIO;
-                       return 0;
-               }
-
-       case CDROMMULTISESSION:{
-                       struct cdrom_multisession *ms =
-                           (struct cdrom_multisession *) arg;
-                       xtrace(IOCTL, "ioctl() MULTISESSION\n");
-                       /* Always return stuff in LBA, and let the Uniform cdrom driver
-                          worry about what the user actually wants */
-                       ms->addr.lba = msf2log(&stuffp->multi.msf_last);
-                       ms->xa_flag = !!stuffp->multi.multi;
-                       xtrace(MS,
-                              "ioctl() (%d, 0x%08x [%02x:%02x.%02x])\n",
-                              ms->xa_flag, ms->addr.lba,
-                              stuffp->multi.msf_last.minute,
-                              stuffp->multi.msf_last.second,
-                              stuffp->multi.msf_last.frame);
-
-                       return 0;
-               }
-
-       case CDROMEJECT:{
-                       xtrace(IOCTL, "ioctl() EJECT\n");
-                       if (stuffp->users > 1)
-                               return -EBUSY;
-                       return (mcdx_tray_move(cdi, 1));
-               }
-
-       case CDROMCLOSETRAY:{
-                       xtrace(IOCTL, "ioctl() CDROMCLOSETRAY\n");
-                       return (mcdx_tray_move(cdi, 0));
-               }
-
-       case CDROMVOLCTRL:{
-                       struct cdrom_volctrl *volctrl =
-                           (struct cdrom_volctrl *) arg;
-                       xtrace(IOCTL, "ioctl() VOLCTRL\n");
-
-#if 0                          /* not tested! */
-                       /* adjust for the weirdness of workman (md) */
-                       /* can't test it (hs) */
-                       volctrl.channel2 = volctrl.channel1;
-                       volctrl.channel1 = volctrl.channel3 = 0x00;
-#endif
-                       return mcdx_setattentuator(stuffp, volctrl, 2);
-               }
-
-       default:
-               return -EINVAL;
-       }
-}
-
-static void do_mcdx_request(request_queue_t * q)
-{
-       struct s_drive_stuff *stuffp;
-       struct request *req;
-
-      again:
-
-       req = elv_next_request(q);
-       if (!req)
-               return;
-
-       stuffp = req->rq_disk->private_data;
-
-       if (!stuffp->present) {
-               xwarn("do_request(): bad device: %s\n",req->rq_disk->disk_name);
-               xtrace(REQUEST, "end_request(0): bad device\n");
-               end_request(req, 0);
-               return;
-       }
-
-       if (stuffp->audio) {
-               xwarn("do_request() attempt to read from audio cd\n");
-               xtrace(REQUEST, "end_request(0): read from audio\n");
-               end_request(req, 0);
-               return;
-       }
-
-       xtrace(REQUEST, "do_request() (%lu + %lu)\n",
-              req->sector, req->nr_sectors);
-
-       if (req->cmd != READ) {
-               xwarn("do_request(): non-read command to cd!!\n");
-               xtrace(REQUEST, "end_request(0): write\n");
-               end_request(req, 0);
-               return;
-       }
-       else {
-               stuffp->status = 0;
-               while (req->nr_sectors) {
-                       int i;
-
-                       i = mcdx_transfer(stuffp,
-                                         req->buffer,
-                                         req->sector,
-                                         req->nr_sectors);
-
-                       if (i == -1) {
-                               end_request(req, 0);
-                               goto again;
-                       }
-                       req->sector += i;
-                       req->nr_sectors -= i;
-                       req->buffer += (i * 512);
-               }
-               end_request(req, 1);
-               goto again;
-
-               xtrace(REQUEST, "end_request(1)\n");
-               end_request(req, 1);
-       }
-
-       goto again;
-}
-
-static int mcdx_open(struct cdrom_device_info *cdi, int purpose)
-{
-       struct s_drive_stuff *stuffp;
-       xtrace(OPENCLOSE, "open()\n");
-       stuffp = cdi->handle;
-       if (!stuffp->present)
-               return -ENXIO;
-
-       /* Make the modules looking used ... (thanx bjorn).
-        * But we shouldn't forget to decrement the module counter
-        * on error return */
-
-       /* this is only done to test if the drive talks with us */
-       if (-1 == mcdx_getstatus(stuffp, 1))
-               return -EIO;
-
-       if (stuffp->xxx) {
-
-               xtrace(OPENCLOSE, "open() media changed\n");
-               stuffp->audiostatus = CDROM_AUDIO_INVALID;
-               stuffp->readcmd = 0;
-               xtrace(OPENCLOSE, "open() Request multisession info\n");
-               if (-1 ==
-                   mcdx_requestmultidiskinfo(stuffp, &stuffp->multi, 6))
-                       xinfo("No multidiskinfo\n");
-       } else {
-               /* multisession ? */
-               if (!stuffp->multi.multi)
-                       stuffp->multi.msf_last.second = 2;
-
-               xtrace(OPENCLOSE, "open() MS: %d, last @ %02x:%02x.%02x\n",
-                      stuffp->multi.multi,
-                      stuffp->multi.msf_last.minute,
-                      stuffp->multi.msf_last.second,
-                      stuffp->multi.msf_last.frame);
-
-               {;
-               }               /* got multisession information */
-               /* request the disks table of contents (aka diskinfo) */
-               if (-1 == mcdx_requesttocdata(stuffp, &stuffp->di, 1)) {
-
-                       stuffp->lastsector = -1;
-
-               } else {
-
-                       stuffp->lastsector = (CD_FRAMESIZE / 512)
-                           * msf2log(&stuffp->di.msf_leadout) - 1;
-
-                       xtrace(OPENCLOSE,
-                              "open() start %d (%02x:%02x.%02x) %d\n",
-                              stuffp->di.n_first,
-                              stuffp->di.msf_first.minute,
-                              stuffp->di.msf_first.second,
-                              stuffp->di.msf_first.frame,
-                              msf2log(&stuffp->di.msf_first));
-                       xtrace(OPENCLOSE,
-                              "open() last %d (%02x:%02x.%02x) %d\n",
-                              stuffp->di.n_last,
-                              stuffp->di.msf_leadout.minute,
-                              stuffp->di.msf_leadout.second,
-                              stuffp->di.msf_leadout.frame,
-                              msf2log(&stuffp->di.msf_leadout));
-               }
-
-               if (stuffp->toc) {
-                       xtrace(MALLOC, "open() free old toc @ %p\n",
-                              stuffp->toc);
-                       kfree(stuffp->toc);
-
-                       stuffp->toc = NULL;
-               }
-
-               xtrace(OPENCLOSE, "open() init irq generation\n");
-               if (-1 == mcdx_config(stuffp, 1))
-                       return -EIO;
-#ifdef FALLBACK
-               /* Set the read speed */
-               xwarn("AAA %x AAA\n", stuffp->readcmd);
-               if (stuffp->readerrs)
-                       stuffp->readcmd = READ1X;
-               else
-                       stuffp->readcmd =
-                           stuffp->present | SINGLE ? READ1X : READ2X;
-               xwarn("XXX %x XXX\n", stuffp->readcmd);
-#else
-               stuffp->readcmd =
-                   stuffp->present | SINGLE ? READ1X : READ2X;
-#endif
-
-               /* try to get the first sector, iff any ... */
-               if (stuffp->lastsector >= 0) {
-                       char buf[512];
-                       int ans;
-                       int tries;
-
-                       stuffp->xa = 0;
-                       stuffp->audio = 0;
-
-                       for (tries = 6; tries; tries--) {
-
-                               stuffp->introk = 1;
-
-                               xtrace(OPENCLOSE, "open() try as %s\n",
-                                      stuffp->xa ? "XA" : "normal");
-                               /* set data mode */
-                               if (-1 == (ans = mcdx_setdatamode(stuffp,
-                                                                 stuffp->
-                                                                 xa ?
-                                                                 MODE2 :
-                                                                 MODE1,
-                                                                 1))) {
-                                       /* return -EIO; */
-                                       stuffp->xa = 0;
-                                       break;
-                               }
-
-                               if ((stuffp->audio = e_audio(ans)))
-                                       break;
-
-                               while (0 ==
-                                      (ans =
-                                       mcdx_transfer(stuffp, buf, 0, 1)));
-
-                               if (ans == 1)
-                                       break;
-                               stuffp->xa = !stuffp->xa;
-                       }
-               }
-               /* xa disks will be read in raw mode, others not */
-               if (-1 == mcdx_setdrivemode(stuffp,
-                                           stuffp->xa ? RAW : COOKED,
-                                           1))
-                       return -EIO;
-               if (stuffp->audio) {
-                       xinfo("open() audio disk found\n");
-               } else if (stuffp->lastsector >= 0) {
-                       xinfo("open() %s%s disk found\n",
-                             stuffp->xa ? "XA / " : "",
-                             stuffp->multi.
-                             multi ? "Multi Session" : "Single Session");
-               }
-       }
-       stuffp->xxx = 0;
-       stuffp->users++;
-       return 0;
-}
-
-static void mcdx_close(struct cdrom_device_info *cdi)
-{
-       struct s_drive_stuff *stuffp;
-
-       xtrace(OPENCLOSE, "close()\n");
-
-       stuffp = cdi->handle;
-
-       --stuffp->users;
-}
-
-static int mcdx_media_changed(struct cdrom_device_info *cdi, int disc_nr)
-/*     Return: 1 if media changed since last call to this function
-                       0 otherwise */
-{
-       struct s_drive_stuff *stuffp;
-
-       xinfo("mcdx_media_changed called for device %s\n", cdi->name);
-
-       stuffp = cdi->handle;
-       mcdx_getstatus(stuffp, 1);
-
-       if (stuffp->yyy == 0)
-               return 0;
-
-       stuffp->yyy = 0;
-       return 1;
-}
-
-#ifndef MODULE
-static int __init mcdx_setup(char *str)
-{
-       int pi[4];
-       (void) get_options(str, ARRAY_SIZE(pi), pi);
-
-       if (pi[0] > 0)
-               mcdx_drive_map[0][0] = pi[1];
-       if (pi[0] > 1)
-               mcdx_drive_map[0][1] = pi[2];
-       return 1;
-}
-
-__setup("mcdx=", mcdx_setup);
-
-#endif
-
-/* DIRTY PART ******************************************************/
-
-static void mcdx_delay(struct s_drive_stuff *stuff, long jifs)
-/* This routine is used for sleeping.
- * A jifs value <0 means NO sleeping,
- *              =0 means minimal sleeping (let the kernel
- *                 run for other processes)
- *              >0 means at least sleep for that amount.
- *     May be we could use a simple count loop w/ jumps to itself, but
- *     I wanna make this independent of cpu speed. [1 jiffy is 1/HZ] sec */
-{
-       if (jifs < 0)
-               return;
-
-       xtrace(SLEEP, "*** delay: sleepq\n");
-       interruptible_sleep_on_timeout(&stuff->sleepq, jifs);
-       xtrace(SLEEP, "delay awoken\n");
-       if (signal_pending(current)) {
-               xtrace(SLEEP, "got signal\n");
-       }
-}
-
-static irqreturn_t mcdx_intr(int irq, void *dev_id)
-{
-       struct s_drive_stuff *stuffp = dev_id;
-       unsigned char b;
-
-#ifdef AK2
-       if (!stuffp->busy && stuffp->pending)
-               stuffp->int_err = 1;
-
-#endif                         /* AK2 */
-       /* get the interrupt status */
-       b = inb(stuffp->rreg_status);
-       stuffp->introk = ~b & MCDX_RBIT_DTEN;
-
-       /* NOTE: We only should get interrupts if the data we
-        * requested are ready to transfer.
-        * But the drive seems to generate ``asynchronous'' interrupts
-        * on several error conditions too.  (Despite the err int enable
-        * setting during initialisation) */
-
-       /* if not ok, read the next byte as the drives status */
-       if (!stuffp->introk) {
-               xtrace(IRQ, "intr() irq %d hw status 0x%02x\n", irq, b);
-               if (~b & MCDX_RBIT_STEN) {
-                       xinfo("intr() irq %d    status 0x%02x\n",
-                             irq, inb(stuffp->rreg_data));
-               } else {
-                       xinfo("intr() irq %d ambiguous hw status\n", irq);
-               }
-       } else {
-               xtrace(IRQ, "irq() irq %d ok, status %02x\n", irq, b);
-       }
-
-       stuffp->busy = 0;
-       wake_up_interruptible(&stuffp->busyq);
-       return IRQ_HANDLED;
-}
-
-
-static int mcdx_talk(struct s_drive_stuff *stuffp,
-         const unsigned char *cmd, size_t cmdlen,
-         void *buffer, size_t size, unsigned int timeout, int tries)
-/* Send a command to the drive, wait for the result.
- * returns -1 on timeout, drive status otherwise
- * If buffer is not zero, the result (length size) is stored there.
- * If buffer is zero the size should be the number of bytes to read
- * from the drive.  These bytes are discarded.
- */
-{
-       int st;
-       char c;
-       int discard;
-
-       /* Somebody wants the data read? */
-       if ((discard = (buffer == NULL)))
-               buffer = &c;
-
-       while (stuffp->lock) {
-               xtrace(SLEEP, "*** talk: lockq\n");
-               interruptible_sleep_on(&stuffp->lockq);
-               xtrace(SLEEP, "talk: awoken\n");
-       }
-
-       stuffp->lock = 1;
-
-       /* An operation other then reading data destroys the
-          * data already requested and remembered in stuffp->request, ... */
-       stuffp->valid = 0;
-
-#if MCDX_DEBUG & TALK
-       {
-               unsigned char i;
-               xtrace(TALK,
-                      "talk() %d / %d tries, res.size %d, command 0x%02x",
-                      tries, timeout, size, (unsigned char) cmd[0]);
-               for (i = 1; i < cmdlen; i++)
-                       xtrace(TALK, " 0x%02x", cmd[i]);
-               xtrace(TALK, "\n");
-       }
-#endif
-
-       /*  give up if all tries are done (bad) or if the status
-        *  st != -1 (good) */
-       for (st = -1; st == -1 && tries; tries--) {
-
-               char *bp = (char *) buffer;
-               size_t sz = size;
-
-               outsb(stuffp->wreg_data, cmd, cmdlen);
-               xtrace(TALK, "talk() command sent\n");
-
-               /* get the status byte */
-               if (-1 == mcdx_getval(stuffp, timeout, 0, bp)) {
-                       xinfo("talk() %02x timed out (status), %d tr%s left\n",
-                            cmd[0], tries - 1, tries == 2 ? "y" : "ies");
-                       continue;
-               }
-               st = *bp;
-               sz--;
-               if (!discard)
-                       bp++;
-
-               xtrace(TALK, "talk() got status 0x%02x\n", st);
-
-               /* command error? */
-               if (e_cmderr(st)) {
-                       xwarn("command error cmd = %02x %s \n",
-                             cmd[0], cmdlen > 1 ? "..." : "");
-                       st = -1;
-                       continue;
-               }
-
-               /* audio status? */
-               if (stuffp->audiostatus == CDROM_AUDIO_INVALID)
-                       stuffp->audiostatus =
-                           e_audiobusy(st) ? CDROM_AUDIO_PLAY :
-                           CDROM_AUDIO_NO_STATUS;
-               else if (stuffp->audiostatus == CDROM_AUDIO_PLAY
-                        && e_audiobusy(st) == 0)
-                       stuffp->audiostatus = CDROM_AUDIO_COMPLETED;
-
-               /* media change? */
-               if (e_changed(st)) {
-                       xinfo("talk() media changed\n");
-                       stuffp->xxx = stuffp->yyy = 1;
-               }
-
-               /* now actually get the data */
-               while (sz--) {
-                       if (-1 == mcdx_getval(stuffp, timeout, 0, bp)) {
-                               xinfo("talk() %02x timed out (data), %d tr%s left\n",
-                                    cmd[0], tries - 1,
-                                    tries == 2 ? "y" : "ies");
-                               st = -1;
-                               break;
-                       }
-                       if (!discard)
-                               bp++;
-                       xtrace(TALK, "talk() got 0x%02x\n", *(bp - 1));
-               }
-       }
-
-#if !MCDX_QUIET
-       if (!tries && st == -1)
-               xinfo("talk() giving up\n");
-#endif
-
-       stuffp->lock = 0;
-       wake_up_interruptible(&stuffp->lockq);
-
-       xtrace(TALK, "talk() done with 0x%02x\n", st);
-       return st;
-}
-
-/* MODULE STUFF ***********************************************************/
-
-static int __init __mcdx_init(void)
-{
-       int i;
-       int drives = 0;
-
-       mcdx_init();
-       for (i = 0; i < MCDX_NDRIVES; i++) {
-               if (mcdx_stuffp[i]) {
-                       xtrace(INIT, "init_module() drive %d stuff @ %p\n",
-                              i, mcdx_stuffp[i]);
-                       drives++;
-               }
-       }
-
-       if (!drives)
-               return -EIO;
-
-       return 0;
-}
-
-static void __exit mcdx_exit(void)
-{
-       int i;
-
-       xinfo("cleanup_module called\n");
-
-       for (i = 0; i < MCDX_NDRIVES; i++) {
-               struct s_drive_stuff *stuffp = mcdx_stuffp[i];
-               if (!stuffp)
-                       continue;
-               del_gendisk(stuffp->disk);
-               if (unregister_cdrom(&stuffp->info)) {
-                       printk(KERN_WARNING "Can't unregister cdrom mcdx\n");
-                       continue;
-               }
-               put_disk(stuffp->disk);
-               release_region(stuffp->wreg_data, MCDX_IO_SIZE);
-               free_irq(stuffp->irq, NULL);
-               if (stuffp->toc) {
-                       xtrace(MALLOC, "cleanup_module() free toc @ %p\n",
-                              stuffp->toc);
-                       kfree(stuffp->toc);
-               }
-               xtrace(MALLOC, "cleanup_module() free stuffp @ %p\n",
-                      stuffp);
-               mcdx_stuffp[i] = NULL;
-               kfree(stuffp);
-       }
-
-       if (unregister_blkdev(MAJOR_NR, "mcdx") != 0) {
-               xwarn("cleanup() unregister_blkdev() failed\n");
-       }
-#if !MCDX_QUIET
-       else
-       xinfo("cleanup() succeeded\n");
-#endif
-       blk_cleanup_queue(mcdx_queue);
-}
-
-#ifdef MODULE
-module_init(__mcdx_init);
-#endif
-module_exit(mcdx_exit);
-
-
-/* Support functions ************************************************/
-
-static int __init mcdx_init_drive(int drive)
-{
-       struct s_version version;
-       struct gendisk *disk;
-       struct s_drive_stuff *stuffp;
-       int size = sizeof(*stuffp);
-       char msg[80];
-
-       xtrace(INIT, "init() try drive %d\n", drive);
-
-       xtrace(INIT, "kmalloc space for stuffpt's\n");
-       xtrace(MALLOC, "init() malloc %d bytes\n", size);
-       if (!(stuffp = kzalloc(size, GFP_KERNEL))) {
-               xwarn("init() malloc failed\n");
-               return 1;
-       }
-
-       disk = alloc_disk(1);
-       if (!disk) {
-               xwarn("init() malloc failed\n");
-               kfree(stuffp);
-               return 1;
-       }
-
-       xtrace(INIT, "init() got %d bytes for drive stuff @ %p\n",
-              sizeof(*stuffp), stuffp);
-
-       /* set default values */
-       stuffp->present = 0;    /* this should be 0 already */
-       stuffp->toc = NULL;     /* this should be NULL already */
-
-       /* setup our irq and i/o addresses */
-       stuffp->irq = irq(mcdx_drive_map[drive]);
-       stuffp->wreg_data = stuffp->rreg_data = port(mcdx_drive_map[drive]);
-       stuffp->wreg_reset = stuffp->rreg_status = stuffp->wreg_data + 1;
-       stuffp->wreg_hcon = stuffp->wreg_reset + 1;
-       stuffp->wreg_chn = stuffp->wreg_hcon + 1;
-
-       init_waitqueue_head(&stuffp->busyq);
-       init_waitqueue_head(&stuffp->lockq);
-       init_waitqueue_head(&stuffp->sleepq);
-
-       /* check if i/o addresses are available */
-       if (!request_region(stuffp->wreg_data, MCDX_IO_SIZE, "mcdx")) {
-               xwarn("0x%03x,%d: Init failed. "
-                     "I/O ports (0x%03x..0x%03x) already in use.\n",
-                     stuffp->wreg_data, stuffp->irq,
-                     stuffp->wreg_data,
-                     stuffp->wreg_data + MCDX_IO_SIZE - 1);
-               xtrace(MALLOC, "init() free stuffp @ %p\n", stuffp);
-               kfree(stuffp);
-               put_disk(disk);
-               xtrace(INIT, "init() continue at next drive\n");
-               return 0;       /* next drive */
-       }
-
-       xtrace(INIT, "init() i/o port is available at 0x%03x\n"
-              stuffp->wreg_data);
-       xtrace(INIT, "init() hardware reset\n");
-       mcdx_reset(stuffp, HARD, 1);
-
-       xtrace(INIT, "init() get version\n");
-       if (-1 == mcdx_requestversion(stuffp, &version, 4)) {
-               /* failed, next drive */
-               release_region(stuffp->wreg_data, MCDX_IO_SIZE);
-               xwarn("%s=0x%03x,%d: Init failed. Can't get version.\n",
-                     MCDX, stuffp->wreg_data, stuffp->irq);
-               xtrace(MALLOC, "init() free stuffp @ %p\n", stuffp);
-               kfree(stuffp);
-               put_disk(disk);
-               xtrace(INIT, "init() continue at next drive\n");
-               return 0;
-       }
-
-       switch (version.code) {
-       case 'D':
-               stuffp->readcmd = READ2X;
-               stuffp->present = DOUBLE | DOOR | MULTI;
-               break;
-       case 'F':
-               stuffp->readcmd = READ1X;
-               stuffp->present = SINGLE | DOOR | MULTI;
-               break;
-       case 'M':
-               stuffp->readcmd = READ1X;
-               stuffp->present = SINGLE;
-               break;
-       default:
-               stuffp->present = 0;
-               break;
-       }
-
-       stuffp->playcmd = READ1X;
-
-       if (!stuffp->present) {
-               release_region(stuffp->wreg_data, MCDX_IO_SIZE);
-               xwarn("%s=0x%03x,%d: Init failed. No Mitsumi CD-ROM?.\n",
-                     MCDX, stuffp->wreg_data, stuffp->irq);
-               kfree(stuffp);
-               put_disk(disk);
-               return 0;       /* next drive */
-       }
-
-       xtrace(INIT, "init() register blkdev\n");
-       if (register_blkdev(MAJOR_NR, "mcdx")) {
-               release_region(stuffp->wreg_data, MCDX_IO_SIZE);
-               kfree(stuffp);
-               put_disk(disk);
-               return 1;
-       }
-
-       mcdx_queue = blk_init_queue(do_mcdx_request, &mcdx_lock);
-       if (!mcdx_queue) {
-               unregister_blkdev(MAJOR_NR, "mcdx");
-               release_region(stuffp->wreg_data, MCDX_IO_SIZE);
-               kfree(stuffp);
-               put_disk(disk);
-               return 1;
-       }
-
-       xtrace(INIT, "init() subscribe irq and i/o\n");
-       if (request_irq(stuffp->irq, mcdx_intr, IRQF_DISABLED, "mcdx", stuffp)) {
-               release_region(stuffp->wreg_data, MCDX_IO_SIZE);
-               xwarn("%s=0x%03x,%d: Init failed. Can't get irq (%d).\n",
-                     MCDX, stuffp->wreg_data, stuffp->irq, stuffp->irq);
-               stuffp->irq = 0;
-               blk_cleanup_queue(mcdx_queue);
-               kfree(stuffp);
-               put_disk(disk);
-               return 0;
-       }
-
-       xtrace(INIT, "init() get garbage\n");
-       {
-               int i;
-               mcdx_delay(stuffp, HZ / 2);
-               for (i = 100; i; i--)
-                       (void) inb(stuffp->rreg_status);
-       }
-
-
-#ifdef WE_KNOW_WHY
-       /* irq 11 -> channel register */
-       outb(0x50, stuffp->wreg_chn);
-#endif
-
-       xtrace(INIT, "init() set non dma but irq mode\n");
-       mcdx_config(stuffp, 1);
-
-       stuffp->info.ops = &mcdx_dops;
-       stuffp->info.speed = 2;
-       stuffp->info.capacity = 1;
-       stuffp->info.handle = stuffp;
-       sprintf(stuffp->info.name, "mcdx%d", drive);
-       disk->major = MAJOR_NR;
-       disk->first_minor = drive;
-       strcpy(disk->disk_name, stuffp->info.name);
-       disk->fops = &mcdx_bdops;
-       disk->flags = GENHD_FL_CD;
-       stuffp->disk = disk;
-
-       sprintf(msg, " mcdx: Mitsumi CD-ROM installed at 0x%03x, irq %d."
-               " (Firmware version %c %x)\n",
-               stuffp->wreg_data, stuffp->irq, version.code, version.ver);
-       mcdx_stuffp[drive] = stuffp;
-       xtrace(INIT, "init() mcdx_stuffp[%d] = %p\n", drive, stuffp);
-       if (register_cdrom(&stuffp->info) != 0) {
-               printk("Cannot register Mitsumi CD-ROM!\n");
-               free_irq(stuffp->irq, NULL);
-               release_region(stuffp->wreg_data, MCDX_IO_SIZE);
-               kfree(stuffp);
-               put_disk(disk);
-               if (unregister_blkdev(MAJOR_NR, "mcdx") != 0)
-                       xwarn("cleanup() unregister_blkdev() failed\n");
-               blk_cleanup_queue(mcdx_queue);
-               return 2;
-       }
-       disk->private_data = stuffp;
-       disk->queue = mcdx_queue;
-       add_disk(disk);
-       printk(msg);
-       return 0;
-}
-
-static int __init mcdx_init(void)
-{
-       int drive;
-       xwarn("Version 2.14(hs) \n");
-
-       xwarn("$Id: mcdx.c,v 1.21 1997/01/26 07:12:59 davem Exp $\n");
-
-       /* zero the pointer array */
-       for (drive = 0; drive < MCDX_NDRIVES; drive++)
-               mcdx_stuffp[drive] = NULL;
-
-       /* do the initialisation */
-       for (drive = 0; drive < MCDX_NDRIVES; drive++) {
-               switch (mcdx_init_drive(drive)) {
-               case 2:
-                       return -EIO;
-               case 1:
-                       break;
-               }
-       }
-       return 0;
-}
-
-static int mcdx_transfer(struct s_drive_stuff *stuffp,
-             char *p, int sector, int nr_sectors)
-/*     This seems to do the actually transfer.  But it does more.  It
-       keeps track of errors occurred and will (if possible) fall back
-       to single speed on error.
-       Return: -1 on timeout or other error
-                       else status byte (as in stuff->st) */
-{
-       int ans;
-
-       ans = mcdx_xfer(stuffp, p, sector, nr_sectors);
-       return ans;
-#ifdef FALLBACK
-       if (-1 == ans)
-               stuffp->readerrs++;
-       else
-               return ans;
-
-       if (stuffp->readerrs && stuffp->readcmd == READ1X) {
-               xwarn("XXX Already reading 1x -- no chance\n");
-               return -1;
-       }
-
-       xwarn("XXX Fallback to 1x\n");
-
-       stuffp->readcmd = READ1X;
-       return mcdx_transfer(stuffp, p, sector, nr_sectors);
-#endif
-
-}
-
-
-static int mcdx_xfer(struct s_drive_stuff *stuffp,
-                    char *p, int sector, int nr_sectors)
-/*     This does actually the transfer from the drive.
-       Return: -1 on timeout or other error
-                       else status byte (as in stuff->st) */
-{
-       int border;
-       int done = 0;
-       long timeout;
-
-       if (stuffp->audio) {
-               xwarn("Attempt to read from audio CD.\n");
-               return -1;
-       }
-
-       if (!stuffp->readcmd) {
-               xinfo("Can't transfer from missing disk.\n");
-               return -1;
-       }
-
-       while (stuffp->lock) {
-               interruptible_sleep_on(&stuffp->lockq);
-       }
-
-       if (stuffp->valid && (sector >= stuffp->pending)
-           && (sector < stuffp->low_border)) {
-
-               /* All (or at least a part of the sectors requested) seems
-                  * to be already requested, so we don't need to bother the
-                  * drive with new requests ...
-                  * Wait for the drive become idle, but first
-                  * check for possible occurred errors --- the drive
-                  * seems to report them asynchronously */
-
-
-               border = stuffp->high_border < (border =
-                                               sector + nr_sectors)
-                   ? stuffp->high_border : border;
-
-               stuffp->lock = current->pid;
-
-               do {
-
-                       while (stuffp->busy) {
-
-                               timeout =
-                                   interruptible_sleep_on_timeout
-                                   (&stuffp->busyq, 5 * HZ);
-
-                               if (!stuffp->introk) {
-                                       xtrace(XFER,
-                                              "error via interrupt\n");
-                               } else if (!timeout) {
-                                       xtrace(XFER, "timeout\n");
-                               } else if (signal_pending(current)) {
-                                       xtrace(XFER, "signal\n");
-                               } else
-                                       continue;
-
-                               stuffp->lock = 0;
-                               stuffp->busy = 0;
-                               stuffp->valid = 0;
-
-                               wake_up_interruptible(&stuffp->lockq);
-                               xtrace(XFER, "transfer() done (-1)\n");
-                               return -1;
-                       }
-
-                       /* check if we need to set the busy flag (as we
-                        * expect an interrupt */
-                       stuffp->busy = (3 == (stuffp->pending & 3));
-
-                       /* Test if it's the first sector of a block,
-                        * there we have to skip some bytes as we read raw data */
-                       if (stuffp->xa && (0 == (stuffp->pending & 3))) {
-                               const int HEAD =
-                                   CD_FRAMESIZE_RAW - CD_XA_TAIL -
-                                   CD_FRAMESIZE;
-                               insb(stuffp->rreg_data, p, HEAD);
-                       }
-
-                       /* now actually read the data */
-                       insb(stuffp->rreg_data, p, 512);
-
-                       /* test if it's the last sector of a block,
-                        * if so, we have to handle XA special */
-                       if ((3 == (stuffp->pending & 3)) && stuffp->xa) {
-                               char dummy[CD_XA_TAIL];
-                               insb(stuffp->rreg_data, &dummy[0], CD_XA_TAIL);
-                       }
-
-                       if (stuffp->pending == sector) {
-                               p += 512;
-                               done++;
-                               sector++;
-                       }
-               } while (++(stuffp->pending) < border);
-
-               stuffp->lock = 0;
-               wake_up_interruptible(&stuffp->lockq);
-
-       } else {
-
-               /* The requested sector(s) is/are out of the
-                * already requested range, so we have to bother the drive
-                * with a new request. */
-
-               static unsigned char cmd[] = {
-                       0,
-                       0, 0, 0,
-                       0, 0, 0
-               };
-
-               cmd[0] = stuffp->readcmd;
-
-               /* The numbers held in ->pending, ..., should be valid */
-               stuffp->valid = 1;
-               stuffp->pending = sector & ~3;
-
-               /* do some sanity checks */
-               if (stuffp->pending > stuffp->lastsector) {
-                       xwarn
-                           ("transfer() sector %d from nirvana requested.\n",
-                            stuffp->pending);
-                       stuffp->status = MCDX_ST_EOM;
-                       stuffp->valid = 0;
-                       xtrace(XFER, "transfer() done (-1)\n");
-                       return -1;
-               }
-
-               if ((stuffp->low_border = stuffp->pending + DIRECT_SIZE)
-                   > stuffp->lastsector + 1) {
-                       xtrace(XFER, "cut low_border\n");
-                       stuffp->low_border = stuffp->lastsector + 1;
-               }
-               if ((stuffp->high_border = stuffp->pending + REQUEST_SIZE)
-                   > stuffp->lastsector + 1) {
-                       xtrace(XFER, "cut high_border\n");
-                       stuffp->high_border = stuffp->lastsector + 1;
-               }
-
-               {               /* Convert the sector to be requested to MSF format */
-                       struct cdrom_msf0 pending;
-                       log2msf(stuffp->pending / 4, &pending);
-                       cmd[1] = pending.minute;
-                       cmd[2] = pending.second;
-                       cmd[3] = pending.frame;
-               }
-
-               cmd[6] =
-                   (unsigned
-                    char) ((stuffp->high_border - stuffp->pending) / 4);
-               xtrace(XFER, "[%2d]\n", cmd[6]);
-
-               stuffp->busy = 1;
-               /* Now really issue the request command */
-               outsb(stuffp->wreg_data, cmd, sizeof cmd);
-
-       }
-#ifdef AK2
-       if (stuffp->int_err) {
-               stuffp->valid = 0;
-               stuffp->int_err = 0;
-               return -1;
-       }
-#endif                         /* AK2 */
-
-       stuffp->low_border = (stuffp->low_border +=
-                             done) <
-           stuffp->high_border ? stuffp->low_border : stuffp->high_border;
-
-       return done;
-}
-
-
-/*     Access to elements of the mcdx_drive_map members */
-
-static unsigned port(int *ip)
-{
-       return ip[0];
-}
-static int irq(int *ip)
-{
-       return ip[1];
-}
-
-/*     Misc number converters */
-
-static unsigned int bcd2uint(unsigned char c)
-{
-       return (c >> 4) * 10 + (c & 0x0f);
-}
-
-static unsigned int uint2bcd(unsigned int ival)
-{
-       return ((ival / 10) << 4) | (ival % 10);
-}
-
-static void log2msf(unsigned int l, struct cdrom_msf0 *pmsf)
-{
-       l += CD_MSF_OFFSET;
-       pmsf->minute = uint2bcd(l / 4500), l %= 4500;
-       pmsf->second = uint2bcd(l / 75);
-       pmsf->frame = uint2bcd(l % 75);
-}
-
-static unsigned int msf2log(const struct cdrom_msf0 *pmsf)
-{
-       return bcd2uint(pmsf->frame)
-           + bcd2uint(pmsf->second) * 75
-           + bcd2uint(pmsf->minute) * 4500 - CD_MSF_OFFSET;
-}
-
-int mcdx_readtoc(struct s_drive_stuff *stuffp)
-/*  Read the toc entries from the CD,
- *  Return: -1 on failure, else 0 */
-{
-
-       if (stuffp->toc) {
-               xtrace(READTOC, "ioctl() toc already read\n");
-               return 0;
-       }
-
-       xtrace(READTOC, "ioctl() readtoc for %d tracks\n",
-              stuffp->di.n_last - stuffp->di.n_first + 1);
-
-       if (-1 == mcdx_hold(stuffp, 1))
-               return -1;
-
-       xtrace(READTOC, "ioctl() tocmode\n");
-       if (-1 == mcdx_setdrivemode(stuffp, TOC, 1))
-               return -EIO;
-
-       /* all seems to be ok so far ... malloc */
-       {
-               int size;
-               size =
-                   sizeof(struct s_subqcode) * (stuffp->di.n_last -
-                                                stuffp->di.n_first + 2);
-
-               xtrace(MALLOC, "ioctl() malloc %d bytes\n", size);
-               stuffp->toc = kmalloc(size, GFP_KERNEL);
-               if (!stuffp->toc) {
-                       xwarn("Cannot malloc %d bytes for toc\n", size);
-                       mcdx_setdrivemode(stuffp, DATA, 1);
-                       return -EIO;
-               }
-       }
-
-       /* now read actually the index */
-       {
-               int trk;
-               int retries;
-
-               for (trk = 0;
-                    trk < (stuffp->di.n_last - stuffp->di.n_first + 1);
-                    trk++)
-                       stuffp->toc[trk].index = 0;
-
-               for (retries = 300; retries; retries--) {       /* why 300? */
-                       struct s_subqcode q;
-                       unsigned int idx;
-
-                       if (-1 == mcdx_requestsubqcode(stuffp, &q, 1)) {
-                               mcdx_setdrivemode(stuffp, DATA, 1);
-                               return -EIO;
-                       }
-
-                       idx = bcd2uint(q.index);
-
-                       if ((idx > 0)
-                           && (idx <= stuffp->di.n_last)
-                           && (q.tno == 0)
-                           && (stuffp->toc[idx - stuffp->di.n_first].
-                               index == 0)) {
-                               stuffp->toc[idx - stuffp->di.n_first] = q;
-                               xtrace(READTOC,
-                                      "ioctl() toc idx %d (trk %d)\n",
-                                      idx, trk);
-                               trk--;
-                       }
-                       if (trk == 0)
-                               break;
-               }
-               memset(&stuffp->
-                      toc[stuffp->di.n_last - stuffp->di.n_first + 1], 0,
-                      sizeof(stuffp->toc[0]));
-               stuffp->toc[stuffp->di.n_last - stuffp->di.n_first +
-                           1].dt = stuffp->di.msf_leadout;
-       }
-
-       /* unset toc mode */
-       xtrace(READTOC, "ioctl() undo toc mode\n");
-       if (-1 == mcdx_setdrivemode(stuffp, DATA, 2))
-               return -EIO;
-
-#if MCDX_DEBUG && READTOC
-       {
-               int trk;
-               for (trk = 0;
-                    trk < (stuffp->di.n_last - stuffp->di.n_first + 2);
-                    trk++)
-                       xtrace(READTOC, "ioctl() %d readtoc %02x %02x %02x"
-                              "  %02x:%02x.%02x  %02x:%02x.%02x\n",
-                              trk + stuffp->di.n_first,
-                              stuffp->toc[trk].control,
-                              stuffp->toc[trk].tno,
-                              stuffp->toc[trk].index,
-                              stuffp->toc[trk].tt.minute,
-                              stuffp->toc[trk].tt.second,
-                              stuffp->toc[trk].tt.frame,
-                              stuffp->toc[trk].dt.minute,
-                              stuffp->toc[trk].dt.second,
-                              stuffp->toc[trk].dt.frame);
-       }
-#endif
-
-       return 0;
-}
-
-static int
-mcdx_playmsf(struct s_drive_stuff *stuffp, const struct cdrom_msf *msf)
-{
-       unsigned char cmd[7] = {
-               0, 0, 0, 0, 0, 0, 0
-       };
-
-       if (!stuffp->readcmd) {
-               xinfo("Can't play from missing disk.\n");
-               return -1;
-       }
-
-       cmd[0] = stuffp->playcmd;
-
-       cmd[1] = msf->cdmsf_min0;
-       cmd[2] = msf->cdmsf_sec0;
-       cmd[3] = msf->cdmsf_frame0;
-       cmd[4] = msf->cdmsf_min1;
-       cmd[5] = msf->cdmsf_sec1;
-       cmd[6] = msf->cdmsf_frame1;
-
-       xtrace(PLAYMSF, "ioctl(): play %x "
-              "%02x:%02x:%02x -- %02x:%02x:%02x\n",
-              cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5], cmd[6]);
-
-       outsb(stuffp->wreg_data, cmd, sizeof cmd);
-
-       if (-1 == mcdx_getval(stuffp, 3 * HZ, 0, NULL)) {
-               xwarn("playmsf() timeout\n");
-               return -1;
-       }
-
-       stuffp->audiostatus = CDROM_AUDIO_PLAY;
-       return 0;
-}
-
-static int
-mcdx_playtrk(struct s_drive_stuff *stuffp, const struct cdrom_ti *ti)
-{
-       struct s_subqcode *p;
-       struct cdrom_msf msf;
-
-       if (-1 == mcdx_readtoc(stuffp))
-               return -1;
-
-       if (ti)
-               p = &stuffp->toc[ti->cdti_trk0 - stuffp->di.n_first];
-       else
-               p = &stuffp->start;
-
-       msf.cdmsf_min0 = p->dt.minute;
-       msf.cdmsf_sec0 = p->dt.second;
-       msf.cdmsf_frame0 = p->dt.frame;
-
-       if (ti) {
-               p = &stuffp->toc[ti->cdti_trk1 - stuffp->di.n_first + 1];
-               stuffp->stop = *p;
-       } else
-               p = &stuffp->stop;
-
-       msf.cdmsf_min1 = p->dt.minute;
-       msf.cdmsf_sec1 = p->dt.second;
-       msf.cdmsf_frame1 = p->dt.frame;
-
-       return mcdx_playmsf(stuffp, &msf);
-}
-
-
-/* Drive functions ************************************************/
-
-static int mcdx_tray_move(struct cdrom_device_info *cdi, int position)
-{
-       struct s_drive_stuff *stuffp = cdi->handle;
-
-       if (!stuffp->present)
-               return -ENXIO;
-       if (!(stuffp->present & DOOR))
-               return -ENOSYS;
-
-       if (position)           /* 1: eject */
-               return mcdx_talk(stuffp, "\xf6", 1, NULL, 1, 5 * HZ, 3);
-       else                    /* 0: close */
-               return mcdx_talk(stuffp, "\xf8", 1, NULL, 1, 5 * HZ, 3);
-       return 1;
-}
-
-static int mcdx_stop(struct s_drive_stuff *stuffp, int tries)
-{
-       return mcdx_talk(stuffp, "\xf0", 1, NULL, 1, 2 * HZ, tries);
-}
-
-static int mcdx_hold(struct s_drive_stuff *stuffp, int tries)
-{
-       return mcdx_talk(stuffp, "\x70", 1, NULL, 1, 2 * HZ, tries);
-}
-
-static int mcdx_requestsubqcode(struct s_drive_stuff *stuffp,
-                    struct s_subqcode *sub, int tries)
-{
-       char buf[11];
-       int ans;
-
-       if (-1 == (ans = mcdx_talk(stuffp, "\x20", 1, buf, sizeof(buf),
-                                  2 * HZ, tries)))
-               return -1;
-       sub->control = buf[1];
-       sub->tno = buf[2];
-       sub->index = buf[3];
-       sub->tt.minute = buf[4];
-       sub->tt.second = buf[5];
-       sub->tt.frame = buf[6];
-       sub->dt.minute = buf[8];
-       sub->dt.second = buf[9];
-       sub->dt.frame = buf[10];
-
-       return ans;
-}
-
-static int mcdx_requestmultidiskinfo(struct s_drive_stuff *stuffp,
-                         struct s_multi *multi, int tries)
-{
-       char buf[5];
-       int ans;
-
-       if (stuffp->present & MULTI) {
-               ans =
-                   mcdx_talk(stuffp, "\x11", 1, buf, sizeof(buf), 2 * HZ,
-                             tries);
-               multi->multi = buf[1];
-               multi->msf_last.minute = buf[2];
-               multi->msf_last.second = buf[3];
-               multi->msf_last.frame = buf[4];
-               return ans;
-       } else {
-               multi->multi = 0;
-               return 0;
-       }
-}
-
-static int mcdx_requesttocdata(struct s_drive_stuff *stuffp, struct s_diskinfo *info,
-                   int tries)
-{
-       char buf[9];
-       int ans;
-       ans =
-           mcdx_talk(stuffp, "\x10", 1, buf, sizeof(buf), 2 * HZ, tries);
-       if (ans == -1) {
-               info->n_first = 0;
-               info->n_last = 0;
-       } else {
-               info->n_first = bcd2uint(buf[1]);
-               info->n_last = bcd2uint(buf[2]);
-               info->msf_leadout.minute = buf[3];
-               info->msf_leadout.second = buf[4];
-               info->msf_leadout.frame = buf[5];
-               info->msf_first.minute = buf[6];
-               info->msf_first.second = buf[7];
-               info->msf_first.frame = buf[8];
-       }
-       return ans;
-}
-
-static int mcdx_setdrivemode(struct s_drive_stuff *stuffp, enum drivemodes mode,
-                 int tries)
-{
-       char cmd[2];
-       int ans;
-
-       xtrace(HW, "setdrivemode() %d\n", mode);
-
-       if (-1 == (ans = mcdx_talk(stuffp, "\xc2", 1, cmd, sizeof(cmd), 5 * HZ, tries)))
-               return -1;
-
-       switch (mode) {
-       case TOC:
-               cmd[1] |= 0x04;
-               break;
-       case DATA:
-               cmd[1] &= ~0x04;
-               break;
-       case RAW:
-               cmd[1] |= 0x40;
-               break;
-       case COOKED:
-               cmd[1] &= ~0x40;
-               break;
-       default:
-               break;
-       }
-       cmd[0] = 0x50;
-       return mcdx_talk(stuffp, cmd, 2, NULL, 1, 5 * HZ, tries);
-}
-
-static int mcdx_setdatamode(struct s_drive_stuff *stuffp, enum datamodes mode,
-                int tries)
-{
-       unsigned char cmd[2] = { 0xa0 };
-       xtrace(HW, "setdatamode() %d\n", mode);
-       switch (mode) {
-       case MODE0:
-               cmd[1] = 0x00;
-               break;
-       case MODE1:
-               cmd[1] = 0x01;
-               break;
-       case MODE2:
-               cmd[1] = 0x02;
-               break;
-       default:
-               return -EINVAL;
-       }
-       return mcdx_talk(stuffp, cmd, 2, NULL, 1, 5 * HZ, tries);
-}
-
-static int mcdx_config(struct s_drive_stuff *stuffp, int tries)
-{
-       char cmd[4];
-
-       xtrace(HW, "config()\n");
-
-       cmd[0] = 0x90;
-
-       cmd[1] = 0x10;          /* irq enable */
-       cmd[2] = 0x05;          /* pre, err irq enable */
-
-       if (-1 == mcdx_talk(stuffp, cmd, 3, NULL, 1, 1 * HZ, tries))
-               return -1;
-
-       cmd[1] = 0x02;          /* dma select */
-       cmd[2] = 0x00;          /* no dma */
-
-       return mcdx_talk(stuffp, cmd, 3, NULL, 1, 1 * HZ, tries);
-}
-
-static int mcdx_requestversion(struct s_drive_stuff *stuffp, struct s_version *ver,
-                   int tries)
-{
-       char buf[3];
-       int ans;
-
-       if (-1 == (ans = mcdx_talk(stuffp, "\xdc",
-                                  1, buf, sizeof(buf), 2 * HZ, tries)))
-               return ans;
-
-       ver->code = buf[1];
-       ver->ver = buf[2];
-
-       return ans;
-}
-
-static int mcdx_reset(struct s_drive_stuff *stuffp, enum resetmodes mode, int tries)
-{
-       if (mode == HARD) {
-               outb(0, stuffp->wreg_chn);      /* no dma, no irq -> hardware */
-               outb(0, stuffp->wreg_reset);    /* hw reset */
-               return 0;
-       } else
-               return mcdx_talk(stuffp, "\x60", 1, NULL, 1, 5 * HZ, tries);
-}
-
-static int mcdx_lockdoor(struct cdrom_device_info *cdi, int lock)
-{
-       struct s_drive_stuff *stuffp = cdi->handle;
-       char cmd[2] = { 0xfe };
-
-       if (!(stuffp->present & DOOR))
-               return -ENOSYS;
-       if (stuffp->present & DOOR) {
-               cmd[1] = lock ? 0x01 : 0x00;
-               return mcdx_talk(stuffp, cmd, sizeof(cmd), NULL, 1, 5 * HZ, 3);
-       } else
-               return 0;
-}
-
-static int mcdx_getstatus(struct s_drive_stuff *stuffp, int tries)
-{
-       return mcdx_talk(stuffp, "\x40", 1, NULL, 1, 5 * HZ, tries);
-}
-
-static int
-mcdx_getval(struct s_drive_stuff *stuffp, int to, int delay, char *buf)
-{
-       unsigned long timeout = to + jiffies;
-       char c;
-
-       if (!buf)
-               buf = &c;
-
-       while (inb(stuffp->rreg_status) & MCDX_RBIT_STEN) {
-               if (time_after(jiffies, timeout))
-                       return -1;
-               mcdx_delay(stuffp, delay);
-       }
-
-       *buf = (unsigned char) inb(stuffp->rreg_data) & 0xff;
-
-       return 0;
-}
-
-static int mcdx_setattentuator(struct s_drive_stuff *stuffp,
-                   struct cdrom_volctrl *vol, int tries)
-{
-       char cmd[5];
-       cmd[0] = 0xae;
-       cmd[1] = vol->channel0;
-       cmd[2] = 0;
-       cmd[3] = vol->channel1;
-       cmd[4] = 0;
-
-       return mcdx_talk(stuffp, cmd, sizeof(cmd), NULL, 5, 200, tries);
-}
-
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_BLOCKDEV_MAJOR(MITSUMI_X_CDROM_MAJOR);
diff --git a/drivers/cdrom/mcdx.h b/drivers/cdrom/mcdx.h
deleted file mode 100644 (file)
index 83c364a..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Definitions for the Mitsumi CDROM interface
- * Copyright (C) 1995 1996 Heiko Schlittermann <heiko@lotte.sax.de>
- * VERSION: @VERSION@
- * 
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.  If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Thanks to
- *  The Linux Community at all and ...
- *  Martin Harris (he wrote the first Mitsumi Driver)
- *  Eberhard Moenkeberg (he gave me much support and the initial kick)
- *  Bernd Huebner, Ruediger Helsch (Unifix-Software Gmbh, they
- *      improved the original driver)
- *  Jon Tombs, Bjorn Ekwall (module support)
- *  Daniel v. Mosnenck (he sent me the Technical and Programming Reference)
- *  Gerd Knorr (he lent me his PhotoCD)
- *  Nils Faerber and Roger E. Wolff (extensively tested the LU portion)
- *  Andreas Kies (testing the mysterious hang up's)
- *  ... somebody forgotten?
- *  Marcin Dalecki
- *  
- */
-
-/*
- *     The following lines are for user configuration
- *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *     {0|1} -- 1 if you want the driver detect your drive, may crash and
- *     needs a long time to seek.  The higher the address the longer the
- *     seek.
- *
- *  WARNING: AUTOPROBE doesn't work.
- */
-#define MCDX_AUTOPROBE 0
-
-/*
- *     Drive specific settings according to the jumpers on the controller
- *     board(s).
- *     o       MCDX_NDRIVES  :  number of used entries of the following table
- *     o       MCDX_DRIVEMAP :  table of {i/o base, irq} per controller
- *
- *     NOTE: I didn't get a drive at irq 9(2) working.  Not even alone.
- */
-#if MCDX_AUTOPROBE == 0
-       #define MCDX_NDRIVES 1
-       #define MCDX_DRIVEMAP {         \
-                       {0x300, 11},    \
-                       {0x304, 05},    \
-                       {0x000, 00},    \
-                       {0x000, 00},    \
-                       {0x000, 00},    \
-               }
-#else
-       #error Autoprobing is not implemented yet.
-#endif
-
-#ifndef MCDX_QUIET
-#define MCDX_QUIET   1
-#endif
-
-#ifndef MCDX_DEBUG
-#define MCDX_DEBUG   0
-#endif
-
-/* *** make the following line uncommented, if you're sure,
- * *** all configuration is done */
-/* #define I_WAS_HERE */
-
-/*     The name of the device */
-#define MCDX "mcdx"    
-
-/* Flags for DEBUGGING */
-#define INIT           0
-#define MALLOC                 0
-#define IOCTL          0
-#define PLAYTRK     0
-#define SUBCHNL     0
-#define TOCHDR      0
-#define MS          0
-#define PLAYMSF     0
-#define READTOC     0
-#define OPENCLOSE      0
-#define HW                 0
-#define TALK           0
-#define IRQ            0
-#define XFER           0
-#define REQUEST                0
-#define SLEEP          0
-
-/*     The following addresses are taken from the Mitsumi Reference 
- *  and describe the possible i/o range for the controller.
- */
-#define MCDX_IO_BEGIN  ((char*) 0x300) /* first base of i/o addr */
-#define MCDX_IO_END            ((char*) 0x3fc) /* last base of i/o addr */
-
-/*     Per controller 4 bytes i/o are needed. */
-#define MCDX_IO_SIZE           4
-
-/*
- *     Bits
- */
-
-/* The status byte, returned from every command, set if
- * the description is true */
-#define MCDX_RBIT_OPEN       0x80      /* door is open */
-#define MCDX_RBIT_DISKSET    0x40      /* disk set (recognised) */
-#define MCDX_RBIT_CHANGED    0x20      /* disk was changed */
-#define MCDX_RBIT_CHECK      0x10      /* disk rotates, servo is on */
-#define MCDX_RBIT_AUDIOTR    0x08   /* current track is audio */
-#define MCDX_RBIT_RDERR      0x04      /* read error, refer SENSE KEY */
-#define MCDX_RBIT_AUDIOBS    0x02      /* currently playing audio */
-#define MCDX_RBIT_CMDERR     0x01      /* command, param or format error */
-
-/* The I/O Register holding the h/w status of the drive,
- * can be read at i/o base + 1 */
-#define MCDX_RBIT_DOOR       0x10      /* door is open */
-#define MCDX_RBIT_STEN       0x04      /* if 0, i/o base contains drive status */
-#define MCDX_RBIT_DTEN       0x02      /* if 0, i/o base contains data */
-
-/*
- *     The commands.
- */
-
-#define OPCODE 1               /* offset of opcode */
-#define MCDX_CMD_REQUEST_TOC           1, 0x10
-#define MCDX_CMD_REQUEST_STATUS                1, 0x40 
-#define MCDX_CMD_RESET                         1, 0x60
-#define MCDX_CMD_REQUEST_DRIVE_MODE    1, 0xc2
-#define MCDX_CMD_SET_INTERLEAVE                2, 0xc8, 0
-#define MCDX_CMD_DATAMODE_SET          2, 0xa0, 0
-       #define MCDX_DATAMODE1          0x01
-       #define MCDX_DATAMODE2          0x02
-#define MCDX_CMD_LOCK_DOOR             2, 0xfe, 0
-
-#define READ_AHEAD                     4       /* 8 Sectors (4K) */
-
-/*     Useful macros */
-#define e_door(x)              ((x) & MCDX_RBIT_OPEN)
-#define e_check(x)             (~(x) & MCDX_RBIT_CHECK)
-#define e_notset(x)            (~(x) & MCDX_RBIT_DISKSET)
-#define e_changed(x)   ((x) & MCDX_RBIT_CHANGED)
-#define e_audio(x)             ((x) & MCDX_RBIT_AUDIOTR)
-#define e_audiobusy(x) ((x) & MCDX_RBIT_AUDIOBS)
-#define e_cmderr(x)            ((x) & MCDX_RBIT_CMDERR)
-#define e_readerr(x)   ((x) & MCDX_RBIT_RDERR)
-
-/**    no drive specific */
-#define MCDX_CDBLK     2048    /* 2048 cooked data each blk */
-
-#define MCDX_DATA_TIMEOUT      (HZ/10) /* 0.1 second */
-
-/*
- * Access to the msf array
- */
-#define MSF_MIN                0                       /* minute */
-#define MSF_SEC                1                       /* second */
-#define MSF_FRM                2                       /* frame  */
-
-/*
- * Errors
- */
-#define MCDX_E         1                       /* unspec error */
-#define MCDX_ST_EOM 0x0100             /* end of media */
-#define MCDX_ST_DRV 0x00ff             /* mask to query the drive status */
-
-#ifndef I_WAS_HERE
-#ifndef MODULE
-#warning You have not edited mcdx.h
-#warning Perhaps irq and i/o settings are wrong.
-#endif
-#endif
-
-/* ex:set ts=4 sw=4: */
diff --git a/drivers/cdrom/optcd.c b/drivers/cdrom/optcd.c
deleted file mode 100644 (file)
index 3541690..0000000
+++ /dev/null
@@ -1,2105 +0,0 @@
-/*     linux/drivers/cdrom/optcd.c - Optics Storage 8000 AT CDROM driver
-       $Id: optcd.c,v 1.11 1997/01/26 07:13:00 davem Exp $
-
-       Copyright (C) 1995 Leo Spiekman (spiekman@dutette.et.tudelft.nl)
-
-
-       Based on Aztech CD268 CDROM driver by Werner Zimmermann and preworks
-       by Eberhard Moenkeberg (emoenke@gwdg.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, or (at your option)
-       any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-       GNU General Public License for more details.
-
-       You 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.
-*/
-\f
-/*     Revision history
-
-
-       14-5-95         v0.0    Plays sound tracks. No reading of data CDs yet.
-                               Detection of disk change doesn't work.
-       21-5-95         v0.1    First ALPHA version. CD can be mounted. The
-                               device major nr is borrowed from the Aztech
-                               driver. Speed is around 240 kb/s, as measured
-                               with "time dd if=/dev/cdrom of=/dev/null \
-                               bs=2048 count=4096".
-       24-6-95         v0.2    Reworked the #defines for the command codes
-                               and the like, as well as the structure of
-                               the hardware communication protocol, to
-                               reflect the "official" documentation, kindly
-                               supplied by C.K. Tan, Optics Storage Pte. Ltd.
-                               Also tidied up the state machine somewhat.
-       28-6-95         v0.3    Removed the ISP-16 interface code, as this
-                               should go into its own driver. The driver now
-                               has its own major nr.
-                               Disk change detection now seems to work, too.
-                               This version became part of the standard
-                               kernel as of version 1.3.7
-       24-9-95         v0.4    Re-inserted ISP-16 interface code which I
-                               copied from sjcd.c, with a few changes.
-                               Updated README.optcd. Submitted for
-                               inclusion in 1.3.21
-       29-9-95         v0.4a   Fixed bug that prevented compilation as module
-       25-10-95        v0.5    Started multisession code. Implementation
-                               copied from Werner Zimmermann, who copied it
-                               from Heiko Schlittermann's mcdx.
-       17-1-96         v0.6    Multisession works; some cleanup too.
-       18-4-96         v0.7    Increased some timing constants;
-                               thanks to Luke McFarlane. Also tidied up some
-                               printk behaviour. ISP16 initialization
-                               is now handled by a separate driver.
-                               
-       09-11-99                Make kernel-parameter implementation work with 2.3.x 
-                               Removed init_module & cleanup_module in favor of 
-                               module_init & module_exit.
-                               Torben Mathiasen <tmm@image.dk>
-*/
-\f
-/* Includes */
-
-
-#include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-
-#include <asm/io.h>
-#include <linux/blkdev.h>
-
-#include <linux/cdrom.h>
-#include "optcd.h"
-
-#include <asm/uaccess.h>
-
-#define MAJOR_NR OPTICS_CDROM_MAJOR
-#define QUEUE (opt_queue)
-#define CURRENT elv_next_request(opt_queue)
-
-\f
-/* Debug support */
-
-
-/* Don't forget to add new debug flags here. */
-#if DEBUG_DRIVE_IF | DEBUG_VFS | DEBUG_CONV | DEBUG_TOC | \
-    DEBUG_BUFFERS | DEBUG_REQUEST | DEBUG_STATE | DEBUG_MULTIS
-#define DEBUG(x) debug x
-static void debug(int debug_this, const char* fmt, ...)
-{
-       char s[1024];
-       va_list args;
-
-       if (!debug_this)
-               return;
-
-       va_start(args, fmt);
-       vsnprintf(s, sizeof(s), fmt, args);
-       printk(KERN_DEBUG "optcd: %s\n", s);
-       va_end(args);
-}
-#else
-#define DEBUG(x)
-#endif
-
-\f
-/* Drive hardware/firmware characteristics
-   Identifiers in accordance with Optics Storage documentation */
-
-
-#define optcd_port optcd                       /* Needed for the modutils. */
-static short optcd_port = OPTCD_PORTBASE;      /* I/O base of drive. */
-module_param(optcd_port, short, 0);
-/* Drive registers, read */
-#define DATA_PORT      optcd_port      /* Read data/status */
-#define STATUS_PORT    optcd_port+1    /* Indicate data/status availability */
-
-/* Drive registers, write */
-#define COMIN_PORT     optcd_port      /* For passing command/parameter */
-#define RESET_PORT     optcd_port+1    /* Write anything and wait 0.5 sec */
-#define HCON_PORT      optcd_port+2    /* Host Xfer Configuration */
-
-
-/* Command completion/status read from DATA register */
-#define ST_DRVERR              0x80
-#define ST_DOOR_OPEN           0x40
-#define ST_MIXEDMODE_DISK      0x20
-#define ST_MODE_BITS           0x1c
-#define ST_M_STOP              0x00
-#define ST_M_READ              0x04
-#define ST_M_AUDIO             0x04
-#define ST_M_PAUSE             0x08
-#define ST_M_INITIAL           0x0c
-#define ST_M_ERROR             0x10
-#define ST_M_OTHERS            0x14
-#define        ST_MODE2TRACK           0x02
-#define        ST_DSK_CHG              0x01
-#define ST_L_LOCK              0x01
-#define ST_CMD_OK              0x00
-#define ST_OP_OK               0x01
-#define ST_PA_OK               0x02
-#define ST_OP_ERROR            0x05
-#define ST_PA_ERROR            0x06
-
-
-/* Error codes (appear as command completion code from DATA register) */
-/* Player related errors */
-#define ERR_ILLCMD     0x11    /* Illegal command to player module */
-#define ERR_ILLPARM    0x12    /* Illegal parameter to player module */
-#define ERR_SLEDGE     0x13
-#define ERR_FOCUS      0x14
-#define ERR_MOTOR      0x15
-#define ERR_RADIAL     0x16
-#define ERR_PLL                0x17    /* PLL lock error */
-#define ERR_SUB_TIM    0x18    /* Subcode timeout error */
-#define ERR_SUB_NF     0x19    /* Subcode not found error */
-#define ERR_TRAY       0x1a
-#define ERR_TOC                0x1b    /* Table of Contents read error */
-#define ERR_JUMP       0x1c
-/* Data errors */
-#define ERR_MODE       0x21
-#define ERR_FORM       0x22
-#define ERR_HEADADDR   0x23    /* Header Address not found */
-#define ERR_CRC                0x24
-#define ERR_ECC                0x25    /* Uncorrectable ECC error */
-#define ERR_CRC_UNC    0x26    /* CRC error and uncorrectable error */
-#define ERR_ILLBSYNC   0x27    /* Illegal block sync error */
-#define ERR_VDST       0x28    /* VDST not found */
-/* Timeout errors */
-#define ERR_READ_TIM   0x31    /* Read timeout error */
-#define ERR_DEC_STP    0x32    /* Decoder stopped */
-#define ERR_DEC_TIM    0x33    /* Decoder interrupt timeout error */
-/* Function abort codes */
-#define ERR_KEY                0x41    /* Key -Detected abort */
-#define ERR_READ_FINISH        0x42    /* Read Finish */
-/* Second Byte diagnostic codes */
-#define ERR_NOBSYNC    0x01    /* No block sync */
-#define ERR_SHORTB     0x02    /* Short block */
-#define ERR_LONGB      0x03    /* Long block */
-#define ERR_SHORTDSP   0x04    /* Short DSP word */
-#define ERR_LONGDSP    0x05    /* Long DSP word */
-
-
-/* Status availability flags read from STATUS register */
-#define FL_EJECT       0x20
-#define FL_WAIT                0x10    /* active low */
-#define FL_EOP         0x08    /* active low */
-#define FL_STEN                0x04    /* Status available when low */
-#define FL_DTEN                0x02    /* Data available when low */
-#define FL_DRQ         0x01    /* active low */
-#define FL_RESET       0xde    /* These bits are high after a reset */
-#define FL_STDT                (FL_STEN|FL_DTEN)
-
-
-/* Transfer mode, written to HCON register */
-#define HCON_DTS       0x08
-#define HCON_SDRQB     0x04
-#define HCON_LOHI      0x02
-#define HCON_DMA16     0x01
-
-
-/* Drive command set, written to COMIN register */
-/* Quick response commands */
-#define COMDRVST       0x20    /* Drive Status Read */
-#define COMERRST       0x21    /* Error Status Read */
-#define COMIOCTLISTAT  0x22    /* Status Read; reset disk changed bit */
-#define COMINITSINGLE  0x28    /* Initialize Single Speed */
-#define COMINITDOUBLE  0x29    /* Initialize Double Speed */
-#define COMUNLOCK      0x30    /* Unlock */
-#define COMLOCK                0x31    /* Lock */
-#define COMLOCKST      0x32    /* Lock/Unlock Status */
-#define COMVERSION     0x40    /* Get Firmware Revision */
-#define COMVOIDREADMODE        0x50    /* Void Data Read Mode */
-/* Read commands */
-#define COMFETCH       0x60    /* Prefetch Data */
-#define COMREAD                0x61    /* Read */
-#define COMREADRAW     0x62    /* Read Raw Data */
-#define COMREADALL     0x63    /* Read All 2646 Bytes */
-/* Player control commands */
-#define COMLEADIN      0x70    /* Seek To Lead-in */
-#define COMSEEK                0x71    /* Seek */
-#define COMPAUSEON     0x80    /* Pause On */
-#define COMPAUSEOFF    0x81    /* Pause Off */
-#define COMSTOP                0x82    /* Stop */
-#define COMOPEN                0x90    /* Open Tray Door */
-#define COMCLOSE       0x91    /* Close Tray Door */
-#define COMPLAY                0xa0    /* Audio Play */
-#define COMPLAY_TNO    0xa2    /* Audio Play By Track Number */
-#define COMSUBQ                0xb0    /* Read Sub-q Code */
-#define COMLOCATION    0xb1    /* Read Head Position */
-/* Audio control commands */
-#define COMCHCTRL      0xc0    /* Audio Channel Control */
-/* Miscellaneous (test) commands */
-#define COMDRVTEST     0xd0    /* Write Test Bytes */
-#define COMTEST                0xd1    /* Diagnostic Test */
-\f
-/* Low level drive interface. Only here we do actual I/O
-   Waiting for status / data available */
-
-
-/* Busy wait until FLAG goes low. Return 0 on timeout. */
-static inline int flag_low(int flag, unsigned long timeout)
-{
-       int flag_high;
-       unsigned long count = 0;
-
-       while ((flag_high = (inb(STATUS_PORT) & flag)))
-               if (++count >= timeout)
-                       break;
-
-       DEBUG((DEBUG_DRIVE_IF, "flag_low 0x%x count %ld%s",
-               flag, count, flag_high ? " timeout" : ""));
-       return !flag_high;
-}
-
-
-/* Timed waiting for status or data */
-static int sleep_timeout;      /* max # of ticks to sleep */
-static DECLARE_WAIT_QUEUE_HEAD(waitq);
-static void sleep_timer(unsigned long data);
-static DEFINE_TIMER(delay_timer, sleep_timer, 0, 0);
-static DEFINE_SPINLOCK(optcd_lock);
-static struct request_queue *opt_queue;
-
-/* Timer routine: wake up when desired flag goes low,
-   or when timeout expires. */
-static void sleep_timer(unsigned long data)
-{
-       int flags = inb(STATUS_PORT) & FL_STDT;
-
-       if (flags == FL_STDT && --sleep_timeout > 0) {
-               mod_timer(&delay_timer, jiffies + HZ/100); /* multi-statement macro */
-       } else
-               wake_up(&waitq);
-}
-
-
-/* Sleep until FLAG goes low. Return 0 on timeout or wrong flag low. */
-static int sleep_flag_low(int flag, unsigned long timeout)
-{
-       int flag_high;
-
-       DEBUG((DEBUG_DRIVE_IF, "sleep_flag_low"));
-
-       sleep_timeout = timeout;
-       flag_high = inb(STATUS_PORT) & flag;
-       if (flag_high && sleep_timeout > 0) {
-               mod_timer(&delay_timer, jiffies + HZ/100);
-               sleep_on(&waitq);
-               flag_high = inb(STATUS_PORT) & flag;
-       }
-
-       DEBUG((DEBUG_DRIVE_IF, "flag 0x%x count %ld%s",
-               flag, timeout, flag_high ? " timeout" : ""));
-       return !flag_high;
-}
-\f
-/* Low level drive interface. Only here we do actual I/O
-   Sending commands and parameters */
-
-
-/* Errors in the command protocol */
-#define ERR_IF_CMD_TIMEOUT     0x100
-#define ERR_IF_ERR_TIMEOUT     0x101
-#define ERR_IF_RESP_TIMEOUT    0x102
-#define ERR_IF_DATA_TIMEOUT    0x103
-#define ERR_IF_NOSTAT          0x104
-
-
-/* Send command code. Return <0 indicates error */
-static int send_cmd(int cmd)
-{
-       unsigned char ack;
-
-       DEBUG((DEBUG_DRIVE_IF, "sending command 0x%02x\n", cmd));
-
-       outb(HCON_DTS, HCON_PORT);      /* Enable Suspend Data Transfer */
-       outb(cmd, COMIN_PORT);          /* Send command code */
-       if (!flag_low(FL_STEN, BUSY_TIMEOUT))   /* Wait for status */
-               return -ERR_IF_CMD_TIMEOUT;
-       ack = inb(DATA_PORT);           /* read command acknowledge */
-       outb(HCON_SDRQB, HCON_PORT);    /* Disable Suspend Data Transfer */
-       return ack==ST_OP_OK ? 0 : -ack;
-}
-
-
-/* Send command parameters. Return <0 indicates error */
-static int send_params(struct cdrom_msf *params)
-{
-       unsigned char ack;
-
-       DEBUG((DEBUG_DRIVE_IF, "sending parameters"
-               " %02x:%02x:%02x"
-               " %02x:%02x:%02x",
-               params->cdmsf_min0,
-               params->cdmsf_sec0,
-               params->cdmsf_frame0,
-               params->cdmsf_min1,
-               params->cdmsf_sec1,
-               params->cdmsf_frame1));
-
-       outb(params->cdmsf_min0, COMIN_PORT);
-       outb(params->cdmsf_sec0, COMIN_PORT);
-       outb(params->cdmsf_frame0, COMIN_PORT);
-       outb(params->cdmsf_min1, COMIN_PORT);
-       outb(params->cdmsf_sec1, COMIN_PORT);
-       outb(params->cdmsf_frame1, COMIN_PORT);
-       if (!flag_low(FL_STEN, BUSY_TIMEOUT))   /* Wait for status */
-               return -ERR_IF_CMD_TIMEOUT;
-       ack = inb(DATA_PORT);           /* read command acknowledge */
-       return ack==ST_PA_OK ? 0 : -ack;
-}
-
-
-/* Send parameters for SEEK command. Return <0 indicates error */
-static int send_seek_params(struct cdrom_msf *params)
-{
-       unsigned char ack;
-
-       DEBUG((DEBUG_DRIVE_IF, "sending seek parameters"
-               " %02x:%02x:%02x",
-               params->cdmsf_min0,
-               params->cdmsf_sec0,
-               params->cdmsf_frame0));
-
-       outb(params->cdmsf_min0, COMIN_PORT);
-       outb(params->cdmsf_sec0, COMIN_PORT);
-       outb(params->cdmsf_frame0, COMIN_PORT);
-       if (!flag_low(FL_STEN, BUSY_TIMEOUT))   /* Wait for status */
-               return -ERR_IF_CMD_TIMEOUT;
-       ack = inb(DATA_PORT);           /* read command acknowledge */
-       return ack==ST_PA_OK ? 0 : -ack;
-}
-
-
-/* Wait for command execution status. Choice between busy waiting
-   and sleeping. Return value <0 indicates timeout. */
-static inline int get_exec_status(int busy_waiting)
-{
-       unsigned char exec_status;
-
-       if (busy_waiting
-           ? !flag_low(FL_STEN, BUSY_TIMEOUT)
-           : !sleep_flag_low(FL_STEN, SLEEP_TIMEOUT))
-               return -ERR_IF_CMD_TIMEOUT;
-
-       exec_status = inb(DATA_PORT);
-       DEBUG((DEBUG_DRIVE_IF, "returned exec status 0x%02x", exec_status));
-       return exec_status;
-}
-
-
-/* Wait busy for extra byte of data that a command returns.
-   Return value <0 indicates timeout. */
-static inline int get_data(int short_timeout)
-{
-       unsigned char data;
-
-       if (!flag_low(FL_STEN, short_timeout ? FAST_TIMEOUT : BUSY_TIMEOUT))
-               return -ERR_IF_DATA_TIMEOUT;
-
-       data = inb(DATA_PORT);
-       DEBUG((DEBUG_DRIVE_IF, "returned data 0x%02x", data));
-       return data;
-}
-
-
-/* Returns 0 if failed */
-static int reset_drive(void)
-{
-       unsigned long count = 0;
-       int flags;
-
-       DEBUG((DEBUG_DRIVE_IF, "reset drive"));
-
-       outb(0, RESET_PORT);
-       while (++count < RESET_WAIT)
-               inb(DATA_PORT);
-
-       count = 0;
-       while ((flags = (inb(STATUS_PORT) & FL_RESET)) != FL_RESET)
-               if (++count >= BUSY_TIMEOUT)
-                       break;
-
-       DEBUG((DEBUG_DRIVE_IF, "reset %s",
-               flags == FL_RESET ? "succeeded" : "failed"));
-
-       if (flags != FL_RESET)
-               return 0;               /* Reset failed */
-       outb(HCON_SDRQB, HCON_PORT);    /* Disable Suspend Data Transfer */
-       return 1;                       /* Reset succeeded */
-}
-
-
-/* Facilities for asynchronous operation */
-
-/* Read status/data availability flags FL_STEN and FL_DTEN */
-static inline int stdt_flags(void)
-{
-       return inb(STATUS_PORT) & FL_STDT;
-}
-
-
-/* Fetch status that has previously been waited for. <0 means not available */
-static inline int fetch_status(void)
-{
-       unsigned char status;
-
-       if (inb(STATUS_PORT) & FL_STEN)
-               return -ERR_IF_NOSTAT;
-
-       status = inb(DATA_PORT);
-       DEBUG((DEBUG_DRIVE_IF, "fetched exec status 0x%02x", status));
-       return status;
-}
-
-
-/* Fetch data that has previously been waited for. */
-static inline void fetch_data(char *buf, int n)
-{
-       insb(DATA_PORT, buf, n);
-       DEBUG((DEBUG_DRIVE_IF, "fetched 0x%x bytes", n));
-}
-
-
-/* Flush status and data fifos */
-static inline void flush_data(void)
-{
-       while ((inb(STATUS_PORT) & FL_STDT) != FL_STDT)
-               inb(DATA_PORT);
-       DEBUG((DEBUG_DRIVE_IF, "flushed fifos"));
-}
-\f
-/* Command protocol */
-
-
-/* Send a simple command and wait for response. Command codes < COMFETCH
-   are quick response commands */
-static inline int exec_cmd(int cmd)
-{
-       int ack = send_cmd(cmd);
-       if (ack < 0)
-               return ack;
-       return get_exec_status(cmd < COMFETCH);
-}
-
-
-/* Send a command with parameters. Don't wait for the response,
- * which consists of data blocks read from the CD. */
-static inline int exec_read_cmd(int cmd, struct cdrom_msf *params)
-{
-       int ack = send_cmd(cmd);
-       if (ack < 0)
-               return ack;
-       return send_params(params);
-}
-
-
-/* Send a seek command with parameters and wait for response */
-static inline int exec_seek_cmd(int cmd, struct cdrom_msf *params)
-{
-       int ack = send_cmd(cmd);
-       if (ack < 0)
-               return ack;
-       ack = send_seek_params(params);
-       if (ack < 0)
-               return ack;
-       return 0;
-}
-
-
-/* Send a command with parameters and wait for response */
-static inline int exec_long_cmd(int cmd, struct cdrom_msf *params)
-{
-       int ack = exec_read_cmd(cmd, params);
-       if (ack < 0)
-               return ack;
-       return get_exec_status(0);
-}
-\f
-/* Address conversion routines */
-
-
-/* Binary to BCD (2 digits) */
-static inline void single_bin2bcd(u_char *p)
-{
-       DEBUG((DEBUG_CONV, "bin2bcd %02d", *p));
-       *p = (*p % 10) | ((*p / 10) << 4);
-}
-
-
-/* Convert entire msf struct */
-static void bin2bcd(struct cdrom_msf *msf)
-{
-       single_bin2bcd(&msf->cdmsf_min0);
-       single_bin2bcd(&msf->cdmsf_sec0);
-       single_bin2bcd(&msf->cdmsf_frame0);
-       single_bin2bcd(&msf->cdmsf_min1);
-       single_bin2bcd(&msf->cdmsf_sec1);
-       single_bin2bcd(&msf->cdmsf_frame1);
-}
-
-
-/* Linear block address to minute, second, frame form */
-#define CD_FPM (CD_SECS * CD_FRAMES)   /* frames per minute */
-
-static void lba2msf(int lba, struct cdrom_msf *msf)
-{
-       DEBUG((DEBUG_CONV, "lba2msf %d", lba));
-       lba += CD_MSF_OFFSET;
-       msf->cdmsf_min0 = lba / CD_FPM; lba %= CD_FPM;
-       msf->cdmsf_sec0 = lba / CD_FRAMES;
-       msf->cdmsf_frame0 = lba % CD_FRAMES;
-       msf->cdmsf_min1 = 0;
-       msf->cdmsf_sec1 = 0;
-       msf->cdmsf_frame1 = 0;
-       bin2bcd(msf);
-}
-
-
-/* Two BCD digits to binary */
-static inline u_char bcd2bin(u_char bcd)
-{
-       DEBUG((DEBUG_CONV, "bcd2bin %x%02x", bcd));
-       return (bcd >> 4) * 10 + (bcd & 0x0f);
-}
-
-
-static void msf2lba(union cdrom_addr *addr)
-{
-       addr->lba = addr->msf.minute * CD_FPM
-                   + addr->msf.second * CD_FRAMES
-                   + addr->msf.frame - CD_MSF_OFFSET;
-}
-
-
-/* Minute, second, frame address BCD to binary or to linear address,
-   depending on MODE */
-static void msf_bcd2bin(union cdrom_addr *addr)
-{
-       addr->msf.minute = bcd2bin(addr->msf.minute);
-       addr->msf.second = bcd2bin(addr->msf.second);
-       addr->msf.frame = bcd2bin(addr->msf.frame);
-}
-\f
-/* High level drive commands */
-
-
-static int audio_status = CDROM_AUDIO_NO_STATUS;
-static char toc_uptodate = 0;
-static char disk_changed = 1;
-
-/* Get drive status, flagging completion of audio play and disk changes. */
-static int drive_status(void)
-{
-       int status;
-
-       status = exec_cmd(COMIOCTLISTAT);
-       DEBUG((DEBUG_DRIVE_IF, "IOCTLISTAT: %03x", status));
-       if (status < 0)
-               return status;
-       if (status == 0xff)     /* No status available */
-               return -ERR_IF_NOSTAT;
-
-       if (((status & ST_MODE_BITS) != ST_M_AUDIO) &&
-               (audio_status == CDROM_AUDIO_PLAY)) {
-               audio_status = CDROM_AUDIO_COMPLETED;
-       }
-
-       if (status & ST_DSK_CHG) {
-               toc_uptodate = 0;
-               disk_changed = 1;
-               audio_status = CDROM_AUDIO_NO_STATUS;
-       }
-
-       return status;
-}
-
-
-/* Read the current Q-channel info. Also used for reading the
-   table of contents. qp->cdsc_format must be set on entry to
-   indicate the desired address format */
-static int get_q_channel(struct cdrom_subchnl *qp)
-{
-       int status, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10;
-
-       status = drive_status();
-       if (status < 0)
-               return status;
-       qp->cdsc_audiostatus = audio_status;
-
-       status = exec_cmd(COMSUBQ);
-       if (status < 0)
-               return status;
-
-       d1 = get_data(0);
-       if (d1 < 0)
-               return d1;
-       qp->cdsc_adr = d1;
-       qp->cdsc_ctrl = d1 >> 4;
-
-       d2 = get_data(0);
-       if (d2 < 0)
-               return d2;
-       qp->cdsc_trk = bcd2bin(d2);
-
-       d3 = get_data(0);
-       if (d3 < 0)
-               return d3;
-       qp->cdsc_ind = bcd2bin(d3);
-
-       d4 = get_data(0);
-       if (d4 < 0)
-               return d4;
-       qp->cdsc_reladdr.msf.minute = d4;
-
-       d5 = get_data(0);
-       if (d5 < 0)
-               return d5;
-       qp->cdsc_reladdr.msf.second = d5;
-
-       d6 = get_data(0);
-       if (d6 < 0)
-               return d6;
-       qp->cdsc_reladdr.msf.frame = d6;
-
-       d7 = get_data(0);
-       if (d7 < 0)
-               return d7;
-       /* byte not used */
-
-       d8 = get_data(0);
-       if (d8 < 0)
-               return d8;
-       qp->cdsc_absaddr.msf.minute = d8;
-
-       d9 = get_data(0);
-       if (d9 < 0)
-               return d9;
-       qp->cdsc_absaddr.msf.second = d9;
-
-       d10 = get_data(0);
-       if (d10 < 0)
-               return d10;
-       qp->cdsc_absaddr.msf.frame = d10;
-
-       DEBUG((DEBUG_TOC, "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
-               d1, d2, d3, d4, d5, d6, d7, d8, d9, d10));
-
-       msf_bcd2bin(&qp->cdsc_absaddr);
-       msf_bcd2bin(&qp->cdsc_reladdr);
-       if (qp->cdsc_format == CDROM_LBA) {
-               msf2lba(&qp->cdsc_absaddr);
-               msf2lba(&qp->cdsc_reladdr);
-       }
-
-       return 0;
-}
-\f
-/* Table of contents handling */
-
-
-/* Errors in table of contents */
-#define ERR_TOC_MISSINGINFO    0x120
-#define ERR_TOC_MISSINGENTRY   0x121
-
-
-struct cdrom_disk_info {
-       unsigned char           first;
-       unsigned char           last;
-       struct cdrom_msf0       disk_length;
-       struct cdrom_msf0       first_track;
-       /* Multisession info: */
-       unsigned char           next;
-       struct cdrom_msf0       next_session;
-       struct cdrom_msf0       last_session;
-       unsigned char           multi;
-       unsigned char           xa;
-       unsigned char           audio;
-};
-static struct cdrom_disk_info disk_info;
-
-#define MAX_TRACKS             111
-static struct cdrom_subchnl toc[MAX_TRACKS];
-
-#define QINFO_FIRSTTRACK       100 /* bcd2bin(0xa0) */
-#define QINFO_LASTTRACK                101 /* bcd2bin(0xa1) */
-#define QINFO_DISKLENGTH       102 /* bcd2bin(0xa2) */
-#define QINFO_NEXTSESSION      110 /* bcd2bin(0xb0) */
-
-#define I_FIRSTTRACK   0x01
-#define I_LASTTRACK    0x02
-#define I_DISKLENGTH   0x04
-#define I_NEXTSESSION  0x08
-#define I_ALL  (I_FIRSTTRACK | I_LASTTRACK | I_DISKLENGTH)
-
-
-#if DEBUG_TOC
-static void toc_debug_info(int i)
-{
-       printk(KERN_DEBUG "#%3d ctl %1x, adr %1x, track %2d index %3d"
-               "  %2d:%02d.%02d %2d:%02d.%02d\n",
-               i, toc[i].cdsc_ctrl, toc[i].cdsc_adr,
-               toc[i].cdsc_trk, toc[i].cdsc_ind,
-               toc[i].cdsc_reladdr.msf.minute,
-               toc[i].cdsc_reladdr.msf.second,
-               toc[i].cdsc_reladdr.msf.frame,
-               toc[i].cdsc_absaddr.msf.minute,
-               toc[i].cdsc_absaddr.msf.second,
-               toc[i].cdsc_absaddr.msf.frame);
-}
-#endif
-
-
-static int read_toc(void)
-{
-       int status, limit, count;
-       unsigned char got_info = 0;
-       struct cdrom_subchnl q_info;
-#if DEBUG_TOC
-       int i;
-#endif
-
-       DEBUG((DEBUG_TOC, "starting read_toc"));
-
-       count = 0;
-       for (limit = 60; limit > 0; limit--) {
-               int index;
-
-               q_info.cdsc_format = CDROM_MSF;
-               status = get_q_channel(&q_info);
-               if (status < 0)
-                       return status;
-
-               index = q_info.cdsc_ind;
-               if (index > 0 && index < MAX_TRACKS
-                   && q_info.cdsc_trk == 0 && toc[index].cdsc_ind == 0) {
-                       toc[index] = q_info;
-                       DEBUG((DEBUG_TOC, "got %d", index));
-                       if (index < 100)
-                               count++;
-
-                       switch (q_info.cdsc_ind) {
-                       case QINFO_FIRSTTRACK:
-                               got_info |= I_FIRSTTRACK;
-                               break;
-                       case QINFO_LASTTRACK:
-                               got_info |= I_LASTTRACK;
-                               break;
-                       case QINFO_DISKLENGTH:
-                               got_info |= I_DISKLENGTH;
-                               break;
-                       case QINFO_NEXTSESSION:
-                               got_info |= I_NEXTSESSION;
-                               break;
-                       }
-               }
-
-               if ((got_info & I_ALL) == I_ALL
-                   && toc[QINFO_FIRSTTRACK].cdsc_absaddr.msf.minute + count
-                      >= toc[QINFO_LASTTRACK].cdsc_absaddr.msf.minute + 1)
-                       break;
-       }
-
-       /* Construct disk_info from TOC */
-       if (disk_info.first == 0) {
-               disk_info.first = toc[QINFO_FIRSTTRACK].cdsc_absaddr.msf.minute;
-               disk_info.first_track.minute =
-                       toc[disk_info.first].cdsc_absaddr.msf.minute;
-               disk_info.first_track.second =
-                       toc[disk_info.first].cdsc_absaddr.msf.second;
-               disk_info.first_track.frame =
-                       toc[disk_info.first].cdsc_absaddr.msf.frame;
-       }
-       disk_info.last = toc[QINFO_LASTTRACK].cdsc_absaddr.msf.minute;
-       disk_info.disk_length.minute =
-                       toc[QINFO_DISKLENGTH].cdsc_absaddr.msf.minute;
-       disk_info.disk_length.second =
-                       toc[QINFO_DISKLENGTH].cdsc_absaddr.msf.second-2;
-       disk_info.disk_length.frame =
-                       toc[QINFO_DISKLENGTH].cdsc_absaddr.msf.frame;
-       disk_info.next_session.minute =
-                       toc[QINFO_NEXTSESSION].cdsc_reladdr.msf.minute;
-       disk_info.next_session.second =
-                       toc[QINFO_NEXTSESSION].cdsc_reladdr.msf.second;
-       disk_info.next_session.frame =
-                       toc[QINFO_NEXTSESSION].cdsc_reladdr.msf.frame;
-       disk_info.next = toc[QINFO_FIRSTTRACK].cdsc_absaddr.msf.minute;
-       disk_info.last_session.minute =
-                       toc[disk_info.next].cdsc_absaddr.msf.minute;
-       disk_info.last_session.second =
-                       toc[disk_info.next].cdsc_absaddr.msf.second;
-       disk_info.last_session.frame =
-                       toc[disk_info.next].cdsc_absaddr.msf.frame;
-       toc[disk_info.last + 1].cdsc_absaddr.msf.minute =
-                       disk_info.disk_length.minute;
-       toc[disk_info.last + 1].cdsc_absaddr.msf.second =
-                       disk_info.disk_length.second;
-       toc[disk_info.last + 1].cdsc_absaddr.msf.frame =
-                       disk_info.disk_length.frame;
-#if DEBUG_TOC
-       for (i = 1; i <= disk_info.last + 1; i++)
-               toc_debug_info(i);
-       toc_debug_info(QINFO_FIRSTTRACK);
-       toc_debug_info(QINFO_LASTTRACK);
-       toc_debug_info(QINFO_DISKLENGTH);
-       toc_debug_info(QINFO_NEXTSESSION);
-#endif
-
-       DEBUG((DEBUG_TOC, "exiting read_toc, got_info %x, count %d",
-               got_info, count));
-       if ((got_info & I_ALL) != I_ALL
-           || toc[QINFO_FIRSTTRACK].cdsc_absaddr.msf.minute + count
-              < toc[QINFO_LASTTRACK].cdsc_absaddr.msf.minute + 1)
-               return -ERR_TOC_MISSINGINFO;
-       return 0;
-}
-
-
-#ifdef MULTISESSION
-static int get_multi_disk_info(void)
-{
-       int sessions, status;
-       struct cdrom_msf multi_index;
-
-
-       for (sessions = 2; sessions < 10 /* %%for now */; sessions++) {
-               int count;
-
-               for (count = 100; count < MAX_TRACKS; count++) 
-                       toc[count].cdsc_ind = 0;
-
-               multi_index.cdmsf_min0 = disk_info.next_session.minute;
-               multi_index.cdmsf_sec0 = disk_info.next_session.second;
-               multi_index.cdmsf_frame0 = disk_info.next_session.frame;
-               if (multi_index.cdmsf_sec0 >= 20)
-                       multi_index.cdmsf_sec0 -= 20;
-               else {
-                       multi_index.cdmsf_sec0 += 40;
-                       multi_index.cdmsf_min0--;
-               }
-               DEBUG((DEBUG_MULTIS, "Try %d: %2d:%02d.%02d", sessions,
-                       multi_index.cdmsf_min0,
-                       multi_index.cdmsf_sec0,
-                       multi_index.cdmsf_frame0));
-               bin2bcd(&multi_index);
-               multi_index.cdmsf_min1 = 0;
-               multi_index.cdmsf_sec1 = 0;
-               multi_index.cdmsf_frame1 = 1;
-
-               status = exec_read_cmd(COMREAD, &multi_index);
-               if (status < 0) {
-                       DEBUG((DEBUG_TOC, "exec_read_cmd COMREAD: %02x",
-                               -status));
-                       break;
-               }
-               status = sleep_flag_low(FL_DTEN, MULTI_SEEK_TIMEOUT) ?
-                               0 : -ERR_TOC_MISSINGINFO;
-               flush_data();
-               if (status < 0) {
-                       DEBUG((DEBUG_TOC, "sleep_flag_low: %02x", -status));
-                       break;
-               }
-
-               status = read_toc();
-               if (status < 0) {
-                       DEBUG((DEBUG_TOC, "read_toc: %02x", -status));
-                       break;
-               }
-
-               disk_info.multi = 1;
-       }
-
-       exec_cmd(COMSTOP);
-
-       if (status < 0)
-               return -EIO;
-       return 0;
-}
-#endif /* MULTISESSION */
-
-
-static int update_toc(void)
-{
-       int status, count;
-
-       if (toc_uptodate)
-               return 0;
-
-       DEBUG((DEBUG_TOC, "starting update_toc"));
-
-       disk_info.first = 0;
-       for (count = 0; count < MAX_TRACKS; count++) 
-               toc[count].cdsc_ind = 0;
-
-       status = exec_cmd(COMLEADIN);
-       if (status < 0)
-               return -EIO;
-
-       status = read_toc();
-       if (status < 0) {
-               DEBUG((DEBUG_TOC, "read_toc: %02x", -status));
-               return -EIO;
-       }
-
-        /* Audio disk detection. Look at first track. */
-       disk_info.audio =
-               (toc[disk_info.first].cdsc_ctrl & CDROM_DATA_TRACK) ? 0 : 1;
-
-       /* XA detection */
-       disk_info.xa = drive_status() & ST_MODE2TRACK;
-
-       /* Multisession detection: if we want this, define MULTISESSION */
-       disk_info.multi = 0;
-#ifdef MULTISESSION
-       if (disk_info.xa)
-               get_multi_disk_info();  /* Here disk_info.multi is set */
-#endif /* MULTISESSION */
-       if (disk_info.multi)
-               printk(KERN_WARNING "optcd: Multisession support experimental, "
-                       "see Documentation/cdrom/optcd\n");
-
-       DEBUG((DEBUG_TOC, "exiting update_toc"));
-
-       toc_uptodate = 1;
-       return 0;
-}
-\f
-/* Request handling */
-
-static int current_valid(void)
-{
-        return CURRENT &&
-               CURRENT->cmd == READ &&
-               CURRENT->sector != -1;
-}
-
-/* Buffers for block size conversion. */
-#define NOBUF          -1
-
-static char buf[CD_FRAMESIZE * N_BUFS];
-static volatile int buf_bn[N_BUFS], next_bn;
-static volatile int buf_in = 0, buf_out = NOBUF;
-
-static inline void opt_invalidate_buffers(void)
-{
-       int i;
-
-       DEBUG((DEBUG_BUFFERS, "executing opt_invalidate_buffers"));
-
-       for (i = 0; i < N_BUFS; i++)
-               buf_bn[i] = NOBUF;
-       buf_out = NOBUF;
-}
-
-
-/* Take care of the different block sizes between cdrom and Linux.
-   When Linux gets variable block sizes this will probably go away. */
-static void transfer(void)
-{
-#if DEBUG_BUFFERS | DEBUG_REQUEST
-       printk(KERN_DEBUG "optcd: executing transfer\n");
-#endif
-
-       if (!current_valid())
-               return;
-       while (CURRENT -> nr_sectors) {
-               int bn = CURRENT -> sector / 4;
-               int i, offs, nr_sectors;
-               for (i = 0; i < N_BUFS && buf_bn[i] != bn; ++i);
-
-               DEBUG((DEBUG_REQUEST, "found %d", i));
-
-               if (i >= N_BUFS) {
-                       buf_out = NOBUF;
-                       break;
-               }
-
-               offs = (i * 4 + (CURRENT -> sector & 3)) * 512;
-               nr_sectors = 4 - (CURRENT -> sector & 3);
-
-               if (buf_out != i) {
-                       buf_out = i;
-                       if (buf_bn[i] != bn) {
-                               buf_out = NOBUF;
-                               continue;
-                       }
-               }
-
-               if (nr_sectors > CURRENT -> nr_sectors)
-                       nr_sectors = CURRENT -> nr_sectors;
-               memcpy(CURRENT -> buffer, buf + offs, nr_sectors * 512);
-               CURRENT -> nr_sectors -= nr_sectors;
-               CURRENT -> sector += nr_sectors;
-               CURRENT -> buffer += nr_sectors * 512;
-       }
-}
-
-
-/* State machine for reading disk blocks */
-
-enum state_e {
-       S_IDLE,         /* 0 */
-       S_START,        /* 1 */
-       S_READ,         /* 2 */
-       S_DATA,         /* 3 */
-       S_STOP,         /* 4 */
-       S_STOPPING      /* 5 */
-};
-
-static volatile enum state_e state = S_IDLE;
-#if DEBUG_STATE
-static volatile enum state_e state_old = S_STOP;
-static volatile int flags_old = 0;
-static volatile long state_n = 0;
-#endif
-
-
-/* Used as mutex to keep do_optcd_request (and other processes calling
-   ioctl) out while some process is inside a VFS call.
-   Reverse is accomplished by checking if state = S_IDLE upon entry
-   of opt_ioctl and opt_media_change. */
-static int in_vfs = 0;
-
-
-static volatile int transfer_is_active = 0;
-static volatile int error = 0; /* %% do something with this?? */
-static int tries;              /* ibid?? */
-static int timeout = 0;
-
-static void poll(unsigned long data);
-static struct timer_list req_timer = {.function = poll};
-
-
-static void poll(unsigned long data)
-{
-       static volatile int read_count = 1;
-       int flags;
-       int loop_again = 1;
-       int status = 0;
-       int skip = 0;
-
-       if (error) {
-               printk(KERN_ERR "optcd: I/O error 0x%02x\n", error);
-               opt_invalidate_buffers();
-               if (!tries--) {
-                       printk(KERN_ERR "optcd: read block %d failed;"
-                               " Giving up\n", next_bn);
-                       if (transfer_is_active)
-                               loop_again = 0;
-                       if (current_valid())
-                               end_request(CURRENT, 0);
-                       tries = 5;
-               }
-               error = 0;
-               state = S_STOP;
-       }
-
-       while (loop_again)
-       {
-               loop_again = 0; /* each case must flip this back to 1 if we want
-                                to come back up here */
-
-#if DEBUG_STATE
-               if (state == state_old)
-                       state_n++;
-               else {
-                       state_old = state;
-                       if (++state_n > 1)
-                               printk(KERN_DEBUG "optcd: %ld times "
-                                       "in previous state\n", state_n);
-                       printk(KERN_DEBUG "optcd: state %d\n", state);
-                       state_n = 0;
-               }
-#endif
-
-               switch (state) {
-               case S_IDLE:
-                       return;
-               case S_START:
-                       if (in_vfs)
-                               break;
-                       if (send_cmd(COMDRVST)) {
-                               state = S_IDLE;
-                               while (current_valid())
-                                       end_request(CURRENT, 0);
-                               return;
-                       }
-                       state = S_READ;
-                       timeout = READ_TIMEOUT;
-                       break;
-               case S_READ: {
-                       struct cdrom_msf msf;
-                       if (!skip) {
-                               status = fetch_status();
-                               if (status < 0)
-                                       break;
-                               if (status & ST_DSK_CHG) {
-                                       toc_uptodate = 0;
-                                       opt_invalidate_buffers();
-                               }
-                       }
-                       skip = 0;
-                       if ((status & ST_DOOR_OPEN) || (status & ST_DRVERR)) {
-                               toc_uptodate = 0;
-                               opt_invalidate_buffers();
-                               printk(KERN_WARNING "optcd: %s\n",
-                                       (status & ST_DOOR_OPEN)
-                                       ? "door open"
-                                       : "disk removed");
-                               state = S_IDLE;
-                               while (current_valid())
-                                       end_request(CURRENT, 0);
-                               return;
-                       }
-                       if (!current_valid()) {
-                               state = S_STOP;
-                               loop_again = 1;
-                               break;
-                       }
-                       next_bn = CURRENT -> sector / 4;
-                       lba2msf(next_bn, &msf);
-                       read_count = N_BUFS;
-                       msf.cdmsf_frame1 = read_count; /* Not BCD! */
-
-                       DEBUG((DEBUG_REQUEST, "reading %x:%x.%x %x:%x.%x",
-                               msf.cdmsf_min0,
-                               msf.cdmsf_sec0,
-                               msf.cdmsf_frame0,
-                               msf.cdmsf_min1,
-                               msf.cdmsf_sec1,
-                               msf.cdmsf_frame1));
-                       DEBUG((DEBUG_REQUEST, "next_bn:%d buf_in:%d"
-                               " buf_out:%d buf_bn:%d",
-                               next_bn,
-                               buf_in,
-                               buf_out,
-                               buf_bn[buf_in]));
-
-                       exec_read_cmd(COMREAD, &msf);
-                       state = S_DATA;
-                       timeout = READ_TIMEOUT;
-                       break;
-               }
-               case S_DATA:
-                       flags = stdt_flags() & (FL_STEN|FL_DTEN);
-
-#if DEBUG_STATE
-                       if (flags != flags_old) {
-                               flags_old = flags;
-                               printk(KERN_DEBUG "optcd: flags:%x\n", flags);
-                       }
-                       if (flags == FL_STEN)
-                               printk(KERN_DEBUG "timeout cnt: %d\n", timeout);
-#endif
-
-                       switch (flags) {
-                       case FL_DTEN:           /* only STEN low */
-                               if (!tries--) {
-                                       printk(KERN_ERR
-                                               "optcd: read block %d failed; "
-                                               "Giving up\n", next_bn);
-                                       if (transfer_is_active) {
-                                               tries = 0;
-                                               break;
-                                       }
-                                       if (current_valid())
-                                               end_request(CURRENT, 0);
-                                       tries = 5;
-                               }
-                               state = S_START;
-                               timeout = READ_TIMEOUT;
-                               loop_again = 1;
-                       case (FL_STEN|FL_DTEN):  /* both high */
-                               break;
-                       default:        /* DTEN low */
-                               tries = 5;
-                               if (!current_valid() && buf_in == buf_out) {
-                                       state = S_STOP;
-                                       loop_again = 1;
-                                       break;
-                               }
-                               if (read_count<=0)
-                                       printk(KERN_WARNING
-                                               "optcd: warning - try to read"
-                                               " 0 frames\n");
-                               while (read_count) {
-                                       buf_bn[buf_in] = NOBUF;
-                                       if (!flag_low(FL_DTEN, BUSY_TIMEOUT)) {
-                                       /* should be no waiting here!?? */
-                                               printk(KERN_ERR
-                                                  "read_count:%d "
-                                                  "CURRENT->nr_sectors:%ld "
-                                                  "buf_in:%d\n",
-                                                       read_count,
-                                                       CURRENT->nr_sectors,
-                                                       buf_in);
-                                               printk(KERN_ERR
-                                                       "transfer active: %x\n",
-                                                       transfer_is_active);
-                                               read_count = 0;
-                                               state = S_STOP;
-                                               loop_again = 1;
-                                               end_request(CURRENT, 0);
-                                               break;
-                                       }
-                                       fetch_data(buf+
-                                           CD_FRAMESIZE*buf_in,
-                                           CD_FRAMESIZE);
-                                       read_count--;
-
-                                       DEBUG((DEBUG_REQUEST,
-                                               "S_DATA; ---I've read data- "
-                                               "read_count: %d",
-                                               read_count));
-                                       DEBUG((DEBUG_REQUEST,
-                                               "next_bn:%d  buf_in:%d "
-                                               "buf_out:%d  buf_bn:%d",
-                                               next_bn,
-                                               buf_in,
-                                               buf_out,
-                                               buf_bn[buf_in]));
-
-                                       buf_bn[buf_in] = next_bn++;
-                                       if (buf_out == NOBUF)
-                                               buf_out = buf_in;
-                                       buf_in = buf_in + 1 ==
-                                               N_BUFS ? 0 : buf_in + 1;
-                               }
-                               if (!transfer_is_active) {
-                                       while (current_valid()) {
-                                               transfer();
-                                               if (CURRENT -> nr_sectors == 0)
-                                                       end_request(CURRENT, 1);
-                                               else
-                                                       break;
-                                       }
-                               }
-
-                               if (current_valid()
-                                   && (CURRENT -> sector / 4 < next_bn ||
-                                   CURRENT -> sector / 4 >
-                                    next_bn + N_BUFS)) {
-                                       state = S_STOP;
-                                       loop_again = 1;
-                                       break;
-                               }
-                               timeout = READ_TIMEOUT;
-                               if (read_count == 0) {
-                                       state = S_STOP;
-                                       loop_again = 1;
-                                       break;
-                               }
-                       }
-                       break;
-               case S_STOP:
-                       if (read_count != 0)
-                               printk(KERN_ERR
-                                       "optcd: discard data=%x frames\n",
-                                       read_count);
-                       flush_data();
-                       if (send_cmd(COMDRVST)) {
-                               state = S_IDLE;
-                               while (current_valid())
-                                       end_request(CURRENT, 0);
-                               return;
-                       }
-                       state = S_STOPPING;
-                       timeout = STOP_TIMEOUT;
-                       break;
-               case S_STOPPING:
-                       status = fetch_status();
-                       if (status < 0 && timeout)
-                                       break;
-                       if ((status >= 0) && (status & ST_DSK_CHG)) {
-                               toc_uptodate = 0;
-                               opt_invalidate_buffers();
-                       }
-                       if (current_valid()) {
-                               if (status >= 0) {
-                                       state = S_READ;
-                                       loop_again = 1;
-                                       skip = 1;
-                                       break;
-                               } else {
-                                       state = S_START;
-                                       timeout = 1;
-                               }
-                       } else {
-                               state = S_IDLE;
-                               return;
-                       }
-                       break;
-               default:
-                       printk(KERN_ERR "optcd: invalid state %d\n", state);
-                       return;
-               } /* case */
-       } /* while */
-
-       if (!timeout--) {
-               printk(KERN_ERR "optcd: timeout in state %d\n", state);
-               state = S_STOP;
-               if (exec_cmd(COMSTOP) < 0) {
-                       state = S_IDLE;
-                       while (current_valid())
-                               end_request(CURRENT, 0);
-                       return;
-               }
-       }
-
-       mod_timer(&req_timer, jiffies + HZ/100);
-}
-
-
-static void do_optcd_request(request_queue_t * q)
-{
-       DEBUG((DEBUG_REQUEST, "do_optcd_request(%ld+%ld)",
-              CURRENT -> sector, CURRENT -> nr_sectors));
-
-       if (disk_info.audio) {
-               printk(KERN_WARNING "optcd: tried to mount an Audio CD\n");
-               end_request(CURRENT, 0);
-               return;
-       }
-
-       transfer_is_active = 1;
-       while (current_valid()) {
-               transfer();     /* First try to transfer block from buffers */
-               if (CURRENT -> nr_sectors == 0) {
-                       end_request(CURRENT, 1);
-               } else {        /* Want to read a block not in buffer */
-                       buf_out = NOBUF;
-                       if (state == S_IDLE) {
-                               /* %% Should this block the request queue?? */
-                               if (update_toc() < 0) {
-                                       while (current_valid())
-                                               end_request(CURRENT, 0);
-                                       break;
-                               }
-                               /* Start state machine */
-                               state = S_START;
-                               timeout = READ_TIMEOUT;
-                               tries = 5;
-                               /* %% why not start right away?? */
-                               mod_timer(&req_timer, jiffies + HZ/100);
-                       }
-                       break;
-               }
-       }
-       transfer_is_active = 0;
-
-       DEBUG((DEBUG_REQUEST, "next_bn:%d  buf_in:%d buf_out:%d  buf_bn:%d",
-              next_bn, buf_in, buf_out, buf_bn[buf_in]));
-       DEBUG((DEBUG_REQUEST, "do_optcd_request ends"));
-}
-\f
-/* IOCTLs */
-
-
-static char auto_eject = 0;
-
-static int cdrompause(void)
-{
-       int status;
-
-       if (audio_status != CDROM_AUDIO_PLAY)
-               return -EINVAL;
-
-       status = exec_cmd(COMPAUSEON);
-       if (status < 0) {
-               DEBUG((DEBUG_VFS, "exec_cmd COMPAUSEON: %02x", -status));
-               return -EIO;
-       }
-       audio_status = CDROM_AUDIO_PAUSED;
-       return 0;
-}
-
-
-static int cdromresume(void)
-{
-       int status;
-
-       if (audio_status != CDROM_AUDIO_PAUSED)
-               return -EINVAL;
-
-       status = exec_cmd(COMPAUSEOFF);
-       if (status < 0) {
-               DEBUG((DEBUG_VFS, "exec_cmd COMPAUSEOFF: %02x", -status));
-               audio_status = CDROM_AUDIO_ERROR;
-               return -EIO;
-       }
-       audio_status = CDROM_AUDIO_PLAY;
-       return 0;
-}
-
-
-static int cdromplaymsf(void __user *arg)
-{
-       int status;
-       struct cdrom_msf msf;
-
-       if (copy_from_user(&msf, arg, sizeof msf))
-               return -EFAULT;
-
-       bin2bcd(&msf);
-       status = exec_long_cmd(COMPLAY, &msf);
-       if (status < 0) {
-               DEBUG((DEBUG_VFS, "exec_long_cmd COMPLAY: %02x", -status));
-               audio_status = CDROM_AUDIO_ERROR;
-               return -EIO;
-       }
-
-       audio_status = CDROM_AUDIO_PLAY;
-       return 0;
-}
-
-
-static int cdromplaytrkind(void __user *arg)
-{
-       int status;
-       struct cdrom_ti ti;
-       struct cdrom_msf msf;
-
-       if (copy_from_user(&ti, arg, sizeof ti))
-               return -EFAULT;
-
-       if (ti.cdti_trk0 < disk_info.first
-           || ti.cdti_trk0 > disk_info.last
-           || ti.cdti_trk1 < ti.cdti_trk0)
-               return -EINVAL;
-       if (ti.cdti_trk1 > disk_info.last)
-               ti.cdti_trk1 = disk_info.last;
-
-       msf.cdmsf_min0 = toc[ti.cdti_trk0].cdsc_absaddr.msf.minute;
-       msf.cdmsf_sec0 = toc[ti.cdti_trk0].cdsc_absaddr.msf.second;
-       msf.cdmsf_frame0 = toc[ti.cdti_trk0].cdsc_absaddr.msf.frame;
-       msf.cdmsf_min1 = toc[ti.cdti_trk1 + 1].cdsc_absaddr.msf.minute;
-       msf.cdmsf_sec1 = toc[ti.cdti_trk1 + 1].cdsc_absaddr.msf.second;
-       msf.cdmsf_frame1 = toc[ti.cdti_trk1 + 1].cdsc_absaddr.msf.frame;
-
-       DEBUG((DEBUG_VFS, "play %02d:%02d.%02d to %02d:%02d.%02d",
-               msf.cdmsf_min0,
-               msf.cdmsf_sec0,
-               msf.cdmsf_frame0,
-               msf.cdmsf_min1,
-               msf.cdmsf_sec1,
-               msf.cdmsf_frame1));
-
-       bin2bcd(&msf);
-       status = exec_long_cmd(COMPLAY, &msf);
-       if (status < 0) {
-               DEBUG((DEBUG_VFS, "exec_long_cmd COMPLAY: %02x", -status));
-               audio_status = CDROM_AUDIO_ERROR;
-               return -EIO;
-       }
-
-       audio_status = CDROM_AUDIO_PLAY;
-       return 0;
-}
-
-
-static int cdromreadtochdr(void __user *arg)
-{
-       struct cdrom_tochdr tochdr;
-
-       tochdr.cdth_trk0 = disk_info.first;
-       tochdr.cdth_trk1 = disk_info.last;
-
-       return copy_to_user(arg, &tochdr, sizeof tochdr) ? -EFAULT : 0;
-}
-
-
-static int cdromreadtocentry(void __user *arg)
-{
-       struct cdrom_tocentry entry;
-       struct cdrom_subchnl *tocptr;
-
-       if (copy_from_user(&entry, arg, sizeof entry))
-               return -EFAULT;
-
-       if (entry.cdte_track == CDROM_LEADOUT)
-               tocptr = &toc[disk_info.last + 1];
-       else if (entry.cdte_track > disk_info.last
-               || entry.cdte_track < disk_info.first)
-               return -EINVAL;
-       else
-               tocptr = &toc[entry.cdte_track];
-
-       entry.cdte_adr = tocptr->cdsc_adr;
-       entry.cdte_ctrl = tocptr->cdsc_ctrl;
-       entry.cdte_addr.msf.minute = tocptr->cdsc_absaddr.msf.minute;
-       entry.cdte_addr.msf.second = tocptr->cdsc_absaddr.msf.second;
-       entry.cdte_addr.msf.frame = tocptr->cdsc_absaddr.msf.frame;
-       /* %% What should go into entry.cdte_datamode? */
-
-       if (entry.cdte_format == CDROM_LBA)
-               msf2lba(&entry.cdte_addr);
-       else if (entry.cdte_format != CDROM_MSF)
-               return -EINVAL;
-
-       return copy_to_user(arg, &entry, sizeof entry) ? -EFAULT : 0;
-}
-
-
-static int cdromvolctrl(void __user *arg)
-{
-       int status;
-       struct cdrom_volctrl volctrl;
-       struct cdrom_msf msf;
-
-       if (copy_from_user(&volctrl, arg, sizeof volctrl))
-               return -EFAULT;
-
-       msf.cdmsf_min0 = 0x10;
-       msf.cdmsf_sec0 = 0x32;
-       msf.cdmsf_frame0 = volctrl.channel0;
-       msf.cdmsf_min1 = volctrl.channel1;
-       msf.cdmsf_sec1 = volctrl.channel2;
-       msf.cdmsf_frame1 = volctrl.channel3;
-
-       status = exec_long_cmd(COMCHCTRL, &msf);
-       if (status < 0) {
-               DEBUG((DEBUG_VFS, "exec_long_cmd COMCHCTRL: %02x", -status));
-               return -EIO;
-       }
-       return 0;
-}
-
-
-static int cdromsubchnl(void __user *arg)
-{
-       int status;
-       struct cdrom_subchnl subchnl;
-
-       if (copy_from_user(&subchnl, arg, sizeof subchnl))
-               return -EFAULT;
-
-       if (subchnl.cdsc_format != CDROM_LBA
-           && subchnl.cdsc_format != CDROM_MSF)
-               return -EINVAL;
-
-       status = get_q_channel(&subchnl);
-       if (status < 0) {
-               DEBUG((DEBUG_VFS, "get_q_channel: %02x", -status));
-               return -EIO;
-       }
-
-       if (copy_to_user(arg, &subchnl, sizeof subchnl))
-               return -EFAULT;
-       return 0;
-}
-
-
-static struct gendisk *optcd_disk;
-
-
-static int cdromread(void __user *arg, int blocksize, int cmd)
-{
-       int status;
-       struct cdrom_msf msf;
-
-       if (copy_from_user(&msf, arg, sizeof msf))
-               return -EFAULT;
-
-       bin2bcd(&msf);
-       msf.cdmsf_min1 = 0;
-       msf.cdmsf_sec1 = 0;
-       msf.cdmsf_frame1 = 1;   /* read only one frame */
-       status = exec_read_cmd(cmd, &msf);
-
-       DEBUG((DEBUG_VFS, "read cmd status 0x%x", status));
-
-       if (!sleep_flag_low(FL_DTEN, SLEEP_TIMEOUT))
-               return -EIO;
-
-       fetch_data(optcd_disk->private_data, blocksize);
-
-       if (copy_to_user(arg, optcd_disk->private_data, blocksize))
-               return -EFAULT;
-
-       return 0;
-}
-
-
-static int cdromseek(void __user *arg)
-{
-       int status;
-       struct cdrom_msf msf;
-
-       if (copy_from_user(&msf, arg, sizeof msf))
-               return -EFAULT;
-
-       bin2bcd(&msf);
-       status = exec_seek_cmd(COMSEEK, &msf);
-
-       DEBUG((DEBUG_VFS, "COMSEEK status 0x%x", status));
-
-       if (status < 0)
-               return -EIO;
-       return 0;
-}
-
-
-#ifdef MULTISESSION
-static int cdrommultisession(void __user *arg)
-{
-       struct cdrom_multisession ms;
-
-       if (copy_from_user(&ms, arg, sizeof ms))
-               return -EFAULT;
-
-       ms.addr.msf.minute = disk_info.last_session.minute;
-       ms.addr.msf.second = disk_info.last_session.second;
-       ms.addr.msf.frame = disk_info.last_session.frame;
-
-       if (ms.addr_format != CDROM_LBA
-          && ms.addr_format != CDROM_MSF)
-               return -EINVAL;
-       if (ms.addr_format == CDROM_LBA)
-               msf2lba(&ms.addr);
-
-       ms.xa_flag = disk_info.xa;
-
-       if (copy_to_user(arg, &ms, sizeof(struct cdrom_multisession)))
-               return -EFAULT;
-
-#if DEBUG_MULTIS
-       if (ms.addr_format == CDROM_MSF)
-                       printk(KERN_DEBUG
-                       "optcd: multisession xa:%d, msf:%02d:%02d.%02d\n",
-                       ms.xa_flag,
-                       ms.addr.msf.minute,
-                       ms.addr.msf.second,
-                       ms.addr.msf.frame);
-       else
-               printk(KERN_DEBUG
-                   "optcd: multisession %d, lba:0x%08x [%02d:%02d.%02d])\n",
-                       ms.xa_flag,
-                       ms.addr.lba,
-                       disk_info.last_session.minute,
-                       disk_info.last_session.second,
-                       disk_info.last_session.frame);
-#endif /* DEBUG_MULTIS */
-
-       return 0;
-}
-#endif /* MULTISESSION */
-
-
-static int cdromreset(void)
-{
-       if (state != S_IDLE) {
-               error = 1;
-               tries = 0;
-       }
-
-       toc_uptodate = 0;
-       disk_changed = 1;
-       opt_invalidate_buffers();
-       audio_status = CDROM_AUDIO_NO_STATUS;
-
-       if (!reset_drive())
-               return -EIO;
-       return 0;
-}
-\f
-/* VFS calls */
-
-
-static int opt_ioctl(struct inode *ip, struct file *fp,
-                     unsigned int cmd, unsigned long arg)
-{
-       int status, err, retval = 0;
-       void __user *argp = (void __user *)arg;
-
-       DEBUG((DEBUG_VFS, "starting opt_ioctl"));
-
-       if (!ip)
-               return -EINVAL;
-
-       if (cmd == CDROMRESET)
-               return cdromreset();
-
-       /* is do_optcd_request or another ioctl busy? */
-       if (state != S_IDLE || in_vfs)
-               return -EBUSY;
-
-       in_vfs = 1;
-
-       status = drive_status();
-       if (status < 0) {
-               DEBUG((DEBUG_VFS, "drive_status: %02x", -status));
-               in_vfs = 0;
-               return -EIO;
-       }
-
-       if (status & ST_DOOR_OPEN)
-               switch (cmd) {  /* Actions that can be taken with door open */
-               case CDROMCLOSETRAY:
-                       /* We do this before trying to read the toc. */
-                       err = exec_cmd(COMCLOSE);
-                       if (err < 0) {
-                               DEBUG((DEBUG_VFS,
-                                      "exec_cmd COMCLOSE: %02x", -err));
-                               in_vfs = 0;
-                               return -EIO;
-                       }
-                       break;
-               default:        in_vfs = 0;
-                               return -EBUSY;
-               }
-
-       err = update_toc();
-       if (err < 0) {
-               DEBUG((DEBUG_VFS, "update_toc: %02x", -err));
-               in_vfs = 0;
-               return -EIO;
-       }
-
-       DEBUG((DEBUG_VFS, "ioctl cmd 0x%x", cmd));
-
-       switch (cmd) {
-       case CDROMPAUSE:        retval = cdrompause(); break;
-       case CDROMRESUME:       retval = cdromresume(); break;
-       case CDROMPLAYMSF:      retval = cdromplaymsf(argp); break;
-       case CDROMPLAYTRKIND:   retval = cdromplaytrkind(argp); break;
-       case CDROMREADTOCHDR:   retval = cdromreadtochdr(argp); break;
-       case CDROMREADTOCENTRY: retval = cdromreadtocentry(argp); break;
-
-       case CDROMSTOP:         err = exec_cmd(COMSTOP);
-                               if (err < 0) {
-                                       DEBUG((DEBUG_VFS,
-                                               "exec_cmd COMSTOP: %02x",
-                                               -err));
-                                       retval = -EIO;
-                               } else
-                                       audio_status = CDROM_AUDIO_NO_STATUS;
-                               break;
-       case CDROMSTART:        break;  /* This is a no-op */
-       case CDROMEJECT:        err = exec_cmd(COMUNLOCK);
-                               if (err < 0) {
-                                       DEBUG((DEBUG_VFS,
-                                               "exec_cmd COMUNLOCK: %02x",
-                                               -err));
-                                       retval = -EIO;
-                                       break;
-                               }
-                               err = exec_cmd(COMOPEN);
-                               if (err < 0) {
-                                       DEBUG((DEBUG_VFS,
-                                               "exec_cmd COMOPEN: %02x",
-                                               -err));
-                                       retval = -EIO;
-                               }
-                               break;
-
-       case CDROMVOLCTRL:      retval = cdromvolctrl(argp); break;
-       case CDROMSUBCHNL:      retval = cdromsubchnl(argp); break;
-
-       /* The drive detects the mode and automatically delivers the
-          correct 2048 bytes, so we don't need these IOCTLs */
-       case CDROMREADMODE2:    retval = -EINVAL; break;
-       case CDROMREADMODE1:    retval = -EINVAL; break;
-
-       /* Drive doesn't support reading audio */
-       case CDROMREADAUDIO:    retval = -EINVAL; break;
-
-       case CDROMEJECT_SW:     auto_eject = (char) arg;
-                               break;
-
-#ifdef MULTISESSION
-       case CDROMMULTISESSION: retval = cdrommultisession(argp); break;
-#endif
-
-       case CDROM_GET_MCN:     retval = -EINVAL; break; /* not implemented */
-       case CDROMVOLREAD:      retval = -EINVAL; break; /* not implemented */
-
-       case CDROMREADRAW:
-                       /* this drive delivers 2340 bytes in raw mode */
-                       retval = cdromread(argp, CD_FRAMESIZE_RAW1, COMREADRAW);
-                       break;
-       case CDROMREADCOOKED:
-                       retval = cdromread(argp, CD_FRAMESIZE, COMREAD);
-                       break;
-       case CDROMREADALL:
-                       retval = cdromread(argp, CD_FRAMESIZE_RAWER, COMREADALL);
-                       break;
-
-       case CDROMSEEK:         retval = cdromseek(argp); break;
-       case CDROMPLAYBLK:      retval = -EINVAL; break; /* not implemented */
-       case CDROMCLOSETRAY:    break;  /* The action was taken earlier */
-       default:                retval = -EINVAL;
-       }
-       in_vfs = 0;
-       return retval;
-}
-
-
-static int open_count = 0;
-
-/* Open device special file; check that a disk is in. */
-static int opt_open(struct inode *ip, struct file *fp)
-{
-       DEBUG((DEBUG_VFS, "starting opt_open"));
-
-       if (!open_count && state == S_IDLE) {
-               int status;
-               char *buf;
-
-               buf = kmalloc(CD_FRAMESIZE_RAWER, GFP_KERNEL);
-               if (!buf) {
-                       printk(KERN_INFO "optcd: cannot allocate read buffer\n");
-                       return -ENOMEM;
-               }
-               optcd_disk->private_data = buf;         /* save read buffer */
-
-               toc_uptodate = 0;
-               opt_invalidate_buffers();
-
-               status = exec_cmd(COMCLOSE);    /* close door */
-               if (status < 0) {
-                       DEBUG((DEBUG_VFS, "exec_cmd COMCLOSE: %02x", -status));
-               }
-
-               status = drive_status();
-               if (status < 0) {
-                       DEBUG((DEBUG_VFS, "drive_status: %02x", -status));
-                       goto err_out;
-               }
-               DEBUG((DEBUG_VFS, "status: %02x", status));
-               if ((status & ST_DOOR_OPEN) || (status & ST_DRVERR)) {
-                       printk(KERN_INFO "optcd: no disk or door open\n");
-                       goto err_out;
-               }
-               status = exec_cmd(COMLOCK);             /* Lock door */
-               if (status < 0) {
-                       DEBUG((DEBUG_VFS, "exec_cmd COMLOCK: %02x", -status));
-               }
-               status = update_toc();  /* Read table of contents */
-               if (status < 0) {
-                       DEBUG((DEBUG_VFS, "update_toc: %02x", -status));
-                       status = exec_cmd(COMUNLOCK);   /* Unlock door */
-                       if (status < 0) {
-                               DEBUG((DEBUG_VFS,
-                                      "exec_cmd COMUNLOCK: %02x", -status));
-                       }
-                       goto err_out;
-               }
-               open_count++;
-       }
-
-       DEBUG((DEBUG_VFS, "exiting opt_open"));
-
-       return 0;
-
-err_out:
-       return -EIO;
-}
-
-
-/* Release device special file; flush all blocks from the buffer cache */
-static int opt_release(struct inode *ip, struct file *fp)
-{
-       int status;
-
-       DEBUG((DEBUG_VFS, "executing opt_release"));
-       DEBUG((DEBUG_VFS, "inode: %p, device: %s, file: %p\n",
-               ip, ip->i_bdev->bd_disk->disk_name, fp));
-
-       if (!--open_count) {
-               toc_uptodate = 0;
-               opt_invalidate_buffers();
-               status = exec_cmd(COMUNLOCK);   /* Unlock door */
-               if (status < 0) {
-                       DEBUG((DEBUG_VFS, "exec_cmd COMUNLOCK: %02x", -status));
-               }
-               if (auto_eject) {
-                       status = exec_cmd(COMOPEN);
-                       DEBUG((DEBUG_VFS, "exec_cmd COMOPEN: %02x", -status));
-               }
-               kfree(optcd_disk->private_data);
-               del_timer(&delay_timer);
-               del_timer(&req_timer);
-       }
-       return 0;
-}
-
-
-/* Check if disk has been changed */
-static int opt_media_change(struct gendisk *disk)
-{
-       DEBUG((DEBUG_VFS, "executing opt_media_change"));
-       DEBUG((DEBUG_VFS, "dev: %s; disk_changed = %d\n",
-                       disk->disk_name, disk_changed));
-
-       if (disk_changed) {
-               disk_changed = 0;
-               return 1;
-       }
-       return 0;
-}
-\f
-/* Driver initialisation */
-
-
-/* Returns 1 if a drive is detected with a version string
-   starting with "DOLPHIN". Otherwise 0. */
-static int __init version_ok(void)
-{
-       char devname[100];
-       int count, i, ch, status;
-
-       status = exec_cmd(COMVERSION);
-       if (status < 0) {
-               DEBUG((DEBUG_VFS, "exec_cmd COMVERSION: %02x", -status));
-               return 0;
-       }
-       if ((count = get_data(1)) < 0) {
-               DEBUG((DEBUG_VFS, "get_data(1): %02x", -count));
-               return 0;
-       }
-       for (i = 0, ch = -1; count > 0; count--) {
-               if ((ch = get_data(1)) < 0) {
-                       DEBUG((DEBUG_VFS, "get_data(1): %02x", -ch));
-                       break;
-               }
-               if (i < 99)
-                       devname[i++] = ch;
-       }
-       devname[i] = '\0';
-       if (ch < 0)
-               return 0;
-
-       printk(KERN_INFO "optcd: Device %s detected\n", devname);
-       return ((devname[0] == 'D')
-            && (devname[1] == 'O')
-            && (devname[2] == 'L')
-            && (devname[3] == 'P')
-            && (devname[4] == 'H')
-            && (devname[5] == 'I')
-            && (devname[6] == 'N'));
-}
-
-
-static struct block_device_operations opt_fops = {
-       .owner          = THIS_MODULE,
-       .open           = opt_open,
-       .release        = opt_release,
-       .ioctl          = opt_ioctl,
-       .media_changed  = opt_media_change,
-};
-
-#ifndef MODULE
-/* Get kernel parameter when used as a kernel driver */
-static int optcd_setup(char *str)
-{
-       int ints[4];
-       (void)get_options(str, ARRAY_SIZE(ints), ints);
-       
-       if (ints[0] > 0)
-               optcd_port = ints[1];
-
-       return 1;
-}
-
-__setup("optcd=", optcd_setup);
-
-#endif /* MODULE */
-
-/* Test for presence of drive and initialize it. Called at boot time
-   or during module initialisation. */
-static int __init optcd_init(void)
-{
-       int status;
-
-       if (optcd_port <= 0) {
-               printk(KERN_INFO
-                       "optcd: no Optics Storage CDROM Initialization\n");
-               return -EIO;
-       }
-       optcd_disk = alloc_disk(1);
-       if (!optcd_disk) {
-               printk(KERN_ERR "optcd: can't allocate disk\n");
-               return -ENOMEM;
-       }
-       optcd_disk->major = MAJOR_NR;
-       optcd_disk->first_minor = 0;
-       optcd_disk->fops = &opt_fops;
-       sprintf(optcd_disk->disk_name, "optcd");
-
-       if (!request_region(optcd_port, 4, "optcd")) {
-               printk(KERN_ERR "optcd: conflict, I/O port 0x%x already used\n",
-                       optcd_port);
-               put_disk(optcd_disk);
-               return -EIO;
-       }
-
-       if (!reset_drive()) {
-               printk(KERN_ERR "optcd: drive at 0x%x not ready\n", optcd_port);
-               release_region(optcd_port, 4);
-               put_disk(optcd_disk);
-               return -EIO;
-       }
-       if (!version_ok()) {
-               printk(KERN_ERR "optcd: unknown drive detected; aborting\n");
-               release_region(optcd_port, 4);
-               put_disk(optcd_disk);
-               return -EIO;
-       }
-       status = exec_cmd(COMINITDOUBLE);
-       if (status < 0) {
-               printk(KERN_ERR "optcd: cannot init double speed mode\n");
-               release_region(optcd_port, 4);
-               DEBUG((DEBUG_VFS, "exec_cmd COMINITDOUBLE: %02x", -status));
-               put_disk(optcd_disk);
-               return -EIO;
-       }
-       if (register_blkdev(MAJOR_NR, "optcd")) {
-               release_region(optcd_port, 4);
-               put_disk(optcd_disk);
-               return -EIO;
-       }
-
-
-       opt_queue = blk_init_queue(do_optcd_request, &optcd_lock);
-       if (!opt_queue) {
-               unregister_blkdev(MAJOR_NR, "optcd");
-               release_region(optcd_port, 4);
-               put_disk(optcd_disk);
-               return -ENOMEM;
-       }
-
-       blk_queue_hardsect_size(opt_queue, 2048);
-       optcd_disk->queue = opt_queue;
-       add_disk(optcd_disk);
-
-       printk(KERN_INFO "optcd: DOLPHIN 8000 AT CDROM at 0x%x\n", optcd_port);
-       return 0;
-}
-
-
-static void __exit optcd_exit(void)
-{
-       del_gendisk(optcd_disk);
-       put_disk(optcd_disk);
-       if (unregister_blkdev(MAJOR_NR, "optcd") == -EINVAL) {
-               printk(KERN_ERR "optcd: what's that: can't unregister\n");
-               return;
-       }
-       blk_cleanup_queue(opt_queue);
-       release_region(optcd_port, 4);
-       printk(KERN_INFO "optcd: module released.\n");
-}
-
-module_init(optcd_init);
-module_exit(optcd_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_BLOCKDEV_MAJOR(OPTICS_CDROM_MAJOR);
diff --git a/drivers/cdrom/optcd.h b/drivers/cdrom/optcd.h
deleted file mode 100644 (file)
index 1911bb9..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*     linux/include/linux/optcd.h - Optics Storage 8000 AT CDROM driver
-       $Id: optcd.h,v 1.2 1996/01/15 18:43:44 root Exp root $
-
-       Copyright (C) 1995 Leo Spiekman (spiekman@dutette.et.tudelft.nl)
-
-
-       Configuration file for linux/drivers/cdrom/optcd.c
-*/
-
-#ifndef _LINUX_OPTCD_H
-#define _LINUX_OPTCD_H
-
-
-/* I/O base of drive. Drive uses base to base+2.
-   This setting can be overridden with the kernel or insmod command
-   line option 'optcd=<portbase>'. Use address of 0 to disable driver. */
-#define OPTCD_PORTBASE 0x340
-
-
-/* enable / disable parts of driver by define / undef */
-#define        MULTISESSION            /* multisession support (ALPHA) */
-
-
-/* Change 0 to 1 to debug various parts of the driver */
-#define        DEBUG_DRIVE_IF  0       /* Low level drive interface */
-#define        DEBUG_CONV      0       /* Address conversions */
-#define        DEBUG_BUFFERS   0       /* Buffering and block size conversion */
-#define        DEBUG_REQUEST   0       /* Request mechanism */
-#define        DEBUG_STATE     0       /* State machine */
-#define        DEBUG_TOC       0       /* Q-channel and Table of Contents */
-#define        DEBUG_MULTIS    0       /* Multisession code */
-#define        DEBUG_VFS       0       /* VFS interface */
-
-
-/* Don't touch these unless you know what you're doing. */
-
-/* Various timeout loop repetition counts. */
-#define BUSY_TIMEOUT           10000000        /* for busy wait */
-#define FAST_TIMEOUT           100000          /* ibid. for probing */
-#define SLEEP_TIMEOUT          6000            /* for timer wait */
-#define MULTI_SEEK_TIMEOUT     1000            /* for timer wait */
-#define READ_TIMEOUT           6000            /* for poll wait */
-#define STOP_TIMEOUT           2000            /* for poll wait */
-#define RESET_WAIT             5000            /* busy wait at drive reset */
-
-/* # of buffers for block size conversion. 6 is optimal for my setup (P75),
-   giving 280 kb/s, with 0.4% CPU usage. Experiment to find your optimal
-   setting */
-#define N_BUFS         6
-
-
-#endif /* _LINUX_OPTCD_H */
diff --git a/drivers/cdrom/sbpcd.c b/drivers/cdrom/sbpcd.c
deleted file mode 100644 (file)
index a1283b1..0000000
+++ /dev/null
@@ -1,5966 +0,0 @@
-/*
- *  sbpcd.c   CD-ROM device driver for the whole family of traditional,
- *            non-ATAPI IDE-style Matsushita/Panasonic CR-5xx drives.
- *            Works with SoundBlaster compatible cards and with "no-sound"
- *            interface cards like Lasermate, Panasonic CI-101P, Teac, ...
- *            Also for the Longshine LCS-7260 drive.
- *            Also for the IBM "External ISA CD-Rom" drive.
- *            Also for the CreativeLabs CD200 drive.
- *            Also for the TEAC CD-55A drive.
- *            Also for the ECS-AT "Vertos 100" drive.
- *            Not for Sanyo drives (but for the H94A, sjcd is there...).
- *            Not for any other Funai drives than the CD200 types (sometimes
- *             labelled E2550UA or MK4015 or 2800F).
- */
-
-#define VERSION "v4.63 Andrew J. Kroll <ag784@freenet.buffalo.edu> Wed Jul 26 04:24:10 EDT 2000"
-
-/*   Copyright (C) 1993, 1994, 1995  Eberhard Moenkeberg <emoenke@gwdg.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, 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.
- *
- *   If you change this software, you should mail a .diff file with some
- *   description lines to emoenke@gwdg.de. I want to know about it.
- *
- *   If you are the editor of a Linux CD, you should enable sbpcd.c within
- *   your boot floppy kernel and send me one of your CDs for free.
- *
- *   If you would like to port the driver to an other operating system (f.e.
- *   FreeBSD or NetBSD) or use it as an information source, you shall not be
- *   restricted by the GPL under the following conditions:
- *     a) the source code of your work is freely available
- *     b) my part of the work gets mentioned at all places where your 
- *        authorship gets mentioned
- *     c) I receive a copy of your code together with a full installation
- *        package of your operating system for free.
- *
- *
- *  VERSION HISTORY
- *
- *  0.1  initial release, April/May 93, after mcd.c (Martin Harriss)
- *
- *  0.2  thek "repeat:"-loop in do_sbpcd_request did not check for
- *       end-of-request_queue (resulting in kernel panic).
- *       Flow control seems stable, but throughput is not better.  
- *
- *  0.3  interrupt locking totally eliminated (maybe "inb" and "outb"
- *       are still locking) - 0.2 made keyboard-type-ahead losses.
- *       check_sbpcd_media_change added (to use by isofs/inode.c)
- *       - but it detects almost nothing.
- *
- *  0.4  use MAJOR 25 definitely.
- *       Almost total re-design to support double-speed drives and
- *       "naked" (no sound) interface cards ("LaserMate" interface type).
- *       Flow control should be exact now.
- *       Don't occupy the SbPro IRQ line (not needed either); will
- *       live together with Hannu Savolainen's sndkit now.
- *       Speeded up data transfer to 150 kB/sec, with help from Kai
- *       Makisara, the "provider" of the "mt" tape utility.
- *       Give "SpinUp" command if necessary.
- *       First steps to support up to 4 drives (but currently only one).
- *       Implemented audio capabilities - workman should work, xcdplayer
- *       gives some problems.
- *       This version is still consuming too much CPU time, and
- *       sleeping still has to be worked on.
- *       During "long" implied seeks, it seems possible that a 
- *       ReadStatus command gets ignored. That gives the message
- *       "ResponseStatus timed out" (happens about 6 times here during
- *       a "ls -alR" of the YGGDRASIL LGX-Beta CD). Such a case is
- *       handled without data error, but it should get done better.
- *
- *  0.5  Free CPU during waits (again with help from Kai Makisara).
- *       Made it work together with the LILO/kernel setup standard.
- *       Included auto-probing code, as suggested by YGGDRASIL.
- *       Formal redesign to add DDI debugging.
- *       There are still flaws in IOCTL (workman with double speed drive).
- *
- *  1.0  Added support for all drive IDs (0...3, no longer only 0)
- *       and up to 4 drives on one controller.
- *       Added "#define MANY_SESSION" for "old" multi session CDs.
- *
- *  1.1  Do SpinUp for new drives, too.
- *       Revised for clean compile under "old" kernels (0.99pl9).
- *
- *  1.2  Found the "workman with double-speed drive" bug: use the driver's
- *       audio_state, not what the drive is reporting with ReadSubQ.
- *
- *  1.3  Minor cleanups.
- *       Refinements regarding Workman.
- *
- *  1.4  Read XA disks (PhotoCDs) with "old" drives, too (but only the first
- *       session - no chance to fully access a "multi-session" CD).
- *       This currently still is too slow (50 kB/sec) - but possibly
- *       the old drives won't do it faster.
- *       Implemented "door (un)lock" for new drives (still does not work
- *       as wanted - no lock possible after an unlock).
- *       Added some debugging printout for the UPC/EAN code - but my drives 
- *       return only zeroes. Is there no UPC/EAN code written?
- *
- *  1.5  Laborate with UPC/EAN code (not better yet).
- *       Adapt to kernel 1.1.8 change (have to explicitly include
- *       <linux/string.h> now).
- *
- *  1.6  Trying to read audio frames as data. Impossible with the current
- *       drive firmware levels, as it seems. Awaiting any hint. ;-)
- *       Changed "door unlock": repeat it until success.
- *       Changed CDROMSTOP routine (stop somewhat "softer" so that Workman
- *       won't get confused).
- *       Added a third interface type: Sequoia S-1000, as used with the SPEA
- *       Media FX sound card. This interface (usable for Sony and Mitsumi 
- *       drives, too) needs a special configuration setup and behaves like a 
- *       LaserMate type after that. Still experimental - I do not have such
- *       an interface.
- *       Use the "variable BLOCK_SIZE" feature (2048). But it does only work
- *       if you give the mount option "block=2048".
- *       The media_check routine is currently disabled; now that it gets
- *       called as it should I fear it must get synchronized for not to
- *       disturb the normal driver's activity.
- *
- *  2.0  Version number bumped - two reasons:
- *       - reading audio tracks as data works now with CR-562 and CR-563. We
- *       currently do it by an IOCTL (yet has to get standardized), one frame
- *       at a time; that is pretty slow. But it works.
- *       - we are maintaining now up to 4 interfaces (each up to 4 drives):
- *       did it the easy way - a different MAJOR (25, 26, ...) and a different
- *       copy of the driver (sbpcd.c, sbpcd2.c, sbpcd3.c, sbpcd4.c - only
- *       distinguished by the value of SBPCD_ISSUE and the driver's name),
- *       and a common sbpcd.h file.
- *       Bettered the "ReadCapacity error" problem with old CR-52x drives (the
- *       drives sometimes need a manual "eject/insert" before work): just
- *       reset the drive and do again. Needs lots of resets here and sometimes
- *       that does not cure, so this can't be the solution.
- *
- *  2.1  Found bug with multisession CDs (accessing frame 16).
- *       "read audio" works now with address type CDROM_MSF, too.
- *       Bigger audio frame buffer: allows reading max. 4 frames at time; this
- *       gives a significant speedup, but reading more than one frame at once
- *       gives missing chunks at each single frame boundary.
- *
- *  2.2  Kernel interface cleanups: timers, init, setup, media check.
- *
- *  2.3  Let "door lock" and "eject" live together.
- *       Implemented "close tray" (done automatically during open).
- *
- *  2.4  Use different names for device registering.
- *
- *  2.5  Added "#if EJECT" code (default: enabled) to automatically eject
- *       the tray during last call to "sbpcd_release".
- *       Added "#if JUKEBOX" code (default: disabled) to automatically eject
- *       the tray during call to "sbpcd_open" if no disk is in.
- *       Turn on the CD volume of "compatible" sound cards, too; just define
- *       SOUND_BASE (in sbpcd.h) accordingly (default: disabled).
- *
- *  2.6  Nothing new.  
- *
- *  2.7  Added CDROMEJECT_SW ioctl to set the "EJECT" behavior on the fly:
- *       0 disables, 1 enables auto-ejecting. Useful to keep the tray in
- *       during shutdown.
- *
- *  2.8  Added first support (still BETA, I need feedback or a drive) for
- *       the Longshine LCS-7260 drives. They appear as double-speed drives
- *       using the "old" command scheme, extended by tray control and door
- *       lock functions.
- *       Found (and fixed preliminary) a flaw with some multisession CDs: we
- *       have to re-direct not only the accesses to frame 16 (the isofs
- *       routines drive it up to max. 100), but also those to the continuation
- *       (repetition) frames (as far as they exist - currently set fix as
- *       16..20).
- *       Changed default of the "JUKEBOX" define. If you use this default,
- *       your tray will eject if you try to mount without a disk in. Next
- *       mount command will insert the tray - so, just fill in a disk. ;-)
- *
- *  2.9  Fulfilled the Longshine LCS-7260 support; with great help and
- *       experiments by Serge Robyns.
- *       First attempts to support the TEAC CD-55A drives; but still not
- *       usable yet.
- *       Implemented the CDROMMULTISESSION ioctl; this is an attempt to handle
- *       multi session CDs more "transparent" (redirection handling has to be
- *       done within the isofs routines, and only for the special purpose of
- *       obtaining the "right" volume descriptor; accesses to the raw device
- *       should not get redirected).
- *
- *  3.0  Just a "normal" increment, with some provisions to do it better. ;-)
- *       Introduced "#define READ_AUDIO" to specify the maximum number of 
- *       audio frames to grab with one request. This defines a buffer size
- *       within kernel space; a value of 0 will reserve no such space and
- *       disable the CDROMREADAUDIO ioctl. A value of 75 enables the reading
- *       of a whole second with one command, but will use a buffer of more
- *       than 172 kB.
- *       Started CD200 support. Drive detection should work, but nothing
- *       more.
- *
- *  3.1  Working to support the CD200 and the Teac CD-55A drives.
- *       AT-BUS style device numbering no longer used: use SCSI style now.
- *       So, the first "found" device has MINOR 0, regardless of the
- *       jumpered drive ID. This implies modifications to the /dev/sbpcd*
- *       entries for some people, but will help the DAU (german TLA, english:
- *       "newbie", maybe ;-) to install his "first" system from a CD.
- *
- *  3.2  Still testing with CD200 and CD-55A drives.
- *
- *  3.3  Working with CD200 support.
- *
- *  3.4  Auto-probing stops if an address of 0 is seen (to be entered with
- *       the kernel command line).
- *       Made the driver "loadable". If used as a module, "audio copy" is
- *       disabled, and the internal read ahead data buffer has a reduced size
- *       of 4 kB; so, throughput may be reduced a little bit with slow CPUs.
- *
- *  3.5  Provisions to handle weird photoCDs which have an interrupted
- *       "formatting" immediately after the last frames of some files: simply
- *       never "read ahead" with MultiSession CDs. By this, CPU usage may be
- *       increased with those CDs, and there may be a loss in speed.
- *       Re-structured the messaging system.
- *       The "loadable" version no longer has a limited READ_AUDIO buffer
- *       size.
- *       Removed "MANY_SESSION" handling for "old" multi session CDs.
- *       Added "private" IOCTLs CDROMRESET and CDROMVOLREAD.
- *       Started again to support the TEAC CD-55A drives, now that I found
- *       the money for "my own" drive. ;-)
- *       The TEAC CD-55A support is fairly working now.
- *       I have measured that the drive "delivers" at 600 kB/sec (even with
- *       bigger requests than the drive's 64 kB buffer can satisfy), but
- *       the "real" rate does not exceed 520 kB/sec at the moment. 
- *       Caused by the various changes to build in TEAC support, the timed
- *       loops are de-optimized at the moment (less throughput with CR-52x
- *       drives, and the TEAC will give speed only with SBP_BUFFER_FRAMES 64).
- *
- *  3.6  Fixed TEAC data read problems with SbPro interfaces.
- *       Initial size of the READ_AUDIO buffer is 0. Can get set to any size
- *       during runtime.
- *
- *  3.7  Introduced MAX_DRIVES for some poor interface cards (seen with TEAC
- *       drives) which allow only one drive (ID 0); this avoids repetitive
- *       detection under IDs 1..3. 
- *       Elongated cmd_out_T response waiting; necessary for photo CDs with
- *       a lot of sessions.
- *       Bettered the sbpcd_open() behavior with TEAC drives.
- *
- *  3.8  Elongated max_latency for CR-56x drives.
- *
- *  3.9  Finally fixed the long-known SoundScape/SPEA/Sequoia S-1000 interface
- *       configuration bug.
- *       Now Corey, Heiko, Ken, Leo, Vadim/Eric & Werner are invited to copy
- *       the config_spea() routine into their drivers. ;-)
- *
- *  4.0  No "big step" - normal version increment.
- *       Adapted the benefits from 1.3.33.
- *       Fiddled with CDROMREADAUDIO flaws.
- *       Avoid ReadCapacity command with CD200 drives (the MKE 1.01 version
- *       seems not to support it).
- *       Fulfilled "read audio" for CD200 drives, with help of Pete Heist
- *       (heistp@rpi.edu).
- *
- *  4.1  Use loglevel KERN_INFO with printk().
- *       Added support for "Vertos 100" drive ("ECS-AT") - it is very similar
- *       to the Longshine LCS-7260. Give feedback if you can - I never saw
- *       such a drive, and I have no specs.
- *
- *  4.2  Support for Teac 16-bit interface cards. Can't get auto-detected,
- *       so you have to jumper your card to 0x2C0. Still not 100% - come
- *       in contact if you can give qualified feedback.
- *       Use loglevel KERN_NOTICE with printk(). If you get annoyed by a
- *       flood of unwanted messages and the accompanied delay, try to read
- *       my documentation. Especially the Linux CDROM drivers have to do an
- *       important job for the newcomers, so the "distributed" version has
- *       to fit some special needs. Since generations, the flood of messages
- *       is user-configurable (even at runtime), but to get aware of this, one
- *       needs a special mental quality: the ability to read.
- *       
- *  4.3  CD200F does not like to receive a command while the drive is
- *       reading the ToC; still trying to solve it.
- *       Removed some redundant verify_area calls (yes, Heiko Eissfeldt
- *       is visiting all the Linux CDROM drivers ;-).
- *       
- *  4.4  Adapted one idea from tiensivu@pilot.msu.edu's "stripping-down"
- *       experiments: "KLOGD_PAUSE".
- *       Inhibited "play audio" attempts with data CDs. Provisions for a
- *       "data-safe" handling of "mixed" (data plus audio) Cds.
- *
- *  4.5  Meanwhile Gonzalo Tornaria <tornaria@cmat.edu.uy> (GTL) built a
- *       special end_request routine: we seem to have to take care for not
- *       to have two processes working at the request list. My understanding
- *       was and is that ll_rw_blk should not call do_sbpcd_request as long
- *       as there is still one call active (the first call will care for all
- *       outstanding I/Os, and if a second call happens, that is a bug in
- *       ll_rw_blk.c).
- *       "Check media change" without touching any drive.
- *
- *  4.6  Use a semaphore to synchronize multi-activity; elaborated by Rob
- *       Riggs <rriggs@tesser.com>. At the moment, we simply block "read"
- *       against "ioctl" and vice versa. This could be refined further, but
- *       I guess with almost no performance increase.
- *       Experiments to speed up the CD-55A; again with help of Rob Riggs
- *       (to be true, he gave both, idea & code. ;-)
- *
- *  4.61 Ported to Uniform CD-ROM driver by 
- *       Heiko Eissfeldt <heiko@colossus.escape.de> with additional
- *       changes by Erik Andersen <andersee@debian.org>
- *
- *  4.62 Fix a bug where playing audio left the drive in an unusable state.
- *         Heiko Eissfeldt <heiko@colossus.escape.de>
- *
- *  November 1999 -- Make kernel-parameter implementation work with 2.3.x 
- *                  Removed init_module & cleanup_module in favor of 
- *                  module_init & module_exit.
- *                  Torben Mathiasen <tmm@image.dk>
- *
- *  4.63 Bug fixes for audio annoyances, new legacy CDROM maintainer.
- *             Annoying things fixed:
- *             TOC reread on automated disk changes
- *             TOC reread on manual cd changes
- *             Play IOCTL tries to play CD before it's actually ready... sometimes.
- *             CD_AUDIO_COMPLETED state so workman (and other playes) can repeat play.
- *             Andrew J. Kroll <ag784@freenet.buffalo.edu> Wed Jul 26 04:24:10 EDT 2000
- *
- *  4.64 Fix module parameters - were being completely ignored.
- *      Can also specify max_drives=N as a setup int to get rid of
- *      "ghost" drives on crap hardware (aren't they all?)   Paul Gortmaker
- *
- *  TODO
- *     implement "read all subchannel data" (96 bytes per frame)
- *     remove alot of the virtual status bits and deal with hardware status
- *     move the change of cd for audio to a better place
- *     add debug levels to insmod parameters (trivial)
- *
- *     special thanks to Kai Makisara (kai.makisara@vtt.fi) for his fine
- *     elaborated speed-up experiments (and the fabulous results!), for
- *     the "push" towards load-free wait loops, and for the extensive mail
- *     thread which brought additional hints and bug fixes.
- *
- */
-
-/*
- * Trying to merge requests breaks this driver horribly (as in it goes
- * boom and apparently has done so since 2.3.41).  As it is a legacy
- * driver for a horribly slow double speed CD on a hideous interface
- * designed for polled operation, I won't lose any sleep in simply
- * disallowing merging.                                Paul G.  02/2001
- *
- * Thu May 30 14:14:47 CEST 2002:
- *
- * I have presumably found the reson for the above - there was a bogous
- * end_request substitute, which was manipulating the request queues
- * incorrectly. If someone has access to the actual hardware, and it's
- * still operations - well  please free to test it.
- *
- * Marcin Dalecki
- */
-
-/*
- * Add bio/kdev_t changes for 2.5.x required to make it work again. 
- * Still room for improvement in the request handling here if anyone
- * actually cares.  Bring your own chainsaw.    Paul G.  02/2002
- */
-
-
-#include <linux/module.h>
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/timer.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/cdrom.h>
-#include <linux/ioport.h>
-#include <linux/major.h>
-#include <linux/string.h>
-#include <linux/vmalloc.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <stdarg.h>
-#include "sbpcd.h"
-
-#define MAJOR_NR MATSUSHITA_CDROM_MAJOR
-#include <linux/blkdev.h>
-
-/*==========================================================================*/
-#if SBPCD_DIS_IRQ
-# define SBPCD_CLI cli()
-# define SBPCD_STI sti()
-#else
-# define SBPCD_CLI
-# define SBPCD_STI
-#endif
-
-/*==========================================================================*/
-/*
- * auto-probing address list
- * inspired by Adam J. Richter from Yggdrasil
- *
- * still not good enough - can cause a hang.
- *   example: a NE 2000 ethernet card at 300 will cause a hang probing 310.
- * if that happens, reboot and use the LILO (kernel) command line.
- * The possibly conflicting ethernet card addresses get NOT probed 
- * by default - to minimize the hang possibilities. 
- *
- * The SB Pro addresses get "mirrored" at 0x6xx and some more locations - to
- * avoid a type error, the 0x2xx-addresses must get checked before 0x6xx.
- *
- * send mail to emoenke@gwdg.de if your interface card is not FULLY
- * represented here.
- */
-static int sbpcd[] =
-{
-       CDROM_PORT, SBPRO, /* probe with user's setup first */
-#if DISTRIBUTION
-       0x230, 1, /* Soundblaster Pro and 16 (default) */
-#if 0
-       0x300, 0, /* CI-101P (default), WDH-7001C (default),
-                    Galaxy (default), Reveal (one default) */
-       0x250, 1, /* OmniCD default, Soundblaster Pro and 16 */
-       0x2C0, 3, /* Teac 16-bit cards */
-       0x260, 1, /* OmniCD */
-       0x320, 0, /* Lasermate, CI-101P, WDH-7001C, Galaxy, Reveal (other default),
-                    Longshine LCS-6853 (default) */
-       0x338, 0, /* Reveal Sound Wave 32 card model #SC600 */
-       0x340, 0, /* Mozart sound card (default), Lasermate, CI-101P */
-       0x360, 0, /* Lasermate, CI-101P */
-       0x270, 1, /* Soundblaster 16 */
-       0x670, 0, /* "sound card #9" */
-       0x690, 0, /* "sound card #9" */
-       0x338, 2, /* SPEA Media FX, Ensonic SoundScape (default) */
-       0x328, 2, /* SPEA Media FX */
-       0x348, 2, /* SPEA Media FX */
-       0x634, 0, /* some newer sound cards */
-       0x638, 0, /* some newer sound cards */
-       0x230, 1, /* some newer sound cards */
-       /* due to incomplete address decoding of the SbPro card, these must be last */
-       0x630, 0, /* "sound card #9" (default) */
-       0x650, 0, /* "sound card #9" */
-#ifdef MODULE
-       /*
-        * some "hazardous" locations (no harm with the loadable version)
-        * (will stop the bus if a NE2000 ethernet card resides at offset -0x10)
-        */
-       0x330, 0, /* Lasermate, CI-101P, WDH-7001C */
-       0x350, 0, /* Lasermate, CI-101P */
-       0x358, 2, /* SPEA Media FX */
-       0x370, 0, /* Lasermate, CI-101P */
-       0x290, 1, /* Soundblaster 16 */
-       0x310, 0, /* Lasermate, CI-101P, WDH-7001C */
-#endif /* MODULE */
-#endif
-#endif /* DISTRIBUTION */
-};
-
-/*
- * Protects access to global structures etc.
- */
-static  __cacheline_aligned DEFINE_SPINLOCK(sbpcd_lock);
-static struct request_queue *sbpcd_queue;
-
-/* You can only set the first pair, from old MODULE_PARM code.  */
-static int sbpcd_set(const char *val, struct kernel_param *kp)
-{
-       get_options((char *)val, 2, (int *)sbpcd);
-       return 0;
-}
-module_param_call(sbpcd, sbpcd_set, NULL, NULL, 0);
-
-#define NUM_PROBE  (sizeof(sbpcd) / sizeof(int))
-
-/*==========================================================================*/
-
-#define INLINE inline
-
-/*==========================================================================*/
-/*
- * the forward references:
- */
-static void sbp_sleep(u_int);
-static void mark_timeout_delay(u_long);
-static void mark_timeout_data(u_long);
-#if 0
-static void mark_timeout_audio(u_long);
-#endif
-static void sbp_read_cmd(struct request *req);
-static int sbp_data(struct request *req);
-static int cmd_out(void);
-static int DiskInfo(void);
-
-/*==========================================================================*/
-
-/*
- * pattern for printk selection:
- *
- * (1<<DBG_INF)  necessary information
- * (1<<DBG_BSZ)  BLOCK_SIZE trace
- * (1<<DBG_REA)  "read" status trace
- * (1<<DBG_CHK)  "media check" trace
- * (1<<DBG_TIM)  datarate timer test
- * (1<<DBG_INI)  initialization trace
- * (1<<DBG_TOC)  tell TocEntry values
- * (1<<DBG_IOC)  ioctl trace
- * (1<<DBG_STA)  "ResponseStatus" trace
- * (1<<DBG_ERR)  "cc_ReadError" trace
- * (1<<DBG_CMD)  "cmd_out" trace
- * (1<<DBG_WRN)  give explanation before auto-probing
- * (1<<DBG_MUL)  multi session code test
- * (1<<DBG_IDX)  "drive_id != 0" test code
- * (1<<DBG_IOX)  some special information
- * (1<<DBG_DID)  drive ID test
- * (1<<DBG_RES)  drive reset info
- * (1<<DBG_SPI)  SpinUp test info
- * (1<<DBG_IOS)  ioctl trace: "subchannel"
- * (1<<DBG_IO2)  ioctl trace: general
- * (1<<DBG_UPC)  show UPC info
- * (1<<DBG_XA1)  XA mode debugging
- * (1<<DBG_LCK)  door (un)lock info
- * (1<<DBG_SQ1)   dump SubQ frame
- * (1<<DBG_AUD)  "read audio" debugging
- * (1<<DBG_SEQ)  Sequoia interface configuration trace
- * (1<<DBG_LCS)  Longshine LCS-7260 debugging trace
- * (1<<DBG_CD2)  MKE/Funai CD200 debugging trace
- * (1<<DBG_TEA)  TEAC CD-55A debugging trace
- * (1<<DBG_ECS)  ECS-AT (Vertos-100) debugging trace
- * (1<<DBG_000)  unnecessary information
- */
-#if DISTRIBUTION
-static int sbpcd_debug = (1<<DBG_INF);
-#else
-static int sbpcd_debug = 0 & ((1<<DBG_INF) |
-                         (1<<DBG_TOC) |
-                         (1<<DBG_MUL) |
-                         (1<<DBG_UPC));
-#endif /* DISTRIBUTION */
-
-static int sbpcd_ioaddr = CDROM_PORT;  /* default I/O base address */
-static int sbpro_type = SBPRO;
-static unsigned char f_16bit;
-static unsigned char do_16bit;
-static int CDo_command, CDo_reset;
-static int CDo_sel_i_d, CDo_enable;
-static int CDi_info, CDi_status, CDi_data;
-static struct cdrom_msf msf;
-static struct cdrom_ti ti;
-static struct cdrom_tochdr tochdr;
-static struct cdrom_tocentry tocentry;
-static struct cdrom_subchnl SC;
-static struct cdrom_volctrl volctrl;
-static struct cdrom_read_audio read_audio;
-
-static unsigned char msgnum;
-static char msgbuf[80];
-
-static int max_drives = MAX_DRIVES;
-module_param(max_drives, int, 0);
-#ifndef MODULE
-static unsigned char setup_done;
-static const char *str_sb_l = "soundblaster";
-static const char *str_sp_l = "spea";
-static const char *str_ss_l = "soundscape";
-static const char *str_t16_l = "teac16bit";
-static const char *str_ss = "SoundScape";
-#endif
-static const char *str_sb = "SoundBlaster";
-static const char *str_lm = "LaserMate";
-static const char *str_sp = "SPEA";
-static const char *str_t16 = "Teac16bit";
-static const char *type;
-static const char *major_name="sbpcd";
-
-/*==========================================================================*/
-
-#ifdef FUTURE
-static DECLARE_WAIT_QUEUE_HEAD(sbp_waitq);
-#endif /* FUTURE */
-
-static int teac=SBP_TEAC_SPEED;
-static int buffers=SBP_BUFFER_FRAMES;
-
-static u_char family0[]="MATSHITA"; /* MKE CR-521, CR-522, CR-523 */
-static u_char family1[]="CR-56";    /* MKE CR-562, CR-563 */
-static u_char family2[]="CD200";    /* MKE CD200, Funai CD200F */
-static u_char familyL[]="LCS-7260"; /* Longshine LCS-7260 */
-static u_char familyT[]="CD-55";    /* TEAC CD-55A */
-static u_char familyV[]="ECS-AT";   /* ECS Vertos 100 */
-
-static u_int recursion; /* internal testing only */
-static u_int fatal_err; /* internal testing only */
-static u_int response_count;
-static u_int flags_cmd_out;
-static u_char cmd_type;
-static u_char drvcmd[10];
-static u_char infobuf[20];
-static u_char xa_head_buf[CD_XA_HEAD];
-static u_char xa_tail_buf[CD_XA_TAIL];
-
-#if OLD_BUSY
-static volatile u_char busy_data;
-static volatile u_char busy_audio; /* true semaphores would be safer */
-#endif /* OLD_BUSY */ 
-static DECLARE_MUTEX(ioctl_read_sem);
-static u_long timeout;
-static volatile u_char timed_out_delay;
-static volatile u_char timed_out_data;
-#if 0
-static volatile u_char timed_out_audio;
-#endif
-static u_int datarate= 1000000;
-static u_int maxtim16=16000000;
-static u_int maxtim04= 4000000;
-static u_int maxtim02= 2000000;
-static u_int maxtim_8=   30000;
-#if LONG_TIMING
-static u_int maxtim_data= 9000;
-#else
-static u_int maxtim_data= 3000;
-#endif /* LONG_TIMING */ 
-#if DISTRIBUTION
-static int n_retries=6;
-#else
-static int n_retries=6;
-#endif
-/*==========================================================================*/
-
-static int ndrives;
-static u_char drv_pattern[NR_SBPCD]={speed_auto,speed_auto,speed_auto,speed_auto};
-
-/*==========================================================================*/
-/*
- * drive space begins here (needed separate for each unit) 
- */
-static struct sbpcd_drive {
-       char drv_id;           /* "jumpered" drive ID or -1 */
-       char drv_sel;          /* drive select lines bits */
-       
-       char drive_model[9];
-       u_char firmware_version[4];
-       char f_eject;          /* auto-eject flag: 0 or 1 */
-       u_char *sbp_buf;       /* Pointer to internal data buffer,
-                                 space allocated during sbpcd_init() */
-       u_int sbp_bufsiz;      /* size of sbp_buf (# of frames) */
-       int sbp_first_frame;   /* First frame in buffer */
-       int sbp_last_frame;    /* Last frame in buffer  */
-       int sbp_read_frames;   /* Number of frames being read to buffer */
-       int sbp_current;       /* Frame being currently read */
-       
-       u_char mode;           /* read_mode: READ_M1, READ_M2, READ_SC, READ_AU */
-       u_char *aud_buf;       /* Pointer to audio data buffer,
-                                 space allocated during sbpcd_init() */
-       u_int sbp_audsiz;      /* size of aud_buf (# of raw frames) */
-       u_int drv_type;
-       u_char drv_options;
-       int status_bits;
-       u_char diskstate_flags;
-       u_char sense_byte;
-       
-       u_char CD_changed;
-       char open_count;
-       u_char error_byte;
-       
-       u_char f_multisession;
-       u_int lba_multi;
-       int first_session;
-       int last_session;
-       int track_of_last_session;
-       
-       u_char audio_state;
-       u_int pos_audio_start;
-       u_int pos_audio_end;
-       char vol_chan0;
-       u_char vol_ctrl0;
-       char vol_chan1;
-       u_char vol_ctrl1;
-#if 000 /* no supported drive has it */
-       char vol_chan2;
-       u_char vol_ctrl2;
-       char vol_chan3;
-       u_char vol_ctrl3;
-#endif /*000 */
-       u_char volume_control; /* TEAC on/off bits */
-       
-       u_char SubQ_ctl_adr;
-       u_char SubQ_trk;
-       u_char SubQ_pnt_idx;
-       u_int SubQ_run_tot;
-       u_int SubQ_run_trk;
-       u_char SubQ_whatisthis;
-       
-       u_char UPC_ctl_adr;
-       u_char UPC_buf[7];
-       
-       int frame_size;
-       int CDsize_frm;
-       
-       u_char xa_byte; /* 0x20: XA capabilities */
-       u_char n_first_track; /* binary */
-       u_char n_last_track; /* binary (not bcd), 0x01...0x63 */
-       u_int size_msf; /* time of whole CD, position of LeadOut track */
-       u_int size_blk;
-       
-       u_char TocEnt_nixbyte; /* em */
-       u_char TocEnt_ctl_adr;
-       u_char TocEnt_number;
-       u_char TocEnt_format; /* em */
-       u_int TocEnt_address;
-#ifdef SAFE_MIXED
-       char has_data;
-#endif /* SAFE_MIXED */ 
-       u_char ored_ctl_adr; /* to detect if CDROM contains data tracks */
-       
-       struct {
-               u_char nixbyte; /* em */
-               u_char ctl_adr; /* 0x4x: data, 0x0x: audio */
-               u_char number;
-               u_char format; /* em */ /* 0x00: lba, 0x01: msf */
-               u_int address;
-       } TocBuffer[MAX_TRACKS+1]; /* last entry faked */ 
-       
-       int in_SpinUp; /* CR-52x test flag */
-       int n_bytes; /* TEAC awaited response count */
-       u_char error_state, b3, b4; /* TEAC command error state */
-       u_char f_drv_error; /* TEAC command error flag */
-       u_char speed_byte;
-       int frmsiz;
-       u_char f_XA; /* 1: XA */
-       u_char type_byte; /* 0, 1, 3 */
-       u_char mode_xb_6;
-       u_char mode_yb_7;
-       u_char mode_xb_8;
-       u_char delay;
-       struct cdrom_device_info *sbpcd_infop;
-       struct gendisk *disk;
-} D_S[NR_SBPCD];
-
-static struct sbpcd_drive *current_drive = D_S;
-
-/*
- * drive space ends here (needed separate for each unit)
- */
-/*==========================================================================*/
-#if 0
-unsigned long cli_sti; /* for saving the processor flags */
-#endif
-/*==========================================================================*/
-static DEFINE_TIMER(delay_timer, mark_timeout_delay, 0, 0);
-static DEFINE_TIMER(data_timer, mark_timeout_data, 0, 0);
-#if 0
-static DEFINE_TIMER(audio_timer, mark_timeout_audio, 0, 0);
-#endif
-/*==========================================================================*/
-/*
- * DDI interface
- */
-static void msg(int level, const char *fmt, ...)
-{
-#if DISTRIBUTION
-#define MSG_LEVEL KERN_NOTICE
-#else
-#define MSG_LEVEL KERN_INFO
-#endif /* DISTRIBUTION */
-
-       char buf[256];
-       va_list args;
-       
-       if (!(sbpcd_debug&(1<<level))) return;
-       
-       msgnum++;
-       if (msgnum>99) msgnum=0;
-       va_start(args, fmt);
-       vsnprintf(buf, sizeof(buf), fmt, args);
-       va_end(args);
-       printk(MSG_LEVEL "%s-%d [%02d]:  %s", major_name, current_drive - D_S, msgnum, buf);
-#if KLOGD_PAUSE
-       sbp_sleep(KLOGD_PAUSE); /* else messages get lost */
-#endif /* KLOGD_PAUSE */ 
-       return;
-}
-/*==========================================================================*/
-/*
- * DDI interface: runtime trace bit pattern maintenance
- */
-static int sbpcd_dbg_ioctl(unsigned long arg, int level)
-{
-       switch(arg)
-       {
-       case 0: /* OFF */
-               sbpcd_debug = DBG_INF;
-               break;
-               
-       default:
-               if (arg>=128) sbpcd_debug &= ~(1<<(arg-128));
-               else sbpcd_debug |= (1<<arg);
-       }
-       return (arg);
-}
-/*==========================================================================*/
-static void mark_timeout_delay(u_long i)
-{
-       timed_out_delay=1;
-#if 0
-       msg(DBG_TIM,"delay timer expired.\n");
-#endif
-}
-/*==========================================================================*/
-static void mark_timeout_data(u_long i)
-{
-       timed_out_data=1;
-#if 0
-       msg(DBG_TIM,"data timer expired.\n");
-#endif
-}
-/*==========================================================================*/
-#if 0
-static void mark_timeout_audio(u_long i)
-{
-       timed_out_audio=1;
-#if 0
-       msg(DBG_TIM,"audio timer expired.\n");
-#endif
-}
-#endif
-/*==========================================================================*/
-/*
- * Wait a little while (used for polling the drive).
- */
-static void sbp_sleep(u_int time)
-{
-       sti();
-       schedule_timeout_interruptible(time);
-       sti();
-}
-/*==========================================================================*/
-#define RETURN_UP(rc) {up(&ioctl_read_sem); return(rc);}
-/*==========================================================================*/
-/*
- *  convert logical_block_address to m-s-f_number (3 bytes only)
- */
-static INLINE void lba2msf(int lba, u_char *msf)
-{
-       lba += CD_MSF_OFFSET;
-       msf[0] = lba / (CD_SECS*CD_FRAMES);
-       lba %= CD_SECS*CD_FRAMES;
-       msf[1] = lba / CD_FRAMES;
-       msf[2] = lba % CD_FRAMES;
-}
-/*==========================================================================*/
-/*==========================================================================*/
-/*
- *  convert msf-bin to msf-bcd
- */
-static INLINE void bin2bcdx(u_char *p)  /* must work only up to 75 or 99 */
-{
-       *p=((*p/10)<<4)|(*p%10);
-}
-/*==========================================================================*/
-static INLINE u_int blk2msf(u_int blk)
-{
-       MSF msf;
-       u_int mm;
-       
-       msf.c[3] = 0;
-       msf.c[2] = (blk + CD_MSF_OFFSET) / (CD_SECS * CD_FRAMES);
-       mm = (blk + CD_MSF_OFFSET) % (CD_SECS * CD_FRAMES);
-       msf.c[1] = mm / CD_FRAMES;
-       msf.c[0] = mm % CD_FRAMES;
-       return (msf.n);
-}
-/*==========================================================================*/
-static INLINE u_int make16(u_char rh, u_char rl)
-{
-       return ((rh<<8)|rl);
-}
-/*==========================================================================*/
-static INLINE u_int make32(u_int rh, u_int rl)
-{
-       return ((rh<<16)|rl);
-}
-/*==========================================================================*/
-static INLINE u_char swap_nibbles(u_char i)
-{
-       return ((i<<4)|(i>>4));
-}
-/*==========================================================================*/
-static INLINE u_char byt2bcd(u_char i)
-{
-       return (((i/10)<<4)+i%10);
-}
-/*==========================================================================*/
-static INLINE u_char bcd2bin(u_char bcd)
-{
-       return ((bcd>>4)*10+(bcd&0x0F));
-}
-/*==========================================================================*/
-static INLINE int msf2blk(int msfx)
-{
-       MSF msf;
-       int i;
-       
-       msf.n=msfx;
-       i=(msf.c[2] * CD_SECS + msf.c[1]) * CD_FRAMES + msf.c[0] - CD_MSF_OFFSET;
-       if (i<0) return (0);
-       return (i);
-}
-/*==========================================================================*/
-/*
- *  convert m-s-f_number (3 bytes only) to logical_block_address 
- */
-static INLINE int msf2lba(u_char *msf)
-{
-       int i;
-       
-       i=(msf[0] * CD_SECS + msf[1]) * CD_FRAMES + msf[2] - CD_MSF_OFFSET;
-       if (i<0) return (0);
-       return (i);
-}
-/*==========================================================================*/
-/* evaluate cc_ReadError code */ 
-static int sta2err(int sta)
-{
-       if (famT_drive)
-       {
-               if (sta==0x00) return (0);
-               if (sta==0x01) return (-604); /* CRC error */
-               if (sta==0x02) return (-602); /* drive not ready */
-               if (sta==0x03) return (-607); /* unknown media */
-               if (sta==0x04) return (-612); /* general failure */
-               if (sta==0x05) return (0);
-               if (sta==0x06) return (-ERR_DISKCHANGE); /* disk change */
-               if (sta==0x0b) return (-612); /* general failure */
-               if (sta==0xff) return (-612); /* general failure */
-               return (0);
-       }
-       else
-       {
-               if (sta<=2) return (sta);
-               if (sta==0x05) return (-604); /* CRC error */
-               if (sta==0x06) return (-606); /* seek error */
-               if (sta==0x0d) return (-606); /* seek error */
-               if (sta==0x0e) return (-603); /* unknown command */
-               if (sta==0x14) return (-603); /* unknown command */
-               if (sta==0x0c) return (-611); /* read fault */
-               if (sta==0x0f) return (-611); /* read fault */
-               if (sta==0x10) return (-611); /* read fault */
-               if (sta>=0x16) return (-612); /* general failure */
-               if (sta==0x11) return (-ERR_DISKCHANGE); /* disk change (LCS: removed) */
-               if (famL_drive)
-                       if (sta==0x12) return (-ERR_DISKCHANGE); /* disk change (inserted) */
-               return (-602); /* drive not ready */
-       }
-}
-/*==========================================================================*/
-static INLINE void clr_cmdbuf(void)
-{
-       int i;
-       
-       for (i=0;i<10;i++) drvcmd[i]=0;
-       cmd_type=0;
-}
-/*==========================================================================*/
-static void flush_status(void)
-{
-       int i;
-       
-       sbp_sleep(15*HZ/10);
-       for (i=maxtim_data;i!=0;i--) inb(CDi_status);
-}
-/*====================================================================*/
-/*
- * CDi status loop for Teac CD-55A (Rob Riggs)
- *
- * This is needed because for some strange reason
- * the CD-55A can take a real long time to give a
- * status response. This seems to happen after we
- * issue a READ command where a long seek is involved.
- *
- * I tried to ensure that we get max throughput with
- * minimal busy waiting. We busy wait at first, then
- * "switch gears" and start sleeping. We sleep for
- * longer periods of time the longer we wait.
- *
- */
-static int CDi_stat_loop_T(void)
-{
-       int     i, gear=1;
-       u_long  timeout_1, timeout_2, timeout_3, timeout_4;
-
-       timeout_1 = jiffies + HZ / 50;  /* sbp_sleep(0) for a short period */
-       timeout_2 = jiffies + HZ / 5;   /* nap for no more than 200ms */
-       timeout_3 = jiffies + 5 * HZ;   /* sleep for up to 5s */
-       timeout_4 = jiffies + 45 * HZ;  /* long sleep for up to 45s. */
-       do
-          {
-            i = inb(CDi_status);
-            if (!(i&s_not_data_ready)) return (i);
-            if (!(i&s_not_result_ready)) return (i);
-            switch(gear)
-              {
-              case 4:
-                sbp_sleep(HZ);
-                if (time_after(jiffies, timeout_4)) gear++;
-                msg(DBG_TEA, "CDi_stat_loop_T: long sleep active.\n");
-                break;
-              case 3:
-                sbp_sleep(HZ/10);
-                if (time_after(jiffies, timeout_3)) gear++;
-                break;
-              case 2:
-                sbp_sleep(HZ/100);
-                if (time_after(jiffies, timeout_2)) gear++;
-                break;
-              case 1:
-                sbp_sleep(0);
-                if (time_after(jiffies, timeout_1)) gear++;
-              }
-          } while (gear < 5);
-       return -1;
-}
-/*==========================================================================*/
-static int CDi_stat_loop(void)
-{
-       int i,j;
-       
-       for(timeout = jiffies + 10*HZ, i=maxtim_data; time_before(jiffies, timeout); )
-       {
-               for ( ;i!=0;i--)
-               {
-                       j=inb(CDi_status);
-                       if (!(j&s_not_data_ready)) return (j);
-                       if (!(j&s_not_result_ready)) return (j);
-                       if (fam0L_drive) if (j&s_attention) return (j);
-               }
-               sbp_sleep(1);
-               i = 1;
-       }
-       msg(DBG_LCS,"CDi_stat_loop failed in line %d\n", __LINE__);
-       return (-1);
-}
-/*==========================================================================*/
-#if 00000
-/*==========================================================================*/
-static int tst_DataReady(void)
-{
-       int i;
-       
-       i=inb(CDi_status);
-       if (i&s_not_data_ready) return (0);
-       return (1);
-}
-/*==========================================================================*/
-static int tst_ResultReady(void)
-{
-       int i;
-       
-       i=inb(CDi_status);
-       if (i&s_not_result_ready) return (0);
-       return (1);
-}
-/*==========================================================================*/
-static int tst_Attention(void)
-{
-       int i;
-       
-       i=inb(CDi_status);
-       if (i&s_attention) return (1);
-       return (0);
-}
-/*==========================================================================*/
-#endif
-/*==========================================================================*/
-static int ResponseInfo(void)
-{
-       int i,j,st=0;
-       u_long timeout;
-       
-       for (i=0,timeout=jiffies+HZ;i<response_count;i++) 
-       {
-               for (j=maxtim_data; ; )
-               {
-                       for ( ;j!=0;j-- )
-                       {
-                               st=inb(CDi_status);
-                               if (!(st&s_not_result_ready)) break;
-                       }
-                       if ((j!=0)||time_after_eq(jiffies, timeout)) break;
-                       sbp_sleep(1);
-                       j = 1;
-               }
-               if (time_after_eq(jiffies, timeout)) break;
-               infobuf[i]=inb(CDi_info);
-       }
-#if 000
-       while (!(inb(CDi_status)&s_not_result_ready))
-       {
-               infobuf[i++]=inb(CDi_info);
-       }
-       j=i-response_count;
-       if (j>0) msg(DBG_INF,"ResponseInfo: got %d trailing bytes.\n",j);
-#endif /* 000 */
-       for (j=0;j<i;j++)
-               sprintf(&msgbuf[j*3]," %02X",infobuf[j]);
-       msgbuf[j*3]=0;
-       msg(DBG_CMD,"ResponseInfo:%s (%d,%d)\n",msgbuf,response_count,i);
-       j=response_count-i;
-       if (j>0) return (-j);
-       else return (i);
-}
-/*==========================================================================*/
-static void EvaluateStatus(int st)
-{
-       current_drive->status_bits=0;
-       if (fam1_drive) current_drive->status_bits=st|p_success;
-       else if (fam0_drive)
-       {
-               if (st&p_caddin_old) current_drive->status_bits |= p_door_closed|p_caddy_in;
-               if (st&p_spinning) current_drive->status_bits |= p_spinning;
-               if (st&p_check) current_drive->status_bits |= p_check;
-               if (st&p_success_old) current_drive->status_bits |= p_success;
-               if (st&p_busy_old) current_drive->status_bits |= p_busy_new;
-               if (st&p_disk_ok) current_drive->status_bits |= p_disk_ok;
-       }
-       else if (famLV_drive)
-       {
-               current_drive->status_bits |= p_success;
-               if (st&p_caddin_old) current_drive->status_bits |= p_disk_ok|p_caddy_in;
-               if (st&p_spinning) current_drive->status_bits |= p_spinning;
-               if (st&p_check) current_drive->status_bits |= p_check;
-               if (st&p_busy_old) current_drive->status_bits |= p_busy_new;
-               if (st&p_lcs_door_closed) current_drive->status_bits |= p_door_closed;
-               if (st&p_lcs_door_locked) current_drive->status_bits |= p_door_locked;
-       }
-       else if (fam2_drive)
-       {
-               current_drive->status_bits |= p_success;
-               if (st&p2_check) current_drive->status_bits |= p1_check;
-               if (st&p2_door_closed) current_drive->status_bits |= p1_door_closed;
-               if (st&p2_disk_in) current_drive->status_bits |= p1_disk_in;
-               if (st&p2_busy1) current_drive->status_bits |= p1_busy;
-               if (st&p2_busy2) current_drive->status_bits |= p1_busy;
-               if (st&p2_spinning) current_drive->status_bits |= p1_spinning;
-               if (st&p2_door_locked) current_drive->status_bits |= p1_door_locked;
-               if (st&p2_disk_ok) current_drive->status_bits |= p1_disk_ok;
-       }
-       else if (famT_drive)
-       {
-               return; /* still needs to get coded */
-               current_drive->status_bits |= p_success;
-               if (st&p2_check) current_drive->status_bits |= p1_check;
-               if (st&p2_door_closed) current_drive->status_bits |= p1_door_closed;
-               if (st&p2_disk_in) current_drive->status_bits |= p1_disk_in;
-               if (st&p2_busy1) current_drive->status_bits |= p1_busy;
-               if (st&p2_busy2) current_drive->status_bits |= p1_busy;
-               if (st&p2_spinning) current_drive->status_bits |= p1_spinning;
-               if (st&p2_door_locked) current_drive->status_bits |= p1_door_locked;
-               if (st&p2_disk_ok) current_drive->status_bits |= p1_disk_ok;
-       }
-       return;
-}
-/*==========================================================================*/
-static int cmd_out_T(void);
-
-static int get_state_T(void)
-{
-       int i;
-
-       clr_cmdbuf();
-       current_drive->n_bytes=1;
-       drvcmd[0]=CMDT_STATUS;
-       i=cmd_out_T();
-       if (i>=0) i=infobuf[0];
-       else
-       {
-               msg(DBG_TEA,"get_state_T error %d\n", i);
-               return (i);
-       }
-       if (i>=0)
-               /* 2: closed, disk in */
-               current_drive->status_bits=p1_door_closed|p1_disk_in|p1_spinning|p1_disk_ok;
-       else if (current_drive->error_state==6)
-       {
-               /* 3: closed, disk in, changed ("06 xx xx") */
-               current_drive->status_bits=p1_door_closed|p1_disk_in;
-               current_drive->CD_changed=0xFF;
-               current_drive->diskstate_flags &= ~toc_bit;
-       }
-       else if ((current_drive->error_state!=2)||(current_drive->b3!=0x3A)||(current_drive->b4==0x00))
-       {
-               /* 1: closed, no disk ("xx yy zz"or "02 3A 00") */
-               current_drive->status_bits=p1_door_closed;
-               current_drive->open_count=0;
-       }
-       else if (current_drive->b4==0x01)
-       {
-               /* 0: open ("02 3A 01") */
-               current_drive->status_bits=0;
-               current_drive->open_count=0;
-       }
-       else
-       {
-               /* 1: closed, no disk ("02 3A xx") */
-               current_drive->status_bits=p1_door_closed;
-               current_drive->open_count=0;
-       }
-       return (current_drive->status_bits);
-}
-/*==========================================================================*/
-static int ResponseStatus(void)
-{
-       int i,j;
-       u_long timeout;
-       
-       msg(DBG_STA,"doing ResponseStatus...\n");
-       if (famT_drive) return (get_state_T());
-       if (flags_cmd_out & f_respo3) timeout = jiffies;
-       else if (flags_cmd_out & f_respo2) timeout = jiffies + 16*HZ;
-       else timeout = jiffies + 4*HZ;
-       j=maxtim_8;
-       do
-       {
-               for ( ;j!=0;j--)
-               { 
-                       i=inb(CDi_status);
-                       if (!(i&s_not_result_ready)) break;
-               }
-               if ((j!=0)||time_after(jiffies, timeout)) break;
-               sbp_sleep(1);
-               j = 1;
-       }
-       while (1);
-       if (j==0) 
-       {
-               if ((flags_cmd_out & f_respo3) == 0)
-                       msg(DBG_STA,"ResponseStatus: timeout.\n");
-               current_drive->status_bits=0;
-               return (-401);
-       }
-       i=inb(CDi_info);
-       msg(DBG_STA,"ResponseStatus: response %02X.\n", i);
-       EvaluateStatus(i);
-       msg(DBG_STA,"status_bits=%02X, i=%02X\n",current_drive->status_bits,i);
-       return (current_drive->status_bits);
-}
-/*==========================================================================*/
-static void cc_ReadStatus(void)
-{
-       int i;
-       
-       msg(DBG_STA,"giving cc_ReadStatus command\n");
-       if (famT_drive) return;
-       SBPCD_CLI;
-       if (fam0LV_drive) OUT(CDo_command,CMD0_STATUS);
-       else if (fam1_drive) OUT(CDo_command,CMD1_STATUS);
-       else if (fam2_drive) OUT(CDo_command,CMD2_STATUS);
-       if (!fam0LV_drive) for (i=0;i<6;i++) OUT(CDo_command,0);
-       SBPCD_STI;
-}
-/*==========================================================================*/
-static int cc_ReadError(void)
-{
-       int i;
-
-       clr_cmdbuf();
-       msg(DBG_ERR,"giving cc_ReadError command.\n");
-       if (fam1_drive)
-       {
-               drvcmd[0]=CMD1_READ_ERR;
-               response_count=8;
-               flags_cmd_out=f_putcmd|f_ResponseStatus;
-       }
-       else if (fam0LV_drive)
-       {
-               drvcmd[0]=CMD0_READ_ERR;
-               response_count=6;
-               if (famLV_drive)
-                       flags_cmd_out=f_putcmd;
-               else
-                       flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus;
-       }
-       else if (fam2_drive)
-       {
-               drvcmd[0]=CMD2_READ_ERR;
-               response_count=6;
-               flags_cmd_out=f_putcmd;
-       }
-       else if (famT_drive)
-       {
-               response_count=5;
-               drvcmd[0]=CMDT_READ_ERR;
-       }
-       i=cmd_out();
-       current_drive->error_byte=0;
-       msg(DBG_ERR,"cc_ReadError: cmd_out(CMDx_READ_ERR) returns %d (%02X)\n",i,i);
-       if (i<0) return (i);
-       if (fam0V_drive) i=1;
-       else i=2;
-       current_drive->error_byte=infobuf[i];
-       msg(DBG_ERR,"cc_ReadError: infobuf[%d] is %d (%02X)\n",i,current_drive->error_byte,current_drive->error_byte);
-       i=sta2err(infobuf[i]);
-        if (i==-ERR_DISKCHANGE)
-        {
-                current_drive->CD_changed=0xFF;
-                current_drive->diskstate_flags &= ~toc_bit;
-        }
-       return (i);
-}
-/*==========================================================================*/
-static int cc_DriveReset(void);
-
-static int cmd_out_T(void)
-{
-#undef CMDT_TRIES
-#define CMDT_TRIES 1000
-#define TEST_FALSE_FF 1
-
-       int i, j, l=0, m, ntries;
-       unsigned long flags;
-
-       current_drive->error_state=0;
-       current_drive->b3=0;
-       current_drive->b4=0;
-       current_drive->f_drv_error=0;
-       for (i=0;i<10;i++) sprintf(&msgbuf[i*3]," %02X",drvcmd[i]);
-       msgbuf[i*3]=0;
-       msg(DBG_CMD,"cmd_out_T:%s\n",msgbuf);
-
-       OUT(CDo_sel_i_d,0);
-       OUT(CDo_enable,current_drive->drv_sel);
-       i=inb(CDi_status);
-       do_16bit=0;
-       if ((f_16bit)&&(!(i&0x80)))
-       {
-               do_16bit=1;
-               msg(DBG_TEA,"cmd_out_T: do_16bit set.\n");
-       }
-       if (!(i&s_not_result_ready))
-       do
-       {
-               j=inb(CDi_info);
-               i=inb(CDi_status);
-               sbp_sleep(0);
-               msg(DBG_TEA,"cmd_out_T: spurious !s_not_result_ready. (%02X)\n", j);
-       }
-       while (!(i&s_not_result_ready));
-       save_flags(flags); cli();
-       for (i=0;i<10;i++) OUT(CDo_command,drvcmd[i]);
-       restore_flags(flags);
-       for (ntries=CMDT_TRIES;ntries>0;ntries--)
-       {
-               if (drvcmd[0]==CMDT_READ_VER) sbp_sleep(HZ); /* fixme */
-#if 01
-               OUT(CDo_sel_i_d,1);
-#endif /* 01 */
-               if (teac==2)
-                  {
-                    if ((i=CDi_stat_loop_T()) == -1) break;
-                  }
-               else
-                  {
-#if 0
-                    OUT(CDo_sel_i_d,1);
-#endif /* 0 */ 
-                    i=inb(CDi_status);
-                  }
-               if (!(i&s_not_data_ready)) /* f.e. CMDT_DISKINFO */
-               {
-                       OUT(CDo_sel_i_d,1);
-                       if (drvcmd[0]==CMDT_READ) return (0); /* handled elsewhere */
-                       if (drvcmd[0]==CMDT_DISKINFO)
-                       {
-                               l=0;
-                               do
-                                {
-                                        if (do_16bit)
-                                        {
-                                                i=inw(CDi_data);
-                                                infobuf[l++]=i&0x0ff;
-                                                infobuf[l++]=i>>8;
-#if TEST_FALSE_FF
-                                                if ((l==2)&&(infobuf[0]==0x0ff))
-                                                {
-                                                        infobuf[0]=infobuf[1];
-                                                        l=1;
-                                                        msg(DBG_TEA,"cmd_out_T: do_16bit: false first byte!\n");
-                                                }
-#endif /* TEST_FALSE_FF */ 
-                                        }
-                                        else infobuf[l++]=inb(CDi_data);
-                                        i=inb(CDi_status);
-                                }
-                               while (!(i&s_not_data_ready));
-                               for (j=0;j<l;j++) sprintf(&msgbuf[j*3]," %02X",infobuf[j]);
-                               msgbuf[j*3]=0;
-                               msg(DBG_CMD,"cmd_out_T data response:%s\n", msgbuf);
-                       }
-                       else
-                       {
-                               msg(DBG_TEA,"cmd_out_T: data response with cmd_%02X!\n",
-                                    drvcmd[0]);
-                               j=0;
-                               do
-                               {
-                                        if (do_16bit) i=inw(CDi_data);
-                                        else i=inb(CDi_data);
-                                        j++;
-                                        i=inb(CDi_status);
-                               }
-                               while (!(i&s_not_data_ready));
-                               msg(DBG_TEA,"cmd_out_T: data response: discarded %d bytes/words.\n", j);
-                               fatal_err++;
-                       }
-               }
-               i=inb(CDi_status);
-               if (!(i&s_not_result_ready))
-               {
-                       OUT(CDo_sel_i_d,0);
-                       if (drvcmd[0]==CMDT_DISKINFO) m=l;
-                       else m=0;
-                       do
-                       {
-                               infobuf[m++]=inb(CDi_info);
-                               i=inb(CDi_status);
-                       }
-                       while (!(i&s_not_result_ready));
-                       for (j=0;j<m;j++) sprintf(&msgbuf[j*3]," %02X",infobuf[j]);
-                       msgbuf[j*3]=0;
-                       msg(DBG_CMD,"cmd_out_T info response:%s\n", msgbuf);
-                       if (drvcmd[0]==CMDT_DISKINFO)
-                        {
-                                infobuf[0]=infobuf[l];
-                                if (infobuf[0]!=0x02) return (l); /* data length */
-                        }
-                       else if (infobuf[0]!=0x02) return (m); /* info length */
-                       do
-                       {
-                               ++recursion;
-                               if (recursion>1) msg(DBG_TEA,"cmd_out_T READ_ERR recursion (%02X): %d !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n", drvcmd[0], recursion);
-                               clr_cmdbuf();
-                               drvcmd[0]=CMDT_READ_ERR;
-                               j=cmd_out_T(); /* !!! recursive here !!! */
-                               --recursion;
-                               sbp_sleep(1);
-                       }
-                       while (j<0);
-                       current_drive->error_state=infobuf[2];
-                       current_drive->b3=infobuf[3];
-                       current_drive->b4=infobuf[4];
-                       if (current_drive->f_drv_error)
-                       {
-                               current_drive->f_drv_error=0;
-                               cc_DriveReset();
-                               current_drive->error_state=2;
-                       }
-                       return (-current_drive->error_state-400);
-               }
-               if (drvcmd[0]==CMDT_READ) return (0); /* handled elsewhere */
-               if ((teac==0)||(ntries<(CMDT_TRIES-5))) sbp_sleep(HZ/10);
-               else sbp_sleep(HZ/100);
-               if (ntries>(CMDT_TRIES-50)) continue;
-               msg(DBG_TEA,"cmd_out_T: next CMDT_TRIES (%02X): %d.\n", drvcmd[0], ntries-1);
-       }
-       current_drive->f_drv_error=1;
-       cc_DriveReset();
-       current_drive->error_state=2;
-       return (-99);
-}
-/*==========================================================================*/
-static int cmd_out(void)
-{
-       int i=0;
-       
-       if (famT_drive) return(cmd_out_T());
-       
-       if (flags_cmd_out&f_putcmd)
-       { 
-               unsigned long flags;
-               for (i=0;i<7;i++)
-                       sprintf(&msgbuf[i*3], " %02X", drvcmd[i]);
-               msgbuf[i*3]=0;
-               msg(DBG_CMD,"cmd_out:%s\n", msgbuf);
-               save_flags(flags); cli();
-               for (i=0;i<7;i++) OUT(CDo_command,drvcmd[i]);
-               restore_flags(flags);
-       }
-       if (response_count!=0)
-       {
-               if (cmd_type!=0)
-               {
-                       if (sbpro_type==1) OUT(CDo_sel_i_d,1);
-                       msg(DBG_INF,"misleaded to try ResponseData.\n");
-                       if (sbpro_type==1) OUT(CDo_sel_i_d,0);
-                       return (-22);
-               }
-               else i=ResponseInfo();
-               if (i<0) return (i);
-       }
-       if (current_drive->in_SpinUp) msg(DBG_SPI,"in_SpinUp: to CDi_stat_loop.\n");
-       if (flags_cmd_out&f_lopsta)
-       {
-               i=CDi_stat_loop();
-               if ((i<0)||!(i&s_attention)) return (-8);
-       }
-       if (!(flags_cmd_out&f_getsta)) goto LOC_229;
-       
- LOC_228:
-       if (current_drive->in_SpinUp) msg(DBG_SPI,"in_SpinUp: to cc_ReadStatus.\n");
-       cc_ReadStatus();
-       
- LOC_229:
-       if (flags_cmd_out&f_ResponseStatus) 
-       {
-               if (current_drive->in_SpinUp) msg(DBG_SPI,"in_SpinUp: to ResponseStatus.\n");
-               i=ResponseStatus();
-               /* builds status_bits, returns orig. status or p_busy_new */
-               if (i<0) return (i);
-               if (flags_cmd_out&(f_bit1|f_wait_if_busy))
-               {
-                       if (!st_check)
-                       {
-                               if ((flags_cmd_out&f_bit1)&&(i&p_success)) goto LOC_232;
-                               if ((!(flags_cmd_out&f_wait_if_busy))||(!st_busy)) goto LOC_228;
-                       }
-               }
-       }
- LOC_232:
-       if (!(flags_cmd_out&f_obey_p_check)) return (0);
-       if (!st_check) return (0);
-       if (current_drive->in_SpinUp) msg(DBG_SPI,"in_SpinUp: to cc_ReadError.\n");
-       i=cc_ReadError();
-       if (current_drive->in_SpinUp) msg(DBG_SPI,"in_SpinUp: to cmd_out OK.\n");
-       msg(DBG_000,"cmd_out: cc_ReadError=%d\n", i);
-       return (i);
-}
-/*==========================================================================*/
-static int cc_Seek(u_int pos, char f_blk_msf)
-{
-       int i;
-       
-  clr_cmdbuf();
-       if (f_blk_msf>1) return (-3);
-       if (fam0V_drive)
-       {
-               drvcmd[0]=CMD0_SEEK;
-               if (f_blk_msf==1) pos=msf2blk(pos);
-               drvcmd[2]=(pos>>16)&0x00FF;
-               drvcmd[3]=(pos>>8)&0x00FF;
-               drvcmd[4]=pos&0x00FF;
-               if (fam0_drive)
-                 flags_cmd_out = f_putcmd | f_respo2 | f_lopsta | f_getsta |
-                       f_ResponseStatus | f_obey_p_check | f_bit1;
-               else
-                 flags_cmd_out = f_putcmd;
-       }
-       else if (fam1L_drive)
-       {
-               drvcmd[0]=CMD1_SEEK; /* same as CMD1_ and CMDL_ */
-               if (f_blk_msf==0) pos=blk2msf(pos);
-               drvcmd[1]=(pos>>16)&0x00FF;
-               drvcmd[2]=(pos>>8)&0x00FF;
-               drvcmd[3]=pos&0x00FF;
-               if (famL_drive)
-                       flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
-               else
-                       flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
-       }
-       else if (fam2_drive)
-       {
-               drvcmd[0]=CMD2_SEEK;
-               if (f_blk_msf==0) pos=blk2msf(pos);
-               drvcmd[2]=(pos>>24)&0x00FF;
-               drvcmd[3]=(pos>>16)&0x00FF;
-               drvcmd[4]=(pos>>8)&0x00FF;
-               drvcmd[5]=pos&0x00FF;
-               flags_cmd_out=f_putcmd|f_ResponseStatus;
-       }
-       else if (famT_drive)
-       {
-               drvcmd[0]=CMDT_SEEK;
-               if (f_blk_msf==1) pos=msf2blk(pos);
-               drvcmd[2]=(pos>>24)&0x00FF;
-               drvcmd[3]=(pos>>16)&0x00FF;
-               drvcmd[4]=(pos>>8)&0x00FF;
-               drvcmd[5]=pos&0x00FF;
-               current_drive->n_bytes=1;
-       }
-       response_count=0;
-       i=cmd_out();
-       return (i);
-}
-/*==========================================================================*/
-static int cc_SpinUp(void)
-{
-       int i;
-       
-       msg(DBG_SPI,"SpinUp.\n");
-       current_drive->in_SpinUp = 1;
-       clr_cmdbuf();
-       if (fam0LV_drive)
-       {
-               drvcmd[0]=CMD0_SPINUP;
-               if (fam0L_drive)
-                 flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|
-                   f_ResponseStatus|f_obey_p_check|f_bit1;
-               else
-                 flags_cmd_out=f_putcmd;
-       }
-       else if (fam1_drive)
-       {
-               drvcmd[0]=CMD1_SPINUP;
-               flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
-       }
-       else if (fam2_drive)
-       {
-               drvcmd[0]=CMD2_TRAY_CTL;
-               drvcmd[4]=0x01; /* "spinup" */
-               flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
-       }
-       else if (famT_drive)
-       {
-               drvcmd[0]=CMDT_TRAY_CTL;
-               drvcmd[4]=0x03; /* "insert", it hopefully spins the drive up */
-       }
-       response_count=0;
-       i=cmd_out();
-       current_drive->in_SpinUp = 0;
-       return (i);
-}
-/*==========================================================================*/
-static int cc_SpinDown(void)
-{
-       int i;
-       
-       if (fam0_drive) return (0);
-       clr_cmdbuf();
-       response_count=0;
-       if (fam1_drive)
-       {
-               drvcmd[0]=CMD1_SPINDOWN;
-               flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
-       }
-       else if (fam2_drive)
-       {
-               drvcmd[0]=CMD2_TRAY_CTL;
-               drvcmd[4]=0x02; /* "eject" */
-               flags_cmd_out=f_putcmd|f_ResponseStatus;
-       }
-       else if (famL_drive)
-       {
-               drvcmd[0]=CMDL_SPINDOWN;
-               drvcmd[1]=1;
-               flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
-       }
-       else if (famV_drive)
-       {
-               drvcmd[0]=CMDV_SPINDOWN;
-               flags_cmd_out=f_putcmd;
-       }
-       else if (famT_drive)
-       {
-               drvcmd[0]=CMDT_TRAY_CTL;
-               drvcmd[4]=0x02; /* "eject" */
-       }
-       i=cmd_out();
-       return (i);
-}
-/*==========================================================================*/
-static int cc_get_mode_T(void)
-{
-       int i;
-       
-       clr_cmdbuf();
-       response_count=10;
-       drvcmd[0]=CMDT_GETMODE;
-       drvcmd[4]=response_count;
-       i=cmd_out_T();
-       return (i);
-}
-/*==========================================================================*/
-static int cc_set_mode_T(void)
-{
-       int i;
-       
-       clr_cmdbuf();
-       response_count=1;
-       drvcmd[0]=CMDT_SETMODE;
-       drvcmd[1]=current_drive->speed_byte;
-       drvcmd[2]=current_drive->frmsiz>>8;
-       drvcmd[3]=current_drive->frmsiz&0x0FF;
-       drvcmd[4]=current_drive->f_XA; /* 1: XA */
-       drvcmd[5]=current_drive->type_byte; /* 0, 1, 3 */
-       drvcmd[6]=current_drive->mode_xb_6;
-       drvcmd[7]=current_drive->mode_yb_7|current_drive->volume_control;
-       drvcmd[8]=current_drive->mode_xb_8;
-       drvcmd[9]=current_drive->delay;
-       i=cmd_out_T();
-       return (i);
-}
-/*==========================================================================*/
-static int cc_prep_mode_T(void)
-{
-       int i, j;
-       
-       i=cc_get_mode_T();
-       if (i<0) return (i);
-       for (i=0;i<10;i++)
-               sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
-       msgbuf[i*3]=0;
-       msg(DBG_TEA,"CMDT_GETMODE:%s\n", msgbuf);
-       current_drive->speed_byte=0x02; /* 0x02: auto quad, 0x82: quad, 0x81: double, 0x80: single */
-       current_drive->frmsiz=make16(infobuf[2],infobuf[3]);
-       current_drive->f_XA=infobuf[4];
-       if (current_drive->f_XA==0) current_drive->type_byte=0;
-       else current_drive->type_byte=1;
-       current_drive->mode_xb_6=infobuf[6];
-       current_drive->mode_yb_7=1;
-       current_drive->mode_xb_8=infobuf[8];
-       current_drive->delay=0; /* 0, 1, 2, 3 */
-       j=cc_set_mode_T();
-       i=cc_get_mode_T();
-       for (i=0;i<10;i++)
-               sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
-       msgbuf[i*3]=0;
-       msg(DBG_TEA,"CMDT_GETMODE:%s\n", msgbuf);
-       return (j);
-}
-/*==========================================================================*/
-static int cc_SetSpeed(u_char speed, u_char x1, u_char x2)
-{
-       int i;
-       
-       if (fam0LV_drive) return (0);
-       clr_cmdbuf();
-       response_count=0;
-       if (fam1_drive)
-       {
-               drvcmd[0]=CMD1_SETMODE;
-               drvcmd[1]=0x03;
-               drvcmd[2]=speed;
-               drvcmd[3]=x1;
-               drvcmd[4]=x2;
-               flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
-       }
-       else if (fam2_drive)
-       {
-               drvcmd[0]=CMD2_SETSPEED;
-               if (speed&speed_auto)
-               {
-                       drvcmd[2]=0xFF;
-                       drvcmd[3]=0xFF;
-               }
-               else
-               {
-                       drvcmd[2]=0;
-                       drvcmd[3]=150;
-               }
-               flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
-       }
-       else if (famT_drive)
-       {
-               return (0);
-       }
-       i=cmd_out();
-       return (i);
-}
-/*==========================================================================*/
-static int cc_SetVolume(void)
-{
-       int i;
-       u_char channel0,channel1,volume0,volume1;
-       u_char control0,value0,control1,value1;
-       
-       current_drive->diskstate_flags &= ~volume_bit;
-       clr_cmdbuf();
-       channel0=current_drive->vol_chan0;
-       volume0=current_drive->vol_ctrl0;
-       channel1=control1=current_drive->vol_chan1;
-       volume1=value1=current_drive->vol_ctrl1;
-       control0=value0=0;
-       
-       if (famV_drive) return (0);
-
-       if (((current_drive->drv_options&audio_mono)!=0)&&(current_drive->drv_type>=drv_211))
-       {
-               if ((volume0!=0)&&(volume1==0))
-               {
-                       volume1=volume0;
-                       channel1=channel0;
-               }
-               else if ((volume0==0)&&(volume1!=0))
-               {
-                       volume0=volume1;
-                       channel0=channel1;
-               }
-       }
-       if (channel0>1)
-       {
-               channel0=0;
-               volume0=0;
-       }
-       if (channel1>1)
-       {
-               channel1=1;
-               volume1=0;
-       }
-       
-       if (fam1_drive)
-       {
-               control0=channel0+1;
-               control1=channel1+1;
-               value0=(volume0>volume1)?volume0:volume1;
-               value1=value0;
-               if (volume0==0) control0=0;
-               if (volume1==0) control1=0;
-               drvcmd[0]=CMD1_SETMODE;
-               drvcmd[1]=0x05;
-               drvcmd[3]=control0;
-               drvcmd[4]=value0;
-               drvcmd[5]=control1;
-               drvcmd[6]=value1;
-               flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
-       }
-       else if (fam2_drive)
-       {
-               control0=channel0+1;
-               control1=channel1+1;
-               value0=(volume0>volume1)?volume0:volume1;
-               value1=value0;
-               if (volume0==0) control0=0;
-               if (volume1==0) control1=0;
-               drvcmd[0]=CMD2_SETMODE;
-               drvcmd[1]=0x0E;
-               drvcmd[3]=control0;
-               drvcmd[4]=value0;
-               drvcmd[5]=control1;
-               drvcmd[6]=value1;
-               flags_cmd_out=f_putcmd|f_ResponseStatus;
-       }
-       else if (famL_drive)
-       {
-               if ((volume0==0)||(channel0!=0)) control0 |= 0x80;
-               if ((volume1==0)||(channel1!=1)) control0 |= 0x40;
-               if (volume0|volume1) value0=0x80;
-               drvcmd[0]=CMDL_SETMODE;
-               drvcmd[1]=0x03;
-               drvcmd[4]=control0;
-               drvcmd[5]=value0;
-               flags_cmd_out=f_putcmd|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
-       }
-       else if (fam0_drive) /* different firmware levels */
-       {
-               if (current_drive->drv_type>=drv_300)
-               {
-                       control0=volume0&0xFC;
-                       value0=volume1&0xFC;
-                       if ((volume0!=0)&&(volume0<4)) control0 |= 0x04;
-                       if ((volume1!=0)&&(volume1<4)) value0 |= 0x04;
-                       if (channel0!=0) control0 |= 0x01;
-                       if (channel1==1) value0 |= 0x01;
-               }
-               else
-               {
-                       value0=(volume0>volume1)?volume0:volume1;
-                       if (current_drive->drv_type<drv_211)
-                       {
-                               if (channel0!=0)
-                               {
-                                       i=channel1;
-                                       channel1=channel0;
-                                       channel0=i;
-                                       i=volume1;
-                                       volume1=volume0;
-                                       volume0=i;
-                               }
-                               if (channel0==channel1)
-                               {
-                                       if (channel0==0)
-                                       {
-                                               channel1=1;
-                                               volume1=0;
-                                               volume0=value0;
-                                       }
-                                       else
-                                       {
-                                               channel0=0;
-                                               volume0=0;
-                                               volume1=value0;
-                                       }
-                               }
-                       }
-                       
-                       if ((volume0!=0)&&(volume1!=0))
-                       {
-                               if (volume0==0xFF) volume1=0xFF;
-                               else if (volume1==0xFF) volume0=0xFF;
-                       }
-                       else if (current_drive->drv_type<drv_201) volume0=volume1=value0;
-                       
-                       if (current_drive->drv_type>=drv_201)
-                       {
-                               if (volume0==0) control0 |= 0x80;
-                               if (volume1==0) control0 |= 0x40;
-                       }
-                       if (current_drive->drv_type>=drv_211)
-                       {
-                               if (channel0!=0) control0 |= 0x20;
-                               if (channel1!=1) control0 |= 0x10;
-                       }
-               }
-               drvcmd[0]=CMD0_SETMODE;
-               drvcmd[1]=0x83;
-               drvcmd[4]=control0;
-               drvcmd[5]=value0;
-               flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
-       }
-       else if (famT_drive)
-       {
-               current_drive->volume_control=0;
-               if (!volume0) current_drive->volume_control|=0x10;
-               if (!volume1) current_drive->volume_control|=0x20;
-               i=cc_prep_mode_T();
-               if (i<0) return (i);
-       }
-       if (!famT_drive)
-       {
-               response_count=0;
-               i=cmd_out();
-               if (i<0) return (i);
-       }
-       current_drive->diskstate_flags |= volume_bit;
-       return (0);
-}
-/*==========================================================================*/
-static int GetStatus(void)
-{
-       int i;
-       
-       if (famT_drive) return (0);
-       flags_cmd_out=f_getsta|f_ResponseStatus|f_obey_p_check;
-       response_count=0;
-       cmd_type=0;
-       i=cmd_out();
-       return (i);
-}
-/*==========================================================================*/
-static int cc_DriveReset(void)
-{
-       int i;
-       
-       msg(DBG_RES,"cc_DriveReset called.\n");
-       clr_cmdbuf();
-       response_count=0;
-       if (fam0LV_drive) OUT(CDo_reset,0x00);
-       else if (fam1_drive)
-       {
-               drvcmd[0]=CMD1_RESET;
-               flags_cmd_out=f_putcmd;
-               i=cmd_out();
-       }
-       else if (fam2_drive)
-       {
-               drvcmd[0]=CMD2_RESET;
-               flags_cmd_out=f_putcmd;
-               i=cmd_out();
-               OUT(CDo_reset,0x00);
-       }
-       else if (famT_drive)
-       {
-               OUT(CDo_sel_i_d,0);
-               OUT(CDo_enable,current_drive->drv_sel);
-               OUT(CDo_command,CMDT_RESET);
-               for (i=1;i<10;i++) OUT(CDo_command,0);
-       }
-       if (fam0LV_drive) sbp_sleep(5*HZ); /* wait 5 seconds */
-       else sbp_sleep(1*HZ); /* wait a second */
-#if 1
-       if (famT_drive)
-       {
-               msg(DBG_TEA, "================CMDT_RESET given=================.\n");
-               sbp_sleep(3*HZ);
-       }
-#endif /* 1 */ 
-       flush_status();
-       i=GetStatus();
-       if (i<0) return i;
-       if (!famT_drive)
-               if (current_drive->error_byte!=aud_12) return -501;
-       return (0);
-}
-
-/*==========================================================================*/
-static int SetSpeed(void)
-{
-       int i, speed;
-       
-       if (!(current_drive->drv_options&(speed_auto|speed_300|speed_150))) return (0);
-       speed=speed_auto;
-       if (!(current_drive->drv_options&speed_auto))
-       {
-               speed |= speed_300;
-               if (!(current_drive->drv_options&speed_300)) speed=0;
-       }
-       i=cc_SetSpeed(speed,0,0);
-       return (i);
-}
-
-static void switch_drive(struct sbpcd_drive *);
-
-static int sbpcd_select_speed(struct cdrom_device_info *cdi, int speed)
-{
-       struct sbpcd_drive *p = cdi->handle;
-       if (p != current_drive)
-               switch_drive(p);
-
-       return cc_SetSpeed(speed == 2 ? speed_300 : speed_150, 0, 0);
-}
-
-/*==========================================================================*/
-static int DriveReset(void)
-{
-       int i;
-       
-       i=cc_DriveReset();
-       if (i<0) return (-22);
-       do
-       {
-               i=GetStatus();
-               if ((i<0)&&(i!=-ERR_DISKCHANGE)) {
-                       return (-2); /* from sta2err */
-               }
-               if (!st_caddy_in) break;
-               sbp_sleep(1);
-       }
-       while (!st_diskok);
-#if 000
-       current_drive->CD_changed=1;
-#endif
-       if ((st_door_closed) && (st_caddy_in))
-       {
-               i=DiskInfo();
-               if (i<0) return (-23);
-       }
-       return (0);
-}
-
-static int sbpcd_reset(struct cdrom_device_info *cdi)
-{
-       struct sbpcd_drive *p = cdi->handle;
-       if (p != current_drive)
-               switch_drive(p);
-       return DriveReset();
-}
-
-/*==========================================================================*/
-static int cc_PlayAudio(int pos_audio_start,int pos_audio_end)
-{
-       int i, j, n;
-       
-       if (current_drive->audio_state==audio_playing) return (-EINVAL);
-       clr_cmdbuf();
-       response_count=0;
-       if (famLV_drive)
-       {
-               drvcmd[0]=CMDL_PLAY;
-               i=msf2blk(pos_audio_start);
-               n=msf2blk(pos_audio_end)+1-i;
-               drvcmd[1]=(i>>16)&0x00FF;
-               drvcmd[2]=(i>>8)&0x00FF;
-               drvcmd[3]=i&0x00FF;
-               drvcmd[4]=(n>>16)&0x00FF;
-               drvcmd[5]=(n>>8)&0x00FF;
-               drvcmd[6]=n&0x00FF;
-               if (famL_drive)
-               flags_cmd_out = f_putcmd | f_respo2 | f_lopsta | f_getsta |
-                       f_ResponseStatus | f_obey_p_check | f_wait_if_busy;
-               else
-                 flags_cmd_out = f_putcmd;
-       }
-       else
-       {
-               j=1;
-               if (fam1_drive)
-               {
-                       drvcmd[0]=CMD1_PLAY_MSF;
-                       flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus |
-                               f_obey_p_check | f_wait_if_busy;
-               }
-               else if (fam2_drive)
-               {
-                       drvcmd[0]=CMD2_PLAY_MSF;
-                       flags_cmd_out = f_putcmd | f_ResponseStatus | f_obey_p_check;
-               }
-               else if (famT_drive)
-               {
-                       drvcmd[0]=CMDT_PLAY_MSF;
-                       j=3;
-                       response_count=1;
-               }
-               else if (fam0_drive)
-               {
-                       drvcmd[0]=CMD0_PLAY_MSF;
-                       flags_cmd_out = f_putcmd | f_respo2 | f_lopsta | f_getsta |
-                               f_ResponseStatus | f_obey_p_check | f_wait_if_busy;
-               }
-               drvcmd[j]=(pos_audio_start>>16)&0x00FF;
-               drvcmd[j+1]=(pos_audio_start>>8)&0x00FF;
-               drvcmd[j+2]=pos_audio_start&0x00FF;
-               drvcmd[j+3]=(pos_audio_end>>16)&0x00FF;
-               drvcmd[j+4]=(pos_audio_end>>8)&0x00FF;
-               drvcmd[j+5]=pos_audio_end&0x00FF;
-       }
-       i=cmd_out();
-       return (i);
-}
-/*==========================================================================*/
-static int cc_Pause_Resume(int pau_res)
-{
-       int i;
-       
-       clr_cmdbuf();
-       response_count=0;
-       if (fam1_drive)
-       {
-               drvcmd[0]=CMD1_PAU_RES;
-               if (pau_res!=1) drvcmd[1]=0x80;
-               flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
-       }
-       else if (fam2_drive)
-       {
-               drvcmd[0]=CMD2_PAU_RES;
-               if (pau_res!=1) drvcmd[2]=0x01;
-               flags_cmd_out=f_putcmd|f_ResponseStatus;
-       }
-       else if (fam0LV_drive)
-       {
-               drvcmd[0]=CMD0_PAU_RES;
-               if (pau_res!=1) drvcmd[1]=0x80;
-               if (famL_drive)
-                       flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|
-                               f_obey_p_check|f_bit1;
-               else if (famV_drive)
-                 flags_cmd_out=f_putcmd;
-               else
-                       flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|
-                               f_obey_p_check;
-       }
-       else if (famT_drive)
-       {
-               if (pau_res==3) return (cc_PlayAudio(current_drive->pos_audio_start,current_drive->pos_audio_end));
-               else if (pau_res==1) drvcmd[0]=CMDT_PAUSE;
-               else return (-56);
-       }
-       i=cmd_out();
-       return (i);
-}
-/*==========================================================================*/
-static int cc_LockDoor(char lock)
-{
-       int i;
-       
-       if (fam0_drive) return (0);
-       msg(DBG_LCK,"cc_LockDoor: %d (drive %d)\n", lock, current_drive - D_S);
-       msg(DBG_LCS,"p_door_locked bit %d before\n", st_door_locked);
-       clr_cmdbuf();
-       response_count=0;
-       if (fam1_drive)
-       {
-               drvcmd[0]=CMD1_LOCK_CTL;
-               if (lock==1) drvcmd[1]=0x01;
-               flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
-       }
-       else if (fam2_drive)
-       {
-               drvcmd[0]=CMD2_LOCK_CTL;
-               if (lock==1) drvcmd[4]=0x01;
-               flags_cmd_out=f_putcmd|f_ResponseStatus;
-       }
-       else if (famLV_drive)
-       {
-               drvcmd[0]=CMDL_LOCK_CTL;
-               if (lock==1) drvcmd[1]=0x01;
-               if (famL_drive)
-                 flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
-               else
-                 flags_cmd_out=f_putcmd;
-       }
-       else if (famT_drive)
-       {
-               drvcmd[0]=CMDT_LOCK_CTL;
-               if (lock==1) drvcmd[4]=0x01;
-       }
-       i=cmd_out();
-       msg(DBG_LCS,"p_door_locked bit %d after\n", st_door_locked);
-       return (i);
-}
-/*==========================================================================*/
-/*==========================================================================*/
-static int UnLockDoor(void)
-{
-       int i,j;
-       
-       j=20;
-       do
-       {
-               i=cc_LockDoor(0);
-               --j;
-               sbp_sleep(1);
-       }
-       while ((i<0)&&(j));
-       if (i<0)
-       {
-               cc_DriveReset();
-               return -84;
-       }
-       return (0);
-}
-/*==========================================================================*/
-static int LockDoor(void)
-{
-       int i,j;
-       
-       j=20;
-       do
-       {
-               i=cc_LockDoor(1);
-               --j;
-               sbp_sleep(1);
-       }
-       while ((i<0)&&(j));
-       if (j==0)
-       {               
-               cc_DriveReset();
-               j=20;
-               do
-               {
-                       i=cc_LockDoor(1);
-                       --j;
-                       sbp_sleep(1);
-               }
-               while ((i<0)&&(j));
-       }
-       return (i);
-}
-
-static int sbpcd_lock_door(struct cdrom_device_info *cdi, int lock)
-{
-  return lock ? LockDoor() : UnLockDoor();
-}
-
-/*==========================================================================*/
-static int cc_CloseTray(void)
-{
-       int i;
-       
-       if (fam0_drive) return (0);
-       msg(DBG_LCK,"cc_CloseTray (drive %d)\n", current_drive - D_S);
-       msg(DBG_LCS,"p_door_closed bit %d before\n", st_door_closed);
-       
-       clr_cmdbuf();
-       response_count=0;
-       if (fam1_drive)
-       {
-               drvcmd[0]=CMD1_TRAY_CTL;
-               flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
-       }
-       else if (fam2_drive)
-       {
-               drvcmd[0]=CMD2_TRAY_CTL;
-               drvcmd[1]=0x01;
-               drvcmd[4]=0x03; /* "insert" */
-               flags_cmd_out=f_putcmd|f_ResponseStatus;
-       }
-       else if (famLV_drive)
-       {
-               drvcmd[0]=CMDL_TRAY_CTL;
-               if (famLV_drive)
-                 flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|
-                       f_ResponseStatus|f_obey_p_check|f_bit1;
-               else
-                 flags_cmd_out=f_putcmd;
-       }
-       else if (famT_drive)
-       {
-               drvcmd[0]=CMDT_TRAY_CTL;
-               drvcmd[4]=0x03; /* "insert" */
-       }
-       i=cmd_out();
-       msg(DBG_LCS,"p_door_closed bit %d after\n", st_door_closed);
-
-       i=cc_ReadError();
-       flags_cmd_out |= f_respo2;
-       cc_ReadStatus(); /* command: give 1-byte status */
-       i=ResponseStatus();
-       if (famT_drive&&(i<0))
-       {
-               cc_DriveReset();
-               i=ResponseStatus();
-#if 0
-                sbp_sleep(HZ);
-#endif /* 0 */ 
-               i=ResponseStatus();
-       }
-       if (i<0)
-       {
-               msg(DBG_INF,"sbpcd cc_CloseTray: ResponseStatus timed out (%d).\n",i);
-       }
-       if (!(famT_drive))
-       {
-               if (!st_spinning)
-               {
-                       cc_SpinUp();
-                       if (st_check) i=cc_ReadError();
-                       flags_cmd_out |= f_respo2;
-                       cc_ReadStatus();
-                       i=ResponseStatus();
-               } else {
-               }
-       }
-       i=DiskInfo();
-       return (i);
-}
-
-static int sbpcd_tray_move(struct cdrom_device_info *cdi, int position)
-{
-       int retval=0;
-       switch_drive(cdi->handle);
-       /* DUH! --AJK */
-       if(current_drive->CD_changed != 0xFF) {
-               current_drive->CD_changed=0xFF;
-               current_drive->diskstate_flags &= ~cd_size_bit;
-       }
-       if (position == 1) {
-               cc_SpinDown();
-       } else {
-               retval=cc_CloseTray();
-       }
-  return retval;
-}
-
-/*==========================================================================*/
-static int cc_ReadSubQ(void)
-{
-       int i,j;
-
-       current_drive->diskstate_flags &= ~subq_bit;
-       for (j=255;j>0;j--)
-       {
-               clr_cmdbuf();
-               if (fam1_drive)
-               {
-                       drvcmd[0]=CMD1_READSUBQ;
-                       flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
-                       response_count=11;
-               }
-               else if (fam2_drive)
-               {
-                       drvcmd[0]=CMD2_READSUBQ;
-                       drvcmd[1]=0x02;
-                       drvcmd[3]=0x01;
-                       flags_cmd_out=f_putcmd;
-                       response_count=10;
-               }
-               else if (fam0LV_drive)
-               {
-                       drvcmd[0]=CMD0_READSUBQ;
-                       drvcmd[1]=0x02;
-                       if (famLV_drive)
-                               flags_cmd_out=f_putcmd;
-                       else
-                               flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
-                       response_count=13;
-               }
-               else if (famT_drive)
-               {
-                       response_count=12;
-                       drvcmd[0]=CMDT_READSUBQ;
-                       drvcmd[1]=0x02;
-                       drvcmd[2]=0x40;
-                       drvcmd[3]=0x01;
-                       drvcmd[8]=response_count;
-               }
-               i=cmd_out();
-               if (i<0) return (i);
-               for (i=0;i<response_count;i++)
-               {
-                       sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
-                       msgbuf[i*3]=0;
-                       msg(DBG_SQ1,"cc_ReadSubQ:%s\n", msgbuf);
-               }
-               if (famT_drive) break;
-               if (infobuf[0]!=0) break;
-               if ((!st_spinning) || (j==1))
-               {
-                       current_drive->SubQ_ctl_adr=current_drive->SubQ_trk=current_drive->SubQ_pnt_idx=current_drive->SubQ_whatisthis=0;
-                       current_drive->SubQ_run_tot=current_drive->SubQ_run_trk=0;
-                       return (0);
-               }
-       }
-       if (famT_drive) current_drive->SubQ_ctl_adr=infobuf[1];
-       else current_drive->SubQ_ctl_adr=swap_nibbles(infobuf[1]);
-       current_drive->SubQ_trk=byt2bcd(infobuf[2]);
-       current_drive->SubQ_pnt_idx=byt2bcd(infobuf[3]);
-       if (fam0LV_drive) i=5;
-       else if (fam12_drive) i=4;
-       else if (famT_drive) i=8;
-       current_drive->SubQ_run_tot=make32(make16(0,infobuf[i]),make16(infobuf[i+1],infobuf[i+2])); /* msf-bin */
-       i=7;
-       if (fam0LV_drive) i=9;
-       else if (fam12_drive) i=7;
-       else if (famT_drive) i=4;
-       current_drive->SubQ_run_trk=make32(make16(0,infobuf[i]),make16(infobuf[i+1],infobuf[i+2])); /* msf-bin */
-       current_drive->SubQ_whatisthis=infobuf[i+3];
-       current_drive->diskstate_flags |= subq_bit;
-       return (0);
-}
-/*==========================================================================*/
-static int cc_ModeSense(void)
-{
-       int i;
-       
-       if (fam2_drive) return (0);
-       if (famV_drive) return (0);
-       current_drive->diskstate_flags &= ~frame_size_bit;
-       clr_cmdbuf();
-       if (fam1_drive)
-       {
-               response_count=5;
-               drvcmd[0]=CMD1_GETMODE;
-               flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
-       }
-       else if (fam0L_drive)
-       {
-               response_count=2;
-               drvcmd[0]=CMD0_GETMODE;
-               if (famL_drive) flags_cmd_out=f_putcmd;
-               else flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
-       }
-       else if (famT_drive)
-       {
-               response_count=10;
-               drvcmd[0]=CMDT_GETMODE;
-               drvcmd[4]=response_count;
-       }
-       i=cmd_out();
-       if (i<0) return (i);
-       i=0;
-       current_drive->sense_byte=0;
-       if (fam1_drive) current_drive->sense_byte=infobuf[i++];
-       else if (famT_drive)
-       {
-               if (infobuf[4]==0x01) current_drive->xa_byte=0x20;
-               else current_drive->xa_byte=0;
-               i=2;
-       }
-       current_drive->frame_size=make16(infobuf[i],infobuf[i+1]);
-       for (i=0;i<response_count;i++)
-               sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
-       msgbuf[i*3]=0;
-       msg(DBG_XA1,"cc_ModeSense:%s\n", msgbuf);
-       
-       current_drive->diskstate_flags |= frame_size_bit;
-       return (0);
-}
-/*==========================================================================*/
-/*==========================================================================*/
-static int cc_ModeSelect(int framesize)
-{
-       int i;
-       
-       if (fam2_drive) return (0);
-       if (famV_drive) return (0);
-       current_drive->diskstate_flags &= ~frame_size_bit;
-       clr_cmdbuf();
-       current_drive->frame_size=framesize;
-       if (framesize==CD_FRAMESIZE_RAW) current_drive->sense_byte=0x82;
-       else current_drive->sense_byte=0x00;
-       
-       msg(DBG_XA1,"cc_ModeSelect: %02X %04X\n",
-           current_drive->sense_byte, current_drive->frame_size);
-       
-       if (fam1_drive)
-       {
-               drvcmd[0]=CMD1_SETMODE;
-               drvcmd[1]=0x00;
-               drvcmd[2]=current_drive->sense_byte;
-               drvcmd[3]=(current_drive->frame_size>>8)&0xFF;
-               drvcmd[4]=current_drive->frame_size&0xFF;
-               flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
-       }
-       else if (fam0L_drive)
-       {
-               drvcmd[0]=CMD0_SETMODE;
-               drvcmd[1]=0x00;
-               drvcmd[2]=(current_drive->frame_size>>8)&0xFF;
-               drvcmd[3]=current_drive->frame_size&0xFF;
-               drvcmd[4]=0x00;
-               if(famL_drive)
-                       flags_cmd_out=f_putcmd|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check;
-               else
-                       flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
-       }
-       else if (famT_drive)
-       {
-               return (-1);
-       }
-       response_count=0;
-       i=cmd_out();
-       if (i<0) return (i);
-       current_drive->diskstate_flags |= frame_size_bit;
-       return (0);
-}
-/*==========================================================================*/
-static int cc_GetVolume(void)
-{
-       int i;
-       u_char switches;
-       u_char chan0=0;
-       u_char vol0=0;
-       u_char chan1=1;
-       u_char vol1=0;
-       
-       if (famV_drive) return (0);
-       current_drive->diskstate_flags &= ~volume_bit;
-       clr_cmdbuf();
-       if (fam1_drive)
-       {
-               drvcmd[0]=CMD1_GETMODE;
-               drvcmd[1]=0x05;
-               response_count=5;
-               flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
-       }
-       else if (fam2_drive)
-       {
-               drvcmd[0]=CMD2_GETMODE;
-               drvcmd[1]=0x0E;
-               response_count=5;
-               flags_cmd_out=f_putcmd;
-       }
-       else if (fam0L_drive)
-       {
-               drvcmd[0]=CMD0_GETMODE;
-               drvcmd[1]=0x03;
-               response_count=2;
-               if(famL_drive)
-                       flags_cmd_out=f_putcmd;
-               else
-                       flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
-       }
-       else if (famT_drive)
-       {
-               i=cc_get_mode_T();
-               if (i<0) return (i);
-       }
-       if (!famT_drive)
-       {
-               i=cmd_out();
-               if (i<0) return (i);
-       }
-       if (fam1_drive)
-       {
-               chan0=infobuf[1]&0x0F;
-               vol0=infobuf[2];
-               chan1=infobuf[3]&0x0F;
-               vol1=infobuf[4];
-               if (chan0==0)
-               {
-                       chan0=1;
-                       vol0=0;
-               }
-               if (chan1==0)
-               {
-                       chan1=2;
-                       vol1=0;
-               }
-               chan0 >>= 1;
-               chan1 >>= 1;
-       }
-       else if (fam2_drive)
-       {
-               chan0=infobuf[1];
-               vol0=infobuf[2];
-               chan1=infobuf[3];
-               vol1=infobuf[4];
-       }
-       else if (famL_drive)
-       {
-               chan0=0;
-               chan1=1;
-               vol0=vol1=infobuf[1];
-               switches=infobuf[0];
-               if ((switches&0x80)!=0) chan0=1;
-               if ((switches&0x40)!=0) chan1=0;
-       }
-       else if (fam0_drive) /* different firmware levels */
-       {
-               chan0=0;
-               chan1=1;
-               vol0=vol1=infobuf[1];
-               if (current_drive->drv_type>=drv_201)
-               {
-                       if (current_drive->drv_type<drv_300)
-                       {
-                               switches=infobuf[0];
-                               if ((switches&0x80)!=0) vol0=0;
-                               if ((switches&0x40)!=0) vol1=0;
-                               if (current_drive->drv_type>=drv_211)
-                               {
-                                       if ((switches&0x20)!=0) chan0=1;
-                                       if ((switches&0x10)!=0) chan1=0;
-                               }
-                       }
-                       else
-                       {
-                               vol0=infobuf[0];
-                               if ((vol0&0x01)!=0) chan0=1;
-                               if ((vol1&0x01)==0) chan1=0;
-                               vol0 &= 0xFC;
-                               vol1 &= 0xFC;
-                               if (vol0!=0) vol0 += 3;
-                               if (vol1!=0) vol1 += 3;
-                       }
-               }
-       }
-       else if (famT_drive)
-       {
-               current_drive->volume_control=infobuf[7];
-               chan0=0;
-               chan1=1;
-               if (current_drive->volume_control&0x10) vol0=0;
-               else vol0=0xff;
-               if (current_drive->volume_control&0x20) vol1=0;
-               else vol1=0xff;
-       }
-       current_drive->vol_chan0=chan0;
-       current_drive->vol_ctrl0=vol0;
-       current_drive->vol_chan1=chan1;
-       current_drive->vol_ctrl1=vol1;
-#if 000
-       current_drive->vol_chan2=2;
-       current_drive->vol_ctrl2=0xFF;
-       current_drive->vol_chan3=3;
-       current_drive->vol_ctrl3=0xFF;
-#endif /*  000 */
-       current_drive->diskstate_flags |= volume_bit;
-       return (0);
-}
-/*==========================================================================*/
-static int cc_ReadCapacity(void)
-{
-       int i, j;
-       
-       if (fam2_drive) return (0); /* some firmware lacks this command */
-       if (famLV_drive) return (0); /* some firmware lacks this command */
-       if (famT_drive) return (0); /* done with cc_ReadTocDescr() */
-       current_drive->diskstate_flags &= ~cd_size_bit;
-       for (j=3;j>0;j--)
-       {
-               clr_cmdbuf();
-               if (fam1_drive)
-               {
-                       drvcmd[0]=CMD1_CAPACITY;
-                       response_count=5;
-                       flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
-               }
-#if 00
-               else if (fam2_drive)
-               {
-                       drvcmd[0]=CMD2_CAPACITY;
-                       response_count=8;
-                       flags_cmd_out=f_putcmd;
-               }
-#endif
-               else if (fam0_drive)
-               {
-                       drvcmd[0]=CMD0_CAPACITY;
-                       response_count=5;
-                       flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
-               }
-               i=cmd_out();
-               if (i>=0) break;
-               msg(DBG_000,"cc_ReadCapacity: cmd_out: err %d\n", i);
-               cc_ReadError();
-       }
-       if (j==0) return (i);
-       if (fam1_drive) current_drive->CDsize_frm=msf2blk(make32(make16(0,infobuf[0]),make16(infobuf[1],infobuf[2])))+CD_MSF_OFFSET;
-       else if (fam0_drive) current_drive->CDsize_frm=make32(make16(0,infobuf[0]),make16(infobuf[1],infobuf[2]));
-#if 00
-       else if (fam2_drive) current_drive->CDsize_frm=make32(make16(infobuf[0],infobuf[1]),make16(infobuf[2],infobuf[3]));
-#endif
-       current_drive->diskstate_flags |= cd_size_bit;
-       msg(DBG_000,"cc_ReadCapacity: %d frames.\n", current_drive->CDsize_frm);
-       return (0);
-}
-/*==========================================================================*/
-static int cc_ReadTocDescr(void)
-{
-       int i;
-       
-       current_drive->diskstate_flags &= ~toc_bit;
-       clr_cmdbuf();
-       if (fam1_drive)
-       {
-               drvcmd[0]=CMD1_DISKINFO;
-               response_count=6;
-               flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
-       }
-       else if (fam0LV_drive)
-       {
-               drvcmd[0]=CMD0_DISKINFO;
-               response_count=6;
-               if(famLV_drive)
-                       flags_cmd_out=f_putcmd;
-               else
-                       flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
-       }
-       else if (fam2_drive)
-       {
-               /* possibly longer timeout periods necessary */
-               current_drive->f_multisession=0;
-               drvcmd[0]=CMD2_DISKINFO;
-               drvcmd[1]=0x02;
-               drvcmd[2]=0xAB;
-               drvcmd[3]=0xFF; /* session */
-               response_count=8;
-               flags_cmd_out=f_putcmd;
-       }
-       else if (famT_drive)
-       {
-               current_drive->f_multisession=0;
-               response_count=12;
-               drvcmd[0]=CMDT_DISKINFO;
-               drvcmd[1]=0x02;
-               drvcmd[6]=CDROM_LEADOUT;
-               drvcmd[8]=response_count;
-               drvcmd[9]=0x00;
-       }
-       i=cmd_out();
-       if (i<0) return (i);
-       if ((famT_drive)&&(i<response_count)) return (-100-i);
-       if ((fam1_drive)||(fam2_drive)||(fam0LV_drive))
-               current_drive->xa_byte=infobuf[0];
-       if (fam2_drive)
-       {
-               current_drive->first_session=infobuf[1];
-               current_drive->last_session=infobuf[2];
-               current_drive->n_first_track=infobuf[3];
-               current_drive->n_last_track=infobuf[4];
-               if (current_drive->first_session!=current_drive->last_session)
-               {
-                       current_drive->f_multisession=1;
-                       current_drive->lba_multi=msf2blk(make32(make16(0,infobuf[5]),make16(infobuf[6],infobuf[7])));
-               }
-#if 0
-               if (current_drive->first_session!=current_drive->last_session)
-               {
-                       if (current_drive->last_session<=20)
-                               zwanzig=current_drive->last_session+1;
-                       else zwanzig=20;
-                       for (count=current_drive->first_session;count<zwanzig;count++)
-                       {
-                               drvcmd[0]=CMD2_DISKINFO;
-                               drvcmd[1]=0x02;
-                               drvcmd[2]=0xAB;
-                               drvcmd[3]=count;
-                               response_count=8;
-                               flags_cmd_out=f_putcmd;
-                               i=cmd_out();
-                               if (i<0) return (i);
-                               current_drive->msf_multi_n[count]=make32(make16(0,infobuf[5]),make16(infobuf[6],infobuf[7]));
-                       }
-                       current_drive->diskstate_flags |= multisession_bit;
-               }
-#endif
-               drvcmd[0]=CMD2_DISKINFO;
-               drvcmd[1]=0x02;
-               drvcmd[2]=0xAA;
-               drvcmd[3]=0xFF;
-               response_count=5;
-               flags_cmd_out=f_putcmd;
-               i=cmd_out();
-               if (i<0) return (i);
-               current_drive->size_msf=make32(make16(0,infobuf[2]),make16(infobuf[3],infobuf[4]));
-               current_drive->size_blk=msf2blk(current_drive->size_msf);
-               current_drive->CDsize_frm=current_drive->size_blk+1;
-       }
-       else if (famT_drive)
-       {
-               current_drive->size_msf=make32(make16(infobuf[8],infobuf[9]),make16(infobuf[10],infobuf[11]));
-               current_drive->size_blk=msf2blk(current_drive->size_msf);
-               current_drive->CDsize_frm=current_drive->size_blk+1;
-               current_drive->n_first_track=infobuf[2];
-               current_drive->n_last_track=infobuf[3];
-       }
-       else
-       {
-               current_drive->n_first_track=infobuf[1];
-               current_drive->n_last_track=infobuf[2];
-               current_drive->size_msf=make32(make16(0,infobuf[3]),make16(infobuf[4],infobuf[5]));
-               current_drive->size_blk=msf2blk(current_drive->size_msf);
-               if (famLV_drive) current_drive->CDsize_frm=current_drive->size_blk+1;
-       }
-       current_drive->diskstate_flags |= toc_bit;
-       msg(DBG_TOC,"TocDesc: xa %02X firstt %02X lastt %02X size %08X firstses %02X lastsess %02X\n",
-           current_drive->xa_byte,
-           current_drive->n_first_track,
-           current_drive->n_last_track,
-           current_drive->size_msf,
-           current_drive->first_session,
-           current_drive->last_session);
-       return (0);
-}
-/*==========================================================================*/
-static int cc_ReadTocEntry(int num)
-{
-       int i;
-       
-       clr_cmdbuf();
-       if (fam1_drive)
-       {
-               drvcmd[0]=CMD1_READTOC;
-               drvcmd[2]=num;
-               response_count=8;
-               flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
-       }
-       else if (fam2_drive)
-       {
-               /* possibly longer timeout periods necessary */
-               drvcmd[0]=CMD2_DISKINFO;
-               drvcmd[1]=0x02;
-               drvcmd[2]=num;
-               response_count=5;
-               flags_cmd_out=f_putcmd;
-       }
-       else if (fam0LV_drive)
-       {
-               drvcmd[0]=CMD0_READTOC;
-               drvcmd[1]=0x02;
-               drvcmd[2]=num;
-               response_count=8;
-               if (famLV_drive)
-                       flags_cmd_out=f_putcmd;
-               else
-                 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
-       }
-       else if (famT_drive)
-       {
-               response_count=12;
-               drvcmd[0]=CMDT_DISKINFO;
-               drvcmd[1]=0x02;
-               drvcmd[6]=num;
-               drvcmd[8]=response_count;
-               drvcmd[9]=0x00;
-       }
-       i=cmd_out();
-       if (i<0) return (i);
-       if ((famT_drive)&&(i<response_count)) return (-100-i);
-       if ((fam1_drive)||(fam0LV_drive))
-       {
-               current_drive->TocEnt_nixbyte=infobuf[0];
-               i=1;
-       }
-       else if (fam2_drive) i=0;
-       else if (famT_drive) i=5;
-       current_drive->TocEnt_ctl_adr=swap_nibbles(infobuf[i++]);
-       if ((fam1_drive)||(fam0L_drive))
-       {
-               current_drive->TocEnt_number=infobuf[i++];
-               current_drive->TocEnt_format=infobuf[i];
-       }
-       else
-         {
-           current_drive->TocEnt_number=num;
-           current_drive->TocEnt_format=0;
-         }
-       if (fam1_drive) i=4;
-       else if (fam0LV_drive) i=5;
-       else if (fam2_drive) i=2;
-       else if (famT_drive) i=9;
-       current_drive->TocEnt_address=make32(make16(0,infobuf[i]),
-                                    make16(infobuf[i+1],infobuf[i+2]));
-       for (i=0;i<response_count;i++)
-               sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
-       msgbuf[i*3]=0;
-       msg(DBG_ECS,"TocEntry:%s\n", msgbuf);
-       msg(DBG_TOC,"TocEntry: %02X %02X %02X %02X %08X\n",
-           current_drive->TocEnt_nixbyte, current_drive->TocEnt_ctl_adr,
-           current_drive->TocEnt_number, current_drive->TocEnt_format,
-           current_drive->TocEnt_address);
-       return (0);
-}
-/*==========================================================================*/
-static int cc_ReadPacket(void)
-{
-       int i;
-       
-       clr_cmdbuf();
-       drvcmd[0]=CMD0_PACKET;
-       drvcmd[1]=response_count;
-       if(famL_drive) flags_cmd_out=f_putcmd;
-       else if (fam01_drive)
-               flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
-       else if (fam2_drive) return (-1); /* not implemented yet */
-       else if (famT_drive)
-       {
-               return (-1);
-       }
-       i=cmd_out();
-       return (i);
-}
-/*==========================================================================*/
-static int convert_UPC(u_char *p)
-{
-       int i;
-       
-       p++;
-       if (fam0L_drive) p[13]=0;
-       for (i=0;i<7;i++)
-       {
-               if (fam1_drive) current_drive->UPC_buf[i]=swap_nibbles(*p++);
-               else if (fam0L_drive)
-               {
-                       current_drive->UPC_buf[i]=((*p++)<<4)&0xFF;
-                       current_drive->UPC_buf[i] |= *p++;
-               }
-               else if (famT_drive)
-               {
-                       return (-1);
-               }
-               else /* CD200 */
-               {
-                       return (-1);
-               }
-       }
-       current_drive->UPC_buf[6] &= 0xF0;
-       return (0);
-}
-/*==========================================================================*/
-static int cc_ReadUPC(void)
-{
-       int i;
-#if TEST_UPC
-       int block, checksum;
-#endif /* TEST_UPC */ 
-       
-       if (fam2_drive) return (0); /* not implemented yet */
-       if (famT_drive) return (0); /* not implemented yet */
-       if (famV_drive) return (0); /* not implemented yet */
-#if 1
-       if (fam0_drive) return (0); /* but it should work */
-#endif
-       
-       current_drive->diskstate_flags &= ~upc_bit;
-#if TEST_UPC
-       for (block=CD_MSF_OFFSET+1;block<CD_MSF_OFFSET+200;block++)
-       {
-#endif /* TEST_UPC */ 
-               clr_cmdbuf();
-               if (fam1_drive)
-               {
-                       drvcmd[0]=CMD1_READ_UPC;
-#if TEST_UPC
-                       drvcmd[1]=(block>>16)&0xFF;
-                       drvcmd[2]=(block>>8)&0xFF;
-                       drvcmd[3]=block&0xFF;
-#endif /* TEST_UPC */ 
-                       response_count=8;
-                       flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
-               }
-               else if (fam0L_drive)
-               {
-                       drvcmd[0]=CMD0_READ_UPC;
-#if TEST_UPC
-                       drvcmd[2]=(block>>16)&0xFF;
-                       drvcmd[3]=(block>>8)&0xFF;
-                       drvcmd[4]=block&0xFF;
-#endif /* TEST_UPC */ 
-                       response_count=0;
-                       flags_cmd_out=f_putcmd|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
-               }
-               else if (fam2_drive)
-               {
-                       return (-1);
-               }
-               else if (famT_drive)
-               {
-                       return (-1);
-               }
-               i=cmd_out();
-               if (i<0)
-               {
-                       msg(DBG_000,"cc_ReadUPC cmd_out: err %d\n", i);
-                       return (i);
-               }
-               if (fam0L_drive)
-               {
-                       response_count=16;
-                       if (famL_drive) flags_cmd_out=f_putcmd;
-                       i=cc_ReadPacket();
-                       if (i<0)
-                       {
-                               msg(DBG_000,"cc_ReadUPC ReadPacket: err %d\n", i);
-                               return (i);
-                       }
-               }
-#if TEST_UPC
-               checksum=0;
-#endif /* TEST_UPC */ 
-               for (i=0;i<(fam1_drive?8:16);i++)
-               {
-#if TEST_UPC
-                       checksum |= infobuf[i];
-#endif /* TEST_UPC */ 
-                       sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
-               }
-               msgbuf[i*3]=0;
-               msg(DBG_UPC,"UPC info:%s\n", msgbuf);
-#if TEST_UPC
-               if ((checksum&0x7F)!=0) break;
-       }
-#endif /* TEST_UPC */ 
-       current_drive->UPC_ctl_adr=0;
-       if (fam1_drive) i=0;
-       else i=2;
-       if ((infobuf[i]&0x80)!=0)
-       {
-               convert_UPC(&infobuf[i]);
-               current_drive->UPC_ctl_adr = (current_drive->TocEnt_ctl_adr & 0xF0) | 0x02;
-       }
-       for (i=0;i<7;i++)
-               sprintf(&msgbuf[i*3], " %02X", current_drive->UPC_buf[i]);
-       sprintf(&msgbuf[i*3], " (%02X)", current_drive->UPC_ctl_adr);
-       msgbuf[i*3+5]=0;
-       msg(DBG_UPC,"UPC code:%s\n", msgbuf);
-       current_drive->diskstate_flags |= upc_bit;
-       return (0);
-}
-
-static int sbpcd_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
-{
-       int i;
-       unsigned char *mcnp = mcn->medium_catalog_number;
-       unsigned char *resp;
-
-       current_drive->diskstate_flags &= ~upc_bit;
-       clr_cmdbuf();
-       if (fam1_drive)
-       {
-               drvcmd[0]=CMD1_READ_UPC;
-               response_count=8;
-               flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
-       }
-       else if (fam0L_drive)
-       {
-               drvcmd[0]=CMD0_READ_UPC;
-               response_count=0;
-               flags_cmd_out=f_putcmd|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
-       }
-       else if (fam2_drive)
-       {
-               return (-1);
-       }
-       else if (famT_drive)
-       {
-               return (-1);
-       }
-       i=cmd_out();
-       if (i<0)
-       {
-               msg(DBG_000,"cc_ReadUPC cmd_out: err %d\n", i);
-               return (i);
-       }
-       if (fam0L_drive)
-       {
-               response_count=16;
-               if (famL_drive) flags_cmd_out=f_putcmd;
-               i=cc_ReadPacket();
-               if (i<0)
-               {
-                       msg(DBG_000,"cc_ReadUPC ReadPacket: err %d\n", i);
-                       return (i);
-               }
-       }
-       current_drive->UPC_ctl_adr=0;
-       if (fam1_drive) i=0;
-       else i=2;
-
-       resp = infobuf + i;
-       if (*resp++ == 0x80) {
-               /* packed bcd to single ASCII digits */
-               *mcnp++ = (*resp >> 4)     + '0';
-               *mcnp++ = (*resp++ & 0x0f) + '0';
-               *mcnp++ = (*resp >> 4)     + '0';
-               *mcnp++ = (*resp++ & 0x0f) + '0';
-               *mcnp++ = (*resp >> 4)     + '0';
-               *mcnp++ = (*resp++ & 0x0f) + '0';
-               *mcnp++ = (*resp >> 4)     + '0';
-               *mcnp++ = (*resp++ & 0x0f) + '0';
-               *mcnp++ = (*resp >> 4)     + '0';
-               *mcnp++ = (*resp++ & 0x0f) + '0';
-               *mcnp++ = (*resp >> 4)     + '0';
-               *mcnp++ = (*resp++ & 0x0f) + '0';
-               *mcnp++ = (*resp >> 4)     + '0';
-       }
-       *mcnp = '\0';
-
-       current_drive->diskstate_flags |= upc_bit;
-       return (0);
-}
-
-/*==========================================================================*/
-static int cc_CheckMultiSession(void)
-{
-       int i;
-       
-       if (fam2_drive) return (0);
-       current_drive->f_multisession=0;
-       current_drive->lba_multi=0;
-       if (fam0_drive) return (0);
-       clr_cmdbuf();
-       if (fam1_drive)
-       {
-               drvcmd[0]=CMD1_MULTISESS;
-               response_count=6;
-               flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
-               i=cmd_out();
-               if (i<0) return (i);
-               if ((infobuf[0]&0x80)!=0)
-               {
-                       current_drive->f_multisession=1;
-                       current_drive->lba_multi=msf2blk(make32(make16(0,infobuf[1]),
-                                                       make16(infobuf[2],infobuf[3])));
-               }
-       }
-       else if (famLV_drive)
-       {
-               drvcmd[0]=CMDL_MULTISESS;
-               drvcmd[1]=3;
-               drvcmd[2]=1;
-               response_count=8;
-               flags_cmd_out=f_putcmd;
-               i=cmd_out();
-               if (i<0) return (i);
-               current_drive->lba_multi=msf2blk(make32(make16(0,infobuf[5]),
-                                               make16(infobuf[6],infobuf[7])));
-       }
-       else if (famT_drive)
-       {
-               response_count=12;
-               drvcmd[0]=CMDT_DISKINFO;
-               drvcmd[1]=0x02;
-               drvcmd[6]=0;
-               drvcmd[8]=response_count;
-               drvcmd[9]=0x40;
-               i=cmd_out();
-               if (i<0) return (i);
-               if (i<response_count) return (-100-i);
-               current_drive->first_session=infobuf[2];
-               current_drive->last_session=infobuf[3];
-               current_drive->track_of_last_session=infobuf[6];
-               if (current_drive->first_session!=current_drive->last_session)
-               {
-                       current_drive->f_multisession=1;
-                       current_drive->lba_multi=msf2blk(make32(make16(0,infobuf[9]),make16(infobuf[10],infobuf[11])));
-               }
-       }
-       for (i=0;i<response_count;i++)
-               sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
-       msgbuf[i*3]=0;
-       msg(DBG_MUL,"MultiSession Info:%s (%d)\n", msgbuf, current_drive->lba_multi);
-       if (current_drive->lba_multi>200)
-       {
-               current_drive->f_multisession=1;
-               msg(DBG_MUL,"MultiSession base: %06X\n", current_drive->lba_multi);
-       }
-       return (0);
-}
-/*==========================================================================*/
-#ifdef FUTURE
-static int cc_SubChanInfo(int frame, int count, u_char *buffer)
-       /* "frame" is a RED BOOK (msf-bin) address */
-{
-       int i;
-       
-       if (fam0LV_drive) return (-ENOSYS); /* drive firmware lacks it */
-       if (famT_drive)
-       {
-               return (-1);
-       }
-#if 0
-       if (current_drive->audio_state!=audio_playing) return (-ENODATA);
-#endif
-       clr_cmdbuf();
-       drvcmd[0]=CMD1_SUBCHANINF;
-       drvcmd[1]=(frame>>16)&0xFF;
-       drvcmd[2]=(frame>>8)&0xFF;
-       drvcmd[3]=frame&0xFF;
-       drvcmd[5]=(count>>8)&0xFF;
-       drvcmd[6]=count&0xFF;
-       flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
-       cmd_type=READ_SC;
-       current_drive->frame_size=CD_FRAMESIZE_SUB;
-       i=cmd_out(); /* which buffer to use? */
-       return (i);
-}
-#endif /* FUTURE */ 
-/*==========================================================================*/
-static void __init check_datarate(void)
-{
-       int i=0;
-       
-       msg(DBG_IOX,"check_datarate entered.\n");
-       datarate=0;
-#if TEST_STI
-       for (i=0;i<=1000;i++) printk(".");
-#endif
-       /* set a timer to make (timed_out_delay!=0) after 1.1 seconds */
-#if 1
-       del_timer(&delay_timer);
-#endif
-       delay_timer.expires=jiffies+11*HZ/10;
-       timed_out_delay=0;
-       add_timer(&delay_timer);
-#if 0
-       msg(DBG_TIM,"delay timer started (11*HZ/10).\n");
-#endif
-       do
-       {
-               i=inb(CDi_status);
-               datarate++;
-#if 1
-               if (datarate>0x6FFFFFFF) break;
-#endif 
-       }
-       while (!timed_out_delay);
-       del_timer(&delay_timer);
-#if 0
-       msg(DBG_TIM,"datarate: %04X\n", datarate);
-#endif
-       if (datarate<65536) datarate=65536;
-       maxtim16=datarate*16;
-       maxtim04=datarate*4;
-       maxtim02=datarate*2;
-       maxtim_8=datarate/32;
-#if LONG_TIMING
-       maxtim_data=datarate/100;
-#else
-       maxtim_data=datarate/300;
-#endif /* LONG_TIMING */ 
-#if 0
-       msg(DBG_TIM,"maxtim_8 %d, maxtim_data %d.\n", maxtim_8, maxtim_data);
-#endif
-}
-/*==========================================================================*/
-#if 0
-static int c2_ReadError(int fam)
-{
-       int i;
-       
-       clr_cmdbuf();
-       response_count=9;
-       clr_respo_buf(9);
-       if (fam==1)
-       {
-               drvcmd[0]=CMD0_READ_ERR; /* same as CMD1_ and CMDL_ */
-               i=do_cmd(f_putcmd|f_lopsta|f_getsta|f_ResponseStatus);
-       }
-       else if (fam==2)
-       {
-               drvcmd[0]=CMD2_READ_ERR;
-               i=do_cmd(f_putcmd);
-       }
-       else return (-1);
-       return (i);
-}
-#endif
-/*==========================================================================*/
-static void __init ask_mail(void)
-{
-       int i;
-       
-       msg(DBG_INF, "please mail the following lines to emoenke@gwdg.de\n");
-       msg(DBG_INF, "(don't mail if you are not using the actual kernel):\n");
-       msg(DBG_INF, "%s\n", VERSION);
-       msg(DBG_INF, "address %03X, type %s, drive %s (ID %d)\n",
-           CDo_command, type, current_drive->drive_model, current_drive->drv_id);
-       for (i=0;i<12;i++)
-               sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
-       msgbuf[i*3]=0;
-       msg(DBG_INF,"infobuf =%s\n", msgbuf);
-       for (i=0;i<12;i++)
-               sprintf(&msgbuf[i*3], " %c ", infobuf[i]);
-       msgbuf[i*3]=0;
-       msg(DBG_INF,"infobuf =%s\n", msgbuf);
-}
-/*==========================================================================*/
-static int __init check_version(void)
-{
-       int i, j, l;
-       int teac_possible=0;
-       
-       msg(DBG_INI,"check_version: id=%d, d=%d.\n", current_drive->drv_id, current_drive - D_S);
-       current_drive->drv_type=0;
-
-       /* check for CR-52x, CR-56x, LCS-7260 and ECS-AT */
-       /* clear any pending error state */
-       clr_cmdbuf();
-       drvcmd[0]=CMD0_READ_ERR; /* same as CMD1_ and CMDL_ */
-       response_count=9;
-       flags_cmd_out=f_putcmd;
-       i=cmd_out();
-       if (i<0) msg(DBG_INI,"CMD0_READ_ERR returns %d (ok anyway).\n",i);
-       /* read drive version */
-       clr_cmdbuf();
-       for (i=0;i<12;i++) infobuf[i]=0;
-       drvcmd[0]=CMD0_READ_VER; /* same as CMD1_ and CMDL_ */
-       response_count=12; /* fam1: only 11 */
-       flags_cmd_out=f_putcmd;
-       i=cmd_out();
-       if (i<-1) msg(DBG_INI,"CMD0_READ_VER returns %d\n",i);
-       if (i==-11) teac_possible++;
-       j=0;
-       for (i=0;i<12;i++) j+=infobuf[i];
-       if (j)
-       {
-               for (i=0;i<12;i++)
-                       sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
-               msgbuf[i*3]=0;
-               msg(DBG_ECS,"infobuf =%s\n", msgbuf);
-               for (i=0;i<12;i++)
-                       sprintf(&msgbuf[i*3], " %c ", infobuf[i]);
-               msgbuf[i*3]=0;
-               msg(DBG_ECS,"infobuf =%s\n", msgbuf);
-       }
-       for (i=0;i<4;i++) if (infobuf[i]!=family1[i]) break;
-       if (i==4)
-       {
-               current_drive->drive_model[0]='C';
-               current_drive->drive_model[1]='R';
-               current_drive->drive_model[2]='-';
-               current_drive->drive_model[3]='5';
-               current_drive->drive_model[4]=infobuf[i++];
-               current_drive->drive_model[5]=infobuf[i++];
-               current_drive->drive_model[6]=0;
-               current_drive->drv_type=drv_fam1;
-       }
-       if (!current_drive->drv_type)
-       {
-               for (i=0;i<8;i++) if (infobuf[i]!=family0[i]) break;
-               if (i==8)
-               {
-                       current_drive->drive_model[0]='C';
-                       current_drive->drive_model[1]='R';
-                       current_drive->drive_model[2]='-';
-                       current_drive->drive_model[3]='5';
-                       current_drive->drive_model[4]='2';
-                       current_drive->drive_model[5]='x';
-                       current_drive->drive_model[6]=0;
-                       current_drive->drv_type=drv_fam0;
-               }
-       }
-       if (!current_drive->drv_type)
-       {
-               for (i=0;i<8;i++) if (infobuf[i]!=familyL[i]) break;
-               if (i==8)
-               {
-                       for (j=0;j<8;j++)
-                               current_drive->drive_model[j]=infobuf[j];
-                       current_drive->drive_model[8]=0;
-                       current_drive->drv_type=drv_famL;
-               }
-       }
-       if (!current_drive->drv_type)
-       {
-               for (i=0;i<6;i++) if (infobuf[i]!=familyV[i]) break;
-               if (i==6)
-               {
-                       for (j=0;j<6;j++)
-                               current_drive->drive_model[j]=infobuf[j];
-                       current_drive->drive_model[6]=0;
-                       current_drive->drv_type=drv_famV;
-                       i+=2; /* 2 blanks before version */
-               }
-       }
-       if (!current_drive->drv_type)
-       {
-               /* check for CD200 */
-               clr_cmdbuf();
-               drvcmd[0]=CMD2_READ_ERR;
-               response_count=9;
-               flags_cmd_out=f_putcmd;
-               i=cmd_out();
-               if (i<0) msg(DBG_INI,"CMD2_READERR returns %d (ok anyway).\n",i);
-               if (i<0) msg(DBG_000,"CMD2_READERR returns %d (ok anyway).\n",i);
-               /* read drive version */
-               clr_cmdbuf();
-               for (i=0;i<12;i++) infobuf[i]=0;
-               if (sbpro_type==1) OUT(CDo_sel_i_d,0);
-#if 0
-               OUT(CDo_reset,0);
-               sbp_sleep(6*HZ);
-               OUT(CDo_enable,current_drive->drv_sel);
-#endif
-               drvcmd[0]=CMD2_READ_VER;
-               response_count=12;
-               flags_cmd_out=f_putcmd;
-               i=cmd_out();
-               if (i<0) msg(DBG_INI,"CMD2_READ_VER returns %d\n",i);
-               if (i==-7) teac_possible++;
-               j=0;
-               for (i=0;i<12;i++) j+=infobuf[i];
-               if (j)
-               {
-                       for (i=0;i<12;i++)
-                               sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
-                       msgbuf[i*3]=0;
-                       msg(DBG_IDX,"infobuf =%s\n", msgbuf);
-                       for (i=0;i<12;i++)
-                               sprintf(&msgbuf[i*3], " %c ", infobuf[i]);
-                       msgbuf[i*3]=0;
-                       msg(DBG_IDX,"infobuf =%s\n", msgbuf);
-               }
-               if (i>=0)
-               {
-                       for (i=0;i<5;i++) if (infobuf[i]!=family2[i]) break;
-                       if (i==5)
-                       {
-                               current_drive->drive_model[0]='C';
-                               current_drive->drive_model[1]='D';
-                               current_drive->drive_model[2]='2';
-                               current_drive->drive_model[3]='0';
-                               current_drive->drive_model[4]='0';
-                               current_drive->drive_model[5]=infobuf[i++];
-                               current_drive->drive_model[6]=infobuf[i++];
-                               current_drive->drive_model[7]=0;
-                               current_drive->drv_type=drv_fam2;
-                       }
-               }
-       }
-       if (!current_drive->drv_type)
-       {
-               /* check for TEAC CD-55A */
-               msg(DBG_TEA,"teac_possible: %d\n",teac_possible);
-               for (j=1;j<=((current_drive->drv_id==0)?3:1);j++)
-               {
-                       for (l=1;l<=((current_drive->drv_id==0)?10:1);l++)
-                       {
-                               msg(DBG_TEA,"TEAC reset #%d-%d.\n", j, l);
-                               if (sbpro_type==1) OUT(CDo_reset,0);
-                               else
-                               {
-                                       OUT(CDo_enable,current_drive->drv_sel);
-                                       OUT(CDo_sel_i_d,0);
-                                       OUT(CDo_command,CMDT_RESET);
-                                       for (i=0;i<9;i++) OUT(CDo_command,0);
-                               }
-                               sbp_sleep(5*HZ/10);
-                               OUT(CDo_enable,current_drive->drv_sel);
-                               OUT(CDo_sel_i_d,0);
-                               i=inb(CDi_status);
-                               msg(DBG_TEA,"TEAC CDi_status: %02X.\n",i);
-#if 0
-                               if (i&s_not_result_ready) continue; /* drive not present or ready */
-#endif
-                               i=inb(CDi_info);
-                               msg(DBG_TEA,"TEAC CDi_info: %02X.\n",i);
-                               if (i==0x55) break; /* drive found */
-                       }
-                       if (i==0x55) break; /* drive found */
-               }
-               if (i==0x55) /* drive found */
-               {
-                       msg(DBG_TEA,"TEAC drive found.\n");
-                       clr_cmdbuf();
-                       flags_cmd_out=f_putcmd;
-                       response_count=12;
-                       drvcmd[0]=CMDT_READ_VER;
-                       drvcmd[4]=response_count;
-                       for (i=0;i<12;i++) infobuf[i]=0;
-                       i=cmd_out_T();
-                       if (i!=0) msg(DBG_TEA,"cmd_out_T(CMDT_READ_VER) returns %d.\n",i);
-                       for (i=1;i<6;i++) if (infobuf[i]!=familyT[i-1]) break;
-                       if (i==6)
-                       {
-                               current_drive->drive_model[0]='C';
-                               current_drive->drive_model[1]='D';
-                               current_drive->drive_model[2]='-';
-                               current_drive->drive_model[3]='5';
-                               current_drive->drive_model[4]='5';
-                               current_drive->drive_model[5]=0;
-                               current_drive->drv_type=drv_famT;
-                       }
-               }
-       }
-       if (!current_drive->drv_type)
-       {
-               msg(DBG_TEA,"no drive found at address %03X under ID %d.\n",CDo_command,current_drive->drv_id);
-               return (-522);
-       }
-       for (j=0;j<4;j++) current_drive->firmware_version[j]=infobuf[i+j];
-       if (famL_drive)
-       {
-         u_char lcs_firm_e1[]="A E1";
-         u_char lcs_firm_f4[]="A4F4";
-               
-         for (j=0;j<4;j++)
-           if (current_drive->firmware_version[j]!=lcs_firm_e1[j]) break;
-         if (j==4) current_drive->drv_type=drv_e1;
-         
-         for (j=0;j<4;j++)
-           if (current_drive->firmware_version[j]!=lcs_firm_f4[j]) break;
-         if (j==4) current_drive->drv_type=drv_f4;
-
-         if (current_drive->drv_type==drv_famL) ask_mail();
-       }
-       else if (famT_drive)
-       {
-               j=infobuf[4]; /* one-byte version??? - here: 0x15 */
-               if (j=='5')
-               {
-                       current_drive->firmware_version[0]=infobuf[7];
-                       current_drive->firmware_version[1]=infobuf[8];
-                       current_drive->firmware_version[2]=infobuf[10];
-                       current_drive->firmware_version[3]=infobuf[11];
-               }
-               else
-               {
-                       if (j!=0x15) ask_mail();
-                       current_drive->firmware_version[0]='0';
-                       current_drive->firmware_version[1]='.';
-                       current_drive->firmware_version[2]='0'+(j>>4);
-                       current_drive->firmware_version[3]='0'+(j&0x0f);
-               }
-       }
-       else /* CR-52x, CR-56x, CD200, ECS-AT */
-       {
-               j = (current_drive->firmware_version[0] & 0x0F) * 100 +
-                       (current_drive->firmware_version[2] & 0x0F) *10 +
-                               (current_drive->firmware_version[3] & 0x0F);
-               if (fam0_drive)
-               {
-                       if (j<200) current_drive->drv_type=drv_199;
-                       else if (j<201) current_drive->drv_type=drv_200;
-                       else if (j<210) current_drive->drv_type=drv_201;
-                       else if (j<211) current_drive->drv_type=drv_210;
-                       else if (j<300) current_drive->drv_type=drv_211;
-                       else if (j>=300) current_drive->drv_type=drv_300;
-               }
-               else if (fam1_drive)
-               {
-                       if (j<100) current_drive->drv_type=drv_099;
-                       else
-                       {
-                               current_drive->drv_type=drv_100;
-                               if ((j!=500)&&(j!=102)) ask_mail();
-                       }
-               }
-               else if (fam2_drive)
-               {
-                       if (current_drive->drive_model[5]=='F')
-                       {
-                               if ((j!=1)&&(j!=35)&&(j!=200)&&(j!=210))
-                                 ask_mail(); /* unknown version at time */
-                       }
-                       else
-                       {
-                               msg(DBG_INF,"this CD200 drive is not fully supported yet - only audio will work.\n");
-                               if ((j!=101)&&(j!=35))
-                                 ask_mail(); /* unknown version at time */
-                       }
-               }
-               else if (famV_drive)
-                 {
-                   if ((j==100)||(j==150)) current_drive->drv_type=drv_at;
-                   ask_mail(); /* hopefully we get some feedback by this */
-                 }
-       }
-       msg(DBG_LCS,"drive type %02X\n",current_drive->drv_type);
-       msg(DBG_INI,"check_version done.\n");
-       return (0);
-}
-/*==========================================================================*/
-static void switch_drive(struct sbpcd_drive *p)
-{
-       current_drive = p;
-       OUT(CDo_enable,current_drive->drv_sel);
-       msg(DBG_DID,"drive %d (ID=%d) activated.\n",
-               current_drive - D_S, current_drive->drv_id);
-       return;
-}
-/*==========================================================================*/
-#ifdef PATH_CHECK
-/*
- * probe for the presence of an interface card
- */
-static int __init check_card(int port)
-{
-#undef N_RESPO
-#define N_RESPO 20
-       int i, j, k;
-       u_char response[N_RESPO];
-       u_char save_port0;
-       u_char save_port3;
-       
-       msg(DBG_INI,"check_card entered.\n");
-       save_port0=inb(port+0);
-       save_port3=inb(port+3);
-       
-       for (j=0;j<NR_SBPCD;j++)
-       {
-               OUT(port+3,j) ; /* enable drive #j */
-               OUT(port+0,CMD0_PATH_CHECK);
-               for (i=10;i>0;i--) OUT(port+0,0);
-               for (k=0;k<N_RESPO;k++) response[k]=0;
-               for (k=0;k<N_RESPO;k++)
-               {
-                       for (i=10000;i>0;i--)
-                       {
-                               if (inb(port+1)&s_not_result_ready) continue;
-                               response[k]=inb(port+0);
-                               break;
-                       }
-               }
-               for (i=0;i<N_RESPO;i++)
-                       sprintf(&msgbuf[i*3], " %02X", response[i]);
-               msgbuf[i*3]=0;
-               msg(DBG_TEA,"path check 00 (%d): %s\n", j, msgbuf);
-               OUT(port+0,CMD0_PATH_CHECK);
-               for (i=10;i>0;i--) OUT(port+0,0);
-               for (k=0;k<N_RESPO;k++) response[k]=0xFF;
-               for (k=0;k<N_RESPO;k++)
-               {
-                       for (i=10000;i>0;i--)
-                       {
-                               if (inb(port+1)&s_not_result_ready) continue;
-                               response[k]=inb(port+0);
-                               break;
-                       }
-               }
-               for (i=0;i<N_RESPO;i++)
-                       sprintf(&msgbuf[i*3], " %02X", response[i]);
-               msgbuf[i*3]=0;
-               msg(DBG_TEA,"path check 00 (%d): %s\n", j, msgbuf);
-
-               if (response[0]==0xAA)
-                       if (response[1]==0x55)
-                               return (0);
-       }
-       for (j=0;j<NR_SBPCD;j++)
-       {
-               OUT(port+3,j) ; /* enable drive #j */
-               OUT(port+0,CMD2_READ_VER);
-               for (i=10;i>0;i--) OUT(port+0,0);
-               for (k=0;k<N_RESPO;k++) response[k]=0;
-               for (k=0;k<N_RESPO;k++)
-               {
-                       for (i=1000000;i>0;i--)
-                       {
-                               if (inb(port+1)&s_not_result_ready) continue;
-                               response[k]=inb(port+0);
-                               break;
-                       }
-               }
-               for (i=0;i<N_RESPO;i++)
-                       sprintf(&msgbuf[i*3], " %02X", response[i]);
-               msgbuf[i*3]=0;
-               msg(DBG_TEA,"path check 12 (%d): %s\n", j, msgbuf);
-
-               OUT(port+0,CMD2_READ_VER);
-               for (i=10;i>0;i--) OUT(port+0,0);
-               for (k=0;k<N_RESPO;k++) response[k]=0xFF;
-               for (k=0;k<N_RESPO;k++)
-               {
-                       for (i=1000000;i>0;i--)
-                       {
-                               if (inb(port+1)&s_not_result_ready) continue;
-                               response[k]=inb(port+0);
-                               break;
-                       }
-               }
-               for (i=0;i<N_RESPO;i++)
-                       sprintf(&msgbuf[i*3], " %02X", response[i]);
-               msgbuf[i*3]=0;
-               msg(DBG_TEA,"path check 12 (%d): %s\n", j, msgbuf);
-
-               if (response[0]==0xAA)
-                       if (response[1]==0x55)
-                               return (0);
-       }
-       OUT(port+0,save_port0);
-       OUT(port+3,save_port3);
-       return (0); /* in any case - no real "function" at time */
-}
-#endif /* PATH_CHECK */ 
-/*==========================================================================*/
-/*==========================================================================*/
-/*
- * probe for the presence of drives on the selected controller
- */
-static int __init check_drives(void)
-{
-       int i, j;
-       
-       msg(DBG_INI,"check_drives entered.\n");
-       ndrives=0;
-       for (j=0;j<max_drives;j++)
-       {
-               struct sbpcd_drive *p = D_S + ndrives;
-               p->drv_id=j;
-               if (sbpro_type==1) p->drv_sel=(j&0x01)<<1|(j&0x02)>>1;
-               else p->drv_sel=j;
-               switch_drive(p);
-               msg(DBG_INI,"check_drives: drive %d (ID=%d) activated.\n",ndrives,j);
-               msg(DBG_000,"check_drives: drive %d (ID=%d) activated.\n",ndrives,j);
-               i=check_version();
-               if (i<0) msg(DBG_INI,"check_version returns %d.\n",i);
-               else
-               {
-                       current_drive->drv_options=drv_pattern[j];
-                       if (fam0L_drive) current_drive->drv_options&=~(speed_auto|speed_300|speed_150);
-                       msg(DBG_INF, "Drive %d (ID=%d): %.9s (%.4s) at 0x%03X (type %d)\n",
-                           current_drive - D_S,
-                           current_drive->drv_id,
-                           current_drive->drive_model,
-                           current_drive->firmware_version,
-                           CDo_command,
-                           sbpro_type);
-                       ndrives++;
-               }
-       }
-       for (j=ndrives;j<NR_SBPCD;j++) D_S[j].drv_id=-1;
-       if (ndrives==0) return (-1);
-       return (0);
-}
-/*==========================================================================*/
-#ifdef FUTURE
-/*
- *  obtain if requested service disturbs current audio state
- */            
-static int obey_audio_state(u_char audio_state, u_char func,u_char subfunc)
-{
-       switch (audio_state)                   /* audio status from controller  */
-       {
-       case aud_11: /* "audio play in progress" */
-       case audx11:
-               switch (func)                      /* DOS command code */
-               {
-               case cmd_07: /* input flush  */
-               case cmd_0d: /* open device  */
-               case cmd_0e: /* close device */
-               case cmd_0c: /* ioctl output */
-                       return (1);
-               case cmd_03: /* ioctl input  */
-                       switch (subfunc)
-                               /* DOS ioctl input subfunction */
-                       {
-                       case cxi_00:
-                       case cxi_06:
-                       case cxi_09:
-                               return (1);
-                       default:
-                               return (ERROR15);
-                       }
-                       return (1);
-               default:
-                       return (ERROR15);
-               }
-               return (1);
-       case aud_12:                  /* "audio play paused"      */
-       case audx12:
-               return (1);
-       default:
-               return (2);
-       }
-}
-/*==========================================================================*/
-/* allowed is only
- * ioctl_o, flush_input, open_device, close_device, 
- * tell_address, tell_volume, tell_capabiliti,
- * tell_framesize, tell_CD_changed, tell_audio_posi
- */
-static int check_allowed1(u_char func1, u_char func2)
-{
-#if 000
-       if (func1==ioctl_o) return (0);
-       if (func1==read_long) return (-1);
-       if (func1==read_long_prefetch) return (-1);
-       if (func1==seek) return (-1);
-       if (func1==audio_play) return (-1);
-       if (func1==audio_pause) return (-1);
-       if (func1==audio_resume) return (-1);
-       if (func1!=ioctl_i) return (0);
-       if (func2==tell_SubQ_run_tot) return (-1);
-       if (func2==tell_cdsize) return (-1);
-       if (func2==tell_TocDescrip) return (-1);
-       if (func2==tell_TocEntry) return (-1);
-       if (func2==tell_subQ_info) return (-1);
-       if (fam1_drive) if (func2==tell_SubChanInfo) return (-1);
-       if (func2==tell_UPC) return (-1);
-#else
-       return (0);
-#endif
-}
-/*==========================================================================*/
-static int check_allowed2(u_char func1, u_char func2)
-{
-#if 000
-       if (func1==read_long) return (-1);
-       if (func1==read_long_prefetch) return (-1);
-       if (func1==seek) return (-1);
-       if (func1==audio_play) return (-1);
-  if (func1!=ioctl_o) return (0);
-       if (fam1_drive)
-       {
-               if (func2==EjectDisk) return (-1);
-               if (func2==CloseTray) return (-1);
-       }
-#else
-       return (0);
-#endif
-}
-/*==========================================================================*/
-static int check_allowed3(u_char func1, u_char func2)
-{
-#if 000
-       if (func1==ioctl_i)
-       {
-               if (func2==tell_address) return (0);
-               if (func2==tell_capabiliti) return (0);
-               if (func2==tell_CD_changed) return (0);
-               if (fam0L_drive) if (func2==tell_SubChanInfo) return (0);
-               return (-1);
-       }
-       if (func1==ioctl_o)
-       {
-               if (func2==DriveReset) return (0);
-               if (fam0L_drive)
-               {
-                       if (func2==EjectDisk) return (0);
-                       if (func2==LockDoor) return (0);
-         if (func2==CloseTray) return (0);
-               }
-               return (-1);
-    }
-       if (func1==flush_input) return (-1);
-       if (func1==read_long) return (-1);
-       if (func1==read_long_prefetch) return (-1);
-       if (func1==seek) return (-1);
-       if (func1==audio_play) return (-1);
-       if (func1==audio_pause) return (-1);
-       if (func1==audio_resume) return (-1);
-#else
-       return (0);
-#endif
-}
-/*==========================================================================*/
-static int seek_pos_audio_end(void)
-{
-       int i;
-
-       i=msf2blk(current_drive->pos_audio_end)-1;
-       if (i<0) return (-1);
-       i=cc_Seek(i,0);
-       return (i);
-}
-#endif /* FUTURE */ 
-/*==========================================================================*/
-static int ReadToC(void)
-{
-       int i, j;
-       current_drive->diskstate_flags &= ~toc_bit;
-       current_drive->ored_ctl_adr=0;
-       /* special handling of CD-I HE */
-       if ((current_drive->n_first_track == 2 && current_drive->n_last_track == 2) ||
-             current_drive->xa_byte == 0x10)
-        {
-               current_drive->TocBuffer[1].nixbyte=0;
-               current_drive->TocBuffer[1].ctl_adr=0x40;
-               current_drive->TocBuffer[1].number=1;
-               current_drive->TocBuffer[1].format=0;
-               current_drive->TocBuffer[1].address=blk2msf(0);
-               current_drive->ored_ctl_adr |= 0x40;
-               current_drive->n_first_track = 1;
-               current_drive->n_last_track = 1;
-               current_drive->xa_byte = 0x10;
-                j = 2;
-        } else
-       for (j=current_drive->n_first_track;j<=current_drive->n_last_track;j++)
-       {
-               i=cc_ReadTocEntry(j);
-               if (i<0)
-               {
-                       msg(DBG_INF,"cc_ReadTocEntry(%d) returns %d.\n",j,i);
-                       return (i);
-               }
-               current_drive->TocBuffer[j].nixbyte=current_drive->TocEnt_nixbyte;
-               current_drive->TocBuffer[j].ctl_adr=current_drive->TocEnt_ctl_adr;
-               current_drive->TocBuffer[j].number=current_drive->TocEnt_number;
-               current_drive->TocBuffer[j].format=current_drive->TocEnt_format;
-               current_drive->TocBuffer[j].address=current_drive->TocEnt_address;
-               current_drive->ored_ctl_adr |= current_drive->TocEnt_ctl_adr;
-       }
-       /* fake entry for LeadOut Track */
-       current_drive->TocBuffer[j].nixbyte=0;
-       current_drive->TocBuffer[j].ctl_adr=0;
-       current_drive->TocBuffer[j].number=CDROM_LEADOUT;
-       current_drive->TocBuffer[j].format=0;
-       current_drive->TocBuffer[j].address=current_drive->size_msf;
-       
-       current_drive->diskstate_flags |= toc_bit;
-       return (0);
-}
-/*==========================================================================*/
-static int DiskInfo(void)
-{
-       int i, j;
-       
-       current_drive->mode=READ_M1;
-       
-#undef LOOP_COUNT
-#define LOOP_COUNT 10 /* needed for some "old" drives */
-       
-       msg(DBG_000,"DiskInfo entered.\n");
-       for (j=1;j<LOOP_COUNT;j++)
-       {
-#if 0
-               i=SetSpeed();
-               if (i<0)
-               {
-                       msg(DBG_INF,"DiskInfo: SetSpeed returns %d\n", i);
-                       continue;
-               }
-               i=cc_ModeSense();
-               if (i<0)
-               {
-                       msg(DBG_INF,"DiskInfo: cc_ModeSense returns %d\n", i);
-                       continue;
-               }
-#endif
-               i=cc_ReadCapacity();
-               if (i>=0) break;
-               msg(DBG_INF,"DiskInfo: ReadCapacity #%d returns %d\n", j, i);
-#if 0
-               i=cc_DriveReset();
-#endif
-               if (!fam0_drive && j == 2) break;
-       }
-       if (j==LOOP_COUNT) return (-33); /* give up */
-       
-       i=cc_ReadTocDescr();
-       if (i<0)
-       {
-               msg(DBG_INF,"DiskInfo: ReadTocDescr returns %d\n", i);
-               return (i);
-       }
-       i=ReadToC();
-       if (i<0)
-       {
-               msg(DBG_INF,"DiskInfo: ReadToC returns %d\n", i);
-               return (i);
-       }
-       i=cc_CheckMultiSession();
-       if (i<0)
-       {
-               msg(DBG_INF,"DiskInfo: cc_CheckMultiSession returns %d\n", i);
-               return (i);
-       }
-       if (current_drive->f_multisession) current_drive->sbp_bufsiz=1;  /* possibly a weird PhotoCD */
-       else current_drive->sbp_bufsiz=buffers;
-       i=cc_ReadTocEntry(current_drive->n_first_track);
-       if (i<0)
-       {
-               msg(DBG_INF,"DiskInfo: cc_ReadTocEntry(1) returns %d\n", i);
-               return (i);
-       }
-       i=cc_ReadUPC();
-       if (i<0) msg(DBG_INF,"DiskInfo: cc_ReadUPC returns %d\n", i);
-       if ((fam0L_drive) && (current_drive->xa_byte==0x20 || current_drive->xa_byte == 0x10))
-       {
-               /* XA disk with old drive */
-               cc_ModeSelect(CD_FRAMESIZE_RAW1);
-               cc_ModeSense();
-       }
-       if (famT_drive) cc_prep_mode_T();
-       msg(DBG_000,"DiskInfo done.\n");
-       return (0);
-}
-
-static int sbpcd_drive_status(struct cdrom_device_info *cdi, int slot_nr)
-{
-       struct sbpcd_drive *p = cdi->handle;
-       int st;
-
-       if (CDSL_CURRENT != slot_nr) {
-                /* we have no changer support */
-                return -EINVAL;
-       }
-
-        cc_ReadStatus();
-       st=ResponseStatus();
-       if (st<0)
-       {
-               msg(DBG_INF,"sbpcd_drive_status: timeout.\n");
-               return (0);
-       }
-       msg(DBG_000,"Drive Status: door_locked =%d.\n", st_door_locked);
-       msg(DBG_000,"Drive Status: door_closed =%d.\n", st_door_closed);
-       msg(DBG_000,"Drive Status: caddy_in =%d.\n", st_caddy_in);
-       msg(DBG_000,"Drive Status: disk_ok =%d.\n", st_diskok);
-       msg(DBG_000,"Drive Status: spinning =%d.\n", st_spinning);
-       msg(DBG_000,"Drive Status: busy =%d.\n", st_busy);
-
-#if 0
-  if (!(p->status_bits & p_door_closed)) return CDS_TRAY_OPEN;
-  if (p->status_bits & p_disk_ok) return CDS_DISC_OK;
-  if (p->status_bits & p_disk_in) return CDS_DRIVE_NOT_READY;
-
-  return CDS_NO_DISC;
-#else
-  if (p->status_bits & p_spinning) return CDS_DISC_OK;
-/*  return CDS_TRAY_OPEN; */
-  return CDS_NO_DISC;
-  
-#endif
-
-}
-
-
-/*==========================================================================*/
-#ifdef FUTURE
-/*
- *  called always if driver gets entered
- *  returns 0 or ERROR2 or ERROR15
- */
-static int prepare(u_char func, u_char subfunc)
-{
-       int i;
-       
-       if (fam0L_drive)
-       {
-               i=inb(CDi_status);
-               if (i&s_attention) GetStatus();
-       }
-       else if (fam1_drive) GetStatus();
-       else if (fam2_drive) GetStatus();
-       else if (famT_drive) GetStatus();
-       if (current_drive->CD_changed==0xFF)
-       {
-               current_drive->diskstate_flags=0;
-               current_drive->audio_state=0;
-               if (!st_diskok)
-               {
-                       i=check_allowed1(func,subfunc);
-                       if (i<0) return (-2);
-               }
-               else 
-               {
-                       i=check_allowed3(func,subfunc);
-                       if (i<0)
-                       {
-                               current_drive->CD_changed=1;
-                               return (-15);
-                       }
-               }
-       }
-       else
-       {
-               if (!st_diskok)
-               {
-                       current_drive->diskstate_flags=0;
-                       current_drive->audio_state=0;
-                       i=check_allowed1(func,subfunc);
-                       if (i<0) return (-2);
-               }
-               else
-               { 
-                       if (st_busy)
-                       {
-                               if (current_drive->audio_state!=audio_pausing)
-                               {
-                                       i=check_allowed2(func,subfunc);
-                                       if (i<0) return (-2);
-                               }
-                       }
-                       else
-                       {
-                               if (current_drive->audio_state==audio_playing) seek_pos_audio_end();
-                               current_drive->audio_state=0;
-                       }
-                       if (!frame_size_valid)
-                       {
-                               i=DiskInfo();
-                               if (i<0)
-                               {
-                                       current_drive->diskstate_flags=0;
-                                       current_drive->audio_state=0;
-                                       i=check_allowed1(func,subfunc);
-                                       if (i<0) return (-2);
-                               }
-                       }
-               }
-    }
-       return (0);
-}
-#endif /* FUTURE */ 
-/*==========================================================================*/
-/*==========================================================================*/
-/*
- * Check the results of the "get status" command.
- */
-static int sbp_status(void)
-{
-       int st;
-       
-       st=ResponseStatus();
-       if (st<0)
-       {
-               msg(DBG_INF,"sbp_status: timeout.\n");
-               return (0);
-       }
-       
-       if (!st_spinning) msg(DBG_SPI,"motor got off - ignoring.\n");
-       
-       if (st_check) 
-       {
-               msg(DBG_INF,"st_check detected - retrying.\n");
-               return (0);
-       }
-       if (!st_door_closed)
-       {
-               msg(DBG_INF,"door is open - retrying.\n");
-               return (0);
-       }
-       if (!st_caddy_in)
-       {
-               msg(DBG_INF,"disk removed - retrying.\n");
-               return (0);
-       }
-       if (!st_diskok) 
-       {
-               msg(DBG_INF,"!st_diskok detected - retrying.\n");
-               return (0);
-       }
-       if (st_busy) 
-       {
-               msg(DBG_INF,"st_busy detected - retrying.\n");
-               return (0);
-       }
-       return (1);
-}
-/*==========================================================================*/
-               
-static int sbpcd_get_last_session(struct cdrom_device_info *cdi, struct cdrom_multisession *ms_infp)
-{
-       struct sbpcd_drive *p = cdi->handle;
-       ms_infp->addr_format = CDROM_LBA;
-       ms_infp->addr.lba    = p->lba_multi;
-       if (p->f_multisession)
-               ms_infp->xa_flag=1; /* valid redirection address */
-       else
-               ms_infp->xa_flag=0; /* invalid redirection address */
-
-       return  0;
-}
-
-static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
-                      void * arg)
-{
-       struct sbpcd_drive *p = cdi->handle;
-       int i, st, j;
-       
-       msg(DBG_IO2,"ioctl(%s, 0x%08lX, 0x%08p)\n", cdi->name, cmd, arg);
-       if (p->drv_id==-1) {
-               msg(DBG_INF, "ioctl: bad device: %s\n", cdi->name);
-               return (-ENXIO);             /* no such drive */
-       }
-       down(&ioctl_read_sem);
-       if (p != current_drive)
-               switch_drive(p);
-       
-       msg(DBG_IO2,"ioctl: device %s, request %04X\n",cdi->name,cmd);
-       switch (cmd)            /* Sun-compatible */
-       {
-               
-       case CDROMPAUSE:     /* Pause the drive */
-               msg(DBG_IOC,"ioctl: CDROMPAUSE entered.\n");
-               /* pause the drive unit when it is currently in PLAY mode,         */
-               /* or reset the starting and ending locations when in PAUSED mode. */
-               /* If applicable, at the next stopping point it reaches            */
-               /* the drive will discontinue playing.                             */
-               switch (current_drive->audio_state)
-               {
-               case audio_playing:
-                       if (famL_drive) i=cc_ReadSubQ();
-                       else i=cc_Pause_Resume(1);
-                       if (i<0) RETURN_UP(-EIO);
-                       if (famL_drive) i=cc_Pause_Resume(1);
-                       else i=cc_ReadSubQ();
-                       if (i<0) RETURN_UP(-EIO);
-                       current_drive->pos_audio_start=current_drive->SubQ_run_tot;
-                       current_drive->audio_state=audio_pausing;
-                       RETURN_UP(0);
-               case audio_pausing:
-                       i=cc_Seek(current_drive->pos_audio_start,1);
-                       if (i<0) RETURN_UP(-EIO);
-                       RETURN_UP(0);
-               default:
-                       RETURN_UP(-EINVAL);
-               }
-
-       case CDROMRESUME: /* resume paused audio play */
-               msg(DBG_IOC,"ioctl: CDROMRESUME entered.\n");
-               /* resume playing audio tracks when a previous PLAY AUDIO call has  */
-               /* been paused with a PAUSE command.                                */
-               /* It will resume playing from the location saved in SubQ_run_tot.  */
-               if (current_drive->audio_state!=audio_pausing) RETURN_UP(-EINVAL);
-               if (famL_drive)
-                       i=cc_PlayAudio(current_drive->pos_audio_start,
-                                      current_drive->pos_audio_end);
-               else i=cc_Pause_Resume(3);
-               if (i<0) RETURN_UP(-EIO);
-               current_drive->audio_state=audio_playing;
-               RETURN_UP(0);
-
-       case CDROMPLAYMSF:
-               msg(DBG_IOC,"ioctl: CDROMPLAYMSF entered.\n");
-#ifdef SAFE_MIXED
-               if (current_drive->has_data>1) RETURN_UP(-EBUSY);
-#endif /* SAFE_MIXED */
-               if (current_drive->audio_state==audio_playing)
-               {
-                       i=cc_Pause_Resume(1);
-                       if (i<0) RETURN_UP(-EIO);
-                       i=cc_ReadSubQ();
-                       if (i<0) RETURN_UP(-EIO);
-                       current_drive->pos_audio_start=current_drive->SubQ_run_tot;
-                       i=cc_Seek(current_drive->pos_audio_start,1);
-               }
-               memcpy(&msf, (void *) arg, sizeof(struct cdrom_msf));
-               /* values come as msf-bin */
-               current_drive->pos_audio_start = (msf.cdmsf_min0<<16) |
-                        (msf.cdmsf_sec0<<8) |
-                               msf.cdmsf_frame0;
-               current_drive->pos_audio_end = (msf.cdmsf_min1<<16) |
-                       (msf.cdmsf_sec1<<8) |
-                               msf.cdmsf_frame1;
-               msg(DBG_IOX,"ioctl: CDROMPLAYMSF %08X %08X\n",
-                   current_drive->pos_audio_start,current_drive->pos_audio_end);
-               i=cc_PlayAudio(current_drive->pos_audio_start,current_drive->pos_audio_end);
-               if (i<0)
-               {
-                       msg(DBG_INF,"ioctl: cc_PlayAudio returns %d\n",i);
-                       DriveReset();
-                       current_drive->audio_state=0;
-                       RETURN_UP(-EIO);
-               }
-               current_drive->audio_state=audio_playing;
-               RETURN_UP(0);
-               
-       case CDROMPLAYTRKIND: /* Play a track.  This currently ignores index. */
-               msg(DBG_IOC,"ioctl: CDROMPLAYTRKIND entered.\n");
-#ifdef SAFE_MIXED
-               if (current_drive->has_data>1) RETURN_UP(-EBUSY);
-#endif /* SAFE_MIXED */
-               if (current_drive->audio_state==audio_playing)
-               {
-                       msg(DBG_IOX,"CDROMPLAYTRKIND: already audio_playing.\n");
-#if 1
-                       RETURN_UP(0); /* just let us play on */
-#else
-                       RETURN_UP(-EINVAL); /* play on, but say "error" */
-#endif
-               }
-               memcpy(&ti,(void *) arg,sizeof(struct cdrom_ti));
-               msg(DBG_IOX,"ioctl: trk0: %d, ind0: %d, trk1:%d, ind1:%d\n",
-                   ti.cdti_trk0,ti.cdti_ind0,ti.cdti_trk1,ti.cdti_ind1);
-               if (ti.cdti_trk0<current_drive->n_first_track) RETURN_UP(-EINVAL);
-               if (ti.cdti_trk0>current_drive->n_last_track) RETURN_UP(-EINVAL);
-               if (ti.cdti_trk1<ti.cdti_trk0) ti.cdti_trk1=ti.cdti_trk0;
-               if (ti.cdti_trk1>current_drive->n_last_track) ti.cdti_trk1=current_drive->n_last_track;
-               current_drive->pos_audio_start=current_drive->TocBuffer[ti.cdti_trk0].address;
-               current_drive->pos_audio_end=current_drive->TocBuffer[ti.cdti_trk1+1].address;
-               i=cc_PlayAudio(current_drive->pos_audio_start,current_drive->pos_audio_end);
-               if (i<0)
-               {
-                       msg(DBG_INF,"ioctl: cc_PlayAudio returns %d\n",i);
-                       DriveReset();
-                       current_drive->audio_state=0;
-                       RETURN_UP(-EIO);
-               }
-               current_drive->audio_state=audio_playing;
-               RETURN_UP(0);
-               
-       case CDROMREADTOCHDR:        /* Read the table of contents header */
-               msg(DBG_IOC,"ioctl: CDROMREADTOCHDR entered.\n");
-               tochdr.cdth_trk0=current_drive->n_first_track;
-               tochdr.cdth_trk1=current_drive->n_last_track;
-               memcpy((void *) arg, &tochdr, sizeof(struct cdrom_tochdr));
-               RETURN_UP(0);
-               
-       case CDROMREADTOCENTRY:      /* Read an entry in the table of contents */
-               msg(DBG_IOC,"ioctl: CDROMREADTOCENTRY entered.\n");
-               memcpy(&tocentry, (void *) arg, sizeof(struct cdrom_tocentry));
-               i=tocentry.cdte_track;
-               if (i==CDROM_LEADOUT) i=current_drive->n_last_track+1;
-               else if (i<current_drive->n_first_track||i>current_drive->n_last_track)
-                  RETURN_UP(-EINVAL);
-               tocentry.cdte_adr=current_drive->TocBuffer[i].ctl_adr&0x0F;
-               tocentry.cdte_ctrl=(current_drive->TocBuffer[i].ctl_adr>>4)&0x0F;
-               tocentry.cdte_datamode=current_drive->TocBuffer[i].format;
-               if (tocentry.cdte_format==CDROM_MSF) /* MSF-bin required */
-               {
-                       tocentry.cdte_addr.msf.minute=(current_drive->TocBuffer[i].address>>16)&0x00FF;
-                       tocentry.cdte_addr.msf.second=(current_drive->TocBuffer[i].address>>8)&0x00FF;
-                       tocentry.cdte_addr.msf.frame=current_drive->TocBuffer[i].address&0x00FF;
-               }
-               else if (tocentry.cdte_format==CDROM_LBA) /* blk required */
-                       tocentry.cdte_addr.lba=msf2blk(current_drive->TocBuffer[i].address);
-               else RETURN_UP(-EINVAL);
-               memcpy((void *) arg, &tocentry, sizeof(struct cdrom_tocentry));
-               RETURN_UP(0);
-               
-       case CDROMSTOP:      /* Spin down the drive */
-               msg(DBG_IOC,"ioctl: CDROMSTOP entered.\n");
-#ifdef SAFE_MIXED
-               if (current_drive->has_data>1) RETURN_UP(-EBUSY);
-#endif /* SAFE_MIXED */ 
-               i=cc_Pause_Resume(1);
-               current_drive->audio_state=0;
-#if 0
-               cc_DriveReset();
-#endif
-               RETURN_UP(i);
-
-       case CDROMSTART:  /* Spin up the drive */
-               msg(DBG_IOC,"ioctl: CDROMSTART entered.\n");
-               cc_SpinUp();
-               current_drive->audio_state=0;
-               RETURN_UP(0);
-
-       case CDROMVOLCTRL:   /* Volume control */
-               msg(DBG_IOC,"ioctl: CDROMVOLCTRL entered.\n");
-               memcpy(&volctrl,(char *) arg,sizeof(volctrl));
-               current_drive->vol_chan0=0;
-               current_drive->vol_ctrl0=volctrl.channel0;
-               current_drive->vol_chan1=1;
-               current_drive->vol_ctrl1=volctrl.channel1;
-               i=cc_SetVolume();
-               RETURN_UP(0);
-
-       case CDROMVOLREAD:   /* read Volume settings from drive */
-               msg(DBG_IOC,"ioctl: CDROMVOLREAD entered.\n");
-               st=cc_GetVolume();
-               if (st<0) RETURN_UP(st);
-               volctrl.channel0=current_drive->vol_ctrl0;
-               volctrl.channel1=current_drive->vol_ctrl1;
-               volctrl.channel2=0;
-               volctrl.channel2=0;
-               memcpy((void *)arg,&volctrl,sizeof(volctrl));
-               RETURN_UP(0);
-
-       case CDROMSUBCHNL:   /* Get subchannel info */
-               msg(DBG_IOS,"ioctl: CDROMSUBCHNL entered.\n");
-               /* Bogus, I can do better than this! --AJK
-               if ((st_spinning)||(!subq_valid)) {
-                       i=cc_ReadSubQ();
-                       if (i<0) RETURN_UP(-EIO);
-               }
-               */
-               i=cc_ReadSubQ();
-               if (i<0) {
-                       j=cc_ReadError(); /* clear out error status from drive */
-                       current_drive->audio_state=CDROM_AUDIO_NO_STATUS;
-                       /* get and set the disk state here,
-                       probably not the right place, but who cares!
-                       It makes it work properly! --AJK */
-                       if (current_drive->CD_changed==0xFF) {
-                               msg(DBG_000,"Disk changed detect\n");
-                               current_drive->diskstate_flags &= ~cd_size_bit;
-                       }
-                       RETURN_UP(-EIO);
-               }
-               if (current_drive->CD_changed==0xFF) {
-                       /* reread the TOC because the disk has changed! --AJK */
-                       msg(DBG_000,"Disk changed STILL detected, rereading TOC!\n");
-                       i=DiskInfo();
-                       if(i==0) {
-                               current_drive->CD_changed=0x00; /* cd has changed, procede, */
-                               RETURN_UP(-EIO); /* and get TOC, etc on next try! --AJK */
-                       } else {
-                               RETURN_UP(-EIO); /* we weren't ready yet! --AJK */
-                       }
-               }
-               memcpy(&SC, (void *) arg, sizeof(struct cdrom_subchnl));
-               /*
-                       This virtual crap is very bogus!
-                       It doesn't detect when the cd is done playing audio!
-                       Lets do this right with proper hardware register reading!
-               */
-               cc_ReadStatus();
-               i=ResponseStatus();
-               msg(DBG_000,"Drive Status: door_locked =%d.\n", st_door_locked);
-               msg(DBG_000,"Drive Status: door_closed =%d.\n", st_door_closed);
-               msg(DBG_000,"Drive Status: caddy_in =%d.\n", st_caddy_in);
-               msg(DBG_000,"Drive Status: disk_ok =%d.\n", st_diskok);
-               msg(DBG_000,"Drive Status: spinning =%d.\n", st_spinning);
-               msg(DBG_000,"Drive Status: busy =%d.\n", st_busy);
-               /* st_busy indicates if it's _ACTUALLY_ playing audio */
-               switch (current_drive->audio_state)
-               {
-               case audio_playing:
-                       if(st_busy==0) {
-                               /* CD has stopped playing audio --AJK */
-                               current_drive->audio_state=audio_completed;
-                               SC.cdsc_audiostatus=CDROM_AUDIO_COMPLETED;
-                       } else {
-                               SC.cdsc_audiostatus=CDROM_AUDIO_PLAY;
-                       }
-                       break;
-               case audio_pausing:
-                       SC.cdsc_audiostatus=CDROM_AUDIO_PAUSED;
-                       break;
-               case audio_completed:
-                       SC.cdsc_audiostatus=CDROM_AUDIO_COMPLETED;
-                       break;
-               default:
-                       SC.cdsc_audiostatus=CDROM_AUDIO_NO_STATUS;
-                       break;
-               }
-               SC.cdsc_adr=current_drive->SubQ_ctl_adr;
-               SC.cdsc_ctrl=current_drive->SubQ_ctl_adr>>4;
-               SC.cdsc_trk=bcd2bin(current_drive->SubQ_trk);
-               SC.cdsc_ind=bcd2bin(current_drive->SubQ_pnt_idx);
-               if (SC.cdsc_format==CDROM_LBA)
-               {
-                       SC.cdsc_absaddr.lba=msf2blk(current_drive->SubQ_run_tot);
-                       SC.cdsc_reladdr.lba=msf2blk(current_drive->SubQ_run_trk);
-               }
-               else /* not only if (SC.cdsc_format==CDROM_MSF) */
-               {
-                       SC.cdsc_absaddr.msf.minute=(current_drive->SubQ_run_tot>>16)&0x00FF;
-                       SC.cdsc_absaddr.msf.second=(current_drive->SubQ_run_tot>>8)&0x00FF;
-                       SC.cdsc_absaddr.msf.frame=current_drive->SubQ_run_tot&0x00FF;
-                       SC.cdsc_reladdr.msf.minute=(current_drive->SubQ_run_trk>>16)&0x00FF;
-                       SC.cdsc_reladdr.msf.second=(current_drive->SubQ_run_trk>>8)&0x00FF;
-                       SC.cdsc_reladdr.msf.frame=current_drive->SubQ_run_trk&0x00FF;
-               }
-               memcpy((void *) arg, &SC, sizeof(struct cdrom_subchnl));
-               msg(DBG_IOS,"CDROMSUBCHNL: %1X %02X %08X %08X %02X %02X %06X %06X\n",
-                   SC.cdsc_format,SC.cdsc_audiostatus,
-                   SC.cdsc_adr,SC.cdsc_ctrl,
-                   SC.cdsc_trk,SC.cdsc_ind,
-                   SC.cdsc_absaddr,SC.cdsc_reladdr);
-               RETURN_UP(0);
-
-       default:
-               msg(DBG_IOC,"ioctl: unknown function request %04X\n", cmd);
-               RETURN_UP(-EINVAL);
-       } /* end switch(cmd) */
-}
-/*==========================================================================*/
-/*
- *  Take care of the different block sizes between cdrom and Linux.
- */
-static void sbp_transfer(struct request *req)
-{
-       long offs;
-
-       while ( (req->nr_sectors > 0) &&
-              (req->sector/4 >= current_drive->sbp_first_frame) &&
-              (req->sector/4 <= current_drive->sbp_last_frame) )
-       {
-               offs = (req->sector - current_drive->sbp_first_frame * 4) * 512;
-               memcpy(req->buffer, current_drive->sbp_buf + offs, 512);
-               req->nr_sectors--;
-               req->sector++;
-               req->buffer += 512;
-       }
-}
-/*==========================================================================*/
-/*
- *  special end_request for sbpcd to solve CURRENT==NULL bug. (GTL)
- *  GTL = Gonzalo Tornaria <tornaria@cmat.edu.uy>
- *
- *  This is a kludge so we don't need to modify end_request.
- *  We put the req we take out after INIT_REQUEST in the requests list,
- *  so that end_request will discard it.
- *
- *  The bug could be present in other block devices, perhaps we
- *  should modify INIT_REQUEST and end_request instead, and
- *  change every block device..
- *
- *  Could be a race here?? Could e.g. a timer interrupt schedule() us?
- *  If so, we should copy end_request here, and do it right.. (or
- *  modify end_request and the block devices).
- *
- *  In any case, the race here would be much small than it was, and
- *  I couldn't reproduce..
- *
- *  The race could be: suppose CURRENT==NULL. We put our req in the list,
- *  and we are scheduled. Other process takes over, and gets into
- *  do_sbpcd_request. It sees CURRENT!=NULL (it is == to our req), so
- *  proceeds. It ends, so CURRENT is now NULL.. Now we awake somewhere in
- *  end_request, but now CURRENT==NULL... oops!
- *
- */
-#undef DEBUG_GTL
-
-/*==========================================================================*/
-/*
- *  I/O request routine, called from Linux kernel.
- */
-static void do_sbpcd_request(request_queue_t * q)
-{
-       u_int block;
-       u_int nsect;
-       int status_tries, data_tries;
-       struct request *req;
-       struct sbpcd_drive *p;
-#ifdef DEBUG_GTL
-       static int xx_nr=0;
-       int xnr;
-#endif
-
- request_loop:
-#ifdef DEBUG_GTL
-       xnr=++xx_nr;
-
-       req = elv_next_request(q);
-
-       if (!req)
-       {
-               printk( "do_sbpcd_request[%di](NULL), Pid:%d, Time:%li\n",
-                       xnr, current->pid, jiffies);
-               printk( "do_sbpcd_request[%do](NULL) end 0 (null), Time:%li\n",
-                       xnr, jiffies);
-               return;
-       }
-
-       printk(" do_sbpcd_request[%di](%p:%ld+%ld), Pid:%d, Time:%li\n",
-               xnr, req, req->sector, req->nr_sectors, current->pid, jiffies);
-#endif
-
-       req = elv_next_request(q);      /* take out our request so no other */
-       if (!req)
-               return;
-
-       if (req -> sector == -1)
-               end_request(req, 0);
-       spin_unlock_irq(q->queue_lock);
-
-       down(&ioctl_read_sem);
-       if (rq_data_dir(elv_next_request(q)) != READ)
-       {
-               msg(DBG_INF, "bad cmd %d\n", req->cmd[0]);
-               goto err_done;
-       }
-       p = req->rq_disk->private_data;
-#if OLD_BUSY
-       while (busy_audio) sbp_sleep(HZ); /* wait a bit */
-       busy_data=1;
-#endif /* OLD_BUSY */
-
-       if (p->audio_state==audio_playing) goto err_done;
-       if (p != current_drive)
-               switch_drive(p);
-
-       block = req->sector; /* always numbered as 512-byte-pieces */
-       nsect = req->nr_sectors; /* always counted as 512-byte-pieces */
-
-       msg(DBG_BSZ,"read sector %d (%d sectors)\n", block, nsect);
-#if 0
-       msg(DBG_MUL,"read LBA %d\n", block/4);
-#endif
-
-       sbp_transfer(req);
-       /* if we satisfied the request from the buffer, we're done. */
-       if (req->nr_sectors == 0)
-       {
-#ifdef DEBUG_GTL
-               printk(" do_sbpcd_request[%do](%p:%ld+%ld) end 2, Time:%li\n",
-                       xnr, req, req->sector, req->nr_sectors, jiffies);
-#endif
-               up(&ioctl_read_sem);
-               spin_lock_irq(q->queue_lock);
-               end_request(req, 1);
-               goto request_loop;
-       }
-
-#ifdef FUTURE
-       i=prepare(0,0); /* at moment not really a hassle check, but ... */
-       if (i!=0)
-               msg(DBG_INF,"\"prepare\" tells error %d -- ignored\n", i);
-#endif /* FUTURE */
-
-       if (!st_spinning) cc_SpinUp();
-
-       for (data_tries=n_retries; data_tries > 0; data_tries--)
-       {
-               for (status_tries=3; status_tries > 0; status_tries--)
-               {
-                       flags_cmd_out |= f_respo3;
-                       cc_ReadStatus();
-                       if (sbp_status() != 0) break;
-                       if (st_check) cc_ReadError();
-                       sbp_sleep(1);    /* wait a bit, try again */
-               }
-               if (status_tries == 0)
-               {
-                       msg(DBG_INF,"sbp_status: failed after 3 tries in line %d\n", __LINE__);
-                       break;
-               }
-               
-               sbp_read_cmd(req);
-               sbp_sleep(0);
-               if (sbp_data(req) != 0)
-               {
-#ifdef SAFE_MIXED
-                       current_drive->has_data=2; /* is really a data disk */
-#endif /* SAFE_MIXED */
-#ifdef DEBUG_GTL
-                       printk(" do_sbpcd_request[%do](%p:%ld+%ld) end 3, Time:%li\n",
-                               xnr, req, req->sector, req->nr_sectors, jiffies);
-#endif
-                       up(&ioctl_read_sem);
-                       spin_lock_irq(q->queue_lock);
-                       end_request(req, 1);
-                       goto request_loop;
-               }
-       }
-
- err_done:
-#if OLD_BUSY
-       busy_data=0;
-#endif /* OLD_BUSY */
-#ifdef DEBUG_GTL
-       printk(" do_sbpcd_request[%do](%p:%ld+%ld) end 4 (error), Time:%li\n",
-               xnr, req, req->sector, req->nr_sectors, jiffies);
-#endif
-       up(&ioctl_read_sem);
-       sbp_sleep(0);    /* wait a bit, try again */
-       spin_lock_irq(q->queue_lock);
-       end_request(req, 0);
-       goto request_loop;
-}
-/*==========================================================================*/
-/*
- *  build and send the READ command.
- */
-static void sbp_read_cmd(struct request *req)
-{
-#undef OLD
-
-       int i;
-       int block;
-
-       current_drive->sbp_first_frame=current_drive->sbp_last_frame=-1;      /* purge buffer */
-       current_drive->sbp_current = 0;
-       block=req->sector/4;
-       if (block+current_drive->sbp_bufsiz <= current_drive->CDsize_frm)
-               current_drive->sbp_read_frames = current_drive->sbp_bufsiz;
-       else
-       {
-               current_drive->sbp_read_frames=current_drive->CDsize_frm-block;
-               /* avoid reading past end of data */
-               if (current_drive->sbp_read_frames < 1)
-               {
-                       msg(DBG_INF,"requested frame %d, CD size %d ???\n",
-                           block, current_drive->CDsize_frm);
-                       current_drive->sbp_read_frames=1;
-               }
-       }
-
-       flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus | f_obey_p_check;
-       clr_cmdbuf();
-       if (famV_drive)
-         {
-           drvcmd[0]=CMDV_READ;
-           lba2msf(block,&drvcmd[1]); /* msf-bcd format required */
-           bin2bcdx(&drvcmd[1]);
-           bin2bcdx(&drvcmd[2]);
-           bin2bcdx(&drvcmd[3]);
-           drvcmd[4]=current_drive->sbp_read_frames>>8;
-           drvcmd[5]=current_drive->sbp_read_frames&0xff;
-           drvcmd[6]=0x02; /* flag "msf-bcd" */
-       }
-       else if (fam0L_drive)
-       {
-               flags_cmd_out |= f_lopsta | f_getsta | f_bit1;
-               if (current_drive->xa_byte==0x20)
-               {
-                       cmd_type=READ_M2;
-                       drvcmd[0]=CMD0_READ_XA; /* "read XA frames", old drives */
-                       drvcmd[1]=(block>>16)&0x0ff;
-                       drvcmd[2]=(block>>8)&0x0ff;
-                       drvcmd[3]=block&0x0ff;
-                       drvcmd[4]=(current_drive->sbp_read_frames>>8)&0x0ff;
-                       drvcmd[5]=current_drive->sbp_read_frames&0x0ff;
-               }
-               else
-               {
-                       drvcmd[0]=CMD0_READ; /* "read frames", old drives */
-                       if (current_drive->drv_type>=drv_201)
-                       {
-                               lba2msf(block,&drvcmd[1]); /* msf-bcd format required */
-                               bin2bcdx(&drvcmd[1]);
-                               bin2bcdx(&drvcmd[2]);
-                               bin2bcdx(&drvcmd[3]);
-                       }
-                       else
-                       {
-                               drvcmd[1]=(block>>16)&0x0ff;
-                               drvcmd[2]=(block>>8)&0x0ff;
-                               drvcmd[3]=block&0x0ff;
-                       }
-                       drvcmd[4]=(current_drive->sbp_read_frames>>8)&0x0ff;
-                       drvcmd[5]=current_drive->sbp_read_frames&0x0ff;
-                       drvcmd[6]=(current_drive->drv_type<drv_201)?0:2; /* flag "lba or msf-bcd format" */
-               }
-       }
-       else if (fam1_drive)
-       {
-               drvcmd[0]=CMD1_READ;
-               lba2msf(block,&drvcmd[1]); /* msf-bin format required */
-               drvcmd[5]=(current_drive->sbp_read_frames>>8)&0x0ff;
-               drvcmd[6]=current_drive->sbp_read_frames&0x0ff;
-       }
-       else if (fam2_drive)
-       {
-               drvcmd[0]=CMD2_READ;
-               lba2msf(block,&drvcmd[1]); /* msf-bin format required */
-               drvcmd[4]=(current_drive->sbp_read_frames>>8)&0x0ff;
-               drvcmd[5]=current_drive->sbp_read_frames&0x0ff;
-               drvcmd[6]=0x02;
-       }
-       else if (famT_drive)
-       {
-               drvcmd[0]=CMDT_READ;
-               drvcmd[2]=(block>>24)&0x0ff;
-               drvcmd[3]=(block>>16)&0x0ff;
-               drvcmd[4]=(block>>8)&0x0ff;
-               drvcmd[5]=block&0x0ff;
-               drvcmd[7]=(current_drive->sbp_read_frames>>8)&0x0ff;
-               drvcmd[8]=current_drive->sbp_read_frames&0x0ff;
-       }
-       flags_cmd_out=f_putcmd;
-       response_count=0;
-       i=cmd_out();
-       if (i<0) msg(DBG_INF,"error giving READ command: %0d\n", i);
-       return;
-}
-/*==========================================================================*/
-/*
- *  Check the completion of the read-data command.  On success, read
- *  the current_drive->sbp_bufsiz * 2048 bytes of data from the disk into buffer.
- */
-static int sbp_data(struct request *req)
-{
-       int i=0, j=0, l, frame;
-       u_int try=0;
-       u_long timeout;
-       u_char *p;
-       u_int data_tries = 0;
-       u_int data_waits = 0;
-       u_int data_retrying = 0;
-       int error_flag;
-       int xa_count;
-       int max_latency;
-       int success;
-       int wait;
-       int duration;
-
-       error_flag=0;
-       success=0;
-#if LONG_TIMING
-       max_latency=9*HZ;
-#else
-       if (current_drive->f_multisession) max_latency=15*HZ;
-       else max_latency=5*HZ;
-#endif
-       duration=jiffies;
-       for (frame=0;frame<current_drive->sbp_read_frames&&!error_flag; frame++)
-       {
-               SBPCD_CLI;
-
-               del_timer(&data_timer);
-               data_timer.expires=jiffies+max_latency;
-               timed_out_data=0;
-               add_timer(&data_timer);
-               while (!timed_out_data)
-               {
-                       if (current_drive->f_multisession) try=maxtim_data*4;
-                       else try=maxtim_data;
-                       msg(DBG_000,"sbp_data: CDi_status loop: try=%d.\n",try);
-                       for ( ; try!=0;try--)
-                       {
-                               j=inb(CDi_status);
-                               if (!(j&s_not_data_ready)) break;
-                               if (!(j&s_not_result_ready)) break;
-                               if (fam0LV_drive) if (j&s_attention) break;
-                       }
-                       if (!(j&s_not_data_ready)) goto data_ready;
-                       if (try==0)
-                       {
-                               if (data_retrying == 0) data_waits++;
-                               data_retrying = 1;
-                               msg(DBG_000,"sbp_data: CDi_status loop: sleeping.\n");
-                               sbp_sleep(1);
-                               try = 1;
-                       }
-               }
-               msg(DBG_INF,"sbp_data: CDi_status loop expired.\n");
-       data_ready:
-               del_timer(&data_timer);
-
-               if (timed_out_data)
-               {
-                       msg(DBG_INF,"sbp_data: CDi_status timeout (timed_out_data) (%02X).\n", j);
-                       error_flag++;
-               }
-               if (try==0)
-               {
-                       msg(DBG_INF,"sbp_data: CDi_status timeout (try=0) (%02X).\n", j);
-                       error_flag++;
-               }
-               if (!(j&s_not_result_ready))
-               {
-                       msg(DBG_INF, "sbp_data: RESULT_READY where DATA_READY awaited (%02X).\n", j);
-                       response_count=20;
-                       j=ResponseInfo();
-                       j=inb(CDi_status);
-               }
-               if (j&s_not_data_ready)
-               {
-                       if ((current_drive->ored_ctl_adr&0x40)==0)
-                               msg(DBG_INF, "CD contains no data tracks.\n");
-                       else msg(DBG_INF, "sbp_data: DATA_READY timeout (%02X).\n", j);
-                       error_flag++;
-               }
-               SBPCD_STI;
-               if (error_flag) break;
-
-               msg(DBG_000, "sbp_data: beginning to read.\n");
-               p = current_drive->sbp_buf + frame *  CD_FRAMESIZE;
-               if (sbpro_type==1) OUT(CDo_sel_i_d,1);
-               if (cmd_type==READ_M2) {
-                        if (do_16bit) insw(CDi_data, xa_head_buf, CD_XA_HEAD>>1);
-                        else insb(CDi_data, xa_head_buf, CD_XA_HEAD);
-               }
-               if (do_16bit) insw(CDi_data, p, CD_FRAMESIZE>>1);
-               else insb(CDi_data, p, CD_FRAMESIZE);
-               if (cmd_type==READ_M2) {
-                        if (do_16bit) insw(CDi_data, xa_tail_buf, CD_XA_TAIL>>1);
-                        else insb(CDi_data, xa_tail_buf, CD_XA_TAIL);
-               }
-               current_drive->sbp_current++;
-               if (sbpro_type==1) OUT(CDo_sel_i_d,0);
-               if (cmd_type==READ_M2)
-               {
-                       for (xa_count=0;xa_count<CD_XA_HEAD;xa_count++)
-                               sprintf(&msgbuf[xa_count*3], " %02X", xa_head_buf[xa_count]);
-                       msgbuf[xa_count*3]=0;
-                       msg(DBG_XA1,"xa head:%s\n", msgbuf);
-               }
-               data_retrying = 0;
-               data_tries++;
-               if (data_tries >= 1000)
-               {
-                       msg(DBG_INF,"sbp_data() statistics: %d waits in %d frames.\n", data_waits, data_tries);
-                       data_waits = data_tries = 0;
-               }
-       }
-       duration=jiffies-duration;
-       msg(DBG_TEA,"time to read %d frames: %d jiffies .\n",frame,duration);
-       if (famT_drive)
-       {
-               wait=8;
-               do
-               {
-                       if (teac==2)
-                          {
-                            if ((i=CDi_stat_loop_T()) == -1) break;
-                          }
-                        else
-                          {
-                            sbp_sleep(1);
-                            OUT(CDo_sel_i_d,0);
-                            i=inb(CDi_status);
-                          }
-                       if (!(i&s_not_data_ready))
-                       {
-                               OUT(CDo_sel_i_d,1);
-                               j=0;
-                               do
-                               {
-                                       if (do_16bit) i=inw(CDi_data);
-                                       else i=inb(CDi_data);
-                                       j++;
-                                       i=inb(CDi_status);
-                               }
-                               while (!(i&s_not_data_ready));
-                               msg(DBG_TEA, "==========too much data (%d bytes/words)==============.\n", j);
-                       }
-                       if (!(i&s_not_result_ready))
-                       {
-                               OUT(CDo_sel_i_d,0);
-                               l=0;
-                               do
-                               {
-                                       infobuf[l++]=inb(CDi_info);
-                                       i=inb(CDi_status);
-                               }
-                               while (!(i&s_not_result_ready));
-                               if (infobuf[0]==0x00) success=1;
-#if 1
-                               for (j=0;j<l;j++) sprintf(&msgbuf[j*3], " %02X", infobuf[j]);
-                               msgbuf[j*3]=0;
-                               msg(DBG_TEA,"sbp_data info response:%s\n", msgbuf);
-#endif
-                               if (infobuf[0]==0x02)
-                               {
-                                       error_flag++;
-                                       do
-                                       {
-                                               ++recursion;
-                                               if (recursion>1) msg(DBG_TEA,"cmd_out_T READ_ERR recursion (sbp_data): %d !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n",recursion);
-                                               else msg(DBG_TEA,"sbp_data: CMDT_READ_ERR necessary.\n");
-                                               clr_cmdbuf();
-                                               drvcmd[0]=CMDT_READ_ERR;
-                                               j=cmd_out_T(); /* !!! recursive here !!! */
-                                               --recursion;
-                                               sbp_sleep(1);
-                                       }
-                                       while (j<0);
-                                       current_drive->error_state=infobuf[2];
-                                       current_drive->b3=infobuf[3];
-                                       current_drive->b4=infobuf[4];
-                               }
-                               break;
-                       }
-                       else
-                       {
-#if 0
-                               msg(DBG_TEA, "============= waiting for result=================.\n");
-                               sbp_sleep(1);
-#endif
-                       }
-               }
-               while (wait--);
-       }
-
-       if (error_flag) /* must have been spurious D_RDY or (ATTN&&!D_RDY) */
-       {
-               msg(DBG_TEA, "================error flag: %d=================.\n", error_flag);
-               msg(DBG_INF,"sbp_data: read aborted by drive.\n");
-#if 1
-               i=cc_DriveReset(); /* ugly fix to prevent a hang */
-#else
-               i=cc_ReadError();
-#endif
-               return (0);
-       }
-       
-       if (fam0LV_drive)
-       {
-               SBPCD_CLI;
-               i=maxtim_data;
-               for (timeout=jiffies+HZ; time_before(jiffies, timeout); timeout--)
-               {
-                       for ( ;i!=0;i--)
-                       {
-                               j=inb(CDi_status);
-                               if (!(j&s_not_data_ready)) break;
-                               if (!(j&s_not_result_ready)) break;
-                               if (j&s_attention) break;
-                       }
-                       if (i != 0 || time_after_eq(jiffies, timeout)) break;
-                       sbp_sleep(0);
-                       i = 1;
-               }
-               if (i==0) msg(DBG_INF,"status timeout after READ.\n");
-               if (!(j&s_attention))
-               {
-                       msg(DBG_INF,"sbp_data: timeout waiting DRV_ATTN - retrying.\n");
-                       i=cc_DriveReset();  /* ugly fix to prevent a hang */
-                       SBPCD_STI;
-                       return (0);
-               }
-               SBPCD_STI;
-       }
-
-#if 0
-       if (!success)
-#endif
-               do
-               {
-                       if (fam0LV_drive) cc_ReadStatus();
-#if 1
-                       if (famT_drive) msg(DBG_TEA, "================before ResponseStatus=================.\n", i);
-#endif
-                       i=ResponseStatus();  /* builds status_bits, returns orig. status (old) or faked p_success (new) */
-#if 1
-                       if (famT_drive) msg(DBG_TEA, "================ResponseStatus: %d=================.\n", i);
-#endif
-                       if (i<0)
-                       {
-                               msg(DBG_INF,"bad cc_ReadStatus after read: %02X\n", current_drive->status_bits);
-                               return (0);
-                       }
-               }
-               while ((fam0LV_drive)&&(!st_check)&&(!(i&p_success)));
-       if (st_check)
-       {
-               i=cc_ReadError();
-               msg(DBG_INF,"cc_ReadError was necessary after read: %d\n",i);
-               return (0);
-       }
-       if (fatal_err)
-       {
-               fatal_err=0;
-               current_drive->sbp_first_frame=current_drive->sbp_last_frame=-1;      /* purge buffer */
-               current_drive->sbp_current = 0;
-               msg(DBG_INF,"sbp_data: fatal_err - retrying.\n");
-               return (0);
-       }
-       
-       current_drive->sbp_first_frame = req -> sector / 4;
-       current_drive->sbp_last_frame = current_drive->sbp_first_frame + current_drive->sbp_read_frames - 1;
-       sbp_transfer(req);
-       return (1);
-}
-/*==========================================================================*/
-
-static int sbpcd_block_open(struct inode *inode, struct file *file)
-{
-       struct sbpcd_drive *p = inode->i_bdev->bd_disk->private_data;
-       return cdrom_open(p->sbpcd_infop, inode, file);
-}
-
-static int sbpcd_block_release(struct inode *inode, struct file *file)
-{
-       struct sbpcd_drive *p = inode->i_bdev->bd_disk->private_data;
-       return cdrom_release(p->sbpcd_infop, file);
-}
-
-static int sbpcd_block_ioctl(struct inode *inode, struct file *file,
-                               unsigned cmd, unsigned long arg)
-{
-       struct sbpcd_drive *p = inode->i_bdev->bd_disk->private_data;
-       struct cdrom_device_info *cdi = p->sbpcd_infop;
-       int ret, i;
-
-       ret = cdrom_ioctl(file, p->sbpcd_infop, inode, cmd, arg);
-       if (ret != -ENOSYS)
-               return ret;
-
-       msg(DBG_IO2,"ioctl(%s, 0x%08lX, 0x%08lX)\n", cdi->name, cmd, arg);
-       if (p->drv_id==-1) {
-               msg(DBG_INF, "ioctl: bad device: %s\n", cdi->name);
-               return (-ENXIO);             /* no such drive */
-       }
-       down(&ioctl_read_sem);
-       if (p != current_drive)
-               switch_drive(p);
-       
-       msg(DBG_IO2,"ioctl: device %s, request %04X\n",cdi->name,cmd);
-       switch (cmd)            /* Sun-compatible */
-       {
-       case DDIOCSDBG:         /* DDI Debug */
-               if (!capable(CAP_SYS_ADMIN)) RETURN_UP(-EPERM);
-               i=sbpcd_dbg_ioctl(arg,1);
-               RETURN_UP(i);
-       case CDROMRESET:      /* hard reset the drive */
-               msg(DBG_IOC,"ioctl: CDROMRESET entered.\n");
-               i=DriveReset();
-               current_drive->audio_state=0;
-               RETURN_UP(i);
-
-       case CDROMREADMODE1:
-               msg(DBG_IOC,"ioctl: CDROMREADMODE1 requested.\n");
-#ifdef SAFE_MIXED
-               if (current_drive->has_data>1) RETURN_UP(-EBUSY);
-#endif /* SAFE_MIXED */
-               cc_ModeSelect(CD_FRAMESIZE);
-               cc_ModeSense();
-               current_drive->mode=READ_M1;
-               RETURN_UP(0);
-
-       case CDROMREADMODE2: /* not usable at the moment */
-               msg(DBG_IOC,"ioctl: CDROMREADMODE2 requested.\n");
-#ifdef SAFE_MIXED
-               if (current_drive->has_data>1) RETURN_UP(-EBUSY);
-#endif /* SAFE_MIXED */
-               cc_ModeSelect(CD_FRAMESIZE_RAW1);
-               cc_ModeSense();
-               current_drive->mode=READ_M2;
-               RETURN_UP(0);
-
-       case CDROMAUDIOBUFSIZ: /* configure the audio buffer size */
-               msg(DBG_IOC,"ioctl: CDROMAUDIOBUFSIZ entered.\n");
-               if (current_drive->sbp_audsiz>0)
-                       vfree(current_drive->aud_buf);
-               current_drive->aud_buf=NULL;
-               current_drive->sbp_audsiz=arg;
-
-               if (current_drive->sbp_audsiz>16)
-               {
-                       current_drive->sbp_audsiz = 0;
-                       RETURN_UP(current_drive->sbp_audsiz);
-               }
-       
-               if (current_drive->sbp_audsiz>0)
-               {
-                       current_drive->aud_buf=(u_char *) vmalloc(current_drive->sbp_audsiz*CD_FRAMESIZE_RAW);
-                       if (current_drive->aud_buf==NULL)
-                       {
-                               msg(DBG_INF,"audio buffer (%d frames) not available.\n",current_drive->sbp_audsiz);
-                               current_drive->sbp_audsiz=0;
-                       }
-                       else msg(DBG_INF,"audio buffer size: %d frames.\n",current_drive->sbp_audsiz);
-               }
-               RETURN_UP(current_drive->sbp_audsiz);
-
-       case CDROMREADAUDIO:
-       { /* start of CDROMREADAUDIO */
-               int i=0, j=0, frame, block=0;
-               u_int try=0;
-               u_long timeout;
-               u_char *p;
-               u_int data_tries = 0;
-               u_int data_waits = 0;
-               u_int data_retrying = 0;
-               int status_tries;
-               int error_flag;
-
-               msg(DBG_IOC,"ioctl: CDROMREADAUDIO entered.\n");
-               if (fam0_drive) RETURN_UP(-EINVAL);
-               if (famL_drive) RETURN_UP(-EINVAL);
-               if (famV_drive) RETURN_UP(-EINVAL);
-               if (famT_drive) RETURN_UP(-EINVAL);
-#ifdef SAFE_MIXED
-               if (current_drive->has_data>1) RETURN_UP(-EBUSY);
-#endif /* SAFE_MIXED */
-               if (current_drive->aud_buf==NULL) RETURN_UP(-EINVAL);
-               if (copy_from_user(&read_audio, (void __user *)arg,
-                                  sizeof(struct cdrom_read_audio)))
-                       RETURN_UP(-EFAULT);
-               if (read_audio.nframes < 0 || read_audio.nframes>current_drive->sbp_audsiz) RETURN_UP(-EINVAL);
-               if (!access_ok(VERIFY_WRITE, read_audio.buf,
-                             read_audio.nframes*CD_FRAMESIZE_RAW))
-                       RETURN_UP(-EFAULT);
-
-               if (read_audio.addr_format==CDROM_MSF) /* MSF-bin specification of where to start */
-                       block=msf2lba(&read_audio.addr.msf.minute);
-               else if (read_audio.addr_format==CDROM_LBA) /* lba specification of where to start */
-                       block=read_audio.addr.lba;
-               else RETURN_UP(-EINVAL);
-#if 000
-               i=cc_SetSpeed(speed_150,0,0);
-               if (i) msg(DBG_AUD,"read_audio: SetSpeed error %d\n", i);
-#endif
-               msg(DBG_AUD,"read_audio: lba: %d, msf: %06X\n",
-                   block, blk2msf(block));
-               msg(DBG_AUD,"read_audio: before cc_ReadStatus.\n");
-#if OLD_BUSY
-               while (busy_data) sbp_sleep(HZ/10); /* wait a bit */
-               busy_audio=1;
-#endif /* OLD_BUSY */
-               error_flag=0;
-               for (data_tries=5; data_tries>0; data_tries--)
-               {
-                       msg(DBG_AUD,"data_tries=%d ...\n", data_tries);
-                       current_drive->mode=READ_AU;
-                       cc_ModeSelect(CD_FRAMESIZE_RAW);
-                       cc_ModeSense();
-                       for (status_tries=3; status_tries > 0; status_tries--)
-                       {
-                               flags_cmd_out |= f_respo3;
-                               cc_ReadStatus();
-                               if (sbp_status() != 0) break;
-                               if (st_check) cc_ReadError();
-                               sbp_sleep(1);    /* wait a bit, try again */
-                       }
-                       if (status_tries == 0)
-                       {
-                               msg(DBG_AUD,"read_audio: sbp_status: failed after 3 tries in line %d.\n", __LINE__);
-                               continue;
-                       }
-                       msg(DBG_AUD,"read_audio: sbp_status: ok.\n");
-
-                       flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus | f_obey_p_check;
-                       if (fam0L_drive)
-                       {
-                               flags_cmd_out |= f_lopsta | f_getsta | f_bit1;
-                               cmd_type=READ_M2;
-                               drvcmd[0]=CMD0_READ_XA; /* "read XA frames", old drives */
-                               drvcmd[1]=(block>>16)&0x000000ff;
-                               drvcmd[2]=(block>>8)&0x000000ff;
-                               drvcmd[3]=block&0x000000ff;
-                               drvcmd[4]=0;
-                               drvcmd[5]=read_audio.nframes; /* # of frames */
-                               drvcmd[6]=0;
-                       }
-                       else if (fam1_drive)
-                       {
-                               drvcmd[0]=CMD1_READ; /* "read frames", new drives */
-                               lba2msf(block,&drvcmd[1]); /* msf-bin format required */
-                               drvcmd[4]=0;
-                               drvcmd[5]=0;
-                               drvcmd[6]=read_audio.nframes; /* # of frames */
-                       }
-                       else if (fam2_drive)
-                       {
-                               drvcmd[0]=CMD2_READ_XA2;
-                               lba2msf(block,&drvcmd[1]); /* msf-bin format required */
-                               drvcmd[4]=0;
-                               drvcmd[5]=read_audio.nframes; /* # of frames */
-                               drvcmd[6]=0x11; /* raw mode */
-                       }
-                       else if (famT_drive) /* CD-55A: not tested yet */
-                       {
-                       }
-                       msg(DBG_AUD,"read_audio: before giving \"read\" command.\n");
-                       flags_cmd_out=f_putcmd;
-                       response_count=0;
-                       i=cmd_out();
-                       if (i<0) msg(DBG_INF,"error giving READ AUDIO command: %0d\n", i);
-                       sbp_sleep(0);
-                       msg(DBG_AUD,"read_audio: after giving \"read\" command.\n");
-                       for (frame=1;frame<2 && !error_flag; frame++)
-                       {
-                               try=maxtim_data;
-                               for (timeout=jiffies+9*HZ; ; )
-                               {
-                                       for ( ; try!=0;try--)
-                                       {
-                                               j=inb(CDi_status);
-                                               if (!(j&s_not_data_ready)) break;
-                                               if (!(j&s_not_result_ready)) break;
-                                               if (fam0L_drive) if (j&s_attention) break;
-                                       }
-                                       if (try != 0 || time_after_eq(jiffies, timeout)) break;
-                                       if (data_retrying == 0) data_waits++;
-                                       data_retrying = 1;
-                                       sbp_sleep(1);
-                                       try = 1;
-                               }
-                               if (try==0)
-                               {
-                                       msg(DBG_INF,"read_audio: sbp_data: CDi_status timeout.\n");
-                                       error_flag++;
-                                       break;
-                               }
-                               msg(DBG_AUD,"read_audio: sbp_data: CDi_status ok.\n");
-                               if (j&s_not_data_ready)
-                               {
-                                       msg(DBG_INF, "read_audio: sbp_data: DATA_READY timeout.\n");
-                                       error_flag++;
-                                       break;
-                               }
-                               msg(DBG_AUD,"read_audio: before reading data.\n");
-                               error_flag=0;
-                               p = current_drive->aud_buf;
-                               if (sbpro_type==1) OUT(CDo_sel_i_d,1);
-                               if (do_16bit)
-                               {
-                                       u_short *p2 = (u_short *) p;
-
-                                       for (; (u_char *) p2 < current_drive->aud_buf + read_audio.nframes*CD_FRAMESIZE_RAW;)
-                                       {
-                                               if ((inb_p(CDi_status)&s_not_data_ready)) continue;
-
-                                               /* get one sample */
-                                               *p2++ = inw_p(CDi_data);
-                                               *p2++ = inw_p(CDi_data);
-                                       }
-                               } else {
-                                       for (; p < current_drive->aud_buf + read_audio.nframes*CD_FRAMESIZE_RAW;)
-                                       {
-                                               if ((inb_p(CDi_status)&s_not_data_ready)) continue;
-
-                                               /* get one sample */
-                                               *p++ = inb_p(CDi_data);
-                                               *p++ = inb_p(CDi_data);
-                                               *p++ = inb_p(CDi_data);
-                                               *p++ = inb_p(CDi_data);
-                                       }
-                               }
-                               if (sbpro_type==1) OUT(CDo_sel_i_d,0);
-                               data_retrying = 0;
-                       }
-                       msg(DBG_AUD,"read_audio: after reading data.\n");
-                       if (error_flag)    /* must have been spurious D_RDY or (ATTN&&!D_RDY) */
-                       {
-                               msg(DBG_AUD,"read_audio: read aborted by drive\n");
-#if 0000
-                               i=cc_DriveReset();                /* ugly fix to prevent a hang */
-#else
-                               i=cc_ReadError();
-#endif
-                               continue;
-                       }
-                       if (fam0L_drive)
-                       {
-                               i=maxtim_data;
-                               for (timeout=jiffies+9*HZ; time_before(jiffies, timeout); timeout--)
-                               {
-                                       for ( ;i!=0;i--)
-                                       {
-                                               j=inb(CDi_status);
-                                               if (!(j&s_not_data_ready)) break;
-                                               if (!(j&s_not_result_ready)) break;
-                                               if (j&s_attention) break;
-                                       }
-                                       if (i != 0 || time_after_eq(jiffies, timeout)) break;
-                                       sbp_sleep(0);
-                                       i = 1;
-                               }
-                               if (i==0) msg(DBG_AUD,"read_audio: STATUS TIMEOUT AFTER READ");
-                               if (!(j&s_attention))
-                               {
-                                       msg(DBG_AUD,"read_audio: sbp_data: timeout waiting DRV_ATTN - retrying\n");
-                                       i=cc_DriveReset();  /* ugly fix to prevent a hang */
-                                       continue;
-                               }
-                       }
-                       do
-                       {
-                               if (fam0L_drive) cc_ReadStatus();
-                               i=ResponseStatus();  /* builds status_bits, returns orig. status (old) or faked p_success (new) */
-                               if (i<0) { msg(DBG_AUD,
-                                              "read_audio: cc_ReadStatus error after read: %02X\n",
-                                              current_drive->status_bits);
-                                          continue; /* FIXME */
-                                  }
-                       }
-                       while ((fam0L_drive)&&(!st_check)&&(!(i&p_success)));
-                       if (st_check)
-                       {
-                               i=cc_ReadError();
-                               msg(DBG_AUD,"read_audio: cc_ReadError was necessary after read: %02X\n",i);
-                               continue;
-                       }
-                       if (copy_to_user(read_audio.buf,
-                                        current_drive->aud_buf,
-                                        read_audio.nframes * CD_FRAMESIZE_RAW))
-                               RETURN_UP(-EFAULT);
-                       msg(DBG_AUD,"read_audio: copy_to_user done.\n");
-                       break;
-               }
-               cc_ModeSelect(CD_FRAMESIZE);
-               cc_ModeSense();
-               current_drive->mode=READ_M1;
-#if OLD_BUSY
-               busy_audio=0;
-#endif /* OLD_BUSY */
-               if (data_tries == 0)
-               {
-                       msg(DBG_AUD,"read_audio: failed after 5 tries in line %d.\n", __LINE__);
-                       RETURN_UP(-EIO);
-               }
-               msg(DBG_AUD,"read_audio: successful return.\n");
-               RETURN_UP(0);
-       } /* end of CDROMREADAUDIO */
-
-       default:
-               msg(DBG_IOC,"ioctl: unknown function request %04X\n", cmd);
-               RETURN_UP(-EINVAL);
-       } /* end switch(cmd) */
-}
-
-static int sbpcd_block_media_changed(struct gendisk *disk)
-{
-       struct sbpcd_drive *p = disk->private_data;
-       return cdrom_media_changed(p->sbpcd_infop);
-}
-
-static struct block_device_operations sbpcd_bdops =
-{
-       .owner          = THIS_MODULE,
-       .open           = sbpcd_block_open,
-       .release        = sbpcd_block_release,
-       .ioctl          = sbpcd_block_ioctl,
-       .media_changed  = sbpcd_block_media_changed,
-};
-/*==========================================================================*/
-/*
- *  Open the device special file.  Check that a disk is in. Read TOC.
- */
-static int sbpcd_open(struct cdrom_device_info *cdi, int purpose)
-{
-       struct sbpcd_drive *p = cdi->handle;
-
-       down(&ioctl_read_sem);
-       switch_drive(p);
-
-       /*
-        * try to keep an "open" counter here and lock the door if 0->1.
-        */
-       msg(DBG_LCK,"open_count: %d -> %d\n",
-           current_drive->open_count,current_drive->open_count+1);
-       if (++current_drive->open_count<=1)
-       {
-               int i;
-               i=LockDoor();
-               current_drive->open_count=1;
-               if (famT_drive) msg(DBG_TEA,"sbpcd_open: before i=DiskInfo();.\n");
-               i=DiskInfo();
-               if (famT_drive) msg(DBG_TEA,"sbpcd_open: after i=DiskInfo();.\n");
-               if ((current_drive->ored_ctl_adr&0x40)==0)
-               {               
-                       msg(DBG_INF,"CD contains no data tracks.\n");
-#ifdef SAFE_MIXED
-                       current_drive->has_data=0;
-#endif /* SAFE_MIXED */
-               }
-#ifdef SAFE_MIXED
-               else if (current_drive->has_data<1) current_drive->has_data=1;
-#endif /* SAFE_MIXED */ 
-       }
-       if (!st_spinning) cc_SpinUp();
-       RETURN_UP(0);
-}
-/*==========================================================================*/
-/*
- *  On close, we flush all sbp blocks from the buffer cache.
- */
-static void sbpcd_release(struct cdrom_device_info * cdi)
-{
-       struct sbpcd_drive *p = cdi->handle;
-
-       if (p->drv_id==-1) {
-               msg(DBG_INF, "release: bad device: %s\n", cdi->name);
-               return;
-       }
-       down(&ioctl_read_sem);
-       switch_drive(p);
-       /*
-        * try to keep an "open" counter here and unlock the door if 1->0.
-        */
-       msg(DBG_LCK,"open_count: %d -> %d\n",
-           p->open_count,p->open_count-1);
-       if (p->open_count>-2) /* CDROMEJECT may have been done */
-       {
-               if (--p->open_count<=0) 
-               {
-                       p->sbp_first_frame=p->sbp_last_frame=-1;
-                       if (p->audio_state!=audio_playing)
-                               if (p->f_eject) cc_SpinDown();
-                       p->diskstate_flags &= ~cd_size_bit;
-                       p->open_count=0; 
-#ifdef SAFE_MIXED
-                       p->has_data=0;
-#endif /* SAFE_MIXED */ 
-               }
-       }
-       up(&ioctl_read_sem);
-       return ;
-}
-/*==========================================================================*/
-/*
- *
- */
-static int sbpcd_media_changed( struct cdrom_device_info *cdi, int disc_nr);
-static struct cdrom_device_ops sbpcd_dops = {
-       .open                   = sbpcd_open,
-       .release                = sbpcd_release,
-       .drive_status           = sbpcd_drive_status,
-       .media_changed          = sbpcd_media_changed,
-       .tray_move              = sbpcd_tray_move,
-       .lock_door              = sbpcd_lock_door,
-       .select_speed           = sbpcd_select_speed,
-       .get_last_session       = sbpcd_get_last_session,
-       .get_mcn                = sbpcd_get_mcn,
-       .reset                  = sbpcd_reset,
-       .audio_ioctl            = sbpcd_audio_ioctl,
-       .capability             = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
-                               CDC_MULTI_SESSION | CDC_MEDIA_CHANGED |
-                               CDC_MCN | CDC_PLAY_AUDIO,
-       .n_minors               = 1,
-};
-
-/*==========================================================================*/
-/*
- * accept "kernel command line" parameters 
- * (suggested by Peter MacDonald with SLS 1.03)
- *
- * This is only implemented for the first controller. Should be enough to
- * allow installing with a "strange" distribution kernel.
- *
- * use: tell LILO:
- *                 sbpcd=0x230,SoundBlaster
- *             or
- *                 sbpcd=0x300,LaserMate
- *             or
- *                 sbpcd=0x338,SoundScape
- *             or
- *                 sbpcd=0x2C0,Teac16bit
- *
- * (upper/lower case sensitive here - but all-lowercase is ok!!!).
- *
- * the address value has to be the CDROM PORT ADDRESS -
- * not the soundcard base address.
- * For the SPEA/SoundScape setup, DO NOT specify the "configuration port"
- * address, but the address which is really used for the CDROM (usually 8
- * bytes above).
- *
- */
-
-int sbpcd_setup(char *s)
-{
-#ifndef MODULE
-       int p[4];
-       (void)get_options(s, ARRAY_SIZE(p), p);
-       setup_done++;
-       msg(DBG_INI,"sbpcd_setup called with %04X,%s\n",p[1], s);
-       sbpro_type=0; /* default: "LaserMate" */
-       if (p[0]>1) sbpro_type=p[2];
-       else if (!strcmp(s,str_sb)) sbpro_type=1;
-       else if (!strcmp(s,str_sb_l)) sbpro_type=1;
-       else if (!strcmp(s,str_sp)) sbpro_type=2;
-       else if (!strcmp(s,str_sp_l)) sbpro_type=2;
-       else if (!strcmp(s,str_ss)) sbpro_type=2;
-       else if (!strcmp(s,str_ss_l)) sbpro_type=2;
-       else if (!strcmp(s,str_t16)) sbpro_type=3;
-       else if (!strcmp(s,str_t16_l)) sbpro_type=3;
-       if (p[0]>0) sbpcd_ioaddr=p[1];
-       if (p[0]>2) max_drives=p[3];
-#else
-       sbpcd_ioaddr = sbpcd[0];
-       sbpro_type = sbpcd[1];
-#endif
-       
-       CDo_command=sbpcd_ioaddr;
-       CDi_info=sbpcd_ioaddr;
-       CDi_status=sbpcd_ioaddr+1;
-       CDo_sel_i_d=sbpcd_ioaddr+1;
-       CDo_reset=sbpcd_ioaddr+2;
-       CDo_enable=sbpcd_ioaddr+3; 
-       f_16bit=0;
-       if ((sbpro_type==1)||(sbpro_type==3))
-       {
-               CDi_data=sbpcd_ioaddr;
-               if (sbpro_type==3)
-                {
-                        f_16bit=1;
-                        sbpro_type=1;
-                }
-       }
-       else CDi_data=sbpcd_ioaddr+2;
-
-       return 1;
-}
-
-__setup("sbpcd=", sbpcd_setup);
-
-
-/*==========================================================================*/
-/*
- * Sequoia S-1000 CD-ROM Interface Configuration
- * as used within SPEA Media FX, Ensonic SoundScape and some Reveal cards
- * The soundcard has to get jumpered for the interface type "Panasonic"
- * (not Sony or Mitsumi) and to get soft-configured for
- *     -> configuration port address
- *     -> CDROM port offset (num_ports): has to be 8 here. Possibly this
- *        offset value determines the interface type (none, Panasonic,
- *        Mitsumi, Sony).
- *        The interface uses a configuration port (0x320, 0x330, 0x340, 0x350)
- *        some bytes below the real CDROM address.
- *         
- *        For the Panasonic style (LaserMate) interface and the configuration
- *        port 0x330, we have to use an offset of 8; so, the real CDROM port
- *        address is 0x338.
- */
-static int __init config_spea(void)
-{
-       /*
-         * base address offset between configuration port and CDROM port,
-        * this probably defines the interface type
-         *   2 (type=??): 0x00
-         *   8 (type=LaserMate):0x10
-         *  16 (type=??):0x20
-         *  32 (type=??):0x30
-         */
-       int n_ports=0x10;
-
-       int irq_number=0; /* off:0x00, 2/9:0x01, 7:0x03, 12:0x05, 15:0x07 */
-       int dma_channel=0; /* off: 0x00, 0:0x08, 1:0x18, 3:0x38, 5:0x58, 6:0x68 */
-       int dack_polarity=0; /* L:0x00, H:0x80 */
-       int drq_polarity=0x40; /* L:0x00, H:0x40 */
-       int i;
-
-#define SPEA_REG_1 sbpcd_ioaddr-0x08+4
-#define SPEA_REG_2 sbpcd_ioaddr-0x08+5
-       
-       OUT(SPEA_REG_1,0xFF);
-       i=inb(SPEA_REG_1);
-       if (i!=0x0F)
-       {
-               msg(DBG_SEQ,"no SPEA interface at %04X present.\n", sbpcd_ioaddr);
-               return (-1); /* no interface found */
-       }
-       OUT(SPEA_REG_1,0x04);
-       OUT(SPEA_REG_2,0xC0);
-       
-       OUT(SPEA_REG_1,0x05);
-       OUT(SPEA_REG_2,0x10|drq_polarity|dack_polarity);
-       
-#if 1
-#define SPEA_PATTERN 0x80
-#else
-#define SPEA_PATTERN 0x00
-#endif
-       OUT(SPEA_REG_1,0x06);
-       OUT(SPEA_REG_2,dma_channel|irq_number|SPEA_PATTERN);
-       OUT(SPEA_REG_2,dma_channel|irq_number|SPEA_PATTERN);
-       
-       OUT(SPEA_REG_1,0x09);
-       i=(inb(SPEA_REG_2)&0xCF)|n_ports;
-       OUT(SPEA_REG_2,i);
-       
-       sbpro_type = 0; /* acts like a LaserMate interface now */
-       msg(DBG_SEQ,"found SoundScape interface at %04X.\n", sbpcd_ioaddr);
-       return (0);
-}
-
-/*==========================================================================*/
-/*
- *  Test for presence of drive and initialize it.
- *  Called once at boot or load time.
- */
-
-/* FIXME: cleanups after failed allocations are too ugly for words */
-#ifdef MODULE
-int __init __sbpcd_init(void)
-#else
-int __init sbpcd_init(void)
-#endif
-{
-       int i=0, j=0;
-       int addr[2]={1, CDROM_PORT};
-       int port_index;
-
-       sti();
-       
-       msg(DBG_INF,"sbpcd.c %s\n", VERSION);
-#ifndef MODULE
-#if DISTRIBUTION
-       if (!setup_done)
-       {
-               msg(DBG_INF,"Looking for Matsushita/Panasonic, CreativeLabs, Longshine, TEAC CD-ROM drives\n");
-               msg(DBG_INF,"= = = = = = = = = = W A R N I N G = = = = = = = = = =\n");
-               msg(DBG_INF,"Auto-Probing can cause a hang (f.e. touching an NE2000 card).\n");
-               msg(DBG_INF,"If that happens, you have to reboot and use the\n");
-               msg(DBG_INF,"LILO (kernel) command line feature like:\n");
-               msg(DBG_INF,"   LILO boot: ... sbpcd=0x230,SoundBlaster\n");
-               msg(DBG_INF,"or like:\n");
-               msg(DBG_INF,"   LILO boot: ... sbpcd=0x300,LaserMate\n");
-               msg(DBG_INF,"or like:\n");
-               msg(DBG_INF,"   LILO boot: ... sbpcd=0x338,SoundScape\n");
-               msg(DBG_INF,"with your REAL address.\n");
-               msg(DBG_INF,"= = = = = = = = = = END of WARNING = = = = = == = = =\n");
-       }
-#endif /* DISTRIBUTION */
-       sbpcd[0]=sbpcd_ioaddr; /* possibly changed by kernel command line */
-       sbpcd[1]=sbpro_type; /* possibly changed by kernel command line */
-#endif /* MODULE */
-       
-       for (port_index=0;port_index<NUM_PROBE;port_index+=2)
-       {
-               addr[1]=sbpcd[port_index];
-               if (addr[1]==0) break;
-               if (check_region(addr[1],4))
-               {
-                       msg(DBG_INF,"check_region: %03X is not free.\n",addr[1]);
-                       continue;
-               }
-               if (sbpcd[port_index+1]==2) type=str_sp;
-               else if (sbpcd[port_index+1]==1) type=str_sb;
-               else if (sbpcd[port_index+1]==3) type=str_t16;
-               else type=str_lm;
-               sbpcd_setup((char *)type);
-#if DISTRIBUTION
-               msg(DBG_INF,"Scanning 0x%X (%s)...\n", CDo_command, type);
-#endif /* DISTRIBUTION */
-               if (sbpcd[port_index+1]==2)
-               {
-                       i=config_spea();
-                       if (i<0) continue;
-               }
-#ifdef PATH_CHECK
-               if (check_card(addr[1])) continue;
-#endif /* PATH_CHECK */ 
-               i=check_drives();
-               msg(DBG_INI,"check_drives done.\n");
-               if (i>=0) break; /* drive found */
-       } /* end of cycling through the set of possible I/O port addresses */
-       
-       if (ndrives==0)
-       {
-               msg(DBG_INF, "No drive found.\n");
-#ifdef MODULE
-               return -EIO;
-#else
-               goto init_done;
-#endif /* MODULE */
-       }
-       
-       if (port_index>0)
-          {
-            msg(DBG_INF, "You should read Documentation/cdrom/sbpcd\n");
-            msg(DBG_INF, "and then configure sbpcd.h for your hardware.\n");
-          }
-       check_datarate();
-       msg(DBG_INI,"check_datarate done.\n");
-       
-       for (j=0;j<NR_SBPCD;j++)
-       {
-               struct sbpcd_drive *p = D_S + j;
-               if (p->drv_id==-1)
-                       continue;
-               switch_drive(p);
-#if 1
-               if (!famL_drive) cc_DriveReset();
-#endif
-               if (!st_spinning) cc_SpinUp();
-               p->sbp_first_frame = -1;  /* First frame in buffer */
-               p->sbp_last_frame = -1;   /* Last frame in buffer  */
-               p->sbp_read_frames = 0;   /* Number of frames being read to buffer */
-               p->sbp_current = 0;       /* Frame being currently read */
-               p->CD_changed=1;
-               p->frame_size=CD_FRAMESIZE;
-               p->f_eject=0;
-#if EJECT
-               if (!fam0_drive) p->f_eject=1;
-#endif /* EJECT */ 
-               cc_ReadStatus();
-               i=ResponseStatus();  /* returns orig. status or p_busy_new */
-               if (famT_drive) i=ResponseStatus();  /* returns orig. status or p_busy_new */
-               if (i<0)
-               {
-                       if (i!=-402)
-                               msg(DBG_INF,"init: ResponseStatus returns %d.\n",i);
-               }
-               else
-               {
-                       if (st_check)
-                       {
-                               i=cc_ReadError();
-                               msg(DBG_INI,"init: cc_ReadError returns %d\n",i);
-                       }
-               }
-               msg(DBG_INI,"init: first GetStatus: %d\n",i);
-               msg(DBG_LCS,"init: first GetStatus: error_byte=%d\n",
-                   p->error_byte);
-               if (p->error_byte==aud_12)
-               {
-                       timeout=jiffies+2*HZ;
-                       do
-                       {
-                               i=GetStatus();
-                               msg(DBG_INI,"init: second GetStatus: %02X\n",i);
-                               msg(DBG_LCS,
-                                   "init: second GetStatus: error_byte=%d\n",
-                                   p->error_byte);
-                               if (i<0) break;
-                               if (!st_caddy_in) break;
-                               }
-                       while ((!st_diskok)||time_after(jiffies, timeout));
-               }
-               i=SetSpeed();
-               if (i>=0) p->CD_changed=1;
-       }
-
-       if (!request_region(CDo_command,4,major_name))
-       {
-               printk(KERN_WARNING "sbpcd: Unable to request region 0x%x\n", CDo_command);
-               return -EIO;
-       }
-
-       /*
-        * Turn on the CD audio channels.
-        * The addresses are obtained from SOUND_BASE (see sbpcd.h).
-        */
-#if SOUND_BASE
-       OUT(MIXER_addr,MIXER_CD_Volume); /* select SB Pro mixer register */
-       OUT(MIXER_data,0xCC); /* one nibble per channel, max. value: 0xFF */
-#endif /* SOUND_BASE */
-
-       if (register_blkdev(MAJOR_NR, major_name)) {
-#ifdef MODULE
-               return -EIO;
-#else
-               goto init_done;
-#endif /* MODULE */
-       }
-
-       /*
-        * init error handling is broken beyond belief in this driver...
-        */
-       sbpcd_queue = blk_init_queue(do_sbpcd_request, &sbpcd_lock);
-       if (!sbpcd_queue) {
-               release_region(CDo_command,4);
-               unregister_blkdev(MAJOR_NR, major_name);
-               return -ENOMEM;
-       }
-
-       for (j=0;j<NR_SBPCD;j++)
-       {
-               struct cdrom_device_info * sbpcd_infop;
-               struct gendisk *disk;
-               struct sbpcd_drive *p = D_S + j;
-
-               if (p->drv_id==-1) continue;
-               switch_drive(p);
-#ifdef SAFE_MIXED
-               p->has_data=0;
-#endif /* SAFE_MIXED */ 
-               /*
-                * allocate memory for the frame buffers
-                */
-               p->aud_buf=NULL;
-               p->sbp_audsiz=0;
-               p->sbp_bufsiz=buffers;
-               if (p->drv_type&drv_fam1)
-                       if (READ_AUDIO>0)
-                               p->sbp_audsiz = READ_AUDIO;
-               p->sbp_buf=(u_char *) vmalloc(buffers*CD_FRAMESIZE);
-               if (!p->sbp_buf) {
-                       msg(DBG_INF,"data buffer (%d frames) not available.\n",
-                               buffers);
-                       if ((unregister_blkdev(MAJOR_NR, major_name) == -EINVAL))
-                       {
-                               printk("Can't unregister %s\n", major_name);
-                       }
-                       release_region(CDo_command,4);
-                       blk_cleanup_queue(sbpcd_queue);
-                       return -EIO;
-               }
-#ifdef MODULE
-               msg(DBG_INF,"data buffer size: %d frames.\n",buffers);
-#endif /* MODULE */
-               if (p->sbp_audsiz>0)
-               {
-                       p->aud_buf=(u_char *) vmalloc(p->sbp_audsiz*CD_FRAMESIZE_RAW);
-                       if (p->aud_buf==NULL) msg(DBG_INF,"audio buffer (%d frames) not available.\n",p->sbp_audsiz);
-                       else msg(DBG_INF,"audio buffer size: %d frames.\n",p->sbp_audsiz);
-               }
-                sbpcd_infop = vmalloc(sizeof (struct cdrom_device_info));
-               if (sbpcd_infop == NULL)
-               {
-                        release_region(CDo_command,4);
-                       blk_cleanup_queue(sbpcd_queue);
-                        return -ENOMEM;
-               }
-               memset(sbpcd_infop, 0, sizeof(struct cdrom_device_info));
-               sbpcd_infop->ops = &sbpcd_dops;
-               sbpcd_infop->speed = 2;
-               sbpcd_infop->capacity = 1;
-               sprintf(sbpcd_infop->name, "sbpcd%d", j);
-               sbpcd_infop->handle = p;
-               p->sbpcd_infop = sbpcd_infop;
-               disk = alloc_disk(1);
-               disk->major = MAJOR_NR;
-               disk->first_minor = j;
-               disk->fops = &sbpcd_bdops;
-               strcpy(disk->disk_name, sbpcd_infop->name);
-               disk->flags = GENHD_FL_CD;
-               p->disk = disk;
-               if (register_cdrom(sbpcd_infop))
-               {
-                       printk(" sbpcd: Unable to register with Uniform CD-ROm driver\n");
-               }
-               disk->private_data = p;
-               disk->queue = sbpcd_queue;
-               add_disk(disk);
-       }
-       blk_queue_hardsect_size(sbpcd_queue, CD_FRAMESIZE);
-
-#ifndef MODULE
- init_done:
-#endif
-       return 0;
-}
-/*==========================================================================*/
-#ifdef MODULE
-static void sbpcd_exit(void)
-{
-       int j;
-       
-       if ((unregister_blkdev(MAJOR_NR, major_name) == -EINVAL))
-       {
-               msg(DBG_INF, "What's that: can't unregister %s.\n", major_name);
-               return;
-       }
-       release_region(CDo_command,4);
-       blk_cleanup_queue(sbpcd_queue);
-       for (j=0;j<NR_SBPCD;j++)
-       {
-               if (D_S[j].drv_id==-1) continue;
-               del_gendisk(D_S[j].disk);
-               put_disk(D_S[j].disk);
-               vfree(D_S[j].sbp_buf);
-               if (D_S[j].sbp_audsiz>0)
-                       vfree(D_S[j].aud_buf);
-               if ((unregister_cdrom(D_S[j].sbpcd_infop) == -EINVAL))
-               {
-                       msg(DBG_INF, "What's that: can't unregister info %s.\n", major_name);
-                       return;
-               }
-               vfree(D_S[j].sbpcd_infop);
-       }
-       msg(DBG_INF, "%s module released.\n", major_name);
-}
-
-
-module_init(__sbpcd_init) /*HACK!*/;
-module_exit(sbpcd_exit);
-
-
-#endif /* MODULE */
-static int sbpcd_media_changed(struct cdrom_device_info *cdi, int disc_nr)
-{
-       struct sbpcd_drive *p = cdi->handle;
-       msg(DBG_CHK,"media_check (%s) called\n", cdi->name);
-       
-       if (p->CD_changed==0xFF)
-        {
-                p->CD_changed=0;
-                msg(DBG_CHK,"medium changed (drive %s)\n", cdi->name);
-               current_drive->diskstate_flags &= ~toc_bit;
-               /* we *don't* need invalidate here, it's done by caller */
-               current_drive->diskstate_flags &= ~cd_size_bit;
-#ifdef SAFE_MIXED
-               current_drive->has_data=0;
-#endif /* SAFE_MIXED */ 
-
-                return (1);
-        }
-        else
-                return (0);
-}
-
-MODULE_LICENSE("GPL");
-/* FIXME: Old modules.conf claims MATSUSHITA_CDROM2_MAJOR and CDROM3, but
-   AFAICT this doesn't support those majors, so why? --RR 30 Jul 2003 */
-MODULE_ALIAS_BLOCKDEV_MAJOR(MATSUSHITA_CDROM_MAJOR);
-
-/*==========================================================================*/
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file. 
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 8
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -8
- * c-argdecl-indent: 8
- * c-label-offset: -8
- * c-continued-statement-offset: 8
- * c-continued-brace-offset: 0
- * End:
- */
-
diff --git a/drivers/cdrom/sbpcd.h b/drivers/cdrom/sbpcd.h
deleted file mode 100644 (file)
index 2f2225f..0000000
+++ /dev/null
@@ -1,839 +0,0 @@
-/*
- * sbpcd.h   Specify interface address and interface type here.
- */
-
-/*
- * Attention! This file contains user-serviceable parts!
- * I recommend to make use of it...
- * If you feel helpless, look into Documentation/cdrom/sbpcd
- * (good idea anyway, at least before mailing me).
- *
- * The definitions for the first controller can get overridden by
- * the kernel command line ("lilo boot option").
- * Examples:
- *                                 sbpcd=0x300,LaserMate
- *                             or
- *                                 sbpcd=0x230,SoundBlaster
- *                             or
- *                                 sbpcd=0x338,SoundScape
- *                             or
- *                                 sbpcd=0x2C0,Teac16bit
- *
- * If sbpcd gets used as a module, you can load it with
- *     insmod sbpcd.o sbpcd=0x300,0
- * or
- *     insmod sbpcd.o sbpcd=0x230,1
- * or
- *     insmod sbpcd.o sbpcd=0x338,2
- * or
- *     insmod sbpcd.o sbpcd=0x2C0,3
- * respective to override the configured address and type.
- */
-
-/*
- * define your CDROM port base address as CDROM_PORT
- * and specify the type of your interface card as SBPRO.
- *
- * address:
- * ========
- * SBPRO type addresses typically are 0x0230 (=0x220+0x10), 0x0250, ...
- * LASERMATE type (CI-101P, WDH-7001C) addresses typically are 0x0300, ...
- * SOUNDSCAPE addresses are from the LASERMATE type and range. You have to
- * specify the REAL address here, not the configuration port address. Look
- * at the CDROM driver's invoking line within your DOS CONFIG.SYS, or let
- * sbpcd auto-probe, if you are not firm with the address.
- * There are some soundcards on the market with 0x0630, 0x0650, ...; their
- * type is not obvious (both types are possible).
- *
- * example: if your SBPRO audio address is 0x220, specify 0x230 and SBPRO 1.
- *          if your soundcard has its CDROM port above 0x300, specify
- *          that address and try SBPRO 0 first.
- *          if your SoundScape configuration port is at 0x330, specify
- *          0x338 and SBPRO 2.
- *
- * interface type:
- * ===============
- * set SBPRO to 1 for "true" SoundBlaster card
- * set SBPRO to 0 for "compatible" soundcards and
- *                for "poor" (no sound) interface cards.
- * set SBPRO to 2 for Ensonic SoundScape or SPEA Media FX cards
- * set SBPRO to 3 for Teac 16bit interface cards
- *
- * Almost all "compatible" sound boards need to set SBPRO to 0.
- * If SBPRO is set wrong, the drives will get found - but any
- * data access will give errors (audio access will work).
- * The "OmniCD" no-sound interface card from CreativeLabs and most Teac
- * interface cards need SBPRO 1.
- *
- * sound base:
- * ===========
- * The SOUND_BASE definition tells if we should try to turn the CD sound
- * channels on. It will only be of use regarding soundcards with a SbPro
- * compatible mixer.
- *
- * Example: #define SOUND_BASE 0x220 enables the sound card's CD channels
- *          #define SOUND_BASE 0     leaves the soundcard untouched
- */
-#define CDROM_PORT 0x340 /* <-----------<< port address                      */
-#define SBPRO      0     /* <-----------<< interface type                    */
-#define MAX_DRIVES 4     /* set to 1 if the card does not use "drive select" */
-#define SOUND_BASE 0x220 /* <-----------<< sound address of this card or 0   */
-
-/*
- * some more or less user dependent definitions - service them!
- */
-
-/* Set this to 0 once you have configured your interface definitions right. */
-#define DISTRIBUTION 1
-
-/*
- * Time to wait after giving a message.
- * This gets important if you enable non-standard DBG_xxx flags.
- * You will see what happens if you omit the pause or make it
- * too short. Be warned!
- */
-#define KLOGD_PAUSE 1
-
-/* tray control: eject tray if no disk is in */
-#if DISTRIBUTION
-#define JUKEBOX 0
-#else
-#define JUKEBOX 1
-#endif /* DISTRIBUTION */
-
-/* tray control: eject tray after last use */
-#if DISTRIBUTION
-#define EJECT 0
-#else
-#define EJECT 1
-#endif /* DISTRIBUTION */
-
-/* max. number of audio frames to read with one     */
-/* request (allocates n* 2352 bytes kernel memory!) */
-/* may be freely adjusted, f.e. 75 (= 1 sec.), at   */
-/* runtime by use of the CDROMAUDIOBUFSIZ ioctl.    */
-#define READ_AUDIO 0
-
-/* Optimizations for the Teac CD-55A drive read performance.
- * SBP_TEAC_SPEED can be changed here, or one can set the 
- * variable "teac" when loading as a module.
- * Valid settings are:
- *   0 - very slow - the recommended "DISTRIBUTION 1" setup.
- *   1 - 2x performance with little overhead. No busy waiting.
- *   2 - 4x performance with 5ms overhead per read. Busy wait.
- *
- * Setting SBP_TEAC_SPEED or the variable 'teac' to anything
- * other than 0 may cause problems. If you run into them, first
- * change SBP_TEAC_SPEED back to 0 and see if your drive responds
- * normally. If yes, you are "allowed" to report your case - to help
- * me with the driver, not to solve your hassle. Don´t mail if you
- * simply are stuck into your own "tuning" experiments, you know?
- */
-#define SBP_TEAC_SPEED 1
-
-/*==========================================================================*/
-/*==========================================================================*/
-/*
- * nothing to change below here if you are not fully aware what you're doing
- */
-#ifndef _LINUX_SBPCD_H
-
-#define _LINUX_SBPCD_H
-/*==========================================================================*/
-/*==========================================================================*/
-/*
- * driver's own read_ahead, data mode
- */
-#define SBP_BUFFER_FRAMES 8 
-
-#define LONG_TIMING 0 /* test against timeouts with "gold" CDs on CR-521 */
-#undef  FUTURE
-#undef SAFE_MIXED
-
-#define TEST_UPC 0
-#define SPEA_TEST 0
-#define TEST_STI 0
-#define OLD_BUSY 0
-#undef PATH_CHECK
-#ifndef SOUND_BASE
-#define SOUND_BASE 0
-#endif
-#if DISTRIBUTION
-#undef SBP_TEAC_SPEED
-#define SBP_TEAC_SPEED 0
-#endif
-/*==========================================================================*/
-/*
- * DDI interface definitions
- * "invented" by Fred N. van Kempen..
- */
-#define DDIOCSDBG      0x9000
-
-/*==========================================================================*/
-/*
- * "private" IOCTL functions
- */
-#define CDROMAUDIOBUFSIZ       0x5382 /* set the audio buffer size */
-
-/*==========================================================================*/
-/*
- * Debug output levels
- */
-#define DBG_INF        1       /* necessary information */
-#define DBG_BSZ        2       /* BLOCK_SIZE trace */
-#define DBG_REA        3       /* READ status trace */
-#define DBG_CHK        4       /* MEDIA CHECK trace */
-#define DBG_TIM        5       /* datarate timer test */
-#define DBG_INI        6       /* initialization trace */
-#define DBG_TOC        7       /* tell TocEntry values */
-#define DBG_IOC        8       /* ioctl trace */
-#define DBG_STA        9       /* ResponseStatus() trace */
-#define DBG_ERR        10      /* cc_ReadError() trace */
-#define DBG_CMD        11      /* cmd_out() trace */
-#define DBG_WRN        12      /* give explanation before auto-probing */
-#define DBG_MUL        13      /* multi session code test */
-#define DBG_IDX        14      /* test code for drive_id !=0 */
-#define DBG_IOX        15      /* some special information */
-#define DBG_DID        16      /* drive ID test */
-#define DBG_RES        17      /* drive reset info */
-#define DBG_SPI        18      /* SpinUp test */
-#define DBG_IOS        19      /* ioctl trace: subchannel functions */
-#define DBG_IO2        20      /* ioctl trace: general */
-#define DBG_UPC        21      /* show UPC information */
-#define DBG_XA1        22      /* XA mode debugging */
-#define DBG_LCK        23      /* door (un)lock info */
-#define DBG_SQ1        24      /* dump SubQ frame */
-#define DBG_AUD        25      /* READ AUDIO debugging */
-#define DBG_SEQ        26      /* Sequoia interface configuration trace */
-#define DBG_LCS        27      /* Longshine LCS-7260 debugging trace */
-#define DBG_CD2        28      /* MKE/Funai CD200 debugging trace */
-#define DBG_TEA        29      /* TEAC CD-55A debugging trace */
-#define DBG_ECS        30      /* ECS-AT (Vertos 100) debugging trace */
-#define DBG_000        31      /* unnecessary information */
-
-/*==========================================================================*/
-/*==========================================================================*/
-
-/*
- * bits of flags_cmd_out:
- */
-#define f_respo3               0x100
-#define f_putcmd               0x80
-#define f_respo2               0x40
-#define f_lopsta               0x20
-#define f_getsta               0x10
-#define f_ResponseStatus       0x08
-#define f_obey_p_check         0x04
-#define f_bit1                 0x02
-#define f_wait_if_busy         0x01
-
-/*
- * diskstate_flags:
- */
-#define x80_bit                        0x80
-#define upc_bit                        0x40
-#define volume_bit             0x20
-#define toc_bit                        0x10
-#define multisession_bit       0x08
-#define cd_size_bit            0x04
-#define subq_bit               0x02
-#define frame_size_bit         0x01
-
-/*
- * disk states (bits of diskstate_flags):
- */
-#define upc_valid              (current_drive->diskstate_flags&upc_bit)
-#define volume_valid           (current_drive->diskstate_flags&volume_bit)
-#define toc_valid              (current_drive->diskstate_flags&toc_bit)
-#define cd_size_valid          (current_drive->diskstate_flags&cd_size_bit)
-#define subq_valid             (current_drive->diskstate_flags&subq_bit)
-#define frame_size_valid       (current_drive->diskstate_flags&frame_size_bit)
-
-/*
- * the status_bits variable
- */
-#define p_success      0x100
-#define p_door_closed  0x80
-#define p_caddy_in     0x40
-#define p_spinning     0x20
-#define p_check                0x10
-#define p_busy_new     0x08
-#define p_door_locked  0x04
-#define p_disk_ok      0x01
-
-/*
- * LCS-7260 special status result bits:
- */
-#define p_lcs_door_locked      0x02
-#define p_lcs_door_closed      0x01 /* probably disk_in */
-
-/*
- * CR-52x special status result bits:
- */
-#define p_caddin_old   0x40
-#define p_success_old  0x08
-#define p_busy_old     0x04
-#define p_bit_1                0x02    /* hopefully unused now */
-
-/*
- * "generation specific" defs of the status result bits:
- */
-#define p0_door_closed 0x80
-#define p0_caddy_in    0x40
-#define p0_spinning    0x20
-#define p0_check       0x10
-#define p0_success     0x08 /* unused */
-#define p0_busy                0x04
-#define p0_bit_1       0x02 /* unused */
-#define p0_disk_ok     0x01
-
-#define pL_disk_in     0x40
-#define pL_spinning    0x20
-#define pL_check       0x10
-#define pL_success     0x08 /* unused ?? */
-#define pL_busy                0x04
-#define pL_door_locked 0x02
-#define pL_door_closed 0x01
-
-#define pV_door_closed 0x40
-#define pV_spinning    0x20
-#define pV_check       0x10
-#define pV_success     0x08
-#define pV_busy                0x04
-#define pV_door_locked 0x02
-#define pV_disk_ok     0x01
-
-#define p1_door_closed 0x80
-#define p1_disk_in     0x40
-#define p1_spinning    0x20
-#define p1_check       0x10
-#define p1_busy                0x08
-#define p1_door_locked 0x04
-#define p1_bit_1       0x02 /* unused */
-#define p1_disk_ok     0x01
-
-#define p2_disk_ok     0x80
-#define p2_door_locked 0x40
-#define p2_spinning    0x20
-#define p2_busy2       0x10
-#define p2_busy1       0x08
-#define p2_door_closed 0x04
-#define p2_disk_in     0x02
-#define p2_check       0x01
-
-/*
- * used drive states:
- */
-#define st_door_closed (current_drive->status_bits&p_door_closed)
-#define st_caddy_in    (current_drive->status_bits&p_caddy_in)
-#define st_spinning    (current_drive->status_bits&p_spinning)
-#define st_check       (current_drive->status_bits&p_check)
-#define st_busy                (current_drive->status_bits&p_busy_new)
-#define st_door_locked (current_drive->status_bits&p_door_locked)
-#define st_diskok      (current_drive->status_bits&p_disk_ok)
-
-/*
- * bits of the CDi_status register:
- */
-#define s_not_result_ready     0x04 /* 0: "result ready" */
-#define s_not_data_ready       0x02 /* 0: "data ready"   */
-#define s_attention            0x01 /* 1: "attention required" */
-/*
- * usable as:
- */
-#define DRV_ATTN       ((inb(CDi_status)&s_attention)!=0)
-#define DATA_READY     ((inb(CDi_status)&s_not_data_ready)==0)
-#define RESULT_READY   ((inb(CDi_status)&s_not_result_ready)==0)
-
-/*
- * drive families and types (firmware versions):
- */
-#define drv_fam0       0x0100          /* CR-52x family */
-#define drv_199                (drv_fam0+0x01) /* <200 */
-#define drv_200                (drv_fam0+0x02) /* <201 */
-#define drv_201                (drv_fam0+0x03) /* <210 */
-#define drv_210                (drv_fam0+0x04) /* <211 */
-#define drv_211                (drv_fam0+0x05) /* <300 */
-#define drv_300                (drv_fam0+0x06) /* >=300 */
-
-#define drv_fam1       0x0200          /* CR-56x family */
-#define drv_099                (drv_fam1+0x01) /* <100 */
-#define drv_100                (drv_fam1+0x02) /* >=100, only 1.02 and 5.00 known */
-
-#define drv_fam2       0x0400          /* CD200 family */
-
-#define drv_famT       0x0800          /* TEAC CD-55A */
-
-#define drv_famL       0x1000          /* Longshine family */
-#define drv_260                (drv_famL+0x01) /* LCS-7260 */
-#define drv_e1         (drv_famL+0x01) /* LCS-7260, firmware "A E1" */
-#define drv_f4         (drv_famL+0x02) /* LCS-7260, firmware "A4F4" */
-
-#define drv_famV       0x2000          /* ECS-AT (vertos-100) family */
-#define drv_at         (drv_famV+0x01) /* ECS-AT, firmware "1.00" */
-
-#define fam0_drive     (current_drive->drv_type&drv_fam0)
-#define famL_drive     (current_drive->drv_type&drv_famL)
-#define famV_drive     (current_drive->drv_type&drv_famV)
-#define fam1_drive     (current_drive->drv_type&drv_fam1)
-#define fam2_drive     (current_drive->drv_type&drv_fam2)
-#define famT_drive     (current_drive->drv_type&drv_famT)
-#define fam0L_drive    (current_drive->drv_type&(drv_fam0|drv_famL))
-#define fam0V_drive    (current_drive->drv_type&(drv_fam0|drv_famV))
-#define famLV_drive    (current_drive->drv_type&(drv_famL|drv_famV))
-#define fam0LV_drive   (current_drive->drv_type&(drv_fam0|drv_famL|drv_famV))
-#define fam1L_drive    (current_drive->drv_type&(drv_fam1|drv_famL))
-#define fam1V_drive    (current_drive->drv_type&(drv_fam1|drv_famV))
-#define fam1LV_drive   (current_drive->drv_type&(drv_fam1|drv_famL|drv_famV))
-#define fam01_drive    (current_drive->drv_type&(drv_fam0|drv_fam1))
-#define fam12_drive    (current_drive->drv_type&(drv_fam1|drv_fam2))
-#define fam2T_drive    (current_drive->drv_type&(drv_fam2|drv_famT))
-
-/*
- * audio states:
- */
-#define audio_completed        3 /* Forgot this one! --AJK */
-#define audio_playing  2
-#define audio_pausing  1
-
-/*
- * drv_pattern, drv_options:
- */
-#define speed_auto     0x80
-#define speed_300      0x40
-#define speed_150      0x20
-#define audio_mono     0x04
-
-/*
- * values of cmd_type (0 else):
- */
-#define READ_M1        0x01    /* "data mode 1": 2048 bytes per frame */
-#define READ_M2        0x02    /* "data mode 2": 12+2048+280 bytes per frame */
-#define READ_SC        0x04    /* "subchannel info": 96 bytes per frame */
-#define READ_AU        0x08    /* "audio frame": 2352 bytes per frame */
-
-/*
- * sense_byte:
- *
- *          values: 00
- *                  01
- *                  81
- *                  82 "raw audio" mode
- *                  xx from infobuf[0] after 85 00 00 00 00 00 00
- */
-
-/* audio status (bin) */
-#define aud_00 0x00 /* Audio status byte not supported or not valid */
-#define audx11 0x0b /* Audio play operation in progress             */
-#define audx12 0x0c /* Audio play operation paused                  */
-#define audx13 0x0d /* Audio play operation successfully completed  */
-#define audx14 0x0e /* Audio play operation stopped due to error    */
-#define audx15 0x0f /* No current audio status to return            */
-/* audio status (bcd) */
-#define aud_11 0x11 /* Audio play operation in progress             */
-#define aud_12 0x12 /* Audio play operation paused                  */
-#define aud_13 0x13 /* Audio play operation successfully completed  */
-#define aud_14 0x14 /* Audio play operation stopped due to error    */
-#define aud_15 0x15 /* No current audio status to return            */
-
-/*
- * highest allowed drive number (MINOR+1)
- */
-#define NR_SBPCD       4
-
-/*
- * we try to never disable interrupts - seems to work
- */
-#define SBPCD_DIS_IRQ  0
-
-/*
- * "write byte to port"
- */
-#define OUT(x,y)       outb(y,x)
-
-/*==========================================================================*/
-
-#define MIXER_addr SOUND_BASE+4 /* sound card's address register */
-#define MIXER_data SOUND_BASE+5 /* sound card's data register */
-#define MIXER_CD_Volume        0x28    /* internal SB Pro register address */
-
-/*==========================================================================*/
-
-#define MAX_TRACKS     99
-
-#define ERR_DISKCHANGE 615
-
-/*==========================================================================*/
-/*
- * To make conversions easier (machine dependent!)
- */
-typedef union _msf
-{
-       u_int n;
-       u_char c[4];
-} MSF;
-
-typedef union _blk
-{
-       u_int n;
-       u_char c[4];
-} BLK;
-
-/*==========================================================================*/
-
-/*============================================================================
-==============================================================================
-
-COMMAND SET of "old" drives like CR-521, CR-522
-               (the CR-562 family is different):
-
-No.    Command                        Code
---------------------------------------------
-
-Drive Commands:
- 1     Seek                            01      
- 2     Read Data                       02
- 3     Read XA-Data                    03
- 4     Read Header                     04
- 5     Spin Up                         05
- 6     Spin Down                       06
- 7     Diagnostic                      07
- 8     Read UPC                        08
- 9     Read ISRC                       09
-10     Play Audio                      0A
-11     Play Audio MSF                  0B
-12     Play Audio Track/Index          0C
-
-Status Commands:
-13     Read Status                     81      
-14     Read Error                      82
-15     Read Drive Version              83
-16     Mode Select                     84
-17     Mode Sense                      85
-18     Set XA Parameter                86
-19     Read XA Parameter               87
-20     Read Capacity                   88
-21     Read SUB_Q                      89
-22     Read Disc Code                  8A
-23     Read Disc Information           8B
-24     Read TOC                        8C
-25     Pause/Resume                    8D
-26     Read Packet                     8E
-27     Read Path Check                 00
-all numbers (lba, msf-bin, msf-bcd, counts) to transfer high byte first
-
-mnemo     7-byte command        #bytes response (r0...rn)
-________ ____________________  ____ 
-
-Read Status:
-status:  81.                    (1)  one-byte command, gives the main
-                                                          status byte
-Read Error:
-check1:  82 00 00 00 00 00 00.  (6)  r1: audio status
-
-Read Packet:
-check2:  8e xx 00 00 00 00 00. (xx)  gets xx bytes response, relating
-                                        to commands 01 04 05 07 08 09
-
-Play Audio:
-play:    0a ll-bb-aa nn-nn-nn.  (0)  play audio, ll-bb-aa: starting block (lba),
-                                                 nn-nn-nn: #blocks
-Play Audio MSF:
-         0b mm-ss-ff mm-ss-ff   (0)  play audio from/to
-
-Play Audio Track/Index:
-         0c ...
-
-Pause/Resume:
-pause:   8d pr 00 00 00 00 00.  (0)  pause (pr=00) 
-                                     resume (pr=80) audio playing
-
-Mode Select:
-         84 00 nn-nn ??.?? 00   (0)  nn-nn: 2048 or 2340
-                                     possibly defines transfer size
-
-set_vol: 84 83 00 00 sw le 00.  (0)  sw(itch): lrxxxxxx (off=1)
-                                     le(vel): min=0, max=FF, else half
-                                    (firmware 2.11)
-
-Mode Sense:
-get_vol: 85 03 00 00 00 00 00.  (2)  tell current audio volume setting
-
-Read Disc Information:
-tocdesc: 8b 00 00 00 00 00 00.  (6)  read the toc descriptor ("msf-bin"-format)
-
-Read TOC:
-tocent:  8c fl nn 00 00 00 00.  (8)  read toc entry #nn
-                                       (fl=0:"lba"-, =2:"msf-bin"-format)
-
-Read Capacity:
-capacit: 88 00 00 00 00 00 00.  (5)  "read CD-ROM capacity"
-
-
-Read Path Check:
-ping:    00 00 00 00 00 00 00.  (2)  r0=AA, r1=55
-                                     ("ping" if the drive is connected)
-
-Read Drive Version:
-ident:   83 00 00 00 00 00 00. (12)  gives "MATSHITAn.nn" 
-                                     (n.nn = 2.01, 2.11., 3.00, ...)
-
-Seek:
-seek:    01 00 ll-bb-aa 00 00.  (0)  
-seek:    01 02 mm-ss-ff 00 00.  (0)  
-
-Read Data:
-read:    02 xx-xx-xx nn-nn fl.  (?)  read nn-nn blocks of 2048 bytes,
-                                     starting at block xx-xx-xx  
-                                     fl=0: "lba"-, =2:"msf-bcd"-coded xx-xx-xx
-
-Read XA-Data:
-read:    03 xx-xx-xx nn-nn fl.  (?)  read nn-nn blocks of 2340 bytes, 
-                                     starting at block xx-xx-xx
-                                     fl=0: "lba"-, =2:"msf-bcd"-coded xx-xx-xx
-
-Read SUB_Q:
-         89 fl 00 00 00 00 00. (13)  r0: audio status, r4-r7: lba/msf, 
-                                       fl=0: "lba", fl=2: "msf"
-
-Read Disc Code:
-         8a 00 00 00 00 00 00. (14)  possibly extended "check condition"-info
-
-Read Header:
-         04 00 ll-bb-aa 00 00.  (0)   4 bytes response with "check2"
-         04 02 mm-ss-ff 00 00.  (0)   4 bytes response with "check2"
-
-Spin Up:
-         05 00 ll-bb-aa 00 00.  (0)  possibly implies a "seek"
-
-Spin Down:
-         06 ...
-
-Diagnostic:
-         07 00 ll-bb-aa 00 00.  (2)   2 bytes response with "check2"
-         07 02 mm-ss-ff 00 00.  (2)   2 bytes response with "check2"
-
-Read UPC:
-         08 00 ll-bb-aa 00 00. (16)  
-         08 02 mm-ss-ff 00 00. (16)  
-
-Read ISRC:
-         09 00 ll-bb-aa 00 00. (15)  15 bytes response with "check2"
-         09 02 mm-ss-ff 00 00. (15)  15 bytes response with "check2"
-
-Set XA Parameter:
-         86 ...
-
-Read XA Parameter:
-         87 ...
-
-==============================================================================
-============================================================================*/
-
-/*
- * commands
- *
- * CR-52x:      CMD0_
- * CR-56x:      CMD1_
- * CD200:       CMD2_
- * LCS-7260:    CMDL_
- * TEAC CD-55A: CMDT_
- * ECS-AT:      CMDV_
- */
-#define CMD1_RESET     0x0a
-#define CMD2_RESET     0x01
-#define CMDT_RESET     0xc0
-
-#define CMD1_LOCK_CTL  0x0c
-#define CMD2_LOCK_CTL  0x1e
-#define CMDT_LOCK_CTL  CMD2_LOCK_CTL
-#define CMDL_LOCK_CTL  0x0e
-#define CMDV_LOCK_CTL  CMDL_LOCK_CTL
-
-#define CMD1_TRAY_CTL  0x07
-#define CMD2_TRAY_CTL  0x1b
-#define CMDT_TRAY_CTL  CMD2_TRAY_CTL
-#define CMDL_TRAY_CTL  0x0d
-#define CMDV_TRAY_CTL  CMDL_TRAY_CTL
-
-#define CMD1_MULTISESS 0x8d
-#define CMDL_MULTISESS 0x8c
-#define CMDV_MULTISESS CMDL_MULTISESS
-
-#define CMD1_SUBCHANINF        0x11
-#define CMD2_SUBCHANINF        0x??
-
-#define CMD1_ABORT     0x08
-#define CMD2_ABORT     0x08
-#define CMDT_ABORT     0x08
-
-#define CMD2_x02       0x02
-
-#define CMD2_SETSPEED  0xda
-
-#define CMD0_PATH_CHECK        0x00
-#define CMD1_PATH_CHECK        0x???
-#define CMD2_PATH_CHECK        0x???
-#define CMDT_PATH_CHECK        0x???
-#define CMDL_PATH_CHECK        CMD0_PATH_CHECK
-#define CMDV_PATH_CHECK        CMD0_PATH_CHECK
-
-#define CMD0_SEEK      0x01
-#define CMD1_SEEK      CMD0_SEEK
-#define CMD2_SEEK      0x2b
-#define CMDT_SEEK      CMD2_SEEK
-#define CMDL_SEEK      CMD0_SEEK
-#define CMDV_SEEK      CMD0_SEEK
-
-#define CMD0_READ      0x02
-#define CMD1_READ      0x10
-#define CMD2_READ      0x28
-#define CMDT_READ      CMD2_READ
-#define CMDL_READ      CMD0_READ
-#define CMDV_READ      CMD0_READ
-
-#define CMD0_READ_XA   0x03
-#define CMD2_READ_XA   0xd4
-#define CMD2_READ_XA2  0xd5
-#define CMDL_READ_XA   CMD0_READ_XA /* really ?? */
-#define CMDV_READ_XA   CMD0_READ_XA
-
-#define CMD0_READ_HEAD 0x04
-
-#define CMD0_SPINUP    0x05
-#define CMD1_SPINUP    0x02
-#define CMD2_SPINUP    CMD2_TRAY_CTL
-#define CMDL_SPINUP    CMD0_SPINUP
-#define CMDV_SPINUP    CMD0_SPINUP
-
-#define CMD0_SPINDOWN  0x06 /* really??? */
-#define CMD1_SPINDOWN  0x06
-#define CMD2_SPINDOWN  CMD2_TRAY_CTL
-#define CMDL_SPINDOWN  0x0d
-#define CMDV_SPINDOWN  CMD0_SPINDOWN
-
-#define CMD0_DIAG      0x07
-
-#define CMD0_READ_UPC  0x08
-#define CMD1_READ_UPC  0x88
-#define CMD2_READ_UPC  0x???
-#define CMDL_READ_UPC  CMD0_READ_UPC
-#define CMDV_READ_UPC  0x8f
-
-#define CMD0_READ_ISRC 0x09
-
-#define CMD0_PLAY      0x0a
-#define CMD1_PLAY      0x???
-#define CMD2_PLAY      0x???
-#define CMDL_PLAY      CMD0_PLAY
-#define CMDV_PLAY      CMD0_PLAY
-
-#define CMD0_PLAY_MSF  0x0b
-#define CMD1_PLAY_MSF  0x0e
-#define CMD2_PLAY_MSF  0x47
-#define CMDT_PLAY_MSF  CMD2_PLAY_MSF
-#define CMDL_PLAY_MSF  0x???
-
-#define CMD0_PLAY_TI   0x0c
-#define CMD1_PLAY_TI   0x0f
-
-#define CMD0_STATUS    0x81
-#define CMD1_STATUS    0x05
-#define CMD2_STATUS    0x00
-#define CMDT_STATUS    CMD2_STATUS
-#define CMDL_STATUS    CMD0_STATUS
-#define CMDV_STATUS    CMD0_STATUS
-#define CMD2_SEEK_LEADIN 0x00
-
-#define CMD0_READ_ERR  0x82
-#define CMD1_READ_ERR  CMD0_READ_ERR
-#define CMD2_READ_ERR  0x03
-#define CMDT_READ_ERR  CMD2_READ_ERR /* get audio status */
-#define CMDL_READ_ERR  CMD0_READ_ERR
-#define CMDV_READ_ERR  CMD0_READ_ERR
-
-#define CMD0_READ_VER  0x83
-#define CMD1_READ_VER  CMD0_READ_VER
-#define CMD2_READ_VER  0x12
-#define CMDT_READ_VER  CMD2_READ_VER /* really ?? */
-#define CMDL_READ_VER  CMD0_READ_VER
-#define CMDV_READ_VER  CMD0_READ_VER
-
-#define CMD0_SETMODE   0x84
-#define CMD1_SETMODE   0x09
-#define CMD2_SETMODE   0x55
-#define CMDT_SETMODE   CMD2_SETMODE
-#define CMDL_SETMODE   CMD0_SETMODE
-
-#define CMD0_GETMODE   0x85
-#define CMD1_GETMODE   0x84
-#define CMD2_GETMODE   0x5a
-#define CMDT_GETMODE   CMD2_GETMODE
-#define CMDL_GETMODE   CMD0_GETMODE
-
-#define CMD0_SET_XA    0x86
-
-#define CMD0_GET_XA    0x87
-
-#define CMD0_CAPACITY  0x88
-#define CMD1_CAPACITY  0x85
-#define CMD2_CAPACITY  0x25
-#define CMDL_CAPACITY  CMD0_CAPACITY /* missing in some firmware versions */
-
-#define CMD0_READSUBQ  0x89
-#define CMD1_READSUBQ  0x87
-#define CMD2_READSUBQ  0x42
-#define CMDT_READSUBQ  CMD2_READSUBQ
-#define CMDL_READSUBQ  CMD0_READSUBQ
-#define CMDV_READSUBQ  CMD0_READSUBQ
-
-#define CMD0_DISKCODE  0x8a
-
-#define CMD0_DISKINFO  0x8b
-#define CMD1_DISKINFO  CMD0_DISKINFO
-#define CMD2_DISKINFO  0x43
-#define CMDT_DISKINFO  CMD2_DISKINFO
-#define CMDL_DISKINFO  CMD0_DISKINFO
-#define CMDV_DISKINFO  CMD0_DISKINFO
-
-#define CMD0_READTOC   0x8c
-#define CMD1_READTOC   CMD0_READTOC
-#define CMD2_READTOC   0x???
-#define CMDL_READTOC   CMD0_READTOC
-#define CMDV_READTOC   CMD0_READTOC
-
-#define CMD0_PAU_RES   0x8d
-#define CMD1_PAU_RES   0x0d
-#define CMD2_PAU_RES   0x4b
-#define CMDT_PAUSE     CMD2_PAU_RES
-#define CMDL_PAU_RES   CMD0_PAU_RES
-#define CMDV_PAUSE     CMD0_PAU_RES
-
-#define CMD0_PACKET    0x8e
-#define CMD1_PACKET    CMD0_PACKET
-#define CMD2_PACKET    0x???
-#define CMDL_PACKET    CMD0_PACKET
-#define CMDV_PACKET    0x???
-
-/*==========================================================================*/
-/*==========================================================================*/
-#endif /* _LINUX_SBPCD_H */
-/*==========================================================================*/
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file. 
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 8
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -8
- * c-argdecl-indent: 8
- * c-label-offset: -8
- * c-continued-statement-offset: 8
- * c-continued-brace-offset: 0
- * End:
- */
diff --git a/drivers/cdrom/sjcd.c b/drivers/cdrom/sjcd.c
deleted file mode 100644 (file)
index 5409fca..0000000
+++ /dev/null
@@ -1,1815 +0,0 @@
-/* -- sjcd.c
- *
- *   Sanyo CD-ROM device driver implementation, Version 1.6
- *   Copyright (C) 1995  Vadim V. Model
- *
- *   model@cecmow.enet.dec.com
- *   vadim@rbrf.ru
- *   vadim@ipsun.ras.ru
- *
- *
- *  This driver is based on pre-works by Eberhard Moenkeberg (emoenke@gwdg.de);
- *  it was developed under use of mcd.c from Martin Harriss, with help of
- *  Eric van der Maarel (H.T.M.v.d.Maarel@marin.nl).
- *
- *  It is planned to include these routines into sbpcd.c later - to make
- *  a "mixed use" on one cable possible for all kinds of drives which use
- *  the SoundBlaster/Panasonic style CDROM interface. But today, the
- *  ability to install directly from CDROM is more important than flexibility.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You 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.
- *
- *  History:
- *  1.1 First public release with kernel version 1.3.7.
- *      Written by Vadim Model.
- *  1.2 Added detection and configuration of cdrom interface
- *      on ISP16 soundcard.
- *      Allow for command line options: sjcd=<io_base>,<irq>,<dma>
- *  1.3 Some minor changes to README.sjcd.
- *  1.4 MSS Sound support!! Listen to a CD through the speakers.
- *  1.5 Module support and bugfixes.
- *      Tray locking.
- *  1.6 Removed ISP16 code from this driver.
- *      Allow only to set io base address on command line: sjcd=<io_base>
- *      Changes to Documentation/cdrom/sjcd
- *      Added cleanup after any error in the initialisation.
- *  1.7 Added code to set the sector size tables to prevent the bug present in 
- *      the previous version of this driver.  Coded added by Anthony Barbachan 
- *      from bugfix tip originally suggested by Alan Cox.
- *
- *  November 1999 -- Make kernel-parameter implementation work with 2.3.x 
- *                  Removed init_module & cleanup_module in favor of 
- *                  module_init & module_exit.
- *                  Torben Mathiasen <tmm@image.dk>
- */
-
-#define SJCD_VERSION_MAJOR 1
-#define SJCD_VERSION_MINOR 7
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/mm.h>
-#include <linux/timer.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/cdrom.h>
-#include <linux/ioport.h>
-#include <linux/string.h>
-#include <linux/major.h>
-#include <linux/init.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <linux/blkdev.h>
-#include "sjcd.h"
-
-static int sjcd_present = 0;
-static struct request_queue *sjcd_queue;
-
-#define MAJOR_NR SANYO_CDROM_MAJOR
-#define QUEUE (sjcd_queue)
-#define CURRENT elv_next_request(sjcd_queue)
-
-#define SJCD_BUF_SIZ 32                /* cdr-h94a has internal 64K buffer */
-
-/*
- * buffer for block size conversion
- */
-static char sjcd_buf[2048 * SJCD_BUF_SIZ];
-static volatile int sjcd_buf_bn[SJCD_BUF_SIZ], sjcd_next_bn;
-static volatile int sjcd_buf_in, sjcd_buf_out = -1;
-
-/*
- * Status.
- */
-static unsigned short sjcd_status_valid = 0;
-static unsigned short sjcd_door_closed;
-static unsigned short sjcd_door_was_open;
-static unsigned short sjcd_media_is_available;
-static unsigned short sjcd_media_is_changed;
-static unsigned short sjcd_toc_uptodate = 0;
-static unsigned short sjcd_command_failed;
-static volatile unsigned char sjcd_completion_status = 0;
-static volatile unsigned char sjcd_completion_error = 0;
-static unsigned short sjcd_command_is_in_progress = 0;
-static unsigned short sjcd_error_reported = 0;
-static DEFINE_SPINLOCK(sjcd_lock);
-
-static int sjcd_open_count;
-
-static int sjcd_audio_status;
-static struct sjcd_play_msf sjcd_playing;
-
-static int sjcd_base = SJCD_BASE_ADDR;
-
-module_param(sjcd_base, int, 0);
-
-static DECLARE_WAIT_QUEUE_HEAD(sjcd_waitq);
-
-/*
- * Data transfer.
- */
-static volatile unsigned short sjcd_transfer_is_active = 0;
-
-enum sjcd_transfer_state {
-       SJCD_S_IDLE = 0,
-       SJCD_S_START = 1,
-       SJCD_S_MODE = 2,
-       SJCD_S_READ = 3,
-       SJCD_S_DATA = 4,
-       SJCD_S_STOP = 5,
-       SJCD_S_STOPPING = 6
-};
-static enum sjcd_transfer_state sjcd_transfer_state = SJCD_S_IDLE;
-static long sjcd_transfer_timeout = 0;
-static int sjcd_read_count = 0;
-static unsigned char sjcd_mode = 0;
-
-#define SJCD_READ_TIMEOUT 5000
-
-#if defined( SJCD_GATHER_STAT )
-/*
- * Statistic.
- */
-static struct sjcd_stat statistic;
-#endif
-
-/*
- * Timer.
- */
-static DEFINE_TIMER(sjcd_delay_timer, NULL, 0, 0);
-
-#define SJCD_SET_TIMER( func, tmout )           \
-    ( sjcd_delay_timer.expires = jiffies+tmout,         \
-      sjcd_delay_timer.function = ( void * )func, \
-      add_timer( &sjcd_delay_timer ) )
-
-#define CLEAR_TIMER del_timer( &sjcd_delay_timer )
-
-/*
- * Set up device, i.e., use command line data to set
- * base address.
- */
-#ifndef MODULE
-static int __init sjcd_setup(char *str)
-{
-       int ints[2];
-       (void) get_options(str, ARRAY_SIZE(ints), ints);
-       if (ints[0] > 0)
-               sjcd_base = ints[1];
-
-       return 1;
-}
-
-__setup("sjcd=", sjcd_setup);
-
-#endif
-
-/*
- * Special converters.
- */
-static unsigned char bin2bcd(int bin)
-{
-       int u, v;
-
-       u = bin % 10;
-       v = bin / 10;
-       return (u | (v << 4));
-}
-
-static int bcd2bin(unsigned char bcd)
-{
-       return ((bcd >> 4) * 10 + (bcd & 0x0F));
-}
-
-static long msf2hsg(struct msf *mp)
-{
-       return (bcd2bin(mp->frame) + bcd2bin(mp->sec) * 75
-               + bcd2bin(mp->min) * 4500 - 150);
-}
-
-static void hsg2msf(long hsg, struct msf *msf)
-{
-       hsg += 150;
-       msf->min = hsg / 4500;
-       hsg %= 4500;
-       msf->sec = hsg / 75;
-       msf->frame = hsg % 75;
-       msf->min = bin2bcd(msf->min);   /* convert to BCD */
-       msf->sec = bin2bcd(msf->sec);
-       msf->frame = bin2bcd(msf->frame);
-}
-
-/*
- * Send a command to cdrom. Invalidate status.
- */
-static void sjcd_send_cmd(unsigned char cmd)
-{
-#if defined( SJCD_TRACE )
-       printk("SJCD: send_cmd( 0x%x )\n", cmd);
-#endif
-       outb(cmd, SJCDPORT(0));
-       sjcd_command_is_in_progress = 1;
-       sjcd_status_valid = 0;
-       sjcd_command_failed = 0;
-}
-
-/*
- * Send a command with one arg to cdrom. Invalidate status.
- */
-static void sjcd_send_1_cmd(unsigned char cmd, unsigned char a)
-{
-#if defined( SJCD_TRACE )
-       printk("SJCD: send_1_cmd( 0x%x, 0x%x )\n", cmd, a);
-#endif
-       outb(cmd, SJCDPORT(0));
-       outb(a, SJCDPORT(0));
-       sjcd_command_is_in_progress = 1;
-       sjcd_status_valid = 0;
-       sjcd_command_failed = 0;
-}
-
-/*
- * Send a command with four args to cdrom. Invalidate status.
- */
-static void sjcd_send_4_cmd(unsigned char cmd, unsigned char a,
-                           unsigned char b, unsigned char c,
-                           unsigned char d)
-{
-#if defined( SJCD_TRACE )
-       printk("SJCD: send_4_cmd( 0x%x )\n", cmd);
-#endif
-       outb(cmd, SJCDPORT(0));
-       outb(a, SJCDPORT(0));
-       outb(b, SJCDPORT(0));
-       outb(c, SJCDPORT(0));
-       outb(d, SJCDPORT(0));
-       sjcd_command_is_in_progress = 1;
-       sjcd_status_valid = 0;
-       sjcd_command_failed = 0;
-}
-
-/*
- * Send a play or read command to cdrom. Invalidate Status.
- */
-static void sjcd_send_6_cmd(unsigned char cmd, struct sjcd_play_msf *pms)
-{
-#if defined( SJCD_TRACE )
-       printk("SJCD: send_long_cmd( 0x%x )\n", cmd);
-#endif
-       outb(cmd, SJCDPORT(0));
-       outb(pms->start.min, SJCDPORT(0));
-       outb(pms->start.sec, SJCDPORT(0));
-       outb(pms->start.frame, SJCDPORT(0));
-       outb(pms->end.min, SJCDPORT(0));
-       outb(pms->end.sec, SJCDPORT(0));
-       outb(pms->end.frame, SJCDPORT(0));
-       sjcd_command_is_in_progress = 1;
-       sjcd_status_valid = 0;
-       sjcd_command_failed = 0;
-}
-
-/*
- * Get a value from the data port. Should not block, so we use a little
- * wait for a while. Returns 0 if OK.
- */
-static int sjcd_load_response(void *buf, int len)
-{
-       unsigned char *resp = (unsigned char *) buf;
-
-       for (; len; --len) {
-               int i;
-               for (i = 200;
-                    i-- && !SJCD_STATUS_AVAILABLE(inb(SJCDPORT(1))););
-               if (i > 0)
-                       *resp++ = (unsigned char) inb(SJCDPORT(0));
-               else
-                       break;
-       }
-       return (len);
-}
-
-/*
- * Load and parse command completion status (drive info byte and maybe error).
- * Sorry, no error classification yet.
- */
-static void sjcd_load_status(void)
-{
-       sjcd_media_is_changed = 0;
-       sjcd_completion_error = 0;
-       sjcd_completion_status = inb(SJCDPORT(0));
-       if (sjcd_completion_status & SST_DOOR_OPENED) {
-               sjcd_door_closed = sjcd_media_is_available = 0;
-       } else {
-               sjcd_door_closed = 1;
-               if (sjcd_completion_status & SST_MEDIA_CHANGED)
-                       sjcd_media_is_available = sjcd_media_is_changed =
-                           1;
-               else if (sjcd_completion_status & 0x0F) {
-                       /*
-                        * OK, we seem to catch an error ...
-                        */
-                       while (!SJCD_STATUS_AVAILABLE(inb(SJCDPORT(1))));
-                       sjcd_completion_error = inb(SJCDPORT(0));
-                       if ((sjcd_completion_status & 0x08) &&
-                           (sjcd_completion_error & 0x40))
-                               sjcd_media_is_available = 0;
-                       else
-                               sjcd_command_failed = 1;
-               } else
-                       sjcd_media_is_available = 1;
-       }
-       /*
-        * Ok, status loaded successfully.
-        */
-       sjcd_status_valid = 1, sjcd_error_reported = 0;
-       sjcd_command_is_in_progress = 0;
-
-       /*
-        * If the disk is changed, the TOC is not valid.
-        */
-       if (sjcd_media_is_changed)
-               sjcd_toc_uptodate = 0;
-#if defined( SJCD_TRACE )
-       printk("SJCD: status %02x.%02x loaded.\n",
-              (int) sjcd_completion_status, (int) sjcd_completion_error);
-#endif
-}
-
-/*
- * Read status from cdrom. Check to see if the status is available.
- */
-static int sjcd_check_status(void)
-{
-       /*
-        * Try to load the response from cdrom into buffer.
-        */
-       if (SJCD_STATUS_AVAILABLE(inb(SJCDPORT(1)))) {
-               sjcd_load_status();
-               return (1);
-       } else {
-               /*
-                * No status is available.
-                */
-               return (0);
-       }
-}
-
-/*
- * This is just timeout counter, and nothing more. Surprised ? :-)
- */
-static volatile long sjcd_status_timeout;
-
-/*
- * We need about 10 seconds to wait. The longest command takes about 5 seconds
- * to probe the disk (usually after tray closed or drive reset). Other values
- * should be thought of for other commands.
- */
-#define SJCD_WAIT_FOR_STATUS_TIMEOUT 1000
-
-static void sjcd_status_timer(void)
-{
-       if (sjcd_check_status()) {
-               /*
-                * The command completed and status is loaded, stop waiting.
-                */
-               wake_up(&sjcd_waitq);
-       } else if (--sjcd_status_timeout <= 0) {
-               /*
-                * We are timed out. 
-                */
-               wake_up(&sjcd_waitq);
-       } else {
-               /*
-                * We have still some time to wait. Try again.
-                */
-               SJCD_SET_TIMER(sjcd_status_timer, 1);
-       }
-}
-
-/*
- * Wait for status for 10 sec approx. Returns non-positive when timed out.
- * Should not be used while reading data CDs.
- */
-static int sjcd_wait_for_status(void)
-{
-       sjcd_status_timeout = SJCD_WAIT_FOR_STATUS_TIMEOUT;
-       SJCD_SET_TIMER(sjcd_status_timer, 1);
-       sleep_on(&sjcd_waitq);
-#if defined( SJCD_DIAGNOSTIC ) || defined ( SJCD_TRACE )
-       if (sjcd_status_timeout <= 0)
-               printk("SJCD: Error Wait For Status.\n");
-#endif
-       return (sjcd_status_timeout);
-}
-
-static int sjcd_receive_status(void)
-{
-       int i;
-#if defined( SJCD_TRACE )
-       printk("SJCD: receive_status\n");
-#endif
-       /*
-        * Wait a bit for status available.
-        */
-       for (i = 200; i-- && (sjcd_check_status() == 0););
-       if (i < 0) {
-#if defined( SJCD_TRACE )
-               printk("SJCD: long wait for status\n");
-#endif
-               if (sjcd_wait_for_status() <= 0)
-                       printk("SJCD: Timeout when read status.\n");
-               else
-                       i = 0;
-       }
-       return (i);
-}
-
-/*
- * Load the status. Issue get status command and wait for status available.
- */
-static void sjcd_get_status(void)
-{
-#if defined( SJCD_TRACE )
-       printk("SJCD: get_status\n");
-#endif
-       sjcd_send_cmd(SCMD_GET_STATUS);
-       sjcd_receive_status();
-}
-
-/*
- * Check the drive if the disk is changed. Should be revised.
- */
-static int sjcd_disk_change(struct gendisk *disk)
-{
-#if 0
-       printk("SJCD: sjcd_disk_change(%s)\n", disk->disk_name);
-#endif
-       if (!sjcd_command_is_in_progress)
-               sjcd_get_status();
-       return (sjcd_status_valid ? sjcd_media_is_changed : 0);
-}
-
-/*
- * Read the table of contents (TOC) and TOC header if necessary.
- * We assume that the drive contains no more than 99 toc entries.
- */
-static struct sjcd_hw_disk_info sjcd_table_of_contents[SJCD_MAX_TRACKS];
-static unsigned char sjcd_first_track_no, sjcd_last_track_no;
-#define sjcd_disk_length  sjcd_table_of_contents[0].un.track_msf
-
-static int sjcd_update_toc(void)
-{
-       struct sjcd_hw_disk_info info;
-       int i;
-#if defined( SJCD_TRACE )
-       printk("SJCD: update toc:\n");
-#endif
-       /*
-        * check to see if we need to do anything
-        */
-       if (sjcd_toc_uptodate)
-               return (0);
-
-       /*
-        * Get the TOC start information.
-        */
-       sjcd_send_1_cmd(SCMD_GET_DISK_INFO, SCMD_GET_1_TRACK);
-       sjcd_receive_status();
-
-       if (!sjcd_status_valid) {
-               printk("SJCD: cannot load status.\n");
-               return (-1);
-       }
-
-       if (!sjcd_media_is_available) {
-               printk("SJCD: no disk in drive\n");
-               return (-1);
-       }
-
-       if (!sjcd_command_failed) {
-               if (sjcd_load_response(&info, sizeof(info)) != 0) {
-                       printk
-                           ("SJCD: cannot load response about TOC start.\n");
-                       return (-1);
-               }
-               sjcd_first_track_no = bcd2bin(info.un.track_no);
-       } else {
-               printk("SJCD: get first failed\n");
-               return (-1);
-       }
-#if defined( SJCD_TRACE )
-       printk("SJCD: TOC start 0x%02x ", sjcd_first_track_no);
-#endif
-       /*
-        * Get the TOC finish information.
-        */
-       sjcd_send_1_cmd(SCMD_GET_DISK_INFO, SCMD_GET_L_TRACK);
-       sjcd_receive_status();
-
-       if (!sjcd_status_valid) {
-               printk("SJCD: cannot load status.\n");
-               return (-1);
-       }
-
-       if (!sjcd_media_is_available) {
-               printk("SJCD: no disk in drive\n");
-               return (-1);
-       }
-
-       if (!sjcd_command_failed) {
-               if (sjcd_load_response(&info, sizeof(info)) != 0) {
-                       printk
-                           ("SJCD: cannot load response about TOC finish.\n");
-                       return (-1);
-               }
-               sjcd_last_track_no = bcd2bin(info.un.track_no);
-       } else {
-               printk("SJCD: get last failed\n");
-               return (-1);
-       }
-#if defined( SJCD_TRACE )
-       printk("SJCD: TOC finish 0x%02x ", sjcd_last_track_no);
-#endif
-       for (i = sjcd_first_track_no; i <= sjcd_last_track_no; i++) {
-               /*
-                * Get the first track information.
-                */
-               sjcd_send_1_cmd(SCMD_GET_DISK_INFO, bin2bcd(i));
-               sjcd_receive_status();
-
-               if (!sjcd_status_valid) {
-                       printk("SJCD: cannot load status.\n");
-                       return (-1);
-               }
-
-               if (!sjcd_media_is_available) {
-                       printk("SJCD: no disk in drive\n");
-                       return (-1);
-               }
-
-               if (!sjcd_command_failed) {
-                       if (sjcd_load_response(&sjcd_table_of_contents[i],
-                                              sizeof(struct
-                                                     sjcd_hw_disk_info))
-                           != 0) {
-                               printk
-                                   ("SJCD: cannot load info for %d track\n",
-                                    i);
-                               return (-1);
-                       }
-               } else {
-                       printk("SJCD: get info %d failed\n", i);
-                       return (-1);
-               }
-       }
-
-       /*
-        * Get the disk length info.
-        */
-       sjcd_send_1_cmd(SCMD_GET_DISK_INFO, SCMD_GET_D_SIZE);
-       sjcd_receive_status();
-
-       if (!sjcd_status_valid) {
-               printk("SJCD: cannot load status.\n");
-               return (-1);
-       }
-
-       if (!sjcd_media_is_available) {
-               printk("SJCD: no disk in drive\n");
-               return (-1);
-       }
-
-       if (!sjcd_command_failed) {
-               if (sjcd_load_response(&info, sizeof(info)) != 0) {
-                       printk
-                           ("SJCD: cannot load response about disk size.\n");
-                       return (-1);
-               }
-               sjcd_disk_length.min = info.un.track_msf.min;
-               sjcd_disk_length.sec = info.un.track_msf.sec;
-               sjcd_disk_length.frame = info.un.track_msf.frame;
-       } else {
-               printk("SJCD: get size failed\n");
-               return (1);
-       }
-#if defined( SJCD_TRACE )
-       printk("SJCD: (%02x:%02x.%02x)\n", sjcd_disk_length.min,
-              sjcd_disk_length.sec, sjcd_disk_length.frame);
-#endif
-       return (0);
-}
-
-/*
- * Load subchannel information.
- */
-static int sjcd_get_q_info(struct sjcd_hw_qinfo *qp)
-{
-       int s;
-#if defined( SJCD_TRACE )
-       printk("SJCD: load sub q\n");
-#endif
-       sjcd_send_cmd(SCMD_GET_QINFO);
-       s = sjcd_receive_status();
-       if (s < 0 || sjcd_command_failed || !sjcd_status_valid) {
-               sjcd_send_cmd(0xF2);
-               s = sjcd_receive_status();
-               if (s < 0 || sjcd_command_failed || !sjcd_status_valid)
-                       return (-1);
-               sjcd_send_cmd(SCMD_GET_QINFO);
-               s = sjcd_receive_status();
-               if (s < 0 || sjcd_command_failed || !sjcd_status_valid)
-                       return (-1);
-       }
-       if (sjcd_media_is_available)
-               if (sjcd_load_response(qp, sizeof(*qp)) == 0)
-                       return (0);
-       return (-1);
-}
-
-/*
- * Start playing from the specified position.
- */
-static int sjcd_play(struct sjcd_play_msf *mp)
-{
-       struct sjcd_play_msf msf;
-
-       /*
-        * Turn the device to play mode.
-        */
-       sjcd_send_1_cmd(SCMD_SET_MODE, SCMD_MODE_PLAY);
-       if (sjcd_receive_status() < 0)
-               return (-1);
-
-       /*
-        * Seek to the starting point.
-        */
-       msf.start = mp->start;
-       msf.end.min = msf.end.sec = msf.end.frame = 0x00;
-       sjcd_send_6_cmd(SCMD_SEEK, &msf);
-       if (sjcd_receive_status() < 0)
-               return (-1);
-
-       /*
-        * Start playing.
-        */
-       sjcd_send_6_cmd(SCMD_PLAY, mp);
-       return (sjcd_receive_status());
-}
-
-/*
- * Tray control functions.
- */
-static int sjcd_tray_close(void)
-{
-#if defined( SJCD_TRACE )
-       printk("SJCD: tray_close\n");
-#endif
-       sjcd_send_cmd(SCMD_CLOSE_TRAY);
-       return (sjcd_receive_status());
-}
-
-static int sjcd_tray_lock(void)
-{
-#if defined( SJCD_TRACE )
-       printk("SJCD: tray_lock\n");
-#endif
-       sjcd_send_cmd(SCMD_LOCK_TRAY);
-       return (sjcd_receive_status());
-}
-
-static int sjcd_tray_unlock(void)
-{
-#if defined( SJCD_TRACE )
-       printk("SJCD: tray_unlock\n");
-#endif
-       sjcd_send_cmd(SCMD_UNLOCK_TRAY);
-       return (sjcd_receive_status());
-}
-
-static int sjcd_tray_open(void)
-{
-#if defined( SJCD_TRACE )
-       printk("SJCD: tray_open\n");
-#endif
-       sjcd_send_cmd(SCMD_EJECT_TRAY);
-       return (sjcd_receive_status());
-}
-
-/*
- * Do some user commands.
- */
-static int sjcd_ioctl(struct inode *ip, struct file *fp,
-                     unsigned int cmd, unsigned long arg)
-{
-       void __user *argp = (void __user *)arg;
-#if defined( SJCD_TRACE )
-       printk("SJCD:ioctl\n");
-#endif
-
-       sjcd_get_status();
-       if (!sjcd_status_valid)
-               return (-EIO);
-       if (sjcd_update_toc() < 0)
-               return (-EIO);
-
-       switch (cmd) {
-       case CDROMSTART:{
-#if defined( SJCD_TRACE )
-                       printk("SJCD: ioctl: start\n");
-#endif
-                       return (0);
-               }
-
-       case CDROMSTOP:{
-#if defined( SJCD_TRACE )
-                       printk("SJCD: ioctl: stop\n");
-#endif
-                       sjcd_send_cmd(SCMD_PAUSE);
-                       (void) sjcd_receive_status();
-                       sjcd_audio_status = CDROM_AUDIO_NO_STATUS;
-                       return (0);
-               }
-
-       case CDROMPAUSE:{
-                       struct sjcd_hw_qinfo q_info;
-#if defined( SJCD_TRACE )
-                       printk("SJCD: ioctl: pause\n");
-#endif
-                       if (sjcd_audio_status == CDROM_AUDIO_PLAY) {
-                               sjcd_send_cmd(SCMD_PAUSE);
-                               (void) sjcd_receive_status();
-                               if (sjcd_get_q_info(&q_info) < 0) {
-                                       sjcd_audio_status =
-                                           CDROM_AUDIO_NO_STATUS;
-                               } else {
-                                       sjcd_audio_status =
-                                           CDROM_AUDIO_PAUSED;
-                                       sjcd_playing.start = q_info.abs;
-                               }
-                               return (0);
-                       } else
-                               return (-EINVAL);
-               }
-
-       case CDROMRESUME:{
-#if defined( SJCD_TRACE )
-                       printk("SJCD: ioctl: resume\n");
-#endif
-                       if (sjcd_audio_status == CDROM_AUDIO_PAUSED) {
-                               /*
-                                * continue play starting at saved location
-                                */
-                               if (sjcd_play(&sjcd_playing) < 0) {
-                                       sjcd_audio_status =
-                                           CDROM_AUDIO_ERROR;
-                                       return (-EIO);
-                               } else {
-                                       sjcd_audio_status =
-                                           CDROM_AUDIO_PLAY;
-                                       return (0);
-                               }
-                       } else
-                               return (-EINVAL);
-               }
-
-       case CDROMPLAYTRKIND:{
-                       struct cdrom_ti ti;
-                       int s = -EFAULT;
-#if defined( SJCD_TRACE )
-                       printk("SJCD: ioctl: playtrkind\n");
-#endif
-                       if (!copy_from_user(&ti, argp, sizeof(ti))) {
-                               s = 0;
-                               if (ti.cdti_trk0 < sjcd_first_track_no)
-                                       return (-EINVAL);
-                               if (ti.cdti_trk1 > sjcd_last_track_no)
-                                       ti.cdti_trk1 = sjcd_last_track_no;
-                               if (ti.cdti_trk0 > ti.cdti_trk1)
-                                       return (-EINVAL);
-
-                               sjcd_playing.start =
-                                   sjcd_table_of_contents[ti.cdti_trk0].
-                                   un.track_msf;
-                               sjcd_playing.end =
-                                   (ti.cdti_trk1 <
-                                    sjcd_last_track_no) ?
-                                   sjcd_table_of_contents[ti.cdti_trk1 +
-                                                          1].un.
-                                   track_msf : sjcd_table_of_contents[0].
-                                   un.track_msf;
-
-                               if (sjcd_play(&sjcd_playing) < 0) {
-                                       sjcd_audio_status =
-                                           CDROM_AUDIO_ERROR;
-                                       return (-EIO);
-                               } else
-                                       sjcd_audio_status =
-                                           CDROM_AUDIO_PLAY;
-                       }
-                       return (s);
-               }
-
-       case CDROMPLAYMSF:{
-                       struct cdrom_msf sjcd_msf;
-                       int s;
-#if defined( SJCD_TRACE )
-                       printk("SJCD: ioctl: playmsf\n");
-#endif
-                       if ((s =
-                            access_ok(VERIFY_READ, argp, sizeof(sjcd_msf))
-                                       ? 0 : -EFAULT) == 0) {
-                               if (sjcd_audio_status == CDROM_AUDIO_PLAY) {
-                                       sjcd_send_cmd(SCMD_PAUSE);
-                                       (void) sjcd_receive_status();
-                                       sjcd_audio_status =
-                                           CDROM_AUDIO_NO_STATUS;
-                               }
-
-                               if (copy_from_user(&sjcd_msf, argp,
-                                              sizeof(sjcd_msf)))
-                                       return (-EFAULT);
-
-                               sjcd_playing.start.min =
-                                   bin2bcd(sjcd_msf.cdmsf_min0);
-                               sjcd_playing.start.sec =
-                                   bin2bcd(sjcd_msf.cdmsf_sec0);
-                               sjcd_playing.start.frame =
-                                   bin2bcd(sjcd_msf.cdmsf_frame0);
-                               sjcd_playing.end.min =
-                                   bin2bcd(sjcd_msf.cdmsf_min1);
-                               sjcd_playing.end.sec =
-                                   bin2bcd(sjcd_msf.cdmsf_sec1);
-                               sjcd_playing.end.frame =
-                                   bin2bcd(sjcd_msf.cdmsf_frame1);
-
-                               if (sjcd_play(&sjcd_playing) < 0) {
-                                       sjcd_audio_status =
-                                           CDROM_AUDIO_ERROR;
-                                       return (-EIO);
-                               } else
-                                       sjcd_audio_status =
-                                           CDROM_AUDIO_PLAY;
-                       }
-                       return (s);
-               }
-
-       case CDROMREADTOCHDR:{
-                       struct cdrom_tochdr toc_header;
-#if defined (SJCD_TRACE )
-                       printk("SJCD: ioctl: readtocheader\n");
-#endif
-                       toc_header.cdth_trk0 = sjcd_first_track_no;
-                       toc_header.cdth_trk1 = sjcd_last_track_no;
-                       if (copy_to_user(argp, &toc_header,
-                                        sizeof(toc_header)))
-                               return -EFAULT;
-                       return 0;
-               }
-
-       case CDROMREADTOCENTRY:{
-                       struct cdrom_tocentry toc_entry;
-                       int s;
-#if defined( SJCD_TRACE )
-                       printk("SJCD: ioctl: readtocentry\n");
-#endif
-                       if ((s =
-                            access_ok(VERIFY_WRITE, argp, sizeof(toc_entry))
-                                       ? 0 : -EFAULT) == 0) {
-                               struct sjcd_hw_disk_info *tp;
-
-                               if (copy_from_user(&toc_entry, argp,
-                                              sizeof(toc_entry)))
-                                       return (-EFAULT);
-                               if (toc_entry.cdte_track == CDROM_LEADOUT)
-                                       tp = &sjcd_table_of_contents[0];
-                               else if (toc_entry.cdte_track <
-                                        sjcd_first_track_no)
-                                       return (-EINVAL);
-                               else if (toc_entry.cdte_track >
-                                        sjcd_last_track_no)
-                                       return (-EINVAL);
-                               else
-                                       tp = &sjcd_table_of_contents
-                                           [toc_entry.cdte_track];
-
-                               toc_entry.cdte_adr =
-                                   tp->track_control & 0x0F;
-                               toc_entry.cdte_ctrl =
-                                   tp->track_control >> 4;
-
-                               switch (toc_entry.cdte_format) {
-                               case CDROM_LBA:
-                                       toc_entry.cdte_addr.lba =
-                                           msf2hsg(&(tp->un.track_msf));
-                                       break;
-                               case CDROM_MSF:
-                                       toc_entry.cdte_addr.msf.minute =
-                                           bcd2bin(tp->un.track_msf.min);
-                                       toc_entry.cdte_addr.msf.second =
-                                           bcd2bin(tp->un.track_msf.sec);
-                                       toc_entry.cdte_addr.msf.frame =
-                                           bcd2bin(tp->un.track_msf.
-                                                   frame);
-                                       break;
-                               default:
-                                       return (-EINVAL);
-                               }
-                               if (copy_to_user(argp, &toc_entry,
-                                                sizeof(toc_entry)))
-                                       s = -EFAULT;
-                       }
-                       return (s);
-               }
-
-       case CDROMSUBCHNL:{
-                       struct cdrom_subchnl subchnl;
-                       int s;
-#if defined( SJCD_TRACE )
-                       printk("SJCD: ioctl: subchnl\n");
-#endif
-                       if ((s =
-                            access_ok(VERIFY_WRITE, argp, sizeof(subchnl))
-                                       ? 0 : -EFAULT) == 0) {
-                               struct sjcd_hw_qinfo q_info;
-
-                               if (copy_from_user(&subchnl, argp,
-                                              sizeof(subchnl)))
-                                       return (-EFAULT);
-
-                               if (sjcd_get_q_info(&q_info) < 0)
-                                       return (-EIO);
-
-                               subchnl.cdsc_audiostatus =
-                                   sjcd_audio_status;
-                               subchnl.cdsc_adr =
-                                   q_info.track_control & 0x0F;
-                               subchnl.cdsc_ctrl =
-                                   q_info.track_control >> 4;
-                               subchnl.cdsc_trk =
-                                   bcd2bin(q_info.track_no);
-                               subchnl.cdsc_ind = bcd2bin(q_info.x);
-
-                               switch (subchnl.cdsc_format) {
-                               case CDROM_LBA:
-                                       subchnl.cdsc_absaddr.lba =
-                                           msf2hsg(&(q_info.abs));
-                                       subchnl.cdsc_reladdr.lba =
-                                           msf2hsg(&(q_info.rel));
-                                       break;
-                               case CDROM_MSF:
-                                       subchnl.cdsc_absaddr.msf.minute =
-                                           bcd2bin(q_info.abs.min);
-                                       subchnl.cdsc_absaddr.msf.second =
-                                           bcd2bin(q_info.abs.sec);
-                                       subchnl.cdsc_absaddr.msf.frame =
-                                           bcd2bin(q_info.abs.frame);
-                                       subchnl.cdsc_reladdr.msf.minute =
-                                           bcd2bin(q_info.rel.min);
-                                       subchnl.cdsc_reladdr.msf.second =
-                                           bcd2bin(q_info.rel.sec);
-                                       subchnl.cdsc_reladdr.msf.frame =
-                                           bcd2bin(q_info.rel.frame);
-                                       break;
-                               default:
-                                       return (-EINVAL);
-                               }
-                               if (copy_to_user(argp, &subchnl,
-                                                sizeof(subchnl)))
-                                       s = -EFAULT;
-                       }
-                       return (s);
-               }
-
-       case CDROMVOLCTRL:{
-                       struct cdrom_volctrl vol_ctrl;
-                       int s;
-#if defined( SJCD_TRACE )
-                       printk("SJCD: ioctl: volctrl\n");
-#endif
-                       if ((s =
-                            access_ok(VERIFY_READ, argp, sizeof(vol_ctrl))
-                                       ? 0 : -EFAULT) == 0) {
-                               unsigned char dummy[4];
-
-                               if (copy_from_user(&vol_ctrl, argp,
-                                              sizeof(vol_ctrl)))
-                                       return (-EFAULT);
-                               sjcd_send_4_cmd(SCMD_SET_VOLUME,
-                                               vol_ctrl.channel0, 0xFF,
-                                               vol_ctrl.channel1, 0xFF);
-                               if (sjcd_receive_status() < 0)
-                                       return (-EIO);
-                               (void) sjcd_load_response(dummy, 4);
-                       }
-                       return (s);
-               }
-
-       case CDROMEJECT:{
-#if defined( SJCD_TRACE )
-                       printk("SJCD: ioctl: eject\n");
-#endif
-                       if (!sjcd_command_is_in_progress) {
-                               sjcd_tray_unlock();
-                               sjcd_send_cmd(SCMD_EJECT_TRAY);
-                               (void) sjcd_receive_status();
-                       }
-                       return (0);
-               }
-
-#if defined( SJCD_GATHER_STAT )
-       case 0xABCD:{
-#if defined( SJCD_TRACE )
-                       printk("SJCD: ioctl: statistic\n");
-#endif
-                       if (copy_to_user(argp, &statistic, sizeof(statistic)))
-                               return -EFAULT;
-                       return 0;
-               }
-#endif
-
-       default:
-               return (-EINVAL);
-       }
-}
-
-/*
- * Invalidate internal buffers of the driver.
- */
-static void sjcd_invalidate_buffers(void)
-{
-       int i;
-       for (i = 0; i < SJCD_BUF_SIZ; sjcd_buf_bn[i++] = -1);
-       sjcd_buf_out = -1;
-}
-
-/*
- * Take care of the different block sizes between cdrom and Linux.
- * When Linux gets variable block sizes this will probably go away.
- */
-
-static int current_valid(void)
-{
-        return CURRENT &&
-               CURRENT->cmd == READ &&
-               CURRENT->sector != -1;
-}
-
-static void sjcd_transfer(void)
-{
-#if defined( SJCD_TRACE )
-       printk("SJCD: transfer:\n");
-#endif
-       if (current_valid()) {
-               while (CURRENT->nr_sectors) {
-                       int i, bn = CURRENT->sector / 4;
-                       for (i = 0;
-                            i < SJCD_BUF_SIZ && sjcd_buf_bn[i] != bn;
-                            i++);
-                       if (i < SJCD_BUF_SIZ) {
-                               int offs =
-                                   (i * 4 + (CURRENT->sector & 3)) * 512;
-                               int nr_sectors = 4 - (CURRENT->sector & 3);
-                               if (sjcd_buf_out != i) {
-                                       sjcd_buf_out = i;
-                                       if (sjcd_buf_bn[i] != bn) {
-                                               sjcd_buf_out = -1;
-                                               continue;
-                                       }
-                               }
-                               if (nr_sectors > CURRENT->nr_sectors)
-                                       nr_sectors = CURRENT->nr_sectors;
-#if defined( SJCD_TRACE )
-                               printk("SJCD: copy out\n");
-#endif
-                               memcpy(CURRENT->buffer, sjcd_buf + offs,
-                                      nr_sectors * 512);
-                               CURRENT->nr_sectors -= nr_sectors;
-                               CURRENT->sector += nr_sectors;
-                               CURRENT->buffer += nr_sectors * 512;
-                       } else {
-                               sjcd_buf_out = -1;
-                               break;
-                       }
-               }
-       }
-#if defined( SJCD_TRACE )
-       printk("SJCD: transfer: done\n");
-#endif
-}
-
-static void sjcd_poll(void)
-{
-#if defined( SJCD_GATHER_STAT )
-       /*
-        * Update total number of ticks.
-        */
-       statistic.ticks++;
-       statistic.tticks[sjcd_transfer_state]++;
-#endif
-
-      ReSwitch:switch (sjcd_transfer_state) {
-
-       case SJCD_S_IDLE:{
-#if defined( SJCD_GATHER_STAT )
-                       statistic.idle_ticks++;
-#endif
-#if defined( SJCD_TRACE )
-                       printk("SJCD_S_IDLE\n");
-#endif
-                       return;
-               }
-
-       case SJCD_S_START:{
-#if defined( SJCD_GATHER_STAT )
-                       statistic.start_ticks++;
-#endif
-                       sjcd_send_cmd(SCMD_GET_STATUS);
-                       sjcd_transfer_state =
-                           sjcd_mode ==
-                           SCMD_MODE_COOKED ? SJCD_S_READ : SJCD_S_MODE;
-                       sjcd_transfer_timeout = 500;
-#if defined( SJCD_TRACE )
-                       printk("SJCD_S_START: goto SJCD_S_%s mode\n",
-                              sjcd_transfer_state ==
-                              SJCD_S_READ ? "READ" : "MODE");
-#endif
-                       break;
-               }
-
-       case SJCD_S_MODE:{
-                       if (sjcd_check_status()) {
-                               /*
-                                * Previous command is completed.
-                                */
-                               if (!sjcd_status_valid
-                                   || sjcd_command_failed) {
-#if defined( SJCD_TRACE )
-                                       printk
-                                           ("SJCD_S_MODE: pre-cmd failed: goto to SJCD_S_STOP mode\n");
-#endif
-                                       sjcd_transfer_state = SJCD_S_STOP;
-                                       goto ReSwitch;
-                               }
-
-                               sjcd_mode = 0;  /* unknown mode; should not be valid when failed */
-                               sjcd_send_1_cmd(SCMD_SET_MODE,
-                                               SCMD_MODE_COOKED);
-                               sjcd_transfer_state = SJCD_S_READ;
-                               sjcd_transfer_timeout = 1000;
-#if defined( SJCD_TRACE )
-                               printk
-                                   ("SJCD_S_MODE: goto SJCD_S_READ mode\n");
-#endif
-                       }
-#if defined( SJCD_GATHER_STAT )
-                       else
-                               statistic.mode_ticks++;
-#endif
-                       break;
-               }
-
-       case SJCD_S_READ:{
-                       if (sjcd_status_valid ? 1 : sjcd_check_status()) {
-                               /*
-                                * Previous command is completed.
-                                */
-                               if (!sjcd_status_valid
-                                   || sjcd_command_failed) {
-#if defined( SJCD_TRACE )
-                                       printk
-                                           ("SJCD_S_READ: pre-cmd failed: goto to SJCD_S_STOP mode\n");
-#endif
-                                       sjcd_transfer_state = SJCD_S_STOP;
-                                       goto ReSwitch;
-                               }
-                               if (!sjcd_media_is_available) {
-#if defined( SJCD_TRACE )
-                                       printk
-                                           ("SJCD_S_READ: no disk: goto to SJCD_S_STOP mode\n");
-#endif
-                                       sjcd_transfer_state = SJCD_S_STOP;
-                                       goto ReSwitch;
-                               }
-                               if (sjcd_mode != SCMD_MODE_COOKED) {
-                                       /*
-                                        * We seem to come from set mode. So discard one byte of result.
-                                        */
-                                       if (sjcd_load_response
-                                           (&sjcd_mode, 1) != 0) {
-#if defined( SJCD_TRACE )
-                                               printk
-                                                   ("SJCD_S_READ: load failed: goto to SJCD_S_STOP mode\n");
-#endif
-                                               sjcd_transfer_state =
-                                                   SJCD_S_STOP;
-                                               goto ReSwitch;
-                                       }
-                                       if (sjcd_mode != SCMD_MODE_COOKED) {
-#if defined( SJCD_TRACE )
-                                               printk
-                                                   ("SJCD_S_READ: mode failed: goto to SJCD_S_STOP mode\n");
-#endif
-                                               sjcd_transfer_state =
-                                                   SJCD_S_STOP;
-                                               goto ReSwitch;
-                                       }
-                               }
-
-                               if (current_valid()) {
-                                       struct sjcd_play_msf msf;
-
-                                       sjcd_next_bn = CURRENT->sector / 4;
-                                       hsg2msf(sjcd_next_bn, &msf.start);
-                                       msf.end.min = 0;
-                                       msf.end.sec = 0;
-                                       msf.end.frame = sjcd_read_count =
-                                           SJCD_BUF_SIZ;
-#if defined( SJCD_TRACE )
-                                       printk
-                                           ("SJCD: ---reading msf-address %x:%x:%x  %x:%x:%x\n",
-                                            msf.start.min, msf.start.sec,
-                                            msf.start.frame, msf.end.min,
-                                            msf.end.sec, msf.end.frame);
-                                       printk
-                                           ("sjcd_next_bn:%x buf_in:%x buf_out:%x buf_bn:%x\n",
-                                            sjcd_next_bn, sjcd_buf_in,
-                                            sjcd_buf_out,
-                                            sjcd_buf_bn[sjcd_buf_in]);
-#endif
-                                       sjcd_send_6_cmd(SCMD_DATA_READ,
-                                                       &msf);
-                                       sjcd_transfer_state = SJCD_S_DATA;
-                                       sjcd_transfer_timeout = 500;
-#if defined( SJCD_TRACE )
-                                       printk
-                                           ("SJCD_S_READ: go to SJCD_S_DATA mode\n");
-#endif
-                               } else {
-#if defined( SJCD_TRACE )
-                                       printk
-                                           ("SJCD_S_READ: nothing to read: go to SJCD_S_STOP mode\n");
-#endif
-                                       sjcd_transfer_state = SJCD_S_STOP;
-                                       goto ReSwitch;
-                               }
-                       }
-#if defined( SJCD_GATHER_STAT )
-                       else
-                               statistic.read_ticks++;
-#endif
-                       break;
-               }
-
-       case SJCD_S_DATA:{
-                       unsigned char stat;
-
-                     sjcd_s_data:stat =
-                           inb(SJCDPORT
-                               (1));
-#if defined( SJCD_TRACE )
-                       printk("SJCD_S_DATA: status = 0x%02x\n", stat);
-#endif
-                       if (SJCD_STATUS_AVAILABLE(stat)) {
-                               /*
-                                * No data is waiting for us in the drive buffer. Status of operation
-                                * completion is available. Read and parse it.
-                                */
-                               sjcd_load_status();
-
-                               if (!sjcd_status_valid
-                                   || sjcd_command_failed) {
-#if defined( SJCD_TRACE )
-                                       printk
-                                           ("SJCD: read block %d failed, maybe audio disk? Giving up\n",
-                                            sjcd_next_bn);
-#endif
-                                       if (current_valid())
-                                               end_request(CURRENT, 0);
-#if defined( SJCD_TRACE )
-                                       printk
-                                           ("SJCD_S_DATA: pre-cmd failed: go to SJCD_S_STOP mode\n");
-#endif
-                                       sjcd_transfer_state = SJCD_S_STOP;
-                                       goto ReSwitch;
-                               }
-
-                               if (!sjcd_media_is_available) {
-                                       printk
-                                           ("SJCD_S_DATA: no disk: go to SJCD_S_STOP mode\n");
-                                       sjcd_transfer_state = SJCD_S_STOP;
-                                       goto ReSwitch;
-                               }
-
-                               sjcd_transfer_state = SJCD_S_READ;
-                               goto ReSwitch;
-                       } else if (SJCD_DATA_AVAILABLE(stat)) {
-                               /*
-                                * One frame is read into device buffer. We must copy it to our memory.
-                                * Otherwise cdrom hangs up. Check to see if we have something to copy
-                                * to.
-                                */
-                               if (!current_valid()
-                                   && sjcd_buf_in == sjcd_buf_out) {
-#if defined( SJCD_TRACE )
-                                       printk
-                                           ("SJCD_S_DATA: nothing to read: go to SJCD_S_STOP mode\n");
-                                       printk
-                                           (" ... all the date would be discarded\n");
-#endif
-                                       sjcd_transfer_state = SJCD_S_STOP;
-                                       goto ReSwitch;
-                               }
-
-                               /*
-                                * Everything seems to be OK. Just read the frame and recalculate
-                                * indices.
-                                */
-                               sjcd_buf_bn[sjcd_buf_in] = -1;  /* ??? */
-                               insb(SJCDPORT(2),
-                                    sjcd_buf + 2048 * sjcd_buf_in, 2048);
-#if defined( SJCD_TRACE )
-                               printk
-                                   ("SJCD_S_DATA: next_bn=%d, buf_in=%d, buf_out=%d, buf_bn=%d\n",
-                                    sjcd_next_bn, sjcd_buf_in,
-                                    sjcd_buf_out,
-                                    sjcd_buf_bn[sjcd_buf_in]);
-#endif
-                               sjcd_buf_bn[sjcd_buf_in] = sjcd_next_bn++;
-                               if (sjcd_buf_out == -1)
-                                       sjcd_buf_out = sjcd_buf_in;
-                               if (++sjcd_buf_in == SJCD_BUF_SIZ)
-                                       sjcd_buf_in = 0;
-
-                               /*
-                                * Only one frame is ready at time. So we should turn over to wait for
-                                * another frame. If we need that, of course.
-                                */
-                               if (--sjcd_read_count == 0) {
-                                       /*
-                                        * OK, request seems to be precessed. Continue transferring...
-                                        */
-                                       if (!sjcd_transfer_is_active) {
-                                               while (current_valid()) {
-                                                       /*
-                                                        * Continue transferring.
-                                                        */
-                                                       sjcd_transfer();
-                                                       if (CURRENT->
-                                                           nr_sectors ==
-                                                           0)
-                                                               end_request
-                                                                   (CURRENT, 1);
-                                                       else
-                                                               break;
-                                               }
-                                       }
-                                       if (current_valid() &&
-                                           (CURRENT->sector / 4 <
-                                            sjcd_next_bn
-                                            || CURRENT->sector / 4 >
-                                            sjcd_next_bn +
-                                            SJCD_BUF_SIZ)) {
-#if defined( SJCD_TRACE )
-                                               printk
-                                                   ("SJCD_S_DATA: can't read: go to SJCD_S_STOP mode\n");
-#endif
-                                               sjcd_transfer_state =
-                                                   SJCD_S_STOP;
-                                               goto ReSwitch;
-                                       }
-                               }
-                               /*
-                                * Now we should turn around rather than wait for while.
-                                */
-                               goto sjcd_s_data;
-                       }
-#if defined( SJCD_GATHER_STAT )
-                       else
-                               statistic.data_ticks++;
-#endif
-                       break;
-               }
-
-       case SJCD_S_STOP:{
-                       sjcd_read_count = 0;
-                       sjcd_send_cmd(SCMD_STOP);
-                       sjcd_transfer_state = SJCD_S_STOPPING;
-                       sjcd_transfer_timeout = 500;
-#if defined( SJCD_GATHER_STAT )
-                       statistic.stop_ticks++;
-#endif
-                       break;
-               }
-
-       case SJCD_S_STOPPING:{
-                       unsigned char stat;
-
-                       stat = inb(SJCDPORT(1));
-#if defined( SJCD_TRACE )
-                       printk("SJCD_S_STOP: status = 0x%02x\n", stat);
-#endif
-                       if (SJCD_DATA_AVAILABLE(stat)) {
-                               int i;
-#if defined( SJCD_TRACE )
-                               printk("SJCD_S_STOP: discard data\n");
-#endif
-                               /*
-                                * Discard all the data from the pipe. Foolish method.
-                                */
-                               for (i = 2048; i--;
-                                    (void) inb(SJCDPORT(2)));
-                               sjcd_transfer_timeout = 500;
-                       } else if (SJCD_STATUS_AVAILABLE(stat)) {
-                               sjcd_load_status();
-                               if (sjcd_status_valid
-                                   && sjcd_media_is_changed) {
-                                       sjcd_toc_uptodate = 0;
-                                       sjcd_invalidate_buffers();
-                               }
-                               if (current_valid()) {
-                                       if (sjcd_status_valid)
-                                               sjcd_transfer_state =
-                                                   SJCD_S_READ;
-                                       else
-                                               sjcd_transfer_state =
-                                                   SJCD_S_START;
-                               } else
-                                       sjcd_transfer_state = SJCD_S_IDLE;
-                               goto ReSwitch;
-                       }
-#if defined( SJCD_GATHER_STAT )
-                       else
-                               statistic.stopping_ticks++;
-#endif
-                       break;
-               }
-
-       default:
-               printk("SJCD: poll: invalid state %d\n",
-                      sjcd_transfer_state);
-               return;
-       }
-
-       if (--sjcd_transfer_timeout == 0) {
-               printk("SJCD: timeout in state %d\n", sjcd_transfer_state);
-               while (current_valid())
-                       end_request(CURRENT, 0);
-               sjcd_send_cmd(SCMD_STOP);
-               sjcd_transfer_state = SJCD_S_IDLE;
-               goto ReSwitch;
-       }
-
-       /*
-        * Get back in some time. 1 should be replaced with count variable to
-        * avoid unnecessary testings.
-        */
-       SJCD_SET_TIMER(sjcd_poll, 1);
-}
-
-static void do_sjcd_request(request_queue_t * q)
-{
-#if defined( SJCD_TRACE )
-       printk("SJCD: do_sjcd_request(%ld+%ld)\n",
-              CURRENT->sector, CURRENT->nr_sectors);
-#endif
-       sjcd_transfer_is_active = 1;
-       while (current_valid()) {
-               sjcd_transfer();
-               if (CURRENT->nr_sectors == 0)
-                       end_request(CURRENT, 1);
-               else {
-                       sjcd_buf_out = -1;      /* Want to read a block not in buffer */
-                       if (sjcd_transfer_state == SJCD_S_IDLE) {
-                               if (!sjcd_toc_uptodate) {
-                                       if (sjcd_update_toc() < 0) {
-                                               printk
-                                                   ("SJCD: transfer: discard\n");
-                                               while (current_valid())
-                                                       end_request(CURRENT, 0);
-                                               break;
-                                       }
-                               }
-                               sjcd_transfer_state = SJCD_S_START;
-                               SJCD_SET_TIMER(sjcd_poll, HZ / 100);
-                       }
-                       break;
-               }
-       }
-       sjcd_transfer_is_active = 0;
-#if defined( SJCD_TRACE )
-       printk
-           ("sjcd_next_bn:%x sjcd_buf_in:%x sjcd_buf_out:%x sjcd_buf_bn:%x\n",
-            sjcd_next_bn, sjcd_buf_in, sjcd_buf_out,
-            sjcd_buf_bn[sjcd_buf_in]);
-       printk("do_sjcd_request ends\n");
-#endif
-}
-
-/*
- * Open the device special file. Check disk is in.
- */
-static int sjcd_open(struct inode *ip, struct file *fp)
-{
-       /*
-        * Check the presence of device.
-        */
-       if (!sjcd_present)
-               return (-ENXIO);
-
-       /*
-        * Only read operations are allowed. Really? (:-)
-        */
-       if (fp->f_mode & 2)
-               return (-EROFS);
-
-       if (sjcd_open_count == 0) {
-               int s, sjcd_open_tries;
-/* We don't know that, do we? */
-/*
-    sjcd_audio_status = CDROM_AUDIO_NO_STATUS;
-*/
-               sjcd_mode = 0;
-               sjcd_door_was_open = 0;
-               sjcd_transfer_state = SJCD_S_IDLE;
-               sjcd_invalidate_buffers();
-               sjcd_status_valid = 0;
-
-               /*
-                * Strict status checking.
-                */
-               for (sjcd_open_tries = 4; --sjcd_open_tries;) {
-                       if (!sjcd_status_valid)
-                               sjcd_get_status();
-                       if (!sjcd_status_valid) {
-#if defined( SJCD_DIAGNOSTIC )
-                               printk
-                                   ("SJCD: open: timed out when check status.\n");
-#endif
-                               goto err_out;
-                       } else if (!sjcd_media_is_available) {
-#if defined( SJCD_DIAGNOSTIC )
-                               printk("SJCD: open: no disk in drive\n");
-#endif
-                               if (!sjcd_door_closed) {
-                                       sjcd_door_was_open = 1;
-#if defined( SJCD_TRACE )
-                                       printk
-                                           ("SJCD: open: close the tray\n");
-#endif
-                                       s = sjcd_tray_close();
-                                       if (s < 0 || !sjcd_status_valid
-                                           || sjcd_command_failed) {
-#if defined( SJCD_DIAGNOSTIC )
-                                               printk
-                                                   ("SJCD: open: tray close attempt failed\n");
-#endif
-                                               goto err_out;
-                                       }
-                                       continue;
-                               } else
-                                       goto err_out;
-                       }
-                       break;
-               }
-               s = sjcd_tray_lock();
-               if (s < 0 || !sjcd_status_valid || sjcd_command_failed) {
-#if defined( SJCD_DIAGNOSTIC )
-                       printk("SJCD: open: tray lock attempt failed\n");
-#endif
-                       goto err_out;
-               }
-#if defined( SJCD_TRACE )
-               printk("SJCD: open: done\n");
-#endif
-       }
-
-       ++sjcd_open_count;
-       return (0);
-
-      err_out:
-       return (-EIO);
-}
-
-/*
- * On close, we flush all sjcd blocks from the buffer cache.
- */
-static int sjcd_release(struct inode *inode, struct file *file)
-{
-       int s;
-
-#if defined( SJCD_TRACE )
-       printk("SJCD: release\n");
-#endif
-       if (--sjcd_open_count == 0) {
-               sjcd_invalidate_buffers();
-               s = sjcd_tray_unlock();
-               if (s < 0 || !sjcd_status_valid || sjcd_command_failed) {
-#if defined( SJCD_DIAGNOSTIC )
-                       printk
-                           ("SJCD: release: tray unlock attempt failed.\n");
-#endif
-               }
-               if (sjcd_door_was_open) {
-                       s = sjcd_tray_open();
-                       if (s < 0 || !sjcd_status_valid
-                           || sjcd_command_failed) {
-#if defined( SJCD_DIAGNOSTIC )
-                               printk
-                                   ("SJCD: release: tray unload attempt failed.\n");
-#endif
-                       }
-               }
-       }
-       return 0;
-}
-
-/*
- * A list of file operations allowed for this cdrom.
- */
-static struct block_device_operations sjcd_fops = {
-       .owner          = THIS_MODULE,
-       .open           = sjcd_open,
-       .release        = sjcd_release,
-       .ioctl          = sjcd_ioctl,
-       .media_changed  = sjcd_disk_change,
-};
-
-/*
- * Following stuff is intended for initialization of the cdrom. It
- * first looks for presence of device. If the device is present, it
- * will be reset. Then read the version of the drive and load status.
- * The version is two BCD-coded bytes.
- */
-static struct {
-       unsigned char major, minor;
-} sjcd_version;
-
-static struct gendisk *sjcd_disk;
-
-/*
- * Test for presence of drive and initialize it. Called at boot time.
- * Probe cdrom, find out version and status.
- */
-static int __init sjcd_init(void)
-{
-       int i;
-
-       printk(KERN_INFO
-              "SJCD: Sanyo CDR-H94A cdrom driver version %d.%d.\n",
-              SJCD_VERSION_MAJOR, SJCD_VERSION_MINOR);
-
-#if defined( SJCD_TRACE )
-       printk("SJCD: sjcd=0x%x: ", sjcd_base);
-#endif
-
-       if (register_blkdev(MAJOR_NR, "sjcd"))
-               return -EIO;
-
-       sjcd_queue = blk_init_queue(do_sjcd_request, &sjcd_lock);
-       if (!sjcd_queue)
-               goto out0;
-
-       blk_queue_hardsect_size(sjcd_queue, 2048);
-
-       sjcd_disk = alloc_disk(1);
-       if (!sjcd_disk) {
-               printk(KERN_ERR "SJCD: can't allocate disk");
-               goto out1;
-       }
-       sjcd_disk->major = MAJOR_NR,
-       sjcd_disk->first_minor = 0,
-       sjcd_disk->fops = &sjcd_fops,
-       sprintf(sjcd_disk->disk_name, "sjcd");
-
-       if (!request_region(sjcd_base, 4,"sjcd")) {
-               printk
-                   ("SJCD: Init failed, I/O port (%X) is already in use\n",
-                    sjcd_base);
-               goto out2;
-       }
-
-       /*
-        * Check for card. Since we are booting now, we can't use standard
-        * wait algorithm.
-        */
-       printk(KERN_INFO "SJCD: Resetting: ");
-       sjcd_send_cmd(SCMD_RESET);
-       for (i = 1000; i > 0 && !sjcd_status_valid; --i) {
-               unsigned long timer;
-
-               /*
-                * Wait 10ms approx.
-                */
-               for (timer = jiffies; time_before_eq(jiffies, timer););
-               if ((i % 100) == 0)
-                       printk(".");
-               (void) sjcd_check_status();
-       }
-       if (i == 0 || sjcd_command_failed) {
-               printk(" reset failed, no drive found.\n");
-               goto out3;
-       } else
-               printk("\n");
-
-       /*
-        * Get and print out cdrom version.
-        */
-       printk(KERN_INFO "SJCD: Getting version: ");
-       sjcd_send_cmd(SCMD_GET_VERSION);
-       for (i = 1000; i > 0 && !sjcd_status_valid; --i) {
-               unsigned long timer;
-
-               /*
-                * Wait 10ms approx.
-                */
-               for (timer = jiffies; time_before_eq(jiffies, timer););
-               if ((i % 100) == 0)
-                       printk(".");
-               (void) sjcd_check_status();
-       }
-       if (i == 0 || sjcd_command_failed) {
-               printk(" get version failed, no drive found.\n");
-               goto out3;
-       }
-
-       if (sjcd_load_response(&sjcd_version, sizeof(sjcd_version)) == 0) {
-               printk(" %1x.%02x\n", (int) sjcd_version.major,
-                      (int) sjcd_version.minor);
-       } else {
-               printk(" read version failed, no drive found.\n");
-               goto out3;
-       }
-
-       /*
-        * Check and print out the tray state. (if it is needed?).
-        */
-       if (!sjcd_status_valid) {
-               printk(KERN_INFO "SJCD: Getting status: ");
-               sjcd_send_cmd(SCMD_GET_STATUS);
-               for (i = 1000; i > 0 && !sjcd_status_valid; --i) {
-                       unsigned long timer;
-
-                       /*
-                        * Wait 10ms approx.
-                        */
-                       for (timer = jiffies;
-                            time_before_eq(jiffies, timer););
-                       if ((i % 100) == 0)
-                               printk(".");
-                       (void) sjcd_check_status();
-               }
-               if (i == 0 || sjcd_command_failed) {
-                       printk(" get status failed, no drive found.\n");
-                       goto out3;
-               } else
-                       printk("\n");
-       }
-
-       printk(KERN_INFO "SJCD: Status: port=0x%x.\n", sjcd_base);
-       sjcd_disk->queue = sjcd_queue;
-       add_disk(sjcd_disk);
-
-       sjcd_present++;
-       return (0);
-out3:
-       release_region(sjcd_base, 4);
-out2:
-       put_disk(sjcd_disk);
-out1:
-       blk_cleanup_queue(sjcd_queue);
-out0:
-       if ((unregister_blkdev(MAJOR_NR, "sjcd") == -EINVAL))
-               printk("SJCD: cannot unregister device.\n");
-       return (-EIO);
-}
-
-static void __exit sjcd_exit(void)
-{
-       del_gendisk(sjcd_disk);
-       put_disk(sjcd_disk);
-       release_region(sjcd_base, 4);
-       blk_cleanup_queue(sjcd_queue);
-       if ((unregister_blkdev(MAJOR_NR, "sjcd") == -EINVAL))
-               printk("SJCD: cannot unregister device.\n");
-       printk(KERN_INFO "SJCD: module: removed.\n");
-}
-
-module_init(sjcd_init);
-module_exit(sjcd_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_BLOCKDEV_MAJOR(SANYO_CDROM_MAJOR);
diff --git a/drivers/cdrom/sjcd.h b/drivers/cdrom/sjcd.h
deleted file mode 100644 (file)
index 0aa5e71..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Definitions for a Sanyo CD-ROM interface.
- *
- *   Copyright (C) 1995  Vadim V. Model
- *                                       model@cecmow.enet.dec.com
- *                                       vadim@rbrf.msk.su
- *                                       vadim@ipsun.ras.ru
- *                       Eric van der Maarel
- *                                       H.T.M.v.d.Maarel@marin.nl
- *
- *  This information is based on mcd.c from M. Harriss and sjcd102.lst from
- *  E. Moenkeberg.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __SJCD_H__
-#define __SJCD_H__
-
-/*
- * Change this to set the I/O port address as default. More flexibility
- * come with setup implementation.
- */
-#define SJCD_BASE_ADDR      0x340
-
-/*
- * Change this to set the irq as default. Really SANYO do not use interrupts
- * at all.
- */
-#define SJCD_INTR_NR        0
-
-/*
- * Change this to set the dma as default value. really SANYO does not use
- * direct memory access at all.
- */
-#define SJCD_DMA_NR         0
-
-/*
- * Macros which allow us to find out the status of the drive.
- */
-#define SJCD_STATUS_AVAILABLE( x ) (((x)&0x02)==0)
-#define SJCD_DATA_AVAILABLE( x )   (((x)&0x01)==0)
-
-/*
- * Port access macro. Three ports are available: S-data port (command port),
- * status port (read only) and D-data port (read only).
- */
-#define SJCDPORT( x )       ( sjcd_base + ( x ) )
-#define SJCD_STATUS_PORT    SJCDPORT( 1 )
-#define SJCD_S_DATA_PORT    SJCDPORT( 0 )
-#define SJCD_COMMAND_PORT   SJCDPORT( 0 )
-#define SJCD_D_DATA_PORT    SJCDPORT( 2 )
-
-/*
- * Drive info bits. Drive info available as first (mandatory) byte of
- * command completion status.
- */
-#define SST_NOT_READY       0x10        /* no disk in the drive (???) */
-#define SST_MEDIA_CHANGED   0x20        /* disk is changed */
-#define SST_DOOR_OPENED     0x40        /* door is open */
-
-/* commands */
-
-#define SCMD_EJECT_TRAY     0xD0        /* eject tray if not locked */
-#define SCMD_LOCK_TRAY      0xD2        /* lock tray when in */
-#define SCMD_UNLOCK_TRAY    0xD4        /* unlock tray when in */
-#define SCMD_CLOSE_TRAY     0xD6        /* load tray in */
-
-#define SCMD_RESET          0xFA        /* soft reset */
-#define SCMD_GET_STATUS     0x80
-#define SCMD_GET_VERSION    0xCC
-
-#define SCMD_DATA_READ      0xA0        /* are the same, depend on mode&args */
-#define SCMD_SEEK           0xA0
-#define SCMD_PLAY           0xA0
-
-#define SCMD_GET_QINFO      0xA8
-
-#define SCMD_SET_MODE       0xC4
-#define SCMD_MODE_PLAY      0xE0
-#define SCMD_MODE_COOKED    (0xF8 & ~0x20)
-#define SCMD_MODE_RAW       0xF9
-#define SCMD_MODE_x20_BIT   0x20        /* What is it for ? */
-
-#define SCMD_SET_VOLUME     0xAE
-#define SCMD_PAUSE          0xE0
-#define SCMD_STOP           0xE0
-
-#define SCMD_GET_DISK_INFO  0xAA
-
-/*
- * Some standard arguments for SCMD_GET_DISK_INFO.
- */
-#define SCMD_GET_1_TRACK    0xA0    /* get the first track information */
-#define SCMD_GET_L_TRACK    0xA1    /* get the last track information */
-#define SCMD_GET_D_SIZE     0xA2    /* get the whole disk information */
-
-/*
- * Borrowed from hd.c. Allows to optimize multiple port read commands.
- */
-#define S_READ_DATA( port, buf, nr )      insb( port, buf, nr )
-
-/*
- * We assume that there are no audio disks with TOC length more than this
- * number (I personally have never seen disks with more than 20 fragments).
- */
-#define SJCD_MAX_TRACKS                100
-
-struct msf {
-  unsigned char   min;
-  unsigned char   sec;
-  unsigned char   frame;
-};
-
-struct sjcd_hw_disk_info {
-  unsigned char track_control;
-  unsigned char track_no;
-  unsigned char x, y, z;
-  union {
-    unsigned char track_no;
-    struct msf track_msf;
-  } un;
-};
-
-struct sjcd_hw_qinfo {
-  unsigned char track_control;
-  unsigned char track_no;
-  unsigned char x;
-  struct msf rel;
-  struct msf abs;
-};
-
-struct sjcd_play_msf {
-  struct msf  start;
-  struct msf  end;
-};
-
-struct sjcd_disk_info {
-  unsigned char   first;
-  unsigned char   last;
-  struct msf      disk_length;
-  struct msf      first_track;
-};
-
-struct sjcd_toc {
-  unsigned char   ctrl_addr;
-  unsigned char   track;
-  unsigned char   point_index;
-  struct msf      track_time;
-  struct msf      disk_time;
-};
-
-#if defined( SJCD_GATHER_STAT )
-
-struct sjcd_stat {
-  int ticks;
-  int tticks[ 8 ];
-  int idle_ticks;
-  int start_ticks;
-  int mode_ticks;
-  int read_ticks;
-  int data_ticks;
-  int stop_ticks;
-  int stopping_ticks;
-};
-
-#endif
-
-#endif
diff --git a/drivers/cdrom/sonycd535.c b/drivers/cdrom/sonycd535.c
deleted file mode 100644 (file)
index f77ada9..0000000
+++ /dev/null
@@ -1,1689 +0,0 @@
-/*
- * Sony CDU-535 interface device driver
- *
- * This is a modified version of the CDU-31A device driver (see below).
- * Changes were made using documentation for the CDU-531 (which Sony
- * assures me is very similar to the 535) and partial disassembly of the
- * DOS driver.  I used Minyard's driver and replaced the CDU-31A
- * commands with the CDU-531 commands.  This was complicated by a different
- * interface protocol with the drive.  The driver is still polled.
- *
- * Data transfer rate is about 110 Kb/sec, theoretical maximum is 150 Kb/sec.
- * I tried polling without the sony_sleep during the data transfers but
- * it did not speed things up any.
- *
- * 1993-05-23 (rgj) changed the major number to 21 to get rid of conflict
- * with CDU-31A driver.  This is the also the number from the Linux
- * Device Driver Registry for the Sony Drive.  Hope nobody else is using it.
- *
- * 1993-08-29 (rgj) remove the configuring of the interface board address
- * from the top level configuration, you have to modify it in this file.
- *
- * 1995-01-26 Made module-capable (Joel Katz <Stimpson@Panix.COM>)
- *
- * 1995-05-20
- *  Modified to support CDU-510/515 series
- *      (Claudio Porfiri<C.Porfiri@nisms.tei.ericsson.se>)
- *  Fixed to report verify_area() failures
- *      (Heiko Eissfeldt <heiko@colossus.escape.de>)
- *
- * 1995-06-01
- *  More changes to support CDU-510/515 series
- *      (Claudio Porfiri<C.Porfiri@nisms.tei.ericsson.se>)
- *
- * November 1999 -- Make kernel-parameter implementation work with 2.3.x 
- *                 Removed init_module & cleanup_module in favor of 
- *                 module_init & module_exit.
- *                  Torben Mathiasen <tmm@image.dk>
- *
- * September 2003 - Fix SMP support by removing cli/sti calls.
- *                  Using spinlocks with a wait_queue instead.
- *                  Felipe Damasio <felipewd@terra.com.br>
- *
- * Things to do:
- *  - handle errors and status better, put everything into a single word
- *  - use interrupts (code mostly there, but a big hole still missing)
- *  - handle multi-session CDs?
- *  - use DMA?
- *
- *  Known Bugs:
- *  -
- *
- *   Ken Pizzini (ken@halcyon.com)
- *
- * Original by:
- *   Ron Jeppesen (ronj.an@site007.saic.com)
- *
- *
- *------------------------------------------------------------------------
- * Sony CDROM interface device driver.
- *
- * Corey Minyard (minyard@wf-rch.cirr.com) (CDU-535 complaints to Ken above)
- *
- * Colossians 3:17
- *
- * The Sony interface device driver handles Sony interface CDROM
- * drives and provides a complete block-level interface as well as an
- * ioctl() interface compatible with the Sun (as specified in
- * include/linux/cdrom.h).  With this interface, CDROMs can be
- * accessed and standard audio CDs can be played back normally.
- *
- * This interface is (unfortunately) a polled interface.  This is
- * because most Sony interfaces are set up with DMA and interrupts
- * disables.  Some (like mine) do not even have the capability to
- * handle interrupts or DMA.  For this reason you will see a bit of
- * the following:
- *
- *   snap = jiffies;
- *   while (jiffies-snap < SONY_JIFFIES_TIMEOUT)
- *   {
- *             if (some_condition())
- *         break;
- *      sony_sleep();
- *   }
- *   if (some_condition not met)
- *   {
- *      return an_error;
- *   }
- *
- * This ugly hack waits for something to happen, sleeping a little
- * between every try.  (The conditional is written so that jiffies
- * wrap-around is handled properly.)
- *
- * One thing about these drives: They talk in MSF (Minute Second Frame) format.
- * There are 75 frames a second, 60 seconds a minute, and up to 75 minutes on a
- * disk.  The funny thing is that these are sent to the drive in BCD, but the
- * interface wants to see them in decimal.  A lot of conversion goes on.
- *
- *  Copyright (C) 1993  Corey Minyard
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You 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/errno.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/hdreg.h>
-#include <linux/genhd.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-
-#define REALLY_SLOW_IO
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-
-#include <linux/cdrom.h>
-
-#define MAJOR_NR CDU535_CDROM_MAJOR
-#include <linux/blkdev.h>
-
-#define sony535_cd_base_io sonycd535 /* for compatible parameter passing with "insmod" */
-#include "sonycd535.h"
-
-/*
- * this is the base address of the interface card for the Sony CDU-535
- * CDROM drive.  If your jumpers are set for an address other than
- * this one (the default), change the following line to the
- * proper address.
- */
-#ifndef CDU535_ADDRESS
-# define CDU535_ADDRESS                        0x340
-#endif
-#ifndef CDU535_INTERRUPT
-# define CDU535_INTERRUPT              0
-#endif
-#ifndef CDU535_HANDLE
-# define CDU535_HANDLE                 "cdu535"
-#endif
-#ifndef CDU535_MESSAGE_NAME
-# define CDU535_MESSAGE_NAME   "Sony CDU-535"
-#endif
-
-#define CDU535_BLOCK_SIZE      2048 
-#ifndef MAX_SPINUP_RETRY
-# define MAX_SPINUP_RETRY              3       /* 1 is sufficient for most drives... */
-#endif
-#ifndef RETRY_FOR_BAD_STATUS
-# define RETRY_FOR_BAD_STATUS  100     /* in 10th of second */
-#endif
-
-#ifndef DEBUG
-# define DEBUG 1
-#endif
-
-/*
- *  SONY535_BUFFER_SIZE determines the size of internal buffer used
- *  by the drive.  It must be at least 2K and the larger the buffer
- *  the better the transfer rate.  It does however take system memory.
- *  On my system I get the following transfer rates using dd to read
- *  10 Mb off /dev/cdrom.
- *
- *    8K buffer      43 Kb/sec
- *   16K buffer      66 Kb/sec
- *   32K buffer      91 Kb/sec
- *   64K buffer     111 Kb/sec
- *  128K buffer     123 Kb/sec
- *  512K buffer     123 Kb/sec
- */
-#define SONY535_BUFFER_SIZE    (64*1024)
-
-/*
- *  if LOCK_DOORS is defined then the eject button is disabled while
- * the device is open.
- */
-#ifndef NO_LOCK_DOORS
-# define LOCK_DOORS
-#endif
-
-static int read_subcode(void);
-static void sony_get_toc(void);
-static int cdu_open(struct inode *inode, struct file *filp);
-static inline unsigned int int_to_bcd(unsigned int val);
-static unsigned int bcd_to_int(unsigned int bcd);
-static int do_sony_cmd(Byte * cmd, int nCmd, Byte status[2],
-                                          Byte * response, int n_response, int ignoreStatusBit7);
-
-/* The base I/O address of the Sony Interface.  This is a variable (not a
-   #define) so it can be easily changed via some future ioctl() */
-static unsigned int sony535_cd_base_io = CDU535_ADDRESS;
-module_param(sony535_cd_base_io, int, 0);
-
-/*
- * The following are I/O addresses of the various registers for the drive.  The
- * comment for the base address also applies here.
- */
-static unsigned short select_unit_reg;
-static unsigned short result_reg;
-static unsigned short command_reg;
-static unsigned short read_status_reg;
-static unsigned short data_reg;
-
-static DEFINE_SPINLOCK(sonycd535_lock); /* queue lock */
-static struct request_queue *sonycd535_queue;
-
-static int initialized;                        /* Has the drive been initialized? */
-static int sony_disc_changed = 1;      /* Has the disk been changed
-                                          since the last check? */
-static int sony_toc_read;              /* Has the table of contents been
-                                          read? */
-static unsigned int sony_buffer_size;  /* Size in bytes of the read-ahead
-                                          buffer. */
-static unsigned int sony_buffer_sectors;       /* Size (in 2048 byte records) of
-                                                  the read-ahead buffer. */
-static unsigned int sony_usage;                /* How many processes have the
-                                          drive open. */
-
-static int sony_first_block = -1;      /* First OS block (512 byte) in
-                                          the read-ahead buffer */
-static int sony_last_block = -1;       /* Last OS block (512 byte) in
-                                          the read-ahead buffer */
-
-static struct s535_sony_toc *sony_toc; /* Points to the table of
-                                          contents. */
-
-static struct s535_sony_subcode *last_sony_subcode;            /* Points to the last
-                                                                  subcode address read */
-static Byte **sony_buffer;             /* Points to the pointers
-                                          to the sector buffers */
-
-static int sony_inuse;                 /* is the drive in use? Only one
-                                          open at a time allowed */
-
-/*
- * The audio status uses the values from read subchannel data as specified
- * in include/linux/cdrom.h.
- */
-static int sony_audio_status = CDROM_AUDIO_NO_STATUS;
-
-/*
- * The following are a hack for pausing and resuming audio play.  The drive
- * does not work as I would expect it, if you stop it then start it again,
- * the drive seeks back to the beginning and starts over.  This holds the
- * position during a pause so a resume can restart it.  It uses the
- * audio status variable above to tell if it is paused.
- *   I just kept the CDU-31A driver behavior rather than using the PAUSE
- * command on the CDU-535.
- */
-static Byte cur_pos_msf[3];
-static Byte final_pos_msf[3];
-
-/* What IRQ is the drive using?  0 if none. */
-static int sony535_irq_used = CDU535_INTERRUPT;
-
-/* The interrupt handler will wake this queue up when it gets an interrupt. */
-static DECLARE_WAIT_QUEUE_HEAD(cdu535_irq_wait);
-
-
-/*
- * This routine returns 1 if the disk has been changed since the last
- * check or 0 if it hasn't.  Setting flag to 0 resets the changed flag.
- */
-static int
-cdu535_check_media_change(struct gendisk *disk)
-{
-       /* if driver is not initialized, always return 0 */
-       int retval = initialized ? sony_disc_changed : 0;
-       sony_disc_changed = 0;
-       return retval;
-}
-
-static inline void
-enable_interrupts(void)
-{
-#ifdef USE_IRQ
-       /*
-        * This code was taken from cdu31a.c; it will not
-        * directly work for the cdu535 as written...
-        */
-       curr_control_reg |= ( SONY_ATTN_INT_EN_BIT
-                                               | SONY_RES_RDY_INT_EN_BIT
-                                               | SONY_DATA_RDY_INT_EN_BIT);
-       outb(curr_control_reg, sony_cd_control_reg);
-#endif
-}
-
-static inline void
-disable_interrupts(void)
-{
-#ifdef USE_IRQ
-       /*
-        * This code was taken from cdu31a.c; it will not
-        * directly work for the cdu535 as written...
-        */
-       curr_control_reg &= ~(SONY_ATTN_INT_EN_BIT
-                                               | SONY_RES_RDY_INT_EN_BIT
-                                               | SONY_DATA_RDY_INT_EN_BIT);
-       outb(curr_control_reg, sony_cd_control_reg);
-#endif
-}
-
-static irqreturn_t
-cdu535_interrupt(int irq, void *dev_id)
-{
-       disable_interrupts();
-       if (waitqueue_active(&cdu535_irq_wait)) {
-               wake_up(&cdu535_irq_wait);
-               return IRQ_HANDLED;
-       }
-       printk(CDU535_MESSAGE_NAME
-                       ": Got an interrupt but nothing was waiting\n");
-       return IRQ_NONE;
-}
-
-
-/*
- * Wait a little while.
- */
-static inline void
-sony_sleep(void)
-{
-       if (sony535_irq_used <= 0) {    /* poll */
-               yield();
-       } else {        /* Interrupt driven */
-               DEFINE_WAIT(wait);
-               
-               spin_lock_irq(&sonycd535_lock);
-               enable_interrupts();
-               prepare_to_wait(&cdu535_irq_wait, &wait, TASK_INTERRUPTIBLE);
-               spin_unlock_irq(&sonycd535_lock);
-               schedule();
-               finish_wait(&cdu535_irq_wait, &wait);
-       }
-}
-
-/*------------------start of SONY CDU535 very specific ---------------------*/
-
-/****************************************************************************
- * void select_unit( int unit_no )
- *
- *  Select the specified unit (0-3) so that subsequent commands reference it
- ****************************************************************************/
-static void
-select_unit(int unit_no)
-{
-       unsigned int select_mask = ~(1 << unit_no);
-       outb(select_mask, select_unit_reg);
-}
-
-/***************************************************************************
- * int read_result_reg( Byte *data_ptr )
- *
- *  Read a result byte from the Sony CDU controller, store in location pointed
- * to by data_ptr.  Return zero on success, TIME_OUT if we did not receive
- * data.
- ***************************************************************************/
-static int
-read_result_reg(Byte *data_ptr)
-{
-       unsigned long snap;
-       int read_status;
-
-       snap = jiffies;
-       while (jiffies-snap < SONY_JIFFIES_TIMEOUT) {
-               read_status = inb(read_status_reg);
-               if ((read_status & SONY535_RESULT_NOT_READY_BIT) == 0) {
-#if DEBUG > 1
-                       printk(CDU535_MESSAGE_NAME
-                                       ": read_result_reg(): readStatReg = 0x%x\n", read_status);
-#endif
-                       *data_ptr = inb(result_reg);
-                       return 0;
-               } else {
-                       sony_sleep();
-               }
-       }
-       printk(CDU535_MESSAGE_NAME " read_result_reg: TIME OUT!\n");
-       return TIME_OUT;
-}
-
-/****************************************************************************
- * int read_exec_status( Byte status[2] )
- *
- *  Read the execution status of the last command and put into status.
- * Handles reading second status word if available.  Returns 0 on success,
- * TIME_OUT on failure.
- ****************************************************************************/
-static int
-read_exec_status(Byte status[2])
-{
-       status[1] = 0;
-       if (read_result_reg(&(status[0])) != 0)
-               return TIME_OUT;
-       if ((status[0] & 0x80) != 0) {  /* byte two follows */
-               if (read_result_reg(&(status[1])) != 0)
-                       return TIME_OUT;
-       }
-#if DEBUG > 1
-       printk(CDU535_MESSAGE_NAME ": read_exec_status: read 0x%x 0x%x\n",
-                       status[0], status[1]);
-#endif
-       return 0;
-}
-
-/****************************************************************************
- * int check_drive_status( void )
- *
- *  Check the current drive status.  Using this before executing a command
- * takes care of the problem of unsolicited drive status-2 messages.
- * Add a check of the audio status if we think the disk is playing.
- ****************************************************************************/
-static int
-check_drive_status(void)
-{
-       Byte status, e_status[2];
-       int  CDD, ATN;
-       Byte cmd;
-
-       select_unit(0);
-       if (sony_audio_status == CDROM_AUDIO_PLAY) {    /* check status */
-               outb(SONY535_REQUEST_AUDIO_STATUS, command_reg);
-               if (read_result_reg(&status) == 0) {
-                       switch (status) {
-                       case 0x0:
-                               break;          /* play in progress */
-                       case 0x1:
-                               break;          /* paused */
-                       case 0x3:               /* audio play completed */
-                       case 0x5:               /* play not requested */
-                               sony_audio_status = CDROM_AUDIO_COMPLETED;
-                               read_subcode();
-                               break;
-                       case 0x4:               /* error during play */
-                               sony_audio_status = CDROM_AUDIO_ERROR;
-                               break;
-                       }
-               }
-       }
-       /* now check drive status */
-       outb(SONY535_REQUEST_DRIVE_STATUS_2, command_reg);
-       if (read_result_reg(&status) != 0)
-               return TIME_OUT;
-
-#if DEBUG > 1
-       printk(CDU535_MESSAGE_NAME ": check_drive_status() got 0x%x\n", status);
-#endif
-
-       if (status == 0)
-               return 0;
-
-       ATN = status & 0xf;
-       CDD = (status >> 4) & 0xf;
-
-       switch (ATN) {
-       case 0x0:
-               break;                                  /* go on to CDD stuff */
-       case SONY535_ATN_BUSY:
-               if (initialized)
-                       printk(CDU535_MESSAGE_NAME " error: drive busy\n");
-               return CD_BUSY;
-       case SONY535_ATN_EJECT_IN_PROGRESS:
-               printk(CDU535_MESSAGE_NAME " error: eject in progress\n");
-               sony_audio_status = CDROM_AUDIO_INVALID;
-               return CD_BUSY;
-       case SONY535_ATN_RESET_OCCURRED:
-       case SONY535_ATN_DISC_CHANGED:
-       case SONY535_ATN_RESET_AND_DISC_CHANGED:
-#if DEBUG > 0
-               printk(CDU535_MESSAGE_NAME " notice: reset occurred or disc changed\n");
-#endif
-               sony_disc_changed = 1;
-               sony_toc_read = 0;
-               sony_audio_status = CDROM_AUDIO_NO_STATUS;
-               sony_first_block = -1;
-               sony_last_block = -1;
-               if (initialized) {
-                       cmd = SONY535_SPIN_UP;
-                       do_sony_cmd(&cmd, 1, e_status, NULL, 0, 0);
-                       sony_get_toc();
-               }
-               return 0;
-       default:
-               printk(CDU535_MESSAGE_NAME " error: drive busy (ATN=0x%x)\n", ATN);
-               return CD_BUSY;
-       }
-       switch (CDD) {                  /* the 531 docs are not helpful in decoding this */
-       case 0x0:                               /* just use the values from the DOS driver */
-       case 0x2:
-       case 0xa:
-               break;                          /* no error */
-       case 0xc:
-               printk(CDU535_MESSAGE_NAME
-                               ": check_drive_status(): CDD = 0xc! Not properly handled!\n");
-               return CD_BUSY;         /* ? */
-       default:
-               return CD_BUSY;
-       }
-       return 0;
-}      /* check_drive_status() */
-
-/*****************************************************************************
- * int do_sony_cmd( Byte *cmd, int n_cmd, Byte status[2],
- *                Byte *response, int n_response, int ignore_status_bit7 )
- *
- *  Generic routine for executing commands.  The command and its parameters
- *  should be placed in the cmd[] array, number of bytes in the command is
- *  stored in nCmd.  The response from the command will be stored in the
- *  response array.  The number of bytes you expect back (excluding status)
- *  should be passed in n_response.  Finally, some
- *  commands set bit 7 of the return status even when there is no second
- *  status byte, on these commands set ignoreStatusBit7 TRUE.
- *    If the command was sent and data received back, then we return 0,
- *  else we return TIME_OUT.  You still have to check the status yourself.
- *    You should call check_drive_status() before calling this routine
- *  so that you do not lose notifications of disk changes, etc.
- ****************************************************************************/
-static int
-do_sony_cmd(Byte * cmd, int n_cmd, Byte status[2],
-                       Byte * response, int n_response, int ignore_status_bit7)
-{
-       int i;
-
-       /* write out the command */
-       for (i = 0; i < n_cmd; i++)
-               outb(cmd[i], command_reg);
-
-       /* read back the status */
-       if (read_result_reg(status) != 0)
-               return TIME_OUT;
-       if (!ignore_status_bit7 && ((status[0] & 0x80) != 0)) {
-               /* get second status byte */
-               if (read_result_reg(status + 1) != 0)
-                       return TIME_OUT;
-       } else {
-               status[1] = 0;
-       }
-#if DEBUG > 2
-       printk(CDU535_MESSAGE_NAME ": do_sony_cmd %x: %x %x\n",
-                       *cmd, status[0], status[1]);
-#endif
-
-       /* do not know about when I should read set of data and when not to */
-       if ((status[0] & ((ignore_status_bit7 ? 0x7f : 0xff) & 0x8f)) != 0)
-               return 0;
-
-       /* else, read in rest of data */
-       for (i = 0; 0 < n_response; n_response--, i++)
-               if (read_result_reg(response + i) != 0)
-                       return TIME_OUT;
-       return 0;
-}      /* do_sony_cmd() */
-
-/**************************************************************************
- * int set_drive_mode( int mode, Byte status[2] )
- *
- *  Set the drive mode to the specified value (mode=0 is audio, mode=e0
- * is mode-1 CDROM
- **************************************************************************/
-static int
-set_drive_mode(int mode, Byte status[2])
-{
-       Byte cmd_buff[2];
-       Byte ret_buff[1];
-
-       cmd_buff[0] = SONY535_SET_DRIVE_MODE;
-       cmd_buff[1] = mode;
-       return do_sony_cmd(cmd_buff, 2, status, ret_buff, 1, 1);
-}
-
-/***************************************************************************
- * int seek_and_read_N_blocks( Byte params[], int n_blocks, Byte status[2],
- *                             Byte *data_buff, int buff_size )
- *
- *  Read n_blocks of data from the CDROM starting at position params[0:2],
- *  number of blocks in stored in params[3:5] -- both these are already
- *  int bcd format.
- *  Transfer the data into the buffer pointed at by data_buff.  buff_size
- *  gives the number of bytes available in the buffer.
- *    The routine returns number of bytes read in if successful, otherwise
- *  it returns one of the standard error returns.
- ***************************************************************************/
-static int
-seek_and_read_N_blocks(Byte params[], int n_blocks, Byte status[2],
-                                          Byte **buff, int buf_size)
-{
-       Byte cmd_buff[7];
-       int  i;
-       int  read_status;
-       unsigned long snap;
-       Byte *data_buff;
-       int  sector_count = 0;
-
-       if (buf_size < CDU535_BLOCK_SIZE * n_blocks)
-               return NO_ROOM;
-
-       set_drive_mode(SONY535_CDROM_DRIVE_MODE, status);
-
-       /* send command to read the data */
-       cmd_buff[0] = SONY535_SEEK_AND_READ_N_BLOCKS_1;
-       for (i = 0; i < 6; i++)
-               cmd_buff[i + 1] = params[i];
-       for (i = 0; i < 7; i++)
-               outb(cmd_buff[i], command_reg);
-
-       /* read back the data one block at a time */
-       while (0 < n_blocks--) {
-               /* wait for data to be ready */
-               int data_valid = 0;
-               snap = jiffies;
-               while (jiffies-snap < SONY_JIFFIES_TIMEOUT) {
-                       read_status = inb(read_status_reg);
-                       if ((read_status & SONY535_RESULT_NOT_READY_BIT) == 0) {
-                               read_exec_status(status);
-                               return BAD_STATUS;
-                       }
-                       if ((read_status & SONY535_DATA_NOT_READY_BIT) == 0) {
-                               /* data is ready, read it */
-                               data_buff = buff[sector_count++];
-                               for (i = 0; i < CDU535_BLOCK_SIZE; i++)
-                                       *data_buff++ = inb(data_reg);   /* unrolling this loop does not seem to help */
-                               data_valid = 1;
-                               break;                  /* exit the timeout loop */
-                       }
-                       sony_sleep();           /* data not ready, sleep a while */
-               }
-               if (!data_valid)
-                       return TIME_OUT;        /* if we reach this stage */
-       }
-
-       /* read all the data, now read the status */
-       if ((i = read_exec_status(status)) != 0)
-               return i;
-       return CDU535_BLOCK_SIZE * sector_count;
-}      /* seek_and_read_N_blocks() */
-
-/****************************************************************************
- * int request_toc_data( Byte status[2], struct s535_sony_toc *toc )
- *
- *  Read in the table of contents data.  Converts all the bcd data
- * into integers in the toc structure.
- ****************************************************************************/
-static int
-request_toc_data(Byte status[2], struct s535_sony_toc *toc)
-{
-       int  to_status;
-       int  i, j, n_tracks, track_no;
-       int  first_track_num, last_track_num;
-       Byte cmd_no = 0xb2;
-       Byte track_address_buffer[5];
-
-       /* read the fixed portion of the table of contents */
-       if ((to_status = do_sony_cmd(&cmd_no, 1, status, (Byte *) toc, 15, 1)) != 0)
-               return to_status;
-
-       /* convert the data into integers so we can use them */
-       first_track_num = bcd_to_int(toc->first_track_num);
-       last_track_num = bcd_to_int(toc->last_track_num);
-       n_tracks = last_track_num - first_track_num + 1;
-
-       /* read each of the track address descriptors */
-       for (i = 0; i < n_tracks; i++) {
-               /* read the descriptor into a temporary buffer */
-               for (j = 0; j < 5; j++) {
-                       if (read_result_reg(track_address_buffer + j) != 0)
-                               return TIME_OUT;
-                       if (j == 1)             /* need to convert from bcd */
-                               track_no = bcd_to_int(track_address_buffer[j]);
-               }
-               /* copy the descriptor to proper location - sonycd.c just fills */
-               memcpy(toc->tracks + i, track_address_buffer, 5);
-       }
-       return 0;
-}      /* request_toc_data() */
-
-/***************************************************************************
- * int spin_up_drive( Byte status[2] )
- *
- *  Spin up the drive (unless it is already spinning).
- ***************************************************************************/
-static int
-spin_up_drive(Byte status[2])
-{
-       Byte cmd;
-
-       /* first see if the drive is already spinning */
-       cmd = SONY535_REQUEST_DRIVE_STATUS_1;
-       if (do_sony_cmd(&cmd, 1, status, NULL, 0, 0) != 0)
-               return TIME_OUT;
-       if ((status[0] & SONY535_STATUS1_NOT_SPINNING) == 0)
-               return 0;       /* it's already spinning */
-
-       /* otherwise, give the spin-up command */
-       cmd = SONY535_SPIN_UP;
-       return do_sony_cmd(&cmd, 1, status, NULL, 0, 0);
-}
-
-/*--------------------end of SONY CDU535 very specific ---------------------*/
-
-/* Convert from an integer 0-99 to BCD */
-static inline unsigned int
-int_to_bcd(unsigned int val)
-{
-       int retval;
-
-       retval = (val / 10) << 4;
-       retval = retval | val % 10;
-       return retval;
-}
-
-
-/* Convert from BCD to an integer from 0-99 */
-static unsigned int
-bcd_to_int(unsigned int bcd)
-{
-       return (((bcd >> 4) & 0x0f) * 10) + (bcd & 0x0f);
-}
-
-
-/*
- * Convert a logical sector value (like the OS would want to use for
- * a block device) to an MSF format.
- */
-static void
-log_to_msf(unsigned int log, Byte *msf)
-{
-       log = log + LOG_START_OFFSET;
-       msf[0] = int_to_bcd(log / 4500);
-       log = log % 4500;
-       msf[1] = int_to_bcd(log / 75);
-       msf[2] = int_to_bcd(log % 75);
-}
-
-
-/*
- * Convert an MSF format to a logical sector.
- */
-static unsigned int
-msf_to_log(Byte *msf)
-{
-       unsigned int log;
-
-
-       log = bcd_to_int(msf[2]);
-       log += bcd_to_int(msf[1]) * 75;
-       log += bcd_to_int(msf[0]) * 4500;
-       log = log - LOG_START_OFFSET;
-
-       return log;
-}
-
-
-/*
- * Take in integer size value and put it into a buffer like
- * the drive would want to see a number-of-sector value.
- */
-static void
-size_to_buf(unsigned int size, Byte *buf)
-{
-       buf[0] = size / 65536;
-       size = size % 65536;
-       buf[1] = size / 256;
-       buf[2] = size % 256;
-}
-
-
-/*
- * The OS calls this to perform a read or write operation to the drive.
- * Write obviously fail.  Reads to a read ahead of sony_buffer_size
- * bytes to help speed operations.  This especially helps since the OS
- * may use 1024 byte blocks and the drive uses 2048 byte blocks.  Since most
- * data access on a CD is done sequentially, this saves a lot of operations.
- */
-static void
-do_cdu535_request(request_queue_t * q)
-{
-       struct request *req;
-       unsigned int read_size;
-       int  block;
-       int  nsect;
-       int  copyoff;
-       int  spin_up_retry;
-       Byte params[10];
-       Byte status[2];
-       Byte cmd[2];
-
-       while (1) {
-               req = elv_next_request(q);
-               if (!req)
-                       return;
-
-               block = req->sector;
-               nsect = req->nr_sectors;
-               if (!blk_fs_request(req)) {
-                       end_request(req, 0);
-                       continue;
-               }
-               if (rq_data_dir(req) == WRITE) {
-                       end_request(req, 0);
-                       continue;
-               }
-               /*
-                * If the block address is invalid or the request goes beyond
-                * the end of the media, return an error.
-                */
-               if (sony_toc->lead_out_start_lba <= (block/4)) {
-                       end_request(req, 0);
-                       return;
-               }
-               if (sony_toc->lead_out_start_lba <= ((block + nsect) / 4)) {
-                       end_request(req, 0);
-                       return;
-               }
-               while (0 < nsect) {
-                       /*
-                        * If the requested sector is not currently in
-                        * the read-ahead buffer, it must be read in.
-                        */
-                       if ((block < sony_first_block) || (sony_last_block < block)) {
-                               sony_first_block = (block / 4) * 4;
-                               log_to_msf(block / 4, params);
-                               
-                               /*
-                                * If the full read-ahead would go beyond the end of the media, trim
-                                * it back to read just till the end of the media.
-                                */
-                               if (sony_toc->lead_out_start_lba <= ((block / 4) + sony_buffer_sectors)) {
-                                       sony_last_block = (sony_toc->lead_out_start_lba * 4) - 1;
-                                       read_size = sony_toc->lead_out_start_lba - (block / 4);
-                               } else {
-                                       sony_last_block = sony_first_block + (sony_buffer_sectors * 4) - 1;
-                                       read_size = sony_buffer_sectors;
-                               }
-                               size_to_buf(read_size, &params[3]);
-                               
-                               /*
-                                * Read the data.  If the drive was not spinning,
-                                * spin it up and try some more.
-                                */
-                               for (spin_up_retry=0 ;; ++spin_up_retry) {
-                                       /* This loop has been modified to support the Sony
-                                        * CDU-510/515 series, thanks to Claudio Porfiri 
-                                        * <C.Porfiri@nisms.tei.ericsson.se>.
-                                        */
-                                       /*
-                                        * This part is to deal with very slow hardware.  We
-                                        * try at most MAX_SPINUP_RETRY times to read the same
-                                        * block.  A check for seek_and_read_N_blocks' result is
-                                        * performed; if the result is wrong, the CDROM's engine
-                                        * is restarted and the operation is tried again.
-                                        */
-                                       /*
-                                        * 1995-06-01: The system got problems when downloading
-                                        * from Slackware CDROM, the problem seems to be:
-                                        * seek_and_read_N_blocks returns BAD_STATUS and we
-                                        * should wait for a while before retrying, so a new
-                                        * part was added to discriminate the return value from
-                                        * seek_and_read_N_blocks for the various cases.
-                                        */
-                                       int readStatus = seek_and_read_N_blocks(params, read_size,
-                                                                               status, sony_buffer, (read_size * CDU535_BLOCK_SIZE));
-                                       if (0 <= readStatus)    /* Good data; common case, placed first */
-                                               break;
-                                       if (readStatus == NO_ROOM || spin_up_retry == MAX_SPINUP_RETRY) {
-                                               /* give up */
-                                               if (readStatus == NO_ROOM)
-                                                       printk(CDU535_MESSAGE_NAME " No room to read from CD\n");
-                                               else
-                                                       printk(CDU535_MESSAGE_NAME " Read error: 0x%.2x\n",
-                                                              status[0]);
-                                               sony_first_block = -1;
-                                               sony_last_block = -1;
-                                               end_request(req, 0);
-                                               return;
-                                       }
-                                       if (readStatus == BAD_STATUS) {
-                                               /* Sleep for a while, then retry */
-                                               set_current_state(TASK_INTERRUPTIBLE);
-                                               spin_unlock_irq(&sonycd535_lock);
-                                               schedule_timeout(RETRY_FOR_BAD_STATUS*HZ/10);
-                                               spin_lock_irq(&sonycd535_lock);
-                                       }
-#if DEBUG > 0
-                                       printk(CDU535_MESSAGE_NAME
-                                              " debug: calling spin up when reading data!\n");
-#endif
-                                       cmd[0] = SONY535_SPIN_UP;
-                                       do_sony_cmd(cmd, 1, status, NULL, 0, 0);
-                               }
-                       }
-                       /*
-                        * The data is in memory now, copy it to the buffer and advance to the
-                        * next block to read.
-                        */
-                       copyoff = block - sony_first_block;
-                       memcpy(req->buffer,
-                              sony_buffer[copyoff / 4] + 512 * (copyoff % 4), 512);
-                       
-                       block += 1;
-                       nsect -= 1;
-                       req->buffer += 512;
-               }
-
-               end_request(req, 1);
-       }
-}
-
-/*
- * Read the table of contents from the drive and set sony_toc_read if
- * successful.
- */
-static void
-sony_get_toc(void)
-{
-       Byte status[2];
-       if (!sony_toc_read) {
-               /* do not call check_drive_status() from here since it can call this routine */
-               if (request_toc_data(status, sony_toc) < 0)
-                       return;
-               sony_toc->lead_out_start_lba = msf_to_log(sony_toc->lead_out_start_msf);
-               sony_toc_read = 1;
-       }
-}
-
-
-/*
- * Search for a specific track in the table of contents.  track is
- * passed in bcd format
- */
-static int
-find_track(int track)
-{
-       int i;
-       int num_tracks;
-
-
-       num_tracks = bcd_to_int(sony_toc->last_track_num) -
-               bcd_to_int(sony_toc->first_track_num) + 1;
-       for (i = 0; i < num_tracks; i++) {
-               if (sony_toc->tracks[i].track == track) {
-                       return i;
-               }
-       }
-
-       return -1;
-}
-
-/*
- * Read the subcode and put it int last_sony_subcode for future use.
- */
-static int
-read_subcode(void)
-{
-       Byte cmd = SONY535_REQUEST_SUB_Q_DATA;
-       Byte status[2];
-       int  dsc_status;
-
-       if (check_drive_status() != 0)
-               return -EIO;
-
-       if ((dsc_status = do_sony_cmd(&cmd, 1, status, (Byte *) last_sony_subcode,
-                                                          sizeof(struct s535_sony_subcode), 1)) != 0) {
-               printk(CDU535_MESSAGE_NAME " error 0x%.2x, %d (read_subcode)\n",
-                               status[0], dsc_status);
-               return -EIO;
-       }
-       return 0;
-}
-
-
-/*
- * Get the subchannel info like the CDROMSUBCHNL command wants to see it.  If
- * the drive is playing, the subchannel needs to be read (since it would be
- * changing).  If the drive is paused or completed, the subcode information has
- * already been stored, just use that.  The ioctl call wants things in decimal
- * (not BCD), so all the conversions are done.
- */
-static int
-sony_get_subchnl_info(void __user *arg)
-{
-       struct cdrom_subchnl schi;
-
-       /* Get attention stuff */
-       if (check_drive_status() != 0)
-               return -EIO;
-
-       sony_get_toc();
-       if (!sony_toc_read) {
-               return -EIO;
-       }
-       if (copy_from_user(&schi, arg, sizeof schi))
-               return -EFAULT;
-
-       switch (sony_audio_status) {
-       case CDROM_AUDIO_PLAY:
-               if (read_subcode() < 0) {
-                       return -EIO;
-               }
-               break;
-
-       case CDROM_AUDIO_PAUSED:
-       case CDROM_AUDIO_COMPLETED:
-               break;
-
-       case CDROM_AUDIO_NO_STATUS:
-               schi.cdsc_audiostatus = sony_audio_status;
-               if (copy_to_user(arg, &schi, sizeof schi))
-                       return -EFAULT;
-               return 0;
-               break;
-
-       case CDROM_AUDIO_INVALID:
-       case CDROM_AUDIO_ERROR:
-       default:
-               return -EIO;
-       }
-
-       schi.cdsc_audiostatus = sony_audio_status;
-       schi.cdsc_adr = last_sony_subcode->address;
-       schi.cdsc_ctrl = last_sony_subcode->control;
-       schi.cdsc_trk = bcd_to_int(last_sony_subcode->track_num);
-       schi.cdsc_ind = bcd_to_int(last_sony_subcode->index_num);
-       if (schi.cdsc_format == CDROM_MSF) {
-               schi.cdsc_absaddr.msf.minute = bcd_to_int(last_sony_subcode->abs_msf[0]);
-               schi.cdsc_absaddr.msf.second = bcd_to_int(last_sony_subcode->abs_msf[1]);
-               schi.cdsc_absaddr.msf.frame = bcd_to_int(last_sony_subcode->abs_msf[2]);
-
-               schi.cdsc_reladdr.msf.minute = bcd_to_int(last_sony_subcode->rel_msf[0]);
-               schi.cdsc_reladdr.msf.second = bcd_to_int(last_sony_subcode->rel_msf[1]);
-               schi.cdsc_reladdr.msf.frame = bcd_to_int(last_sony_subcode->rel_msf[2]);
-       } else if (schi.cdsc_format == CDROM_LBA) {
-               schi.cdsc_absaddr.lba = msf_to_log(last_sony_subcode->abs_msf);
-               schi.cdsc_reladdr.lba = msf_to_log(last_sony_subcode->rel_msf);
-       }
-       return copy_to_user(arg, &schi, sizeof schi) ? -EFAULT : 0;
-}
-
-
-/*
- * The big ugly ioctl handler.
- */
-static int
-cdu_ioctl(struct inode *inode,
-                 struct file *file,
-                 unsigned int cmd,
-                 unsigned long arg)
-{
-       Byte status[2];
-       Byte cmd_buff[10], params[10];
-       int  i;
-       int  dsc_status;
-       void __user *argp = (void __user *)arg;
-
-       if (check_drive_status() != 0)
-               return -EIO;
-
-       switch (cmd) {
-       case CDROMSTART:                        /* Spin up the drive */
-               if (spin_up_drive(status) < 0) {
-                       printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMSTART)\n",
-                                       status[0]);
-                       return -EIO;
-               }
-               return 0;
-               break;
-
-       case CDROMSTOP:                 /* Spin down the drive */
-               cmd_buff[0] = SONY535_HOLD;
-               do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
-
-               /*
-                * Spin the drive down, ignoring the error if the disk was
-                * already not spinning.
-                */
-               sony_audio_status = CDROM_AUDIO_NO_STATUS;
-               cmd_buff[0] = SONY535_SPIN_DOWN;
-               dsc_status = do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
-               if (((dsc_status < 0) && (dsc_status != BAD_STATUS)) ||
-                       ((status[0] & ~(SONY535_STATUS1_NOT_SPINNING)) != 0)) {
-                       printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMSTOP)\n",
-                                       status[0]);
-                       return -EIO;
-               }
-               return 0;
-               break;
-
-       case CDROMPAUSE:                        /* Pause the drive */
-               cmd_buff[0] = SONY535_HOLD;             /* CDU-31 driver uses AUDIO_STOP, not pause */
-               if (do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0) != 0) {
-                       printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMPAUSE)\n",
-                                       status[0]);
-                       return -EIO;
-               }
-               /* Get the current position and save it for resuming */
-               if (read_subcode() < 0) {
-                       return -EIO;
-               }
-               cur_pos_msf[0] = last_sony_subcode->abs_msf[0];
-               cur_pos_msf[1] = last_sony_subcode->abs_msf[1];
-               cur_pos_msf[2] = last_sony_subcode->abs_msf[2];
-               sony_audio_status = CDROM_AUDIO_PAUSED;
-               return 0;
-               break;
-
-       case CDROMRESUME:                       /* Start the drive after being paused */
-               set_drive_mode(SONY535_AUDIO_DRIVE_MODE, status);
-
-               if (sony_audio_status != CDROM_AUDIO_PAUSED) {
-                       return -EINVAL;
-               }
-               spin_up_drive(status);
-
-               /* Start the drive at the saved position. */
-               cmd_buff[0] = SONY535_PLAY_AUDIO;
-               cmd_buff[1] = 0;                /* play back starting at this address */
-               cmd_buff[2] = cur_pos_msf[0];
-               cmd_buff[3] = cur_pos_msf[1];
-               cmd_buff[4] = cur_pos_msf[2];
-               cmd_buff[5] = SONY535_PLAY_AUDIO;
-               cmd_buff[6] = 2;                /* set ending address */
-               cmd_buff[7] = final_pos_msf[0];
-               cmd_buff[8] = final_pos_msf[1];
-               cmd_buff[9] = final_pos_msf[2];
-               if ((do_sony_cmd(cmd_buff, 5, status, NULL, 0, 0) != 0) ||
-                       (do_sony_cmd(cmd_buff + 5, 5, status, NULL, 0, 0) != 0)) {
-                       printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMRESUME)\n",
-                                       status[0]);
-                       return -EIO;
-               }
-               sony_audio_status = CDROM_AUDIO_PLAY;
-               return 0;
-               break;
-
-       case CDROMPLAYMSF:                      /* Play starting at the given MSF address. */
-               if (copy_from_user(params, argp, 6))
-                       return -EFAULT;
-               spin_up_drive(status);
-               set_drive_mode(SONY535_AUDIO_DRIVE_MODE, status);
-
-               /* The parameters are given in int, must be converted */
-               for (i = 0; i < 3; i++) {
-                       cmd_buff[2 + i] = int_to_bcd(params[i]);
-                       cmd_buff[7 + i] = int_to_bcd(params[i + 3]);
-               }
-               cmd_buff[0] = SONY535_PLAY_AUDIO;
-               cmd_buff[1] = 0;                /* play back starting at this address */
-               /* cmd_buff[2-4] are filled in for loop above */
-               cmd_buff[5] = SONY535_PLAY_AUDIO;
-               cmd_buff[6] = 2;                /* set ending address */
-               /* cmd_buff[7-9] are filled in for loop above */
-               if ((do_sony_cmd(cmd_buff, 5, status, NULL, 0, 0) != 0) ||
-                       (do_sony_cmd(cmd_buff + 5, 5, status, NULL, 0, 0) != 0)) {
-                       printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMPLAYMSF)\n",
-                                       status[0]);
-                       return -EIO;
-               }
-               /* Save the final position for pauses and resumes */
-               final_pos_msf[0] = cmd_buff[7];
-               final_pos_msf[1] = cmd_buff[8];
-               final_pos_msf[2] = cmd_buff[9];
-               sony_audio_status = CDROM_AUDIO_PLAY;
-               return 0;
-               break;
-
-       case CDROMREADTOCHDR:           /* Read the table of contents header */
-               {
-                       struct cdrom_tochdr __user *hdr = argp;
-                       struct cdrom_tochdr loc_hdr;
-
-                       sony_get_toc();
-                       if (!sony_toc_read)
-                               return -EIO;
-                       loc_hdr.cdth_trk0 = bcd_to_int(sony_toc->first_track_num);
-                       loc_hdr.cdth_trk1 = bcd_to_int(sony_toc->last_track_num);
-                       if (copy_to_user(hdr, &loc_hdr, sizeof *hdr))
-                               return -EFAULT;
-               }
-               return 0;
-               break;
-
-       case CDROMREADTOCENTRY: /* Read a given table of contents entry */
-               {
-                       struct cdrom_tocentry __user *entry = argp;
-                       struct cdrom_tocentry loc_entry;
-                       int  track_idx;
-                       Byte *msf_val = NULL;
-
-                       sony_get_toc();
-                       if (!sony_toc_read) {
-                               return -EIO;
-                       }
-
-                       if (copy_from_user(&loc_entry, entry, sizeof loc_entry))
-                               return -EFAULT;
-
-                       /* Lead out is handled separately since it is special. */
-                       if (loc_entry.cdte_track == CDROM_LEADOUT) {
-                               loc_entry.cdte_adr = 0 /*sony_toc->address2 */ ;
-                               loc_entry.cdte_ctrl = sony_toc->control2;
-                               msf_val = sony_toc->lead_out_start_msf;
-                       } else {
-                               track_idx = find_track(int_to_bcd(loc_entry.cdte_track));
-                               if (track_idx < 0)
-                                       return -EINVAL;
-                               loc_entry.cdte_adr = 0 /*sony_toc->tracks[track_idx].address */ ;
-                               loc_entry.cdte_ctrl = sony_toc->tracks[track_idx].control;
-                               msf_val = sony_toc->tracks[track_idx].track_start_msf;
-                       }
-
-                       /* Logical buffer address or MSF format requested? */
-                       if (loc_entry.cdte_format == CDROM_LBA) {
-                               loc_entry.cdte_addr.lba = msf_to_log(msf_val);
-                       } else if (loc_entry.cdte_format == CDROM_MSF) {
-                               loc_entry.cdte_addr.msf.minute = bcd_to_int(*msf_val);
-                               loc_entry.cdte_addr.msf.second = bcd_to_int(*(msf_val + 1));
-                               loc_entry.cdte_addr.msf.frame = bcd_to_int(*(msf_val + 2));
-                       }
-                       if (copy_to_user(entry, &loc_entry, sizeof *entry))
-                               return -EFAULT;
-               }
-               return 0;
-               break;
-
-       case CDROMPLAYTRKIND:           /* Play a track.  This currently ignores index. */
-               {
-                       struct cdrom_ti ti;
-                       int track_idx;
-
-                       sony_get_toc();
-                       if (!sony_toc_read)
-                               return -EIO;
-
-                       if (copy_from_user(&ti, argp, sizeof ti))
-                               return -EFAULT;
-                       if ((ti.cdti_trk0 < sony_toc->first_track_num)
-                               || (sony_toc->last_track_num < ti.cdti_trk0)
-                               || (ti.cdti_trk1 < ti.cdti_trk0)) {
-                               return -EINVAL;
-                       }
-                       track_idx = find_track(int_to_bcd(ti.cdti_trk0));
-                       if (track_idx < 0)
-                               return -EINVAL;
-                       params[1] = sony_toc->tracks[track_idx].track_start_msf[0];
-                       params[2] = sony_toc->tracks[track_idx].track_start_msf[1];
-                       params[3] = sony_toc->tracks[track_idx].track_start_msf[2];
-                       /*
-                        * If we want to stop after the last track, use the lead-out
-                        * MSF to do that.
-                        */
-                       if (bcd_to_int(sony_toc->last_track_num) <= ti.cdti_trk1) {
-                               log_to_msf(msf_to_log(sony_toc->lead_out_start_msf) - 1,
-                                                  &(params[4]));
-                       } else {
-                               track_idx = find_track(int_to_bcd(ti.cdti_trk1 + 1));
-                               if (track_idx < 0)
-                                       return -EINVAL;
-                               log_to_msf(msf_to_log(sony_toc->tracks[track_idx].track_start_msf) - 1,
-                                                  &(params[4]));
-                       }
-                       params[0] = 0x03;
-
-                       spin_up_drive(status);
-
-                       set_drive_mode(SONY535_AUDIO_DRIVE_MODE, status);
-
-                       /* Start the drive at the saved position. */
-                       cmd_buff[0] = SONY535_PLAY_AUDIO;
-                       cmd_buff[1] = 0;        /* play back starting at this address */
-                       cmd_buff[2] = params[1];
-                       cmd_buff[3] = params[2];
-                       cmd_buff[4] = params[3];
-                       cmd_buff[5] = SONY535_PLAY_AUDIO;
-                       cmd_buff[6] = 2;        /* set ending address */
-                       cmd_buff[7] = params[4];
-                       cmd_buff[8] = params[5];
-                       cmd_buff[9] = params[6];
-                       if ((do_sony_cmd(cmd_buff, 5, status, NULL, 0, 0) != 0) ||
-                               (do_sony_cmd(cmd_buff + 5, 5, status, NULL, 0, 0) != 0)) {
-                               printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMPLAYTRKIND)\n",
-                                               status[0]);
-                               printk("... Params: %x %x %x %x %x %x %x\n",
-                                               params[0], params[1], params[2],
-                                               params[3], params[4], params[5], params[6]);
-                               return -EIO;
-                       }
-                       /* Save the final position for pauses and resumes */
-                       final_pos_msf[0] = params[4];
-                       final_pos_msf[1] = params[5];
-                       final_pos_msf[2] = params[6];
-                       sony_audio_status = CDROM_AUDIO_PLAY;
-                       return 0;
-               }
-
-       case CDROMSUBCHNL:                      /* Get subchannel info */
-               return sony_get_subchnl_info(argp);
-
-       case CDROMVOLCTRL:                      /* Volume control.  What volume does this change, anyway? */
-               {
-                       struct cdrom_volctrl volctrl;
-
-                       if (copy_from_user(&volctrl, argp, sizeof volctrl))
-                               return -EFAULT;
-                       cmd_buff[0] = SONY535_SET_VOLUME;
-                       cmd_buff[1] = volctrl.channel0;
-                       cmd_buff[2] = volctrl.channel1;
-                       if (do_sony_cmd(cmd_buff, 3, status, NULL, 0, 0) != 0) {
-                               printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMVOLCTRL)\n",
-                                               status[0]);
-                               return -EIO;
-                       }
-               }
-               return 0;
-
-       case CDROMEJECT:                        /* Eject the drive */
-               cmd_buff[0] = SONY535_STOP;
-               do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
-               cmd_buff[0] = SONY535_SPIN_DOWN;
-               do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
-
-               sony_audio_status = CDROM_AUDIO_INVALID;
-               cmd_buff[0] = SONY535_EJECT_CADDY;
-               if (do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0) != 0) {
-                       printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMEJECT)\n",
-                                       status[0]);
-                       return -EIO;
-               }
-               return 0;
-               break;
-
-       default:
-               return -EINVAL;
-       }
-}
-
-
-/*
- * Open the drive for operations.  Spin the drive up and read the table of
- * contents if these have not already been done.
- */
-static int
-cdu_open(struct inode *inode,
-                struct file *filp)
-{
-       Byte status[2], cmd_buff[2];
-
-       if (sony_inuse)
-               return -EBUSY;
-       if (check_drive_status() != 0)
-               return -EIO;
-       sony_inuse = 1;
-
-       if (spin_up_drive(status) != 0) {
-               printk(CDU535_MESSAGE_NAME " error 0x%.2x (cdu_open, spin up)\n",
-                               status[0]);
-               sony_inuse = 0;
-               return -EIO;
-       }
-       sony_get_toc();
-       if (!sony_toc_read) {
-               cmd_buff[0] = SONY535_SPIN_DOWN;
-               do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
-               sony_inuse = 0;
-               return -EIO;
-       }
-       check_disk_change(inode->i_bdev);
-       sony_usage++;
-
-#ifdef LOCK_DOORS
-       /* disable the eject button while mounted */
-       cmd_buff[0] = SONY535_DISABLE_EJECT_BUTTON;
-       do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
-#endif
-
-       return 0;
-}
-
-
-/*
- * Close the drive.  Spin it down if no task is using it.  The spin
- * down will fail if playing audio, so audio play is OK.
- */
-static int
-cdu_release(struct inode *inode,
-                       struct file *filp)
-{
-       Byte status[2], cmd_no;
-
-       sony_inuse = 0;
-
-       if (0 < sony_usage) {
-               sony_usage--;
-       }
-       if (sony_usage == 0) {
-               check_drive_status();
-
-               if (sony_audio_status != CDROM_AUDIO_PLAY) {
-                       cmd_no = SONY535_SPIN_DOWN;
-                       do_sony_cmd(&cmd_no, 1, status, NULL, 0, 0);
-               }
-#ifdef LOCK_DOORS
-               /* enable the eject button after umount */
-               cmd_no = SONY535_ENABLE_EJECT_BUTTON;
-               do_sony_cmd(&cmd_no, 1, status, NULL, 0, 0);
-#endif
-       }
-       return 0;
-}
-
-static struct block_device_operations cdu_fops =
-{
-       .owner          = THIS_MODULE,
-       .open           = cdu_open,
-       .release        = cdu_release,
-       .ioctl          = cdu_ioctl,
-       .media_changed  = cdu535_check_media_change,
-};
-
-static struct gendisk *cdu_disk;
-
-/*
- * Initialize the driver.
- */
-static int __init sony535_init(void)
-{
-       struct s535_sony_drive_config drive_config;
-       Byte cmd_buff[3];
-       Byte ret_buff[2];
-       Byte status[2];
-       unsigned long snap;
-       int  got_result = 0;
-       int  tmp_irq;
-       int  i;
-       int err;
-
-       /* Setting the base I/O address to 0 will disable it. */
-       if ((sony535_cd_base_io == 0xffff)||(sony535_cd_base_io == 0))
-               return 0;
-
-       /* Set up all the register locations */
-       result_reg = sony535_cd_base_io;
-       command_reg = sony535_cd_base_io;
-       data_reg = sony535_cd_base_io + 1;
-       read_status_reg = sony535_cd_base_io + 2;
-       select_unit_reg = sony535_cd_base_io + 3;
-
-#ifndef USE_IRQ
-       sony535_irq_used = 0;   /* polling only until this is ready... */
-#endif
-       /* we need to poll until things get initialized */
-       tmp_irq = sony535_irq_used;
-       sony535_irq_used = 0;
-
-#if DEBUG > 0
-       printk(KERN_INFO CDU535_MESSAGE_NAME ": probing base address %03X\n",
-                       sony535_cd_base_io);
-#endif
-       /* look for the CD-ROM, follows the procedure in the DOS driver */
-       inb(select_unit_reg);
-       /* wait for 40 18 Hz ticks (reverse-engineered from DOS driver) */
-       schedule_timeout_interruptible((HZ+17)*40/18);
-       inb(result_reg);
-
-       outb(0, read_status_reg);       /* does a reset? */
-       snap = jiffies;
-       while (jiffies-snap < SONY_JIFFIES_TIMEOUT) {
-               select_unit(0);
-               if (inb(result_reg) != 0xff) {
-                       got_result = 1;
-                       break;
-               }
-               sony_sleep();
-       }
-
-       if (!got_result || check_drive_status() == TIME_OUT)
-               goto Enodev;
-
-       /* CD-ROM drive responded --  get the drive configuration */
-       cmd_buff[0] = SONY535_INQUIRY;
-       if (do_sony_cmd(cmd_buff, 1, status, (Byte *)&drive_config, 28, 1) != 0)
-               goto Enodev;
-
-       /* was able to get the configuration,
-        * set drive mode as rest of init
-        */
-#if DEBUG > 0
-       /* 0x50 == CADDY_NOT_INSERTED | NOT_SPINNING */
-       if ( (status[0] & 0x7f) != 0 && (status[0] & 0x7f) != 0x50 )
-               printk(CDU535_MESSAGE_NAME
-                               "Inquiry command returned status = 0x%x\n", status[0]);
-#endif
-       /* now ready to use interrupts, if available */
-       sony535_irq_used = tmp_irq;
-
-       /* A negative sony535_irq_used will attempt an autoirq. */
-       if (sony535_irq_used < 0) {
-               unsigned long irq_mask, delay;
-
-               irq_mask = probe_irq_on();
-               enable_interrupts();
-               outb(0, read_status_reg);       /* does a reset? */
-               delay = jiffies + HZ/10;
-               while (time_before(jiffies, delay)) ;
-
-               sony535_irq_used = probe_irq_off(irq_mask);
-               disable_interrupts();
-       }
-       if (sony535_irq_used > 0) {
-           if (request_irq(sony535_irq_used, cdu535_interrupt,
-                                               IRQF_DISABLED, CDU535_HANDLE, NULL)) {
-                       printk("Unable to grab IRQ%d for the " CDU535_MESSAGE_NAME
-                                       " driver; polling instead.\n", sony535_irq_used);
-                       sony535_irq_used = 0;
-               }
-       }
-       cmd_buff[0] = SONY535_SET_DRIVE_MODE;
-       cmd_buff[1] = 0x0;      /* default audio */
-       if (do_sony_cmd(cmd_buff, 2, status, ret_buff, 1, 1) != 0)
-               goto Enodev_irq;
-
-       /* set the drive mode successful, we are set! */
-       sony_buffer_size = SONY535_BUFFER_SIZE;
-       sony_buffer_sectors = sony_buffer_size / CDU535_BLOCK_SIZE;
-
-       printk(KERN_INFO CDU535_MESSAGE_NAME " I/F CDROM : %8.8s %16.16s %4.4s",
-                  drive_config.vendor_id,
-                  drive_config.product_id,
-                  drive_config.product_rev_level);
-       printk("  base address %03X, ", sony535_cd_base_io);
-       if (tmp_irq > 0)
-               printk("IRQ%d, ", tmp_irq);
-       printk("using %d byte buffer\n", sony_buffer_size);
-
-       if (register_blkdev(MAJOR_NR, CDU535_HANDLE)) {
-               err = -EIO;
-               goto out1;
-       }
-       sonycd535_queue = blk_init_queue(do_cdu535_request, &sonycd535_lock);
-       if (!sonycd535_queue) {
-               err = -ENOMEM;
-               goto out1a;
-       }
-
-       blk_queue_hardsect_size(sonycd535_queue, CDU535_BLOCK_SIZE);
-       sony_toc = kmalloc(sizeof(struct s535_sony_toc), GFP_KERNEL);
-       err = -ENOMEM;
-       if (!sony_toc)
-               goto out2;
-       last_sony_subcode = kmalloc(sizeof(struct s535_sony_subcode), GFP_KERNEL);
-       if (!last_sony_subcode)
-               goto out3;
-       sony_buffer = kmalloc(sizeof(Byte *) * sony_buffer_sectors, GFP_KERNEL);
-       if (!sony_buffer)
-               goto out4;
-       for (i = 0; i < sony_buffer_sectors; i++) {
-               sony_buffer[i] = kmalloc(CDU535_BLOCK_SIZE, GFP_KERNEL);
-               if (!sony_buffer[i]) {
-                       while (--i>=0)
-                               kfree(sony_buffer[i]);
-                       goto out5;
-               }
-       }
-       initialized = 1;
-
-       cdu_disk = alloc_disk(1);
-       if (!cdu_disk)
-               goto out6;
-       cdu_disk->major = MAJOR_NR;
-       cdu_disk->first_minor = 0;
-       cdu_disk->fops = &cdu_fops;
-       sprintf(cdu_disk->disk_name, "cdu");
-
-       if (!request_region(sony535_cd_base_io, 4, CDU535_HANDLE)) {
-               printk(KERN_WARNING"sonycd535: Unable to request region 0x%x\n",
-                       sony535_cd_base_io);
-               goto out7;
-       }
-       cdu_disk->queue = sonycd535_queue;
-       add_disk(cdu_disk);
-       return 0;
-
-out7:
-       put_disk(cdu_disk);
-out6:
-       for (i = 0; i < sony_buffer_sectors; i++)
-               kfree(sony_buffer[i]);
-out5:
-       kfree(sony_buffer);
-out4:
-       kfree(last_sony_subcode);
-out3:
-       kfree(sony_toc);
-out2:
-       blk_cleanup_queue(sonycd535_queue);
-out1a:
-       unregister_blkdev(MAJOR_NR, CDU535_HANDLE);
-out1:
-       if (sony535_irq_used)
-               free_irq(sony535_irq_used, NULL);
-       return err;
-Enodev_irq:
-       if (sony535_irq_used)
-               free_irq(sony535_irq_used, NULL);
-Enodev:
-       printk("Did not find a " CDU535_MESSAGE_NAME " drive\n");
-       return -EIO;
-}
-
-#ifndef MODULE
-
-/*
- * accept "kernel command line" parameters
- * (added by emoenke@gwdg.de)
- *
- * use: tell LILO:
- *                 sonycd535=0x320
- *
- * the address value has to be the existing CDROM port address.
- */
-static int __init
-sonycd535_setup(char *strings)
-{
-       int ints[3];
-       (void)get_options(strings, ARRAY_SIZE(ints), ints);
-       /* if IRQ change and default io base desired,
-        * then call with io base of 0
-        */
-       if (ints[0] > 0)
-               if (ints[1] != 0)
-                       sony535_cd_base_io = ints[1];
-       if (ints[0] > 1)
-               sony535_irq_used = ints[2];
-       if ((strings != NULL) && (*strings != '\0'))
-               printk(CDU535_MESSAGE_NAME
-                               ": Warning: Unknown interface type: %s\n", strings);
-                               
-       return 1;
-}
-
-__setup("sonycd535=", sonycd535_setup);
-
-#endif /* MODULE */
-
-static void __exit
-sony535_exit(void)
-{
-       int i;
-
-       release_region(sony535_cd_base_io, 4);
-       for (i = 0; i < sony_buffer_sectors; i++)
-               kfree(sony_buffer[i]);
-       kfree(sony_buffer);
-       kfree(last_sony_subcode);
-       kfree(sony_toc);
-       del_gendisk(cdu_disk);
-       put_disk(cdu_disk);
-       blk_cleanup_queue(sonycd535_queue);
-       if (unregister_blkdev(MAJOR_NR, CDU535_HANDLE) == -EINVAL)
-               printk("Uh oh, couldn't unregister " CDU535_HANDLE "\n");
-       else
-               printk(KERN_INFO CDU535_HANDLE " module released\n");
-}
-
-module_init(sony535_init);
-module_exit(sony535_exit);
-
-
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_BLOCKDEV_MAJOR(CDU535_CDROM_MAJOR);
diff --git a/drivers/cdrom/sonycd535.h b/drivers/cdrom/sonycd535.h
deleted file mode 100644 (file)
index 5dea1ef..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-#ifndef SONYCD535_H
-#define SONYCD535_H
-
-/*
- * define all the commands recognized by the CDU-531/5
- */
-#define SONY535_REQUEST_DRIVE_STATUS_1         (0x80)
-#define SONY535_REQUEST_SENSE                  (0x82)
-#define SONY535_REQUEST_DRIVE_STATUS_2         (0x84)
-#define SONY535_REQUEST_ERROR_STATUS           (0x86)
-#define SONY535_REQUEST_AUDIO_STATUS           (0x88)
-#define SONY535_INQUIRY                                (0x8a)
-
-#define SONY535_SET_INACTIVITY_TIME            (0x90)
-
-#define SONY535_SEEK_AND_READ_N_BLOCKS_1       (0xa0)
-#define SONY535_SEEK_AND_READ_N_BLOCKS_2       (0xa4)
-#define SONY535_PLAY_AUDIO                     (0xa6)
-
-#define SONY535_REQUEST_DISC_CAPACITY          (0xb0)
-#define SONY535_REQUEST_TOC_DATA               (0xb2)
-#define SONY535_REQUEST_SUB_Q_DATA             (0xb4)
-#define SONY535_REQUEST_ISRC                   (0xb6)
-#define SONY535_REQUEST_UPC_EAN                        (0xb8)
-
-#define SONY535_SET_DRIVE_MODE                 (0xc0)
-#define SONY535_REQUEST_DRIVE_MODE             (0xc2)
-#define SONY535_SET_RETRY_COUNT                        (0xc4)
-
-#define SONY535_DIAGNOSTIC_1                   (0xc6)
-#define SONY535_DIAGNOSTIC_4                   (0xcc)
-#define SONY535_DIAGNOSTIC_5                   (0xce)
-
-#define SONY535_EJECT_CADDY                    (0xd0)
-#define SONY535_DISABLE_EJECT_BUTTON           (0xd2)
-#define SONY535_ENABLE_EJECT_BUTTON            (0xd4)
-
-#define SONY535_HOLD                           (0xe0)
-#define SONY535_AUDIO_PAUSE_ON_OFF             (0xe2)
-#define SONY535_SET_VOLUME                     (0xe8)
-
-#define SONY535_STOP                           (0xf0)
-#define SONY535_SPIN_UP                                (0xf2)
-#define SONY535_SPIN_DOWN                      (0xf4)
-
-#define SONY535_CLEAR_PARAMETERS               (0xf6)
-#define SONY535_CLEAR_ENDING_ADDRESS           (0xf8)
-
-/*
- * define some masks
- */
-#define SONY535_DATA_NOT_READY_BIT             (0x1)
-#define SONY535_RESULT_NOT_READY_BIT           (0x2)
-
-/*
- *  drive status 1
- */
-#define SONY535_STATUS1_COMMAND_ERROR          (0x1)
-#define SONY535_STATUS1_DATA_ERROR             (0x2)
-#define SONY535_STATUS1_SEEK_ERROR             (0x4)
-#define SONY535_STATUS1_DISC_TYPE_ERROR                (0x8)
-#define SONY535_STATUS1_NOT_SPINNING           (0x10)
-#define SONY535_STATUS1_EJECT_BUTTON_PRESSED   (0x20)
-#define SONY535_STATUS1_CADDY_NOT_INSERTED     (0x40)
-#define SONY535_STATUS1_BYTE_TWO_FOLLOWS       (0x80)
-
-/*
- * drive status 2
- */
-#define SONY535_CDD_LOADING_ERROR              (0x7)
-#define SONY535_CDD_NO_DISC                    (0x8)
-#define SONY535_CDD_UNLOADING_ERROR            (0x9)
-#define SONY535_CDD_CADDY_NOT_INSERTED         (0xd)
-#define SONY535_ATN_RESET_OCCURRED             (0x2)
-#define SONY535_ATN_DISC_CHANGED               (0x4)
-#define SONY535_ATN_RESET_AND_DISC_CHANGED     (0x6)
-#define SONY535_ATN_EJECT_IN_PROGRESS          (0xe)
-#define SONY535_ATN_BUSY                       (0xf)
-
-/*
- * define some parameters
- */
-#define SONY535_AUDIO_DRIVE_MODE               (0)
-#define SONY535_CDROM_DRIVE_MODE               (0xe0)
-
-#define SONY535_PLAY_OP_PLAYBACK               (0)
-#define SONY535_PLAY_OP_ENTER_HOLD             (1)
-#define SONY535_PLAY_OP_SET_AUDIO_ENDING_ADDR  (2)
-#define SONY535_PLAY_OP_SCAN_FORWARD           (3)
-#define SONY535_PLAY_OP_SCAN_BACKWARD          (4)
-
-/*
- *  convert from msf format to block number 
- */
-#define SONY_BLOCK_NUMBER(m,s,f) (((m)*60L+(s))*75L+(f))
-#define SONY_BLOCK_NUMBER_MSF(x) (((x)[0]*60L+(x)[1])*75L+(x)[2])
-
-/*
- *  error return values from the doSonyCmd() routines
- */
-#define TIME_OUT                       (-1)
-#define NO_CDROM                       (-2)
-#define BAD_STATUS                     (-3)
-#define CD_BUSY                                (-4)
-#define NOT_DATA_CD                    (-5)
-#define NO_ROOM                                (-6)
-
-#define LOG_START_OFFSET        150     /* Offset of first logical sector */
-
-#define SONY_JIFFIES_TIMEOUT   (5*HZ)  /* Maximum time
-                                          the drive will wait/try for an
-                                          operation */
-#define SONY_READY_RETRIES      (50000)  /* How many times to retry a
-                                                  spin waiting for a register
-                                                  to come ready */
-#define SONY535_FAST_POLLS     (10000)   /* how many times recheck 
-                                                  status waiting for a data
-                                                  to become ready */
-
-typedef unsigned char Byte;
-
-/*
- * This is the complete status returned from the drive configuration request
- * command.
- */
-struct s535_sony_drive_config
-{
-   char vendor_id[8];
-   char product_id[16];
-   char product_rev_level[4];
-};
-
-/* The following is returned from the request sub-q data command */
-struct s535_sony_subcode
-{
-   unsigned char address        :4;
-   unsigned char control        :4;
-   unsigned char track_num;
-   unsigned char index_num;
-   unsigned char rel_msf[3];
-   unsigned char abs_msf[3];
-};
-
-struct s535_sony_disc_capacity
-{
-   Byte mFirstTrack, sFirstTrack, fFirstTrack;
-   Byte mLeadOut, sLeadOut, fLeadOut;
-};
-
-/*
- * The following is returned from the request TOC (Table Of Contents) command.
- * (last_track_num-first_track_num+1) values are valid in tracks.
- */
-struct s535_sony_toc
-{
-   unsigned char reserved0      :4;
-   unsigned char control0       :4;
-   unsigned char point0;
-   unsigned char first_track_num;
-   unsigned char reserved0a;
-   unsigned char reserved0b;
-   unsigned char reserved1      :4;
-   unsigned char control1       :4;
-   unsigned char point1;
-   unsigned char last_track_num;
-   unsigned char dummy1;
-   unsigned char dummy2;
-   unsigned char reserved2      :4;
-   unsigned char control2       :4;
-   unsigned char point2;
-   unsigned char lead_out_start_msf[3];
-   struct
-   {
-      unsigned char reserved    :4;
-      unsigned char control     :4;
-      unsigned char track;
-      unsigned char track_start_msf[3];
-   } tracks[100];
-
-   unsigned int lead_out_start_lba;
-};
-
-#endif /* SONYCD535_H */
index ef683ebd367caf7b4b4045857525301ef2e25285..f6648682b43ab4669a8e06dbb46adf9649c94049 100644 (file)
@@ -374,20 +374,6 @@ config ISTALLION
          To compile this driver as a module, choose M here: the
          module will be called istallion.
 
-config AU1000_UART
-       bool "Enable Au1000 UART Support"
-       depends on SERIAL_NONSTANDARD && MIPS
-       help
-         If you have an Alchemy AU1000 processor (MIPS based) and you want
-         to use serial ports, say Y.  Otherwise, say N.
-
-config AU1000_SERIAL_CONSOLE
-       bool "Enable Au1000 serial console"
-       depends on AU1000_UART
-       help
-         If you have an Alchemy AU1000 processor (MIPS based) and you want
-         to use a console on a serial port, say Y.  Otherwise, say N.
-
 config SERIAL_DEC
        bool "DECstation serial support"
        depends on MACH_DECSTATION
@@ -815,7 +801,7 @@ config SGI_IP27_RTC
 
 config GEN_RTC
        tristate "Generic /dev/rtc emulation"
-       depends on RTC!=y && !IA64 && !ARM && !M32R && !SPARC && !FRV && !S390 && !SUPERH
+       depends on RTC!=y && !IA64 && !ARM && !M32R && !MIPS && !SPARC && !FRV && !S390 && !SUPERH
        ---help---
          If you say Y here and create a character special file /dev/rtc with
          major number 10 and minor number 135 using mknod ("man mknod"), you
index e6c534e6284638a610d8a1549b52530d6d4225af..df0ddf14b85cd3d695718beffae359b4581881f8 100644 (file)
@@ -462,9 +462,7 @@ static int __devinit agp_amdk7_probe(struct pci_dev *pdev,
         * erratum 46: Setup violation on AGP SBA pins - Disable side band addressing.
         * With this lot disabled, we should prevent lockups. */
        if (agp_bridge->dev->device == PCI_DEVICE_ID_AMD_FE_GATE_700E) {
-               u8 revision=0;
-               pci_read_config_byte(pdev, PCI_REVISION_ID, &revision);
-               if (revision == 0x10 || revision == 0x11) {
+               if (pdev->revision == 0x10 || pdev->revision == 0x11) {
                        agp_bridge->flags = AGP_ERRATA_FASTWRITES;
                        agp_bridge->flags |= AGP_ERRATA_SBA;
                        agp_bridge->flags |= AGP_ERRATA_1X;
index 801abdd290669a092765191ef86450593dc23c2d..d95662e96326dfe152029b2042890f24ccfa5148 100644 (file)
@@ -367,10 +367,8 @@ static __devinit int cache_nbs (struct pci_dev *pdev, u32 cap_ptr)
 static void __devinit amd8151_init(struct pci_dev *pdev, struct agp_bridge_data *bridge)
 {
        char *revstring;
-       u8 rev_id;
 
-       pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id);
-       switch (rev_id) {
+       switch (pdev->revision) {
        case 0x01: revstring="A0"; break;
        case 0x02: revstring="A1"; break;
        case 0x11: revstring="B0"; break;
@@ -386,7 +384,7 @@ static void __devinit amd8151_init(struct pci_dev *pdev, struct agp_bridge_data
         * Work around errata.
         * Chips before B2 stepping incorrectly reporting v3.5
         */
-       if (rev_id < 0x13) {
+       if (pdev->revision < 0x13) {
                printk (KERN_INFO PFX "Correcting AGP revision (reports 3.5, is really 3.0)\n");
                bridge->major_version = 3;
                bridge->minor_version = 0;
index ebdd6dd66edb6b27931061a3ea732014f58bb31e..1b47c89a1b992c7946b3d9b6ae1fcf843a47eebb 100644 (file)
@@ -321,7 +321,7 @@ EXPORT_SYMBOL(agp_try_unsupported_boot);
 static int __init agp_init(void)
 {
        if (!agp_off)
-               printk(KERN_INFO "Linux agpgart interface v%d.%d (c) Dave Jones\n",
+               printk(KERN_INFO "Linux agpgart interface v%d.%d\n",
                        AGPGART_VERSION_MAJOR, AGPGART_VERSION_MINOR);
        return 0;
 }
index 8e222f2b80cc4bb2ee28535e936fcd83d6fb397c..b5df7e61aeb2aa4b7282733d357a24dee06b887a 100644 (file)
@@ -2171,52 +2171,42 @@ static int create_files(struct bmc_device *bmc)
        int err;
 
        bmc->device_id_attr.attr.name = "device_id";
-       bmc->device_id_attr.attr.owner = THIS_MODULE;
        bmc->device_id_attr.attr.mode = S_IRUGO;
        bmc->device_id_attr.show = device_id_show;
 
        bmc->provides_dev_sdrs_attr.attr.name = "provides_device_sdrs";
-       bmc->provides_dev_sdrs_attr.attr.owner = THIS_MODULE;
        bmc->provides_dev_sdrs_attr.attr.mode = S_IRUGO;
        bmc->provides_dev_sdrs_attr.show = provides_dev_sdrs_show;
 
        bmc->revision_attr.attr.name = "revision";
-       bmc->revision_attr.attr.owner = THIS_MODULE;
        bmc->revision_attr.attr.mode = S_IRUGO;
        bmc->revision_attr.show = revision_show;
 
        bmc->firmware_rev_attr.attr.name = "firmware_revision";
-       bmc->firmware_rev_attr.attr.owner = THIS_MODULE;
        bmc->firmware_rev_attr.attr.mode = S_IRUGO;
        bmc->firmware_rev_attr.show = firmware_rev_show;
 
        bmc->version_attr.attr.name = "ipmi_version";
-       bmc->version_attr.attr.owner = THIS_MODULE;
        bmc->version_attr.attr.mode = S_IRUGO;
        bmc->version_attr.show = ipmi_version_show;
 
        bmc->add_dev_support_attr.attr.name = "additional_device_support";
-       bmc->add_dev_support_attr.attr.owner = THIS_MODULE;
        bmc->add_dev_support_attr.attr.mode = S_IRUGO;
        bmc->add_dev_support_attr.show = add_dev_support_show;
 
        bmc->manufacturer_id_attr.attr.name = "manufacturer_id";
-       bmc->manufacturer_id_attr.attr.owner = THIS_MODULE;
        bmc->manufacturer_id_attr.attr.mode = S_IRUGO;
        bmc->manufacturer_id_attr.show = manufacturer_id_show;
 
        bmc->product_id_attr.attr.name = "product_id";
-       bmc->product_id_attr.attr.owner = THIS_MODULE;
        bmc->product_id_attr.attr.mode = S_IRUGO;
        bmc->product_id_attr.show = product_id_show;
 
        bmc->guid_attr.attr.name = "guid";
-       bmc->guid_attr.attr.owner = THIS_MODULE;
        bmc->guid_attr.attr.mode = S_IRUGO;
        bmc->guid_attr.show = guid_show;
 
        bmc->aux_firmware_rev_attr.attr.name = "aux_firmware_revision";
-       bmc->aux_firmware_rev_attr.attr.owner = THIS_MODULE;
        bmc->aux_firmware_rev_attr.attr.mode = S_IRUGO;
        bmc->aux_firmware_rev_attr.show = aux_firmware_rev_show;
 
index 1b094509b1d2fdb5acaebb980a7e157c3b592b2e..90965b4def5cda2e90f6d5def2f3e879bee14035 100644 (file)
@@ -1005,8 +1005,8 @@ static const unsigned short x86_keycodes[256] =
        284,285,309,  0,312, 91,327,328,329,331,333,335,336,337,338,339,
        367,288,302,304,350, 89,334,326,267,126,268,269,125,347,348,349,
        360,261,262,263,268,376,100,101,321,316,373,286,289,102,351,355,
-       103,104,105,275,287,279,306,106,274,107,294,364,358,363,362,361,
-       291,108,381,281,290,272,292,305,280, 99,112,257,258,359,113,114,
+       103,104,105,275,287,279,258,106,274,107,294,364,358,363,362,361,
+       291,108,381,281,290,272,292,305,280, 99,112,257,306,359,113,114,
        264,117,271,374,379,265,266, 93, 94, 95, 85,259,375,260, 90,116,
        377,109,111,277,278,282,283,295,296,297,299,300,301,293,303,307,
        308,310,313,314,315,317,318,319,320,357,322,323,324,325,276,330,
index cc9a9d0df979f5dcf69b4e70d4f7945aae68a490..bbee97ff355f6987cb1714e97e8b73f8ecf03270 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/crash_dump.h>
 #include <linux/backing-dev.h>
 #include <linux/bootmem.h>
-#include <linux/pipe_fs_i.h>
+#include <linux/splice.h>
 #include <linux/pfn.h>
 
 #include <asm/uaccess.h>
@@ -75,6 +75,13 @@ static inline int uncached_access(struct file *file, unsigned long addr)
         * On ia64, we ignore O_SYNC because we cannot tolerate memory attribute aliases.
         */
        return !(efi_mem_attributes(addr) & EFI_MEMORY_WB);
+#elif defined(CONFIG_MIPS)
+       {
+               extern int __uncached_access(struct file *file,
+                                            unsigned long addr);
+
+               return __uncached_access(file, addr);
+       }
 #else
        /*
         * Accessing memory above the top the kernel knows about or through a file pointer
index 1da92a689ae455f542533b1a980fa6c36d8aa75c..85a23283dff55144b594ae86b6a87100814fdf66 100644 (file)
@@ -2721,9 +2721,9 @@ static void __devexit sx_pci_remove(struct pci_dev *pdev)
    its because the standard requires it. So check for SUBVENDOR_ID. */
 static struct pci_device_id sx_pci_tbl[] = {
        { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8,
-               .subvendor = 0x0200,.subdevice = PCI_ANY_ID },
+               .subvendor = PCI_ANY_ID, .subdevice = 0x0200 },
        { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8,
-               .subvendor = 0x0300,.subdevice = PCI_ANY_ID },
+               .subvendor = PCI_ANY_ID, .subdevice = 0x0300 },
        { 0 }
 };
 
index 0cea8d4907dfb965d509e356f51c18ca23118756..e5ed09192be8675b615f6978dcf92f41a3dcf316 100644 (file)
  *  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/platform_device.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/init.h>
-#include <linux/irq.h>
 #include <linux/interrupt.h>
+#include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/platform_device.h>
 #include <linux/spinlock.h>
 #include <linux/types.h>
 
-#include <asm/cpu.h>
 #include <asm/io.h>
 #include <asm/vr41xx/giu.h>
 #include <asm/vr41xx/irq.h>
@@ -44,18 +43,6 @@ static int major;    /* default is dynamic major device number */
 module_param(major, int, 0);
 MODULE_PARM_DESC(major, "Major device number");
 
-#define GIU_TYPE1_START                0x0b000100UL
-#define GIU_TYPE1_SIZE         0x20UL
-
-#define GIU_TYPE2_START                0x0f000140UL
-#define GIU_TYPE2_SIZE         0x20UL
-
-#define GIU_TYPE3_START                0x0f000140UL
-#define GIU_TYPE3_SIZE         0x28UL
-
-#define GIU_PULLUPDOWN_START   0x0b0002e0UL
-#define GIU_PULLUPDOWN_SIZE    0x04UL
-
 #define GIUIOSELL      0x00
 #define GIUIOSELH      0x02
 #define GIUPIODL       0x04
@@ -89,8 +76,6 @@ MODULE_PARM_DESC(major, "Major device number");
 #define GPIO_HAS_INTERRUPT_EDGE_SELECT 0x0100
 
 static spinlock_t giu_lock;
-static struct resource *giu_resource1;
-static struct resource *giu_resource2;
 static unsigned long giu_flags;
 static unsigned int giu_nr_pins;
 
@@ -234,7 +219,7 @@ void vr41xx_set_irq_trigger(unsigned int pin, irq_trigger_t trigger, irq_signal_
                                giu_set(GIUINTHTSELL, mask);
                        else
                                giu_clear(GIUINTHTSELL, mask);
-                       if (current_cpu_data.cputype == CPU_VR4133) {
+                       if (giu_flags & GPIO_HAS_INTERRUPT_EDGE_SELECT) {
                                switch (trigger) {
                                case IRQ_TRIGGER_EDGE_FALLING:
                                        giu_set(GIUFEDGEINHL, mask);
@@ -269,7 +254,7 @@ void vr41xx_set_irq_trigger(unsigned int pin, irq_trigger_t trigger, irq_signal_
                                giu_set(GIUINTHTSELH, mask);
                        else
                                giu_clear(GIUINTHTSELH, mask);
-                       if (current_cpu_data.cputype == CPU_VR4133) {
+                       if (giu_flags & GPIO_HAS_INTERRUPT_EDGE_SELECT) {
                                switch (trigger) {
                                case IRQ_TRIGGER_EDGE_FALLING:
                                        giu_set(GIUFEDGEINHH, mask);
@@ -298,7 +283,6 @@ void vr41xx_set_irq_trigger(unsigned int pin, irq_trigger_t trigger, irq_signal_
                giu_write(GIUINTSTATH, mask);
        }
 }
-
 EXPORT_SYMBOL_GPL(vr41xx_set_irq_trigger);
 
 void vr41xx_set_irq_level(unsigned int pin, irq_level_t level)
@@ -321,7 +305,6 @@ void vr41xx_set_irq_level(unsigned int pin, irq_level_t level)
                giu_write(GIUINTSTATH, mask);
        }
 }
-
 EXPORT_SYMBOL_GPL(vr41xx_set_irq_level);
 
 gpio_data_t vr41xx_gpio_get_pin(unsigned int pin)
@@ -350,7 +333,6 @@ gpio_data_t vr41xx_gpio_get_pin(unsigned int pin)
 
        return GPIO_DATA_LOW;
 }
-
 EXPORT_SYMBOL_GPL(vr41xx_gpio_get_pin);
 
 int vr41xx_gpio_set_pin(unsigned int pin, gpio_data_t data)
@@ -388,7 +370,6 @@ int vr41xx_gpio_set_pin(unsigned int pin, gpio_data_t data)
 
        return 0;
 }
-
 EXPORT_SYMBOL_GPL(vr41xx_gpio_set_pin);
 
 int vr41xx_gpio_set_direction(unsigned int pin, gpio_direction_t dir)
@@ -438,7 +419,6 @@ int vr41xx_gpio_set_direction(unsigned int pin, gpio_direction_t dir)
 
        return 0;
 }
-
 EXPORT_SYMBOL_GPL(vr41xx_gpio_set_direction);
 
 int vr41xx_gpio_pullupdown(unsigned int pin, gpio_pull_t pull)
@@ -477,7 +457,6 @@ int vr41xx_gpio_pullupdown(unsigned int pin, gpio_pull_t pull)
 
        return 0;
 }
-
 EXPORT_SYMBOL_GPL(vr41xx_gpio_pullupdown);
 
 static ssize_t gpio_read(struct file *file, char __user *buf, size_t len,
@@ -596,61 +575,40 @@ static const struct file_operations gpio_fops = {
 
 static int __devinit giu_probe(struct platform_device *dev)
 {
-       unsigned long start, size, flags = 0;
-       unsigned int nr_pins = 0, trigger, i, pin;
-       struct resource *res1, *res2 = NULL;
-       void *base;
+       struct resource *res;
+       unsigned int trigger, i, pin;
        struct irq_chip *chip;
-       int retval;
-
-       switch (current_cpu_data.cputype) {
-       case CPU_VR4111:
-       case CPU_VR4121:
-               start = GIU_TYPE1_START;
-               size = GIU_TYPE1_SIZE;
-               flags = GPIO_HAS_PULLUPDOWN_IO;
-               nr_pins = 50;
+       int irq, retval;
+
+       switch (dev->id) {
+       case GPIO_50PINS_PULLUPDOWN:
+               giu_flags = GPIO_HAS_PULLUPDOWN_IO;
+               giu_nr_pins = 50;
                break;
-       case CPU_VR4122:
-       case CPU_VR4131:
-               start = GIU_TYPE2_START;
-               size = GIU_TYPE2_SIZE;
-               nr_pins = 36;
+       case GPIO_36PINS:
+               giu_nr_pins = 36;
                break;
-       case CPU_VR4133:
-               start = GIU_TYPE3_START;
-               size = GIU_TYPE3_SIZE;
-               flags = GPIO_HAS_INTERRUPT_EDGE_SELECT;
-               nr_pins = 48;
+       case GPIO_48PINS_EDGE_SELECT:
+               giu_flags = GPIO_HAS_INTERRUPT_EDGE_SELECT;
+               giu_nr_pins = 48;
                break;
        default:
+               printk(KERN_ERR "GIU: unknown ID %d\n", dev->id);
                return -ENODEV;
        }
 
-       res1 = request_mem_region(start, size, "GIU");
-       if (res1 == NULL)
+       res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+       if (!res)
                return -EBUSY;
 
-       base = ioremap(start, size);
-       if (base == NULL) {
-               release_resource(res1);
+       giu_base = ioremap(res->start, res->end - res->start + 1);
+       if (!giu_base)
                return -ENOMEM;
-       }
-
-       if (flags & GPIO_HAS_PULLUPDOWN_IO) {
-               res2 = request_mem_region(GIU_PULLUPDOWN_START, GIU_PULLUPDOWN_SIZE, "GIU");
-               if (res2 == NULL) {
-                       iounmap(base);
-                       release_resource(res1);
-                       return -EBUSY;
-               }
-       }
 
        retval = register_chrdev(major, "GIU", &gpio_fops);
        if (retval < 0) {
-               iounmap(base);
-               release_resource(res1);
-               release_resource(res2);
+               iounmap(giu_base);
+               giu_base = NULL;
                return retval;
        }
 
@@ -660,11 +618,6 @@ static int __devinit giu_probe(struct platform_device *dev)
        }
 
        spin_lock_init(&giu_lock);
-       giu_base = base;
-       giu_resource1 = res1;
-       giu_resource2 = res2;
-       giu_flags = flags;
-       giu_nr_pins = nr_pins;
 
        giu_write(GIUINTENL, 0);
        giu_write(GIUINTENH, 0);
@@ -685,22 +638,23 @@ static int __devinit giu_probe(struct platform_device *dev)
 
        }
 
-       return cascade_irq(GIUINT_IRQ, giu_get_irq);
+       irq = platform_get_irq(dev, 0);
+       if (irq < 0 || irq >= NR_IRQS)
+               return -EBUSY;
+
+       return cascade_irq(irq, giu_get_irq);
 }
 
 static int __devexit giu_remove(struct platform_device *dev)
 {
-       iounmap(giu_base);
-
-       release_resource(giu_resource1);
-       if (giu_flags & GPIO_HAS_PULLUPDOWN_IO)
-               release_resource(giu_resource2);
+       if (giu_base) {
+               iounmap(giu_base);
+               giu_base = NULL;
+       }
 
        return 0;
 }
 
-static struct platform_device *giu_platform_device;
-
 static struct platform_driver giu_device_driver = {
        .probe          = giu_probe,
        .remove         = __devexit_p(giu_remove),
@@ -712,30 +666,12 @@ static struct platform_driver giu_device_driver = {
 
 static int __init vr41xx_giu_init(void)
 {
-       int retval;
-
-       giu_platform_device = platform_device_alloc("GIU", -1);
-       if (!giu_platform_device)
-               return -ENOMEM;
-
-       retval = platform_device_add(giu_platform_device);
-       if (retval < 0) {
-               platform_device_put(giu_platform_device);
-               return retval;
-       }
-
-       retval = platform_driver_register(&giu_device_driver);
-       if (retval < 0)
-               platform_device_unregister(giu_platform_device);
-
-       return retval;
+       return platform_driver_register(&giu_device_driver);
 }
 
 static void __exit vr41xx_giu_exit(void)
 {
        platform_driver_unregister(&giu_device_driver);
-
-       platform_device_unregister(giu_platform_device);
 }
 
 module_init(vr41xx_giu_init);
index 5cfcff532545b019e3f984dbf3de5273b91d464b..e783dbf0f162fe736339366b6afea4af55ea6cc0 100644 (file)
@@ -105,14 +105,11 @@ static inline void acpi_pm_need_workaround(void)
  */
 static void __devinit acpi_pm_check_blacklist(struct pci_dev *dev)
 {
-       u8 rev;
-
        if (acpi_pm_good)
                return;
 
-       pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
        /* the bug has been fixed in PIIX4M */
-       if (rev < 3) {
+       if (dev->revision < 3) {
                printk(KERN_WARNING "* Found PM-Timer Bug on the chipset."
                       " Due to workarounds for a bug,\n"
                       "* this clock source is slow. Consider trying"
index eb37fba9b7efccf163badc70450aee38873b60d3..0db9e1bda3227f36cb383a641ae0ca670724eb0a 100644 (file)
@@ -826,13 +826,21 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
        /* set up files for this cpu device */
        drv_attr = cpufreq_driver->attr;
        while ((drv_attr) && (*drv_attr)) {
-               sysfs_create_file(&policy->kobj, &((*drv_attr)->attr));
+               ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr));
+               if (ret)
+                       goto err_out_driver_exit;
                drv_attr++;
        }
-       if (cpufreq_driver->get)
-               sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr);
-       if (cpufreq_driver->target)
-               sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
+       if (cpufreq_driver->get){
+               ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr);
+               if (ret)
+                       goto err_out_driver_exit;
+       }
+       if (cpufreq_driver->target){
+               ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
+               if (ret)
+                       goto err_out_driver_exit;
+       }
 
        spin_lock_irqsave(&cpufreq_driver_lock, flags);
        for_each_cpu_mask(j, policy->cpus) {
index 8532bb79e5fc52dfc8d45ac3aba16b3f6ecd796f..e794527e49251d10564e703805b1965844c12b65 100644 (file)
@@ -96,15 +96,25 @@ static struct dbs_tuners {
 
 static inline cputime64_t get_cpu_idle_time(unsigned int cpu)
 {
-       cputime64_t retval;
+       cputime64_t idle_time;
+       cputime64_t cur_jiffies;
+       cputime64_t busy_time;
 
-       retval = cputime64_add(kstat_cpu(cpu).cpustat.idle,
-                       kstat_cpu(cpu).cpustat.iowait);
+       cur_jiffies = jiffies64_to_cputime64(get_jiffies_64());
+       busy_time = cputime64_add(kstat_cpu(cpu).cpustat.user,
+                       kstat_cpu(cpu).cpustat.system);
 
-       if (dbs_tuners_ins.ignore_nice)
-               retval = cputime64_add(retval, kstat_cpu(cpu).cpustat.nice);
+       busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.irq);
+       busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.softirq);
+       busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.steal);
 
-       return retval;
+       if (!dbs_tuners_ins.ignore_nice) {
+               busy_time = cputime64_add(busy_time,
+                               kstat_cpu(cpu).cpustat.nice);
+       }
+
+       idle_time = cputime64_sub(cur_jiffies, busy_time);
+       return idle_time;
 }
 
 /*
@@ -325,7 +335,7 @@ static struct attribute_group dbs_attr_group = {
 static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
 {
        unsigned int idle_ticks, total_ticks;
-       unsigned int load;
+       unsigned int load = 0;
        cputime64_t cur_jiffies;
 
        struct cpufreq_policy *policy;
@@ -339,7 +349,8 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
        cur_jiffies = jiffies64_to_cputime64(get_jiffies_64());
        total_ticks = (unsigned int) cputime64_sub(cur_jiffies,
                        this_dbs_info->prev_cpu_wall);
-       this_dbs_info->prev_cpu_wall = cur_jiffies;
+       this_dbs_info->prev_cpu_wall = get_jiffies_64();
+
        if (!total_ticks)
                return;
        /*
@@ -370,7 +381,8 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
                if (tmp_idle_ticks < idle_ticks)
                        idle_ticks = tmp_idle_ticks;
        }
-       load = (100 * (total_ticks - idle_ticks)) / total_ticks;
+       if (likely(total_ticks > idle_ticks))
+               load = (100 * (total_ticks - idle_ticks)) / total_ticks;
 
        /* Check for frequency increase */
        if (load > dbs_tuners_ins.up_threshold) {
index d2f0cbd8b8f3f294ef7a1f834d52bbfcb2bf02c3..917b9bab9ccbc924a6e583997cf96dc03e09071f 100644 (file)
@@ -25,8 +25,7 @@ static spinlock_t cpufreq_stats_lock;
 
 #define CPUFREQ_STATDEVICE_ATTR(_name,_mode,_show) \
 static struct freq_attr _attr_##_name = {\
-       .attr = {.name = __stringify(_name), .owner = THIS_MODULE, \
-               .mode = _mode, }, \
+       .attr = {.name = __stringify(_name), .mode = _mode, }, \
        .show = _show,\
 };
 
index 860345c7799ab1188c21945756ec6e696019b10e..51bedab6c808da57dd2b26e896021613d2540655 100644 (file)
@@ -37,6 +37,7 @@ static unsigned int   cpu_set_freq[NR_CPUS]; /* CPU freq desired by userspace */
 static unsigned int    cpu_is_managed[NR_CPUS];
 
 static DEFINE_MUTEX    (userspace_mutex);
+static int cpus_using_userspace_governor;
 
 #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_GOVERNOR, "userspace", msg)
 
@@ -47,7 +48,11 @@ userspace_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
 {
         struct cpufreq_freqs *freq = data;
 
-       dprintk("saving cpu_cur_freq of cpu %u to be %u kHz\n", freq->cpu, freq->new);
+       if (!cpu_is_managed[freq->cpu])
+               return 0;
+
+       dprintk("saving cpu_cur_freq of cpu %u to be %u kHz\n",
+                       freq->cpu, freq->new);
        cpu_cur_freq[freq->cpu] = freq->new;
 
         return 0;
@@ -120,7 +125,7 @@ store_speed (struct cpufreq_policy *policy, const char *buf, size_t count)
 
 static struct freq_attr freq_attr_scaling_setspeed =
 {
-       .attr = { .name = "scaling_setspeed", .mode = 0644, .owner = THIS_MODULE },
+       .attr = { .name = "scaling_setspeed", .mode = 0644 },
        .show = show_speed,
        .store = store_speed,
 };
@@ -142,6 +147,13 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
                if (rc)
                        goto start_out;
 
+               if (cpus_using_userspace_governor == 0) {
+                       cpufreq_register_notifier(
+                                       &userspace_cpufreq_notifier_block,
+                                       CPUFREQ_TRANSITION_NOTIFIER);
+               }
+               cpus_using_userspace_governor++;
+
                cpu_is_managed[cpu] = 1;
                cpu_min_freq[cpu] = policy->min;
                cpu_max_freq[cpu] = policy->max;
@@ -153,6 +165,13 @@ start_out:
                break;
        case CPUFREQ_GOV_STOP:
                mutex_lock(&userspace_mutex);
+               cpus_using_userspace_governor--;
+               if (cpus_using_userspace_governor == 0) {
+                       cpufreq_unregister_notifier(
+                                       &userspace_cpufreq_notifier_block,
+                                       CPUFREQ_TRANSITION_NOTIFIER);
+               }
+
                cpu_is_managed[cpu] = 0;
                cpu_min_freq[cpu] = 0;
                cpu_max_freq[cpu] = 0;
@@ -198,7 +217,6 @@ EXPORT_SYMBOL(cpufreq_gov_userspace);
 
 static int __init cpufreq_gov_userspace_init(void)
 {
-       cpufreq_register_notifier(&userspace_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
        return cpufreq_register_governor(&cpufreq_gov_userspace);
 }
 
@@ -206,7 +224,6 @@ static int __init cpufreq_gov_userspace_init(void)
 static void __exit cpufreq_gov_userspace_exit(void)
 {
        cpufreq_unregister_governor(&cpufreq_gov_userspace);
-        cpufreq_unregister_notifier(&userspace_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
 }
 
 
index e7490925fdcf51acaf7d00039a609465a1aaf54d..5409f3afb3f85fab2a0b7e160c2972805b0a374d 100644 (file)
@@ -199,7 +199,6 @@ static ssize_t show_available_freqs (struct cpufreq_policy *policy, char *buf)
 struct freq_attr cpufreq_freq_attr_scaling_available_freqs = {
        .attr = { .name = "scaling_available_frequencies",
                  .mode = 0444,
-                 .owner=THIS_MODULE
                },
        .show = show_available_freqs,
 };
index 9eb1edacd825d3d4c4e5d345bfb9c869bef98aaa..0aeab3218bb6d6b8c503b2f2386133e611f4a5f7 100644 (file)
@@ -336,8 +336,11 @@ fw_card_bm_work(struct work_struct *work)
        }
 
  pick_me:
-       /* Now figure out what gap count to set. */
-       if (card->topology_type == FW_TOPOLOGY_A &&
+       /*
+        * Pick a gap count from 1394a table E-1.  The table doesn't cover
+        * the typically much larger 1394b beta repeater delays though.
+        */
+       if (!card->beta_repeaters_present &&
            card->root_node->max_hops < ARRAY_SIZE(gap_count_table))
                gap_count = gap_count_table[card->root_node->max_hops];
        else
index dbb76427d52947d64e14f6c11855dac5be698650..75388641a7d34619f1a1ec1c11aa856e5d13fe6f 100644 (file)
@@ -397,7 +397,7 @@ static int ioctl_send_request(struct client *client, void *buffer)
                        request->tcode & 0x1f,
                        device->node->node_id,
                        request->generation,
-                       device->node->max_speed,
+                       device->max_speed,
                        request->offset,
                        response->response.data, request->length,
                        complete_transaction, response);
index c1ce465d97103b3855393cd79bdfd778d531d41b..2b6586341635b9ed57dafc5f6ebb977924177010 100644 (file)
@@ -401,8 +401,7 @@ static int read_rom(struct fw_device *device, int index, u32 * data)
 
        offset = 0xfffff0000400ULL + index * 4;
        fw_send_request(device->card, &t, TCODE_READ_QUADLET_REQUEST,
-                       device->node_id,
-                       device->generation, SCODE_100,
+                       device->node_id, device->generation, device->max_speed,
                        offset, NULL, 4, complete_transaction, &callback_data);
 
        wait_for_completion(&callback_data.done);
@@ -418,6 +417,8 @@ static int read_bus_info_block(struct fw_device *device)
        u32 stack[16], sp, key;
        int i, end, length;
 
+       device->max_speed = SCODE_100;
+
        /* First read the bus info block. */
        for (i = 0; i < 5; i++) {
                if (read_rom(device, i, &rom[i]) != RCODE_COMPLETE)
@@ -434,6 +435,33 @@ static int read_bus_info_block(struct fw_device *device)
                        return -1;
        }
 
+       device->max_speed = device->node->max_speed;
+
+       /*
+        * Determine the speed of
+        *   - devices with link speed less than PHY speed,
+        *   - devices with 1394b PHY (unless only connected to 1394a PHYs),
+        *   - all devices if there are 1394b repeaters.
+        * Note, we cannot use the bus info block's link_spd as starting point
+        * because some buggy firmwares set it lower than necessary and because
+        * 1394-1995 nodes do not have the field.
+        */
+       if ((rom[2] & 0x7) < device->max_speed ||
+           device->max_speed == SCODE_BETA ||
+           device->card->beta_repeaters_present) {
+               u32 dummy;
+
+               /* for S1600 and S3200 */
+               if (device->max_speed == SCODE_BETA)
+                       device->max_speed = device->card->link_speed;
+
+               while (device->max_speed > SCODE_100) {
+                       if (read_rom(device, 0, &dummy) == RCODE_COMPLETE)
+                               break;
+                       device->max_speed--;
+               }
+       }
+
        /*
         * Now parse the config rom.  The config rom is a recursive
         * directory structure so we parse it using a stack of
@@ -680,8 +708,10 @@ static void fw_device_init(struct work_struct *work)
                    FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN)
                fw_device_shutdown(&device->work.work);
        else
-               fw_notify("created new fw device %s (%d config rom retries)\n",
-                         device->device.bus_id, device->config_rom_retries);
+               fw_notify("created new fw device %s "
+                         "(%d config rom retries, S%d00)\n",
+                         device->device.bus_id, device->config_rom_retries,
+                         1 << device->max_speed);
 
        /*
         * Reschedule the IRM work if we just finished reading the
index af1723eae4ba6d7868d521fd340de08fdd993a9b..d13e6a69707ffe6265a32fbd92efbfb0b31497d1 100644 (file)
@@ -40,6 +40,7 @@ struct fw_device {
        struct fw_node *node;
        int node_id;
        int generation;
+       unsigned max_speed;
        struct fw_card *card;
        struct device device;
        struct list_head link;
index 96c8ac5b86ccceaeed1ce0355b1f8c0c3cd1dda0..41476abc069310ce0989f546de49130d566ea736 100644 (file)
@@ -1934,12 +1934,12 @@ static int pci_suspend(struct pci_dev *pdev, pm_message_t state)
        free_irq(pdev->irq, ohci);
        err = pci_save_state(pdev);
        if (err) {
-               fw_error("pci_save_state failed with %d", err);
+               fw_error("pci_save_state failed\n");
                return err;
        }
        err = pci_set_power_state(pdev, pci_choose_state(pdev, state));
        if (err) {
-               fw_error("pci_set_power_state failed with %d", err);
+               fw_error("pci_set_power_state failed\n");
                return err;
        }
 
@@ -1955,7 +1955,7 @@ static int pci_resume(struct pci_dev *pdev)
        pci_restore_state(pdev);
        err = pci_enable_device(pdev);
        if (err) {
-               fw_error("pci_enable_device failed with %d", err);
+               fw_error("pci_enable_device failed\n");
                return err;
        }
 
index a98d3915e26f33f926d8e0c383842cb5330018db..7c53be0387fbb675b8c26453982d14a6ddf9da0d 100644 (file)
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/mod_devicetable.h>
 #include <linux/device.h>
 #include <linux/scatterlist.h>
 #include <linux/dma-mapping.h>
+#include <linux/blkdev.h>
+#include <linux/string.h>
 #include <linux/timer.h>
 
 #include <scsi/scsi.h>
 #include "fw-topology.h"
 #include "fw-device.h"
 
+/*
+ * So far only bridges from Oxford Semiconductor are known to support
+ * concurrent logins. Depending on firmware, four or two concurrent logins
+ * are possible on OXFW911 and newer Oxsemi bridges.
+ *
+ * Concurrent logins are useful together with cluster filesystems.
+ */
+static int sbp2_param_exclusive_login = 1;
+module_param_named(exclusive_login, sbp2_param_exclusive_login, bool, 0644);
+MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device "
+                "(default = Y, use N for concurrent initiators)");
+
 /* I don't know why the SCSI stack doesn't define something like this... */
 typedef void (*scsi_done_fn_t)(struct scsi_cmnd *);
 
@@ -154,7 +169,7 @@ struct sbp2_orb {
 #define MANAGEMENT_ORB_LUN(v)                  ((v))
 #define MANAGEMENT_ORB_FUNCTION(v)             ((v) << 16)
 #define MANAGEMENT_ORB_RECONNECT(v)            ((v) << 20)
-#define MANAGEMENT_ORB_EXCLUSIVE               ((1) << 28)
+#define MANAGEMENT_ORB_EXCLUSIVE(v)            ((v) ? 1 << 28 : 0)
 #define MANAGEMENT_ORB_REQUEST_FORMAT(v)       ((v) << 29)
 #define MANAGEMENT_ORB_NOTIFY                  ((1) << 31)
 
@@ -205,9 +220,8 @@ struct sbp2_command_orb {
        scsi_done_fn_t done;
        struct fw_unit *unit;
 
-       struct sbp2_pointer page_table[SG_ALL];
+       struct sbp2_pointer page_table[SG_ALL] __attribute__((aligned(8)));
        dma_addr_t page_table_bus;
-       dma_addr_t request_buffer_bus;
 };
 
 /*
@@ -347,8 +361,7 @@ sbp2_send_orb(struct sbp2_orb *orb, struct fw_unit *unit,
        spin_unlock_irqrestore(&device->card->lock, flags);
 
        fw_send_request(device->card, &orb->t, TCODE_WRITE_BLOCK_REQUEST,
-                       node_id, generation,
-                       device->node->max_speed, offset,
+                       node_id, generation, device->max_speed, offset,
                        &orb->pointer, sizeof(orb->pointer),
                        complete_transaction, orb);
 }
@@ -383,7 +396,7 @@ static void
 complete_management_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
 {
        struct sbp2_management_orb *orb =
-           (struct sbp2_management_orb *)base_orb;
+               container_of(base_orb, struct sbp2_management_orb, base);
 
        if (status)
                memcpy(&orb->status, status, sizeof(*status));
@@ -403,21 +416,11 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation,
        if (orb == NULL)
                return -ENOMEM;
 
-       /*
-        * The sbp2 device is going to send a block read request to
-        * read out the request from host memory, so map it for dma.
-        */
-       orb->base.request_bus =
-               dma_map_single(device->card->device, &orb->request,
-                              sizeof(orb->request), DMA_TO_DEVICE);
-       if (dma_mapping_error(orb->base.request_bus))
-               goto out;
-
        orb->response_bus =
                dma_map_single(device->card->device, &orb->response,
                               sizeof(orb->response), DMA_FROM_DEVICE);
        if (dma_mapping_error(orb->response_bus))
-               goto out;
+               goto fail_mapping_response;
 
        orb->request.response.high    = 0;
        orb->request.response.low     = orb->response_bus;
@@ -432,14 +435,9 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation,
        orb->request.status_fifo.high = sd->address_handler.offset >> 32;
        orb->request.status_fifo.low  = sd->address_handler.offset;
 
-       /*
-        * FIXME: Yeah, ok this isn't elegant, we hardwire exclusive
-        * login and 1 second reconnect time.  The reconnect setting
-        * is probably fine, but the exclusive login should be an option.
-        */
        if (function == SBP2_LOGIN_REQUEST) {
                orb->request.misc |=
-                       MANAGEMENT_ORB_EXCLUSIVE |
+                       MANAGEMENT_ORB_EXCLUSIVE(sbp2_param_exclusive_login) |
                        MANAGEMENT_ORB_RECONNECT(0);
        }
 
@@ -448,6 +446,12 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation,
        init_completion(&orb->done);
        orb->base.callback = complete_management_orb;
 
+       orb->base.request_bus =
+               dma_map_single(device->card->device, &orb->request,
+                              sizeof(orb->request), DMA_TO_DEVICE);
+       if (dma_mapping_error(orb->base.request_bus))
+               goto fail_mapping_request;
+
        sbp2_send_orb(&orb->base, unit,
                      node_id, generation, sd->management_agent_address);
 
@@ -479,9 +483,10 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation,
  out:
        dma_unmap_single(device->card->device, orb->base.request_bus,
                         sizeof(orb->request), DMA_TO_DEVICE);
+ fail_mapping_request:
        dma_unmap_single(device->card->device, orb->response_bus,
                         sizeof(orb->response), DMA_FROM_DEVICE);
-
+ fail_mapping_response:
        if (response)
                fw_memcpy_from_be32(response,
                                    orb->response, sizeof(orb->response));
@@ -511,7 +516,7 @@ static int sbp2_agent_reset(struct fw_unit *unit)
                return -ENOMEM;
 
        fw_send_request(device->card, t, TCODE_WRITE_QUADLET_REQUEST,
-                       sd->node_id, sd->generation, SCODE_400,
+                       sd->node_id, sd->generation, device->max_speed,
                        sd->command_block_agent_address + SBP2_AGENT_RESET,
                        &zero, sizeof(zero), complete_agent_reset_write, t);
 
@@ -521,17 +526,15 @@ static int sbp2_agent_reset(struct fw_unit *unit)
 static void sbp2_reconnect(struct work_struct *work);
 static struct scsi_host_template scsi_driver_template;
 
-static void
-release_sbp2_device(struct kref *kref)
+static void release_sbp2_device(struct kref *kref)
 {
        struct sbp2_device *sd = container_of(kref, struct sbp2_device, kref);
        struct Scsi_Host *host =
                container_of((void *)sd, struct Scsi_Host, hostdata[0]);
 
+       scsi_remove_host(host);
        sbp2_send_management_orb(sd->unit, sd->node_id, sd->generation,
                                 SBP2_LOGOUT_REQUEST, sd->login_id, NULL);
-
-       scsi_remove_host(host);
        fw_core_remove_address_handler(&sd->address_handler);
        fw_notify("removed sbp2 unit %s\n", sd->unit->device.bus_id);
        put_device(&sd->unit->device);
@@ -833,7 +836,8 @@ sbp2_status_to_sense_data(u8 *sbp2_status, u8 *sense_data)
 static void
 complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
 {
-       struct sbp2_command_orb *orb = (struct sbp2_command_orb *)base_orb;
+       struct sbp2_command_orb *orb =
+               container_of(base_orb, struct sbp2_command_orb, base);
        struct fw_unit *unit = orb->unit;
        struct fw_device *device = fw_device(unit->device.parent);
        struct scatterlist *sg;
@@ -880,12 +884,7 @@ complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
 
        if (orb->page_table_bus != 0)
                dma_unmap_single(device->card->device, orb->page_table_bus,
-                                sizeof(orb->page_table_bus), DMA_TO_DEVICE);
-
-       if (orb->request_buffer_bus != 0)
-               dma_unmap_single(device->card->device, orb->request_buffer_bus,
-                                sizeof(orb->request_buffer_bus),
-                                DMA_FROM_DEVICE);
+                                sizeof(orb->page_table), DMA_TO_DEVICE);
 
        orb->cmd->result = result;
        orb->done(orb->cmd);
@@ -900,7 +899,6 @@ static int sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb)
        struct fw_device *device = fw_device(unit->device.parent);
        struct scatterlist *sg;
        int sg_len, l, i, j, count;
-       size_t size;
        dma_addr_t sg_addr;
 
        sg = (struct scatterlist *)orb->cmd->request_buffer;
@@ -935,6 +933,11 @@ static int sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb)
                sg_len = sg_dma_len(sg + i);
                sg_addr = sg_dma_address(sg + i);
                while (sg_len) {
+                       /* FIXME: This won't get us out of the pinch. */
+                       if (unlikely(j >= ARRAY_SIZE(orb->page_table))) {
+                               fw_error("page table overflow\n");
+                               goto fail_page_table;
+                       }
                        l = min(sg_len, SBP2_MAX_SG_ELEMENT_LENGTH);
                        orb->page_table[j].low = sg_addr;
                        orb->page_table[j].high = (l << 16);
@@ -944,7 +947,13 @@ static int sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb)
                }
        }
 
-       size = sizeof(orb->page_table[0]) * j;
+       fw_memcpy_to_be32(orb->page_table, orb->page_table,
+                         sizeof(orb->page_table[0]) * j);
+       orb->page_table_bus =
+               dma_map_single(device->card->device, orb->page_table,
+                              sizeof(orb->page_table), DMA_TO_DEVICE);
+       if (dma_mapping_error(orb->page_table_bus))
+               goto fail_page_table;
 
        /*
         * The data_descriptor pointer is the one case where we need
@@ -953,20 +962,12 @@ static int sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb)
         * initiator (i.e. us), but data_descriptor can refer to data
         * on other nodes so we need to put our ID in descriptor.high.
         */
-
-       orb->page_table_bus =
-               dma_map_single(device->card->device, orb->page_table,
-                              size, DMA_TO_DEVICE);
-       if (dma_mapping_error(orb->page_table_bus))
-               goto fail_page_table;
        orb->request.data_descriptor.high = sd->address_high;
        orb->request.data_descriptor.low  = orb->page_table_bus;
        orb->request.misc |=
                COMMAND_ORB_PAGE_TABLE_PRESENT |
                COMMAND_ORB_DATA_SIZE(j);
 
-       fw_memcpy_to_be32(orb->page_table, orb->page_table, size);
-
        return 0;
 
  fail_page_table:
@@ -991,7 +992,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
         * transfer direction not handled.
         */
        if (cmd->sc_data_direction == DMA_BIDIRECTIONAL) {
-               fw_error("Cannot handle DMA_BIDIRECTIONAL - rejecting command");
+               fw_error("Can't handle DMA_BIDIRECTIONAL, rejecting command\n");
                cmd->result = DID_ERROR << 16;
                done(cmd);
                return 0;
@@ -1005,11 +1006,6 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
 
        /* Initialize rcode to something not RCODE_COMPLETE. */
        orb->base.rcode = -1;
-       orb->base.request_bus =
-               dma_map_single(device->card->device, &orb->request,
-                              sizeof(orb->request), DMA_TO_DEVICE);
-       if (dma_mapping_error(orb->base.request_bus))
-               goto fail_mapping;
 
        orb->unit = unit;
        orb->done = done;
@@ -1024,8 +1020,8 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
         * if we set this to max_speed + 7, we get the right value.
         */
        orb->request.misc =
-               COMMAND_ORB_MAX_PAYLOAD(device->node->max_speed + 7) |
-               COMMAND_ORB_SPEED(device->node->max_speed) |
+               COMMAND_ORB_MAX_PAYLOAD(device->max_speed + 7) |
+               COMMAND_ORB_SPEED(device->max_speed) |
                COMMAND_ORB_NOTIFY;
 
        if (cmd->sc_data_direction == DMA_FROM_DEVICE)
@@ -1036,7 +1032,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
                        COMMAND_ORB_DIRECTION(SBP2_DIRECTION_TO_MEDIA);
 
        if (cmd->use_sg && sbp2_command_orb_map_scatterlist(orb) < 0)
-               goto fail_map_payload;
+               goto fail_mapping;
 
        fw_memcpy_to_be32(&orb->request, &orb->request, sizeof(orb->request));
 
@@ -1045,15 +1041,17 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
        memcpy(orb->request.command_block, cmd->cmnd, COMMAND_SIZE(*cmd->cmnd));
 
        orb->base.callback = complete_command_orb;
+       orb->base.request_bus =
+               dma_map_single(device->card->device, &orb->request,
+                              sizeof(orb->request), DMA_TO_DEVICE);
+       if (dma_mapping_error(orb->base.request_bus))
+               goto fail_mapping;
 
        sbp2_send_orb(&orb->base, unit, sd->node_id, sd->generation,
                      sd->command_block_agent_address + SBP2_ORB_POINTER);
 
        return 0;
 
- fail_map_payload:
-       dma_unmap_single(device->card->device, orb->base.request_bus,
-                        sizeof(orb->request), DMA_TO_DEVICE);
  fail_mapping:
        kfree(orb);
  fail_alloc:
@@ -1087,7 +1085,8 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev)
                fw_notify("setting fix_capacity for %s\n", unit->device.bus_id);
                sdev->fix_capacity = 1;
        }
-
+       if (sd->workarounds & SBP2_WORKAROUND_128K_MAX_TRANS)
+               blk_queue_max_sectors(sdev->request_queue, 128 * 1024 / 512);
        return 0;
 }
 
index 7aebb8ae0efa0a1723ee473b653df4db977a7eaa..39e5cd12aa526176a70013f958ca6506de9a487c 100644 (file)
@@ -135,17 +135,17 @@ static void update_hop_count(struct fw_node *node)
        int i;
 
        for (i = 0; i < node->port_count; i++) {
-               if (node->ports[i].node == NULL)
+               if (node->ports[i] == NULL)
                        continue;
 
-               if (node->ports[i].node->max_hops > max_child_hops)
-                       max_child_hops = node->ports[i].node->max_hops;
+               if (node->ports[i]->max_hops > max_child_hops)
+                       max_child_hops = node->ports[i]->max_hops;
 
-               if (node->ports[i].node->max_depth > depths[0]) {
+               if (node->ports[i]->max_depth > depths[0]) {
                        depths[1] = depths[0];
-                       depths[0] = node->ports[i].node->max_depth;
-               } else if (node->ports[i].node->max_depth > depths[1])
-                       depths[1] = node->ports[i].node->max_depth;
+                       depths[0] = node->ports[i]->max_depth;
+               } else if (node->ports[i]->max_depth > depths[1])
+                       depths[1] = node->ports[i]->max_depth;
        }
 
        node->max_depth = depths[0] + 1;
@@ -172,7 +172,8 @@ static struct fw_node *build_tree(struct fw_card *card,
        struct list_head stack, *h;
        u32 *next_sid, *end, q;
        int i, port_count, child_port_count, phy_id, parent_count, stack_depth;
-       int gap_count, topology_type;
+       int gap_count;
+       bool beta_repeaters_present;
 
        local_node = NULL;
        node = NULL;
@@ -182,7 +183,7 @@ static struct fw_node *build_tree(struct fw_card *card,
        phy_id = 0;
        irm_node = NULL;
        gap_count = SELF_ID_GAP_COUNT(*sid);
-       topology_type = 0;
+       beta_repeaters_present = false;
 
        while (sid < end) {
                next_sid = count_ports(sid, &port_count, &child_port_count);
@@ -214,7 +215,7 @@ static struct fw_node *build_tree(struct fw_card *card,
 
                node = fw_node_create(q, port_count, card->color);
                if (node == NULL) {
-                       fw_error("Out of memory while building topology.");
+                       fw_error("Out of memory while building topology.\n");
                        return NULL;
                }
 
@@ -224,11 +225,6 @@ static struct fw_node *build_tree(struct fw_card *card,
                if (SELF_ID_CONTENDER(q))
                        irm_node = node;
 
-               if (node->phy_speed == SCODE_BETA)
-                       topology_type |= FW_TOPOLOGY_B;
-               else
-                       topology_type |= FW_TOPOLOGY_A;
-
                parent_count = 0;
 
                for (i = 0; i < port_count; i++) {
@@ -249,12 +245,12 @@ static struct fw_node *build_tree(struct fw_card *card,
                                break;
 
                        case SELFID_PORT_CHILD:
-                               node->ports[i].node = child;
+                               node->ports[i] = child;
                                /*
                                 * Fix up parent reference for this
                                 * child node.
                                 */
-                               child->ports[child->color].node = node;
+                               child->ports[child->color] = node;
                                child->color = card->color;
                                child = fw_node(child->link.next);
                                break;
@@ -278,6 +274,10 @@ static struct fw_node *build_tree(struct fw_card *card,
                list_add_tail(&node->link, &stack);
                stack_depth += 1 - child_port_count;
 
+               if (node->phy_speed == SCODE_BETA &&
+                   parent_count + child_port_count > 1)
+                       beta_repeaters_present = true;
+
                /*
                 * If all PHYs does not report the same gap count
                 * setting, we fall back to 63 which will force a gap
@@ -295,7 +295,7 @@ static struct fw_node *build_tree(struct fw_card *card,
        card->root_node = node;
        card->irm_node = irm_node;
        card->gap_count = gap_count;
-       card->topology_type = topology_type;
+       card->beta_repeaters_present = beta_repeaters_present;
 
        return local_node;
 }
@@ -321,7 +321,7 @@ for_each_fw_node(struct fw_card *card, struct fw_node *root,
                node->color = card->color;
 
                for (i = 0; i < node->port_count; i++) {
-                       child = node->ports[i].node;
+                       child = node->ports[i];
                        if (!child)
                                continue;
                        if (child->color == card->color)
@@ -382,11 +382,11 @@ static void move_tree(struct fw_node *node0, struct fw_node *node1, int port)
        struct fw_node *tree;
        int i;
 
-       tree = node1->ports[port].node;
-       node0->ports[port].node = tree;
+       tree = node1->ports[port];
+       node0->ports[port] = tree;
        for (i = 0; i < tree->port_count; i++) {
-               if (tree->ports[i].node == node1) {
-                       tree->ports[i].node = node0;
+               if (tree->ports[i] == node1) {
+                       tree->ports[i] = node0;
                        break;
                }
        }
@@ -437,19 +437,17 @@ update_tree(struct fw_card *card, struct fw_node *root)
                        card->irm_node = node0;
 
                for (i = 0; i < node0->port_count; i++) {
-                       if (node0->ports[i].node && node1->ports[i].node) {
+                       if (node0->ports[i] && node1->ports[i]) {
                                /*
                                 * This port didn't change, queue the
                                 * connected node for further
                                 * investigation.
                                 */
-                               if (node0->ports[i].node->color == card->color)
+                               if (node0->ports[i]->color == card->color)
                                        continue;
-                               list_add_tail(&node0->ports[i].node->link,
-                                             &list0);
-                               list_add_tail(&node1->ports[i].node->link,
-                                             &list1);
-                       } else if (node0->ports[i].node) {
+                               list_add_tail(&node0->ports[i]->link, &list0);
+                               list_add_tail(&node1->ports[i]->link, &list1);
+                       } else if (node0->ports[i]) {
                                /*
                                 * The nodes connected here were
                                 * unplugged; unref the lost nodes and
@@ -457,10 +455,10 @@ update_tree(struct fw_card *card, struct fw_node *root)
                                 * them.
                                 */
 
-                               for_each_fw_node(card, node0->ports[i].node,
+                               for_each_fw_node(card, node0->ports[i],
                                                 report_lost_node);
-                               node0->ports[i].node = NULL;
-                       } else if (node1->ports[i].node) {
+                               node0->ports[i] = NULL;
+                       } else if (node1->ports[i]) {
                                /*
                                 * One or more node were connected to
                                 * this port. Move the new nodes into
@@ -468,7 +466,7 @@ update_tree(struct fw_card *card, struct fw_node *root)
                                 * callbacks for them.
                                 */
                                move_tree(node0, node1, i);
-                               for_each_fw_node(card, node0->ports[i].node,
+                               for_each_fw_node(card, node0->ports[i],
                                                 report_found_node);
                        }
                }
index 363b6cbcd0b335087fba9701cd22b7bc2ea04975..1b56b4ac7fb2c0298830544a31fc5d4b2909d2b7 100644 (file)
 #ifndef __fw_topology_h
 #define __fw_topology_h
 
-enum {
-       FW_TOPOLOGY_A =         0x01,
-       FW_TOPOLOGY_B =         0x02,
-       FW_TOPOLOGY_MIXED =     0x03,
-};
-
 enum {
        FW_NODE_CREATED =   0x00,
        FW_NODE_UPDATED =   0x01,
@@ -33,21 +27,16 @@ enum {
        FW_NODE_LINK_OFF =  0x04,
 };
 
-struct fw_port {
-       struct fw_node *node;
-       unsigned speed : 3; /* S100, S200, ... S3200 */
-};
-
 struct fw_node {
        u16 node_id;
        u8 color;
        u8 port_count;
-       unsigned link_on : 1;
-       unsigned initiated_reset : 1;
-       unsigned b_path : 1;
-       u8 phy_speed : 3; /* As in the self ID packet. */
-       u8 max_speed : 5; /* Minimum of all phy-speeds and port speeds on
-                          * the path from the local node to this node. */
+       u8 link_on : 1;
+       u8 initiated_reset : 1;
+       u8 b_path : 1;
+       u8 phy_speed : 2; /* As in the self ID packet. */
+       u8 max_speed : 2; /* Minimum of all phy-speeds on the path from the
+                          * local node to this node. */
        u8 max_depth : 4; /* Maximum depth to any leaf node */
        u8 max_hops : 4;  /* Max hops in this sub tree */
        atomic_t ref_count;
@@ -58,7 +47,7 @@ struct fw_node {
        /* Upper layer specific data. */
        void *data;
 
-       struct fw_port ports[0];
+       struct fw_node *ports[0];
 };
 
 static inline struct fw_node *
index acdc3be38c613af6ba6a6a4a0eae5921ac1cca3a..5abed193f4a65deb8c6ab3f27355a03a9d3092e8 100644 (file)
@@ -81,7 +81,6 @@
 
 #define fw_notify(s, args...) printk(KERN_NOTICE KBUILD_MODNAME ": " s, ## args)
 #define fw_error(s, args...) printk(KERN_ERR KBUILD_MODNAME ": " s, ## args)
-#define fw_debug(s, args...) printk(KERN_DEBUG KBUILD_MODNAME ": " s, ## args)
 
 static inline void
 fw_memcpy_from_be32(void *_dst, void *_src, size_t size)
@@ -246,7 +245,7 @@ struct fw_card {
        struct fw_node *irm_node;
        int color;
        int gap_count;
-       int topology_type;
+       bool beta_repeaters_present;
 
        int index;
 
index 88f462122a30fea0c4516de34891fcb433538182..05f02a326f1c6283277964f307873df9cb5a5489 100644 (file)
@@ -84,4 +84,13 @@ config DCDBAS
          Say Y or M here to enable the driver for use by Dell systems
          management software such as Dell OpenManage.
 
+config DMIID
+    bool "Export DMI identification via sysfs to userspace"
+    depends on DMI
+    default y
+       help
+         Say Y here if you want to query SMBIOS/DMI system identification
+         information from userspace through /sys/class/dmi/id/ or if you want
+         DMI-based module auto-loading.
+
 endmenu
index 98e395f4bb29e8a37233f737f72fa5564208843d..8d4ebc805a505cae9ff188fc24604e88e058be60 100644 (file)
@@ -7,3 +7,4 @@ obj-$(CONFIG_EFI_VARS)          += efivars.o
 obj-$(CONFIG_EFI_PCDP)         += pcdp.o
 obj-$(CONFIG_DELL_RBU)          += dell_rbu.o
 obj-$(CONFIG_DCDBAS)           += dcdbas.o
+obj-$(CONFIG_DMIID)            += dmi-id.o
index 1865b56fb141643878b50b4874c4be56f612ff0c..18cdcb3ae1ca3d11131b0cf9498086a25066ec14 100644 (file)
@@ -149,8 +149,9 @@ static ssize_t smi_data_buf_size_store(struct device *dev,
        return count;
 }
 
-static ssize_t smi_data_read(struct kobject *kobj, char *buf, loff_t pos,
-                            size_t count)
+static ssize_t smi_data_read(struct kobject *kobj,
+                            struct bin_attribute *bin_attr,
+                            char *buf, loff_t pos, size_t count)
 {
        size_t max_read;
        ssize_t ret;
@@ -170,8 +171,9 @@ out:
        return ret;
 }
 
-static ssize_t smi_data_write(struct kobject *kobj, char *buf, loff_t pos,
-                             size_t count)
+static ssize_t smi_data_write(struct kobject *kobj,
+                             struct bin_attribute *bin_attr,
+                             char *buf, loff_t pos, size_t count)
 {
        ssize_t ret;
 
index 58a85182b3e8d589d704000a25cfc5ecfab23351..dcdba0f1b32c835cdcd37d0d2cb975442ab31348 100644 (file)
@@ -67,8 +67,7 @@
 #define DCDBAS_BIN_ATTR_RW(_name) \
 struct bin_attribute bin_attr_##_name = { \
        .attr =  { .name = __stringify(_name), \
-                  .mode = 0600, \
-                  .owner = THIS_MODULE }, \
+                  .mode = 0600 }, \
        .read =  _name##_read, \
        .write = _name##_write, \
 }
index fc702e40bd431c2cfdd715beacd636fb3d886c49..477a3d0e3caf83ccffb2cf472375cafcc799733e 100644 (file)
@@ -543,8 +543,9 @@ static ssize_t read_rbu_mono_data(char *buffer, loff_t pos, size_t count)
        return ret_count;
 }
 
-static ssize_t read_rbu_data(struct kobject *kobj, char *buffer,
-       loff_t pos, size_t count)
+static ssize_t read_rbu_data(struct kobject *kobj,
+                            struct bin_attribute *bin_attr,
+                            char *buffer, loff_t pos, size_t count)
 {
        ssize_t ret_count = 0;
 
@@ -591,8 +592,9 @@ static void callbackfn_rbu(const struct firmware *fw, void *context)
        spin_unlock(&rbu_data.lock);
 }
 
-static ssize_t read_rbu_image_type(struct kobject *kobj, char *buffer,
-       loff_t pos, size_t count)
+static ssize_t read_rbu_image_type(struct kobject *kobj,
+                                  struct bin_attribute *bin_attr,
+                                  char *buffer, loff_t pos, size_t count)
 {
        int size = 0;
        if (!pos)
@@ -600,8 +602,9 @@ static ssize_t read_rbu_image_type(struct kobject *kobj, char *buffer,
        return size;
 }
 
-static ssize_t write_rbu_image_type(struct kobject *kobj, char *buffer,
-       loff_t pos, size_t count)
+static ssize_t write_rbu_image_type(struct kobject *kobj,
+                                   struct bin_attribute *bin_attr,
+                                   char *buffer, loff_t pos, size_t count)
 {
        int rc = count;
        int req_firm_rc = 0;
@@ -660,8 +663,9 @@ static ssize_t write_rbu_image_type(struct kobject *kobj, char *buffer,
        return rc;
 }
 
-static ssize_t read_rbu_packet_size(struct kobject *kobj, char *buffer,
-       loff_t pos, size_t count)
+static ssize_t read_rbu_packet_size(struct kobject *kobj,
+                                   struct bin_attribute *bin_attr,
+                                   char *buffer, loff_t pos, size_t count)
 {
        int size = 0;
        if (!pos) {
@@ -672,8 +676,9 @@ static ssize_t read_rbu_packet_size(struct kobject *kobj, char *buffer,
        return size;
 }
 
-static ssize_t write_rbu_packet_size(struct kobject *kobj, char *buffer,
-       loff_t pos, size_t count)
+static ssize_t write_rbu_packet_size(struct kobject *kobj,
+                                    struct bin_attribute *bin_attr,
+                                    char *buffer, loff_t pos, size_t count)
 {
        unsigned long temp;
        spin_lock(&rbu_data.lock);
@@ -687,18 +692,18 @@ static ssize_t write_rbu_packet_size(struct kobject *kobj, char *buffer,
 }
 
 static struct bin_attribute rbu_data_attr = {
-       .attr = {.name = "data",.owner = THIS_MODULE,.mode = 0444},
+       .attr = {.name = "data", .mode = 0444},
        .read = read_rbu_data,
 };
 
 static struct bin_attribute rbu_image_type_attr = {
-       .attr = {.name = "image_type",.owner = THIS_MODULE,.mode = 0644},
+       .attr = {.name = "image_type", .mode = 0644},
        .read = read_rbu_image_type,
        .write = write_rbu_image_type,
 };
 
 static struct bin_attribute rbu_packet_size_attr = {
-       .attr = {.name = "packet_size",.owner = THIS_MODULE,.mode = 0644},
+       .attr = {.name = "packet_size", .mode = 0644},
        .read = read_rbu_packet_size,
        .write = write_rbu_packet_size,
 };
diff --git a/drivers/firmware/dmi-id.c b/drivers/firmware/dmi-id.c
new file mode 100644 (file)
index 0000000..59c3b5a
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ * Export SMBIOS/DMI info via sysfs to userspace
+ *
+ * Copyright 2007, Lennart Poettering
+ *
+ * Licensed under GPLv2
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/dmi.h>
+#include <linux/device.h>
+#include <linux/autoconf.h>
+
+#define DEFINE_DMI_ATTR(_name, _mode, _show)           \
+static struct device_attribute sys_dmi_##_name##_attr =        \
+       __ATTR(_name, _mode, _show, NULL);
+
+#define DEFINE_DMI_ATTR_WITH_SHOW(_name, _mode, _field)                        \
+static ssize_t sys_dmi_##_name##_show(struct device *dev,              \
+                                     struct device_attribute *attr,    \
+                                     char *page)                       \
+{                                                                      \
+       ssize_t len;                                                    \
+       len = scnprintf(page, PAGE_SIZE, "%s\n", dmi_get_system_info(_field)); \
+       page[len-1] = '\n';                                             \
+       return len;                                                     \
+}                                                                      \
+DEFINE_DMI_ATTR(_name, _mode, sys_dmi_##_name##_show);
+
+DEFINE_DMI_ATTR_WITH_SHOW(bios_vendor,         0444, DMI_BIOS_VENDOR);
+DEFINE_DMI_ATTR_WITH_SHOW(bios_version,                0444, DMI_BIOS_VERSION);
+DEFINE_DMI_ATTR_WITH_SHOW(bios_date,           0444, DMI_BIOS_DATE);
+DEFINE_DMI_ATTR_WITH_SHOW(sys_vendor,          0444, DMI_SYS_VENDOR);
+DEFINE_DMI_ATTR_WITH_SHOW(product_name,                0444, DMI_PRODUCT_NAME);
+DEFINE_DMI_ATTR_WITH_SHOW(product_version,     0444, DMI_PRODUCT_VERSION);
+DEFINE_DMI_ATTR_WITH_SHOW(product_serial,      0400, DMI_PRODUCT_SERIAL);
+DEFINE_DMI_ATTR_WITH_SHOW(product_uuid,                0400, DMI_PRODUCT_UUID);
+DEFINE_DMI_ATTR_WITH_SHOW(board_vendor,                0444, DMI_BOARD_VENDOR);
+DEFINE_DMI_ATTR_WITH_SHOW(board_name,          0444, DMI_BOARD_NAME);
+DEFINE_DMI_ATTR_WITH_SHOW(board_version,       0444, DMI_BOARD_VERSION);
+DEFINE_DMI_ATTR_WITH_SHOW(board_serial,                0400, DMI_BOARD_SERIAL);
+DEFINE_DMI_ATTR_WITH_SHOW(board_asset_tag,     0444, DMI_BOARD_ASSET_TAG);
+DEFINE_DMI_ATTR_WITH_SHOW(chassis_vendor,      0444, DMI_CHASSIS_VENDOR);
+DEFINE_DMI_ATTR_WITH_SHOW(chassis_type,                0444, DMI_CHASSIS_TYPE);
+DEFINE_DMI_ATTR_WITH_SHOW(chassis_version,     0444, DMI_CHASSIS_VERSION);
+DEFINE_DMI_ATTR_WITH_SHOW(chassis_serial,      0400, DMI_CHASSIS_SERIAL);
+DEFINE_DMI_ATTR_WITH_SHOW(chassis_asset_tag,   0444, DMI_CHASSIS_ASSET_TAG);
+
+static void ascii_filter(char *d, const char *s)
+{
+       /* Filter out characters we don't want to see in the modalias string */
+       for (; *s; s++)
+               if (*s > ' ' && *s < 127 && *s != ':')
+                       *(d++) = *s;
+
+       *d = 0;
+}
+
+static ssize_t get_modalias(char *buffer, size_t buffer_size)
+{
+       static const struct mafield {
+               const char *prefix;
+               int field;
+       } fields[] = {
+               { "bvn", DMI_BIOS_VENDOR },
+               { "bvr", DMI_BIOS_VERSION },
+               { "bd",  DMI_BIOS_DATE },
+               { "svn", DMI_SYS_VENDOR },
+               { "pn",  DMI_PRODUCT_NAME },
+               { "pvr", DMI_PRODUCT_VERSION },
+               { "rvn", DMI_BOARD_VENDOR },
+               { "rn",  DMI_BOARD_NAME },
+               { "rvr", DMI_BOARD_VERSION },
+               { "cvn", DMI_CHASSIS_VENDOR },
+               { "ct",  DMI_CHASSIS_TYPE },
+               { "cvr", DMI_CHASSIS_VERSION },
+               { NULL,  DMI_NONE }
+       };
+
+       ssize_t l, left;
+       char *p;
+       const struct mafield *f;
+
+       strcpy(buffer, "dmi");
+       p = buffer + 3; left = buffer_size - 4;
+
+       for (f = fields; f->prefix && left > 0; f++) {
+               const char *c;
+               char *t;
+
+               c = dmi_get_system_info(f->field);
+               if (!c)
+                       continue;
+
+               t = kmalloc(strlen(c) + 1, GFP_KERNEL);
+               if (!t)
+                       break;
+               ascii_filter(t, c);
+               l = scnprintf(p, left, ":%s%s", f->prefix, t);
+               kfree(t);
+
+               p += l;
+               left -= l;
+       }
+
+       p[0] = ':';
+       p[1] = 0;
+
+       return p - buffer + 1;
+}
+
+static ssize_t sys_dmi_modalias_show(struct device *dev,
+                                    struct device_attribute *attr, char *page)
+{
+       ssize_t r;
+       r = get_modalias(page, PAGE_SIZE-1);
+       page[r] = '\n';
+       page[r+1] = 0;
+       return r+1;
+}
+
+DEFINE_DMI_ATTR(modalias, 0444, sys_dmi_modalias_show);
+
+static struct attribute *sys_dmi_attributes[DMI_STRING_MAX+2];
+
+static struct attribute_group sys_dmi_attribute_group = {
+       .attrs = sys_dmi_attributes,
+};
+
+static struct attribute_group* sys_dmi_attribute_groups[] = {
+       &sys_dmi_attribute_group,
+       NULL
+};
+
+static int dmi_dev_uevent(struct device *dev, char **envp,
+                           int num_envp, char *buffer, int buffer_size)
+{
+       strcpy(buffer, "MODALIAS=");
+       get_modalias(buffer+9, buffer_size-9);
+       envp[0] = buffer;
+       envp[1] = NULL;
+
+       return 0;
+}
+
+static struct class dmi_class = {
+       .name = "dmi",
+       .dev_release = (void(*)(struct device *)) kfree,
+       .dev_uevent = dmi_dev_uevent,
+};
+
+static struct device *dmi_dev;
+
+/* Initialization */
+
+#define ADD_DMI_ATTR(_name, _field) \
+       if (dmi_get_system_info(_field)) \
+               sys_dmi_attributes[i++] = & sys_dmi_##_name##_attr.attr;
+
+extern int dmi_available;
+
+static int __init dmi_id_init(void)
+{
+       int ret, i;
+
+       if (!dmi_available)
+               return -ENODEV;
+
+       /* Not necessarily all DMI fields are available on all
+        * systems, hence let's built an attribute table of just
+        * what's available */
+       i = 0;
+       ADD_DMI_ATTR(bios_vendor,       DMI_BIOS_VENDOR);
+       ADD_DMI_ATTR(bios_version,      DMI_BIOS_VERSION);
+       ADD_DMI_ATTR(bios_date,         DMI_BIOS_DATE);
+       ADD_DMI_ATTR(sys_vendor,        DMI_SYS_VENDOR);
+       ADD_DMI_ATTR(product_name,      DMI_PRODUCT_NAME);
+       ADD_DMI_ATTR(product_version,   DMI_PRODUCT_VERSION);
+       ADD_DMI_ATTR(product_serial,    DMI_PRODUCT_SERIAL);
+       ADD_DMI_ATTR(product_uuid,      DMI_PRODUCT_UUID);
+       ADD_DMI_ATTR(board_vendor,      DMI_BOARD_VENDOR);
+       ADD_DMI_ATTR(board_name,        DMI_BOARD_NAME);
+       ADD_DMI_ATTR(board_version,     DMI_BOARD_VERSION);
+       ADD_DMI_ATTR(board_serial,      DMI_BOARD_SERIAL);
+       ADD_DMI_ATTR(board_asset_tag,   DMI_BOARD_ASSET_TAG);
+       ADD_DMI_ATTR(chassis_vendor,    DMI_CHASSIS_VENDOR);
+       ADD_DMI_ATTR(chassis_type,      DMI_CHASSIS_TYPE);
+       ADD_DMI_ATTR(chassis_version,   DMI_CHASSIS_VERSION);
+       ADD_DMI_ATTR(chassis_serial,    DMI_CHASSIS_SERIAL);
+       ADD_DMI_ATTR(chassis_asset_tag, DMI_CHASSIS_ASSET_TAG);
+       sys_dmi_attributes[i++] = &sys_dmi_modalias_attr.attr;
+
+       ret = class_register(&dmi_class);
+       if (ret)
+               return ret;
+
+       dmi_dev = kzalloc(sizeof(*dmi_dev), GFP_KERNEL);
+       if (!dmi_dev) {
+               ret = -ENOMEM;
+               goto fail_class_unregister;
+       }
+
+       dmi_dev->class = &dmi_class;
+       strcpy(dmi_dev->bus_id, "id");
+       dmi_dev->groups = sys_dmi_attribute_groups;
+
+       ret = device_register(dmi_dev);
+       if (ret)
+               goto fail_class_unregister;
+
+       return 0;
+
+fail_class_unregister:
+
+       class_unregister(&dmi_class);
+
+       return ret;
+}
+
+arch_initcall(dmi_id_init);
index 37deee6c0c1cc5aa4ca575797dea77d6ad792243..f7318b3b51f2a0860bf2f952896d60f746bd98a8 100644 (file)
@@ -84,6 +84,7 @@ static int __init dmi_checksum(u8 *buf)
 
 static char *dmi_ident[DMI_STRING_MAX];
 static LIST_HEAD(dmi_devices);
+int dmi_available;
 
 /*
  *     Save a DMI string
@@ -102,6 +103,51 @@ static void __init dmi_save_ident(struct dmi_header *dm, int slot, int string)
        dmi_ident[slot] = p;
 }
 
+static void __init dmi_save_uuid(struct dmi_header *dm, int slot, int index)
+{
+       u8 *d = (u8*) dm + index;
+       char *s;
+       int is_ff = 1, is_00 = 1, i;
+
+       if (dmi_ident[slot])
+               return;
+
+       for (i = 0; i < 16 && (is_ff || is_00); i++) {
+               if(d[i] != 0x00) is_ff = 0;
+               if(d[i] != 0xFF) is_00 = 0;
+       }
+
+       if (is_ff || is_00)
+               return;
+
+       s = dmi_alloc(16*2+4+1);
+       if (!s)
+               return;
+
+       sprintf(s,
+               "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
+               d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7],
+               d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
+
+        dmi_ident[slot] = s;
+}
+
+static void __init dmi_save_type(struct dmi_header *dm, int slot, int index)
+{
+       u8 *d = (u8*) dm + index;
+       char *s;
+
+       if (dmi_ident[slot])
+               return;
+
+       s = dmi_alloc(4);
+       if (!s)
+               return;
+
+       sprintf(s, "%u", *d & 0x7F);
+       dmi_ident[slot] = s;
+}
+
 static void __init dmi_save_devices(struct dmi_header *dm)
 {
        int i, count = (dm->length - sizeof(struct dmi_header)) / 2;
@@ -192,11 +238,21 @@ static void __init dmi_decode(struct dmi_header *dm)
                dmi_save_ident(dm, DMI_PRODUCT_NAME, 5);
                dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6);
                dmi_save_ident(dm, DMI_PRODUCT_SERIAL, 7);
+               dmi_save_uuid(dm, DMI_PRODUCT_UUID, 8);
                break;
        case 2:         /* Base Board Information */
                dmi_save_ident(dm, DMI_BOARD_VENDOR, 4);
                dmi_save_ident(dm, DMI_BOARD_NAME, 5);
                dmi_save_ident(dm, DMI_BOARD_VERSION, 6);
+               dmi_save_ident(dm, DMI_BOARD_SERIAL, 7);
+               dmi_save_ident(dm, DMI_BOARD_ASSET_TAG, 8);
+               break;
+       case 3:         /* Chassis Information */
+               dmi_save_ident(dm, DMI_CHASSIS_VENDOR, 4);
+               dmi_save_type(dm, DMI_CHASSIS_TYPE, 5);
+               dmi_save_ident(dm, DMI_CHASSIS_VERSION, 6);
+               dmi_save_ident(dm, DMI_CHASSIS_SERIAL, 7);
+               dmi_save_ident(dm, DMI_CHASSIS_ASSET_TAG, 8);
                break;
        case 10:        /* Onboard Devices Information */
                dmi_save_devices(dm);
@@ -243,18 +299,20 @@ void __init dmi_scan_machine(void)
                if (efi.smbios == EFI_INVALID_TABLE_ADDR)
                        goto out;
 
-               /* This is called as a core_initcall() because it isn't
-                * needed during early boot.  This also means we can
-                * iounmap the space when we're done with it.
-               */
+               /* This is called as a core_initcall() because it isn't
+                * needed during early boot.  This also means we can
+                * iounmap the space when we're done with it.
+                */
                p = dmi_ioremap(efi.smbios, 32);
                if (p == NULL)
                        goto out;
 
                rc = dmi_present(p + 0x10); /* offset of _DMI_ string */
                dmi_iounmap(p, 32);
-               if (!rc)
+               if (!rc) {
+                       dmi_available = 1;
                        return;
+               }
        }
        else {
                /*
@@ -268,8 +326,10 @@ void __init dmi_scan_machine(void)
 
                for (q = p; q < p + 0x10000; q += 16) {
                        rc = dmi_present(q);
-                       if (!rc)
+                       if (!rc) {
+                               dmi_available = 1;
                                return;
+                       }
                }
        }
  out:  printk(KERN_INFO "DMI not present or invalid.\n");
@@ -404,3 +464,4 @@ int dmi_get_year(int field)
 
        return year;
 }
+
index d8806e4f182984c841603d8d3d365c77d98c6cec..15232271d848c225364df28d17b10dc7d60217be 100644 (file)
@@ -74,7 +74,7 @@ static struct edd_device *edd_devices[EDD_MBR_SIG_MAX];
 
 #define EDD_DEVICE_ATTR(_name,_mode,_show,_test) \
 struct edd_attribute edd_attr_##_name = {      \
-       .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE },     \
+       .attr = {.name = __stringify(_name), .mode = _mode },   \
        .show   = _show,                                \
        .test   = _test,                                \
 };
index 1324984a4c355e1accf093f05608c0d214579303..bfd2d67df689d8ccb33138c78935b73ae7363d31 100644 (file)
@@ -131,21 +131,21 @@ struct efivar_attribute {
 
 #define EFI_ATTR(_name, _mode, _show, _store) \
 struct subsys_attribute efi_attr_##_name = { \
-       .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE}, \
+       .attr = {.name = __stringify(_name), .mode = _mode}, \
        .show = _show, \
        .store = _store, \
 };
 
 #define EFIVAR_ATTR(_name, _mode, _show, _store) \
 struct efivar_attribute efivar_attr_##_name = { \
-       .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE}, \
+       .attr = {.name = __stringify(_name), .mode = _mode}, \
        .show = _show, \
        .store = _store, \
 };
 
 #define VAR_SUBSYS_ATTR(_name, _mode, _show, _store) \
 struct subsys_attribute var_subsys_attr_##_name = { \
-       .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE}, \
+       .attr = {.name = __stringify(_name), .mode = _mode}, \
        .show = _show, \
        .store = _store, \
 };
index 8fbe9fdac128ea232099499729f80693b3aa0acf..3b63b0b7812206e643fb0cc73b1070bc65e84cca 100644 (file)
@@ -1,8 +1,12 @@
 #
 # HID driver configuration
 #
-menu "HID Devices"
+menuconfig HID_SUPPORT
+       bool "HID Devices"
        depends on INPUT
+       default y
+
+if HID_SUPPORT
 
 config HID
        tristate "Generic HID support"
@@ -24,6 +28,7 @@ config HID
 
 config HID_DEBUG
        bool "HID debugging support"
+       default y if !EMBEDDED
        depends on HID
        ---help---
        This option lets the HID layer output diagnostics about its internal
@@ -38,5 +43,4 @@ config HID_DEBUG
 
 source "drivers/hid/usbhid/Kconfig"
 
-endmenu
-
+endif # HID_SUPPORT
index 6ec04e79f6856c0340f20a31f0b08bb9b6afeeb6..317cf8a7b63c11ed03e76772c8c8710a3ec5505c 100644 (file)
 #define DRIVER_DESC "HID core driver"
 #define DRIVER_LICENSE "GPL"
 
+#ifdef CONFIG_HID_DEBUG
+int hid_debug = 0;
+module_param_named(debug, hid_debug, bool, 0600);
+MODULE_PARM_DESC(debug, "Turn HID debugging mode on and off");
+EXPORT_SYMBOL_GPL(hid_debug);
+#endif
+
 /*
  * Register a new report for a device.
  */
@@ -78,7 +85,7 @@ static struct hid_field *hid_register_field(struct hid_report *report, unsigned
        struct hid_field *field;
 
        if (report->maxfield == HID_MAX_FIELDS) {
-               dbg("too many fields in report");
+               dbg_hid("too many fields in report\n");
                return NULL;
        }
 
@@ -106,7 +113,7 @@ static int open_collection(struct hid_parser *parser, unsigned type)
        usage = parser->local.usage[0];
 
        if (parser->collection_stack_ptr == HID_COLLECTION_STACK_SIZE) {
-               dbg("collection stack overflow");
+               dbg_hid("collection stack overflow\n");
                return -1;
        }
 
@@ -114,7 +121,7 @@ static int open_collection(struct hid_parser *parser, unsigned type)
                collection = kmalloc(sizeof(struct hid_collection) *
                                parser->device->collection_size * 2, GFP_KERNEL);
                if (collection == NULL) {
-                       dbg("failed to reallocate collection array");
+                       dbg_hid("failed to reallocate collection array\n");
                        return -1;
                }
                memcpy(collection, parser->device->collection,
@@ -150,7 +157,7 @@ static int open_collection(struct hid_parser *parser, unsigned type)
 static int close_collection(struct hid_parser *parser)
 {
        if (!parser->collection_stack_ptr) {
-               dbg("collection stack underflow");
+               dbg_hid("collection stack underflow\n");
                return -1;
        }
        parser->collection_stack_ptr--;
@@ -178,7 +185,7 @@ static unsigned hid_lookup_collection(struct hid_parser *parser, unsigned type)
 static int hid_add_usage(struct hid_parser *parser, unsigned usage)
 {
        if (parser->local.usage_index >= HID_MAX_USAGES) {
-               dbg("usage index exceeded");
+               dbg_hid("usage index exceeded\n");
                return -1;
        }
        parser->local.usage[parser->local.usage_index] = usage;
@@ -202,12 +209,12 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign
        int i;
 
        if (!(report = hid_register_report(parser->device, report_type, parser->global.report_id))) {
-               dbg("hid_register_report failed");
+               dbg_hid("hid_register_report failed\n");
                return -1;
        }
 
        if (parser->global.logical_maximum < parser->global.logical_minimum) {
-               dbg("logical range invalid %d %d", parser->global.logical_minimum, parser->global.logical_maximum);
+               dbg_hid("logical range invalid %d %d\n", parser->global.logical_minimum, parser->global.logical_maximum);
                return -1;
        }
 
@@ -287,7 +294,7 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
                case HID_GLOBAL_ITEM_TAG_PUSH:
 
                        if (parser->global_stack_ptr == HID_GLOBAL_STACK_SIZE) {
-                               dbg("global enviroment stack overflow");
+                               dbg_hid("global enviroment stack overflow\n");
                                return -1;
                        }
 
@@ -298,7 +305,7 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
                case HID_GLOBAL_ITEM_TAG_POP:
 
                        if (!parser->global_stack_ptr) {
-                               dbg("global enviroment stack underflow");
+                               dbg_hid("global enviroment stack underflow\n");
                                return -1;
                        }
 
@@ -342,27 +349,27 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
 
                case HID_GLOBAL_ITEM_TAG_REPORT_SIZE:
                        if ((parser->global.report_size = item_udata(item)) > 32) {
-                               dbg("invalid report_size %d", parser->global.report_size);
+                               dbg_hid("invalid report_size %d\n", parser->global.report_size);
                                return -1;
                        }
                        return 0;
 
                case HID_GLOBAL_ITEM_TAG_REPORT_COUNT:
                        if ((parser->global.report_count = item_udata(item)) > HID_MAX_USAGES) {
-                               dbg("invalid report_count %d", parser->global.report_count);
+                               dbg_hid("invalid report_count %d\n", parser->global.report_count);
                                return -1;
                        }
                        return 0;
 
                case HID_GLOBAL_ITEM_TAG_REPORT_ID:
                        if ((parser->global.report_id = item_udata(item)) == 0) {
-                               dbg("report_id 0 is invalid");
+                               dbg_hid("report_id 0 is invalid\n");
                                return -1;
                        }
                        return 0;
 
                default:
-                       dbg("unknown global tag 0x%x", item->tag);
+                       dbg_hid("unknown global tag 0x%x\n", item->tag);
                        return -1;
        }
 }
@@ -377,7 +384,7 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
        unsigned n;
 
        if (item->size == 0) {
-               dbg("item data expected for local item");
+               dbg_hid("item data expected for local item\n");
                return -1;
        }
 
@@ -395,14 +402,14 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
                                 * items and the first delimiter set.
                                 */
                                if (parser->local.delimiter_depth != 0) {
-                                       dbg("nested delimiters");
+                                       dbg_hid("nested delimiters\n");
                                        return -1;
                                }
                                parser->local.delimiter_depth++;
                                parser->local.delimiter_branch++;
                        } else {
                                if (parser->local.delimiter_depth < 1) {
-                                       dbg("bogus close delimiter");
+                                       dbg_hid("bogus close delimiter\n");
                                        return -1;
                                }
                                parser->local.delimiter_depth--;
@@ -412,7 +419,7 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
                case HID_LOCAL_ITEM_TAG_USAGE:
 
                        if (parser->local.delimiter_branch > 1) {
-                               dbg("alternative usage ignored");
+                               dbg_hid("alternative usage ignored\n");
                                return 0;
                        }
 
@@ -424,7 +431,7 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
                case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM:
 
                        if (parser->local.delimiter_branch > 1) {
-                               dbg("alternative usage ignored");
+                               dbg_hid("alternative usage ignored\n");
                                return 0;
                        }
 
@@ -437,7 +444,7 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
                case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM:
 
                        if (parser->local.delimiter_branch > 1) {
-                               dbg("alternative usage ignored");
+                               dbg_hid("alternative usage ignored\n");
                                return 0;
                        }
 
@@ -446,14 +453,14 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
 
                        for (n = parser->local.usage_minimum; n <= data; n++)
                                if (hid_add_usage(parser, n)) {
-                                       dbg("hid_add_usage failed\n");
+                                       dbg_hid("hid_add_usage failed\n");
                                        return -1;
                                }
                        return 0;
 
                default:
 
-                       dbg("unknown local item tag 0x%x", item->tag);
+                       dbg_hid("unknown local item tag 0x%x\n", item->tag);
                        return 0;
        }
        return 0;
@@ -487,7 +494,7 @@ static int hid_parser_main(struct hid_parser *parser, struct hid_item *item)
                        ret = hid_add_field(parser, HID_FEATURE_REPORT, data);
                        break;
                default:
-                       dbg("unknown main item tag 0x%x", item->tag);
+                       dbg_hid("unknown main item tag 0x%x\n", item->tag);
                        ret = 0;
        }
 
@@ -502,7 +509,7 @@ static int hid_parser_main(struct hid_parser *parser, struct hid_item *item)
 
 static int hid_parser_reserved(struct hid_parser *parser, struct hid_item *item)
 {
-       dbg("reserved item type, tag 0x%x", item->tag);
+       dbg_hid("reserved item type, tag 0x%x\n", item->tag);
        return 0;
 }
 
@@ -667,14 +674,14 @@ struct hid_device *hid_parse_report(__u8 *start, unsigned size)
        while ((start = fetch_item(start, end, &item)) != NULL) {
 
                if (item.format != HID_ITEM_FORMAT_SHORT) {
-                       dbg("unexpected long global item");
+                       dbg_hid("unexpected long global item\n");
                        hid_free_device(device);
                        vfree(parser);
                        return NULL;
                }
 
                if (dispatch_type[item.type](parser, &item)) {
-                       dbg("item %u %u %u %u parsing failed\n",
+                       dbg_hid("item %u %u %u %u parsing failed\n",
                                item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag);
                        hid_free_device(device);
                        vfree(parser);
@@ -683,13 +690,13 @@ struct hid_device *hid_parse_report(__u8 *start, unsigned size)
 
                if (start == end) {
                        if (parser->collection_stack_ptr) {
-                               dbg("unbalanced collection at end of report description");
+                               dbg_hid("unbalanced collection at end of report description\n");
                                hid_free_device(device);
                                vfree(parser);
                                return NULL;
                        }
                        if (parser->local.delimiter_depth) {
-                               dbg("unbalanced delimiter at end of report description");
+                               dbg_hid("unbalanced delimiter at end of report description\n");
                                hid_free_device(device);
                                vfree(parser);
                                return NULL;
@@ -699,7 +706,7 @@ struct hid_device *hid_parse_report(__u8 *start, unsigned size)
                }
        }
 
-       dbg("item fetching failed at offset %d\n", (int)(end - start));
+       dbg_hid("item fetching failed at offset %d\n", (int)(end - start));
        hid_free_device(device);
        vfree(parser);
        return NULL;
@@ -915,13 +922,13 @@ int hid_set_field(struct hid_field *field, unsigned offset, __s32 value)
        hid_dump_input(field->usage + offset, value);
 
        if (offset >= field->report_count) {
-               dbg("offset (%d) exceeds report_count (%d)", offset, field->report_count);
+               dbg_hid("offset (%d) exceeds report_count (%d)\n", offset, field->report_count);
                hid_dump_field(field, 8);
                return -1;
        }
        if (field->logical_minimum < 0) {
                if (value != snto32(s32ton(value, size), size)) {
-                       dbg("value %d is out of range", value);
+                       dbg_hid("value %d is out of range\n", value);
                        return -1;
                }
        }
@@ -934,19 +941,17 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i
 {
        struct hid_report_enum *report_enum = hid->report_enum + type;
        struct hid_report *report;
-       int n, rsize;
+       int n, rsize, i;
 
        if (!hid)
                return -ENODEV;
 
        if (!size) {
-               dbg("empty report");
+               dbg_hid("empty report\n");
                return -1;
        }
 
-#ifdef CONFIG_HID_DEBUG
-       printk(KERN_DEBUG __FILE__ ": report (size %u) (%snumbered)\n", size, report_enum->numbered ? "" : "un");
-#endif
+       dbg_hid("report (size %u) (%snumbered)\n", size, report_enum->numbered ? "" : "un");
 
        n = 0;                          /* Normally report number is 0 */
        if (report_enum->numbered) {    /* Device uses numbered reports, data[0] is report number */
@@ -954,25 +959,21 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i
                size--;
        }
 
-#ifdef CONFIG_HID_DEBUG
-       {
-               int i;
-               printk(KERN_DEBUG __FILE__ ": report %d (size %u) = ", n, size);
-               for (i = 0; i < size; i++)
-                       printk(" %02x", data[i]);
-               printk("\n");
-       }
-#endif
+       /* dump the report descriptor */
+       dbg_hid("report %d (size %u) = ", n, size);
+       for (i = 0; i < size; i++)
+               dbg_hid_line(" %02x", data[i]);
+       dbg_hid_line("\n");
 
        if (!(report = report_enum->report_id_hash[n])) {
-               dbg("undefined report_id %d received", n);
+               dbg_hid("undefined report_id %d received\n", n);
                return -1;
        }
 
        rsize = ((report->size - 1) >> 3) + 1;
 
        if (size < rsize) {
-               dbg("report %d is too short, (%d < %d)", report->id, size, rsize);
+               dbg_hid("report %d is too short, (%d < %d)\n", report->id, size, rsize);
                memset(data + size, 0, rsize - size);
        }
 
index 83c4126b37c333f59b575a40dce9f6fd1d2b675b..a13757b7898028986f98739eecfb3649be96bdfd 100644 (file)
@@ -347,6 +347,9 @@ static void resolv_usage_page(unsigned page) {
 void hid_resolv_usage(unsigned usage) {
        const struct hid_usage_entry *p;
 
+       if (!hid_debug)
+               return;
+
        resolv_usage_page(usage >> 16);
        printk(".");
        for (p = hid_usage_table; p->description; p++)
@@ -369,6 +372,9 @@ __inline__ static void tab(int n) {
 void hid_dump_field(struct hid_field *field, int n) {
        int j;
 
+       if (!hid_debug)
+               return;
+
        if (field->physical) {
                tab(n);
                printk("Physical(");
@@ -466,6 +472,9 @@ void hid_dump_device(struct hid_device *device) {
        unsigned i,k;
        static char *table[] = {"INPUT", "OUTPUT", "FEATURE"};
 
+       if (!hid_debug)
+               return;
+
        for (i = 0; i < HID_REPORT_TYPES; i++) {
                report_enum = device->report_enum + i;
                list = report_enum->report_list.next;
@@ -489,6 +498,9 @@ void hid_dump_device(struct hid_device *device) {
 EXPORT_SYMBOL_GPL(hid_dump_device);
 
 void hid_dump_input(struct hid_usage *usage, __s32 value) {
+       if (!hid_debug)
+               return;
+
        printk("hid-debug: input ");
        hid_resolv_usage(usage->hid);
        printk(" = %d\n", value);
@@ -758,6 +770,9 @@ static char **names[EV_MAX + 1] = {
 
 void hid_resolv_event(__u8 type, __u16 code) {
 
+       if (!hid_debug)
+               return;
+
        printk("%s.%s", events[type] ? events[type] : "?",
                names[type] ? (names[type][code] ? names[type][code] : "?") : "?");
 }
index 7f817897b178063059be2cfde16e19caa8b6d3df..8edbd30cf7955bcb54e80d2ce42fe6f2f545b8e2 100644 (file)
@@ -60,6 +60,19 @@ static const unsigned char hid_keyboard[256] = {
        150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk
 };
 
+/* extended mapping for certain Logitech hardware (Logitech cordless desktop LX500) */
+#define LOGITECH_EXPANDED_KEYMAP_SIZE 80
+static int logitech_expanded_keymap[LOGITECH_EXPANDED_KEYMAP_SIZE] = {
+         0,216,  0,213,175,156,  0,  0,  0,  0,
+       144,  0,  0,  0,  0,  0,  0,  0,  0,212,
+       174,167,152,161,112,  0,  0,  0,154,  0,
+         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+         0,  0,  0,  0,  0,183,184,185,186,187,
+       188,189,190,191,192,193,194,  0,  0,  0
+};
+
 static const struct {
        __s32 x;
        __s32 y;
@@ -308,9 +321,7 @@ static int hidinput_setkeycode(struct input_dev *dev, int scancode,
                
                clear_bit(old_keycode, dev->keybit);
                set_bit(usage->code, dev->keybit);
-#ifdef CONFIG_HID_DEBUG
-               printk (KERN_DEBUG "Assigned keycode %d to HID usage code %x\n", keycode, scancode);
-#endif
+               dbg_hid(KERN_DEBUG "Assigned keycode %d to HID usage code %x\n", keycode, scancode);
                /* Set the keybit for the old keycode if the old keycode is used
                 * by another key */
                if (hidinput_find_key (hid, 0, old_keycode))
@@ -333,11 +344,9 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
 
        field->hidinput = hidinput;
 
-#ifdef CONFIG_HID_DEBUG
-       printk(KERN_DEBUG "Mapping: ");
+       dbg_hid("Mapping: ");
        hid_resolv_usage(usage->hid);
-       printk(" ---> ");
-#endif
+       dbg_hid_line(" ---> ");
 
        if (field->flags & HID_MAIN_ITEM_CONSTANT)
                goto ignore;
@@ -378,6 +387,21 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
                                        }
                        }
 
+                       /* Special handling for Logitech Cordless Desktop */
+                       if (field->application != HID_GD_MOUSE) {
+                               if (device->quirks & HID_QUIRK_LOGITECH_EXPANDED_KEYMAP) {
+                                       int hid = usage->hid & HID_USAGE;
+                                       if (hid < LOGITECH_EXPANDED_KEYMAP_SIZE && logitech_expanded_keymap[hid] != 0)
+                                               code = logitech_expanded_keymap[hid];
+                               }
+                       } else {
+                               if (device->quirks & HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL) {
+                                       int hid = usage->hid & HID_USAGE;
+                                       if (hid == 7 || hid == 8)
+                                               goto ignore;
+                               }
+                       }
+
                        map_key(code);
                        break;
 
@@ -566,6 +590,11 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
                                case 0x0e5: map_key_clear(KEY_BASSBOOST);       break;
                                case 0x0e9: map_key_clear(KEY_VOLUMEUP);        break;
                                case 0x0ea: map_key_clear(KEY_VOLUMEDOWN);      break;
+
+                               /* reserved in HUT 1.12. Reported on Petalynx remote */
+                               case 0x0f6: map_key_clear(KEY_NEXT);            break;
+                               case 0x0fa: map_key_clear(KEY_BACK);            break;
+
                                case 0x183: map_key_clear(KEY_CONFIG);          break;
                                case 0x184: map_key_clear(KEY_WORDPROCESSOR);   break;
                                case 0x185: map_key_clear(KEY_EDITOR);          break;
@@ -598,7 +627,9 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
                                case 0x21b: map_key_clear(KEY_COPY);            break;
                                case 0x21c: map_key_clear(KEY_CUT);             break;
                                case 0x21d: map_key_clear(KEY_PASTE);           break;
-                               case 0x221: map_key_clear(KEY_FIND);            break;
+                               case 0x21f: map_key_clear(KEY_FIND);            break;
+                               case 0x221: map_key_clear(KEY_SEARCH);          break;
+                               case 0x222: map_key_clear(KEY_GOTO);            break;
                                case 0x223: map_key_clear(KEY_HOMEPAGE);        break;
                                case 0x224: map_key_clear(KEY_BACK);            break;
                                case 0x225: map_key_clear(KEY_FORWARD);         break;
@@ -688,7 +719,28 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
                        break;
 
                case HID_UP_MSVENDOR:
-                       goto ignore;
+
+                       /* special case - Chicony Chicony KU-0418 tactical pad */
+                       if (device->vendor == 0x04f2 && device->product == 0x0418) {
+                               set_bit(EV_REP, input->evbit);
+                               switch(usage->hid & HID_USAGE) {
+                                       case 0xff01: map_key_clear(BTN_1);              break;
+                                       case 0xff02: map_key_clear(BTN_2);              break;
+                                       case 0xff03: map_key_clear(BTN_3);              break;
+                                       case 0xff04: map_key_clear(BTN_4);              break;
+                                       case 0xff05: map_key_clear(BTN_5);              break;
+                                       case 0xff06: map_key_clear(BTN_6);              break;
+                                       case 0xff07: map_key_clear(BTN_7);              break;
+                                       case 0xff08: map_key_clear(BTN_8);              break;
+                                       case 0xff09: map_key_clear(BTN_9);              break;
+                                       case 0xff0a: map_key_clear(BTN_A);              break;
+                                       case 0xff0b: map_key_clear(BTN_B);              break;
+                                       default:    goto ignore;
+                               }
+                       } else {
+                               goto ignore;
+                       }
+                       break;
 
                case HID_UP_CUSTOM: /* Reported on Logitech and Powerbook USB keyboards */
 
@@ -704,10 +756,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
                        }
                        break;
 
-               case HID_UP_LOGIVENDOR: /* Reported on Logitech Ultra X Media Remote */
-
+               case HID_UP_LOGIVENDOR:
                        set_bit(EV_REP, input->evbit);
                        switch(usage->hid & HID_USAGE) {
+                               /* Reported on Logitech Ultra X Media Remote */
                                case 0x004: map_key_clear(KEY_AGAIN);           break;
                                case 0x00d: map_key_clear(KEY_HOME);            break;
                                case 0x024: map_key_clear(KEY_SHUFFLE);         break;
@@ -725,6 +777,14 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
                                case 0x04d: map_key_clear(KEY_SUBTITLE);        break;
                                case 0x051: map_key_clear(KEY_RED);             break;
                                case 0x052: map_key_clear(KEY_CLOSE);           break;
+
+                               /* Reported on Petalynx Maxter remote */
+                               case 0x05a: map_key_clear(KEY_TEXT);            break;
+                               case 0x05b: map_key_clear(KEY_RED);             break;
+                               case 0x05c: map_key_clear(KEY_GREEN);           break;
+                               case 0x05d: map_key_clear(KEY_YELLOW);          break;
+                               case 0x05e: map_key_clear(KEY_BLUE);            break;
+
                                default:    goto ignore;
                        }
                        break;
@@ -818,16 +878,24 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
                        field->dpad = usage->code;
        }
 
+       /* for those devices which produce Consumer volume usage as relative,
+        * we emulate pressing volumeup/volumedown appropriate number of times
+        * in hidinput_hid_event()
+        */
+       if ((usage->type == EV_ABS) && (field->flags & HID_MAIN_ITEM_RELATIVE) &&
+                       (usage->code == ABS_VOLUME)) {
+               set_bit(KEY_VOLUMEUP, input->keybit);
+               set_bit(KEY_VOLUMEDOWN, input->keybit);
+       }
+
        hid_resolv_event(usage->type, usage->code);
-#ifdef CONFIG_HID_DEBUG
-       printk("\n");
-#endif
+
+       dbg_hid_line("\n");
+
        return;
 
 ignore:
-#ifdef CONFIG_HID_DEBUG
-       printk("IGNORED\n");
-#endif
+       dbg_hid_line("IGNORED\n");
        return;
 }
 
@@ -896,18 +964,33 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
        }
 
        if (usage->hid == (HID_UP_PID | 0x83UL)) { /* Simultaneous Effects Max */
-               dbg("Maximum Effects - %d",value);
+               dbg_hid("Maximum Effects - %d\n",value);
                return;
        }
 
        if (usage->hid == (HID_UP_PID | 0x7fUL)) {
-               dbg("PID Pool Report\n");
+               dbg_hid("PID Pool Report\n");
                return;
        }
 
        if ((usage->type == EV_KEY) && (usage->code == 0)) /* Key 0 is "unassigned", not KEY_UNKNOWN */
                return;
 
+       if ((usage->type == EV_ABS) && (field->flags & HID_MAIN_ITEM_RELATIVE) &&
+                       (usage->code == ABS_VOLUME)) {
+               int count = abs(value);
+               int direction = value > 0 ? KEY_VOLUMEUP : KEY_VOLUMEDOWN;
+               int i;
+
+               for (i = 0; i < count; i++) {
+                       input_event(input, EV_KEY, direction, 1);
+                       input_sync(input);
+                       input_event(input, EV_KEY, direction, 0);
+                       input_sync(input);
+               }
+               return;
+       }
+
        input_event(input, usage->type, usage->code, value);
 
        if ((field->flags & HID_MAIN_ITEM_RELATIVE) && (usage->type == EV_KEY))
@@ -976,7 +1059,7 @@ int hidinput_connect(struct hid_device *hid)
                        if (IS_INPUT_APPLICATION(hid->collection[i].usage))
                                break;
 
-       if (i == hid->maxcollection)
+       if (i == hid->maxcollection && (hid->quirks & HID_QUIRK_HIDINPUT) == 0)
                return -1;
 
        if (hid->quirks & HID_QUIRK_SKIP_OUTPUT_REPORTS)
@@ -994,7 +1077,7 @@ int hidinput_connect(struct hid_device *hid)
                                if (!hidinput || !input_dev) {
                                        kfree(hidinput);
                                        input_free_device(input_dev);
-                                       err("Out of memory during hid input probe");
+                                       err_hid("Out of memory during hid input probe");
                                        return -1;
                                }
 
index d91b9dac6dff67843b2a8faeff47a9807f6eac45..b2baeaeba9beb2d8a5f598ffec4d24375bab2fb2 100644 (file)
@@ -60,6 +60,12 @@ MODULE_PARM_DESC(quirks, "Add/modify USB HID quirks by specifying "
                " quirks=vendorID:productID:quirks"
                " where vendorID, productID, and quirks are all in"
                " 0x-prefixed hex");
+static char *rdesc_quirks_param[MAX_USBHID_BOOT_QUIRKS] = { [ 0 ... (MAX_USBHID_BOOT_QUIRKS - 1) ] = NULL };
+module_param_array_named(rdesc_quirks, rdesc_quirks_param, charp, NULL, 0444);
+MODULE_PARM_DESC(rdesc_quirks, "Add/modify report descriptor quirks by specifying "
+               " rdesc_quirks=vendorID:productID:rdesc_quirks"
+               " where vendorID, productID, and rdesc_quirks are all in"
+               " 0x-prefixed hex");
 /*
  * Input submission and I/O error handler.
  */
@@ -127,7 +133,7 @@ static void hid_reset(struct work_struct *work)
                        hid_io_error(hid);
                break;
        default:
-               err("can't reset device, %s-%s/input%d, status %d",
+               err_hid("can't reset device, %s-%s/input%d, status %d",
                                hid_to_usb_dev(hid)->bus->bus_name,
                                hid_to_usb_dev(hid)->devpath,
                                usbhid->ifnum, rc);
@@ -220,7 +226,7 @@ static void hid_irq_in(struct urb *urb)
        if (status) {
                clear_bit(HID_IN_RUNNING, &usbhid->iofl);
                if (status != -EPERM) {
-                       err("can't resubmit intr, %s-%s/input%d, status %d",
+                       err_hid("can't resubmit intr, %s-%s/input%d, status %d",
                                        hid_to_usb_dev(hid)->bus->bus_name,
                                        hid_to_usb_dev(hid)->devpath,
                                        usbhid->ifnum, status);
@@ -240,10 +246,10 @@ static int hid_submit_out(struct hid_device *hid)
        usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0);
        usbhid->urbout->dev = hid_to_usb_dev(hid);
 
-       dbg("submitting out urb");
+       dbg_hid("submitting out urb\n");
 
        if (usb_submit_urb(usbhid->urbout, GFP_ATOMIC)) {
-               err("usb_submit_urb(out) failed");
+               err_hid("usb_submit_urb(out) failed");
                return -1;
        }
 
@@ -287,12 +293,12 @@ static int hid_submit_ctrl(struct hid_device *hid)
        usbhid->cr->wIndex = cpu_to_le16(usbhid->ifnum);
        usbhid->cr->wLength = cpu_to_le16(len);
 
-       dbg("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u",
+       dbg_hid("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u\n",
                usbhid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report",
                usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength);
 
        if (usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC)) {
-               err("usb_submit_urb(ctrl) failed");
+               err_hid("usb_submit_urb(ctrl) failed");
                return -1;
        }
 
@@ -474,7 +480,7 @@ int usbhid_wait_io(struct hid_device *hid)
        if (!wait_event_timeout(hid->wait, (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl) &&
                                        !test_bit(HID_OUT_RUNNING, &usbhid->iofl)),
                                        10*HZ)) {
-               dbg("timeout waiting for ctrl or out queue to clear");
+               dbg_hid("timeout waiting for ctrl or out queue to clear\n");
                return -1;
        }
 
@@ -632,20 +638,6 @@ static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid)
        usb_buffer_free(dev, usbhid->bufsize, usbhid->ctrlbuf, usbhid->ctrlbuf_dma);
 }
 
-/*
- * Cherry Cymotion keyboard have an invalid HID report descriptor,
- * that needs fixing before we can parse it.
- */
-
-static void hid_fixup_cymotion_descriptor(char *rdesc, int rsize)
-{
-       if (rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) {
-               info("Fixing up Cherry Cymotion report descriptor");
-               rdesc[11] = rdesc[16] = 0xff;
-               rdesc[12] = rdesc[17] = 0x03;
-       }
-}
-
 /*
  * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller
  * to "operational".  Without this, the ps3 controller will not report any
@@ -667,51 +659,11 @@ static void hid_fixup_sony_ps3_controller(struct usb_device *dev, int ifnum)
                                 USB_CTRL_GET_TIMEOUT);
 
        if (result < 0)
-               err("%s failed: %d\n", __func__, result);
+               err_hid("%s failed: %d\n", __func__, result);
 
        kfree(buf);
 }
 
-/*
- * Certain Logitech keyboards send in report #3 keys which are far
- * above the logical maximum described in descriptor. This extends
- * the original value of 0x28c of logical maximum to 0x104d
- */
-static void hid_fixup_logitech_descriptor(unsigned char *rdesc, int rsize)
-{
-       if (rsize >= 90 && rdesc[83] == 0x26
-                       && rdesc[84] == 0x8c
-                       && rdesc[85] == 0x02) {
-               info("Fixing up Logitech keyboard report descriptor");
-               rdesc[84] = rdesc[89] = 0x4d;
-               rdesc[85] = rdesc[90] = 0x10;
-       }
-}
-
-/*
- * Some USB barcode readers from cypress have usage min and usage max in
- * the wrong order
- */
-static void hid_fixup_cypress_descriptor(unsigned char *rdesc, int rsize)
-{
-       short fixed = 0;
-       int i;
-
-       for (i = 0; i < rsize - 4; i++) {
-               if (rdesc[i] == 0x29 && rdesc [i+2] == 0x19) {
-                       unsigned char tmp;
-
-                       rdesc[i] = 0x19; rdesc[i+2] = 0x29;
-                       tmp = rdesc[i+3];
-                       rdesc[i+3] = rdesc[i+1];
-                       rdesc[i+1] = tmp;
-               }
-       }
-
-       if (fixed)
-               info("Fixing up Cypress report descriptor");
-}
-
 static struct hid_device *usb_hid_configure(struct usb_interface *intf)
 {
        struct usb_host_interface *interface = intf->cur_altsetting;
@@ -746,7 +698,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
        if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) &&
            (!interface->desc.bNumEndpoints ||
             usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) {
-               dbg("class descriptor not present\n");
+               dbg_hid("class descriptor not present\n");
                return NULL;
        }
 
@@ -755,41 +707,34 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
                        rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength);
 
        if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) {
-               dbg("weird size of report descriptor (%u)", rsize);
+               dbg_hid("weird size of report descriptor (%u)\n", rsize);
                return NULL;
        }
 
        if (!(rdesc = kmalloc(rsize, GFP_KERNEL))) {
-               dbg("couldn't allocate rdesc memory");
+               dbg_hid("couldn't allocate rdesc memory\n");
                return NULL;
        }
 
        hid_set_idle(dev, interface->desc.bInterfaceNumber, 0, 0);
 
        if ((n = hid_get_class_descriptor(dev, interface->desc.bInterfaceNumber, HID_DT_REPORT, rdesc, rsize)) < 0) {
-               dbg("reading report descriptor failed");
+               dbg_hid("reading report descriptor failed\n");
                kfree(rdesc);
                return NULL;
        }
 
-       if ((quirks & HID_QUIRK_CYMOTION))
-               hid_fixup_cymotion_descriptor(rdesc, rsize);
-
-       if (quirks & HID_QUIRK_LOGITECH_DESCRIPTOR)
-               hid_fixup_logitech_descriptor(rdesc, rsize);
+       usbhid_fixup_report_descriptor(le16_to_cpu(dev->descriptor.idVendor),
+                       le16_to_cpu(dev->descriptor.idProduct), rdesc,
+                       rsize, rdesc_quirks_param);
 
-       if (quirks & HID_QUIRK_SWAPPED_MIN_MAX)
-               hid_fixup_cypress_descriptor(rdesc, rsize);
-
-#ifdef CONFIG_HID_DEBUG
-       printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n);
+       dbg_hid("report descriptor (size %u, read %d) = ", rsize, n);
        for (n = 0; n < rsize; n++)
-               printk(" %02x", (unsigned char) rdesc[n]);
-       printk("\n");
-#endif
+               dbg_hid_line(" %02x", (unsigned char) rdesc[n]);
+       dbg_hid_line("\n");
 
        if (!(hid = hid_parse_report(rdesc, n))) {
-               dbg("parsing report descriptor failed");
+               dbg_hid("parsing report descriptor failed\n");
                kfree(rdesc);
                return NULL;
        }
@@ -861,7 +806,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
        }
 
        if (!usbhid->urbin) {
-               err("couldn't find an input interrupt endpoint");
+               err_hid("couldn't find an input interrupt endpoint");
                goto fail;
        }
 
@@ -956,7 +901,7 @@ static void hid_disconnect(struct usb_interface *intf)
        usb_kill_urb(usbhid->urbctrl);
 
        del_timer_sync(&usbhid->io_retry);
-       flush_scheduled_work();
+       cancel_work_sync(&usbhid->reset_work);
 
        if (hid->claimed & HID_CLAIMED_INPUT)
                hidinput_disconnect(hid);
@@ -978,7 +923,7 @@ static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id)
        int i;
        char *c;
 
-       dbg("HID probe called for ifnum %d",
+       dbg_hid("HID probe called for ifnum %d\n",
                        intf->altsetting->desc.bInterfaceNumber);
 
        if (!(hid = usb_hid_configure(intf)))
@@ -1064,20 +1009,22 @@ static int hid_resume(struct usb_interface *intf)
 }
 
 /* Treat USB reset pretty much the same as suspend/resume */
-static void hid_pre_reset(struct usb_interface *intf)
+static int hid_pre_reset(struct usb_interface *intf)
 {
        /* FIXME: What if the interface is already suspended? */
        hid_suspend(intf, PMSG_ON);
+       return 0;
 }
 
-static void hid_post_reset(struct usb_interface *intf)
+/* Same routine used for post_reset and reset_resume */
+static int hid_post_reset(struct usb_interface *intf)
 {
        struct usb_device *dev = interface_to_usbdev (intf);
 
        hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0);
        /* FIXME: Any more reinitialization needed? */
 
-       hid_resume(intf);
+       return hid_resume(intf);
 }
 
 static struct usb_device_id hid_usb_ids [] = {
@@ -1094,6 +1041,7 @@ static struct usb_driver hid_driver = {
        .disconnect =   hid_disconnect,
        .suspend =      hid_suspend,
        .resume =       hid_resume,
+       .reset_resume = hid_post_reset,
        .pre_reset =    hid_pre_reset,
        .post_reset =   hid_post_reset,
        .id_table =     hid_usb_ids,
index c5cd4107d6aff59f833c4ec9bc79b956522fd135..4b7ab6a46d93b9d2e539820382a33b8edd76ee71 100644 (file)
@@ -78,7 +78,7 @@ static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *ef
                report->field[0]->value[1] = 0x08;
                report->field[0]->value[2] = x;
                report->field[0]->value[3] = y;
-               dbg("(x, y)=(%04x, %04x)", x, y);
+               dbg_hid("(x, y)=(%04x, %04x)\n", x, y);
                usbhid_submit_report(hid, report, USB_DIR_OUT);
                break;
 
@@ -93,7 +93,7 @@ static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *ef
                report->field[0]->value[1] = 0x00;
                report->field[0]->value[2] = left;
                report->field[0]->value[3] = right;
-               dbg("(left, right)=(%04x, %04x)", left, right);
+               dbg_hid("(left, right)=(%04x, %04x)\n", left, right);
                usbhid_submit_report(hid, report, USB_DIR_OUT);
                break;
        }
@@ -113,20 +113,20 @@ int hid_lgff_init(struct hid_device* hid)
 
        /* Find the report to use */
        if (list_empty(report_list)) {
-               err("No output report found");
+               err_hid("No output report found");
                return -1;
        }
 
        /* Check that the report looks ok */
        report = list_entry(report_list->next, struct hid_report, list);
        if (!report) {
-               err("NULL output report");
+               err_hid("NULL output report");
                return -1;
        }
 
        field = report->field[0];
        if (!field) {
-               err("NULL field");
+               err_hid("NULL field");
                return -1;
        }
 
index f5a90e950e6b54cfcd48381f89d8b38e141b1aea..011326178c0670c5b5e680a47d741661101a45aa 100644 (file)
@@ -738,6 +738,7 @@ static void pidff_autocenter(struct pidff_device *pidff, u16 magnitude)
        pidff->set_effect[PID_TRIGGER_BUTTON].value[0] = 0;
        pidff->set_effect[PID_TRIGGER_REPEAT_INT].value[0] = 0;
        pidff_set(&pidff->set_effect[PID_GAIN], magnitude);
+       pidff->set_effect[PID_DIRECTION_ENABLE].value[0] = 1;
        pidff->set_effect[PID_START_DELAY].value[0] = 0;
 
        usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_EFFECT],
index f6c4145dc20253a885ead58fabd0665c8497f273..775b9f3b8ce3e37cce8cc2e45166c1035107d59f 100644 (file)
 #define USB_VENDOR_ID_ESSENTIAL_REALITY        0x0d7f
 #define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100
 
+#define USB_VENDOR_ID_GAMERON          0x0810
+#define USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR 0x0001
+
 #define USB_VENDOR_ID_GLAB             0x06c2
 #define USB_DEVICE_ID_4_PHIDGETSERVO_30        0x0038
 #define USB_DEVICE_ID_1_PHIDGETSERVO_30        0x0039
 #define USB_VENDOR_ID_LOGITECH         0x046d
 #define USB_DEVICE_ID_LOGITECH_RECEIVER        0xc101
 #define USB_DEVICE_ID_LOGITECH_WHEEL   0xc294
+#define USB_DEVICE_ID_LOGITECH_KBD     0xc311
 #define USB_DEVICE_ID_S510_RECEIVER    0xc50c
 #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_EDGE      0xc714
 
 #define USB_DEVICE_ID_MGE_UPS          0xffff
 #define USB_DEVICE_ID_MGE_UPS1         0x0001
 
+#define USB_VENDOR_ID_MICROSOFT                0x045e
+#define USB_DEVICE_ID_SIDEWINDER_GV    0x003b
+
+#define USB_VENDOR_ID_NCR              0x0404
+#define USB_DEVICE_ID_NCR_FIRST                0x0300
+#define USB_DEVICE_ID_NCR_LAST         0x03ff
+
 #define USB_VENDOR_ID_NEC              0x073e
 #define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301
 
 #define USB_VENDOR_ID_PANTHERLORD      0x0810
 #define USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK    0x0001
 
+#define USB_VENDOR_ID_PETALYNX         0x18b1
+#define USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE   0x0037
+
 #define USB_VENDOR_ID_PLAYDOTCOM       0x0b43
 #define USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII     0x0003
 
@@ -278,6 +293,7 @@ static const struct hid_blacklist {
        { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR, HID_QUIRK_BADPAD },
        { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD },
        { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD },
+       { USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR, HID_QUIRK_MULTI_INPUT },
        { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
        { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
        { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
@@ -285,11 +301,10 @@ static const struct hid_blacklist {
        { 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_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION, HID_QUIRK_CYMOTION },
-
        { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE, HID_QUIRK_DUPLICATE_USAGES },
 
        { USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM, HID_QUIRK_HIDDEV },
+       { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV, HID_QUIRK_HIDINPUT },
 
        { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_01, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_10, HID_QUIRK_IGNORE },
@@ -409,9 +424,7 @@ static const struct hid_blacklist {
        { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302, HID_QUIRK_IGNORE },
 
-       { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER, HID_QUIRK_LOGITECH_DESCRIPTOR },
-       { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER, HID_QUIRK_LOGITECH_DESCRIPTOR },
-       { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2, HID_QUIRK_LOGITECH_DESCRIPTOR },
+       { 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_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE, HID_QUIRK_MIGHTYMOUSE | HID_QUIRK_INVERT_HWHEEL },
 
@@ -426,6 +439,7 @@ static const struct hid_blacklist {
        { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL, HID_QUIRK_NOGET },
+       { USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
@@ -448,9 +462,28 @@ static const struct hid_blacklist {
        { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
 
        { USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_W7658, HID_QUIRK_RESET_LEDS },
+       { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KBD, HID_QUIRK_RESET_LEDS },
 
-       { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1, HID_QUIRK_SWAPPED_MIN_MAX },
-       { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2, HID_QUIRK_SWAPPED_MIN_MAX },
+       { 0, 0 }
+};
+
+/* Quirks for devices which require report descriptor fixup go here */
+static const struct hid_rdesc_blacklist {
+       __u16 idVendor;
+       __u16 idProduct;
+       __u32 quirks;
+} hid_rdesc_blacklist[] = {
+
+       { USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION, HID_QUIRK_RDESC_CYMOTION },
+
+       { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER, HID_QUIRK_RDESC_LOGITECH },
+       { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER, HID_QUIRK_RDESC_LOGITECH },
+       { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2, HID_QUIRK_RDESC_LOGITECH },
+
+       { USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE, HID_QUIRK_RDESC_PETALYNX },
+
+       { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1, HID_QUIRK_RDESC_SWAPPED_MIN_MAX },
+       { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2, HID_QUIRK_RDESC_SWAPPED_MIN_MAX },
 
        { 0, 0 }
 };
@@ -493,7 +526,7 @@ static struct hid_blacklist *usbhid_exists_dquirk(const u16 idVendor,
        }
 
        if (bl_entry != NULL)
-               dbg("Found dynamic quirk 0x%x for USB HID vendor 0x%hx prod 0x%hx\n",
+               dbg_hid("Found dynamic quirk 0x%x for USB HID vendor 0x%hx prod 0x%hx\n",
                                bl_entry->quirks, bl_entry->idVendor,
                                bl_entry->idProduct);
 
@@ -521,13 +554,13 @@ int usbhid_modify_dquirk(const u16 idVendor, const u16 idProduct,
        int list_edited = 0;
 
        if (!idVendor) {
-               dbg("Cannot add a quirk with idVendor = 0");
+               dbg_hid("Cannot add a quirk with idVendor = 0\n");
                return -EINVAL;
        }
 
        q_new = kmalloc(sizeof(struct quirks_list_struct), GFP_KERNEL);
        if (!q_new) {
-               dbg("Could not allocate quirks_list_struct");
+               dbg_hid("Could not allocate quirks_list_struct\n");
                return -ENOMEM;
        }
 
@@ -559,7 +592,6 @@ int usbhid_modify_dquirk(const u16 idVendor, const u16 idProduct,
        return 0;
 }
 
-
 /**
  * usbhid_remove_all_dquirks: remove all runtime HID quirks from memory
  *
@@ -643,7 +675,7 @@ static const struct hid_blacklist *usbhid_exists_squirk(const u16 idVendor,
                        bl_entry = &hid_blacklist[n];
 
        if (bl_entry != NULL)
-               dbg("Found squirk 0x%x for USB HID vendor 0x%hx prod 0x%hx\n",
+               dbg_hid("Found squirk 0x%x for USB HID vendor 0x%hx prod 0x%hx\n",
                                bl_entry->quirks, bl_entry->idVendor, 
                                bl_entry->idProduct);
        return bl_entry;
@@ -675,6 +707,12 @@ u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct)
                                idProduct <= USB_DEVICE_ID_CODEMERCS_IOW_LAST)
                        return HID_QUIRK_IGNORE;
 
+       /* NCR devices must not be queried for reports */
+       if (idVendor == USB_VENDOR_ID_NCR &&
+                       idProduct >= USB_DEVICE_ID_NCR_FIRST &&
+                       idProduct <= USB_DEVICE_ID_NCR_LAST)
+                       return HID_QUIRK_NOGET;
+
        down_read(&dquirks_rwsem);
        bl_entry = usbhid_exists_dquirk(idVendor, idProduct);
        if (!bl_entry)
@@ -686,3 +724,126 @@ u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct)
        return quirks;
 }
 
+/*
+ * Cherry Cymotion keyboard have an invalid HID report descriptor,
+ * that needs fixing before we can parse it.
+ */
+static void usbhid_fixup_cymotion_descriptor(char *rdesc, int rsize)
+{
+       if (rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) {
+               printk(KERN_INFO "Fixing up Cherry Cymotion report descriptor\n");
+               rdesc[11] = rdesc[16] = 0xff;
+               rdesc[12] = rdesc[17] = 0x03;
+       }
+}
+
+
+/*
+ * Certain Logitech keyboards send in report #3 keys which are far
+ * above the logical maximum described in descriptor. This extends
+ * the original value of 0x28c of logical maximum to 0x104d
+ */
+static void usbhid_fixup_logitech_descriptor(unsigned char *rdesc, int rsize)
+{
+       if (rsize >= 90 && rdesc[83] == 0x26
+                       && rdesc[84] == 0x8c
+                       && rdesc[85] == 0x02) {
+               printk(KERN_INFO "Fixing up Logitech keyboard report descriptor\n");
+               rdesc[84] = rdesc[89] = 0x4d;
+               rdesc[85] = rdesc[90] = 0x10;
+       }
+}
+
+/* Petalynx Maxter Remote has maximum for consumer page set too low */
+static void usbhid_fixup_petalynx_descriptor(unsigned char *rdesc, int rsize)
+{
+       if (rsize >= 60 && rdesc[39] == 0x2a
+                       && rdesc[40] == 0xf5
+                       && rdesc[41] == 0x00
+                       && rdesc[59] == 0x26
+                       && rdesc[60] == 0xf9
+                       && rdesc[61] == 0x00) {
+               printk(KERN_INFO "Fixing up Petalynx Maxter Remote report descriptor\n");
+               rdesc[60] = 0xfa;
+               rdesc[40] = 0xfa;
+       }
+}
+
+/*
+ * Some USB barcode readers from cypress have usage min and usage max in
+ * the wrong order
+ */
+static void usbhid_fixup_cypress_descriptor(unsigned char *rdesc, int rsize)
+{
+       short fixed = 0;
+       int i;
+
+       for (i = 0; i < rsize - 4; i++) {
+               if (rdesc[i] == 0x29 && rdesc [i+2] == 0x19) {
+                       unsigned char tmp;
+
+                       rdesc[i] = 0x19; rdesc[i+2] = 0x29;
+                       tmp = rdesc[i+3];
+                       rdesc[i+3] = rdesc[i+1];
+                       rdesc[i+1] = tmp;
+               }
+       }
+
+       if (fixed)
+               printk(KERN_INFO "Fixing up Cypress report descriptor\n");
+}
+
+
+static void __usbhid_fixup_report_descriptor(__u32 quirks, char *rdesc, unsigned rsize)
+{
+       if ((quirks & HID_QUIRK_RDESC_CYMOTION))
+               usbhid_fixup_cymotion_descriptor(rdesc, rsize);
+
+       if (quirks & HID_QUIRK_RDESC_LOGITECH)
+               usbhid_fixup_logitech_descriptor(rdesc, rsize);
+
+       if (quirks & HID_QUIRK_RDESC_SWAPPED_MIN_MAX)
+               usbhid_fixup_cypress_descriptor(rdesc, rsize);
+
+       if (quirks & HID_QUIRK_RDESC_PETALYNX)
+               usbhid_fixup_petalynx_descriptor(rdesc, rsize);
+}
+
+/**
+ * usbhid_fixup_report_descriptor: check if report descriptor needs fixup
+ *
+ * Description:
+ *     Walks the hid_rdesc_blacklist[] array and checks whether the device
+ *     is known to have broken report descriptor that needs to be fixed up
+ *     prior to entering the HID parser
+ *
+ * Returns: nothing
+ */
+void usbhid_fixup_report_descriptor(const u16 idVendor, const u16 idProduct,
+                                   char *rdesc, unsigned rsize, char **quirks_param)
+{
+       int n, m;
+       u16 paramVendor, paramProduct;
+       u32 quirks;
+
+       /* static rdesc quirk entries */
+       for (n = 0; hid_rdesc_blacklist[n].idVendor; n++)
+               if (hid_rdesc_blacklist[n].idVendor == idVendor &&
+                               hid_rdesc_blacklist[n].idProduct == idProduct)
+                       __usbhid_fixup_report_descriptor(hid_rdesc_blacklist[n].quirks,
+                                       rdesc, rsize);
+
+       /* runtime rdesc quirk entries handling */
+       for (n = 0; quirks_param[n] && n < MAX_USBHID_BOOT_QUIRKS; n++) {
+               m = sscanf(quirks_param[n], "0x%hx:0x%hx:0x%x",
+                               &paramVendor, &paramProduct, &quirks);
+
+               if (m != 3)
+                       printk(KERN_WARNING
+                               "Could not parse HID quirk module param %s\n",
+                               quirks_param[n]);
+               else if (paramVendor == idVendor && paramProduct == idProduct)
+                       __usbhid_fixup_report_descriptor(quirks, rdesc, rsize);
+       }
+
+}
index ab5ba6ef891cb756fd531119baeabef7211c6dcd..555bb48b4295d0d7ea167702ea125bcb4cbd1088 100644 (file)
@@ -70,7 +70,7 @@ static int hid_tmff_play(struct input_dev *dev, void *data, struct ff_effect *ef
 
        tmff->rumble->value[0] = left;
        tmff->rumble->value[1] = right;
-       dbg("(left,right)=(%08x, %08x)", left, right);
+       dbg_hid("(left,right)=(%08x, %08x)\n", left, right);
        usbhid_submit_report(hid, tmff->report, USB_DIR_OUT);
 
        return 0;
index a7fbffcdaf363e4398155b774da7bf32156b9db3..5a688274f6a3331d2264d10de5fff780de473b9c 100644 (file)
  */
 
 
-/* #define DEBUG */
-
-#define debug(format, arg...) pr_debug("hid-zpff: " format "\n" , ## arg)
-
 #include <linux/input.h>
 #include <linux/usb.h>
 #include <linux/hid.h>
@@ -49,14 +45,14 @@ static int hid_zpff_play(struct input_dev *dev, void *data,
 
        left = effect->u.rumble.strong_magnitude;
        right = effect->u.rumble.weak_magnitude;
-       debug("called with 0x%04x 0x%04x", left, right);
+       dbg_hid("called with 0x%04x 0x%04x\n", left, right);
 
        left = left * 0x7f / 0xffff;
        right = right * 0x7f / 0xffff;
 
        zpff->report->field[2]->value[0] = left;
        zpff->report->field[3]->value[0] = right;
-       debug("running with 0x%02x 0x%02x", left, right);
+       dbg_hid("running with 0x%02x 0x%02x\n", left, right);
        usbhid_submit_report(hid, zpff->report, USB_DIR_OUT);
 
        return 0;
index 488d61bdbf2c1960d4d84e4cd3347f56916fcd1d..e793127f971eae29903298b7cb6d3ec64a156325 100644 (file)
@@ -779,7 +779,7 @@ int hiddev_connect(struct hid_device *hid)
 
        retval = usb_register_dev(usbhid->intf, &hiddev_class);
        if (retval) {
-               err("Not able to get a minor for this device.");
+               err_hid("Not able to get a minor for this device.");
                kfree(hiddev);
                return -1;
        }
index 1309787807130cfa2e2121ae856ccde721da92ff..b76b02f7b52de04a11e17d2a17e0e80b850d9922 100644 (file)
@@ -125,7 +125,7 @@ static void usb_kbd_irq(struct urb *urb)
 resubmit:
        i = usb_submit_urb (urb, GFP_ATOMIC);
        if (i)
-               err ("can't resubmit intr, %s-%s/input0, status %d",
+               err_hid ("can't resubmit intr, %s-%s/input0, status %d",
                                kbd->usbdev->bus->bus_name,
                                kbd->usbdev->devpath, i);
 }
@@ -151,7 +151,7 @@ static int usb_kbd_event(struct input_dev *dev, unsigned int type,
        *(kbd->leds) = kbd->newleds;
        kbd->led->dev = kbd->usbdev;
        if (usb_submit_urb(kbd->led, GFP_ATOMIC))
-               err("usb_submit_urb(leds) failed");
+               err_hid("usb_submit_urb(leds) failed");
 
        return 0;
 }
@@ -169,7 +169,7 @@ static void usb_kbd_led(struct urb *urb)
        *(kbd->leds) = kbd->newleds;
        kbd->led->dev = kbd->usbdev;
        if (usb_submit_urb(kbd->led, GFP_ATOMIC))
-               err("usb_submit_urb(leds) failed");
+               err_hid("usb_submit_urb(leds) failed");
 }
 
 static int usb_kbd_open(struct input_dev *dev)
index 58899078810b787b03dfda4ff894ef43ab2d6709..014dfa575be73e0c156ac77fa08224513cb59d11 100644 (file)
@@ -34,10 +34,6 @@ config I2C_ALGOPCA
          This support is also available as a module.  If so, the module 
          will be called i2c-algo-pca.
 
-config I2C_ALGO8XX
-       tristate "MPC8xx CPM I2C interface"
-       depends on 8xx
-
 config I2C_ALGO_SGI
        tristate "I2C SGI interfaces"
        depends on SGI_IP22 || SGI_IP32 || X86_VISWS
index 838dc1c19d61b4ba0fe7908a9ac851d1c5189a59..fcde9bab5b96e07d510b39221874a015228be34b 100644 (file)
@@ -207,6 +207,7 @@ config I2C_PIIX4
            ATI IXP300
            ATI IXP400
            ATI SB600
+           ATI SB700
            Serverworks OSB4
            Serverworks CSB5
            Serverworks CSB6
@@ -390,11 +391,6 @@ config I2C_PROSAVAGE
          This support is also available as a module.  If so, the module 
          will be called i2c-prosavage.
 
-config I2C_RPXLITE
-       tristate "Embedded Planet RPX Lite/Classic support"
-       depends on RPXLITE || RPXCLASSIC
-       select I2C_ALGO8XX
-
 config I2C_S3C2410
        tristate "S3C2410 I2C Driver"
        depends on ARCH_S3C2410
@@ -512,6 +508,22 @@ config I2C_SIS96X
          This driver can also be built as a module.  If so, the module
          will be called i2c-sis96x.
 
+config I2C_TAOS_EVM
+       tristate "TAOS evaluation module"
+       depends on EXPERIMENTAL
+       select SERIO
+       select SERIO_SERPORT
+       default n
+       help
+         This supports TAOS evaluation modules on serial port. In order to
+         use this driver, you will need the inputattach tool, which is part
+         of the input-utils package.
+
+         If unsure, say N.
+
+         This support is also available as a module.  If so, the module
+         will be called i2c-taos-evm.
+
 config I2C_STUB
        tristate "I2C/SMBus Test Stub"
        depends on EXPERIMENTAL && m
@@ -635,4 +647,13 @@ config I2C_PNX
          This driver can also be built as a module.  If so, the module
          will be called i2c-pnx.
 
+config I2C_PMCMSP
+       tristate "PMC MSP I2C TWI Controller"
+       depends on PMC_MSP
+       help
+         This driver supports the PMC TWI controller on MSP devices.
+
+         This driver can also be built as module. If so, the module
+         will be called i2c-pmcmsp.
+
 endmenu
index 14d1432f698bf9b24ffd6b70917361dd93403238..a6db4e38bda8c237c5db961f88fec40511898dd0 100644 (file)
@@ -32,10 +32,10 @@ obj-$(CONFIG_I2C_PARPORT_LIGHT)     += i2c-parport-light.o
 obj-$(CONFIG_I2C_PASEMI)       += i2c-pasemi.o
 obj-$(CONFIG_I2C_PCA_ISA)      += i2c-pca-isa.o
 obj-$(CONFIG_I2C_PIIX4)                += i2c-piix4.o
+obj-$(CONFIG_I2C_PMCMSP)       += i2c-pmcmsp.o
 obj-$(CONFIG_I2C_PNX)          += i2c-pnx.o
 obj-$(CONFIG_I2C_PROSAVAGE)    += i2c-prosavage.o
 obj-$(CONFIG_I2C_PXA)          += i2c-pxa.o
-obj-$(CONFIG_I2C_RPXLITE)      += i2c-rpx.o
 obj-$(CONFIG_I2C_S3C2410)      += i2c-s3c2410.o
 obj-$(CONFIG_I2C_SAVAGE4)      += i2c-savage4.o
 obj-$(CONFIG_I2C_SIBYTE)       += i2c-sibyte.o
@@ -44,6 +44,7 @@ obj-$(CONFIG_I2C_SIS5595)     += i2c-sis5595.o
 obj-$(CONFIG_I2C_SIS630)       += i2c-sis630.o
 obj-$(CONFIG_I2C_SIS96X)       += i2c-sis96x.o
 obj-$(CONFIG_I2C_STUB)         += i2c-stub.o
+obj-$(CONFIG_I2C_TAOS_EVM)     += i2c-taos-evm.o
 obj-$(CONFIG_I2C_TINY_USB)     += i2c-tiny-usb.o
 obj-$(CONFIG_I2C_VERSATILE)    += i2c-versatile.o
 obj-$(CONFIG_I2C_ACORN)                += i2c-acorn.o
index a7dd54654a9a18d8ecec076668feadc4d3405022..025f19423faffee0df8e88cabf67d630e48cc52f 100644 (file)
@@ -63,14 +63,14 @@ static void i2c_gpio_setscl_val(void *data, int state)
        gpio_set_value(pdata->scl_pin, state);
 }
 
-int i2c_gpio_getsda(void *data)
+static int i2c_gpio_getsda(void *data)
 {
        struct i2c_gpio_platform_data *pdata = data;
 
        return gpio_get_value(pdata->sda_pin);
 }
 
-int i2c_gpio_getscl(void *data)
+static int i2c_gpio_getscl(void *data)
 {
        struct i2c_gpio_platform_data *pdata = data;
 
@@ -142,7 +142,13 @@ static int __init i2c_gpio_probe(struct platform_device *pdev)
        adap->algo_data = bit_data;
        adap->dev.parent = &pdev->dev;
 
-       ret = i2c_bit_add_bus(adap);
+       /*
+        * If "dev->id" is negative we consider it as zero.
+        * The reason to do so is to avoid sysfs names that only make
+        * sense when there are multiple adapters.
+        */
+       adap->nr = pdev->id >= 0 ? pdev->id : 0;
+       ret = i2c_bit_add_numbered_bus(adap);
        if (ret)
                goto err_add_bus;
 
index 611b57192c9618ac6159267b4371f89835efd75c..8f5c686123b8a5da5fae95064cb3bd8355ca5428 100644 (file)
 
 /*
     SUPPORTED DEVICES  PCI ID
-    82801AA            2413           
-    82801AB            2423           
-    82801BA            2443           
-    82801CA/CAM                2483           
-    82801DB            24C3   (HW PEC supported, 32 byte buffer not supported)
-    82801EB            24D3   (HW PEC supported, 32 byte buffer not supported)
+    82801AA            2413
+    82801AB            2423
+    82801BA            2443
+    82801CA/CAM                2483
+    82801DB            24C3   (HW PEC supported)
+    82801EB            24D3   (HW PEC supported)
     6300ESB            25A4
     ICH6               266A
     ICH7               27DA
 #define SMBHSTCFG_SMB_SMI_EN   2
 #define SMBHSTCFG_I2C_EN       4
 
+/* Auxillary control register bits, ICH4+ only */
+#define SMBAUXCTL_CRC          1
+#define SMBAUXCTL_E32B         2
+
+/* kill bit for SMBHSTCNT */
+#define SMBHSTCNT_KILL         2
+
 /* Other settings */
 #define MAX_TIMEOUT            100
 #define ENABLE_INT9            0       /* set to 0x01 to enable - untested */
 #define I801_START             0x40
 #define I801_PEC_EN            0x80    /* ICH4 only */
 
-
-static int i801_transaction(void);
-static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
-                                 int command, int hwpec);
+/* I801 Hosts Status register bits */
+#define SMBHSTSTS_BYTE_DONE    0x80
+#define SMBHSTSTS_INUSE_STS    0x40
+#define SMBHSTSTS_SMBALERT_STS 0x20
+#define SMBHSTSTS_FAILED       0x10
+#define SMBHSTSTS_BUS_ERR      0x08
+#define SMBHSTSTS_DEV_ERR      0x04
+#define SMBHSTSTS_INTR         0x02
+#define SMBHSTSTS_HOST_BUSY    0x01
 
 static unsigned long i801_smba;
 static unsigned char i801_original_hstcfg;
@@ -102,7 +114,7 @@ static struct pci_driver i801_driver;
 static struct pci_dev *I801_dev;
 static int isich4;
 
-static int i801_transaction(void)
+static int i801_transaction(int xact)
 {
        int temp;
        int result = 0;
@@ -127,33 +139,40 @@ static int i801_transaction(void)
                }
        }
 
-       outb_p(inb(SMBHSTCNT) | I801_START, SMBHSTCNT);
+       /* the current contents of SMBHSTCNT can be overwritten, since PEC,
+        * INTREN, SMBSCMD are passed in xact */
+       outb_p(xact | I801_START, SMBHSTCNT);
 
        /* We will always wait for a fraction of a second! */
        do {
                msleep(1);
                temp = inb_p(SMBHSTSTS);
-       } while ((temp & 0x01) && (timeout++ < MAX_TIMEOUT));
+       } while ((temp & SMBHSTSTS_HOST_BUSY) && (timeout++ < MAX_TIMEOUT));
 
        /* If the SMBus is still busy, we give up */
        if (timeout >= MAX_TIMEOUT) {
                dev_dbg(&I801_dev->dev, "SMBus Timeout!\n");
                result = -1;
+               /* try to stop the current command */
+               dev_dbg(&I801_dev->dev, "Terminating the current operation\n");
+               outb_p(inb_p(SMBHSTCNT) | SMBHSTCNT_KILL, SMBHSTCNT);
+               msleep(1);
+               outb_p(inb_p(SMBHSTCNT) & (~SMBHSTCNT_KILL), SMBHSTCNT);
        }
 
-       if (temp & 0x10) {
+       if (temp & SMBHSTSTS_FAILED) {
                result = -1;
                dev_dbg(&I801_dev->dev, "Error: Failed bus transaction\n");
        }
 
-       if (temp & 0x08) {
+       if (temp & SMBHSTSTS_BUS_ERR) {
                result = -1;
                dev_err(&I801_dev->dev, "Bus collision! SMBus may be locked "
                        "until next hard reset. (sorry!)\n");
                /* Clock stops and slave is stuck in mid-transmission */
        }
 
-       if (temp & 0x04) {
+       if (temp & SMBHSTSTS_DEV_ERR) {
                result = -1;
                dev_dbg(&I801_dev->dev, "Error: no response!\n");
        }
@@ -172,44 +191,70 @@ static int i801_transaction(void)
        return result;
 }
 
-/* All-inclusive block transaction function */
-static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
-                                 int command, int hwpec)
+/* wait for INTR bit as advised by Intel */
+static void i801_wait_hwpec(void)
+{
+       int timeout = 0;
+       int temp;
+
+       do {
+               msleep(1);
+               temp = inb_p(SMBHSTSTS);
+       } while ((!(temp & SMBHSTSTS_INTR))
+                && (timeout++ < MAX_TIMEOUT));
+
+       if (timeout >= MAX_TIMEOUT) {
+               dev_dbg(&I801_dev->dev, "PEC Timeout!\n");
+       }
+       outb_p(temp, SMBHSTSTS);
+}
+
+static int i801_block_transaction_by_block(union i2c_smbus_data *data,
+                                          char read_write, int hwpec)
+{
+       int i, len;
+
+       inb_p(SMBHSTCNT); /* reset the data buffer index */
+
+       /* Use 32-byte buffer to process this transaction */
+       if (read_write == I2C_SMBUS_WRITE) {
+               len = data->block[0];
+               outb_p(len, SMBHSTDAT0);
+               for (i = 0; i < len; i++)
+                       outb_p(data->block[i+1], SMBBLKDAT);
+       }
+
+       if (i801_transaction(I801_BLOCK_DATA | ENABLE_INT9 |
+                            I801_PEC_EN * hwpec))
+               return -1;
+
+       if (read_write == I2C_SMBUS_READ) {
+               len = inb_p(SMBHSTDAT0);
+               if (len < 1 || len > I2C_SMBUS_BLOCK_MAX)
+                       return -1;
+
+               data->block[0] = len;
+               for (i = 0; i < len; i++)
+                       data->block[i + 1] = inb_p(SMBBLKDAT);
+       }
+       return 0;
+}
+
+static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data,
+                                              char read_write, int hwpec)
 {
        int i, len;
        int smbcmd;
        int temp;
        int result = 0;
        int timeout;
-       unsigned char hostc, errmask;
+       unsigned char errmask;
 
-       if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
-               if (read_write == I2C_SMBUS_WRITE) {
-                       /* set I2C_EN bit in configuration register */
-                       pci_read_config_byte(I801_dev, SMBHSTCFG, &hostc);
-                       pci_write_config_byte(I801_dev, SMBHSTCFG,
-                                             hostc | SMBHSTCFG_I2C_EN);
-               } else {
-                       dev_err(&I801_dev->dev,
-                               "I2C_SMBUS_I2C_BLOCK_READ not DB!\n");
-                       return -1;
-               }
-       }
+       len = data->block[0];
 
        if (read_write == I2C_SMBUS_WRITE) {
-               len = data->block[0];
-               if (len < 1)
-                       len = 1;
-               if (len > 32)
-                       len = 32;
                outb_p(len, SMBHSTDAT0);
                outb_p(data->block[1], SMBBLKDAT);
-       } else {
-               len = 32;       /* max for reads */
-       }
-
-       if(isich4 && command != I2C_SMBUS_I2C_BLOCK_DATA) {
-               /* set 32 byte buffer */
        }
 
        for (i = 1; i <= len; i++) {
@@ -227,13 +272,13 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
                /* Make sure the SMBus host is ready to start transmitting */
                temp = inb_p(SMBHSTSTS);
                if (i == 1) {
-                       /* Erronenous conditions before transaction: 
+                       /* Erronenous conditions before transaction:
                         * Byte_Done, Failed, Bus_Err, Dev_Err, Intr, Host_Busy */
-                       errmask=0x9f; 
+                       errmask = 0x9f;
                } else {
-                       /* Erronenous conditions during transaction: 
+                       /* Erronenous conditions during transaction:
                         * Failed, Bus_Err, Dev_Err, Intr */
-                       errmask=0x1e; 
+                       errmask = 0x1e;
                }
                if (temp & errmask) {
                        dev_dbg(&I801_dev->dev, "SMBus busy (%02x). "
@@ -242,14 +287,11 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
                        if (((temp = inb_p(SMBHSTSTS)) & errmask) != 0x00) {
                                dev_err(&I801_dev->dev,
                                        "Reset failed! (%02x)\n", temp);
-                               result = -1;
-                                goto END;
+                               return -1;
                        }
-                       if (i != 1) {
+                       if (i != 1)
                                /* if die in middle of block transaction, fail */
-                               result = -1;
-                               goto END;
-                       }
+                               return -1;
                }
 
                if (i == 1)
@@ -261,33 +303,38 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
                        msleep(1);
                        temp = inb_p(SMBHSTSTS);
                }
-                   while ((!(temp & 0x80))
-                          && (timeout++ < MAX_TIMEOUT));
+               while ((!(temp & SMBHSTSTS_BYTE_DONE))
+                      && (timeout++ < MAX_TIMEOUT));
 
                /* If the SMBus is still busy, we give up */
                if (timeout >= MAX_TIMEOUT) {
+                       /* try to stop the current command */
+                       dev_dbg(&I801_dev->dev, "Terminating the current "
+                                               "operation\n");
+                       outb_p(inb_p(SMBHSTCNT) | SMBHSTCNT_KILL, SMBHSTCNT);
+                       msleep(1);
+                       outb_p(inb_p(SMBHSTCNT) & (~SMBHSTCNT_KILL),
+                               SMBHSTCNT);
                        result = -1;
                        dev_dbg(&I801_dev->dev, "SMBus Timeout!\n");
                }
 
-               if (temp & 0x10) {
+               if (temp & SMBHSTSTS_FAILED) {
                        result = -1;
                        dev_dbg(&I801_dev->dev,
                                "Error: Failed bus transaction\n");
-               } else if (temp & 0x08) {
+               } else if (temp & SMBHSTSTS_BUS_ERR) {
                        result = -1;
                        dev_err(&I801_dev->dev, "Bus collision!\n");
-               } else if (temp & 0x04) {
+               } else if (temp & SMBHSTSTS_DEV_ERR) {
                        result = -1;
                        dev_dbg(&I801_dev->dev, "Error: no response!\n");
                }
 
                if (i == 1 && read_write == I2C_SMBUS_READ) {
                        len = inb_p(SMBHSTDAT0);
-                       if (len < 1)
-                               len = 1;
-                       if (len > 32)
-                               len = 32;
+                       if (len < 1 || len > I2C_SMBUS_BLOCK_MAX)
+                               return -1;
                        data->block[0] = len;
                }
 
@@ -310,25 +357,58 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
                        inb_p(SMBHSTDAT0), inb_p(SMBBLKDAT));
 
                if (result < 0)
-                       goto END;
+                       return result;
        }
+       return result;
+}
 
-       if (hwpec) {
-               /* wait for INTR bit as advised by Intel */
-               timeout = 0;
-               do {
-                       msleep(1);
-                       temp = inb_p(SMBHSTSTS);
-               } while ((!(temp & 0x02))
-                          && (timeout++ < MAX_TIMEOUT));
+static int i801_set_block_buffer_mode(void)
+{
+       outb_p(inb_p(SMBAUXCTL) | SMBAUXCTL_E32B, SMBAUXCTL);
+       if ((inb_p(SMBAUXCTL) & SMBAUXCTL_E32B) == 0)
+               return -1;
+       return 0;
+}
 
-               if (timeout >= MAX_TIMEOUT) {
-                       dev_dbg(&I801_dev->dev, "PEC Timeout!\n");
+/* Block transaction function */
+static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
+                                 int command, int hwpec)
+{
+       int result = 0;
+       unsigned char hostc;
+
+       if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
+               if (read_write == I2C_SMBUS_WRITE) {
+                       /* set I2C_EN bit in configuration register */
+                       pci_read_config_byte(I801_dev, SMBHSTCFG, &hostc);
+                       pci_write_config_byte(I801_dev, SMBHSTCFG,
+                                             hostc | SMBHSTCFG_I2C_EN);
+               } else {
+                       dev_err(&I801_dev->dev,
+                               "I2C_SMBUS_I2C_BLOCK_READ not DB!\n");
+                       return -1;
                }
-               outb_p(temp, SMBHSTSTS); 
        }
-       result = 0;
-END:
+
+       if (read_write == I2C_SMBUS_WRITE) {
+               if (data->block[0] < 1)
+                       data->block[0] = 1;
+               if (data->block[0] > I2C_SMBUS_BLOCK_MAX)
+                       data->block[0] = I2C_SMBUS_BLOCK_MAX;
+       } else {
+               data->block[0] = 32;    /* max for reads */
+       }
+
+       if (isich4 && i801_set_block_buffer_mode() == 0 )
+               result = i801_block_transaction_by_block(data, read_write,
+                                                        hwpec);
+       else
+               result = i801_block_transaction_byte_by_byte(data, read_write,
+                                                            hwpec);
+
+       if (result == 0 && hwpec)
+               i801_wait_hwpec();
+
        if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
                /* restore saved configuration register value */
                pci_write_config_byte(I801_dev, SMBHSTCFG, hostc);
@@ -393,19 +473,22 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr,
                return -1;
        }
 
-       outb_p(hwpec, SMBAUXCTL);       /* enable/disable hardware PEC */
+       if (hwpec)      /* enable/disable hardware PEC */
+               outb_p(inb_p(SMBAUXCTL) | SMBAUXCTL_CRC, SMBAUXCTL);
+       else
+               outb_p(inb_p(SMBAUXCTL) & (~SMBAUXCTL_CRC), SMBAUXCTL);
 
        if(block)
                ret = i801_block_transaction(data, read_write, size, hwpec);
-       else {
-               outb_p(xact | ENABLE_INT9, SMBHSTCNT);
-               ret = i801_transaction();
-       }
+       else
+               ret = i801_transaction(xact | ENABLE_INT9);
 
        /* Some BIOSes don't like it when PEC is enabled at reboot or resume
-          time, so we forcibly disable it after every transaction. */
+          time, so we forcibly disable it after every transaction. Turn off
+          E32B for the same reason. */
        if (hwpec)
-               outb_p(0, SMBAUXCTL);
+               outb_p(inb_p(SMBAUXCTL) & ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B),
+                      SMBAUXCTL);
 
        if(block)
                return ret;
index 90e2d9350c1bd12d390a2495872c837cc5959a5f..440342bc62e183d0d20b8acced8ea0a9a5cd5b86 100644 (file)
@@ -491,6 +491,7 @@ iop3xx_i2c_probe(struct platform_device *pdev)
        new_adapter->id = I2C_HW_IOP3XX;
        new_adapter->owner = THIS_MODULE;
        new_adapter->dev.parent = &pdev->dev;
+       new_adapter->nr = pdev->id;
 
        /*
         * Default values...should these come in from board code?
@@ -508,7 +509,7 @@ iop3xx_i2c_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, new_adapter);
        new_adapter->algo_data = adapter_data;
 
-       i2c_add_adapter(new_adapter);
+       i2c_add_numbered_adapter(new_adapter);
 
        return 0;
 
index c6b6898592b19af7573dbe0d5b19322775959a07..851c3ed513d015e50b5c75c362a014dfa09c1c1d 100644 (file)
@@ -74,6 +74,25 @@ static irqreturn_t mpc_i2c_isr(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
+/* Sometimes 9th clock pulse isn't generated, and slave doesn't release
+ * the bus, because it wants to send ACK.
+ * Following sequence of enabling/disabling and sending start/stop generates
+ * the pulse, so it's all OK.
+ */
+static void mpc_i2c_fixup(struct mpc_i2c *i2c)
+{
+       writeccr(i2c, 0);
+       udelay(30);
+       writeccr(i2c, CCR_MEN);
+       udelay(30);
+       writeccr(i2c, CCR_MSTA | CCR_MTX);
+       udelay(30);
+       writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN);
+       udelay(30);
+       writeccr(i2c, CCR_MEN);
+       udelay(30);
+}
+
 static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
 {
        unsigned long orig_jiffies = jiffies;
@@ -153,6 +172,7 @@ static void mpc_i2c_start(struct mpc_i2c *i2c)
 static void mpc_i2c_stop(struct mpc_i2c *i2c)
 {
        writeccr(i2c, CCR_MEN);
+       writeccr(i2c, 0);
 }
 
 static int mpc_write(struct mpc_i2c *i2c, int target,
@@ -245,6 +265,9 @@ static int mpc_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
                }
                if (time_after(jiffies, orig_jiffies + HZ)) {
                        pr_debug("I2C: timeout\n");
+                       if (readb(i2c->base + MPC_I2C_SR) ==
+                           (CSR_MCF | CSR_MBB | CSR_RXAK))
+                               mpc_i2c_fixup(i2c);
                        return -EIO;
                }
                schedule();
@@ -327,9 +350,10 @@ static int fsl_i2c_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, i2c);
 
        i2c->adap = mpc_ops;
+       i2c->adap.nr = pdev->id;
        i2c_set_adapdata(&i2c->adap, i2c);
        i2c->adap.dev.parent = &pdev->dev;
-       if ((result = i2c_add_adapter(&i2c->adap)) < 0) {
+       if ((result = i2c_add_numbered_adapter(&i2c->adap)) < 0) {
                printk(KERN_ERR "i2c-mpc - failed to add adapter\n");
                goto fail_add;
        }
index a55b3335d1becd05d5ebbcafb8d4477b50f9d099..251154ae5d97ad3eb0bddff1067c3a655075ba5f 100644 (file)
@@ -527,6 +527,7 @@ mv64xxx_i2c_probe(struct platform_device *pd)
        drv_data->adapter.class = I2C_CLASS_HWMON;
        drv_data->adapter.timeout = pdata->timeout;
        drv_data->adapter.retries = pdata->retries;
+       drv_data->adapter.nr = pd->id;
        platform_set_drvdata(pd, drv_data);
        i2c_set_adapdata(&drv_data->adapter, drv_data);
 
@@ -539,7 +540,7 @@ mv64xxx_i2c_probe(struct platform_device *pd)
                        drv_data->irq);
                rc = -EINVAL;
                goto exit_unmap_regs;
-       } else if ((rc = i2c_add_adapter(&drv_data->adapter)) != 0) {
+       } else if ((rc = i2c_add_numbered_adapter(&drv_data->adapter)) != 0) {
                dev_err(&drv_data->adapter.dev,
                        "mv64xxx: Can't add i2c adapter, rc: %d\n", -rc);
                goto exit_free_irq;
index 3cd0d63e7b501c047e04e52945211e988409b0a1..c48140f782d09c276dcb4c6b31d5201dd213b6dd 100644 (file)
@@ -61,6 +61,7 @@ struct nforce2_smbus {
        struct i2c_adapter adapter;
        int base;
        int size;
+       int blockops;
 };
 
 
@@ -80,6 +81,8 @@ struct nforce2_smbus {
 #define NVIDIA_SMB_ADDR                (smbus->base + 0x02)    /* address */
 #define NVIDIA_SMB_CMD         (smbus->base + 0x03)    /* command */
 #define NVIDIA_SMB_DATA                (smbus->base + 0x04)    /* 32 data registers */
+#define NVIDIA_SMB_BCNT                (smbus->base + 0x24)    /* number of data
+                                                          bytes */
 
 #define NVIDIA_SMB_STS_DONE    0x80
 #define NVIDIA_SMB_STS_ALRM    0x40
@@ -92,6 +95,7 @@ struct nforce2_smbus {
 #define NVIDIA_SMB_PRTCL_BYTE                  0x04
 #define NVIDIA_SMB_PRTCL_BYTE_DATA             0x06
 #define NVIDIA_SMB_PRTCL_WORD_DATA             0x08
+#define NVIDIA_SMB_PRTCL_BLOCK_DATA            0x0a
 #define NVIDIA_SMB_PRTCL_PEC                   0x80
 
 static struct pci_driver nforce2_driver;
@@ -103,6 +107,8 @@ static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
 {
        struct nforce2_smbus *smbus = adap->algo_data;
        unsigned char protocol, pec, temp;
+       u8 len;
+       int i;
 
        protocol = (read_write == I2C_SMBUS_READ) ? NVIDIA_SMB_PRTCL_READ :
                NVIDIA_SMB_PRTCL_WRITE;
@@ -137,6 +143,25 @@ static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
                        protocol |= NVIDIA_SMB_PRTCL_WORD_DATA | pec;
                        break;
 
+               case I2C_SMBUS_BLOCK_DATA:
+                       outb_p(command, NVIDIA_SMB_CMD);
+                       if (read_write == I2C_SMBUS_WRITE) {
+                               len = data->block[0];
+                               if ((len == 0) || (len > I2C_SMBUS_BLOCK_MAX)) {
+                                       dev_err(&adap->dev,
+                                               "Transaction failed "
+                                               "(requested block size: %d)\n",
+                                               len);
+                                       return -1;
+                               }
+                               outb_p(len, NVIDIA_SMB_BCNT);
+                               for (i = 0; i < I2C_SMBUS_BLOCK_MAX; i++)
+                                       outb_p(data->block[i + 1],
+                                              NVIDIA_SMB_DATA+i);
+                       }
+                       protocol |= NVIDIA_SMB_PRTCL_BLOCK_DATA | pec;
+                       break;
+
                default:
                        dev_err(&adap->dev, "Unsupported transaction %d\n", size);
                        return -1;
@@ -174,6 +199,14 @@ static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
                case I2C_SMBUS_WORD_DATA:
                        data->word = inb_p(NVIDIA_SMB_DATA) | (inb_p(NVIDIA_SMB_DATA+1) << 8);
                        break;
+
+               case I2C_SMBUS_BLOCK_DATA:
+                       len = inb_p(NVIDIA_SMB_BCNT);
+                       len = min_t(u8, len, I2C_SMBUS_BLOCK_MAX);
+                       for (i = 0; i < len; i++)
+                               data->block[i+1] = inb_p(NVIDIA_SMB_DATA + i);
+                       data->block[0] = len;
+                       break;
        }
 
        return 0;
@@ -184,7 +217,9 @@ static u32 nforce2_func(struct i2c_adapter *adapter)
 {
        /* other functionality might be possible, but is not tested */
        return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
-           I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA;
+              I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
+              (((struct nforce2_smbus*)adapter->algo_data)->blockops ?
+               I2C_FUNC_SMBUS_BLOCK_DATA : 0);
 }
 
 static struct i2c_algorithm smbus_algorithm = {
@@ -268,6 +303,13 @@ static int __devinit nforce2_probe(struct pci_dev *dev, const struct pci_device_
                return -ENOMEM;
        pci_set_drvdata(dev, smbuses);
 
+       switch(dev->device) {
+       case PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SMBUS:
+       case PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SMBUS:
+               smbuses[0].blockops = 1;
+               smbuses[1].blockops = 1;
+       }
+
        /* SMBus adapter 1 */
        res1 = nforce2_probe_smb(dev, 4, NFORCE_PCI_SMB1, &smbuses[0], "SMB1");
        if (res1 < 0) {
index 5a52bf5e3fb0a8c2f93263fa4e95e85e1b50763f..debc76cd2161c64b1c675d196ec8d40e3b9c8e50 100644 (file)
@@ -23,7 +23,7 @@
    Supports:
        Intel PIIX4, 440MX
        Serverworks OSB4, CSB5, CSB6, HT-1000
-       ATI IXP200, IXP300, IXP400, SB600
+       ATI IXP200, IXP300, IXP400, SB600, SB700
        SMSC Victory66
 
    Note: we assume there can only be one device, with one SMBus interface.
@@ -399,6 +399,8 @@ static struct pci_device_id piix4_ids[] = {
          .driver_data = 0 },
        { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SMBUS),
          .driver_data = 0 },
+       { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SMBUS),
+         .driver_data = 0 },
        { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4),
          .driver_data = 0 },
        { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5),
diff --git a/drivers/i2c/busses/i2c-pmcmsp.c b/drivers/i2c/busses/i2c-pmcmsp.c
new file mode 100644 (file)
index 0000000..03188d2
--- /dev/null
@@ -0,0 +1,653 @@
+/*
+ * Specific bus support for PMC-TWI compliant implementation on MSP71xx.
+ *
+ * Copyright 2005-2007 PMC-Sierra, Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/completion.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+
+#define DRV_NAME       "pmcmsptwi"
+
+#define MSP_TWI_SF_CLK_REG_OFFSET      0x00
+#define MSP_TWI_HS_CLK_REG_OFFSET      0x04
+#define MSP_TWI_CFG_REG_OFFSET         0x08
+#define MSP_TWI_CMD_REG_OFFSET         0x0c
+#define MSP_TWI_ADD_REG_OFFSET         0x10
+#define MSP_TWI_DAT_0_REG_OFFSET       0x14
+#define MSP_TWI_DAT_1_REG_OFFSET       0x18
+#define MSP_TWI_INT_STS_REG_OFFSET     0x1c
+#define MSP_TWI_INT_MSK_REG_OFFSET     0x20
+#define MSP_TWI_BUSY_REG_OFFSET                0x24
+
+#define MSP_TWI_INT_STS_DONE                   (1 << 0)
+#define MSP_TWI_INT_STS_LOST_ARBITRATION       (1 << 1)
+#define MSP_TWI_INT_STS_NO_RESPONSE            (1 << 2)
+#define MSP_TWI_INT_STS_DATA_COLLISION         (1 << 3)
+#define MSP_TWI_INT_STS_BUSY                   (1 << 4)
+#define MSP_TWI_INT_STS_ALL                    0x1f
+
+#define MSP_MAX_BYTES_PER_RW           8
+#define MSP_MAX_POLL                   5
+#define MSP_POLL_DELAY                 10
+#define MSP_IRQ_TIMEOUT                        (MSP_MAX_POLL * MSP_POLL_DELAY)
+
+/* IO Operation macros */
+#define pmcmsptwi_readl                __raw_readl
+#define pmcmsptwi_writel       __raw_writel
+
+/* TWI command type */
+enum pmcmsptwi_cmd_type {
+       MSP_TWI_CMD_WRITE       = 0,    /* Write only */
+       MSP_TWI_CMD_READ        = 1,    /* Read only */
+       MSP_TWI_CMD_WRITE_READ  = 2,    /* Write then Read */
+};
+
+/* The possible results of the xferCmd */
+enum pmcmsptwi_xfer_result {
+       MSP_TWI_XFER_OK = 0,
+       MSP_TWI_XFER_TIMEOUT,
+       MSP_TWI_XFER_BUSY,
+       MSP_TWI_XFER_DATA_COLLISION,
+       MSP_TWI_XFER_NO_RESPONSE,
+       MSP_TWI_XFER_LOST_ARBITRATION,
+};
+
+/* Corresponds to a PMCTWI clock configuration register */
+struct pmcmsptwi_clock {
+       u8 filter;      /* Bits 15:12,  default = 0x03 */
+       u16 clock;      /* Bits 9:0,    default = 0x001f */
+};
+
+struct pmcmsptwi_clockcfg {
+       struct pmcmsptwi_clock standard;  /* The standard/fast clock config */
+       struct pmcmsptwi_clock highspeed; /* The highspeed clock config */
+};
+
+/* Corresponds to the main TWI configuration register */
+struct pmcmsptwi_cfg {
+       u8 arbf;        /* Bits 15:12,  default=0x03 */
+       u8 nak;         /* Bits 11:8,   default=0x03 */
+       u8 add10;       /* Bit 7,       default=0x00 */
+       u8 mst_code;    /* Bits 6:4,    default=0x00 */
+       u8 arb;         /* Bit 1,       default=0x01 */
+       u8 highspeed;   /* Bit 0,       default=0x00 */
+};
+
+/* A single pmctwi command to issue */
+struct pmcmsptwi_cmd {
+       u16 addr;       /* The slave address (7 or 10 bits) */
+       enum pmcmsptwi_cmd_type type;   /* The command type */
+       u8 write_len;   /* Number of bytes in the write buffer */
+       u8 read_len;    /* Number of bytes in the read buffer */
+       u8 *write_data; /* Buffer of characters to send */
+       u8 *read_data;  /* Buffer to fill with incoming data */
+};
+
+/* The private data */
+struct pmcmsptwi_data {
+       void __iomem *iobase;                   /* iomapped base for IO */
+       int irq;                                /* IRQ to use (0 disables) */
+       struct completion wait;                 /* Completion for xfer */
+       struct mutex lock;                      /* Used for threadsafeness */
+       enum pmcmsptwi_xfer_result last_result; /* result of last xfer */
+};
+
+/* The default settings */
+const static struct pmcmsptwi_clockcfg pmcmsptwi_defclockcfg = {
+       .standard = {
+               .filter = 0x3,
+               .clock  = 0x1f,
+       },
+       .highspeed = {
+               .filter = 0x3,
+               .clock  = 0x1f,
+       },
+};
+
+const static struct pmcmsptwi_cfg pmcmsptwi_defcfg = {
+       .arbf           = 0x03,
+       .nak            = 0x03,
+       .add10          = 0x00,
+       .mst_code       = 0x00,
+       .arb            = 0x01,
+       .highspeed      = 0x00,
+};
+
+static struct pmcmsptwi_data pmcmsptwi_data;
+
+static struct i2c_adapter pmcmsptwi_adapter;
+
+/* inline helper functions */
+static inline u32 pmcmsptwi_clock_to_reg(
+                       const struct pmcmsptwi_clock *clock)
+{
+       return ((clock->filter & 0xf) << 12) | (clock->clock & 0x03ff);
+}
+
+static inline void pmcmsptwi_reg_to_clock(
+                       u32 reg, struct pmcmsptwi_clock *clock)
+{
+       clock->filter = (reg >> 12) & 0xf;
+       clock->clock = reg & 0x03ff;
+}
+
+static inline u32 pmcmsptwi_cfg_to_reg(const struct pmcmsptwi_cfg *cfg)
+{
+       return ((cfg->arbf & 0xf) << 12) |
+               ((cfg->nak & 0xf) << 8) |
+               ((cfg->add10 & 0x1) << 7) |
+               ((cfg->mst_code & 0x7) << 4) |
+               ((cfg->arb & 0x1) << 1) |
+               (cfg->highspeed & 0x1);
+}
+
+static inline void pmcmsptwi_reg_to_cfg(u32 reg, struct pmcmsptwi_cfg *cfg)
+{
+       cfg->arbf = (reg >> 12) & 0xf;
+       cfg->nak = (reg >> 8) & 0xf;
+       cfg->add10 = (reg >> 7) & 0x1;
+       cfg->mst_code = (reg >> 4) & 0x7;
+       cfg->arb = (reg >> 1) & 0x1;
+       cfg->highspeed = reg & 0x1;
+}
+
+/*
+ * Sets the current clock configuration
+ */
+static void pmcmsptwi_set_clock_config(const struct pmcmsptwi_clockcfg *cfg,
+                                       struct pmcmsptwi_data *data)
+{
+       mutex_lock(&data->lock);
+       pmcmsptwi_writel(pmcmsptwi_clock_to_reg(&cfg->standard),
+                               data->iobase + MSP_TWI_SF_CLK_REG_OFFSET);
+       pmcmsptwi_writel(pmcmsptwi_clock_to_reg(&cfg->highspeed),
+                               data->iobase + MSP_TWI_HS_CLK_REG_OFFSET);
+       mutex_unlock(&data->lock);
+}
+
+/*
+ * Gets the current TWI bus configuration
+ */
+static void pmcmsptwi_get_twi_config(struct pmcmsptwi_cfg *cfg,
+                                       struct pmcmsptwi_data *data)
+{
+       mutex_lock(&data->lock);
+       pmcmsptwi_reg_to_cfg(pmcmsptwi_readl(
+                               data->iobase + MSP_TWI_CFG_REG_OFFSET), cfg);
+       mutex_unlock(&data->lock);
+}
+
+/*
+ * Sets the current TWI bus configuration
+ */
+static void pmcmsptwi_set_twi_config(const struct pmcmsptwi_cfg *cfg,
+                                       struct pmcmsptwi_data *data)
+{
+       mutex_lock(&data->lock);
+       pmcmsptwi_writel(pmcmsptwi_cfg_to_reg(cfg),
+                               data->iobase + MSP_TWI_CFG_REG_OFFSET);
+       mutex_unlock(&data->lock);
+}
+
+/*
+ * Parses the 'int_sts' register and returns a well-defined error code
+ */
+static enum pmcmsptwi_xfer_result pmcmsptwi_get_result(u32 reg)
+{
+       if (reg & MSP_TWI_INT_STS_LOST_ARBITRATION) {
+               dev_dbg(&pmcmsptwi_adapter.dev,
+                       "Result: Lost arbitration\n");
+               return MSP_TWI_XFER_LOST_ARBITRATION;
+       } else if (reg & MSP_TWI_INT_STS_NO_RESPONSE) {
+               dev_dbg(&pmcmsptwi_adapter.dev,
+                       "Result: No response\n");
+               return MSP_TWI_XFER_NO_RESPONSE;
+       } else if (reg & MSP_TWI_INT_STS_DATA_COLLISION) {
+               dev_dbg(&pmcmsptwi_adapter.dev,
+                       "Result: Data collision\n");
+               return MSP_TWI_XFER_DATA_COLLISION;
+       } else if (reg & MSP_TWI_INT_STS_BUSY) {
+               dev_dbg(&pmcmsptwi_adapter.dev,
+                       "Result: Bus busy\n");
+               return MSP_TWI_XFER_BUSY;
+       }
+
+       dev_dbg(&pmcmsptwi_adapter.dev, "Result: Operation succeeded\n");
+       return MSP_TWI_XFER_OK;
+}
+
+/*
+ * In interrupt mode, handle the interrupt.
+ * NOTE: Assumes data->lock is held.
+ */
+static irqreturn_t pmcmsptwi_interrupt(int irq, void *ptr)
+{
+       struct pmcmsptwi_data *data = ptr;
+
+       u32 reason = pmcmsptwi_readl(data->iobase +
+                                       MSP_TWI_INT_STS_REG_OFFSET);
+       pmcmsptwi_writel(reason, data->iobase + MSP_TWI_INT_STS_REG_OFFSET);
+
+       dev_dbg(&pmcmsptwi_adapter.dev, "Got interrupt 0x%08x\n", reason);
+       if (!(reason & MSP_TWI_INT_STS_DONE))
+               return IRQ_NONE;
+
+       data->last_result = pmcmsptwi_get_result(reason);
+       complete(&data->wait);
+
+       return IRQ_HANDLED;
+}
+
+/*
+ * Probe for and register the device and return 0 if there is one.
+ */
+static int __devinit pmcmsptwi_probe(struct platform_device *pldev)
+{
+       struct resource *res;
+       int rc = -ENODEV;
+
+       /* get the static platform resources */
+       res = platform_get_resource(pldev, IORESOURCE_MEM, 0);
+       if (!res) {
+               dev_err(&pldev->dev, "IOMEM resource not found\n");
+               goto ret_err;
+       }
+
+       /* reserve the memory region */
+       if (!request_mem_region(res->start, res->end - res->start + 1,
+                               pldev->name)) {
+               dev_err(&pldev->dev,
+                       "Unable to get memory/io address region 0x%08x\n",
+                       res->start);
+               rc = -EBUSY;
+               goto ret_err;
+       }
+
+       /* remap the memory */
+       pmcmsptwi_data.iobase = ioremap_nocache(res->start,
+                                               res->end - res->start + 1);
+       if (!pmcmsptwi_data.iobase) {
+               dev_err(&pldev->dev,
+                       "Unable to ioremap address 0x%08x\n", res->start);
+               rc = -EIO;
+               goto ret_unreserve;
+       }
+
+       /* request the irq */
+       pmcmsptwi_data.irq = platform_get_irq(pldev, 0);
+       if (pmcmsptwi_data.irq) {
+               rc = request_irq(pmcmsptwi_data.irq, &pmcmsptwi_interrupt,
+                       IRQF_SHARED | IRQF_DISABLED | IRQF_SAMPLE_RANDOM,
+                       pldev->name, &pmcmsptwi_data);
+               if (rc == 0) {
+                       /*
+                        * Enable 'DONE' interrupt only.
+                        *
+                        * If you enable all interrupts, you will get one on
+                        * error and another when the operation completes.
+                        * This way you only have to handle one interrupt,
+                        * but you can still check all result flags.
+                        */
+                       pmcmsptwi_writel(MSP_TWI_INT_STS_DONE,
+                                       pmcmsptwi_data.iobase +
+                                       MSP_TWI_INT_MSK_REG_OFFSET);
+               } else {
+                       dev_warn(&pldev->dev,
+                               "Could not assign TWI IRQ handler "
+                               "to irq %d (continuing with poll)\n",
+                               pmcmsptwi_data.irq);
+                       pmcmsptwi_data.irq = 0;
+               }
+       }
+
+       init_completion(&pmcmsptwi_data.wait);
+       mutex_init(&pmcmsptwi_data.lock);
+
+       pmcmsptwi_set_clock_config(&pmcmsptwi_defclockcfg, &pmcmsptwi_data);
+       pmcmsptwi_set_twi_config(&pmcmsptwi_defcfg, &pmcmsptwi_data);
+
+       printk(KERN_INFO DRV_NAME ": Registering MSP71xx I2C adapter\n");
+
+       pmcmsptwi_adapter.dev.parent = &pldev->dev;
+       platform_set_drvdata(pldev, &pmcmsptwi_adapter);
+       i2c_set_adapdata(&pmcmsptwi_adapter, &pmcmsptwi_data);
+
+       rc = i2c_add_adapter(&pmcmsptwi_adapter);
+       if (rc) {
+               dev_err(&pldev->dev, "Unable to register I2C adapter\n");
+               goto ret_unmap;
+       }
+
+       return 0;
+
+ret_unmap:
+       platform_set_drvdata(pldev, NULL);
+       if (pmcmsptwi_data.irq) {
+               pmcmsptwi_writel(0,
+                       pmcmsptwi_data.iobase + MSP_TWI_INT_MSK_REG_OFFSET);
+               free_irq(pmcmsptwi_data.irq, &pmcmsptwi_data);
+       }
+
+       iounmap(pmcmsptwi_data.iobase);
+
+ret_unreserve:
+       release_mem_region(res->start, res->end - res->start + 1);
+
+ret_err:
+       return rc;
+}
+
+/*
+ * Release the device and return 0 if there is one.
+ */
+static int __devexit pmcmsptwi_remove(struct platform_device *pldev)
+{
+       struct resource *res;
+
+       i2c_del_adapter(&pmcmsptwi_adapter);
+
+       platform_set_drvdata(pldev, NULL);
+       if (pmcmsptwi_data.irq) {
+               pmcmsptwi_writel(0,
+                       pmcmsptwi_data.iobase + MSP_TWI_INT_MSK_REG_OFFSET);
+               free_irq(pmcmsptwi_data.irq, &pmcmsptwi_data);
+       }
+
+       iounmap(pmcmsptwi_data.iobase);
+
+       res = platform_get_resource(pldev, IORESOURCE_MEM, 0);
+       release_mem_region(res->start, res->end - res->start + 1);
+
+       return 0;
+}
+
+/*
+ * Polls the 'busy' register until the command is complete.
+ * NOTE: Assumes data->lock is held.
+ */
+static void pmcmsptwi_poll_complete(struct pmcmsptwi_data *data)
+{
+       int i;
+
+       for (i = 0; i < MSP_MAX_POLL; i++) {
+               u32 val = pmcmsptwi_readl(data->iobase +
+                                               MSP_TWI_BUSY_REG_OFFSET);
+               if (val == 0) {
+                       u32 reason = pmcmsptwi_readl(data->iobase +
+                                               MSP_TWI_INT_STS_REG_OFFSET);
+                       pmcmsptwi_writel(reason, data->iobase +
+                                               MSP_TWI_INT_STS_REG_OFFSET);
+                       data->last_result = pmcmsptwi_get_result(reason);
+                       return;
+               }
+               udelay(MSP_POLL_DELAY);
+       }
+
+       dev_dbg(&pmcmsptwi_adapter.dev, "Result: Poll timeout\n");
+       data->last_result = MSP_TWI_XFER_TIMEOUT;
+}
+
+/*
+ * Do the transfer (low level):
+ *   May use interrupt-driven or polling, depending on if an IRQ is
+ *   presently registered.
+ * NOTE: Assumes data->lock is held.
+ */
+static enum pmcmsptwi_xfer_result pmcmsptwi_do_xfer(
+                       u32 reg, struct pmcmsptwi_data *data)
+{
+       dev_dbg(&pmcmsptwi_adapter.dev, "Writing cmd reg 0x%08x\n", reg);
+       pmcmsptwi_writel(reg, data->iobase + MSP_TWI_CMD_REG_OFFSET);
+       if (data->irq) {
+               unsigned long timeleft = wait_for_completion_timeout(
+                                               &data->wait, MSP_IRQ_TIMEOUT);
+               if (timeleft == 0) {
+                       dev_dbg(&pmcmsptwi_adapter.dev,
+                               "Result: IRQ timeout\n");
+                       complete(&data->wait);
+                       data->last_result = MSP_TWI_XFER_TIMEOUT;
+               }
+       } else
+               pmcmsptwi_poll_complete(data);
+
+       return data->last_result;
+}
+
+/*
+ * Helper routine, converts 'pmctwi_cmd' struct to register format
+ */
+static inline u32 pmcmsptwi_cmd_to_reg(const struct pmcmsptwi_cmd *cmd)
+{
+       return ((cmd->type & 0x3) << 8) |
+               (((cmd->write_len - 1) & 0x7) << 4) |
+               ((cmd->read_len - 1) & 0x7);
+}
+
+/*
+ * Do the transfer (high level)
+ */
+static enum pmcmsptwi_xfer_result pmcmsptwi_xfer_cmd(
+                       struct pmcmsptwi_cmd *cmd,
+                       struct pmcmsptwi_data *data)
+{
+       enum pmcmsptwi_xfer_result retval;
+
+       if ((cmd->type == MSP_TWI_CMD_WRITE && cmd->write_len == 0) ||
+           (cmd->type == MSP_TWI_CMD_READ && cmd->read_len == 0) ||
+           (cmd->type == MSP_TWI_CMD_WRITE_READ &&
+           (cmd->read_len == 0 || cmd->write_len == 0))) {
+               dev_err(&pmcmsptwi_adapter.dev,
+                       "%s: Cannot transfer less than 1 byte\n",
+                       __FUNCTION__);
+               return -EINVAL;
+       }
+
+       if (cmd->read_len > MSP_MAX_BYTES_PER_RW ||
+           cmd->write_len > MSP_MAX_BYTES_PER_RW) {
+               dev_err(&pmcmsptwi_adapter.dev,
+                       "%s: Cannot transfer more than %d bytes\n",
+                       __FUNCTION__, MSP_MAX_BYTES_PER_RW);
+               return -EINVAL;
+       }
+
+       mutex_lock(&data->lock);
+       dev_dbg(&pmcmsptwi_adapter.dev,
+               "Setting address to 0x%04x\n", cmd->addr);
+       pmcmsptwi_writel(cmd->addr, data->iobase + MSP_TWI_ADD_REG_OFFSET);
+
+       if (cmd->type == MSP_TWI_CMD_WRITE ||
+           cmd->type == MSP_TWI_CMD_WRITE_READ) {
+               __be64 tmp = cpu_to_be64p((u64 *)cmd->write_data);
+               tmp >>= (MSP_MAX_BYTES_PER_RW - cmd->write_len) * 8;
+               dev_dbg(&pmcmsptwi_adapter.dev, "Writing 0x%016llx\n", tmp);
+               pmcmsptwi_writel(tmp & 0x00000000ffffffffLL,
+                               data->iobase + MSP_TWI_DAT_0_REG_OFFSET);
+               if (cmd->write_len > 4)
+                       pmcmsptwi_writel(tmp >> 32,
+                               data->iobase + MSP_TWI_DAT_1_REG_OFFSET);
+       }
+
+       retval = pmcmsptwi_do_xfer(pmcmsptwi_cmd_to_reg(cmd), data);
+       if (retval != MSP_TWI_XFER_OK)
+               goto xfer_err;
+
+       if (cmd->type == MSP_TWI_CMD_READ ||
+           cmd->type == MSP_TWI_CMD_WRITE_READ) {
+               int i;
+               u64 rmsk = ~(0xffffffffffffffffLL << (cmd->read_len * 8));
+               u64 tmp = (u64)pmcmsptwi_readl(data->iobase +
+                                       MSP_TWI_DAT_0_REG_OFFSET);
+               if (cmd->read_len > 4)
+                       tmp |= (u64)pmcmsptwi_readl(data->iobase +
+                                       MSP_TWI_DAT_1_REG_OFFSET) << 32;
+               tmp &= rmsk;
+               dev_dbg(&pmcmsptwi_adapter.dev, "Read 0x%016llx\n", tmp);
+
+               for (i = 0; i < cmd->read_len; i++)
+                       cmd->read_data[i] = tmp >> i;
+       }
+
+xfer_err:
+       mutex_unlock(&data->lock);
+
+       return retval;
+}
+
+/* -- Algorithm functions -- */
+
+/*
+ * Sends an i2c command out on the adapter
+ */
+static int pmcmsptwi_master_xfer(struct i2c_adapter *adap,
+                               struct i2c_msg *msg, int num)
+{
+       struct pmcmsptwi_data *data = i2c_get_adapdata(adap);
+       struct pmcmsptwi_cmd cmd;
+       struct pmcmsptwi_cfg oldcfg, newcfg;
+       int ret;
+
+       if (num > 2) {
+               dev_dbg(&adap->dev, "%d messages unsupported\n", num);
+               return -EINVAL;
+       } else if (num == 2) {
+               /* Check for a dual write-then-read command */
+               struct i2c_msg *nextmsg = msg + 1;
+               if (!(msg->flags & I2C_M_RD) &&
+                   (nextmsg->flags & I2C_M_RD) &&
+                   msg->addr == nextmsg->addr) {
+                       cmd.type = MSP_TWI_CMD_WRITE_READ;
+                       cmd.write_len = msg->len;
+                       cmd.write_data = msg->buf;
+                       cmd.read_len = nextmsg->len;
+                       cmd.read_data = nextmsg->buf;
+               } else {
+                       dev_dbg(&adap->dev,
+                               "Non write-read dual messages unsupported\n");
+                       return -EINVAL;
+               }
+       } else if (msg->flags & I2C_M_RD) {
+               cmd.type = MSP_TWI_CMD_READ;
+               cmd.read_len = msg->len;
+               cmd.read_data = msg->buf;
+               cmd.write_len = 0;
+               cmd.write_data = NULL;
+       } else {
+               cmd.type = MSP_TWI_CMD_WRITE;
+               cmd.read_len = 0;
+               cmd.read_data = NULL;
+               cmd.write_len = msg->len;
+               cmd.write_data = msg->buf;
+       }
+
+       if (msg->len == 0) {
+               dev_err(&adap->dev, "Zero-byte messages unsupported\n");
+               return -EINVAL;
+       }
+
+       cmd.addr = msg->addr;
+
+       if (msg->flags & I2C_M_TEN) {
+               pmcmsptwi_get_twi_config(&newcfg, data);
+               memcpy(&oldcfg, &newcfg, sizeof(oldcfg));
+
+               /* Set the special 10-bit address flag */
+               newcfg.add10 = 1;
+
+               pmcmsptwi_set_twi_config(&newcfg, data);
+       }
+
+       /* Execute the command */
+       ret = pmcmsptwi_xfer_cmd(&cmd, data);
+
+       if (msg->flags & I2C_M_TEN)
+               pmcmsptwi_set_twi_config(&oldcfg, data);
+
+       dev_dbg(&adap->dev, "I2C %s of %d bytes ",
+               (msg->flags & I2C_M_RD) ? "read" : "write", msg->len);
+       if (ret != MSP_TWI_XFER_OK) {
+               /*
+                * TODO: We could potentially loop and retry in the case
+                * of MSP_TWI_XFER_TIMEOUT.
+                */
+               dev_dbg(&adap->dev, "failed\n");
+               return -1;
+       }
+
+       dev_dbg(&adap->dev, "succeeded\n");
+       return 0;
+}
+
+static u32 pmcmsptwi_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR |
+               I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA |
+               I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_PROC_CALL;
+}
+
+/* -- Initialization -- */
+
+static struct i2c_algorithm pmcmsptwi_algo = {
+       .master_xfer    = pmcmsptwi_master_xfer,
+       .functionality  = pmcmsptwi_i2c_func,
+};
+
+static struct i2c_adapter pmcmsptwi_adapter = {
+       .owner          = THIS_MODULE,
+       .class          = I2C_CLASS_HWMON,
+       .algo           = &pmcmsptwi_algo,
+       .name           = DRV_NAME,
+};
+
+static struct platform_driver pmcmsptwi_driver = {
+       .probe  = pmcmsptwi_probe,
+       .remove = __devexit_p(pmcmsptwi_remove),
+       .driver {
+               .name   = DRV_NAME,
+               .owner  = THIS_MODULE,
+       },
+};
+
+static int __init pmcmsptwi_init(void)
+{
+       return platform_driver_register(&pmcmsptwi_driver);
+}
+
+static void __exit pmcmsptwi_exit(void)
+{
+       platform_driver_unregister(&pmcmsptwi_driver);
+}
+
+MODULE_DESCRIPTION("PMC MSP TWI/SMBus/I2C driver");
+MODULE_LICENSE("GPL");
+
+module_init(pmcmsptwi_init);
+module_exit(pmcmsptwi_exit);
index 1425d2245c827f8f9a103a3f74dfb3a7cfb70df3..0ab4f2627c26c58c3eb53fb593da0fffe7f03bff 100644 (file)
@@ -121,8 +121,7 @@ static s32 i2c_powermac_smbus_xfer( struct i2c_adapter*     adap,
                if (rc)
                        goto bail;
                rc = pmac_i2c_xfer(bus, addrdir, 1, command,
-                                  read ? data->block : &data->block[1],
-                                  data->block[0]);
+                                  &data->block[1], data->block[0]);
                break;
 
         default:
index 28e7b91a4553ff3d33f5e830fb881a0e7c8f6886..9d6b790d43210fa3e21ff7b3b3c9fc6b6011c941 100644 (file)
@@ -921,7 +921,14 @@ static int i2c_pxa_probe(struct platform_device *dev)
                i2c->adap.class = plat->class;
        }
 
-       ret = i2c_add_adapter(&i2c->adap);
+       /*
+        * If "dev->id" is negative we consider it as zero.
+        * The reason to do so is to avoid sysfs names that only make
+        * sense when there are multiple adapters.
+        */
+       i2c->adap.nr = dev->id >= 0 ? dev->id : 0;
+
+       ret = i2c_add_numbered_adapter(&i2c->adap);
        if (ret < 0) {
                printk(KERN_INFO "I2C: Failed to add bus\n");
                goto eadapt;
diff --git a/drivers/i2c/busses/i2c-rpx.c b/drivers/i2c/busses/i2c-rpx.c
deleted file mode 100644 (file)
index 8764df0..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Embedded Planet RPX Lite MPC8xx CPM I2C interface.
- * Copyright (c) 1999 Dan Malek (dmalek@jlc.net).
- *
- * moved into proper i2c interface;
- * Brad Parker (brad@heeltoe.com)
- *
- * RPX lite specific parts of the i2c interface
- * Update:  There actually isn't anything RPXLite-specific about this module.
- * This should work for most any 8xx board.  The console messages have been 
- * changed to eliminate RPXLite references.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/stddef.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-8xx.h>
-#include <asm/mpc8xx.h>
-#include <asm/commproc.h>
-
-
-static void
-rpx_iic_init(struct i2c_algo_8xx_data *data)
-{
-       volatile cpm8xx_t *cp;
-       volatile immap_t *immap;
-
-       cp = cpmp;      /* Get pointer to Communication Processor */
-       immap = (immap_t *)IMAP_ADDR;   /* and to internal registers */
-
-       data->iip = (iic_t *)&cp->cp_dparam[PROFF_IIC];
-
-       /* Check for and use a microcode relocation patch.
-       */
-       if ((data->reloc = data->iip->iic_rpbase))
-               data->iip = (iic_t *)&cp->cp_dpmem[data->iip->iic_rpbase];
-               
-       data->i2c = (i2c8xx_t *)&(immap->im_i2c);
-       data->cp = cp;
-
-       /* Initialize Port B IIC pins.
-       */
-       cp->cp_pbpar |= 0x00000030;
-       cp->cp_pbdir |= 0x00000030;
-       cp->cp_pbodr |= 0x00000030;
-
-       /* Allocate space for two transmit and two receive buffer
-        * descriptors in the DP ram.
-        */
-       data->dp_addr = cpm_dpalloc(sizeof(cbd_t) * 4, 8);
-               
-       /* ptr to i2c area */
-       data->i2c = (i2c8xx_t *)&(((immap_t *)IMAP_ADDR)->im_i2c);
-}
-
-static int rpx_install_isr(int irq, void (*func)(void *), void *data)
-{
-       /* install interrupt handler */
-       cpm_install_handler(irq, func, data);
-
-       return 0;
-}
-
-static struct i2c_algo_8xx_data rpx_data = {
-       .setisr = rpx_install_isr
-};
-
-static struct i2c_adapter rpx_ops = {
-       .owner          = THIS_MODULE,
-       .name           = "m8xx",
-       .id             = I2C_HW_MPC8XX_EPON,
-       .algo_data      = &rpx_data,
-};
-
-int __init i2c_rpx_init(void)
-{
-       printk(KERN_INFO "i2c-rpx: i2c MPC8xx driver\n");
-
-       /* reset hardware to sane state */
-       rpx_iic_init(&rpx_data);
-
-       if (i2c_8xx_add_bus(&rpx_ops) < 0) {
-               printk(KERN_ERR "i2c-rpx: Unable to register with I2C\n");
-               return -ENODEV;
-       }
-
-       return 0;
-}
-
-void __exit i2c_rpx_exit(void)
-{
-       i2c_8xx_del_bus(&rpx_ops);
-}
-
-MODULE_AUTHOR("Dan Malek <dmalek@jlc.net>");
-MODULE_DESCRIPTION("I2C-Bus adapter routines for MPC8xx boards");
-
-module_init(i2c_rpx_init);
-module_exit(i2c_rpx_exit);
index b7fb65c301124eb54e786bc5ef33153737028f06..8adf4abaa0352aff13ba7797456544459c27999f 100644 (file)
@@ -25,8 +25,6 @@
 /* This interfaces to the I2C bus of the Savage4 to gain access to
    the BT869 and possibly other I2C devices. The DDC bus is not
    yet supported because its register is not memory-mapped.
-   However we leave the DDC code here, commented out, to make
-   it easier to add later.
 */
 
 #include <linux/kernel.h>
 #include <linux/i2c-algo-bit.h>
 #include <asm/io.h>
 
-/* 3DFX defines */
-#define PCI_CHIP_SAVAGE3D      0x8A20
-#define PCI_CHIP_SAVAGE3D_MV   0x8A21
+/* device IDs */
 #define PCI_CHIP_SAVAGE4       0x8A22
 #define PCI_CHIP_SAVAGE2000    0x9102
-#define PCI_CHIP_PROSAVAGE_PM  0x8A25
-#define PCI_CHIP_PROSAVAGE_KM  0x8A26
-#define PCI_CHIP_SAVAGE_MX_MV  0x8c10
-#define PCI_CHIP_SAVAGE_MX     0x8c11
-#define PCI_CHIP_SAVAGE_IX_MV  0x8c12
-#define PCI_CHIP_SAVAGE_IX     0x8c13
 
 #define REG                    0xff20  /* Serial Port 1 Register */
 
 /* bit locations in the register */
-#define DDC_ENAB               0x00040000
-#define DDC_SCL_OUT            0x00080000
-#define DDC_SDA_OUT            0x00100000
-#define DDC_SCL_IN             0x00200000
-#define DDC_SDA_IN             0x00400000
 #define I2C_ENAB               0x00000020
 #define I2C_SCL_OUT            0x00000001
 #define I2C_SDA_OUT            0x00000002
 #define I2C_SCL_IN             0x00000008
 #define I2C_SDA_IN             0x00000010
 
-/* initialization states */
-#define INIT2                  0x20
-#define INIT3                  0x04
-
 /* delays */
 #define CYCLE_DELAY            10
 #define TIMEOUT                        (HZ / 2)
index a6feed449dbe65756ee0016e93fc1be5859dd4f4..283769cecee297531fd80c66e1cc34f1ee1bbf64 100644 (file)
@@ -129,6 +129,7 @@ MODULE_PARM_DESC(force_addr, "Initialize the base address of the i2c controller"
 
 static struct pci_driver sis5595_driver;
 static unsigned short sis5595_base;
+static struct pci_dev *sis5595_pdev;
 
 static u8 sis5595_read(u8 reg)
 {
@@ -379,6 +380,8 @@ MODULE_DEVICE_TABLE (pci, sis5595_ids);
 
 static int __devinit sis5595_probe(struct pci_dev *dev, const struct pci_device_id *id)
 {
+       int err;
+
        if (sis5595_setup(dev)) {
                dev_err(&dev->dev, "SIS5595 not detected, module not inserted.\n");
                return -ENODEV;
@@ -389,20 +392,24 @@ static int __devinit sis5595_probe(struct pci_dev *dev, const struct pci_device_
 
        sprintf(sis5595_adapter.name, "SMBus SIS5595 adapter at %04x",
                sis5595_base + SMB_INDEX);
-       return i2c_add_adapter(&sis5595_adapter);
-}
+       err = i2c_add_adapter(&sis5595_adapter);
+       if (err) {
+               release_region(sis5595_base + SMB_INDEX, 2);
+               return err;
+       }
 
-static void __devexit sis5595_remove(struct pci_dev *dev)
-{
-       i2c_del_adapter(&sis5595_adapter);
-       release_region(sis5595_base + SMB_INDEX, 2);
+       /* Always return failure here.  This is to allow other drivers to bind
+        * to this pci device.  We don't really want to have control over the
+        * pci device, we only wanted to read as few register values from it.
+        */
+       sis5595_pdev =  pci_dev_get(dev);
+       return -ENODEV;
 }
 
 static struct pci_driver sis5595_driver = {
        .name           = "sis5595_smbus",
        .id_table       = sis5595_ids,
        .probe          = sis5595_probe,
-       .remove         = __devexit_p(sis5595_remove),
 };
 
 static int __init i2c_sis5595_init(void)
@@ -413,6 +420,12 @@ static int __init i2c_sis5595_init(void)
 static void __exit i2c_sis5595_exit(void)
 {
        pci_unregister_driver(&sis5595_driver);
+       if (sis5595_pdev) {
+               i2c_del_adapter(&sis5595_adapter);
+               release_region(sis5595_base + SMB_INDEX, 2);
+               pci_dev_put(sis5595_pdev);
+               sis5595_pdev = NULL;
+       }
 }
 
 MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
diff --git a/drivers/i2c/busses/i2c-taos-evm.c b/drivers/i2c/busses/i2c-taos-evm.c
new file mode 100644 (file)
index 0000000..1b0cfd5
--- /dev/null
@@ -0,0 +1,330 @@
+/*
+ * Driver for the TAOS evaluation modules
+ * These devices include an I2C master which can be controlled over the
+ * serial port.
+ *
+ * Copyright (C) 2007 Jean Delvare <khali@linux-fr.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+#include <linux/serio.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+
+#define TAOS_BUFFER_SIZE       63
+
+#define TAOS_STATE_INIT                0
+#define TAOS_STATE_IDLE                1
+#define TAOS_STATE_SEND                2
+#define TAOS_STATE_RECV                3
+
+#define TAOS_CMD_RESET         0x12
+
+static DECLARE_WAIT_QUEUE_HEAD(wq);
+
+struct taos_data {
+       struct i2c_adapter adapter;
+       struct i2c_client *client;
+       int state;
+       u8 addr;                /* last used address */
+       unsigned char buffer[TAOS_BUFFER_SIZE];
+       unsigned int pos;       /* position inside the buffer */
+};
+
+/* TAOS TSL2550 EVM */
+static struct i2c_board_info tsl2550_info = {
+       I2C_BOARD_INFO("tsl2550", 0x39),
+       .type   = "tsl2550",
+};
+
+/* Instantiate i2c devices based on the adapter name */
+static struct i2c_client *taos_instantiate_device(struct i2c_adapter *adapter)
+{
+       if (!strncmp(adapter->name, "TAOS TSL2550 EVM", 16)) {
+               dev_info(&adapter->dev, "Instantiating device %s at 0x%02x\n",
+                       tsl2550_info.driver_name, tsl2550_info.addr);
+               return i2c_new_device(adapter, &tsl2550_info);
+       }
+
+       return NULL;
+}
+
+static int taos_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
+                          unsigned short flags, char read_write, u8 command,
+                          int size, union i2c_smbus_data *data)
+{
+       struct serio *serio = adapter->algo_data;
+       struct taos_data *taos = serio_get_drvdata(serio);
+       char *p;
+
+       /* Encode our transaction. "@" is for the device address, "$" for the
+          SMBus command and "#" for the data. */
+       p = taos->buffer;
+
+       /* The device remembers the last used address, no need to send it
+          again if it's the same */
+       if (addr != taos->addr)
+               p += sprintf(p, "@%02X", addr);
+
+       switch (size) {
+       case I2C_SMBUS_BYTE:
+               if (read_write == I2C_SMBUS_WRITE)
+                       sprintf(p, "$#%02X", command);
+               else
+                       sprintf(p, "$");
+               break;
+       case I2C_SMBUS_BYTE_DATA:
+               if (read_write == I2C_SMBUS_WRITE)
+                       sprintf(p, "$%02X#%02X", command, data->byte);
+               else
+                       sprintf(p, "$%02X", command);
+               break;
+       default:
+               dev_dbg(&adapter->dev, "Unsupported transaction size %d\n",
+                       size);
+               return -EINVAL;
+       }
+
+       /* Send the transaction to the TAOS EVM */
+       dev_dbg(&adapter->dev, "Command buffer: %s\n", taos->buffer);
+       taos->pos = 0;
+       taos->state = TAOS_STATE_SEND;
+       serio_write(serio, taos->buffer[0]);
+       wait_event_interruptible_timeout(wq, taos->state == TAOS_STATE_IDLE,
+                                        msecs_to_jiffies(250));
+       if (taos->state != TAOS_STATE_IDLE) {
+               dev_err(&adapter->dev, "Transaction failed "
+                       "(state=%d, pos=%d)\n", taos->state, taos->pos);
+               taos->addr = 0;
+               return -EIO;
+       }
+       taos->addr = addr;
+
+       /* Start the transaction and read the answer */
+       taos->pos = 0;
+       taos->state = TAOS_STATE_RECV;
+       serio_write(serio, read_write == I2C_SMBUS_WRITE ? '>' : '<');
+       wait_event_interruptible_timeout(wq, taos->state == TAOS_STATE_IDLE,
+                                        msecs_to_jiffies(150));
+       if (taos->state != TAOS_STATE_IDLE
+        || taos->pos != 6) {
+               dev_err(&adapter->dev, "Transaction timeout (pos=%d)\n",
+                       taos->pos);
+               return -EIO;
+       }
+       dev_dbg(&adapter->dev, "Answer buffer: %s\n", taos->buffer);
+
+       /* Interpret the returned string */
+       p = taos->buffer + 2;
+       p[3] = '\0';
+       if (!strcmp(p, "NAK"))
+               return -ENODEV;
+
+       if (read_write == I2C_SMBUS_WRITE) {
+               if (!strcmp(p, "ACK"))
+                       return 0;
+       } else {
+               if (p[0] == 'x') {
+                       data->byte = simple_strtol(p + 1, NULL, 16);
+                       return 0;
+               }
+       }
+
+       return -EIO;
+}
+
+static u32 taos_smbus_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA;
+}
+
+static const struct i2c_algorithm taos_algorithm = {
+       .smbus_xfer     = taos_smbus_xfer,
+       .functionality  = taos_smbus_func,
+};
+
+static irqreturn_t taos_interrupt(struct serio *serio, unsigned char data,
+                                 unsigned int flags)
+{
+       struct taos_data *taos = serio_get_drvdata(serio);
+
+       switch (taos->state) {
+       case TAOS_STATE_INIT:
+               taos->buffer[taos->pos++] = data;
+               if (data == ':'
+                || taos->pos == TAOS_BUFFER_SIZE - 1) {
+                       taos->buffer[taos->pos] = '\0';
+                       taos->state = TAOS_STATE_IDLE;
+                       wake_up_interruptible(&wq);
+               }
+               break;
+       case TAOS_STATE_SEND:
+               if (taos->buffer[++taos->pos])
+                       serio_write(serio, taos->buffer[taos->pos]);
+               else {
+                       taos->state = TAOS_STATE_IDLE;
+                       wake_up_interruptible(&wq);
+               }
+               break;
+       case TAOS_STATE_RECV:
+               taos->buffer[taos->pos++] = data;
+               if (data == ']') {
+                       taos->buffer[taos->pos] = '\0';
+                       taos->state = TAOS_STATE_IDLE;
+                       wake_up_interruptible(&wq);
+               }
+               break;
+       }
+
+       return IRQ_HANDLED;
+}
+
+/* Extract the adapter name from the buffer received after reset.
+   The buffer is modified and a pointer inside the buffer is returned. */
+static char *taos_adapter_name(char *buffer)
+{
+       char *start, *end;
+
+       start = strstr(buffer, "TAOS ");
+       if (!start)
+               return NULL;
+
+       end = strchr(start, '\r');
+       if (!end)
+               return NULL;
+       *end = '\0';
+
+       return start;
+}
+
+static int taos_connect(struct serio *serio, struct serio_driver *drv)
+{
+       struct taos_data *taos;
+       struct i2c_adapter *adapter;
+       char *name;
+       int err;
+
+       taos = kzalloc(sizeof(struct taos_data), GFP_KERNEL);
+       if (!taos) {
+               err = -ENOMEM;
+               goto exit;
+       }
+       taos->state = TAOS_STATE_INIT;
+       serio_set_drvdata(serio, taos);
+
+       err = serio_open(serio, drv);
+       if (err)
+               goto exit_kfree;
+
+       adapter = &taos->adapter;
+       adapter->owner = THIS_MODULE;
+       adapter->algo = &taos_algorithm;
+       adapter->algo_data = serio;
+       adapter->dev.parent = &serio->dev;
+
+       /* Reset the TAOS evaluation module to identify it */
+       serio_write(serio, TAOS_CMD_RESET);
+       wait_event_interruptible_timeout(wq, taos->state == TAOS_STATE_IDLE,
+                                        msecs_to_jiffies(2000));
+
+       if (taos->state != TAOS_STATE_IDLE) {
+               err = -ENODEV;
+               dev_dbg(&serio->dev, "TAOS EVM reset failed (state=%d, "
+                       "pos=%d)\n", taos->state, taos->pos);
+               goto exit_close;
+       }
+
+       name = taos_adapter_name(taos->buffer);
+       if (!name) {
+               err = -ENODEV;
+               dev_err(&serio->dev, "TAOS EVM identification failed\n");
+               goto exit_close;
+       }
+       strlcpy(adapter->name, name, sizeof(adapter->name));
+
+       err = i2c_add_adapter(adapter);
+       if (err)
+               goto exit_close;
+       dev_dbg(&serio->dev, "Connected to TAOS EVM\n");
+
+       taos->client = taos_instantiate_device(adapter);
+       return 0;
+
+ exit_close:
+       serio_close(serio);
+ exit_kfree:
+       serio_set_drvdata(serio, NULL);
+       kfree(taos);
+ exit:
+       return err;
+}
+
+static void taos_disconnect(struct serio *serio)
+{
+       struct taos_data *taos = serio_get_drvdata(serio);
+
+       if (taos->client)
+               i2c_unregister_device(taos->client);
+       i2c_del_adapter(&taos->adapter);
+       serio_close(serio);
+       serio_set_drvdata(serio, NULL);
+       kfree(taos);
+
+       dev_dbg(&serio->dev, "Disconnected from TAOS EVM\n");
+}
+
+static struct serio_device_id taos_serio_ids[] = {
+       {
+               .type   = SERIO_RS232,
+               .proto  = SERIO_TAOSEVM,
+               .id     = SERIO_ANY,
+               .extra  = SERIO_ANY,
+       },
+       { 0 }
+};
+MODULE_DEVICE_TABLE(serio, taos_serio_ids);
+
+static struct serio_driver taos_drv = {
+       .driver         = {
+               .name   = "taos-evm",
+       },
+       .description    = "TAOS evaluation module driver",
+       .id_table       = taos_serio_ids,
+       .connect        = taos_connect,
+       .disconnect     = taos_disconnect,
+       .interrupt      = taos_interrupt,
+};
+
+static int __init taos_init(void)
+{
+       return serio_register_driver(&taos_drv);
+}
+
+static void __exit taos_exit(void)
+{
+       serio_unregister_driver(&taos_drv);
+}
+
+MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
+MODULE_DESCRIPTION("TAOS evaluation module driver");
+MODULE_LICENSE("GPL");
+
+module_init(taos_init);
+module_exit(taos_exit);
index 7a2bc06304fca779a3a5c2194d6d9d92e34a199c..edc275002f8087a2501251a37dc2c29e5b637838 100644 (file)
@@ -235,7 +235,7 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr,
                if (!(vt596_features & FEATURE_I2CBLOCK))
                        goto exit_unsupported;
                if (read_write == I2C_SMBUS_READ)
-                       outb_p(I2C_SMBUS_BLOCK_MAX, SMBHSTDAT0);
+                       outb_p(data->block[0], SMBHSTDAT0);
                /* Fall through */
        case I2C_SMBUS_BLOCK_DATA:
                outb_p(command, SMBHSTCMD);
@@ -397,8 +397,7 @@ found:
        case PCI_DEVICE_ID_VIA_82C686_4:
                /* The VT82C686B (rev 0x40) does support I2C block
                   transactions, but the VT82C686A (rev 0x30) doesn't */
-               if (!pci_read_config_byte(pdev, PCI_REVISION_ID, &temp)
-                && temp >= 0x40)
+               if (pdev->revision >= 0x40)
                        vt596_features |= FEATURE_I2CBLOCK;
                break;
        }
index 0d6bd4f7b7fa6a782c53148f386dd623a6edc811..e6c4a2b762ec955497864f860815fb027d9aa275 100644 (file)
@@ -310,8 +310,6 @@ static s32 scx200_acb_smbus_xfer(struct i2c_adapter *adapter,
                break;
 
        case I2C_SMBUS_I2C_BLOCK_DATA:
-               if (rw == I2C_SMBUS_READ)
-                       data->block[0] = I2C_SMBUS_BLOCK_MAX; /* For now */
                len = data->block[0];
                if (len == 0 || len > I2C_SMBUS_BLOCK_MAX)
                        return -EINVAL;
@@ -388,7 +386,7 @@ static const struct i2c_algorithm scx200_acb_algorithm = {
 };
 
 static struct scx200_acb_iface *scx200_acb_list;
-static DECLARE_MUTEX(scx200_acb_list_mutex);
+static DEFINE_MUTEX(scx200_acb_list_mutex);
 
 static __init int scx200_acb_probe(struct scx200_acb_iface *iface)
 {
@@ -472,10 +470,10 @@ static int __init scx200_acb_create(struct scx200_acb_iface *iface)
                return -ENODEV;
        }
 
-       down(&scx200_acb_list_mutex);
+       mutex_lock(&scx200_acb_list_mutex);
        iface->next = scx200_acb_list;
        scx200_acb_list = iface;
-       up(&scx200_acb_list_mutex);
+       mutex_unlock(&scx200_acb_list_mutex);
 
        return 0;
 }
@@ -633,10 +631,10 @@ static void __exit scx200_acb_cleanup(void)
 {
        struct scx200_acb_iface *iface;
 
-       down(&scx200_acb_list_mutex);
+       mutex_lock(&scx200_acb_list_mutex);
        while ((iface = scx200_acb_list) != NULL) {
                scx200_acb_list = iface->next;
-               up(&scx200_acb_list_mutex);
+               mutex_unlock(&scx200_acb_list_mutex);
 
                i2c_del_adapter(&iface->adapter);
 
@@ -648,9 +646,9 @@ static void __exit scx200_acb_cleanup(void)
                        release_region(iface->base, 8);
 
                kfree(iface);
-               down(&scx200_acb_list_mutex);
+               mutex_lock(&scx200_acb_list_mutex);
        }
-       up(&scx200_acb_list_mutex);
+       mutex_unlock(&scx200_acb_list_mutex);
 }
 
 module_init(scx200_acb_init);
index ea085a006eadd163318a9e68e79d9a8c8cc31627..3944e889cb219cb2dcbad8ee75603023f2893608 100644 (file)
@@ -5,7 +5,7 @@
 menu "Miscellaneous I2C Chip support"
 
 config SENSORS_DS1337
-       tristate "Dallas Semiconductor DS1337 and DS1339 Real Time Clock"
+       tristate "Dallas DS1337 and DS1339 Real Time Clock (DEPRECATED)"
        depends on EXPERIMENTAL
        help
          If you say yes here you get support for Dallas Semiconductor
@@ -14,8 +14,11 @@ config SENSORS_DS1337
          This driver can also be built as a module.  If so, the module
          will be called ds1337.
 
+         This driver is deprecated and will be dropped soon. Use
+         rtc-ds1307 instead.
+
 config SENSORS_DS1374
-       tristate "Maxim/Dallas Semiconductor DS1374 Real Time Clock"
+       tristate "Dallas DS1374 Real Time Clock (DEPRECATED)"
        depends on EXPERIMENTAL
        help
          If you say yes here you get support for Dallas Semiconductor
@@ -24,6 +27,19 @@ config SENSORS_DS1374
          This driver can also be built as a module.  If so, the module
          will be called ds1374.
 
+         This driver is deprecated and will be dropped soon. Use
+         rtc-ds1374 instead.
+
+config DS1682
+       tristate "Dallas DS1682 Total Elapsed Time Recorder with Alarm"
+       depends on EXPERIMENTAL
+       help
+         If you say yes here you get support for Dallas Semiconductor
+         DS1682 Total Elapsed Time Recorder.
+
+         This driver can also be built as a module.  If so, the module
+         will be called ds1682.
+
 config SENSORS_EEPROM
        tristate "EEPROM reader"
        depends on EXPERIMENTAL
@@ -101,7 +117,7 @@ config TPS65010
          will be called tps65010.
 
 config SENSORS_M41T00
-       tristate "ST M41T00 RTC chip"
+       tristate "ST M41T00 RTC chip (DEPRECATED)"
        depends on PPC32
        help
          If you say yes here you get support for the ST M41T00 RTC chip.
@@ -109,6 +125,9 @@ config SENSORS_M41T00
          This driver can also be built as a module.  If so, the module
          will be called m41t00.
 
+         This driver is deprecated and will be dropped soon. Use
+         rtc-ds1307 or rtc-m41t80 instead.
+
 config SENSORS_MAX6875
        tristate "Maxim MAX6875 Power supply supervisor"
        depends on EXPERIMENTAL
@@ -124,4 +143,14 @@ config SENSORS_MAX6875
          This driver can also be built as a module.  If so, the module
          will be called max6875.
 
+config SENSORS_TSL2550
+       tristate "Taos TSL2550 ambient light sensor"
+       depends on EXPERIMENTAL
+       help
+         If you say yes here you get support for the Taos TSL2550
+         ambient light sensor.
+
+         This driver can also be built as a module.  If so, the module
+         will be called tsl2550.
+
 endmenu
index 779868ef2e268c6a4520625acadcd21823ceb50b..d8cbeb3f4b634f6e76a4fe5fd4e0a0a3a1d26386 100644 (file)
@@ -4,6 +4,7 @@
 
 obj-$(CONFIG_SENSORS_DS1337)   += ds1337.o
 obj-$(CONFIG_SENSORS_DS1374)   += ds1374.o
+obj-$(CONFIG_DS1682)           += ds1682.o
 obj-$(CONFIG_SENSORS_EEPROM)   += eeprom.o
 obj-$(CONFIG_SENSORS_MAX6875)  += max6875.o
 obj-$(CONFIG_SENSORS_M41T00)   += m41t00.o
@@ -12,6 +13,7 @@ obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o
 obj-$(CONFIG_SENSORS_PCF8591)  += pcf8591.o
 obj-$(CONFIG_ISP1301_OMAP)     += isp1301_omap.o
 obj-$(CONFIG_TPS65010)         += tps65010.o
+obj-$(CONFIG_SENSORS_TSL2550)  += tsl2550.o
 
 ifeq ($(CONFIG_I2C_DEBUG_CHIP),y)
 EXTRA_CFLAGS += -DDEBUG
diff --git a/drivers/i2c/chips/ds1682.c b/drivers/i2c/chips/ds1682.c
new file mode 100644 (file)
index 0000000..25fd467
--- /dev/null
@@ -0,0 +1,259 @@
+/*
+ * Dallas Semiconductor DS1682 Elapsed Time Recorder device driver
+ *
+ * Written by: Grant Likely <grant.likely@secretlab.ca>
+ *
+ * Copyright (C) 2007 Secret Lab Technologies 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.
+ */
+
+/*
+ * The DS1682 elapsed timer recorder is a simple device that implements
+ * one elapsed time counter, one event counter, an alarm signal and 10
+ * bytes of general purpose EEPROM.
+ *
+ * This driver provides access to the DS1682 counters and user data via
+ * the sysfs.  The following attributes are added to the device node:
+ *     elapsed_time (u32): Total elapsed event time in ms resolution
+ *     alarm_time (u32): When elapsed time exceeds the value in alarm_time,
+ *                       then the alarm pin is asserted.
+ *     event_count (u16): number of times the event pin has gone low.
+ *     eeprom (u8[10]): general purpose EEPROM
+ *
+ * Counter registers and user data are both read/write unless the device
+ * has been write protected.  This driver does not support turning off write
+ * protection.  Once write protection is turned on, it is impossible to
+ * turn it off again, so I have left the feature out of this driver to avoid
+ * accidental enabling, but it is trivial to add write protect support.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/string.h>
+#include <linux/list.h>
+#include <linux/sysfs.h>
+#include <linux/ctype.h>
+#include <linux/hwmon-sysfs.h>
+
+/* Device registers */
+#define DS1682_REG_CONFIG              0x00
+#define DS1682_REG_ALARM               0x01
+#define DS1682_REG_ELAPSED             0x05
+#define DS1682_REG_EVT_CNTR            0x09
+#define DS1682_REG_EEPROM              0x0b
+#define DS1682_REG_RESET               0x1d
+#define DS1682_REG_WRITE_DISABLE       0x1e
+#define DS1682_REG_WRITE_MEM_DISABLE   0x1f
+
+#define DS1682_EEPROM_SIZE             10
+
+/*
+ * Generic counter attributes
+ */
+static ssize_t ds1682_show(struct device *dev, struct device_attribute *attr,
+                          char *buf)
+{
+       struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+       struct i2c_client *client = to_i2c_client(dev);
+       __le32 val = 0;
+       int rc;
+
+       dev_dbg(dev, "ds1682_show() called on %s\n", attr->attr.name);
+
+       /* Read the register */
+       rc = i2c_smbus_read_i2c_block_data(client, sattr->index, sattr->nr,
+                                          (u8 *) & val);
+       if (rc < 0)
+               return -EIO;
+
+       /* Special case: the 32 bit regs are time values with 1/4s
+        * resolution, scale them up to milliseconds */
+       if (sattr->nr == 4)
+               return sprintf(buf, "%llu\n", ((u64) le32_to_cpu(val)) * 250);
+
+       /* Format the output string and return # of bytes */
+       return sprintf(buf, "%li\n", (long)le32_to_cpu(val));
+}
+
+static ssize_t ds1682_store(struct device *dev, struct device_attribute *attr,
+                           const char *buf, size_t count)
+{
+       struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+       struct i2c_client *client = to_i2c_client(dev);
+       char *endp;
+       u64 val;
+       __le32 val_le;
+       int rc;
+
+       dev_dbg(dev, "ds1682_store() called on %s\n", attr->attr.name);
+
+       /* Decode input */
+       val = simple_strtoull(buf, &endp, 0);
+       if (buf == endp) {
+               dev_dbg(dev, "input string not a number\n");
+               return -EINVAL;
+       }
+
+       /* Special case: the 32 bit regs are time values with 1/4s
+        * resolution, scale input down to quarter-seconds */
+       if (sattr->nr == 4)
+               do_div(val, 250);
+
+       /* write out the value */
+       val_le = cpu_to_le32(val);
+       rc = i2c_smbus_write_i2c_block_data(client, sattr->index, sattr->nr,
+                                           (u8 *) & val_le);
+       if (rc < 0) {
+               dev_err(dev, "register write failed; reg=0x%x, size=%i\n",
+                       sattr->index, sattr->nr);
+               return -EIO;
+       }
+
+       return count;
+}
+
+/*
+ * Simple register attributes
+ */
+static SENSOR_DEVICE_ATTR_2(elapsed_time, S_IRUGO | S_IWUSR, ds1682_show,
+                           ds1682_store, 4, DS1682_REG_ELAPSED);
+static SENSOR_DEVICE_ATTR_2(alarm_time, S_IRUGO | S_IWUSR, ds1682_show,
+                           ds1682_store, 4, DS1682_REG_ALARM);
+static SENSOR_DEVICE_ATTR_2(event_count, S_IRUGO | S_IWUSR, ds1682_show,
+                           ds1682_store, 2, DS1682_REG_EVT_CNTR);
+
+static const struct attribute_group ds1682_group = {
+       .attrs = (struct attribute *[]) {
+               &sensor_dev_attr_elapsed_time.dev_attr.attr,
+               &sensor_dev_attr_alarm_time.dev_attr.attr,
+               &sensor_dev_attr_event_count.dev_attr.attr,
+               NULL,
+       },
+};
+
+/*
+ * User data attribute
+ */
+static ssize_t ds1682_eeprom_read(struct kobject *kobj, char *buf, loff_t off,
+                                 size_t count)
+{
+       struct i2c_client *client = kobj_to_i2c_client(kobj);
+       int rc;
+
+       dev_dbg(&client->dev, "ds1682_eeprom_read(p=%p, off=%lli, c=%zi)\n",
+               buf, off, count);
+
+       if (off >= DS1682_EEPROM_SIZE)
+               return 0;
+
+       if (off + count > DS1682_EEPROM_SIZE)
+               count = DS1682_EEPROM_SIZE - off;
+
+       rc = i2c_smbus_read_i2c_block_data(client, DS1682_REG_EEPROM + off,
+                                          count, buf);
+       if (rc < 0)
+               return -EIO;
+
+       return count;
+}
+
+static ssize_t ds1682_eeprom_write(struct kobject *kobj, char *buf, loff_t off,
+                                  size_t count)
+{
+       struct i2c_client *client = kobj_to_i2c_client(kobj);
+
+       dev_dbg(&client->dev, "ds1682_eeprom_write(p=%p, off=%lli, c=%zi)\n",
+               buf, off, count);
+
+       if (off >= DS1682_EEPROM_SIZE)
+               return -ENOSPC;
+
+       if (off + count > DS1682_EEPROM_SIZE)
+               count = DS1682_EEPROM_SIZE - off;
+
+       /* Write out to the device */
+       if (i2c_smbus_write_i2c_block_data(client, DS1682_REG_EEPROM + off,
+                                          count, buf) < 0)
+               return -EIO;
+
+       return count;
+}
+
+static struct bin_attribute ds1682_eeprom_attr = {
+       .attr = {
+               .name = "eeprom",
+               .mode = S_IRUGO | S_IWUSR,
+               .owner = THIS_MODULE,
+       },
+       .size = DS1682_EEPROM_SIZE,
+       .read = ds1682_eeprom_read,
+       .write = ds1682_eeprom_write,
+};
+
+/*
+ * Called when a ds1682 device is matched with this driver
+ */
+static int ds1682_probe(struct i2c_client *client)
+{
+       int rc;
+
+       if (!i2c_check_functionality(client->adapter,
+                                    I2C_FUNC_SMBUS_I2C_BLOCK)) {
+               dev_err(&client->dev, "i2c bus does not support the ds1682\n");
+               rc = -ENODEV;
+               goto exit;
+       }
+
+       rc = sysfs_create_group(&client->dev.kobj, &ds1682_group);
+       if (rc)
+               goto exit;
+
+       rc = sysfs_create_bin_file(&client->dev.kobj, &ds1682_eeprom_attr);
+       if (rc)
+               goto exit_bin_attr;
+
+       return 0;
+
+ exit_bin_attr:
+       sysfs_remove_group(&client->dev.kobj, &ds1682_group);
+ exit:
+       return rc;
+}
+
+static int ds1682_remove(struct i2c_client *client)
+{
+       sysfs_remove_bin_file(&client->dev.kobj, &ds1682_eeprom_attr);
+       sysfs_remove_group(&client->dev.kobj, &ds1682_group);
+       return 0;
+}
+
+static struct i2c_driver ds1682_driver = {
+       .driver = {
+               .name = "ds1682",
+       },
+       .probe = ds1682_probe,
+       .remove = ds1682_remove,
+};
+
+static int __init ds1682_init(void)
+{
+       return i2c_add_driver(&ds1682_driver);
+}
+
+static void __exit ds1682_exit(void)
+{
+       i2c_del_driver(&ds1682_driver);
+}
+
+MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
+MODULE_DESCRIPTION("DS1682 Elapsed Time Indicator driver");
+MODULE_LICENSE("GPL");
+
+module_init(ds1682_init);
+module_exit(ds1682_exit);
index bfce13c8f1ff764d9c6036a8b4cef9cb86cdf106..d3da1fb05b9bebe13d342f7d3a09fbbda585e58d 100644 (file)
@@ -88,8 +88,10 @@ static void eeprom_update_client(struct i2c_client *client, u8 slice)
                dev_dbg(&client->dev, "Starting eeprom update, slice %u\n", slice);
 
                if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
-                       for (i = slice << 5; i < (slice + 1) << 5; i += I2C_SMBUS_BLOCK_MAX)
-                               if (i2c_smbus_read_i2c_block_data(client, i, data->data + i) != I2C_SMBUS_BLOCK_MAX)
+                       for (i = slice << 5; i < (slice + 1) << 5; i += 32)
+                               if (i2c_smbus_read_i2c_block_data(client, i,
+                                                       32, data->data + i)
+                                                       != 32)
                                        goto exit;
                } else {
                        if (i2c_smbus_write_byte(client, slice << 5)) {
@@ -110,7 +112,8 @@ exit:
        mutex_unlock(&data->update_lock);
 }
 
-static ssize_t eeprom_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
+static ssize_t eeprom_read(struct kobject *kobj, struct bin_attribute *bin_attr,
+                          char *buf, loff_t off, size_t count)
 {
        struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj));
        struct eeprom_data *data = i2c_get_clientdata(client);
@@ -143,7 +146,6 @@ static struct bin_attribute eeprom_attr = {
        .attr = {
                .name = "eeprom",
                .mode = S_IRUGO,
-               .owner = THIS_MODULE,
        },
        .size = EEPROM_SIZE,
        .read = eeprom_read,
index 76645c1429776e182b87e3d2578adc40222cffa1..64692f666372e374cacfeaedaab1bad5293b3e1f 100644 (file)
@@ -106,6 +106,7 @@ static void max6875_update_slice(struct i2c_client *client, int slice)
                                            I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
                        if (i2c_smbus_read_i2c_block_data(client,
                                                          MAX6875_CMD_BLK_READ,
+                                                         SLICE_SIZE,
                                                          buf) != SLICE_SIZE) {
                                goto exit_up;
                        }
@@ -125,8 +126,9 @@ exit_up:
        mutex_unlock(&data->update_lock);
 }
 
-static ssize_t max6875_read(struct kobject *kobj, char *buf, loff_t off,
-                           size_t count)
+static ssize_t max6875_read(struct kobject *kobj,
+                           struct bin_attribute *bin_attr,
+                           char *buf, loff_t off, size_t count)
 {
        struct i2c_client *client = kobj_to_i2c_client(kobj);
        struct max6875_data *data = i2c_get_clientdata(client);
@@ -152,7 +154,6 @@ static struct bin_attribute user_eeprom_attr = {
        .attr = {
                .name = "eeprom",
                .mode = S_IRUGO,
-               .owner = THIS_MODULE,
        },
        .size = USER_EEPROM_SIZE,
        .read = max6875_read,
diff --git a/drivers/i2c/chips/tsl2550.c b/drivers/i2c/chips/tsl2550.c
new file mode 100644 (file)
index 0000000..3de4b19
--- /dev/null
@@ -0,0 +1,460 @@
+/*
+ *  tsl2550.c - Linux kernel modules for ambient light sensor
+ *
+ *  Copyright (C) 2007 Rodolfo Giometti <giometti@linux.it>
+ *  Copyright (C) 2007 Eurotech S.p.A. <info@eurotech.it>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+
+#define TSL2550_DRV_NAME       "tsl2550"
+#define DRIVER_VERSION         "1.1.1"
+
+/*
+ * Defines
+ */
+
+#define TSL2550_POWER_DOWN             0x00
+#define TSL2550_POWER_UP               0x03
+#define TSL2550_STANDARD_RANGE         0x18
+#define TSL2550_EXTENDED_RANGE         0x1d
+#define TSL2550_READ_ADC0              0x43
+#define TSL2550_READ_ADC1              0x83
+
+/*
+ * Structs
+ */
+
+struct tsl2550_data {
+       struct i2c_client *client;
+       struct mutex update_lock;
+
+       unsigned int power_state : 1;
+       unsigned int operating_mode : 1;
+};
+
+/*
+ * Global data
+ */
+
+static const u8 TSL2550_MODE_RANGE[2] = {
+       TSL2550_STANDARD_RANGE, TSL2550_EXTENDED_RANGE,
+};
+
+/*
+ * Management functions
+ */
+
+static int tsl2550_set_operating_mode(struct i2c_client *client, int mode)
+{
+       struct tsl2550_data *data = i2c_get_clientdata(client);
+
+       int ret = i2c_smbus_write_byte(client, TSL2550_MODE_RANGE[mode]);
+
+       data->operating_mode = mode;
+
+       return ret;
+}
+
+static int tsl2550_set_power_state(struct i2c_client *client, int state)
+{
+       struct tsl2550_data *data = i2c_get_clientdata(client);
+       int ret;
+
+       if (state == 0)
+               ret = i2c_smbus_write_byte(client, TSL2550_POWER_DOWN);
+       else {
+               ret = i2c_smbus_write_byte(client, TSL2550_POWER_UP);
+
+               /* On power up we should reset operating mode also... */
+               tsl2550_set_operating_mode(client, data->operating_mode);
+       }
+
+       data->power_state = state;
+
+       return ret;
+}
+
+static int tsl2550_get_adc_value(struct i2c_client *client, u8 cmd)
+{
+       unsigned long end;
+       int loop = 0, ret = 0;
+
+       /*
+        * Read ADC channel waiting at most 400ms (see data sheet for further
+        * info).
+        * To avoid long busy wait we spin for few milliseconds then
+        * start sleeping.
+        */
+       end = jiffies + msecs_to_jiffies(400);
+       while (time_before(jiffies, end)) {
+               i2c_smbus_write_byte(client, cmd);
+
+               if (loop++ < 5)
+                       mdelay(1);
+               else
+                       msleep(1);
+
+               ret = i2c_smbus_read_byte(client);
+               if (ret < 0)
+                       return ret;
+               else if (ret & 0x0080)
+                       break;
+       }
+       if (!(ret & 0x80))
+               return -EIO;
+       return ret & 0x7f;      /* remove the "valid" bit */
+}
+
+/*
+ * LUX calculation
+ */
+
+#define        TSL2550_MAX_LUX         1846
+
+static const u8 ratio_lut[] = {
+       100, 100, 100, 100, 100, 100, 100, 100,
+       100, 100, 100, 100, 100, 100, 99, 99,
+       99, 99, 99, 99, 99, 99, 99, 99,
+       99, 99, 99, 98, 98, 98, 98, 98,
+       98, 98, 97, 97, 97, 97, 97, 96,
+       96, 96, 96, 95, 95, 95, 94, 94,
+       93, 93, 93, 92, 92, 91, 91, 90,
+       89, 89, 88, 87, 87, 86, 85, 84,
+       83, 82, 81, 80, 79, 78, 77, 75,
+       74, 73, 71, 69, 68, 66, 64, 62,
+       60, 58, 56, 54, 52, 49, 47, 44,
+       42, 41, 40, 40, 39, 39, 38, 38,
+       37, 37, 37, 36, 36, 36, 35, 35,
+       35, 35, 34, 34, 34, 34, 33, 33,
+       33, 33, 32, 32, 32, 32, 32, 31,
+       31, 31, 31, 31, 30, 30, 30, 30,
+       30,
+};
+
+static const u16 count_lut[] = {
+       0, 1, 2, 3, 4, 5, 6, 7,
+       8, 9, 10, 11, 12, 13, 14, 15,
+       16, 18, 20, 22, 24, 26, 28, 30,
+       32, 34, 36, 38, 40, 42, 44, 46,
+       49, 53, 57, 61, 65, 69, 73, 77,
+       81, 85, 89, 93, 97, 101, 105, 109,
+       115, 123, 131, 139, 147, 155, 163, 171,
+       179, 187, 195, 203, 211, 219, 227, 235,
+       247, 263, 279, 295, 311, 327, 343, 359,
+       375, 391, 407, 423, 439, 455, 471, 487,
+       511, 543, 575, 607, 639, 671, 703, 735,
+       767, 799, 831, 863, 895, 927, 959, 991,
+       1039, 1103, 1167, 1231, 1295, 1359, 1423, 1487,
+       1551, 1615, 1679, 1743, 1807, 1871, 1935, 1999,
+       2095, 2223, 2351, 2479, 2607, 2735, 2863, 2991,
+       3119, 3247, 3375, 3503, 3631, 3759, 3887, 4015,
+};
+
+/*
+ * This function is described into Taos TSL2550 Designer's Notebook
+ * pages 2, 3.
+ */
+static int tsl2550_calculate_lux(u8 ch0, u8 ch1)
+{
+       unsigned int lux;
+
+       /* Look up count from channel values */
+       u16 c0 = count_lut[ch0];
+       u16 c1 = count_lut[ch1];
+
+       /*
+        * Calculate ratio.
+        * Note: the "128" is a scaling factor
+        */
+       u8 r = 128;
+
+       /* Avoid division by 0 and count 1 cannot be greater than count 0 */
+       if (c0 && (c1 <= c0))
+               r = c1 * 128 / c0;
+       else
+               return -1;
+
+       /* Calculate LUX */
+       lux = ((c0 - c1) * ratio_lut[r]) / 256;
+
+       /* LUX range check */
+       return lux > TSL2550_MAX_LUX ? TSL2550_MAX_LUX : lux;
+}
+
+/*
+ * SysFS support
+ */
+
+static ssize_t tsl2550_show_power_state(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev));
+
+       return sprintf(buf, "%u\n", data->power_state);
+}
+
+static ssize_t tsl2550_store_power_state(struct device *dev,
+               struct device_attribute *attr, const char *buf, size_t count)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct tsl2550_data *data = i2c_get_clientdata(client);
+       unsigned long val = simple_strtoul(buf, NULL, 10);
+       int ret;
+
+       if (val < 0 || val > 1)
+               return -EINVAL;
+
+       mutex_lock(&data->update_lock);
+       ret = tsl2550_set_power_state(client, val);
+       mutex_unlock(&data->update_lock);
+
+       if (ret < 0)
+               return ret;
+
+       return count;
+}
+
+static DEVICE_ATTR(power_state, S_IWUSR | S_IRUGO,
+                  tsl2550_show_power_state, tsl2550_store_power_state);
+
+static ssize_t tsl2550_show_operating_mode(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev));
+
+       return sprintf(buf, "%u\n", data->operating_mode);
+}
+
+static ssize_t tsl2550_store_operating_mode(struct device *dev,
+               struct device_attribute *attr, const char *buf, size_t count)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct tsl2550_data *data = i2c_get_clientdata(client);
+       unsigned long val = simple_strtoul(buf, NULL, 10);
+       int ret;
+
+       if (val < 0 || val > 1)
+               return -EINVAL;
+
+       if (data->power_state == 0)
+               return -EBUSY;
+
+       mutex_lock(&data->update_lock);
+       ret = tsl2550_set_operating_mode(client, val);
+       mutex_unlock(&data->update_lock);
+
+       if (ret < 0)
+               return ret;
+
+       return count;
+}
+
+static DEVICE_ATTR(operating_mode, S_IWUSR | S_IRUGO,
+                  tsl2550_show_operating_mode, tsl2550_store_operating_mode);
+
+static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf)
+{
+       u8 ch0, ch1;
+       int ret;
+
+       ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC0);
+       if (ret < 0)
+               return ret;
+       ch0 = ret;
+
+       mdelay(1);
+
+       ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC1);
+       if (ret < 0)
+               return ret;
+       ch1 = ret;
+
+       /* Do the job */
+       ret = tsl2550_calculate_lux(ch0, ch1);
+       if (ret < 0)
+               return ret;
+
+       return sprintf(buf, "%d\n", ret);
+}
+
+static ssize_t tsl2550_show_lux1_input(struct device *dev,
+                       struct device_attribute *attr, char *buf)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct tsl2550_data *data = i2c_get_clientdata(client);
+       int ret;
+
+       /* No LUX data if not operational */
+       if (!data->power_state)
+               return -EBUSY;
+
+       mutex_lock(&data->update_lock);
+       ret = __tsl2550_show_lux(client, buf);
+       mutex_unlock(&data->update_lock);
+
+       return ret;
+}
+
+static DEVICE_ATTR(lux1_input, S_IRUGO,
+                  tsl2550_show_lux1_input, NULL);
+
+static struct attribute *tsl2550_attributes[] = {
+       &dev_attr_power_state.attr,
+       &dev_attr_operating_mode.attr,
+       &dev_attr_lux1_input.attr,
+       NULL
+};
+
+static const struct attribute_group tsl2550_attr_group = {
+       .attrs = tsl2550_attributes,
+};
+
+/*
+ * Initialization function
+ */
+
+static int tsl2550_init_client(struct i2c_client *client)
+{
+       struct tsl2550_data *data = i2c_get_clientdata(client);
+       int err;
+
+       /*
+        * Probe the chip. To do so we try to power up the device and then to
+        * read back the 0x03 code
+        */
+       err = i2c_smbus_write_byte(client, TSL2550_POWER_UP);
+       if (err < 0)
+               return err;
+       mdelay(1);
+       if (i2c_smbus_read_byte(client) != TSL2550_POWER_UP)
+               return -ENODEV;
+       data->power_state = 1;
+
+       /* Set the default operating mode */
+       err = i2c_smbus_write_byte(client,
+                                  TSL2550_MODE_RANGE[data->operating_mode]);
+       if (err < 0)
+               return err;
+
+       return 0;
+}
+
+/*
+ * I2C init/probing/exit functions
+ */
+
+static struct i2c_driver tsl2550_driver;
+static int __devinit tsl2550_probe(struct i2c_client *client)
+{
+       struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+       struct tsl2550_data *data;
+       int *opmode, err = 0;
+
+       if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) {
+               err = -EIO;
+               goto exit;
+       }
+
+       data = kzalloc(sizeof(struct tsl2550_data), GFP_KERNEL);
+       if (!data) {
+               err = -ENOMEM;
+               goto exit;
+       }
+       data->client = client;
+       i2c_set_clientdata(client, data);
+
+       /* Check platform data */
+       opmode = client->dev.platform_data;
+       if (opmode) {
+               if (*opmode < 0 || *opmode > 1) {
+                       dev_err(&client->dev, "invalid operating_mode (%d)\n",
+                                       *opmode);
+                       err = -EINVAL;
+                       goto exit_kfree;
+               }
+               data->operating_mode = *opmode;
+       } else
+               data->operating_mode = 0;       /* default mode is standard */
+       dev_info(&client->dev, "%s operating mode\n",
+                       data->operating_mode ? "extended" : "standard");
+
+       mutex_init(&data->update_lock);
+
+       /* Initialize the TSL2550 chip */
+       err = tsl2550_init_client(client);
+       if (err)
+               goto exit_kfree;
+
+       /* Register sysfs hooks */
+       err = sysfs_create_group(&client->dev.kobj, &tsl2550_attr_group);
+       if (err)
+               goto exit_kfree;
+
+       dev_info(&client->dev, "support ver. %s enabled\n", DRIVER_VERSION);
+
+       return 0;
+
+exit_kfree:
+       kfree(data);
+exit:
+       return err;
+}
+
+static int __devexit tsl2550_remove(struct i2c_client *client)
+{
+       sysfs_remove_group(&client->dev.kobj, &tsl2550_attr_group);
+
+       /* Power down the device */
+       tsl2550_set_power_state(client, 0);
+
+       kfree(i2c_get_clientdata(client));
+
+       return 0;
+}
+
+static struct i2c_driver tsl2550_driver = {
+       .driver = {
+               .name   = TSL2550_DRV_NAME,
+               .owner  = THIS_MODULE,
+       },
+       .probe  = tsl2550_probe,
+       .remove = __devexit_p(tsl2550_remove),
+};
+
+static int __init tsl2550_init(void)
+{
+       return i2c_add_driver(&tsl2550_driver);
+}
+
+static void __exit tsl2550_exit(void)
+{
+       i2c_del_driver(&tsl2550_driver);
+}
+
+MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
+MODULE_DESCRIPTION("TSL2550 ambient light sensor driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRIVER_VERSION);
+
+module_init(tsl2550_init);
+module_exit(tsl2550_exit);
index 435925eba437df0e3cf9cdc9896c3ca6fc97abe4..6971a62397db2cd581cf59b3e8d87e3f404aeb85 100644 (file)
@@ -207,6 +207,7 @@ EXPORT_SYMBOL_GPL(i2c_bus_type);
  * i2c_new_device - instantiate an i2c device for use with a new style driver
  * @adap: the adapter managing the device
  * @info: describes one I2C device; bus_num is ignored
+ * Context: can sleep
  *
  * Create a device to work with a new style i2c driver, where binding is
  * handled through driver model probe()/remove() methods.  This call is not
@@ -255,6 +256,7 @@ EXPORT_SYMBOL_GPL(i2c_new_device);
 /**
  * i2c_unregister_device - reverse effect of i2c_new_device()
  * @client: value returned from i2c_new_device()
+ * Context: can sleep
  */
 void i2c_unregister_device(struct i2c_client *client)
 {
@@ -379,6 +381,7 @@ out_list:
 /**
  * i2c_add_adapter - declare i2c adapter, use dynamic bus number
  * @adapter: the adapter to add
+ * Context: can sleep
  *
  * This routine is used to declare an I2C adapter when its bus number
  * doesn't matter.  Examples: for I2C adapters dynamically added by
@@ -416,6 +419,7 @@ EXPORT_SYMBOL(i2c_add_adapter);
 /**
  * i2c_add_numbered_adapter - declare i2c adapter, use static bus number
  * @adap: the adapter to register (with adap->nr initialized)
+ * Context: can sleep
  *
  * This routine is used to declare an I2C adapter when its bus number
  * matters.  Example: for I2C adapters from system-on-chip CPUs, or
@@ -463,6 +467,14 @@ retry:
 }
 EXPORT_SYMBOL_GPL(i2c_add_numbered_adapter);
 
+/**
+ * i2c_del_adapter - unregister I2C adapter
+ * @adap: the adapter being unregistered
+ * Context: can sleep
+ *
+ * This unregisters an I2C adapter which was previously registered
+ * by @i2c_add_adapter or @i2c_add_numbered_adapter.
+ */
 int i2c_del_adapter(struct i2c_adapter *adap)
 {
        struct list_head  *item, *_n;
@@ -598,6 +610,7 @@ EXPORT_SYMBOL(i2c_register_driver);
 /**
  * i2c_del_driver - unregister I2C driver
  * @driver: the driver being unregistered
+ * Context: can sleep
  */
 void i2c_del_driver(struct i2c_driver *driver)
 {
@@ -1331,10 +1344,14 @@ s32 i2c_smbus_write_block_data(struct i2c_client *client, u8 command,
 EXPORT_SYMBOL(i2c_smbus_write_block_data);
 
 /* Returns the number of read bytes */
-s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client, u8 command, u8 *values)
+s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client, u8 command,
+                                 u8 length, u8 *values)
 {
        union i2c_smbus_data data;
 
+       if (length > I2C_SMBUS_BLOCK_MAX)
+               length = I2C_SMBUS_BLOCK_MAX;
+       data.block[0] = length;
        if (i2c_smbus_xfer(client->adapter,client->addr,client->flags,
                              I2C_SMBUS_READ,command,
                              I2C_SMBUS_I2C_BLOCK_DATA,&data))
@@ -1455,7 +1472,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
                break;
        case I2C_SMBUS_I2C_BLOCK_DATA:
                if (read_write == I2C_SMBUS_READ) {
-                       msg[1].len = I2C_SMBUS_BLOCK_MAX;
+                       msg[1].len = data->block[0];
                } else {
                        msg[0].len = data->block[0] + 1;
                        if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 1) {
@@ -1511,9 +1528,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
                                data->word = msgbuf1[0] | (msgbuf1[1] << 8);
                                break;
                        case I2C_SMBUS_I2C_BLOCK_DATA:
-                               /* fixed at 32 for now */
-                               data->block[0] = I2C_SMBUS_BLOCK_MAX;
-                               for (i = 0; i < I2C_SMBUS_BLOCK_MAX; i++)
+                               for (i = 0; i < data->block[0]; i++)
                                        data->block[i+1] = msgbuf1[i];
                                break;
                        case I2C_SMBUS_BLOCK_DATA:
index e7a7097105923296482dcc37acef6a8bc53fddb9..64eee9551b2203f73654890921e766c4a7608c31 100644 (file)
@@ -283,6 +283,7 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file,
                    (data_arg.size != I2C_SMBUS_WORD_DATA) &&
                    (data_arg.size != I2C_SMBUS_PROC_CALL) &&
                    (data_arg.size != I2C_SMBUS_BLOCK_DATA) &&
+                   (data_arg.size != I2C_SMBUS_I2C_BLOCK_BROKEN) &&
                    (data_arg.size != I2C_SMBUS_I2C_BLOCK_DATA) &&
                    (data_arg.size != I2C_SMBUS_BLOCK_PROC_CALL)) {
                        dev_dbg(&client->adapter->dev,
@@ -329,10 +330,18 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file,
 
                if ((data_arg.size == I2C_SMBUS_PROC_CALL) ||
                    (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) ||
+                   (data_arg.size == I2C_SMBUS_I2C_BLOCK_DATA) ||
                    (data_arg.read_write == I2C_SMBUS_WRITE)) {
                        if (copy_from_user(&temp, data_arg.data, datasize))
                                return -EFAULT;
                }
+               if (data_arg.size == I2C_SMBUS_I2C_BLOCK_BROKEN) {
+                       /* Convert old I2C block commands to the new
+                          convention. This preserves binary compatibility. */
+                       data_arg.size = I2C_SMBUS_I2C_BLOCK_DATA;
+                       if (data_arg.read_write == I2C_SMBUS_READ)
+                               temp.block[0] = I2C_SMBUS_BLOCK_MAX;
+               }
                res = i2c_smbus_xfer(client->adapter,client->addr,client->flags,
                      data_arg.read_write,
                      data_arg.command,data_arg.size,&temp);
index 66f826252aee4d6c66fa606a2348c25f4d3a4dad..444a0b84f5bdeddbff12fcfb40265c5f6f4b224e 100644 (file)
@@ -448,23 +448,21 @@ static int icside_dma_test_irq(ide_drive_t *drive)
                        ICS_ARCIN_V6_INTRSTAT_1)) & 1;
 }
 
-static int icside_dma_timeout(ide_drive_t *drive)
+static void icside_dma_timeout(ide_drive_t *drive)
 {
        printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name);
 
        if (icside_dma_test_irq(drive))
-               return 0;
+               return;
 
-       ide_dump_status(drive, "DMA timeout",
-               HWIF(drive)->INB(IDE_STATUS_REG));
+       ide_dump_status(drive, "DMA timeout", HWIF(drive)->INB(IDE_STATUS_REG));
 
-       return icside_dma_end(drive);
+       icside_dma_end(drive);
 }
 
-static int icside_dma_lostirq(ide_drive_t *drive)
+static void icside_dma_lost_irq(ide_drive_t *drive)
 {
        printk(KERN_ERR "%s: IRQ lost\n", drive->name);
-       return 1;
 }
 
 static void icside_dma_init(ide_hwif_t *hwif)
@@ -490,8 +488,8 @@ static void icside_dma_init(ide_hwif_t *hwif)
        hwif->dma_start         = icside_dma_start;
        hwif->ide_dma_end       = icside_dma_end;
        hwif->ide_dma_test_irq  = icside_dma_test_irq;
-       hwif->ide_dma_timeout   = icside_dma_timeout;
-       hwif->ide_dma_lostirq   = icside_dma_lostirq;
+       hwif->dma_timeout       = icside_dma_timeout;
+       hwif->dma_lost_irq      = icside_dma_lost_irq;
 
        hwif->drives[0].autodma = hwif->autodma;
        hwif->drives[1].autodma = hwif->autodma;
index ca0341c05e556bf8828cc32349c7cfc07da29ebd..886091bc7db01e1028804b136a635f53f7c6cc3f 100644 (file)
@@ -819,7 +819,7 @@ init_e100_ide (void)
                hwif->dma_host_off = &cris_dma_off;
                hwif->dma_host_on = &cris_dma_on;
                hwif->dma_off_quietly = &cris_dma_off;
-               hwif->udma_four = 0;
+               hwif->cbl = ATA_CBL_PATA40;
                hwif->ultra_mask = cris_ultra_mask;
                hwif->mwdma_mask = 0x07; /* Multiword DMA 0-2 */
                hwif->autodma = 1;
index 252ab8295edfd9fef5fc0fb029e0ed33c898e9f0..1486eb212ccc7b2952ebe0d9fba53edd2e5324c2 100644 (file)
@@ -481,7 +481,7 @@ void cdrom_analyze_sense_data(ide_drive_t *drive,
                else
                        printk("  Unknown Error Type: ");
 
-               if (sense->sense_key < ARY_LEN(sense_key_texts))
+               if (sense->sense_key < ARRAY_SIZE(sense_key_texts))
                        s = sense_key_texts[sense->sense_key];
 
                printk("%s -- (Sense key=0x%02x)\n", s, sense->sense_key);
@@ -491,7 +491,7 @@ void cdrom_analyze_sense_data(ide_drive_t *drive,
                                 sense->ascq);
                        s = buf;
                } else {
-                       int lo = 0, mid, hi = ARY_LEN(sense_data_texts);
+                       int lo = 0, mid, hi = ARRAY_SIZE(sense_data_texts);
                        unsigned long key = (sense->sense_key << 16);
                        key |= (sense->asc << 8);
                        if (!(sense->ascq >= 0x80 && sense->ascq <= 0xdd))
@@ -524,7 +524,7 @@ void cdrom_analyze_sense_data(ide_drive_t *drive,
 
                if (failed_command != NULL) {
 
-                       int lo=0, mid, hi= ARY_LEN (packet_command_texts);
+                       int lo=0, mid, hi= ARRAY_SIZE(packet_command_texts);
                        s = NULL;
 
                        while (hi > lo) {
index ad1f2ed14a3723cbcec3081341487e7d784c494c..228b29c5d2e4d0684d6f2490ed6aa7c5a6bfa098 100644 (file)
@@ -498,8 +498,6 @@ struct cdrom_info {
  * Descriptions of ATAPI error codes.
  */
 
-#define ARY_LEN(a) ((sizeof(a) / sizeof(a[0])))
-
 /* This stuff should be in cdrom.h, since it is now generic... */
 
 /* ATAPI sense keys (from table 140 of ATAPI 2.6) */
index dc2175c81f5efe5c955729efd5b23b22c612d48e..b1304a7f3e0acfea5bb2ab900a0f0f1ab75e0169 100644 (file)
@@ -1190,11 +1190,11 @@ static int idedisk_ioctl(struct inode *inode, struct file *file,
        return generic_ide_ioctl(drive, file, bdev, cmd, arg);
 
 read_val:
-       down(&ide_setting_sem);
+       mutex_lock(&ide_setting_mtx);
        spin_lock_irqsave(&ide_lock, flags);
        err = *val;
        spin_unlock_irqrestore(&ide_lock, flags);
-       up(&ide_setting_sem);
+       mutex_unlock(&ide_setting_mtx);
        return err >= 0 ? put_user(err, (long __user *)arg) : err;
 
 set_val:
@@ -1204,9 +1204,9 @@ set_val:
                if (!capable(CAP_SYS_ADMIN))
                        err = -EACCES;
                else {
-                       down(&ide_setting_sem);
+                       mutex_lock(&ide_setting_mtx);
                        err = setfunc(drive, arg);
-                       up(&ide_setting_sem);
+                       mutex_unlock(&ide_setting_mtx);
                }
        }
        return err;
index ead141e2db9e2d12213daaa5d746fe178a05724d..5fe1d72ab4514e97a5dbcc5c3c1ea6183cd46324 100644 (file)
 
 static const struct drive_list_entry drive_whitelist [] = {
 
-       { "Micropolis 2112A"    ,       "ALL"           },
-       { "CONNER CTMA 4000"    ,       "ALL"           },
-       { "CONNER CTT8000-A"    ,       "ALL"           },
-       { "ST34342A"            ,       "ALL"           },
+       { "Micropolis 2112A"    ,       NULL            },
+       { "CONNER CTMA 4000"    ,       NULL            },
+       { "CONNER CTT8000-A"    ,       NULL            },
+       { "ST34342A"            ,       NULL            },
        { NULL                  ,       NULL            }
 };
 
 static const struct drive_list_entry drive_blacklist [] = {
 
-       { "WDC AC11000H"        ,       "ALL"           },
-       { "WDC AC22100H"        ,       "ALL"           },
-       { "WDC AC32500H"        ,       "ALL"           },
-       { "WDC AC33100H"        ,       "ALL"           },
-       { "WDC AC31600H"        ,       "ALL"           },
+       { "WDC AC11000H"        ,       NULL            },
+       { "WDC AC22100H"        ,       NULL            },
+       { "WDC AC32500H"        ,       NULL            },
+       { "WDC AC33100H"        ,       NULL            },
+       { "WDC AC31600H"        ,       NULL            },
        { "WDC AC32100H"        ,       "24.09P07"      },
        { "WDC AC23200L"        ,       "21.10N21"      },
-       { "Compaq CRD-8241B"    ,       "ALL"           },
-       { "CRD-8400B"           ,       "ALL"           },
-       { "CRD-8480B",                  "ALL"           },
-       { "CRD-8482B",                  "ALL"           },
-       { "CRD-84"              ,       "ALL"           },
-       { "SanDisk SDP3B"       ,       "ALL"           },
-       { "SanDisk SDP3B-64"    ,       "ALL"           },
-       { "SANYO CD-ROM CRD"    ,       "ALL"           },
-       { "HITACHI CDR-8"       ,       "ALL"           },
-       { "HITACHI CDR-8335"    ,       "ALL"           },
-       { "HITACHI CDR-8435"    ,       "ALL"           },
-       { "Toshiba CD-ROM XM-6202B"     ,       "ALL"           },
-       { "TOSHIBA CD-ROM XM-1702BC",   "ALL"           },
-       { "CD-532E-A"           ,       "ALL"           },
-       { "E-IDE CD-ROM CR-840",        "ALL"           },
-       { "CD-ROM Drive/F5A",   "ALL"           },
-       { "WPI CDD-820",                "ALL"           },
-       { "SAMSUNG CD-ROM SC-148C",     "ALL"           },
-       { "SAMSUNG CD-ROM SC",  "ALL"           },
-       { "ATAPI CD-ROM DRIVE 40X MAXIMUM",     "ALL"           },
-       { "_NEC DV5800A",               "ALL"           },  
+       { "Compaq CRD-8241B"    ,       NULL            },
+       { "CRD-8400B"           ,       NULL            },
+       { "CRD-8480B",                  NULL            },
+       { "CRD-8482B",                  NULL            },
+       { "CRD-84"              ,       NULL            },
+       { "SanDisk SDP3B"       ,       NULL            },
+       { "SanDisk SDP3B-64"    ,       NULL            },
+       { "SANYO CD-ROM CRD"    ,       NULL            },
+       { "HITACHI CDR-8"       ,       NULL            },
+       { "HITACHI CDR-8335"    ,       NULL            },
+       { "HITACHI CDR-8435"    ,       NULL            },
+       { "Toshiba CD-ROM XM-6202B"     ,       NULL            },
+       { "TOSHIBA CD-ROM XM-1702BC",   NULL            },
+       { "CD-532E-A"           ,       NULL            },
+       { "E-IDE CD-ROM CR-840",        NULL            },
+       { "CD-ROM Drive/F5A",   NULL            },
+       { "WPI CDD-820",                NULL            },
+       { "SAMSUNG CD-ROM SC-148C",     NULL            },
+       { "SAMSUNG CD-ROM SC",  NULL            },
+       { "ATAPI CD-ROM DRIVE 40X MAXIMUM",     NULL            },
+       { "_NEC DV5800A",               NULL            },
        { "SAMSUNG CD-ROM SN-124",      "N001" },
-       { "Seagate STT20000A",          "ALL" },
+       { "Seagate STT20000A",          NULL  },
        { NULL                  ,       NULL            }
 
 };
@@ -147,8 +147,8 @@ int ide_in_drive_list(struct hd_driveid *id, const struct drive_list_entry *driv
 {
        for ( ; drive_table->id_model ; drive_table++)
                if ((!strcmp(drive_table->id_model, id->model)) &&
-                   ((strstr(id->fw_rev, drive_table->id_firmware)) ||
-                    (!strcmp(drive_table->id_firmware, "ALL"))))
+                   (!drive_table->id_firmware ||
+                    strstr(id->fw_rev, drive_table->id_firmware)))
                        return 1;
        return 0;
 }
@@ -702,8 +702,22 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base)
                        mask = id->dma_mword & hwif->mwdma_mask;
                break;
        case XFER_SW_DMA_0:
-               if (id->field_valid & 2)
+               if (id->field_valid & 2) {
                        mask = id->dma_1word & hwif->swdma_mask;
+               } else if (id->tDMA) {
+                       /*
+                        * ide_fix_driveid() doesn't convert ->tDMA to the
+                        * CPU endianness so we need to do it here
+                        */
+                       u8 mode = le16_to_cpu(id->tDMA);
+
+                       /*
+                        * if the mode is valid convert it to the mask
+                        * (the maximum allowed mode is XFER_SW_DMA_2)
+                        */
+                       if (mode <= 2)
+                               mask = ((2 << mode) - 1) & hwif->swdma_mask;
+               }
                break;
        default:
                BUG();
@@ -847,27 +861,27 @@ int ide_set_dma(ide_drive_t *drive)
        return rc;
 }
 
-EXPORT_SYMBOL_GPL(ide_set_dma);
-
 #ifdef CONFIG_BLK_DEV_IDEDMA_PCI
-int __ide_dma_lostirq (ide_drive_t *drive)
+void ide_dma_lost_irq (ide_drive_t *drive)
 {
        printk("%s: DMA interrupt recovery\n", drive->name);
-       return 1;
 }
 
-EXPORT_SYMBOL(__ide_dma_lostirq);
+EXPORT_SYMBOL(ide_dma_lost_irq);
 
-int __ide_dma_timeout (ide_drive_t *drive)
+void ide_dma_timeout (ide_drive_t *drive)
 {
+       ide_hwif_t *hwif = HWIF(drive);
+
        printk(KERN_ERR "%s: timeout waiting for DMA\n", drive->name);
-       if (HWIF(drive)->ide_dma_test_irq(drive))
-               return 0;
 
-       return HWIF(drive)->ide_dma_end(drive);
+       if (hwif->ide_dma_test_irq(drive))
+               return;
+
+       hwif->ide_dma_end(drive);
 }
 
-EXPORT_SYMBOL(__ide_dma_timeout);
+EXPORT_SYMBOL(ide_dma_timeout);
 
 /*
  * Needed for allowing full modular support of ide-driver
@@ -1018,10 +1032,10 @@ void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_p
                hwif->ide_dma_end = &__ide_dma_end;
        if (!hwif->ide_dma_test_irq)
                hwif->ide_dma_test_irq = &__ide_dma_test_irq;
-       if (!hwif->ide_dma_timeout)
-               hwif->ide_dma_timeout = &__ide_dma_timeout;
-       if (!hwif->ide_dma_lostirq)
-               hwif->ide_dma_lostirq = &__ide_dma_lostirq;
+       if (!hwif->dma_timeout)
+               hwif->dma_timeout = &ide_dma_timeout;
+       if (!hwif->dma_lost_irq)
+               hwif->dma_lost_irq = &ide_dma_lost_irq;
 
        if (hwif->chipset != ide_trm290) {
                u8 dma_stat = hwif->INB(hwif->dma_status);
index bfe8f1b712bad1cfc3356fdc204b2553a2f0583b..c5b5011da56e37a568c19e06dd27383a834fa358 100644 (file)
@@ -1350,7 +1350,7 @@ static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
                                                hwif->INB(IDE_STATUS_REG));
        } else {
                printk(KERN_WARNING "%s: DMA timeout retry\n", drive->name);
-               (void) hwif->ide_dma_timeout(drive);
+               hwif->dma_timeout(drive);
        }
 
        /*
@@ -1466,7 +1466,7 @@ void ide_timer_expiry (unsigned long data)
                                startstop = handler(drive);
                        } else if (drive_is_ready(drive)) {
                                if (drive->waiting_for_dma)
-                                       (void) hwgroup->hwif->ide_dma_lostirq(drive);
+                                       hwgroup->hwif->dma_lost_irq(drive);
                                (void)ide_ack_intr(hwif);
                                printk(KERN_WARNING "%s: lost interrupt\n", drive->name);
                                startstop = handler(drive);
index f0be5f665a0e0ae21af516609c0a82c556b4e0cd..92578b6832e9fbb2e31dd0287f1664ae979ab082 100644 (file)
@@ -574,7 +574,10 @@ u8 eighty_ninty_three (ide_drive_t *drive)
        ide_hwif_t *hwif = drive->hwif;
        struct hd_driveid *id = drive->id;
 
-       if (hwif->udma_four == 0)
+       if (hwif->cbl == ATA_CBL_PATA40_SHORT)
+               return 1;
+
+       if (hwif->cbl != ATA_CBL_PATA80)
                goto no_80w;
 
        /* Check for SATA but only if we are ATA5 or higher */
@@ -600,7 +603,8 @@ no_80w:
 
        printk(KERN_WARNING "%s: %s side 80-wire cable detection failed, "
                            "limiting max speed to UDMA33\n",
-                           drive->name, hwif->udma_four ? "drive" : "host");
+                           drive->name,
+                           hwif->cbl == ATA_CBL_PATA80 ? "drive" : "host");
 
        drive->udma33_warned = 1;
 
index f5ce22c38f827eceec594021ad68d1c5811aeacf..cc5801399467360bbd1097a5aa36801a487a6a36 100644 (file)
@@ -144,7 +144,7 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd)
        local_irq_enable();
        ide_fix_driveid(id);
 
-#if defined (CONFIG_SCSI_EATA_DMA) || defined (CONFIG_SCSI_EATA_PIO) || defined (CONFIG_SCSI_EATA)
+#if defined (CONFIG_SCSI_EATA_PIO) || defined (CONFIG_SCSI_EATA)
        /*
         * EATA SCSI controllers do a hardware ATA emulation:
         * Ignore them if there is a driver for them available.
@@ -154,7 +154,7 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd)
                printk("%s: EATA SCSI HBA %.10s\n", drive->name, id->model);
                goto err_misc;
        }
-#endif /* CONFIG_SCSI_EATA_DMA || CONFIG_SCSI_EATA_PIO */
+#endif /* CONFIG_SCSI_EATA || CONFIG_SCSI_EATA_PIO */
 
        /*
         *  WIN_IDENTIFY returns little-endian info,
@@ -1025,7 +1025,7 @@ static int init_irq (ide_hwif_t *hwif)
        BUG_ON(irqs_disabled());        
        BUG_ON(hwif == NULL);
 
-       down(&ide_cfg_sem);
+       mutex_lock(&ide_cfg_mtx);
        hwif->hwgroup = NULL;
 #if MAX_HWIFS > 1
        /*
@@ -1154,7 +1154,7 @@ static int init_irq (ide_hwif_t *hwif)
                printk(" (%sed with %s)",
                        hwif->sharing_irq ? "shar" : "serializ", match->name);
        printk("\n");
-       up(&ide_cfg_sem);
+       mutex_unlock(&ide_cfg_mtx);
        return 0;
 out_unlink:
        spin_lock_irq(&ide_lock);
@@ -1177,7 +1177,7 @@ out_unlink:
        }
        spin_unlock_irq(&ide_lock);
 out_up:
-       up(&ide_cfg_sem);
+       mutex_unlock(&ide_cfg_mtx);
        return 1;
 }
 
index ea94c9aa1220754b8cad352bff4cb8102e08075f..fc1d8ae6a80381d08937faf4dc5d2fd687d33c7c 100644 (file)
@@ -156,7 +156,7 @@ static int __ide_add_setting(ide_drive_t *drive, const char *name, int rw, int d
 {
        ide_settings_t **p = (ide_settings_t **) &drive->settings, *setting = NULL;
 
-       down(&ide_setting_sem);
+       mutex_lock(&ide_setting_mtx);
        while ((*p) && strcmp((*p)->name, name) < 0)
                p = &((*p)->next);
        if ((setting = kzalloc(sizeof(*setting), GFP_KERNEL)) == NULL)
@@ -177,10 +177,10 @@ static int __ide_add_setting(ide_drive_t *drive, const char *name, int rw, int d
        if (auto_remove)
                setting->auto_remove = 1;
        *p = setting;
-       up(&ide_setting_sem);
+       mutex_unlock(&ide_setting_mtx);
        return 0;
 abort:
-       up(&ide_setting_sem);
+       mutex_unlock(&ide_setting_mtx);
        kfree(setting);
        return -1;
 }
@@ -224,7 +224,7 @@ static void __ide_remove_setting (ide_drive_t *drive, char *name)
  *
  *     Automatically remove all the driver specific settings for this
  *     drive. This function may not be called from IRQ context. The
- *     caller must hold ide_setting_sem.
+ *     caller must hold ide_setting_mtx.
  */
 
 static void auto_remove_settings (ide_drive_t *drive)
@@ -269,7 +269,7 @@ static ide_settings_t *ide_find_setting_by_name(ide_drive_t *drive, char *name)
  *     @setting: drive setting
  *
  *     Read a drive setting and return the value. The caller
- *     must hold the ide_setting_sem when making this call.
+ *     must hold the ide_setting_mtx when making this call.
  *
  *     BUGS: the data return and error are the same return value
  *     so an error -EINVAL and true return of the same value cannot
@@ -306,7 +306,7 @@ static int ide_read_setting(ide_drive_t *drive, ide_settings_t *setting)
  *     @val: value
  *
  *     Write a drive setting if it is possible. The caller
- *     must hold the ide_setting_sem when making this call.
+ *     must hold the ide_setting_mtx when making this call.
  *
  *     BUGS: the data return and error are the same return value
  *     so an error -EINVAL and true return of the same value cannot
@@ -367,7 +367,7 @@ static int set_xfer_rate (ide_drive_t *drive, int arg)
  *     @drive: drive being configured
  *
  *     Add the generic parts of the system settings to the /proc files.
- *     The caller must not be holding the ide_setting_sem.
+ *     The caller must not be holding the ide_setting_mtx.
  */
 
 void ide_add_generic_settings (ide_drive_t *drive)
@@ -408,7 +408,7 @@ static int proc_ide_read_settings
 
        proc_ide_settings_warn();
 
-       down(&ide_setting_sem);
+       mutex_lock(&ide_setting_mtx);
        out += sprintf(out, "name\t\t\tvalue\t\tmin\t\tmax\t\tmode\n");
        out += sprintf(out, "----\t\t\t-----\t\t---\t\t---\t\t----\n");
        while(setting) {
@@ -428,7 +428,7 @@ static int proc_ide_read_settings
                setting = setting->next;
        }
        len = out - page;
-       up(&ide_setting_sem);
+       mutex_unlock(&ide_setting_mtx);
        PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
 }
 
@@ -508,16 +508,16 @@ static int proc_ide_write_settings(struct file *file, const char __user *buffer,
                                ++p;
                        }
 
-                       down(&ide_setting_sem);
+                       mutex_lock(&ide_setting_mtx);
                        setting = ide_find_setting_by_name(drive, name);
                        if (!setting)
                        {
-                               up(&ide_setting_sem);
+                               mutex_unlock(&ide_setting_mtx);
                                goto parse_error;
                        }
                        if (for_real)
                                ide_write_setting(drive, setting, val * setting->div_factor / setting->mul_factor);
-                       up(&ide_setting_sem);
+                       mutex_unlock(&ide_setting_mtx);
                }
        } while (!for_real++);
        free_page((unsigned long)buf);
@@ -705,7 +705,7 @@ EXPORT_SYMBOL(ide_proc_register_driver);
  *     Clean up the driver specific /proc files and IDE settings
  *     for a given drive.
  *
- *     Takes ide_setting_sem and ide_lock.
+ *     Takes ide_setting_mtx and ide_lock.
  *     Caller must hold none of the locks.
  */
 
@@ -715,10 +715,10 @@ void ide_proc_unregister_driver(ide_drive_t *drive, ide_driver_t *driver)
 
        ide_remove_proc_entries(drive->proc, driver->proc);
 
-       down(&ide_setting_sem);
+       mutex_lock(&ide_setting_mtx);
        spin_lock_irqsave(&ide_lock, flags);
        /*
-        * ide_setting_sem protects the settings list
+        * ide_setting_mtx protects the settings list
         * ide_lock protects the use of settings
         *
         * so we need to hold both, ide_settings_sem because we want to
@@ -726,11 +726,11 @@ void ide_proc_unregister_driver(ide_drive_t *drive, ide_driver_t *driver)
         * a setting out that is being used.
         *
         * OTOH both ide_{read,write}_setting are only ever used under
-        * ide_setting_sem.
+        * ide_setting_mtx.
         */
        auto_remove_settings(drive);
        spin_unlock_irqrestore(&ide_lock, flags);
-       up(&ide_setting_sem);
+       mutex_unlock(&ide_setting_mtx);
 }
 
 EXPORT_SYMBOL(ide_proc_unregister_driver);
index c0864b1e92285ed514fe5982a79383fdd9efbc3b..e6cb8593b5ba8382ce4e481e524bdcf6b1de3ca7 100644 (file)
@@ -102,66 +102,16 @@ static struct ide_timing ide_timing[] = {
 #define EZ(v,unit)             ((v)?ENOUGH(v,unit):0)
 
 #define XFER_MODE      0xf0
-#define XFER_UDMA_133  0x48
-#define XFER_UDMA_100  0x44
-#define XFER_UDMA_66   0x42
-#define XFER_UDMA      0x40
 #define XFER_MWDMA     0x20
-#define XFER_SWDMA     0x10
 #define XFER_EPIO      0x01
 #define XFER_PIO       0x00
 
-static short ide_find_best_mode(ide_drive_t *drive, int map)
+static short ide_find_best_pio_mode(ide_drive_t *drive)
 {
        struct hd_driveid *id = drive->id;
        short best = 0;
 
-       if (!id)
-               return XFER_PIO_SLOW;
-
-       if ((map & XFER_UDMA) && (id->field_valid & 4)) {       /* Want UDMA and UDMA bitmap valid */
-
-               if ((map & XFER_UDMA_133) == XFER_UDMA_133)
-                       if ((best = (id->dma_ultra & 0x0040) ? XFER_UDMA_6 : 0)) return best;
-
-               if ((map & XFER_UDMA_100) == XFER_UDMA_100)
-                       if ((best = (id->dma_ultra & 0x0020) ? XFER_UDMA_5 : 0)) return best;
-
-               if ((map & XFER_UDMA_66) == XFER_UDMA_66)
-                       if ((best = (id->dma_ultra & 0x0010) ? XFER_UDMA_4 :
-                                   (id->dma_ultra & 0x0008) ? XFER_UDMA_3 : 0)) return best;
-
-                if ((best = (id->dma_ultra & 0x0004) ? XFER_UDMA_2 :
-                           (id->dma_ultra & 0x0002) ? XFER_UDMA_1 :
-                           (id->dma_ultra & 0x0001) ? XFER_UDMA_0 : 0)) return best;
-       }
-
-       if ((map & XFER_MWDMA) && (id->field_valid & 2)) {      /* Want MWDMA and drive has EIDE fields */
-
-               if ((best = (id->dma_mword & 0x0004) ? XFER_MW_DMA_2 :
-                           (id->dma_mword & 0x0002) ? XFER_MW_DMA_1 :
-                           (id->dma_mword & 0x0001) ? XFER_MW_DMA_0 : 0)) return best;
-       }
-
-       if (map & XFER_SWDMA) {                                 /* Want SWDMA */
-
-               if (id->field_valid & 2) {                      /* EIDE SWDMA */
-
-                       if ((best = (id->dma_1word & 0x0004) ? XFER_SW_DMA_2 :
-                                   (id->dma_1word & 0x0002) ? XFER_SW_DMA_1 :
-                                   (id->dma_1word & 0x0001) ? XFER_SW_DMA_0 : 0)) return best;
-               }
-
-               if (id->capability & 1) {                       /* Pre-EIDE style SWDMA */
-
-                       if ((best = (id->tDMA == 2) ? XFER_SW_DMA_2 :
-                                   (id->tDMA == 1) ? XFER_SW_DMA_1 :
-                                   (id->tDMA == 0) ? XFER_SW_DMA_0 : 0)) return best;
-               }
-       }
-
-
-       if ((map & XFER_EPIO) && (id->field_valid & 2)) {       /* EIDE PIO modes */
+       if (id->field_valid & 2) {      /* EIDE PIO modes */
 
                if ((best = (drive->id->eide_pio_modes & 4) ? XFER_PIO_5 :
                            (drive->id->eide_pio_modes & 2) ? XFER_PIO_4 :
@@ -262,7 +212,7 @@ static int ide_timing_compute(ide_drive_t *drive, short speed, struct ide_timing
  */
 
        if ((speed & XFER_MODE) != XFER_PIO) {
-               ide_timing_compute(drive, ide_find_best_mode(drive, XFER_PIO | XFER_EPIO), &p, T, UT);
+               ide_timing_compute(drive, ide_find_best_pio_mode(drive), &p, T, UT);
                ide_timing_merge(&p, t, t, IDE_TIMING_ALL);
        }
 
index 0cd76bf66833aa1afedc47715fc9271d5a85145d..c948a5c17a5d8c1e1cb5afe9682afa1f51e95442 100644 (file)
@@ -169,7 +169,7 @@ static const u8 ide_hwif_to_major[] = { IDE0_MAJOR, IDE1_MAJOR,
 static int idebus_parameter;   /* holds the "idebus=" parameter */
 static int system_bus_speed;   /* holds what we think is VESA/PCI bus speed */
 
-DECLARE_MUTEX(ide_cfg_sem);
+DEFINE_MUTEX(ide_cfg_mtx);
  __cacheline_aligned_in_smp DEFINE_SPINLOCK(ide_lock);
 
 #ifdef CONFIG_IDEPCI_PCIBUS_ORDER
@@ -460,6 +460,8 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
        hwif->mwdma_mask                = tmp_hwif->mwdma_mask;
        hwif->swdma_mask                = tmp_hwif->swdma_mask;
 
+       hwif->cbl                       = tmp_hwif->cbl;
+
        hwif->chipset                   = tmp_hwif->chipset;
        hwif->hold                      = tmp_hwif->hold;
 
@@ -496,8 +498,8 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
        hwif->ide_dma_clear_irq         = tmp_hwif->ide_dma_clear_irq;
        hwif->dma_host_on               = tmp_hwif->dma_host_on;
        hwif->dma_host_off              = tmp_hwif->dma_host_off;
-       hwif->ide_dma_lostirq           = tmp_hwif->ide_dma_lostirq;
-       hwif->ide_dma_timeout           = tmp_hwif->ide_dma_timeout;
+       hwif->dma_lost_irq              = tmp_hwif->dma_lost_irq;
+       hwif->dma_timeout               = tmp_hwif->dma_timeout;
 
        hwif->OUTB                      = tmp_hwif->OUTB;
        hwif->OUTBSYNC                  = tmp_hwif->OUTBSYNC;
@@ -533,7 +535,6 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
        hwif->extra_base                = tmp_hwif->extra_base;
        hwif->extra_ports               = tmp_hwif->extra_ports;
        hwif->autodma                   = tmp_hwif->autodma;
-       hwif->udma_four                 = tmp_hwif->udma_four;
 
        hwif->hwif_data                 = tmp_hwif->hwif_data;
 }
@@ -564,7 +565,7 @@ void ide_unregister(unsigned int index)
 {
        ide_drive_t *drive;
        ide_hwif_t *hwif, *g;
-       static ide_hwif_t tmp_hwif; /* protected by ide_cfg_sem */
+       static ide_hwif_t tmp_hwif; /* protected by ide_cfg_mtx */
        ide_hwgroup_t *hwgroup;
        int irq_count = 0, unit;
 
@@ -572,7 +573,7 @@ void ide_unregister(unsigned int index)
 
        BUG_ON(in_interrupt());
        BUG_ON(irqs_disabled());
-       down(&ide_cfg_sem);
+       mutex_lock(&ide_cfg_mtx);
        spin_lock_irq(&ide_lock);
        hwif = &ide_hwifs[index];
        if (!hwif->present)
@@ -679,7 +680,7 @@ void ide_unregister(unsigned int index)
 
 abort:
        spin_unlock_irq(&ide_lock);
-       up(&ide_cfg_sem);
+       mutex_unlock(&ide_cfg_mtx);
 }
 
 EXPORT_SYMBOL(ide_unregister);
@@ -817,9 +818,9 @@ EXPORT_SYMBOL(ide_register_hw);
  *     Locks for IDE setting functionality
  */
 
-DECLARE_MUTEX(ide_setting_sem);
+DEFINE_MUTEX(ide_setting_mtx);
 
-EXPORT_SYMBOL_GPL(ide_setting_sem);
+EXPORT_SYMBOL_GPL(ide_setting_mtx);
 
 /**
  *     ide_spin_wait_hwgroup   -       wait for group
@@ -1192,11 +1193,11 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device
        }
 
 read_val:
-       down(&ide_setting_sem);
+       mutex_lock(&ide_setting_mtx);
        spin_lock_irqsave(&ide_lock, flags);
        err = *val;
        spin_unlock_irqrestore(&ide_lock, flags);
-       up(&ide_setting_sem);
+       mutex_unlock(&ide_setting_mtx);
        return err >= 0 ? put_user(err, (long __user *)arg) : err;
 
 set_val:
@@ -1206,9 +1207,9 @@ set_val:
                if (!capable(CAP_SYS_ADMIN))
                        err = -EACCES;
                else {
-                       down(&ide_setting_sem);
+                       mutex_lock(&ide_setting_mtx);
                        err = setfunc(drive, arg);
-                       up(&ide_setting_sem);
+                       mutex_unlock(&ide_setting_mtx);
                }
        }
        return err;
@@ -1548,7 +1549,11 @@ static int __init ide_setup(char *s)
                                goto bad_option;
                        case -7: /* ata66 */
 #ifdef CONFIG_BLK_DEV_IDEPCI
-                               hwif->udma_four = 1;
+                               /*
+                                * Use ATA_CBL_PATA40_SHORT so drive side
+                                * cable detection is also overriden.
+                                */
+                               hwif->cbl = ATA_CBL_PATA40_SHORT;
                                goto obsolete_option;
 #else
                                goto bad_hwif;
index 45ed03591cd88df752caeb58bea03379f6367cd8..8f2db8dd35f75f7875e3cac91cbf6303de086e19 100644 (file)
@@ -130,7 +130,7 @@ struct hd_i_struct {
        
 #ifdef HD_TYPE
 static struct hd_i_struct hd_info[] = { HD_TYPE };
-static int NR_HD = ((sizeof (hd_info))/(sizeof (struct hd_i_struct)));
+static int NR_HD = ARRAY_SIZE(hd_info);
 #else
 static struct hd_i_struct hd_info[MAX_HD];
 static int NR_HD;
@@ -623,7 +623,8 @@ repeat:
        cyl   = track / disk->head;
 #ifdef DEBUG
        printk("%s: %sing: CHS=%d/%d/%d, sectors=%d, buffer=%p\n",
-               req->rq_disk->disk_name, (req->cmd == READ)?"read":"writ",
+               req->rq_disk->disk_name,
+               req_data_dir(req) == READ ? "read" : "writ",
                cyl, head, sec, nsect, req->buffer);
 #endif
        if (blk_fs_request(req)) {
@@ -718,74 +719,25 @@ static int __init hd_init(void)
        device_timer.function = hd_times_out;
        blk_queue_hardsect_size(hd_queue, 512);
 
-#ifdef __i386__
        if (!NR_HD) {
-               extern struct drive_info drive_info;
-               unsigned char *BIOS = (unsigned char *) &drive_info;
-               unsigned long flags;
-               int cmos_disks;
-
-               for (drive=0 ; drive<2 ; drive++) {
-                       hd_info[drive].cyl = *(unsigned short *) BIOS;
-                       hd_info[drive].head = *(2+BIOS);
-                       hd_info[drive].wpcom = *(unsigned short *) (5+BIOS);
-                       hd_info[drive].ctl = *(8+BIOS);
-                       hd_info[drive].lzone = *(unsigned short *) (12+BIOS);
-                       hd_info[drive].sect = *(14+BIOS);
-#ifdef does_not_work_for_everybody_with_scsi_but_helps_ibm_vp
-                       if (hd_info[drive].cyl && NR_HD == drive)
-                               NR_HD++;
-#endif
-                       BIOS += 16;
-               }
-
-       /*
-               We query CMOS about hard disks : it could be that 
-               we have a SCSI/ESDI/etc controller that is BIOS
-               compatible with ST-506, and thus showing up in our
-               BIOS table, but not register compatible, and therefore
-               not present in CMOS.
-
-               Furthermore, we will assume that our ST-506 drives
-               <if any> are the primary drives in the system, and 
-               the ones reflected as drive 1 or 2.
-
-               The first drive is stored in the high nibble of CMOS
-               byte 0x12, the second in the low nibble.  This will be
-               either a 4 bit drive type or 0xf indicating use byte 0x19 
-               for an 8 bit type, drive 1, 0x1a for drive 2 in CMOS.
-
-               Needless to say, a non-zero value means we have 
-               an AT controller hard disk for that drive.
-
-               Currently the rtc_lock is a bit academic since this
-               driver is non-modular, but someday... ?         Paul G.
-       */
-
-               spin_lock_irqsave(&rtc_lock, flags);
-               cmos_disks = CMOS_READ(0x12);
-               spin_unlock_irqrestore(&rtc_lock, flags);
-
-               if (cmos_disks & 0xf0) {
-                       if (cmos_disks & 0x0f)
-                               NR_HD = 2;
-                       else
-                               NR_HD = 1;
-               }
-       }
-#endif /* __i386__ */
-#ifdef __arm__
-       if (!NR_HD) {
-               /* We don't know anything about the drive.  This means
+               /*
+                * We don't know anything about the drive.  This means
                 * that you *MUST* specify the drive parameters to the
                 * kernel yourself.
+                *
+                * If we were on an i386, we used to read this info from
+                * the BIOS or CMOS.  This doesn't work all that well,
+                * since this assumes that this is a primary or secondary
+                * drive, and if we're using this legacy driver, it's
+                * probably an auxilliary controller added to recover
+                * legacy data off an ST-506 drive.  Either way, it's
+                * definitely safest to have the user explicitly specify
+                * the information.
                 */
                printk("hd: no drives specified - use hd=cyl,head,sectors"
                        " on kernel command line\n");
-       }
-#endif
-       if (!NR_HD)
                goto out;
+       }
 
        for (drive=0 ; drive < NR_HD ; drive++) {
                struct gendisk *disk = alloc_disk(64);
index c211fc78345d16b0c3f9da4ef96b8a1ff6c79bbd..b557c45a5a9dc614e7aa556e07554f5b3623457a 100644 (file)
@@ -77,15 +77,6 @@ int macide_ack_intr(ide_hwif_t* hwif)
        return 0;
 }
 
-#ifdef CONFIG_BLK_DEV_MAC_MEDIABAY
-static void macide_mediabay_interrupt(int irq, void *dev_id)
-{
-       int state = baboon->mb_status & 0x04;
-
-       printk(KERN_INFO "macide: media bay %s detected\n", state? "removal":"insertion");
-}
-#endif
-
 /*
  * Probe for a Macintosh IDE interface
  */
@@ -128,11 +119,6 @@ void macide_init(void)
                        ide_drive_t *drive = &ide_hwifs[index].drives[0];
                        drive->capacity64 = drive->cyl*drive->head*drive->sect;
 
-#ifdef CONFIG_BLK_DEV_MAC_MEDIABAY
-                       request_irq(IRQ_BABOON_2, macide_mediabay_interrupt,
-                                       IRQ_FLG_FAST, "mediabay",
-                                       macide_mediabay_interrupt);
-#endif
                }
                break;
 
index ca95e990862ebdf36df33f936e47709b8d1ace6a..2e7013a2a7f635073eefef53498a54698e095fe5 100644 (file)
@@ -381,9 +381,7 @@ static int auide_dma_setup(ide_drive_t *drive)
 
 static int auide_dma_check(ide_drive_t *drive)
 {
-       u8 speed;
-
-#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+       u8 speed = ide_max_dma_mode(drive);
 
        if( dbdma_init_done == 0 ){
                auide_hwif.white_list = ide_in_drive_list(drive->id,
@@ -394,7 +392,6 @@ static int auide_dma_check(ide_drive_t *drive)
                auide_ddma_init(&auide_hwif);
                dbdma_init_done = 1;
        }
-#endif
 
        /* Is the drive in our DMA black list? */
 
@@ -409,8 +406,6 @@ static int auide_dma_check(ide_drive_t *drive)
        else
                drive->using_dma = 1;
 
-       speed = ide_find_best_mode(drive, XFER_PIO | XFER_MWDMA);
-       
        if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
                return 0;
 
@@ -456,10 +451,9 @@ static void auide_dma_off_quietly(ide_drive_t *drive)
        drive->using_dma = 0;
 }
 
-static int auide_dma_lostirq(ide_drive_t *drive)
+static void auide_dma_lost_irq(ide_drive_t *drive)
 {
        printk(KERN_ERR "%s: IRQ lost\n", drive->name);
-       return 0;
 }
 
 static void auide_ddma_tx_callback(int irq, void *param)
@@ -489,16 +483,16 @@ static void auide_init_dbdma_dev(dbdev_tab_t *dev, u32 dev_id, u32 tsize, u32 de
   
 #if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
 
-static int auide_dma_timeout(ide_drive_t *drive)
+static void auide_dma_timeout(ide_drive_t *drive)
 {
-//      printk("%s\n", __FUNCTION__);
+       ide_hwif_t *hwif = HWIF(drive);
 
        printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name);
 
-       if (HWIF(drive)->ide_dma_test_irq(drive))
-               return 0;
+       if (hwif->ide_dma_test_irq(drive))
+               return;
 
-       return HWIF(drive)->ide_dma_end(drive);
+       hwif->ide_dma_end(drive);
 }
                                        
 
@@ -721,7 +715,7 @@ static int au_ide_probe(struct device *dev)
 
 #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
        hwif->dma_off_quietly           = &auide_dma_off_quietly;
-       hwif->ide_dma_timeout           = &auide_dma_timeout;
+       hwif->dma_timeout               = &auide_dma_timeout;
 
        hwif->ide_dma_check             = &auide_dma_check;
        hwif->dma_exec_cmd              = &auide_dma_exec_cmd;
@@ -731,7 +725,7 @@ static int au_ide_probe(struct device *dev)
        hwif->ide_dma_test_irq          = &auide_dma_test_irq;
        hwif->dma_host_off              = &auide_dma_host_off;
        hwif->dma_host_on               = &auide_dma_host_on;
-       hwif->ide_dma_lostirq           = &auide_dma_lostirq;
+       hwif->dma_lost_irq              = &auide_dma_lost_irq;
        hwif->ide_dma_on                = &auide_dma_on;
 
        hwif->autodma                   = 1;
index b173bc66ce1e19ae25efef18e8361864c850a877..e5d09367627ee19e99217af29dd2bae68fc50286 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/ide/pci/aec62xx.c             Version 0.21    Apr 21, 2007
+ * linux/drivers/ide/pci/aec62xx.c             Version 0.24    May 24, 2007
  *
  * Copyright (C) 1999-2002     Andre Hedrick <andre@linux-ide.org>
  * Copyright (C) 2007          MontaVista Software, Inc. <source@mvista.com>
@@ -140,25 +140,10 @@ static int aec6260_tune_chipset (ide_drive_t *drive, u8 xferspeed)
        return(ide_config_drive_speed(drive, speed));
 }
 
-static int aec62xx_tune_chipset (ide_drive_t *drive, u8 speed)
-{
-       switch (HWIF(drive)->pci_dev->device) {
-               case PCI_DEVICE_ID_ARTOP_ATP865:
-               case PCI_DEVICE_ID_ARTOP_ATP865R:
-               case PCI_DEVICE_ID_ARTOP_ATP860:
-               case PCI_DEVICE_ID_ARTOP_ATP860R:
-                       return ((int) aec6260_tune_chipset(drive, speed));
-               case PCI_DEVICE_ID_ARTOP_ATP850UF:
-                       return ((int) aec6210_tune_chipset(drive, speed));
-               default:
-                       return -1;
-       }
-}
-
 static void aec62xx_tune_drive (ide_drive_t *drive, u8 pio)
 {
        pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
-       (void) aec62xx_tune_chipset(drive, pio + XFER_PIO_0);
+       (void) HWIF(drive)->speedproc(drive, pio + XFER_PIO_0);
 }
 
 static int aec62xx_config_drive_xfer_rate (ide_drive_t *drive)
@@ -172,12 +157,9 @@ static int aec62xx_config_drive_xfer_rate (ide_drive_t *drive)
        return -1;
 }
 
-static int aec62xx_irq_timeout (ide_drive_t *drive)
+static void aec62xx_dma_lost_irq (ide_drive_t *drive)
 {
-       ide_hwif_t *hwif        = HWIF(drive);
-       struct pci_dev *dev     = hwif->pci_dev;
-
-       switch(dev->device) {
+       switch (HWIF(drive)->pci_dev->device) {
                case PCI_DEVICE_ID_ARTOP_ATP860:
                case PCI_DEVICE_ID_ARTOP_ATP860R:
                case PCI_DEVICE_ID_ARTOP_ATP865:
@@ -186,7 +168,6 @@ static int aec62xx_irq_timeout (ide_drive_t *drive)
                default:
                        break;
        }
-       return 0;
 }
 
 static unsigned int __devinit init_chipset_aec62xx(struct pci_dev *dev, const char *name)
@@ -224,64 +205,46 @@ static unsigned int __devinit init_chipset_aec62xx(struct pci_dev *dev, const ch
 
 static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif)
 {
-       struct pci_dev *dev = hwif->pci_dev;
+       struct pci_dev *dev     = hwif->pci_dev;
+       u8 reg54 = 0,  mask     = hwif->channel ? 0xf0 : 0x0f;
+       unsigned long flags;
 
-       hwif->autodma = 0;
        hwif->tuneproc = &aec62xx_tune_drive;
-       hwif->speedproc = &aec62xx_tune_chipset;
 
-       if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF)
-               hwif->serialized = hwif->channel;
-
-       if (hwif->mate)
-               hwif->mate->serialized = hwif->serialized;
+       if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) {
+               if(hwif->mate)
+                       hwif->mate->serialized = hwif->serialized = 1;
+               hwif->speedproc = &aec6210_tune_chipset;
+       } else
+               hwif->speedproc = &aec6260_tune_chipset;
 
        if (!hwif->dma_base) {
-               hwif->drives[0].autotune = 1;
-               hwif->drives[1].autotune = 1;
+               hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
                return;
        }
 
        hwif->ultra_mask = hwif->cds->udma_mask;
-
-       /* atp865 and atp865r */
-       if (hwif->ultra_mask == 0x3f) {
-               /* check bit 0x10 of DMA status register */
-               if (inb(pci_resource_start(dev, 4) + 2) & 0x10)
-                       hwif->ultra_mask = 0x7f; /* udma0-6 */
-       }
-
        hwif->mwdma_mask = 0x07;
 
        hwif->ide_dma_check     = &aec62xx_config_drive_xfer_rate;
-       hwif->ide_dma_lostirq   = &aec62xx_irq_timeout;
-
-       if (!noautodma)
-               hwif->autodma = 1;
-       hwif->drives[0].autodma = hwif->autodma;
-       hwif->drives[1].autodma = hwif->autodma;
-}
-
-static void __devinit init_dma_aec62xx(ide_hwif_t *hwif, unsigned long dmabase)
-{
-       struct pci_dev *dev     = hwif->pci_dev;
+       hwif->dma_lost_irq      = &aec62xx_dma_lost_irq;
 
        if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) {
-               u8 reg54h = 0;
-               unsigned long flags;
-
                spin_lock_irqsave(&ide_lock, flags);
-               pci_read_config_byte(dev, 0x54, &reg54h);
-               pci_write_config_byte(dev, 0x54, reg54h & ~(hwif->channel ? 0xF0 : 0x0F));
+               pci_read_config_byte (dev, 0x54, &reg54);
+               pci_write_config_byte(dev, 0x54, (reg54 & ~mask));
                spin_unlock_irqrestore(&ide_lock, flags);
-       } else {
-               u8 ata66        = 0;
+       } else if (hwif->cbl != ATA_CBL_PATA40_SHORT) {
+               u8 ata66 = 0, mask = hwif->channel ? 0x02 : 0x01;
+
                pci_read_config_byte(hwif->pci_dev, 0x49, &ata66);
-               if (!(hwif->udma_four))
-                       hwif->udma_four = (ata66&(hwif->channel?0x02:0x01))?0:1;
+
+               hwif->cbl = (ata66 & mask) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
        }
 
-       ide_setup_dma(hwif, dmabase, 8);
+       if (!noautodma)
+               hwif->autodma = 1;
+       hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma;
 }
 
 static int __devinit init_setup_aec62xx(struct pci_dev *dev, ide_pci_device_t *d)
@@ -291,16 +254,12 @@ static int __devinit init_setup_aec62xx(struct pci_dev *dev, ide_pci_device_t *d
 
 static int __devinit init_setup_aec6x80(struct pci_dev *dev, ide_pci_device_t *d)
 {
-       unsigned long bar4reg = pci_resource_start(dev, 4);
-
-       if (inb(bar4reg+2) & 0x10) {
-               strcpy(d->name, "AEC6880");
-               if (dev->device == PCI_DEVICE_ID_ARTOP_ATP865R)
-                       strcpy(d->name, "AEC6880R");
-       } else {
-               strcpy(d->name, "AEC6280");
-               if (dev->device == PCI_DEVICE_ID_ARTOP_ATP865R)
-                       strcpy(d->name, "AEC6280R");
+       unsigned long dma_base = pci_resource_start(dev, 4);
+
+       if (inb(dma_base + 2) & 0x10) {
+               d->name = (dev->device == PCI_DEVICE_ID_ARTOP_ATP865R) ?
+                         "AEC6880R" : "AEC6880";
+               d->udma_mask = 0x7f; /* udma0-6 */
        }
 
        return ide_setup_pci_device(dev, d);
@@ -312,7 +271,6 @@ static ide_pci_device_t aec62xx_chipsets[] __devinitdata = {
                .init_setup     = init_setup_aec62xx,
                .init_chipset   = init_chipset_aec62xx,
                .init_hwif      = init_hwif_aec62xx,
-               .init_dma       = init_dma_aec62xx,
                .channels       = 2,
                .autodma        = AUTODMA,
                .enablebits     = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
@@ -323,7 +281,6 @@ static ide_pci_device_t aec62xx_chipsets[] __devinitdata = {
                .init_setup     = init_setup_aec62xx,
                .init_chipset   = init_chipset_aec62xx,
                .init_hwif      = init_hwif_aec62xx,
-               .init_dma       = init_dma_aec62xx,
                .channels       = 2,
                .autodma        = NOAUTODMA,
                .bootable       = OFF_BOARD,
@@ -333,28 +290,25 @@ static ide_pci_device_t aec62xx_chipsets[] __devinitdata = {
                .init_setup     = init_setup_aec62xx,
                .init_chipset   = init_chipset_aec62xx,
                .init_hwif      = init_hwif_aec62xx,
-               .init_dma       = init_dma_aec62xx,
                .channels       = 2,
                .autodma        = AUTODMA,
                .enablebits     = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
                .bootable       = NEVER_BOARD,
                .udma_mask      = 0x1f, /* udma0-4 */
        },{     /* 3 */
-               .name           = "AEC6X80",
+               .name           = "AEC6280",
                .init_setup     = init_setup_aec6x80,
                .init_chipset   = init_chipset_aec62xx,
                .init_hwif      = init_hwif_aec62xx,
-               .init_dma       = init_dma_aec62xx,
                .channels       = 2,
                .autodma        = AUTODMA,
                .bootable       = OFF_BOARD,
                .udma_mask      = 0x3f, /* udma0-5 */
        },{     /* 4 */
-               .name           = "AEC6X80R",
+               .name           = "AEC6280R",
                .init_setup     = init_setup_aec6x80,
                .init_chipset   = init_chipset_aec62xx,
                .init_hwif      = init_hwif_aec62xx,
-               .init_dma       = init_dma_aec62xx,
                .channels       = 2,
                .autodma        = AUTODMA,
                .enablebits     = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
@@ -370,13 +324,16 @@ static ide_pci_device_t aec62xx_chipsets[] __devinitdata = {
  *
  *     Called when the PCI registration layer (or the IDE initialization)
  *     finds a device matching our IDE device tables.
+ *
+ *     NOTE: since we're going to modify the 'name' field for AEC-6[26]80[R]
+ *     chips, pass a local copy of 'struct pci_device_id' down the call chain.
  */
  
 static int __devinit aec62xx_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       ide_pci_device_t *d = &aec62xx_chipsets[id->driver_data];
+       ide_pci_device_t d = aec62xx_chipsets[id->driver_data];
 
-       return d->init_setup(dev, d);
+       return d.init_setup(dev, &d);
 }
 
 static struct pci_device_id aec62xx_pci_tbl[] = {
index 27525ec2e19a68a566a2c53bfba05d4c4263117d..ba0fb92b041770870dbfb5e49bdb0e2c28480f14 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/ide/pci/alim15x3.c            Version 0.21    2007/02/03
+ * linux/drivers/ide/pci/alim15x3.c            Version 0.25    Jun 9 2007
  *
  *  Copyright (C) 1998-2000 Michel Aubry, Maintainer
  *  Copyright (C) 1998-2000 Andrzej Krzysztofowicz, Maintainer
@@ -10,6 +10,7 @@
  *  Copyright (C) 2002 Alan Cox <alan@redhat.com>
  *  ALi (now ULi M5228) support by Clear Zhang <Clear.Zhang@ali.com.tw>
  *  Copyright (C) 2007 MontaVista Software, Inc. <source@mvista.com>
+ *  Copyright (C) 2007 Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
  *
  *  (U)DMA capable version of ali 1533/1543(C), 1535(D)
  *
@@ -36,6 +37,7 @@
 #include <linux/hdreg.h>
 #include <linux/ide.h>
 #include <linux/init.h>
+#include <linux/dmi.h>
 
 #include <asm/io.h>
 
@@ -506,7 +508,7 @@ static unsigned int __devinit init_chipset_ali15x3 (struct pci_dev *dev, const c
        u8 tmpbyte;
        struct pci_dev *north = pci_get_slot(dev->bus, PCI_DEVFN(0,0));
 
-       pci_read_config_byte(dev, PCI_REVISION_ID, &m5229_revision);
+       m5229_revision = dev->revision;
 
        isa_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);
 
@@ -583,6 +585,35 @@ out:
        return 0;
 }
 
+/*
+ *     Cable special cases
+ */
+
+static struct dmi_system_id cable_dmi_table[] = {
+       {
+               .ident = "HP Pavilion N5430",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
+                       DMI_MATCH(DMI_BOARD_NAME, "OmniBook N32N-736"),
+               },
+       },
+       { }
+};
+
+static int ali_cable_override(struct pci_dev *pdev)
+{
+       /* Fujitsu P2000 */
+       if (pdev->subsystem_vendor == 0x10CF &&
+           pdev->subsystem_device == 0x10AF)
+               return 1;
+
+       /* Systems by DMI */
+       if (dmi_check_system(cable_dmi_table))
+               return 1;
+
+       return 0;
+}
+
 /**
  *     ata66_ali15x3   -       check for UDMA 66 support
  *     @hwif: IDE interface
@@ -594,37 +625,31 @@ out:
  *     FIXME: frobs bits that are not defined on newer ALi devicea
  */
 
-static unsigned int __devinit ata66_ali15x3 (ide_hwif_t *hwif)
+static u8 __devinit ata66_ali15x3(ide_hwif_t *hwif)
 {
        struct pci_dev *dev     = hwif->pci_dev;
-       unsigned int ata66      = 0;
-       u8 cable_80_pin[2]      = { 0, 0 };
-
        unsigned long flags;
-       u8 tmpbyte;
+       u8 cbl = ATA_CBL_PATA40, tmpbyte;
 
        local_irq_save(flags);
 
        if (m5229_revision >= 0xC2) {
                /*
-                * Ultra66 cable detection (from Host View)
-                * m5229, 0x4a, bit0: primary, bit1: secondary 80 pin
-                */
-               pci_read_config_byte(dev, 0x4a, &tmpbyte);
-               /*
-                * 0x4a, bit0 is 0 => primary channel
-                * has 80-pin (from host view)
-                */
-               if (!(tmpbyte & 0x01)) cable_80_pin[0] = 1;
-               /*
-                * 0x4a, bit1 is 0 => secondary channel
-                * has 80-pin (from host view)
-                */
-               if (!(tmpbyte & 0x02)) cable_80_pin[1] = 1;
-               /*
-                * Allow ata66 if cable of current channel has 80 pins
+                * m5229 80-pin cable detection (from Host View)
+                *
+                * 0x4a bit0 is 0 => primary channel has 80-pin
+                * 0x4a bit1 is 0 => secondary channel has 80-pin
+                *
+                * Certain laptops use short but suitable cables
+                * and don't implement the detect logic.
                 */
-               ata66 = (hwif->channel)?cable_80_pin[1]:cable_80_pin[0];
+               if (ali_cable_override(dev))
+                       cbl = ATA_CBL_PATA40_SHORT;
+               else {
+                       pci_read_config_byte(dev, 0x4a, &tmpbyte);
+                       if ((tmpbyte & (1 << hwif->channel)) == 0)
+                               cbl = ATA_CBL_PATA80;
+               }
        } else {
                /*
                 * check m1533, 0x5e, bit 1~4 == 1001 => & 00011110 = 00010010
@@ -657,7 +682,7 @@ static unsigned int __devinit ata66_ali15x3 (ide_hwif_t *hwif)
 
        local_irq_restore(flags);
 
-       return(ata66);
+       return cbl;
 }
 
 /**
@@ -708,8 +733,9 @@ static void __devinit init_hwif_common_ali15x3 (ide_hwif_t *hwif)
                hwif->dma_setup = &ali15x3_dma_setup;
                if (!noautodma)
                        hwif->autodma = 1;
-               if (!(hwif->udma_four))
-                       hwif->udma_four = ata66_ali15x3(hwif);
+
+               if (hwif->cbl != ATA_CBL_PATA40_SHORT)
+                       hwif->cbl = ata66_ali15x3(hwif);
        }
        hwif->drives[0].autodma = hwif->autodma;
        hwif->drives[1].autodma = hwif->autodma;
index a2be65fcf89c6f45aed44cfbccd83471a543b814..8d30b99a54d8cca8e9db1aad2cb719a16f3a6916 100644 (file)
@@ -1,10 +1,11 @@
 /*
- * Version 2.16
+ * Version 2.20
  *
  * AMD 755/756/766/8111 and nVidia nForce/2/2s/3/3s/CK804/MCP04
  * IDE driver for Linux.
  *
  * Copyright (c) 2000-2002 Vojtech Pavlik
+ * Copyright (c) 2007 Bartlomiej Zolnierkiewicz
  *
  * Based on the work of:
  *      Andre Hedrick
 #define AMD_ADDRESS_SETUP      (0x0c + amd_config->base)
 #define AMD_UDMA_TIMING                (0x10 + amd_config->base)
 
-#define AMD_UDMA               0x07
-#define AMD_UDMA_33            0x01
-#define AMD_UDMA_66            0x02
-#define AMD_UDMA_100           0x03
-#define AMD_UDMA_133           0x04
 #define AMD_CHECK_SWDMA                0x08
 #define AMD_BAD_SWDMA          0x10
 #define AMD_BAD_FIFO           0x20
 
 static struct amd_ide_chip {
        unsigned short id;
-       unsigned long base;
-       unsigned char flags;
+       u8 base;
+       u8 udma_mask;
+       u8 flags;
 } amd_ide_chips[] = {
-       { PCI_DEVICE_ID_AMD_COBRA_7401,         0x40, AMD_UDMA_33 | AMD_BAD_SWDMA },
-       { PCI_DEVICE_ID_AMD_VIPER_7409,         0x40, AMD_UDMA_66 | AMD_CHECK_SWDMA },
-       { PCI_DEVICE_ID_AMD_VIPER_7411,         0x40, AMD_UDMA_100 | AMD_BAD_FIFO },
-       { PCI_DEVICE_ID_AMD_OPUS_7441,          0x40, AMD_UDMA_100 },
-       { PCI_DEVICE_ID_AMD_8111_IDE,           0x40, AMD_UDMA_133 | AMD_CHECK_SERENADE },
-       { PCI_DEVICE_ID_NVIDIA_NFORCE_IDE,      0x50, AMD_UDMA_100 },
-       { PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE,     0x50, AMD_UDMA_133 },
-       { PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE,    0x50, AMD_UDMA_133 },
-       { PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA,   0x50, AMD_UDMA_133 },
-       { PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE,     0x50, AMD_UDMA_133 },
-       { PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE,    0x50, AMD_UDMA_133 },
-       { PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA,   0x50, AMD_UDMA_133 },
-       { PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2,  0x50, AMD_UDMA_133 },
-       { PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE,        0x50, AMD_UDMA_133 },
-       { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE,        0x50, AMD_UDMA_133 },
-       { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE,        0x50, AMD_UDMA_133 },
-       { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE,        0x50, AMD_UDMA_133 },
-       { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE,        0x50, AMD_UDMA_133 },
-       { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE,        0x50, AMD_UDMA_133 },
-       { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE,        0x50, AMD_UDMA_133 },
-       { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_IDE,        0x50, AMD_UDMA_133 },
-       { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE,        0x50, AMD_UDMA_133 },
-       { PCI_DEVICE_ID_AMD_CS5536_IDE,                 0x40, AMD_UDMA_100 },
+       { PCI_DEVICE_ID_AMD_COBRA_7401,          0x40, ATA_UDMA2, AMD_BAD_SWDMA },
+       { PCI_DEVICE_ID_AMD_VIPER_7409,          0x40, ATA_UDMA4, AMD_CHECK_SWDMA },
+       { PCI_DEVICE_ID_AMD_VIPER_7411,          0x40, ATA_UDMA5, AMD_BAD_FIFO },
+       { PCI_DEVICE_ID_AMD_OPUS_7441,           0x40, ATA_UDMA5, },
+       { PCI_DEVICE_ID_AMD_8111_IDE,            0x40, ATA_UDMA6, AMD_CHECK_SERENADE },
+       { PCI_DEVICE_ID_NVIDIA_NFORCE_IDE,       0x50, ATA_UDMA5, },
+       { PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE,      0x50, ATA_UDMA6, },
+       { PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE,     0x50, ATA_UDMA6, },
+       { PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA,    0x50, ATA_UDMA6, },
+       { PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE,      0x50, ATA_UDMA6, },
+       { PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE,     0x50, ATA_UDMA6, },
+       { PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA,    0x50, ATA_UDMA6, },
+       { PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2,   0x50, ATA_UDMA6, },
+       { PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE, 0x50, ATA_UDMA6, },
+       { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, 0x50, ATA_UDMA6, },
+       { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, 0x50, ATA_UDMA6, },
+       { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, 0x50, ATA_UDMA6, },
+       { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE, 0x50, ATA_UDMA6, },
+       { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE, 0x50, ATA_UDMA6, },
+       { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE, 0x50, ATA_UDMA6, },
+       { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_IDE, 0x50, ATA_UDMA6, },
+       { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE, 0x50, ATA_UDMA6, },
+       { PCI_DEVICE_ID_AMD_CS5536_IDE,          0x40, ATA_UDMA5, },
        { 0 }
 };
 
@@ -87,7 +84,7 @@ static ide_pci_device_t *amd_chipset;
 static unsigned int amd_80w;
 static unsigned int amd_clock;
 
-static char *amd_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" };
+static char *amd_dma[] = { "16", "25", "33", "44", "66", "100", "133" };
 static unsigned char amd_cyc2udma[] = { 6, 6, 5, 4, 0, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 7 };
 
 /*
@@ -126,9 +123,8 @@ static int amd74xx_get_info(char *buffer, char **addr, off_t offset, int count)
        amd_print("Driver Version:                     2.13");
        amd_print("South Bridge:                       %s", pci_name(bmide_dev));
 
-       pci_read_config_byte(dev, PCI_REVISION_ID, &t);
-       amd_print("Revision:                           IDE %#x", t);
-       amd_print("Highest DMA rate:                   %s", amd_dma[amd_config->flags & AMD_UDMA]);
+       amd_print("Revision:                           IDE %#x", dev->revision);
+       amd_print("Highest DMA rate:                   UDMA%s", amd_dma[fls(amd_config->udma_mask) - 1]);
 
        amd_print("BM-DMA base:                        %#lx", amd_base);
        amd_print("PCI clock:                          %d.%dMHz", amd_clock / 1000, amd_clock / 100 % 10);
@@ -221,12 +217,12 @@ static void amd_set_speed(struct pci_dev *dev, unsigned char dn, struct ide_timi
        pci_write_config_byte(dev, AMD_DRIVE_TIMING + (3 - dn),
                ((FIT(timing->active, 1, 16) - 1) << 4) | (FIT(timing->recover, 1, 16) - 1));
 
-       switch (amd_config->flags & AMD_UDMA) {
-               case AMD_UDMA_33:  t = timing->udma ? (0xc0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break;
-               case AMD_UDMA_66:  t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 2, 10)]) : 0x03; break;
-               case AMD_UDMA_100: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 1, 10)]) : 0x03; break;
-               case AMD_UDMA_133: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 1, 15)]) : 0x03; break;
-               default: return;
+       switch (amd_config->udma_mask) {
+       case ATA_UDMA2: t = timing->udma ? (0xc0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break;
+       case ATA_UDMA4: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 2, 10)]) : 0x03; break;
+       case ATA_UDMA5: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 1, 10)]) : 0x03; break;
+       case ATA_UDMA6: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 1, 15)]) : 0x03; break;
+       default: return;
        }
 
        pci_write_config_byte(dev, AMD_UDMA_TIMING + (3 - dn), t);
@@ -248,7 +244,7 @@ static int amd_set_drive(ide_drive_t *drive, u8 speed)
                ide_config_drive_speed(drive, speed);
 
        T = 1000000000 / amd_clock;
-       UT = T / min_t(int, max_t(int, amd_config->flags & AMD_UDMA, 1), 2);
+       UT = (amd_config->udma_mask == ATA_UDMA2) ? T : (T / 2);
 
        ide_timing_compute(drive, speed, &t, T, UT);
 
@@ -277,29 +273,19 @@ static int amd_set_drive(ide_drive_t *drive, u8 speed)
 static void amd74xx_tune_drive(ide_drive_t *drive, u8 pio)
 {
        if (pio == 255) {
-               amd_set_drive(drive, ide_find_best_mode(drive, XFER_PIO | XFER_EPIO));
+               amd_set_drive(drive, ide_find_best_pio_mode(drive));
                return;
        }
 
        amd_set_drive(drive, XFER_PIO_0 + min_t(byte, pio, 5));
 }
 
-/*
- * amd74xx_dmaproc() is a callback from upper layers that can do
- * a lot, but we use it for DMA/PIO tuning only, delegating everything
- * else to the default ide_dmaproc().
- */
-
 static int amd74xx_ide_dma_check(ide_drive_t *drive)
 {
-       int w80 = HWIF(drive)->udma_four;
+       u8 speed = ide_max_dma_mode(drive);
 
-       u8 speed = ide_find_best_mode(drive,
-               XFER_PIO | XFER_EPIO | XFER_MWDMA | XFER_UDMA |
-               ((amd_config->flags & AMD_BAD_SWDMA) ? 0 : XFER_SWDMA) |
-               (w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_66 ? XFER_UDMA_66 : 0) |
-               (w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_100 ? XFER_UDMA_100 : 0) |
-               (w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_133 ? XFER_UDMA_133 : 0));
+       if (speed == 0)
+               speed = ide_find_best_pio_mode(drive);
 
        amd_set_drive(drive, speed);
 
@@ -325,8 +311,7 @@ static unsigned int __devinit init_chipset_amd74xx(struct pci_dev *dev, const ch
  */
 
        if (amd_config->flags & AMD_CHECK_SWDMA) {
-               pci_read_config_byte(dev, PCI_REVISION_ID, &t);
-               if (t <= 7)
+               if (dev->revision <= 7)
                        amd_config->flags |= AMD_BAD_SWDMA;
        }
 
@@ -334,10 +319,10 @@ static unsigned int __devinit init_chipset_amd74xx(struct pci_dev *dev, const ch
  * Check 80-wire cable presence.
  */
 
-       switch (amd_config->flags & AMD_UDMA) {
+       switch (amd_config->udma_mask) {
 
-               case AMD_UDMA_133:
-               case AMD_UDMA_100:
+               case ATA_UDMA6:
+               case ATA_UDMA5:
                        pci_read_config_byte(dev, AMD_CABLE_DETECT, &t);
                        pci_read_config_dword(dev, AMD_UDMA_TIMING, &u);
                        amd_80w = ((t & 0x3) ? 1 : 0) | ((t & 0xc) ? 2 : 0);
@@ -349,7 +334,7 @@ static unsigned int __devinit init_chipset_amd74xx(struct pci_dev *dev, const ch
                                }
                        break;
 
-               case AMD_UDMA_66:
+               case ATA_UDMA4:
                        /* no host side cable detection */
                        amd_80w = 0x03;
                        break;
@@ -370,7 +355,7 @@ static unsigned int __devinit init_chipset_amd74xx(struct pci_dev *dev, const ch
        if ((amd_config->flags & AMD_CHECK_SERENADE) &&
                dev->subsystem_vendor == PCI_VENDOR_ID_AMD &&
                dev->subsystem_device == PCI_DEVICE_ID_AMD_SERENADE)
-                       amd_config->flags = AMD_UDMA_100;
+                       amd_config->udma_mask = ATA_UDMA5;
 
 /*
  * Determine the system bus clock.
@@ -395,8 +380,9 @@ static unsigned int __devinit init_chipset_amd74xx(struct pci_dev *dev, const ch
  */
 
        pci_read_config_byte(dev, PCI_REVISION_ID, &t);
-       printk(KERN_INFO "%s: %s (rev %02x) %s controller\n",
-               amd_chipset->name, pci_name(dev), t, amd_dma[amd_config->flags & AMD_UDMA]);
+       printk(KERN_INFO "%s: %s (rev %02x) UDMA%s controller\n",
+               amd_chipset->name, pci_name(dev), dev->revision,
+               amd_dma[fls(amd_config->udma_mask) - 1]);
 
 /*
  * Register /proc/ide/amd74xx entry
@@ -437,12 +423,19 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
                return;
 
         hwif->atapi_dma = 1;
-        hwif->ultra_mask = 0x7f;
-        hwif->mwdma_mask = 0x07;
-        hwif->swdma_mask = 0x07;
 
-       if (!hwif->udma_four)
-               hwif->udma_four = (amd_80w >> hwif->channel) & 1;
+       hwif->ultra_mask = amd_config->udma_mask;
+       hwif->mwdma_mask = 0x07;
+       if ((amd_config->flags & AMD_BAD_SWDMA) == 0)
+               hwif->swdma_mask = 0x07;
+
+       if (hwif->cbl != ATA_CBL_PATA40_SHORT) {
+               if ((amd_80w >> hwif->channel) & 1)
+                       hwif->cbl = ATA_CBL_PATA80;
+               else
+                       hwif->cbl = ATA_CBL_PATA40;
+       }
+
         hwif->ide_dma_check = &amd74xx_ide_dma_check;
         if (!noautodma)
                 hwif->autodma = 1;
index 8ab33faf6f76776d860d1b2db3ce72834937f369..2761510309b381a17de6dd8078262d104191de33 100644 (file)
@@ -264,10 +264,11 @@ static void __devinit init_hwif_atiixp(ide_hwif_t *hwif)
        hwif->swdma_mask = 0x04;
 
        pci_read_config_byte(pdev, ATIIXP_IDE_UDMA_MODE + ch, &udma_mode);
+
        if ((udma_mode & 0x07) >= 0x04 || (udma_mode & 0x70) >= 0x40)
-               hwif->udma_four = 1;
+               hwif->cbl = ATA_CBL_PATA80;
        else
-               hwif->udma_four = 0;
+               hwif->cbl = ATA_CBL_PATA40;
 
        hwif->dma_host_on = &atiixp_dma_host_on;
        hwif->dma_host_off = &atiixp_dma_host_off;
index 7c57dc696f5206d9b4d4f26e0d185e874f2fd1a3..1e89dd6e5bbf9e0eb45d27132f89ba6d4805d776 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/ide/pci/cmd64x.c              Version 1.47    Mar 19, 2007
+ * linux/drivers/ide/pci/cmd64x.c              Version 1.50    May 10, 2007
  *
  * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines.
  *           Due to massive hardware bugs, UltraDMA is only supported
@@ -52,9 +52,6 @@
 #define   ARTTIM23_DIS_RA2     0x04
 #define   ARTTIM23_DIS_RA3     0x08
 #define   ARTTIM23_INTR_CH1    0x10
-#define ARTTIM2                0x57
-#define ARTTIM3                0x57
-#define DRWTIM23       0x58
 #define DRWTIM2                0x58
 #define BRST           0x59
 #define DRWTIM3                0x5b
@@ -91,7 +88,6 @@ static char * print_cmd64x_get_info (char *buf, struct pci_dev *dev, int index)
        u8 reg72 = 0, reg73 = 0;                        /* primary */
        u8 reg7a = 0, reg7b = 0;                        /* secondary */
        u8 reg50 = 1, reg51 = 1, reg57 = 0, reg71 = 0;  /* extra */
-       u8 rev = 0;
 
        p += sprintf(p, "\nController: %d\n", index);
        p += sprintf(p, "PCI-%x Chipset.\n", dev->device);
@@ -106,9 +102,8 @@ static char * print_cmd64x_get_info (char *buf, struct pci_dev *dev, int index)
        (void) pci_read_config_byte(dev, UDIDETCR1, &reg7b);
 
        /* PCI0643/6 originally didn't have the primary channel enable bit */
-       (void) pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
        if ((dev->device == PCI_DEVICE_ID_CMD_643) ||
-           (dev->device == PCI_DEVICE_ID_CMD_646 && rev < 3))
+           (dev->device == PCI_DEVICE_ID_CMD_646 && dev->revision < 3))
                reg51 |= CNTRL_ENA_1ST;
 
        p += sprintf(p, "---------------- Primary Channel "
@@ -469,71 +464,43 @@ static int cmd646_1_ide_dma_end (ide_drive_t *drive)
 
 static unsigned int __devinit init_chipset_cmd64x(struct pci_dev *dev, const char *name)
 {
-       u32 class_rev = 0;
        u8 mrdmode = 0;
 
-       pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
-       class_rev &= 0xff;
+       if (dev->device == PCI_DEVICE_ID_CMD_646) {
+               u8 rev = 0;
 
-       switch(dev->device) {
-               case PCI_DEVICE_ID_CMD_643:
-                       break;
-               case PCI_DEVICE_ID_CMD_646:
-                       printk(KERN_INFO "%s: chipset revision 0x%02X, ", name, class_rev);
-                       switch(class_rev) {
-                               case 0x07:
-                               case 0x05:
-                                       printk("UltraDMA Capable");
-                                       break;
-                               case 0x03:
-                                       printk("MultiWord DMA Force Limited");
-                                       break;
-                               case 0x01:
-                               default:
-                                       printk("MultiWord DMA Limited, IRQ workaround enabled");
-                                       break;
-                               }
-                       printk("\n");
-                        break;
-               case PCI_DEVICE_ID_CMD_648:
-               case PCI_DEVICE_ID_CMD_649:
+               pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
+
+               switch (rev) {
+               case 0x07:
+               case 0x05:
+                       printk("%s: UltraDMA capable", name);
                        break;
+               case 0x03:
                default:
+                       printk("%s: MultiWord DMA force limited", name);
+                       break;
+               case 0x01:
+                       printk("%s: MultiWord DMA limited, "
+                              "IRQ workaround enabled\n", name);
                        break;
+               }
        }
 
        /* Set a good latency timer and cache line size value. */
        (void) pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
        /* FIXME: pci_set_master() to ensure a good latency timer value */
 
-       /* Setup interrupts. */
-       (void) pci_read_config_byte(dev, MRDMODE, &mrdmode);
-       mrdmode &= ~(0x30);
-       (void) pci_write_config_byte(dev, MRDMODE, mrdmode);
-
-       /* Use MEMORY READ LINE for reads.
-        * NOTE: Although not mentioned in the PCI0646U specs,
-        *       these bits are write only and won't be read
-        *       back as set or not.  The PCI0646U2 specs clarify
-        *       this point.
+       /*
+        * Enable interrupts, select MEMORY READ LINE for reads.
+        *
+        * NOTE: although not mentioned in the PCI0646U specs,
+        * bits 0-1 are write only and won't be read back as
+        * set or not -- PCI0646U2 specs clarify this point.
         */
-       (void) pci_write_config_byte(dev, MRDMODE, mrdmode | 0x02);
-
-       /* Set reasonable active/recovery/address-setup values. */
-       (void) pci_write_config_byte(dev, ARTTIM0,  0x40);
-       (void) pci_write_config_byte(dev, DRWTIM0,  0x3f);
-       (void) pci_write_config_byte(dev, ARTTIM1,  0x40);
-       (void) pci_write_config_byte(dev, DRWTIM1,  0x3f);
-#ifdef __i386__
-       (void) pci_write_config_byte(dev, ARTTIM23, 0x1c);
-#else
-       (void) pci_write_config_byte(dev, ARTTIM23, 0x5c);
-#endif
-       (void) pci_write_config_byte(dev, DRWTIM23, 0x3f);
-       (void) pci_write_config_byte(dev, DRWTIM3,  0x3f);
-#ifdef CONFIG_PPC
-       (void) pci_write_config_byte(dev, UDIDETCR0, 0xf0);
-#endif /* CONFIG_PPC */
+       (void) pci_read_config_byte (dev, MRDMODE, &mrdmode);
+       mrdmode &= ~0x30;
+       (void) pci_write_config_byte(dev, MRDMODE, (mrdmode | 0x02));
 
 #if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_IDE_PROC_FS)
 
@@ -548,29 +515,27 @@ static unsigned int __devinit init_chipset_cmd64x(struct pci_dev *dev, const cha
        return 0;
 }
 
-static unsigned int __devinit ata66_cmd64x(ide_hwif_t *hwif)
+static u8 __devinit ata66_cmd64x(ide_hwif_t *hwif)
 {
-       u8 ata66 = 0, mask = (hwif->channel) ? 0x02 : 0x01;
+       struct pci_dev  *dev    = hwif->pci_dev;
+       u8 bmidecsr = 0, mask   = hwif->channel ? 0x02 : 0x01;
 
-       switch(hwif->pci_dev->device) {
-               case PCI_DEVICE_ID_CMD_643:
-               case PCI_DEVICE_ID_CMD_646:
-                       return ata66;
-               default:
-                       break;
+       switch (dev->device) {
+       case PCI_DEVICE_ID_CMD_648:
+       case PCI_DEVICE_ID_CMD_649:
+               pci_read_config_byte(dev, BMIDECSR, &bmidecsr);
+               return (bmidecsr & mask) ? ATA_CBL_PATA80 : ATA_CBL_PATA40;
+       default:
+               return ATA_CBL_PATA40;
        }
-       pci_read_config_byte(hwif->pci_dev, BMIDECSR, &ata66);
-       return (ata66 & mask) ? 1 : 0;
 }
 
 static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif)
 {
        struct pci_dev *dev     = hwif->pci_dev;
-       unsigned int class_rev;
+       u8 rev                  = 0;
 
-       hwif->autodma = 0;
-       pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
-       class_rev &= 0xff;
+       pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
 
        hwif->tuneproc  = &cmd64x_tune_drive;
        hwif->speedproc = &cmd64x_tune_chipset;
@@ -580,8 +545,8 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif)
        if (!hwif->dma_base)
                return;
 
-       hwif->atapi_dma = 1;
-
+       hwif->atapi_dma  = 1;
+       hwif->mwdma_mask = 0x07;
        hwif->ultra_mask = hwif->cds->udma_mask;
 
        /*
@@ -596,16 +561,15 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif)
         *
         * So we only do UltraDMA on revision 0x05 and 0x07 chipsets.
         */
-       if (dev->device == PCI_DEVICE_ID_CMD_646 && class_rev < 5)
+       if (dev->device == PCI_DEVICE_ID_CMD_646 && rev < 5)
                hwif->ultra_mask = 0x00;
 
-       hwif->mwdma_mask = 0x07;
-
        hwif->ide_dma_check = &cmd64x_config_drive_for_dma;
-       if (!(hwif->udma_four))
-               hwif->udma_four = ata66_cmd64x(hwif);
 
-       switch(dev->device) {
+       if (hwif->cbl != ATA_CBL_PATA40_SHORT)
+               hwif->cbl = ata66_cmd64x(hwif);
+
+       switch (dev->device) {
        case PCI_DEVICE_ID_CMD_648:
        case PCI_DEVICE_ID_CMD_649:
        alt_irq_bits:
@@ -614,10 +578,10 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif)
                break;
        case PCI_DEVICE_ID_CMD_646:
                hwif->chipset = ide_cmd646;
-               if (class_rev == 0x01) {
+               if (rev == 0x01) {
                        hwif->ide_dma_end = &cmd646_1_ide_dma_end;
                        break;
-               } else if (class_rev >= 0x03)
+               } else if (rev >= 0x03)
                        goto alt_irq_bits;
                /* fall thru */
        default:
@@ -626,11 +590,9 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif)
                break;
        }
 
-
        if (!noautodma)
                hwif->autodma = 1;
-       hwif->drives[0].autodma = hwif->autodma;
-       hwif->drives[1].autodma = hwif->autodma;
+       hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma;
 }
 
 static int __devinit init_setup_cmd64x(struct pci_dev *dev, ide_pci_device_t *d)
@@ -640,14 +602,11 @@ static int __devinit init_setup_cmd64x(struct pci_dev *dev, ide_pci_device_t *d)
 
 static int __devinit init_setup_cmd646(struct pci_dev *dev, ide_pci_device_t *d)
 {
-       u8 rev = 0;
-
        /*
         * The original PCI0646 didn't have the primary channel enable bit,
         * it appeared starting with PCI0646U (i.e. revision ID 3).
         */
-       pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
-       if (rev < 3)
+       if (dev->revision < 3)
                d->enablebits[0].reg = 0;
 
        return ide_setup_pci_device(dev, d);
index 1eec1f308d16f26955deb92a71588dd079cbd194..b5c00d15a70403ffdbc829c71d3b0ff4137c0d9b 100644 (file)
@@ -236,7 +236,7 @@ static unsigned int __devinit init_chipset_cs5530 (struct pci_dev *dev, const ch
         */
 
        pci_set_master(cs5530_0);
-       pci_set_mwi(cs5530_0);
+       pci_try_set_mwi(cs5530_0);
 
        /*
         * Set PCI CacheLineSize to 16-bytes:
index 41925c47ef05968d484107b34b7c22b1e53373c4..10f61f38243cbc6242ee1b33c2634b1cdca6a8e1 100644 (file)
@@ -187,7 +187,8 @@ static u8 __devinit cs5535_cable_detect(struct pci_dev *dev)
 
        /* if a 80 wire cable was detected */
        pci_read_config_byte(dev, CS5535_CABLE_DETECT, &bit);
-       return (bit & 1);
+
+       return (bit & 1) ? ATA_CBL_PATA80 : ATA_CBL_PATA40;
 }
 
 /****
@@ -212,8 +213,7 @@ static void __devinit init_hwif_cs5535(ide_hwif_t *hwif)
        hwif->ultra_mask = 0x1F;
        hwif->mwdma_mask = 0x07;
 
-
-       hwif->udma_four = cs5535_cable_detect(hwif->pci_dev);
+       hwif->cbl = cs5535_cable_detect(hwif->pci_dev);
 
        if (!noautodma)
                hwif->autodma = 1;
index c33d0b0f11c91896eb498bb1a5f030ad7ce6b51b..e9b07a97c3408d1da2ac7cca57e268ed4173f3a6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/ide/pci/hpt366.c              Version 1.06    Jun 27, 2007
+ * linux/drivers/ide/pci/hpt366.c              Version 1.10    Jun 29, 2007
  *
  * Copyright (C) 1999-2003             Andre Hedrick <andre@linux-ide.org>
  * Portions Copyright (C) 2001         Sun Microsystems, Inc.
@@ -77,7 +77,7 @@
  *   since they may tamper with its fields
  * - prefix the driver startup messages with the real chip name
  * - claim the extra 240 bytes of I/O space for all chips
- * - optimize the rate masking/filtering and the drive list lookup code
+ * - optimize the UltraDMA filtering and the drive list lookup code
  * - use pci_get_slot() to get to the function 1 of HPT36x/374
  * - cache offset of the channel's misc. control registers (MCRs) being used
  *   throughout the driver
@@ -99,9 +99,9 @@
  *   stop duplicating it for each channel by storing the pointer in the pci_dev
  *   structure: first, at the init_setup stage, point it to a static "template"
  *   with only the chip type and its specific base DPLL frequency, the highest
- *   supported DMA mode, and the chip settings table pointer filled, then, at
- *   the init_chipset stage, allocate per-chip instance  and fill it with the
- *   rest of the necessary information
+ *   UltraDMA mode, and the chip settings table pointer filled,  then, at the
+ *   init_chipset stage, allocate per-chip instance  and fill it with the rest
+ *   of the necessary information
  * - get rid of the constant thresholds in the HPT37x PCI clock detection code,
  *   switch  to calculating  PCI clock frequency based on the chip's base DPLL
  *   frequency
  *   also fixing the interchanged 25/40 MHz PCI clock cases for HPT36x chips;
  *   unify HPT36x/37x timing setup code and the speedproc handlers by joining
  *   the register setting lists into the table indexed by the clock selected
+ * - set the correct hwif->ultra_mask for each individual chip
  *     Sergei Shtylyov, <sshtylyov@ru.mvista.com> or <source@mvista.com>
  */
 
@@ -391,7 +392,7 @@ enum ata_clock {
 
 struct hpt_info {
        u8 chip_type;           /* Chip type */
-       u8 max_mode;            /* Speeds allowed */
+       u8 max_ultra;           /* Max. UltraDMA mode allowed */
        u8 dpll_clk;            /* DPLL clock in MHz */
        u8 pci_clk;             /* PCI  clock in MHz */
        u32 **settings;         /* Chipset settings table */
@@ -430,77 +431,77 @@ static u32 *hpt37x_settings[NUM_ATA_CLOCKS] = {
 
 static struct hpt_info hpt36x __devinitdata = {
        .chip_type      = HPT36x,
-       .max_mode       = (HPT366_ALLOW_ATA66_4 || HPT366_ALLOW_ATA66_3) ? 2 : 1,
+       .max_ultra      = HPT366_ALLOW_ATA66_3 ? (HPT366_ALLOW_ATA66_4 ? 4 : 3) : 2,
        .dpll_clk       = 0,    /* no DPLL */
        .settings       = hpt36x_settings
 };
 
 static struct hpt_info hpt370 __devinitdata = {
        .chip_type      = HPT370,
-       .max_mode       = HPT370_ALLOW_ATA100_5 ? 3 : 2,
+       .max_ultra      = HPT370_ALLOW_ATA100_5 ? 5 : 4,
        .dpll_clk       = 48,
        .settings       = hpt37x_settings
 };
 
 static struct hpt_info hpt370a __devinitdata = {
        .chip_type      = HPT370A,
-       .max_mode       = HPT370_ALLOW_ATA100_5 ? 3 : 2,
+       .max_ultra      = HPT370_ALLOW_ATA100_5 ? 5 : 4,
        .dpll_clk       = 48,
        .settings       = hpt37x_settings
 };
 
 static struct hpt_info hpt374 __devinitdata = {
        .chip_type      = HPT374,
-       .max_mode       = 3,
+       .max_ultra      = 5,
        .dpll_clk       = 48,
        .settings       = hpt37x_settings
 };
 
 static struct hpt_info hpt372 __devinitdata = {
        .chip_type      = HPT372,
-       .max_mode       = HPT372_ALLOW_ATA133_6 ? 4 : 3,
+       .max_ultra      = HPT372_ALLOW_ATA133_6 ? 6 : 5,
        .dpll_clk       = 55,
        .settings       = hpt37x_settings
 };
 
 static struct hpt_info hpt372a __devinitdata = {
        .chip_type      = HPT372A,
-       .max_mode       = HPT372_ALLOW_ATA133_6 ? 4 : 3,
+       .max_ultra      = HPT372_ALLOW_ATA133_6 ? 6 : 5,
        .dpll_clk       = 66,
        .settings       = hpt37x_settings
 };
 
 static struct hpt_info hpt302 __devinitdata = {
        .chip_type      = HPT302,
-       .max_mode       = HPT302_ALLOW_ATA133_6 ? 4 : 3,
+       .max_ultra      = HPT372_ALLOW_ATA133_6 ? 6 : 5,
        .dpll_clk       = 66,
        .settings       = hpt37x_settings
 };
 
 static struct hpt_info hpt371 __devinitdata = {
        .chip_type      = HPT371,
-       .max_mode       = HPT371_ALLOW_ATA133_6 ? 4 : 3,
+       .max_ultra      = HPT371_ALLOW_ATA133_6 ? 6 : 5,
        .dpll_clk       = 66,
        .settings       = hpt37x_settings
 };
 
 static struct hpt_info hpt372n __devinitdata = {
        .chip_type      = HPT372N,
-       .max_mode       = HPT372_ALLOW_ATA133_6 ? 4 : 3,
+       .max_ultra      = HPT372_ALLOW_ATA133_6 ? 6 : 5,
        .dpll_clk       = 77,
        .settings       = hpt37x_settings
 };
 
 static struct hpt_info hpt302n __devinitdata = {
        .chip_type      = HPT302N,
-       .max_mode       = HPT302_ALLOW_ATA133_6 ? 4 : 3,
+       .max_ultra      = HPT302_ALLOW_ATA133_6 ? 6 : 5,
        .dpll_clk       = 77,
        .settings       = hpt37x_settings
 };
 
 static struct hpt_info hpt371n __devinitdata = {
        .chip_type      = HPT371N,
-       .max_mode       = HPT371_ALLOW_ATA133_6 ? 4 : 3,
+       .max_ultra      = HPT371_ALLOW_ATA133_6 ? 6 : 5,
        .dpll_clk       = 77,
        .settings       = hpt37x_settings
 };
@@ -523,53 +524,38 @@ static int check_in_drive_list(ide_drive_t *drive, const char **list)
 static u8 hpt3xx_udma_filter(ide_drive_t *drive)
 {
        struct hpt_info *info   = pci_get_drvdata(HWIF(drive)->pci_dev);
-       u8 chip_type            = info->chip_type;
-       u8 mode                 = info->max_mode;
        u8 mask;
 
-       switch (mode) {
-               case 0x04:
-                       mask = 0x7f;
-                       break;
-               case 0x03:
+       switch (info->chip_type) {
+       case HPT370A:
+               if (!HPT370_ALLOW_ATA100_5 ||
+                   check_in_drive_list(drive, bad_ata100_5))
+                       return 0x1f;
+               else
+                       return 0x3f;
+       case HPT370:
+               if (!HPT370_ALLOW_ATA100_5 ||
+                   check_in_drive_list(drive, bad_ata100_5))
+                       mask = 0x1f;
+               else
                        mask = 0x3f;
-                       if (chip_type >= HPT374)
-                               break;
-                       if (!check_in_drive_list(drive, bad_ata100_5))
-                               goto check_bad_ata33;
-                       /* fall thru */
-               case 0x02:
+               break;
+       case HPT36x:
+               if (!HPT366_ALLOW_ATA66_4 ||
+                   check_in_drive_list(drive, bad_ata66_4))
+                       mask = 0x0f;
+               else
                        mask = 0x1f;
 
-                       /*
-                        * CHECK ME, Does this need to be changed to HPT374 ??
-                        */
-                       if (chip_type >= HPT370)
-                               goto check_bad_ata33;
-                       if (HPT366_ALLOW_ATA66_4 &&
-                           !check_in_drive_list(drive, bad_ata66_4))
-                               goto check_bad_ata33;
-
-                       mask = 0x0f;
-                       if (HPT366_ALLOW_ATA66_3 &&
-                           !check_in_drive_list(drive, bad_ata66_3))
-                               goto check_bad_ata33;
-                       /* fall thru */
-               case 0x01:
+               if (!HPT366_ALLOW_ATA66_3 ||
+                   check_in_drive_list(drive, bad_ata66_3))
                        mask = 0x07;
-
-               check_bad_ata33:
-                       if (chip_type >= HPT370A)
-                               break;
-                       if (!check_in_drive_list(drive, bad_ata33))
-                               break;
-                       /* fall thru */
-               case 0x00:
-               default:
-                       mask = 0x00;
-                       break;
+               break;
+       default:
+               return 0x7f;
        }
-       return mask;
+
+       return check_in_drive_list(drive, bad_ata33) ? 0x00 : mask;
 }
 
 static u32 get_speed_setting(u8 speed, struct hpt_info *info)
@@ -737,7 +723,7 @@ static int hpt366_config_drive_xfer_rate(ide_drive_t *drive)
  * This is specific to the HPT366 UDMA chipset
  * by HighPoint|Triones Technologies, Inc.
  */
-static int hpt366_ide_dma_lostirq(ide_drive_t *drive)
+static void hpt366_dma_lost_irq(ide_drive_t *drive)
 {
        struct pci_dev *dev = HWIF(drive)->pci_dev;
        u8 mcr1 = 0, mcr3 = 0, scr1 = 0;
@@ -749,7 +735,7 @@ static int hpt366_ide_dma_lostirq(ide_drive_t *drive)
                drive->name, __FUNCTION__, mcr1, mcr3, scr1);
        if (scr1 & 0x10)
                pci_write_config_byte(dev, 0x5a, scr1 & ~0x10);
-       return __ide_dma_lostirq(drive);
+       ide_dma_lost_irq(drive);
 }
 
 static void hpt370_clear_engine(ide_drive_t *drive)
@@ -799,10 +785,10 @@ static int hpt370_ide_dma_end(ide_drive_t *drive)
        return __ide_dma_end(drive);
 }
 
-static int hpt370_ide_dma_timeout(ide_drive_t *drive)
+static void hpt370_dma_timeout(ide_drive_t *drive)
 {
        hpt370_irq_timeout(drive);
-       return __ide_dma_timeout(drive);
+       ide_dma_timeout(drive);
 }
 
 /* returns 1 if DMA IRQ issued, 0 otherwise */
@@ -1150,7 +1136,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha
                  * Select 66 MHz DPLL clock only if UltraATA/133 mode is
                  * supported/enabled, use 50 MHz DPLL clock otherwise...
                  */
-               if (info->max_mode == 0x04) {
+               if (info->max_ultra == 6) {
                        dpll_clk = 66;
                        clock = ATA_CLOCK_66MHZ;
                } else if (dpll_clk) {  /* HPT36x chips don't have DPLL */
@@ -1243,7 +1229,7 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
        struct pci_dev  *dev            = hwif->pci_dev;
        struct hpt_info *info           = pci_get_drvdata(dev);
        int serialize                   = HPT_SERIALIZE_IO;
-       u8  scr1 = 0, ata66             = (hwif->channel) ? 0x01 : 0x02;
+       u8  scr1 = 0, ata66             = hwif->channel ? 0x01 : 0x02;
        u8  chip_type                   = info->chip_type;
        u8  new_mcr, old_mcr            = 0;
 
@@ -1256,7 +1242,9 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
        hwif->intrproc                  = &hpt3xx_intrproc;
        hwif->maskproc                  = &hpt3xx_maskproc;
        hwif->busproc                   = &hpt3xx_busproc;
-       hwif->udma_filter               = &hpt3xx_udma_filter;
+
+       if (chip_type <= HPT370A)
+               hwif->udma_filter       = &hpt3xx_udma_filter;
 
        /*
         * HPT3xxN chips have some complications:
@@ -1305,7 +1293,7 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
                return;
        }
 
-       hwif->ultra_mask = 0x7f;
+       hwif->ultra_mask = hwif->cds->udma_mask;
        hwif->mwdma_mask = 0x07;
 
        /*
@@ -1342,8 +1330,8 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
        } else
                pci_read_config_byte (dev, 0x5a, &scr1);
 
-       if (!hwif->udma_four)
-               hwif->udma_four = (scr1 & ata66) ? 0 : 1;
+       if (hwif->cbl != ATA_CBL_PATA40_SHORT)
+               hwif->cbl = (scr1 & ata66) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
 
        hwif->ide_dma_check             = &hpt366_config_drive_xfer_rate;
 
@@ -1353,9 +1341,9 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
        } else if (chip_type >= HPT370) {
                hwif->dma_start         = &hpt370_ide_dma_start;
                hwif->ide_dma_end       = &hpt370_ide_dma_end;
-               hwif->ide_dma_timeout   = &hpt370_ide_dma_timeout;
+               hwif->dma_timeout       = &hpt370_dma_timeout;
        } else
-               hwif->ide_dma_lostirq   = &hpt366_ide_dma_lostirq;
+               hwif->dma_lost_irq      = &hpt366_dma_lost_irq;
 
        if (!noautodma)
                hwif->autodma = 1;
@@ -1425,11 +1413,9 @@ static int __devinit init_setup_hpt372n(struct pci_dev *dev, ide_pci_device_t *d
 static int __devinit init_setup_hpt371(struct pci_dev *dev, ide_pci_device_t *d)
 {
        struct hpt_info *info;
-       u8 rev = 0, mcr1 = 0;
+       u8 mcr1 = 0;
 
-       pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
-
-       if (rev > 1) {
+       if (dev->revision > 1) {
                d->name = "HPT371N";
 
                info = &hpt371n;
@@ -1454,11 +1440,8 @@ static int __devinit init_setup_hpt371(struct pci_dev *dev, ide_pci_device_t *d)
 static int __devinit init_setup_hpt372a(struct pci_dev *dev, ide_pci_device_t *d)
 {
        struct hpt_info *info;
-       u8 rev = 0;
-
-       pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
 
-       if (rev > 1) {
+       if (dev->revision > 1) {
                d->name = "HPT372N";
 
                info = &hpt372n;
@@ -1472,11 +1455,8 @@ static int __devinit init_setup_hpt372a(struct pci_dev *dev, ide_pci_device_t *d
 static int __devinit init_setup_hpt302(struct pci_dev *dev, ide_pci_device_t *d)
 {
        struct hpt_info *info;
-       u8 rev = 0;
 
-       pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
-
-       if (rev > 1) {
+       if (dev->revision > 1) {
                d->name = "HPT302N";
 
                info = &hpt302n;
@@ -1490,7 +1470,7 @@ static int __devinit init_setup_hpt302(struct pci_dev *dev, ide_pci_device_t *d)
 static int __devinit init_setup_hpt366(struct pci_dev *dev, ide_pci_device_t *d)
 {
        struct pci_dev *dev2;
-       u8 rev = 0;
+       u8 rev = dev->revision;
        static char   *chipset_names[] = { "HPT366", "HPT366",  "HPT368",
                                           "HPT370", "HPT370A", "HPT372",
                                           "HPT372N" };
@@ -1501,11 +1481,35 @@ static int __devinit init_setup_hpt366(struct pci_dev *dev, ide_pci_device_t *d)
        if (PCI_FUNC(dev->devfn) & 1)
                return -ENODEV;
 
-       pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
+       switch (rev) {
+       case 0:
+       case 1:
+       case 2:
+               /*
+                * HPT36x chips have one channel per function and have
+                * both channel enable bits located differently and visible
+                * to both functions -- really stupid design decision... :-(
+                * Bit 4 is for the primary channel, bit 5 for the secondary.
+                */
+               d->channels = 1;
+               d->enablebits[0].mask = d->enablebits[0].val = 0x10;
 
-       if (rev > 6)
+               d->udma_mask = HPT366_ALLOW_ATA66_3 ?
+                             (HPT366_ALLOW_ATA66_4 ? 0x1f : 0x0f) : 0x07;
+               break;
+       case 3:
+       case 4:
+               d->udma_mask = HPT370_ALLOW_ATA100_5 ? 0x3f : 0x1f;
+               break;
+       default:
                rev = 6;
-               
+               /* fall thru */
+       case 5:
+       case 6:
+               d->udma_mask = HPT372_ALLOW_ATA133_6 ? 0x7f : 0x3f;
+               break;
+       }
+
        d->name = chipset_names[rev];
 
        pci_set_drvdata(dev, info[rev]);
@@ -1513,15 +1517,6 @@ static int __devinit init_setup_hpt366(struct pci_dev *dev, ide_pci_device_t *d)
        if (rev > 2)
                goto init_single;
 
-       /*
-        * HPT36x chips have one channel per function and have
-        * both channel enable bits located differently and visible
-        * to both functions -- really stupid design decision... :-(
-        * Bit 4 is for the primary channel, bit 5 for the secondary.
-        */
-       d->channels = 1;
-       d->enablebits[0].mask = d->enablebits[0].val = 0x10;
-
        if ((dev2 = pci_get_slot(dev->bus, dev->devfn + 1)) != NULL) {
                u8  mcr1 = 0, pin1 = 0, pin2 = 0;
                int ret;
@@ -1573,6 +1568,7 @@ static ide_pci_device_t hpt366_chipsets[] __devinitdata = {
                .channels       = 2,
                .autodma        = AUTODMA,
                .enablebits     = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
+               .udma_mask      = HPT372_ALLOW_ATA133_6 ? 0x7f : 0x3f,
                .bootable       = OFF_BOARD,
                .extra          = 240
        },{     /* 2 */
@@ -1584,6 +1580,7 @@ static ide_pci_device_t hpt366_chipsets[] __devinitdata = {
                .channels       = 2,
                .autodma        = AUTODMA,
                .enablebits     = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
+               .udma_mask      = HPT302_ALLOW_ATA133_6 ? 0x7f : 0x3f,
                .bootable       = OFF_BOARD,
                .extra          = 240
        },{     /* 3 */
@@ -1595,6 +1592,7 @@ static ide_pci_device_t hpt366_chipsets[] __devinitdata = {
                .channels       = 2,
                .autodma        = AUTODMA,
                .enablebits     = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
+               .udma_mask      = HPT371_ALLOW_ATA133_6 ? 0x7f : 0x3f,
                .bootable       = OFF_BOARD,
                .extra          = 240
        },{     /* 4 */
@@ -1606,6 +1604,7 @@ static ide_pci_device_t hpt366_chipsets[] __devinitdata = {
                .channels       = 2,    /* 4 */
                .autodma        = AUTODMA,
                .enablebits     = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
+               .udma_mask      = 0x3f,
                .bootable       = OFF_BOARD,
                .extra          = 240
        },{     /* 5 */
@@ -1617,6 +1616,7 @@ static ide_pci_device_t hpt366_chipsets[] __devinitdata = {
                .channels       = 2,    /* 4 */
                .autodma        = AUTODMA,
                .enablebits     = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
+               .udma_mask      = HPT372_ALLOW_ATA133_6 ? 0x7f : 0x3f,
                .bootable       = OFF_BOARD,
                .extra          = 240
        }
index c04a02687b95ec91c3687761c6f3e4e318b380c5..ff48c23e571ea03ad6506437b3ece40f3afedd47 100644 (file)
@@ -231,7 +231,7 @@ static int it8213_config_drive_for_dma (ide_drive_t *drive)
 
 static void __devinit init_hwif_it8213(ide_hwif_t *hwif)
 {
-       u8 reg42h = 0, ata66 = 0;
+       u8 reg42h = 0;
 
        hwif->speedproc = &it8213_tune_chipset;
        hwif->tuneproc  = &it8213_tuneproc;
@@ -250,11 +250,11 @@ static void __devinit init_hwif_it8213(ide_hwif_t *hwif)
        hwif->swdma_mask = 0x04;
 
        pci_read_config_byte(hwif->pci_dev, 0x42, &reg42h);
-       ata66 = (reg42h & 0x02) ? 0 : 1;
 
        hwif->ide_dma_check = &it8213_config_drive_for_dma;
-       if (!(hwif->udma_four))
-               hwif->udma_four = ata66;
+
+       if (hwif->cbl != ATA_CBL_PATA40_SHORT)
+               hwif->cbl = (reg42h & 0x02) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
 
        /*
         *      The BIOS often doesn't set up DMA on this controller
index 3aeb7f1b79168f9790f3faafda531c653b7195c4..8197b653ba1ed8cbb67e450ed6d5af628a21dd40 100644 (file)
@@ -491,10 +491,10 @@ static int it821x_config_drive_for_dma (ide_drive_t *drive)
  *     the needed logic onboard.
  */
 
-static unsigned int __devinit ata66_it821x(ide_hwif_t *hwif)
+static u8 __devinit ata66_it821x(ide_hwif_t *hwif)
 {
        /* The reference driver also only does disk side */
-       return 1;
+       return ATA_CBL_PATA80;
 }
 
 /**
@@ -662,8 +662,9 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif)
        hwif->mwdma_mask = 0x07;
 
        hwif->ide_dma_check = &it821x_config_drive_for_dma;
-       if (!(hwif->udma_four))
-               hwif->udma_four = ata66_it821x(hwif);
+
+       if (hwif->cbl != ATA_CBL_PATA40_SHORT)
+               hwif->cbl = ata66_it821x(hwif);
 
        /*
         *      The BIOS often doesn't set up DMA on this controller
index 76ed251472298682a516c0b6699dc0c07a7618d4..a6008f63e71ef677721411e7d2f36cb1696e9141 100644 (file)
@@ -25,10 +25,10 @@ typedef enum {
  *     ata66_jmicron           -       Cable check
  *     @hwif: IDE port
  *
- *     Return 1 if the cable is 80pin
+ *     Returns the cable type.
  */
 
-static int __devinit ata66_jmicron(ide_hwif_t *hwif)
+static u8 __devinit ata66_jmicron(ide_hwif_t *hwif)
 {
        struct pci_dev *pdev = hwif->pci_dev;
 
@@ -70,16 +70,17 @@ static int __devinit ata66_jmicron(ide_hwif_t *hwif)
        {
        case PORT_PATA0:
                if (control & (1 << 3)) /* 40/80 pin primary */
-                       return 0;
-               return 1;
+                       return ATA_CBL_PATA40;
+               return ATA_CBL_PATA80;
        case PORT_PATA1:
                if (control5 & (1 << 19))       /* 40/80 pin secondary */
-                       return 0;
-               return 1;
+                       return ATA_CBL_PATA40;
+               return ATA_CBL_PATA80;
        case PORT_SATA:
                break;
        }
-       return 1; /* Avoid bogus "control reaches end of non-void function" */
+       /* Avoid bogus "control reaches end of non-void function" */
+       return ATA_CBL_PATA80;
 }
 
 static void jmicron_tuneproc (ide_drive_t *drive, byte mode_wanted)
@@ -159,8 +160,9 @@ static void __devinit init_hwif_jmicron(ide_hwif_t *hwif)
        hwif->mwdma_mask = 0x07;
 
        hwif->ide_dma_check = &jmicron_config_drive_for_dma;
-       if (!(hwif->udma_four))
-               hwif->udma_four = ata66_jmicron(hwif);
+
+       if (hwif->cbl != ATA_CBL_PATA40_SHORT)
+               hwif->cbl = ata66_jmicron(hwif);
 
        hwif->autodma = 1;
        hwif->drives[0].autodma = hwif->autodma;
index 0765dce6948eb1f91cc39ce878bac44750776a11..ee5020df005d7515eaf7822c18515a34fb119fff 100644 (file)
@@ -225,7 +225,10 @@ static void pdcnew_tune_drive(ide_drive_t *drive, u8 pio)
 
 static u8 pdcnew_cable_detect(ide_hwif_t *hwif)
 {
-       return get_indexed_reg(hwif, 0x0b) & 0x04;
+       if (get_indexed_reg(hwif, 0x0b) & 0x04)
+               return ATA_CBL_PATA40;
+       else
+               return ATA_CBL_PATA80;
 }
 
 static int pdcnew_config_drive_xfer_rate(ide_drive_t *drive)
@@ -509,8 +512,8 @@ static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif)
 
        hwif->ide_dma_check = &pdcnew_config_drive_xfer_rate;
 
-       if (!hwif->udma_four)
-               hwif->udma_four = pdcnew_cable_detect(hwif) ? 0 : 1;
+       if (hwif->cbl != ATA_CBL_PATA40_SHORT)
+               hwif->cbl = pdcnew_cable_detect(hwif);
 
        if (!noautodma)
                hwif->autodma = 1;
index 23844687deea90a8d8a33efcb5486d7fabcb74df..41ac4a94959fb2c6fd1e4032cf599fe9370d84b4 100644 (file)
@@ -152,8 +152,10 @@ static void pdc202xx_tune_drive(ide_drive_t *drive, u8 pio)
 static u8 pdc202xx_old_cable_detect (ide_hwif_t *hwif)
 {
        u16 CIS = 0, mask = (hwif->channel) ? (1<<11) : (1<<10);
+
        pci_read_config_word(hwif->pci_dev, 0x50, &CIS);
-       return (CIS & mask) ? 1 : 0;
+
+       return (CIS & mask) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
 }
 
 /*
@@ -267,18 +269,24 @@ somebody_else:
        return (dma_stat & 4) == 4;     /* return 1 if INTR asserted */
 }
 
-static int pdc202xx_ide_dma_lostirq(ide_drive_t *drive)
+static void pdc202xx_dma_lost_irq(ide_drive_t *drive)
 {
-       if (HWIF(drive)->resetproc != NULL)
-               HWIF(drive)->resetproc(drive);
-       return __ide_dma_lostirq(drive);
+       ide_hwif_t *hwif = HWIF(drive);
+
+       if (hwif->resetproc != NULL)
+               hwif->resetproc(drive);
+
+       ide_dma_lost_irq(drive);
 }
 
-static int pdc202xx_ide_dma_timeout(ide_drive_t *drive)
+static void pdc202xx_dma_timeout(ide_drive_t *drive)
 {
-       if (HWIF(drive)->resetproc != NULL)
-               HWIF(drive)->resetproc(drive);
-       return __ide_dma_timeout(drive);
+       ide_hwif_t *hwif = HWIF(drive);
+
+       if (hwif->resetproc != NULL)
+               hwif->resetproc(drive);
+
+       ide_dma_timeout(drive);
 }
 
 static void pdc202xx_reset_host (ide_hwif_t *hwif)
@@ -347,12 +355,13 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif)
        hwif->err_stops_fifo = 1;
 
        hwif->ide_dma_check = &pdc202xx_config_drive_xfer_rate;
-       hwif->ide_dma_lostirq = &pdc202xx_ide_dma_lostirq;
-       hwif->ide_dma_timeout = &pdc202xx_ide_dma_timeout;
+       hwif->dma_lost_irq = &pdc202xx_dma_lost_irq;
+       hwif->dma_timeout = &pdc202xx_dma_timeout;
 
        if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246) {
-               if (!(hwif->udma_four))
-                       hwif->udma_four = (pdc202xx_old_cable_detect(hwif)) ? 0 : 1;
+               if (hwif->cbl != ATA_CBL_PATA40_SHORT)
+                       hwif->cbl = pdc202xx_old_cable_detect(hwif);
+
                hwif->dma_start = &pdc202xx_old_ide_dma_start;
                hwif->ide_dma_end = &pdc202xx_old_ide_dma_end;
        } 
index 8b219dd630241f4285512e61a9b417872c5147e8..1372c35be035fcc898cb1fe708f8056c56079fde 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/ide/pci/piix.c       Version 0.47    February 8, 2007
+ *  linux/drivers/ide/pci/piix.c       Version 0.50    Jun 10, 2007
  *
  *  Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer
  *  Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
@@ -394,14 +394,45 @@ static void piix_dma_clear_irq(ide_drive_t *drive)
        hwif->OUTB(dma_stat, hwif->dma_status);
 }
 
-static int __devinit piix_cable_detect(ide_hwif_t *hwif)
+struct ich_laptop {
+       u16 device;
+       u16 subvendor;
+       u16 subdevice;
+};
+
+/*
+ *     List of laptops that use short cables rather than 80 wire
+ */
+
+static const struct ich_laptop ich_laptop[] = {
+       /* devid, subvendor, subdev */
+       { 0x27DF, 0x0005, 0x0280 },     /* ICH7 on Acer 5602WLMi */
+       { 0x27DF, 0x1025, 0x0110 },     /* ICH7 on Acer 3682WLMi */
+       { 0x27DF, 0x1043, 0x1267 },     /* ICH7 on Asus W5F */
+       { 0x24CA, 0x1025, 0x0061 },     /* ICH4 on Acer Aspire 2023WLMi */
+       /* end marker */
+       { 0, }
+};
+
+static u8 __devinit piix_cable_detect(ide_hwif_t *hwif)
 {
-       struct pci_dev *dev = hwif->pci_dev;
+       struct pci_dev *pdev = hwif->pci_dev;
+       const struct ich_laptop *lap = &ich_laptop[0];
        u8 reg54h = 0, mask = hwif->channel ? 0xc0 : 0x30;
 
-       pci_read_config_byte(dev, 0x54, &reg54h);
+       /* check for specials */
+       while (lap->device) {
+               if (lap->device == pdev->device &&
+                   lap->subvendor == pdev->subsystem_vendor &&
+                   lap->subdevice == pdev->subsystem_device) {
+                       return ATA_CBL_PATA40_SHORT;
+               }
+               lap++;
+       }
+
+       pci_read_config_byte(pdev, 0x54, &reg54h);
 
-       return (reg54h & mask) ? 1 : 0;
+       return (reg54h & mask) ? ATA_CBL_PATA80 : ATA_CBL_PATA40;
 }
 
 /**
@@ -444,8 +475,8 @@ static void __devinit init_hwif_piix(ide_hwif_t *hwif)
        hwif->swdma_mask = 0x04;
 
        if (hwif->ultra_mask & 0x78) {
-               if (!hwif->udma_four)
-                       hwif->udma_four = piix_cable_detect(hwif);
+               if (hwif->cbl != ATA_CBL_PATA40_SHORT)
+                       hwif->cbl = piix_cable_detect(hwif);
        }
 
        if (no_piix_dma)
@@ -541,18 +572,16 @@ static void __devinit piix_check_450nx(void)
 {
        struct pci_dev *pdev = NULL;
        u16 cfg;
-       u8 rev;
        while((pdev=pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, pdev))!=NULL)
        {
                /* Look for 450NX PXB. Check for problem configurations
                   A PCI quirk checks bit 6 already */
-               pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
                pci_read_config_word(pdev, 0x41, &cfg);
                /* Only on the original revision: IDE DMA can hang */
-               if(rev == 0x00)
+               if (pdev->revision == 0x00)
                        no_piix_dma = 1;
                /* On all revisions below 5 PXB bus lock must be disabled for IDE */
-               else if(cfg & (1<<14) && rev < 5)
+               else if (cfg & (1<<14) && pdev->revision < 5)
                        no_piix_dma = 2;
        }
        if(no_piix_dma)
index 55bc0a32e34f9d1b8781bef98a34461cce96ade8..7b87488e3daa831fee54fba1e4dc9f8d59c43b94 100644 (file)
@@ -716,7 +716,7 @@ static void __devinit init_hwif_scc(ide_hwif_t *hwif)
        hwif->atapi_dma = 1;
 
        /* we support 80c cable only. */
-       hwif->udma_four = 1;
+       hwif->cbl = ATA_CBL_PATA80;
 
        hwif->autodma = 0;
        if (!noautodma)
index d9c4fd1ae9969784144f10d073c7d078b490bbc6..ed04e0c8dd4c491ae71f3f4b4821de6aa5e5ee97 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/ide/pci/serverworks.c         Version 0.11    Jun 2 2007
+ * linux/drivers/ide/pci/serverworks.c         Version 0.20    Jun 3 2007
  *
  * Copyright (C) 1998-2000 Michel Aubry
  * Copyright (C) 1998-2000 Andrzej Krzysztofowicz
@@ -55,7 +55,6 @@ static const char *svwks_bad_ata100[] = {
        NULL
 };
 
-static u8 svwks_revision = 0;
 static struct pci_dev *isa_dev;
 
 static int check_in_drive_lists (ide_drive_t *drive, const char **list)
@@ -71,9 +70,6 @@ static u8 svwks_udma_filter(ide_drive_t *drive)
        struct pci_dev *dev     = HWIF(drive)->pci_dev;
        u8 mask = 0;
 
-       if (!svwks_revision)
-               pci_read_config_byte(dev, PCI_REVISION_ID, &svwks_revision);
-
        if (dev->device == PCI_DEVICE_ID_SERVERWORKS_HT1000IDE)
                return 0x1f;
        if (dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) {
@@ -88,9 +84,9 @@ static u8 svwks_udma_filter(ide_drive_t *drive)
                        return 0;
                /* Check the OSB4 DMA33 enable bit */
                return ((reg & 0x00004000) == 0x00004000) ? 0x07 : 0;
-       } else if (svwks_revision < SVWKS_CSB5_REVISION_NEW) {
+       } else if (dev->revision < SVWKS_CSB5_REVISION_NEW) {
                return 0x07;
-       } else if (svwks_revision >= SVWKS_CSB5_REVISION_NEW) {
+       } else if (dev->revision >= SVWKS_CSB5_REVISION_NEW) {
                u8 btr = 0, mode;
                pci_read_config_byte(dev, 0x5A, &btr);
                mode = btr & 0x3;
@@ -151,84 +147,11 @@ static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed)
        if(dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4 &&
                drive->media == ide_disk && speed >= XFER_UDMA_0)
                        BUG();
-                       
-       pci_read_config_byte(dev, drive_pci[drive->dn], &pio_timing);
-       pci_read_config_byte(dev, drive_pci2[drive->dn], &dma_timing);
+
        pci_read_config_byte(dev, (0x56|hwif->channel), &ultra_timing);
        pci_read_config_word(dev, 0x4A, &csb5_pio);
        pci_read_config_byte(dev, 0x54, &ultra_enable);
 
-       /* If we are in RAID mode (eg AMI MegaIDE) then we can't it
-          turns out trust the firmware configuration */
-
-       if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE)
-               goto oem_setup_failed;
-
-       /* Per Specified Design by OEM, and ASIC Architect */
-       if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) ||
-           (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) {
-               if (!drive->init_speed) {
-                       u8 dma_stat = inb(hwif->dma_status);
-
-                       if (((ultra_enable << (7-drive->dn) & 0x80) == 0x80) &&
-                           ((dma_stat & (1<<(5+unit))) == (1<<(5+unit)))) {
-                               drive->current_speed = drive->init_speed = XFER_UDMA_0 + udma_modes[(ultra_timing >> (4*unit)) & ~(0xF0)];
-                               return 0;
-                       } else if ((dma_timing) &&
-                                  ((dma_stat&(1<<(5+unit)))==(1<<(5+unit)))) {
-                               u8 dmaspeed;
-
-                               switch (dma_timing & 0x77) {
-                               case 0x20:
-                                       dmaspeed = XFER_MW_DMA_2;
-                                       break;
-                               case 0x21:
-                                       dmaspeed = XFER_MW_DMA_1;
-                                       break;
-                               case 0x77:
-                                       dmaspeed = XFER_MW_DMA_0;
-                                       break;
-                               default:
-                                       goto dma_pio;
-                               }
-
-                               drive->current_speed = drive->init_speed = dmaspeed;
-                               return 0;
-                       }
-dma_pio:
-                       if (pio_timing) {
-                               u8 piospeed;
-
-                               switch (pio_timing & 0x7f) {
-                               case 0x20:
-                                       piospeed = XFER_PIO_4;
-                                       break;
-                               case 0x22:
-                                       piospeed = XFER_PIO_3;
-                                       break;
-                               case 0x34:
-                                       piospeed = XFER_PIO_2;
-                                       break;
-                               case 0x47:
-                                       piospeed = XFER_PIO_1;
-                                       break;
-                               case 0x5d:
-                                       piospeed = XFER_PIO_0;
-                                       break;
-                               default:
-                                       goto oem_setup_failed;
-                               }
-
-                               drive->current_speed = drive->init_speed = piospeed;
-                               return 0;
-                       }
-               }
-       }
-
-oem_setup_failed:
-
-       pio_timing      = 0;
-       dma_timing      = 0;
        ultra_timing    &= ~(0x0F << (4*unit));
        ultra_enable    &= ~(0x01 << drive->dn);
        csb5_pio        &= ~(0x0F << (4*drive->dn));
@@ -307,9 +230,6 @@ static unsigned int __devinit init_chipset_svwks (struct pci_dev *dev, const cha
        unsigned int reg;
        u8 btr;
 
-       /* save revision id to determine DMA capability */
-       pci_read_config_byte(dev, PCI_REVISION_ID, &svwks_revision);
-
        /* force Master Latency Timer value to 64 PCICLKs */
        pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x40);
 
@@ -388,7 +308,7 @@ static unsigned int __devinit init_chipset_svwks (struct pci_dev *dev, const cha
                if (!(PCI_FUNC(dev->devfn) & 1))
                        btr |= 0x2;
                else
-                       btr |= (svwks_revision >= SVWKS_CSB5_REVISION_NEW) ? 0x3 : 0x2;
+                       btr |= (dev->revision >= SVWKS_CSB5_REVISION_NEW) ? 0x3 : 0x2;
                pci_write_config_byte(dev, 0x5A, btr);
        }
        /* Setup HT1000 SouthBridge Controller - Single Channel Only */
@@ -402,9 +322,9 @@ static unsigned int __devinit init_chipset_svwks (struct pci_dev *dev, const cha
        return dev->irq;
 }
 
-static unsigned int __devinit ata66_svwks_svwks (ide_hwif_t *hwif)
+static u8 __devinit ata66_svwks_svwks(ide_hwif_t *hwif)
 {
-       return 1;
+       return ATA_CBL_PATA80;
 }
 
 /* On Dell PowerEdge servers with a CSB5/CSB6, the top two bits
@@ -414,7 +334,7 @@ static unsigned int __devinit ata66_svwks_svwks (ide_hwif_t *hwif)
  * Bit 14 clear = primary IDE channel does not have 80-pin cable.
  * Bit 14 set   = primary IDE channel has 80-pin cable.
  */
-static unsigned int __devinit ata66_svwks_dell (ide_hwif_t *hwif)
+static u8 __devinit ata66_svwks_dell(ide_hwif_t *hwif)
 {
        struct pci_dev *dev = hwif->pci_dev;
        if (dev->subsystem_vendor == PCI_VENDOR_ID_DELL &&
@@ -422,8 +342,8 @@ static unsigned int __devinit ata66_svwks_dell (ide_hwif_t *hwif)
            (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE ||
             dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE))
                return ((1 << (hwif->channel + 14)) &
-                       dev->subsystem_device) ? 1 : 0;
-       return 0;
+                       dev->subsystem_device) ? ATA_CBL_PATA80 : ATA_CBL_PATA40;
+       return ATA_CBL_PATA40;
 }
 
 /* Sun Cobalt Alpine hardware avoids the 80-pin cable
@@ -432,18 +352,18 @@ static unsigned int __devinit ata66_svwks_dell (ide_hwif_t *hwif)
  *
  * WARNING: this only works on Alpine hardware!
  */
-static unsigned int __devinit ata66_svwks_cobalt (ide_hwif_t *hwif)
+static u8 __devinit ata66_svwks_cobalt(ide_hwif_t *hwif)
 {
        struct pci_dev *dev = hwif->pci_dev;
        if (dev->subsystem_vendor == PCI_VENDOR_ID_SUN &&
            dev->vendor == PCI_VENDOR_ID_SERVERWORKS &&
            dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE)
                return ((1 << (hwif->channel + 14)) &
-                       dev->subsystem_device) ? 1 : 0;
-       return 0;
+                       dev->subsystem_device) ? ATA_CBL_PATA80 : ATA_CBL_PATA40;
+       return ATA_CBL_PATA40;
 }
 
-static unsigned int __devinit ata66_svwks (ide_hwif_t *hwif)
+static u8 __devinit ata66_svwks(ide_hwif_t *hwif)
 {
        struct pci_dev *dev = hwif->pci_dev;
 
@@ -462,9 +382,9 @@ static unsigned int __devinit ata66_svwks (ide_hwif_t *hwif)
        /* Per Specified Design by OEM, and ASIC Architect */
        if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) ||
            (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2))
-               return 1;
+               return ATA_CBL_PATA80;
 
-       return 0;
+       return ATA_CBL_PATA40;
 }
 
 static void __devinit init_hwif_svwks (ide_hwif_t *hwif)
@@ -495,8 +415,8 @@ static void __devinit init_hwif_svwks (ide_hwif_t *hwif)
 
        hwif->ide_dma_check = &svwks_config_drive_xfer_rate;
        if (hwif->pci_dev->device != PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) {
-               if (!hwif->udma_four)
-                       hwif->udma_four = ata66_svwks(hwif);
+               if (hwif->cbl != ATA_CBL_PATA40_SHORT)
+                       hwif->cbl = ata66_svwks(hwif);
        }
        if (!noautodma)
                hwif->autodma = 1;
index d3185e29a38eef3c6763c68ef390e4b3aaa0ec69..d396b2929ed87791564600b85675d72eda7af774 100644 (file)
@@ -316,14 +316,6 @@ static void sgiioc4_dma_host_off(ide_drive_t * drive)
        sgiioc4_clearirq(drive);
 }
 
-static int
-sgiioc4_ide_dma_lostirq(ide_drive_t * drive)
-{
-       HWIF(drive)->resetproc(drive);
-
-       return __ide_dma_lostirq(drive);
-}
-
 static void
 sgiioc4_resetproc(ide_drive_t * drive)
 {
@@ -331,6 +323,14 @@ sgiioc4_resetproc(ide_drive_t * drive)
        sgiioc4_clearirq(drive);
 }
 
+static void
+sgiioc4_dma_lost_irq(ide_drive_t * drive)
+{
+       sgiioc4_resetproc(drive);
+
+       ide_dma_lost_irq(drive);
+}
+
 static u8
 sgiioc4_INB(unsigned long port)
 {
@@ -607,8 +607,8 @@ ide_init_sgiioc4(ide_hwif_t * hwif)
        hwif->ide_dma_test_irq = &sgiioc4_ide_dma_test_irq;
        hwif->dma_host_on = &sgiioc4_dma_host_on;
        hwif->dma_host_off = &sgiioc4_dma_host_off;
-       hwif->ide_dma_lostirq = &sgiioc4_ide_dma_lostirq;
-       hwif->ide_dma_timeout = &__ide_dma_timeout;
+       hwif->dma_lost_irq = &sgiioc4_dma_lost_irq;
+       hwif->dma_timeout = &ide_dma_timeout;
 
        hwif->INB = &sgiioc4_INB;
 }
index 1a4444e7226aa840093e39779bc192eaed8d728f..1c3e354878934dd923116fe7a6723524057c8026 100644 (file)
@@ -933,16 +933,17 @@ static void __devinit init_iops_siimage(ide_hwif_t *hwif)
  *     interface.
  */
 
-static unsigned int __devinit ata66_siimage(ide_hwif_t *hwif)
+static u8 __devinit ata66_siimage(ide_hwif_t *hwif)
 {
        unsigned long addr = siimage_selreg(hwif, 0);
-       if (pci_get_drvdata(hwif->pci_dev) == NULL) {
-               u8 ata66 = 0;
+       u8 ata66 = 0;
+
+       if (pci_get_drvdata(hwif->pci_dev) == NULL)
                pci_read_config_byte(hwif->pci_dev, addr, &ata66);
-               return (ata66 & 0x01) ? 1 : 0;
-       }
+       else
+               ata66 = hwif->INB(addr);
 
-       return (hwif->INB(addr) & 0x01) ? 1 : 0;
+       return (ata66 & 0x01) ? ATA_CBL_PATA80 : ATA_CBL_PATA40;
 }
 
 /**
@@ -988,8 +989,9 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif)
                hwif->atapi_dma = 1;
 
        hwif->ide_dma_check = &siimage_config_drive_for_dma;
-       if (!(hwif->udma_four))
-               hwif->udma_four = ata66_siimage(hwif);
+
+       if (hwif->cbl != ATA_CBL_PATA40_SHORT)
+               hwif->cbl = ata66_siimage(hwif);
 
        if (hwif->mmio) {
                hwif->ide_dma_test_irq = &siimage_mmio_ide_dma_test_irq;
index ec0adad9ef6132928094a5774c06daedd52525d7..756a9b6eb4624aa5688d3b2420a5dbde659a5977 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/ide/pci/sis5513.c     Version 0.20    Mar 4, 2007
+ * linux/drivers/ide/pci/sis5513.c     Version 0.25    Jun 10, 2007
  *
  * Copyright (C) 1999-2000     Andre Hedrick <andre@linux-ide.org>
  * Copyright (C) 2002          Lionel Bouton <Lionel.Bouton@inet6.fr>, Maintainer
@@ -659,9 +659,7 @@ static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const c
 
                /* Special case for SiS630 : 630S/ET is ATA_100a */
                if (SiSHostChipInfo[i].host_id == PCI_DEVICE_ID_SI_630) {
-                       u8 hostrev;
-                       pci_read_config_byte(host, PCI_REVISION_ID, &hostrev);
-                       if (hostrev >= 0x30)
+                       if (host->revision >= 0x30)
                                chipset_family = ATA_100a;
                }
                pci_dev_put(host);
@@ -702,7 +700,6 @@ static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const c
                        u16 trueid;
                        u8 prefctl;
                        u8 idecfg;
-                       u8 sbrev;
 
                        pci_read_config_byte(dev, 0x4a, &idecfg);
                        pci_write_config_byte(dev, 0x4a, idecfg | 0x10);
@@ -712,11 +709,10 @@ static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const c
                        if (trueid == 0x5517) { /* SiS 961/961B */
 
                                lpc_bridge = pci_get_slot(dev->bus, 0x10); /* Bus 0, Dev 2, Fn 0 */
-                               pci_read_config_byte(lpc_bridge, PCI_REVISION_ID, &sbrev);
                                pci_read_config_byte(dev, 0x49, &prefctl);
                                pci_dev_put(lpc_bridge);
 
-                               if (sbrev == 0x10 && (prefctl & 0x80)) {
+                               if (lpc_bridge->revision == 0x10 && (prefctl & 0x80)) {
                                        printk(KERN_INFO "SIS5513: SiS 961B MuTIOL IDE UDMA133 controller\n");
                                        chipset_family = ATA_133a;
                                } else {
@@ -796,10 +792,33 @@ static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const c
        return 0;
 }
 
-static unsigned int __devinit ata66_sis5513 (ide_hwif_t *hwif)
+struct sis_laptop {
+       u16 device;
+       u16 subvendor;
+       u16 subdevice;
+};
+
+static const struct sis_laptop sis_laptop[] = {
+       /* devid, subvendor, subdev */
+       { 0x5513, 0x1043, 0x1107 },     /* ASUS A6K */
+       /* end marker */
+       { 0, }
+};
+
+static u8 __devinit ata66_sis5513(ide_hwif_t *hwif)
 {
+       struct pci_dev *pdev = hwif->pci_dev;
+       const struct sis_laptop *lap = &sis_laptop[0];
        u8 ata66 = 0;
 
+       while (lap->device) {
+               if (lap->device == pdev->device &&
+                   lap->subvendor == pdev->subsystem_vendor &&
+                   lap->subdevice == pdev->subsystem_device)
+                       return ATA_CBL_PATA40_SHORT;
+               lap++;
+       }
+
        if (chipset_family >= ATA_133) {
                u16 regw = 0;
                u16 reg_addr = hwif->channel ? 0x52: 0x50;
@@ -811,7 +830,8 @@ static unsigned int __devinit ata66_sis5513 (ide_hwif_t *hwif)
                pci_read_config_byte(hwif->pci_dev, 0x48, &reg48h);
                ata66 = (reg48h & mask) ? 0 : 1;
        }
-        return ata66;
+
+       return ata66 ? ATA_CBL_PATA80 : ATA_CBL_PATA40;
 }
 
 static void __devinit init_hwif_sis5513 (ide_hwif_t *hwif)
@@ -841,8 +861,8 @@ static void __devinit init_hwif_sis5513 (ide_hwif_t *hwif)
        if (!chipset_family)
                return;
 
-       if (!(hwif->udma_four))
-               hwif->udma_four = ata66_sis5513(hwif);
+       if (hwif->cbl != ATA_CBL_PATA40_SHORT)
+               hwif->cbl = ata66_sis5513(hwif);
 
        if (chipset_family > ATA_16) {
                hwif->ide_dma_check = &sis5513_config_xfer_rate;
index 7c383d9cc4727344a2a28d627e016c09fba7841b..a7323d278c49ae15036941b13d3573a05116e273 100644 (file)
@@ -195,7 +195,7 @@ static inline void sl82c105_reset_host(struct pci_dev *dev)
  * This function is called when the IDE timer expires, the drive
  * indicates that it is READY, and we were waiting for DMA to complete.
  */
-static int sl82c105_ide_dma_lostirq(ide_drive_t *drive)
+static void sl82c105_dma_lost_irq(ide_drive_t *drive)
 {
        ide_hwif_t *hwif        = HWIF(drive);
        struct pci_dev *dev     = hwif->pci_dev;
@@ -222,9 +222,6 @@ static int sl82c105_ide_dma_lostirq(ide_drive_t *drive)
        }
 
        sl82c105_reset_host(dev);
-
-       /* __ide_dma_lostirq would return 1, so we do as well */
-       return 1;
 }
 
 /*
@@ -244,15 +241,12 @@ static void sl82c105_dma_start(ide_drive_t *drive)
        ide_dma_start(drive);
 }
 
-static int sl82c105_ide_dma_timeout(ide_drive_t *drive)
+static void sl82c105_dma_timeout(ide_drive_t *drive)
 {
-       ide_hwif_t *hwif        = HWIF(drive);
-       struct pci_dev *dev     = hwif->pci_dev;
+       DBG(("sl82c105_dma_timeout(drive:%s)\n", drive->name));
 
-       DBG(("sl82c105_ide_dma_timeout(drive:%s)\n", drive->name));
-
-       sl82c105_reset_host(dev);
-       return __ide_dma_timeout(drive);
+       sl82c105_reset_host(HWIF(drive)->pci_dev);
+       ide_dma_timeout(drive);
 }
 
 static int sl82c105_ide_dma_on(ide_drive_t *drive)
@@ -344,7 +338,6 @@ static void sl82c105_tune_drive(ide_drive_t *drive, u8 pio)
 static unsigned int sl82c105_bridge_revision(struct pci_dev *dev)
 {
        struct pci_dev *bridge;
-       u8 rev;
 
        /*
         * The bridge should be part of the same device, but function 0.
@@ -366,10 +359,9 @@ static unsigned int sl82c105_bridge_revision(struct pci_dev *dev)
        /*
         * We need to find function 0's revision, not function 1
         */
-       pci_read_config_byte(bridge, PCI_REVISION_ID, &rev);
        pci_dev_put(bridge);
 
-       return rev;
+       return bridge->revision;
 }
 
 /*
@@ -441,9 +433,9 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
        hwif->ide_dma_check             = &sl82c105_ide_dma_check;
        hwif->ide_dma_on                = &sl82c105_ide_dma_on;
        hwif->dma_off_quietly           = &sl82c105_dma_off_quietly;
-       hwif->ide_dma_lostirq           = &sl82c105_ide_dma_lostirq;
+       hwif->dma_lost_irq              = &sl82c105_dma_lost_irq;
        hwif->dma_start                 = &sl82c105_dma_start;
-       hwif->ide_dma_timeout           = &sl82c105_ide_dma_timeout;
+       hwif->dma_timeout               = &sl82c105_dma_timeout;
 
        if (!noautodma)
                hwif->autodma = 1;
index c40f291f91e04c62cce013882abcc67ef53ad05d..575dbbd8b482edb345960fc5e56ecbf87ed39693 100644 (file)
@@ -199,10 +199,9 @@ static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif)
        hwif->mwdma_mask = 0x06;
        hwif->swdma_mask = 0x04;
 
-       if (!hwif->udma_four) {
+       if (hwif->cbl != ATA_CBL_PATA40_SHORT)
                /* bit[0(1)]: 0:80, 1:40 */
-               hwif->udma_four = (reg47 & mask) ? 0 : 1;
-       }
+               hwif->cbl = (reg47 & mask) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
 
        hwif->ide_dma_check = &slc90e66_config_drive_xfer_rate;
 
index cee619bb2eaf8a7713ccc7582acb48b22f4c10e8..8de1f8e224946b589fb173df6d572499598eecb2 100644 (file)
@@ -220,13 +220,13 @@ static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif)
        hwif->ide_dma_check     = &tc86c001_config_drive_xfer_rate;
        hwif->dma_start         = &tc86c001_dma_start;
 
-       if (!hwif->udma_four) {
+       if (hwif->cbl != ATA_CBL_PATA40_SHORT) {
                /*
                 * System Control  1 Register bit 13 (PDIAGN):
                 * 0=80-pin cable, 1=40-pin cable
                 */
                scr1 = hwif->INW(sc_base + 0x00);
-               hwif->udma_four = (scr1 & 0x2000) ? 0 : 1;
+               hwif->cbl = (scr1 & 0x2000) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
        }
 
        if (!noautodma)
index a508550c4095cecb0a43ffb474ca4d94b531d30b..27e92fb9f95e0c49cdd1a874e017a8dc021a4f6a 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *
- * Version 3.38
+ * Version 3.45
  *
  * VIA IDE driver for Linux. Supported southbridges:
  *
@@ -9,6 +9,7 @@
  *   vt8235, vt8237, vt8237a
  *
  * Copyright (c) 2000-2002 Vojtech Pavlik
+ * Copyright (c) 2007 Bartlomiej Zolnierkiewicz
  *
  * Based on the work of:
  *     Michel Aubry
@@ -33,6 +34,8 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/ide.h>
+#include <linux/dmi.h>
+
 #include <asm/io.h>
 
 #ifdef CONFIG_PPC_CHRP
@@ -41,8 +44,6 @@
 
 #include "ide-timing.h"
 
-#define DISPLAY_VIA_TIMINGS
-
 #define VIA_IDE_ENABLE         0x40
 #define VIA_IDE_CONFIG         0x41
 #define VIA_FIFO_CONFIG                0x43
 #define VIA_ADDRESS_SETUP      0x4c
 #define VIA_UDMA_TIMING                0x50
 
-#define VIA_UDMA               0x007
-#define VIA_UDMA_NONE          0x000
-#define VIA_UDMA_33            0x001
-#define VIA_UDMA_66            0x002
-#define VIA_UDMA_100           0x003
-#define VIA_UDMA_133           0x004
-#define VIA_BAD_PREQ           0x010   /* Crashes if PREQ# till DDACK# set */
-#define VIA_BAD_CLK66          0x020   /* 66 MHz clock doesn't work correctly */
-#define VIA_SET_FIFO           0x040   /* Needs to have FIFO split set */
-#define VIA_NO_UNMASK          0x080   /* Doesn't work with IRQ unmasking on */
-#define VIA_BAD_ID             0x100   /* Has wrong vendor ID (0x1107) */
-#define VIA_BAD_AST            0x200   /* Don't touch Address Setup Timing */
+#define VIA_BAD_PREQ           0x01 /* Crashes if PREQ# till DDACK# set */
+#define VIA_BAD_CLK66          0x02 /* 66 MHz clock doesn't work correctly */
+#define VIA_SET_FIFO           0x04 /* Needs to have FIFO split set */
+#define VIA_NO_UNMASK          0x08 /* Doesn't work with IRQ unmasking on */
+#define VIA_BAD_ID             0x10 /* Has wrong vendor ID (0x1107) */
+#define VIA_BAD_AST            0x20 /* Don't touch Address Setup Timing */
 
 /*
  * VIA SouthBridge chips.
@@ -76,36 +71,37 @@ static struct via_isa_bridge {
        u16 id;
        u8 rev_min;
        u8 rev_max;
-       u16 flags;
+       u8 udma_mask;
+       u8 flags;
 } via_isa_bridges[] = {
-       { "cx700",      PCI_DEVICE_ID_VIA_CX700,    0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
-       { "vt8237s",    PCI_DEVICE_ID_VIA_8237S,    0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
-       { "vt6410",     PCI_DEVICE_ID_VIA_6410,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
-       { "vt8251",     PCI_DEVICE_ID_VIA_8251,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
-       { "vt8237",     PCI_DEVICE_ID_VIA_8237,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
-       { "vt8237a",    PCI_DEVICE_ID_VIA_8237A,    0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
-       { "vt8235",     PCI_DEVICE_ID_VIA_8235,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
-       { "vt8233a",    PCI_DEVICE_ID_VIA_8233A,    0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
-       { "vt8233c",    PCI_DEVICE_ID_VIA_8233C_0,  0x00, 0x2f, VIA_UDMA_100 },
-       { "vt8233",     PCI_DEVICE_ID_VIA_8233_0,   0x00, 0x2f, VIA_UDMA_100 },
-       { "vt8231",     PCI_DEVICE_ID_VIA_8231,     0x00, 0x2f, VIA_UDMA_100 },
-       { "vt82c686b",  PCI_DEVICE_ID_VIA_82C686,   0x40, 0x4f, VIA_UDMA_100 },
-       { "vt82c686a",  PCI_DEVICE_ID_VIA_82C686,   0x10, 0x2f, VIA_UDMA_66 },
-       { "vt82c686",   PCI_DEVICE_ID_VIA_82C686,   0x00, 0x0f, VIA_UDMA_33 | VIA_BAD_CLK66 },
-       { "vt82c596b",  PCI_DEVICE_ID_VIA_82C596,   0x10, 0x2f, VIA_UDMA_66 },
-       { "vt82c596a",  PCI_DEVICE_ID_VIA_82C596,   0x00, 0x0f, VIA_UDMA_33 | VIA_BAD_CLK66 },
-       { "vt82c586b",  PCI_DEVICE_ID_VIA_82C586_0, 0x47, 0x4f, VIA_UDMA_33 | VIA_SET_FIFO },
-       { "vt82c586b",  PCI_DEVICE_ID_VIA_82C586_0, 0x40, 0x46, VIA_UDMA_33 | VIA_SET_FIFO | VIA_BAD_PREQ },
-       { "vt82c586b",  PCI_DEVICE_ID_VIA_82C586_0, 0x30, 0x3f, VIA_UDMA_33 | VIA_SET_FIFO },
-       { "vt82c586a",  PCI_DEVICE_ID_VIA_82C586_0, 0x20, 0x2f, VIA_UDMA_33 | VIA_SET_FIFO },
-       { "vt82c586",   PCI_DEVICE_ID_VIA_82C586_0, 0x00, 0x0f, VIA_UDMA_NONE | VIA_SET_FIFO },
-       { "vt82c576",   PCI_DEVICE_ID_VIA_82C576,   0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO | VIA_NO_UNMASK },
-       { "vt82c576",   PCI_DEVICE_ID_VIA_82C576,   0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO | VIA_NO_UNMASK | VIA_BAD_ID },
+       { "cx700",      PCI_DEVICE_ID_VIA_CX700,    0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
+       { "vt8237s",    PCI_DEVICE_ID_VIA_8237S,    0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
+       { "vt6410",     PCI_DEVICE_ID_VIA_6410,     0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
+       { "vt8251",     PCI_DEVICE_ID_VIA_8251,     0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
+       { "vt8237",     PCI_DEVICE_ID_VIA_8237,     0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
+       { "vt8237a",    PCI_DEVICE_ID_VIA_8237A,    0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
+       { "vt8235",     PCI_DEVICE_ID_VIA_8235,     0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
+       { "vt8233a",    PCI_DEVICE_ID_VIA_8233A,    0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
+       { "vt8233c",    PCI_DEVICE_ID_VIA_8233C_0,  0x00, 0x2f, ATA_UDMA5, },
+       { "vt8233",     PCI_DEVICE_ID_VIA_8233_0,   0x00, 0x2f, ATA_UDMA5, },
+       { "vt8231",     PCI_DEVICE_ID_VIA_8231,     0x00, 0x2f, ATA_UDMA5, },
+       { "vt82c686b",  PCI_DEVICE_ID_VIA_82C686,   0x40, 0x4f, ATA_UDMA5, },
+       { "vt82c686a",  PCI_DEVICE_ID_VIA_82C686,   0x10, 0x2f, ATA_UDMA4, },
+       { "vt82c686",   PCI_DEVICE_ID_VIA_82C686,   0x00, 0x0f, ATA_UDMA2, VIA_BAD_CLK66 },
+       { "vt82c596b",  PCI_DEVICE_ID_VIA_82C596,   0x10, 0x2f, ATA_UDMA4, },
+       { "vt82c596a",  PCI_DEVICE_ID_VIA_82C596,   0x00, 0x0f, ATA_UDMA2, VIA_BAD_CLK66 },
+       { "vt82c586b",  PCI_DEVICE_ID_VIA_82C586_0, 0x47, 0x4f, ATA_UDMA2, VIA_SET_FIFO },
+       { "vt82c586b",  PCI_DEVICE_ID_VIA_82C586_0, 0x40, 0x46, ATA_UDMA2, VIA_SET_FIFO | VIA_BAD_PREQ },
+       { "vt82c586b",  PCI_DEVICE_ID_VIA_82C586_0, 0x30, 0x3f, ATA_UDMA2, VIA_SET_FIFO },
+       { "vt82c586a",  PCI_DEVICE_ID_VIA_82C586_0, 0x20, 0x2f, ATA_UDMA2, VIA_SET_FIFO },
+       { "vt82c586",   PCI_DEVICE_ID_VIA_82C586_0, 0x00, 0x0f,      0x00, VIA_SET_FIFO },
+       { "vt82c576",   PCI_DEVICE_ID_VIA_82C576,   0x00, 0x2f,      0x00, VIA_SET_FIFO | VIA_NO_UNMASK },
+       { "vt82c576",   PCI_DEVICE_ID_VIA_82C576,   0x00, 0x2f,      0x00, VIA_SET_FIFO | VIA_NO_UNMASK | VIA_BAD_ID },
        { NULL }
 };
 
 static unsigned int via_clock;
-static char *via_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" };
+static char *via_dma[] = { "16", "25", "33", "44", "66", "100", "133" };
 
 struct via82cxxx_dev
 {
@@ -140,12 +136,12 @@ static void via_set_speed(ide_hwif_t *hwif, u8 dn, struct ide_timing *timing)
        pci_write_config_byte(dev, VIA_DRIVE_TIMING + (3 - dn),
                ((FIT(timing->active, 1, 16) - 1) << 4) | (FIT(timing->recover, 1, 16) - 1));
 
-       switch (vdev->via_config->flags & VIA_UDMA) {
-               case VIA_UDMA_33:  t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break;
-               case VIA_UDMA_66:  t = timing->udma ? (0xe8 | (FIT(timing->udma, 2, 9) - 2)) : 0x0f; break;
-               case VIA_UDMA_100: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 9) - 2)) : 0x07; break;
-               case VIA_UDMA_133: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 9) - 2)) : 0x07; break;
-               default: return;
+       switch (vdev->via_config->udma_mask) {
+       case ATA_UDMA2: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break;
+       case ATA_UDMA4: t = timing->udma ? (0xe8 | (FIT(timing->udma, 2, 9) - 2)) : 0x0f; break;
+       case ATA_UDMA5: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 9) - 2)) : 0x07; break;
+       case ATA_UDMA6: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 9) - 2)) : 0x07; break;
+       default: return;
        }
 
        pci_write_config_byte(dev, VIA_UDMA_TIMING + (3 - dn), t);
@@ -173,12 +169,12 @@ static int via_set_drive(ide_drive_t *drive, u8 speed)
 
        T = 1000000000 / via_clock;
 
-       switch (vdev->via_config->flags & VIA_UDMA) {
-               case VIA_UDMA_33:   UT = T;   break;
-               case VIA_UDMA_66:   UT = T/2; break;
-               case VIA_UDMA_100:  UT = T/3; break;
-               case VIA_UDMA_133:  UT = T/4; break;
-               default: UT = T;
+       switch (vdev->via_config->udma_mask) {
+       case ATA_UDMA2: UT = T;   break;
+       case ATA_UDMA4: UT = T/2; break;
+       case ATA_UDMA5: UT = T/3; break;
+       case ATA_UDMA6: UT = T/4; break;
+       default:        UT = T;
        }
 
        ide_timing_compute(drive, speed, &t, T, UT);
@@ -208,8 +204,7 @@ static int via_set_drive(ide_drive_t *drive, u8 speed)
 static void via82cxxx_tune_drive(ide_drive_t *drive, u8 pio)
 {
        if (pio == 255) {
-               via_set_drive(drive,
-                       ide_find_best_mode(drive, XFER_PIO | XFER_EPIO));
+               via_set_drive(drive, ide_find_best_pio_mode(drive));
                return;
        }
 
@@ -226,16 +221,10 @@ static void via82cxxx_tune_drive(ide_drive_t *drive, u8 pio)
  
 static int via82cxxx_ide_dma_check (ide_drive_t *drive)
 {
-       ide_hwif_t *hwif = HWIF(drive);
-       struct via82cxxx_dev *vdev = pci_get_drvdata(hwif->pci_dev);
-       u16 w80 = hwif->udma_four;
+       u8 speed = ide_max_dma_mode(drive);
 
-       u16 speed = ide_find_best_mode(drive,
-               XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA |
-               (vdev->via_config->flags & VIA_UDMA ? XFER_UDMA : 0) |
-               (w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_66 ? XFER_UDMA_66 : 0) |
-               (w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_100 ? XFER_UDMA_100 : 0) |
-               (w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_133 ? XFER_UDMA_133 : 0));
+       if (speed == 0)
+               speed = ide_find_best_pio_mode(drive);
 
        via_set_drive(drive, speed);
 
@@ -248,16 +237,14 @@ static int via82cxxx_ide_dma_check (ide_drive_t *drive)
 static struct via_isa_bridge *via_config_find(struct pci_dev **isa)
 {
        struct via_isa_bridge *via_config;
-       u8 t;
 
        for (via_config = via_isa_bridges; via_config->id; via_config++)
                if ((*isa = pci_get_device(PCI_VENDOR_ID_VIA +
                        !!(via_config->flags & VIA_BAD_ID),
                        via_config->id, NULL))) {
 
-                       pci_read_config_byte(*isa, PCI_REVISION_ID, &t);
-                       if (t >= via_config->rev_min &&
-                           t <= via_config->rev_max)
+                       if ((*isa)->revision >= via_config->rev_min &&
+                           (*isa)->revision <= via_config->rev_max)
                                break;
                        pci_dev_put(*isa);
                }
@@ -272,8 +259,8 @@ static void __devinit via_cable_detect(struct via82cxxx_dev *vdev, u32 u)
 {
        int i;
 
-       switch (vdev->via_config->flags & VIA_UDMA) {
-               case VIA_UDMA_66:
+       switch (vdev->via_config->udma_mask) {
+               case ATA_UDMA4:
                        for (i = 24; i >= 0; i -= 8)
                                if (((u >> (i & 16)) & 8) &&
                                    ((u >> i) & 0x20) &&
@@ -286,7 +273,7 @@ static void __devinit via_cable_detect(struct via82cxxx_dev *vdev, u32 u)
                                }
                        break;
 
-               case VIA_UDMA_100:
+               case ATA_UDMA5:
                        for (i = 24; i >= 0; i -= 8)
                                if (((u >> i) & 0x10) ||
                                    (((u >> i) & 0x20) &&
@@ -298,7 +285,7 @@ static void __devinit via_cable_detect(struct via82cxxx_dev *vdev, u32 u)
                                }
                        break;
 
-               case VIA_UDMA_133:
+               case ATA_UDMA6:
                        for (i = 24; i >= 0; i -= 8)
                                if (((u >> i) & 0x10) ||
                                    (((u >> i) & 0x20) &&
@@ -353,7 +340,7 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const
 
        via_cable_detect(vdev, u);
 
-       if ((via_config->flags & VIA_UDMA) == VIA_UDMA_66) {
+       if (via_config->udma_mask == ATA_UDMA4) {
                /* Enable Clk66 */
                pci_write_config_dword(dev, VIA_UDMA_TIMING, u|0x80008);
        } else if (via_config->flags & VIA_BAD_CLK66) {
@@ -415,17 +402,54 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const
         * Print the boot message.
         */
 
-       pci_read_config_byte(isa, PCI_REVISION_ID, &t);
-       printk(KERN_INFO "VP_IDE: VIA %s (rev %02x) IDE %s "
+       printk(KERN_INFO "VP_IDE: VIA %s (rev %02x) IDE %sDMA%s "
                "controller on pci%s\n",
-               via_config->name, t,
-               via_dma[via_config->flags & VIA_UDMA],
+               via_config->name, isa->revision,
+               via_config->udma_mask ? "U" : "MW",
+               via_dma[via_config->udma_mask ?
+                       (fls(via_config->udma_mask) - 1) : 0],
                pci_name(dev));
 
        pci_dev_put(isa);
        return 0;
 }
 
+/*
+ *     Cable special cases
+ */
+
+static struct dmi_system_id cable_dmi_table[] = {
+       {
+               .ident = "Acer Ferrari 3400",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "Acer,Inc."),
+                       DMI_MATCH(DMI_BOARD_NAME, "Ferrari 3400"),
+               },
+       },
+       { }
+};
+
+static int via_cable_override(void)
+{
+       /* Systems by DMI */
+       if (dmi_check_system(cable_dmi_table))
+               return 1;
+       return 0;
+}
+
+static u8 __devinit via82cxxx_cable_detect(ide_hwif_t *hwif)
+{
+       struct via82cxxx_dev *vdev = pci_get_drvdata(hwif->pci_dev);
+
+       if (via_cable_override())
+               return ATA_CBL_PATA40_SHORT;
+
+       if ((vdev->via_80w >> hwif->channel) & 1)
+               return ATA_CBL_PATA80;
+       else
+               return ATA_CBL_PATA40;
+}
+
 static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
 {
        struct via82cxxx_dev *vdev = pci_get_drvdata(hwif->pci_dev);
@@ -454,12 +478,14 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
                return;
 
        hwif->atapi_dma = 1;
-       hwif->ultra_mask = 0x7f;
+
+       hwif->ultra_mask = vdev->via_config->udma_mask;
        hwif->mwdma_mask = 0x07;
        hwif->swdma_mask = 0x07;
 
-       if (!hwif->udma_four)
-               hwif->udma_four = (vdev->via_80w >> hwif->channel) & 1;
+       if (hwif->cbl != ATA_CBL_PATA40_SHORT)
+               hwif->cbl = via82cxxx_cable_detect(hwif);
+
        hwif->ide_dma_check = &via82cxxx_ide_dma_check;
        if (!noautodma)
                hwif->autodma = 1;
index 45fc36f0f219feaba9649978c69d697966e2ba57..e46f47206542bfec313086e5feab745b62131562 100644 (file)
@@ -942,8 +942,8 @@ pmac_ide_tune_chipset (ide_drive_t *drive, byte speed)
                                return 1;
                case XFER_UDMA_4:
                case XFER_UDMA_3:
-                       if (HWIF(drive)->udma_four == 0)
-                               return 1;               
+                       if (drive->hwif->cbl != ATA_CBL_PATA80)
+                               return 1;
                case XFER_UDMA_2:
                case XFER_UDMA_1:
                case XFER_UDMA_0:
@@ -1244,7 +1244,7 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
        hwif->chipset = ide_pmac;
        hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET] || pmif->mediabay;
        hwif->hold = pmif->mediabay;
-       hwif->udma_four = pmif->cable_80;
+       hwif->cbl = pmif->cable_80 ? ATA_CBL_PATA80 : ATA_CBL_PATA40;
        hwif->drives[0].unmask = 1;
        hwif->drives[1].unmask = 1;
        hwif->tuneproc = pmac_ide_tuneproc;
@@ -1821,28 +1821,11 @@ pmac_ide_dma_check(ide_drive_t *drive)
                enable = 0;
 
        if (enable) {
-               short mode;
-               
-               map = XFER_MWDMA;
-               if (pmif->kind == controller_kl_ata4
-                   || pmif->kind == controller_un_ata6
-                   || pmif->kind == controller_k2_ata6
-                   || pmif->kind == controller_sh_ata6) {
-                       map |= XFER_UDMA;
-                       if (pmif->cable_80) {
-                               map |= XFER_UDMA_66;
-                               if (pmif->kind == controller_un_ata6 ||
-                                   pmif->kind == controller_k2_ata6 ||
-                                   pmif->kind == controller_sh_ata6)
-                                       map |= XFER_UDMA_100;
-                               if (pmif->kind == controller_sh_ata6)
-                                       map |= XFER_UDMA_133;
-                       }
-               }
-               mode = ide_find_best_mode(drive, map);
-               if (mode & XFER_UDMA)
+               u8 mode = ide_max_dma_mode(drive);
+
+               if (mode >= XFER_UDMA_0)
                        drive->using_dma = pmac_ide_udma_enable(drive, mode);
-               else if (mode & XFER_MWDMA)
+               else if (mode >= XFER_MW_DMA_0)
                        drive->using_dma = pmac_ide_mdma_enable(drive, mode);
                hwif->OUTB(0, IDE_CONTROL_REG);
                /* Apply settings to controller */
@@ -2004,20 +1987,19 @@ static void pmac_ide_dma_host_on(ide_drive_t *drive)
 {
 }
 
-static int
-pmac_ide_dma_lostirq (ide_drive_t *drive)
+static void
+pmac_ide_dma_lost_irq (ide_drive_t *drive)
 {
        pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
        volatile struct dbdma_regs __iomem *dma;
        unsigned long status;
 
        if (pmif == NULL)
-               return 0;
+               return;
        dma = pmif->dma_regs;
 
        status = readl(&dma->status);
        printk(KERN_ERR "ide-pmac lost interrupt, dma status: %lx\n", status);
-       return 0;
 }
 
 /*
@@ -2057,8 +2039,8 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
        hwif->ide_dma_test_irq = &pmac_ide_dma_test_irq;
        hwif->dma_host_off = &pmac_ide_dma_host_off;
        hwif->dma_host_on = &pmac_ide_dma_host_on;
-       hwif->ide_dma_timeout = &__ide_dma_timeout;
-       hwif->ide_dma_lostirq = &pmac_ide_dma_lostirq;
+       hwif->dma_timeout = &ide_dma_timeout;
+       hwif->dma_lost_irq = &pmac_ide_dma_lost_irq;
 
        hwif->atapi_dma = 1;
        switch(pmif->kind) {
index 20814137761220e5ebbf00dd86e2ee0e21421a3e..65722117ab6e449b7cf2445a286d1e63131fcb4f 100644 (file)
@@ -2280,7 +2280,7 @@ static void dv1394_remove_host(struct hpsb_host *host)
        } while (video);
 
        if (found_ohci_card)
-               class_device_destroy(hpsb_protocol_class, MKDEV(IEEE1394_MAJOR,
+               device_destroy(hpsb_protocol_class, MKDEV(IEEE1394_MAJOR,
                           IEEE1394_MINOR_BLOCK_DV1394 * 16 + (host->id << 2)));
 }
 
@@ -2295,9 +2295,9 @@ static void dv1394_add_host(struct hpsb_host *host)
 
        ohci = (struct ti_ohci *)host->hostdata;
 
-       class_device_create(hpsb_protocol_class, NULL, MKDEV(
-               IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)), 
-               NULL, "dv1394-%d", id);
+       device_create(hpsb_protocol_class, NULL, MKDEV(
+               IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)),
+               "dv1394-%d", id);
 
        dv1394_init(ohci, DV1394_NTSC, MODE_RECEIVE);
        dv1394_init(ohci, DV1394_NTSC, MODE_TRANSMIT);
index 7c13fb3c167b02b541834283d272d1a5a17f5860..93362eed94eda0be345958ab069f0f78935c6443 100644 (file)
@@ -599,9 +599,7 @@ static void ether1394_add_host(struct hpsb_host *host)
        }
 
        SET_MODULE_OWNER(dev);
-
-       /* This used to be &host->device in Linux 2.6.20 and before. */
-       SET_NETDEV_DEV(dev, host->device.parent);
+       SET_NETDEV_DEV(dev, &host->device);
 
        priv = netdev_priv(dev);
        INIT_LIST_HEAD(&priv->ip_node_list);
index 83a49331275188e265346f2ed70e753c2f52a010..b6425469b6ee455ef0690f1bb5dc7653a15e37d6 100644 (file)
@@ -483,37 +483,6 @@ int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host,
        return retval;
 }
 
-/**
- * hpsb_listen_channel - enable receving a certain isochronous channel
- *
- * Reception is handled through the @hl's iso_receive op.
- */
-int hpsb_listen_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
-                       unsigned int channel)
-{
-       if (channel > 63) {
-               HPSB_ERR("%s called with invalid channel", __FUNCTION__);
-               return -EINVAL;
-       }
-       if (host->iso_listen_count[channel]++ == 0)
-               return host->driver->devctl(host, ISO_LISTEN_CHANNEL, channel);
-       return 0;
-}
-
-/**
- * hpsb_unlisten_channel - disable receving a certain isochronous channel
- */
-void hpsb_unlisten_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
-                          unsigned int channel)
-{
-       if (channel > 63) {
-               HPSB_ERR("%s called with invalid channel", __FUNCTION__);
-               return;
-       }
-       if (--host->iso_listen_count[channel] == 0)
-               host->driver->devctl(host, ISO_UNLISTEN_CHANNEL, channel);
-}
-
 static void init_hpsb_highlevel(struct hpsb_host *host)
 {
        INIT_LIST_HEAD(&dummy_zero_addr.host_list);
@@ -570,20 +539,6 @@ void highlevel_host_reset(struct hpsb_host *host)
        read_unlock_irqrestore(&hl_irqs_lock, flags);
 }
 
-void highlevel_iso_receive(struct hpsb_host *host, void *data, size_t length)
-{
-       unsigned long flags;
-       struct hpsb_highlevel *hl;
-       int channel = (((quadlet_t *)data)[0] >> 8) & 0x3f;
-
-       read_lock_irqsave(&hl_irqs_lock, flags);
-       list_for_each_entry(hl, &hl_irqs, irq_list) {
-               if (hl->iso_receive)
-                       hl->iso_receive(host, channel, data, length);
-       }
-       read_unlock_irqrestore(&hl_irqs_lock, flags);
-}
-
 void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction,
                           void *data, size_t length)
 {
index 63474f7ee69d5ac48bf1a6d8670e7450fcb53cc7..eb9fe321e09a37507c6527df82c7abd352db0b2a 100644 (file)
@@ -26,9 +26,7 @@ struct hpsb_address_serve {
 struct hpsb_highlevel {
        const char *name;
 
-       /* Any of the following pointers can legally be NULL, except for
-        * iso_receive which can only be NULL when you don't request
-        * channels. */
+       /* Any of the following pointers can legally be NULL. */
 
        /* New host initialized.  Will also be called during
         * hpsb_register_highlevel for all hosts already installed. */
@@ -43,13 +41,6 @@ struct hpsb_highlevel {
         * You can not expect to be able to do stock hpsb_reads. */
        void (*host_reset)(struct hpsb_host *host);
 
-       /* An isochronous packet was received.  Channel contains the channel
-        * number for your convenience, it is also contained in the included
-        * packet header (first quadlet, CRCs are missing).  You may get called
-        * for channel/host combinations you did not request. */
-       void (*iso_receive)(struct hpsb_host *host, int channel,
-                           quadlet_t *data, size_t length);
-
        /* A write request was received on either the FCP_COMMAND (direction =
         * 0) or the FCP_RESPONSE (direction = 1) register.  The cts arg
         * contains the cts field (first byte of data). */
@@ -109,7 +100,6 @@ int highlevel_lock(struct hpsb_host *host, int nodeid, quadlet_t *store,
 int highlevel_lock64(struct hpsb_host *host, int nodeid, octlet_t *store,
                     u64 addr, octlet_t data, octlet_t arg, int ext_tcode,
                     u16 flags);
-void highlevel_iso_receive(struct hpsb_host *host, void *data, size_t length);
 void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction,
                           void *data, size_t length);
 
@@ -125,10 +115,6 @@ int hpsb_register_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host,
                            struct hpsb_address_ops *ops, u64 start, u64 end);
 int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host,
                              u64 start);
-int hpsb_listen_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
-                       unsigned int channel);
-void hpsb_unlisten_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
-                          unsigned int channel);
 
 void *hpsb_get_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host);
 void *hpsb_create_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host,
index bd0755c789c52d469fd85aa842398117bccc0909..8dd09d8504196eecbe750887ec23f702667b105d 100644 (file)
@@ -154,15 +154,16 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
 
        memcpy(&h->device, &nodemgr_dev_template_host, sizeof(h->device));
        h->device.parent = dev;
+       set_dev_node(&h->device, dev_to_node(dev));
        snprintf(h->device.bus_id, BUS_ID_SIZE, "fw-host%d", h->id);
 
-       h->class_dev.dev = &h->device;
-       h->class_dev.class = &hpsb_host_class;
-       snprintf(h->class_dev.class_id, BUS_ID_SIZE, "fw-host%d", h->id);
+       h->host_dev.parent = &h->device;
+       h->host_dev.class = &hpsb_host_class;
+       snprintf(h->host_dev.bus_id, BUS_ID_SIZE, "fw-host%d", h->id);
 
        if (device_register(&h->device))
                goto fail;
-       if (class_device_register(&h->class_dev)) {
+       if (device_register(&h->host_dev)) {
                device_unregister(&h->device);
                goto fail;
        }
@@ -202,7 +203,7 @@ void hpsb_remove_host(struct hpsb_host *host)
        host->driver = &dummy_driver;
        highlevel_remove_host(host);
 
-       class_device_unregister(&host->class_dev);
+       device_unregister(&host->host_dev);
        device_unregister(&host->device);
 }
 
index feb55d032294f0559e17d655dbe20d501d311a47..e4e8aeb4d7788d2caf2ef7d5821dbf77a038c27d 100644 (file)
@@ -28,8 +28,6 @@ struct hpsb_host {
        struct timer_list timeout;
        unsigned long timeout_interval;
 
-       unsigned char iso_listen_count[64];
-
        int node_count;      /* number of identified nodes on this bus */
        int selfid_count;    /* total number of SelfIDs received */
        int nodes_active;    /* number of nodes with active link layer */
@@ -57,7 +55,7 @@ struct hpsb_host {
        struct hpsb_host_driver *driver;
        struct pci_dev *pdev;
        struct device device;
-       struct class_device class_dev;
+       struct device host_dev;
 
        struct delayed_work delayed_reset;
        unsigned config_roms:31;
@@ -99,12 +97,6 @@ enum devctl_cmd {
        /* Cancel all outstanding async requests without resetting the bus.
         * Return void. */
        CANCEL_REQUESTS,
-
-       /* Start or stop receiving isochronous channel in arg.  Return void.
-        * This acts as an optimization hint, hosts are not required not to
-        * listen on unrequested channels. */
-       ISO_LISTEN_CHANNEL,
-       ISO_UNLISTEN_CHANNEL
 };
 
 enum isoctl_cmd {
index 8f71b6a06aa0b45cbb8dcef0aca25e4ecfb33ddd..0fc8c6e559e4a64d160bfbc0c7fcd4a04d8538e5 100644 (file)
@@ -1028,11 +1028,6 @@ void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size,
                handle_incoming_packet(host, tcode, data, size, write_acked);
                break;
 
-
-       case TCODE_ISO_DATA:
-               highlevel_iso_receive(host, data, size);
-               break;
-
        case TCODE_CYCLE_START:
                /* simply ignore this packet if it is passed on */
                break;
@@ -1316,7 +1311,6 @@ EXPORT_SYMBOL(hpsb_make_streampacket);
 EXPORT_SYMBOL(hpsb_make_lockpacket);
 EXPORT_SYMBOL(hpsb_make_lock64packet);
 EXPORT_SYMBOL(hpsb_make_phypacket);
-EXPORT_SYMBOL(hpsb_make_isopacket);
 EXPORT_SYMBOL(hpsb_read);
 EXPORT_SYMBOL(hpsb_write);
 EXPORT_SYMBOL(hpsb_packet_success);
@@ -1327,8 +1321,6 @@ EXPORT_SYMBOL(hpsb_unregister_highlevel);
 EXPORT_SYMBOL(hpsb_register_addrspace);
 EXPORT_SYMBOL(hpsb_unregister_addrspace);
 EXPORT_SYMBOL(hpsb_allocate_and_register_addrspace);
-EXPORT_SYMBOL(hpsb_listen_channel);
-EXPORT_SYMBOL(hpsb_unlisten_channel);
 EXPORT_SYMBOL(hpsb_get_hostinfo);
 EXPORT_SYMBOL(hpsb_create_hostinfo);
 EXPORT_SYMBOL(hpsb_destroy_hostinfo);
index ad526523d0ef85fa556beda8b8b63d2e01fab424..21d50f73a210cbadfc6c39e128da8e06d0fa9310 100644 (file)
@@ -24,9 +24,8 @@ struct hpsb_packet {
 
        nodeid_t node_id;
 
-       /* Async and Iso types should be clear, raw means send-as-is, do not
-        * CRC!  Byte swapping shall still be done in this case. */
-       enum { hpsb_async, hpsb_iso, hpsb_raw } __attribute__((packed)) type;
+       /* hpsb_raw = send as-is, do not CRC (but still byte-swap it) */
+       enum { hpsb_async, hpsb_raw } __attribute__((packed)) type;
 
        /* Okay, this is core internal and a no care for hosts.
         * queued   = queued for sending
@@ -37,7 +36,7 @@ struct hpsb_packet {
                hpsb_unused, hpsb_queued, hpsb_pending, hpsb_complete
        } __attribute__((packed)) state;
 
-       /* These are core internal. */
+       /* These are core-internal. */
        signed char tlabel;
        signed char ack_code;
        unsigned char tcode;
@@ -62,11 +61,15 @@ struct hpsb_packet {
        /* Store jiffies for implementing bus timeouts. */
        unsigned long sendtime;
 
-       /* Sizes are in bytes. *data can be DMA-mapped. */
+       /* Core-internal.  */
        size_t allocated_data_size;     /* as allocated */
+
+       /* Sizes are in bytes. To be set by caller of hpsb_alloc_packet. */
        size_t data_size;               /* as filled in */
        size_t header_size;             /* as filled in, not counting the CRC */
-       quadlet_t *data;
+
+       /* Buffers */
+       quadlet_t *data;                /* can be DMA-mapped */
        quadlet_t header[5];
        quadlet_t embedded_data[0];     /* keep as last member */
 };
index 40078ce930c86035ea2d5453ebc0f85851dd1fa1..c39c70a8aa9fce1e8eae54cdd0df6ab3a0c4a1e5 100644 (file)
@@ -89,18 +89,6 @@ static void fill_async_lock(struct hpsb_packet *packet, u64 addr, int extcode,
        packet->expect_response = 1;
 }
 
-static void fill_iso_packet(struct hpsb_packet *packet, int length, int channel,
-                           int tag, int sync)
-{
-       packet->header[0] = (length << 16) | (tag << 14) | (channel << 8)
-           | (TCODE_ISO_DATA << 4) | sync;
-
-       packet->header_size = 4;
-       packet->data_size = length;
-       packet->type = hpsb_iso;
-       packet->tcode = TCODE_ISO_DATA;
-}
-
 static void fill_phy_packet(struct hpsb_packet *packet, quadlet_t data)
 {
        packet->header[0] = data;
@@ -491,24 +479,6 @@ struct hpsb_packet *hpsb_make_phypacket(struct hpsb_host *host, quadlet_t data)
        return p;
 }
 
-struct hpsb_packet *hpsb_make_isopacket(struct hpsb_host *host,
-                                       int length, int channel,
-                                       int tag, int sync)
-{
-       struct hpsb_packet *p;
-
-       p = hpsb_alloc_packet(length);
-       if (!p)
-               return NULL;
-
-       p->host = host;
-       fill_iso_packet(p, length, channel, tag, sync);
-
-       p->generation = get_hpsb_generation(host);
-
-       return p;
-}
-
 /*
  * FIXME - these functions should probably read from / write to user space to
  * avoid in kernel buffers for user space callers
index 86b8ee692ea7711bc868c407e816871ce7b6c969..d2d5bc3546d74093b2fe0ce56ef913b63ef6648e 100644 (file)
@@ -19,8 +19,6 @@ struct hpsb_packet *hpsb_make_lock64packet(struct hpsb_host *host,
                                           nodeid_t node, u64 addr, int extcode,
                                           octlet_t *data, octlet_t arg);
 struct hpsb_packet *hpsb_make_phypacket(struct hpsb_host *host, quadlet_t data);
-struct hpsb_packet *hpsb_make_isopacket(struct hpsb_host *host, int length,
-                                       int channel, int tag, int sync);
 struct hpsb_packet *hpsb_make_writepacket(struct hpsb_host *host,
                                          nodeid_t node, u64 addr,
                                          quadlet_t *buffer, size_t length);
index 81b3864d2ba785b51b25d597965a608ff7879fcb..c4d3d4131f01728725496526687de8a55906bc20 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/mutex.h>
 #include <linux/freezer.h>
 #include <asm/atomic.h>
+#include <asm/semaphore.h>
 
 #include "csr.h"
 #include "highlevel.h"
@@ -145,8 +146,6 @@ static struct csr1212_bus_ops nodemgr_csr_ops = {
  * but now we are much simpler because of the LDM.
  */
 
-static DEFINE_MUTEX(nodemgr_serialize);
-
 struct host_info {
        struct hpsb_host *host;
        struct list_head list;
@@ -154,7 +153,7 @@ struct host_info {
 };
 
 static int nodemgr_bus_match(struct device * dev, struct device_driver * drv);
-static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp,
+static int nodemgr_uevent(struct device *dev, char **envp, int num_envp,
                          char *buffer, int buffer_size);
 static void nodemgr_resume_ne(struct node_entry *ne);
 static void nodemgr_remove_ne(struct node_entry *ne);
@@ -165,37 +164,38 @@ struct bus_type ieee1394_bus_type = {
        .match          = nodemgr_bus_match,
 };
 
-static void host_cls_release(struct class_device *class_dev)
+static void host_cls_release(struct device *dev)
 {
-       put_device(&container_of((class_dev), struct hpsb_host, class_dev)->device);
+       put_device(&container_of((dev), struct hpsb_host, host_dev)->device);
 }
 
 struct class hpsb_host_class = {
        .name           = "ieee1394_host",
-       .release        = host_cls_release,
+       .dev_release    = host_cls_release,
 };
 
-static void ne_cls_release(struct class_device *class_dev)
+static void ne_cls_release(struct device *dev)
 {
-       put_device(&container_of((class_dev), struct node_entry, class_dev)->device);
+       put_device(&container_of((dev), struct node_entry, node_dev)->device);
 }
 
 static struct class nodemgr_ne_class = {
        .name           = "ieee1394_node",
-       .release        = ne_cls_release,
+       .dev_release    = ne_cls_release,
 };
 
-static void ud_cls_release(struct class_device *class_dev)
+static void ud_cls_release(struct device *dev)
 {
-       put_device(&container_of((class_dev), struct unit_directory, class_dev)->device);
+       put_device(&container_of((dev), struct unit_directory, unit_dev)->device);
 }
 
 /* The name here is only so that unit directory hotplug works with old
- * style hotplug, which only ever did unit directories anyway. */
+ * style hotplug, which only ever did unit directories anyway.
+ */
 static struct class nodemgr_ud_class = {
        .name           = "ieee1394",
-       .release        = ud_cls_release,
-       .uevent         = nodemgr_uevent,
+       .dev_release    = ud_cls_release,
+       .dev_uevent     = nodemgr_uevent,
 };
 
 static struct hpsb_highlevel nodemgr_highlevel;
@@ -730,11 +730,11 @@ static DEFINE_MUTEX(nodemgr_serialize_remove_uds);
 
 static void nodemgr_remove_uds(struct node_entry *ne)
 {
-       struct class_device *cdev;
+       struct device *dev;
        struct unit_directory *tmp, *ud;
 
-       /* Iteration over nodemgr_ud_class.children has to be protected by
-        * nodemgr_ud_class.sem, but class_device_unregister() will eventually
+       /* Iteration over nodemgr_ud_class.devices has to be protected by
+        * nodemgr_ud_class.sem, but device_unregister() will eventually
         * take nodemgr_ud_class.sem too. Therefore pick out one ud at a time,
         * release the semaphore, and then unregister the ud. Since this code
         * may be called from other contexts besides the knodemgrds, protect the
@@ -744,9 +744,9 @@ static void nodemgr_remove_uds(struct node_entry *ne)
        for (;;) {
                ud = NULL;
                down(&nodemgr_ud_class.sem);
-               list_for_each_entry(cdev, &nodemgr_ud_class.children, node) {
-                       tmp = container_of(cdev, struct unit_directory,
-                                          class_dev);
+               list_for_each_entry(dev, &nodemgr_ud_class.devices, node) {
+                       tmp = container_of(dev, struct unit_directory,
+                                          unit_dev);
                        if (tmp->ne == ne) {
                                ud = tmp;
                                break;
@@ -755,7 +755,7 @@ static void nodemgr_remove_uds(struct node_entry *ne)
                up(&nodemgr_ud_class.sem);
                if (ud == NULL)
                        break;
-               class_device_unregister(&ud->class_dev);
+               device_unregister(&ud->unit_dev);
                device_unregister(&ud->device);
        }
        mutex_unlock(&nodemgr_serialize_remove_uds);
@@ -772,10 +772,9 @@ static void nodemgr_remove_ne(struct node_entry *ne)
 
        HPSB_DEBUG("Node removed: ID:BUS[" NODE_BUS_FMT "]  GUID[%016Lx]",
                   NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid);
-
        nodemgr_remove_uds(ne);
 
-       class_device_unregister(&ne->class_dev);
+       device_unregister(&ne->node_dev);
        device_unregister(dev);
 
        put_device(dev);
@@ -783,7 +782,9 @@ static void nodemgr_remove_ne(struct node_entry *ne)
 
 static int __nodemgr_remove_host_dev(struct device *dev, void *data)
 {
-       nodemgr_remove_ne(container_of(dev, struct node_entry, device));
+       if (dev->bus == &ieee1394_bus_type)
+               nodemgr_remove_ne(container_of(dev, struct node_entry,
+                                 device));
        return 0;
 }
 
@@ -850,14 +851,14 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, struct csr1212_csr
        snprintf(ne->device.bus_id, BUS_ID_SIZE, "%016Lx",
                 (unsigned long long)(ne->guid));
 
-       ne->class_dev.dev = &ne->device;
-       ne->class_dev.class = &nodemgr_ne_class;
-       snprintf(ne->class_dev.class_id, BUS_ID_SIZE, "%016Lx",
-                (unsigned long long)(ne->guid));
+       ne->node_dev.parent = &ne->device;
+       ne->node_dev.class = &nodemgr_ne_class;
+       snprintf(ne->node_dev.bus_id, BUS_ID_SIZE, "%016Lx",
+               (unsigned long long)(ne->guid));
 
        if (device_register(&ne->device))
                goto fail_devreg;
-       if (class_device_register(&ne->class_dev))
+       if (device_register(&ne->node_dev))
                goto fail_classdevreg;
        get_device(&ne->device);
 
@@ -885,12 +886,12 @@ fail_alloc:
 
 static struct node_entry *find_entry_by_guid(u64 guid)
 {
-       struct class_device *cdev;
+       struct device *dev;
        struct node_entry *ne, *ret_ne = NULL;
 
        down(&nodemgr_ne_class.sem);
-       list_for_each_entry(cdev, &nodemgr_ne_class.children, node) {
-               ne = container_of(cdev, struct node_entry, class_dev);
+       list_for_each_entry(dev, &nodemgr_ne_class.devices, node) {
+               ne = container_of(dev, struct node_entry, node_dev);
 
                if (ne->guid == guid) {
                        ret_ne = ne;
@@ -906,12 +907,12 @@ static struct node_entry *find_entry_by_guid(u64 guid)
 static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host,
                                               nodeid_t nodeid)
 {
-       struct class_device *cdev;
+       struct device *dev;
        struct node_entry *ne, *ret_ne = NULL;
 
        down(&nodemgr_ne_class.sem);
-       list_for_each_entry(cdev, &nodemgr_ne_class.children, node) {
-               ne = container_of(cdev, struct node_entry, class_dev);
+       list_for_each_entry(dev, &nodemgr_ne_class.devices, node) {
+               ne = container_of(dev, struct node_entry, node_dev);
 
                if (ne->host == host && ne->nodeid == nodeid) {
                        ret_ne = ne;
@@ -935,14 +936,14 @@ static void nodemgr_register_device(struct node_entry *ne,
        snprintf(ud->device.bus_id, BUS_ID_SIZE, "%s-%u",
                 ne->device.bus_id, ud->id);
 
-       ud->class_dev.dev = &ud->device;
-       ud->class_dev.class = &nodemgr_ud_class;
-       snprintf(ud->class_dev.class_id, BUS_ID_SIZE, "%s-%u",
+       ud->unit_dev.parent = &ud->device;
+       ud->unit_dev.class = &nodemgr_ud_class;
+       snprintf(ud->unit_dev.bus_id, BUS_ID_SIZE, "%s-%u",
                 ne->device.bus_id, ud->id);
 
        if (device_register(&ud->device))
                goto fail_devreg;
-       if (class_device_register(&ud->class_dev))
+       if (device_register(&ud->unit_dev))
                goto fail_classdevreg;
        get_device(&ud->device);
 
@@ -1159,7 +1160,7 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent
 
 #ifdef CONFIG_HOTPLUG
 
-static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp,
+static int nodemgr_uevent(struct device *dev, char **envp, int num_envp,
                          char *buffer, int buffer_size)
 {
        struct unit_directory *ud;
@@ -1169,10 +1170,10 @@ static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp,
        /* ieee1394:venNmoNspNverN */
        char buf[8 + 1 + 3 + 8 + 2 + 8 + 2 + 8 + 3 + 8 + 1];
 
-       if (!cdev)
+       if (!dev)
                return -ENODEV;
 
-       ud = container_of(cdev, struct unit_directory, class_dev);
+       ud = container_of(dev, struct unit_directory, unit_dev);
 
        if (ud->ne->in_limbo || ud->ignore_driver)
                return -ENODEV;
@@ -1207,7 +1208,7 @@ do {                                                              \
 
 #else
 
-static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp,
+static int nodemgr_uevent(struct device *dev, char **envp, int num_envp,
                          char *buffer, int buffer_size)
 {
        return -ENODEV;
@@ -1378,8 +1379,10 @@ static void nodemgr_node_scan(struct host_info *hi, int generation)
 
 static void nodemgr_suspend_ne(struct node_entry *ne)
 {
-       struct class_device *cdev;
+       struct device *dev;
        struct unit_directory *ud;
+       struct device_driver *drv;
+       int error;
 
        HPSB_DEBUG("Node suspended: ID:BUS[" NODE_BUS_FMT "]  GUID[%016Lx]",
                   NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid);
@@ -1388,15 +1391,24 @@ static void nodemgr_suspend_ne(struct node_entry *ne)
        WARN_ON(device_create_file(&ne->device, &dev_attr_ne_in_limbo));
 
        down(&nodemgr_ud_class.sem);
-       list_for_each_entry(cdev, &nodemgr_ud_class.children, node) {
-               ud = container_of(cdev, struct unit_directory, class_dev);
+       list_for_each_entry(dev, &nodemgr_ud_class.devices, node) {
+               ud = container_of(dev, struct unit_directory, unit_dev);
                if (ud->ne != ne)
                        continue;
 
-               if (ud->device.driver &&
-                   (!ud->device.driver->suspend ||
-                     ud->device.driver->suspend(&ud->device, PMSG_SUSPEND)))
+               drv = get_driver(ud->device.driver);
+               if (!drv)
+                       continue;
+
+               error = 1; /* release if suspend is not implemented */
+               if (drv->suspend) {
+                       down(&ud->device.sem);
+                       error = drv->suspend(&ud->device, PMSG_SUSPEND);
+                       up(&ud->device.sem);
+               }
+               if (error)
                        device_release_driver(&ud->device);
+               put_driver(drv);
        }
        up(&nodemgr_ud_class.sem);
 }
@@ -1404,20 +1416,29 @@ static void nodemgr_suspend_ne(struct node_entry *ne)
 
 static void nodemgr_resume_ne(struct node_entry *ne)
 {
-       struct class_device *cdev;
+       struct device *dev;
        struct unit_directory *ud;
+       struct device_driver *drv;
 
        ne->in_limbo = 0;
        device_remove_file(&ne->device, &dev_attr_ne_in_limbo);
 
        down(&nodemgr_ud_class.sem);
-       list_for_each_entry(cdev, &nodemgr_ud_class.children, node) {
-               ud = container_of(cdev, struct unit_directory, class_dev);
+       list_for_each_entry(dev, &nodemgr_ud_class.devices, node) {
+               ud = container_of(dev, struct unit_directory, unit_dev);
                if (ud->ne != ne)
                        continue;
 
-               if (ud->device.driver && ud->device.driver->resume)
-                       ud->device.driver->resume(&ud->device);
+               drv = get_driver(ud->device.driver);
+               if (!drv)
+                       continue;
+
+               if (drv->resume) {
+                       down(&ud->device.sem);
+                       drv->resume(&ud->device);
+                       up(&ud->device.sem);
+               }
+               put_driver(drv);
        }
        up(&nodemgr_ud_class.sem);
 
@@ -1428,23 +1449,32 @@ static void nodemgr_resume_ne(struct node_entry *ne)
 
 static void nodemgr_update_pdrv(struct node_entry *ne)
 {
+       struct device *dev;
        struct unit_directory *ud;
+       struct device_driver *drv;
        struct hpsb_protocol_driver *pdrv;
-       struct class_device *cdev;
+       int error;
 
        down(&nodemgr_ud_class.sem);
-       list_for_each_entry(cdev, &nodemgr_ud_class.children, node) {
-               ud = container_of(cdev, struct unit_directory, class_dev);
+       list_for_each_entry(dev, &nodemgr_ud_class.devices, node) {
+               ud = container_of(dev, struct unit_directory, unit_dev);
                if (ud->ne != ne)
                        continue;
 
-               if (ud->device.driver) {
-                       pdrv = container_of(ud->device.driver,
-                                           struct hpsb_protocol_driver,
-                                           driver);
-                       if (pdrv->update && pdrv->update(ud))
-                               device_release_driver(&ud->device);
+               drv = get_driver(ud->device.driver);
+               if (!drv)
+                       continue;
+
+               error = 0;
+               pdrv = container_of(drv, struct hpsb_protocol_driver, driver);
+               if (pdrv->update) {
+                       down(&ud->device.sem);
+                       error = pdrv->update(ud);
+                       up(&ud->device.sem);
                }
+               if (error)
+                       device_release_driver(&ud->device);
+               put_driver(drv);
        }
        up(&nodemgr_ud_class.sem);
 }
@@ -1509,7 +1539,7 @@ static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int ge
 static void nodemgr_node_probe(struct host_info *hi, int generation)
 {
        struct hpsb_host *host = hi->host;
-       struct class_device *cdev;
+       struct device *dev;
        struct node_entry *ne;
 
        /* Do some processing of the nodes we've probed. This pulls them
@@ -1522,13 +1552,13 @@ static void nodemgr_node_probe(struct host_info *hi, int generation)
         * improvement...) */
 
        down(&nodemgr_ne_class.sem);
-       list_for_each_entry(cdev, &nodemgr_ne_class.children, node) {
-               ne = container_of(cdev, struct node_entry, class_dev);
+       list_for_each_entry(dev, &nodemgr_ne_class.devices, node) {
+               ne = container_of(dev, struct node_entry, node_dev);
                if (!ne->needs_probe)
                        nodemgr_probe_ne(hi, ne, generation);
        }
-       list_for_each_entry(cdev, &nodemgr_ne_class.children, node) {
-               ne = container_of(cdev, struct node_entry, class_dev);
+       list_for_each_entry(dev, &nodemgr_ne_class.devices, node) {
+               ne = container_of(dev, struct node_entry, node_dev);
                if (ne->needs_probe)
                        nodemgr_probe_ne(hi, ne, generation);
        }
@@ -1686,18 +1716,12 @@ static int nodemgr_host_thread(void *__hi)
                if (kthread_should_stop())
                        goto exit;
 
-               if (mutex_lock_interruptible(&nodemgr_serialize)) {
-                       if (try_to_freeze())
-                               continue;
-                       goto exit;
-               }
-
                /* Pause for 1/4 second in 1/16 second intervals,
                 * to make sure things settle down. */
                g = get_hpsb_generation(host);
                for (i = 0; i < 4 ; i++) {
                        if (msleep_interruptible(63) || kthread_should_stop())
-                               goto unlock_exit;
+                               goto exit;
 
                        /* Now get the generation in which the node ID's we collect
                         * are valid.  During the bus scan we will use this generation
@@ -1715,7 +1739,6 @@ static int nodemgr_host_thread(void *__hi)
                if (!nodemgr_check_irm_capability(host, reset_cycles) ||
                    !nodemgr_do_irm_duties(host, reset_cycles)) {
                        reset_cycles++;
-                       mutex_unlock(&nodemgr_serialize);
                        continue;
                }
                reset_cycles = 0;
@@ -1732,11 +1755,7 @@ static int nodemgr_host_thread(void *__hi)
 
                /* Update some of our sysfs symlinks */
                nodemgr_update_host_dev_links(host);
-
-               mutex_unlock(&nodemgr_serialize);
        }
-unlock_exit:
-       mutex_unlock(&nodemgr_serialize);
 exit:
        HPSB_VERBOSE("NodeMgr: Exiting thread");
        return 0;
@@ -1756,13 +1775,13 @@ exit:
  */
 int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *))
 {
-       struct class_device *cdev;
+       struct device *dev;
        struct hpsb_host *host;
        int error = 0;
 
        down(&hpsb_host_class.sem);
-       list_for_each_entry(cdev, &hpsb_host_class.children, node) {
-               host = container_of(cdev, struct hpsb_host, class_dev);
+       list_for_each_entry(dev, &hpsb_host_class.devices, node) {
+               host = container_of(dev, struct hpsb_host, host_dev);
 
                if ((error = cb(host, data)))
                        break;
index 4530b29d941c37c0bc74debaeab810920057b363..919e92e2a9556b12045fca7371f8faf6e955e679 100644 (file)
@@ -84,7 +84,7 @@ struct unit_directory {
        int length;             /* Number of quadlets */
 
        struct device device;
-       struct class_device class_dev;
+       struct device unit_dev;
 
        struct csr1212_keyval *ud_kv;
        u32 lun;                /* logical unit number immediate value */
@@ -107,7 +107,7 @@ struct node_entry {
        u32 capabilities;
 
        struct device device;
-       struct class_device class_dev;
+       struct device node_dev;
 
        /* Means this node is not attached anymore */
        int in_limbo;
index 5dadfd296f79c4796e414e3de301a3c4f9714569..5667c8102efc0dcc56d14a786e602a7437ab4596 100644 (file)
@@ -138,19 +138,6 @@ printk(KERN_INFO "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->
 #define DBGMSG(fmt, args...) do {} while (0)
 #endif
 
-#ifdef CONFIG_IEEE1394_OHCI_DMA_DEBUG
-#define OHCI_DMA_ALLOC(fmt, args...) \
-       HPSB_ERR("%s(%s)alloc(%d): "fmt, OHCI1394_DRIVER_NAME, __FUNCTION__, \
-               ++global_outstanding_dmas, ## args)
-#define OHCI_DMA_FREE(fmt, args...) \
-       HPSB_ERR("%s(%s)free(%d): "fmt, OHCI1394_DRIVER_NAME, __FUNCTION__, \
-               --global_outstanding_dmas, ## args)
-static int global_outstanding_dmas = 0;
-#else
-#define OHCI_DMA_ALLOC(fmt, args...) do {} while (0)
-#define OHCI_DMA_FREE(fmt, args...) do {} while (0)
-#endif
-
 /* print general (card independent) information */
 #define PRINT_G(level, fmt, args...) \
 printk(level "%s: " fmt "\n" , OHCI1394_DRIVER_NAME , ## args)
@@ -170,7 +157,6 @@ static void dma_trm_reset(struct dma_trm_ctx *d);
 static int alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d,
                             enum context_type type, int ctx, int num_desc,
                             int buf_size, int split_buf_size, int context_base);
-static void stop_dma_rcv_ctx(struct dma_rcv_ctx *d);
 static void free_dma_rcv_ctx(struct dma_rcv_ctx *d);
 
 static int alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d,
@@ -533,9 +519,6 @@ static void ohci_initialize(struct ti_ohci *ohci)
        initialize_dma_trm_ctx(&ohci->at_req_context);
        initialize_dma_trm_ctx(&ohci->at_resp_context);
        
-       /* Initialize IR Legacy DMA channel mask */
-       ohci->ir_legacy_channels = 0;
-
        /* Accept AR requests from all nodes */
        reg_write(ohci, OHCI1394_AsReqFilterHiSet, 0x80000000);
 
@@ -733,7 +716,6 @@ static void insert_packet(struct ti_ohci *ohci,
                                 pci_map_single(ohci->dev, packet->data,
                                                packet->data_size,
                                                PCI_DMA_TODEVICE));
-                       OHCI_DMA_ALLOC("single, block transmit packet");
 
                         d->prg_cpu[idx]->end.branchAddress = 0;
                         d->prg_cpu[idx]->end.status = 0;
@@ -783,7 +765,6 @@ static void insert_packet(struct ti_ohci *ohci,
                 d->prg_cpu[idx]->end.address = cpu_to_le32(
                                pci_map_single(ohci->dev, packet->data,
                                packet->data_size, PCI_DMA_TODEVICE));
-               OHCI_DMA_ALLOC("single, iso transmit packet");
 
                 d->prg_cpu[idx]->end.branchAddress = 0;
                 d->prg_cpu[idx]->end.status = 0;
@@ -884,36 +865,9 @@ static int ohci_transmit(struct hpsb_host *host, struct hpsb_packet *packet)
                return -EOVERFLOW;
        }
 
-       /* Decide whether we have an iso, a request, or a response packet */
        if (packet->type == hpsb_raw)
                d = &ohci->at_req_context;
-       else if ((packet->tcode == TCODE_ISO_DATA) && (packet->type == hpsb_iso)) {
-               /* The legacy IT DMA context is initialized on first
-                * use.  However, the alloc cannot be run from
-                * interrupt context, so we bail out if that is the
-                * case. I don't see anyone sending ISO packets from
-                * interrupt context anyway... */
-
-               if (ohci->it_legacy_context.ohci == NULL) {
-                       if (in_interrupt()) {
-                               PRINT(KERN_ERR,
-                                     "legacy IT context cannot be initialized during interrupt");
-                               return -EINVAL;
-                       }
-
-                       if (alloc_dma_trm_ctx(ohci, &ohci->it_legacy_context,
-                                             DMA_CTX_ISO, 0, IT_NUM_DESC,
-                                             OHCI1394_IsoXmitContextBase) < 0) {
-                               PRINT(KERN_ERR,
-                                     "error initializing legacy IT context");
-                               return -ENOMEM;
-                       }
-
-                       initialize_dma_trm_ctx(&ohci->it_legacy_context);
-               }
-
-               d = &ohci->it_legacy_context;
-       } else if ((packet->tcode & 0x02) && (packet->tcode != TCODE_ISO_DATA))
+       else if ((packet->tcode & 0x02) && (packet->tcode != TCODE_ISO_DATA))
                d = &ohci->at_resp_context;
        else
                d = &ohci->at_req_context;
@@ -932,9 +886,7 @@ static int ohci_transmit(struct hpsb_host *host, struct hpsb_packet *packet)
 static int ohci_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg)
 {
        struct ti_ohci *ohci = host->hostdata;
-       int retval = 0;
-       unsigned long flags;
-       int phy_reg;
+       int retval = 0, phy_reg;
 
        switch (cmd) {
        case RESET_BUS:
@@ -1027,117 +979,6 @@ static int ohci_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg)
                dma_trm_reset(&ohci->at_resp_context);
                break;
 
-       case ISO_LISTEN_CHANNEL:
-        {
-               u64 mask;
-               struct dma_rcv_ctx *d = &ohci->ir_legacy_context;
-               int ir_legacy_active;
-
-               if (arg<0 || arg>63) {
-                       PRINT(KERN_ERR,
-                             "%s: IS0 listen channel %d is out of range",
-                             __FUNCTION__, arg);
-                       return -EFAULT;
-               }
-
-               mask = (u64)0x1<<arg;
-
-                spin_lock_irqsave(&ohci->IR_channel_lock, flags);
-
-               if (ohci->ISO_channel_usage & mask) {
-                       PRINT(KERN_ERR,
-                             "%s: IS0 listen channel %d is already used",
-                             __FUNCTION__, arg);
-                       spin_unlock_irqrestore(&ohci->IR_channel_lock, flags);
-                       return -EFAULT;
-               }
-
-               ir_legacy_active = ohci->ir_legacy_channels;
-
-               ohci->ISO_channel_usage |= mask;
-               ohci->ir_legacy_channels |= mask;
-
-                spin_unlock_irqrestore(&ohci->IR_channel_lock, flags);
-
-               if (!ir_legacy_active) {
-                       if (ohci1394_register_iso_tasklet(ohci,
-                                         &ohci->ir_legacy_tasklet) < 0) {
-                               PRINT(KERN_ERR, "No IR DMA context available");
-                               return -EBUSY;
-                       }
-
-                       /* the IR context can be assigned to any DMA context
-                        * by ohci1394_register_iso_tasklet */
-                       d->ctx = ohci->ir_legacy_tasklet.context;
-                       d->ctrlSet = OHCI1394_IsoRcvContextControlSet +
-                               32*d->ctx;
-                       d->ctrlClear = OHCI1394_IsoRcvContextControlClear +
-                               32*d->ctx;
-                       d->cmdPtr = OHCI1394_IsoRcvCommandPtr + 32*d->ctx;
-                       d->ctxtMatch = OHCI1394_IsoRcvContextMatch + 32*d->ctx;
-
-                       initialize_dma_rcv_ctx(&ohci->ir_legacy_context, 1);
-
-                       if (printk_ratelimit())
-                               DBGMSG("IR legacy activated");
-               }
-
-                spin_lock_irqsave(&ohci->IR_channel_lock, flags);
-
-               if (arg>31)
-                       reg_write(ohci, OHCI1394_IRMultiChanMaskHiSet,
-                                 1<<(arg-32));
-               else
-                       reg_write(ohci, OHCI1394_IRMultiChanMaskLoSet,
-                                 1<<arg);
-
-                spin_unlock_irqrestore(&ohci->IR_channel_lock, flags);
-                DBGMSG("Listening enabled on channel %d", arg);
-                break;
-        }
-       case ISO_UNLISTEN_CHANNEL:
-        {
-               u64 mask;
-
-               if (arg<0 || arg>63) {
-                       PRINT(KERN_ERR,
-                             "%s: IS0 unlisten channel %d is out of range",
-                             __FUNCTION__, arg);
-                       return -EFAULT;
-               }
-
-               mask = (u64)0x1<<arg;
-
-                spin_lock_irqsave(&ohci->IR_channel_lock, flags);
-
-               if (!(ohci->ISO_channel_usage & mask)) {
-                       PRINT(KERN_ERR,
-                             "%s: IS0 unlisten channel %d is not used",
-                             __FUNCTION__, arg);
-                       spin_unlock_irqrestore(&ohci->IR_channel_lock, flags);
-                       return -EFAULT;
-               }
-
-               ohci->ISO_channel_usage &= ~mask;
-               ohci->ir_legacy_channels &= ~mask;
-
-               if (arg>31)
-                       reg_write(ohci, OHCI1394_IRMultiChanMaskHiClear,
-                                 1<<(arg-32));
-               else
-                       reg_write(ohci, OHCI1394_IRMultiChanMaskLoClear,
-                                 1<<arg);
-
-                spin_unlock_irqrestore(&ohci->IR_channel_lock, flags);
-                DBGMSG("Listening disabled on channel %d", arg);
-
-               if (ohci->ir_legacy_channels == 0) {
-                       stop_dma_rcv_ctx(&ohci->ir_legacy_context);
-                       DBGMSG("ISO legacy receive context stopped");
-               }
-
-                break;
-        }
        default:
                PRINT_G(KERN_ERR, "ohci_devctl cmd %d not implemented yet",
                        cmd);
@@ -2869,12 +2710,10 @@ static void dma_trm_tasklet (unsigned long data)
                list_del_init(&packet->driver_list);
                hpsb_packet_sent(ohci->host, packet, ack);
 
-               if (datasize) {
+               if (datasize)
                        pci_unmap_single(ohci->dev,
                                         cpu_to_le32(d->prg_cpu[d->sent_ind]->end.address),
                                         datasize, PCI_DMA_TODEVICE);
-                       OHCI_DMA_FREE("single Xmit data packet");
-               }
 
                d->sent_ind = (d->sent_ind+1)%d->num_desc;
                d->free_prgs++;
@@ -2885,22 +2724,6 @@ static void dma_trm_tasklet (unsigned long data)
        spin_unlock_irqrestore(&d->lock, flags);
 }
 
-static void stop_dma_rcv_ctx(struct dma_rcv_ctx *d)
-{
-       if (d->ctrlClear) {
-               ohci1394_stop_context(d->ohci, d->ctrlClear, NULL);
-
-               if (d->type == DMA_CTX_ISO) {
-                       /* disable interrupts */
-                       reg_write(d->ohci, OHCI1394_IsoRecvIntMaskClear, 1 << d->ctx);
-                       ohci1394_unregister_iso_tasklet(d->ohci, &d->ohci->ir_legacy_tasklet);
-               } else {
-                       tasklet_kill(&d->task);
-               }
-       }
-}
-
-
 static void free_dma_rcv_ctx(struct dma_rcv_ctx *d)
 {
        int i;
@@ -2913,23 +2736,19 @@ static void free_dma_rcv_ctx(struct dma_rcv_ctx *d)
 
        if (d->buf_cpu) {
                for (i=0; i<d->num_desc; i++)
-                       if (d->buf_cpu[i] && d->buf_bus[i]) {
+                       if (d->buf_cpu[i] && d->buf_bus[i])
                                pci_free_consistent(
                                        ohci->dev, d->buf_size,
                                        d->buf_cpu[i], d->buf_bus[i]);
-                               OHCI_DMA_FREE("consistent dma_rcv buf[%d]", i);
-                       }
                kfree(d->buf_cpu);
                kfree(d->buf_bus);
        }
        if (d->prg_cpu) {
                for (i=0; i<d->num_desc; i++)
-                       if (d->prg_cpu[i] && d->prg_bus[i]) {
-                               pci_pool_free(d->prg_pool, d->prg_cpu[i], d->prg_bus[i]);
-                               OHCI_DMA_FREE("consistent dma_rcv prg[%d]", i);
-                       }
+                       if (d->prg_cpu[i] && d->prg_bus[i])
+                               pci_pool_free(d->prg_pool, d->prg_cpu[i],
+                                             d->prg_bus[i]);
                pci_pool_destroy(d->prg_pool);
-               OHCI_DMA_FREE("dma_rcv prg pool");
                kfree(d->prg_cpu);
                kfree(d->prg_bus);
        }
@@ -2998,13 +2817,10 @@ alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d,
        }
        num_allocs++;
 
-       OHCI_DMA_ALLOC("dma_rcv prg pool");
-
        for (i=0; i<d->num_desc; i++) {
                d->buf_cpu[i] = pci_alloc_consistent(ohci->dev,
                                                     d->buf_size,
                                                     d->buf_bus+i);
-               OHCI_DMA_ALLOC("consistent dma_rcv buf[%d]", i);
 
                if (d->buf_cpu[i] != NULL) {
                        memset(d->buf_cpu[i], 0, d->buf_size);
@@ -3016,7 +2832,6 @@ alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d,
                }
 
                d->prg_cpu[i] = pci_pool_alloc(d->prg_pool, GFP_KERNEL, d->prg_bus+i);
-               OHCI_DMA_ALLOC("pool dma_rcv prg[%d]", i);
 
                 if (d->prg_cpu[i] != NULL) {
                         memset(d->prg_cpu[i], 0, sizeof(struct dma_cmd));
@@ -3030,18 +2845,11 @@ alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d,
 
         spin_lock_init(&d->lock);
 
-       if (type == DMA_CTX_ISO) {
-               ohci1394_init_iso_tasklet(&ohci->ir_legacy_tasklet,
-                                         OHCI_ISO_MULTICHANNEL_RECEIVE,
-                                         dma_rcv_tasklet, (unsigned long) d);
-       } else {
-               d->ctrlSet = context_base + OHCI1394_ContextControlSet;
-               d->ctrlClear = context_base + OHCI1394_ContextControlClear;
-               d->cmdPtr = context_base + OHCI1394_ContextCommandPtr;
-
-               tasklet_init (&d->task, dma_rcv_tasklet, (unsigned long) d);
-       }
+       d->ctrlSet = context_base + OHCI1394_ContextControlSet;
+       d->ctrlClear = context_base + OHCI1394_ContextControlClear;
+       d->cmdPtr = context_base + OHCI1394_ContextCommandPtr;
 
+       tasklet_init(&d->task, dma_rcv_tasklet, (unsigned long) d);
        return 0;
 }
 
@@ -3057,12 +2865,10 @@ static void free_dma_trm_ctx(struct dma_trm_ctx *d)
 
        if (d->prg_cpu) {
                for (i=0; i<d->num_desc; i++)
-                       if (d->prg_cpu[i] && d->prg_bus[i]) {
-                               pci_pool_free(d->prg_pool, d->prg_cpu[i], d->prg_bus[i]);
-                               OHCI_DMA_FREE("pool dma_trm prg[%d]", i);
-                       }
+                       if (d->prg_cpu[i] && d->prg_bus[i])
+                               pci_pool_free(d->prg_pool, d->prg_cpu[i],
+                                             d->prg_bus[i]);
                pci_pool_destroy(d->prg_pool);
-               OHCI_DMA_FREE("dma_trm prg pool");
                kfree(d->prg_cpu);
                kfree(d->prg_bus);
        }
@@ -3108,11 +2914,8 @@ alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d,
        }
        num_allocs++;
 
-       OHCI_DMA_ALLOC("dma_rcv prg pool");
-
        for (i = 0; i < d->num_desc; i++) {
                d->prg_cpu[i] = pci_pool_alloc(d->prg_pool, GFP_KERNEL, d->prg_bus+i);
-               OHCI_DMA_ALLOC("pool dma_trm prg[%d]", i);
 
                 if (d->prg_cpu[i] != NULL) {
                         memset(d->prg_cpu[i], 0, sizeof(struct at_dma_prg));
@@ -3127,28 +2930,10 @@ alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d,
         spin_lock_init(&d->lock);
 
        /* initialize tasklet */
-       if (type == DMA_CTX_ISO) {
-               ohci1394_init_iso_tasklet(&ohci->it_legacy_tasklet, OHCI_ISO_TRANSMIT,
-                                         dma_trm_tasklet, (unsigned long) d);
-               if (ohci1394_register_iso_tasklet(ohci,
-                                                 &ohci->it_legacy_tasklet) < 0) {
-                       PRINT(KERN_ERR, "No IT DMA context available");
-                       free_dma_trm_ctx(d);
-                       return -EBUSY;
-               }
-
-               /* IT can be assigned to any context by register_iso_tasklet */
-               d->ctx = ohci->it_legacy_tasklet.context;
-               d->ctrlSet = OHCI1394_IsoXmitContextControlSet + 16 * d->ctx;
-               d->ctrlClear = OHCI1394_IsoXmitContextControlClear + 16 * d->ctx;
-               d->cmdPtr = OHCI1394_IsoXmitCommandPtr + 16 * d->ctx;
-       } else {
-               d->ctrlSet = context_base + OHCI1394_ContextControlSet;
-               d->ctrlClear = context_base + OHCI1394_ContextControlClear;
-               d->cmdPtr = context_base + OHCI1394_ContextCommandPtr;
-               tasklet_init (&d->task, dma_trm_tasklet, (unsigned long)d);
-       }
-
+       d->ctrlSet = context_base + OHCI1394_ContextControlSet;
+       d->ctrlClear = context_base + OHCI1394_ContextControlClear;
+       d->cmdPtr = context_base + OHCI1394_ContextCommandPtr;
+       tasklet_init(&d->task, dma_trm_tasklet, (unsigned long)d);
        return 0;
 }
 
@@ -3294,7 +3079,6 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev,
        ohci->csr_config_rom_cpu =
                pci_alloc_consistent(ohci->dev, OHCI_CONFIG_ROM_LEN,
                                     &ohci->csr_config_rom_bus);
-       OHCI_DMA_ALLOC("consistent csr_config_rom");
        if (ohci->csr_config_rom_cpu == NULL)
                FAIL(-ENOMEM, "Failed to allocate buffer config rom");
        ohci->init_state = OHCI_INIT_HAVE_CONFIG_ROM_BUFFER;
@@ -3303,8 +3087,6 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev,
        ohci->selfid_buf_cpu =
                pci_alloc_consistent(ohci->dev, OHCI1394_SI_DMA_BUF_SIZE,
                       &ohci->selfid_buf_bus);
-       OHCI_DMA_ALLOC("consistent selfid_buf");
-
        if (ohci->selfid_buf_cpu == NULL)
                FAIL(-ENOMEM, "Failed to allocate DMA buffer for self-id packets");
        ohci->init_state = OHCI_INIT_HAVE_SELFID_BUFFER;
@@ -3377,20 +3159,6 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev,
        ohci->ISO_channel_usage = 0;
         spin_lock_init(&ohci->IR_channel_lock);
 
-       /* Allocate the IR DMA context right here so we don't have
-        * to do it in interrupt path - note that this doesn't
-        * waste much memory and avoids the jugglery required to
-        * allocate it in IRQ path. */
-       if (alloc_dma_rcv_ctx(ohci, &ohci->ir_legacy_context,
-                             DMA_CTX_ISO, 0, IR_NUM_DESC,
-                             IR_BUF_SIZE, IR_SPLIT_BUF_SIZE,
-                             OHCI1394_IsoRcvContextBase) < 0) {
-               FAIL(-ENOMEM, "Cannot allocate IR Legacy DMA context");
-       }
-
-       /* We hopefully don't have to pre-allocate IT DMA like we did
-        * for IR DMA above. Allocate it on-demand and mark inactive. */
-       ohci->it_legacy_context.ohci = NULL;
        spin_lock_init(&ohci->event_lock);
 
        /*
@@ -3483,20 +3251,16 @@ static void ohci1394_pci_remove(struct pci_dev *pdev)
                free_dma_rcv_ctx(&ohci->ar_resp_context);
                free_dma_trm_ctx(&ohci->at_req_context);
                free_dma_trm_ctx(&ohci->at_resp_context);
-               free_dma_rcv_ctx(&ohci->ir_legacy_context);
-               free_dma_trm_ctx(&ohci->it_legacy_context);
 
        case OHCI_INIT_HAVE_SELFID_BUFFER:
                pci_free_consistent(ohci->dev, OHCI1394_SI_DMA_BUF_SIZE,
                                    ohci->selfid_buf_cpu,
                                    ohci->selfid_buf_bus);
-               OHCI_DMA_FREE("consistent selfid_buf");
 
        case OHCI_INIT_HAVE_CONFIG_ROM_BUFFER:
                pci_free_consistent(ohci->dev, OHCI_CONFIG_ROM_LEN,
                                    ohci->csr_config_rom_cpu,
                                    ohci->csr_config_rom_bus);
-               OHCI_DMA_FREE("consistent csr_config_rom");
 
        case OHCI_INIT_HAVE_IOMAPPING:
                iounmap(ohci->registers);
index f1ad539e7c1b34d2567c18cd1df89926e92f299e..4320bf010495c3bb7eabc0c76bfd600ecd3588da 100644 (file)
@@ -190,23 +190,10 @@ struct ti_ohci {
        unsigned long ir_multichannel_used; /* ditto */
         spinlock_t IR_channel_lock;
 
-       /* iso receive (legacy API) */
-       u64 ir_legacy_channels; /* note: this differs from ISO_channel_usage;
-                                  it only accounts for channels listened to
-                                  by the legacy API, so that we can know when
-                                  it is safe to free the legacy API context */
-
-       struct dma_rcv_ctx ir_legacy_context;
-       struct ohci1394_iso_tasklet ir_legacy_tasklet;
-
         /* iso transmit */
        int nb_iso_xmit_ctx;
        unsigned long it_ctx_usage; /* use test_and_set_bit() for atomicity */
 
-       /* iso transmit (legacy API) */
-       struct dma_trm_ctx it_legacy_context;
-       struct ohci1394_iso_tasklet it_legacy_tasklet;
-
         u64 ISO_channel_usage;
 
         /* IEEE-1394 part follows */
@@ -221,7 +208,6 @@ struct ti_ohci {
 
        /* Tasklets for iso receive and transmit, used by video1394
         * and dv1394 */
-
        struct list_head iso_tasklet_list;
        spinlock_t iso_tasklet_list_lock;
 
index 0742befe92270f0d9557072dc59a6b2771e5197c..d1a5bcdb5e0be9c5bab2facb893e996731cda317 100644 (file)
@@ -477,7 +477,11 @@ static void send_next(struct ti_lynx *lynx, int what)
         struct lynx_send_data *d;
         struct hpsb_packet *packet;
 
+#if 0 /* has been removed from ieee1394 core */
         d = (what == hpsb_iso ? &lynx->iso_send : &lynx->async);
+#else
+       d = &lynx->async;
+#endif
         if (!list_empty(&d->pcl_queue)) {
                 PRINT(KERN_ERR, lynx->id, "trying to queue a new packet in nonempty fifo");
                 BUG();
@@ -511,9 +515,11 @@ static void send_next(struct ti_lynx *lynx, int what)
         case hpsb_async:
                 pcl.buffer[0].control |= PCL_CMD_XMT;
                 break;
+#if 0 /* has been removed from ieee1394 core */
         case hpsb_iso:
                 pcl.buffer[0].control |= PCL_CMD_XMT | PCL_ISOMODE;
                 break;
+#endif
         case hpsb_raw:
                 pcl.buffer[0].control |= PCL_CMD_UNFXMT;
                 break;
@@ -542,9 +548,11 @@ static int lynx_transmit(struct hpsb_host *host, struct hpsb_packet *packet)
         case hpsb_raw:
                 d = &lynx->async;
                 break;
+#if 0 /* has been removed from ieee1394 core */
         case hpsb_iso:
                 d = &lynx->iso_send;
                 break;
+#endif
         default:
                 PRINT(KERN_ERR, lynx->id, "invalid packet type %d",
                       packet->type);
@@ -797,7 +805,7 @@ static int lynx_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg)
                }
 
                 break;
-
+#if 0 /* has been removed from ieee1394 core */
         case ISO_LISTEN_CHANNEL:
                 spin_lock_irqsave(&lynx->iso_rcv.lock, flags);
 
@@ -819,7 +827,7 @@ static int lynx_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg)
 
                 spin_unlock_irqrestore(&lynx->iso_rcv.lock, flags);
                 break;
-
+#endif
         default:
                 PRINT(KERN_ERR, lynx->id, "unknown devctl command %d", cmd);
                 retval = -1;
@@ -1009,11 +1017,11 @@ static irqreturn_t lynx_irq_handler(int irq, void *dev_id)
                                 pci_unmap_single(lynx->dev, lynx->iso_send.data_dma,
                                                  packet->data_size, PCI_DMA_TODEVICE);
                         }
-
+#if 0 /* has been removed from ieee1394 core */
                         if (!list_empty(&lynx->iso_send.queue)) {
                                 send_next(lynx, hpsb_iso);
                         }
-
+#endif
                         spin_unlock(&lynx->iso_send.queue_lock);
 
                         if (pcl.pcl_status & DMA_CHAN_STAT_PKTCMPL) {
index 50daabf6e5fa38317ce247246945a40191975db7..a06aaad5b448da6072a0c4469b60cfa64eafa1e3 100644 (file)
@@ -36,11 +36,6 @@ struct file_info {
 
         u8 __user *fcp_buffer;
 
-       /* old ISO API */
-        u64 listen_channels;
-        quadlet_t __user *iso_buffer;
-        size_t iso_buffer_length;
-
         u8 notification; /* (busreset-notification) RAW1394_NOTIFY_OFF/ON */
 
        /* new rawiso API */
index f1d05eeb9f5190216b68504dc78fcc1fb7ef38fe..336e5ff4cfcf6f111cf5c57d6a043c5767d1513d 100644 (file)
@@ -98,21 +98,6 @@ static struct hpsb_address_ops arm_ops = {
 
 static void queue_complete_cb(struct pending_request *req);
 
-#include <asm/current.h>
-static void print_old_iso_deprecation(void)
-{
-       static pid_t p;
-
-       if (p == current->pid)
-               return;
-       p = current->pid;
-       printk(KERN_WARNING "raw1394: WARNING - Program \"%s\" uses unsupported"
-              " isochronous request types which will be removed in a next"
-              " kernel release\n", current->comm);
-       printk(KERN_WARNING "raw1394: Update your software to use libraw1394's"
-              " newer interface\n");
-}
-
 static struct pending_request *__alloc_pending_request(gfp_t flags)
 {
        struct pending_request *req;
@@ -297,67 +282,6 @@ static void host_reset(struct hpsb_host *host)
        spin_unlock_irqrestore(&host_info_lock, flags);
 }
 
-static void iso_receive(struct hpsb_host *host, int channel, quadlet_t * data,
-                       size_t length)
-{
-       unsigned long flags;
-       struct host_info *hi;
-       struct file_info *fi;
-       struct pending_request *req, *req_next;
-       struct iso_block_store *ibs = NULL;
-       LIST_HEAD(reqs);
-
-       if ((atomic_read(&iso_buffer_size) + length) > iso_buffer_max) {
-               HPSB_INFO("dropped iso packet");
-               return;
-       }
-
-       spin_lock_irqsave(&host_info_lock, flags);
-       hi = find_host_info(host);
-
-       if (hi != NULL) {
-               list_for_each_entry(fi, &hi->file_info_list, list) {
-                       if (!(fi->listen_channels & (1ULL << channel)))
-                               continue;
-
-                       req = __alloc_pending_request(GFP_ATOMIC);
-                       if (!req)
-                               break;
-
-                       if (!ibs) {
-                               ibs = kmalloc(sizeof(*ibs) + length,
-                                             GFP_ATOMIC);
-                               if (!ibs) {
-                                       kfree(req);
-                                       break;
-                               }
-
-                               atomic_add(length, &iso_buffer_size);
-                               atomic_set(&ibs->refcount, 0);
-                               ibs->data_size = length;
-                               memcpy(ibs->data, data, length);
-                       }
-
-                       atomic_inc(&ibs->refcount);
-
-                       req->file_info = fi;
-                       req->ibs = ibs;
-                       req->data = ibs->data;
-                       req->req.type = RAW1394_REQ_ISO_RECEIVE;
-                       req->req.generation = get_hpsb_generation(host);
-                       req->req.misc = 0;
-                       req->req.recvb = ptr2int(fi->iso_buffer);
-                       req->req.length = min(length, fi->iso_buffer_length);
-
-                       list_add_tail(&req->list, &reqs);
-               }
-       }
-       spin_unlock_irqrestore(&host_info_lock, flags);
-
-       list_for_each_entry_safe(req, req_next, &reqs, list)
-           queue_complete_req(req);
-}
-
 static void fcp_request(struct hpsb_host *host, int nodeid, int direction,
                        int cts, u8 * data, size_t length)
 {
@@ -434,7 +358,11 @@ struct compat_raw1394_req {
 
        __u64 sendb;
        __u64 recvb;
-} __attribute__((packed));
+}
+#if defined(CONFIG_X86_64) || defined(CONFIG_IA64)
+__attribute__((packed))
+#endif
+;
 
 static const char __user *raw1394_compat_write(const char __user *buf)
 {
@@ -459,7 +387,7 @@ static const char __user *raw1394_compat_write(const char __user *buf)
 static int
 raw1394_compat_read(const char __user *buf, struct raw1394_request *r)
 {
-       struct compat_raw1394_req __user *cr = (typeof(cr)) r;
+       struct compat_raw1394_req __user *cr = (typeof(cr)) buf;
        if (!access_ok(VERIFY_WRITE, cr, sizeof(struct compat_raw1394_req)) ||
            P(type) ||
            P(error) ||
@@ -587,7 +515,7 @@ static int state_opened(struct file_info *fi, struct pending_request *req)
 
        req->req.length = 0;
        queue_complete_req(req);
-       return sizeof(struct raw1394_request);
+       return 0;
 }
 
 static int state_initialized(struct file_info *fi, struct pending_request *req)
@@ -601,7 +529,7 @@ static int state_initialized(struct file_info *fi, struct pending_request *req)
                req->req.generation = atomic_read(&internal_generation);
                req->req.length = 0;
                queue_complete_req(req);
-               return sizeof(struct raw1394_request);
+               return 0;
        }
 
        switch (req->req.type) {
@@ -673,44 +601,7 @@ out_set_card:
        }
 
        queue_complete_req(req);
-       return sizeof(struct raw1394_request);
-}
-
-static void handle_iso_listen(struct file_info *fi, struct pending_request *req)
-{
-       int channel = req->req.misc;
-
-       if ((channel > 63) || (channel < -64)) {
-               req->req.error = RAW1394_ERROR_INVALID_ARG;
-       } else if (channel >= 0) {
-               /* allocate channel req.misc */
-               if (fi->listen_channels & (1ULL << channel)) {
-                       req->req.error = RAW1394_ERROR_ALREADY;
-               } else {
-                       if (hpsb_listen_channel
-                           (&raw1394_highlevel, fi->host, channel)) {
-                               req->req.error = RAW1394_ERROR_ALREADY;
-                       } else {
-                               fi->listen_channels |= 1ULL << channel;
-                               fi->iso_buffer = int2ptr(req->req.recvb);
-                               fi->iso_buffer_length = req->req.length;
-                       }
-               }
-       } else {
-               /* deallocate channel (one's complement neg) req.misc */
-               channel = ~channel;
-
-               if (fi->listen_channels & (1ULL << channel)) {
-                       hpsb_unlisten_channel(&raw1394_highlevel, fi->host,
-                                             channel);
-                       fi->listen_channels &= ~(1ULL << channel);
-               } else {
-                       req->req.error = RAW1394_ERROR_INVALID_ARG;
-               }
-       }
-
-       req->req.length = 0;
-       queue_complete_req(req);
+       return 0;
 }
 
 static void handle_fcp_listen(struct file_info *fi, struct pending_request *req)
@@ -865,7 +756,7 @@ static int handle_async_request(struct file_info *fi,
        if (req->req.error) {
                req->req.length = 0;
                queue_complete_req(req);
-               return sizeof(struct raw1394_request);
+               return 0;
        }
 
        hpsb_set_packet_complete_task(packet,
@@ -883,51 +774,7 @@ static int handle_async_request(struct file_info *fi,
                hpsb_free_tlabel(packet);
                queue_complete_req(req);
        }
-       return sizeof(struct raw1394_request);
-}
-
-static int handle_iso_send(struct file_info *fi, struct pending_request *req,
-                          int channel)
-{
-       unsigned long flags;
-       struct hpsb_packet *packet;
-
-       packet = hpsb_make_isopacket(fi->host, req->req.length, channel & 0x3f,
-                                    (req->req.misc >> 16) & 0x3,
-                                    req->req.misc & 0xf);
-       if (!packet)
-               return -ENOMEM;
-
-       packet->speed_code = req->req.address & 0x3;
-
-       req->packet = packet;
-
-       if (copy_from_user(packet->data, int2ptr(req->req.sendb),
-                          req->req.length)) {
-               req->req.error = RAW1394_ERROR_MEMFAULT;
-               req->req.length = 0;
-               queue_complete_req(req);
-               return sizeof(struct raw1394_request);
-       }
-
-       req->req.length = 0;
-       hpsb_set_packet_complete_task(packet,
-                                     (void (*)(void *))queue_complete_req,
-                                     req);
-
-       spin_lock_irqsave(&fi->reqlists_lock, flags);
-       list_add_tail(&req->list, &fi->req_pending);
-       spin_unlock_irqrestore(&fi->reqlists_lock, flags);
-
-       /* Update the generation of the packet just before sending. */
-       packet->generation = req->req.generation;
-
-       if (hpsb_send_packet(packet) < 0) {
-               req->req.error = RAW1394_ERROR_SEND_ERROR;
-               queue_complete_req(req);
-       }
-
-       return sizeof(struct raw1394_request);
+       return 0;
 }
 
 static int handle_async_send(struct file_info *fi, struct pending_request *req)
@@ -943,7 +790,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
                req->req.error = RAW1394_ERROR_INVALID_ARG;
                req->req.length = 0;
                queue_complete_req(req);
-               return sizeof(struct raw1394_request);
+               return 0;
        }
 
        data_size = req->req.length - header_length;
@@ -957,7 +804,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
                req->req.error = RAW1394_ERROR_MEMFAULT;
                req->req.length = 0;
                queue_complete_req(req);
-               return sizeof(struct raw1394_request);
+               return 0;
        }
 
        if (copy_from_user
@@ -966,7 +813,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
                req->req.error = RAW1394_ERROR_MEMFAULT;
                req->req.length = 0;
                queue_complete_req(req);
-               return sizeof(struct raw1394_request);
+               return 0;
        }
 
        packet->type = hpsb_async;
@@ -994,7 +841,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
                queue_complete_req(req);
        }
 
-       return sizeof(struct raw1394_request);
+       return 0;
 }
 
 static int arm_read(struct hpsb_host *host, int nodeid, quadlet_t * buffer,
@@ -1869,7 +1716,7 @@ static int arm_register(struct file_info *fi, struct pending_request *req)
                spin_lock_irqsave(&host_info_lock, flags);
                list_add_tail(&addr->addr_list, &fi->addr_list);
                spin_unlock_irqrestore(&host_info_lock, flags);
-               return sizeof(struct raw1394_request);
+               return 0;
        }
        retval =
            hpsb_register_addrspace(&raw1394_highlevel, fi->host, &arm_ops,
@@ -1887,7 +1734,7 @@ static int arm_register(struct file_info *fi, struct pending_request *req)
                return (-EALREADY);
        }
        free_pending_request(req);      /* immediate success or fail */
-       return sizeof(struct raw1394_request);
+       return 0;
 }
 
 static int arm_unregister(struct file_info *fi, struct pending_request *req)
@@ -1955,7 +1802,7 @@ static int arm_unregister(struct file_info *fi, struct pending_request *req)
                vfree(addr->addr_space_buffer);
                kfree(addr);
                free_pending_request(req);      /* immediate success or fail */
-               return sizeof(struct raw1394_request);
+               return 0;
        }
        retval =
            hpsb_unregister_addrspace(&raw1394_highlevel, fi->host,
@@ -1971,7 +1818,7 @@ static int arm_unregister(struct file_info *fi, struct pending_request *req)
        vfree(addr->addr_space_buffer);
        kfree(addr);
        free_pending_request(req);      /* immediate success or fail */
-       return sizeof(struct raw1394_request);
+       return 0;
 }
 
 /* Copy data from ARM buffer(s) to user buffer. */
@@ -2013,7 +1860,7 @@ static int arm_get_buf(struct file_info *fi, struct pending_request *req)
                                 * queue no response, and therefore nobody
                                 * will free it. */
                                free_pending_request(req);
-                               return sizeof(struct raw1394_request);
+                               return 0;
                        } else {
                                DBGMSG("arm_get_buf request exceeded mapping");
                                spin_unlock_irqrestore(&host_info_lock, flags);
@@ -2065,7 +1912,7 @@ static int arm_set_buf(struct file_info *fi, struct pending_request *req)
                                 * queue no response, and therefore nobody
                                 * will free it. */
                                free_pending_request(req);
-                               return sizeof(struct raw1394_request);
+                               return 0;
                        } else {
                                DBGMSG("arm_set_buf request exceeded mapping");
                                spin_unlock_irqrestore(&host_info_lock, flags);
@@ -2086,7 +1933,7 @@ static int reset_notification(struct file_info *fi, struct pending_request *req)
            (req->req.misc == RAW1394_NOTIFY_ON)) {
                fi->notification = (u8) req->req.misc;
                free_pending_request(req);      /* we have to free the request, because we queue no response, and therefore nobody will free it */
-               return sizeof(struct raw1394_request);
+               return 0;
        }
        /* error EINVAL (22) invalid argument */
        return (-EINVAL);
@@ -2119,12 +1966,12 @@ static int write_phypacket(struct file_info *fi, struct pending_request *req)
                req->req.length = 0;
                queue_complete_req(req);
        }
-       return sizeof(struct raw1394_request);
+       return 0;
 }
 
 static int get_config_rom(struct file_info *fi, struct pending_request *req)
 {
-       int ret = sizeof(struct raw1394_request);
+       int ret = 0;
        quadlet_t *data = kmalloc(req->req.length, GFP_KERNEL);
        int status;
 
@@ -2154,7 +2001,7 @@ static int get_config_rom(struct file_info *fi, struct pending_request *req)
 
 static int update_config_rom(struct file_info *fi, struct pending_request *req)
 {
-       int ret = sizeof(struct raw1394_request);
+       int ret = 0;
        quadlet_t *data = kmalloc(req->req.length, GFP_KERNEL);
        if (!data)
                return -ENOMEM;
@@ -2221,7 +2068,7 @@ static int modify_config_rom(struct file_info *fi, struct pending_request *req)
 
                        hpsb_update_config_rom_image(fi->host);
                        free_pending_request(req);
-                       return sizeof(struct raw1394_request);
+                       return 0;
                }
        }
 
@@ -2286,7 +2133,7 @@ static int modify_config_rom(struct file_info *fi, struct pending_request *req)
                /* we have to free the request, because we queue no response,
                 * and therefore nobody will free it */
                free_pending_request(req);
-               return sizeof(struct raw1394_request);
+               return 0;
        } else {
                for (dentry =
                     fi->csr1212_dirs[dr]->value.directory.dentries_head;
@@ -2311,11 +2158,7 @@ static int state_connected(struct file_info *fi, struct pending_request *req)
 
        case RAW1394_REQ_ECHO:
                queue_complete_req(req);
-               return sizeof(struct raw1394_request);
-
-       case RAW1394_REQ_ISO_SEND:
-               print_old_iso_deprecation();
-               return handle_iso_send(fi, req, node);
+               return 0;
 
        case RAW1394_REQ_ARM_REGISTER:
                return arm_register(fi, req);
@@ -2332,27 +2175,30 @@ static int state_connected(struct file_info *fi, struct pending_request *req)
        case RAW1394_REQ_RESET_NOTIFY:
                return reset_notification(fi, req);
 
+       case RAW1394_REQ_ISO_SEND:
        case RAW1394_REQ_ISO_LISTEN:
-               print_old_iso_deprecation();
-               handle_iso_listen(fi, req);
-               return sizeof(struct raw1394_request);
+               printk(KERN_DEBUG "raw1394: old iso ABI has been removed\n");
+               req->req.error = RAW1394_ERROR_COMPAT;
+               req->req.misc = RAW1394_KERNELAPI_VERSION;
+               queue_complete_req(req);
+               return 0;
 
        case RAW1394_REQ_FCP_LISTEN:
                handle_fcp_listen(fi, req);
-               return sizeof(struct raw1394_request);
+               return 0;
 
        case RAW1394_REQ_RESET_BUS:
                if (req->req.misc == RAW1394_LONG_RESET) {
                        DBGMSG("busreset called (type: LONG)");
                        hpsb_reset_bus(fi->host, LONG_RESET);
                        free_pending_request(req);      /* we have to free the request, because we queue no response, and therefore nobody will free it */
-                       return sizeof(struct raw1394_request);
+                       return 0;
                }
                if (req->req.misc == RAW1394_SHORT_RESET) {
                        DBGMSG("busreset called (type: SHORT)");
                        hpsb_reset_bus(fi->host, SHORT_RESET);
                        free_pending_request(req);      /* we have to free the request, because we queue no response, and therefore nobody will free it */
-                       return sizeof(struct raw1394_request);
+                       return 0;
                }
                /* error EINVAL (22) invalid argument */
                return (-EINVAL);
@@ -2371,7 +2217,7 @@ static int state_connected(struct file_info *fi, struct pending_request *req)
                req->req.generation = get_hpsb_generation(fi->host);
                req->req.length = 0;
                queue_complete_req(req);
-               return sizeof(struct raw1394_request);
+               return 0;
        }
 
        switch (req->req.type) {
@@ -2384,7 +2230,7 @@ static int state_connected(struct file_info *fi, struct pending_request *req)
        if (req->req.length == 0) {
                req->req.error = RAW1394_ERROR_INVALID_ARG;
                queue_complete_req(req);
-               return sizeof(struct raw1394_request);
+               return 0;
        }
 
        return handle_async_request(fi, req, node);
@@ -2395,7 +2241,7 @@ static ssize_t raw1394_write(struct file *file, const char __user * buffer,
 {
        struct file_info *fi = (struct file_info *)file->private_data;
        struct pending_request *req;
-       ssize_t retval = 0;
+       ssize_t retval = -EBADFD;
 
 #ifdef CONFIG_COMPAT
        if (count == sizeof(struct compat_raw1394_req) &&
@@ -2437,6 +2283,9 @@ static ssize_t raw1394_write(struct file *file, const char __user * buffer,
 
        if (retval < 0) {
                free_pending_request(req);
+       } else {
+               BUG_ON(retval);
+               retval = count;
        }
 
        return retval;
@@ -2802,6 +2651,103 @@ static int raw1394_ioctl(struct inode *inode, struct file *file,
        return -EINVAL;
 }
 
+#ifdef CONFIG_COMPAT
+struct raw1394_iso_packets32 {
+        __u32 n_packets;
+        compat_uptr_t infos;
+} __attribute__((packed));
+
+struct raw1394_cycle_timer32 {
+        __u32 cycle_timer;
+        __u64 local_time;
+}
+#if defined(CONFIG_X86_64) || defined(CONFIG_IA64)
+__attribute__((packed))
+#endif
+;
+
+#define RAW1394_IOC_ISO_RECV_PACKETS32          \
+        _IOW ('#', 0x25, struct raw1394_iso_packets32)
+#define RAW1394_IOC_ISO_XMIT_PACKETS32          \
+        _IOW ('#', 0x27, struct raw1394_iso_packets32)
+#define RAW1394_IOC_GET_CYCLE_TIMER32           \
+        _IOR ('#', 0x30, struct raw1394_cycle_timer32)
+
+static long raw1394_iso_xmit_recv_packets32(struct file *file, unsigned int cmd,
+                                          struct raw1394_iso_packets32 __user *arg)
+{
+       compat_uptr_t infos32;
+       void *infos;
+       long err = -EFAULT;
+       struct raw1394_iso_packets __user *dst = compat_alloc_user_space(sizeof(struct raw1394_iso_packets));
+
+       if (!copy_in_user(&dst->n_packets, &arg->n_packets, sizeof arg->n_packets) &&
+           !copy_from_user(&infos32, &arg->infos, sizeof infos32)) {
+               infos = compat_ptr(infos32);
+               if (!copy_to_user(&dst->infos, &infos, sizeof infos))
+                       err = raw1394_ioctl(NULL, file, cmd, (unsigned long)dst);
+       }
+       return err;
+}
+
+static long raw1394_read_cycle_timer32(struct file_info *fi, void __user * uaddr)
+{
+       struct raw1394_cycle_timer32 ct;
+       int err;
+
+       err = hpsb_read_cycle_timer(fi->host, &ct.cycle_timer, &ct.local_time);
+       if (!err)
+               if (copy_to_user(uaddr, &ct, sizeof(ct)))
+                       err = -EFAULT;
+       return err;
+}
+
+static long raw1394_compat_ioctl(struct file *file,
+                                unsigned int cmd, unsigned long arg)
+{
+       struct file_info *fi = file->private_data;
+       void __user *argp = (void __user *)arg;
+       long err;
+
+       lock_kernel();
+       switch (cmd) {
+       /* These requests have same format as long as 'int' has same size. */
+       case RAW1394_IOC_ISO_RECV_INIT:
+       case RAW1394_IOC_ISO_RECV_START:
+       case RAW1394_IOC_ISO_RECV_LISTEN_CHANNEL:
+       case RAW1394_IOC_ISO_RECV_UNLISTEN_CHANNEL:
+       case RAW1394_IOC_ISO_RECV_SET_CHANNEL_MASK:
+       case RAW1394_IOC_ISO_RECV_RELEASE_PACKETS:
+       case RAW1394_IOC_ISO_RECV_FLUSH:
+       case RAW1394_IOC_ISO_XMIT_RECV_STOP:
+       case RAW1394_IOC_ISO_XMIT_INIT:
+       case RAW1394_IOC_ISO_XMIT_START:
+       case RAW1394_IOC_ISO_XMIT_SYNC:
+       case RAW1394_IOC_ISO_GET_STATUS:
+       case RAW1394_IOC_ISO_SHUTDOWN:
+       case RAW1394_IOC_ISO_QUEUE_ACTIVITY:
+               err = raw1394_ioctl(NULL, file, cmd, arg);
+               break;
+       /* These request have different format. */
+       case RAW1394_IOC_ISO_RECV_PACKETS32:
+               err = raw1394_iso_xmit_recv_packets32(file, RAW1394_IOC_ISO_RECV_PACKETS, argp);
+               break;
+       case RAW1394_IOC_ISO_XMIT_PACKETS32:
+               err = raw1394_iso_xmit_recv_packets32(file, RAW1394_IOC_ISO_XMIT_PACKETS, argp);
+               break;
+       case RAW1394_IOC_GET_CYCLE_TIMER32:
+               err = raw1394_read_cycle_timer32(fi, argp);
+               break;
+       default:
+               err = -EINVAL;
+               break;
+       }
+       unlock_kernel();
+
+       return err;
+}
+#endif
+
 static unsigned int raw1394_poll(struct file *file, poll_table * pt)
 {
        struct file_info *fi = file->private_data;
@@ -2861,14 +2807,7 @@ static int raw1394_release(struct inode *inode, struct file *file)
        if (fi->iso_state != RAW1394_ISO_INACTIVE)
                raw1394_iso_shutdown(fi);
 
-       for (i = 0; i < 64; i++) {
-               if (fi->listen_channels & (1ULL << i)) {
-                       hpsb_unlisten_channel(&raw1394_highlevel, fi->host, i);
-               }
-       }
-
        spin_lock_irqsave(&host_info_lock, flags);
-       fi->listen_channels = 0;
 
        fail = 0;
        /* set address-entries invalid */
@@ -3030,7 +2969,6 @@ static struct hpsb_highlevel raw1394_highlevel = {
        .add_host = add_host,
        .remove_host = remove_host,
        .host_reset = host_reset,
-       .iso_receive = iso_receive,
        .fcp_request = fcp_request,
 };
 
@@ -3041,7 +2979,9 @@ static const struct file_operations raw1394_fops = {
        .write = raw1394_write,
        .mmap = raw1394_mmap,
        .ioctl = raw1394_ioctl,
-       // .compat_ioctl = ... someone needs to do this
+#ifdef CONFIG_COMPAT
+       .compat_ioctl = raw1394_compat_ioctl,
+#endif
        .poll = raw1394_poll,
        .open = raw1394_open,
        .release = raw1394_release,
@@ -3054,9 +2994,9 @@ static int __init init_raw1394(void)
        hpsb_register_highlevel(&raw1394_highlevel);
 
        if (IS_ERR
-           (class_device_create
-            (hpsb_protocol_class, NULL,
-             MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16), NULL,
+           (device_create(
+             hpsb_protocol_class, NULL,
+             MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16),
              RAW1394_DEVICE_NAME))) {
                ret = -EFAULT;
                goto out_unreg;
@@ -3083,9 +3023,9 @@ static int __init init_raw1394(void)
        goto out;
 
       out_dev:
-       class_device_destroy(hpsb_protocol_class,
-                            MKDEV(IEEE1394_MAJOR,
-                                  IEEE1394_MINOR_BLOCK_RAW1394 * 16));
+       device_destroy(hpsb_protocol_class,
+                      MKDEV(IEEE1394_MAJOR,
+                            IEEE1394_MINOR_BLOCK_RAW1394 * 16));
       out_unreg:
        hpsb_unregister_highlevel(&raw1394_highlevel);
       out:
@@ -3094,9 +3034,9 @@ static int __init init_raw1394(void)
 
 static void __exit cleanup_raw1394(void)
 {
-       class_device_destroy(hpsb_protocol_class,
-                            MKDEV(IEEE1394_MAJOR,
-                                  IEEE1394_MINOR_BLOCK_RAW1394 * 16));
+       device_destroy(hpsb_protocol_class,
+                      MKDEV(IEEE1394_MAJOR,
+                            IEEE1394_MINOR_BLOCK_RAW1394 * 16));
        cdev_del(&raw1394_cdev);
        hpsb_unregister_highlevel(&raw1394_highlevel);
        hpsb_unregister_protocol(&raw1394_driver);
index 7bd22ee1afbb1d56a2a71e9c86cd86b3ad5bfc43..963ac20373d20c860ac7d4f89e5db819b68cfbae 100644 (file)
 #define RAW1394_REQ_ASYNC_WRITE     101
 #define RAW1394_REQ_LOCK            102
 #define RAW1394_REQ_LOCK64          103
-#define RAW1394_REQ_ISO_SEND        104
+#define RAW1394_REQ_ISO_SEND        104 /* removed ABI, now a no-op */
 #define RAW1394_REQ_ASYNC_SEND      105
 #define RAW1394_REQ_ASYNC_STREAM    106
 
-#define RAW1394_REQ_ISO_LISTEN      200
+#define RAW1394_REQ_ISO_LISTEN      200 /* removed ABI, now a no-op */
 #define RAW1394_REQ_FCP_LISTEN      201
 #define RAW1394_REQ_RESET_BUS       202
 #define RAW1394_REQ_GET_ROM         203
index 3f873cc7e247a7944d4ac27359600daf378fb1f7..e0c385a3b45079efc796904d588733a3f5a08449 100644 (file)
@@ -118,14 +118,13 @@ MODULE_PARM_DESC(max_speed, "Force max speed "
                 "(3 = 800Mb/s, 2 = 400Mb/s, 1 = 200Mb/s, 0 = 100Mb/s)");
 
 /*
- * Set serialize_io to 1 if you'd like only one scsi command sent
- * down to us at a time (debugging). This might be necessary for very
- * badly behaved sbp2 devices.
+ * Set serialize_io to 0 or N to use dynamically appended lists of command ORBs.
+ * This is and always has been buggy in multiple subtle ways. See above TODOs.
  */
 static int sbp2_serialize_io = 1;
-module_param_named(serialize_io, sbp2_serialize_io, int, 0444);
-MODULE_PARM_DESC(serialize_io, "Serialize I/O coming from scsi drivers "
-                "(default = 1, faster = 0)");
+module_param_named(serialize_io, sbp2_serialize_io, bool, 0444);
+MODULE_PARM_DESC(serialize_io, "Serialize requests coming from SCSI drivers "
+                "(default = Y, faster but buggy = N)");
 
 /*
  * Bump up max_sectors if you'd like to support very large sized
@@ -154,9 +153,9 @@ MODULE_PARM_DESC(max_sectors, "Change max sectors per I/O supported "
  * are possible on OXFW911 and newer Oxsemi bridges.
  */
 static int sbp2_exclusive_login = 1;
-module_param_named(exclusive_login, sbp2_exclusive_login, int, 0644);
+module_param_named(exclusive_login, sbp2_exclusive_login, bool, 0644);
 MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device "
-                "(default = 1)");
+                "(default = Y, use N for concurrent initiators)");
 
 /*
  * If any of the following workarounds is required for your device to work,
index 44402b9d82a8ab0200cf435e7bd7336e5e2a80aa..333a4bb767434997bc0fa06e6fd922a063d46c86 100644 (file)
@@ -67,7 +67,7 @@ struct sbp2_command_orb {
 #define ORB_SET_LUN(v)                 ((v) & 0xffff)
 #define ORB_SET_FUNCTION(v)            (((v) & 0xf) << 16)
 #define ORB_SET_RECONNECT(v)           (((v) & 0xf) << 20)
-#define ORB_SET_EXCLUSIVE(v)           (((v) & 0x1) << 28)
+#define ORB_SET_EXCLUSIVE(v)           ((v) ? 1 << 28 : 0)
 #define ORB_SET_LOGIN_RESP_LENGTH(v)   ((v) & 0xffff)
 #define ORB_SET_PASSWD_LENGTH(v)       (((v) & 0xffff) << 16)
 
index 87ebd0846c3410d56afbc520180046322bc44cdc..bd28adfd7afc6742e7859ced1fffcd374a8a8717 100644 (file)
@@ -1340,9 +1340,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;
-       class_device_create(hpsb_protocol_class, NULL, MKDEV(
-               IEEE1394_MAJOR, minor), 
-               NULL, "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id);
+       device_create(hpsb_protocol_class, NULL,
+                     MKDEV(IEEE1394_MAJOR, minor),
+                     "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id);
 }
 
 
@@ -1351,8 +1351,8 @@ static void video1394_remove_host (struct hpsb_host *host)
        struct ti_ohci *ohci = hpsb_get_hostinfo(&video1394_highlevel, host);
 
        if (ohci)
-               class_device_destroy(hpsb_protocol_class, MKDEV(IEEE1394_MAJOR,
-                       IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id));
+               device_destroy(hpsb_protocol_class, MKDEV(IEEE1394_MAJOR,
+                              IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id));
        return;
 }
 
index 994decc7bcf2afd9c2c129fb6556af935ad8ce73..a193dfbf99d2f38dd6c9066efb63daeaa14d3b1b 100644 (file)
@@ -1,14 +1,14 @@
-menu "InfiniBand support"
-       depends on HAS_IOMEM
-
-config INFINIBAND
-       depends on PCI || BROKEN
+menuconfig INFINIBAND
        tristate "InfiniBand support"
+       depends on PCI || BROKEN
+       depends on HAS_IOMEM
        ---help---
          Core support for InfiniBand (IB).  Make sure to also select
          any protocols you wish to use as well as drivers for your
          InfiniBand hardware.
 
+if INFINIBAND
+
 config INFINIBAND_USER_MAD
        tristate "InfiniBand userspace MAD support"
        depends on INFINIBAND
@@ -20,7 +20,6 @@ config INFINIBAND_USER_MAD
 
 config INFINIBAND_USER_ACCESS
        tristate "InfiniBand userspace access (verbs and CM)"
-       depends on INFINIBAND
        ---help---
          Userspace InfiniBand access support.  This enables the
          kernel side of userspace verbs and the userspace
@@ -37,7 +36,7 @@ config INFINIBAND_USER_MEM
 
 config INFINIBAND_ADDR_TRANS
        bool
-       depends on INFINIBAND && INET
+       depends on INET
        default y
 
 source "drivers/infiniband/hw/mthca/Kconfig"
@@ -54,4 +53,4 @@ source "drivers/infiniband/ulp/srp/Kconfig"
 
 source "drivers/infiniband/ulp/iser/Kconfig"
 
-endmenu
+endif # INFINIBAND
index ecd1a3057c61bf41e9f09c5be5727de78866620d..db2633e4aae6ec65b2bc49ecba6752a57b02650f 100644 (file)
@@ -3,7 +3,7 @@
  * Copyright (c) 2004, 2005 Infinicon Corporation.  All rights reserved.
  * Copyright (c) 2004, 2005 Intel Corporation.  All rights reserved.
  * Copyright (c) 2004, 2005 Topspin Corporation.  All rights reserved.
- * Copyright (c) 2004, 2005 Voltaire Corporation.  All rights reserved.
+ * Copyright (c) 2004-2007 Voltaire Corporation.  All rights reserved.
  * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -34,7 +34,6 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  *
- * $Id: agent.c 1389 2004-12-27 22:56:47Z roland $
  */
 
 #include <linux/slab.h>
@@ -42,6 +41,7 @@
 
 #include "agent.h"
 #include "smi.h"
+#include "mad_priv.h"
 
 #define SPFX "ib_agent: "
 
@@ -87,8 +87,13 @@ int agent_send_response(struct ib_mad *mad, struct ib_grh *grh,
        struct ib_mad_send_buf *send_buf;
        struct ib_ah *ah;
        int ret;
+       struct ib_mad_send_wr_private *mad_send_wr;
+
+       if (device->node_type == RDMA_NODE_IB_SWITCH)
+               port_priv = ib_get_agent_port(device, 0);
+       else
+               port_priv = ib_get_agent_port(device, port_num);
 
-       port_priv = ib_get_agent_port(device, port_num);
        if (!port_priv) {
                printk(KERN_ERR SPFX "Unable to find port agent\n");
                return -ENODEV;
@@ -113,6 +118,14 @@ int agent_send_response(struct ib_mad *mad, struct ib_grh *grh,
 
        memcpy(send_buf->mad, mad, sizeof *mad);
        send_buf->ah = ah;
+
+       if (device->node_type == RDMA_NODE_IB_SWITCH) {
+               mad_send_wr = container_of(send_buf,
+                                          struct ib_mad_send_wr_private,
+                                          send_buf);
+               mad_send_wr->send_wr.wr.ud.port_num = port_num;
+       }
+
        if ((ret = ib_post_send_mad(send_buf, NULL))) {
                printk(KERN_ERR SPFX "ib_post_send_mad error:%d\n", ret);
                goto err2;
index 40c004a2697e62281c17380f32cfea619f0a9f95..9820c67ba47dd2566eaaac76cce25e5a0ebdc834 100644 (file)
@@ -87,6 +87,7 @@ struct cm_port {
 struct cm_device {
        struct list_head list;
        struct ib_device *device;
+       u8 ack_delay;
        struct cm_port port[0];
 };
 
@@ -95,7 +96,7 @@ struct cm_av {
        union ib_gid dgid;
        struct ib_ah_attr ah_attr;
        u16 pkey_index;
-       u8 packet_life_time;
+       u8 timeout;
 };
 
 struct cm_work {
@@ -154,6 +155,7 @@ struct cm_id_private {
        u8 retry_count;
        u8 rnr_retry_count;
        u8 service_timeout;
+       u8 target_ack_delay;
 
        struct list_head work_list;
        atomic_t work_count;
@@ -293,7 +295,7 @@ static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av)
        av->port = port;
        ib_init_ah_from_path(cm_dev->device, port->port_num, path,
                             &av->ah_attr);
-       av->packet_life_time = path->packet_life_time;
+       av->timeout = path->packet_life_time + 1;
        return 0;
 }
 
@@ -318,12 +320,10 @@ static int cm_alloc_id(struct cm_id_private *cm_id_priv)
 
 static void cm_free_id(__be32 local_id)
 {
-       unsigned long flags;
-
-       spin_lock_irqsave(&cm.lock, flags);
+       spin_lock_irq(&cm.lock);
        idr_remove(&cm.local_id_table,
                   (__force int) (local_id ^ cm.random_id_operand));
-       spin_unlock_irqrestore(&cm.lock, flags);
+       spin_unlock_irq(&cm.lock);
 }
 
 static struct cm_id_private * cm_get_id(__be32 local_id, __be32 remote_id)
@@ -345,11 +345,10 @@ static struct cm_id_private * cm_get_id(__be32 local_id, __be32 remote_id)
 static struct cm_id_private * cm_acquire_id(__be32 local_id, __be32 remote_id)
 {
        struct cm_id_private *cm_id_priv;
-       unsigned long flags;
 
-       spin_lock_irqsave(&cm.lock, flags);
+       spin_lock_irq(&cm.lock);
        cm_id_priv = cm_get_id(local_id, remote_id);
-       spin_unlock_irqrestore(&cm.lock, flags);
+       spin_unlock_irq(&cm.lock);
 
        return cm_id_priv;
 }
@@ -646,6 +645,25 @@ static inline int cm_convert_to_ms(int iba_time)
        return 1 << max(iba_time - 8, 0);
 }
 
+/*
+ * calculate: 4.096x2^ack_timeout = 4.096x2^ack_delay + 2x4.096x2^life_time
+ * Because of how ack_timeout is stored, adding one doubles the timeout.
+ * To avoid large timeouts, select the max(ack_delay, life_time + 1), and
+ * increment it (round up) only if the other is within 50%.
+ */
+static u8 cm_ack_timeout(u8 ca_ack_delay, u8 packet_life_time)
+{
+       int ack_timeout = packet_life_time + 1;
+
+       if (ack_timeout >= ca_ack_delay)
+               ack_timeout += (ca_ack_delay >= (ack_timeout - 1));
+       else
+               ack_timeout = ca_ack_delay +
+                             (ack_timeout >= (ca_ack_delay - 1));
+
+       return min(31, ack_timeout);
+}
+
 static void cm_cleanup_timewait(struct cm_timewait_info *timewait_info)
 {
        if (timewait_info->inserted_remote_id) {
@@ -689,7 +707,7 @@ static void cm_enter_timewait(struct cm_id_private *cm_id_priv)
         * timewait before notifying the user that we've exited timewait.
         */
        cm_id_priv->id.state = IB_CM_TIMEWAIT;
-       wait_time = cm_convert_to_ms(cm_id_priv->av.packet_life_time + 1);
+       wait_time = cm_convert_to_ms(cm_id_priv->av.timeout);
        queue_delayed_work(cm.wq, &cm_id_priv->timewait_info->work.work,
                           msecs_to_jiffies(wait_time));
        cm_id_priv->timewait_info = NULL;
@@ -713,31 +731,30 @@ static void cm_destroy_id(struct ib_cm_id *cm_id, int err)
 {
        struct cm_id_private *cm_id_priv;
        struct cm_work *work;
-       unsigned long flags;
 
        cm_id_priv = container_of(cm_id, struct cm_id_private, id);
 retest:
-       spin_lock_irqsave(&cm_id_priv->lock, flags);
+       spin_lock_irq(&cm_id_priv->lock);
        switch (cm_id->state) {
        case IB_CM_LISTEN:
                cm_id->state = IB_CM_IDLE;
-               spin_unlock_irqrestore(&cm_id_priv->lock, flags);
-               spin_lock_irqsave(&cm.lock, flags);
+               spin_unlock_irq(&cm_id_priv->lock);
+               spin_lock_irq(&cm.lock);
                rb_erase(&cm_id_priv->service_node, &cm.listen_service_table);
-               spin_unlock_irqrestore(&cm.lock, flags);
+               spin_unlock_irq(&cm.lock);
                break;
        case IB_CM_SIDR_REQ_SENT:
                cm_id->state = IB_CM_IDLE;
                ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
-               spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+               spin_unlock_irq(&cm_id_priv->lock);
                break;
        case IB_CM_SIDR_REQ_RCVD:
-               spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+               spin_unlock_irq(&cm_id_priv->lock);
                cm_reject_sidr_req(cm_id_priv, IB_SIDR_REJECT);
                break;
        case IB_CM_REQ_SENT:
                ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
-               spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+               spin_unlock_irq(&cm_id_priv->lock);
                ib_send_cm_rej(cm_id, IB_CM_REJ_TIMEOUT,
                               &cm_id_priv->id.device->node_guid,
                               sizeof cm_id_priv->id.device->node_guid,
@@ -747,9 +764,9 @@ retest:
                if (err == -ENOMEM) {
                        /* Do not reject to allow future retries. */
                        cm_reset_to_idle(cm_id_priv);
-                       spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+                       spin_unlock_irq(&cm_id_priv->lock);
                } else {
-                       spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+                       spin_unlock_irq(&cm_id_priv->lock);
                        ib_send_cm_rej(cm_id, IB_CM_REJ_CONSUMER_DEFINED,
                                       NULL, 0, NULL, 0);
                }
@@ -762,25 +779,25 @@ retest:
        case IB_CM_MRA_REQ_SENT:
        case IB_CM_REP_RCVD:
        case IB_CM_MRA_REP_SENT:
-               spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+               spin_unlock_irq(&cm_id_priv->lock);
                ib_send_cm_rej(cm_id, IB_CM_REJ_CONSUMER_DEFINED,
                               NULL, 0, NULL, 0);
                break;
        case IB_CM_ESTABLISHED:
-               spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+               spin_unlock_irq(&cm_id_priv->lock);
                ib_send_cm_dreq(cm_id, NULL, 0);
                goto retest;
        case IB_CM_DREQ_SENT:
                ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
                cm_enter_timewait(cm_id_priv);
-               spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+               spin_unlock_irq(&cm_id_priv->lock);
                break;
        case IB_CM_DREQ_RCVD:
-               spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+               spin_unlock_irq(&cm_id_priv->lock);
                ib_send_cm_drep(cm_id, NULL, 0);
                break;
        default:
-               spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+               spin_unlock_irq(&cm_id_priv->lock);
                break;
        }
 
@@ -912,7 +929,8 @@ static void cm_format_req(struct cm_req_msg *req_msg,
        cm_req_set_primary_sl(req_msg, param->primary_path->sl);
        cm_req_set_primary_subnet_local(req_msg, 1); /* local only... */
        cm_req_set_primary_local_ack_timeout(req_msg,
-               min(31, param->primary_path->packet_life_time + 1));
+               cm_ack_timeout(cm_id_priv->av.port->cm_dev->ack_delay,
+                              param->primary_path->packet_life_time));
 
        if (param->alternate_path) {
                req_msg->alt_local_lid = param->alternate_path->slid;
@@ -927,7 +945,8 @@ static void cm_format_req(struct cm_req_msg *req_msg,
                cm_req_set_alt_sl(req_msg, param->alternate_path->sl);
                cm_req_set_alt_subnet_local(req_msg, 1); /* local only... */
                cm_req_set_alt_local_ack_timeout(req_msg,
-                       min(31, param->alternate_path->packet_life_time + 1));
+                       cm_ack_timeout(cm_id_priv->av.port->cm_dev->ack_delay,
+                                      param->alternate_path->packet_life_time));
        }
 
        if (param->private_data && param->private_data_len)
@@ -1169,7 +1188,6 @@ static void cm_format_req_event(struct cm_work *work,
 static void cm_process_work(struct cm_id_private *cm_id_priv,
                            struct cm_work *work)
 {
-       unsigned long flags;
        int ret;
 
        /* We will typically only have the current event to report. */
@@ -1177,9 +1195,9 @@ static void cm_process_work(struct cm_id_private *cm_id_priv,
        cm_free_work(work);
 
        while (!ret && !atomic_add_negative(-1, &cm_id_priv->work_count)) {
-               spin_lock_irqsave(&cm_id_priv->lock, flags);
+               spin_lock_irq(&cm_id_priv->lock);
                work = cm_dequeue_work(cm_id_priv);
-               spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+               spin_unlock_irq(&cm_id_priv->lock);
                BUG_ON(!work);
                ret = cm_id_priv->id.cm_handler(&cm_id_priv->id,
                                                &work->cm_event);
@@ -1250,7 +1268,6 @@ static void cm_dup_req_handler(struct cm_work *work,
                               struct cm_id_private *cm_id_priv)
 {
        struct ib_mad_send_buf *msg = NULL;
-       unsigned long flags;
        int ret;
 
        /* Quick state check to discard duplicate REQs. */
@@ -1261,7 +1278,7 @@ static void cm_dup_req_handler(struct cm_work *work,
        if (ret)
                return;
 
-       spin_lock_irqsave(&cm_id_priv->lock, flags);
+       spin_lock_irq(&cm_id_priv->lock);
        switch (cm_id_priv->id.state) {
        case IB_CM_MRA_REQ_SENT:
                cm_format_mra((struct cm_mra_msg *) msg->mad, cm_id_priv,
@@ -1276,14 +1293,14 @@ static void cm_dup_req_handler(struct cm_work *work,
        default:
                goto unlock;
        }
-       spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+       spin_unlock_irq(&cm_id_priv->lock);
 
        ret = ib_post_send_mad(msg, NULL);
        if (ret)
                goto free;
        return;
 
-unlock:        spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+unlock:        spin_unlock_irq(&cm_id_priv->lock);
 free:  cm_free_msg(msg);
 }
 
@@ -1293,17 +1310,16 @@ static struct cm_id_private * cm_match_req(struct cm_work *work,
        struct cm_id_private *listen_cm_id_priv, *cur_cm_id_priv;
        struct cm_timewait_info *timewait_info;
        struct cm_req_msg *req_msg;
-       unsigned long flags;
 
        req_msg = (struct cm_req_msg *)work->mad_recv_wc->recv_buf.mad;
 
        /* Check for possible duplicate REQ. */
-       spin_lock_irqsave(&cm.lock, flags);
+       spin_lock_irq(&cm.lock);
        timewait_info = cm_insert_remote_id(cm_id_priv->timewait_info);
        if (timewait_info) {
                cur_cm_id_priv = cm_get_id(timewait_info->work.local_id,
                                           timewait_info->work.remote_id);
-               spin_unlock_irqrestore(&cm.lock, flags);
+               spin_unlock_irq(&cm.lock);
                if (cur_cm_id_priv) {
                        cm_dup_req_handler(work, cur_cm_id_priv);
                        cm_deref_id(cur_cm_id_priv);
@@ -1315,7 +1331,7 @@ static struct cm_id_private * cm_match_req(struct cm_work *work,
        timewait_info = cm_insert_remote_qpn(cm_id_priv->timewait_info);
        if (timewait_info) {
                cm_cleanup_timewait(cm_id_priv->timewait_info);
-               spin_unlock_irqrestore(&cm.lock, flags);
+               spin_unlock_irq(&cm.lock);
                cm_issue_rej(work->port, work->mad_recv_wc,
                             IB_CM_REJ_STALE_CONN, CM_MSG_RESPONSE_REQ,
                             NULL, 0);
@@ -1328,7 +1344,7 @@ static struct cm_id_private * cm_match_req(struct cm_work *work,
                                           req_msg->private_data);
        if (!listen_cm_id_priv) {
                cm_cleanup_timewait(cm_id_priv->timewait_info);
-               spin_unlock_irqrestore(&cm.lock, flags);
+               spin_unlock_irq(&cm.lock);
                cm_issue_rej(work->port, work->mad_recv_wc,
                             IB_CM_REJ_INVALID_SERVICE_ID, CM_MSG_RESPONSE_REQ,
                             NULL, 0);
@@ -1338,7 +1354,7 @@ static struct cm_id_private * cm_match_req(struct cm_work *work,
        atomic_inc(&cm_id_priv->refcount);
        cm_id_priv->id.state = IB_CM_REQ_RCVD;
        atomic_inc(&cm_id_priv->work_count);
-       spin_unlock_irqrestore(&cm.lock, flags);
+       spin_unlock_irq(&cm.lock);
 out:
        return listen_cm_id_priv;
 }
@@ -1440,7 +1456,8 @@ static void cm_format_rep(struct cm_rep_msg *rep_msg,
        cm_rep_set_starting_psn(rep_msg, cpu_to_be32(param->starting_psn));
        rep_msg->resp_resources = param->responder_resources;
        rep_msg->initiator_depth = param->initiator_depth;
-       cm_rep_set_target_ack_delay(rep_msg, param->target_ack_delay);
+       cm_rep_set_target_ack_delay(rep_msg,
+                                   cm_id_priv->av.port->cm_dev->ack_delay);
        cm_rep_set_failover(rep_msg, param->failover_accepted);
        cm_rep_set_flow_ctrl(rep_msg, param->flow_control);
        cm_rep_set_rnr_retry_count(rep_msg, param->rnr_retry_count);
@@ -1591,7 +1608,6 @@ static void cm_dup_rep_handler(struct cm_work *work)
        struct cm_id_private *cm_id_priv;
        struct cm_rep_msg *rep_msg;
        struct ib_mad_send_buf *msg = NULL;
-       unsigned long flags;
        int ret;
 
        rep_msg = (struct cm_rep_msg *) work->mad_recv_wc->recv_buf.mad;
@@ -1604,7 +1620,7 @@ static void cm_dup_rep_handler(struct cm_work *work)
        if (ret)
                goto deref;
 
-       spin_lock_irqsave(&cm_id_priv->lock, flags);
+       spin_lock_irq(&cm_id_priv->lock);
        if (cm_id_priv->id.state == IB_CM_ESTABLISHED)
                cm_format_rtu((struct cm_rtu_msg *) msg->mad, cm_id_priv,
                              cm_id_priv->private_data,
@@ -1616,14 +1632,14 @@ static void cm_dup_rep_handler(struct cm_work *work)
                              cm_id_priv->private_data_len);
        else
                goto unlock;
-       spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+       spin_unlock_irq(&cm_id_priv->lock);
 
        ret = ib_post_send_mad(msg, NULL);
        if (ret)
                goto free;
        goto deref;
 
-unlock:        spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+unlock:        spin_unlock_irq(&cm_id_priv->lock);
 free:  cm_free_msg(msg);
 deref: cm_deref_id(cm_id_priv);
 }
@@ -1632,7 +1648,6 @@ static int cm_rep_handler(struct cm_work *work)
 {
        struct cm_id_private *cm_id_priv;
        struct cm_rep_msg *rep_msg;
-       unsigned long flags;
        int ret;
 
        rep_msg = (struct cm_rep_msg *)work->mad_recv_wc->recv_buf.mad;
@@ -1644,13 +1659,13 @@ static int cm_rep_handler(struct cm_work *work)
 
        cm_format_rep_event(work);
 
-       spin_lock_irqsave(&cm_id_priv->lock, flags);
+       spin_lock_irq(&cm_id_priv->lock);
        switch (cm_id_priv->id.state) {
        case IB_CM_REQ_SENT:
        case IB_CM_MRA_REQ_RCVD:
                break;
        default:
-               spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+               spin_unlock_irq(&cm_id_priv->lock);
                ret = -EINVAL;
                goto error;
        }
@@ -1663,7 +1678,7 @@ static int cm_rep_handler(struct cm_work *work)
        /* Check for duplicate REP. */
        if (cm_insert_remote_id(cm_id_priv->timewait_info)) {
                spin_unlock(&cm.lock);
-               spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+               spin_unlock_irq(&cm_id_priv->lock);
                ret = -EINVAL;
                goto error;
        }
@@ -1673,7 +1688,7 @@ static int cm_rep_handler(struct cm_work *work)
                         &cm.remote_id_table);
                cm_id_priv->timewait_info->inserted_remote_id = 0;
                spin_unlock(&cm.lock);
-               spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+               spin_unlock_irq(&cm_id_priv->lock);
                cm_issue_rej(work->port, work->mad_recv_wc,
                             IB_CM_REJ_STALE_CONN, CM_MSG_RESPONSE_REP,
                             NULL, 0);
@@ -1689,6 +1704,13 @@ static int cm_rep_handler(struct cm_work *work)
        cm_id_priv->responder_resources = rep_msg->initiator_depth;
        cm_id_priv->sq_psn = cm_rep_get_starting_psn(rep_msg);
        cm_id_priv->rnr_retry_count = cm_rep_get_rnr_retry_count(rep_msg);
+       cm_id_priv->target_ack_delay = cm_rep_get_target_ack_delay(rep_msg);
+       cm_id_priv->av.timeout =
+                       cm_ack_timeout(cm_id_priv->target_ack_delay,
+                                      cm_id_priv->av.timeout - 1);
+       cm_id_priv->alt_av.timeout =
+                       cm_ack_timeout(cm_id_priv->target_ack_delay,
+                                      cm_id_priv->alt_av.timeout - 1);
 
        /* todo: handle peer_to_peer */
 
@@ -1696,7 +1718,7 @@ static int cm_rep_handler(struct cm_work *work)
        ret = atomic_inc_and_test(&cm_id_priv->work_count);
        if (!ret)
                list_add_tail(&work->list, &cm_id_priv->work_list);
-       spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+       spin_unlock_irq(&cm_id_priv->lock);
 
        if (ret)
                cm_process_work(cm_id_priv, work);
@@ -1712,7 +1734,6 @@ error:
 static int cm_establish_handler(struct cm_work *work)
 {
        struct cm_id_private *cm_id_priv;
-       unsigned long flags;
        int ret;
 
        /* See comment in cm_establish about lookup. */
@@ -1720,9 +1741,9 @@ static int cm_establish_handler(struct cm_work *work)
        if (!cm_id_priv)
                return -EINVAL;
 
-       spin_lock_irqsave(&cm_id_priv->lock, flags);
+       spin_lock_irq(&cm_id_priv->lock);
        if (cm_id_priv->id.state != IB_CM_ESTABLISHED) {
-               spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+               spin_unlock_irq(&cm_id_priv->lock);
                goto out;
        }
 
@@ -1730,7 +1751,7 @@ static int cm_establish_handler(struct cm_work *work)
        ret = atomic_inc_and_test(&cm_id_priv->work_count);
        if (!ret)
                list_add_tail(&work->list, &cm_id_priv->work_list);
-       spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+       spin_unlock_irq(&cm_id_priv->lock);
 
        if (ret)
                cm_process_work(cm_id_priv, work);
@@ -1746,7 +1767,6 @@ static int cm_rtu_handler(struct cm_work *work)
 {
        struct cm_id_private *cm_id_priv;
        struct cm_rtu_msg *rtu_msg;
-       unsigned long flags;
        int ret;
 
        rtu_msg = (struct cm_rtu_msg *)work->mad_recv_wc->recv_buf.mad;
@@ -1757,10 +1777,10 @@ static int cm_rtu_handler(struct cm_work *work)
 
        work->cm_event.private_data = &rtu_msg->private_data;
 
-       spin_lock_irqsave(&cm_id_priv->lock, flags);
+       spin_lock_irq(&cm_id_priv->lock);
        if (cm_id_priv->id.state != IB_CM_REP_SENT &&
            cm_id_priv->id.state != IB_CM_MRA_REP_RCVD) {
-               spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+               spin_unlock_irq(&cm_id_priv->lock);
                goto out;
        }
        cm_id_priv->id.state = IB_CM_ESTABLISHED;
@@ -1769,7 +1789,7 @@ static int cm_rtu_handler(struct cm_work *work)
        ret = atomic_inc_and_test(&cm_id_priv->work_count);
        if (!ret)
                list_add_tail(&work->list, &cm_id_priv->work_list);
-       spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+       spin_unlock_irq(&cm_id_priv->lock);
 
        if (ret)
                cm_process_work(cm_id_priv, work);
@@ -1932,7 +1952,6 @@ static int cm_dreq_handler(struct cm_work *work)
        struct cm_id_private *cm_id_priv;
        struct cm_dreq_msg *dreq_msg;
        struct ib_mad_send_buf *msg = NULL;
-       unsigned long flags;
        int ret;
 
        dreq_msg = (struct cm_dreq_msg *)work->mad_recv_wc->recv_buf.mad;
@@ -1945,7 +1964,7 @@ static int cm_dreq_handler(struct cm_work *work)
 
        work->cm_event.private_data = &dreq_msg->private_data;
 
-       spin_lock_irqsave(&cm_id_priv->lock, flags);
+       spin_lock_irq(&cm_id_priv->lock);
        if (cm_id_priv->local_qpn != cm_dreq_get_remote_qpn(dreq_msg))
                goto unlock;
 
@@ -1964,7 +1983,7 @@ static int cm_dreq_handler(struct cm_work *work)
                cm_format_drep((struct cm_drep_msg *) msg->mad, cm_id_priv,
                               cm_id_priv->private_data,
                               cm_id_priv->private_data_len);
-               spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+               spin_unlock_irq(&cm_id_priv->lock);
 
                if (ib_post_send_mad(msg, NULL))
                        cm_free_msg(msg);
@@ -1977,7 +1996,7 @@ static int cm_dreq_handler(struct cm_work *work)
        ret = atomic_inc_and_test(&cm_id_priv->work_count);
        if (!ret)
                list_add_tail(&work->list, &cm_id_priv->work_list);
-       spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+       spin_unlock_irq(&cm_id_priv->lock);
 
        if (ret)
                cm_process_work(cm_id_priv, work);
@@ -1985,7 +2004,7 @@ static int cm_dreq_handler(struct cm_work *work)
                cm_deref_id(cm_id_priv);
        return 0;
 
-unlock:        spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+unlock:        spin_unlock_irq(&cm_id_priv->lock);
 deref: cm_deref_id(cm_id_priv);
        return -EINVAL;
 }
@@ -1994,7 +2013,6 @@ static int cm_drep_handler(struct cm_work *work)
 {
        struct cm_id_private *cm_id_priv;
        struct cm_drep_msg *drep_msg;
-       unsigned long flags;
        int ret;
 
        drep_msg = (struct cm_drep_msg *)work->mad_recv_wc->recv_buf.mad;
@@ -2005,10 +2023,10 @@ static int cm_drep_handler(struct cm_work *work)
 
        work->cm_event.private_data = &drep_msg->private_data;
 
-       spin_lock_irqsave(&cm_id_priv->lock, flags);
+       spin_lock_irq(&cm_id_priv->lock);
        if (cm_id_priv->id.state != IB_CM_DREQ_SENT &&
            cm_id_priv->id.state != IB_CM_DREQ_RCVD) {
-               spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+               spin_unlock_irq(&cm_id_priv->lock);
                goto out;
        }
        cm_enter_timewait(cm_id_priv);
@@ -2017,7 +2035,7 @@ static int cm_drep_handler(struct cm_work *work)
        ret = atomic_inc_and_test(&cm_id_priv->work_count);
        if (!ret)
                list_add_tail(&work->list, &cm_id_priv->work_list);
-       spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+       spin_unlock_irq(&cm_id_priv->lock);
 
        if (ret)
                cm_process_work(cm_id_priv, work);
@@ -2107,17 +2125,16 @@ static struct cm_id_private * cm_acquire_rejected_id(struct cm_rej_msg *rej_msg)
 {
        struct cm_timewait_info *timewait_info;
        struct cm_id_private *cm_id_priv;
-       unsigned long flags;
        __be32 remote_id;
 
        remote_id = rej_msg->local_comm_id;
 
        if (__be16_to_cpu(rej_msg->reason) == IB_CM_REJ_TIMEOUT) {
-               spin_lock_irqsave(&cm.lock, flags);
+               spin_lock_irq(&cm.lock);
                timewait_info = cm_find_remote_id( *((__be64 *) rej_msg->ari),
                                                  remote_id);
                if (!timewait_info) {
-                       spin_unlock_irqrestore(&cm.lock, flags);
+                       spin_unlock_irq(&cm.lock);
                        return NULL;
                }
                cm_id_priv = idr_find(&cm.local_id_table, (__force int)
@@ -2129,7 +2146,7 @@ static struct cm_id_private * cm_acquire_rejected_id(struct cm_rej_msg *rej_msg)
                        else
                                cm_id_priv = NULL;
                }
-               spin_unlock_irqrestore(&cm.lock, flags);
+               spin_unlock_irq(&cm.lock);
        } else if (cm_rej_get_msg_rejected(rej_msg) == CM_MSG_RESPONSE_REQ)
                cm_id_priv = cm_acquire_id(rej_msg->remote_comm_id, 0);
        else
@@ -2142,7 +2159,6 @@ static int cm_rej_handler(struct cm_work *work)
 {
        struct cm_id_private *cm_id_priv;
        struct cm_rej_msg *rej_msg;
-       unsigned long flags;
        int ret;
 
        rej_msg = (struct cm_rej_msg *)work->mad_recv_wc->recv_buf.mad;
@@ -2152,7 +2168,7 @@ static int cm_rej_handler(struct cm_work *work)
 
        cm_format_rej_event(work);
 
-       spin_lock_irqsave(&cm_id_priv->lock, flags);
+       spin_lock_irq(&cm_id_priv->lock);
        switch (cm_id_priv->id.state) {
        case IB_CM_REQ_SENT:
        case IB_CM_MRA_REQ_RCVD:
@@ -2176,7 +2192,7 @@ static int cm_rej_handler(struct cm_work *work)
                cm_enter_timewait(cm_id_priv);
                break;
        default:
-               spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+               spin_unlock_irq(&cm_id_priv->lock);
                ret = -EINVAL;
                goto out;
        }
@@ -2184,7 +2200,7 @@ static int cm_rej_handler(struct cm_work *work)
        ret = atomic_inc_and_test(&cm_id_priv->work_count);
        if (!ret)
                list_add_tail(&work->list, &cm_id_priv->work_list);
-       spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+       spin_unlock_irq(&cm_id_priv->lock);
 
        if (ret)
                cm_process_work(cm_id_priv, work);
@@ -2295,7 +2311,6 @@ static int cm_mra_handler(struct cm_work *work)
 {
        struct cm_id_private *cm_id_priv;
        struct cm_mra_msg *mra_msg;
-       unsigned long flags;
        int timeout, ret;
 
        mra_msg = (struct cm_mra_msg *)work->mad_recv_wc->recv_buf.mad;
@@ -2307,9 +2322,9 @@ static int cm_mra_handler(struct cm_work *work)
        work->cm_event.param.mra_rcvd.service_timeout =
                                        cm_mra_get_service_timeout(mra_msg);
        timeout = cm_convert_to_ms(cm_mra_get_service_timeout(mra_msg)) +
-                 cm_convert_to_ms(cm_id_priv->av.packet_life_time);
+                 cm_convert_to_ms(cm_id_priv->av.timeout);
 
-       spin_lock_irqsave(&cm_id_priv->lock, flags);
+       spin_lock_irq(&cm_id_priv->lock);
        switch (cm_id_priv->id.state) {
        case IB_CM_REQ_SENT:
                if (cm_mra_get_msg_mraed(mra_msg) != CM_MSG_RESPONSE_REQ ||
@@ -2342,7 +2357,7 @@ static int cm_mra_handler(struct cm_work *work)
        ret = atomic_inc_and_test(&cm_id_priv->work_count);
        if (!ret)
                list_add_tail(&work->list, &cm_id_priv->work_list);
-       spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+       spin_unlock_irq(&cm_id_priv->lock);
 
        if (ret)
                cm_process_work(cm_id_priv, work);
@@ -2350,7 +2365,7 @@ static int cm_mra_handler(struct cm_work *work)
                cm_deref_id(cm_id_priv);
        return 0;
 out:
-       spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+       spin_unlock_irq(&cm_id_priv->lock);
        cm_deref_id(cm_id_priv);
        return -EINVAL;
 }
@@ -2379,7 +2394,8 @@ static void cm_format_lap(struct cm_lap_msg *lap_msg,
        cm_lap_set_sl(lap_msg, alternate_path->sl);
        cm_lap_set_subnet_local(lap_msg, 1); /* local only... */
        cm_lap_set_local_ack_timeout(lap_msg,
-               min(31, alternate_path->packet_life_time + 1));
+               cm_ack_timeout(cm_id_priv->av.port->cm_dev->ack_delay,
+                              alternate_path->packet_life_time));
 
        if (private_data && private_data_len)
                memcpy(lap_msg->private_data, private_data, private_data_len);
@@ -2410,6 +2426,9 @@ int ib_send_cm_lap(struct ib_cm_id *cm_id,
        ret = cm_init_av_by_path(alternate_path, &cm_id_priv->alt_av);
        if (ret)
                goto out;
+       cm_id_priv->alt_av.timeout =
+                       cm_ack_timeout(cm_id_priv->target_ack_delay,
+                                      cm_id_priv->alt_av.timeout - 1);
 
        ret = cm_alloc_msg(cm_id_priv, &msg);
        if (ret)
@@ -2465,7 +2484,6 @@ static int cm_lap_handler(struct cm_work *work)
        struct cm_lap_msg *lap_msg;
        struct ib_cm_lap_event_param *param;
        struct ib_mad_send_buf *msg = NULL;
-       unsigned long flags;
        int ret;
 
        /* todo: verify LAP request and send reject APR if invalid. */
@@ -2480,7 +2498,7 @@ static int cm_lap_handler(struct cm_work *work)
        cm_format_path_from_lap(cm_id_priv, param->alternate_path, lap_msg);
        work->cm_event.private_data = &lap_msg->private_data;
 
-       spin_lock_irqsave(&cm_id_priv->lock, flags);
+       spin_lock_irq(&cm_id_priv->lock);
        if (cm_id_priv->id.state != IB_CM_ESTABLISHED)
                goto unlock;
 
@@ -2497,7 +2515,7 @@ static int cm_lap_handler(struct cm_work *work)
                              cm_id_priv->service_timeout,
                              cm_id_priv->private_data,
                              cm_id_priv->private_data_len);
-               spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+               spin_unlock_irq(&cm_id_priv->lock);
 
                if (ib_post_send_mad(msg, NULL))
                        cm_free_msg(msg);
@@ -2515,7 +2533,7 @@ static int cm_lap_handler(struct cm_work *work)
        ret = atomic_inc_and_test(&cm_id_priv->work_count);
        if (!ret)
                list_add_tail(&work->list, &cm_id_priv->work_list);
-       spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+       spin_unlock_irq(&cm_id_priv->lock);
 
        if (ret)
                cm_process_work(cm_id_priv, work);
@@ -2523,7 +2541,7 @@ static int cm_lap_handler(struct cm_work *work)
                cm_deref_id(cm_id_priv);
        return 0;
 
-unlock:        spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+unlock:        spin_unlock_irq(&cm_id_priv->lock);
 deref: cm_deref_id(cm_id_priv);
        return -EINVAL;
 }
@@ -2598,7 +2616,6 @@ static int cm_apr_handler(struct cm_work *work)
 {
        struct cm_id_private *cm_id_priv;
        struct cm_apr_msg *apr_msg;
-       unsigned long flags;
        int ret;
 
        apr_msg = (struct cm_apr_msg *)work->mad_recv_wc->recv_buf.mad;
@@ -2612,11 +2629,11 @@ static int cm_apr_handler(struct cm_work *work)
        work->cm_event.param.apr_rcvd.info_len = apr_msg->info_length;
        work->cm_event.private_data = &apr_msg->private_data;
 
-       spin_lock_irqsave(&cm_id_priv->lock, flags);
+       spin_lock_irq(&cm_id_priv->lock);
        if (cm_id_priv->id.state != IB_CM_ESTABLISHED ||
            (cm_id_priv->id.lap_state != IB_CM_LAP_SENT &&
             cm_id_priv->id.lap_state != IB_CM_MRA_LAP_RCVD)) {
-               spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+               spin_unlock_irq(&cm_id_priv->lock);
                goto out;
        }
        cm_id_priv->id.lap_state = IB_CM_LAP_IDLE;
@@ -2626,7 +2643,7 @@ static int cm_apr_handler(struct cm_work *work)
        ret = atomic_inc_and_test(&cm_id_priv->work_count);
        if (!ret)
                list_add_tail(&work->list, &cm_id_priv->work_list);
-       spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+       spin_unlock_irq(&cm_id_priv->lock);
 
        if (ret)
                cm_process_work(cm_id_priv, work);
@@ -2761,7 +2778,6 @@ static int cm_sidr_req_handler(struct cm_work *work)
        struct cm_id_private *cm_id_priv, *cur_cm_id_priv;
        struct cm_sidr_req_msg *sidr_req_msg;
        struct ib_wc *wc;
-       unsigned long flags;
 
        cm_id = ib_create_cm_id(work->port->cm_dev->device, NULL, NULL);
        if (IS_ERR(cm_id))
@@ -2778,27 +2794,26 @@ static int cm_sidr_req_handler(struct cm_work *work)
                                work->mad_recv_wc->recv_buf.grh,
                                &cm_id_priv->av);
        cm_id_priv->id.remote_id = sidr_req_msg->request_id;
-       cm_id_priv->id.state = IB_CM_SIDR_REQ_RCVD;
        cm_id_priv->tid = sidr_req_msg->hdr.tid;
        atomic_inc(&cm_id_priv->work_count);
 
-       spin_lock_irqsave(&cm.lock, flags);
+       spin_lock_irq(&cm.lock);
        cur_cm_id_priv = cm_insert_remote_sidr(cm_id_priv);
        if (cur_cm_id_priv) {
-               spin_unlock_irqrestore(&cm.lock, flags);
+               spin_unlock_irq(&cm.lock);
                goto out; /* Duplicate message. */
        }
+       cm_id_priv->id.state = IB_CM_SIDR_REQ_RCVD;
        cur_cm_id_priv = cm_find_listen(cm_id->device,
                                        sidr_req_msg->service_id,
                                        sidr_req_msg->private_data);
        if (!cur_cm_id_priv) {
-               rb_erase(&cm_id_priv->sidr_id_node, &cm.remote_sidr_table);
-               spin_unlock_irqrestore(&cm.lock, flags);
-               /* todo: reply with no match */
+               spin_unlock_irq(&cm.lock);
+               cm_reject_sidr_req(cm_id_priv, IB_SIDR_UNSUPPORTED);
                goto out; /* No match. */
        }
        atomic_inc(&cur_cm_id_priv->refcount);
-       spin_unlock_irqrestore(&cm.lock, flags);
+       spin_unlock_irq(&cm.lock);
 
        cm_id_priv->id.cm_handler = cur_cm_id_priv->id.cm_handler;
        cm_id_priv->id.context = cur_cm_id_priv->id.context;
@@ -2899,7 +2914,6 @@ static int cm_sidr_rep_handler(struct cm_work *work)
 {
        struct cm_sidr_rep_msg *sidr_rep_msg;
        struct cm_id_private *cm_id_priv;
-       unsigned long flags;
 
        sidr_rep_msg = (struct cm_sidr_rep_msg *)
                                work->mad_recv_wc->recv_buf.mad;
@@ -2907,14 +2921,14 @@ static int cm_sidr_rep_handler(struct cm_work *work)
        if (!cm_id_priv)
                return -EINVAL; /* Unmatched reply. */
 
-       spin_lock_irqsave(&cm_id_priv->lock, flags);
+       spin_lock_irq(&cm_id_priv->lock);
        if (cm_id_priv->id.state != IB_CM_SIDR_REQ_SENT) {
-               spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+               spin_unlock_irq(&cm_id_priv->lock);
                goto out;
        }
        cm_id_priv->id.state = IB_CM_IDLE;
        ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
-       spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+       spin_unlock_irq(&cm_id_priv->lock);
 
        cm_format_sidr_rep_event(work);
        cm_process_work(cm_id_priv, work);
@@ -2930,14 +2944,13 @@ static void cm_process_send_error(struct ib_mad_send_buf *msg,
        struct cm_id_private *cm_id_priv;
        struct ib_cm_event cm_event;
        enum ib_cm_state state;
-       unsigned long flags;
        int ret;
 
        memset(&cm_event, 0, sizeof cm_event);
        cm_id_priv = msg->context[0];
 
        /* Discard old sends or ones without a response. */
-       spin_lock_irqsave(&cm_id_priv->lock, flags);
+       spin_lock_irq(&cm_id_priv->lock);
        state = (enum ib_cm_state) (unsigned long) msg->context[1];
        if (msg != cm_id_priv->msg || state != cm_id_priv->id.state)
                goto discard;
@@ -2964,7 +2977,7 @@ static void cm_process_send_error(struct ib_mad_send_buf *msg,
        default:
                goto discard;
        }
-       spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+       spin_unlock_irq(&cm_id_priv->lock);
        cm_event.param.send_status = wc_status;
 
        /* No other events can occur on the cm_id at this point. */
@@ -2974,7 +2987,7 @@ static void cm_process_send_error(struct ib_mad_send_buf *msg,
                ib_destroy_cm_id(&cm_id_priv->id);
        return;
 discard:
-       spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+       spin_unlock_irq(&cm_id_priv->lock);
        cm_free_msg(msg);
 }
 
@@ -3269,8 +3282,7 @@ static int cm_init_qp_rtr_attr(struct cm_id_private *cm_id_priv,
                        *qp_attr_mask |= IB_QP_ALT_PATH;
                        qp_attr->alt_port_num = cm_id_priv->alt_av.port->port_num;
                        qp_attr->alt_pkey_index = cm_id_priv->alt_av.pkey_index;
-                       qp_attr->alt_timeout =
-                                       cm_id_priv->alt_av.packet_life_time + 1;
+                       qp_attr->alt_timeout = cm_id_priv->alt_av.timeout;
                        qp_attr->alt_ah_attr = cm_id_priv->alt_av.ah_attr;
                }
                ret = 0;
@@ -3308,8 +3320,7 @@ static int cm_init_qp_rts_attr(struct cm_id_private *cm_id_priv,
                                *qp_attr_mask |= IB_QP_TIMEOUT | IB_QP_RETRY_CNT |
                                                 IB_QP_RNR_RETRY |
                                                 IB_QP_MAX_QP_RD_ATOMIC;
-                               qp_attr->timeout =
-                                       cm_id_priv->av.packet_life_time + 1;
+                               qp_attr->timeout = cm_id_priv->av.timeout;
                                qp_attr->retry_cnt = cm_id_priv->retry_count;
                                qp_attr->rnr_retry = cm_id_priv->rnr_retry_count;
                                qp_attr->max_rd_atomic =
@@ -3323,8 +3334,7 @@ static int cm_init_qp_rts_attr(struct cm_id_private *cm_id_priv,
                        *qp_attr_mask = IB_QP_ALT_PATH | IB_QP_PATH_MIG_STATE;
                        qp_attr->alt_port_num = cm_id_priv->alt_av.port->port_num;
                        qp_attr->alt_pkey_index = cm_id_priv->alt_av.pkey_index;
-                       qp_attr->alt_timeout =
-                               cm_id_priv->alt_av.packet_life_time + 1;
+                       qp_attr->alt_timeout = cm_id_priv->alt_av.timeout;
                        qp_attr->alt_ah_attr = cm_id_priv->alt_av.ah_attr;
                        qp_attr->path_mig_state = IB_MIG_REARM;
                }
@@ -3364,6 +3374,16 @@ int ib_cm_init_qp_attr(struct ib_cm_id *cm_id,
 }
 EXPORT_SYMBOL(ib_cm_init_qp_attr);
 
+void cm_get_ack_delay(struct cm_device *cm_dev)
+{
+       struct ib_device_attr attr;
+
+       if (ib_query_device(cm_dev->device, &attr))
+               cm_dev->ack_delay = 0; /* acks will rely on packet life time */
+       else
+               cm_dev->ack_delay = attr.local_ca_ack_delay;
+}
+
 static void cm_add_one(struct ib_device *device)
 {
        struct cm_device *cm_dev;
@@ -3388,6 +3408,7 @@ static void cm_add_one(struct ib_device *device)
                return;
 
        cm_dev->device = device;
+       cm_get_ack_delay(cm_dev);
 
        set_bit(IB_MGMT_METHOD_SEND, reg_req.method_mask);
        for (i = 1; i <= device->phys_port_cnt; i++) {
index 4d3aee90c249783bee765b3286b944e6c3abc426..aec9c7af825dd9ba2e3b5dc8c9f18f1026eb3dfb 100644 (file)
@@ -35,6 +35,7 @@
 #define CM_MSGS_H
 
 #include <rdma/ib_mad.h>
+#include <rdma/ib_cm.h>
 
 /*
  * Parameters to routines below should be in network-byte order, and values
index 32a0e66d2a235215bece711619ae36003660142d..23af7a032a035fbb1c082ca69fdc69053d026515 100644 (file)
@@ -2326,7 +2326,6 @@ static int cma_accept_ib(struct rdma_id_private *id_priv,
        rep.private_data_len = conn_param->private_data_len;
        rep.responder_resources = conn_param->responder_resources;
        rep.initiator_depth = conn_param->initiator_depth;
-       rep.target_ack_delay = CMA_CM_RESPONSE_TIMEOUT;
        rep.failover_accepted = 0;
        rep.flow_control = conn_param->flow_control;
        rep.rnr_retry_count = conn_param->rnr_retry_count;
index 85ccf13b8041353db8c43b6b5bd91d4efb17b446..6b8faca02f8a169c779d56f547e5308bb398930c 100644 (file)
@@ -675,10 +675,16 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
        struct ib_mad_port_private *port_priv;
        struct ib_mad_agent_private *recv_mad_agent = NULL;
        struct ib_device *device = mad_agent_priv->agent.device;
-       u8 port_num = mad_agent_priv->agent.port_num;
+       u8 port_num;
        struct ib_wc mad_wc;
        struct ib_send_wr *send_wr = &mad_send_wr->send_wr;
 
+       if (device->node_type == RDMA_NODE_IB_SWITCH &&
+           smp->mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE)
+               port_num = send_wr->wr.ud.port_num;
+       else
+               port_num = mad_agent_priv->agent.port_num;
+
        /*
         * Directed route handling starts if the initial LID routed part of
         * a request or the ending LID routed part of a response is empty.
@@ -1839,6 +1845,7 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv,
        struct ib_mad_private *recv, *response;
        struct ib_mad_list_head *mad_list;
        struct ib_mad_agent_private *mad_agent;
+       int port_num;
 
        response = kmem_cache_alloc(ib_mad_cache, GFP_KERNEL);
        if (!response)
@@ -1872,25 +1879,50 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv,
        if (!validate_mad(&recv->mad.mad, qp_info->qp->qp_num))
                goto out;
 
+       if (port_priv->device->node_type == RDMA_NODE_IB_SWITCH)
+               port_num = wc->port_num;
+       else
+               port_num = port_priv->port_num;
+
        if (recv->mad.mad.mad_hdr.mgmt_class ==
            IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) {
+               enum smi_forward_action retsmi;
+
                if (smi_handle_dr_smp_recv(&recv->mad.smp,
                                           port_priv->device->node_type,
-                                          port_priv->port_num,
+                                          port_num,
                                           port_priv->device->phys_port_cnt) ==
                                           IB_SMI_DISCARD)
                        goto out;
 
-               if (smi_check_forward_dr_smp(&recv->mad.smp) == IB_SMI_LOCAL)
+               retsmi = smi_check_forward_dr_smp(&recv->mad.smp);
+               if (retsmi == IB_SMI_LOCAL)
                        goto local;
 
-               if (smi_handle_dr_smp_send(&recv->mad.smp,
-                                          port_priv->device->node_type,
-                                          port_priv->port_num) == IB_SMI_DISCARD)
-                       goto out;
+               if (retsmi == IB_SMI_SEND) { /* don't forward */
+                       if (smi_handle_dr_smp_send(&recv->mad.smp,
+                                                  port_priv->device->node_type,
+                                                  port_num) == IB_SMI_DISCARD)
+                               goto out;
+
+                       if (smi_check_local_smp(&recv->mad.smp, port_priv->device) == IB_SMI_DISCARD)
+                               goto out;
+               } else if (port_priv->device->node_type == RDMA_NODE_IB_SWITCH) {
+                       /* forward case for switches */
+                       memcpy(response, recv, sizeof(*response));
+                       response->header.recv_wc.wc = &response->header.wc;
+                       response->header.recv_wc.recv_buf.mad = &response->mad.mad;
+                       response->header.recv_wc.recv_buf.grh = &response->grh;
+
+                       if (!agent_send_response(&response->mad.mad,
+                                                &response->grh, wc,
+                                                port_priv->device,
+                                                smi_get_fwd_port(&recv->mad.smp),
+                                                qp_info->qp->qp_num))
+                               response = NULL;
 
-               if (smi_check_local_smp(&recv->mad.smp, port_priv->device) == IB_SMI_DISCARD)
                        goto out;
+               }
        }
 
 local:
@@ -1919,7 +1951,7 @@ local:
                                agent_send_response(&response->mad.mad,
                                                    &recv->grh, wc,
                                                    port_priv->device,
-                                                   port_priv->port_num,
+                                                   port_num,
                                                    qp_info->qp->qp_num);
                                goto out;
                        }
index 1e13ab42b70b5ceb382be0914cfd7bc34f904b4d..15b4c4d3606dbc4954d399e5ef0f1d5a5d254bb0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 Intel Corporation.  All rights reserved.
+ * Copyright (c) 2006 Intel Corporation.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
index 24c93fd320fb8716fb605c2c89afb9f9fd17ce6a..b1d4bbf4ce5c7f4fcc848b4cc98fd5fc007aa7f8 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2004 Topspin Communications.  All rights reserved.
- * Copyright (c) 2005 Voltaire, Inc.  All rights reserved.
+ * Copyright (c) 2005 Voltaire, Inc.  All rights reserved.
  * Copyright (c) 2006 Intel Corporation.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
index 6469406ea9d82551fe8135cfdead567708ef347e..20ab6b3e484d517f29a21fa316f51e01681b30c7 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2004 Topspin Communications.  All rights reserved.
- * Copyright (c) 2005 Voltaire, Inc.  All rights reserved.
+ * Copyright (c) 2005 Voltaire, Inc.  All rights reserved.
  * Copyright (c) 2006 Intel Corporation.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -56,6 +56,7 @@ MODULE_LICENSE("Dual BSD/GPL");
 struct ib_sa_sm_ah {
        struct ib_ah        *ah;
        struct kref          ref;
+       u16                  pkey_index;
        u8                   src_path_mask;
 };
 
@@ -382,6 +383,13 @@ static void update_sm_ah(struct work_struct *work)
        kref_init(&new_ah->ref);
        new_ah->src_path_mask = (1 << port_attr.lmc) - 1;
 
+       new_ah->pkey_index = 0;
+       if (ib_find_pkey(port->agent->device, port->port_num,
+                        IB_DEFAULT_PKEY_FULL, &new_ah->pkey_index) &&
+           ib_find_pkey(port->agent->device, port->port_num,
+                        IB_DEFAULT_PKEY_PARTIAL, &new_ah->pkey_index))
+               printk(KERN_ERR "Couldn't find index for default PKey\n");
+
        memset(&ah_attr, 0, sizeof ah_attr);
        ah_attr.dlid     = port_attr.sm_lid;
        ah_attr.sl       = port_attr.sm_sl;
@@ -512,6 +520,35 @@ int ib_init_ah_from_path(struct ib_device *device, u8 port_num,
 }
 EXPORT_SYMBOL(ib_init_ah_from_path);
 
+static int alloc_mad(struct ib_sa_query *query, gfp_t gfp_mask)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&query->port->ah_lock, flags);
+       kref_get(&query->port->sm_ah->ref);
+       query->sm_ah = query->port->sm_ah;
+       spin_unlock_irqrestore(&query->port->ah_lock, flags);
+
+       query->mad_buf = ib_create_send_mad(query->port->agent, 1,
+                                           query->sm_ah->pkey_index,
+                                           0, IB_MGMT_SA_HDR, IB_MGMT_SA_DATA,
+                                           gfp_mask);
+       if (!query->mad_buf) {
+               kref_put(&query->sm_ah->ref, free_sm_ah);
+               return -ENOMEM;
+       }
+
+       query->mad_buf->ah = query->sm_ah->ah;
+
+       return 0;
+}
+
+static void free_mad(struct ib_sa_query *query)
+{
+       ib_free_send_mad(query->mad_buf);
+       kref_put(&query->sm_ah->ref, free_sm_ah);
+}
+
 static void init_mad(struct ib_sa_mad *mad, struct ib_mad_agent *agent)
 {
        unsigned long flags;
@@ -548,20 +585,11 @@ retry:
        query->mad_buf->context[0] = query;
        query->id = id;
 
-       spin_lock_irqsave(&query->port->ah_lock, flags);
-       kref_get(&query->port->sm_ah->ref);
-       query->sm_ah = query->port->sm_ah;
-       spin_unlock_irqrestore(&query->port->ah_lock, flags);
-
-       query->mad_buf->ah = query->sm_ah->ah;
-
        ret = ib_post_send_mad(query->mad_buf, NULL);
        if (ret) {
                spin_lock_irqsave(&idr_lock, flags);
                idr_remove(&query_idr, id);
                spin_unlock_irqrestore(&idr_lock, flags);
-
-               kref_put(&query->sm_ah->ref, free_sm_ah);
        }
 
        /*
@@ -647,13 +675,10 @@ int ib_sa_path_rec_get(struct ib_sa_client *client,
        if (!query)
                return -ENOMEM;
 
-       query->sa_query.mad_buf = ib_create_send_mad(agent, 1, 0,
-                                                    0, IB_MGMT_SA_HDR,
-                                                    IB_MGMT_SA_DATA, gfp_mask);
-       if (!query->sa_query.mad_buf) {
-               ret = -ENOMEM;
+       query->sa_query.port     = port;
+       ret = alloc_mad(&query->sa_query, gfp_mask);
+       if (ret)
                goto err1;
-       }
 
        ib_sa_client_get(client);
        query->sa_query.client = client;
@@ -665,7 +690,6 @@ int ib_sa_path_rec_get(struct ib_sa_client *client,
 
        query->sa_query.callback = callback ? ib_sa_path_rec_callback : NULL;
        query->sa_query.release  = ib_sa_path_rec_release;
-       query->sa_query.port     = port;
        mad->mad_hdr.method      = IB_MGMT_METHOD_GET;
        mad->mad_hdr.attr_id     = cpu_to_be16(IB_SA_ATTR_PATH_REC);
        mad->sa_hdr.comp_mask    = comp_mask;
@@ -683,7 +707,7 @@ int ib_sa_path_rec_get(struct ib_sa_client *client,
 err2:
        *sa_query = NULL;
        ib_sa_client_put(query->sa_query.client);
-       ib_free_send_mad(query->sa_query.mad_buf);
+       free_mad(&query->sa_query);
 
 err1:
        kfree(query);
@@ -773,13 +797,10 @@ int ib_sa_service_rec_query(struct ib_sa_client *client,
        if (!query)
                return -ENOMEM;
 
-       query->sa_query.mad_buf = ib_create_send_mad(agent, 1, 0,
-                                                    0, IB_MGMT_SA_HDR,
-                                                    IB_MGMT_SA_DATA, gfp_mask);
-       if (!query->sa_query.mad_buf) {
-               ret = -ENOMEM;
+       query->sa_query.port     = port;
+       ret = alloc_mad(&query->sa_query, gfp_mask);
+       if (ret)
                goto err1;
-       }
 
        ib_sa_client_get(client);
        query->sa_query.client = client;
@@ -791,7 +812,6 @@ int ib_sa_service_rec_query(struct ib_sa_client *client,
 
        query->sa_query.callback = callback ? ib_sa_service_rec_callback : NULL;
        query->sa_query.release  = ib_sa_service_rec_release;
-       query->sa_query.port     = port;
        mad->mad_hdr.method      = method;
        mad->mad_hdr.attr_id     = cpu_to_be16(IB_SA_ATTR_SERVICE_REC);
        mad->sa_hdr.comp_mask    = comp_mask;
@@ -810,7 +830,7 @@ int ib_sa_service_rec_query(struct ib_sa_client *client,
 err2:
        *sa_query = NULL;
        ib_sa_client_put(query->sa_query.client);
-       ib_free_send_mad(query->sa_query.mad_buf);
+       free_mad(&query->sa_query);
 
 err1:
        kfree(query);
@@ -869,13 +889,10 @@ int ib_sa_mcmember_rec_query(struct ib_sa_client *client,
        if (!query)
                return -ENOMEM;
 
-       query->sa_query.mad_buf = ib_create_send_mad(agent, 1, 0,
-                                                    0, IB_MGMT_SA_HDR,
-                                                    IB_MGMT_SA_DATA, gfp_mask);
-       if (!query->sa_query.mad_buf) {
-               ret = -ENOMEM;
+       query->sa_query.port     = port;
+       ret = alloc_mad(&query->sa_query, gfp_mask);
+       if (ret)
                goto err1;
-       }
 
        ib_sa_client_get(client);
        query->sa_query.client = client;
@@ -887,7 +904,6 @@ int ib_sa_mcmember_rec_query(struct ib_sa_client *client,
 
        query->sa_query.callback = callback ? ib_sa_mcmember_rec_callback : NULL;
        query->sa_query.release  = ib_sa_mcmember_rec_release;
-       query->sa_query.port     = port;
        mad->mad_hdr.method      = method;
        mad->mad_hdr.attr_id     = cpu_to_be16(IB_SA_ATTR_MC_MEMBER_REC);
        mad->sa_hdr.comp_mask    = comp_mask;
@@ -906,7 +922,7 @@ int ib_sa_mcmember_rec_query(struct ib_sa_client *client,
 err2:
        *sa_query = NULL;
        ib_sa_client_put(query->sa_query.client);
-       ib_free_send_mad(query->sa_query.mad_buf);
+       free_mad(&query->sa_query);
 
 err1:
        kfree(query);
@@ -939,8 +955,7 @@ static void send_handler(struct ib_mad_agent *agent,
        idr_remove(&query_idr, query->id);
        spin_unlock_irqrestore(&idr_lock, flags);
 
-       ib_free_send_mad(mad_send_wc->send_buf);
-       kref_put(&query->sm_ah->ref, free_sm_ah);
+       free_mad(query);
        ib_sa_client_put(query->client);
        query->release(query);
 }
index 2bca753eb62276a7c49d52594e06c1a78ec6ba1a..87236753bce9b7a93f9b41b30297e7d4c5a4d432 100644 (file)
@@ -192,7 +192,7 @@ enum smi_action smi_handle_dr_smp_recv(struct ib_smp *smp, u8 node_type,
                        }
                        /* smp->hop_ptr updated when sending */
                        return (node_type == RDMA_NODE_IB_SWITCH ?
-                               IB_SMI_HANDLE: IB_SMI_DISCARD);
+                               IB_SMI_HANDLE : IB_SMI_DISCARD);
                }
 
                /* C14-13:4 -- hop_ptr = 0 -> give to SM */
@@ -211,7 +211,7 @@ enum smi_forward_action smi_check_forward_dr_smp(struct ib_smp *smp)
        if (!ib_get_smp_direction(smp)) {
                /* C14-9:2 -- intermediate hop */
                if (hop_ptr && hop_ptr < hop_cnt)
-                       return IB_SMI_SEND;
+                       return IB_SMI_FORWARD;
 
                /* C14-9:3 -- at the end of the DR segment of path */
                if (hop_ptr == hop_cnt)
@@ -224,7 +224,7 @@ enum smi_forward_action smi_check_forward_dr_smp(struct ib_smp *smp)
        } else {
                /* C14-13:2  -- intermediate hop */
                if (2 <= hop_ptr && hop_ptr <= hop_cnt)
-                       return IB_SMI_SEND;
+                       return IB_SMI_FORWARD;
 
                /* C14-13:3 -- at the end of the DR segment of path */
                if (hop_ptr == 1)
@@ -233,3 +233,13 @@ enum smi_forward_action smi_check_forward_dr_smp(struct ib_smp *smp)
        }
        return IB_SMI_LOCAL;
 }
+
+/*
+ * Return the forwarding port number from initial_path for outgoing SMP and
+ * from return_path for returning SMP
+ */
+int smi_get_fwd_port(struct ib_smp *smp)
+{
+       return (!ib_get_smp_direction(smp) ? smp->initial_path[smp->hop_ptr+1] :
+               smp->return_path[smp->hop_ptr-1]);
+}
index 9a4b349efc307253baf3c44e843f0eabbf4fb215..1cfc2984434fe517e99c1004fe3fc6b5176c49bc 100644 (file)
@@ -48,10 +48,12 @@ enum smi_action {
 enum smi_forward_action {
        IB_SMI_LOCAL,   /* SMP should be completed up the stack */
        IB_SMI_SEND,    /* received DR SMP should be forwarded to the send queue */
+       IB_SMI_FORWARD  /* SMP should be forwarded (for switches only) */
 };
 
 enum smi_action smi_handle_dr_smp_recv(struct ib_smp *smp, u8 node_type,
                                       int port_num, int phys_port_cnt);
+int smi_get_fwd_port(struct ib_smp *smp);
 extern enum smi_forward_action smi_check_forward_dr_smp(struct ib_smp *smp);
 extern enum smi_action smi_handle_dr_smp_send(struct ib_smp *smp,
                                              u8 node_type, int port_num);
index 08c299ebf4a8b5da88872c9116782ce5dd91c3ec..70b77ae67422da6d1fc624a7dc1242a9cbe06af2 100644 (file)
@@ -311,7 +311,7 @@ static ssize_t show_pma_counter(struct ib_port *p, struct port_attribute *attr,
                return sprintf(buf, "N/A (no PMA)\n");
 
        in_mad  = kzalloc(sizeof *in_mad, GFP_KERNEL);
-       out_mad = kmalloc(sizeof *in_mad, GFP_KERNEL);
+       out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
        if (!in_mad || !out_mad) {
                ret = -ENOMEM;
                goto out;
@@ -479,7 +479,6 @@ alloc_group_attrs(ssize_t (*show)(struct ib_port *,
 
                element->attr.attr.name  = element->name;
                element->attr.attr.mode  = S_IRUGO;
-               element->attr.attr.owner = THIS_MODULE;
                element->attr.show       = show;
                element->index           = i;
 
index 2586a3ee8eba6ae35c77a09460d3b9ea18e954fa..424983f5b1ee249f5685907d6f695c03c20d4c4a 100644 (file)
@@ -823,7 +823,6 @@ static ssize_t ib_ucm_send_rep(struct ib_ucm_file *file,
        param.private_data_len    = cmd.len;
        param.responder_resources = cmd.responder_resources;
        param.initiator_depth     = cmd.initiator_depth;
-       param.target_ack_delay    = cmd.target_ack_delay;
        param.failover_accepted   = cmd.failover_accepted;
        param.flow_control        = cmd.flow_control;
        param.rnr_retry_count     = cmd.rnr_retry_count;
index d40652a801511b597b17de382c243d6d45adc3ef..26d0470eef6ec2c2a3abb706c821cc23437e26c1 100644 (file)
@@ -121,6 +121,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
 
        cur_base = addr & PAGE_MASK;
 
+       ret = 0;
        while (npages) {
                ret = get_user_pages(current, current->mm, cur_base,
                                     min_t(int, npages,
index 809cb14ac6deca2f6476e066e0cd290b546112bb..e6ce5f209e471ab8491a4c7ecacfa28a2532f979 100644 (file)
@@ -1,6 +1,6 @@
 config INFINIBAND_AMSO1100
        tristate "Ammasso 1100 HCA support"
-       depends on PCI && INET && INFINIBAND
+       depends on PCI && INET
        ---help---
          This is a low-level driver for the Ammasso 1100 host
          channel adapter (HCA).
index 77977f55dca3f4b55b3268aa3cd4a37b77a33ae6..2acec3fadf6951795b4f5c4122cae67234644e84 100644 (file)
@@ -1,6 +1,6 @@
 config INFINIBAND_CXGB3
        tristate "Chelsio RDMA Driver"
-       depends on CHELSIO_T3 && INFINIBAND && INET
+       depends on CHELSIO_T3 && INET
        select GENERIC_ALLOCATOR
        ---help---
          This is an iWARP/RDMA driver for the Chelsio T3 1GbE and
index 76049afc76554ef2a4c0487b348faca768dfc3d7..1518b41482ae017467faab19246805da98033414 100644 (file)
@@ -144,7 +144,7 @@ static int cxio_hal_clear_qp_ctx(struct cxio_rdev *rdev_p, u32 qpid)
        }
        wqe = (struct t3_modify_qp_wr *) skb_put(skb, sizeof(*wqe));
        memset(wqe, 0, sizeof(*wqe));
-       build_fw_riwrh((struct fw_riwrh *) wqe, T3_WR_QP_MOD, 3, 1, qpid, 7);
+       build_fw_riwrh((struct fw_riwrh *) wqe, T3_WR_QP_MOD, 3, 0, qpid, 7);
        wqe->flags = cpu_to_be32(MODQP_WRITE_EC);
        sge_cmd = qpid << 8 | 3;
        wqe->sge_cmd = cpu_to_be64(sge_cmd);
@@ -548,7 +548,7 @@ static int cxio_hal_init_ctrl_qp(struct cxio_rdev *rdev_p)
                        V_EC_UP_TOKEN(T3_CTL_QP_TID) | F_EC_VALID)) << 32;
        wqe = (struct t3_modify_qp_wr *) skb_put(skb, sizeof(*wqe));
        memset(wqe, 0, sizeof(*wqe));
-       build_fw_riwrh((struct fw_riwrh *) wqe, T3_WR_QP_MOD, 0, 1,
+       build_fw_riwrh((struct fw_riwrh *) wqe, T3_WR_QP_MOD, 0, 0,
                       T3_CTL_QP_TID, 7);
        wqe->flags = cpu_to_be32(MODQP_WRITE_EC);
        sge_cmd = (3ULL << 56) | FW_RI_SGEEC_START << 8 | 3;
@@ -833,7 +833,7 @@ int cxio_rdma_init(struct cxio_rdev *rdev_p, struct t3_rdma_init_attr *attr)
        wqe->ird = cpu_to_be32(attr->ird);
        wqe->qp_dma_addr = cpu_to_be64(attr->qp_dma_addr);
        wqe->qp_dma_size = cpu_to_be32(attr->qp_dma_size);
-       wqe->rsvd = 0;
+       wqe->irs = cpu_to_be32(attr->irs);
        skb->priority = 0;      /* 0=>ToeQ; 1=>CtrlQ */
        return (cxgb3_ofld_send(rdev_p->t3cdev_p, skb));
 }
index ff7290eacefb7ee83ec95565384a29891a06f91b..c84d4ac49355b3bc2f3d41f265b4e75c8cb568cf 100644 (file)
@@ -294,6 +294,7 @@ struct t3_rdma_init_attr {
        u64 qp_dma_addr;
        u32 qp_dma_size;
        u32 flags;
+       u32 irs;
 };
 
 struct t3_rdma_init_wr {
@@ -314,7 +315,7 @@ struct t3_rdma_init_wr {
        __be32 ird;
        __be64 qp_dma_addr;     /* 7 */
        __be32 qp_dma_size;     /* 8 */
-       u32 rsvd;
+       u32 irs;
 };
 
 struct t3_genbit {
index b2faff5abce8648f533211fec884d0fc04b8d19d..3b41dc0c39dd9c2da189273862ae5c1cf3362be3 100644 (file)
@@ -254,8 +254,6 @@ static void release_ep_resources(struct iwch_ep *ep)
        cxgb3_remove_tid(ep->com.tdev, (void *)ep, ep->hwtid);
        dst_release(ep->dst);
        l2t_release(L2DATA(ep->com.tdev), ep->l2t);
-       if (ep->com.tdev->type == T3B)
-               release_tid(ep->com.tdev, ep->hwtid, NULL);
        put_ep(&ep->com);
 }
 
@@ -515,7 +513,7 @@ static void send_mpa_req(struct iwch_ep *ep, struct sk_buff *skb)
        req->len = htonl(len);
        req->param = htonl(V_TX_PORT(ep->l2t->smt_idx) |
                           V_TX_SNDBUF(snd_win>>15));
-       req->flags = htonl(F_TX_IMM_ACK|F_TX_INIT);
+       req->flags = htonl(F_TX_INIT);
        req->sndseq = htonl(ep->snd_seq);
        BUG_ON(ep->mpa_skb);
        ep->mpa_skb = skb;
@@ -566,7 +564,7 @@ static int send_mpa_reject(struct iwch_ep *ep, const void *pdata, u8 plen)
        req->len = htonl(mpalen);
        req->param = htonl(V_TX_PORT(ep->l2t->smt_idx) |
                           V_TX_SNDBUF(snd_win>>15));
-       req->flags = htonl(F_TX_IMM_ACK|F_TX_INIT);
+       req->flags = htonl(F_TX_INIT);
        req->sndseq = htonl(ep->snd_seq);
        BUG_ON(ep->mpa_skb);
        ep->mpa_skb = skb;
@@ -618,7 +616,7 @@ static int send_mpa_reply(struct iwch_ep *ep, const void *pdata, u8 plen)
        req->len = htonl(len);
        req->param = htonl(V_TX_PORT(ep->l2t->smt_idx) |
                           V_TX_SNDBUF(snd_win>>15));
-       req->flags = htonl(F_TX_MORE | F_TX_IMM_ACK | F_TX_INIT);
+       req->flags = htonl(F_TX_INIT);
        req->sndseq = htonl(ep->snd_seq);
        ep->mpa_skb = skb;
        state_set(&ep->com, MPA_REP_SENT);
@@ -641,6 +639,7 @@ static int act_establish(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
        cxgb3_insert_tid(ep->com.tdev, &t3c_client, ep, tid);
 
        ep->snd_seq = ntohl(req->snd_isn);
+       ep->rcv_seq = ntohl(req->rcv_isn);
 
        set_emss(ep, ntohs(req->tcp_opt));
 
@@ -1023,6 +1022,9 @@ static int rx_data(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
        skb_pull(skb, sizeof(*hdr));
        skb_trim(skb, dlen);
 
+       ep->rcv_seq += dlen;
+       BUG_ON(ep->rcv_seq != (ntohl(hdr->seq) + dlen));
+
        switch (state_read(&ep->com)) {
        case MPA_REQ_SENT:
                process_mpa_reply(ep, skb);
@@ -1060,7 +1062,6 @@ static int tx_ack(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
        struct iwch_ep *ep = ctx;
        struct cpl_wr_ack *hdr = cplhdr(skb);
        unsigned int credits = ntohs(hdr->credits);
-       enum iwch_qp_attr_mask  mask;
 
        PDBG("%s ep %p credits %u\n", __FUNCTION__, ep, credits);
 
@@ -1072,30 +1073,6 @@ static int tx_ack(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
        ep->mpa_skb = NULL;
        dst_confirm(ep->dst);
        if (state_read(&ep->com) == MPA_REP_SENT) {
-               struct iwch_qp_attributes attrs;
-
-               /* bind QP to EP and move to RTS */
-               attrs.mpa_attr = ep->mpa_attr;
-               attrs.max_ird = ep->ord;
-               attrs.max_ord = ep->ord;
-               attrs.llp_stream_handle = ep;
-               attrs.next_state = IWCH_QP_STATE_RTS;
-
-               /* bind QP and TID with INIT_WR */
-               mask = IWCH_QP_ATTR_NEXT_STATE |
-                                    IWCH_QP_ATTR_LLP_STREAM_HANDLE |
-                                    IWCH_QP_ATTR_MPA_ATTR |
-                                    IWCH_QP_ATTR_MAX_IRD |
-                                    IWCH_QP_ATTR_MAX_ORD;
-
-               ep->com.rpl_err = iwch_modify_qp(ep->com.qp->rhp,
-                                    ep->com.qp, mask, &attrs, 1);
-
-               if (!ep->com.rpl_err) {
-                       state_set(&ep->com, FPDU_MODE);
-                       established_upcall(ep);
-               }
-
                ep->com.rpl_done = 1;
                PDBG("waking up ep %p\n", ep);
                wake_up(&ep->com.waitq);
@@ -1124,6 +1101,15 @@ static int abort_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
        return CPL_RET_BUF_DONE;
 }
 
+/*
+ * Return whether a failed active open has allocated a TID
+ */
+static inline int act_open_has_tid(int status)
+{
+       return status != CPL_ERR_TCAM_FULL && status != CPL_ERR_CONN_EXIST &&
+              status != CPL_ERR_ARP_MISS;
+}
+
 static int act_open_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
 {
        struct iwch_ep *ep = ctx;
@@ -1133,7 +1119,7 @@ static int act_open_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
             status2errno(rpl->status));
        connect_reply_upcall(ep, status2errno(rpl->status));
        state_set(&ep->com, DEAD);
-       if (ep->com.tdev->type == T3B)
+       if (ep->com.tdev->type == T3B && act_open_has_tid(rpl->status))
                release_tid(ep->com.tdev, GET_TID(rpl), NULL);
        cxgb3_free_atid(ep->com.tdev, ep->atid);
        dst_release(ep->dst);
@@ -1378,6 +1364,7 @@ static int pass_establish(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
 
        PDBG("%s ep %p\n", __FUNCTION__, ep);
        ep->snd_seq = ntohl(req->snd_isn);
+       ep->rcv_seq = ntohl(req->rcv_isn);
 
        set_emss(ep, ntohs(req->tcp_opt));
 
@@ -1485,6 +1472,13 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
        int ret;
        int state;
 
+       if (is_neg_adv_abort(req->status)) {
+               PDBG("%s neg_adv_abort ep %p tid %d\n", __FUNCTION__, ep,
+                    ep->hwtid);
+               t3_l2t_send_event(ep->com.tdev, ep->l2t);
+               return CPL_RET_BUF_DONE;
+       }
+
        /*
         * We get 2 peer aborts from the HW.  The first one must
         * be ignored except for scribbling that we need one more.
@@ -1494,13 +1488,6 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
                return CPL_RET_BUF_DONE;
        }
 
-       if (is_neg_adv_abort(req->status)) {
-               PDBG("%s neg_adv_abort ep %p tid %d\n", __FUNCTION__, ep,
-                    ep->hwtid);
-               t3_l2t_send_event(ep->com.tdev, ep->l2t);
-               return CPL_RET_BUF_DONE;
-       }
-
        state = state_read(&ep->com);
        PDBG("%s ep %p state %u\n", __FUNCTION__, ep, state);
        switch (state) {
@@ -1732,10 +1719,8 @@ int iwch_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
        struct iwch_qp *qp = get_qhp(h, conn_param->qpn);
 
        PDBG("%s ep %p tid %u\n", __FUNCTION__, ep, ep->hwtid);
-       if (state_read(&ep->com) == DEAD) {
-               put_ep(&ep->com);
+       if (state_read(&ep->com) == DEAD)
                return -ECONNRESET;
-       }
 
        BUG_ON(state_read(&ep->com) != MPA_REQ_RCVD);
        BUG_ON(!qp);
@@ -1755,17 +1740,8 @@ int iwch_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
        ep->ird = conn_param->ird;
        ep->ord = conn_param->ord;
        PDBG("%s %d ird %d ord %d\n", __FUNCTION__, __LINE__, ep->ird, ep->ord);
+
        get_ep(&ep->com);
-       err = send_mpa_reply(ep, conn_param->private_data,
-                            conn_param->private_data_len);
-       if (err) {
-               ep->com.cm_id = NULL;
-               ep->com.qp = NULL;
-               cm_id->rem_ref(cm_id);
-               abort_connection(ep, NULL, GFP_KERNEL);
-               put_ep(&ep->com);
-               return err;
-       }
 
        /* bind QP to EP and move to RTS */
        attrs.mpa_attr = ep->mpa_attr;
@@ -1783,16 +1759,28 @@ int iwch_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
 
        err = iwch_modify_qp(ep->com.qp->rhp,
                             ep->com.qp, mask, &attrs, 1);
+       if (err)
+               goto err;
 
-       if (err) {
-               ep->com.cm_id = NULL;
-               ep->com.qp = NULL;
-               cm_id->rem_ref(cm_id);
-               abort_connection(ep, NULL, GFP_KERNEL);
-       } else {
-               state_set(&ep->com, FPDU_MODE);
-               established_upcall(ep);
-       }
+       err = send_mpa_reply(ep, conn_param->private_data,
+                            conn_param->private_data_len);
+       if (err)
+               goto err;
+
+       /* wait for wr_ack */
+       wait_event(ep->com.waitq, ep->com.rpl_done);
+       err = ep->com.rpl_err;
+       if (err)
+               goto err;
+
+       state_set(&ep->com, FPDU_MODE);
+       established_upcall(ep);
+       put_ep(&ep->com);
+       return 0;
+err:
+       ep->com.cm_id = NULL;
+       ep->com.qp = NULL;
+       cm_id->rem_ref(cm_id);
        put_ep(&ep->com);
        return err;
 }
index 21a388c313cffb536a2812fbc54a054480bd73f9..6107e7cd9b57dd54377c29601a473bbd8f24cc12 100644 (file)
@@ -175,6 +175,7 @@ struct iwch_ep {
        unsigned int atid;
        u32 hwtid;
        u32 snd_seq;
+       u32 rcv_seq;
        struct l2t_entry *l2t;
        struct dst_entry *dst;
        struct sk_buff *mpa_skb;
index e7c2c3948037e6853586be07e01f2c1f3b5731bb..f0c777589374cccf1af919534805675246e05f2c 100644 (file)
@@ -1163,9 +1163,10 @@ int iwch_register_device(struct iwch_dev *dev)
        dev->ibdev.post_recv = iwch_post_receive;
 
 
-       dev->ibdev.iwcm =
-           (struct iw_cm_verbs *) kmalloc(sizeof(struct iw_cm_verbs),
-                                          GFP_KERNEL);
+       dev->ibdev.iwcm = kmalloc(sizeof(struct iw_cm_verbs), GFP_KERNEL);
+       if (!dev->ibdev.iwcm)
+               return -ENOMEM;
+
        dev->ibdev.iwcm->connect = iwch_connect;
        dev->ibdev.iwcm->accept = iwch_accept_cr;
        dev->ibdev.iwcm->reject = iwch_reject_cr;
index 714dddbc9a987ec3ba6ac7633226d1e1cd831e1b..dd89b6b91f9c3f90ec564c7f95f3bdc9090aea75 100644 (file)
@@ -628,9 +628,9 @@ int iwch_post_terminate(struct iwch_qp *qhp, struct respQ_msg_t *rsp_msg)
        /* immediate data starts here. */
        term = (struct terminate_message *)wqe->send.sgl;
        build_term_codes(rsp_msg, &term->layer_etype, &term->ecode);
-       build_fw_riwrh((void *)wqe, T3_WR_SEND,
-                      T3_COMPLETION_FLAG | T3_NOTIFY_FLAG, 1,
-                      qhp->ep->hwtid, 5);
+       wqe->send.wrh.op_seop_flags = cpu_to_be32(V_FW_RIWR_OP(T3_WR_SEND) |
+                        V_FW_RIWR_FLAGS(T3_COMPLETION_FLAG | T3_NOTIFY_FLAG));
+       wqe->send.wrh.gen_tid_len = cpu_to_be32(V_FW_RIWR_TID(qhp->ep->hwtid));
        skb->priority = CPL_PRIORITY_DATA;
        return cxgb3_ofld_send(qhp->rhp->rdev.t3cdev_p, skb);
 }
@@ -732,6 +732,7 @@ static int rdma_init(struct iwch_dev *rhp, struct iwch_qp *qhp,
        init_attr.qp_dma_addr = qhp->wq.dma_addr;
        init_attr.qp_dma_size = (1UL << qhp->wq.size_log2);
        init_attr.flags = rqes_posted(qhp) ? RECVS_POSTED : 0;
+       init_attr.irs = qhp->ep->rcv_seq;
        PDBG("%s init_attr.rq_addr 0x%x init_attr.rq_size = %d "
             "flags 0x%x qpcaps 0x%x\n", __FUNCTION__,
             init_attr.rq_addr, init_attr.rq_size,
index 1a854598e0e68d01ca4a4ede2bb765cc13e2dac5..59f807d8d58e5eb043fad41b7182bca53bac8cc5 100644 (file)
@@ -1,6 +1,6 @@
 config INFINIBAND_EHCA
        tristate "eHCA support"
-       depends on IBMEBUS && INFINIBAND
+       depends on IBMEBUS
        ---help---
        This driver supports the IBM pSeries eHCA InfiniBand adapter.
 
index 0d6e2c4bb2451f27f78dfea5aa191c1f66cebe58..3cd6bf3402d10c8a0d9d097b72d8fdf9b1bb5a11 100644 (file)
@@ -118,7 +118,7 @@ struct ib_ah *ehca_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
                }
                memcpy(&av->av.grh.word_1, &gid, sizeof(gid));
        }
-       av->av.pmtu = EHCA_MAX_MTU;
+       av->av.pmtu = shca->max_mtu;
 
        /* dgid comes in grh.word_3 */
        memcpy(&av->av.grh.word_3, &ah_attr->grh.dgid,
@@ -137,6 +137,8 @@ int ehca_modify_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr)
        struct ehca_av *av;
        struct ehca_ud_av new_ehca_av;
        struct ehca_pd *my_pd = container_of(ah->pd, struct ehca_pd, ib_pd);
+       struct ehca_shca *shca = container_of(ah->pd->device, struct ehca_shca,
+                                             ib_device);
        u32 cur_pid = current->tgid;
 
        if (my_pd->ib_pd.uobject && my_pd->ib_pd.uobject->context &&
@@ -192,7 +194,7 @@ int ehca_modify_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr)
                memcpy(&new_ehca_av.grh.word_1, &gid, sizeof(gid));
        }
 
-       new_ehca_av.pmtu = EHCA_MAX_MTU;
+       new_ehca_av.pmtu = shca->max_mtu;
 
        memcpy(&new_ehca_av.grh.word_3, &ah_attr->grh.dgid,
               sizeof(ah_attr->grh.dgid));
index 1d286d3cc2d5b05aa357e5ebd87015cace5a6bce..daf823ea1acedb242caa59e22b35de602570d1b5 100644 (file)
@@ -5,6 +5,7 @@
  *
  *  Authors: Heiko J Schick <schickhj@de.ibm.com>
  *           Christoph Raisch <raisch@de.ibm.com>
+ *           Joachim Fenkes <fenkes@de.ibm.com>
  *
  *  Copyright (c) 2005 IBM Corporation
  *
@@ -86,11 +87,17 @@ struct ehca_eq {
        struct ehca_eqe_cache_entry eqe_cache[EHCA_EQE_CACHE_SIZE];
 };
 
+struct ehca_sma_attr {
+       u16 lid, lmc, sm_sl, sm_lid;
+       u16 pkey_tbl_len, pkeys[16];
+};
+
 struct ehca_sport {
        struct ib_cq *ibcq_aqp1;
        struct ib_qp *ibqp_aqp1;
        enum ib_rate  rate;
        enum ib_port_state port_state;
+       struct ehca_sma_attr saved_attr;
 };
 
 struct ehca_shca {
@@ -107,6 +114,8 @@ struct ehca_shca {
        struct ehca_pd *pd;
        struct h_galpas galpas;
        struct mutex modify_mutex;
+       u64 hca_cap;
+       int max_mtu;
 };
 
 struct ehca_pd {
@@ -115,9 +124,20 @@ struct ehca_pd {
        u32 ownpid;
 };
 
+enum ehca_ext_qp_type {
+       EQPT_NORMAL    = 0,
+       EQPT_LLQP      = 1,
+       EQPT_SRQBASE   = 2,
+       EQPT_SRQ       = 3,
+};
+
 struct ehca_qp {
-       struct ib_qp ib_qp;
+       union {
+               struct ib_qp ib_qp;
+               struct ib_srq ib_srq;
+       };
        u32 qp_type;
+       enum ehca_ext_qp_type ext_type;
        struct ipz_queue ipz_squeue;
        struct ipz_queue ipz_rqueue;
        struct h_galpas galpas;
@@ -140,6 +160,10 @@ struct ehca_qp {
        u32 mm_count_galpa;
 };
 
+#define IS_SRQ(qp) (qp->ext_type == EQPT_SRQ)
+#define HAS_SQ(qp) (qp->ext_type != EQPT_SRQ)
+#define HAS_RQ(qp) (qp->ext_type != EQPT_SRQBASE)
+
 /* must be power of 2 */
 #define QP_HASHTAB_LEN 8
 
@@ -156,8 +180,8 @@ struct ehca_cq {
        spinlock_t cb_lock;
        struct hlist_head qp_hashtab[QP_HASHTAB_LEN];
        struct list_head entry;
-       u32 nr_callbacks; /* #events assigned to cpu by scaling code */
-       u32 nr_events;    /* #events seen */
+       u32 nr_callbacks;   /* #events assigned to cpu by scaling code */
+       atomic_t nr_events; /* #events seen */
        wait_queue_head_t wait_completion;
        spinlock_t task_lock;
        u32 ownpid;
@@ -275,9 +299,8 @@ void ehca_cleanup_av_cache(void);
 int ehca_init_mrmw_cache(void);
 void ehca_cleanup_mrmw_cache(void);
 
-extern spinlock_t ehca_qp_idr_lock;
-extern spinlock_t ehca_cq_idr_lock;
-extern spinlock_t hcall_lock;
+extern rwlock_t ehca_qp_idr_lock;
+extern rwlock_t ehca_cq_idr_lock;
 extern struct idr ehca_qp_idr;
 extern struct idr ehca_cq_idr;
 
@@ -305,6 +328,7 @@ struct ehca_create_qp_resp {
        u32 qp_num;
        u32 token;
        u32 qp_type;
+       u32 ext_type;
        u32 qkey;
        /* qp_num assigned by ehca: sqp0/1 may have got different numbers */
        u32 real_qp_num;
@@ -320,14 +344,42 @@ struct ehca_alloc_cq_parms {
        struct ipz_eq_handle eq_handle;
 };
 
+enum ehca_service_type {
+       ST_RC  = 0,
+       ST_UC  = 1,
+       ST_RD  = 2,
+       ST_UD  = 3,
+};
+
+enum ehca_ll_comp_flags {
+       LLQP_SEND_COMP = 0x20,
+       LLQP_RECV_COMP = 0x40,
+       LLQP_COMP_MASK = 0x60,
+};
+
 struct ehca_alloc_qp_parms {
-       int servicetype;
+/* input parameters */
+       enum ehca_service_type servicetype;
        int sigtype;
-       int daqp_ctrl;
-       int max_send_sge;
-       int max_recv_sge;
+       enum ehca_ext_qp_type ext_type;
+       enum ehca_ll_comp_flags ll_comp_flags;
+
+       int max_send_wr, max_recv_wr;
+       int max_send_sge, max_recv_sge;
        int ud_av_l_key_ctl;
 
+       u32 token;
+       struct ipz_eq_handle eq_handle;
+       struct ipz_pd pd;
+       struct ipz_cq_handle send_cq_handle, recv_cq_handle;
+
+       u32 srq_qpn, srq_token, srq_limit;
+
+/* output parameters */
+       u32 real_qp_num;
+       struct ipz_qp_handle qp_handle;
+       struct h_galpas galpas;
+
        u16 act_nr_send_wqes;
        u16 act_nr_recv_wqes;
        u8  act_nr_recv_sges;
@@ -335,9 +387,6 @@ struct ehca_alloc_qp_parms {
 
        u32 nr_rq_pages;
        u32 nr_sq_pages;
-
-       struct ipz_eq_handle ipz_eq_handle;
-       struct ipz_pd pd;
 };
 
 int ehca_cq_assign_qp(struct ehca_cq *cq, struct ehca_qp *qp);
index 5665f213b81a2ec11309ad0d8a9d0bddf0a4a785..fb3df5c271e7e144d5ffb344296ba9a9a775adab 100644 (file)
@@ -228,8 +228,8 @@ struct hcp_modify_qp_control_block {
 #define MQPCB_QP_NUMBER                         EHCA_BMASK_IBM(8,31)
 #define MQPCB_MASK_QP_ENABLE                    EHCA_BMASK_IBM(48,48)
 #define MQPCB_QP_ENABLE                         EHCA_BMASK_IBM(31,31)
-#define MQPCB_MASK_CURR_SQR_LIMIT               EHCA_BMASK_IBM(49,49)
-#define MQPCB_CURR_SQR_LIMIT                    EHCA_BMASK_IBM(15,31)
+#define MQPCB_MASK_CURR_SRQ_LIMIT               EHCA_BMASK_IBM(49,49)
+#define MQPCB_CURR_SRQ_LIMIT                    EHCA_BMASK_IBM(16,31)
 #define MQPCB_MASK_QP_AFF_ASYN_EV_LOG_REG       EHCA_BMASK_IBM(50,50)
 #define MQPCB_MASK_SHARED_RQ_HNDL               EHCA_BMASK_IBM(51,51)
 
index 67f0670fe3b18624cd752a9ed01b65a660165d81..01d4a148bd719c4cd955c0628034b97cc14543d8 100644 (file)
@@ -56,11 +56,11 @@ int ehca_cq_assign_qp(struct ehca_cq *cq, struct ehca_qp *qp)
 {
        unsigned int qp_num = qp->real_qp_num;
        unsigned int key = qp_num & (QP_HASHTAB_LEN-1);
-       unsigned long spl_flags;
+       unsigned long flags;
 
-       spin_lock_irqsave(&cq->spinlock, spl_flags);
+       spin_lock_irqsave(&cq->spinlock, flags);
        hlist_add_head(&qp->list_entries, &cq->qp_hashtab[key]);
-       spin_unlock_irqrestore(&cq->spinlock, spl_flags);
+       spin_unlock_irqrestore(&cq->spinlock, flags);
 
        ehca_dbg(cq->ib_cq.device, "cq_num=%x real_qp_num=%x",
                 cq->cq_number, qp_num);
@@ -74,9 +74,9 @@ int ehca_cq_unassign_qp(struct ehca_cq *cq, unsigned int real_qp_num)
        unsigned int key = real_qp_num & (QP_HASHTAB_LEN-1);
        struct hlist_node *iter;
        struct ehca_qp *qp;
-       unsigned long spl_flags;
+       unsigned long flags;
 
-       spin_lock_irqsave(&cq->spinlock, spl_flags);
+       spin_lock_irqsave(&cq->spinlock, flags);
        hlist_for_each(iter, &cq->qp_hashtab[key]) {
                qp = hlist_entry(iter, struct ehca_qp, list_entries);
                if (qp->real_qp_num == real_qp_num) {
@@ -88,7 +88,7 @@ int ehca_cq_unassign_qp(struct ehca_cq *cq, unsigned int real_qp_num)
                        break;
                }
        }
-       spin_unlock_irqrestore(&cq->spinlock, spl_flags);
+       spin_unlock_irqrestore(&cq->spinlock, flags);
        if (ret)
                ehca_err(cq->ib_cq.device,
                         "qp not found cq_num=%x real_qp_num=%x",
@@ -146,6 +146,7 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
        spin_lock_init(&my_cq->spinlock);
        spin_lock_init(&my_cq->cb_lock);
        spin_lock_init(&my_cq->task_lock);
+       atomic_set(&my_cq->nr_events, 0);
        init_waitqueue_head(&my_cq->wait_completion);
        my_cq->ownpid = current->tgid;
 
@@ -162,9 +163,9 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
                        goto create_cq_exit1;
                }
 
-               spin_lock_irqsave(&ehca_cq_idr_lock, flags);
+               write_lock_irqsave(&ehca_cq_idr_lock, flags);
                ret = idr_get_new(&ehca_cq_idr, my_cq, &my_cq->token);
-               spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
+               write_unlock_irqrestore(&ehca_cq_idr_lock, flags);
 
        } while (ret == -EAGAIN);
 
@@ -293,9 +294,9 @@ create_cq_exit3:
                         "cq_num=%x h_ret=%lx", my_cq, my_cq->cq_number, h_ret);
 
 create_cq_exit2:
-       spin_lock_irqsave(&ehca_cq_idr_lock, flags);
+       write_lock_irqsave(&ehca_cq_idr_lock, flags);
        idr_remove(&ehca_cq_idr, my_cq->token);
-       spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
+       write_unlock_irqrestore(&ehca_cq_idr_lock, flags);
 
 create_cq_exit1:
        kmem_cache_free(cq_cache, my_cq);
@@ -303,16 +304,6 @@ create_cq_exit1:
        return cq;
 }
 
-static int get_cq_nr_events(struct ehca_cq *my_cq)
-{
-       int ret;
-       unsigned long flags;
-       spin_lock_irqsave(&ehca_cq_idr_lock, flags);
-       ret = my_cq->nr_events;
-       spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
-       return ret;
-}
-
 int ehca_destroy_cq(struct ib_cq *cq)
 {
        u64 h_ret;
@@ -339,17 +330,18 @@ int ehca_destroy_cq(struct ib_cq *cq)
                }
        }
 
-       spin_lock_irqsave(&ehca_cq_idr_lock, flags);
-       while (my_cq->nr_events) {
-               spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
-               wait_event(my_cq->wait_completion, !get_cq_nr_events(my_cq));
-               spin_lock_irqsave(&ehca_cq_idr_lock, flags);
-               /* recheck nr_events to assure no cqe has just arrived */
-       }
-
+       /*
+        * remove the CQ from the idr first to make sure
+        * no more interrupt tasklets will touch this CQ
+        */
+       write_lock_irqsave(&ehca_cq_idr_lock, flags);
        idr_remove(&ehca_cq_idr, my_cq->token);
-       spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
+       write_unlock_irqrestore(&ehca_cq_idr_lock, flags);
+
+       /* now wait until all pending events have completed */
+       wait_event(my_cq->wait_completion, !atomic_read(&my_cq->nr_events));
 
+       /* nobody's using our CQ any longer -- we can destroy it */
        h_ret = hipz_h_destroy_cq(adapter_handle, my_cq, 0);
        if (h_ret == H_R_STATE) {
                /* cq in err: read err data and destroy it forcibly */
index 32b55a4f0e5bbe604fd607e4fcdaac343f3e5a86..bbd3c6a5822f1d0b65cc97f536e1a3ee7d33719e 100644 (file)
 
 int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props)
 {
-       int ret = 0;
+       int i, ret = 0;
        struct ehca_shca *shca = container_of(ibdev, struct ehca_shca,
                                              ib_device);
        struct hipz_query_hca *rblock;
 
+       static const u32 cap_mapping[] = {
+               IB_DEVICE_RESIZE_MAX_WR,      HCA_CAP_WQE_RESIZE,
+               IB_DEVICE_BAD_PKEY_CNTR,      HCA_CAP_BAD_P_KEY_CTR,
+               IB_DEVICE_BAD_QKEY_CNTR,      HCA_CAP_Q_KEY_VIOL_CTR,
+               IB_DEVICE_RAW_MULTI,          HCA_CAP_RAW_PACKET_MCAST,
+               IB_DEVICE_AUTO_PATH_MIG,      HCA_CAP_AUTO_PATH_MIG,
+               IB_DEVICE_CHANGE_PHY_PORT,    HCA_CAP_SQD_RTS_PORT_CHANGE,
+               IB_DEVICE_UD_AV_PORT_ENFORCE, HCA_CAP_AH_PORT_NR_CHECK,
+               IB_DEVICE_CURR_QP_STATE_MOD,  HCA_CAP_CUR_QP_STATE_MOD,
+               IB_DEVICE_SHUTDOWN_PORT,      HCA_CAP_SHUTDOWN_PORT,
+               IB_DEVICE_INIT_TYPE,          HCA_CAP_INIT_TYPE,
+               IB_DEVICE_PORT_ACTIVE_EVENT,  HCA_CAP_PORT_ACTIVE_EVENT,
+       };
+
        rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
        if (!rblock) {
                ehca_err(&shca->ib_device, "Can't allocate rblock memory.");
@@ -96,6 +110,13 @@ int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props)
        props->max_total_mcast_qp_attach
                = min_t(int, rblock->max_total_mcast_qp_attach, INT_MAX);
 
+       /* translate device capabilities */
+       props->device_cap_flags = IB_DEVICE_SYS_IMAGE_GUID |
+               IB_DEVICE_RC_RNR_NAK_GEN | IB_DEVICE_N_NOTIFY_CQ;
+       for (i = 0; i < ARRAY_SIZE(cap_mapping); i += 2)
+               if (rblock->hca_cap_indicators & cap_mapping[i + 1])
+                       props->device_cap_flags |= cap_mapping[i];
+
 query_device1:
        ehca_free_fw_ctrlblock(rblock);
 
@@ -172,6 +193,40 @@ query_port1:
        return ret;
 }
 
+int ehca_query_sma_attr(struct ehca_shca *shca,
+                       u8 port, struct ehca_sma_attr *attr)
+{
+       int ret = 0;
+       struct hipz_query_port *rblock;
+
+       rblock = ehca_alloc_fw_ctrlblock(GFP_ATOMIC);
+       if (!rblock) {
+               ehca_err(&shca->ib_device, "Can't allocate rblock memory.");
+               return -ENOMEM;
+       }
+
+       if (hipz_h_query_port(shca->ipz_hca_handle, port, rblock) != H_SUCCESS) {
+               ehca_err(&shca->ib_device, "Can't query port properties");
+               ret = -EINVAL;
+               goto query_sma_attr1;
+       }
+
+       memset(attr, 0, sizeof(struct ehca_sma_attr));
+
+       attr->lid    = rblock->lid;
+       attr->lmc    = rblock->lmc;
+       attr->sm_sl  = rblock->sm_sl;
+       attr->sm_lid = rblock->sm_lid;
+
+       attr->pkey_tbl_len = rblock->pkey_tbl_len;
+       memcpy(attr->pkeys, rblock->pkey_entries, sizeof(attr->pkeys));
+
+query_sma_attr1:
+       ehca_free_fw_ctrlblock(rblock);
+
+       return ret;
+}
+
 int ehca_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 *pkey)
 {
        int ret = 0;
@@ -261,7 +316,7 @@ int ehca_modify_port(struct ib_device *ibdev,
        }
 
        if (mutex_lock_interruptible(&shca->modify_mutex))
-                return -ERESTARTSYS;
+               return -ERESTARTSYS;
 
        rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
        if (!rblock) {
@@ -290,7 +345,7 @@ modify_port2:
        ehca_free_fw_ctrlblock(rblock);
 
 modify_port1:
-        mutex_unlock(&shca->modify_mutex);
+       mutex_unlock(&shca->modify_mutex);
 
        return ret;
 }
index 100329ba33439f79c30c391e17c9e677dbe8c979..96eba383075437e4dfea5deb10e307b693282ed4 100644 (file)
@@ -5,6 +5,8 @@
  *
  *  Authors: Heiko J Schick <schickhj@de.ibm.com>
  *           Khadija Souissi <souissi@de.ibm.com>
+ *           Hoang-Nam Nguyen <hnguyen@de.ibm.com>
+ *           Joachim Fenkes <fenkes@de.ibm.com>
  *
  *  Copyright (c) 2005 IBM Corporation
  *
@@ -59,6 +61,7 @@
 #define NEQE_EVENT_CODE        EHCA_BMASK_IBM(2,7)
 #define NEQE_PORT_NUMBER       EHCA_BMASK_IBM(8,15)
 #define NEQE_PORT_AVAILABILITY EHCA_BMASK_IBM(16,16)
+#define NEQE_DISRUPTIVE        EHCA_BMASK_IBM(16,16)
 
 #define ERROR_DATA_LENGTH      EHCA_BMASK_IBM(52,63)
 #define ERROR_DATA_TYPE        EHCA_BMASK_IBM(0,7)
@@ -178,12 +181,11 @@ static void qp_event_callback(struct ehca_shca *shca,
 {
        struct ib_event event;
        struct ehca_qp *qp;
-       unsigned long flags;
        u32 token = EHCA_BMASK_GET(EQE_QP_TOKEN, eqe);
 
-       spin_lock_irqsave(&ehca_qp_idr_lock, flags);
+       read_lock(&ehca_qp_idr_lock);
        qp = idr_find(&ehca_qp_idr, token);
-       spin_unlock_irqrestore(&ehca_qp_idr_lock, flags);
+       read_unlock(&ehca_qp_idr_lock);
 
 
        if (!qp)
@@ -207,18 +209,22 @@ static void cq_event_callback(struct ehca_shca *shca,
                              u64 eqe)
 {
        struct ehca_cq *cq;
-       unsigned long flags;
        u32 token = EHCA_BMASK_GET(EQE_CQ_TOKEN, eqe);
 
-       spin_lock_irqsave(&ehca_cq_idr_lock, flags);
+       read_lock(&ehca_cq_idr_lock);
        cq = idr_find(&ehca_cq_idr, token);
-       spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
+       if (cq)
+               atomic_inc(&cq->nr_events);
+       read_unlock(&ehca_cq_idr_lock);
 
        if (!cq)
                return;
 
        ehca_error_data(shca, cq, cq->ipz_cq_handle.handle);
 
+       if (atomic_dec_and_test(&cq->nr_events))
+               wake_up(&cq->wait_completion);
+
        return;
 }
 
@@ -281,30 +287,61 @@ static void parse_identifier(struct ehca_shca *shca, u64 eqe)
        return;
 }
 
-static void parse_ec(struct ehca_shca *shca, u64 eqe)
+static void dispatch_port_event(struct ehca_shca *shca, int port_num,
+                               enum ib_event_type type, const char *msg)
 {
        struct ib_event event;
+
+       ehca_info(&shca->ib_device, "port %d %s.", port_num, msg);
+       event.device = &shca->ib_device;
+       event.event = type;
+       event.element.port_num = port_num;
+       ib_dispatch_event(&event);
+}
+
+static void notify_port_conf_change(struct ehca_shca *shca, int port_num)
+{
+       struct ehca_sma_attr  new_attr;
+       struct ehca_sma_attr *old_attr = &shca->sport[port_num - 1].saved_attr;
+
+       ehca_query_sma_attr(shca, port_num, &new_attr);
+
+       if (new_attr.sm_sl  != old_attr->sm_sl ||
+           new_attr.sm_lid != old_attr->sm_lid)
+               dispatch_port_event(shca, port_num, IB_EVENT_SM_CHANGE,
+                                   "SM changed");
+
+       if (new_attr.lid != old_attr->lid ||
+           new_attr.lmc != old_attr->lmc)
+               dispatch_port_event(shca, port_num, IB_EVENT_LID_CHANGE,
+                                   "LID changed");
+
+       if (new_attr.pkey_tbl_len != old_attr->pkey_tbl_len ||
+           memcmp(new_attr.pkeys, old_attr->pkeys,
+                  sizeof(u16) * new_attr.pkey_tbl_len))
+               dispatch_port_event(shca, port_num, IB_EVENT_PKEY_CHANGE,
+                                   "P_Key changed");
+
+       *old_attr = new_attr;
+}
+
+static void parse_ec(struct ehca_shca *shca, u64 eqe)
+{
        u8 ec   = EHCA_BMASK_GET(NEQE_EVENT_CODE, eqe);
        u8 port = EHCA_BMASK_GET(NEQE_PORT_NUMBER, eqe);
 
        switch (ec) {
        case 0x30: /* port availability change */
                if (EHCA_BMASK_GET(NEQE_PORT_AVAILABILITY, eqe)) {
-                       ehca_info(&shca->ib_device,
-                                 "port %x is active.", port);
-                       event.device = &shca->ib_device;
-                       event.event = IB_EVENT_PORT_ACTIVE;
-                       event.element.port_num = port;
                        shca->sport[port - 1].port_state = IB_PORT_ACTIVE;
-                       ib_dispatch_event(&event);
+                       dispatch_port_event(shca, port, IB_EVENT_PORT_ACTIVE,
+                                           "is active");
+                       ehca_query_sma_attr(shca, port,
+                                           &shca->sport[port - 1].saved_attr);
                } else {
-                       ehca_info(&shca->ib_device,
-                                 "port %x is inactive.", port);
-                       event.device = &shca->ib_device;
-                       event.event = IB_EVENT_PORT_ERR;
-                       event.element.port_num = port;
                        shca->sport[port - 1].port_state = IB_PORT_DOWN;
-                       ib_dispatch_event(&event);
+                       dispatch_port_event(shca, port, IB_EVENT_PORT_ERR,
+                                           "is inactive");
                }
                break;
        case 0x31:
@@ -312,24 +349,19 @@ static void parse_ec(struct ehca_shca *shca, u64 eqe)
                 * disruptive change is caused by
                 * LID, PKEY or SM change
                 */
-               ehca_warn(&shca->ib_device,
-                         "disruptive port %x configuration change", port);
-
-               ehca_info(&shca->ib_device,
-                         "port %x is inactive.", port);
-               event.device = &shca->ib_device;
-               event.event = IB_EVENT_PORT_ERR;
-               event.element.port_num = port;
-               shca->sport[port - 1].port_state = IB_PORT_DOWN;
-               ib_dispatch_event(&event);
-
-               ehca_info(&shca->ib_device,
-                         "port %x is active.", port);
-               event.device = &shca->ib_device;
-               event.event = IB_EVENT_PORT_ACTIVE;
-               event.element.port_num = port;
-               shca->sport[port - 1].port_state = IB_PORT_ACTIVE;
-               ib_dispatch_event(&event);
+               if (EHCA_BMASK_GET(NEQE_DISRUPTIVE, eqe)) {
+                       ehca_warn(&shca->ib_device, "disruptive port "
+                                 "%d configuration change", port);
+
+                       shca->sport[port - 1].port_state = IB_PORT_DOWN;
+                       dispatch_port_event(shca, port, IB_EVENT_PORT_ERR,
+                                           "is inactive");
+
+                       shca->sport[port - 1].port_state = IB_PORT_ACTIVE;
+                       dispatch_port_event(shca, port, IB_EVENT_PORT_ACTIVE,
+                                           "is active");
+               } else
+                       notify_port_conf_change(shca, port);
                break;
        case 0x32: /* adapter malfunction */
                ehca_err(&shca->ib_device, "Adapter malfunction.");
@@ -404,7 +436,6 @@ static inline void process_eqe(struct ehca_shca *shca, struct ehca_eqe *eqe)
 {
        u64 eqe_value;
        u32 token;
-       unsigned long flags;
        struct ehca_cq *cq;
 
        eqe_value = eqe->entry;
@@ -412,27 +443,24 @@ static inline void process_eqe(struct ehca_shca *shca, struct ehca_eqe *eqe)
        if (EHCA_BMASK_GET(EQE_COMPLETION_EVENT, eqe_value)) {
                ehca_dbg(&shca->ib_device, "Got completion event");
                token = EHCA_BMASK_GET(EQE_CQ_TOKEN, eqe_value);
-               spin_lock_irqsave(&ehca_cq_idr_lock, flags);
+               read_lock(&ehca_cq_idr_lock);
                cq = idr_find(&ehca_cq_idr, token);
+               if (cq)
+                       atomic_inc(&cq->nr_events);
+               read_unlock(&ehca_cq_idr_lock);
                if (cq == NULL) {
-                       spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
                        ehca_err(&shca->ib_device,
                                 "Invalid eqe for non-existing cq token=%x",
                                 token);
                        return;
                }
                reset_eq_pending(cq);
-               cq->nr_events++;
-               spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
                if (ehca_scaling_code)
                        queue_comp_task(cq);
                else {
                        comp_event_callback(cq);
-                       spin_lock_irqsave(&ehca_cq_idr_lock, flags);
-                       cq->nr_events--;
-                       if (!cq->nr_events)
+                       if (atomic_dec_and_test(&cq->nr_events))
                                wake_up(&cq->wait_completion);
-                       spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
                }
        } else {
                ehca_dbg(&shca->ib_device, "Got non completion event");
@@ -476,17 +504,17 @@ void ehca_process_eq(struct ehca_shca *shca, int is_irq)
                eqe_value = eqe_cache[eqe_cnt].eqe->entry;
                if (EHCA_BMASK_GET(EQE_COMPLETION_EVENT, eqe_value)) {
                        token = EHCA_BMASK_GET(EQE_CQ_TOKEN, eqe_value);
-                       spin_lock(&ehca_cq_idr_lock);
+                       read_lock(&ehca_cq_idr_lock);
                        eqe_cache[eqe_cnt].cq = idr_find(&ehca_cq_idr, token);
+                       if (eqe_cache[eqe_cnt].cq)
+                               atomic_inc(&eqe_cache[eqe_cnt].cq->nr_events);
+                       read_unlock(&ehca_cq_idr_lock);
                        if (!eqe_cache[eqe_cnt].cq) {
-                               spin_unlock(&ehca_cq_idr_lock);
                                ehca_err(&shca->ib_device,
                                         "Invalid eqe for non-existing cq "
                                         "token=%x", token);
                                continue;
                        }
-                       eqe_cache[eqe_cnt].cq->nr_events++;
-                       spin_unlock(&ehca_cq_idr_lock);
                } else
                        eqe_cache[eqe_cnt].cq = NULL;
                eqe_cnt++;
@@ -517,11 +545,8 @@ void ehca_process_eq(struct ehca_shca *shca, int is_irq)
                        else {
                                struct ehca_cq *cq = eq->eqe_cache[i].cq;
                                comp_event_callback(cq);
-                               spin_lock(&ehca_cq_idr_lock);
-                               cq->nr_events--;
-                               if (!cq->nr_events)
+                               if (atomic_dec_and_test(&cq->nr_events))
                                        wake_up(&cq->wait_completion);
-                               spin_unlock(&ehca_cq_idr_lock);
                        }
                } else {
                        ehca_dbg(&shca->ib_device, "Got non completion event");
@@ -621,13 +646,10 @@ static void run_comp_task(struct ehca_cpu_comp_task* cct)
        while (!list_empty(&cct->cq_list)) {
                cq = list_entry(cct->cq_list.next, struct ehca_cq, entry);
                spin_unlock_irqrestore(&cct->task_lock, flags);
-               comp_event_callback(cq);
 
-               spin_lock_irqsave(&ehca_cq_idr_lock, flags);
-               cq->nr_events--;
-               if (!cq->nr_events)
+               comp_event_callback(cq);
+               if (atomic_dec_and_test(&cq->nr_events))
                        wake_up(&cq->wait_completion);
-               spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
 
                spin_lock_irqsave(&cct->task_lock, flags);
                spin_lock(&cq->task_lock);
index 6ed06ee033ed2f326a6674d21701eed3479fa2df..3346cb06cea62a4d4a4036364fba3cf174756dda 100644 (file)
@@ -47,7 +47,6 @@ struct ehca_shca;
 
 #include <linux/interrupt.h>
 #include <linux/types.h>
-#include <asm/atomic.h>
 
 int ehca_error_data(struct ehca_shca *shca, void *data, u64 resource);
 
index 37e7fe0908cfad268e8da90142f9d6f8aeaa85ec..77aeca6a2c2f3e2428dd989b8eabc4afa496fd5d 100644 (file)
@@ -49,6 +49,9 @@ int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props);
 int ehca_query_port(struct ib_device *ibdev, u8 port,
                    struct ib_port_attr *props);
 
+int ehca_query_sma_attr(struct ehca_shca *shca, u8 port,
+                       struct ehca_sma_attr *attr);
+
 int ehca_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 * pkey);
 
 int ehca_query_gid(struct ib_device *ibdev, u8 port, int index,
@@ -154,6 +157,21 @@ int ehca_post_send(struct ib_qp *qp, struct ib_send_wr *send_wr,
 int ehca_post_recv(struct ib_qp *qp, struct ib_recv_wr *recv_wr,
                   struct ib_recv_wr **bad_recv_wr);
 
+int ehca_post_srq_recv(struct ib_srq *srq,
+                      struct ib_recv_wr *recv_wr,
+                      struct ib_recv_wr **bad_recv_wr);
+
+struct ib_srq *ehca_create_srq(struct ib_pd *pd,
+                              struct ib_srq_init_attr *init_attr,
+                              struct ib_udata *udata);
+
+int ehca_modify_srq(struct ib_srq *srq, struct ib_srq_attr *attr,
+                   enum ib_srq_attr_mask attr_mask, struct ib_udata *udata);
+
+int ehca_query_srq(struct ib_srq *srq, struct ib_srq_attr *srq_attr);
+
+int ehca_destroy_srq(struct ib_srq *srq);
+
 u64 ehca_define_sqp(struct ehca_shca *shca, struct ehca_qp *ibqp,
                    struct ib_qp_init_attr *qp_init_attr);
 
index c3f99f33b49c59bfa5d357dc0771eb0c787e9831..28ba2dd242165f626ead5afc46f43a978de18d9b 100644 (file)
@@ -94,17 +94,15 @@ MODULE_PARM_DESC(poll_all_eqs,
 MODULE_PARM_DESC(static_rate,
                 "set permanent static rate (default: disabled)");
 MODULE_PARM_DESC(scaling_code,
-                "set scaling code (0: disabled, 1: enabled/default)");
+                "set scaling code (0: disabled/default, 1: enabled)");
 
-spinlock_t ehca_qp_idr_lock;
-spinlock_t ehca_cq_idr_lock;
-spinlock_t hcall_lock;
+DEFINE_RWLOCK(ehca_qp_idr_lock);
+DEFINE_RWLOCK(ehca_cq_idr_lock);
 DEFINE_IDR(ehca_qp_idr);
 DEFINE_IDR(ehca_cq_idr);
 
-
-static struct list_head shca_list; /* list of all registered ehcas */
-static spinlock_t shca_list_lock;
+static LIST_HEAD(shca_list); /* list of all registered ehcas */
+static DEFINE_SPINLOCK(shca_list_lock);
 
 static struct timer_list poll_eqs_timer;
 
@@ -205,11 +203,35 @@ static void ehca_destroy_slab_caches(void)
 #define EHCA_HCAAVER  EHCA_BMASK_IBM(32,39)
 #define EHCA_REVID    EHCA_BMASK_IBM(40,63)
 
+static struct cap_descr {
+       u64 mask;
+       char *descr;
+} hca_cap_descr[] = {
+       { HCA_CAP_AH_PORT_NR_CHECK, "HCA_CAP_AH_PORT_NR_CHECK" },
+       { HCA_CAP_ATOMIC, "HCA_CAP_ATOMIC" },
+       { HCA_CAP_AUTO_PATH_MIG, "HCA_CAP_AUTO_PATH_MIG" },
+       { HCA_CAP_BAD_P_KEY_CTR, "HCA_CAP_BAD_P_KEY_CTR" },
+       { HCA_CAP_SQD_RTS_PORT_CHANGE, "HCA_CAP_SQD_RTS_PORT_CHANGE" },
+       { HCA_CAP_CUR_QP_STATE_MOD, "HCA_CAP_CUR_QP_STATE_MOD" },
+       { HCA_CAP_INIT_TYPE, "HCA_CAP_INIT_TYPE" },
+       { HCA_CAP_PORT_ACTIVE_EVENT, "HCA_CAP_PORT_ACTIVE_EVENT" },
+       { HCA_CAP_Q_KEY_VIOL_CTR, "HCA_CAP_Q_KEY_VIOL_CTR" },
+       { HCA_CAP_WQE_RESIZE, "HCA_CAP_WQE_RESIZE" },
+       { HCA_CAP_RAW_PACKET_MCAST, "HCA_CAP_RAW_PACKET_MCAST" },
+       { HCA_CAP_SHUTDOWN_PORT, "HCA_CAP_SHUTDOWN_PORT" },
+       { HCA_CAP_RC_LL_QP, "HCA_CAP_RC_LL_QP" },
+       { HCA_CAP_SRQ, "HCA_CAP_SRQ" },
+       { HCA_CAP_UD_LL_QP, "HCA_CAP_UD_LL_QP" },
+       { HCA_CAP_RESIZE_MR, "HCA_CAP_RESIZE_MR" },
+       { HCA_CAP_MINI_QP, "HCA_CAP_MINI_QP" },
+};
+
 int ehca_sense_attributes(struct ehca_shca *shca)
 {
-       int ret = 0;
+       int i, ret = 0;
        u64 h_ret;
        struct hipz_query_hca *rblock;
+       struct hipz_query_port *port;
 
        rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
        if (!rblock) {
@@ -222,7 +244,7 @@ int ehca_sense_attributes(struct ehca_shca *shca)
                ehca_gen_err("Cannot query device properties. h_ret=%lx",
                             h_ret);
                ret = -EPERM;
-               goto num_ports1;
+               goto sense_attributes1;
        }
 
        if (ehca_nr_ports == 1)
@@ -242,18 +264,44 @@ int ehca_sense_attributes(struct ehca_shca *shca)
                ehca_gen_dbg(" ... hardware version=%x:%x", hcaaver, revid);
 
                if ((hcaaver == 1) && (revid == 0))
-                       shca->hw_level = 0;
+                       shca->hw_level = 0x11;
                else if ((hcaaver == 1) && (revid == 1))
-                       shca->hw_level = 1;
+                       shca->hw_level = 0x12;
                else if ((hcaaver == 1) && (revid == 2))
-                       shca->hw_level = 2;
+                       shca->hw_level = 0x13;
+               else if ((hcaaver == 2) && (revid == 0))
+                       shca->hw_level = 0x21;
+               else if ((hcaaver == 2) && (revid == 0x10))
+                       shca->hw_level = 0x22;
+               else {
+                       ehca_gen_warn("unknown hardware version"
+                                     " - assuming default level");
+                       shca->hw_level = 0x22;
+               }
        }
        ehca_gen_dbg(" ... hardware level=%x", shca->hw_level);
 
        shca->sport[0].rate = IB_RATE_30_GBPS;
        shca->sport[1].rate = IB_RATE_30_GBPS;
 
-num_ports1:
+       shca->hca_cap = rblock->hca_cap_indicators;
+       ehca_gen_dbg(" ... HCA capabilities:");
+       for (i = 0; i < ARRAY_SIZE(hca_cap_descr); i++)
+               if (EHCA_BMASK_GET(hca_cap_descr[i].mask, shca->hca_cap))
+                       ehca_gen_dbg("   %s", hca_cap_descr[i].descr);
+
+       port = (struct hipz_query_port *) rblock;
+       h_ret = hipz_h_query_port(shca->ipz_hca_handle, 1, port);
+       if (h_ret != H_SUCCESS) {
+               ehca_gen_err("Cannot query port properties. h_ret=%lx",
+                            h_ret);
+               ret = -EPERM;
+               goto sense_attributes1;
+       }
+
+       shca->max_mtu = port->max_mtu;
+
+sense_attributes1:
        ehca_free_fw_ctrlblock(rblock);
        return ret;
 }
@@ -293,7 +341,7 @@ int ehca_init_device(struct ehca_shca *shca)
        strlcpy(shca->ib_device.name, "ehca%d", IB_DEVICE_NAME_MAX);
        shca->ib_device.owner               = THIS_MODULE;
 
-       shca->ib_device.uverbs_abi_ver      = 6;
+       shca->ib_device.uverbs_abi_ver      = 7;
        shca->ib_device.uverbs_cmd_mask     =
                (1ull << IB_USER_VERBS_CMD_GET_CONTEXT)         |
                (1ull << IB_USER_VERBS_CMD_QUERY_DEVICE)        |
@@ -361,6 +409,20 @@ int ehca_init_device(struct ehca_shca *shca)
        /* shca->ib_device.process_mad      = ehca_process_mad;     */
        shca->ib_device.mmap                = ehca_mmap;
 
+       if (EHCA_BMASK_GET(HCA_CAP_SRQ, shca->hca_cap)) {
+               shca->ib_device.uverbs_cmd_mask |=
+                       (1ull << IB_USER_VERBS_CMD_CREATE_SRQ) |
+                       (1ull << IB_USER_VERBS_CMD_MODIFY_SRQ) |
+                       (1ull << IB_USER_VERBS_CMD_QUERY_SRQ) |
+                       (1ull << IB_USER_VERBS_CMD_DESTROY_SRQ);
+
+               shca->ib_device.create_srq          = ehca_create_srq;
+               shca->ib_device.modify_srq          = ehca_modify_srq;
+               shca->ib_device.query_srq           = ehca_query_srq;
+               shca->ib_device.destroy_srq         = ehca_destroy_srq;
+               shca->ib_device.post_srq_recv       = ehca_post_srq_recv;
+       }
+
        return ret;
 }
 
@@ -800,14 +862,6 @@ int __init ehca_module_init(void)
 
        printk(KERN_INFO "eHCA Infiniband Device Driver "
               "(Rel.: SVNEHCA_0023)\n");
-       idr_init(&ehca_qp_idr);
-       idr_init(&ehca_cq_idr);
-       spin_lock_init(&ehca_qp_idr_lock);
-       spin_lock_init(&ehca_cq_idr_lock);
-       spin_lock_init(&hcall_lock);
-
-       INIT_LIST_HEAD(&shca_list);
-       spin_lock_init(&shca_list_lock);
 
        if ((ret = ehca_create_comp_pool())) {
                ehca_gen_err("Cannot create comp pool.");
index b5bc787c77b655fda3404b2a08f273590921f951..74671250303f00433247cae49679b89be401a6f8 100644 (file)
@@ -3,7 +3,9 @@
  *
  *  QP functions
  *
- *  Authors: Waleri Fomin <fomin@de.ibm.com>
+ *  Authors: Joachim Fenkes <fenkes@de.ibm.com>
+ *           Stefan Roscher <stefan.roscher@de.ibm.com>
+ *           Waleri Fomin <fomin@de.ibm.com>
  *           Hoang-Nam Nguyen <hnguyen@de.ibm.com>
  *           Reinhard Ernst <rernst@de.ibm.com>
  *           Heiko J Schick <schickhj@de.ibm.com>
@@ -234,13 +236,6 @@ static inline enum ib_qp_statetrans get_modqp_statetrans(int ib_fromstate,
        return index;
 }
 
-enum ehca_service_type {
-       ST_RC = 0,
-       ST_UC = 1,
-       ST_RD = 2,
-       ST_UD = 3
-};
-
 /*
  * ibqptype2servicetype returns hcp service type corresponding to given
  * ib qp type used by create_qp()
@@ -268,15 +263,34 @@ static inline int ibqptype2servicetype(enum ib_qp_type ibqptype)
 }
 
 /*
- * init_qp_queues initializes/constructs r/squeue and registers queue pages.
+ * init userspace queue info from ipz_queue data
  */
-static inline int init_qp_queues(struct ehca_shca *shca,
-                                struct ehca_qp *my_qp,
-                                int nr_sq_pages,
-                                int nr_rq_pages,
-                                int swqe_size,
-                                int rwqe_size,
-                                int nr_send_sges, int nr_receive_sges)
+static inline void queue2resp(struct ipzu_queue_resp *resp,
+                             struct ipz_queue *queue)
+{
+       resp->qe_size = queue->qe_size;
+       resp->act_nr_of_sg = queue->act_nr_of_sg;
+       resp->queue_length = queue->queue_length;
+       resp->pagesize = queue->pagesize;
+       resp->toggle_state = queue->toggle_state;
+}
+
+static inline int ll_qp_msg_size(int nr_sge)
+{
+       return 128 << nr_sge;
+}
+
+/*
+ * init_qp_queue initializes/constructs r/squeue and registers queue pages.
+ */
+static inline int init_qp_queue(struct ehca_shca *shca,
+                               struct ehca_qp *my_qp,
+                               struct ipz_queue *queue,
+                               int q_type,
+                               u64 expected_hret,
+                               int nr_q_pages,
+                               int wqe_size,
+                               int nr_sges)
 {
        int ret, cnt, ipz_rc;
        void *vpage;
@@ -284,127 +298,93 @@ static inline int init_qp_queues(struct ehca_shca *shca,
        struct ib_device *ib_dev = &shca->ib_device;
        struct ipz_adapter_handle ipz_hca_handle = shca->ipz_hca_handle;
 
-       ipz_rc = ipz_queue_ctor(&my_qp->ipz_squeue,
-                               nr_sq_pages,
-                               EHCA_PAGESIZE, swqe_size, nr_send_sges);
+       if (!nr_q_pages)
+               return 0;
+
+       ipz_rc = ipz_queue_ctor(queue, nr_q_pages, EHCA_PAGESIZE,
+                               wqe_size, nr_sges);
        if (!ipz_rc) {
-               ehca_err(ib_dev,"Cannot allocate page for squeue. ipz_rc=%x",
+               ehca_err(ib_dev, "Cannot allocate page for queue. ipz_rc=%x",
                         ipz_rc);
                return -EBUSY;
        }
 
-       ipz_rc = ipz_queue_ctor(&my_qp->ipz_rqueue,
-                               nr_rq_pages,
-                               EHCA_PAGESIZE, rwqe_size, nr_receive_sges);
-       if (!ipz_rc) {
-               ehca_err(ib_dev, "Cannot allocate page for rqueue. ipz_rc=%x",
-                        ipz_rc);
-               ret = -EBUSY;
-               goto init_qp_queues0;
-       }
-       /* register SQ pages */
-       for (cnt = 0; cnt < nr_sq_pages; cnt++) {
-               vpage = ipz_qpageit_get_inc(&my_qp->ipz_squeue);
+       /* register queue pages */
+       for (cnt = 0; cnt < nr_q_pages; cnt++) {
+               vpage = ipz_qpageit_get_inc(queue);
                if (!vpage) {
-                       ehca_err(ib_dev, "SQ ipz_qpageit_get_inc() "
+                       ehca_err(ib_dev, "ipz_qpageit_get_inc() "
                                 "failed p_vpage= %p", vpage);
                        ret = -EINVAL;
-                       goto init_qp_queues1;
+                       goto init_qp_queue1;
                }
                rpage = virt_to_abs(vpage);
 
                h_ret = hipz_h_register_rpage_qp(ipz_hca_handle,
                                                 my_qp->ipz_qp_handle,
-                                                &my_qp->pf, 0, 0,
+                                                NULL, 0, q_type,
                                                 rpage, 1,
                                                 my_qp->galpas.kernel);
-               if (h_ret < H_SUCCESS) {
-                       ehca_err(ib_dev, "SQ hipz_qp_register_rpage()"
-                                " failed rc=%lx", h_ret);
-                       ret = ehca2ib_return_code(h_ret);
-                       goto init_qp_queues1;
-               }
-       }
-
-       ipz_qeit_reset(&my_qp->ipz_squeue);
-
-       /* register RQ pages */
-       for (cnt = 0; cnt < nr_rq_pages; cnt++) {
-               vpage = ipz_qpageit_get_inc(&my_qp->ipz_rqueue);
-               if (!vpage) {
-                       ehca_err(ib_dev, "RQ ipz_qpageit_get_inc() "
-                                "failed p_vpage = %p", vpage);
-                       ret = -EINVAL;
-                       goto init_qp_queues1;
-               }
-
-               rpage = virt_to_abs(vpage);
-
-               h_ret = hipz_h_register_rpage_qp(ipz_hca_handle,
-                                                my_qp->ipz_qp_handle,
-                                                &my_qp->pf, 0, 1,
-                                                rpage, 1,my_qp->galpas.kernel);
-               if (h_ret < H_SUCCESS) {
-                       ehca_err(ib_dev, "RQ hipz_qp_register_rpage() failed "
-                                "rc=%lx", h_ret);
-                       ret = ehca2ib_return_code(h_ret);
-                       goto init_qp_queues1;
-               }
-               if (cnt == (nr_rq_pages - 1)) { /* last page! */
-                       if (h_ret != H_SUCCESS) {
-                               ehca_err(ib_dev, "RQ hipz_qp_register_rpage() "
+               if (cnt == (nr_q_pages - 1)) {  /* last page! */
+                       if (h_ret != expected_hret) {
+                               ehca_err(ib_dev, "hipz_qp_register_rpage() "
                                         "h_ret= %lx ", h_ret);
                                ret = ehca2ib_return_code(h_ret);
-                               goto init_qp_queues1;
+                               goto init_qp_queue1;
                        }
                        vpage = ipz_qpageit_get_inc(&my_qp->ipz_rqueue);
                        if (vpage) {
                                ehca_err(ib_dev, "ipz_qpageit_get_inc() "
                                         "should not succeed vpage=%p", vpage);
                                ret = -EINVAL;
-                               goto init_qp_queues1;
+                               goto init_qp_queue1;
                        }
                } else {
                        if (h_ret != H_PAGE_REGISTERED) {
-                               ehca_err(ib_dev, "RQ hipz_qp_register_rpage() "
+                               ehca_err(ib_dev, "hipz_qp_register_rpage() "
                                         "h_ret= %lx ", h_ret);
                                ret = ehca2ib_return_code(h_ret);
-                               goto init_qp_queues1;
+                               goto init_qp_queue1;
                        }
                }
        }
 
-       ipz_qeit_reset(&my_qp->ipz_rqueue);
+       ipz_qeit_reset(queue);
 
        return 0;
 
-init_qp_queues1:
-       ipz_queue_dtor(&my_qp->ipz_rqueue);
-init_qp_queues0:
-       ipz_queue_dtor(&my_qp->ipz_squeue);
+init_qp_queue1:
+       ipz_queue_dtor(queue);
        return ret;
 }
 
-struct ib_qp *ehca_create_qp(struct ib_pd *pd,
-                            struct ib_qp_init_attr *init_attr,
-                            struct ib_udata *udata)
+/*
+ * Create an ib_qp struct that is either a QP or an SRQ, depending on
+ * the value of the is_srq parameter. If init_attr and srq_init_attr share
+ * fields, the field out of init_attr is used.
+ */
+struct ehca_qp *internal_create_qp(struct ib_pd *pd,
+                                  struct ib_qp_init_attr *init_attr,
+                                  struct ib_srq_init_attr *srq_init_attr,
+                                  struct ib_udata *udata, int is_srq)
 {
-       static int da_rc_msg_size[]={ 128, 256, 512, 1024, 2048, 4096 };
-       static int da_ud_sq_msg_size[]={ 128, 384, 896, 1920, 3968 };
        struct ehca_qp *my_qp;
        struct ehca_pd *my_pd = container_of(pd, struct ehca_pd, ib_pd);
        struct ehca_shca *shca = container_of(pd->device, struct ehca_shca,
                                              ib_device);
        struct ib_ucontext *context = NULL;
        u64 h_ret;
-       int max_send_sge, max_recv_sge, ret;
+       int is_llqp = 0, has_srq = 0;
+       int qp_type, max_send_sge, max_recv_sge, ret;
 
        /* h_call's out parameters */
        struct ehca_alloc_qp_parms parms;
-       u32 swqe_size = 0, rwqe_size = 0;
-       u8 daqp_completion, isdaqp;
+       u32 swqe_size = 0, rwqe_size = 0, ib_qp_num;
        unsigned long flags;
 
+       memset(&parms, 0, sizeof(parms));
+       qp_type = init_attr->qp_type;
+
        if (init_attr->sq_sig_type != IB_SIGNAL_REQ_WR &&
                init_attr->sq_sig_type != IB_SIGNAL_ALL_WR) {
                ehca_err(pd->device, "init_attr->sg_sig_type=%x not allowed",
@@ -412,41 +392,98 @@ struct ib_qp *ehca_create_qp(struct ib_pd *pd,
                return ERR_PTR(-EINVAL);
        }
 
-       /* save daqp completion bits */
-       daqp_completion = init_attr->qp_type & 0x60;
-       /* save daqp bit */
-       isdaqp = (init_attr->qp_type & 0x80) ? 1 : 0;
-       init_attr->qp_type = init_attr->qp_type & 0x1F;
+       /* save LLQP info */
+       if (qp_type & 0x80) {
+               is_llqp = 1;
+               parms.ext_type = EQPT_LLQP;
+               parms.ll_comp_flags = qp_type & LLQP_COMP_MASK;
+       }
+       qp_type &= 0x1F;
+       init_attr->qp_type &= 0x1F;
 
-       if (init_attr->qp_type != IB_QPT_UD &&
-           init_attr->qp_type != IB_QPT_SMI &&
-           init_attr->qp_type != IB_QPT_GSI &&
-           init_attr->qp_type != IB_QPT_UC &&
-           init_attr->qp_type != IB_QPT_RC) {
-               ehca_err(pd->device, "wrong QP Type=%x", init_attr->qp_type);
-               return ERR_PTR(-EINVAL);
+       /* handle SRQ base QPs */
+       if (init_attr->srq) {
+               struct ehca_qp *my_srq =
+                       container_of(init_attr->srq, struct ehca_qp, ib_srq);
+
+               has_srq = 1;
+               parms.ext_type = EQPT_SRQBASE;
+               parms.srq_qpn = my_srq->real_qp_num;
+               parms.srq_token = my_srq->token;
        }
-       if ((init_attr->qp_type != IB_QPT_RC && init_attr->qp_type != IB_QPT_UD)
-           && isdaqp) {
-               ehca_err(pd->device, "unsupported LL QP Type=%x",
-                        init_attr->qp_type);
+
+       if (is_llqp && has_srq) {
+               ehca_err(pd->device, "LLQPs can't have an SRQ");
                return ERR_PTR(-EINVAL);
-       } else if (init_attr->qp_type == IB_QPT_RC && isdaqp &&
-                  (init_attr->cap.max_send_wr > 255 ||
-                   init_attr->cap.max_recv_wr > 255 )) {
-                      ehca_err(pd->device, "Invalid Number of max_sq_wr =%x "
-                               "or max_rq_wr=%x for QP Type=%x",
-                               init_attr->cap.max_send_wr,
-                               init_attr->cap.max_recv_wr,init_attr->qp_type);
-                      return ERR_PTR(-EINVAL);
-       } else if (init_attr->qp_type == IB_QPT_UD && isdaqp &&
-                 init_attr->cap.max_send_wr > 255) {
-               ehca_err(pd->device,
-                        "Invalid Number of max_send_wr=%x for UD QP_TYPE=%x",
-                        init_attr->cap.max_send_wr, init_attr->qp_type);
+       }
+
+       /* handle SRQs */
+       if (is_srq) {
+               parms.ext_type = EQPT_SRQ;
+               parms.srq_limit = srq_init_attr->attr.srq_limit;
+               if (init_attr->cap.max_recv_sge > 3) {
+                       ehca_err(pd->device, "no more than three SGEs "
+                                "supported for SRQ  pd=%p  max_sge=%x",
+                                pd, init_attr->cap.max_recv_sge);
+                       return ERR_PTR(-EINVAL);
+               }
+       }
+
+       /* check QP type */
+       if (qp_type != IB_QPT_UD &&
+           qp_type != IB_QPT_UC &&
+           qp_type != IB_QPT_RC &&
+           qp_type != IB_QPT_SMI &&
+           qp_type != IB_QPT_GSI) {
+               ehca_err(pd->device, "wrong QP Type=%x", qp_type);
                return ERR_PTR(-EINVAL);
        }
 
+       if (is_llqp) {
+               switch (qp_type) {
+               case IB_QPT_RC:
+                       if ((init_attr->cap.max_send_wr > 255) ||
+                           (init_attr->cap.max_recv_wr > 255)) {
+                               ehca_err(pd->device,
+                                        "Invalid Number of max_sq_wr=%x "
+                                        "or max_rq_wr=%x for RC LLQP",
+                                        init_attr->cap.max_send_wr,
+                                        init_attr->cap.max_recv_wr);
+                               return ERR_PTR(-EINVAL);
+                       }
+                       break;
+               case IB_QPT_UD:
+                       if (!EHCA_BMASK_GET(HCA_CAP_UD_LL_QP, shca->hca_cap)) {
+                               ehca_err(pd->device, "UD LLQP not supported "
+                                        "by this adapter");
+                               return ERR_PTR(-ENOSYS);
+                       }
+                       if (!(init_attr->cap.max_send_sge <= 5
+                           && init_attr->cap.max_send_sge >= 1
+                           && init_attr->cap.max_recv_sge <= 5
+                           && init_attr->cap.max_recv_sge >= 1)) {
+                               ehca_err(pd->device,
+                                        "Invalid Number of max_send_sge=%x "
+                                        "or max_recv_sge=%x for UD LLQP",
+                                        init_attr->cap.max_send_sge,
+                                        init_attr->cap.max_recv_sge);
+                               return ERR_PTR(-EINVAL);
+                       } else if (init_attr->cap.max_send_wr > 255) {
+                               ehca_err(pd->device,
+                                        "Invalid Number of "
+                                        "ax_send_wr=%x for UD QP_TYPE=%x",
+                                        init_attr->cap.max_send_wr, qp_type);
+                               return ERR_PTR(-EINVAL);
+                       }
+                       break;
+               default:
+                       ehca_err(pd->device, "unsupported LL QP Type=%x",
+                                qp_type);
+                       return ERR_PTR(-EINVAL);
+                       break;
+               }
+       }
+
        if (pd->uobject && udata)
                context = pd->uobject->context;
 
@@ -456,16 +493,17 @@ struct ib_qp *ehca_create_qp(struct ib_pd *pd,
                return ERR_PTR(-ENOMEM);
        }
 
-       memset (&parms, 0, sizeof(struct ehca_alloc_qp_parms));
        spin_lock_init(&my_qp->spinlock_s);
        spin_lock_init(&my_qp->spinlock_r);
+       my_qp->qp_type = qp_type;
+       my_qp->ext_type = parms.ext_type;
 
-       my_qp->recv_cq =
-               container_of(init_attr->recv_cq, struct ehca_cq, ib_cq);
-       my_qp->send_cq =
-               container_of(init_attr->send_cq, struct ehca_cq, ib_cq);
-
-       my_qp->init_attr = *init_attr;
+       if (init_attr->recv_cq)
+               my_qp->recv_cq =
+                       container_of(init_attr->recv_cq, struct ehca_cq, ib_cq);
+       if (init_attr->send_cq)
+               my_qp->send_cq =
+                       container_of(init_attr->send_cq, struct ehca_cq, ib_cq);
 
        do {
                if (!idr_pre_get(&ehca_qp_idr, GFP_KERNEL)) {
@@ -474,9 +512,9 @@ struct ib_qp *ehca_create_qp(struct ib_pd *pd,
                        goto create_qp_exit0;
                }
 
-               spin_lock_irqsave(&ehca_qp_idr_lock, flags);
+               write_lock_irqsave(&ehca_qp_idr_lock, flags);
                ret = idr_get_new(&ehca_qp_idr, my_qp, &my_qp->token);
-               spin_unlock_irqrestore(&ehca_qp_idr_lock, flags);
+               write_unlock_irqrestore(&ehca_qp_idr_lock, flags);
 
        } while (ret == -EAGAIN);
 
@@ -486,10 +524,10 @@ struct ib_qp *ehca_create_qp(struct ib_pd *pd,
                goto create_qp_exit0;
        }
 
-       parms.servicetype = ibqptype2servicetype(init_attr->qp_type);
+       parms.servicetype = ibqptype2servicetype(qp_type);
        if (parms.servicetype < 0) {
                ret = -EINVAL;
-               ehca_err(pd->device, "Invalid qp_type=%x", init_attr->qp_type);
+               ehca_err(pd->device, "Invalid qp_type=%x", qp_type);
                goto create_qp_exit0;
        }
 
@@ -501,21 +539,25 @@ struct ib_qp *ehca_create_qp(struct ib_pd *pd,
        /* UD_AV CIRCUMVENTION */
        max_send_sge = init_attr->cap.max_send_sge;
        max_recv_sge = init_attr->cap.max_recv_sge;
-       if (IB_QPT_UD == init_attr->qp_type ||
-           IB_QPT_GSI == init_attr->qp_type ||
-           IB_QPT_SMI == init_attr->qp_type) {
+       if (parms.servicetype == ST_UD && !is_llqp) {
                max_send_sge += 2;
                max_recv_sge += 2;
        }
 
-       parms.ipz_eq_handle = shca->eq.ipz_eq_handle;
-       parms.daqp_ctrl = isdaqp | daqp_completion;
+       parms.token = my_qp->token;
+       parms.eq_handle = shca->eq.ipz_eq_handle;
        parms.pd = my_pd->fw_pd;
-       parms.max_recv_sge = max_recv_sge;
-       parms.max_send_sge = max_send_sge;
+       if (my_qp->send_cq)
+               parms.send_cq_handle = my_qp->send_cq->ipz_cq_handle;
+       if (my_qp->recv_cq)
+               parms.recv_cq_handle = my_qp->recv_cq->ipz_cq_handle;
 
-       h_ret = hipz_h_alloc_resource_qp(shca->ipz_hca_handle, my_qp, &parms);
+       parms.max_send_wr = init_attr->cap.max_send_wr;
+       parms.max_recv_wr = init_attr->cap.max_recv_wr;
+       parms.max_send_sge = max_send_sge;
+       parms.max_recv_sge = max_recv_sge;
 
+       h_ret = hipz_h_alloc_resource_qp(shca->ipz_hca_handle, &parms);
        if (h_ret != H_SUCCESS) {
                ehca_err(pd->device, "h_alloc_resource_qp() failed h_ret=%lx",
                         h_ret);
@@ -523,18 +565,20 @@ struct ib_qp *ehca_create_qp(struct ib_pd *pd,
                goto create_qp_exit1;
        }
 
-       my_qp->ib_qp.qp_num = my_qp->real_qp_num;
+       ib_qp_num = my_qp->real_qp_num = parms.real_qp_num;
+       my_qp->ipz_qp_handle = parms.qp_handle;
+       my_qp->galpas = parms.galpas;
 
-       switch (init_attr->qp_type) {
+       switch (qp_type) {
        case IB_QPT_RC:
-               if (isdaqp == 0) {
+               if (!is_llqp) {
                        swqe_size = offsetof(struct ehca_wqe, u.nud.sg_list[
                                             (parms.act_nr_send_sges)]);
                        rwqe_size = offsetof(struct ehca_wqe, u.nud.sg_list[
                                             (parms.act_nr_recv_sges)]);
-               } else { /* for daqp we need to use msg size, not wqe size */
-                       swqe_size = da_rc_msg_size[max_send_sge];
-                       rwqe_size = da_rc_msg_size[max_recv_sge];
+               } else { /* for LLQP we need to use msg size, not wqe size */
+                       swqe_size = ll_qp_msg_size(max_send_sge);
+                       rwqe_size = ll_qp_msg_size(max_recv_sge);
                        parms.act_nr_send_sges = 1;
                        parms.act_nr_recv_sges = 1;
                }
@@ -549,29 +593,27 @@ struct ib_qp *ehca_create_qp(struct ib_pd *pd,
        case IB_QPT_UD:
        case IB_QPT_GSI:
        case IB_QPT_SMI:
-               /* UD circumvention */
-               parms.act_nr_recv_sges -= 2;
-               parms.act_nr_send_sges -= 2;
-               if (isdaqp) {
-                       swqe_size = da_ud_sq_msg_size[max_send_sge];
-                       rwqe_size = da_rc_msg_size[max_recv_sge];
+               if (is_llqp) {
+                       swqe_size = ll_qp_msg_size(parms.act_nr_send_sges);
+                       rwqe_size = ll_qp_msg_size(parms.act_nr_recv_sges);
                        parms.act_nr_send_sges = 1;
                        parms.act_nr_recv_sges = 1;
                } else {
+                       /* UD circumvention */
+                       parms.act_nr_send_sges -= 2;
+                       parms.act_nr_recv_sges -= 2;
                        swqe_size = offsetof(struct ehca_wqe,
                                             u.ud_av.sg_list[parms.act_nr_send_sges]);
                        rwqe_size = offsetof(struct ehca_wqe,
                                             u.ud_av.sg_list[parms.act_nr_recv_sges]);
                }
 
-               if (IB_QPT_GSI == init_attr->qp_type ||
-                   IB_QPT_SMI == init_attr->qp_type) {
+               if (IB_QPT_GSI == qp_type || IB_QPT_SMI == qp_type) {
                        parms.act_nr_send_wqes = init_attr->cap.max_send_wr;
                        parms.act_nr_recv_wqes = init_attr->cap.max_recv_wr;
                        parms.act_nr_send_sges = init_attr->cap.max_send_sge;
                        parms.act_nr_recv_sges = init_attr->cap.max_recv_sge;
-                       my_qp->ib_qp.qp_num =
-                               (init_attr->qp_type == IB_QPT_SMI) ? 0 : 1;
+                       ib_qp_num = (qp_type == IB_QPT_SMI) ? 0 : 1;
                }
 
                break;
@@ -580,108 +622,234 @@ struct ib_qp *ehca_create_qp(struct ib_pd *pd,
                break;
        }
 
-       /* initializes r/squeue and registers queue pages */
-       ret = init_qp_queues(shca, my_qp,
-                            parms.nr_sq_pages, parms.nr_rq_pages,
-                            swqe_size, rwqe_size,
-                            parms.act_nr_send_sges, parms.act_nr_recv_sges);
-       if (ret) {
-               ehca_err(pd->device,
-                        "Couldn't initialize r/squeue and pages ret=%x", ret);
-               goto create_qp_exit2;
+       /* initialize r/squeue and register queue pages */
+       if (HAS_SQ(my_qp)) {
+               ret = init_qp_queue(
+                       shca, my_qp, &my_qp->ipz_squeue, 0,
+                       HAS_RQ(my_qp) ? H_PAGE_REGISTERED : H_SUCCESS,
+                       parms.nr_sq_pages, swqe_size,
+                       parms.act_nr_send_sges);
+               if (ret) {
+                       ehca_err(pd->device, "Couldn't initialize squeue "
+                                "and pages  ret=%x", ret);
+                       goto create_qp_exit2;
+               }
        }
 
-       my_qp->ib_qp.pd = &my_pd->ib_pd;
-       my_qp->ib_qp.device = my_pd->ib_pd.device;
+       if (HAS_RQ(my_qp)) {
+               ret = init_qp_queue(
+                       shca, my_qp, &my_qp->ipz_rqueue, 1,
+                       H_SUCCESS, parms.nr_rq_pages, rwqe_size,
+                       parms.act_nr_recv_sges);
+               if (ret) {
+                       ehca_err(pd->device, "Couldn't initialize rqueue "
+                                "and pages ret=%x", ret);
+                       goto create_qp_exit3;
+               }
+       }
 
-       my_qp->ib_qp.recv_cq = init_attr->recv_cq;
-       my_qp->ib_qp.send_cq = init_attr->send_cq;
+       if (is_srq) {
+               my_qp->ib_srq.pd = &my_pd->ib_pd;
+               my_qp->ib_srq.device = my_pd->ib_pd.device;
 
-       my_qp->ib_qp.qp_type = init_attr->qp_type;
+               my_qp->ib_srq.srq_context = init_attr->qp_context;
+               my_qp->ib_srq.event_handler = init_attr->event_handler;
+       } else {
+               my_qp->ib_qp.qp_num = ib_qp_num;
+               my_qp->ib_qp.pd = &my_pd->ib_pd;
+               my_qp->ib_qp.device = my_pd->ib_pd.device;
+
+               my_qp->ib_qp.recv_cq = init_attr->recv_cq;
+               my_qp->ib_qp.send_cq = init_attr->send_cq;
 
-       my_qp->qp_type = init_attr->qp_type;
-       my_qp->ib_qp.srq = init_attr->srq;
+               my_qp->ib_qp.qp_type = qp_type;
+               my_qp->ib_qp.srq = init_attr->srq;
 
-       my_qp->ib_qp.qp_context = init_attr->qp_context;
-       my_qp->ib_qp.event_handler = init_attr->event_handler;
+               my_qp->ib_qp.qp_context = init_attr->qp_context;
+               my_qp->ib_qp.event_handler = init_attr->event_handler;
+       }
 
        init_attr->cap.max_inline_data = 0; /* not supported yet */
        init_attr->cap.max_recv_sge = parms.act_nr_recv_sges;
        init_attr->cap.max_recv_wr = parms.act_nr_recv_wqes;
        init_attr->cap.max_send_sge = parms.act_nr_send_sges;
        init_attr->cap.max_send_wr = parms.act_nr_send_wqes;
+       my_qp->init_attr = *init_attr;
 
        /* NOTE: define_apq0() not supported yet */
-       if (init_attr->qp_type == IB_QPT_GSI) {
+       if (qp_type == IB_QPT_GSI) {
                h_ret = ehca_define_sqp(shca, my_qp, init_attr);
                if (h_ret != H_SUCCESS) {
                        ehca_err(pd->device, "ehca_define_sqp() failed rc=%lx",
                                 h_ret);
                        ret = ehca2ib_return_code(h_ret);
-                       goto create_qp_exit3;
+                       goto create_qp_exit4;
                }
        }
-       if (init_attr->send_cq) {
-               struct ehca_cq *cq = container_of(init_attr->send_cq,
-                                                 struct ehca_cq, ib_cq);
-               ret = ehca_cq_assign_qp(cq, my_qp);
+
+       if (my_qp->send_cq) {
+               ret = ehca_cq_assign_qp(my_qp->send_cq, my_qp);
                if (ret) {
                        ehca_err(pd->device, "Couldn't assign qp to send_cq ret=%x",
                                 ret);
-                       goto create_qp_exit3;
+                       goto create_qp_exit4;
                }
-               my_qp->send_cq = cq;
        }
+
        /* copy queues, galpa data to user space */
        if (context && udata) {
-               struct ipz_queue *ipz_rqueue = &my_qp->ipz_rqueue;
-               struct ipz_queue *ipz_squeue = &my_qp->ipz_squeue;
                struct ehca_create_qp_resp resp;
                memset(&resp, 0, sizeof(resp));
 
                resp.qp_num = my_qp->real_qp_num;
                resp.token = my_qp->token;
                resp.qp_type = my_qp->qp_type;
+               resp.ext_type = my_qp->ext_type;
                resp.qkey = my_qp->qkey;
                resp.real_qp_num = my_qp->real_qp_num;
-               /* rqueue properties */
-               resp.ipz_rqueue.qe_size = ipz_rqueue->qe_size;
-               resp.ipz_rqueue.act_nr_of_sg = ipz_rqueue->act_nr_of_sg;
-               resp.ipz_rqueue.queue_length = ipz_rqueue->queue_length;
-               resp.ipz_rqueue.pagesize = ipz_rqueue->pagesize;
-               resp.ipz_rqueue.toggle_state = ipz_rqueue->toggle_state;
-               /* squeue properties */
-               resp.ipz_squeue.qe_size = ipz_squeue->qe_size;
-               resp.ipz_squeue.act_nr_of_sg = ipz_squeue->act_nr_of_sg;
-               resp.ipz_squeue.queue_length = ipz_squeue->queue_length;
-               resp.ipz_squeue.pagesize = ipz_squeue->pagesize;
-               resp.ipz_squeue.toggle_state = ipz_squeue->toggle_state;
+               if (HAS_SQ(my_qp))
+                       queue2resp(&resp.ipz_squeue, &my_qp->ipz_squeue);
+               if (HAS_RQ(my_qp))
+                       queue2resp(&resp.ipz_rqueue, &my_qp->ipz_rqueue);
+
                if (ib_copy_to_udata(udata, &resp, sizeof resp)) {
                        ehca_err(pd->device, "Copy to udata failed");
                        ret = -EINVAL;
-                       goto create_qp_exit3;
+                       goto create_qp_exit4;
                }
        }
 
-       return &my_qp->ib_qp;
+       return my_qp;
+
+create_qp_exit4:
+       if (HAS_RQ(my_qp))
+               ipz_queue_dtor(&my_qp->ipz_rqueue);
 
 create_qp_exit3:
-       ipz_queue_dtor(&my_qp->ipz_rqueue);
-       ipz_queue_dtor(&my_qp->ipz_squeue);
+       if (HAS_SQ(my_qp))
+               ipz_queue_dtor(&my_qp->ipz_squeue);
 
 create_qp_exit2:
        hipz_h_destroy_qp(shca->ipz_hca_handle, my_qp);
 
 create_qp_exit1:
-       spin_lock_irqsave(&ehca_qp_idr_lock, flags);
+       write_lock_irqsave(&ehca_qp_idr_lock, flags);
        idr_remove(&ehca_qp_idr, my_qp->token);
-       spin_unlock_irqrestore(&ehca_qp_idr_lock, flags);
+       write_unlock_irqrestore(&ehca_qp_idr_lock, flags);
 
 create_qp_exit0:
        kmem_cache_free(qp_cache, my_qp);
        return ERR_PTR(ret);
 }
 
+struct ib_qp *ehca_create_qp(struct ib_pd *pd,
+                            struct ib_qp_init_attr *qp_init_attr,
+                            struct ib_udata *udata)
+{
+       struct ehca_qp *ret;
+
+       ret = internal_create_qp(pd, qp_init_attr, NULL, udata, 0);
+       return IS_ERR(ret) ? (struct ib_qp *) ret : &ret->ib_qp;
+}
+
+int internal_destroy_qp(struct ib_device *dev, struct ehca_qp *my_qp,
+                       struct ib_uobject *uobject);
+
+struct ib_srq *ehca_create_srq(struct ib_pd *pd,
+                              struct ib_srq_init_attr *srq_init_attr,
+                              struct ib_udata *udata)
+{
+       struct ib_qp_init_attr qp_init_attr;
+       struct ehca_qp *my_qp;
+       struct ib_srq *ret;
+       struct ehca_shca *shca = container_of(pd->device, struct ehca_shca,
+                                             ib_device);
+       struct hcp_modify_qp_control_block *mqpcb;
+       u64 hret, update_mask;
+
+       /* For common attributes, internal_create_qp() takes its info
+        * out of qp_init_attr, so copy all common attrs there.
+        */
+       memset(&qp_init_attr, 0, sizeof(qp_init_attr));
+       qp_init_attr.event_handler = srq_init_attr->event_handler;
+       qp_init_attr.qp_context = srq_init_attr->srq_context;
+       qp_init_attr.sq_sig_type = IB_SIGNAL_ALL_WR;
+       qp_init_attr.qp_type = IB_QPT_RC;
+       qp_init_attr.cap.max_recv_wr = srq_init_attr->attr.max_wr;
+       qp_init_attr.cap.max_recv_sge = srq_init_attr->attr.max_sge;
+
+       my_qp = internal_create_qp(pd, &qp_init_attr, srq_init_attr, udata, 1);
+       if (IS_ERR(my_qp))
+               return (struct ib_srq *) my_qp;
+
+       /* copy back return values */
+       srq_init_attr->attr.max_wr = qp_init_attr.cap.max_recv_wr;
+       srq_init_attr->attr.max_sge = qp_init_attr.cap.max_recv_sge;
+
+       /* drive SRQ into RTR state */
+       mqpcb = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
+       if (!mqpcb) {
+               ehca_err(pd->device, "Could not get zeroed page for mqpcb "
+                        "ehca_qp=%p qp_num=%x ", my_qp, my_qp->real_qp_num);
+               ret = ERR_PTR(-ENOMEM);
+               goto create_srq1;
+       }
+
+       mqpcb->qp_state = EHCA_QPS_INIT;
+       mqpcb->prim_phys_port = 1;
+       update_mask = EHCA_BMASK_SET(MQPCB_MASK_QP_STATE, 1);
+       hret = hipz_h_modify_qp(shca->ipz_hca_handle,
+                               my_qp->ipz_qp_handle,
+                               &my_qp->pf,
+                               update_mask,
+                               mqpcb, my_qp->galpas.kernel);
+       if (hret != H_SUCCESS) {
+               ehca_err(pd->device, "Could not modify SRQ to INIT"
+                        "ehca_qp=%p qp_num=%x hret=%lx",
+                        my_qp, my_qp->real_qp_num, hret);
+               goto create_srq2;
+       }
+
+       mqpcb->qp_enable = 1;
+       update_mask = EHCA_BMASK_SET(MQPCB_MASK_QP_ENABLE, 1);
+       hret = hipz_h_modify_qp(shca->ipz_hca_handle,
+                               my_qp->ipz_qp_handle,
+                               &my_qp->pf,
+                               update_mask,
+                               mqpcb, my_qp->galpas.kernel);
+       if (hret != H_SUCCESS) {
+               ehca_err(pd->device, "Could not enable SRQ"
+                        "ehca_qp=%p qp_num=%x hret=%lx",
+                        my_qp, my_qp->real_qp_num, hret);
+               goto create_srq2;
+       }
+
+       mqpcb->qp_state  = EHCA_QPS_RTR;
+       update_mask = EHCA_BMASK_SET(MQPCB_MASK_QP_STATE, 1);
+       hret = hipz_h_modify_qp(shca->ipz_hca_handle,
+                               my_qp->ipz_qp_handle,
+                               &my_qp->pf,
+                               update_mask,
+                               mqpcb, my_qp->galpas.kernel);
+       if (hret != H_SUCCESS) {
+               ehca_err(pd->device, "Could not modify SRQ to RTR"
+                        "ehca_qp=%p qp_num=%x hret=%lx",
+                        my_qp, my_qp->real_qp_num, hret);
+               goto create_srq2;
+       }
+
+       return &my_qp->ib_srq;
+
+create_srq2:
+       ret = ERR_PTR(ehca2ib_return_code(hret));
+       ehca_free_fw_ctrlblock(mqpcb);
+
+create_srq1:
+       internal_destroy_qp(pd->device, my_qp, my_qp->ib_srq.uobject);
+
+       return ret;
+}
+
 /*
  * prepare_sqe_rts called by internal_modify_qp() at trans sqe -> rts
  * set purge bit of bad wqe and subsequent wqes to avoid reentering sqe
@@ -765,7 +933,7 @@ static int internal_modify_qp(struct ib_qp *ibqp,
        u64 h_ret;
        int bad_wqe_cnt = 0;
        int squeue_locked = 0;
-       unsigned long spl_flags = 0;
+       unsigned long flags = 0;
 
        /* do query_qp to obtain current attr values */
        mqpcb = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
@@ -886,6 +1054,17 @@ static int internal_modify_qp(struct ib_qp *ibqp,
                 "ehca_qp=%p qp_num=%x <VALID STATE CHANGE> qp_state_xsit=%x",
                 my_qp, ibqp->qp_num, statetrans);
 
+       /* eHCA2 rev2 and higher require the SEND_GRH_FLAG to be set
+        * in non-LL UD QPs.
+        */
+       if ((my_qp->qp_type == IB_QPT_UD) &&
+           (my_qp->ext_type != EQPT_LLQP) &&
+           (statetrans == IB_QPST_INIT2RTR) &&
+           (shca->hw_level >= 0x22)) {
+               update_mask |= EHCA_BMASK_SET(MQPCB_MASK_SEND_GRH_FLAG, 1);
+               mqpcb->send_grh_flag = 1;
+       }
+
        /* sqe -> rts: set purge bit of bad wqe before actual trans */
        if ((my_qp->qp_type == IB_QPT_UD ||
             my_qp->qp_type == IB_QPT_GSI ||
@@ -895,7 +1074,7 @@ static int internal_modify_qp(struct ib_qp *ibqp,
                if (!ibqp->uobject) {
                        struct ehca_wqe *wqe;
                        /* lock send queue */
-                       spin_lock_irqsave(&my_qp->spinlock_s, spl_flags);
+                       spin_lock_irqsave(&my_qp->spinlock_s, flags);
                        squeue_locked = 1;
                        /* mark next free wqe */
                        wqe = (struct ehca_wqe*)
@@ -1181,7 +1360,7 @@ static int internal_modify_qp(struct ib_qp *ibqp,
 
 modify_qp_exit2:
        if (squeue_locked) { /* this means: sqe -> rts */
-               spin_unlock_irqrestore(&my_qp->spinlock_s, spl_flags);
+               spin_unlock_irqrestore(&my_qp->spinlock_s, flags);
                my_qp->sqerr_purgeflag = 1;
        }
 
@@ -1312,6 +1491,9 @@ int ehca_query_qp(struct ib_qp *qp,
        qp_attr->alt_port_num = qpcb->alt_phys_port;
        qp_attr->alt_timeout = qpcb->timeout_al;
 
+       qp_attr->max_dest_rd_atomic = qpcb->rdma_nr_atomic_resp_res;
+       qp_attr->max_rd_atomic = qpcb->rdma_atomic_outst_dest_qp;
+
        /* primary av */
        qp_attr->ah_attr.sl = qpcb->service_level;
 
@@ -1367,53 +1549,170 @@ query_qp_exit1:
        return ret;
 }
 
-int ehca_destroy_qp(struct ib_qp *ibqp)
+int ehca_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
+                   enum ib_srq_attr_mask attr_mask, struct ib_udata *udata)
 {
-       struct ehca_qp *my_qp = container_of(ibqp, struct ehca_qp, ib_qp);
-       struct ehca_shca *shca = container_of(ibqp->device, struct ehca_shca,
+       struct ehca_qp *my_qp =
+               container_of(ibsrq, struct ehca_qp, ib_srq);
+       struct ehca_pd *my_pd =
+               container_of(ibsrq->pd, struct ehca_pd, ib_pd);
+       struct ehca_shca *shca =
+               container_of(ibsrq->pd->device, struct ehca_shca, ib_device);
+       struct hcp_modify_qp_control_block *mqpcb;
+       u64 update_mask;
+       u64 h_ret;
+       int ret = 0;
+
+       u32 cur_pid = current->tgid;
+       if (my_pd->ib_pd.uobject && my_pd->ib_pd.uobject->context &&
+           my_pd->ownpid != cur_pid) {
+               ehca_err(ibsrq->pd->device, "Invalid caller pid=%x ownpid=%x",
+                        cur_pid, my_pd->ownpid);
+               return -EINVAL;
+       }
+
+       mqpcb = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
+       if (!mqpcb) {
+               ehca_err(ibsrq->device, "Could not get zeroed page for mqpcb "
+                        "ehca_qp=%p qp_num=%x ", my_qp, my_qp->real_qp_num);
+               return -ENOMEM;
+       }
+
+       update_mask = 0;
+       if (attr_mask & IB_SRQ_LIMIT) {
+               attr_mask &= ~IB_SRQ_LIMIT;
+               update_mask |=
+                       EHCA_BMASK_SET(MQPCB_MASK_CURR_SRQ_LIMIT, 1)
+                       | EHCA_BMASK_SET(MQPCB_MASK_QP_AFF_ASYN_EV_LOG_REG, 1);
+               mqpcb->curr_srq_limit =
+                       EHCA_BMASK_SET(MQPCB_CURR_SRQ_LIMIT, attr->srq_limit);
+               mqpcb->qp_aff_asyn_ev_log_reg =
+                       EHCA_BMASK_SET(QPX_AAELOG_RESET_SRQ_LIMIT, 1);
+       }
+
+       /* by now, all bits in attr_mask should have been cleared */
+       if (attr_mask) {
+               ehca_err(ibsrq->device, "invalid attribute mask bits set  "
+                        "attr_mask=%x", attr_mask);
+               ret = -EINVAL;
+               goto modify_srq_exit0;
+       }
+
+       if (ehca_debug_level)
+               ehca_dmp(mqpcb, 4*70, "qp_num=%x", my_qp->real_qp_num);
+
+       h_ret = hipz_h_modify_qp(shca->ipz_hca_handle, my_qp->ipz_qp_handle,
+                                NULL, update_mask, mqpcb,
+                                my_qp->galpas.kernel);
+
+       if (h_ret != H_SUCCESS) {
+               ret = ehca2ib_return_code(h_ret);
+               ehca_err(ibsrq->device, "hipz_h_modify_qp() failed rc=%lx "
+                        "ehca_qp=%p qp_num=%x",
+                        h_ret, my_qp, my_qp->real_qp_num);
+       }
+
+modify_srq_exit0:
+       ehca_free_fw_ctrlblock(mqpcb);
+
+       return ret;
+}
+
+int ehca_query_srq(struct ib_srq *srq, struct ib_srq_attr *srq_attr)
+{
+       struct ehca_qp *my_qp = container_of(srq, struct ehca_qp, ib_srq);
+       struct ehca_pd *my_pd = container_of(srq->pd, struct ehca_pd, ib_pd);
+       struct ehca_shca *shca = container_of(srq->device, struct ehca_shca,
                                              ib_device);
+       struct ipz_adapter_handle adapter_handle = shca->ipz_hca_handle;
+       struct hcp_modify_qp_control_block *qpcb;
+       u32 cur_pid = current->tgid;
+       int ret = 0;
+       u64 h_ret;
+
+       if (my_pd->ib_pd.uobject  && my_pd->ib_pd.uobject->context  &&
+           my_pd->ownpid != cur_pid) {
+               ehca_err(srq->device, "Invalid caller pid=%x ownpid=%x",
+                        cur_pid, my_pd->ownpid);
+               return -EINVAL;
+       }
+
+       qpcb = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
+       if (!qpcb) {
+               ehca_err(srq->device, "Out of memory for qpcb "
+                        "ehca_qp=%p qp_num=%x", my_qp, my_qp->real_qp_num);
+               return -ENOMEM;
+       }
+
+       h_ret = hipz_h_query_qp(adapter_handle, my_qp->ipz_qp_handle,
+                               NULL, qpcb, my_qp->galpas.kernel);
+
+       if (h_ret != H_SUCCESS) {
+               ret = ehca2ib_return_code(h_ret);
+               ehca_err(srq->device, "hipz_h_query_qp() failed "
+                        "ehca_qp=%p qp_num=%x h_ret=%lx",
+                        my_qp, my_qp->real_qp_num, h_ret);
+               goto query_srq_exit1;
+       }
+
+       srq_attr->max_wr = qpcb->max_nr_outst_recv_wr - 1;
+       srq_attr->srq_limit = EHCA_BMASK_GET(
+               MQPCB_CURR_SRQ_LIMIT, qpcb->curr_srq_limit);
+
+       if (ehca_debug_level)
+               ehca_dmp(qpcb, 4*70, "qp_num=%x", my_qp->real_qp_num);
+
+query_srq_exit1:
+       ehca_free_fw_ctrlblock(qpcb);
+
+       return ret;
+}
+
+int internal_destroy_qp(struct ib_device *dev, struct ehca_qp *my_qp,
+                       struct ib_uobject *uobject)
+{
+       struct ehca_shca *shca = container_of(dev, struct ehca_shca, ib_device);
        struct ehca_pd *my_pd = container_of(my_qp->ib_qp.pd, struct ehca_pd,
                                             ib_pd);
        u32 cur_pid = current->tgid;
-       u32 qp_num = ibqp->qp_num;
+       u32 qp_num = my_qp->real_qp_num;
        int ret;
        u64 h_ret;
        u8 port_num;
        enum ib_qp_type qp_type;
        unsigned long flags;
 
-       if (ibqp->uobject) {
+       if (uobject) {
                if (my_qp->mm_count_galpa ||
                    my_qp->mm_count_rqueue || my_qp->mm_count_squeue) {
-                       ehca_err(ibqp->device, "Resources still referenced in "
-                                "user space qp_num=%x", ibqp->qp_num);
+                       ehca_err(dev, "Resources still referenced in "
+                                "user space qp_num=%x", qp_num);
                        return -EINVAL;
                }
                if (my_pd->ownpid != cur_pid) {
-                       ehca_err(ibqp->device, "Invalid caller pid=%x ownpid=%x",
+                       ehca_err(dev, "Invalid caller pid=%x ownpid=%x",
                                 cur_pid, my_pd->ownpid);
                        return -EINVAL;
                }
        }
 
        if (my_qp->send_cq) {
-               ret = ehca_cq_unassign_qp(my_qp->send_cq,
-                                             my_qp->real_qp_num);
+               ret = ehca_cq_unassign_qp(my_qp->send_cq, qp_num);
                if (ret) {
-                       ehca_err(ibqp->device, "Couldn't unassign qp from "
+                       ehca_err(dev, "Couldn't unassign qp from "
                                 "send_cq ret=%x qp_num=%x cq_num=%x", ret,
-                                my_qp->ib_qp.qp_num, my_qp->send_cq->cq_number);
+                                qp_num, my_qp->send_cq->cq_number);
                        return ret;
                }
        }
 
-       spin_lock_irqsave(&ehca_qp_idr_lock, flags);
+       write_lock_irqsave(&ehca_qp_idr_lock, flags);
        idr_remove(&ehca_qp_idr, my_qp->token);
-       spin_unlock_irqrestore(&ehca_qp_idr_lock, flags);
+       write_unlock_irqrestore(&ehca_qp_idr_lock, flags);
 
        h_ret = hipz_h_destroy_qp(shca->ipz_hca_handle, my_qp);
        if (h_ret != H_SUCCESS) {
-               ehca_err(ibqp->device, "hipz_h_destroy_qp() failed rc=%lx "
+               ehca_err(dev, "hipz_h_destroy_qp() failed rc=%lx "
                         "ehca_qp=%p qp_num=%x", h_ret, my_qp, qp_num);
                return ehca2ib_return_code(h_ret);
        }
@@ -1424,7 +1723,7 @@ int ehca_destroy_qp(struct ib_qp *ibqp)
        /* no support for IB_QPT_SMI yet */
        if (qp_type == IB_QPT_GSI) {
                struct ib_event event;
-               ehca_info(ibqp->device, "device %s: port %x is inactive.",
+               ehca_info(dev, "device %s: port %x is inactive.",
                          shca->ib_device.name, port_num);
                event.device = &shca->ib_device;
                event.event = IB_EVENT_PORT_ERR;
@@ -1433,12 +1732,28 @@ int ehca_destroy_qp(struct ib_qp *ibqp)
                ib_dispatch_event(&event);
        }
 
-       ipz_queue_dtor(&my_qp->ipz_rqueue);
-       ipz_queue_dtor(&my_qp->ipz_squeue);
+       if (HAS_RQ(my_qp))
+               ipz_queue_dtor(&my_qp->ipz_rqueue);
+       if (HAS_SQ(my_qp))
+               ipz_queue_dtor(&my_qp->ipz_squeue);
        kmem_cache_free(qp_cache, my_qp);
        return 0;
 }
 
+int ehca_destroy_qp(struct ib_qp *qp)
+{
+       return internal_destroy_qp(qp->device,
+                                  container_of(qp, struct ehca_qp, ib_qp),
+                                  qp->uobject);
+}
+
+int ehca_destroy_srq(struct ib_srq *srq)
+{
+       return internal_destroy_qp(srq->device,
+                                  container_of(srq, struct ehca_qp, ib_srq),
+                                  srq->uobject);
+}
+
 int ehca_init_qp_cache(void)
 {
        qp_cache = kmem_cache_create("ehca_cache_qp",
index caec9dee09e1b0df65a0e03fed29d2e16324d4c3..61da65e6e5e09957868d2097808d77ad809b5baf 100644 (file)
@@ -3,8 +3,9 @@
  *
  *  post_send/recv, poll_cq, req_notify
  *
- *  Authors: Waleri Fomin <fomin@de.ibm.com>
- *           Hoang-Nam Nguyen <hnguyen@de.ibm.com>
+ *  Authors: Hoang-Nam Nguyen <hnguyen@de.ibm.com>
+ *           Waleri Fomin <fomin@de.ibm.com>
+ *           Joachim Fenkes <fenkes@de.ibm.com>
  *           Reinhard Ernst <rernst@de.ibm.com>
  *
  *  Copyright (c) 2005 IBM Corporation
@@ -362,10 +363,10 @@ int ehca_post_send(struct ib_qp *qp,
        struct ehca_wqe *wqe_p;
        int wqe_cnt = 0;
        int ret = 0;
-       unsigned long spl_flags;
+       unsigned long flags;
 
        /* LOCK the QUEUE */
-       spin_lock_irqsave(&my_qp->spinlock_s, spl_flags);
+       spin_lock_irqsave(&my_qp->spinlock_s, flags);
 
        /* loop processes list of send reqs */
        for (cur_send_wr = send_wr; cur_send_wr != NULL;
@@ -406,26 +407,31 @@ int ehca_post_send(struct ib_qp *qp,
        } /* eof for cur_send_wr */
 
 post_send_exit0:
-       /* UNLOCK the QUEUE */
-       spin_unlock_irqrestore(&my_qp->spinlock_s, spl_flags);
        iosync(); /* serialize GAL register access */
        hipz_update_sqa(my_qp, wqe_cnt);
+       spin_unlock_irqrestore(&my_qp->spinlock_s, flags);
        return ret;
 }
 
-int ehca_post_recv(struct ib_qp *qp,
-                  struct ib_recv_wr *recv_wr,
-                  struct ib_recv_wr **bad_recv_wr)
+static int internal_post_recv(struct ehca_qp *my_qp,
+                             struct ib_device *dev,
+                             struct ib_recv_wr *recv_wr,
+                             struct ib_recv_wr **bad_recv_wr)
 {
-       struct ehca_qp *my_qp = container_of(qp, struct ehca_qp, ib_qp);
        struct ib_recv_wr *cur_recv_wr;
        struct ehca_wqe *wqe_p;
        int wqe_cnt = 0;
        int ret = 0;
-       unsigned long spl_flags;
+       unsigned long flags;
+
+       if (unlikely(!HAS_RQ(my_qp))) {
+               ehca_err(dev, "QP has no RQ  ehca_qp=%p qp_num=%x ext_type=%d",
+                        my_qp, my_qp->real_qp_num, my_qp->ext_type);
+               return -ENODEV;
+       }
 
        /* LOCK the QUEUE */
-       spin_lock_irqsave(&my_qp->spinlock_r, spl_flags);
+       spin_lock_irqsave(&my_qp->spinlock_r, flags);
 
        /* loop processes list of send reqs */
        for (cur_recv_wr = recv_wr; cur_recv_wr != NULL;
@@ -439,8 +445,8 @@ int ehca_post_recv(struct ib_qp *qp,
                                *bad_recv_wr = cur_recv_wr;
                        if (wqe_cnt == 0) {
                                ret = -ENOMEM;
-                               ehca_err(qp->device, "Too many posted WQEs "
-                                        "qp_num=%x", qp->qp_num);
+                               ehca_err(dev, "Too many posted WQEs "
+                                        "qp_num=%x", my_qp->real_qp_num);
                        }
                        goto post_recv_exit0;
                }
@@ -455,23 +461,39 @@ int ehca_post_recv(struct ib_qp *qp,
                        *bad_recv_wr = cur_recv_wr;
                        if (wqe_cnt == 0) {
                                ret = -EINVAL;
-                               ehca_err(qp->device, "Could not write WQE "
-                                        "qp_num=%x", qp->qp_num);
+                               ehca_err(dev, "Could not write WQE "
+                                        "qp_num=%x", my_qp->real_qp_num);
                        }
                        goto post_recv_exit0;
                }
                wqe_cnt++;
-               ehca_gen_dbg("ehca_qp=%p qp_num=%x wqe_cnt=%d",
-                    my_qp, qp->qp_num, wqe_cnt);
+               ehca_dbg(dev, "ehca_qp=%p qp_num=%x wqe_cnt=%d",
+                        my_qp, my_qp->real_qp_num, wqe_cnt);
        } /* eof for cur_recv_wr */
 
 post_recv_exit0:
-       spin_unlock_irqrestore(&my_qp->spinlock_r, spl_flags);
        iosync(); /* serialize GAL register access */
        hipz_update_rqa(my_qp, wqe_cnt);
+       spin_unlock_irqrestore(&my_qp->spinlock_r, flags);
        return ret;
 }
 
+int ehca_post_recv(struct ib_qp *qp,
+                  struct ib_recv_wr *recv_wr,
+                  struct ib_recv_wr **bad_recv_wr)
+{
+       return internal_post_recv(container_of(qp, struct ehca_qp, ib_qp),
+                                 qp->device, recv_wr, bad_recv_wr);
+}
+
+int ehca_post_srq_recv(struct ib_srq *srq,
+                      struct ib_recv_wr *recv_wr,
+                      struct ib_recv_wr **bad_recv_wr)
+{
+       return internal_post_recv(container_of(srq, struct ehca_qp, ib_srq),
+                                 srq->device, recv_wr, bad_recv_wr);
+}
+
 /*
  * ib_wc_opcode table converts ehca wc opcode to ib
  * Since we use zero to indicate invalid opcode, the actual ib opcode must
@@ -494,6 +516,7 @@ static inline int ehca_poll_cq_one(struct ib_cq *cq, struct ib_wc *wc)
        int ret = 0;
        struct ehca_cq *my_cq = container_of(cq, struct ehca_cq, ib_cq);
        struct ehca_cqe *cqe;
+       struct ehca_qp *my_qp;
        int cqe_count = 0;
 
 poll_cq_one_read_cqe:
@@ -513,7 +536,7 @@ poll_cq_one_read_cqe:
        if (unlikely(cqe->status & WC_STATUS_PURGE_BIT)) {
                struct ehca_qp *qp=ehca_cq_get_qp(my_cq, cqe->local_qp_number);
                int purgeflag;
-               unsigned long spl_flags;
+               unsigned long flags;
                if (!qp) {
                        ehca_err(cq->device, "cq_num=%x qp_num=%x "
                                 "could not find qp -> ignore cqe",
@@ -523,9 +546,9 @@ poll_cq_one_read_cqe:
                        /* ignore this purged cqe */
                        goto poll_cq_one_read_cqe;
                }
-               spin_lock_irqsave(&qp->spinlock_s, spl_flags);
+               spin_lock_irqsave(&qp->spinlock_s, flags);
                purgeflag = qp->sqerr_purgeflag;
-               spin_unlock_irqrestore(&qp->spinlock_s, spl_flags);
+               spin_unlock_irqrestore(&qp->spinlock_s, flags);
 
                if (purgeflag) {
                        ehca_dbg(cq->device, "Got CQE with purged bit qp_num=%x "
@@ -545,7 +568,7 @@ poll_cq_one_read_cqe:
        }
 
        /* tracing cqe */
-       if (ehca_debug_level) {
+       if (unlikely(ehca_debug_level)) {
                ehca_dbg(cq->device,
                         "Received COMPLETION ehca_cq=%p cq_num=%x -----",
                         my_cq, my_cq->cq_number);
@@ -579,7 +602,11 @@ poll_cq_one_read_cqe:
        } else
                wc->status = IB_WC_SUCCESS;
 
-       wc->qp = NULL;
+       read_lock(&ehca_qp_idr_lock);
+       my_qp = idr_find(&ehca_qp_idr, cqe->qp_token);
+       wc->qp = &my_qp->ib_qp;
+       read_unlock(&ehca_qp_idr_lock);
+
        wc->byte_len = cqe->nr_bytes_transferred;
        wc->pkey_index = cqe->pkey_index;
        wc->slid = cqe->rlid;
@@ -589,7 +616,7 @@ poll_cq_one_read_cqe:
        wc->imm_data = cpu_to_be32(cqe->immediate_data);
        wc->sl = cqe->service_level;
 
-       if (wc->status != IB_WC_SUCCESS)
+       if (unlikely(wc->status != IB_WC_SUCCESS))
                ehca_dbg(cq->device,
                         "ehca_cq=%p cq_num=%x WARNING unsuccessful cqe "
                         "OPType=%x status=%x qp_num=%x src_qp=%x wr_id=%lx "
@@ -610,7 +637,7 @@ int ehca_poll_cq(struct ib_cq *cq, int num_entries, struct ib_wc *wc)
        int nr;
        struct ib_wc *current_wc = wc;
        int ret = 0;
-       unsigned long spl_flags;
+       unsigned long flags;
 
        if (num_entries < 1) {
                ehca_err(cq->device, "Invalid num_entries=%d ehca_cq=%p "
@@ -619,14 +646,14 @@ int ehca_poll_cq(struct ib_cq *cq, int num_entries, struct ib_wc *wc)
                goto poll_cq_exit0;
        }
 
-       spin_lock_irqsave(&my_cq->spinlock, spl_flags);
+       spin_lock_irqsave(&my_cq->spinlock, flags);
        for (nr = 0; nr < num_entries; nr++) {
                ret = ehca_poll_cq_one(cq, current_wc);
                if (ret)
                        break;
                current_wc++;
        } /* eof for nr */
-       spin_unlock_irqrestore(&my_cq->spinlock, spl_flags);
+       spin_unlock_irqrestore(&my_cq->spinlock, flags);
        if (ret == -EAGAIN  || !ret)
                ret = nr;
 
@@ -637,7 +664,6 @@ poll_cq_exit0:
 int ehca_req_notify_cq(struct ib_cq *cq, enum ib_cq_notify_flags notify_flags)
 {
        struct ehca_cq *my_cq = container_of(cq, struct ehca_cq, ib_cq);
-       unsigned long spl_flags;
        int ret = 0;
 
        switch (notify_flags & IB_CQ_SOLICITED_MASK) {
@@ -652,6 +678,7 @@ int ehca_req_notify_cq(struct ib_cq *cq, enum ib_cq_notify_flags notify_flags)
        }
 
        if (notify_flags & IB_CQ_REPORT_MISSED_EVENTS) {
+               unsigned long spl_flags;
                spin_lock_irqsave(&my_cq->spinlock, spl_flags);
                ret = ipz_qeit_is_valid(&my_cq->ipz_queue);
                spin_unlock_irqrestore(&my_cq->spinlock, spl_flags);
index 973c4b59154575fa9a0dad89864051183d848bc8..03b185f873dafb8c8641358efef02f9f1633dd0f 100644 (file)
@@ -59,6 +59,7 @@
 #include <linux/cpu.h>
 #include <linux/device.h>
 
+#include <asm/atomic.h>
 #include <asm/abs_addr.h>
 #include <asm/ibmebus.h>
 #include <asm/io.h>
index 73db920b6945e7b255f3ac2ac996ab87b42aa2de..3031b3bb56f9bc6b7ad3eb24d58d2b6d21f138ac 100644 (file)
@@ -253,16 +253,16 @@ int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
        u32 rsrc_type = (fileoffset >> 24) & 0xF; /* sq,rq,cmnd_window */
        u32 cur_pid = current->tgid;
        u32 ret;
-       unsigned long flags;
        struct ehca_cq *cq;
        struct ehca_qp *qp;
        struct ehca_pd *pd;
+       struct ib_uobject *uobject;
 
        switch (q_type) {
        case  1: /* CQ */
-               spin_lock_irqsave(&ehca_cq_idr_lock, flags);
+               read_lock(&ehca_cq_idr_lock);
                cq = idr_find(&ehca_cq_idr, idr_handle);
-               spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
+               read_unlock(&ehca_cq_idr_lock);
 
                /* make sure this mmap really belongs to the authorized user */
                if (!cq)
@@ -288,9 +288,9 @@ int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
                break;
 
        case 2: /* QP */
-               spin_lock_irqsave(&ehca_qp_idr_lock, flags);
+               read_lock(&ehca_qp_idr_lock);
                qp = idr_find(&ehca_qp_idr, idr_handle);
-               spin_unlock_irqrestore(&ehca_qp_idr_lock, flags);
+               read_unlock(&ehca_qp_idr_lock);
 
                /* make sure this mmap really belongs to the authorized user */
                if (!qp)
@@ -304,7 +304,8 @@ int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
                        return -ENOMEM;
                }
 
-               if (!qp->ib_qp.uobject || qp->ib_qp.uobject->context != context)
+               uobject = IS_SRQ(qp) ? qp->ib_srq.uobject : qp->ib_qp.uobject;
+               if (!uobject || uobject->context != context)
                        return -EINVAL;
 
                ret = ehca_mmap_qp(vma, qp, rsrc_type);
index 5766ae3a202995bebb306f4aae1f4580a888109a..4776a8b0feec4f02bbf6f90e8de04f79e0e9dbda 100644 (file)
@@ -5,6 +5,7 @@
  *
  *  Authors: Christoph Raisch <raisch@de.ibm.com>
  *           Hoang-Nam Nguyen <hnguyen@de.ibm.com>
+ *           Joachim Fenkes <fenkes@de.ibm.com>
  *           Gerd Bayer <gerd.bayer@de.ibm.com>
  *           Waleri Fomin <fomin@de.ibm.com>
  *
 #define H_ALL_RES_QP_MAX_SEND_SGE       EHCA_BMASK_IBM(32, 39)
 #define H_ALL_RES_QP_MAX_RECV_SGE       EHCA_BMASK_IBM(40, 47)
 
+#define H_ALL_RES_QP_UD_AV_LKEY         EHCA_BMASK_IBM(32, 63)
+#define H_ALL_RES_QP_SRQ_QP_TOKEN       EHCA_BMASK_IBM(0, 31)
+#define H_ALL_RES_QP_SRQ_QP_HANDLE      EHCA_BMASK_IBM(0, 64)
+#define H_ALL_RES_QP_SRQ_LIMIT          EHCA_BMASK_IBM(48, 63)
+#define H_ALL_RES_QP_SRQ_QPN            EHCA_BMASK_IBM(40, 63)
+
 #define H_ALL_RES_QP_ACT_OUTST_SEND_WR  EHCA_BMASK_IBM(16, 31)
 #define H_ALL_RES_QP_ACT_OUTST_RECV_WR  EHCA_BMASK_IBM(48, 63)
 #define H_ALL_RES_QP_ACT_SEND_SGE       EHCA_BMASK_IBM(8, 15)
 #define H_MP_SHUTDOWN                   EHCA_BMASK_IBM(48, 48)
 #define H_MP_RESET_QKEY_CTR             EHCA_BMASK_IBM(49, 49)
 
-/* direct access qp controls */
-#define DAQP_CTRL_ENABLE    0x01
-#define DAQP_CTRL_SEND_COMP 0x20
-#define DAQP_CTRL_RECV_COMP 0x40
+static DEFINE_SPINLOCK(hcall_lock);
 
 static u32 get_longbusy_msecs(int longbusy_rc)
 {
@@ -155,7 +159,7 @@ static long ehca_plpar_hcall9(unsigned long opcode,
 {
        long ret;
        int i, sleep_msecs, lock_is_set = 0;
-       unsigned long flags;
+       unsigned long flags = 0;
 
        ehca_gen_dbg("opcode=%lx arg1=%lx arg2=%lx arg3=%lx arg4=%lx "
                     "arg5=%lx arg6=%lx arg7=%lx arg8=%lx arg9=%lx",
@@ -284,53 +288,53 @@ u64 hipz_h_alloc_resource_cq(const struct ipz_adapter_handle adapter_handle,
 }
 
 u64 hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle,
-                            struct ehca_qp *qp,
                             struct ehca_alloc_qp_parms *parms)
 {
        u64 ret;
-       u64 allocate_controls;
-       u64 max_r10_reg;
+       u64 allocate_controls, max_r10_reg, r11, r12;
        u64 outs[PLPAR_HCALL9_BUFSIZE];
-       u16 max_nr_receive_wqes = qp->init_attr.cap.max_recv_wr + 1;
-       u16 max_nr_send_wqes = qp->init_attr.cap.max_send_wr + 1;
-       int daqp_ctrl = parms->daqp_ctrl;
 
        allocate_controls =
-               EHCA_BMASK_SET(H_ALL_RES_QP_ENHANCED_OPS,
-                              (daqp_ctrl & DAQP_CTRL_ENABLE) ? 1 : 0)
+               EHCA_BMASK_SET(H_ALL_RES_QP_ENHANCED_OPS, parms->ext_type)
                | EHCA_BMASK_SET(H_ALL_RES_QP_PTE_PIN, 0)
                | EHCA_BMASK_SET(H_ALL_RES_QP_SERVICE_TYPE, parms->servicetype)
                | EHCA_BMASK_SET(H_ALL_RES_QP_SIGNALING_TYPE, parms->sigtype)
                | EHCA_BMASK_SET(H_ALL_RES_QP_LL_RQ_CQE_POSTING,
-                                (daqp_ctrl & DAQP_CTRL_RECV_COMP) ? 1 : 0)
+                                !!(parms->ll_comp_flags & LLQP_RECV_COMP))
                | EHCA_BMASK_SET(H_ALL_RES_QP_LL_SQ_CQE_POSTING,
-                                (daqp_ctrl & DAQP_CTRL_SEND_COMP) ? 1 : 0)
+                                !!(parms->ll_comp_flags & LLQP_SEND_COMP))
                | EHCA_BMASK_SET(H_ALL_RES_QP_UD_AV_LKEY_CTRL,
                                 parms->ud_av_l_key_ctl)
                | EHCA_BMASK_SET(H_ALL_RES_QP_RESOURCE_TYPE, 1);
 
        max_r10_reg =
                EHCA_BMASK_SET(H_ALL_RES_QP_MAX_OUTST_SEND_WR,
-                              max_nr_send_wqes)
+                              parms->max_send_wr + 1)
                | EHCA_BMASK_SET(H_ALL_RES_QP_MAX_OUTST_RECV_WR,
-                                max_nr_receive_wqes)
+                                parms->max_recv_wr + 1)
                | EHCA_BMASK_SET(H_ALL_RES_QP_MAX_SEND_SGE,
                                 parms->max_send_sge)
                | EHCA_BMASK_SET(H_ALL_RES_QP_MAX_RECV_SGE,
                                 parms->max_recv_sge);
 
+       r11 = EHCA_BMASK_SET(H_ALL_RES_QP_SRQ_QP_TOKEN, parms->srq_token);
+
+       if (parms->ext_type == EQPT_SRQ)
+               r12 = EHCA_BMASK_SET(H_ALL_RES_QP_SRQ_LIMIT, parms->srq_limit);
+       else
+               r12 = EHCA_BMASK_SET(H_ALL_RES_QP_SRQ_QPN, parms->srq_qpn);
+
        ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
                                adapter_handle.handle,             /* r4  */
                                allocate_controls,                 /* r5  */
-                               qp->send_cq->ipz_cq_handle.handle,
-                               qp->recv_cq->ipz_cq_handle.handle,
-                               parms->ipz_eq_handle.handle,
-                               ((u64)qp->token << 32) | parms->pd.value,
-                               max_r10_reg,                       /* r10 */
-                               parms->ud_av_l_key_ctl,            /* r11 */
-                               0);
-       qp->ipz_qp_handle.handle = outs[0];
-       qp->real_qp_num = (u32)outs[1];
+                               parms->send_cq_handle.handle,
+                               parms->recv_cq_handle.handle,
+                               parms->eq_handle.handle,
+                               ((u64)parms->token << 32) | parms->pd.value,
+                               max_r10_reg, r11, r12);
+
+       parms->qp_handle.handle = outs[0];
+       parms->real_qp_num = (u32)outs[1];
        parms->act_nr_send_wqes =
                (u16)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_OUTST_SEND_WR, outs[2]);
        parms->act_nr_recv_wqes =
@@ -345,7 +349,7 @@ u64 hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle,
                (u32)EHCA_BMASK_GET(H_ALL_RES_QP_RQUEUE_SIZE_PAGES, outs[4]);
 
        if (ret == H_SUCCESS)
-               hcp_galpas_ctor(&qp->galpas, outs[6], outs[6]);
+               hcp_galpas_ctor(&parms->galpas, outs[6], outs[6]);
 
        if (ret == H_NOT_ENOUGH_RESOURCES)
                ehca_gen_err("Not enough resources. ret=%lx", ret);
index 2869f7dd61969415c1383cb357cdc7baeb4b4fde..60ce02b7066389e657c1ff7a33a9b8ee87b8120d 100644 (file)
@@ -78,7 +78,6 @@ u64 hipz_h_alloc_resource_cq(const struct ipz_adapter_handle adapter_handle,
  * initialize resources, create empty QPPTs (2 rings).
  */
 u64 hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle,
-                            struct ehca_qp *qp,
                             struct ehca_alloc_qp_parms *parms);
 
 u64 hipz_h_query_port(const struct ipz_adapter_handle adapter_handle,
index fad91368dc5a7893237c3acebbf5eefa443aad28..dad6dea5636b55e1883eca6ac59e6f9248aafbd7 100644 (file)
@@ -163,6 +163,7 @@ struct hipz_qptemm {
 
 #define QPX_SQADDER EHCA_BMASK_IBM(48,63)
 #define QPX_RQADDER EHCA_BMASK_IBM(48,63)
+#define QPX_AAELOG_RESET_SRQ_LIMIT EHCA_BMASK_IBM(3,3)
 
 #define QPTEMM_OFFSET(x) offsetof(struct hipz_qptemm,x)
 
@@ -360,6 +361,24 @@ struct hipz_query_hca {
        u32 max_neq;
 } __attribute__ ((packed));
 
+#define HCA_CAP_AH_PORT_NR_CHECK      EHCA_BMASK_IBM( 0,  0)
+#define HCA_CAP_ATOMIC                EHCA_BMASK_IBM( 1,  1)
+#define HCA_CAP_AUTO_PATH_MIG         EHCA_BMASK_IBM( 2,  2)
+#define HCA_CAP_BAD_P_KEY_CTR         EHCA_BMASK_IBM( 3,  3)
+#define HCA_CAP_SQD_RTS_PORT_CHANGE   EHCA_BMASK_IBM( 4,  4)
+#define HCA_CAP_CUR_QP_STATE_MOD      EHCA_BMASK_IBM( 5,  5)
+#define HCA_CAP_INIT_TYPE             EHCA_BMASK_IBM( 6,  6)
+#define HCA_CAP_PORT_ACTIVE_EVENT     EHCA_BMASK_IBM( 7,  7)
+#define HCA_CAP_Q_KEY_VIOL_CTR        EHCA_BMASK_IBM( 8,  8)
+#define HCA_CAP_WQE_RESIZE            EHCA_BMASK_IBM( 9,  9)
+#define HCA_CAP_RAW_PACKET_MCAST      EHCA_BMASK_IBM(10, 10)
+#define HCA_CAP_SHUTDOWN_PORT         EHCA_BMASK_IBM(11, 11)
+#define HCA_CAP_RC_LL_QP              EHCA_BMASK_IBM(12, 12)
+#define HCA_CAP_SRQ                   EHCA_BMASK_IBM(13, 13)
+#define HCA_CAP_UD_LL_QP              EHCA_BMASK_IBM(16, 16)
+#define HCA_CAP_RESIZE_MR             EHCA_BMASK_IBM(17, 17)
+#define HCA_CAP_MINI_QP               EHCA_BMASK_IBM(18, 18)
+
 /* query port response block */
 struct hipz_query_port {
        u32 state;
index 57f141a36bceb2c6a5579ab4548f9d2c1cae3b2e..007f0882fd403a20805c988b2dd98e3ba0db1d07 100644 (file)
@@ -105,7 +105,6 @@ void *ipz_qpageit_get_inc(struct ipz_queue *queue);
  * step in struct ipz_queue, will wrap in ringbuffer
  * returns address (kv) of Queue Entry BEFORE increment
  * warning don't use in parallel with ipz_qpageit_get_inc()
- * warning unpredictable results may occur if steps>act_nr_of_queue_entries
  */
 static inline void *ipz_qeit_get_inc(struct ipz_queue *queue)
 {
@@ -120,32 +119,25 @@ static inline void *ipz_qeit_get_inc(struct ipz_queue *queue)
        return ret;
 }
 
+/*
+ * return a bool indicating whether current Queue Entry is valid
+ */
+static inline int ipz_qeit_is_valid(struct ipz_queue *queue)
+{
+       struct ehca_cqe *cqe = ipz_qeit_get(queue);
+       return ((cqe->cqe_flags >> 7) == (queue->toggle_state & 1));
+}
+
 /*
  * return current Queue Entry, increment Queue Entry iterator by one
  * step in struct ipz_queue, will wrap in ringbuffer
  * returns address (kv) of Queue Entry BEFORE increment
  * returns 0 and does not increment, if wrong valid state
  * warning don't use in parallel with ipz_qpageit_get_inc()
- * warning unpredictable results may occur if steps>act_nr_of_queue_entries
  */
 static inline void *ipz_qeit_get_inc_valid(struct ipz_queue *queue)
 {
-       struct ehca_cqe *cqe = ipz_qeit_get(queue);
-       u32 cqe_flags = cqe->cqe_flags;
-
-       if ((cqe_flags >> 7) != (queue->toggle_state & 1))
-               return NULL;
-
-       ipz_qeit_get_inc(queue);
-       return cqe;
-}
-
-static inline int ipz_qeit_is_valid(struct ipz_queue *queue)
-{
-       struct ehca_cqe *cqe = ipz_qeit_get(queue);
-       u32 cqe_flags = cqe->cqe_flags;
-
-       return cqe_flags >> 7 == (queue->toggle_state & 1);
+       return ipz_qeit_is_valid(queue) ? ipz_qeit_get_inc(queue) : NULL;
 }
 
 /*
index 90c14543677de94c1f1a74464d4bbe27ae6ef9cf..044da5828a787537b9744cf6401a06e48c4c00d2 100644 (file)
@@ -1,6 +1,6 @@
 config INFINIBAND_IPATH
        tristate "QLogic InfiniPath Driver"
-       depends on (PCI_MSI || HT_IRQ) && 64BIT && INFINIBAND && NET
+       depends on (PCI_MSI || HT_IRQ) && 64BIT && NET
        ---help---
        This is a driver for QLogic InfiniPath host channel adapters,
        including InfiniBand verbs support.  This driver allows these
index 10c008f22ba6947b9a5cf9c9d75f5cb976651452..b4b786d0dfcaaafff0af2bc45465c6b32984f3a7 100644 (file)
@@ -189,8 +189,7 @@ typedef enum _ipath_ureg {
 #define IPATH_RUNTIME_FORCE_WC_ORDER   0x4
 #define IPATH_RUNTIME_RCVHDR_COPY      0x8
 #define IPATH_RUNTIME_MASTER   0x10
-#define IPATH_RUNTIME_PBC_REWRITE 0x20
-#define IPATH_RUNTIME_LOOSE_DMA_ALIGN 0x40
+/* 0x20 and 0x40 are no longer used, but are reserved for ABI compatibility */
 
 /*
  * This structure is returned by ipath_userinit() immediately after
@@ -432,8 +431,15 @@ struct ipath_user_info {
 #define IPATH_CMD_UNUSED_1     25
 #define IPATH_CMD_UNUSED_2     26
 #define IPATH_CMD_PIOAVAILUPD  27      /* force an update of PIOAvail reg */
+#define IPATH_CMD_POLL_TYPE    28      /* set the kind of polling we want */
 
-#define IPATH_CMD_MAX          27
+#define IPATH_CMD_MAX          28
+
+/*
+ * Poll types
+ */
+#define IPATH_POLL_TYPE_URGENT  0x01
+#define IPATH_POLL_TYPE_OVERFLOW 0x02
 
 struct ipath_port_info {
        __u32 num_active;       /* number of active units */
@@ -474,6 +480,8 @@ struct ipath_cmd {
                __u16 part_key;
                /* user address of __u32 bitmask of active slaves */
                __u64 slave_mask_addr;
+               /* type of polling we want */
+               __u16 poll_type;
        } cmd;
 };
 
@@ -502,13 +510,30 @@ struct __ipath_sendpkt {
        struct ipath_iovec sps_iov[4];
 };
 
-/* Passed into diag data special file's ->write method. */
+/*
+ * diagnostics can send a packet by "writing" one of the following
+ * two structs to diag data special file
+ * The first is the legacy version for backward compatibility
+ */
 struct ipath_diag_pkt {
        __u32 unit;
        __u64 data;
        __u32 len;
 };
 
+/* The second diag_pkt struct is the expanded version that allows
+ * more control over the packet, specifically, by allowing a custom
+ * pbc (+ extra) qword, so that special modes and deliberate
+ * changes to CRCs can be used. The elements were also re-ordered
+ * for better alignment and to avoid padding issues.
+ */
+struct ipath_diag_xpkt {
+       __u64 data;
+       __u64 pbc_wd;
+       __u32 unit;
+       __u32 len;
+};
+
 /*
  * Data layout in I2C flash (for GUID, etc.)
  * All fields are little-endian binary unless otherwise stated
index 3e9241badba059859fe500cd53661c9ce3dbf693..a6f04d27ec576c021061df4d13d8f18e3fde61e1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 QLogic, Inc. All rights reserved.
+ * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
  * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -90,6 +90,8 @@ void ipath_cq_enter(struct ipath_cq *cq, struct ib_wc *entry, int solicited)
        wc->queue[head].sl = entry->sl;
        wc->queue[head].dlid_path_bits = entry->dlid_path_bits;
        wc->queue[head].port_num = entry->port_num;
+       /* Make sure queue entry is written before the head index. */
+       smp_wmb();
        wc->head = next;
 
        if (cq->notify == IB_CQ_NEXT_COMP ||
@@ -139,7 +141,8 @@ int ipath_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry)
 
                if (tail == wc->head)
                        break;
-
+               /* Make sure entry is read after head index is read. */
+               smp_rmb();
                qp = ipath_lookup_qpn(&to_idev(cq->ibcq.device)->qp_table,
                                      wc->queue[tail].qp_num);
                entry->qp = &qp->ibqp;
index 42bfbdb0d3e6af48abb11e411248afde6f850570..19c56e6491eb0c65183a7ff1a344cf5f4447d0e7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 QLogic, Inc. All rights reserved.
+ * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
  * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
index 63e8368b0e95260011a0ad8733624ce064d54f0a..a698f1949d1040da508c1c727acca8bf6bb24dbb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 QLogic, Inc. All rights reserved.
+ * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
  * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -323,13 +323,14 @@ static ssize_t ipath_diagpkt_write(struct file *fp,
 {
        u32 __iomem *piobuf;
        u32 plen, clen, pbufn;
-       struct ipath_diag_pkt dp;
+       struct ipath_diag_pkt odp;
+       struct ipath_diag_xpkt dp;
        u32 *tmpbuf = NULL;
        struct ipath_devdata *dd;
        ssize_t ret = 0;
        u64 val;
 
-       if (count < sizeof(dp)) {
+       if (count != sizeof(dp)) {
                ret = -EINVAL;
                goto bail;
        }
@@ -339,6 +340,29 @@ static ssize_t ipath_diagpkt_write(struct file *fp,
                goto bail;
        }
 
+       /*
+        * Due to padding/alignment issues (lessened with new struct)
+        * the old and new structs are the same length. We need to
+        * disambiguate them, which we can do because odp.len has never
+        * been less than the total of LRH+BTH+DETH so far, while
+        * dp.unit (same offset) unit is unlikely to get that high.
+        * Similarly, dp.data, the pointer to user at the same offset
+        * as odp.unit, is almost certainly at least one (512byte)page
+        * "above" NULL. The if-block below can be omitted if compatibility
+        * between a new driver and older diagnostic code is unimportant.
+        * compatibility the other direction (new diags, old driver) is
+        * handled in the diagnostic code, with a warning.
+        */
+       if (dp.unit >= 20 && dp.data < 512) {
+               /* very probable version mismatch. Fix it up */
+               memcpy(&odp, &dp, sizeof(odp));
+               /* We got a legacy dp, copy elements to dp */
+               dp.unit = odp.unit;
+               dp.data = odp.data;
+               dp.len = odp.len;
+               dp.pbc_wd = 0; /* Indicate we need to compute PBC wd */
+       }
+
        /* send count must be an exact number of dwords */
        if (dp.len & 3) {
                ret = -EINVAL;
@@ -371,9 +395,10 @@ static ssize_t ipath_diagpkt_write(struct file *fp,
                ret = -ENODEV;
                goto bail;
        }
+       /* Check link state, but not if we have custom PBC */
        val = dd->ipath_lastibcstat & IPATH_IBSTATE_MASK;
-       if (val != IPATH_IBSTATE_INIT && val != IPATH_IBSTATE_ARM &&
-           val != IPATH_IBSTATE_ACTIVE) {
+       if (!dp.pbc_wd && val != IPATH_IBSTATE_INIT &&
+               val != IPATH_IBSTATE_ARM && val != IPATH_IBSTATE_ACTIVE) {
                ipath_cdbg(VERBOSE, "unit %u not ready (state %llx)\n",
                           dd->ipath_unit, (unsigned long long) val);
                ret = -EINVAL;
@@ -419,9 +444,13 @@ static ssize_t ipath_diagpkt_write(struct file *fp,
                ipath_cdbg(VERBOSE, "unit %u 0x%x+1w pio%d\n",
                           dd->ipath_unit, plen - 1, pbufn);
 
+       if (dp.pbc_wd == 0)
+               /* Legacy operation, use computed pbc_wd */
+               dp.pbc_wd = plen;
+
        /* we have to flush after the PBC for correctness on some cpus
         * or WC buffer can be written out of order */
-       writeq(plen, piobuf);
+       writeq(dp.pbc_wd, piobuf);
        ipath_flush_wc();
        /* copy all by the trigger word, then flush, so it's written
         * to chip before trigger word, then write trigger word, then
index e3a223209710bd7fa81a13798d18a8cb253f80be..9361f5ab8bd637f32dc6171ef0f5281f20b8c060 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 QLogic, Inc. All rights reserved.
+ * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
  * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -104,6 +104,9 @@ static int __devinit ipath_init_one(struct pci_dev *,
 #define PCI_DEVICE_ID_INFINIPATH_HT 0xd
 #define PCI_DEVICE_ID_INFINIPATH_PE800 0x10
 
+/* Number of seconds before our card status check...  */
+#define STATUS_TIMEOUT 60
+
 static const struct pci_device_id ipath_pci_tbl[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_PATHSCALE, PCI_DEVICE_ID_INFINIPATH_HT) },
        { PCI_DEVICE(PCI_VENDOR_ID_PATHSCALE, PCI_DEVICE_ID_INFINIPATH_PE800) },
@@ -119,6 +122,18 @@ static struct pci_driver ipath_driver = {
        .id_table = ipath_pci_tbl,
 };
 
+static void ipath_check_status(struct work_struct *work)
+{
+       struct ipath_devdata *dd = container_of(work, struct ipath_devdata,
+                                               status_work.work);
+
+       /*
+        * If we don't have any interrupts, let the user know and
+        * don't bother checking again.
+        */
+       if (dd->ipath_int_counter == 0)
+               dev_err(&dd->pcidev->dev, "No interrupts detected.\n");
+}
 
 static inline void read_bars(struct ipath_devdata *dd, struct pci_dev *dev,
                             u32 *bar0, u32 *bar1)
@@ -187,6 +202,8 @@ static struct ipath_devdata *ipath_alloc_devdata(struct pci_dev *pdev)
        dd->pcidev = pdev;
        pci_set_drvdata(pdev, dd);
 
+       INIT_DELAYED_WORK(&dd->status_work, ipath_check_status);
+
        list_add(&dd->ipath_list, &ipath_dev_list);
 
 bail_unlock:
@@ -270,7 +287,6 @@ static int __devinit ipath_init_one(struct pci_dev *pdev,
        struct ipath_devdata *dd;
        unsigned long long addr;
        u32 bar0 = 0, bar1 = 0;
-       u8 rev;
 
        dd = ipath_alloc_devdata(pdev);
        if (IS_ERR(dd)) {
@@ -432,13 +448,7 @@ static int __devinit ipath_init_one(struct pci_dev *pdev,
        dd->ipath_deviceid = ent->device;       /* save for later use */
        dd->ipath_vendorid = ent->vendor;
 
-       ret = pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
-       if (ret) {
-               ipath_dev_err(dd, "Failed to read PCI revision ID unit "
-                             "%u: err %d\n", dd->ipath_unit, -ret);
-               goto bail_regions;      /* shouldn't ever happen */
-       }
-       dd->ipath_pcirev = rev;
+       dd->ipath_pcirev = pdev->revision;
 
 #if defined(__powerpc__)
        /* There isn't a generic way to specify writethrough mappings */
@@ -511,6 +521,9 @@ static int __devinit ipath_init_one(struct pci_dev *pdev,
        ipath_diag_add(dd);
        ipath_register_ib_device(dd);
 
+       /* Check that card status in STATUS_TIMEOUT seconds. */
+       schedule_delayed_work(&dd->status_work, HZ * STATUS_TIMEOUT);
+
        goto bail;
 
 bail_irqsetup:
@@ -638,6 +651,9 @@ static void __devexit ipath_remove_one(struct pci_dev *pdev)
         */
        ipath_shutdown_device(dd);
 
+       cancel_delayed_work(&dd->status_work);
+       flush_scheduled_work();
+
        if (dd->verbs_dev)
                ipath_unregister_ib_device(dd->verbs_dev);
 
@@ -706,9 +722,9 @@ void ipath_disarm_piobufs(struct ipath_devdata *dd, unsigned first,
        u64 sendctrl, sendorig;
 
        ipath_cdbg(PKT, "disarm %u PIObufs first=%u\n", cnt, first);
-       sendorig = dd->ipath_sendctrl | INFINIPATH_S_DISARM;
+       sendorig = dd->ipath_sendctrl;
        for (i = first; i < last; i++) {
-               sendctrl = sendorig |
+               sendctrl = sendorig  | INFINIPATH_S_DISARM |
                        (i << INFINIPATH_S_DISARMPIOBUF_SHIFT);
                ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
                                 sendctrl);
@@ -719,12 +735,12 @@ void ipath_disarm_piobufs(struct ipath_devdata *dd, unsigned first,
         * while we were looping; no critical bits that would require
         * locking.
         *
-        * Write a 0, and then the original value, reading scratch in
+        * disable PIOAVAILUPD, then re-enable, reading scratch in
         * between.  This seems to avoid a chip timing race that causes
         * pioavail updates to memory to stop.
         */
        ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
-                        0);
+                        sendorig & ~IPATH_S_PIOBUFAVAILUPD);
        sendorig = ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
        ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
                         dd->ipath_sendctrl);
@@ -1021,14 +1037,10 @@ void ipath_kreceive(struct ipath_devdata *dd)
                goto bail;
        }
 
-       /* There is already a thread processing this queue. */
-       if (test_and_set_bit(0, &dd->ipath_rcv_pending))
-               goto bail;
-
        l = dd->ipath_port0head;
        hdrqtail = (u32) le64_to_cpu(*dd->ipath_hdrqtailptr);
        if (l == hdrqtail)
-               goto done;
+               goto bail;
 
 reloop:
        for (i = 0; l != hdrqtail; i++) {
@@ -1163,10 +1175,6 @@ reloop:
        ipath_stats.sps_avgpkts_call =
                ipath_stats.sps_port0pkts / ++totcalls;
 
-done:
-       clear_bit(0, &dd->ipath_rcv_pending);
-       smp_mb__after_clear_bit();
-
 bail:;
 }
 
@@ -1596,6 +1604,35 @@ int ipath_waitfor_mdio_cmdready(struct ipath_devdata *dd)
        return ret;
 }
 
+
+/*
+ * Flush all sends that might be in the ready to send state, as well as any
+ * that are in the process of being sent.   Used whenever we need to be
+ * sure the send side is idle.  Cleans up all buffer state by canceling
+ * all pio buffers, and issuing an abort, which cleans up anything in the
+ * launch fifo.  The cancel is superfluous on some chip versions, but
+ * it's safer to always do it.
+ * PIOAvail bits are updated by the chip as if normal send had happened.
+ */
+void ipath_cancel_sends(struct ipath_devdata *dd)
+{
+       ipath_dbg("Cancelling all in-progress send buffers\n");
+       dd->ipath_lastcancel = jiffies+HZ/2; /* skip armlaunch errs a bit */
+       /*
+        * the abort bit is auto-clearing.  We read scratch to be sure
+        * that cancels and the abort have taken effect in the chip.
+        */
+       ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
+               INFINIPATH_S_ABORT);
+       ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
+       ipath_disarm_piobufs(dd, 0,
+               (unsigned)(dd->ipath_piobcnt2k + dd->ipath_piobcnt4k));
+
+       /* and again, be sure all have hit the chip */
+       ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
+}
+
+
 static void ipath_set_ib_lstate(struct ipath_devdata *dd, int which)
 {
        static const char *what[4] = {
@@ -1617,14 +1654,8 @@ static void ipath_set_ib_lstate(struct ipath_devdata *dd, int which)
                           INFINIPATH_IBCS_LINKTRAININGSTATE_MASK]);
        /* flush all queued sends when going to DOWN or INIT, to be sure that
         * they don't block MAD packets */
-       if (!linkcmd || linkcmd == INFINIPATH_IBCC_LINKCMD_INIT) {
-               ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
-                                INFINIPATH_S_ABORT);
-               ipath_disarm_piobufs(dd, dd->ipath_lastport_piobuf,
-                                   (unsigned)(dd->ipath_piobcnt2k +
-                                   dd->ipath_piobcnt4k) -
-                                   dd->ipath_lastport_piobuf);
-       }
+       if (!linkcmd || linkcmd == INFINIPATH_IBCC_LINKCMD_INIT)
+               ipath_cancel_sends(dd);
 
        ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl,
                         dd->ipath_ibcctrl | which);
@@ -1846,6 +1877,87 @@ void ipath_write_kreg_port(const struct ipath_devdata *dd, ipath_kreg regno,
        ipath_write_kreg(dd, where, value);
 }
 
+/*
+ * Following deal with the "obviously simple" task of overriding the state
+ * of the LEDS, which normally indicate link physical and logical status.
+ * The complications arise in dealing with different hardware mappings
+ * and the board-dependent routine being called from interrupts.
+ * and then there's the requirement to _flash_ them.
+ */
+#define LED_OVER_FREQ_SHIFT 8
+#define LED_OVER_FREQ_MASK (0xFF<<LED_OVER_FREQ_SHIFT)
+/* Below is "non-zero" to force override, but both actual LEDs are off */
+#define LED_OVER_BOTH_OFF (8)
+
+void ipath_run_led_override(unsigned long opaque)
+{
+       struct ipath_devdata *dd = (struct ipath_devdata *)opaque;
+       int timeoff;
+       int pidx;
+       u64 lstate, ltstate, val;
+
+       if (!(dd->ipath_flags & IPATH_INITTED))
+               return;
+
+       pidx = dd->ipath_led_override_phase++ & 1;
+       dd->ipath_led_override = dd->ipath_led_override_vals[pidx];
+       timeoff = dd->ipath_led_override_timeoff;
+
+       /*
+        * below potentially restores the LED values per current status,
+        * should also possibly setup the traffic-blink register,
+        * but leave that to per-chip functions.
+        */
+       val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_ibcstatus);
+       ltstate = (val >> INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) &
+                 INFINIPATH_IBCS_LINKTRAININGSTATE_MASK;
+       lstate = (val >> INFINIPATH_IBCS_LINKSTATE_SHIFT) &
+                INFINIPATH_IBCS_LINKSTATE_MASK;
+
+       dd->ipath_f_setextled(dd, lstate, ltstate);
+       mod_timer(&dd->ipath_led_override_timer, jiffies + timeoff);
+}
+
+void ipath_set_led_override(struct ipath_devdata *dd, unsigned int val)
+{
+       int timeoff, freq;
+
+       if (!(dd->ipath_flags & IPATH_INITTED))
+               return;
+
+       /* First check if we are blinking. If not, use 1HZ polling */
+       timeoff = HZ;
+       freq = (val & LED_OVER_FREQ_MASK) >> LED_OVER_FREQ_SHIFT;
+
+       if (freq) {
+               /* For blink, set each phase from one nybble of val */
+               dd->ipath_led_override_vals[0] = val & 0xF;
+               dd->ipath_led_override_vals[1] = (val >> 4) & 0xF;
+               timeoff = (HZ << 4)/freq;
+       } else {
+               /* Non-blink set both phases the same. */
+               dd->ipath_led_override_vals[0] = val & 0xF;
+               dd->ipath_led_override_vals[1] = val & 0xF;
+       }
+       dd->ipath_led_override_timeoff = timeoff;
+
+       /*
+        * If the timer has not already been started, do so. Use a "quick"
+        * timeout so the function will be called soon, to look at our request.
+        */
+       if (atomic_inc_return(&dd->ipath_led_override_timer_active) == 1) {
+               /* Need to start timer */
+               init_timer(&dd->ipath_led_override_timer);
+               dd->ipath_led_override_timer.function =
+                                                ipath_run_led_override;
+               dd->ipath_led_override_timer.data = (unsigned long) dd;
+               dd->ipath_led_override_timer.expires = jiffies + 1;
+               add_timer(&dd->ipath_led_override_timer);
+       } else {
+               atomic_dec(&dd->ipath_led_override_timer_active);
+       }
+}
+
 /**
  * ipath_shutdown_device - shut down a device
  * @dd: the infinipath device
@@ -1886,17 +1998,9 @@ void ipath_shutdown_device(struct ipath_devdata *dd)
         */
        udelay(5);
 
-       /*
-        * abort any armed or launched PIO buffers that didn't go. (self
-        * clearing).  Will cause any packet currently being transmitted to
-        * go out with an EBP, and may also cause a short packet error on
-        * the receiver.
-        */
-       ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
-                        INFINIPATH_S_ABORT);
-
        ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKINITCMD_DISABLE <<
                            INFINIPATH_IBCC_LINKINITCMD_SHIFT);
+       ipath_cancel_sends(dd);
 
        /* disable IBC */
        dd->ipath_control &= ~INFINIPATH_C_LINKENABLE;
@@ -1909,7 +2013,6 @@ void ipath_shutdown_device(struct ipath_devdata *dd)
         * Turn the LEDs off explictly for the same reason.
         */
        dd->ipath_f_quiet_serdes(dd);
-       dd->ipath_f_setextled(dd, 0, 0);
 
        if (dd->ipath_stats_timer_active) {
                del_timer_sync(&dd->ipath_stats_timer);
@@ -1925,6 +2028,9 @@ void ipath_shutdown_device(struct ipath_devdata *dd)
                         ~0ULL & ~INFINIPATH_HWE_MEMBISTFAILED);
        ipath_write_kreg(dd, dd->ipath_kregs->kr_errorclear, -1LL);
        ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, -1LL);
+
+       ipath_cdbg(VERBOSE, "Flush time and errors to EEPROM\n");
+       ipath_update_eeprom_log(dd);
 }
 
 /**
@@ -2085,6 +2191,16 @@ int ipath_reset_device(int unit)
                goto bail;
        }
 
+       if (atomic_read(&dd->ipath_led_override_timer_active)) {
+               /* Need to stop LED timer, _then_ shut off LEDs */
+               del_timer_sync(&dd->ipath_led_override_timer);
+               atomic_set(&dd->ipath_led_override_timer_active, 0);
+       }
+
+       /* Shut off LEDs after we are sure timer is not running */
+       dd->ipath_led_override = LED_OVER_BOTH_OFF;
+       dd->ipath_f_setextled(dd, 0, 0);
+
        dev_info(&dd->pcidev->dev, "Reset on unit %u requested\n", unit);
 
        if (!dd->ipath_kregbase || !(dd->ipath_flags & IPATH_PRESENT)) {
index 030185f90ee2b6ffe9ef70de2dc61ed4aa9c1c65..6b9147964a4f734638e42ae648493326b953d4b8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 QLogic, Inc. All rights reserved.
+ * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
  * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -95,39 +95,37 @@ static int i2c_gpio_set(struct ipath_devdata *dd,
                        enum i2c_type line,
                        enum i2c_state new_line_state)
 {
-       u64 read_val, write_val, mask, *gpioval;
+       u64 out_mask, dir_mask, *gpioval;
+       unsigned long flags = 0;
 
        gpioval = &dd->ipath_gpio_out;
-       read_val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_extctrl);
-       if (line == i2c_line_scl)
-               mask = dd->ipath_gpio_scl;
-       else
-               mask = dd->ipath_gpio_sda;
 
-       if (new_line_state == i2c_line_high)
+       if (line == i2c_line_scl) {
+               dir_mask = dd->ipath_gpio_scl;
+               out_mask = (1UL << dd->ipath_gpio_scl_num);
+       } else {
+               dir_mask = dd->ipath_gpio_sda;
+               out_mask = (1UL << dd->ipath_gpio_sda_num);
+       }
+
+       spin_lock_irqsave(&dd->ipath_gpio_lock, flags);
+       if (new_line_state == i2c_line_high) {
                /* tri-state the output rather than force high */
-               write_val = read_val & ~mask;
-       else
+               dd->ipath_extctrl &= ~dir_mask;
+       } else {
                /* config line to be an output */
-               write_val = read_val | mask;
-       ipath_write_kreg(dd, dd->ipath_kregs->kr_extctrl, write_val);
+               dd->ipath_extctrl |= dir_mask;
+       }
+       ipath_write_kreg(dd, dd->ipath_kregs->kr_extctrl, dd->ipath_extctrl);
 
-       /* set high and verify */
+       /* set output as well (no real verify) */
        if (new_line_state == i2c_line_high)
-               write_val = 0x1UL;
+               *gpioval |= out_mask;
        else
-               write_val = 0x0UL;
+               *gpioval &= ~out_mask;
 
-       if (line == i2c_line_scl) {
-               write_val <<= dd->ipath_gpio_scl_num;
-               *gpioval = *gpioval & ~(1UL << dd->ipath_gpio_scl_num);
-               *gpioval |= write_val;
-       } else {
-               write_val <<= dd->ipath_gpio_sda_num;
-               *gpioval = *gpioval & ~(1UL << dd->ipath_gpio_sda_num);
-               *gpioval |= write_val;
-       }
        ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_out, *gpioval);
+       spin_unlock_irqrestore(&dd->ipath_gpio_lock, flags);
 
        return 0;
 }
@@ -145,8 +143,9 @@ static int i2c_gpio_get(struct ipath_devdata *dd,
                        enum i2c_type line,
                        enum i2c_state *curr_statep)
 {
-       u64 read_val, write_val, mask;
+       u64 read_val, mask;
        int ret;
+       unsigned long flags = 0;
 
        /* check args */
        if (curr_statep == NULL) {
@@ -154,15 +153,21 @@ static int i2c_gpio_get(struct ipath_devdata *dd,
                goto bail;
        }
 
-       read_val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_extctrl);
        /* config line to be an input */
        if (line == i2c_line_scl)
                mask = dd->ipath_gpio_scl;
        else
                mask = dd->ipath_gpio_sda;
-       write_val = read_val & ~mask;
-       ipath_write_kreg(dd, dd->ipath_kregs->kr_extctrl, write_val);
+
+       spin_lock_irqsave(&dd->ipath_gpio_lock, flags);
+       dd->ipath_extctrl &= ~mask;
+       ipath_write_kreg(dd, dd->ipath_kregs->kr_extctrl, dd->ipath_extctrl);
+       /*
+        * Below is very unlikely to reflect true input state if Output
+        * Enable actually changed.
+        */
        read_val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_extstatus);
+       spin_unlock_irqrestore(&dd->ipath_gpio_lock, flags);
 
        if (read_val & mask)
                *curr_statep = i2c_line_high;
@@ -192,6 +197,7 @@ static void i2c_wait_for_writes(struct ipath_devdata *dd)
 
 static void scl_out(struct ipath_devdata *dd, u8 bit)
 {
+       udelay(1);
        i2c_gpio_set(dd, i2c_line_scl, bit ? i2c_line_high : i2c_line_low);
 
        i2c_wait_for_writes(dd);
@@ -314,12 +320,18 @@ static int eeprom_reset(struct ipath_devdata *dd)
        int clock_cycles_left = 9;
        u64 *gpioval = &dd->ipath_gpio_out;
        int ret;
+       unsigned long flags;
 
-       eeprom_init = 1;
+       spin_lock_irqsave(&dd->ipath_gpio_lock, flags);
+       /* Make sure shadows are consistent */
+       dd->ipath_extctrl = ipath_read_kreg64(dd, dd->ipath_kregs->kr_extctrl);
        *gpioval = ipath_read_kreg64(dd, dd->ipath_kregs->kr_gpio_out);
+       spin_unlock_irqrestore(&dd->ipath_gpio_lock, flags);
+
        ipath_cdbg(VERBOSE, "Resetting i2c eeprom; initial gpioout reg "
                   "is %llx\n", (unsigned long long) *gpioval);
 
+       eeprom_init = 1;
        /*
         * This is to get the i2c into a known state, by first going low,
         * then tristate sda (and then tristate scl as first thing
@@ -355,8 +367,8 @@ bail:
  * @len: number of bytes to receive
  */
 
-int ipath_eeprom_read(struct ipath_devdata *dd, u8 eeprom_offset,
-                     void *buffer, int len)
+static int ipath_eeprom_internal_read(struct ipath_devdata *dd,
+                                       u8 eeprom_offset, void *buffer, int len)
 {
        /* compiler complains unless initialized */
        u8 single_byte = 0;
@@ -406,6 +418,7 @@ bail:
        return ret;
 }
 
+
 /**
  * ipath_eeprom_write - writes data to the eeprom via I2C
  * @dd: the infinipath device
@@ -413,8 +426,8 @@ bail:
  * @buffer: data to write
  * @len: number of bytes to write
  */
-int ipath_eeprom_write(struct ipath_devdata *dd, u8 eeprom_offset,
-                      const void *buffer, int len)
+int ipath_eeprom_internal_write(struct ipath_devdata *dd, u8 eeprom_offset,
+                               const void *buffer, int len)
 {
        u8 single_byte;
        int sub_len;
@@ -488,6 +501,38 @@ bail:
        return ret;
 }
 
+/*
+ * The public entry-points ipath_eeprom_read() and ipath_eeprom_write()
+ * are now just wrappers around the internal functions.
+ */
+int ipath_eeprom_read(struct ipath_devdata *dd, u8 eeprom_offset,
+                       void *buff, int len)
+{
+       int ret;
+
+       ret = down_interruptible(&dd->ipath_eep_sem);
+       if (!ret) {
+               ret = ipath_eeprom_internal_read(dd, eeprom_offset, buff, len);
+               up(&dd->ipath_eep_sem);
+       }
+
+       return ret;
+}
+
+int ipath_eeprom_write(struct ipath_devdata *dd, u8 eeprom_offset,
+                       const void *buff, int len)
+{
+       int ret;
+
+       ret = down_interruptible(&dd->ipath_eep_sem);
+       if (!ret) {
+               ret = ipath_eeprom_internal_write(dd, eeprom_offset, buff, len);
+               up(&dd->ipath_eep_sem);
+       }
+
+       return ret;
+}
+
 static u8 flash_csum(struct ipath_flash *ifp, int adjust)
 {
        u8 *ip = (u8 *) ifp;
@@ -515,7 +560,7 @@ void ipath_get_eeprom_info(struct ipath_devdata *dd)
        void *buf;
        struct ipath_flash *ifp;
        __be64 guid;
-       int len;
+       int len, eep_stat;
        u8 csum, *bguid;
        int t = dd->ipath_unit;
        struct ipath_devdata *dd0 = ipath_lookup(0);
@@ -559,7 +604,11 @@ void ipath_get_eeprom_info(struct ipath_devdata *dd)
                goto bail;
        }
 
-       if (ipath_eeprom_read(dd, 0, buf, len)) {
+       down(&dd->ipath_eep_sem);
+       eep_stat = ipath_eeprom_internal_read(dd, 0, buf, len);
+       up(&dd->ipath_eep_sem);
+
+       if (eep_stat) {
                ipath_dev_err(dd, "Failed reading GUID from eeprom\n");
                goto done;
        }
@@ -634,8 +683,192 @@ void ipath_get_eeprom_info(struct ipath_devdata *dd)
        ipath_cdbg(VERBOSE, "Initted GUID to %llx from eeprom\n",
                   (unsigned long long) be64_to_cpu(dd->ipath_guid));
 
+       memcpy(&dd->ipath_eep_st_errs, &ifp->if_errcntp, IPATH_EEP_LOG_CNT);
+       /*
+        * Power-on (actually "active") hours are kept as little-endian value
+        * in EEPROM, but as seconds in a (possibly as small as 24-bit)
+        * atomic_t while running.
+        */
+       atomic_set(&dd->ipath_active_time, 0);
+       dd->ipath_eep_hrs = ifp->if_powerhour[0] | (ifp->if_powerhour[1] << 8);
+
 done:
        vfree(buf);
 
 bail:;
 }
+
+/**
+ * ipath_update_eeprom_log - copy active-time and error counters to eeprom
+ * @dd: the infinipath device
+ *
+ * Although the time is kept as seconds in the ipath_devdata struct, it is
+ * rounded to hours for re-write, as we have only 16 bits in EEPROM.
+ * First-cut code reads whole (expected) struct ipath_flash, modifies,
+ * re-writes. Future direction: read/write only what we need, assuming
+ * that the EEPROM had to have been "good enough" for driver init, and
+ * if not, we aren't making it worse.
+ *
+ */
+
+int ipath_update_eeprom_log(struct ipath_devdata *dd)
+{
+       void *buf;
+       struct ipath_flash *ifp;
+       int len, hi_water;
+       uint32_t new_time, new_hrs;
+       u8 csum;
+       int ret, idx;
+       unsigned long flags;
+
+       /* first, check if we actually need to do anything. */
+       ret = 0;
+       for (idx = 0; idx < IPATH_EEP_LOG_CNT; ++idx) {
+               if (dd->ipath_eep_st_new_errs[idx]) {
+                       ret = 1;
+                       break;
+               }
+       }
+       new_time = atomic_read(&dd->ipath_active_time);
+
+       if (ret == 0 && new_time < 3600)
+               return 0;
+
+       /*
+        * The quick-check above determined that there is something worthy
+        * of logging, so get current contents and do a more detailed idea.
+        */
+       len = offsetof(struct ipath_flash, if_future);
+       buf = vmalloc(len);
+       ret = 1;
+       if (!buf) {
+               ipath_dev_err(dd, "Couldn't allocate memory to read %u "
+                               "bytes from eeprom for logging\n", len);
+               goto bail;
+       }
+
+       /* Grab semaphore and read current EEPROM. If we get an
+        * error, let go, but if not, keep it until we finish write.
+        */
+       ret = down_interruptible(&dd->ipath_eep_sem);
+       if (ret) {
+               ipath_dev_err(dd, "Unable to acquire EEPROM for logging\n");
+               goto free_bail;
+       }
+       ret = ipath_eeprom_internal_read(dd, 0, buf, len);
+       if (ret) {
+               up(&dd->ipath_eep_sem);
+               ipath_dev_err(dd, "Unable read EEPROM for logging\n");
+               goto free_bail;
+       }
+       ifp = (struct ipath_flash *)buf;
+
+       csum = flash_csum(ifp, 0);
+       if (csum != ifp->if_csum) {
+               up(&dd->ipath_eep_sem);
+               ipath_dev_err(dd, "EEPROM cks err (0x%02X, S/B 0x%02X)\n",
+                               csum, ifp->if_csum);
+               ret = 1;
+               goto free_bail;
+       }
+       hi_water = 0;
+       spin_lock_irqsave(&dd->ipath_eep_st_lock, flags);
+       for (idx = 0; idx < IPATH_EEP_LOG_CNT; ++idx) {
+               int new_val = dd->ipath_eep_st_new_errs[idx];
+               if (new_val) {
+                       /*
+                        * If we have seen any errors, add to EEPROM values
+                        * We need to saturate at 0xFF (255) and we also
+                        * would need to adjust the checksum if we were
+                        * trying to minimize EEPROM traffic
+                        * Note that we add to actual current count in EEPROM,
+                        * in case it was altered while we were running.
+                        */
+                       new_val += ifp->if_errcntp[idx];
+                       if (new_val > 0xFF)
+                               new_val = 0xFF;
+                       if (ifp->if_errcntp[idx] != new_val) {
+                               ifp->if_errcntp[idx] = new_val;
+                               hi_water = offsetof(struct ipath_flash,
+                                               if_errcntp) + idx;
+                       }
+                       /*
+                        * update our shadow (used to minimize EEPROM
+                        * traffic), to match what we are about to write.
+                        */
+                       dd->ipath_eep_st_errs[idx] = new_val;
+                       dd->ipath_eep_st_new_errs[idx] = 0;
+               }
+       }
+       /*
+        * now update active-time. We would like to round to the nearest hour
+        * but unless atomic_t are sure to be proper signed ints we cannot,
+        * because we need to account for what we "transfer" to EEPROM and
+        * if we log an hour at 31 minutes, then we would need to set
+        * active_time to -29 to accurately count the _next_ hour.
+        */
+       if (new_time > 3600) {
+               new_hrs = new_time / 3600;
+               atomic_sub((new_hrs * 3600), &dd->ipath_active_time);
+               new_hrs += dd->ipath_eep_hrs;
+               if (new_hrs > 0xFFFF)
+                       new_hrs = 0xFFFF;
+               dd->ipath_eep_hrs = new_hrs;
+               if ((new_hrs & 0xFF) != ifp->if_powerhour[0]) {
+                       ifp->if_powerhour[0] = new_hrs & 0xFF;
+                       hi_water = offsetof(struct ipath_flash, if_powerhour);
+               }
+               if ((new_hrs >> 8) != ifp->if_powerhour[1]) {
+                       ifp->if_powerhour[1] = new_hrs >> 8;
+                       hi_water = offsetof(struct ipath_flash, if_powerhour)
+                                       + 1;
+               }
+       }
+       /*
+        * There is a tiny possibility that we could somehow fail to write
+        * the EEPROM after updating our shadows, but problems from holding
+        * the spinlock too long are a much bigger issue.
+        */
+       spin_unlock_irqrestore(&dd->ipath_eep_st_lock, flags);
+       if (hi_water) {
+               /* we made some change to the data, uopdate cksum and write */
+               csum = flash_csum(ifp, 1);
+               ret = ipath_eeprom_internal_write(dd, 0, buf, hi_water + 1);
+       }
+       up(&dd->ipath_eep_sem);
+       if (ret)
+               ipath_dev_err(dd, "Failed updating EEPROM\n");
+
+free_bail:
+       vfree(buf);
+bail:
+       return ret;
+
+}
+
+/**
+ * ipath_inc_eeprom_err - increment one of the four error counters
+ * that are logged to EEPROM.
+ * @dd: the infinipath device
+ * @eidx: 0..3, the counter to increment
+ * @incr: how much to add
+ *
+ * Each counter is 8-bits, and saturates at 255 (0xFF). They
+ * are copied to the EEPROM (aka flash) whenever ipath_update_eeprom_log()
+ * is called, but it can only be called in a context that allows sleep.
+ * This function can be called even at interrupt level.
+ */
+
+void ipath_inc_eeprom_err(struct ipath_devdata *dd, u32 eidx, u32 incr)
+{
+       uint new_val;
+       unsigned long flags;
+
+       spin_lock_irqsave(&dd->ipath_eep_st_lock, flags);
+       new_val = dd->ipath_eep_st_new_errs[eidx] + incr;
+       if (new_val > 255)
+               new_val = 255;
+       dd->ipath_eep_st_new_errs[eidx] = new_val;
+       spin_unlock_irqrestore(&dd->ipath_eep_st_lock, flags);
+       return;
+}
index 1272aaf2a78543f86fa9288e7cf85e2426ead2be..33ab0d6b80ff3085a0ed423b4fe980fd1c938807 100644 (file)
@@ -396,7 +396,8 @@ static int ipath_tid_update(struct ipath_portdata *pd, struct file *fp,
                           "TID %u, vaddr %lx, physaddr %llx pgp %p\n",
                           tid, vaddr, (unsigned long long) physaddr,
                           pagep[i]);
-               dd->ipath_f_put_tid(dd, &tidbase[tid], 1, physaddr);
+               dd->ipath_f_put_tid(dd, &tidbase[tid], RCVHQ_RCV_TYPE_EXPECTED,
+                                   physaddr);
                /*
                 * don't check this tid in ipath_portshadow, since we
                 * just filled it in; start with the next one.
@@ -422,7 +423,8 @@ static int ipath_tid_update(struct ipath_portdata *pd, struct file *fp,
                        if (dd->ipath_pageshadow[porttid + tid]) {
                                ipath_cdbg(VERBOSE, "Freeing TID %u\n",
                                           tid);
-                               dd->ipath_f_put_tid(dd, &tidbase[tid], 1,
+                               dd->ipath_f_put_tid(dd, &tidbase[tid],
+                                                   RCVHQ_RCV_TYPE_EXPECTED,
                                                    dd->ipath_tidinvalid);
                                pci_unmap_page(dd->pcidev,
                                        dd->ipath_physshadow[porttid + tid],
@@ -538,7 +540,8 @@ static int ipath_tid_free(struct ipath_portdata *pd, unsigned subport,
                if (dd->ipath_pageshadow[porttid + tid]) {
                        ipath_cdbg(VERBOSE, "PID %u freeing TID %u\n",
                                   pd->port_pid, tid);
-                       dd->ipath_f_put_tid(dd, &tidbase[tid], 1,
+                       dd->ipath_f_put_tid(dd, &tidbase[tid],
+                                           RCVHQ_RCV_TYPE_EXPECTED,
                                            dd->ipath_tidinvalid);
                        pci_unmap_page(dd->pcidev,
                                dd->ipath_physshadow[porttid + tid],
@@ -921,7 +924,8 @@ static int ipath_create_user_egr(struct ipath_portdata *pd)
                                            (u64 __iomem *)
                                            ((char __iomem *)
                                             dd->ipath_kregbase +
-                                            dd->ipath_rcvegrbase), 0, pa);
+                                            dd->ipath_rcvegrbase),
+                                           RCVHQ_RCV_TYPE_EAGER, pa);
                        pa += egrsize;
                }
                cond_resched(); /* don't hog the cpu */
@@ -1337,68 +1341,133 @@ bail:
        return ret;
 }
 
-static unsigned int ipath_poll(struct file *fp,
-                              struct poll_table_struct *pt)
+static unsigned int ipath_poll_urgent(struct ipath_portdata *pd,
+                                     struct file *fp,
+                                     struct poll_table_struct *pt)
 {
-       struct ipath_portdata *pd;
-       u32 head, tail;
-       int bit;
        unsigned pollflag = 0;
        struct ipath_devdata *dd;
 
-       pd = port_fp(fp);
-       if (!pd)
-               goto bail;
        dd = pd->port_dd;
 
-       bit = pd->port_port + INFINIPATH_R_INTRAVAIL_SHIFT;
-       set_bit(bit, &dd->ipath_rcvctrl);
+       if (test_bit(IPATH_PORT_WAITING_OVERFLOW, &pd->int_flag)) {
+               pollflag |= POLLERR;
+               clear_bit(IPATH_PORT_WAITING_OVERFLOW, &pd->int_flag);
+       }
 
-       /*
-        * Before blocking, make sure that head is still == tail,
-        * reading from the chip, so we can be sure the interrupt
-        * enable has made it to the chip.  If not equal, disable
-        * interrupt again and return immediately.  This avoids races,
-        * and the overhead of the chip read doesn't matter much at
-        * this point, since we are waiting for something anyway.
-        */
+       if (test_bit(IPATH_PORT_WAITING_URG, &pd->int_flag)) {
+               pollflag |= POLLIN | POLLRDNORM;
+               clear_bit(IPATH_PORT_WAITING_URG, &pd->int_flag);
+       }
 
-       ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl,
-                        dd->ipath_rcvctrl);
+       if (!pollflag) {
+               set_bit(IPATH_PORT_WAITING_URG, &pd->port_flag);
+               if (pd->poll_type & IPATH_POLL_TYPE_OVERFLOW)
+                       set_bit(IPATH_PORT_WAITING_OVERFLOW,
+                               &pd->port_flag);
+
+               poll_wait(fp, &pd->port_wait, pt);
+       }
+
+       return pollflag;
+}
+
+static unsigned int ipath_poll_next(struct ipath_portdata *pd,
+                                   struct file *fp,
+                                   struct poll_table_struct *pt)
+{
+       u32 head, tail;
+       unsigned pollflag = 0;
+       struct ipath_devdata *dd;
+
+       dd = pd->port_dd;
 
        head = ipath_read_ureg32(dd, ur_rcvhdrhead, pd->port_port);
-       tail = ipath_read_ureg32(dd, ur_rcvhdrtail, pd->port_port);
+       tail = *(volatile u64 *)pd->port_rcvhdrtail_kvaddr;
 
-       if (tail == head) {
+       if (test_bit(IPATH_PORT_WAITING_OVERFLOW, &pd->int_flag)) {
+               pollflag |= POLLERR;
+               clear_bit(IPATH_PORT_WAITING_OVERFLOW, &pd->int_flag);
+       }
+
+       if (tail != head ||
+           test_bit(IPATH_PORT_WAITING_RCV, &pd->int_flag)) {
+               pollflag |= POLLIN | POLLRDNORM;
+               clear_bit(IPATH_PORT_WAITING_RCV, &pd->int_flag);
+       }
+
+       if (!pollflag) {
                set_bit(IPATH_PORT_WAITING_RCV, &pd->port_flag);
+               if (pd->poll_type & IPATH_POLL_TYPE_OVERFLOW)
+                       set_bit(IPATH_PORT_WAITING_OVERFLOW,
+                               &pd->port_flag);
+
+               set_bit(pd->port_port + INFINIPATH_R_INTRAVAIL_SHIFT,
+                       &dd->ipath_rcvctrl);
+
+               ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl,
+                                dd->ipath_rcvctrl);
+
                if (dd->ipath_rhdrhead_intr_off) /* arm rcv interrupt */
-                       (void)ipath_write_ureg(dd, ur_rcvhdrhead,
-                                              dd->ipath_rhdrhead_intr_off
-                                              | head, pd->port_port);
-               poll_wait(fp, &pd->port_wait, pt);
+                       ipath_write_ureg(dd, ur_rcvhdrhead,
+                                        dd->ipath_rhdrhead_intr_off | head,
+                                        pd->port_port);
 
-               if (test_bit(IPATH_PORT_WAITING_RCV, &pd->port_flag)) {
-                       /* timed out, no packets received */
-                       clear_bit(IPATH_PORT_WAITING_RCV, &pd->port_flag);
-                       pd->port_rcvwait_to++;
-               }
-               else
-                       pollflag = POLLIN | POLLRDNORM;
-       }
-       else {
-               /* it's already happened; don't do wait_event overhead */
-               pollflag = POLLIN | POLLRDNORM;
-               pd->port_rcvnowait++;
+               poll_wait(fp, &pd->port_wait, pt);
        }
 
-       clear_bit(bit, &dd->ipath_rcvctrl);
-       ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl,
-                        dd->ipath_rcvctrl);
+       return pollflag;
+}
+
+static unsigned int ipath_poll(struct file *fp,
+                              struct poll_table_struct *pt)
+{
+       struct ipath_portdata *pd;
+       unsigned pollflag;
+
+       pd = port_fp(fp);
+       if (!pd)
+               pollflag = 0;
+       else if (pd->poll_type & IPATH_POLL_TYPE_URGENT)
+               pollflag = ipath_poll_urgent(pd, fp, pt);
+       else
+               pollflag = ipath_poll_next(pd, fp, pt);
 
-bail:
        return pollflag;
 }
 
+static int ipath_supports_subports(int user_swmajor, int user_swminor)
+{
+       /* no subport implementation prior to software version 1.3 */
+       return (user_swmajor > 1) || (user_swminor >= 3);
+}
+
+static int ipath_compatible_subports(int user_swmajor, int user_swminor)
+{
+       /* this code is written long-hand for clarity */
+       if (IPATH_USER_SWMAJOR != user_swmajor) {
+               /* no promise of compatibility if major mismatch */
+               return 0;
+       }
+       if (IPATH_USER_SWMAJOR == 1) {
+               switch (IPATH_USER_SWMINOR) {
+               case 0:
+               case 1:
+               case 2:
+                       /* no subport implementation so cannot be compatible */
+                       return 0;
+               case 3:
+                       /* 3 is only compatible with itself */
+                       return user_swminor == 3;
+               default:
+                       /* >= 4 are compatible (or are expected to be) */
+                       return user_swminor >= 4;
+               }
+       }
+       /* make no promises yet for future major versions */
+       return 0;
+}
+
 static int init_subports(struct ipath_devdata *dd,
                         struct ipath_portdata *pd,
                         const struct ipath_user_info *uinfo)
@@ -1408,20 +1477,32 @@ static int init_subports(struct ipath_devdata *dd,
        size_t size;
 
        /*
-        * If the user is requesting zero or one port,
+        * If the user is requesting zero subports,
         * skip the subport allocation.
         */
-       if (uinfo->spu_subport_cnt <= 1)
+       if (uinfo->spu_subport_cnt <= 0)
+               goto bail;
+
+       /* Self-consistency check for ipath_compatible_subports() */
+       if (ipath_supports_subports(IPATH_USER_SWMAJOR, IPATH_USER_SWMINOR) &&
+           !ipath_compatible_subports(IPATH_USER_SWMAJOR,
+                                      IPATH_USER_SWMINOR)) {
+               dev_info(&dd->pcidev->dev,
+                        "Inconsistent ipath_compatible_subports()\n");
                goto bail;
+       }
 
-       /* Old user binaries don't know about new subport implementation */
-       if ((uinfo->spu_userversion & 0xffff) != IPATH_USER_SWMINOR) {
+       /* Check for subport compatibility */
+       if (!ipath_compatible_subports(uinfo->spu_userversion >> 16,
+                                      uinfo->spu_userversion & 0xffff)) {
                dev_info(&dd->pcidev->dev,
-                        "Mismatched user minor version (%d) and driver "
-                         "minor version (%d) while port sharing. Ensure "
+                        "Mismatched user version (%d.%d) and driver "
+                        "version (%d.%d) while port sharing. Ensure "
                          "that driver and library are from the same "
                          "release.\n",
+                        (int) (uinfo->spu_userversion >> 16),
                          (int) (uinfo->spu_userversion & 0xffff),
+                        IPATH_USER_SWMAJOR,
                         IPATH_USER_SWMINOR);
                goto bail;
        }
@@ -1725,14 +1806,13 @@ static int ipath_open(struct inode *in, struct file *fp)
        return fp->private_data ? 0 : -ENOMEM;
 }
 
-
 /* Get port early, so can set affinity prior to memory allocation */
 static int ipath_assign_port(struct file *fp,
                              const struct ipath_user_info *uinfo)
 {
        int ret;
        int i_minor;
-       unsigned swminor;
+       unsigned swmajor, swminor;
 
        /* Check to be sure we haven't already initialized this file */
        if (port_fp(fp)) {
@@ -1741,7 +1821,8 @@ static int ipath_assign_port(struct file *fp,
        }
 
        /* for now, if major version is different, bail */
-       if ((uinfo->spu_userversion >> 16) != IPATH_USER_SWMAJOR) {
+       swmajor = uinfo->spu_userversion >> 16;
+       if (swmajor != IPATH_USER_SWMAJOR) {
                ipath_dbg("User major version %d not same as driver "
                          "major %d\n", uinfo->spu_userversion >> 16,
                          IPATH_USER_SWMAJOR);
@@ -1756,7 +1837,8 @@ static int ipath_assign_port(struct file *fp,
 
        mutex_lock(&ipath_mutex);
 
-       if (swminor == IPATH_USER_SWMINOR && uinfo->spu_subport_cnt &&
+       if (ipath_compatible_subports(swmajor, swminor) &&
+           uinfo->spu_subport_cnt &&
            (ret = find_shared_port(fp, uinfo))) {
                mutex_unlock(&ipath_mutex);
                if (ret > 0)
@@ -2020,7 +2102,8 @@ static int ipath_port_info(struct ipath_portdata *pd, u16 subport,
        info.port = pd->port_port;
        info.subport = subport;
        /* Don't return new fields if old library opened the port. */
-       if ((pd->userversion & 0xffff) == IPATH_USER_SWMINOR) {
+       if (ipath_supports_subports(pd->userversion >> 16,
+                                   pd->userversion & 0xffff)) {
                /* Number of user ports available for this device. */
                info.num_ports = pd->port_dd->ipath_cfgports - 1;
                info.num_subports = pd->port_subport_cnt;
@@ -2123,6 +2206,11 @@ static ssize_t ipath_write(struct file *fp, const char __user *data,
                src = NULL;
                dest = NULL;
                break;
+       case IPATH_CMD_POLL_TYPE:
+               copy = sizeof(cmd.cmd.poll_type);
+               dest = &cmd.cmd.poll_type;
+               src = &ucmd->cmd.poll_type;
+               break;
        default:
                ret = -EINVAL;
                goto bail;
@@ -2195,6 +2283,9 @@ static ssize_t ipath_write(struct file *fp, const char __user *data,
        case IPATH_CMD_PIOAVAILUPD:
                ret = ipath_force_pio_avail_update(pd->port_dd);
                break;
+       case IPATH_CMD_POLL_TYPE:
+               pd->poll_type = cmd.cmd.poll_type;
+               break;
        }
 
        if (ret >= 0)
index ebd5c7bd2cdbec4680163237360ee88b12822b67..2e689b974e1f48ed4e6538b72882e166b60c36ce 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 QLogic, Inc. All rights reserved.
+ * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
  * Copyright (c) 2006 PathScale, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -257,9 +257,14 @@ static ssize_t atomic_port_info_read(struct file *file, char __user *buf,
                /* Notimpl InitType (actually, an SMA decision) */
                /* VLHighLimit is 0 (only one VL) */
                ; /* VLArbitrationHighCap is 0 (only one VL) */
+       /*
+        * Note: the chips support a maximum MTU of 4096, but the driver
+        * hasn't implemented this feature yet, so set the maximum
+        * to 2048.
+        */
        portinfo[10] =  /* VLArbitrationLowCap is 0 (only one VL) */
                /* InitTypeReply is SMA decision */
-               (5 << 16)       /* MTUCap 4096 */
+               (4 << 16)       /* MTUCap 2048 */
                | (7 << 13)     /* VLStallCount */
                | (0x1f << 8)   /* HOQLife */
                | (1 << 4)
index 4171198fc2025cc6358c7ac21e0ddcfb13206e48..650745d83faccbe0f3da87ffbc6feb11087b1137 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 QLogic, Inc. All rights reserved.
+ * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
  * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -36,6 +36,7 @@
  * HT chip.
  */
 
+#include <linux/vmalloc.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/htirq.h>
@@ -439,6 +440,7 @@ static void ipath_ht_handle_hwerrors(struct ipath_devdata *dd, char *msg,
        u32 bits, ctrl;
        int isfatal = 0;
        char bitsmsg[64];
+       int log_idx;
 
        hwerrs = ipath_read_kreg64(dd, dd->ipath_kregs->kr_hwerrstatus);
 
@@ -467,6 +469,11 @@ static void ipath_ht_handle_hwerrors(struct ipath_devdata *dd, char *msg,
 
        hwerrs &= dd->ipath_hwerrmask;
 
+       /* We log some errors to EEPROM, check if we have any of those. */
+       for (log_idx = 0; log_idx < IPATH_EEP_LOG_CNT; ++log_idx)
+               if (hwerrs & dd->ipath_eep_st_masks[log_idx].hwerrs_to_log)
+                       ipath_inc_eeprom_err(dd, log_idx, 1);
+
        /*
         * make sure we get this much out, unless told to be quiet,
         * it's a parity error we may recover from,
@@ -502,9 +509,7 @@ static void ipath_ht_handle_hwerrors(struct ipath_devdata *dd, char *msg,
                if (!hwerrs) {
                        ipath_dbg("Clearing freezemode on ignored or "
                                  "recovered hardware error\n");
-                       ctrl &= ~INFINIPATH_C_FREEZEMODE;
-                       ipath_write_kreg(dd, dd->ipath_kregs->kr_control,
-                                        ctrl);
+                       ipath_clear_freeze(dd);
                }
        }
 
@@ -672,10 +677,16 @@ static int ipath_ht_boardname(struct ipath_devdata *dd, char *name,
        if (n)
                snprintf(name, namelen, "%s", n);
 
+       if (dd->ipath_boardrev != 6 && dd->ipath_boardrev != 7 &&
+           dd->ipath_boardrev != 11) {
+               ipath_dev_err(dd, "Unsupported InfiniPath board %s!\n", name);
+               ret = 1;
+               goto bail;
+       }
        if (dd->ipath_majrev != 3 || (dd->ipath_minrev < 2 ||
-               dd->ipath_minrev > 3)) {
+               dd->ipath_minrev > 4)) {
                /*
-                * This version of the driver only supports Rev 3.2 and 3.3
+                * This version of the driver only supports Rev 3.2 - 3.4
                 */
                ipath_dev_err(dd,
                              "Unsupported InfiniPath hardware revision %u.%u!\n",
@@ -689,36 +700,11 @@ static int ipath_ht_boardname(struct ipath_devdata *dd, char *name,
         * copies
         */
        dd->ipath_flags |= IPATH_32BITCOUNTERS;
+       dd->ipath_flags |= IPATH_GPIO_INTR;
        if (dd->ipath_htspeed != 800)
                ipath_dev_err(dd,
                              "Incorrectly configured for HT @ %uMHz\n",
                              dd->ipath_htspeed);
-       if (dd->ipath_boardrev == 7 || dd->ipath_boardrev == 11 ||
-           dd->ipath_boardrev == 6)
-               dd->ipath_flags |= IPATH_GPIO_INTR;
-       else
-               dd->ipath_flags |= IPATH_POLL_RX_INTR;
-       if (dd->ipath_boardrev == 8) {  /* LS/X-1 */
-               u64 val;
-               val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_extstatus);
-               if (val & INFINIPATH_EXTS_SERDESSEL) {
-                       /*
-                        * hardware disabled
-                        *
-                        * This means that the chip is hardware disabled,
-                        * and will not be able to bring up the link,
-                        * in any case.  We special case this and abort
-                        * early, to avoid later messages.  We also set
-                        * the DISABLED status bit
-                        */
-                       ipath_dbg("Unit %u is hardware-disabled\n",
-                                 dd->ipath_unit);
-                       *dd->ipath_statusp |= IPATH_STATUS_DISABLED;
-                       /* this value is handled differently */
-                       ret = 2;
-                       goto bail;
-               }
-       }
        ret = 0;
 
 bail:
@@ -1058,12 +1044,24 @@ static void ipath_setup_ht_setextled(struct ipath_devdata *dd,
                                     u64 lst, u64 ltst)
 {
        u64 extctl;
+       unsigned long flags = 0;
 
        /* the diags use the LED to indicate diag info, so we leave
         * the external LED alone when the diags are running */
        if (ipath_diag_inuse)
                return;
 
+       /* Allow override of LED display for, e.g. Locating system in rack */
+       if (dd->ipath_led_override) {
+               ltst = (dd->ipath_led_override & IPATH_LED_PHYS)
+                       ? INFINIPATH_IBCS_LT_STATE_LINKUP
+                       : INFINIPATH_IBCS_LT_STATE_DISABLED;
+               lst = (dd->ipath_led_override & IPATH_LED_LOG)
+                       ? INFINIPATH_IBCS_L_STATE_ACTIVE
+                       : INFINIPATH_IBCS_L_STATE_DOWN;
+       }
+
+       spin_lock_irqsave(&dd->ipath_gpio_lock, flags);
        /*
         * start by setting both LED control bits to off, then turn
         * on the appropriate bit(s).
@@ -1092,6 +1090,7 @@ static void ipath_setup_ht_setextled(struct ipath_devdata *dd,
        }
        dd->ipath_extctrl = extctl;
        ipath_write_kreg(dd, dd->ipath_kregs->kr_extctrl, extctl);
+       spin_unlock_irqrestore(&dd->ipath_gpio_lock, flags);
 }
 
 static void ipath_init_ht_variables(struct ipath_devdata *dd)
@@ -1157,6 +1156,22 @@ static void ipath_init_ht_variables(struct ipath_devdata *dd)
 
        dd->ipath_i_rcvavail_mask = INFINIPATH_I_RCVAVAIL_MASK;
        dd->ipath_i_rcvurg_mask = INFINIPATH_I_RCVURG_MASK;
+
+       /*
+        * EEPROM error log 0 is TXE Parity errors. 1 is RXE Parity.
+        * 2 is Some Misc, 3 is reserved for future.
+        */
+       dd->ipath_eep_st_masks[0].hwerrs_to_log =
+               INFINIPATH_HWE_TXEMEMPARITYERR_MASK <<
+               INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT;
+
+       dd->ipath_eep_st_masks[1].hwerrs_to_log =
+               INFINIPATH_HWE_RXEMEMPARITYERR_MASK <<
+               INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT;
+
+       dd->ipath_eep_st_masks[2].errs_to_log =
+               INFINIPATH_E_INVALIDADDR | INFINIPATH_E_RESET;
+
 }
 
 /**
@@ -1372,7 +1387,7 @@ static void ipath_ht_quiet_serdes(struct ipath_devdata *dd)
  * ipath_pe_put_tid - write a TID in chip
  * @dd: the infinipath device
  * @tidptr: pointer to the expected TID (in chip) to udpate
- * @tidtype: 0 for eager, 1 for expected
+ * @tidtype: RCVHQ_RCV_TYPE_EAGER (1) for eager, RCVHQ_RCV_TYPE_EXPECTED (0) for expected
  * @pa: physical address of in memory buffer; ipath_tidinvalid if freeing
  *
  * This exists as a separate routine to allow for special locking etc.
@@ -1393,7 +1408,7 @@ static void ipath_ht_put_tid(struct ipath_devdata *dd,
                                 "40 bits, using only 40!!!\n", pa);
                        pa &= INFINIPATH_RT_ADDR_MASK;
                }
-               if (type == 0)
+               if (type == RCVHQ_RCV_TYPE_EAGER)
                        pa |= dd->ipath_tidtemplate;
                else {
                        /* in words (fixed, full page).  */
@@ -1433,7 +1448,8 @@ static void ipath_ht_clear_tids(struct ipath_devdata *dd, unsigned port)
                                   port * dd->ipath_rcvtidcnt *
                                   sizeof(*tidbase));
        for (i = 0; i < dd->ipath_rcvtidcnt; i++)
-               ipath_ht_put_tid(dd, &tidbase[i], 1, dd->ipath_tidinvalid);
+               ipath_ht_put_tid(dd, &tidbase[i], RCVHQ_RCV_TYPE_EXPECTED,
+                                dd->ipath_tidinvalid);
 
        tidbase = (u64 __iomem *) ((char __iomem *)(dd->ipath_kregbase) +
                                   dd->ipath_rcvegrbase +
@@ -1441,7 +1457,8 @@ static void ipath_ht_clear_tids(struct ipath_devdata *dd, unsigned port)
                                   sizeof(*tidbase));
 
        for (i = 0; i < dd->ipath_rcvegrcnt; i++)
-               ipath_ht_put_tid(dd, &tidbase[i], 0, dd->ipath_tidinvalid);
+               ipath_ht_put_tid(dd, &tidbase[i], RCVHQ_RCV_TYPE_EAGER,
+                                dd->ipath_tidinvalid);
 }
 
 /**
@@ -1528,11 +1545,6 @@ static int ipath_ht_early_init(struct ipath_devdata *dd)
                writel(16, piobuf);
                piobuf += pioincr;
        }
-       /*
-        * self-clearing
-        */
-       ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
-                        INFINIPATH_S_ABORT);
 
        ipath_get_eeprom_info(dd);
        if (dd->ipath_boardrev == 5 && dd->ipath_serial[0] == '1' &&
@@ -1543,8 +1555,10 @@ static int ipath_ht_early_init(struct ipath_devdata *dd)
                 * with 128, rather than 112.
                 */
                dd->ipath_flags |= IPATH_GPIO_INTR;
-               dd->ipath_flags &= ~IPATH_POLL_RX_INTR;
-       }
+       } else
+               ipath_dev_err(dd, "Unsupported InfiniPath serial "
+                             "number %.16s!\n", dd->ipath_serial);
+
        return 0;
 }
 
@@ -1561,7 +1575,6 @@ static int ipath_ht_txe_recover(struct ipath_devdata *dd)
        }
        dev_info(&dd->pcidev->dev,
                "Recovering from TXE PIO parity error\n");
-       ipath_disarm_senderrbufs(dd, 1);
        return 1;
 }
 
index 4e2e3dfeb2c8c3f77cb245ee91c2bbeeff470380..9868ccda5f26769b66dc76593ef107a53a5630f2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 QLogic, Inc. All rights reserved.
+ * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
  * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -296,13 +296,6 @@ static const struct ipath_cregs ipath_pe_cregs = {
 #define IPATH_GPIO_SCL (1ULL << \
        (_IPATH_GPIO_SCL_NUM+INFINIPATH_EXTC_GPIOOE_SHIFT))
 
-/*
- * Rev2 silicon allows suppressing check for ArmLaunch errors.
- * this can speed up short packet sends on systems that do
- * not guaranteee write-order.
- */
-#define INFINIPATH_XGXS_SUPPRESS_ARMLAUNCH_ERR (1ULL<<63)
-
 /* 6120 specific hardware errors... */
 static const struct ipath_hwerror_msgs ipath_6120_hwerror_msgs[] = {
        INFINIPATH_HWE_MSG(PCIEPOISONEDTLP, "PCIe Poisoned TLP"),
@@ -347,6 +340,7 @@ static void ipath_pe_handle_hwerrors(struct ipath_devdata *dd, char *msg,
        u32 bits, ctrl;
        int isfatal = 0;
        char bitsmsg[64];
+       int log_idx;
 
        hwerrs = ipath_read_kreg64(dd, dd->ipath_kregs->kr_hwerrstatus);
        if (!hwerrs) {
@@ -374,6 +368,11 @@ static void ipath_pe_handle_hwerrors(struct ipath_devdata *dd, char *msg,
 
        hwerrs &= dd->ipath_hwerrmask;
 
+       /* We log some errors to EEPROM, check if we have any of those. */
+       for (log_idx = 0; log_idx < IPATH_EEP_LOG_CNT; ++log_idx)
+               if (hwerrs & dd->ipath_eep_st_masks[log_idx].hwerrs_to_log)
+                       ipath_inc_eeprom_err(dd, log_idx, 1);
+
        /*
         * make sure we get this much out, unless told to be quiet,
         * or it's occurred within the last 5 seconds
@@ -431,10 +430,12 @@ static void ipath_pe_handle_hwerrors(struct ipath_devdata *dd, char *msg,
                        *dd->ipath_statusp |= IPATH_STATUS_HWERROR;
                        dd->ipath_flags &= ~IPATH_INITTED;
                } else {
-                       ipath_dbg("Clearing freezemode on ignored hardware "
-                                 "error\n");
-                       ipath_write_kreg(dd, dd->ipath_kregs->kr_control,
-                                        dd->ipath_control);
+                       static u32 freeze_cnt;
+
+                       freeze_cnt++;
+                       ipath_dbg("Clearing freezemode on ignored or recovered "
+                                 "hardware error (%u)\n", freeze_cnt);
+                       ipath_clear_freeze(dd);
                }
        }
 
@@ -680,17 +681,6 @@ static int ipath_pe_bringup_serdes(struct ipath_devdata *dd)
                val |= dd->ipath_rx_pol_inv <<
                        INFINIPATH_XGXS_RX_POL_SHIFT;
        }
-       if (dd->ipath_minrev >= 2) {
-               /* Rev 2. can tolerate multiple writes to PBC, and
-                * allowing them can provide lower latency on some
-                * CPUs, but this feature is off by default, only
-                * turned on by setting D63 of XGXSconfig reg.
-                * May want to make this conditional more
-                * fine-grained in future. This is not exactly
-                * related to XGXS, but where the bit ended up.
-                */
-               val |= INFINIPATH_XGXS_SUPPRESS_ARMLAUNCH_ERR;
-       }
        if (val != prev_val)
                ipath_write_kreg(dd, dd->ipath_kregs->kr_xgxsconfig, val);
 
@@ -791,12 +781,24 @@ static void ipath_setup_pe_setextled(struct ipath_devdata *dd, u64 lst,
                                     u64 ltst)
 {
        u64 extctl;
+       unsigned long flags = 0;
 
        /* the diags use the LED to indicate diag info, so we leave
         * the external LED alone when the diags are running */
        if (ipath_diag_inuse)
                return;
 
+       /* Allow override of LED display for, e.g. Locating system in rack */
+       if (dd->ipath_led_override) {
+               ltst = (dd->ipath_led_override & IPATH_LED_PHYS)
+                       ? INFINIPATH_IBCS_LT_STATE_LINKUP
+                       : INFINIPATH_IBCS_LT_STATE_DISABLED;
+               lst = (dd->ipath_led_override & IPATH_LED_LOG)
+                       ? INFINIPATH_IBCS_L_STATE_ACTIVE
+                       : INFINIPATH_IBCS_L_STATE_DOWN;
+       }
+
+       spin_lock_irqsave(&dd->ipath_gpio_lock, flags);
        extctl = dd->ipath_extctrl & ~(INFINIPATH_EXTC_LED1PRIPORT_ON |
                                       INFINIPATH_EXTC_LED2PRIPORT_ON);
 
@@ -806,6 +808,7 @@ static void ipath_setup_pe_setextled(struct ipath_devdata *dd, u64 lst,
                extctl |= INFINIPATH_EXTC_LED1PRIPORT_ON;
        dd->ipath_extctrl = extctl;
        ipath_write_kreg(dd, dd->ipath_kregs->kr_extctrl, extctl);
+       spin_unlock_irqrestore(&dd->ipath_gpio_lock, flags);
 }
 
 /**
@@ -955,6 +958,27 @@ static void ipath_init_pe_variables(struct ipath_devdata *dd)
 
        dd->ipath_i_rcvavail_mask = INFINIPATH_I_RCVAVAIL_MASK;
        dd->ipath_i_rcvurg_mask = INFINIPATH_I_RCVURG_MASK;
+
+       /*
+        * EEPROM error log 0 is TXE Parity errors. 1 is RXE Parity.
+        * 2 is Some Misc, 3 is reserved for future.
+        */
+       dd->ipath_eep_st_masks[0].hwerrs_to_log =
+               INFINIPATH_HWE_TXEMEMPARITYERR_MASK <<
+               INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT;
+
+       /* Ignore errors in PIO/PBC on systems with unordered write-combining */
+       if (ipath_unordered_wc())
+               dd->ipath_eep_st_masks[0].hwerrs_to_log &= ~TXE_PIO_PARITY;
+
+       dd->ipath_eep_st_masks[1].hwerrs_to_log =
+               INFINIPATH_HWE_RXEMEMPARITYERR_MASK <<
+               INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT;
+
+       dd->ipath_eep_st_masks[2].errs_to_log =
+               INFINIPATH_E_INVALIDADDR | INFINIPATH_E_RESET;
+
+
 }
 
 /* setup the MSI stuff again after a reset.  I'd like to just call
@@ -1082,7 +1106,7 @@ bail:
  * ipath_pe_put_tid - write a TID in chip
  * @dd: the infinipath device
  * @tidptr: pointer to the expected TID (in chip) to udpate
- * @tidtype: 0 for eager, 1 for expected
+ * @tidtype: RCVHQ_RCV_TYPE_EAGER (1) for eager, RCVHQ_RCV_TYPE_EXPECTED (0) for expected
  * @pa: physical address of in memory buffer; ipath_tidinvalid if freeing
  *
  * This exists as a separate routine to allow for special locking etc.
@@ -1108,7 +1132,7 @@ static void ipath_pe_put_tid(struct ipath_devdata *dd, u64 __iomem *tidptr,
                                      "BUG: Physical page address 0x%lx "
                                      "has bits set in 31-29\n", pa);
 
-               if (type == 0)
+               if (type == RCVHQ_RCV_TYPE_EAGER)
                        pa |= dd->ipath_tidtemplate;
                else /* for now, always full 4KB page */
                        pa |= 2 << 29;
@@ -1132,7 +1156,7 @@ static void ipath_pe_put_tid(struct ipath_devdata *dd, u64 __iomem *tidptr,
  * ipath_pe_put_tid_2 - write a TID in chip, Revision 2 or higher
  * @dd: the infinipath device
  * @tidptr: pointer to the expected TID (in chip) to udpate
- * @tidtype: 0 for eager, 1 for expected
+ * @tidtype: RCVHQ_RCV_TYPE_EAGER (1) for eager, RCVHQ_RCV_TYPE_EXPECTED (0) for expected
  * @pa: physical address of in memory buffer; ipath_tidinvalid if freeing
  *
  * This exists as a separate routine to allow for selection of the
@@ -1157,7 +1181,7 @@ static void ipath_pe_put_tid_2(struct ipath_devdata *dd, u64 __iomem *tidptr,
                                      "BUG: Physical page address 0x%lx "
                                      "has bits set in 31-29\n", pa);
 
-               if (type == 0)
+               if (type == RCVHQ_RCV_TYPE_EAGER)
                        pa |= dd->ipath_tidtemplate;
                else /* for now, always full 4KB page */
                        pa |= 2 << 29;
@@ -1196,7 +1220,8 @@ static void ipath_pe_clear_tids(struct ipath_devdata *dd, unsigned port)
                 port * dd->ipath_rcvtidcnt * sizeof(*tidbase));
 
        for (i = 0; i < dd->ipath_rcvtidcnt; i++)
-               ipath_pe_put_tid(dd, &tidbase[i], 0, tidinv);
+               ipath_pe_put_tid(dd, &tidbase[i], RCVHQ_RCV_TYPE_EXPECTED,
+                                tidinv);
 
        tidbase = (u64 __iomem *)
                ((char __iomem *)(dd->ipath_kregbase) +
@@ -1204,7 +1229,8 @@ static void ipath_pe_clear_tids(struct ipath_devdata *dd, unsigned port)
                 port * dd->ipath_rcvegrcnt * sizeof(*tidbase));
 
        for (i = 0; i < dd->ipath_rcvegrcnt; i++)
-               ipath_pe_put_tid(dd, &tidbase[i], 1, tidinv);
+               ipath_pe_put_tid(dd, &tidbase[i], RCVHQ_RCV_TYPE_EAGER,
+                                tidinv);
 }
 
 /**
@@ -1311,13 +1337,6 @@ static int ipath_pe_get_base_info(struct ipath_portdata *pd, void *kbase)
 
        dd = pd->port_dd;
 
-       if (dd != NULL && dd->ipath_minrev >= 2) {
-               ipath_cdbg(PROC, "IBA6120 Rev2, allow multiple PBC write\n");
-               kinfo->spi_runtime_flags |= IPATH_RUNTIME_PBC_REWRITE;
-               ipath_cdbg(PROC, "IBA6120 Rev2, allow loose DMA alignment\n");
-               kinfo->spi_runtime_flags |= IPATH_RUNTIME_LOOSE_DMA_ALIGN;
-       }
-
 done:
        kinfo->spi_runtime_flags |= IPATH_RUNTIME_PCIE;
        return 0;
@@ -1354,7 +1373,6 @@ static int ipath_pe_txe_recover(struct ipath_devdata *dd)
                dev_info(&dd->pcidev->dev,
                        "Recovering from TXE PIO parity error\n");
        }
-       ipath_disarm_senderrbufs(dd, 1);
        return 1;
 }
 
index 7045ba6894944dd3f1a593661ef083b74069bb6d..49951d5838049349df8ca39237365deb90525fbd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 QLogic, Inc. All rights reserved.
+ * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
  * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -133,7 +133,8 @@ static int create_port0_egr(struct ipath_devdata *dd)
                                   dd->ipath_ibmaxlen, PCI_DMA_FROMDEVICE);
                dd->ipath_f_put_tid(dd, e + (u64 __iomem *)
                                    ((char __iomem *) dd->ipath_kregbase +
-                                    dd->ipath_rcvegrbase), 0,
+                                    dd->ipath_rcvegrbase),
+                                   RCVHQ_RCV_TYPE_EAGER,
                                    dd->ipath_port0_skbinfo[e].phys);
        }
 
@@ -310,7 +311,12 @@ static int init_chip_first(struct ipath_devdata *dd,
        val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_sendpiosize);
        dd->ipath_piosize2k = val & ~0U;
        dd->ipath_piosize4k = val >> 32;
-       dd->ipath_ibmtu = 4096; /* default to largest legal MTU */
+       /*
+        * Note: the chips support a maximum MTU of 4096, but the driver
+        * hasn't implemented this feature yet, so set the initial value
+        * to 2048.
+        */
+       dd->ipath_ibmtu = 2048;
        val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_sendpiobufcnt);
        dd->ipath_piobcnt2k = val & ~0U;
        dd->ipath_piobcnt4k = val >> 32;
@@ -340,6 +346,10 @@ static int init_chip_first(struct ipath_devdata *dd,
 
        spin_lock_init(&dd->ipath_tid_lock);
 
+       spin_lock_init(&dd->ipath_gpio_lock);
+       spin_lock_init(&dd->ipath_eep_st_lock);
+       sema_init(&dd->ipath_eep_sem, 1);
+
 done:
        *pdp = pd;
        return ret;
@@ -646,7 +656,7 @@ static int init_housekeeping(struct ipath_devdata *dd,
        ret = dd->ipath_f_get_boardname(dd, boardn, sizeof boardn);
 
        snprintf(dd->ipath_boardversion, sizeof(dd->ipath_boardversion),
-                "Driver %u.%u, %s, InfiniPath%u %u.%u, PCI %u, "
+                "ChipABI %u.%u, %s, InfiniPath%u %u.%u, PCI %u, "
                 "SW Compat %u\n",
                 IPATH_CHIP_VERS_MAJ, IPATH_CHIP_VERS_MIN, boardn,
                 (unsigned)(dd->ipath_revision >> INFINIPATH_R_ARCH_SHIFT) &
@@ -727,7 +737,7 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit)
        uports = dd->ipath_cfgports ? dd->ipath_cfgports - 1 : 0;
        if (ipath_kpiobufs == 0) {
                /* not set by user (this is default) */
-               if (piobufs >= (uports * IPATH_MIN_USER_PORT_BUFCNT) + 32)
+               if (piobufs > 144)
                        kpiobufs = 32;
                else
                        kpiobufs = 16;
@@ -767,6 +777,12 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit)
                   piobufs, dd->ipath_pbufsport, uports);
 
        dd->ipath_f_early_init(dd);
+       /*
+        * cancel any possible active sends from early driver load.
+        * Follows early_init because some chips have to initialize
+        * PIO buffers in early_init to avoid false parity errors.
+        */
+       ipath_cancel_sends(dd);
 
        /* early_init sets rcvhdrentsize and rcvhdrsize, so this must be
         * done after early_init */
index a90d3b5699c46cc1169faf99ef3c72fbc4a92772..47aa43428fbf90b1284b6af4dee729debdc976bd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 QLogic, Inc. All rights reserved.
+ * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
  * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -93,7 +93,8 @@ void ipath_disarm_senderrbufs(struct ipath_devdata *dd, int rewrite)
 
        if (sbuf[0] || sbuf[1] || (piobcnt > 128 && (sbuf[2] || sbuf[3]))) {
                int i;
-               if (ipath_debug & (__IPATH_PKTDBG|__IPATH_DBG)) {
+               if (ipath_debug & (__IPATH_PKTDBG|__IPATH_DBG) &&
+                       dd->ipath_lastcancel > jiffies) {
                        __IPATH_DBG_WHICH(__IPATH_PKTDBG|__IPATH_DBG,
                                          "SendbufErrs %lx %lx", sbuf[0],
                                          sbuf[1]);
@@ -108,7 +109,8 @@ void ipath_disarm_senderrbufs(struct ipath_devdata *dd, int rewrite)
                                        ipath_clrpiobuf(dd, i);
                                ipath_disarm_piobufs(dd, i, 1);
                        }
-               dd->ipath_lastcancel = jiffies+3; /* no armlaunch for a bit */
+               /* ignore armlaunch errs for a bit */
+               dd->ipath_lastcancel = jiffies+3;
        }
 }
 
@@ -130,6 +132,17 @@ void ipath_disarm_senderrbufs(struct ipath_devdata *dd, int rewrite)
         INFINIPATH_E_SMINPKTLEN | INFINIPATH_E_SPKTLEN | \
         INFINIPATH_E_INVALIDADDR)
 
+/*
+ * this is similar to E_SUM_ERRS, but can't ignore armlaunch, don't ignore
+ * errors not related to freeze and cancelling buffers.  Can't ignore
+ * armlaunch because could get more while still cleaning up, and need
+ * to cancel those as they happen.
+ */
+#define E_SPKT_ERRS_IGNORE \
+        (INFINIPATH_E_SDROPPEDDATAPKT | INFINIPATH_E_SDROPPEDSMPPKT | \
+        INFINIPATH_E_SMAXPKTLEN | INFINIPATH_E_SMINPKTLEN | \
+        INFINIPATH_E_SPKTLEN)
+
 /*
  * these are errors that can occur when the link changes state while
  * a packet is being sent or received.  This doesn't cover things
@@ -290,12 +303,7 @@ static void handle_e_ibstatuschanged(struct ipath_devdata *dd,
                 * Flush all queued sends when link went to DOWN or INIT,
                 * to be sure that they don't block SMA and other MAD packets
                 */
-               ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
-                                INFINIPATH_S_ABORT);
-               ipath_disarm_piobufs(dd, dd->ipath_lastport_piobuf,
-                                                       (unsigned)(dd->ipath_piobcnt2k +
-                                       dd->ipath_piobcnt4k) -
-                                       dd->ipath_lastport_piobuf);
+               ipath_cancel_sends(dd);
        }
        else if (lstate == IPATH_IBSTATE_INIT || lstate == IPATH_IBSTATE_ARM ||
            lstate == IPATH_IBSTATE_ACTIVE) {
@@ -505,6 +513,7 @@ static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs)
        int i, iserr = 0;
        int chkerrpkts = 0, noprint = 0;
        unsigned supp_msgs;
+       int log_idx;
 
        supp_msgs = handle_frequent_errors(dd, errs, msg, &noprint);
 
@@ -518,6 +527,13 @@ static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs)
        if (errs & INFINIPATH_E_HARDWARE) {
                /* reuse same msg buf */
                dd->ipath_f_handle_hwerrors(dd, msg, sizeof msg);
+       } else {
+               u64 mask;
+               for (log_idx = 0; log_idx < IPATH_EEP_LOG_CNT; ++log_idx) {
+                       mask = dd->ipath_eep_st_masks[log_idx].errs_to_log;
+                       if (errs & mask)
+                               ipath_inc_eeprom_err(dd, log_idx, 1);
+               }
        }
 
        if (!noprint && (errs & ~dd->ipath_e_bitsextant))
@@ -675,6 +691,17 @@ static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs)
                                        chkerrpkts = 1;
                                dd->ipath_lastrcvhdrqtails[i] = tl;
                                pd->port_hdrqfull++;
+                               if (test_bit(IPATH_PORT_WAITING_OVERFLOW,
+                                            &pd->port_flag)) {
+                                       clear_bit(
+                                         IPATH_PORT_WAITING_OVERFLOW,
+                                         &pd->port_flag);
+                                       set_bit(
+                                         IPATH_PORT_WAITING_OVERFLOW,
+                                         &pd->int_flag);
+                                       wake_up_interruptible(
+                                         &pd->port_wait);
+                               }
                        }
                }
        }
@@ -744,6 +771,72 @@ static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs)
        return chkerrpkts;
 }
 
+
+/*
+ * try to cleanup as much as possible for anything that might have gone
+ * wrong while in freeze mode, such as pio buffers being written by user
+ * processes (causing armlaunch), send errors due to going into freeze mode,
+ * etc., and try to avoid causing extra interrupts while doing so.
+ * Forcibly update the in-memory pioavail register copies after cleanup
+ * because the chip won't do it for anything changing while in freeze mode
+ * (we don't want to wait for the next pio buffer state change).
+ * Make sure that we don't lose any important interrupts by using the chip
+ * feature that says that writing 0 to a bit in *clear that is set in
+ * *status will cause an interrupt to be generated again (if allowed by
+ * the *mask value).
+ */
+void ipath_clear_freeze(struct ipath_devdata *dd)
+{
+       int i, im;
+       __le64 val;
+
+       /* disable error interrupts, to avoid confusion */
+       ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, 0ULL);
+
+       /*
+        * clear all sends, because they have may been
+        * completed by usercode while in freeze mode, and
+        * therefore would not be sent, and eventually
+        * might cause the process to run out of bufs
+        */
+       ipath_cancel_sends(dd);
+       ipath_write_kreg(dd, dd->ipath_kregs->kr_control,
+                        dd->ipath_control);
+
+       /* ensure pio avail updates continue */
+       ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
+                dd->ipath_sendctrl & ~IPATH_S_PIOBUFAVAILUPD);
+       ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
+       ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
+                dd->ipath_sendctrl);
+
+       /*
+        * We just enabled pioavailupdate, so dma copy is almost certainly
+        * not yet right, so read the registers directly.  Similar to init
+        */
+       for (i = 0; i < dd->ipath_pioavregs; i++) {
+               /* deal with 6110 chip bug */
+               im = i > 3 ? ((i&1) ? i-1 : i+1) : i;
+               val = ipath_read_kreg64(dd, 0x1000+(im*sizeof(u64)));
+               dd->ipath_pioavailregs_dma[i] = dd->ipath_pioavailshadow[i]
+                       = le64_to_cpu(val);
+       }
+
+       /*
+        * force new interrupt if any hwerr, error or interrupt bits are
+        * still set, and clear "safe" send packet errors related to freeze
+        * and cancelling sends.  Re-enable error interrupts before possible
+        * force of re-interrupt on pending interrupts.
+        */
+       ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrclear, 0ULL);
+       ipath_write_kreg(dd, dd->ipath_kregs->kr_errorclear,
+               E_SPKT_ERRS_IGNORE);
+       ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask,
+               ~dd->ipath_maskederrs);
+       ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, 0ULL);
+}
+
+
 /* this is separate to allow for better optimization of ipath_intr() */
 
 static void ipath_bad_intr(struct ipath_devdata *dd, u32 * unexpectp)
@@ -872,14 +965,25 @@ static void handle_urcv(struct ipath_devdata *dd, u32 istat)
                   dd->ipath_i_rcvurg_mask);
        for (i = 1; i < dd->ipath_cfgports; i++) {
                struct ipath_portdata *pd = dd->ipath_pd[i];
-               if (portr & (1 << i) && pd && pd->port_cnt &&
-                       test_bit(IPATH_PORT_WAITING_RCV, &pd->port_flag)) {
-                       clear_bit(IPATH_PORT_WAITING_RCV,
-                                 &pd->port_flag);
-                       clear_bit(i + INFINIPATH_R_INTRAVAIL_SHIFT,
-                                 &dd->ipath_rcvctrl);
-                       wake_up_interruptible(&pd->port_wait);
-                       rcvdint = 1;
+               if (portr & (1 << i) && pd && pd->port_cnt) {
+                       if (test_bit(IPATH_PORT_WAITING_RCV,
+                                    &pd->port_flag)) {
+                               clear_bit(IPATH_PORT_WAITING_RCV,
+                                         &pd->port_flag);
+                               set_bit(IPATH_PORT_WAITING_RCV,
+                                       &pd->int_flag);
+                               clear_bit(i + INFINIPATH_R_INTRAVAIL_SHIFT,
+                                         &dd->ipath_rcvctrl);
+                               wake_up_interruptible(&pd->port_wait);
+                               rcvdint = 1;
+                       } else if (test_bit(IPATH_PORT_WAITING_URG,
+                                           &pd->port_flag)) {
+                               clear_bit(IPATH_PORT_WAITING_URG,
+                                         &pd->port_flag);
+                               set_bit(IPATH_PORT_WAITING_URG,
+                                       &pd->int_flag);
+                               wake_up_interruptible(&pd->port_wait);
+                       }
                }
        }
        if (rcvdint) {
@@ -905,6 +1009,9 @@ irqreturn_t ipath_intr(int irq, void *data)
 
        ipath_stats.sps_ints++;
 
+       if (dd->ipath_int_counter != (u32) -1)
+               dd->ipath_int_counter++;
+
        if (!(dd->ipath_flags & IPATH_PRESENT)) {
                /*
                 * This return value is not great, but we do not want the
index 12194f3dd8cc2b12c9909a3e212b7f8a06c5b93b..3105005fc9d25d0dfd84a5afb93dae7dd6a8bf4a 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef _IPATH_KERNEL_H
 #define _IPATH_KERNEL_H
 /*
- * Copyright (c) 2006 QLogic, Inc. All rights reserved.
+ * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
  * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
 extern struct infinipath_stats ipath_stats;
 
 #define IPATH_CHIP_SWVERSION IPATH_CHIP_VERS_MAJ
+/*
+ * First-cut critierion for "device is active" is
+ * two thousand dwords combined Tx, Rx traffic per
+ * 5-second interval. SMA packets are 64 dwords,
+ * and occur "a few per second", presumably each way.
+ */
+#define IPATH_TRAFFIC_ACTIVE_THRESHOLD (2000)
+/*
+ * Struct used to indicate which errors are logged in each of the
+ * error-counters that are logged to EEPROM. A counter is incremented
+ * _once_ (saturating at 255) for each event with any bits set in
+ * the error or hwerror register masks below.
+ */
+#define IPATH_EEP_LOG_CNT (4)
+struct ipath_eep_log_mask {
+       u64 errs_to_log;
+       u64 hwerrs_to_log;
+};
 
 struct ipath_portdata {
        void **port_rcvegrbuf;
@@ -109,6 +127,8 @@ struct ipath_portdata {
        u32 port_tidcursor;
        /* next expected TID to check */
        unsigned long port_flag;
+       /* what happened */
+       unsigned long int_flag;
        /* WAIT_RCV that timed out, no interrupt */
        u32 port_rcvwait_to;
        /* WAIT_PIO that timed out, no interrupt */
@@ -137,6 +157,8 @@ struct ipath_portdata {
        u32 userversion;
        /* Bitmask of active slaves */
        u32 active_slaves;
+       /* Type of packets or conditions we want to poll for */
+       u16 poll_type;
 };
 
 struct sk_buff;
@@ -275,6 +297,8 @@ struct ipath_devdata {
        u32 ipath_lastport_piobuf;
        /* is a stats timer active */
        u32 ipath_stats_timer_active;
+       /* number of interrupts for this device -- saturates... */
+       u32 ipath_int_counter;
        /* dwords sent read from counter */
        u32 ipath_lastsword;
        /* dwords received read from counter */
@@ -369,9 +393,6 @@ struct ipath_devdata {
        struct class_device *diag_class_dev;
        /* timer used to prevent stats overflow, error throttling, etc. */
        struct timer_list ipath_stats_timer;
-       /* check for stale messages in rcv queue */
-       /* only allow one intr at a time. */
-       unsigned long ipath_rcv_pending;
        void *ipath_dummy_hdrq; /* used after port close */
        dma_addr_t ipath_dummy_hdrq_phys;
 
@@ -399,6 +420,8 @@ struct ipath_devdata {
        u64 ipath_gpio_out;
        /* shadow the gpio mask register */
        u64 ipath_gpio_mask;
+       /* shadow the gpio output enable, etc... */
+       u64 ipath_extctrl;
        /* kr_revision shadow */
        u64 ipath_revision;
        /*
@@ -473,8 +496,6 @@ struct ipath_devdata {
        u32 ipath_cregbase;
        /* shadow the control register contents */
        u32 ipath_control;
-       /* shadow the gpio output contents */
-       u32 ipath_extctrl;
        /* PCI revision register (HTC rev on FPGA) */
        u32 ipath_pcirev;
 
@@ -552,6 +573,9 @@ struct ipath_devdata {
        u32 ipath_overrun_thresh_errs;
        u32 ipath_lli_errs;
 
+       /* status check work */
+       struct delayed_work status_work;
+
        /*
         * Not all devices managed by a driver instance are the same
         * type, so these fields must be per-device.
@@ -575,6 +599,37 @@ struct ipath_devdata {
        u16 ipath_gpio_scl_num;
        u64 ipath_gpio_sda;
        u64 ipath_gpio_scl;
+
+       /* lock for doing RMW of shadows/regs for ExtCtrl and GPIO */
+       spinlock_t ipath_gpio_lock;
+
+       /* used to override LED behavior */
+       u8 ipath_led_override;  /* Substituted for normal value, if non-zero */
+       u16 ipath_led_override_timeoff; /* delta to next timer event */
+       u8 ipath_led_override_vals[2]; /* Alternates per blink-frame */
+       u8 ipath_led_override_phase; /* Just counts, LSB picks from vals[] */
+       atomic_t ipath_led_override_timer_active;
+       /* Used to flash LEDs in override mode */
+       struct timer_list ipath_led_override_timer;
+
+       /* Support (including locks) for EEPROM logging of errors and time */
+       /* control access to actual counters, timer */
+       spinlock_t ipath_eep_st_lock;
+       /* control high-level access to EEPROM */
+       struct semaphore ipath_eep_sem;
+       /* Below inc'd by ipath_snap_cntrs(), locked by ipath_eep_st_lock */
+       uint64_t ipath_traffic_wds;
+       /* active time is kept in seconds, but logged in hours */
+       atomic_t ipath_active_time;
+       /* Below are nominal shadow of EEPROM, new since last EEPROM update */
+       uint8_t ipath_eep_st_errs[IPATH_EEP_LOG_CNT];
+       uint8_t ipath_eep_st_new_errs[IPATH_EEP_LOG_CNT];
+       uint16_t ipath_eep_hrs;
+       /*
+        * masks for which bits of errs, hwerrs that cause
+        * each of the counters to increment.
+        */
+       struct ipath_eep_log_mask ipath_eep_st_masks[IPATH_EEP_LOG_CNT];
 };
 
 /* Private data for file operations */
@@ -592,6 +647,7 @@ int ipath_enable_wc(struct ipath_devdata *dd);
 void ipath_disable_wc(struct ipath_devdata *dd);
 int ipath_count_units(int *npresentp, int *nupp, u32 *maxportsp);
 void ipath_shutdown_device(struct ipath_devdata *);
+void ipath_clear_freeze(struct ipath_devdata *);
 
 struct file_operations;
 int ipath_cdev_init(int minor, char *name, const struct file_operations *fops,
@@ -627,6 +683,7 @@ int ipath_unordered_wc(void);
 
 void ipath_disarm_piobufs(struct ipath_devdata *, unsigned first,
                          unsigned cnt);
+void ipath_cancel_sends(struct ipath_devdata *);
 
 int ipath_create_rcvhdrq(struct ipath_devdata *, struct ipath_portdata *);
 void ipath_free_pddata(struct ipath_devdata *, struct ipath_portdata *);
@@ -685,7 +742,6 @@ int ipath_set_rx_pol_inv(struct ipath_devdata *dd, u8 new_pol_inv);
                 * are 64bit */
 #define IPATH_32BITCOUNTERS 0x20000
                /* can miss port0 rx interrupts */
-#define IPATH_POLL_RX_INTR  0x40000
 #define IPATH_DISABLED      0x80000 /* administratively disabled */
                /* Use GPIO interrupts for new counters */
 #define IPATH_GPIO_ERRINTRS 0x100000
@@ -704,6 +760,10 @@ int ipath_set_rx_pol_inv(struct ipath_devdata *dd, u8 new_pol_inv);
 #define IPATH_PORT_WAITING_PIO   3
                /* master has not finished initializing */
 #define IPATH_PORT_MASTER_UNINIT 4
+               /* waiting for an urgent packet to arrive */
+#define IPATH_PORT_WAITING_URG 5
+               /* waiting for a header overflow */
+#define IPATH_PORT_WAITING_OVERFLOW 6
 
 /* free up any allocated data at closes */
 void ipath_free_data(struct ipath_portdata *dd);
@@ -713,9 +773,20 @@ u32 __iomem *ipath_getpiobuf(struct ipath_devdata *, u32 *);
 void ipath_init_iba6120_funcs(struct ipath_devdata *);
 void ipath_init_iba6110_funcs(struct ipath_devdata *);
 void ipath_get_eeprom_info(struct ipath_devdata *);
+int ipath_update_eeprom_log(struct ipath_devdata *dd);
+void ipath_inc_eeprom_err(struct ipath_devdata *dd, u32 eidx, u32 incr);
 u64 ipath_snap_cntr(struct ipath_devdata *, ipath_creg);
 void ipath_disarm_senderrbufs(struct ipath_devdata *, int);
 
+/*
+ * Set LED override, only the two LSBs have "public" meaning, but
+ * any non-zero value substitutes them for the Link and LinkTrain
+ * LED states.
+ */
+#define IPATH_LED_PHYS 1 /* Physical (linktraining) GREEN LED */
+#define IPATH_LED_LOG 2  /* Logical (link) YELLOW LED */
+void ipath_set_led_override(struct ipath_devdata *dd, unsigned int val);
+
 /*
  * number of words used for protocol header if not set by ipath_userinit();
  */
index dd487c100f5ba06865ef0bea3904b05a6520ca0c..85a4aefc6c03cbbb94f63af4eade1f92a36f91fe 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 QLogic, Inc. All rights reserved.
+ * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
  * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
index 05a1d2b01d9dae8be479e912bbc98a5c5e1a83c4..82616b779e2452e6b2fbaaf0cc101c9f5889298b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 QLogic, Inc. All rights reserved.
+ * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
  * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
index 3854a4eae68479a75fb614d6807ffae1009946f9..415709c4d85b777dcabc0ae45ee613d51c72d5e7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 QLogic, Inc. All rights reserved.
+ * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
  * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
index 25908b02fbe578f57fd6ee7128ea0c9b22169f32..d61c030445451076f1d3fae4d01cde99f034cb44 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 QLogic, Inc. All rights reserved.
+ * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
  * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -103,7 +103,7 @@ static int recv_subn_get_nodeinfo(struct ib_smp *smp,
        /* This is already in network order */
        nip->sys_guid = to_idev(ibdev)->sys_image_guid;
        nip->node_guid = dd->ipath_guid;
-       nip->port_guid = nip->sys_guid;
+       nip->port_guid = dd->ipath_guid;
        nip->partition_cap = cpu_to_be16(ipath_get_npkeys(dd));
        nip->device_id = cpu_to_be16(dd->ipath_deviceid);
        majrev = dd->ipath_majrev;
@@ -292,7 +292,12 @@ static int recv_subn_get_portinfo(struct ib_smp *smp,
        /* pip->vl_arb_high_cap; // only one VL */
        /* pip->vl_arb_low_cap; // only one VL */
        /* InitTypeReply = 0 */
-       pip->inittypereply_mtucap = IB_MTU_4096;
+       /*
+        * Note: the chips support a maximum MTU of 4096, but the driver
+        * hasn't implemented this feature yet, so set the maximum value
+        * to 2048.
+        */
+       pip->inittypereply_mtucap = IB_MTU_2048;
        // HCAs ignore VLStallCount and HOQLife
        /* pip->vlstallcnt_hoqlife; */
        pip->operationalvl_pei_peo_fpi_fpo = 0x10;      /* OVLs = 1 */
index 937bc3396b534420ce90a51f9dd1fe822483738b..fa830e22002fc09d9bcea91f0b908b60558d60f7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 QLogic, Inc. All rights reserved.
+ * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
index bdeef8d4f279cb5abb8c5954e15dda65a461128d..e442470a23755ff87947434abc21ff39a2d54158 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 QLogic, Inc. All rights reserved.
+ * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
  * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
index bfef08ecd342561b0d1272766564f43a700b1b2a..1324b35ff1f855b460e1a62723cd8f95a1023838 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 QLogic, Inc. All rights reserved.
+ * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
  * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -336,7 +336,7 @@ static void ipath_reset_qp(struct ipath_qp *qp)
        qp->qkey = 0;
        qp->qp_access_flags = 0;
        qp->s_busy = 0;
-       qp->s_flags &= ~IPATH_S_SIGNAL_REQ_WR;
+       qp->s_flags &= IPATH_S_SIGNAL_REQ_WR;
        qp->s_hdrwords = 0;
        qp->s_psn = 0;
        qp->r_psn = 0;
@@ -507,16 +507,13 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
                    attr->port_num > ibqp->device->phys_port_cnt)
                        goto inval;
 
+       /*
+        * Note: the chips support a maximum MTU of 4096, but the driver
+        * hasn't implemented this feature yet, so don't allow Path MTU
+        * values greater than 2048.
+        */
        if (attr_mask & IB_QP_PATH_MTU)
-               if (attr->path_mtu > IB_MTU_4096)
-                       goto inval;
-
-       if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC)
-               if (attr->max_dest_rd_atomic > 1)
-                       goto inval;
-
-       if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC)
-               if (attr->max_rd_atomic > 1)
+               if (attr->path_mtu > IB_MTU_2048)
                        goto inval;
 
        if (attr_mask & IB_QP_PATH_MIG_STATE)
index 1915771fd038ebaf6204f46b3fcc6ef2e1ffee55..46744ea2babdb336510b3772ed7dfd9fb6d8608c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 QLogic, Inc. All rights reserved.
+ * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
  * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -125,8 +125,10 @@ static int ipath_make_rc_ack(struct ipath_qp *qp,
                        if (len > pmtu) {
                                len = pmtu;
                                qp->s_ack_state = OP(RDMA_READ_RESPONSE_FIRST);
-                       } else
+                       } else {
                                qp->s_ack_state = OP(RDMA_READ_RESPONSE_ONLY);
+                               e->sent = 1;
+                       }
                        ohdr->u.aeth = ipath_compute_aeth(qp);
                        hwords++;
                        qp->s_ack_rdma_psn = e->psn;
@@ -143,6 +145,7 @@ static int ipath_make_rc_ack(struct ipath_qp *qp,
                                cpu_to_be32(e->atomic_data);
                        hwords += sizeof(ohdr->u.at) / sizeof(u32);
                        bth2 = e->psn;
+                       e->sent = 1;
                }
                bth0 = qp->s_ack_state << 24;
                break;
@@ -158,6 +161,7 @@ static int ipath_make_rc_ack(struct ipath_qp *qp,
                        ohdr->u.aeth = ipath_compute_aeth(qp);
                        hwords++;
                        qp->s_ack_state = OP(RDMA_READ_RESPONSE_LAST);
+                       qp->s_ack_queue[qp->s_tail_ack_queue].sent = 1;
                }
                bth0 = qp->s_ack_state << 24;
                bth2 = qp->s_ack_rdma_psn++ & IPATH_PSN_MASK;
@@ -188,7 +192,7 @@ static int ipath_make_rc_ack(struct ipath_qp *qp,
        }
        qp->s_hdrwords = hwords;
        qp->s_cur_size = len;
-       *bth0p = bth0;
+       *bth0p = bth0 | (1 << 22); /* Set M bit */
        *bth2p = bth2;
        return 1;
 
@@ -240,7 +244,7 @@ int ipath_make_rc_req(struct ipath_qp *qp,
 
        /* header size in 32-bit words LRH+BTH = (8+12)/4. */
        hwords = 5;
-       bth0 = 0;
+       bth0 = 1 << 22; /* Set M bit */
 
        /* Send a request. */
        wqe = get_swqe_ptr(qp, qp->s_cur);
@@ -604,7 +608,7 @@ static void send_rc_ack(struct ipath_qp *qp)
        }
        /* read pkey_index w/o lock (its atomic) */
        bth0 = ipath_get_pkey(dev->dd, qp->s_pkey_index) |
-               OP(ACKNOWLEDGE) << 24;
+               (OP(ACKNOWLEDGE) << 24) | (1 << 22);
        if (qp->r_nak_state)
                ohdr->u.aeth = cpu_to_be32((qp->r_msn & IPATH_MSN_MASK) |
                                            (qp->r_nak_state <<
@@ -806,13 +810,15 @@ static inline void update_last_psn(struct ipath_qp *qp, u32 psn)
  * Called at interrupt level with the QP s_lock held and interrupts disabled.
  * Returns 1 if OK, 0 if current operation should be aborted (NAK).
  */
-static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode)
+static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode,
+                    u64 val)
 {
        struct ipath_ibdev *dev = to_idev(qp->ibqp.device);
        struct ib_wc wc;
        struct ipath_swqe *wqe;
        int ret = 0;
        u32 ack_psn;
+       int diff;
 
        /*
         * Remove the QP from the timeout queue (or RNR timeout queue).
@@ -840,7 +846,19 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode)
         * The MSN might be for a later WQE than the PSN indicates so
         * only complete WQEs that the PSN finishes.
         */
-       while (ipath_cmp24(ack_psn, wqe->lpsn) >= 0) {
+       while ((diff = ipath_cmp24(ack_psn, wqe->lpsn)) >= 0) {
+               /*
+                * RDMA_READ_RESPONSE_ONLY is a special case since
+                * we want to generate completion events for everything
+                * before the RDMA read, copy the data, then generate
+                * the completion for the read.
+                */
+               if (wqe->wr.opcode == IB_WR_RDMA_READ &&
+                   opcode == OP(RDMA_READ_RESPONSE_ONLY) &&
+                   diff == 0) {
+                       ret = 1;
+                       goto bail;
+               }
                /*
                 * If this request is a RDMA read or atomic, and the ACK is
                 * for a later operation, this ACK NAKs the RDMA read or
@@ -851,12 +869,10 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode)
                 * is sent but before the response is received.
                 */
                if ((wqe->wr.opcode == IB_WR_RDMA_READ &&
-                    (opcode != OP(RDMA_READ_RESPONSE_LAST) ||
-                     ipath_cmp24(ack_psn, wqe->lpsn) != 0)) ||
+                    (opcode != OP(RDMA_READ_RESPONSE_LAST) || diff != 0)) ||
                    ((wqe->wr.opcode == IB_WR_ATOMIC_CMP_AND_SWP ||
                      wqe->wr.opcode == IB_WR_ATOMIC_FETCH_AND_ADD) &&
-                    (opcode != OP(ATOMIC_ACKNOWLEDGE) ||
-                     ipath_cmp24(wqe->psn, psn) != 0))) {
+                    (opcode != OP(ATOMIC_ACKNOWLEDGE) || diff != 0))) {
                        /*
                         * The last valid PSN seen is the previous
                         * request's.
@@ -870,6 +886,9 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode)
                         */
                        goto bail;
                }
+               if (wqe->wr.opcode == IB_WR_ATOMIC_CMP_AND_SWP ||
+                   wqe->wr.opcode == IB_WR_ATOMIC_FETCH_AND_ADD)
+                       *(u64 *) wqe->sg_list[0].vaddr = val;
                if (qp->s_num_rd_atomic &&
                    (wqe->wr.opcode == IB_WR_RDMA_READ ||
                     wqe->wr.opcode == IB_WR_ATOMIC_CMP_AND_SWP ||
@@ -1079,6 +1098,7 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev,
        int diff;
        u32 pad;
        u32 aeth;
+       u64 val;
 
        spin_lock_irqsave(&qp->s_lock, flags);
 
@@ -1118,8 +1138,6 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev,
                        data += sizeof(__be32);
                }
                if (opcode == OP(ATOMIC_ACKNOWLEDGE)) {
-                       u64 val;
-
                        if (!header_in_data) {
                                __be32 *p = ohdr->u.at.atomic_ack_eth;
 
@@ -1127,12 +1145,13 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev,
                                        be32_to_cpu(p[1]);
                        } else
                                val = be64_to_cpu(((__be64 *) data)[0]);
-                       *(u64 *) wqe->sg_list[0].vaddr = val;
-               }
-               if (!do_rc_ack(qp, aeth, psn, opcode) ||
+               } else
+                       val = 0;
+               if (!do_rc_ack(qp, aeth, psn, opcode, val) ||
                    opcode != OP(RDMA_READ_RESPONSE_FIRST))
                        goto ack_done;
                hdrsize += 4;
+               wqe = get_swqe_ptr(qp, qp->s_last);
                if (unlikely(wqe->wr.opcode != IB_WR_RDMA_READ))
                        goto ack_op_err;
                /*
@@ -1176,13 +1195,12 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev,
                goto bail;
 
        case OP(RDMA_READ_RESPONSE_ONLY):
-               if (unlikely(ipath_cmp24(psn, qp->s_last_psn + 1))) {
-                       dev->n_rdma_seq++;
-                       ipath_restart_rc(qp, qp->s_last_psn + 1, &wc);
+               if (!header_in_data)
+                       aeth = be32_to_cpu(ohdr->u.aeth);
+               else
+                       aeth = be32_to_cpu(((__be32 *) data)[0]);
+               if (!do_rc_ack(qp, aeth, psn, opcode, 0))
                        goto ack_done;
-               }
-               if (unlikely(wqe->wr.opcode != IB_WR_RDMA_READ))
-                       goto ack_op_err;
                /* Get the number of bytes the message was padded by. */
                pad = (be32_to_cpu(ohdr->bth[0]) >> 20) & 3;
                /*
@@ -1197,6 +1215,7 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev,
                 * have to be careful to copy the data to the right
                 * location.
                 */
+               wqe = get_swqe_ptr(qp, qp->s_last);
                qp->s_rdma_read_len = restart_sge(&qp->s_rdma_read_sge,
                                                  wqe, psn, pmtu);
                goto read_last;
@@ -1230,7 +1249,8 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev,
                        data += sizeof(__be32);
                }
                ipath_copy_sge(&qp->s_rdma_read_sge, data, tlen);
-               (void) do_rc_ack(qp, aeth, psn, OP(RDMA_READ_RESPONSE_LAST));
+               (void) do_rc_ack(qp, aeth, psn,
+                                OP(RDMA_READ_RESPONSE_LAST), 0);
                goto ack_done;
        }
 
@@ -1344,8 +1364,11 @@ static inline int ipath_rc_rcv_error(struct ipath_ibdev *dev,
                        e = NULL;
                        break;
                }
-               if (ipath_cmp24(psn, e->psn) >= 0)
+               if (ipath_cmp24(psn, e->psn) >= 0) {
+                       if (prev == qp->s_tail_ack_queue)
+                               old_req = 0;
                        break;
+               }
        }
        switch (opcode) {
        case OP(RDMA_READ_REQUEST): {
@@ -1460,6 +1483,22 @@ static void ipath_rc_error(struct ipath_qp *qp, enum ib_wc_status err)
        spin_unlock_irqrestore(&qp->s_lock, flags);
 }
 
+static inline void ipath_update_ack_queue(struct ipath_qp *qp, unsigned n)
+{
+       unsigned long flags;
+       unsigned next;
+
+       next = n + 1;
+       if (next > IPATH_MAX_RDMA_ATOMIC)
+               next = 0;
+       spin_lock_irqsave(&qp->s_lock, flags);
+       if (n == qp->s_tail_ack_queue) {
+               qp->s_tail_ack_queue = next;
+               qp->s_ack_state = OP(ACKNOWLEDGE);
+       }
+       spin_unlock_irqrestore(&qp->s_lock, flags);
+}
+
 /**
  * ipath_rc_rcv - process an incoming RC packet
  * @dev: the device this packet came in on
@@ -1672,6 +1711,9 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
        case OP(RDMA_WRITE_FIRST):
        case OP(RDMA_WRITE_ONLY):
        case OP(RDMA_WRITE_ONLY_WITH_IMMEDIATE):
+               if (unlikely(!(qp->qp_access_flags &
+                              IB_ACCESS_REMOTE_WRITE)))
+                       goto nack_inv;
                /* consume RWQE */
                /* RETH comes after BTH */
                if (!header_in_data)
@@ -1701,9 +1743,6 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
                        qp->r_sge.sge.length = 0;
                        qp->r_sge.sge.sge_length = 0;
                }
-               if (unlikely(!(qp->qp_access_flags &
-                              IB_ACCESS_REMOTE_WRITE)))
-                       goto nack_acc;
                if (opcode == OP(RDMA_WRITE_FIRST))
                        goto send_middle;
                else if (opcode == OP(RDMA_WRITE_ONLY))
@@ -1717,13 +1756,17 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
                u32 len;
                u8 next;
 
-               if (unlikely(!(qp->qp_access_flags & IB_ACCESS_REMOTE_READ)))
-                       goto nack_acc;
+               if (unlikely(!(qp->qp_access_flags &
+                              IB_ACCESS_REMOTE_READ)))
+                       goto nack_inv;
                next = qp->r_head_ack_queue + 1;
                if (next > IPATH_MAX_RDMA_ATOMIC)
                        next = 0;
-               if (unlikely(next == qp->s_tail_ack_queue))
-                       goto nack_inv;
+               if (unlikely(next == qp->s_tail_ack_queue)) {
+                       if (!qp->s_ack_queue[next].sent)
+                               goto nack_inv;
+                       ipath_update_ack_queue(qp, next);
+               }
                e = &qp->s_ack_queue[qp->r_head_ack_queue];
                /* RETH comes after BTH */
                if (!header_in_data)
@@ -1758,6 +1801,7 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
                        e->rdma_sge.sge.sge_length = 0;
                }
                e->opcode = opcode;
+               e->sent = 0;
                e->psn = psn;
                /*
                 * We need to increment the MSN here instead of when we
@@ -1789,12 +1833,15 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
 
                if (unlikely(!(qp->qp_access_flags &
                               IB_ACCESS_REMOTE_ATOMIC)))
-                       goto nack_acc;
+                       goto nack_inv;
                next = qp->r_head_ack_queue + 1;
                if (next > IPATH_MAX_RDMA_ATOMIC)
                        next = 0;
-               if (unlikely(next == qp->s_tail_ack_queue))
-                       goto nack_inv;
+               if (unlikely(next == qp->s_tail_ack_queue)) {
+                       if (!qp->s_ack_queue[next].sent)
+                               goto nack_inv;
+                       ipath_update_ack_queue(qp, next);
+               }
                if (!header_in_data)
                        ateth = &ohdr->u.atomic_eth;
                else
@@ -1819,6 +1866,7 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
                                      be64_to_cpu(ateth->compare_data),
                                      sdata);
                e->opcode = opcode;
+               e->sent = 0;
                e->psn = psn & IPATH_PSN_MASK;
                qp->r_msn++;
                qp->r_psn++;
index c182bcd62098cd180e4d73c7a4cecd41a3804ba3..708eba3165d764f0c54b45084bb1cfb927b5ff73 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 QLogic, Inc. All rights reserved.
+ * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
  * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
index d9c2a9b15d8686f27ae54e137ecb244ded1b3242..85256747d8a185223da6aaf4eab5dd8287d04908 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 QLogic, Inc. All rights reserved.
+ * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
  * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -194,6 +194,8 @@ int ipath_get_rwqe(struct ipath_qp *qp, int wr_id_only)
                        ret = 0;
                        goto bail;
                }
+               /* Make sure entry is read after head index is read. */
+               smp_rmb();
                wqe = get_rwqe_ptr(rq, tail);
                if (++tail >= rq->size)
                        tail = 0;
@@ -267,7 +269,7 @@ again:
        spin_lock_irqsave(&sqp->s_lock, flags);
 
        if (!(ib_ipath_state_ops[sqp->state] & IPATH_PROCESS_SEND_OK) ||
-           qp->s_rnr_timeout) {
+           sqp->s_rnr_timeout) {
                spin_unlock_irqrestore(&sqp->s_lock, flags);
                goto done;
        }
@@ -319,12 +321,22 @@ again:
                break;
 
        case IB_WR_RDMA_WRITE_WITH_IMM:
+               if (unlikely(!(qp->qp_access_flags &
+                              IB_ACCESS_REMOTE_WRITE))) {
+                       wc.status = IB_WC_REM_INV_REQ_ERR;
+                       goto err;
+               }
                wc.wc_flags = IB_WC_WITH_IMM;
                wc.imm_data = wqe->wr.imm_data;
                if (!ipath_get_rwqe(qp, 1))
                        goto rnr_nak;
                /* FALLTHROUGH */
        case IB_WR_RDMA_WRITE:
+               if (unlikely(!(qp->qp_access_flags &
+                              IB_ACCESS_REMOTE_WRITE))) {
+                       wc.status = IB_WC_REM_INV_REQ_ERR;
+                       goto err;
+               }
                if (wqe->length == 0)
                        break;
                if (unlikely(!ipath_rkey_ok(qp, &qp->r_sge, wqe->length,
@@ -354,8 +366,10 @@ again:
 
        case IB_WR_RDMA_READ:
                if (unlikely(!(qp->qp_access_flags &
-                              IB_ACCESS_REMOTE_READ)))
-                       goto acc_err;
+                              IB_ACCESS_REMOTE_READ))) {
+                       wc.status = IB_WC_REM_INV_REQ_ERR;
+                       goto err;
+               }
                if (unlikely(!ipath_rkey_ok(qp, &sqp->s_sge, wqe->length,
                                            wqe->wr.wr.rdma.remote_addr,
                                            wqe->wr.wr.rdma.rkey,
@@ -369,8 +383,10 @@ again:
        case IB_WR_ATOMIC_CMP_AND_SWP:
        case IB_WR_ATOMIC_FETCH_AND_ADD:
                if (unlikely(!(qp->qp_access_flags &
-                              IB_ACCESS_REMOTE_ATOMIC)))
-                       goto acc_err;
+                              IB_ACCESS_REMOTE_ATOMIC))) {
+                       wc.status = IB_WC_REM_INV_REQ_ERR;
+                       goto err;
+               }
                if (unlikely(!ipath_rkey_ok(qp, &qp->r_sge, sizeof(u64),
                                            wqe->wr.wr.atomic.remote_addr,
                                            wqe->wr.wr.atomic.rkey,
@@ -396,6 +412,8 @@ again:
 
                if (len > sge->length)
                        len = sge->length;
+               if (len > sge->sge_length)
+                       len = sge->sge_length;
                BUG_ON(len == 0);
                ipath_copy_sge(&qp->r_sge, sge->vaddr, len);
                sge->vaddr += len;
@@ -503,11 +521,9 @@ void ipath_no_bufs_available(struct ipath_qp *qp, struct ipath_ibdev *dev)
         * could be called.  If we are still in the tasklet function,
         * tasklet_hi_schedule() will not call us until the next time
         * tasklet_hi_schedule() is called.
-        * We clear the tasklet flag now since we are committing to return
-        * from the tasklet function.
+        * We leave the busy flag set so that another post send doesn't
+        * try to put the same QP on the piowait list again.
         */
-       clear_bit(IPATH_S_BUSY, &qp->s_busy);
-       tasklet_unlock(&qp->s_task);
        want_buffer(dev->dd);
        dev->n_piowait++;
 }
index 03acae66ba81a5e0512307f19688c8b18c038b09..40c36ec190167080784383f457dff4c541a21f71 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 QLogic, Inc. All rights reserved.
+ * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
  * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -80,6 +80,8 @@ int ipath_post_srq_receive(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
                wqe->num_sge = wr->num_sge;
                for (i = 0; i < wr->num_sge; i++)
                        wqe->sg_list[i] = wr->sg_list[i];
+               /* Make sure queue entry is written before the head index. */
+               smp_wmb();
                wq->head = next;
                spin_unlock_irqrestore(&srq->rq.lock, flags);
        }
index d8b5e4cefe250afe961018f219d980ec2eb79306..73ed17d031887cbf5da73d57ee92f0c8b6aeb457 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 QLogic, Inc. All rights reserved.
+ * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
  * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -55,6 +55,7 @@ u64 ipath_snap_cntr(struct ipath_devdata *dd, ipath_creg creg)
        u64 val64;
        unsigned long t0, t1;
        u64 ret;
+       unsigned long flags;
 
        t0 = jiffies;
        /* If fast increment counters are only 32 bits, snapshot them,
@@ -91,12 +92,18 @@ u64 ipath_snap_cntr(struct ipath_devdata *dd, ipath_creg creg)
        if (creg == dd->ipath_cregs->cr_wordsendcnt) {
                if (val != dd->ipath_lastsword) {
                        dd->ipath_sword += val - dd->ipath_lastsword;
+                       spin_lock_irqsave(&dd->ipath_eep_st_lock, flags);
+                       dd->ipath_traffic_wds += val - dd->ipath_lastsword;
+                       spin_unlock_irqrestore(&dd->ipath_eep_st_lock, flags);
                        dd->ipath_lastsword = val;
                }
                val64 = dd->ipath_sword;
        } else if (creg == dd->ipath_cregs->cr_wordrcvcnt) {
                if (val != dd->ipath_lastrword) {
                        dd->ipath_rword += val - dd->ipath_lastrword;
+                       spin_lock_irqsave(&dd->ipath_eep_st_lock, flags);
+                       dd->ipath_traffic_wds += val - dd->ipath_lastrword;
+                       spin_unlock_irqrestore(&dd->ipath_eep_st_lock, flags);
                        dd->ipath_lastrword = val;
                }
                val64 = dd->ipath_rword;
@@ -200,6 +207,7 @@ void ipath_get_faststats(unsigned long opaque)
        struct ipath_devdata *dd = (struct ipath_devdata *) opaque;
        u32 val;
        static unsigned cnt;
+       unsigned long flags;
 
        /*
         * don't access the chip while running diags, or memory diags can
@@ -210,9 +218,20 @@ void ipath_get_faststats(unsigned long opaque)
                /* but re-arm the timer, for diags case; won't hurt other */
                goto done;
 
+       /*
+        * We now try to maintain a "active timer", based on traffic
+        * exceeding a threshold, so we need to check the word-counts
+        * even if they are 64-bit.
+        */
+       ipath_snap_cntr(dd, dd->ipath_cregs->cr_wordsendcnt);
+       ipath_snap_cntr(dd, dd->ipath_cregs->cr_wordrcvcnt);
+       spin_lock_irqsave(&dd->ipath_eep_st_lock, flags);
+       if (dd->ipath_traffic_wds  >= IPATH_TRAFFIC_ACTIVE_THRESHOLD)
+               atomic_add(5, &dd->ipath_active_time); /* S/B #define */
+       dd->ipath_traffic_wds = 0;
+       spin_unlock_irqrestore(&dd->ipath_eep_st_lock, flags);
+
        if (dd->ipath_flags & IPATH_32BITCOUNTERS) {
-               ipath_snap_cntr(dd, dd->ipath_cregs->cr_wordsendcnt);
-               ipath_snap_cntr(dd, dd->ipath_cregs->cr_wordrcvcnt);
                ipath_snap_cntr(dd, dd->ipath_cregs->cr_pktsendcnt);
                ipath_snap_cntr(dd, dd->ipath_cregs->cr_pktrcvcnt);
        }
index 4dc398d5e01190a29380a7043fc4d2e6410f6e54..16238cd3a036ddcf03899b0f37a91fd85fcd2eba 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 QLogic, Inc. All rights reserved.
+ * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
  * Copyright (c) 2006 PathScale, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -596,6 +596,43 @@ bail:
        return ret;
 }
 
+static ssize_t store_led_override(struct device *dev,
+                         struct device_attribute *attr,
+                         const char *buf,
+                         size_t count)
+{
+       struct ipath_devdata *dd = dev_get_drvdata(dev);
+       int ret;
+       u16 val;
+
+       ret = ipath_parse_ushort(buf, &val);
+       if (ret > 0)
+               ipath_set_led_override(dd, val);
+       else
+               ipath_dev_err(dd, "attempt to set invalid LED override\n");
+       return ret;
+}
+
+static ssize_t show_logged_errs(struct device *dev,
+                               struct device_attribute *attr,
+                               char *buf)
+{
+       struct ipath_devdata *dd = dev_get_drvdata(dev);
+       int idx, count;
+
+       /* force consistency with actual EEPROM */
+       if (ipath_update_eeprom_log(dd) != 0)
+               return -ENXIO;
+
+       count = 0;
+       for (idx = 0; idx < IPATH_EEP_LOG_CNT; ++idx) {
+               count += scnprintf(buf + count, PAGE_SIZE - count, "%d%c",
+                       dd->ipath_eep_st_errs[idx],
+                       idx == (IPATH_EEP_LOG_CNT - 1) ? '\n' : ' ');
+       }
+
+       return count;
+}
 
 static DRIVER_ATTR(num_units, S_IRUGO, show_num_units, NULL);
 static DRIVER_ATTR(version, S_IRUGO, show_version, NULL);
@@ -625,6 +662,8 @@ static DEVICE_ATTR(status_str, S_IRUGO, show_status_str, NULL);
 static DEVICE_ATTR(boardversion, S_IRUGO, show_boardversion, NULL);
 static DEVICE_ATTR(unit, S_IRUGO, show_unit, NULL);
 static DEVICE_ATTR(rx_pol_inv, S_IWUSR, NULL, store_rx_pol_inv);
+static DEVICE_ATTR(led_override, S_IWUSR, NULL, store_led_override);
+static DEVICE_ATTR(logged_errors, S_IRUGO, show_logged_errs, NULL);
 
 static struct attribute *dev_attributes[] = {
        &dev_attr_guid.attr,
@@ -641,6 +680,8 @@ static struct attribute *dev_attributes[] = {
        &dev_attr_unit.attr,
        &dev_attr_enabled.attr,
        &dev_attr_rx_pol_inv.attr,
+       &dev_attr_led_override.attr,
+       &dev_attr_logged_errors.attr,
        NULL
 };
 
index 1c2b03c2ef5e9dd31366f36477132b7b4a8aeada..8380fbc50d2cbe3f9f398cc12d9cd617541f2e7e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 QLogic, Inc. All rights reserved.
+ * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
  * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -58,7 +58,6 @@ static void complete_last_send(struct ipath_qp *qp, struct ipath_swqe *wqe,
                wc->port_num = 0;
                ipath_cq_enter(to_icq(qp->ibqp.send_cq), wc, 0);
        }
-       wqe = get_swqe_ptr(qp, qp->s_last);
 }
 
 /**
@@ -87,7 +86,7 @@ int ipath_make_uc_req(struct ipath_qp *qp,
 
        /* header size in 32-bit words LRH+BTH = (8+12)/4. */
        hwords = 5;
-       bth0 = 0;
+       bth0 = 1 << 22; /* Set M bit */
 
        /* Get the next send request. */
        wqe = get_swqe_ptr(qp, qp->s_last);
@@ -97,8 +96,10 @@ int ipath_make_uc_req(struct ipath_qp *qp,
                 * Signal the completion of the last send
                 * (if there is one).
                 */
-               if (qp->s_last != qp->s_tail)
+               if (qp->s_last != qp->s_tail) {
                        complete_last_send(qp, wqe, &wc);
+                       wqe = get_swqe_ptr(qp, qp->s_last);
+               }
 
                /* Check if send work queue is empty. */
                if (qp->s_tail == qp->s_head)
index a518f7c8fa83a9372fc9a5327e646825876261bf..f9a3338a5fb7aa6e90b57c44e88c3b55fe8de87f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 QLogic, Inc. All rights reserved.
+ * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
  * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -176,6 +176,8 @@ static void ipath_ud_loopback(struct ipath_qp *sqp,
                        dev->n_pkt_drops++;
                        goto bail_sge;
                }
+               /* Make sure entry is read after head index is read. */
+               smp_rmb();
                wqe = get_rwqe_ptr(rq, tail);
                if (++tail >= rq->size)
                        tail = 0;
@@ -231,6 +233,8 @@ static void ipath_ud_loopback(struct ipath_qp *sqp,
 
                if (len > length)
                        len = length;
+               if (len > sge->sge_length)
+                       len = sge->sge_length;
                BUG_ON(len == 0);
                ipath_copy_sge(&rsge, sge->vaddr, len);
                sge->vaddr += len;
index 8536aeb96af862ee2581c307f1ef25155850eb00..27034d38b3ddcadcdcfed50c066081533e8915ac 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 QLogic, Inc. All rights reserved.
+ * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
  * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
index bb70845279b8148aba4f2dcf4a769b9429efda48..65f7181e9cf81b7e2db757dc188fc6e7dfee0cb6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 QLogic, Inc. All rights reserved.
+ * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
  * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -164,9 +164,11 @@ void ipath_copy_sge(struct ipath_sge_state *ss, void *data, u32 length)
        while (length) {
                u32 len = sge->length;
 
-               BUG_ON(len == 0);
                if (len > length)
                        len = length;
+               if (len > sge->sge_length)
+                       len = sge->sge_length;
+               BUG_ON(len == 0);
                memcpy(sge->vaddr, data, len);
                sge->vaddr += len;
                sge->length -= len;
@@ -202,9 +204,11 @@ void ipath_skip_sge(struct ipath_sge_state *ss, u32 length)
        while (length) {
                u32 len = sge->length;
 
-               BUG_ON(len == 0);
                if (len > length)
                        len = length;
+               if (len > sge->sge_length)
+                       len = sge->sge_length;
+               BUG_ON(len == 0);
                sge->vaddr += len;
                sge->length -= len;
                sge->sge_length -= len;
@@ -323,6 +327,8 @@ static int ipath_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
                wqe->num_sge = wr->num_sge;
                for (i = 0; i < wr->num_sge; i++)
                        wqe->sg_list[i] = wr->sg_list[i];
+               /* Make sure queue entry is written before the head index. */
+               smp_wmb();
                wq->head = next;
                spin_unlock_irqrestore(&qp->r_rq.lock, flags);
        }
@@ -948,6 +954,7 @@ int ipath_ib_piobufavail(struct ipath_ibdev *dev)
                qp = list_entry(dev->piowait.next, struct ipath_qp,
                                piowait);
                list_del_init(&qp->piowait);
+               clear_bit(IPATH_S_BUSY, &qp->s_busy);
                tasklet_hi_schedule(&qp->s_task);
        }
        spin_unlock_irqrestore(&dev->pending_lock, flags);
@@ -981,6 +988,8 @@ static int ipath_query_device(struct ib_device *ibdev,
        props->max_ah = ib_ipath_max_ahs;
        props->max_cqe = ib_ipath_max_cqes;
        props->max_mr = dev->lk_table.max;
+       props->max_fmr = dev->lk_table.max;
+       props->max_map_per_fmr = 32767;
        props->max_pd = ib_ipath_max_pds;
        props->max_qp_rd_atom = IPATH_MAX_RDMA_ATOMIC;
        props->max_qp_init_rd_atom = 255;
@@ -1051,7 +1060,12 @@ static int ipath_query_port(struct ib_device *ibdev,
        props->max_vl_num = 1;          /* VLCap = VL0 */
        props->init_type_reply = 0;
 
-       props->max_mtu = IB_MTU_4096;
+       /*
+        * Note: the chips support a maximum MTU of 4096, but the driver
+        * hasn't implemented this feature yet, so set the maximum value
+        * to 2048.
+        */
+       props->max_mtu = IB_MTU_2048;
        switch (dev->dd->ipath_ibmtu) {
        case 4096:
                mtu = IB_MTU_4096;
@@ -1361,13 +1375,6 @@ static void __verbs_timer(unsigned long arg)
 {
        struct ipath_devdata *dd = (struct ipath_devdata *) arg;
 
-       /*
-        * If port 0 receive packet interrupts are not available, or
-        * can be missed, poll the receive queue
-        */
-       if (dd->ipath_flags & IPATH_POLL_RX_INTR)
-               ipath_kreceive(dd);
-
        /* Handle verbs layer timeouts. */
        ipath_ib_timer(dd->verbs_dev);
 
index 088b837ebea8f2c22770f1d578e778d378696224..f3d1f2cee6f8f15ac5cd066e92f79dda3ebf9d3b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 QLogic, Inc. All rights reserved.
+ * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
  * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -321,6 +321,7 @@ struct ipath_sge_state {
  */
 struct ipath_ack_entry {
        u8 opcode;
+       u8 sent;
        u32 psn;
        union {
                struct ipath_sge_state rdma_sge;
index dd691cfa507932f04ac9b4fb07e163ee18ba19ec..9e5abf9c309d56dca3f42fc8951da8032ad48861 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 QLogic, Inc. All rights reserved.
+ * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
  * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
index 0095bb70f34e7bbe1f0257ef13402e69865a8e83..1d7bd82a1fb1fa3ffe8c4cebf08a3cd1b57529ce 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 QLogic, Inc. All rights reserved.
+ * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
index 04696e62da878ac3322d483bec9d62afbd3c7164..3428acb0868c202383304105546fc023d3a0917e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 QLogic, Inc. All rights reserved.
+ * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
  * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -63,12 +63,29 @@ int ipath_enable_wc(struct ipath_devdata *dd)
         * of 2 address matching the length (which has to be a power of 2).
         * For rev1, that means the base address, for rev2, it will be just
         * the PIO buffers themselves.
+        * For chips with two sets of buffers, the calculations are
+        * somewhat more complicated; we need to sum, and the piobufbase
+        * register has both offsets, 2K in low 32 bits, 4K in high 32 bits.
+        * The buffers are still packed, so a single range covers both.
         */
-       pioaddr = addr + dd->ipath_piobufbase;
-       piolen = (dd->ipath_piobcnt2k +
-                 dd->ipath_piobcnt4k) *
-               ALIGN(dd->ipath_piobcnt2k +
-                     dd->ipath_piobcnt4k, dd->ipath_palign);
+       if (dd->ipath_piobcnt2k && dd->ipath_piobcnt4k) { /* 2 sizes */
+               unsigned long pio2kbase, pio4kbase;
+               pio2kbase = dd->ipath_piobufbase & 0xffffffffUL;
+               pio4kbase = (dd->ipath_piobufbase >> 32) & 0xffffffffUL;
+               if (pio2kbase < pio4kbase) { /* all, for now */
+                       pioaddr = addr + pio2kbase;
+                       piolen = pio4kbase - pio2kbase +
+                               dd->ipath_piobcnt4k * dd->ipath_4kalign;
+               } else {
+                       pioaddr = addr + pio4kbase;
+                       piolen = pio2kbase - pio4kbase +
+                               dd->ipath_piobcnt2k * dd->ipath_palign;
+               }
+       } else {  /* single buffer size (2K, currently) */
+               pioaddr = addr + dd->ipath_piobufbase;
+               piolen = dd->ipath_piobcnt2k * dd->ipath_palign +
+                       dd->ipath_piobcnt4k * dd->ipath_4kalign;
+       }
 
        for (bits = 0; !(piolen & (1ULL << bits)); bits++)
                /* do nothing */ ;
index b8912cdb966347c4235caec5fedb6833223b7713..4175a4bd0c78841e8d9e121a53a4481069195ef6 100644 (file)
@@ -1,6 +1,5 @@
 config MLX4_INFINIBAND
        tristate "Mellanox ConnectX HCA support"
-       depends on INFINIBAND
        select MLX4_CORE
        ---help---
          This driver provides low-level InfiniBand support for
index c591616dccde7ca0e2632e2b77f4a7e366a2062d..dde8fe9af47e3f24cf13574c363f873a1297fec3 100644 (file)
@@ -169,7 +169,7 @@ static int mlx4_ib_query_port(struct ib_device *ibdev, u8 port,
        props->phys_state       = out_mad->data[33] >> 4;
        props->port_cap_flags   = be32_to_cpup((__be32 *) (out_mad->data + 20));
        props->gid_tbl_len      = to_mdev(ibdev)->dev->caps.gid_table_len[port];
-       props->max_msg_sz       = 0x80000000;
+       props->max_msg_sz       = to_mdev(ibdev)->dev->caps.max_msg_sz;
        props->pkey_tbl_len     = to_mdev(ibdev)->dev->caps.pkey_table_len[port];
        props->bad_pkey_cntr    = be16_to_cpup((__be16 *) (out_mad->data + 46));
        props->qkey_viol_cntr   = be16_to_cpup((__be16 *) (out_mad->data + 48));
@@ -523,11 +523,13 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
                (1ull << IB_USER_VERBS_CMD_DESTROY_CQ)          |
                (1ull << IB_USER_VERBS_CMD_CREATE_QP)           |
                (1ull << IB_USER_VERBS_CMD_MODIFY_QP)           |
+               (1ull << IB_USER_VERBS_CMD_QUERY_QP)            |
                (1ull << IB_USER_VERBS_CMD_DESTROY_QP)          |
                (1ull << IB_USER_VERBS_CMD_ATTACH_MCAST)        |
                (1ull << IB_USER_VERBS_CMD_DETACH_MCAST)        |
                (1ull << IB_USER_VERBS_CMD_CREATE_SRQ)          |
                (1ull << IB_USER_VERBS_CMD_MODIFY_SRQ)          |
+               (1ull << IB_USER_VERBS_CMD_QUERY_SRQ)           |
                (1ull << IB_USER_VERBS_CMD_DESTROY_SRQ);
 
        ibdev->ib_dev.query_device      = mlx4_ib_query_device;
@@ -546,10 +548,12 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
        ibdev->ib_dev.destroy_ah        = mlx4_ib_destroy_ah;
        ibdev->ib_dev.create_srq        = mlx4_ib_create_srq;
        ibdev->ib_dev.modify_srq        = mlx4_ib_modify_srq;
+       ibdev->ib_dev.query_srq         = mlx4_ib_query_srq;
        ibdev->ib_dev.destroy_srq       = mlx4_ib_destroy_srq;
        ibdev->ib_dev.post_srq_recv     = mlx4_ib_post_srq_recv;
        ibdev->ib_dev.create_qp         = mlx4_ib_create_qp;
        ibdev->ib_dev.modify_qp         = mlx4_ib_modify_qp;
+       ibdev->ib_dev.query_qp          = mlx4_ib_query_qp;
        ibdev->ib_dev.destroy_qp        = mlx4_ib_destroy_qp;
        ibdev->ib_dev.post_send         = mlx4_ib_post_send;
        ibdev->ib_dev.post_recv         = mlx4_ib_post_recv;
index 24ccadd6e4f84dce47c206e6ac31179dd60f28f4..705ff2fa237e85e73d3ddf8a6e0d8911f737a9e1 100644 (file)
@@ -35,6 +35,7 @@
 
 #include <linux/compiler.h>
 #include <linux/list.h>
+#include <linux/mutex.h>
 
 #include <rdma/ib_verbs.h>
 #include <rdma/ib_umem.h>
@@ -255,6 +256,7 @@ struct ib_srq *mlx4_ib_create_srq(struct ib_pd *pd,
                                  struct ib_udata *udata);
 int mlx4_ib_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
                       enum ib_srq_attr_mask attr_mask, struct ib_udata *udata);
+int mlx4_ib_query_srq(struct ib_srq *srq, struct ib_srq_attr *srq_attr);
 int mlx4_ib_destroy_srq(struct ib_srq *srq);
 void mlx4_ib_free_srq_wqe(struct mlx4_ib_srq *srq, int wqe_index);
 int mlx4_ib_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
@@ -266,6 +268,8 @@ struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd,
 int mlx4_ib_destroy_qp(struct ib_qp *qp);
 int mlx4_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
                      int attr_mask, struct ib_udata *udata);
+int mlx4_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, int qp_attr_mask,
+                    struct ib_qp_init_attr *qp_init_attr);
 int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
                      struct ib_send_wr **bad_wr);
 int mlx4_ib_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
index 28a08bdd1800badc5ff207d274055ccd5ae760bd..40042184ad589b0b8b9d124b6622637f11251f02 100644 (file)
@@ -1455,3 +1455,140 @@ out:
 
        return err;
 }
+
+static inline enum ib_qp_state to_ib_qp_state(enum mlx4_qp_state mlx4_state)
+{
+       switch (mlx4_state) {
+       case MLX4_QP_STATE_RST:      return IB_QPS_RESET;
+       case MLX4_QP_STATE_INIT:     return IB_QPS_INIT;
+       case MLX4_QP_STATE_RTR:      return IB_QPS_RTR;
+       case MLX4_QP_STATE_RTS:      return IB_QPS_RTS;
+       case MLX4_QP_STATE_SQ_DRAINING:
+       case MLX4_QP_STATE_SQD:      return IB_QPS_SQD;
+       case MLX4_QP_STATE_SQER:     return IB_QPS_SQE;
+       case MLX4_QP_STATE_ERR:      return IB_QPS_ERR;
+       default:                     return -1;
+       }
+}
+
+static inline enum ib_mig_state to_ib_mig_state(int mlx4_mig_state)
+{
+       switch (mlx4_mig_state) {
+       case MLX4_QP_PM_ARMED:          return IB_MIG_ARMED;
+       case MLX4_QP_PM_REARM:          return IB_MIG_REARM;
+       case MLX4_QP_PM_MIGRATED:       return IB_MIG_MIGRATED;
+       default: return -1;
+       }
+}
+
+static int to_ib_qp_access_flags(int mlx4_flags)
+{
+       int ib_flags = 0;
+
+       if (mlx4_flags & MLX4_QP_BIT_RRE)
+               ib_flags |= IB_ACCESS_REMOTE_READ;
+       if (mlx4_flags & MLX4_QP_BIT_RWE)
+               ib_flags |= IB_ACCESS_REMOTE_WRITE;
+       if (mlx4_flags & MLX4_QP_BIT_RAE)
+               ib_flags |= IB_ACCESS_REMOTE_ATOMIC;
+
+       return ib_flags;
+}
+
+static void to_ib_ah_attr(struct mlx4_dev *dev, struct ib_ah_attr *ib_ah_attr,
+                               struct mlx4_qp_path *path)
+{
+       memset(ib_ah_attr, 0, sizeof *path);
+       ib_ah_attr->port_num      = path->sched_queue & 0x40 ? 2 : 1;
+
+       if (ib_ah_attr->port_num == 0 || ib_ah_attr->port_num > dev->caps.num_ports)
+               return;
+
+       ib_ah_attr->dlid          = be16_to_cpu(path->rlid);
+       ib_ah_attr->sl            = (path->sched_queue >> 2) & 0xf;
+       ib_ah_attr->src_path_bits = path->grh_mylmc & 0x7f;
+       ib_ah_attr->static_rate   = path->static_rate ? path->static_rate - 5 : 0;
+       ib_ah_attr->ah_flags      = (path->grh_mylmc & (1 << 7)) ? IB_AH_GRH : 0;
+       if (ib_ah_attr->ah_flags) {
+               ib_ah_attr->grh.sgid_index = path->mgid_index;
+               ib_ah_attr->grh.hop_limit  = path->hop_limit;
+               ib_ah_attr->grh.traffic_class =
+                       (be32_to_cpu(path->tclass_flowlabel) >> 20) & 0xff;
+               ib_ah_attr->grh.flow_label =
+                       be32_to_cpu(path->tclass_flowlabel) & 0xffffff;
+               memcpy(ib_ah_attr->grh.dgid.raw,
+                       path->rgid, sizeof ib_ah_attr->grh.dgid.raw);
+       }
+}
+
+int mlx4_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, int qp_attr_mask,
+                    struct ib_qp_init_attr *qp_init_attr)
+{
+       struct mlx4_ib_dev *dev = to_mdev(ibqp->device);
+       struct mlx4_ib_qp *qp = to_mqp(ibqp);
+       struct mlx4_qp_context context;
+       int mlx4_state;
+       int err;
+
+       if (qp->state == IB_QPS_RESET) {
+               qp_attr->qp_state = IB_QPS_RESET;
+               goto done;
+       }
+
+       err = mlx4_qp_query(dev->dev, &qp->mqp, &context);
+       if (err)
+               return -EINVAL;
+
+       mlx4_state = be32_to_cpu(context.flags) >> 28;
+
+       qp_attr->qp_state            = to_ib_qp_state(mlx4_state);
+       qp_attr->path_mtu            = context.mtu_msgmax >> 5;
+       qp_attr->path_mig_state      =
+               to_ib_mig_state((be32_to_cpu(context.flags) >> 11) & 0x3);
+       qp_attr->qkey                = be32_to_cpu(context.qkey);
+       qp_attr->rq_psn              = be32_to_cpu(context.rnr_nextrecvpsn) & 0xffffff;
+       qp_attr->sq_psn              = be32_to_cpu(context.next_send_psn) & 0xffffff;
+       qp_attr->dest_qp_num         = be32_to_cpu(context.remote_qpn) & 0xffffff;
+       qp_attr->qp_access_flags     =
+               to_ib_qp_access_flags(be32_to_cpu(context.params2));
+
+       if (qp->ibqp.qp_type == IB_QPT_RC || qp->ibqp.qp_type == IB_QPT_UC) {
+               to_ib_ah_attr(dev->dev, &qp_attr->ah_attr, &context.pri_path);
+               to_ib_ah_attr(dev->dev, &qp_attr->alt_ah_attr, &context.alt_path);
+               qp_attr->alt_pkey_index = context.alt_path.pkey_index & 0x7f;
+               qp_attr->alt_port_num   = qp_attr->alt_ah_attr.port_num;
+       }
+
+       qp_attr->pkey_index = context.pri_path.pkey_index & 0x7f;
+       qp_attr->port_num   = context.pri_path.sched_queue & 0x40 ? 2 : 1;
+
+       /* qp_attr->en_sqd_async_notify is only applicable in modify qp */
+       qp_attr->sq_draining = mlx4_state == MLX4_QP_STATE_SQ_DRAINING;
+
+       qp_attr->max_rd_atomic = 1 << ((be32_to_cpu(context.params1) >> 21) & 0x7);
+
+       qp_attr->max_dest_rd_atomic =
+               1 << ((be32_to_cpu(context.params2) >> 21) & 0x7);
+       qp_attr->min_rnr_timer      =
+               (be32_to_cpu(context.rnr_nextrecvpsn) >> 24) & 0x1f;
+       qp_attr->timeout            = context.pri_path.ackto >> 3;
+       qp_attr->retry_cnt          = (be32_to_cpu(context.params1) >> 16) & 0x7;
+       qp_attr->rnr_retry          = (be32_to_cpu(context.params1) >> 13) & 0x7;
+       qp_attr->alt_timeout        = context.alt_path.ackto >> 3;
+
+done:
+       qp_attr->cur_qp_state        = qp_attr->qp_state;
+       if (!ibqp->uobject) {
+               qp_attr->cap.max_send_wr     = qp->sq.wqe_cnt;
+               qp_attr->cap.max_recv_wr     = qp->rq.wqe_cnt;
+               qp_attr->cap.max_send_sge    = qp->sq.max_gs;
+               qp_attr->cap.max_recv_sge    = qp->rq.max_gs;
+               qp_attr->cap.max_inline_data = (1 << qp->sq.wqe_shift) -
+                       send_wqe_overhead(qp->ibqp.qp_type) -
+                       sizeof (struct mlx4_wqe_inline_seg);
+               qp_init_attr->cap            = qp_attr->cap;
+       }
+
+       return 0;
+}
+
index 12fac1c8989dc34bd959aa2735fbf692844c745b..408748fb5285697d24c44b8cd5bebbb19a780f68 100644 (file)
@@ -240,6 +240,24 @@ int mlx4_ib_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
        return 0;
 }
 
+int mlx4_ib_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *srq_attr)
+{
+       struct mlx4_ib_dev *dev = to_mdev(ibsrq->device);
+       struct mlx4_ib_srq *srq = to_msrq(ibsrq);
+       int ret;
+       int limit_watermark;
+
+       ret = mlx4_srq_query(dev->dev, &srq->msrq, &limit_watermark);
+       if (ret)
+               return ret;
+
+       srq_attr->srq_limit = be16_to_cpu(limit_watermark);
+       srq_attr->max_wr    = srq->msrq.max - 1;
+       srq_attr->max_sge   = srq->msrq.max_gs;
+
+       return 0;
+}
+
 int mlx4_ib_destroy_srq(struct ib_srq *srq)
 {
        struct mlx4_ib_dev *dev = to_mdev(srq->device);
index 9aa5a4468a753c0ee241277e8d957ffb8207b8d4..03efc074967e2b5344f18acc25f23d2ecf14b2c0 100644 (file)
@@ -1,6 +1,6 @@
 config INFINIBAND_MTHCA
        tristate "Mellanox HCA support"
-       depends on PCI && INFINIBAND
+       depends on PCI
        ---help---
          This is a low-level driver for Mellanox InfiniHost host
          channel adapters (HCAs), including the MT23108 PCI-X HCA
index f930e55b58fcd45ae947b6b29efc9d6efa87dd1c..a763067096182fe14d9502a2a5fdd6135bd6e580 100644 (file)
@@ -255,7 +255,7 @@ int mthca_buf_alloc(struct mthca_dev *dev, int size, int max_direct,
                        dma_list[i] = t;
                        pci_unmap_addr_set(&buf->page_list[i], mapping, t);
 
-                       memset(buf->page_list[i].buf, 0, PAGE_SIZE);
+                       clear_page(buf->page_list[i].buf);
                }
        }
 
index 8ec9fa1ff9ea10809ac8dac3e32d904559ff7176..8592b26dc4e1b051d5fe7704e285371145c7587e 100644 (file)
@@ -522,7 +522,7 @@ static int mthca_create_eq(struct mthca_dev *dev,
                dma_list[i] = t;
                pci_unmap_addr_set(&eq->page_list[i], mapping, t);
 
-               memset(eq->page_list[i].buf, 0, PAGE_SIZE);
+               clear_page(eq->page_list[i].buf);
        }
 
        for (i = 0; i < eq->nent; ++i)
index af78ccc4ce7108aba6968b5438a0d8adbc7be4f2..1f76bad020f3f1799025bf7fbad08f1acc7d9489 100644 (file)
@@ -1,6 +1,6 @@
 config INFINIBAND_IPOIB
        tristate "IP-over-InfiniBand"
-       depends on INFINIBAND && NETDEVICES && INET && (IPV6 || IPV6=n)
+       depends on NETDEVICES && INET && (IPV6 || IPV6=n)
        ---help---
          Support for the IP-over-InfiniBand protocol (IPoIB). This
          transports IP packets over InfiniBand so you can use your IB
index ea74d1eaf0046c15c78e6a819067b8743a572a71..08b4676a38201ad94fc5d165ce2a27ed139a36a1 100644 (file)
@@ -281,7 +281,6 @@ static int ipoib_cm_send_rep(struct net_device *dev, struct ib_cm_id *cm_id,
        rep.private_data_len = sizeof data;
        rep.flow_control = 0;
        rep.rnr_retry_count = req->rnr_retry_count;
-       rep.target_ack_delay = 20; /* FIXME */
        rep.srq = 1;
        rep.qp_num = qp->qp_num;
        rep.starting_psn = psn;
@@ -1148,7 +1147,6 @@ static void ipoib_cm_skb_reap(struct work_struct *work)
 {
        struct ipoib_dev_priv *priv = container_of(work, struct ipoib_dev_priv,
                                                   cm.skb_task);
-       struct net_device *dev = priv->dev;
        struct sk_buff *skb;
 
        unsigned mtu = priv->mcast_mtu;
@@ -1162,7 +1160,7 @@ static void ipoib_cm_skb_reap(struct work_struct *work)
                        icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
                else if (skb->protocol == htons(ETH_P_IPV6))
-                       icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, dev);
+                       icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, priv->dev);
 #endif
                dev_kfree_skb_any(skb);
                spin_lock_irq(&priv->tx_lock);
index 8404f05b2b6eefd04a018b5da67698b65cfb09fd..10944888cffd79de3c8b4751ceac2929a0296141 100644 (file)
@@ -196,6 +196,13 @@ static void ipoib_ib_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
                return;
        }
 
+       /*
+        * Drop packets that this interface sent, ie multicast packets
+        * that the HCA has replicated.
+        */
+       if (wc->slid == priv->local_lid && wc->src_qp == priv->qp->qp_num)
+               goto repost;
+
        /*
         * If we can't allocate a new RX buffer, dump
         * this packet and reuse the old buffer.
@@ -213,24 +220,18 @@ static void ipoib_ib_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
        skb_put(skb, wc->byte_len);
        skb_pull(skb, IB_GRH_BYTES);
 
-       if (wc->slid != priv->local_lid ||
-           wc->src_qp != priv->qp->qp_num) {
-               skb->protocol = ((struct ipoib_header *) skb->data)->proto;
-               skb_reset_mac_header(skb);
-               skb_pull(skb, IPOIB_ENCAP_LEN);
+       skb->protocol = ((struct ipoib_header *) skb->data)->proto;
+       skb_reset_mac_header(skb);
+       skb_pull(skb, IPOIB_ENCAP_LEN);
 
-               dev->last_rx = jiffies;
-               ++priv->stats.rx_packets;
-               priv->stats.rx_bytes += skb->len;
+       dev->last_rx = jiffies;
+       ++priv->stats.rx_packets;
+       priv->stats.rx_bytes += skb->len;
 
-               skb->dev = dev;
-               /* XXX get correct PACKET_ type here */
-               skb->pkt_type = PACKET_HOST;
-               netif_receive_skb(skb);
-       } else {
-               ipoib_dbg_data(priv, "dropping loopback packet\n");
-               dev_kfree_skb_any(skb);
-       }
+       skb->dev = dev;
+       /* XXX get correct PACKET_ type here */
+       skb->pkt_type = PACKET_HOST;
+       netif_receive_skb(skb);
 
 repost:
        if (unlikely(ipoib_ib_post_receive(dev, wr_id)))
index aecbb9083f0c06c770dfb20aba8c1068c9629e1f..fe604c8d299621b9dad04d8e4a9d85672b9ab326 100644 (file)
@@ -1,6 +1,6 @@
 config INFINIBAND_ISER
        tristate "iSCSI Extensions for RDMA (iSER)"
-       depends on INFINIBAND && SCSI && INET
+       depends on SCSI && INET
        select SCSI_ISCSI_ATTRS
        ---help---
          Support for the iSCSI Extensions for RDMA (iSER) Protocol
index 8fe3be4e991081b291d2e724cfe473b1ee8e07ea..3432dce29520a6df599c7a9e7614027257236913 100644 (file)
@@ -1,6 +1,6 @@
 config INFINIBAND_SRP
        tristate "InfiniBand SCSI RDMA Protocol"
-       depends on INFINIBAND && SCSI
+       depends on SCSI
        ---help---
          Support for the SCSI RDMA Protocol over InfiniBand.  This
          allows you to access storage devices that speak SRP over
index be6b93c20f606b9e477746e81688d7abe25bcdda..ab4b2d9b5327a881da8a2bf13748d29ea72328fa 100644 (file)
@@ -30,6 +30,7 @@ struct evdev {
        wait_queue_head_t wait;
        struct evdev_client *grab;
        struct list_head client_list;
+       struct device dev;
 };
 
 struct evdev_client {
@@ -94,8 +95,10 @@ static int evdev_flush(struct file *file, fl_owner_t id)
        return input_flush_device(&evdev->handle, file);
 }
 
-static void evdev_free(struct evdev *evdev)
+static void evdev_free(struct device *dev)
 {
+       struct evdev *evdev = container_of(dev, struct evdev, dev);
+
        evdev_table[evdev->minor] = NULL;
        kfree(evdev);
 }
@@ -114,12 +117,10 @@ static int evdev_release(struct inode *inode, struct file *file)
        list_del(&client->node);
        kfree(client);
 
-       if (!--evdev->open) {
-               if (evdev->exist)
-                       input_close_device(&evdev->handle);
-               else
-                       evdev_free(evdev);
-       }
+       if (!--evdev->open && evdev->exist)
+               input_close_device(&evdev->handle);
+
+       put_device(&evdev->dev);
 
        return 0;
 }
@@ -139,24 +140,32 @@ static int evdev_open(struct inode *inode, struct file *file)
        if (!evdev || !evdev->exist)
                return -ENODEV;
 
+       get_device(&evdev->dev);
+
        client = kzalloc(sizeof(struct evdev_client), GFP_KERNEL);
-       if (!client)
-               return -ENOMEM;
+       if (!client) {
+               error = -ENOMEM;
+               goto err_put_evdev;
+       }
 
        client->evdev = evdev;
        list_add_tail(&client->node, &evdev->client_list);
 
        if (!evdev->open++ && evdev->exist) {
                error = input_open_device(&evdev->handle);
-               if (error) {
-                       list_del(&client->node);
-                       kfree(client);
-                       return error;
-               }
+               if (error)
+                       goto err_free_client;
        }
 
        file->private_data = client;
        return 0;
+
+ err_free_client:
+       list_del(&client->node);
+       kfree(client);
+ err_put_evdev:
+       put_device(&evdev->dev);
+       return error;
 }
 
 #ifdef CONFIG_COMPAT
@@ -625,8 +634,6 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
                         const struct input_device_id *id)
 {
        struct evdev *evdev;
-       struct class_device *cdev;
-       dev_t devt;
        int minor;
        int error;
 
@@ -649,38 +656,32 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
        evdev->handle.name = evdev->name;
        evdev->handle.handler = handler;
        evdev->handle.private = evdev;
-       sprintf(evdev->name, "event%d", minor);
-
-       evdev_table[minor] = evdev;
+       snprintf(evdev->name, sizeof(evdev->name), "event%d", minor);
 
-       devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor),
+       snprintf(evdev->dev.bus_id, sizeof(evdev->dev.bus_id),
+                "event%d", minor);
+       evdev->dev.class = &input_class;
+       evdev->dev.parent = &dev->dev;
+       evdev->dev.devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor);
+       evdev->dev.release = evdev_free;
+       device_initialize(&evdev->dev);
 
-       cdev = class_device_create(&input_class, &dev->cdev, devt,
-                                  dev->cdev.dev, evdev->name);
-       if (IS_ERR(cdev)) {
-               error = PTR_ERR(cdev);
-               goto err_free_evdev;
-       }
+       evdev_table[minor] = evdev;
 
-       /* temporary symlink to keep userspace happy */
-       error = sysfs_create_link(&input_class.subsys.kobj,
-                                 &cdev->kobj, evdev->name);
+       error = device_add(&evdev->dev);
        if (error)
-               goto err_cdev_destroy;
+               goto err_free_evdev;
 
        error = input_register_handle(&evdev->handle);
        if (error)
-               goto err_remove_link;
+               goto err_delete_evdev;
 
        return 0;
 
- err_remove_link:
-       sysfs_remove_link(&input_class.subsys.kobj, evdev->name);
- err_cdev_destroy:
-       class_device_destroy(&input_class, devt);
+ err_delete_evdev:
+       device_del(&evdev->dev);
  err_free_evdev:
-       kfree(evdev);
-       evdev_table[minor] = NULL;
+       put_device(&evdev->dev);
        return error;
 }
 
@@ -690,10 +691,8 @@ static void evdev_disconnect(struct input_handle *handle)
        struct evdev_client *client;
 
        input_unregister_handle(handle);
+       device_del(&evdev->dev);
 
-       sysfs_remove_link(&input_class.subsys.kobj, evdev->name);
-       class_device_destroy(&input_class,
-                       MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + evdev->minor));
        evdev->exist = 0;
 
        if (evdev->open) {
@@ -702,8 +701,9 @@ static void evdev_disconnect(struct input_handle *handle)
                list_for_each_entry(client, &evdev->client_list, node)
                        kill_fasync(&client->fasync, SIGIO, POLL_HUP);
                wake_up_interruptible(&evdev->wait);
-       } else
-               evdev_free(evdev);
+       }
+
+       put_device(&evdev->dev);
 }
 
 static const struct input_device_id evdev_ids[] = {
index ccd8abafcb708c2f4aedf962c5f27f4dbe9ca0dc..75b4d2a83dd99ff842308e1a96400cd809aac383 100644 (file)
@@ -442,7 +442,7 @@ static int input_attach_handler(struct input_dev *dev, struct input_handler *han
                printk(KERN_ERR
                        "input: failed to attach handler %s to device %s, "
                        "error: %d\n",
-                       handler->name, kobject_name(&dev->cdev.kobj), error);
+                       handler->name, kobject_name(&dev->dev.kobj), error);
 
        return error;
 }
@@ -527,7 +527,7 @@ static void input_seq_print_bitmap(struct seq_file *seq, const char *name,
 static int input_devices_seq_show(struct seq_file *seq, void *v)
 {
        struct input_dev *dev = container_of(v, struct input_dev, node);
-       const char *path = kobject_get_path(&dev->cdev.kobj, GFP_KERNEL);
+       const char *path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);
        struct input_handle *handle;
 
        seq_printf(seq, "I: Bus=%04x Vendor=%04x Product=%04x Version=%04x\n",
@@ -682,15 +682,17 @@ static inline int input_proc_init(void) { return 0; }
 static inline void input_proc_exit(void) { }
 #endif
 
-#define INPUT_DEV_STRING_ATTR_SHOW(name)                                       \
-static ssize_t input_dev_show_##name(struct class_device *dev, char *buf)      \
-{                                                                              \
-       struct input_dev *input_dev = to_input_dev(dev);                        \
-                                                                               \
-       return scnprintf(buf, PAGE_SIZE, "%s\n",                                \
-                        input_dev->name ? input_dev->name : "");               \
-}                                                                              \
-static CLASS_DEVICE_ATTR(name, S_IRUGO, input_dev_show_##name, NULL);
+#define INPUT_DEV_STRING_ATTR_SHOW(name)                               \
+static ssize_t input_dev_show_##name(struct device *dev,               \
+                                    struct device_attribute *attr,     \
+                                    char *buf)                         \
+{                                                                      \
+       struct input_dev *input_dev = to_input_dev(dev);                \
+                                                                       \
+       return scnprintf(buf, PAGE_SIZE, "%s\n",                        \
+                        input_dev->name ? input_dev->name : "");       \
+}                                                                      \
+static DEVICE_ATTR(name, S_IRUGO, input_dev_show_##name, NULL)
 
 INPUT_DEV_STRING_ATTR_SHOW(name);
 INPUT_DEV_STRING_ATTR_SHOW(phys);
@@ -744,7 +746,9 @@ static int input_print_modalias(char *buf, int size, struct input_dev *id,
        return len;
 }
 
-static ssize_t input_dev_show_modalias(struct class_device *dev, char *buf)
+static ssize_t input_dev_show_modalias(struct device *dev,
+                                      struct device_attribute *attr,
+                                      char *buf)
 {
        struct input_dev *id = to_input_dev(dev);
        ssize_t len;
@@ -753,13 +757,13 @@ static ssize_t input_dev_show_modalias(struct class_device *dev, char *buf)
 
        return min_t(int, len, PAGE_SIZE);
 }
-static CLASS_DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL);
+static DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL);
 
 static struct attribute *input_dev_attrs[] = {
-       &class_device_attr_name.attr,
-       &class_device_attr_phys.attr,
-       &class_device_attr_uniq.attr,
-       &class_device_attr_modalias.attr,
+       &dev_attr_name.attr,
+       &dev_attr_phys.attr,
+       &dev_attr_uniq.attr,
+       &dev_attr_modalias.attr,
        NULL
 };
 
@@ -767,13 +771,15 @@ static struct attribute_group input_dev_attr_group = {
        .attrs  = input_dev_attrs,
 };
 
-#define INPUT_DEV_ID_ATTR(name)                                                        \
-static ssize_t input_dev_show_id_##name(struct class_device *dev, char *buf)   \
-{                                                                              \
-       struct input_dev *input_dev = to_input_dev(dev);                        \
-       return scnprintf(buf, PAGE_SIZE, "%04x\n", input_dev->id.name);         \
-}                                                                              \
-static CLASS_DEVICE_ATTR(name, S_IRUGO, input_dev_show_id_##name, NULL);
+#define INPUT_DEV_ID_ATTR(name)                                                \
+static ssize_t input_dev_show_id_##name(struct device *dev,            \
+                                       struct device_attribute *attr,  \
+                                       char *buf)                      \
+{                                                                      \
+       struct input_dev *input_dev = to_input_dev(dev);                \
+       return scnprintf(buf, PAGE_SIZE, "%04x\n", input_dev->id.name); \
+}                                                                      \
+static DEVICE_ATTR(name, S_IRUGO, input_dev_show_id_##name, NULL)
 
 INPUT_DEV_ID_ATTR(bustype);
 INPUT_DEV_ID_ATTR(vendor);
@@ -781,10 +787,10 @@ INPUT_DEV_ID_ATTR(product);
 INPUT_DEV_ID_ATTR(version);
 
 static struct attribute *input_dev_id_attrs[] = {
-       &class_device_attr_bustype.attr,
-       &class_device_attr_vendor.attr,
-       &class_device_attr_product.attr,
-       &class_device_attr_version.attr,
+       &dev_attr_bustype.attr,
+       &dev_attr_vendor.attr,
+       &dev_attr_product.attr,
+       &dev_attr_version.attr,
        NULL
 };
 
@@ -813,15 +819,17 @@ static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap,
        return len;
 }
 
-#define INPUT_DEV_CAP_ATTR(ev, bm)                                             \
-static ssize_t input_dev_show_cap_##bm(struct class_device *dev, char *buf)    \
-{                                                                              \
-       struct input_dev *input_dev = to_input_dev(dev);                        \
-       int len = input_print_bitmap(buf, PAGE_SIZE,                            \
-                                    input_dev->bm##bit, ev##_MAX, 1);          \
-       return min_t(int, len, PAGE_SIZE);                                      \
-}                                                                              \
-static CLASS_DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL);
+#define INPUT_DEV_CAP_ATTR(ev, bm)                                     \
+static ssize_t input_dev_show_cap_##bm(struct device *dev,             \
+                                      struct device_attribute *attr,   \
+                                      char *buf)                       \
+{                                                                      \
+       struct input_dev *input_dev = to_input_dev(dev);                \
+       int len = input_print_bitmap(buf, PAGE_SIZE,                    \
+                                    input_dev->bm##bit, ev##_MAX, 1);  \
+       return min_t(int, len, PAGE_SIZE);                              \
+}                                                                      \
+static DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL)
 
 INPUT_DEV_CAP_ATTR(EV, ev);
 INPUT_DEV_CAP_ATTR(KEY, key);
@@ -834,15 +842,15 @@ INPUT_DEV_CAP_ATTR(FF, ff);
 INPUT_DEV_CAP_ATTR(SW, sw);
 
 static struct attribute *input_dev_caps_attrs[] = {
-       &class_device_attr_ev.attr,
-       &class_device_attr_key.attr,
-       &class_device_attr_rel.attr,
-       &class_device_attr_abs.attr,
-       &class_device_attr_msc.attr,
-       &class_device_attr_led.attr,
-       &class_device_attr_snd.attr,
-       &class_device_attr_ff.attr,
-       &class_device_attr_sw.attr,
+       &dev_attr_ev.attr,
+       &dev_attr_key.attr,
+       &dev_attr_rel.attr,
+       &dev_attr_abs.attr,
+       &dev_attr_msc.attr,
+       &dev_attr_led.attr,
+       &dev_attr_snd.attr,
+       &dev_attr_ff.attr,
+       &dev_attr_sw.attr,
        NULL
 };
 
@@ -858,9 +866,9 @@ static struct attribute_group *input_dev_attr_groups[] = {
        NULL
 };
 
-static void input_dev_release(struct class_device *class_dev)
+static void input_dev_release(struct device *device)
 {
-       struct input_dev *dev = to_input_dev(class_dev);
+       struct input_dev *dev = to_input_dev(device);
 
        input_ff_destroy(dev);
        kfree(dev);
@@ -947,10 +955,10 @@ static int input_add_uevent_modalias_var(char **envp, int num_envp, int *cur_ind
                        return err;                                     \
        } while (0)
 
-static int input_dev_uevent(struct class_device *cdev, char **envp,
+static int input_dev_uevent(struct device *device, char **envp,
                            int num_envp, char *buffer, int buffer_size)
 {
-       struct input_dev *dev = to_input_dev(cdev);
+       struct input_dev *dev = to_input_dev(device);
        int i = 0;
        int len = 0;
 
@@ -988,10 +996,14 @@ static int input_dev_uevent(struct class_device *cdev, char **envp,
        return 0;
 }
 
+static struct device_type input_dev_type = {
+       .groups         = input_dev_attr_groups,
+       .release        = input_dev_release,
+       .uevent         = input_dev_uevent,
+};
+
 struct class input_class = {
-       .name                   = "input",
-       .release                = input_dev_release,
-       .uevent                 = input_dev_uevent,
+       .name           = "input",
 };
 EXPORT_SYMBOL_GPL(input_class);
 
@@ -1010,9 +1022,9 @@ struct input_dev *input_allocate_device(void)
 
        dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL);
        if (dev) {
-               dev->cdev.class = &input_class;
-               dev->cdev.groups = input_dev_attr_groups;
-               class_device_initialize(&dev->cdev);
+               dev->dev.type = &input_dev_type;
+               dev->dev.class = &input_class;
+               device_initialize(&dev->dev);
                mutex_init(&dev->mutex);
                INIT_LIST_HEAD(&dev->h_list);
                INIT_LIST_HEAD(&dev->node);
@@ -1131,17 +1143,17 @@ int input_register_device(struct input_dev *dev)
 
        list_add_tail(&dev->node, &input_dev_list);
 
-       snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id),
+       snprintf(dev->dev.bus_id, sizeof(dev->dev.bus_id),
                 "input%ld", (unsigned long) atomic_inc_return(&input_no) - 1);
 
-       if (!dev->cdev.dev)
-               dev->cdev.dev = dev->dev.parent;
+       if (dev->cdev.dev)
+               dev->dev.parent = dev->cdev.dev;
 
-       error = class_device_add(&dev->cdev);
+       error = device_add(&dev->dev);
        if (error)
                return error;
 
-       path = kobject_get_path(&dev->cdev.kobj, GFP_KERNEL);
+       path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);
        printk(KERN_INFO "input: %s as %s\n",
                dev->name ? dev->name : "Unspecified device", path ? path : "N/A");
        kfree(path);
@@ -1173,7 +1185,7 @@ void input_unregister_device(struct input_dev *dev)
 
        list_del_init(&dev->node);
 
-       class_device_unregister(&dev->cdev);
+       device_unregister(&dev->dev);
 
        input_wakeup_procfs_readers();
 }
index 10e3b7bc925fd7b68ca8e7bb418d39471caa776c..a9a0180bfd462f1c31895641a75448e596630bcc 100644 (file)
@@ -43,6 +43,8 @@ struct joydev {
        struct input_handle handle;
        wait_queue_head_t wait;
        struct list_head client_list;
+       struct device dev;
+
        struct js_corr corr[ABS_MAX + 1];
        struct JS_DATA_SAVE_TYPE glue;
        int nabs;
@@ -138,8 +140,10 @@ static int joydev_fasync(int fd, struct file *file, int on)
        return retval < 0 ? retval : 0;
 }
 
-static void joydev_free(struct joydev *joydev)
+static void joydev_free(struct device *dev)
 {
+       struct joydev *joydev = container_of(dev, struct joydev, dev);
+
        joydev_table[joydev->minor] = NULL;
        kfree(joydev);
 }
@@ -154,12 +158,10 @@ static int joydev_release(struct inode *inode, struct file *file)
        list_del(&client->node);
        kfree(client);
 
-       if (!--joydev->open) {
-               if (joydev->exist)
-                       input_close_device(&joydev->handle);
-               else
-                       joydev_free(joydev);
-       }
+       if (!--joydev->open && joydev->exist)
+               input_close_device(&joydev->handle);
+
+       put_device(&joydev->dev);
 
        return 0;
 }
@@ -178,24 +180,32 @@ static int joydev_open(struct inode *inode, struct file *file)
        if (!joydev || !joydev->exist)
                return -ENODEV;
 
+       get_device(&joydev->dev);
+
        client = kzalloc(sizeof(struct joydev_client), GFP_KERNEL);
-       if (!client)
-               return -ENOMEM;
+       if (!client) {
+               error = -ENOMEM;
+               goto err_put_joydev;
+       }
 
        client->joydev = joydev;
        list_add_tail(&client->node, &joydev->client_list);
 
        if (!joydev->open++ && joydev->exist) {
                error = input_open_device(&joydev->handle);
-               if (error) {
-                       list_del(&client->node);
-                       kfree(client);
-                       return error;
-               }
+               if (error)
+                       goto err_free_client;
        }
 
        file->private_data = client;
        return 0;
+
+ err_free_client:
+       list_del(&client->node);
+       kfree(client);
+ err_put_joydev:
+       put_device(&joydev->dev);
+       return error;
 }
 
 static ssize_t joydev_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
@@ -481,8 +491,6 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
                          const struct input_device_id *id)
 {
        struct joydev *joydev;
-       struct class_device *cdev;
-       dev_t devt;
        int i, j, t, minor;
        int error;
 
@@ -505,7 +513,7 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
        joydev->handle.name = joydev->name;
        joydev->handle.handler = handler;
        joydev->handle.private = joydev;
-       sprintf(joydev->name, "js%d", minor);
+       snprintf(joydev->name, sizeof(joydev->name), "js%d", minor);
 
        for (i = 0; i < ABS_MAX + 1; i++)
                if (test_bit(i, dev->absbit)) {
@@ -547,36 +555,30 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
                joydev->abs[i] = joydev_correct(dev->abs[j], joydev->corr + i);
        }
 
-       joydev_table[minor] = joydev;
-
-       devt = MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor),
+       snprintf(joydev->dev.bus_id, sizeof(joydev->dev.bus_id),
+                "js%d", minor);
+       joydev->dev.class = &input_class;
+       joydev->dev.parent = &dev->dev;
+       joydev->dev.devt = MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor);
+       joydev->dev.release = joydev_free;
+       device_initialize(&joydev->dev);
 
-       cdev = class_device_create(&input_class, &dev->cdev, devt,
-                                  dev->cdev.dev, joydev->name);
-       if (IS_ERR(cdev)) {
-               error = PTR_ERR(cdev);
-               goto err_free_joydev;
-       }
+       joydev_table[minor] = joydev;
 
-       /* temporary symlink to keep userspace happy */
-       error = sysfs_create_link(&input_class.subsys.kobj,
-                                 &cdev->kobj, joydev->name);
+       error = device_add(&joydev->dev);
        if (error)
-               goto err_cdev_destroy;
+               goto err_free_joydev;
 
        error = input_register_handle(&joydev->handle);
        if (error)
-               goto err_remove_link;
+               goto err_delete_joydev;
 
        return 0;
 
- err_remove_link:
-       sysfs_remove_link(&input_class.subsys.kobj, joydev->name);
- err_cdev_destroy:
-       class_device_destroy(&input_class, devt);
+ err_delete_joydev:
+       device_del(&joydev->dev);
  err_free_joydev:
-       joydev_table[minor] = NULL;
-       kfree(joydev);
+       put_device(&joydev->dev);
        return error;
 }
 
@@ -587,9 +589,8 @@ static void joydev_disconnect(struct input_handle *handle)
        struct joydev_client *client;
 
        input_unregister_handle(handle);
+       device_del(&joydev->dev);
 
-       sysfs_remove_link(&input_class.subsys.kobj, joydev->name);
-       class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor));
        joydev->exist = 0;
 
        if (joydev->open) {
@@ -597,8 +598,9 @@ static void joydev_disconnect(struct input_handle *handle)
                list_for_each_entry(client, &joydev->client_list, node)
                        kill_fasync(&client->fasync, SIGIO, POLL_HUP);
                wake_up_interruptible(&joydev->wait);
-       } else
-               joydev_free(joydev);
+       }
+
+       put_device(&joydev->dev);
 }
 
 static const struct input_device_id joydev_blacklist[] = {
index b0023452ec90a78c7297804ded4c0c3757d900dd..12db72d83ea0b254e048de0d68016010b153228d 100644 (file)
@@ -268,4 +268,11 @@ config JOYSTICK_XPAD
          To compile this driver as a module, choose M here: the
          module will be called xpad.
 
+config JOYSTICK_XPAD_FF
+       bool "X-Box gamepad rumble support"
+       depends on JOYSTICK_XPAD && INPUT
+       select INPUT_FF_MEMLESS
+       ---help---
+         Say Y here if you want to take advantage of xbox 360 rumble features.
+
 endif
index 555319e6378c47620d9a187b3493c5c82cfe0553..4ed3a3eadf1964eaad388e4f603720910e675811 100644 (file)
@@ -320,10 +320,10 @@ static int multiport_io(struct gameport* gameport, int sendflags, int sendcode,
 
 static int dig_mode_start(struct gameport *gameport, u32 *packet)
 {
-       int i, seq_len = sizeof(init_seq)/sizeof(int);
+       int i;
        int flags, tries = 0, bads = 0;
 
-       for (i = 0; i < seq_len; i++) {     /* Send magic sequence */
+       for (i = 0; i < ARRAY_SIZE(init_seq); i++) {     /* Send magic sequence */
                if (init_seq[i])
                        gameport_trigger(gameport);
                udelay(GRIP_INIT_DELAY);
index 8c8cd95a6989dbf8ffd5c2105b08c0837867dc9e..244089c52650f1af2eae67185f05c3277abdfe3a 100644 (file)
@@ -8,6 +8,7 @@
  *                    Ivan Hawkes <blackhawk@ivanhawkes.com>
  *               2005 Dominic Cerquetti <binary1230@yahoo.com>
  *               2006 Adam Buchbinder <adam.buchbinder@gmail.com>
+ *               2007 Jan Kratochvil <honza@jikos.cz>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -28,6 +29,7 @@
  *  - information from     http://euc.jp/periphs/xbox-controller.ja.html
  *  - the iForce driver    drivers/char/joystick/iforce.c
  *  - the skeleton-driver  drivers/usb/usb-skeleton.c
+ *  - Xbox 360 information http://www.free60.org/wiki/Gamepad
  *
  * Thanks to:
  *  - ITO Takayuki for providing essential xpad information on his website
@@ -88,6 +90,9 @@
 #define MAP_DPAD_TO_AXES       1
 #define MAP_DPAD_UNKNOWN       -1
 
+#define XTYPE_XBOX        0
+#define XTYPE_XBOX360     1
+
 static int dpad_to_buttons;
 module_param(dpad_to_buttons, bool, S_IRUGO);
 MODULE_PARM_DESC(dpad_to_buttons, "Map D-PAD to buttons rather than axes for unknown pads");
@@ -97,40 +102,42 @@ static const struct xpad_device {
        u16 idProduct;
        char *name;
        u8 dpad_mapping;
+       u8 xtype;
 } xpad_device[] = {
-       { 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", MAP_DPAD_TO_AXES },
-       { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", MAP_DPAD_TO_AXES },
-       { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", MAP_DPAD_TO_AXES },
-       { 0x045e, 0x0287, "Microsoft Xbox Controller S", MAP_DPAD_TO_AXES },
-       { 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", MAP_DPAD_TO_BUTTONS },
-       { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", MAP_DPAD_TO_AXES },
-       { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", MAP_DPAD_TO_AXES },
-       { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", MAP_DPAD_TO_AXES },
-       { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", MAP_DPAD_TO_AXES },
-       { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", MAP_DPAD_TO_AXES },
-       { 0x0738, 0x4516, "Mad Catz Control Pad", MAP_DPAD_TO_AXES },
-       { 0x0738, 0x4522, "Mad Catz LumiCON", MAP_DPAD_TO_AXES },
-       { 0x0738, 0x4526, "Mad Catz Control Pad Pro", MAP_DPAD_TO_AXES },
-       { 0x0738, 0x4536, "Mad Catz MicroCON", MAP_DPAD_TO_AXES },
-       { 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS },
-       { 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", MAP_DPAD_TO_AXES },
-       { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS },
-       { 0x0c12, 0x8802, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES },
-       { 0x0c12, 0x8810, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES },
-       { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", MAP_DPAD_TO_AXES },
-       { 0x0e4c, 0x1097, "Radica Gamester Controller", MAP_DPAD_TO_AXES },
-       { 0x0e4c, 0x2390, "Radica Games Jtech Controller", MAP_DPAD_TO_AXES},
-       { 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", MAP_DPAD_TO_AXES },
-       { 0x0e6f, 0x0005, "Eclipse wireless Controller", MAP_DPAD_TO_AXES },
-       { 0x0e6f, 0x0006, "Edge wireless Controller", MAP_DPAD_TO_AXES },
-       { 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", MAP_DPAD_TO_AXES },
-       { 0x0f30, 0x0202, "Joytech Advanced Controller", MAP_DPAD_TO_AXES },
-       { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", MAP_DPAD_TO_AXES },
-       { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", MAP_DPAD_TO_AXES },
-       { 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS },
-       { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS },
-       { 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES },
-       { 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN }
+       { 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+       { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+       { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+       { 0x045e, 0x0287, "Microsoft Xbox Controller S", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+       { 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
+       { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+       { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+       { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+       { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+       { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+       { 0x0738, 0x4516, "Mad Catz Control Pad", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+       { 0x0738, 0x4522, "Mad Catz LumiCON", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+       { 0x0738, 0x4526, "Mad Catz Control Pad Pro", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+       { 0x0738, 0x4536, "Mad Catz MicroCON", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+       { 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
+       { 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+       { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
+       { 0x0c12, 0x8802, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+       { 0x0c12, 0x8810, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+       { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+       { 0x0e4c, 0x1097, "Radica Gamester Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+       { 0x0e4c, 0x2390, "Radica Games Jtech Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+       { 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+       { 0x0e6f, 0x0005, "Eclipse wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+       { 0x0e6f, 0x0006, "Edge wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+       { 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+       { 0x0f30, 0x0202, "Joytech Advanced Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+       { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+       { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+       { 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
+       { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
+       { 0x045e, 0x028e, "Microsoft X-Box 360 pad", MAP_DPAD_TO_AXES, XTYPE_XBOX360 },
+       { 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+       { 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN, XTYPE_XBOX }
 };
 
 static const signed short xpad_btn[] = {
@@ -146,6 +153,12 @@ static const signed short xpad_btn_pad[] = {
        -1                              /* terminating entry */
 };
 
+static const signed short xpad360_btn[] = {  /* buttons for x360 controller */
+       BTN_TL, BTN_TR,         /* Button LB/RB */
+       BTN_MODE,               /* The big X button */
+       -1
+};
+
 static const signed short xpad_abs[] = {
        ABS_X, ABS_Y,           /* left stick */
        ABS_RX, ABS_RY,         /* right stick */
@@ -159,8 +172,12 @@ static const signed short xpad_abs_pad[] = {
        -1                      /* terminating entry */
 };
 
+/* Xbox 360 has a vendor-specific (sub)class, so we cannot match it with only
+ * USB_INTERFACE_INFO, more to that this device has 4 InterfaceProtocols,
+ * but we need only one of them. */
 static struct usb_device_id xpad_table [] = {
        { USB_INTERFACE_INFO('X', 'B', 0) },    /* X-Box USB-IF not approved class */
+       { USB_DEVICE_INTERFACE_PROTOCOL(0x045e, 0x028e, 1) },   /* X-Box 360 controller */
        { }
 };
 
@@ -174,9 +191,16 @@ struct usb_xpad {
        unsigned char *idata;           /* input data */
        dma_addr_t idata_dma;
 
+#ifdef CONFIG_JOYSTICK_XPAD_FF
+       struct urb *irq_out;            /* urb for interrupt out report */
+       unsigned char *odata;           /* output data */
+       dma_addr_t odata_dma;
+#endif
+
        char phys[65];                  /* physical device path */
 
        int dpad_mapping;               /* map d-pad to buttons or to axes */
+       int xtype;                      /* type of xbox device */
 };
 
 /*
@@ -212,8 +236,8 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d
        } else /* xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS */ {
                input_report_key(dev, BTN_LEFT,  data[2] & 0x04);
                input_report_key(dev, BTN_RIGHT, data[2] & 0x08);
-               input_report_key(dev, BTN_0,     data[2] & 0x01); // up
-               input_report_key(dev, BTN_1,     data[2] & 0x02); // down
+               input_report_key(dev, BTN_0,     data[2] & 0x01); /* up */
+               input_report_key(dev, BTN_1,     data[2] & 0x02); /* down */
        }
 
        /* start/back buttons and stick press left/right */
@@ -235,6 +259,64 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d
        input_sync(dev);
 }
 
+/*
+ *     xpad360_process_packet
+ *
+ *     Completes a request by converting the data into events for the
+ *     input subsystem. It is version for xbox 360 controller
+ *
+ *     The used report descriptor was taken from:
+ *             http://www.free60.org/wiki/Gamepad
+ */
+
+static void xpad360_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data)
+{
+       struct input_dev *dev = xpad->dev;
+
+       /* digital pad */
+       if (xpad->dpad_mapping == MAP_DPAD_TO_AXES) {
+               input_report_abs(dev, ABS_HAT0X, !!(data[2] & 0x08) - !!(data[2] & 0x04));
+               input_report_abs(dev, ABS_HAT0Y, !!(data[2] & 0x02) - !!(data[2] & 0x01));
+       } else if (xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS) {
+               /* dpad as buttons (right, left, down, up) */
+               input_report_key(dev, BTN_LEFT, data[2] & 0x04);
+               input_report_key(dev, BTN_RIGHT, data[2] & 0x08);
+               input_report_key(dev, BTN_0, data[2] & 0x01);   /* up */
+               input_report_key(dev, BTN_1, data[2] & 0x02);   /* down */
+       }
+
+       /* start/back buttons */
+       input_report_key(dev, BTN_START,  data[2] & 0x10);
+       input_report_key(dev, BTN_BACK,   data[2] & 0x20);
+
+       /* stick press left/right */
+       input_report_key(dev, BTN_THUMBL, data[2] & 0x40);
+       input_report_key(dev, BTN_THUMBR, data[2] & 0x80);
+
+       /* buttons A,B,X,Y,TL,TR and MODE */
+       input_report_key(dev, BTN_A,    data[3] & 0x10);
+       input_report_key(dev, BTN_B,    data[3] & 0x20);
+       input_report_key(dev, BTN_X,    data[3] & 0x40);
+       input_report_key(dev, BTN_Y,    data[3] & 0x80);
+       input_report_key(dev, BTN_TL,   data[3] & 0x01);
+       input_report_key(dev, BTN_TR,   data[3] & 0x02);
+       input_report_key(dev, BTN_MODE, data[3] & 0x04);
+
+       /* left stick */
+       input_report_abs(dev, ABS_X, (__s16) (((__s16)data[7] << 8) | (__s16)data[6]));
+       input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[9] << 8) | (__s16)data[8]));
+
+       /* right stick */
+       input_report_abs(dev, ABS_RX, (__s16) (((__s16)data[11] << 8) | (__s16)data[10]));
+       input_report_abs(dev, ABS_RY, (__s16) (((__s16)data[13] << 8) | (__s16)data[12]));
+
+       /* triggers left/right */
+       input_report_abs(dev, ABS_Z, data[4]);
+       input_report_abs(dev, ABS_RZ, data[5]);
+
+       input_sync(dev);
+}
+
 static void xpad_irq_in(struct urb *urb)
 {
        struct usb_xpad *xpad = urb->context;
@@ -255,7 +337,10 @@ static void xpad_irq_in(struct urb *urb)
                goto exit;
        }
 
-       xpad_process_packet(xpad, 0, xpad->idata);
+       if (xpad->xtype == XTYPE_XBOX360)
+               xpad360_process_packet(xpad, 0, xpad->idata);
+       else
+               xpad_process_packet(xpad, 0, xpad->idata);
 
 exit:
        retval = usb_submit_urb (urb, GFP_ATOMIC);
@@ -264,7 +349,114 @@ exit:
                     __FUNCTION__, retval);
 }
 
-static int xpad_open (struct input_dev *dev)
+#ifdef CONFIG_JOYSTICK_XPAD_FF
+static void xpad_irq_out(struct urb *urb)
+{
+       int retval;
+
+       switch (urb->status) {
+               case 0:
+               /* success */
+               break;
+               case -ECONNRESET:
+               case -ENOENT:
+               case -ESHUTDOWN:
+                       /* this urb is terminated, clean up */
+                       dbg("%s - urb shutting down with status: %d",  __FUNCTION__, urb->status);
+                       return;
+               default:
+                       dbg("%s - nonzero urb status received: %d",  __FUNCTION__, urb->status);
+                       goto exit;
+       }
+
+exit:
+       retval = usb_submit_urb(urb, GFP_ATOMIC);
+       if (retval)
+               err("%s - usb_submit_urb failed with result %d",
+                  __FUNCTION__, retval);
+}
+
+static int xpad_play_effect(struct input_dev *dev, void *data,
+                           struct ff_effect *effect)
+{
+       struct usb_xpad *xpad = input_get_drvdata(dev);
+
+       if (effect->type == FF_RUMBLE) {
+               __u16 strong = effect->u.rumble.strong_magnitude;
+               __u16 weak = effect->u.rumble.weak_magnitude;
+               xpad->odata[0] = 0x00;
+               xpad->odata[1] = 0x08;
+               xpad->odata[2] = 0x00;
+               xpad->odata[3] = strong / 256;
+               xpad->odata[4] = weak / 256;
+               xpad->odata[5] = 0x00;
+               xpad->odata[6] = 0x00;
+               xpad->odata[7] = 0x00;
+               usb_submit_urb(xpad->irq_out, GFP_KERNEL);
+       }
+
+       return 0;
+}
+
+static int xpad_init_ff(struct usb_interface *intf, struct usb_xpad *xpad)
+{
+       struct usb_endpoint_descriptor *ep_irq_out;
+       int error = -ENOMEM;
+
+       if (xpad->xtype != XTYPE_XBOX360)
+               return 0;
+
+       xpad->odata = usb_buffer_alloc(xpad->udev, XPAD_PKT_LEN,
+                                      GFP_ATOMIC, &xpad->odata_dma );
+       if (!xpad->odata)
+               goto fail1;
+
+       xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL);
+       if (!xpad->irq_out)
+               goto fail2;
+
+       ep_irq_out = &intf->cur_altsetting->endpoint[1].desc;
+       usb_fill_int_urb(xpad->irq_out, xpad->udev,
+                        usb_sndintpipe(xpad->udev, ep_irq_out->bEndpointAddress),
+                        xpad->odata, XPAD_PKT_LEN,
+                        xpad_irq_out, xpad, ep_irq_out->bInterval);
+       xpad->irq_out->transfer_dma = xpad->odata_dma;
+       xpad->irq_out->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+       input_set_capability(xpad->dev, EV_FF, FF_RUMBLE);
+
+       error = input_ff_create_memless(xpad->dev, NULL, xpad_play_effect);
+       if (error)
+               goto fail2;
+
+       return 0;
+
+ fail2:        usb_buffer_free(xpad->udev, XPAD_PKT_LEN, xpad->odata, xpad->odata_dma);
+ fail1:        return error;
+}
+
+static void xpad_stop_ff(struct usb_xpad *xpad)
+{
+       if (xpad->xtype == XTYPE_XBOX360)
+               usb_kill_urb(xpad->irq_out);
+}
+
+static void xpad_deinit_ff(struct usb_xpad *xpad)
+{
+       if (xpad->xtype == XTYPE_XBOX360) {
+               usb_free_urb(xpad->irq_out);
+               usb_buffer_free(xpad->udev, XPAD_PKT_LEN,
+                               xpad->odata, xpad->odata_dma);
+       }
+}
+
+#else
+static int xpad_init_ff(struct usb_interface *intf, struct usb_xpad *xpad) { return 0; }
+static void xpad_stop_ff(struct usb_xpad *xpad) { }
+static void xpad_deinit_ff(struct usb_xpad *xpad) { }
+#endif
+
+static int xpad_open(struct input_dev *dev)
 {
        struct usb_xpad *xpad = input_get_drvdata(dev);
 
@@ -275,11 +467,12 @@ static int xpad_open (struct input_dev *dev)
        return 0;
 }
 
-static void xpad_close (struct input_dev *dev)
+static void xpad_close(struct input_dev *dev)
 {
        struct usb_xpad *xpad = input_get_drvdata(dev);
 
        usb_kill_urb(xpad->irq_in);
+       xpad_stop_ff(xpad);
 }
 
 static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs)
@@ -335,6 +528,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
 
        xpad->udev = udev;
        xpad->dpad_mapping = xpad_device[i].dpad_mapping;
+       xpad->xtype = xpad_device[i].xtype;
        if (xpad->dpad_mapping == MAP_DPAD_UNKNOWN)
                xpad->dpad_mapping = dpad_to_buttons;
        xpad->dev = input_dev;
@@ -356,6 +550,9 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
        /* set up buttons */
        for (i = 0; xpad_btn[i] >= 0; i++)
                set_bit(xpad_btn[i], input_dev->keybit);
+       if (xpad->xtype == XTYPE_XBOX360)
+               for (i = 0; xpad360_btn[i] >= 0; i++)
+                       set_bit(xpad360_btn[i], input_dev->keybit);
        if (xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS)
                for (i = 0; xpad_btn_pad[i] >= 0; i++)
                        set_bit(xpad_btn_pad[i], input_dev->keybit);
@@ -367,6 +564,10 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
                for (i = 0; xpad_abs_pad[i] >= 0; i++)
                    xpad_set_up_abs(input_dev, xpad_abs_pad[i]);
 
+       error = xpad_init_ff(intf, xpad);
+       if (error)
+               goto fail2;
+
        ep_irq_in = &intf->cur_altsetting->endpoint[0].desc;
        usb_fill_int_urb(xpad->irq_in, udev,
                         usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
@@ -396,10 +597,10 @@ static void xpad_disconnect(struct usb_interface *intf)
 
        usb_set_intfdata(intf, NULL);
        if (xpad) {
-               usb_kill_urb(xpad->irq_in);
                input_unregister_device(xpad->dev);
+               xpad_deinit_ff(xpad);
                usb_free_urb(xpad->irq_in);
-               usb_buffer_free(interface_to_usbdev(intf), XPAD_PKT_LEN,
+               usb_buffer_free(xpad->udev, XPAD_PKT_LEN,
                                xpad->idata, xpad->idata_dma);
                kfree(xpad);
        }
index 9950fcb33650a6ef015fe3343e527249df47f58f..41fc3d03b6eb495759cb93fbb7611e2acf76b712 100644 (file)
@@ -89,7 +89,7 @@ static unsigned char atkbd_set2_keycode[512] = {
          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
        217,100,255,  0, 97,165,  0,  0,156,  0,  0,  0,  0,  0,  0,125,
        173,114,  0,113,  0,  0,  0,126,128,  0,  0,140,  0,  0,  0,127,
-       159,  0,115,  0,164,  0,  0,116,158,  0,150,166,  0,  0,  0,142,
+       159,  0,115,  0,164,  0,  0,116,158,  0,172,166,  0,  0,  0,142,
        157,  0,  0,  0,  0,  0,  0,  0,155,  0, 98,  0,  0,163,  0,  0,
        226,  0,  0,  0,  0,  0,  0,  0,  0,255, 96,  0,  0,  0,143,  0,
          0,  0,  0,  0,  0,  0,  0,  0,  0,107,  0,105,102,  0,  0,112,
@@ -111,7 +111,7 @@ static unsigned char atkbd_set3_keycode[512] = {
         82, 83, 80, 76, 77, 72, 69, 98,  0, 96, 81,  0, 78, 73, 55,183,
 
        184,185,186,187, 74, 94, 92, 93,  0,  0,  0,125,126,127,112,  0,
-         0,139,150,163,165,115,152,150,166,140,160,154,113,114,167,168,
+         0,139,172,163,165,115,152,172,166,140,160,154,113,114,167,168,
        148,149,147,140
 };
 
index f9e82c9ca42191142dcab70ed8493072bc049d39..ebe5eacf299036c3b0c47ceac0f365c0a39bcec6 100644 (file)
@@ -140,7 +140,7 @@ static int pxakbd_resume(struct platform_device *pdev)
                KPREC = pdata->reg_kprec;
 
                /* Enable unit clock */
-               pxa_set_cken(CKEN19_KEYPAD, 1);
+               pxa_set_cken(CKEN_KEYPAD, 1);
        }
 
        mutex_unlock(&input_dev->mutex);
index 88e29074ac901c461aa687c995c3f58ae4fa353c..9b26574f1466a179a8a7782931855f2d946e3947 100644 (file)
@@ -65,9 +65,13 @@ config INPUT_COBALT_BTNS
 config INPUT_WISTRON_BTNS
        tristate "x86 Wistron laptop button interface"
        depends on X86 && !X86_64
+       select INPUT_POLLDEV
+       select NEW_LEDS
+       select LEDS_CLASS
        help
          Say Y here for support of Winstron laptop button interface, used on
-         laptops of various brands, including Acer and Fujitsu-Siemens.
+         laptops of various brands, including Acer and Fujitsu-Siemens. If
+         available, mail and wifi leds will be controlable via /sys/class/leds.
 
          To compile this driver as a module, choose M here: the module will
          be called wistron_btns.
index 961aad7a0476236c0002f1f476f8d482dcb2616b..60121f10f8d91203d481603c9295af4f52495390 100644 (file)
 #include <linux/io.h>
 #include <linux/dmi.h>
 #include <linux/init.h>
-#include <linux/input.h>
+#include <linux/input-polldev.h>
 #include <linux/interrupt.h>
+#include <linux/jiffies.h>
 #include <linux/kernel.h>
 #include <linux/mc146818rtc.h>
 #include <linux/module.h>
 #include <linux/preempt.h>
 #include <linux/string.h>
-#include <linux/timer.h>
 #include <linux/types.h>
 #include <linux/platform_device.h>
+#include <linux/leds.h>
 
-/*
- * Number of attempts to read data from queue per poll;
- * the queue can hold up to 31 entries
- */
-#define MAX_POLL_ITERATIONS 64
-
-#define POLL_FREQUENCY 10 /* Number of polls per second */
-
-#if POLL_FREQUENCY > HZ
-#error "POLL_FREQUENCY too high"
-#endif
+/* How often we poll keys - msecs */
+#define POLL_INTERVAL_DEFAULT  500 /* when idle */
+#define POLL_INTERVAL_BURST    100 /* when a key was recently pressed */
 
 /* BIOS subsystem IDs */
 #define WIFI           0x35
 #define BLUETOOTH      0x34
+#define MAIL_LED       0x31
 
 MODULE_AUTHOR("Miloslav Trmac <mitr@volny.cz>");
 MODULE_DESCRIPTION("Wistron laptop button driver");
 MODULE_LICENSE("GPL v2");
-MODULE_VERSION("0.2");
+MODULE_VERSION("0.3");
 
 static int force; /* = 0; */
 module_param(force, bool, 0);
@@ -248,9 +242,10 @@ enum { KE_END, KE_KEY, KE_SW, KE_WIFI, KE_BLUETOOTH };
 #define FE_WIFI_LED 0x02
 #define FE_UNTESTED 0x80
 
-static const struct key_entry *keymap; /* = NULL; Current key map */
+static struct key_entry *keymap; /* = NULL; Current key map */
 static int have_wifi;
 static int have_bluetooth;
+static int have_leds;
 
 static int __init dmi_matched(struct dmi_system_id *dmi)
 {
@@ -263,6 +258,8 @@ static int __init dmi_matched(struct dmi_system_id *dmi)
                else if (key->type == KE_BLUETOOTH)
                        have_bluetooth = 1;
        }
+       have_leds = key->code & (FE_MAIL_LED | FE_WIFI_LED);
+
        return 1;
 }
 
@@ -966,118 +963,163 @@ static int __init select_keymap(void)
 
  /* Input layer interface */
 
-static struct input_dev *input_dev;
+static struct input_polled_dev *wistron_idev;
+static unsigned long jiffies_last_press;
+static int wifi_enabled;
+static int bluetooth_enabled;
 
-static int __devinit setup_input_dev(void)
+static void report_key(struct input_dev *dev, unsigned int keycode)
 {
-       const struct key_entry *key;
-       int error;
+       input_report_key(dev, keycode, 1);
+       input_sync(dev);
+       input_report_key(dev, keycode, 0);
+       input_sync(dev);
+}
 
-       input_dev = input_allocate_device();
-       if (!input_dev)
-               return -ENOMEM;
+static void report_switch(struct input_dev *dev, unsigned int code, int value)
+{
+       input_report_switch(dev, code, value);
+       input_sync(dev);
+}
 
-       input_dev->name = "Wistron laptop buttons";
-       input_dev->phys = "wistron/input0";
-       input_dev->id.bustype = BUS_HOST;
-       input_dev->cdev.dev = &wistron_device->dev;
 
-       for (key = keymap; key->type != KE_END; key++) {
-               switch (key->type) {
-                       case KE_KEY:
-                               set_bit(EV_KEY, input_dev->evbit);
-                               set_bit(key->keycode, input_dev->keybit);
-                               break;
+ /* led management */
+static void wistron_mail_led_set(struct led_classdev *led_cdev,
+                               enum led_brightness value)
+{
+       bios_set_state(MAIL_LED, (value != LED_OFF) ? 1 : 0);
+}
 
-                       case KE_SW:
-                               set_bit(EV_SW, input_dev->evbit);
-                               set_bit(key->sw.code, input_dev->swbit);
-                               break;
+/* same as setting up wifi card, but for laptops on which the led is managed */
+static void wistron_wifi_led_set(struct led_classdev *led_cdev,
+                               enum led_brightness value)
+{
+       bios_set_state(WIFI, (value != LED_OFF) ? 1 : 0);
+}
 
-                       default:
-                               ;
-               }
-       }
+static struct led_classdev wistron_mail_led = {
+       .name                   = "mail:green",
+       .brightness_set         = wistron_mail_led_set,
+};
 
-       /* reads information flags on KE_END */
-       if (key->code & FE_UNTESTED)
-               printk(KERN_WARNING "Untested laptop multimedia keys, "
-                       "please report success or failure to eric.piel"
-                       "@tremplin-utc.net\n");
+static struct led_classdev wistron_wifi_led = {
+       .name                   = "wifi:red",
+       .brightness_set         = wistron_wifi_led_set,
+};
 
-       error = input_register_device(input_dev);
-       if (error) {
-               input_free_device(input_dev);
-               return error;
+static void __devinit wistron_led_init(struct device *parent)
+{
+       if (have_leds & FE_WIFI_LED) {
+               u16 wifi = bios_get_default_setting(WIFI);
+               if (wifi & 1) {
+                       wistron_wifi_led.brightness = (wifi & 2) ? LED_FULL : LED_OFF;
+                       if (led_classdev_register(parent, &wistron_wifi_led))
+                               have_leds &= ~FE_WIFI_LED;
+                       else
+                               bios_set_state(WIFI, wistron_wifi_led.brightness);
+
+               } else
+                       have_leds &= ~FE_WIFI_LED;
        }
 
-       return 0;
+       if (have_leds & FE_MAIL_LED) {
+               /* bios_get_default_setting(MAIL) always retuns 0, so just turn the led off */
+               wistron_mail_led.brightness = LED_OFF;
+               if (led_classdev_register(parent, &wistron_mail_led))
+                       have_leds &= ~FE_MAIL_LED;
+               else
+                       bios_set_state(MAIL_LED, wistron_mail_led.brightness);
+       }
 }
 
-static void report_key(unsigned keycode)
+static void __devexit wistron_led_remove(void)
 {
-       input_report_key(input_dev, keycode, 1);
-       input_sync(input_dev);
-       input_report_key(input_dev, keycode, 0);
-       input_sync(input_dev);
+       if (have_leds & FE_MAIL_LED)
+               led_classdev_unregister(&wistron_mail_led);
+
+       if (have_leds & FE_WIFI_LED)
+               led_classdev_unregister(&wistron_wifi_led);
 }
 
-static void report_switch(unsigned code, int value)
+static inline void wistron_led_suspend(void)
 {
-       input_report_switch(input_dev, code, value);
-       input_sync(input_dev);
+       if (have_leds & FE_MAIL_LED)
+               led_classdev_suspend(&wistron_mail_led);
+
+       if (have_leds & FE_WIFI_LED)
+               led_classdev_suspend(&wistron_wifi_led);
 }
 
- /* Driver core */
+static inline void wistron_led_resume(void)
+{
+       if (have_leds & FE_MAIL_LED)
+               led_classdev_resume(&wistron_mail_led);
 
-static int wifi_enabled;
-static int bluetooth_enabled;
+       if (have_leds & FE_WIFI_LED)
+               led_classdev_resume(&wistron_wifi_led);
+}
+
+static struct key_entry *wistron_get_entry_by_scancode(int code)
+{
+       struct key_entry *key;
 
-static void poll_bios(unsigned long);
+       for (key = keymap; key->type != KE_END; key++)
+               if (code == key->code)
+                       return key;
 
-static struct timer_list poll_timer = TIMER_INITIALIZER(poll_bios, 0, 0);
+       return NULL;
+}
 
-static void handle_key(u8 code)
+static struct key_entry *wistron_get_entry_by_keycode(int keycode)
 {
-       const struct key_entry *key;
+       struct key_entry *key;
 
-       for (key = keymap; key->type != KE_END; key++) {
-               if (code == key->code) {
-                       switch (key->type) {
-                       case KE_KEY:
-                               report_key(key->keycode);
-                               break;
+       for (key = keymap; key->type != KE_END; key++)
+               if (key->type == KE_KEY && keycode == key->keycode)
+                       return key;
 
-                       case KE_SW:
-                               report_switch(key->sw.code, key->sw.value);
-                               break;
+       return NULL;
+}
 
-                       case KE_WIFI:
-                               if (have_wifi) {
-                                       wifi_enabled = !wifi_enabled;
-                                       bios_set_state(WIFI, wifi_enabled);
-                               }
-                               break;
+static void handle_key(u8 code)
+{
+       const struct key_entry *key = wistron_get_entry_by_scancode(code);
 
-                       case KE_BLUETOOTH:
-                               if (have_bluetooth) {
-                                       bluetooth_enabled = !bluetooth_enabled;
-                                       bios_set_state(BLUETOOTH, bluetooth_enabled);
-                               }
-                               break;
+       if (key) {
+               switch (key->type) {
+               case KE_KEY:
+                       report_key(wistron_idev->input, key->keycode);
+                       break;
 
-                       case KE_END:
-                               break;
-                       default:
-                               BUG();
+               case KE_SW:
+                       report_switch(wistron_idev->input,
+                                     key->sw.code, key->sw.value);
+                       break;
+
+               case KE_WIFI:
+                       if (have_wifi) {
+                               wifi_enabled = !wifi_enabled;
+                               bios_set_state(WIFI, wifi_enabled);
+                       }
+                       break;
+
+               case KE_BLUETOOTH:
+                       if (have_bluetooth) {
+                               bluetooth_enabled = !bluetooth_enabled;
+                               bios_set_state(BLUETOOTH, bluetooth_enabled);
                        }
-                       return;
+                       break;
+
+               default:
+                       BUG();
                }
-       }
-       printk(KERN_NOTICE "wistron_btns: Unknown key code %02X\n", code);
+               jiffies_last_press = jiffies;
+       } else
+               printk(KERN_NOTICE
+                       "wistron_btns: Unknown key code %02X\n", code);
 }
 
-static void poll_bios(unsigned long discard)
+static void poll_bios(bool discard)
 {
        u8 qlen;
        u16 val;
@@ -1090,15 +1132,118 @@ static void poll_bios(unsigned long discard)
                if (val != 0 && !discard)
                        handle_key((u8)val);
        }
+}
+
+static void wistron_flush(struct input_polled_dev *dev)
+{
+       /* Flush stale event queue */
+       poll_bios(true);
+}
+
+static void wistron_poll(struct input_polled_dev *dev)
+{
+       poll_bios(false);
+
+       /* Increase poll frequency if user is currently pressing keys (< 2s ago) */
+       if (time_before(jiffies, jiffies_last_press + 2 * HZ))
+               dev->poll_interval = POLL_INTERVAL_BURST;
+       else
+               dev->poll_interval = POLL_INTERVAL_DEFAULT;
+}
+
+static int wistron_getkeycode(struct input_dev *dev, int scancode, int *keycode)
+{
+       const struct key_entry *key = wistron_get_entry_by_scancode(scancode);
+
+       if (key && key->type == KE_KEY) {
+               *keycode = key->keycode;
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
+static int wistron_setkeycode(struct input_dev *dev, int scancode, int keycode)
+{
+       struct key_entry *key;
+       int old_keycode;
+
+       if (keycode < 0 || keycode > KEY_MAX)
+               return -EINVAL;
+
+       key = wistron_get_entry_by_scancode(scancode);
+       if (key && key->type == KE_KEY) {
+               old_keycode = key->keycode;
+               key->keycode = keycode;
+               set_bit(keycode, dev->keybit);
+               if (!wistron_get_entry_by_keycode(old_keycode))
+                       clear_bit(old_keycode, dev->keybit);
+               return 0;
+       }
 
-       mod_timer(&poll_timer, jiffies + HZ / POLL_FREQUENCY);
+       return -EINVAL;
 }
 
+static int __devinit setup_input_dev(void)
+{
+       const struct key_entry *key;
+       struct input_dev *input_dev;
+       int error;
+
+       wistron_idev = input_allocate_polled_device();
+       if (!wistron_idev)
+               return -ENOMEM;
+
+       wistron_idev->flush = wistron_flush;
+       wistron_idev->poll = wistron_poll;
+       wistron_idev->poll_interval = POLL_INTERVAL_DEFAULT;
+
+       input_dev = wistron_idev->input;
+       input_dev->name = "Wistron laptop buttons";
+       input_dev->phys = "wistron/input0";
+       input_dev->id.bustype = BUS_HOST;
+       input_dev->dev.parent = &wistron_device->dev;
+
+       input_dev->getkeycode = wistron_getkeycode;
+       input_dev->setkeycode = wistron_setkeycode;
+
+       for (key = keymap; key->type != KE_END; key++) {
+               switch (key->type) {
+                       case KE_KEY:
+                               set_bit(EV_KEY, input_dev->evbit);
+                               set_bit(key->keycode, input_dev->keybit);
+                               break;
+
+                       case KE_SW:
+                               set_bit(EV_SW, input_dev->evbit);
+                               set_bit(key->sw.code, input_dev->swbit);
+                               break;
+
+                       default:
+                               break;
+               }
+       }
+
+       /* reads information flags on KE_END */
+       if (key->code & FE_UNTESTED)
+               printk(KERN_WARNING "Untested laptop multimedia keys, "
+                       "please report success or failure to eric.piel"
+                       "@tremplin-utc.net\n");
+
+       error = input_register_polled_device(wistron_idev);
+       if (error) {
+               input_free_polled_device(wistron_idev);
+               return error;
+       }
+
+       return 0;
+}
+
+/* Driver core */
+
 static int __devinit wistron_probe(struct platform_device *dev)
 {
-       int err = setup_input_dev();
-       if (err)
-               return err;
+       int err;
 
        bios_attach();
        cmos_address = bios_get_cmos_address();
@@ -1125,15 +1270,21 @@ static int __devinit wistron_probe(struct platform_device *dev)
                        bios_set_state(BLUETOOTH, bluetooth_enabled);
        }
 
-       poll_bios(1); /* Flush stale event queue and arm timer */
+       wistron_led_init(&dev->dev);
+       err = setup_input_dev();
+       if (err) {
+               bios_detach();
+               return err;
+       }
 
        return 0;
 }
 
 static int __devexit wistron_remove(struct platform_device *dev)
 {
-       del_timer_sync(&poll_timer);
-       input_unregister_device(input_dev);
+       wistron_led_remove();
+       input_unregister_polled_device(wistron_idev);
+       input_free_polled_device(wistron_idev);
        bios_detach();
 
        return 0;
@@ -1142,14 +1293,13 @@ static int __devexit wistron_remove(struct platform_device *dev)
 #ifdef CONFIG_PM
 static int wistron_suspend(struct platform_device *dev, pm_message_t state)
 {
-       del_timer_sync(&poll_timer);
-
        if (have_wifi)
                bios_set_state(WIFI, 0);
 
        if (have_bluetooth)
                bios_set_state(BLUETOOTH, 0);
 
+       wistron_led_suspend();
        return 0;
 }
 
@@ -1161,7 +1311,8 @@ static int wistron_resume(struct platform_device *dev)
        if (have_bluetooth)
                bios_set_state(BLUETOOTH, bluetooth_enabled);
 
-       poll_bios(1);
+       wistron_led_resume();
+       poll_bios(true);
 
        return 0;
 }
index 50e06e8dd05d764a2af87fe7aa8d5c5e6f52db94..7bbea097cda2849108a9e5c052101226059e1802 100644 (file)
@@ -216,4 +216,20 @@ config MOUSE_HIL
        help
          Say Y here to support HIL pointers.
 
+config MOUSE_GPIO
+       tristate "GPIO mouse"
+       depends on GENERIC_GPIO
+       select INPUT_POLLDEV
+       help
+         This driver simulates a mouse on GPIO lines of various CPUs (and some
+         other chips).
+
+         Say Y here if your device has buttons or a simple joystick connected
+         directly to GPIO lines. Your board-specific setup logic must also
+         provide a platform device and platform data saying which GPIOs are
+         used.
+
+         To compile this driver as a module, choose M here: the
+         module will be called gpio_mouse.
+
 endif
index aa4ba878533f13956b7afe867639fc43714fc894..9e6e36330820e7d9dc4092a45e2cfd53a6530204 100644 (file)
@@ -15,6 +15,7 @@ obj-$(CONFIG_MOUSE_PS2)               += psmouse.o
 obj-$(CONFIG_MOUSE_SERIAL)     += sermouse.o
 obj-$(CONFIG_MOUSE_HIL)                += hil_ptr.o
 obj-$(CONFIG_MOUSE_VSXXXAA)    += vsxxxaa.o
+obj-$(CONFIG_MOUSE_GPIO)       += gpio_mouse.o
 
 psmouse-objs := psmouse-base.o synaptics.o
 
diff --git a/drivers/input/mouse/gpio_mouse.c b/drivers/input/mouse/gpio_mouse.c
new file mode 100644 (file)
index 0000000..0936d6b
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ * Driver for simulating a mouse on GPIO lines.
+ *
+ * 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/init.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/input-polldev.h>
+#include <linux/gpio_mouse.h>
+
+#include <asm/gpio.h>
+
+/*
+ * Timer function which is run every scan_ms ms when the device is opened.
+ * The dev input varaible is set to the the input_dev pointer.
+ */
+static void gpio_mouse_scan(struct input_polled_dev *dev)
+{
+       struct gpio_mouse_platform_data *gpio = dev->private;
+       struct input_dev *input = dev->input;
+       int x, y;
+
+       if (gpio->bleft >= 0)
+               input_report_key(input, BTN_LEFT,
+                               gpio_get_value(gpio->bleft) ^ gpio->polarity);
+       if (gpio->bmiddle >= 0)
+               input_report_key(input, BTN_MIDDLE,
+                               gpio_get_value(gpio->bmiddle) ^ gpio->polarity);
+       if (gpio->bright >= 0)
+               input_report_key(input, BTN_RIGHT,
+                               gpio_get_value(gpio->bright) ^ gpio->polarity);
+
+       x = (gpio_get_value(gpio->right) ^ gpio->polarity)
+               - (gpio_get_value(gpio->left) ^ gpio->polarity);
+       y = (gpio_get_value(gpio->down) ^ gpio->polarity)
+               - (gpio_get_value(gpio->up) ^ gpio->polarity);
+
+       input_report_rel(input, REL_X, x);
+       input_report_rel(input, REL_Y, y);
+       input_sync(input);
+}
+
+static int __init gpio_mouse_probe(struct platform_device *pdev)
+{
+       struct gpio_mouse_platform_data *pdata = pdev->dev.platform_data;
+       struct input_polled_dev *input_poll;
+       struct input_dev *input;
+       int pin, i;
+       int error;
+
+       if (!pdata) {
+               dev_err(&pdev->dev, "no platform data\n");
+               error = -ENXIO;
+               goto out;
+       }
+
+       if (pdata->scan_ms < 0) {
+               dev_err(&pdev->dev, "invalid scan time\n");
+               error = -EINVAL;
+               goto out;
+       }
+
+       for (i = 0; i < GPIO_MOUSE_PIN_MAX; i++) {
+               pin = pdata->pins[i];
+
+               if (pin < 0) {
+
+                       if (i <= GPIO_MOUSE_PIN_RIGHT) {
+                               /* Mouse direction is required. */
+                               dev_err(&pdev->dev,
+                                       "missing GPIO for directions\n");
+                               error = -EINVAL;
+                               goto out_free_gpios;
+                       }
+
+                       if (i == GPIO_MOUSE_PIN_BLEFT)
+                               dev_dbg(&pdev->dev, "no left button defined\n");
+
+               } else {
+                       error = gpio_request(pin, "gpio_mouse");
+                       if (error) {
+                               dev_err(&pdev->dev, "fail %d pin (%d idx)\n",
+                                       pin, i);
+                               goto out_free_gpios;
+                       }
+
+                       gpio_direction_input(pin);
+               }
+       }
+
+       input_poll = input_allocate_polled_device();
+       if (!input_poll) {
+               dev_err(&pdev->dev, "not enough memory for input device\n");
+               error = -ENOMEM;
+               goto out_free_gpios;
+       }
+
+       platform_set_drvdata(pdev, input_poll);
+
+       /* set input-polldev handlers */
+       input_poll->private = pdata;
+       input_poll->poll = gpio_mouse_scan;
+       input_poll->poll_interval = pdata->scan_ms;
+
+       input = input_poll->input;
+       input->name = pdev->name;
+       input->id.bustype = BUS_HOST;
+       input->dev.parent = &pdev->dev;
+
+       input_set_capability(input, EV_REL, REL_X);
+       input_set_capability(input, EV_REL, REL_Y);
+       if (pdata->bleft >= 0)
+               input_set_capability(input, EV_KEY, BTN_LEFT);
+       if (pdata->bmiddle >= 0)
+               input_set_capability(input, EV_KEY, BTN_MIDDLE);
+       if (pdata->bright >= 0)
+               input_set_capability(input, EV_KEY, BTN_RIGHT);
+
+       error = input_register_polled_device(input_poll);
+       if (error) {
+               dev_err(&pdev->dev, "could not register input device\n");
+               goto out_free_polldev;
+       }
+
+       dev_dbg(&pdev->dev, "%d ms scan time, buttons: %s%s%s\n",
+                       pdata->scan_ms,
+                       pdata->bleft < 0 ? "" : "left ",
+                       pdata->bmiddle < 0 ? "" : "middle ",
+                       pdata->bright < 0 ? "" : "right");
+
+       return 0;
+
+ out_free_polldev:
+       input_free_polled_device(input_poll);
+       platform_set_drvdata(pdev, NULL);
+
+ out_free_gpios:
+       while (--i >= 0) {
+               pin = pdata->pins[i];
+               if (pin)
+                       gpio_free(pin);
+       }
+ out:
+       return error;
+}
+
+static int __devexit gpio_mouse_remove(struct platform_device *pdev)
+{
+       struct input_polled_dev *input = platform_get_drvdata(pdev);
+       struct gpio_mouse_platform_data *pdata = input->private;
+       int pin, i;
+
+       input_unregister_polled_device(input);
+       input_free_polled_device(input);
+
+       for (i = 0; i < GPIO_MOUSE_PIN_MAX; i++) {
+               pin = pdata->pins[i];
+               if (pin >= 0)
+                       gpio_free(pin);
+       }
+
+       platform_set_drvdata(pdev, NULL);
+
+       return 0;
+}
+
+struct platform_driver gpio_mouse_device_driver = {
+       .remove         = __devexit_p(gpio_mouse_remove),
+       .driver         = {
+               .name   = "gpio_mouse",
+       }
+};
+
+static int __init gpio_mouse_init(void)
+{
+       return platform_driver_probe(&gpio_mouse_device_driver,
+                       gpio_mouse_probe);
+}
+module_init(gpio_mouse_init);
+
+static void __exit gpio_mouse_exit(void)
+{
+       platform_driver_unregister(&gpio_mouse_device_driver);
+}
+module_exit(gpio_mouse_exit);
+
+MODULE_AUTHOR("Hans-Christian Egtvedt <hcegtvedt@atmel.com>");
+MODULE_DESCRIPTION("GPIO mouse driver");
+MODULE_LICENSE("GPL");
index f15f695777f8ff6b0c352a948a9a1bc0fe942a2f..b9f0fb2530e2357cb1f39ff1e52d48cf764ccc1b 100644 (file)
@@ -177,6 +177,15 @@ static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
                packet[1] |= (packet[0] & 0x40) << 1;
        }
 
+/*
+ * Cortron PS2 Trackball reports SIDE button on the 4th bit of the first
+ * byte.
+ */
+       if (psmouse->type == PSMOUSE_CORTRON) {
+               input_report_key(dev, BTN_SIDE, (packet[0] >> 3) & 1);
+               packet[0] |= 0x08;
+       }
+
 /*
  * Generic PS/2 Mouse
  */
@@ -539,6 +548,20 @@ static int ps2bare_detect(struct psmouse *psmouse, int set_properties)
        return 0;
 }
 
+/*
+ * Cortron PS/2 protocol detection. There's no special way to detect it, so it
+ * must be forced by sysfs protocol writing.
+ */
+static int cortron_detect(struct psmouse *psmouse, int set_properties)
+{
+       if (set_properties) {
+               psmouse->vendor = "Cortron";
+               psmouse->name = "PS/2 Trackball";
+               set_bit(BTN_SIDE, psmouse->dev->keybit);
+       }
+
+       return 0;
+}
 
 /*
  * psmouse_extensions() probes for any extensions to the basic PS/2 protocol
@@ -739,6 +762,12 @@ static const struct psmouse_protocol psmouse_protocols[] = {
                .detect         = touchkit_ps2_detect,
        },
 #endif
+       {
+               .type           = PSMOUSE_CORTRON,
+               .name           = "CortronPS/2",
+               .alias          = "cortps",
+               .detect         = cortron_detect,
+       },
        {
                .type           = PSMOUSE_AUTO,
                .name           = "auto",
index 3964e8acbc54da1b96c2f67fd12bc9f13ca61151..1317bdd8cc7c42c935fac9899c5bdcbda0a5a51b 100644 (file)
@@ -88,6 +88,7 @@ enum psmouse_type {
        PSMOUSE_LIFEBOOK,
        PSMOUSE_TRACKPOINT,
        PSMOUSE_TOUCHKIT_PS2,
+       PSMOUSE_CORTRON,
        PSMOUSE_AUTO            /* This one should always be last */
 };
 
@@ -118,7 +119,6 @@ static struct psmouse_attribute psmouse_attr_##_name = {                    \
                .attr   = {                                                     \
                        .name   = __stringify(_name),                           \
                        .mode   = _mode,                                        \
-                       .owner  = THIS_MODULE,                                  \
                },                                                              \
                .show   = psmouse_attr_show_helper,                             \
                .store  = psmouse_attr_set_helper,                              \
index 3f4866d8d18c85a8dae983273ba578e2e1df3d8f..9173916b8be5f34b84a02d1697ad8bdcc0483676 100644 (file)
@@ -64,6 +64,7 @@ struct mousedev {
        wait_queue_head_t wait;
        struct list_head client_list;
        struct input_handle handle;
+       struct device dev;
 
        struct list_head mixdev_node;
        int mixdev_open;
@@ -112,7 +113,7 @@ static unsigned char mousedev_imex_seq[] = { 0xf3, 200, 0xf3, 200, 0xf3, 80 };
 static struct input_handler mousedev_handler;
 
 static struct mousedev *mousedev_table[MOUSEDEV_MINORS];
-static struct mousedev mousedev_mix;
+static struct mousedev *mousedev_mix;
 static LIST_HEAD(mousedev_mix_list);
 
 #define fx(i)  (mousedev->old_x[(mousedev->pkt_count - (i)) & 03])
@@ -218,10 +219,10 @@ static void mousedev_key_event(struct mousedev *mousedev, unsigned int code, int
 
        if (value) {
                set_bit(index, &mousedev->packet.buttons);
-               set_bit(index, &mousedev_mix.packet.buttons);
+               set_bit(index, &mousedev_mix->packet.buttons);
        } else {
                clear_bit(index, &mousedev->packet.buttons);
-               clear_bit(index, &mousedev_mix.packet.buttons);
+               clear_bit(index, &mousedev_mix->packet.buttons);
        }
 }
 
@@ -287,11 +288,11 @@ static void mousedev_touchpad_touch(struct mousedev *mousedev, int value)
                         * motion packet so we won't mess current position.
                         */
                        set_bit(0, &mousedev->packet.buttons);
-                       set_bit(0, &mousedev_mix.packet.buttons);
-                       mousedev_notify_readers(mousedev, &mousedev_mix.packet);
-                       mousedev_notify_readers(&mousedev_mix, &mousedev_mix.packet);
+                       set_bit(0, &mousedev_mix->packet.buttons);
+                       mousedev_notify_readers(mousedev, &mousedev_mix->packet);
+                       mousedev_notify_readers(mousedev_mix, &mousedev_mix->packet);
                        clear_bit(0, &mousedev->packet.buttons);
-                       clear_bit(0, &mousedev_mix.packet.buttons);
+                       clear_bit(0, &mousedev_mix->packet.buttons);
                }
                mousedev->touch = mousedev->pkt_count = 0;
                mousedev->frac_dx = 0;
@@ -343,7 +344,7 @@ static void mousedev_event(struct input_handle *handle, unsigned int type, unsig
                                }
 
                                mousedev_notify_readers(mousedev, &mousedev->packet);
-                               mousedev_notify_readers(&mousedev_mix, &mousedev->packet);
+                               mousedev_notify_readers(mousedev_mix, &mousedev->packet);
 
                                mousedev->packet.dx = mousedev->packet.dy = mousedev->packet.dz = 0;
                                mousedev->packet.abs_event = 0;
@@ -362,8 +363,10 @@ static int mousedev_fasync(int fd, struct file *file, int on)
        return retval < 0 ? retval : 0;
 }
 
-static void mousedev_free(struct mousedev *mousedev)
+static void mousedev_free(struct device *dev)
 {
+       struct mousedev *mousedev = container_of(dev, struct mousedev, dev);
+
        mousedev_table[mousedev->minor] = NULL;
        kfree(mousedev);
 }
@@ -372,15 +375,16 @@ static int mixdev_add_device(struct mousedev *mousedev)
 {
        int error;
 
-       if (mousedev_mix.open) {
+       if (mousedev_mix->open) {
                error = input_open_device(&mousedev->handle);
                if (error)
                        return error;
 
                mousedev->open++;
-               mousedev->mixdev_open++;
+               mousedev->mixdev_open = 1;
        }
 
+       get_device(&mousedev->dev);
        list_add_tail(&mousedev->mixdev_node, &mousedev_mix_list);
 
        return 0;
@@ -395,36 +399,40 @@ static void mixdev_remove_device(struct mousedev *mousedev)
        }
 
        list_del_init(&mousedev->mixdev_node);
+       put_device(&mousedev->dev);
 }
 
 static void mixdev_open_devices(void)
 {
        struct mousedev *mousedev;
 
+       if (mousedev_mix->open++)
+               return;
+
        list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) {
-               if (mousedev->exist && !mousedev->open) {
-                       if (input_open_device(&mousedev->handle))
-                               continue;
+               if (!mousedev->mixdev_open) {
+                       if (!mousedev->open && mousedev->exist)
+                               if (input_open_device(&mousedev->handle))
+                                       continue;
 
                        mousedev->open++;
-                       mousedev->mixdev_open++;
+                       mousedev->mixdev_open = 1;
                }
        }
 }
 
 static void mixdev_close_devices(void)
 {
-       struct mousedev *mousedev, *next;
+       struct mousedev *mousedev;
 
-       list_for_each_entry_safe(mousedev, next, &mousedev_mix_list, mixdev_node) {
+       if (--mousedev_mix->open)
+               return;
+
+       list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) {
                if (mousedev->mixdev_open) {
                        mousedev->mixdev_open = 0;
-                       if (!--mousedev->open) {
-                               if (mousedev->exist)
-                                       input_close_device(&mousedev->handle);
-                               else
-                                       mousedev_free(mousedev);
-                       }
+                       if (!--mousedev->open && mousedev->exist)
+                               input_close_device(&mousedev->handle);
                }
        }
 }
@@ -439,14 +447,12 @@ static int mousedev_release(struct inode *inode, struct file *file)
        list_del(&client->node);
        kfree(client);
 
-       if (!--mousedev->open) {
-               if (mousedev->minor == MOUSEDEV_MIX)
-                       mixdev_close_devices();
-               else if (mousedev->exist)
-                       input_close_device(&mousedev->handle);
-               else
-                       mousedev_free(mousedev);
-       }
+       if (mousedev->minor == MOUSEDEV_MIX)
+               mixdev_close_devices();
+       else if (!--mousedev->open && mousedev->exist)
+               input_close_device(&mousedev->handle);
+
+       put_device(&mousedev->dev);
 
        return 0;
 }
@@ -473,9 +479,13 @@ static int mousedev_open(struct inode *inode, struct file *file)
        if (!mousedev)
                return -ENODEV;
 
+       get_device(&mousedev->dev);
+
        client = kzalloc(sizeof(struct mousedev_client), GFP_KERNEL);
-       if (!client)
-               return -ENOMEM;
+       if (!client) {
+               error = -ENOMEM;
+               goto err_put_mousedev;
+       }
 
        spin_lock_init(&client->packet_lock);
        client->pos_x = xres / 2;
@@ -483,21 +493,23 @@ static int mousedev_open(struct inode *inode, struct file *file)
        client->mousedev = mousedev;
        list_add_tail(&client->node, &mousedev->client_list);
 
-       if (!mousedev->open++) {
-               if (mousedev->minor == MOUSEDEV_MIX)
-                       mixdev_open_devices();
-               else if (mousedev->exist) {
-                       error = input_open_device(&mousedev->handle);
-                       if (error) {
-                               list_del(&client->node);
-                               kfree(client);
-                               return error;
-                       }
-               }
+       if (mousedev->minor == MOUSEDEV_MIX)
+               mixdev_open_devices();
+       else if (!mousedev->open++ && mousedev->exist) {
+               error = input_open_device(&mousedev->handle);
+               if (error)
+                       goto err_free_client;
        }
 
        file->private_data = client;
        return 0;
+
+ err_free_client:
+       list_del(&client->node);
+       kfree(client);
+ err_put_mousedev:
+       put_device(&mousedev->dev);
+       return error;
 }
 
 static inline int mousedev_limit_delta(int delta, int limit)
@@ -680,57 +692,96 @@ static const struct file_operations mousedev_fops = {
        .fasync =       mousedev_fasync,
 };
 
-static int mousedev_connect(struct input_handler *handler, struct input_dev *dev,
-                           const struct input_device_id *id)
+static struct mousedev *mousedev_create(struct input_dev *dev,
+                                       struct input_handler *handler,
+                                       int minor)
 {
        struct mousedev *mousedev;
-       struct class_device *cdev;
-       dev_t devt;
-       int minor;
        int error;
 
-       for (minor = 0; minor < MOUSEDEV_MINORS && mousedev_table[minor]; minor++);
-       if (minor == MOUSEDEV_MINORS) {
-               printk(KERN_ERR "mousedev: no more free mousedev devices\n");
-               return -ENFILE;
-       }
-
        mousedev = kzalloc(sizeof(struct mousedev), GFP_KERNEL);
-       if (!mousedev)
-               return -ENOMEM;
+       if (!mousedev) {
+               error = -ENOMEM;
+               goto err_out;
+       }
 
        INIT_LIST_HEAD(&mousedev->client_list);
        INIT_LIST_HEAD(&mousedev->mixdev_node);
        init_waitqueue_head(&mousedev->wait);
 
+       if (minor == MOUSEDEV_MIX)
+               strlcpy(mousedev->name, "mice", sizeof(mousedev->name));
+       else
+               snprintf(mousedev->name, sizeof(mousedev->name),
+                        "mouse%d", minor);
+
        mousedev->minor = minor;
        mousedev->exist = 1;
        mousedev->handle.dev = dev;
        mousedev->handle.name = mousedev->name;
        mousedev->handle.handler = handler;
        mousedev->handle.private = mousedev;
-       sprintf(mousedev->name, "mouse%d", minor);
 
-       mousedev_table[minor] = mousedev;
+       strlcpy(mousedev->dev.bus_id, mousedev->name,
+               sizeof(mousedev->dev.bus_id));
+       mousedev->dev.class = &input_class;
+       if (dev)
+               mousedev->dev.parent = &dev->dev;
+       mousedev->dev.devt = MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor);
+       mousedev->dev.release = mousedev_free;
+       device_initialize(&mousedev->dev);
 
-       devt = MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor),
+       mousedev_table[minor] = mousedev;
 
-       cdev = class_device_create(&input_class, &dev->cdev, devt,
-                                  dev->cdev.dev, mousedev->name);
-       if (IS_ERR(cdev)) {
-               error = PTR_ERR(cdev);
+       error = device_add(&mousedev->dev);
+       if (error)
                goto err_free_mousedev;
+
+       return mousedev;
+
+ err_free_mousedev:
+       put_device(&mousedev->dev);
+ err_out:
+       return ERR_PTR(error);
+}
+
+static void mousedev_destroy(struct mousedev *mousedev)
+{
+       struct mousedev_client *client;
+
+       device_del(&mousedev->dev);
+       mousedev->exist = 0;
+
+       if (mousedev->open) {
+               input_close_device(&mousedev->handle);
+               list_for_each_entry(client, &mousedev->client_list, node)
+                       kill_fasync(&client->fasync, SIGIO, POLL_HUP);
+               wake_up_interruptible(&mousedev->wait);
        }
 
-       /* temporary symlink to keep userspace happy */
-       error = sysfs_create_link(&input_class.subsys.kobj,
-                                 &cdev->kobj, mousedev->name);
-       if (error)
-               goto err_cdev_destroy;
+       put_device(&mousedev->dev);
+}
+
+static int mousedev_connect(struct input_handler *handler, struct input_dev *dev,
+                           const struct input_device_id *id)
+{
+       struct mousedev *mousedev;
+       int minor;
+       int error;
+
+       for (minor = 0; minor < MOUSEDEV_MINORS && mousedev_table[minor]; minor++);
+       if (minor == MOUSEDEV_MINORS) {
+               printk(KERN_ERR "mousedev: no more free mousedev devices\n");
+               return -ENFILE;
+       }
+
+       mousedev = mousedev_create(dev, handler, minor);
+       if (IS_ERR(mousedev))
+               return PTR_ERR(mousedev);
 
        error = input_register_handle(&mousedev->handle);
        if (error)
-               goto err_remove_link;
+               goto err_delete_mousedev;
 
        error = mixdev_add_device(mousedev);
        if (error)
@@ -740,37 +791,18 @@ static int mousedev_connect(struct input_handler *handler, struct input_dev *dev
 
  err_unregister_handle:
        input_unregister_handle(&mousedev->handle);
- err_remove_link:
-       sysfs_remove_link(&input_class.subsys.kobj, mousedev->name);
- err_cdev_destroy:
-       class_device_destroy(&input_class, devt);
- err_free_mousedev:
-       mousedev_table[minor] = NULL;
-       kfree(mousedev);
+ err_delete_mousedev:
+       device_unregister(&mousedev->dev);
        return error;
 }
 
 static void mousedev_disconnect(struct input_handle *handle)
 {
        struct mousedev *mousedev = handle->private;
-       struct mousedev_client *client;
-
-       input_unregister_handle(handle);
-
-       sysfs_remove_link(&input_class.subsys.kobj, mousedev->name);
-       class_device_destroy(&input_class,
-                       MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + mousedev->minor));
-       mousedev->exist = 0;
 
        mixdev_remove_device(mousedev);
-
-       if (mousedev->open) {
-               input_close_device(handle);
-               list_for_each_entry(client, &mousedev->client_list, node)
-                       kill_fasync(&client->fasync, SIGIO, POLL_HUP);
-               wake_up_interruptible(&mousedev->wait);
-       } else
-               mousedev_free(mousedev);
+       input_unregister_handle(handle);
+       mousedev_destroy(mousedev);
 }
 
 static const struct input_device_id mousedev_ids[] = {
@@ -822,25 +854,16 @@ static int psaux_registered;
 
 static int __init mousedev_init(void)
 {
-       struct class_device *cdev;
        int error;
 
+       mousedev_mix = mousedev_create(NULL, &mousedev_handler, MOUSEDEV_MIX);
+       if (IS_ERR(mousedev_mix))
+               return PTR_ERR(mousedev_mix);
+
        error = input_register_handler(&mousedev_handler);
-       if (error)
+       if (error) {
+               mousedev_destroy(mousedev_mix);
                return error;
-
-       memset(&mousedev_mix, 0, sizeof(struct mousedev));
-       INIT_LIST_HEAD(&mousedev_mix.client_list);
-       init_waitqueue_head(&mousedev_mix.wait);
-       mousedev_table[MOUSEDEV_MIX] = &mousedev_mix;
-       mousedev_mix.exist = 1;
-       mousedev_mix.minor = MOUSEDEV_MIX;
-
-       cdev = class_device_create(&input_class, NULL,
-                       MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX), NULL, "mice");
-       if (IS_ERR(cdev)) {
-               input_unregister_handler(&mousedev_handler);
-               return PTR_ERR(cdev);
        }
 
 #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
@@ -863,9 +886,8 @@ static void __exit mousedev_exit(void)
        if (psaux_registered)
                misc_deregister(&psaux_mouse);
 #endif
-       class_device_destroy(&input_class,
-                       MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX));
        input_unregister_handler(&mousedev_handler);
+       mousedev_destroy(mousedev_mix);
 }
 
 module_init(mousedev_init);
index 887357666c683f0337dfe8dfef3756fd3fe77ad2..0403622ae26752976327823802861b321b521d69 100644 (file)
@@ -160,7 +160,7 @@ static ssize_t serio_raw_read(struct file *file, char __user *buffer, size_t cou
 {
        struct serio_raw_list *list = file->private_data;
        struct serio_raw *serio_raw = list->serio_raw;
-       char c;
+       char uninitialized_var(c);
        ssize_t retval = 0;
 
        if (!serio_raw->serio)
index cc0a498763d8db609e7dd03d5086f50010931765..94683f58c9e18ec5b933d7721ab3b07467ae9a1c 100644 (file)
@@ -82,8 +82,8 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.5 (May-15-2004)"
-#define DRIVER_AUTHOR  "Bryan W. Headley/Chris Atenasio"
+#define DRIVER_VERSION "v2.3 (May 2, 2007)"
+#define DRIVER_AUTHOR  "Bryan W. Headley/Chris Atenasio/Cedric Brun/Rene van Paassen"
 #define DRIVER_DESC    "Aiptek HyperPen USB Tablet Driver (Linux 2.6.x)"
 
 /*
  * (returned as Report 3 - absolute coordinates from the mouse)
  *
  *        bit7  bit6  bit5  bit4  bit3  bit2  bit1  bit0
- * byte0   0     0     0     0     0     0     1     0
+ * byte0   0     0     0     0     0     0     1     1
  * byte1  X7    X6    X5    X4    X3    X2    X1    X0
  * byte2  X15   X14   X13   X12   X11   X10   X9    X8
  * byte3  Y7    Y6    Y5    Y4    Y3    Y2    Y1    Y0
  * (returned as Report 5 - macrokeys from the mouse)
  *
  *        bit7  bit6  bit5  bit4  bit3  bit2  bit1  bit0
- * byte0   0     0     0     0     0     1     0     0
+ * byte0   0     0     0     0     0     1     0     1
  * byte1   0     0     0    BS2   BS    Tip   IR    DV
  * byte2   0     0     0     0     0     0     1     0
  * byte3   0     0     0    K4    K3    K2    K1    K0
 #define AIPTEK_WHEEL_DISABLE                           (-10101)
 
        /* ToolCode values, which BTW are 0x140 .. 0x14f
-        * We have things set up such that if TOOL_BUTTON_FIRED_BIT is
-        * not set, we'll send one instance of AIPTEK_TOOL_BUTTON_xxx.
-        *
-        * Whenever the user resets the value, TOOL_BUTTON_FIRED_BIT will
-        * get reset.
+        * We have things set up such that if the tool button has changed,
+        * the tools get reset.
         */
-#define TOOL_BUTTON(x)                                 ((x) & 0x14f)
-#define TOOL_BUTTON_FIRED(x)                           ((x) & 0x200)
-#define TOOL_BUTTON_FIRED_BIT                          0x200
        /* toolMode codes
         */
 #define AIPTEK_TOOL_BUTTON_PEN_MODE                    BTN_TOOL_PEN
 
        /* Mouse button programming
         */
-#define AIPTEK_MOUSE_LEFT_BUTTON               0x01
-#define AIPTEK_MOUSE_RIGHT_BUTTON              0x02
-#define AIPTEK_MOUSE_MIDDLE_BUTTON             0x04
+#define AIPTEK_MOUSE_LEFT_BUTTON               0x04
+#define AIPTEK_MOUSE_RIGHT_BUTTON              0x08
+#define AIPTEK_MOUSE_MIDDLE_BUTTON             0x10
 
        /* Stylus button programming
         */
@@ -294,7 +288,6 @@ struct aiptek_features {
        int modelCode;          /* Tablet model code (not unique) */
        int firmwareCode;       /* prom/eeprom version            */
        char usbPath[64 + 1];   /* device's physical usb path     */
-       char inputPath[64 + 1]; /* input device path              */
 };
 
 struct aiptek_settings {
@@ -327,9 +320,32 @@ struct aiptek {
        int inDelay;                            /* jitter: in jitter delay?      */
        unsigned long endDelay;                 /* jitter: time when delay ends  */
        int previousJitterable;                 /* jitterable prev value     */
+
+       int lastMacro;                          /* macro key to reset            */
+       int previousToolMode;                   /* pen, pencil, brush, etc. tool */
        unsigned char *data;                    /* incoming packet data          */
 };
 
+static const int eventTypes[] = {
+        EV_KEY, EV_ABS, EV_REL, EV_MSC,
+};
+
+static const int absEvents[] = {
+        ABS_X, ABS_Y, ABS_PRESSURE, ABS_TILT_X, ABS_TILT_Y,
+        ABS_WHEEL, ABS_MISC,
+};
+
+static const int relEvents[] = {
+        REL_X, REL_Y, REL_WHEEL,
+};
+
+static const int buttonEvents[] = {
+       BTN_LEFT, BTN_RIGHT, BTN_MIDDLE,
+       BTN_TOOL_PEN, BTN_TOOL_RUBBER, BTN_TOOL_PENCIL, BTN_TOOL_AIRBRUSH,
+       BTN_TOOL_BRUSH, BTN_TOOL_MOUSE, BTN_TOOL_LENS, BTN_TOUCH,
+       BTN_STYLUS, BTN_STYLUS2,
+};
+
 /*
  * Permit easy lookup of keyboard events to send, versus
  * the bitmap which comes from the tablet. This hides the
@@ -345,23 +361,39 @@ static const int macroKeyEvents[] = {
 };
 
 /***********************************************************************
- * Relative reports deliver values in 2's complement format to
- * deal with negative offsets.
+ * Map values to strings and back. Every map shoudl have the following
+ * as its last element: { NULL, AIPTEK_INVALID_VALUE }.
  */
-static int aiptek_convert_from_2s_complement(unsigned char c)
+#define AIPTEK_INVALID_VALUE   -1
+
+struct aiptek_map {
+       const char *string;
+       int value;
+};
+
+static int map_str_to_val(const struct aiptek_map *map, const char *str, size_t count)
 {
-       int ret;
-       unsigned char b = c;
-       int negate = 0;
+       const struct aiptek_map *p;
 
-       if ((b & 0x80) != 0) {
-               b = ~b;
-               b--;
-               negate = 1;
-       }
-       ret = b;
-       ret = (negate == 1) ? -ret : ret;
-       return ret;
+       if (str[count - 1] == '\n')
+               count--;
+
+       for (p = map; p->string; p++)
+               if (!strncmp(str, p->string, count))
+                       return p->value;
+
+       return AIPTEK_INVALID_VALUE;
+}
+
+static const char *map_val_to_str(const struct aiptek_map *map, int val)
+{
+       const struct aiptek_map *p;
+
+       for (p = map; p->value != AIPTEK_INVALID_VALUE; p++)
+               if (val == p->value)
+                       return p->string;
+
+       return "unknown";
 }
 
 /***********************************************************************
@@ -385,6 +417,9 @@ static int aiptek_convert_from_2s_complement(unsigned char c)
  * Proximity. Why two events? I thought it interesting to know if the
  * Proximity event occurred while the tablet was in absolute or relative
  * mode.
+ * Update: REL_MISC proved not to be such a good idea. With REL_MISC you
+ * get an event transmitted each time. ABS_MISC works better, since it
+ * can be set and re-set. Thus, only using ABS_MISC from now on.
  *
  * Other tablets use the notion of a certain minimum stylus pressure
  * to infer proximity. While that could have been done, that is yet
@@ -441,8 +476,8 @@ static void aiptek_irq(struct urb *urb)
                        aiptek->diagnostic =
                            AIPTEK_DIAGNOSTIC_SENDING_RELATIVE_IN_ABSOLUTE;
                } else {
-                       x = aiptek_convert_from_2s_complement(data[2]);
-                       y = aiptek_convert_from_2s_complement(data[3]);
+                       x = (signed char) data[2];
+                       y = (signed char) data[3];
 
                        /* jitterable keeps track of whether any button has been pressed.
                         * We're also using it to remap the physical mouse button mask
@@ -451,18 +486,20 @@ static void aiptek_irq(struct urb *urb)
                         * that a non-zero value indicates that one or more
                         * mouse button was pressed.)
                         */
-                       jitterable = data[5] & 0x07;
+                       jitterable = data[1] & 0x07;
 
-                       left = (data[5] & aiptek->curSetting.mouseButtonLeft) != 0 ? 1 : 0;
-                       right = (data[5] & aiptek->curSetting.mouseButtonRight) != 0 ? 1 : 0;
-                       middle = (data[5] & aiptek->curSetting.mouseButtonMiddle) != 0 ? 1 : 0;
+                       left = (data[1] & aiptek->curSetting.mouseButtonLeft >> 2) != 0 ? 1 : 0;
+                       right = (data[1] & aiptek->curSetting.mouseButtonRight >> 2) != 0 ? 1 : 0;
+                       middle = (data[1] & aiptek->curSetting.mouseButtonMiddle >> 2) != 0 ? 1 : 0;
 
                        input_report_key(inputdev, BTN_LEFT, left);
                        input_report_key(inputdev, BTN_MIDDLE, middle);
                        input_report_key(inputdev, BTN_RIGHT, right);
+
+                       input_report_abs(inputdev, ABS_MISC,
+                                        1 | AIPTEK_REPORT_TOOL_UNKNOWN);
                        input_report_rel(inputdev, REL_X, x);
                        input_report_rel(inputdev, REL_Y, y);
-                       input_report_rel(inputdev, REL_MISC, 1 | AIPTEK_REPORT_TOOL_UNKNOWN);
 
                        /* Wheel support is in the form of a single-event
                         * firing.
@@ -472,6 +509,11 @@ static void aiptek_irq(struct urb *urb)
                                                 aiptek->curSetting.wheel);
                                aiptek->curSetting.wheel = AIPTEK_WHEEL_DISABLE;
                        }
+                       if (aiptek->lastMacro != -1) {
+                               input_report_key(inputdev,
+                                                macroKeyEvents[aiptek->lastMacro], 0);
+                               aiptek->lastMacro = -1;
+                       }
                        input_sync(inputdev);
                }
        }
@@ -489,8 +531,8 @@ static void aiptek_irq(struct urb *urb)
                        y = le16_to_cpu(get_unaligned((__le16 *) (data + 3)));
                        z = le16_to_cpu(get_unaligned((__le16 *) (data + 6)));
 
-                       p = (data[5] & 0x01) != 0 ? 1 : 0;
-                       dv = (data[5] & 0x02) != 0 ? 1 : 0;
+                       dv = (data[5] & 0x01) != 0 ? 1 : 0;
+                       p = (data[5] & 0x02) != 0 ? 1 : 0;
                        tip = (data[5] & 0x04) != 0 ? 1 : 0;
 
                        /* Use jitterable to re-arrange button masks
@@ -505,16 +547,18 @@ static void aiptek_irq(struct urb *urb)
                         * all 'bad' reports...
                         */
                        if (dv != 0) {
-                               /* If we've not already sent a tool_button_?? code, do
-                                * so now. Then set FIRED_BIT so it won't be resent unless
-                                * the user forces FIRED_BIT off.
+                               /* If the selected tool changed, reset the old
+                                * tool key, and set the new one.
                                 */
-                               if (TOOL_BUTTON_FIRED
-                                   (aiptek->curSetting.toolMode) == 0) {
+                               if (aiptek->previousToolMode !=
+                                   aiptek->curSetting.toolMode) {
+                                       input_report_key(inputdev,
+                                                        aiptek->previousToolMode, 0);
                                        input_report_key(inputdev,
-                                                        TOOL_BUTTON(aiptek->curSetting.toolMode),
+                                                        aiptek->curSetting.toolMode,
                                                         1);
-                                       aiptek->curSetting.toolMode |= TOOL_BUTTON_FIRED_BIT;
+                                       aiptek->previousToolMode =
+                                                 aiptek->curSetting.toolMode;
                                }
 
                                if (p != 0) {
@@ -550,6 +594,11 @@ static void aiptek_irq(struct urb *urb)
                                        }
                                }
                                input_report_abs(inputdev, ABS_MISC, p | AIPTEK_REPORT_TOOL_STYLUS);
+                               if (aiptek->lastMacro != -1) {
+                                       input_report_key(inputdev,
+                                                        macroKeyEvents[aiptek->lastMacro], 0);
+                                       aiptek->lastMacro = -1;
+                               }
                                input_sync(inputdev);
                        }
                }
@@ -568,23 +617,25 @@ static void aiptek_irq(struct urb *urb)
 
                        jitterable = data[5] & 0x1c;
 
-                       p = (data[5] & 0x01) != 0 ? 1 : 0;
-                       dv = (data[5] & 0x02) != 0 ? 1 : 0;
+                       dv = (data[5] & 0x01) != 0 ? 1 : 0;
+                       p = (data[5] & 0x02) != 0 ? 1 : 0;
                        left = (data[5] & aiptek->curSetting.mouseButtonLeft) != 0 ? 1 : 0;
                        right = (data[5] & aiptek->curSetting.mouseButtonRight) != 0 ? 1 : 0;
                        middle = (data[5] & aiptek->curSetting.mouseButtonMiddle) != 0 ? 1 : 0;
 
                        if (dv != 0) {
-                               /* If we've not already sent a tool_button_?? code, do
-                                * so now. Then set FIRED_BIT so it won't be resent unless
-                                * the user forces FIRED_BIT off.
+                               /* If the selected tool changed, reset the old
+                                * tool key, and set the new one.
                                 */
-                               if (TOOL_BUTTON_FIRED
-                                   (aiptek->curSetting.toolMode) == 0) {
+                               if (aiptek->previousToolMode !=
+                                   aiptek->curSetting.toolMode) {
+                                       input_report_key(inputdev,
+                                                        aiptek->previousToolMode, 0);
                                        input_report_key(inputdev,
-                                                        TOOL_BUTTON(aiptek->curSetting.toolMode),
+                                                        aiptek->curSetting.toolMode,
                                                         1);
-                                       aiptek->curSetting.toolMode |= TOOL_BUTTON_FIRED_BIT;
+                                       aiptek->previousToolMode =
+                                                 aiptek->curSetting.toolMode;
                                }
 
                                if (p != 0) {
@@ -605,7 +656,12 @@ static void aiptek_irq(struct urb *urb)
                                                aiptek->curSetting.wheel = AIPTEK_WHEEL_DISABLE;
                                        }
                                }
-                               input_report_rel(inputdev, REL_MISC, p | AIPTEK_REPORT_TOOL_MOUSE);
+                               input_report_abs(inputdev, ABS_MISC, p | AIPTEK_REPORT_TOOL_MOUSE);
+                               if (aiptek->lastMacro != -1) {
+                                       input_report_key(inputdev,
+                                                        macroKeyEvents[aiptek->lastMacro], 0);
+                                       aiptek->lastMacro = -1;
+                               }
                                input_sync(inputdev);
                        }
                }
@@ -615,98 +671,83 @@ static void aiptek_irq(struct urb *urb)
        else if (data[0] == 4) {
                jitterable = data[1] & 0x18;
 
-               p = (data[1] & 0x01) != 0 ? 1 : 0;
-               dv = (data[1] & 0x02) != 0 ? 1 : 0;
+               dv = (data[1] & 0x01) != 0 ? 1 : 0;
+               p = (data[1] & 0x02) != 0 ? 1 : 0;
                tip = (data[1] & 0x04) != 0 ? 1 : 0;
                bs = (data[1] & aiptek->curSetting.stylusButtonLower) != 0 ? 1 : 0;
                pck = (data[1] & aiptek->curSetting.stylusButtonUpper) != 0 ? 1 : 0;
 
-               macro = data[3];
+               macro = dv && p && tip && !(data[3] & 1) ? (data[3] >> 1) : -1;
                z = le16_to_cpu(get_unaligned((__le16 *) (data + 4)));
 
-               if (dv != 0) {
-                       /* If we've not already sent a tool_button_?? code, do
-                        * so now. Then set FIRED_BIT so it won't be resent unless
-                        * the user forces FIRED_BIT off.
+               if (dv) {
+                       /* If the selected tool changed, reset the old
+                        * tool key, and set the new one.
                         */
-                       if (TOOL_BUTTON_FIRED(aiptek->curSetting.toolMode) == 0) {
+                       if (aiptek->previousToolMode !=
+                           aiptek->curSetting.toolMode) {
+                               input_report_key(inputdev,
+                                                aiptek->previousToolMode, 0);
                                input_report_key(inputdev,
-                                                TOOL_BUTTON(aiptek->curSetting.toolMode),
+                                                aiptek->curSetting.toolMode,
                                                 1);
-                               aiptek->curSetting.toolMode |= TOOL_BUTTON_FIRED_BIT;
+                               aiptek->previousToolMode =
+                                       aiptek->curSetting.toolMode;
                        }
+               }
 
-                       if (p != 0) {
-                               input_report_key(inputdev, BTN_TOUCH, tip);
-                               input_report_key(inputdev, BTN_STYLUS, bs);
-                               input_report_key(inputdev, BTN_STYLUS2, pck);
-                               input_report_abs(inputdev, ABS_PRESSURE, z);
-                       }
+               if (aiptek->lastMacro != -1 && aiptek->lastMacro != macro) {
+                       input_report_key(inputdev, macroKeyEvents[aiptek->lastMacro], 0);
+                       aiptek->lastMacro = -1;
+               }
 
-                       /* For safety, we're sending key 'break' codes for the
-                        * neighboring macro keys.
-                        */
-                       if (macro > 0) {
-                               input_report_key(inputdev,
-                                                macroKeyEvents[macro - 1], 0);
-                       }
-                       if (macro < 25) {
-                               input_report_key(inputdev,
-                                                macroKeyEvents[macro + 1], 0);
-                       }
-                       input_report_key(inputdev, macroKeyEvents[macro], p);
-                       input_report_abs(inputdev, ABS_MISC,
-                                        p | AIPTEK_REPORT_TOOL_STYLUS);
-                       input_sync(inputdev);
+               if (macro != -1 && macro != aiptek->lastMacro) {
+                       input_report_key(inputdev, macroKeyEvents[macro], 1);
+                       aiptek->lastMacro = macro;
                }
+               input_report_abs(inputdev, ABS_MISC,
+                                p | AIPTEK_REPORT_TOOL_STYLUS);
+               input_sync(inputdev);
        }
        /* Report 5s come from the macro keys when pressed by mouse
         */
        else if (data[0] == 5) {
                jitterable = data[1] & 0x1c;
 
-               p = (data[1] & 0x01) != 0 ? 1 : 0;
-               dv = (data[1] & 0x02) != 0 ? 1 : 0;
+               dv = (data[1] & 0x01) != 0 ? 1 : 0;
+               p = (data[1] & 0x02) != 0 ? 1 : 0;
                left = (data[1]& aiptek->curSetting.mouseButtonLeft) != 0 ? 1 : 0;
                right = (data[1] & aiptek->curSetting.mouseButtonRight) != 0 ? 1 : 0;
                middle = (data[1] & aiptek->curSetting.mouseButtonMiddle) != 0 ? 1 : 0;
-               macro = data[3];
+               macro = dv && p && left && !(data[3] & 1) ? (data[3] >> 1) : 0;
 
-               if (dv != 0) {
-                       /* If we've not already sent a tool_button_?? code, do
-                        * so now. Then set FIRED_BIT so it won't be resent unless
-                        * the user forces FIRED_BIT off.
+               if (dv) {
+                       /* If the selected tool changed, reset the old
+                        * tool key, and set the new one.
                         */
-                       if (TOOL_BUTTON_FIRED(aiptek->curSetting.toolMode) == 0) {
-                               input_report_key(inputdev,
-                                                TOOL_BUTTON(aiptek->curSetting.toolMode),
-                                                1);
-                               aiptek->curSetting.toolMode |= TOOL_BUTTON_FIRED_BIT;
-                       }
-
-                       if (p != 0) {
-                               input_report_key(inputdev, BTN_LEFT, left);
-                               input_report_key(inputdev, BTN_MIDDLE, middle);
-                               input_report_key(inputdev, BTN_RIGHT, right);
+                       if (aiptek->previousToolMode !=
+                           aiptek->curSetting.toolMode) {
+                               input_report_key(inputdev,
+                                                aiptek->previousToolMode, 0);
+                               input_report_key(inputdev,
+                                                aiptek->curSetting.toolMode, 1);
+                               aiptek->previousToolMode = aiptek->curSetting.toolMode;
                        }
+               }
 
-                       /* For safety, we're sending key 'break' codes for the
-                        * neighboring macro keys.
-                        */
-                       if (macro > 0) {
-                               input_report_key(inputdev,
-                                                macroKeyEvents[macro - 1], 0);
-                       }
-                       if (macro < 25) {
-                               input_report_key(inputdev,
-                                                macroKeyEvents[macro + 1], 0);
-                       }
+               if (aiptek->lastMacro != -1 && aiptek->lastMacro != macro) {
+                       input_report_key(inputdev, macroKeyEvents[aiptek->lastMacro], 0);
+                       aiptek->lastMacro = -1;
+               }
 
+               if (macro != -1 && macro != aiptek->lastMacro) {
                        input_report_key(inputdev, macroKeyEvents[macro], 1);
-                       input_report_rel(inputdev, ABS_MISC,
-                                        p | AIPTEK_REPORT_TOOL_MOUSE);
-                       input_sync(inputdev);
+                       aiptek->lastMacro = macro;
                }
+
+               input_report_abs(inputdev, ABS_MISC,
+                                p | AIPTEK_REPORT_TOOL_MOUSE);
+               input_sync(inputdev);
        }
        /* We have no idea which tool can generate a report 6. Theoretically,
         * neither need to, having been given reports 4 & 5 for such use.
@@ -725,15 +766,18 @@ static void aiptek_irq(struct urb *urb)
                                         0);
                }
 
-               /* If we've not already sent a tool_button_?? code, do
-                * so now. Then set FIRED_BIT so it won't be resent unless
-                * the user forces FIRED_BIT off.
-                */
-               if (TOOL_BUTTON_FIRED(aiptek->curSetting.toolMode) == 0) {
+               /* If the selected tool changed, reset the old
+                  tool key, and set the new one.
+               */
+               if (aiptek->previousToolMode !=
+                   aiptek->curSetting.toolMode) {
+                       input_report_key(inputdev,
+                                        aiptek->previousToolMode, 0);
                        input_report_key(inputdev,
-                                        TOOL_BUTTON(aiptek->curSetting.
-                                                    toolMode), 1);
-                       aiptek->curSetting.toolMode |= TOOL_BUTTON_FIRED_BIT;
+                                        aiptek->curSetting.toolMode,
+                                        1);
+                       aiptek->previousToolMode =
+                               aiptek->curSetting.toolMode;
                }
 
                input_report_key(inputdev, macroKeyEvents[macro], 1);
@@ -1007,9 +1051,6 @@ static ssize_t show_tabletSize(struct device *dev, struct device_attribute *attr
 {
        struct aiptek *aiptek = dev_get_drvdata(dev);
 
-       if (aiptek == NULL)
-               return 0;
-
        return snprintf(buf, PAGE_SIZE, "%dx%d\n",
                        aiptek->inputdev->absmax[ABS_X] + 1,
                        aiptek->inputdev->absmax[ABS_Y] + 1);
@@ -1023,118 +1064,36 @@ static ssize_t show_tabletSize(struct device *dev, struct device_attribute *attr
  */
 static DEVICE_ATTR(size, S_IRUGO, show_tabletSize, NULL);
 
-/***********************************************************************
- * support routines for the 'product_id' file
- */
-static ssize_t show_tabletProductId(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       struct aiptek *aiptek = dev_get_drvdata(dev);
-
-       if (aiptek == NULL)
-               return 0;
-
-       return snprintf(buf, PAGE_SIZE, "0x%04x\n",
-                       aiptek->inputdev->id.product);
-}
-
-static DEVICE_ATTR(product_id, S_IRUGO, show_tabletProductId, NULL);
-
-/***********************************************************************
- * support routines for the 'vendor_id' file
- */
-static ssize_t show_tabletVendorId(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       struct aiptek *aiptek = dev_get_drvdata(dev);
-
-       if (aiptek == NULL)
-               return 0;
-
-       return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->inputdev->id.vendor);
-}
-
-static DEVICE_ATTR(vendor_id, S_IRUGO, show_tabletVendorId, NULL);
-
-/***********************************************************************
- * support routines for the 'vendor' file
- */
-static ssize_t show_tabletManufacturer(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       struct aiptek *aiptek = dev_get_drvdata(dev);
-       int retval;
-
-       if (aiptek == NULL)
-               return 0;
-
-       retval = snprintf(buf, PAGE_SIZE, "%s\n", aiptek->usbdev->manufacturer);
-       return retval;
-}
-
-static DEVICE_ATTR(vendor, S_IRUGO, show_tabletManufacturer, NULL);
-
-/***********************************************************************
- * support routines for the 'product' file
- */
-static ssize_t show_tabletProduct(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       struct aiptek *aiptek = dev_get_drvdata(dev);
-       int retval;
-
-       if (aiptek == NULL)
-               return 0;
-
-       retval = snprintf(buf, PAGE_SIZE, "%s\n", aiptek->usbdev->product);
-       return retval;
-}
-
-static DEVICE_ATTR(product, S_IRUGO, show_tabletProduct, NULL);
-
 /***********************************************************************
  * support routines for the 'pointer_mode' file. Note that this file
  * both displays current setting and allows reprogramming.
  */
+static struct aiptek_map pointer_mode_map[] = {
+       { "stylus",     AIPTEK_POINTER_ONLY_STYLUS_MODE },
+       { "mouse",      AIPTEK_POINTER_ONLY_MOUSE_MODE },
+       { "either",     AIPTEK_POINTER_EITHER_MODE },
+       { NULL,         AIPTEK_INVALID_VALUE }
+};
+
 static ssize_t show_tabletPointerMode(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct aiptek *aiptek = dev_get_drvdata(dev);
-       char *s;
-
-       if (aiptek == NULL)
-               return 0;
-
-       switch (aiptek->curSetting.pointerMode) {
-       case AIPTEK_POINTER_ONLY_STYLUS_MODE:
-               s = "stylus";
-               break;
-
-       case AIPTEK_POINTER_ONLY_MOUSE_MODE:
-               s = "mouse";
-               break;
-
-       case AIPTEK_POINTER_EITHER_MODE:
-               s = "either";
-               break;
 
-       default:
-               s = "unknown";
-               break;
-       }
-       return snprintf(buf, PAGE_SIZE, "%s\n", s);
+       return snprintf(buf, PAGE_SIZE, "%s\n",
+                       map_val_to_str(pointer_mode_map,
+                                       aiptek->curSetting.pointerMode));
 }
 
 static ssize_t
 store_tabletPointerMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
        struct aiptek *aiptek = dev_get_drvdata(dev);
-       if (aiptek == NULL)
-               return 0;
+       int new_mode = map_str_to_val(pointer_mode_map, buf, count);
 
-       if (strcmp(buf, "stylus") == 0) {
-               aiptek->newSetting.pointerMode =
-                   AIPTEK_POINTER_ONLY_STYLUS_MODE;
-       } else if (strcmp(buf, "mouse") == 0) {
-               aiptek->newSetting.pointerMode = AIPTEK_POINTER_ONLY_MOUSE_MODE;
-       } else if (strcmp(buf, "either") == 0) {
-               aiptek->newSetting.pointerMode = AIPTEK_POINTER_EITHER_MODE;
-       }
+       if (new_mode == AIPTEK_INVALID_VALUE)
+               return -EINVAL;
+
+       aiptek->newSetting.pointerMode = new_mode;
        return count;
 }
 
@@ -1146,44 +1105,32 @@ static DEVICE_ATTR(pointer_mode,
  * support routines for the 'coordinate_mode' file. Note that this file
  * both displays current setting and allows reprogramming.
  */
+
+static struct aiptek_map coordinate_mode_map[] = {
+       { "absolute",   AIPTEK_COORDINATE_ABSOLUTE_MODE },
+       { "relative",   AIPTEK_COORDINATE_RELATIVE_MODE },
+       { NULL,         AIPTEK_INVALID_VALUE }
+};
+
 static ssize_t show_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct aiptek *aiptek = dev_get_drvdata(dev);
-       char *s;
 
-       if (aiptek == NULL)
-               return 0;
-
-       switch (aiptek->curSetting.coordinateMode) {
-       case AIPTEK_COORDINATE_ABSOLUTE_MODE:
-               s = "absolute";
-               break;
-
-       case AIPTEK_COORDINATE_RELATIVE_MODE:
-               s = "relative";
-               break;
-
-       default:
-               s = "unknown";
-               break;
-       }
-       return snprintf(buf, PAGE_SIZE, "%s\n", s);
+       return snprintf(buf, PAGE_SIZE, "%s\n",
+                       map_val_to_str(coordinate_mode_map,
+                                       aiptek->curSetting.coordinateMode));
 }
 
 static ssize_t
 store_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
        struct aiptek *aiptek = dev_get_drvdata(dev);
-       if (aiptek == NULL)
-               return 0;
+       int new_mode = map_str_to_val(coordinate_mode_map, buf, count);
 
-       if (strcmp(buf, "absolute") == 0) {
-               aiptek->newSetting.pointerMode =
-                   AIPTEK_COORDINATE_ABSOLUTE_MODE;
-       } else if (strcmp(buf, "relative") == 0) {
-               aiptek->newSetting.pointerMode =
-                   AIPTEK_COORDINATE_RELATIVE_MODE;
-       }
+       if (new_mode == AIPTEK_INVALID_VALUE)
+               return -EINVAL;
+
+       aiptek->newSetting.coordinateMode = new_mode;
        return count;
 }
 
@@ -1195,73 +1142,37 @@ static DEVICE_ATTR(coordinate_mode,
  * support routines for the 'tool_mode' file. Note that this file
  * both displays current setting and allows reprogramming.
  */
+
+static struct aiptek_map tool_mode_map[] = {
+       { "mouse",      AIPTEK_TOOL_BUTTON_MOUSE_MODE },
+       { "eraser",     AIPTEK_TOOL_BUTTON_ERASER_MODE },
+       { "pencil",     AIPTEK_TOOL_BUTTON_PENCIL_MODE },
+       { "pen",        AIPTEK_TOOL_BUTTON_PEN_MODE },
+       { "brush",      AIPTEK_TOOL_BUTTON_BRUSH_MODE },
+       { "airbrush",   AIPTEK_TOOL_BUTTON_AIRBRUSH_MODE },
+       { "lens",       AIPTEK_TOOL_BUTTON_LENS_MODE },
+       { NULL,         AIPTEK_INVALID_VALUE }
+};
+
 static ssize_t show_tabletToolMode(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct aiptek *aiptek = dev_get_drvdata(dev);
-       char *s;
-
-       if (aiptek == NULL)
-               return 0;
-
-       switch (TOOL_BUTTON(aiptek->curSetting.toolMode)) {
-       case AIPTEK_TOOL_BUTTON_MOUSE_MODE:
-               s = "mouse";
-               break;
-
-       case AIPTEK_TOOL_BUTTON_ERASER_MODE:
-               s = "eraser";
-               break;
-
-       case AIPTEK_TOOL_BUTTON_PENCIL_MODE:
-               s = "pencil";
-               break;
-
-       case AIPTEK_TOOL_BUTTON_PEN_MODE:
-               s = "pen";
-               break;
-
-       case AIPTEK_TOOL_BUTTON_BRUSH_MODE:
-               s = "brush";
-               break;
-
-       case AIPTEK_TOOL_BUTTON_AIRBRUSH_MODE:
-               s = "airbrush";
-               break;
-
-       case AIPTEK_TOOL_BUTTON_LENS_MODE:
-               s = "lens";
-               break;
 
-       default:
-               s = "unknown";
-               break;
-       }
-       return snprintf(buf, PAGE_SIZE, "%s\n", s);
+       return snprintf(buf, PAGE_SIZE, "%s\n",
+                       map_val_to_str(tool_mode_map,
+                                       aiptek->curSetting.toolMode));
 }
 
 static ssize_t
 store_tabletToolMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
        struct aiptek *aiptek = dev_get_drvdata(dev);
-       if (aiptek == NULL)
-               return 0;
+       int new_mode = map_str_to_val(tool_mode_map, buf, count);
 
-       if (strcmp(buf, "mouse") == 0) {
-               aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_MOUSE_MODE;
-       } else if (strcmp(buf, "eraser") == 0) {
-               aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_ERASER_MODE;
-       } else if (strcmp(buf, "pencil") == 0) {
-               aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_PENCIL_MODE;
-       } else if (strcmp(buf, "pen") == 0) {
-               aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_PEN_MODE;
-       } else if (strcmp(buf, "brush") == 0) {
-               aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_BRUSH_MODE;
-       } else if (strcmp(buf, "airbrush") == 0) {
-               aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_AIRBRUSH_MODE;
-       } else if (strcmp(buf, "lens") == 0) {
-               aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_LENS_MODE;
-       }
+       if (new_mode == AIPTEK_INVALID_VALUE)
+               return -EINVAL;
 
+       aiptek->newSetting.toolMode = new_mode;
        return count;
 }
 
@@ -1277,9 +1188,6 @@ static ssize_t show_tabletXtilt(struct device *dev, struct device_attribute *att
 {
        struct aiptek *aiptek = dev_get_drvdata(dev);
 
-       if (aiptek == NULL)
-               return 0;
-
        if (aiptek->curSetting.xTilt == AIPTEK_TILT_DISABLE) {
                return snprintf(buf, PAGE_SIZE, "disable\n");
        } else {
@@ -1294,9 +1202,6 @@ store_tabletXtilt(struct device *dev, struct device_attribute *attr, const char
        struct aiptek *aiptek = dev_get_drvdata(dev);
        int x;
 
-       if (aiptek == NULL)
-               return 0;
-
        if (strcmp(buf, "disable") == 0) {
                aiptek->newSetting.xTilt = AIPTEK_TILT_DISABLE;
        } else {
@@ -1319,9 +1224,6 @@ static ssize_t show_tabletYtilt(struct device *dev, struct device_attribute *att
 {
        struct aiptek *aiptek = dev_get_drvdata(dev);
 
-       if (aiptek == NULL)
-               return 0;
-
        if (aiptek->curSetting.yTilt == AIPTEK_TILT_DISABLE) {
                return snprintf(buf, PAGE_SIZE, "disable\n");
        } else {
@@ -1336,9 +1238,6 @@ store_tabletYtilt(struct device *dev, struct device_attribute *attr, const char
        struct aiptek *aiptek = dev_get_drvdata(dev);
        int y;
 
-       if (aiptek == NULL)
-               return 0;
-
        if (strcmp(buf, "disable") == 0) {
                aiptek->newSetting.yTilt = AIPTEK_TILT_DISABLE;
        } else {
@@ -1361,9 +1260,6 @@ static ssize_t show_tabletJitterDelay(struct device *dev, struct device_attribut
 {
        struct aiptek *aiptek = dev_get_drvdata(dev);
 
-       if (aiptek == NULL)
-               return 0;
-
        return snprintf(buf, PAGE_SIZE, "%d\n", aiptek->curSetting.jitterDelay);
 }
 
@@ -1372,9 +1268,6 @@ store_tabletJitterDelay(struct device *dev, struct device_attribute *attr, const
 {
        struct aiptek *aiptek = dev_get_drvdata(dev);
 
-       if (aiptek == NULL)
-               return 0;
-
        aiptek->newSetting.jitterDelay = (int)simple_strtol(buf, NULL, 10);
        return count;
 }
@@ -1391,9 +1284,6 @@ static ssize_t show_tabletProgrammableDelay(struct device *dev, struct device_at
 {
        struct aiptek *aiptek = dev_get_drvdata(dev);
 
-       if (aiptek == NULL)
-               return 0;
-
        return snprintf(buf, PAGE_SIZE, "%d\n",
                        aiptek->curSetting.programmableDelay);
 }
@@ -1403,9 +1293,6 @@ store_tabletProgrammableDelay(struct device *dev, struct device_attribute *attr,
 {
        struct aiptek *aiptek = dev_get_drvdata(dev);
 
-       if (aiptek == NULL)
-               return 0;
-
        aiptek->newSetting.programmableDelay = (int)simple_strtol(buf, NULL, 10);
        return count;
 }
@@ -1414,23 +1301,6 @@ static DEVICE_ATTR(delay,
                   S_IRUGO | S_IWUGO,
                   show_tabletProgrammableDelay, store_tabletProgrammableDelay);
 
-/***********************************************************************
- * support routines for the 'input_path' file. Note that this file
- * only displays current setting.
- */
-static ssize_t show_tabletInputDevice(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       struct aiptek *aiptek = dev_get_drvdata(dev);
-
-       if (aiptek == NULL)
-               return 0;
-
-       return snprintf(buf, PAGE_SIZE, "/dev/input/%s\n",
-                       aiptek->features.inputPath);
-}
-
-static DEVICE_ATTR(input_path, S_IRUGO, show_tabletInputDevice, NULL);
-
 /***********************************************************************
  * support routines for the 'event_count' file. Note that this file
  * only displays current setting.
@@ -1439,9 +1309,6 @@ static ssize_t show_tabletEventsReceived(struct device *dev, struct device_attri
 {
        struct aiptek *aiptek = dev_get_drvdata(dev);
 
-       if (aiptek == NULL)
-               return 0;
-
        return snprintf(buf, PAGE_SIZE, "%ld\n", aiptek->eventCount);
 }
 
@@ -1456,9 +1323,6 @@ static ssize_t show_tabletDiagnosticMessage(struct device *dev, struct device_at
        struct aiptek *aiptek = dev_get_drvdata(dev);
        char *retMsg;
 
-       if (aiptek == NULL)
-               return 0;
-
        switch (aiptek->diagnostic) {
        case AIPTEK_DIAGNOSTIC_NA:
                retMsg = "no errors\n";
@@ -1493,45 +1357,32 @@ static DEVICE_ATTR(diagnostic, S_IRUGO, show_tabletDiagnosticMessage, NULL);
  * support routines for the 'stylus_upper' file. Note that this file
  * both displays current setting and allows for setting changing.
  */
+
+static struct aiptek_map stylus_button_map[] = {
+       { "upper",      AIPTEK_STYLUS_UPPER_BUTTON },
+       { "lower",      AIPTEK_STYLUS_LOWER_BUTTON },
+       { NULL,         AIPTEK_INVALID_VALUE }
+};
+
 static ssize_t show_tabletStylusUpper(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct aiptek *aiptek = dev_get_drvdata(dev);
-       char *s;
-
-       if (aiptek == NULL)
-               return 0;
-
-       switch (aiptek->curSetting.stylusButtonUpper) {
-       case AIPTEK_STYLUS_UPPER_BUTTON:
-               s = "upper";
-               break;
-
-       case AIPTEK_STYLUS_LOWER_BUTTON:
-               s = "lower";
-               break;
 
-       default:
-               s = "unknown";
-               break;
-       }
-       return snprintf(buf, PAGE_SIZE, "%s\n", s);
+       return snprintf(buf, PAGE_SIZE, "%s\n",
+                       map_val_to_str(stylus_button_map,
+                                       aiptek->curSetting.stylusButtonUpper));
 }
 
 static ssize_t
 store_tabletStylusUpper(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
        struct aiptek *aiptek = dev_get_drvdata(dev);
+       int new_button = map_str_to_val(stylus_button_map, buf, count);
 
-       if (aiptek == NULL)
-               return 0;
+       if (new_button == AIPTEK_INVALID_VALUE)
+               return -EINVAL;
 
-       if (strcmp(buf, "upper") == 0) {
-               aiptek->newSetting.stylusButtonUpper =
-                   AIPTEK_STYLUS_UPPER_BUTTON;
-       } else if (strcmp(buf, "lower") == 0) {
-               aiptek->newSetting.stylusButtonUpper =
-                   AIPTEK_STYLUS_LOWER_BUTTON;
-       }
+       aiptek->newSetting.stylusButtonUpper = new_button;
        return count;
 }
 
@@ -1543,45 +1394,26 @@ static DEVICE_ATTR(stylus_upper,
  * support routines for the 'stylus_lower' file. Note that this file
  * both displays current setting and allows for setting changing.
  */
+
 static ssize_t show_tabletStylusLower(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct aiptek *aiptek = dev_get_drvdata(dev);
-       char *s;
-
-       if (aiptek == NULL)
-               return 0;
-
-       switch (aiptek->curSetting.stylusButtonLower) {
-       case AIPTEK_STYLUS_UPPER_BUTTON:
-               s = "upper";
-               break;
-
-       case AIPTEK_STYLUS_LOWER_BUTTON:
-               s = "lower";
-               break;
 
-       default:
-               s = "unknown";
-               break;
-       }
-       return snprintf(buf, PAGE_SIZE, "%s\n", s);
+       return snprintf(buf, PAGE_SIZE, "%s\n",
+                       map_val_to_str(stylus_button_map,
+                                       aiptek->curSetting.stylusButtonLower));
 }
 
 static ssize_t
 store_tabletStylusLower(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
        struct aiptek *aiptek = dev_get_drvdata(dev);
+       int new_button = map_str_to_val(stylus_button_map, buf, count);
 
-       if (aiptek == NULL)
-               return 0;
+       if (new_button == AIPTEK_INVALID_VALUE)
+               return -EINVAL;
 
-       if (strcmp(buf, "upper") == 0) {
-               aiptek->newSetting.stylusButtonLower =
-                   AIPTEK_STYLUS_UPPER_BUTTON;
-       } else if (strcmp(buf, "lower") == 0) {
-               aiptek->newSetting.stylusButtonLower =
-                   AIPTEK_STYLUS_LOWER_BUTTON;
-       }
+       aiptek->newSetting.stylusButtonLower = new_button;
        return count;
 }
 
@@ -1593,49 +1425,33 @@ static DEVICE_ATTR(stylus_lower,
  * support routines for the 'mouse_left' file. Note that this file
  * both displays current setting and allows for setting changing.
  */
+
+static struct aiptek_map mouse_button_map[] = {
+       { "left",       AIPTEK_MOUSE_LEFT_BUTTON },
+       { "middle",     AIPTEK_MOUSE_MIDDLE_BUTTON },
+       { "right",      AIPTEK_MOUSE_RIGHT_BUTTON },
+       { NULL,         AIPTEK_INVALID_VALUE }
+};
+
 static ssize_t show_tabletMouseLeft(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct aiptek *aiptek = dev_get_drvdata(dev);
-       char *s;
-
-       if (aiptek == NULL)
-               return 0;
-
-       switch (aiptek->curSetting.mouseButtonLeft) {
-       case AIPTEK_MOUSE_LEFT_BUTTON:
-               s = "left";
-               break;
-
-       case AIPTEK_MOUSE_MIDDLE_BUTTON:
-               s = "middle";
-               break;
-
-       case AIPTEK_MOUSE_RIGHT_BUTTON:
-               s = "right";
-               break;
 
-       default:
-               s = "unknown";
-               break;
-       }
-       return snprintf(buf, PAGE_SIZE, "%s\n", s);
+       return snprintf(buf, PAGE_SIZE, "%s\n",
+                       map_val_to_str(mouse_button_map,
+                                       aiptek->curSetting.mouseButtonLeft));
 }
 
 static ssize_t
 store_tabletMouseLeft(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
        struct aiptek *aiptek = dev_get_drvdata(dev);
+       int new_button = map_str_to_val(mouse_button_map, buf, count);
 
-       if (aiptek == NULL)
-               return 0;
+       if (new_button == AIPTEK_INVALID_VALUE)
+               return -EINVAL;
 
-       if (strcmp(buf, "left") == 0) {
-               aiptek->newSetting.mouseButtonLeft = AIPTEK_MOUSE_LEFT_BUTTON;
-       } else if (strcmp(buf, "middle") == 0) {
-               aiptek->newSetting.mouseButtonLeft = AIPTEK_MOUSE_MIDDLE_BUTTON;
-       } else if (strcmp(buf, "right") == 0) {
-               aiptek->newSetting.mouseButtonLeft = AIPTEK_MOUSE_RIGHT_BUTTON;
-       }
+       aiptek->newSetting.mouseButtonLeft = new_button;
        return count;
 }
 
@@ -1650,48 +1466,22 @@ static DEVICE_ATTR(mouse_left,
 static ssize_t show_tabletMouseMiddle(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct aiptek *aiptek = dev_get_drvdata(dev);
-       char *s;
 
-       if (aiptek == NULL)
-               return 0;
-
-       switch (aiptek->curSetting.mouseButtonMiddle) {
-       case AIPTEK_MOUSE_LEFT_BUTTON:
-               s = "left";
-               break;
-
-       case AIPTEK_MOUSE_MIDDLE_BUTTON:
-               s = "middle";
-               break;
-
-       case AIPTEK_MOUSE_RIGHT_BUTTON:
-               s = "right";
-               break;
-
-       default:
-               s = "unknown";
-               break;
-       }
-       return snprintf(buf, PAGE_SIZE, "%s\n", s);
+       return snprintf(buf, PAGE_SIZE, "%s\n",
+                       map_val_to_str(mouse_button_map,
+                                       aiptek->curSetting.mouseButtonMiddle));
 }
 
 static ssize_t
 store_tabletMouseMiddle(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
        struct aiptek *aiptek = dev_get_drvdata(dev);
+       int new_button = map_str_to_val(mouse_button_map, buf, count);
 
-       if (aiptek == NULL)
-               return 0;
+       if (new_button == AIPTEK_INVALID_VALUE)
+               return -EINVAL;
 
-       if (strcmp(buf, "left") == 0) {
-               aiptek->newSetting.mouseButtonMiddle = AIPTEK_MOUSE_LEFT_BUTTON;
-       } else if (strcmp(buf, "middle") == 0) {
-               aiptek->newSetting.mouseButtonMiddle =
-                   AIPTEK_MOUSE_MIDDLE_BUTTON;
-       } else if (strcmp(buf, "right") == 0) {
-               aiptek->newSetting.mouseButtonMiddle =
-                   AIPTEK_MOUSE_RIGHT_BUTTON;
-       }
+       aiptek->newSetting.mouseButtonMiddle = new_button;
        return count;
 }
 
@@ -1706,47 +1496,22 @@ static DEVICE_ATTR(mouse_middle,
 static ssize_t show_tabletMouseRight(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct aiptek *aiptek = dev_get_drvdata(dev);
-       char *s;
-
-       if (aiptek == NULL)
-               return 0;
-
-       switch (aiptek->curSetting.mouseButtonRight) {
-       case AIPTEK_MOUSE_LEFT_BUTTON:
-               s = "left";
-               break;
-
-       case AIPTEK_MOUSE_MIDDLE_BUTTON:
-               s = "middle";
-               break;
 
-       case AIPTEK_MOUSE_RIGHT_BUTTON:
-               s = "right";
-               break;
-
-       default:
-               s = "unknown";
-               break;
-       }
-       return snprintf(buf, PAGE_SIZE, "%s\n", s);
+       return snprintf(buf, PAGE_SIZE, "%s\n",
+                       map_val_to_str(mouse_button_map,
+                                       aiptek->curSetting.mouseButtonRight));
 }
 
 static ssize_t
 store_tabletMouseRight(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
        struct aiptek *aiptek = dev_get_drvdata(dev);
+       int new_button = map_str_to_val(mouse_button_map, buf, count);
 
-       if (aiptek == NULL)
-               return 0;
+       if (new_button == AIPTEK_INVALID_VALUE)
+               return -EINVAL;
 
-       if (strcmp(buf, "left") == 0) {
-               aiptek->newSetting.mouseButtonRight = AIPTEK_MOUSE_LEFT_BUTTON;
-       } else if (strcmp(buf, "middle") == 0) {
-               aiptek->newSetting.mouseButtonRight =
-                   AIPTEK_MOUSE_MIDDLE_BUTTON;
-       } else if (strcmp(buf, "right") == 0) {
-               aiptek->newSetting.mouseButtonRight = AIPTEK_MOUSE_RIGHT_BUTTON;
-       }
+       aiptek->newSetting.mouseButtonRight = new_button;
        return count;
 }
 
@@ -1762,9 +1527,6 @@ static ssize_t show_tabletWheel(struct device *dev, struct device_attribute *att
 {
        struct aiptek *aiptek = dev_get_drvdata(dev);
 
-       if (aiptek == NULL)
-               return 0;
-
        if (aiptek->curSetting.wheel == AIPTEK_WHEEL_DISABLE) {
                return snprintf(buf, PAGE_SIZE, "disable\n");
        } else {
@@ -1778,9 +1540,6 @@ store_tabletWheel(struct device *dev, struct device_attribute *attr, const char
 {
        struct aiptek *aiptek = dev_get_drvdata(dev);
 
-       if (aiptek == NULL)
-               return 0;
-
        aiptek->newSetting.wheel = (int)simple_strtol(buf, NULL, 10);
        return count;
 }
@@ -1794,11 +1553,6 @@ static DEVICE_ATTR(wheel,
  */
 static ssize_t show_tabletExecute(struct device *dev, struct device_attribute *attr, char *buf)
 {
-       struct aiptek *aiptek = dev_get_drvdata(dev);
-
-       if (aiptek == NULL)
-               return 0;
-
        /* There is nothing useful to display, so a one-line manual
         * is in order...
         */
@@ -1811,9 +1565,6 @@ store_tabletExecute(struct device *dev, struct device_attribute *attr, const cha
 {
        struct aiptek *aiptek = dev_get_drvdata(dev);
 
-       if (aiptek == NULL)
-               return 0;
-
        /* We do not care what you write to this file. Merely the action
         * of writing to this file triggers a tablet reprogramming.
         */
@@ -1837,9 +1588,6 @@ static ssize_t show_tabletODMCode(struct device *dev, struct device_attribute *a
 {
        struct aiptek *aiptek = dev_get_drvdata(dev);
 
-       if (aiptek == NULL)
-               return 0;
-
        return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->features.odmCode);
 }
 
@@ -1853,9 +1601,6 @@ static ssize_t show_tabletModelCode(struct device *dev, struct device_attribute
 {
        struct aiptek *aiptek = dev_get_drvdata(dev);
 
-       if (aiptek == NULL)
-               return 0;
-
        return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->features.modelCode);
 }
 
@@ -1869,86 +1614,39 @@ static ssize_t show_firmwareCode(struct device *dev, struct device_attribute *at
 {
        struct aiptek *aiptek = dev_get_drvdata(dev);
 
-       if (aiptek == NULL)
-               return 0;
-
        return snprintf(buf, PAGE_SIZE, "%04x\n",
                        aiptek->features.firmwareCode);
 }
 
 static DEVICE_ATTR(firmware_code, S_IRUGO, show_firmwareCode, NULL);
 
-/***********************************************************************
- * This routine removes all existing sysfs files managed by this device
- * driver.
- */
-static void aiptek_delete_files(struct device *dev)
-{
-       device_remove_file(dev, &dev_attr_size);
-       device_remove_file(dev, &dev_attr_product_id);
-       device_remove_file(dev, &dev_attr_vendor_id);
-       device_remove_file(dev, &dev_attr_vendor);
-       device_remove_file(dev, &dev_attr_product);
-       device_remove_file(dev, &dev_attr_pointer_mode);
-       device_remove_file(dev, &dev_attr_coordinate_mode);
-       device_remove_file(dev, &dev_attr_tool_mode);
-       device_remove_file(dev, &dev_attr_xtilt);
-       device_remove_file(dev, &dev_attr_ytilt);
-       device_remove_file(dev, &dev_attr_jitter);
-       device_remove_file(dev, &dev_attr_delay);
-       device_remove_file(dev, &dev_attr_input_path);
-       device_remove_file(dev, &dev_attr_event_count);
-       device_remove_file(dev, &dev_attr_diagnostic);
-       device_remove_file(dev, &dev_attr_odm_code);
-       device_remove_file(dev, &dev_attr_model_code);
-       device_remove_file(dev, &dev_attr_firmware_code);
-       device_remove_file(dev, &dev_attr_stylus_lower);
-       device_remove_file(dev, &dev_attr_stylus_upper);
-       device_remove_file(dev, &dev_attr_mouse_left);
-       device_remove_file(dev, &dev_attr_mouse_middle);
-       device_remove_file(dev, &dev_attr_mouse_right);
-       device_remove_file(dev, &dev_attr_wheel);
-       device_remove_file(dev, &dev_attr_execute);
-}
-
-/***********************************************************************
- * This routine creates the sysfs files managed by this device
- * driver.
- */
-static int aiptek_add_files(struct device *dev)
-{
-       int ret;
+static struct attribute *aiptek_attributes[] = {
+       &dev_attr_size.attr,
+       &dev_attr_pointer_mode.attr,
+       &dev_attr_coordinate_mode.attr,
+       &dev_attr_tool_mode.attr,
+       &dev_attr_xtilt.attr,
+       &dev_attr_ytilt.attr,
+       &dev_attr_jitter.attr,
+       &dev_attr_delay.attr,
+       &dev_attr_event_count.attr,
+       &dev_attr_diagnostic.attr,
+       &dev_attr_odm_code.attr,
+       &dev_attr_model_code.attr,
+       &dev_attr_firmware_code.attr,
+       &dev_attr_stylus_lower.attr,
+       &dev_attr_stylus_upper.attr,
+       &dev_attr_mouse_left.attr,
+       &dev_attr_mouse_middle.attr,
+       &dev_attr_mouse_right.attr,
+       &dev_attr_wheel.attr,
+       &dev_attr_execute.attr,
+       NULL
+};
 
-       if ((ret = device_create_file(dev, &dev_attr_size)) ||
-           (ret = device_create_file(dev, &dev_attr_product_id)) ||
-           (ret = device_create_file(dev, &dev_attr_vendor_id)) ||
-           (ret = device_create_file(dev, &dev_attr_vendor)) ||
-           (ret = device_create_file(dev, &dev_attr_product)) ||
-           (ret = device_create_file(dev, &dev_attr_pointer_mode)) ||
-           (ret = device_create_file(dev, &dev_attr_coordinate_mode)) ||
-           (ret = device_create_file(dev, &dev_attr_tool_mode)) ||
-           (ret = device_create_file(dev, &dev_attr_xtilt)) ||
-           (ret = device_create_file(dev, &dev_attr_ytilt)) ||
-           (ret = device_create_file(dev, &dev_attr_jitter)) ||
-           (ret = device_create_file(dev, &dev_attr_delay)) ||
-           (ret = device_create_file(dev, &dev_attr_input_path)) ||
-           (ret = device_create_file(dev, &dev_attr_event_count)) ||
-           (ret = device_create_file(dev, &dev_attr_diagnostic)) ||
-           (ret = device_create_file(dev, &dev_attr_odm_code)) ||
-           (ret = device_create_file(dev, &dev_attr_model_code)) ||
-           (ret = device_create_file(dev, &dev_attr_firmware_code)) ||
-           (ret = device_create_file(dev, &dev_attr_stylus_lower)) ||
-           (ret = device_create_file(dev, &dev_attr_stylus_upper)) ||
-           (ret = device_create_file(dev, &dev_attr_mouse_left)) ||
-           (ret = device_create_file(dev, &dev_attr_mouse_middle)) ||
-           (ret = device_create_file(dev, &dev_attr_mouse_right)) ||
-           (ret = device_create_file(dev, &dev_attr_wheel)) ||
-           (ret = device_create_file(dev, &dev_attr_execute))) {
-               err("aiptek: killing own sysfs device files\n");
-               aiptek_delete_files(dev);
-       }
-       return ret;
-}
+static struct attribute_group aiptek_attribute_group = {
+       .attrs  = aiptek_attributes,
+};
 
 /***********************************************************************
  * This routine is called when a tablet has been identified. It basically
@@ -1961,8 +1659,6 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
        struct usb_endpoint_descriptor *endpoint;
        struct aiptek *aiptek;
        struct input_dev *inputdev;
-       struct input_handle *inputhandle;
-       struct list_head *node, *next;
        int i;
        int speeds[] = { 0,
                AIPTEK_PROGRAMMABLE_DELAY_50,
@@ -1984,17 +1680,23 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
 
        aiptek = kzalloc(sizeof(struct aiptek), GFP_KERNEL);
        inputdev = input_allocate_device();
-       if (!aiptek || !inputdev)
+       if (!aiptek || !inputdev) {
+               warn("aiptek: cannot allocate memory or input device");
                goto fail1;
+        }
 
        aiptek->data = usb_buffer_alloc(usbdev, AIPTEK_PACKET_LENGTH,
                                        GFP_ATOMIC, &aiptek->data_dma);
-       if (!aiptek->data)
+        if (!aiptek->data) {
+               warn("aiptek: cannot allocate usb buffer");
                goto fail1;
+       }
 
        aiptek->urb = usb_alloc_urb(0, GFP_KERNEL);
-       if (!aiptek->urb)
+       if (!aiptek->urb) {
+               warn("aiptek: cannot allocate urb");
                goto fail2;
+       }
 
        aiptek->inputdev = inputdev;
        aiptek->usbdev = usbdev;
@@ -2002,6 +1704,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
        aiptek->inDelay = 0;
        aiptek->endDelay = 0;
        aiptek->previousJitterable = 0;
+       aiptek->lastMacro = -1;
 
        /* Set up the curSettings struct. Said struct contains the current
         * programmable parameters. The newSetting struct contains changes
@@ -2054,36 +1757,23 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
        /* Now program the capacities of the tablet, in terms of being
         * an input device.
         */
-       inputdev->evbit[0] |= BIT(EV_KEY)
-           | BIT(EV_ABS)
-           | BIT(EV_REL)
-           | BIT(EV_MSC);
-
-       inputdev->absbit[0] |= BIT(ABS_MISC);
+       for (i = 0; i < ARRAY_SIZE(eventTypes); ++i)
+               __set_bit(eventTypes[i], inputdev->evbit);
 
-       inputdev->relbit[0] |=
-           (BIT(REL_X) | BIT(REL_Y) | BIT(REL_WHEEL) | BIT(REL_MISC));
+       for (i = 0; i < ARRAY_SIZE(absEvents); ++i)
+               __set_bit(absEvents[i], inputdev->absbit);
 
-       inputdev->keybit[LONG(BTN_LEFT)] |=
-           (BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE));
+       for (i = 0; i < ARRAY_SIZE(relEvents); ++i)
+               __set_bit(relEvents[i], inputdev->relbit);
 
-       inputdev->keybit[LONG(BTN_DIGI)] |=
-           (BIT(BTN_TOOL_PEN) |
-            BIT(BTN_TOOL_RUBBER) |
-            BIT(BTN_TOOL_PENCIL) |
-            BIT(BTN_TOOL_AIRBRUSH) |
-            BIT(BTN_TOOL_BRUSH) |
-            BIT(BTN_TOOL_MOUSE) |
-            BIT(BTN_TOOL_LENS) |
-            BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2));
+       __set_bit(MSC_SERIAL, inputdev->mscbit);
 
-       inputdev->mscbit[0] = BIT(MSC_SERIAL);
+       /* Set up key and button codes */
+       for (i = 0; i < ARRAY_SIZE(buttonEvents); ++i)
+               __set_bit(buttonEvents[i], inputdev->keybit);
 
-       /* Programming the tablet macro keys needs to be done with a for loop
-        * as the keycodes are discontiguous.
-        */
        for (i = 0; i < ARRAY_SIZE(macroKeyEvents); ++i)
-               set_bit(macroKeyEvents[i], inputdev->keybit);
+               __set_bit(macroKeyEvents[i], inputdev->keybit);
 
        /*
         * Program the input device coordinate capacities. We do not yet
@@ -2134,25 +1824,11 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
                }
        }
 
-       /* Register the tablet as an Input Device
-        */
-       err = input_register_device(aiptek->inputdev);
-       if (err)
+       /* Murphy says that some day someone will have a tablet that fails the
+          above test. That's you, Frederic Rodrigo */
+       if (i == ARRAY_SIZE(speeds)) {
+               info("input: Aiptek tried all speeds, no sane response");
                goto fail2;
-
-       /* We now will look for the evdev device which is mapped to
-        * the tablet. The partial name is kept in the link list of
-        * input_handles associated with this input device.
-        * What identifies an evdev input_handler is that it begins
-        * with 'event', continues with a digit, and that in turn
-        * is mapped to input/eventN.
-        */
-       list_for_each_safe(node, next, &inputdev->h_list) {
-               inputhandle = to_handle(node);
-               if (strncmp(inputhandle->name, "event", 5) == 0) {
-                       strcpy(aiptek->features.inputPath, inputhandle->name);
-                       break;
-               }
        }
 
        /* Associate this driver's struct with the usb interface.
@@ -2161,18 +1837,27 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
 
        /* Set up the sysfs files
         */
-       aiptek_add_files(&intf->dev);
+       err = sysfs_create_group(&intf->dev.kobj, &aiptek_attribute_group);
+       if (err) {
+               warn("aiptek: cannot create sysfs group err: %d", err);
+               goto fail3;
+        }
 
-       /* Make sure the evdev module is loaded. Assuming evdev IS a module :-)
+       /* Register the tablet as an Input Device
         */
-       if (request_module("evdev") != 0)
-               info("aiptek: error loading 'evdev' module");
-
+       err = input_register_device(aiptek->inputdev);
+       if (err) {
+               warn("aiptek: input_register_device returned err: %d", err);
+               goto fail4;
+        }
        return 0;
 
+ fail4:        sysfs_remove_group(&intf->dev.kobj, &aiptek_attribute_group);
+ fail3: usb_free_urb(aiptek->urb);
  fail2:        usb_buffer_free(usbdev, AIPTEK_PACKET_LENGTH, aiptek->data,
                        aiptek->data_dma);
- fail1:        input_free_device(inputdev);
+ fail1: usb_set_intfdata(intf, NULL);
+       input_free_device(inputdev);
        kfree(aiptek);
        return err;
 }
@@ -2192,7 +1877,7 @@ static void aiptek_disconnect(struct usb_interface *intf)
                 */
                usb_kill_urb(aiptek->urb);
                input_unregister_device(aiptek->inputdev);
-               aiptek_delete_files(&intf->dev);
+               sysfs_remove_group(&intf->dev.kobj, &aiptek_attribute_group);
                usb_free_urb(aiptek->urb);
                usb_buffer_free(interface_to_usbdev(intf),
                                AIPTEK_PACKET_LENGTH,
index ef01a807ec0f9b6e0cd95eaafacc5030e0f2a308..6542edb6f76efe505629b8690dfa4e50b8267329 100644 (file)
@@ -11,7 +11,7 @@
  *  Copyright (c) 2000 Daniel Egger            <egger@suse.de>
  *  Copyright (c) 2001 Frederic Lepied         <flepied@mandrakesoft.com>
  *  Copyright (c) 2004 Panagiotis Issaris      <panagiotis.issaris@mech.kuleuven.ac.be>
- *  Copyright (c) 2002-2006 Ping Cheng         <pingc@wacom.com>
+ *  Copyright (c) 2002-2007 Ping Cheng         <pingc@wacom.com>
  *
  *  ChangeLog:
  *      v0.1 (vp)  - Initial release
@@ -62,8 +62,9 @@
  *                 - Minor data report fix
  *      v1.46 (pc) - Split wacom.c into wacom_sys.c and wacom_wac.c,
  *                - where wacom_sys.c deals with system specific code,
- *                - and wacom_wac.c deals with Wacom specific code
+ *                - and wacom_wac.c deals with Wacom specific code
  *                - Support Intuos3 4x6
+ *      v1.47 (pc) - Added support for Bamboo
  */
 
 /*
@@ -84,7 +85,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.46"
+#define DRIVER_VERSION "v1.47"
 #define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
 #define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver"
 #define DRIVER_LICENSE "GPL"
@@ -123,6 +124,7 @@ extern void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wa
 extern void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
 extern void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
 extern void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
+extern void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
 extern __u16 wacom_le16_to_cpu(unsigned char *data);
 extern __u16 wacom_be16_to_cpu(unsigned char *data);
 extern struct wacom_features * get_wacom_feature(const struct usb_device_id *id);
index 83bddef6606770a536048c6a9250dbd084627c88..064e123c9b766170be132d2bb894b535d168b961 100644 (file)
@@ -138,6 +138,12 @@ static void wacom_close(struct input_dev *dev)
        usb_kill_urb(wacom->irq);
 }
 
+void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
+{
+       input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_1) | BIT(BTN_5);
+       input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0);
+}
+
 void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
 {
        input_dev->evbit[0] |= BIT(EV_MSC);
index 7661f03a2db2ab3cbb51e6d40e28db54db9ac32b..fc03ba256f4c54c540e200c23e7d0b25bccda9fb 100644 (file)
@@ -178,7 +178,8 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
 
                        case 2: /* Mouse with wheel */
                                wacom_report_key(wcombo, BTN_MIDDLE, data[1] & 0x04);
-                               if (wacom->features->type == WACOM_G4) {
+                               if (wacom->features->type == WACOM_G4 ||
+                                               wacom->features->type == WACOM_MO) {
                                        rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : (data[7] & 0x03);
                                        wacom_report_rel(wcombo, REL_WHEEL, -rw);
                                } else
@@ -190,7 +191,8 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
                                id = 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)
+                               if (wacom->features->type == WACOM_G4 ||
+                                               wacom->features->type == WACOM_MO)
                                        wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f);
                                else
                                        wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f);
@@ -226,7 +228,8 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
        }
 
        /* send pad data */
-       if (wacom->features->type == WACOM_G4) {
+       switch (wacom->features->type) {
+           case WACOM_G4:
                if (data[7] & 0xf8) {
                        wacom_input_sync(wcombo); /* sync last event */
                        wacom->id[1] = 1;
@@ -247,6 +250,33 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
                        wacom_report_abs(wcombo, ABS_MISC, 0);
                        wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
                }
+               break;
+           case WACOM_MO:
+               if ((data[7] & 0xf8) || (data[8] & 0x80)) {
+                       wacom_input_sync(wcombo); /* sync last event */
+                       wacom->id[1] = 1;
+                       wacom->serial[1] = (data[7] & 0xf8);
+                       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_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
+               } else if (wacom->id[1]) {
+                       wacom_input_sync(wcombo); /* sync last event */
+                       wacom->id[1] = 0;
+                       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, 0);
+                       wacom_report_abs(wcombo, ABS_MISC, 0);
+                       wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
+               }
+               break;
        }
        return 1;
 }
@@ -331,7 +361,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo)
                        wacom_report_key(wcombo, BTN_EXTRA, 0);
                        wacom_report_abs(wcombo, ABS_THROTTLE, 0);
                        wacom_report_abs(wcombo, ABS_RZ, 0);
-               } else {
+               } else {
                        wacom_report_abs(wcombo, ABS_PRESSURE, 0);
                        wacom_report_abs(wcombo, ABS_TILT_X, 0);
                        wacom_report_abs(wcombo, ABS_TILT_Y, 0);
@@ -423,9 +453,9 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo)
                 return result-1;
 
        /* Only large I3 and I1 & I2 support Lense Cursor */
-       if((wacom->tool[idx] == BTN_TOOL_LENS)
+       if ((wacom->tool[idx] == BTN_TOOL_LENS)
                        && ((wacom->features->type == INTUOS3)
-                       || (wacom->features->type == INTUOS3S)))
+                       || (wacom->features->type == INTUOS3S)))
                return 0;
 
        /* Cintiq doesn't send data when RDY bit isn't set */
@@ -517,6 +547,7 @@ int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo)
                        break;
                case WACOM_G4:
                case GRAPHIRE:
+               case WACOM_MO:
                        return (wacom_graphire_irq(wacom_wac, wcombo));
                        break;
                case PTU:
@@ -538,6 +569,8 @@ int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo)
 void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
 {
        switch (wacom_wac->features->type) {
+               case WACOM_MO:
+                       input_dev_mo(input_dev, wacom_wac);
                case WACOM_G4:
                        input_dev_g4(input_dev, wacom_wac);
                        /* fall through */
@@ -579,6 +612,7 @@ static struct wacom_features wacom_features[] = {
        { "Wacom Volito2 4x5",   8,   5104,  3712,  511, 63, GRAPHIRE },
        { "Wacom Volito2 2x3",   8,   3248,  2320,  511, 63, GRAPHIRE },
        { "Wacom PenPartner2",   8,   3250,  2320,  255, 63, GRAPHIRE },
+       { "Wacom Bamboo",        9,  14760,  9225,  511, 63, WACOM_MO },
        { "Wacom Intuos 4x5",   10,  12700, 10600, 1023, 31, INTUOS },
        { "Wacom Intuos 6x8",   10,  20320, 16240, 1023, 31, INTUOS },
        { "Wacom Intuos 9x12",  10,  30480, 24060, 1023, 31, INTUOS },
@@ -627,6 +661,7 @@ static struct usb_device_id wacom_ids[] = {
        { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x62) },
        { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x63) },
        { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x64) },
+       { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x65) },
        { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x20) },
        { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x21) },
        { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x22) },
index a5e12e8756de046e9bcf62ddeaaba165183246ad..a302e229bb8a7d005d65f62f6831245b2bbcd96a 100644 (file)
@@ -25,6 +25,7 @@ enum {
        INTUOS3,
        INTUOS3L,
        CINTIQ,
+       WACOM_MO,
        MAX_TYPE
 };
 
index e5cca9bd040632bcbe7d7064a63ca4394c077e3d..69371779806ac57182548230a9513e2754efd064 100644 (file)
@@ -177,6 +177,7 @@ config TOUCHSCREEN_USB_COMPOSITE
          - some other eTurboTouch
          - Gunze AHL61
          - DMC TSC-10/25
+         - IRTOUCHSYSTEMS/UNITOP
 
          Have a look at <http://linux.chapter7.ch/touchkit/> for
          a usage description and the required user-space stuff.
@@ -219,4 +220,9 @@ config TOUCHSCREEN_USB_DMC_TSC10
        bool "DMC TSC-10/25 device support" if EMBEDDED
        depends on TOUCHSCREEN_USB_COMPOSITE
 
+config TOUCHSCREEN_USB_IRTOUCH
+       default y
+       bool "IRTOUCHSYSTEMS/UNITOP device support" if EMBEDDED
+       depends on TOUCHSCREEN_USB_COMPOSITE
+
 endif
index e3f22852bd0978c422db77d050a9072a013a9549..b407028ffc59dcc514fa02d8c66f2aab9065a046 100644 (file)
@@ -9,6 +9,7 @@
  *  - eTurboTouch
  *  - Gunze AHL61
  *  - DMC TSC-10/25
+ *  - IRTOUCHSYSTEMS/UNITOP
  *
  * Copyright (C) 2004-2006 by Daniel Ritz <daniel.ritz@gmx.ch>
  * Copyright (C) by Todd E. Johnson (mtouchusb.c)
@@ -110,6 +111,7 @@ enum {
        DEVTYPE_ETURBO,
        DEVTYPE_GUNZE,
        DEVTYPE_DMC_TSC10,
+       DEVTYPE_IRTOUCH,
 };
 
 static struct usb_device_id usbtouch_devices[] = {
@@ -150,6 +152,11 @@ static struct usb_device_id usbtouch_devices[] = {
        {USB_DEVICE(0x0afa, 0x03e8), .driver_info = DEVTYPE_DMC_TSC10},
 #endif
 
+#ifdef CONFIG_TOUCHSCREEN_USB_IRTOUCH
+       {USB_DEVICE(0x595a, 0x0001), .driver_info = DEVTYPE_IRTOUCH},
+       {USB_DEVICE(0x6615, 0x0001), .driver_info = DEVTYPE_IRTOUCH},
+#endif
+
        {}
 };
 
@@ -415,6 +422,21 @@ static int dmc_tsc10_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
 #endif
 
 
+/*****************************************************************************
+ * IRTOUCH Part
+ */
+#ifdef CONFIG_TOUCHSCREEN_USB_IRTOUCH
+static int irtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
+{
+       dev->x = (pkt[3] << 8) | pkt[2];
+       dev->y = (pkt[5] << 8) | pkt[4];
+       dev->touch = (pkt[1] & 0x03) ? 1 : 0;
+
+       return 1;
+}
+#endif
+
+
 /*****************************************************************************
  * the different device descriptors
  */
@@ -504,6 +526,17 @@ static struct usbtouch_device_info usbtouch_dev_info[] = {
                .read_data      = dmc_tsc10_read_data,
        },
 #endif
+
+#ifdef CONFIG_TOUCHSCREEN_USB_IRTOUCH
+       [DEVTYPE_IRTOUCH] = {
+               .min_xc         = 0x0,
+               .max_xc         = 0x0fff,
+               .min_yc         = 0x0,
+               .max_yc         = 0x0fff,
+               .rept_size      = 8,
+               .read_data      = irtouch_read_data,
+       },
+#endif
 };
 
 
index 2db364898e15f434e852c304bbcb855e271de00b..d2f882e98e5e21c0c9c23b5d8c3e072883de052a 100644 (file)
@@ -109,9 +109,11 @@ struct tsdev {
        int open;
        int minor;
        char name[8];
+       struct input_handle handle;
        wait_queue_head_t wait;
        struct list_head client_list;
-       struct input_handle handle;
+       struct device dev;
+
        int x, y, pressure;
        struct ts_calibration cal;
 };
@@ -163,9 +165,13 @@ static int tsdev_open(struct inode *inode, struct file *file)
        if (!tsdev || !tsdev->exist)
                return -ENODEV;
 
+       get_device(&tsdev->dev);
+
        client = kzalloc(sizeof(struct tsdev_client), GFP_KERNEL);
-       if (!client)
-               return -ENOMEM;
+       if (!client) {
+               error = -ENOMEM;
+               goto err_put_tsdev;
+       }
 
        client->tsdev = tsdev;
        client->raw = (i >= TSDEV_MINORS / 2) ? 1 : 0;
@@ -173,19 +179,25 @@ static int tsdev_open(struct inode *inode, struct file *file)
 
        if (!tsdev->open++ && tsdev->exist) {
                error = input_open_device(&tsdev->handle);
-               if (error) {
-                       list_del(&client->node);
-                       kfree(client);
-                       return error;
-               }
+               if (error)
+                       goto err_free_client;
        }
 
        file->private_data = client;
        return 0;
+
+ err_free_client:
+       list_del(&client->node);
+       kfree(client);
+ err_put_tsdev:
+       put_device(&tsdev->dev);
+       return error;
 }
 
-static void tsdev_free(struct tsdev *tsdev)
+static void tsdev_free(struct device *dev)
 {
+       struct tsdev *tsdev = container_of(dev, struct tsdev, dev);
+
        tsdev_table[tsdev->minor] = NULL;
        kfree(tsdev);
 }
@@ -200,12 +212,10 @@ static int tsdev_release(struct inode *inode, struct file *file)
        list_del(&client->node);
        kfree(client);
 
-       if (!--tsdev->open) {
-               if (tsdev->exist)
-                       input_close_device(&tsdev->handle);
-               else
-                       tsdev_free(tsdev);
-       }
+       if (!--tsdev->open && tsdev->exist)
+               input_close_device(&tsdev->handle);
+
+       put_device(&tsdev->dev);
 
        return 0;
 }
@@ -361,7 +371,7 @@ static void tsdev_event(struct input_handle *handle, unsigned int type,
                int x, y, tmp;
 
                do_gettimeofday(&time);
-               client->event[client->head].millisecs = time.tv_usec / 100;
+               client->event[client->head].millisecs = time.tv_usec / 1000;
                client->event[client->head].pressure = tsdev->pressure;
 
                x = tsdev->x;
@@ -388,8 +398,6 @@ static int tsdev_connect(struct input_handler *handler, struct input_dev *dev,
                         const struct input_device_id *id)
 {
        struct tsdev *tsdev;
-       struct class_device *cdev;
-       dev_t devt;
        int minor, delta;
        int error;
 
@@ -407,14 +415,13 @@ static int tsdev_connect(struct input_handler *handler, struct input_dev *dev,
        INIT_LIST_HEAD(&tsdev->client_list);
        init_waitqueue_head(&tsdev->wait);
 
-       sprintf(tsdev->name, "ts%d", minor);
-
        tsdev->exist = 1;
        tsdev->minor = minor;
        tsdev->handle.dev = dev;
        tsdev->handle.name = tsdev->name;
        tsdev->handle.handler = handler;
        tsdev->handle.private = tsdev;
+       snprintf(tsdev->name, sizeof(tsdev->name), "ts%d", minor);
 
        /* Precompute the rough calibration matrix */
        delta = dev->absmax [ABS_X] - dev->absmin [ABS_X] + 1;
@@ -429,36 +436,30 @@ static int tsdev_connect(struct input_handler *handler, struct input_dev *dev,
        tsdev->cal.yscale = (yres << 8) / delta;
        tsdev->cal.ytrans = - ((dev->absmin [ABS_Y] * tsdev->cal.yscale) >> 8);
 
-       tsdev_table[minor] = tsdev;
-
-       devt = MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor),
+       snprintf(tsdev->dev.bus_id, sizeof(tsdev->dev.bus_id),
+                "ts%d", minor);
+       tsdev->dev.class = &input_class;
+       tsdev->dev.parent = &dev->dev;
+       tsdev->dev.devt = MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor);
+       tsdev->dev.release = tsdev_free;
+       device_initialize(&tsdev->dev);
 
-       cdev = class_device_create(&input_class, &dev->cdev, devt,
-                                  dev->cdev.dev, tsdev->name);
-       if (IS_ERR(cdev)) {
-               error = PTR_ERR(cdev);
-               goto err_free_tsdev;
-       }
+       tsdev_table[minor] = tsdev;
 
-       /* temporary symlink to keep userspace happy */
-       error = sysfs_create_link(&input_class.subsys.kobj,
-                                 &cdev->kobj, tsdev->name);
+       error = device_add(&tsdev->dev);
        if (error)
-               goto err_cdev_destroy;
+               goto err_free_tsdev;
 
        error = input_register_handle(&tsdev->handle);
        if (error)
-               goto err_remove_link;
+               goto err_delete_tsdev;
 
        return 0;
 
- err_remove_link:
-       sysfs_remove_link(&input_class.subsys.kobj, tsdev->name);
- err_cdev_destroy:
-       class_device_destroy(&input_class, devt);
+ err_delete_tsdev:
+       device_del(&tsdev->dev);
  err_free_tsdev:
-       tsdev_table[minor] = NULL;
-       kfree(tsdev);
+       put_device(&tsdev->dev);
        return error;
 }
 
@@ -468,10 +469,8 @@ static void tsdev_disconnect(struct input_handle *handle)
        struct tsdev_client *client;
 
        input_unregister_handle(handle);
+       device_del(&tsdev->dev);
 
-       sysfs_remove_link(&input_class.subsys.kobj, tsdev->name);
-       class_device_destroy(&input_class,
-                       MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + tsdev->minor));
        tsdev->exist = 0;
 
        if (tsdev->open) {
@@ -479,8 +478,9 @@ static void tsdev_disconnect(struct input_handle *handle)
                list_for_each_entry(client, &tsdev->client_list, node)
                        kill_fasync(&client->fasync, SIGIO, POLL_HUP);
                wake_up_interruptible(&tsdev->wait);
-       } else
-               tsdev_free(tsdev);
+       }
+
+       put_device(&tsdev->dev);
 }
 
 static const struct input_device_id tsdev_ids[] = {
index 34031064534612018d85f19e1e914b4e9949ec41..6339bb443f624e56f4fbfe97b3f400d968e5d8ac 100644 (file)
@@ -287,7 +287,6 @@ setup_sct_quadro(struct IsdnCard *card)
 #ifdef CONFIG_PCI
        struct IsdnCardState *cs = card->cs;
        char tmp[64];
-       u_char pci_rev_id;
        u_int found = 0;
        u_int pci_ioaddr1, pci_ioaddr2, pci_ioaddr3, pci_ioaddr4, pci_ioaddr5;
 
@@ -335,8 +334,7 @@ setup_sct_quadro(struct IsdnCard *card)
                }
 #ifdef ATTEMPT_PCI_REMAPPING
 /* HACK: PLX revision 1 bug: PLX address bit 7 must not be set */
-               pci_read_config_byte(dev_a8, PCI_REVISION_ID, &pci_rev_id);
-               if ((pci_ioaddr1 & 0x80) && (pci_rev_id == 1)) {
+               if ((pci_ioaddr1 & 0x80) && (dev_a8->revision == 1)) {
                        printk(KERN_WARNING "HiSax: %s (%s): PLX rev 1, remapping required!\n",
                                CardType[card->typ],
                                sct_quadro_subtypes[cs->subtyp]);
index 11ced17f438a8469a39cf303eda067ff9b21193b..4fcb245ba184edd3d06684f4e2572b5571918212 100644 (file)
@@ -212,7 +212,6 @@ int wf_register_control(struct wf_control *new_ct)
        list_add(&new_ct->link, &wf_controls);
 
        new_ct->attr.attr.name = new_ct->name;
-       new_ct->attr.attr.owner = THIS_MODULE;
        new_ct->attr.attr.mode = 0644;
        new_ct->attr.show = wf_show_control;
        new_ct->attr.store = wf_store_control;
@@ -325,7 +324,6 @@ int wf_register_sensor(struct wf_sensor *new_sr)
        list_add(&new_sr->link, &wf_sensors);
 
        new_sr->attr.attr.name = new_sr->name;
-       new_sr->attr.attr.owner = THIS_MODULE;
        new_sr->attr.attr.mode = 0444;
        new_sr->attr.show = wf_show_sensor;
        new_sr->attr.store = NULL;
index 1043b39aa123e716b67613229e2c34229d1c4274..351982bcec1b21d3a46c767f2879202c73e1419b 100644 (file)
@@ -67,26 +67,6 @@ static struct i2c_driver wf_sat_driver = {
        .detach_client  = wf_sat_detach,
 };
 
-/*
- * XXX i2c_smbus_read_i2c_block_data doesn't pass the requested
- * length down to the low-level driver, so we use this, which
- * works well enough with the SMU i2c driver code...
- */
-static int sat_read_block(struct i2c_client *client, u8 command,
-                         u8 *values, int len)
-{
-       union i2c_smbus_data data;
-       int err;
-
-       data.block[0] = len;
-       err = i2c_smbus_xfer(client->adapter, client->addr, client->flags,
-                            I2C_SMBUS_READ, command, I2C_SMBUS_I2C_BLOCK_DATA,
-                            &data);
-       if (!err)
-               memcpy(values, data.block, len);
-       return err;
-}
-
 struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id, int id,
                                                  unsigned int *size)
 {
@@ -124,8 +104,8 @@ struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id, int id,
                return NULL;
 
        for (i = 0; i < len; i += 4) {
-               err = sat_read_block(&sat->i2c, 0xa, data, 4);
-               if (err) {
+               err = i2c_smbus_read_i2c_block_data(&sat->i2c, 0xa, 4, data);
+               if (err < 0) {
                        printk(KERN_ERR "smu_sat_get_sdb_part rd err %d\n",
                               err);
                        goto fail;
@@ -157,8 +137,8 @@ static int wf_sat_read_cache(struct wf_sat *sat)
 {
        int err;
 
-       err = sat_read_block(&sat->i2c, 0x3f, sat->cache, 16);
-       if (err)
+       err = i2c_smbus_read_i2c_block_data(&sat->i2c, 0x3f, 16, sat->cache);
+       if (err < 0)
                return err;
        sat->last_read = jiffies;
 #ifdef LOTSA_DEBUG
index bfd9b9c6252ce7ab909764200f264371a2aecdaa..64bf3a81db93986573ede44f7300b6440b743bd3 100644 (file)
@@ -264,6 +264,12 @@ config DM_MULTIPATH_EMC
        ---help---
          Multipath support for EMC CX/AX series hardware.
 
+config DM_MULTIPATH_RDAC
+       tristate "LSI/Engenio RDAC multipath support (EXPERIMENTAL)"
+       depends on DM_MULTIPATH && BLK_DEV_DM && EXPERIMENTAL
+       ---help---
+         Multipath support for LSI/Engenio RDAC.
+
 config DM_DELAY
        tristate "I/O delaying target (EXPERIMENTAL)"
        depends on BLK_DEV_DM && EXPERIMENTAL
index 71eb45f74171a5c2ac1011917e1e680c63f6bcb3..c49366cdc05d07e991a081ac55ea4eaf6e8f1b3a 100644 (file)
@@ -7,6 +7,7 @@ dm-mod-objs     := dm.o dm-table.o dm-target.o dm-linear.o dm-stripe.o \
 dm-multipath-objs := dm-hw-handler.o dm-path-selector.o dm-mpath.o
 dm-snapshot-objs := dm-snap.o dm-exception-store.o
 dm-mirror-objs := dm-log.o dm-raid1.o
+dm-rdac-objs   := dm-mpath-rdac.o
 md-mod-objs     := md.o bitmap.o
 raid456-objs   := raid5.o raid6algos.o raid6recov.o raid6tables.o \
                   raid6int1.o raid6int2.o raid6int4.o \
@@ -34,6 +35,7 @@ obj-$(CONFIG_DM_CRYPT)                += dm-crypt.o
 obj-$(CONFIG_DM_DELAY)         += dm-delay.o
 obj-$(CONFIG_DM_MULTIPATH)     += dm-multipath.o dm-round-robin.o
 obj-$(CONFIG_DM_MULTIPATH_EMC) += dm-emc.o
+obj-$(CONFIG_DM_MULTIPATH_RDAC)        += dm-rdac.o
 obj-$(CONFIG_DM_SNAPSHOT)      += dm-snapshot.o
 obj-$(CONFIG_DM_MIRROR)                += dm-mirror.o
 obj-$(CONFIG_DM_ZERO)          += dm-zero.o
index c6be88826fae4d7aaea55ea0f6f8da7bf3b747ee..16ee3b018b3aa83b80beda532ded23b609b731fb 100644 (file)
@@ -8,7 +8,6 @@
 #define DM_BIO_LIST_H
 
 #include <linux/bio.h>
-#include <linux/prefetch.h>
 
 struct bio_list {
        struct bio *head;
@@ -31,8 +30,7 @@ static inline void bio_list_init(struct bio_list *bl)
 }
 
 #define bio_list_for_each(bio, bl) \
-       for (bio = (bl)->head; bio && ({ prefetch(bio->bi_next); 1; }); \
-            bio = bio->bi_next)
+       for (bio = (bl)->head; bio; bio = bio->bi_next)
 
 static inline unsigned bio_list_size(const struct bio_list *bl)
 {
index 7b0fcfc9eaa5fc0f724d3313360a304b6bbab3a6..ba952a032598c2411bb3f7ff793f6d00baec92bc 100644 (file)
@@ -30,7 +30,7 @@
 /*
  * per bio private data
  */
-struct crypt_io {
+struct dm_crypt_io {
        struct dm_target *target;
        struct bio *base_bio;
        struct work_struct work;
@@ -106,7 +106,7 @@ struct crypt_config {
 
 static struct kmem_cache *_crypt_io_pool;
 
-static void clone_init(struct crypt_io *, struct bio *);
+static void clone_init(struct dm_crypt_io *, struct bio *);
 
 /*
  * Different IV generation algorithms:
@@ -382,7 +382,7 @@ static int crypt_convert(struct crypt_config *cc,
 
  static void dm_crypt_bio_destructor(struct bio *bio)
  {
-       struct crypt_io *io = bio->bi_private;
+       struct dm_crypt_io *io = bio->bi_private;
        struct crypt_config *cc = io->target->private;
 
        bio_free(bio, cc->bs);
@@ -393,7 +393,7 @@ static int crypt_convert(struct crypt_config *cc,
  * This should never violate the device limitations
  * May return a smaller bio when running out of pages
  */
-static struct bio *crypt_alloc_buffer(struct crypt_io *io, unsigned int size)
+static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned size)
 {
        struct crypt_config *cc = io->target->private;
        struct bio *clone;
@@ -479,7 +479,7 @@ static void crypt_free_buffer_pages(struct crypt_config *cc,
  * One of the bios was finished. Check for completion of
  * the whole request and correctly clean up the buffer.
  */
-static void dec_pending(struct crypt_io *io, int error)
+static void dec_pending(struct dm_crypt_io *io, int error)
 {
        struct crypt_config *cc = (struct crypt_config *) io->target->private;
 
@@ -503,7 +503,7 @@ static void dec_pending(struct crypt_io *io, int error)
 static struct workqueue_struct *_kcryptd_workqueue;
 static void kcryptd_do_work(struct work_struct *work);
 
-static void kcryptd_queue_io(struct crypt_io *io)
+static void kcryptd_queue_io(struct dm_crypt_io *io)
 {
        INIT_WORK(&io->work, kcryptd_do_work);
        queue_work(_kcryptd_workqueue, &io->work);
@@ -511,7 +511,7 @@ static void kcryptd_queue_io(struct crypt_io *io)
 
 static int crypt_endio(struct bio *clone, unsigned int done, int error)
 {
-       struct crypt_io *io = clone->bi_private;
+       struct dm_crypt_io *io = clone->bi_private;
        struct crypt_config *cc = io->target->private;
        unsigned read_io = bio_data_dir(clone) == READ;
 
@@ -545,7 +545,7 @@ out:
        return error;
 }
 
-static void clone_init(struct crypt_io *io, struct bio *clone)
+static void clone_init(struct dm_crypt_io *io, struct bio *clone)
 {
        struct crypt_config *cc = io->target->private;
 
@@ -556,7 +556,7 @@ static void clone_init(struct crypt_io *io, struct bio *clone)
        clone->bi_destructor = dm_crypt_bio_destructor;
 }
 
-static void process_read(struct crypt_io *io)
+static void process_read(struct dm_crypt_io *io)
 {
        struct crypt_config *cc = io->target->private;
        struct bio *base_bio = io->base_bio;
@@ -587,7 +587,7 @@ static void process_read(struct crypt_io *io)
        generic_make_request(clone);
 }
 
-static void process_write(struct crypt_io *io)
+static void process_write(struct dm_crypt_io *io)
 {
        struct crypt_config *cc = io->target->private;
        struct bio *base_bio = io->base_bio;
@@ -644,7 +644,7 @@ static void process_write(struct crypt_io *io)
        }
 }
 
-static void process_read_endio(struct crypt_io *io)
+static void process_read_endio(struct dm_crypt_io *io)
 {
        struct crypt_config *cc = io->target->private;
        struct convert_context ctx;
@@ -657,7 +657,7 @@ static void process_read_endio(struct crypt_io *io)
 
 static void kcryptd_do_work(struct work_struct *work)
 {
-       struct crypt_io *io = container_of(work, struct crypt_io, work);
+       struct dm_crypt_io *io = container_of(work, struct dm_crypt_io, work);
 
        if (io->post_process)
                process_read_endio(io);
@@ -939,10 +939,7 @@ static int crypt_map(struct dm_target *ti, struct bio *bio,
                     union map_info *map_context)
 {
        struct crypt_config *cc = ti->private;
-       struct crypt_io *io;
-
-       if (bio_barrier(bio))
-               return -EOPNOTSUPP;
+       struct dm_crypt_io *io;
 
        io = mempool_alloc(cc->io_pool, GFP_NOIO);
        io->target = ti;
@@ -1062,9 +1059,7 @@ static int __init dm_crypt_init(void)
 {
        int r;
 
-       _crypt_io_pool = kmem_cache_create("dm-crypt_io",
-                                          sizeof(struct crypt_io),
-                                          0, 0, NULL, NULL);
+       _crypt_io_pool = KMEM_CACHE(dm_crypt_io, 0);
        if (!_crypt_io_pool)
                return -ENOMEM;
 
index 52c7cf9e58036428bea63e9ae9cc56ddf8a37c44..6928c136d3c540d8fdcec9730216f436e1cd9131 100644 (file)
@@ -20,7 +20,7 @@
 
 struct delay_c {
        struct timer_list delay_timer;
-       struct semaphore timer_lock;
+       struct mutex timer_lock;
        struct work_struct flush_expired_bios;
        struct list_head delayed_bios;
        atomic_t may_delay;
@@ -37,7 +37,7 @@ struct delay_c {
        unsigned writes;
 };
 
-struct delay_info {
+struct dm_delay_info {
        struct delay_c *context;
        struct list_head list;
        struct bio *bio;
@@ -58,12 +58,12 @@ static void handle_delayed_timer(unsigned long data)
 
 static void queue_timeout(struct delay_c *dc, unsigned long expires)
 {
-       down(&dc->timer_lock);
+       mutex_lock(&dc->timer_lock);
 
        if (!timer_pending(&dc->delay_timer) || expires < dc->delay_timer.expires)
                mod_timer(&dc->delay_timer, expires);
 
-       up(&dc->timer_lock);
+       mutex_unlock(&dc->timer_lock);
 }
 
 static void flush_bios(struct bio *bio)
@@ -80,7 +80,7 @@ static void flush_bios(struct bio *bio)
 
 static struct bio *flush_delayed_bios(struct delay_c *dc, int flush_all)
 {
-       struct delay_info *delayed, *next;
+       struct dm_delay_info *delayed, *next;
        unsigned long next_expires = 0;
        int start_timer = 0;
        BIO_LIST(flush_bios);
@@ -193,13 +193,11 @@ out:
                goto bad;
        }
 
-       init_timer(&dc->delay_timer);
-       dc->delay_timer.function = handle_delayed_timer;
-       dc->delay_timer.data = (unsigned long)dc;
+       setup_timer(&dc->delay_timer, handle_delayed_timer, (unsigned long)dc);
 
        INIT_WORK(&dc->flush_expired_bios, flush_expired_bios);
        INIT_LIST_HEAD(&dc->delayed_bios);
-       init_MUTEX(&dc->timer_lock);
+       mutex_init(&dc->timer_lock);
        atomic_set(&dc->may_delay, 1);
 
        ti->private = dc;
@@ -227,7 +225,7 @@ static void delay_dtr(struct dm_target *ti)
 
 static int delay_bio(struct delay_c *dc, int delay, struct bio *bio)
 {
-       struct delay_info *delayed;
+       struct dm_delay_info *delayed;
        unsigned long expires = 0;
 
        if (!delay || !atomic_read(&dc->may_delay))
@@ -338,10 +336,7 @@ static int __init dm_delay_init(void)
                goto bad_queue;
        }
 
-       delayed_cache = kmem_cache_create("dm-delay",
-                                         sizeof(struct delay_info),
-                                         __alignof__(struct delay_info),
-                                         0, NULL, NULL);
+       delayed_cache = KMEM_CACHE(dm_delay_info, 0);
        if (!delayed_cache) {
                DMERR("Couldn't create delayed bio cache.");
                goto bad_memcache;
index 07e0a0c84f6ef9f8d93da5b914f22dfc0f9c47fc..3d65917a1bbbe97e2336d75255d97fe7a9ca2bf9 100644 (file)
@@ -125,9 +125,11 @@ struct pstore {
        uint32_t callback_count;
        struct commit_callback *callbacks;
        struct dm_io_client *io_client;
+
+       struct workqueue_struct *metadata_wq;
 };
 
-static inline unsigned int sectors_to_pages(unsigned int sectors)
+static unsigned sectors_to_pages(unsigned sectors)
 {
        return sectors / (PAGE_SIZE >> 9);
 }
@@ -156,10 +158,24 @@ static void free_area(struct pstore *ps)
        ps->area = NULL;
 }
 
+struct mdata_req {
+       struct io_region *where;
+       struct dm_io_request *io_req;
+       struct work_struct work;
+       int result;
+};
+
+static void do_metadata(struct work_struct *work)
+{
+       struct mdata_req *req = container_of(work, struct mdata_req, work);
+
+       req->result = dm_io(req->io_req, 1, req->where, NULL);
+}
+
 /*
  * Read or write a chunk aligned and sized block of data from a device.
  */
-static int chunk_io(struct pstore *ps, uint32_t chunk, int rw)
+static int chunk_io(struct pstore *ps, uint32_t chunk, int rw, int metadata)
 {
        struct io_region where = {
                .bdev = ps->snap->cow->bdev,
@@ -173,8 +189,23 @@ static int chunk_io(struct pstore *ps, uint32_t chunk, int rw)
                .client = ps->io_client,
                .notify.fn = NULL,
        };
+       struct mdata_req req;
+
+       if (!metadata)
+               return dm_io(&io_req, 1, &where, NULL);
+
+       req.where = &where;
+       req.io_req = &io_req;
 
-       return dm_io(&io_req, 1, &where, NULL);
+       /*
+        * Issue the synchronous I/O from a different thread
+        * to avoid generic_make_request recursion.
+        */
+       INIT_WORK(&req.work, do_metadata);
+       queue_work(ps->metadata_wq, &req.work);
+       flush_workqueue(ps->metadata_wq);
+
+       return req.result;
 }
 
 /*
@@ -189,7 +220,7 @@ static int area_io(struct pstore *ps, uint32_t area, int rw)
        /* convert a metadata area index to a chunk index */
        chunk = 1 + ((ps->exceptions_per_area + 1) * area);
 
-       r = chunk_io(ps, chunk, rw);
+       r = chunk_io(ps, chunk, rw, 0);
        if (r)
                return r;
 
@@ -230,7 +261,7 @@ static int read_header(struct pstore *ps, int *new_snapshot)
        if (r)
                return r;
 
-       r = chunk_io(ps, 0, READ);
+       r = chunk_io(ps, 0, READ, 1);
        if (r)
                goto bad;
 
@@ -292,7 +323,7 @@ static int write_header(struct pstore *ps)
        dh->version = cpu_to_le32(ps->version);
        dh->chunk_size = cpu_to_le32(ps->snap->chunk_size);
 
-       return chunk_io(ps, 0, WRITE);
+       return chunk_io(ps, 0, WRITE, 1);
 }
 
 /*
@@ -393,7 +424,7 @@ static int read_exceptions(struct pstore *ps)
        return 0;
 }
 
-static inline struct pstore *get_info(struct exception_store *store)
+static struct pstore *get_info(struct exception_store *store)
 {
        return (struct pstore *) store->context;
 }
@@ -409,6 +440,7 @@ static void persistent_destroy(struct exception_store *store)
 {
        struct pstore *ps = get_info(store);
 
+       destroy_workqueue(ps->metadata_wq);
        dm_io_client_destroy(ps->io_client);
        vfree(ps->callbacks);
        free_area(ps);
@@ -457,17 +489,18 @@ static int persistent_read_metadata(struct exception_store *store)
                /*
                 * Sanity checks.
                 */
-               if (!ps->valid) {
-                       DMWARN("snapshot is marked invalid");
-                       return -EINVAL;
-               }
-
                if (ps->version != SNAPSHOT_DISK_VERSION) {
                        DMWARN("unable to handle snapshot disk version %d",
                               ps->version);
                        return -EINVAL;
                }
 
+               /*
+                * Metadata are valid, but snapshot is invalidated
+                */
+               if (!ps->valid)
+                       return 1;
+
                /*
                 * Read the metadata.
                 */
@@ -480,7 +513,7 @@ static int persistent_read_metadata(struct exception_store *store)
 }
 
 static int persistent_prepare(struct exception_store *store,
-                             struct exception *e)
+                             struct dm_snap_exception *e)
 {
        struct pstore *ps = get_info(store);
        uint32_t stride;
@@ -505,7 +538,7 @@ static int persistent_prepare(struct exception_store *store,
 }
 
 static void persistent_commit(struct exception_store *store,
-                             struct exception *e,
+                             struct dm_snap_exception *e,
                              void (*callback) (void *, int success),
                              void *callback_context)
 {
@@ -588,6 +621,12 @@ int dm_create_persistent(struct exception_store *store)
        atomic_set(&ps->pending_count, 0);
        ps->callbacks = NULL;
 
+       ps->metadata_wq = create_singlethread_workqueue("ksnaphd");
+       if (!ps->metadata_wq) {
+               DMERR("couldn't start header metadata update thread");
+               return -ENOMEM;
+       }
+
        store->destroy = persistent_destroy;
        store->read_metadata = persistent_read_metadata;
        store->prepare_exception = persistent_prepare;
@@ -616,7 +655,8 @@ static int transient_read_metadata(struct exception_store *store)
        return 0;
 }
 
-static int transient_prepare(struct exception_store *store, struct exception *e)
+static int transient_prepare(struct exception_store *store,
+                            struct dm_snap_exception *e)
 {
        struct transient_c *tc = (struct transient_c *) store->context;
        sector_t size = get_dev_size(store->snap->cow->bdev);
@@ -631,9 +671,9 @@ static int transient_prepare(struct exception_store *store, struct exception *e)
 }
 
 static void transient_commit(struct exception_store *store,
-                     struct exception *e,
-                     void (*callback) (void *, int success),
-                     void *callback_context)
+                            struct dm_snap_exception *e,
+                            void (*callback) (void *, int success),
+                            void *callback_context)
 {
        /* Just succeed */
        callback(callback_context, 1);
index 352c6fbeac53a19dd82f8ef6994b733da4ad931d..f3a772486437e1ee08608e28835adf85911aaaf8 100644 (file)
@@ -293,7 +293,10 @@ static void do_region(int rw, unsigned int region, struct io_region *where,
                 * bvec for bio_get/set_region() and decrement bi_max_vecs
                 * to hide it from bio_add_page().
                 */
-               num_bvecs = (remaining / (PAGE_SIZE >> SECTOR_SHIFT)) + 2;
+               num_bvecs = dm_sector_div_up(remaining,
+                                            (PAGE_SIZE >> SECTOR_SHIFT));
+               num_bvecs = 1 + min_t(int, bio_get_nr_vecs(where->bdev),
+                                     num_bvecs);
                bio = bio_alloc_bioset(GFP_NOIO, num_bvecs, io->client->bios);
                bio->bi_sector = where->sector + (where->count - remaining);
                bio->bi_bdev = where->bdev;
diff --git a/drivers/md/dm-mpath-rdac.c b/drivers/md/dm-mpath-rdac.c
new file mode 100644 (file)
index 0000000..8b776b8
--- /dev/null
@@ -0,0 +1,700 @@
+/*
+ * Engenio/LSI RDAC DM HW handler
+ *
+ * Copyright (C) 2005 Mike Christie. All rights reserved.
+ * Copyright (C) Chandra Seetharaman, IBM Corp. 2007
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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 <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_eh.h>
+
+#define DM_MSG_PREFIX "multipath rdac"
+
+#include "dm.h"
+#include "dm-hw-handler.h"
+
+#define RDAC_DM_HWH_NAME "rdac"
+#define RDAC_DM_HWH_VER "0.4"
+
+/*
+ * LSI mode page stuff
+ *
+ * These struct definitions and the forming of the
+ * mode page were taken from the LSI RDAC 2.4 GPL'd
+ * driver, and then converted to Linux conventions.
+ */
+#define RDAC_QUIESCENCE_TIME 20;
+/*
+ * Page Codes
+ */
+#define RDAC_PAGE_CODE_REDUNDANT_CONTROLLER 0x2c
+
+/*
+ * Controller modes definitions
+ */
+#define RDAC_MODE_TRANSFER_ALL_LUNS            0x01
+#define RDAC_MODE_TRANSFER_SPECIFIED_LUNS      0x02
+
+/*
+ * RDAC Options field
+ */
+#define RDAC_FORCED_QUIESENCE 0x02
+
+#define RDAC_FAILOVER_TIMEOUT (60 * HZ)
+
+struct rdac_mode_6_hdr {
+       u8      data_len;
+       u8      medium_type;
+       u8      device_params;
+       u8      block_desc_len;
+};
+
+struct rdac_mode_10_hdr {
+       u16     data_len;
+       u8      medium_type;
+       u8      device_params;
+       u16     reserved;
+       u16     block_desc_len;
+};
+
+struct rdac_mode_common {
+       u8      controller_serial[16];
+       u8      alt_controller_serial[16];
+       u8      rdac_mode[2];
+       u8      alt_rdac_mode[2];
+       u8      quiescence_timeout;
+       u8      rdac_options;
+};
+
+struct rdac_pg_legacy {
+       struct rdac_mode_6_hdr hdr;
+       u8      page_code;
+       u8      page_len;
+       struct rdac_mode_common common;
+#define MODE6_MAX_LUN  32
+       u8      lun_table[MODE6_MAX_LUN];
+       u8      reserved2[32];
+       u8      reserved3;
+       u8      reserved4;
+};
+
+struct rdac_pg_expanded {
+       struct rdac_mode_10_hdr hdr;
+       u8      page_code;
+       u8      subpage_code;
+       u8      page_len[2];
+       struct rdac_mode_common common;
+       u8      lun_table[256];
+       u8      reserved3;
+       u8      reserved4;
+};
+
+struct c9_inquiry {
+       u8      peripheral_info;
+       u8      page_code;      /* 0xC9 */
+       u8      reserved1;
+       u8      page_len;
+       u8      page_id[4];     /* "vace" */
+       u8      avte_cvp;
+       u8      path_prio;
+       u8      reserved2[38];
+};
+
+#define SUBSYS_ID_LEN  16
+#define SLOT_ID_LEN    2
+
+struct c4_inquiry {
+       u8      peripheral_info;
+       u8      page_code;      /* 0xC4 */
+       u8      reserved1;
+       u8      page_len;
+       u8      page_id[4];     /* "subs" */
+       u8      subsys_id[SUBSYS_ID_LEN];
+       u8      revision[4];
+       u8      slot_id[SLOT_ID_LEN];
+       u8      reserved[2];
+};
+
+struct rdac_controller {
+       u8                      subsys_id[SUBSYS_ID_LEN];
+       u8                      slot_id[SLOT_ID_LEN];
+       int                     use_10_ms;
+       struct kref             kref;
+       struct list_head        node; /* list of all controllers */
+       spinlock_t              lock;
+       int                     submitted;
+       struct list_head        cmd_list; /* list of commands to be submitted */
+       union                   {
+               struct rdac_pg_legacy legacy;
+               struct rdac_pg_expanded expanded;
+       } mode_select;
+};
+struct c8_inquiry {
+       u8      peripheral_info;
+       u8      page_code; /* 0xC8 */
+       u8      reserved1;
+       u8      page_len;
+       u8      page_id[4]; /* "edid" */
+       u8      reserved2[3];
+       u8      vol_uniq_id_len;
+       u8      vol_uniq_id[16];
+       u8      vol_user_label_len;
+       u8      vol_user_label[60];
+       u8      array_uniq_id_len;
+       u8      array_unique_id[16];
+       u8      array_user_label_len;
+       u8      array_user_label[60];
+       u8      lun[8];
+};
+
+struct c2_inquiry {
+       u8      peripheral_info;
+       u8      page_code;      /* 0xC2 */
+       u8      reserved1;
+       u8      page_len;
+       u8      page_id[4];     /* "swr4" */
+       u8      sw_version[3];
+       u8      sw_date[3];
+       u8      features_enabled;
+       u8      max_lun_supported;
+       u8      partitions[239]; /* Total allocation length should be 0xFF */
+};
+
+struct rdac_handler {
+       struct list_head        entry; /* list waiting to submit MODE SELECT */
+       unsigned                timeout;
+       struct rdac_controller  *ctlr;
+#define UNINITIALIZED_LUN      (1 << 8)
+       unsigned                lun;
+       unsigned char           sense[SCSI_SENSE_BUFFERSIZE];
+       struct dm_path          *path;
+       struct work_struct      work;
+#define        SEND_C2_INQUIRY         1
+#define        SEND_C4_INQUIRY         2
+#define        SEND_C8_INQUIRY         3
+#define        SEND_C9_INQUIRY         4
+#define        SEND_MODE_SELECT        5
+       int                     cmd_to_send;
+       union                   {
+               struct c2_inquiry c2;
+               struct c4_inquiry c4;
+               struct c8_inquiry c8;
+               struct c9_inquiry c9;
+       } inq;
+};
+
+static LIST_HEAD(ctlr_list);
+static DEFINE_SPINLOCK(list_lock);
+static struct workqueue_struct *rdac_wkqd;
+
+static inline int had_failures(struct request *req, int error)
+{
+       return (error || host_byte(req->errors) != DID_OK ||
+                       msg_byte(req->errors) != COMMAND_COMPLETE);
+}
+
+static void rdac_resubmit_all(struct rdac_handler *h)
+{
+       struct rdac_controller *ctlr = h->ctlr;
+       struct rdac_handler *tmp, *h1;
+
+       spin_lock(&ctlr->lock);
+       list_for_each_entry_safe(h1, tmp, &ctlr->cmd_list, entry) {
+               h1->cmd_to_send = SEND_C9_INQUIRY;
+               queue_work(rdac_wkqd, &h1->work);
+               list_del(&h1->entry);
+       }
+       ctlr->submitted = 0;
+       spin_unlock(&ctlr->lock);
+}
+
+static void mode_select_endio(struct request *req, int error)
+{
+       struct rdac_handler *h = req->end_io_data;
+       struct scsi_sense_hdr sense_hdr;
+       int sense = 0, fail = 0;
+
+       if (had_failures(req, error)) {
+               fail = 1;
+               goto failed;
+       }
+
+       if (status_byte(req->errors) == CHECK_CONDITION) {
+               scsi_normalize_sense(req->sense, SCSI_SENSE_BUFFERSIZE,
+                               &sense_hdr);
+               sense = (sense_hdr.sense_key << 16) | (sense_hdr.asc << 8) |
+                               sense_hdr.ascq;
+               /* If it is retryable failure, submit the c9 inquiry again */
+               if (sense == 0x59136 || sense == 0x68b02 || sense == 0xb8b02 ||
+                   sense == 0x62900) {
+                       /* 0x59136    - Command lock contention
+                        * 0x[6b]8b02 - Quiesense in progress or achieved
+                        * 0x62900    - Power On, Reset, or Bus Device Reset
+                        */
+                       h->cmd_to_send = SEND_C9_INQUIRY;
+                       queue_work(rdac_wkqd, &h->work);
+                       goto done;
+               }
+               if (sense)
+                       DMINFO("MODE_SELECT failed on %s with sense 0x%x",
+                                               h->path->dev->name, sense);
+       }
+failed:
+       if (fail || sense)
+               dm_pg_init_complete(h->path, MP_FAIL_PATH);
+       else
+               dm_pg_init_complete(h->path, 0);
+
+done:
+       rdac_resubmit_all(h);
+       __blk_put_request(req->q, req);
+}
+
+static struct request *get_rdac_req(struct rdac_handler *h,
+                       void *buffer, unsigned buflen, int rw)
+{
+       struct request *rq;
+       struct request_queue *q = bdev_get_queue(h->path->dev->bdev);
+
+       rq = blk_get_request(q, rw, GFP_KERNEL);
+
+       if (!rq) {
+               DMINFO("get_rdac_req: blk_get_request failed");
+               return NULL;
+       }
+
+       if (buflen && blk_rq_map_kern(q, rq, buffer, buflen, GFP_KERNEL)) {
+               blk_put_request(rq);
+               DMINFO("get_rdac_req: blk_rq_map_kern failed");
+               return NULL;
+       }
+
+       memset(&rq->cmd, 0, BLK_MAX_CDB);
+       rq->sense = h->sense;
+       memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
+       rq->sense_len = 0;
+
+       rq->end_io_data = h;
+       rq->timeout = h->timeout;
+       rq->cmd_type = REQ_TYPE_BLOCK_PC;
+       rq->cmd_flags = REQ_FAILFAST | REQ_NOMERGE;
+       return rq;
+}
+
+static struct request *rdac_failover_get(struct rdac_handler *h)
+{
+       struct request *rq;
+       struct rdac_mode_common *common;
+       unsigned data_size;
+
+       if (h->ctlr->use_10_ms) {
+               struct rdac_pg_expanded *rdac_pg;
+
+               data_size = sizeof(struct rdac_pg_expanded);
+               rdac_pg = &h->ctlr->mode_select.expanded;
+               memset(rdac_pg, 0, data_size);
+               common = &rdac_pg->common;
+               rdac_pg->page_code = RDAC_PAGE_CODE_REDUNDANT_CONTROLLER + 0x40;
+               rdac_pg->subpage_code = 0x1;
+               rdac_pg->page_len[0] = 0x01;
+               rdac_pg->page_len[1] = 0x28;
+               rdac_pg->lun_table[h->lun] = 0x81;
+       } else {
+               struct rdac_pg_legacy *rdac_pg;
+
+               data_size = sizeof(struct rdac_pg_legacy);
+               rdac_pg = &h->ctlr->mode_select.legacy;
+               memset(rdac_pg, 0, data_size);
+               common = &rdac_pg->common;
+               rdac_pg->page_code = RDAC_PAGE_CODE_REDUNDANT_CONTROLLER;
+               rdac_pg->page_len = 0x68;
+               rdac_pg->lun_table[h->lun] = 0x81;
+       }
+       common->rdac_mode[1] = RDAC_MODE_TRANSFER_SPECIFIED_LUNS;
+       common->quiescence_timeout = RDAC_QUIESCENCE_TIME;
+       common->rdac_options = RDAC_FORCED_QUIESENCE;
+
+       /* get request for block layer packet command */
+       rq = get_rdac_req(h, &h->ctlr->mode_select, data_size, WRITE);
+       if (!rq) {
+               DMERR("rdac_failover_get: no rq");
+               return NULL;
+       }
+
+       /* Prepare the command. */
+       if (h->ctlr->use_10_ms) {
+               rq->cmd[0] = MODE_SELECT_10;
+               rq->cmd[7] = data_size >> 8;
+               rq->cmd[8] = data_size & 0xff;
+       } else {
+               rq->cmd[0] = MODE_SELECT;
+               rq->cmd[4] = data_size;
+       }
+       rq->cmd_len = COMMAND_SIZE(rq->cmd[0]);
+
+       return rq;
+}
+
+/* Acquires h->ctlr->lock */
+static void submit_mode_select(struct rdac_handler *h)
+{
+       struct request *rq;
+       struct request_queue *q = bdev_get_queue(h->path->dev->bdev);
+
+       spin_lock(&h->ctlr->lock);
+       if (h->ctlr->submitted) {
+               list_add(&h->entry, &h->ctlr->cmd_list);
+               goto drop_lock;
+       }
+
+       if (!q) {
+               DMINFO("submit_mode_select: no queue");
+               goto fail_path;
+       }
+
+       rq = rdac_failover_get(h);
+       if (!rq) {
+               DMERR("submit_mode_select: no rq");
+               goto fail_path;
+       }
+
+       DMINFO("queueing MODE_SELECT command on %s", h->path->dev->name);
+
+       blk_execute_rq_nowait(q, NULL, rq, 1, mode_select_endio);
+       h->ctlr->submitted = 1;
+       goto drop_lock;
+fail_path:
+       dm_pg_init_complete(h->path, MP_FAIL_PATH);
+drop_lock:
+       spin_unlock(&h->ctlr->lock);
+}
+
+static void release_ctlr(struct kref *kref)
+{
+       struct rdac_controller *ctlr;
+       ctlr = container_of(kref, struct rdac_controller, kref);
+
+       spin_lock(&list_lock);
+       list_del(&ctlr->node);
+       spin_unlock(&list_lock);
+       kfree(ctlr);
+}
+
+static struct rdac_controller *get_controller(u8 *subsys_id, u8 *slot_id)
+{
+       struct rdac_controller *ctlr, *tmp;
+
+       spin_lock(&list_lock);
+
+       list_for_each_entry(tmp, &ctlr_list, node) {
+               if ((memcmp(tmp->subsys_id, subsys_id, SUBSYS_ID_LEN) == 0) &&
+                         (memcmp(tmp->slot_id, slot_id, SLOT_ID_LEN) == 0)) {
+                       kref_get(&tmp->kref);
+                       spin_unlock(&list_lock);
+                       return tmp;
+               }
+       }
+       ctlr = kmalloc(sizeof(*ctlr), GFP_ATOMIC);
+       if (!ctlr)
+               goto done;
+
+       /* initialize fields of controller */
+       memcpy(ctlr->subsys_id, subsys_id, SUBSYS_ID_LEN);
+       memcpy(ctlr->slot_id, slot_id, SLOT_ID_LEN);
+       kref_init(&ctlr->kref);
+       spin_lock_init(&ctlr->lock);
+       ctlr->submitted = 0;
+       ctlr->use_10_ms = -1;
+       INIT_LIST_HEAD(&ctlr->cmd_list);
+       list_add(&ctlr->node, &ctlr_list);
+done:
+       spin_unlock(&list_lock);
+       return ctlr;
+}
+
+static void c4_endio(struct request *req, int error)
+{
+       struct rdac_handler *h = req->end_io_data;
+       struct c4_inquiry *sp;
+
+       if (had_failures(req, error)) {
+               dm_pg_init_complete(h->path, MP_FAIL_PATH);
+               goto done;
+       }
+
+       sp = &h->inq.c4;
+
+       h->ctlr = get_controller(sp->subsys_id, sp->slot_id);
+
+       if (h->ctlr) {
+               h->cmd_to_send = SEND_C9_INQUIRY;
+               queue_work(rdac_wkqd, &h->work);
+       } else
+               dm_pg_init_complete(h->path, MP_FAIL_PATH);
+done:
+       __blk_put_request(req->q, req);
+}
+
+static void c2_endio(struct request *req, int error)
+{
+       struct rdac_handler *h = req->end_io_data;
+       struct c2_inquiry *sp;
+
+       if (had_failures(req, error)) {
+               dm_pg_init_complete(h->path, MP_FAIL_PATH);
+               goto done;
+       }
+
+       sp = &h->inq.c2;
+
+       /* If more than MODE6_MAX_LUN luns are supported, use mode select 10 */
+       if (sp->max_lun_supported >= MODE6_MAX_LUN)
+               h->ctlr->use_10_ms = 1;
+       else
+               h->ctlr->use_10_ms = 0;
+
+       h->cmd_to_send = SEND_MODE_SELECT;
+       queue_work(rdac_wkqd, &h->work);
+done:
+       __blk_put_request(req->q, req);
+}
+
+static void c9_endio(struct request *req, int error)
+{
+       struct rdac_handler *h = req->end_io_data;
+       struct c9_inquiry *sp;
+
+       if (had_failures(req, error)) {
+               dm_pg_init_complete(h->path, MP_FAIL_PATH);
+               goto done;
+       }
+
+       /* We need to look at the sense keys here to take clear action.
+        * For now simple logic: If the host is in AVT mode or if controller
+        * owns the lun, return dm_pg_init_complete(), otherwise submit
+        * MODE SELECT.
+        */
+       sp = &h->inq.c9;
+
+       /* If in AVT mode, return success */
+       if ((sp->avte_cvp >> 7) == 0x1) {
+               dm_pg_init_complete(h->path, 0);
+               goto done;
+       }
+
+       /* If the controller on this path owns the LUN, return success */
+       if (sp->avte_cvp & 0x1) {
+               dm_pg_init_complete(h->path, 0);
+               goto done;
+       }
+
+       if (h->ctlr) {
+               if (h->ctlr->use_10_ms == -1)
+                       h->cmd_to_send = SEND_C2_INQUIRY;
+               else
+                       h->cmd_to_send = SEND_MODE_SELECT;
+       } else
+               h->cmd_to_send = SEND_C4_INQUIRY;
+       queue_work(rdac_wkqd, &h->work);
+done:
+       __blk_put_request(req->q, req);
+}
+
+static void c8_endio(struct request *req, int error)
+{
+       struct rdac_handler *h = req->end_io_data;
+       struct c8_inquiry *sp;
+
+       if (had_failures(req, error)) {
+               dm_pg_init_complete(h->path, MP_FAIL_PATH);
+               goto done;
+       }
+
+       /* We need to look at the sense keys here to take clear action.
+        * For now simple logic: Get the lun from the inquiry page.
+        */
+       sp = &h->inq.c8;
+       h->lun = sp->lun[7]; /* currently it uses only one byte */
+       h->cmd_to_send = SEND_C9_INQUIRY;
+       queue_work(rdac_wkqd, &h->work);
+done:
+       __blk_put_request(req->q, req);
+}
+
+static void submit_inquiry(struct rdac_handler *h, int page_code,
+               unsigned int len, rq_end_io_fn endio)
+{
+       struct request *rq;
+       struct request_queue *q = bdev_get_queue(h->path->dev->bdev);
+
+       if (!q)
+               goto fail_path;
+
+       rq = get_rdac_req(h, &h->inq, len, READ);
+       if (!rq)
+               goto fail_path;
+
+       /* Prepare the command. */
+       rq->cmd[0] = INQUIRY;
+       rq->cmd[1] = 1;
+       rq->cmd[2] = page_code;
+       rq->cmd[4] = len;
+       rq->cmd_len = COMMAND_SIZE(INQUIRY);
+       blk_execute_rq_nowait(q, NULL, rq, 1, endio);
+       return;
+
+fail_path:
+       dm_pg_init_complete(h->path, MP_FAIL_PATH);
+}
+
+static void service_wkq(struct work_struct *work)
+{
+       struct rdac_handler *h = container_of(work, struct rdac_handler, work);
+
+       switch (h->cmd_to_send) {
+       case SEND_C2_INQUIRY:
+               submit_inquiry(h, 0xC2, sizeof(struct c2_inquiry), c2_endio);
+               break;
+       case SEND_C4_INQUIRY:
+               submit_inquiry(h, 0xC4, sizeof(struct c4_inquiry), c4_endio);
+               break;
+       case SEND_C8_INQUIRY:
+               submit_inquiry(h, 0xC8, sizeof(struct c8_inquiry), c8_endio);
+               break;
+       case SEND_C9_INQUIRY:
+               submit_inquiry(h, 0xC9, sizeof(struct c9_inquiry), c9_endio);
+               break;
+       case SEND_MODE_SELECT:
+               submit_mode_select(h);
+               break;
+       default:
+               BUG();
+       }
+}
+/*
+ * only support subpage2c until we confirm that this is just a matter of
+ * of updating firmware or not, and RDAC (basic AVT works already) for now
+ * but we can add these in in when we get time and testers
+ */
+static int rdac_create(struct hw_handler *hwh, unsigned argc, char **argv)
+{
+       struct rdac_handler *h;
+       unsigned timeout;
+
+       if (argc == 0) {
+               /* No arguments: use defaults */
+               timeout = RDAC_FAILOVER_TIMEOUT;
+       } else if (argc != 1) {
+               DMWARN("incorrect number of arguments");
+               return -EINVAL;
+       } else {
+               if (sscanf(argv[1], "%u", &timeout) != 1) {
+                       DMWARN("invalid timeout value");
+                       return -EINVAL;
+               }
+       }
+
+       h = kzalloc(sizeof(*h), GFP_KERNEL);
+       if (!h)
+               return -ENOMEM;
+
+       hwh->context = h;
+       h->timeout = timeout;
+       h->lun = UNINITIALIZED_LUN;
+       INIT_WORK(&h->work, service_wkq);
+       DMWARN("using RDAC command with timeout %u", h->timeout);
+
+       return 0;
+}
+
+static void rdac_destroy(struct hw_handler *hwh)
+{
+       struct rdac_handler *h = hwh->context;
+
+       if (h->ctlr)
+               kref_put(&h->ctlr->kref, release_ctlr);
+       kfree(h);
+       hwh->context = NULL;
+}
+
+static unsigned rdac_error(struct hw_handler *hwh, struct bio *bio)
+{
+       /* Try default handler */
+       return dm_scsi_err_handler(hwh, bio);
+}
+
+static void rdac_pg_init(struct hw_handler *hwh, unsigned bypassed,
+                       struct dm_path *path)
+{
+       struct rdac_handler *h = hwh->context;
+
+       h->path = path;
+       switch (h->lun) {
+       case UNINITIALIZED_LUN:
+               submit_inquiry(h, 0xC8, sizeof(struct c8_inquiry), c8_endio);
+               break;
+       default:
+               submit_inquiry(h, 0xC9, sizeof(struct c9_inquiry), c9_endio);
+       }
+}
+
+static struct hw_handler_type rdac_handler = {
+       .name = RDAC_DM_HWH_NAME,
+       .module = THIS_MODULE,
+       .create = rdac_create,
+       .destroy = rdac_destroy,
+       .pg_init = rdac_pg_init,
+       .error = rdac_error,
+};
+
+static int __init rdac_init(void)
+{
+       int r = dm_register_hw_handler(&rdac_handler);
+
+       if (r < 0) {
+               DMERR("%s: register failed %d", RDAC_DM_HWH_NAME, r);
+               return r;
+       }
+
+       rdac_wkqd = create_singlethread_workqueue("rdac_wkqd");
+       if (!rdac_wkqd) {
+               DMERR("Failed to create workqueue rdac_wkqd.");
+               dm_unregister_hw_handler(&rdac_handler);
+               return -ENOMEM;
+       }
+
+       DMINFO("%s: version %s loaded", RDAC_DM_HWH_NAME, RDAC_DM_HWH_VER);
+       return 0;
+}
+
+static void __exit rdac_exit(void)
+{
+       int r = dm_unregister_hw_handler(&rdac_handler);
+
+       destroy_workqueue(rdac_wkqd);
+       if (r < 0)
+               DMERR("%s: unregister failed %d", RDAC_DM_HWH_NAME, r);
+}
+
+module_init(rdac_init);
+module_exit(rdac_exit);
+
+MODULE_DESCRIPTION("DM Multipath LSI/Engenio RDAC support");
+MODULE_AUTHOR("Mike Christie, Chandra Seetharaman");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(RDAC_DM_HWH_VER);
index de54b39e6ffe9fb78cbad18c2a5d5b559d54d870..d6ca9d0a6fd1cbd5fd8f223e9e2b901092e631f3 100644 (file)
@@ -83,7 +83,7 @@ struct multipath {
        struct work_struct trigger_event;
 
        /*
-        * We must use a mempool of mpath_io structs so that we
+        * We must use a mempool of dm_mpath_io structs so that we
         * can resubmit bios on error.
         */
        mempool_t *mpio_pool;
@@ -92,7 +92,7 @@ struct multipath {
 /*
  * Context information attached to each bio we process.
  */
-struct mpath_io {
+struct dm_mpath_io {
        struct pgpath *pgpath;
        struct dm_bio_details details;
 };
@@ -122,7 +122,7 @@ static struct pgpath *alloc_pgpath(void)
        return pgpath;
 }
 
-static inline void free_pgpath(struct pgpath *pgpath)
+static void free_pgpath(struct pgpath *pgpath)
 {
        kfree(pgpath);
 }
@@ -299,8 +299,8 @@ static int __must_push_back(struct multipath *m)
                dm_noflush_suspending(m->ti));
 }
 
-static int map_io(struct multipath *m, struct bio *bio, struct mpath_io *mpio,
-                 unsigned was_queued)
+static int map_io(struct multipath *m, struct bio *bio,
+                 struct dm_mpath_io *mpio, unsigned was_queued)
 {
        int r = DM_MAPIO_REMAPPED;
        unsigned long flags;
@@ -374,7 +374,7 @@ static void dispatch_queued_ios(struct multipath *m)
        int r;
        unsigned long flags;
        struct bio *bio = NULL, *next;
-       struct mpath_io *mpio;
+       struct dm_mpath_io *mpio;
        union map_info *info;
 
        spin_lock_irqsave(&m->lock, flags);
@@ -795,12 +795,9 @@ static int multipath_map(struct dm_target *ti, struct bio *bio,
                         union map_info *map_context)
 {
        int r;
-       struct mpath_io *mpio;
+       struct dm_mpath_io *mpio;
        struct multipath *m = (struct multipath *) ti->private;
 
-       if (bio_barrier(bio))
-               return -EOPNOTSUPP;
-
        mpio = mempool_alloc(m->mpio_pool, GFP_NOIO);
        dm_bio_record(&mpio->details, bio);
 
@@ -1014,7 +1011,7 @@ void dm_pg_init_complete(struct dm_path *path, unsigned err_flags)
  * end_io handling
  */
 static int do_end_io(struct multipath *m, struct bio *bio,
-                    int error, struct mpath_io *mpio)
+                    int error, struct dm_mpath_io *mpio)
 {
        struct hw_handler *hwh = &m->hw_handler;
        unsigned err_flags = MP_FAIL_PATH;      /* Default behavior */
@@ -1075,8 +1072,8 @@ static int do_end_io(struct multipath *m, struct bio *bio,
 static int multipath_end_io(struct dm_target *ti, struct bio *bio,
                            int error, union map_info *map_context)
 {
-       struct multipath *m = (struct multipath *) ti->private;
-       struct mpath_io *mpio = (struct mpath_io *) map_context->ptr;
+       struct multipath *m = ti->private;
+       struct dm_mpath_io *mpio = map_context->ptr;
        struct pgpath *pgpath = mpio->pgpath;
        struct path_selector *ps;
        int r;
@@ -1346,22 +1343,20 @@ static int __init dm_multipath_init(void)
        int r;
 
        /* allocate a slab for the dm_ios */
-       _mpio_cache = kmem_cache_create("dm_mpath", sizeof(struct mpath_io),
-                                       0, 0, NULL, NULL);
+       _mpio_cache = KMEM_CACHE(dm_mpath_io, 0);
        if (!_mpio_cache)
                return -ENOMEM;
 
        r = dm_register_target(&multipath_target);
        if (r < 0) {
-               DMERR("%s: register failed %d", multipath_target.name, r);
+               DMERR("register failed %d", r);
                kmem_cache_destroy(_mpio_cache);
                return -EINVAL;
        }
 
        kmultipathd = create_workqueue("kmpathd");
        if (!kmultipathd) {
-               DMERR("%s: failed to create workqueue kmpathd",
-                               multipath_target.name);
+               DMERR("failed to create workqueue kmpathd");
                dm_unregister_target(&multipath_target);
                kmem_cache_destroy(_mpio_cache);
                return -ENOMEM;
@@ -1382,8 +1377,7 @@ static void __exit dm_multipath_exit(void)
 
        r = dm_unregister_target(&multipath_target);
        if (r < 0)
-               DMERR("%s: target unregister failed %d",
-                     multipath_target.name, r);
+               DMERR("target unregister failed %d", r);
        kmem_cache_destroy(_mpio_cache);
 }
 
index ef124b71ccc8f1dfd9aa0fdfad0fad81010b0613..1a876f9965e008f9a2008b37806a5fd95443aef8 100644 (file)
@@ -24,6 +24,7 @@
 #define DM_IO_PAGES 64
 
 #define DM_RAID1_HANDLE_ERRORS 0x01
+#define errors_handled(p)      ((p)->features & DM_RAID1_HANDLE_ERRORS)
 
 static DECLARE_WAIT_QUEUE_HEAD(_kmirrord_recovery_stopped);
 
@@ -85,6 +86,7 @@ struct region_hash {
        struct list_head clean_regions;
        struct list_head quiesced_regions;
        struct list_head recovered_regions;
+       struct list_head failed_recovered_regions;
 };
 
 enum {
@@ -132,6 +134,7 @@ struct mirror_set {
        /* recovery */
        region_t nr_regions;
        int in_sync;
+       int log_failure;
 
        struct mirror *default_mirror;  /* Default mirror */
 
@@ -204,6 +207,7 @@ static int rh_init(struct region_hash *rh, struct mirror_set *ms,
        INIT_LIST_HEAD(&rh->clean_regions);
        INIT_LIST_HEAD(&rh->quiesced_regions);
        INIT_LIST_HEAD(&rh->recovered_regions);
+       INIT_LIST_HEAD(&rh->failed_recovered_regions);
 
        rh->region_pool = mempool_create_kmalloc_pool(MIN_REGIONS,
                                                      sizeof(struct region));
@@ -368,6 +372,7 @@ static void rh_update_states(struct region_hash *rh)
 
        LIST_HEAD(clean);
        LIST_HEAD(recovered);
+       LIST_HEAD(failed_recovered);
 
        /*
         * Quickly grab the lists.
@@ -378,10 +383,8 @@ static void rh_update_states(struct region_hash *rh)
                list_splice(&rh->clean_regions, &clean);
                INIT_LIST_HEAD(&rh->clean_regions);
 
-               list_for_each_entry (reg, &clean, list) {
-                       rh->log->type->clear_region(rh->log, reg->key);
+               list_for_each_entry(reg, &clean, list)
                        list_del(&reg->hash_list);
-               }
        }
 
        if (!list_empty(&rh->recovered_regions)) {
@@ -391,6 +394,15 @@ static void rh_update_states(struct region_hash *rh)
                list_for_each_entry (reg, &recovered, list)
                        list_del(&reg->hash_list);
        }
+
+       if (!list_empty(&rh->failed_recovered_regions)) {
+               list_splice(&rh->failed_recovered_regions, &failed_recovered);
+               INIT_LIST_HEAD(&rh->failed_recovered_regions);
+
+               list_for_each_entry(reg, &failed_recovered, list)
+                       list_del(&reg->hash_list);
+       }
+
        spin_unlock(&rh->region_lock);
        write_unlock_irq(&rh->hash_lock);
 
@@ -405,10 +417,17 @@ static void rh_update_states(struct region_hash *rh)
                mempool_free(reg, rh->region_pool);
        }
 
-       rh->log->type->flush(rh->log);
+       list_for_each_entry_safe(reg, next, &failed_recovered, list) {
+               complete_resync_work(reg, errors_handled(rh->ms) ? 0 : 1);
+               mempool_free(reg, rh->region_pool);
+       }
 
-       list_for_each_entry_safe (reg, next, &clean, list)
+       list_for_each_entry_safe(reg, next, &clean, list) {
+               rh->log->type->clear_region(rh->log, reg->key);
                mempool_free(reg, rh->region_pool);
+       }
+
+       rh->log->type->flush(rh->log);
 }
 
 static void rh_inc(struct region_hash *rh, region_t region)
@@ -555,21 +574,25 @@ static struct region *rh_recovery_start(struct region_hash *rh)
        return reg;
 }
 
-/* FIXME: success ignored for now */
 static void rh_recovery_end(struct region *reg, int success)
 {
        struct region_hash *rh = reg->rh;
 
        spin_lock_irq(&rh->region_lock);
-       list_add(&reg->list, &reg->rh->recovered_regions);
+       if (success)
+               list_add(&reg->list, &reg->rh->recovered_regions);
+       else {
+               reg->state = RH_NOSYNC;
+               list_add(&reg->list, &reg->rh->failed_recovered_regions);
+       }
        spin_unlock_irq(&rh->region_lock);
 
        wake(rh->ms);
 }
 
-static void rh_flush(struct region_hash *rh)
+static int rh_flush(struct region_hash *rh)
 {
-       rh->log->type->flush(rh->log);
+       return rh->log->type->flush(rh->log);
 }
 
 static void rh_delay(struct region_hash *rh, struct bio *bio)
@@ -633,7 +656,14 @@ static void recovery_complete(int read_err, unsigned int write_err,
 {
        struct region *reg = (struct region *) context;
 
-       /* FIXME: better error handling */
+       if (read_err)
+               /* Read error means the failure of default mirror. */
+               DMERR_LIMIT("Unable to read primary mirror during recovery");
+
+       if (write_err)
+               DMERR_LIMIT("Write error during recovery (error = 0x%x)",
+                           write_err);
+
        rh_recovery_end(reg, !(read_err || write_err));
 }
 
@@ -863,12 +893,15 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes)
         */
        rh_inc_pending(&ms->rh, &sync);
        rh_inc_pending(&ms->rh, &nosync);
-       rh_flush(&ms->rh);
+       ms->log_failure = rh_flush(&ms->rh) ? 1 : 0;
 
        /*
         * Dispatch io.
         */
-       while ((bio = bio_list_pop(&sync)))
+       if (unlikely(ms->log_failure))
+               while ((bio = bio_list_pop(&sync)))
+                       bio_endio(bio, bio->bi_size, -EIO);
+       else while ((bio = bio_list_pop(&sync)))
                do_write(ms, bio);
 
        while ((bio = bio_list_pop(&recover)))
@@ -1145,6 +1178,15 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv)
        argv += args_used;
        argc -= args_used;
 
+       /*
+        * Any read-balancing addition depends on the
+        * DM_RAID1_HANDLE_ERRORS flag being present.
+        * This is because the decision to balance depends
+        * on the sync state of a region.  If the above
+        * flag is not present, we ignore errors; and
+        * the sync state may be inaccurate.
+        */
+
        if (argc) {
                ti->error = "Too many mirror arguments";
                free_context(ms, ti, ms->nr_mirrors);
@@ -1288,12 +1330,12 @@ static int mirror_status(struct dm_target *ti, status_type_t type,
                for (m = 0; m < ms->nr_mirrors; m++)
                        DMEMIT("%s ", ms->mirror[m].dev->name);
 
-               DMEMIT("%llu/%llu",
+               DMEMIT("%llu/%llu 0 ",
                        (unsigned long long)ms->rh.log->type->
                                get_sync_count(ms->rh.log),
                        (unsigned long long)ms->nr_regions);
 
-               sz = ms->rh.log->type->status(ms->rh.log, type, result, maxlen);
+               sz += ms->rh.log->type->status(ms->rh.log, type, result+sz, maxlen-sz);
 
                break;
 
@@ -1335,8 +1377,7 @@ static int __init dm_mirror_init(void)
 
        r = dm_register_target(&mirror_target);
        if (r < 0) {
-               DMERR("%s: Failed to register mirror target",
-                     mirror_target.name);
+               DMERR("Failed to register mirror target");
                dm_dirty_log_exit();
        }
 
@@ -1349,7 +1390,7 @@ static void __exit dm_mirror_exit(void)
 
        r = dm_unregister_target(&mirror_target);
        if (r < 0)
-               DMERR("%s: unregister failed %d", mirror_target.name, r);
+               DMERR("unregister failed %d", r);
 
        dm_dirty_log_exit();
 }
index a348a97b65af3f243e2a8b11433e612df2d0856b..391dfa2ad4347a690d8bc4636515ebfff39a5f08 100644 (file)
@@ -205,7 +205,7 @@ static void __exit dm_rr_exit(void)
        int r = dm_unregister_path_selector(&rr_ps);
 
        if (r < 0)
-               DMERR("round-robin: unregister failed %d", r);
+               DMERR("unregister failed %d", r);
 }
 
 module_init(dm_rr_init);
index 0821a2b68a73a98719cb931c82196a74bfe471d4..83ddbfe6b8a415ca492c2db7b4701c1492a2a623 100644 (file)
@@ -42,8 +42,8 @@
 static struct workqueue_struct *ksnapd;
 static void flush_queued_bios(struct work_struct *work);
 
-struct pending_exception {
-       struct exception e;
+struct dm_snap_pending_exception {
+       struct dm_snap_exception e;
 
        /*
         * Origin buffers waiting for this to complete are held
@@ -63,7 +63,7 @@ struct pending_exception {
         * group of pending_exceptions.  It is always last to get freed.
         * These fields get set up when writing to the origin.
         */
-       struct pending_exception *primary_pe;
+       struct dm_snap_pending_exception *primary_pe;
 
        /*
         * Number of pending_exceptions processing this chunk.
@@ -137,7 +137,7 @@ static void exit_origin_hash(void)
        kfree(_origins);
 }
 
-static inline unsigned int origin_hash(struct block_device *bdev)
+static unsigned origin_hash(struct block_device *bdev)
 {
        return bdev->bd_dev & ORIGIN_MASK;
 }
@@ -231,7 +231,7 @@ static int init_exception_table(struct exception_table *et, uint32_t size)
 static void exit_exception_table(struct exception_table *et, struct kmem_cache *mem)
 {
        struct list_head *slot;
-       struct exception *ex, *next;
+       struct dm_snap_exception *ex, *next;
        int i, size;
 
        size = et->hash_mask + 1;
@@ -245,18 +245,19 @@ static void exit_exception_table(struct exception_table *et, struct kmem_cache *
        vfree(et->table);
 }
 
-static inline uint32_t exception_hash(struct exception_table *et, chunk_t chunk)
+static uint32_t exception_hash(struct exception_table *et, chunk_t chunk)
 {
        return chunk & et->hash_mask;
 }
 
-static void insert_exception(struct exception_table *eh, struct exception *e)
+static void insert_exception(struct exception_table *eh,
+                            struct dm_snap_exception *e)
 {
        struct list_head *l = &eh->table[exception_hash(eh, e->old_chunk)];
        list_add(&e->hash_list, l);
 }
 
-static inline void remove_exception(struct exception *e)
+static void remove_exception(struct dm_snap_exception *e)
 {
        list_del(&e->hash_list);
 }
@@ -265,11 +266,11 @@ static inline void remove_exception(struct exception *e)
  * Return the exception data for a sector, or NULL if not
  * remapped.
  */
-static struct exception *lookup_exception(struct exception_table *et,
-                                         chunk_t chunk)
+static struct dm_snap_exception *lookup_exception(struct exception_table *et,
+                                                 chunk_t chunk)
 {
        struct list_head *slot;
-       struct exception *e;
+       struct dm_snap_exception *e;
 
        slot = &et->table[exception_hash(et, chunk)];
        list_for_each_entry (e, slot, hash_list)
@@ -279,9 +280,9 @@ static struct exception *lookup_exception(struct exception_table *et,
        return NULL;
 }
 
-static inline struct exception *alloc_exception(void)
+static struct dm_snap_exception *alloc_exception(void)
 {
-       struct exception *e;
+       struct dm_snap_exception *e;
 
        e = kmem_cache_alloc(exception_cache, GFP_NOIO);
        if (!e)
@@ -290,24 +291,24 @@ static inline struct exception *alloc_exception(void)
        return e;
 }
 
-static inline void free_exception(struct exception *e)
+static void free_exception(struct dm_snap_exception *e)
 {
        kmem_cache_free(exception_cache, e);
 }
 
-static inline struct pending_exception *alloc_pending_exception(void)
+static struct dm_snap_pending_exception *alloc_pending_exception(void)
 {
        return mempool_alloc(pending_pool, GFP_NOIO);
 }
 
-static inline void free_pending_exception(struct pending_exception *pe)
+static void free_pending_exception(struct dm_snap_pending_exception *pe)
 {
        mempool_free(pe, pending_pool);
 }
 
 int dm_add_exception(struct dm_snapshot *s, chunk_t old, chunk_t new)
 {
-       struct exception *e;
+       struct dm_snap_exception *e;
 
        e = alloc_exception();
        if (!e)
@@ -334,7 +335,7 @@ static int calc_max_buckets(void)
 /*
  * Rounds a number down to a power of 2.
  */
-static inline uint32_t round_down(uint32_t n)
+static uint32_t round_down(uint32_t n)
 {
        while (n & (n - 1))
                n &= (n - 1);
@@ -384,7 +385,7 @@ static int init_hash_tables(struct dm_snapshot *s)
  * Round a number up to the nearest 'size' boundary.  size must
  * be a power of 2.
  */
-static inline ulong round_up(ulong n, ulong size)
+static ulong round_up(ulong n, ulong size)
 {
        size--;
        return (n + size) & ~size;
@@ -522,9 +523,12 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 
        /* Metadata must only be loaded into one table at once */
        r = s->store.read_metadata(&s->store);
-       if (r) {
+       if (r < 0) {
                ti->error = "Failed to read snapshot metadata";
                goto bad6;
+       } else if (r > 0) {
+               s->valid = 0;
+               DMWARN("Snapshot is marked invalid.");
        }
 
        bio_list_init(&s->queued_bios);
@@ -577,7 +581,7 @@ static void __free_exceptions(struct dm_snapshot *s)
 
 static void snapshot_dtr(struct dm_target *ti)
 {
-       struct dm_snapshot *s = (struct dm_snapshot *) ti->private;
+       struct dm_snapshot *s = ti->private;
 
        flush_workqueue(ksnapd);
 
@@ -655,14 +659,14 @@ static void __invalidate_snapshot(struct dm_snapshot *s, int err)
        dm_table_event(s->table);
 }
 
-static void get_pending_exception(struct pending_exception *pe)
+static void get_pending_exception(struct dm_snap_pending_exception *pe)
 {
        atomic_inc(&pe->ref_count);
 }
 
-static struct bio *put_pending_exception(struct pending_exception *pe)
+static struct bio *put_pending_exception(struct dm_snap_pending_exception *pe)
 {
-       struct pending_exception *primary_pe;
+       struct dm_snap_pending_exception *primary_pe;
        struct bio *origin_bios = NULL;
 
        primary_pe = pe->primary_pe;
@@ -692,9 +696,9 @@ static struct bio *put_pending_exception(struct pending_exception *pe)
        return origin_bios;
 }
 
-static void pending_complete(struct pending_exception *pe, int success)
+static void pending_complete(struct dm_snap_pending_exception *pe, int success)
 {
-       struct exception *e;
+       struct dm_snap_exception *e;
        struct dm_snapshot *s = pe->snap;
        struct bio *origin_bios = NULL;
        struct bio *snapshot_bios = NULL;
@@ -748,7 +752,8 @@ static void pending_complete(struct pending_exception *pe, int success)
 
 static void commit_callback(void *context, int success)
 {
-       struct pending_exception *pe = (struct pending_exception *) context;
+       struct dm_snap_pending_exception *pe = context;
+
        pending_complete(pe, success);
 }
 
@@ -758,7 +763,7 @@ static void commit_callback(void *context, int success)
  */
 static void copy_callback(int read_err, unsigned int write_err, void *context)
 {
-       struct pending_exception *pe = (struct pending_exception *) context;
+       struct dm_snap_pending_exception *pe = context;
        struct dm_snapshot *s = pe->snap;
 
        if (read_err || write_err)
@@ -773,7 +778,7 @@ static void copy_callback(int read_err, unsigned int write_err, void *context)
 /*
  * Dispatches the copy operation to kcopyd.
  */
-static void start_copy(struct pending_exception *pe)
+static void start_copy(struct dm_snap_pending_exception *pe)
 {
        struct dm_snapshot *s = pe->snap;
        struct io_region src, dest;
@@ -803,11 +808,11 @@ static void start_copy(struct pending_exception *pe)
  * NOTE: a write lock must be held on snap->lock before calling
  * this.
  */
-static struct pending_exception *
+static struct dm_snap_pending_exception *
 __find_pending_exception(struct dm_snapshot *s, struct bio *bio)
 {
-       struct exception *e;
-       struct pending_exception *pe;
+       struct dm_snap_exception *e;
+       struct dm_snap_pending_exception *pe;
        chunk_t chunk = sector_to_chunk(s, bio->bi_sector);
 
        /*
@@ -816,7 +821,7 @@ __find_pending_exception(struct dm_snapshot *s, struct bio *bio)
        e = lookup_exception(&s->pending, chunk);
        if (e) {
                /* cast the exception to a pending exception */
-               pe = container_of(e, struct pending_exception, e);
+               pe = container_of(e, struct dm_snap_pending_exception, e);
                goto out;
        }
 
@@ -836,7 +841,7 @@ __find_pending_exception(struct dm_snapshot *s, struct bio *bio)
        e = lookup_exception(&s->pending, chunk);
        if (e) {
                free_pending_exception(pe);
-               pe = container_of(e, struct pending_exception, e);
+               pe = container_of(e, struct dm_snap_pending_exception, e);
                goto out;
        }
 
@@ -860,8 +865,8 @@ __find_pending_exception(struct dm_snapshot *s, struct bio *bio)
        return pe;
 }
 
-static inline void remap_exception(struct dm_snapshot *s, struct exception *e,
-                                  struct bio *bio)
+static void remap_exception(struct dm_snapshot *s, struct dm_snap_exception *e,
+                           struct bio *bio)
 {
        bio->bi_bdev = s->cow->bdev;
        bio->bi_sector = chunk_to_sector(s, e->new_chunk) +
@@ -871,11 +876,11 @@ static inline void remap_exception(struct dm_snapshot *s, struct exception *e,
 static int snapshot_map(struct dm_target *ti, struct bio *bio,
                        union map_info *map_context)
 {
-       struct exception *e;
-       struct dm_snapshot *s = (struct dm_snapshot *) ti->private;
+       struct dm_snap_exception *e;
+       struct dm_snapshot *s = ti->private;
        int r = DM_MAPIO_REMAPPED;
        chunk_t chunk;
-       struct pending_exception *pe = NULL;
+       struct dm_snap_pending_exception *pe = NULL;
 
        chunk = sector_to_chunk(s, bio->bi_sector);
 
@@ -884,9 +889,6 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio,
        if (!s->valid)
                return -EIO;
 
-       if (unlikely(bio_barrier(bio)))
-               return -EOPNOTSUPP;
-
        /* FIXME: should only take write lock if we need
         * to copy an exception */
        down_write(&s->lock);
@@ -945,7 +947,7 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio,
 
 static void snapshot_resume(struct dm_target *ti)
 {
-       struct dm_snapshot *s = (struct dm_snapshot *) ti->private;
+       struct dm_snapshot *s = ti->private;
 
        down_write(&s->lock);
        s->active = 1;
@@ -955,7 +957,7 @@ static void snapshot_resume(struct dm_target *ti)
 static int snapshot_status(struct dm_target *ti, status_type_t type,
                           char *result, unsigned int maxlen)
 {
-       struct dm_snapshot *snap = (struct dm_snapshot *) ti->private;
+       struct dm_snapshot *snap = ti->private;
 
        switch (type) {
        case STATUSTYPE_INFO:
@@ -999,8 +1001,8 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio)
 {
        int r = DM_MAPIO_REMAPPED, first = 0;
        struct dm_snapshot *snap;
-       struct exception *e;
-       struct pending_exception *pe, *next_pe, *primary_pe = NULL;
+       struct dm_snap_exception *e;
+       struct dm_snap_pending_exception *pe, *next_pe, *primary_pe = NULL;
        chunk_t chunk;
        LIST_HEAD(pe_queue);
 
@@ -1147,19 +1149,16 @@ static int origin_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 
 static void origin_dtr(struct dm_target *ti)
 {
-       struct dm_dev *dev = (struct dm_dev *) ti->private;
+       struct dm_dev *dev = ti->private;
        dm_put_device(ti, dev);
 }
 
 static int origin_map(struct dm_target *ti, struct bio *bio,
                      union map_info *map_context)
 {
-       struct dm_dev *dev = (struct dm_dev *) ti->private;
+       struct dm_dev *dev = ti->private;
        bio->bi_bdev = dev->bdev;
 
-       if (unlikely(bio_barrier(bio)))
-               return -EOPNOTSUPP;
-
        /* Only tell snapshots if this is a write */
        return (bio_rw(bio) == WRITE) ? do_origin(dev, bio) : DM_MAPIO_REMAPPED;
 }
@@ -1172,7 +1171,7 @@ static int origin_map(struct dm_target *ti, struct bio *bio,
  */
 static void origin_resume(struct dm_target *ti)
 {
-       struct dm_dev *dev = (struct dm_dev *) ti->private;
+       struct dm_dev *dev = ti->private;
        struct dm_snapshot *snap;
        struct origin *o;
        chunk_t chunk_size = 0;
@@ -1190,7 +1189,7 @@ static void origin_resume(struct dm_target *ti)
 static int origin_status(struct dm_target *ti, status_type_t type, char *result,
                         unsigned int maxlen)
 {
-       struct dm_dev *dev = (struct dm_dev *) ti->private;
+       struct dm_dev *dev = ti->private;
 
        switch (type) {
        case STATUSTYPE_INFO:
@@ -1249,21 +1248,14 @@ static int __init dm_snapshot_init(void)
                goto bad2;
        }
 
-       exception_cache = kmem_cache_create("dm-snapshot-ex",
-                                           sizeof(struct exception),
-                                           __alignof__(struct exception),
-                                           0, NULL, NULL);
+       exception_cache = KMEM_CACHE(dm_snap_exception, 0);
        if (!exception_cache) {
                DMERR("Couldn't create exception cache.");
                r = -ENOMEM;
                goto bad3;
        }
 
-       pending_cache =
-           kmem_cache_create("dm-snapshot-in",
-                             sizeof(struct pending_exception),
-                             __alignof__(struct pending_exception),
-                             0, NULL, NULL);
+       pending_cache = KMEM_CACHE(dm_snap_pending_exception, 0);
        if (!pending_cache) {
                DMERR("Couldn't create pending cache.");
                r = -ENOMEM;
index 15fa2ae6cdc2971f590a814578d06536b75b8484..650e0f1f51d8a6c312a001c8443cf3bc8064d481 100644 (file)
@@ -30,7 +30,7 @@ typedef sector_t chunk_t;
  * An exception is used where an old chunk of data has been
  * replaced by a new one.
  */
-struct exception {
+struct dm_snap_exception {
        struct list_head hash_list;
 
        chunk_t old_chunk;
@@ -58,13 +58,13 @@ struct exception_store {
         * Find somewhere to store the next exception.
         */
        int (*prepare_exception) (struct exception_store *store,
-                                 struct exception *e);
+                                 struct dm_snap_exception *e);
 
        /*
         * Update the metadata with this exception.
         */
        void (*commit_exception) (struct exception_store *store,
-                                 struct exception *e,
+                                 struct dm_snap_exception *e,
                                  void (*callback) (void *, int success),
                                  void *callback_context);
 
index 2717a355dc5bf6847243de88f78fd540da5e941b..f4f7d35561ab83753f03fe16a186514514916bf6 100644 (file)
@@ -45,7 +45,7 @@ struct dm_io {
  * One of these is allocated per target within a bio.  Hopefully
  * this will be simplified out one day.
  */
-struct target_io {
+struct dm_target_io {
        struct dm_io *io;
        struct dm_target *ti;
        union map_info info;
@@ -54,7 +54,7 @@ struct target_io {
 union map_info *dm_get_mapinfo(struct bio *bio)
 {
        if (bio && bio->bi_private)
-               return &((struct target_io *)bio->bi_private)->info;
+               return &((struct dm_target_io *)bio->bi_private)->info;
        return NULL;
 }
 
@@ -132,14 +132,12 @@ static int __init local_init(void)
        int r;
 
        /* allocate a slab for the dm_ios */
-       _io_cache = kmem_cache_create("dm_io",
-                                     sizeof(struct dm_io), 0, 0, NULL, NULL);
+       _io_cache = KMEM_CACHE(dm_io, 0);
        if (!_io_cache)
                return -ENOMEM;
 
        /* allocate a slab for the target ios */
-       _tio_cache = kmem_cache_create("dm_tio", sizeof(struct target_io),
-                                      0, 0, NULL, NULL);
+       _tio_cache = KMEM_CACHE(dm_target_io, 0);
        if (!_tio_cache) {
                kmem_cache_destroy(_io_cache);
                return -ENOMEM;
@@ -325,22 +323,22 @@ out:
        return r;
 }
 
-static inline struct dm_io *alloc_io(struct mapped_device *md)
+static struct dm_io *alloc_io(struct mapped_device *md)
 {
        return mempool_alloc(md->io_pool, GFP_NOIO);
 }
 
-static inline void free_io(struct mapped_device *md, struct dm_io *io)
+static void free_io(struct mapped_device *md, struct dm_io *io)
 {
        mempool_free(io, md->io_pool);
 }
 
-static inline struct target_io *alloc_tio(struct mapped_device *md)
+static struct dm_target_io *alloc_tio(struct mapped_device *md)
 {
        return mempool_alloc(md->tio_pool, GFP_NOIO);
 }
 
-static inline void free_tio(struct mapped_device *md, struct target_io *tio)
+static void free_tio(struct mapped_device *md, struct dm_target_io *tio)
 {
        mempool_free(tio, md->tio_pool);
 }
@@ -498,7 +496,7 @@ static void dec_pending(struct dm_io *io, int error)
 static int clone_endio(struct bio *bio, unsigned int done, int error)
 {
        int r = 0;
-       struct target_io *tio = bio->bi_private;
+       struct dm_target_io *tio = bio->bi_private;
        struct mapped_device *md = tio->io->md;
        dm_endio_fn endio = tio->ti->type->end_io;
 
@@ -558,7 +556,7 @@ static sector_t max_io_len(struct mapped_device *md,
 }
 
 static void __map_bio(struct dm_target *ti, struct bio *clone,
-                     struct target_io *tio)
+                     struct dm_target_io *tio)
 {
        int r;
        sector_t sector;
@@ -672,7 +670,7 @@ static void __clone_and_map(struct clone_info *ci)
        struct bio *clone, *bio = ci->bio;
        struct dm_target *ti = dm_table_find_target(ci->map, ci->sector);
        sector_t len = 0, max = max_io_len(ci->md, ci->sector, ti);
-       struct target_io *tio;
+       struct dm_target_io *tio;
 
        /*
         * Allocate a target io object.
@@ -802,6 +800,15 @@ static int dm_request(request_queue_t *q, struct bio *bio)
        int rw = bio_data_dir(bio);
        struct mapped_device *md = q->queuedata;
 
+       /*
+        * There is no use in forwarding any barrier request since we can't
+        * guarantee it is (or can be) handled by the targets correctly.
+        */
+       if (unlikely(bio_barrier(bio))) {
+               bio_endio(bio, bio->bi_size, -EOPNOTSUPP);
+               return 0;
+       }
+
        down_read(&md->io_lock);
 
        disk_stat_inc(dm_disk(md), ios[rw]);
index 2f796b1436b2a6f898fac79f05cf4bee036d04f0..462ee652a89015c94490d6500b3e8f879fd8de46 100644 (file)
 
 #define DM_NAME "device-mapper"
 
-#define DMERR(f, arg...) printk(KERN_ERR DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg)
-#define DMWARN(f, arg...) printk(KERN_WARNING DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg)
-#define DMINFO(f, arg...) printk(KERN_INFO DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg)
+#define DMERR(f, arg...) \
+       printk(KERN_ERR DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg)
+#define DMERR_LIMIT(f, arg...) \
+       do { \
+               if (printk_ratelimit()) \
+                       printk(KERN_ERR DM_NAME ": " DM_MSG_PREFIX ": " \
+                              f "\n", ## arg); \
+       } while (0)
+
+#define DMWARN(f, arg...) \
+       printk(KERN_WARNING DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg)
+#define DMWARN_LIMIT(f, arg...) \
+       do { \
+               if (printk_ratelimit()) \
+                       printk(KERN_WARNING DM_NAME ": " DM_MSG_PREFIX ": " \
+                              f "\n", ## arg); \
+       } while (0)
+
+#define DMINFO(f, arg...) \
+       printk(KERN_INFO DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg)
+#define DMINFO_LIMIT(f, arg...) \
+       do { \
+               if (printk_ratelimit()) \
+                       printk(KERN_INFO DM_NAME ": " DM_MSG_PREFIX ": " f \
+                              "\n", ## arg); \
+       } while (0)
+
 #ifdef CONFIG_DM_DEBUG
-#  define DMDEBUG(f, arg...) printk(KERN_DEBUG DM_NAME ": " DM_MSG_PREFIX " DEBUG: " f "\n", ## arg)
+#  define DMDEBUG(f, arg...) \
+       printk(KERN_DEBUG DM_NAME ": " DM_MSG_PREFIX " DEBUG: " f "\n", ## arg)
+#  define DMDEBUG_LIMIT(f, arg...) \
+       do { \
+               if (printk_ratelimit()) \
+                       printk(KERN_DEBUG DM_NAME ": " DM_MSG_PREFIX ": " f \
+                              "\n", ## arg); \
+       } while (0)
 #else
 #  define DMDEBUG(f, arg...) do {} while (0)
+#  define DMDEBUG_LIMIT(f, arg...) do {} while (0)
 #endif
 
 #define DMEMIT(x...) sz += ((sz >= maxlen) ? \
index dbc234e3c69f917fb58e7a2f7d26b89dea324b9f..7e052378c47ea6af6c42eec7f134934b6d49d1c0 100644 (file)
@@ -29,7 +29,7 @@
 static struct workqueue_struct *_kcopyd_wq;
 static struct work_struct _kcopyd_work;
 
-static inline void wake(void)
+static void wake(void)
 {
        queue_work(_kcopyd_wq, &_kcopyd_work);
 }
@@ -226,10 +226,7 @@ static LIST_HEAD(_pages_jobs);
 
 static int jobs_init(void)
 {
-       _job_cache = kmem_cache_create("kcopyd-jobs",
-                                      sizeof(struct kcopyd_job),
-                                      __alignof__(struct kcopyd_job),
-                                      0, NULL, NULL);
+       _job_cache = KMEM_CACHE(kcopyd_job, 0);
        if (!_job_cache)
                return -ENOMEM;
 
@@ -258,7 +255,7 @@ static void jobs_exit(void)
  * Functions to push and pop a job onto the head of a given job
  * list.
  */
-static inline struct kcopyd_job *pop(struct list_head *jobs)
+static struct kcopyd_job *pop(struct list_head *jobs)
 {
        struct kcopyd_job *job = NULL;
        unsigned long flags;
@@ -274,7 +271,7 @@ static inline struct kcopyd_job *pop(struct list_head *jobs)
        return job;
 }
 
-static inline void push(struct list_head *jobs, struct kcopyd_job *job)
+static void push(struct list_head *jobs, struct kcopyd_job *job)
 {
        unsigned long flags;
 
index fdf5d6e46eac1f5250d231c14a1fec1398462680..5e6f17df204b458e0c3b634d40498e79a6ece678 100644 (file)
@@ -94,7 +94,6 @@ struct gemtek_pci_card {
 
        u32 iobase;
        u32 length;
-       u8  chiprev;
        u16 model;
 
        u32 current_frequency;
@@ -415,7 +414,6 @@ static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci
                goto err_pci;
        }
 
-       pci_read_config_byte( pci_dev, PCI_REVISION_ID, &card->chiprev );
        pci_read_config_word( pci_dev, PCI_SUBSYSTEM_ID, &card->model );
 
        pci_set_drvdata( pci_dev, card );
@@ -436,7 +434,7 @@ static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci
        gemtek_pci_mute( card );
 
        printk( KERN_INFO "Gemtek PCI Radio (rev. %d) found at 0x%04x-0x%04x.\n",
-               card->chiprev, card->iobase, card->iobase + card->length - 1 );
+               pci_dev->revision, card->iobase, card->iobase + card->length - 1 );
 
        return 0;
 
index 664aba8b4d85231895954ac48df4447212796d48..7533fc2033195b97e2648a82225514e7663007b1 100644 (file)
@@ -1809,7 +1809,6 @@ static int __devinit meye_probe(struct pci_dev *pcidev,
 {
        int ret = -EBUSY;
        unsigned long mchip_adr;
-       u8 revision;
 
        if (meye.mchip_dev != NULL) {
                printk(KERN_ERR "meye: only one device allowed!\n");
@@ -1885,7 +1884,6 @@ static int __devinit meye_probe(struct pci_dev *pcidev,
                goto outreqirq;
        }
 
-       pci_read_config_byte(meye.mchip_dev, PCI_REVISION_ID, &revision);
        pci_write_config_byte(meye.mchip_dev, PCI_CACHE_LINE_SIZE, 8);
        pci_write_config_byte(meye.mchip_dev, PCI_LATENCY_TIMER, 64);
 
@@ -1939,7 +1937,7 @@ static int __devinit meye_probe(struct pci_dev *pcidev,
        printk(KERN_INFO "meye: Motion Eye Camera Driver v%s.\n",
               MEYE_DRIVER_VERSION);
        printk(KERN_INFO "meye: mchip KL5A72002 rev. %d, base %lx, irq %d\n",
-              revision, mchip_adr, meye.mchip_irq);
+              meye.mchip_dev->revision, mchip_adr, meye.mchip_irq);
 
        return 0;
 
index 616eee9c04f10c01d6799855d19d81b315cc5be5..bd601efa7bd188b77a3ced5e24a4f7684684a76a 100644 (file)
@@ -34,6 +34,11 @@ config PHANTOM
          If you choose to build module, its name will be phantom. If unsure,
          say N here.
 
+config EEPROM_93CX6
+       tristate "EEPROM 93CX6 support"
+       ---help---
+         This is a driver for the EEPROM chipsets 93c46 and 93c66.
+         The driver supports both read as well as write commands.
 
          If unsure, say N.
 
@@ -187,5 +192,4 @@ config THINKPAD_ACPI_BAY
 
          If you are not sure, say Y here.
 
-
 endmenu
index 8abbf2f07a65d4d0d3633ba87fd6e4c69807b540..b5ce0e3dba861ea037e78a939ecdc60ab758c8c6 100644 (file)
@@ -14,3 +14,4 @@ obj-$(CONFIG_PHANTOM)         += phantom.o
 obj-$(CONFIG_SGI_IOC4)         += ioc4.o
 obj-$(CONFIG_SONY_LAPTOP)      += sony-laptop.o
 obj-$(CONFIG_THINKPAD_ACPI)    += thinkpad_acpi.o
+obj-$(CONFIG_EEPROM_93CX6)     += eeprom_93cx6.o
index 4f9060a2a2f2fce960486d07132fa889179510aa..7798f590e5aab8c840b3f839d249926e67308343 100644 (file)
@@ -737,8 +737,7 @@ static void asus_hotk_notify(acpi_handle handle, u32 event, void *data)
        struct device_attribute dev_attr_##_name = {                    \
                .attr = {                                               \
                        .name = __stringify(_name),                     \
-                       .mode = 0,                                      \
-                       .owner = THIS_MODULE },                         \
+                       .mode = 0 },                                    \
                .show   = NULL,                                         \
                .store  = NULL,                                         \
        }
diff --git a/drivers/misc/eeprom_93cx6.c b/drivers/misc/eeprom_93cx6.c
new file mode 100644 (file)
index 0000000..ea55654
--- /dev/null
@@ -0,0 +1,241 @@
+/*
+       Copyright (C) 2004 - 2006 rt2x00 SourceForge Project
+       <http://rt2x00.serialmonkey.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.
+ */
+
+/*
+       Module: eeprom_93cx6
+       Abstract: EEPROM reader routines for 93cx6 chipsets.
+       Supported chipsets: 93c46 & 93c66.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/delay.h>
+#include <linux/eeprom_93cx6.h>
+
+MODULE_AUTHOR("http://rt2x00.serialmonkey.com");
+MODULE_VERSION("1.0");
+MODULE_DESCRIPTION("EEPROM 93cx6 chip driver");
+MODULE_LICENSE("GPL");
+
+static inline void eeprom_93cx6_pulse_high(struct eeprom_93cx6 *eeprom)
+{
+       eeprom->reg_data_clock = 1;
+       eeprom->register_write(eeprom);
+
+       /*
+        * Add a short delay for the pulse to work.
+        * According to the specifications the "maximum minimum"
+        * time should be 450ns.
+        */
+       ndelay(450);
+}
+
+static inline void eeprom_93cx6_pulse_low(struct eeprom_93cx6 *eeprom)
+{
+       eeprom->reg_data_clock = 0;
+       eeprom->register_write(eeprom);
+
+       /*
+        * Add a short delay for the pulse to work.
+        * According to the specifications the "maximum minimum"
+        * time should be 450ns.
+        */
+       ndelay(450);
+}
+
+static void eeprom_93cx6_startup(struct eeprom_93cx6 *eeprom)
+{
+       /*
+        * Clear all flags, and enable chip select.
+        */
+       eeprom->register_read(eeprom);
+       eeprom->reg_data_in = 0;
+       eeprom->reg_data_out = 0;
+       eeprom->reg_data_clock = 0;
+       eeprom->reg_chip_select = 1;
+       eeprom->register_write(eeprom);
+
+       /*
+        * kick a pulse.
+        */
+       eeprom_93cx6_pulse_high(eeprom);
+       eeprom_93cx6_pulse_low(eeprom);
+}
+
+static void eeprom_93cx6_cleanup(struct eeprom_93cx6 *eeprom)
+{
+       /*
+        * Clear chip_select and data_in flags.
+        */
+       eeprom->register_read(eeprom);
+       eeprom->reg_data_in = 0;
+       eeprom->reg_chip_select = 0;
+       eeprom->register_write(eeprom);
+
+       /*
+        * kick a pulse.
+        */
+       eeprom_93cx6_pulse_high(eeprom);
+       eeprom_93cx6_pulse_low(eeprom);
+}
+
+static void eeprom_93cx6_write_bits(struct eeprom_93cx6 *eeprom,
+       const u16 data, const u16 count)
+{
+       unsigned int i;
+
+       eeprom->register_read(eeprom);
+
+       /*
+        * Clear data flags.
+        */
+       eeprom->reg_data_in = 0;
+       eeprom->reg_data_out = 0;
+
+       /*
+        * Start writing all bits.
+        */
+       for (i = count; i > 0; i--) {
+               /*
+                * Check if this bit needs to be set.
+                */
+               eeprom->reg_data_in = !!(data & (1 << (i - 1)));
+
+               /*
+                * Write the bit to the eeprom register.
+                */
+               eeprom->register_write(eeprom);
+
+               /*
+                * Kick a pulse.
+                */
+               eeprom_93cx6_pulse_high(eeprom);
+               eeprom_93cx6_pulse_low(eeprom);
+       }
+
+       eeprom->reg_data_in = 0;
+       eeprom->register_write(eeprom);
+}
+
+static void eeprom_93cx6_read_bits(struct eeprom_93cx6 *eeprom,
+       u16 *data, const u16 count)
+{
+       unsigned int i;
+       u16 buf = 0;
+
+       eeprom->register_read(eeprom);
+
+       /*
+        * Clear data flags.
+        */
+       eeprom->reg_data_in = 0;
+       eeprom->reg_data_out = 0;
+
+       /*
+        * Start reading all bits.
+        */
+       for (i = count; i > 0; i--) {
+               eeprom_93cx6_pulse_high(eeprom);
+
+               eeprom->register_read(eeprom);
+
+               /*
+                * Clear data_in flag.
+                */
+               eeprom->reg_data_in = 0;
+
+               /*
+                * Read if the bit has been set.
+                */
+               if (eeprom->reg_data_out)
+                       buf |= (1 << (i - 1));
+
+               eeprom_93cx6_pulse_low(eeprom);
+       }
+
+       *data = buf;
+}
+
+/**
+ * eeprom_93cx6_read - Read multiple words from eeprom
+ * @eeprom: Pointer to eeprom structure
+ * @word: Word index from where we should start reading
+ * @data: target pointer where the information will have to be stored
+ *
+ * This function will read the eeprom data as host-endian word
+ * into the given data pointer.
+ */
+void eeprom_93cx6_read(struct eeprom_93cx6 *eeprom, const u8 word,
+       u16 *data)
+{
+       u16 command;
+
+       /*
+        * Initialize the eeprom register
+        */
+       eeprom_93cx6_startup(eeprom);
+
+       /*
+        * Select the read opcode and the word to be read.
+        */
+       command = (PCI_EEPROM_READ_OPCODE << eeprom->width) | word;
+       eeprom_93cx6_write_bits(eeprom, command,
+               PCI_EEPROM_WIDTH_OPCODE + eeprom->width);
+
+       /*
+        * Read the requested 16 bits.
+        */
+       eeprom_93cx6_read_bits(eeprom, data, 16);
+
+       /*
+        * Cleanup eeprom register.
+        */
+       eeprom_93cx6_cleanup(eeprom);
+}
+EXPORT_SYMBOL_GPL(eeprom_93cx6_read);
+
+/**
+ * eeprom_93cx6_multiread - Read multiple words from eeprom
+ * @eeprom: Pointer to eeprom structure
+ * @word: Word index from where we should start reading
+ * @data: target pointer where the information will have to be stored
+ * @words: Number of words that should be read.
+ *
+ * This function will read all requested words from the eeprom,
+ * this is done by calling eeprom_93cx6_read() multiple times.
+ * But with the additional change that while the eeprom_93cx6_read
+ * will return host ordered bytes, this method will return little
+ * endian words.
+ */
+void eeprom_93cx6_multiread(struct eeprom_93cx6 *eeprom, const u8 word,
+       __le16 *data, const u16 words)
+{
+       unsigned int i;
+       u16 tmp;
+
+       for (i = 0; i < words; i++) {
+               tmp = 0;
+               eeprom_93cx6_read(eeprom, word + i, &tmp);
+               data[i] = cpu_to_le16(tmp);
+       }
+}
+EXPORT_SYMBOL_GPL(eeprom_93cx6_multiread);
+
index 41e901f53e7c819699b909f2a3afcf7a3587e6b4..932a415197b3f636b5122f83c8472f4566fb1a75 100644 (file)
@@ -23,6 +23,8 @@
  * msi-laptop.c - MSI S270 laptop support. This laptop is sold under
  * various brands, including "Cytron/TCM/Medion/Tchibo MD96100".
  *
+ * Driver also supports S271, S420 models.
+ *
  * This driver exports a few files in /sys/devices/platform/msi-laptop-pf/:
  *
  *   lcd_level - Screen brightness: contains a single integer in the
@@ -281,25 +283,56 @@ static struct platform_device *msipf_device;
 
 /* Initialization */
 
+static int dmi_check_cb(struct dmi_system_id *id)
+{
+        printk("msi-laptop: Identified laptop model '%s'.\n", id->ident);
+        return 0;
+}
+
 static struct dmi_system_id __initdata msi_dmi_table[] = {
        {
                .ident = "MSI S270",
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD"),
                        DMI_MATCH(DMI_PRODUCT_NAME, "MS-1013"),
-               }
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "0131"),
+                       DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR INT'L CO.,LTD")
+               },
+               .callback = dmi_check_cb
+       },
+       {
+               .ident = "MSI S271",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "MS-1058"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "0581"),
+                       DMI_MATCH(DMI_BOARD_NAME, "MS-1058")
+               },
+               .callback = dmi_check_cb
+       },
+       {
+               .ident = "MSI S420",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "MS-1412"),
+                       DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
+                       DMI_MATCH(DMI_BOARD_NAME, "MS-1412")
+               },
+               .callback = dmi_check_cb
        },
        {
                .ident = "Medion MD96100",
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "NOTEBOOK"),
                        DMI_MATCH(DMI_PRODUCT_NAME, "SAM2000"),
-               }
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "0131"),
+                       DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR INT'L CO.,LTD")
+               },
+               .callback = dmi_check_cb
        },
        { }
 };
 
-
 static int __init msi_init(void)
 {
        int ret;
@@ -394,3 +427,8 @@ MODULE_AUTHOR("Lennart Poettering");
 MODULE_DESCRIPTION("MSI Laptop Support");
 MODULE_VERSION(MSI_DRIVER_VERSION);
 MODULE_LICENSE("GPL");
+
+MODULE_ALIAS("dmi:*:svnMICRO-STARINT'LCO.,LTD:pnMS-1013:pvr0131*:cvnMICRO-STARINT'LCO.,LTD:ct10:*");
+MODULE_ALIAS("dmi:*:svnMicro-StarInternational:pnMS-1058:pvr0581:rvnMSI:rnMS-1058:*:ct10:*");
+MODULE_ALIAS("dmi:*:svnMicro-StarInternational:pnMS-1412:*:rvnMSI:rnMS-1412:*:cvnMICRO-STARINT'LCO.,LTD:ct10:*");
+MODULE_ALIAS("dmi:*:svnNOTEBOOK:pnSAM2000:pvr0131*:cvnMICRO-STARINT'LCO.,LTD:ct10:*");
index 9320a8c73239ceff909e30a045bb06aec60bd5ee..a49cb9737cd858c8f36679249b29f86b565426f2 100644 (file)
@@ -14,3 +14,21 @@ config MMC_BLOCK
          mount the filesystem. Almost everyone wishing MMC support
          should say Y or M here.
 
+config MMC_BLOCK_BOUNCE
+       bool "Use bounce buffer for simple hosts"
+       depends on MMC_BLOCK
+       default y
+       help
+         SD/MMC is a high latency protocol where it is crucial to
+         send large requests in order to get high performance. Many
+         controllers, however, are restricted to continuous memory
+         (i.e. they can't do scatter-gather), something the kernel
+         rarely can provide.
+
+         Say Y here to help these restricted hosts by bouncing
+         requests back and forth from a large buffer. You will get
+         a big performance gain at the cost of up to 64 KiB of
+         physical memory.
+
+         If unsure, say Y here.
+
index 540ff4bea54c6f8eb3366b6066393dec6567ae8e..cbd4b6e3e17c6a30cb91fc24aff63fe12dd14384 100644 (file)
@@ -262,7 +262,9 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
                }
 
                brq.data.sg = mq->sg;
-               brq.data.sg_len = blk_rq_map_sg(req->q, req, brq.data.sg);
+               brq.data.sg_len = mmc_queue_map_sg(mq);
+
+               mmc_queue_bounce_pre(mq);
 
                if (brq.data.blocks !=
                    (req->nr_sectors >> (md->block_bits - 9))) {
@@ -279,6 +281,9 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
                }
 
                mmc_wait_for_req(card->host, &brq.mrq);
+
+               mmc_queue_bounce_post(mq);
+
                if (brq.cmd.error) {
                        printk(KERN_ERR "%s: error %d sending read/write command\n",
                               req->rq_disk->disk_name, brq.cmd.error);
index dd97bc798409eb0bdec4d5a413c217c173a642e4..4fb2089dc6900cb1399496defcf8184b106cdbd0 100644 (file)
@@ -17,6 +17,8 @@
 #include <linux/mmc/host.h>
 #include "queue.h"
 
+#define MMC_QUEUE_BOUNCESZ     65536
+
 #define MMC_QUEUE_SUSPENDED    (1 << 0)
 
 /*
@@ -118,6 +120,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
        struct mmc_host *host = card->host;
        u64 limit = BLK_BOUNCE_HIGH;
        int ret;
+       unsigned int bouncesz;
 
        if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask)
                limit = *mmc_dev(host)->dma_mask;
@@ -127,21 +130,61 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
        if (!mq->queue)
                return -ENOMEM;
 
-       blk_queue_prep_rq(mq->queue, mmc_prep_request);
-       blk_queue_bounce_limit(mq->queue, limit);
-       blk_queue_max_sectors(mq->queue, host->max_req_size / 512);
-       blk_queue_max_phys_segments(mq->queue, host->max_phys_segs);
-       blk_queue_max_hw_segments(mq->queue, host->max_hw_segs);
-       blk_queue_max_segment_size(mq->queue, host->max_seg_size);
-
        mq->queue->queuedata = mq;
        mq->req = NULL;
 
-       mq->sg = kmalloc(sizeof(struct scatterlist) * host->max_phys_segs,
-                        GFP_KERNEL);
-       if (!mq->sg) {
-               ret = -ENOMEM;
-               goto cleanup_queue;
+       blk_queue_prep_rq(mq->queue, mmc_prep_request);
+
+#ifdef CONFIG_MMC_BLOCK_BOUNCE
+       if (host->max_hw_segs == 1) {
+               bouncesz = MMC_QUEUE_BOUNCESZ;
+
+               if (bouncesz > host->max_req_size)
+                       bouncesz = host->max_req_size;
+               if (bouncesz > host->max_seg_size)
+                       bouncesz = host->max_seg_size;
+
+               mq->bounce_buf = kmalloc(bouncesz, GFP_KERNEL);
+               if (!mq->bounce_buf) {
+                       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_max_sectors(mq->queue, bouncesz / 512);
+                       blk_queue_max_phys_segments(mq->queue, bouncesz / 512);
+                       blk_queue_max_hw_segments(mq->queue, bouncesz / 512);
+                       blk_queue_max_segment_size(mq->queue, bouncesz);
+
+                       mq->sg = kmalloc(sizeof(struct scatterlist),
+                               GFP_KERNEL);
+                       if (!mq->sg) {
+                               ret = -ENOMEM;
+                               goto free_bounce_buf;
+                       }
+
+                       mq->bounce_sg = kmalloc(sizeof(struct scatterlist) *
+                               bouncesz / 512, GFP_KERNEL);
+                       if (!mq->bounce_sg) {
+                               ret = -ENOMEM;
+                               goto free_sg;
+                       }
+               }
+       }
+#endif
+
+       if (!mq->bounce_buf) {
+               blk_queue_bounce_limit(mq->queue, limit);
+               blk_queue_max_sectors(mq->queue, host->max_req_size / 512);
+               blk_queue_max_phys_segments(mq->queue, host->max_phys_segs);
+               blk_queue_max_hw_segments(mq->queue, host->max_hw_segs);
+               blk_queue_max_segment_size(mq->queue, host->max_seg_size);
+
+               mq->sg = kmalloc(sizeof(struct scatterlist) *
+                       host->max_phys_segs, GFP_KERNEL);
+               if (!mq->sg) {
+                       ret = -ENOMEM;
+                       goto cleanup_queue;
+               }
        }
 
        init_MUTEX(&mq->thread_sem);
@@ -149,14 +192,21 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
        mq->thread = kthread_run(mmc_queue_thread, mq, "mmcqd");
        if (IS_ERR(mq->thread)) {
                ret = PTR_ERR(mq->thread);
-               goto free_sg;
+               goto free_bounce_sg;
        }
 
        return 0;
-
+ free_bounce_sg:
+       if (mq->bounce_sg)
+               kfree(mq->bounce_sg);
+       mq->bounce_sg = NULL;
  free_sg:
        kfree(mq->sg);
        mq->sg = NULL;
+ free_bounce_buf:
+       if (mq->bounce_buf)
+               kfree(mq->bounce_buf);
+       mq->bounce_buf = NULL;
  cleanup_queue:
        blk_cleanup_queue(mq->queue);
        return ret;
@@ -178,9 +228,17 @@ void mmc_cleanup_queue(struct mmc_queue *mq)
        /* Then terminate our worker thread */
        kthread_stop(mq->thread);
 
+       if (mq->bounce_sg)
+               kfree(mq->bounce_sg);
+       mq->bounce_sg = NULL;
+
        kfree(mq->sg);
        mq->sg = NULL;
 
+       if (mq->bounce_buf)
+               kfree(mq->bounce_buf);
+       mq->bounce_buf = NULL;
+
        blk_cleanup_queue(mq->queue);
 
        mq->card = NULL;
@@ -231,3 +289,108 @@ 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 = page_address(dst->page) + dst->offset;
+                       dst_size = dst->length;
+               }
+
+               if (src_size == 0) {
+                       src_buf = page_address(src->page) + src->offset;
+                       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--;
+               }
+       }
+}
+
+unsigned int mmc_queue_map_sg(struct mmc_queue *mq)
+{
+       unsigned int sg_len;
+
+       if (!mq->bounce_buf)
+               return blk_rq_map_sg(mq->queue, mq->req, mq->sg);
+
+       BUG_ON(!mq->bounce_sg);
+
+       sg_len = blk_rq_map_sg(mq->queue, mq->req, mq->bounce_sg);
+
+       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;
+       }
+
+       mq->sg[0].page = virt_to_page(mq->bounce_buf);
+       mq->sg[0].offset = offset_in_page(mq->bounce_buf);
+       mq->sg[0].length = 0;
+
+       while (sg_len) {
+               mq->sg[0].length += mq->bounce_sg[sg_len - 1].length;
+               sg_len--;
+       }
+
+       return 1;
+}
+
+void mmc_queue_bounce_pre(struct mmc_queue *mq)
+{
+       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);
+}
+
+void mmc_queue_bounce_post(struct mmc_queue *mq)
+{
+       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);
+}
+
index 1590b3f3f1f7d8d54fbdf1eb1a27c6f25893205e..64e66e0d4994a9176662354cd123fb0cee2315a0 100644 (file)
@@ -14,6 +14,9 @@ struct mmc_queue {
        void                    *data;
        struct request_queue    *queue;
        struct scatterlist      *sg;
+       char                    *bounce_buf;
+       struct scatterlist      *bounce_sg;
+       unsigned int            bounce_sg_len;
 };
 
 extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *);
@@ -21,4 +24,8 @@ extern void mmc_cleanup_queue(struct mmc_queue *);
 extern void mmc_queue_suspend(struct mmc_queue *);
 extern void mmc_queue_resume(struct mmc_queue *);
 
+extern unsigned int mmc_queue_map_sg(struct mmc_queue *);
+extern void mmc_queue_bounce_pre(struct mmc_queue *);
+extern void mmc_queue_bounce_post(struct mmc_queue *);
+
 #endif
index 1075b02ae754ef6f7c357a294e2f7b004cfce062..3fdd08c7f143c8f874db806a948e54790f299efc 100644 (file)
@@ -7,5 +7,6 @@ ifeq ($(CONFIG_MMC_DEBUG),y)
 endif
 
 obj-$(CONFIG_MMC)              += mmc_core.o
-mmc_core-y                     := core.o sysfs.o mmc.o mmc_ops.o sd.o sd_ops.o
+mmc_core-y                     := core.o sysfs.o bus.o host.o \
+                                  mmc.o mmc_ops.o sd.o sd_ops.o
 
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
new file mode 100644 (file)
index 0000000..348b566
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+ *  linux/drivers/mmc/core/bus.c
+ *
+ *  Copyright (C) 2003 Russell King, All Rights Reserved.
+ *  Copyright (C) 2007 Pierre Ossman
+ *
+ * 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.
+ *
+ *  MMC card bus driver model
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+
+#include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
+
+#include "sysfs.h"
+#include "core.h"
+#include "bus.h"
+
+#define dev_to_mmc_card(d)     container_of(d, struct mmc_card, dev)
+#define to_mmc_driver(d)       container_of(d, struct mmc_driver, drv)
+
+static ssize_t mmc_type_show(struct device *dev,
+       struct device_attribute *attr, char *buf)
+{
+       struct mmc_card *card = dev_to_mmc_card(dev);
+
+       switch (card->type) {
+       case MMC_TYPE_MMC:
+               return sprintf(buf, "MMC\n");
+       case MMC_TYPE_SD:
+               return sprintf(buf, "SD\n");
+       default:
+               return -EFAULT;
+       }
+}
+
+static struct device_attribute mmc_dev_attrs[] = {
+       MMC_ATTR_RO(type),
+       __ATTR_NULL,
+};
+
+/*
+ * This currently matches any MMC driver to any MMC card - drivers
+ * themselves make the decision whether to drive this card in their
+ * probe method.
+ */
+static int mmc_bus_match(struct device *dev, struct device_driver *drv)
+{
+       return 1;
+}
+
+static int
+mmc_bus_uevent(struct device *dev, char **envp, int num_envp, char *buf,
+               int buf_size)
+{
+       struct mmc_card *card = dev_to_mmc_card(dev);
+       int retval = 0, i = 0, length = 0;
+
+#define add_env(fmt,val) do {                                  \
+       retval = add_uevent_var(envp, num_envp, &i,             \
+                               buf, buf_size, &length,         \
+                               fmt, val);                      \
+       if (retval)                                             \
+               return retval;                                  \
+} while (0);
+
+       switch (card->type) {
+       case MMC_TYPE_MMC:
+               add_env("MMC_TYPE=%s", "MMC");
+               break;
+       case MMC_TYPE_SD:
+               add_env("MMC_TYPE=%s", "SD");
+               break;
+       }
+
+       add_env("MMC_NAME=%s", mmc_card_name(card));
+
+#undef add_env
+
+       envp[i] = NULL;
+
+       return 0;
+}
+
+static int mmc_bus_probe(struct device *dev)
+{
+       struct mmc_driver *drv = to_mmc_driver(dev->driver);
+       struct mmc_card *card = dev_to_mmc_card(dev);
+
+       return drv->probe(card);
+}
+
+static int mmc_bus_remove(struct device *dev)
+{
+       struct mmc_driver *drv = to_mmc_driver(dev->driver);
+       struct mmc_card *card = dev_to_mmc_card(dev);
+
+       drv->remove(card);
+
+       return 0;
+}
+
+static int mmc_bus_suspend(struct device *dev, pm_message_t state)
+{
+       struct mmc_driver *drv = to_mmc_driver(dev->driver);
+       struct mmc_card *card = dev_to_mmc_card(dev);
+       int ret = 0;
+
+       if (dev->driver && drv->suspend)
+               ret = drv->suspend(card, state);
+       return ret;
+}
+
+static int mmc_bus_resume(struct device *dev)
+{
+       struct mmc_driver *drv = to_mmc_driver(dev->driver);
+       struct mmc_card *card = dev_to_mmc_card(dev);
+       int ret = 0;
+
+       if (dev->driver && drv->resume)
+               ret = drv->resume(card);
+       return ret;
+}
+
+static struct bus_type mmc_bus_type = {
+       .name           = "mmc",
+       .dev_attrs      = mmc_dev_attrs,
+       .match          = mmc_bus_match,
+       .uevent         = mmc_bus_uevent,
+       .probe          = mmc_bus_probe,
+       .remove         = mmc_bus_remove,
+       .suspend        = mmc_bus_suspend,
+       .resume         = mmc_bus_resume,
+};
+
+int mmc_register_bus(void)
+{
+       return bus_register(&mmc_bus_type);
+}
+
+void mmc_unregister_bus(void)
+{
+       bus_unregister(&mmc_bus_type);
+}
+
+/**
+ *     mmc_register_driver - register a media driver
+ *     @drv: MMC media driver
+ */
+int mmc_register_driver(struct mmc_driver *drv)
+{
+       drv->drv.bus = &mmc_bus_type;
+       return driver_register(&drv->drv);
+}
+
+EXPORT_SYMBOL(mmc_register_driver);
+
+/**
+ *     mmc_unregister_driver - unregister a media driver
+ *     @drv: MMC media driver
+ */
+void mmc_unregister_driver(struct mmc_driver *drv)
+{
+       drv->drv.bus = &mmc_bus_type;
+       driver_unregister(&drv->drv);
+}
+
+EXPORT_SYMBOL(mmc_unregister_driver);
+
+static void mmc_release_card(struct device *dev)
+{
+       struct mmc_card *card = dev_to_mmc_card(dev);
+
+       kfree(card);
+}
+
+/*
+ * Allocate and initialise a new MMC card structure.
+ */
+struct mmc_card *mmc_alloc_card(struct mmc_host *host)
+{
+       struct mmc_card *card;
+
+       card = kmalloc(sizeof(struct mmc_card), GFP_KERNEL);
+       if (!card)
+               return ERR_PTR(-ENOMEM);
+
+       memset(card, 0, sizeof(struct mmc_card));
+
+       card->host = host;
+
+       device_initialize(&card->dev);
+
+       card->dev.parent = mmc_classdev(host);
+       card->dev.bus = &mmc_bus_type;
+       card->dev.release = mmc_release_card;
+
+       return card;
+}
+
+/*
+ * Register a new MMC card with the driver model.
+ */
+int mmc_add_card(struct mmc_card *card)
+{
+       int ret;
+
+       snprintf(card->dev.bus_id, sizeof(card->dev.bus_id),
+                "%s:%04x", mmc_hostname(card->host), card->rca);
+
+       card->dev.uevent_suppress = 1;
+
+       ret = device_add(&card->dev);
+       if (ret)
+               return ret;
+
+       if (card->host->bus_ops->sysfs_add) {
+               ret = card->host->bus_ops->sysfs_add(card->host, card);
+               if (ret) {
+                       device_del(&card->dev);
+                       return ret;
+                }
+       }
+
+       card->dev.uevent_suppress = 0;
+
+       kobject_uevent(&card->dev.kobj, KOBJ_ADD);
+
+       mmc_card_set_present(card);
+
+       return 0;
+}
+
+/*
+ * Unregister a new MMC card with the driver model, and
+ * (eventually) free it.
+ */
+void mmc_remove_card(struct mmc_card *card)
+{
+       if (mmc_card_present(card)) {
+               if (card->host->bus_ops->sysfs_remove)
+                       card->host->bus_ops->sysfs_remove(card->host, card);
+               device_del(&card->dev);
+       }
+
+       put_device(&card->dev);
+}
+
diff --git a/drivers/mmc/core/bus.h b/drivers/mmc/core/bus.h
new file mode 100644 (file)
index 0000000..4f35431
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ *  linux/drivers/mmc/core/bus.h
+ *
+ *  Copyright (C) 2003 Russell King, All Rights Reserved.
+ *  Copyright 2007 Pierre Ossman
+ *
+ * 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 _MMC_CORE_BUS_H
+#define _MMC_CORE_BUS_H
+
+struct mmc_card *mmc_alloc_card(struct mmc_host *host);
+int mmc_add_card(struct mmc_card *card);
+void mmc_remove_card(struct mmc_card *card);
+
+int mmc_register_bus(void);
+void mmc_unregister_bus(void);
+
+#endif
+
index 7385acfa1dd939a29e77fc414f89be7b47bed576..b5d8a6d90cca6dfdac015f2e6cac031786963067 100644 (file)
@@ -27,7 +27,8 @@
 #include <linux/mmc/sd.h>
 
 #include "core.h"
-#include "sysfs.h"
+#include "bus.h"
+#include "host.h"
 
 #include "mmc_ops.h"
 #include "sd_ops.h"
 extern int mmc_attach_mmc(struct mmc_host *host, u32 ocr);
 extern int mmc_attach_sd(struct mmc_host *host, u32 ocr);
 
+static struct workqueue_struct *workqueue;
+
+/*
+ * Internal function. Schedule delayed work in the MMC work queue.
+ */
+static int mmc_schedule_delayed_work(struct delayed_work *work,
+                                    unsigned long delay)
+{
+       return queue_delayed_work(workqueue, work, delay);
+}
+
+/*
+ * Internal function. Flush all scheduled work from the MMC work queue.
+ */
+static void mmc_flush_scheduled_work(void)
+{
+       flush_workqueue(workqueue);
+}
+
 /**
  *     mmc_request_done - finish processing an MMC request
  *     @host: MMC host which completed request
@@ -368,22 +388,6 @@ void mmc_set_timing(struct mmc_host *host, unsigned int timing)
        mmc_set_ios(host);
 }
 
-/*
- * Allocate a new MMC card
- */
-struct mmc_card *mmc_alloc_card(struct mmc_host *host)
-{
-       struct mmc_card *card;
-
-       card = kmalloc(sizeof(struct mmc_card), GFP_KERNEL);
-       if (!card)
-               return ERR_PTR(-ENOMEM);
-
-       mmc_init_card(card, host);
-
-       return card;
-}
-
 /*
  * Apply power to the MMC stack.  This is a two-stage process.
  * First, we enable power to the card without the clock running.
@@ -512,7 +516,7 @@ void mmc_detect_change(struct mmc_host *host, unsigned long delay)
 EXPORT_SYMBOL(mmc_detect_change);
 
 
-static void mmc_rescan(struct work_struct *work)
+void mmc_rescan(struct work_struct *work)
 {
        struct mmc_host *host =
                container_of(work, struct mmc_host, detect.work);
@@ -561,69 +565,13 @@ static void mmc_rescan(struct work_struct *work)
        }
 }
 
-
-/**
- *     mmc_alloc_host - initialise the per-host structure.
- *     @extra: sizeof private data structure
- *     @dev: pointer to host device model structure
- *
- *     Initialise the per-host structure.
- */
-struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
+void mmc_start_host(struct mmc_host *host)
 {
-       struct mmc_host *host;
-
-       host = mmc_alloc_host_sysfs(extra, dev);
-       if (host) {
-               spin_lock_init(&host->lock);
-               init_waitqueue_head(&host->wq);
-               INIT_DELAYED_WORK(&host->detect, mmc_rescan);
-
-               /*
-                * By default, hosts do not support SGIO or large requests.
-                * They have to set these according to their abilities.
-                */
-               host->max_hw_segs = 1;
-               host->max_phys_segs = 1;
-               host->max_seg_size = PAGE_CACHE_SIZE;
-
-               host->max_req_size = PAGE_CACHE_SIZE;
-               host->max_blk_size = 512;
-               host->max_blk_count = PAGE_CACHE_SIZE / 512;
-       }
-
-       return host;
-}
-
-EXPORT_SYMBOL(mmc_alloc_host);
-
-/**
- *     mmc_add_host - initialise host hardware
- *     @host: mmc host
- */
-int mmc_add_host(struct mmc_host *host)
-{
-       int ret;
-
-       ret = mmc_add_host_sysfs(host);
-       if (ret == 0) {
-               mmc_power_off(host);
-               mmc_detect_change(host, 0);
-       }
-
-       return ret;
+       mmc_power_off(host);
+       mmc_detect_change(host, 0);
 }
 
-EXPORT_SYMBOL(mmc_add_host);
-
-/**
- *     mmc_remove_host - remove host hardware
- *     @host: mmc host
- *
- *     Unregister and remove all cards associated with this host,
- *     and power down the MMC bus.
- */
-void mmc_remove_host(struct mmc_host *host)
+void mmc_stop_host(struct mmc_host *host)
 {
 #ifdef CONFIG_MMC_DEBUG
        unsigned long flags;
@@ -648,24 +596,8 @@ void mmc_remove_host(struct mmc_host *host)
        BUG_ON(host->card);
 
        mmc_power_off(host);
-       mmc_remove_host_sysfs(host);
 }
 
-EXPORT_SYMBOL(mmc_remove_host);
-
-/**
- *     mmc_free_host - free the host structure
- *     @host: mmc host
- *
- *     Free the host once all references to it have been dropped.
- */
-void mmc_free_host(struct mmc_host *host)
-{
-       mmc_free_host_sysfs(host);
-}
-
-EXPORT_SYMBOL(mmc_free_host);
-
 #ifdef CONFIG_PM
 
 /**
@@ -726,4 +658,31 @@ EXPORT_SYMBOL(mmc_resume_host);
 
 #endif
 
+static int __init mmc_init(void)
+{
+       int ret;
+
+       workqueue = create_singlethread_workqueue("kmmcd");
+       if (!workqueue)
+               return -ENOMEM;
+
+       ret = mmc_register_bus();
+       if (ret == 0) {
+               ret = mmc_register_host_class();
+               if (ret)
+                       mmc_unregister_bus();
+       }
+       return ret;
+}
+
+static void __exit mmc_exit(void)
+{
+       mmc_unregister_host_class();
+       mmc_unregister_bus();
+       destroy_workqueue(workqueue);
+}
+
+module_init(mmc_init);
+module_exit(mmc_exit);
+
 MODULE_LICENSE("GPL");
index 177264d090accaad5be378b4aa1258639e9d5c90..ae006b30dd86bdbb3fdeb3367fc66c83847e711d 100644 (file)
@@ -18,6 +18,8 @@
 struct mmc_bus_ops {
        void (*remove)(struct mmc_host *);
        void (*detect)(struct mmc_host *);
+       int (*sysfs_add)(struct mmc_host *, struct mmc_card *card);
+       void (*sysfs_remove)(struct mmc_host *, struct mmc_card *card);
        void (*suspend)(struct mmc_host *);
        void (*resume)(struct mmc_host *);
 };
@@ -54,8 +56,6 @@ void mmc_set_bus_width(struct mmc_host *host, unsigned int width);
 u32 mmc_select_voltage(struct mmc_host *host, u32 ocr);
 void mmc_set_timing(struct mmc_host *host, unsigned int timing);
 
-struct mmc_card *mmc_alloc_card(struct mmc_host *host);
-
 static inline void mmc_delay(unsigned int ms)
 {
        if (ms < 1000 / HZ) {
@@ -66,5 +66,9 @@ static inline void mmc_delay(unsigned int ms)
        }
 }
 
+void mmc_rescan(struct work_struct *work);
+void mmc_start_host(struct mmc_host *host);
+void mmc_stop_host(struct mmc_host *host);
+
 #endif
 
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
new file mode 100644 (file)
index 0000000..1433d95
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ *  linux/drivers/mmc/core/host.c
+ *
+ *  Copyright (C) 2003 Russell King, All Rights Reserved.
+ *  Copyright (C) 2007 Pierre Ossman
+ *
+ * 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.
+ *
+ *  MMC host class device management
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/idr.h>
+#include <linux/pagemap.h>
+
+#include <linux/mmc/host.h>
+
+#include "core.h"
+#include "host.h"
+
+#define cls_dev_to_mmc_host(d) container_of(d, struct mmc_host, class_dev)
+
+static void mmc_host_classdev_release(struct device *dev)
+{
+       struct mmc_host *host = cls_dev_to_mmc_host(dev);
+       kfree(host);
+}
+
+static struct class mmc_host_class = {
+       .name           = "mmc_host",
+       .dev_release    = mmc_host_classdev_release,
+};
+
+int mmc_register_host_class(void)
+{
+       return class_register(&mmc_host_class);
+}
+
+void mmc_unregister_host_class(void)
+{
+       class_unregister(&mmc_host_class);
+}
+
+static DEFINE_IDR(mmc_host_idr);
+static DEFINE_SPINLOCK(mmc_host_lock);
+
+/**
+ *     mmc_alloc_host - initialise the per-host structure.
+ *     @extra: sizeof private data structure
+ *     @dev: pointer to host device model structure
+ *
+ *     Initialise the per-host structure.
+ */
+struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
+{
+       struct mmc_host *host;
+
+       host = kmalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL);
+       if (!host)
+               return NULL;
+
+       memset(host, 0, sizeof(struct mmc_host) + extra);
+
+       host->parent = dev;
+       host->class_dev.parent = dev;
+       host->class_dev.class = &mmc_host_class;
+       device_initialize(&host->class_dev);
+
+       spin_lock_init(&host->lock);
+       init_waitqueue_head(&host->wq);
+       INIT_DELAYED_WORK(&host->detect, mmc_rescan);
+
+       /*
+        * By default, hosts do not support SGIO or large requests.
+        * They have to set these according to their abilities.
+        */
+       host->max_hw_segs = 1;
+       host->max_phys_segs = 1;
+       host->max_seg_size = PAGE_CACHE_SIZE;
+
+       host->max_req_size = PAGE_CACHE_SIZE;
+       host->max_blk_size = 512;
+       host->max_blk_count = PAGE_CACHE_SIZE / 512;
+
+       return host;
+}
+
+EXPORT_SYMBOL(mmc_alloc_host);
+
+/**
+ *     mmc_add_host - initialise host hardware
+ *     @host: mmc host
+ */
+int mmc_add_host(struct mmc_host *host)
+{
+       int err;
+
+       if (!idr_pre_get(&mmc_host_idr, GFP_KERNEL))
+               return -ENOMEM;
+
+       spin_lock(&mmc_host_lock);
+       err = idr_get_new(&mmc_host_idr, host, &host->index);
+       spin_unlock(&mmc_host_lock);
+       if (err)
+               return err;
+
+       snprintf(host->class_dev.bus_id, BUS_ID_SIZE,
+                "mmc%d", host->index);
+
+       err = device_add(&host->class_dev);
+       if (err)
+               return err;
+
+       mmc_start_host(host);
+
+       return 0;
+}
+
+EXPORT_SYMBOL(mmc_add_host);
+
+/**
+ *     mmc_remove_host - remove host hardware
+ *     @host: mmc host
+ *
+ *     Unregister and remove all cards associated with this host,
+ *     and power down the MMC bus.
+ */
+void mmc_remove_host(struct mmc_host *host)
+{
+       mmc_stop_host(host);
+
+       device_del(&host->class_dev);
+
+       spin_lock(&mmc_host_lock);
+       idr_remove(&mmc_host_idr, host->index);
+       spin_unlock(&mmc_host_lock);
+}
+
+EXPORT_SYMBOL(mmc_remove_host);
+
+/**
+ *     mmc_free_host - free the host structure
+ *     @host: mmc host
+ *
+ *     Free the host once all references to it have been dropped.
+ */
+void mmc_free_host(struct mmc_host *host)
+{
+       put_device(&host->class_dev);
+}
+
+EXPORT_SYMBOL(mmc_free_host);
+
diff --git a/drivers/mmc/core/host.h b/drivers/mmc/core/host.h
new file mode 100644 (file)
index 0000000..c2dc3d2
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ *  linux/drivers/mmc/core/host.h
+ *
+ *  Copyright (C) 2003 Russell King, All Rights Reserved.
+ *  Copyright 2007 Pierre Ossman
+ *
+ * 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 _MMC_CORE_HOST_H
+#define _MMC_CORE_HOST_H
+
+int mmc_register_host_class(void);
+void mmc_unregister_host_class(void);
+
+#endif
+
index 42cc2867ed7d51a2b0105c1697e19d032e00b538..66f85bfa8dbbfb9704df09c68245d3d137339275 100644 (file)
@@ -18,6 +18,7 @@
 
 #include "core.h"
 #include "sysfs.h"
+#include "bus.h"
 #include "mmc_ops.h"
 
 static const unsigned int tran_exp[] = {
@@ -236,7 +237,7 @@ out:
  * In the case of a resume, "curcard" will contain the card
  * we're trying to reinitialise.
  */
-static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
+static int mmc_init_card(struct mmc_host *host, u32 ocr,
        struct mmc_card *oldcard)
 {
        struct mmc_card *card;
@@ -413,8 +414,7 @@ static void mmc_detect(struct mmc_host *host)
        mmc_release_host(host);
 
        if (err != MMC_ERR_NONE) {
-               mmc_remove_card(host->card);
-               host->card = NULL;
+               mmc_remove(host);
 
                mmc_claim_host(host);
                mmc_detach_bus(host);
@@ -422,6 +422,53 @@ static void mmc_detect(struct mmc_host *host)
        }
 }
 
+MMC_ATTR_FN(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1],
+       card->raw_cid[2], card->raw_cid[3]);
+MMC_ATTR_FN(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1],
+       card->raw_csd[2], card->raw_csd[3]);
+MMC_ATTR_FN(date, "%02d/%04d\n", card->cid.month, card->cid.year);
+MMC_ATTR_FN(fwrev, "0x%x\n", card->cid.fwrev);
+MMC_ATTR_FN(hwrev, "0x%x\n", card->cid.hwrev);
+MMC_ATTR_FN(manfid, "0x%06x\n", card->cid.manfid);
+MMC_ATTR_FN(name, "%s\n", card->cid.prod_name);
+MMC_ATTR_FN(oemid, "0x%04x\n", card->cid.oemid);
+MMC_ATTR_FN(serial, "0x%08x\n", card->cid.serial);
+
+static struct device_attribute mmc_dev_attrs[] = {
+       MMC_ATTR_RO(cid),
+       MMC_ATTR_RO(csd),
+       MMC_ATTR_RO(date),
+       MMC_ATTR_RO(fwrev),
+       MMC_ATTR_RO(hwrev),
+       MMC_ATTR_RO(manfid),
+       MMC_ATTR_RO(name),
+       MMC_ATTR_RO(oemid),
+       MMC_ATTR_RO(serial),
+       __ATTR_NULL,
+};
+
+/*
+ * Adds sysfs entries as relevant.
+ */
+static int mmc_sysfs_add(struct mmc_host *host, struct mmc_card *card)
+{
+       int ret;
+
+       ret = mmc_add_attrs(card, mmc_dev_attrs);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+/*
+ * Removes the sysfs entries added by mmc_sysfs_add().
+ */
+static void mmc_sysfs_remove(struct mmc_host *host, struct mmc_card *card)
+{
+       mmc_remove_attrs(card, mmc_dev_attrs);
+}
+
 #ifdef CONFIG_MMC_UNSAFE_RESUME
 
 /*
@@ -453,11 +500,9 @@ static void mmc_resume(struct mmc_host *host)
 
        mmc_claim_host(host);
 
-       err = mmc_sd_init_card(host, host->ocr, host->card);
+       err = mmc_init_card(host, host->ocr, host->card);
        if (err != MMC_ERR_NONE) {
-               mmc_remove_card(host->card);
-               host->card = NULL;
-
+               mmc_remove(host);
                mmc_detach_bus(host);
        }
 
@@ -474,6 +519,8 @@ static void mmc_resume(struct mmc_host *host)
 static const struct mmc_bus_ops mmc_ops = {
        .remove = mmc_remove,
        .detect = mmc_detect,
+       .sysfs_add = mmc_sysfs_add,
+       .sysfs_remove = mmc_sysfs_remove,
        .suspend = mmc_suspend,
        .resume = mmc_resume,
 };
@@ -512,13 +559,13 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr)
        /*
         * Detect and init the card.
         */
-       err = mmc_sd_init_card(host, host->ocr, NULL);
+       err = mmc_init_card(host, host->ocr, NULL);
        if (err != MMC_ERR_NONE)
                goto err;
 
        mmc_release_host(host);
 
-       err = mmc_register_card(host->card);
+       err = mmc_add_card(host->card);
        if (err)
                goto reclaim_host;
 
index 918477c490b0207bbc5a81733d0289b7f3b8ff76..1240684083f1830c9e58c6f40ccad9c11ea10c71 100644 (file)
 
 #include "core.h"
 #include "sysfs.h"
+#include "bus.h"
 #include "mmc_ops.h"
 #include "sd_ops.h"
 
-#include "core.h"
-
 static const unsigned int tran_exp[] = {
        10000,          100000,         1000000,        10000000,
        0,              0,              0,              0
@@ -487,8 +486,7 @@ static void mmc_sd_detect(struct mmc_host *host)
        mmc_release_host(host);
 
        if (err != MMC_ERR_NONE) {
-               mmc_remove_card(host->card);
-               host->card = NULL;
+               mmc_sd_remove(host);
 
                mmc_claim_host(host);
                mmc_detach_bus(host);
@@ -496,6 +494,55 @@ static void mmc_sd_detect(struct mmc_host *host)
        }
 }
 
+MMC_ATTR_FN(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1],
+       card->raw_cid[2], card->raw_cid[3]);
+MMC_ATTR_FN(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1],
+       card->raw_csd[2], card->raw_csd[3]);
+MMC_ATTR_FN(scr, "%08x%08x\n", card->raw_scr[0], card->raw_scr[1]);
+MMC_ATTR_FN(date, "%02d/%04d\n", card->cid.month, card->cid.year);
+MMC_ATTR_FN(fwrev, "0x%x\n", card->cid.fwrev);
+MMC_ATTR_FN(hwrev, "0x%x\n", card->cid.hwrev);
+MMC_ATTR_FN(manfid, "0x%06x\n", card->cid.manfid);
+MMC_ATTR_FN(name, "%s\n", card->cid.prod_name);
+MMC_ATTR_FN(oemid, "0x%04x\n", card->cid.oemid);
+MMC_ATTR_FN(serial, "0x%08x\n", card->cid.serial);
+
+static struct device_attribute mmc_sd_dev_attrs[] = {
+       MMC_ATTR_RO(cid),
+       MMC_ATTR_RO(csd),
+       MMC_ATTR_RO(scr),
+       MMC_ATTR_RO(date),
+       MMC_ATTR_RO(fwrev),
+       MMC_ATTR_RO(hwrev),
+       MMC_ATTR_RO(manfid),
+       MMC_ATTR_RO(name),
+       MMC_ATTR_RO(oemid),
+       MMC_ATTR_RO(serial),
+       __ATTR_NULL,
+};
+
+/*
+ * Adds sysfs entries as relevant.
+ */
+static int mmc_sd_sysfs_add(struct mmc_host *host, struct mmc_card *card)
+{
+       int ret;
+
+       ret = mmc_add_attrs(card, mmc_sd_dev_attrs);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+/*
+ * Removes the sysfs entries added by mmc_sysfs_add().
+ */
+static void mmc_sd_sysfs_remove(struct mmc_host *host, struct mmc_card *card)
+{
+       mmc_remove_attrs(card, mmc_sd_dev_attrs);
+}
+
 #ifdef CONFIG_MMC_UNSAFE_RESUME
 
 /*
@@ -529,9 +576,7 @@ static void mmc_sd_resume(struct mmc_host *host)
 
        err = mmc_sd_init_card(host, host->ocr, host->card);
        if (err != MMC_ERR_NONE) {
-               mmc_remove_card(host->card);
-               host->card = NULL;
-
+               mmc_sd_remove(host);
                mmc_detach_bus(host);
        }
 
@@ -548,6 +593,8 @@ static void mmc_sd_resume(struct mmc_host *host)
 static const struct mmc_bus_ops mmc_sd_ops = {
        .remove = mmc_sd_remove,
        .detect = mmc_sd_detect,
+       .sysfs_add = mmc_sd_sysfs_add,
+       .sysfs_remove = mmc_sd_sysfs_remove,
        .suspend = mmc_sd_suspend,
        .resume = mmc_sd_resume,
 };
@@ -599,7 +646,7 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr)
 
        mmc_release_host(host);
 
-       err = mmc_register_card(host->card);
+       err = mmc_add_card(host->card);
        if (err)
                goto reclaim_host;
 
index 843b1fbba55724f060074bfe070659b645eb4b76..00a97e70f91425a57b1fc28628a5884ff93c285d 100644 (file)
@@ -2,6 +2,7 @@
  *  linux/drivers/mmc/core/sysfs.c
  *
  *  Copyright (C) 2003 Russell King, All Rights Reserved.
+ *  Copyright 2007 Pierre Ossman
  *
  * 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
  *
  *  MMC sysfs/driver model support.
  */
-#include <linux/module.h>
-#include <linux/init.h>
 #include <linux/device.h>
-#include <linux/idr.h>
-#include <linux/workqueue.h>
 
 #include <linux/mmc/card.h>
-#include <linux/mmc/host.h>
 
 #include "sysfs.h"
 
-#define dev_to_mmc_card(d)     container_of(d, struct mmc_card, dev)
-#define to_mmc_driver(d)       container_of(d, struct mmc_driver, drv)
-#define cls_dev_to_mmc_host(d) container_of(d, struct mmc_host, class_dev)
-
-#define MMC_ATTR(name, fmt, args...)                                   \
-static ssize_t mmc_##name##_show (struct device *dev, struct device_attribute *attr, char *buf)        \
-{                                                                      \
-       struct mmc_card *card = dev_to_mmc_card(dev);                   \
-       return sprintf(buf, fmt, args);                                 \
-}
-
-MMC_ATTR(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1],
-       card->raw_cid[2], card->raw_cid[3]);
-MMC_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1],
-       card->raw_csd[2], card->raw_csd[3]);
-MMC_ATTR(scr, "%08x%08x\n", card->raw_scr[0], card->raw_scr[1]);
-MMC_ATTR(date, "%02d/%04d\n", card->cid.month, card->cid.year);
-MMC_ATTR(fwrev, "0x%x\n", card->cid.fwrev);
-MMC_ATTR(hwrev, "0x%x\n", card->cid.hwrev);
-MMC_ATTR(manfid, "0x%06x\n", card->cid.manfid);
-MMC_ATTR(name, "%s\n", card->cid.prod_name);
-MMC_ATTR(oemid, "0x%04x\n", card->cid.oemid);
-MMC_ATTR(serial, "0x%08x\n", card->cid.serial);
-
-#define MMC_ATTR_RO(name) __ATTR(name, S_IRUGO, mmc_##name##_show, NULL)
-
-static struct device_attribute mmc_dev_attrs[] = {
-       MMC_ATTR_RO(cid),
-       MMC_ATTR_RO(csd),
-       MMC_ATTR_RO(date),
-       MMC_ATTR_RO(fwrev),
-       MMC_ATTR_RO(hwrev),
-       MMC_ATTR_RO(manfid),
-       MMC_ATTR_RO(name),
-       MMC_ATTR_RO(oemid),
-       MMC_ATTR_RO(serial),
-       __ATTR_NULL
-};
-
-static struct device_attribute mmc_dev_attr_scr = MMC_ATTR_RO(scr);
-
-
-static void mmc_release_card(struct device *dev)
-{
-       struct mmc_card *card = dev_to_mmc_card(dev);
-
-       kfree(card);
-}
-
-/*
- * This currently matches any MMC driver to any MMC card - drivers
- * themselves make the decision whether to drive this card in their
- * probe method.
- */
-static int mmc_bus_match(struct device *dev, struct device_driver *drv)
-{
-       return 1;
-}
-
-static int
-mmc_bus_uevent(struct device *dev, char **envp, int num_envp, char *buf,
-               int buf_size)
-{
-       struct mmc_card *card = dev_to_mmc_card(dev);
-       char ccc[13];
-       int retval = 0, i = 0, length = 0;
-
-#define add_env(fmt,val) do {                                  \
-       retval = add_uevent_var(envp, num_envp, &i,             \
-                               buf, buf_size, &length,         \
-                               fmt, val);                      \
-       if (retval)                                             \
-               return retval;                                  \
-} while (0);
-
-       for (i = 0; i < 12; i++)
-               ccc[i] = card->csd.cmdclass & (1 << i) ? '1' : '0';
-       ccc[12] = '\0';
-
-       add_env("MMC_CCC=%s", ccc);
-       add_env("MMC_MANFID=%06x", card->cid.manfid);
-       add_env("MMC_NAME=%s", mmc_card_name(card));
-       add_env("MMC_OEMID=%04x", card->cid.oemid);
-#undef add_env
-       envp[i] = NULL;
-
-       return 0;
-}
-
-static int mmc_bus_suspend(struct device *dev, pm_message_t state)
-{
-       struct mmc_driver *drv = to_mmc_driver(dev->driver);
-       struct mmc_card *card = dev_to_mmc_card(dev);
-       int ret = 0;
-
-       if (dev->driver && drv->suspend)
-               ret = drv->suspend(card, state);
-       return ret;
-}
-
-static int mmc_bus_resume(struct device *dev)
-{
-       struct mmc_driver *drv = to_mmc_driver(dev->driver);
-       struct mmc_card *card = dev_to_mmc_card(dev);
-       int ret = 0;
-
-       if (dev->driver && drv->resume)
-               ret = drv->resume(card);
-       return ret;
-}
-
-static int mmc_bus_probe(struct device *dev)
-{
-       struct mmc_driver *drv = to_mmc_driver(dev->driver);
-       struct mmc_card *card = dev_to_mmc_card(dev);
-
-       return drv->probe(card);
-}
-
-static int mmc_bus_remove(struct device *dev)
-{
-       struct mmc_driver *drv = to_mmc_driver(dev->driver);
-       struct mmc_card *card = dev_to_mmc_card(dev);
-
-       drv->remove(card);
-
-       return 0;
-}
-
-static struct bus_type mmc_bus_type = {
-       .name           = "mmc",
-       .dev_attrs      = mmc_dev_attrs,
-       .match          = mmc_bus_match,
-       .uevent         = mmc_bus_uevent,
-       .probe          = mmc_bus_probe,
-       .remove         = mmc_bus_remove,
-       .suspend        = mmc_bus_suspend,
-       .resume         = mmc_bus_resume,
-};
-
-/**
- *     mmc_register_driver - register a media driver
- *     @drv: MMC media driver
- */
-int mmc_register_driver(struct mmc_driver *drv)
-{
-       drv->drv.bus = &mmc_bus_type;
-       return driver_register(&drv->drv);
-}
-
-EXPORT_SYMBOL(mmc_register_driver);
-
-/**
- *     mmc_unregister_driver - unregister a media driver
- *     @drv: MMC media driver
- */
-void mmc_unregister_driver(struct mmc_driver *drv)
-{
-       drv->drv.bus = &mmc_bus_type;
-       driver_unregister(&drv->drv);
-}
-
-EXPORT_SYMBOL(mmc_unregister_driver);
-
-
-/*
- * Internal function.  Initialise a MMC card structure.
- */
-void mmc_init_card(struct mmc_card *card, struct mmc_host *host)
-{
-       memset(card, 0, sizeof(struct mmc_card));
-       card->host = host;
-       device_initialize(&card->dev);
-       card->dev.parent = mmc_classdev(host);
-       card->dev.bus = &mmc_bus_type;
-       card->dev.release = mmc_release_card;
-}
-
-/*
- * Internal function.  Register a new MMC card with the driver model.
- */
-int mmc_register_card(struct mmc_card *card)
+int mmc_add_attrs(struct mmc_card *card, struct device_attribute *attrs)
 {
-       int ret;
+       int error = 0;
+       int i;
 
-       snprintf(card->dev.bus_id, sizeof(card->dev.bus_id),
-                "%s:%04x", mmc_hostname(card->host), card->rca);
-
-       ret = device_add(&card->dev);
-       if (ret == 0) {
-               if (mmc_card_sd(card)) {
-                       ret = device_create_file(&card->dev, &mmc_dev_attr_scr);
-                       if (ret)
-                               device_del(&card->dev);
+       for (i = 0; attr_name(attrs[i]); i++) {
+               error = device_create_file(&card->dev, &attrs[i]);
+               if (error) {
+                       while (--i >= 0)
+                               device_remove_file(&card->dev, &attrs[i]);
+                       break;
                }
        }
-       if (ret == 0)
-               mmc_card_set_present(card);
-       return ret;
-}
-
-/*
- * Internal function.  Unregister a new MMC card with the
- * driver model, and (eventually) free it.
- */
-void mmc_remove_card(struct mmc_card *card)
-{
-       if (mmc_card_present(card)) {
-               if (mmc_card_sd(card))
-                       device_remove_file(&card->dev, &mmc_dev_attr_scr);
-
-               device_del(&card->dev);
-       }
-
-       put_device(&card->dev);
-}
-
-
-static void mmc_host_classdev_release(struct device *dev)
-{
-       struct mmc_host *host = cls_dev_to_mmc_host(dev);
-       kfree(host);
-}
-
-static struct class mmc_host_class = {
-       .name           = "mmc_host",
-       .dev_release    = mmc_host_classdev_release,
-};
-
-static DEFINE_IDR(mmc_host_idr);
-static DEFINE_SPINLOCK(mmc_host_lock);
-
-/*
- * Internal function. Allocate a new MMC host.
- */
-struct mmc_host *mmc_alloc_host_sysfs(int extra, struct device *dev)
-{
-       struct mmc_host *host;
-
-       host = kmalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL);
-       if (host) {
-               memset(host, 0, sizeof(struct mmc_host) + extra);
-
-               host->parent = dev;
-               host->class_dev.parent = dev;
-               host->class_dev.class = &mmc_host_class;
-               device_initialize(&host->class_dev);
-       }
 
-       return host;
+       return error;
 }
 
-/*
- * Internal function. Register a new MMC host with the MMC class.
- */
-int mmc_add_host_sysfs(struct mmc_host *host)
+void mmc_remove_attrs(struct mmc_card *card, struct device_attribute *attrs)
 {
-       int err;
-
-       if (!idr_pre_get(&mmc_host_idr, GFP_KERNEL))
-               return -ENOMEM;
-
-       spin_lock(&mmc_host_lock);
-       err = idr_get_new(&mmc_host_idr, host, &host->index);
-       spin_unlock(&mmc_host_lock);
-       if (err)
-               return err;
-
-       snprintf(host->class_dev.bus_id, BUS_ID_SIZE,
-                "mmc%d", host->index);
-
-       return device_add(&host->class_dev);
-}
+       int i;
 
-/*
- * Internal function. Unregister a MMC host with the MMC class.
- */
-void mmc_remove_host_sysfs(struct mmc_host *host)
-{
-       device_del(&host->class_dev);
-
-       spin_lock(&mmc_host_lock);
-       idr_remove(&mmc_host_idr, host->index);
-       spin_unlock(&mmc_host_lock);
-}
-
-/*
- * Internal function. Free a MMC host.
- */
-void mmc_free_host_sysfs(struct mmc_host *host)
-{
-       put_device(&host->class_dev);
-}
-
-static struct workqueue_struct *workqueue;
-
-/*
- * Internal function. Schedule delayed work in the MMC work queue.
- */
-int mmc_schedule_delayed_work(struct delayed_work *work, unsigned long delay)
-{
-       return queue_delayed_work(workqueue, work, delay);
-}
-
-/*
- * Internal function. Flush all scheduled work from the MMC work queue.
- */
-void mmc_flush_scheduled_work(void)
-{
-       flush_workqueue(workqueue);
-}
-
-static int __init mmc_init(void)
-{
-       int ret;
-
-       workqueue = create_singlethread_workqueue("kmmcd");
-       if (!workqueue)
-               return -ENOMEM;
-
-       ret = bus_register(&mmc_bus_type);
-       if (ret == 0) {
-               ret = class_register(&mmc_host_class);
-               if (ret)
-                       bus_unregister(&mmc_bus_type);
-       }
-       return ret;
-}
-
-static void __exit mmc_exit(void)
-{
-       class_unregister(&mmc_host_class);
-       bus_unregister(&mmc_bus_type);
-       destroy_workqueue(workqueue);
+       for (i = 0; attr_name(attrs[i]); i++)
+               device_remove_file(&card->dev, &attrs[i]);
 }
 
-module_init(mmc_init);
-module_exit(mmc_exit);
index 80e29b35828209588112e805f20d98ef561c99a8..4b8f670bd10f7561ed9fd3c25fac0fe7e3d44efd 100644 (file)
 #ifndef _MMC_CORE_SYSFS_H
 #define _MMC_CORE_SYSFS_H
 
-void mmc_init_card(struct mmc_card *card, struct mmc_host *host);
-int mmc_register_card(struct mmc_card *card);
-void mmc_remove_card(struct mmc_card *card);
+#define MMC_ATTR_FN(name, fmt, args...)                                        \
+static ssize_t mmc_##name##_show (struct device *dev, struct device_attribute *attr, char *buf)        \
+{                                                                      \
+       struct mmc_card *card = container_of(dev, struct mmc_card, dev);\
+       return sprintf(buf, fmt, args);                                 \
+}
 
-struct mmc_host *mmc_alloc_host_sysfs(int extra, struct device *dev);
-int mmc_add_host_sysfs(struct mmc_host *host);
-void mmc_remove_host_sysfs(struct mmc_host *host);
-void mmc_free_host_sysfs(struct mmc_host *host);
+#define MMC_ATTR_RO(name) __ATTR(name, S_IRUGO, mmc_##name##_show, NULL)
 
-int mmc_schedule_work(struct work_struct *work);
-int mmc_schedule_delayed_work(struct delayed_work *work, unsigned long delay);
-void mmc_flush_scheduled_work(void);
+int mmc_add_attrs(struct mmc_card *card, struct device_attribute *attrs);
+void mmc_remove_attrs(struct mmc_card *card, struct device_attribute *attrs);
 
 #endif
index 5b00c194b6285a0bb76e7101765bf60bedceaf55..28c881895ab79c42a154481644cae2366d5bd47b 100644 (file)
@@ -78,8 +78,6 @@
 
 #define DRIVER_NAME "at91_mci"
 
-#undef SUPPORT_4WIRE
-
 #define FL_SENT_COMMAND        (1 << 0)
 #define FL_SENT_STOP   (1 << 1)
 
@@ -131,7 +129,7 @@ struct at91mci_host
 /*
  * Copy from sg to a dma block - used for transfers
  */
-static inline void at91mci_sg_to_dma(struct at91mci_host *host, struct mmc_data *data)
+static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data *data)
 {
        unsigned int len, i, size;
        unsigned *dmabuf = host->buffer;
@@ -180,7 +178,7 @@ static inline void at91mci_sg_to_dma(struct at91mci_host *host, struct mmc_data
 /*
  * Prepare a dma read
  */
-static void at91mci_pre_dma_read(struct at91mci_host *host)
+static void at91_mci_pre_dma_read(struct at91mci_host *host)
 {
        int i;
        struct scatterlist *sg;
@@ -248,7 +246,7 @@ static void at91mci_pre_dma_read(struct at91mci_host *host)
 /*
  * Handle after a dma read
  */
-static void at91mci_post_dma_read(struct at91mci_host *host)
+static void at91_mci_post_dma_read(struct at91mci_host *host)
 {
        struct mmc_command *cmd;
        struct mmc_data *data;
@@ -268,8 +266,6 @@ static void at91mci_post_dma_read(struct at91mci_host *host)
        }
 
        while (host->in_use_index < host->transfer_index) {
-               unsigned int *buffer;
-
                struct scatterlist *sg;
 
                pr_debug("finishing index %d\n", host->in_use_index);
@@ -280,29 +276,31 @@ static void at91mci_post_dma_read(struct at91mci_host *host)
 
                dma_unmap_page(NULL, sg->dma_address, sg->length, DMA_FROM_DEVICE);
 
-               /* Swap the contents of the buffer */
-               buffer = kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset;
-               pr_debug("buffer = %p, length = %d\n", buffer, sg->length);
-
                data->bytes_xfered += sg->length;
 
                if (cpu_is_at91rm9200()) {      /* AT91RM9200 errata */
+                       unsigned int *buffer;
                        int index;
 
+                       /* Swap the contents of the buffer */
+                       buffer = kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset;
+                       pr_debug("buffer = %p, length = %d\n", buffer, sg->length);
+
                        for (index = 0; index < (sg->length / 4); index++)
                                buffer[index] = swab32(buffer[index]);
+
+                       kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
                }
 
-               kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
                flush_dcache_page(sg->page);
        }
 
        /* Is there another transfer to trigger? */
        if (host->transfer_index < data->sg_len)
-               at91mci_pre_dma_read(host);
+               at91_mci_pre_dma_read(host);
        else {
+               at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_ENDRX);
                at91_mci_write(host, AT91_MCI_IER, AT91_MCI_RXBUFF);
-               at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
        }
 
        pr_debug("post dma read done\n");
@@ -323,7 +321,6 @@ static void at91_mci_handle_transmitted(struct at91mci_host *host)
 
        /* Now wait for cmd ready */
        at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_TXBUFE);
-       at91_mci_write(host, AT91_MCI_IER, AT91_MCI_NOTBUSY);
 
        cmd = host->cmd;
        if (!cmd) return;
@@ -331,18 +328,53 @@ static void at91_mci_handle_transmitted(struct at91mci_host *host)
        data = cmd->data;
        if (!data) return;
 
+       if (cmd->data->flags & MMC_DATA_MULTI) {
+               pr_debug("multiple write : wait for BLKE...\n");
+               at91_mci_write(host, AT91_MCI_IER, AT91_MCI_BLKE);
+       } else
+               at91_mci_write(host, AT91_MCI_IER, AT91_MCI_NOTBUSY);
+
        data->bytes_xfered = host->total_length;
 }
 
+/*Handle after command sent ready*/
+static int at91_mci_handle_cmdrdy(struct at91mci_host *host)
+{
+       if (!host->cmd)
+               return 1;
+       else if (!host->cmd->data) {
+               if (host->flags & FL_SENT_STOP) {
+                       /*After multi block write, we must wait for NOTBUSY*/
+                       at91_mci_write(host, AT91_MCI_IER, AT91_MCI_NOTBUSY);
+               } else return 1;
+       } else if (host->cmd->data->flags & MMC_DATA_WRITE) {
+               /*After sendding multi-block-write command, start DMA transfer*/
+               at91_mci_write(host, AT91_MCI_IER, AT91_MCI_TXBUFE);
+               at91_mci_write(host, AT91_MCI_IER, AT91_MCI_BLKE);
+               at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_TXTEN);
+       }
+
+       /* command not completed, have to wait */
+       return 0;
+}
+
+
 /*
  * Enable the controller
  */
 static void at91_mci_enable(struct at91mci_host *host)
 {
+       unsigned int mr;
+
        at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIEN);
        at91_mci_write(host, AT91_MCI_IDR, 0xffffffff);
        at91_mci_write(host, AT91_MCI_DTOR, AT91_MCI_DTOMUL_1M | AT91_MCI_DTOCYC);
-       at91_mci_write(host, AT91_MCI_MR, AT91_MCI_PDCMODE | 0x34a);
+       mr = AT91_MCI_PDCMODE | 0x34a;
+
+       if (cpu_is_at91sam9260() || cpu_is_at91sam9263())
+               mr |= AT91_MCI_RDPROOF | AT91_MCI_WRPROOF;
+
+       at91_mci_write(host, AT91_MCI_MR, mr);
 
        /* use Slot A or B (only one at same time) */
        at91_mci_write(host, AT91_MCI_SDCR, host->board->slot_b);
@@ -358,9 +390,8 @@ static void at91_mci_disable(struct at91mci_host *host)
 
 /*
  * Send a command
- * return the interrupts to enable
  */
-static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_command *cmd)
+static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command *cmd)
 {
        unsigned int cmdr, mr;
        unsigned int block_length;
@@ -371,8 +402,7 @@ static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_
 
        host->cmd = cmd;
 
-       /* Not sure if this is needed */
-#if 0
+       /* Needed for leaving busy state before CMD1 */
        if ((at91_mci_read(host, AT91_MCI_SR) & AT91_MCI_RTOE) && (cmd->opcode == 1)) {
                pr_debug("Clearing timeout\n");
                at91_mci_write(host, AT91_MCI_ARGR, 0);
@@ -382,7 +412,7 @@ static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_
                        pr_debug("Clearing: SR = %08X\n", at91_mci_read(host, AT91_MCI_SR));
                }
        }
-#endif
+
        cmdr = cmd->opcode;
 
        if (mmc_resp_type(cmd) == MMC_RSP_NONE)
@@ -439,50 +469,48 @@ static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_
                at91_mci_write(host, ATMEL_PDC_TCR, 0);
                at91_mci_write(host, ATMEL_PDC_TNPR, 0);
                at91_mci_write(host, ATMEL_PDC_TNCR, 0);
+               ier = AT91_MCI_CMDRDY;
+       } else {
+               /* zero block length and PDC mode */
+               mr = at91_mci_read(host, AT91_MCI_MR) & 0x7fff;
+               at91_mci_write(host, AT91_MCI_MR, mr | (block_length << 16) | AT91_MCI_PDCMODE);
 
-               at91_mci_write(host, AT91_MCI_ARGR, cmd->arg);
-               at91_mci_write(host, AT91_MCI_CMDR, cmdr);
-               return AT91_MCI_CMDRDY;
-       }
-
-       mr = at91_mci_read(host, AT91_MCI_MR) & 0x7fff; /* zero block length and PDC mode */
-       at91_mci_write(host, AT91_MCI_MR, mr | (block_length << 16) | AT91_MCI_PDCMODE);
-
-       /*
-        * Disable the PDC controller
-        */
-       at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
-
-       if (cmdr & AT91_MCI_TRCMD_START) {
-               data->bytes_xfered = 0;
-               host->transfer_index = 0;
-               host->in_use_index = 0;
-               if (cmdr & AT91_MCI_TRDIR) {
-                       /*
-                        * Handle a read
-                        */
-                       host->buffer = NULL;
-                       host->total_length = 0;
-
-                       at91mci_pre_dma_read(host);
-                       ier = AT91_MCI_ENDRX /* | AT91_MCI_RXBUFF */;
-               }
-               else {
-                       /*
-                        * Handle a write
-                        */
-                       host->total_length = block_length * blocks;
-                       host->buffer = dma_alloc_coherent(NULL,
-                                                 host->total_length,
-                                                 &host->physical_address, GFP_KERNEL);
-
-                       at91mci_sg_to_dma(host, data);
-
-                       pr_debug("Transmitting %d bytes\n", host->total_length);
+               /*
+                * Disable the PDC controller
+                */
+               at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
 
-                       at91_mci_write(host, ATMEL_PDC_TPR, host->physical_address);
-                       at91_mci_write(host, ATMEL_PDC_TCR, host->total_length / 4);
-                       ier = AT91_MCI_TXBUFE;
+               if (cmdr & AT91_MCI_TRCMD_START) {
+                       data->bytes_xfered = 0;
+                       host->transfer_index = 0;
+                       host->in_use_index = 0;
+                       if (cmdr & AT91_MCI_TRDIR) {
+                               /*
+                                * Handle a read
+                                */
+                               host->buffer = NULL;
+                               host->total_length = 0;
+
+                               at91_mci_pre_dma_read(host);
+                               ier = AT91_MCI_ENDRX /* | AT91_MCI_RXBUFF */;
+                       }
+                       else {
+                               /*
+                                * Handle a write
+                                */
+                               host->total_length = block_length * blocks;
+                               host->buffer = dma_alloc_coherent(NULL,
+                                               host->total_length,
+                                               &host->physical_address, GFP_KERNEL);
+
+                               at91_mci_sg_to_dma(host, data);
+
+                               pr_debug("Transmitting %d bytes\n", host->total_length);
+
+                               at91_mci_write(host, ATMEL_PDC_TPR, host->physical_address);
+                               at91_mci_write(host, ATMEL_PDC_TCR, host->total_length / 4);
+                               ier = AT91_MCI_CMDRDY;
+                       }
                }
        }
 
@@ -497,39 +525,24 @@ static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_
        if (cmdr & AT91_MCI_TRCMD_START) {
                if (cmdr & AT91_MCI_TRDIR)
                        at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTEN);
-               else
-                       at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_TXTEN);
        }
-       return ier;
-}
-
-/*
- * Wait for a command to complete
- */
-static void at91mci_process_command(struct at91mci_host *host, struct mmc_command *cmd)
-{
-       unsigned int ier;
-
-       ier = at91_mci_send_command(host, cmd);
-
-       pr_debug("setting ier to %08X\n", ier);
 
-       /* Stop on errors or the required value */
+       /* Enable selected interrupts */
        at91_mci_write(host, AT91_MCI_IER, AT91_MCI_ERRORS | ier);
 }
 
 /*
  * Process the next step in the request
  */
-static void at91mci_process_next(struct at91mci_host *host)
+static void at91_mci_process_next(struct at91mci_host *host)
 {
        if (!(host->flags & FL_SENT_COMMAND)) {
                host->flags |= FL_SENT_COMMAND;
-               at91mci_process_command(host, host->request->cmd);
+               at91_mci_send_command(host, host->request->cmd);
        }
        else if ((!(host->flags & FL_SENT_STOP)) && host->request->stop) {
                host->flags |= FL_SENT_STOP;
-               at91mci_process_command(host, host->request->stop);
+               at91_mci_send_command(host, host->request->stop);
        }
        else
                mmc_request_done(host->mmc, host->request);
@@ -538,7 +551,7 @@ static void at91mci_process_next(struct at91mci_host *host)
 /*
  * Handle a command that has been completed
  */
-static void at91mci_completed_command(struct at91mci_host *host)
+static void at91_mci_completed_command(struct at91mci_host *host)
 {
        struct mmc_command *cmd = host->cmd;
        unsigned int status;
@@ -583,7 +596,7 @@ static void at91mci_completed_command(struct at91mci_host *host)
        else
                cmd->error = MMC_ERR_NONE;
 
-       at91mci_process_next(host);
+       at91_mci_process_next(host);
 }
 
 /*
@@ -595,7 +608,7 @@ static void at91_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
        host->request = mrq;
        host->flags = 0;
 
-       at91mci_process_next(host);
+       at91_mci_process_next(host);
 }
 
 /*
@@ -698,29 +711,33 @@ static irqreturn_t at91_mci_irq(int irq, void *devid)
                        at91_mci_handle_transmitted(host);
                }
 
+               if (int_status & AT91_MCI_ENDRX) {
+                       pr_debug("ENDRX\n");
+                       at91_mci_post_dma_read(host);
+               }
+
                if (int_status & AT91_MCI_RXBUFF) {
                        pr_debug("RX buffer full\n");
-                       at91_mci_write(host, AT91_MCI_IER, AT91_MCI_CMDRDY);
+                       at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
+                       at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_RXBUFF | AT91_MCI_ENDRX);
+                       completed = 1;
                }
 
                if (int_status & AT91_MCI_ENDTX)
                        pr_debug("Transmit has ended\n");
 
-               if (int_status & AT91_MCI_ENDRX) {
-                       pr_debug("Receive has ended\n");
-                       at91mci_post_dma_read(host);
-               }
-
                if (int_status & AT91_MCI_NOTBUSY) {
                        pr_debug("Card is ready\n");
-                       at91_mci_write(host, AT91_MCI_IER, AT91_MCI_CMDRDY);
+                       completed = 1;
                }
 
                if (int_status & AT91_MCI_DTIP)
                        pr_debug("Data transfer in progress\n");
 
-               if (int_status & AT91_MCI_BLKE)
+               if (int_status & AT91_MCI_BLKE) {
                        pr_debug("Block transfer has ended\n");
+                       completed = 1;
+               }
 
                if (int_status & AT91_MCI_TXRDY)
                        pr_debug("Ready to transmit\n");
@@ -730,14 +747,14 @@ static irqreturn_t at91_mci_irq(int irq, void *devid)
 
                if (int_status & AT91_MCI_CMDRDY) {
                        pr_debug("Command ready\n");
-                       completed = 1;
+                       completed = at91_mci_handle_cmdrdy(host);
                }
        }
 
        if (completed) {
                pr_debug("Completed command\n");
                at91_mci_write(host, AT91_MCI_IDR, 0xffffffff);
-               at91mci_completed_command(host);
+               at91_mci_completed_command(host);
        } else
                at91_mci_write(host, AT91_MCI_IDR, int_status);
 
@@ -830,11 +847,11 @@ static int __init at91_mci_probe(struct platform_device *pdev)
        host->bus_mode = 0;
        host->board = pdev->dev.platform_data;
        if (host->board->wire4) {
-#ifdef SUPPORT_4WIRE
-               mmc->caps |= MMC_CAP_4_BIT_DATA;
-#else
-               printk("AT91 MMC: 4 wire bus mode not supported by this driver - using 1 wire\n");
-#endif
+               if (cpu_is_at91sam9260() || cpu_is_at91sam9263())
+                       mmc->caps |= MMC_CAP_4_BIT_DATA;
+               else
+                       printk("AT91 MMC: 4 wire bus mode not supported"
+                               " - using 1 wire\n");
        }
 
        /*
index 1b163220df2bad67727bf242ab982333dd6b5e54..df17c281278a68d272a21756b1be5eb1f1d9c82f 100644 (file)
@@ -1,25 +1,3 @@
-#undef MMC_STRPCL
-#undef MMC_STAT
-#undef MMC_CLKRT
-#undef MMC_SPI
-#undef MMC_CMDAT
-#undef MMC_RESTO
-#undef MMC_RDTO
-#undef MMC_BLKLEN
-#undef MMC_NOB
-#undef MMC_PRTBUF
-#undef MMC_I_MASK
-#undef END_CMD_RES
-#undef PRG_DONE
-#undef DATA_TRAN_DONE
-#undef MMC_I_REG
-#undef MMC_CMD
-#undef MMC_ARGH
-#undef MMC_ARGL
-#undef MMC_RES
-#undef MMC_RXFIFO
-#undef MMC_TXFIFO
-
 #define MMC_STRPCL     0x0000
 #define STOP_CLOCK             (1 << 0)
 #define START_CLOCK            (2 << 0)
index a359efdd77ebda58632a169728e6ce7ba6103d6f..10d15c39d003a58e372f306c53c3f5d3aba76787 100644 (file)
@@ -70,6 +70,14 @@ static const struct pci_device_id pci_ids[] __devinitdata = {
                .driver_data    = SDHCI_QUIRK_SINGLE_POWER_WRITE,
        },
 
+       {
+               .vendor         = PCI_VENDOR_ID_ENE,
+               .device         = PCI_DEVICE_ID_ENE_CB712_SD_2,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .driver_data    = SDHCI_QUIRK_SINGLE_POWER_WRITE,
+       },
+
        {       /* Generic SD host controller */
                PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00)
        },
@@ -1022,7 +1030,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
                writel(SDHCI_INT_BUS_POWER, host->ioaddr + SDHCI_INT_STATUS);
        }
 
-       intmask &= SDHCI_INT_BUS_POWER;
+       intmask &= ~SDHCI_INT_BUS_POWER;
 
        if (intmask) {
                printk(KERN_ERR "%s: Unexpected interrupt 0x%08x.\n",
index 78872c3f3760d63f191deed477a7307bb5d4c505..b96ac8e119dc15efdfe4251742aee5be4b8b420f 100644 (file)
@@ -84,7 +84,7 @@ static unsigned long __initdata doc_locations[] = {
 #elif defined(CONFIG_MOMENCO_OCELOT)
        0x2f000000,
         0xff000000,
-#elif defined(CONFIG_MOMENCO_OCELOT_G) || defined (CONFIG_MOMENCO_OCELOT_C)
+#elif defined(CONFIG_MOMENCO_OCELOT_G)
         0xff000000,
 ##else
 #warning Unknown architecture for DiskOnChip. No default probe locations defined
index b665e4ac2208458bc70d1f8dfe9cd00a3a6a58fd..f88ebc5b685e93863fc14ad138f0d8fb089acf38 100644 (file)
@@ -258,12 +258,6 @@ config MTD_TSUNAMI
        help
          Support for the flash chip on Tsunami TIG bus.
 
-config MTD_LASAT
-       tristate "LASAT flash device"
-       depends on LASAT && MTD_CFI
-       help
-         Support for the flash chips on the Lasat 100 and 200 boards.
-
 config MTD_NETtel
        tristate "CFI flash device on SnapGear/SecureEdge"
        depends on X86 && MTD_PARTITIONS && MTD_JEDECPROBE
index 3acbb5d01ca4edc159238390e1f827ebee431524..970b189271a289370970dc966fb4b5cb50795c76 100644 (file)
@@ -47,7 +47,6 @@ obj-$(CONFIG_MTD_OCELOT)      += ocelot.o
 obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o
 obj-$(CONFIG_MTD_PCI)          += pci.o
 obj-$(CONFIG_MTD_ALCHEMY)       += alchemy-flash.o
-obj-$(CONFIG_MTD_LASAT)                += lasat.o
 obj-$(CONFIG_MTD_AUTCPU12)     += autcpu12-nvram.o
 obj-$(CONFIG_MTD_EDB7312)      += edb7312.o
 obj-$(CONFIG_MTD_IMPA7)                += impa7.o
diff --git a/drivers/mtd/maps/lasat.c b/drivers/mtd/maps/lasat.c
deleted file mode 100644 (file)
index e343763..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Flash device on Lasat 100 and 200 boards
- *
- * (C) 2002 Brian Murphy <brian@murphy.dk>
- *
- * 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.
- *
- * $Id: lasat.c,v 1.9 2004/11/04 13:24:15 gleixner Exp $
- *
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <asm/io.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-#include <asm/lasat/lasat.h>
-
-static struct mtd_info *lasat_mtd;
-
-static struct mtd_partition partition_info[LASAT_MTD_LAST];
-static char *lasat_mtd_partnames[] = {"Bootloader", "Service", "Normal", "Filesystem", "Config"};
-
-static void lasat_set_vpp(struct map_info *map, int vpp)
-{
-       if (vpp)
-           *lasat_misc->flash_wp_reg |= 1 << lasat_misc->flash_wp_bit;
-       else
-           *lasat_misc->flash_wp_reg &= ~(1 << lasat_misc->flash_wp_bit);
-}
-
-static struct map_info lasat_map = {
-       .name = "LASAT flash",
-       .bankwidth = 4,
-       .set_vpp = lasat_set_vpp
-};
-
-static int __init init_lasat(void)
-{
-       int i;
-       /* since we use AMD chips and set_vpp is not implimented
-        * for these (yet) we still have to permanently enable flash write */
-       printk(KERN_NOTICE "Unprotecting flash\n");
-       ENABLE_VPP((&lasat_map));
-
-       lasat_map.phys = lasat_flash_partition_start(LASAT_MTD_BOOTLOADER);
-       lasat_map.virt = ioremap_nocache(
-                       lasat_map.phys, lasat_board_info.li_flash_size);
-       lasat_map.size = lasat_board_info.li_flash_size;
-
-       simple_map_init(&lasat_map);
-
-       for (i=0; i < LASAT_MTD_LAST; i++)
-               partition_info[i].name = lasat_mtd_partnames[i];
-
-       lasat_mtd = do_map_probe("cfi_probe", &lasat_map);
-
-       if (!lasat_mtd)
-           lasat_mtd = do_map_probe("jedec_probe", &lasat_map);
-
-       if (lasat_mtd) {
-               u32 size, offset = 0;
-
-               lasat_mtd->owner = THIS_MODULE;
-
-               for (i=0; i < LASAT_MTD_LAST; i++) {
-                       size = lasat_flash_partition_size(i);
-                       partition_info[i].size = size;
-                       partition_info[i].offset = offset;
-                       offset += size;
-               }
-
-               add_mtd_partitions( lasat_mtd, partition_info, LASAT_MTD_LAST );
-               return 0;
-       }
-
-       iounmap(lasat_map.virt);
-       return -ENXIO;
-}
-
-static void __exit cleanup_lasat(void)
-{
-       if (lasat_mtd) {
-               del_mtd_partitions(lasat_mtd);
-               map_destroy(lasat_mtd);
-       }
-       if (lasat_map.virt) {
-               iounmap(lasat_map.virt);
-               lasat_map.virt = 0;
-       }
-}
-
-module_init(init_lasat);
-module_exit(cleanup_lasat);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Brian Murphy <brian@murphy.dk>");
-MODULE_DESCRIPTION("Lasat Safepipe/Masquerade MTD map driver");
index 595208f965a55cdd31f5359cd704d283785a3d34..17c868034aad4a8d7cee4851400867bb9b299747 100644 (file)
@@ -59,7 +59,7 @@ static unsigned long __initdata doc_locations[] = {
 #elif defined(CONFIG_MOMENCO_OCELOT)
        0x2f000000,
        0xff000000,
-#elif defined(CONFIG_MOMENCO_OCELOT_G) || defined (CONFIG_MOMENCO_OCELOT_C)
+#elif defined(CONFIG_MOMENCO_OCELOT_G)
        0xff000000,
 #else
 #warning Unknown architecture for DiskOnChip. No default probe locations defined
index da1a22c13865fc2c94f77aae7a542c48682fdfa7..ab18343e58ef844068dce2716b55a2c474795d5f 100644 (file)
@@ -990,7 +990,7 @@ static void elmc_rcv_int(struct net_device *dev)
                                if (skb != NULL) {
                                        skb_reserve(skb, 2);    /* 16 byte alignment */
                                        skb_put(skb,totlen);
-                                       eth_copy_and_sum(skb, (char *) p->base+(unsigned long) rbd->buffer,totlen,0);
+                                       skb_copy_to_linear_data(skb, (char *) p->base+(unsigned long) rbd->buffer,totlen);
                                        skb->protocol = eth_type_trans(skb, dev);
                                        netif_rx(skb);
                                        dev->last_rx = jiffies;
index f26ca331615e596e01a3e48d1357fa58494dec20..6deb20fc7a08017f6b9ef7955a827103181529c7 100644 (file)
@@ -324,7 +324,7 @@ static struct vortex_chip_info {
        {"3c980C Python-T",
         PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, },
        {"3cSOHO100-TX Hurricane",
-        PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, },
+        PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, },
        {"3c555 Laptop Hurricane",
         PCI_USES_MASTER, IS_CYCLONE|EEPROM_8BIT|HAS_HWCKSM, 128, },
        {"3c556 Laptop Tornado",
index 0877fc372f4b87dc8c11d661f52da6a20f381053..e89ace109a5d149b3c62b3628c72a9a722512596 100644 (file)
@@ -333,9 +333,9 @@ static int lance_rx (struct net_device *dev)
 
                         skb_reserve (skb, 2);           /* 16 byte align */
                         skb_put (skb, len);             /* make room */
-                        eth_copy_and_sum(skb,
+                        skb_copy_to_linear_data(skb,
                                          (unsigned char *)&(ib->rx_buf [lp->rx_new][0]),
-                                         len, 0);
+                                         len);
                         skb->protocol = eth_type_trans (skb, dev);
                        netif_rx (skb);
                        dev->last_rx = jiffies;
index a804965e654259a3f136e02d0a4aa961b286eef2..807e6992e6142ef9399466f53ab038b89807d2cc 100644 (file)
@@ -107,11 +107,6 @@ MODULE_PARM_DESC (multicast_filter_limit, "8139cp: maximum number of filtered mu
 
 #define PFX                    DRV_NAME ": "
 
-#ifndef TRUE
-#define FALSE 0
-#define TRUE (!FALSE)
-#endif
-
 #define CP_DEF_MSG_ENABLE      (NETIF_MSG_DRV          | \
                                 NETIF_MSG_PROBE        | \
                                 NETIF_MSG_LINK)
@@ -661,7 +656,7 @@ static irqreturn_t cp_interrupt (int irq, void *dev_instance)
        if (status & (TxOK | TxErr | TxEmpty | SWInt))
                cp_tx(cp);
        if (status & LinkChg)
-               mii_check_media(&cp->mii_if, netif_msg_link(cp), FALSE);
+               mii_check_media(&cp->mii_if, netif_msg_link(cp), false);
 
        spin_unlock(&cp->lock);
 
@@ -1188,7 +1183,7 @@ static int cp_open (struct net_device *dev)
                goto err_out_hw;
 
        netif_carrier_off(dev);
-       mii_check_media(&cp->mii_if, netif_msg_link(cp), TRUE);
+       mii_check_media(&cp->mii_if, netif_msg_link(cp), true);
        netif_start_queue(dev);
 
        return 0;
@@ -1804,7 +1799,6 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        void __iomem *regs;
        resource_size_t pciaddr;
        unsigned int addr_len, i, pci_using_dac;
-       u8 pci_rev;
 
 #ifndef MODULE
        static int version_printed;
@@ -1812,13 +1806,11 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
                printk("%s", version);
 #endif
 
-       pci_read_config_byte(pdev, PCI_REVISION_ID, &pci_rev);
-
        if (pdev->vendor == PCI_VENDOR_ID_REALTEK &&
-           pdev->device == PCI_DEVICE_ID_REALTEK_8139 && pci_rev < 0x20) {
+           pdev->device == PCI_DEVICE_ID_REALTEK_8139 && pdev->revision < 0x20) {
                dev_err(&pdev->dev,
                           "This (id %04x:%04x rev %02x) is not an 8139C+ compatible chip\n",
-                          pdev->vendor, pdev->device, pci_rev);
+                          pdev->vendor, pdev->device, pdev->revision);
                dev_err(&pdev->dev, "Try the \"8139too\" driver instead.\n");
                return -ENODEV;
        }
@@ -2050,7 +2042,7 @@ static int cp_resume (struct pci_dev *pdev)
 
        spin_lock_irqsave (&cp->lock, flags);
 
-       mii_check_media(&cp->mii_if, netif_msg_link(cp), FALSE);
+       mii_check_media(&cp->mii_if, netif_msg_link(cp), false);
 
        spin_unlock_irqrestore (&cp->lock, flags);
 
index a844b1fe2dc45d29af24e6c7803af5e152e28976..327eaa7b4999183dee5ad600dc56b29efbbed787 100644 (file)
@@ -931,7 +931,6 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
        int i, addr_len, option;
        void __iomem *ioaddr;
        static int board_idx = -1;
-       u8 pci_rev;
 
        assert (pdev != NULL);
        assert (ent != NULL);
@@ -949,13 +948,11 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
        }
 #endif
 
-       pci_read_config_byte(pdev, PCI_REVISION_ID, &pci_rev);
-
        if (pdev->vendor == PCI_VENDOR_ID_REALTEK &&
-           pdev->device == PCI_DEVICE_ID_REALTEK_8139 && pci_rev >= 0x20) {
+           pdev->device == PCI_DEVICE_ID_REALTEK_8139 && pdev->revision >= 0x20) {
                dev_info(&pdev->dev,
                           "This (id %04x:%04x rev %02x) is an enhanced 8139C+ chip\n",
-                          pdev->vendor, pdev->device, pci_rev);
+                          pdev->vendor, pdev->device, pdev->revision);
                dev_info(&pdev->dev,
                           "Use the \"8139cp\" driver for improved performance and stability.\n");
        }
@@ -2017,7 +2014,7 @@ no_early_rx:
 #if RX_BUF_IDX == 3
                        wrap_copy(skb, rx_ring, ring_offset+4, pkt_size);
 #else
-                       eth_copy_and_sum (skb, &rx_ring[ring_offset + 4], pkt_size, 0);
+                       skb_copy_to_linear_data (skb, &rx_ring[ring_offset + 4], pkt_size);
 #endif
                        skb_put (skb, pkt_size);
 
index 414de5bd228fae2dd1a2e3615ee4741d7f47aeee..04ddec0f4c61a4ed98d8f37d49df59daf8c7ee42 100644 (file)
@@ -73,6 +73,9 @@ struct ei_device {
        u32 *reg_offset;                /* Register mapping table */
        spinlock_t page_lock;           /* Page register locks */
        unsigned long priv;             /* Private field to store bus IDs etc. */
+#ifdef AX88796_PLATFORM
+       unsigned char rxcr_base;        /* default value for RXCR */
+#endif
 };
 
 /* The maximum number of 8390 interrupt service routines called per IRQ. */
@@ -86,11 +89,19 @@ struct ei_device {
 /* Some generic ethernet register configurations. */
 #define E8390_TX_IRQ_MASK      0xa     /* For register EN0_ISR */
 #define E8390_RX_IRQ_MASK      0x5
+
+#ifdef AX88796_PLATFORM
+#define E8390_RXCONFIG         (ei_status.rxcr_base | 0x04)
+#define E8390_RXOFF            (ei_status.rxcr_base | 0x20)
+#else
 #define E8390_RXCONFIG         0x4     /* EN0_RXCR: broadcasts, no multicast,errors */
 #define E8390_RXOFF            0x20    /* EN0_RXCR: Accept no packets */
+#endif
+
 #define E8390_TXCONFIG         0x00    /* EN0_TXCR: Normal transmit mode */
 #define E8390_TXOFF            0x02    /* EN0_TXCR: Transmitter off */
 
+
 /*  Register accessed at EN_CMD, the 8390 base addr.  */
 #define E8390_STOP     0x01    /* Stop and reset the chip */
 #define E8390_START    0x02    /* Start the chip, clear reset */
index b49375abb5f4d2c3349da24ddd9706eccba9b8e9..ba314adf68b86ecf856a6ebecada8c2ef019feb9 100644 (file)
@@ -3,10 +3,7 @@
 # Network device configuration
 #
 
-menu "Network device support"
-       depends on NET
-
-config NETDEVICES
+menuconfig NETDEVICES
        default y if UML
        bool "Network device support"
        ---help---
@@ -28,6 +25,14 @@ config NETDEVICES
 # that for each of the symbols.
 if NETDEVICES
 
+config NETDEVICES_MULTIQUEUE
+       bool "Netdevice multiple hardware queue support"
+       ---help---
+         Say Y here if you want to allow the network stack to use multiple
+         hardware TX queues on an ethernet device.
+
+         Most people will say N here.
+
 config IFB
        tristate "Intermediate Functional Block support"
        depends on NET_CLS_ACT
@@ -151,11 +156,9 @@ source "drivers/net/phy/Kconfig"
 #      Ethernet
 #
 
-menu "Ethernet (10 or 100Mbit)"
-       depends on !UML
-
-config NET_ETHERNET
+menuconfig NET_ETHERNET
        bool "Ethernet (10 or 100Mbit)"
+       depends on !UML
        ---help---
          Ethernet (also called IEEE 802.3 or ISO 8802-2) is the most common
          type of Local Area Network (LAN) in universities and companies.
@@ -180,9 +183,10 @@ config NET_ETHERNET
          kernel: saying N will just cause the configurator to skip all
          the questions about Ethernet network cards. If unsure, say N.
 
+if NET_ETHERNET
+
 config MII
        tristate "Generic Media Independent Interface device support"
-       depends on NET_ETHERNET
        help
          Most ethernet controllers have MII transceiver either as an external
          or internal device.  It is safe to say Y or M here even if your
@@ -190,7 +194,7 @@ config MII
 
 config MACB
        tristate "Atmel MACB support"
-       depends on NET_ETHERNET && (AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263)
+       depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263
        select MII
        help
          The Atmel MACB ethernet interface is found on many AT32 and AT91
@@ -201,9 +205,18 @@ config MACB
 
 source "drivers/net/arm/Kconfig"
 
+config AX88796
+       tristate "ASIX AX88796 NE2000 clone support"
+       depends on ARM || MIPS
+       select CRC32
+       select MII
+       help
+         AX88796 driver, using platform bus to provide
+         chip detection and resources
+
 config MACE
        tristate "MACE (Power Mac ethernet) support"
-       depends on NET_ETHERNET && PPC_PMAC && PPC32
+       depends on PPC_PMAC && PPC32
        select CRC32
        help
          Power Macintoshes and clones with Ethernet built-in on the
@@ -226,7 +239,7 @@ config MACE_AAUI_PORT
 
 config BMAC
        tristate "BMAC (G3 ethernet) support"
-       depends on NET_ETHERNET && PPC_PMAC && PPC32
+       depends on PPC_PMAC && PPC32
        select CRC32
        help
          Say Y for support of BMAC Ethernet interfaces. These are used on G3
@@ -237,7 +250,7 @@ config BMAC
 
 config ARIADNE
        tristate "Ariadne support"
-       depends on NET_ETHERNET && ZORRO
+       depends on ZORRO
        help
          If you have a Village Tronic Ariadne Ethernet adapter, say Y.
          Otherwise, say N.
@@ -247,7 +260,7 @@ config ARIADNE
 
 config A2065
        tristate "A2065 support"
-       depends on NET_ETHERNET && ZORRO
+       depends on ZORRO
        select CRC32
        help
          If you have a Commodore A2065 Ethernet adapter, say Y. Otherwise,
@@ -258,7 +271,7 @@ config A2065
 
 config HYDRA
        tristate "Hydra support"
-       depends on NET_ETHERNET && ZORRO
+       depends on ZORRO
        select CRC32
        help
          If you have a Hydra Ethernet adapter, say Y. Otherwise, say N.
@@ -268,7 +281,7 @@ config HYDRA
 
 config ZORRO8390
        tristate "Zorro NS8390-based Ethernet support"
-       depends on NET_ETHERNET && ZORRO
+       depends on ZORRO
        select CRC32
        help
          This driver is for Zorro Ethernet cards using an NS8390-compatible
@@ -281,7 +294,7 @@ config ZORRO8390
 
 config APNE
        tristate "PCMCIA NE2000 support"
-       depends on NET_ETHERNET && AMIGA_PCMCIA
+       depends on AMIGA_PCMCIA
        select CRC32
        help
          If you have a PCMCIA NE2000 compatible adapter, say Y.  Otherwise,
@@ -292,7 +305,7 @@ config APNE
 
 config APOLLO_ELPLUS
        tristate "Apollo 3c505 support"
-       depends on NET_ETHERNET && APOLLO
+       depends on APOLLO
        help
          Say Y or M here if your Apollo has a 3Com 3c505 ISA Ethernet card.
          If you don't have one made for Apollos, you can use one from a PC,
@@ -301,7 +314,7 @@ config APOLLO_ELPLUS
 
 config MAC8390
        bool "Macintosh NS 8390 based ethernet cards"
-       depends on NET_ETHERNET && MAC
+       depends on MAC
        select CRC32
        help
          If you want to include a driver to support Nubus or LC-PDS
@@ -311,7 +324,7 @@ config MAC8390
 
 config MAC89x0
        tristate "Macintosh CS89x0 based ethernet cards"
-       depends on NET_ETHERNET && MAC
+       depends on MAC
        ---help---
          Support for CS89x0 chipset based Ethernet cards.  If you have a
          Nubus or LC-PDS network (Ethernet) card of this type, say Y and
@@ -324,7 +337,7 @@ config MAC89x0
 
 config MACSONIC
        tristate "Macintosh SONIC based ethernet (onboard, NuBus, LC, CS)"
-       depends on NET_ETHERNET && MAC
+       depends on MAC
        ---help---
          Support for NatSemi SONIC based Ethernet devices.  This includes
          the onboard Ethernet in many Quadras as well as some LC-PDS,
@@ -338,7 +351,7 @@ config MACSONIC
 
 config MACMACE
        bool "Macintosh (AV) onboard MACE ethernet"
-       depends on NET_ETHERNET && MAC
+       depends on MAC
        select CRC32
        help
          Support for the onboard AMD 79C940 MACE Ethernet controller used in
@@ -348,7 +361,7 @@ config MACMACE
 
 config MVME147_NET
        tristate "MVME147 (Lance) Ethernet support"
-       depends on NET_ETHERNET && MVME147
+       depends on MVME147
        select CRC32
        help
          Support for the on-board Ethernet interface on the Motorola MVME147
@@ -358,7 +371,7 @@ config MVME147_NET
 
 config MVME16x_NET
        tristate "MVME16x Ethernet support"
-       depends on NET_ETHERNET && MVME16x
+       depends on MVME16x
        help
          This is the driver for the Ethernet interface on the Motorola
          MVME162, 166, 167, 172 and 177 boards.  Say Y here to include the
@@ -367,7 +380,7 @@ config MVME16x_NET
 
 config BVME6000_NET
        tristate "BVME6000 Ethernet support"
-       depends on NET_ETHERNET && BVME6000
+       depends on BVME6000
        help
          This is the driver for the Ethernet interface on BVME4000 and
          BVME6000 VME boards.  Say Y here to include the driver for this chip
@@ -376,7 +389,7 @@ config BVME6000_NET
 
 config ATARILANCE
        tristate "Atari Lance support"
-       depends on NET_ETHERNET && ATARI
+       depends on ATARI
        help
          Say Y to include support for several Atari Ethernet adapters based
          on the AMD Lance chipset: RieblCard (with or without battery), or
@@ -384,7 +397,7 @@ config ATARILANCE
 
 config ATARI_BIONET
        tristate "BioNet-100 support"
-       depends on NET_ETHERNET && ATARI && ATARI_ACSI && BROKEN
+       depends on ATARI && ATARI_ACSI && BROKEN
        help
          Say Y to include support for BioData's BioNet-100 Ethernet adapter
          for the ACSI port. The driver works (has to work...) with a polled
@@ -392,7 +405,7 @@ config ATARI_BIONET
 
 config ATARI_PAMSNET
        tristate "PAMsNet support"
-       depends on NET_ETHERNET && ATARI && ATARI_ACSI && BROKEN
+       depends on ATARI && ATARI_ACSI && BROKEN
        help
          Say Y to include support for the PAMsNet Ethernet adapter for the
          ACSI port ("ACSI node"). The driver works (has to work...) with a
@@ -400,7 +413,7 @@ config ATARI_PAMSNET
 
 config SUN3LANCE
        tristate "Sun3/Sun3x on-board LANCE support"
-       depends on NET_ETHERNET && (SUN3 || SUN3X)
+       depends on SUN3 || SUN3X
        help
          Most Sun3 and Sun3x motherboards (including the 3/50, 3/60 and 3/80)
          featured an AMD Lance 10Mbit Ethernet controller on board; say Y
@@ -413,7 +426,7 @@ config SUN3LANCE
 
 config SUN3_82586
        bool "Sun3 on-board Intel 82586 support"
-       depends on NET_ETHERNET && SUN3
+       depends on SUN3
        help
          This driver enables support for the on-board Intel 82586 based
          Ethernet adapter found on Sun 3/1xx and 3/2xx motherboards.  Note
@@ -422,7 +435,7 @@ config SUN3_82586
 
 config HPLANCE
        bool "HP on-board LANCE support"
-       depends on NET_ETHERNET && DIO
+       depends on DIO
        select CRC32
        help
          If you want to use the builtin "LANCE" Ethernet controller on an
@@ -430,21 +443,28 @@ config HPLANCE
 
 config LASI_82596
        tristate "Lasi ethernet"
-       depends on NET_ETHERNET && GSC
+       depends on GSC
        help
          Say Y here to support the builtin Intel 82596 ethernet controller
          found in Hewlett-Packard PA-RISC machines with 10Mbit ethernet.
 
+config SNI_82596
+       tristate "SNI RM ethernet"
+       depends on NET_ETHERNET && SNI_RM
+       help
+         Say Y here to support the on-board Intel 82596 ethernet controller
+         built into SNI RM machines.
+
 config MIPS_JAZZ_SONIC
        tristate "MIPS JAZZ onboard SONIC Ethernet support"
-       depends on NET_ETHERNET && MACH_JAZZ
+       depends on MACH_JAZZ
        help
          This is the driver for the onboard card of MIPS Magnum 4000,
          Acer PICA, Olivetti M700-10 and a few other identical OEM systems.
 
 config MIPS_AU1X00_ENET
        bool "MIPS AU1000 Ethernet support"
-       depends on NET_ETHERNET && SOC_AU1X00
+       depends on SOC_AU1X00
        select PHYLIB
        select CRC32
        help
@@ -453,11 +473,11 @@ config MIPS_AU1X00_ENET
 
 config NET_SB1250_MAC
        tristate "SB1250 Ethernet support"
-       depends on NET_ETHERNET && SIBYTE_SB1xxx_SOC
+       depends on SIBYTE_SB1xxx_SOC
 
 config SGI_IOC3_ETH
        bool "SGI IOC3 Ethernet"
-       depends on NET_ETHERNET && PCI && SGI_IP27
+       depends on PCI && SGI_IP27
        select CRC32
        select MII
        help
@@ -487,7 +507,7 @@ config SGI_IOC3_ETH_HW_TX_CSUM
 
 config MIPS_SIM_NET
        tristate "MIPS simulator Network device"
-       depends on NET_ETHERNET && MIPS_SIM
+       depends on MIPS_SIM
        help
          The MIPSNET device is a simple Ethernet network device which is
          emulated by the MIPS Simulator.
@@ -495,11 +515,11 @@ config MIPS_SIM_NET
 
 config SGI_O2MACE_ETH
        tristate "SGI O2 MACE Fast Ethernet support"
-       depends on NET_ETHERNET && SGI_IP32=y
+       depends on SGI_IP32=y
 
 config STNIC
        tristate "National DP83902AV  support"
-       depends on NET_ETHERNET && SUPERH
+       depends on SUPERH
        select CRC32
        help
          Support for cards based on the National Semiconductor DP83902AV
@@ -511,7 +531,7 @@ config STNIC
 
 config SUNLANCE
        tristate "Sun LANCE support"
-       depends on NET_ETHERNET && SBUS
+       depends on SBUS
        select CRC32
        help
          This driver supports the "le" interface present on all 32-bit Sparc
@@ -524,7 +544,7 @@ config SUNLANCE
 
 config HAPPYMEAL
        tristate "Sun Happy Meal 10/100baseT support"
-       depends on NET_ETHERNET && (SBUS || PCI)
+       depends on SBUS || PCI
        select CRC32
        help
          This driver supports the "hme" interface present on most Ultra
@@ -537,7 +557,7 @@ config HAPPYMEAL
 
 config SUNBMAC
        tristate "Sun BigMAC 10/100baseT support (EXPERIMENTAL)"
-       depends on NET_ETHERNET && SBUS && EXPERIMENTAL
+       depends on SBUS && EXPERIMENTAL
        select CRC32
        help
          This driver supports the "be" interface available as an Sbus option.
@@ -548,7 +568,7 @@ config SUNBMAC
 
 config SUNQE
        tristate "Sun QuadEthernet support"
-       depends on NET_ETHERNET && SBUS
+       depends on SBUS
        select CRC32
        help
          This driver supports the "qe" 10baseT Ethernet device, available as
@@ -560,7 +580,7 @@ config SUNQE
 
 config SUNGEM
        tristate "Sun GEM support"
-       depends on NET_ETHERNET && PCI
+       depends on PCI
        select CRC32
        help
          Support for the Sun GEM chip, aka Sun GigabitEthernet/P 2.0.  See also
@@ -568,7 +588,7 @@ config SUNGEM
 
 config CASSINI
        tristate "Sun Cassini support"
-       depends on NET_ETHERNET && PCI
+       depends on PCI
        select CRC32
        help
          Support for the Sun Cassini chip, aka Sun GigaSwift Ethernet. See also
@@ -576,7 +596,7 @@ config CASSINI
 
 config NET_VENDOR_3COM
        bool "3COM cards"
-       depends on NET_ETHERNET && (ISA || EISA || MCA || PCI)
+       depends on ISA || EISA || MCA || PCI
        help
          If you have a network (Ethernet) card belonging to this class, say Y
          and read the Ethernet-HOWTO, available from
@@ -736,7 +756,7 @@ config TYPHOON
 
 config LANCE
        tristate "AMD LANCE and PCnet (AT1500 and NE2100) support"
-       depends on NET_ETHERNET && ISA && ISA_DMA_API
+       depends on ISA && ISA_DMA_API
        help
          If you have a network (Ethernet) card of this type, say Y and read
          the Ethernet-HOWTO, available from
@@ -748,7 +768,7 @@ config LANCE
 
 config NET_VENDOR_SMC
        bool "Western Digital/SMC cards"
-       depends on NET_ETHERNET && (ISA || MCA || EISA || MAC)
+       depends on ISA || MCA || EISA || MAC
        help
          If you have a network (Ethernet) card belonging to this class, say Y
          and read the Ethernet-HOWTO, available from
@@ -818,11 +838,27 @@ config ULTRA32
          <file:Documentation/networking/net-modules.txt>. The module
          will be called smc-ultra32.
 
+config SMC9194
+       tristate "SMC 9194 support"
+       depends on NET_VENDOR_SMC && (ISA || MAC && BROKEN)
+       select CRC32
+       ---help---
+         This is support for the SMC9xxx based Ethernet cards. Choose this
+         option if you have a DELL laptop with the docking station, or
+         another SMC9192/9194 based chipset.  Say Y if you want it compiled
+         into the kernel, and read the file
+         <file:Documentation/networking/smc9.txt> and the Ethernet-HOWTO,
+         available from <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here and read
+         <file:Documentation/networking/net-modules.txt>. The module
+         will be called smc9194.
+
 config SMC91X
        tristate "SMC 91C9x/91C1xxx support"
        select CRC32
        select MII
-       depends on NET_ETHERNET && (ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH || SOC_AU1X00 || BFIN)
+       depends on ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH || SOC_AU1X00 || BFIN
        help
          This is a driver for SMC's 91x series of Ethernet chipsets,
          including the SMC91C94 and the SMC91C111. Say Y if you want it
@@ -836,26 +872,10 @@ config SMC91X
          module, say M here and read <file:Documentation/kbuild/modules.txt>
          as well as <file:Documentation/networking/net-modules.txt>.
 
-config SMC9194
-       tristate "SMC 9194 support"
-       depends on NET_VENDOR_SMC && (ISA || MAC && BROKEN)
-       select CRC32
-       ---help---
-         This is support for the SMC9xxx based Ethernet cards. Choose this
-         option if you have a DELL laptop with the docking station, or
-         another SMC9192/9194 based chipset.  Say Y if you want it compiled
-         into the kernel, and read the file
-         <file:Documentation/networking/smc9.txt> and the Ethernet-HOWTO,
-         available from <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
-         will be called smc9194.
-
 config NET_NETX
        tristate "NetX Ethernet support"
        select MII
-       depends on NET_ETHERNET && ARCH_NETX
+       depends on ARCH_NETX
        help
          This is support for the Hilscher netX builtin Ethernet ports
 
@@ -865,7 +885,7 @@ config NET_NETX
 
 config DM9000
        tristate "DM9000 support"
-       depends on (ARM || MIPS) && NET_ETHERNET
+       depends on ARM || BLACKFIN || MIPS
        select CRC32
        select MII
        ---help---
@@ -879,7 +899,7 @@ config SMC911X
        tristate "SMSC LAN911[5678] support"
        select CRC32
        select MII
-       depends on NET_ETHERNET && ARCH_PXA
+       depends on ARCH_PXA
        help
          This is a driver for SMSC's LAN911x series of Ethernet chipsets
          including the new LAN9115, LAN9116, LAN9117, and LAN9118.
@@ -893,7 +913,7 @@ config SMC911X
 
 config NET_VENDOR_RACAL
        bool "Racal-Interlan (Micom) NI cards"
-       depends on NET_ETHERNET && ISA
+       depends on ISA
        help
          If you have a network (Ethernet) card belonging to this class, such
          as the NI5010, NI5210 or NI6210, say Y and read the Ethernet-HOWTO,
@@ -945,7 +965,7 @@ source "drivers/net/tulip/Kconfig"
 
 config AT1700
        tristate "AT1700/1720 support (EXPERIMENTAL)"
-       depends on NET_ETHERNET && (ISA || MCA_LEGACY) && EXPERIMENTAL
+       depends on (ISA || MCA_LEGACY) && EXPERIMENTAL
        select CRC32
        ---help---
          If you have a network (Ethernet) card of this type, say Y and read
@@ -958,7 +978,7 @@ config AT1700
 
 config DEPCA
        tristate "DEPCA, DE10x, DE200, DE201, DE202, DE422 support"
-       depends on NET_ETHERNET && (ISA || EISA || MCA)
+       depends on ISA || EISA || MCA
        select CRC32
        ---help---
          If you have a network (Ethernet) card of this type, say Y and read
@@ -972,7 +992,7 @@ config DEPCA
 
 config HP100
        tristate "HP 10/100VG PCLAN (ISA, EISA, PCI) support"
-       depends on NET_ETHERNET && (ISA || EISA || PCI)
+       depends on ISA || EISA || PCI
        help
          If you have a network (Ethernet) card of this type, say Y and read
          the Ethernet-HOWTO, available from
@@ -984,7 +1004,7 @@ config HP100
 
 config NET_ISA
        bool "Other ISA cards"
-       depends on NET_ETHERNET && ISA
+       depends on ISA
        ---help---
          If your network (Ethernet) card hasn't been mentioned yet and its
          bus system (that's the way the cards talks to the other components
@@ -1147,7 +1167,7 @@ config SEEQ8005
 
 config NE2_MCA
        tristate "NE/2 (ne2000 MCA version) support"
-       depends on NET_ETHERNET && MCA_LEGACY
+       depends on MCA_LEGACY
        select CRC32
        help
          If you have a network (Ethernet) card of this type, say Y and read
@@ -1160,7 +1180,7 @@ config NE2_MCA
 
 config IBMLANA
        tristate "IBM LAN Adapter/A support"
-       depends on NET_ETHERNET && MCA && MCA_LEGACY
+       depends on MCA && MCA_LEGACY
        ---help---
          This is a Micro Channel Ethernet adapter.  You need to set
          CONFIG_MCA to use this driver.  It is both available as an in-kernel
@@ -1176,7 +1196,7 @@ config IBMLANA
 
 config IBMVETH
        tristate "IBM LAN Virtual Ethernet support"
-       depends on NET_ETHERNET && PPC_PSERIES
+       depends on PPC_PSERIES
        ---help---
          This driver supports virtual ethernet adapters on newer IBM iSeries
          and pSeries systems.
@@ -1257,7 +1277,7 @@ config IBM_EMAC_TAH
 
 config NET_PCI
        bool "EISA, VLB, PCI and on board controllers"
-       depends on NET_ETHERNET && (ISA || EISA || PCI)
+       depends on ISA || EISA || PCI
        help
          This is another class of network cards which attach directly to the
          bus. If you have one of those, say Y and read the Ethernet-HOWTO,
@@ -1313,6 +1333,7 @@ config AMD8111_ETH
          To compile this driver as a module, choose M here and read
          <file:Documentation/networking/net-modules.txt>. The module
          will be called amd8111e.
+
 config AMD8111E_NAPI
        bool "Enable NAPI support"
        depends on AMD8111_ETH
@@ -1778,7 +1799,7 @@ config SC92031
 
 config NET_POCKET
        bool "Pocket and portable adapters"
-       depends on NET_ETHERNET && PARPORT
+       depends on PARPORT
        ---help---
          Cute little network (Ethernet) devices which attach to the parallel
          port ("pocket adapters"), commonly used with laptops. If you have
@@ -1847,14 +1868,14 @@ config DE620
 
 config SGISEEQ
        tristate "SGI Seeq ethernet controller support"
-       depends on NET_ETHERNET && SGI_IP22
+       depends on SGI_IP22
        help
          Say Y here if you have an Seeq based Ethernet network card. This is
          used in many Silicon Graphics machines.
 
 config DECLANCE
        tristate "DEC LANCE ethernet controller support"
-       depends on NET_ETHERNET && MACH_DECSTATION
+       depends on MACH_DECSTATION
        select CRC32
        help
          This driver is for the series of Ethernet controllers produced by
@@ -1884,7 +1905,7 @@ config FEC2
 
 config NE_H8300
        tristate "NE2000 compatible support for H8/300"
-       depends on H8300 && NET_ETHERNET
+       depends on H8300
        help
          Say Y here if you want to use the NE2000 compatible
          controller on the Renesas H8/300 processor.
@@ -1892,7 +1913,7 @@ config NE_H8300
 source "drivers/net/fec_8xx/Kconfig"
 source "drivers/net/fs_enet/Kconfig"
 
-endmenu
+endif # NET_ETHERNET
 
 #
 #      Gigabit Ethernet
@@ -2101,7 +2122,7 @@ config SKGE
          with better performance and more complete ethtool support.
 
          It does not support the link failover and network management 
-         features that "portable" vendor supplied sk98lin driver does.
+         features available in the hardware.
 
          This driver supports adapters based on the original Yukon chipset:
          Marvell 88E8001, Belkin F5D5005, CNet GigaCard, DLink DGE-530T,
@@ -2114,7 +2135,7 @@ config SKGE
          will be called skge.  This is recommended.
 
 config SKY2
-       tristate "SysKonnect Yukon2 support (EXPERIMENTAL)"
+       tristate "SysKonnect Yukon2 support"
        depends on PCI
        select CRC32
        ---help---
@@ -2129,92 +2150,15 @@ config SKY2
          To compile this driver as a module, choose M here: the module
          will be called sky2.  This is recommended.
 
-config SK98LIN
-       tristate "Marvell Yukon Chipset / SysKonnect SK-98xx Support (DEPRECATED)"
-       depends on PCI
-       ---help---
-         Say Y here if you have a Marvell Yukon or SysKonnect SK-98xx/SK-95xx
-         compliant Gigabit Ethernet Adapter.
+config SKY2_DEBUG
+       bool "Debugging interface"
+       depends on SKY2 && DEBUG_FS
+       help
+        This option adds the ability to dump driver state for debugging.
+        The file debugfs/sky2/ethX displays the state of the internal
+        transmit and receive rings.
 
-         This driver supports the original Yukon chipset. This driver is
-         deprecated and will be removed from the kernel in the near future,
-         it has been replaced by the skge driver. skge is cleaner and
-         seems to work better.
-
-         This driver does not support the newer Yukon2 chipset. A separate
-         driver, sky2, is provided to support Yukon2-based adapters.
-
-         The following adapters are supported by this driver:
-           - 3Com 3C940 Gigabit LOM Ethernet Adapter
-           - 3Com 3C941 Gigabit LOM Ethernet Adapter
-           - Allied Telesyn AT-2970LX Gigabit Ethernet Adapter
-           - Allied Telesyn AT-2970LX/2SC Gigabit Ethernet Adapter
-           - Allied Telesyn AT-2970SX Gigabit Ethernet Adapter
-           - Allied Telesyn AT-2970SX/2SC Gigabit Ethernet Adapter
-           - Allied Telesyn AT-2970TX Gigabit Ethernet Adapter
-           - Allied Telesyn AT-2970TX/2TX Gigabit Ethernet Adapter
-           - Allied Telesyn AT-2971SX Gigabit Ethernet Adapter
-           - Allied Telesyn AT-2971T Gigabit Ethernet Adapter
-           - Belkin Gigabit Desktop Card 10/100/1000Base-T Adapter, Copper RJ-45
-           - EG1032 v2 Instant Gigabit Network Adapter
-           - EG1064 v2 Instant Gigabit Network Adapter
-           - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Abit)
-           - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Albatron)
-           - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Asus)
-           - Marvell 88E8001 Gigabit LOM Ethernet Adapter (ECS)
-           - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Epox)
-           - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Foxconn)
-           - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Gigabyte)
-           - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Iwill)
-           - Marvell 88E8050 Gigabit LOM Ethernet Adapter (Intel)
-           - Marvell RDK-8001 Adapter
-           - Marvell RDK-8002 Adapter
-           - Marvell RDK-8003 Adapter
-           - Marvell RDK-8004 Adapter
-           - Marvell RDK-8006 Adapter
-           - Marvell RDK-8007 Adapter
-           - Marvell RDK-8008 Adapter
-           - Marvell RDK-8009 Adapter
-           - Marvell RDK-8010 Adapter
-           - Marvell RDK-8011 Adapter
-           - Marvell RDK-8012 Adapter
-           - Marvell RDK-8052 Adapter
-           - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (32 bit)
-           - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (64 bit)
-           - N-Way PCI-Bus Giga-Card 1000/100/10Mbps(L)
-           - SK-9521 10/100/1000Base-T Adapter
-           - SK-9521 V2.0 10/100/1000Base-T Adapter
-           - SK-9821 Gigabit Ethernet Server Adapter (SK-NET GE-T)
-           - SK-9821 V2.0 Gigabit Ethernet 10/100/1000Base-T Adapter
-           - SK-9822 Gigabit Ethernet Server Adapter (SK-NET GE-T dual link)
-           - SK-9841 Gigabit Ethernet Server Adapter (SK-NET GE-LX)
-           - SK-9841 V2.0 Gigabit Ethernet 1000Base-LX Adapter
-           - SK-9842 Gigabit Ethernet Server Adapter (SK-NET GE-LX dual link)
-           - SK-9843 Gigabit Ethernet Server Adapter (SK-NET GE-SX)
-           - SK-9843 V2.0 Gigabit Ethernet 1000Base-SX Adapter
-           - SK-9844 Gigabit Ethernet Server Adapter (SK-NET GE-SX dual link)
-           - SK-9851 V2.0 Gigabit Ethernet 1000Base-SX Adapter
-           - SK-9861 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition)
-           - SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter
-           - SK-9862 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition dual link)
-           - SK-9871 Gigabit Ethernet Server Adapter (SK-NET GE-ZX)
-           - SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter
-           - SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link)
-           - SMC EZ Card 1000 (SMC9452TXV.2)
-         
-         The adapters support Jumbo Frames.
-         The dual link adapters support link-failover and dual port features.
-         Both Marvell Yukon and SysKonnect SK-98xx/SK-95xx adapters support 
-         the scatter-gather functionality with sendfile(). Please refer to 
-         <file:Documentation/networking/sk98lin.txt> for more information about
-         optional driver parameters.
-         Questions concerning this driver may be addressed to:
-             <linux@syskonnect.de>
-         
-         If you want to compile this driver as a module ( = code which can be
-         inserted in and removed from the running kernel whenever you want),
-         say M here and read <file:Documentation/kbuild/modules.txt>. The module will
-         be called sk98lin. This is recommended.
+        If unsure, say N.
 
 config VIA_VELOCITY
        tristate "VIA Velocity support"
@@ -2264,6 +2208,16 @@ config TSI108_ETH
             To compile this driver as a module, choose M here: the module
             will be called tsi108_eth.
 
+config GELIC_NET
+       tristate "PS3 Gigabit Ethernet driver"
+       depends on PPC_PS3
+       help
+         This driver supports the network device on the PS3 game
+         console.  This driver has built-in support for Ethernet.
+
+         To compile this driver as a module, choose M here: the
+         module will be called ps3_gelic.
+
 config GIANFAR
        tristate "Gianfar Ethernet"
        depends on 85xx || 83xx || PPC_86xx
@@ -2303,7 +2257,7 @@ config UGETH_TX_ON_DEMAND
 
 config MV643XX_ETH
        tristate "MV-643XX Ethernet support"
-       depends on MOMENCO_OCELOT_C || MOMENCO_JAGUAR_ATX || MV64360 || MV64X60 || MOMENCO_OCELOT_3 || (PPC_MULTIPLATFORM && PPC32)
+       depends on MV64360 || MV64X60 || (PPC_MULTIPLATFORM && PPC32)
        select MII
        help
          This driver supports the gigabit Ethernet on the Marvell MV643XX
@@ -2838,6 +2792,19 @@ config PPPOATM
          which can lead to bad results if the ATM peer loses state and
          changes its encapsulation unilaterally.
 
+config PPPOL2TP
+       tristate "PPP over L2TP (EXPERIMENTAL)"
+       depends on EXPERIMENTAL && PPP
+       help
+         Support for PPP-over-L2TP socket family. L2TP is a protocol
+         used by ISPs and enterprises to tunnel PPP traffic over UDP
+         tunnels. L2TP is replacing PPTP for VPN uses.
+
+         This kernel component handles only L2TP data packets: a
+         userland daemon handles L2TP the control protocol (tunnel
+         and session setup). One such daemon is OpenL2TP
+         (http://openl2tp.sourceforge.net/).
+
 config SLIP
        tristate "SLIP (serial line) support"
        ---help---
@@ -2948,8 +2915,6 @@ config NETCONSOLE
        If you want to log kernel messages over the network, enable this.
        See <file:Documentation/networking/netconsole.txt> for details.
 
-endif #NETDEVICES
-
 config NETPOLL
        def_bool NETCONSOLE
 
@@ -2961,4 +2926,4 @@ config NETPOLL_TRAP
 config NET_POLL_CONTROLLER
        def_bool NETPOLL
 
-endmenu
+endif # NETDEVICES
index a77affa4f6e66d33b707f0aeb71e6efaa23b6a46..a2241e6e145765a896d90eb91cdbe8b9b54b53f0 100644 (file)
@@ -60,10 +60,11 @@ obj-$(CONFIG_TIGON3) += tg3.o
 obj-$(CONFIG_BNX2) += bnx2.o
 spidernet-y += spider_net.o spider_net_ethtool.o
 obj-$(CONFIG_SPIDER_NET) += spidernet.o sungem_phy.o
+obj-$(CONFIG_GELIC_NET) += ps3_gelic.o
+ps3_gelic-objs += ps3_gelic_net.o
 obj-$(CONFIG_TC35815) += tc35815.o
 obj-$(CONFIG_SKGE) += skge.o
 obj-$(CONFIG_SKY2) += sky2.o
-obj-$(CONFIG_SK98LIN) += sk98lin/
 obj-$(CONFIG_SKFP) += skfp/
 obj-$(CONFIG_VIA_RHINE) += via-rhine.o
 obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o
@@ -107,6 +108,7 @@ obj-$(CONFIG_NET_SB1250_MAC) += sb1250-mac.o
 obj-$(CONFIG_B44) += b44.o
 obj-$(CONFIG_FORCEDETH) += forcedeth.o
 obj-$(CONFIG_NE_H8300) += ne-h8300.o
+obj-$(CONFIG_AX88796) += ax88796.o
 
 obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o
 obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o
@@ -119,6 +121,7 @@ obj-$(CONFIG_PPP_DEFLATE) += ppp_deflate.o
 obj-$(CONFIG_PPP_BSDCOMP) += bsd_comp.o
 obj-$(CONFIG_PPP_MPPE) += ppp_mppe.o
 obj-$(CONFIG_PPPOE) += pppox.o pppoe.o
+obj-$(CONFIG_PPPOL2TP) += pppox.o pppol2tp.o
 
 obj-$(CONFIG_SLIP) += slip.o
 obj-$(CONFIG_SLHC) += slhc.o
@@ -157,6 +160,7 @@ obj-$(CONFIG_ELPLUS) += 3c505.o
 obj-$(CONFIG_AC3200) += ac3200.o 8390.o
 obj-$(CONFIG_APRICOT) += 82596.o
 obj-$(CONFIG_LASI_82596) += lasi_82596.o
+obj-$(CONFIG_SNI_82596) += sni_82596.o
 obj-$(CONFIG_MVME16x_NET) += 82596.o
 obj-$(CONFIG_BVME6000_NET) += 82596.o
 obj-$(CONFIG_SC92031) += sc92031.o
index 81d5a374042a3a103f29d58d847963bccc70bef3..a45de6975bfe74735feacd88e71df684b6904017 100644 (file)
@@ -322,9 +322,9 @@ static int lance_rx (struct net_device *dev)
 
                        skb_reserve (skb, 2);           /* 16 byte align */
                        skb_put (skb, len);             /* make room */
-                       eth_copy_and_sum(skb,
+                       skb_copy_to_linear_data(skb,
                                         (unsigned char *)&(ib->rx_buf [lp->rx_new][0]),
-                                        len, 0);
+                                        len);
                        skb->protocol = eth_type_trans (skb, dev);
                        netif_rx (skb);
                        dev->last_rx = jiffies;
index 04382f979c996ef9834061c21ffe25399ad879e8..b78a4e5ceeb2825889439a7be1f7969767d7c311 100644 (file)
@@ -159,10 +159,6 @@ static struct pci_device_id acenic_pci_tbl[] = {
 };
 MODULE_DEVICE_TABLE(pci, acenic_pci_tbl);
 
-#ifndef SET_NETDEV_DEV
-#define SET_NETDEV_DEV(net, pdev)      do{} while(0)
-#endif
-
 #define ace_sync_irq(irq)      synchronize_irq(irq)
 
 #ifndef offset_in_page
index a241ae7855a309391e62db8e8b654dae6aaf8b38..bc5a38a6705f06df72d8452e555b0de6f008ade0 100644 (file)
@@ -746,7 +746,7 @@ static int ariadne_rx(struct net_device *dev)
 
            skb_reserve(skb,2);         /* 16 byte align */
            skb_put(skb,pkt_len);       /* Make room */
-           eth_copy_and_sum(skb, (char *)priv->rx_buff[entry], pkt_len,0);
+           skb_copy_to_linear_data(skb, (char *)priv->rx_buff[entry], pkt_len);
            skb->protocol=eth_type_trans(skb,dev);
 #if 0
            printk(KERN_DEBUG "RX pkt type 0x%04x from ",
index 678e4f48d36bf957b8e35630f3c428438fb37bd8..5bf2d33887aca4acf4f45dc3bdf893d2a335a4ba 100644 (file)
@@ -4,7 +4,7 @@
 #
 config ARM_AM79C961A
        bool "ARM EBSA110 AM79C961A support"
-       depends on NET_ETHERNET && ARM && ARCH_EBSA110
+       depends on ARM && ARCH_EBSA110
        select CRC32
        help
          If you wish to compile a kernel for the EBSA-110, then you should
@@ -12,21 +12,21 @@ config ARM_AM79C961A
 
 config ARM_ETHER1
        tristate "Acorn Ether1 support"
-       depends on NET_ETHERNET && ARM && ARCH_ACORN
+       depends on ARM && ARCH_ACORN
        help
          If you have an Acorn system with one of these (AKA25) network cards,
          you should say Y to this option if you wish to use it with Linux.
 
 config ARM_ETHER3
        tristate "Acorn/ANT Ether3 support"
-       depends on NET_ETHERNET && ARM && ARCH_ACORN
+       depends on ARM && ARCH_ACORN
        help
          If you have an Acorn system with one of these network cards, you
          should say Y to this option if you wish to use it with Linux.
 
 config ARM_ETHERH
        tristate "I-cubed EtherH/ANT EtherM support"
-       depends on NET_ETHERNET && ARM && ARCH_ACORN
+       depends on ARM && ARCH_ACORN
        select CRC32
        help
          If you have an Acorn system with one of these network cards, you
@@ -34,7 +34,7 @@ config ARM_ETHERH
 
 config ARM_AT91_ETHER
        tristate "AT91RM9200 Ethernet support"
-       depends on NET_ETHERNET && ARM && ARCH_AT91RM9200
+       depends on ARM && ARCH_AT91RM9200
        select MII
        help
          If you wish to compile a kernel for the AT91RM9200 and enable
@@ -42,7 +42,7 @@ config ARM_AT91_ETHER
 
 config EP93XX_ETH
        tristate "EP93xx Ethernet support"
-       depends on NET_ETHERNET && ARM && ARCH_EP93XX
+       depends on ARM && ARCH_EP93XX
        help
          This is a driver for the ethernet hardware included in EP93xx CPUs.
          Say Y if you are building a kernel for EP93xx based devices.
index 2438c5bff23730d084590fd0cbc0c236955d10dd..f6ece1d43f6e81494d6fd1ca6f1d45112882b15e 100644 (file)
@@ -258,7 +258,7 @@ static int ep93xx_rx(struct net_device *dev, int *budget)
                        skb_reserve(skb, 2);
                        dma_sync_single(NULL, ep->descs->rdesc[entry].buf_addr,
                                                length, DMA_FROM_DEVICE);
-                       eth_copy_and_sum(skb, ep->rx_buf[entry], length, 0);
+                       skb_copy_to_linear_data(skb, ep->rx_buf[entry], length);
                        skb_put(skb, length);
                        skb->protocol = eth_type_trans(skb, dev);
 
index 54714409a09b03d963ff881879687301aed5bc3e..f7356374a2e72de6d64920430f7c1a00e2711f4e 100644 (file)
@@ -295,10 +295,7 @@ int if_up = 0;
 /* Setup the DMA counter */
 
 static void
-setup_dma (address, rw_flag, num_blocks)
-       void *address;
-       unsigned rw_flag;
-       int num_blocks;
+setup_dma (void *address, unsigned rw_flag, int num_blocks)
 {
        WRITEMODE((unsigned) rw_flag          | DMA_FDC | SEC_COUNT | REG_ACSI |
                  A1);
@@ -317,9 +314,7 @@ setup_dma (address, rw_flag, num_blocks)
 /* Send the first byte of an command block */
 
 static int
-send_first (target, byte)
-       int target;
-       unsigned char byte;
+send_first (int target, unsigned char byte)
 {
        rw = READ;
        acsi_delay_end(COMMAND_DELAY);
@@ -338,10 +333,7 @@ send_first (target, byte)
 /* Send the rest of an command block */
 
 static int
-send_1_5 (lun, command, dma)
-       int lun;
-       unsigned char *command;
-       int dma;
+send_1_5 (int lun, unsigned char *command, int dma)
 {
        int i, j;
 
@@ -371,8 +363,7 @@ get_status (void)
 /* Calculate the number of received bytes */
 
 static int
-calc_received (start_address)
-       void *start_address;
+calc_received (void *start_address)
 {
        return (int)(
                (((unsigned long)DMAHIGH << 16) | ((unsigned)DMAMID << 8) | DMALOW)
@@ -384,8 +375,7 @@ calc_received (start_address)
 /* start() starts the PAM's DMA adaptor */
 
 static void
-start (target)
-       int target;
+start (int target)
 {
        send_first(target, START);
 }
@@ -393,8 +383,7 @@ start (target)
 /* stop() stops the PAM's DMA adaptor and returns a value of zero in case of success */
 
 static int
-stop (target)
-       int target;
+stop (int target)
 {
        int ret = -1;
        unsigned char cmd_buffer[5];
@@ -415,8 +404,7 @@ bad:
 /* testpkt() returns the number of received packets waiting in the queue */
 
 static int
-testpkt(target)
-       int target;
+testpkt(int target)
 {
        int ret = -1;
 
@@ -431,9 +419,7 @@ bad:
 /* Please note: The buffer is for internal use only but must be defined!   */
 
 static int
-inquiry (target, buffer)
-       int target;
-       unsigned char *buffer;
+inquiry (int target, unsigned char *buffer)
 {
        int ret = -1;
        unsigned char *vbuffer = phys_to_virt((unsigned long)buffer);
@@ -468,9 +454,7 @@ bad:
  */
 
 static HADDR
-*read_hw_addr(target, buffer)
-       int target;
-       unsigned char *buffer;
+*read_hw_addr(int target, unsigned char *buffer)
 {
        HADDR *ret = 0;
        unsigned char cmd_buffer[5];
@@ -491,9 +475,7 @@ bad:
 }
 
 static irqreturn_t
-pamsnet_intr(irq, data, fp)
-       int irq;
-       void *data;
+pamsnet_intr(int irq, void *data)
 {
        return IRQ_HANDLED;
 }
@@ -501,9 +483,7 @@ pamsnet_intr(irq, data, fp)
 /* receivepkt() loads a packet to a given buffer and returns its length */
 
 static int
-receivepkt (target, buffer)
-       int target;
-       unsigned char *buffer;
+receivepkt (int target, unsigned char *buffer)
 {
        int ret = -1;
        unsigned char cmd_buffer[5];
@@ -526,10 +506,7 @@ bad:
              successfully */
 
 static int
-sendpkt (target, buffer, length)
-       int target;
-       unsigned char *buffer;
-       int length;
+sendpkt (int target, unsigned char *buffer, int length)
 {
        int ret = -1;
        unsigned char cmd_buffer[5];
@@ -665,7 +642,8 @@ struct net_device * __init pamsnet_probe (int unit)
    there is non-reboot way to recover if something goes wrong.
  */
 static int
-pamsnet_open(struct net_device *dev) {
+pamsnet_open(struct net_device *dev)
+{
        struct net_local *lp = netdev_priv(dev);
 
        if (pamsnet_debug > 0)
@@ -694,7 +672,8 @@ pamsnet_open(struct net_device *dev) {
 }
 
 static int
-pamsnet_send_packet(struct sk_buff *skb, struct net_device *dev) {
+pamsnet_send_packet(struct sk_buff *skb, struct net_device *dev)
+{
        struct net_local *lp = netdev_priv(dev);
        unsigned long flags;
 
@@ -741,7 +720,8 @@ pamsnet_send_packet(struct sk_buff *skb, struct net_device *dev) {
 /* We have a good packet(s), get it/them out of the buffers.
  */
 static void
-pamsnet_poll_rx(struct net_device *dev) {
+pamsnet_poll_rx(struct net_device *dev)
+{
        struct net_local *lp = netdev_priv(dev);
        int boguscount;
        int pkt_len;
@@ -816,7 +796,8 @@ pamsnet_poll_rx(struct net_device *dev) {
  * passes them to the higher layers and restarts the timer.
  */
 static void
-pamsnet_tick(unsigned long data) {
+pamsnet_tick(unsigned long data)
+{
        struct net_device        *dev = (struct net_device *)data;
        struct net_local *lp = netdev_priv(dev);
 
@@ -832,7 +813,8 @@ pamsnet_tick(unsigned long data) {
 /* The inverse routine to pamsnet_open().
  */
 static int
-pamsnet_close(struct net_device *dev) {
+pamsnet_close(struct net_device *dev)
+{
        struct net_local *lp = netdev_priv(dev);
 
        if (pamsnet_debug > 0)
index b1c6034e68fa320ddd48fabec94374d403e09ae5..df4c1a0071aa37a141d3018e80198c1d13e5880e 100644 (file)
@@ -210,7 +210,6 @@ struct atl1_hw {
        u16 phy_spd_default;
 
        u16 dev_rev;
-       u8 revision_id;
 
        /* spi flash */
        u8 flash_vendor;
index 6862c11ff86408972ca124ab6813ee52fe497c0b..501919eb7f5eab6242f28c682448f6f348839ecd 100644 (file)
@@ -118,10 +118,6 @@ static int __devinit atl1_sw_init(struct atl1_adapter *adapter)
 {
        struct atl1_hw *hw = &adapter->hw;
        struct net_device *netdev = adapter->netdev;
-       struct pci_dev *pdev = adapter->pdev;
-
-       /* PCI config space info */
-       pci_read_config_byte(pdev, PCI_REVISION_ID, &hw->revision_id);
 
        hw->max_frame_size = netdev->mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
        hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE;
@@ -634,14 +630,13 @@ static void atl1_intr_tx(struct atl1_adapter *adapter)
        struct atl1_buffer *buffer_info;
        u16 sw_tpd_next_to_clean;
        u16 cmb_tpd_next_to_clean;
-       u8 update = 0;
 
        sw_tpd_next_to_clean = atomic_read(&tpd_ring->next_to_clean);
        cmb_tpd_next_to_clean = le16_to_cpu(adapter->cmb.cmb->tpd_cons_idx);
 
        while (cmb_tpd_next_to_clean != sw_tpd_next_to_clean) {
                struct tx_packet_desc *tpd;
-               update = 1;
+
                tpd = ATL1_TPD_DESC(tpd_ring, sw_tpd_next_to_clean);
                buffer_info = &tpd_ring->buffer_info[sw_tpd_next_to_clean];
                if (buffer_info->dma) {
index c27cfcef45fafeddec8cc4a4e1cf23844e61fe3c..e86b3691765b7721eff0947e91d92d5d396c1c57 100644 (file)
@@ -1205,8 +1205,8 @@ static int au1000_rx(struct net_device *dev)
                                continue;
                        }
                        skb_reserve(skb, 2);    /* 16 byte IP header align */
-                       eth_copy_and_sum(skb,
-                               (unsigned char *)pDB->vaddr, frmlen, 0);
+                       skb_copy_to_linear_data(skb,
+                               (unsigned char *)pDB->vaddr, frmlen);
                        skb_put(skb, frmlen);
                        skb->protocol = eth_type_trans(skb, dev);
                        netif_rx(skb);  /* pass the packet to upper layers */
diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c
new file mode 100644 (file)
index 0000000..d19874b
--- /dev/null
@@ -0,0 +1,952 @@
+/* drivers/net/ax88796.c
+ *
+ * Copyright 2005,2007 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Asix AX88796 10/100 Ethernet controller support
+ *     Based on ne.c, by Donald Becker, et-al.
+ *
+ * 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/errno.h>
+#include <linux/isapnp.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+
+#include <net/ax88796.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+
+static int phy_debug = 0;
+
+/* Rename the lib8390.c functions to show that they are in this driver */
+#define __ei_open       ax_ei_open
+#define __ei_close      ax_ei_close
+#define __ei_poll      ax_ei_poll
+#define __ei_tx_timeout ax_ei_tx_timeout
+#define __ei_interrupt  ax_ei_interrupt
+#define ____alloc_ei_netdev ax__alloc_ei_netdev
+#define __NS8390_init   ax_NS8390_init
+
+/* force unsigned long back to 'void __iomem *' */
+#define ax_convert_addr(_a) ((void __force __iomem *)(_a))
+
+#define ei_inb(_a)     readb(ax_convert_addr(_a))
+#define ei_outb(_v, _a) writeb(_v, ax_convert_addr(_a))
+
+#define ei_inb_p(_a)   ei_inb(_a)
+#define ei_outb_p(_v, _a) ei_outb(_v, _a)
+
+/* define EI_SHIFT() to take into account our register offsets */
+#define EI_SHIFT(x)     (ei_local->reg_offset[(x)])
+
+/* Ensure we have our RCR base value */
+#define AX88796_PLATFORM
+
+static unsigned char version[] = "ax88796.c: Copyright 2005,2007 Simtec Electronics\n";
+
+#include "lib8390.c"
+
+#define DRV_NAME "ax88796"
+#define DRV_VERSION "1.00"
+
+/* from ne.c */
+#define NE_CMD         EI_SHIFT(0x00)
+#define NE_RESET       EI_SHIFT(0x1f)
+#define NE_DATAPORT    EI_SHIFT(0x10)
+
+#define NE1SM_START_PG 0x20    /* First page of TX buffer */
+#define NE1SM_STOP_PG  0x40    /* Last page +1 of RX ring */
+#define NESM_START_PG  0x40    /* First page of TX buffer */
+#define NESM_STOP_PG   0x80    /* Last page +1 of RX ring */
+
+/* device private data */
+
+struct ax_device {
+       struct timer_list        mii_timer;
+       spinlock_t               mii_lock;
+       struct mii_if_info       mii;
+
+       u32                      msg_enable;
+       void __iomem            *map2;
+       struct platform_device  *dev;
+       struct resource         *mem;
+       struct resource         *mem2;
+       struct ax_plat_data     *plat;
+
+       unsigned char            running;
+       unsigned char            resume_open;
+
+       u32                      reg_offsets[0x20];
+};
+
+static inline struct ax_device *to_ax_dev(struct net_device *dev)
+{
+       struct ei_device *ei_local = netdev_priv(dev);
+       return (struct ax_device *)(ei_local+1);
+}
+
+/* ax_initial_check
+ *
+ * do an initial probe for the card to check wether it exists
+ * and is functional
+ */
+
+static int ax_initial_check(struct net_device *dev)
+{
+       struct ei_device *ei_local = netdev_priv(dev);
+       void __iomem *ioaddr = ei_local->mem;
+       int reg0;
+       int regd;
+
+       reg0 = ei_inb(ioaddr);
+       if (reg0 == 0xFF)
+               return -ENODEV;
+
+       ei_outb(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD);
+       regd = ei_inb(ioaddr + 0x0d);
+       ei_outb(0xff, ioaddr + 0x0d);
+       ei_outb(E8390_NODMA+E8390_PAGE0, ioaddr + E8390_CMD);
+       ei_inb(ioaddr + EN0_COUNTER0); /* Clear the counter by reading. */
+       if (ei_inb(ioaddr + EN0_COUNTER0) != 0) {
+               ei_outb(reg0, ioaddr);
+               ei_outb(regd, ioaddr + 0x0d);   /* Restore the old values. */
+               return -ENODEV;
+       }
+
+       return 0;
+}
+
+/* Hard reset the card.  This used to pause for the same period that a
+   8390 reset command required, but that shouldn't be necessary. */
+
+static void ax_reset_8390(struct net_device *dev)
+{
+       struct ei_device *ei_local = netdev_priv(dev);
+       unsigned long reset_start_time = jiffies;
+       void __iomem *addr = (void __iomem *)dev->base_addr;
+
+       if (ei_debug > 1)
+               printk(KERN_DEBUG "resetting the 8390 t=%ld...", jiffies);
+
+       ei_outb(ei_inb(addr + NE_RESET), addr + NE_RESET);
+
+       ei_status.txing = 0;
+       ei_status.dmaing = 0;
+
+       /* This check _should_not_ be necessary, omit eventually. */
+       while ((ei_inb(addr + EN0_ISR) & ENISR_RESET) == 0) {
+               if (jiffies - reset_start_time > 2*HZ/100) {
+                       printk(KERN_WARNING "%s: %s did not complete.\n",
+                              __FUNCTION__, dev->name);
+                       break;
+               }
+       }
+
+       ei_outb(ENISR_RESET, addr + EN0_ISR);   /* Ack intr. */
+}
+
+
+static void ax_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
+                           int ring_page)
+{
+       struct ei_device *ei_local = netdev_priv(dev);
+       void __iomem *nic_base = ei_local->mem;
+
+       /* This *shouldn't* happen. If it does, it's the last thing you'll see */
+       if (ei_status.dmaing) {
+               printk(KERN_EMERG "%s: DMAing conflict in %s [DMAstat:%d][irqlock:%d].\n",
+                       dev->name, __FUNCTION__,
+                      ei_status.dmaing, ei_status.irqlock);
+               return;
+       }
+
+       ei_status.dmaing |= 0x01;
+       ei_outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
+       ei_outb(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO);
+       ei_outb(0, nic_base + EN0_RCNTHI);
+       ei_outb(0, nic_base + EN0_RSARLO);              /* On page boundary */
+       ei_outb(ring_page, nic_base + EN0_RSARHI);
+       ei_outb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
+
+       if (ei_status.word16)
+               readsw(nic_base + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)>>1);
+       else
+               readsb(nic_base + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr));
+
+       ei_outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
+       ei_status.dmaing &= ~0x01;
+
+       le16_to_cpus(&hdr->count);
+}
+
+
+/* Block input and output, similar to the Crynwr packet driver.  If you
+   are porting to a new ethercard, look at the packet driver source for hints.
+   The NEx000 doesn't share the on-board packet memory -- you have to put
+   the packet out through the "remote DMA" dataport using ei_outb. */
+
+static void ax_block_input(struct net_device *dev, int count,
+                          struct sk_buff *skb, int ring_offset)
+{
+       struct ei_device *ei_local = netdev_priv(dev);
+       void __iomem *nic_base = ei_local->mem;
+       char *buf = skb->data;
+
+       if (ei_status.dmaing) {
+               printk(KERN_EMERG "%s: DMAing conflict in ax_block_input "
+                       "[DMAstat:%d][irqlock:%d].\n",
+                       dev->name, ei_status.dmaing, ei_status.irqlock);
+               return;
+       }
+
+       ei_status.dmaing |= 0x01;
+
+       ei_outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
+       ei_outb(count & 0xff, nic_base + EN0_RCNTLO);
+       ei_outb(count >> 8, nic_base + EN0_RCNTHI);
+       ei_outb(ring_offset & 0xff, nic_base + EN0_RSARLO);
+       ei_outb(ring_offset >> 8, nic_base + EN0_RSARHI);
+       ei_outb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
+
+       if (ei_status.word16) {
+               readsw(nic_base + NE_DATAPORT, buf, count >> 1);
+               if (count & 0x01)
+                       buf[count-1] = ei_inb(nic_base + NE_DATAPORT);
+
+       } else {
+               readsb(nic_base + NE_DATAPORT, buf, count);
+       }
+
+       ei_status.dmaing &= ~1;
+}
+
+static void ax_block_output(struct net_device *dev, int count,
+                           const unsigned char *buf, const int start_page)
+{
+       struct ei_device *ei_local = netdev_priv(dev);
+       void __iomem *nic_base = ei_local->mem;
+       unsigned long dma_start;
+
+       /* Round the count up for word writes.  Do we need to do this?
+          What effect will an odd byte count have on the 8390?
+          I should check someday. */
+
+       if (ei_status.word16 && (count & 0x01))
+               count++;
+
+       /* This *shouldn't* happen. If it does, it's the last thing you'll see */
+       if (ei_status.dmaing) {
+               printk(KERN_EMERG "%s: DMAing conflict in %s."
+                       "[DMAstat:%d][irqlock:%d]\n",
+                       dev->name, __FUNCTION__,
+                      ei_status.dmaing, ei_status.irqlock);
+               return;
+       }
+
+       ei_status.dmaing |= 0x01;
+       /* We should already be in page 0, but to be safe... */
+       ei_outb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD);
+
+       ei_outb(ENISR_RDC, nic_base + EN0_ISR);
+
+       /* Now the normal output. */
+       ei_outb(count & 0xff, nic_base + EN0_RCNTLO);
+       ei_outb(count >> 8,   nic_base + EN0_RCNTHI);
+       ei_outb(0x00, nic_base + EN0_RSARLO);
+       ei_outb(start_page, nic_base + EN0_RSARHI);
+
+       ei_outb(E8390_RWRITE+E8390_START, nic_base + NE_CMD);
+       if (ei_status.word16) {
+               writesw(nic_base + NE_DATAPORT, buf, count>>1);
+       } else {
+               writesb(nic_base + NE_DATAPORT, buf, count);
+       }
+
+       dma_start = jiffies;
+
+       while ((ei_inb(nic_base + EN0_ISR) & ENISR_RDC) == 0) {
+               if (jiffies - dma_start > 2*HZ/100) {           /* 20ms */
+                       printk(KERN_WARNING "%s: timeout waiting for Tx RDC.\n", dev->name);
+                       ax_reset_8390(dev);
+                       ax_NS8390_init(dev,1);
+                       break;
+               }
+       }
+
+       ei_outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
+       ei_status.dmaing &= ~0x01;
+       return;
+}
+
+/* definitions for accessing MII/EEPROM interface */
+
+#define AX_MEMR                        EI_SHIFT(0x14)
+#define AX_MEMR_MDC            (1<<0)
+#define AX_MEMR_MDIR           (1<<1)
+#define AX_MEMR_MDI            (1<<2)
+#define AX_MEMR_MDO            (1<<3)
+#define AX_MEMR_EECS           (1<<4)
+#define AX_MEMR_EEI            (1<<5)
+#define AX_MEMR_EEO            (1<<6)
+#define AX_MEMR_EECLK          (1<<7)
+
+/* ax_mii_ei_outbits
+ *
+ * write the specified set of bits to the phy
+*/
+
+static void
+ax_mii_ei_outbits(struct net_device *dev, unsigned int bits, int len)
+{
+       struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+       void __iomem *memr_addr = (void __iomem *)dev->base_addr + AX_MEMR;
+       unsigned int memr;
+
+       /* clock low, data to output mode */
+       memr = ei_inb(memr_addr);
+       memr &= ~(AX_MEMR_MDC | AX_MEMR_MDIR);
+       ei_outb(memr, memr_addr);
+
+       for (len--; len >= 0; len--) {
+               if (bits & (1 << len))
+                       memr |= AX_MEMR_MDO;
+               else
+                       memr &= ~AX_MEMR_MDO;
+
+               ei_outb(memr, memr_addr);
+
+               /* clock high */
+
+               ei_outb(memr | AX_MEMR_MDC, memr_addr);
+               udelay(1);
+
+               /* clock low */
+               ei_outb(memr, memr_addr);
+       }
+
+       /* leaves the clock line low, mdir input */
+       memr |= AX_MEMR_MDIR;
+       ei_outb(memr, (void __iomem *)dev->base_addr + AX_MEMR);
+}
+
+/* ax_phy_ei_inbits
+ *
+ * read a specified number of bits from the phy
+*/
+
+static unsigned int
+ax_phy_ei_inbits(struct net_device *dev, int no)
+{
+       struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+       void __iomem *memr_addr = (void __iomem *)dev->base_addr + AX_MEMR;
+       unsigned int memr;
+       unsigned int result = 0;
+
+       /* clock low, data to input mode */
+       memr = ei_inb(memr_addr);
+       memr &= ~AX_MEMR_MDC;
+       memr |= AX_MEMR_MDIR;
+       ei_outb(memr, memr_addr);
+
+       for (no--; no >= 0; no--) {
+               ei_outb(memr | AX_MEMR_MDC, memr_addr);
+
+               udelay(1);
+
+               if (ei_inb(memr_addr) & AX_MEMR_MDI)
+                       result |= (1<<no);
+
+               ei_outb(memr, memr_addr);
+       }
+
+       return result;
+}
+
+/* ax_phy_issueaddr
+ *
+ * use the low level bit shifting routines to send the address
+ * and command to the specified phy
+*/
+
+static void
+ax_phy_issueaddr(struct net_device *dev, int phy_addr, int reg, int opc)
+{
+       if (phy_debug)
+               pr_debug("%s: dev %p, %04x, %04x, %d\n",
+                       __FUNCTION__, dev, phy_addr, reg, opc);
+
+       ax_mii_ei_outbits(dev, 0x3f, 6);        /* pre-amble */
+       ax_mii_ei_outbits(dev, 1, 2);           /* frame-start */
+       ax_mii_ei_outbits(dev, opc, 2);         /* op code */
+       ax_mii_ei_outbits(dev, phy_addr, 5);    /* phy address */
+       ax_mii_ei_outbits(dev, reg, 5);         /* reg address */
+}
+
+static int
+ax_phy_read(struct net_device *dev, int phy_addr, int reg)
+{
+       struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+       unsigned long flags;
+       unsigned int result;
+
+       spin_lock_irqsave(&ei_local->page_lock, flags);
+
+       ax_phy_issueaddr(dev, phy_addr, reg, 2);
+
+       result = ax_phy_ei_inbits(dev, 17);
+       result &= ~(3<<16);
+
+       spin_unlock_irqrestore(&ei_local->page_lock, flags);
+
+       if (phy_debug)
+               pr_debug("%s: %04x.%04x => read %04x\n", __FUNCTION__,
+                        phy_addr, reg, result);
+
+       return result;
+}
+
+static void
+ax_phy_write(struct net_device *dev, int phy_addr, int reg, int value)
+{
+       struct ei_device *ei = (struct ei_device *) netdev_priv(dev);
+       unsigned long flags;
+
+       printk(KERN_DEBUG "%s: %p, %04x, %04x %04x\n",
+              __FUNCTION__, dev, phy_addr, reg, value);
+
+       spin_lock_irqsave(&ei->page_lock, flags);
+
+       ax_phy_issueaddr(dev, phy_addr, reg, 1);
+       ax_mii_ei_outbits(dev, 2, 2);           /* send TA */
+       ax_mii_ei_outbits(dev, value, 16);
+
+       spin_unlock_irqrestore(&ei->page_lock, flags);
+}
+
+static void ax_mii_expiry(unsigned long data)
+{
+       struct net_device *dev = (struct net_device *)data;
+       struct ax_device  *ax = to_ax_dev(dev);
+       unsigned long flags;
+
+       spin_lock_irqsave(&ax->mii_lock, flags);
+       mii_check_media(&ax->mii, netif_msg_link(ax), 0);
+       spin_unlock_irqrestore(&ax->mii_lock, flags);
+
+       if (ax->running) {
+               ax->mii_timer.expires = jiffies + HZ*2;
+               add_timer(&ax->mii_timer);
+       }
+}
+
+static int ax_open(struct net_device *dev)
+{
+       struct ax_device  *ax = to_ax_dev(dev);
+       struct ei_device *ei_local = netdev_priv(dev);
+       int ret;
+
+       dev_dbg(ax->dev, "%s: open\n", dev->name);
+
+       ret = request_irq(dev->irq, ax_ei_interrupt, 0, dev->name, dev);
+       if (ret)
+               return ret;
+
+       ret = ax_ei_open(dev);
+       if (ret)
+               return ret;
+
+       /* turn the phy on (if turned off) */
+
+       ei_outb(ax->plat->gpoc_val, ei_local->mem + EI_SHIFT(0x17));
+       ax->running = 1;
+
+       /* start the MII timer */
+
+       init_timer(&ax->mii_timer);
+
+       ax->mii_timer.expires  = jiffies+1;
+       ax->mii_timer.data     = (unsigned long) dev;
+       ax->mii_timer.function = ax_mii_expiry;
+
+       add_timer(&ax->mii_timer);
+
+       return 0;
+}
+
+static int ax_close(struct net_device *dev)
+{
+       struct ax_device *ax = to_ax_dev(dev);
+       struct ei_device *ei_local = netdev_priv(dev);
+
+       dev_dbg(ax->dev, "%s: close\n", dev->name);
+
+       /* turn the phy off */
+
+       ei_outb(ax->plat->gpoc_val | (1<<6),
+              ei_local->mem + EI_SHIFT(0x17));
+
+       ax->running = 0;
+       wmb();
+
+       del_timer_sync(&ax->mii_timer);
+       ax_ei_close(dev);
+
+       free_irq(dev->irq, dev);
+       return 0;
+}
+
+static int ax_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
+{
+       struct ax_device *ax = to_ax_dev(dev);
+       unsigned long flags;
+       int rc;
+
+       if (!netif_running(dev))
+               return -EINVAL;
+
+       spin_lock_irqsave(&ax->mii_lock, flags);
+       rc = generic_mii_ioctl(&ax->mii, if_mii(req), cmd, NULL);
+       spin_unlock_irqrestore(&ax->mii_lock, flags);
+
+       return rc;
+}
+
+/* ethtool ops */
+
+static void ax_get_drvinfo(struct net_device *dev,
+                          struct ethtool_drvinfo *info)
+{
+       struct ax_device *ax = to_ax_dev(dev);
+
+       strcpy(info->driver, DRV_NAME);
+       strcpy(info->version, DRV_VERSION);
+       strcpy(info->bus_info, ax->dev->name);
+}
+
+static int ax_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+       struct ax_device *ax = to_ax_dev(dev);
+       unsigned long flags;
+
+       spin_lock_irqsave(&ax->mii_lock, flags);
+       mii_ethtool_gset(&ax->mii, cmd);
+       spin_lock_irqsave(&ax->mii_lock, flags);
+
+       return 0;
+}
+
+static int ax_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+       struct ax_device *ax = to_ax_dev(dev);
+       unsigned long flags;
+       int rc;
+
+       spin_lock_irqsave(&ax->mii_lock, flags);
+       rc = mii_ethtool_sset(&ax->mii, cmd);
+       spin_lock_irqsave(&ax->mii_lock, flags);
+
+       return rc;
+}
+
+static int ax_nway_reset(struct net_device *dev)
+{
+       struct ax_device *ax = to_ax_dev(dev);
+       return mii_nway_restart(&ax->mii);
+}
+
+static u32 ax_get_link(struct net_device *dev)
+{
+       struct ax_device *ax = to_ax_dev(dev);
+       return mii_link_ok(&ax->mii);
+}
+
+static const struct ethtool_ops ax_ethtool_ops = {
+       .get_drvinfo            = ax_get_drvinfo,
+       .get_settings           = ax_get_settings,
+       .set_settings           = ax_set_settings,
+       .nway_reset             = ax_nway_reset,
+       .get_link               = ax_get_link,
+       .get_perm_addr          = ethtool_op_get_perm_addr,
+};
+
+/* setup code */
+
+static void ax_initial_setup(struct net_device *dev, struct ei_device *ei_local)
+{
+       void __iomem *ioaddr = ei_local->mem;
+       struct ax_device *ax = to_ax_dev(dev);
+
+       /* Select page 0*/
+       ei_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, ioaddr + E8390_CMD);
+
+       /* set to byte access */
+       ei_outb(ax->plat->dcr_val & ~1, ioaddr + EN0_DCFG);
+       ei_outb(ax->plat->gpoc_val, ioaddr + EI_SHIFT(0x17));
+}
+
+/* ax_init_dev
+ *
+ * initialise the specified device, taking care to note the MAC
+ * address it may already have (if configured), ensure
+ * the device is ready to be used by lib8390.c and registerd with
+ * the network layer.
+ */
+
+static int ax_init_dev(struct net_device *dev, int first_init)
+{
+       struct ei_device *ei_local = netdev_priv(dev);
+       struct ax_device *ax = to_ax_dev(dev);
+       void __iomem *ioaddr = ei_local->mem;
+       unsigned int start_page;
+       unsigned int stop_page;
+       int ret;
+       int i;
+
+       ret = ax_initial_check(dev);
+       if (ret)
+               goto err_out;
+
+       /* setup goes here */
+
+       ax_initial_setup(dev, ei_local);
+
+       /* read the mac from the card prom if we need it */
+
+       if (first_init && ax->plat->flags & AXFLG_HAS_EEPROM) {
+               unsigned char SA_prom[32];
+
+               for(i = 0; i < sizeof(SA_prom); i+=2) {
+                       SA_prom[i] = ei_inb(ioaddr + NE_DATAPORT);
+                       SA_prom[i+1] = ei_inb(ioaddr + NE_DATAPORT);
+               }
+
+               if (ax->plat->wordlength == 2)
+                       for (i = 0; i < 16; i++)
+                               SA_prom[i] = SA_prom[i+i];
+
+               memcpy(dev->dev_addr,  SA_prom, 6);
+       }
+
+       if (ax->plat->wordlength == 2) {
+               /* We must set the 8390 for word mode. */
+               ei_outb(ax->plat->dcr_val, ei_local->mem + EN0_DCFG);
+               start_page = NESM_START_PG;
+               stop_page = NESM_STOP_PG;
+       } else {
+               start_page = NE1SM_START_PG;
+               stop_page = NE1SM_STOP_PG;
+       }
+
+       /* load the mac-address from the device if this is the
+        * first time we've initialised */
+
+       if (first_init && ax->plat->flags & AXFLG_MAC_FROMDEV) {
+               ei_outb(E8390_NODMA + E8390_PAGE1 + E8390_STOP,
+                       ei_local->mem + E8390_CMD); /* 0x61 */
+
+               for (i = 0 ; i < ETHER_ADDR_LEN ; i++)
+                       dev->dev_addr[i] = ei_inb(ioaddr + EN1_PHYS_SHIFT(i));
+       }
+
+       ax_reset_8390(dev);
+
+       ei_status.name = "AX88796";
+       ei_status.tx_start_page = start_page;
+       ei_status.stop_page = stop_page;
+       ei_status.word16 = (ax->plat->wordlength == 2);
+       ei_status.rx_start_page = start_page + TX_PAGES;
+
+#ifdef PACKETBUF_MEMSIZE
+        /* Allow the packet buffer size to be overridden by know-it-alls. */
+       ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE;
+#endif
+
+       ei_status.reset_8390    = &ax_reset_8390;
+       ei_status.block_input   = &ax_block_input;
+       ei_status.block_output  = &ax_block_output;
+       ei_status.get_8390_hdr  = &ax_get_8390_hdr;
+       ei_status.priv = 0;
+
+       dev->open               = ax_open;
+       dev->stop               = ax_close;
+       dev->do_ioctl           = ax_ioctl;
+       dev->ethtool_ops        = &ax_ethtool_ops;
+
+       ax->msg_enable          = NETIF_MSG_LINK;
+       ax->mii.phy_id_mask     = 0x1f;
+       ax->mii.reg_num_mask    = 0x1f;
+       ax->mii.phy_id          = 0x10;         /* onboard phy */
+       ax->mii.force_media     = 0;
+       ax->mii.full_duplex     = 0;
+       ax->mii.mdio_read       = ax_phy_read;
+       ax->mii.mdio_write      = ax_phy_write;
+       ax->mii.dev             = dev;
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       dev->poll_controller = ax_ei_poll;
+#endif
+       ax_NS8390_init(dev, 0);
+
+       if (first_init) {
+               printk("AX88796: %dbit, irq %d, %lx, MAC: ",
+                      ei_status.word16 ? 16:8, dev->irq, dev->base_addr);
+
+               for (i = 0; i < ETHER_ADDR_LEN; i++)
+                       printk("%2.2x%c", dev->dev_addr[i],
+                              (i < (ETHER_ADDR_LEN-1) ? ':' : ' '));
+
+               printk("\n");
+       }
+
+       ret = register_netdev(dev);
+       if (ret)
+               goto out_irq;
+
+       return 0;
+
+ out_irq:
+       /* cleanup irq */
+       free_irq(dev->irq, dev);
+ err_out:
+       return ret;
+}
+
+static int ax_remove(struct platform_device *_dev)
+{
+       struct net_device *dev = platform_get_drvdata(_dev);
+       struct ax_device  *ax;
+
+       ax = to_ax_dev(dev);
+
+       unregister_netdev(dev);
+       free_irq(dev->irq, dev);
+
+       iounmap(ei_status.mem);
+       release_resource(ax->mem);
+       kfree(ax->mem);
+
+       if (ax->map2) {
+               iounmap(ax->map2);
+               release_resource(ax->mem2);
+               kfree(ax->mem2);
+       }
+
+       free_netdev(dev);
+
+       return 0;
+}
+
+/* ax_probe
+ *
+ * This is the entry point when the platform device system uses to
+ * notify us of a new device to attach to. Allocate memory, find
+ * the resources and information passed, and map the necessary registers.
+*/
+
+static int ax_probe(struct platform_device *pdev)
+{
+       struct net_device *dev;
+       struct ax_device  *ax;
+       struct resource   *res;
+       size_t size;
+       int ret;
+
+       dev = ax__alloc_ei_netdev(sizeof(struct ax_device));
+       if (dev == NULL)
+               return -ENOMEM;
+
+       /* ok, let's setup our device */
+       ax = to_ax_dev(dev);
+
+       memset(ax, 0, sizeof(struct ax_device));
+
+       spin_lock_init(&ax->mii_lock);
+
+       ax->dev = pdev;
+       ax->plat = pdev->dev.platform_data;
+       platform_set_drvdata(pdev, dev);
+
+       ei_status.rxcr_base  = ax->plat->rcr_val;
+
+       /* find the platform resources */
+
+       dev->irq  = platform_get_irq(pdev, 0);
+       if (dev->irq < 0) {
+               dev_err(&pdev->dev, "no IRQ specified\n");
+               ret = -ENXIO;
+               goto exit_mem;
+       }
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (res == NULL) {
+               dev_err(&pdev->dev, "no MEM specified\n");
+               ret = -ENXIO;
+               goto exit_mem;
+       }
+
+       size = (res->end - res->start) + 1;
+
+       /* setup the register offsets from either the platform data
+        * or by using the size of the resource provided */
+
+       if (ax->plat->reg_offsets)
+               ei_status.reg_offset = ax->plat->reg_offsets;
+       else {
+               ei_status.reg_offset = ax->reg_offsets;
+               for (ret = 0; ret < 0x18; ret++)
+                       ax->reg_offsets[ret] = (size / 0x18) * ret;
+       }
+
+       ax->mem = request_mem_region(res->start, size, pdev->name);
+       if (ax->mem == NULL) {
+               dev_err(&pdev->dev, "cannot reserve registers\n");
+               ret = -ENXIO;
+               goto exit_mem;
+       }
+
+       ei_status.mem = ioremap(res->start, size);
+       dev->base_addr = (long)ei_status.mem;
+
+       if (ei_status.mem == NULL) {
+               dev_err(&pdev->dev, "Cannot ioremap area (%08zx,%08zx)\n",
+                       res->start, res->end);
+
+               ret = -ENXIO;
+               goto exit_req;
+       }
+
+       /* look for reset area */
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+       if (res == NULL) {
+               if (!ax->plat->reg_offsets) {
+                       for (ret = 0; ret < 0x20; ret++)
+                               ax->reg_offsets[ret] = (size / 0x20) * ret;
+               }
+
+               ax->map2 = NULL;
+       } else {
+               size = (res->end - res->start) + 1;
+
+               ax->mem2 = request_mem_region(res->start, size, pdev->name);
+               if (ax->mem == NULL) {
+                       dev_err(&pdev->dev, "cannot reserve registers\n");
+                       ret = -ENXIO;
+                       goto exit_mem1;
+               }
+
+               ax->map2 = ioremap(res->start, size);
+               if (ax->map2 == NULL) {
+                       dev_err(&pdev->dev, "cannot map reset register");
+                       ret = -ENXIO;
+                       goto exit_mem2;
+               }
+
+               ei_status.reg_offset[0x1f] = ax->map2 - ei_status.mem;
+       }
+
+       /* got resources, now initialise and register device */
+
+       ret = ax_init_dev(dev, 1);
+       if (!ret)
+               return 0;
+
+       if (ax->map2 == NULL)
+               goto exit_mem1;
+
+       iounmap(ax->map2);
+
+ exit_mem2:
+       release_resource(ax->mem2);
+       kfree(ax->mem2);
+
+ exit_mem1:
+       iounmap(ei_status.mem);
+
+ exit_req:
+       release_resource(ax->mem);
+       kfree(ax->mem);
+
+ exit_mem:
+       free_netdev(dev);
+
+       return ret;
+}
+
+/* suspend and resume */
+
+#ifdef CONFIG_PM
+static int ax_suspend(struct platform_device *dev, pm_message_t state)
+{
+       struct net_device *ndev = platform_get_drvdata(dev);
+       struct ax_device  *ax = to_ax_dev(ndev);
+
+       ax->resume_open = ax->running;
+
+       netif_device_detach(ndev);
+       ax_close(ndev);
+
+       return 0;
+}
+
+static int ax_resume(struct platform_device *pdev)
+{
+       struct net_device *ndev = platform_get_drvdata(pdev);
+       struct ax_device  *ax = to_ax_dev(ndev);
+
+       ax_initial_setup(ndev, netdev_priv(ndev));
+       ax_NS8390_init(ndev, ax->resume_open);
+       netif_device_attach(ndev);
+
+       if (ax->resume_open)
+               ax_open(ndev);
+
+       return 0;
+}
+
+#else
+#define ax_suspend NULL
+#define ax_resume  NULL
+#endif
+
+static struct platform_driver axdrv = {
+       .driver = {
+               .name           = "ax88796",
+               .owner          = THIS_MODULE,
+       },
+       .probe          = ax_probe,
+       .remove         = ax_remove,
+       .suspend        = ax_suspend,
+       .resume         = ax_resume,
+};
+
+static int __init axdrv_init(void)
+{
+       return platform_driver_register(&axdrv);
+}
+
+static void __exit axdrv_exit(void)
+{
+       platform_driver_unregister(&axdrv);
+}
+
+module_init(axdrv_init);
+module_exit(axdrv_exit);
+
+MODULE_DESCRIPTION("AX88796 10/100 Ethernet platform driver");
+MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
+MODULE_LICENSE("GPL v2");
index 879a2fff474e007f62907e642d1ea9fdab2ec04b..96fb0ec905a7f176b691c811a0563991f1985c4f 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/ethtool.h>
 #include <linux/mii.h>
 #include <linux/if_ether.h>
+#include <linux/if_vlan.h>
 #include <linux/etherdevice.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
@@ -68,8 +69,8 @@
          (BP)->tx_cons - (BP)->tx_prod - TX_RING_GAP(BP))
 #define NEXT_TX(N)             (((N) + 1) & (B44_TX_RING_SIZE - 1))
 
-#define RX_PKT_BUF_SZ          (1536 + bp->rx_offset + 64)
-#define TX_PKT_BUF_SZ          (B44_MAX_MTU + ETH_HLEN + 8)
+#define RX_PKT_OFFSET          30
+#define RX_PKT_BUF_SZ          (1536 + RX_PKT_OFFSET + 64)
 
 /* minimum number of free TX descriptors required to wake up TX process */
 #define B44_TX_WAKEUP_THRESH           (B44_TX_RING_SIZE / 4)
@@ -599,8 +600,7 @@ static void b44_timer(unsigned long __opaque)
 
        spin_unlock_irq(&bp->lock);
 
-       bp->timer.expires = jiffies + HZ;
-       add_timer(&bp->timer);
+       mod_timer(&bp->timer, round_jiffies(jiffies + HZ));
 }
 
 static void b44_tx(struct b44 *bp)
@@ -653,7 +653,7 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
                src_map = &bp->rx_buffers[src_idx];
        dest_idx = dest_idx_unmasked & (B44_RX_RING_SIZE - 1);
        map = &bp->rx_buffers[dest_idx];
-       skb = dev_alloc_skb(RX_PKT_BUF_SZ);
+       skb = netdev_alloc_skb(bp->dev, RX_PKT_BUF_SZ);
        if (skb == NULL)
                return -ENOMEM;
 
@@ -669,7 +669,7 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
                if (!dma_mapping_error(mapping))
                        pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE);
                dev_kfree_skb_any(skb);
-               skb = __dev_alloc_skb(RX_PKT_BUF_SZ,GFP_DMA);
+               skb = __netdev_alloc_skb(bp->dev, RX_PKT_BUF_SZ, GFP_ATOMIC|GFP_DMA);
                if (skb == NULL)
                        return -ENOMEM;
                mapping = pci_map_single(bp->pdev, skb->data,
@@ -684,11 +684,9 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
                }
        }
 
-       skb->dev = bp->dev;
-       skb_reserve(skb, bp->rx_offset);
+       rh = (struct rx_header *) skb->data;
+       skb_reserve(skb, RX_PKT_OFFSET);
 
-       rh = (struct rx_header *)
-               (skb->data - bp->rx_offset);
        rh->len = 0;
        rh->flags = 0;
 
@@ -698,13 +696,13 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
        if (src_map != NULL)
                src_map->skb = NULL;
 
-       ctrl  = (DESC_CTRL_LEN & (RX_PKT_BUF_SZ - bp->rx_offset));
+       ctrl  = (DESC_CTRL_LEN & (RX_PKT_BUF_SZ - RX_PKT_OFFSET));
        if (dest_idx == (B44_RX_RING_SIZE - 1))
                ctrl |= DESC_CTRL_EOT;
 
        dp = &bp->rx_ring[dest_idx];
        dp->ctrl = cpu_to_le32(ctrl);
-       dp->addr = cpu_to_le32((u32) mapping + bp->rx_offset + bp->dma_offset);
+       dp->addr = cpu_to_le32((u32) mapping + RX_PKT_OFFSET + bp->dma_offset);
 
        if (bp->flags & B44_FLAG_RX_RING_HACK)
                b44_sync_dma_desc_for_device(bp->pdev, bp->rx_ring_dma,
@@ -783,7 +781,7 @@ static int b44_rx(struct b44 *bp, int budget)
                                            PCI_DMA_FROMDEVICE);
                rh = (struct rx_header *) skb->data;
                len = le16_to_cpu(rh->len);
-               if ((len > (RX_PKT_BUF_SZ - bp->rx_offset)) ||
+               if ((len > (RX_PKT_BUF_SZ - RX_PKT_OFFSET)) ||
                    (rh->flags & cpu_to_le16(RX_FLAG_ERRORS))) {
                drop_it:
                        b44_recycle_rx(bp, cons, bp->rx_prod);
@@ -815,8 +813,8 @@ static int b44_rx(struct b44 *bp, int budget)
                        pci_unmap_single(bp->pdev, map,
                                         skb_size, PCI_DMA_FROMDEVICE);
                        /* Leave out rx_header */
-                       skb_put(skb, len+bp->rx_offset);
-                       skb_pull(skb,bp->rx_offset);
+                       skb_put(skb, len + RX_PKT_OFFSET);
+                       skb_pull(skb, RX_PKT_OFFSET);
                } else {
                        struct sk_buff *copy_skb;
 
@@ -828,7 +826,7 @@ static int b44_rx(struct b44 *bp, int budget)
                        skb_reserve(copy_skb, 2);
                        skb_put(copy_skb, len);
                        /* DMA sync done above, copy just the actual packet */
-                       skb_copy_from_linear_data_offset(skb, bp->rx_offset,
+                       skb_copy_from_linear_data_offset(skb, RX_PKT_OFFSET,
                                                         copy_skb->data, len);
                        skb = copy_skb;
                }
@@ -969,7 +967,6 @@ static void b44_tx_timeout(struct net_device *dev)
 static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct b44 *bp = netdev_priv(dev);
-       struct sk_buff *bounce_skb;
        int rc = NETDEV_TX_OK;
        dma_addr_t mapping;
        u32 len, entry, ctrl;
@@ -987,12 +984,13 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE);
        if (dma_mapping_error(mapping) || mapping + len > DMA_30BIT_MASK) {
+               struct sk_buff *bounce_skb;
+
                /* Chip can't handle DMA to/from >1GB, use bounce buffer */
                if (!dma_mapping_error(mapping))
                        pci_unmap_single(bp->pdev, mapping, len, PCI_DMA_TODEVICE);
 
-               bounce_skb = __dev_alloc_skb(TX_PKT_BUF_SZ,
-                                            GFP_ATOMIC|GFP_DMA);
+               bounce_skb = __dev_alloc_skb(len, GFP_ATOMIC | GFP_DMA);
                if (!bounce_skb)
                        goto err_out;
 
@@ -1001,13 +999,12 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
                if (dma_mapping_error(mapping) || mapping + len > DMA_30BIT_MASK) {
                        if (!dma_mapping_error(mapping))
                                pci_unmap_single(bp->pdev, mapping,
-                                        len, PCI_DMA_TODEVICE);
+                                                len, PCI_DMA_TODEVICE);
                        dev_kfree_skb_any(bounce_skb);
                        goto err_out;
                }
 
-               skb_copy_from_linear_data(skb, skb_put(bounce_skb, len),
-                                         skb->len);
+               skb_copy_from_linear_data(skb, skb_put(bounce_skb, len), len);
                dev_kfree_skb_any(skb);
                skb = bounce_skb;
        }
@@ -1396,12 +1393,12 @@ static void b44_init_hw(struct b44 *bp, int reset_kind)
        bw32(bp, B44_TX_WMARK, 56); /* XXX magic */
        if (reset_kind == B44_PARTIAL_RESET) {
                bw32(bp, B44_DMARX_CTRL, (DMARX_CTRL_ENABLE |
-                                     (bp->rx_offset << DMARX_CTRL_ROSHIFT)));
+                                     (RX_PKT_OFFSET << DMARX_CTRL_ROSHIFT)));
        } else {
                bw32(bp, B44_DMATX_CTRL, DMATX_CTRL_ENABLE);
                bw32(bp, B44_DMATX_ADDR, bp->tx_ring_dma + bp->dma_offset);
                bw32(bp, B44_DMARX_CTRL, (DMARX_CTRL_ENABLE |
-                                     (bp->rx_offset << DMARX_CTRL_ROSHIFT)));
+                                     (RX_PKT_OFFSET << DMARX_CTRL_ROSHIFT)));
                bw32(bp, B44_DMARX_ADDR, bp->rx_ring_dma + bp->dma_offset);
 
                bw32(bp, B44_DMARX_PTR, bp->rx_pending);
@@ -2093,11 +2090,6 @@ static int __devinit b44_get_invariants(struct b44 *bp)
 
        bp->phy_addr = eeprom[90] & 0x1f;
 
-       /* With this, plus the rx_header prepended to the data by the
-        * hardware, we'll land the ethernet header on a 2-byte boundary.
-        */
-       bp->rx_offset = 30;
-
        bp->imask = IMASK_DEF;
 
        bp->core_unit = ssb_core_unit(bp);
@@ -2348,11 +2340,11 @@ static int b44_resume(struct pci_dev *pdev)
        netif_device_attach(bp->dev);
        spin_unlock_irq(&bp->lock);
 
-       bp->timer.expires = jiffies + HZ;
-       add_timer(&bp->timer);
-
        b44_enable_ints(bp);
        netif_wake_queue(dev);
+
+       mod_timer(&bp->timer, jiffies + 1);
+
        return 0;
 }
 
index 18fc13336628fd5fa532ee822b9d0bcf378b4e7c..e537e63f292e6e948dfea4567cacfe99a0ef1a0b 100644 (file)
@@ -443,8 +443,6 @@ struct b44 {
 #define B44_FLAG_TX_RING_HACK  0x40000000
 #define B44_FLAG_WOL_ENABLE    0x80000000
 
-       u32                     rx_offset;
-
        u32                     msg_enable;
 
        struct timer_list       timer;
index ce3ed67a878e39af77ab5a95453406091b7c6e15..4e5e1cb2adc1d7019275e84349b00f73dfd82215 100644 (file)
@@ -54,8 +54,8 @@
 
 #define DRV_MODULE_NAME                "bnx2"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "1.5.11"
-#define DRV_MODULE_RELDATE     "June 4, 2007"
+#define DRV_MODULE_VERSION     "1.6.2"
+#define DRV_MODULE_RELDATE     "July 6, 2007"
 
 #define RUN_AT(x) (jiffies + (x))
 
@@ -550,6 +550,9 @@ bnx2_report_fw_link(struct bnx2 *bp)
 {
        u32 fw_link_status = 0;
 
+       if (bp->phy_flags & REMOTE_PHY_CAP_FLAG)
+               return;
+
        if (bp->link_up) {
                u32 bmsr;
 
@@ -601,12 +604,21 @@ bnx2_report_fw_link(struct bnx2 *bp)
        REG_WR_IND(bp, bp->shmem_base + BNX2_LINK_STATUS, fw_link_status);
 }
 
+static char *
+bnx2_xceiver_str(struct bnx2 *bp)
+{
+       return ((bp->phy_port == PORT_FIBRE) ? "SerDes" :
+               ((bp->phy_flags & PHY_SERDES_FLAG) ? "Remote Copper" :
+                "Copper"));
+}
+
 static void
 bnx2_report_link(struct bnx2 *bp)
 {
        if (bp->link_up) {
                netif_carrier_on(bp->dev);
-               printk(KERN_INFO PFX "%s NIC Link is Up, ", bp->dev->name);
+               printk(KERN_INFO PFX "%s NIC %s Link is Up, ", bp->dev->name,
+                      bnx2_xceiver_str(bp));
 
                printk("%d Mbps ", bp->line_speed);
 
@@ -630,7 +642,8 @@ bnx2_report_link(struct bnx2 *bp)
        }
        else {
                netif_carrier_off(bp->dev);
-               printk(KERN_ERR PFX "%s NIC Link is Down\n", bp->dev->name);
+               printk(KERN_ERR PFX "%s NIC %s Link is Down\n", bp->dev->name,
+                      bnx2_xceiver_str(bp));
        }
 
        bnx2_report_fw_link(bp);
@@ -1100,6 +1113,9 @@ bnx2_set_link(struct bnx2 *bp)
                return 0;
        }
 
+       if (bp->phy_flags & REMOTE_PHY_CAP_FLAG)
+               return 0;
+
        link_up = bp->link_up;
 
        bnx2_enable_bmsr1(bp);
@@ -1210,12 +1226,74 @@ bnx2_phy_get_pause_adv(struct bnx2 *bp)
        return adv;
 }
 
+static int bnx2_fw_sync(struct bnx2 *, u32, int);
+
 static int
-bnx2_setup_serdes_phy(struct bnx2 *bp)
+bnx2_setup_remote_phy(struct bnx2 *bp, u8 port)
+{
+       u32 speed_arg = 0, pause_adv;
+
+       pause_adv = bnx2_phy_get_pause_adv(bp);
+
+       if (bp->autoneg & AUTONEG_SPEED) {
+               speed_arg |= BNX2_NETLINK_SET_LINK_ENABLE_AUTONEG;
+               if (bp->advertising & ADVERTISED_10baseT_Half)
+                       speed_arg |= BNX2_NETLINK_SET_LINK_SPEED_10HALF;
+               if (bp->advertising & ADVERTISED_10baseT_Full)
+                       speed_arg |= BNX2_NETLINK_SET_LINK_SPEED_10FULL;
+               if (bp->advertising & ADVERTISED_100baseT_Half)
+                       speed_arg |= BNX2_NETLINK_SET_LINK_SPEED_100HALF;
+               if (bp->advertising & ADVERTISED_100baseT_Full)
+                       speed_arg |= BNX2_NETLINK_SET_LINK_SPEED_100FULL;
+               if (bp->advertising & ADVERTISED_1000baseT_Full)
+                       speed_arg |= BNX2_NETLINK_SET_LINK_SPEED_1GFULL;
+               if (bp->advertising & ADVERTISED_2500baseX_Full)
+                       speed_arg |= BNX2_NETLINK_SET_LINK_SPEED_2G5FULL;
+       } else {
+               if (bp->req_line_speed == SPEED_2500)
+                       speed_arg = BNX2_NETLINK_SET_LINK_SPEED_2G5FULL;
+               else if (bp->req_line_speed == SPEED_1000)
+                       speed_arg = BNX2_NETLINK_SET_LINK_SPEED_1GFULL;
+               else if (bp->req_line_speed == SPEED_100) {
+                       if (bp->req_duplex == DUPLEX_FULL)
+                               speed_arg = BNX2_NETLINK_SET_LINK_SPEED_100FULL;
+                       else
+                               speed_arg = BNX2_NETLINK_SET_LINK_SPEED_100HALF;
+               } else if (bp->req_line_speed == SPEED_10) {
+                       if (bp->req_duplex == DUPLEX_FULL)
+                               speed_arg = BNX2_NETLINK_SET_LINK_SPEED_10FULL;
+                       else
+                               speed_arg = BNX2_NETLINK_SET_LINK_SPEED_10HALF;
+               }
+       }
+
+       if (pause_adv & (ADVERTISE_1000XPAUSE | ADVERTISE_PAUSE_CAP))
+               speed_arg |= BNX2_NETLINK_SET_LINK_FC_SYM_PAUSE;
+       if (pause_adv & (ADVERTISE_1000XPSE_ASYM | ADVERTISE_1000XPSE_ASYM))
+               speed_arg |= BNX2_NETLINK_SET_LINK_FC_ASYM_PAUSE;
+
+       if (port == PORT_TP)
+               speed_arg |= BNX2_NETLINK_SET_LINK_PHY_APP_REMOTE |
+                            BNX2_NETLINK_SET_LINK_ETH_AT_WIRESPEED;
+
+       REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_MB_ARG0, speed_arg);
+
+       spin_unlock_bh(&bp->phy_lock);
+       bnx2_fw_sync(bp, BNX2_DRV_MSG_CODE_CMD_SET_LINK, 0);
+       spin_lock_bh(&bp->phy_lock);
+
+       return 0;
+}
+
+static int
+bnx2_setup_serdes_phy(struct bnx2 *bp, u8 port)
 {
        u32 adv, bmcr;
        u32 new_adv = 0;
 
+       if (bp->phy_flags & REMOTE_PHY_CAP_FLAG)
+               return (bnx2_setup_remote_phy(bp, port));
+
        if (!(bp->autoneg & AUTONEG_SPEED)) {
                u32 new_bmcr;
                int force_link_down = 0;
@@ -1323,7 +1401,9 @@ bnx2_setup_serdes_phy(struct bnx2 *bp)
 }
 
 #define ETHTOOL_ALL_FIBRE_SPEED                                                \
-       (ADVERTISED_1000baseT_Full)
+       (bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) ?                       \
+               (ADVERTISED_2500baseX_Full | ADVERTISED_1000baseT_Full) :\
+               (ADVERTISED_1000baseT_Full)
 
 #define ETHTOOL_ALL_COPPER_SPEED                                       \
        (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |            \
@@ -1335,6 +1415,188 @@ bnx2_setup_serdes_phy(struct bnx2 *bp)
 
 #define PHY_ALL_1000_SPEED (ADVERTISE_1000HALF | ADVERTISE_1000FULL)
 
+static void
+bnx2_set_default_remote_link(struct bnx2 *bp)
+{
+       u32 link;
+
+       if (bp->phy_port == PORT_TP)
+               link = REG_RD_IND(bp, bp->shmem_base + BNX2_RPHY_COPPER_LINK);
+       else
+               link = REG_RD_IND(bp, bp->shmem_base + BNX2_RPHY_SERDES_LINK);
+
+       if (link & BNX2_NETLINK_SET_LINK_ENABLE_AUTONEG) {
+               bp->req_line_speed = 0;
+               bp->autoneg |= AUTONEG_SPEED;
+               bp->advertising = ADVERTISED_Autoneg;
+               if (link & BNX2_NETLINK_SET_LINK_SPEED_10HALF)
+                       bp->advertising |= ADVERTISED_10baseT_Half;
+               if (link & BNX2_NETLINK_SET_LINK_SPEED_10FULL)
+                       bp->advertising |= ADVERTISED_10baseT_Full;
+               if (link & BNX2_NETLINK_SET_LINK_SPEED_100HALF)
+                       bp->advertising |= ADVERTISED_100baseT_Half;
+               if (link & BNX2_NETLINK_SET_LINK_SPEED_100FULL)
+                       bp->advertising |= ADVERTISED_100baseT_Full;
+               if (link & BNX2_NETLINK_SET_LINK_SPEED_1GFULL)
+                       bp->advertising |= ADVERTISED_1000baseT_Full;
+               if (link & BNX2_NETLINK_SET_LINK_SPEED_2G5FULL)
+                       bp->advertising |= ADVERTISED_2500baseX_Full;
+       } else {
+               bp->autoneg = 0;
+               bp->advertising = 0;
+               bp->req_duplex = DUPLEX_FULL;
+               if (link & BNX2_NETLINK_SET_LINK_SPEED_10) {
+                       bp->req_line_speed = SPEED_10;
+                       if (link & BNX2_NETLINK_SET_LINK_SPEED_10HALF)
+                               bp->req_duplex = DUPLEX_HALF;
+               }
+               if (link & BNX2_NETLINK_SET_LINK_SPEED_100) {
+                       bp->req_line_speed = SPEED_100;
+                       if (link & BNX2_NETLINK_SET_LINK_SPEED_100HALF)
+                               bp->req_duplex = DUPLEX_HALF;
+               }
+               if (link & BNX2_NETLINK_SET_LINK_SPEED_1GFULL)
+                       bp->req_line_speed = SPEED_1000;
+               if (link & BNX2_NETLINK_SET_LINK_SPEED_2G5FULL)
+                       bp->req_line_speed = SPEED_2500;
+       }
+}
+
+static void
+bnx2_set_default_link(struct bnx2 *bp)
+{
+       if (bp->phy_flags & REMOTE_PHY_CAP_FLAG)
+               return bnx2_set_default_remote_link(bp);
+
+       bp->autoneg = AUTONEG_SPEED | AUTONEG_FLOW_CTRL;
+       bp->req_line_speed = 0;
+       if (bp->phy_flags & PHY_SERDES_FLAG) {
+               u32 reg;
+
+               bp->advertising = ETHTOOL_ALL_FIBRE_SPEED | ADVERTISED_Autoneg;
+
+               reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_CONFIG);
+               reg &= BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK;
+               if (reg == BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G) {
+                       bp->autoneg = 0;
+                       bp->req_line_speed = bp->line_speed = SPEED_1000;
+                       bp->req_duplex = DUPLEX_FULL;
+               }
+       } else
+               bp->advertising = ETHTOOL_ALL_COPPER_SPEED | ADVERTISED_Autoneg;
+}
+
+static void
+bnx2_send_heart_beat(struct bnx2 *bp)
+{
+       u32 msg;
+       u32 addr;
+
+       spin_lock(&bp->indirect_lock);
+       msg = (u32) (++bp->fw_drv_pulse_wr_seq & BNX2_DRV_PULSE_SEQ_MASK);
+       addr = bp->shmem_base + BNX2_DRV_PULSE_MB;
+       REG_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, addr);
+       REG_WR(bp, BNX2_PCICFG_REG_WINDOW, msg);
+       spin_unlock(&bp->indirect_lock);
+}
+
+static void
+bnx2_remote_phy_event(struct bnx2 *bp)
+{
+       u32 msg;
+       u8 link_up = bp->link_up;
+       u8 old_port;
+
+       msg = REG_RD_IND(bp, bp->shmem_base + BNX2_LINK_STATUS);
+
+       if (msg & BNX2_LINK_STATUS_HEART_BEAT_EXPIRED)
+               bnx2_send_heart_beat(bp);
+
+       msg &= ~BNX2_LINK_STATUS_HEART_BEAT_EXPIRED;
+
+       if ((msg & BNX2_LINK_STATUS_LINK_UP) == BNX2_LINK_STATUS_LINK_DOWN)
+               bp->link_up = 0;
+       else {
+               u32 speed;
+
+               bp->link_up = 1;
+               speed = msg & BNX2_LINK_STATUS_SPEED_MASK;
+               bp->duplex = DUPLEX_FULL;
+               switch (speed) {
+                       case BNX2_LINK_STATUS_10HALF:
+                               bp->duplex = DUPLEX_HALF;
+                       case BNX2_LINK_STATUS_10FULL:
+                               bp->line_speed = SPEED_10;
+                               break;
+                       case BNX2_LINK_STATUS_100HALF:
+                               bp->duplex = DUPLEX_HALF;
+                       case BNX2_LINK_STATUS_100BASE_T4:
+                       case BNX2_LINK_STATUS_100FULL:
+                               bp->line_speed = SPEED_100;
+                               break;
+                       case BNX2_LINK_STATUS_1000HALF:
+                               bp->duplex = DUPLEX_HALF;
+                       case BNX2_LINK_STATUS_1000FULL:
+                               bp->line_speed = SPEED_1000;
+                               break;
+                       case BNX2_LINK_STATUS_2500HALF:
+                               bp->duplex = DUPLEX_HALF;
+                       case BNX2_LINK_STATUS_2500FULL:
+                               bp->line_speed = SPEED_2500;
+                               break;
+                       default:
+                               bp->line_speed = 0;
+                               break;
+               }
+
+               spin_lock(&bp->phy_lock);
+               bp->flow_ctrl = 0;
+               if ((bp->autoneg & (AUTONEG_SPEED | AUTONEG_FLOW_CTRL)) !=
+                   (AUTONEG_SPEED | AUTONEG_FLOW_CTRL)) {
+                       if (bp->duplex == DUPLEX_FULL)
+                               bp->flow_ctrl = bp->req_flow_ctrl;
+               } else {
+                       if (msg & BNX2_LINK_STATUS_TX_FC_ENABLED)
+                               bp->flow_ctrl |= FLOW_CTRL_TX;
+                       if (msg & BNX2_LINK_STATUS_RX_FC_ENABLED)
+                               bp->flow_ctrl |= FLOW_CTRL_RX;
+               }
+
+               old_port = bp->phy_port;
+               if (msg & BNX2_LINK_STATUS_SERDES_LINK)
+                       bp->phy_port = PORT_FIBRE;
+               else
+                       bp->phy_port = PORT_TP;
+
+               if (old_port != bp->phy_port)
+                       bnx2_set_default_link(bp);
+
+               spin_unlock(&bp->phy_lock);
+       }
+       if (bp->link_up != link_up)
+               bnx2_report_link(bp);
+
+       bnx2_set_mac_link(bp);
+}
+
+static int
+bnx2_set_remote_link(struct bnx2 *bp)
+{
+       u32 evt_code;
+
+       evt_code = REG_RD_IND(bp, bp->shmem_base + BNX2_FW_EVT_CODE_MB);
+       switch (evt_code) {
+               case BNX2_FW_EVT_CODE_LINK_EVENT:
+                       bnx2_remote_phy_event(bp);
+                       break;
+               case BNX2_FW_EVT_CODE_SW_TIMER_EXPIRATION_EVENT:
+               default:
+                       bnx2_send_heart_beat(bp);
+                       break;
+       }
+       return 0;
+}
+
 static int
 bnx2_setup_copper_phy(struct bnx2 *bp)
 {
@@ -1433,13 +1695,13 @@ bnx2_setup_copper_phy(struct bnx2 *bp)
 }
 
 static int
-bnx2_setup_phy(struct bnx2 *bp)
+bnx2_setup_phy(struct bnx2 *bp, u8 port)
 {
        if (bp->loopback == MAC_LOOPBACK)
                return 0;
 
        if (bp->phy_flags & PHY_SERDES_FLAG) {
-               return (bnx2_setup_serdes_phy(bp));
+               return (bnx2_setup_serdes_phy(bp, port));
        }
        else {
                return (bnx2_setup_copper_phy(bp));
@@ -1659,6 +1921,9 @@ bnx2_init_phy(struct bnx2 *bp)
 
         REG_WR(bp, BNX2_EMAC_ATTENTION_ENA, BNX2_EMAC_ATTENTION_ENA_LINK);
 
+       if (bp->phy_flags & REMOTE_PHY_CAP_FLAG)
+               goto setup_phy;
+
        bnx2_read_phy(bp, MII_PHYSID1, &val);
        bp->phy_id = val << 16;
        bnx2_read_phy(bp, MII_PHYSID2, &val);
@@ -1676,7 +1941,9 @@ bnx2_init_phy(struct bnx2 *bp)
                rc = bnx2_init_copper_phy(bp);
        }
 
-       bnx2_setup_phy(bp);
+setup_phy:
+       if (!rc)
+               rc = bnx2_setup_phy(bp, bp->phy_port);
 
        return rc;
 }
@@ -1984,6 +2251,9 @@ bnx2_phy_int(struct bnx2 *bp)
                bnx2_set_link(bp);
                spin_unlock(&bp->phy_lock);
        }
+       if (bnx2_phy_event_is_set(bp, STATUS_ATTN_BITS_TIMER_ABORT))
+               bnx2_set_remote_link(bp);
+
 }
 
 static void
@@ -2297,6 +2567,7 @@ bnx2_interrupt(int irq, void *dev_instance)
 {
        struct net_device *dev = dev_instance;
        struct bnx2 *bp = netdev_priv(dev);
+       struct status_block *sblk = bp->status_blk;
 
        /* When using INTx, it is possible for the interrupt to arrive
         * at the CPU before the status block posted prior to the
@@ -2304,7 +2575,7 @@ bnx2_interrupt(int irq, void *dev_instance)
         * When using MSI, the MSI message will always complete after
         * the status block write.
         */
-       if ((bp->status_blk->status_idx == bp->last_status_idx) &&
+       if ((sblk->status_idx == bp->last_status_idx) &&
            (REG_RD(bp, BNX2_PCICFG_MISC_STATUS) &
             BNX2_PCICFG_MISC_STATUS_INTA_VALUE))
                return IRQ_NONE;
@@ -2313,16 +2584,25 @@ bnx2_interrupt(int irq, void *dev_instance)
                BNX2_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM |
                BNX2_PCICFG_INT_ACK_CMD_MASK_INT);
 
+       /* Read back to deassert IRQ immediately to avoid too many
+        * spurious interrupts.
+        */
+       REG_RD(bp, BNX2_PCICFG_INT_ACK_CMD);
+
        /* Return here if interrupt is shared and is disabled. */
        if (unlikely(atomic_read(&bp->intr_sem) != 0))
                return IRQ_HANDLED;
 
-       netif_rx_schedule(dev);
+       if (netif_rx_schedule_prep(dev)) {
+               bp->last_status_idx = sblk->status_idx;
+               __netif_rx_schedule(dev);
+       }
 
        return IRQ_HANDLED;
 }
 
-#define STATUS_ATTN_EVENTS     STATUS_ATTN_BITS_LINK_STATE
+#define STATUS_ATTN_EVENTS     (STATUS_ATTN_BITS_LINK_STATE | \
+                                STATUS_ATTN_BITS_TIMER_ABORT)
 
 static inline int
 bnx2_has_work(struct bnx2 *bp)
@@ -3562,6 +3842,36 @@ nvram_write_end:
        return rc;
 }
 
+static void
+bnx2_init_remote_phy(struct bnx2 *bp)
+{
+       u32 val;
+
+       bp->phy_flags &= ~REMOTE_PHY_CAP_FLAG;
+       if (!(bp->phy_flags & PHY_SERDES_FLAG))
+               return;
+
+       val = REG_RD_IND(bp, bp->shmem_base + BNX2_FW_CAP_MB);
+       if ((val & BNX2_FW_CAP_SIGNATURE_MASK) != BNX2_FW_CAP_SIGNATURE)
+               return;
+
+       if (val & BNX2_FW_CAP_REMOTE_PHY_CAPABLE) {
+               if (netif_running(bp->dev)) {
+                       val = BNX2_DRV_ACK_CAP_SIGNATURE |
+                             BNX2_FW_CAP_REMOTE_PHY_CAPABLE;
+                       REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_ACK_CAP_MB,
+                                  val);
+               }
+               bp->phy_flags |= REMOTE_PHY_CAP_FLAG;
+
+               val = REG_RD_IND(bp, bp->shmem_base + BNX2_LINK_STATUS);
+               if (val & BNX2_LINK_STATUS_SERDES_LINK)
+                       bp->phy_port = PORT_FIBRE;
+               else
+                       bp->phy_port = PORT_TP;
+       }
+}
+
 static int
 bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
 {
@@ -3642,6 +3952,12 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
        if (rc)
                return rc;
 
+       spin_lock_bh(&bp->phy_lock);
+       bnx2_init_remote_phy(bp);
+       if (bp->phy_flags & REMOTE_PHY_CAP_FLAG)
+               bnx2_set_default_remote_link(bp);
+       spin_unlock_bh(&bp->phy_lock);
+
        if (CHIP_ID(bp) == CHIP_ID_5706_A0) {
                /* Adjust the voltage regular to two steps lower.  The default
                 * of this register is 0x0000000e. */
@@ -3826,7 +4142,7 @@ bnx2_init_chip(struct bnx2 *bp)
        rc = bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT2 | BNX2_DRV_MSG_CODE_RESET,
                          0);
 
-       REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS, 0x5ffffff);
+       REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS, BNX2_MISC_ENABLE_DEFAULT);
        REG_RD(bp, BNX2_MISC_ENABLE_SET_BITS);
 
        udelay(20);
@@ -4069,8 +4385,8 @@ bnx2_init_nic(struct bnx2 *bp)
 
        spin_lock_bh(&bp->phy_lock);
        bnx2_init_phy(bp);
-       spin_unlock_bh(&bp->phy_lock);
        bnx2_set_link(bp);
+       spin_unlock_bh(&bp->phy_lock);
        return 0;
 }
 
@@ -4600,6 +4916,9 @@ bnx2_5706_serdes_timer(struct bnx2 *bp)
 static void
 bnx2_5708_serdes_timer(struct bnx2 *bp)
 {
+       if (bp->phy_flags & REMOTE_PHY_CAP_FLAG)
+               return;
+
        if ((bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) == 0) {
                bp->serdes_an_pending = 0;
                return;
@@ -4631,7 +4950,6 @@ static void
 bnx2_timer(unsigned long data)
 {
        struct bnx2 *bp = (struct bnx2 *) data;
-       u32 msg;
 
        if (!netif_running(bp->dev))
                return;
@@ -4639,8 +4957,7 @@ bnx2_timer(unsigned long data)
        if (atomic_read(&bp->intr_sem) != 0)
                goto bnx2_restart_timer;
 
-       msg = (u32) ++bp->fw_drv_pulse_wr_seq;
-       REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_PULSE_MB, msg);
+       bnx2_send_heart_beat(bp);
 
        bp->stats_blk->stat_FwRxDrop = REG_RD_IND(bp, BNX2_FW_RX_DROP_COUNT);
 
@@ -5083,17 +5400,25 @@ static int
 bnx2_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
        struct bnx2 *bp = netdev_priv(dev);
+       int support_serdes = 0, support_copper = 0;
 
        cmd->supported = SUPPORTED_Autoneg;
-       if (bp->phy_flags & PHY_SERDES_FLAG) {
+       if (bp->phy_flags & REMOTE_PHY_CAP_FLAG) {
+               support_serdes = 1;
+               support_copper = 1;
+       } else if (bp->phy_port == PORT_FIBRE)
+               support_serdes = 1;
+       else
+               support_copper = 1;
+
+       if (support_serdes) {
                cmd->supported |= SUPPORTED_1000baseT_Full |
                        SUPPORTED_FIBRE;
                if (bp->phy_flags & PHY_2_5G_CAPABLE_FLAG)
                        cmd->supported |= SUPPORTED_2500baseX_Full;
 
-               cmd->port = PORT_FIBRE;
        }
-       else {
+       if (support_copper) {
                cmd->supported |= SUPPORTED_10baseT_Half |
                        SUPPORTED_10baseT_Full |
                        SUPPORTED_100baseT_Half |
@@ -5101,9 +5426,10 @@ bnx2_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                        SUPPORTED_1000baseT_Full |
                        SUPPORTED_TP;
 
-               cmd->port = PORT_TP;
        }
 
+       spin_lock_bh(&bp->phy_lock);
+       cmd->port = bp->phy_port;
        cmd->advertising = bp->advertising;
 
        if (bp->autoneg & AUTONEG_SPEED) {
@@ -5121,6 +5447,7 @@ bnx2_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                cmd->speed = -1;
                cmd->duplex = -1;
        }
+       spin_unlock_bh(&bp->phy_lock);
 
        cmd->transceiver = XCVR_INTERNAL;
        cmd->phy_address = bp->phy_addr;
@@ -5136,6 +5463,15 @@ bnx2_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
        u8 req_duplex = bp->req_duplex;
        u16 req_line_speed = bp->req_line_speed;
        u32 advertising = bp->advertising;
+       int err = -EINVAL;
+
+       spin_lock_bh(&bp->phy_lock);
+
+       if (cmd->port != PORT_TP && cmd->port != PORT_FIBRE)
+               goto err_out_unlock;
+
+       if (cmd->port != bp->phy_port && !(bp->phy_flags & REMOTE_PHY_CAP_FLAG))
+               goto err_out_unlock;
 
        if (cmd->autoneg == AUTONEG_ENABLE) {
                autoneg |= AUTONEG_SPEED;
@@ -5148,44 +5484,41 @@ bnx2_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                        (cmd->advertising == ADVERTISED_100baseT_Half) ||
                        (cmd->advertising == ADVERTISED_100baseT_Full)) {
 
-                       if (bp->phy_flags & PHY_SERDES_FLAG)
-                               return -EINVAL;
+                       if (cmd->port == PORT_FIBRE)
+                               goto err_out_unlock;
 
                        advertising = cmd->advertising;
 
                } else if (cmd->advertising == ADVERTISED_2500baseX_Full) {
-                       if (!(bp->phy_flags & PHY_2_5G_CAPABLE_FLAG))
-                               return -EINVAL;
-               } else if (cmd->advertising == ADVERTISED_1000baseT_Full) {
+                       if (!(bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) ||
+                           (cmd->port == PORT_TP))
+                               goto err_out_unlock;
+               } else if (cmd->advertising == ADVERTISED_1000baseT_Full)
                        advertising = cmd->advertising;
-               }
-               else if (cmd->advertising == ADVERTISED_1000baseT_Half) {
-                       return -EINVAL;
-               }
+               else if (cmd->advertising == ADVERTISED_1000baseT_Half)
+                       goto err_out_unlock;
                else {
-                       if (bp->phy_flags & PHY_SERDES_FLAG) {
+                       if (cmd->port == PORT_FIBRE)
                                advertising = ETHTOOL_ALL_FIBRE_SPEED;
-                       }
-                       else {
+                       else
                                advertising = ETHTOOL_ALL_COPPER_SPEED;
-                       }
                }
                advertising |= ADVERTISED_Autoneg;
        }
        else {
-               if (bp->phy_flags & PHY_SERDES_FLAG) {
+               if (cmd->port == PORT_FIBRE) {
                        if ((cmd->speed != SPEED_1000 &&
                             cmd->speed != SPEED_2500) ||
                            (cmd->duplex != DUPLEX_FULL))
-                               return -EINVAL;
+                               goto err_out_unlock;
 
                        if (cmd->speed == SPEED_2500 &&
                            !(bp->phy_flags & PHY_2_5G_CAPABLE_FLAG))
-                               return -EINVAL;
-               }
-               else if (cmd->speed == SPEED_1000) {
-                       return -EINVAL;
+                               goto err_out_unlock;
                }
+               else if (cmd->speed == SPEED_1000 || cmd->speed == SPEED_2500)
+                       goto err_out_unlock;
+
                autoneg &= ~AUTONEG_SPEED;
                req_line_speed = cmd->speed;
                req_duplex = cmd->duplex;
@@ -5197,13 +5530,12 @@ bnx2_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
        bp->req_line_speed = req_line_speed;
        bp->req_duplex = req_duplex;
 
-       spin_lock_bh(&bp->phy_lock);
-
-       bnx2_setup_phy(bp);
+       err = bnx2_setup_phy(bp, cmd->port);
 
+err_out_unlock:
        spin_unlock_bh(&bp->phy_lock);
 
-       return 0;
+       return err;
 }
 
 static void
@@ -5214,11 +5546,7 @@ bnx2_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
        strcpy(info->driver, DRV_MODULE_NAME);
        strcpy(info->version, DRV_MODULE_VERSION);
        strcpy(info->bus_info, pci_name(bp->pdev));
-       info->fw_version[0] = ((bp->fw_ver & 0xff000000) >> 24) + '0';
-       info->fw_version[2] = ((bp->fw_ver & 0xff0000) >> 16) + '0';
-       info->fw_version[4] = ((bp->fw_ver & 0xff00) >> 8) + '0';
-       info->fw_version[1] = info->fw_version[3] = '.';
-       info->fw_version[5] = 0;
+       strcpy(info->fw_version, bp->fw_version);
 }
 
 #define BNX2_REGDUMP_LEN               (32 * 1024)
@@ -5330,6 +5658,14 @@ bnx2_nway_reset(struct net_device *dev)
 
        spin_lock_bh(&bp->phy_lock);
 
+       if (bp->phy_flags & REMOTE_PHY_CAP_FLAG) {
+               int rc;
+
+               rc = bnx2_setup_remote_phy(bp, bp->phy_port);
+               spin_unlock_bh(&bp->phy_lock);
+               return rc;
+       }
+
        /* Force a link down visible on the other side */
        if (bp->phy_flags & PHY_SERDES_FLAG) {
                bnx2_write_phy(bp, bp->mii_bmcr, BMCR_LOOPBACK);
@@ -5543,7 +5879,7 @@ bnx2_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause)
 
        spin_lock_bh(&bp->phy_lock);
 
-       bnx2_setup_phy(bp);
+       bnx2_setup_phy(bp, bp->phy_port);
 
        spin_unlock_bh(&bp->phy_lock);
 
@@ -5939,6 +6275,9 @@ bnx2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
        case SIOCGMIIREG: {
                u32 mii_regval;
 
+               if (bp->phy_flags & REMOTE_PHY_CAP_FLAG)
+                       return -EOPNOTSUPP;
+
                if (!netif_running(dev))
                        return -EAGAIN;
 
@@ -5955,6 +6294,9 @@ bnx2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
                if (!capable(CAP_NET_ADMIN))
                        return -EPERM;
 
+               if (bp->phy_flags & REMOTE_PHY_CAP_FLAG)
+                       return -EOPNOTSUPP;
+
                if (!netif_running(dev))
                        return -EAGAIN;
 
@@ -6116,7 +6458,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
 {
        struct bnx2 *bp;
        unsigned long mem_len;
-       int rc;
+       int rc, i, j;
        u32 reg;
        u64 dma_mask, persist_dma_mask;
 
@@ -6273,7 +6615,35 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
                goto err_out_unmap;
        }
 
-       bp->fw_ver = REG_RD_IND(bp, bp->shmem_base + BNX2_DEV_INFO_BC_REV);
+       reg = REG_RD_IND(bp, bp->shmem_base + BNX2_DEV_INFO_BC_REV);
+       for (i = 0, j = 0; i < 3; i++) {
+               u8 num, k, skip0;
+
+               num = (u8) (reg >> (24 - (i * 8)));
+               for (k = 100, skip0 = 1; k >= 1; num %= k, k /= 10) {
+                       if (num >= k || !skip0 || k == 1) {
+                               bp->fw_version[j++] = (num / k) + '0';
+                               skip0 = 0;
+                       }
+               }
+               if (i != 2)
+                       bp->fw_version[j++] = '.';
+       }
+       reg = REG_RD_IND(bp, bp->shmem_base + BNX2_BC_STATE_CONDITION);
+       reg &= BNX2_CONDITION_MFW_RUN_MASK;
+       if (reg != BNX2_CONDITION_MFW_RUN_UNKNOWN &&
+           reg != BNX2_CONDITION_MFW_RUN_NONE) {
+               int i;
+               u32 addr = REG_RD_IND(bp, bp->shmem_base + BNX2_MFW_VER_PTR);
+
+               bp->fw_version[j++] = ' ';
+               for (i = 0; i < 3; i++) {
+                       reg = REG_RD_IND(bp, addr + i * 4);
+                       reg = swab32(reg);
+                       memcpy(&bp->fw_version[j], &reg, 4);
+                       j += 4;
+               }
+       }
 
        reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_MAC_UPPER);
        bp->mac_addr[0] = (u8) (reg >> 8);
@@ -6315,7 +6685,9 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
        else if (CHIP_BOND_ID(bp) & CHIP_BOND_ID_SERDES_BIT)
                bp->phy_flags |= PHY_SERDES_FLAG;
 
+       bp->phy_port = PORT_TP;
        if (bp->phy_flags & PHY_SERDES_FLAG) {
+               bp->phy_port = PORT_FIBRE;
                bp->flags |= NO_WOL_FLAG;
                if (CHIP_NUM(bp) != CHIP_NUM_5706) {
                        bp->phy_addr = 2;
@@ -6324,6 +6696,8 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
                        if (reg & BNX2_SHARED_HW_CFG_PHY_2_5G)
                                bp->phy_flags |= PHY_2_5G_CAPABLE_FLAG;
                }
+               bnx2_init_remote_phy(bp);
+
        } else if (CHIP_NUM(bp) == CHIP_NUM_5706 ||
                   CHIP_NUM(bp) == CHIP_NUM_5708)
                bp->phy_flags |= PHY_CRC_FIX_FLAG;
@@ -6363,10 +6737,9 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
                while ((amd_8132 = pci_get_device(PCI_VENDOR_ID_AMD,
                                                  PCI_DEVICE_ID_AMD_8132_BRIDGE,
                                                  amd_8132))) {
-                       u8 rev;
 
-                       pci_read_config_byte(amd_8132, PCI_REVISION_ID, &rev);
-                       if (rev >= 0x10 && rev <= 0x13) {
+                       if (amd_8132->revision >= 0x10 &&
+                           amd_8132->revision <= 0x13) {
                                disable_msi = 1;
                                pci_dev_put(amd_8132);
                                break;
@@ -6374,23 +6747,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
                }
        }
 
-       bp->autoneg = AUTONEG_SPEED | AUTONEG_FLOW_CTRL;
-       bp->req_line_speed = 0;
-       if (bp->phy_flags & PHY_SERDES_FLAG) {
-               bp->advertising = ETHTOOL_ALL_FIBRE_SPEED | ADVERTISED_Autoneg;
-
-               reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_CONFIG);
-               reg &= BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK;
-               if (reg == BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G) {
-                       bp->autoneg = 0;
-                       bp->req_line_speed = bp->line_speed = SPEED_1000;
-                       bp->req_duplex = DUPLEX_FULL;
-               }
-       }
-       else {
-               bp->advertising = ETHTOOL_ALL_COPPER_SPEED | ADVERTISED_Autoneg;
-       }
-
+       bnx2_set_default_link(bp);
        bp->req_flow_ctrl = FLOW_CTRL_RX | FLOW_CTRL_TX;
 
        init_timer(&bp->timer);
@@ -6490,10 +6847,10 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        memcpy(dev->perm_addr, bp->mac_addr, 6);
        bp->name = board_info[ent->driver_data].name;
 
+       dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
        if (CHIP_NUM(bp) == CHIP_NUM_5709)
-               dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG;
-       else
-               dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
+               dev->features |= NETIF_F_IPV6_CSUM;
+
 #ifdef BCM_VLAN
        dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
 #endif
index 49a5de253b17ff1af7f18fcfc7c92cacc0e7a2cb..d8cd1afeb23d2b386c8300eb60911cfe26c107f3 100644 (file)
@@ -6338,6 +6338,8 @@ struct l2_fhdr {
 
 #define RX_COPY_THRESH                 92
 
+#define BNX2_MISC_ENABLE_DEFAULT       0x7ffffff
+
 #define DMA_READ_CHANS 5
 #define DMA_WRITE_CHANS        3
 
@@ -6537,6 +6539,7 @@ struct bnx2 {
 #define PHY_INT_MODE_AUTO_POLLING_FLAG 0x100
 #define PHY_INT_MODE_LINK_READY_FLAG   0x200
 #define PHY_DIS_EARLY_DAC_FLAG         0x400
+#define REMOTE_PHY_CAP_FLAG            0x800
 
        u32                     mii_bmcr;
        u32                     mii_bmsr;
@@ -6625,6 +6628,7 @@ struct bnx2 {
        u16                     req_line_speed;
        u8                      req_duplex;
 
+       u8                      phy_port;
        u8                      link_up;
 
        u16                     line_speed;
@@ -6656,7 +6660,7 @@ struct bnx2 {
 
        u32                     shmem_base;
 
-       u32                     fw_ver;
+       char                    fw_version[32];
 
        int                     pm_cap;
        int                     pcix_cap;
@@ -6770,7 +6774,7 @@ struct fw_info {
  * the firmware has timed out, the driver will assume there is no firmware
  * running and there won't be any firmware-driver synchronization during a
  * driver reset. */
-#define FW_ACK_TIME_OUT_MS                  100
+#define FW_ACK_TIME_OUT_MS                  1000
 
 
 #define BNX2_DRV_RESET_SIGNATURE               0x00000000
@@ -6788,6 +6792,7 @@ struct fw_info {
 #define BNX2_DRV_MSG_CODE_DIAG                  0x07000000
 #define BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL        0x09000000
 #define BNX2_DRV_MSG_CODE_UNLOAD_LNK_DN                 0x0b000000
+#define BNX2_DRV_MSG_CODE_CMD_SET_LINK          0x10000000
 
 #define BNX2_DRV_MSG_DATA                       0x00ff0000
 #define BNX2_DRV_MSG_DATA_WAIT0                         0x00010000
@@ -6836,6 +6841,7 @@ struct fw_info {
 #define BNX2_LINK_STATUS_SERDES_LINK            (1<<20)
 #define BNX2_LINK_STATUS_PARTNER_AD_2500FULL    (1<<21)
 #define BNX2_LINK_STATUS_PARTNER_AD_2500HALF    (1<<22)
+#define BNX2_LINK_STATUS_HEART_BEAT_EXPIRED     (1<<31)
 
 #define BNX2_DRV_PULSE_MB                      0x00000010
 #define BNX2_DRV_PULSE_SEQ_MASK                         0x00007fff
@@ -6845,6 +6851,30 @@ struct fw_info {
  * This is used for debugging. */
 #define BNX2_DRV_MSG_DATA_PULSE_CODE_ALWAYS_ALIVE       0x00080000
 
+#define BNX2_DRV_MB_ARG0                       0x00000014
+#define BNX2_NETLINK_SET_LINK_SPEED_10HALF      (1<<0)
+#define BNX2_NETLINK_SET_LINK_SPEED_10FULL      (1<<1)
+#define BNX2_NETLINK_SET_LINK_SPEED_10          \
+       (BNX2_NETLINK_SET_LINK_SPEED_10HALF |    \
+        BNX2_NETLINK_SET_LINK_SPEED_10FULL)
+#define BNX2_NETLINK_SET_LINK_SPEED_100HALF     (1<<2)
+#define BNX2_NETLINK_SET_LINK_SPEED_100FULL     (1<<3)
+#define BNX2_NETLINK_SET_LINK_SPEED_100                 \
+       (BNX2_NETLINK_SET_LINK_SPEED_100HALF |   \
+        BNX2_NETLINK_SET_LINK_SPEED_100FULL)
+#define BNX2_NETLINK_SET_LINK_SPEED_1GHALF      (1<<4)
+#define BNX2_NETLINK_SET_LINK_SPEED_1GFULL      (1<<5)
+#define BNX2_NETLINK_SET_LINK_SPEED_2G5HALF     (1<<6)
+#define BNX2_NETLINK_SET_LINK_SPEED_2G5FULL     (1<<7)
+#define BNX2_NETLINK_SET_LINK_SPEED_10GHALF     (1<<8)
+#define BNX2_NETLINK_SET_LINK_SPEED_10GFULL     (1<<9)
+#define BNX2_NETLINK_SET_LINK_ENABLE_AUTONEG    (1<<10)
+#define BNX2_NETLINK_SET_LINK_PHY_APP_REMOTE    (1<<11)
+#define BNX2_NETLINK_SET_LINK_FC_SYM_PAUSE      (1<<12)
+#define BNX2_NETLINK_SET_LINK_FC_ASYM_PAUSE     (1<<13)
+#define BNX2_NETLINK_SET_LINK_ETH_AT_WIRESPEED  (1<<14)
+#define BNX2_NETLINK_SET_LINK_PHY_RESET                 (1<<15)
+
 #define BNX2_DEV_INFO_SIGNATURE                        0x00000020
 #define BNX2_DEV_INFO_SIGNATURE_MAGIC           0x44564900
 #define BNX2_DEV_INFO_SIGNATURE_MAGIC_MASK      0xffffff00
@@ -7006,6 +7036,8 @@ struct fw_info {
 #define BNX2_PORT_FEATURE_MBA_VLAN_TAG_MASK     0xffff
 #define BNX2_PORT_FEATURE_MBA_VLAN_ENABLE       0x10000
 
+#define BNX2_MFW_VER_PTR                       0x00000014c
+
 #define BNX2_BC_STATE_RESET_TYPE               0x000001c0
 #define BNX2_BC_STATE_RESET_TYPE_SIG            0x00005254
 #define BNX2_BC_STATE_RESET_TYPE_SIG_MASK       0x0000ffff
@@ -7059,12 +7091,42 @@ struct fw_info {
 #define BNX2_BC_STATE_ERR_NO_RXP                (BNX2_BC_STATE_SIGN | 0x0600)
 #define BNX2_BC_STATE_ERR_TOO_MANY_RBUF                 (BNX2_BC_STATE_SIGN | 0x0700)
 
+#define BNX2_BC_STATE_CONDITION                        0x000001c8
+#define BNX2_CONDITION_MFW_RUN_UNKNOWN          0x00000000
+#define BNX2_CONDITION_MFW_RUN_IPMI             0x00002000
+#define BNX2_CONDITION_MFW_RUN_UMP              0x00004000
+#define BNX2_CONDITION_MFW_RUN_NCSI             0x00006000
+#define BNX2_CONDITION_MFW_RUN_NONE             0x0000e000
+#define BNX2_CONDITION_MFW_RUN_MASK             0x0000e000
+
 #define BNX2_BC_STATE_DEBUG_CMD                        0x1dc
 #define BNX2_BC_STATE_BC_DBG_CMD_SIGNATURE      0x42440000
 #define BNX2_BC_STATE_BC_DBG_CMD_SIGNATURE_MASK         0xffff0000
 #define BNX2_BC_STATE_BC_DBG_CMD_LOOP_CNT_MASK  0xffff
 #define BNX2_BC_STATE_BC_DBG_CMD_LOOP_INFINITE  0xffff
 
+#define BNX2_FW_EVT_CODE_MB                    0x354
+#define BNX2_FW_EVT_CODE_SW_TIMER_EXPIRATION_EVENT 0x00000000
+#define BNX2_FW_EVT_CODE_LINK_EVENT             0x00000001
+
+#define BNX2_DRV_ACK_CAP_MB                    0x364
+#define BNX2_DRV_ACK_CAP_SIGNATURE              0x35450000
+#define BNX2_CAPABILITY_SIGNATURE_MASK          0xFFFF0000
+
+#define BNX2_FW_CAP_MB                         0x368
+#define BNX2_FW_CAP_SIGNATURE                   0xaa550000
+#define BNX2_FW_ACK_DRV_SIGNATURE               0x52500000
+#define BNX2_FW_CAP_SIGNATURE_MASK              0xffff0000
+#define BNX2_FW_CAP_REMOTE_PHY_CAPABLE          0x00000001
+#define BNX2_FW_CAP_REMOTE_PHY_PRESENT          0x00000002
+
+#define BNX2_RPHY_SIGNATURE                    0x36c
+#define BNX2_RPHY_LOAD_SIGNATURE                0x5a5a5a5a
+
+#define BNX2_RPHY_FLAGS                                0x370
+#define BNX2_RPHY_SERDES_LINK                  0x374
+#define BNX2_RPHY_COPPER_LINK                  0x378
+
 #define HOST_VIEW_SHMEM_BASE                   0x167c00
 
 #endif
index 6287ffbda7f794c4d2312bc421d4f12fb1b32456..cb9cb3013f4250d7fbf302b4495fa069abd47efa 100644 (file)
@@ -187,7 +187,7 @@ static void bond_send_gratuitous_arp(struct bonding *bond);
 
 /*---------------------------- General routines -----------------------------*/
 
-const char *bond_mode_name(int mode)
+static const char *bond_mode_name(int mode)
 {
        switch (mode) {
        case BOND_MODE_ROUNDROBIN :
@@ -1224,7 +1224,8 @@ static void bond_detach_slave(struct bonding *bond, struct slave *slave)
 
 /*---------------------------------- IOCTL ----------------------------------*/
 
-int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_dev)
+static int bond_sethwaddr(struct net_device *bond_dev,
+                         struct net_device *slave_dev)
 {
        dprintk("bond_dev=%p\n", bond_dev);
        dprintk("slave_dev=%p\n", slave_dev);
@@ -1390,6 +1391,11 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
                goto err_free;
        }
 
+       res = netdev_set_master(slave_dev, bond_dev);
+       if (res) {
+               dprintk("Error %d calling netdev_set_master\n", res);
+               goto err_close;
+       }
        /* open the slave since the application closed it */
        res = dev_open(slave_dev);
        if (res) {
@@ -1397,12 +1403,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
                goto err_restore_mac;
        }
 
-       res = netdev_set_master(slave_dev, bond_dev);
-       if (res) {
-               dprintk("Error %d calling netdev_set_master\n", res);
-               goto err_close;
-       }
-
        new_slave->dev = slave_dev;
        slave_dev->priv_flags |= IFF_BONDING;
 
index a89102116ccb22e670f383ea9b7df0d6091db9eb..6dcbd25e3ef03671dce73fd1b5aa2d9399898b08 100644 (file)
@@ -301,13 +301,11 @@ int bond_create_slave_symlinks(struct net_device *master, struct net_device *sla
 void bond_destroy_slave_symlinks(struct net_device *master, struct net_device *slave);
 int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev);
 int bond_release(struct net_device *bond_dev, struct net_device *slave_dev);
-int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_dev);
 void bond_mii_monitor(struct net_device *bond_dev);
 void bond_loadbalance_arp_mon(struct net_device *bond_dev);
 void bond_activebackup_arp_mon(struct net_device *bond_dev);
 void bond_set_mode_ops(struct bonding *bond, int mode);
 int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl);
-const char *bond_mode_name(int mode);
 void bond_select_active_slave(struct bonding *bond);
 void bond_change_active_slave(struct bonding *bond, struct slave *new_active);
 void bond_register_arp(struct bonding *);
index 59b9943b077d4225c236a1a702fc5d9fbaa82f4b..f6e4030c73d118c043ca7daebfdc051ef78320f3 100644 (file)
@@ -3422,21 +3422,19 @@ done:
 static void cas_check_pci_invariants(struct cas *cp)
 {
        struct pci_dev *pdev = cp->pdev;
-       u8 rev;
 
        cp->cas_flags = 0;
-       pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
        if ((pdev->vendor == PCI_VENDOR_ID_SUN) &&
            (pdev->device == PCI_DEVICE_ID_SUN_CASSINI)) {
-               if (rev >= CAS_ID_REVPLUS)
+               if (pdev->revision >= CAS_ID_REVPLUS)
                        cp->cas_flags |= CAS_FLAG_REG_PLUS;
-               if (rev < CAS_ID_REVPLUS02u)
+               if (pdev->revision < CAS_ID_REVPLUS02u)
                        cp->cas_flags |= CAS_FLAG_TARGET_ABORT;
 
                /* Original Cassini supports HW CSUM, but it's not
                 * enabled by default as it can trigger TX hangs.
                 */
-               if (rev < CAS_ID_REV2)
+               if (pdev->revision < CAS_ID_REV2)
                        cp->cas_flags |= CAS_FLAG_NO_HW_CSUM;
        } else {
                /* Only sun has original cassini chips.  */
@@ -4919,13 +4917,13 @@ static int __devinit cas_init_one(struct pci_dev *pdev,
        pci_cmd &= ~PCI_COMMAND_SERR;
        pci_cmd |= PCI_COMMAND_PARITY;
        pci_write_config_word(pdev, PCI_COMMAND, pci_cmd);
-       if (pci_set_mwi(pdev))
+       if (pci_try_set_mwi(pdev))
                printk(KERN_WARNING PFX "Could not enable MWI for %s\n",
                       pci_name(pdev));
 
        /*
         * On some architectures, the default cache line size set
-        * by pci_set_mwi reduces perforamnce.  We have to increase
+        * by pci_try_set_mwi reduces perforamnce.  We have to increase
         * it for this case.  To start, we'll print some configuration
         * data.
         */
index 80c3d8f268a7091edce2bd01f05174b1fc065afc..ab72563b81ee569ce7f9a139203762dcc5598314 100644 (file)
@@ -71,27 +71,29 @@ enum {                              /* adapter flags */
        QUEUES_BOUND = (1 << 3),
 };
 
+struct fl_pg_chunk {
+       struct page *page;
+       void *va;
+       unsigned int offset;
+};
+
 struct rx_desc;
 struct rx_sw_desc;
 
-struct sge_fl_page {
-       struct skb_frag_struct frag;
-       unsigned char *va;
-};
-
-struct sge_fl {                        /* SGE per free-buffer list state */
-       unsigned int buf_size;  /* size of each Rx buffer */
-       unsigned int credits;   /* # of available Rx buffers */
-       unsigned int size;      /* capacity of free list */
-       unsigned int cidx;      /* consumer index */
-       unsigned int pidx;      /* producer index */
-       unsigned int gen;       /* free list generation */
-       unsigned int cntxt_id;  /* SGE context id for the free list */
-       struct sge_fl_page page;
-       struct rx_desc *desc;   /* address of HW Rx descriptor ring */
-       struct rx_sw_desc *sdesc;       /* address of SW Rx descriptor ring */
-       dma_addr_t phys_addr;   /* physical address of HW ring start */
-       unsigned long empty;    /* # of times queue ran out of buffers */
+struct sge_fl {                     /* SGE per free-buffer list state */
+       unsigned int buf_size;      /* size of each Rx buffer */
+       unsigned int credits;       /* # of available Rx buffers */
+       unsigned int size;          /* capacity of free list */
+       unsigned int cidx;          /* consumer index */
+       unsigned int pidx;          /* producer index */
+       unsigned int gen;           /* free list generation */
+       struct fl_pg_chunk pg_chunk;/* page chunk cache */
+       unsigned int use_pages;     /* whether FL uses pages or sk_buffs */
+       struct rx_desc *desc;       /* address of HW Rx descriptor ring */
+       struct rx_sw_desc *sdesc;   /* address of SW Rx descriptor ring */
+       dma_addr_t   phys_addr;     /* physical address of HW ring start */
+       unsigned int cntxt_id;      /* SGE context id for the free list */
+       unsigned long empty;        /* # of times queue ran out of buffers */
        unsigned long alloc_failed; /* # of times buffer allocation failed */
 };
 
index 8d1379633698737835b28e66bb0f9c2bd1e067b0..16378004507ad65c253b0b6df22c4c600897e00f 100644 (file)
@@ -101,6 +101,7 @@ enum {
        TCB_SIZE = 128,         /* TCB size */
        NMTUS = 16,             /* size of MTU table */
        NCCTRL_WIN = 32,        /* # of congestion control windows */
+       PROTO_SRAM_LINES = 128, /* size of TP sram */
 };
 
 #define MAX_RX_COALESCING_LEN 16224U
@@ -123,6 +124,30 @@ enum {                             /* adapter interrupt-maintained statistics */
        IRQ_NUM_STATS           /* keep last */
 };
 
+enum {
+       TP_VERSION_MAJOR        = 1,
+       TP_VERSION_MINOR        = 0,
+       TP_VERSION_MICRO        = 44
+};
+
+#define S_TP_VERSION_MAJOR             16
+#define M_TP_VERSION_MAJOR             0xFF
+#define V_TP_VERSION_MAJOR(x)          ((x) << S_TP_VERSION_MAJOR)
+#define G_TP_VERSION_MAJOR(x)          \
+           (((x) >> S_TP_VERSION_MAJOR) & M_TP_VERSION_MAJOR)
+
+#define S_TP_VERSION_MINOR             8
+#define M_TP_VERSION_MINOR             0xFF
+#define V_TP_VERSION_MINOR(x)          ((x) << S_TP_VERSION_MINOR)
+#define G_TP_VERSION_MINOR(x)          \
+           (((x) >> S_TP_VERSION_MINOR) & M_TP_VERSION_MINOR)
+
+#define S_TP_VERSION_MICRO             0
+#define M_TP_VERSION_MICRO             0xFF
+#define V_TP_VERSION_MICRO(x)          ((x) << S_TP_VERSION_MICRO)
+#define G_TP_VERSION_MICRO(x)          \
+           (((x) >> S_TP_VERSION_MICRO) & M_TP_VERSION_MICRO)
+
 enum {
        SGE_QSETS = 8,          /* # of SGE Tx/Rx/RspQ sets */
        SGE_RXQ_PER_SET = 2,    /* # of Rx queues per set */
@@ -654,6 +679,9 @@ const struct adapter_info *t3_get_adapter_info(unsigned int board_id);
 int t3_seeprom_read(struct adapter *adapter, u32 addr, u32 *data);
 int t3_seeprom_write(struct adapter *adapter, u32 addr, u32 data);
 int t3_seeprom_wp(struct adapter *adapter, int enable);
+int t3_check_tpsram_version(struct adapter *adapter);
+int t3_check_tpsram(struct adapter *adapter, u8 *tp_ram, unsigned int size);
+int t3_set_proto_sram(struct adapter *adap, u8 *data);
 int t3_read_flash(struct adapter *adapter, unsigned int addr,
                  unsigned int nwords, u32 *data, int byte_oriented);
 int t3_load_fw(struct adapter *adapter, const u8 * fw_data, unsigned int size);
index d8a1f5452c51513092a2504548a6c8998d038a39..6fd1e5241833d7e2f68800f092ade1074e27256a 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/proc_fs.h>
 #include <linux/rtnetlink.h>
 #include <linux/firmware.h>
+#include <linux/log2.h>
 #include <asm/uaccess.h>
 
 #include "common.h"
@@ -1818,8 +1819,8 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
                        return -EBUSY;
                if (copy_from_user(&m, useraddr, sizeof(m)))
                        return -EFAULT;
-               if (!m.rx_pg_sz || (m.rx_pg_sz & (m.rx_pg_sz - 1)) ||
-                       !m.tx_pg_sz || (m.tx_pg_sz & (m.tx_pg_sz - 1)))
+               if (!is_power_of_2(m.rx_pg_sz) ||
+                       !is_power_of_2(m.tx_pg_sz))
                        return -EINVAL; /* not power of 2 */
                if (!(m.rx_pg_sz & 0x14000))
                        return -EINVAL; /* not 16KB or 64KB */
@@ -2088,6 +2089,42 @@ static void cxgb_netpoll(struct net_device *dev)
 }
 #endif
 
+#define TPSRAM_NAME "t3%c_protocol_sram-%d.%d.%d.bin"
+int update_tpsram(struct adapter *adap)
+{
+       const struct firmware *tpsram;
+       char buf[64];
+       struct device *dev = &adap->pdev->dev;
+       int ret;
+       char rev;
+       
+       rev = adap->params.rev == T3_REV_B2 ? 'b' : 'a';
+
+       snprintf(buf, sizeof(buf), TPSRAM_NAME, rev,
+                TP_VERSION_MAJOR, TP_VERSION_MINOR, TP_VERSION_MICRO);
+
+       ret = request_firmware(&tpsram, buf, dev);
+       if (ret < 0) {
+               dev_err(dev, "could not load TP SRAM: unable to load %s\n",
+                       buf);
+               return ret;
+       }
+       
+       ret = t3_check_tpsram(adap, tpsram->data, tpsram->size);
+       if (ret)
+               goto release_tpsram;    
+
+       ret = t3_set_proto_sram(adap, tpsram->data);
+       if (ret)
+               dev_err(dev, "loading protocol SRAM failed\n");
+
+release_tpsram:
+       release_firmware(tpsram);
+       
+       return ret;
+}
+
+
 /*
  * Periodic accumulation of MAC statistics.
  */
@@ -2437,6 +2474,13 @@ static int __devinit init_one(struct pci_dev *pdev,
                goto out_free_dev;
        }
 
+       err = t3_check_tpsram_version(adapter);
+       if (err == -EINVAL)
+               err = update_tpsram(adapter);
+
+       if (err)
+               goto out_free_dev;
+               
        /*
         * The card is now ready to go.  If any errors occur during device
         * registration we do not fail the whole card but rather proceed only
index 020859c855d7c6836657ab133484f0d7d6aa4ef5..aa80313c922ef3913e5f85796c51921111505a45 100644 (file)
 
 #define A_TP_MOD_CHANNEL_WEIGHT 0x434
 
+#define A_TP_MOD_RATE_LIMIT 0x438
+
 #define A_TP_PIO_ADDR 0x440
 
 #define A_TP_PIO_DATA 0x444
 #define G_TXDROPCNTCH0RCVD(x) (((x) >> S_TXDROPCNTCH0RCVD) & \
                               M_TXDROPCNTCH0RCVD)
 
+#define A_TP_PROXY_FLOW_CNTL 0x4b0
+
+#define A_TP_EMBED_OP_FIELD0 0x4e8
+#define A_TP_EMBED_OP_FIELD1 0x4ec
+#define A_TP_EMBED_OP_FIELD2 0x4f0
+#define A_TP_EMBED_OP_FIELD3 0x4f4
+#define A_TP_EMBED_OP_FIELD4 0x4f8
+#define A_TP_EMBED_OP_FIELD5 0x4fc
+
 #define A_ULPRX_CTL 0x500
 
 #define S_ROUND_ROBIN    4
index a60ec4d4707c50c2919bf2f99cd5f5051f3d483a..a2cfd68ac757555e42b13309f019146f6a6f00e4 100644 (file)
 
 #define SGE_RX_SM_BUF_SIZE 1536
 
-/*
- * If USE_RX_PAGE is defined, the small freelist populated with (partial)
- * pages instead of skbs. Pages are carved up into RX_PAGE_SIZE chunks (must
- * be a multiple of the host page size).
- */
-#define USE_RX_PAGE
-#define RX_PAGE_SIZE 2048
-
-/*
- * skb freelist packets are copied into a new skb (and the freelist one is 
- * reused) if their len is <= 
- */
 #define SGE_RX_COPY_THRES  256
+#define SGE_RX_PULL_LEN    128
 
 /*
- * Minimum number of freelist entries before we start dropping TUNNEL frames.
+ * Page chunk size for FL0 buffers if FL0 is to be populated with page chunks.
+ * It must be a divisor of PAGE_SIZE.  If set to 0 FL0 will use sk_buffs
+ * directly.
  */
+#define FL0_PG_CHUNK_SIZE  2048
+
 #define SGE_RX_DROP_THRES 16
 
 /*
@@ -100,12 +93,12 @@ struct tx_sw_desc {                /* SW state per Tx descriptor */
        struct sk_buff *skb;
 };
 
-struct rx_sw_desc {            /* SW state per Rx descriptor */
+struct rx_sw_desc {                /* SW state per Rx descriptor */
        union {
                struct sk_buff *skb;
-               struct sge_fl_page page;
-       } t;
-        DECLARE_PCI_UNMAP_ADDR(dma_addr);
+               struct fl_pg_chunk pg_chunk;
+       };
+       DECLARE_PCI_UNMAP_ADDR(dma_addr);
 };
 
 struct rsp_desc {              /* response queue descriptor */
@@ -351,27 +344,26 @@ static void free_rx_bufs(struct pci_dev *pdev, struct sge_fl *q)
 
                pci_unmap_single(pdev, pci_unmap_addr(d, dma_addr),
                                 q->buf_size, PCI_DMA_FROMDEVICE);
-
-               if (q->buf_size != RX_PAGE_SIZE) {
-                       kfree_skb(d->t.skb);
-                       d->t.skb = NULL;
+               if (q->use_pages) {
+                       put_page(d->pg_chunk.page);
+                       d->pg_chunk.page = NULL;
                } else {
-                       if (d->t.page.frag.page)
-                               put_page(d->t.page.frag.page);
-                       d->t.page.frag.page = NULL;
+                       kfree_skb(d->skb);
+                       d->skb = NULL;
                }
                if (++cidx == q->size)
                        cidx = 0;
        }
 
-       if (q->page.frag.page)
-               put_page(q->page.frag.page);
-       q->page.frag.page = NULL;
+       if (q->pg_chunk.page) {
+               __free_page(q->pg_chunk.page);
+               q->pg_chunk.page = NULL;
+       }
 }
 
 /**
  *     add_one_rx_buf - add a packet buffer to a free-buffer list
- *     @va: va of the buffer to add
+ *     @va:  buffer start VA
  *     @len: the buffer length
  *     @d: the HW Rx descriptor to write
  *     @sd: the SW Rx descriptor to write
@@ -381,7 +373,7 @@ static void free_rx_bufs(struct pci_dev *pdev, struct sge_fl *q)
  *     Add a buffer of the given length to the supplied HW and SW Rx
  *     descriptors.
  */
-static inline void add_one_rx_buf(unsigned char *va, unsigned int len,
+static inline void add_one_rx_buf(void *va, unsigned int len,
                                  struct rx_desc *d, struct rx_sw_desc *sd,
                                  unsigned int gen, struct pci_dev *pdev)
 {
@@ -397,6 +389,27 @@ static inline void add_one_rx_buf(unsigned char *va, unsigned int len,
        d->gen2 = cpu_to_be32(V_FLD_GEN2(gen));
 }
 
+static int alloc_pg_chunk(struct sge_fl *q, struct rx_sw_desc *sd, gfp_t gfp)
+{
+       if (!q->pg_chunk.page) {
+               q->pg_chunk.page = alloc_page(gfp);
+               if (unlikely(!q->pg_chunk.page))
+                       return -ENOMEM;
+               q->pg_chunk.va = page_address(q->pg_chunk.page);
+               q->pg_chunk.offset = 0;
+       }
+       sd->pg_chunk = q->pg_chunk;
+
+       q->pg_chunk.offset += q->buf_size;
+       if (q->pg_chunk.offset == PAGE_SIZE)
+               q->pg_chunk.page = NULL;
+       else {
+               q->pg_chunk.va += q->buf_size;
+               get_page(q->pg_chunk.page);
+       }
+       return 0;
+}
+
 /**
  *     refill_fl - refill an SGE free-buffer list
  *     @adapter: the adapter
@@ -410,49 +423,29 @@ static inline void add_one_rx_buf(unsigned char *va, unsigned int len,
  */
 static void refill_fl(struct adapter *adap, struct sge_fl *q, int n, gfp_t gfp)
 {
+       void *buf_start;
        struct rx_sw_desc *sd = &q->sdesc[q->pidx];
        struct rx_desc *d = &q->desc[q->pidx];
-       struct sge_fl_page *p = &q->page;
 
        while (n--) {
-               unsigned char *va;
-
-               if (unlikely(q->buf_size != RX_PAGE_SIZE)) {
-                       struct sk_buff *skb = alloc_skb(q->buf_size, gfp);
-
-                       if (!skb) {
-                               q->alloc_failed++;
+               if (q->use_pages) {
+                       if (unlikely(alloc_pg_chunk(q, sd, gfp))) {
+nomem:                         q->alloc_failed++;
                                break;
                        }
-                       va = skb->data;
-                       sd->t.skb = skb;
+                       buf_start = sd->pg_chunk.va;
                } else {
-                       if (!p->frag.page) {
-                               p->frag.page = alloc_pages(gfp, 0);
-                               if (unlikely(!p->frag.page)) {
-                                       q->alloc_failed++;
-                                       break;
-                               } else {
-                                       p->frag.size = RX_PAGE_SIZE;
-                                       p->frag.page_offset = 0;
-                                       p->va = page_address(p->frag.page);
-                               }
-                       }
+                       struct sk_buff *skb = alloc_skb(q->buf_size, gfp);
 
-                       memcpy(&sd->t, p, sizeof(*p));
-                       va = p->va;
+                       if (!skb)
+                               goto nomem;
 
-                       p->frag.page_offset += RX_PAGE_SIZE;
-                       BUG_ON(p->frag.page_offset > PAGE_SIZE);
-                       p->va += RX_PAGE_SIZE;
-                       if (p->frag.page_offset == PAGE_SIZE)
-                               p->frag.page = NULL;
-                       else
-                               get_page(p->frag.page);
+                       sd->skb = skb;
+                       buf_start = skb->data;
                }
 
-               add_one_rx_buf(va, q->buf_size, d, sd, q->gen, adap->pdev);
-
+               add_one_rx_buf(buf_start, q->buf_size, d, sd, q->gen,
+                              adap->pdev);
                d++;
                sd++;
                if (++q->pidx == q->size) {
@@ -487,7 +480,7 @@ static void recycle_rx_buf(struct adapter *adap, struct sge_fl *q,
        struct rx_desc *from = &q->desc[idx];
        struct rx_desc *to = &q->desc[q->pidx];
 
-       memcpy(&q->sdesc[q->pidx], &q->sdesc[idx], sizeof(struct rx_sw_desc));
+       q->sdesc[q->pidx] = q->sdesc[idx];
        to->addr_lo = from->addr_lo;    /* already big endian */
        to->addr_hi = from->addr_hi;    /* likewise */
        wmb();
@@ -649,6 +642,132 @@ static inline unsigned int flits_to_desc(unsigned int n)
        return flit_desc_map[n];
 }
 
+/**
+ *     get_packet - return the next ingress packet buffer from a free list
+ *     @adap: the adapter that received the packet
+ *     @fl: the SGE free list holding the packet
+ *     @len: the packet length including any SGE padding
+ *     @drop_thres: # of remaining buffers before we start dropping packets
+ *
+ *     Get the next packet from a free list and complete setup of the
+ *     sk_buff.  If the packet is small we make a copy and recycle the
+ *     original buffer, otherwise we use the original buffer itself.  If a
+ *     positive drop threshold is supplied packets are dropped and their
+ *     buffers recycled if (a) the number of remaining buffers is under the
+ *     threshold and the packet is too big to copy, or (b) the packet should
+ *     be copied but there is no memory for the copy.
+ */
+static struct sk_buff *get_packet(struct adapter *adap, struct sge_fl *fl,
+                                 unsigned int len, unsigned int drop_thres)
+{
+       struct sk_buff *skb = NULL;
+       struct rx_sw_desc *sd = &fl->sdesc[fl->cidx];
+
+       prefetch(sd->skb->data);
+       fl->credits--;
+
+       if (len <= SGE_RX_COPY_THRES) {
+               skb = alloc_skb(len, GFP_ATOMIC);
+               if (likely(skb != NULL)) {
+                       __skb_put(skb, len);
+                       pci_dma_sync_single_for_cpu(adap->pdev,
+                                           pci_unmap_addr(sd, dma_addr), len,
+                                           PCI_DMA_FROMDEVICE);
+                       memcpy(skb->data, sd->skb->data, len);
+                       pci_dma_sync_single_for_device(adap->pdev,
+                                           pci_unmap_addr(sd, dma_addr), len,
+                                           PCI_DMA_FROMDEVICE);
+               } else if (!drop_thres)
+                       goto use_orig_buf;
+recycle:
+               recycle_rx_buf(adap, fl, fl->cidx);
+               return skb;
+       }
+
+       if (unlikely(fl->credits < drop_thres))
+               goto recycle;
+
+use_orig_buf:
+       pci_unmap_single(adap->pdev, pci_unmap_addr(sd, dma_addr),
+                        fl->buf_size, PCI_DMA_FROMDEVICE);
+       skb = sd->skb;
+       skb_put(skb, len);
+       __refill_fl(adap, fl);
+       return skb;
+}
+
+/**
+ *     get_packet_pg - return the next ingress packet buffer from a free list
+ *     @adap: the adapter that received the packet
+ *     @fl: the SGE free list holding the packet
+ *     @len: the packet length including any SGE padding
+ *     @drop_thres: # of remaining buffers before we start dropping packets
+ *
+ *     Get the next packet from a free list populated with page chunks.
+ *     If the packet is small we make a copy and recycle the original buffer,
+ *     otherwise we attach the original buffer as a page fragment to a fresh
+ *     sk_buff.  If a positive drop threshold is supplied packets are dropped
+ *     and their buffers recycled if (a) the number of remaining buffers is
+ *     under the threshold and the packet is too big to copy, or (b) there's
+ *     no system memory.
+ *
+ *     Note: this function is similar to @get_packet but deals with Rx buffers
+ *     that are page chunks rather than sk_buffs.
+ */
+static struct sk_buff *get_packet_pg(struct adapter *adap, struct sge_fl *fl,
+                                    unsigned int len, unsigned int drop_thres)
+{
+       struct sk_buff *skb = NULL;
+       struct rx_sw_desc *sd = &fl->sdesc[fl->cidx];
+
+       if (len <= SGE_RX_COPY_THRES) {
+               skb = alloc_skb(len, GFP_ATOMIC);
+               if (likely(skb != NULL)) {
+                       __skb_put(skb, len);
+                       pci_dma_sync_single_for_cpu(adap->pdev,
+                                           pci_unmap_addr(sd, dma_addr), len,
+                                           PCI_DMA_FROMDEVICE);
+                       memcpy(skb->data, sd->pg_chunk.va, len);
+                       pci_dma_sync_single_for_device(adap->pdev,
+                                           pci_unmap_addr(sd, dma_addr), len,
+                                           PCI_DMA_FROMDEVICE);
+               } else if (!drop_thres)
+                       return NULL;
+recycle:
+               fl->credits--;
+               recycle_rx_buf(adap, fl, fl->cidx);
+               return skb;
+       }
+
+       if (unlikely(fl->credits <= drop_thres))
+               goto recycle;
+
+       skb = alloc_skb(SGE_RX_PULL_LEN, GFP_ATOMIC);
+       if (unlikely(!skb)) {
+               if (!drop_thres)
+                       return NULL;
+               goto recycle;
+       }
+
+       pci_unmap_single(adap->pdev, pci_unmap_addr(sd, dma_addr),
+                        fl->buf_size, PCI_DMA_FROMDEVICE);
+       __skb_put(skb, SGE_RX_PULL_LEN);
+       memcpy(skb->data, sd->pg_chunk.va, SGE_RX_PULL_LEN);
+       skb_fill_page_desc(skb, 0, sd->pg_chunk.page,
+                          sd->pg_chunk.offset + SGE_RX_PULL_LEN,
+                          len - SGE_RX_PULL_LEN);
+       skb->len = len;
+       skb->data_len = len - SGE_RX_PULL_LEN;
+       skb->truesize += skb->data_len;
+
+       fl->credits--;
+       /*
+        * We do not refill FLs here, we let the caller do it to overlap a
+        * prefetch.
+        */
+       return skb;
+}
+
 /**
  *     get_imm_packet - return the next ingress packet buffer from a response
  *     @resp: the response descriptor containing the packet data
@@ -1715,85 +1834,6 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq,
                netif_rx(skb);
 }
 
-#define SKB_DATA_SIZE 128
-
-static void skb_data_init(struct sk_buff *skb, struct sge_fl_page *p,
-                         unsigned int len)
-{
-       skb->len = len;
-       if (len <= SKB_DATA_SIZE) {
-               skb_copy_to_linear_data(skb, p->va, len);
-               skb->tail += len;
-               put_page(p->frag.page);
-       } else {
-               skb_copy_to_linear_data(skb, p->va, SKB_DATA_SIZE);
-               skb_shinfo(skb)->frags[0].page = p->frag.page;
-               skb_shinfo(skb)->frags[0].page_offset =
-                   p->frag.page_offset + SKB_DATA_SIZE;
-               skb_shinfo(skb)->frags[0].size = len - SKB_DATA_SIZE;
-               skb_shinfo(skb)->nr_frags = 1;
-               skb->data_len = len - SKB_DATA_SIZE;
-               skb->tail += SKB_DATA_SIZE;
-               skb->truesize += skb->data_len;
-       }
-}
-
-/**
-*      get_packet - return the next ingress packet buffer from a free list
-*      @adap: the adapter that received the packet
-*      @fl: the SGE free list holding the packet
-*      @len: the packet length including any SGE padding
-*      @drop_thres: # of remaining buffers before we start dropping packets
-*
-*      Get the next packet from a free list and complete setup of the
-*      sk_buff.  If the packet is small we make a copy and recycle the
-*      original buffer, otherwise we use the original buffer itself.  If a
-*      positive drop threshold is supplied packets are dropped and their
-*      buffers recycled if (a) the number of remaining buffers is under the
-*      threshold and the packet is too big to copy, or (b) the packet should
-*      be copied but there is no memory for the copy.
-*/
-static struct sk_buff *get_packet(struct adapter *adap, struct sge_fl *fl,
-                                 unsigned int len, unsigned int drop_thres)
-{
-       struct sk_buff *skb = NULL;
-       struct rx_sw_desc *sd = &fl->sdesc[fl->cidx];
-
-       prefetch(sd->t.skb->data);
-
-       if (len <= SGE_RX_COPY_THRES) {
-               skb = alloc_skb(len, GFP_ATOMIC);
-               if (likely(skb != NULL)) {
-                       struct rx_desc *d = &fl->desc[fl->cidx];
-                       dma_addr_t mapping =
-                           (dma_addr_t)((u64) be32_to_cpu(d->addr_hi) << 32 |
-                                        be32_to_cpu(d->addr_lo));
-
-                       __skb_put(skb, len);
-                       pci_dma_sync_single_for_cpu(adap->pdev, mapping, len,
-                                                   PCI_DMA_FROMDEVICE);
-                       skb_copy_from_linear_data(sd->t.skb, skb->data, len);
-                       pci_dma_sync_single_for_device(adap->pdev, mapping, len,
-                                                      PCI_DMA_FROMDEVICE);
-               } else if (!drop_thres)
-                       goto use_orig_buf;
-recycle:
-               recycle_rx_buf(adap, fl, fl->cidx);
-               return skb;
-       }
-
-       if (unlikely(fl->credits < drop_thres))
-               goto recycle;
-
-use_orig_buf:
-       pci_unmap_single(adap->pdev, pci_unmap_addr(sd, dma_addr),
-                        fl->buf_size, PCI_DMA_FROMDEVICE);
-       skb = sd->t.skb;
-       skb_put(skb, len);
-       __refill_fl(adap, fl);
-       return skb;
-}
-
 /**
  *     handle_rsp_cntrl_info - handles control information in a response
  *     @qs: the queue set corresponding to the response
@@ -1935,7 +1975,7 @@ static int process_responses(struct adapter *adap, struct sge_qset *qs,
                } else if (flags & F_RSPD_IMM_DATA_VALID) {
                        skb = get_imm_packet(r);
                        if (unlikely(!skb)) {
-                             no_mem:
+no_mem:
                                q->next_holdoff = NOMEM_INTR_DELAY;
                                q->nomem++;
                                /* consume one credit since we tried */
@@ -1945,53 +1985,29 @@ static int process_responses(struct adapter *adap, struct sge_qset *qs,
                        q->imm_data++;
                        ethpad = 0;
                } else if ((len = ntohl(r->len_cq)) != 0) {
-                       struct sge_fl *fl =
-                           (len & F_RSPD_FLQ) ? &qs->fl[1] : &qs->fl[0];
+                       struct sge_fl *fl;
 
-                       if (fl->buf_size == RX_PAGE_SIZE) {
-                               struct rx_sw_desc *sd = &fl->sdesc[fl->cidx];
-                               struct sge_fl_page *p = &sd->t.page;
-
-                               prefetch(p->va);
-                               prefetch(p->va + L1_CACHE_BYTES);
+                       fl = (len & F_RSPD_FLQ) ? &qs->fl[1] : &qs->fl[0];
+                       if (fl->use_pages) {
+                               void *addr = fl->sdesc[fl->cidx].pg_chunk.va;
 
+                               prefetch(addr);
+#if L1_CACHE_BYTES < 128
+                               prefetch(addr + L1_CACHE_BYTES);
+#endif
                                __refill_fl(adap, fl);
 
-                               pci_unmap_single(adap->pdev,
-                                                pci_unmap_addr(sd, dma_addr),
-                                                fl->buf_size,
-                                                PCI_DMA_FROMDEVICE);
-
-                               if (eth) {
-                                       if (unlikely(fl->credits <
-                                                    SGE_RX_DROP_THRES))
-                                               goto eth_recycle;
-
-                                       skb = alloc_skb(SKB_DATA_SIZE,
-                                                       GFP_ATOMIC);
-                                       if (unlikely(!skb)) {
-eth_recycle:
-                                               q->rx_drops++;
-                                               recycle_rx_buf(adap, fl,
-                                                              fl->cidx);
-                                               goto eth_done;
-                                       }
-                               } else {
-                                       skb = alloc_skb(SKB_DATA_SIZE,
-                                                       GFP_ATOMIC);
-                                       if (unlikely(!skb))
-                                               goto no_mem;
-                               }
-
-                               skb_data_init(skb, p, G_RSPD_LEN(len));
-eth_done:
-                               fl->credits--;
-                               q->eth_pkts++;
-                       } else {
-                               fl->credits--;
+                               skb = get_packet_pg(adap, fl, G_RSPD_LEN(len),
+                                                eth ? SGE_RX_DROP_THRES : 0);
+                       } else
                                skb = get_packet(adap, fl, G_RSPD_LEN(len),
                                                 eth ? SGE_RX_DROP_THRES : 0);
-                       }
+                       if (unlikely(!skb)) {
+                               if (!eth)
+                                       goto no_mem;
+                               q->rx_drops++;
+                       } else if (unlikely(r->rss_hdr.opcode == CPL_TRACE_PKT))
+                               __skb_pull(skb, 2);
 
                        if (++fl->cidx == fl->size)
                                fl->cidx = 0;
@@ -2016,20 +2032,15 @@ eth_done:
                        q->credits = 0;
                }
 
-               if (skb) {
-                       /* Preserve the RSS info in csum & priority */
-                       skb->csum = rss_hi;
-                       skb->priority = rss_lo;
-
+               if (likely(skb != NULL)) {
                        if (eth)
                                rx_eth(adap, q, skb, ethpad);
                        else {
-                               if (unlikely(r->rss_hdr.opcode ==
-                                            CPL_TRACE_PKT))
-                                       __skb_pull(skb, ethpad);
-
-                               ngathered = rx_offload(&adap->tdev, q,
-                                                      skb, offload_skbs,
+                               /* Preserve the RSS info in csum & priority */
+                               skb->csum = rss_hi;
+                               skb->priority = rss_lo;
+                               ngathered = rx_offload(&adap->tdev, q, skb,
+                                                      offload_skbs,
                                                       ngathered);
                        }
                }
@@ -2635,25 +2646,15 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports,
        q->txq[TXQ_ETH].stop_thres = nports *
            flits_to_desc(sgl_len(MAX_SKB_FRAGS + 1) + 3);
 
-       if (!is_offload(adapter)) {
-#ifdef USE_RX_PAGE
-               q->fl[0].buf_size = RX_PAGE_SIZE;
+#if FL0_PG_CHUNK_SIZE > 0
+       q->fl[0].buf_size = FL0_PG_CHUNK_SIZE;
 #else
-               q->fl[0].buf_size = SGE_RX_SM_BUF_SIZE + 2 +
-                   sizeof(struct cpl_rx_pkt);
+       q->fl[0].buf_size = SGE_RX_SM_BUF_SIZE + sizeof(struct cpl_rx_data);
 #endif
-               q->fl[1].buf_size = MAX_FRAME_SIZE + 2 +
-                   sizeof(struct cpl_rx_pkt);
-       } else {
-#ifdef USE_RX_PAGE
-               q->fl[0].buf_size = RX_PAGE_SIZE;
-#else
-               q->fl[0].buf_size = SGE_RX_SM_BUF_SIZE +
-                   sizeof(struct cpl_rx_data);
-#endif
-               q->fl[1].buf_size = (16 * 1024) -
-                   SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
-       }
+       q->fl[0].use_pages = FL0_PG_CHUNK_SIZE > 0;
+       q->fl[1].buf_size = is_offload(adapter) ?
+               (16 * 1024) - SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) :
+               MAX_FRAME_SIZE + 2 + sizeof(struct cpl_rx_pkt);
 
        spin_lock(&adapter->sge.reg_lock);
 
index fb485d0a43d8a768bcc5673c4a3d51b1f5a8f0f3..dd3149d94ba8ed7115e9bd5149d7a26afe5b09f9 100644 (file)
@@ -847,6 +847,64 @@ static int t3_write_flash(struct adapter *adapter, unsigned int addr,
        return 0;
 }
 
+/**
+ *     t3_check_tpsram_version - read the tp sram version
+ *     @adapter: the adapter
+ *
+ *     Reads the protocol sram version from serial eeprom.
+ */
+int t3_check_tpsram_version(struct adapter *adapter)
+{
+       int ret;
+       u32 vers;
+       unsigned int major, minor;
+
+       /* Get version loaded in SRAM */
+       t3_write_reg(adapter, A_TP_EMBED_OP_FIELD0, 0);
+       ret = t3_wait_op_done(adapter, A_TP_EMBED_OP_FIELD0,
+                             1, 1, 5, 1);
+       if (ret)
+               return ret;
+       
+       vers = t3_read_reg(adapter, A_TP_EMBED_OP_FIELD1);
+
+       major = G_TP_VERSION_MAJOR(vers);
+       minor = G_TP_VERSION_MINOR(vers);
+
+       if (major == TP_VERSION_MAJOR && minor == TP_VERSION_MINOR) 
+               return 0;
+
+       return -EINVAL;
+}
+
+/**
+ *     t3_check_tpsram - check if provided protocol SRAM 
+ *                       is compatible with this driver
+ *     @adapter: the adapter
+ *     @tp_sram: the firmware image to write
+ *     @size: image size
+ *
+ *     Checks if an adapter's tp sram is compatible with the driver.
+ *     Returns 0 if the versions are compatible, a negative error otherwise.
+ */
+int t3_check_tpsram(struct adapter *adapter, u8 *tp_sram, unsigned int size)
+{
+       u32 csum;
+       unsigned int i;
+       const u32 *p = (const u32 *)tp_sram;
+
+       /* Verify checksum */
+       for (csum = 0, i = 0; i < size / sizeof(csum); i++)
+               csum += ntohl(p[i]);
+       if (csum != 0xffffffff) {
+               CH_ERR(adapter, "corrupted protocol SRAM image, checksum %u\n",
+                      csum);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 enum fw_version_type {
        FW_VERSION_N3,
        FW_VERSION_T3
@@ -921,7 +979,7 @@ static int t3_flash_erase_sectors(struct adapter *adapter, int start, int end)
 /*
  *     t3_load_fw - download firmware
  *     @adapter: the adapter
- *     @fw_data: the firrware image to write
+ *     @fw_data: the firmware image to write
  *     @size: image size
  *
  *     Write the supplied firmware image to the card's serial flash.
@@ -2362,7 +2420,7 @@ static void tp_config(struct adapter *adap, const struct tp_params *p)
                     F_TCPCHECKSUMOFFLOAD | V_IPTTL(64));
        t3_write_reg(adap, A_TP_TCP_OPTIONS, V_MTUDEFAULT(576) |
                     F_MTUENABLE | V_WINDOWSCALEMODE(1) |
-                    V_TIMESTAMPSMODE(1) | V_SACKMODE(1) | V_SACKRX(1));
+                    V_TIMESTAMPSMODE(0) | V_SACKMODE(1) | V_SACKRX(1));
        t3_write_reg(adap, A_TP_DACK_CONFIG, V_AUTOSTATE3(1) |
                     V_AUTOSTATE2(1) | V_AUTOSTATE1(0) |
                     V_BYTETHRESHOLD(16384) | V_MSSTHRESHOLD(2) |
@@ -2371,16 +2429,18 @@ static void tp_config(struct adapter *adap, const struct tp_params *p)
                         F_IPV6ENABLE | F_NICMODE);
        t3_write_reg(adap, A_TP_TX_RESOURCE_LIMIT, 0x18141814);
        t3_write_reg(adap, A_TP_PARA_REG4, 0x5050105);
-       t3_set_reg_field(adap, A_TP_PARA_REG6,
-                        adap->params.rev > 0 ? F_ENABLEESND : F_T3A_ENABLEESND,
-                        0);
+       t3_set_reg_field(adap, A_TP_PARA_REG6, 0,
+                        adap->params.rev > 0 ? F_ENABLEESND :
+                        F_T3A_ENABLEESND);
 
        t3_set_reg_field(adap, A_TP_PC_CONFIG,
-                        F_ENABLEEPCMDAFULL | F_ENABLEOCSPIFULL,
-                        F_TXDEFERENABLE | F_HEARBEATDACK | F_TXCONGESTIONMODE |
-                        F_RXCONGESTIONMODE);
+                        F_ENABLEEPCMDAFULL,
+                        F_ENABLEOCSPIFULL |F_TXDEFERENABLE | F_HEARBEATDACK |
+                        F_TXCONGESTIONMODE | F_RXCONGESTIONMODE);
        t3_set_reg_field(adap, A_TP_PC_CONFIG2, F_CHDRAFULL, 0);
-
+       t3_write_reg(adap, A_TP_PROXY_FLOW_CNTL, 1080);
+       t3_write_reg(adap, A_TP_PROXY_FLOW_CNTL, 1000);
+       
        if (adap->params.rev > 0) {
                tp_wr_indirect(adap, A_TP_EGRESS_CONFIG, F_REWRITEFORCETOSIZE);
                t3_set_reg_field(adap, A_TP_PARA_REG3, F_TXPACEAUTO,
@@ -2390,9 +2450,10 @@ static void tp_config(struct adapter *adap, const struct tp_params *p)
        } else
                t3_set_reg_field(adap, A_TP_PARA_REG3, 0, F_TXPACEFIXED);
 
-       t3_write_reg(adap, A_TP_TX_MOD_QUEUE_WEIGHT1, 0x12121212);
-       t3_write_reg(adap, A_TP_TX_MOD_QUEUE_WEIGHT0, 0x12121212);
-       t3_write_reg(adap, A_TP_MOD_CHANNEL_WEIGHT, 0x1212);
+       t3_write_reg(adap, A_TP_TX_MOD_QUEUE_WEIGHT1, 0);
+       t3_write_reg(adap, A_TP_TX_MOD_QUEUE_WEIGHT0, 0);
+       t3_write_reg(adap, A_TP_MOD_CHANNEL_WEIGHT, 0);
+       t3_write_reg(adap, A_TP_MOD_RATE_LIMIT, 0xf2200000);
 }
 
 /* Desired TP timer resolution in usec */
@@ -2468,6 +2529,7 @@ int t3_tp_set_coalescing_size(struct adapter *adap, unsigned int size, int psh)
                val |= F_RXCOALESCEENABLE;
                if (psh)
                        val |= F_RXCOALESCEPSHEN;
+               size = min(MAX_RX_COALESCING_LEN, size);
                t3_write_reg(adap, A_TP_PARA_REG2, V_RXCOALESCESIZE(size) |
                             V_MAXRXDATA(MAX_RX_COALESCING_LEN));
        }
@@ -2496,11 +2558,11 @@ static void __devinit init_mtus(unsigned short mtus[])
         * it can accomodate max size TCP/IP headers when SACK and timestamps
         * are enabled and still have at least 8 bytes of payload.
         */
-       mtus[0] = 88;
-       mtus[1] = 256;
-       mtus[2] = 512;
-       mtus[3] = 576;
-       mtus[4] = 808;
+       mtus[1] = 88;
+       mtus[1] = 88;
+       mtus[2] = 256;
+       mtus[3] = 512;
+       mtus[4] = 576;
        mtus[5] = 1024;
        mtus[6] = 1280;
        mtus[7] = 1492;
@@ -2682,6 +2744,34 @@ static void ulp_config(struct adapter *adap, const struct tp_params *p)
        t3_write_reg(adap, A_ULPRX_TDDP_TAGMASK, 0xffffffff);
 }
 
+/**
+ *     t3_set_proto_sram - set the contents of the protocol sram
+ *     @adapter: the adapter
+ *     @data: the protocol image
+ *
+ *     Write the contents of the protocol SRAM.
+ */
+int t3_set_proto_sram(struct adapter *adap, u8 *data)
+{
+       int i;
+       u32 *buf = (u32 *)data;
+
+       for (i = 0; i < PROTO_SRAM_LINES; i++) {
+               t3_write_reg(adap, A_TP_EMBED_OP_FIELD5, cpu_to_be32(*buf++));
+               t3_write_reg(adap, A_TP_EMBED_OP_FIELD4, cpu_to_be32(*buf++));
+               t3_write_reg(adap, A_TP_EMBED_OP_FIELD3, cpu_to_be32(*buf++));
+               t3_write_reg(adap, A_TP_EMBED_OP_FIELD2, cpu_to_be32(*buf++));
+               t3_write_reg(adap, A_TP_EMBED_OP_FIELD1, cpu_to_be32(*buf++));
+               
+               t3_write_reg(adap, A_TP_EMBED_OP_FIELD0, i << 1 | 1 << 31);
+               if (t3_wait_op_done(adap, A_TP_EMBED_OP_FIELD0, 1, 1, 5, 1))
+                       return -EIO;
+       }
+       t3_write_reg(adap, A_TP_EMBED_OP_FIELD0, 0);
+
+       return 0;
+}
+
 void t3_config_trace_filter(struct adapter *adapter,
                            const struct trace_params *tp, int filter_index,
                            int invert, int enable)
@@ -2802,7 +2892,7 @@ static void init_hw_for_avail_ports(struct adapter *adap, int nports)
                t3_set_reg_field(adap, A_ULPTX_CONFIG, F_CFG_RR_ARB, 0);
                t3_write_reg(adap, A_MPS_CFG, F_TPRXPORTEN | F_TPTXPORT0EN |
                             F_PORT0ACTIVE | F_ENFORCEPKT);
-               t3_write_reg(adap, A_PM1_TX_CFG, 0xc000c000);
+               t3_write_reg(adap, A_PM1_TX_CFG, 0xffffffff);
        } else {
                t3_set_reg_field(adap, A_ULPRX_CTL, 0, F_ROUND_ROBIN);
                t3_set_reg_field(adap, A_ULPTX_CONFIG, 0, F_CFG_RR_ARB);
@@ -3097,7 +3187,7 @@ int t3_init_hw(struct adapter *adapter, u32 fw_params)
        else
                t3_set_reg_field(adapter, A_PCIX_CFG, 0, F_CLIDECEN);
 
-       t3_write_reg(adapter, A_PM1_RX_CFG, 0xf000f000);
+       t3_write_reg(adapter, A_PM1_RX_CFG, 0xffffffff);
        init_hw_for_avail_ports(adapter, adapter->params.nports);
        t3_sge_init(adapter, &adapter->params.sge);
 
index b112317f033e1950d311490607e1cb7d16c43162..eb508bf8022a0595bd228b2ede3e94040e39f782 100644 (file)
@@ -39,6 +39,6 @@
 
 /* Firmware version */
 #define FW_VERSION_MAJOR 4
-#define FW_VERSION_MINOR 0
+#define FW_VERSION_MINOR 3
 #define FW_VERSION_MICRO 0
 #endif                         /* __CHELSIO_VERSION_H */
index 74ec64a1625d2763ea8b03373b4f686055df51c1..04e3710c908269e3510a9492296ee041e75e717b 100644 (file)
@@ -250,7 +250,6 @@ rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent)
                        np->an_enable = 1;
                mii_set_media (dev);
        }
-       pci_read_config_byte(pdev, PCI_REVISION_ID, &np->pci_rev_id);
 
        err = register_netdev (dev);
        if (err)
@@ -866,9 +865,9 @@ receive_packet (struct net_device *dev)
                                                            PCI_DMA_FROMDEVICE);
                                /* 16 byte align the IP header */
                                skb_reserve (skb, 2);
-                               eth_copy_and_sum (skb,
+                               skb_copy_to_linear_data (skb,
                                                  np->rx_skbuff[entry]->data,
-                                                 pkt_len, 0);
+                                                 pkt_len);
                                skb_put (skb, pkt_len);
                                pci_dma_sync_single_for_device(np->pdev,
                                                               desc->fraginfo &
@@ -879,7 +878,7 @@ receive_packet (struct net_device *dev)
                        skb->protocol = eth_type_trans (skb, dev);
 #if 0
                        /* Checksum done by hw, but csum value unavailable. */
-                       if (np->pci_rev_id >= 0x0c &&
+                       if (np->pdev->pci_rev_id >= 0x0c &&
                                !(frame_status & (TCPError | UDPError | IPError))) {
                                skb->ip_summed = CHECKSUM_UNNECESSARY;
                        }
index 814c449c359fac1f4255b59ccd9977b8458fcb72..e443065a452e690600b647250cedb2ababf1e8ab 100644 (file)
@@ -668,7 +668,6 @@ struct netdev_private {
        unsigned int rx_flow:1;         /* Rx flow control enable */
        unsigned int phy_media:1;       /* 1: fiber, 0: copper */
        unsigned int link_status:1;     /* Current link status */
-       unsigned char pci_rev_id;       /* PCI revision ID */
        struct netdev_desc *last_tx;    /* Last Tx descriptor used. */
        unsigned long cur_rx, old_rx;   /* Producer/consumer ring indices */
        unsigned long cur_tx, old_tx;
index 264fa0e2e0750401ff200a063f46e68a2f45378c..c3de81bf090a3f92062c236f560cee7f63fd1d69 100644 (file)
 #define PRINTK(args...)   printk(KERN_DEBUG args)
 #endif
 
+#ifdef CONFIG_BLACKFIN
+#define readsb insb
+#define readsw insw
+#define readsl insl
+#define writesb        outsb
+#define writesw        outsw
+#define writesl        outsl
+#define DM9000_IRQ_FLAGS       (IRQF_SHARED | IRQF_TRIGGER_HIGH)
+#else
+#define DM9000_IRQ_FLAGS       IRQF_SHARED
+#endif
+
 /*
  * Transmit timeout, default 5 seconds.
  */
@@ -431,6 +443,9 @@ dm9000_probe(struct platform_device *pdev)
                db->io_addr = (void __iomem *)base;
                db->io_data = (void __iomem *)(base + 4);
 
+               /* ensure at least we have a default set of IO routines */
+               dm9000_set_io(db, 2);
+
        } else {
                db->addr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
                db->data_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
@@ -614,7 +629,7 @@ dm9000_open(struct net_device *dev)
 
        PRINTK2("entering dm9000_open\n");
 
-       if (request_irq(dev->irq, &dm9000_interrupt, IRQF_SHARED, dev->name, dev))
+       if (request_irq(dev->irq, &dm9000_interrupt, DM9000_IRQ_FLAGS, dev->name, dev))
                return -EAGAIN;
 
        /* Initialize DM9000 board */
index 60673bc292c0dec05678601cc65e093c8af84b56..756a6bcb038d4e053593735be5ced5f8c3c678a3 100644 (file)
 #include <linux/etherdevice.h>
 #include <linux/init.h>
 #include <linux/moduleparam.h>
+#include <linux/rtnetlink.h>
+#include <net/rtnetlink.h>
 
 static int numdummies = 1;
 
 static int dummy_xmit(struct sk_buff *skb, struct net_device *dev);
-static struct net_device_stats *dummy_get_stats(struct net_device *dev);
 
 static int dummy_set_address(struct net_device *dev, void *p)
 {
@@ -56,13 +57,13 @@ static void set_multicast_list(struct net_device *dev)
 {
 }
 
-static void __init dummy_setup(struct net_device *dev)
+static void dummy_setup(struct net_device *dev)
 {
        /* Initialize the device structure. */
-       dev->get_stats = dummy_get_stats;
        dev->hard_start_xmit = dummy_xmit;
        dev->set_multicast_list = set_multicast_list;
        dev->set_mac_address = dummy_set_address;
+       dev->destructor = free_netdev;
 
        /* Fill in device structure with ethernet-generic values. */
        ether_setup(dev);
@@ -76,77 +77,80 @@ static void __init dummy_setup(struct net_device *dev)
 
 static int dummy_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-       struct net_device_stats *stats = netdev_priv(dev);
-
-       stats->tx_packets++;
-       stats->tx_bytes+=skb->len;
+       dev->stats.tx_packets++;
+       dev->stats.tx_bytes += skb->len;
 
        dev_kfree_skb(skb);
        return 0;
 }
 
-static struct net_device_stats *dummy_get_stats(struct net_device *dev)
+static int dummy_validate(struct nlattr *tb[], struct nlattr *data[])
 {
-       return netdev_priv(dev);
+       if (tb[IFLA_ADDRESS]) {
+               if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
+                       return -EINVAL;
+               if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
+                       return -EADDRNOTAVAIL;
+       }
+       return 0;
 }
 
-static struct net_device **dummies;
+static struct rtnl_link_ops dummy_link_ops __read_mostly = {
+       .kind           = "dummy",
+       .setup          = dummy_setup,
+       .validate       = dummy_validate,
+};
 
 /* Number of dummy devices to be set up by this module. */
 module_param(numdummies, int, 0);
 MODULE_PARM_DESC(numdummies, "Number of dummy pseudo devices");
 
-static int __init dummy_init_one(int index)
+static int __init dummy_init_one(void)
 {
        struct net_device *dev_dummy;
        int err;
 
-       dev_dummy = alloc_netdev(sizeof(struct net_device_stats),
-                                "dummy%d", dummy_setup);
-
+       dev_dummy = alloc_netdev(0, "dummy%d", dummy_setup);
        if (!dev_dummy)
                return -ENOMEM;
 
-       if ((err = register_netdev(dev_dummy))) {
-               free_netdev(dev_dummy);
-               dev_dummy = NULL;
-       } else {
-               dummies[index] = dev_dummy;
-       }
+       err = dev_alloc_name(dev_dummy, dev_dummy->name);
+       if (err < 0)
+               goto err;
 
-       return err;
-}
+       dev_dummy->rtnl_link_ops = &dummy_link_ops;
+       err = register_netdevice(dev_dummy);
+       if (err < 0)
+               goto err;
+       return 0;
 
-static void dummy_free_one(int index)
-{
-       unregister_netdev(dummies[index]);
-       free_netdev(dummies[index]);
+err:
+       free_netdev(dev_dummy);
+       return err;
 }
 
 static int __init dummy_init_module(void)
 {
        int i, err = 0;
-       dummies = kmalloc(numdummies * sizeof(void *), GFP_KERNEL);
-       if (!dummies)
-               return -ENOMEM;
+
+       rtnl_lock();
+       err = __rtnl_link_register(&dummy_link_ops);
+
        for (i = 0; i < numdummies && !err; i++)
-               err = dummy_init_one(i);
-       if (err) {
-               i--;
-               while (--i >= 0)
-                       dummy_free_one(i);
-       }
+               err = dummy_init_one();
+       if (err < 0)
+               __rtnl_link_unregister(&dummy_link_ops);
+       rtnl_unlock();
+
        return err;
 }
 
 static void __exit dummy_cleanup_module(void)
 {
-       int i;
-       for (i = 0; i < numdummies; i++)
-               dummy_free_one(i);
-       kfree(dummies);
+       rtnl_link_unregister(&dummy_link_ops);
 }
 
 module_init(dummy_init_module);
 module_exit(dummy_cleanup_module);
 MODULE_LICENSE("GPL");
+MODULE_ALIAS_RTNL_LINK("dummy");
index 763810c7f33aa1e3bb682e1afdc780ac18ca8ce1..6b6401e9304e6b2a298773019cb2c6d32f26a0f9 100644 (file)
 
 #define DRV_NAME               "e100"
 #define DRV_EXT                        "-NAPI"
-#define DRV_VERSION            "3.5.17-k4"DRV_EXT
+#define DRV_VERSION            "3.5.23-k4"DRV_EXT
 #define DRV_DESCRIPTION                "Intel(R) PRO/100 Network Driver"
 #define DRV_COPYRIGHT          "Copyright(c) 1999-2006 Intel Corporation"
 #define PFX                    DRV_NAME ": "
@@ -583,7 +583,6 @@ struct nic {
        u32 rx_tco_frames;
        u32 rx_over_length_errors;
 
-       u8 rev_id;
        u16 leds;
        u16 eeprom_wc;
        u16 eeprom[256];
@@ -937,9 +936,8 @@ static void e100_get_defaults(struct nic *nic)
        struct param_range rfds = { .min = 16, .max = 256, .count = 256 };
        struct param_range cbs  = { .min = 64, .max = 256, .count = 128 };
 
-       pci_read_config_byte(nic->pdev, PCI_REVISION_ID, &nic->rev_id);
        /* MAC type is encoded as rev ID; exception: ICH is treated as 82559 */
-       nic->mac = (nic->flags & ich) ? mac_82559_D101M : nic->rev_id;
+       nic->mac = (nic->flags & ich) ? mac_82559_D101M : nic->pdev->revision;
        if(nic->mac == mac_unknown)
                nic->mac = mac_82557_D100_A;
 
@@ -1024,10 +1022,16 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb)
                config->mwi_enable = 0x1;       /* 1=enable, 0=disable */
                config->standard_tcb = 0x0;     /* 1=standard, 0=extended */
                config->rx_long_ok = 0x1;       /* 1=VLANs ok, 0=standard */
-               if(nic->mac >= mac_82559_D101M)
+               if (nic->mac >= mac_82559_D101M) {
                        config->tno_intr = 0x1;         /* TCO stats enable */
-               else
+                       /* Enable TCO in extended config */
+                       if (nic->mac >= mac_82551_10) {
+                               config->byte_count = 0x20; /* extended bytes */
+                               config->rx_d102_mode = 0x1; /* GMRC for TCO */
+                       }
+               } else {
                        config->standard_stat_counter = 0x0;
+               }
        }
 
        DPRINTK(HW, DEBUG, "[00-07]=%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
@@ -1273,7 +1277,7 @@ static void e100_setup_ucode(struct nic *nic, struct cb *cb, struct sk_buff *skb
        if (nic->flags & ich)
                goto noloaducode;
 
-       /* Search for ucode match against h/w rev_id */
+       /* Search for ucode match against h/w revision */
        for (opts = ucode_opts; opts->mac; opts++) {
                int i;
                u32 *ucode = opts->ucode;
@@ -2232,7 +2236,7 @@ static void e100_get_regs(struct net_device *netdev,
        u32 *buff = p;
        int i;
 
-       regs->version = (1 << 24) | nic->rev_id;
+       regs->version = (1 << 24) | nic->pdev->revision;
        buff[0] = ioread8(&nic->csr->scb.cmd_hi) << 24 |
                ioread8(&nic->csr->scb.cmd_lo) << 16 |
                ioread16(&nic->csr->scb.status);
index cf8af928a69cd4b9d157fb97cb6f6071dc421ba8..f48b659e0c2bd3dbdfbb6015ad22acdd5f876951 100644 (file)
@@ -1266,8 +1266,7 @@ e1000_sw_init(struct e1000_adapter *adapter)
        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);
+       hw->revision_id = pdev->revision;
 
        pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
 
index 9800341956a2e36a1277e9f9830547abdbc737ba..9afa47edfc5850e65309530f68e8dbab2f437656 100644 (file)
@@ -1801,7 +1801,7 @@ speedo_rx(struct net_device *dev)
 
 #if 1 || USE_IP_CSUM
                                /* Packet is in one chunk -- we can copy + cksum. */
-                               eth_copy_and_sum(skb, sp->rx_skbuff[entry]->data, pkt_len, 0);
+                               skb_copy_to_linear_data(skb, sp->rx_skbuff[entry]->data, pkt_len);
                                skb_put(skb, pkt_len);
 #else
                                skb_copy_from_linear_data(sp->rx_skbuff[entry],
index c0f81b5a30fb4737b0b89839d9d3cb93ae62b591..f03f070451dee57f51120566bb5fae7aa30c33cc 100644 (file)
 #include <asm/io.h>
 
 #define DRV_NAME       "ehea"
-#define DRV_VERSION    "EHEA_0064"
+#define DRV_VERSION    "EHEA_0067"
+
+/* EHEA capability flags */
+#define DLPAR_PORT_ADD_REM 1
+#define DLPAR_MEM_ADD 2
+#define DLPAR_MEM_REM 4
+#define EHEA_CAPABILITIES (DLPAR_PORT_ADD_REM)
 
 #define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \
        | NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR)
@@ -136,10 +142,10 @@ void ehea_dump(void *adr, int len, char *msg);
        (0xffffffffffffffffULL >> ((64 - (mask)) & 0xffff))
 
 #define EHEA_BMASK_SET(mask, value) \
-        ((EHEA_BMASK_MASK(mask) & ((u64)(value))) << EHEA_BMASK_SHIFTPOS(mask))
+       ((EHEA_BMASK_MASK(mask) & ((u64)(value))) << EHEA_BMASK_SHIFTPOS(mask))
 
 #define EHEA_BMASK_GET(mask, value) \
-        (EHEA_BMASK_MASK(mask) & (((u64)(value)) >> EHEA_BMASK_SHIFTPOS(mask)))
+       (EHEA_BMASK_MASK(mask) & (((u64)(value)) >> EHEA_BMASK_SHIFTPOS(mask)))
 
 /*
  * Generic ehea page
@@ -190,7 +196,7 @@ struct ehea_av;
  * Queue attributes passed to ehea_create_qp()
  */
 struct ehea_qp_init_attr {
-        /* input parameter */
+       /* input parameter */
        u32 qp_token;           /* queue token */
        u8 low_lat_rq1;
        u8 signalingtype;       /* cqe generation flag */
@@ -212,7 +218,7 @@ struct ehea_qp_init_attr {
        u64 recv_cq_handle;
        u64 aff_eq_handle;
 
-        /* output parameter */
+       /* output parameter */
        u32 qp_nr;
        u16 act_nr_send_wqes;
        u16 act_nr_rwqes_rq1;
@@ -279,12 +285,12 @@ struct ehea_qp {
  * Completion Queue attributes
  */
 struct ehea_cq_attr {
-        /* input parameter */
+       /* input parameter */
        u32 max_nr_of_cqes;
        u32 cq_token;
        u64 eq_handle;
 
-        /* output parameter */
+       /* output parameter */
        u32 act_nr_of_cqes;
        u32 nr_pages;
 };
index 1246757f2c22cd5a7807596f56e3aad9d306ad59..1af7ca499ec517232e7c83dc845f2f336c07430c 100644 (file)
@@ -211,34 +211,34 @@ static inline void epa_store_acc(struct h_epa epa, u32 offset, u64 value)
 }
 
 #define epa_store_eq(epa, offset, value)\
-        epa_store(epa, EQTEMM_OFFSET(offset), value)
+       epa_store(epa, EQTEMM_OFFSET(offset), value)
 #define epa_load_eq(epa, offset)\
-        epa_load(epa, EQTEMM_OFFSET(offset))
+       epa_load(epa, EQTEMM_OFFSET(offset))
 
 #define epa_store_cq(epa, offset, value)\
-        epa_store(epa, CQTEMM_OFFSET(offset), value)
+       epa_store(epa, CQTEMM_OFFSET(offset), value)
 #define epa_load_cq(epa, offset)\
-        epa_load(epa, CQTEMM_OFFSET(offset))
+       epa_load(epa, CQTEMM_OFFSET(offset))
 
 #define epa_store_qp(epa, offset, value)\
-        epa_store(epa, QPTEMM_OFFSET(offset), value)
+       epa_store(epa, QPTEMM_OFFSET(offset), value)
 #define epa_load_qp(epa, offset)\
-        epa_load(epa, QPTEMM_OFFSET(offset))
+       epa_load(epa, QPTEMM_OFFSET(offset))
 
 #define epa_store_qped(epa, offset, value)\
-        epa_store(epa, QPEDMM_OFFSET(offset), value)
+       epa_store(epa, QPEDMM_OFFSET(offset), value)
 #define epa_load_qped(epa, offset)\
-        epa_load(epa, QPEDMM_OFFSET(offset))
+       epa_load(epa, QPEDMM_OFFSET(offset))
 
 #define epa_store_mrmw(epa, offset, value)\
-        epa_store(epa, MRMWMM_OFFSET(offset), value)
+       epa_store(epa, MRMWMM_OFFSET(offset), value)
 #define epa_load_mrmw(epa, offset)\
-        epa_load(epa, MRMWMM_OFFSET(offset))
+       epa_load(epa, MRMWMM_OFFSET(offset))
 
 #define epa_store_base(epa, offset, value)\
-        epa_store(epa, HCAGR_OFFSET(offset), value)
+       epa_store(epa, HCAGR_OFFSET(offset), value)
 #define epa_load_base(epa, offset)\
-        epa_load(epa, HCAGR_OFFSET(offset))
+       epa_load(epa, HCAGR_OFFSET(offset))
 
 static inline void ehea_update_sqa(struct ehea_qp *qp, u16 nr_wqes)
 {
index 9e13433a268a7a40c360a17ed7904281a89e245b..383144db4d18df1187749dfb98138251dff66b46 100644 (file)
@@ -81,7 +81,7 @@ MODULE_PARM_DESC(use_mcs, " 0:NAPI, 1:Multiple receive queues, Default = 1 ");
 static int port_name_cnt = 0;
 
 static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev,
-                                        const struct of_device_id *id);
+                                       const struct of_device_id *id);
 
 static int __devexit ehea_remove(struct ibmebus_dev *dev);
 
@@ -236,7 +236,7 @@ static int ehea_refill_rq_def(struct ehea_port_res *pr,
 
                rwqe = ehea_get_next_rwqe(qp, rq_nr);
                rwqe->wr_id = EHEA_BMASK_SET(EHEA_WR_ID_TYPE, wqe_type)
-                           | EHEA_BMASK_SET(EHEA_WR_ID_INDEX, index);
+                           | EHEA_BMASK_SET(EHEA_WR_ID_INDEX, index);
                rwqe->sg_list[0].l_key = pr->recv_mr.lkey;
                rwqe->sg_list[0].vaddr = (u64)skb->data;
                rwqe->sg_list[0].len = packet_size;
@@ -427,7 +427,7 @@ static struct ehea_cqe *ehea_proc_rwqes(struct net_device *dev,
                                                break;
                                }
                                skb_copy_to_linear_data(skb, ((char*)cqe) + 64,
-                                              cqe->num_bytes_transfered - 4);
+                                                cqe->num_bytes_transfered - 4);
                                ehea_fill_skb(port->netdev, skb, cqe);
                        } else if (rq == 2) {  /* RQ2 */
                                skb = get_skb_by_index(skb_arr_rq2,
@@ -618,7 +618,7 @@ static struct ehea_port *ehea_get_port(struct ehea_adapter *adapter,
 
        for (i = 0; i < EHEA_MAX_PORTS; i++)
                if (adapter->port[i])
-                       if (adapter->port[i]->logical_port_id == logical_port)
+                       if (adapter->port[i]->logical_port_id == logical_port)
                                return adapter->port[i];
        return NULL;
 }
@@ -1695,6 +1695,7 @@ static void ehea_xmit2(struct sk_buff *skb, struct net_device *dev,
 {
        if (skb->protocol == htons(ETH_P_IP)) {
                const struct iphdr *iph = ip_hdr(skb);
+
                /* IPv4 */
                swqe->tx_control |= EHEA_SWQE_CRC
                                 | EHEA_SWQE_IP_CHECKSUM
@@ -1705,13 +1706,12 @@ static void ehea_xmit2(struct sk_buff *skb, struct net_device *dev,
                write_ip_start_end(swqe, skb);
 
                if (iph->protocol == IPPROTO_UDP) {
-                       if ((iph->frag_off & IP_MF) ||
-                           (iph->frag_off & IP_OFFSET))
+                       if ((iph->frag_off & IP_MF)
+                           || (iph->frag_off & IP_OFFSET))
                                /* IP fragment, so don't change cs */
                                swqe->tx_control &= ~EHEA_SWQE_TCP_CHECKSUM;
                        else
                                write_udp_offset_end(swqe, skb);
-
                } else if (iph->protocol == IPPROTO_TCP) {
                        write_tcp_offset_end(swqe, skb);
                }
@@ -1739,6 +1739,7 @@ static void ehea_xmit3(struct sk_buff *skb, struct net_device *dev,
 
        if (skb->protocol == htons(ETH_P_IP)) {
                const struct iphdr *iph = ip_hdr(skb);
+
                /* IPv4 */
                write_ip_start_end(swqe, skb);
 
@@ -1751,8 +1752,8 @@ static void ehea_xmit3(struct sk_buff *skb, struct net_device *dev,
                        write_tcp_offset_end(swqe, skb);
 
                } else if (iph->protocol == IPPROTO_UDP) {
-                       if ((iph->frag_off & IP_MF) ||
-                           (iph->frag_off & IP_OFFSET))
+                       if ((iph->frag_off & IP_MF)
+                           || (iph->frag_off & IP_OFFSET))
                                /* IP fragment, so don't change cs */
                                swqe->tx_control |= EHEA_SWQE_CRC
                                                 | EHEA_SWQE_IMM_DATA_PRESENT;
@@ -2407,7 +2408,7 @@ static void __devinit logical_port_release(struct device *dev)
 }
 
 static int ehea_driver_sysfs_add(struct device *dev,
-                                 struct device_driver *driver)
+                                struct device_driver *driver)
 {
        int ret;
 
@@ -2424,7 +2425,7 @@ static int ehea_driver_sysfs_add(struct device *dev,
 }
 
 static void ehea_driver_sysfs_remove(struct device *dev,
-                                     struct device_driver *driver)
+                                    struct device_driver *driver)
 {
        struct device_driver *drv = driver;
 
@@ -2453,7 +2454,7 @@ static struct device *ehea_register_port(struct ehea_port *port,
        }
 
        ret = device_create_file(&port->ofdev.dev, &dev_attr_log_port_id);
-        if (ret) {
+       if (ret) {
                ehea_error("failed to register attributes, ret=%d", ret);
                goto out_unreg_of_dev;
        }
@@ -2601,6 +2602,7 @@ static int ehea_setup_ports(struct ehea_adapter *adapter)
 {
        struct device_node *lhea_dn;
        struct device_node *eth_dn = NULL;
+
        const u32 *dn_log_port_id;
        int i = 0;
 
@@ -2608,7 +2610,7 @@ static int ehea_setup_ports(struct ehea_adapter *adapter)
        while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) {
 
                dn_log_port_id = of_get_property(eth_dn, "ibm,hea-port-no",
-                                                   NULL);
+                                                NULL);
                if (!dn_log_port_id) {
                        ehea_error("bad device node: eth_dn name=%s",
                                   eth_dn->full_name);
@@ -2648,7 +2650,7 @@ static struct device_node *ehea_get_eth_dn(struct ehea_adapter *adapter,
        while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) {
 
                dn_log_port_id = of_get_property(eth_dn, "ibm,hea-port-no",
-                                                   NULL);
+                                                NULL);
                if (dn_log_port_id)
                        if (*dn_log_port_id == logical_port_id)
                                return eth_dn;
@@ -2789,7 +2791,7 @@ static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev,
        adapter->ebus_dev = dev;
 
        adapter_handle = of_get_property(dev->ofdev.node, "ibm,hea-handle",
-                                           NULL);
+                                        NULL);
        if (adapter_handle)
                adapter->handle = *adapter_handle;
 
@@ -2921,6 +2923,15 @@ static int check_module_parm(void)
        return ret;
 }
 
+static ssize_t ehea_show_capabilities(struct device_driver *drv,
+                                     char *buf)
+{
+       return sprintf(buf, "%d", EHEA_CAPABILITIES);
+}
+
+static DRIVER_ATTR(capabilities, S_IRUSR | S_IRGRP | S_IROTH,
+                  ehea_show_capabilities, NULL);
+
 int __init ehea_module_init(void)
 {
        int ret;
@@ -2932,8 +2943,19 @@ int __init ehea_module_init(void)
        if (ret)
                goto out;
        ret = ibmebus_register_driver(&ehea_driver);
-       if (ret)
+       if (ret) {
                ehea_error("failed registering eHEA device driver on ebus");
+               goto out;
+       }
+
+       ret = driver_create_file(&ehea_driver.driver,
+                                &driver_attr_capabilities);
+       if (ret) {
+               ehea_error("failed to register capabilities attribute, ret=%d",
+                          ret);
+               ibmebus_unregister_driver(&ehea_driver);
+               goto out;
+       }
 
 out:
        return ret;
@@ -2941,6 +2963,7 @@ out:
 
 static void __exit ehea_module_exit(void)
 {
+       driver_remove_file(&ehea_driver.driver, &driver_attr_capabilities);
        ibmebus_unregister_driver(&ehea_driver);
 }
 
index f24a8862977ddda82589dc17c75fb4232f204dec..29eaa46948b0e0c07cf72acba70ef0608cf97b2c 100644 (file)
@@ -211,7 +211,7 @@ u64 ehea_destroy_cq_res(struct ehea_cq *cq, u64 force)
        u64 hret;
        u64 adapter_handle = cq->adapter->handle;
 
-        /* deregister all previous registered pages */
+       /* deregister all previous registered pages */
        hret = ehea_h_free_resource(adapter_handle, cq->fw_handle, force);
        if (hret != H_SUCCESS)
                return hret;
@@ -362,7 +362,7 @@ int ehea_destroy_eq(struct ehea_eq *eq)
        if (hret != H_SUCCESS) {
                ehea_error("destroy EQ failed");
                return -EIO;
-        }
+       }
 
        return 0;
 }
@@ -507,44 +507,44 @@ out_freemem:
 
 u64 ehea_destroy_qp_res(struct ehea_qp *qp, u64 force)
 {
-        u64 hret;
-        struct ehea_qp_init_attr *qp_attr = &qp->init_attr;
+       u64 hret;
+       struct ehea_qp_init_attr *qp_attr = &qp->init_attr;
 
 
-        ehea_h_disable_and_get_hea(qp->adapter->handle, qp->fw_handle);
-        hret = ehea_h_free_resource(qp->adapter->handle, qp->fw_handle, force);
-        if (hret != H_SUCCESS)
-                return hret;
+       ehea_h_disable_and_get_hea(qp->adapter->handle, qp->fw_handle);
+       hret = ehea_h_free_resource(qp->adapter->handle, qp->fw_handle, force);
+       if (hret != H_SUCCESS)
+               return hret;
 
-        hw_queue_dtor(&qp->hw_squeue);
-        hw_queue_dtor(&qp->hw_rqueue1);
+       hw_queue_dtor(&qp->hw_squeue);
+       hw_queue_dtor(&qp->hw_rqueue1);
 
-        if (qp_attr->rq_count > 1)
-                hw_queue_dtor(&qp->hw_rqueue2);
-        if (qp_attr->rq_count > 2)
-                hw_queue_dtor(&qp->hw_rqueue3);
-        kfree(qp);
+       if (qp_attr->rq_count > 1)
+               hw_queue_dtor(&qp->hw_rqueue2);
+       if (qp_attr->rq_count > 2)
+               hw_queue_dtor(&qp->hw_rqueue3);
+       kfree(qp);
 
-        return hret;
+       return hret;
 }
 
 int ehea_destroy_qp(struct ehea_qp *qp)
 {
-        u64 hret;
-        if (!qp)
-                return 0;
+       u64 hret;
+       if (!qp)
+               return 0;
 
-        if ((hret = ehea_destroy_qp_res(qp, NORMAL_FREE)) == H_R_STATE) {
-                ehea_error_data(qp->adapter, qp->fw_handle);
-                hret = ehea_destroy_qp_res(qp, FORCE_FREE);
-        }
+       if ((hret = ehea_destroy_qp_res(qp, NORMAL_FREE)) == H_R_STATE) {
+               ehea_error_data(qp->adapter, qp->fw_handle);
+               hret = ehea_destroy_qp_res(qp, FORCE_FREE);
+       }
 
-        if (hret != H_SUCCESS) {
-                ehea_error("destroy QP failed");
-                return -EIO;
-        }
+       if (hret != H_SUCCESS) {
+               ehea_error("destroy QP failed");
+               return -EIO;
+       }
 
-        return 0;
+       return 0;
 }
 
 int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr)
index 5e517946f46a6c1deaee52eb25664467cd233528..119778401e486f9ea808f6266702adfe2ee7e403 100644 (file)
@@ -1201,7 +1201,7 @@ static int epic_rx(struct net_device *dev, int budget)
                                                            ep->rx_ring[entry].bufaddr,
                                                            ep->rx_buf_sz,
                                                            PCI_DMA_FROMDEVICE);
-                               eth_copy_and_sum(skb, ep->rx_skbuff[entry]->data, pkt_len, 0);
+                               skb_copy_to_linear_data(skb, ep->rx_skbuff[entry]->data, pkt_len);
                                skb_put(skb, pkt_len);
                                pci_dma_sync_single_for_device(ep->pci_dev,
                                                               ep->rx_ring[entry].bufaddr,
index abe9b089c610552988e1a56d3a50d01e5cc5e4cf..ff9f177d7157ec9f43326d6c6fc61226d8fab3ba 100644 (file)
@@ -1727,8 +1727,8 @@ static int netdev_rx(struct net_device *dev)
                                /* Call copy + cksum if available. */
 
 #if ! defined(__alpha__)
-                               eth_copy_and_sum(skb,
-                                       np->cur_rx->skbuff->data, pkt_len, 0);
+                               skb_copy_to_linear_data(skb,
+                                       np->cur_rx->skbuff->data, pkt_len);
                                skb_put(skb, pkt_len);
 #else
                                memcpy(skb_put(skb, pkt_len),
index 255b09124e1120c6c3be9306eaadac0ef1740f48..03023dd17829da101765112c4b7ef6054e4a9325 100644 (file)
@@ -648,7 +648,7 @@ while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) {
                fep->stats.rx_dropped++;
        } else {
                skb_put(skb,pkt_len-4); /* Make room */
-               eth_copy_and_sum(skb, data, pkt_len-4, 0);
+               skb_copy_to_linear_data(skb, data, pkt_len-4);
                skb->protocol=eth_type_trans(skb,dev);
                netif_rx(skb);
        }
index a84c232395e3fdf72dc63c070341ad756d2aaa39..afb34ded26ee271c22e29b5e40d735eb71883e80 100644 (file)
@@ -1,6 +1,6 @@
 config FEC_8XX
        tristate "Motorola 8xx FEC driver"
-       depends on NET_ETHERNET && 8xx
+       depends on 8XX
        select MII
 
 config FEC_8XX_GENERIC_PHY
index 42ba1c012ee2c3ad0f20ec14588bd5751507e8f3..67046e8c21eb9a97051017cf2b90b8e733bc60c5 100644 (file)
@@ -5084,15 +5084,13 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
        np->wolenabled = 0;
 
        if (id->driver_data & DEV_HAS_POWER_CNTRL) {
-               u8 revision_id;
-               pci_read_config_byte(pci_dev, PCI_REVISION_ID, &revision_id);
 
                /* take phy and nic out of low power mode */
                powerstate = readl(base + NvRegPowerState2);
                powerstate &= ~NVREG_POWERSTATE2_POWERUP_MASK;
                if ((id->device == PCI_DEVICE_ID_NVIDIA_NVENET_12 ||
                     id->device == PCI_DEVICE_ID_NVIDIA_NVENET_13) &&
-                   revision_id >= 0xA3)
+                   pci_dev->revision >= 0xA3)
                        powerstate |= NVREG_POWERSTATE2_POWERUP_REV_A3;
                writel(powerstate, base + NvRegPowerState2);
        }
index 6aaee67dd4b78037d428f8d456fa5ef594e6786f..e27ee210b605ff0fa41da3197ce84a62a628183e 100644 (file)
@@ -1,6 +1,6 @@
 config FS_ENET
        tristate "Freescale Ethernet Driver"
-       depends on NET_ETHERNET && (CPM1 || CPM2)
+       depends on CPM1 || CPM2
        select MII
 
 config FS_ENET_HAS_SCC
index 1b854bf07b09fec79f6abfa5b58f70b6ef91d1be..d7a1a58de7669b3bfefbf062ccb0fd8d98ec60b9 100644 (file)
@@ -130,6 +130,9 @@ static int gfar_remove(struct platform_device *pdev);
 static void free_skb_resources(struct gfar_private *priv);
 static void gfar_set_multi(struct net_device *dev);
 static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr);
+static void gfar_configure_serdes(struct net_device *dev);
+extern int gfar_local_mdio_write(struct gfar_mii *regs, int mii_id, int regnum, u16 value);
+extern int gfar_local_mdio_read(struct gfar_mii *regs, int mii_id, int regnum);
 #ifdef CONFIG_GFAR_NAPI
 static int gfar_poll(struct net_device *dev, int *budget);
 #endif
@@ -451,6 +454,9 @@ static int init_phy(struct net_device *dev)
 
        phydev = phy_connect(dev, phy_id, &adjust_link, 0, interface);
 
+       if (interface == PHY_INTERFACE_MODE_SGMII)
+               gfar_configure_serdes(dev);
+
        if (IS_ERR(phydev)) {
                printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
                return PTR_ERR(phydev);
@@ -465,6 +471,27 @@ static int init_phy(struct net_device *dev)
        return 0;
 }
 
+static void gfar_configure_serdes(struct net_device *dev)
+{
+       struct gfar_private *priv = netdev_priv(dev);
+       struct gfar_mii __iomem *regs =
+                       (void __iomem *)&priv->regs->gfar_mii_regs;
+
+       /* Initialise TBI i/f to communicate with serdes (lynx phy) */
+
+       /* Single clk mode, mii mode off(for aerdes communication) */
+       gfar_local_mdio_write(regs, TBIPA_VALUE, MII_TBICON, TBICON_CLK_SELECT);
+
+       /* Supported pause and full-duplex, no half-duplex */
+       gfar_local_mdio_write(regs, TBIPA_VALUE, MII_ADVERTISE,
+                       ADVERTISE_1000XFULL | ADVERTISE_1000XPAUSE |
+                       ADVERTISE_1000XPSE_ASYM);
+
+       /* ANEG enable, restart ANEG, full duplex mode, speed[1] set */
+       gfar_local_mdio_write(regs, TBIPA_VALUE, MII_BMCR, BMCR_ANENABLE |
+                       BMCR_ANRESTART | BMCR_FULLDPLX | BMCR_SPEED1000);
+}
+
 static void init_registers(struct net_device *dev)
 {
        struct gfar_private *priv = netdev_priv(dev);
index 39e9e321fcbc1d2c2e4c0bd9fd294a7bccfea33c..d8e779c102faf3becd6c281cab68cee44f8ea9b6 100644 (file)
@@ -136,6 +136,12 @@ extern const char gfar_driver_version[];
 #define MIIMCFG_RESET           0x80000000
 #define MIIMIND_BUSY            0x00000001
 
+/* TBI register addresses */
+#define MII_TBICON             0x11
+
+/* TBICON register bit fields */
+#define TBICON_CLK_SELECT      0x0020
+
 /* MAC register bits */
 #define MACCFG1_SOFT_RESET     0x80000000
 #define MACCFG1_RESET_RX_MC    0x00080000
index bcc6b82f4a33b6a9385ef66197a556fdf3b82149..5dd34a1a7b899217eaabdb8b4abdb8985695684c 100644 (file)
 #include "gianfar.h"
 #include "gianfar_mii.h"
 
-/* Write value to the PHY at mii_id at register regnum,
- * on the bus, waiting until the write is done before returning.
- * All PHY configuration is done through the TSEC1 MIIM regs */
-int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
+/*
+ * Write value to the PHY at mii_id at register regnum,
+ * on the bus attached to the local interface, which may be different from the
+ * generic mdio bus (tied to a single interface), waiting until the write is
+ * done before returning. This is helpful in programming interfaces like
+ * the TBI which control interfaces like onchip SERDES and are always tied to
+ * the local mdio pins, which may not be the same as system mdio bus, used for
+ * controlling the external PHYs, for example.
+ */
+int gfar_local_mdio_write(struct gfar_mii *regs, int mii_id,
+                         int regnum, u16 value)
 {
-       struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;
-
        /* Set the PHY address and the register address we want to write */
        gfar_write(&regs->miimadd, (mii_id << 8) | regnum);
 
@@ -63,12 +68,19 @@ int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
        return 0;
 }
 
-/* Read the bus for PHY at addr mii_id, register regnum, and
- * return the value.  Clears miimcom first.  All PHY
- * configuration has to be done through the TSEC1 MIIM regs */
-int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
+/*
+ * Read the bus for PHY at addr mii_id, register regnum, and
+ * return the value.  Clears miimcom first.  All PHY operation
+ * done on the bus attached to the local interface,
+ * which may be different from the generic mdio bus
+ * This is helpful in programming interfaces like
+ * the TBI which, inturn, control interfaces like onchip SERDES
+ * and are always tied to the local mdio pins, which may not be the
+ * same as system mdio bus, used for controlling the external PHYs, for eg.
+ */
+int gfar_local_mdio_read(struct gfar_mii *regs, int mii_id, int regnum)
+
 {
-       struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;
        u16 value;
 
        /* Set the PHY address and the register address we want to read */
@@ -88,6 +100,27 @@ int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
        return value;
 }
 
+/* Write value to the PHY at mii_id at register regnum,
+ * on the bus, waiting until the write is done before returning.
+ * All PHY configuration is done through the TSEC1 MIIM regs */
+int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
+{
+       struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;
+
+       /* Write to the local MII regs */
+       return(gfar_local_mdio_write(regs, mii_id, regnum, value));
+}
+
+/* Read the bus for PHY at addr mii_id, register regnum, and
+ * return the value.  Clears miimcom first.  All PHY
+ * configuration has to be done through the TSEC1 MIIM regs */
+int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
+{
+       struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;
+
+       /* Read the local MII regs */
+       return(gfar_local_mdio_read(regs, mii_id, regnum));
+}
 
 /* Reset the MIIM registers, and wait for the bus to free */
 int gfar_mdio_reset(struct mii_bus *bus)
index 2521b111b3a5edd2636997a4bbd7257cc1062054..15254dc7876a453e19eac1f88525a0fa9b17da8f 100644 (file)
@@ -1575,8 +1575,8 @@ static int hamachi_rx(struct net_device *dev)
                                                            PCI_DMA_FROMDEVICE);
                                /* Call copy + cksum if available. */
 #if 1 || USE_IP_COPYSUM
-                               eth_copy_and_sum(skb,
-                                       hmp->rx_skbuff[entry]->data, pkt_len, 0);
+                               skb_copy_to_linear_data(skb,
+                                       hmp->rx_skbuff[entry]->data, pkt_len);
                                skb_put(skb, pkt_len);
 #else
                                memcpy(skb_put(skb, pkt_len), hmp->rx_ring_dma
index 6ec3d500f3341ac491519c60d27d2f2c1b936c45..d96eb72295488fe486136df191a3a0f8c8b6b96d 100644 (file)
@@ -1337,7 +1337,7 @@ const char * buf, size_t count)
 
 #define ATTR(_name, _mode)      \
         struct attribute veth_##_name##_attr = {               \
-        .name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE \
+        .name = __stringify(_name), .mode = _mode, \
         };
 
 static ATTR(active, 0644);
index 07b4c0d7a75c415244077e207428641269f13c6a..f5c3598e59afd928d89085e841e45b62fc6c9b92 100644 (file)
@@ -136,13 +136,14 @@ resched:
 
 }
 
-static void __init ifb_setup(struct net_device *dev)
+static void ifb_setup(struct net_device *dev)
 {
        /* Initialize the device structure. */
        dev->get_stats = ifb_get_stats;
        dev->hard_start_xmit = ifb_xmit;
        dev->open = &ifb_open;
        dev->stop = &ifb_close;
+       dev->destructor = free_netdev;
 
        /* Fill in device structure with ethernet-generic values. */
        ether_setup(dev);
@@ -197,12 +198,6 @@ static struct net_device_stats *ifb_get_stats(struct net_device *dev)
        return stats;
 }
 
-static struct net_device **ifbs;
-
-/* Number of ifb devices to be set up by this module. */
-module_param(numifbs, int, 0);
-MODULE_PARM_DESC(numifbs, "Number of ifb devices");
-
 static int ifb_close(struct net_device *dev)
 {
        struct ifb_private *dp = netdev_priv(dev);
@@ -226,6 +221,28 @@ static int ifb_open(struct net_device *dev)
        return 0;
 }
 
+static int ifb_validate(struct nlattr *tb[], struct nlattr *data[])
+{
+       if (tb[IFLA_ADDRESS]) {
+               if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
+                       return -EINVAL;
+               if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
+                       return -EADDRNOTAVAIL;
+       }
+       return 0;
+}
+
+static struct rtnl_link_ops ifb_link_ops __read_mostly = {
+       .kind           = "ifb",
+       .priv_size      = sizeof(struct ifb_private),
+       .setup          = ifb_setup,
+       .validate       = ifb_validate,
+};
+
+/* Number of ifb devices to be set up by this module. */
+module_param(numifbs, int, 0);
+MODULE_PARM_DESC(numifbs, "Number of ifb devices");
+
 static int __init ifb_init_one(int index)
 {
        struct net_device *dev_ifb;
@@ -237,49 +254,44 @@ static int __init ifb_init_one(int index)
        if (!dev_ifb)
                return -ENOMEM;
 
-       if ((err = register_netdev(dev_ifb))) {
-               free_netdev(dev_ifb);
-               dev_ifb = NULL;
-       } else {
-               ifbs[index] = dev_ifb;
-       }
+       err = dev_alloc_name(dev_ifb, dev_ifb->name);
+       if (err < 0)
+               goto err;
 
-       return err;
-}
+       dev_ifb->rtnl_link_ops = &ifb_link_ops;
+       err = register_netdevice(dev_ifb);
+       if (err < 0)
+               goto err;
+       return 0;
 
-static void ifb_free_one(int index)
-{
-       unregister_netdev(ifbs[index]);
-       free_netdev(ifbs[index]);
+err:
+       free_netdev(dev_ifb);
+       return err;
 }
 
 static int __init ifb_init_module(void)
 {
-       int i, err = 0;
-       ifbs = kmalloc(numifbs * sizeof(void *), GFP_KERNEL);
-       if (!ifbs)
-               return -ENOMEM;
+       int i, err;
+
+       rtnl_lock();
+       err = __rtnl_link_register(&ifb_link_ops);
+
        for (i = 0; i < numifbs && !err; i++)
                err = ifb_init_one(i);
-       if (err) {
-               i--;
-               while (--i >= 0)
-                       ifb_free_one(i);
-       }
+       if (err)
+               __rtnl_link_unregister(&ifb_link_ops);
+       rtnl_unlock();
 
        return err;
 }
 
 static void __exit ifb_cleanup_module(void)
 {
-       int i;
-
-       for (i = 0; i < numifbs; i++)
-               ifb_free_one(i);
-       kfree(ifbs);
+       rtnl_link_unregister(&ifb_link_ops);
 }
 
 module_init(ifb_init_module);
 module_exit(ifb_cleanup_module);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Jamal Hadi Salim");
+MODULE_ALIAS_RTNL_LINK("ifb");
index f749e07c642524b9e8a5249c852c831798f7f304..3ca1e8ece5485c43a99079175c1ab1aaab9db732 100644 (file)
@@ -352,13 +352,12 @@ static u64 nic_find(struct ioc3 *ioc3, int *last)
 
 static int nic_init(struct ioc3 *ioc3)
 {
-       const char *type;
+       const char *unknown = "unknown";
+       const char *type = unknown;
        u8 crc;
        u8 serial[6];
        int save = 0, i;
 
-       type = "unknown";
-
        while (1) {
                u64 reg;
                reg = nic_find(ioc3, &save);
@@ -392,7 +391,7 @@ static int nic_init(struct ioc3 *ioc3)
        }
 
        printk("Found %s NIC", type);
-       if (type != "unknown") {
+       if (type != unknown) {
                printk (" registration number %02x:%02x:%02x:%02x:%02x:%02x,"
                        " CRC %02x", serial[0], serial[1], serial[2],
                        serial[3], serial[4], serial[5], crc);
@@ -1103,20 +1102,28 @@ static int ioc3_close(struct net_device *dev)
  * MiniDINs; all other subdevices are left swinging in the wind, leave
  * them disabled.
  */
-static inline int ioc3_is_menet(struct pci_dev *pdev)
+
+static int ioc3_adjacent_is_ioc3(struct pci_dev *pdev, int slot)
+{
+       struct pci_dev *dev = pci_get_slot(pdev->bus, PCI_DEVFN(slot, 0));
+       int ret = 0;
+
+       if (dev) {
+               if (dev->vendor == PCI_VENDOR_ID_SGI &&
+                       dev->device == PCI_DEVICE_ID_SGI_IOC3)
+                       ret = 1;
+               pci_dev_put(dev);
+       }
+
+       return ret;
+}
+
+static int ioc3_is_menet(struct pci_dev *pdev)
 {
-       struct pci_dev *dev;
-
-       return pdev->bus->parent == NULL
-              && (dev = pci_find_slot(pdev->bus->number, PCI_DEVFN(0, 0)))
-              && dev->vendor == PCI_VENDOR_ID_SGI
-              && dev->device == PCI_DEVICE_ID_SGI_IOC3
-              && (dev = pci_find_slot(pdev->bus->number, PCI_DEVFN(1, 0)))
-              && dev->vendor == PCI_VENDOR_ID_SGI
-              && dev->device == PCI_DEVICE_ID_SGI_IOC3
-              && (dev = pci_find_slot(pdev->bus->number, PCI_DEVFN(2, 0)))
-              && dev->vendor == PCI_VENDOR_ID_SGI
-              && dev->device == PCI_DEVICE_ID_SGI_IOC3;
+       return pdev->bus->parent == NULL &&
+              ioc3_adjacent_is_ioc3(pdev, 0) &&
+              ioc3_adjacent_is_ioc3(pdev, 1) &&
+              ioc3_adjacent_is_ioc3(pdev, 2);
 }
 
 #ifdef CONFIG_SERIAL_8250
index 217429122e793e550399d5722498e41bcfed7514..bdd5c979beadc249e7a70bb5a0e47cbfaf03c5a8 100644 (file)
@@ -4,7 +4,7 @@
 * Version:       0.1.1
 * Description:   Irda KingSun/DonShine USB Dongle
 * Status:        Experimental
-* Author:        Alex Villac�s Lasso <a_villacis@palosanto.com>
+* Author:        Alex Villacís Lasso <a_villacis@palosanto.com>
 *
 *      Based on stir4200 and mcs7780 drivers, with (strange?) differences
 *
@@ -652,6 +652,6 @@ static void __exit kingsun_cleanup(void)
 }
 module_exit(kingsun_cleanup);
 
-MODULE_AUTHOR("Alex Villac�s Lasso <a_villacis@palosanto.com>");
+MODULE_AUTHOR("Alex Villacís Lasso <a_villacis@palosanto.com>");
 MODULE_DESCRIPTION("IrDA-USB Dongle Driver for KingSun/DonShine");
 MODULE_LICENSE("GPL");
index bf78ef1120adf2f9696b29f38450d77832778fde..0538ca9ce0588c937cd5289ec5be0261cbc99c8e 100644 (file)
@@ -44,6 +44,7 @@ MODULE_LICENSE("GPL");
 #include <linux/time.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/mutex.h>
 #include <asm/uaccess.h>
 #include <asm/byteorder.h>
 
@@ -1660,8 +1661,8 @@ vlsi_irda_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        idev = ndev->priv;
 
        spin_lock_init(&idev->lock);
-       init_MUTEX(&idev->sem);
-       down(&idev->sem);
+       mutex_init(&idev->mtx);
+       mutex_lock(&idev->mtx);
        idev->pdev = pdev;
 
        if (vlsi_irda_init(ndev) < 0)
@@ -1689,12 +1690,12 @@ vlsi_irda_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        IRDA_MESSAGE("%s: registered device %s\n", drivername, ndev->name);
 
        pci_set_drvdata(pdev, ndev);
-       up(&idev->sem);
+       mutex_unlock(&idev->mtx);
 
        return 0;
 
 out_freedev:
-       up(&idev->sem);
+       mutex_unlock(&idev->mtx);
        free_netdev(ndev);
 out_disable:
        pci_disable_device(pdev);
@@ -1716,12 +1717,12 @@ static void __devexit vlsi_irda_remove(struct pci_dev *pdev)
        unregister_netdev(ndev);
 
        idev = ndev->priv;
-       down(&idev->sem);
+       mutex_lock(&idev->mtx);
        if (idev->proc_entry) {
                remove_proc_entry(ndev->name, vlsi_proc_root);
                idev->proc_entry = NULL;
        }
-       up(&idev->sem);
+       mutex_unlock(&idev->mtx);
 
        free_netdev(ndev);
 
@@ -1751,7 +1752,7 @@ static int vlsi_irda_suspend(struct pci_dev *pdev, pm_message_t state)
                return 0;
        }
        idev = ndev->priv;      
-       down(&idev->sem);
+       mutex_lock(&idev->mtx);
        if (pdev->current_state != 0) {                 /* already suspended */
                if (state.event > pdev->current_state) {        /* simply go deeper */
                        pci_set_power_state(pdev, pci_choose_state(pdev, state));
@@ -1759,7 +1760,7 @@ static int vlsi_irda_suspend(struct pci_dev *pdev, pm_message_t state)
                }
                else
                        IRDA_ERROR("%s - %s: invalid suspend request %u -> %u\n", __FUNCTION__, pci_name(pdev), pdev->current_state, state.event);
-               up(&idev->sem);
+               mutex_unlock(&idev->mtx);
                return 0;
        }
 
@@ -1775,7 +1776,7 @@ static int vlsi_irda_suspend(struct pci_dev *pdev, pm_message_t state)
        pci_set_power_state(pdev, pci_choose_state(pdev, state));
        pdev->current_state = state.event;
        idev->resume_ok = 1;
-       up(&idev->sem);
+       mutex_unlock(&idev->mtx);
        return 0;
 }
 
@@ -1790,9 +1791,9 @@ static int vlsi_irda_resume(struct pci_dev *pdev)
                return 0;
        }
        idev = ndev->priv;      
-       down(&idev->sem);
+       mutex_lock(&idev->mtx);
        if (pdev->current_state == 0) {
-               up(&idev->sem);
+               mutex_unlock(&idev->mtx);
                IRDA_WARNING("%s - %s: already resumed\n",
                             __FUNCTION__, pci_name(pdev));
                return 0;
@@ -1814,7 +1815,7 @@ static int vlsi_irda_resume(struct pci_dev *pdev)
                 * device and independently resume_ok should catch any garbage config.
                 */
                IRDA_WARNING("%s - hm, nothing to resume?\n", __FUNCTION__);
-               up(&idev->sem);
+               mutex_unlock(&idev->mtx);
                return 0;
        }
 
@@ -1824,7 +1825,7 @@ static int vlsi_irda_resume(struct pci_dev *pdev)
                netif_device_attach(ndev);
        }
        idev->resume_ok = 0;
-       up(&idev->sem);
+       mutex_unlock(&idev->mtx);
        return 0;
 }
 
index 2d3b773d8e3503294010f677d33eff62e5d96a4a..ca12a60964199b162bb7b3782995156944414742 100644 (file)
@@ -728,7 +728,7 @@ typedef struct vlsi_irda_dev {
        struct timeval          last_rx;
 
        spinlock_t              lock;
-       struct semaphore        sem;
+       struct mutex            mtx;
 
        u8                      resume_ok;      
        struct proc_dir_entry   *proc_entry;
index d5f694fc4a216369e19f97a75a7f53caaebf386c..d9ce1aef148a5d9ab4c4d3ccf8c4b0e5ded4eda2 100644 (file)
@@ -111,7 +111,7 @@ static int ixpdev_rx(struct net_device *dev, int *budget)
                skb = dev_alloc_skb(desc->pkt_length + 2);
                if (likely(skb != NULL)) {
                        skb_reserve(skb, 2);
-                       eth_copy_and_sum(skb, buf, desc->pkt_length, 0);
+                       skb_copy_to_linear_data(skb, buf, desc->pkt_length);
                        skb_put(skb, desc->pkt_length);
                        skb->protocol = eth_type_trans(skb, nds[desc->channel]);
 
index 0fe96c85828b0b997014904c23b737c56e574bec..a2f37e52b9284cd4ec128b19cf8475a04a59d9a3 100644 (file)
@@ -1186,9 +1186,9 @@ lance_rx(struct net_device *dev)
                                }
                                skb_reserve(skb,2);     /* 16 byte align */
                                skb_put(skb,pkt_len);   /* Make room */
-                               eth_copy_and_sum(skb,
+                               skb_copy_to_linear_data(skb,
                                        (unsigned char *)isa_bus_to_virt((lp->rx_ring[entry].base & 0x00ffffff)),
-                                       pkt_len,0);
+                                       pkt_len);
                                skb->protocol=eth_type_trans(skb,dev);
                                netif_rx(skb);
                                dev->last_rx = jiffies;
index 741780e14b2cc64f026a56dfcaf7c6e4085529ba..efbae4b8398e5b6cbdf8da59db85f83e18fd7212 100644 (file)
 #include <linux/dma-mapping.h>
 
 #include <asm/io.h>
-#include <asm/pgtable.h>
 #include <asm/irq.h>
 #include <asm/pdc.h>
-#include <asm/cache.h>
 #include <asm/parisc-device.h>
 
 #define LASI_82596_DRIVER_VERSION "LASI 82596 driver - Revision: 1.30"
 
-/* DEBUG flags
- */
-
-#define DEB_INIT       0x0001
-#define DEB_PROBE      0x0002
-#define DEB_SERIOUS    0x0004
-#define DEB_ERRORS     0x0008
-#define DEB_MULTI      0x0010
-#define DEB_TDR                0x0020
-#define DEB_OPEN       0x0040
-#define DEB_RESET      0x0080
-#define DEB_ADDCMD     0x0100
-#define DEB_STATUS     0x0200
-#define DEB_STARTTX    0x0400
-#define DEB_RXADDR     0x0800
-#define DEB_TXADDR     0x1000
-#define DEB_RXFRAME    0x2000
-#define DEB_INTS       0x4000
-#define DEB_STRUCT     0x8000
-#define DEB_ANY                0xffff
-
-
-#define DEB(x,y)       if (i596_debug & (x)) { y; }
-
-
-#define  CHECK_WBACK(priv, addr,len) \
-       do { dma_cache_sync((priv)->dev, (void *)addr, len, DMA_TO_DEVICE); } while (0)
-
-#define  CHECK_INV(priv, addr,len) \
-       do { dma_cache_sync((priv)->dev, (void *)addr, len, DMA_FROM_DEVICE); } while(0)
-
-#define  CHECK_WBACK_INV(priv, addr,len) \
-       do { dma_cache_sync((priv)->dev, (void *)addr, len, DMA_BIDIRECTIONAL); } while (0)
-
-
 #define PA_I82596_RESET                0       /* Offsets relative to LASI-LAN-Addr.*/
 #define PA_CPU_PORT_L_ACCESS   4
 #define PA_CHANNEL_ATTENTION   8
 
+#define OPT_SWAP_PORT  0x0001  /* Need to wordswp on the MPU port */
 
-/*
- * Define various macros for Channel Attention, word swapping etc., dependent
- * on architecture.  MVME and BVME are 680x0 based, otherwise it is Intel.
- */
+#define DMA_ALLOC                        dma_alloc_noncoherent
+#define DMA_FREE                         dma_free_noncoherent
+#define DMA_WBACK(ndev, addr, len) \
+       do { dma_cache_sync((ndev)->dev.parent, (void *)addr, len, DMA_TO_DEVICE); } while (0)
 
-#ifdef __BIG_ENDIAN
-#define WSWAPrfd(x)  (((u32)(x)<<16) | ((((u32)(x)))>>16))
-#define WSWAPrbd(x)  (((u32)(x)<<16) | ((((u32)(x)))>>16))
-#define WSWAPiscp(x) (((u32)(x)<<16) | ((((u32)(x)))>>16))
-#define WSWAPscb(x)  (((u32)(x)<<16) | ((((u32)(x)))>>16))
-#define WSWAPcmd(x)  (((u32)(x)<<16) | ((((u32)(x)))>>16))
-#define WSWAPtbd(x)  (((u32)(x)<<16) | ((((u32)(x)))>>16))
-#define WSWAPchar(x) (((u32)(x)<<16) | ((((u32)(x)))>>16))
-#define ISCP_BUSY      0x00010000
-#define MACH_IS_APRICOT        0
-#else
-#define WSWAPrfd(x)     ((struct i596_rfd *)(x))
-#define WSWAPrbd(x)     ((struct i596_rbd *)(x))
-#define WSWAPiscp(x)    ((struct i596_iscp *)(x))
-#define WSWAPscb(x)     ((struct i596_scb *)(x))
-#define WSWAPcmd(x)     ((struct i596_cmd *)(x))
-#define WSWAPtbd(x)     ((struct i596_tbd *)(x))
-#define WSWAPchar(x)    ((char *)(x))
-#define ISCP_BUSY      0x0001
-#define MACH_IS_APRICOT        1
-#endif
+#define DMA_INV(ndev, addr, len) \
+       do { dma_cache_sync((ndev)->dev.parent, (void *)addr, len, DMA_FROM_DEVICE); } while (0)
 
-/*
- * The MPU_PORT command allows direct access to the 82596. With PORT access
- * the following commands are available (p5-18). The 32-bit port command
- * must be word-swapped with the most significant word written first.
- * This only applies to VME boards.
- */
-#define PORT_RESET             0x00    /* reset 82596 */
-#define PORT_SELFTEST          0x01    /* selftest */
-#define PORT_ALTSCP            0x02    /* alternate SCB address */
-#define PORT_ALTDUMP           0x03    /* Alternate DUMP address */
+#define DMA_WBACK_INV(ndev, addr, len) \
+       do { dma_cache_sync((ndev)->dev.parent, (void *)addr, len, DMA_BIDIRECTIONAL); } while (0)
+
+#define SYSBUS      0x0000006c;
+
+/* big endian CPU, 82596 "big" endian mode */
+#define SWAP32(x)   (((u32)(x)<<16) | ((((u32)(x)))>>16))
+#define SWAP16(x)   (x)
 
-static int i596_debug = (DEB_SERIOUS|DEB_PROBE);
+#include "lib82596.c"
 
 MODULE_AUTHOR("Richard Hirst");
 MODULE_DESCRIPTION("i82596 driver");
@@ -180,255 +123,15 @@ MODULE_LICENSE("GPL");
 module_param(i596_debug, int, 0);
 MODULE_PARM_DESC(i596_debug, "lasi_82596 debug mask");
 
-/* Copy frames shorter than rx_copybreak, otherwise pass on up in
- * a full sized sk_buff.  Value of 100 stolen from tulip.c (!alpha).
- */
-static int rx_copybreak = 100;
-
-#define MAX_DRIVERS    4       /* max count of drivers */
-
-#define PKT_BUF_SZ     1536
-#define MAX_MC_CNT     64
-
-#define I596_NULL ((u32)0xffffffff)
-
-#define CMD_EOL                0x8000  /* The last command of the list, stop. */
-#define CMD_SUSP       0x4000  /* Suspend after doing cmd. */
-#define CMD_INTR       0x2000  /* Interrupt after doing cmd. */
-
-#define CMD_FLEX       0x0008  /* Enable flexible memory model */
-
-enum commands {
-       CmdNOp = 0, CmdSASetup = 1, CmdConfigure = 2, CmdMulticastList = 3,
-       CmdTx = 4, CmdTDR = 5, CmdDump = 6, CmdDiagnose = 7
-};
-
-#define STAT_C         0x8000  /* Set to 0 after execution */
-#define STAT_B         0x4000  /* Command being executed */
-#define STAT_OK                0x2000  /* Command executed ok */
-#define STAT_A         0x1000  /* Command aborted */
-
-#define         CUC_START      0x0100
-#define         CUC_RESUME     0x0200
-#define         CUC_SUSPEND    0x0300
-#define         CUC_ABORT      0x0400
-#define         RX_START       0x0010
-#define         RX_RESUME      0x0020
-#define         RX_SUSPEND     0x0030
-#define         RX_ABORT       0x0040
-
-#define TX_TIMEOUT     5
-
-#define OPT_SWAP_PORT  0x0001  /* Need to wordswp on the MPU port */
-
-
-struct i596_reg {
-       unsigned short porthi;
-       unsigned short portlo;
-       u32            ca;
-};
-
-#define EOF            0x8000
-#define SIZE_MASK      0x3fff
-
-struct i596_tbd {
-       unsigned short size;
-       unsigned short pad;
-       dma_addr_t     next;
-       dma_addr_t     data;
-       u32 cache_pad[5];               /* Total 32 bytes... */
-};
-
-/* The command structure has two 'next' pointers; v_next is the address of
- * the next command as seen by the CPU, b_next is the address of the next
- * command as seen by the 82596.  The b_next pointer, as used by the 82596
- * always references the status field of the next command, rather than the
- * v_next field, because the 82596 is unaware of v_next.  It may seem more
- * logical to put v_next at the end of the structure, but we cannot do that
- * because the 82596 expects other fields to be there, depending on command
- * type.
- */
-
-struct i596_cmd {
-       struct i596_cmd *v_next;        /* Address from CPUs viewpoint */
-       unsigned short status;
-       unsigned short command;
-       dma_addr_t     b_next;  /* Address from i596 viewpoint */
-};
-
-struct tx_cmd {
-       struct i596_cmd cmd;
-       dma_addr_t     tbd;
-       unsigned short size;
-       unsigned short pad;
-       struct sk_buff *skb;            /* So we can free it after tx */
-       dma_addr_t dma_addr;
-#ifdef __LP64__
-       u32 cache_pad[6];               /* Total 64 bytes... */
-#else
-       u32 cache_pad[1];               /* Total 32 bytes... */
-#endif
-};
-
-struct tdr_cmd {
-       struct i596_cmd cmd;
-       unsigned short status;
-       unsigned short pad;
-};
-
-struct mc_cmd {
-       struct i596_cmd cmd;
-       short mc_cnt;
-       char mc_addrs[MAX_MC_CNT*6];
-};
-
-struct sa_cmd {
-       struct i596_cmd cmd;
-       char eth_addr[8];
-};
-
-struct cf_cmd {
-       struct i596_cmd cmd;
-       char i596_config[16];
-};
-
-struct i596_rfd {
-       unsigned short stat;
-       unsigned short cmd;
-       dma_addr_t     b_next;  /* Address from i596 viewpoint */
-       dma_addr_t     rbd;
-       unsigned short count;
-       unsigned short size;
-       struct i596_rfd *v_next;        /* Address from CPUs viewpoint */
-       struct i596_rfd *v_prev;
-#ifndef __LP64__
-       u32 cache_pad[2];               /* Total 32 bytes... */
-#endif
-};
-
-struct i596_rbd {
-    /* hardware data */
-    unsigned short count;
-    unsigned short zero1;
-    dma_addr_t     b_next;
-    dma_addr_t     b_data;             /* Address from i596 viewpoint */
-    unsigned short size;
-    unsigned short zero2;
-    /* driver data */
-    struct sk_buff *skb;
-    struct i596_rbd *v_next;
-    dma_addr_t     b_addr;             /* This rbd addr from i596 view */
-    unsigned char *v_data;             /* Address from CPUs viewpoint */
-                                       /* Total 32 bytes... */
-#ifdef __LP64__
-    u32 cache_pad[4];
-#endif
-};
-
-/* These values as chosen so struct i596_private fits in one page... */
-
-#define TX_RING_SIZE 32
-#define RX_RING_SIZE 16
-
-struct i596_scb {
-       unsigned short status;
-       unsigned short command;
-       dma_addr_t    cmd;
-       dma_addr_t    rfd;
-       u32           crc_err;
-       u32           align_err;
-       u32           resource_err;
-       u32           over_err;
-       u32           rcvdt_err;
-       u32           short_err;
-       unsigned short t_on;
-       unsigned short t_off;
-};
-
-struct i596_iscp {
-       u32           stat;
-       dma_addr_t    scb;
-};
-
-struct i596_scp {
-       u32           sysbus;
-       u32            pad;
-       dma_addr_t    iscp;
-};
-
-struct i596_private {
-       volatile struct i596_scp scp            __attribute__((aligned(32)));
-       volatile struct i596_iscp iscp          __attribute__((aligned(32)));
-       volatile struct i596_scb scb            __attribute__((aligned(32)));
-       struct sa_cmd sa_cmd                    __attribute__((aligned(32)));
-       struct cf_cmd cf_cmd                    __attribute__((aligned(32)));
-       struct tdr_cmd tdr_cmd                  __attribute__((aligned(32)));
-       struct mc_cmd mc_cmd                    __attribute__((aligned(32)));
-       struct i596_rfd rfds[RX_RING_SIZE]      __attribute__((aligned(32)));
-       struct i596_rbd rbds[RX_RING_SIZE]      __attribute__((aligned(32)));
-       struct tx_cmd tx_cmds[TX_RING_SIZE]     __attribute__((aligned(32)));
-       struct i596_tbd tbds[TX_RING_SIZE]      __attribute__((aligned(32)));
-       u32    stat;
-       int last_restart;
-       struct i596_rfd *rfd_head;
-       struct i596_rbd *rbd_head;
-       struct i596_cmd *cmd_tail;
-       struct i596_cmd *cmd_head;
-       int cmd_backlog;
-       u32    last_cmd;
-       struct net_device_stats stats;
-       int next_tx_cmd;
-       int options;
-       spinlock_t lock;
-       dma_addr_t dma_addr;
-       struct device *dev;
-};
-
-static const char init_setup[] =
-{
-       0x8E,                   /* length, prefetch on */
-       0xC8,                   /* fifo to 8, monitor off */
-       0x80,                   /* don't save bad frames */
-       0x2E,                   /* No source address insertion, 8 byte preamble */
-       0x00,                   /* priority and backoff defaults */
-       0x60,                   /* interframe spacing */
-       0x00,                   /* slot time LSB */
-       0xf2,                   /* slot time and retries */
-       0x00,                   /* promiscuous mode */
-       0x00,                   /* collision detect */
-       0x40,                   /* minimum frame length */
-       0xff,
-       0x00,
-       0x7f /*  *multi IA */ };
-
-static int i596_open(struct net_device *dev);
-static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t i596_interrupt(int irq, void *dev_id);
-static int i596_close(struct net_device *dev);
-static struct net_device_stats *i596_get_stats(struct net_device *dev);
-static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd);
-static void i596_tx_timeout (struct net_device *dev);
-static void print_eth(unsigned char *buf, char *str);
-static void set_multicast_list(struct net_device *dev);
-
-static int rx_ring_size = RX_RING_SIZE;
-static int ticks_limit = 100;
-static int max_cmd_backlog = TX_RING_SIZE-1;
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-static void i596_poll_controller(struct net_device *dev);
-#endif
-
-
-static inline void CA(struct net_device *dev)
+static inline void ca(struct net_device *dev)
 {
        gsc_writel(0, dev->base_addr + PA_CHANNEL_ATTENTION);
 }
 
 
-static inline void MPU_PORT(struct net_device *dev, int c, dma_addr_t x)
+static void mpu_port(struct net_device *dev, int c, dma_addr_t x)
 {
-       struct i596_private *lp = dev->priv;
+       struct i596_private *lp = netdev_priv(dev);
 
        u32 v = (u32) (c) | (u32) (x);
        u16 a, b;
@@ -446,1078 +149,15 @@ static inline void MPU_PORT(struct net_device *dev, int c, dma_addr_t x)
        gsc_writel(b, dev->base_addr + PA_CPU_PORT_L_ACCESS);
 }
 
-
-static inline int wait_istat(struct net_device *dev, struct i596_private *lp, int delcnt, char *str)
-{
-       CHECK_INV(lp, &(lp->iscp), sizeof(struct i596_iscp));
-       while (--delcnt && lp->iscp.stat) {
-               udelay(10);
-               CHECK_INV(lp, &(lp->iscp), sizeof(struct i596_iscp));
-       }
-       if (!delcnt) {
-               printk("%s: %s, iscp.stat %04x, didn't clear\n",
-                    dev->name, str, lp->iscp.stat);
-               return -1;
-       }
-       else
-               return 0;
-}
-
-
-static inline int wait_cmd(struct net_device *dev, struct i596_private *lp, int delcnt, char *str)
-{
-       CHECK_INV(lp, &(lp->scb), sizeof(struct i596_scb));
-       while (--delcnt && lp->scb.command) {
-               udelay(10);
-               CHECK_INV(lp, &(lp->scb), sizeof(struct i596_scb));
-       }
-       if (!delcnt) {
-               printk("%s: %s, status %4.4x, cmd %4.4x.\n",
-                    dev->name, str, lp->scb.status, lp->scb.command);
-               return -1;
-       }
-       else
-               return 0;
-}
-
-
-static void i596_display_data(struct net_device *dev)
-{
-       struct i596_private *lp = dev->priv;
-       struct i596_cmd *cmd;
-       struct i596_rfd *rfd;
-       struct i596_rbd *rbd;
-
-       printk("lp and scp at %p, .sysbus = %08x, .iscp = %08x\n",
-              &lp->scp, lp->scp.sysbus, lp->scp.iscp);
-       printk("iscp at %p, iscp.stat = %08x, .scb = %08x\n",
-              &lp->iscp, lp->iscp.stat, lp->iscp.scb);
-       printk("scb at %p, scb.status = %04x, .command = %04x,"
-               " .cmd = %08x, .rfd = %08x\n",
-              &lp->scb, lp->scb.status, lp->scb.command,
-               lp->scb.cmd, lp->scb.rfd);
-       printk("   errors: crc %x, align %x, resource %x,"
-               " over %x, rcvdt %x, short %x\n",
-               lp->scb.crc_err, lp->scb.align_err, lp->scb.resource_err,
-               lp->scb.over_err, lp->scb.rcvdt_err, lp->scb.short_err);
-       cmd = lp->cmd_head;
-       while (cmd != NULL) {
-               printk("cmd at %p, .status = %04x, .command = %04x, .b_next = %08x\n",
-                 cmd, cmd->status, cmd->command, cmd->b_next);
-               cmd = cmd->v_next;
-       }
-       rfd = lp->rfd_head;
-       printk("rfd_head = %p\n", rfd);
-       do {
-               printk("   %p .stat %04x, .cmd %04x, b_next %08x, rbd %08x,"
-                        " count %04x\n",
-                       rfd, rfd->stat, rfd->cmd, rfd->b_next, rfd->rbd,
-                       rfd->count);
-               rfd = rfd->v_next;
-       } while (rfd != lp->rfd_head);
-       rbd = lp->rbd_head;
-       printk("rbd_head = %p\n", rbd);
-       do {
-               printk("   %p .count %04x, b_next %08x, b_data %08x, size %04x\n",
-                       rbd, rbd->count, rbd->b_next, rbd->b_data, rbd->size);
-               rbd = rbd->v_next;
-       } while (rbd != lp->rbd_head);
-       CHECK_INV(lp, lp, sizeof(struct i596_private));
-}
-
-
-#if defined(ENABLE_MVME16x_NET) || defined(ENABLE_BVME6000_NET)
-static void i596_error(int irq, void *dev_id)
-{
-       struct net_device *dev = dev_id;
-       volatile unsigned char *pcc2 = (unsigned char *) 0xfff42000;
-
-       pcc2[0x28] = 1;
-       pcc2[0x2b] = 0x1d;
-       printk("%s: Error interrupt\n", dev->name);
-       i596_display_data(dev);
-}
-#endif
-
-#define virt_to_dma(lp,v) ((lp)->dma_addr + (dma_addr_t)((unsigned long)(v)-(unsigned long)(lp)))
-
-static inline void init_rx_bufs(struct net_device *dev)
-{
-       struct i596_private *lp = dev->priv;
-       int i;
-       struct i596_rfd *rfd;
-       struct i596_rbd *rbd;
-
-       /* First build the Receive Buffer Descriptor List */
-
-       for (i = 0, rbd = lp->rbds; i < rx_ring_size; i++, rbd++) {
-               dma_addr_t dma_addr;
-               struct sk_buff *skb = dev_alloc_skb(PKT_BUF_SZ + 4);
-
-               if (skb == NULL)
-                       panic("%s: alloc_skb() failed", __FILE__);
-               skb_reserve(skb, 2);
-               dma_addr = dma_map_single(lp->dev, skb->data,PKT_BUF_SZ,
-                                         DMA_FROM_DEVICE);
-               skb->dev = dev;
-               rbd->v_next = rbd+1;
-               rbd->b_next = WSWAPrbd(virt_to_dma(lp,rbd+1));
-               rbd->b_addr = WSWAPrbd(virt_to_dma(lp,rbd));
-               rbd->skb = skb;
-               rbd->v_data = skb->data;
-               rbd->b_data = WSWAPchar(dma_addr);
-               rbd->size = PKT_BUF_SZ;
-       }
-       lp->rbd_head = lp->rbds;
-       rbd = lp->rbds + rx_ring_size - 1;
-       rbd->v_next = lp->rbds;
-       rbd->b_next = WSWAPrbd(virt_to_dma(lp,lp->rbds));
-
-       /* Now build the Receive Frame Descriptor List */
-
-       for (i = 0, rfd = lp->rfds; i < rx_ring_size; i++, rfd++) {
-               rfd->rbd = I596_NULL;
-               rfd->v_next = rfd+1;
-               rfd->v_prev = rfd-1;
-               rfd->b_next = WSWAPrfd(virt_to_dma(lp,rfd+1));
-               rfd->cmd = CMD_FLEX;
-       }
-       lp->rfd_head = lp->rfds;
-       lp->scb.rfd = WSWAPrfd(virt_to_dma(lp,lp->rfds));
-       rfd = lp->rfds;
-       rfd->rbd = WSWAPrbd(virt_to_dma(lp,lp->rbd_head));
-       rfd->v_prev = lp->rfds + rx_ring_size - 1;
-       rfd = lp->rfds + rx_ring_size - 1;
-       rfd->v_next = lp->rfds;
-       rfd->b_next = WSWAPrfd(virt_to_dma(lp,lp->rfds));
-       rfd->cmd = CMD_EOL|CMD_FLEX;
-
-       CHECK_WBACK_INV(lp, lp, sizeof(struct i596_private));
-}
-
-static inline void remove_rx_bufs(struct net_device *dev)
-{
-       struct i596_private *lp = dev->priv;
-       struct i596_rbd *rbd;
-       int i;
-
-       for (i = 0, rbd = lp->rbds; i < rx_ring_size; i++, rbd++) {
-               if (rbd->skb == NULL)
-                       break;
-               dma_unmap_single(lp->dev,
-                                (dma_addr_t)WSWAPchar(rbd->b_data),
-                                PKT_BUF_SZ, DMA_FROM_DEVICE);
-               dev_kfree_skb(rbd->skb);
-       }
-}
-
-
-static void rebuild_rx_bufs(struct net_device *dev)
-{
-       struct i596_private *lp = dev->priv;
-       int i;
-
-       /* Ensure rx frame/buffer descriptors are tidy */
-
-       for (i = 0; i < rx_ring_size; i++) {
-               lp->rfds[i].rbd = I596_NULL;
-               lp->rfds[i].cmd = CMD_FLEX;
-       }
-       lp->rfds[rx_ring_size-1].cmd = CMD_EOL|CMD_FLEX;
-       lp->rfd_head = lp->rfds;
-       lp->scb.rfd = WSWAPrfd(virt_to_dma(lp,lp->rfds));
-       lp->rbd_head = lp->rbds;
-       lp->rfds[0].rbd = WSWAPrbd(virt_to_dma(lp,lp->rbds));
-
-       CHECK_WBACK_INV(lp, lp, sizeof(struct i596_private));
-}
-
-
-static int init_i596_mem(struct net_device *dev)
-{
-       struct i596_private *lp = dev->priv;
-       unsigned long flags;
-
-       disable_irq(dev->irq);  /* disable IRQs from LAN */
-       DEB(DEB_INIT,
-               printk("RESET 82596 port: %lx (with IRQ %d disabled)\n",
-                      (dev->base_addr + PA_I82596_RESET),
-                      dev->irq));
-
-       gsc_writel(0, (dev->base_addr + PA_I82596_RESET)); /* Hard Reset */
-       udelay(100);                    /* Wait 100us - seems to help */
-
-       /* change the scp address */
-
-       lp->last_cmd = jiffies;
-
-
-       lp->scp.sysbus = 0x0000006c;
-       lp->scp.iscp = WSWAPiscp(virt_to_dma(lp,&(lp->iscp)));
-       lp->iscp.scb = WSWAPscb(virt_to_dma(lp,&(lp->scb)));
-       lp->iscp.stat = ISCP_BUSY;
-       lp->cmd_backlog = 0;
-
-       lp->cmd_head = NULL;
-        lp->scb.cmd = I596_NULL;
-
-       DEB(DEB_INIT, printk("%s: starting i82596.\n", dev->name));
-
-       CHECK_WBACK(lp, &(lp->scp), sizeof(struct i596_scp));
-       CHECK_WBACK(lp, &(lp->iscp), sizeof(struct i596_iscp));
-
-       MPU_PORT(dev, PORT_ALTSCP, virt_to_dma(lp,&lp->scp));
-
-       CA(dev);
-
-       if (wait_istat(dev, lp, 1000, "initialization timed out"))
-               goto failed;
-       DEB(DEB_INIT, printk("%s: i82596 initialization successful\n", dev->name));
-
-       /* Ensure rx frame/buffer descriptors are tidy */
-       rebuild_rx_bufs(dev);
-
-       lp->scb.command = 0;
-       CHECK_WBACK(lp, &(lp->scb), sizeof(struct i596_scb));
-
-       enable_irq(dev->irq);   /* enable IRQs from LAN */
-
-       DEB(DEB_INIT, printk("%s: queuing CmdConfigure\n", dev->name));
-       memcpy(lp->cf_cmd.i596_config, init_setup, sizeof(init_setup));
-       lp->cf_cmd.cmd.command = CmdConfigure;
-       CHECK_WBACK(lp, &(lp->cf_cmd), sizeof(struct cf_cmd));
-       i596_add_cmd(dev, &lp->cf_cmd.cmd);
-
-       DEB(DEB_INIT, printk("%s: queuing CmdSASetup\n", dev->name));
-       memcpy(lp->sa_cmd.eth_addr, dev->dev_addr, 6);
-       lp->sa_cmd.cmd.command = CmdSASetup;
-       CHECK_WBACK(lp, &(lp->sa_cmd), sizeof(struct sa_cmd));
-       i596_add_cmd(dev, &lp->sa_cmd.cmd);
-
-       DEB(DEB_INIT, printk("%s: queuing CmdTDR\n", dev->name));
-       lp->tdr_cmd.cmd.command = CmdTDR;
-       CHECK_WBACK(lp, &(lp->tdr_cmd), sizeof(struct tdr_cmd));
-       i596_add_cmd(dev, &lp->tdr_cmd.cmd);
-
-       spin_lock_irqsave (&lp->lock, flags);
-
-       if (wait_cmd(dev, lp, 1000, "timed out waiting to issue RX_START")) {
-               spin_unlock_irqrestore (&lp->lock, flags);
-               goto failed;
-       }
-       DEB(DEB_INIT, printk("%s: Issuing RX_START\n", dev->name));
-       lp->scb.command = RX_START;
-       lp->scb.rfd = WSWAPrfd(virt_to_dma(lp,lp->rfds));
-       CHECK_WBACK(lp, &(lp->scb), sizeof(struct i596_scb));
-
-       CA(dev);
-
-       spin_unlock_irqrestore (&lp->lock, flags);
-
-       if (wait_cmd(dev, lp, 1000, "RX_START not processed"))
-               goto failed;
-       DEB(DEB_INIT, printk("%s: Receive unit started OK\n", dev->name));
-
-       return 0;
-
-failed:
-       printk("%s: Failed to initialise 82596\n", dev->name);
-       MPU_PORT(dev, PORT_RESET, 0);
-       return -1;
-}
-
-
-static inline int i596_rx(struct net_device *dev)
-{
-       struct i596_private *lp = dev->priv;
-       struct i596_rfd *rfd;
-       struct i596_rbd *rbd;
-       int frames = 0;
-
-       DEB(DEB_RXFRAME, printk("i596_rx(), rfd_head %p, rbd_head %p\n",
-                       lp->rfd_head, lp->rbd_head));
-
-
-       rfd = lp->rfd_head;             /* Ref next frame to check */
-
-       CHECK_INV(lp, rfd, sizeof(struct i596_rfd));
-       while ((rfd->stat) & STAT_C) {  /* Loop while complete frames */
-               if (rfd->rbd == I596_NULL)
-                       rbd = NULL;
-               else if (rfd->rbd == lp->rbd_head->b_addr) {
-                       rbd = lp->rbd_head;
-                       CHECK_INV(lp, rbd, sizeof(struct i596_rbd));
-               }
-               else {
-                       printk("%s: rbd chain broken!\n", dev->name);
-                       /* XXX Now what? */
-                       rbd = NULL;
-               }
-               DEB(DEB_RXFRAME, printk("  rfd %p, rfd.rbd %08x, rfd.stat %04x\n",
-                       rfd, rfd->rbd, rfd->stat));
-
-               if (rbd != NULL && ((rfd->stat) & STAT_OK)) {
-                       /* a good frame */
-                       int pkt_len = rbd->count & 0x3fff;
-                       struct sk_buff *skb = rbd->skb;
-                       int rx_in_place = 0;
-
-                       DEB(DEB_RXADDR,print_eth(rbd->v_data, "received"));
-                       frames++;
-
-                       /* Check if the packet is long enough to just accept
-                        * without copying to a properly sized skbuff.
-                        */
-
-                       if (pkt_len > rx_copybreak) {
-                               struct sk_buff *newskb;
-                               dma_addr_t dma_addr;
-
-                               dma_unmap_single(lp->dev,(dma_addr_t)WSWAPchar(rbd->b_data), PKT_BUF_SZ, DMA_FROM_DEVICE);
-                               /* Get fresh skbuff to replace filled one. */
-                               newskb = dev_alloc_skb(PKT_BUF_SZ + 4);
-                               if (newskb == NULL) {
-                                       skb = NULL;     /* drop pkt */
-                                       goto memory_squeeze;
-                               }
-                               skb_reserve(newskb, 2);
-
-                               /* Pass up the skb already on the Rx ring. */
-                               skb_put(skb, pkt_len);
-                               rx_in_place = 1;
-                               rbd->skb = newskb;
-                               newskb->dev = dev;
-                               dma_addr = dma_map_single(lp->dev, newskb->data, PKT_BUF_SZ, DMA_FROM_DEVICE);
-                               rbd->v_data = newskb->data;
-                               rbd->b_data = WSWAPchar(dma_addr);
-                               CHECK_WBACK_INV(lp, rbd, sizeof(struct i596_rbd));
-                       }
-                       else
-                               skb = dev_alloc_skb(pkt_len + 2);
-memory_squeeze:
-                       if (skb == NULL) {
-                               /* XXX tulip.c can defer packets here!! */
-                               printk("%s: i596_rx Memory squeeze, dropping packet.\n", dev->name);
-                               lp->stats.rx_dropped++;
-                       }
-                       else {
-                               if (!rx_in_place) {
-                                       /* 16 byte align the data fields */
-                                       dma_sync_single_for_cpu(lp->dev, (dma_addr_t)WSWAPchar(rbd->b_data), PKT_BUF_SZ, DMA_FROM_DEVICE);
-                                       skb_reserve(skb, 2);
-                                       memcpy(skb_put(skb,pkt_len), rbd->v_data, pkt_len);
-                                       dma_sync_single_for_device(lp->dev, (dma_addr_t)WSWAPchar(rbd->b_data), PKT_BUF_SZ, DMA_FROM_DEVICE);
-                               }
-                               skb->len = pkt_len;
-                               skb->protocol=eth_type_trans(skb,dev);
-                               netif_rx(skb);
-                               dev->last_rx = jiffies;
-                               lp->stats.rx_packets++;
-                               lp->stats.rx_bytes+=pkt_len;
-                       }
-               }
-               else {
-                       DEB(DEB_ERRORS, printk("%s: Error, rfd.stat = 0x%04x\n",
-                                       dev->name, rfd->stat));
-                       lp->stats.rx_errors++;
-                       if ((rfd->stat) & 0x0001)
-                               lp->stats.collisions++;
-                       if ((rfd->stat) & 0x0080)
-                               lp->stats.rx_length_errors++;
-                       if ((rfd->stat) & 0x0100)
-                               lp->stats.rx_over_errors++;
-                       if ((rfd->stat) & 0x0200)
-                               lp->stats.rx_fifo_errors++;
-                       if ((rfd->stat) & 0x0400)
-                               lp->stats.rx_frame_errors++;
-                       if ((rfd->stat) & 0x0800)
-                               lp->stats.rx_crc_errors++;
-                       if ((rfd->stat) & 0x1000)
-                               lp->stats.rx_length_errors++;
-               }
-
-               /* Clear the buffer descriptor count and EOF + F flags */
-
-               if (rbd != NULL && (rbd->count & 0x4000)) {
-                       rbd->count = 0;
-                       lp->rbd_head = rbd->v_next;
-                       CHECK_WBACK_INV(lp, rbd, sizeof(struct i596_rbd));
-               }
-
-               /* Tidy the frame descriptor, marking it as end of list */
-
-               rfd->rbd = I596_NULL;
-               rfd->stat = 0;
-               rfd->cmd = CMD_EOL|CMD_FLEX;
-               rfd->count = 0;
-
-               /* Remove end-of-list from old end descriptor */
-
-               rfd->v_prev->cmd = CMD_FLEX;
-
-               /* Update record of next frame descriptor to process */
-
-               lp->scb.rfd = rfd->b_next;
-               lp->rfd_head = rfd->v_next;
-               CHECK_WBACK_INV(lp, rfd->v_prev, sizeof(struct i596_rfd));
-               CHECK_WBACK_INV(lp, rfd, sizeof(struct i596_rfd));
-               rfd = lp->rfd_head;
-               CHECK_INV(lp, rfd, sizeof(struct i596_rfd));
-       }
-
-       DEB(DEB_RXFRAME, printk("frames %d\n", frames));
-
-       return 0;
-}
-
-
-static inline void i596_cleanup_cmd(struct net_device *dev, struct i596_private *lp)
-{
-       struct i596_cmd *ptr;
-
-       while (lp->cmd_head != NULL) {
-               ptr = lp->cmd_head;
-               lp->cmd_head = ptr->v_next;
-               lp->cmd_backlog--;
-
-               switch ((ptr->command) & 0x7) {
-               case CmdTx:
-                       {
-                               struct tx_cmd *tx_cmd = (struct tx_cmd *) ptr;
-                               struct sk_buff *skb = tx_cmd->skb;
-                               dma_unmap_single(lp->dev, tx_cmd->dma_addr, skb->len, DMA_TO_DEVICE);
-
-                               dev_kfree_skb(skb);
-
-                               lp->stats.tx_errors++;
-                               lp->stats.tx_aborted_errors++;
-
-                               ptr->v_next = NULL;
-                               ptr->b_next = I596_NULL;
-                               tx_cmd->cmd.command = 0;  /* Mark as free */
-                               break;
-                       }
-               default:
-                       ptr->v_next = NULL;
-                       ptr->b_next = I596_NULL;
-               }
-               CHECK_WBACK_INV(lp, ptr, sizeof(struct i596_cmd));
-       }
-
-       wait_cmd(dev, lp, 100, "i596_cleanup_cmd timed out");
-       lp->scb.cmd = I596_NULL;
-       CHECK_WBACK(lp, &(lp->scb), sizeof(struct i596_scb));
-}
-
-
-static inline void i596_reset(struct net_device *dev, struct i596_private *lp)
-{
-       unsigned long flags;
-
-       DEB(DEB_RESET, printk("i596_reset\n"));
-
-       spin_lock_irqsave (&lp->lock, flags);
-
-       wait_cmd(dev, lp, 100, "i596_reset timed out");
-
-       netif_stop_queue(dev);
-
-       /* FIXME: this command might cause an lpmc */
-       lp->scb.command = CUC_ABORT | RX_ABORT;
-       CHECK_WBACK(lp, &(lp->scb), sizeof(struct i596_scb));
-       CA(dev);
-
-       /* wait for shutdown */
-       wait_cmd(dev, lp, 1000, "i596_reset 2 timed out");
-       spin_unlock_irqrestore (&lp->lock, flags);
-
-       i596_cleanup_cmd(dev,lp);
-       i596_rx(dev);
-
-       netif_start_queue(dev);
-       init_i596_mem(dev);
-}
-
-
-static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd)
-{
-       struct i596_private *lp = dev->priv;
-       unsigned long flags;
-
-       DEB(DEB_ADDCMD, printk("i596_add_cmd cmd_head %p\n", lp->cmd_head));
-
-       cmd->status = 0;
-       cmd->command |= (CMD_EOL | CMD_INTR);
-       cmd->v_next = NULL;
-       cmd->b_next = I596_NULL;
-       CHECK_WBACK(lp, cmd, sizeof(struct i596_cmd));
-
-       spin_lock_irqsave (&lp->lock, flags);
-
-       if (lp->cmd_head != NULL) {
-               lp->cmd_tail->v_next = cmd;
-               lp->cmd_tail->b_next = WSWAPcmd(virt_to_dma(lp,&cmd->status));
-               CHECK_WBACK(lp, lp->cmd_tail, sizeof(struct i596_cmd));
-       } else {
-               lp->cmd_head = cmd;
-               wait_cmd(dev, lp, 100, "i596_add_cmd timed out");
-               lp->scb.cmd = WSWAPcmd(virt_to_dma(lp,&cmd->status));
-               lp->scb.command = CUC_START;
-               CHECK_WBACK(lp, &(lp->scb), sizeof(struct i596_scb));
-               CA(dev);
-       }
-       lp->cmd_tail = cmd;
-       lp->cmd_backlog++;
-
-       spin_unlock_irqrestore (&lp->lock, flags);
-
-       if (lp->cmd_backlog > max_cmd_backlog) {
-               unsigned long tickssofar = jiffies - lp->last_cmd;
-
-               if (tickssofar < ticks_limit)
-                       return;
-
-               printk("%s: command unit timed out, status resetting.\n", dev->name);
-#if 1
-               i596_reset(dev, lp);
-#endif
-       }
-}
-
-#if 0
-/* this function makes a perfectly adequate probe...  but we have a
-   device list */
-static int i596_test(struct net_device *dev)
-{
-       struct i596_private *lp = dev->priv;
-       volatile int *tint;
-       u32 data;
-
-       tint = (volatile int *)(&(lp->scp));
-       data = virt_to_dma(lp,tint);
-
-       tint[1] = -1;
-       CHECK_WBACK(lp, tint, PAGE_SIZE);
-
-       MPU_PORT(dev, 1, data);
-
-       for(data = 1000000; data; data--) {
-               CHECK_INV(lp, tint, PAGE_SIZE);
-               if(tint[1] != -1)
-                       break;
-
-       }
-
-       printk("i596_test result %d\n", tint[1]);
-
-}
-#endif
-
-
-static int i596_open(struct net_device *dev)
-{
-       DEB(DEB_OPEN, printk("%s: i596_open() irq %d.\n", dev->name, dev->irq));
-
-       if (request_irq(dev->irq, &i596_interrupt, 0, "i82596", dev)) {
-               printk("%s: IRQ %d not free\n", dev->name, dev->irq);
-               goto out;
-       }
-
-       init_rx_bufs(dev);
-
-       if (init_i596_mem(dev)) {
-               printk("%s: Failed to init memory\n", dev->name);
-               goto out_remove_rx_bufs;
-       }
-
-       netif_start_queue(dev);
-
-       return 0;
-
-out_remove_rx_bufs:
-       remove_rx_bufs(dev);
-       free_irq(dev->irq, dev);
-out:
-       return -EAGAIN;
-}
-
-static void i596_tx_timeout (struct net_device *dev)
-{
-       struct i596_private *lp = dev->priv;
-
-       /* Transmitter timeout, serious problems. */
-       DEB(DEB_ERRORS, printk("%s: transmit timed out, status resetting.\n",
-                       dev->name));
-
-       lp->stats.tx_errors++;
-
-       /* Try to restart the adaptor */
-       if (lp->last_restart == lp->stats.tx_packets) {
-               DEB(DEB_ERRORS, printk("Resetting board.\n"));
-               /* Shutdown and restart */
-               i596_reset (dev, lp);
-       } else {
-               /* Issue a channel attention signal */
-               DEB(DEB_ERRORS, printk("Kicking board.\n"));
-               lp->scb.command = CUC_START | RX_START;
-               CHECK_WBACK_INV(lp, &(lp->scb), sizeof(struct i596_scb));
-               CA (dev);
-               lp->last_restart = lp->stats.tx_packets;
-       }
-
-       dev->trans_start = jiffies;
-       netif_wake_queue (dev);
-}
-
-
-static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-       struct i596_private *lp = dev->priv;
-       struct tx_cmd *tx_cmd;
-       struct i596_tbd *tbd;
-       short length = skb->len;
-       dev->trans_start = jiffies;
-
-       DEB(DEB_STARTTX, printk("%s: i596_start_xmit(%x,%p) called\n", dev->name,
-                               skb->len, skb->data));
-
-       if (length < ETH_ZLEN) {
-               if (skb_padto(skb, ETH_ZLEN))
-                       return 0;
-               length = ETH_ZLEN;
-       }
-
-       netif_stop_queue(dev);
-
-       tx_cmd = lp->tx_cmds + lp->next_tx_cmd;
-       tbd = lp->tbds + lp->next_tx_cmd;
-
-       if (tx_cmd->cmd.command) {
-               DEB(DEB_ERRORS, printk("%s: xmit ring full, dropping packet.\n",
-                               dev->name));
-               lp->stats.tx_dropped++;
-
-               dev_kfree_skb(skb);
-       } else {
-               if (++lp->next_tx_cmd == TX_RING_SIZE)
-                       lp->next_tx_cmd = 0;
-               tx_cmd->tbd = WSWAPtbd(virt_to_dma(lp,tbd));
-               tbd->next = I596_NULL;
-
-               tx_cmd->cmd.command = CMD_FLEX | CmdTx;
-               tx_cmd->skb = skb;
-
-               tx_cmd->pad = 0;
-               tx_cmd->size = 0;
-               tbd->pad = 0;
-               tbd->size = EOF | length;
-
-               tx_cmd->dma_addr = dma_map_single(lp->dev, skb->data, skb->len,
-                               DMA_TO_DEVICE);
-               tbd->data = WSWAPchar(tx_cmd->dma_addr);
-
-               DEB(DEB_TXADDR,print_eth(skb->data, "tx-queued"));
-               CHECK_WBACK_INV(lp, tx_cmd, sizeof(struct tx_cmd));
-               CHECK_WBACK_INV(lp, tbd, sizeof(struct i596_tbd));
-               i596_add_cmd(dev, &tx_cmd->cmd);
-
-               lp->stats.tx_packets++;
-               lp->stats.tx_bytes += length;
-       }
-
-       netif_start_queue(dev);
-
-       return 0;
-}
-
-static void print_eth(unsigned char *add, char *str)
-{
-       int i;
-
-       printk("i596 0x%p, ", add);
-       for (i = 0; i < 6; i++)
-               printk(" %02X", add[i + 6]);
-       printk(" -->");
-       for (i = 0; i < 6; i++)
-               printk(" %02X", add[i]);
-       printk(" %02X%02X, %s\n", add[12], add[13], str);
-}
-
-
 #define LAN_PROM_ADDR  0xF0810000
 
-static int __devinit i82596_probe(struct net_device *dev,
-                                 struct device *gen_dev)
-{
-       int i;
-       struct i596_private *lp;
-       char eth_addr[6];
-       dma_addr_t dma_addr;
-
-       /* This lot is ensure things have been cache line aligned. */
-       BUILD_BUG_ON(sizeof(struct i596_rfd) != 32);
-       BUILD_BUG_ON(sizeof(struct i596_rbd) &  31);
-       BUILD_BUG_ON(sizeof(struct tx_cmd)   &  31);
-       BUILD_BUG_ON(sizeof(struct i596_tbd) != 32);
-#ifndef __LP64__
-       BUILD_BUG_ON(sizeof(struct i596_private) > 4096);
-#endif
-
-       if (!dev->base_addr || !dev->irq)
-               return -ENODEV;
-
-       if (pdc_lan_station_id(eth_addr, dev->base_addr)) {
-               for (i=0; i < 6; i++) {
-                       eth_addr[i] = gsc_readb(LAN_PROM_ADDR + i);
-               }
-               printk(KERN_INFO "%s: MAC of HP700 LAN read from EEPROM\n", __FILE__);
-       }
-
-       dev->mem_start = (unsigned long) dma_alloc_noncoherent(gen_dev,
-               sizeof(struct i596_private), &dma_addr, GFP_KERNEL);
-       if (!dev->mem_start) {
-               printk(KERN_ERR "%s: Couldn't get shared memory\n", __FILE__);
-               return -ENOMEM;
-       }
-
-       for (i = 0; i < 6; i++)
-               dev->dev_addr[i] = eth_addr[i];
-
-       /* The 82596-specific entries in the device structure. */
-       dev->open = i596_open;
-       dev->stop = i596_close;
-       dev->hard_start_xmit = i596_start_xmit;
-       dev->get_stats = i596_get_stats;
-       dev->set_multicast_list = set_multicast_list;
-       dev->tx_timeout = i596_tx_timeout;
-       dev->watchdog_timeo = TX_TIMEOUT;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       dev->poll_controller = i596_poll_controller;
-#endif
-
-       dev->priv = (void *)(dev->mem_start);
-
-       lp = dev->priv;
-       memset(lp, 0, sizeof(struct i596_private));
-
-       lp->scb.command = 0;
-       lp->scb.cmd = I596_NULL;
-       lp->scb.rfd = I596_NULL;
-       spin_lock_init(&lp->lock);
-       lp->dma_addr = dma_addr;
-       lp->dev = gen_dev;
-
-       CHECK_WBACK_INV(lp, dev->mem_start, sizeof(struct i596_private));
-
-       i = register_netdev(dev);
-       if (i) {
-               lp = dev->priv;
-               dma_free_noncoherent(lp->dev, sizeof(struct i596_private),
-                                   (void *)dev->mem_start, lp->dma_addr);
-               return i;
-       };
-
-       DEB(DEB_PROBE, printk(KERN_INFO "%s: 82596 at %#3lx,", dev->name, dev->base_addr));
-       for (i = 0; i < 6; i++)
-               DEB(DEB_PROBE, printk(" %2.2X", dev->dev_addr[i]));
-       DEB(DEB_PROBE, printk(" IRQ %d.\n", dev->irq));
-       DEB(DEB_INIT, printk(KERN_INFO "%s: lp at 0x%p (%d bytes), lp->scb at 0x%p\n",
-               dev->name, lp, (int)sizeof(struct i596_private), &lp->scb));
-
-       return 0;
-}
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-static void i596_poll_controller(struct net_device *dev)
-{
-       disable_irq(dev->irq);
-       i596_interrupt(dev->irq, dev);
-       enable_irq(dev->irq);
-}
-#endif
-
-static irqreturn_t i596_interrupt(int irq, void *dev_id)
-{
-       struct net_device *dev = dev_id;
-       struct i596_private *lp;
-       unsigned short status, ack_cmd = 0;
-
-       if (dev == NULL) {
-               printk("%s: irq %d for unknown device.\n", __FUNCTION__, irq);
-               return IRQ_NONE;
-       }
-
-       lp = dev->priv;
-
-       spin_lock (&lp->lock);
-
-       wait_cmd(dev, lp, 100, "i596 interrupt, timeout");
-       status = lp->scb.status;
-
-       DEB(DEB_INTS, printk("%s: i596 interrupt, IRQ %d, status %4.4x.\n",
-                       dev->name, irq, status));
-
-       ack_cmd = status & 0xf000;
-
-       if (!ack_cmd) {
-               DEB(DEB_ERRORS, printk("%s: interrupt with no events\n", dev->name));
-               spin_unlock (&lp->lock);
-               return IRQ_NONE;
-       }
-
-       if ((status & 0x8000) || (status & 0x2000)) {
-               struct i596_cmd *ptr;
-
-               if ((status & 0x8000))
-                       DEB(DEB_INTS, printk("%s: i596 interrupt completed command.\n", dev->name));
-               if ((status & 0x2000))
-                       DEB(DEB_INTS, printk("%s: i596 interrupt command unit inactive %x.\n", dev->name, status & 0x0700));
-
-               while (lp->cmd_head != NULL) {
-                       CHECK_INV(lp, lp->cmd_head, sizeof(struct i596_cmd));
-                       if (!(lp->cmd_head->status & STAT_C))
-                               break;
-
-                       ptr = lp->cmd_head;
-
-                       DEB(DEB_STATUS, printk("cmd_head->status = %04x, ->command = %04x\n",
-                                      lp->cmd_head->status, lp->cmd_head->command));
-                       lp->cmd_head = ptr->v_next;
-                       lp->cmd_backlog--;
-
-                       switch ((ptr->command) & 0x7) {
-                       case CmdTx:
-                           {
-                               struct tx_cmd *tx_cmd = (struct tx_cmd *) ptr;
-                               struct sk_buff *skb = tx_cmd->skb;
-
-                               if ((ptr->status) & STAT_OK) {
-                                       DEB(DEB_TXADDR, print_eth(skb->data, "tx-done"));
-                               } else {
-                                       lp->stats.tx_errors++;
-                                       if ((ptr->status) & 0x0020)
-                                               lp->stats.collisions++;
-                                       if (!((ptr->status) & 0x0040))
-                                               lp->stats.tx_heartbeat_errors++;
-                                       if ((ptr->status) & 0x0400)
-                                               lp->stats.tx_carrier_errors++;
-                                       if ((ptr->status) & 0x0800)
-                                               lp->stats.collisions++;
-                                       if ((ptr->status) & 0x1000)
-                                               lp->stats.tx_aborted_errors++;
-                               }
-                               dma_unmap_single(lp->dev, tx_cmd->dma_addr, skb->len, DMA_TO_DEVICE);
-                               dev_kfree_skb_irq(skb);
-
-                               tx_cmd->cmd.command = 0; /* Mark free */
-                               break;
-                           }
-                       case CmdTDR:
-                           {
-                               unsigned short status = ((struct tdr_cmd *)ptr)->status;
-
-                               if (status & 0x8000) {
-                                       DEB(DEB_ANY, printk("%s: link ok.\n", dev->name));
-                               } else {
-                                       if (status & 0x4000)
-                                               printk("%s: Transceiver problem.\n", dev->name);
-                                       if (status & 0x2000)
-                                               printk("%s: Termination problem.\n", dev->name);
-                                       if (status & 0x1000)
-                                               printk("%s: Short circuit.\n", dev->name);
-
-                                       DEB(DEB_TDR, printk("%s: Time %d.\n", dev->name, status & 0x07ff));
-                               }
-                               break;
-                           }
-                       case CmdConfigure:
-                               /* Zap command so set_multicast_list() knows it is free */
-                               ptr->command = 0;
-                               break;
-                       }
-                       ptr->v_next = NULL;
-                       ptr->b_next = I596_NULL;
-                       CHECK_WBACK(lp, ptr, sizeof(struct i596_cmd));
-                       lp->last_cmd = jiffies;
-               }
-
-               /* This mess is arranging that only the last of any outstanding
-                * commands has the interrupt bit set.  Should probably really
-                * only add to the cmd queue when the CU is stopped.
-                */
-               ptr = lp->cmd_head;
-               while ((ptr != NULL) && (ptr != lp->cmd_tail)) {
-                       struct i596_cmd *prev = ptr;
-
-                       ptr->command &= 0x1fff;
-                       ptr = ptr->v_next;
-                       CHECK_WBACK_INV(lp, prev, sizeof(struct i596_cmd));
-               }
-
-               if ((lp->cmd_head != NULL))
-                       ack_cmd |= CUC_START;
-               lp->scb.cmd = WSWAPcmd(virt_to_dma(lp,&lp->cmd_head->status));
-               CHECK_WBACK_INV(lp, &lp->scb, sizeof(struct i596_scb));
-       }
-       if ((status & 0x1000) || (status & 0x4000)) {
-               if ((status & 0x4000))
-                       DEB(DEB_INTS, printk("%s: i596 interrupt received a frame.\n", dev->name));
-               i596_rx(dev);
-               /* Only RX_START if stopped - RGH 07-07-96 */
-               if (status & 0x1000) {
-                       if (netif_running(dev)) {
-                               DEB(DEB_ERRORS, printk("%s: i596 interrupt receive unit inactive, status 0x%x\n", dev->name, status));
-                               ack_cmd |= RX_START;
-                               lp->stats.rx_errors++;
-                               lp->stats.rx_fifo_errors++;
-                               rebuild_rx_bufs(dev);
-                       }
-               }
-       }
-       wait_cmd(dev, lp, 100, "i596 interrupt, timeout");
-       lp->scb.command = ack_cmd;
-       CHECK_WBACK(lp, &lp->scb, sizeof(struct i596_scb));
-
-       /* DANGER: I suspect that some kind of interrupt
-        acknowledgement aside from acking the 82596 might be needed
-        here...  but it's running acceptably without */
-
-       CA(dev);
-
-       wait_cmd(dev, lp, 100, "i596 interrupt, exit timeout");
-       DEB(DEB_INTS, printk("%s: exiting interrupt.\n", dev->name));
-
-       spin_unlock (&lp->lock);
-       return IRQ_HANDLED;
-}
-
-static int i596_close(struct net_device *dev)
-{
-       struct i596_private *lp = dev->priv;
-       unsigned long flags;
-
-       netif_stop_queue(dev);
-
-       DEB(DEB_INIT, printk("%s: Shutting down ethercard, status was %4.4x.\n",
-                      dev->name, lp->scb.status));
-
-       spin_lock_irqsave(&lp->lock, flags);
-
-       wait_cmd(dev, lp, 100, "close1 timed out");
-       lp->scb.command = CUC_ABORT | RX_ABORT;
-       CHECK_WBACK(lp, &lp->scb, sizeof(struct i596_scb));
-
-       CA(dev);
-
-       wait_cmd(dev, lp, 100, "close2 timed out");
-       spin_unlock_irqrestore(&lp->lock, flags);
-       DEB(DEB_STRUCT,i596_display_data(dev));
-       i596_cleanup_cmd(dev,lp);
-
-       disable_irq(dev->irq);
-
-       free_irq(dev->irq, dev);
-       remove_rx_bufs(dev);
-
-       return 0;
-}
-
-static struct net_device_stats *
- i596_get_stats(struct net_device *dev)
-{
-       struct i596_private *lp = dev->priv;
-
-       return &lp->stats;
-}
-
-/*
- *    Set or clear the multicast filter for this adaptor.
- */
-
-static void set_multicast_list(struct net_device *dev)
-{
-       struct i596_private *lp = dev->priv;
-       int config = 0, cnt;
-
-       DEB(DEB_MULTI, printk("%s: set multicast list, %d entries, promisc %s, allmulti %s\n",
-               dev->name, dev->mc_count, dev->flags & IFF_PROMISC ? "ON" : "OFF",
-               dev->flags & IFF_ALLMULTI ? "ON" : "OFF"));
-
-       if ((dev->flags & IFF_PROMISC) && !(lp->cf_cmd.i596_config[8] & 0x01)) {
-               lp->cf_cmd.i596_config[8] |= 0x01;
-               config = 1;
-       }
-       if (!(dev->flags & IFF_PROMISC) && (lp->cf_cmd.i596_config[8] & 0x01)) {
-               lp->cf_cmd.i596_config[8] &= ~0x01;
-               config = 1;
-       }
-       if ((dev->flags & IFF_ALLMULTI) && (lp->cf_cmd.i596_config[11] & 0x20)) {
-               lp->cf_cmd.i596_config[11] &= ~0x20;
-               config = 1;
-       }
-       if (!(dev->flags & IFF_ALLMULTI) && !(lp->cf_cmd.i596_config[11] & 0x20)) {
-               lp->cf_cmd.i596_config[11] |= 0x20;
-               config = 1;
-       }
-       if (config) {
-               if (lp->cf_cmd.cmd.command)
-                       printk("%s: config change request already queued\n",
-                              dev->name);
-               else {
-                       lp->cf_cmd.cmd.command = CmdConfigure;
-                       CHECK_WBACK_INV(lp, &lp->cf_cmd, sizeof(struct cf_cmd));
-                       i596_add_cmd(dev, &lp->cf_cmd.cmd);
-               }
-       }
-
-       cnt = dev->mc_count;
-       if (cnt > MAX_MC_CNT)
-       {
-               cnt = MAX_MC_CNT;
-               printk("%s: Only %d multicast addresses supported",
-                       dev->name, cnt);
-       }
-
-       if (dev->mc_count > 0) {
-               struct dev_mc_list *dmi;
-               unsigned char *cp;
-               struct mc_cmd *cmd;
-
-               cmd = &lp->mc_cmd;
-               cmd->cmd.command = CmdMulticastList;
-               cmd->mc_cnt = dev->mc_count * 6;
-               cp = cmd->mc_addrs;
-               for (dmi = dev->mc_list; cnt && dmi != NULL; dmi = dmi->next, cnt--, cp += 6) {
-                       memcpy(cp, dmi->dmi_addr, 6);
-                       if (i596_debug > 1)
-                               DEB(DEB_MULTI, printk("%s: Adding address %02x:%02x:%02x:%02x:%02x:%02x\n",
-                                               dev->name, cp[0],cp[1],cp[2],cp[3],cp[4],cp[5]));
-               }
-               CHECK_WBACK_INV(lp, &lp->mc_cmd, sizeof(struct mc_cmd));
-               i596_add_cmd(dev, &cmd->cmd);
-       }
-}
-
-static int debug = -1;
-module_param(debug, int, 0);
-MODULE_PARM_DESC(debug, "lasi_82596 debug mask");
-
-static int num_drivers;
-static struct net_device *netdevs[MAX_DRIVERS];
-
 static int __devinit
 lan_init_chip(struct parisc_device *dev)
 {
        struct  net_device *netdevice;
+       struct i596_private *lp;
        int     retval;
-
-       if (num_drivers >= MAX_DRIVERS) {
-               /* max count of possible i82596 drivers reached */
-               return -ENOMEM;
-       }
-
-       if (num_drivers == 0)
-               printk(KERN_INFO LASI_82596_DRIVER_VERSION "\n");
+       int i;
 
        if (!dev->irq) {
                printk(KERN_ERR "%s: IRQ not found for i82596 at 0x%lx\n",
@@ -1528,28 +168,45 @@ lan_init_chip(struct parisc_device *dev)
        printk(KERN_INFO "Found i82596 at 0x%lx, IRQ %d\n", dev->hpa.start,
                        dev->irq);
 
-       netdevice = alloc_etherdev(0);
+       netdevice = alloc_etherdev(sizeof(struct i596_private));
        if (!netdevice)
                return -ENOMEM;
+       SET_NETDEV_DEV(netdevice, &dev->dev);
+       parisc_set_drvdata (dev, netdevice);
 
        netdevice->base_addr = dev->hpa.start;
        netdevice->irq = dev->irq;
 
-       retval = i82596_probe(netdevice, &dev->dev);
+       if (pdc_lan_station_id(netdevice->dev_addr, netdevice->base_addr)) {
+               for (i = 0; i < 6; i++) {
+                       netdevice->dev_addr[i] = gsc_readb(LAN_PROM_ADDR + i);
+               }
+               printk(KERN_INFO
+                      "%s: MAC of HP700 LAN read from EEPROM\n", __FILE__);
+       }
+
+       lp = netdev_priv(netdevice);
+       lp->options = dev->id.sversion == 0x72 ? OPT_SWAP_PORT : 0;
+
+       retval = i82596_probe(netdevice);
        if (retval) {
                free_netdev(netdevice);
                return -ENODEV;
        }
-
-       if (dev->id.sversion == 0x72) {
-               ((struct i596_private *)netdevice->priv)->options = OPT_SWAP_PORT;
-       }
-
-       netdevs[num_drivers++] = netdevice;
-
        return retval;
 }
 
+static int __devexit lan_remove_chip (struct parisc_device *pdev)
+{
+       struct net_device *dev = parisc_get_drvdata(pdev);
+       struct i596_private *lp = netdev_priv(dev);
+
+       unregister_netdev (dev);
+       DMA_FREE(&pdev->dev, sizeof(struct i596_private),
+                (void *)lp->dma, lp->dma_addr);
+       free_netdev (dev);
+       return 0;
+}
 
 static struct parisc_device_id lan_tbl[] = {
        { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008a },
@@ -1563,12 +220,12 @@ static struct parisc_driver lan_driver = {
        .name           = "lasi_82596",
        .id_table       = lan_tbl,
        .probe          = lan_init_chip,
+       .remove         = __devexit_p(lan_remove_chip),
 };
 
 static int __devinit lasi_82596_init(void)
 {
-       if (debug >= 0)
-               i596_debug = debug;
+       printk(KERN_INFO LASI_82596_DRIVER_VERSION "\n");
        return register_parisc_driver(&lan_driver);
 }
 
@@ -1576,25 +233,6 @@ module_init(lasi_82596_init);
 
 static void __exit lasi_82596_exit(void)
 {
-       int i;
-
-       for (i=0; i<MAX_DRIVERS; i++) {
-               struct i596_private *lp;
-               struct net_device *netdevice;
-
-               netdevice = netdevs[i];
-               if (!netdevice)
-                       continue;
-
-               unregister_netdev(netdevice);
-
-               lp = netdevice->priv;
-               dma_free_noncoherent(lp->dev, sizeof(struct i596_private),
-                                      (void *)netdevice->mem_start, lp->dma_addr);
-               free_netdev(netdevice);
-       }
-       num_drivers = 0;
-
        unregister_parisc_driver(&lan_driver);
 }
 
diff --git a/drivers/net/lib82596.c b/drivers/net/lib82596.c
new file mode 100644 (file)
index 0000000..5884f5b
--- /dev/null
@@ -0,0 +1,1434 @@
+/* lasi_82596.c -- driver for the intel 82596 ethernet controller, as
+   munged into HPPA boxen .
+
+   This driver is based upon 82596.c, original credits are below...
+   but there were too many hoops which HP wants jumped through to
+   keep this code in there in a sane manner.
+
+   3 primary sources of the mess --
+   1) hppa needs *lots* of cacheline flushing to keep this kind of
+   MMIO running.
+
+   2) The 82596 needs to see all of its pointers as their physical
+   address.  Thus virt_to_bus/bus_to_virt are *everywhere*.
+
+   3) The implementation HP is using seems to be significantly pickier
+   about when and how the command and RX units are started.  some
+   command ordering was changed.
+
+   Examination of the mach driver leads one to believe that there
+   might be a saner way to pull this off...  anyone who feels like a
+   full rewrite can be my guest.
+
+   Split 02/13/2000 Sam Creasey (sammy@oh.verio.com)
+
+   02/01/2000  Initial modifications for parisc by Helge Deller (deller@gmx.de)
+   03/02/2000  changes for better/correct(?) cache-flushing (deller)
+*/
+
+/* 82596.c: A generic 82596 ethernet driver for linux. */
+/*
+   Based on Apricot.c
+   Written 1994 by Mark Evans.
+   This driver is for the Apricot 82596 bus-master interface
+
+   Modularised 12/94 Mark Evans
+
+
+   Modified to support the 82596 ethernet chips on 680x0 VME boards.
+   by Richard Hirst <richard@sleepie.demon.co.uk>
+   Renamed to be 82596.c
+
+   980825:  Changed to receive directly in to sk_buffs which are
+   allocated at open() time.  Eliminates copy on incoming frames
+   (small ones are still copied).  Shared data now held in a
+   non-cached page, so we can run on 68060 in copyback mode.
+
+   TBD:
+   * look at deferring rx frames rather than discarding (as per tulip)
+   * handle tx ring full as per tulip
+   * performace test to tune rx_copybreak
+
+   Most of my modifications relate to the braindead big-endian
+   implementation by Intel.  When the i596 is operating in
+   'big-endian' mode, it thinks a 32 bit value of 0x12345678
+   should be stored as 0x56781234.  This is a real pain, when
+   you have linked lists which are shared by the 680x0 and the
+   i596.
+
+   Driver skeleton
+   Written 1993 by Donald Becker.
+   Copyright 1993 United States Government as represented by the Director,
+   National Security Agency. This software may only be used and distributed
+   according to the terms of the GNU General Public License as modified by SRC,
+   incorporated herein by reference.
+
+   The author may be reached as becker@scyld.com, or C/O
+   Scyld Computing Corporation, 410 Severn Ave., Suite 210, Annapolis MD 21403
+
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/bitops.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+
+/* DEBUG flags
+ */
+
+#define DEB_INIT       0x0001
+#define DEB_PROBE      0x0002
+#define DEB_SERIOUS    0x0004
+#define DEB_ERRORS     0x0008
+#define DEB_MULTI      0x0010
+#define DEB_TDR                0x0020
+#define DEB_OPEN       0x0040
+#define DEB_RESET      0x0080
+#define DEB_ADDCMD     0x0100
+#define DEB_STATUS     0x0200
+#define DEB_STARTTX    0x0400
+#define DEB_RXADDR     0x0800
+#define DEB_TXADDR     0x1000
+#define DEB_RXFRAME    0x2000
+#define DEB_INTS       0x4000
+#define DEB_STRUCT     0x8000
+#define DEB_ANY                0xffff
+
+
+#define DEB(x, y)      if (i596_debug & (x)) { y; }
+
+
+/*
+ * The MPU_PORT command allows direct access to the 82596. With PORT access
+ * the following commands are available (p5-18). The 32-bit port command
+ * must be word-swapped with the most significant word written first.
+ * This only applies to VME boards.
+ */
+#define PORT_RESET             0x00    /* reset 82596 */
+#define PORT_SELFTEST          0x01    /* selftest */
+#define PORT_ALTSCP            0x02    /* alternate SCB address */
+#define PORT_ALTDUMP           0x03    /* Alternate DUMP address */
+
+static int i596_debug = (DEB_SERIOUS|DEB_PROBE);
+
+/* Copy frames shorter than rx_copybreak, otherwise pass on up in
+ * a full sized sk_buff.  Value of 100 stolen from tulip.c (!alpha).
+ */
+static int rx_copybreak = 100;
+
+#define PKT_BUF_SZ     1536
+#define MAX_MC_CNT     64
+
+#define ISCP_BUSY      0x0001
+
+#define I596_NULL ((u32)0xffffffff)
+
+#define CMD_EOL                0x8000  /* The last command of the list, stop. */
+#define CMD_SUSP       0x4000  /* Suspend after doing cmd. */
+#define CMD_INTR       0x2000  /* Interrupt after doing cmd. */
+
+#define CMD_FLEX       0x0008  /* Enable flexible memory model */
+
+enum commands {
+       CmdNOp = 0, CmdSASetup = 1, CmdConfigure = 2, CmdMulticastList = 3,
+       CmdTx = 4, CmdTDR = 5, CmdDump = 6, CmdDiagnose = 7
+};
+
+#define STAT_C         0x8000  /* Set to 0 after execution */
+#define STAT_B         0x4000  /* Command being executed */
+#define STAT_OK                0x2000  /* Command executed ok */
+#define STAT_A         0x1000  /* Command aborted */
+
+#define         CUC_START      0x0100
+#define         CUC_RESUME     0x0200
+#define         CUC_SUSPEND    0x0300
+#define         CUC_ABORT      0x0400
+#define         RX_START       0x0010
+#define         RX_RESUME      0x0020
+#define         RX_SUSPEND     0x0030
+#define         RX_ABORT       0x0040
+
+#define TX_TIMEOUT     5
+
+
+struct i596_reg {
+       unsigned short porthi;
+       unsigned short portlo;
+       u32            ca;
+};
+
+#define EOF            0x8000
+#define SIZE_MASK      0x3fff
+
+struct i596_tbd {
+       unsigned short size;
+       unsigned short pad;
+       dma_addr_t     next;
+       dma_addr_t     data;
+       u32 cache_pad[5];               /* Total 32 bytes... */
+};
+
+/* The command structure has two 'next' pointers; v_next is the address of
+ * the next command as seen by the CPU, b_next is the address of the next
+ * command as seen by the 82596.  The b_next pointer, as used by the 82596
+ * always references the status field of the next command, rather than the
+ * v_next field, because the 82596 is unaware of v_next.  It may seem more
+ * logical to put v_next at the end of the structure, but we cannot do that
+ * because the 82596 expects other fields to be there, depending on command
+ * type.
+ */
+
+struct i596_cmd {
+       struct i596_cmd *v_next;        /* Address from CPUs viewpoint */
+       unsigned short status;
+       unsigned short command;
+       dma_addr_t     b_next;  /* Address from i596 viewpoint */
+};
+
+struct tx_cmd {
+       struct i596_cmd cmd;
+       dma_addr_t     tbd;
+       unsigned short size;
+       unsigned short pad;
+       struct sk_buff *skb;            /* So we can free it after tx */
+       dma_addr_t dma_addr;
+#ifdef __LP64__
+       u32 cache_pad[6];               /* Total 64 bytes... */
+#else
+       u32 cache_pad[1];               /* Total 32 bytes... */
+#endif
+};
+
+struct tdr_cmd {
+       struct i596_cmd cmd;
+       unsigned short status;
+       unsigned short pad;
+};
+
+struct mc_cmd {
+       struct i596_cmd cmd;
+       short mc_cnt;
+       char mc_addrs[MAX_MC_CNT*6];
+};
+
+struct sa_cmd {
+       struct i596_cmd cmd;
+       char eth_addr[8];
+};
+
+struct cf_cmd {
+       struct i596_cmd cmd;
+       char i596_config[16];
+};
+
+struct i596_rfd {
+       unsigned short stat;
+       unsigned short cmd;
+       dma_addr_t     b_next;  /* Address from i596 viewpoint */
+       dma_addr_t     rbd;
+       unsigned short count;
+       unsigned short size;
+       struct i596_rfd *v_next;        /* Address from CPUs viewpoint */
+       struct i596_rfd *v_prev;
+#ifndef __LP64__
+       u32 cache_pad[2];               /* Total 32 bytes... */
+#endif
+};
+
+struct i596_rbd {
+    /* hardware data */
+    unsigned short count;
+    unsigned short zero1;
+    dma_addr_t     b_next;
+    dma_addr_t     b_data;             /* Address from i596 viewpoint */
+    unsigned short size;
+    unsigned short zero2;
+    /* driver data */
+    struct sk_buff *skb;
+    struct i596_rbd *v_next;
+    dma_addr_t     b_addr;             /* This rbd addr from i596 view */
+    unsigned char *v_data;             /* Address from CPUs viewpoint */
+                                       /* Total 32 bytes... */
+#ifdef __LP64__
+    u32 cache_pad[4];
+#endif
+};
+
+/* These values as chosen so struct i596_dma fits in one page... */
+
+#define TX_RING_SIZE 32
+#define RX_RING_SIZE 16
+
+struct i596_scb {
+       unsigned short status;
+       unsigned short command;
+       dma_addr_t    cmd;
+       dma_addr_t    rfd;
+       u32           crc_err;
+       u32           align_err;
+       u32           resource_err;
+       u32           over_err;
+       u32           rcvdt_err;
+       u32           short_err;
+       unsigned short t_on;
+       unsigned short t_off;
+};
+
+struct i596_iscp {
+       u32           stat;
+       dma_addr_t    scb;
+};
+
+struct i596_scp {
+       u32           sysbus;
+       u32           pad;
+       dma_addr_t    iscp;
+};
+
+struct i596_dma {
+       struct i596_scp scp                     __attribute__((aligned(32)));
+       volatile struct i596_iscp iscp          __attribute__((aligned(32)));
+       volatile struct i596_scb scb            __attribute__((aligned(32)));
+       struct sa_cmd sa_cmd                    __attribute__((aligned(32)));
+       struct cf_cmd cf_cmd                    __attribute__((aligned(32)));
+       struct tdr_cmd tdr_cmd                  __attribute__((aligned(32)));
+       struct mc_cmd mc_cmd                    __attribute__((aligned(32)));
+       struct i596_rfd rfds[RX_RING_SIZE]      __attribute__((aligned(32)));
+       struct i596_rbd rbds[RX_RING_SIZE]      __attribute__((aligned(32)));
+       struct tx_cmd tx_cmds[TX_RING_SIZE]     __attribute__((aligned(32)));
+       struct i596_tbd tbds[TX_RING_SIZE]      __attribute__((aligned(32)));
+};
+
+struct i596_private {
+       struct i596_dma *dma;
+       u32    stat;
+       int last_restart;
+       struct i596_rfd *rfd_head;
+       struct i596_rbd *rbd_head;
+       struct i596_cmd *cmd_tail;
+       struct i596_cmd *cmd_head;
+       int cmd_backlog;
+       u32    last_cmd;
+       struct net_device_stats stats;
+       int next_tx_cmd;
+       int options;
+       spinlock_t lock;       /* serialize access to chip */
+       dma_addr_t dma_addr;
+       void __iomem *mpu_port;
+       void __iomem *ca;
+};
+
+static const char init_setup[] =
+{
+       0x8E,           /* length, prefetch on */
+       0xC8,           /* fifo to 8, monitor off */
+       0x80,           /* don't save bad frames */
+       0x2E,           /* No source address insertion, 8 byte preamble */
+       0x00,           /* priority and backoff defaults */
+       0x60,           /* interframe spacing */
+       0x00,           /* slot time LSB */
+       0xf2,           /* slot time and retries */
+       0x00,           /* promiscuous mode */
+       0x00,           /* collision detect */
+       0x40,           /* minimum frame length */
+       0xff,
+       0x00,
+       0x7f /*  *multi IA */ };
+
+static int i596_open(struct net_device *dev);
+static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static irqreturn_t i596_interrupt(int irq, void *dev_id);
+static int i596_close(struct net_device *dev);
+static struct net_device_stats *i596_get_stats(struct net_device *dev);
+static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd);
+static void i596_tx_timeout (struct net_device *dev);
+static void print_eth(unsigned char *buf, char *str);
+static void set_multicast_list(struct net_device *dev);
+static inline void ca(struct net_device *dev);
+static void mpu_port(struct net_device *dev, int c, dma_addr_t x);
+
+static int rx_ring_size = RX_RING_SIZE;
+static int ticks_limit = 100;
+static int max_cmd_backlog = TX_RING_SIZE-1;
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void i596_poll_controller(struct net_device *dev);
+#endif
+
+
+static inline int wait_istat(struct net_device *dev, struct i596_dma *dma, int delcnt, char *str)
+{
+       DMA_INV(dev, &(dma->iscp), sizeof(struct i596_iscp));
+       while (--delcnt && dma->iscp.stat) {
+               udelay(10);
+               DMA_INV(dev, &(dma->iscp), sizeof(struct i596_iscp));
+       }
+       if (!delcnt) {
+               printk(KERN_ERR "%s: %s, iscp.stat %04x, didn't clear\n",
+                    dev->name, str, SWAP16(dma->iscp.stat));
+               return -1;
+       } else
+               return 0;
+}
+
+
+static inline int wait_cmd(struct net_device *dev, struct i596_dma *dma, int delcnt, char *str)
+{
+       DMA_INV(dev, &(dma->scb), sizeof(struct i596_scb));
+       while (--delcnt && dma->scb.command) {
+               udelay(10);
+               DMA_INV(dev, &(dma->scb), sizeof(struct i596_scb));
+       }
+       if (!delcnt) {
+               printk(KERN_ERR "%s: %s, status %4.4x, cmd %4.4x.\n",
+                      dev->name, str,
+                      SWAP16(dma->scb.status),
+                      SWAP16(dma->scb.command));
+               return -1;
+       } else
+               return 0;
+}
+
+
+static void i596_display_data(struct net_device *dev)
+{
+       struct i596_private *lp = netdev_priv(dev);
+       struct i596_dma *dma = lp->dma;
+       struct i596_cmd *cmd;
+       struct i596_rfd *rfd;
+       struct i596_rbd *rbd;
+
+       printk(KERN_DEBUG "lp and scp at %p, .sysbus = %08x, .iscp = %08x\n",
+              &dma->scp, dma->scp.sysbus, SWAP32(dma->scp.iscp));
+       printk(KERN_DEBUG "iscp at %p, iscp.stat = %08x, .scb = %08x\n",
+              &dma->iscp, SWAP32(dma->iscp.stat), SWAP32(dma->iscp.scb));
+       printk(KERN_DEBUG "scb at %p, scb.status = %04x, .command = %04x,"
+               " .cmd = %08x, .rfd = %08x\n",
+              &dma->scb, SWAP16(dma->scb.status), SWAP16(dma->scb.command),
+               SWAP16(dma->scb.cmd), SWAP32(dma->scb.rfd));
+       printk(KERN_DEBUG "   errors: crc %x, align %x, resource %x,"
+              " over %x, rcvdt %x, short %x\n",
+              SWAP32(dma->scb.crc_err), SWAP32(dma->scb.align_err),
+              SWAP32(dma->scb.resource_err), SWAP32(dma->scb.over_err),
+              SWAP32(dma->scb.rcvdt_err), SWAP32(dma->scb.short_err));
+       cmd = lp->cmd_head;
+       while (cmd != NULL) {
+               printk(KERN_DEBUG
+                      "cmd at %p, .status = %04x, .command = %04x,"
+                      " .b_next = %08x\n",
+                      cmd, SWAP16(cmd->status), SWAP16(cmd->command),
+                      SWAP32(cmd->b_next));
+               cmd = cmd->v_next;
+       }
+       rfd = lp->rfd_head;
+       printk(KERN_DEBUG "rfd_head = %p\n", rfd);
+       do {
+               printk(KERN_DEBUG
+                      "   %p .stat %04x, .cmd %04x, b_next %08x, rbd %08x,"
+                      " count %04x\n",
+                      rfd, SWAP16(rfd->stat), SWAP16(rfd->cmd),
+                      SWAP32(rfd->b_next), SWAP32(rfd->rbd),
+                      SWAP16(rfd->count));
+               rfd = rfd->v_next;
+       } while (rfd != lp->rfd_head);
+       rbd = lp->rbd_head;
+       printk(KERN_DEBUG "rbd_head = %p\n", rbd);
+       do {
+               printk(KERN_DEBUG
+                      "   %p .count %04x, b_next %08x, b_data %08x,"
+                      " size %04x\n",
+                       rbd, SWAP16(rbd->count), SWAP32(rbd->b_next),
+                      SWAP32(rbd->b_data), SWAP16(rbd->size));
+               rbd = rbd->v_next;
+       } while (rbd != lp->rbd_head);
+       DMA_INV(dev, dma, sizeof(struct i596_dma));
+}
+
+
+#define virt_to_dma(lp, v) ((lp)->dma_addr + (dma_addr_t)((unsigned long)(v)-(unsigned long)((lp)->dma)))
+
+static inline int init_rx_bufs(struct net_device *dev)
+{
+       struct i596_private *lp = netdev_priv(dev);
+       struct i596_dma *dma = lp->dma;
+       int i;
+       struct i596_rfd *rfd;
+       struct i596_rbd *rbd;
+
+       /* First build the Receive Buffer Descriptor List */
+
+       for (i = 0, rbd = dma->rbds; i < rx_ring_size; i++, rbd++) {
+               dma_addr_t dma_addr;
+               struct sk_buff *skb = netdev_alloc_skb(dev, PKT_BUF_SZ + 4);
+
+               if (skb == NULL)
+                       return -1;
+               skb_reserve(skb, 2);
+               dma_addr = dma_map_single(dev->dev.parent, skb->data,
+                                         PKT_BUF_SZ, DMA_FROM_DEVICE);
+               rbd->v_next = rbd+1;
+               rbd->b_next = SWAP32(virt_to_dma(lp, rbd+1));
+               rbd->b_addr = SWAP32(virt_to_dma(lp, rbd));
+               rbd->skb = skb;
+               rbd->v_data = skb->data;
+               rbd->b_data = SWAP32(dma_addr);
+               rbd->size = SWAP16(PKT_BUF_SZ);
+       }
+       lp->rbd_head = dma->rbds;
+       rbd = dma->rbds + rx_ring_size - 1;
+       rbd->v_next = dma->rbds;
+       rbd->b_next = SWAP32(virt_to_dma(lp, dma->rbds));
+
+       /* Now build the Receive Frame Descriptor List */
+
+       for (i = 0, rfd = dma->rfds; i < rx_ring_size; i++, rfd++) {
+               rfd->rbd = I596_NULL;
+               rfd->v_next = rfd+1;
+               rfd->v_prev = rfd-1;
+               rfd->b_next = SWAP32(virt_to_dma(lp, rfd+1));
+               rfd->cmd = SWAP16(CMD_FLEX);
+       }
+       lp->rfd_head = dma->rfds;
+       dma->scb.rfd = SWAP32(virt_to_dma(lp, dma->rfds));
+       rfd = dma->rfds;
+       rfd->rbd = SWAP32(virt_to_dma(lp, lp->rbd_head));
+       rfd->v_prev = dma->rfds + rx_ring_size - 1;
+       rfd = dma->rfds + rx_ring_size - 1;
+       rfd->v_next = dma->rfds;
+       rfd->b_next = SWAP32(virt_to_dma(lp, dma->rfds));
+       rfd->cmd = SWAP16(CMD_EOL|CMD_FLEX);
+
+       DMA_WBACK_INV(dev, dma, sizeof(struct i596_dma));
+       return 0;
+}
+
+static inline void remove_rx_bufs(struct net_device *dev)
+{
+       struct i596_private *lp = netdev_priv(dev);
+       struct i596_rbd *rbd;
+       int i;
+
+       for (i = 0, rbd = lp->dma->rbds; i < rx_ring_size; i++, rbd++) {
+               if (rbd->skb == NULL)
+                       break;
+               dma_unmap_single(dev->dev.parent,
+                                (dma_addr_t)SWAP32(rbd->b_data),
+                                PKT_BUF_SZ, DMA_FROM_DEVICE);
+               dev_kfree_skb(rbd->skb);
+       }
+}
+
+
+static void rebuild_rx_bufs(struct net_device *dev)
+{
+       struct i596_private *lp = netdev_priv(dev);
+       struct i596_dma *dma = lp->dma;
+       int i;
+
+       /* Ensure rx frame/buffer descriptors are tidy */
+
+       for (i = 0; i < rx_ring_size; i++) {
+               dma->rfds[i].rbd = I596_NULL;
+               dma->rfds[i].cmd = SWAP16(CMD_FLEX);
+       }
+       dma->rfds[rx_ring_size-1].cmd = SWAP16(CMD_EOL|CMD_FLEX);
+       lp->rfd_head = dma->rfds;
+       dma->scb.rfd = SWAP32(virt_to_dma(lp, dma->rfds));
+       lp->rbd_head = dma->rbds;
+       dma->rfds[0].rbd = SWAP32(virt_to_dma(lp, dma->rbds));
+
+       DMA_WBACK_INV(dev, dma, sizeof(struct i596_dma));
+}
+
+
+static int init_i596_mem(struct net_device *dev)
+{
+       struct i596_private *lp = netdev_priv(dev);
+       struct i596_dma *dma = lp->dma;
+       unsigned long flags;
+
+       mpu_port(dev, PORT_RESET, 0);
+       udelay(100);                    /* Wait 100us - seems to help */
+
+       /* change the scp address */
+
+       lp->last_cmd = jiffies;
+
+       dma->scp.sysbus = SYSBUS;
+       dma->scp.iscp = SWAP32(virt_to_dma(lp, &(dma->iscp)));
+       dma->iscp.scb = SWAP32(virt_to_dma(lp, &(dma->scb)));
+       dma->iscp.stat = SWAP32(ISCP_BUSY);
+       lp->cmd_backlog = 0;
+
+       lp->cmd_head = NULL;
+       dma->scb.cmd = I596_NULL;
+
+       DEB(DEB_INIT, printk(KERN_DEBUG "%s: starting i82596.\n", dev->name));
+
+       DMA_WBACK(dev, &(dma->scp), sizeof(struct i596_scp));
+       DMA_WBACK(dev, &(dma->iscp), sizeof(struct i596_iscp));
+       DMA_WBACK(dev, &(dma->scb), sizeof(struct i596_scb));
+
+       mpu_port(dev, PORT_ALTSCP, virt_to_dma(lp, &dma->scp));
+       ca(dev);
+       if (wait_istat(dev, dma, 1000, "initialization timed out"))
+               goto failed;
+       DEB(DEB_INIT, printk(KERN_DEBUG
+                            "%s: i82596 initialization successful\n",
+                            dev->name));
+
+       if (request_irq(dev->irq, &i596_interrupt, 0, "i82596", dev)) {
+               printk(KERN_ERR "%s: IRQ %d not free\n", dev->name, dev->irq);
+               goto failed;
+       }
+
+       /* Ensure rx frame/buffer descriptors are tidy */
+       rebuild_rx_bufs(dev);
+
+       dma->scb.command = 0;
+       DMA_WBACK(dev, &(dma->scb), sizeof(struct i596_scb));
+
+       DEB(DEB_INIT, printk(KERN_DEBUG
+                            "%s: queuing CmdConfigure\n", dev->name));
+       memcpy(dma->cf_cmd.i596_config, init_setup, 14);
+       dma->cf_cmd.cmd.command = SWAP16(CmdConfigure);
+       DMA_WBACK(dev, &(dma->cf_cmd), sizeof(struct cf_cmd));
+       i596_add_cmd(dev, &dma->cf_cmd.cmd);
+
+       DEB(DEB_INIT, printk(KERN_DEBUG "%s: queuing CmdSASetup\n", dev->name));
+       memcpy(dma->sa_cmd.eth_addr, dev->dev_addr, 6);
+       dma->sa_cmd.cmd.command = SWAP16(CmdSASetup);
+       DMA_WBACK(dev, &(dma->sa_cmd), sizeof(struct sa_cmd));
+       i596_add_cmd(dev, &dma->sa_cmd.cmd);
+
+       DEB(DEB_INIT, printk(KERN_DEBUG "%s: queuing CmdTDR\n", dev->name));
+       dma->tdr_cmd.cmd.command = SWAP16(CmdTDR);
+       DMA_WBACK(dev, &(dma->tdr_cmd), sizeof(struct tdr_cmd));
+       i596_add_cmd(dev, &dma->tdr_cmd.cmd);
+
+       spin_lock_irqsave (&lp->lock, flags);
+
+       if (wait_cmd(dev, dma, 1000, "timed out waiting to issue RX_START")) {
+               spin_unlock_irqrestore (&lp->lock, flags);
+               goto failed_free_irq;
+       }
+       DEB(DEB_INIT, printk(KERN_DEBUG "%s: Issuing RX_START\n", dev->name));
+       dma->scb.command = SWAP16(RX_START);
+       dma->scb.rfd = SWAP32(virt_to_dma(lp, dma->rfds));
+       DMA_WBACK(dev, &(dma->scb), sizeof(struct i596_scb));
+
+       ca(dev);
+
+       spin_unlock_irqrestore (&lp->lock, flags);
+       if (wait_cmd(dev, dma, 1000, "RX_START not processed"))
+               goto failed_free_irq;
+       DEB(DEB_INIT, printk(KERN_DEBUG
+                            "%s: Receive unit started OK\n", dev->name));
+       return 0;
+
+failed_free_irq:
+       free_irq(dev->irq, dev);
+failed:
+       printk(KERN_ERR "%s: Failed to initialise 82596\n", dev->name);
+       mpu_port(dev, PORT_RESET, 0);
+       return -1;
+}
+
+
+static inline int i596_rx(struct net_device *dev)
+{
+       struct i596_private *lp = netdev_priv(dev);
+       struct i596_rfd *rfd;
+       struct i596_rbd *rbd;
+       int frames = 0;
+
+       DEB(DEB_RXFRAME, printk(KERN_DEBUG
+                               "i596_rx(), rfd_head %p, rbd_head %p\n",
+                               lp->rfd_head, lp->rbd_head));
+
+
+       rfd = lp->rfd_head;             /* Ref next frame to check */
+
+       DMA_INV(dev, rfd, sizeof(struct i596_rfd));
+       while (rfd->stat & SWAP16(STAT_C)) {    /* Loop while complete frames */
+               if (rfd->rbd == I596_NULL)
+                       rbd = NULL;
+               else if (rfd->rbd == lp->rbd_head->b_addr) {
+                       rbd = lp->rbd_head;
+                       DMA_INV(dev, rbd, sizeof(struct i596_rbd));
+               } else {
+                       printk(KERN_ERR "%s: rbd chain broken!\n", dev->name);
+                       /* XXX Now what? */
+                       rbd = NULL;
+               }
+               DEB(DEB_RXFRAME, printk(KERN_DEBUG
+                                     "  rfd %p, rfd.rbd %08x, rfd.stat %04x\n",
+                                     rfd, rfd->rbd, rfd->stat));
+
+               if (rbd != NULL && (rfd->stat & SWAP16(STAT_OK))) {
+                       /* a good frame */
+                       int pkt_len = SWAP16(rbd->count) & 0x3fff;
+                       struct sk_buff *skb = rbd->skb;
+                       int rx_in_place = 0;
+
+                       DEB(DEB_RXADDR, print_eth(rbd->v_data, "received"));
+                       frames++;
+
+                       /* Check if the packet is long enough to just accept
+                        * without copying to a properly sized skbuff.
+                        */
+
+                       if (pkt_len > rx_copybreak) {
+                               struct sk_buff *newskb;
+                               dma_addr_t dma_addr;
+
+                               dma_unmap_single(dev->dev.parent,
+                                                (dma_addr_t)SWAP32(rbd->b_data),
+                                                PKT_BUF_SZ, DMA_FROM_DEVICE);
+                               /* Get fresh skbuff to replace filled one. */
+                               newskb = netdev_alloc_skb(dev, PKT_BUF_SZ + 4);
+                               if (newskb == NULL) {
+                                       skb = NULL;     /* drop pkt */
+                                       goto memory_squeeze;
+                               }
+                               skb_reserve(newskb, 2);
+
+                               /* Pass up the skb already on the Rx ring. */
+                               skb_put(skb, pkt_len);
+                               rx_in_place = 1;
+                               rbd->skb = newskb;
+                               dma_addr = dma_map_single(dev->dev.parent,
+                                                         newskb->data,
+                                                         PKT_BUF_SZ,
+                                                         DMA_FROM_DEVICE);
+                               rbd->v_data = newskb->data;
+                               rbd->b_data = SWAP32(dma_addr);
+                               DMA_WBACK_INV(dev, rbd, sizeof(struct i596_rbd));
+                       } else
+                               skb = netdev_alloc_skb(dev, pkt_len + 2);
+memory_squeeze:
+                       if (skb == NULL) {
+                               /* XXX tulip.c can defer packets here!! */
+                               printk(KERN_ERR
+                                      "%s: i596_rx Memory squeeze, dropping packet.\n",
+                                      dev->name);
+                               lp->stats.rx_dropped++;
+                       } else {
+                               if (!rx_in_place) {
+                                       /* 16 byte align the data fields */
+                                       dma_sync_single_for_cpu(dev->dev.parent,
+                                                               (dma_addr_t)SWAP32(rbd->b_data),
+                                                               PKT_BUF_SZ, DMA_FROM_DEVICE);
+                                       skb_reserve(skb, 2);
+                                       memcpy(skb_put(skb, pkt_len), rbd->v_data, pkt_len);
+                                       dma_sync_single_for_device(dev->dev.parent,
+                                                                  (dma_addr_t)SWAP32(rbd->b_data),
+                                                                  PKT_BUF_SZ, DMA_FROM_DEVICE);
+                               }
+                               skb->len = pkt_len;
+                               skb->protocol = eth_type_trans(skb, dev);
+                               netif_rx(skb);
+                               dev->last_rx = jiffies;
+                               lp->stats.rx_packets++;
+                               lp->stats.rx_bytes += pkt_len;
+                       }
+               } else {
+                       DEB(DEB_ERRORS, printk(KERN_DEBUG
+                                              "%s: Error, rfd.stat = 0x%04x\n",
+                                              dev->name, rfd->stat));
+                       lp->stats.rx_errors++;
+                       if (rfd->stat & SWAP16(0x0100))
+                               lp->stats.collisions++;
+                       if (rfd->stat & SWAP16(0x8000))
+                               lp->stats.rx_length_errors++;
+                       if (rfd->stat & SWAP16(0x0001))
+                               lp->stats.rx_over_errors++;
+                       if (rfd->stat & SWAP16(0x0002))
+                               lp->stats.rx_fifo_errors++;
+                       if (rfd->stat & SWAP16(0x0004))
+                               lp->stats.rx_frame_errors++;
+                       if (rfd->stat & SWAP16(0x0008))
+                               lp->stats.rx_crc_errors++;
+                       if (rfd->stat & SWAP16(0x0010))
+                               lp->stats.rx_length_errors++;
+               }
+
+               /* Clear the buffer descriptor count and EOF + F flags */
+
+               if (rbd != NULL && (rbd->count & SWAP16(0x4000))) {
+                       rbd->count = 0;
+                       lp->rbd_head = rbd->v_next;
+                       DMA_WBACK_INV(dev, rbd, sizeof(struct i596_rbd));
+               }
+
+               /* Tidy the frame descriptor, marking it as end of list */
+
+               rfd->rbd = I596_NULL;
+               rfd->stat = 0;
+               rfd->cmd = SWAP16(CMD_EOL|CMD_FLEX);
+               rfd->count = 0;
+
+               /* Update record of next frame descriptor to process */
+
+               lp->dma->scb.rfd = rfd->b_next;
+               lp->rfd_head = rfd->v_next;
+               DMA_WBACK_INV(dev, rfd, sizeof(struct i596_rfd));
+
+               /* Remove end-of-list from old end descriptor */
+
+               rfd->v_prev->cmd = SWAP16(CMD_FLEX);
+               DMA_WBACK_INV(dev, rfd->v_prev, sizeof(struct i596_rfd));
+               rfd = lp->rfd_head;
+               DMA_INV(dev, rfd, sizeof(struct i596_rfd));
+       }
+
+       DEB(DEB_RXFRAME, printk(KERN_DEBUG "frames %d\n", frames));
+
+       return 0;
+}
+
+
+static inline void i596_cleanup_cmd(struct net_device *dev, struct i596_private *lp)
+{
+       struct i596_cmd *ptr;
+
+       while (lp->cmd_head != NULL) {
+               ptr = lp->cmd_head;
+               lp->cmd_head = ptr->v_next;
+               lp->cmd_backlog--;
+
+               switch (SWAP16(ptr->command) & 0x7) {
+               case CmdTx:
+                       {
+                               struct tx_cmd *tx_cmd = (struct tx_cmd *) ptr;
+                               struct sk_buff *skb = tx_cmd->skb;
+                               dma_unmap_single(dev->dev.parent,
+                                                tx_cmd->dma_addr,
+                                                skb->len, DMA_TO_DEVICE);
+
+                               dev_kfree_skb(skb);
+
+                               lp->stats.tx_errors++;
+                               lp->stats.tx_aborted_errors++;
+
+                               ptr->v_next = NULL;
+                               ptr->b_next = I596_NULL;
+                               tx_cmd->cmd.command = 0;  /* Mark as free */
+                               break;
+                       }
+               default:
+                       ptr->v_next = NULL;
+                       ptr->b_next = I596_NULL;
+               }
+               DMA_WBACK_INV(dev, ptr, sizeof(struct i596_cmd));
+       }
+
+       wait_cmd(dev, lp->dma, 100, "i596_cleanup_cmd timed out");
+       lp->dma->scb.cmd = I596_NULL;
+       DMA_WBACK(dev, &(lp->dma->scb), sizeof(struct i596_scb));
+}
+
+
+static inline void i596_reset(struct net_device *dev, struct i596_private *lp)
+{
+       unsigned long flags;
+
+       DEB(DEB_RESET, printk(KERN_DEBUG "i596_reset\n"));
+
+       spin_lock_irqsave (&lp->lock, flags);
+
+       wait_cmd(dev, lp->dma, 100, "i596_reset timed out");
+
+       netif_stop_queue(dev);
+
+       /* FIXME: this command might cause an lpmc */
+       lp->dma->scb.command = SWAP16(CUC_ABORT | RX_ABORT);
+       DMA_WBACK(dev, &(lp->dma->scb), sizeof(struct i596_scb));
+       ca(dev);
+
+       /* wait for shutdown */
+       wait_cmd(dev, lp->dma, 1000, "i596_reset 2 timed out");
+       spin_unlock_irqrestore (&lp->lock, flags);
+
+       i596_cleanup_cmd(dev, lp);
+       i596_rx(dev);
+
+       netif_start_queue(dev);
+       init_i596_mem(dev);
+}
+
+
+static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd)
+{
+       struct i596_private *lp = netdev_priv(dev);
+       struct i596_dma *dma = lp->dma;
+       unsigned long flags;
+
+       DEB(DEB_ADDCMD, printk(KERN_DEBUG "i596_add_cmd cmd_head %p\n",
+                              lp->cmd_head));
+
+       cmd->status = 0;
+       cmd->command |= SWAP16(CMD_EOL | CMD_INTR);
+       cmd->v_next = NULL;
+       cmd->b_next = I596_NULL;
+       DMA_WBACK(dev, cmd, sizeof(struct i596_cmd));
+
+       spin_lock_irqsave (&lp->lock, flags);
+
+       if (lp->cmd_head != NULL) {
+               lp->cmd_tail->v_next = cmd;
+               lp->cmd_tail->b_next = SWAP32(virt_to_dma(lp, &cmd->status));
+               DMA_WBACK(dev, lp->cmd_tail, sizeof(struct i596_cmd));
+       } else {
+               lp->cmd_head = cmd;
+               wait_cmd(dev, dma, 100, "i596_add_cmd timed out");
+               dma->scb.cmd = SWAP32(virt_to_dma(lp, &cmd->status));
+               dma->scb.command = SWAP16(CUC_START);
+               DMA_WBACK(dev, &(dma->scb), sizeof(struct i596_scb));
+               ca(dev);
+       }
+       lp->cmd_tail = cmd;
+       lp->cmd_backlog++;
+
+       spin_unlock_irqrestore (&lp->lock, flags);
+
+       if (lp->cmd_backlog > max_cmd_backlog) {
+               unsigned long tickssofar = jiffies - lp->last_cmd;
+
+               if (tickssofar < ticks_limit)
+                       return;
+
+               printk(KERN_ERR
+                      "%s: command unit timed out, status resetting.\n",
+                      dev->name);
+#if 1
+               i596_reset(dev, lp);
+#endif
+       }
+}
+
+static int i596_open(struct net_device *dev)
+{
+       DEB(DEB_OPEN, printk(KERN_DEBUG
+                            "%s: i596_open() irq %d.\n", dev->name, dev->irq));
+
+       if (init_rx_bufs(dev)) {
+               printk(KERN_ERR "%s: Failed to init rx bufs\n", dev->name);
+               return -EAGAIN;
+       }
+       if (init_i596_mem(dev)) {
+               printk(KERN_ERR "%s: Failed to init memory\n", dev->name);
+               goto out_remove_rx_bufs;
+       }
+       netif_start_queue(dev);
+
+       return 0;
+
+out_remove_rx_bufs:
+       remove_rx_bufs(dev);
+       return -EAGAIN;
+}
+
+static void i596_tx_timeout (struct net_device *dev)
+{
+       struct i596_private *lp = netdev_priv(dev);
+
+       /* Transmitter timeout, serious problems. */
+       DEB(DEB_ERRORS, printk(KERN_DEBUG
+                              "%s: transmit timed out, status resetting.\n",
+                              dev->name));
+
+       lp->stats.tx_errors++;
+
+       /* Try to restart the adaptor */
+       if (lp->last_restart == lp->stats.tx_packets) {
+               DEB(DEB_ERRORS, printk(KERN_DEBUG "Resetting board.\n"));
+               /* Shutdown and restart */
+               i596_reset (dev, lp);
+       } else {
+               /* Issue a channel attention signal */
+               DEB(DEB_ERRORS, printk(KERN_DEBUG "Kicking board.\n"));
+               lp->dma->scb.command = SWAP16(CUC_START | RX_START);
+               DMA_WBACK_INV(dev, &(lp->dma->scb), sizeof(struct i596_scb));
+               ca (dev);
+               lp->last_restart = lp->stats.tx_packets;
+       }
+
+       dev->trans_start = jiffies;
+       netif_wake_queue (dev);
+}
+
+
+static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+       struct i596_private *lp = netdev_priv(dev);
+       struct tx_cmd *tx_cmd;
+       struct i596_tbd *tbd;
+       short length = skb->len;
+       dev->trans_start = jiffies;
+
+       DEB(DEB_STARTTX, printk(KERN_DEBUG
+                               "%s: i596_start_xmit(%x,%p) called\n",
+                               dev->name, skb->len, skb->data));
+
+       if (length < ETH_ZLEN) {
+               if (skb_padto(skb, ETH_ZLEN))
+                       return 0;
+               length = ETH_ZLEN;
+       }
+
+       netif_stop_queue(dev);
+
+       tx_cmd = lp->dma->tx_cmds + lp->next_tx_cmd;
+       tbd = lp->dma->tbds + lp->next_tx_cmd;
+
+       if (tx_cmd->cmd.command) {
+               DEB(DEB_ERRORS, printk(KERN_DEBUG
+                                      "%s: xmit ring full, dropping packet.\n",
+                                      dev->name));
+               lp->stats.tx_dropped++;
+
+               dev_kfree_skb(skb);
+       } else {
+               if (++lp->next_tx_cmd == TX_RING_SIZE)
+                       lp->next_tx_cmd = 0;
+               tx_cmd->tbd = SWAP32(virt_to_dma(lp, tbd));
+               tbd->next = I596_NULL;
+
+               tx_cmd->cmd.command = SWAP16(CMD_FLEX | CmdTx);
+               tx_cmd->skb = skb;
+
+               tx_cmd->pad = 0;
+               tx_cmd->size = 0;
+               tbd->pad = 0;
+               tbd->size = SWAP16(EOF | length);
+
+               tx_cmd->dma_addr = dma_map_single(dev->dev.parent, skb->data,
+                                                 skb->len, DMA_TO_DEVICE);
+               tbd->data = SWAP32(tx_cmd->dma_addr);
+
+               DEB(DEB_TXADDR, print_eth(skb->data, "tx-queued"));
+               DMA_WBACK_INV(dev, tx_cmd, sizeof(struct tx_cmd));
+               DMA_WBACK_INV(dev, tbd, sizeof(struct i596_tbd));
+               i596_add_cmd(dev, &tx_cmd->cmd);
+
+               lp->stats.tx_packets++;
+               lp->stats.tx_bytes += length;
+       }
+
+       netif_start_queue(dev);
+
+       return 0;
+}
+
+static void print_eth(unsigned char *add, char *str)
+{
+       int i;
+
+       printk(KERN_DEBUG "i596 0x%p, ", add);
+       for (i = 0; i < 6; i++)
+               printk(" %02X", add[i + 6]);
+       printk(" -->");
+       for (i = 0; i < 6; i++)
+               printk(" %02X", add[i]);
+       printk(" %02X%02X, %s\n", add[12], add[13], str);
+}
+
+static int __devinit i82596_probe(struct net_device *dev)
+{
+       int i;
+       struct i596_private *lp = netdev_priv(dev);
+       struct i596_dma *dma;
+
+       /* This lot is ensure things have been cache line aligned. */
+       BUILD_BUG_ON(sizeof(struct i596_rfd) != 32);
+       BUILD_BUG_ON(sizeof(struct i596_rbd) &  31);
+       BUILD_BUG_ON(sizeof(struct tx_cmd)   &  31);
+       BUILD_BUG_ON(sizeof(struct i596_tbd) != 32);
+#ifndef __LP64__
+       BUILD_BUG_ON(sizeof(struct i596_dma) > 4096);
+#endif
+
+       if (!dev->base_addr || !dev->irq)
+               return -ENODEV;
+
+       dma = (struct i596_dma *) DMA_ALLOC(dev->dev.parent,
+               sizeof(struct i596_dma), &lp->dma_addr, GFP_KERNEL);
+       if (!dma) {
+               printk(KERN_ERR "%s: Couldn't get shared memory\n", __FILE__);
+               return -ENOMEM;
+       }
+
+       /* The 82596-specific entries in the device structure. */
+       dev->open = i596_open;
+       dev->stop = i596_close;
+       dev->hard_start_xmit = i596_start_xmit;
+       dev->get_stats = i596_get_stats;
+       dev->set_multicast_list = set_multicast_list;
+       dev->tx_timeout = i596_tx_timeout;
+       dev->watchdog_timeo = TX_TIMEOUT;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       dev->poll_controller = i596_poll_controller;
+#endif
+
+       memset(dma, 0, sizeof(struct i596_dma));
+       lp->dma = dma;
+
+       dma->scb.command = 0;
+       dma->scb.cmd = I596_NULL;
+       dma->scb.rfd = I596_NULL;
+       spin_lock_init(&lp->lock);
+
+       DMA_WBACK_INV(dev, dma, sizeof(struct i596_dma));
+
+       i = register_netdev(dev);
+       if (i) {
+               DMA_FREE(dev->dev.parent, sizeof(struct i596_dma),
+                                   (void *)dma, lp->dma_addr);
+               return i;
+       };
+
+       DEB(DEB_PROBE, printk(KERN_INFO "%s: 82596 at %#3lx,",
+                             dev->name, dev->base_addr));
+       for (i = 0; i < 6; i++)
+               DEB(DEB_PROBE, printk(" %2.2X", dev->dev_addr[i]));
+       DEB(DEB_PROBE, printk(" IRQ %d.\n", dev->irq));
+       DEB(DEB_INIT, printk(KERN_INFO
+                            "%s: dma at 0x%p (%d bytes), lp->scb at 0x%p\n",
+                            dev->name, dma, (int)sizeof(struct i596_dma),
+                            &dma->scb));
+
+       return 0;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void i596_poll_controller(struct net_device *dev)
+{
+       disable_irq(dev->irq);
+       i596_interrupt(dev->irq, dev);
+       enable_irq(dev->irq);
+}
+#endif
+
+static irqreturn_t i596_interrupt(int irq, void *dev_id)
+{
+       struct net_device *dev = dev_id;
+       struct i596_private *lp;
+       struct i596_dma *dma;
+       unsigned short status, ack_cmd = 0;
+
+       if (dev == NULL) {
+               printk(KERN_WARNING "%s: irq %d for unknown device.\n",
+                      __FUNCTION__, irq);
+               return IRQ_NONE;
+       }
+
+       lp = netdev_priv(dev);
+       dma = lp->dma;
+
+       spin_lock (&lp->lock);
+
+       wait_cmd(dev, dma, 100, "i596 interrupt, timeout");
+       status = SWAP16(dma->scb.status);
+
+       DEB(DEB_INTS, printk(KERN_DEBUG
+                            "%s: i596 interrupt, IRQ %d, status %4.4x.\n",
+                       dev->name, irq, status));
+
+       ack_cmd = status & 0xf000;
+
+       if (!ack_cmd) {
+               DEB(DEB_ERRORS, printk(KERN_DEBUG
+                                      "%s: interrupt with no events\n",
+                                      dev->name));
+               spin_unlock (&lp->lock);
+               return IRQ_NONE;
+       }
+
+       if ((status & 0x8000) || (status & 0x2000)) {
+               struct i596_cmd *ptr;
+
+               if ((status & 0x8000))
+                       DEB(DEB_INTS,
+                           printk(KERN_DEBUG
+                                  "%s: i596 interrupt completed command.\n",
+                                  dev->name));
+               if ((status & 0x2000))
+                       DEB(DEB_INTS,
+                           printk(KERN_DEBUG
+                                  "%s: i596 interrupt command unit inactive %x.\n",
+                                  dev->name, status & 0x0700));
+
+               while (lp->cmd_head != NULL) {
+                       DMA_INV(dev, lp->cmd_head, sizeof(struct i596_cmd));
+                       if (!(lp->cmd_head->status & SWAP16(STAT_C)))
+                               break;
+
+                       ptr = lp->cmd_head;
+
+                       DEB(DEB_STATUS,
+                           printk(KERN_DEBUG
+                                  "cmd_head->status = %04x, ->command = %04x\n",
+                                  SWAP16(lp->cmd_head->status),
+                                  SWAP16(lp->cmd_head->command)));
+                       lp->cmd_head = ptr->v_next;
+                       lp->cmd_backlog--;
+
+                       switch (SWAP16(ptr->command) & 0x7) {
+                       case CmdTx:
+                           {
+                               struct tx_cmd *tx_cmd = (struct tx_cmd *) ptr;
+                               struct sk_buff *skb = tx_cmd->skb;
+
+                               if (ptr->status & SWAP16(STAT_OK)) {
+                                       DEB(DEB_TXADDR,
+                                           print_eth(skb->data, "tx-done"));
+                               } else {
+                                       lp->stats.tx_errors++;
+                                       if (ptr->status & SWAP16(0x0020))
+                                               lp->stats.collisions++;
+                                       if (!(ptr->status & SWAP16(0x0040)))
+                                               lp->stats.tx_heartbeat_errors++;
+                                       if (ptr->status & SWAP16(0x0400))
+                                               lp->stats.tx_carrier_errors++;
+                                       if (ptr->status & SWAP16(0x0800))
+                                               lp->stats.collisions++;
+                                       if (ptr->status & SWAP16(0x1000))
+                                               lp->stats.tx_aborted_errors++;
+                               }
+                               dma_unmap_single(dev->dev.parent,
+                                                tx_cmd->dma_addr,
+                                                skb->len, DMA_TO_DEVICE);
+                               dev_kfree_skb_irq(skb);
+
+                               tx_cmd->cmd.command = 0; /* Mark free */
+                               break;
+                           }
+                       case CmdTDR:
+                           {
+                               unsigned short status = SWAP16(((struct tdr_cmd *)ptr)->status);
+
+                               if (status & 0x8000) {
+                                       DEB(DEB_ANY,
+                                           printk(KERN_DEBUG "%s: link ok.\n",
+                                                  dev->name));
+                               } else {
+                                       if (status & 0x4000)
+                                               printk(KERN_ERR
+                                                      "%s: Transceiver problem.\n",
+                                                      dev->name);
+                                       if (status & 0x2000)
+                                               printk(KERN_ERR
+                                                      "%s: Termination problem.\n",
+                                                      dev->name);
+                                       if (status & 0x1000)
+                                               printk(KERN_ERR
+                                                      "%s: Short circuit.\n",
+                                                      dev->name);
+
+                                       DEB(DEB_TDR,
+                                           printk(KERN_DEBUG "%s: Time %d.\n",
+                                                  dev->name, status & 0x07ff));
+                               }
+                               break;
+                           }
+                       case CmdConfigure:
+                               /*
+                                * Zap command so set_multicast_list() know
+                                * it is free
+                                */
+                               ptr->command = 0;
+                               break;
+                       }
+                       ptr->v_next = NULL;
+                       ptr->b_next = I596_NULL;
+                       DMA_WBACK(dev, ptr, sizeof(struct i596_cmd));
+                       lp->last_cmd = jiffies;
+               }
+
+               /* This mess is arranging that only the last of any outstanding
+                * commands has the interrupt bit set.  Should probably really
+                * only add to the cmd queue when the CU is stopped.
+                */
+               ptr = lp->cmd_head;
+               while ((ptr != NULL) && (ptr != lp->cmd_tail)) {
+                       struct i596_cmd *prev = ptr;
+
+                       ptr->command &= SWAP16(0x1fff);
+                       ptr = ptr->v_next;
+                       DMA_WBACK_INV(dev, prev, sizeof(struct i596_cmd));
+               }
+
+               if (lp->cmd_head != NULL)
+                       ack_cmd |= CUC_START;
+               dma->scb.cmd = SWAP32(virt_to_dma(lp, &lp->cmd_head->status));
+               DMA_WBACK_INV(dev, &dma->scb, sizeof(struct i596_scb));
+       }
+       if ((status & 0x1000) || (status & 0x4000)) {
+               if ((status & 0x4000))
+                       DEB(DEB_INTS,
+                           printk(KERN_DEBUG
+                                  "%s: i596 interrupt received a frame.\n",
+                                  dev->name));
+               i596_rx(dev);
+               /* Only RX_START if stopped - RGH 07-07-96 */
+               if (status & 0x1000) {
+                       if (netif_running(dev)) {
+                               DEB(DEB_ERRORS,
+                                   printk(KERN_DEBUG
+                                          "%s: i596 interrupt receive unit inactive, status 0x%x\n",
+                                          dev->name, status));
+                               ack_cmd |= RX_START;
+                               lp->stats.rx_errors++;
+                               lp->stats.rx_fifo_errors++;
+                               rebuild_rx_bufs(dev);
+                       }
+               }
+       }
+       wait_cmd(dev, dma, 100, "i596 interrupt, timeout");
+       dma->scb.command = SWAP16(ack_cmd);
+       DMA_WBACK(dev, &dma->scb, sizeof(struct i596_scb));
+
+       /* DANGER: I suspect that some kind of interrupt
+        acknowledgement aside from acking the 82596 might be needed
+        here...  but it's running acceptably without */
+
+       ca(dev);
+
+       wait_cmd(dev, dma, 100, "i596 interrupt, exit timeout");
+       DEB(DEB_INTS, printk(KERN_DEBUG "%s: exiting interrupt.\n", dev->name));
+
+       spin_unlock (&lp->lock);
+       return IRQ_HANDLED;
+}
+
+static int i596_close(struct net_device *dev)
+{
+       struct i596_private *lp = netdev_priv(dev);
+       unsigned long flags;
+
+       netif_stop_queue(dev);
+
+       DEB(DEB_INIT,
+           printk(KERN_DEBUG
+                  "%s: Shutting down ethercard, status was %4.4x.\n",
+                  dev->name, SWAP16(lp->dma->scb.status)));
+
+       spin_lock_irqsave(&lp->lock, flags);
+
+       wait_cmd(dev, lp->dma, 100, "close1 timed out");
+       lp->dma->scb.command = SWAP16(CUC_ABORT | RX_ABORT);
+       DMA_WBACK(dev, &lp->dma->scb, sizeof(struct i596_scb));
+
+       ca(dev);
+
+       wait_cmd(dev, lp->dma, 100, "close2 timed out");
+       spin_unlock_irqrestore(&lp->lock, flags);
+       DEB(DEB_STRUCT, i596_display_data(dev));
+       i596_cleanup_cmd(dev, lp);
+
+       free_irq(dev->irq, dev);
+       remove_rx_bufs(dev);
+
+       return 0;
+}
+
+static struct net_device_stats *i596_get_stats(struct net_device *dev)
+{
+       struct i596_private *lp = netdev_priv(dev);
+
+       return &lp->stats;
+}
+
+/*
+ *    Set or clear the multicast filter for this adaptor.
+ */
+
+static void set_multicast_list(struct net_device *dev)
+{
+       struct i596_private *lp = netdev_priv(dev);
+       struct i596_dma *dma = lp->dma;
+       int config = 0, cnt;
+
+       DEB(DEB_MULTI,
+           printk(KERN_DEBUG
+                  "%s: set multicast list, %d entries, promisc %s, allmulti %s\n",
+                  dev->name, dev->mc_count,
+                  dev->flags & IFF_PROMISC ? "ON" : "OFF",
+                  dev->flags & IFF_ALLMULTI ? "ON" : "OFF"));
+
+       if ((dev->flags & IFF_PROMISC) &&
+           !(dma->cf_cmd.i596_config[8] & 0x01)) {
+               dma->cf_cmd.i596_config[8] |= 0x01;
+               config = 1;
+       }
+       if (!(dev->flags & IFF_PROMISC) &&
+           (dma->cf_cmd.i596_config[8] & 0x01)) {
+               dma->cf_cmd.i596_config[8] &= ~0x01;
+               config = 1;
+       }
+       if ((dev->flags & IFF_ALLMULTI) &&
+           (dma->cf_cmd.i596_config[11] & 0x20)) {
+               dma->cf_cmd.i596_config[11] &= ~0x20;
+               config = 1;
+       }
+       if (!(dev->flags & IFF_ALLMULTI) &&
+           !(dma->cf_cmd.i596_config[11] & 0x20)) {
+               dma->cf_cmd.i596_config[11] |= 0x20;
+               config = 1;
+       }
+       if (config) {
+               if (dma->cf_cmd.cmd.command)
+                       printk(KERN_INFO
+                              "%s: config change request already queued\n",
+                              dev->name);
+               else {
+                       dma->cf_cmd.cmd.command = SWAP16(CmdConfigure);
+                       DMA_WBACK_INV(dev, &dma->cf_cmd, sizeof(struct cf_cmd));
+                       i596_add_cmd(dev, &dma->cf_cmd.cmd);
+               }
+       }
+
+       cnt = dev->mc_count;
+       if (cnt > MAX_MC_CNT) {
+               cnt = MAX_MC_CNT;
+               printk(KERN_NOTICE "%s: Only %d multicast addresses supported",
+                       dev->name, cnt);
+       }
+
+       if (dev->mc_count > 0) {
+               struct dev_mc_list *dmi;
+               unsigned char *cp;
+               struct mc_cmd *cmd;
+
+               cmd = &dma->mc_cmd;
+               cmd->cmd.command = SWAP16(CmdMulticastList);
+               cmd->mc_cnt = SWAP16(dev->mc_count * 6);
+               cp = cmd->mc_addrs;
+               for (dmi = dev->mc_list;
+                    cnt && dmi != NULL;
+                    dmi = dmi->next, cnt--, cp += 6) {
+                       memcpy(cp, dmi->dmi_addr, 6);
+                       if (i596_debug > 1)
+                               DEB(DEB_MULTI,
+                                   printk(KERN_DEBUG
+                                          "%s: Adding address %02x:%02x:%02x:%02x:%02x:%02x\n",
+                                          dev->name, cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]));
+               }
+               DMA_WBACK_INV(dev, &dma->mc_cmd, sizeof(struct mc_cmd));
+               i596_add_cmd(dev, &cmd->cmd);
+       }
+}
index fef3193121f907b7d41a44bb931a8bbd1e9c6641..9a343b965975eb469a133cdbd133c1faee74831c 100644 (file)
@@ -577,7 +577,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id)
        struct mace_data *mp = netdev_priv(dev);
        volatile struct mace *mb = mp->mace;
        int intr, fs;
-       unsigned int flags;
+       unsigned long flags;
 
        /* don't want the dma interrupt handler to fire */
        local_irq_save(flags);
index d2b065351e4511fda36c5e4bd101c15e2fd647b6..c45cbe43a0c483830891e109beb306d11dc51d2a 100644 (file)
@@ -138,6 +138,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
 #define QUERY_DEV_CAP_ACK_DELAY_OFFSET         0x35
 #define QUERY_DEV_CAP_MTU_WIDTH_OFFSET         0x36
 #define QUERY_DEV_CAP_VL_PORT_OFFSET           0x37
+#define QUERY_DEV_CAP_MAX_MSG_SZ_OFFSET                0x38
 #define QUERY_DEV_CAP_MAX_GID_OFFSET           0x3b
 #define QUERY_DEV_CAP_RATE_SUPPORT_OFFSET      0x3c
 #define QUERY_DEV_CAP_MAX_PKEY_OFFSET          0x3f
@@ -220,6 +221,8 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
        dev_cap->local_ca_ack_delay = field & 0x1f;
        MLX4_GET(field, outbox, QUERY_DEV_CAP_VL_PORT_OFFSET);
        dev_cap->num_ports = field & 0xf;
+       MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_MSG_SZ_OFFSET);
+       dev_cap->max_msg_sz = 1 << (field & 0x1f);
        MLX4_GET(stat_rate, outbox, QUERY_DEV_CAP_RATE_SUPPORT_OFFSET);
        dev_cap->stat_rate_support = stat_rate;
        MLX4_GET(dev_cap->flags, outbox, QUERY_DEV_CAP_FLAGS_OFFSET);
index 296254ac27c14b0a5fbfa0f3789e149e91336e80..7e1dd9e25cfbabb9fa995d51c2c1fbf149518de6 100644 (file)
@@ -60,6 +60,7 @@ struct mlx4_dev_cap {
        int max_rdma_global;
        int local_ca_ack_delay;
        int num_ports;
+       u32 max_msg_sz;
        int max_mtu[MLX4_MAX_PORTS + 1];
        int max_port_width[MLX4_MAX_PORTS + 1];
        int max_vl[MLX4_MAX_PORTS + 1];
index c3da2a2f543127c7b89a34af0b1279923b4a3496..a4f2e0475a719e249358a54f5cd2c892ad5c12e0 100644 (file)
@@ -154,6 +154,7 @@ static int __devinit mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev
        dev->caps.reserved_uars      = dev_cap->reserved_uars;
        dev->caps.reserved_pds       = dev_cap->reserved_pds;
        dev->caps.mtt_entry_sz       = MLX4_MTT_ENTRY_PER_SEG * dev_cap->mtt_entry_sz;
+       dev->caps.max_msg_sz         = dev_cap->max_msg_sz;
        dev->caps.page_size_cap      = ~(u32) (dev_cap->min_page_sz - 1);
        dev->caps.flags              = dev_cap->flags;
        dev->caps.stat_rate_support  = dev_cap->stat_rate_support;
index 3d3b6d24d8d3689a3116501c0baf100a8c182720..d9c91a71fc873b71ba85bd8b242df9e830eb3972 100644 (file)
@@ -37,6 +37,7 @@
 #ifndef MLX4_H
 #define MLX4_H
 
+#include <linux/mutex.h>
 #include <linux/radix-tree.h>
 
 #include <linux/mlx4/device.h>
index 7f8b7d55b6e110ba5dbc49d0917e9e3fbb592ad4..19b48c71cf7f2e315eb31ba8a47af6b824c2d181 100644 (file)
@@ -113,8 +113,7 @@ int mlx4_qp_modify(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
        struct mlx4_cmd_mailbox *mailbox;
        int ret = 0;
 
-       if (cur_state < 0 || cur_state >= MLX4_QP_NUM_STATE ||
-           new_state < 0 || cur_state >= MLX4_QP_NUM_STATE ||
+       if (cur_state >= MLX4_QP_NUM_STATE || cur_state >= MLX4_QP_NUM_STATE ||
            !op[cur_state][new_state])
                return -EINVAL;
 
@@ -278,3 +277,24 @@ void mlx4_cleanup_qp_table(struct mlx4_dev *dev)
        mlx4_CONF_SPECIAL_QP(dev, 0);
        mlx4_bitmap_cleanup(&mlx4_priv(dev)->qp_table.bitmap);
 }
+
+int mlx4_qp_query(struct mlx4_dev *dev, struct mlx4_qp *qp,
+                 struct mlx4_qp_context *context)
+{
+       struct mlx4_cmd_mailbox *mailbox;
+       int err;
+
+       mailbox = mlx4_alloc_cmd_mailbox(dev);
+       if (IS_ERR(mailbox))
+               return PTR_ERR(mailbox);
+
+       err = mlx4_cmd_box(dev, 0, mailbox->dma, qp->qpn, 0,
+                          MLX4_CMD_QUERY_QP, MLX4_CMD_TIME_CLASS_A);
+       if (!err)
+               memcpy(context, mailbox->buf + 8, sizeof *context);
+
+       mlx4_free_cmd_mailbox(dev, mailbox);
+       return err;
+}
+EXPORT_SYMBOL_GPL(mlx4_qp_query);
+
index 2134f83aed8769fd9398e7365271e9e397e926ab..b061c86d6839aa3bd72aa0a7828f98c477b4bec9 100644 (file)
@@ -102,6 +102,13 @@ static int mlx4_ARM_SRQ(struct mlx4_dev *dev, int srq_num, int limit_watermark)
                        MLX4_CMD_TIME_CLASS_B);
 }
 
+static int mlx4_QUERY_SRQ(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox,
+                         int srq_num)
+{
+       return mlx4_cmd_box(dev, 0, mailbox->dma, srq_num, 0, MLX4_CMD_QUERY_SRQ,
+                           MLX4_CMD_TIME_CLASS_A);
+}
+
 int mlx4_srq_alloc(struct mlx4_dev *dev, u32 pdn, struct mlx4_mtt *mtt,
                   u64 db_rec, struct mlx4_srq *srq)
 {
@@ -205,6 +212,29 @@ int mlx4_srq_arm(struct mlx4_dev *dev, struct mlx4_srq *srq, int limit_watermark
 }
 EXPORT_SYMBOL_GPL(mlx4_srq_arm);
 
+int mlx4_srq_query(struct mlx4_dev *dev, struct mlx4_srq *srq, int *limit_watermark)
+{
+       struct mlx4_cmd_mailbox *mailbox;
+       struct mlx4_srq_context *srq_context;
+       int err;
+
+       mailbox = mlx4_alloc_cmd_mailbox(dev);
+       if (IS_ERR(mailbox))
+               return PTR_ERR(mailbox);
+
+       srq_context = mailbox->buf;
+
+       err = mlx4_QUERY_SRQ(dev, mailbox, srq->srqn);
+       if (err)
+               goto err_out;
+       *limit_watermark = srq_context->limit_watermark;
+
+err_out:
+       mlx4_free_cmd_mailbox(dev, mailbox);
+       return err;
+}
+EXPORT_SYMBOL_GPL(mlx4_srq_query);
+
 int __devinit mlx4_init_srq_table(struct mlx4_dev *dev)
 {
        struct mlx4_srq_table *srq_table = &mlx4_priv(dev)->srq_table;
index d0cc122fa3f0f0710eb610f7d23cbdbd7527469a..e1732c164a4092e925bcf4235b540c60e7ecb92e 100644 (file)
@@ -60,6 +60,7 @@
 #include <linux/crc32.h>
 #include <linux/moduleparam.h>
 #include <linux/io.h>
+#include <linux/log2.h>
 #include <net/checksum.h>
 #include <asm/byteorder.h>
 #include <asm/io.h>
@@ -1804,7 +1805,7 @@ static int myri10ge_open(struct net_device *dev)
         */
        big_pow2 = dev->mtu + ETH_HLEN + VLAN_HLEN + MXGEFW_PAD;
        if (big_pow2 < MYRI10GE_ALLOC_SIZE / 2) {
-               while ((big_pow2 & (big_pow2 - 1)) != 0)
+               while (!is_power_of_2(big_pow2))
                        big_pow2++;
                mgp->big_bytes = dev->mtu + ETH_HLEN + VLAN_HLEN + MXGEFW_PAD;
        } else {
index 460a08718c69f8c740fcb5716720ea44219b14f6..3450051ae56b635c260f56d159314466eb0e5a0a 100644 (file)
@@ -2357,8 +2357,8 @@ static void netdev_rx(struct net_device *dev, int *work_done, int work_to_do)
                                        np->rx_dma[entry],
                                        buflen,
                                        PCI_DMA_FROMDEVICE);
-                               eth_copy_and_sum(skb,
-                                       np->rx_skbuff[entry]->data, pkt_len, 0);
+                               skb_copy_to_linear_data(skb,
+                                       np->rx_skbuff[entry]->data, pkt_len);
                                skb_put(skb, pkt_len);
                                pci_dma_sync_single_for_device(np->pci_dev,
                                        np->rx_dma[entry],
index 619503742b7dd3c2f013757c28b92ef8d6880fa1..325269d8ae388fa4744276288b7ba0dc5f897450 100644 (file)
@@ -1097,109 +1097,6 @@ 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);
 
-static inline void netxen_nic_disable_int(struct netxen_adapter *adapter)
-{
-       uint32_t        mask = 0x7ff;
-       int retries = 32;
-
-       DPRINTK(1, INFO, "Entered ISR Disable \n");
-
-       switch (adapter->portnum) {
-       case 0:
-               writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0));
-               break;
-       case 1:
-               writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1));
-               break;
-       case 2:
-               writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2));
-               break;
-       case 3:
-               writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3));
-               break;
-       }
-
-       if (adapter->intr_scheme != -1 &&
-               adapter->intr_scheme != INTR_SCHEME_PERPORT) {
-               writel(mask,
-                       (void *)(PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK)));
-       }
-
-       /* Window = 0 or 1 */
-       if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
-               do {
-                       writel(0xffffffff, (void *)
-                               (PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_STATUS)));
-                       mask = readl((void *)
-                                       (pci_base_offset(adapter, ISR_INT_VECTOR)));
-                       if (!(mask & 0x80))
-                               break;
-                       udelay(10);
-               } while (--retries);
-
-               if (!retries) {
-                       printk(KERN_NOTICE "%s: Failed to disable interrupt completely\n",
-                                       netxen_nic_driver_name);
-               }
-       }
-
-       DPRINTK(1, INFO, "Done with Disable Int\n");
-
-       return;
-}
-
-static inline void netxen_nic_enable_int(struct netxen_adapter *adapter)
-{
-       u32 mask;
-
-       DPRINTK(1, INFO, "Entered ISR Enable \n");
-
-       if (adapter->intr_scheme != -1 &&
-               adapter->intr_scheme != INTR_SCHEME_PERPORT) {
-               switch (adapter->ahw.board_type) {
-               case NETXEN_NIC_GBE:
-                       mask  =  0x77b;
-                       break;
-               case NETXEN_NIC_XGBE:
-                       mask  =  0x77f;
-                       break;
-               default:
-                       mask  =  0x7ff;
-                       break;
-               }
-
-               writel(mask,
-                       (void *)(PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK)));
-       }
-       switch (adapter->portnum) {
-       case 0:
-               writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0));
-               break;
-       case 1:
-               writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1));
-               break;
-       case 2:
-               writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2));
-               break;
-       case 3:
-               writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3));
-               break;
-       }
-
-       if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
-               mask = 0xbff;
-               if (adapter->intr_scheme != -1 &&
-                       adapter->intr_scheme != INTR_SCHEME_PERPORT) {
-                       writel(0X0, NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR));
-               }
-               writel(mask,
-                       (void *)(PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_MASK)));
-       }
-
-       DPRINTK(1, INFO, "Done with enable Int\n");
-
-       return;
-}
 
 /*
  * NetXen Board information
index a66ff58366cfcdae2be977efd7041eaf859e2be9..b703ccfe040b41319e429d6780cf78cb72f9f3d5 100644 (file)
@@ -54,8 +54,6 @@ static char netxen_nic_driver_string[] = "NetXen Network Driver version "
 #define NETXEN_ADAPTER_UP_MAGIC 777
 #define NETXEN_NIC_PEG_TUNE 0
 
-u8 nx_p2_id = NX_P2_C0;
-
 #define DMA_32BIT_MASK 0x00000000ffffffffULL
 #define DMA_35BIT_MASK 0x00000007ffffffffULL
 
@@ -156,6 +154,103 @@ static inline void netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter
 #define        ADAPTER_LIST_SIZE 12
 int netxen_cards_found;
 
+static void netxen_nic_disable_int(struct netxen_adapter *adapter)
+{
+       uint32_t        mask = 0x7ff;
+       int retries = 32;
+
+       DPRINTK(1, INFO, "Entered ISR Disable \n");
+
+       switch (adapter->portnum) {
+       case 0:
+               writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0));
+               break;
+       case 1:
+               writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1));
+               break;
+       case 2:
+               writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2));
+               break;
+       case 3:
+               writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3));
+               break;
+       }
+
+       if (adapter->intr_scheme != -1 &&
+           adapter->intr_scheme != INTR_SCHEME_PERPORT)
+               writel(mask,PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK));
+
+       /* Window = 0 or 1 */
+       if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
+               do {
+                       writel(0xffffffff,
+                              PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_STATUS));
+                       mask = readl(pci_base_offset(adapter, ISR_INT_VECTOR));
+                       if (!(mask & 0x80))
+                               break;
+                       udelay(10);
+               } while (--retries);
+
+               if (!retries) {
+                       printk(KERN_NOTICE "%s: Failed to disable interrupt completely\n",
+                                       netxen_nic_driver_name);
+               }
+       }
+
+       DPRINTK(1, INFO, "Done with Disable Int\n");
+}
+
+static void netxen_nic_enable_int(struct netxen_adapter *adapter)
+{
+       u32 mask;
+
+       DPRINTK(1, INFO, "Entered ISR Enable \n");
+
+       if (adapter->intr_scheme != -1 &&
+               adapter->intr_scheme != INTR_SCHEME_PERPORT) {
+               switch (adapter->ahw.board_type) {
+               case NETXEN_NIC_GBE:
+                       mask  =  0x77b;
+                       break;
+               case NETXEN_NIC_XGBE:
+                       mask  =  0x77f;
+                       break;
+               default:
+                       mask  =  0x7ff;
+                       break;
+               }
+
+               writel(mask, PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK));
+       }
+
+       switch (adapter->portnum) {
+       case 0:
+               writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0));
+               break;
+       case 1:
+               writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1));
+               break;
+       case 2:
+               writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2));
+               break;
+       case 3:
+               writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3));
+               break;
+       }
+
+       if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
+               mask = 0xbff;
+               if (adapter->intr_scheme != -1 &&
+                       adapter->intr_scheme != INTR_SCHEME_PERPORT) {
+                       writel(0X0, NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR));
+               }
+               writel(mask,
+                      PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_MASK));
+       }
+
+       DPRINTK(1, INFO, "Done with enable Int\n");
+}
+
 /*
  * netxen_nic_probe()
  *
@@ -210,8 +305,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                goto err_out_disable_pdev;
 
        pci_set_master(pdev);
-       pci_read_config_byte(pdev, PCI_REVISION_ID, &nx_p2_id);
-       if (nx_p2_id == NX_P2_C1 &&
+       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;
@@ -455,7 +549,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task);
        adapter->ahw.pdev = pdev;
        adapter->proc_cmd_buf_counter = 0;
-       adapter->ahw.revision_id = nx_p2_id;
+       adapter->ahw.revision_id = pdev->revision;
 
        /* make sure Window == 1 */
        netxen_nic_pci_change_crbwindow(adapter, 1);
index 75102d30730f0cdecf3942485211cfbcfe5eb59f..05e0577a0e103b55a2c8431595ebc2cb679a4675 100644 (file)
@@ -724,7 +724,7 @@ int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter)
        __u32 mac_cfg0;
        u32 port = physical_port[adapter->portnum];
 
-       if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
+       if (port > NETXEN_NIU_MAX_GBE_PORTS)
                return -EINVAL;
        mac_cfg0 = 0;
        netxen_gb_soft_reset(mac_cfg0);
@@ -757,7 +757,7 @@ int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter,
        __u32 reg;
        u32 port = physical_port[adapter->portnum];
 
-       if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
+       if (port > NETXEN_NIU_MAX_GBE_PORTS)
                return -EINVAL;
 
        /* save previous contents */
@@ -894,7 +894,7 @@ int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
        __u32 reg;
        u32 port = physical_port[adapter->portnum];
 
-       if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS))
+       if (port > NETXEN_NIU_MAX_XG_PORTS)
                return -EINVAL;
 
        if (netxen_nic_hw_read_wx(adapter,
index 8dbd6d1900b583e10c0bab764ee9651e5c2ee265..5e7999db2096a69cd0e67bdaae38de4a72868889 100644 (file)
@@ -936,7 +936,7 @@ static void ni52_rcv_int(struct net_device *dev)
                                        {
                                                skb_reserve(skb,2);
                                                skb_put(skb,totlen);
-                                               eth_copy_and_sum(skb,(char *) p->base+(unsigned long) rbd->buffer,totlen,0);
+                                               skb_copy_to_linear_data(skb,(char *) p->base+(unsigned long) rbd->buffer,totlen);
                                                skb->protocol=eth_type_trans(skb,dev);
                                                netif_rx(skb);
                                                dev->last_rx = jiffies;
index 3818edf0ac18c8ad443d712ebc31c3b2404df1fd..4ef5fe345191fa6122499aae9242702fe8a7ca77 100644 (file)
@@ -1096,7 +1096,7 @@ static void ni65_recv_intr(struct net_device *dev,int csr0)
 #ifdef RCV_VIA_SKB
                                if( (unsigned long) (skb->data + R_BUF_SIZE) > 0x1000000) {
                                        skb_put(skb,len);
-                                       eth_copy_and_sum(skb, (unsigned char *)(p->recv_skb[p->rmdnum]->data),len,0);
+                                       skb_copy_to_linear_data(skb, (unsigned char *)(p->recv_skb[p->rmdnum]->data),len);
                                }
                                else {
                                        struct sk_buff *skb1 = p->recv_skb[p->rmdnum];
@@ -1108,7 +1108,7 @@ static void ni65_recv_intr(struct net_device *dev,int csr0)
                                }
 #else
                                skb_put(skb,len);
-                               eth_copy_and_sum(skb, (unsigned char *) p->recvbounce[p->rmdnum],len,0);
+                               skb_copy_to_linear_data(skb, (unsigned char *) p->recvbounce[p->rmdnum],len);
 #endif
                                p->stats.rx_packets++;
                                p->stats.rx_bytes += len;
index 8d38425e46c3cba389aaee76bada0765be257c3e..0b3066a6fe405217250c2a97e67fdbadc926cbdc 100644 (file)
@@ -755,7 +755,7 @@ static int pasemi_mac_open(struct net_device *dev)
        flags |= PAS_MAC_CFG_PCFG_TSR_1G | PAS_MAC_CFG_PCFG_SPD_1G;
 
        pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_RXCH_CFG(mac->dma_rxch),
-                              PAS_IOB_DMA_RXCH_CFG_CNTTH(1));
+                              PAS_IOB_DMA_RXCH_CFG_CNTTH(0));
 
        pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_TXCH_CFG(mac->dma_txch),
                               PAS_IOB_DMA_TXCH_CFG_CNTTH(32));
index df8998b4f37ee5819b07af0a60a8f45e017d5b80..3cdbe118200be40ffcc4d4c5527467fcc4bfac84 100644 (file)
@@ -1567,7 +1567,7 @@ static void netdrv_rx_interrupt (struct net_device *dev,
                if (skb) {
                        skb_reserve (skb, 2);   /* 16 byte align the IP fields. */
 
-                       eth_copy_and_sum (skb, &rx_ring[ring_offset + 4], pkt_size, 0);
+                       skb_copy_to_linear_data (skb, &rx_ring[ring_offset + 4], pkt_size);
                        skb_put (skb, pkt_size);
 
                        skb->protocol = eth_type_trans (skb, dev);
index 808fae1577e0d8feea3be1ab3e263e599c870ed9..50dff1b81d3408b5724f297083c7284488453fb8 100644 (file)
@@ -521,6 +521,7 @@ static void mdio_write(kio_addr_t addr, int phy_id, int loc, int value)
 
 static int axnet_open(struct net_device *dev)
 {
+    int ret;
     axnet_dev_t *info = PRIV(dev);
     struct pcmcia_device *link = info->p_dev;
     
@@ -529,9 +530,11 @@ static int axnet_open(struct net_device *dev)
     if (!pcmcia_dev_present(link))
        return -ENODEV;
 
-    link->open++;
+    ret = request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, "axnet_cs", dev);
+    if (ret)
+           return ret;
 
-    request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, "axnet_cs", dev);
+    link->open++;
 
     info->link_status = 0x00;
     init_timer(&info->watchdog);
index 3f93d4933235cba3f39c0776760e4077d63a53df..85d5f2ca4bb55d6e14e0e2ffc0684975d7b0e500 100644 (file)
@@ -109,7 +109,7 @@ static const struct ethtool_ops netdev_ethtool_ops;
     card type
  */
 typedef enum { MBH10302, MBH10304, TDK, CONTEC, LA501, UNGERMANN, 
-              XXX10304
+              XXX10304, NEC, KME
 } cardtype_t;
 
 /*
@@ -374,6 +374,18 @@ static int fmvj18x_config(struct pcmcia_device *link)
                link->io.NumPorts2 = 8;
            }
            break;
+       case MANFID_NEC:
+           cardtype = NEC; /* MultiFunction Card */
+           link->conf.ConfigBase = 0x800;
+           link->conf.ConfigIndex = 0x47;
+           link->io.NumPorts2 = 8;
+           break;
+       case MANFID_KME:
+           cardtype = KME; /* MultiFunction Card */
+           link->conf.ConfigBase = 0x800;
+           link->conf.ConfigIndex = 0x47;
+           link->io.NumPorts2 = 8;
+           break;
        case MANFID_CONTEC:
            cardtype = CONTEC;
            break;
@@ -450,6 +462,8 @@ static int fmvj18x_config(struct pcmcia_device *link)
     case TDK:
     case LA501:
     case CONTEC:
+    case NEC:
+    case KME:
        tuple.DesiredTuple = CISTPL_FUNCE;
        tuple.TupleOffset = 0;
        CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
@@ -469,6 +483,10 @@ static int fmvj18x_config(struct pcmcia_device *link)
                card_name = "TDK LAK-CD021";
            } else if( cardtype == LA501 ) {
                card_name = "LA501";
+           } else if( cardtype == NEC ) {
+               card_name = "PK-UG-J001";
+           } else if( cardtype == KME ) {
+               card_name = "Panasonic";
            } else {
                card_name = "C-NET(PC)C";
            }
@@ -678,8 +696,11 @@ static struct pcmcia_device_id fmvj18x_ids[] = {
        PCMCIA_DEVICE_PROD_ID1("PCMCIA MBH10302", 0x8f4005da),
        PCMCIA_DEVICE_PROD_ID1("UBKK,V2.0", 0x90888080),
        PCMCIA_PFC_DEVICE_PROD_ID12(0, "TDK", "GlobalNetworker 3410/3412", 0x1eae9475, 0xd9a93bed),
+       PCMCIA_PFC_DEVICE_PROD_ID12(0, "NEC", "PK-UG-J001" ,0x18df0ba0 ,0x831b1064),
        PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0105, 0x0d0a),
        PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0105, 0x0e0a),
+       PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0032, 0x0a05),
+       PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0032, 0x1101),
        PCMCIA_DEVICE_NULL,
 };
 MODULE_DEVICE_TABLE(pcmcia, fmvj18x_ids);
index d88e9b2e93cf919a66edff259be28b5e2214c402..63de89e93b70cc5235cd11fe33fb32d024973722 100644 (file)
@@ -960,6 +960,7 @@ static void mii_phy_probe(struct net_device *dev)
 
 static int pcnet_open(struct net_device *dev)
 {
+    int ret;
     pcnet_dev_t *info = PRIV(dev);
     struct pcmcia_device *link = info->p_dev;
 
@@ -968,10 +969,12 @@ static int pcnet_open(struct net_device *dev)
     if (!pcmcia_dev_present(link))
        return -ENODEV;
 
-    link->open++;
-
     set_misc_reg(dev);
-    request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, dev_info, dev);
+    ret = request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, dev_info, dev);
+    if (ret)
+           return ret;
+
+    link->open++;
 
     info->phy_id = info->eth_phy;
     info->link_status = 0x00;
@@ -1552,6 +1555,7 @@ static struct pcmcia_device_id pcnet_ids[] = {
        PCMCIA_PFC_DEVICE_PROD_ID12(0, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae),
        PCMCIA_PFC_DEVICE_PROD_ID12(0, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033),
        PCMCIA_PFC_DEVICE_PROD_ID12(0, "LINKSYS", "PCMLM336", 0xf7cb0b07, 0x7a821b58),
+       PCMCIA_PFC_DEVICE_PROD_ID12(0, "MICRO RESEARCH", "COMBO-L/M-336", 0xb2ced065, 0x3ced0555),
        PCMCIA_PFC_DEVICE_PROD_ID12(0, "PCMCIAs", "ComboCard", 0xdcfe12d3, 0xcd8906cc),
        PCMCIA_PFC_DEVICE_PROD_ID12(0, "PCMCIAs", "LanModem", 0xdcfe12d3, 0xc67c648f),
        PCMCIA_MFC_DEVICE_PROD_ID12(0, "IBM", "Home and Away 28.8 PC Card       ", 0xb569a6e5, 0x5bd4ff2c),
@@ -1577,6 +1581,7 @@ static struct pcmcia_device_id pcnet_ids[] = {
        PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1103),
        PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1121),
        PCMCIA_DEVICE_PROD_ID12("2408LAN", "Ethernet", 0x352fff7f, 0x00b2e941),
+       PCMCIA_DEVICE_PROD_ID1234("Socket", "CF 10/100 Ethernet Card", "Revision B", "05/11/06", 0xb38bcc2e, 0x4de88352, 0xeaca6c8d, 0x7e57c22e),
        PCMCIA_DEVICE_PROD_ID123("Cardwell", "PCMCIA", "ETHERNET", 0x9533672e, 0x281f1c5d, 0x3ff7175b),
        PCMCIA_DEVICE_PROD_ID123("CNet  ", "CN30BC", "ETHERNET", 0x9fe55d3d, 0x85601198, 0x3ff7175b),
        PCMCIA_DEVICE_PROD_ID123("Digital", "Ethernet", "Adapter", 0x9999ab35, 0x00b2e941, 0x4b0d829e),
index 9c171a7390e2b4ab09e5a77f3fee8c19732e05d3..465485a3fbc642529c0c84a60c92ddd10b102b2e 100644 (file)
@@ -1235,9 +1235,9 @@ static void pcnet32_rx_entry(struct net_device *dev,
                                            lp->rx_dma_addr[entry],
                                            pkt_len,
                                            PCI_DMA_FROMDEVICE);
-               eth_copy_and_sum(skb,
+               skb_copy_to_linear_data(skb,
                                 (unsigned char *)(lp->rx_skbuff[entry]->data),
-                                pkt_len, 0);
+                                pkt_len);
                pci_dma_sync_single_for_device(lp->pci_dev,
                                               lp->rx_dma_addr[entry],
                                               pkt_len,
index 09b6f259eb9225efbedec3d12523f48736c13a79..dd09011c7ee5d9656aec4891860c3ee3a6537b74 100644 (file)
@@ -55,6 +55,11 @@ config BROADCOM_PHY
        ---help---
          Currently supports the BCM5411, BCM5421 and BCM5461 PHYs.
 
+config ICPLUS_PHY
+       tristate "Drivers for ICPlus PHYs"
+       ---help---
+         Currently supports the IP175C PHY.
+
 config FIXED_PHY
        tristate "Drivers for PHY emulation on fixed speed/link"
        ---help---
index bcd1efbd2a181a9799e25047bd97df578f7afbec..8885650647ffa8e8a6b80db85815a6272eadad4f 100644 (file)
@@ -11,4 +11,5 @@ obj-$(CONFIG_QSEMI_PHY)               += qsemi.o
 obj-$(CONFIG_SMSC_PHY)         += smsc.o
 obj-$(CONFIG_VITESSE_PHY)      += vitesse.o
 obj-$(CONFIG_BROADCOM_PHY)     += broadcom.o
+obj-$(CONFIG_ICPLUS_PHY)       += icplus.o
 obj-$(CONFIG_FIXED_PHY)                += fixed.o
diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c
new file mode 100644 (file)
index 0000000..af3f1f2
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Driver for ICPlus PHYs
+ *
+ * Copyright (c) 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 as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/unistd.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/phy.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+
+MODULE_DESCRIPTION("ICPlus IP175C PHY driver");
+MODULE_AUTHOR("Michael Barkowski");
+MODULE_LICENSE("GPL");
+
+static int ip175c_config_init(struct phy_device *phydev)
+{
+       int err, i;
+       static int full_reset_performed = 0;
+
+       if (full_reset_performed == 0) {
+
+               /* master reset */
+               err = phydev->bus->write(phydev->bus, 30, 0, 0x175c);
+               if (err < 0)
+                       return err;
+
+               /* ensure no bus delays overlap reset period */
+               err = phydev->bus->read(phydev->bus, 30, 0);
+
+               /* data sheet specifies reset period is 2 msec */
+               mdelay(2);
+
+               /* enable IP175C mode */
+               err = phydev->bus->write(phydev->bus, 29, 31, 0x175c);
+               if (err < 0)
+                       return err;
+
+               /* Set MII0 speed and duplex (in PHY mode) */
+               err = phydev->bus->write(phydev->bus, 29, 22, 0x420);
+               if (err < 0)
+                       return err;
+
+               /* reset switch ports */
+               for (i = 0; i < 5; i++) {
+                       err = phydev->bus->write(phydev->bus, i,
+                                                MII_BMCR, BMCR_RESET);
+                       if (err < 0)
+                               return err;
+               }
+
+               for (i = 0; i < 5; i++)
+                       err = phydev->bus->read(phydev->bus, i, MII_BMCR);
+
+               mdelay(2);
+
+               full_reset_performed = 1;
+       }
+
+       if (phydev->addr != 4) {
+               phydev->state = PHY_RUNNING;
+               phydev->speed = SPEED_100;
+               phydev->duplex = DUPLEX_FULL;
+               phydev->link = 1;
+               netif_carrier_on(phydev->attached_dev);
+       }
+
+       return 0;
+}
+
+static int ip175c_read_status(struct phy_device *phydev)
+{
+       if (phydev->addr == 4) /* WAN port */
+               genphy_read_status(phydev);
+       else
+               /* Don't need to read status for switch ports */
+               phydev->irq = PHY_IGNORE_INTERRUPT;
+
+       return 0;
+}
+
+static int ip175c_config_aneg(struct phy_device *phydev)
+{
+       if (phydev->addr == 4) /* WAN port */
+               genphy_config_aneg(phydev);
+
+       return 0;
+}
+
+static struct phy_driver ip175c_driver = {
+       .phy_id         = 0x02430d80,
+       .name           = "ICPlus IP175C",
+       .phy_id_mask    = 0x0ffffff0,
+       .features       = PHY_BASIC_FEATURES,
+       .config_init    = &ip175c_config_init,
+       .config_aneg    = &ip175c_config_aneg,
+       .read_status    = &ip175c_read_status,
+       .driver         = { .owner = THIS_MODULE,},
+};
+
+static int __init ip175c_init(void)
+{
+       return phy_driver_register(&ip175c_driver);
+}
+
+static void __exit ip175c_exit(void)
+{
+       phy_driver_unregister(&ip175c_driver);
+}
+
+module_init(ip175c_init);
+module_exit(ip175c_exit);
index b87f8d2a888bb409af90e36a99662c2310ad54d3..d2ede5ff9fffc5e70136207738c7fada30ca31e4 100644 (file)
@@ -60,6 +60,7 @@
 #define MII_M1111_PHY_EXT_SR           0x1b
 #define MII_M1111_HWCFG_MODE_MASK      0xf
 #define MII_M1111_HWCFG_MODE_RGMII     0xb
+#define MII_M1111_HWCFG_MODE_SGMII_NO_CLK      0x4
 
 MODULE_DESCRIPTION("Marvell PHY driver");
 MODULE_AUTHOR("Andy Fleming");
@@ -169,6 +170,21 @@ static int m88e1111_config_init(struct phy_device *phydev)
                        return err;
        }
 
+       if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
+               int temp;
+
+               temp = phy_read(phydev, MII_M1111_PHY_EXT_SR);
+               if (temp < 0)
+                       return temp;
+
+               temp &= ~(MII_M1111_HWCFG_MODE_MASK);
+               temp |= MII_M1111_HWCFG_MODE_SGMII_NO_CLK;
+
+               err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp);
+               if (err < 0)
+                       return err;
+       }
+
        err = phy_write(phydev, MII_BMCR, BMCR_RESET);
        if (err < 0)
                return err;
@@ -238,77 +254,84 @@ static int m88e1145_config_init(struct phy_device *phydev)
        return 0;
 }
 
-static struct phy_driver m88e1101_driver = {
-       .phy_id = 0x01410c60,
-       .phy_id_mask = 0xfffffff0,
-       .name = "Marvell 88E1101",
-       .features = PHY_GBIT_FEATURES,
-       .flags = PHY_HAS_INTERRUPT,
-       .config_aneg = &marvell_config_aneg,
-       .read_status = &genphy_read_status,
-       .ack_interrupt = &marvell_ack_interrupt,
-       .config_intr = &marvell_config_intr,
-       .driver = {.owner = THIS_MODULE,},
-};
-
-static struct phy_driver m88e1111_driver = {
-       .phy_id = 0x01410cc0,
-       .phy_id_mask = 0xfffffff0,
-       .name = "Marvell 88E1111",
-       .features = PHY_GBIT_FEATURES,
-       .flags = PHY_HAS_INTERRUPT,
-       .config_aneg = &marvell_config_aneg,
-       .read_status = &genphy_read_status,
-       .ack_interrupt = &marvell_ack_interrupt,
-       .config_intr = &marvell_config_intr,
-       .config_init = &m88e1111_config_init,
-       .driver = {.owner = THIS_MODULE,},
-};
-
-static struct phy_driver m88e1145_driver = {
-       .phy_id = 0x01410cd0,
-       .phy_id_mask = 0xfffffff0,
-       .name = "Marvell 88E1145",
-       .features = PHY_GBIT_FEATURES,
-       .flags = PHY_HAS_INTERRUPT,
-       .config_init = &m88e1145_config_init,
-       .config_aneg = &marvell_config_aneg,
-       .read_status = &genphy_read_status,
-       .ack_interrupt = &marvell_ack_interrupt,
-       .config_intr = &marvell_config_intr,
-       .driver = {.owner = THIS_MODULE,},
+static struct phy_driver marvell_drivers[] = {
+       {
+               .phy_id = 0x01410c60,
+               .phy_id_mask = 0xfffffff0,
+               .name = "Marvell 88E1101",
+               .features = PHY_GBIT_FEATURES,
+               .flags = PHY_HAS_INTERRUPT,
+               .config_aneg = &marvell_config_aneg,
+               .read_status = &genphy_read_status,
+               .ack_interrupt = &marvell_ack_interrupt,
+               .config_intr = &marvell_config_intr,
+               .driver = {.owner = THIS_MODULE,},
+       },
+       {
+               .phy_id = 0x01410c90,
+               .phy_id_mask = 0xfffffff0,
+               .name = "Marvell 88E1112",
+               .features = PHY_GBIT_FEATURES,
+               .flags = PHY_HAS_INTERRUPT,
+               .config_init = &m88e1111_config_init,
+               .config_aneg = &marvell_config_aneg,
+               .read_status = &genphy_read_status,
+               .ack_interrupt = &marvell_ack_interrupt,
+               .config_intr = &marvell_config_intr,
+               .driver = {.owner = THIS_MODULE,},
+       },
+       {
+               .phy_id = 0x01410cc0,
+               .phy_id_mask = 0xfffffff0,
+               .name = "Marvell 88E1111",
+               .features = PHY_GBIT_FEATURES,
+               .flags = PHY_HAS_INTERRUPT,
+               .config_init = &m88e1111_config_init,
+               .config_aneg = &marvell_config_aneg,
+               .read_status = &genphy_read_status,
+               .ack_interrupt = &marvell_ack_interrupt,
+               .config_intr = &marvell_config_intr,
+               .driver = {.owner = THIS_MODULE,},
+       },
+       {
+               .phy_id = 0x01410cd0,
+               .phy_id_mask = 0xfffffff0,
+               .name = "Marvell 88E1145",
+               .features = PHY_GBIT_FEATURES,
+               .flags = PHY_HAS_INTERRUPT,
+               .config_init = &m88e1145_config_init,
+               .config_aneg = &marvell_config_aneg,
+               .read_status = &genphy_read_status,
+               .ack_interrupt = &marvell_ack_interrupt,
+               .config_intr = &marvell_config_intr,
+               .driver = {.owner = THIS_MODULE,},
+       }
 };
 
 static int __init marvell_init(void)
 {
        int ret;
+       int i;
 
-       ret = phy_driver_register(&m88e1101_driver);
-       if (ret)
-               return ret;
+       for (i = 0; i < ARRAY_SIZE(marvell_drivers); i++) {
+               ret = phy_driver_register(&marvell_drivers[i]);
 
-       ret = phy_driver_register(&m88e1111_driver);
-       if (ret)
-               goto err1111;
-
-       ret = phy_driver_register(&m88e1145_driver);
-       if (ret)
-               goto err1145;
+               if (ret) {
+                       while (i-- > 0)
+                               phy_driver_unregister(&marvell_drivers[i]);
+                       return ret;
+               }
+       }
 
        return 0;
-
-err1145:
-       phy_driver_unregister(&m88e1111_driver);
-err1111:
-       phy_driver_unregister(&m88e1101_driver);
-       return ret;
 }
 
 static void __exit marvell_exit(void)
 {
-       phy_driver_unregister(&m88e1101_driver);
-       phy_driver_unregister(&m88e1111_driver);
-       phy_driver_unregister(&m88e1145_driver);
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(marvell_drivers); i++)
+               phy_driver_unregister(&marvell_drivers[i]);
 }
 
 module_init(marvell_init);
diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c
new file mode 100644 (file)
index 0000000..5891a0f
--- /dev/null
@@ -0,0 +1,2486 @@
+/*****************************************************************************
+ * Linux PPP over L2TP (PPPoX/PPPoL2TP) Sockets
+ *
+ * PPPoX    --- Generic PPP encapsulation socket family
+ * PPPoL2TP --- PPP over L2TP (RFC 2661)
+ *
+ * Version:    1.0.0
+ *
+ * Authors:    Martijn van Oosterhout <kleptog@svana.org>
+ *             James Chapman (jchapman@katalix.com)
+ * Contributors:
+ *             Michal Ostrowski <mostrows@speakeasy.net>
+ *             Arnaldo Carvalho de Melo <acme@xconectiva.com.br>
+ *             David S. Miller (davem@redhat.com)
+ *
+ * License:
+ *             This program is free software; you can redistribute it and/or
+ *             modify it under the terms of the GNU General Public License
+ *             as published by the Free Software Foundation; either version
+ *             2 of the License, or (at your option) any later version.
+ *
+ */
+
+/* This driver handles only L2TP data frames; control frames are handled by a
+ * userspace application.
+ *
+ * To send data in an L2TP session, userspace opens a PPPoL2TP socket and
+ * attaches it to a bound UDP socket with local tunnel_id / session_id and
+ * peer tunnel_id / session_id set. Data can then be sent or received using
+ * regular socket sendmsg() / recvmsg() calls. Kernel parameters of the socket
+ * can be read or modified using ioctl() or [gs]etsockopt() calls.
+ *
+ * When a PPPoL2TP socket is connected with local and peer session_id values
+ * zero, the socket is treated as a special tunnel management socket.
+ *
+ * Here's example userspace code to create a socket for sending/receiving data
+ * over an L2TP session:-
+ *
+ *     struct sockaddr_pppol2tp sax;
+ *     int fd;
+ *     int session_fd;
+ *
+ *     fd = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OL2TP);
+ *
+ *     sax.sa_family = AF_PPPOX;
+ *     sax.sa_protocol = PX_PROTO_OL2TP;
+ *     sax.pppol2tp.fd = tunnel_fd;    // bound UDP socket
+ *     sax.pppol2tp.addr.sin_addr.s_addr = addr->sin_addr.s_addr;
+ *     sax.pppol2tp.addr.sin_port = addr->sin_port;
+ *     sax.pppol2tp.addr.sin_family = AF_INET;
+ *     sax.pppol2tp.s_tunnel  = tunnel_id;
+ *     sax.pppol2tp.s_session = session_id;
+ *     sax.pppol2tp.d_tunnel  = peer_tunnel_id;
+ *     sax.pppol2tp.d_session = peer_session_id;
+ *
+ *     session_fd = connect(fd, (struct sockaddr *)&sax, sizeof(sax));
+ *
+ * A pppd plugin that allows PPP traffic to be carried over L2TP using
+ * this driver is available from the OpenL2TP project at
+ * http://openl2tp.sourceforge.net.
+ */
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/string.h>
+#include <linux/list.h>
+#include <asm/uaccess.h>
+
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/kthread.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/jiffies.h>
+
+#include <linux/netdevice.h>
+#include <linux/net.h>
+#include <linux/inetdevice.h>
+#include <linux/skbuff.h>
+#include <linux/init.h>
+#include <linux/ip.h>
+#include <linux/udp.h>
+#include <linux/if_pppox.h>
+#include <linux/if_pppol2tp.h>
+#include <net/sock.h>
+#include <linux/ppp_channel.h>
+#include <linux/ppp_defs.h>
+#include <linux/if_ppp.h>
+#include <linux/file.h>
+#include <linux/hash.h>
+#include <linux/sort.h>
+#include <linux/proc_fs.h>
+#include <net/dst.h>
+#include <net/ip.h>
+#include <net/udp.h>
+#include <net/xfrm.h>
+
+#include <asm/byteorder.h>
+#include <asm/atomic.h>
+
+
+#define PPPOL2TP_DRV_VERSION   "V1.0"
+
+/* L2TP header constants */
+#define L2TP_HDRFLAG_T    0x8000
+#define L2TP_HDRFLAG_L    0x4000
+#define L2TP_HDRFLAG_S    0x0800
+#define L2TP_HDRFLAG_O    0x0200
+#define L2TP_HDRFLAG_P    0x0100
+
+#define L2TP_HDR_VER_MASK  0x000F
+#define L2TP_HDR_VER      0x0002
+
+/* Space for UDP, L2TP and PPP headers */
+#define PPPOL2TP_HEADER_OVERHEAD       40
+
+/* Just some random numbers */
+#define L2TP_TUNNEL_MAGIC      0x42114DDA
+#define L2TP_SESSION_MAGIC     0x0C04EB7D
+
+#define PPPOL2TP_HASH_BITS     4
+#define PPPOL2TP_HASH_SIZE     (1 << PPPOL2TP_HASH_BITS)
+
+/* Default trace flags */
+#define PPPOL2TP_DEFAULT_DEBUG_FLAGS   0
+
+#define PRINTK(_mask, _type, _lvl, _fmt, args...)                      \
+       do {                                                            \
+               if ((_mask) & (_type))                                  \
+                       printk(_lvl "PPPOL2TP: " _fmt, ##args);         \
+       } while(0)
+
+/* Number of bytes to build transmit L2TP headers.
+ * Unfortunately the size is different depending on whether sequence numbers
+ * are enabled.
+ */
+#define PPPOL2TP_L2TP_HDR_SIZE_SEQ             10
+#define PPPOL2TP_L2TP_HDR_SIZE_NOSEQ           6
+
+struct pppol2tp_tunnel;
+
+/* Describes a session. It is the sk_user_data field in the PPPoL2TP
+ * socket. Contains information to determine incoming packets and transmit
+ * outgoing ones.
+ */
+struct pppol2tp_session
+{
+       int                     magic;          /* should be
+                                                * L2TP_SESSION_MAGIC */
+       int                     owner;          /* pid that opened the socket */
+
+       struct sock             *sock;          /* Pointer to the session
+                                                * PPPoX socket */
+       struct sock             *tunnel_sock;   /* Pointer to the tunnel UDP
+                                                * socket */
+
+       struct pppol2tp_addr    tunnel_addr;    /* Description of tunnel */
+
+       struct pppol2tp_tunnel  *tunnel;        /* back pointer to tunnel
+                                                * context */
+
+       char                    name[20];       /* "sess xxxxx/yyyyy", where
+                                                * x=tunnel_id, y=session_id */
+       int                     mtu;
+       int                     mru;
+       int                     flags;          /* accessed by PPPIOCGFLAGS.
+                                                * Unused. */
+       unsigned                recv_seq:1;     /* expect receive packets with
+                                                * sequence numbers? */
+       unsigned                send_seq:1;     /* send packets with sequence
+                                                * numbers? */
+       unsigned                lns_mode:1;     /* behave as LNS? LAC enables
+                                                * sequence numbers under
+                                                * control of LNS. */
+       int                     debug;          /* bitmask of debug message
+                                                * categories */
+       int                     reorder_timeout; /* configured reorder timeout
+                                                 * (in jiffies) */
+       u16                     nr;             /* session NR state (receive) */
+       u16                     ns;             /* session NR state (send) */
+       struct sk_buff_head     reorder_q;      /* receive reorder queue */
+       struct pppol2tp_ioc_stats stats;
+       struct hlist_node       hlist;          /* Hash list node */
+};
+
+/* The sk_user_data field of the tunnel's UDP socket. It contains info to track
+ * all the associated sessions so incoming packets can be sorted out
+ */
+struct pppol2tp_tunnel
+{
+       int                     magic;          /* Should be L2TP_TUNNEL_MAGIC */
+       rwlock_t                hlist_lock;     /* protect session_hlist */
+       struct hlist_head       session_hlist[PPPOL2TP_HASH_SIZE];
+                                               /* hashed list of sessions,
+                                                * hashed by id */
+       int                     debug;          /* bitmask of debug message
+                                                * categories */
+       char                    name[12];       /* "tunl xxxxx" */
+       struct pppol2tp_ioc_stats stats;
+
+       void (*old_sk_destruct)(struct sock *);
+
+       struct sock             *sock;          /* Parent socket */
+       struct list_head        list;           /* Keep a list of all open
+                                                * prepared sockets */
+
+       atomic_t                ref_count;
+};
+
+/* Private data stored for received packets in the skb.
+ */
+struct pppol2tp_skb_cb {
+       u16                     ns;
+       u16                     nr;
+       u16                     has_seq;
+       u16                     length;
+       unsigned long           expires;
+};
+
+#define PPPOL2TP_SKB_CB(skb)   ((struct pppol2tp_skb_cb *) &skb->cb[sizeof(struct inet_skb_parm)])
+
+static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb);
+static void pppol2tp_tunnel_free(struct pppol2tp_tunnel *tunnel);
+
+static atomic_t pppol2tp_tunnel_count;
+static atomic_t pppol2tp_session_count;
+static struct ppp_channel_ops pppol2tp_chan_ops = { pppol2tp_xmit , NULL };
+static struct proto_ops pppol2tp_ops;
+static LIST_HEAD(pppol2tp_tunnel_list);
+static DEFINE_RWLOCK(pppol2tp_tunnel_list_lock);
+
+/* Helpers to obtain tunnel/session contexts from sockets.
+ */
+static inline struct pppol2tp_session *pppol2tp_sock_to_session(struct sock *sk)
+{
+       struct pppol2tp_session *session;
+
+       if (sk == NULL)
+               return NULL;
+
+       session = (struct pppol2tp_session *)(sk->sk_user_data);
+       if (session == NULL)
+               return NULL;
+
+       BUG_ON(session->magic != L2TP_SESSION_MAGIC);
+
+       return session;
+}
+
+static inline struct pppol2tp_tunnel *pppol2tp_sock_to_tunnel(struct sock *sk)
+{
+       struct pppol2tp_tunnel *tunnel;
+
+       if (sk == NULL)
+               return NULL;
+
+       tunnel = (struct pppol2tp_tunnel *)(sk->sk_user_data);
+       if (tunnel == NULL)
+               return NULL;
+
+       BUG_ON(tunnel->magic != L2TP_TUNNEL_MAGIC);
+
+       return tunnel;
+}
+
+/* Tunnel reference counts. Incremented per session that is added to
+ * the tunnel.
+ */
+static inline void pppol2tp_tunnel_inc_refcount(struct pppol2tp_tunnel *tunnel)
+{
+       atomic_inc(&tunnel->ref_count);
+}
+
+static inline void pppol2tp_tunnel_dec_refcount(struct pppol2tp_tunnel *tunnel)
+{
+       if (atomic_dec_and_test(&tunnel->ref_count))
+               pppol2tp_tunnel_free(tunnel);
+}
+
+/* Session hash list.
+ * The session_id SHOULD be random according to RFC2661, but several
+ * L2TP implementations (Cisco and Microsoft) use incrementing
+ * session_ids.  So we do a real hash on the session_id, rather than a
+ * simple bitmask.
+ */
+static inline struct hlist_head *
+pppol2tp_session_id_hash(struct pppol2tp_tunnel *tunnel, u16 session_id)
+{
+       unsigned long hash_val = (unsigned long) session_id;
+       return &tunnel->session_hlist[hash_long(hash_val, PPPOL2TP_HASH_BITS)];
+}
+
+/* Lookup a session by id
+ */
+static struct pppol2tp_session *
+pppol2tp_session_find(struct pppol2tp_tunnel *tunnel, u16 session_id)
+{
+       struct hlist_head *session_list =
+               pppol2tp_session_id_hash(tunnel, session_id);
+       struct pppol2tp_session *session;
+       struct hlist_node *walk;
+
+       read_lock(&tunnel->hlist_lock);
+       hlist_for_each_entry(session, walk, session_list, hlist) {
+               if (session->tunnel_addr.s_session == session_id) {
+                       read_unlock(&tunnel->hlist_lock);
+                       return session;
+               }
+       }
+       read_unlock(&tunnel->hlist_lock);
+
+       return NULL;
+}
+
+/* Lookup a tunnel by id
+ */
+static struct pppol2tp_tunnel *pppol2tp_tunnel_find(u16 tunnel_id)
+{
+       struct pppol2tp_tunnel *tunnel = NULL;
+
+       read_lock(&pppol2tp_tunnel_list_lock);
+       list_for_each_entry(tunnel, &pppol2tp_tunnel_list, list) {
+               if (tunnel->stats.tunnel_id == tunnel_id) {
+                       read_unlock(&pppol2tp_tunnel_list_lock);
+                       return tunnel;
+               }
+       }
+       read_unlock(&pppol2tp_tunnel_list_lock);
+
+       return NULL;
+}
+
+/*****************************************************************************
+ * Receive data handling
+ *****************************************************************************/
+
+/* Queue a skb in order. We come here only if the skb has an L2TP sequence
+ * number.
+ */
+static void pppol2tp_recv_queue_skb(struct pppol2tp_session *session, struct sk_buff *skb)
+{
+       struct sk_buff *skbp;
+       u16 ns = PPPOL2TP_SKB_CB(skb)->ns;
+
+       spin_lock(&session->reorder_q.lock);
+       skb_queue_walk(&session->reorder_q, skbp) {
+               if (PPPOL2TP_SKB_CB(skbp)->ns > ns) {
+                       __skb_insert(skb, skbp->prev, skbp, &session->reorder_q);
+                       PRINTK(session->debug, PPPOL2TP_MSG_SEQ, KERN_DEBUG,
+                              "%s: pkt %hu, inserted before %hu, reorder_q len=%d\n",
+                              session->name, ns, PPPOL2TP_SKB_CB(skbp)->ns,
+                              skb_queue_len(&session->reorder_q));
+                       session->stats.rx_oos_packets++;
+                       goto out;
+               }
+       }
+
+       __skb_queue_tail(&session->reorder_q, skb);
+
+out:
+       spin_unlock(&session->reorder_q.lock);
+}
+
+/* Dequeue a single skb.
+ */
+static void pppol2tp_recv_dequeue_skb(struct pppol2tp_session *session, struct sk_buff *skb)
+{
+       struct pppol2tp_tunnel *tunnel = session->tunnel;
+       int length = PPPOL2TP_SKB_CB(skb)->length;
+       struct sock *session_sock = NULL;
+
+       /* We're about to requeue the skb, so unlink it and return resources
+        * to its current owner (a socket receive buffer).
+        */
+       skb_unlink(skb, &session->reorder_q);
+       skb_orphan(skb);
+
+       tunnel->stats.rx_packets++;
+       tunnel->stats.rx_bytes += length;
+       session->stats.rx_packets++;
+       session->stats.rx_bytes += length;
+
+       if (PPPOL2TP_SKB_CB(skb)->has_seq) {
+               /* Bump our Nr */
+               session->nr++;
+               PRINTK(session->debug, PPPOL2TP_MSG_SEQ, KERN_DEBUG,
+                      "%s: updated nr to %hu\n", session->name, session->nr);
+       }
+
+       /* If the socket is bound, send it in to PPP's input queue. Otherwise
+        * queue it on the session socket.
+        */
+       session_sock = session->sock;
+       if (session_sock->sk_state & PPPOX_BOUND) {
+               struct pppox_sock *po;
+               PRINTK(session->debug, PPPOL2TP_MSG_DATA, KERN_DEBUG,
+                      "%s: recv %d byte data frame, passing to ppp\n",
+                      session->name, length);
+
+               /* We need to forget all info related to the L2TP packet
+                * gathered in the skb as we are going to reuse the same
+                * skb for the inner packet.
+                * Namely we need to:
+                * - reset xfrm (IPSec) information as it applies to
+                *   the outer L2TP packet and not to the inner one
+                * - release the dst to force a route lookup on the inner
+                *   IP packet since skb->dst currently points to the dst
+                *   of the UDP tunnel
+                * - reset netfilter information as it doesn't apply
+                *   to the inner packet either
+                */
+               secpath_reset(skb);
+               dst_release(skb->dst);
+               skb->dst = NULL;
+               nf_reset(skb);
+
+               po = pppox_sk(session_sock);
+               ppp_input(&po->chan, skb);
+       } else {
+               PRINTK(session->debug, PPPOL2TP_MSG_DATA, KERN_INFO,
+                      "%s: socket not bound\n", session->name);
+
+               /* Not bound. Nothing we can do, so discard. */
+               session->stats.rx_errors++;
+               kfree_skb(skb);
+       }
+
+       sock_put(session->sock);
+}
+
+/* Dequeue skbs from the session's reorder_q, subject to packet order.
+ * Skbs that have been in the queue for too long are simply discarded.
+ */
+static void pppol2tp_recv_dequeue(struct pppol2tp_session *session)
+{
+       struct sk_buff *skb;
+       struct sk_buff *tmp;
+
+       /* If the pkt at the head of the queue has the nr that we
+        * expect to send up next, dequeue it and any other
+        * in-sequence packets behind it.
+        */
+       spin_lock(&session->reorder_q.lock);
+       skb_queue_walk_safe(&session->reorder_q, skb, tmp) {
+               if (time_after(jiffies, PPPOL2TP_SKB_CB(skb)->expires)) {
+                       session->stats.rx_seq_discards++;
+                       session->stats.rx_errors++;
+                       PRINTK(session->debug, PPPOL2TP_MSG_SEQ, KERN_DEBUG,
+                              "%s: oos pkt %hu len %d discarded (too old), "
+                              "waiting for %hu, reorder_q_len=%d\n",
+                              session->name, PPPOL2TP_SKB_CB(skb)->ns,
+                              PPPOL2TP_SKB_CB(skb)->length, session->nr,
+                              skb_queue_len(&session->reorder_q));
+                       __skb_unlink(skb, &session->reorder_q);
+                       kfree_skb(skb);
+                       continue;
+               }
+
+               if (PPPOL2TP_SKB_CB(skb)->has_seq) {
+                       if (PPPOL2TP_SKB_CB(skb)->ns != session->nr) {
+                               PRINTK(session->debug, PPPOL2TP_MSG_SEQ, KERN_DEBUG,
+                                      "%s: holding oos pkt %hu len %d, "
+                                      "waiting for %hu, reorder_q_len=%d\n",
+                                      session->name, PPPOL2TP_SKB_CB(skb)->ns,
+                                      PPPOL2TP_SKB_CB(skb)->length, session->nr,
+                                      skb_queue_len(&session->reorder_q));
+                               goto out;
+                       }
+               }
+               spin_unlock(&session->reorder_q.lock);
+               pppol2tp_recv_dequeue_skb(session, skb);
+               spin_lock(&session->reorder_q.lock);
+       }
+
+out:
+       spin_unlock(&session->reorder_q.lock);
+}
+
+/* Internal receive frame. Do the real work of receiving an L2TP data frame
+ * here. The skb is not on a list when we get here.
+ * Returns 0 if the packet was a data packet and was successfully passed on.
+ * Returns 1 if the packet was not a good data packet and could not be
+ * forwarded.  All such packets are passed up to userspace to deal with.
+ */
+static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb)
+{
+       struct pppol2tp_session *session = NULL;
+       struct pppol2tp_tunnel *tunnel;
+       unsigned char *ptr;
+       u16 hdrflags;
+       u16 tunnel_id, session_id;
+       int length;
+       struct udphdr *uh;
+
+       tunnel = pppol2tp_sock_to_tunnel(sock);
+       if (tunnel == NULL)
+               goto error;
+
+       /* Short packet? */
+       if (skb->len < sizeof(struct udphdr)) {
+               PRINTK(tunnel->debug, PPPOL2TP_MSG_DATA, KERN_INFO,
+                      "%s: recv short packet (len=%d)\n", tunnel->name, skb->len);
+               goto error;
+       }
+
+       /* Point to L2TP header */
+       ptr = skb->data + sizeof(struct udphdr);
+
+       /* Get L2TP header flags */
+       hdrflags = ntohs(*(__be16*)ptr);
+
+       /* Trace packet contents, if enabled */
+       if (tunnel->debug & PPPOL2TP_MSG_DATA) {
+               printk(KERN_DEBUG "%s: recv: ", tunnel->name);
+
+               for (length = 0; length < 16; length++)
+                       printk(" %02X", ptr[length]);
+               printk("\n");
+       }
+
+       /* Get length of L2TP packet */
+       uh = (struct udphdr *) skb_transport_header(skb);
+       length = ntohs(uh->len) - sizeof(struct udphdr);
+
+       /* Too short? */
+       if (length < 12) {
+               PRINTK(tunnel->debug, PPPOL2TP_MSG_DATA, KERN_INFO,
+                      "%s: recv short L2TP packet (len=%d)\n", tunnel->name, length);
+               goto error;
+       }
+
+       /* If type is control packet, it is handled by userspace. */
+       if (hdrflags & L2TP_HDRFLAG_T) {
+               PRINTK(tunnel->debug, PPPOL2TP_MSG_DATA, KERN_DEBUG,
+                      "%s: recv control packet, len=%d\n", tunnel->name, length);
+               goto error;
+       }
+
+       /* Skip flags */
+       ptr += 2;
+
+       /* If length is present, skip it */
+       if (hdrflags & L2TP_HDRFLAG_L)
+               ptr += 2;
+
+       /* Extract tunnel and session ID */
+       tunnel_id = ntohs(*(__be16 *) ptr);
+       ptr += 2;
+       session_id = ntohs(*(__be16 *) ptr);
+       ptr += 2;
+
+       /* Find the session context */
+       session = pppol2tp_session_find(tunnel, session_id);
+       if (!session) {
+               /* Not found? Pass to userspace to deal with */
+               PRINTK(tunnel->debug, PPPOL2TP_MSG_DATA, KERN_INFO,
+                      "%s: no socket found (%hu/%hu). Passing up.\n",
+                      tunnel->name, tunnel_id, session_id);
+               goto error;
+       }
+       sock_hold(session->sock);
+
+       /* The ref count on the socket was increased by the above call since
+        * we now hold a pointer to the session. Take care to do sock_put()
+        * when exiting this function from now on...
+        */
+
+       /* Handle the optional sequence numbers.  If we are the LAC,
+        * enable/disable sequence numbers under the control of the LNS.  If
+        * no sequence numbers present but we were expecting them, discard
+        * frame.
+        */
+       if (hdrflags & L2TP_HDRFLAG_S) {
+               u16 ns, nr;
+               ns = ntohs(*(__be16 *) ptr);
+               ptr += 2;
+               nr = ntohs(*(__be16 *) ptr);
+               ptr += 2;
+
+               /* Received a packet with sequence numbers. If we're the LNS,
+                * check if we sre sending sequence numbers and if not,
+                * configure it so.
+                */
+               if ((!session->lns_mode) && (!session->send_seq)) {
+                       PRINTK(session->debug, PPPOL2TP_MSG_SEQ, KERN_INFO,
+                              "%s: requested to enable seq numbers by LNS\n",
+                              session->name);
+                       session->send_seq = -1;
+               }
+
+               /* Store L2TP info in the skb */
+               PPPOL2TP_SKB_CB(skb)->ns = ns;
+               PPPOL2TP_SKB_CB(skb)->nr = nr;
+               PPPOL2TP_SKB_CB(skb)->has_seq = 1;
+
+               PRINTK(session->debug, PPPOL2TP_MSG_SEQ, KERN_DEBUG,
+                      "%s: recv data ns=%hu, nr=%hu, session nr=%hu\n",
+                      session->name, ns, nr, session->nr);
+       } else {
+               /* No sequence numbers.
+                * If user has configured mandatory sequence numbers, discard.
+                */
+               if (session->recv_seq) {
+                       PRINTK(session->debug, PPPOL2TP_MSG_SEQ, KERN_WARNING,
+                              "%s: recv data has no seq numbers when required. "
+                              "Discarding\n", session->name);
+                       session->stats.rx_seq_discards++;
+                       session->stats.rx_errors++;
+                       goto discard;
+               }
+
+               /* If we're the LAC and we're sending sequence numbers, the
+                * LNS has requested that we no longer send sequence numbers.
+                * If we're the LNS and we're sending sequence numbers, the
+                * LAC is broken. Discard the frame.
+                */
+               if ((!session->lns_mode) && (session->send_seq)) {
+                       PRINTK(session->debug, PPPOL2TP_MSG_SEQ, KERN_INFO,
+                              "%s: requested to disable seq numbers by LNS\n",
+                              session->name);
+                       session->send_seq = 0;
+               } else if (session->send_seq) {
+                       PRINTK(session->debug, PPPOL2TP_MSG_SEQ, KERN_WARNING,
+                              "%s: recv data has no seq numbers when required. "
+                              "Discarding\n", session->name);
+                       session->stats.rx_seq_discards++;
+                       session->stats.rx_errors++;
+                       goto discard;
+               }
+
+               /* Store L2TP info in the skb */
+               PPPOL2TP_SKB_CB(skb)->has_seq = 0;
+       }
+
+       /* If offset bit set, skip it. */
+       if (hdrflags & L2TP_HDRFLAG_O)
+               ptr += 2 + ntohs(*(__be16 *) ptr);
+
+       skb_pull(skb, ptr - skb->data);
+
+       /* Skip PPP header, if present.  In testing, Microsoft L2TP clients
+        * don't send the PPP header (PPP header compression enabled), but
+        * other clients can include the header. So we cope with both cases
+        * here. The PPP header is always FF03 when using L2TP.
+        *
+        * Note that skb->data[] isn't dereferenced from a u16 ptr here since
+        * the field may be unaligned.
+        */
+       if ((skb->data[0] == 0xff) && (skb->data[1] == 0x03))
+               skb_pull(skb, 2);
+
+       /* Prepare skb for adding to the session's reorder_q.  Hold
+        * packets for max reorder_timeout or 1 second if not
+        * reordering.
+        */
+       PPPOL2TP_SKB_CB(skb)->length = length;
+       PPPOL2TP_SKB_CB(skb)->expires = jiffies +
+               (session->reorder_timeout ? session->reorder_timeout : HZ);
+
+       /* Add packet to the session's receive queue. Reordering is done here, if
+        * enabled. Saved L2TP protocol info is stored in skb->sb[].
+        */
+       if (PPPOL2TP_SKB_CB(skb)->has_seq) {
+               if (session->reorder_timeout != 0) {
+                       /* Packet reordering enabled. Add skb to session's
+                        * reorder queue, in order of ns.
+                        */
+                       pppol2tp_recv_queue_skb(session, skb);
+               } else {
+                       /* Packet reordering disabled. Discard out-of-sequence
+                        * packets
+                        */
+                       if (PPPOL2TP_SKB_CB(skb)->ns != session->nr) {
+                               session->stats.rx_seq_discards++;
+                               session->stats.rx_errors++;
+                               PRINTK(session->debug, PPPOL2TP_MSG_SEQ, KERN_DEBUG,
+                                      "%s: oos pkt %hu len %d discarded, "
+                                      "waiting for %hu, reorder_q_len=%d\n",
+                                      session->name, PPPOL2TP_SKB_CB(skb)->ns,
+                                      PPPOL2TP_SKB_CB(skb)->length, session->nr,
+                                      skb_queue_len(&session->reorder_q));
+                               goto discard;
+                       }
+                       skb_queue_tail(&session->reorder_q, skb);
+               }
+       } else {
+               /* No sequence numbers. Add the skb to the tail of the
+                * reorder queue. This ensures that it will be
+                * delivered after all previous sequenced skbs.
+                */
+               skb_queue_tail(&session->reorder_q, skb);
+       }
+
+       /* Try to dequeue as many skbs from reorder_q as we can. */
+       pppol2tp_recv_dequeue(session);
+
+       return 0;
+
+discard:
+       kfree_skb(skb);
+       sock_put(session->sock);
+
+       return 0;
+
+error:
+       return 1;
+}
+
+/* UDP encapsulation receive handler. See net/ipv4/udp.c.
+ * Return codes:
+ * 0 : success.
+ * <0: error
+ * >0: skb should be passed up to userspace as UDP.
+ */
+static int pppol2tp_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
+{
+       struct pppol2tp_tunnel *tunnel;
+
+       tunnel = pppol2tp_sock_to_tunnel(sk);
+       if (tunnel == NULL)
+               goto pass_up;
+
+       PRINTK(tunnel->debug, PPPOL2TP_MSG_DATA, KERN_DEBUG,
+              "%s: received %d bytes\n", tunnel->name, skb->len);
+
+       if (pppol2tp_recv_core(sk, skb))
+               goto pass_up;
+
+       return 0;
+
+pass_up:
+       return 1;
+}
+
+/* Receive message. This is the recvmsg for the PPPoL2TP socket.
+ */
+static int pppol2tp_recvmsg(struct kiocb *iocb, struct socket *sock,
+                           struct msghdr *msg, size_t len,
+                           int flags)
+{
+       int err;
+       struct sk_buff *skb;
+       struct sock *sk = sock->sk;
+
+       err = -EIO;
+       if (sk->sk_state & PPPOX_BOUND)
+               goto end;
+
+       msg->msg_namelen = 0;
+
+       err = 0;
+       skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
+                               flags & MSG_DONTWAIT, &err);
+       if (skb) {
+               err = memcpy_toiovec(msg->msg_iov, (unsigned char *) skb->data,
+                                    skb->len);
+               if (err < 0)
+                       goto do_skb_free;
+               err = skb->len;
+       }
+do_skb_free:
+       kfree_skb(skb);
+end:
+       return err;
+}
+
+/************************************************************************
+ * Transmit handling
+ ***********************************************************************/
+
+/* Tell how big L2TP headers are for a particular session. This
+ * depends on whether sequence numbers are being used.
+ */
+static inline int pppol2tp_l2tp_header_len(struct pppol2tp_session *session)
+{
+       if (session->send_seq)
+               return PPPOL2TP_L2TP_HDR_SIZE_SEQ;
+
+       return PPPOL2TP_L2TP_HDR_SIZE_NOSEQ;
+}
+
+/* Build an L2TP header for the session into the buffer provided.
+ */
+static void pppol2tp_build_l2tp_header(struct pppol2tp_session *session,
+                                      void *buf)
+{
+       __be16 *bufp = buf;
+       u16 flags = L2TP_HDR_VER;
+
+       if (session->send_seq)
+               flags |= L2TP_HDRFLAG_S;
+
+       /* Setup L2TP header.
+        * FIXME: Can this ever be unaligned? Is direct dereferencing of
+        * 16-bit header fields safe here for all architectures?
+        */
+       *bufp++ = htons(flags);
+       *bufp++ = htons(session->tunnel_addr.d_tunnel);
+       *bufp++ = htons(session->tunnel_addr.d_session);
+       if (session->send_seq) {
+               *bufp++ = htons(session->ns);
+               *bufp++ = 0;
+               session->ns++;
+               PRINTK(session->debug, PPPOL2TP_MSG_SEQ, KERN_DEBUG,
+                      "%s: updated ns to %hu\n", session->name, session->ns);
+       }
+}
+
+/* This is the sendmsg for the PPPoL2TP pppol2tp_session socket.  We come here
+ * when a user application does a sendmsg() on the session socket. L2TP and
+ * PPP headers must be inserted into the user's data.
+ */
+static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
+                           size_t total_len)
+{
+       static const unsigned char ppph[2] = { 0xff, 0x03 };
+       struct sock *sk = sock->sk;
+       struct inet_sock *inet;
+       __wsum csum = 0;
+       struct sk_buff *skb;
+       int error;
+       int hdr_len;
+       struct pppol2tp_session *session;
+       struct pppol2tp_tunnel *tunnel;
+       struct udphdr *uh;
+
+       error = -ENOTCONN;
+       if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED))
+               goto error;
+
+       /* Get session and tunnel contexts */
+       error = -EBADF;
+       session = pppol2tp_sock_to_session(sk);
+       if (session == NULL)
+               goto error;
+
+       tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock);
+       if (tunnel == NULL)
+               goto error;
+
+       /* What header length is configured for this session? */
+       hdr_len = pppol2tp_l2tp_header_len(session);
+
+       /* Allocate a socket buffer */
+       error = -ENOMEM;
+       skb = sock_wmalloc(sk, NET_SKB_PAD + sizeof(struct iphdr) +
+                          sizeof(struct udphdr) + hdr_len +
+                          sizeof(ppph) + total_len,
+                          0, GFP_KERNEL);
+       if (!skb)
+               goto error;
+
+       /* Reserve space for headers. */
+       skb_reserve(skb, NET_SKB_PAD);
+       skb_reset_network_header(skb);
+       skb_reserve(skb, sizeof(struct iphdr));
+       skb_reset_transport_header(skb);
+
+       /* Build UDP header */
+       inet = inet_sk(session->tunnel_sock);
+       uh = (struct udphdr *) skb->data;
+       uh->source = inet->sport;
+       uh->dest = inet->dport;
+       uh->len = htons(hdr_len + sizeof(ppph) + total_len);
+       uh->check = 0;
+       skb_put(skb, sizeof(struct udphdr));
+
+       /* Build L2TP header */
+       pppol2tp_build_l2tp_header(session, skb->data);
+       skb_put(skb, hdr_len);
+
+       /* Add PPP header */
+       skb->data[0] = ppph[0];
+       skb->data[1] = ppph[1];
+       skb_put(skb, 2);
+
+       /* Copy user data into skb */
+       error = memcpy_fromiovec(skb->data, m->msg_iov, total_len);
+       if (error < 0) {
+               kfree_skb(skb);
+               goto error;
+       }
+       skb_put(skb, total_len);
+
+       /* Calculate UDP checksum if configured to do so */
+       if (session->tunnel_sock->sk_no_check != UDP_CSUM_NOXMIT)
+               csum = udp_csum_outgoing(sk, skb);
+
+       /* Debug */
+       if (session->send_seq)
+               PRINTK(session->debug, PPPOL2TP_MSG_DATA, KERN_DEBUG,
+                      "%s: send %Zd bytes, ns=%hu\n", session->name,
+                      total_len, session->ns - 1);
+       else
+               PRINTK(session->debug, PPPOL2TP_MSG_DATA, KERN_DEBUG,
+                      "%s: send %Zd bytes\n", session->name, total_len);
+
+       if (session->debug & PPPOL2TP_MSG_DATA) {
+               int i;
+               unsigned char *datap = skb->data;
+
+               printk(KERN_DEBUG "%s: xmit:", session->name);
+               for (i = 0; i < total_len; i++) {
+                       printk(" %02X", *datap++);
+                       if (i == 15) {
+                               printk(" ...");
+                               break;
+                       }
+               }
+               printk("\n");
+       }
+
+       /* Queue the packet to IP for output */
+       error = ip_queue_xmit(skb, 1);
+
+       /* Update stats */
+       if (error >= 0) {
+               tunnel->stats.tx_packets++;
+               tunnel->stats.tx_bytes += skb->len;
+               session->stats.tx_packets++;
+               session->stats.tx_bytes += skb->len;
+       } else {
+               tunnel->stats.tx_errors++;
+               session->stats.tx_errors++;
+       }
+
+error:
+       return error;
+}
+
+/* Transmit function called by generic PPP driver.  Sends PPP frame
+ * over PPPoL2TP socket.
+ *
+ * This is almost the same as pppol2tp_sendmsg(), but rather than
+ * being called with a msghdr from userspace, it is called with a skb
+ * from the kernel.
+ *
+ * The supplied skb from ppp doesn't have enough headroom for the
+ * insertion of L2TP, UDP and IP headers so we need to allocate more
+ * headroom in the skb. This will create a cloned skb. But we must be
+ * careful in the error case because the caller will expect to free
+ * the skb it supplied, not our cloned skb. So we take care to always
+ * leave the original skb unfreed if we return an error.
+ */
+static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
+{
+       static const u8 ppph[2] = { 0xff, 0x03 };
+       struct sock *sk = (struct sock *) chan->private;
+       struct sock *sk_tun;
+       int hdr_len;
+       struct pppol2tp_session *session;
+       struct pppol2tp_tunnel *tunnel;
+       int rc;
+       int headroom;
+       int data_len = skb->len;
+       struct inet_sock *inet;
+       __wsum csum = 0;
+       struct sk_buff *skb2 = NULL;
+       struct udphdr *uh;
+
+       if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED))
+               goto abort;
+
+       /* Get session and tunnel contexts from the socket */
+       session = pppol2tp_sock_to_session(sk);
+       if (session == NULL)
+               goto abort;
+
+       sk_tun = session->tunnel_sock;
+       if (sk_tun == NULL)
+               goto abort;
+       tunnel = pppol2tp_sock_to_tunnel(sk_tun);
+       if (tunnel == NULL)
+               goto abort;
+
+       /* What header length is configured for this session? */
+       hdr_len = pppol2tp_l2tp_header_len(session);
+
+       /* Check that there's enough headroom in the skb to insert IP,
+        * UDP and L2TP and PPP headers. If not enough, expand it to
+        * make room. Note that a new skb (or a clone) is
+        * allocated. If we return an error from this point on, make
+        * sure we free the new skb but do not free the original skb
+        * since that is done by the caller for the error case.
+        */
+       headroom = NET_SKB_PAD + sizeof(struct iphdr) +
+               sizeof(struct udphdr) + hdr_len + sizeof(ppph);
+       if (skb_headroom(skb) < headroom) {
+               skb2 = skb_realloc_headroom(skb, headroom);
+               if (skb2 == NULL)
+                       goto abort;
+       } else
+               skb2 = skb;
+
+       /* Check that the socket has room */
+       if (atomic_read(&sk_tun->sk_wmem_alloc) < sk_tun->sk_sndbuf)
+               skb_set_owner_w(skb2, sk_tun);
+       else
+               goto discard;
+
+       /* Setup PPP header */
+       skb_push(skb2, sizeof(ppph));
+       skb2->data[0] = ppph[0];
+       skb2->data[1] = ppph[1];
+
+       /* Setup L2TP header */
+       skb_push(skb2, hdr_len);
+       pppol2tp_build_l2tp_header(session, skb2->data);
+
+       /* Setup UDP header */
+       inet = inet_sk(sk_tun);
+       skb_push(skb2, sizeof(struct udphdr));
+       skb_reset_transport_header(skb2);
+       uh = (struct udphdr *) skb2->data;
+       uh->source = inet->sport;
+       uh->dest = inet->dport;
+       uh->len = htons(sizeof(struct udphdr) + hdr_len + sizeof(ppph) + data_len);
+       uh->check = 0;
+
+       /* Calculate UDP checksum if configured to do so */
+       if (sk_tun->sk_no_check != UDP_CSUM_NOXMIT)
+               csum = udp_csum_outgoing(sk_tun, skb2);
+
+       /* Debug */
+       if (session->send_seq)
+               PRINTK(session->debug, PPPOL2TP_MSG_DATA, KERN_DEBUG,
+                      "%s: send %d bytes, ns=%hu\n", session->name,
+                      data_len, session->ns - 1);
+       else
+               PRINTK(session->debug, PPPOL2TP_MSG_DATA, KERN_DEBUG,
+                      "%s: send %d bytes\n", session->name, data_len);
+
+       if (session->debug & PPPOL2TP_MSG_DATA) {
+               int i;
+               unsigned char *datap = skb2->data;
+
+               printk(KERN_DEBUG "%s: xmit:", session->name);
+               for (i = 0; i < data_len; i++) {
+                       printk(" %02X", *datap++);
+                       if (i == 31) {
+                               printk(" ...");
+                               break;
+                       }
+               }
+               printk("\n");
+       }
+
+       /* Get routing info from the tunnel socket */
+       skb2->dst = sk_dst_get(sk_tun);
+
+       /* Queue the packet to IP for output */
+       rc = ip_queue_xmit(skb2, 1);
+
+       /* Update stats */
+       if (rc >= 0) {
+               tunnel->stats.tx_packets++;
+               tunnel->stats.tx_bytes += skb2->len;
+               session->stats.tx_packets++;
+               session->stats.tx_bytes += skb2->len;
+       } else {
+               tunnel->stats.tx_errors++;
+               session->stats.tx_errors++;
+       }
+
+       /* Free the original skb */
+       kfree_skb(skb);
+
+       return 1;
+
+discard:
+       /* Free the new skb. Caller will free original skb. */
+       if (skb2 != skb)
+               kfree_skb(skb2);
+abort:
+       return 0;
+}
+
+/*****************************************************************************
+ * Session (and tunnel control) socket create/destroy.
+ *****************************************************************************/
+
+/* When the tunnel UDP socket is closed, all the attached sockets need to go
+ * too.
+ */
+static void pppol2tp_tunnel_closeall(struct pppol2tp_tunnel *tunnel)
+{
+       int hash;
+       struct hlist_node *walk;
+       struct hlist_node *tmp;
+       struct pppol2tp_session *session;
+       struct sock *sk;
+
+       if (tunnel == NULL)
+               BUG();
+
+       PRINTK(tunnel->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+              "%s: closing all sessions...\n", tunnel->name);
+
+       write_lock(&tunnel->hlist_lock);
+       for (hash = 0; hash < PPPOL2TP_HASH_SIZE; hash++) {
+again:
+               hlist_for_each_safe(walk, tmp, &tunnel->session_hlist[hash]) {
+                       session = hlist_entry(walk, struct pppol2tp_session, hlist);
+
+                       sk = session->sock;
+
+                       PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+                              "%s: closing session\n", session->name);
+
+                       hlist_del_init(&session->hlist);
+
+                       /* Since we should hold the sock lock while
+                        * doing any unbinding, we need to release the
+                        * lock we're holding before taking that lock.
+                        * Hold a reference to the sock so it doesn't
+                        * disappear as we're jumping between locks.
+                        */
+                       sock_hold(sk);
+                       write_unlock(&tunnel->hlist_lock);
+                       lock_sock(sk);
+
+                       if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) {
+                               pppox_unbind_sock(sk);
+                               sk->sk_state = PPPOX_DEAD;
+                               sk->sk_state_change(sk);
+                       }
+
+                       /* Purge any queued data */
+                       skb_queue_purge(&sk->sk_receive_queue);
+                       skb_queue_purge(&sk->sk_write_queue);
+                       skb_queue_purge(&session->reorder_q);
+
+                       release_sock(sk);
+                       sock_put(sk);
+
+                       /* Now restart from the beginning of this hash
+                        * chain.  We always remove a session from the
+                        * list so we are guaranteed to make forward
+                        * progress.
+                        */
+                       write_lock(&tunnel->hlist_lock);
+                       goto again;
+               }
+       }
+       write_unlock(&tunnel->hlist_lock);
+}
+
+/* Really kill the tunnel.
+ * Come here only when all sessions have been cleared from the tunnel.
+ */
+static void pppol2tp_tunnel_free(struct pppol2tp_tunnel *tunnel)
+{
+       /* Remove from socket list */
+       write_lock(&pppol2tp_tunnel_list_lock);
+       list_del_init(&tunnel->list);
+       write_unlock(&pppol2tp_tunnel_list_lock);
+
+       atomic_dec(&pppol2tp_tunnel_count);
+       kfree(tunnel);
+}
+
+/* Tunnel UDP socket destruct hook.
+ * The tunnel context is deleted only when all session sockets have been
+ * closed.
+ */
+static void pppol2tp_tunnel_destruct(struct sock *sk)
+{
+       struct pppol2tp_tunnel *tunnel;
+
+       tunnel = pppol2tp_sock_to_tunnel(sk);
+       if (tunnel == NULL)
+               goto end;
+
+       PRINTK(tunnel->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+              "%s: closing...\n", tunnel->name);
+
+       /* Close all sessions */
+       pppol2tp_tunnel_closeall(tunnel);
+
+       /* No longer an encapsulation socket. See net/ipv4/udp.c */
+       (udp_sk(sk))->encap_type = 0;
+       (udp_sk(sk))->encap_rcv = NULL;
+
+       /* Remove hooks into tunnel socket */
+       tunnel->sock = NULL;
+       sk->sk_destruct = tunnel->old_sk_destruct;
+       sk->sk_user_data = NULL;
+
+       /* Call original (UDP) socket descructor */
+       if (sk->sk_destruct != NULL)
+               (*sk->sk_destruct)(sk);
+
+       pppol2tp_tunnel_dec_refcount(tunnel);
+
+end:
+       return;
+}
+
+/* Really kill the session socket. (Called from sock_put() if
+ * refcnt == 0.)
+ */
+static void pppol2tp_session_destruct(struct sock *sk)
+{
+       struct pppol2tp_session *session = NULL;
+
+       if (sk->sk_user_data != NULL) {
+               struct pppol2tp_tunnel *tunnel;
+
+               session = pppol2tp_sock_to_session(sk);
+               if (session == NULL)
+                       goto out;
+
+               /* Don't use pppol2tp_sock_to_tunnel() here to
+                * get the tunnel context because the tunnel
+                * socket might have already been closed (its
+                * sk->sk_user_data will be NULL) so use the
+                * session's private tunnel ptr instead.
+                */
+               tunnel = session->tunnel;
+               if (tunnel != NULL) {
+                       BUG_ON(tunnel->magic != L2TP_TUNNEL_MAGIC);
+
+                       /* If session_id is zero, this is a null
+                        * session context, which was created for a
+                        * socket that is being used only to manage
+                        * tunnels.
+                        */
+                       if (session->tunnel_addr.s_session != 0) {
+                               /* Delete the session socket from the
+                                * hash
+                                */
+                               write_lock(&tunnel->hlist_lock);
+                               hlist_del_init(&session->hlist);
+                               write_unlock(&tunnel->hlist_lock);
+
+                               atomic_dec(&pppol2tp_session_count);
+                       }
+
+                       /* This will delete the tunnel context if this
+                        * is the last session on the tunnel.
+                        */
+                       session->tunnel = NULL;
+                       session->tunnel_sock = NULL;
+                       pppol2tp_tunnel_dec_refcount(tunnel);
+               }
+       }
+
+       kfree(session);
+out:
+       return;
+}
+
+/* Called when the PPPoX socket (session) is closed.
+ */
+static int pppol2tp_release(struct socket *sock)
+{
+       struct sock *sk = sock->sk;
+       int error;
+
+       if (!sk)
+               return 0;
+
+       error = -EBADF;
+       lock_sock(sk);
+       if (sock_flag(sk, SOCK_DEAD) != 0)
+               goto error;
+
+       pppox_unbind_sock(sk);
+
+       /* Signal the death of the socket. */
+       sk->sk_state = PPPOX_DEAD;
+       sock_orphan(sk);
+       sock->sk = NULL;
+
+       /* Purge any queued data */
+       skb_queue_purge(&sk->sk_receive_queue);
+       skb_queue_purge(&sk->sk_write_queue);
+
+       release_sock(sk);
+
+       /* This will delete the session context via
+        * pppol2tp_session_destruct() if the socket's refcnt drops to
+        * zero.
+        */
+       sock_put(sk);
+
+       return 0;
+
+error:
+       release_sock(sk);
+       return error;
+}
+
+/* Internal function to prepare a tunnel (UDP) socket to have PPPoX
+ * sockets attached to it.
+ */
+static struct sock *pppol2tp_prepare_tunnel_socket(int fd, u16 tunnel_id,
+                                                  int *error)
+{
+       int err;
+       struct socket *sock = NULL;
+       struct sock *sk;
+       struct pppol2tp_tunnel *tunnel;
+       struct sock *ret = NULL;
+
+       /* Get the tunnel UDP socket from the fd, which was opened by
+        * the userspace L2TP daemon.
+        */
+       err = -EBADF;
+       sock = sockfd_lookup(fd, &err);
+       if (!sock) {
+               PRINTK(-1, PPPOL2TP_MSG_CONTROL, KERN_ERR,
+                      "tunl %hu: sockfd_lookup(fd=%d) returned %d\n",
+                      tunnel_id, fd, err);
+               goto err;
+       }
+
+       /* Quick sanity checks */
+       err = -ESOCKTNOSUPPORT;
+       if (sock->type != SOCK_DGRAM) {
+               PRINTK(-1, PPPOL2TP_MSG_CONTROL, KERN_ERR,
+                      "tunl %hu: fd %d wrong type, got %d, expected %d\n",
+                      tunnel_id, fd, sock->type, SOCK_DGRAM);
+               goto err;
+       }
+       err = -EAFNOSUPPORT;
+       if (sock->ops->family != AF_INET) {
+               PRINTK(-1, PPPOL2TP_MSG_CONTROL, KERN_ERR,
+                      "tunl %hu: fd %d wrong family, got %d, expected %d\n",
+                      tunnel_id, fd, sock->ops->family, AF_INET);
+               goto err;
+       }
+
+       err = -ENOTCONN;
+       sk = sock->sk;
+
+       /* Check if this socket has already been prepped */
+       tunnel = (struct pppol2tp_tunnel *)sk->sk_user_data;
+       if (tunnel != NULL) {
+               /* User-data field already set */
+               err = -EBUSY;
+               BUG_ON(tunnel->magic != L2TP_TUNNEL_MAGIC);
+
+               /* This socket has already been prepped */
+               ret = tunnel->sock;
+               goto out;
+       }
+
+       /* This socket is available and needs prepping. Create a new tunnel
+        * context and init it.
+        */
+       sk->sk_user_data = tunnel = kzalloc(sizeof(struct pppol2tp_tunnel), GFP_KERNEL);
+       if (sk->sk_user_data == NULL) {
+               err = -ENOMEM;
+               goto err;
+       }
+
+       tunnel->magic = L2TP_TUNNEL_MAGIC;
+       sprintf(&tunnel->name[0], "tunl %hu", tunnel_id);
+
+       tunnel->stats.tunnel_id = tunnel_id;
+       tunnel->debug = PPPOL2TP_DEFAULT_DEBUG_FLAGS;
+
+       /* Hook on the tunnel socket destructor so that we can cleanup
+        * if the tunnel socket goes away.
+        */
+       tunnel->old_sk_destruct = sk->sk_destruct;
+       sk->sk_destruct = &pppol2tp_tunnel_destruct;
+
+       tunnel->sock = sk;
+       sk->sk_allocation = GFP_ATOMIC;
+
+       /* Misc init */
+       rwlock_init(&tunnel->hlist_lock);
+
+       /* Add tunnel to our list */
+       INIT_LIST_HEAD(&tunnel->list);
+       write_lock(&pppol2tp_tunnel_list_lock);
+       list_add(&tunnel->list, &pppol2tp_tunnel_list);
+       write_unlock(&pppol2tp_tunnel_list_lock);
+       atomic_inc(&pppol2tp_tunnel_count);
+
+       /* Bump the reference count. The tunnel context is deleted
+        * only when this drops to zero.
+        */
+       pppol2tp_tunnel_inc_refcount(tunnel);
+
+       /* Mark socket as an encapsulation socket. See net/ipv4/udp.c */
+       (udp_sk(sk))->encap_type = UDP_ENCAP_L2TPINUDP;
+       (udp_sk(sk))->encap_rcv = pppol2tp_udp_encap_recv;
+
+       ret = tunnel->sock;
+
+       *error = 0;
+out:
+       if (sock)
+               sockfd_put(sock);
+
+       return ret;
+
+err:
+       *error = err;
+       goto out;
+}
+
+static struct proto pppol2tp_sk_proto = {
+       .name     = "PPPOL2TP",
+       .owner    = THIS_MODULE,
+       .obj_size = sizeof(struct pppox_sock),
+};
+
+/* socket() handler. Initialize a new struct sock.
+ */
+static int pppol2tp_create(struct socket *sock)
+{
+       int error = -ENOMEM;
+       struct sock *sk;
+
+       sk = sk_alloc(PF_PPPOX, GFP_KERNEL, &pppol2tp_sk_proto, 1);
+       if (!sk)
+               goto out;
+
+       sock_init_data(sock, sk);
+
+       sock->state  = SS_UNCONNECTED;
+       sock->ops    = &pppol2tp_ops;
+
+       sk->sk_backlog_rcv = pppol2tp_recv_core;
+       sk->sk_protocol    = PX_PROTO_OL2TP;
+       sk->sk_family      = PF_PPPOX;
+       sk->sk_state       = PPPOX_NONE;
+       sk->sk_type        = SOCK_STREAM;
+       sk->sk_destruct    = pppol2tp_session_destruct;
+
+       error = 0;
+
+out:
+       return error;
+}
+
+/* connect() handler. Attach a PPPoX socket to a tunnel UDP socket
+ */
+static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
+                           int sockaddr_len, int flags)
+{
+       struct sock *sk = sock->sk;
+       struct sockaddr_pppol2tp *sp = (struct sockaddr_pppol2tp *) uservaddr;
+       struct pppox_sock *po = pppox_sk(sk);
+       struct sock *tunnel_sock = NULL;
+       struct pppol2tp_session *session = NULL;
+       struct pppol2tp_tunnel *tunnel;
+       struct dst_entry *dst;
+       int error = 0;
+
+       lock_sock(sk);
+
+       error = -EINVAL;
+       if (sp->sa_protocol != PX_PROTO_OL2TP)
+               goto end;
+
+       /* Check for already bound sockets */
+       error = -EBUSY;
+       if (sk->sk_state & PPPOX_CONNECTED)
+               goto end;
+
+       /* We don't supporting rebinding anyway */
+       error = -EALREADY;
+       if (sk->sk_user_data)
+               goto end; /* socket is already attached */
+
+       /* Don't bind if s_tunnel is 0 */
+       error = -EINVAL;
+       if (sp->pppol2tp.s_tunnel == 0)
+               goto end;
+
+       /* Special case: prepare tunnel socket if s_session and
+        * d_session is 0. Otherwise look up tunnel using supplied
+        * tunnel id.
+        */
+       if ((sp->pppol2tp.s_session == 0) && (sp->pppol2tp.d_session == 0)) {
+               tunnel_sock = pppol2tp_prepare_tunnel_socket(sp->pppol2tp.fd,
+                                                            sp->pppol2tp.s_tunnel,
+                                                            &error);
+               if (tunnel_sock == NULL)
+                       goto end;
+
+               tunnel = tunnel_sock->sk_user_data;
+       } else {
+               tunnel = pppol2tp_tunnel_find(sp->pppol2tp.s_tunnel);
+
+               /* Error if we can't find the tunnel */
+               error = -ENOENT;
+               if (tunnel == NULL)
+                       goto end;
+
+               tunnel_sock = tunnel->sock;
+       }
+
+       /* Check that this session doesn't already exist */
+       error = -EEXIST;
+       session = pppol2tp_session_find(tunnel, sp->pppol2tp.s_session);
+       if (session != NULL)
+               goto end;
+
+       /* Allocate and initialize a new session context. */
+       session = kzalloc(sizeof(struct pppol2tp_session), GFP_KERNEL);
+       if (session == NULL) {
+               error = -ENOMEM;
+               goto end;
+       }
+
+       skb_queue_head_init(&session->reorder_q);
+
+       session->magic       = L2TP_SESSION_MAGIC;
+       session->owner       = current->pid;
+       session->sock        = sk;
+       session->tunnel      = tunnel;
+       session->tunnel_sock = tunnel_sock;
+       session->tunnel_addr = sp->pppol2tp;
+       sprintf(&session->name[0], "sess %hu/%hu",
+               session->tunnel_addr.s_tunnel,
+               session->tunnel_addr.s_session);
+
+       session->stats.tunnel_id  = session->tunnel_addr.s_tunnel;
+       session->stats.session_id = session->tunnel_addr.s_session;
+
+       INIT_HLIST_NODE(&session->hlist);
+
+       /* Inherit debug options from tunnel */
+       session->debug = tunnel->debug;
+
+       /* Default MTU must allow space for UDP/L2TP/PPP
+        * headers.
+        */
+       session->mtu = session->mru = 1500 - PPPOL2TP_HEADER_OVERHEAD;
+
+       /* If PMTU discovery was enabled, use the MTU that was discovered */
+       dst = sk_dst_get(sk);
+       if (dst != NULL) {
+               u32 pmtu = dst_mtu(__sk_dst_get(sk));
+               if (pmtu != 0)
+                       session->mtu = session->mru = pmtu -
+                               PPPOL2TP_HEADER_OVERHEAD;
+               dst_release(dst);
+       }
+
+       /* Special case: if source & dest session_id == 0x0000, this socket is
+        * being created to manage the tunnel. Don't add the session to the
+        * session hash list, just set up the internal context for use by
+        * ioctl() and sockopt() handlers.
+        */
+       if ((session->tunnel_addr.s_session == 0) &&
+           (session->tunnel_addr.d_session == 0)) {
+               error = 0;
+               sk->sk_user_data = session;
+               goto out_no_ppp;
+       }
+
+       /* Get tunnel context from the tunnel socket */
+       tunnel = pppol2tp_sock_to_tunnel(tunnel_sock);
+       if (tunnel == NULL) {
+               error = -EBADF;
+               goto end;
+       }
+
+       /* Right now, because we don't have a way to push the incoming skb's
+        * straight through the UDP layer, the only header we need to worry
+        * about is the L2TP header. This size is different depending on
+        * whether sequence numbers are enabled for the data channel.
+        */
+       po->chan.hdrlen = PPPOL2TP_L2TP_HDR_SIZE_NOSEQ;
+
+       po->chan.private = sk;
+       po->chan.ops     = &pppol2tp_chan_ops;
+       po->chan.mtu     = session->mtu;
+
+       error = ppp_register_channel(&po->chan);
+       if (error)
+               goto end;
+
+       /* This is how we get the session context from the socket. */
+       sk->sk_user_data = session;
+
+       /* Add session to the tunnel's hash list */
+       write_lock(&tunnel->hlist_lock);
+       hlist_add_head(&session->hlist,
+                      pppol2tp_session_id_hash(tunnel,
+                                               session->tunnel_addr.s_session));
+       write_unlock(&tunnel->hlist_lock);
+
+       atomic_inc(&pppol2tp_session_count);
+
+out_no_ppp:
+       pppol2tp_tunnel_inc_refcount(tunnel);
+       sk->sk_state = PPPOX_CONNECTED;
+       PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+              "%s: created\n", session->name);
+
+end:
+       release_sock(sk);
+
+       if (error != 0)
+               PRINTK(session ? session->debug : -1, PPPOL2TP_MSG_CONTROL, KERN_WARNING,
+                      "%s: connect failed: %d\n", session->name, error);
+
+       return error;
+}
+
+/* getname() support.
+ */
+static int pppol2tp_getname(struct socket *sock, struct sockaddr *uaddr,
+                           int *usockaddr_len, int peer)
+{
+       int len = sizeof(struct sockaddr_pppol2tp);
+       struct sockaddr_pppol2tp sp;
+       int error = 0;
+       struct pppol2tp_session *session;
+
+       error = -ENOTCONN;
+       if (sock->sk->sk_state != PPPOX_CONNECTED)
+               goto end;
+
+       session = pppol2tp_sock_to_session(sock->sk);
+       if (session == NULL) {
+               error = -EBADF;
+               goto end;
+       }
+
+       sp.sa_family    = AF_PPPOX;
+       sp.sa_protocol  = PX_PROTO_OL2TP;
+       memcpy(&sp.pppol2tp, &session->tunnel_addr,
+              sizeof(struct pppol2tp_addr));
+
+       memcpy(uaddr, &sp, len);
+
+       *usockaddr_len = len;
+
+       error = 0;
+
+end:
+       return error;
+}
+
+/****************************************************************************
+ * ioctl() handlers.
+ *
+ * The PPPoX socket is created for L2TP sessions: tunnels have their own UDP
+ * sockets. However, in order to control kernel tunnel features, we allow
+ * userspace to create a special "tunnel" PPPoX socket which is used for
+ * control only.  Tunnel PPPoX sockets have session_id == 0 and simply allow
+ * the user application to issue L2TP setsockopt(), getsockopt() and ioctl()
+ * calls.
+ ****************************************************************************/
+
+/* Session ioctl helper.
+ */
+static int pppol2tp_session_ioctl(struct pppol2tp_session *session,
+                                 unsigned int cmd, unsigned long arg)
+{
+       struct ifreq ifr;
+       int err = 0;
+       struct sock *sk = session->sock;
+       int val = (int) arg;
+
+       PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_DEBUG,
+              "%s: pppol2tp_session_ioctl(cmd=%#x, arg=%#lx)\n",
+              session->name, cmd, arg);
+
+       sock_hold(sk);
+
+       switch (cmd) {
+       case SIOCGIFMTU:
+               err = -ENXIO;
+               if (!(sk->sk_state & PPPOX_CONNECTED))
+                       break;
+
+               err = -EFAULT;
+               if (copy_from_user(&ifr, (void __user *) arg, sizeof(struct ifreq)))
+                       break;
+               ifr.ifr_mtu = session->mtu;
+               if (copy_to_user((void __user *) arg, &ifr, sizeof(struct ifreq)))
+                       break;
+
+               PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+                      "%s: get mtu=%d\n", session->name, session->mtu);
+               err = 0;
+               break;
+
+       case SIOCSIFMTU:
+               err = -ENXIO;
+               if (!(sk->sk_state & PPPOX_CONNECTED))
+                       break;
+
+               err = -EFAULT;
+               if (copy_from_user(&ifr, (void __user *) arg, sizeof(struct ifreq)))
+                       break;
+
+               session->mtu = ifr.ifr_mtu;
+
+               PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+                      "%s: set mtu=%d\n", session->name, session->mtu);
+               err = 0;
+               break;
+
+       case PPPIOCGMRU:
+               err = -ENXIO;
+               if (!(sk->sk_state & PPPOX_CONNECTED))
+                       break;
+
+               err = -EFAULT;
+               if (put_user(session->mru, (int __user *) arg))
+                       break;
+
+               PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+                      "%s: get mru=%d\n", session->name, session->mru);
+               err = 0;
+               break;
+
+       case PPPIOCSMRU:
+               err = -ENXIO;
+               if (!(sk->sk_state & PPPOX_CONNECTED))
+                       break;
+
+               err = -EFAULT;
+               if (get_user(val,(int __user *) arg))
+                       break;
+
+               session->mru = val;
+               PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+                      "%s: set mru=%d\n", session->name, session->mru);
+               err = 0;
+               break;
+
+       case PPPIOCGFLAGS:
+               err = -EFAULT;
+               if (put_user(session->flags, (int __user *) arg))
+                       break;
+
+               PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+                      "%s: get flags=%d\n", session->name, session->flags);
+               err = 0;
+               break;
+
+       case PPPIOCSFLAGS:
+               err = -EFAULT;
+               if (get_user(val, (int __user *) arg))
+                       break;
+               session->flags = val;
+               PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+                      "%s: set flags=%d\n", session->name, session->flags);
+               err = 0;
+               break;
+
+       case PPPIOCGL2TPSTATS:
+               err = -ENXIO;
+               if (!(sk->sk_state & PPPOX_CONNECTED))
+                       break;
+
+               if (copy_to_user((void __user *) arg, &session->stats,
+                                sizeof(session->stats)))
+                       break;
+               PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+                      "%s: get L2TP stats\n", session->name);
+               err = 0;
+               break;
+
+       default:
+               err = -ENOSYS;
+               break;
+       }
+
+       sock_put(sk);
+
+       return err;
+}
+
+/* Tunnel ioctl helper.
+ *
+ * Note the special handling for PPPIOCGL2TPSTATS below. If the ioctl data
+ * specifies a session_id, the session ioctl handler is called. This allows an
+ * application to retrieve session stats via a tunnel socket.
+ */
+static int pppol2tp_tunnel_ioctl(struct pppol2tp_tunnel *tunnel,
+                                unsigned int cmd, unsigned long arg)
+{
+       int err = 0;
+       struct sock *sk = tunnel->sock;
+       struct pppol2tp_ioc_stats stats_req;
+
+       PRINTK(tunnel->debug, PPPOL2TP_MSG_CONTROL, KERN_DEBUG,
+              "%s: pppol2tp_tunnel_ioctl(cmd=%#x, arg=%#lx)\n", tunnel->name,
+              cmd, arg);
+
+       sock_hold(sk);
+
+       switch (cmd) {
+       case PPPIOCGL2TPSTATS:
+               err = -ENXIO;
+               if (!(sk->sk_state & PPPOX_CONNECTED))
+                       break;
+
+               if (copy_from_user(&stats_req, (void __user *) arg,
+                                  sizeof(stats_req))) {
+                       err = -EFAULT;
+                       break;
+               }
+               if (stats_req.session_id != 0) {
+                       /* resend to session ioctl handler */
+                       struct pppol2tp_session *session =
+                               pppol2tp_session_find(tunnel, stats_req.session_id);
+                       if (session != NULL)
+                               err = pppol2tp_session_ioctl(session, cmd, arg);
+                       else
+                               err = -EBADR;
+                       break;
+               }
+#ifdef CONFIG_XFRM
+               tunnel->stats.using_ipsec = (sk->sk_policy[0] || sk->sk_policy[1]) ? 1 : 0;
+#endif
+               if (copy_to_user((void __user *) arg, &tunnel->stats,
+                                sizeof(tunnel->stats))) {
+                       err = -EFAULT;
+                       break;
+               }
+               PRINTK(tunnel->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+                      "%s: get L2TP stats\n", tunnel->name);
+               err = 0;
+               break;
+
+       default:
+               err = -ENOSYS;
+               break;
+       }
+
+       sock_put(sk);
+
+       return err;
+}
+
+/* Main ioctl() handler.
+ * Dispatch to tunnel or session helpers depending on the socket.
+ */
+static int pppol2tp_ioctl(struct socket *sock, unsigned int cmd,
+                         unsigned long arg)
+{
+       struct sock *sk = sock->sk;
+       struct pppol2tp_session *session;
+       struct pppol2tp_tunnel *tunnel;
+       int err;
+
+       if (!sk)
+               return 0;
+
+       err = -EBADF;
+       if (sock_flag(sk, SOCK_DEAD) != 0)
+               goto end;
+
+       err = -ENOTCONN;
+       if ((sk->sk_user_data == NULL) ||
+           (!(sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND))))
+               goto end;
+
+       /* Get session context from the socket */
+       err = -EBADF;
+       session = pppol2tp_sock_to_session(sk);
+       if (session == NULL)
+               goto end;
+
+       /* Special case: if session's session_id is zero, treat ioctl as a
+        * tunnel ioctl
+        */
+       if ((session->tunnel_addr.s_session == 0) &&
+           (session->tunnel_addr.d_session == 0)) {
+               err = -EBADF;
+               tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock);
+               if (tunnel == NULL)
+                       goto end;
+
+               err = pppol2tp_tunnel_ioctl(tunnel, cmd, arg);
+               goto end;
+       }
+
+       err = pppol2tp_session_ioctl(session, cmd, arg);
+
+end:
+       return err;
+}
+
+/*****************************************************************************
+ * setsockopt() / getsockopt() support.
+ *
+ * The PPPoX socket is created for L2TP sessions: tunnels have their own UDP
+ * sockets. In order to control kernel tunnel features, we allow userspace to
+ * create a special "tunnel" PPPoX socket which is used for control only.
+ * Tunnel PPPoX sockets have session_id == 0 and simply allow the user
+ * application to issue L2TP setsockopt(), getsockopt() and ioctl() calls.
+ *****************************************************************************/
+
+/* Tunnel setsockopt() helper.
+ */
+static int pppol2tp_tunnel_setsockopt(struct sock *sk,
+                                     struct pppol2tp_tunnel *tunnel,
+                                     int optname, int val)
+{
+       int err = 0;
+
+       switch (optname) {
+       case PPPOL2TP_SO_DEBUG:
+               tunnel->debug = val;
+               PRINTK(tunnel->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+                      "%s: set debug=%x\n", tunnel->name, tunnel->debug);
+               break;
+
+       default:
+               err = -ENOPROTOOPT;
+               break;
+       }
+
+       return err;
+}
+
+/* Session setsockopt helper.
+ */
+static int pppol2tp_session_setsockopt(struct sock *sk,
+                                      struct pppol2tp_session *session,
+                                      int optname, int val)
+{
+       int err = 0;
+
+       switch (optname) {
+       case PPPOL2TP_SO_RECVSEQ:
+               if ((val != 0) && (val != 1)) {
+                       err = -EINVAL;
+                       break;
+               }
+               session->recv_seq = val ? -1 : 0;
+               PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+                      "%s: set recv_seq=%d\n", session->name,
+                      session->recv_seq);
+               break;
+
+       case PPPOL2TP_SO_SENDSEQ:
+               if ((val != 0) && (val != 1)) {
+                       err = -EINVAL;
+                       break;
+               }
+               session->send_seq = val ? -1 : 0;
+               {
+                       struct sock *ssk      = session->sock;
+                       struct pppox_sock *po = pppox_sk(ssk);
+                       po->chan.hdrlen = val ? PPPOL2TP_L2TP_HDR_SIZE_SEQ :
+                               PPPOL2TP_L2TP_HDR_SIZE_NOSEQ;
+               }
+               PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+                      "%s: set send_seq=%d\n", session->name, session->send_seq);
+               break;
+
+       case PPPOL2TP_SO_LNSMODE:
+               if ((val != 0) && (val != 1)) {
+                       err = -EINVAL;
+                       break;
+               }
+               session->lns_mode = val ? -1 : 0;
+               PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+                      "%s: set lns_mode=%d\n", session->name,
+                      session->lns_mode);
+               break;
+
+       case PPPOL2TP_SO_DEBUG:
+               session->debug = val;
+               PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+                      "%s: set debug=%x\n", session->name, session->debug);
+               break;
+
+       case PPPOL2TP_SO_REORDERTO:
+               session->reorder_timeout = msecs_to_jiffies(val);
+               PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+                      "%s: set reorder_timeout=%d\n", session->name,
+                      session->reorder_timeout);
+               break;
+
+       default:
+               err = -ENOPROTOOPT;
+               break;
+       }
+
+       return err;
+}
+
+/* Main setsockopt() entry point.
+ * Does API checks, then calls either the tunnel or session setsockopt
+ * handler, according to whether the PPPoL2TP socket is a for a regular
+ * session or the special tunnel type.
+ */
+static int pppol2tp_setsockopt(struct socket *sock, int level, int optname,
+                              char __user *optval, int optlen)
+{
+       struct sock *sk = sock->sk;
+       struct pppol2tp_session *session = sk->sk_user_data;
+       struct pppol2tp_tunnel *tunnel;
+       int val;
+       int err;
+
+       if (level != SOL_PPPOL2TP)
+               return udp_prot.setsockopt(sk, level, optname, optval, optlen);
+
+       if (optlen < sizeof(int))
+               return -EINVAL;
+
+       if (get_user(val, (int __user *)optval))
+               return -EFAULT;
+
+       err = -ENOTCONN;
+       if (sk->sk_user_data == NULL)
+               goto end;
+
+       /* Get session context from the socket */
+       err = -EBADF;
+       session = pppol2tp_sock_to_session(sk);
+       if (session == NULL)
+               goto end;
+
+       /* Special case: if session_id == 0x0000, treat as operation on tunnel
+        */
+       if ((session->tunnel_addr.s_session == 0) &&
+           (session->tunnel_addr.d_session == 0)) {
+               err = -EBADF;
+               tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock);
+               if (tunnel == NULL)
+                       goto end;
+
+               err = pppol2tp_tunnel_setsockopt(sk, tunnel, optname, val);
+       } else
+               err = pppol2tp_session_setsockopt(sk, session, optname, val);
+
+       err = 0;
+
+end:
+       return err;
+}
+
+/* Tunnel getsockopt helper. Called with sock locked.
+ */
+static int pppol2tp_tunnel_getsockopt(struct sock *sk,
+                                     struct pppol2tp_tunnel *tunnel,
+                                     int optname, int __user *val)
+{
+       int err = 0;
+
+       switch (optname) {
+       case PPPOL2TP_SO_DEBUG:
+               *val = tunnel->debug;
+               PRINTK(tunnel->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+                      "%s: get debug=%x\n", tunnel->name, tunnel->debug);
+               break;
+
+       default:
+               err = -ENOPROTOOPT;
+               break;
+       }
+
+       return err;
+}
+
+/* Session getsockopt helper. Called with sock locked.
+ */
+static int pppol2tp_session_getsockopt(struct sock *sk,
+                                      struct pppol2tp_session *session,
+                                      int optname, int __user *val)
+{
+       int err = 0;
+
+       switch (optname) {
+       case PPPOL2TP_SO_RECVSEQ:
+               *val = session->recv_seq;
+               PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+                      "%s: get recv_seq=%d\n", session->name, *val);
+               break;
+
+       case PPPOL2TP_SO_SENDSEQ:
+               *val = session->send_seq;
+               PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+                      "%s: get send_seq=%d\n", session->name, *val);
+               break;
+
+       case PPPOL2TP_SO_LNSMODE:
+               *val = session->lns_mode;
+               PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+                      "%s: get lns_mode=%d\n", session->name, *val);
+               break;
+
+       case PPPOL2TP_SO_DEBUG:
+               *val = session->debug;
+               PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+                      "%s: get debug=%d\n", session->name, *val);
+               break;
+
+       case PPPOL2TP_SO_REORDERTO:
+               *val = (int) jiffies_to_msecs(session->reorder_timeout);
+               PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+                      "%s: get reorder_timeout=%d\n", session->name, *val);
+               break;
+
+       default:
+               err = -ENOPROTOOPT;
+       }
+
+       return err;
+}
+
+/* Main getsockopt() entry point.
+ * Does API checks, then calls either the tunnel or session getsockopt
+ * handler, according to whether the PPPoX socket is a for a regular session
+ * or the special tunnel type.
+ */
+static int pppol2tp_getsockopt(struct socket *sock, int level,
+                              int optname, char __user *optval, int __user *optlen)
+{
+       struct sock *sk = sock->sk;
+       struct pppol2tp_session *session = sk->sk_user_data;
+       struct pppol2tp_tunnel *tunnel;
+       int val, len;
+       int err;
+
+       if (level != SOL_PPPOL2TP)
+               return udp_prot.getsockopt(sk, level, optname, optval, optlen);
+
+       if (get_user(len, (int __user *) optlen))
+               return -EFAULT;
+
+       len = min_t(unsigned int, len, sizeof(int));
+
+       if (len < 0)
+               return -EINVAL;
+
+       err = -ENOTCONN;
+       if (sk->sk_user_data == NULL)
+               goto end;
+
+       /* Get the session context */
+       err = -EBADF;
+       session = pppol2tp_sock_to_session(sk);
+       if (session == NULL)
+               goto end;
+
+       /* Special case: if session_id == 0x0000, treat as operation on tunnel */
+       if ((session->tunnel_addr.s_session == 0) &&
+           (session->tunnel_addr.d_session == 0)) {
+               err = -EBADF;
+               tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock);
+               if (tunnel == NULL)
+                       goto end;
+
+               err = pppol2tp_tunnel_getsockopt(sk, tunnel, optname, &val);
+       } else
+               err = pppol2tp_session_getsockopt(sk, session, optname, &val);
+
+       err = -EFAULT;
+       if (put_user(len, (int __user *) optlen))
+               goto end;
+
+       if (copy_to_user((void __user *) optval, &val, len))
+               goto end;
+
+       err = 0;
+end:
+       return err;
+}
+
+/*****************************************************************************
+ * /proc filesystem for debug
+ *****************************************************************************/
+
+#ifdef CONFIG_PROC_FS
+
+#include <linux/seq_file.h>
+
+struct pppol2tp_seq_data {
+       struct pppol2tp_tunnel *tunnel; /* current tunnel */
+       struct pppol2tp_session *session; /* NULL means get first session in tunnel */
+};
+
+static struct pppol2tp_session *next_session(struct pppol2tp_tunnel *tunnel, struct pppol2tp_session *curr)
+{
+       struct pppol2tp_session *session = NULL;
+       struct hlist_node *walk;
+       int found = 0;
+       int next = 0;
+       int i;
+
+       read_lock(&tunnel->hlist_lock);
+       for (i = 0; i < PPPOL2TP_HASH_SIZE; i++) {
+               hlist_for_each_entry(session, walk, &tunnel->session_hlist[i], hlist) {
+                       if (curr == NULL) {
+                               found = 1;
+                               goto out;
+                       }
+                       if (session == curr) {
+                               next = 1;
+                               continue;
+                       }
+                       if (next) {
+                               found = 1;
+                               goto out;
+                       }
+               }
+       }
+out:
+       read_unlock(&tunnel->hlist_lock);
+       if (!found)
+               session = NULL;
+
+       return session;
+}
+
+static struct pppol2tp_tunnel *next_tunnel(struct pppol2tp_tunnel *curr)
+{
+       struct pppol2tp_tunnel *tunnel = NULL;
+
+       read_lock(&pppol2tp_tunnel_list_lock);
+       if (list_is_last(&curr->list, &pppol2tp_tunnel_list)) {
+               goto out;
+       }
+       tunnel = list_entry(curr->list.next, struct pppol2tp_tunnel, list);
+out:
+       read_unlock(&pppol2tp_tunnel_list_lock);
+
+       return tunnel;
+}
+
+static void *pppol2tp_seq_start(struct seq_file *m, loff_t *offs)
+{
+       struct pppol2tp_seq_data *pd = SEQ_START_TOKEN;
+       loff_t pos = *offs;
+
+       if (!pos)
+               goto out;
+
+       BUG_ON(m->private == NULL);
+       pd = m->private;
+
+       if (pd->tunnel == NULL) {
+               if (!list_empty(&pppol2tp_tunnel_list))
+                       pd->tunnel = list_entry(pppol2tp_tunnel_list.next, struct pppol2tp_tunnel, list);
+       } else {
+               pd->session = next_session(pd->tunnel, pd->session);
+               if (pd->session == NULL) {
+                       pd->tunnel = next_tunnel(pd->tunnel);
+               }
+       }
+
+       /* NULL tunnel and session indicates end of list */
+       if ((pd->tunnel == NULL) && (pd->session == NULL))
+               pd = NULL;
+
+out:
+       return pd;
+}
+
+static void *pppol2tp_seq_next(struct seq_file *m, void *v, loff_t *pos)
+{
+       (*pos)++;
+       return NULL;
+}
+
+static void pppol2tp_seq_stop(struct seq_file *p, void *v)
+{
+       /* nothing to do */
+}
+
+static void pppol2tp_seq_tunnel_show(struct seq_file *m, void *v)
+{
+       struct pppol2tp_tunnel *tunnel = v;
+
+       seq_printf(m, "\nTUNNEL '%s', %c %d\n",
+                  tunnel->name,
+                  (tunnel == tunnel->sock->sk_user_data) ? 'Y':'N',
+                  atomic_read(&tunnel->ref_count) - 1);
+       seq_printf(m, " %08x %llu/%llu/%llu %llu/%llu/%llu\n",
+                  tunnel->debug,
+                  tunnel->stats.tx_packets, tunnel->stats.tx_bytes,
+                  tunnel->stats.tx_errors,
+                  tunnel->stats.rx_packets, tunnel->stats.rx_bytes,
+                  tunnel->stats.rx_errors);
+}
+
+static void pppol2tp_seq_session_show(struct seq_file *m, void *v)
+{
+       struct pppol2tp_session *session = v;
+
+       seq_printf(m, "  SESSION '%s' %08X/%d %04X/%04X -> "
+                  "%04X/%04X %d %c\n",
+                  session->name,
+                  ntohl(session->tunnel_addr.addr.sin_addr.s_addr),
+                  ntohs(session->tunnel_addr.addr.sin_port),
+                  session->tunnel_addr.s_tunnel,
+                  session->tunnel_addr.s_session,
+                  session->tunnel_addr.d_tunnel,
+                  session->tunnel_addr.d_session,
+                  session->sock->sk_state,
+                  (session == session->sock->sk_user_data) ?
+                  'Y' : 'N');
+       seq_printf(m, "   %d/%d/%c/%c/%s %08x %u\n",
+                  session->mtu, session->mru,
+                  session->recv_seq ? 'R' : '-',
+                  session->send_seq ? 'S' : '-',
+                  session->lns_mode ? "LNS" : "LAC",
+                  session->debug,
+                  jiffies_to_msecs(session->reorder_timeout));
+       seq_printf(m, "   %hu/%hu %llu/%llu/%llu %llu/%llu/%llu\n",
+                  session->nr, session->ns,
+                  session->stats.tx_packets,
+                  session->stats.tx_bytes,
+                  session->stats.tx_errors,
+                  session->stats.rx_packets,
+                  session->stats.rx_bytes,
+                  session->stats.rx_errors);
+}
+
+static int pppol2tp_seq_show(struct seq_file *m, void *v)
+{
+       struct pppol2tp_seq_data *pd = v;
+
+       /* display header on line 1 */
+       if (v == SEQ_START_TOKEN) {
+               seq_puts(m, "PPPoL2TP driver info, " PPPOL2TP_DRV_VERSION "\n");
+               seq_puts(m, "TUNNEL name, user-data-ok session-count\n");
+               seq_puts(m, " debug tx-pkts/bytes/errs rx-pkts/bytes/errs\n");
+               seq_puts(m, "  SESSION name, addr/port src-tid/sid "
+                        "dest-tid/sid state user-data-ok\n");
+               seq_puts(m, "   mtu/mru/rcvseq/sendseq/lns debug reorderto\n");
+               seq_puts(m, "   nr/ns tx-pkts/bytes/errs rx-pkts/bytes/errs\n");
+               goto out;
+       }
+
+       /* Show the tunnel or session context.
+        */
+       if (pd->session == NULL)
+               pppol2tp_seq_tunnel_show(m, pd->tunnel);
+       else
+               pppol2tp_seq_session_show(m, pd->session);
+
+out:
+       return 0;
+}
+
+static struct seq_operations pppol2tp_seq_ops = {
+       .start          = pppol2tp_seq_start,
+       .next           = pppol2tp_seq_next,
+       .stop           = pppol2tp_seq_stop,
+       .show           = pppol2tp_seq_show,
+};
+
+/* Called when our /proc file is opened. We allocate data for use when
+ * iterating our tunnel / session contexts and store it in the private
+ * data of the seq_file.
+ */
+static int pppol2tp_proc_open(struct inode *inode, struct file *file)
+{
+       struct seq_file *m;
+       struct pppol2tp_seq_data *pd;
+       int ret = 0;
+
+       ret = seq_open(file, &pppol2tp_seq_ops);
+       if (ret < 0)
+               goto out;
+
+       m = file->private_data;
+
+       /* Allocate and fill our proc_data for access later */
+       ret = -ENOMEM;
+       m->private = kzalloc(sizeof(struct pppol2tp_seq_data), GFP_KERNEL);
+       if (m->private == NULL)
+               goto out;
+
+       pd = m->private;
+       ret = 0;
+
+out:
+       return ret;
+}
+
+/* Called when /proc file access completes.
+ */
+static int pppol2tp_proc_release(struct inode *inode, struct file *file)
+{
+       struct seq_file *m = (struct seq_file *)file->private_data;
+
+       kfree(m->private);
+       m->private = NULL;
+
+       return seq_release(inode, file);
+}
+
+static struct file_operations pppol2tp_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = pppol2tp_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = pppol2tp_proc_release,
+};
+
+static struct proc_dir_entry *pppol2tp_proc;
+
+#endif /* CONFIG_PROC_FS */
+
+/*****************************************************************************
+ * Init and cleanup
+ *****************************************************************************/
+
+static struct proto_ops pppol2tp_ops = {
+       .family         = AF_PPPOX,
+       .owner          = THIS_MODULE,
+       .release        = pppol2tp_release,
+       .bind           = sock_no_bind,
+       .connect        = pppol2tp_connect,
+       .socketpair     = sock_no_socketpair,
+       .accept         = sock_no_accept,
+       .getname        = pppol2tp_getname,
+       .poll           = datagram_poll,
+       .listen         = sock_no_listen,
+       .shutdown       = sock_no_shutdown,
+       .setsockopt     = pppol2tp_setsockopt,
+       .getsockopt     = pppol2tp_getsockopt,
+       .sendmsg        = pppol2tp_sendmsg,
+       .recvmsg        = pppol2tp_recvmsg,
+       .mmap           = sock_no_mmap,
+       .ioctl          = pppox_ioctl,
+};
+
+static struct pppox_proto pppol2tp_proto = {
+       .create         = pppol2tp_create,
+       .ioctl          = pppol2tp_ioctl
+};
+
+static int __init pppol2tp_init(void)
+{
+       int err;
+
+       err = proto_register(&pppol2tp_sk_proto, 0);
+       if (err)
+               goto out;
+       err = register_pppox_proto(PX_PROTO_OL2TP, &pppol2tp_proto);
+       if (err)
+               goto out_unregister_pppol2tp_proto;
+
+#ifdef CONFIG_PROC_FS
+       pppol2tp_proc = create_proc_entry("pppol2tp", 0, proc_net);
+       if (!pppol2tp_proc) {
+               err = -ENOMEM;
+               goto out_unregister_pppox_proto;
+       }
+       pppol2tp_proc->proc_fops = &pppol2tp_proc_fops;
+#endif /* CONFIG_PROC_FS */
+       printk(KERN_INFO "PPPoL2TP kernel driver, %s\n",
+              PPPOL2TP_DRV_VERSION);
+
+out:
+       return err;
+
+out_unregister_pppox_proto:
+       unregister_pppox_proto(PX_PROTO_OL2TP);
+out_unregister_pppol2tp_proto:
+       proto_unregister(&pppol2tp_sk_proto);
+       goto out;
+}
+
+static void __exit pppol2tp_exit(void)
+{
+       unregister_pppox_proto(PX_PROTO_OL2TP);
+
+#ifdef CONFIG_PROC_FS
+       remove_proc_entry("pppol2tp", proc_net);
+#endif
+       proto_unregister(&pppol2tp_sk_proto);
+}
+
+module_init(pppol2tp_init);
+module_exit(pppol2tp_exit);
+
+MODULE_AUTHOR("Martijn van Oosterhout <kleptog@svana.org>,"
+             "James Chapman <jchapman@katalix.com>");
+MODULE_DESCRIPTION("PPP over L2TP over UDP");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(PPPOL2TP_DRV_VERSION);
diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c
new file mode 100644 (file)
index 0000000..08d2506
--- /dev/null
@@ -0,0 +1,1576 @@
+/*
+ *  PS3 gelic network driver.
+ *
+ * Copyright (C) 2007 Sony Computer Entertainment Inc.
+ * Copyright 2006, 2007 Sony Corporation
+ *
+ * This file is based on: spider_net.c
+ *
+ * (C) Copyright IBM Corp. 2005
+ *
+ * Authors : Utz Bacher <utz.bacher@de.ibm.com>
+ *           Jens Osterkamp <Jens.Osterkamp@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.
+ */
+
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/if_vlan.h>
+
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+
+#include <linux/dma-mapping.h>
+#include <net/checksum.h>
+#include <asm/firmware.h>
+#include <asm/ps3.h>
+#include <asm/lv1call.h>
+
+#include "ps3_gelic_net.h"
+
+#define DRV_NAME "Gelic Network Driver"
+#define DRV_VERSION "1.0"
+
+MODULE_AUTHOR("SCE Inc.");
+MODULE_DESCRIPTION("Gelic Network driver");
+MODULE_LICENSE("GPL");
+
+static inline struct device *ctodev(struct gelic_net_card *card)
+{
+       return &card->dev->core;
+}
+static inline unsigned int bus_id(struct gelic_net_card *card)
+{
+       return card->dev->bus_id;
+}
+static inline unsigned int dev_id(struct gelic_net_card *card)
+{
+       return card->dev->dev_id;
+}
+
+/* set irq_mask */
+static int gelic_net_set_irq_mask(struct gelic_net_card *card, u64 mask)
+{
+       int status;
+
+       status = lv1_net_set_interrupt_mask(bus_id(card), dev_id(card),
+                                           mask, 0);
+       if (status)
+               dev_info(ctodev(card),
+                        "lv1_net_set_interrupt_mask failed %d\n", status);
+       return status;
+}
+static inline void gelic_net_rx_irq_on(struct gelic_net_card *card)
+{
+       gelic_net_set_irq_mask(card, card->ghiintmask | GELIC_NET_RXINT);
+}
+static inline void gelic_net_rx_irq_off(struct gelic_net_card *card)
+{
+       gelic_net_set_irq_mask(card, card->ghiintmask & ~GELIC_NET_RXINT);
+}
+/**
+ * gelic_net_get_descr_status -- returns the status of a descriptor
+ * @descr: descriptor to look at
+ *
+ * returns the status as in the dmac_cmd_status field of the descriptor
+ */
+static enum gelic_net_descr_status
+gelic_net_get_descr_status(struct gelic_net_descr *descr)
+{
+       u32 cmd_status;
+
+       cmd_status = descr->dmac_cmd_status;
+       cmd_status >>= GELIC_NET_DESCR_IND_PROC_SHIFT;
+       return cmd_status;
+}
+
+/**
+ * gelic_net_set_descr_status -- sets the status of a descriptor
+ * @descr: descriptor to change
+ * @status: status to set in the descriptor
+ *
+ * changes the status to the specified value. Doesn't change other bits
+ * in the status
+ */
+static void gelic_net_set_descr_status(struct gelic_net_descr *descr,
+                                      enum gelic_net_descr_status status)
+{
+       u32 cmd_status;
+
+       /* read the status */
+       cmd_status = descr->dmac_cmd_status;
+       /* clean the upper 4 bits */
+       cmd_status &= GELIC_NET_DESCR_IND_PROC_MASKO;
+       /* add the status to it */
+       cmd_status |= ((u32)status) << GELIC_NET_DESCR_IND_PROC_SHIFT;
+       /* and write it back */
+       descr->dmac_cmd_status = cmd_status;
+       /*
+        * dma_cmd_status field is used to indicate whether the descriptor
+        * is valid or not.
+        * Usually caller of this function wants to inform that to the
+        * hardware, so we assure here the hardware sees the change.
+        */
+       wmb();
+}
+
+/**
+ * gelic_net_free_chain - free descriptor chain
+ * @card: card structure
+ * @descr_in: address of desc
+ */
+static void gelic_net_free_chain(struct gelic_net_card *card,
+                                struct gelic_net_descr *descr_in)
+{
+       struct gelic_net_descr *descr;
+
+       for (descr = descr_in; descr && descr->bus_addr; descr = descr->next) {
+               dma_unmap_single(ctodev(card), descr->bus_addr,
+                                GELIC_NET_DESCR_SIZE, DMA_BIDIRECTIONAL);
+               descr->bus_addr = 0;
+       }
+}
+
+/**
+ * gelic_net_init_chain - links descriptor chain
+ * @card: card structure
+ * @chain: address of chain
+ * @start_descr: address of descriptor array
+ * @no: number of descriptors
+ *
+ * we manage a circular list that mirrors the hardware structure,
+ * except that the hardware uses bus addresses.
+ *
+ * returns 0 on success, <0 on failure
+ */
+static int gelic_net_init_chain(struct gelic_net_card *card,
+                               struct gelic_net_descr_chain *chain,
+                               struct gelic_net_descr *start_descr, int no)
+{
+       int i;
+       struct gelic_net_descr *descr;
+
+       descr = start_descr;
+       memset(descr, 0, sizeof(*descr) * no);
+
+       /* set up the hardware pointers in each descriptor */
+       for (i = 0; i < no; i++, descr++) {
+               gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE);
+               descr->bus_addr =
+                       dma_map_single(ctodev(card), descr,
+                                      GELIC_NET_DESCR_SIZE,
+                                      DMA_BIDIRECTIONAL);
+
+               if (!descr->bus_addr)
+                       goto iommu_error;
+
+               descr->next = descr + 1;
+               descr->prev = descr - 1;
+       }
+       /* make them as ring */
+       (descr - 1)->next = start_descr;
+       start_descr->prev = (descr - 1);
+
+       /* chain bus addr of hw descriptor */
+       descr = start_descr;
+       for (i = 0; i < no; i++, descr++) {
+               descr->next_descr_addr = descr->next->bus_addr;
+       }
+
+       chain->head = start_descr;
+       chain->tail = start_descr;
+
+       /* do not chain last hw descriptor */
+       (descr - 1)->next_descr_addr = 0;
+
+       return 0;
+
+iommu_error:
+       for (i--, descr--; 0 <= i; i--, descr--)
+               if (descr->bus_addr)
+                       dma_unmap_single(ctodev(card), descr->bus_addr,
+                                        GELIC_NET_DESCR_SIZE,
+                                        DMA_BIDIRECTIONAL);
+       return -ENOMEM;
+}
+
+/**
+ * gelic_net_prepare_rx_descr - reinitializes a rx descriptor
+ * @card: card structure
+ * @descr: descriptor to re-init
+ *
+ * return 0 on succes, <0 on failure
+ *
+ * allocates a new rx skb, iommu-maps it and attaches it to the descriptor.
+ * Activate the descriptor state-wise
+ */
+static int gelic_net_prepare_rx_descr(struct gelic_net_card *card,
+                                     struct gelic_net_descr *descr)
+{
+       int offset;
+       unsigned int bufsize;
+
+       if (gelic_net_get_descr_status(descr) !=  GELIC_NET_DESCR_NOT_IN_USE) {
+               dev_info(ctodev(card), "%s: ERROR status \n", __func__);
+       }
+       /* we need to round up the buffer size to a multiple of 128 */
+       bufsize = ALIGN(GELIC_NET_MAX_MTU, GELIC_NET_RXBUF_ALIGN);
+
+       /* and we need to have it 128 byte aligned, therefore we allocate a
+        * bit more */
+       descr->skb = netdev_alloc_skb(card->netdev,
+               bufsize + GELIC_NET_RXBUF_ALIGN - 1);
+       if (!descr->skb) {
+               descr->buf_addr = 0; /* tell DMAC don't touch memory */
+               dev_info(ctodev(card),
+                        "%s:allocate skb failed !!\n", __func__);
+               return -ENOMEM;
+       }
+       descr->buf_size = bufsize;
+       descr->dmac_cmd_status = 0;
+       descr->result_size = 0;
+       descr->valid_size = 0;
+       descr->data_error = 0;
+
+       offset = ((unsigned long)descr->skb->data) &
+               (GELIC_NET_RXBUF_ALIGN - 1);
+       if (offset)
+               skb_reserve(descr->skb, GELIC_NET_RXBUF_ALIGN - offset);
+       /* io-mmu-map the skb */
+       descr->buf_addr = dma_map_single(ctodev(card), descr->skb->data,
+                                        GELIC_NET_MAX_MTU,
+                                        DMA_FROM_DEVICE);
+       if (!descr->buf_addr) {
+               dev_kfree_skb_any(descr->skb);
+               descr->skb = NULL;
+               dev_info(ctodev(card),
+                        "%s:Could not iommu-map rx buffer\n", __func__);
+               gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE);
+               return -ENOMEM;
+       } else {
+               gelic_net_set_descr_status(descr, GELIC_NET_DESCR_CARDOWNED);
+               return 0;
+       }
+}
+
+/**
+ * gelic_net_release_rx_chain - free all skb of rx descr
+ * @card: card structure
+ *
+ */
+static void gelic_net_release_rx_chain(struct gelic_net_card *card)
+{
+       struct gelic_net_descr *descr = card->rx_chain.head;
+
+       do {
+               if (descr->skb) {
+                       dma_unmap_single(ctodev(card),
+                                        descr->buf_addr,
+                                        descr->skb->len,
+                                        DMA_FROM_DEVICE);
+                       descr->buf_addr = 0;
+                       dev_kfree_skb_any(descr->skb);
+                       descr->skb = NULL;
+                       descr->dmac_cmd_status = GELIC_NET_DESCR_NOT_IN_USE;
+               }
+               descr = descr->next;
+       } while (descr != card->rx_chain.head);
+}
+
+/**
+ * gelic_net_fill_rx_chain - fills descriptors/skbs in the rx chains
+ * @card: card structure
+ *
+ * fills all descriptors in the rx chain: allocates skbs
+ * and iommu-maps them.
+ * returns 0 on success, <0 on failure
+ */
+static int gelic_net_fill_rx_chain(struct gelic_net_card *card)
+{
+       struct gelic_net_descr *descr = card->rx_chain.head;
+       int ret;
+
+       do {
+               if (!descr->skb) {
+                       ret = gelic_net_prepare_rx_descr(card, descr);
+                       if (ret)
+                               goto rewind;
+               }
+               descr = descr->next;
+       } while (descr != card->rx_chain.head);
+
+       return 0;
+rewind:
+       gelic_net_release_rx_chain(card);
+       return ret;
+}
+
+/**
+ * gelic_net_alloc_rx_skbs - allocates rx skbs in rx descriptor chains
+ * @card: card structure
+ *
+ * returns 0 on success, <0 on failure
+ */
+static int gelic_net_alloc_rx_skbs(struct gelic_net_card *card)
+{
+       struct gelic_net_descr_chain *chain;
+       int ret;
+       chain = &card->rx_chain;
+       ret = gelic_net_fill_rx_chain(card);
+       chain->head = card->rx_top->prev; /* point to the last */
+       return ret;
+}
+
+/**
+ * gelic_net_release_tx_descr - processes a used tx descriptor
+ * @card: card structure
+ * @descr: descriptor to release
+ *
+ * releases a used tx descriptor (unmapping, freeing of skb)
+ */
+static void gelic_net_release_tx_descr(struct gelic_net_card *card,
+                           struct gelic_net_descr *descr)
+{
+       struct sk_buff *skb;
+
+
+       if (descr->data_status & (1 << GELIC_NET_TXDESC_TAIL)) {
+               /* 2nd descriptor */
+               skb = descr->skb;
+               dma_unmap_single(ctodev(card), descr->buf_addr, skb->len,
+                                DMA_TO_DEVICE);
+               dev_kfree_skb_any(skb);
+       } else {
+               dma_unmap_single(ctodev(card), descr->buf_addr,
+                                descr->buf_size, DMA_TO_DEVICE);
+       }
+
+       descr->buf_addr = 0;
+       descr->buf_size = 0;
+       descr->next_descr_addr = 0;
+       descr->result_size = 0;
+       descr->valid_size = 0;
+       descr->data_status = 0;
+       descr->data_error = 0;
+       descr->skb = NULL;
+
+       /* set descr status */
+       descr->dmac_cmd_status = GELIC_NET_DMAC_CMDSTAT_NOT_IN_USE;
+}
+
+/**
+ * gelic_net_release_tx_chain - processes sent tx descriptors
+ * @card: adapter structure
+ * @stop: net_stop sequence
+ *
+ * releases the tx descriptors that gelic has finished with
+ */
+static void gelic_net_release_tx_chain(struct gelic_net_card *card, int stop)
+{
+       struct gelic_net_descr_chain *tx_chain;
+       enum gelic_net_descr_status status;
+       int release = 0;
+
+       for (tx_chain = &card->tx_chain;
+            tx_chain->head != tx_chain->tail && tx_chain->tail;
+            tx_chain->tail = tx_chain->tail->next) {
+               status = gelic_net_get_descr_status(tx_chain->tail);
+               switch (status) {
+               case GELIC_NET_DESCR_RESPONSE_ERROR:
+               case GELIC_NET_DESCR_PROTECTION_ERROR:
+               case GELIC_NET_DESCR_FORCE_END:
+                       if (printk_ratelimit())
+                               dev_info(ctodev(card),
+                                        "%s: forcing end of tx descriptor " \
+                                        "with status %x\n",
+                                        __func__, status);
+                       card->netdev_stats.tx_dropped++;
+                       break;
+
+               case GELIC_NET_DESCR_COMPLETE:
+                       card->netdev_stats.tx_packets++;
+                       card->netdev_stats.tx_bytes +=
+                               tx_chain->tail->skb->len;
+                       break;
+
+               case GELIC_NET_DESCR_CARDOWNED:
+                       /* pending tx request */
+               default:
+                       /* any other value (== GELIC_NET_DESCR_NOT_IN_USE) */
+                       goto out;
+               }
+               gelic_net_release_tx_descr(card, tx_chain->tail);
+               release = 1;
+       }
+out:
+       if (!stop && release)
+               netif_wake_queue(card->netdev);
+}
+
+/**
+ * gelic_net_set_multi - sets multicast addresses and promisc flags
+ * @netdev: interface device structure
+ *
+ * gelic_net_set_multi configures multicast addresses as needed for the
+ * netdev interface. It also sets up multicast, allmulti and promisc
+ * flags appropriately
+ */
+static void gelic_net_set_multi(struct net_device *netdev)
+{
+       struct gelic_net_card *card = netdev_priv(netdev);
+       struct dev_mc_list *mc;
+       unsigned int i;
+       uint8_t *p;
+       u64 addr;
+       int status;
+
+       /* clear all multicast address */
+       status = lv1_net_remove_multicast_address(bus_id(card), dev_id(card),
+                                                 0, 1);
+       if (status)
+               dev_err(ctodev(card),
+                       "lv1_net_remove_multicast_address failed %d\n",
+                       status);
+       /* set broadcast address */
+       status = lv1_net_add_multicast_address(bus_id(card), dev_id(card),
+                                              GELIC_NET_BROADCAST_ADDR, 0);
+       if (status)
+               dev_err(ctodev(card),
+                       "lv1_net_add_multicast_address failed, %d\n",
+                       status);
+
+       if (netdev->flags & IFF_ALLMULTI
+               || netdev->mc_count > GELIC_NET_MC_COUNT_MAX) { /* list max */
+               status = lv1_net_add_multicast_address(bus_id(card),
+                                                      dev_id(card),
+                                                      0, 1);
+               if (status)
+                       dev_err(ctodev(card),
+                               "lv1_net_add_multicast_address failed, %d\n",
+                               status);
+               return;
+       }
+
+       /* set multicast address */
+       for (mc = netdev->mc_list; mc; mc = mc->next) {
+               addr = 0;
+               p = mc->dmi_addr;
+               for (i = 0; i < ETH_ALEN; i++) {
+                       addr <<= 8;
+                       addr |= *p++;
+               }
+               status = lv1_net_add_multicast_address(bus_id(card),
+                                                      dev_id(card),
+                                                      addr, 0);
+               if (status)
+                       dev_err(ctodev(card),
+                               "lv1_net_add_multicast_address failed, %d\n",
+                               status);
+       }
+}
+
+/**
+ * gelic_net_enable_rxdmac - enables the receive DMA controller
+ * @card: card structure
+ *
+ * gelic_net_enable_rxdmac enables the DMA controller by setting RX_DMA_EN
+ * in the GDADMACCNTR register
+ */
+static inline void gelic_net_enable_rxdmac(struct gelic_net_card *card)
+{
+       int status;
+
+       status = lv1_net_start_rx_dma(bus_id(card), dev_id(card),
+                               card->rx_chain.tail->bus_addr, 0);
+       if (status)
+               dev_info(ctodev(card),
+                        "lv1_net_start_rx_dma failed, status=%d\n", status);
+}
+
+/**
+ * gelic_net_disable_rxdmac - disables the receive DMA controller
+ * @card: card structure
+ *
+ * gelic_net_disable_rxdmac terminates processing on the DMA controller by
+ * turing off DMA and issueing a force end
+ */
+static inline void gelic_net_disable_rxdmac(struct gelic_net_card *card)
+{
+       int status;
+
+       /* this hvc blocks until the DMA in progress really stopped */
+       status = lv1_net_stop_rx_dma(bus_id(card), dev_id(card), 0);
+       if (status)
+               dev_err(ctodev(card),
+                       "lv1_net_stop_rx_dma faild, %d\n", status);
+}
+
+/**
+ * gelic_net_disable_txdmac - disables the transmit DMA controller
+ * @card: card structure
+ *
+ * gelic_net_disable_txdmac terminates processing on the DMA controller by
+ * turing off DMA and issueing a force end
+ */
+static inline void gelic_net_disable_txdmac(struct gelic_net_card *card)
+{
+       int status;
+
+       /* this hvc blocks until the DMA in progress really stopped */
+       status = lv1_net_stop_tx_dma(bus_id(card), dev_id(card), 0);
+       if (status)
+               dev_err(ctodev(card),
+                       "lv1_net_stop_tx_dma faild, status=%d\n", status);
+}
+
+/**
+ * gelic_net_stop - called upon ifconfig down
+ * @netdev: interface device structure
+ *
+ * always returns 0
+ */
+static int gelic_net_stop(struct net_device *netdev)
+{
+       struct gelic_net_card *card = netdev_priv(netdev);
+
+       netif_poll_disable(netdev);
+       netif_stop_queue(netdev);
+
+       /* turn off DMA, force end */
+       gelic_net_disable_rxdmac(card);
+       gelic_net_disable_txdmac(card);
+
+       gelic_net_set_irq_mask(card, 0);
+
+       /* disconnect event port */
+       free_irq(card->netdev->irq, card->netdev);
+       ps3_sb_event_receive_port_destroy(card->dev, card->netdev->irq);
+       card->netdev->irq = NO_IRQ;
+
+       netif_carrier_off(netdev);
+
+       /* release chains */
+       gelic_net_release_tx_chain(card, 1);
+       gelic_net_release_rx_chain(card);
+
+       gelic_net_free_chain(card, card->tx_top);
+       gelic_net_free_chain(card, card->rx_top);
+
+       return 0;
+}
+
+/**
+ * gelic_net_get_next_tx_descr - returns the next available tx descriptor
+ * @card: device structure to get descriptor from
+ *
+ * returns the address of the next descriptor, or NULL if not available.
+ */
+static struct gelic_net_descr *
+gelic_net_get_next_tx_descr(struct gelic_net_card *card)
+{
+       if (!card->tx_chain.head)
+               return NULL;
+       /*  see if we can two consecutive free descrs */
+       if (card->tx_chain.tail != card->tx_chain.head->next &&
+           gelic_net_get_descr_status(card->tx_chain.head) ==
+           GELIC_NET_DESCR_NOT_IN_USE &&
+           card->tx_chain.tail != card->tx_chain.head->next->next &&
+           gelic_net_get_descr_status(card->tx_chain.head->next) ==
+            GELIC_NET_DESCR_NOT_IN_USE )
+               return card->tx_chain.head;
+       else
+               return NULL;
+
+}
+
+/**
+ * gelic_net_set_txdescr_cmdstat - sets the tx descriptor command field
+ * @descr: descriptor structure to fill out
+ * @skb: packet to consider
+ * @middle: middle of frame
+ *
+ * fills out the command and status field of the descriptor structure,
+ * depending on hardware checksum settings. This function assumes a wmb()
+ * has executed before.
+ */
+static void gelic_net_set_txdescr_cmdstat(struct gelic_net_descr *descr,
+                                         struct sk_buff *skb, int middle)
+{
+       u32 eofr;
+
+       if (middle)
+               eofr = 0;
+       else
+               eofr = GELIC_NET_DMAC_CMDSTAT_END_FRAME;
+
+       if (skb->ip_summed != CHECKSUM_PARTIAL)
+               descr->dmac_cmd_status = GELIC_NET_DMAC_CMDSTAT_NOCS | eofr;
+       else {
+               /* is packet ip?
+                * if yes: tcp? udp? */
+               if (skb->protocol == htons(ETH_P_IP)) {
+                       if (ip_hdr(skb)->protocol == IPPROTO_TCP)
+                               descr->dmac_cmd_status =
+                                       GELIC_NET_DMAC_CMDSTAT_TCPCS | eofr;
+                       else if (ip_hdr(skb)->protocol == IPPROTO_UDP)
+                               descr->dmac_cmd_status =
+                                       GELIC_NET_DMAC_CMDSTAT_UDPCS | eofr;
+                       else    /*
+                                * the stack should checksum non-tcp and non-udp
+                                * packets on his own: NETIF_F_IP_CSUM
+                                */
+                               descr->dmac_cmd_status =
+                                       GELIC_NET_DMAC_CMDSTAT_NOCS | eofr;
+               }
+       }
+}
+
+/**
+ * gelic_net_prepare_tx_descr_v - get dma address of skb_data
+ * @card: card structure
+ * @descr: descriptor structure
+ * @skb: packet to use
+ *
+ * returns 0 on success, <0 on failure.
+ *
+ */
+static int gelic_net_prepare_tx_descr_v(struct gelic_net_card *card,
+                                       struct gelic_net_descr *descr,
+                                       struct sk_buff *skb)
+{
+       dma_addr_t buf[2];
+       unsigned int vlan_len;
+
+       if (skb->len < GELIC_NET_VLAN_POS)
+               return -EINVAL;
+
+       memcpy(&descr->vlan, skb->data, GELIC_NET_VLAN_POS);
+       if (card->vlan_index != -1) {
+               descr->vlan.h_vlan_proto = htons(ETH_P_8021Q); /* vlan 0x8100*/
+               descr->vlan.h_vlan_TCI = htons(card->vlan_id[card->vlan_index]);
+               vlan_len = GELIC_NET_VLAN_POS + VLAN_HLEN; /* VLAN_HLEN=4 */
+       } else
+               vlan_len = GELIC_NET_VLAN_POS; /* no vlan tag */
+
+       /* first descr */
+       buf[0] = dma_map_single(ctodev(card), &descr->vlan,
+                            vlan_len, DMA_TO_DEVICE);
+
+       if (!buf[0]) {
+               dev_err(ctodev(card),
+                       "dma map 1 failed (%p, %i). Dropping packet\n",
+                       skb->data, vlan_len);
+               return -ENOMEM;
+       }
+
+       descr->buf_addr = buf[0];
+       descr->buf_size = vlan_len;
+       descr->skb = skb; /* not used */
+       descr->data_status = 0;
+       gelic_net_set_txdescr_cmdstat(descr, skb, 1); /* not the frame end */
+
+       /* second descr */
+       card->tx_chain.head = card->tx_chain.head->next;
+       descr->next_descr_addr = descr->next->bus_addr;
+       descr = descr->next;
+       if (gelic_net_get_descr_status(descr) != GELIC_NET_DESCR_NOT_IN_USE)
+               /* XXX will be removed */
+               dev_err(ctodev(card), "descr is not free!\n");
+
+       buf[1] = dma_map_single(ctodev(card), skb->data + GELIC_NET_VLAN_POS,
+                            skb->len - GELIC_NET_VLAN_POS,
+                            DMA_TO_DEVICE);
+
+       if (!buf[1]) {
+               dev_err(ctodev(card),
+                       "dma map 2 failed (%p, %i). Dropping packet\n",
+                       skb->data + GELIC_NET_VLAN_POS,
+                       skb->len - GELIC_NET_VLAN_POS);
+               dma_unmap_single(ctodev(card), buf[0], vlan_len,
+                                DMA_TO_DEVICE);
+               return -ENOMEM;
+       }
+
+       descr->buf_addr = buf[1];
+       descr->buf_size = skb->len - GELIC_NET_VLAN_POS;
+       descr->skb = skb;
+       descr->data_status = 0;
+       descr->next_descr_addr = 0; /* terminate hw descr */
+       gelic_net_set_txdescr_cmdstat(descr, skb, 0);
+
+       return 0;
+}
+
+/**
+ * gelic_net_kick_txdma - enables TX DMA processing
+ * @card: card structure
+ * @descr: descriptor address to enable TX processing at
+ *
+ */
+static int gelic_net_kick_txdma(struct gelic_net_card *card,
+                               struct gelic_net_descr *descr)
+{
+       int status = -ENXIO;
+       int count = 10;
+
+       if (card->tx_dma_progress)
+               return 0;
+
+       if (gelic_net_get_descr_status(descr) == GELIC_NET_DESCR_CARDOWNED) {
+               card->tx_dma_progress = 1;
+               /* sometimes we need retry here */
+               while (count--) {
+                       status = lv1_net_start_tx_dma(bus_id(card),
+                                                     dev_id(card),
+                                                     descr->bus_addr, 0);
+                       if (!status)
+                               break;
+               }
+               if (!count)
+                       dev_info(ctodev(card), "lv1_net_start_txdma failed," \
+                               "status=%d %#lx\n",
+                                status, card->irq_status);
+       }
+       return status;
+}
+
+/**
+ * gelic_net_xmit - transmits a frame over the device
+ * @skb: packet to send out
+ * @netdev: interface device structure
+ *
+ * returns 0 on success, <0 on failure
+ */
+static int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
+{
+       struct gelic_net_card *card = netdev_priv(netdev);
+       struct gelic_net_descr *descr = NULL;
+       int result;
+       unsigned long flags;
+
+       spin_lock_irqsave(&card->tx_dma_lock, flags);
+
+       gelic_net_release_tx_chain(card, 0);
+       if (!skb)
+               goto kick;
+       descr = gelic_net_get_next_tx_descr(card);
+       if (!descr) {
+               netif_stop_queue(netdev);
+               spin_unlock_irqrestore(&card->tx_dma_lock, flags);
+               return NETDEV_TX_BUSY;
+       }
+       result = gelic_net_prepare_tx_descr_v(card, descr, skb);
+
+       if (result)
+               goto error;
+
+       card->tx_chain.head = card->tx_chain.head->next;
+
+       if (descr->prev)
+               descr->prev->next_descr_addr = descr->bus_addr;
+kick:
+       /*
+        * as hardware descriptor is modified in the above lines,
+        * ensure that the hardware sees it
+        */
+       wmb();
+       if (gelic_net_kick_txdma(card, card->tx_chain.tail))
+               goto error;
+
+       netdev->trans_start = jiffies;
+       spin_unlock_irqrestore(&card->tx_dma_lock, flags);
+       return NETDEV_TX_OK;
+
+error:
+       card->netdev_stats.tx_dropped++;
+       spin_unlock_irqrestore(&card->tx_dma_lock, flags);
+       return NETDEV_TX_LOCKED;
+}
+
+/**
+ * gelic_net_pass_skb_up - takes an skb from a descriptor and passes it on
+ * @descr: descriptor to process
+ * @card: card structure
+ *
+ * iommu-unmaps the skb, fills out skb structure and passes the data to the
+ * stack. The descriptor state is not changed.
+ */
+static void gelic_net_pass_skb_up(struct gelic_net_descr *descr,
+                                struct gelic_net_card *card)
+{
+       struct sk_buff *skb;
+       struct net_device *netdev;
+       u32 data_status, data_error;
+
+       data_status = descr->data_status;
+       data_error = descr->data_error;
+       netdev = card->netdev;
+       /* unmap skb buffer */
+       skb = descr->skb;
+       dma_unmap_single(ctodev(card), descr->buf_addr, GELIC_NET_MAX_MTU,
+                        DMA_FROM_DEVICE);
+
+       skb_put(skb, descr->valid_size? descr->valid_size : descr->result_size);
+       if (!descr->valid_size)
+               dev_info(ctodev(card), "buffer full %x %x %x\n",
+                        descr->result_size, descr->buf_size,
+                        descr->dmac_cmd_status);
+
+       descr->skb = NULL;
+       /*
+        * the card put 2 bytes vlan tag in front
+        * of the ethernet frame
+        */
+       skb_pull(skb, 2);
+       skb->protocol = eth_type_trans(skb, netdev);
+
+       /* checksum offload */
+       if (card->rx_csum) {
+               if ((data_status & GELIC_NET_DATA_STATUS_CHK_MASK) &&
+                   (!(data_error & GELIC_NET_DATA_ERROR_CHK_MASK)))
+                       skb->ip_summed = CHECKSUM_UNNECESSARY;
+               else
+                       skb->ip_summed = CHECKSUM_NONE;
+       } else
+               skb->ip_summed = CHECKSUM_NONE;
+
+       /* update netdevice statistics */
+       card->netdev_stats.rx_packets++;
+       card->netdev_stats.rx_bytes += skb->len;
+
+       /* pass skb up to stack */
+       netif_receive_skb(skb);
+}
+
+/**
+ * gelic_net_decode_one_descr - processes an rx descriptor
+ * @card: card structure
+ *
+ * returns 1 if a packet has been sent to the stack, otherwise 0
+ *
+ * processes an rx descriptor by iommu-unmapping the data buffer and passing
+ * the packet up to the stack
+ */
+static int gelic_net_decode_one_descr(struct gelic_net_card *card)
+{
+       enum gelic_net_descr_status status;
+       struct gelic_net_descr_chain *chain = &card->rx_chain;
+       struct gelic_net_descr *descr = chain->tail;
+       int dmac_chain_ended;
+
+       status = gelic_net_get_descr_status(descr);
+       /* is this descriptor terminated with next_descr == NULL? */
+       dmac_chain_ended =
+               descr->dmac_cmd_status & GELIC_NET_DMAC_CMDSTAT_RXDCEIS;
+
+       if (status == GELIC_NET_DESCR_CARDOWNED)
+               return 0;
+
+       if (status == GELIC_NET_DESCR_NOT_IN_USE) {
+               dev_dbg(ctodev(card), "dormant descr? %p\n", descr);
+               return 0;
+       }
+
+       if ((status == GELIC_NET_DESCR_RESPONSE_ERROR) ||
+           (status == GELIC_NET_DESCR_PROTECTION_ERROR) ||
+           (status == GELIC_NET_DESCR_FORCE_END)) {
+               dev_info(ctodev(card), "dropping RX descriptor with state %x\n",
+                        status);
+               card->netdev_stats.rx_dropped++;
+               goto refill;
+       }
+
+       if ((status != GELIC_NET_DESCR_COMPLETE) &&
+           (status != GELIC_NET_DESCR_FRAME_END)) {
+               dev_dbg(ctodev(card), "RX descriptor with state %x\n",
+                       status);
+               goto refill;
+       }
+
+       /* ok, we've got a packet in descr */
+       gelic_net_pass_skb_up(descr, card); /* 1: skb_up sccess */
+
+refill:
+       descr->next_descr_addr = 0; /* unlink the descr */
+
+       /* change the descriptor state: */
+       gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE);
+
+       /* refill one desc
+        * FIXME: this can fail, but for now, just leave this
+        * descriptor without skb
+        */
+       gelic_net_prepare_rx_descr(card, descr);
+       chain->head = descr;
+       chain->tail = descr->next;
+       descr->prev->next_descr_addr = descr->bus_addr;
+
+       if (dmac_chain_ended) {
+               gelic_net_enable_rxdmac(card);
+               dev_dbg(ctodev(card), "reenable rx dma\n");
+       }
+
+       return 1;
+}
+
+/**
+ * gelic_net_poll - NAPI poll function called by the stack to return packets
+ * @netdev: interface device structure
+ * @budget: number of packets we can pass to the stack at most
+ *
+ * returns 0 if no more packets available to the driver/stack. Returns 1,
+ * if the quota is exceeded, but the driver has still packets.
+ *
+ */
+static int gelic_net_poll(struct net_device *netdev, int *budget)
+{
+       struct gelic_net_card *card = netdev_priv(netdev);
+       int packets_to_do, packets_done = 0;
+       int no_more_packets = 0;
+
+       packets_to_do = min(*budget, netdev->quota);
+
+       while (packets_to_do) {
+               if (gelic_net_decode_one_descr(card)) {
+                       packets_done++;
+                       packets_to_do--;
+               } else {
+                       /* no more packets for the stack */
+                       no_more_packets = 1;
+                       break;
+               }
+       }
+       netdev->quota -= packets_done;
+       *budget -= packets_done;
+       if (no_more_packets) {
+               netif_rx_complete(netdev);
+               gelic_net_rx_irq_on(card);
+               return 0;
+       } else
+               return 1;
+}
+
+/**
+ * gelic_net_get_stats - get interface statistics
+ * @netdev: interface device structure
+ *
+ * returns the interface statistics residing in the gelic_net_card struct
+ */
+static struct net_device_stats *gelic_net_get_stats(struct net_device *netdev)
+{
+       struct gelic_net_card *card = netdev_priv(netdev);
+
+       return &card->netdev_stats;
+}
+
+/**
+ * gelic_net_change_mtu - changes the MTU of an interface
+ * @netdev: interface device structure
+ * @new_mtu: new MTU value
+ *
+ * returns 0 on success, <0 on failure
+ */
+static int gelic_net_change_mtu(struct net_device *netdev, int new_mtu)
+{
+       /* no need to re-alloc skbs or so -- the max mtu is about 2.3k
+        * and mtu is outbound only anyway */
+       if ((new_mtu < GELIC_NET_MIN_MTU) ||
+           (new_mtu > GELIC_NET_MAX_MTU)) {
+               return -EINVAL;
+       }
+       netdev->mtu = new_mtu;
+       return 0;
+}
+
+/**
+ * gelic_net_interrupt - event handler for gelic_net
+ */
+static irqreturn_t gelic_net_interrupt(int irq, void *ptr)
+{
+       unsigned long flags;
+       struct net_device *netdev = ptr;
+       struct gelic_net_card *card = netdev_priv(netdev);
+       u64 status;
+
+       status = card->irq_status;
+
+       if (!status)
+               return IRQ_NONE;
+
+       if (status & GELIC_NET_RXINT) {
+               gelic_net_rx_irq_off(card);
+               netif_rx_schedule(netdev);
+       }
+
+       if (status & GELIC_NET_TXINT) {
+               spin_lock_irqsave(&card->tx_dma_lock, flags);
+               card->tx_dma_progress = 0;
+               spin_unlock_irqrestore(&card->tx_dma_lock, flags);
+               /* start pending DMA */
+               gelic_net_xmit(NULL, netdev);
+       }
+       return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/**
+ * gelic_net_poll_controller - artificial interrupt for netconsole etc.
+ * @netdev: interface device structure
+ *
+ * see Documentation/networking/netconsole.txt
+ */
+static void gelic_net_poll_controller(struct net_device *netdev)
+{
+       struct gelic_net_card *card = netdev_priv(netdev);
+
+       gelic_net_set_irq_mask(card, 0);
+       gelic_net_interrupt(netdev->irq, netdev);
+       gelic_net_set_irq_mask(card, card->ghiintmask);
+}
+#endif /* CONFIG_NET_POLL_CONTROLLER */
+
+/**
+ * gelic_net_open_device - open device and map dma region
+ * @card: card structure
+ */
+static int gelic_net_open_device(struct gelic_net_card *card)
+{
+       int result;
+
+       result = ps3_sb_event_receive_port_setup(card->dev, PS3_BINDING_CPU_ANY,
+               &card->netdev->irq);
+
+       if (result) {
+               dev_info(ctodev(card),
+                        "%s:%d: gelic_net_open_device failed (%d)\n",
+                        __func__, __LINE__, result);
+               result = -EPERM;
+               goto fail_alloc_irq;
+       }
+
+       result = request_irq(card->netdev->irq, gelic_net_interrupt,
+                            IRQF_DISABLED, "gelic network", card->netdev);
+
+       if (result) {
+               dev_info(ctodev(card), "%s:%d: request_irq failed (%d)\n",
+                       __func__, __LINE__, result);
+               goto fail_request_irq;
+       }
+
+       return 0;
+
+fail_request_irq:
+       ps3_sb_event_receive_port_destroy(card->dev, card->netdev->irq);
+       card->netdev->irq = NO_IRQ;
+fail_alloc_irq:
+       return result;
+}
+
+
+/**
+ * gelic_net_open - called upon ifonfig up
+ * @netdev: interface device structure
+ *
+ * returns 0 on success, <0 on failure
+ *
+ * gelic_net_open allocates all the descriptors and memory needed for
+ * operation, sets up multicast list and enables interrupts
+ */
+static int gelic_net_open(struct net_device *netdev)
+{
+       struct gelic_net_card *card = netdev_priv(netdev);
+
+       dev_dbg(ctodev(card), " -> %s:%d\n", __func__, __LINE__);
+
+       gelic_net_open_device(card);
+
+       if (gelic_net_init_chain(card, &card->tx_chain,
+                       card->descr, GELIC_NET_TX_DESCRIPTORS))
+               goto alloc_tx_failed;
+       if (gelic_net_init_chain(card, &card->rx_chain,
+                                card->descr + GELIC_NET_RX_DESCRIPTORS,
+                                GELIC_NET_RX_DESCRIPTORS))
+               goto alloc_rx_failed;
+
+       /* head of chain */
+       card->tx_top = card->tx_chain.head;
+       card->rx_top = card->rx_chain.head;
+       dev_dbg(ctodev(card), "descr rx %p, tx %p, size %#lx, num %#x\n",
+               card->rx_top, card->tx_top, sizeof(struct gelic_net_descr),
+               GELIC_NET_RX_DESCRIPTORS);
+       /* allocate rx skbs */
+       if (gelic_net_alloc_rx_skbs(card))
+               goto alloc_skbs_failed;
+
+       card->tx_dma_progress = 0;
+       card->ghiintmask = GELIC_NET_RXINT | GELIC_NET_TXINT;
+
+       gelic_net_set_irq_mask(card, card->ghiintmask);
+       gelic_net_enable_rxdmac(card);
+
+       netif_start_queue(netdev);
+       netif_carrier_on(netdev);
+       netif_poll_enable(netdev);
+
+       return 0;
+
+alloc_skbs_failed:
+       gelic_net_free_chain(card, card->rx_top);
+alloc_rx_failed:
+       gelic_net_free_chain(card, card->tx_top);
+alloc_tx_failed:
+       return -ENOMEM;
+}
+
+#ifdef GELIC_NET_ETHTOOL
+static void gelic_net_get_drvinfo (struct net_device *netdev,
+                                  struct ethtool_drvinfo *info)
+{
+       strncpy(info->driver, DRV_NAME, sizeof(info->driver) - 1);
+       strncpy(info->version, DRV_VERSION, sizeof(info->version) - 1);
+}
+
+static int gelic_net_get_settings(struct net_device *netdev,
+                                 struct ethtool_cmd *cmd)
+{
+       struct gelic_net_card *card = netdev_priv(netdev);
+       int status;
+       u64 v1, v2;
+       int speed, duplex;
+
+       speed = duplex = -1;
+       status = lv1_net_control(bus_id(card), dev_id(card),
+                       GELIC_NET_GET_ETH_PORT_STATUS, GELIC_NET_PORT, 0, 0,
+                       &v1, &v2);
+       if (status) {
+               /* link down */
+       } else {
+               if (v1 & GELIC_NET_FULL_DUPLEX) {
+                       duplex = DUPLEX_FULL;
+               } else {
+                       duplex = DUPLEX_HALF;
+               }
+
+               if (v1 & GELIC_NET_SPEED_10 ) {
+                       speed = SPEED_10;
+               } else if (v1 & GELIC_NET_SPEED_100) {
+                       speed = SPEED_100;
+               } else if (v1 & GELIC_NET_SPEED_1000) {
+                       speed = SPEED_1000;
+               }
+       }
+       cmd->supported = SUPPORTED_TP | SUPPORTED_Autoneg |
+                       SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
+                       SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
+                       SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full;
+       cmd->advertising = cmd->supported;
+       cmd->speed = speed;
+       cmd->duplex = duplex;
+       cmd->autoneg = AUTONEG_ENABLE; /* always enabled */
+       cmd->port = PORT_TP;
+
+       return 0;
+}
+
+static u32 gelic_net_get_link(struct net_device *netdev)
+{
+       struct gelic_net_card *card = netdev_priv(netdev);
+       int status;
+       u64 v1, v2;
+       int link;
+
+       status = lv1_net_control(bus_id(card), dev_id(card),
+                       GELIC_NET_GET_ETH_PORT_STATUS, GELIC_NET_PORT, 0, 0,
+                       &v1, &v2);
+       if (status)
+               return 0; /* link down */
+
+       if (v1 & GELIC_NET_LINK_UP)
+               link = 1;
+       else
+               link = 0;
+
+       return link;
+}
+
+static int gelic_net_nway_reset(struct net_device *netdev)
+{
+       if (netif_running(netdev)) {
+               gelic_net_stop(netdev);
+               gelic_net_open(netdev);
+       }
+       return 0;
+}
+
+static u32 gelic_net_get_tx_csum(struct net_device *netdev)
+{
+       return (netdev->features & NETIF_F_IP_CSUM) != 0;
+}
+
+static int gelic_net_set_tx_csum(struct net_device *netdev, u32 data)
+{
+       if (data)
+               netdev->features |= NETIF_F_IP_CSUM;
+       else
+               netdev->features &= ~NETIF_F_IP_CSUM;
+
+       return 0;
+}
+
+static u32 gelic_net_get_rx_csum(struct net_device *netdev)
+{
+       struct gelic_net_card *card = netdev_priv(netdev);
+
+       return card->rx_csum;
+}
+
+static int gelic_net_set_rx_csum(struct net_device *netdev, u32 data)
+{
+       struct gelic_net_card *card = netdev_priv(netdev);
+
+       card->rx_csum = data;
+       return 0;
+}
+
+static struct ethtool_ops gelic_net_ethtool_ops = {
+       .get_drvinfo    = gelic_net_get_drvinfo,
+       .get_settings   = gelic_net_get_settings,
+       .get_link       = gelic_net_get_link,
+       .nway_reset     = gelic_net_nway_reset,
+       .get_tx_csum    = gelic_net_get_tx_csum,
+       .set_tx_csum    = gelic_net_set_tx_csum,
+       .get_rx_csum    = gelic_net_get_rx_csum,
+       .set_rx_csum    = gelic_net_set_rx_csum,
+};
+#endif
+
+/**
+ * gelic_net_tx_timeout_task - task scheduled by the watchdog timeout
+ * function (to be called not under interrupt status)
+ * @work: work is context of tx timout task
+ *
+ * called as task when tx hangs, resets interface (if interface is up)
+ */
+static void gelic_net_tx_timeout_task(struct work_struct *work)
+{
+       struct gelic_net_card *card =
+               container_of(work, struct gelic_net_card, tx_timeout_task);
+       struct net_device *netdev = card->netdev;
+
+       dev_info(ctodev(card), "%s:Timed out. Restarting... \n", __func__);
+
+       if (!(netdev->flags & IFF_UP))
+               goto out;
+
+       netif_device_detach(netdev);
+       gelic_net_stop(netdev);
+
+       gelic_net_open(netdev);
+       netif_device_attach(netdev);
+
+out:
+       atomic_dec(&card->tx_timeout_task_counter);
+}
+
+/**
+ * gelic_net_tx_timeout - called when the tx timeout watchdog kicks in.
+ * @netdev: interface device structure
+ *
+ * called, if tx hangs. Schedules a task that resets the interface
+ */
+static void gelic_net_tx_timeout(struct net_device *netdev)
+{
+       struct gelic_net_card *card;
+
+       card = netdev_priv(netdev);
+       atomic_inc(&card->tx_timeout_task_counter);
+       if (netdev->flags & IFF_UP)
+               schedule_work(&card->tx_timeout_task);
+       else
+               atomic_dec(&card->tx_timeout_task_counter);
+}
+
+/**
+ * gelic_net_setup_netdev_ops - initialization of net_device operations
+ * @netdev: net_device structure
+ *
+ * fills out function pointers in the net_device structure
+ */
+static void gelic_net_setup_netdev_ops(struct net_device *netdev)
+{
+       netdev->open = &gelic_net_open;
+       netdev->stop = &gelic_net_stop;
+       netdev->hard_start_xmit = &gelic_net_xmit;
+       netdev->get_stats = &gelic_net_get_stats;
+       netdev->set_multicast_list = &gelic_net_set_multi;
+       netdev->change_mtu = &gelic_net_change_mtu;
+       /* tx watchdog */
+       netdev->tx_timeout = &gelic_net_tx_timeout;
+       netdev->watchdog_timeo = GELIC_NET_WATCHDOG_TIMEOUT;
+       /* NAPI */
+       netdev->poll = &gelic_net_poll;
+       netdev->weight = GELIC_NET_NAPI_WEIGHT;
+#ifdef GELIC_NET_ETHTOOL
+       netdev->ethtool_ops = &gelic_net_ethtool_ops;
+#endif
+}
+
+/**
+ * gelic_net_setup_netdev - initialization of net_device
+ * @card: card structure
+ *
+ * Returns 0 on success or <0 on failure
+ *
+ * gelic_net_setup_netdev initializes the net_device structure
+ **/
+static int gelic_net_setup_netdev(struct gelic_net_card *card)
+{
+       struct net_device *netdev = card->netdev;
+       struct sockaddr addr;
+       unsigned int i;
+       int status;
+       u64 v1, v2;
+
+       SET_MODULE_OWNER(netdev);
+       SET_NETDEV_DEV(netdev, &card->dev->core);
+       spin_lock_init(&card->tx_dma_lock);
+
+       card->rx_csum = GELIC_NET_RX_CSUM_DEFAULT;
+
+       gelic_net_setup_netdev_ops(netdev);
+
+       netdev->features = NETIF_F_IP_CSUM;
+
+       status = lv1_net_control(bus_id(card), dev_id(card),
+                                GELIC_NET_GET_MAC_ADDRESS,
+                                0, 0, 0, &v1, &v2);
+       if (status || !is_valid_ether_addr((u8 *)&v1)) {
+               dev_info(ctodev(card),
+                        "%s:lv1_net_control GET_MAC_ADDR failed %d\n",
+                        __func__, status);
+               return -EINVAL;
+       }
+       v1 <<= 16;
+       memcpy(addr.sa_data, &v1, ETH_ALEN);
+       memcpy(netdev->dev_addr, addr.sa_data, ETH_ALEN);
+       dev_info(ctodev(card), "MAC addr %02x:%02x:%02x:%02x:%02x:%02x\n",
+                netdev->dev_addr[0], netdev->dev_addr[1],
+                netdev->dev_addr[2], netdev->dev_addr[3],
+                netdev->dev_addr[4], netdev->dev_addr[5]);
+
+       card->vlan_index = -1;  /* no vlan */
+       for (i = 0; i < GELIC_NET_VLAN_MAX; i++) {
+               status = lv1_net_control(bus_id(card), dev_id(card),
+                                       GELIC_NET_GET_VLAN_ID,
+                                       i + 1, /* index; one based */
+                                       0, 0, &v1, &v2);
+               if (status == GELIC_NET_VLAN_NO_ENTRY) {
+                       dev_dbg(ctodev(card),
+                               "GELIC_VLAN_ID no entry:%d, VLAN disabled\n",
+                               status);
+                       card->vlan_id[i] = 0;
+               } else if (status) {
+                       dev_dbg(ctodev(card),
+                               "%s:GELIC_NET_VLAN_ID faild, status=%d\n",
+                               __func__, status);
+                       card->vlan_id[i] = 0;
+               } else {
+                       card->vlan_id[i] = (u32)v1;
+                       dev_dbg(ctodev(card), "vlan_id:%d, %lx\n", i, v1);
+               }
+       }
+       if (card->vlan_id[GELIC_NET_VLAN_WIRED - 1])
+               card->vlan_index = GELIC_NET_VLAN_WIRED - 1;
+
+       status = register_netdev(netdev);
+       if (status) {
+               dev_err(ctodev(card), "%s:Couldn't register net_device: %d\n",
+                       __func__, status);
+               return status;
+       }
+
+       return 0;
+}
+
+/**
+ * gelic_net_alloc_card - allocates net_device and card structure
+ *
+ * returns the card structure or NULL in case of errors
+ *
+ * the card and net_device structures are linked to each other
+ */
+static struct gelic_net_card *gelic_net_alloc_card(void)
+{
+       struct net_device *netdev;
+       struct gelic_net_card *card;
+       size_t alloc_size;
+
+       alloc_size = sizeof (*card) +
+               sizeof (struct gelic_net_descr) * GELIC_NET_RX_DESCRIPTORS +
+               sizeof (struct gelic_net_descr) * GELIC_NET_TX_DESCRIPTORS;
+       /*
+        * we assume private data is allocated 32 bytes (or more) aligned
+        * so that gelic_net_descr should be 32 bytes aligned.
+        * Current alloc_etherdev() does do it because NETDEV_ALIGN
+        * is 32.
+        * check this assumption here.
+        */
+       BUILD_BUG_ON(NETDEV_ALIGN < 32);
+       BUILD_BUG_ON(offsetof(struct gelic_net_card, irq_status) % 8);
+       BUILD_BUG_ON(offsetof(struct gelic_net_card, descr) % 32);
+
+       netdev = alloc_etherdev(alloc_size);
+       if (!netdev)
+               return NULL;
+
+       card = netdev_priv(netdev);
+       card->netdev = netdev;
+       INIT_WORK(&card->tx_timeout_task, gelic_net_tx_timeout_task);
+       init_waitqueue_head(&card->waitq);
+       atomic_set(&card->tx_timeout_task_counter, 0);
+
+       return card;
+}
+
+/**
+ * ps3_gelic_driver_probe - add a device to the control of this driver
+ */
+static int ps3_gelic_driver_probe (struct ps3_system_bus_device *dev)
+{
+       struct gelic_net_card *card = gelic_net_alloc_card();
+       int result;
+
+       if (!card) {
+               dev_info(&dev->core, "gelic_net_alloc_card failed\n");
+               result = -ENOMEM;
+               goto fail_alloc_card;
+       }
+
+       ps3_system_bus_set_driver_data(dev, card);
+       card->dev = dev;
+
+       result = ps3_open_hv_device(dev);
+
+       if (result) {
+               dev_dbg(&dev->core, "ps3_open_hv_device failed\n");
+               goto fail_open;
+       }
+
+       result = ps3_dma_region_create(dev->d_region);
+
+       if (result) {
+               dev_dbg(&dev->core, "ps3_dma_region_create failed(%d)\n",
+                       result);
+               BUG_ON("check region type");
+               goto fail_dma_region;
+       }
+
+       result = lv1_net_set_interrupt_status_indicator(bus_id(card),
+                                                       dev_id(card),
+               ps3_mm_phys_to_lpar(__pa(&card->irq_status)),
+               0);
+
+       if (result) {
+               dev_dbg(&dev->core,
+                       "lv1_net_set_interrupt_status_indicator failed: %s\n",
+                       ps3_result(result));
+               result = -EIO;
+               goto fail_status_indicator;
+       }
+
+       result = gelic_net_setup_netdev(card);
+
+       if (result) {
+               dev_dbg(&dev->core, "%s:%d: ps3_dma_region_create failed: "
+                       "(%d)\n", __func__, __LINE__, result);
+               goto fail_setup_netdev;
+       }
+
+       return 0;
+
+fail_setup_netdev:
+       lv1_net_set_interrupt_status_indicator(bus_id(card),
+                                              bus_id(card),
+                                              0 , 0);
+fail_status_indicator:
+       ps3_dma_region_free(dev->d_region);
+fail_dma_region:
+       ps3_close_hv_device(dev);
+fail_open:
+       ps3_system_bus_set_driver_data(dev, NULL);
+       free_netdev(card->netdev);
+fail_alloc_card:
+       return result;
+}
+
+/**
+ * ps3_gelic_driver_remove - remove a device from the control of this driver
+ */
+
+static int ps3_gelic_driver_remove (struct ps3_system_bus_device *dev)
+{
+       struct gelic_net_card *card = ps3_system_bus_get_driver_data(dev);
+
+       wait_event(card->waitq,
+                  atomic_read(&card->tx_timeout_task_counter) == 0);
+
+       lv1_net_set_interrupt_status_indicator(bus_id(card), dev_id(card),
+                                              0 , 0);
+
+       unregister_netdev(card->netdev);
+       free_netdev(card->netdev);
+
+       ps3_system_bus_set_driver_data(dev, NULL);
+
+       ps3_dma_region_free(dev->d_region);
+
+       ps3_close_hv_device(dev);
+
+       return 0;
+}
+
+static struct ps3_system_bus_driver ps3_gelic_driver = {
+       .match_id = PS3_MATCH_ID_GELIC,
+       .probe = ps3_gelic_driver_probe,
+       .remove = ps3_gelic_driver_remove,
+       .shutdown = ps3_gelic_driver_remove,
+       .core.name = "ps3_gelic_driver",
+       .core.owner = THIS_MODULE,
+};
+
+static int __init ps3_gelic_driver_init (void)
+{
+       return firmware_has_feature(FW_FEATURE_PS3_LV1)
+               ? ps3_system_bus_driver_register(&ps3_gelic_driver)
+               : -ENODEV;
+}
+
+static void __exit ps3_gelic_driver_exit (void)
+{
+       ps3_system_bus_driver_unregister(&ps3_gelic_driver);
+}
+
+module_init (ps3_gelic_driver_init);
+module_exit (ps3_gelic_driver_exit);
+
+MODULE_ALIAS(PS3_MODULE_ALIAS_GELIC);
+
diff --git a/drivers/net/ps3_gelic_net.h b/drivers/net/ps3_gelic_net.h
new file mode 100644 (file)
index 0000000..5e1c286
--- /dev/null
@@ -0,0 +1,239 @@
+/*
+ *  PS3 Platfom gelic network driver.
+ *
+ * Copyright (C) 2007 Sony Computer Entertainment Inc.
+ * Copyright 2006, 2007 Sony Corporation.
+ *
+ * This file is based on: spider_net.h
+ *
+ * (C) Copyright IBM Corp. 2005
+ *
+ * Authors : Utz Bacher <utz.bacher@de.ibm.com>
+ *           Jens Osterkamp <Jens.Osterkamp@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.
+ */
+#ifndef _GELIC_NET_H
+#define _GELIC_NET_H
+
+#define GELIC_NET_DRV_NAME "Gelic Network Driver"
+#define GELIC_NET_DRV_VERSION "1.0"
+
+#define GELIC_NET_ETHTOOL               /* use ethtool */
+
+/* ioctl */
+#define GELIC_NET_GET_MODE              (SIOCDEVPRIVATE + 0)
+#define GELIC_NET_SET_MODE              (SIOCDEVPRIVATE + 1)
+
+/* descriptors */
+#define GELIC_NET_RX_DESCRIPTORS        128 /* num of descriptors */
+#define GELIC_NET_TX_DESCRIPTORS        128 /* num of descriptors */
+
+#define GELIC_NET_MAX_MTU               2308
+#define GELIC_NET_MIN_MTU               64
+#define GELIC_NET_RXBUF_ALIGN           128
+#define GELIC_NET_RX_CSUM_DEFAULT       1 /* hw chksum */
+#define GELIC_NET_WATCHDOG_TIMEOUT      5*HZ
+#define GELIC_NET_NAPI_WEIGHT           (GELIC_NET_RX_DESCRIPTORS)
+#define GELIC_NET_BROADCAST_ADDR        0xffffffffffffL
+#define GELIC_NET_VLAN_POS              (VLAN_ETH_ALEN * 2)
+#define GELIC_NET_VLAN_MAX              4
+#define GELIC_NET_MC_COUNT_MAX          32 /* multicast address list */
+
+enum gelic_net_int0_status {
+       GELIC_NET_GDTDCEINT  = 24,
+       GELIC_NET_GRFANMINT  = 28,
+};
+
+/* GHIINT1STS bits */
+enum gelic_net_int1_status {
+       GELIC_NET_GDADCEINT = 14,
+};
+
+/* interrupt mask */
+#define GELIC_NET_TXINT                   (1L << (GELIC_NET_GDTDCEINT + 32))
+
+#define GELIC_NET_RXINT0                  (1L << (GELIC_NET_GRFANMINT + 32))
+#define GELIC_NET_RXINT1                  (1L << GELIC_NET_GDADCEINT)
+#define GELIC_NET_RXINT                   (GELIC_NET_RXINT0 | GELIC_NET_RXINT1)
+
+ /* RX descriptor data_status bits */
+#define GELIC_NET_RXDMADU      0x80000000 /* destination MAC addr unknown */
+#define GELIC_NET_RXLSTFBF     0x40000000 /* last frame buffer            */
+#define GELIC_NET_RXIPCHK      0x20000000 /* IP checksum performed        */
+#define GELIC_NET_RXTCPCHK     0x10000000 /* TCP/UDP checksup performed   */
+#define GELIC_NET_RXIPSPKT     0x08000000 /* IPsec packet   */
+#define GELIC_NET_RXIPSAHPRT   0x04000000 /* IPsec AH protocol performed */
+#define GELIC_NET_RXIPSESPPRT  0x02000000 /* IPsec ESP protocol performed */
+#define GELIC_NET_RXSESPAH     0x01000000 /*
+                                           * IPsec ESP protocol auth
+                                           * performed
+                                           */
+
+#define GELIC_NET_RXWTPKT      0x00C00000 /*
+                                           * wakeup trigger packet
+                                           * 01: Magic Packet (TM)
+                                           * 10: ARP packet
+                                           * 11: Multicast MAC addr
+                                           */
+#define GELIC_NET_RXVLNPKT     0x00200000 /* VLAN packet */
+/* bit 20..16 reserved */
+#define GELIC_NET_RXRECNUM     0x0000ff00 /* reception receipt number */
+/* bit 7..0 reserved */
+
+#define GELIC_NET_TXDESC_TAIL          0
+#define GELIC_NET_DATA_STATUS_CHK_MASK (GELIC_NET_RXIPCHK | GELIC_NET_RXTCPCHK)
+
+/* RX descriptor data_error bits */
+/* bit 31 reserved */
+#define GELIC_NET_RXALNERR     0x40000000 /* alignement error 10/100M */
+#define GELIC_NET_RXOVERERR    0x20000000 /* oversize error */
+#define GELIC_NET_RXRNTERR     0x10000000 /* Runt error */
+#define GELIC_NET_RXIPCHKERR   0x08000000 /* IP checksum  error */
+#define GELIC_NET_RXTCPCHKERR  0x04000000 /* TCP/UDP checksum  error */
+#define GELIC_NET_RXUMCHSP     0x02000000 /* unmatched sp on sp */
+#define GELIC_NET_RXUMCHSPI    0x01000000 /* unmatched SPI on SAD */
+#define GELIC_NET_RXUMCHSAD    0x00800000 /* unmatched SAD */
+#define GELIC_NET_RXIPSAHERR   0x00400000 /* auth error on AH protocol
+                                           * processing */
+#define GELIC_NET_RXIPSESPAHERR        0x00200000 /* auth error on ESP protocol
+                                           * processing */
+#define GELIC_NET_RXDRPPKT     0x00100000 /* drop packet */
+#define GELIC_NET_RXIPFMTERR   0x00080000 /* IP packet format error */
+/* bit 18 reserved */
+#define GELIC_NET_RXDATAERR    0x00020000 /* IP packet format error */
+#define GELIC_NET_RXCALERR     0x00010000 /* cariier extension length
+                                           * error */
+#define GELIC_NET_RXCREXERR    0x00008000 /* carrier extention error */
+#define GELIC_NET_RXMLTCST     0x00004000 /* multicast address frame */
+/* bit 13..0 reserved */
+#define GELIC_NET_DATA_ERROR_CHK_MASK          \
+       (GELIC_NET_RXIPCHKERR | GELIC_NET_RXTCPCHKERR)
+
+
+/* tx descriptor command and status */
+#define GELIC_NET_DMAC_CMDSTAT_NOCS       0xa0080000 /* middle of frame */
+#define GELIC_NET_DMAC_CMDSTAT_TCPCS      0xa00a0000
+#define GELIC_NET_DMAC_CMDSTAT_UDPCS      0xa00b0000
+#define GELIC_NET_DMAC_CMDSTAT_END_FRAME  0x00040000 /* end of frame */
+
+#define GELIC_NET_DMAC_CMDSTAT_RXDCEIS   0x00000002 /* descriptor chain end
+                                                     * interrupt status */
+
+#define GELIC_NET_DMAC_CMDSTAT_CHAIN_END  0x00000002 /* RXDCEIS:DMA stopped */
+#define GELIC_NET_DMAC_CMDSTAT_NOT_IN_USE 0xb0000000
+#define GELIC_NET_DESCR_IND_PROC_SHIFT    28
+#define GELIC_NET_DESCR_IND_PROC_MASKO    0x0fffffff
+
+
+enum gelic_net_descr_status {
+       GELIC_NET_DESCR_COMPLETE            = 0x00, /* used in rx and tx */
+       GELIC_NET_DESCR_RESPONSE_ERROR      = 0x01, /* used in rx and tx */
+       GELIC_NET_DESCR_PROTECTION_ERROR    = 0x02, /* used in rx and tx */
+       GELIC_NET_DESCR_FRAME_END           = 0x04, /* used in rx */
+       GELIC_NET_DESCR_FORCE_END           = 0x05, /* used in rx and tx */
+       GELIC_NET_DESCR_CARDOWNED           = 0x0a, /* used in rx and tx */
+       GELIC_NET_DESCR_NOT_IN_USE                  /* any other value */
+};
+/* for lv1_net_control */
+#define GELIC_NET_GET_MAC_ADDRESS               0x0000000000000001
+#define GELIC_NET_GET_ETH_PORT_STATUS           0x0000000000000002
+#define GELIC_NET_SET_NEGOTIATION_MODE          0x0000000000000003
+#define GELIC_NET_GET_VLAN_ID                   0x0000000000000004
+
+#define GELIC_NET_LINK_UP                       0x0000000000000001
+#define GELIC_NET_FULL_DUPLEX                   0x0000000000000002
+#define GELIC_NET_AUTO_NEG                      0x0000000000000004
+#define GELIC_NET_SPEED_10                      0x0000000000000010
+#define GELIC_NET_SPEED_100                     0x0000000000000020
+#define GELIC_NET_SPEED_1000                    0x0000000000000040
+
+#define GELIC_NET_VLAN_ALL                      0x0000000000000001
+#define GELIC_NET_VLAN_WIRED                    0x0000000000000002
+#define GELIC_NET_VLAN_WIRELESS                 0x0000000000000003
+#define GELIC_NET_VLAN_PSP                      0x0000000000000004
+#define GELIC_NET_VLAN_PORT0                    0x0000000000000010
+#define GELIC_NET_VLAN_PORT1                    0x0000000000000011
+#define GELIC_NET_VLAN_PORT2                    0x0000000000000012
+#define GELIC_NET_VLAN_DAEMON_CLIENT_BSS        0x0000000000000013
+#define GELIC_NET_VLAN_LIBERO_CLIENT_BSS        0x0000000000000014
+#define GELIC_NET_VLAN_NO_ENTRY                 -6
+
+#define GELIC_NET_PORT                          2 /* for port status */
+
+/* size of hardware part of gelic descriptor */
+#define GELIC_NET_DESCR_SIZE   (32)
+struct gelic_net_descr {
+       /* as defined by the hardware */
+       u32 buf_addr;
+       u32 buf_size;
+       u32 next_descr_addr;
+       u32 dmac_cmd_status;
+       u32 result_size;
+       u32 valid_size; /* all zeroes for tx */
+       u32 data_status;
+       u32 data_error; /* all zeroes for tx */
+
+       /* used in the driver */
+       struct sk_buff *skb;
+       dma_addr_t bus_addr;
+       struct gelic_net_descr *next;
+       struct gelic_net_descr *prev;
+       struct vlan_ethhdr vlan;
+} __attribute__((aligned(32)));
+
+struct gelic_net_descr_chain {
+       /* we walk from tail to head */
+       struct gelic_net_descr *head;
+       struct gelic_net_descr *tail;
+};
+
+struct gelic_net_card {
+       struct net_device *netdev;
+       /*
+        * hypervisor requires irq_status should be
+        * 8 bytes aligned, but u64 member is
+        * always disposed in that manner
+        */
+       u64 irq_status;
+       u64 ghiintmask;
+
+       struct ps3_system_bus_device *dev;
+       u32 vlan_id[GELIC_NET_VLAN_MAX];
+       int vlan_index;
+
+       struct gelic_net_descr_chain tx_chain;
+       struct gelic_net_descr_chain rx_chain;
+       /* gurad dmac descriptor chain*/
+       spinlock_t chain_lock;
+
+       struct net_device_stats netdev_stats;
+       int rx_csum;
+       /* guard tx_dma_progress */
+       spinlock_t tx_dma_lock;
+       int tx_dma_progress;
+
+       struct work_struct tx_timeout_task;
+       atomic_t tx_timeout_task_counter;
+       wait_queue_head_t waitq;
+
+       struct gelic_net_descr *tx_top, *rx_top;
+       struct gelic_net_descr descr[0];
+};
+
+
+extern unsigned long p_to_lp(long pa);
+
+#endif /* _GELIC_NET_H */
index 585be044ebbbdac47d88b0bb76eeb7e932ea027a..8be8be451ada960037f8521776066b1b33c12a22 100755 (executable)
@@ -2433,37 +2433,22 @@ static int ql_get_seg_count(struct ql3_adapter *qdev,
        return -1;
 }
 
-static void ql_hw_csum_setup(struct sk_buff *skb,
+static void ql_hw_csum_setup(const struct sk_buff *skb,
                             struct ob_mac_iocb_req *mac_iocb_ptr)
 {
-       struct ethhdr *eth;
-       struct iphdr *ip = NULL;
-       u8 offset = ETH_HLEN;
+       const struct iphdr *ip = ip_hdr(skb);
 
-       eth = (struct ethhdr *)(skb->data);
+       mac_iocb_ptr->ip_hdr_off = skb_network_offset(skb);
+       mac_iocb_ptr->ip_hdr_len = ip->ihl;
 
-       if (eth->h_proto == __constant_htons(ETH_P_IP)) {
-               ip = (struct iphdr *)&skb->data[ETH_HLEN];
-       } else if (eth->h_proto == htons(ETH_P_8021Q) &&
-                  ((struct vlan_ethhdr *)skb->data)->
-                  h_vlan_encapsulated_proto == __constant_htons(ETH_P_IP)) {
-               ip = (struct iphdr *)&skb->data[VLAN_ETH_HLEN];
-               offset = VLAN_ETH_HLEN;
-       }
-
-       if (ip) {
-               if (ip->protocol == IPPROTO_TCP) {
-                       mac_iocb_ptr->flags1 |= OB_3032MAC_IOCB_REQ_TC | 
+       if (ip->protocol == IPPROTO_TCP) {
+               mac_iocb_ptr->flags1 |= OB_3032MAC_IOCB_REQ_TC |
                        OB_3032MAC_IOCB_REQ_IC;
-                       mac_iocb_ptr->ip_hdr_off = offset;
-                       mac_iocb_ptr->ip_hdr_len = ip->ihl;
-               } else if (ip->protocol == IPPROTO_UDP) {
-                       mac_iocb_ptr->flags1 |= OB_3032MAC_IOCB_REQ_UC | 
+       } else {
+               mac_iocb_ptr->flags1 |= OB_3032MAC_IOCB_REQ_UC |
                        OB_3032MAC_IOCB_REQ_IC;
-                       mac_iocb_ptr->ip_hdr_off = offset;
-                       mac_iocb_ptr->ip_hdr_len = ip->ihl;
-               }
        }
+
 }
 
 /*
index 5ec7752caa4806c7a2adb10d898c11e04a39583f..982a9010c7a925e0b2e29b14cbe156d670c57d2b 100644 (file)
@@ -1,53 +1,11 @@
 /*
-=========================================================================
- r8169.c: A RealTek RTL-8169 Gigabit Ethernet driver for Linux kernel 2.4.x.
- --------------------------------------------------------------------
-
- History:
- Feb  4 2002   - created initially by ShuChen <shuchen@realtek.com.tw>.
- May 20 2002   - Add link status force-mode and TBI mode support.
-       2004    - Massive updates. See kernel SCM system for details.
-=========================================================================
-  1. [DEPRECATED: use ethtool instead] The media can be forced in 5 modes.
-        Command: 'insmod r8169 media = SET_MEDIA'
-        Ex:      'insmod r8169 media = 0x04' will force PHY to operate in 100Mpbs Half-duplex.
-
-        SET_MEDIA can be:
-               _10_Half        = 0x01
-               _10_Full        = 0x02
-               _100_Half       = 0x04
-               _100_Full       = 0x08
-               _1000_Full      = 0x10
-
-  2. Support TBI mode.
-=========================================================================
-VERSION 1.1    <2002/10/4>
-
-       The bit4:0 of MII register 4 is called "selector field", and have to be
-       00001b to indicate support of IEEE std 802.3 during NWay process of
-       exchanging Link Code Word (FLP).
-
-VERSION 1.2    <2002/11/30>
-
-       - Large style cleanup
-       - Use ether_crc in stock kernel (linux/crc32.h)
-       - Copy mc_filter setup code from 8139cp
-         (includes an optimization, and avoids set_bit use)
-
-VERSION 1.6LK  <2004/04/14>
-
-       - Merge of Realtek's version 1.6
-       - Conversion to DMA API
-       - Suspend/resume
-       - Endianness
-       - Misc Rx/Tx bugs
-
-VERSION 2.2LK  <2005/01/25>
-
-       - RX csum, TX csum/SG, TSO
-       - VLAN
-       - baby (< 7200) Jumbo frames support
-       - Merge of Realtek's version 2.2 (new phy)
+ * r8169.c: RealTek 8169/8168/8101 ethernet driver.
+ *
+ * Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw>
+ * Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com>
+ * Copyright (c) a lot of people too. Please respect their work.
+ *
+ * See MAINTAINERS file for support contact information.
  */
 
 #include <linux/module.h>
@@ -108,11 +66,6 @@ VERSION 2.2LK       <2005/01/25>
 #define rtl8169_rx_quota(count, quota) count
 #endif
 
-/* media options */
-#define MAX_UNITS 8
-static int media[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 };
-static int num_media = 0;
-
 /* Maximum events (Rx packets, etc.) to handle at each interrupt. */
 static const int max_interrupt_work = 20;
 
@@ -126,7 +79,7 @@ static const int multicast_filter_limit = 32;
 #define RX_FIFO_THRESH 7       /* 7 means NO threshold, Rx buffer level before first PCI xfer. */
 #define RX_DMA_BURST   6       /* Maximum PCI burst, '6' is 1024 */
 #define TX_DMA_BURST   6       /* Maximum PCI burst, '6' is 1024 */
-#define EarlyTxThld    0x3F    /* 0x3F means NO early transmit */
+#define EarlyTxThld    0x3F    /* 0x3F means NO early transmit */
 #define RxPacketMaxSize        0x3FE8  /* 16K - 1 - ETH_HLEN - VLAN - CRC... */
 #define SafeMtu                0x1c20  /* ... actually life sucks beyond ~7k */
 #define InterFrameGap  0x03    /* 3 means InterFrameGap = the shortest one */
@@ -151,16 +104,17 @@ static const int multicast_filter_limit = 32;
 #define RTL_R32(reg)           ((unsigned long) readl (ioaddr + (reg)))
 
 enum mac_version {
-       RTL_GIGA_MAC_VER_01 = 0x00,
-       RTL_GIGA_MAC_VER_02 = 0x01,
-       RTL_GIGA_MAC_VER_03 = 0x02,
-       RTL_GIGA_MAC_VER_04 = 0x03,
-       RTL_GIGA_MAC_VER_05 = 0x04,
-       RTL_GIGA_MAC_VER_11 = 0x0b,
-       RTL_GIGA_MAC_VER_12 = 0x0c,
-       RTL_GIGA_MAC_VER_13 = 0x0d,
-       RTL_GIGA_MAC_VER_14 = 0x0e,
-       RTL_GIGA_MAC_VER_15 = 0x0f
+       RTL_GIGA_MAC_VER_01 = 0x01, // 8169
+       RTL_GIGA_MAC_VER_02 = 0x02, // 8169S
+       RTL_GIGA_MAC_VER_03 = 0x03, // 8110S
+       RTL_GIGA_MAC_VER_04 = 0x04, // 8169SB
+       RTL_GIGA_MAC_VER_05 = 0x05, // 8110SCd
+       RTL_GIGA_MAC_VER_06 = 0x06, // 8110SCe
+       RTL_GIGA_MAC_VER_11 = 0x0b, // 8168Bb
+       RTL_GIGA_MAC_VER_12 = 0x0c, // 8168Be 8168Bf
+       RTL_GIGA_MAC_VER_13 = 0x0d, // 8101Eb 8101Ec
+       RTL_GIGA_MAC_VER_14 = 0x0e, // 8101
+       RTL_GIGA_MAC_VER_15 = 0x0f  // 8101
 };
 
 enum phy_version {
@@ -180,11 +134,12 @@ static const struct {
        u8 mac_version;
        u32 RxConfigMask;       /* Clears the bits supported by this chip */
 } rtl_chip_info[] = {
-       _R("RTL8169",           RTL_GIGA_MAC_VER_01, 0xff7e1880),
-       _R("RTL8169s/8110s",    RTL_GIGA_MAC_VER_02, 0xff7e1880),
-       _R("RTL8169s/8110s",    RTL_GIGA_MAC_VER_03, 0xff7e1880),
-       _R("RTL8169sb/8110sb",  RTL_GIGA_MAC_VER_04, 0xff7e1880),
-       _R("RTL8169sc/8110sc",  RTL_GIGA_MAC_VER_05, 0xff7e1880),
+       _R("RTL8169",           RTL_GIGA_MAC_VER_01, 0xff7e1880), // 8169
+       _R("RTL8169s",          RTL_GIGA_MAC_VER_02, 0xff7e1880), // 8169S
+       _R("RTL8110s",          RTL_GIGA_MAC_VER_03, 0xff7e1880), // 8110S
+       _R("RTL8169sb/8110sb",  RTL_GIGA_MAC_VER_04, 0xff7e1880), // 8169SB
+       _R("RTL8169sc/8110sc",  RTL_GIGA_MAC_VER_05, 0xff7e1880), // 8110SCd
+       _R("RTL8169sc/8110sc",  RTL_GIGA_MAC_VER_06, 0xff7e1880), // 8110SCe
        _R("RTL8168b/8111b",    RTL_GIGA_MAC_VER_11, 0xff7e1880), // PCI-E
        _R("RTL8168b/8111b",    RTL_GIGA_MAC_VER_12, 0xff7e1880), // PCI-E
        _R("RTL8101e",          RTL_GIGA_MAC_VER_13, 0xff7e1880), // PCI-E 8139
@@ -199,20 +154,15 @@ enum cfg_version {
        RTL_CFG_2
 };
 
-static const struct {
-       unsigned int region;
-       unsigned int align;
-} rtl_cfg_info[] = {
-       [RTL_CFG_0] = { 1, NET_IP_ALIGN },
-       [RTL_CFG_1] = { 2, NET_IP_ALIGN },
-       [RTL_CFG_2] = { 2, 8 }
-};
+static void rtl_hw_start_8169(struct net_device *);
+static void rtl_hw_start_8168(struct net_device *);
+static void rtl_hw_start_8101(struct net_device *);
 
 static struct pci_device_id rtl8169_pci_tbl[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_REALTEK,     0x8129), 0, 0, RTL_CFG_0 },
        { PCI_DEVICE(PCI_VENDOR_ID_REALTEK,     0x8136), 0, 0, RTL_CFG_2 },
        { PCI_DEVICE(PCI_VENDOR_ID_REALTEK,     0x8167), 0, 0, RTL_CFG_0 },
-       { PCI_DEVICE(PCI_VENDOR_ID_REALTEK,     0x8168), 0, 0, RTL_CFG_2 },
+       { PCI_DEVICE(PCI_VENDOR_ID_REALTEK,     0x8168), 0, 0, RTL_CFG_1 },
        { PCI_DEVICE(PCI_VENDOR_ID_REALTEK,     0x8169), 0, 0, RTL_CFG_0 },
        { PCI_DEVICE(PCI_VENDOR_ID_DLINK,       0x4300), 0, 0, RTL_CFG_0 },
        { PCI_DEVICE(0x1259,                    0xc107), 0, 0, RTL_CFG_0 },
@@ -230,62 +180,63 @@ static struct {
        u32 msg_enable;
 } debug = { -1 };
 
-enum RTL8169_registers {
-       MAC0 = 0,               /* Ethernet hardware address. */
-       MAR0 = 8,               /* Multicast filter. */
-       CounterAddrLow = 0x10,
-       CounterAddrHigh = 0x14,
-       TxDescStartAddrLow = 0x20,
-       TxDescStartAddrHigh = 0x24,
-       TxHDescStartAddrLow = 0x28,
-       TxHDescStartAddrHigh = 0x2c,
-       FLASH = 0x30,
-       ERSR = 0x36,
-       ChipCmd = 0x37,
-       TxPoll = 0x38,
-       IntrMask = 0x3C,
-       IntrStatus = 0x3E,
-       TxConfig = 0x40,
-       RxConfig = 0x44,
-       RxMissed = 0x4C,
-       Cfg9346 = 0x50,
-       Config0 = 0x51,
-       Config1 = 0x52,
-       Config2 = 0x53,
-       Config3 = 0x54,
-       Config4 = 0x55,
-       Config5 = 0x56,
-       MultiIntr = 0x5C,
-       PHYAR = 0x60,
-       TBICSR = 0x64,
-       TBI_ANAR = 0x68,
-       TBI_LPAR = 0x6A,
-       PHYstatus = 0x6C,
-       RxMaxSize = 0xDA,
-       CPlusCmd = 0xE0,
-       IntrMitigate = 0xE2,
-       RxDescAddrLow = 0xE4,
-       RxDescAddrHigh = 0xE8,
-       EarlyTxThres = 0xEC,
-       FuncEvent = 0xF0,
-       FuncEventMask = 0xF4,
-       FuncPresetState = 0xF8,
-       FuncForceEvent = 0xFC,
+enum rtl_registers {
+       MAC0            = 0,    /* Ethernet hardware address. */
+       MAC4            = 4,
+       MAR0            = 8,    /* Multicast filter. */
+       CounterAddrLow          = 0x10,
+       CounterAddrHigh         = 0x14,
+       TxDescStartAddrLow      = 0x20,
+       TxDescStartAddrHigh     = 0x24,
+       TxHDescStartAddrLow     = 0x28,
+       TxHDescStartAddrHigh    = 0x2c,
+       FLASH           = 0x30,
+       ERSR            = 0x36,
+       ChipCmd         = 0x37,
+       TxPoll          = 0x38,
+       IntrMask        = 0x3c,
+       IntrStatus      = 0x3e,
+       TxConfig        = 0x40,
+       RxConfig        = 0x44,
+       RxMissed        = 0x4c,
+       Cfg9346         = 0x50,
+       Config0         = 0x51,
+       Config1         = 0x52,
+       Config2         = 0x53,
+       Config3         = 0x54,
+       Config4         = 0x55,
+       Config5         = 0x56,
+       MultiIntr       = 0x5c,
+       PHYAR           = 0x60,
+       TBICSR          = 0x64,
+       TBI_ANAR        = 0x68,
+       TBI_LPAR        = 0x6a,
+       PHYstatus       = 0x6c,
+       RxMaxSize       = 0xda,
+       CPlusCmd        = 0xe0,
+       IntrMitigate    = 0xe2,
+       RxDescAddrLow   = 0xe4,
+       RxDescAddrHigh  = 0xe8,
+       EarlyTxThres    = 0xec,
+       FuncEvent       = 0xf0,
+       FuncEventMask   = 0xf4,
+       FuncPresetState = 0xf8,
+       FuncForceEvent  = 0xfc,
 };
 
-enum RTL8169_register_content {
+enum rtl_register_content {
        /* InterruptStatusBits */
-       SYSErr = 0x8000,
-       PCSTimeout = 0x4000,
-       SWInt = 0x0100,
-       TxDescUnavail = 0x80,
-       RxFIFOOver = 0x40,
-       LinkChg = 0x20,
-       RxOverflow = 0x10,
-       TxErr = 0x08,
-       TxOK = 0x04,
-       RxErr = 0x02,
-       RxOK = 0x01,
+       SYSErr          = 0x8000,
+       PCSTimeout      = 0x4000,
+       SWInt           = 0x0100,
+       TxDescUnavail   = 0x0080,
+       RxFIFOOver      = 0x0040,
+       LinkChg         = 0x0020,
+       RxOverflow      = 0x0010,
+       TxErr           = 0x0008,
+       TxOK            = 0x0004,
+       RxErr           = 0x0002,
+       RxOK            = 0x0001,
 
        /* RxStatusDesc */
        RxFOVF  = (1 << 23),
@@ -295,26 +246,31 @@ enum RTL8169_register_content {
        RxCRC   = (1 << 19),
 
        /* ChipCmdBits */
-       CmdReset = 0x10,
-       CmdRxEnb = 0x08,
-       CmdTxEnb = 0x04,
-       RxBufEmpty = 0x01,
+       CmdReset        = 0x10,
+       CmdRxEnb        = 0x08,
+       CmdTxEnb        = 0x04,
+       RxBufEmpty      = 0x01,
+
+       /* TXPoll register p.5 */
+       HPQ             = 0x80,         /* Poll cmd on the high prio queue */
+       NPQ             = 0x40,         /* Poll cmd on the low prio queue */
+       FSWInt          = 0x01,         /* Forced software interrupt */
 
        /* Cfg9346Bits */
-       Cfg9346_Lock = 0x00,
-       Cfg9346_Unlock = 0xC0,
+       Cfg9346_Lock    = 0x00,
+       Cfg9346_Unlock  = 0xc0,
 
        /* rx_mode_bits */
-       AcceptErr = 0x20,
-       AcceptRunt = 0x10,
-       AcceptBroadcast = 0x08,
-       AcceptMulticast = 0x04,
-       AcceptMyPhys = 0x02,
-       AcceptAllPhys = 0x01,
+       AcceptErr       = 0x20,
+       AcceptRunt      = 0x10,
+       AcceptBroadcast = 0x08,
+       AcceptMulticast = 0x04,
+       AcceptMyPhys    = 0x02,
+       AcceptAllPhys   = 0x01,
 
        /* RxConfigBits */
-       RxCfgFIFOShift = 13,
-       RxCfgDMAShift = 8,
+       RxCfgFIFOShift  = 13,
+       RxCfgDMAShift   =  8,
 
        /* TxConfigBits */
        TxInterFrameGapShift = 24,
@@ -323,6 +279,10 @@ enum RTL8169_register_content {
        /* Config1 register p.24 */
        PMEnable        = (1 << 0),     /* Power Management Enable */
 
+       /* Config2 register p. 25 */
+       PCI_Clock_66MHz = 0x01,
+       PCI_Clock_33MHz = 0x00,
+
        /* Config3 register p.25 */
        MagicPacket     = (1 << 5),     /* Wake up when receives a Magic Packet */
        LinkUp          = (1 << 4),     /* Wake up when the cable connection is re-established */
@@ -343,36 +303,34 @@ enum RTL8169_register_content {
        TBINwComplete   = 0x01000000,
 
        /* CPlusCmd p.31 */
+       PktCntrDisable  = (1 << 7),     // 8168
        RxVlan          = (1 << 6),
        RxChkSum        = (1 << 5),
        PCIDAC          = (1 << 4),
        PCIMulRW        = (1 << 3),
+       INTT_0          = 0x0000,       // 8168
+       INTT_1          = 0x0001,       // 8168
+       INTT_2          = 0x0002,       // 8168
+       INTT_3          = 0x0003,       // 8168
 
        /* rtl8169_PHYstatus */
-       TBI_Enable = 0x80,
-       TxFlowCtrl = 0x40,
-       RxFlowCtrl = 0x20,
-       _1000bpsF = 0x10,
-       _100bps = 0x08,
-       _10bps = 0x04,
-       LinkStatus = 0x02,
-       FullDup = 0x01,
-
-       /* _MediaType */
-       _10_Half = 0x01,
-       _10_Full = 0x02,
-       _100_Half = 0x04,
-       _100_Full = 0x08,
-       _1000_Full = 0x10,
+       TBI_Enable      = 0x80,
+       TxFlowCtrl      = 0x40,
+       RxFlowCtrl      = 0x20,
+       _1000bpsF       = 0x10,
+       _100bps         = 0x08,
+       _10bps          = 0x04,
+       LinkStatus      = 0x02,
+       FullDup         = 0x01,
 
        /* _TBICSRBit */
-       TBILinkOK = 0x02000000,
+       TBILinkOK       = 0x02000000,
 
        /* DumpCounterCommand */
-       CounterDump = 0x8,
+       CounterDump     = 0x8,
 };
 
-enum _DescStatusBit {
+enum desc_status_bit {
        DescOwn         = (1 << 31), /* Descriptor is owned by NIC */
        RingEnd         = (1 << 30), /* End of descriptor ring */
        FirstFrag       = (1 << 29), /* First segment of a packet */
@@ -405,15 +363,15 @@ enum _DescStatusBit {
 #define RsvdMask       0x3fffc000
 
 struct TxDesc {
-       u32 opts1;
-       u32 opts2;
-       u64 addr;
+       __le32 opts1;
+       __le32 opts2;
+       __le64 addr;
 };
 
 struct RxDesc {
-       u32 opts1;
-       u32 opts2;
-       u64 addr;
+       __le32 opts1;
+       __le32 opts2;
+       __le64 addr;
 };
 
 struct ring_info {
@@ -446,6 +404,8 @@ struct rtl8169_private {
        unsigned rx_buf_sz;
        struct timer_list timer;
        u16 cp_cmd;
+       u16 intr_event;
+       u16 napi_event;
        u16 intr_mask;
        int phy_auto_nego_reg;
        int phy_1000_ctrl_reg;
@@ -455,6 +415,7 @@ struct rtl8169_private {
        int (*set_speed)(struct net_device *, u8 autoneg, u16 speed, u8 duplex);
        void (*get_settings)(struct net_device *, struct ethtool_cmd *);
        void (*phy_reset_enable)(void __iomem *);
+       void (*hw_start)(struct net_device *);
        unsigned int (*phy_reset_pending)(void __iomem *);
        unsigned int (*link_ok)(void __iomem *);
        struct delayed_work task;
@@ -463,8 +424,6 @@ struct rtl8169_private {
 
 MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
 MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver");
-module_param_array(media, int, &num_media, 0);
-MODULE_PARM_DESC(media, "force phy operation. Deprecated by ethtool (8).");
 module_param(rx_copybreak, int, 0);
 MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames");
 module_param(use_dac, int, 0);
@@ -478,9 +437,9 @@ static int rtl8169_open(struct net_device *dev);
 static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance);
 static int rtl8169_init_ring(struct net_device *dev);
-static void rtl8169_hw_start(struct net_device *dev);
+static void rtl_hw_start(struct net_device *dev);
 static int rtl8169_close(struct net_device *dev);
-static void rtl8169_set_rx_mode(struct net_device *dev);
+static void rtl_set_rx_mode(struct net_device *dev);
 static void rtl8169_tx_timeout(struct net_device *dev);
 static struct net_device_stats *rtl8169_get_stats(struct net_device *dev);
 static int rtl8169_rx_interrupt(struct net_device *, struct rtl8169_private *,
@@ -493,35 +452,37 @@ static void rtl8169_rx_clear(struct rtl8169_private *tp);
 static int rtl8169_poll(struct net_device *dev, int *budget);
 #endif
 
-static const u16 rtl8169_intr_mask =
-       SYSErr | LinkChg | RxOverflow | RxFIFOOver | TxErr | TxOK | RxErr | RxOK;
-static const u16 rtl8169_napi_event =
-       RxOK | RxOverflow | RxFIFOOver | TxOK | TxErr;
 static const unsigned int rtl8169_rx_config =
        (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift);
 
-static void mdio_write(void __iomem *ioaddr, int RegAddr, int value)
+static void mdio_write(void __iomem *ioaddr, int reg_addr, int value)
 {
        int i;
 
-       RTL_W32(PHYAR, 0x80000000 | (RegAddr & 0xFF) << 16 | value);
+       RTL_W32(PHYAR, 0x80000000 | (reg_addr & 0xFF) << 16 | value);
 
        for (i = 20; i > 0; i--) {
-               /* Check if the RTL8169 has completed writing to the specified MII register */
+               /*
+                * Check if the RTL8169 has completed writing to the specified
+                * MII register.
+                */
                if (!(RTL_R32(PHYAR) & 0x80000000))
                        break;
                udelay(25);
        }
 }
 
-static int mdio_read(void __iomem *ioaddr, int RegAddr)
+static int mdio_read(void __iomem *ioaddr, int reg_addr)
 {
        int i, value = -1;
 
-       RTL_W32(PHYAR, 0x0 | (RegAddr & 0xFF) << 16);
+       RTL_W32(PHYAR, 0x0 | (reg_addr & 0xFF) << 16);
 
        for (i = 20; i > 0; i--) {
-               /* Check if the RTL8169 has completed retrieving data from the specified MII register */
+               /*
+                * Check if the RTL8169 has completed retrieving data from
+                * the specified MII register.
+                */
                if (RTL_R32(PHYAR) & 0x80000000) {
                        value = (int) (RTL_R32(PHYAR) & 0xFFFF);
                        break;
@@ -579,7 +540,8 @@ static void rtl8169_xmii_reset_enable(void __iomem *ioaddr)
 }
 
 static void rtl8169_check_link_status(struct net_device *dev,
-                                     struct rtl8169_private *tp, void __iomem *ioaddr)
+                                     struct rtl8169_private *tp,
+                                     void __iomem *ioaddr)
 {
        unsigned long flags;
 
@@ -596,38 +558,6 @@ static void rtl8169_check_link_status(struct net_device *dev,
        spin_unlock_irqrestore(&tp->lock, flags);
 }
 
-static void rtl8169_link_option(int idx, u8 *autoneg, u16 *speed, u8 *duplex)
-{
-       struct {
-               u16 speed;
-               u8 duplex;
-               u8 autoneg;
-               u8 media;
-       } link_settings[] = {
-               { SPEED_10,     DUPLEX_HALF, AUTONEG_DISABLE,   _10_Half },
-               { SPEED_10,     DUPLEX_FULL, AUTONEG_DISABLE,   _10_Full },
-               { SPEED_100,    DUPLEX_HALF, AUTONEG_DISABLE,   _100_Half },
-               { SPEED_100,    DUPLEX_FULL, AUTONEG_DISABLE,   _100_Full },
-               { SPEED_1000,   DUPLEX_FULL, AUTONEG_DISABLE,   _1000_Full },
-               /* Make TBI happy */
-               { SPEED_1000,   DUPLEX_FULL, AUTONEG_ENABLE,    0xff }
-       }, *p;
-       unsigned char option;
-
-       option = ((idx < MAX_UNITS) && (idx >= 0)) ? media[idx] : 0xff;
-
-       if ((option != 0xff) && !idx && netif_msg_drv(&debug))
-               printk(KERN_WARNING PFX "media option is deprecated.\n");
-
-       for (p = link_settings; p->media != 0xff; p++) {
-               if (p->media == option)
-                       break;
-       }
-       *autoneg = p->autoneg;
-       *speed = p->speed;
-       *duplex = p->duplex;
-}
-
 static void rtl8169_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
        struct rtl8169_private *tp = netdev_priv(dev);
@@ -667,7 +597,7 @@ static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
        struct rtl8169_private *tp = netdev_priv(dev);
        void __iomem *ioaddr = tp->mmio_addr;
-       int i;
+       unsigned int i;
        static struct {
                u32 opt;
                u16 reg;
@@ -893,8 +823,7 @@ static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc,
        int ret;
 
        if (tp->vlgrp && (opts2 & RxVlanTag)) {
-               rtl8169_rx_hwaccel_skb(skb, tp->vlgrp,
-                                      swab16(opts2 & 0xffff));
+               rtl8169_rx_hwaccel_skb(skb, tp->vlgrp, swab16(opts2 & 0xffff));
                ret = 0;
        } else
                ret = -1;
@@ -1115,7 +1044,6 @@ static void rtl8169_get_strings(struct net_device *dev, u32 stringset, u8 *data)
        }
 }
 
-
 static const struct ethtool_ops rtl8169_ethtool_ops = {
        .get_drvinfo            = rtl8169_get_drvinfo,
        .get_regs_len           = rtl8169_get_regs_len,
@@ -1141,8 +1069,8 @@ static const struct ethtool_ops rtl8169_ethtool_ops = {
        .get_perm_addr          = ethtool_op_get_perm_addr,
 };
 
-static void rtl8169_write_gmii_reg_bit(void __iomem *ioaddr, int reg, int bitnum,
-                                      int bitval)
+static void rtl8169_write_gmii_reg_bit(void __iomem *ioaddr, int reg,
+                                      int bitnum, int bitval)
 {
        int val;
 
@@ -1152,8 +1080,20 @@ static void rtl8169_write_gmii_reg_bit(void __iomem *ioaddr, int reg, int bitnum
        mdio_write(ioaddr, reg, val & 0xffff);
 }
 
-static void rtl8169_get_mac_version(struct rtl8169_private *tp, void __iomem *ioaddr)
+static void rtl8169_get_mac_version(struct rtl8169_private *tp,
+                                   void __iomem *ioaddr)
 {
+       /*
+        * The driver currently handles the 8168Bf and the 8168Be identically
+        * but they can be identified more specifically through the test below
+        * if needed:
+        *
+        * (RTL_R32(TxConfig) & 0x700000) == 0x500000 ? 8168Bf : 8168Be
+        *
+        * Same thing for the 8101Eb and the 8101Ec:
+        *
+        * (RTL_R32(TxConfig) & 0x700000) == 0x200000 ? 8101Eb : 8101Ec
+        */
        const struct {
                u32 mask;
                int mac_version;
@@ -1163,6 +1103,7 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, void __iomem *io
                { 0x34000000,   RTL_GIGA_MAC_VER_13 },
                { 0x30800000,   RTL_GIGA_MAC_VER_14 },
                { 0x30000000,   RTL_GIGA_MAC_VER_11 },
+               { 0x98000000,   RTL_GIGA_MAC_VER_06 },
                { 0x18000000,   RTL_GIGA_MAC_VER_05 },
                { 0x10000000,   RTL_GIGA_MAC_VER_04 },
                { 0x04000000,   RTL_GIGA_MAC_VER_03 },
@@ -1171,7 +1112,7 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, void __iomem *io
        }, *p = mac_info;
        u32 reg;
 
-       reg = RTL_R32(TxConfig) & 0x7c800000;
+       reg = RTL_R32(TxConfig) & 0xfc800000;
        while ((reg & p->mask) != p->mask)
                p++;
        tp->mac_version = p->mac_version;
@@ -1182,7 +1123,8 @@ static void rtl8169_print_mac_version(struct rtl8169_private *tp)
        dprintk("mac_version = 0x%02x\n", tp->mac_version);
 }
 
-static void rtl8169_get_phy_version(struct rtl8169_private *tp, void __iomem *ioaddr)
+static void rtl8169_get_phy_version(struct rtl8169_private *tp,
+                                   void __iomem *ioaddr)
 {
        const struct {
                u16 mask;
@@ -1259,7 +1201,7 @@ static void rtl8169_hw_phy_config(struct net_device *dev)
                  0xbf00 }      //w 0 15 0 bf00
                }
        }, *p = phy_magic;
-       int i;
+       unsigned int i;
 
        rtl8169_print_mac_version(tp);
        rtl8169_print_phy_version(tp);
@@ -1393,7 +1335,7 @@ static void rtl8169_phy_reset(struct net_device *dev,
                              struct rtl8169_private *tp)
 {
        void __iomem *ioaddr = tp->mmio_addr;
-       int i;
+       unsigned int i;
 
        tp->phy_reset_enable(ioaddr);
        for (i = 0; i < 100; i++) {
@@ -1408,21 +1350,16 @@ static void rtl8169_phy_reset(struct net_device *dev,
 static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp)
 {
        void __iomem *ioaddr = tp->mmio_addr;
-       static int board_idx = -1;
-       u8 autoneg, duplex;
-       u16 speed;
-
-       board_idx++;
 
        rtl8169_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_03) {
-               dprintk("Set PCI Latency=0x40\n");
-               pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40);
-       }
+       pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40);
+
+       if (tp->mac_version <= RTL_GIGA_MAC_VER_06)
+               pci_write_config_byte(tp->pci_dev, PCI_CACHE_LINE_SIZE, 0x08);
 
        if (tp->mac_version == RTL_GIGA_MAC_VER_02) {
                dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
@@ -1431,16 +1368,52 @@ static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp)
                mdio_write(ioaddr, 0x0b, 0x0000); //w 0x0b 15 0 0
        }
 
-       rtl8169_link_option(board_idx, &autoneg, &speed, &duplex);
-
        rtl8169_phy_reset(dev, tp);
 
-       rtl8169_set_speed(dev, autoneg, speed, duplex);
+       /*
+        * rtl8169_set_speed_xmii takes good care of the Fast Ethernet
+        * only 8101. Don't panic.
+        */
+       rtl8169_set_speed(dev, AUTONEG_ENABLE, SPEED_1000, DUPLEX_FULL);
 
        if ((RTL_R8(PHYstatus) & TBI_Enable) && netif_msg_link(tp))
                printk(KERN_INFO PFX "%s: TBI auto-negotiating\n", dev->name);
 }
 
+static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr)
+{
+       void __iomem *ioaddr = tp->mmio_addr;
+       u32 high;
+       u32 low;
+
+       low  = addr[0] | (addr[1] << 8) | (addr[2] << 16) | (addr[3] << 24);
+       high = addr[4] | (addr[5] << 8);
+
+       spin_lock_irq(&tp->lock);
+
+       RTL_W8(Cfg9346, Cfg9346_Unlock);
+       RTL_W32(MAC0, low);
+       RTL_W32(MAC4, high);
+       RTL_W8(Cfg9346, Cfg9346_Lock);
+
+       spin_unlock_irq(&tp->lock);
+}
+
+static int rtl_set_mac_address(struct net_device *dev, void *p)
+{
+       struct rtl8169_private *tp = netdev_priv(dev);
+       struct sockaddr *addr = p;
+
+       if (!is_valid_ether_addr(addr->sa_data))
+               return -EADDRNOTAVAIL;
+
+       memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+
+       rtl_rar_set(tp, dev->dev_addr);
+
+       return 0;
+}
+
 static int rtl8169_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
        struct rtl8169_private *tp = netdev_priv(dev);
@@ -1467,15 +1440,49 @@ static int rtl8169_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
        return -EOPNOTSUPP;
 }
 
+static const struct rtl_cfg_info {
+       void (*hw_start)(struct net_device *);
+       unsigned int region;
+       unsigned int align;
+       u16 intr_event;
+       u16 napi_event;
+} rtl_cfg_infos [] = {
+       [RTL_CFG_0] = {
+               .hw_start       = rtl_hw_start_8169,
+               .region         = 1,
+               .align          = 0,
+               .intr_event     = SYSErr | LinkChg | RxOverflow |
+                                 RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
+               .napi_event     = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow
+       },
+       [RTL_CFG_1] = {
+               .hw_start       = rtl_hw_start_8168,
+               .region         = 2,
+               .align          = 8,
+               .intr_event     = SYSErr | LinkChg | RxOverflow |
+                                 TxErr | TxOK | RxOK | RxErr,
+               .napi_event     = TxErr | TxOK | RxOK | RxOverflow
+       },
+       [RTL_CFG_2] = {
+               .hw_start       = rtl_hw_start_8101,
+               .region         = 2,
+               .align          = 8,
+               .intr_event     = SYSErr | LinkChg | RxOverflow | PCSTimeout |
+                                 RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
+               .napi_event     = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow
+       }
+};
+
 static int __devinit
 rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-       const unsigned int region = rtl_cfg_info[ent->driver_data].region;
+       const struct rtl_cfg_info *cfg = rtl_cfg_infos + ent->driver_data;
+       const unsigned int region = cfg->region;
        struct rtl8169_private *tp;
        struct net_device *dev;
        void __iomem *ioaddr;
-       unsigned int pm_cap;
-       int i, rc;
+       unsigned int i;
+       int rc;
 
        if (netif_msg_drv(&debug)) {
                printk(KERN_INFO "%s Gigabit Ethernet driver %s loaded\n",
@@ -1508,20 +1515,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (rc < 0)
                goto err_out_disable_2;
 
-       /* save power state before pci_enable_device overwrites it */
-       pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
-       if (pm_cap) {
-               u16 pwr_command, acpi_idle_state;
-
-               pci_read_config_word(pdev, pm_cap + PCI_PM_CTRL, &pwr_command);
-               acpi_idle_state = pwr_command & PCI_PM_CTRL_STATE_MASK;
-       } else {
-               if (netif_msg_probe(tp)) {
-                       dev_err(&pdev->dev,
-                               "PowerManagement capability not found.\n");
-               }
-       }
-
        /* make sure PCI base addr 1 is MMIO */
        if (!(pci_resource_flags(pdev, region) & IORESOURCE_MEM)) {
                if (netif_msg_probe(tp)) {
@@ -1585,7 +1578,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        RTL_W8(ChipCmd, CmdReset);
 
        /* Check that the chip has finished the reset. */
-       for (i = 100; i > 0; i--) {
+       for (i = 0; i < 100; i++) {
                if ((RTL_R8(ChipCmd) & CmdReset) == 0)
                        break;
                msleep_interruptible(1);
@@ -1647,11 +1640,12 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        SET_ETHTOOL_OPS(dev, &rtl8169_ethtool_ops);
        dev->stop = rtl8169_close;
        dev->tx_timeout = rtl8169_tx_timeout;
-       dev->set_multicast_list = rtl8169_set_rx_mode;
+       dev->set_multicast_list = rtl_set_rx_mode;
        dev->watchdog_timeo = RTL8169_TX_TIMEOUT;
        dev->irq = pdev->irq;
        dev->base_addr = (unsigned long) ioaddr;
        dev->change_mtu = rtl8169_change_mtu;
+       dev->set_mac_address = rtl_set_mac_address;
 
 #ifdef CONFIG_R8169_NAPI
        dev->poll = rtl8169_poll;
@@ -1670,7 +1664,10 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        tp->intr_mask = 0xffff;
        tp->pci_dev = pdev;
        tp->mmio_addr = ioaddr;
-       tp->align = rtl_cfg_info[ent->driver_data].align;
+       tp->align = cfg->align;
+       tp->hw_start = cfg->hw_start;
+       tp->intr_event = cfg->intr_event;
+       tp->napi_event = cfg->napi_event;
 
        init_timer(&tp->timer);
        tp->timer.data = (unsigned long) dev;
@@ -1685,15 +1682,17 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        pci_set_drvdata(pdev, dev);
 
        if (netif_msg_probe(tp)) {
+               u32 xid = RTL_R32(TxConfig) & 0x7cf0f8ff;
+
                printk(KERN_INFO "%s: %s at 0x%lx, "
                       "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "
-                      "IRQ %d\n",
+                      "XID %08x IRQ %d\n",
                       dev->name,
                       rtl_chip_info[tp->chipset].name,
                       dev->base_addr,
                       dev->dev_addr[0], dev->dev_addr[1],
                       dev->dev_addr[2], dev->dev_addr[3],
-                      dev->dev_addr[4], dev->dev_addr[5], dev->irq);
+                      dev->dev_addr[4], dev->dev_addr[5], xid, dev->irq);
        }
 
        rtl8169_init_phy(dev, tp);
@@ -1714,15 +1713,11 @@ err_out_free_dev_1:
        goto out;
 }
 
-static void __devexit
-rtl8169_remove_one(struct pci_dev *pdev)
+static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
 {
        struct net_device *dev = pci_get_drvdata(pdev);
        struct rtl8169_private *tp = netdev_priv(dev);
 
-       assert(dev != NULL);
-       assert(tp != NULL);
-
        flush_scheduled_work();
 
        unregister_netdev(dev);
@@ -1774,7 +1769,7 @@ static int rtl8169_open(struct net_device *dev)
        if (retval < 0)
                goto err_release_ring_2;
 
-       rtl8169_hw_start(dev);
+       rtl_hw_start(dev);
 
        rtl8169_request_timer(dev);
 
@@ -1805,7 +1800,7 @@ static void rtl8169_hw_reset(void __iomem *ioaddr)
        RTL_R8(ChipCmd);
 }
 
-static void rtl8169_set_rx_tx_config_registers(struct rtl8169_private *tp)
+static void rtl_set_rx_tx_config_registers(struct rtl8169_private *tp)
 {
        void __iomem *ioaddr = tp->mmio_addr;
        u32 cfg = rtl8169_rx_config;
@@ -1818,45 +1813,90 @@ static void rtl8169_set_rx_tx_config_registers(struct rtl8169_private *tp)
                (InterFrameGap << TxInterFrameGapShift));
 }
 
-static void rtl8169_hw_start(struct net_device *dev)
+static void rtl_hw_start(struct net_device *dev)
 {
        struct rtl8169_private *tp = netdev_priv(dev);
        void __iomem *ioaddr = tp->mmio_addr;
-       struct pci_dev *pdev = tp->pci_dev;
-       u16 cmd;
-       u32 i;
+       unsigned int i;
 
        /* Soft reset the chip. */
        RTL_W8(ChipCmd, CmdReset);
 
        /* Check that the chip has finished the reset. */
-       for (i = 100; i > 0; i--) {
+       for (i = 0; i < 100; i++) {
                if ((RTL_R8(ChipCmd) & CmdReset) == 0)
                        break;
                msleep_interruptible(1);
        }
 
-       if (tp->mac_version == RTL_GIGA_MAC_VER_05) {
-               RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) | PCIMulRW);
-               pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 0x08);
-       }
+       tp->hw_start(dev);
 
-       if (tp->mac_version == RTL_GIGA_MAC_VER_13) {
-               pci_write_config_word(pdev, 0x68, 0x00);
-               pci_write_config_word(pdev, 0x69, 0x08);
-       }
+       netif_start_queue(dev);
+}
 
-       /* Undocumented stuff. */
-       if (tp->mac_version == RTL_GIGA_MAC_VER_05) {
-               /* Realtek's r1000_n.c driver uses '&& 0x01' here. Well... */
-               if ((RTL_R8(Config2) & 0x07) & 0x01)
-                       RTL_W32(0x7c, 0x0007ffff);
 
-               RTL_W32(0x7c, 0x0007ff00);
+static void rtl_set_rx_tx_desc_registers(struct rtl8169_private *tp,
+                                        void __iomem *ioaddr)
+{
+       /*
+        * Magic spell: some iop3xx ARM board needs the TxDescAddrHigh
+        * register to be written before TxDescAddrLow to work.
+        * Switching from MMIO to I/O access fixes the issue as well.
+        */
+       RTL_W32(TxDescStartAddrHigh, ((u64) tp->TxPhyAddr) >> 32);
+       RTL_W32(TxDescStartAddrLow, ((u64) tp->TxPhyAddr) & DMA_32BIT_MASK);
+       RTL_W32(RxDescAddrHigh, ((u64) tp->RxPhyAddr) >> 32);
+       RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr) & DMA_32BIT_MASK);
+}
+
+static u16 rtl_rw_cpluscmd(void __iomem *ioaddr)
+{
+       u16 cmd;
+
+       cmd = RTL_R16(CPlusCmd);
+       RTL_W16(CPlusCmd, cmd);
+       return cmd;
+}
+
+static void rtl_set_rx_max_size(void __iomem *ioaddr)
+{
+       /* Low hurts. Let's disable the filtering. */
+       RTL_W16(RxMaxSize, 16383);
+}
+
+static void rtl8169_set_magic_reg(void __iomem *ioaddr, unsigned mac_version)
+{
+       struct {
+               u32 mac_version;
+               u32 clk;
+               u32 val;
+       } cfg2_info [] = {
+               { RTL_GIGA_MAC_VER_05, PCI_Clock_33MHz, 0x000fff00 }, // 8110SCd
+               { RTL_GIGA_MAC_VER_05, PCI_Clock_66MHz, 0x000fffff },
+               { RTL_GIGA_MAC_VER_06, PCI_Clock_33MHz, 0x00ffff00 }, // 8110SCe
+               { RTL_GIGA_MAC_VER_06, PCI_Clock_66MHz, 0x00ffffff }
+       }, *p = cfg2_info;
+       unsigned int i;
+       u32 clk;
 
-               pci_read_config_word(pdev, PCI_COMMAND, &cmd);
-               cmd = cmd & 0xef;
-               pci_write_config_word(pdev, PCI_COMMAND, cmd);
+       clk = RTL_R8(Config2) & PCI_Clock_66MHz;
+       for (i = 0; i < ARRAY_SIZE(cfg2_info); i++) {
+               if ((p->mac_version == mac_version) && (p->clk == clk)) {
+                       RTL_W32(0x7c, p->val);
+                       break;
+               }
+       }
+}
+
+static void rtl_hw_start_8169(struct net_device *dev)
+{
+       struct rtl8169_private *tp = netdev_priv(dev);
+       void __iomem *ioaddr = tp->mmio_addr;
+       struct pci_dev *pdev = tp->pci_dev;
+
+       if (tp->mac_version == RTL_GIGA_MAC_VER_05) {
+               RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) | PCIMulRW);
+               pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 0x08);
        }
 
        RTL_W8(Cfg9346, Cfg9346_Unlock);
@@ -1868,19 +1908,11 @@ static void rtl8169_hw_start(struct net_device *dev)
 
        RTL_W8(EarlyTxThres, EarlyTxThld);
 
-       /* Low hurts. Let's disable the filtering. */
-       RTL_W16(RxMaxSize, 16383);
-
-       if ((tp->mac_version == RTL_GIGA_MAC_VER_01) ||
-           (tp->mac_version == RTL_GIGA_MAC_VER_02) ||
-           (tp->mac_version == RTL_GIGA_MAC_VER_03) ||
-           (tp->mac_version == RTL_GIGA_MAC_VER_04))
-               rtl8169_set_rx_tx_config_registers(tp);
+       rtl_set_rx_max_size(ioaddr);
 
-       cmd = RTL_R16(CPlusCmd);
-       RTL_W16(CPlusCmd, cmd);
+       rtl_set_rx_tx_config_registers(tp);
 
-       tp->cp_cmd |= cmd | PCIMulRW;
+       tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW;
 
        if ((tp->mac_version == RTL_GIGA_MAC_VER_02) ||
            (tp->mac_version == RTL_GIGA_MAC_VER_03)) {
@@ -1891,29 +1923,15 @@ static void rtl8169_hw_start(struct net_device *dev)
 
        RTL_W16(CPlusCmd, tp->cp_cmd);
 
+       rtl8169_set_magic_reg(ioaddr, tp->mac_version);
+
        /*
         * Undocumented corner. Supposedly:
         * (TxTimer << 12) | (TxPackets << 8) | (RxTimer << 4) | RxPackets
         */
        RTL_W16(IntrMitigate, 0x0000);
 
-       /*
-        * Magic spell: some iop3xx ARM board needs the TxDescAddrHigh
-        * register to be written before TxDescAddrLow to work.
-        * Switching from MMIO to I/O access fixes the issue as well.
-        */
-       RTL_W32(TxDescStartAddrHigh, ((u64) tp->TxPhyAddr >> 32));
-       RTL_W32(TxDescStartAddrLow, ((u64) tp->TxPhyAddr & DMA_32BIT_MASK));
-       RTL_W32(RxDescAddrHigh, ((u64) tp->RxPhyAddr >> 32));
-       RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr & DMA_32BIT_MASK));
-
-       if ((tp->mac_version != RTL_GIGA_MAC_VER_01) &&
-           (tp->mac_version != RTL_GIGA_MAC_VER_02) &&
-           (tp->mac_version != RTL_GIGA_MAC_VER_03) &&
-           (tp->mac_version != RTL_GIGA_MAC_VER_04)) {
-               RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
-               rtl8169_set_rx_tx_config_registers(tp);
-       }
+       rtl_set_rx_tx_desc_registers(tp, ioaddr);
 
        RTL_W8(Cfg9346, Cfg9346_Lock);
 
@@ -1922,15 +1940,107 @@ static void rtl8169_hw_start(struct net_device *dev)
 
        RTL_W32(RxMissed, 0);
 
-       rtl8169_set_rx_mode(dev);
+       rtl_set_rx_mode(dev);
 
        /* no early-rx interrupts */
        RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000);
 
        /* Enable all known interrupts by setting the interrupt mask. */
-       RTL_W16(IntrMask, rtl8169_intr_mask);
+       RTL_W16(IntrMask, tp->intr_event);
 
-       netif_start_queue(dev);
+       RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
+}
+
+static void rtl_hw_start_8168(struct net_device *dev)
+{
+       struct rtl8169_private *tp = netdev_priv(dev);
+       void __iomem *ioaddr = tp->mmio_addr;
+       struct pci_dev *pdev = tp->pci_dev;
+       u8 ctl;
+
+       RTL_W8(Cfg9346, Cfg9346_Unlock);
+
+       RTL_W8(EarlyTxThres, EarlyTxThld);
+
+       rtl_set_rx_max_size(ioaddr);
+
+       rtl_set_rx_tx_config_registers(tp);
+
+       tp->cp_cmd |= RTL_R16(CPlusCmd) | PktCntrDisable | INTT_1;
+
+       RTL_W16(CPlusCmd, tp->cp_cmd);
+
+       /* Tx performance tweak. */
+       pci_read_config_byte(pdev, 0x69, &ctl);
+       ctl = (ctl & ~0x70) | 0x50;
+       pci_write_config_byte(pdev, 0x69, ctl);
+
+       RTL_W16(IntrMitigate, 0x5151);
+
+       /* Work around for RxFIFO overflow. */
+       if (tp->mac_version == RTL_GIGA_MAC_VER_11) {
+               tp->intr_event |= RxFIFOOver | PCSTimeout;
+               tp->intr_event &= ~RxOverflow;
+       }
+
+       rtl_set_rx_tx_desc_registers(tp, ioaddr);
+
+       RTL_W8(Cfg9346, Cfg9346_Lock);
+
+       RTL_R8(IntrMask);
+
+       RTL_W32(RxMissed, 0);
+
+       rtl_set_rx_mode(dev);
+
+       RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
+
+       RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000);
+
+       RTL_W16(IntrMask, tp->intr_event);
+}
+
+static void rtl_hw_start_8101(struct net_device *dev)
+{
+       struct rtl8169_private *tp = netdev_priv(dev);
+       void __iomem *ioaddr = tp->mmio_addr;
+       struct pci_dev *pdev = tp->pci_dev;
+
+       if (tp->mac_version == RTL_GIGA_MAC_VER_13) {
+               pci_write_config_word(pdev, 0x68, 0x00);
+               pci_write_config_word(pdev, 0x69, 0x08);
+       }
+
+       RTL_W8(Cfg9346, Cfg9346_Unlock);
+
+       RTL_W8(EarlyTxThres, EarlyTxThld);
+
+       rtl_set_rx_max_size(ioaddr);
+
+       tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW;
+
+       RTL_W16(CPlusCmd, tp->cp_cmd);
+
+       RTL_W16(IntrMitigate, 0x0000);
+
+       rtl_set_rx_tx_desc_registers(tp, ioaddr);
+
+       RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
+       rtl_set_rx_tx_config_registers(tp);
+
+       RTL_W8(Cfg9346, Cfg9346_Lock);
+
+       RTL_R8(IntrMask);
+
+       RTL_W32(RxMissed, 0);
+
+       rtl_set_rx_mode(dev);
+
+       RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
+
+       RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xf000);
+
+       RTL_W16(IntrMask, tp->intr_event);
 }
 
 static int rtl8169_change_mtu(struct net_device *dev, int new_mtu)
@@ -1956,7 +2066,7 @@ static int rtl8169_change_mtu(struct net_device *dev, int new_mtu)
 
        netif_poll_enable(dev);
 
-       rtl8169_hw_start(dev);
+       rtl_hw_start(dev);
 
        rtl8169_request_timer(dev);
 
@@ -1997,38 +2107,38 @@ static inline void rtl8169_map_to_asic(struct RxDesc *desc, dma_addr_t mapping,
        rtl8169_mark_to_asic(desc, rx_buf_sz);
 }
 
-static int rtl8169_alloc_rx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff,
-                               struct RxDesc *desc, int rx_buf_sz,
-                               unsigned int align)
+static struct sk_buff *rtl8169_alloc_rx_skb(struct pci_dev *pdev,
+                                           struct net_device *dev,
+                                           struct RxDesc *desc, int rx_buf_sz,
+                                           unsigned int align)
 {
        struct sk_buff *skb;
        dma_addr_t mapping;
-       int ret = 0;
+       unsigned int pad;
 
-       skb = dev_alloc_skb(rx_buf_sz + align);
+       pad = align ? align : NET_IP_ALIGN;
+
+       skb = netdev_alloc_skb(dev, rx_buf_sz + pad);
        if (!skb)
                goto err_out;
 
-       skb_reserve(skb, (align - 1) & (unsigned long)skb->data);
-       *sk_buff = skb;
+       skb_reserve(skb, align ? ((pad - 1) & (unsigned long)skb->data) : pad);
 
        mapping = pci_map_single(pdev, skb->data, rx_buf_sz,
                                 PCI_DMA_FROMDEVICE);
 
        rtl8169_map_to_asic(desc, mapping, rx_buf_sz);
-
 out:
-       return ret;
+       return skb;
 
 err_out:
-       ret = -ENOMEM;
        rtl8169_make_unusable_by_asic(desc);
        goto out;
 }
 
 static void rtl8169_rx_clear(struct rtl8169_private *tp)
 {
-       int i;
+       unsigned int i;
 
        for (i = 0; i < NUM_RX_DESC; i++) {
                if (tp->Rx_skbuff[i]) {
@@ -2043,16 +2153,22 @@ static u32 rtl8169_rx_fill(struct rtl8169_private *tp, struct net_device *dev,
 {
        u32 cur;
 
-       for (cur = start; end - cur > 0; cur++) {
-               int ret, i = cur % NUM_RX_DESC;
+       for (cur = start; end - cur != 0; cur++) {
+               struct sk_buff *skb;
+               unsigned int i = cur % NUM_RX_DESC;
+
+               WARN_ON((s32)(end - cur) < 0);
 
                if (tp->Rx_skbuff[i])
                        continue;
 
-               ret = rtl8169_alloc_rx_skb(tp->pci_dev, tp->Rx_skbuff + i,
-                       tp->RxDescArray + i, tp->rx_buf_sz, tp->align);
-               if (ret < 0)
+               skb = rtl8169_alloc_rx_skb(tp->pci_dev, dev,
+                                          tp->RxDescArray + i,
+                                          tp->rx_buf_sz, tp->align);
+               if (!skb)
                        break;
+
+               tp->Rx_skbuff[i] = skb;
        }
        return cur - start;
 }
@@ -2164,14 +2280,9 @@ static void rtl8169_reinit_task(struct work_struct *work)
 
        ret = rtl8169_open(dev);
        if (unlikely(ret < 0)) {
-               if (net_ratelimit()) {
-                       struct rtl8169_private *tp = netdev_priv(dev);
-
-                       if (netif_msg_drv(tp)) {
-                               printk(PFX KERN_ERR
-                                      "%s: reinit failure (status = %d)."
-                                      " Rescheduling.\n", dev->name, ret);
-                       }
+               if (net_ratelimit() && netif_msg_drv(tp)) {
+                       printk(PFX KERN_ERR "%s: reinit failure (status = %d)."
+                              " Rescheduling.\n", dev->name, ret);
                }
                rtl8169_schedule_work(dev, rtl8169_reinit_task);
        }
@@ -2198,16 +2309,12 @@ static void rtl8169_reset_task(struct work_struct *work)
 
        if (tp->dirty_rx == tp->cur_rx) {
                rtl8169_init_ring_indexes(tp);
-               rtl8169_hw_start(dev);
+               rtl_hw_start(dev);
                netif_wake_queue(dev);
        } else {
-               if (net_ratelimit()) {
-                       struct rtl8169_private *tp = netdev_priv(dev);
-
-                       if (netif_msg_intr(tp)) {
-                               printk(PFX KERN_EMERG
-                                      "%s: Rx buffers shortage\n", dev->name);
-                       }
+               if (net_ratelimit() && netif_msg_intr(tp)) {
+                       printk(PFX KERN_EMERG "%s: Rx buffers shortage\n",
+                              dev->name);
                }
                rtl8169_schedule_work(dev, rtl8169_reset_task);
        }
@@ -2344,7 +2451,7 @@ static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        smp_wmb();
 
-       RTL_W8(TxPoll, 0x40);   /* set polling bit */
+       RTL_W8(TxPoll, NPQ);    /* set polling bit */
 
        if (TX_BUFFS_AVAIL(tp) < MAX_SKB_FRAGS) {
                netif_stop_queue(dev);
@@ -2414,16 +2521,12 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev)
        rtl8169_schedule_work(dev, rtl8169_reinit_task);
 }
 
-static void
-rtl8169_tx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
-                    void __iomem *ioaddr)
+static void rtl8169_tx_interrupt(struct net_device *dev,
+                                struct rtl8169_private *tp,
+                                void __iomem *ioaddr)
 {
        unsigned int dirty_tx, tx_left;
 
-       assert(dev != NULL);
-       assert(tp != NULL);
-       assert(ioaddr != NULL);
-
        dirty_tx = tp->dirty_tx;
        smp_rmb();
        tx_left = tp->cur_tx - dirty_tx;
@@ -2480,38 +2583,37 @@ static inline void rtl8169_rx_csum(struct sk_buff *skb, struct RxDesc *desc)
                skb->ip_summed = CHECKSUM_NONE;
 }
 
-static inline int rtl8169_try_rx_copy(struct sk_buff **sk_buff, int pkt_size,
-                                     struct RxDesc *desc, int rx_buf_sz,
-                                     unsigned int align)
+static inline bool rtl8169_try_rx_copy(struct sk_buff **sk_buff,
+                                      struct rtl8169_private *tp, int pkt_size,
+                                      dma_addr_t addr)
 {
-       int ret = -1;
+       struct sk_buff *skb;
+       bool done = false;
 
-       if (pkt_size < rx_copybreak) {
-               struct sk_buff *skb;
+       if (pkt_size >= rx_copybreak)
+               goto out;
 
-               skb = dev_alloc_skb(pkt_size + align);
-               if (skb) {
-                       skb_reserve(skb, (align - 1) & (unsigned long)skb->data);
-                       eth_copy_and_sum(skb, sk_buff[0]->data, pkt_size, 0);
-                       *sk_buff = skb;
-                       rtl8169_mark_to_asic(desc, rx_buf_sz);
-                       ret = 0;
-               }
-       }
-       return ret;
+       skb = netdev_alloc_skb(tp->dev, pkt_size + NET_IP_ALIGN);
+       if (!skb)
+               goto out;
+
+       pci_dma_sync_single_for_cpu(tp->pci_dev, addr, pkt_size,
+                                   PCI_DMA_FROMDEVICE);
+       skb_reserve(skb, NET_IP_ALIGN);
+       skb_copy_from_linear_data(*sk_buff, skb->data, pkt_size);
+       *sk_buff = skb;
+       done = true;
+out:
+       return done;
 }
 
-static int
-rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
-                    void __iomem *ioaddr)
+static int rtl8169_rx_interrupt(struct net_device *dev,
+                               struct rtl8169_private *tp,
+                               void __iomem *ioaddr)
 {
        unsigned int cur_rx, rx_left;
        unsigned int delta, count;
 
-       assert(dev != NULL);
-       assert(tp != NULL);
-       assert(ioaddr != NULL);
-
        cur_rx = tp->cur_rx;
        rx_left = NUM_RX_DESC + tp->dirty_rx - cur_rx;
        rx_left = rtl8169_rx_quota(rx_left, (u32) dev->quota);
@@ -2544,9 +2646,9 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
                        rtl8169_mark_to_asic(desc, tp->rx_buf_sz);
                } else {
                        struct sk_buff *skb = tp->Rx_skbuff[entry];
+                       dma_addr_t addr = le64_to_cpu(desc->addr);
                        int pkt_size = (status & 0x00001FFF) - 4;
-                       void (*pci_action)(struct pci_dev *, dma_addr_t,
-                               size_t, int) = pci_dma_sync_single_for_device;
+                       struct pci_dev *pdev = tp->pci_dev;
 
                        /*
                         * The driver does not support incoming fragmented
@@ -2562,19 +2664,16 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
 
                        rtl8169_rx_csum(skb, desc);
 
-                       pci_dma_sync_single_for_cpu(tp->pci_dev,
-                               le64_to_cpu(desc->addr), tp->rx_buf_sz,
-                               PCI_DMA_FROMDEVICE);
-
-                       if (rtl8169_try_rx_copy(&skb, pkt_size, desc,
-                                               tp->rx_buf_sz, tp->align)) {
-                               pci_action = pci_unmap_single;
+                       if (rtl8169_try_rx_copy(&skb, tp, pkt_size, addr)) {
+                               pci_dma_sync_single_for_device(pdev, addr,
+                                       pkt_size, PCI_DMA_FROMDEVICE);
+                               rtl8169_mark_to_asic(desc, tp->rx_buf_sz);
+                       } else {
+                               pci_unmap_single(pdev, addr, pkt_size,
+                                                PCI_DMA_FROMDEVICE);
                                tp->Rx_skbuff[entry] = NULL;
                        }
 
-                       pci_action(tp->pci_dev, le64_to_cpu(desc->addr),
-                                  tp->rx_buf_sz, PCI_DMA_FROMDEVICE);
-
                        skb_put(skb, pkt_size);
                        skb->protocol = eth_type_trans(skb, dev);
 
@@ -2585,6 +2684,13 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
                        tp->stats.rx_bytes += pkt_size;
                        tp->stats.rx_packets++;
                }
+
+               /* Work around for AMD plateform. */
+               if ((desc->opts2 & 0xfffe000) &&
+                   (tp->mac_version == RTL_GIGA_MAC_VER_05)) {
+                       desc->opts2 = 0;
+                       cur_rx++;
+               }
        }
 
        count = cur_rx - tp->cur_rx;
@@ -2608,11 +2714,9 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
        return count;
 }
 
-/* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */
-static irqreturn_t
-rtl8169_interrupt(int irq, void *dev_instance)
+static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
 {
-       struct net_device *dev = (struct net_device *) dev_instance;
+       struct net_device *dev = dev_instance;
        struct rtl8169_private *tp = netdev_priv(dev);
        int boguscnt = max_interrupt_work;
        void __iomem *ioaddr = tp->mmio_addr;
@@ -2637,9 +2741,17 @@ rtl8169_interrupt(int irq, void *dev_instance)
                RTL_W16(IntrStatus,
                        (status & RxFIFOOver) ? (status | RxOverflow) : status);
 
-               if (!(status & rtl8169_intr_mask))
+               if (!(status & tp->intr_event))
                        break;
 
+                /* Work around for rx fifo overflow */
+                if (unlikely(status & RxFIFOOver) &&
+                   (tp->mac_version == RTL_GIGA_MAC_VER_11)) {
+                       netif_stop_queue(dev);
+                       rtl8169_tx_timeout(dev);
+                       break;
+               }
+
                if (unlikely(status & SYSErr)) {
                        rtl8169_pcierr_interrupt(dev);
                        break;
@@ -2649,8 +2761,8 @@ rtl8169_interrupt(int irq, void *dev_instance)
                        rtl8169_check_link_status(dev, tp, ioaddr);
 
 #ifdef CONFIG_R8169_NAPI
-               RTL_W16(IntrMask, rtl8169_intr_mask & ~rtl8169_napi_event);
-               tp->intr_mask = ~rtl8169_napi_event;
+               RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event);
+               tp->intr_mask = ~tp->napi_event;
 
                if (likely(netif_rx_schedule_prep(dev)))
                        __netif_rx_schedule(dev);
@@ -2661,9 +2773,9 @@ rtl8169_interrupt(int irq, void *dev_instance)
                break;
 #else
                /* Rx interrupt */
-               if (status & (RxOK | RxOverflow | RxFIFOOver)) {
+               if (status & (RxOK | RxOverflow | RxFIFOOver))
                        rtl8169_rx_interrupt(dev, tp, ioaddr);
-               }
+
                /* Tx interrupt */
                if (status & (TxOK | TxErr))
                        rtl8169_tx_interrupt(dev, tp, ioaddr);
@@ -2707,7 +2819,7 @@ static int rtl8169_poll(struct net_device *dev, int *budget)
                 * write is safe - FR
                 */
                smp_wmb();
-               RTL_W16(IntrMask, rtl8169_intr_mask);
+               RTL_W16(IntrMask, tp->intr_event);
        }
 
        return (work_done >= work_to_do);
@@ -2789,14 +2901,13 @@ static int rtl8169_close(struct net_device *dev)
        return 0;
 }
 
-static void
-rtl8169_set_rx_mode(struct net_device *dev)
+static void rtl_set_rx_mode(struct net_device *dev)
 {
        struct rtl8169_private *tp = netdev_priv(dev);
        void __iomem *ioaddr = tp->mmio_addr;
        unsigned long flags;
        u32 mc_filter[2];       /* Multicast hash filter */
-       int i, rx_mode;
+       int rx_mode;
        u32 tmp = 0;
 
        if (dev->flags & IFF_PROMISC) {
@@ -2816,6 +2927,8 @@ rtl8169_set_rx_mode(struct net_device *dev)
                mc_filter[1] = mc_filter[0] = 0xffffffff;
        } else {
                struct dev_mc_list *mclist;
+               unsigned int i;
+
                rx_mode = AcceptBroadcast | AcceptMyPhys;
                mc_filter[1] = mc_filter[0] = 0;
                for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
@@ -2840,10 +2953,11 @@ rtl8169_set_rx_mode(struct net_device *dev)
                mc_filter[1] = 0xffffffff;
        }
 
-       RTL_W32(RxConfig, tmp);
        RTL_W32(MAR0 + 0, mc_filter[0]);
        RTL_W32(MAR0 + 4, mc_filter[1]);
 
+       RTL_W32(RxConfig, tmp);
+
        spin_unlock_irqrestore(&tp->lock, flags);
 }
 
@@ -2931,14 +3045,12 @@ static struct pci_driver rtl8169_pci_driver = {
 #endif
 };
 
-static int __init
-rtl8169_init_module(void)
+static int __init rtl8169_init_module(void)
 {
        return pci_register_driver(&rtl8169_pci_driver);
 }
 
-static void __exit
-rtl8169_cleanup_module(void)
+static void __exit rtl8169_cleanup_module(void)
 {
        pci_unregister_driver(&rtl8169_pci_driver);
 }
index 25c73d47daad9c29c0bb52e5c9035efbd9818909..5c2e41fac6d2d8bee3d57330cf73149f71b3dba1 100644 (file)
@@ -516,7 +516,7 @@ static unsigned int write_eeprom(struct rr_private *rrpriv,
 }
 
 
-static int __init rr_init(struct net_device *dev)
+static int __devinit rr_init(struct net_device *dev)
 {
        struct rr_private *rrpriv;
        struct rr_regs __iomem *regs;
index 09078ff84cd2f20478373d8a93a1ec4db8ce5e66..58bbfdd4f9016e29026fbe8527a46966f626619e 100644 (file)
@@ -469,11 +469,18 @@ static struct pci_device_id s2io_tbl[] __devinitdata = {
 
 MODULE_DEVICE_TABLE(pci, s2io_tbl);
 
+static struct pci_error_handlers s2io_err_handler = {
+       .error_detected = s2io_io_error_detected,
+       .slot_reset = s2io_io_slot_reset,
+       .resume = s2io_io_resume,
+};
+
 static struct pci_driver s2io_driver = {
       .name = "S2IO",
       .id_table = s2io_tbl,
       .probe = s2io_init_nic,
       .remove = __devexit_p(s2io_rem_nic),
+      .err_handler = &s2io_err_handler,
 };
 
 /* A simplifier macro used both by init and free shared_mem Fns(). */
@@ -1128,7 +1135,7 @@ static int init_nic(struct s2io_nic *nic)
         * SXE-008 TRANSMIT DMA ARBITRATION ISSUE.
         */
        if ((nic->device_type == XFRAME_I_DEVICE) &&
-               (get_xena_rev_id(nic->pdev) < 4))
+               (nic->pdev->revision < 4))
                writeq(PCC_ENABLE_FOUR, &bar0->pcc_enable);
 
        val64 = readq(&bar0->tx_fifo_partition_0);
@@ -1866,7 +1873,7 @@ static int verify_pcc_quiescent(struct s2io_nic *sp, int flag)
        herc = (sp->device_type == XFRAME_II_DEVICE);
 
        if (flag == FALSE) {
-               if ((!herc && (get_xena_rev_id(sp->pdev) >= 4)) || herc) {
+               if ((!herc && (sp->pdev->revision >= 4)) || herc) {
                        if (!(val64 & ADAPTER_STATUS_RMAC_PCC_IDLE))
                                ret = 1;
                } else {
@@ -1874,7 +1881,7 @@ static int verify_pcc_quiescent(struct s2io_nic *sp, int flag)
                                ret = 1;
                }
        } else {
-               if ((!herc && (get_xena_rev_id(sp->pdev) >= 4)) || herc) {
+               if ((!herc && (sp->pdev->revision >= 4)) || herc) {
                        if (((val64 & ADAPTER_STATUS_RMAC_PCC_IDLE) ==
                             ADAPTER_STATUS_RMAC_PCC_IDLE))
                                ret = 1;
@@ -2689,6 +2696,9 @@ static void s2io_netpoll(struct net_device *dev)
        u64 val64 = 0xFFFFFFFFFFFFFFFFULL;
        int i;
 
+       if (pci_channel_offline(nic->pdev))
+               return;
+
        disable_irq(dev->irq);
 
        atomic_inc(&nic->isr_cnt);
@@ -3215,6 +3225,8 @@ static void alarm_intr_handler(struct s2io_nic *nic)
        int i;
        if (atomic_read(&nic->card_state) == CARD_DOWN)
                return;
+       if (pci_channel_offline(nic->pdev))
+               return;
        nic->mac_control.stats_info->sw_stat.ring_full_cnt = 0;
        /* Handling the XPAK counters update */
        if(nic->mac_control.stats_info->xpak_stat.xpak_timer_count < 72000) {
@@ -3958,7 +3970,6 @@ static int s2io_close(struct net_device *dev)
        /* Reset card, kill tasklet and free Tx and Rx buffers. */
        s2io_card_down(sp);
 
-       sp->device_close_flag = TRUE;   /* Device is shut down. */
        return 0;
 }
 
@@ -4314,6 +4325,10 @@ static irqreturn_t s2io_isr(int irq, void *dev_id)
        struct mac_info *mac_control;
        struct config_param *config;
 
+       /* Pretend we handled any irq's from a disconnected card */
+       if (pci_channel_offline(sp->pdev))
+               return IRQ_NONE;
+
        atomic_inc(&sp->isr_cnt);
        mac_control = &sp->mac_control;
        config = &sp->config;
@@ -6569,7 +6584,7 @@ static void s2io_rem_isr(struct s2io_nic * sp)
        } while(cnt < 5);
 }
 
-static void s2io_card_down(struct s2io_nic * sp)
+static void do_s2io_card_down(struct s2io_nic * sp, int do_io)
 {
        int cnt = 0;
        struct XENA_dev_config __iomem *bar0 = sp->bar0;
@@ -6584,7 +6599,8 @@ static void s2io_card_down(struct s2io_nic * sp)
        atomic_set(&sp->card_state, CARD_DOWN);
 
        /* disable Tx and Rx traffic on the NIC */
-       stop_nic(sp);
+       if (do_io)
+               stop_nic(sp);
 
        s2io_rem_isr(sp);
 
@@ -6592,7 +6608,7 @@ static void s2io_card_down(struct s2io_nic * sp)
        tasklet_kill(&sp->task);
 
        /* Check if the device is Quiescent and then Reset the NIC */
-       do {
+       while(do_io) {
                /* As per the HW requirement we need to replenish the
                 * receive buffer to avoid the ring bump. Since there is
                 * no intention of processing the Rx frame at this pointwe are
@@ -6617,8 +6633,9 @@ static void s2io_card_down(struct s2io_nic * sp)
                                  (unsigned long long) val64);
                        break;
                }
-       } while (1);
-       s2io_reset(sp);
+       }
+       if (do_io)
+               s2io_reset(sp);
 
        spin_lock_irqsave(&sp->tx_lock, flags);
        /* Free all Tx buffers */
@@ -6633,6 +6650,11 @@ static void s2io_card_down(struct s2io_nic * sp)
        clear_bit(0, &(sp->link_state));
 }
 
+static void s2io_card_down(struct s2io_nic * sp)
+{
+       do_s2io_card_down(sp, 1);
+}
+
 static int s2io_card_up(struct s2io_nic * sp)
 {
        int i, ret = 0;
@@ -7053,23 +7075,6 @@ static void s2io_link(struct s2io_nic * sp, int link)
        sp->start_time = jiffies;
 }
 
-/**
- *  get_xena_rev_id - to identify revision ID of xena.
- *  @pdev : PCI Dev structure
- *  Description:
- *  Function to identify the Revision ID of xena.
- *  Return value:
- *  returns the revision ID of the device.
- */
-
-static int get_xena_rev_id(struct pci_dev *pdev)
-{
-       u8 id = 0;
-       int ret;
-       ret = pci_read_config_byte(pdev, PCI_REVISION_ID, (u8 *) & id);
-       return id;
-}
-
 /**
  *  s2io_init_pci -Initialization of PCI and PCI-X configuration registers .
  *  @sp : private member of the device structure, which is a pointer to the
@@ -7528,7 +7533,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
        s2io_vpd_read(sp);
        DBG_PRINT(ERR_DBG, "Copyright(c) 2002-2007 Neterion Inc.\n");
        DBG_PRINT(ERR_DBG, "%s: Neterion %s (rev %d)\n",dev->name,
-                 sp->product_name, get_xena_rev_id(sp->pdev));
+                 sp->product_name, pdev->revision);
        DBG_PRINT(ERR_DBG, "%s: Driver version %s\n", dev->name,
                  s2io_driver_version);
        DBG_PRINT(ERR_DBG, "%s: MAC ADDR: "
@@ -8010,3 +8015,85 @@ static void lro_append_pkt(struct s2io_nic *sp, struct lro *lro,
        sp->mac_control.stats_info->sw_stat.clubbed_frms_cnt++;
        return;
 }
+
+/**
+ * s2io_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 s2io_io_error_detected(struct pci_dev *pdev,
+                                               pci_channel_state_t state)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct s2io_nic *sp = netdev->priv;
+
+       netif_device_detach(netdev);
+
+       if (netif_running(netdev)) {
+               /* Bring down the card, while avoiding PCI I/O */
+               do_s2io_card_down(sp, 0);
+       }
+       pci_disable_device(pdev);
+
+       return PCI_ERS_RESULT_NEED_RESET;
+}
+
+/**
+ * s2io_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.
+ * At this point, the card has exprienced a hard reset,
+ * followed by fixups by BIOS, and has its config space
+ * set up identically to what it was at cold boot.
+ */
+static pci_ers_result_t s2io_io_slot_reset(struct pci_dev *pdev)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct s2io_nic *sp = netdev->priv;
+
+       if (pci_enable_device(pdev)) {
+               printk(KERN_ERR "s2io: "
+                      "Cannot re-enable PCI device after reset.\n");
+               return PCI_ERS_RESULT_DISCONNECT;
+       }
+
+       pci_set_master(pdev);
+       s2io_reset(sp);
+
+       return PCI_ERS_RESULT_RECOVERED;
+}
+
+/**
+ * s2io_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.
+ */
+static void s2io_io_resume(struct pci_dev *pdev)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct s2io_nic *sp = netdev->priv;
+
+       if (netif_running(netdev)) {
+               if (s2io_card_up(sp)) {
+                       printk(KERN_ERR "s2io: "
+                              "Can't bring device back up after reset.\n");
+                       return;
+               }
+
+               if (s2io_set_mac_addr(netdev, netdev->dev_addr) == FAILURE) {
+                       s2io_card_down(sp);
+                       printk(KERN_ERR "s2io: "
+                              "Can't resetore mac addr after reset.\n");
+                       return;
+               }
+       }
+
+       netif_device_attach(netdev);
+       netif_wake_queue(netdev);
+}
index 54baa0b8ec7c937a17b8f2ae984e2799831cb9c6..3887fe63a908146bc2fdff545a73ed2eebab098e 100644 (file)
@@ -794,7 +794,6 @@ struct s2io_nic {
 
        struct net_device_stats stats;
        int high_dma_flag;
-       int device_close_flag;
        int device_enabled_once;
 
        char name[60];
@@ -1034,7 +1033,6 @@ static void s2io_set_link(struct work_struct *work);
 static int s2io_set_swapper(struct s2io_nic * sp);
 static void s2io_card_down(struct s2io_nic *nic);
 static int s2io_card_up(struct s2io_nic *nic);
-static int get_xena_rev_id(struct pci_dev *pdev);
 static int wait_for_cmd_complete(void __iomem *addr, u64 busy_bit,
                                        int bit_state);
 static int s2io_add_isr(struct s2io_nic * sp);
@@ -1052,6 +1050,11 @@ static void lro_append_pkt(struct s2io_nic *sp, struct lro *lro,
                           struct sk_buff *skb, u32 tcp_len);
 static int rts_ds_steer(struct s2io_nic *nic, u8 ds_codepoint, u8 ring);
 
+static pci_ers_result_t s2io_io_error_detected(struct pci_dev *pdev,
+                                             pci_channel_state_t state);
+static pci_ers_result_t s2io_io_slot_reset(struct pci_dev *pdev);
+static void s2io_io_resume(struct pci_dev *pdev);
+
 #define s2io_tcp_mss(skb) skb_shinfo(skb)->gso_size
 #define s2io_udp_mss(skb) skb_shinfo(skb)->gso_size
 #define s2io_offload_type(skb) skb_shinfo(skb)->gso_type
index ad94358ece8943da8e9327052657b99bc7a71301..451486b32f233e04de60207fb965b9c0e7873e4f 100644 (file)
@@ -690,9 +690,9 @@ static int lan_saa9730_rx(struct net_device *dev)
                                lp->stats.rx_packets++;
                                skb_reserve(skb, 2);    /* 16 byte align */
                                skb_put(skb, len);      /* make room */
-                               eth_copy_and_sum(skb,
+                               skb_copy_to_linear_data(skb,
                                                 (unsigned char *) pData,
-                                                len, 0);
+                                                len);
                                skb->protocol = eth_type_trans(skb, dev);
                                netif_rx(skb);
                                dev->last_rx = jiffies;
index 2106becf6990c42dbe297753f3aeb07cd12ba1c8..384b4685e977a453884d56fc81c4f2b0747680da 100644 (file)
@@ -320,7 +320,7 @@ static inline void sgiseeq_rx(struct net_device *dev, struct sgiseeq_private *sp
                                skb_put(skb, len);
 
                                /* Copy out of kseg1 to avoid silly cache flush. */
-                               eth_copy_and_sum(skb, pkt_pointer + 2, len, 0);
+                               skb_copy_to_linear_data(skb, pkt_pointer + 2, len);
                                skb->protocol = eth_type_trans(skb, dev);
 
                                /* We don't want to receive our own packets */
index bc8de48da3135f923525a3f8c902c9c5fbd26d9f..ec2ad9f0efa25bcbc46509149920bdd8a6a4ec5a 100644 (file)
@@ -548,7 +548,7 @@ static inline int sis190_try_rx_copy(struct sk_buff **sk_buff, int pkt_size,
                skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN);
                if (skb) {
                        skb_reserve(skb, NET_IP_ALIGN);
-                       eth_copy_and_sum(skb, sk_buff[0]->data, pkt_size, 0);
+                       skb_copy_to_linear_data(skb, sk_buff[0]->data, pkt_size);
                        *sk_buff = skb;
                        sis190_give_to_asic(desc, rx_buf_sz);
                        ret = 0;
index 2cb2e156c7587cbd1878ab743b3fda3f754ac41f..7c6e4808399a047501f0fddbe0a4462f2f4fab13 100644 (file)
@@ -573,7 +573,7 @@ static int __devinit sis900_probe(struct pci_dev *pci_dev,
  *     return error if it failed to found.
  */
 
-static int __init sis900_mii_probe(struct net_device * net_dev)
+static int __devinit sis900_mii_probe(struct net_device * net_dev)
 {
        struct sis900_private * sis_priv = net_dev->priv;
        const char *dev_name = pci_name(sis_priv->pci_dev);
diff --git a/drivers/net/sk98lin/Makefile b/drivers/net/sk98lin/Makefile
deleted file mode 100644 (file)
index afd900d..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-#
-# Makefile for the SysKonnect SK-98xx device driver.
-#
-
-
-#
-# Standalone driver params
-# SKPARAM += -DSK_KERNEL_24
-# SKPARAM += -DSK_KERNEL_24_26
-# SKPARAM += -DSK_KERNEL_26
-# SKPARAM += -DSK_KERNEL_22_24
-
-obj-$(CONFIG_SK98LIN) += sk98lin.o
-sk98lin-objs    :=     \
-               skge.o          \
-               skethtool.o     \
-               skdim.o         \
-               skaddr.o        \
-               skgehwt.o       \
-               skgeinit.o      \
-               skgepnmi.o      \
-               skgesirq.o      \
-               ski2c.o         \
-               sklm80.o        \
-               skqueue.o       \
-               skrlmt.o        \
-               sktimer.o       \
-               skvpd.o         \
-               skxmac2.o
-
-# DBGDEF =  \
-# -DDEBUG
-
-ifdef DEBUG
-DBGDEF +=  \
--DSK_DEBUG_CHKMOD=0x00000000L \
--DSK_DEBUG_CHKCAT=0x00000000L
-endif
-
-
-# **** possible debug modules for SK_DEBUG_CHKMOD *****************
-# SK_DBGMOD_MERR        0x00000001L     /* general module error indication */
-# SK_DBGMOD_HWM         0x00000002L     /* Hardware init module */
-# SK_DBGMOD_RLMT        0x00000004L     /* RLMT module */
-# SK_DBGMOD_VPD         0x00000008L     /* VPD module */
-# SK_DBGMOD_I2C         0x00000010L     /* I2C module */
-# SK_DBGMOD_PNMI        0x00000020L     /* PNMI module */
-# SK_DBGMOD_CSUM        0x00000040L     /* CSUM module */
-# SK_DBGMOD_ADDR        0x00000080L     /* ADDR module */
-# SK_DBGMOD_DRV         0x00010000L     /* DRV module */
-
-# **** possible debug categories for SK_DEBUG_CHKCAT **************
-# *** common modules ***
-# SK_DBGCAT_INIT        0x00000001L     module/driver initialization
-# SK_DBGCAT_CTRL        0x00000002L     controlling: add/rmv MCA/MAC and other controls (IOCTL)
-# SK_DBGCAT_ERR         0x00000004L     error handling paths
-# SK_DBGCAT_TX          0x00000008L     transmit path
-# SK_DBGCAT_RX          0x00000010L     receive path
-# SK_DBGCAT_IRQ         0x00000020L     general IRQ handling
-# SK_DBGCAT_QUEUE       0x00000040L     any queue management
-# SK_DBGCAT_DUMP        0x00000080L     large data output e.g. hex dump
-# SK_DBGCAT_FATAL       0x00000100L     large data output e.g. hex dump
-
-# *** driver (file skge.c) ***
-# SK_DBGCAT_DRV_ENTRY           0x00010000      entry points
-# SK_DBGCAT_DRV_???             0x00020000      not used
-# SK_DBGCAT_DRV_MCA             0x00040000      multicast
-# SK_DBGCAT_DRV_TX_PROGRESS     0x00080000      tx path
-# SK_DBGCAT_DRV_RX_PROGRESS     0x00100000      rx path
-# SK_DBGCAT_DRV_PROGRESS        0x00200000      general runtime
-# SK_DBGCAT_DRV_???             0x00400000      not used
-# SK_DBGCAT_DRV_PROM            0x00800000      promiscuous mode
-# SK_DBGCAT_DRV_TX_FRAME        0x01000000      display tx frames
-# SK_DBGCAT_DRV_ERROR           0x02000000      error conditions
-# SK_DBGCAT_DRV_INT_SRC         0x04000000      interrupts sources
-# SK_DBGCAT_DRV_EVENT           0x08000000      driver events
-
-EXTRA_CFLAGS += -Idrivers/net/sk98lin -DSK_DIAG_SUPPORT -DGENESIS -DYUKON $(DBGDEF) $(SKPARAM)
-
-clean:
-       rm -f core *.o *.a *.s
-
-
-
-
-
-
diff --git a/drivers/net/sk98lin/h/lm80.h b/drivers/net/sk98lin/h/lm80.h
deleted file mode 100644 (file)
index 4e2dbbf..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-/******************************************************************************
- *
- * Name:       lm80.h  
- * Project:    Gigabit Ethernet Adapters, Common Modules
- * Version:    $Revision: 1.6 $
- * Date:       $Date: 2003/05/13 17:26:52 $
- * Purpose:    Contains all defines for the LM80 Chip
- *             (National Semiconductor).
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect.
- *     (C)Copyright 2002-2003 Marvell.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-#ifndef __INC_LM80_H
-#define __INC_LM80_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/* defines ********************************************************************/
-
-/*
- * LM80 register definition
- *
- * All registers are 8 bit wide
- */
-#define LM80_CFG                       0x00    /* Configuration Register */
-#define LM80_ISRC_1                    0x01    /* Interrupt Status Register 1 */
-#define LM80_ISRC_2                    0x02    /* Interrupt Status Register 2 */
-#define LM80_IMSK_1                    0x03    /* Interrupt Mask Register 1 */
-#define LM80_IMSK_2                    0x04    /* Interrupt Mask Register 2 */
-#define LM80_FAN_CTRL          0x05    /* Fan Devisor/RST#/OS# Register */
-#define LM80_TEMP_CTRL         0x06    /* OS# Config, Temp Res. Reg */
-       /* 0x07 - 0x1f reserved */
-       /* current values */
-#define LM80_VT0_IN                    0x20    /* current Voltage 0 value */
-#define LM80_VT1_IN                    0x21    /* current Voltage 1 value */
-#define LM80_VT2_IN                    0x22    /* current Voltage 2 value */
-#define LM80_VT3_IN                    0x23    /* current Voltage 3 value */
-#define LM80_VT4_IN                    0x24    /* current Voltage 4 value */
-#define LM80_VT5_IN                    0x25    /* current Voltage 5 value */
-#define LM80_VT6_IN                    0x26    /* current Voltage 6 value */
-#define LM80_TEMP_IN           0x27    /* current Temperature value */
-#define LM80_FAN1_IN           0x28    /* current Fan 1 count */
-#define LM80_FAN2_IN           0x29    /* current Fan 2 count */
-       /* limit values */
-#define LM80_VT0_HIGH_LIM      0x2a    /* high limit val for Voltage 0 */
-#define LM80_VT0_LOW_LIM       0x2b    /* low limit val for Voltage 0 */
-#define LM80_VT1_HIGH_LIM      0x2c    /* high limit val for Voltage 1 */
-#define LM80_VT1_LOW_LIM       0x2d    /* low limit val for Voltage 1 */
-#define LM80_VT2_HIGH_LIM      0x2e    /* high limit val for Voltage 2 */
-#define LM80_VT2_LOW_LIM       0x2f    /* low limit val for Voltage 2 */
-#define LM80_VT3_HIGH_LIM      0x30    /* high limit val for Voltage 3 */
-#define LM80_VT3_LOW_LIM       0x31    /* low limit val for Voltage 3 */
-#define LM80_VT4_HIGH_LIM      0x32    /* high limit val for Voltage 4 */
-#define LM80_VT4_LOW_LIM       0x33    /* low limit val for Voltage 4 */
-#define LM80_VT5_HIGH_LIM      0x34    /* high limit val for Voltage 5 */
-#define LM80_VT5_LOW_LIM       0x35    /* low limit val for Voltage 5 */
-#define LM80_VT6_HIGH_LIM      0x36    /* high limit val for Voltage 6 */
-#define LM80_VT6_LOW_LIM       0x37    /* low limit val for Voltage 6 */
-#define LM80_THOT_LIM_UP       0x38    /* hot temperature limit (high) */
-#define LM80_THOT_LIM_LO       0x39    /* hot temperature limit (low) */
-#define LM80_TOS_LIM_UP                0x3a    /* OS temperature limit (high) */
-#define LM80_TOS_LIM_LO                0x3b    /* OS temperature limit (low) */
-#define LM80_FAN1_COUNT_LIM    0x3c    /* Fan 1 count limit (high) */
-#define LM80_FAN2_COUNT_LIM    0x3d    /* Fan 2 count limit (low) */
-       /* 0x3e - 0x3f reserved */
-
-/*
- * LM80 bit definitions
- */
-
-/*     LM80_CFG                Configuration Register */
-#define LM80_CFG_START         (1<<0)  /* start monitoring operation */
-#define LM80_CFG_INT_ENA       (1<<1)  /* enables the INT# Interrupt output */
-#define LM80_CFG_INT_POL       (1<<2)  /* INT# pol: 0 act low, 1 act high */
-#define LM80_CFG_INT_CLR       (1<<3)  /* disables INT#/RST_OUT#/OS# outputs */
-#define LM80_CFG_RESET         (1<<4)  /* signals a reset */
-#define LM80_CFG_CHASS_CLR     (1<<5)  /* clears Chassis Intrusion (CI) pin */
-#define LM80_CFG_GPO           (1<<6)  /* drives the GPO# pin */
-#define LM80_CFG_INIT          (1<<7)  /* restore power on defaults */
-
-/*     LM80_ISRC_1             Interrupt Status Register 1 */
-/*     LM80_IMSK_1             Interrupt Mask Register 1 */
-#define LM80_IS_VT0                    (1<<0)  /* limit exceeded for Voltage 0 */
-#define LM80_IS_VT1                    (1<<1)  /* limit exceeded for Voltage 1 */
-#define LM80_IS_VT2                    (1<<2)  /* limit exceeded for Voltage 2 */
-#define LM80_IS_VT3                    (1<<3)  /* limit exceeded for Voltage 3 */
-#define LM80_IS_VT4                    (1<<4)  /* limit exceeded for Voltage 4 */
-#define LM80_IS_VT5                    (1<<5)  /* limit exceeded for Voltage 5 */
-#define LM80_IS_VT6                    (1<<6)  /* limit exceeded for Voltage 6 */
-#define LM80_IS_INT_IN         (1<<7)  /* state of INT_IN# */
-
-/*     LM80_ISRC_2             Interrupt Status Register 2 */
-/*     LM80_IMSK_2             Interrupt Mask Register 2 */
-#define LM80_IS_TEMP           (1<<0)  /* HOT temperature limit exceeded */
-#define LM80_IS_BTI                    (1<<1)  /* state of BTI# pin */
-#define LM80_IS_FAN1           (1<<2)  /* count limit exceeded for Fan 1 */
-#define LM80_IS_FAN2           (1<<3)  /* count limit exceeded for Fan 2 */
-#define LM80_IS_CI                     (1<<4)  /* Chassis Intrusion occured */
-#define LM80_IS_OS                     (1<<5)  /* OS temperature limit exceeded */
-       /* bit 6 and 7 are reserved in LM80_ISRC_2 */
-#define LM80_IS_HT_IRQ_MD      (1<<6)  /* Hot temperature interrupt mode */
-#define LM80_IS_OT_IRQ_MD      (1<<7)  /* OS temperature interrupt mode */
-
-/*     LM80_FAN_CTRL           Fan Devisor/RST#/OS# Register */
-#define LM80_FAN1_MD_SEL       (1<<0)  /* Fan 1 mode select */
-#define LM80_FAN2_MD_SEL       (1<<1)  /* Fan 2 mode select */
-#define LM80_FAN1_PRM_CTL      (3<<2)  /* Fan 1 speed control */
-#define LM80_FAN2_PRM_CTL      (3<<4)  /* Fan 2 speed control */
-#define LM80_FAN_OS_ENA                (1<<6)  /* enable OS mode on RST_OUT#/OS# pins*/
-#define LM80_FAN_RST_ENA       (1<<7)  /* sets RST_OUT#/OS# pins in RST mode */
-
-/*     LM80_TEMP_CTRL          OS# Config, Temp Res. Reg */
-#define LM80_TEMP_OS_STAT      (1<<0)  /* mirrors the state of RST_OUT#/OS# */
-#define LM80_TEMP_OS_POL       (1<<1)  /* select OS# polarity */
-#define LM80_TEMP_OS_MODE      (1<<2)  /* selects Interrupt mode */
-#define LM80_TEMP_RES          (1<<3)  /* selects 9 or 11 bit temp resulution*/
-#define LM80_TEMP_LSB          (0xf<<4)/* 4 LSBs of 11 bit temp data */
-#define LM80_TEMP_LSB_9                (1<<7)  /* LSB of 9 bit temperature data */
-
-       /* 0x07 - 0x1f reserved */
-/*     LM80_VT0_IN             current Voltage 0 value */
-/*     LM80_VT1_IN             current Voltage 1 value */
-/*     LM80_VT2_IN             current Voltage 2 value */
-/*     LM80_VT3_IN             current Voltage 3 value */
-/*     LM80_VT4_IN             current Voltage 4 value */
-/*     LM80_VT5_IN             current Voltage 5 value */
-/*     LM80_VT6_IN             current Voltage 6 value */
-/*     LM80_TEMP_IN            current temperature value */
-/*     LM80_FAN1_IN            current Fan 1 count */
-/*     LM80_FAN2_IN            current Fan 2 count */
-/*     LM80_VT0_HIGH_LIM       high limit val for Voltage 0 */
-/*     LM80_VT0_LOW_LIM        low limit val for Voltage 0 */
-/*     LM80_VT1_HIGH_LIM       high limit val for Voltage 1 */
-/*     LM80_VT1_LOW_LIM        low limit val for Voltage 1 */
-/*     LM80_VT2_HIGH_LIM       high limit val for Voltage 2 */
-/*     LM80_VT2_LOW_LIM        low limit val for Voltage 2 */
-/*     LM80_VT3_HIGH_LIM       high limit val for Voltage 3 */
-/*     LM80_VT3_LOW_LIM        low limit val for Voltage 3 */
-/*     LM80_VT4_HIGH_LIM       high limit val for Voltage 4 */
-/*     LM80_VT4_LOW_LIM        low limit val for Voltage 4 */
-/*     LM80_VT5_HIGH_LIM       high limit val for Voltage 5 */
-/*     LM80_VT5_LOW_LIM        low limit val for Voltage 5 */
-/*     LM80_VT6_HIGH_LIM       high limit val for Voltage 6 */
-/*     LM80_VT6_LOW_LIM        low limit val for Voltage 6 */
-/*     LM80_THOT_LIM_UP        hot temperature limit (high) */
-/*     LM80_THOT_LIM_LO        hot temperature limit (low) */
-/*     LM80_TOS_LIM_UP         OS temperature limit (high) */
-/*     LM80_TOS_LIM_LO         OS temperature limit (low) */
-/*     LM80_FAN1_COUNT_LIM     Fan 1 count limit (high) */
-/*     LM80_FAN2_COUNT_LIM     Fan 2 count limit (low) */
-       /* 0x3e - 0x3f reserved */
-
-#define LM80_ADDR              0x28    /* LM80 default addr */
-
-/* typedefs *******************************************************************/
-
-
-/* function prototypes ********************************************************/
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __INC_LM80_H */
diff --git a/drivers/net/sk98lin/h/skaddr.h b/drivers/net/sk98lin/h/skaddr.h
deleted file mode 100644 (file)
index 423ad06..0000000
+++ /dev/null
@@ -1,285 +0,0 @@
-/******************************************************************************
- *
- * Name:       skaddr.h
- * Project:    Gigabit Ethernet Adapters, ADDR-Modul
- * Version:    $Revision: 1.29 $
- * Date:       $Date: 2003/05/13 16:57:24 $
- * Purpose:    Header file for Address Management (MC, UC, Prom).
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect GmbH.
- *     (C)Copyright 2002-2003 Marvell.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * Description:
- *
- * This module is intended to manage multicast addresses and promiscuous mode
- * on GEnesis adapters.
- *
- * Include File Hierarchy:
- *
- *     "skdrv1st.h"
- *     ...
- *     "sktypes.h"
- *     "skqueue.h"
- *     "skaddr.h"
- *     ...
- *     "skdrv2nd.h"
- *
- ******************************************************************************/
-
-#ifndef __INC_SKADDR_H
-#define __INC_SKADDR_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* cplusplus */
-
-/* defines ********************************************************************/
-
-#define SK_MAC_ADDR_LEN                                6       /* Length of MAC address. */
-#define        SK_MAX_ADDRS                            14      /* #Addrs for exact match. */
-
-/* ----- Common return values ----- */
-
-#define SK_ADDR_SUCCESS                                0       /* Function returned successfully. */
-#define SK_ADDR_ILLEGAL_PORT                   100     /* Port number too high. */
-#define SK_ADDR_TOO_EARLY                      101     /* Function called too early. */
-
-/* ----- Clear/Add flag bits ----- */
-
-#define SK_ADDR_PERMANENT                      1       /* RLMT Address */
-
-/* ----- Additional Clear flag bits ----- */
-
-#define SK_MC_SW_ONLY                          2       /* Do not update HW when clearing. */
-
-/* ----- Override flag bits ----- */
-
-#define SK_ADDR_LOGICAL_ADDRESS                0
-#define SK_ADDR_VIRTUAL_ADDRESS                (SK_ADDR_LOGICAL_ADDRESS)       /* old */
-#define SK_ADDR_PHYSICAL_ADDRESS       1
-#define SK_ADDR_CLEAR_LOGICAL          2
-#define SK_ADDR_SET_LOGICAL                    4
-
-/* ----- Override return values ----- */
-
-#define SK_ADDR_OVERRIDE_SUCCESS       (SK_ADDR_SUCCESS)
-#define SK_ADDR_DUPLICATE_ADDRESS      1
-#define SK_ADDR_MULTICAST_ADDRESS      2
-
-/* ----- Partitioning of excact match table ----- */
-
-#define SK_ADDR_EXACT_MATCHES          16      /* #Exact match entries. */
-
-#define SK_ADDR_FIRST_MATCH_RLMT       1
-#define SK_ADDR_LAST_MATCH_RLMT                2
-#define SK_ADDR_FIRST_MATCH_DRV                3
-#define SK_ADDR_LAST_MATCH_DRV         (SK_ADDR_EXACT_MATCHES - 1)
-
-/* ----- SkAddrMcAdd/SkAddrMcUpdate return values ----- */
-
-#define SK_MC_FILTERING_EXACT          0       /* Exact filtering. */
-#define SK_MC_FILTERING_INEXACT                1       /* Inexact filtering. */
-
-/* ----- Additional SkAddrMcAdd return values ----- */
-
-#define SK_MC_ILLEGAL_ADDRESS          2       /* Illegal address. */
-#define SK_MC_ILLEGAL_PORT                     3       /* Illegal port (not the active one). */
-#define SK_MC_RLMT_OVERFLOW                    4       /* Too many RLMT mc addresses. */
-
-/* Promiscuous mode bits ----- */
-
-#define SK_PROM_MODE_NONE                      0       /* Normal receive. */
-#define SK_PROM_MODE_LLC                       1       /* Receive all LLC frames. */
-#define SK_PROM_MODE_ALL_MC                    2       /* Receive all multicast frames. */
-/* #define SK_PROM_MODE_NON_LLC                4 */    /* Receive all non-LLC frames. */
-
-/* Macros */
-
-#ifdef OLD_STUFF
-#ifndef SK_ADDR_EQUAL
-/*
- * "&" instead of "&&" allows better optimization on IA-64.
- * The replacement is safe here, as all bytes exist.
- */
-#ifndef SK_ADDR_DWORD_COMPARE
-#define SK_ADDR_EQUAL(A1,A2)   ( \
-       (((SK_U8 *)(A1))[5] == ((SK_U8 *)(A2))[5]) & \
-       (((SK_U8 *)(A1))[4] == ((SK_U8 *)(A2))[4]) & \
-       (((SK_U8 *)(A1))[3] == ((SK_U8 *)(A2))[3]) & \
-       (((SK_U8 *)(A1))[2] == ((SK_U8 *)(A2))[2]) & \
-       (((SK_U8 *)(A1))[1] == ((SK_U8 *)(A2))[1]) & \
-       (((SK_U8 *)(A1))[0] == ((SK_U8 *)(A2))[0]))
-#else  /* SK_ADDR_DWORD_COMPARE */
-#define SK_ADDR_EQUAL(A1,A2)   ( \
-       (*(SK_U32 *)&(((SK_U8 *)(A1))[2]) == *(SK_U32 *)&(((SK_U8 *)(A2))[2])) & \
-       (*(SK_U32 *)&(((SK_U8 *)(A1))[0]) == *(SK_U32 *)&(((SK_U8 *)(A2))[0])))
-#endif /* SK_ADDR_DWORD_COMPARE */
-#endif /* SK_ADDR_EQUAL */
-#endif /* 0 */
-
-#ifndef SK_ADDR_EQUAL
-#ifndef SK_ADDR_DWORD_COMPARE
-#define SK_ADDR_EQUAL(A1,A2)   ( \
-       (((SK_U8 SK_FAR *)(A1))[5] == ((SK_U8 SK_FAR *)(A2))[5]) & \
-       (((SK_U8 SK_FAR *)(A1))[4] == ((SK_U8 SK_FAR *)(A2))[4]) & \
-       (((SK_U8 SK_FAR *)(A1))[3] == ((SK_U8 SK_FAR *)(A2))[3]) & \
-       (((SK_U8 SK_FAR *)(A1))[2] == ((SK_U8 SK_FAR *)(A2))[2]) & \
-       (((SK_U8 SK_FAR *)(A1))[1] == ((SK_U8 SK_FAR *)(A2))[1]) & \
-       (((SK_U8 SK_FAR *)(A1))[0] == ((SK_U8 SK_FAR *)(A2))[0]))
-#else  /* SK_ADDR_DWORD_COMPARE */
-#define SK_ADDR_EQUAL(A1,A2)   ( \
-       (*(SK_U16 SK_FAR *)&(((SK_U8 SK_FAR *)(A1))[4]) == \
-       *(SK_U16 SK_FAR *)&(((SK_U8 SK_FAR *)(A2))[4])) && \
-       (*(SK_U32 SK_FAR *)&(((SK_U8 SK_FAR *)(A1))[0]) == \
-       *(SK_U32 SK_FAR *)&(((SK_U8 SK_FAR *)(A2))[0])))
-#endif /* SK_ADDR_DWORD_COMPARE */
-#endif /* SK_ADDR_EQUAL */
-
-/* typedefs *******************************************************************/
-
-typedef struct s_MacAddr {
-       SK_U8   a[SK_MAC_ADDR_LEN];
-} SK_MAC_ADDR;
-
-
-/* SK_FILTER is used to ensure alignment of the filter. */
-typedef union s_InexactFilter {
-       SK_U8   Bytes[8];
-       SK_U64  Val;    /* Dummy entry for alignment only. */
-} SK_FILTER64;
-
-
-typedef struct s_AddrNet SK_ADDR_NET;
-
-
-typedef struct s_AddrPort {
-
-/* ----- Public part (read-only) ----- */
-
-       SK_MAC_ADDR     CurrentMacAddress;      /* Current physical MAC Address. */
-       SK_MAC_ADDR     PermanentMacAddress;    /* Permanent physical MAC Address. */
-       int             PromMode;               /* Promiscuous Mode. */
-
-/* ----- Private part ----- */
-
-       SK_MAC_ADDR     PreviousMacAddress;     /* Prev. phys. MAC Address. */
-       SK_BOOL         CurrentMacAddressSet;   /* CurrentMacAddress is set. */
-       SK_U8           Align01;
-
-       SK_U32          FirstExactMatchRlmt;
-       SK_U32          NextExactMatchRlmt;
-       SK_U32          FirstExactMatchDrv;
-       SK_U32          NextExactMatchDrv;
-       SK_MAC_ADDR     Exact[SK_ADDR_EXACT_MATCHES];
-       SK_FILTER64     InexactFilter;                  /* For 64-bit hash register. */
-       SK_FILTER64     InexactRlmtFilter;              /* For 64-bit hash register. */
-       SK_FILTER64     InexactDrvFilter;               /* For 64-bit hash register. */
-} SK_ADDR_PORT;
-
-
-struct s_AddrNet {
-/* ----- Public part (read-only) ----- */
-
-       SK_MAC_ADDR             CurrentMacAddress;      /* Logical MAC Address. */
-       SK_MAC_ADDR             PermanentMacAddress;    /* Logical MAC Address. */
-
-/* ----- Private part ----- */
-
-       SK_U32                  ActivePort;             /* View of module ADDR. */
-       SK_BOOL                 CurrentMacAddressSet;   /* CurrentMacAddress is set. */
-       SK_U8                   Align01;
-       SK_U16                  Align02;
-};
-
-
-typedef struct s_Addr {
-
-/* ----- Public part (read-only) ----- */
-
-       SK_ADDR_NET             Net[SK_MAX_NETS];
-       SK_ADDR_PORT    Port[SK_MAX_MACS];
-
-/* ----- Private part ----- */
-} SK_ADDR;
-
-/* function prototypes ********************************************************/
-
-#ifndef SK_KR_PROTO
-
-/* Functions provided by SkAddr */
-
-/* ANSI/C++ compliant function prototypes */
-
-extern int     SkAddrInit(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int     Level);
-
-extern int     SkAddrMcClear(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       SK_U32  PortNumber,
-       int     Flags);
-
-extern int     SkAddrMcAdd(
-       SK_AC           *pAC,
-       SK_IOC          IoC,
-       SK_U32          PortNumber,
-       SK_MAC_ADDR     *pMc,
-       int             Flags);
-
-extern int     SkAddrMcUpdate(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       SK_U32  PortNumber);
-
-extern int     SkAddrOverride(
-       SK_AC           *pAC,
-       SK_IOC          IoC,
-       SK_U32          PortNumber,
-       SK_MAC_ADDR     SK_FAR *pNewAddr,
-       int             Flags);
-
-extern int     SkAddrPromiscuousChange(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       SK_U32  PortNumber,
-       int     NewPromMode);
-
-#ifndef SK_SLIM
-extern int     SkAddrSwap(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       SK_U32  FromPortNumber,
-       SK_U32  ToPortNumber);
-#endif
-
-#else  /* defined(SK_KR_PROTO)) */
-
-/* Non-ANSI/C++ compliant function prototypes */
-
-#error KR-style prototypes are not yet provided.
-
-#endif /* defined(SK_KR_PROTO)) */
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __INC_SKADDR_H */
diff --git a/drivers/net/sk98lin/h/skcsum.h b/drivers/net/sk98lin/h/skcsum.h
deleted file mode 100644 (file)
index 6e256bd..0000000
+++ /dev/null
@@ -1,213 +0,0 @@
-/******************************************************************************
- *
- * Name:       skcsum.h
- * Project:    GEnesis - SysKonnect SK-NET Gigabit Ethernet (SK-98xx)
- * Version:    $Revision: 1.10 $
- * Date:       $Date: 2003/08/20 13:59:57 $
- * Purpose:    Store/verify Internet checksum in send/receive packets.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2001 SysKonnect GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * Description:
- *
- * Public header file for the "GEnesis" common module "CSUM".
- *
- * "GEnesis" is an abbreviation of "Gigabit Ethernet Network System in Silicon"
- * and is the code name of this SysKonnect project.
- *
- * Compilation Options:
- *
- *     SK_USE_CSUM - Define if CSUM is to be used. Otherwise, CSUM will be an
- *     empty module.
- *
- *     SKCS_OVERWRITE_PROTO - Define to overwrite the default protocol id
- *     definitions. In this case, all SKCS_PROTO_xxx definitions must be made
- *     external.
- *
- *     SKCS_OVERWRITE_STATUS - Define to overwrite the default return status
- *     definitions. In this case, all SKCS_STATUS_xxx definitions must be made
- *     external.
- *
- * Include File Hierarchy:
- *
- *     "h/skcsum.h"
- *      "h/sktypes.h"
- *      "h/skqueue.h"
- *
- ******************************************************************************/
-
-#ifndef __INC_SKCSUM_H
-#define __INC_SKCSUM_H
-
-#include "h/sktypes.h"
-#include "h/skqueue.h"
-
-/* defines ********************************************************************/
-
-/*
- * Define the default bit flags for 'SKCS_PACKET_INFO.ProtocolFlags'  if no user
- * overwrite.
- */
-#ifndef SKCS_OVERWRITE_PROTO   /* User overwrite? */
-#define SKCS_PROTO_IP  0x1     /* IP (Internet Protocol version 4) */
-#define SKCS_PROTO_TCP 0x2     /* TCP (Transmission Control Protocol) */
-#define SKCS_PROTO_UDP 0x4     /* UDP (User Datagram Protocol) */
-
-/* Indices for protocol statistics. */
-#define SKCS_PROTO_STATS_IP    0
-#define SKCS_PROTO_STATS_UDP   1
-#define SKCS_PROTO_STATS_TCP   2
-#define SKCS_NUM_PROTOCOLS     3       /* Number of supported protocols. */
-#endif /* !SKCS_OVERWRITE_PROTO */
-
-/*
- * Define the default SKCS_STATUS type and values if no user overwrite.
- *
- *     SKCS_STATUS_UNKNOWN_IP_VERSION - Not an IP v4 frame.
- *     SKCS_STATUS_IP_CSUM_ERROR - IP checksum error.
- *     SKCS_STATUS_IP_CSUM_ERROR_TCP - IP checksum error in TCP frame.
- *     SKCS_STATUS_IP_CSUM_ERROR_UDP - IP checksum error in UDP frame
- *     SKCS_STATUS_IP_FRAGMENT - IP fragment (IP checksum ok).
- *     SKCS_STATUS_IP_CSUM_OK - IP checksum ok (not a TCP or UDP frame).
- *     SKCS_STATUS_TCP_CSUM_ERROR - TCP checksum error (IP checksum ok).
- *     SKCS_STATUS_UDP_CSUM_ERROR - UDP checksum error (IP checksum ok).
- *     SKCS_STATUS_TCP_CSUM_OK - IP and TCP checksum ok.
- *     SKCS_STATUS_UDP_CSUM_OK - IP and UDP checksum ok.
- *     SKCS_STATUS_IP_CSUM_OK_NO_UDP - IP checksum OK and no UDP checksum. 
- */
-#ifndef SKCS_OVERWRITE_STATUS  /* User overwrite? */
-#define SKCS_STATUS    int     /* Define status type. */
-
-#define SKCS_STATUS_UNKNOWN_IP_VERSION 1
-#define SKCS_STATUS_IP_CSUM_ERROR              2
-#define SKCS_STATUS_IP_FRAGMENT                        3
-#define SKCS_STATUS_IP_CSUM_OK                 4
-#define SKCS_STATUS_TCP_CSUM_ERROR             5
-#define SKCS_STATUS_UDP_CSUM_ERROR             6
-#define SKCS_STATUS_TCP_CSUM_OK                        7
-#define SKCS_STATUS_UDP_CSUM_OK                        8
-/* needed for Microsoft */
-#define SKCS_STATUS_IP_CSUM_ERROR_UDP  9
-#define SKCS_STATUS_IP_CSUM_ERROR_TCP  10
-/* UDP checksum may be omitted */
-#define SKCS_STATUS_IP_CSUM_OK_NO_UDP  11
-#endif /* !SKCS_OVERWRITE_STATUS */
-
-/* Clear protocol statistics event. */
-#define SK_CSUM_EVENT_CLEAR_PROTO_STATS        1
-
-/*
- * Add two values in one's complement.
- *
- * Note: One of the two input values may be "longer" than 16-bit, but then the
- * resulting sum may be 17 bits long. In this case, add zero to the result using
- * SKCS_OC_ADD() again.
- *
- *     Result = Value1 + Value2
- */
-#define SKCS_OC_ADD(Result, Value1, Value2) {                          \
-       unsigned long Sum;                                              \
-                                                                       \
-       Sum = (unsigned long) (Value1) + (unsigned long) (Value2);      \
-       /* Add-in any carry. */                                         \
-       (Result) = (Sum & 0xffff) + (Sum >> 16);                        \
-}
-
-/*
- * Subtract two values in one's complement.
- *
- *     Result = Value1 - Value2
- */
-#define SKCS_OC_SUB(Result, Value1, Value2)    \
-       SKCS_OC_ADD((Result), (Value1), ~(Value2) & 0xffff)
-
-/* typedefs *******************************************************************/
-
-/*
- * SKCS_PROTO_STATS - The CSUM protocol statistics structure.
- *
- * There is one instance of this structure for each protocol supported.
- */
-typedef struct s_CsProtocolStatistics {
-       SK_U64 RxOkCts;         /* Receive checksum ok. */
-       SK_U64 RxUnableCts;     /* Unable to verify receive checksum. */
-       SK_U64 RxErrCts;        /* Receive checksum error. */
-       SK_U64 TxOkCts;         /* Transmit checksum ok. */
-       SK_U64 TxUnableCts;     /* Unable to calculate checksum in hw. */
-} SKCS_PROTO_STATS;
-
-/*
- * s_Csum - The CSUM module context structure.
- */
-typedef struct s_Csum {
-       /* Enabled receive SK_PROTO_XXX bit flags. */
-       unsigned ReceiveFlags[SK_MAX_NETS];
-#ifdef TX_CSUM
-       unsigned TransmitFlags[SK_MAX_NETS];
-#endif /* TX_CSUM */
-
-       /* The protocol statistics structure; one per supported protocol. */
-       SKCS_PROTO_STATS ProtoStats[SK_MAX_NETS][SKCS_NUM_PROTOCOLS];
-} SK_CSUM;
-
-/*
- * SKCS_PACKET_INFO - The packet information structure.
- */
-typedef struct s_CsPacketInfo {
-       /* Bit field specifiying the desired/found protocols. */
-       unsigned ProtocolFlags;
-
-       /* Length of complete IP header, including any option fields. */
-       unsigned IpHeaderLength;
-
-       /* IP header checksum. */
-       unsigned IpHeaderChecksum;
-
-       /* TCP/UDP pseudo header checksum. */
-       unsigned PseudoHeaderChecksum;
-} SKCS_PACKET_INFO;
-
-/* function prototypes ********************************************************/
-
-#ifndef SK_CS_CALCULATE_CHECKSUM
-extern unsigned SkCsCalculateChecksum(
-       void            *pData,
-       unsigned        Length);
-#endif /* SK_CS_CALCULATE_CHECKSUM */
-
-extern int SkCsEvent(
-       SK_AC           *pAc,
-       SK_IOC          Ioc,
-       SK_U32          Event,
-       SK_EVPARA       Param);
-
-extern SKCS_STATUS SkCsGetReceiveInfo(
-       SK_AC           *pAc,
-       void            *pIpHeader,
-       unsigned        Checksum1,
-       unsigned        Checksum2,
-       int                     NetNumber);
-
-extern void SkCsSetReceiveFlags(
-       SK_AC           *pAc,
-       unsigned        ReceiveFlags,
-       unsigned        *pChecksum1Offset,
-       unsigned        *pChecksum2Offset,
-       int                     NetNumber);
-
-#endif /* __INC_SKCSUM_H */
diff --git a/drivers/net/sk98lin/h/skdebug.h b/drivers/net/sk98lin/h/skdebug.h
deleted file mode 100644 (file)
index 3cba171..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/******************************************************************************
- *
- * Name:       skdebug.h
- * Project:    Gigabit Ethernet Adapters, Common Modules
- * Version:    $Revision: 1.14 $
- * Date:       $Date: 2003/05/13 17:26:00 $
- * Purpose:    SK specific DEBUG support
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect.
- *     (C)Copyright 2002-2003 Marvell.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-#ifndef __INC_SKDEBUG_H
-#define __INC_SKDEBUG_H
-
-#ifdef DEBUG
-#ifndef SK_DBG_MSG
-#define SK_DBG_MSG(pAC,comp,cat,arg) \
-               if ( ((comp) & SK_DBG_CHKMOD(pAC)) &&   \
-                     ((cat) & SK_DBG_CHKCAT(pAC)) ) {  \
-                       SK_DBG_PRINTF arg ;             \
-               }
-#endif
-#else
-#define SK_DBG_MSG(pAC,comp,lev,arg)
-#endif
-
-/* PLS NOTE:
- * =========
- * Due to any restrictions of kernel printf routines do not use other
- * format identifiers as: %x %d %c %s .
- * Never use any combined format identifiers such as: %lx %ld in your
- * printf - argument (arg) because some OS specific kernel printfs may
- * only support some basic identifiers.
- */
-
-/* Debug modules */
-
-#define SK_DBGMOD_MERR 0x00000001L     /* general module error indication */
-#define SK_DBGMOD_HWM  0x00000002L     /* Hardware init module */
-#define SK_DBGMOD_RLMT 0x00000004L     /* RLMT module */
-#define SK_DBGMOD_VPD  0x00000008L     /* VPD module */
-#define SK_DBGMOD_I2C  0x00000010L     /* I2C module */
-#define SK_DBGMOD_PNMI 0x00000020L     /* PNMI module */
-#define SK_DBGMOD_CSUM 0x00000040L     /* CSUM module */
-#define SK_DBGMOD_ADDR 0x00000080L     /* ADDR module */
-#define SK_DBGMOD_PECP 0x00000100L     /* PECP module */
-#define SK_DBGMOD_POWM 0x00000200L     /* Power Management module */
-
-/* Debug events */
-
-#define SK_DBGCAT_INIT 0x00000001L     /* module/driver initialization */
-#define SK_DBGCAT_CTRL 0x00000002L     /* controlling devices */
-#define SK_DBGCAT_ERR  0x00000004L     /* error handling paths */
-#define SK_DBGCAT_TX   0x00000008L     /* transmit path */
-#define SK_DBGCAT_RX   0x00000010L     /* receive path */
-#define SK_DBGCAT_IRQ  0x00000020L     /* general IRQ handling */
-#define SK_DBGCAT_QUEUE        0x00000040L     /* any queue management */
-#define SK_DBGCAT_DUMP 0x00000080L     /* large data output e.g. hex dump */
-#define SK_DBGCAT_FATAL        0x00000100L     /* fatal error */
-
-#endif /* __INC_SKDEBUG_H */
diff --git a/drivers/net/sk98lin/h/skdrv1st.h b/drivers/net/sk98lin/h/skdrv1st.h
deleted file mode 100644 (file)
index 91b8d4f..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-/******************************************************************************
- *
- * Name:       skdrv1st.h
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.4 $
- * Date:       $Date: 2003/11/12 14:28:14 $
- * Purpose:    First header file for driver and all other modules
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect GmbH.
- *     (C)Copyright 2002-2003 Marvell.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * Description:
- *
- * This is the first include file of the driver, which includes all
- * neccessary system header files and some of the GEnesis header files.
- * It also defines some basic items.
- *
- * Include File Hierarchy:
- *
- *     see skge.c
- *
- ******************************************************************************/
-
-#ifndef __INC_SKDRV1ST_H
-#define __INC_SKDRV1ST_H
-
-typedef struct s_AC    SK_AC;
-
-/* Set card versions */
-#define SK_FAR
-
-/* override some default functions with optimized linux functions */
-
-#define SK_PNMI_STORE_U16(p,v)         memcpy((char*)(p),(char*)&(v),2)
-#define SK_PNMI_STORE_U32(p,v)         memcpy((char*)(p),(char*)&(v),4)
-#define SK_PNMI_STORE_U64(p,v)         memcpy((char*)(p),(char*)&(v),8)
-#define SK_PNMI_READ_U16(p,v)          memcpy((char*)&(v),(char*)(p),2)
-#define SK_PNMI_READ_U32(p,v)          memcpy((char*)&(v),(char*)(p),4)
-#define SK_PNMI_READ_U64(p,v)          memcpy((char*)&(v),(char*)(p),8)
-
-#define SK_ADDR_EQUAL(a1,a2)           (!memcmp(a1,a2,6))
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/bitops.h>
-#include <asm/byteorder.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
-#include <linux/init.h>
-#include <asm/uaccess.h>
-#include <net/checksum.h>
-
-#define SK_CS_CALCULATE_CHECKSUM
-#ifndef CONFIG_X86_64
-#define SkCsCalculateChecksum(p,l)     ((~ip_compute_csum(p, l)) & 0xffff)
-#else
-#define SkCsCalculateChecksum(p,l)     ((~ip_fast_csum(p, l)) & 0xffff)
-#endif
-
-#include       "h/sktypes.h"
-#include       "h/skerror.h"
-#include       "h/skdebug.h"
-#include       "h/lm80.h"
-#include       "h/xmac_ii.h"
-
-#ifdef __LITTLE_ENDIAN
-#define SK_LITTLE_ENDIAN
-#else
-#define SK_BIG_ENDIAN
-#endif
-
-#define SK_NET_DEVICE  net_device
-
-
-/* we use gethrtime(), return unit: nanoseconds */
-#define SK_TICKS_PER_SEC       100
-
-#define        SK_MEM_MAPPED_IO
-
-// #define SK_RLMT_SLOW_LOOKAHEAD
-
-#define SK_MAX_MACS            2
-#define SK_MAX_NETS            2
-
-#define SK_IOC                 char __iomem *
-
-typedef struct s_DrvRlmtMbuf SK_MBUF;
-
-#define        SK_CONST64      INT64_C
-#define        SK_CONSTU64     UINT64_C
-
-#define SK_MEMCPY(dest,src,size)       memcpy(dest,src,size)
-#define SK_MEMCMP(s1,s2,size)          memcmp(s1,s2,size)
-#define SK_MEMSET(dest,val,size)       memset(dest,val,size)
-#define SK_STRLEN(pStr)                        strlen((char*)(pStr))
-#define SK_STRNCPY(pDest,pSrc,size)    strncpy((char*)(pDest),(char*)(pSrc),size)
-#define SK_STRCMP(pStr1,pStr2)         strcmp((char*)(pStr1),(char*)(pStr2))
-
-/* macros to access the adapter */
-#define SK_OUT8(b,a,v)         writeb((v), ((b)+(a)))  
-#define SK_OUT16(b,a,v)                writew((v), ((b)+(a)))  
-#define SK_OUT32(b,a,v)                writel((v), ((b)+(a)))  
-#define SK_IN8(b,a,pv)         (*(pv) = readb((b)+(a)))
-#define SK_IN16(b,a,pv)                (*(pv) = readw((b)+(a)))
-#define SK_IN32(b,a,pv)                (*(pv) = readl((b)+(a)))
-
-#define int8_t         char
-#define int16_t                short
-#define int32_t                long
-#define int64_t                long long
-#define uint8_t                u_char
-#define uint16_t       u_short
-#define uint32_t       u_long
-#define uint64_t       unsigned long long
-#define t_scalar_t     int
-#define t_uscalar_t    unsigned int
-#define uintptr_t      unsigned long
-
-#define __CONCAT__(A,B) A##B
-
-#define INT32_C(a)             __CONCAT__(a,L)
-#define INT64_C(a)             __CONCAT__(a,LL)
-#define UINT32_C(a)            __CONCAT__(a,UL)
-#define UINT64_C(a)            __CONCAT__(a,ULL)
-
-#ifdef DEBUG
-#define SK_DBG_PRINTF          printk
-#ifndef SK_DEBUG_CHKMOD
-#define SK_DEBUG_CHKMOD                0
-#endif
-#ifndef SK_DEBUG_CHKCAT
-#define SK_DEBUG_CHKCAT                0
-#endif
-/* those come from the makefile */
-#define SK_DBG_CHKMOD(pAC)     (SK_DEBUG_CHKMOD)
-#define SK_DBG_CHKCAT(pAC)     (SK_DEBUG_CHKCAT)
-
-extern void SkDbgPrintf(const char *format,...);
-
-#define SK_DBGMOD_DRV                  0x00010000
-
-/**** possible driver debug categories ********************************/
-#define SK_DBGCAT_DRV_ENTRY            0x00010000
-#define SK_DBGCAT_DRV_SAP              0x00020000
-#define SK_DBGCAT_DRV_MCA              0x00040000
-#define SK_DBGCAT_DRV_TX_PROGRESS      0x00080000
-#define SK_DBGCAT_DRV_RX_PROGRESS      0x00100000
-#define SK_DBGCAT_DRV_PROGRESS         0x00200000
-#define SK_DBGCAT_DRV_MSG              0x00400000
-#define SK_DBGCAT_DRV_PROM             0x00800000
-#define SK_DBGCAT_DRV_TX_FRAME         0x01000000
-#define SK_DBGCAT_DRV_ERROR            0x02000000
-#define SK_DBGCAT_DRV_INT_SRC          0x04000000
-#define SK_DBGCAT_DRV_EVENT            0x08000000
-
-#endif
-
-#define SK_ERR_LOG             SkErrorLog
-
-extern void SkErrorLog(SK_AC*, int, int, char*);
-
-#endif
-
diff --git a/drivers/net/sk98lin/h/skdrv2nd.h b/drivers/net/sk98lin/h/skdrv2nd.h
deleted file mode 100644 (file)
index 3fa6717..0000000
+++ /dev/null
@@ -1,447 +0,0 @@
-/******************************************************************************
- *
- * Name:       skdrv2nd.h
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.10 $
- * Date:       $Date: 2003/12/11 16:04:45 $
- * Purpose:    Second header file for driver and all other modules
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect GmbH.
- *     (C)Copyright 2002-2003 Marvell.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * Description:
- *
- * This is the second include file of the driver, which includes all other
- * neccessary files and defines all structures and constants used by the
- * driver and the common modules.
- *
- * Include File Hierarchy:
- *
- *     see skge.c
- *
- ******************************************************************************/
-
-#ifndef __INC_SKDRV2ND_H
-#define __INC_SKDRV2ND_H
-
-#include "h/skqueue.h"
-#include "h/skgehwt.h"
-#include "h/sktimer.h"
-#include "h/ski2c.h"
-#include "h/skgepnmi.h"
-#include "h/skvpd.h"
-#include "h/skgehw.h"
-#include "h/skgeinit.h"
-#include "h/skaddr.h"
-#include "h/skgesirq.h"
-#include "h/skcsum.h"
-#include "h/skrlmt.h"
-#include "h/skgedrv.h"
-
-
-extern SK_MBUF         *SkDrvAllocRlmtMbuf(SK_AC*, SK_IOC, unsigned);
-extern void            SkDrvFreeRlmtMbuf(SK_AC*, SK_IOC, SK_MBUF*);
-extern SK_U64          SkOsGetTime(SK_AC*);
-extern int             SkPciReadCfgDWord(SK_AC*, int, SK_U32*);
-extern int             SkPciReadCfgWord(SK_AC*, int, SK_U16*);
-extern int             SkPciReadCfgByte(SK_AC*, int, SK_U8*);
-extern int             SkPciWriteCfgWord(SK_AC*, int, SK_U16);
-extern int             SkPciWriteCfgByte(SK_AC*, int, SK_U8);
-extern int             SkDrvEvent(SK_AC*, SK_IOC IoC, SK_U32, SK_EVPARA);
-
-#ifdef SK_DIAG_SUPPORT
-extern int             SkDrvEnterDiagMode(SK_AC *pAc);
-extern int             SkDrvLeaveDiagMode(SK_AC *pAc);
-#endif
-
-struct s_DrvRlmtMbuf {
-       SK_MBUF         *pNext;         /* Pointer to next RLMT Mbuf. */
-       SK_U8           *pData;         /* Data buffer (virtually contig.). */
-       unsigned        Size;           /* Data buffer size. */
-       unsigned        Length;         /* Length of packet (<= Size). */
-       SK_U32          PortIdx;        /* Receiving/transmitting port. */
-#ifdef SK_RLMT_MBUF_PRIVATE
-       SK_RLMT_MBUF    Rlmt;           /* Private part for RLMT. */
-#endif  /* SK_RLMT_MBUF_PRIVATE */
-       struct sk_buff  *pOs;           /* Pointer to message block */
-};
-
-
-/*
- * Time macros
- */
-#if SK_TICKS_PER_SEC == 100
-#define SK_PNMI_HUNDREDS_SEC(t)        (t)
-#else
-#define SK_PNMI_HUNDREDS_SEC(t)        ((((unsigned long)t) * 100) / \
-                                                                               (SK_TICKS_PER_SEC))
-#endif
-
-/*
- * New SkOsGetTime
- */
-#define SkOsGetTimeCurrent(pAC, pUsec) {\
-       struct timeval t;\
-       do_gettimeofday(&t);\
-       *pUsec = ((((t.tv_sec) * 1000000L)+t.tv_usec)/10000);\
-}
-
-
-/*
- * ioctl definitions
- */
-#define                SK_IOCTL_BASE           (SIOCDEVPRIVATE)
-#define                SK_IOCTL_GETMIB         (SK_IOCTL_BASE + 0)
-#define                SK_IOCTL_SETMIB         (SK_IOCTL_BASE + 1)
-#define                SK_IOCTL_PRESETMIB      (SK_IOCTL_BASE + 2)
-#define                SK_IOCTL_GEN            (SK_IOCTL_BASE + 3)
-#define                SK_IOCTL_DIAG           (SK_IOCTL_BASE + 4)
-
-typedef struct s_IOCTL SK_GE_IOCTL;
-
-struct s_IOCTL {
-       char __user *   pData;
-       unsigned int    Len;
-};
-
-
-/*
- * define sizes of descriptor rings in bytes
- */
-
-#define                TX_RING_SIZE    (8*1024)
-#define                RX_RING_SIZE    (24*1024)
-
-/*
- * Buffer size for ethernet packets
- */
-#define        ETH_BUF_SIZE    1540
-#define        ETH_MAX_MTU     1514
-#define ETH_MIN_MTU    60
-#define ETH_MULTICAST_BIT      0x01
-#define SK_JUMBO_MTU   9000
-
-/*
- * transmit priority selects the queue: LOW=asynchron, HIGH=synchron
- */
-#define TX_PRIO_LOW    0
-#define TX_PRIO_HIGH   1
-
-/*
- * alignment of rx/tx descriptors
- */
-#define DESCR_ALIGN    64
-
-/*
- * definitions for pnmi. TODO
- */
-#define SK_DRIVER_RESET(pAC, IoC)      0
-#define SK_DRIVER_SENDEVENT(pAC, IoC)  0
-#define SK_DRIVER_SELFTEST(pAC, IoC)   0
-/* For get mtu you must add an own function */
-#define SK_DRIVER_GET_MTU(pAc,IoC,i)   0
-#define SK_DRIVER_SET_MTU(pAc,IoC,i,v) 0
-#define SK_DRIVER_PRESET_MTU(pAc,IoC,i,v)      0
-
-/*
-** Interim definition of SK_DRV_TIMER placed in this file until 
-** common modules have been finalized
-*/
-#define SK_DRV_TIMER                   11 
-#define        SK_DRV_MODERATION_TIMER         1
-#define SK_DRV_MODERATION_TIMER_LENGTH  1000000  /* 1 second */
-#define SK_DRV_RX_CLEANUP_TIMER                2
-#define SK_DRV_RX_CLEANUP_TIMER_LENGTH 1000000  /* 100 millisecs */
-
-/*
-** Definitions regarding transmitting frames 
-** any calculating any checksum.
-*/
-#define C_LEN_ETHERMAC_HEADER_DEST_ADDR 6
-#define C_LEN_ETHERMAC_HEADER_SRC_ADDR  6
-#define C_LEN_ETHERMAC_HEADER_LENTYPE   2
-#define C_LEN_ETHERMAC_HEADER           ( (C_LEN_ETHERMAC_HEADER_DEST_ADDR) + \
-                                          (C_LEN_ETHERMAC_HEADER_SRC_ADDR)  + \
-                                          (C_LEN_ETHERMAC_HEADER_LENTYPE) )
-
-#define C_LEN_ETHERMTU_MINSIZE          46
-#define C_LEN_ETHERMTU_MAXSIZE_STD      1500
-#define C_LEN_ETHERMTU_MAXSIZE_JUMBO    9000
-
-#define C_LEN_ETHERNET_MINSIZE          ( (C_LEN_ETHERMAC_HEADER) + \
-                                          (C_LEN_ETHERMTU_MINSIZE) )
-
-#define C_OFFSET_IPHEADER               C_LEN_ETHERMAC_HEADER
-#define C_OFFSET_IPHEADER_IPPROTO       9
-#define C_OFFSET_TCPHEADER_TCPCS        16
-#define C_OFFSET_UDPHEADER_UDPCS        6
-
-#define C_OFFSET_IPPROTO                ( (C_LEN_ETHERMAC_HEADER) + \
-                                          (C_OFFSET_IPHEADER_IPPROTO) )
-
-#define C_PROTO_ID_UDP                  17       /* refer to RFC 790 or Stevens'   */
-#define C_PROTO_ID_TCP                  6        /* TCP/IP illustrated for details */
-
-/* TX and RX descriptors *****************************************************/
-
-typedef struct s_RxD RXD; /* the receive descriptor */
-
-struct s_RxD {
-       volatile SK_U32 RBControl;      /* Receive Buffer Control */
-       SK_U32          VNextRxd;       /* Next receive descriptor,low dword */
-       SK_U32          VDataLow;       /* Receive buffer Addr, low dword */
-       SK_U32          VDataHigh;      /* Receive buffer Addr, high dword */
-       SK_U32          FrameStat;      /* Receive Frame Status word */
-       SK_U32          TimeStamp;      /* Time stamp from XMAC */
-       SK_U32          TcpSums;        /* TCP Sum 2 / TCP Sum 1 */
-       SK_U32          TcpSumStarts;   /* TCP Sum Start 2 / TCP Sum Start 1 */
-       RXD             *pNextRxd;      /* Pointer to next Rxd */
-       struct sk_buff  *pMBuf;         /* Pointer to Linux' socket buffer */
-};
-
-typedef struct s_TxD TXD; /* the transmit descriptor */
-
-struct s_TxD {
-       volatile SK_U32 TBControl;      /* Transmit Buffer Control */
-       SK_U32          VNextTxd;       /* Next transmit descriptor,low dword */
-       SK_U32          VDataLow;       /* Transmit Buffer Addr, low dword */
-       SK_U32          VDataHigh;      /* Transmit Buffer Addr, high dword */
-       SK_U32          FrameStat;      /* Transmit Frame Status Word */
-       SK_U32          TcpSumOfs;      /* Reserved / TCP Sum Offset */
-       SK_U16          TcpSumSt;       /* TCP Sum Start */
-       SK_U16          TcpSumWr;       /* TCP Sum Write */
-       SK_U32          TcpReserved;    /* not used */
-       TXD             *pNextTxd;      /* Pointer to next Txd */
-       struct sk_buff  *pMBuf;         /* Pointer to Linux' socket buffer */
-};
-
-/* Used interrupt bits in the interrupts source register *********************/
-
-#define DRIVER_IRQS    ((IS_IRQ_SW)   | \
-                       (IS_R1_F)      |(IS_R2_F)  | \
-                       (IS_XS1_F)     |(IS_XA1_F) | \
-                       (IS_XS2_F)     |(IS_XA2_F))
-
-#define SPECIAL_IRQS   ((IS_HW_ERR)   |(IS_I2C_READY)  | \
-                       (IS_EXT_REG)   |(IS_TIMINT)     | \
-                       (IS_PA_TO_RX1) |(IS_PA_TO_RX2)  | \
-                       (IS_PA_TO_TX1) |(IS_PA_TO_TX2)  | \
-                       (IS_MAC1)      |(IS_LNK_SYNC_M1)| \
-                       (IS_MAC2)      |(IS_LNK_SYNC_M2)| \
-                       (IS_R1_C)      |(IS_R2_C)       | \
-                       (IS_XS1_C)     |(IS_XA1_C)      | \
-                       (IS_XS2_C)     |(IS_XA2_C))
-
-#define IRQ_MASK       ((IS_IRQ_SW)   | \
-                       (IS_R1_B)      |(IS_R1_F)     |(IS_R2_B) |(IS_R2_F) | \
-                       (IS_XS1_B)     |(IS_XS1_F)    |(IS_XA1_B)|(IS_XA1_F)| \
-                       (IS_XS2_B)     |(IS_XS2_F)    |(IS_XA2_B)|(IS_XA2_F)| \
-                       (IS_HW_ERR)    |(IS_I2C_READY)| \
-                       (IS_EXT_REG)   |(IS_TIMINT)   | \
-                       (IS_PA_TO_RX1) |(IS_PA_TO_RX2)| \
-                       (IS_PA_TO_TX1) |(IS_PA_TO_TX2)| \
-                       (IS_MAC1)      |(IS_MAC2)     | \
-                       (IS_R1_C)      |(IS_R2_C)     | \
-                       (IS_XS1_C)     |(IS_XA1_C)    | \
-                       (IS_XS2_C)     |(IS_XA2_C))
-
-#define IRQ_HWE_MASK   (IS_ERR_MSK) /* enable all HW irqs */
-
-typedef struct s_DevNet DEV_NET;
-
-struct s_DevNet {
-       int             PortNr;
-       int             NetNr;
-       SK_AC   *pAC;
-};  
-
-typedef struct s_TxPort                TX_PORT;
-
-struct s_TxPort {
-       /* the transmit descriptor rings */
-       caddr_t         pTxDescrRing;   /* descriptor area memory */
-       SK_U64          VTxDescrRing;   /* descr. area bus virt. addr. */
-       TXD             *pTxdRingHead;  /* Head of Tx rings */
-       TXD             *pTxdRingTail;  /* Tail of Tx rings */
-       TXD             *pTxdRingPrev;  /* descriptor sent previously */
-       int             TxdRingFree;    /* # of free entrys */
-       spinlock_t      TxDesRingLock;  /* serialize descriptor accesses */
-       SK_IOC          HwAddr;         /* bmu registers address */
-       int             PortIndex;      /* index number of port (0 or 1) */
-};
-
-typedef struct s_RxPort                RX_PORT;
-
-struct s_RxPort {
-       /* the receive descriptor rings */
-       caddr_t         pRxDescrRing;   /* descriptor area memory */
-       SK_U64          VRxDescrRing;   /* descr. area bus virt. addr. */
-       RXD             *pRxdRingHead;  /* Head of Rx rings */
-       RXD             *pRxdRingTail;  /* Tail of Rx rings */
-       RXD             *pRxdRingPrev;  /* descriptor given to BMU previously */
-       int             RxdRingFree;    /* # of free entrys */
-       int             RxCsum;         /* use receive checksum hardware */
-       spinlock_t      RxDesRingLock;  /* serialize descriptor accesses */
-       int             RxFillLimit;    /* limit for buffers in ring */
-       SK_IOC          HwAddr;         /* bmu registers address */
-       int             PortIndex;      /* index number of port (0 or 1) */
-};
-
-/* Definitions needed for interrupt moderation *******************************/
-
-#define IRQ_EOF_AS_TX     ((IS_XA1_F)     | (IS_XA2_F))
-#define IRQ_EOF_SY_TX     ((IS_XS1_F)     | (IS_XS2_F))
-#define IRQ_MASK_TX_ONLY  ((IRQ_EOF_AS_TX)| (IRQ_EOF_SY_TX))
-#define IRQ_MASK_RX_ONLY  ((IS_R1_F)      | (IS_R2_F))
-#define IRQ_MASK_SP_ONLY  (SPECIAL_IRQS)
-#define IRQ_MASK_TX_RX    ((IRQ_MASK_TX_ONLY)| (IRQ_MASK_RX_ONLY))
-#define IRQ_MASK_SP_RX    ((SPECIAL_IRQS)    | (IRQ_MASK_RX_ONLY))
-#define IRQ_MASK_SP_TX    ((SPECIAL_IRQS)    | (IRQ_MASK_TX_ONLY))
-#define IRQ_MASK_RX_TX_SP ((SPECIAL_IRQS)    | (IRQ_MASK_TX_RX))
-
-#define C_INT_MOD_NONE                 1
-#define C_INT_MOD_STATIC               2
-#define C_INT_MOD_DYNAMIC              4
-
-#define C_CLK_FREQ_GENESIS      53215000 /* shorter: 53.125 MHz  */
-#define C_CLK_FREQ_YUKON        78215000 /* shorter: 78.125 MHz  */
-
-#define C_INTS_PER_SEC_DEFAULT      2000 
-#define C_INT_MOD_ENABLE_PERCENTAGE   50 /* if higher 50% enable */
-#define C_INT_MOD_DISABLE_PERCENTAGE  50 /* if lower 50% disable */
-#define C_INT_MOD_IPS_LOWER_RANGE     30
-#define C_INT_MOD_IPS_UPPER_RANGE     40000
-
-
-typedef struct s_DynIrqModInfo  DIM_INFO;
-struct s_DynIrqModInfo {
-       unsigned long   PrevTimeVal;
-       unsigned int    PrevSysLoad;
-       unsigned int    PrevUsedTime;
-       unsigned int    PrevTotalTime;
-       int             PrevUsedDescrRatio;
-       int             NbrProcessedDescr;
-        SK_U64          PrevPort0RxIntrCts;
-        SK_U64          PrevPort1RxIntrCts;
-        SK_U64          PrevPort0TxIntrCts;
-        SK_U64          PrevPort1TxIntrCts;
-       SK_BOOL         ModJustEnabled;     /* Moderation just enabled yes/no */
-
-       int             MaxModIntsPerSec;            /* Moderation Threshold */
-       int             MaxModIntsPerSecUpperLimit;  /* Upper limit for DIM  */
-       int             MaxModIntsPerSecLowerLimit;  /* Lower limit for DIM  */
-
-       long            MaskIrqModeration;   /* ModIrqType (eg. 'TxRx')      */
-       SK_BOOL         DisplayStats;        /* Stats yes/no                 */
-       SK_BOOL         AutoSizing;          /* Resize DIM-timer on/off      */
-       int             IntModTypeSelect;    /* EnableIntMod (eg. 'dynamic') */
-
-       SK_TIMER        ModTimer; /* just some timer */
-};
-
-typedef struct s_PerStrm       PER_STRM;
-
-#define SK_ALLOC_IRQ   0x00000001
-
-#ifdef SK_DIAG_SUPPORT
-#define        DIAG_ACTIVE             1
-#define        DIAG_NOTACTIVE          0
-#endif
-
-/****************************************************************************
- * Per board structure / Adapter Context structure:
- *     Allocated within attach(9e) and freed within detach(9e).
- *     Contains all 'per device' necessary handles, flags, locks etc.:
- */
-struct s_AC  {
-       SK_GEINIT       GIni;           /* GE init struct */
-       SK_PNMI         Pnmi;           /* PNMI data struct */
-       SK_VPD          vpd;            /* vpd data struct */
-       SK_QUEUE        Event;          /* Event queue */
-       SK_HWT          Hwt;            /* Hardware Timer control struct */
-       SK_TIMCTRL      Tim;            /* Software Timer control struct */
-       SK_I2C          I2c;            /* I2C relevant data structure */
-       SK_ADDR         Addr;           /* for Address module */
-       SK_CSUM         Csum;           /* for checksum module */
-       SK_RLMT         Rlmt;           /* for rlmt module */
-       spinlock_t      SlowPathLock;   /* Normal IRQ lock */
-       struct timer_list BlinkTimer;   /* for LED blinking */
-       int             LedsOn;
-       SK_PNMI_STRUCT_DATA PnmiStruct; /* structure to get all Pnmi-Data */
-       int                     RlmtMode;       /* link check mode to set */
-       int                     RlmtNets;       /* Number of nets */
-       
-       SK_IOC          IoBase;         /* register set of adapter */
-       int             BoardLevel;     /* level of active hw init (0-2) */
-
-       SK_U32          AllocFlag;      /* flag allocation of resources */
-       struct pci_dev  *PciDev;        /* for access to pci config space */
-       struct SK_NET_DEVICE    *dev[2];        /* pointer to device struct */
-
-       int             RxBufSize;      /* length of receive buffers */
-        struct net_device_stats stats; /* linux 'netstat -i' statistics */
-       int             Index;          /* internal board index number */
-
-       /* adapter RAM sizes for queues of active port */
-       int             RxQueueSize;    /* memory used for receive queue */
-       int             TxSQueueSize;   /* memory used for sync. tx queue */
-       int             TxAQueueSize;   /* memory used for async. tx queue */
-
-       int             PromiscCount;   /* promiscuous mode counter  */
-       int             AllMultiCount;  /* allmulticast mode counter */
-       int             MulticCount;    /* number of different MC    */
-                                       /*  addresses for this board */
-                                       /*  (may be more than HW can)*/
-
-       int             HWRevision;     /* Hardware revision */
-       int             ActivePort;     /* the active XMAC port */
-       int             MaxPorts;               /* number of activated ports */
-       int             TxDescrPerRing; /* # of descriptors per tx ring */
-       int             RxDescrPerRing; /* # of descriptors per rx ring */
-
-       caddr_t         pDescrMem;      /* Pointer to the descriptor area */
-       dma_addr_t      pDescrMemDMA;   /* PCI DMA address of area */
-
-       /* the port structures with descriptor rings */
-       TX_PORT         TxPort[SK_MAX_MACS][2];
-       RX_PORT         RxPort[SK_MAX_MACS];
-
-       SK_BOOL         CheckQueue;     /* check event queue soon */
-       SK_TIMER        DrvCleanupTimer;/* to check for pending descriptors */
-       DIM_INFO        DynIrqModInfo;  /* all data related to DIM */
-
-       /* Only for tests */
-       int             PortDown;
-       int             ChipsetType;    /*  Chipset family type 
-                                        *  0 == Genesis family support
-                                        *  1 == Yukon family support
-                                        */
-#ifdef SK_DIAG_SUPPORT
-       SK_U32          DiagModeActive;         /* is diag active?      */
-       SK_BOOL         DiagFlowCtrl;           /* for control purposes */
-       SK_PNMI_STRUCT_DATA PnmiBackup;         /* backup structure for all Pnmi-Data */
-       SK_BOOL         WasIfUp[SK_MAX_MACS];   /* for OpenClose while 
-                                                * DIAG is busy with NIC 
-                                                */
-#endif
-
-};
-
-
-#endif /* __INC_SKDRV2ND_H */
-
diff --git a/drivers/net/sk98lin/h/skerror.h b/drivers/net/sk98lin/h/skerror.h
deleted file mode 100644 (file)
index da062f7..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/******************************************************************************
- *
- * Name:       skerror.h
- * Project:    Gigabit Ethernet Adapters, Common Modules
- * Version:    $Revision: 1.7 $
- * Date:       $Date: 2003/05/13 17:25:13 $
- * Purpose:    SK specific Error log support
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect.
- *     (C)Copyright 2002-2003 Marvell.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-#ifndef _INC_SKERROR_H_
-#define _INC_SKERROR_H_
-
-/*
- * Define Error Classes
- */
-#define        SK_ERRCL_OTHER          (0)             /* Other error */
-#define        SK_ERRCL_CONFIG         (1L<<0) /* Configuration error */
-#define        SK_ERRCL_INIT           (1L<<1) /* Initialization error */
-#define        SK_ERRCL_NORES          (1L<<2) /* Out of Resources error */
-#define        SK_ERRCL_SW                     (1L<<3) /* Internal Software error */
-#define        SK_ERRCL_HW                     (1L<<4) /* Hardware Failure */
-#define        SK_ERRCL_COMM           (1L<<5) /* Communication error */
-
-
-/*
- * Define Error Code Bases
- */
-#define        SK_ERRBASE_RLMT          100    /* Base Error number for RLMT */
-#define        SK_ERRBASE_HWINIT        200    /* Base Error number for HWInit */
-#define        SK_ERRBASE_VPD           300    /* Base Error number for VPD */
-#define        SK_ERRBASE_PNMI          400    /* Base Error number for PNMI */
-#define        SK_ERRBASE_CSUM          500    /* Base Error number for Checksum */
-#define        SK_ERRBASE_SIRQ          600    /* Base Error number for Special IRQ */
-#define        SK_ERRBASE_I2C           700    /* Base Error number for I2C module */
-#define        SK_ERRBASE_QUEUE         800    /* Base Error number for Scheduler */
-#define        SK_ERRBASE_ADDR          900    /* Base Error number for Address module */
-#define SK_ERRBASE_PECP                1000    /* Base Error number for PECP */
-#define        SK_ERRBASE_DRV          1100    /* Base Error number for Driver */
-
-#endif /* _INC_SKERROR_H_ */
diff --git a/drivers/net/sk98lin/h/skgedrv.h b/drivers/net/sk98lin/h/skgedrv.h
deleted file mode 100644 (file)
index 44fd4c3..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/******************************************************************************
- *
- * Name:       skgedrv.h
- * Project:    Gigabit Ethernet Adapters, Common Modules
- * Version:    $Revision: 1.10 $
- * Date:       $Date: 2003/07/04 12:25:01 $
- * Purpose:    Interface with the driver
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect.
- *     (C)Copyright 2002-2003 Marvell.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-#ifndef __INC_SKGEDRV_H_
-#define __INC_SKGEDRV_H_
-
-/* defines ********************************************************************/
-
-/*
- * Define the driver events.
- * Usually the events are defined by the destination module.
- * In case of the driver we put the definition of the events here.
- */
-#define SK_DRV_PORT_RESET               1      /* The port needs to be reset */
-#define SK_DRV_NET_UP                   2      /* The net is operational */
-#define SK_DRV_NET_DOWN                         3      /* The net is down */
-#define SK_DRV_SWITCH_SOFT              4      /* Ports switch with both links connected */
-#define SK_DRV_SWITCH_HARD              5      /* Port switch due to link failure */
-#define SK_DRV_RLMT_SEND                6      /* Send a RLMT packet */
-#define SK_DRV_ADAP_FAIL                7      /* The whole adapter fails */
-#define SK_DRV_PORT_FAIL                8      /* One port fails */
-#define SK_DRV_SWITCH_INTERN    9      /* Port switch by the driver itself */
-#define SK_DRV_POWER_DOWN              10      /* Power down mode */
-#define SK_DRV_TIMER                   11      /* Timer for free use */
-#ifdef SK_NO_RLMT
-#define SK_DRV_LINK_UP                 12      /* Link Up event for driver */
-#define SK_DRV_LINK_DOWN               13      /* Link Down event for driver */
-#endif
-#define SK_DRV_DOWNSHIFT_DET   14      /* Downshift 4-Pair / 2-Pair (YUKON only) */
-#endif /* __INC_SKGEDRV_H_ */
diff --git a/drivers/net/sk98lin/h/skgehw.h b/drivers/net/sk98lin/h/skgehw.h
deleted file mode 100644 (file)
index f6282b7..0000000
+++ /dev/null
@@ -1,2126 +0,0 @@
-/******************************************************************************
- *
- * Name:       skgehw.h
- * Project:    Gigabit Ethernet Adapters, Common Modules
- * Version:    $Revision: 1.56 $
- * Date:       $Date: 2003/09/23 09:01:00 $
- * Purpose:    Defines and Macros for the Gigabit Ethernet Adapter Product Family
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect.
- *     (C)Copyright 2002-2003 Marvell.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-#ifndef __INC_SKGEHW_H
-#define __INC_SKGEHW_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/* defines ********************************************************************/
-
-#define BIT_31         (1UL << 31)
-#define BIT_30         (1L << 30)
-#define BIT_29         (1L << 29)
-#define BIT_28         (1L << 28)
-#define BIT_27         (1L << 27)
-#define BIT_26         (1L << 26)
-#define BIT_25         (1L << 25)
-#define BIT_24         (1L << 24)
-#define BIT_23         (1L << 23)
-#define BIT_22         (1L << 22)
-#define BIT_21         (1L << 21)
-#define BIT_20         (1L << 20)
-#define BIT_19         (1L << 19)
-#define BIT_18         (1L << 18)
-#define BIT_17         (1L << 17)
-#define BIT_16         (1L << 16)
-#define BIT_15         (1L << 15)
-#define BIT_14         (1L << 14)
-#define BIT_13         (1L << 13)
-#define BIT_12         (1L << 12)
-#define BIT_11         (1L << 11)
-#define BIT_10         (1L << 10)
-#define BIT_9          (1L << 9)
-#define BIT_8          (1L << 8)
-#define BIT_7          (1L << 7)
-#define BIT_6          (1L << 6)
-#define BIT_5          (1L << 5)
-#define BIT_4          (1L << 4)
-#define BIT_3          (1L << 3)
-#define BIT_2          (1L << 2)
-#define BIT_1          (1L << 1)
-#define BIT_0          1L
-
-#define BIT_15S                (1U << 15)
-#define BIT_14S                (1 << 14)
-#define BIT_13S                (1 << 13)
-#define BIT_12S                (1 << 12)
-#define BIT_11S                (1 << 11)
-#define BIT_10S                (1 << 10)
-#define BIT_9S         (1 << 9)
-#define BIT_8S         (1 << 8)
-#define BIT_7S                 (1 << 7)
-#define BIT_6S         (1 << 6)
-#define BIT_5S         (1 << 5)
-#define BIT_4S         (1 << 4)
-#define BIT_3S         (1 << 3)
-#define BIT_2S         (1 << 2)
-#define BIT_1S         (1 << 1)
-#define BIT_0S         1
-
-#define SHIFT31(x)     ((x) << 31)
-#define SHIFT30(x)     ((x) << 30)
-#define SHIFT29(x)     ((x) << 29)
-#define SHIFT28(x)     ((x) << 28)
-#define SHIFT27(x)     ((x) << 27)
-#define SHIFT26(x)     ((x) << 26)
-#define SHIFT25(x)     ((x) << 25)
-#define SHIFT24(x)     ((x) << 24)
-#define SHIFT23(x)     ((x) << 23)
-#define SHIFT22(x)     ((x) << 22)
-#define SHIFT21(x)     ((x) << 21)
-#define SHIFT20(x)     ((x) << 20)
-#define SHIFT19(x)     ((x) << 19)
-#define SHIFT18(x)     ((x) << 18)
-#define SHIFT17(x)     ((x) << 17)
-#define SHIFT16(x)     ((x) << 16)
-#define SHIFT15(x)     ((x) << 15)
-#define SHIFT14(x)     ((x) << 14)
-#define SHIFT13(x)     ((x) << 13)
-#define SHIFT12(x)     ((x) << 12)
-#define SHIFT11(x)     ((x) << 11)
-#define SHIFT10(x)     ((x) << 10)
-#define SHIFT9(x)      ((x) << 9)
-#define SHIFT8(x)      ((x) << 8)
-#define SHIFT7(x)      ((x) << 7)
-#define SHIFT6(x)      ((x) << 6)
-#define SHIFT5(x)      ((x) << 5)
-#define SHIFT4(x)      ((x) << 4)
-#define SHIFT3(x)      ((x) << 3)
-#define SHIFT2(x)      ((x) << 2)
-#define SHIFT1(x)      ((x) << 1)
-#define SHIFT0(x)      ((x) << 0)
-
-/*
- * Configuration Space header
- * Since this module is used for different OS', those may be
- * duplicate on some of them (e.g. Linux). But to keep the
- * common source, we have to live with this...
- */
-#define PCI_VENDOR_ID  0x00    /* 16 bit       Vendor ID */
-#define PCI_DEVICE_ID  0x02    /* 16 bit       Device ID */
-#define PCI_COMMAND            0x04    /* 16 bit       Command */
-#define PCI_STATUS             0x06    /* 16 bit       Status */
-#define PCI_REV_ID             0x08    /*  8 bit       Revision ID */
-#define PCI_CLASS_CODE 0x09    /* 24 bit       Class Code */
-#define PCI_CACHE_LSZ  0x0c    /*  8 bit       Cache Line Size */
-#define PCI_LAT_TIM            0x0d    /*  8 bit       Latency Timer */
-#define PCI_HEADER_T   0x0e    /*  8 bit       Header Type */
-#define PCI_BIST               0x0f    /*  8 bit       Built-in selftest */
-#define PCI_BASE_1ST   0x10    /* 32 bit       1st Base address */
-#define PCI_BASE_2ND   0x14    /* 32 bit       2nd Base address */
-       /* Byte 0x18..0x2b:     reserved */
-#define PCI_SUB_VID            0x2c    /* 16 bit       Subsystem Vendor ID */
-#define PCI_SUB_ID             0x2e    /* 16 bit       Subsystem ID */
-#define PCI_BASE_ROM   0x30    /* 32 bit       Expansion ROM Base Address */
-#define PCI_CAP_PTR            0x34    /*  8 bit       Capabilities Ptr */
-       /* Byte 0x35..0x3b:     reserved */
-#define PCI_IRQ_LINE   0x3c    /*  8 bit       Interrupt Line */
-#define PCI_IRQ_PIN            0x3d    /*  8 bit       Interrupt Pin */
-#define PCI_MIN_GNT            0x3e    /*  8 bit       Min_Gnt */
-#define PCI_MAX_LAT            0x3f    /*  8 bit       Max_Lat */
-       /* Device Dependent Region */
-#define PCI_OUR_REG_1  0x40    /* 32 bit       Our Register 1 */
-#define PCI_OUR_REG_2  0x44    /* 32 bit       Our Register 2 */
-       /* Power Management Region */
-#define PCI_PM_CAP_ID  0x48    /*  8 bit       Power Management Cap. ID */
-#define PCI_PM_NITEM   0x49    /*  8 bit       Next Item Ptr */
-#define PCI_PM_CAP_REG 0x4a    /* 16 bit       Power Management Capabilities */
-#define PCI_PM_CTL_STS 0x4c    /* 16 bit       Power Manag. Control/Status */
-       /* Byte 0x4e:   reserved */
-#define PCI_PM_DAT_REG 0x4f    /*  8 bit       Power Manag. Data Register */
-       /* VPD Region */
-#define PCI_VPD_CAP_ID 0x50    /*  8 bit       VPD Cap. ID */
-#define PCI_VPD_NITEM  0x51    /*  8 bit       Next Item Ptr */
-#define PCI_VPD_ADR_REG        0x52    /* 16 bit       VPD Address Register */
-#define PCI_VPD_DAT_REG        0x54    /* 32 bit       VPD Data Register */
-       /* Byte 0x58..0x59:     reserved */
-#define PCI_SER_LD_CTRL        0x5a    /* 16 bit       SEEPROM Loader Ctrl (YUKON only) */
-       /* Byte 0x5c..0xff:     reserved */
-
-/*
- * I2C Address (PCI Config)
- *
- * Note: The temperature and voltage sensors are relocated on a different
- *      I2C bus.
- */
-#define I2C_ADDR_VPD   0xa0    /* I2C address for the VPD EEPROM */
-
-/*
- * Define Bits and Values of the registers
- */
-/*     PCI_COMMAND     16 bit  Command */
-                                                               /* Bit 15..11:  reserved */
-#define PCI_INT_DIS            BIT_10S         /* Interrupt INTx# disable (PCI 2.3) */
-#define PCI_FBTEN              BIT_9S          /* Fast Back-To-Back enable */
-#define PCI_SERREN             BIT_8S          /* SERR enable */
-#define PCI_ADSTEP             BIT_7S          /* Address Stepping */
-#define PCI_PERREN             BIT_6S          /* Parity Report Response enable */
-#define PCI_VGA_SNOOP  BIT_5S          /* VGA palette snoop */
-#define PCI_MWIEN              BIT_4S          /* Memory write an inv cycl ena */
-#define PCI_SCYCEN             BIT_3S          /* Special Cycle enable */
-#define PCI_BMEN               BIT_2S          /* Bus Master enable */
-#define PCI_MEMEN              BIT_1S          /* Memory Space Access enable */
-#define PCI_IOEN               BIT_0S          /* I/O Space Access enable */
-
-#define PCI_COMMAND_VAL        (PCI_FBTEN | PCI_SERREN | PCI_PERREN | PCI_MWIEN |\
-                                                PCI_BMEN | PCI_MEMEN | PCI_IOEN)
-
-/*     PCI_STATUS      16 bit  Status */
-#define PCI_PERR               BIT_15S         /* Parity Error */
-#define PCI_SERR               BIT_14S         /* Signaled SERR */
-#define PCI_RMABORT            BIT_13S         /* Received Master Abort */
-#define PCI_RTABORT            BIT_12S         /* Received Target Abort */
-                                                               /* Bit 11:      reserved */
-#define PCI_DEVSEL             (3<<9)          /* Bit 10.. 9:  DEVSEL Timing */
-#define PCI_DEV_FAST   (0<<9)          /*              fast */
-#define PCI_DEV_MEDIUM (1<<9)          /*              medium */
-#define PCI_DEV_SLOW   (2<<9)          /*              slow */
-#define PCI_DATAPERR   BIT_8S          /* DATA Parity error detected */
-#define PCI_FB2BCAP            BIT_7S          /* Fast Back-to-Back Capability */
-#define PCI_UDF                        BIT_6S          /* User Defined Features */
-#define PCI_66MHZCAP   BIT_5S          /* 66 MHz PCI bus clock capable */
-#define PCI_NEWCAP             BIT_4S          /* New cap. list implemented */
-#define PCI_INT_STAT   BIT_3S          /* Interrupt INTx# Status (PCI 2.3) */
-                                                               /* Bit  2.. 0:  reserved */
-
-#define PCI_ERRBITS    (PCI_PERR | PCI_SERR | PCI_RMABORT | PCI_RTABORT |\
-                       PCI_DATAPERR)
-
-/*     PCI_CLASS_CODE  24 bit  Class Code */
-/*     Byte 2:         Base Class              (02) */
-/*     Byte 1:         SubClass                (00) */
-/*     Byte 0:         Programming Interface   (00) */
-
-/*     PCI_CACHE_LSZ   8 bit   Cache Line Size */
-/*     Possible values: 0,2,4,8,16,32,64,128   */
-
-/*     PCI_HEADER_T    8 bit   Header Type */
-#define PCI_HD_MF_DEV  BIT_7S  /* 0= single, 1= multi-func dev */
-#define PCI_HD_TYPE            0x7f    /* Bit 6..0:    Header Layout 0= normal */
-
-/*     PCI_BIST        8 bit   Built-in selftest */
-/*     Built-in Self test not supported (optional) */
-
-/*     PCI_BASE_1ST    32 bit  1st Base address */
-#define PCI_MEMSIZE            0x4000L         /* use 16 kB Memory Base */
-#define PCI_MEMBASE_MSK 0xffffc000L    /* Bit 31..14:  Memory Base Address */
-#define PCI_MEMSIZE_MSK 0x00003ff0L    /* Bit 13.. 4:  Memory Size Req. */
-#define PCI_PREFEN             BIT_3           /* Prefetchable */
-#define PCI_MEM_TYP            (3L<<2)         /* Bit  2.. 1:  Memory Type */
-#define PCI_MEM32BIT   (0L<<1)         /* Base addr anywhere in 32 Bit range */
-#define PCI_MEM1M              (1L<<1)         /* Base addr below 1 MegaByte */
-#define PCI_MEM64BIT   (2L<<1)         /* Base addr anywhere in 64 Bit range */
-#define PCI_MEMSPACE   BIT_0           /* Memory Space Indicator */
-
-/*     PCI_BASE_2ND    32 bit  2nd Base address */
-#define PCI_IOBASE             0xffffff00L     /* Bit 31.. 8:  I/O Base address */
-#define PCI_IOSIZE             0x000000fcL     /* Bit  7.. 2:  I/O Size Requirements */
-                                                                       /* Bit  1:      reserved */
-#define PCI_IOSPACE            BIT_0           /* I/O Space Indicator */
-
-/*     PCI_BASE_ROM    32 bit  Expansion ROM Base Address */
-#define PCI_ROMBASE_MSK        0xfffe0000L     /* Bit 31..17:  ROM Base address */
-#define PCI_ROMBASE_SIZ        (0x1cL<<14)     /* Bit 16..14:  Treat as Base or Size */
-#define PCI_ROMSIZE            (0x38L<<11)     /* Bit 13..11:  ROM Size Requirements */
-                                                                       /* Bit 10.. 1:  reserved */
-#define PCI_ROMEN              BIT_0           /* Address Decode enable */
-
-/* Device Dependent Region */
-/*     PCI_OUR_REG_1           32 bit  Our Register 1 */
-                                                                       /* Bit 31..29:  reserved */
-#define PCI_PHY_COMA   BIT_28          /* Set PHY to Coma Mode (YUKON only) */
-#define PCI_TEST_CAL   BIT_27          /* Test PCI buffer calib. (YUKON only) */
-#define PCI_EN_CAL             BIT_26          /* Enable PCI buffer calib. (YUKON only) */
-#define PCI_VIO                        BIT_25          /* PCI I/O Voltage, 0 = 3.3V, 1 = 5V */
-#define PCI_DIS_BOOT   BIT_24          /* Disable BOOT via ROM */
-#define PCI_EN_IO              BIT_23          /* Mapping to I/O space */
-#define PCI_EN_FPROM   BIT_22          /* Enable FLASH mapping to memory */
-                                                                       /*              1 = Map Flash to memory */
-                                                                       /*              0 = Disable addr. dec */
-#define PCI_PAGESIZE   (3L<<20)        /* Bit 21..20:  FLASH Page Size */
-#define PCI_PAGE_16            (0L<<20)        /*              16 k pages      */
-#define PCI_PAGE_32K   (1L<<20)        /*              32 k pages      */
-#define PCI_PAGE_64K   (2L<<20)        /*              64 k pages      */
-#define PCI_PAGE_128K  (3L<<20)        /*              128 k pages     */
-                                                                       /* Bit 19:      reserved        */
-#define PCI_PAGEREG            (7L<<16)        /* Bit 18..16:  Page Register   */
-#define PCI_NOTAR              BIT_15          /* No turnaround cycle */
-#define PCI_FORCE_BE   BIT_14          /* Assert all BEs on MR */
-#define PCI_DIS_MRL            BIT_13          /* Disable Mem Read Line */
-#define PCI_DIS_MRM            BIT_12          /* Disable Mem Read Multiple */
-#define PCI_DIS_MWI            BIT_11          /* Disable Mem Write & Invalidate */
-#define PCI_DISC_CLS   BIT_10          /* Disc: cacheLsz bound */
-#define PCI_BURST_DIS  BIT_9           /* Burst Disable */
-#define PCI_DIS_PCI_CLK        BIT_8           /* Disable PCI clock driving */
-#define PCI_SKEW_DAS   (0xfL<<4)       /* Bit  7.. 4:  Skew Ctrl, DAS Ext */
-#define PCI_SKEW_BASE  0xfL            /* Bit  3.. 0:  Skew Ctrl, Base */
-
-
-/*     PCI_OUR_REG_2           32 bit  Our Register 2 */
-#define PCI_VPD_WR_THR (0xffL<<24)     /* Bit 31..24:  VPD Write Threshold */
-#define PCI_DEV_SEL            (0x7fL<<17)     /* Bit 23..17:  EEPROM Device Select */
-#define PCI_VPD_ROM_SZ (7L<<14)        /* Bit 16..14:  VPD ROM Size    */
-                                                                       /* Bit 13..12:  reserved        */
-#define PCI_PATCH_DIR  (0xfL<<8)       /* Bit 11.. 8:  Ext Patches dir 3..0 */
-#define PCI_PATCH_DIR_3        BIT_11
-#define PCI_PATCH_DIR_2        BIT_10
-#define PCI_PATCH_DIR_1        BIT_9
-#define PCI_PATCH_DIR_0        BIT_8
-#define PCI_EXT_PATCHS (0xfL<<4)       /* Bit  7.. 4:  Extended Patches 3..0 */
-#define PCI_EXT_PATCH_3        BIT_7
-#define PCI_EXT_PATCH_2        BIT_6
-#define PCI_EXT_PATCH_1        BIT_5
-#define PCI_EXT_PATCH_0        BIT_4
-#define PCI_EN_DUMMY_RD        BIT_3           /* Enable Dummy Read */
-#define PCI_REV_DESC   BIT_2           /* Reverse Desc. Bytes */
-                                                                       /* Bit  1:      reserved */
-#define PCI_USEDATA64  BIT_0           /* Use 64Bit Data bus ext */
-
-
-/* Power Management Region */
-/*     PCI_PM_CAP_REG          16 bit  Power Management Capabilities */
-#define PCI_PME_SUP_MSK        (0x1f<<11)      /* Bit 15..11:  PM Event Support Mask */
-#define PCI_PME_D3C_SUP        BIT_15S         /* PME from D3cold Support (if Vaux) */
-#define PCI_PME_D3H_SUP        BIT_14S         /* PME from D3hot Support */
-#define PCI_PME_D2_SUP BIT_13S         /* PME from D2 Support */
-#define PCI_PME_D1_SUP BIT_12S         /* PME from D1 Support */
-#define PCI_PME_D0_SUP BIT_11S         /* PME from D0 Support */
-#define PCI_PM_D2_SUP  BIT_10S         /* D2 Support in 33 MHz mode */
-#define PCI_PM_D1_SUP  BIT_9S          /* D1 Support */
-                                                                       /* Bit  8.. 6:  reserved */
-#define PCI_PM_DSI             BIT_5S          /* Device Specific Initialization */
-#define PCI_PM_APS             BIT_4S          /* Auxialiary Power Source */
-#define PCI_PME_CLOCK  BIT_3S          /* PM Event Clock */
-#define PCI_PM_VER_MSK         7               /* Bit  2.. 0:  PM PCI Spec. version */
-
-/*     PCI_PM_CTL_STS          16 bit  Power Management Control/Status */
-#define PCI_PME_STATUS BIT_15S         /* PME Status (YUKON only) */
-#define PCI_PM_DAT_SCL (3<<13)         /* Bit 14..13:  Data Reg. scaling factor */
-#define PCI_PM_DAT_SEL (0xf<<9)        /* Bit 12.. 9:  PM data selector field */
-#define PCI_PME_EN             BIT_8S          /* Enable PME# generation (YUKON only) */
-                                                                       /* Bit  7.. 2:  reserved */
-#define PCI_PM_STATE_MSK       3               /* Bit  1.. 0:  Power Management State */
-
-#define PCI_PM_STATE_D0                0               /* D0:  Operational (default) */
-#define PCI_PM_STATE_D1                1               /* D1:  (YUKON only) */
-#define PCI_PM_STATE_D2                2               /* D2:  (YUKON only) */
-#define PCI_PM_STATE_D3        3               /* D3:  HOT, Power Down and Reset */
-
-/* VPD Region */
-/*     PCI_VPD_ADR_REG         16 bit  VPD Address Register */
-#define PCI_VPD_FLAG   BIT_15S         /* starts VPD rd/wr cycle */
-#define PCI_VPD_ADR_MSK        0x7fffL         /* Bit 14.. 0:  VPD address mask */
-
-/*     Control Register File (Address Map) */
-
-/*
- *     Bank 0
- */
-#define B0_RAP                 0x0000  /*  8 bit       Register Address Port */
-       /* 0x0001 - 0x0003:     reserved */
-#define B0_CTST                        0x0004  /* 16 bit       Control/Status register */
-#define B0_LED                 0x0006  /*  8 Bit       LED register */
-#define B0_POWER_CTRL  0x0007  /*  8 Bit       Power Control reg (YUKON only) */
-#define B0_ISRC                        0x0008  /* 32 bit       Interrupt Source Register */
-#define B0_IMSK                        0x000c  /* 32 bit       Interrupt Mask Register */
-#define B0_HWE_ISRC            0x0010  /* 32 bit       HW Error Interrupt Src Reg */
-#define B0_HWE_IMSK            0x0014  /* 32 bit       HW Error Interrupt Mask Reg */
-#define B0_SP_ISRC             0x0018  /* 32 bit       Special Interrupt Source Reg */
-       /* 0x001c:              reserved */
-
-/* B0 XMAC 1 registers (GENESIS only) */
-#define B0_XM1_IMSK            0x0020  /* 16 bit r/w   XMAC 1 Interrupt Mask Register*/
-       /* 0x0022 - 0x0027:     reserved */
-#define B0_XM1_ISRC            0x0028  /* 16 bit ro    XMAC 1 Interrupt Status Reg */
-       /* 0x002a - 0x002f:     reserved */
-#define B0_XM1_PHY_ADDR 0x0030 /* 16 bit r/w   XMAC 1 PHY Address Register */
-       /* 0x0032 - 0x0033:     reserved */
-#define B0_XM1_PHY_DATA 0x0034 /* 16 bit r/w   XMAC 1 PHY Data Register */
-       /* 0x0036 - 0x003f:     reserved */
-
-/* B0 XMAC 2 registers (GENESIS only) */
-#define B0_XM2_IMSK            0x0040  /* 16 bit r/w   XMAC 2 Interrupt Mask Register*/
-       /* 0x0042 - 0x0047:     reserved */
-#define B0_XM2_ISRC            0x0048  /* 16 bit ro    XMAC 2 Interrupt Status Reg */
-       /* 0x004a - 0x004f:     reserved */
-#define B0_XM2_PHY_ADDR 0x0050 /* 16 bit r/w   XMAC 2 PHY Address Register */
-       /* 0x0052 - 0x0053:     reserved */
-#define B0_XM2_PHY_DATA 0x0054 /* 16 bit r/w   XMAC 2 PHY Data Register */
-       /* 0x0056 - 0x005f:     reserved */
-
-/* BMU Control Status Registers */
-#define B0_R1_CSR              0x0060  /* 32 bit       BMU Ctrl/Stat Rx Queue 1 */
-#define B0_R2_CSR              0x0064  /* 32 bit       BMU Ctrl/Stat Rx Queue 2 */
-#define B0_XS1_CSR             0x0068  /* 32 bit       BMU Ctrl/Stat Sync Tx Queue 1 */
-#define B0_XA1_CSR             0x006c  /* 32 bit       BMU Ctrl/Stat Async Tx Queue 1*/
-#define B0_XS2_CSR             0x0070  /* 32 bit       BMU Ctrl/Stat Sync Tx Queue 2 */
-#define B0_XA2_CSR             0x0074  /* 32 bit       BMU Ctrl/Stat Async Tx Queue 2*/
-       /* 0x0078 - 0x007f:     reserved */
-
-/*
- *     Bank 1
- *     - completely empty (this is the RAP Block window)
- *     Note: if RAP = 1 this page is reserved
- */
-
-/*
- *     Bank 2
- */
-/* NA reg = 48 bit Network Address Register, 3x16 or 8x8 bit readable */
-#define B2_MAC_1               0x0100  /* NA reg        MAC Address 1 */
-       /* 0x0106 - 0x0107:     reserved */
-#define B2_MAC_2               0x0108  /* NA reg        MAC Address 2 */
-       /* 0x010e - 0x010f:     reserved */
-#define B2_MAC_3               0x0110  /* NA reg        MAC Address 3 */
-       /* 0x0116 - 0x0117:     reserved */
-#define B2_CONN_TYP            0x0118  /*  8 bit       Connector type */
-#define B2_PMD_TYP             0x0119  /*  8 bit       PMD type */
-#define B2_MAC_CFG             0x011a  /*  8 bit       MAC Configuration / Chip Revision */
-#define B2_CHIP_ID             0x011b  /*  8 bit       Chip Identification Number */
-       /* Eprom registers are currently of no use */
-#define B2_E_0                 0x011c  /*  8 bit       EPROM Byte 0 (ext. SRAM size */
-#define B2_E_1                 0x011d  /*  8 bit       EPROM Byte 1 (PHY type) */
-#define B2_E_2                 0x011e  /*  8 bit       EPROM Byte 2 */
-#define B2_E_3                 0x011f  /*  8 bit       EPROM Byte 3 */
-#define B2_FAR                 0x0120  /* 32 bit       Flash-Prom Addr Reg/Cnt */
-#define B2_FDP                 0x0124  /*  8 bit       Flash-Prom Data Port */
-       /* 0x0125 - 0x0127:     reserved */
-#define B2_LD_CTRL             0x0128  /*  8 bit       EPROM loader control register */
-#define B2_LD_TEST             0x0129  /*  8 bit       EPROM loader test register */
-       /* 0x012a - 0x012f:     reserved */
-#define B2_TI_INI              0x0130  /* 32 bit       Timer Init Value */
-#define B2_TI_VAL              0x0134  /* 32 bit       Timer Value */
-#define B2_TI_CTRL             0x0138  /*  8 bit       Timer Control */
-#define B2_TI_TEST             0x0139  /*  8 Bit       Timer Test */
-       /* 0x013a - 0x013f:     reserved */
-#define B2_IRQM_INI            0x0140  /* 32 bit       IRQ Moderation Timer Init Reg.*/
-#define B2_IRQM_VAL            0x0144  /* 32 bit       IRQ Moderation Timer Value */
-#define B2_IRQM_CTRL   0x0148  /*  8 bit       IRQ Moderation Timer Control */
-#define B2_IRQM_TEST   0x0149  /*  8 bit       IRQ Moderation Timer Test */
-#define B2_IRQM_MSK    0x014c  /* 32 bit       IRQ Moderation Mask */
-#define B2_IRQM_HWE_MSK 0x0150 /* 32 bit       IRQ Moderation HW Error Mask */
-       /* 0x0154 - 0x0157:     reserved */
-#define B2_TST_CTRL1   0x0158  /*  8 bit       Test Control Register 1 */
-#define B2_TST_CTRL2   0x0159  /*  8 bit       Test Control Register 2 */
-       /* 0x015a - 0x015b:     reserved */
-#define B2_GP_IO               0x015c  /* 32 bit       General Purpose I/O Register */
-#define B2_I2C_CTRL            0x0160  /* 32 bit       I2C HW Control Register */
-#define B2_I2C_DATA            0x0164  /* 32 bit       I2C HW Data Register */
-#define B2_I2C_IRQ             0x0168  /* 32 bit       I2C HW IRQ Register */
-#define B2_I2C_SW              0x016c  /* 32 bit       I2C SW Port Register */
-
-/* Blink Source Counter (GENESIS only) */
-#define B2_BSC_INI             0x0170  /* 32 bit       Blink Source Counter Init Val */
-#define B2_BSC_VAL             0x0174  /* 32 bit       Blink Source Counter Value */
-#define B2_BSC_CTRL            0x0178  /*  8 bit       Blink Source Counter Control */
-#define B2_BSC_STAT            0x0179  /*  8 bit       Blink Source Counter Status */
-#define B2_BSC_TST             0x017a  /* 16 bit       Blink Source Counter Test Reg */
-       /* 0x017c - 0x017f:     reserved */
-
-/*
- *     Bank 3
- */
-/* RAM Random Registers */
-#define B3_RAM_ADDR            0x0180  /* 32 bit       RAM Address, to read or write */
-#define B3_RAM_DATA_LO 0x0184  /* 32 bit       RAM Data Word (low dWord) */
-#define B3_RAM_DATA_HI 0x0188  /* 32 bit       RAM Data Word (high dWord) */
-       /* 0x018c - 0x018f:     reserved */
-
-/* RAM Interface Registers */
-/*
- * The HW-Spec. calls this registers Timeout Value 0..11. But this names are
- * not usable in SW. Please notice these are NOT real timeouts, these are
- * the number of qWords transferred continuously.
- */
-#define B3_RI_WTO_R1   0x0190  /*  8 bit       WR Timeout Queue R1             (TO0) */
-#define B3_RI_WTO_XA1  0x0191  /*  8 bit       WR Timeout Queue XA1    (TO1) */
-#define B3_RI_WTO_XS1  0x0192  /*  8 bit       WR Timeout Queue XS1    (TO2) */
-#define B3_RI_RTO_R1   0x0193  /*  8 bit       RD Timeout Queue R1             (TO3) */
-#define B3_RI_RTO_XA1  0x0194  /*  8 bit       RD Timeout Queue XA1    (TO4) */
-#define B3_RI_RTO_XS1  0x0195  /*  8 bit       RD Timeout Queue XS1    (TO5) */
-#define B3_RI_WTO_R2   0x0196  /*  8 bit       WR Timeout Queue R2             (TO6) */
-#define B3_RI_WTO_XA2  0x0197  /*  8 bit       WR Timeout Queue XA2    (TO7) */
-#define B3_RI_WTO_XS2  0x0198  /*  8 bit       WR Timeout Queue XS2    (TO8) */
-#define B3_RI_RTO_R2   0x0199  /*  8 bit       RD Timeout Queue R2             (TO9) */
-#define B3_RI_RTO_XA2  0x019a  /*  8 bit       RD Timeout Queue XA2    (TO10)*/
-#define B3_RI_RTO_XS2  0x019b  /*  8 bit       RD Timeout Queue XS2    (TO11)*/
-#define B3_RI_TO_VAL   0x019c  /*  8 bit       Current Timeout Count Val */
-       /* 0x019d - 0x019f:     reserved */
-#define B3_RI_CTRL             0x01a0  /* 16 bit       RAM Interface Control Register */
-#define B3_RI_TEST             0x01a2  /*  8 bit       RAM Interface Test Register */
-       /* 0x01a3 - 0x01af:     reserved */
-
-/* MAC Arbiter Registers (GENESIS only) */
-/* these are the no. of qWord transferred continuously and NOT real timeouts */
-#define B3_MA_TOINI_RX1        0x01b0  /*  8 bit       Timeout Init Val Rx Path MAC 1 */
-#define B3_MA_TOINI_RX2        0x01b1  /*  8 bit       Timeout Init Val Rx Path MAC 2 */
-#define B3_MA_TOINI_TX1        0x01b2  /*  8 bit       Timeout Init Val Tx Path MAC 1 */
-#define B3_MA_TOINI_TX2        0x01b3  /*  8 bit       Timeout Init Val Tx Path MAC 2 */
-#define B3_MA_TOVAL_RX1        0x01b4  /*  8 bit       Timeout Value Rx Path MAC 1 */
-#define B3_MA_TOVAL_RX2        0x01b5  /*  8 bit       Timeout Value Rx Path MAC 1 */
-#define B3_MA_TOVAL_TX1        0x01b6  /*  8 bit       Timeout Value Tx Path MAC 2 */
-#define B3_MA_TOVAL_TX2        0x01b7  /*  8 bit       Timeout Value Tx Path MAC 2 */
-#define B3_MA_TO_CTRL  0x01b8  /* 16 bit       MAC Arbiter Timeout Ctrl Reg */
-#define B3_MA_TO_TEST  0x01ba  /* 16 bit       MAC Arbiter Timeout Test Reg */
-       /* 0x01bc - 0x01bf:     reserved */
-#define B3_MA_RCINI_RX1        0x01c0  /*  8 bit       Recovery Init Val Rx Path MAC 1 */
-#define B3_MA_RCINI_RX2        0x01c1  /*  8 bit       Recovery Init Val Rx Path MAC 2 */
-#define B3_MA_RCINI_TX1        0x01c2  /*  8 bit       Recovery Init Val Tx Path MAC 1 */
-#define B3_MA_RCINI_TX2        0x01c3  /*  8 bit       Recovery Init Val Tx Path MAC 2 */
-#define B3_MA_RCVAL_RX1        0x01c4  /*  8 bit       Recovery Value Rx Path MAC 1 */
-#define B3_MA_RCVAL_RX2        0x01c5  /*  8 bit       Recovery Value Rx Path MAC 1 */
-#define B3_MA_RCVAL_TX1        0x01c6  /*  8 bit       Recovery Value Tx Path MAC 2 */
-#define B3_MA_RCVAL_TX2        0x01c7  /*  8 bit       Recovery Value Tx Path MAC 2 */
-#define B3_MA_RC_CTRL  0x01c8  /* 16 bit       MAC Arbiter Recovery Ctrl Reg */
-#define B3_MA_RC_TEST  0x01ca  /* 16 bit       MAC Arbiter Recovery Test Reg */
-       /* 0x01cc - 0x01cf:     reserved */
-
-/* Packet Arbiter Registers (GENESIS only) */
-/* these are real timeouts */
-#define B3_PA_TOINI_RX1        0x01d0  /* 16 bit       Timeout Init Val Rx Path MAC 1 */
-       /* 0x01d2 - 0x01d3:     reserved */
-#define B3_PA_TOINI_RX2        0x01d4  /* 16 bit       Timeout Init Val Rx Path MAC 2 */
-       /* 0x01d6 - 0x01d7:     reserved */
-#define B3_PA_TOINI_TX1        0x01d8  /* 16 bit       Timeout Init Val Tx Path MAC 1 */
-       /* 0x01da - 0x01db:     reserved */
-#define B3_PA_TOINI_TX2        0x01dc  /* 16 bit       Timeout Init Val Tx Path MAC 2 */
-       /* 0x01de - 0x01df:     reserved */
-#define B3_PA_TOVAL_RX1        0x01e0  /* 16 bit       Timeout Val Rx Path MAC 1 */
-       /* 0x01e2 - 0x01e3:     reserved */
-#define B3_PA_TOVAL_RX2        0x01e4  /* 16 bit       Timeout Val Rx Path MAC 2 */
-       /* 0x01e6 - 0x01e7:     reserved */
-#define B3_PA_TOVAL_TX1        0x01e8  /* 16 bit       Timeout Val Tx Path MAC 1 */
-       /* 0x01ea - 0x01eb:     reserved */
-#define B3_PA_TOVAL_TX2        0x01ec  /* 16 bit       Timeout Val Tx Path MAC 2 */
-       /* 0x01ee - 0x01ef:     reserved */
-#define B3_PA_CTRL     0x01f0  /* 16 bit       Packet Arbiter Ctrl Register */
-#define B3_PA_TEST     0x01f2  /* 16 bit       Packet Arbiter Test Register */
-       /* 0x01f4 - 0x01ff:     reserved */
-
-/*
- *     Bank 4 - 5
- */
-/* Transmit Arbiter Registers MAC 1 and 2, use MR_ADDR() to access */
-#define TXA_ITI_INI            0x0200  /* 32 bit       Tx Arb Interval Timer Init Val*/
-#define TXA_ITI_VAL            0x0204  /* 32 bit       Tx Arb Interval Timer Value */
-#define TXA_LIM_INI            0x0208  /* 32 bit       Tx Arb Limit Counter Init Val */
-#define TXA_LIM_VAL            0x020c  /* 32 bit       Tx Arb Limit Counter Value */
-#define TXA_CTRL               0x0210  /*  8 bit       Tx Arbiter Control Register */
-#define TXA_TEST               0x0211  /*  8 bit       Tx Arbiter Test Register */
-#define TXA_STAT               0x0212  /*  8 bit       Tx Arbiter Status Register */
-       /* 0x0213 - 0x027f:     reserved */
-       /* 0x0280 - 0x0292:     MAC 2 */
-       /* 0x0213 - 0x027f:     reserved */
-
-/*
- *     Bank 6
- */
-/* External registers (GENESIS only) */
-#define B6_EXT_REG             0x0300
-
-/*
- *     Bank 7
- */
-/* This is a copy of the Configuration register file (lower half) */
-#define B7_CFG_SPC             0x0380
-
-/*
- *     Bank 8 - 15
- */
-/* Receive and Transmit Queue Registers, use Q_ADDR() to access */
-#define B8_Q_REGS              0x0400
-
-/* Queue Register Offsets, use Q_ADDR() to access */
-#define Q_D            0x00    /* 8*32 bit     Current Descriptor */
-#define Q_DA_L 0x20    /* 32 bit       Current Descriptor Address Low dWord */
-#define Q_DA_H 0x24    /* 32 bit       Current Descriptor Address High dWord */
-#define Q_AC_L 0x28    /* 32 bit       Current Address Counter Low dWord */
-#define Q_AC_H 0x2c    /* 32 bit       Current Address Counter High dWord */
-#define Q_BC   0x30    /* 32 bit       Current Byte Counter */
-#define Q_CSR  0x34    /* 32 bit       BMU Control/Status Register */
-#define Q_F            0x38    /* 32 bit       Flag Register */
-#define Q_T1   0x3c    /* 32 bit       Test Register 1 */
-#define Q_T1_TR        0x3c    /*  8 bit       Test Register 1 Transfer SM */
-#define Q_T1_WR        0x3d    /*  8 bit       Test Register 1 Write Descriptor SM */
-#define Q_T1_RD        0x3e    /*  8 bit       Test Register 1 Read Descriptor SM */
-#define Q_T1_SV        0x3f    /*  8 bit       Test Register 1 Supervisor SM */
-#define Q_T2   0x40    /* 32 bit       Test Register 2 */
-#define Q_T3   0x44    /* 32 bit       Test Register 3 */
-       /* 0x48 - 0x7f: reserved */
-
-/*
- *     Bank 16 - 23
- */
-/* RAM Buffer Registers */
-#define B16_RAM_REGS   0x0800
-
-/* RAM Buffer Register Offsets, use RB_ADDR() to access */
-#define RB_START               0x00    /* 32 bit       RAM Buffer Start Address */
-#define RB_END                 0x04    /* 32 bit       RAM Buffer End Address */
-#define RB_WP                  0x08    /* 32 bit       RAM Buffer Write Pointer */
-#define RB_RP                  0x0c    /* 32 bit       RAM Buffer Read Pointer */
-#define RB_RX_UTPP             0x10    /* 32 bit       Rx Upper Threshold, Pause Pack */
-#define RB_RX_LTPP             0x14    /* 32 bit       Rx Lower Threshold, Pause Pack */
-#define RB_RX_UTHP             0x18    /* 32 bit       Rx Upper Threshold, High Prio */
-#define RB_RX_LTHP             0x1c    /* 32 bit       Rx Lower Threshold, High Prio */
-       /* 0x10 - 0x1f: reserved at Tx RAM Buffer Registers */
-#define RB_PC                  0x20    /* 32 bit       RAM Buffer Packet Counter */
-#define RB_LEV                 0x24    /* 32 bit       RAM Buffer Level Register */
-#define RB_CTRL                        0x28    /*  8 bit       RAM Buffer Control Register */
-#define RB_TST1                        0x29    /*  8 bit       RAM Buffer Test Register 1 */
-#define RB_TST2                        0x2A    /*  8 bit       RAM Buffer Test Register 2 */
-       /* 0x2c - 0x7f: reserved */
-
-/*
- *     Bank 24
- */
-/*
- * Receive MAC FIFO, Receive LED, and Link_Sync regs (GENESIS only)
- * use MR_ADDR() to access
- */
-#define RX_MFF_EA              0x0c00  /* 32 bit       Receive MAC FIFO End Address */
-#define RX_MFF_WP              0x0c04  /* 32 bit       Receive MAC FIFO Write Pointer */
-       /* 0x0c08 - 0x0c0b:     reserved */
-#define RX_MFF_RP              0x0c0c  /* 32 bit       Receive MAC FIFO Read Pointer */
-#define RX_MFF_PC              0x0c10  /* 32 bit       Receive MAC FIFO Packet Cnt */
-#define RX_MFF_LEV             0x0c14  /* 32 bit       Receive MAC FIFO Level */
-#define RX_MFF_CTRL1   0x0c18  /* 16 bit       Receive MAC FIFO Control Reg 1*/
-#define RX_MFF_STAT_TO 0x0c1a  /*  8 bit       Receive MAC Status Timeout */
-#define RX_MFF_TIST_TO 0x0c1b  /*  8 bit       Receive MAC Time Stamp Timeout */
-#define RX_MFF_CTRL2   0x0c1c  /*  8 bit       Receive MAC FIFO Control Reg 2*/
-#define RX_MFF_TST1            0x0c1d  /*  8 bit       Receive MAC FIFO Test Reg 1 */
-#define RX_MFF_TST2            0x0c1e  /*  8 bit       Receive MAC FIFO Test Reg 2 */
-       /* 0x0c1f:      reserved */
-#define RX_LED_INI             0x0c20  /* 32 bit       Receive LED Cnt Init Value */
-#define RX_LED_VAL             0x0c24  /* 32 bit       Receive LED Cnt Current Value */
-#define RX_LED_CTRL            0x0c28  /*  8 bit       Receive LED Cnt Control Reg */
-#define RX_LED_TST             0x0c29  /*  8 bit       Receive LED Cnt Test Register */
-       /* 0x0c2a - 0x0c2f:     reserved */
-#define LNK_SYNC_INI   0x0c30  /* 32 bit       Link Sync Cnt Init Value */
-#define LNK_SYNC_VAL   0x0c34  /* 32 bit       Link Sync Cnt Current Value */
-#define LNK_SYNC_CTRL  0x0c38  /*  8 bit       Link Sync Cnt Control Register */
-#define LNK_SYNC_TST   0x0c39  /*  8 bit       Link Sync Cnt Test Register */
-       /* 0x0c3a - 0x0c3b:     reserved */
-#define LNK_LED_REG            0x0c3c  /*  8 bit       Link LED Register */
-       /* 0x0c3d - 0x0c3f:     reserved */
-
-/* Receive GMAC FIFO (YUKON only), use MR_ADDR() to access */
-#define RX_GMF_EA              0x0c40  /* 32 bit       Rx GMAC FIFO End Address */
-#define RX_GMF_AF_THR  0x0c44  /* 32 bit       Rx GMAC FIFO Almost Full Thresh. */
-#define RX_GMF_CTRL_T  0x0c48  /* 32 bit       Rx GMAC FIFO Control/Test */
-#define RX_GMF_FL_MSK  0x0c4c  /* 32 bit       Rx GMAC FIFO Flush Mask */
-#define RX_GMF_FL_THR  0x0c50  /* 32 bit       Rx GMAC FIFO Flush Threshold */
-       /* 0x0c54 - 0x0c5f:     reserved */
-#define RX_GMF_WP              0x0c60  /* 32 bit       Rx GMAC FIFO Write Pointer */
-       /* 0x0c64 - 0x0c67:     reserved */
-#define RX_GMF_WLEV            0x0c68  /* 32 bit       Rx GMAC FIFO Write Level */
-       /* 0x0c6c - 0x0c6f:     reserved */
-#define RX_GMF_RP              0x0c70  /* 32 bit       Rx GMAC FIFO Read Pointer */
-       /* 0x0c74 - 0x0c77:     reserved */
-#define RX_GMF_RLEV            0x0c78  /* 32 bit       Rx GMAC FIFO Read Level */
-       /* 0x0c7c - 0x0c7f:     reserved */
-
-/*
- *     Bank 25
- */
-       /* 0x0c80 - 0x0cbf:     MAC 2 */
-       /* 0x0cc0 - 0x0cff:     reserved */
-
-/*
- *     Bank 26
- */
-/*
- * Transmit MAC FIFO and Transmit LED Registers (GENESIS only),
- * use MR_ADDR() to access
- */
-#define TX_MFF_EA              0x0d00  /* 32 bit       Transmit MAC FIFO End Address */
-#define TX_MFF_WP              0x0d04  /* 32 bit       Transmit MAC FIFO WR Pointer */
-#define TX_MFF_WSP             0x0d08  /* 32 bit       Transmit MAC FIFO WR Shadow Ptr */
-#define TX_MFF_RP              0x0d0c  /* 32 bit       Transmit MAC FIFO RD Pointer */
-#define TX_MFF_PC              0x0d10  /* 32 bit       Transmit MAC FIFO Packet Cnt */
-#define TX_MFF_LEV             0x0d14  /* 32 bit       Transmit MAC FIFO Level */
-#define TX_MFF_CTRL1   0x0d18  /* 16 bit       Transmit MAC FIFO Ctrl Reg 1 */
-#define TX_MFF_WAF             0x0d1a  /*  8 bit       Transmit MAC Wait after flush */
-       /* 0x0c1b:      reserved */
-#define TX_MFF_CTRL2   0x0d1c  /*  8 bit       Transmit MAC FIFO Ctrl Reg 2 */
-#define TX_MFF_TST1            0x0d1d  /*  8 bit       Transmit MAC FIFO Test Reg 1 */
-#define TX_MFF_TST2            0x0d1e  /*  8 bit       Transmit MAC FIFO Test Reg 2 */
-       /* 0x0d1f:      reserved */
-#define TX_LED_INI             0x0d20  /* 32 bit       Transmit LED Cnt Init Value */
-#define TX_LED_VAL             0x0d24  /* 32 bit       Transmit LED Cnt Current Val */
-#define TX_LED_CTRL            0x0d28  /*  8 bit       Transmit LED Cnt Control Reg */
-#define TX_LED_TST             0x0d29  /*  8 bit       Transmit LED Cnt Test Reg */
-       /* 0x0d2a - 0x0d3f:     reserved */
-
-/* Transmit GMAC FIFO (YUKON only), use MR_ADDR() to access */
-#define TX_GMF_EA              0x0d40  /* 32 bit       Tx GMAC FIFO End Address */
-#define TX_GMF_AE_THR  0x0d44  /* 32 bit       Tx GMAC FIFO Almost Empty Thresh.*/
-#define TX_GMF_CTRL_T  0x0d48  /* 32 bit       Tx GMAC FIFO Control/Test */
-       /* 0x0d4c - 0x0d5f:     reserved */
-#define TX_GMF_WP              0x0d60  /* 32 bit       Tx GMAC FIFO Write Pointer */
-#define TX_GMF_WSP             0x0d64  /* 32 bit       Tx GMAC FIFO Write Shadow Ptr. */
-#define TX_GMF_WLEV            0x0d68  /* 32 bit       Tx GMAC FIFO Write Level */
-       /* 0x0d6c - 0x0d6f:     reserved */
-#define TX_GMF_RP              0x0d70  /* 32 bit       Tx GMAC FIFO Read Pointer */
-#define TX_GMF_RSTP            0x0d74  /* 32 bit       Tx GMAC FIFO Restart Pointer */
-#define TX_GMF_RLEV            0x0d78  /* 32 bit       Tx GMAC FIFO Read Level */
-       /* 0x0d7c - 0x0d7f:     reserved */
-
-/*
- *     Bank 27
- */
-       /* 0x0d80 - 0x0dbf:     MAC 2 */
-       /* 0x0daa - 0x0dff:     reserved */
-
-/*
- *     Bank 28
- */
-/* Descriptor Poll Timer Registers */
-#define B28_DPT_INI            0x0e00  /* 24 bit       Descriptor Poll Timer Init Val */
-#define B28_DPT_VAL            0x0e04  /* 24 bit       Descriptor Poll Timer Curr Val */
-#define B28_DPT_CTRL   0x0e08  /*  8 bit       Descriptor Poll Timer Ctrl Reg */
-       /* 0x0e09:      reserved */
-#define B28_DPT_TST            0x0e0a  /*  8 bit       Descriptor Poll Timer Test Reg */
-       /* 0x0e0b:      reserved */
-
-/* Time Stamp Timer Registers (YUKON only) */
-       /* 0x0e10:      reserved */
-#define GMAC_TI_ST_VAL 0x0e14  /* 32 bit       Time Stamp Timer Curr Val */
-#define GMAC_TI_ST_CTRL        0x0e18  /*  8 bit       Time Stamp Timer Ctrl Reg */
-       /* 0x0e19:      reserved */
-#define GMAC_TI_ST_TST 0x0e1a  /*  8 bit       Time Stamp Timer Test Reg */
-       /* 0x0e1b - 0x0e7f:     reserved */
-
-/*
- *     Bank 29
- */
-       /* 0x0e80 - 0x0efc:     reserved */
-
-/*
- *     Bank 30
- */
-/* GMAC and GPHY Control Registers (YUKON only) */
-#define GMAC_CTRL              0x0f00  /* 32 bit       GMAC Control Reg */
-#define GPHY_CTRL              0x0f04  /* 32 bit       GPHY Control Reg */
-#define GMAC_IRQ_SRC   0x0f08  /*  8 bit       GMAC Interrupt Source Reg */
-       /* 0x0f09 - 0x0f0b:     reserved */
-#define GMAC_IRQ_MSK   0x0f0c  /*  8 bit       GMAC Interrupt Mask Reg */
-       /* 0x0f0d - 0x0f0f:     reserved */
-#define GMAC_LINK_CTRL 0x0f10  /* 16 bit       Link Control Reg */
-       /* 0x0f14 - 0x0f1f:     reserved */
-
-/* Wake-up Frame Pattern Match Control Registers (YUKON only) */
-
-#define WOL_REG_OFFS   0x20    /* HW-Bug: Address is + 0x20 against spec. */
-
-#define WOL_CTRL_STAT  0x0f20  /* 16 bit       WOL Control/Status Reg */
-#define WOL_MATCH_CTL  0x0f22  /*  8 bit       WOL Match Control Reg */
-#define WOL_MATCH_RES  0x0f23  /*  8 bit       WOL Match Result Reg */
-#define WOL_MAC_ADDR_LO        0x0f24  /* 32 bit       WOL MAC Address Low */
-#define WOL_MAC_ADDR_HI        0x0f28  /* 16 bit       WOL MAC Address High */
-#define WOL_PATT_RPTR  0x0f2c  /*  8 bit       WOL Pattern Read Ptr */
-
-/* use this macro to access above registers */
-#define WOL_REG(Reg)   ((Reg) + (pAC->GIni.GIWolOffs))
-
-
-/* WOL Pattern Length Registers (YUKON only) */
-
-#define WOL_PATT_LEN_LO        0x0f30          /* 32 bit       WOL Pattern Length 3..0 */
-#define WOL_PATT_LEN_HI        0x0f34          /* 24 bit       WOL Pattern Length 6..4 */
-
-/* WOL Pattern Counter Registers (YUKON only) */
-
-#define WOL_PATT_CNT_0 0x0f38          /* 32 bit       WOL Pattern Counter 3..0 */
-#define WOL_PATT_CNT_4 0x0f3c          /* 24 bit       WOL Pattern Counter 6..4 */
-       /* 0x0f40 - 0x0f7f:     reserved */
-
-/*
- *     Bank 31
- */
-/* 0x0f80 - 0x0fff:    reserved */
-
-/*
- *     Bank 32 - 33
- */
-#define WOL_PATT_RAM_1 0x1000  /*  WOL Pattern RAM Link 1 */
-
-/*
- *     Bank 0x22 - 0x3f
- */
-/* 0x1100 - 0x1fff:    reserved */
-
-/*
- *     Bank 0x40 - 0x4f
- */
-#define BASE_XMAC_1            0x2000  /* XMAC 1 registers */
-
-/*
- *     Bank 0x50 - 0x5f
- */
-
-#define BASE_GMAC_1            0x2800  /* GMAC 1 registers */
-
-/*
- *     Bank 0x60 - 0x6f
- */
-#define BASE_XMAC_2            0x3000  /* XMAC 2 registers */
-
-/*
- *     Bank 0x70 - 0x7f
- */
-#define BASE_GMAC_2            0x3800  /* GMAC 2 registers */
-
-/*
- *     Control Register Bit Definitions:
- */
-/*     B0_RAP          8 bit   Register Address Port */
-                                                               /* Bit 7:       reserved */
-#define RAP_RAP                        0x3f    /* Bit 6..0:    0 = block 0,..,6f = block 6f */
-
-/*     B0_CTST                 16 bit  Control/Status register */
-                                                               /* Bit 15..14:  reserved */
-#define CS_CLK_RUN_HOT BIT_13S         /* CLK_RUN hot m. (YUKON-Lite only) */
-#define CS_CLK_RUN_RST BIT_12S         /* CLK_RUN reset  (YUKON-Lite only) */
-#define CS_CLK_RUN_ENA BIT_11S         /* CLK_RUN enable (YUKON-Lite only) */
-#define CS_VAUX_AVAIL  BIT_10S         /* VAUX available (YUKON only) */
-#define CS_BUS_CLOCK   BIT_9S          /* Bus Clock 0/1 = 33/66 MHz */
-#define CS_BUS_SLOT_SZ BIT_8S          /* Slot Size 0/1 = 32/64 bit slot */
-#define CS_ST_SW_IRQ   BIT_7S          /* Set IRQ SW Request */
-#define CS_CL_SW_IRQ   BIT_6S          /* Clear IRQ SW Request */
-#define CS_STOP_DONE   BIT_5S          /* Stop Master is finished */
-#define CS_STOP_MAST   BIT_4S          /* Command Bit to stop the master */
-#define CS_MRST_CLR            BIT_3S          /* Clear Master reset   */
-#define CS_MRST_SET            BIT_2S          /* Set Master reset     */
-#define CS_RST_CLR             BIT_1S          /* Clear Software reset */
-#define CS_RST_SET             BIT_0S          /* Set   Software reset */
-
-/*     B0_LED                   8 Bit  LED register */
-                                                               /* Bit  7.. 2:  reserved */
-#define LED_STAT_ON            BIT_1S          /* Status LED on        */
-#define LED_STAT_OFF   BIT_0S          /* Status LED off       */
-
-/*     B0_POWER_CTRL    8 Bit  Power Control reg (YUKON only) */
-#define PC_VAUX_ENA            BIT_7           /* Switch VAUX Enable  */
-#define PC_VAUX_DIS            BIT_6       /* Switch VAUX Disable */
-#define PC_VCC_ENA             BIT_5       /* Switch VCC Enable  */
-#define PC_VCC_DIS             BIT_4       /* Switch VCC Disable */
-#define PC_VAUX_ON             BIT_3       /* Switch VAUX On  */
-#define PC_VAUX_OFF            BIT_2       /* Switch VAUX Off */
-#define PC_VCC_ON              BIT_1       /* Switch VCC On  */
-#define PC_VCC_OFF             BIT_0       /* Switch VCC Off */
-
-/*     B0_ISRC                 32 bit  Interrupt Source Register */
-/*     B0_IMSK                 32 bit  Interrupt Mask Register */
-/*     B0_SP_ISRC              32 bit  Special Interrupt Source Reg */
-/*     B2_IRQM_MSK     32 bit  IRQ Moderation Mask */
-#define IS_ALL_MSK             0xbfffffffUL    /* All Interrupt bits */
-#define IS_HW_ERR              BIT_31          /* Interrupt HW Error */
-                                                               /* Bit 30:      reserved */
-#define IS_PA_TO_RX1   BIT_29          /* Packet Arb Timeout Rx1 */
-#define IS_PA_TO_RX2   BIT_28          /* Packet Arb Timeout Rx2 */
-#define IS_PA_TO_TX1   BIT_27          /* Packet Arb Timeout Tx1 */
-#define IS_PA_TO_TX2   BIT_26          /* Packet Arb Timeout Tx2 */
-#define IS_I2C_READY   BIT_25          /* IRQ on end of I2C Tx */
-#define IS_IRQ_SW              BIT_24          /* SW forced IRQ        */
-#define IS_EXT_REG             BIT_23          /* IRQ from LM80 or PHY (GENESIS only) */
-                                                                       /* IRQ from PHY (YUKON only) */
-#define IS_TIMINT              BIT_22          /* IRQ from Timer       */
-#define IS_MAC1                        BIT_21          /* IRQ from MAC 1       */
-#define IS_LNK_SYNC_M1 BIT_20          /* Link Sync Cnt wrap MAC 1 */
-#define IS_MAC2                        BIT_19          /* IRQ from MAC 2       */
-#define IS_LNK_SYNC_M2 BIT_18          /* Link Sync Cnt wrap MAC 2 */
-/* Receive Queue 1 */
-#define IS_R1_B                        BIT_17          /* Q_R1 End of Buffer */
-#define IS_R1_F                        BIT_16          /* Q_R1 End of Frame */
-#define IS_R1_C                        BIT_15          /* Q_R1 Encoding Error */
-/* Receive Queue 2 */
-#define IS_R2_B                        BIT_14          /* Q_R2 End of Buffer */
-#define IS_R2_F                        BIT_13          /* Q_R2 End of Frame */
-#define IS_R2_C                        BIT_12          /* Q_R2 Encoding Error */
-/* Synchronous Transmit Queue 1 */
-#define IS_XS1_B               BIT_11          /* Q_XS1 End of Buffer */
-#define IS_XS1_F               BIT_10          /* Q_XS1 End of Frame */
-#define IS_XS1_C               BIT_9           /* Q_XS1 Encoding Error */
-/* Asynchronous Transmit Queue 1 */
-#define IS_XA1_B               BIT_8           /* Q_XA1 End of Buffer */
-#define IS_XA1_F               BIT_7           /* Q_XA1 End of Frame */
-#define IS_XA1_C               BIT_6           /* Q_XA1 Encoding Error */
-/* Synchronous Transmit Queue 2 */
-#define IS_XS2_B               BIT_5           /* Q_XS2 End of Buffer */
-#define IS_XS2_F               BIT_4           /* Q_XS2 End of Frame */
-#define IS_XS2_C               BIT_3           /* Q_XS2 Encoding Error */
-/* Asynchronous Transmit Queue 2 */
-#define IS_XA2_B               BIT_2           /* Q_XA2 End of Buffer */
-#define IS_XA2_F               BIT_1           /* Q_XA2 End of Frame */
-#define IS_XA2_C               BIT_0           /* Q_XA2 Encoding Error */
-
-
-/*     B0_HWE_ISRC             32 bit  HW Error Interrupt Src Reg */
-/*     B0_HWE_IMSK             32 bit  HW Error Interrupt Mask Reg */
-/*     B2_IRQM_HWE_MSK 32 bit  IRQ Moderation HW Error Mask */
-#define IS_ERR_MSK             0x00000fffL     /*              All Error bits */
-                                                               /* Bit 31..14:  reserved */
-#define IS_IRQ_TIST_OV BIT_13  /* Time Stamp Timer Overflow (YUKON only) */
-#define IS_IRQ_SENSOR  BIT_12  /* IRQ from Sensor (YUKON only) */
-#define IS_IRQ_MST_ERR BIT_11  /* IRQ master error detected */
-#define IS_IRQ_STAT            BIT_10  /* IRQ status exception */
-#define IS_NO_STAT_M1  BIT_9   /* No Rx Status from MAC 1 */
-#define IS_NO_STAT_M2  BIT_8   /* No Rx Status from MAC 2 */
-#define IS_NO_TIST_M1  BIT_7   /* No Time Stamp from MAC 1 */
-#define IS_NO_TIST_M2  BIT_6   /* No Time Stamp from MAC 2 */
-#define IS_RAM_RD_PAR  BIT_5   /* RAM Read  Parity Error */
-#define IS_RAM_WR_PAR  BIT_4   /* RAM Write Parity Error */
-#define IS_M1_PAR_ERR  BIT_3   /* MAC 1 Parity Error */
-#define IS_M2_PAR_ERR  BIT_2   /* MAC 2 Parity Error */
-#define IS_R1_PAR_ERR  BIT_1   /* Queue R1 Parity Error */
-#define IS_R2_PAR_ERR  BIT_0   /* Queue R2 Parity Error */
-
-/*     B2_CONN_TYP              8 bit  Connector type */
-/*     B2_PMD_TYP               8 bit  PMD type */
-/*     Values of connector and PMD type comply to SysKonnect internal std */
-
-/*     B2_MAC_CFG               8 bit  MAC Configuration / Chip Revision */
-#define CFG_CHIP_R_MSK (0xf<<4)        /* Bit 7.. 4: Chip Revision */
-                                                                       /* Bit 3.. 2:   reserved */
-#define CFG_DIS_M2_CLK BIT_1S          /* Disable Clock for 2nd MAC */
-#define CFG_SNG_MAC            BIT_0S          /* MAC Config: 0=2 MACs / 1=1 MAC*/
-
-/*     B2_CHIP_ID               8 bit  Chip Identification Number */
-#define CHIP_ID_GENESIS                0x0a    /* Chip ID for GENESIS */
-#define CHIP_ID_YUKON          0xb0    /* Chip ID for YUKON */
-#define CHIP_ID_YUKON_LITE     0xb1    /* Chip ID for YUKON-Lite (Rev. A1-A3) */
-#define CHIP_ID_YUKON_LP       0xb2    /* Chip ID for YUKON-LP */
-
-#define CHIP_REV_YU_LITE_A1    3               /* Chip Rev. for YUKON-Lite A1,A2 */
-#define CHIP_REV_YU_LITE_A3    7               /* Chip Rev. for YUKON-Lite A3 */
-
-/*     B2_FAR                  32 bit  Flash-Prom Addr Reg/Cnt */
-#define FAR_ADDR               0x1ffffL        /* Bit 16.. 0:  FPROM Address mask */
-
-/*     B2_LD_CTRL               8 bit  EPROM loader control register */
-/*     Bits are currently reserved */
-
-/*     B2_LD_TEST               8 bit  EPROM loader test register */
-                                                               /* Bit 7.. 4:   reserved */
-#define LD_T_ON                        BIT_3S  /* Loader Test mode on */
-#define LD_T_OFF               BIT_2S  /* Loader Test mode off */
-#define LD_T_STEP              BIT_1S  /* Decrement FPROM addr. Counter */
-#define LD_START               BIT_0S  /* Start loading FPROM */
-
-/*
- *     Timer Section
- */
-/*     B2_TI_CTRL               8 bit  Timer control */
-/*     B2_IRQM_CTRL     8 bit  IRQ Moderation Timer Control */
-                                                               /* Bit 7.. 3:   reserved */
-#define TIM_START              BIT_2S  /* Start Timer */
-#define TIM_STOP               BIT_1S  /* Stop  Timer */
-#define TIM_CLR_IRQ            BIT_0S  /* Clear Timer IRQ (!IRQM) */
-
-/*     B2_TI_TEST               8 Bit  Timer Test */
-/*     B2_IRQM_TEST     8 bit  IRQ Moderation Timer Test */
-/*     B28_DPT_TST              8 bit  Descriptor Poll Timer Test Reg */
-                                                               /* Bit 7.. 3:   reserved */
-#define TIM_T_ON               BIT_2S  /* Test mode on */
-#define TIM_T_OFF              BIT_1S  /* Test mode off */
-#define TIM_T_STEP             BIT_0S  /* Test step */
-
-/*     B28_DPT_INI     32 bit  Descriptor Poll Timer Init Val */
-/*     B28_DPT_VAL     32 bit  Descriptor Poll Timer Curr Val */
-                                                               /* Bit 31..24:  reserved */
-#define DPT_MSK                0x00ffffffL     /* Bit 23.. 0:  Desc Poll Timer Bits */
-
-/*     B28_DPT_CTRL     8 bit  Descriptor Poll Timer Ctrl Reg */
-                                                               /* Bit  7.. 2:  reserved */
-#define DPT_START              BIT_1S  /* Start Descriptor Poll Timer */
-#define DPT_STOP               BIT_0S  /* Stop  Descriptor Poll Timer */
-
-/*     B2_E_3                   8 bit  lower 4 bits used for HW self test result */
-#define B2_E3_RES_MASK 0x0f
-
-/*     B2_TST_CTRL1     8 bit  Test Control Register 1 */
-#define TST_FRC_DPERR_MR       BIT_7S  /* force DATAPERR on MST RD */
-#define TST_FRC_DPERR_MW       BIT_6S  /* force DATAPERR on MST WR */
-#define TST_FRC_DPERR_TR       BIT_5S  /* force DATAPERR on TRG RD */
-#define TST_FRC_DPERR_TW       BIT_4S  /* force DATAPERR on TRG WR */
-#define TST_FRC_APERR_M                BIT_3S  /* force ADDRPERR on MST */
-#define TST_FRC_APERR_T                BIT_2S  /* force ADDRPERR on TRG */
-#define TST_CFG_WRITE_ON       BIT_1S  /* Enable  Config Reg WR */
-#define TST_CFG_WRITE_OFF      BIT_0S  /* Disable Config Reg WR */
-
-/*     B2_TST_CTRL2     8 bit  Test Control Register 2 */
-                                                                       /* Bit 7.. 4:   reserved */
-                       /* force the following error on the next master read/write      */
-#define TST_FRC_DPERR_MR64     BIT_3S  /* DataPERR RD 64       */
-#define TST_FRC_DPERR_MW64     BIT_2S  /* DataPERR WR 64       */
-#define TST_FRC_APERR_1M64     BIT_1S  /* AddrPERR on 1. phase */
-#define TST_FRC_APERR_2M64     BIT_0S  /* AddrPERR on 2. phase */
-
-/*     B2_GP_IO                32 bit  General Purpose I/O Register */
-                                                       /* Bit 31..26:  reserved */
-#define GP_DIR_9       BIT_25  /* IO_9 direct, 0=In/1=Out */
-#define GP_DIR_8       BIT_24  /* IO_8 direct, 0=In/1=Out */
-#define GP_DIR_7       BIT_23  /* IO_7 direct, 0=In/1=Out */
-#define GP_DIR_6       BIT_22  /* IO_6 direct, 0=In/1=Out */
-#define GP_DIR_5       BIT_21  /* IO_5 direct, 0=In/1=Out */
-#define GP_DIR_4       BIT_20  /* IO_4 direct, 0=In/1=Out */
-#define GP_DIR_3       BIT_19  /* IO_3 direct, 0=In/1=Out */
-#define GP_DIR_2       BIT_18  /* IO_2 direct, 0=In/1=Out */
-#define GP_DIR_1       BIT_17  /* IO_1 direct, 0=In/1=Out */
-#define GP_DIR_0       BIT_16  /* IO_0 direct, 0=In/1=Out */
-                                               /* Bit 15..10:  reserved */
-#define GP_IO_9                BIT_9   /* IO_9 pin */
-#define GP_IO_8                BIT_8   /* IO_8 pin */
-#define GP_IO_7                BIT_7   /* IO_7 pin */
-#define GP_IO_6                BIT_6   /* IO_6 pin */
-#define GP_IO_5                BIT_5   /* IO_5 pin */
-#define GP_IO_4                BIT_4   /* IO_4 pin */
-#define GP_IO_3                BIT_3   /* IO_3 pin */
-#define GP_IO_2                BIT_2   /* IO_2 pin */
-#define GP_IO_1                BIT_1   /* IO_1 pin */
-#define GP_IO_0                BIT_0   /* IO_0 pin */
-
-/*     B2_I2C_CTRL             32 bit  I2C HW Control Register */
-#define I2C_FLAG               BIT_31          /* Start read/write if WR */
-#define I2C_ADDR               (0x7fffL<<16)   /* Bit 30..16:  Addr to be RD/WR */
-#define I2C_DEV_SEL            (0x7fL<<9)              /* Bit 15.. 9:  I2C Device Select */
-                                                               /* Bit  8.. 5:  reserved        */
-#define I2C_BURST_LEN  BIT_4           /* Burst Len, 1/4 bytes */
-#define I2C_DEV_SIZE   (7<<1)          /* Bit  3.. 1:  I2C Device Size */
-#define I2C_025K_DEV   (0<<1)          /*              0: 256 Bytes or smal. */
-#define I2C_05K_DEV            (1<<1)          /*              1: 512  Bytes   */
-#define I2C_1K_DEV             (2<<1)          /*              2: 1024 Bytes   */
-#define I2C_2K_DEV             (3<<1)          /*              3: 2048 Bytes   */
-#define I2C_4K_DEV             (4<<1)          /*              4: 4096 Bytes   */
-#define I2C_8K_DEV             (5<<1)          /*              5: 8192 Bytes   */
-#define I2C_16K_DEV            (6<<1)          /*              6: 16384 Bytes  */
-#define I2C_32K_DEV            (7<<1)          /*              7: 32768 Bytes  */
-#define I2C_STOP               BIT_0           /* Interrupt I2C transfer */
-
-/*     B2_I2C_IRQ              32 bit  I2C HW IRQ Register */
-                                                               /* Bit 31.. 1   reserved */
-#define I2C_CLR_IRQ            BIT_0   /* Clear I2C IRQ */
-
-/*     B2_I2C_SW               32 bit (8 bit access)   I2C HW SW Port Register */
-                                                               /* Bit  7.. 3:  reserved */
-#define I2C_DATA_DIR   BIT_2S          /* direction of I2C_DATA */
-#define I2C_DATA               BIT_1S          /* I2C Data Port        */
-#define I2C_CLK                        BIT_0S          /* I2C Clock Port       */
-
-/*
- * I2C Address
- */
-#define I2C_SENS_ADDR  LM80_ADDR       /* I2C Sensor Address, (Volt and Temp)*/
-
-
-/*     B2_BSC_CTRL              8 bit  Blink Source Counter Control */
-                                                       /* Bit  7.. 2:  reserved */
-#define BSC_START      BIT_1S          /* Start Blink Source Counter */
-#define BSC_STOP       BIT_0S          /* Stop  Blink Source Counter */
-
-/*     B2_BSC_STAT              8 bit  Blink Source Counter Status */
-                                                       /* Bit  7.. 1:  reserved */
-#define BSC_SRC                BIT_0S          /* Blink Source, 0=Off / 1=On */
-
-/*     B2_BSC_TST              16 bit  Blink Source Counter Test Reg */
-#define BSC_T_ON       BIT_2S          /* Test mode on */
-#define BSC_T_OFF      BIT_1S          /* Test mode off */
-#define BSC_T_STEP     BIT_0S          /* Test step */
-
-
-/*     B3_RAM_ADDR             32 bit  RAM Address, to read or write */
-                                       /* Bit 31..19:  reserved */
-#define RAM_ADR_RAN    0x0007ffffL     /* Bit 18.. 0:  RAM Address Range */
-
-/* RAM Interface Registers */
-/*     B3_RI_CTRL              16 bit  RAM Iface Control Register */
-                                                               /* Bit 15..10:  reserved */
-#define RI_CLR_RD_PERR BIT_9S  /* Clear IRQ RAM Read Parity Err */
-#define RI_CLR_WR_PERR BIT_8S  /* Clear IRQ RAM Write Parity Err*/
-                                                               /* Bit  7.. 2:  reserved */
-#define RI_RST_CLR             BIT_1S  /* Clear RAM Interface Reset */
-#define RI_RST_SET             BIT_0S  /* Set   RAM Interface Reset */
-
-/*     B3_RI_TEST               8 bit  RAM Iface Test Register */
-                                                               /* Bit 15.. 4:  reserved */
-#define RI_T_EV                        BIT_3S  /* Timeout Event occured */
-#define RI_T_ON                        BIT_2S  /* Timeout Timer Test On */
-#define RI_T_OFF               BIT_1S  /* Timeout Timer Test Off */
-#define RI_T_STEP              BIT_0S  /* Timeout Timer Step */
-
-/* MAC Arbiter Registers */
-/*     B3_MA_TO_CTRL   16 bit  MAC Arbiter Timeout Ctrl Reg */
-                                                               /* Bit 15.. 4:  reserved */
-#define MA_FOE_ON              BIT_3S  /* XMAC Fast Output Enable ON */
-#define MA_FOE_OFF             BIT_2S  /* XMAC Fast Output Enable OFF */
-#define MA_RST_CLR             BIT_1S  /* Clear MAC Arbiter Reset */
-#define MA_RST_SET             BIT_0S  /* Set   MAC Arbiter Reset */
-
-/*     B3_MA_RC_CTRL   16 bit  MAC Arbiter Recovery Ctrl Reg */
-                                                               /* Bit 15.. 8:  reserved */
-#define MA_ENA_REC_TX2 BIT_7S  /* Enable  Recovery Timer TX2 */
-#define MA_DIS_REC_TX2 BIT_6S  /* Disable Recovery Timer TX2 */
-#define MA_ENA_REC_TX1 BIT_5S  /* Enable  Recovery Timer TX1 */
-#define MA_DIS_REC_TX1 BIT_4S  /* Disable Recovery Timer TX1 */
-#define MA_ENA_REC_RX2 BIT_3S  /* Enable  Recovery Timer RX2 */
-#define MA_DIS_REC_RX2 BIT_2S  /* Disable Recovery Timer RX2 */
-#define MA_ENA_REC_RX1 BIT_1S  /* Enable  Recovery Timer RX1 */
-#define MA_DIS_REC_RX1 BIT_0S  /* Disable Recovery Timer RX1 */
-
-/* Packet Arbiter Registers */
-/*     B3_PA_CTRL              16 bit  Packet Arbiter Ctrl Register */
-                                                               /* Bit 15..14:  reserved */
-#define PA_CLR_TO_TX2  BIT_13S /* Clear IRQ Packet Timeout TX2 */
-#define PA_CLR_TO_TX1  BIT_12S /* Clear IRQ Packet Timeout TX1 */
-#define PA_CLR_TO_RX2  BIT_11S /* Clear IRQ Packet Timeout RX2 */
-#define PA_CLR_TO_RX1  BIT_10S /* Clear IRQ Packet Timeout RX1 */
-#define PA_ENA_TO_TX2  BIT_9S  /* Enable  Timeout Timer TX2 */
-#define PA_DIS_TO_TX2  BIT_8S  /* Disable Timeout Timer TX2 */
-#define PA_ENA_TO_TX1  BIT_7S  /* Enable  Timeout Timer TX1 */
-#define PA_DIS_TO_TX1  BIT_6S  /* Disable Timeout Timer TX1 */
-#define PA_ENA_TO_RX2  BIT_5S  /* Enable  Timeout Timer RX2 */
-#define PA_DIS_TO_RX2  BIT_4S  /* Disable Timeout Timer RX2 */
-#define PA_ENA_TO_RX1  BIT_3S  /* Enable  Timeout Timer RX1 */
-#define PA_DIS_TO_RX1  BIT_2S  /* Disable Timeout Timer RX1 */
-#define PA_RST_CLR             BIT_1S  /* Clear MAC Arbiter Reset */
-#define PA_RST_SET             BIT_0S  /* Set   MAC Arbiter Reset */
-
-#define PA_ENA_TO_ALL  (PA_ENA_TO_RX1 | PA_ENA_TO_RX2 |\
-                                               PA_ENA_TO_TX1 | PA_ENA_TO_TX2)
-
-/* Rx/Tx Path related Arbiter Test Registers */
-/*     B3_MA_TO_TEST   16 bit  MAC Arbiter Timeout Test Reg */
-/*     B3_MA_RC_TEST   16 bit  MAC Arbiter Recovery Test Reg */
-/*     B3_PA_TEST              16 bit  Packet Arbiter Test Register */
-/*                     Bit 15, 11, 7, and 3 are reserved in B3_PA_TEST */
-#define TX2_T_EV       BIT_15S         /* TX2 Timeout/Recv Event occured */
-#define TX2_T_ON       BIT_14S         /* TX2 Timeout/Recv Timer Test On */
-#define TX2_T_OFF      BIT_13S         /* TX2 Timeout/Recv Timer Tst Off */
-#define TX2_T_STEP     BIT_12S         /* TX2 Timeout/Recv Timer Step */
-#define TX1_T_EV       BIT_11S         /* TX1 Timeout/Recv Event occured */
-#define TX1_T_ON       BIT_10S         /* TX1 Timeout/Recv Timer Test On */
-#define TX1_T_OFF      BIT_9S          /* TX1 Timeout/Recv Timer Tst Off */
-#define TX1_T_STEP     BIT_8S          /* TX1 Timeout/Recv Timer Step */
-#define RX2_T_EV       BIT_7S          /* RX2 Timeout/Recv Event occured */
-#define RX2_T_ON       BIT_6S          /* RX2 Timeout/Recv Timer Test On */
-#define RX2_T_OFF      BIT_5S          /* RX2 Timeout/Recv Timer Tst Off */
-#define RX2_T_STEP     BIT_4S          /* RX2 Timeout/Recv Timer Step */
-#define RX1_T_EV       BIT_3S          /* RX1 Timeout/Recv Event occured */
-#define RX1_T_ON       BIT_2S          /* RX1 Timeout/Recv Timer Test On */
-#define RX1_T_OFF      BIT_1S          /* RX1 Timeout/Recv Timer Tst Off */
-#define RX1_T_STEP     BIT_0S          /* RX1 Timeout/Recv Timer Step */
-
-
-/* Transmit Arbiter Registers MAC 1 and 2, use MR_ADDR() to access */
-/*     TXA_ITI_INI             32 bit  Tx Arb Interval Timer Init Val */
-/*     TXA_ITI_VAL             32 bit  Tx Arb Interval Timer Value */
-/*     TXA_LIM_INI             32 bit  Tx Arb Limit Counter Init Val */
-/*     TXA_LIM_VAL             32 bit  Tx Arb Limit Counter Value */
-                                                               /* Bit 31..24:  reserved */
-#define TXA_MAX_VAL    0x00ffffffUL/* Bit 23.. 0:      Max TXA Timer/Cnt Val */
-
-/*     TXA_CTRL                 8 bit  Tx Arbiter Control Register */
-#define TXA_ENA_FSYNC  BIT_7S  /* Enable  force of sync Tx queue */
-#define TXA_DIS_FSYNC  BIT_6S  /* Disable force of sync Tx queue */
-#define TXA_ENA_ALLOC  BIT_5S  /* Enable  alloc of free bandwidth */
-#define TXA_DIS_ALLOC  BIT_4S  /* Disable alloc of free bandwidth */
-#define TXA_START_RC   BIT_3S  /* Start sync Rate Control */
-#define TXA_STOP_RC            BIT_2S  /* Stop  sync Rate Control */
-#define TXA_ENA_ARB            BIT_1S  /* Enable  Tx Arbiter */
-#define TXA_DIS_ARB            BIT_0S  /* Disable Tx Arbiter */
-
-/*     TXA_TEST                 8 bit  Tx Arbiter Test Register */
-                                                               /* Bit 7.. 6:   reserved */
-#define TXA_INT_T_ON   BIT_5S  /* Tx Arb Interval Timer Test On */
-#define TXA_INT_T_OFF  BIT_4S  /* Tx Arb Interval Timer Test Off */
-#define TXA_INT_T_STEP BIT_3S  /* Tx Arb Interval Timer Step */
-#define TXA_LIM_T_ON   BIT_2S  /* Tx Arb Limit Timer Test On */
-#define TXA_LIM_T_OFF  BIT_1S  /* Tx Arb Limit Timer Test Off */
-#define TXA_LIM_T_STEP BIT_0S  /* Tx Arb Limit Timer Step */
-
-/*     TXA_STAT                 8 bit  Tx Arbiter Status Register */
-                                                               /* Bit 7.. 1:   reserved */
-#define TXA_PRIO_XS            BIT_0S  /* sync queue has prio to send */
-
-/*     Q_BC                    32 bit  Current Byte Counter */
-                                                               /* Bit 31..16:  reserved */
-#define BC_MAX                 0xffff  /* Bit 15.. 0:  Byte counter */
-
-/* BMU Control Status Registers */
-/*     B0_R1_CSR               32 bit  BMU Ctrl/Stat Rx Queue 1 */
-/*     B0_R2_CSR               32 bit  BMU Ctrl/Stat Rx Queue 2 */
-/*     B0_XA1_CSR              32 bit  BMU Ctrl/Stat Sync Tx Queue 1 */
-/*     B0_XS1_CSR              32 bit  BMU Ctrl/Stat Async Tx Queue 1 */
-/*     B0_XA2_CSR              32 bit  BMU Ctrl/Stat Sync Tx Queue 2 */
-/*     B0_XS2_CSR              32 bit  BMU Ctrl/Stat Async Tx Queue 2 */
-/*     Q_CSR                   32 bit  BMU Control/Status Register */
-                                                               /* Bit 31..25:  reserved */
-#define CSR_SV_IDLE            BIT_24          /* BMU SM Idle */
-                                                               /* Bit 23..22:  reserved */
-#define CSR_DESC_CLR   BIT_21          /* Clear Reset for Descr */
-#define CSR_DESC_SET   BIT_20          /* Set   Reset for Descr */
-#define CSR_FIFO_CLR   BIT_19          /* Clear Reset for FIFO */
-#define CSR_FIFO_SET   BIT_18          /* Set   Reset for FIFO */
-#define CSR_HPI_RUN            BIT_17          /* Release HPI SM */
-#define CSR_HPI_RST            BIT_16          /* Reset   HPI SM to Idle */
-#define CSR_SV_RUN             BIT_15          /* Release Supervisor SM */
-#define CSR_SV_RST             BIT_14          /* Reset   Supervisor SM */
-#define CSR_DREAD_RUN  BIT_13          /* Release Descr Read SM */
-#define CSR_DREAD_RST  BIT_12          /* Reset   Descr Read SM */
-#define CSR_DWRITE_RUN BIT_11          /* Release Descr Write SM */
-#define CSR_DWRITE_RST BIT_10          /* Reset   Descr Write SM */
-#define CSR_TRANS_RUN  BIT_9           /* Release Transfer SM */
-#define CSR_TRANS_RST  BIT_8           /* Reset   Transfer SM */
-#define CSR_ENA_POL            BIT_7           /* Enable  Descr Polling */
-#define CSR_DIS_POL            BIT_6           /* Disable Descr Polling */
-#define CSR_STOP               BIT_5           /* Stop  Rx/Tx Queue */
-#define CSR_START              BIT_4           /* Start Rx/Tx Queue */
-#define CSR_IRQ_CL_P   BIT_3           /* (Rx) Clear Parity IRQ */
-#define CSR_IRQ_CL_B   BIT_2           /* Clear EOB IRQ */
-#define CSR_IRQ_CL_F   BIT_1           /* Clear EOF IRQ */
-#define CSR_IRQ_CL_C   BIT_0           /* Clear ERR IRQ */
-
-#define CSR_SET_RESET  (CSR_DESC_SET | CSR_FIFO_SET | CSR_HPI_RST |\
-                                               CSR_SV_RST | CSR_DREAD_RST | CSR_DWRITE_RST |\
-                                               CSR_TRANS_RST)
-#define CSR_CLR_RESET  (CSR_DESC_CLR | CSR_FIFO_CLR | CSR_HPI_RUN |\
-                                               CSR_SV_RUN | CSR_DREAD_RUN | CSR_DWRITE_RUN |\
-                                               CSR_TRANS_RUN)
-
-/*     Q_F                             32 bit  Flag Register */
-                                                                       /* Bit 31..28:  reserved */
-#define F_ALM_FULL             BIT_27          /* Rx FIFO: almost full */
-#define F_EMPTY                        BIT_27          /* Tx FIFO: empty flag */
-#define F_FIFO_EOF             BIT_26          /* Tag (EOF Flag) bit in FIFO */
-#define F_WM_REACHED   BIT_25          /* Watermark reached */
-                                                                       /* reserved */
-#define F_FIFO_LEVEL   (0x1fL<<16)     /* Bit 23..16:  # of Qwords in FIFO */
-                                                                       /* Bit 15..11:  reserved */
-#define F_WATER_MARK   0x0007ffL       /* Bit 10.. 0:  Watermark */
-
-/*     Q_T1                    32 bit  Test Register 1 */
-/*             Holds four State Machine control Bytes */
-#define SM_CTRL_SV_MSK (0xffL<<24)     /* Bit 31..24:  Control Supervisor SM */
-#define SM_CTRL_RD_MSK (0xffL<<16)     /* Bit 23..16:  Control Read Desc SM */
-#define SM_CTRL_WR_MSK (0xffL<<8)      /* Bit 15.. 8:  Control Write Desc SM */
-#define SM_CTRL_TR_MSK 0xffL           /* Bit  7.. 0:  Control Transfer SM */
-
-/*     Q_T1_TR                  8 bit  Test Register 1 Transfer SM */
-/*     Q_T1_WR                  8 bit  Test Register 1 Write Descriptor SM */
-/*     Q_T1_RD                  8 bit  Test Register 1 Read Descriptor SM */
-/*     Q_T1_SV                  8 bit  Test Register 1 Supervisor SM */
-
-/* The control status byte of each machine looks like ... */
-#define SM_STATE               0xf0    /* Bit 7.. 4:   State which shall be loaded */
-#define SM_LOAD                        BIT_3S  /* Load the SM with SM_STATE */
-#define SM_TEST_ON             BIT_2S  /* Switch on SM Test Mode */
-#define SM_TEST_OFF            BIT_1S  /* Go off the Test Mode */
-#define SM_STEP                        BIT_0S  /* Step the State Machine */
-/* The encoding of the states is not supported by the Diagnostics Tool */
-
-/*     Q_T2                    32 bit  Test Register 2 */
-                                                               /* Bit 31.. 8:  reserved */
-#define T2_AC_T_ON             BIT_7   /* Address Counter Test Mode on */
-#define T2_AC_T_OFF            BIT_6   /* Address Counter Test Mode off */
-#define T2_BC_T_ON             BIT_5   /* Byte Counter Test Mode on */
-#define T2_BC_T_OFF            BIT_4   /* Byte Counter Test Mode off */
-#define T2_STEP04              BIT_3   /* Inc AC/Dec BC by 4 */
-#define T2_STEP03              BIT_2   /* Inc AC/Dec BC by 3 */
-#define T2_STEP02              BIT_1   /* Inc AC/Dec BC by 2 */
-#define T2_STEP01              BIT_0   /* Inc AC/Dec BC by 1 */
-
-/*     Q_T3                    32 bit  Test Register 3 */
-                                                               /* Bit 31.. 7:  reserved */
-#define T3_MUX_MSK             (7<<4)  /* Bit  6.. 4:  Mux Position */
-                                                               /* Bit  3:      reserved */
-#define T3_VRAM_MSK            7               /* Bit  2.. 0:  Virtual RAM Buffer Address */
-
-/* RAM Buffer Register Offsets, use RB_ADDR(Queue, Offs) to access */
-/*     RB_START                32 bit  RAM Buffer Start Address */
-/*     RB_END                  32 bit  RAM Buffer End Address */
-/*     RB_WP                   32 bit  RAM Buffer Write Pointer */
-/*     RB_RP                   32 bit  RAM Buffer Read Pointer */
-/*     RB_RX_UTPP              32 bit  Rx Upper Threshold, Pause Pack */
-/*     RB_RX_LTPP              32 bit  Rx Lower Threshold, Pause Pack */
-/*     RB_RX_UTHP              32 bit  Rx Upper Threshold, High Prio */
-/*     RB_RX_LTHP              32 bit  Rx Lower Threshold, High Prio */
-/*     RB_PC                   32 bit  RAM Buffer Packet Counter */
-/*     RB_LEV                  32 bit  RAM Buffer Level Register */
-                               /* Bit 31..19:  reserved */
-#define RB_MSK 0x0007ffff      /* Bit 18.. 0:  RAM Buffer Pointer Bits */
-
-/*     RB_TST2                  8 bit  RAM Buffer Test Register 2 */
-                                                               /* Bit 7.. 4:   reserved */
-#define RB_PC_DEC              BIT_3S  /* Packet Counter Decrem */
-#define RB_PC_T_ON             BIT_2S  /* Packet Counter Test On */
-#define RB_PC_T_OFF            BIT_1S  /* Packet Counter Tst Off */
-#define RB_PC_INC              BIT_0S  /* Packet Counter Increm */
-
-/*     RB_TST1                  8 bit  RAM Buffer Test Register 1 */
-                                                       /* Bit 7:       reserved */
-#define RB_WP_T_ON             BIT_6S  /* Write Pointer Test On */
-#define RB_WP_T_OFF            BIT_5S  /* Write Pointer Test Off */
-#define RB_WP_INC              BIT_4S  /* Write Pointer Increm */
-                                                               /* Bit 3:       reserved */
-#define RB_RP_T_ON             BIT_2S  /* Read Pointer Test On */
-#define RB_RP_T_OFF            BIT_1S  /* Read Pointer Test Off */
-#define RB_RP_DEC              BIT_0S  /* Read Pointer Decrement */
-
-/*     RB_CTRL                  8 bit  RAM Buffer Control Register */
-                                                               /* Bit 7.. 6:   reserved */
-#define RB_ENA_STFWD   BIT_5S  /* Enable  Store & Forward */
-#define RB_DIS_STFWD   BIT_4S  /* Disable Store & Forward */
-#define RB_ENA_OP_MD   BIT_3S  /* Enable  Operation Mode */
-#define RB_DIS_OP_MD   BIT_2S  /* Disable Operation Mode */
-#define RB_RST_CLR             BIT_1S  /* Clear RAM Buf STM Reset */
-#define RB_RST_SET             BIT_0S  /* Set   RAM Buf STM Reset */
-
-
-/* Receive and Transmit MAC FIFO Registers (GENESIS only) */
-
-/*     RX_MFF_EA               32 bit  Receive MAC FIFO End Address */
-/*     RX_MFF_WP               32 bit  Receive MAC FIFO Write Pointer */
-/*     RX_MFF_RP               32 bit  Receive MAC FIFO Read Pointer */
-/*     RX_MFF_PC               32 bit  Receive MAC FIFO Packet Counter */
-/*     RX_MFF_LEV              32 bit  Receive MAC FIFO Level */
-/*     TX_MFF_EA               32 bit  Transmit MAC FIFO End Address */
-/*     TX_MFF_WP               32 bit  Transmit MAC FIFO Write Pointer */
-/*     TX_MFF_WSP              32 bit  Transmit MAC FIFO WR Shadow Pointer */
-/*     TX_MFF_RP               32 bit  Transmit MAC FIFO Read Pointer */
-/*     TX_MFF_PC               32 bit  Transmit MAC FIFO Packet Cnt */
-/*     TX_MFF_LEV              32 bit  Transmit MAC FIFO Level */
-                                                               /* Bit 31.. 6:  reserved */
-#define MFF_MSK                        0x007fL /* Bit  5.. 0:  MAC FIFO Address/Ptr Bits */
-
-/*     RX_MFF_CTRL1    16 bit  Receive MAC FIFO Control Reg 1 */
-                                                               /* Bit 15..14:  reserved */
-#define MFF_ENA_RDY_PAT        BIT_13S         /* Enable  Ready Patch */
-#define MFF_DIS_RDY_PAT        BIT_12S         /* Disable Ready Patch */
-#define MFF_ENA_TIM_PAT        BIT_11S         /* Enable  Timing Patch */
-#define MFF_DIS_TIM_PAT        BIT_10S         /* Disable Timing Patch */
-#define MFF_ENA_ALM_FUL        BIT_9S          /* Enable  AlmostFull Sign */
-#define MFF_DIS_ALM_FUL        BIT_8S          /* Disable AlmostFull Sign */
-#define MFF_ENA_PAUSE  BIT_7S          /* Enable  Pause Signaling */
-#define MFF_DIS_PAUSE  BIT_6S          /* Disable Pause Signaling */
-#define MFF_ENA_FLUSH  BIT_5S          /* Enable  Frame Flushing */
-#define MFF_DIS_FLUSH  BIT_4S          /* Disable Frame Flushing */
-#define MFF_ENA_TIST   BIT_3S          /* Enable  Time Stamp Gener */
-#define MFF_DIS_TIST   BIT_2S          /* Disable Time Stamp Gener */
-#define MFF_CLR_INTIST BIT_1S          /* Clear IRQ No Time Stamp */
-#define MFF_CLR_INSTAT BIT_0S          /* Clear IRQ No Status */
-
-#define MFF_RX_CTRL_DEF MFF_ENA_TIM_PAT
-
-/*     TX_MFF_CTRL1    16 bit  Transmit MAC FIFO Control Reg 1 */
-#define MFF_CLR_PERR   BIT_15S         /* Clear Parity Error IRQ */
-                                                               /* Bit 14:      reserved */
-#define MFF_ENA_PKT_REC        BIT_13S         /* Enable  Packet Recovery */
-#define MFF_DIS_PKT_REC BIT_12S                /* Disable Packet Recovery */
-/*     MFF_ENA_TIM_PAT  (see RX_MFF_CTRL1) Bit 11:     Enable  Timing Patch */
-/*     MFF_DIS_TIM_PAT  (see RX_MFF_CTRL1) Bit 10:     Disable Timing Patch */
-/*     MFF_ENA_ALM_FUL  (see RX_MFF_CTRL1) Bit  9:     Enable  Almost Full Sign */
-/*     MFF_DIS_ALM_FUL  (see RX_MFF_CTRL1) Bit  8:     Disable Almost Full Sign */
-#define MFF_ENA_W4E            BIT_7S          /* Enable  Wait for Empty */
-#define MFF_DIS_W4E            BIT_6S          /* Disable Wait for Empty */
-/*     MFF_ENA_FLUSH    (see RX_MFF_CTRL1) Bit  5:     Enable  Frame Flushing */
-/*     MFF_DIS_FLUSH    (see RX_MFF_CTRL1) Bit  4:     Disable Frame Flushing */
-#define MFF_ENA_LOOPB  BIT_3S          /* Enable  Loopback */
-#define MFF_DIS_LOOPB  BIT_2S          /* Disable Loopback */
-#define MFF_CLR_MAC_RST        BIT_1S          /* Clear XMAC Reset */
-#define MFF_SET_MAC_RST        BIT_0S          /* Set   XMAC Reset */
-
-#define MFF_TX_CTRL_DEF        (MFF_ENA_PKT_REC | MFF_ENA_TIM_PAT | MFF_ENA_FLUSH)
-
-/*     RX_MFF_TST2              8 bit  Receive MAC FIFO Test Register 2 */
-/*     TX_MFF_TST2              8 bit  Transmit MAC FIFO Test Register 2 */
-                                                               /* Bit 7:       reserved */
-#define MFF_WSP_T_ON   BIT_6S  /* Tx: Write Shadow Ptr TestOn */
-#define MFF_WSP_T_OFF  BIT_5S  /* Tx: Write Shadow Ptr TstOff */
-#define MFF_WSP_INC            BIT_4S  /* Tx: Write Shadow Ptr Increment */
-#define MFF_PC_DEC             BIT_3S  /* Packet Counter Decrement */
-#define MFF_PC_T_ON            BIT_2S  /* Packet Counter Test On */
-#define MFF_PC_T_OFF   BIT_1S  /* Packet Counter Test Off */
-#define MFF_PC_INC             BIT_0S  /* Packet Counter Increment */
-
-/*     RX_MFF_TST1              8 bit  Receive MAC FIFO Test Register 1 */
-/*     TX_MFF_TST1              8 bit  Transmit MAC FIFO Test Register 1 */
-                                       /* Bit 7:       reserved */
-#define MFF_WP_T_ON            BIT_6S  /* Write Pointer Test On */
-#define MFF_WP_T_OFF   BIT_5S  /* Write Pointer Test Off */
-#define MFF_WP_INC             BIT_4S  /* Write Pointer Increm */
-                                                       /* Bit 3:       reserved */
-#define MFF_RP_T_ON            BIT_2S  /* Read Pointer Test On */
-#define MFF_RP_T_OFF   BIT_1S  /* Read Pointer Test Off */
-#define MFF_RP_DEC             BIT_0S  /* Read Pointer Decrement */
-
-/*     RX_MFF_CTRL2     8 bit  Receive MAC FIFO Control Reg 2 */
-/*     TX_MFF_CTRL2     8 bit  Transmit MAC FIFO Control Reg 2 */
-                                                               /* Bit 7..4:    reserved */
-#define MFF_ENA_OP_MD  BIT_3S  /* Enable  Operation Mode */
-#define MFF_DIS_OP_MD  BIT_2S  /* Disable Operation Mode */
-#define MFF_RST_CLR            BIT_1S  /* Clear MAC FIFO Reset */
-#define MFF_RST_SET            BIT_0S  /* Set   MAC FIFO Reset */
-
-
-/*     Link LED Counter Registers (GENESIS only) */
-
-/*     RX_LED_CTRL              8 bit  Receive LED Cnt Control Reg */
-/*     TX_LED_CTRL              8 bit  Transmit LED Cnt Control Reg */
-/*     LNK_SYNC_CTRL    8 bit  Link Sync Cnt Control Register */
-                                                       /* Bit 7.. 3:   reserved */
-#define LED_START              BIT_2S  /* Start Timer */
-#define LED_STOP               BIT_1S  /* Stop Timer */
-#define LED_STATE              BIT_0S  /* Rx/Tx: LED State, 1=LED on */
-#define LED_CLR_IRQ            BIT_0S  /* Lnk:         Clear Link IRQ */
-
-/*     RX_LED_TST               8 bit  Receive LED Cnt Test Register */
-/*     TX_LED_TST               8 bit  Transmit LED Cnt Test Register */
-/*     LNK_SYNC_TST     8 bit  Link Sync Cnt Test Register */
-                                                       /* Bit 7.. 3:   reserved */
-#define LED_T_ON               BIT_2S  /* LED Counter Test mode On */
-#define LED_T_OFF              BIT_1S  /* LED Counter Test mode Off */
-#define LED_T_STEP             BIT_0S  /* LED Counter Step */
-
-/*     LNK_LED_REG              8 bit  Link LED Register */
-                                                               /* Bit 7.. 6:   reserved */
-#define LED_BLK_ON             BIT_5S  /* Link LED Blinking On */
-#define LED_BLK_OFF            BIT_4S  /* Link LED Blinking Off */
-#define LED_SYNC_ON            BIT_3S  /* Use Sync Wire to switch LED */
-#define LED_SYNC_OFF   BIT_2S  /* Disable Sync Wire Input */
-#define LED_ON                 BIT_1S  /* switch LED on */
-#define LED_OFF                        BIT_0S  /* switch LED off */
-
-/*     Receive and Transmit GMAC FIFO Registers (YUKON only) */
-
-/*     RX_GMF_EA               32 bit  Rx GMAC FIFO End Address */
-/*     RX_GMF_AF_THR   32 bit  Rx GMAC FIFO Almost Full Thresh. */
-/*     RX_GMF_WP               32 bit  Rx GMAC FIFO Write Pointer */
-/*     RX_GMF_WLEV             32 bit  Rx GMAC FIFO Write Level */
-/*     RX_GMF_RP               32 bit  Rx GMAC FIFO Read Pointer */
-/*     RX_GMF_RLEV             32 bit  Rx GMAC FIFO Read Level */
-/*     TX_GMF_EA               32 bit  Tx GMAC FIFO End Address */
-/*     TX_GMF_AE_THR   32 bit  Tx GMAC FIFO Almost Empty Thresh.*/
-/*     TX_GMF_WP               32 bit  Tx GMAC FIFO Write Pointer */
-/*     TX_GMF_WSP              32 bit  Tx GMAC FIFO Write Shadow Ptr. */
-/*     TX_GMF_WLEV             32 bit  Tx GMAC FIFO Write Level */
-/*     TX_GMF_RP               32 bit  Tx GMAC FIFO Read Pointer */
-/*     TX_GMF_RSTP             32 bit  Tx GMAC FIFO Restart Pointer */
-/*     TX_GMF_RLEV             32 bit  Tx GMAC FIFO Read Level */
-
-/*     RX_GMF_CTRL_T   32 bit  Rx GMAC FIFO Control/Test */
-                                               /* Bits 31..15: reserved */
-#define GMF_WP_TST_ON  BIT_14          /* Write Pointer Test On */
-#define GMF_WP_TST_OFF BIT_13          /* Write Pointer Test Off */
-#define GMF_WP_STEP            BIT_12          /* Write Pointer Step/Increment */
-                                               /* Bit 11:      reserved */
-#define GMF_RP_TST_ON  BIT_10          /* Read Pointer Test On */
-#define GMF_RP_TST_OFF BIT_9           /* Read Pointer Test Off */
-#define GMF_RP_STEP            BIT_8           /* Read Pointer Step/Increment */
-#define GMF_RX_F_FL_ON BIT_7           /* Rx FIFO Flush Mode On */
-#define GMF_RX_F_FL_OFF        BIT_6           /* Rx FIFO Flush Mode Off */
-#define GMF_CLI_RX_FO  BIT_5           /* Clear IRQ Rx FIFO Overrun */
-#define GMF_CLI_RX_FC  BIT_4           /* Clear IRQ Rx Frame Complete */
-#define GMF_OPER_ON            BIT_3           /* Operational Mode On */
-#define GMF_OPER_OFF   BIT_2           /* Operational Mode Off */
-#define GMF_RST_CLR            BIT_1           /* Clear GMAC FIFO Reset */
-#define GMF_RST_SET            BIT_0           /* Set   GMAC FIFO Reset */
-
-/*     TX_GMF_CTRL_T   32 bit  Tx GMAC FIFO Control/Test */
-                                               /* Bits 31..19: reserved */
-#define GMF_WSP_TST_ON BIT_18          /* Write Shadow Pointer Test On */
-#define GMF_WSP_TST_OFF        BIT_17          /* Write Shadow Pointer Test Off */
-#define GMF_WSP_STEP   BIT_16          /* Write Shadow Pointer Step/Increment */
-                                               /* Bits 15..7: same as for RX_GMF_CTRL_T */
-#define GMF_CLI_TX_FU  BIT_6           /* Clear IRQ Tx FIFO Underrun */
-#define GMF_CLI_TX_FC  BIT_5           /* Clear IRQ Tx Frame Complete */
-#define GMF_CLI_TX_PE  BIT_4           /* Clear IRQ Tx Parity Error */
-                                               /* Bits 3..0: same as for RX_GMF_CTRL_T */
-
-#define GMF_RX_CTRL_DEF                (GMF_OPER_ON | GMF_RX_F_FL_ON)
-#define GMF_TX_CTRL_DEF                GMF_OPER_ON
-
-#define RX_GMF_FL_THR_DEF      0x0a    /* Rx GMAC FIFO Flush Threshold default */
-
-/*     GMAC_TI_ST_CTRL  8 bit  Time Stamp Timer Ctrl Reg (YUKON only) */
-                                                               /* Bit 7.. 3:   reserved */
-#define GMT_ST_START   BIT_2S          /* Start Time Stamp Timer */
-#define GMT_ST_STOP            BIT_1S          /* Stop  Time Stamp Timer */
-#define GMT_ST_CLR_IRQ BIT_0S          /* Clear Time Stamp Timer IRQ */
-
-/*     GMAC_CTRL               32 bit  GMAC Control Reg (YUKON only) */
-                                               /* Bits 31.. 8: reserved */
-#define GMC_H_BURST_ON BIT_7           /* Half Duplex Burst Mode On */
-#define GMC_H_BURST_OFF        BIT_6           /* Half Duplex Burst Mode Off */
-#define GMC_F_LOOPB_ON BIT_5           /* FIFO Loopback On */
-#define GMC_F_LOOPB_OFF        BIT_4           /* FIFO Loopback Off */
-#define GMC_PAUSE_ON   BIT_3           /* Pause On */
-#define GMC_PAUSE_OFF  BIT_2           /* Pause Off */
-#define GMC_RST_CLR            BIT_1           /* Clear GMAC Reset */
-#define GMC_RST_SET            BIT_0           /* Set   GMAC Reset */
-
-/*     GPHY_CTRL               32 bit  GPHY Control Reg (YUKON only) */
-                                               /* Bits 31..29: reserved */
-#define GPC_SEL_BDT            BIT_28  /* Select Bi-Dir. Transfer for MDC/MDIO */
-#define GPC_INT_POL_HI BIT_27  /* IRQ Polarity is Active HIGH */
-#define GPC_75_OHM             BIT_26  /* Use 75 Ohm Termination instead of 50 */
-#define GPC_DIS_FC             BIT_25  /* Disable Automatic Fiber/Copper Detection */
-#define GPC_DIS_SLEEP  BIT_24  /* Disable Energy Detect */
-#define GPC_HWCFG_M_3  BIT_23  /* HWCFG_MODE[3] */
-#define GPC_HWCFG_M_2  BIT_22  /* HWCFG_MODE[2] */
-#define GPC_HWCFG_M_1  BIT_21  /* HWCFG_MODE[1] */
-#define GPC_HWCFG_M_0  BIT_20  /* HWCFG_MODE[0] */
-#define GPC_ANEG_0             BIT_19  /* ANEG[0] */
-#define GPC_ENA_XC             BIT_18  /* Enable MDI crossover */
-#define GPC_DIS_125            BIT_17  /* Disable 125 MHz clock */
-#define GPC_ANEG_3             BIT_16  /* ANEG[3] */
-#define GPC_ANEG_2             BIT_15  /* ANEG[2] */
-#define GPC_ANEG_1             BIT_14  /* ANEG[1] */
-#define GPC_ENA_PAUSE  BIT_13  /* Enable Pause (SYM_OR_REM) */
-#define GPC_PHYADDR_4  BIT_12  /* Bit 4 of Phy Addr */
-#define GPC_PHYADDR_3  BIT_11  /* Bit 3 of Phy Addr */
-#define GPC_PHYADDR_2  BIT_10  /* Bit 2 of Phy Addr */
-#define GPC_PHYADDR_1  BIT_9   /* Bit 1 of Phy Addr */
-#define GPC_PHYADDR_0  BIT_8   /* Bit 0 of Phy Addr */
-                                               /* Bits  7..2:  reserved */
-#define GPC_RST_CLR            BIT_1   /* Clear GPHY Reset */
-#define GPC_RST_SET            BIT_0   /* Set   GPHY Reset */
-
-#define GPC_HWCFG_GMII_COP     (GPC_HWCFG_M_3 | GPC_HWCFG_M_2 | \
-                                                        GPC_HWCFG_M_1 | GPC_HWCFG_M_0)
-
-#define GPC_HWCFG_GMII_FIB     (                                GPC_HWCFG_M_2 | \
-                                                        GPC_HWCFG_M_1 | GPC_HWCFG_M_0)
-
-#define GPC_ANEG_ADV_ALL_M     (GPC_ANEG_3 | GPC_ANEG_2 | \
-                                                        GPC_ANEG_1 | GPC_ANEG_0)
-
-/* forced speed and duplex mode (don't mix with other ANEG bits) */
-#define GPC_FRC10MBIT_HALF     0
-#define GPC_FRC10MBIT_FULL     GPC_ANEG_0
-#define GPC_FRC100MBIT_HALF    GPC_ANEG_1
-#define GPC_FRC100MBIT_FULL    (GPC_ANEG_0 | GPC_ANEG_1)
-
-/* auto-negotiation with limited advertised speeds */
-/* mix only with master/slave settings (for copper) */
-#define GPC_ADV_1000_HALF      GPC_ANEG_2
-#define GPC_ADV_1000_FULL      GPC_ANEG_3
-#define GPC_ADV_ALL                    (GPC_ANEG_2 | GPC_ANEG_3)
-
-/* master/slave settings */
-/* only for copper with 1000 Mbps */
-#define GPC_FORCE_MASTER       0
-#define GPC_FORCE_SLAVE                GPC_ANEG_0
-#define GPC_PREF_MASTER                GPC_ANEG_1
-#define GPC_PREF_SLAVE         (GPC_ANEG_1 | GPC_ANEG_0)
-
-/*     GMAC_IRQ_SRC     8 bit  GMAC Interrupt Source Reg (YUKON only) */
-/*     GMAC_IRQ_MSK     8 bit  GMAC Interrupt Mask   Reg (YUKON only) */
-#define GM_IS_TX_CO_OV BIT_5           /* Transmit Counter Overflow IRQ */
-#define GM_IS_RX_CO_OV BIT_4           /* Receive Counter Overflow IRQ */
-#define GM_IS_TX_FF_UR BIT_3           /* Transmit FIFO Underrun */
-#define GM_IS_TX_COMPL BIT_2           /* Frame Transmission Complete */
-#define GM_IS_RX_FF_OR BIT_1           /* Receive FIFO Overrun */
-#define GM_IS_RX_COMPL BIT_0           /* Frame Reception Complete */
-
-#define GMAC_DEF_MSK   (GM_IS_TX_CO_OV | GM_IS_RX_CO_OV | \
-                                               GM_IS_TX_FF_UR)
-
-/*     GMAC_LINK_CTRL  16 bit  GMAC Link Control Reg (YUKON only) */
-                                               /* Bits 15.. 2: reserved */
-#define GMLC_RST_CLR   BIT_1S          /* Clear GMAC Link Reset */
-#define GMLC_RST_SET   BIT_0S          /* Set   GMAC Link Reset */
-
-
-/*     WOL_CTRL_STAT   16 bit  WOL Control/Status Reg */
-#define WOL_CTL_LINK_CHG_OCC                   BIT_15S
-#define WOL_CTL_MAGIC_PKT_OCC                  BIT_14S
-#define WOL_CTL_PATTERN_OCC                            BIT_13S
-
-#define WOL_CTL_CLEAR_RESULT                   BIT_12S
-
-#define WOL_CTL_ENA_PME_ON_LINK_CHG            BIT_11S
-#define WOL_CTL_DIS_PME_ON_LINK_CHG            BIT_10S
-#define WOL_CTL_ENA_PME_ON_MAGIC_PKT   BIT_9S
-#define WOL_CTL_DIS_PME_ON_MAGIC_PKT   BIT_8S
-#define WOL_CTL_ENA_PME_ON_PATTERN             BIT_7S
-#define WOL_CTL_DIS_PME_ON_PATTERN             BIT_6S
-
-#define WOL_CTL_ENA_LINK_CHG_UNIT              BIT_5S
-#define WOL_CTL_DIS_LINK_CHG_UNIT              BIT_4S
-#define WOL_CTL_ENA_MAGIC_PKT_UNIT             BIT_3S
-#define WOL_CTL_DIS_MAGIC_PKT_UNIT             BIT_2S
-#define WOL_CTL_ENA_PATTERN_UNIT               BIT_1S
-#define WOL_CTL_DIS_PATTERN_UNIT               BIT_0S
-
-#define WOL_CTL_DEFAULT                                \
-       (WOL_CTL_DIS_PME_ON_LINK_CHG |  \
-       WOL_CTL_DIS_PME_ON_PATTERN |    \
-       WOL_CTL_DIS_PME_ON_MAGIC_PKT |  \
-       WOL_CTL_DIS_LINK_CHG_UNIT |             \
-       WOL_CTL_DIS_PATTERN_UNIT |              \
-       WOL_CTL_DIS_MAGIC_PKT_UNIT)
-
-/*     WOL_MATCH_CTL    8 bit  WOL Match Control Reg */
-#define WOL_CTL_PATT_ENA(x)                            (BIT_0 << (x))
-
-#define SK_NUM_WOL_PATTERN             7
-#define SK_PATTERN_PER_WORD            4
-#define SK_BITMASK_PATTERN             7
-#define SK_POW_PATTERN_LENGTH  128
-
-#define WOL_LENGTH_MSK         0x7f
-#define WOL_LENGTH_SHIFT       8
-
-
-/* Receive and Transmit Descriptors ******************************************/
-
-/* Transmit Descriptor struct */
-typedef        struct s_HwTxd {
-       SK_U32 volatile TxCtrl; /* Transmit Buffer Control Field */
-       SK_U32  TxNext;                 /* Physical Address Pointer to the next TxD */
-       SK_U32  TxAdrLo;                /* Physical Tx Buffer Address lower dword */
-       SK_U32  TxAdrHi;                /* Physical Tx Buffer Address upper dword */
-       SK_U32  TxStat;                 /* Transmit Frame Status Word */
-#ifndef        SK_USE_REV_DESC
-       SK_U16  TxTcpOffs;              /* TCP Checksum Calculation Start Value */
-       SK_U16  TxRes1;                 /* 16 bit reserved field */
-       SK_U16  TxTcpWp;                /* TCP Checksum Write Position */
-       SK_U16  TxTcpSp;                /* TCP Checksum Calculation Start Position */
-#else  /* SK_USE_REV_DESC */
-       SK_U16  TxRes1;                 /* 16 bit reserved field */
-       SK_U16  TxTcpOffs;              /* TCP Checksum Calculation Start Value */
-       SK_U16  TxTcpSp;                /* TCP Checksum Calculation Start Position */
-       SK_U16  TxTcpWp;                /* TCP Checksum Write Position */
-#endif /* SK_USE_REV_DESC */
-       SK_U32  TxRes2;                 /* 32 bit reserved field */
-} SK_HWTXD;
-
-/* Receive Descriptor struct */
-typedef        struct s_HwRxd {
-       SK_U32 volatile RxCtrl; /* Receive Buffer Control Field */
-       SK_U32  RxNext;                 /* Physical Address Pointer to the next RxD */
-       SK_U32  RxAdrLo;                /* Physical Rx Buffer Address lower dword */
-       SK_U32  RxAdrHi;                /* Physical Rx Buffer Address upper dword */
-       SK_U32  RxStat;                 /* Receive Frame Status Word */
-       SK_U32  RxTiSt;                 /* Receive Time Stamp (from XMAC on GENESIS) */
-#ifndef        SK_USE_REV_DESC
-       SK_U16  RxTcpSum1;              /* TCP Checksum 1 */
-       SK_U16  RxTcpSum2;              /* TCP Checksum 2 */
-       SK_U16  RxTcpSp1;               /* TCP Checksum Calculation Start Position 1 */
-       SK_U16  RxTcpSp2;               /* TCP Checksum Calculation Start Position 2 */
-#else  /* SK_USE_REV_DESC */
-       SK_U16  RxTcpSum2;              /* TCP Checksum 2 */
-       SK_U16  RxTcpSum1;              /* TCP Checksum 1 */
-       SK_U16  RxTcpSp2;               /* TCP Checksum Calculation Start Position 2 */
-       SK_U16  RxTcpSp1;               /* TCP Checksum Calculation Start Position 1 */
-#endif /* SK_USE_REV_DESC */
-} SK_HWRXD;
-
-/*
- * Drivers which use the reverse descriptor feature (PCI_OUR_REG_2)
- * should set the define SK_USE_REV_DESC.
- * Structures are 'normaly' not endianess dependent. But in
- * this case the SK_U16 fields are bound to bit positions inside the
- * descriptor. RxTcpSum1 e.g. must start at bit 0 within the 6.th DWord.
- * The bit positions inside a DWord are of course endianess dependent and
- * swaps if the DWord is swapped by the hardware.
- */
-
-
-/* Descriptor Bit Definition */
-/*     TxCtrl          Transmit Buffer Control Field */
-/*     RxCtrl          Receive  Buffer Control Field */
-#define BMU_OWN                        BIT_31  /* OWN bit: 0=host/1=BMU */
-#define BMU_STF                        BIT_30  /* Start of Frame */
-#define BMU_EOF                        BIT_29  /* End of Frame */
-#define BMU_IRQ_EOB            BIT_28  /* Req "End of Buffer" IRQ */
-#define BMU_IRQ_EOF            BIT_27  /* Req "End of Frame" IRQ */
-/* TxCtrl specific bits */
-#define BMU_STFWD              BIT_26  /* (Tx) Store & Forward Frame */
-#define BMU_NO_FCS             BIT_25  /* (Tx) Disable MAC FCS (CRC) generation */
-#define BMU_SW                 BIT_24  /* (Tx) 1 bit res. for SW use */
-/* RxCtrl specific bits */
-#define BMU_DEV_0              BIT_26  /* (Rx) Transfer data to Dev0 */
-#define BMU_STAT_VAL   BIT_25  /* (Rx) Rx Status Valid */
-#define BMU_TIST_VAL   BIT_24  /* (Rx) Rx TimeStamp Valid */
-                                                               /* Bit 23..16:  BMU Check Opcodes */
-#define BMU_CHECK              (0x55L<<16)     /* Default BMU check */
-#define BMU_TCP_CHECK  (0x56L<<16)     /* Descr with TCP ext */
-#define BMU_UDP_CHECK  (0x57L<<16)     /* Descr with UDP ext (YUKON only) */
-#define BMU_BBC                        0xffffL /* Bit 15.. 0:  Buffer Byte Counter */
-
-/*     TxStat          Transmit Frame Status Word */
-/*     RxStat          Receive Frame Status Word */
-/*
- *Note: TxStat is reserved for ASIC loopback mode only
- *
- *     The Bits of the Status words are defined in xmac_ii.h
- *     (see XMR_FS bits)
- */
-
-/* macros ********************************************************************/
-
-/* Receive and Transmit Queues */
-#define Q_R1   0x0000          /* Receive Queue 1 */
-#define Q_R2   0x0080          /* Receive Queue 2 */
-#define Q_XS1  0x0200          /* Synchronous Transmit Queue 1 */
-#define Q_XA1  0x0280          /* Asynchronous Transmit Queue 1 */
-#define Q_XS2  0x0300          /* Synchronous Transmit Queue 2 */
-#define Q_XA2  0x0380          /* Asynchronous Transmit Queue 2 */
-
-/*
- *     Macro Q_ADDR()
- *
- *     Use this macro to access the Receive and Transmit Queue Registers.
- *
- * para:
- *     Queue   Queue to access.
- *                             Values: Q_R1, Q_R2, Q_XS1, Q_XA1, Q_XS2, and Q_XA2
- *     Offs    Queue register offset.
- *                             Values: Q_D, Q_DA_L ... Q_T2, Q_T3
- *
- * usage       SK_IN32(pAC, Q_ADDR(Q_R2, Q_BC), pVal)
- */
-#define Q_ADDR(Queue, Offs)    (B8_Q_REGS + (Queue) + (Offs))
-
-/*
- *     Macro RB_ADDR()
- *
- *     Use this macro to access the RAM Buffer Registers.
- *
- * para:
- *     Queue   Queue to access.
- *                             Values: Q_R1, Q_R2, Q_XS1, Q_XA1, Q_XS2, and Q_XA2
- *     Offs    Queue register offset.
- *                             Values: RB_START, RB_END ... RB_LEV, RB_CTRL
- *
- * usage       SK_IN32(pAC, RB_ADDR(Q_R2, RB_RP), pVal)
- */
-#define RB_ADDR(Queue, Offs)   (B16_RAM_REGS + (Queue) + (Offs))
-
-
-/* MAC Related Registers */
-#define MAC_1          0       /* belongs to the port near the slot */
-#define MAC_2          1       /* belongs to the port far away from the slot */
-
-/*
- *     Macro MR_ADDR()
- *
- *     Use this macro to access a MAC Related Registers inside the ASIC.
- *
- * para:
- *     Mac             MAC to access.
- *                             Values: MAC_1, MAC_2
- *     Offs    MAC register offset.
- *                             Values: RX_MFF_EA, RX_MFF_WP ... LNK_LED_REG,
- *                                             TX_MFF_EA, TX_MFF_WP ... TX_LED_TST
- *
- * usage       SK_IN32(pAC, MR_ADDR(MAC_1, TX_MFF_EA), pVal)
- */
-#define MR_ADDR(Mac, Offs)     (((Mac) << 7) + (Offs))
-
-#ifdef SK_LITTLE_ENDIAN
-#define XM_WORD_LO     0
-#define XM_WORD_HI     1
-#else  /* !SK_LITTLE_ENDIAN */
-#define XM_WORD_LO     1
-#define XM_WORD_HI     0
-#endif /* !SK_LITTLE_ENDIAN */
-
-
-/*
- * macros to access the XMAC (GENESIS only)
- *
- * XM_IN16(),          to read a 16 bit register (e.g. XM_MMU_CMD)
- * XM_OUT16(),         to write a 16 bit register (e.g. XM_MMU_CMD)
- * XM_IN32(),          to read a 32 bit register (e.g. XM_TX_EV_CNT)
- * XM_OUT32(),         to write a 32 bit register (e.g. XM_TX_EV_CNT)
- * XM_INADDR(),                to read a network address register (e.g. XM_SRC_CHK)
- * XM_OUTADDR(),       to write a network address register (e.g. XM_SRC_CHK)
- * XM_INHASH(),                to read the XM_HSM_CHK register
- * XM_OUTHASH()                to write the XM_HSM_CHK register
- *
- * para:
- *     Mac             XMAC to access          values: MAC_1 or MAC_2
- *     IoC             I/O context needed for SK I/O macros
- *     Reg             XMAC Register to read or write
- *     (p)Val  Value or pointer to the value which should be read or written
- *
- * usage:      XM_OUT16(IoC, MAC_1, XM_MMU_CMD, Value);
- */
-
-#define XMA(Mac, Reg)                                                                  \
-       ((BASE_XMAC_1 + (Mac) * (BASE_XMAC_2 - BASE_XMAC_1)) | ((Reg) << 1))
-
-#define XM_IN16(IoC, Mac, Reg, pVal)                                   \
-       SK_IN16((IoC), XMA((Mac), (Reg)), (pVal))
-
-#define XM_OUT16(IoC, Mac, Reg, Val)                                   \
-       SK_OUT16((IoC), XMA((Mac), (Reg)), (Val))
-
-#define XM_IN32(IoC, Mac, Reg, pVal) {                                 \
-       SK_IN16((IoC), XMA((Mac), (Reg)),                                       \
-               (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_LO]);         \
-       SK_IN16((IoC), XMA((Mac), (Reg+2)),                                     \
-               (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_HI]);         \
-}
-
-#define XM_OUT32(IoC, Mac, Reg, Val) {                                                                         \
-       SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16)((Val) & 0xffffL));                  \
-       SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16)(((Val) >> 16) & 0xffffL));\
-}
-
-/* Remember: we are always writing to / reading from LITTLE ENDIAN memory */
-
-#define XM_INADDR(IoC, Mac, Reg, pVal) {                               \
-       SK_U16  Word;                                                                           \
-       SK_U8   *pByte;                                                                         \
-       pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0];                         \
-       SK_IN16((IoC), XMA((Mac), (Reg)), &Word);                       \
-       pByte[0] = (SK_U8)(Word  & 0x00ff);                                     \
-       pByte[1] = (SK_U8)((Word >> 8) & 0x00ff);                       \
-       SK_IN16((IoC), XMA((Mac), (Reg+2)), &Word);                     \
-       pByte[2] = (SK_U8)(Word  & 0x00ff);                                     \
-       pByte[3] = (SK_U8)((Word >> 8) & 0x00ff);                       \
-       SK_IN16((IoC), XMA((Mac), (Reg+4)), &Word);                     \
-       pByte[4] = (SK_U8)(Word  & 0x00ff);                                     \
-       pByte[5] = (SK_U8)((Word >> 8) & 0x00ff);                       \
-}
-
-#define XM_OUTADDR(IoC, Mac, Reg, pVal) {                              \
-       SK_U8   SK_FAR *pByte;                                                          \
-       pByte = (SK_U8 SK_FAR *)&((SK_U8 SK_FAR *)(pVal))[0];   \
-       SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16)                     \
-               (((SK_U16)(pByte[0]) & 0x00ff) |                                \
-               (((SK_U16)(pByte[1]) << 8) & 0xff00)));                 \
-       SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16)           \
-               (((SK_U16)(pByte[2]) & 0x00ff) |                                \
-               (((SK_U16)(pByte[3]) << 8) & 0xff00)));                 \
-       SK_OUT16((IoC), XMA((Mac), (Reg+4)), (SK_U16)           \
-               (((SK_U16)(pByte[4]) & 0x00ff) |                                \
-               (((SK_U16)(pByte[5]) << 8) & 0xff00)));                 \
-}
-
-#define XM_INHASH(IoC, Mac, Reg, pVal) {                               \
-       SK_U16  Word;                                                                           \
-       SK_U8   SK_FAR *pByte;                                                          \
-       pByte = (SK_U8 SK_FAR *)&((SK_U8 SK_FAR *)(pVal))[0];   \
-       SK_IN16((IoC), XMA((Mac), (Reg)), &Word);                       \
-       pByte[0] = (SK_U8)(Word  & 0x00ff);                                     \
-       pByte[1] = (SK_U8)((Word >> 8) & 0x00ff);                       \
-       SK_IN16((IoC), XMA((Mac), (Reg+2)), &Word);                     \
-       pByte[2] = (SK_U8)(Word  & 0x00ff);                                     \
-       pByte[3] = (SK_U8)((Word >> 8) & 0x00ff);                       \
-       SK_IN16((IoC), XMA((Mac), (Reg+4)), &Word);                     \
-       pByte[4] = (SK_U8)(Word  & 0x00ff);                                     \
-       pByte[5] = (SK_U8)((Word >> 8) & 0x00ff);                       \
-       SK_IN16((IoC), XMA((Mac), (Reg+6)), &Word);                     \
-       pByte[6] = (SK_U8)(Word  & 0x00ff);                                     \
-       pByte[7] = (SK_U8)((Word >> 8) & 0x00ff);                       \
-}
-
-#define XM_OUTHASH(IoC, Mac, Reg, pVal) {                              \
-       SK_U8   SK_FAR *pByte;                                                          \
-       pByte = (SK_U8 SK_FAR *)&((SK_U8 SK_FAR *)(pVal))[0];   \
-       SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16)                     \
-               (((SK_U16)(pByte[0]) & 0x00ff)|                                 \
-               (((SK_U16)(pByte[1]) << 8) & 0xff00)));                 \
-       SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16)           \
-               (((SK_U16)(pByte[2]) & 0x00ff)|                                 \
-               (((SK_U16)(pByte[3]) << 8) & 0xff00)));                 \
-       SK_OUT16((IoC), XMA((Mac), (Reg+4)), (SK_U16)           \
-               (((SK_U16)(pByte[4]) & 0x00ff)|                                 \
-               (((SK_U16)(pByte[5]) << 8) & 0xff00)));                 \
-       SK_OUT16((IoC), XMA((Mac), (Reg+6)), (SK_U16)           \
-               (((SK_U16)(pByte[6]) & 0x00ff)|                                 \
-               (((SK_U16)(pByte[7]) << 8) & 0xff00)));                 \
-}
-
-/*
- * macros to access the GMAC (YUKON only)
- *
- * GM_IN16(),          to read  a 16 bit register (e.g. GM_GP_STAT)
- * GM_OUT16(),         to write a 16 bit register (e.g. GM_GP_CTRL)
- * GM_IN32(),          to read  a 32 bit register (e.g. GM_)
- * GM_OUT32(),         to write a 32 bit register (e.g. GM_)
- * GM_INADDR(),                to read  a network address register (e.g. GM_SRC_ADDR_1L)
- * GM_OUTADDR(),       to write a network address register (e.g. GM_SRC_ADDR_2L)
- * GM_INHASH(),                to read  the GM_MC_ADDR_H1 register
- * GM_OUTHASH()                to write the GM_MC_ADDR_H1 register
- *
- * para:
- *     Mac             GMAC to access          values: MAC_1 or MAC_2
- *     IoC             I/O context needed for SK I/O macros
- *     Reg             GMAC Register to read or write
- *     (p)Val  Value or pointer to the value which should be read or written
- *
- * usage:      GM_OUT16(IoC, MAC_1, GM_GP_CTRL, Value);
- */
-
-#define GMA(Mac, Reg)                                                                  \
-       ((BASE_GMAC_1 + (Mac) * (BASE_GMAC_2 - BASE_GMAC_1)) | (Reg))
-
-#define GM_IN16(IoC, Mac, Reg, pVal)                                   \
-       SK_IN16((IoC), GMA((Mac), (Reg)), (pVal))
-
-#define GM_OUT16(IoC, Mac, Reg, Val)                                   \
-       SK_OUT16((IoC), GMA((Mac), (Reg)), (Val))
-
-#define GM_IN32(IoC, Mac, Reg, pVal) {                                 \
-       SK_IN16((IoC), GMA((Mac), (Reg)),                                       \
-               (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_LO]);         \
-       SK_IN16((IoC), GMA((Mac), (Reg+4)),                                     \
-               (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_HI]);         \
-}
-
-#define GM_OUT32(IoC, Mac, Reg, Val) {                                                                         \
-       SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16)((Val) & 0xffffL));                  \
-       SK_OUT16((IoC), GMA((Mac), (Reg+4)), (SK_U16)(((Val) >> 16) & 0xffffL));\
-}
-
-#define GM_INADDR(IoC, Mac, Reg, pVal) {                               \
-       SK_U16  Word;                                                                           \
-       SK_U8   *pByte;                                                                         \
-       pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0];                         \
-       SK_IN16((IoC), GMA((Mac), (Reg)), &Word);                       \
-       pByte[0] = (SK_U8)(Word  & 0x00ff);                                     \
-       pByte[1] = (SK_U8)((Word >> 8) & 0x00ff);                       \
-       SK_IN16((IoC), GMA((Mac), (Reg+4)), &Word);                     \
-       pByte[2] = (SK_U8)(Word  & 0x00ff);                                     \
-       pByte[3] = (SK_U8)((Word >> 8) & 0x00ff);                       \
-       SK_IN16((IoC), GMA((Mac), (Reg+8)), &Word);                     \
-       pByte[4] = (SK_U8)(Word  & 0x00ff);                                     \
-       pByte[5] = (SK_U8)((Word >> 8) & 0x00ff);                       \
-}
-
-#define GM_OUTADDR(IoC, Mac, Reg, pVal) {                              \
-       SK_U8   SK_FAR *pByte;                                                          \
-       pByte = (SK_U8 SK_FAR *)&((SK_U8 SK_FAR *)(pVal))[0];   \
-       SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16)                     \
-               (((SK_U16)(pByte[0]) & 0x00ff) |                                \
-               (((SK_U16)(pByte[1]) << 8) & 0xff00)));                 \
-       SK_OUT16((IoC), GMA((Mac), (Reg+4)), (SK_U16)           \
-               (((SK_U16)(pByte[2]) & 0x00ff) |                                \
-               (((SK_U16)(pByte[3]) << 8) & 0xff00)));                 \
-       SK_OUT16((IoC), GMA((Mac), (Reg+8)), (SK_U16)           \
-               (((SK_U16)(pByte[4]) & 0x00ff) |                                \
-               (((SK_U16)(pByte[5]) << 8) & 0xff00)));                 \
-}
-
-#define GM_INHASH(IoC, Mac, Reg, pVal) {                               \
-       SK_U16  Word;                                                                           \
-       SK_U8   *pByte;                                                                         \
-       pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0];                         \
-       SK_IN16((IoC), GMA((Mac), (Reg)), &Word);                       \
-       pByte[0] = (SK_U8)(Word  & 0x00ff);                                     \
-       pByte[1] = (SK_U8)((Word >> 8) & 0x00ff);                       \
-       SK_IN16((IoC), GMA((Mac), (Reg+4)), &Word);                     \
-       pByte[2] = (SK_U8)(Word  & 0x00ff);                                     \
-       pByte[3] = (SK_U8)((Word >> 8) & 0x00ff);                       \
-       SK_IN16((IoC), GMA((Mac), (Reg+8)), &Word);                     \
-       pByte[4] = (SK_U8)(Word  & 0x00ff);                                     \
-       pByte[5] = (SK_U8)((Word >> 8) & 0x00ff);                       \
-       SK_IN16((IoC), GMA((Mac), (Reg+12)), &Word);            \
-       pByte[6] = (SK_U8)(Word  & 0x00ff);                                     \
-       pByte[7] = (SK_U8)((Word >> 8) & 0x00ff);                       \
-}
-
-#define GM_OUTHASH(IoC, Mac, Reg, pVal) {                              \
-       SK_U8   *pByte;                                                                         \
-       pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0];                         \
-       SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16)                     \
-               (((SK_U16)(pByte[0]) & 0x00ff)|                                 \
-               (((SK_U16)(pByte[1]) << 8) & 0xff00)));                 \
-       SK_OUT16((IoC), GMA((Mac), (Reg+4)), (SK_U16)           \
-               (((SK_U16)(pByte[2]) & 0x00ff)|                                 \
-               (((SK_U16)(pByte[3]) << 8) & 0xff00)));                 \
-       SK_OUT16((IoC), GMA((Mac), (Reg+8)), (SK_U16)           \
-               (((SK_U16)(pByte[4]) & 0x00ff)|                                 \
-               (((SK_U16)(pByte[5]) << 8) & 0xff00)));                 \
-       SK_OUT16((IoC), GMA((Mac), (Reg+12)), (SK_U16)          \
-               (((SK_U16)(pByte[6]) & 0x00ff)|                                 \
-               (((SK_U16)(pByte[7]) << 8) & 0xff00)));                 \
-}
-
-/*
- * Different MAC Types
- */
-#define SK_MAC_XMAC            0       /* Xaqti XMAC II */
-#define SK_MAC_GMAC            1       /* Marvell GMAC */
-
-/*
- * Different PHY Types
- */
-#define SK_PHY_XMAC                    0       /* integrated in XMAC II */
-#define SK_PHY_BCOM                    1       /* Broadcom BCM5400 */
-#define SK_PHY_LONE                    2       /* Level One LXT1000 */
-#define SK_PHY_NAT                     3       /* National DP83891 */
-#define SK_PHY_MARV_COPPER     4       /* Marvell 88E1011S */
-#define SK_PHY_MARV_FIBER      5       /* Marvell 88E1011S working on fiber */
-
-/*
- * PHY addresses (bits 12..8 of PHY address reg)
- */
-#define PHY_ADDR_XMAC  (0<<8)
-#define PHY_ADDR_BCOM  (1<<8)
-#define PHY_ADDR_LONE  (3<<8)
-#define PHY_ADDR_NAT   (0<<8)
-
-/* GPHY address (bits 15..11 of SMI control reg) */
-#define PHY_ADDR_MARV  0
-
-/*
- * macros to access the PHY
- *
- * PHY_READ()          read a 16 bit value from the PHY
- * PHY_WRITE()         write a 16 bit value to the PHY
- *
- * para:
- *     IoC             I/O context needed for SK I/O macros
- *     pPort   Pointer to port struct for PhyAddr
- *     Mac             XMAC to access          values: MAC_1 or MAC_2
- *     PhyReg  PHY Register to read or write
- *     (p)Val  Value or pointer to the value which should be read or
- *                     written.
- *
- * usage:      PHY_READ(IoC, pPort, MAC_1, PHY_CTRL, Value);
- * Warning: a PHY_READ on an uninitialized PHY (PHY still in reset) never
- *          comes back. This is checked in DEBUG mode.
- */
-#ifndef DEBUG
-#define PHY_READ(IoC, pPort, Mac, PhyReg, pVal) {                                              \
-       SK_U16 Mmu;                                                                                                             \
-                                                                                                                                               \
-       XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg) | (pPort)->PhyAddr);       \
-       XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal));                                                     \
-       if ((pPort)->PhyType != SK_PHY_XMAC) {                                                          \
-               do {                                                                                                                    \
-                       XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu);                                        \
-               } while ((Mmu & XM_MMU_PHY_RDY) == 0);                                                  \
-               XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal));                                             \
-       }                                                                                                                                       \
-}
-#else
-#define PHY_READ(IoC, pPort, Mac, PhyReg, pVal) {                                              \
-       SK_U16 Mmu;                                                                                                             \
-       int __i = 0;                                                                                                            \
-                                                                                                                                               \
-       XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg) | (pPort)->PhyAddr);       \
-       XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal));                                                     \
-       if ((pPort)->PhyType != SK_PHY_XMAC) {                                                          \
-               do {                                                                                                                    \
-                       XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu);                                        \
-                       __i++;                                                                                                          \
-                       if (__i > 100000) {                                                                                     \
-                               SK_DBG_PRINTF("*****************************\n");               \
-                               SK_DBG_PRINTF("PHY_READ on uninitialized PHY\n");               \
-                               SK_DBG_PRINTF("*****************************\n");               \
-                               break;                                                                                                  \
-                       }                                                                                                                       \
-               } while ((Mmu & XM_MMU_PHY_RDY) == 0);                                                  \
-               XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal));                                             \
-       }                                                                                                                                       \
-}
-#endif /* DEBUG */
-
-#define PHY_WRITE(IoC, pPort, Mac, PhyReg, Val) {                                              \
-       SK_U16 Mmu;                                                                                                                     \
-                                                                                                                                               \
-       if ((pPort)->PhyType != SK_PHY_XMAC) {                                                          \
-               do {                                                                                                                    \
-                       XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu);                                        \
-               } while ((Mmu & XM_MMU_PHY_BUSY) != 0);                                                 \
-       }                                                                                                                                       \
-       XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg) | (pPort)->PhyAddr);       \
-       XM_OUT16((IoC), (Mac), XM_PHY_DATA, (Val));                                                     \
-       if ((pPort)->PhyType != SK_PHY_XMAC) {                                                          \
-               do {                                                                                                                    \
-                       XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu);                                        \
-               } while ((Mmu & XM_MMU_PHY_BUSY) != 0);                                                 \
-       }                                                                                                                                       \
-}
-
-/*
- *     Macro PCI_C()
- *
- *     Use this macro to access PCI config register from the I/O space.
- *
- * para:
- *     Addr    PCI configuration register to access.
- *                     Values: PCI_VENDOR_ID ... PCI_VPD_ADR_REG,
- *
- * usage       SK_IN16(pAC, PCI_C(PCI_VENDOR_ID), pVal);
- */
-#define PCI_C(Addr)    (B7_CFG_SPC + (Addr))   /* PCI Config Space */
-
-/*
- *     Macro SK_HW_ADDR(Base, Addr)
- *
- *     Calculates the effective HW address
- *
- * para:
- *     Base    I/O or memory base address
- *     Addr    Address offset
- *
- * usage:      May be used in SK_INxx and SK_OUTxx macros
- *             #define SK_IN8(pAC, Addr, pVal) ...\
- *                     *pVal = (SK_U8)inp(SK_HW_ADDR(pAC->Hw.Iop, Addr)))
- */
-#ifdef SK_MEM_MAPPED_IO
-#define SK_HW_ADDR(Base, Addr) ((Base) + (Addr))
-#else  /* SK_MEM_MAPPED_IO */
-#define SK_HW_ADDR(Base, Addr) \
-                       ((Base) + (((Addr) & 0x7f) | (((Addr) >> 7 > 0) ? 0x80 : 0)))
-#endif /* SK_MEM_MAPPED_IO */
-
-#define SZ_LONG        (sizeof(SK_U32))
-
-/*
- *     Macro SK_HWAC_LINK_LED()
- *
- *     Use this macro to set the link LED mode.
- * para:
- *     pAC             Pointer to adapter context struct
- *     IoC             I/O context needed for SK I/O macros
- *  Port       Port number
- *     Mode    Mode to set for this LED
- */
-#define SK_HWAC_LINK_LED(pAC, IoC, Port, Mode) \
-       SK_OUT8(IoC, MR_ADDR(Port, LNK_LED_REG), Mode);
-
-
-/* typedefs *******************************************************************/
-
-
-/* function prototypes ********************************************************/
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __INC_SKGEHW_H */
diff --git a/drivers/net/sk98lin/h/skgehwt.h b/drivers/net/sk98lin/h/skgehwt.h
deleted file mode 100644 (file)
index e6b0016..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/******************************************************************************
- *
- * Name:       skhwt.h
- * Project:    Gigabit Ethernet Adapters, Event Scheduler Module
- * Version:    $Revision: 1.7 $
- * Date:       $Date: 2003/09/16 12:55:08 $
- * Purpose:    Defines for the hardware timer functions
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect GmbH.
- *     (C)Copyright 2002-2003 Marvell.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/*
- * SKGEHWT.H   contains all defines and types for the timer functions
- */
-
-#ifndef        _SKGEHWT_H_
-#define _SKGEHWT_H_
-
-/*
- * SK Hardware Timer
- * - needed wherever the HWT module is used
- * - use in Adapters context name pAC->Hwt
- */
-typedef        struct s_Hwt {
-       SK_U32          TStart; /* HWT start */
-       SK_U32          TStop;  /* HWT stop */
-       int             TActive;        /* HWT: flag : active/inactive */
-} SK_HWT;
-
-extern void SkHwtInit(SK_AC *pAC, SK_IOC Ioc);
-extern void SkHwtStart(SK_AC *pAC, SK_IOC Ioc, SK_U32 Time);
-extern void SkHwtStop(SK_AC *pAC, SK_IOC Ioc);
-extern SK_U32 SkHwtRead(SK_AC *pAC, SK_IOC Ioc);
-extern void SkHwtIsr(SK_AC *pAC, SK_IOC Ioc);
-#endif /* _SKGEHWT_H_ */
diff --git a/drivers/net/sk98lin/h/skgei2c.h b/drivers/net/sk98lin/h/skgei2c.h
deleted file mode 100644 (file)
index d9b6f6d..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-/******************************************************************************
- *
- * Name:       skgei2c.h
- * Project:    Gigabit Ethernet Adapters, TWSI-Module
- * Version:    $Revision: 1.25 $
- * Date:       $Date: 2003/10/20 09:06:05 $
- * Purpose:    Special defines for TWSI
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect.
- *     (C)Copyright 2002-2003 Marvell.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/*
- * SKGEI2C.H   contains all SK-98xx specific defines for the TWSI handling
- */
-
-#ifndef _INC_SKGEI2C_H_
-#define _INC_SKGEI2C_H_
-
-/*
- * Macros to access the B2_I2C_CTRL
- */
-#define SK_I2C_CTL(IoC, flag, dev, dev_size, reg, burst) \
-       SK_OUT32(IoC, B2_I2C_CTRL,\
-               (flag ? 0x80000000UL : 0x0L) | \
-               (((SK_U32)reg << 16) & I2C_ADDR) | \
-               (((SK_U32)dev << 9) & I2C_DEV_SEL) | \
-               (dev_size & I2C_DEV_SIZE) | \
-               ((burst << 4) & I2C_BURST_LEN))
-
-#define SK_I2C_STOP(IoC) {                             \
-       SK_U32  I2cCtrl;                                \
-       SK_IN32(IoC, B2_I2C_CTRL, &I2cCtrl);            \
-       SK_OUT32(IoC, B2_I2C_CTRL, I2cCtrl | I2C_STOP); \
-}
-
-#define SK_I2C_GET_CTL(IoC, pI2cCtrl)  SK_IN32(IoC, B2_I2C_CTRL, pI2cCtrl)
-
-/*
- * Macros to access the TWSI SW Registers
- */
-#define SK_I2C_SET_BIT(IoC, SetBits) {                 \
-       SK_U8   OrgBits;                                \
-       SK_IN8(IoC, B2_I2C_SW, &OrgBits);               \
-       SK_OUT8(IoC, B2_I2C_SW, OrgBits | (SK_U8)(SetBits));    \
-}
-
-#define SK_I2C_CLR_BIT(IoC, ClrBits) {                 \
-       SK_U8   OrgBits;                                \
-       SK_IN8(IoC, B2_I2C_SW, &OrgBits);               \
-       SK_OUT8(IoC, B2_I2C_SW, OrgBits & ~((SK_U8)(ClrBits))); \
-}
-
-#define SK_I2C_GET_SW(IoC, pI2cSw)     SK_IN8(IoC, B2_I2C_SW, pI2cSw)
-
-/*
- * define the possible sensor states
- */
-#define        SK_SEN_IDLE             0       /* Idle: sensor not read */
-#define        SK_SEN_VALUE    1       /* Value Read cycle */
-#define        SK_SEN_VALEXT   2       /* Extended Value Read cycle */
-
-/*
- * Conversion factor to convert read Voltage sensor to milli Volt
- * Conversion factor to convert read Temperature sensor to 10th degree Celsius
- */
-#define        SK_LM80_VT_LSB          22      /* 22mV LSB resolution */
-#define        SK_LM80_TEMP_LSB        10      /* 1 degree LSB resolution */
-#define        SK_LM80_TEMPEXT_LSB      5      /* 0.5 degree LSB resolution for ext. val. */
-
-/*
- * formula: counter = (22500*60)/(rpm * divisor * pulses/2)
- * assuming: 6500rpm, 4 pulses, divisor 1
- */
-#define SK_LM80_FAN_FAKTOR     ((22500L*60)/(1*2))
-
-/*
- * Define sensor management data
- * Maximum is reached on Genesis copper dual port and Yukon-64
- * Board specific maximum is in pAC->I2c.MaxSens
- */
-#define        SK_MAX_SENSORS  8       /* maximal no. of installed sensors */
-#define        SK_MIN_SENSORS  5       /* minimal no. of installed sensors */
-
-/*
- * To watch the state machine (SM) use the timer in two ways
- * instead of one as hitherto
- */
-#define        SK_TIMER_WATCH_SM               0       /* Watch the SM to finish in a spec. time */
-#define        SK_TIMER_NEW_GAUGING    1       /* Start a new gauging when timer expires */
-
-/*
- * Defines for the individual thresholds
- */
-
-/* Temperature sensor */
-#define        SK_SEN_TEMP_HIGH_ERR    800     /* Temperature High Err  Threshold */
-#define        SK_SEN_TEMP_HIGH_WARN   700     /* Temperature High Warn Threshold */
-#define        SK_SEN_TEMP_LOW_WARN    100     /* Temperature Low  Warn Threshold */
-#define        SK_SEN_TEMP_LOW_ERR               0     /* Temperature Low  Err  Threshold */
-
-/* VCC which should be 5 V */
-#define        SK_SEN_PCI_5V_HIGH_ERR          5588    /* Voltage PCI High Err  Threshold */
-#define        SK_SEN_PCI_5V_HIGH_WARN         5346    /* Voltage PCI High Warn Threshold */
-#define        SK_SEN_PCI_5V_LOW_WARN          4664    /* Voltage PCI Low  Warn Threshold */
-#define        SK_SEN_PCI_5V_LOW_ERR           4422    /* Voltage PCI Low  Err  Threshold */
-
-/*
- * VIO may be 5 V or 3.3 V. Initialization takes two parts:
- * 1. Initialize lowest lower limit and highest higher limit.
- * 2. After the first value is read correct the upper or the lower limit to
- *    the appropriate C constant.
- *
- * Warning limits are +-5% of the exepected voltage.
- * Error limits are +-10% of the expected voltage.
- */
-
-/* Bug fix AF: 16.Aug.2001: Correct the init base of LM80 sensor */
-
-#define        SK_SEN_PCI_IO_5V_HIGH_ERR       5566    /* + 10% V PCI-IO High Err Threshold */
-#define        SK_SEN_PCI_IO_5V_HIGH_WARN      5324    /* +  5% V PCI-IO High Warn Threshold */
-                                       /*              5000    mVolt */
-#define        SK_SEN_PCI_IO_5V_LOW_WARN       4686    /* -  5% V PCI-IO Low Warn Threshold */
-#define        SK_SEN_PCI_IO_5V_LOW_ERR        4444    /* - 10% V PCI-IO Low Err Threshold */
-
-#define        SK_SEN_PCI_IO_RANGE_LIMITER     4000    /* 4000 mV range delimiter */
-
-/* correction values for the second pass */
-#define        SK_SEN_PCI_IO_3V3_HIGH_ERR      3850    /* + 15% V PCI-IO High Err Threshold */
-#define        SK_SEN_PCI_IO_3V3_HIGH_WARN     3674    /* + 10% V PCI-IO High Warn Threshold */
-                                       /*              3300    mVolt */
-#define        SK_SEN_PCI_IO_3V3_LOW_WARN      2926    /* - 10% V PCI-IO Low Warn Threshold */
-#define        SK_SEN_PCI_IO_3V3_LOW_ERR       2772    /* - 15% V PCI-IO Low Err  Threshold */
-
-/*
- * VDD voltage
- */
-#define        SK_SEN_VDD_HIGH_ERR             3630    /* Voltage ASIC High Err  Threshold */
-#define        SK_SEN_VDD_HIGH_WARN    3476    /* Voltage ASIC High Warn Threshold */
-#define        SK_SEN_VDD_LOW_WARN             3146    /* Voltage ASIC Low  Warn Threshold */
-#define        SK_SEN_VDD_LOW_ERR              2970    /* Voltage ASIC Low  Err  Threshold */
-
-/*
- * PHY PLL 3V3 voltage
- */
-#define        SK_SEN_PLL_3V3_HIGH_ERR         3630    /* Voltage PMA High Err  Threshold */
-#define        SK_SEN_PLL_3V3_HIGH_WARN        3476    /* Voltage PMA High Warn Threshold */
-#define        SK_SEN_PLL_3V3_LOW_WARN         3146    /* Voltage PMA Low  Warn Threshold */
-#define        SK_SEN_PLL_3V3_LOW_ERR          2970    /* Voltage PMA Low  Err  Threshold */
-
-/*
- * VAUX (YUKON only)
- */
-#define        SK_SEN_VAUX_3V3_HIGH_ERR        3630    /* Voltage VAUX High Err Threshold */
-#define        SK_SEN_VAUX_3V3_HIGH_WARN       3476    /* Voltage VAUX High Warn Threshold */
-#define        SK_SEN_VAUX_3V3_LOW_WARN        3146    /* Voltage VAUX Low Warn Threshold */
-#define        SK_SEN_VAUX_3V3_LOW_ERR         2970    /* Voltage VAUX Low Err Threshold */
-#define        SK_SEN_VAUX_0V_WARN_ERR            0    /* if VAUX not present */
-#define        SK_SEN_VAUX_RANGE_LIMITER       1000    /* 1000 mV range delimiter */
-
-/*
- * PHY 2V5 voltage
- */
-#define        SK_SEN_PHY_2V5_HIGH_ERR         2750    /* Voltage PHY High Err Threshold */
-#define        SK_SEN_PHY_2V5_HIGH_WARN        2640    /* Voltage PHY High Warn Threshold */
-#define        SK_SEN_PHY_2V5_LOW_WARN         2376    /* Voltage PHY Low Warn Threshold */
-#define        SK_SEN_PHY_2V5_LOW_ERR          2222    /* Voltage PHY Low Err Threshold */
-
-/*
- * ASIC Core 1V5 voltage (YUKON only)
- */
-#define        SK_SEN_CORE_1V5_HIGH_ERR        1650    /* Voltage ASIC Core High Err Threshold */
-#define        SK_SEN_CORE_1V5_HIGH_WARN       1575    /* Voltage ASIC Core High Warn Threshold */
-#define        SK_SEN_CORE_1V5_LOW_WARN        1425    /* Voltage ASIC Core Low Warn Threshold */
-#define        SK_SEN_CORE_1V5_LOW_ERR         1350    /* Voltage ASIC Core Low Err Threshold */
-
-/*
- * FAN 1 speed
- */
-/* assuming: 6500rpm +-15%, 4 pulses,
- * warning at: 80 %
- * error at:   70 %
- * no upper limit
- */
-#define        SK_SEN_FAN_HIGH_ERR             20000   /* FAN Speed High Err Threshold */
-#define        SK_SEN_FAN_HIGH_WARN    20000   /* FAN Speed High Warn Threshold */
-#define        SK_SEN_FAN_LOW_WARN              5200   /* FAN Speed Low Warn Threshold */
-#define        SK_SEN_FAN_LOW_ERR               4550   /* FAN Speed Low Err Threshold */
-
-/*
- * Some Voltages need dynamic thresholds
- */
-#define        SK_SEN_DYN_INIT_NONE             0  /* No dynamic init of thresholds */
-#define        SK_SEN_DYN_INIT_PCI_IO          10  /* Init PCI-IO with new thresholds */
-#define        SK_SEN_DYN_INIT_VAUX            11  /* Init VAUX with new thresholds */
-
-extern int SkLm80ReadSensor(SK_AC *pAC, SK_IOC IoC, SK_SENSOR *pSen);
-#endif /* n_INC_SKGEI2C_H */
diff --git a/drivers/net/sk98lin/h/skgeinit.h b/drivers/net/sk98lin/h/skgeinit.h
deleted file mode 100644 (file)
index 143e635..0000000
+++ /dev/null
@@ -1,797 +0,0 @@
-/******************************************************************************
- *
- * Name:       skgeinit.h
- * Project:    Gigabit Ethernet Adapters, Common Modules
- * Version:    $Revision: 1.83 $
- * Date:       $Date: 2003/09/16 14:07:37 $
- * Purpose:    Structures and prototypes for the GE Init Module
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect.
- *     (C)Copyright 2002-2003 Marvell.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-#ifndef __INC_SKGEINIT_H_
-#define __INC_SKGEINIT_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/* defines ********************************************************************/
-
-#define SK_TEST_VAL            0x11335577UL
-
-/* modifying Link LED behaviour (used with SkGeLinkLED()) */
-#define SK_LNK_OFF             LED_OFF
-#define SK_LNK_ON              (LED_ON | LED_BLK_OFF | LED_SYNC_OFF)
-#define SK_LNK_BLINK   (LED_ON | LED_BLK_ON  | LED_SYNC_ON)
-#define SK_LNK_PERM            (LED_ON | LED_BLK_OFF | LED_SYNC_ON)
-#define SK_LNK_TST             (LED_ON | LED_BLK_ON  | LED_SYNC_OFF)
-
-/* parameter 'Mode' when calling SK_HWAC_LINK_LED() */
-#define SK_LED_OFF             LED_OFF
-#define SK_LED_ACTIVE  (LED_ON | LED_BLK_OFF | LED_SYNC_OFF)
-#define SK_LED_STANDBY (LED_ON | LED_BLK_ON  | LED_SYNC_OFF)
-
-/* addressing LED Registers in SkGeXmitLED() */
-#define XMIT_LED_INI   0
-#define XMIT_LED_CNT   (RX_LED_VAL - RX_LED_INI)
-#define XMIT_LED_CTRL  (RX_LED_CTRL- RX_LED_INI)
-#define XMIT_LED_TST   (RX_LED_TST - RX_LED_INI)
-
-/* parameter 'Mode' when calling SkGeXmitLED() */
-#define SK_LED_DIS     0
-#define SK_LED_ENA     1
-#define SK_LED_TST     2
-
-/* Counter and Timer constants, for a host clock of 62.5 MHz */
-#define SK_XMIT_DUR            0x002faf08UL    /*  50 ms */
-#define SK_BLK_DUR             0x01dcd650UL    /* 500 ms */
-
-#define SK_DPOLL_DEF   0x00ee6b28UL    /* 250 ms at 62.5 MHz */
-
-#define SK_DPOLL_MAX   0x00ffffffUL    /* 268 ms at 62.5 MHz */
-                                                                               /* 215 ms at 78.12 MHz */
-
-#define SK_FACT_62             100                     /* is given in percent */
-#define SK_FACT_53              85         /* on GENESIS:      53.12 MHz */
-#define SK_FACT_78             125                     /* on YUKON:    78.12 MHz */
-
-/* Timeout values */
-#define SK_MAC_TO_53   72                      /* MAC arbiter timeout */
-#define SK_PKT_TO_53   0x2000          /* Packet arbiter timeout */
-#define SK_PKT_TO_MAX  0xffff          /* Maximum value */
-#define SK_RI_TO_53            36                      /* RAM interface timeout */
-
-#define SK_PHY_ACC_TO  600000          /* PHY access timeout */
-
-/* RAM Buffer High Pause Threshold values */
-#define SK_RB_ULPP             ( 8 * 1024)     /* Upper Level in kB/8 */
-#define SK_RB_LLPP_S   (10 * 1024)     /* Lower Level for small Queues */
-#define SK_RB_LLPP_B   (16 * 1024)     /* Lower Level for big Queues */
-
-#ifndef SK_BMU_RX_WM
-#define SK_BMU_RX_WM   0x600           /* BMU Rx Watermark */
-#endif
-#ifndef SK_BMU_TX_WM
-#define SK_BMU_TX_WM   0x600           /* BMU Tx Watermark */
-#endif
-
-/* XMAC II Rx High Watermark */
-#define SK_XM_RX_HI_WM 0x05aa          /* 1450 */
-
-/* XMAC II Tx Threshold */
-#define SK_XM_THR_REDL 0x01fb          /* .. for redundant link usage */
-#define SK_XM_THR_SL   0x01fb          /* .. for single link adapters */
-#define SK_XM_THR_MULL 0x01fb          /* .. for multiple link usage */
-#define SK_XM_THR_JUMBO        0x03fc          /* .. for jumbo frame usage */
-
-/* values for GIPortUsage */
-#define SK_RED_LINK            1               /* redundant link usage */
-#define SK_MUL_LINK            2               /* multiple link usage */
-#define SK_JUMBO_LINK  3               /* driver uses jumbo frames */
-
-/* Minimum RAM Buffer Rx Queue Size */
-#define SK_MIN_RXQ_SIZE        16              /* 16 kB */
-
-/* Minimum RAM Buffer Tx Queue Size */
-#define SK_MIN_TXQ_SIZE        16              /* 16 kB */
-
-/* Queue Size units */
-#define QZ_UNITS               0x7
-#define QZ_STEP                        8
-
-/* Percentage of queue size from whole memory */
-/* 80 % for receive */
-#define RAM_QUOTA_RX   80L
-/* 0% for sync transfer */
-#define        RAM_QUOTA_SYNC  0L
-/* the rest (20%) is taken for async transfer */
-
-/* Get the rounded queue size in Bytes in 8k steps */
-#define ROUND_QUEUE_SIZE(SizeInBytes)                                  \
-       ((((unsigned long) (SizeInBytes) + (QZ_STEP*1024L)-1) / 1024) & \
-       ~(QZ_STEP-1))
-
-/* Get the rounded queue size in KBytes in 8k steps */
-#define ROUND_QUEUE_SIZE_KB(Kilobytes) \
-       ROUND_QUEUE_SIZE((Kilobytes) * 1024L)
-
-/* Types of RAM Buffer Queues */
-#define SK_RX_SRAM_Q   1       /* small receive queue */
-#define SK_RX_BRAM_Q   2       /* big receive queue */
-#define SK_TX_RAM_Q            3       /* small or big transmit queue */
-
-/* parameter 'Dir' when calling SkGeStopPort() */
-#define SK_STOP_TX     1       /* Stops the transmit path, resets the XMAC */
-#define SK_STOP_RX     2       /* Stops the receive path */
-#define SK_STOP_ALL    3       /* Stops Rx and Tx path, resets the XMAC */
-
-/* parameter 'RstMode' when calling SkGeStopPort() */
-#define SK_SOFT_RST    1       /* perform a software reset */
-#define SK_HARD_RST    2       /* perform a hardware reset */
-
-/* Init Levels */
-#define SK_INIT_DATA   0       /* Init level 0: init data structures */
-#define SK_INIT_IO             1       /* Init level 1: init with IOs */
-#define SK_INIT_RUN            2       /* Init level 2: init for run time */
-
-/* Link Mode Parameter */
-#define SK_LMODE_HALF          1       /* Half Duplex Mode */
-#define SK_LMODE_FULL          2       /* Full Duplex Mode */
-#define SK_LMODE_AUTOHALF      3       /* AutoHalf Duplex Mode */
-#define SK_LMODE_AUTOFULL      4       /* AutoFull Duplex Mode */
-#define SK_LMODE_AUTOBOTH      5       /* AutoBoth Duplex Mode */
-#define SK_LMODE_AUTOSENSE     6       /* configured mode auto sensing */
-#define SK_LMODE_INDETERMINATED        7       /* indeterminated */
-
-/* Auto-negotiation timeout in 100ms granularity */
-#define SK_AND_MAX_TO          6       /* Wait 600 msec before link comes up */
-
-/* Auto-negotiation error codes */
-#define SK_AND_OK                      0       /* no error */
-#define SK_AND_OTHER           1       /* other error than below */
-#define SK_AND_DUP_CAP         2       /* Duplex capabilities error */
-
-
-/* Link Speed Capabilities */
-#define SK_LSPEED_CAP_AUTO                     (1<<0)  /* Automatic resolution */
-#define SK_LSPEED_CAP_10MBPS           (1<<1)  /* 10 Mbps */
-#define SK_LSPEED_CAP_100MBPS          (1<<2)  /* 100 Mbps */
-#define SK_LSPEED_CAP_1000MBPS         (1<<3)  /* 1000 Mbps */
-#define SK_LSPEED_CAP_INDETERMINATED (1<<4) /* indeterminated */
-
-/* Link Speed Parameter */
-#define SK_LSPEED_AUTO                         1       /* Automatic resolution */
-#define SK_LSPEED_10MBPS                       2       /* 10 Mbps */
-#define SK_LSPEED_100MBPS                      3       /* 100 Mbps */
-#define SK_LSPEED_1000MBPS                     4       /* 1000 Mbps */
-#define SK_LSPEED_INDETERMINATED       5       /* indeterminated */
-
-/* Link Speed Current State */
-#define SK_LSPEED_STAT_UNKNOWN         1
-#define SK_LSPEED_STAT_10MBPS          2
-#define SK_LSPEED_STAT_100MBPS                 3
-#define SK_LSPEED_STAT_1000MBPS                4
-#define SK_LSPEED_STAT_INDETERMINATED 5
-
-
-/* Link Capability Parameter */
-#define SK_LMODE_CAP_HALF              (1<<0)  /* Half Duplex Mode */
-#define SK_LMODE_CAP_FULL              (1<<1)  /* Full Duplex Mode */
-#define SK_LMODE_CAP_AUTOHALF  (1<<2)  /* AutoHalf Duplex Mode */
-#define SK_LMODE_CAP_AUTOFULL  (1<<3)  /* AutoFull Duplex Mode */
-#define SK_LMODE_CAP_INDETERMINATED (1<<4) /* indeterminated */
-
-/* Link Mode Current State */
-#define SK_LMODE_STAT_UNKNOWN  1       /* Unknown Duplex Mode */
-#define SK_LMODE_STAT_HALF             2       /* Half Duplex Mode */
-#define SK_LMODE_STAT_FULL             3       /* Full Duplex Mode */
-#define SK_LMODE_STAT_AUTOHALF 4       /* Half Duplex Mode obtained by Auto-Neg */
-#define SK_LMODE_STAT_AUTOFULL 5       /* Full Duplex Mode obtained by Auto-Neg */
-#define SK_LMODE_STAT_INDETERMINATED 6 /* indeterminated */
-
-/* Flow Control Mode Parameter (and capabilities) */
-#define SK_FLOW_MODE_NONE              1       /* No Flow-Control */
-#define SK_FLOW_MODE_LOC_SEND  2       /* Local station sends PAUSE */
-#define SK_FLOW_MODE_SYMMETRIC 3       /* Both stations may send PAUSE */
-#define SK_FLOW_MODE_SYM_OR_REM        4       /* Both stations may send PAUSE or
-                                        * just the remote station may send PAUSE
-                                        */
-#define SK_FLOW_MODE_INDETERMINATED 5  /* indeterminated */
-
-/* Flow Control Status Parameter */
-#define SK_FLOW_STAT_NONE              1       /* No Flow Control */
-#define SK_FLOW_STAT_REM_SEND  2       /* Remote Station sends PAUSE */
-#define SK_FLOW_STAT_LOC_SEND  3       /* Local station sends PAUSE */
-#define SK_FLOW_STAT_SYMMETRIC 4       /* Both station may send PAUSE */
-#define SK_FLOW_STAT_INDETERMINATED 5  /* indeterminated */
-
-/* Master/Slave Mode Capabilities */
-#define SK_MS_CAP_AUTO         (1<<0)  /* Automatic resolution */
-#define SK_MS_CAP_MASTER       (1<<1)  /* This station is master */
-#define SK_MS_CAP_SLAVE                (1<<2)  /* This station is slave */
-#define SK_MS_CAP_INDETERMINATED (1<<3)        /* indeterminated */
-
-/* Set Master/Slave Mode Parameter (and capabilities) */
-#define SK_MS_MODE_AUTO                1       /* Automatic resolution */
-#define SK_MS_MODE_MASTER      2       /* This station is master */
-#define SK_MS_MODE_SLAVE       3       /* This station is slave */
-#define SK_MS_MODE_INDETERMINATED 4    /* indeterminated */
-
-/* Master/Slave Status Parameter */
-#define SK_MS_STAT_UNSET       1       /* The M/S status is not set */
-#define SK_MS_STAT_MASTER      2       /* This station is master */
-#define SK_MS_STAT_SLAVE       3       /* This station is slave */
-#define SK_MS_STAT_FAULT       4       /* M/S resolution failed */
-#define SK_MS_STAT_INDETERMINATED 5    /* indeterminated */
-
-/* parameter 'Mode' when calling SkXmSetRxCmd() */
-#define SK_STRIP_FCS_ON                (1<<0)  /* Enable  FCS stripping of Rx frames */
-#define SK_STRIP_FCS_OFF       (1<<1)  /* Disable FCS stripping of Rx frames */
-#define SK_STRIP_PAD_ON                (1<<2)  /* Enable  pad byte stripping of Rx fr */
-#define SK_STRIP_PAD_OFF       (1<<3)  /* Disable pad byte stripping of Rx fr */
-#define SK_LENERR_OK_ON                (1<<4)  /* Don't chk fr for in range len error */
-#define SK_LENERR_OK_OFF       (1<<5)  /* Check frames for in range len error */
-#define SK_BIG_PK_OK_ON                (1<<6)  /* Don't set Rx Error bit for big frames */
-#define SK_BIG_PK_OK_OFF       (1<<7)  /* Set Rx Error bit for big frames */
-#define SK_SELF_RX_ON          (1<<8)  /* Enable  Rx of own packets */
-#define SK_SELF_RX_OFF         (1<<9)  /* Disable Rx of own packets */
-
-/* parameter 'Para' when calling SkMacSetRxTxEn() */
-#define SK_MAC_LOOPB_ON                (1<<0)  /* Enable  MAC Loopback Mode */
-#define SK_MAC_LOOPB_OFF       (1<<1)  /* Disable MAC Loopback Mode */
-#define SK_PHY_LOOPB_ON                (1<<2)  /* Enable  PHY Loopback Mode */
-#define SK_PHY_LOOPB_OFF       (1<<3)  /* Disable PHY Loopback Mode */
-#define SK_PHY_FULLD_ON                (1<<4)  /* Enable  GMII Full Duplex */
-#define SK_PHY_FULLD_OFF       (1<<5)  /* Disable GMII Full Duplex */
-
-/* States of PState */
-#define SK_PRT_RESET   0       /* the port is reset */
-#define SK_PRT_STOP            1       /* the port is stopped (similar to SW reset) */
-#define SK_PRT_INIT            2       /* the port is initialized */
-#define SK_PRT_RUN             3       /* the port has an active link */
-
-/* PHY power down modes */
-#define PHY_PM_OPERATIONAL_MODE                0       /* PHY operational mode */
-#define PHY_PM_DEEP_SLEEP                      1       /* coma mode --> minimal power */
-#define PHY_PM_IEEE_POWER_DOWN         2       /* IEEE 22.2.4.1.5 compl. power down */
-#define PHY_PM_ENERGY_DETECT           3       /* energy detect */
-#define PHY_PM_ENERGY_DETECT_PLUS      4       /* energy detect plus */
-
-/* Default receive frame limit for Workaround of XMAC Errata */
-#define SK_DEF_RX_WA_LIM       SK_CONSTU64(100)
-
-/* values for GILedBlinkCtrl (LED Blink Control) */
-#define SK_ACT_LED_BLINK       (1<<0)  /* Active LED blinking */
-#define SK_DUP_LED_NORMAL      (1<<1)  /* Duplex LED normal */
-#define SK_LED_LINK100_ON      (1<<2)  /* Link 100M LED on */
-
-/* Link Partner Status */
-#define SK_LIPA_UNKNOWN        0       /* Link partner is in unknown state */
-#define SK_LIPA_MANUAL 1       /* Link partner is in detected manual state */
-#define SK_LIPA_AUTO   2       /* Link partner is in auto-negotiation state */
-
-/* Maximum Restarts before restart is ignored (3Com WA) */
-#define SK_MAX_LRESTART        3       /* Max. 3 times the link is restarted */
-
-/* Max. Auto-neg. timeouts before link detection in sense mode is reset */
-#define SK_MAX_ANEG_TO 10      /* Max. 10 times the sense mode is reset */
-
-/* structures *****************************************************************/
-
-/*
- * MAC specific functions
- */
-typedef struct s_GeMacFunc {
-       int  (*pFnMacUpdateStats)(SK_AC *pAC, SK_IOC IoC, unsigned int Port);
-       int  (*pFnMacStatistic)(SK_AC *pAC, SK_IOC IoC, unsigned int Port,
-                                                       SK_U16 StatAddr, SK_U32 SK_FAR *pVal);
-       int  (*pFnMacResetCounter)(SK_AC *pAC, SK_IOC IoC, unsigned int Port);
-       int  (*pFnMacOverflow)(SK_AC *pAC, SK_IOC IoC, unsigned int Port,
-                                                  SK_U16 IStatus, SK_U64 SK_FAR *pVal);
-} SK_GEMACFUNC;
-
-/*
- * Port Structure
- */
-typedef        struct s_GePort {
-#ifndef SK_DIAG
-       SK_TIMER        PWaTimer;       /* Workaround Timer */
-       SK_TIMER        HalfDupChkTimer;
-#endif /* SK_DIAG */
-       SK_U32  PPrevShorts;    /* Previous Short Counter checking */
-       SK_U32  PPrevFcs;               /* Previous FCS Error Counter checking */
-       SK_U64  PPrevRx;                /* Previous RxOk Counter checking */
-       SK_U64  PRxLim;                 /* Previous RxOk Counter checking */
-       SK_U64  LastOctets;             /* For half duplex hang check */
-       int             PLinkResCt;             /* Link Restart Counter */
-       int             PAutoNegTimeOut;/* Auto-negotiation timeout current value */
-       int             PAutoNegTOCt;   /* Auto-negotiation Timeout Counter */
-       int             PRxQSize;               /* Port Rx Queue Size in kB */
-       int             PXSQSize;               /* Port Synchronous  Transmit Queue Size in kB */
-       int             PXAQSize;               /* Port Asynchronous Transmit Queue Size in kB */
-       SK_U32  PRxQRamStart;   /* Receive Queue RAM Buffer Start Address */
-       SK_U32  PRxQRamEnd;             /* Receive Queue RAM Buffer End Address */
-       SK_U32  PXsQRamStart;   /* Sync Tx Queue RAM Buffer Start Address */
-       SK_U32  PXsQRamEnd;             /* Sync Tx Queue RAM Buffer End Address */
-       SK_U32  PXaQRamStart;   /* Async Tx Queue RAM Buffer Start Address */
-       SK_U32  PXaQRamEnd;             /* Async Tx Queue RAM Buffer End Address */
-       SK_U32  PRxOverCnt;             /* Receive Overflow Counter */
-       int             PRxQOff;                /* Rx Queue Address Offset */
-       int             PXsQOff;                /* Synchronous Tx Queue Address Offset */
-       int             PXaQOff;                /* Asynchronous Tx Queue Address Offset */
-       int             PhyType;                /* PHY used on this port */
-       int             PState;                 /* Port status (reset, stop, init, run) */
-       SK_U16  PhyId1;                 /* PHY Id1 on this port */
-       SK_U16  PhyAddr;                /* MDIO/MDC PHY address */
-       SK_U16  PIsave;                 /* Saved Interrupt status word */
-       SK_U16  PSsave;                 /* Saved PHY status word */
-       SK_U16  PGmANegAdv;             /* Saved GPhy AutoNegAdvertisment register */
-       SK_BOOL PHWLinkUp;              /* The hardware Link is up (wiring) */
-       SK_BOOL PLinkBroken;    /* Is Link broken ? */
-       SK_BOOL PCheckPar;              /* Do we check for parity errors ? */
-       SK_BOOL HalfDupTimerActive;
-       SK_U8   PLinkCap;               /* Link Capabilities */
-       SK_U8   PLinkModeConf;  /* Link Mode configured */
-       SK_U8   PLinkMode;              /* Link Mode currently used */
-       SK_U8   PLinkModeStatus;/* Link Mode Status */
-       SK_U8   PLinkSpeedCap;  /* Link Speed Capabilities(10/100/1000 Mbps) */
-       SK_U8   PLinkSpeed;             /* configured Link Speed (10/100/1000 Mbps) */
-       SK_U8   PLinkSpeedUsed; /* current Link Speed (10/100/1000 Mbps) */
-       SK_U8   PFlowCtrlCap;   /* Flow Control Capabilities */
-       SK_U8   PFlowCtrlMode;  /* Flow Control Mode */
-       SK_U8   PFlowCtrlStatus;/* Flow Control Status */
-       SK_U8   PMSCap;                 /* Master/Slave Capabilities */
-       SK_U8   PMSMode;                /* Master/Slave Mode */
-       SK_U8   PMSStatus;              /* Master/Slave Status */
-       SK_BOOL PAutoNegFail;   /* Auto-negotiation fail flag */
-       SK_U8   PLipaAutoNeg;   /* Auto-negotiation possible with Link Partner */
-       SK_U8   PCableLen;              /* Cable Length */
-       SK_U8   PMdiPairLen[4]; /* MDI[0..3] Pair Length */
-       SK_U8   PMdiPairSts[4]; /* MDI[0..3] Pair Diagnostic Status */
-       SK_U8   PPhyPowerState; /* PHY current power state */
-       int             PMacColThres;   /* MAC Collision Threshold */
-       int             PMacJamLen;             /* MAC Jam length */
-       int             PMacJamIpgVal;  /* MAC Jam IPG */
-       int             PMacJamIpgData; /* MAC IPG Jam to Data */
-       int             PMacIpgData;    /* MAC Data IPG */
-       SK_BOOL PMacLimit4;             /* reset collision counter and backoff algorithm */
-} SK_GEPORT;
-
-/*
- * Gigabit Ethernet Initialization Struct
- * (has to be included in the adapter context)
- */
-typedef        struct s_GeInit {
-       int                     GIChipId;               /* Chip Identification Number */
-       int                     GIChipRev;              /* Chip Revision Number */
-       SK_U8           GIPciHwRev;             /* PCI HW Revision Number */
-       SK_BOOL         GIGenesis;              /* Genesis adapter ? */
-       SK_BOOL         GIYukon;                /* YUKON-A1/Bx chip */
-       SK_BOOL         GIYukonLite;    /* YUKON-Lite chip */
-       SK_BOOL         GICopperType;   /* Copper Type adapter ? */
-       SK_BOOL         GIPciSlot64;    /* 64-bit PCI Slot */
-       SK_BOOL         GIPciClock66;   /* 66 MHz PCI Clock */
-       SK_BOOL         GIVauxAvail;    /* VAUX available (YUKON) */
-       SK_BOOL         GIYukon32Bit;   /* 32-Bit YUKON adapter */
-       SK_U16          GILedBlinkCtrl; /* LED Blink Control */
-       int                     GIMacsFound;    /* Number of MACs found on this adapter */
-       int                     GIMacType;              /* MAC Type used on this adapter */
-       int                     GIHstClkFact;   /* Host Clock Factor (62.5 / HstClk * 100) */
-       int                     GIPortUsage;    /* Driver Port Usage */
-       int                     GILevel;                /* Initialization Level completed */
-       int                     GIRamSize;              /* The RAM size of the adapter in kB */
-       int                     GIWolOffs;              /* WOL Register Offset (HW-Bug in Rev. A) */
-       SK_U32          GIRamOffs;              /* RAM Address Offset for addr calculation */
-       SK_U32          GIPollTimerVal; /* Descr. Poll Timer Init Val (HstClk ticks) */
-       SK_U32          GIValIrqMask;   /* Value for Interrupt Mask */
-       SK_U32          GITimeStampCnt; /* Time Stamp High Counter (YUKON only) */
-       SK_GEPORT       GP[SK_MAX_MACS];/* Port Dependent Information */
-       SK_GEMACFUNC GIFunc;            /* MAC depedent functions */
-} SK_GEINIT;
-
-/*
- * Error numbers and messages for skxmac2.c and skgeinit.c
- */
-#define SKERR_HWI_E001         (SK_ERRBASE_HWINIT)
-#define SKERR_HWI_E001MSG      "SkXmClrExactAddr() has got illegal parameters"
-#define SKERR_HWI_E002         (SKERR_HWI_E001+1)
-#define SKERR_HWI_E002MSG      "SkGeInit(): Level 1 call missing"
-#define SKERR_HWI_E003         (SKERR_HWI_E002+1)
-#define SKERR_HWI_E003MSG      "SkGeInit() called with illegal init Level"
-#define SKERR_HWI_E004         (SKERR_HWI_E003+1)
-#define SKERR_HWI_E004MSG      "SkGeInitPort(): Queue Size illegal configured"
-#define SKERR_HWI_E005         (SKERR_HWI_E004+1)
-#define SKERR_HWI_E005MSG      "SkGeInitPort(): cannot init running ports"
-#define SKERR_HWI_E006         (SKERR_HWI_E005+1)
-#define SKERR_HWI_E006MSG      "SkGeMacInit(): PState does not match HW state"
-#define SKERR_HWI_E007         (SKERR_HWI_E006+1)
-#define SKERR_HWI_E007MSG      "SkXmInitDupMd() called with invalid Dup Mode"
-#define SKERR_HWI_E008         (SKERR_HWI_E007+1)
-#define SKERR_HWI_E008MSG      "SkXmSetRxCmd() called with invalid Mode"
-#define SKERR_HWI_E009         (SKERR_HWI_E008+1)
-#define SKERR_HWI_E009MSG      "SkGeCfgSync() called although PXSQSize zero"
-#define SKERR_HWI_E010         (SKERR_HWI_E009+1)
-#define SKERR_HWI_E010MSG      "SkGeCfgSync() called with invalid parameters"
-#define SKERR_HWI_E011         (SKERR_HWI_E010+1)
-#define SKERR_HWI_E011MSG      "SkGeInitPort(): Receive Queue Size too small"
-#define SKERR_HWI_E012         (SKERR_HWI_E011+1)
-#define SKERR_HWI_E012MSG      "SkGeInitPort(): invalid Queue Size specified"
-#define SKERR_HWI_E013         (SKERR_HWI_E012+1)
-#define SKERR_HWI_E013MSG      "SkGeInitPort(): cfg changed for running queue"
-#define SKERR_HWI_E014         (SKERR_HWI_E013+1)
-#define SKERR_HWI_E014MSG      "SkGeInitPort(): unknown GIPortUsage specified"
-#define SKERR_HWI_E015         (SKERR_HWI_E014+1)
-#define SKERR_HWI_E015MSG      "Illegal Link mode parameter"
-#define SKERR_HWI_E016         (SKERR_HWI_E015+1)
-#define SKERR_HWI_E016MSG      "Illegal Flow control mode parameter"
-#define SKERR_HWI_E017         (SKERR_HWI_E016+1)
-#define SKERR_HWI_E017MSG      "Illegal value specified for GIPollTimerVal"
-#define SKERR_HWI_E018         (SKERR_HWI_E017+1)
-#define SKERR_HWI_E018MSG      "FATAL: SkGeStopPort() does not terminate (Tx)"
-#define SKERR_HWI_E019         (SKERR_HWI_E018+1)
-#define SKERR_HWI_E019MSG      "Illegal Speed parameter"
-#define SKERR_HWI_E020         (SKERR_HWI_E019+1)
-#define SKERR_HWI_E020MSG      "Illegal Master/Slave parameter"
-#define SKERR_HWI_E021         (SKERR_HWI_E020+1)
-#define        SKERR_HWI_E021MSG       "MacUpdateStats(): cannot update statistic counter"
-#define        SKERR_HWI_E022          (SKERR_HWI_E021+1)
-#define        SKERR_HWI_E022MSG       "MacStatistic(): illegal statistic base address"
-#define SKERR_HWI_E023         (SKERR_HWI_E022+1)
-#define SKERR_HWI_E023MSG      "SkGeInitPort(): Transmit Queue Size too small"
-#define SKERR_HWI_E024         (SKERR_HWI_E023+1)
-#define SKERR_HWI_E024MSG      "FATAL: SkGeStopPort() does not terminate (Rx)"
-#define SKERR_HWI_E025         (SKERR_HWI_E024+1)
-#define SKERR_HWI_E025MSG      ""
-
-/* function prototypes ********************************************************/
-
-#ifndef        SK_KR_PROTO
-
-/*
- * public functions in skgeinit.c
- */
-extern void    SkGePollTxD(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       SK_BOOL PollTxD);
-
-extern void    SkGeYellowLED(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             State);
-
-extern int     SkGeCfgSync(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       SK_U32  IntTime,
-       SK_U32  LimCount,
-       int             SyncMode);
-
-extern void    SkGeLoadLnkSyncCnt(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       SK_U32  CntVal);
-
-extern void    SkGeStopPort(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       int             Dir,
-       int             RstMode);
-
-extern int     SkGeInit(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Level);
-
-extern void    SkGeDeInit(
-       SK_AC   *pAC,
-       SK_IOC  IoC);
-
-extern int     SkGeInitPort(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port);
-
-extern void    SkGeXmitLED(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Led,
-       int             Mode);
-
-extern int     SkGeInitAssignRamToQueues(
-       SK_AC   *pAC,
-       int             ActivePort,
-       SK_BOOL DualNet);
-
-/*
- * public functions in skxmac2.c
- */
-extern void SkMacRxTxDisable(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port);
-
-extern void    SkMacSoftRst(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port);
-
-extern void    SkMacHardRst(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port);
-
-extern void    SkXmInitMac(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port);
-
-extern void    SkGmInitMac(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port);
-
-extern void SkMacInitPhy(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       SK_BOOL DoLoop);
-
-extern void SkMacIrqDisable(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port);
-
-extern void    SkMacFlushTxFifo(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port);
-
-extern void    SkMacIrq(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port);
-
-extern int     SkMacAutoNegDone(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port);
-
-extern void    SkMacAutoNegLipaPhy(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       SK_U16  IStatus);
-
-extern int  SkMacRxTxEnable(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port);
-
-extern void    SkMacPromiscMode(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       SK_BOOL Enable);
-
-extern void    SkMacHashing(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       SK_BOOL Enable);
-
-extern void    SkXmPhyRead(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       int             Addr,
-       SK_U16  SK_FAR *pVal);
-
-extern void    SkXmPhyWrite(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       int             Addr,
-       SK_U16  Val);
-
-extern void    SkGmPhyRead(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       int             Addr,
-       SK_U16  SK_FAR *pVal);
-
-extern void    SkGmPhyWrite(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       int             Addr,
-       SK_U16  Val);
-
-extern void    SkXmClrExactAddr(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       int             StartNum,
-       int             StopNum);
-
-extern void    SkXmAutoNegLipaXmac(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       SK_U16  IStatus);
-
-extern int SkXmUpdateStats(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       unsigned int Port);
-
-extern int SkGmUpdateStats(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       unsigned int Port);
-
-extern int SkXmMacStatistic(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       unsigned int Port,
-       SK_U16  StatAddr,
-       SK_U32  SK_FAR *pVal);
-
-extern int SkGmMacStatistic(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       unsigned int Port,
-       SK_U16  StatAddr,
-       SK_U32  SK_FAR *pVal);
-
-extern int SkXmResetCounter(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       unsigned int Port);
-
-extern int SkGmResetCounter(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       unsigned int Port);
-
-extern int SkXmOverflowStatus(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       unsigned int Port,
-       SK_U16  IStatus,
-       SK_U64  SK_FAR *pStatus);
-
-extern int SkGmOverflowStatus(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       unsigned int Port,
-       SK_U16  MacStatus,
-       SK_U64  SK_FAR *pStatus);
-
-extern int SkGmCableDiagStatus(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       SK_BOOL StartTest);
-
-#ifdef SK_DIAG
-extern void    SkGePhyRead(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       int             Addr,
-       SK_U16  *pVal);
-
-extern void    SkGePhyWrite(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       int             Addr,
-       SK_U16  Val);
-
-extern void    SkMacSetRxCmd(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       int             Mode);
-extern void    SkMacCrcGener(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       SK_BOOL Enable);
-extern void    SkMacTimeStamp(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       SK_BOOL Enable);
-extern void    SkXmSendCont(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Port,
-       SK_BOOL Enable);
-#endif /* SK_DIAG */
-
-#else  /* SK_KR_PROTO */
-
-/*
- * public functions in skgeinit.c
- */
-extern void    SkGePollTxD();
-extern void    SkGeYellowLED();
-extern int     SkGeCfgSync();
-extern void    SkGeLoadLnkSyncCnt();
-extern void    SkGeStopPort();
-extern int     SkGeInit();
-extern void    SkGeDeInit();
-extern int     SkGeInitPort();
-extern void    SkGeXmitLED();
-extern int     SkGeInitAssignRamToQueues();
-
-/*
- * public functions in skxmac2.c
- */
-extern void SkMacRxTxDisable();
-extern void    SkMacSoftRst();
-extern void    SkMacHardRst();
-extern void SkMacInitPhy();
-extern int  SkMacRxTxEnable();
-extern void SkMacPromiscMode();
-extern void SkMacHashing();
-extern void SkMacIrqDisable();
-extern void    SkMacFlushTxFifo();
-extern void    SkMacIrq();
-extern int     SkMacAutoNegDone();
-extern void    SkMacAutoNegLipaPhy();
-extern void    SkXmInitMac();
-extern void    SkXmPhyRead();
-extern void    SkXmPhyWrite();
-extern void    SkGmInitMac();
-extern void    SkGmPhyRead();
-extern void    SkGmPhyWrite();
-extern void    SkXmClrExactAddr();
-extern void    SkXmAutoNegLipaXmac();
-extern int     SkXmUpdateStats();
-extern int     SkGmUpdateStats();
-extern int     SkXmMacStatistic();
-extern int     SkGmMacStatistic();
-extern int     SkXmResetCounter();
-extern int     SkGmResetCounter();
-extern int     SkXmOverflowStatus();
-extern int     SkGmOverflowStatus();
-extern int     SkGmCableDiagStatus();
-
-#ifdef SK_DIAG
-extern void    SkGePhyRead();
-extern void    SkGePhyWrite();
-extern void    SkMacSetRxCmd();
-extern void    SkMacCrcGener();
-extern void    SkMacTimeStamp();
-extern void    SkXmSendCont();
-#endif /* SK_DIAG */
-
-#endif /* SK_KR_PROTO */
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __INC_SKGEINIT_H_ */
diff --git a/drivers/net/sk98lin/h/skgepnm2.h b/drivers/net/sk98lin/h/skgepnm2.h
deleted file mode 100644 (file)
index ddd304f..0000000
+++ /dev/null
@@ -1,334 +0,0 @@
-/*****************************************************************************
- *
- * Name:       skgepnm2.h
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.36 $
- * Date:       $Date: 2003/05/23 12:45:13 $
- * Purpose:    Defines for Private Network Management Interface
- *
- ****************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect GmbH.
- *     (C)Copyright 2002-2003 Marvell.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-#ifndef _SKGEPNM2_H_
-#define _SKGEPNM2_H_
-
-/*
- * General definitions
- */
-#define SK_PNMI_CHIPSET_XMAC   1       /* XMAC11800FP */
-#define SK_PNMI_CHIPSET_YUKON  2       /* YUKON */
-
-#define        SK_PNMI_BUS_PCI         1       /* PCI bus*/
-
-/*
- * Actions
- */
-#define SK_PNMI_ACT_IDLE               1
-#define SK_PNMI_ACT_RESET              2
-#define SK_PNMI_ACT_SELFTEST   3
-#define SK_PNMI_ACT_RESETCNT   4
-
-/*
- * VPD releated defines
- */
-
-#define SK_PNMI_VPD_RW         1
-#define SK_PNMI_VPD_RO         2
-
-#define SK_PNMI_VPD_OK                 0
-#define SK_PNMI_VPD_NOTFOUND   1
-#define SK_PNMI_VPD_CUT                        2
-#define SK_PNMI_VPD_TIMEOUT            3
-#define SK_PNMI_VPD_FULL               4
-#define SK_PNMI_VPD_NOWRITE            5
-#define SK_PNMI_VPD_FATAL              6
-
-#define SK_PNMI_VPD_IGNORE     0
-#define SK_PNMI_VPD_CREATE     1
-#define SK_PNMI_VPD_DELETE     2
-
-
-/*
- * RLMT related defines
- */
-#define SK_PNMI_DEF_RLMT_CHG_THRES     240     /* 4 changes per minute */
-
-
-/*
- * VCT internal status values
- */
-#define SK_PNMI_VCT_PENDING    32
-#define SK_PNMI_VCT_TEST_DONE  64
-#define SK_PNMI_VCT_LINK       128
-
-/*
- * Internal table definitions
- */
-#define SK_PNMI_GET            0
-#define SK_PNMI_PRESET 1
-#define SK_PNMI_SET            2
-
-#define SK_PNMI_RO             0
-#define SK_PNMI_RW             1
-#define SK_PNMI_WO             2
-
-typedef struct s_OidTabEntry {
-       SK_U32                  Id;
-       SK_U32                  InstanceNo;
-       unsigned int    StructSize;
-       unsigned int    Offset;
-       int                             Access;
-       int                             (* Func)(SK_AC *pAc, SK_IOC pIo, int action,
-                                                        SK_U32 Id, char* pBuf, unsigned int* pLen,
-                                                        SK_U32 Instance, unsigned int TableIndex,
-                                                        SK_U32 NetNumber);
-       SK_U16                  Param;
-} SK_PNMI_TAB_ENTRY;
-
-
-/*
- * Trap lengths
- */
-#define SK_PNMI_TRAP_SIMPLE_LEN                        17
-#define SK_PNMI_TRAP_SENSOR_LEN_BASE   46
-#define SK_PNMI_TRAP_RLMT_CHANGE_LEN   23
-#define SK_PNMI_TRAP_RLMT_PORT_LEN             23
-
-/*
- * Number of MAC types supported
- */
-#define SK_PNMI_MAC_TYPES      (SK_MAC_GMAC + 1)
-
-/*
- * MAC statistic data list (overall set for MAC types used)
- */
-enum SK_MACSTATS {
-       SK_PNMI_HTX                             = 0,
-       SK_PNMI_HTX_OCTET,
-       SK_PNMI_HTX_OCTETHIGH   = SK_PNMI_HTX_OCTET,
-       SK_PNMI_HTX_OCTETLOW,
-       SK_PNMI_HTX_BROADCAST,
-       SK_PNMI_HTX_MULTICAST,
-       SK_PNMI_HTX_UNICAST,
-       SK_PNMI_HTX_BURST,
-       SK_PNMI_HTX_PMACC,
-       SK_PNMI_HTX_MACC,
-       SK_PNMI_HTX_COL,
-       SK_PNMI_HTX_SINGLE_COL,
-       SK_PNMI_HTX_MULTI_COL,
-       SK_PNMI_HTX_EXCESS_COL,
-       SK_PNMI_HTX_LATE_COL,
-       SK_PNMI_HTX_DEFFERAL,
-       SK_PNMI_HTX_EXCESS_DEF,
-       SK_PNMI_HTX_UNDERRUN,
-       SK_PNMI_HTX_CARRIER,
-       SK_PNMI_HTX_UTILUNDER,
-       SK_PNMI_HTX_UTILOVER,
-       SK_PNMI_HTX_64,
-       SK_PNMI_HTX_127,
-       SK_PNMI_HTX_255,
-       SK_PNMI_HTX_511,
-       SK_PNMI_HTX_1023,
-       SK_PNMI_HTX_MAX,
-       SK_PNMI_HTX_LONGFRAMES,
-       SK_PNMI_HTX_SYNC,
-       SK_PNMI_HTX_SYNC_OCTET,
-       SK_PNMI_HTX_RESERVED,
-       
-       SK_PNMI_HRX,
-       SK_PNMI_HRX_OCTET,
-       SK_PNMI_HRX_OCTETHIGH   = SK_PNMI_HRX_OCTET,
-       SK_PNMI_HRX_OCTETLOW,
-       SK_PNMI_HRX_BADOCTET,
-       SK_PNMI_HRX_BADOCTETHIGH = SK_PNMI_HRX_BADOCTET,
-       SK_PNMI_HRX_BADOCTETLOW,
-       SK_PNMI_HRX_BROADCAST,
-       SK_PNMI_HRX_MULTICAST,
-       SK_PNMI_HRX_UNICAST,
-       SK_PNMI_HRX_PMACC,
-       SK_PNMI_HRX_MACC,
-       SK_PNMI_HRX_PMACC_ERR,
-       SK_PNMI_HRX_MACC_UNKWN,
-       SK_PNMI_HRX_BURST,
-       SK_PNMI_HRX_MISSED,
-       SK_PNMI_HRX_FRAMING,
-       SK_PNMI_HRX_UNDERSIZE,
-       SK_PNMI_HRX_OVERFLOW,
-       SK_PNMI_HRX_JABBER,
-       SK_PNMI_HRX_CARRIER,
-       SK_PNMI_HRX_IRLENGTH,
-       SK_PNMI_HRX_SYMBOL,
-       SK_PNMI_HRX_SHORTS,
-       SK_PNMI_HRX_RUNT,
-       SK_PNMI_HRX_TOO_LONG,
-       SK_PNMI_HRX_FCS,
-       SK_PNMI_HRX_CEXT,
-       SK_PNMI_HRX_UTILUNDER,
-       SK_PNMI_HRX_UTILOVER,
-       SK_PNMI_HRX_64,
-       SK_PNMI_HRX_127,
-       SK_PNMI_HRX_255,
-       SK_PNMI_HRX_511,
-       SK_PNMI_HRX_1023,
-       SK_PNMI_HRX_MAX,
-       SK_PNMI_HRX_LONGFRAMES,
-       
-       SK_PNMI_HRX_RESERVED,
-       
-       SK_PNMI_MAX_IDX         /* NOTE: Ensure SK_PNMI_CNT_NO is set to this value */
-};
-
-/*
- * MAC specific data
- */
-typedef struct s_PnmiStatAddr {
-       SK_U16          Reg;            /* MAC register containing the value */
-       SK_BOOL         GetOffset;      /* TRUE: Offset managed by PNMI (call GetStatVal())*/
-} SK_PNMI_STATADDR;
-
-
-/*
- * SK_PNMI_STRUCT_DATA copy offset evaluation macros
- */
-#define SK_PNMI_OFF(e)         ((SK_U32)(SK_UPTR)&(((SK_PNMI_STRUCT_DATA *)0)->e))
-#define SK_PNMI_MAI_OFF(e)     ((SK_U32)(SK_UPTR)&(((SK_PNMI_STRUCT_DATA *)0)->e))
-#define SK_PNMI_VPD_OFF(e)     ((SK_U32)(SK_UPTR)&(((SK_PNMI_VPD *)0)->e))
-#define SK_PNMI_SEN_OFF(e)     ((SK_U32)(SK_UPTR)&(((SK_PNMI_SENSOR *)0)->e))
-#define SK_PNMI_CHK_OFF(e)     ((SK_U32)(SK_UPTR)&(((SK_PNMI_CHECKSUM *)0)->e))
-#define SK_PNMI_STA_OFF(e)     ((SK_U32)(SK_UPTR)&(((SK_PNMI_STAT *)0)->e))
-#define SK_PNMI_CNF_OFF(e)     ((SK_U32)(SK_UPTR)&(((SK_PNMI_CONF *)0)->e))
-#define SK_PNMI_RLM_OFF(e)     ((SK_U32)(SK_UPTR)&(((SK_PNMI_RLMT *)0)->e))
-#define SK_PNMI_MON_OFF(e)     ((SK_U32)(SK_UPTR)&(((SK_PNMI_RLMT_MONITOR *)0)->e))
-#define SK_PNMI_TRP_OFF(e)     ((SK_U32)(SK_UPTR)&(((SK_PNMI_TRAP *)0)->e))
-
-#define SK_PNMI_SET_STAT(b,s,o)        {SK_U32 Val32; char *pVal; \
-                                       Val32 = (s); \
-                                       pVal = (char *)(b) + ((SK_U32)(SK_UPTR) \
-                                               &(((SK_PNMI_STRUCT_DATA *)0)-> \
-                                               ReturnStatus.ErrorStatus)); \
-                                       SK_PNMI_STORE_U32(pVal, Val32); \
-                                       Val32 = (o); \
-                                       pVal = (char *)(b) + ((SK_U32)(SK_UPTR) \
-                                               &(((SK_PNMI_STRUCT_DATA *)0)-> \
-                                               ReturnStatus.ErrorOffset)); \
-                                       SK_PNMI_STORE_U32(pVal, Val32);}
-
-/*
- * Time macros
- */
-#ifndef SK_PNMI_HUNDREDS_SEC
-#if SK_TICKS_PER_SEC == 100
-#define SK_PNMI_HUNDREDS_SEC(t)        (t)
-#else
-#define SK_PNMI_HUNDREDS_SEC(t)        (((t) * 100) / (SK_TICKS_PER_SEC))
-#endif /* !SK_TICKS_PER_SEC */
-#endif /* !SK_PNMI_HUNDREDS_SEC */
-
-/*
- * Macros to work around alignment problems
- */
-#ifndef SK_PNMI_STORE_U16
-#define SK_PNMI_STORE_U16(p,v) {*(char *)(p) = *((char *)&(v)); \
-                                       *((char *)(p) + 1) = \
-                                               *(((char *)&(v)) + 1);}
-#endif
-
-#ifndef SK_PNMI_STORE_U32
-#define SK_PNMI_STORE_U32(p,v) {*(char *)(p) = *((char *)&(v)); \
-                                       *((char *)(p) + 1) = \
-                                               *(((char *)&(v)) + 1); \
-                                       *((char *)(p) + 2) = \
-                                               *(((char *)&(v)) + 2); \
-                                       *((char *)(p) + 3) = \
-                                               *(((char *)&(v)) + 3);}
-#endif
-
-#ifndef SK_PNMI_STORE_U64
-#define SK_PNMI_STORE_U64(p,v) {*(char *)(p) = *((char *)&(v)); \
-                                       *((char *)(p) + 1) = \
-                                               *(((char *)&(v)) + 1); \
-                                       *((char *)(p) + 2) = \
-                                               *(((char *)&(v)) + 2); \
-                                       *((char *)(p) + 3) = \
-                                               *(((char *)&(v)) + 3); \
-                                       *((char *)(p) + 4) = \
-                                               *(((char *)&(v)) + 4); \
-                                       *((char *)(p) + 5) = \
-                                               *(((char *)&(v)) + 5); \
-                                       *((char *)(p) + 6) = \
-                                               *(((char *)&(v)) + 6); \
-                                       *((char *)(p) + 7) = \
-                                               *(((char *)&(v)) + 7);}
-#endif
-
-#ifndef SK_PNMI_READ_U16
-#define SK_PNMI_READ_U16(p,v)  {*((char *)&(v)) = *(char *)(p); \
-                                       *(((char *)&(v)) + 1) = \
-                                               *((char *)(p) + 1);}
-#endif
-
-#ifndef SK_PNMI_READ_U32
-#define SK_PNMI_READ_U32(p,v)  {*((char *)&(v)) = *(char *)(p); \
-                                       *(((char *)&(v)) + 1) = \
-                                               *((char *)(p) + 1); \
-                                       *(((char *)&(v)) + 2) = \
-                                               *((char *)(p) + 2); \
-                                       *(((char *)&(v)) + 3) = \
-                                               *((char *)(p) + 3);}
-#endif
-
-#ifndef SK_PNMI_READ_U64
-#define SK_PNMI_READ_U64(p,v)  {*((char *)&(v)) = *(char *)(p); \
-                                       *(((char *)&(v)) + 1) = \
-                                               *((char *)(p) + 1); \
-                                       *(((char *)&(v)) + 2) = \
-                                               *((char *)(p) + 2); \
-                                       *(((char *)&(v)) + 3) = \
-                                               *((char *)(p) + 3); \
-                                       *(((char *)&(v)) + 4) = \
-                                               *((char *)(p) + 4); \
-                                       *(((char *)&(v)) + 5) = \
-                                               *((char *)(p) + 5); \
-                                       *(((char *)&(v)) + 6) = \
-                                               *((char *)(p) + 6); \
-                                       *(((char *)&(v)) + 7) = \
-                                               *((char *)(p) + 7);}
-#endif
-
-/*
- * Macros for Debug
- */
-#ifdef DEBUG
-
-#define SK_PNMI_CHECKFLAGS(vSt)        {if (pAC->Pnmi.MacUpdatedFlag > 0 || \
-                                       pAC->Pnmi.RlmtUpdatedFlag > 0 || \
-                                       pAC->Pnmi.SirqUpdatedFlag > 0) { \
-                                               SK_DBG_MSG(pAC, \
-                                               SK_DBGMOD_PNMI, \
-                                               SK_DBGCAT_CTRL, \
-                                               ("PNMI: ERR: %s MacUFlag=%d, RlmtUFlag=%d, SirqUFlag=%d\n", \
-                                               vSt, \
-                                               pAC->Pnmi.MacUpdatedFlag, \
-                                               pAC->Pnmi.RlmtUpdatedFlag, \
-                                               pAC->Pnmi.SirqUpdatedFlag))}}
-
-#else  /* !DEBUG */
-
-#define SK_PNMI_CHECKFLAGS(vSt)        /* Nothing */
-
-#endif /* !DEBUG */
-
-#endif /* _SKGEPNM2_H_ */
diff --git a/drivers/net/sk98lin/h/skgepnmi.h b/drivers/net/sk98lin/h/skgepnmi.h
deleted file mode 100644 (file)
index 1ed214c..0000000
+++ /dev/null
@@ -1,962 +0,0 @@
-/*****************************************************************************
- *
- * Name:       skgepnmi.h
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.62 $
- * Date:       $Date: 2003/08/15 12:31:52 $
- * Purpose:    Defines for Private Network Management Interface
- *
- ****************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect GmbH.
- *     (C)Copyright 2002-2003 Marvell.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-#ifndef _SKGEPNMI_H_
-#define _SKGEPNMI_H_
-
-/*
- * Include dependencies
- */
-#include "h/sktypes.h"
-#include "h/skerror.h"
-#include "h/sktimer.h"
-#include "h/ski2c.h"
-#include "h/skaddr.h"
-#include "h/skrlmt.h"
-#include "h/skvpd.h"
-
-/*
- * Management Database Version
- */
-#define SK_PNMI_MDB_VERSION            0x00030001      /* 3.1 */
-
-
-/*
- * Event definitions
- */
-#define SK_PNMI_EVT_SIRQ_OVERFLOW              1       /* Counter overflow */
-#define SK_PNMI_EVT_SEN_WAR_LOW                        2       /* Lower war thres exceeded */
-#define SK_PNMI_EVT_SEN_WAR_UPP                        3       /* Upper war thres exceeded */
-#define SK_PNMI_EVT_SEN_ERR_LOW                        4       /* Lower err thres exceeded */
-#define SK_PNMI_EVT_SEN_ERR_UPP                        5       /* Upper err thres exceeded */
-#define SK_PNMI_EVT_CHG_EST_TIMER              6       /* Timer event for RLMT Chg */
-#define SK_PNMI_EVT_UTILIZATION_TIMER  7       /* Timer event for Utiliza. */
-#define SK_PNMI_EVT_CLEAR_COUNTER              8       /* Clear statistic counters */
-#define SK_PNMI_EVT_XMAC_RESET                 9       /* XMAC will be reset */
-
-#define SK_PNMI_EVT_RLMT_PORT_UP               10      /* Port came logically up */
-#define SK_PNMI_EVT_RLMT_PORT_DOWN             11      /* Port went logically down */
-#define SK_PNMI_EVT_RLMT_SEGMENTATION  13      /* Two SP root bridges found */
-#define SK_PNMI_EVT_RLMT_ACTIVE_DOWN   14      /* Port went logically down */
-#define SK_PNMI_EVT_RLMT_ACTIVE_UP             15      /* Port came logically up */
-#define SK_PNMI_EVT_RLMT_SET_NETS              16      /* 1. Parameter is number of nets
-                                                                                               1 = single net; 2 = dual net */
-#define SK_PNMI_EVT_VCT_RESET          17      /* VCT port reset timer event started with SET. */
-
-
-/*
- * Return values
- */
-#define SK_PNMI_ERR_OK                         0
-#define SK_PNMI_ERR_GENERAL                    1
-#define SK_PNMI_ERR_TOO_SHORT          2
-#define SK_PNMI_ERR_BAD_VALUE          3
-#define SK_PNMI_ERR_READ_ONLY          4
-#define SK_PNMI_ERR_UNKNOWN_OID                5
-#define SK_PNMI_ERR_UNKNOWN_INST       6
-#define SK_PNMI_ERR_UNKNOWN_NET        7
-#define SK_PNMI_ERR_NOT_SUPPORTED      10
-
-
-/*
- * Return values of driver reset function SK_DRIVER_RESET() and
- * driver event function SK_DRIVER_EVENT()
- */
-#define SK_PNMI_ERR_OK                 0
-#define SK_PNMI_ERR_FAIL               1
-
-
-/*
- * Return values of driver test function SK_DRIVER_SELFTEST()
- */
-#define SK_PNMI_TST_UNKNOWN            (1 << 0)
-#define SK_PNMI_TST_TRANCEIVER         (1 << 1)
-#define SK_PNMI_TST_ASIC               (1 << 2)
-#define SK_PNMI_TST_SENSOR             (1 << 3)
-#define SK_PNMI_TST_POWERMGMT          (1 << 4)
-#define SK_PNMI_TST_PCI                        (1 << 5)
-#define SK_PNMI_TST_MAC                        (1 << 6)
-
-
-/*
- * RLMT specific definitions
- */
-#define SK_PNMI_RLMT_STATUS_STANDBY    1
-#define SK_PNMI_RLMT_STATUS_ACTIVE     2
-#define SK_PNMI_RLMT_STATUS_ERROR      3
-
-#define SK_PNMI_RLMT_LSTAT_PHY_DOWN    1
-#define SK_PNMI_RLMT_LSTAT_AUTONEG     2
-#define SK_PNMI_RLMT_LSTAT_LOG_DOWN    3
-#define SK_PNMI_RLMT_LSTAT_LOG_UP      4
-#define SK_PNMI_RLMT_LSTAT_INDETERMINATED 5
-
-#define SK_PNMI_RLMT_MODE_CHK_LINK     (SK_RLMT_CHECK_LINK)
-#define SK_PNMI_RLMT_MODE_CHK_RX       (SK_RLMT_CHECK_LOC_LINK)
-#define SK_PNMI_RLMT_MODE_CHK_SPT      (SK_RLMT_CHECK_SEG)
-/* #define SK_PNMI_RLMT_MODE_CHK_EX */
-
-/*
- * OID definition
- */
-#ifndef _NDIS_ /* Check, whether NDIS already included OIDs */
-
-#define OID_GEN_XMIT_OK                                        0x00020101
-#define OID_GEN_RCV_OK                                 0x00020102
-#define OID_GEN_XMIT_ERROR                             0x00020103
-#define OID_GEN_RCV_ERROR                              0x00020104
-#define OID_GEN_RCV_NO_BUFFER                  0x00020105
-
-/* #define OID_GEN_DIRECTED_BYTES_XMIT 0x00020201 */
-#define OID_GEN_DIRECTED_FRAMES_XMIT   0x00020202
-/* #define OID_GEN_MULTICAST_BYTES_XMIT        0x00020203 */
-#define OID_GEN_MULTICAST_FRAMES_XMIT  0x00020204
-/* #define OID_GEN_BROADCAST_BYTES_XMIT        0x00020205 */
-#define OID_GEN_BROADCAST_FRAMES_XMIT  0x00020206
-/* #define OID_GEN_DIRECTED_BYTES_RCV  0x00020207 */
-#define OID_GEN_DIRECTED_FRAMES_RCV            0x00020208
-/* #define OID_GEN_MULTICAST_BYTES_RCV 0x00020209 */
-#define OID_GEN_MULTICAST_FRAMES_RCV   0x0002020A
-/* #define OID_GEN_BROADCAST_BYTES_RCV 0x0002020B */
-#define OID_GEN_BROADCAST_FRAMES_RCV   0x0002020C
-#define OID_GEN_RCV_CRC_ERROR                  0x0002020D
-#define OID_GEN_TRANSMIT_QUEUE_LENGTH  0x0002020E
-
-#define OID_802_3_PERMANENT_ADDRESS            0x01010101
-#define OID_802_3_CURRENT_ADDRESS              0x01010102
-/* #define OID_802_3_MULTICAST_LIST            0x01010103 */
-/* #define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104 */
-/* #define OID_802_3_MAC_OPTIONS               0x01010105 */
-                       
-#define OID_802_3_RCV_ERROR_ALIGNMENT  0x01020101
-#define OID_802_3_XMIT_ONE_COLLISION   0x01020102
-#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103
-#define OID_802_3_XMIT_DEFERRED                        0x01020201
-#define OID_802_3_XMIT_MAX_COLLISIONS  0x01020202
-#define OID_802_3_RCV_OVERRUN                  0x01020203
-#define OID_802_3_XMIT_UNDERRUN                        0x01020204
-#define OID_802_3_XMIT_TIMES_CRS_LOST  0x01020206
-#define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207
-
-/*
- * PnP and PM OIDs
- */
-#ifdef SK_POWER_MGMT
-#define OID_PNP_CAPABILITIES                   0xFD010100
-#define OID_PNP_SET_POWER                              0xFD010101
-#define OID_PNP_QUERY_POWER                            0xFD010102
-#define OID_PNP_ADD_WAKE_UP_PATTERN            0xFD010103
-#define OID_PNP_REMOVE_WAKE_UP_PATTERN 0xFD010104
-#define OID_PNP_ENABLE_WAKE_UP                 0xFD010106
-#endif /* SK_POWER_MGMT */
-
-#endif /* _NDIS_ */
-
-#define OID_SKGE_MDB_VERSION                   0xFF010100
-#define OID_SKGE_SUPPORTED_LIST                        0xFF010101
-#define OID_SKGE_VPD_FREE_BYTES                        0xFF010102
-#define OID_SKGE_VPD_ENTRIES_LIST              0xFF010103
-#define OID_SKGE_VPD_ENTRIES_NUMBER            0xFF010104
-#define OID_SKGE_VPD_KEY                               0xFF010105
-#define OID_SKGE_VPD_VALUE                             0xFF010106
-#define OID_SKGE_VPD_ACCESS                            0xFF010107
-#define OID_SKGE_VPD_ACTION                            0xFF010108
-                       
-#define OID_SKGE_PORT_NUMBER                   0xFF010110
-#define OID_SKGE_DEVICE_TYPE                   0xFF010111
-#define OID_SKGE_DRIVER_DESCR                  0xFF010112
-#define OID_SKGE_DRIVER_VERSION                        0xFF010113
-#define OID_SKGE_HW_DESCR                              0xFF010114
-#define OID_SKGE_HW_VERSION                            0xFF010115
-#define OID_SKGE_CHIPSET                               0xFF010116
-#define OID_SKGE_ACTION                                        0xFF010117
-#define OID_SKGE_RESULT                                        0xFF010118
-#define OID_SKGE_BUS_TYPE                              0xFF010119
-#define OID_SKGE_BUS_SPEED                             0xFF01011A
-#define OID_SKGE_BUS_WIDTH                             0xFF01011B
-/* 0xFF01011C unused */
-#define OID_SKGE_DIAG_ACTION                   0xFF01011D
-#define OID_SKGE_DIAG_RESULT                   0xFF01011E
-#define OID_SKGE_MTU                                   0xFF01011F
-#define OID_SKGE_PHYS_CUR_ADDR                 0xFF010120
-#define OID_SKGE_PHYS_FAC_ADDR                 0xFF010121
-#define OID_SKGE_PMD                                   0xFF010122
-#define OID_SKGE_CONNECTOR                             0xFF010123
-#define OID_SKGE_LINK_CAP                              0xFF010124
-#define OID_SKGE_LINK_MODE                             0xFF010125
-#define OID_SKGE_LINK_MODE_STATUS              0xFF010126
-#define OID_SKGE_LINK_STATUS                   0xFF010127
-#define OID_SKGE_FLOWCTRL_CAP                  0xFF010128
-#define OID_SKGE_FLOWCTRL_MODE                 0xFF010129
-#define OID_SKGE_FLOWCTRL_STATUS               0xFF01012A
-#define OID_SKGE_PHY_OPERATION_CAP             0xFF01012B
-#define OID_SKGE_PHY_OPERATION_MODE            0xFF01012C
-#define OID_SKGE_PHY_OPERATION_STATUS  0xFF01012D
-#define OID_SKGE_MULTICAST_LIST                        0xFF01012E
-#define OID_SKGE_CURRENT_PACKET_FILTER 0xFF01012F
-
-#define OID_SKGE_TRAP                                  0xFF010130
-#define OID_SKGE_TRAP_NUMBER                   0xFF010131
-
-#define OID_SKGE_RLMT_MODE                             0xFF010140
-#define OID_SKGE_RLMT_PORT_NUMBER              0xFF010141
-#define OID_SKGE_RLMT_PORT_ACTIVE              0xFF010142
-#define OID_SKGE_RLMT_PORT_PREFERRED   0xFF010143
-#define OID_SKGE_INTERMEDIATE_SUPPORT  0xFF010160
-
-#define OID_SKGE_SPEED_CAP                             0xFF010170
-#define OID_SKGE_SPEED_MODE                            0xFF010171
-#define OID_SKGE_SPEED_STATUS                  0xFF010172
-
-#define OID_SKGE_BOARDLEVEL                            0xFF010180
-
-#define OID_SKGE_SENSOR_NUMBER                 0xFF020100                      
-#define OID_SKGE_SENSOR_INDEX                  0xFF020101
-#define OID_SKGE_SENSOR_DESCR                  0xFF020102
-#define OID_SKGE_SENSOR_TYPE                   0xFF020103
-#define OID_SKGE_SENSOR_VALUE                  0xFF020104
-#define OID_SKGE_SENSOR_WAR_THRES_LOW  0xFF020105
-#define OID_SKGE_SENSOR_WAR_THRES_UPP  0xFF020106
-#define OID_SKGE_SENSOR_ERR_THRES_LOW  0xFF020107
-#define OID_SKGE_SENSOR_ERR_THRES_UPP  0xFF020108
-#define OID_SKGE_SENSOR_STATUS                 0xFF020109
-#define OID_SKGE_SENSOR_WAR_CTS                        0xFF02010A
-#define OID_SKGE_SENSOR_ERR_CTS                        0xFF02010B
-#define OID_SKGE_SENSOR_WAR_TIME               0xFF02010C
-#define OID_SKGE_SENSOR_ERR_TIME               0xFF02010D
-
-#define OID_SKGE_CHKSM_NUMBER                  0xFF020110
-#define OID_SKGE_CHKSM_RX_OK_CTS               0xFF020111
-#define OID_SKGE_CHKSM_RX_UNABLE_CTS   0xFF020112
-#define OID_SKGE_CHKSM_RX_ERR_CTS              0xFF020113
-#define OID_SKGE_CHKSM_TX_OK_CTS               0xFF020114
-#define OID_SKGE_CHKSM_TX_UNABLE_CTS   0xFF020115
-
-#define OID_SKGE_STAT_TX                               0xFF020120
-#define OID_SKGE_STAT_TX_OCTETS                        0xFF020121
-#define OID_SKGE_STAT_TX_BROADCAST             0xFF020122
-#define OID_SKGE_STAT_TX_MULTICAST             0xFF020123
-#define OID_SKGE_STAT_TX_UNICAST               0xFF020124
-#define OID_SKGE_STAT_TX_LONGFRAMES            0xFF020125
-#define OID_SKGE_STAT_TX_BURST                 0xFF020126
-#define OID_SKGE_STAT_TX_PFLOWC                        0xFF020127
-#define OID_SKGE_STAT_TX_FLOWC                 0xFF020128
-#define OID_SKGE_STAT_TX_SINGLE_COL            0xFF020129
-#define OID_SKGE_STAT_TX_MULTI_COL             0xFF02012A
-#define OID_SKGE_STAT_TX_EXCESS_COL            0xFF02012B
-#define OID_SKGE_STAT_TX_LATE_COL              0xFF02012C
-#define OID_SKGE_STAT_TX_DEFFERAL              0xFF02012D
-#define OID_SKGE_STAT_TX_EXCESS_DEF            0xFF02012E
-#define OID_SKGE_STAT_TX_UNDERRUN              0xFF02012F
-#define OID_SKGE_STAT_TX_CARRIER               0xFF020130
-/* #define OID_SKGE_STAT_TX_UTIL               0xFF020131 */
-#define OID_SKGE_STAT_TX_64                            0xFF020132
-#define OID_SKGE_STAT_TX_127                   0xFF020133
-#define OID_SKGE_STAT_TX_255                   0xFF020134
-#define OID_SKGE_STAT_TX_511                   0xFF020135
-#define OID_SKGE_STAT_TX_1023                  0xFF020136
-#define OID_SKGE_STAT_TX_MAX                   0xFF020137
-#define OID_SKGE_STAT_TX_SYNC                  0xFF020138
-#define OID_SKGE_STAT_TX_SYNC_OCTETS   0xFF020139
-#define OID_SKGE_STAT_RX                               0xFF02013A
-#define OID_SKGE_STAT_RX_OCTETS                        0xFF02013B
-#define OID_SKGE_STAT_RX_BROADCAST             0xFF02013C
-#define OID_SKGE_STAT_RX_MULTICAST             0xFF02013D
-#define OID_SKGE_STAT_RX_UNICAST               0xFF02013E
-#define OID_SKGE_STAT_RX_PFLOWC                        0xFF02013F
-#define OID_SKGE_STAT_RX_FLOWC                 0xFF020140
-#define OID_SKGE_STAT_RX_PFLOWC_ERR            0xFF020141
-#define OID_SKGE_STAT_RX_FLOWC_UNKWN   0xFF020142
-#define OID_SKGE_STAT_RX_BURST                 0xFF020143
-#define OID_SKGE_STAT_RX_MISSED                        0xFF020144
-#define OID_SKGE_STAT_RX_FRAMING               0xFF020145
-#define OID_SKGE_STAT_RX_OVERFLOW              0xFF020146
-#define OID_SKGE_STAT_RX_JABBER                        0xFF020147
-#define OID_SKGE_STAT_RX_CARRIER               0xFF020148
-#define OID_SKGE_STAT_RX_IR_LENGTH             0xFF020149
-#define OID_SKGE_STAT_RX_SYMBOL                        0xFF02014A
-#define OID_SKGE_STAT_RX_SHORTS                        0xFF02014B
-#define OID_SKGE_STAT_RX_RUNT                  0xFF02014C
-#define OID_SKGE_STAT_RX_CEXT                  0xFF02014D
-#define OID_SKGE_STAT_RX_TOO_LONG              0xFF02014E
-#define OID_SKGE_STAT_RX_FCS                   0xFF02014F
-/* #define OID_SKGE_STAT_RX_UTIL               0xFF020150 */
-#define OID_SKGE_STAT_RX_64                            0xFF020151
-#define OID_SKGE_STAT_RX_127                   0xFF020152
-#define OID_SKGE_STAT_RX_255                   0xFF020153
-#define OID_SKGE_STAT_RX_511                   0xFF020154
-#define OID_SKGE_STAT_RX_1023                  0xFF020155
-#define OID_SKGE_STAT_RX_MAX                   0xFF020156
-#define OID_SKGE_STAT_RX_LONGFRAMES            0xFF020157
-
-#define OID_SKGE_RLMT_CHANGE_CTS               0xFF020160
-#define OID_SKGE_RLMT_CHANGE_TIME              0xFF020161
-#define OID_SKGE_RLMT_CHANGE_ESTIM             0xFF020162
-#define OID_SKGE_RLMT_CHANGE_THRES             0xFF020163
-
-#define OID_SKGE_RLMT_PORT_INDEX               0xFF020164
-#define OID_SKGE_RLMT_STATUS                   0xFF020165
-#define OID_SKGE_RLMT_TX_HELLO_CTS             0xFF020166
-#define OID_SKGE_RLMT_RX_HELLO_CTS             0xFF020167
-#define OID_SKGE_RLMT_TX_SP_REQ_CTS            0xFF020168
-#define OID_SKGE_RLMT_RX_SP_CTS                        0xFF020169
-
-#define OID_SKGE_RLMT_MONITOR_NUMBER   0xFF010150
-#define OID_SKGE_RLMT_MONITOR_INDEX            0xFF010151
-#define OID_SKGE_RLMT_MONITOR_ADDR             0xFF010152
-#define OID_SKGE_RLMT_MONITOR_ERRS             0xFF010153
-#define OID_SKGE_RLMT_MONITOR_TIMESTAMP        0xFF010154
-#define OID_SKGE_RLMT_MONITOR_ADMIN            0xFF010155
-
-#define OID_SKGE_TX_SW_QUEUE_LEN               0xFF020170
-#define OID_SKGE_TX_SW_QUEUE_MAX               0xFF020171
-#define OID_SKGE_TX_RETRY                              0xFF020172
-#define OID_SKGE_RX_INTR_CTS                   0xFF020173
-#define OID_SKGE_TX_INTR_CTS                   0xFF020174
-#define OID_SKGE_RX_NO_BUF_CTS                 0xFF020175
-#define OID_SKGE_TX_NO_BUF_CTS                 0xFF020176
-#define OID_SKGE_TX_USED_DESCR_NO              0xFF020177
-#define OID_SKGE_RX_DELIVERED_CTS              0xFF020178
-#define OID_SKGE_RX_OCTETS_DELIV_CTS   0xFF020179
-#define OID_SKGE_RX_HW_ERROR_CTS               0xFF02017A
-#define OID_SKGE_TX_HW_ERROR_CTS               0xFF02017B
-#define OID_SKGE_IN_ERRORS_CTS                 0xFF02017C
-#define OID_SKGE_OUT_ERROR_CTS                 0xFF02017D
-#define OID_SKGE_ERR_RECOVERY_CTS              0xFF02017E
-#define OID_SKGE_SYSUPTIME                             0xFF02017F
-
-#define OID_SKGE_ALL_DATA                              0xFF020190
-
-/* Defines for VCT. */
-#define OID_SKGE_VCT_GET                               0xFF020200
-#define OID_SKGE_VCT_SET                               0xFF020201
-#define OID_SKGE_VCT_STATUS                            0xFF020202
-
-#ifdef SK_DIAG_SUPPORT
-/* Defines for driver DIAG mode. */
-#define OID_SKGE_DIAG_MODE                             0xFF020204
-#endif /* SK_DIAG_SUPPORT */
-
-/* New OIDs */
-#define OID_SKGE_DRIVER_RELDATE                        0xFF020210
-#define OID_SKGE_DRIVER_FILENAME               0xFF020211
-#define OID_SKGE_CHIPID                                        0xFF020212
-#define OID_SKGE_RAMSIZE                               0xFF020213
-#define OID_SKGE_VAUXAVAIL                             0xFF020214
-#define OID_SKGE_PHY_TYPE                              0xFF020215
-#define OID_SKGE_PHY_LP_MODE                   0xFF020216
-
-/* VCT struct to store a backup copy of VCT data after a port reset. */
-typedef struct s_PnmiVct {
-       SK_U8                   VctStatus;
-       SK_U8                   PCableLen;
-       SK_U32                  PMdiPairLen[4];
-       SK_U8                   PMdiPairSts[4];
-} SK_PNMI_VCT;
-
-
-/* VCT status values (to be given to CPA via OID_SKGE_VCT_STATUS). */
-#define SK_PNMI_VCT_NONE               0
-#define SK_PNMI_VCT_OLD_VCT_DATA       1
-#define SK_PNMI_VCT_NEW_VCT_DATA       2
-#define SK_PNMI_VCT_OLD_DSP_DATA       4
-#define SK_PNMI_VCT_NEW_DSP_DATA       8
-#define SK_PNMI_VCT_RUNNING            16
-
-
-/* VCT cable test status. */
-#define SK_PNMI_VCT_NORMAL_CABLE               0
-#define SK_PNMI_VCT_SHORT_CABLE                        1
-#define SK_PNMI_VCT_OPEN_CABLE                 2
-#define SK_PNMI_VCT_TEST_FAIL                  3
-#define SK_PNMI_VCT_IMPEDANCE_MISMATCH         4
-
-#define        OID_SKGE_TRAP_SEN_WAR_LOW               500
-#define OID_SKGE_TRAP_SEN_WAR_UPP              501
-#define        OID_SKGE_TRAP_SEN_ERR_LOW               502
-#define OID_SKGE_TRAP_SEN_ERR_UPP              503
-#define OID_SKGE_TRAP_RLMT_CHANGE_THRES        520
-#define OID_SKGE_TRAP_RLMT_CHANGE_PORT 521
-#define OID_SKGE_TRAP_RLMT_PORT_DOWN   522
-#define OID_SKGE_TRAP_RLMT_PORT_UP             523
-#define OID_SKGE_TRAP_RLMT_SEGMENTATION        524
-
-#ifdef SK_DIAG_SUPPORT
-/* Defines for driver DIAG mode. */
-#define SK_DIAG_ATTACHED       2
-#define SK_DIAG_RUNNING                1
-#define SK_DIAG_IDLE           0
-#endif /* SK_DIAG_SUPPORT */
-
-/*
- * Generic PNMI IOCTL subcommand definitions.
- */
-#define        SK_GET_SINGLE_VAR               1
-#define        SK_SET_SINGLE_VAR               2
-#define        SK_PRESET_SINGLE_VAR    3
-#define        SK_GET_FULL_MIB                 4
-#define        SK_SET_FULL_MIB                 5
-#define        SK_PRESET_FULL_MIB              6
-
-
-/*
- * Define error numbers and messages for syslog
- */
-#define SK_PNMI_ERR001         (SK_ERRBASE_PNMI + 1)
-#define SK_PNMI_ERR001MSG      "SkPnmiGetStruct: Unknown OID"
-#define SK_PNMI_ERR002         (SK_ERRBASE_PNMI + 2)
-#define SK_PNMI_ERR002MSG      "SkPnmiGetStruct: Cannot read VPD keys"
-#define SK_PNMI_ERR003         (SK_ERRBASE_PNMI + 3)
-#define SK_PNMI_ERR003MSG      "OidStruct: Called with wrong OID"
-#define SK_PNMI_ERR004         (SK_ERRBASE_PNMI + 4)
-#define SK_PNMI_ERR004MSG      "OidStruct: Called with wrong action"
-#define SK_PNMI_ERR005         (SK_ERRBASE_PNMI + 5)
-#define SK_PNMI_ERR005MSG      "Perform: Cannot reset driver"
-#define SK_PNMI_ERR006         (SK_ERRBASE_PNMI + 6)
-#define SK_PNMI_ERR006MSG      "Perform: Unknown OID action command"
-#define SK_PNMI_ERR007         (SK_ERRBASE_PNMI + 7)
-#define SK_PNMI_ERR007MSG      "General: Driver description not initialized"
-#define SK_PNMI_ERR008         (SK_ERRBASE_PNMI + 8)
-#define SK_PNMI_ERR008MSG      "Addr: Tried to get unknown OID"
-#define SK_PNMI_ERR009         (SK_ERRBASE_PNMI + 9)
-#define SK_PNMI_ERR009MSG      "Addr: Unknown OID"
-#define SK_PNMI_ERR010         (SK_ERRBASE_PNMI + 10)
-#define SK_PNMI_ERR010MSG      "CsumStat: Unknown OID"
-#define SK_PNMI_ERR011         (SK_ERRBASE_PNMI + 11)
-#define SK_PNMI_ERR011MSG      "SensorStat: Sensor descr string too long"
-#define SK_PNMI_ERR012         (SK_ERRBASE_PNMI + 12)
-#define SK_PNMI_ERR012MSG      "SensorStat: Unknown OID"
-#define SK_PNMI_ERR013         (SK_ERRBASE_PNMI + 13)
-#define SK_PNMI_ERR013MSG      ""
-#define SK_PNMI_ERR014         (SK_ERRBASE_PNMI + 14)
-#define SK_PNMI_ERR014MSG      "Vpd: Cannot read VPD keys"
-#define SK_PNMI_ERR015         (SK_ERRBASE_PNMI + 15)
-#define SK_PNMI_ERR015MSG      "Vpd: Internal array for VPD keys to small"
-#define SK_PNMI_ERR016         (SK_ERRBASE_PNMI + 16)
-#define SK_PNMI_ERR016MSG      "Vpd: Key string too long"
-#define SK_PNMI_ERR017         (SK_ERRBASE_PNMI + 17)
-#define SK_PNMI_ERR017MSG      "Vpd: Invalid VPD status pointer"
-#define SK_PNMI_ERR018         (SK_ERRBASE_PNMI + 18)
-#define SK_PNMI_ERR018MSG      "Vpd: VPD data not valid"
-#define SK_PNMI_ERR019         (SK_ERRBASE_PNMI + 19)
-#define SK_PNMI_ERR019MSG      "Vpd: VPD entries list string too long"
-#define SK_PNMI_ERR021         (SK_ERRBASE_PNMI + 21)
-#define SK_PNMI_ERR021MSG      "Vpd: VPD data string too long"
-#define SK_PNMI_ERR022         (SK_ERRBASE_PNMI + 22)
-#define SK_PNMI_ERR022MSG      "Vpd: VPD data string too long should be errored before"
-#define SK_PNMI_ERR023         (SK_ERRBASE_PNMI + 23)
-#define SK_PNMI_ERR023MSG      "Vpd: Unknown OID in get action"
-#define SK_PNMI_ERR024         (SK_ERRBASE_PNMI + 24)
-#define SK_PNMI_ERR024MSG      "Vpd: Unknown OID in preset/set action"
-#define SK_PNMI_ERR025         (SK_ERRBASE_PNMI + 25)
-#define SK_PNMI_ERR025MSG      "Vpd: Cannot write VPD after modify entry"
-#define SK_PNMI_ERR026         (SK_ERRBASE_PNMI + 26)
-#define SK_PNMI_ERR026MSG      "Vpd: Cannot update VPD"
-#define SK_PNMI_ERR027         (SK_ERRBASE_PNMI + 27)
-#define SK_PNMI_ERR027MSG      "Vpd: Cannot delete VPD entry"
-#define SK_PNMI_ERR028         (SK_ERRBASE_PNMI + 28)
-#define SK_PNMI_ERR028MSG      "Vpd: Cannot update VPD after delete entry"
-#define SK_PNMI_ERR029         (SK_ERRBASE_PNMI + 29)
-#define SK_PNMI_ERR029MSG      "General: Driver description string too long"
-#define SK_PNMI_ERR030         (SK_ERRBASE_PNMI + 30)
-#define SK_PNMI_ERR030MSG      "General: Driver version not initialized"
-#define SK_PNMI_ERR031         (SK_ERRBASE_PNMI + 31)
-#define SK_PNMI_ERR031MSG      "General: Driver version string too long"
-#define SK_PNMI_ERR032         (SK_ERRBASE_PNMI + 32)
-#define SK_PNMI_ERR032MSG      "General: Cannot read VPD Name for HW descr"
-#define SK_PNMI_ERR033         (SK_ERRBASE_PNMI + 33)
-#define SK_PNMI_ERR033MSG      "General: HW description string too long"
-#define SK_PNMI_ERR034         (SK_ERRBASE_PNMI + 34)
-#define SK_PNMI_ERR034MSG      "General: Unknown OID"
-#define SK_PNMI_ERR035         (SK_ERRBASE_PNMI + 35)
-#define SK_PNMI_ERR035MSG      "Rlmt: Unknown OID"
-#define SK_PNMI_ERR036         (SK_ERRBASE_PNMI + 36)
-#define SK_PNMI_ERR036MSG      ""
-#define SK_PNMI_ERR037         (SK_ERRBASE_PNMI + 37)
-#define SK_PNMI_ERR037MSG      "Rlmt: SK_RLMT_MODE_CHANGE event return not 0"
-#define SK_PNMI_ERR038         (SK_ERRBASE_PNMI + 38)
-#define SK_PNMI_ERR038MSG      "Rlmt: SK_RLMT_PREFPORT_CHANGE event return not 0"
-#define SK_PNMI_ERR039         (SK_ERRBASE_PNMI + 39)
-#define SK_PNMI_ERR039MSG      "RlmtStat: Unknown OID"
-#define SK_PNMI_ERR040         (SK_ERRBASE_PNMI + 40)
-#define SK_PNMI_ERR040MSG      "PowerManagement: Unknown OID"
-#define SK_PNMI_ERR041         (SK_ERRBASE_PNMI + 41)
-#define SK_PNMI_ERR041MSG      "MacPrivateConf: Unknown OID"
-#define SK_PNMI_ERR042         (SK_ERRBASE_PNMI + 42)
-#define SK_PNMI_ERR042MSG      "MacPrivateConf: SK_HWEV_SET_ROLE returned not 0"
-#define SK_PNMI_ERR043         (SK_ERRBASE_PNMI + 43)
-#define SK_PNMI_ERR043MSG      "MacPrivateConf: SK_HWEV_SET_LMODE returned not 0"
-#define SK_PNMI_ERR044         (SK_ERRBASE_PNMI + 44)
-#define SK_PNMI_ERR044MSG      "MacPrivateConf: SK_HWEV_SET_FLOWMODE returned not 0"
-#define SK_PNMI_ERR045         (SK_ERRBASE_PNMI + 45)
-#define SK_PNMI_ERR045MSG      "MacPrivateConf: SK_HWEV_SET_SPEED returned not 0"
-#define SK_PNMI_ERR046         (SK_ERRBASE_PNMI + 46)
-#define SK_PNMI_ERR046MSG      "Monitor: Unknown OID"
-#define SK_PNMI_ERR047         (SK_ERRBASE_PNMI + 47)
-#define SK_PNMI_ERR047MSG      "SirqUpdate: Event function returns not 0"
-#define SK_PNMI_ERR048         (SK_ERRBASE_PNMI + 48)
-#define SK_PNMI_ERR048MSG      "RlmtUpdate: Event function returns not 0"
-#define SK_PNMI_ERR049         (SK_ERRBASE_PNMI + 49)
-#define SK_PNMI_ERR049MSG      "SkPnmiInit: Invalid size of 'CounterOffset' struct!!"
-#define SK_PNMI_ERR050         (SK_ERRBASE_PNMI + 50)
-#define SK_PNMI_ERR050MSG      "SkPnmiInit: Invalid size of 'StatAddr' table!!"
-#define SK_PNMI_ERR051         (SK_ERRBASE_PNMI + 51)
-#define SK_PNMI_ERR051MSG      "SkPnmiEvent: Port switch suspicious"
-#define SK_PNMI_ERR052         (SK_ERRBASE_PNMI + 52)
-#define SK_PNMI_ERR052MSG      ""
-#define SK_PNMI_ERR053         (SK_ERRBASE_PNMI + 53)
-#define SK_PNMI_ERR053MSG      "General: Driver release date not initialized"
-#define SK_PNMI_ERR054         (SK_ERRBASE_PNMI + 54)
-#define SK_PNMI_ERR054MSG      "General: Driver release date string too long"
-#define SK_PNMI_ERR055         (SK_ERRBASE_PNMI + 55)
-#define SK_PNMI_ERR055MSG      "General: Driver file name not initialized"
-#define SK_PNMI_ERR056         (SK_ERRBASE_PNMI + 56)
-#define SK_PNMI_ERR056MSG      "General: Driver file name string too long"
-
-/*
- * Management counter macros called by the driver
- */
-#define SK_PNMI_SET_DRIVER_DESCR(pAC,v)        ((pAC)->Pnmi.pDriverDescription = \
-       (char *)(v))
-
-#define SK_PNMI_SET_DRIVER_VER(pAC,v)  ((pAC)->Pnmi.pDriverVersion = \
-       (char *)(v))
-
-#define SK_PNMI_SET_DRIVER_RELDATE(pAC,v)      ((pAC)->Pnmi.pDriverReleaseDate = \
-       (char *)(v))
-
-#define SK_PNMI_SET_DRIVER_FILENAME(pAC,v)     ((pAC)->Pnmi.pDriverFileName = \
-       (char *)(v))
-
-#define SK_PNMI_CNT_TX_QUEUE_LEN(pAC,v,p) \
-       { \
-               (pAC)->Pnmi.Port[p].TxSwQueueLen = (SK_U64)(v); \
-               if ((pAC)->Pnmi.Port[p].TxSwQueueLen > (pAC)->Pnmi.Port[p].TxSwQueueMax) { \
-                       (pAC)->Pnmi.Port[p].TxSwQueueMax = (pAC)->Pnmi.Port[p].TxSwQueueLen; \
-               } \
-       }
-#define SK_PNMI_CNT_TX_RETRY(pAC,p)    (((pAC)->Pnmi.Port[p].TxRetryCts)++)
-#define SK_PNMI_CNT_RX_INTR(pAC,p)     (((pAC)->Pnmi.Port[p].RxIntrCts)++)
-#define SK_PNMI_CNT_TX_INTR(pAC,p)     (((pAC)->Pnmi.Port[p].TxIntrCts)++)
-#define SK_PNMI_CNT_NO_RX_BUF(pAC,p)   (((pAC)->Pnmi.Port[p].RxNoBufCts)++)
-#define SK_PNMI_CNT_NO_TX_BUF(pAC,p)   (((pAC)->Pnmi.Port[p].TxNoBufCts)++)
-#define SK_PNMI_CNT_USED_TX_DESCR(pAC,v,p) \
-       ((pAC)->Pnmi.Port[p].TxUsedDescrNo=(SK_U64)(v));
-#define SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC,v,p) \
-       { \
-               ((pAC)->Pnmi.Port[p].RxDeliveredCts)++; \
-               (pAC)->Pnmi.Port[p].RxOctetsDeliveredCts += (SK_U64)(v); \
-       }
-#define SK_PNMI_CNT_ERR_RECOVERY(pAC,p)        (((pAC)->Pnmi.Port[p].ErrRecoveryCts)++);
-
-#define SK_PNMI_CNT_SYNC_OCTETS(pAC,p,v) \
-       { \
-               if ((p) < SK_MAX_MACS) { \
-                       ((pAC)->Pnmi.Port[p].StatSyncCts)++; \
-                       (pAC)->Pnmi.Port[p].StatSyncOctetsCts += (SK_U64)(v); \
-               } \
-       }
-
-#define SK_PNMI_CNT_RX_LONGFRAMES(pAC,p) \
-       { \
-               if ((p) < SK_MAX_MACS) { \
-                       ((pAC)->Pnmi.Port[p].StatRxLongFrameCts++); \
-               } \
-       }
-
-#define SK_PNMI_CNT_RX_FRAMETOOLONG(pAC,p) \
-       { \
-               if ((p) < SK_MAX_MACS) { \
-                       ((pAC)->Pnmi.Port[p].StatRxFrameTooLongCts++); \
-               } \
-       }
-
-#define SK_PNMI_CNT_RX_PMACC_ERR(pAC,p) \
-       { \
-               if ((p) < SK_MAX_MACS) { \
-                       ((pAC)->Pnmi.Port[p].StatRxPMaccErr++); \
-               } \
-       }
-
-/*
- * Conversion Macros
- */
-#define SK_PNMI_PORT_INST2LOG(i)       ((unsigned int)(i) - 1)
-#define SK_PNMI_PORT_LOG2INST(l)       ((unsigned int)(l) + 1)
-#define SK_PNMI_PORT_PHYS2LOG(p)       ((unsigned int)(p) + 1)
-#define SK_PNMI_PORT_LOG2PHYS(pAC,l)   ((unsigned int)(l) - 1)
-#define SK_PNMI_PORT_PHYS2INST(pAC,p)  \
-       (pAC->Pnmi.DualNetActiveFlag ? 2 : ((unsigned int)(p) + 2))
-#define SK_PNMI_PORT_INST2PHYS(pAC,i)  ((unsigned int)(i) - 2)
-
-/*
- * Structure definition for SkPnmiGetStruct and SkPnmiSetStruct
- */
-#define SK_PNMI_VPD_KEY_SIZE   5
-#define SK_PNMI_VPD_BUFSIZE            (VPD_SIZE)
-#define SK_PNMI_VPD_ENTRIES            (VPD_SIZE / 4)
-#define SK_PNMI_VPD_DATALEN            128 /*  Number of data bytes */
-
-#define SK_PNMI_MULTICAST_LISTLEN      64
-#define SK_PNMI_SENSOR_ENTRIES         (SK_MAX_SENSORS)
-#define SK_PNMI_CHECKSUM_ENTRIES       3
-#define SK_PNMI_MAC_ENTRIES                    (SK_MAX_MACS + 1)
-#define SK_PNMI_MONITOR_ENTRIES                20
-#define SK_PNMI_TRAP_ENTRIES           10
-#define SK_PNMI_TRAPLEN                                128
-#define SK_PNMI_STRINGLEN1                     80
-#define SK_PNMI_STRINGLEN2                     25
-#define SK_PNMI_TRAP_QUEUE_LEN         512
-
-typedef struct s_PnmiVpd {
-       char                    VpdKey[SK_PNMI_VPD_KEY_SIZE];
-       char                    VpdValue[SK_PNMI_VPD_DATALEN];
-       SK_U8                   VpdAccess;
-       SK_U8                   VpdAction;
-} SK_PNMI_VPD;
-
-typedef struct s_PnmiSensor {
-       SK_U8                   SensorIndex;
-       char                    SensorDescr[SK_PNMI_STRINGLEN2];
-       SK_U8                   SensorType;
-       SK_U32                  SensorValue;
-       SK_U32                  SensorWarningThresholdLow;
-       SK_U32                  SensorWarningThresholdHigh;
-       SK_U32                  SensorErrorThresholdLow;
-       SK_U32                  SensorErrorThresholdHigh;
-       SK_U8                   SensorStatus;
-       SK_U64                  SensorWarningCts;
-       SK_U64                  SensorErrorCts;
-       SK_U64                  SensorWarningTimestamp;
-       SK_U64                  SensorErrorTimestamp;
-} SK_PNMI_SENSOR;
-
-typedef struct s_PnmiChecksum {
-       SK_U64                  ChecksumRxOkCts;
-       SK_U64                  ChecksumRxUnableCts;
-       SK_U64                  ChecksumRxErrCts;
-       SK_U64                  ChecksumTxOkCts;
-       SK_U64                  ChecksumTxUnableCts;
-} SK_PNMI_CHECKSUM;
-
-typedef struct s_PnmiStat {
-       SK_U64                  StatTxOkCts;
-       SK_U64                  StatTxOctetsOkCts;
-       SK_U64                  StatTxBroadcastOkCts;
-       SK_U64                  StatTxMulticastOkCts;
-       SK_U64                  StatTxUnicastOkCts;
-       SK_U64                  StatTxLongFramesCts;
-       SK_U64                  StatTxBurstCts;
-       SK_U64                  StatTxPauseMacCtrlCts;
-       SK_U64                  StatTxMacCtrlCts;
-       SK_U64                  StatTxSingleCollisionCts;
-       SK_U64                  StatTxMultipleCollisionCts;
-       SK_U64                  StatTxExcessiveCollisionCts;
-       SK_U64                  StatTxLateCollisionCts;
-       SK_U64                  StatTxDeferralCts;
-       SK_U64                  StatTxExcessiveDeferralCts;
-       SK_U64                  StatTxFifoUnderrunCts;
-       SK_U64                  StatTxCarrierCts;
-       SK_U64                  Dummy1; /* StatTxUtilization */
-       SK_U64                  StatTx64Cts;
-       SK_U64                  StatTx127Cts;
-       SK_U64                  StatTx255Cts;
-       SK_U64                  StatTx511Cts;
-       SK_U64                  StatTx1023Cts;
-       SK_U64                  StatTxMaxCts;
-       SK_U64                  StatTxSyncCts;
-       SK_U64                  StatTxSyncOctetsCts;
-       SK_U64                  StatRxOkCts;
-       SK_U64                  StatRxOctetsOkCts;
-       SK_U64                  StatRxBroadcastOkCts;
-       SK_U64                  StatRxMulticastOkCts;
-       SK_U64                  StatRxUnicastOkCts;
-       SK_U64                  StatRxLongFramesCts;
-       SK_U64                  StatRxPauseMacCtrlCts;
-       SK_U64                  StatRxMacCtrlCts;
-       SK_U64                  StatRxPauseMacCtrlErrorCts;
-       SK_U64                  StatRxMacCtrlUnknownCts;
-       SK_U64                  StatRxBurstCts;
-       SK_U64                  StatRxMissedCts;
-       SK_U64                  StatRxFramingCts;
-       SK_U64                  StatRxFifoOverflowCts;
-       SK_U64                  StatRxJabberCts;
-       SK_U64                  StatRxCarrierCts;
-       SK_U64                  StatRxIRLengthCts;
-       SK_U64                  StatRxSymbolCts;
-       SK_U64                  StatRxShortsCts;
-       SK_U64                  StatRxRuntCts;
-       SK_U64                  StatRxCextCts;
-       SK_U64                  StatRxTooLongCts;
-       SK_U64                  StatRxFcsCts;
-       SK_U64                  Dummy2; /* StatRxUtilization */
-       SK_U64                  StatRx64Cts;
-       SK_U64                  StatRx127Cts;
-       SK_U64                  StatRx255Cts;
-       SK_U64                  StatRx511Cts;
-       SK_U64                  StatRx1023Cts;
-       SK_U64                  StatRxMaxCts;
-} SK_PNMI_STAT;
-
-typedef struct s_PnmiConf {
-       char                    ConfMacCurrentAddr[6];
-       char                    ConfMacFactoryAddr[6];
-       SK_U8                   ConfPMD;
-       SK_U8                   ConfConnector;
-       SK_U32                  ConfPhyType;
-       SK_U32                  ConfPhyMode;
-       SK_U8                   ConfLinkCapability;
-       SK_U8                   ConfLinkMode;
-       SK_U8                   ConfLinkModeStatus;
-       SK_U8                   ConfLinkStatus;
-       SK_U8                   ConfFlowCtrlCapability;
-       SK_U8                   ConfFlowCtrlMode;
-       SK_U8                   ConfFlowCtrlStatus;
-       SK_U8                   ConfPhyOperationCapability;
-       SK_U8                   ConfPhyOperationMode;
-       SK_U8                   ConfPhyOperationStatus;
-       SK_U8                   ConfSpeedCapability;
-       SK_U8                   ConfSpeedMode;
-       SK_U8                   ConfSpeedStatus;
-} SK_PNMI_CONF;
-
-typedef struct s_PnmiRlmt {
-       SK_U32                  RlmtIndex;
-       SK_U32                  RlmtStatus;
-       SK_U64                  RlmtTxHelloCts;
-       SK_U64                  RlmtRxHelloCts;
-       SK_U64                  RlmtTxSpHelloReqCts;
-       SK_U64                  RlmtRxSpHelloCts;
-} SK_PNMI_RLMT;
-
-typedef struct s_PnmiRlmtMonitor {
-       SK_U32                  RlmtMonitorIndex;
-       char                    RlmtMonitorAddr[6];
-       SK_U64                  RlmtMonitorErrorCts;
-       SK_U64                  RlmtMonitorTimestamp;
-       SK_U8                   RlmtMonitorAdmin;
-} SK_PNMI_RLMT_MONITOR;
-
-typedef struct s_PnmiRequestStatus {
-       SK_U32                  ErrorStatus;
-       SK_U32                  ErrorOffset;
-} SK_PNMI_REQUEST_STATUS;
-
-typedef struct s_PnmiStrucData {
-       SK_U32                  MgmtDBVersion;
-       SK_PNMI_REQUEST_STATUS  ReturnStatus;
-       SK_U32                  VpdFreeBytes;
-       char                    VpdEntriesList[SK_PNMI_VPD_ENTRIES * SK_PNMI_VPD_KEY_SIZE];
-       SK_U32                  VpdEntriesNumber;
-       SK_PNMI_VPD             Vpd[SK_PNMI_VPD_ENTRIES];
-       SK_U32                  PortNumber;
-       SK_U32                  DeviceType;
-       char                    DriverDescr[SK_PNMI_STRINGLEN1];
-       char                    DriverVersion[SK_PNMI_STRINGLEN2];
-       char                    DriverReleaseDate[SK_PNMI_STRINGLEN1];
-       char                    DriverFileName[SK_PNMI_STRINGLEN1];
-       char                    HwDescr[SK_PNMI_STRINGLEN1];
-       char                    HwVersion[SK_PNMI_STRINGLEN2];
-       SK_U16                  Chipset;
-       SK_U32                  ChipId;
-       SK_U8                   VauxAvail;
-       SK_U32                  RamSize;
-       SK_U32                  MtuSize;
-       SK_U32                  Action;
-       SK_U32                  TestResult;
-       SK_U8                   BusType;
-       SK_U8                   BusSpeed;
-       SK_U8                   BusWidth;
-       SK_U8                   SensorNumber;
-       SK_PNMI_SENSOR  Sensor[SK_PNMI_SENSOR_ENTRIES];
-       SK_U8                   ChecksumNumber;
-       SK_PNMI_CHECKSUM        Checksum[SK_PNMI_CHECKSUM_ENTRIES];
-       SK_PNMI_STAT    Stat[SK_PNMI_MAC_ENTRIES];
-       SK_PNMI_CONF    Conf[SK_PNMI_MAC_ENTRIES];
-       SK_U8                   RlmtMode;
-       SK_U32                  RlmtPortNumber;
-       SK_U8                   RlmtPortActive;
-       SK_U8                   RlmtPortPreferred;
-       SK_U64                  RlmtChangeCts;
-       SK_U64                  RlmtChangeTime;
-       SK_U64                  RlmtChangeEstimate;
-       SK_U64                  RlmtChangeThreshold;
-       SK_PNMI_RLMT    Rlmt[SK_MAX_MACS];
-       SK_U32                  RlmtMonitorNumber;
-       SK_PNMI_RLMT_MONITOR    RlmtMonitor[SK_PNMI_MONITOR_ENTRIES];
-       SK_U32                  TrapNumber;
-       SK_U8                   Trap[SK_PNMI_TRAP_QUEUE_LEN];
-       SK_U64                  TxSwQueueLen;
-       SK_U64                  TxSwQueueMax;
-       SK_U64                  TxRetryCts;
-       SK_U64                  RxIntrCts;
-       SK_U64                  TxIntrCts;
-       SK_U64                  RxNoBufCts;
-       SK_U64                  TxNoBufCts;
-       SK_U64                  TxUsedDescrNo;
-       SK_U64                  RxDeliveredCts;
-       SK_U64                  RxOctetsDeliveredCts;
-       SK_U64                  RxHwErrorsCts;
-       SK_U64                  TxHwErrorsCts;
-       SK_U64                  InErrorsCts;
-       SK_U64                  OutErrorsCts;
-       SK_U64                  ErrRecoveryCts;
-       SK_U64                  SysUpTime;
-} SK_PNMI_STRUCT_DATA;
-
-#define SK_PNMI_STRUCT_SIZE    (sizeof(SK_PNMI_STRUCT_DATA))
-#define SK_PNMI_MIN_STRUCT_SIZE        ((unsigned int)(SK_UPTR)\
-                                &(((SK_PNMI_STRUCT_DATA *)0)->VpdFreeBytes))
-                                                                                                               /*
-                                                                                                                * ReturnStatus field
-                                                                                                                * must be located
-                                                                                                                * before VpdFreeBytes
-                                                                                                                */
-
-/*
- * Various definitions
- */
-#define SK_PNMI_MAX_PROTOS             3
-
-#define SK_PNMI_CNT_NO                 66      /* Must have the value of the enum
-                                                                        * SK_PNMI_MAX_IDX. Define SK_PNMI_CHECK
-                                                                        * for check while init phase 1
-                                                                        */
-
-/*
- * Estimate data structure
- */
-typedef struct s_PnmiEstimate {
-       unsigned int    EstValueIndex;
-       SK_U64                  EstValue[7];
-       SK_U64                  Estimate;
-       SK_TIMER                EstTimer;
-} SK_PNMI_ESTIMATE;
-
-
-/*
- * VCT timer data structure
- */
-typedef struct s_VctTimer {
-       SK_TIMER                VctTimer;
-} SK_PNMI_VCT_TIMER;
-
-
-/*
- * PNMI specific adapter context structure
- */
-typedef struct s_PnmiPort {
-       SK_U64                  StatSyncCts;
-       SK_U64                  StatSyncOctetsCts;
-       SK_U64                  StatRxLongFrameCts;
-       SK_U64                  StatRxFrameTooLongCts;
-       SK_U64                  StatRxPMaccErr;
-       SK_U64                  TxSwQueueLen;
-       SK_U64                  TxSwQueueMax;
-       SK_U64                  TxRetryCts;
-       SK_U64                  RxIntrCts;
-       SK_U64                  TxIntrCts;
-       SK_U64                  RxNoBufCts;
-       SK_U64                  TxNoBufCts;
-       SK_U64                  TxUsedDescrNo;
-       SK_U64                  RxDeliveredCts;
-       SK_U64                  RxOctetsDeliveredCts;
-       SK_U64                  RxHwErrorsCts;
-       SK_U64                  TxHwErrorsCts;
-       SK_U64                  InErrorsCts;
-       SK_U64                  OutErrorsCts;
-       SK_U64                  ErrRecoveryCts;
-       SK_U64                  RxShortZeroMark;
-       SK_U64                  CounterOffset[SK_PNMI_CNT_NO];
-       SK_U32                  CounterHigh[SK_PNMI_CNT_NO];
-       SK_BOOL                 ActiveFlag;
-       SK_U8                   Align[3];
-} SK_PNMI_PORT;
-
-
-typedef struct s_PnmiData {
-       SK_PNMI_PORT    Port    [SK_MAX_MACS];
-       SK_PNMI_PORT    BufPort [SK_MAX_MACS]; /* 2002-09-13 pweber  */
-       SK_U64                  VirtualCounterOffset[SK_PNMI_CNT_NO];
-       SK_U32                  TestResult;
-       char                    HwVersion[10];
-       SK_U16                  Align01;
-
-       char                    *pDriverDescription;
-       char                    *pDriverVersion;
-       char                    *pDriverReleaseDate;
-       char                    *pDriverFileName;
-
-       int                             MacUpdatedFlag;
-       int                             RlmtUpdatedFlag;
-       int                             SirqUpdatedFlag;
-
-       SK_U64                  RlmtChangeCts;
-       SK_U64                  RlmtChangeTime;
-       SK_PNMI_ESTIMATE        RlmtChangeEstimate;
-       SK_U64                  RlmtChangeThreshold;
-
-       SK_U64                  StartUpTime;
-       SK_U32                  DeviceType;
-       char                    PciBusSpeed;
-       char                    PciBusWidth;
-       char                    Chipset;
-       char                    PMD;
-       char                    Connector;
-       SK_BOOL                 DualNetActiveFlag;
-       SK_U16                  Align02;
-
-       char                    TrapBuf[SK_PNMI_TRAP_QUEUE_LEN];
-       unsigned int    TrapBufFree;
-       unsigned int    TrapQueueBeg;
-       unsigned int    TrapQueueEnd;
-       unsigned int    TrapBufPad;
-       unsigned int    TrapUnique;
-       SK_U8           VctStatus[SK_MAX_MACS];
-       SK_PNMI_VCT     VctBackup[SK_MAX_MACS];
-       SK_PNMI_VCT_TIMER VctTimeout[SK_MAX_MACS];
-#ifdef SK_DIAG_SUPPORT
-       SK_U32                  DiagAttached;
-#endif /* SK_DIAG_SUPPORT */
-} SK_PNMI;
-
-
-/*
- * Function prototypes
- */
-extern int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int Level);
-extern int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void* pBuf,
-       unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
-extern int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf,
-       unsigned int *pLen, SK_U32 NetIndex);
-extern int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf,
-       unsigned int *pLen, SK_U32 NetIndex);
-extern int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf,
-       unsigned int *pLen, SK_U32 NetIndex);
-extern int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event,
-       SK_EVPARA Param);
-extern int SkPnmiGenIoctl(SK_AC *pAC, SK_IOC IoC, void * pBuf,
-       unsigned int * pLen, SK_U32 NetIndex);
-
-#endif
diff --git a/drivers/net/sk98lin/h/skgesirq.h b/drivers/net/sk98lin/h/skgesirq.h
deleted file mode 100644 (file)
index 3eec627..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/******************************************************************************
- *
- * Name:       skgesirq.h
- * Project:    Gigabit Ethernet Adapters, Common Modules
- * Version:    $Revision: 1.30 $
- * Date:       $Date: 2003/07/04 12:34:13 $
- * Purpose:    SK specific Gigabit Ethernet special IRQ functions
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect.
- *     (C)Copyright 2002-2003 Marvell.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-#ifndef _INC_SKGESIRQ_H_
-#define _INC_SKGESIRQ_H_
-
-/* Define return codes of SkGePortCheckUp and CheckShort */
-#define        SK_HW_PS_NONE           0       /* No action needed */
-#define        SK_HW_PS_RESTART        1       /* Restart needed */
-#define        SK_HW_PS_LINK           2       /* Link Up actions needed */
-
-/*
- * Define the Event the special IRQ/INI module can handle
- */
-#define SK_HWEV_WATIM                  1       /* Timeout for WA Errata #2 XMAC */
-#define SK_HWEV_PORT_START             2       /* Port Start Event by RLMT */
-#define SK_HWEV_PORT_STOP              3       /* Port Stop Event by RLMT */
-#define SK_HWEV_CLEAR_STAT             4       /* Clear Statistics by PNMI */
-#define SK_HWEV_UPDATE_STAT            5       /* Update Statistics by PNMI */
-#define SK_HWEV_SET_LMODE              6       /* Set Link Mode by PNMI */
-#define SK_HWEV_SET_FLOWMODE   7       /* Set Flow Control Mode by PNMI */
-#define SK_HWEV_SET_ROLE               8       /* Set Master/Slave (Role) by PNMI */
-#define SK_HWEV_SET_SPEED              9       /* Set Link Speed by PNMI */
-#define SK_HWEV_HALFDUP_CHK            10      /* Half Duplex Hangup Workaround */
-
-#define SK_WA_ACT_TIME         (5000000UL)     /* 5 sec */
-#define SK_WA_INA_TIME         (100000UL)      /* 100 msec */
-
-#define SK_HALFDUP_CHK_TIME    (10000UL)       /* 10 msec */
-
-/*
- * Define the error numbers and messages
- */
-#define SKERR_SIRQ_E001                (SK_ERRBASE_SIRQ+0)
-#define SKERR_SIRQ_E001MSG     "Unknown event"
-#define SKERR_SIRQ_E002                (SKERR_SIRQ_E001+1)
-#define SKERR_SIRQ_E002MSG     "Packet timeout RX1"
-#define SKERR_SIRQ_E003                (SKERR_SIRQ_E002+1)
-#define SKERR_SIRQ_E003MSG     "Packet timeout RX2"
-#define SKERR_SIRQ_E004                (SKERR_SIRQ_E003+1)
-#define SKERR_SIRQ_E004MSG     "MAC 1 not correctly initialized"
-#define SKERR_SIRQ_E005                (SKERR_SIRQ_E004+1)
-#define SKERR_SIRQ_E005MSG     "MAC 2 not correctly initialized"
-#define SKERR_SIRQ_E006                (SKERR_SIRQ_E005+1)
-#define SKERR_SIRQ_E006MSG     "CHECK failure R1"
-#define SKERR_SIRQ_E007                (SKERR_SIRQ_E006+1)
-#define SKERR_SIRQ_E007MSG     "CHECK failure R2"
-#define SKERR_SIRQ_E008                (SKERR_SIRQ_E007+1)
-#define SKERR_SIRQ_E008MSG     "CHECK failure XS1"
-#define SKERR_SIRQ_E009                (SKERR_SIRQ_E008+1)
-#define SKERR_SIRQ_E009MSG     "CHECK failure XA1"
-#define SKERR_SIRQ_E010                (SKERR_SIRQ_E009+1)
-#define SKERR_SIRQ_E010MSG     "CHECK failure XS2"
-#define SKERR_SIRQ_E011                (SKERR_SIRQ_E010+1)
-#define SKERR_SIRQ_E011MSG     "CHECK failure XA2"
-#define SKERR_SIRQ_E012                (SKERR_SIRQ_E011+1)
-#define SKERR_SIRQ_E012MSG     "unexpected IRQ Master error"
-#define SKERR_SIRQ_E013                (SKERR_SIRQ_E012+1)
-#define SKERR_SIRQ_E013MSG     "unexpected IRQ Status error"
-#define SKERR_SIRQ_E014                (SKERR_SIRQ_E013+1)
-#define SKERR_SIRQ_E014MSG     "Parity error on RAM (read)"
-#define SKERR_SIRQ_E015                (SKERR_SIRQ_E014+1)
-#define SKERR_SIRQ_E015MSG     "Parity error on RAM (write)"
-#define SKERR_SIRQ_E016                (SKERR_SIRQ_E015+1)
-#define SKERR_SIRQ_E016MSG     "Parity error MAC 1"
-#define SKERR_SIRQ_E017                (SKERR_SIRQ_E016+1)
-#define SKERR_SIRQ_E017MSG     "Parity error MAC 2"
-#define SKERR_SIRQ_E018                (SKERR_SIRQ_E017+1)
-#define SKERR_SIRQ_E018MSG     "Parity error RX 1"
-#define SKERR_SIRQ_E019                (SKERR_SIRQ_E018+1)
-#define SKERR_SIRQ_E019MSG     "Parity error RX 2"
-#define SKERR_SIRQ_E020                (SKERR_SIRQ_E019+1)
-#define SKERR_SIRQ_E020MSG     "MAC transmit FIFO underrun"
-#define SKERR_SIRQ_E021                (SKERR_SIRQ_E020+1)
-#define SKERR_SIRQ_E021MSG     "Spurious TWSI interrupt"
-#define SKERR_SIRQ_E022                (SKERR_SIRQ_E021+1)
-#define SKERR_SIRQ_E022MSG     "Cable pair swap error"
-#define SKERR_SIRQ_E023                (SKERR_SIRQ_E022+1)
-#define SKERR_SIRQ_E023MSG     "Auto-negotiation error"
-#define SKERR_SIRQ_E024                (SKERR_SIRQ_E023+1)
-#define SKERR_SIRQ_E024MSG     "FIFO overflow error"
-#define SKERR_SIRQ_E025                (SKERR_SIRQ_E024+1)
-#define SKERR_SIRQ_E025MSG     "2 Pair Downshift detected"
-
-extern void SkGeSirqIsr(SK_AC *pAC, SK_IOC IoC, SK_U32 Istatus);
-extern int  SkGeSirqEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para);
-extern void SkHWLinkDown(SK_AC *pAC, SK_IOC IoC, int Port);
-
-#endif /* _INC_SKGESIRQ_H_ */
diff --git a/drivers/net/sk98lin/h/ski2c.h b/drivers/net/sk98lin/h/ski2c.h
deleted file mode 100644 (file)
index 6a63f4a..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-/******************************************************************************
- *
- * Name:       ski2c.h
- * Project:    Gigabit Ethernet Adapters, TWSI-Module
- * Version:    $Revision: 1.35 $
- * Date:       $Date: 2003/10/20 09:06:30 $
- * Purpose:    Defines to access Voltage and Temperature Sensor
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect.
- *     (C)Copyright 2002-2003 Marvell.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/*
- * SKI2C.H     contains all I2C specific defines
- */
-
-#ifndef _SKI2C_H_
-#define _SKI2C_H_
-
-typedef struct  s_Sensor SK_SENSOR;
-
-#include "h/skgei2c.h"
-
-/*
- * Define the I2C events.
- */
-#define SK_I2CEV_IRQ   1       /* IRQ happened Event */
-#define SK_I2CEV_TIM   2       /* Timeout event */
-#define SK_I2CEV_CLEAR 3       /* Clear MIB Values */
-
-/*
- * Define READ and WRITE Constants.
- */
-#define I2C_READ       0
-#define I2C_WRITE      1
-#define I2C_BURST      1
-#define I2C_SINGLE     0
-
-#define SKERR_I2C_E001         (SK_ERRBASE_I2C+0)
-#define SKERR_I2C_E001MSG      "Sensor index unknown"
-#define SKERR_I2C_E002         (SKERR_I2C_E001+1)
-#define SKERR_I2C_E002MSG      "TWSI: transfer does not complete"
-#define SKERR_I2C_E003         (SKERR_I2C_E002+1)
-#define SKERR_I2C_E003MSG      "LM80: NAK on device send"
-#define SKERR_I2C_E004         (SKERR_I2C_E003+1)
-#define SKERR_I2C_E004MSG      "LM80: NAK on register send"
-#define SKERR_I2C_E005         (SKERR_I2C_E004+1)
-#define SKERR_I2C_E005MSG      "LM80: NAK on device (2) send"
-#define SKERR_I2C_E006         (SKERR_I2C_E005+1)
-#define SKERR_I2C_E006MSG      "Unknown event"
-#define SKERR_I2C_E007         (SKERR_I2C_E006+1)
-#define SKERR_I2C_E007MSG      "LM80 read out of state"
-#define SKERR_I2C_E008         (SKERR_I2C_E007+1)
-#define SKERR_I2C_E008MSG      "Unexpected sensor read completed"
-#define SKERR_I2C_E009         (SKERR_I2C_E008+1)
-#define SKERR_I2C_E009MSG      "WARNING: temperature sensor out of range"
-#define SKERR_I2C_E010         (SKERR_I2C_E009+1)
-#define SKERR_I2C_E010MSG      "WARNING: voltage sensor out of range"
-#define SKERR_I2C_E011         (SKERR_I2C_E010+1)
-#define SKERR_I2C_E011MSG      "ERROR: temperature sensor out of range"
-#define SKERR_I2C_E012         (SKERR_I2C_E011+1)
-#define SKERR_I2C_E012MSG      "ERROR: voltage sensor out of range"
-#define SKERR_I2C_E013         (SKERR_I2C_E012+1)
-#define SKERR_I2C_E013MSG      "ERROR: couldn't init sensor"
-#define SKERR_I2C_E014         (SKERR_I2C_E013+1)
-#define SKERR_I2C_E014MSG      "WARNING: fan sensor out of range"
-#define SKERR_I2C_E015         (SKERR_I2C_E014+1)
-#define SKERR_I2C_E015MSG      "ERROR: fan sensor out of range"
-#define SKERR_I2C_E016         (SKERR_I2C_E015+1)
-#define SKERR_I2C_E016MSG      "TWSI: active transfer does not complete"
-
-/*
- * Define Timeout values
- */
-#define SK_I2C_TIM_LONG                2000000L        /* 2 seconds */
-#define SK_I2C_TIM_SHORT        100000L        /* 100 milliseconds */
-#define SK_I2C_TIM_WATCH       1000000L        /* 1 second */
-
-/*
- * Define trap and error log hold times
- */
-#ifndef        SK_SEN_ERR_TR_HOLD
-#define SK_SEN_ERR_TR_HOLD             (4*SK_TICKS_PER_SEC)
-#endif
-#ifndef        SK_SEN_ERR_LOG_HOLD
-#define SK_SEN_ERR_LOG_HOLD            (60*SK_TICKS_PER_SEC)
-#endif
-#ifndef        SK_SEN_WARN_TR_HOLD
-#define SK_SEN_WARN_TR_HOLD            (15*SK_TICKS_PER_SEC)
-#endif
-#ifndef        SK_SEN_WARN_LOG_HOLD
-#define SK_SEN_WARN_LOG_HOLD   (15*60*SK_TICKS_PER_SEC)
-#endif
-
-/*
- * Defines for SenType
- */
-#define SK_SEN_UNKNOWN 0
-#define SK_SEN_TEMP            1
-#define SK_SEN_VOLT            2
-#define SK_SEN_FAN             3
-
-/*
- * Define for the SenErrorFlag
- */
-#define SK_SEN_ERR_NOT_PRESENT 0       /* Error Flag: Sensor not present */
-#define SK_SEN_ERR_OK                  1       /* Error Flag: O.K. */
-#define SK_SEN_ERR_WARN                        2       /* Error Flag: Warning */
-#define SK_SEN_ERR_ERR                 3       /* Error Flag: Error */
-#define SK_SEN_ERR_FAULTY              4       /* Error Flag: Faulty */
-
-/*
- * Define the Sensor struct
- */
-struct s_Sensor {
-       char    *SenDesc;                       /* Description */
-       int             SenType;                        /* Voltage or Temperature */
-       SK_I32  SenValue;                       /* Current value of the sensor */
-       SK_I32  SenThreErrHigh;         /* High error Threshhold of this sensor */
-       SK_I32  SenThreWarnHigh;        /* High warning Threshhold of this sensor */
-       SK_I32  SenThreErrLow;          /* Lower error Threshold of the sensor */
-       SK_I32  SenThreWarnLow;         /* Lower warning Threshold of the sensor */
-       int             SenErrFlag;                     /* Sensor indicated an error */
-       SK_BOOL SenInit;                        /* Is sensor initialized ? */
-       SK_U64  SenErrCts;                      /* Error trap counter */
-       SK_U64  SenWarnCts;                     /* Warning trap counter */
-       SK_U64  SenBegErrTS;            /* Begin error timestamp */
-       SK_U64  SenBegWarnTS;           /* Begin warning timestamp */
-       SK_U64  SenLastErrTrapTS;       /* Last error trap timestamp */
-       SK_U64  SenLastErrLogTS;        /* Last error log timestamp */
-       SK_U64  SenLastWarnTrapTS;      /* Last warning trap timestamp */
-       SK_U64  SenLastWarnLogTS;       /* Last warning log timestamp */
-       int             SenState;                       /* Sensor State (see HW specific include) */
-       int             (*SenRead)(SK_AC *pAC, SK_IOC IoC, struct s_Sensor *pSen);
-                                                               /* Sensors read function */
-       SK_U16  SenReg;                         /* Register Address for this sensor */
-       SK_U8   SenDev;                         /* Device Selection for this sensor */
-};
-
-typedef        struct  s_I2c {
-       SK_SENSOR       SenTable[SK_MAX_SENSORS];       /* Sensor Table */
-       int                     CurrSens;       /* Which sensor is currently queried */
-       int                     MaxSens;        /* Max. number of sensors */
-       int                     TimerMode;      /* Use the timer also to watch the state machine */
-       int                     InitLevel;      /* Initialized Level */
-#ifndef SK_DIAG
-       int                     DummyReads;     /* Number of non-checked dummy reads */
-       SK_TIMER        SenTimer;       /* Sensors timer */
-#endif /* !SK_DIAG */
-} SK_I2C;
-
-extern int SkI2cInit(SK_AC *pAC, SK_IOC IoC, int Level);
-#ifdef SK_DIAG
-extern SK_U32 SkI2cRead(SK_AC *pAC, SK_IOC IoC, int Dev, int Size, int Reg,
-                                                int Burst);
-#else /* !SK_DIAG */
-extern int SkI2cEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para);
-extern void SkI2cWaitIrq(SK_AC *pAC, SK_IOC IoC);
-extern void SkI2cIsr(SK_AC *pAC, SK_IOC IoC);
-#endif /* !SK_DIAG */
-#endif /* n_SKI2C_H */
-
diff --git a/drivers/net/sk98lin/h/skqueue.h b/drivers/net/sk98lin/h/skqueue.h
deleted file mode 100644 (file)
index 2ec40d4..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-/******************************************************************************
- *
- * Name:       skqueue.h
- * Project:    Gigabit Ethernet Adapters, Event Scheduler Module
- * Version:    $Revision: 1.16 $
- * Date:       $Date: 2003/09/16 12:50:32 $
- * Purpose:    Defines for the Event queue
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect GmbH.
- *     (C)Copyright 2002-2003 Marvell.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/*
- * SKQUEUE.H   contains all defines and types for the event queue
- */
-
-#ifndef _SKQUEUE_H_
-#define _SKQUEUE_H_
-
-
-/*
- * define the event classes to be served
- */
-#define        SKGE_DRV        1       /* Driver Event Class */
-#define        SKGE_RLMT       2       /* RLMT Event Class */
-#define        SKGE_I2C        3       /* I2C Event Class */
-#define        SKGE_PNMI       4       /* PNMI Event Class */
-#define        SKGE_CSUM       5       /* Checksum Event Class */
-#define        SKGE_HWAC       6       /* Hardware Access Event Class */
-
-#define        SKGE_SWT        9       /* Software Timer Event Class */
-#define        SKGE_LACP       10      /* LACP Aggregation Event Class */
-#define        SKGE_RSF        11      /* RSF Aggregation Event Class */
-#define        SKGE_MARKER     12      /* MARKER Aggregation Event Class */
-#define        SKGE_FD         13      /* FD Distributor Event Class */
-
-/*
- * define event queue as circular buffer
- */
-#define SK_MAX_EVENT   64
-
-/*
- * Parameter union for the Para stuff
- */
-typedef        union u_EvPara {
-       void    *pParaPtr;      /* Parameter Pointer */
-       SK_U64  Para64;         /* Parameter 64bit version */
-       SK_U32  Para32[2];      /* Parameter Array of 32bit parameters */
-} SK_EVPARA;
-
-/*
- * Event Queue
- *     skqueue.c
- * events are class/value pairs
- *     class   is addressee, e.g. RLMT, PNMI etc.
- *     value   is command, e.g. line state change, ring op change etc.
- */
-typedef        struct s_EventElem {
-       SK_U32          Class;                  /* Event class */
-       SK_U32          Event;                  /* Event value */
-       SK_EVPARA       Para;                   /* Event parameter */
-} SK_EVENTELEM;
-
-typedef        struct s_Queue {
-       SK_EVENTELEM    EvQueue[SK_MAX_EVENT];
-       SK_EVENTELEM    *EvPut;
-       SK_EVENTELEM    *EvGet;
-} SK_QUEUE;
-
-extern void SkEventInit(SK_AC *pAC, SK_IOC Ioc, int Level);
-extern void SkEventQueue(SK_AC *pAC, SK_U32 Class, SK_U32 Event,
-       SK_EVPARA Para);
-extern int SkEventDispatcher(SK_AC *pAC, SK_IOC Ioc);
-
-
-/* Define Error Numbers and messages */
-#define        SKERR_Q_E001    (SK_ERRBASE_QUEUE+0)
-#define        SKERR_Q_E001MSG "Event queue overflow"
-#define        SKERR_Q_E002    (SKERR_Q_E001+1)
-#define        SKERR_Q_E002MSG "Undefined event class"
-#endif /* _SKQUEUE_H_ */
-
diff --git a/drivers/net/sk98lin/h/skrlmt.h b/drivers/net/sk98lin/h/skrlmt.h
deleted file mode 100644 (file)
index ca75dfd..0000000
+++ /dev/null
@@ -1,438 +0,0 @@
-/******************************************************************************
- *
- * Name:       skrlmt.h
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.37 $
- * Date:       $Date: 2003/04/15 09:43:43 $
- * Purpose:    Header file for Redundant Link ManagemenT.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect GmbH.
- *     (C)Copyright 2002-2003 Marvell.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * Description:
- *
- * This is the header file for Redundant Link ManagemenT.
- *
- * Include File Hierarchy:
- *
- *     "skdrv1st.h"
- *     ...
- *     "sktypes.h"
- *     "skqueue.h"
- *     "skaddr.h"
- *     "skrlmt.h"
- *     ...
- *     "skdrv2nd.h"
- *
- ******************************************************************************/
-
-#ifndef __INC_SKRLMT_H
-#define __INC_SKRLMT_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* cplusplus */
-
-/* defines ********************************************************************/
-
-#define        SK_RLMT_NET_DOWN_TEMP   1       /* NET_DOWN due to last port down. */
-#define        SK_RLMT_NET_DOWN_FINAL  2       /* NET_DOWN due to RLMT_STOP. */
-
-/* ----- Default queue sizes - must be multiples of 8 KB ----- */
-
-/* Less than 8 KB free in RX queue => pause frames. */
-#define SK_RLMT_STANDBY_QRXSIZE        128     /* Size of rx standby queue in KB. */
-#define SK_RLMT_STANDBY_QXASIZE        32      /* Size of async standby queue in KB. */
-#define SK_RLMT_STANDBY_QXSSIZE        0       /* Size of sync standby queue in KB. */
-
-#define SK_RLMT_MAX_TX_BUF_SIZE        60      /* Maximum RLMT transmit size. */
-
-/* ----- PORT states ----- */
-
-#define SK_RLMT_PS_INIT                        0       /* Port state: Init. */
-#define SK_RLMT_PS_LINK_DOWN   1       /* Port state: Link down. */
-#define SK_RLMT_PS_DOWN                        2       /* Port state: Port down. */
-#define SK_RLMT_PS_GOING_UP            3       /* Port state: Going up. */
-#define SK_RLMT_PS_UP                  4       /* Port state: Up. */
-
-/* ----- RLMT states ----- */
-
-#define SK_RLMT_RS_INIT                        0       /* RLMT state: Init. */
-#define SK_RLMT_RS_NET_DOWN            1       /* RLMT state: Net down. */
-#define SK_RLMT_RS_NET_UP              2       /* RLMT state: Net up. */
-
-/* ----- PORT events ----- */
-
-#define SK_RLMT_LINK_UP                        1001    /* Link came up. */
-#define SK_RLMT_LINK_DOWN              1002    /* Link went down. */
-#define SK_RLMT_PORT_ADDR              1003    /* Port address changed. */
-
-/* ----- RLMT events ----- */
-
-#define SK_RLMT_START                  2001    /* Start RLMT. */
-#define SK_RLMT_STOP                   2002    /* Stop RLMT. */
-#define SK_RLMT_PACKET_RECEIVED        2003    /* Packet was received for RLMT. */
-#define SK_RLMT_STATS_CLEAR            2004    /* Clear statistics. */
-#define SK_RLMT_STATS_UPDATE   2005    /* Update statistics. */
-#define SK_RLMT_PREFPORT_CHANGE        2006    /* Change preferred port. */
-#define SK_RLMT_MODE_CHANGE            2007    /* New RlmtMode. */
-#define SK_RLMT_SET_NETS               2008    /* Number of Nets (1 or 2). */
-
-/* ----- RLMT mode bits ----- */
-
-/*
- * CAUTION:    These defines are private to RLMT.
- *                     Please use the RLMT mode defines below.
- */
-
-#define SK_RLMT_CHECK_LINK               1             /* Check Link. */
-#define SK_RLMT_CHECK_LOC_LINK   2             /* Check other link on same adapter. */
-#define SK_RLMT_CHECK_SEG                4             /* Check segmentation. */
-
-#ifndef RLMT_CHECK_REMOTE
-#define SK_RLMT_CHECK_OTHERS   SK_RLMT_CHECK_LOC_LINK
-#else  /* RLMT_CHECK_REMOTE */
-#define SK_RLMT_CHECK_REM_LINK   8             /* Check link(s) on other adapter(s). */
-#define SK_RLMT_MAX_REMOTE_PORTS_CHECKED       3
-#define SK_RLMT_CHECK_OTHERS   \
-               (SK_RLMT_CHECK_LOC_LINK | SK_RLMT_CHECK_REM_LINK)
-#endif /* RLMT_CHECK_REMOTE */
-
-#ifndef SK_RLMT_ENABLE_TRANSPARENT
-#define SK_RLMT_TRANSPARENT              0             /* RLMT transparent - inactive. */
-#else  /* SK_RLMT_ENABLE_TRANSPARENT */
-#define SK_RLMT_TRANSPARENT            128             /* RLMT transparent. */
-#endif /* SK_RLMT_ENABLE_TRANSPARENT */
-
-/* ----- RLMT modes ----- */
-
-/* Check Link State. */
-#define SK_RLMT_MODE_CLS       (SK_RLMT_CHECK_LINK)
-
-/* Check Local Ports: check other links on the same adapter. */
-#define SK_RLMT_MODE_CLP       (SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK)
-
-/* Check Local Ports and Segmentation Status. */
-#define SK_RLMT_MODE_CLPSS     \
-               (SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK | SK_RLMT_CHECK_SEG)
-
-#ifdef RLMT_CHECK_REMOTE
-/* Check Local and Remote Ports: check links (local or remote). */
-       Name of define TBD!
-#define SK_RLMT_MODE_CRP       \
-               (SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK | SK_RLMT_CHECK_REM_LINK)
-
-/* Check Local and Remote Ports and Segmentation Status. */
-       Name of define TBD!
-#define SK_RLMT_MODE_CRPSS     \
-               (SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK | \
-               SK_RLMT_CHECK_REM_LINK | SK_RLMT_CHECK_SEG)
-#endif /* RLMT_CHECK_REMOTE */
-
-/* ----- RLMT lookahead result bits ----- */
-
-#define SK_RLMT_RX_RLMT                        1       /* Give packet to RLMT. */
-#define SK_RLMT_RX_PROTOCOL            2       /* Give packet to protocol. */
-
-/* Macros */
-
-#if 0
-SK_AC          *pAC            /* adapter context */
-SK_U32         PortNum         /* receiving port */
-unsigned       PktLen          /* received packet's length */
-SK_BOOL                IsBc            /* Flag: packet is broadcast */
-unsigned       *pOffset        /* offs. of bytes to present to SK_RLMT_LOOKAHEAD */
-unsigned       *pNumBytes      /* #Bytes to present to SK_RLMT_LOOKAHEAD */
-#endif /* 0 */
-
-#define SK_RLMT_PRE_LOOKAHEAD(pAC,PortNum,PktLen,IsBc,pOffset,pNumBytes) { \
-       SK_AC   *_pAC; \
-       SK_U32  _PortNum; \
-       _pAC = (pAC); \
-       _PortNum = (SK_U32)(PortNum); \
-       /* _pAC->Rlmt.Port[_PortNum].PacketsRx++; */ \
-       _pAC->Rlmt.Port[_PortNum].PacketsPerTimeSlot++; \
-    if (_pAC->Rlmt.RlmtOff) { \
-               *(pNumBytes) = 0; \
-    } \
-    else {\
-        if ((_pAC->Rlmt.Port[_PortNum].Net->RlmtMode & SK_RLMT_TRANSPARENT) != 0) { \
-               *(pNumBytes) = 0; \
-       } \
-       else if (IsBc) { \
-               if (_pAC->Rlmt.Port[_PortNum].Net->RlmtMode != SK_RLMT_MODE_CLS) { \
-                       *(pNumBytes) = 6; \
-                       *(pOffset) = 6; \
-               } \
-               else { \
-                       *(pNumBytes) = 0; \
-               } \
-       } \
-       else { \
-               if ((PktLen) > SK_RLMT_MAX_TX_BUF_SIZE) { \
-                       /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \
-                       *(pNumBytes) = 0; \
-               } \
-               else { \
-                       *(pNumBytes) = 6; \
-                       *(pOffset) = 0; \
-               } \
-       } \
-    } \
-}
-
-#if 0
-SK_AC          *pAC            /* adapter context */
-SK_U32         PortNum         /* receiving port */
-SK_U8          *pLaPacket,     /* received packet's data (points to pOffset) */
-SK_BOOL                IsBc            /* Flag: packet is broadcast */
-SK_BOOL                IsMc            /* Flag: packet is multicast */
-unsigned       *pForRlmt       /* Result: bits SK_RLMT_RX_RLMT, SK_RLMT_RX_PROTOCOL */
-SK_RLMT_LOOKAHEAD() expects *pNumBytes from
-packet offset *pOffset (s.a.) at *pLaPacket.
-
-If you use SK_RLMT_LOOKAHEAD in a path where you already know if the packet is
-BC, MC, or UC, you should use constants for IsBc and IsMc, so that your compiler
-can trash unneeded parts of the if construction.
-#endif /* 0 */
-
-#define SK_RLMT_LOOKAHEAD(pAC,PortNum,pLaPacket,IsBc,IsMc,pForRlmt) { \
-       SK_AC   *_pAC; \
-       SK_U32  _PortNum; \
-       SK_U8   *_pLaPacket; \
-       _pAC = (pAC); \
-       _PortNum = (SK_U32)(PortNum); \
-       _pLaPacket = (SK_U8 *)(pLaPacket); \
-       if (IsBc) {\
-               if (!SK_ADDR_EQUAL(_pLaPacket, _pAC->Addr.Net[_pAC->Rlmt.Port[ \
-                       _PortNum].Net->NetNumber].CurrentMacAddress.a)) { \
-                       _pAC->Rlmt.Port[_PortNum].BcTimeStamp = SkOsGetTime(_pAC); \
-                       _pAC->Rlmt.CheckSwitch = SK_TRUE; \
-               } \
-               /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \
-               *(pForRlmt) = SK_RLMT_RX_PROTOCOL; \
-       } \
-       else if (IsMc) { \
-               if (SK_ADDR_EQUAL(_pLaPacket, BridgeMcAddr.a)) { \
-                       _pAC->Rlmt.Port[_PortNum].BpduPacketsPerTimeSlot++; \
-                       if (_pAC->Rlmt.Port[_PortNum].Net->RlmtMode & SK_RLMT_CHECK_SEG) { \
-                               *(pForRlmt) = SK_RLMT_RX_RLMT | SK_RLMT_RX_PROTOCOL; \
-                       } \
-                       else { \
-                               *(pForRlmt) = SK_RLMT_RX_PROTOCOL; \
-                       } \
-               } \
-               else if (SK_ADDR_EQUAL(_pLaPacket, SkRlmtMcAddr.a)) { \
-                       *(pForRlmt) = SK_RLMT_RX_RLMT; \
-               } \
-               else { \
-                       /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \
-                       *(pForRlmt) = SK_RLMT_RX_PROTOCOL; \
-               } \
-       } \
-       else { \
-               if (SK_ADDR_EQUAL( \
-                       _pLaPacket, \
-                       _pAC->Addr.Port[_PortNum].CurrentMacAddress.a)) { \
-                       *(pForRlmt) = SK_RLMT_RX_RLMT; \
-               } \
-               else { \
-                       /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \
-                       *(pForRlmt) = SK_RLMT_RX_PROTOCOL; \
-               } \
-       } \
-}
-
-#ifdef SK_RLMT_FAST_LOOKAHEAD
-Error: SK_RLMT_FAST_LOOKAHEAD no longer used. Use new macros for lookahead.
-#endif /* SK_RLMT_FAST_LOOKAHEAD */
-#ifdef SK_RLMT_SLOW_LOOKAHEAD
-Error: SK_RLMT_SLOW_LOOKAHEAD no longer used. Use new macros for lookahead.
-#endif /* SK_RLMT_SLOW_LOOKAHEAD */
-
-/* typedefs *******************************************************************/
-
-#ifdef SK_RLMT_MBUF_PRIVATE
-typedef struct s_RlmtMbuf {
-       some content
-} SK_RLMT_MBUF;
-#endif /* SK_RLMT_MBUF_PRIVATE */
-
-
-#ifdef SK_LA_INFO
-typedef struct s_Rlmt_PacketInfo {
-       unsigned        PacketLength;                   /* Length of packet. */
-       unsigned        PacketType;                             /* Directed/Multicast/Broadcast. */
-} SK_RLMT_PINFO;
-#endif /* SK_LA_INFO */
-
-
-typedef struct s_RootId {
-       SK_U8           Id[8];                                  /* Root Bridge Id. */
-} SK_RLMT_ROOT_ID;
-
-
-typedef struct s_port {
-       SK_MAC_ADDR     CheckAddr;
-       SK_BOOL         SuspectTx;
-} SK_PORT_CHECK;
-
-
-typedef struct s_RlmtNet SK_RLMT_NET;
-
-
-typedef struct s_RlmtPort {
-
-/* ----- Public part (read-only) ----- */
-
-       SK_U8                   PortState;                              /* Current state of this port. */
-
-       /* For PNMI */
-       SK_BOOL                 LinkDown;
-       SK_BOOL                 PortDown;
-       SK_U8                   Align01;
-
-       SK_U32                  PortNumber;                             /* Number of port on adapter. */
-       SK_RLMT_NET *   Net;                                    /* Net port belongs to. */
-
-       SK_U64                  TxHelloCts;
-       SK_U64                  RxHelloCts;
-       SK_U64                  TxSpHelloReqCts;
-       SK_U64                  RxSpHelloCts;
-
-/* ----- Private part ----- */
-
-/*     SK_U64                  PacketsRx; */                           /* Total packets received. */
-       SK_U32                  PacketsPerTimeSlot;             /* Packets rxed between TOs. */
-/*     SK_U32                  DataPacketsPerTimeSlot; */      /* Data packets ... */
-       SK_U32                  BpduPacketsPerTimeSlot; /* BPDU packets rxed in TS. */
-       SK_U64                  BcTimeStamp;                    /* Time of last BC receive. */
-       SK_U64                  GuTimeStamp;                    /* Time of entering GOING_UP. */
-
-       SK_TIMER                UpTimer;                                /* Timer struct Link/Port up. */
-       SK_TIMER                DownRxTimer;                    /* Timer struct down rx. */
-       SK_TIMER                DownTxTimer;                    /* Timer struct down tx. */
-
-       SK_U32                  CheckingState;                  /* Checking State. */
-
-       SK_ADDR_PORT *  AddrPort;
-
-       SK_U8                   Random[4];                              /* Random value. */
-       unsigned                PortsChecked;                   /* #ports checked. */
-       unsigned                PortsSuspect;                   /* #ports checked that are s. */
-       SK_PORT_CHECK   PortCheck[1];
-/*     SK_PORT_CHECK   PortCheck[SK_MAX_MACS - 1]; */
-
-       SK_BOOL                 PortStarted;                    /* Port is started. */
-       SK_BOOL                 PortNoRx;                               /* NoRx for >= 1 time slot. */
-       SK_BOOL                 RootIdSet;
-       SK_RLMT_ROOT_ID Root;                                   /* Root Bridge Id. */
-} SK_RLMT_PORT;
-
-
-struct s_RlmtNet {
-
-/* ----- Public part (read-only) ----- */
-
-       SK_U32                  NetNumber;                      /* Number of net. */
-
-       SK_RLMT_PORT *  Port[SK_MAX_MACS];      /* Ports that belong to this net. */
-       SK_U32                  NumPorts;                       /* Number of ports. */
-       SK_U32                  PrefPort;                       /* Preferred port. */
-
-       /* For PNMI */
-
-       SK_U32                  ChgBcPrio;                      /* Change Priority of last broadcast received */
-       SK_U32                  RlmtMode;                       /* Check ... */
-       SK_U32                  ActivePort;                     /* Active port. */
-       SK_U32                  Preference;             /* 0xFFFFFFFF: Automatic. */
-
-       SK_U8                   RlmtState;                      /* Current RLMT state. */
-
-/* ----- Private part ----- */
-       SK_BOOL                 RootIdSet;
-       SK_U16                  Align01;
-
-       int                             LinksUp;                        /* #Links up. */
-       int                             PortsUp;                        /* #Ports up. */
-       SK_U32                  TimeoutValue;           /* RLMT timeout value. */
-
-       SK_U32                  CheckingState;          /* Checking State. */
-       SK_RLMT_ROOT_ID Root;                           /* Root Bridge Id. */
-
-       SK_TIMER                LocTimer;                       /* Timer struct. */
-       SK_TIMER                SegTimer;                       /* Timer struct. */
-};
-
-
-typedef struct s_Rlmt {
-
-/* ----- Public part (read-only) ----- */
-
-       SK_U32                  NumNets;                        /* Number of nets. */
-       SK_U32                  NetsStarted;            /* Number of nets started. */
-       SK_RLMT_NET             Net[SK_MAX_NETS];       /* Array of available nets. */
-       SK_RLMT_PORT    Port[SK_MAX_MACS];      /* Array of available ports. */
-
-/* ----- Private part ----- */
-       SK_BOOL                 CheckSwitch;
-       SK_BOOL                 RlmtOff;            /* set to zero if the Mac addresses 
-                                           are equal or the second one 
-                                           is zero */
-       SK_U16                  Align01;
-
-} SK_RLMT;
-
-
-extern SK_MAC_ADDR     BridgeMcAddr;
-extern SK_MAC_ADDR     SkRlmtMcAddr;
-
-/* function prototypes ********************************************************/
-
-
-#ifndef SK_KR_PROTO
-
-/* Functions provided by SkRlmt */
-
-/* ANSI/C++ compliant function prototypes */
-
-extern void    SkRlmtInit(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       int             Level);
-
-extern int     SkRlmtEvent(
-       SK_AC           *pAC,
-       SK_IOC          IoC,
-       SK_U32          Event,
-       SK_EVPARA       Para);
-
-#else  /* defined(SK_KR_PROTO) */
-
-/* Non-ANSI/C++ compliant function prototypes */
-
-#error KR-style function prototypes are not yet provided.
-
-#endif /* defined(SK_KR_PROTO)) */
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __INC_SKRLMT_H */
diff --git a/drivers/net/sk98lin/h/sktimer.h b/drivers/net/sk98lin/h/sktimer.h
deleted file mode 100644 (file)
index 04e6d7c..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/******************************************************************************
- *
- * Name:       sktimer.h
- * Project:    Gigabit Ethernet Adapters, Event Scheduler Module
- * Version:    $Revision: 1.11 $
- * Date:       $Date: 2003/09/16 12:58:18 $
- * Purpose:    Defines for the timer functions
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect GmbH.
- *     (C)Copyright 2002-2003 Marvell.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/*
- * SKTIMER.H   contains all defines and types for the timer functions
- */
-
-#ifndef        _SKTIMER_H_
-#define _SKTIMER_H_
-
-#include "h/skqueue.h"
-
-/*
- * SK timer
- * - needed wherever a timer is used. Put this in your data structure
- *   wherever you want.
- */
-typedef        struct s_Timer SK_TIMER;
-
-struct s_Timer {
-       SK_TIMER        *TmNext;        /* linked list */
-       SK_U32          TmClass;        /* Timer Event class */
-       SK_U32          TmEvent;        /* Timer Event value */
-       SK_EVPARA       TmPara;         /* Timer Event parameter */
-       SK_U32          TmDelta;        /* delta time */
-       int                     TmActive;       /* flag: active/inactive */
-};
-
-/*
- * Timer control struct.
- * - use in Adapters context name pAC->Tim
- */
-typedef        struct s_TimCtrl {
-       SK_TIMER        *StQueue;       /* Head of Timer queue */
-} SK_TIMCTRL;
-
-extern void SkTimerInit(SK_AC *pAC, SK_IOC Ioc, int Level);
-extern void SkTimerStop(SK_AC *pAC, SK_IOC Ioc, SK_TIMER *pTimer);
-extern void SkTimerStart(SK_AC *pAC, SK_IOC Ioc, SK_TIMER *pTimer,
-       SK_U32 Time, SK_U32 Class, SK_U32 Event, SK_EVPARA Para);
-extern void SkTimerDone(SK_AC *pAC, SK_IOC Ioc);
-#endif /* _SKTIMER_H_ */
diff --git a/drivers/net/sk98lin/h/sktypes.h b/drivers/net/sk98lin/h/sktypes.h
deleted file mode 100644 (file)
index 40edc96..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/******************************************************************************
- *
- * Name:       sktypes.h
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.2 $
- * Date:       $Date: 2003/10/07 08:16:51 $
- * Purpose:    Define data types for Linux
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect GmbH.
- *     (C)Copyright 2002-2003 Marvell.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-/******************************************************************************
- *
- * Description:
- *
- * In this file, all data types that are needed by the common modules
- * are mapped to Linux data types.
- * 
- *
- * Include File Hierarchy:
- *
- *
- ******************************************************************************/
-
-#ifndef __INC_SKTYPES_H
-#define __INC_SKTYPES_H
-
-
-/* defines *******************************************************************/
-
-/*
- * Data types with a specific size. 'I' = signed, 'U' = unsigned.
- */
-#define SK_I8  s8
-#define SK_U8  u8
-#define SK_I16 s16
-#define SK_U16 u16
-#define SK_I32 s32
-#define SK_U32 u32
-#define SK_I64 s64
-#define SK_U64 u64
-
-#define SK_UPTR        ulong           /* casting pointer <-> integral */
-
-/*
-* Boolean type.
-*/
-#define SK_BOOL                SK_U8
-#define SK_FALSE       0
-#define SK_TRUE                (!SK_FALSE)
-
-/* typedefs *******************************************************************/
-
-/* function prototypes ********************************************************/
-
-#endif /* __INC_SKTYPES_H */
diff --git a/drivers/net/sk98lin/h/skversion.h b/drivers/net/sk98lin/h/skversion.h
deleted file mode 100644 (file)
index a1a7294..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/******************************************************************************
- *
- * Name:       version.h
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.5 $
- * Date:       $Date: 2003/10/07 08:16:51 $
- * Purpose:    SK specific Error log support
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect GmbH.
- *     (C)Copyright 2002-2003 Marvell.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-#ifdef lint
-static const char SysKonnectFileId[] = "@(#) (C) SysKonnect GmbH.";
-static const char SysKonnectBuildNumber[] =
-       "@(#)SK-BUILD: 6.23 PL: 01"; 
-#endif /* !defined(lint) */
-
-#define BOOT_STRING    "sk98lin: Network Device Driver v6.23\n" \
-                       "(C)Copyright 1999-2004 Marvell(R)."
-
-#define VER_STRING     "6.23"
-#define DRIVER_FILE_NAME       "sk98lin"
-#define DRIVER_REL_DATE                "Feb-13-2004"
-
-
diff --git a/drivers/net/sk98lin/h/skvpd.h b/drivers/net/sk98lin/h/skvpd.h
deleted file mode 100644 (file)
index fdd9e48..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-/******************************************************************************
- *
- * Name:       skvpd.h
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.15 $
- * Date:       $Date: 2003/01/13 10:39:38 $
- * Purpose:    Defines and Macros for VPD handling
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2003 SysKonnect GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/*
- * skvpd.h     contains Diagnostic specific defines for VPD handling
- */
-
-#ifndef __INC_SKVPD_H_
-#define __INC_SKVPD_H_
-
-/*
- * Define Resource Type Identifiers and VPD keywords
- */
-#define        RES_ID          0x82    /* Resource Type ID String (Product Name) */
-#define RES_VPD_R      0x90    /* start of VPD read only area */
-#define RES_VPD_W      0x91    /* start of VPD read/write area */
-#define RES_END                0x78    /* Resource Type End Tag */
-
-#ifndef VPD_NAME
-#define VPD_NAME       "Name"  /* Product Name, VPD name of RES_ID */
-#endif /* VPD_NAME */
-#define VPD_PN         "PN"    /* Adapter Part Number */
-#define        VPD_EC          "EC"    /* Adapter Engineering Level */
-#define VPD_MN         "MN"    /* Manufacture ID */
-#define VPD_SN         "SN"    /* Serial Number */
-#define VPD_CP         "CP"    /* Extended Capability */
-#define VPD_RV         "RV"    /* Checksum and Reserved */
-#define        VPD_YA          "YA"    /* Asset Tag Identifier */
-#define VPD_VL         "VL"    /* First Error Log Message (SK specific) */
-#define VPD_VF         "VF"    /* Second Error Log Message (SK specific) */
-#define VPD_RW         "RW"    /* Remaining Read / Write Area */
-
-/* 'type' values for vpd_setup_para() */
-#define VPD_RO_KEY     1       /* RO keys are "PN", "EC", "MN", "SN", "RV" */
-#define VPD_RW_KEY     2       /* RW keys are "Yx", "Vx", and "RW" */
-
-/* 'op' values for vpd_setup_para() */
-#define        ADD_KEY         1       /* add the key at the pos "RV" or "RW" */
-#define OWR_KEY                2       /* overwrite key if already exists */
-
-/*
- * Define READ and WRITE Constants.
- */
-
-#define VPD_DEV_ID_GENESIS     0x4300
-
-#define        VPD_SIZE_YUKON          256
-#define        VPD_SIZE_GENESIS        512
-#define        VPD_SIZE                        512
-#define VPD_READ       0x0000
-#define VPD_WRITE      0x8000
-
-#define VPD_STOP(pAC,IoC)      VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG,VPD_WRITE)
-
-#define VPD_GET_RES_LEN(p)     ((unsigned int) \
-                                       (* (SK_U8 *)&(p)[1]) |\
-                                       ((* (SK_U8 *)&(p)[2]) << 8))
-#define VPD_GET_VPD_LEN(p)     ((unsigned int)(* (SK_U8 *)&(p)[2]))
-#define VPD_GET_VAL(p)         ((char *)&(p)[3])
-
-#define VPD_MAX_LEN    50
-
-/* VPD status */
-       /* bit 7..1 reserved */
-#define VPD_VALID      (1<<0)  /* VPD data buffer, vpd_free_ro, */
-                                                       /* and vpd_free_rw valid         */
-
-/*
- * VPD structs
- */
-typedef        struct s_vpd_status {
-       unsigned short  Align01;                        /* Alignment */
-       unsigned short  vpd_status;                     /* VPD status, description see above */
-       int                             vpd_free_ro;            /* unused bytes in read only area */
-       int                             vpd_free_rw;            /* bytes available in read/write area */
-} SK_VPD_STATUS;
-
-typedef        struct s_vpd {
-       SK_VPD_STATUS   v;                                      /* VPD status structure */
-       char                    vpd_buf[VPD_SIZE];      /* VPD buffer */
-       int                             rom_size;                       /* VPD ROM Size from PCI_OUR_REG_2 */
-       int                             vpd_size;                       /* saved VPD-size */
-} SK_VPD;
-
-typedef        struct s_vpd_para {
-       unsigned int    p_len;  /* parameter length */
-       char                    *p_val; /* points to the value */
-} SK_VPD_PARA;
-
-/*
- * structure of Large Resource Type Identifiers
- */
-
-/* was removed because of alignment problems */
-
-/*
- * structure of VPD keywords
- */
-typedef        struct s_vpd_key {
-       char                    p_key[2];       /* 2 bytes ID string */
-       unsigned char   p_len;          /* 1 byte length */
-       char                    p_val;          /* start of the value string */
-} SK_VPD_KEY;
-
-
-/*
- * System specific VPD macros
- */
-#ifndef SKDIAG
-#ifndef VPD_DO_IO
-#define VPD_OUT8(pAC,IoC,Addr,Val)     (void)SkPciWriteCfgByte(pAC,Addr,Val)
-#define VPD_OUT16(pAC,IoC,Addr,Val)    (void)SkPciWriteCfgWord(pAC,Addr,Val)
-#define VPD_IN8(pAC,IoC,Addr,pVal)     (void)SkPciReadCfgByte(pAC,Addr,pVal)
-#define VPD_IN16(pAC,IoC,Addr,pVal)    (void)SkPciReadCfgWord(pAC,Addr,pVal)
-#define VPD_IN32(pAC,IoC,Addr,pVal)    (void)SkPciReadCfgDWord(pAC,Addr,pVal)
-#else  /* VPD_DO_IO */
-#define VPD_OUT8(pAC,IoC,Addr,Val)     SK_OUT8(IoC,PCI_C(Addr),Val)
-#define VPD_OUT16(pAC,IoC,Addr,Val)    SK_OUT16(IoC,PCI_C(Addr),Val)
-#define VPD_IN8(pAC,IoC,Addr,pVal)     SK_IN8(IoC,PCI_C(Addr),pVal)
-#define VPD_IN16(pAC,IoC,Addr,pVal)    SK_IN16(IoC,PCI_C(Addr),pVal)
-#define VPD_IN32(pAC,IoC,Addr,pVal)    SK_IN32(IoC,PCI_C(Addr),pVal)
-#endif /* VPD_DO_IO */
-#else  /* SKDIAG */
-#define VPD_OUT8(pAC,Ioc,Addr,Val) {                   \
-               if ((pAC)->DgT.DgUseCfgCycle)                   \
-                       SkPciWriteCfgByte(pAC,Addr,Val);        \
-               else                                                                    \
-                       SK_OUT8(pAC,PCI_C(Addr),Val);           \
-               }
-#define VPD_OUT16(pAC,Ioc,Addr,Val) {                  \
-               if ((pAC)->DgT.DgUseCfgCycle)                   \
-                       SkPciWriteCfgWord(pAC,Addr,Val);        \
-               else                                            \
-                       SK_OUT16(pAC,PCI_C(Addr),Val);          \
-               }
-#define VPD_IN8(pAC,Ioc,Addr,pVal) {                   \
-               if ((pAC)->DgT.DgUseCfgCycle)                   \
-                       SkPciReadCfgByte(pAC,Addr,pVal);        \
-               else                                            \
-                       SK_IN8(pAC,PCI_C(Addr),pVal);           \
-               }
-#define VPD_IN16(pAC,Ioc,Addr,pVal) {                  \
-               if ((pAC)->DgT.DgUseCfgCycle)                   \
-                       SkPciReadCfgWord(pAC,Addr,pVal);        \
-               else                                            \
-                       SK_IN16(pAC,PCI_C(Addr),pVal);          \
-               }
-#define VPD_IN32(pAC,Ioc,Addr,pVal) {                  \
-               if ((pAC)->DgT.DgUseCfgCycle)                   \
-                       SkPciReadCfgDWord(pAC,Addr,pVal);       \
-               else                                            \
-                       SK_IN32(pAC,PCI_C(Addr),pVal);          \
-               }
-#endif /* nSKDIAG */
-
-/* function prototypes ********************************************************/
-
-#ifndef        SK_KR_PROTO
-#ifdef SKDIAG
-extern SK_U32  VpdReadDWord(
-       SK_AC           *pAC,
-       SK_IOC          IoC,
-       int                     addr);
-#endif /* SKDIAG */
-
-extern SK_VPD_STATUS   *VpdStat(
-       SK_AC           *pAC,
-       SK_IOC          IoC);
-
-extern int     VpdKeys(
-       SK_AC           *pAC,
-       SK_IOC          IoC,
-       char            *buf,
-       int                     *len,
-       int                     *elements);
-
-extern int     VpdRead(
-       SK_AC           *pAC,
-       SK_IOC          IoC,
-       const char      *key,
-       char            *buf,
-       int                     *len);
-
-extern SK_BOOL VpdMayWrite(
-       char            *key);
-
-extern int     VpdWrite(
-       SK_AC           *pAC,
-       SK_IOC          IoC,
-       const char      *key,
-       const char      *buf);
-
-extern int     VpdDelete(
-       SK_AC           *pAC,
-       SK_IOC          IoC,
-       char            *key);
-
-extern int     VpdUpdate(
-       SK_AC           *pAC,
-       SK_IOC          IoC);
-
-#ifdef SKDIAG
-extern int     VpdReadBlock(
-       SK_AC           *pAC,
-       SK_IOC          IoC,
-       char            *buf,
-       int                     addr,
-       int                     len);
-
-extern int     VpdWriteBlock(
-       SK_AC           *pAC,
-       SK_IOC          IoC,
-       char            *buf,
-       int                     addr,
-       int                     len);
-#endif /* SKDIAG */
-#else  /* SK_KR_PROTO */
-extern SK_U32  VpdReadDWord();
-extern SK_VPD_STATUS   *VpdStat();
-extern int     VpdKeys();
-extern int     VpdRead();
-extern SK_BOOL VpdMayWrite();
-extern int     VpdWrite();
-extern int     VpdDelete();
-extern int     VpdUpdate();
-#endif /* SK_KR_PROTO */
-
-#endif /* __INC_SKVPD_H_ */
diff --git a/drivers/net/sk98lin/h/xmac_ii.h b/drivers/net/sk98lin/h/xmac_ii.h
deleted file mode 100644 (file)
index 7f8e6d0..0000000
+++ /dev/null
@@ -1,1579 +0,0 @@
-/******************************************************************************
- *
- * Name:       xmac_ii.h
- * Project:    Gigabit Ethernet Adapters, Common Modules
- * Version:    $Revision: 1.52 $
- * Date:       $Date: 2003/10/02 16:35:50 $
- * Purpose:    Defines and Macros for Gigabit Ethernet Controller
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect.
- *     (C)Copyright 2002-2003 Marvell.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-#ifndef __INC_XMAC_H
-#define __INC_XMAC_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/* defines ********************************************************************/
-
-/*
- * XMAC II registers
- *
- * The XMAC registers are 16 or 32 bits wide.
- * The XMACs host processor interface is set to 16 bit mode,
- * therefore ALL registers will be addressed with 16 bit accesses.
- *
- * The following macros are provided to access the XMAC registers
- * XM_IN16(), XM_OUT16, XM_IN32(), XM_OUT32(), XM_INADR(), XM_OUTADR(),
- * XM_INHASH(), and XM_OUTHASH().
- * The macros are defined in SkGeHw.h.
- *
- * Note:       NA reg  = Network Address e.g DA, SA etc.
- *
- */
-#define XM_MMU_CMD             0x0000  /* 16 bit r/w   MMU Command Register */
-       /* 0x0004:              reserved */
-#define XM_POFF                        0x0008  /* 32 bit r/w   Packet Offset Register */
-#define XM_BURST               0x000c  /* 32 bit r/w   Burst Register for half duplex*/
-#define XM_1L_VLAN_TAG 0x0010  /* 16 bit r/w   One Level VLAN Tag ID */
-#define XM_2L_VLAN_TAG 0x0014  /* 16 bit r/w   Two Level VLAN Tag ID */
-       /* 0x0018 - 0x001e:     reserved */
-#define XM_TX_CMD              0x0020  /* 16 bit r/w   Transmit Command Register */
-#define XM_TX_RT_LIM   0x0024  /* 16 bit r/w   Transmit Retry Limit Register */
-#define XM_TX_STIME            0x0028  /* 16 bit r/w   Transmit Slottime Register */
-#define XM_TX_IPG              0x002c  /* 16 bit r/w   Transmit Inter Packet Gap */
-#define XM_RX_CMD              0x0030  /* 16 bit r/w   Receive Command Register */
-#define XM_PHY_ADDR            0x0034  /* 16 bit r/w   PHY Address Register */
-#define XM_PHY_DATA            0x0038  /* 16 bit r/w   PHY Data Register */
-       /* 0x003c:              reserved */
-#define XM_GP_PORT             0x0040  /* 32 bit r/w   General Purpose Port Register */
-#define XM_IMSK                        0x0044  /* 16 bit r/w   Interrupt Mask Register */
-#define XM_ISRC                        0x0048  /* 16 bit r/o   Interrupt Status Register */
-#define XM_HW_CFG              0x004c  /* 16 bit r/w   Hardware Config Register */
-       /* 0x0050 - 0x005e:     reserved */
-#define XM_TX_LO_WM            0x0060  /* 16 bit r/w   Tx FIFO Low Water Mark */
-#define XM_TX_HI_WM            0x0062  /* 16 bit r/w   Tx FIFO High Water Mark */
-#define XM_TX_THR              0x0064  /* 16 bit r/w   Tx Request Threshold */
-#define XM_HT_THR              0x0066  /* 16 bit r/w   Host Request Threshold */
-#define XM_PAUSE_DA            0x0068  /* NA reg r/w   Pause Destination Address */
-       /* 0x006e:              reserved */
-#define XM_CTL_PARA            0x0070  /* 32 bit r/w   Control Parameter Register */
-#define XM_MAC_OPCODE  0x0074  /* 16 bit r/w   Opcode for MAC control frames */
-#define XM_MAC_PTIME   0x0076  /* 16 bit r/w   Pause time for MAC ctrl frames*/
-#define XM_TX_STAT             0x0078  /* 32 bit r/o   Tx Status LIFO Register */
-
-       /* 0x0080 - 0x00fc:     16 NA reg r/w   Exact Match Address Registers */
-       /*                              use the XM_EXM() macro to address */
-#define XM_EXM_START   0x0080  /* r/w  Start Address of the EXM Regs */
-
-       /*
-        * XM_EXM(Reg)
-        *
-        * returns the XMAC address offset of specified Exact Match Addr Reg
-        *
-        * para:        Reg     EXM register to addr    (0 .. 15)
-        *
-        * usage:       XM_INADDR(IoC, MAC_1, XM_EXM(i), &val[i]);
-        */
-#define XM_EXM(Reg)    (XM_EXM_START + ((Reg) << 3))
-
-#define XM_SRC_CHK             0x0100  /* NA reg r/w   Source Check Address Register */
-#define XM_SA                  0x0108  /* NA reg r/w   Station Address Register */
-#define XM_HSM                 0x0110  /* 64 bit r/w   Hash Match Address Registers */
-#define XM_RX_LO_WM            0x0118  /* 16 bit r/w   Receive Low Water Mark */
-#define XM_RX_HI_WM            0x011a  /* 16 bit r/w   Receive High Water Mark */
-#define XM_RX_THR              0x011c  /* 32 bit r/w   Receive Request Threshold */
-#define XM_DEV_ID              0x0120  /* 32 bit r/o   Device ID Register */
-#define XM_MODE                        0x0124  /* 32 bit r/w   Mode Register */
-#define XM_LSA                 0x0128  /* NA reg r/o   Last Source Register */
-       /* 0x012e:              reserved */
-#define XM_TS_READ             0x0130  /* 32 bit r/o   Time Stamp Read Register */
-#define XM_TS_LOAD             0x0134  /* 32 bit r/o   Time Stamp Load Value */
-       /* 0x0138 - 0x01fe:     reserved */
-#define XM_STAT_CMD    0x0200  /* 16 bit r/w   Statistics Command Register */
-#define XM_RX_CNT_EV   0x0204  /* 32 bit r/o   Rx Counter Event Register */
-#define XM_TX_CNT_EV   0x0208  /* 32 bit r/o   Tx Counter Event Register */
-#define XM_RX_EV_MSK   0x020c  /* 32 bit r/w   Rx Counter Event Mask */
-#define XM_TX_EV_MSK   0x0210  /* 32 bit r/w   Tx Counter Event Mask */
-       /* 0x0204 - 0x027e:     reserved */
-#define XM_TXF_OK              0x0280  /* 32 bit r/o   Frames Transmitted OK Conuter */
-#define XM_TXO_OK_HI   0x0284  /* 32 bit r/o   Octets Transmitted OK High Cnt*/
-#define XM_TXO_OK_LO   0x0288  /* 32 bit r/o   Octets Transmitted OK Low Cnt */
-#define XM_TXF_BC_OK   0x028c  /* 32 bit r/o   Broadcast Frames Xmitted OK */
-#define XM_TXF_MC_OK   0x0290  /* 32 bit r/o   Multicast Frames Xmitted OK */
-#define XM_TXF_UC_OK   0x0294  /* 32 bit r/o   Unicast Frames Xmitted OK */
-#define XM_TXF_LONG            0x0298  /* 32 bit r/o   Tx Long Frame Counter */
-#define XM_TXE_BURST   0x029c  /* 32 bit r/o   Tx Burst Event Counter */
-#define XM_TXF_MPAUSE  0x02a0  /* 32 bit r/o   Tx Pause MAC Ctrl Frame Cnt */
-#define XM_TXF_MCTRL   0x02a4  /* 32 bit r/o   Tx MAC Ctrl Frame Counter */
-#define XM_TXF_SNG_COL 0x02a8  /* 32 bit r/o   Tx Single Collision Counter */
-#define XM_TXF_MUL_COL 0x02ac  /* 32 bit r/o   Tx Multiple Collision Counter */
-#define XM_TXF_ABO_COL 0x02b0  /* 32 bit r/o   Tx aborted due to Exces. Col. */
-#define XM_TXF_LAT_COL 0x02b4  /* 32 bit r/o   Tx Late Collision Counter */
-#define XM_TXF_DEF             0x02b8  /* 32 bit r/o   Tx Deferred Frame Counter */
-#define XM_TXF_EX_DEF  0x02bc  /* 32 bit r/o   Tx Excessive Deferall Counter */
-#define XM_TXE_FIFO_UR 0x02c0  /* 32 bit r/o   Tx FIFO Underrun Event Cnt */
-#define XM_TXE_CS_ERR  0x02c4  /* 32 bit r/o   Tx Carrier Sense Error Cnt */
-#define XM_TXP_UTIL            0x02c8  /* 32 bit r/o   Tx Utilization in % */
-       /* 0x02cc - 0x02ce:     reserved */
-#define XM_TXF_64B             0x02d0  /* 32 bit r/o   64 Byte Tx Frame Counter */
-#define XM_TXF_127B            0x02d4  /* 32 bit r/o   65-127 Byte Tx Frame Counter */
-#define XM_TXF_255B            0x02d8  /* 32 bit r/o   128-255 Byte Tx Frame Counter */
-#define XM_TXF_511B            0x02dc  /* 32 bit r/o   256-511 Byte Tx Frame Counter */
-#define XM_TXF_1023B   0x02e0  /* 32 bit r/o   512-1023 Byte Tx Frame Counter*/
-#define XM_TXF_MAX_SZ  0x02e4  /* 32 bit r/o   1024-MaxSize Byte Tx Frame Cnt*/
-       /* 0x02e8 - 0x02fe:     reserved */
-#define XM_RXF_OK              0x0300  /* 32 bit r/o   Frames Received OK */
-#define XM_RXO_OK_HI   0x0304  /* 32 bit r/o   Octets Received OK High Cnt */
-#define XM_RXO_OK_LO   0x0308  /* 32 bit r/o   Octets Received OK Low Counter*/
-#define XM_RXF_BC_OK   0x030c  /* 32 bit r/o   Broadcast Frames Received OK */
-#define XM_RXF_MC_OK   0x0310  /* 32 bit r/o   Multicast Frames Received OK */
-#define XM_RXF_UC_OK   0x0314  /* 32 bit r/o   Unicast Frames Received OK */
-#define XM_RXF_MPAUSE  0x0318  /* 32 bit r/o   Rx Pause MAC Ctrl Frame Cnt */
-#define XM_RXF_MCTRL   0x031c  /* 32 bit r/o   Rx MAC Ctrl Frame Counter */
-#define XM_RXF_INV_MP  0x0320  /* 32 bit r/o   Rx invalid Pause Frame Cnt */
-#define XM_RXF_INV_MOC 0x0324  /* 32 bit r/o   Rx Frames with inv. MAC Opcode*/
-#define XM_RXE_BURST   0x0328  /* 32 bit r/o   Rx Burst Event Counter */
-#define XM_RXE_FMISS   0x032c  /* 32 bit r/o   Rx Missed Frames Event Cnt */
-#define XM_RXF_FRA_ERR 0x0330  /* 32 bit r/o   Rx Framing Error Counter */
-#define XM_RXE_FIFO_OV 0x0334  /* 32 bit r/o   Rx FIFO overflow Event Cnt */
-#define XM_RXF_JAB_PKT 0x0338  /* 32 bit r/o   Rx Jabber Packet Frame Cnt */
-#define XM_RXE_CAR_ERR 0x033c  /* 32 bit r/o   Rx Carrier Event Error Cnt */
-#define XM_RXF_LEN_ERR 0x0340  /* 32 bit r/o   Rx in Range Length Error */
-#define XM_RXE_SYM_ERR 0x0344  /* 32 bit r/o   Rx Symbol Error Counter */
-#define XM_RXE_SHT_ERR 0x0348  /* 32 bit r/o   Rx Short Event Error Cnt */
-#define XM_RXE_RUNT            0x034c  /* 32 bit r/o   Rx Runt Event Counter */
-#define XM_RXF_LNG_ERR 0x0350  /* 32 bit r/o   Rx Frame too Long Error Cnt */
-#define XM_RXF_FCS_ERR 0x0354  /* 32 bit r/o   Rx Frame Check Seq. Error Cnt */
-       /* 0x0358 - 0x035a:     reserved */
-#define XM_RXF_CEX_ERR 0x035c  /* 32 bit r/o   Rx Carrier Ext Error Frame Cnt*/
-#define XM_RXP_UTIL            0x0360  /* 32 bit r/o   Rx Utilization in % */
-       /* 0x0364 - 0x0366:     reserved */
-#define XM_RXF_64B             0x0368  /* 32 bit r/o   64 Byte Rx Frame Counter */
-#define XM_RXF_127B            0x036c  /* 32 bit r/o   65-127 Byte Rx Frame Counter */
-#define XM_RXF_255B            0x0370  /* 32 bit r/o   128-255 Byte Rx Frame Counter */
-#define XM_RXF_511B            0x0374  /* 32 bit r/o   256-511 Byte Rx Frame Counter */
-#define XM_RXF_1023B   0x0378  /* 32 bit r/o   512-1023 Byte Rx Frame Counter*/
-#define XM_RXF_MAX_SZ  0x037c  /* 32 bit r/o   1024-MaxSize Byte Rx Frame Cnt*/
-       /* 0x02e8 - 0x02fe:     reserved */
-
-
-/*----------------------------------------------------------------------------*/
-/*
- * XMAC Bit Definitions
- *
- * If the bit access behaviour differs from the register access behaviour
- * (r/w, r/o) this is documented after the bit number.
- * The following bit access behaviours are used:
- *     (sc)    self clearing
- *     (ro)    read only
- */
-
-/*     XM_MMU_CMD      16 bit r/w      MMU Command Register */
-                                                               /* Bit 15..13:  reserved */
-#define XM_MMU_PHY_RDY (1<<12) /* Bit 12:      PHY Read Ready */
-#define XM_MMU_PHY_BUSY        (1<<11) /* Bit 11:      PHY Busy */
-#define XM_MMU_IGN_PF  (1<<10) /* Bit 10:      Ignore Pause Frame */
-#define XM_MMU_MAC_LB  (1<<9)  /* Bit  9:      Enable MAC Loopback */
-                                                               /* Bit  8:      reserved */
-#define XM_MMU_FRC_COL (1<<7)  /* Bit  7:      Force Collision */
-#define XM_MMU_SIM_COL (1<<6)  /* Bit  6:      Simulate Collision */
-#define XM_MMU_NO_PRE  (1<<5)  /* Bit  5:      No MDIO Preamble */
-#define XM_MMU_GMII_FD (1<<4)  /* Bit  4:      GMII uses Full Duplex */
-#define XM_MMU_RAT_CTRL        (1<<3)  /* Bit  3:      Enable Rate Control */
-#define XM_MMU_GMII_LOOP (1<<2)        /* Bit  2:      PHY is in Loopback Mode */
-#define XM_MMU_ENA_RX  (1<<1)  /* Bit  1:      Enable Receiver */
-#define XM_MMU_ENA_TX  (1<<0)  /* Bit  0:      Enable Transmitter */
-
-
-/*     XM_TX_CMD       16 bit r/w      Transmit Command Register */
-                                                               /* Bit 15..7:   reserved */
-#define XM_TX_BK2BK            (1<<6)  /* Bit  6:      Ignor Carrier Sense (Tx Bk2Bk)*/
-#define XM_TX_ENC_BYP  (1<<5)  /* Bit  5:      Set Encoder in Bypass Mode */
-#define XM_TX_SAM_LINE (1<<4)  /* Bit  4: (sc) Start utilization calculation */
-#define XM_TX_NO_GIG_MD        (1<<3)  /* Bit  3:      Disable Carrier Extension */
-#define XM_TX_NO_PRE   (1<<2)  /* Bit  2:      Disable Preamble Generation */
-#define XM_TX_NO_CRC   (1<<1)  /* Bit  1:      Disable CRC Generation */
-#define XM_TX_AUTO_PAD (1<<0)  /* Bit  0:      Enable Automatic Padding */
-
-
-/*     XM_TX_RT_LIM    16 bit r/w      Transmit Retry Limit Register */
-                                                               /* Bit 15..5:   reserved */
-#define XM_RT_LIM_MSK  0x1f    /* Bit  4..0:   Tx Retry Limit */
-
-
-/*     XM_TX_STIME     16 bit r/w      Transmit Slottime Register */
-                                                               /* Bit 15..7:   reserved */
-#define XM_STIME_MSK   0x7f    /* Bit  6..0:   Tx Slottime bits */
-
-
-/*     XM_TX_IPG       16 bit r/w      Transmit Inter Packet Gap */
-                                                               /* Bit 15..8:   reserved */
-#define XM_IPG_MSK             0xff    /* Bit  7..0:   IPG value bits */
-
-
-/*     XM_RX_CMD       16 bit r/w      Receive Command Register */
-                                                               /* Bit 15..9:   reserved */
-#define XM_RX_LENERR_OK (1<<8) /* Bit  8       don't set Rx Err bit for */
-                                                               /*              inrange error packets */
-#define XM_RX_BIG_PK_OK        (1<<7)  /* Bit  7       don't set Rx Err bit for */
-                                                               /*              jumbo packets */
-#define XM_RX_IPG_CAP  (1<<6)  /* Bit  6       repl. type field with IPG */
-#define XM_RX_TP_MD            (1<<5)  /* Bit  5:      Enable transparent Mode */
-#define XM_RX_STRIP_FCS        (1<<4)  /* Bit  4:      Enable FCS Stripping */
-#define XM_RX_SELF_RX  (1<<3)  /* Bit  3:      Enable Rx of own packets */
-#define XM_RX_SAM_LINE (1<<2)  /* Bit  2: (sc) Start utilization calculation */
-#define XM_RX_STRIP_PAD        (1<<1)  /* Bit  1:      Strip pad bytes of Rx frames */
-#define XM_RX_DIS_CEXT (1<<0)  /* Bit  0:      Disable carrier ext. check */
-
-
-/*     XM_PHY_ADDR     16 bit r/w      PHY Address Register */
-                                                               /* Bit 15..5:   reserved */
-#define XM_PHY_ADDR_SZ 0x1f    /* Bit  4..0:   PHY Address bits */
-
-
-/*     XM_GP_PORT      32 bit r/w      General Purpose Port Register */
-                                                               /* Bit 31..7:   reserved */
-#define XM_GP_ANIP             (1L<<6) /* Bit  6: (ro) Auto-Neg. in progress */
-#define XM_GP_FRC_INT  (1L<<5) /* Bit  5: (sc) Force Interrupt */
-                                                               /* Bit  4:      reserved */
-#define XM_GP_RES_MAC  (1L<<3) /* Bit  3: (sc) Reset MAC and FIFOs */
-#define XM_GP_RES_STAT (1L<<2) /* Bit  2: (sc) Reset the statistics module */
-                                                               /* Bit  1:      reserved */
-#define XM_GP_INP_ASS  (1L<<0) /* Bit  0: (ro) GP Input Pin asserted */
-
-
-/*     XM_IMSK         16 bit r/w      Interrupt Mask Register */
-/*     XM_ISRC         16 bit r/o      Interrupt Status Register */
-                                                               /* Bit 15:      reserved */
-#define XM_IS_LNK_AE   (1<<14) /* Bit 14:      Link Asynchronous Event */
-#define XM_IS_TX_ABORT (1<<13) /* Bit 13:      Transmit Abort, late Col. etc */
-#define XM_IS_FRC_INT  (1<<12) /* Bit 12:      Force INT bit set in GP */
-#define XM_IS_INP_ASS  (1<<11) /* Bit 11:      Input Asserted, GP bit 0 set */
-#define XM_IS_LIPA_RC  (1<<10) /* Bit 10:      Link Partner requests config */
-#define XM_IS_RX_PAGE  (1<<9)  /* Bit  9:      Page Received */
-#define XM_IS_TX_PAGE  (1<<8)  /* Bit  8:      Next Page Loaded for Transmit */
-#define XM_IS_AND              (1<<7)  /* Bit  7:      Auto-Negotiation Done */
-#define XM_IS_TSC_OV   (1<<6)  /* Bit  6:      Time Stamp Counter Overflow */
-#define XM_IS_RXC_OV   (1<<5)  /* Bit  5:      Rx Counter Event Overflow */
-#define XM_IS_TXC_OV   (1<<4)  /* Bit  4:      Tx Counter Event Overflow */
-#define XM_IS_RXF_OV   (1<<3)  /* Bit  3:      Receive FIFO Overflow */
-#define XM_IS_TXF_UR   (1<<2)  /* Bit  2:      Transmit FIFO Underrun */
-#define XM_IS_TX_COMP  (1<<1)  /* Bit  1:      Frame Tx Complete */
-#define XM_IS_RX_COMP  (1<<0)  /* Bit  0:      Frame Rx Complete */
-
-#define XM_DEF_MSK     (~(XM_IS_INP_ASS | XM_IS_LIPA_RC | XM_IS_RX_PAGE |\
-                       XM_IS_AND | XM_IS_RXC_OV | XM_IS_TXC_OV | XM_IS_TXF_UR))
-
-
-/*     XM_HW_CFG       16 bit r/w      Hardware Config Register */
-                                                               /* Bit 15.. 4:  reserved */
-#define XM_HW_GEN_EOP  (1<<3)  /* Bit  3:      generate End of Packet pulse */
-#define XM_HW_COM4SIG  (1<<2)  /* Bit  2:      use Comma Detect for Sig. Det.*/
-                                                               /* Bit  1:      reserved */
-#define XM_HW_GMII_MD  (1<<0)  /* Bit  0:      GMII Interface selected */
-
-
-/*     XM_TX_LO_WM     16 bit r/w      Tx FIFO Low Water Mark */
-/*     XM_TX_HI_WM     16 bit r/w      Tx FIFO High Water Mark */
-                                                               /* Bit 15..10   reserved */
-#define XM_TX_WM_MSK   0x01ff  /* Bit  9.. 0   Tx FIFO Watermark bits */
-
-/*     XM_TX_THR       16 bit r/w      Tx Request Threshold */
-/*     XM_HT_THR       16 bit r/w      Host Request Threshold */
-/*     XM_RX_THR       16 bit r/w      Rx Request Threshold */
-                                                               /* Bit 15..11   reserved */
-#define XM_THR_MSK             0x03ff  /* Bit 10.. 0   Rx/Tx Request Threshold bits */
-
-
-/*     XM_TX_STAT      32 bit r/o      Tx Status LIFO Register */
-#define XM_ST_VALID            (1UL<<31)       /* Bit 31:      Status Valid */
-#define XM_ST_BYTE_CNT (0x3fffL<<17)   /* Bit 30..17:  Tx frame Length */
-#define XM_ST_RETRY_CNT        (0x1fL<<12)     /* Bit 16..12:  Retry Count */
-#define XM_ST_EX_COL   (1L<<11)        /* Bit 11:      Excessive Collisions */
-#define XM_ST_EX_DEF   (1L<<10)        /* Bit 10:      Excessive Deferral */
-#define XM_ST_BURST            (1L<<9)         /* Bit  9:      p. xmitted in burst md*/
-#define XM_ST_DEFER            (1L<<8)         /* Bit  8:      packet was defered */
-#define XM_ST_BC               (1L<<7)         /* Bit  7:      Broadcast packet */
-#define XM_ST_MC               (1L<<6)         /* Bit  6:      Multicast packet */
-#define XM_ST_UC               (1L<<5)         /* Bit  5:      Unicast packet */
-#define XM_ST_TX_UR            (1L<<4)         /* Bit  4:      FIFO Underrun occured */
-#define XM_ST_CS_ERR   (1L<<3)         /* Bit  3:      Carrier Sense Error */
-#define XM_ST_LAT_COL  (1L<<2)         /* Bit  2:      Late Collision Error */
-#define XM_ST_MUL_COL  (1L<<1)         /* Bit  1:      Multiple Collisions */
-#define XM_ST_SGN_COL  (1L<<0)         /* Bit  0:      Single Collision */
-
-/*     XM_RX_LO_WM     16 bit r/w      Receive Low Water Mark */
-/*     XM_RX_HI_WM     16 bit r/w      Receive High Water Mark */
-                                                                       /* Bit 15..11:  reserved */
-#define XM_RX_WM_MSK   0x03ff          /* Bit 11.. 0:  Rx FIFO Watermark bits */
-
-
-/*     XM_DEV_ID       32 bit r/o      Device ID Register */
-#define XM_DEV_OUI     (0x00ffffffUL<<8)       /* Bit 31..8:   Device OUI */
-#define XM_DEV_REV     (0x07L << 5)            /* Bit  7..5:   Chip Rev Num */
-
-
-/*     XM_MODE         32 bit r/w      Mode Register */
-                                                                       /* Bit 31..27:  reserved */
-#define XM_MD_ENA_REJ  (1L<<26)        /* Bit 26:      Enable Frame Reject */
-#define XM_MD_SPOE_E   (1L<<25)        /* Bit 25:      Send Pause on Edge */
-                                                                       /*              extern generated */
-#define XM_MD_TX_REP   (1L<<24)        /* Bit 24:      Transmit Repeater Mode */
-#define XM_MD_SPOFF_I  (1L<<23)        /* Bit 23:      Send Pause on FIFO full */
-                                                                       /*              intern generated */
-#define XM_MD_LE_STW   (1L<<22)        /* Bit 22:      Rx Stat Word in Little Endian */
-#define XM_MD_TX_CONT  (1L<<21)        /* Bit 21:      Send Continuous */
-#define XM_MD_TX_PAUSE (1L<<20)        /* Bit 20: (sc) Send Pause Frame */
-#define XM_MD_ATS              (1L<<19)        /* Bit 19:      Append Time Stamp */
-#define XM_MD_SPOL_I   (1L<<18)        /* Bit 18:      Send Pause on Low */
-                                                                       /*              intern generated */
-#define XM_MD_SPOH_I   (1L<<17)        /* Bit 17:      Send Pause on High */
-                                                                       /*              intern generated */
-#define XM_MD_CAP              (1L<<16)        /* Bit 16:      Check Address Pair */
-#define XM_MD_ENA_HASH (1L<<15)        /* Bit 15:      Enable Hashing */
-#define XM_MD_CSA              (1L<<14)        /* Bit 14:      Check Station Address */
-#define XM_MD_CAA              (1L<<13)        /* Bit 13:      Check Address Array */
-#define XM_MD_RX_MCTRL (1L<<12)        /* Bit 12:      Rx MAC Control Frame */
-#define XM_MD_RX_RUNT  (1L<<11)        /* Bit 11:      Rx Runt Frames */
-#define XM_MD_RX_IRLE  (1L<<10)        /* Bit 10:      Rx in Range Len Err Frame */
-#define XM_MD_RX_LONG  (1L<<9)         /* Bit  9:      Rx Long Frame */
-#define XM_MD_RX_CRCE  (1L<<8)         /* Bit  8:      Rx CRC Error Frame */
-#define XM_MD_RX_ERR   (1L<<7)         /* Bit  7:      Rx Error Frame */
-#define XM_MD_DIS_UC   (1L<<6)         /* Bit  6:      Disable Rx Unicast */
-#define XM_MD_DIS_MC   (1L<<5)         /* Bit  5:      Disable Rx Multicast */
-#define XM_MD_DIS_BC   (1L<<4)         /* Bit  4:      Disable Rx Broadcast */
-#define XM_MD_ENA_PROM (1L<<3)         /* Bit  3:      Enable Promiscuous */
-#define XM_MD_ENA_BE   (1L<<2)         /* Bit  2:      Enable Big Endian */
-#define XM_MD_FTF              (1L<<1)         /* Bit  1: (sc) Flush Tx FIFO */
-#define XM_MD_FRF              (1L<<0)         /* Bit  0: (sc) Flush Rx FIFO */
-
-#define XM_PAUSE_MODE  (XM_MD_SPOE_E | XM_MD_SPOL_I | XM_MD_SPOH_I)
-#define XM_DEF_MODE            (XM_MD_RX_RUNT | XM_MD_RX_IRLE | XM_MD_RX_LONG |\
-                               XM_MD_RX_CRCE | XM_MD_RX_ERR | XM_MD_CSA | XM_MD_CAA)
-
-/*     XM_STAT_CMD     16 bit r/w      Statistics Command Register */
-                                                               /* Bit 16..6:   reserved */
-#define XM_SC_SNP_RXC  (1<<5)  /* Bit  5: (sc) Snap Rx Counters */
-#define XM_SC_SNP_TXC  (1<<4)  /* Bit  4: (sc) Snap Tx Counters */
-#define XM_SC_CP_RXC   (1<<3)  /* Bit  3:      Copy Rx Counters Continuously */
-#define XM_SC_CP_TXC   (1<<2)  /* Bit  2:      Copy Tx Counters Continuously */
-#define XM_SC_CLR_RXC  (1<<1)  /* Bit  1: (sc) Clear Rx Counters */
-#define XM_SC_CLR_TXC  (1<<0)  /* Bit  0: (sc) Clear Tx Counters */
-
-
-/*     XM_RX_CNT_EV    32 bit r/o      Rx Counter Event Register */
-/*     XM_RX_EV_MSK    32 bit r/w      Rx Counter Event Mask */
-#define XMR_MAX_SZ_OV  (1UL<<31)       /* Bit 31:      1024-MaxSize Rx Cnt Ov*/
-#define XMR_1023B_OV   (1L<<30)        /* Bit 30:      512-1023Byte Rx Cnt Ov*/
-#define XMR_511B_OV            (1L<<29)        /* Bit 29:      256-511 Byte Rx Cnt Ov*/
-#define XMR_255B_OV            (1L<<28)        /* Bit 28:      128-255 Byte Rx Cnt Ov*/
-#define XMR_127B_OV            (1L<<27)        /* Bit 27:      65-127 Byte Rx Cnt Ov */
-#define XMR_64B_OV             (1L<<26)        /* Bit 26:      64 Byte Rx Cnt Ov */
-#define XMR_UTIL_OV            (1L<<25)        /* Bit 25:      Rx Util Cnt Overflow */
-#define XMR_UTIL_UR            (1L<<24)        /* Bit 24:      Rx Util Cnt Underrun */
-#define XMR_CEX_ERR_OV (1L<<23)        /* Bit 23:      CEXT Err Cnt Ov */
-                                                                       /* Bit 22:      reserved */
-#define XMR_FCS_ERR_OV (1L<<21)        /* Bit 21:      Rx FCS Error Cnt Ov */
-#define XMR_LNG_ERR_OV (1L<<20)        /* Bit 20:      Rx too Long Err Cnt Ov*/
-#define XMR_RUNT_OV            (1L<<19)        /* Bit 19:      Runt Event Cnt Ov */
-#define XMR_SHT_ERR_OV (1L<<18)        /* Bit 18:      Rx Short Ev Err Cnt Ov*/
-#define XMR_SYM_ERR_OV (1L<<17)        /* Bit 17:      Rx Sym Err Cnt Ov */
-                                                                       /* Bit 16:      reserved */
-#define XMR_CAR_ERR_OV (1L<<15)        /* Bit 15:      Rx Carr Ev Err Cnt Ov */
-#define XMR_JAB_PKT_OV (1L<<14)        /* Bit 14:      Rx Jabb Packet Cnt Ov */
-#define XMR_FIFO_OV            (1L<<13)        /* Bit 13:      Rx FIFO Ov Ev Cnt Ov */
-#define XMR_FRA_ERR_OV (1L<<12)        /* Bit 12:      Rx Framing Err Cnt Ov */
-#define XMR_FMISS_OV   (1L<<11)        /* Bit 11:      Rx Missed Ev Cnt Ov */
-#define XMR_BURST              (1L<<10)        /* Bit 10:      Rx Burst Event Cnt Ov */
-#define XMR_INV_MOC            (1L<<9)         /* Bit  9:      Rx with inv. MAC OC Ov*/
-#define XMR_INV_MP             (1L<<8)         /* Bit  8:      Rx inv Pause Frame Ov */
-#define XMR_MCTRL_OV   (1L<<7)         /* Bit  7:      Rx MAC Ctrl-F Cnt Ov */
-#define XMR_MPAUSE_OV  (1L<<6)         /* Bit  6:      Rx Pause MAC Ctrl-F Ov*/
-#define XMR_UC_OK_OV   (1L<<5)         /* Bit  5:      Rx Unicast Frame CntOv*/
-#define XMR_MC_OK_OV   (1L<<4)         /* Bit  4:      Rx Multicast Cnt Ov */
-#define XMR_BC_OK_OV   (1L<<3)         /* Bit  3:      Rx Broadcast Cnt Ov */
-#define XMR_OK_LO_OV   (1L<<2)         /* Bit  2:      Octets Rx OK Low CntOv*/
-#define XMR_OK_HI_OV   (1L<<1)         /* Bit  1:      Octets Rx OK Hi Cnt Ov*/
-#define XMR_OK_OV              (1L<<0)         /* Bit  0:      Frames Received Ok Ov */
-
-#define XMR_DEF_MSK            (XMR_OK_LO_OV | XMR_OK_HI_OV)
-
-/*     XM_TX_CNT_EV    32 bit r/o      Tx Counter Event Register */
-/*     XM_TX_EV_MSK    32 bit r/w      Tx Counter Event Mask */
-                                                                       /* Bit 31..26:  reserved */
-#define XMT_MAX_SZ_OV  (1L<<25)        /* Bit 25:      1024-MaxSize Tx Cnt Ov*/
-#define XMT_1023B_OV   (1L<<24)        /* Bit 24:      512-1023Byte Tx Cnt Ov*/
-#define XMT_511B_OV            (1L<<23)        /* Bit 23:      256-511 Byte Tx Cnt Ov*/
-#define XMT_255B_OV            (1L<<22)        /* Bit 22:      128-255 Byte Tx Cnt Ov*/
-#define XMT_127B_OV            (1L<<21)        /* Bit 21:      65-127 Byte Tx Cnt Ov */
-#define XMT_64B_OV             (1L<<20)        /* Bit 20:      64 Byte Tx Cnt Ov */
-#define XMT_UTIL_OV            (1L<<19)        /* Bit 19:      Tx Util Cnt Overflow */
-#define XMT_UTIL_UR            (1L<<18)        /* Bit 18:      Tx Util Cnt Underrun */
-#define XMT_CS_ERR_OV  (1L<<17)        /* Bit 17:      Tx Carr Sen Err Cnt Ov*/
-#define XMT_FIFO_UR_OV (1L<<16)        /* Bit 16:      Tx FIFO Ur Ev Cnt Ov */
-#define XMT_EX_DEF_OV  (1L<<15)        /* Bit 15:      Tx Ex Deferall Cnt Ov */
-#define XMT_DEF                        (1L<<14)        /* Bit 14:      Tx Deferred Cnt Ov */
-#define XMT_LAT_COL_OV (1L<<13)        /* Bit 13:      Tx Late Col Cnt Ov */
-#define XMT_ABO_COL_OV (1L<<12)        /* Bit 12:      Tx abo dueto Ex Col Ov*/
-#define XMT_MUL_COL_OV (1L<<11)        /* Bit 11:      Tx Mult Col Cnt Ov */
-#define XMT_SNG_COL            (1L<<10)        /* Bit 10:      Tx Single Col Cnt Ov */
-#define XMT_MCTRL_OV   (1L<<9)         /* Bit  9:      Tx MAC Ctrl Counter Ov*/
-#define XMT_MPAUSE             (1L<<8)         /* Bit  8:      Tx Pause MAC Ctrl-F Ov*/
-#define XMT_BURST              (1L<<7)         /* Bit  7:      Tx Burst Event Cnt Ov */
-#define XMT_LONG               (1L<<6)         /* Bit  6:      Tx Long Frame Cnt Ov */
-#define XMT_UC_OK_OV   (1L<<5)         /* Bit  5:      Tx Unicast Cnt Ov */
-#define XMT_MC_OK_OV   (1L<<4)         /* Bit  4:      Tx Multicast Cnt Ov */
-#define XMT_BC_OK_OV   (1L<<3)         /* Bit  3:      Tx Broadcast Cnt Ov */
-#define XMT_OK_LO_OV   (1L<<2)         /* Bit  2:      Octets Tx OK Low CntOv*/
-#define XMT_OK_HI_OV   (1L<<1)         /* Bit  1:      Octets Tx OK Hi Cnt Ov*/
-#define XMT_OK_OV              (1L<<0)         /* Bit  0:      Frames Tx Ok Ov */
-
-#define XMT_DEF_MSK            (XMT_OK_LO_OV | XMT_OK_HI_OV)
-
-/*
- * Receive Frame Status Encoding
- */
-#define XMR_FS_LEN     (0x3fffUL<<18)  /* Bit 31..18:  Rx Frame Length */
-#define XMR_FS_2L_VLAN (1L<<17)        /* Bit 17:      tagged wh 2Lev VLAN ID*/
-#define XMR_FS_1L_VLAN (1L<<16)        /* Bit 16:      tagged wh 1Lev VLAN ID*/
-#define XMR_FS_BC              (1L<<15)        /* Bit 15:      Broadcast Frame */
-#define XMR_FS_MC              (1L<<14)        /* Bit 14:      Multicast Frame */
-#define XMR_FS_UC              (1L<<13)        /* Bit 13:      Unicast Frame */
-                                                                       /* Bit 12:      reserved */
-#define XMR_FS_BURST   (1L<<11)        /* Bit 11:      Burst Mode */
-#define XMR_FS_CEX_ERR (1L<<10)        /* Bit 10:      Carrier Ext. Error */
-#define XMR_FS_802_3   (1L<<9)         /* Bit  9:      802.3 Frame */
-#define XMR_FS_COL_ERR (1L<<8)         /* Bit  8:      Collision Error */
-#define XMR_FS_CAR_ERR (1L<<7)         /* Bit  7:      Carrier Event Error */
-#define XMR_FS_LEN_ERR (1L<<6)         /* Bit  6:      In-Range Length Error */
-#define XMR_FS_FRA_ERR (1L<<5)         /* Bit  5:      Framing Error */
-#define XMR_FS_RUNT            (1L<<4)         /* Bit  4:      Runt Frame */
-#define XMR_FS_LNG_ERR (1L<<3)         /* Bit  3:      Giant (Jumbo) Frame */
-#define XMR_FS_FCS_ERR (1L<<2)         /* Bit  2:      Frame Check Sequ Err */
-#define XMR_FS_ERR             (1L<<1)         /* Bit  1:      Frame Error */
-#define XMR_FS_MCTRL   (1L<<0)         /* Bit  0:      MAC Control Packet */
-
-/*
- * XMR_FS_ERR will be set if
- *     XMR_FS_FCS_ERR, XMR_FS_LNG_ERR, XMR_FS_RUNT,
- *     XMR_FS_FRA_ERR, XMR_FS_LEN_ERR, or XMR_FS_CEX_ERR
- * is set. XMR_FS_LNG_ERR and XMR_FS_LEN_ERR will issue
- * XMR_FS_ERR unless the corresponding bit in the Receive Command
- * Register is set.
- */
-#define XMR_FS_ANY_ERR XMR_FS_ERR
-
-/*----------------------------------------------------------------------------*/
-/*
- * XMAC-PHY Registers, indirect addressed over the XMAC
- */
-#define PHY_XMAC_CTRL          0x00    /* 16 bit r/w   PHY Control Register */
-#define PHY_XMAC_STAT          0x01    /* 16 bit r/w   PHY Status Register */
-#define PHY_XMAC_ID0           0x02    /* 16 bit r/o   PHY ID0 Register */
-#define PHY_XMAC_ID1           0x03    /* 16 bit r/o   PHY ID1 Register */
-#define PHY_XMAC_AUNE_ADV      0x04    /* 16 bit r/w   Auto-Neg. Advertisement */
-#define PHY_XMAC_AUNE_LP       0x05    /* 16 bit r/o   Link Partner Abi Reg */
-#define PHY_XMAC_AUNE_EXP      0x06    /* 16 bit r/o   Auto-Neg. Expansion Reg */
-#define PHY_XMAC_NEPG          0x07    /* 16 bit r/w   Next Page Register */
-#define PHY_XMAC_NEPG_LP       0x08    /* 16 bit r/o   Next Page Link Partner */
-       /* 0x09 - 0x0e:         reserved */
-#define PHY_XMAC_EXT_STAT      0x0f    /* 16 bit r/o   Ext Status Register */
-#define PHY_XMAC_RES_ABI       0x10    /* 16 bit r/o   PHY Resolved Ability */
-
-/*----------------------------------------------------------------------------*/
-/*
- * Broadcom-PHY Registers, indirect addressed over XMAC
- */
-#define PHY_BCOM_CTRL          0x00    /* 16 bit r/w   PHY Control Register */
-#define PHY_BCOM_STAT          0x01    /* 16 bit r/o   PHY Status Register */
-#define PHY_BCOM_ID0           0x02    /* 16 bit r/o   PHY ID0 Register */
-#define PHY_BCOM_ID1           0x03    /* 16 bit r/o   PHY ID1 Register */
-#define PHY_BCOM_AUNE_ADV      0x04    /* 16 bit r/w   Auto-Neg. Advertisement */
-#define PHY_BCOM_AUNE_LP       0x05    /* 16 bit r/o   Link Part Ability Reg */
-#define PHY_BCOM_AUNE_EXP      0x06    /* 16 bit r/o   Auto-Neg. Expansion Reg */
-#define PHY_BCOM_NEPG          0x07    /* 16 bit r/w   Next Page Register */
-#define PHY_BCOM_NEPG_LP       0x08    /* 16 bit r/o   Next Page Link Partner */
-       /* Broadcom-specific registers */
-#define PHY_BCOM_1000T_CTRL    0x09    /* 16 bit r/w   1000Base-T Ctrl Reg */
-#define PHY_BCOM_1000T_STAT    0x0a    /* 16 bit r/o   1000Base-T Status Reg */
-       /* 0x0b - 0x0e:         reserved */
-#define PHY_BCOM_EXT_STAT      0x0f    /* 16 bit r/o   Extended Status Reg */
-#define PHY_BCOM_P_EXT_CTRL    0x10    /* 16 bit r/w   PHY Extended Ctrl Reg */
-#define PHY_BCOM_P_EXT_STAT    0x11    /* 16 bit r/o   PHY Extended Stat Reg */
-#define PHY_BCOM_RE_CTR                0x12    /* 16 bit r/w   Receive Error Counter */
-#define PHY_BCOM_FC_CTR                0x13    /* 16 bit r/w   False Carrier Sense Cnt */
-#define PHY_BCOM_RNO_CTR       0x14    /* 16 bit r/w   Receiver NOT_OK Cnt */
-       /* 0x15 - 0x17:         reserved */
-#define PHY_BCOM_AUX_CTRL      0x18    /* 16 bit r/w   Auxiliary Control Reg */
-#define PHY_BCOM_AUX_STAT      0x19    /* 16 bit r/o   Auxiliary Stat Summary */
-#define PHY_BCOM_INT_STAT      0x1a    /* 16 bit r/o   Interrupt Status Reg */
-#define PHY_BCOM_INT_MASK      0x1b    /* 16 bit r/w   Interrupt Mask Reg */
-       /* 0x1c:                reserved */
-       /* 0x1d - 0x1f:         test registers */
-
-/*----------------------------------------------------------------------------*/
-/*
- * Marvel-PHY Registers, indirect addressed over GMAC
- */
-#define PHY_MARV_CTRL          0x00    /* 16 bit r/w   PHY Control Register */
-#define PHY_MARV_STAT          0x01    /* 16 bit r/o   PHY Status Register */
-#define PHY_MARV_ID0           0x02    /* 16 bit r/o   PHY ID0 Register */
-#define PHY_MARV_ID1           0x03    /* 16 bit r/o   PHY ID1 Register */
-#define PHY_MARV_AUNE_ADV      0x04    /* 16 bit r/w   Auto-Neg. Advertisement */
-#define PHY_MARV_AUNE_LP       0x05    /* 16 bit r/o   Link Part Ability Reg */
-#define PHY_MARV_AUNE_EXP      0x06    /* 16 bit r/o   Auto-Neg. Expansion Reg */
-#define PHY_MARV_NEPG          0x07    /* 16 bit r/w   Next Page Register */
-#define PHY_MARV_NEPG_LP       0x08    /* 16 bit r/o   Next Page Link Partner */
-       /* Marvel-specific registers */
-#define PHY_MARV_1000T_CTRL    0x09    /* 16 bit r/w   1000Base-T Ctrl Reg */
-#define PHY_MARV_1000T_STAT    0x0a    /* 16 bit r/o   1000Base-T Status Reg */
-       /* 0x0b - 0x0e:         reserved */
-#define PHY_MARV_EXT_STAT      0x0f    /* 16 bit r/o   Extended Status Reg */
-#define PHY_MARV_PHY_CTRL      0x10    /* 16 bit r/w   PHY Specific Ctrl Reg */
-#define PHY_MARV_PHY_STAT      0x11    /* 16 bit r/o   PHY Specific Stat Reg */
-#define PHY_MARV_INT_MASK      0x12    /* 16 bit r/w   Interrupt Mask Reg */
-#define PHY_MARV_INT_STAT      0x13    /* 16 bit r/o   Interrupt Status Reg */
-#define PHY_MARV_EXT_CTRL      0x14    /* 16 bit r/w   Ext. PHY Specific Ctrl */
-#define PHY_MARV_RXE_CNT       0x15    /* 16 bit r/w   Receive Error Counter */
-#define PHY_MARV_EXT_ADR       0x16    /* 16 bit r/w   Ext. Ad. for Cable Diag. */
-       /* 0x17:                reserved */
-#define PHY_MARV_LED_CTRL      0x18    /* 16 bit r/w   LED Control Reg */
-#define PHY_MARV_LED_OVER      0x19    /* 16 bit r/w   Manual LED Override Reg */
-#define PHY_MARV_EXT_CTRL_2    0x1a    /* 16 bit r/w   Ext. PHY Specific Ctrl 2 */
-#define PHY_MARV_EXT_P_STAT    0x1b    /* 16 bit r/w   Ext. PHY Spec. Stat Reg */
-#define PHY_MARV_CABLE_DIAG    0x1c    /* 16 bit r/o   Cable Diagnostic Reg */
-       /* 0x1d - 0x1f:         reserved */
-
-/*----------------------------------------------------------------------------*/
-/*
- * Level One-PHY Registers, indirect addressed over XMAC
- */
-#define PHY_LONE_CTRL          0x00    /* 16 bit r/w   PHY Control Register */
-#define PHY_LONE_STAT          0x01    /* 16 bit r/o   PHY Status Register */
-#define PHY_LONE_ID0           0x02    /* 16 bit r/o   PHY ID0 Register */
-#define PHY_LONE_ID1           0x03    /* 16 bit r/o   PHY ID1 Register */
-#define PHY_LONE_AUNE_ADV      0x04    /* 16 bit r/w   Auto-Neg. Advertisement */
-#define PHY_LONE_AUNE_LP       0x05    /* 16 bit r/o   Link Part Ability Reg */
-#define PHY_LONE_AUNE_EXP      0x06    /* 16 bit r/o   Auto-Neg. Expansion Reg */
-#define PHY_LONE_NEPG          0x07    /* 16 bit r/w   Next Page Register */
-#define PHY_LONE_NEPG_LP       0x08    /* 16 bit r/o   Next Page Link Partner */
-       /* Level One-specific registers */
-#define PHY_LONE_1000T_CTRL    0x09    /* 16 bit r/w   1000Base-T Control Reg*/
-#define PHY_LONE_1000T_STAT    0x0a    /* 16 bit r/o   1000Base-T Status Reg */
-       /* 0x0b -0x0e:          reserved */
-#define PHY_LONE_EXT_STAT      0x0f    /* 16 bit r/o   Extended Status Reg */
-#define PHY_LONE_PORT_CFG      0x10    /* 16 bit r/w   Port Configuration Reg*/
-#define PHY_LONE_Q_STAT                0x11    /* 16 bit r/o   Quick Status Reg */
-#define PHY_LONE_INT_ENAB      0x12    /* 16 bit r/w   Interrupt Enable Reg */
-#define PHY_LONE_INT_STAT      0x13    /* 16 bit r/o   Interrupt Status Reg */
-#define PHY_LONE_LED_CFG       0x14    /* 16 bit r/w   LED Configuration Reg */
-#define PHY_LONE_PORT_CTRL     0x15    /* 16 bit r/w   Port Control Reg */
-#define PHY_LONE_CIM           0x16    /* 16 bit r/o   CIM Reg */
-       /* 0x17 -0x1c:          reserved */
-
-/*----------------------------------------------------------------------------*/
-/*
- * National-PHY Registers, indirect addressed over XMAC
- */
-#define PHY_NAT_CTRL           0x00    /* 16 bit r/w   PHY Control Register */
-#define PHY_NAT_STAT           0x01    /* 16 bit r/w   PHY Status Register */
-#define PHY_NAT_ID0                    0x02    /* 16 bit r/o   PHY ID0 Register */
-#define PHY_NAT_ID1                    0x03    /* 16 bit r/o   PHY ID1 Register */
-#define PHY_NAT_AUNE_ADV       0x04    /* 16 bit r/w   Auto-Neg. Advertisement */
-#define PHY_NAT_AUNE_LP                0x05    /* 16 bit r/o   Link Partner Ability Reg */
-#define PHY_NAT_AUNE_EXP       0x06    /* 16 bit r/o   Auto-Neg. Expansion Reg */
-#define PHY_NAT_NEPG           0x07    /* 16 bit r/w   Next Page Register */
-#define PHY_NAT_NEPG_LP                0x08    /* 16 bit r/o   Next Page Link Partner Reg */
-       /* National-specific registers */
-#define PHY_NAT_1000T_CTRL     0x09    /* 16 bit r/w   1000Base-T Control Reg */
-#define PHY_NAT_1000T_STAT     0x0a    /* 16 bit r/o   1000Base-T Status Reg */
-       /* 0x0b -0x0e:          reserved */
-#define PHY_NAT_EXT_STAT       0x0f    /* 16 bit r/o   Extended Status Register */
-#define PHY_NAT_EXT_CTRL1      0x10    /* 16 bit r/o   Extended Control Reg1 */
-#define PHY_NAT_Q_STAT1                0x11    /* 16 bit r/o   Quick Status Reg1 */
-#define PHY_NAT_10B_OP         0x12    /* 16 bit r/o   10Base-T Operations Reg */
-#define PHY_NAT_EXT_CTRL2      0x13    /* 16 bit r/o   Extended Control Reg1 */
-#define PHY_NAT_Q_STAT2                0x14    /* 16 bit r/o   Quick Status Reg2 */
-       /* 0x15 -0x18:          reserved */
-#define PHY_NAT_PHY_ADDR       0x19    /* 16 bit r/o   PHY Address Register */
-
-
-/*----------------------------------------------------------------------------*/
-
-/*
- * PHY bit definitions
- * Bits defined as PHY_X_..., PHY_B_..., PHY_L_... or PHY_N_... are
- * XMAC/Broadcom/LevelOne/National/Marvell-specific.
- * All other are general.
- */
-
-/*****  PHY_XMAC_CTRL  16 bit r/w      PHY Control Register *****/
-/*****  PHY_BCOM_CTRL  16 bit r/w      PHY Control Register *****/
-/*****  PHY_MARV_CTRL  16 bit r/w      PHY Status Register *****/
-/*****  PHY_LONE_CTRL  16 bit r/w      PHY Control Register *****/
-#define PHY_CT_RESET   (1<<15) /* Bit 15: (sc) clear all PHY related regs */
-#define PHY_CT_LOOP            (1<<14) /* Bit 14:      enable Loopback over PHY */
-#define PHY_CT_SPS_LSB (1<<13) /* Bit 13: (BC,L1) Speed select, lower bit */
-#define PHY_CT_ANE             (1<<12) /* Bit 12:      Auto-Negotiation Enabled */
-#define PHY_CT_PDOWN   (1<<11) /* Bit 11: (BC,L1) Power Down Mode */
-#define PHY_CT_ISOL            (1<<10) /* Bit 10: (BC,L1) Isolate Mode */
-#define PHY_CT_RE_CFG  (1<<9)  /* Bit  9: (sc) Restart Auto-Negotiation */
-#define PHY_CT_DUP_MD  (1<<8)  /* Bit  8:      Duplex Mode */
-#define PHY_CT_COL_TST (1<<7)  /* Bit  7: (BC,L1) Collision Test enabled */
-#define PHY_CT_SPS_MSB (1<<6)  /* Bit  6: (BC,L1) Speed select, upper bit */
-                                                               /* Bit  5..0:   reserved */
-
-#define PHY_CT_SP1000  PHY_CT_SPS_MSB  /* enable speed of 1000 Mbps */
-#define PHY_CT_SP100   PHY_CT_SPS_LSB  /* enable speed of  100 Mbps */
-#define PHY_CT_SP10            (0)                             /* enable speed of   10 Mbps */
-
-
-/*****  PHY_XMAC_STAT  16 bit r/w      PHY Status Register *****/
-/*****  PHY_BCOM_STAT  16 bit r/w      PHY Status Register *****/
-/*****  PHY_MARV_STAT  16 bit r/w      PHY Status Register *****/
-/*****  PHY_LONE_STAT  16 bit r/w      PHY Status Register *****/
-                                                               /* Bit 15..9:   reserved */
-                               /*      (BC/L1) 100/10 Mbps cap bits ignored*/
-#define PHY_ST_EXT_ST  (1<<8)  /* Bit  8:      Extended Status Present */
-                                                               /* Bit  7:      reserved */
-#define PHY_ST_PRE_SUP (1<<6)  /* Bit  6: (BC/L1) preamble suppression */
-#define PHY_ST_AN_OVER (1<<5)  /* Bit  5:      Auto-Negotiation Over */
-#define PHY_ST_REM_FLT (1<<4)  /* Bit  4:      Remote Fault Condition Occured */
-#define PHY_ST_AN_CAP  (1<<3)  /* Bit  3:      Auto-Negotiation Capability */
-#define PHY_ST_LSYNC   (1<<2)  /* Bit  2:      Link Synchronized */
-#define PHY_ST_JAB_DET (1<<1)  /* Bit  1: (BC/L1) Jabber Detected */
-#define PHY_ST_EXT_REG (1<<0)  /* Bit  0:      Extended Register available */
-
-
-/***** PHY_XMAC_ID1            16 bit r/o      PHY ID1 Register */
-/***** PHY_BCOM_ID1            16 bit r/o      PHY ID1 Register */
-/***** PHY_MARV_ID1            16 bit r/o      PHY ID1 Register */
-/***** PHY_LONE_ID1            16 bit r/o      PHY ID1 Register */
-#define PHY_I1_OUI_MSK (0x3f<<10)      /* Bit 15..10:  Organization Unique ID */
-#define PHY_I1_MOD_NUM (0x3f<<4)       /* Bit  9.. 4:  Model Number */
-#define PHY_I1_REV_MSK 0x0f            /* Bit  3.. 0:  Revision Number */
-
-/* different Broadcom PHY Ids */
-#define PHY_BCOM_ID1_A1                0x6041
-#define PHY_BCOM_ID1_B2                0x6043
-#define PHY_BCOM_ID1_C0                0x6044
-#define PHY_BCOM_ID1_C5                0x6047
-
-
-/*****  PHY_XMAC_AUNE_ADV      16 bit r/w      Auto-Negotiation Advertisement *****/
-/*****  PHY_XMAC_AUNE_LP       16 bit r/o      Link Partner Ability Reg *****/
-#define PHY_AN_NXT_PG  (1<<15) /* Bit 15:      Request Next Page */
-#define PHY_X_AN_ACK   (1<<14) /* Bit 14: (ro) Acknowledge Received */
-#define PHY_X_AN_RFB   (3<<12) /* Bit 13..12:  Remote Fault Bits */
-                                                               /* Bit 11.. 9:  reserved */
-#define PHY_X_AN_PAUSE (3<<7)  /* Bit  8.. 7:  Pause Bits */
-#define PHY_X_AN_HD            (1<<6)  /* Bit  6:      Half Duplex */
-#define PHY_X_AN_FD            (1<<5)  /* Bit  5:      Full Duplex */
-                                                               /* Bit  4.. 0:  reserved */
-
-/*****  PHY_BCOM_AUNE_ADV      16 bit r/w      Auto-Negotiation Advertisement *****/
-/*****  PHY_BCOM_AUNE_LP       16 bit r/o      Link Partner Ability Reg *****/
-/*     PHY_AN_NXT_PG           (see XMAC) Bit 15:      Request Next Page */
-                                                               /* Bit 14:      reserved */
-#define PHY_B_AN_RF            (1<<13) /* Bit 13:      Remote Fault */
-                                                               /* Bit 12:      reserved */
-#define PHY_B_AN_ASP   (1<<11) /* Bit 11:      Asymmetric Pause */
-#define PHY_B_AN_PC            (1<<10) /* Bit 10:      Pause Capable */
-                                                               /* Bit  9..5:   100/10 BT cap bits ingnored */
-#define PHY_B_AN_SEL   0x1f    /* Bit 4..0:    Selector Field, 00001=Ethernet*/
-
-/*****  PHY_LONE_AUNE_ADV      16 bit r/w      Auto-Negotiation Advertisement *****/
-/*****  PHY_LONE_AUNE_LP       16 bit r/o      Link Partner Ability Reg *****/
-/*     PHY_AN_NXT_PG           (see XMAC) Bit 15:      Request Next Page */
-                                                               /* Bit 14:      reserved */
-#define PHY_L_AN_RF            (1<<13) /* Bit 13:      Remote Fault */
-                                                               /* Bit 12:      reserved */
-#define PHY_L_AN_ASP   (1<<11) /* Bit 11:      Asymmetric Pause */
-#define PHY_L_AN_PC            (1<<10) /* Bit 10:      Pause Capable */
-                                                               /* Bit  9..5:   100/10 BT cap bits ingnored */
-#define PHY_L_AN_SEL   0x1f    /* Bit 4..0:    Selector Field, 00001=Ethernet*/
-
-/*****  PHY_NAT_AUNE_ADV       16 bit r/w      Auto-Negotiation Advertisement *****/
-/*****  PHY_NAT_AUNE_LP                16 bit r/o      Link Partner Ability Reg *****/
-/*     PHY_AN_NXT_PG           (see XMAC) Bit 15:      Request Next Page */
-                                                               /* Bit 14:      reserved */
-#define PHY_N_AN_RF            (1<<13) /* Bit 13:      Remote Fault */
-                                                               /* Bit 12:      reserved */
-#define PHY_N_AN_100F  (1<<11) /* Bit 11:      100Base-T2 FD Support */
-#define PHY_N_AN_100H  (1<<10) /* Bit 10:      100Base-T2 HD Support */
-                                                               /* Bit  9..5:   100/10 BT cap bits ingnored */
-#define PHY_N_AN_SEL   0x1f    /* Bit 4..0:    Selector Field, 00001=Ethernet*/
-
-/* field type definition for PHY_x_AN_SEL */
-#define PHY_SEL_TYPE   0x01    /* 00001 = Ethernet */
-
-/*****  PHY_XMAC_AUNE_EXP      16 bit r/o      Auto-Negotiation Expansion Reg *****/
-                                                               /* Bit 15..4:   reserved */
-#define PHY_ANE_LP_NP  (1<<3)  /* Bit  3:      Link Partner can Next Page */
-#define PHY_ANE_LOC_NP (1<<2)  /* Bit  2:      Local PHY can Next Page */
-#define PHY_ANE_RX_PG  (1<<1)  /* Bit  1:      Page Received */
-                                                               /* Bit  0:      reserved */
-
-/*****  PHY_BCOM_AUNE_EXP      16 bit r/o      Auto-Negotiation Expansion Reg *****/
-/*****  PHY_LONE_AUNE_EXP      16 bit r/o      Auto-Negotiation Expansion Reg *****/
-/*****  PHY_MARV_AUNE_EXP      16 bit r/o      Auto-Negotiation Expansion Reg *****/
-                                                               /* Bit 15..5:   reserved */
-#define PHY_ANE_PAR_DF (1<<4)  /* Bit  4:      Parallel Detection Fault */
-/*     PHY_ANE_LP_NP           (see XMAC) Bit  3:      Link Partner can Next Page */
-/*     PHY_ANE_LOC_NP          (see XMAC) Bit  2:      Local PHY can Next Page */
-/*     PHY_ANE_RX_PG           (see XMAC) Bit  1:      Page Received */
-#define PHY_ANE_LP_CAP (1<<0)  /* Bit  0:      Link Partner Auto-Neg. Cap. */  
-
-/*****  PHY_XMAC_NEPG          16 bit r/w      Next Page Register *****/
-/*****  PHY_BCOM_NEPG          16 bit r/w      Next Page Register *****/
-/*****  PHY_LONE_NEPG          16 bit r/w      Next Page Register *****/
-/*****  PHY_XMAC_NEPG_LP       16 bit r/o      Next Page Link Partner *****/
-/*****  PHY_BCOM_NEPG_LP       16 bit r/o      Next Page Link Partner *****/
-/*****  PHY_LONE_NEPG_LP       16 bit r/o      Next Page Link Partner *****/
-#define PHY_NP_MORE            (1<<15) /* Bit 15:      More, Next Pages to follow */
-#define PHY_NP_ACK1            (1<<14) /* Bit 14: (ro) Ack1, for receiving a message */
-#define PHY_NP_MSG_VAL (1<<13) /* Bit 13:      Message Page valid */
-#define PHY_NP_ACK2            (1<<12) /* Bit 12:      Ack2, comply with msg content */
-#define PHY_NP_TOG             (1<<11) /* Bit 11:      Toggle Bit, ensure sync */
-#define PHY_NP_MSG             0x07ff  /* Bit 10..0:   Message from/to Link Partner */
-
-/*
- * XMAC-Specific
- */
-/*****  PHY_XMAC_EXT_STAT      16 bit r/w      Extended Status Register *****/
-#define PHY_X_EX_FD            (1<<15) /* Bit 15:      Device Supports Full Duplex */
-#define PHY_X_EX_HD            (1<<14) /* Bit 14:      Device Supports Half Duplex */
-                                                               /* Bit 13..0:   reserved */
-
-/*****  PHY_XMAC_RES_ABI       16 bit r/o      PHY Resolved Ability *****/
-                                                               /* Bit 15..9:   reserved */
-#define PHY_X_RS_PAUSE (3<<7)  /* Bit  8..7:   selected Pause Mode */
-#define PHY_X_RS_HD            (1<<6)  /* Bit  6:      Half Duplex Mode selected */
-#define PHY_X_RS_FD            (1<<5)  /* Bit  5:      Full Duplex Mode selected */
-#define PHY_X_RS_ABLMIS (1<<4) /* Bit  4:      duplex or pause cap mismatch */
-#define PHY_X_RS_PAUMIS (1<<3) /* Bit  3:      pause capability mismatch */
-                                                               /* Bit  2..0:   reserved */
-/*
- * Remote Fault Bits (PHY_X_AN_RFB) encoding
- */
-#define X_RFB_OK               (0<<12) /* Bit 13..12   No errors, Link OK */
-#define X_RFB_LF               (1<<12) /* Bit 13..12   Link Failure */
-#define X_RFB_OFF              (2<<12) /* Bit 13..12   Offline */
-#define X_RFB_AN_ERR   (3<<12) /* Bit 13..12   Auto-Negotiation Error */
-
-/*
- * Pause Bits (PHY_X_AN_PAUSE and PHY_X_RS_PAUSE) encoding
- */
-#define PHY_X_P_NO_PAUSE       (0<<7)  /* Bit  8..7:   no Pause Mode */
-#define PHY_X_P_SYM_MD         (1<<7)  /* Bit  8..7:   symmetric Pause Mode */
-#define PHY_X_P_ASYM_MD                (2<<7)  /* Bit  8..7:   asymmetric Pause Mode */
-#define PHY_X_P_BOTH_MD                (3<<7)  /* Bit  8..7:   both Pause Mode */
-
-
-/*
- * Broadcom-Specific
- */
-/*****  PHY_BCOM_1000T_CTRL    16 bit r/w      1000Base-T Control Reg *****/
-#define PHY_B_1000C_TEST       (7<<13) /* Bit 15..13:  Test Modes */
-#define PHY_B_1000C_MSE                (1<<12) /* Bit 12:      Master/Slave Enable */
-#define PHY_B_1000C_MSC                (1<<11) /* Bit 11:      M/S Configuration */
-#define PHY_B_1000C_RD         (1<<10) /* Bit 10:      Repeater/DTE */
-#define PHY_B_1000C_AFD                (1<<9)  /* Bit  9:      Advertise Full Duplex */
-#define PHY_B_1000C_AHD                (1<<8)  /* Bit  8:      Advertise Half Duplex */
-                                                                       /* Bit  7..0:   reserved */
-
-/*****  PHY_BCOM_1000T_STAT    16 bit r/o      1000Base-T Status Reg *****/
-/*****  PHY_MARV_1000T_STAT    16 bit r/o      1000Base-T Status Reg *****/
-#define PHY_B_1000S_MSF                (1<<15) /* Bit 15:      Master/Slave Fault */
-#define PHY_B_1000S_MSR                (1<<14) /* Bit 14:      Master/Slave Result */
-#define PHY_B_1000S_LRS                (1<<13) /* Bit 13:      Local Receiver Status */
-#define PHY_B_1000S_RRS                (1<<12) /* Bit 12:      Remote Receiver Status */
-#define PHY_B_1000S_LP_FD      (1<<11) /* Bit 11:      Link Partner can FD */
-#define PHY_B_1000S_LP_HD      (1<<10) /* Bit 10:      Link Partner can HD */
-                                                                       /* Bit  9..8:   reserved */
-#define PHY_B_1000S_IEC                0xff    /* Bit  7..0:   Idle Error Count */
-
-/*****  PHY_BCOM_EXT_STAT      16 bit r/o      Extended Status Register *****/
-#define PHY_B_ES_X_FD_CAP      (1<<15) /* Bit 15:      1000Base-X FD capable */
-#define PHY_B_ES_X_HD_CAP      (1<<14) /* Bit 14:      1000Base-X HD capable */
-#define PHY_B_ES_T_FD_CAP      (1<<13) /* Bit 13:      1000Base-T FD capable */
-#define PHY_B_ES_T_HD_CAP      (1<<12) /* Bit 12:      1000Base-T HD capable */
-                                                                       /* Bit 11..0:   reserved */
-
-/*****  PHY_BCOM_P_EXT_CTRL    16 bit r/w      PHY Extended Control Reg *****/
-#define PHY_B_PEC_MAC_PHY      (1<<15) /* Bit 15:      10BIT/GMI-Interface */
-#define PHY_B_PEC_DIS_CROSS    (1<<14) /* Bit 14:      Disable MDI Crossover */
-#define PHY_B_PEC_TX_DIS       (1<<13) /* Bit 13:      Tx output Disabled */
-#define PHY_B_PEC_INT_DIS      (1<<12) /* Bit 12:      Interrupts Disabled */
-#define PHY_B_PEC_F_INT                (1<<11) /* Bit 11:      Force Interrupt */
-#define PHY_B_PEC_BY_45                (1<<10) /* Bit 10:      Bypass 4B5B-Decoder */
-#define PHY_B_PEC_BY_SCR       (1<<9)  /* Bit  9:      Bypass Scrambler */
-#define PHY_B_PEC_BY_MLT3      (1<<8)  /* Bit  8:      Bypass MLT3 Encoder */
-#define PHY_B_PEC_BY_RXA       (1<<7)  /* Bit  7:      Bypass Rx Alignm. */
-#define PHY_B_PEC_RES_SCR      (1<<6)  /* Bit  6:      Reset Scrambler */
-#define PHY_B_PEC_EN_LTR       (1<<5)  /* Bit  5:      Ena LED Traffic Mode */
-#define PHY_B_PEC_LED_ON       (1<<4)  /* Bit  4:      Force LED's on */
-#define PHY_B_PEC_LED_OFF      (1<<3)  /* Bit  3:      Force LED's off */
-#define PHY_B_PEC_EX_IPG       (1<<2)  /* Bit  2:      Extend Tx IPG Mode */
-#define PHY_B_PEC_3_LED                (1<<1)  /* Bit  1:      Three Link LED mode */
-#define PHY_B_PEC_HIGH_LA      (1<<0)  /* Bit  0:      GMII FIFO Elasticy */
-
-/*****  PHY_BCOM_P_EXT_STAT    16 bit r/o      PHY Extended Status Reg *****/
-                                                                       /* Bit 15..14:  reserved */
-#define PHY_B_PES_CROSS_STAT   (1<<13) /* Bit 13:      MDI Crossover Status */
-#define PHY_B_PES_INT_STAT     (1<<12) /* Bit 12:      Interrupt Status */
-#define PHY_B_PES_RRS          (1<<11) /* Bit 11:      Remote Receiver Stat. */
-#define PHY_B_PES_LRS          (1<<10) /* Bit 10:      Local Receiver Stat. */
-#define PHY_B_PES_LOCKED       (1<<9)  /* Bit  9:      Locked */
-#define PHY_B_PES_LS           (1<<8)  /* Bit  8:      Link Status */
-#define PHY_B_PES_RF           (1<<7)  /* Bit  7:      Remote Fault */
-#define PHY_B_PES_CE_ER                (1<<6)  /* Bit  6:      Carrier Ext Error */
-#define PHY_B_PES_BAD_SSD      (1<<5)  /* Bit  5:      Bad SSD */
-#define PHY_B_PES_BAD_ESD      (1<<4)  /* Bit  4:      Bad ESD */
-#define PHY_B_PES_RX_ER                (1<<3)  /* Bit  3:      Receive Error */
-#define PHY_B_PES_TX_ER                (1<<2)  /* Bit  2:      Transmit Error */
-#define PHY_B_PES_LOCK_ER      (1<<1)  /* Bit  1:      Lock Error */
-#define PHY_B_PES_MLT3_ER      (1<<0)  /* Bit  0:      MLT3 code Error */
-
-/*****  PHY_BCOM_FC_CTR                16 bit r/w      False Carrier Counter *****/
-                                                                       /* Bit 15..8:   reserved */
-#define PHY_B_FC_CTR           0xff    /* Bit  7..0:   False Carrier Counter */
-
-/*****  PHY_BCOM_RNO_CTR       16 bit r/w      Receive NOT_OK Counter *****/
-#define PHY_B_RC_LOC_MSK       0xff00  /* Bit 15..8:   Local Rx NOT_OK cnt */
-#define PHY_B_RC_REM_MSK       0x00ff  /* Bit  7..0:   Remote Rx NOT_OK cnt */
-
-/*****  PHY_BCOM_AUX_CTRL      16 bit r/w      Auxiliary Control Reg *****/
-#define PHY_B_AC_L_SQE         (1<<15) /* Bit 15:      Low Squelch */
-#define PHY_B_AC_LONG_PACK     (1<<14) /* Bit 14:      Rx Long Packets */
-#define PHY_B_AC_ER_CTRL       (3<<12) /* Bit 13..12:  Edgerate Control */
-                                                                       /* Bit 11:      reserved */
-#define PHY_B_AC_TX_TST                (1<<10) /* Bit 10:      Tx test bit, always 1 */
-                                                                       /* Bit  9.. 8:  reserved */
-#define PHY_B_AC_DIS_PRF       (1<<7)  /* Bit  7:      dis part resp filter */
-                                                                       /* Bit  6:      reserved */
-#define PHY_B_AC_DIS_PM                (1<<5)  /* Bit  5:      dis power management */
-                                                                       /* Bit  4:      reserved */
-#define PHY_B_AC_DIAG          (1<<3)  /* Bit  3:      Diagnostic Mode */
-                                                                       /* Bit  2.. 0:  reserved */
-
-/*****  PHY_BCOM_AUX_STAT      16 bit r/o      Auxiliary Status Reg *****/
-#define PHY_B_AS_AN_C          (1<<15) /* Bit 15:      AutoNeg complete */
-#define PHY_B_AS_AN_CA         (1<<14) /* Bit 14:      AN Complete Ack */
-#define PHY_B_AS_ANACK_D       (1<<13) /* Bit 13:      AN Ack Detect */
-#define PHY_B_AS_ANAB_D                (1<<12) /* Bit 12:      AN Ability Detect */
-#define PHY_B_AS_NPW           (1<<11) /* Bit 11:      AN Next Page Wait */
-#define PHY_B_AS_AN_RES_MSK    (7<<8)  /* Bit 10..8:   AN HDC */
-#define PHY_B_AS_PDF           (1<<7)  /* Bit  7:      Parallel Detect. Fault */
-#define PHY_B_AS_RF                    (1<<6)  /* Bit  6:      Remote Fault */
-#define PHY_B_AS_ANP_R         (1<<5)  /* Bit  5:      AN Page Received */
-#define PHY_B_AS_LP_ANAB       (1<<4)  /* Bit  4:      LP AN Ability */
-#define PHY_B_AS_LP_NPAB       (1<<3)  /* Bit  3:      LP Next Page Ability */
-#define PHY_B_AS_LS                    (1<<2)  /* Bit  2:      Link Status */
-#define PHY_B_AS_PRR           (1<<1)  /* Bit  1:      Pause Resolution-Rx */
-#define PHY_B_AS_PRT           (1<<0)  /* Bit  0:      Pause Resolution-Tx */
-
-#define PHY_B_AS_PAUSE_MSK     (PHY_B_AS_PRR | PHY_B_AS_PRT)
-
-/*****  PHY_BCOM_INT_STAT      16 bit r/o      Interrupt Status Reg *****/
-/*****  PHY_BCOM_INT_MASK      16 bit r/w      Interrupt Mask Reg *****/
-                                                                       /* Bit 15:      reserved */
-#define PHY_B_IS_PSE           (1<<14) /* Bit 14:      Pair Swap Error */
-#define PHY_B_IS_MDXI_SC       (1<<13) /* Bit 13:      MDIX Status Change */
-#define PHY_B_IS_HCT           (1<<12) /* Bit 12:      counter above 32k */
-#define PHY_B_IS_LCT           (1<<11) /* Bit 11:      counter above 128 */
-#define PHY_B_IS_AN_PR         (1<<10) /* Bit 10:      Page Received */
-#define PHY_B_IS_NO_HDCL       (1<<9)  /* Bit  9:      No HCD Link */
-#define PHY_B_IS_NO_HDC                (1<<8)  /* Bit  8:      No HCD */
-#define PHY_B_IS_NEG_USHDC     (1<<7)  /* Bit  7:      Negotiated Unsup. HCD */
-#define PHY_B_IS_SCR_S_ER      (1<<6)  /* Bit  6:      Scrambler Sync Error */
-#define PHY_B_IS_RRS_CHANGE    (1<<5)  /* Bit  5:      Remote Rx Stat Change */
-#define PHY_B_IS_LRS_CHANGE    (1<<4)  /* Bit  4:      Local Rx Stat Change */
-#define PHY_B_IS_DUP_CHANGE    (1<<3)  /* Bit  3:      Duplex Mode Change */
-#define PHY_B_IS_LSP_CHANGE    (1<<2)  /* Bit  2:      Link Speed Change */
-#define PHY_B_IS_LST_CHANGE    (1<<1)  /* Bit  1:      Link Status Changed */
-#define PHY_B_IS_CRC_ER                (1<<0)  /* Bit  0:      CRC Error */
-
-#define PHY_B_DEF_MSK  (~(PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE))
-
-/* Pause Bits (PHY_B_AN_ASP and PHY_B_AN_PC) encoding */
-#define PHY_B_P_NO_PAUSE       (0<<10) /* Bit 11..10:  no Pause Mode */
-#define PHY_B_P_SYM_MD         (1<<10) /* Bit 11..10:  symmetric Pause Mode */
-#define PHY_B_P_ASYM_MD                (2<<10) /* Bit 11..10:  asymmetric Pause Mode */
-#define PHY_B_P_BOTH_MD                (3<<10) /* Bit 11..10:  both Pause Mode */
-
-/*
- * Resolved Duplex mode and Capabilities (Aux Status Summary Reg)
- */
-#define PHY_B_RES_1000FD       (7<<8)  /* Bit 10..8:   1000Base-T Full Dup. */
-#define PHY_B_RES_1000HD       (6<<8)  /* Bit 10..8:   1000Base-T Half Dup. */
-/* others: 100/10: invalid for us */
-
-/*
- * Level One-Specific
- */
-/*****  PHY_LONE_1000T_CTRL    16 bit r/w      1000Base-T Control Reg *****/
-#define PHY_L_1000C_TEST       (7<<13) /* Bit 15..13:  Test Modes */
-#define PHY_L_1000C_MSE                (1<<12) /* Bit 12:      Master/Slave Enable */
-#define PHY_L_1000C_MSC                (1<<11) /* Bit 11:      M/S Configuration */
-#define PHY_L_1000C_RD         (1<<10) /* Bit 10:      Repeater/DTE */
-#define PHY_L_1000C_AFD                (1<<9)  /* Bit  9:      Advertise Full Duplex */
-#define PHY_L_1000C_AHD                (1<<8)  /* Bit  8:      Advertise Half Duplex */
-                                                                       /* Bit  7..0:   reserved */
-
-/*****  PHY_LONE_1000T_STAT    16 bit r/o      1000Base-T Status Reg *****/
-#define PHY_L_1000S_MSF                (1<<15) /* Bit 15:      Master/Slave Fault */
-#define PHY_L_1000S_MSR                (1<<14) /* Bit 14:      Master/Slave Result */
-#define PHY_L_1000S_LRS                (1<<13) /* Bit 13:      Local Receiver Status */
-#define PHY_L_1000S_RRS                (1<<12) /* Bit 12:      Remote Receiver Status */
-#define PHY_L_1000S_LP_FD      (1<<11) /* Bit 11:      Link Partner can FD */
-#define PHY_L_1000S_LP_HD      (1<<10) /* Bit 10:      Link Partner can HD */
-                                                                       /* Bit  9..8:   reserved */
-#define PHY_B_1000S_IEC                0xff    /* Bit  7..0:   Idle Error Count */
-
-/*****  PHY_LONE_EXT_STAT      16 bit r/o      Extended Status Register *****/
-#define PHY_L_ES_X_FD_CAP      (1<<15) /* Bit 15:      1000Base-X FD capable */
-#define PHY_L_ES_X_HD_CAP      (1<<14) /* Bit 14:      1000Base-X HD capable */
-#define PHY_L_ES_T_FD_CAP      (1<<13) /* Bit 13:      1000Base-T FD capable */
-#define PHY_L_ES_T_HD_CAP      (1<<12) /* Bit 12:      1000Base-T HD capable */
-                                                                       /* Bit 11..0:   reserved */
-
-/*****  PHY_LONE_PORT_CFG      16 bit r/w      Port Configuration Reg *****/
-#define PHY_L_PC_REP_MODE      (1<<15) /* Bit 15:      Repeater Mode */
-                                                                       /* Bit 14:      reserved */
-#define PHY_L_PC_TX_DIS                (1<<13) /* Bit 13:      Tx output Disabled */
-#define PHY_L_PC_BY_SCR                (1<<12) /* Bit 12:      Bypass Scrambler */
-#define PHY_L_PC_BY_45         (1<<11) /* Bit 11:      Bypass 4B5B-Decoder */
-#define PHY_L_PC_JAB_DIS       (1<<10) /* Bit 10:      Jabber Disabled */
-#define PHY_L_PC_SQE           (1<<9)  /* Bit  9:      Enable Heartbeat */
-#define PHY_L_PC_TP_LOOP       (1<<8)  /* Bit  8:      TP Loopback */
-#define PHY_L_PC_SSS           (1<<7)  /* Bit  7:      Smart Speed Selection */
-#define PHY_L_PC_FIFO_SIZE     (1<<6)  /* Bit  6:      FIFO Size */
-#define PHY_L_PC_PRE_EN                (1<<5)  /* Bit  5:      Preamble Enable */
-#define PHY_L_PC_CIM           (1<<4)  /* Bit  4:      Carrier Integrity Mon */
-#define PHY_L_PC_10_SER                (1<<3)  /* Bit  3:      Use Serial Output */
-#define PHY_L_PC_ANISOL                (1<<2)  /* Bit  2:      Unisolate Port */
-#define PHY_L_PC_TEN_BIT       (1<<1)  /* Bit  1:      10bit iface mode on */
-#define PHY_L_PC_ALTCLOCK      (1<<0)  /* Bit  0: (ro) ALTCLOCK Mode on */
-
-/*****  PHY_LONE_Q_STAT                16 bit r/o      Quick Status Reg *****/
-#define PHY_L_QS_D_RATE                (3<<14) /* Bit 15..14:  Data Rate */
-#define PHY_L_QS_TX_STAT       (1<<13) /* Bit 13:      Transmitting */
-#define PHY_L_QS_RX_STAT       (1<<12) /* Bit 12:      Receiving */
-#define PHY_L_QS_COL_STAT      (1<<11) /* Bit 11:      Collision */
-#define PHY_L_QS_L_STAT                (1<<10) /* Bit 10:      Link is up */
-#define PHY_L_QS_DUP_MOD       (1<<9)  /* Bit  9:      Full/Half Duplex */
-#define PHY_L_QS_AN                    (1<<8)  /* Bit  8:      AutoNeg is On */
-#define PHY_L_QS_AN_C          (1<<7)  /* Bit  7:      AN is Complete */
-#define PHY_L_QS_LLE           (7<<4)  /* Bit  6:      Line Length Estim. */
-#define PHY_L_QS_PAUSE         (1<<3)  /* Bit  3:      LP advertised Pause */
-#define PHY_L_QS_AS_PAUSE      (1<<2)  /* Bit  2:      LP adv. asym. Pause */
-#define PHY_L_QS_ISOLATE       (1<<1)  /* Bit  1:      CIM Isolated */
-#define PHY_L_QS_EVENT         (1<<0)  /* Bit  0:      Event has occurred */
-
-/*****  PHY_LONE_INT_ENAB      16 bit r/w      Interrupt Enable Reg *****/
-/*****  PHY_LONE_INT_STAT      16 bit r/o      Interrupt Status Reg *****/
-                                                                       /* Bit 15..14:  reserved */
-#define PHY_L_IS_AN_F          (1<<13) /* Bit 13:      Auto-Negotiation fault */
-                                                                       /* Bit 12:      not described */
-#define PHY_L_IS_CROSS         (1<<11) /* Bit 11:      Crossover used */
-#define PHY_L_IS_POL           (1<<10) /* Bit 10:      Polarity correct. used */
-#define PHY_L_IS_SS                    (1<<9)  /* Bit  9:      Smart Speed Downgrade */
-#define PHY_L_IS_CFULL         (1<<8)  /* Bit  8:      Counter Full */
-#define PHY_L_IS_AN_C          (1<<7)  /* Bit  7:      AutoNeg Complete */
-#define PHY_L_IS_SPEED         (1<<6)  /* Bit  6:      Speed Changed */
-#define PHY_L_IS_DUP           (1<<5)  /* Bit  5:      Duplex Changed */
-#define PHY_L_IS_LS                    (1<<4)  /* Bit  4:      Link Status Changed */
-#define PHY_L_IS_ISOL          (1<<3)  /* Bit  3:      Isolate Occured */
-#define PHY_L_IS_MDINT         (1<<2)  /* Bit  2: (ro) STAT: MII Int Pending */
-#define PHY_L_IS_INTEN         (1<<1)  /* Bit  1:      ENAB: Enable IRQs */
-#define PHY_L_IS_FORCE         (1<<0)  /* Bit  0:      ENAB: Force Interrupt */
-
-/* int. mask */
-#define PHY_L_DEF_MSK          (PHY_L_IS_LS | PHY_L_IS_ISOL | PHY_L_IS_INTEN)
-
-/*****  PHY_LONE_LED_CFG       16 bit r/w      LED Configuration Reg *****/
-#define PHY_L_LC_LEDC          (3<<14) /* Bit 15..14:  Col/Blink/On/Off */
-#define PHY_L_LC_LEDR          (3<<12) /* Bit 13..12:  Rx/Blink/On/Off */
-#define PHY_L_LC_LEDT          (3<<10) /* Bit 11..10:  Tx/Blink/On/Off */
-#define PHY_L_LC_LEDG          (3<<8)  /* Bit  9..8:   Giga/Blink/On/Off */
-#define PHY_L_LC_LEDS          (3<<6)  /* Bit  7..6:   10-100/Blink/On/Off */
-#define PHY_L_LC_LEDL          (3<<4)  /* Bit  5..4:   Link/Blink/On/Off */
-#define PHY_L_LC_LEDF          (3<<2)  /* Bit  3..2:   Duplex/Blink/On/Off */
-#define PHY_L_LC_PSTRECH       (1<<1)  /* Bit  1:      Strech LED Pulses */
-#define PHY_L_LC_FREQ          (1<<0)  /* Bit  0:      30/100 ms */
-
-/*****  PHY_LONE_PORT_CTRL     16 bit r/w      Port Control Reg *****/
-#define PHY_L_PC_TX_TCLK       (1<<15) /* Bit 15:      Enable TX_TCLK */
-                                                                       /* Bit 14:      reserved */
-#define PHY_L_PC_ALT_NP                (1<<13) /* Bit 14:      Alternate Next Page */
-#define PHY_L_PC_GMII_ALT      (1<<12) /* Bit 13:      Alternate GMII driver */
-                                                                       /* Bit 11:      reserved */
-#define PHY_L_PC_TEN_CRS       (1<<10) /* Bit 10:      Extend CRS*/
-                                                                       /* Bit  9..0:   not described */
-
-/*****  PHY_LONE_CIM           16 bit r/o      CIM Reg *****/
-#define PHY_L_CIM_ISOL         (255<<8)/* Bit 15..8:   Isolate Count */
-#define PHY_L_CIM_FALSE_CAR    (255<<0)/* Bit  7..0:   False Carrier Count */
-
-
-/*
- * Pause Bits (PHY_L_AN_ASP and PHY_L_AN_PC) encoding
- */
-#define PHY_L_P_NO_PAUSE       (0<<10) /* Bit 11..10:  no Pause Mode */
-#define PHY_L_P_SYM_MD         (1<<10) /* Bit 11..10:  symmetric Pause Mode */
-#define PHY_L_P_ASYM_MD                (2<<10) /* Bit 11..10:  asymmetric Pause Mode */
-#define PHY_L_P_BOTH_MD                (3<<10) /* Bit 11..10:  both Pause Mode */
-
-
-/*
- * National-Specific
- */
-/*****  PHY_NAT_1000T_CTRL     16 bit r/w      1000Base-T Control Reg *****/
-#define PHY_N_1000C_TEST       (7<<13) /* Bit 15..13:  Test Modes */
-#define PHY_N_1000C_MSE                (1<<12) /* Bit 12:      Master/Slave Enable */
-#define PHY_N_1000C_MSC                (1<<11) /* Bit 11:      M/S Configuration */
-#define PHY_N_1000C_RD         (1<<10) /* Bit 10:      Repeater/DTE */
-#define PHY_N_1000C_AFD                (1<<9)  /* Bit  9:      Advertise Full Duplex */
-#define PHY_N_1000C_AHD                (1<<8)  /* Bit  8:      Advertise Half Duplex */
-#define PHY_N_1000C_APC                (1<<7)  /* Bit  7:      Asymmetric Pause Cap. */
-                                                                       /* Bit  6..0:   reserved */
-
-/*****  PHY_NAT_1000T_STAT     16 bit r/o      1000Base-T Status Reg *****/
-#define PHY_N_1000S_MSF                (1<<15) /* Bit 15:      Master/Slave Fault */
-#define PHY_N_1000S_MSR                (1<<14) /* Bit 14:      Master/Slave Result */
-#define PHY_N_1000S_LRS                (1<<13) /* Bit 13:      Local Receiver Status */
-#define PHY_N_1000S_RRS                (1<<12) /* Bit 12:      Remote Receiver Status*/
-#define PHY_N_1000S_LP_FD      (1<<11) /* Bit 11:      Link Partner can FD */
-#define PHY_N_1000S_LP_HD      (1<<10) /* Bit 10:      Link Partner can HD */
-#define PHY_N_1000C_LP_APC     (1<<9)  /* Bit  9:      LP Asym. Pause Cap. */
-                                                                       /* Bit  8:      reserved */
-#define PHY_N_1000S_IEC                0xff    /* Bit  7..0:   Idle Error Count */
-
-/*****  PHY_NAT_EXT_STAT       16 bit r/o      Extended Status Register *****/
-#define PHY_N_ES_X_FD_CAP      (1<<15) /* Bit 15:      1000Base-X FD capable */
-#define PHY_N_ES_X_HD_CAP      (1<<14) /* Bit 14:      1000Base-X HD capable */
-#define PHY_N_ES_T_FD_CAP      (1<<13) /* Bit 13:      1000Base-T FD capable */
-#define PHY_N_ES_T_HD_CAP      (1<<12) /* Bit 12:      1000Base-T HD capable */
-                                                                       /* Bit 11..0:   reserved */
-
-/* todo: those are still missing */
-/*****  PHY_NAT_EXT_CTRL1      16 bit r/o      Extended Control Reg1 *****/
-/*****  PHY_NAT_Q_STAT1                16 bit r/o      Quick Status Reg1 *****/
-/*****  PHY_NAT_10B_OP         16 bit r/o      10Base-T Operations Reg *****/
-/*****  PHY_NAT_EXT_CTRL2      16 bit r/o      Extended Control Reg1 *****/
-/*****  PHY_NAT_Q_STAT2                16 bit r/o      Quick Status Reg2 *****/
-/*****  PHY_NAT_PHY_ADDR       16 bit r/o      PHY Address Register *****/
-
-/*
- * Marvell-Specific
- */
-/*****  PHY_MARV_AUNE_ADV      16 bit r/w      Auto-Negotiation Advertisement *****/
-/*****  PHY_MARV_AUNE_LP       16 bit r/w      Link Part Ability Reg *****/
-#define PHY_M_AN_NXT_PG                BIT_15  /* Request Next Page */
-#define PHY_M_AN_ACK           BIT_14  /* (ro) Acknowledge Received */
-#define PHY_M_AN_RF                    BIT_13  /* Remote Fault */
-                                                                       /* Bit 12:      reserved */
-#define PHY_M_AN_ASP           BIT_11  /* Asymmetric Pause */
-#define PHY_M_AN_PC                    BIT_10  /* MAC Pause implemented */
-#define PHY_M_AN_100_FD                BIT_8   /* Advertise 100Base-TX Full Duplex */
-#define PHY_M_AN_100_HD                BIT_7   /* Advertise 100Base-TX Half Duplex */
-#define PHY_M_AN_10_FD         BIT_6   /* Advertise 10Base-TX Full Duplex */
-#define PHY_M_AN_10_HD         BIT_5   /* Advertise 10Base-TX Half Duplex */
-
-/* special defines for FIBER (88E1011S only) */
-#define PHY_M_AN_ASP_X         BIT_8   /* Asymmetric Pause */
-#define PHY_M_AN_PC_X          BIT_7   /* MAC Pause implemented */
-#define PHY_M_AN_1000X_AHD     BIT_6   /* Advertise 10000Base-X Half Duplex */
-#define PHY_M_AN_1000X_AFD     BIT_5   /* Advertise 10000Base-X Full Duplex */
-
-/* Pause Bits (PHY_M_AN_ASP_X and PHY_M_AN_PC_X) encoding */
-#define PHY_M_P_NO_PAUSE_X     (0<<7)  /* Bit  8.. 7:  no Pause Mode */
-#define PHY_M_P_SYM_MD_X       (1<<7)  /* Bit  8.. 7:  symmetric Pause Mode */
-#define PHY_M_P_ASYM_MD_X      (2<<7)  /* Bit  8.. 7:  asymmetric Pause Mode */
-#define PHY_M_P_BOTH_MD_X      (3<<7)  /* Bit  8.. 7:  both Pause Mode */
-
-/*****  PHY_MARV_1000T_CTRL    16 bit r/w      1000Base-T Control Reg *****/
-#define PHY_M_1000C_TEST       (7<<13) /* Bit 15..13:  Test Modes */
-#define PHY_M_1000C_MSE                (1<<12) /* Bit 12:      Manual Master/Slave Enable */
-#define PHY_M_1000C_MSC                (1<<11) /* Bit 11:      M/S Configuration (1=Master) */
-#define PHY_M_1000C_MPD                (1<<10) /* Bit 10:      Multi-Port Device */
-#define PHY_M_1000C_AFD                (1<<9)  /* Bit  9:      Advertise Full Duplex */
-#define PHY_M_1000C_AHD                (1<<8)  /* Bit  8:      Advertise Half Duplex */
-                                                                       /* Bit  7..0:   reserved */
-
-/*****  PHY_MARV_PHY_CTRL      16 bit r/w      PHY Specific Ctrl Reg *****/
-#define PHY_M_PC_TX_FFD_MSK    (3<<14) /* Bit 15..14:  Tx FIFO Depth Mask */
-#define PHY_M_PC_RX_FFD_MSK    (3<<12) /* Bit 13..12:  Rx FIFO Depth Mask */
-#define PHY_M_PC_ASS_CRS_TX    (1<<11) /* Bit 11:      Assert CRS on Transmit */
-#define PHY_M_PC_FL_GOOD       (1<<10) /* Bit 10:      Force Link Good */
-#define PHY_M_PC_EN_DET_MSK    (3<<8)  /* Bit  9.. 8:  Energy Detect Mask */
-#define PHY_M_PC_ENA_EXT_D     (1<<7)  /* Bit  7:      Enable Ext. Distance (10BT) */
-#define PHY_M_PC_MDIX_MSK      (3<<5)  /* Bit  6.. 5:  MDI/MDIX Config. Mask */
-#define PHY_M_PC_DIS_125CLK    (1<<4)  /* Bit  4:      Disable 125 CLK */
-#define PHY_M_PC_MAC_POW_UP    (1<<3)  /* Bit  3:      MAC Power up */
-#define PHY_M_PC_SQE_T_ENA     (1<<2)  /* Bit  2:      SQE Test Enabled */
-#define PHY_M_PC_POL_R_DIS     (1<<1)  /* Bit  1:      Polarity Reversal Disabled */
-#define PHY_M_PC_DIS_JABBER    (1<<0)  /* Bit  0:      Disable Jabber */
-
-#define PHY_M_PC_EN_DET                        SHIFT8(2)       /* Energy Detect (Mode 1) */
-#define PHY_M_PC_EN_DET_PLUS   SHIFT8(3)       /* Energy Detect Plus (Mode 2) */
-
-#define PHY_M_PC_MDI_XMODE(x)  SHIFT5(x)       
-#define PHY_M_PC_MAN_MDI       0       /* 00 = Manual MDI configuration */
-#define PHY_M_PC_MAN_MDIX      1               /* 01 = Manual MDIX configuration */
-#define PHY_M_PC_ENA_AUTO      3               /* 11 = Enable Automatic Crossover */
-
-/*****  PHY_MARV_PHY_STAT      16 bit r/o      PHY Specific Status Reg *****/
-#define PHY_M_PS_SPEED_MSK     (3<<14) /* Bit 15..14:  Speed Mask */
-#define PHY_M_PS_SPEED_1000    (1<<15) /*       10 = 1000 Mbps */
-#define PHY_M_PS_SPEED_100     (1<<14) /*       01 =  100 Mbps */
-#define PHY_M_PS_SPEED_10      0               /*       00 =   10 Mbps */
-#define PHY_M_PS_FULL_DUP      (1<<13) /* Bit 13:      Full Duplex */
-#define PHY_M_PS_PAGE_REC      (1<<12) /* Bit 12:      Page Received */
-#define PHY_M_PS_SPDUP_RES     (1<<11) /* Bit 11:      Speed & Duplex Resolved */
-#define PHY_M_PS_LINK_UP       (1<<10) /* Bit 10:      Link Up */
-#define PHY_M_PS_CABLE_MSK     (3<<7)  /* Bit  9.. 7:  Cable Length Mask */
-#define PHY_M_PS_MDI_X_STAT    (1<<6)  /* Bit  6:      MDI Crossover Stat (1=MDIX) */
-#define PHY_M_PS_DOWNS_STAT    (1<<5)  /* Bit  5:      Downshift Status (1=downsh.) */
-#define PHY_M_PS_ENDET_STAT    (1<<4)  /* Bit  4:      Energy Detect Status (1=act) */
-#define PHY_M_PS_TX_P_EN       (1<<3)  /* Bit  3:      Tx Pause Enabled */
-#define PHY_M_PS_RX_P_EN       (1<<2)  /* Bit  2:      Rx Pause Enabled */
-#define PHY_M_PS_POL_REV       (1<<1)  /* Bit  1:      Polarity Reversed */
-#define PHY_M_PC_JABBER                (1<<0)  /* Bit  0:      Jabber */
-
-#define PHY_M_PS_PAUSE_MSK     (PHY_M_PS_TX_P_EN | PHY_M_PS_RX_P_EN)
-
-/*****  PHY_MARV_INT_MASK      16 bit r/w      Interrupt Mask Reg *****/
-/*****  PHY_MARV_INT_STAT      16 bit r/o      Interrupt Status Reg *****/
-#define PHY_M_IS_AN_ERROR      (1<<15) /* Bit 15:      Auto-Negotiation Error */
-#define PHY_M_IS_LSP_CHANGE    (1<<14) /* Bit 14:      Link Speed Changed */
-#define PHY_M_IS_DUP_CHANGE    (1<<13) /* Bit 13:      Duplex Mode Changed */
-#define PHY_M_IS_AN_PR         (1<<12) /* Bit 12:      Page Received */
-#define PHY_M_IS_AN_COMPL      (1<<11) /* Bit 11:      Auto-Negotiation Completed */
-#define PHY_M_IS_LST_CHANGE    (1<<10) /* Bit 10:      Link Status Changed */
-#define PHY_M_IS_SYMB_ERROR    (1<<9)  /* Bit  9:      Symbol Error */
-#define PHY_M_IS_FALSE_CARR    (1<<8)  /* Bit  8:      False Carrier */
-#define PHY_M_IS_FIFO_ERROR    (1<<7)  /* Bit  7:      FIFO Overflow/Underrun Error */
-#define PHY_M_IS_MDI_CHANGE    (1<<6)  /* Bit  6:      MDI Crossover Changed */
-#define PHY_M_IS_DOWNSH_DET    (1<<5)  /* Bit  5:      Downshift Detected */
-#define PHY_M_IS_END_CHANGE    (1<<4)  /* Bit  4:      Energy Detect Changed */
-                                                                       /* Bit  3..2:   reserved */
-#define PHY_M_IS_POL_CHANGE    (1<<1)  /* Bit  1:      Polarity Changed */
-#define PHY_M_IS_JABBER                (1<<0)  /* Bit  0:      Jabber */
-
-#define PHY_M_DEF_MSK          (PHY_M_IS_AN_ERROR | PHY_M_IS_AN_PR | \
-                                                       PHY_M_IS_LST_CHANGE | PHY_M_IS_FIFO_ERROR)
-
-/*****  PHY_MARV_EXT_CTRL      16 bit r/w      Ext. PHY Specific Ctrl *****/
-#define PHY_M_EC_M_DSC_MSK     (3<<10) /* Bit 11..10:  Master downshift counter */
-#define PHY_M_EC_S_DSC_MSK     (3<<8)  /* Bit  9.. 8:  Slave  downshift counter */
-#define PHY_M_EC_MAC_S_MSK     (7<<4)  /* Bit  6.. 4:  Def. MAC interface speed */
-#define PHY_M_EC_FIB_AN_ENA    (1<<3)  /* Bit  3:      Fiber Auto-Neg. Enable */
-
-#define PHY_M_EC_M_DSC(x)              SHIFT10(x)      /* 00=1x; 01=2x; 10=3x; 11=4x */
-#define PHY_M_EC_S_DSC(x)              SHIFT8(x)       /* 00=dis; 01=1x; 10=2x; 11=3x */
-#define PHY_M_EC_MAC_S(x)              SHIFT4(x)       /* 01X=0; 110=2.5; 111=25 (MHz) */
-
-#define MAC_TX_CLK_0_MHZ       2
-#define MAC_TX_CLK_2_5_MHZ     6
-#define MAC_TX_CLK_25_MHZ      7
-
-/*****  PHY_MARV_LED_CTRL      16 bit r/w      LED Control Reg *****/
-#define PHY_M_LEDC_DIS_LED     (1<<15) /* Bit 15:      Disable LED */
-#define PHY_M_LEDC_PULS_MSK    (7<<12) /* Bit 14..12:  Pulse Stretch Mask */
-#define PHY_M_LEDC_F_INT       (1<<11) /* Bit 11:      Force Interrupt */
-#define PHY_M_LEDC_BL_R_MSK    (7<<8)  /* Bit 10.. 8:  Blink Rate Mask */
-                                                                       /* Bit  7.. 5:  reserved */
-#define PHY_M_LEDC_LINK_MSK    (3<<3)  /* Bit  4.. 3:  Link Control Mask */
-#define PHY_M_LEDC_DP_CTRL     (1<<2)  /* Bit  2:      Duplex Control */
-#define PHY_M_LEDC_RX_CTRL     (1<<1)  /* Bit  1:      Rx activity / Link */
-#define PHY_M_LEDC_TX_CTRL     (1<<0)  /* Bit  0:      Tx activity / Link */
-
-#define PHY_M_LED_PULS_DUR(x)  SHIFT12(x)      /* Pulse Stretch Duration */
-
-#define        PULS_NO_STR             0               /* no pulse stretching */
-#define        PULS_21MS               1               /* 21 ms to 42 ms */
-#define PULS_42MS              2               /* 42 ms to 84 ms */
-#define PULS_84MS              3               /* 84 ms to 170 ms */
-#define PULS_170MS             4               /* 170 ms to 340 ms */
-#define PULS_340MS             5               /* 340 ms to 670 ms */
-#define PULS_670MS             6               /* 670 ms to 1.3 s */
-#define PULS_1300MS            7               /* 1.3 s to 2.7 s */
-
-#define PHY_M_LED_BLINK_RT(x)  SHIFT8(x)       /* Blink Rate */
-
-#define BLINK_42MS             0               /* 42 ms */
-#define BLINK_84MS             1               /* 84 ms */
-#define BLINK_170MS            2               /* 170 ms */
-#define BLINK_340MS            3               /* 340 ms */
-#define BLINK_670MS            4               /* 670 ms */
-                                                               /* values 5 - 7: reserved */
-
-/*****  PHY_MARV_LED_OVER      16 bit r/w      Manual LED Override Reg *****/
-#define PHY_M_LED_MO_DUP(x)            SHIFT10(x)      /* Bit 11..10:  Duplex */
-#define PHY_M_LED_MO_10(x)             SHIFT8(x)       /* Bit  9.. 8:  Link 10 */
-#define PHY_M_LED_MO_100(x)            SHIFT6(x)       /* Bit  7.. 6:  Link 100 */
-#define PHY_M_LED_MO_1000(x)   SHIFT4(x)       /* Bit  5.. 4:  Link 1000 */
-#define PHY_M_LED_MO_RX(x)             SHIFT2(x)       /* Bit  3.. 2:  Rx */
-#define PHY_M_LED_MO_TX(x)             SHIFT0(x)       /* Bit  1.. 0:  Tx */
-
-#define MO_LED_NORM                    0
-#define MO_LED_BLINK           1
-#define MO_LED_OFF                     2
-#define MO_LED_ON                      3
-
-/*****  PHY_MARV_EXT_CTRL_2    16 bit r/w      Ext. PHY Specific Ctrl 2 *****/
-                                                                       /* Bit 15.. 7:  reserved */
-#define PHY_M_EC2_FI_IMPED     (1<<6)  /* Bit  6:      Fiber Input  Impedance */
-#define PHY_M_EC2_FO_IMPED     (1<<5)  /* Bit  5:      Fiber Output Impedance */
-#define PHY_M_EC2_FO_M_CLK     (1<<4)  /* Bit  4:      Fiber Mode Clock Enable */
-#define PHY_M_EC2_FO_BOOST     (1<<3)  /* Bit  3:      Fiber Output Boost */
-#define PHY_M_EC2_FO_AM_MSK    7               /* Bit  2.. 0:  Fiber Output Amplitude */
-
-/***** PHY_MARV_EXT_P_STAT 16 bit r/w  Ext. PHY Specific Status *****/
-#define PHY_M_FC_AUTO_SEL      (1<<15) /* Bit 15:      Fiber/Copper Auto Sel. dis. */
-#define PHY_M_FC_AN_REG_ACC (1<<14) /* Bit 14: Fiber/Copper Autoneg. reg acc */
-#define PHY_M_FC_RESULUTION (1<<13)    /* Bit 13:      Fiber/Copper Resulution */
-#define PHY_M_SER_IF_AN_BP  (1<<12) /* Bit 12: Ser IF autoneg. bypass enable */
-#define PHY_M_SER_IF_BP_ST     (1<<11) /* Bit 11:      Ser IF autoneg. bypass status */
-#define PHY_M_IRQ_POLARITY     (1<<10) /* Bit 10:      IRQ polarity */
-                                                                       /* Bit 9..4: reserved */
-#define PHY_M_UNDOC1           (1<< 7) /* undocumented bit !! */
-#define PHY_M_MODE_MASK                (0xf<<0)/* Bit 3..0: copy of HWCFG MODE[3:0] */
-
-
-/*****  PHY_MARV_CABLE_DIAG    16 bit r/o      Cable Diagnostic Reg *****/
-#define PHY_M_CABD_ENA_TEST    (1<<15) /* Bit 15:      Enable Test */
-#define PHY_M_CABD_STAT_MSK    (3<<13) /* Bit 14..13:  Status */
-                                                                       /* Bit 12.. 8:  reserved */
-#define PHY_M_CABD_DIST_MSK    0xff    /* Bit  7.. 0:  Distance */
-
-/* values for Cable Diagnostic Status (11=fail; 00=OK; 10=open; 01=short) */
-#define CABD_STAT_NORMAL       0
-#define CABD_STAT_SHORT                1
-#define CABD_STAT_OPEN         2
-#define CABD_STAT_FAIL         3
-
-
-/*
- * GMAC registers
- *
- * The GMAC registers are 16 or 32 bits wide.
- * The GMACs host processor interface is 16 bits wide,
- * therefore ALL registers will be addressed with 16 bit accesses.
- *
- * The following macros are provided to access the GMAC registers
- * GM_IN16(), GM_OUT16, GM_IN32(), GM_OUT32(), GM_INADR(), GM_OUTADR(),
- * GM_INHASH(), and GM_OUTHASH().
- * The macros are defined in SkGeHw.h.
- *
- * Note:       NA reg  = Network Address e.g DA, SA etc.
- *
- */
-
-/* Port Registers */
-#define GM_GP_STAT             0x0000          /* 16 bit r/o   General Purpose Status */
-#define GM_GP_CTRL             0x0004          /* 16 bit r/w   General Purpose Control */
-#define GM_TX_CTRL             0x0008          /* 16 bit r/w   Transmit Control Reg. */
-#define GM_RX_CTRL             0x000c          /* 16 bit r/w   Receive Control Reg. */
-#define GM_TX_FLOW_CTRL        0x0010          /* 16 bit r/w   Transmit Flow-Control */
-#define GM_TX_PARAM            0x0014          /* 16 bit r/w   Transmit Parameter Reg. */
-#define GM_SERIAL_MODE 0x0018          /* 16 bit r/w   Serial Mode Register */
-
-/* Source Address Registers */
-#define GM_SRC_ADDR_1L 0x001c          /* 16 bit r/w   Source Address 1 (low) */
-#define GM_SRC_ADDR_1M 0x0020          /* 16 bit r/w   Source Address 1 (middle) */
-#define GM_SRC_ADDR_1H 0x0024          /* 16 bit r/w   Source Address 1 (high) */
-#define GM_SRC_ADDR_2L 0x0028          /* 16 bit r/w   Source Address 2 (low) */
-#define GM_SRC_ADDR_2M 0x002c          /* 16 bit r/w   Source Address 2 (middle) */
-#define GM_SRC_ADDR_2H 0x0030          /* 16 bit r/w   Source Address 2 (high) */
-
-/* Multicast Address Hash Registers */
-#define GM_MC_ADDR_H1  0x0034          /* 16 bit r/w   Multicast Address Hash 1 */
-#define GM_MC_ADDR_H2  0x0038          /* 16 bit r/w   Multicast Address Hash 2 */
-#define GM_MC_ADDR_H3  0x003c          /* 16 bit r/w   Multicast Address Hash 3 */
-#define GM_MC_ADDR_H4  0x0040          /* 16 bit r/w   Multicast Address Hash 4 */
-
-/* Interrupt Source Registers */
-#define GM_TX_IRQ_SRC  0x0044          /* 16 bit r/o   Tx Overflow IRQ Source */
-#define GM_RX_IRQ_SRC  0x0048          /* 16 bit r/o   Rx Overflow IRQ Source */
-#define GM_TR_IRQ_SRC  0x004c          /* 16 bit r/o   Tx/Rx Over. IRQ Source */
-
-/* Interrupt Mask Registers */
-#define GM_TX_IRQ_MSK  0x0050          /* 16 bit r/w   Tx Overflow IRQ Mask */
-#define GM_RX_IRQ_MSK  0x0054          /* 16 bit r/w   Rx Overflow IRQ Mask */
-#define GM_TR_IRQ_MSK  0x0058          /* 16 bit r/w   Tx/Rx Over. IRQ Mask */
-
-/* Serial Management Interface (SMI) Registers */
-#define GM_SMI_CTRL            0x0080          /* 16 bit r/w   SMI Control Register */
-#define GM_SMI_DATA            0x0084          /* 16 bit r/w   SMI Data Register */
-#define GM_PHY_ADDR            0x0088          /* 16 bit r/w   GPHY Address Register */
-
-/* MIB Counters */
-#define GM_MIB_CNT_BASE        0x0100          /* Base Address of MIB Counters */
-#define GM_MIB_CNT_SIZE        44                      /* Number of MIB Counters */
-
-/*
- * MIB Counters base address definitions (low word) -
- * use offset 4 for access to high word        (32 bit r/o)
- */
-#define GM_RXF_UC_OK \
-                       (GM_MIB_CNT_BASE + 0)   /* Unicast Frames Received OK */
-#define GM_RXF_BC_OK \
-                       (GM_MIB_CNT_BASE + 8)   /* Broadcast Frames Received OK */
-#define GM_RXF_MPAUSE \
-                       (GM_MIB_CNT_BASE + 16)  /* Pause MAC Ctrl Frames Received */
-#define GM_RXF_MC_OK \
-                       (GM_MIB_CNT_BASE + 24)  /* Multicast Frames Received OK */
-#define GM_RXF_FCS_ERR \
-                       (GM_MIB_CNT_BASE + 32)  /* Rx Frame Check Seq. Error */
-       /* GM_MIB_CNT_BASE + 40:        reserved */
-#define GM_RXO_OK_LO \
-                       (GM_MIB_CNT_BASE + 48)  /* Octets Received OK Low */
-#define GM_RXO_OK_HI \
-                       (GM_MIB_CNT_BASE + 56)  /* Octets Received OK High */
-#define GM_RXO_ERR_LO \
-                       (GM_MIB_CNT_BASE + 64)  /* Octets Received Invalid Low */
-#define GM_RXO_ERR_HI \
-                       (GM_MIB_CNT_BASE + 72)  /* Octets Received Invalid High */
-#define GM_RXF_SHT \
-                       (GM_MIB_CNT_BASE + 80)  /* Frames <64 Byte Received OK */
-#define GM_RXE_FRAG \
-                       (GM_MIB_CNT_BASE + 88)  /* Frames <64 Byte Received with FCS Err */
-#define GM_RXF_64B \
-                       (GM_MIB_CNT_BASE + 96)  /* 64 Byte Rx Frame */
-#define GM_RXF_127B \
-                       (GM_MIB_CNT_BASE + 104) /* 65-127 Byte Rx Frame */
-#define GM_RXF_255B \
-                       (GM_MIB_CNT_BASE + 112) /* 128-255 Byte Rx Frame */
-#define GM_RXF_511B \
-                       (GM_MIB_CNT_BASE + 120) /* 256-511 Byte Rx Frame */
-#define GM_RXF_1023B \
-                       (GM_MIB_CNT_BASE + 128) /* 512-1023 Byte Rx Frame */
-#define GM_RXF_1518B \
-                       (GM_MIB_CNT_BASE + 136) /* 1024-1518 Byte Rx Frame */
-#define GM_RXF_MAX_SZ \
-                       (GM_MIB_CNT_BASE + 144) /* 1519-MaxSize Byte Rx Frame */
-#define GM_RXF_LNG_ERR \
-                       (GM_MIB_CNT_BASE + 152) /* Rx Frame too Long Error */
-#define GM_RXF_JAB_PKT \
-                       (GM_MIB_CNT_BASE + 160) /* Rx Jabber Packet Frame */
-       /* GM_MIB_CNT_BASE + 168:       reserved */
-#define GM_RXE_FIFO_OV \
-                       (GM_MIB_CNT_BASE + 176) /* Rx FIFO overflow Event */
-       /* GM_MIB_CNT_BASE + 184:       reserved */
-#define GM_TXF_UC_OK \
-                       (GM_MIB_CNT_BASE + 192) /* Unicast Frames Xmitted OK */
-#define GM_TXF_BC_OK \
-                       (GM_MIB_CNT_BASE + 200) /* Broadcast Frames Xmitted OK */
-#define GM_TXF_MPAUSE \
-                       (GM_MIB_CNT_BASE + 208) /* Pause MAC Ctrl Frames Xmitted */
-#define GM_TXF_MC_OK \
-                       (GM_MIB_CNT_BASE + 216) /* Multicast Frames Xmitted OK */
-#define GM_TXO_OK_LO \
-                       (GM_MIB_CNT_BASE + 224) /* Octets Transmitted OK Low */
-#define GM_TXO_OK_HI \
-                       (GM_MIB_CNT_BASE + 232) /* Octets Transmitted OK High */
-#define GM_TXF_64B \
-                       (GM_MIB_CNT_BASE + 240) /* 64 Byte Tx Frame */
-#define GM_TXF_127B \
-                       (GM_MIB_CNT_BASE + 248) /* 65-127 Byte Tx Frame */
-#define GM_TXF_255B \
-                       (GM_MIB_CNT_BASE + 256) /* 128-255 Byte Tx Frame */
-#define GM_TXF_511B \
-                       (GM_MIB_CNT_BASE + 264) /* 256-511 Byte Tx Frame */
-#define GM_TXF_1023B \
-                       (GM_MIB_CNT_BASE + 272) /* 512-1023 Byte Tx Frame */
-#define GM_TXF_1518B \
-                       (GM_MIB_CNT_BASE + 280) /* 1024-1518 Byte Tx Frame */
-#define GM_TXF_MAX_SZ \
-                       (GM_MIB_CNT_BASE + 288) /* 1519-MaxSize Byte Tx Frame */
-       /* GM_MIB_CNT_BASE + 296:       reserved */
-#define GM_TXF_COL \
-                       (GM_MIB_CNT_BASE + 304) /* Tx Collision */
-#define GM_TXF_LAT_COL \
-                       (GM_MIB_CNT_BASE + 312) /* Tx Late Collision */
-#define GM_TXF_ABO_COL \
-                       (GM_MIB_CNT_BASE + 320) /* Tx aborted due to Exces. Col. */
-#define GM_TXF_MUL_COL \
-                       (GM_MIB_CNT_BASE + 328) /* Tx Multiple Collision */
-#define GM_TXF_SNG_COL \
-                       (GM_MIB_CNT_BASE + 336) /* Tx Single Collision */
-#define GM_TXE_FIFO_UR \
-                       (GM_MIB_CNT_BASE + 344) /* Tx FIFO Underrun Event */
-
-/*----------------------------------------------------------------------------*/
-/*
- * GMAC Bit Definitions
- *
- * If the bit access behaviour differs from the register access behaviour
- * (r/w, r/o) this is documented after the bit number.
- * The following bit access behaviours are used:
- *     (sc)    self clearing
- *     (r/o)   read only
- */
-
-/*     GM_GP_STAT      16 bit r/o      General Purpose Status Register */
-#define GM_GPSR_SPEED          (1<<15) /* Bit 15:      Port Speed (1 = 100 Mbps) */
-#define GM_GPSR_DUPLEX         (1<<14) /* Bit 14:      Duplex Mode (1 = Full) */
-#define GM_GPSR_FC_TX_DIS      (1<<13) /* Bit 13:      Tx Flow-Control Mode Disabled */
-#define GM_GPSR_LINK_UP                (1<<12) /* Bit 12:      Link Up Status */
-#define GM_GPSR_PAUSE          (1<<11) /* Bit 11:      Pause State */
-#define GM_GPSR_TX_ACTIVE      (1<<10) /* Bit 10:      Tx in Progress */
-#define GM_GPSR_EXC_COL                (1<<9)  /* Bit  9:      Excessive Collisions Occured */
-#define GM_GPSR_LAT_COL                (1<<8)  /* Bit  8:      Late Collisions Occured */
-                                                               /* Bit  7..6:   reserved */
-#define GM_GPSR_PHY_ST_CH      (1<<5)  /* Bit  5:      PHY Status Change */
-#define GM_GPSR_GIG_SPEED      (1<<4)  /* Bit  4:      Gigabit Speed (1 = 1000 Mbps) */
-#define GM_GPSR_PART_MODE      (1<<3)  /* Bit  3:      Partition mode */
-#define GM_GPSR_FC_RX_DIS      (1<<2)  /* Bit  2:      Rx Flow-Control Mode Disabled */
-#define GM_GPSR_PROM_EN                (1<<1)  /* Bit  1:      Promiscuous Mode Enabled */
-                                                               /* Bit  0:      reserved */
-       
-/*     GM_GP_CTRL      16 bit r/w      General Purpose Control Register */
-                                                               /* Bit 15:      reserved */
-#define GM_GPCR_PROM_ENA       (1<<14) /* Bit 14:      Enable Promiscuous Mode */
-#define GM_GPCR_FC_TX_DIS      (1<<13) /* Bit 13:      Disable Tx Flow-Control Mode */
-#define GM_GPCR_TX_ENA         (1<<12) /* Bit 12:      Enable Transmit */
-#define GM_GPCR_RX_ENA         (1<<11) /* Bit 11:      Enable Receive */
-#define GM_GPCR_BURST_ENA      (1<<10) /* Bit 10:      Enable Burst Mode */
-#define GM_GPCR_LOOP_ENA       (1<<9)  /* Bit  9:      Enable MAC Loopback Mode */
-#define GM_GPCR_PART_ENA       (1<<8)  /* Bit  8:      Enable Partition Mode */
-#define GM_GPCR_GIGS_ENA       (1<<7)  /* Bit  7:      Gigabit Speed (1000 Mbps) */
-#define GM_GPCR_FL_PASS                (1<<6)  /* Bit  6:      Force Link Pass */
-#define GM_GPCR_DUP_FULL       (1<<5)  /* Bit  5:      Full Duplex Mode */
-#define GM_GPCR_FC_RX_DIS      (1<<4)  /* Bit  4:      Disable Rx Flow-Control Mode */
-#define GM_GPCR_SPEED_100      (1<<3)  /* Bit  3:      Port Speed 100 Mbps */
-#define GM_GPCR_AU_DUP_DIS     (1<<2)  /* Bit  2:      Disable Auto-Update Duplex */
-#define GM_GPCR_AU_FCT_DIS     (1<<1)  /* Bit  1:      Disable Auto-Update Flow-C. */
-#define GM_GPCR_AU_SPD_DIS     (1<<0)  /* Bit  0:      Disable Auto-Update Speed */
-
-#define GM_GPCR_SPEED_1000     (GM_GPCR_GIGS_ENA | GM_GPCR_SPEED_100)
-#define GM_GPCR_AU_ALL_DIS     (GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_FCT_DIS |\
-                                                        GM_GPCR_AU_SPD_DIS)
-       
-/*     GM_TX_CTRL                              16 bit r/w      Transmit Control Register */
-#define GM_TXCR_FORCE_JAM      (1<<15) /* Bit 15:      Force Jam / Flow-Control */
-#define GM_TXCR_CRC_DIS                (1<<14) /* Bit 14:      Disable insertion of CRC */
-#define GM_TXCR_PAD_DIS                (1<<13) /* Bit 13:      Disable padding of packets */
-#define GM_TXCR_COL_THR_MSK    (7<<10) /* Bit 12..10:  Collision Threshold */
-
-#define TX_COL_THR(x)          (SHIFT10(x) & GM_TXCR_COL_THR_MSK)
-
-#define TX_COL_DEF                     0x04
-       
-/*     GM_RX_CTRL                              16 bit r/w      Receive Control Register */
-#define GM_RXCR_UCF_ENA                (1<<15) /* Bit 15:      Enable Unicast filtering */
-#define GM_RXCR_MCF_ENA                (1<<14) /* Bit 14:      Enable Multicast filtering */
-#define GM_RXCR_CRC_DIS                (1<<13) /* Bit 13:      Remove 4-byte CRC */
-#define GM_RXCR_PASS_FC                (1<<12) /* Bit 12:      Pass FC packets to FIFO */
-       
-/*     GM_TX_PARAM                             16 bit r/w      Transmit Parameter Register */
-#define GM_TXPA_JAMLEN_MSK     (0x03<<14)      /* Bit 15..14:  Jam Length */
-#define GM_TXPA_JAMIPG_MSK     (0x1f<<9)       /* Bit 13..9:   Jam IPG */
-#define GM_TXPA_JAMDAT_MSK     (0x1f<<4)       /* Bit  8..4:   IPG Jam to Data */
-                                                               /* Bit  3..0:   reserved */
-
-#define TX_JAM_LEN_VAL(x)      (SHIFT14(x) & GM_TXPA_JAMLEN_MSK)
-#define TX_JAM_IPG_VAL(x)      (SHIFT9(x) & GM_TXPA_JAMIPG_MSK)
-#define TX_IPG_JAM_DATA(x)     (SHIFT4(x) & GM_TXPA_JAMDAT_MSK)
-
-#define TX_JAM_LEN_DEF         0x03
-#define TX_JAM_IPG_DEF         0x0b
-#define TX_IPG_JAM_DEF         0x1c
-
-/*     GM_SERIAL_MODE                  16 bit r/w      Serial Mode Register */
-#define GM_SMOD_DATABL_MSK     (0x1f<<11)      /* Bit 15..11:  Data Blinder (r/o) */
-#define GM_SMOD_LIMIT_4                (1<<10) /* Bit 10:      4 consecutive Tx trials */
-#define GM_SMOD_VLAN_ENA       (1<<9)  /* Bit  9:      Enable VLAN  (Max. Frame Len) */
-#define GM_SMOD_JUMBO_ENA      (1<<8)  /* Bit  8:      Enable Jumbo (Max. Frame Len) */
-                                                               /* Bit  7..5:   reserved */
-#define GM_SMOD_IPG_MSK                0x1f    /* Bit 4..0:    Inter-Packet Gap (IPG) */
-       
-#define DATA_BLIND_VAL(x)      (SHIFT11(x) & GM_SMOD_DATABL_MSK)
-#define DATA_BLIND_DEF         0x04
-
-#define IPG_DATA_VAL(x)                (x & GM_SMOD_IPG_MSK)
-#define IPG_DATA_DEF           0x1e
-
-/*     GM_SMI_CTRL                             16 bit r/w      SMI Control Register */
-#define GM_SMI_CT_PHY_A_MSK    (0x1f<<11)      /* Bit 15..11:  PHY Device Address */
-#define GM_SMI_CT_REG_A_MSK    (0x1f<<6)       /* Bit 10.. 6:  PHY Register Address */
-#define GM_SMI_CT_OP_RD                (1<<5)  /* Bit  5:      OpCode Read (0=Write)*/
-#define GM_SMI_CT_RD_VAL       (1<<4)  /* Bit  4:      Read Valid (Read completed) */
-#define GM_SMI_CT_BUSY         (1<<3)  /* Bit  3:      Busy (Operation in progress) */
-                                                               /* Bit   2..0:  reserved */
-       
-#define GM_SMI_CT_PHY_AD(x)    (SHIFT11(x) & GM_SMI_CT_PHY_A_MSK)
-#define GM_SMI_CT_REG_AD(x)    (SHIFT6(x) & GM_SMI_CT_REG_A_MSK)
-
-       /*      GM_PHY_ADDR                             16 bit r/w      GPHY Address Register */
-                                                               /* Bit  15..6:  reserved */
-#define GM_PAR_MIB_CLR         (1<<5)  /* Bit  5:      Set MIB Clear Counter Mode */
-#define GM_PAR_MIB_TST         (1<<4)  /* Bit  4:      MIB Load Counter (Test Mode) */
-                                                               /* Bit   3..0:  reserved */
-       
-/* Receive Frame Status Encoding */
-#define GMR_FS_LEN     (0xffffUL<<16)  /* Bit 31..16:  Rx Frame Length */
-                                                               /* Bit  15..14: reserved */
-#define GMR_FS_VLAN            (1L<<13)        /* Bit 13:      VLAN Packet */
-#define GMR_FS_JABBER  (1L<<12)        /* Bit 12:      Jabber Packet */
-#define GMR_FS_UN_SIZE (1L<<11)        /* Bit 11:      Undersize Packet */
-#define GMR_FS_MC              (1L<<10)        /* Bit 10:      Multicast Packet */
-#define GMR_FS_BC              (1L<<9)         /* Bit  9:      Broadcast Packet */
-#define GMR_FS_RX_OK   (1L<<8)         /* Bit  8:      Receive OK (Good Packet) */
-#define GMR_FS_GOOD_FC (1L<<7)         /* Bit  7:      Good Flow-Control Packet */
-#define GMR_FS_BAD_FC  (1L<<6)         /* Bit  6:      Bad  Flow-Control Packet */
-#define GMR_FS_MII_ERR (1L<<5)         /* Bit  5:      MII Error */
-#define GMR_FS_LONG_ERR        (1L<<4)         /* Bit  4:      Too Long Packet */
-#define GMR_FS_FRAGMENT        (1L<<3)         /* Bit  3:      Fragment */
-                                                               /* Bit  2:      reserved */
-#define GMR_FS_CRC_ERR (1L<<1)         /* Bit  1:      CRC Error */
-#define GMR_FS_RX_FF_OV        (1L<<0)         /* Bit  0:      Rx FIFO Overflow */
-
-/*
- * GMR_FS_ANY_ERR (analogous to XMR_FS_ANY_ERR)
- */
-#define GMR_FS_ANY_ERR (GMR_FS_CRC_ERR | \
-                       GMR_FS_LONG_ERR | \
-                       GMR_FS_MII_ERR | \
-                       GMR_FS_BAD_FC | \
-                       GMR_FS_GOOD_FC | \
-                       GMR_FS_JABBER)
-
-/* Rx GMAC FIFO Flush Mask (default) */
-#define RX_FF_FL_DEF_MSK       (GMR_FS_CRC_ERR | \
-                       GMR_FS_RX_FF_OV | \
-                       GMR_FS_MII_ERR | \
-                       GMR_FS_BAD_FC | \
-                       GMR_FS_GOOD_FC | \
-                       GMR_FS_UN_SIZE | \
-                       GMR_FS_JABBER)
-
-/* typedefs *******************************************************************/
-
-
-/* function prototypes ********************************************************/
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __INC_XMAC_H */
diff --git a/drivers/net/sk98lin/skaddr.c b/drivers/net/sk98lin/skaddr.c
deleted file mode 100644 (file)
index 6e6c56a..0000000
+++ /dev/null
@@ -1,1788 +0,0 @@
-/******************************************************************************
- *
- * Name:       skaddr.c
- * Project:    Gigabit Ethernet Adapters, ADDR-Module
- * Version:    $Revision: 1.52 $
- * Date:       $Date: 2003/06/02 13:46:15 $
- * Purpose:    Manage Addresses (Multicast and Unicast) and Promiscuous Mode.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect GmbH.
- *     (C)Copyright 2002-2003 Marvell.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * Description:
- *
- * This module is intended to manage multicast addresses, address override,
- * and promiscuous mode on GEnesis and Yukon adapters.
- *
- * Address Layout:
- *     port address:           physical MAC address
- *     1st exact match:        logical MAC address (GEnesis only)
- *     2nd exact match:        RLMT multicast (GEnesis only)
- *     exact match 3-13:       OS-specific multicasts (GEnesis only)
- *
- * Include File Hierarchy:
- *
- *     "skdrv1st.h"
- *     "skdrv2nd.h"
- *
- ******************************************************************************/
-
-#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
-static const char SysKonnectFileId[] =
-       "@(#) $Id: skaddr.c,v 1.52 2003/06/02 13:46:15 tschilli Exp $ (C) Marvell.";
-#endif /* DEBUG ||!LINT || !SK_SLIM */
-
-#define __SKADDR_C
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* cplusplus */
-
-#include "h/skdrv1st.h"
-#include "h/skdrv2nd.h"
-
-/* defines ********************************************************************/
-
-
-#define XMAC_POLY      0xEDB88320UL    /* CRC32-Poly - XMAC: Little Endian */
-#define GMAC_POLY      0x04C11DB7L     /* CRC16-Poly - GMAC: Little Endian */
-#define HASH_BITS      6                               /* #bits in hash */
-#define        SK_MC_BIT       0x01
-
-/* Error numbers and messages. */
-
-#define SKERR_ADDR_E001                (SK_ERRBASE_ADDR + 0)
-#define SKERR_ADDR_E001MSG     "Bad Flags."
-#define SKERR_ADDR_E002                (SKERR_ADDR_E001 + 1)
-#define SKERR_ADDR_E002MSG     "New Error."
-
-/* typedefs *******************************************************************/
-
-/* None. */
-
-/* global variables ***********************************************************/
-
-/* 64-bit hash values with all bits set. */
-
-static const SK_U16    OnesHash[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
-
-/* local variables ************************************************************/
-
-#ifdef DEBUG
-static int     Next0[SK_MAX_MACS] = {0};
-#endif /* DEBUG */
-
-static int SkAddrGmacMcAdd(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber,
-                          SK_MAC_ADDR *pMc, int Flags);
-static int SkAddrGmacMcClear(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber,
-                            int Flags);
-static int SkAddrGmacMcUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber);
-static int SkAddrGmacPromiscuousChange(SK_AC *pAC, SK_IOC IoC,
-                                      SK_U32 PortNumber, int NewPromMode);
-static int SkAddrXmacMcAdd(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber,
-                          SK_MAC_ADDR *pMc, int Flags);
-static int SkAddrXmacMcClear(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber,
-                            int Flags);
-static int SkAddrXmacMcUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber);
-static int SkAddrXmacPromiscuousChange(SK_AC *pAC, SK_IOC IoC,
-                                      SK_U32 PortNumber, int NewPromMode);
-
-/* functions ******************************************************************/
-
-/******************************************************************************
- *
- *     SkAddrInit - initialize data, set state to init
- *
- * Description:
- *
- *     SK_INIT_DATA
- *     ============
- *
- *     This routine clears the multicast tables and resets promiscuous mode.
- *     Some entries are reserved for the "logical MAC address", the
- *     SK-RLMT multicast address, and the BPDU multicast address.
- *
- *
- *     SK_INIT_IO
- *     ==========
- *
- *     All permanent MAC addresses are read from EPROM.
- *     If the current MAC addresses are not already set in software,
- *     they are set to the values of the permanent addresses.
- *     The current addresses are written to the corresponding MAC.
- *
- *
- *     SK_INIT_RUN
- *     ===========
- *
- *     Nothing.
- *
- * Context:
- *     init, pageable
- *
- * Returns:
- *     SK_ADDR_SUCCESS
- */
-int    SkAddrInit(
-SK_AC  *pAC,   /* the adapter context */
-SK_IOC IoC,    /* I/O context */
-int            Level)  /* initialization level */
-{
-       int                     j;
-       SK_U32          i;
-       SK_U8           *InAddr;
-       SK_U16          *OutAddr;
-       SK_ADDR_PORT    *pAPort;
-
-       switch (Level) {
-       case SK_INIT_DATA:
-               SK_MEMSET((char *) &pAC->Addr, (SK_U8) 0,
-            (SK_U16) sizeof(SK_ADDR));
-
-               for (i = 0; i < SK_MAX_MACS; i++) {
-                       pAPort = &pAC->Addr.Port[i];
-                       pAPort->PromMode = SK_PROM_MODE_NONE;
-                       
-                       pAPort->FirstExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT;
-                       pAPort->FirstExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV;
-                       pAPort->NextExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT;
-                       pAPort->NextExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV;
-               }
-#ifdef xDEBUG
-               for (i = 0; i < SK_MAX_MACS; i++) {
-                       if (pAC->Addr.Port[i].NextExactMatchRlmt <
-                               SK_ADDR_FIRST_MATCH_RLMT) {
-                               Next0[i] |= 4;
-                       }
-               }
-#endif /* DEBUG */
-               /* pAC->Addr.InitDone = SK_INIT_DATA; */
-               break;
-
-    case SK_INIT_IO:
-#ifndef SK_NO_RLMT
-               for (i = 0; i < SK_MAX_NETS; i++) {
-                       pAC->Addr.Net[i].ActivePort = pAC->Rlmt.Net[i].ActivePort;
-               }
-#endif /* !SK_NO_RLMT */
-#ifdef xDEBUG
-               for (i = 0; i < SK_MAX_MACS; i++) {
-                       if (pAC->Addr.Port[i].NextExactMatchRlmt <
-                               SK_ADDR_FIRST_MATCH_RLMT) {
-                               Next0[i] |= 8;
-                       }
-               }
-#endif /* DEBUG */
-               
-               /* Read permanent logical MAC address from Control Register File. */
-               for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
-                       InAddr = (SK_U8 *) &pAC->Addr.Net[0].PermanentMacAddress.a[j];
-                       SK_IN8(IoC, B2_MAC_1 + j, InAddr);
-               }
-
-               if (!pAC->Addr.Net[0].CurrentMacAddressSet) {
-                       /* Set the current logical MAC address to the permanent one. */
-                       pAC->Addr.Net[0].CurrentMacAddress =
-                               pAC->Addr.Net[0].PermanentMacAddress;
-                       pAC->Addr.Net[0].CurrentMacAddressSet = SK_TRUE;
-               }
-
-               /* Set the current logical MAC address. */
-               pAC->Addr.Port[pAC->Addr.Net[0].ActivePort].Exact[0] =
-                       pAC->Addr.Net[0].CurrentMacAddress;
-#if SK_MAX_NETS > 1
-               /* Set logical MAC address for net 2 to (log | 3). */
-               if (!pAC->Addr.Net[1].CurrentMacAddressSet) {
-                       pAC->Addr.Net[1].PermanentMacAddress =
-                               pAC->Addr.Net[0].PermanentMacAddress;
-                       pAC->Addr.Net[1].PermanentMacAddress.a[5] |= 3;
-                       /* Set the current logical MAC address to the permanent one. */
-                       pAC->Addr.Net[1].CurrentMacAddress =
-                               pAC->Addr.Net[1].PermanentMacAddress;
-                       pAC->Addr.Net[1].CurrentMacAddressSet = SK_TRUE;
-               }
-#endif /* SK_MAX_NETS > 1 */
-
-#ifdef DEBUG
-               for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
-                       SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT,
-                               ("Permanent MAC Address (Net%d): %02X %02X %02X %02X %02X %02X\n",
-                                       i,
-                                       pAC->Addr.Net[i].PermanentMacAddress.a[0],
-                                       pAC->Addr.Net[i].PermanentMacAddress.a[1],
-                                       pAC->Addr.Net[i].PermanentMacAddress.a[2],
-                                       pAC->Addr.Net[i].PermanentMacAddress.a[3],
-                                       pAC->Addr.Net[i].PermanentMacAddress.a[4],
-                                       pAC->Addr.Net[i].PermanentMacAddress.a[5]))
-                       
-                       SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT,
-                               ("Logical MAC Address (Net%d): %02X %02X %02X %02X %02X %02X\n",
-                                       i,
-                                       pAC->Addr.Net[i].CurrentMacAddress.a[0],
-                                       pAC->Addr.Net[i].CurrentMacAddress.a[1],
-                                       pAC->Addr.Net[i].CurrentMacAddress.a[2],
-                                       pAC->Addr.Net[i].CurrentMacAddress.a[3],
-                                       pAC->Addr.Net[i].CurrentMacAddress.a[4],
-                                       pAC->Addr.Net[i].CurrentMacAddress.a[5]))
-               }
-#endif /* DEBUG */
-
-               for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
-                       pAPort = &pAC->Addr.Port[i];
-
-                       /* Read permanent port addresses from Control Register File. */
-                       for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
-                               InAddr = (SK_U8 *) &pAPort->PermanentMacAddress.a[j];
-                               SK_IN8(IoC, B2_MAC_2 + 8 * i + j, InAddr);
-                       }
-
-                       if (!pAPort->CurrentMacAddressSet) {
-                               /*
-                                * Set the current and previous physical MAC address
-                                * of this port to its permanent MAC address.
-                                */
-                               pAPort->CurrentMacAddress = pAPort->PermanentMacAddress;
-                               pAPort->PreviousMacAddress = pAPort->PermanentMacAddress;
-                               pAPort->CurrentMacAddressSet = SK_TRUE;
-                       }
-
-                       /* Set port's current physical MAC address. */
-                       OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0];
-#ifdef GENESIS
-                       if (pAC->GIni.GIGenesis) {
-                               XM_OUTADDR(IoC, i, XM_SA, OutAddr);
-                       }
-#endif /* GENESIS */
-#ifdef YUKON
-                       if (!pAC->GIni.GIGenesis) {
-                               GM_OUTADDR(IoC, i, GM_SRC_ADDR_1L, OutAddr);
-                       }
-#endif /* YUKON */
-#ifdef DEBUG
-                       SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT,
-                               ("SkAddrInit: Permanent Physical MAC Address: %02X %02X %02X %02X %02X %02X\n",
-                                       pAPort->PermanentMacAddress.a[0],
-                                       pAPort->PermanentMacAddress.a[1],
-                                       pAPort->PermanentMacAddress.a[2],
-                                       pAPort->PermanentMacAddress.a[3],
-                                       pAPort->PermanentMacAddress.a[4],
-                                       pAPort->PermanentMacAddress.a[5]))
-                       
-                       SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT,
-                               ("SkAddrInit: Physical MAC Address: %02X %02X %02X %02X %02X %02X\n",
-                                       pAPort->CurrentMacAddress.a[0],
-                                       pAPort->CurrentMacAddress.a[1],
-                                       pAPort->CurrentMacAddress.a[2],
-                                       pAPort->CurrentMacAddress.a[3],
-                                       pAPort->CurrentMacAddress.a[4],
-                                       pAPort->CurrentMacAddress.a[5]))
-#endif /* DEBUG */
-               }
-               /* pAC->Addr.InitDone = SK_INIT_IO; */
-               break;
-
-       case SK_INIT_RUN:
-#ifdef xDEBUG
-               for (i = 0; i < SK_MAX_MACS; i++) {
-                       if (pAC->Addr.Port[i].NextExactMatchRlmt <
-                               SK_ADDR_FIRST_MATCH_RLMT) {
-                               Next0[i] |= 16;
-                       }
-               }
-#endif /* DEBUG */
-
-               /* pAC->Addr.InitDone = SK_INIT_RUN; */
-               break;
-
-       default:        /* error */
-               break;
-       }
-
-       return (SK_ADDR_SUCCESS);
-       
-}      /* SkAddrInit */
-
-#ifndef SK_SLIM
-
-/******************************************************************************
- *
- *     SkAddrMcClear - clear the multicast table
- *
- * Description:
- *     This routine clears the multicast table.
- *
- *     If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated
- *     immediately.
- *
- *     It calls either SkAddrXmacMcClear or SkAddrGmacMcClear, according
- *     to the adapter in use. The real work is done there.
- *
- * Context:
- *     runtime, pageable
- *     may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY
- *     may be called after SK_INIT_IO without limitation
- *
- * Returns:
- *     SK_ADDR_SUCCESS
- *     SK_ADDR_ILLEGAL_PORT
- */
-int    SkAddrMcClear(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* I/O context */
-SK_U32 PortNumber,     /* Index of affected port */
-int            Flags)          /* permanent/non-perm, sw-only */
-{
-       int ReturnCode;
-       
-       if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
-               return (SK_ADDR_ILLEGAL_PORT);
-       }
-       
-       if (pAC->GIni.GIGenesis) {
-               ReturnCode = SkAddrXmacMcClear(pAC, IoC, PortNumber, Flags);
-       }
-       else {
-               ReturnCode = SkAddrGmacMcClear(pAC, IoC, PortNumber, Flags);
-       }
-
-       return (ReturnCode);
-
-}      /* SkAddrMcClear */
-
-#endif /* !SK_SLIM */
-
-#ifndef SK_SLIM
-
-/******************************************************************************
- *
- *     SkAddrXmacMcClear - clear the multicast table
- *
- * Description:
- *     This routine clears the multicast table
- *     (either entry 2 or entries 3-16 and InexactFilter) of the given port.
- *     If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated
- *     immediately.
- *
- * Context:
- *     runtime, pageable
- *     may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY
- *     may be called after SK_INIT_IO without limitation
- *
- * Returns:
- *     SK_ADDR_SUCCESS
- *     SK_ADDR_ILLEGAL_PORT
- */
-static int     SkAddrXmacMcClear(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* I/O context */
-SK_U32 PortNumber,     /* Index of affected port */
-int            Flags)          /* permanent/non-perm, sw-only */
-{
-       int i;
-
-       if (Flags & SK_ADDR_PERMANENT) {        /* permanent => RLMT */
-
-               /* Clear RLMT multicast addresses. */
-               pAC->Addr.Port[PortNumber].NextExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT;
-       }
-       else {  /* not permanent => DRV */
-
-               /* Clear InexactFilter */
-               for (i = 0; i < 8; i++) {
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0;
-               }
-
-               /* Clear DRV multicast addresses. */
-
-               pAC->Addr.Port[PortNumber].NextExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV;
-       }
-
-       if (!(Flags & SK_MC_SW_ONLY)) {
-               (void) SkAddrXmacMcUpdate(pAC, IoC, PortNumber);
-       }
-
-       return (SK_ADDR_SUCCESS);
-       
-}      /* SkAddrXmacMcClear */
-
-#endif /* !SK_SLIM */
-
-#ifndef SK_SLIM
-
-/******************************************************************************
- *
- *     SkAddrGmacMcClear - clear the multicast table
- *
- * Description:
- *     This routine clears the multicast hashing table (InexactFilter)
- *     (either the RLMT or the driver bits) of the given port.
- *
- *     If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated
- *     immediately.
- *
- * Context:
- *     runtime, pageable
- *     may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY
- *     may be called after SK_INIT_IO without limitation
- *
- * Returns:
- *     SK_ADDR_SUCCESS
- *     SK_ADDR_ILLEGAL_PORT
- */
-static int     SkAddrGmacMcClear(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* I/O context */
-SK_U32 PortNumber,     /* Index of affected port */
-int            Flags)          /* permanent/non-perm, sw-only */
-{
-       int i;
-
-#ifdef DEBUG
-       SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
-               ("GMAC InexactFilter (not cleared): %02X %02X %02X %02X %02X %02X %02X %02X\n",
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0],
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[1],
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[2],
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[3],
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[4],
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[5],
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[6],
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7]))
-#endif /* DEBUG */
-
-       /* Clear InexactFilter */
-       for (i = 0; i < 8; i++) {
-               pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0;
-       }
-       
-       if (Flags & SK_ADDR_PERMANENT) {        /* permanent => RLMT */
-               
-               /* Copy DRV bits to InexactFilter. */
-               for (i = 0; i < 8; i++) {
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |=
-                               pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i];
-                       
-                       /* Clear InexactRlmtFilter. */
-                       pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i] = 0;
-
-               }               
-       }
-       else {  /* not permanent => DRV */
-               
-               /* Copy RLMT bits to InexactFilter. */
-               for (i = 0; i < 8; i++) {
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |=
-                               pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i];
-                       
-                       /* Clear InexactDrvFilter. */
-                       pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i] = 0;
-               }
-       }
-       
-#ifdef DEBUG
-       SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
-               ("GMAC InexactFilter (cleared): %02X %02X %02X %02X %02X %02X %02X %02X\n",
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0],
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[1],
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[2],
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[3],
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[4],
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[5],
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[6],
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7]))
-#endif /* DEBUG */
-       
-       if (!(Flags & SK_MC_SW_ONLY)) {
-               (void) SkAddrGmacMcUpdate(pAC, IoC, PortNumber);
-       }
-       
-       return (SK_ADDR_SUCCESS);
-
-}      /* SkAddrGmacMcClear */
-
-#ifndef SK_ADDR_CHEAT
-
-/******************************************************************************
- *
- *     SkXmacMcHash - hash multicast address
- *
- * Description:
- *     This routine computes the hash value for a multicast address.
- *     A CRC32 algorithm is used.
- *
- * Notes:
- *     The code was adapted from the XaQti data sheet.
- *
- * Context:
- *     runtime, pageable
- *
- * Returns:
- *     Hash value of multicast address.
- */
-static SK_U32 SkXmacMcHash(
-unsigned char *pMc)    /* Multicast address */
-{
-       SK_U32 Idx;
-       SK_U32 Bit;
-       SK_U32 Data;
-       SK_U32 Crc;
-
-       Crc = 0xFFFFFFFFUL;
-       for (Idx = 0; Idx < SK_MAC_ADDR_LEN; Idx++) {
-               Data = *pMc++;
-               for (Bit = 0; Bit < 8; Bit++, Data >>= 1) {
-                       Crc = (Crc >> 1) ^ (((Crc ^ Data) & 1) ? XMAC_POLY : 0);
-               }
-       }
-
-       return (Crc & ((1 << HASH_BITS) - 1));
-
-}      /* SkXmacMcHash */
-
-
-/******************************************************************************
- *
- *     SkGmacMcHash - hash multicast address
- *
- * Description:
- *     This routine computes the hash value for a multicast address.
- *     A CRC16 algorithm is used.
- *
- * Notes:
- *
- *
- * Context:
- *     runtime, pageable
- *
- * Returns:
- *     Hash value of multicast address.
- */
-static SK_U32 SkGmacMcHash(
-unsigned char *pMc)    /* Multicast address */
-{
-       SK_U32 Data;
-       SK_U32 TmpData;
-       SK_U32 Crc;
-       int Byte;
-       int Bit;
-
-       Crc = 0xFFFFFFFFUL;
-       for (Byte = 0; Byte < 6; Byte++) {
-               /* Get next byte. */
-               Data = (SK_U32) pMc[Byte];
-               
-               /* Change bit order in byte. */
-               TmpData = Data;
-               for (Bit = 0; Bit < 8; Bit++) {
-                       if (TmpData & 1L) {
-                               Data |=  1L << (7 - Bit);
-                       }
-                       else {
-                               Data &= ~(1L << (7 - Bit));
-                       }
-                       TmpData >>= 1;
-               }
-               
-               Crc ^= (Data << 24);
-               for (Bit = 0; Bit < 8; Bit++) {
-                       if (Crc & 0x80000000) {
-                               Crc = (Crc << 1) ^ GMAC_POLY;
-                       }
-                       else {
-                               Crc <<= 1;
-                       }
-               }
-       }
-       
-       return (Crc & ((1 << HASH_BITS) - 1));
-
-}      /* SkGmacMcHash */
-
-#endif /* !SK_ADDR_CHEAT */
-
-/******************************************************************************
- *
- *     SkAddrMcAdd - add a multicast address to a port
- *
- * Description:
- *     This routine enables reception for a given address on the given port.
- *
- *     It calls either SkAddrXmacMcAdd or SkAddrGmacMcAdd, according to the
- *     adapter in use. The real work is done there.
- *
- * Notes:
- *     The return code is only valid for SK_PROM_MODE_NONE.
- *
- * Context:
- *     runtime, pageable
- *     may be called after SK_INIT_DATA
- *
- * Returns:
- *     SK_MC_FILTERING_EXACT
- *     SK_MC_FILTERING_INEXACT
- *     SK_MC_ILLEGAL_ADDRESS
- *     SK_MC_ILLEGAL_PORT
- *     SK_MC_RLMT_OVERFLOW
- */
-int    SkAddrMcAdd(
-SK_AC          *pAC,           /* adapter context */
-SK_IOC         IoC,            /* I/O context */
-SK_U32         PortNumber,     /* Port Number */
-SK_MAC_ADDR    *pMc,           /* multicast address to be added */
-int                    Flags)          /* permanent/non-permanent */
-{
-       int ReturnCode;
-       
-       if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
-               return (SK_ADDR_ILLEGAL_PORT);
-       }
-       
-       if (pAC->GIni.GIGenesis) {
-               ReturnCode = SkAddrXmacMcAdd(pAC, IoC, PortNumber, pMc, Flags);
-       }
-       else {
-               ReturnCode = SkAddrGmacMcAdd(pAC, IoC, PortNumber, pMc, Flags);
-       }
-
-       return (ReturnCode);
-
-}      /* SkAddrMcAdd */
-
-
-/******************************************************************************
- *
- *     SkAddrXmacMcAdd - add a multicast address to a port
- *
- * Description:
- *     This routine enables reception for a given address on the given port.
- *
- * Notes:
- *     The return code is only valid for SK_PROM_MODE_NONE.
- *
- *     The multicast bit is only checked if there are no free exact match
- *     entries.
- *
- * Context:
- *     runtime, pageable
- *     may be called after SK_INIT_DATA
- *
- * Returns:
- *     SK_MC_FILTERING_EXACT
- *     SK_MC_FILTERING_INEXACT
- *     SK_MC_ILLEGAL_ADDRESS
- *     SK_MC_RLMT_OVERFLOW
- */
-static int     SkAddrXmacMcAdd(
-SK_AC          *pAC,           /* adapter context */
-SK_IOC         IoC,            /* I/O context */
-SK_U32         PortNumber,     /* Port Number */
-SK_MAC_ADDR    *pMc,           /* multicast address to be added */
-int            Flags)          /* permanent/non-permanent */
-{
-       int     i;
-       SK_U8   Inexact;
-#ifndef SK_ADDR_CHEAT
-       SK_U32 HashBit;
-#endif /* !defined(SK_ADDR_CHEAT) */
-
-       if (Flags & SK_ADDR_PERMANENT) {        /* permanent => RLMT */
-#ifdef xDEBUG
-               if (pAC->Addr.Port[PortNumber].NextExactMatchRlmt <
-                       SK_ADDR_FIRST_MATCH_RLMT) {
-                       Next0[PortNumber] |= 1;
-                       return (SK_MC_RLMT_OVERFLOW);
-               }
-#endif /* DEBUG */
-               
-               if (pAC->Addr.Port[PortNumber].NextExactMatchRlmt >
-                       SK_ADDR_LAST_MATCH_RLMT) {
-                       return (SK_MC_RLMT_OVERFLOW);
-               }
-
-               /* Set a RLMT multicast address. */
-
-               pAC->Addr.Port[PortNumber].Exact[
-                       pAC->Addr.Port[PortNumber].NextExactMatchRlmt++] = *pMc;
-
-               return (SK_MC_FILTERING_EXACT);
-       }
-
-#ifdef xDEBUG
-       if (pAC->Addr.Port[PortNumber].NextExactMatchDrv <
-               SK_ADDR_FIRST_MATCH_DRV) {
-                       Next0[PortNumber] |= 2;
-               return (SK_MC_RLMT_OVERFLOW);
-       }
-#endif /* DEBUG */
-       
-       if (pAC->Addr.Port[PortNumber].NextExactMatchDrv <= SK_ADDR_LAST_MATCH_DRV) {
-
-               /* Set exact match entry. */
-               pAC->Addr.Port[PortNumber].Exact[
-                       pAC->Addr.Port[PortNumber].NextExactMatchDrv++] = *pMc;
-
-               /* Clear InexactFilter */
-               for (i = 0; i < 8; i++) {
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0;
-               }
-       }
-       else {
-               if (!(pMc->a[0] & SK_MC_BIT)) {
-                       /* Hashing only possible with multicast addresses */
-                       return (SK_MC_ILLEGAL_ADDRESS);
-               }
-#ifndef SK_ADDR_CHEAT
-               /* Compute hash value of address. */
-               HashBit = 63 - SkXmacMcHash(&pMc->a[0]);
-
-               /* Add bit to InexactFilter. */
-               pAC->Addr.Port[PortNumber].InexactFilter.Bytes[HashBit / 8] |=
-                       1 << (HashBit % 8);
-#else  /* SK_ADDR_CHEAT */
-               /* Set all bits in InexactFilter. */
-               for (i = 0; i < 8; i++) {
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0xFF;
-               }
-#endif /* SK_ADDR_CHEAT */
-       }
-
-       for (Inexact = 0, i = 0; i < 8; i++) {
-               Inexact |= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i];
-       }
-
-       if (Inexact == 0 && pAC->Addr.Port[PortNumber].PromMode == 0) {
-               return (SK_MC_FILTERING_EXACT);
-       }
-       else {
-               return (SK_MC_FILTERING_INEXACT);
-       }
-
-}      /* SkAddrXmacMcAdd */
-
-
-/******************************************************************************
- *
- *     SkAddrGmacMcAdd - add a multicast address to a port
- *
- * Description:
- *     This routine enables reception for a given address on the given port.
- *
- * Notes:
- *     The return code is only valid for SK_PROM_MODE_NONE.
- *
- * Context:
- *     runtime, pageable
- *     may be called after SK_INIT_DATA
- *
- * Returns:
- *     SK_MC_FILTERING_INEXACT
- *     SK_MC_ILLEGAL_ADDRESS
- */
-static int     SkAddrGmacMcAdd(
-SK_AC          *pAC,           /* adapter context */
-SK_IOC         IoC,            /* I/O context */
-SK_U32         PortNumber,     /* Port Number */
-SK_MAC_ADDR    *pMc,           /* multicast address to be added */
-int            Flags)          /* permanent/non-permanent */
-{
-       int     i;
-#ifndef SK_ADDR_CHEAT
-       SK_U32 HashBit;
-#endif /* !defined(SK_ADDR_CHEAT) */
-               
-       if (!(pMc->a[0] & SK_MC_BIT)) {
-               /* Hashing only possible with multicast addresses */
-               return (SK_MC_ILLEGAL_ADDRESS);
-       }
-       
-#ifndef SK_ADDR_CHEAT
-       
-       /* Compute hash value of address. */
-       HashBit = SkGmacMcHash(&pMc->a[0]);
-       
-       if (Flags & SK_ADDR_PERMANENT) {        /* permanent => RLMT */
-               
-               /* Add bit to InexactRlmtFilter. */
-               pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[HashBit / 8] |=
-                       1 << (HashBit % 8);
-               
-               /* Copy bit to InexactFilter. */
-               for (i = 0; i < 8; i++) {
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |=
-                               pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i];
-               }
-#ifdef DEBUG
-               SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
-               ("GMAC InexactRlmtFilter: %02X %02X %02X %02X %02X %02X %02X %02X\n",
-                       pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[0],
-                       pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[1],
-                       pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[2],
-                       pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[3],
-                       pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[4],
-                       pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[5],
-                       pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[6],
-                       pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[7]))
-#endif /* DEBUG */
-       }
-       else {  /* not permanent => DRV */
-               
-               /* Add bit to InexactDrvFilter. */
-               pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[HashBit / 8] |=
-                       1 << (HashBit % 8);
-               
-               /* Copy bit to InexactFilter. */
-               for (i = 0; i < 8; i++) {
-                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |=
-                               pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i];
-               }
-#ifdef DEBUG
-               SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
-               ("GMAC InexactDrvFilter: %02X %02X %02X %02X %02X %02X %02X %02X\n",
-                       pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[0],
-                       pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[1],
-                       pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[2],
-                       pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[3],
-                       pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[4],
-                       pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[5],
-                       pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[6],
-                       pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[7]))
-#endif /* DEBUG */
-       }
-       
-#else  /* SK_ADDR_CHEAT */
-       
-       /* Set all bits in InexactFilter. */
-       for (i = 0; i < 8; i++) {
-               pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0xFF;
-       }
-#endif /* SK_ADDR_CHEAT */
-               
-       return (SK_MC_FILTERING_INEXACT);
-       
-}      /* SkAddrGmacMcAdd */
-
-#endif /* !SK_SLIM */
-
-/******************************************************************************
- *
- *     SkAddrMcUpdate - update the HW MC address table and set the MAC address
- *
- * Description:
- *     This routine enables reception of the addresses contained in a local
- *     table for a given port.
- *     It also programs the port's current physical MAC address.
- *
- *     It calls either SkAddrXmacMcUpdate or SkAddrGmacMcUpdate, according
- *     to the adapter in use. The real work is done there.
- *
- * Notes:
- *     The return code is only valid for SK_PROM_MODE_NONE.
- *
- * Context:
- *     runtime, pageable
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     SK_MC_FILTERING_EXACT
- *     SK_MC_FILTERING_INEXACT
- *     SK_ADDR_ILLEGAL_PORT
- */
-int    SkAddrMcUpdate(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* I/O context */
-SK_U32 PortNumber)     /* Port Number */
-{
-       int ReturnCode = 0;
-#if (!defined(SK_SLIM) || defined(DEBUG))
-       if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
-               return (SK_ADDR_ILLEGAL_PORT);
-       }
-#endif /* !SK_SLIM || DEBUG */
-
-#ifdef GENESIS
-       if (pAC->GIni.GIGenesis) {
-               ReturnCode = SkAddrXmacMcUpdate(pAC, IoC, PortNumber);
-       }
-#endif /* GENESIS */
-#ifdef YUKON
-       if (!pAC->GIni.GIGenesis) {
-               ReturnCode = SkAddrGmacMcUpdate(pAC, IoC, PortNumber);
-       }
-#endif /* YUKON */
-       return (ReturnCode);
-
-}      /* SkAddrMcUpdate */
-
-
-#ifdef GENESIS
-
-/******************************************************************************
- *
- *     SkAddrXmacMcUpdate - update the HW MC address table and set the MAC address
- *
- * Description:
- *     This routine enables reception of the addresses contained in a local
- *     table for a given port.
- *     It also programs the port's current physical MAC address.
- *
- * Notes:
- *     The return code is only valid for SK_PROM_MODE_NONE.
- *
- * Context:
- *     runtime, pageable
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     SK_MC_FILTERING_EXACT
- *     SK_MC_FILTERING_INEXACT
- *     SK_ADDR_ILLEGAL_PORT
- */
-static int     SkAddrXmacMcUpdate(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* I/O context */
-SK_U32 PortNumber)     /* Port Number */
-{
-       SK_U32          i;
-       SK_U8           Inexact;
-       SK_U16          *OutAddr;
-       SK_ADDR_PORT    *pAPort;
-
-       SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
-               ("SkAddrXmacMcUpdate on Port %u.\n", PortNumber))
-       
-       pAPort = &pAC->Addr.Port[PortNumber];
-
-#ifdef DEBUG
-       SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
-               ("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber]))
-#endif /* DEBUG */
-
-       /* Start with 0 to also program the logical MAC address. */
-       for (i = 0; i < pAPort->NextExactMatchRlmt; i++) {
-               /* Set exact match address i on XMAC */
-               OutAddr = (SK_U16 *) &pAPort->Exact[i].a[0];
-               XM_OUTADDR(IoC, PortNumber, XM_EXM(i), OutAddr);
-       }
-
-       /* Clear other permanent exact match addresses on XMAC */
-       if (pAPort->NextExactMatchRlmt <= SK_ADDR_LAST_MATCH_RLMT) {
-               
-               SkXmClrExactAddr(pAC, IoC, PortNumber, pAPort->NextExactMatchRlmt,
-                       SK_ADDR_LAST_MATCH_RLMT);
-       }
-
-       for (i = pAPort->FirstExactMatchDrv; i < pAPort->NextExactMatchDrv; i++) {
-               OutAddr = (SK_U16 *) &pAPort->Exact[i].a[0];
-               XM_OUTADDR(IoC, PortNumber, XM_EXM(i), OutAddr);
-       }
-
-       /* Clear other non-permanent exact match addresses on XMAC */
-       if (pAPort->NextExactMatchDrv <= SK_ADDR_LAST_MATCH_DRV) {
-               
-               SkXmClrExactAddr(pAC, IoC, PortNumber, pAPort->NextExactMatchDrv,
-                       SK_ADDR_LAST_MATCH_DRV);
-       }
-
-       for (Inexact = 0, i = 0; i < 8; i++) {
-               Inexact |= pAPort->InexactFilter.Bytes[i];
-       }
-
-       if (pAPort->PromMode & SK_PROM_MODE_ALL_MC) {
-               
-               /* Set all bits in 64-bit hash register. */
-               XM_OUTHASH(IoC, PortNumber, XM_HSM, &OnesHash);
-               
-               /* Enable Hashing */
-               SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
-       }
-       else if (Inexact != 0) {
-               
-               /* Set 64-bit hash register to InexactFilter. */
-               XM_OUTHASH(IoC, PortNumber, XM_HSM, &pAPort->InexactFilter.Bytes[0]);
-               
-               /* Enable Hashing */
-               SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
-       }
-       else {
-               /* Disable Hashing */
-               SkMacHashing(pAC, IoC, (int) PortNumber, SK_FALSE);
-       }
-
-       if (pAPort->PromMode != SK_PROM_MODE_NONE) {
-               (void) SkAddrXmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode);
-       }
-
-       /* Set port's current physical MAC address. */
-       OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0];
-       
-       XM_OUTADDR(IoC, PortNumber, XM_SA, OutAddr);
-
-#ifdef xDEBUG
-       for (i = 0; i < pAPort->NextExactMatchRlmt; i++) {
-               SK_U8           InAddr8[6];
-               SK_U16          *InAddr;
-
-               /* Get exact match address i from port PortNumber. */
-               InAddr = (SK_U16 *) &InAddr8[0];
-               
-               XM_INADDR(IoC, PortNumber, XM_EXM(i), InAddr);
-               
-               SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
-                       ("SkAddrXmacMcUpdate: MC address %d on Port %u: ",
-                        "%02x %02x %02x %02x %02x %02x -- %02x %02x %02x %02x %02x %02x\n",
-                               i,
-                               PortNumber,
-                               InAddr8[0],
-                               InAddr8[1],
-                               InAddr8[2],
-                               InAddr8[3],
-                               InAddr8[4],
-                               InAddr8[5],
-                               pAPort->Exact[i].a[0],
-                               pAPort->Exact[i].a[1],
-                               pAPort->Exact[i].a[2],
-                               pAPort->Exact[i].a[3],
-                               pAPort->Exact[i].a[4],
-                               pAPort->Exact[i].a[5]))
-       }
-#endif /* DEBUG */
-
-       /* Determine return value. */
-       if (Inexact == 0 && pAPort->PromMode == 0) {
-               return (SK_MC_FILTERING_EXACT);
-       }
-       else {
-               return (SK_MC_FILTERING_INEXACT);
-       }
-       
-}      /* SkAddrXmacMcUpdate */
-
-#endif  /* GENESIS */
-
-#ifdef YUKON
-
-/******************************************************************************
- *
- *     SkAddrGmacMcUpdate - update the HW MC address table and set the MAC address
- *
- * Description:
- *     This routine enables reception of the addresses contained in a local
- *     table for a given port.
- *     It also programs the port's current physical MAC address.
- *
- * Notes:
- *     The return code is only valid for SK_PROM_MODE_NONE.
- *
- * Context:
- *     runtime, pageable
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     SK_MC_FILTERING_EXACT
- *     SK_MC_FILTERING_INEXACT
- *     SK_ADDR_ILLEGAL_PORT
- */
-static int     SkAddrGmacMcUpdate(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* I/O context */
-SK_U32 PortNumber)     /* Port Number */
-{
-#ifndef SK_SLIM
-       SK_U32          i;
-       SK_U8           Inexact;
-#endif /* not SK_SLIM */
-       SK_U16          *OutAddr;
-       SK_ADDR_PORT    *pAPort;
-
-       SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
-               ("SkAddrGmacMcUpdate on Port %u.\n", PortNumber))
-       
-       pAPort = &pAC->Addr.Port[PortNumber];
-
-#ifdef DEBUG
-       SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
-               ("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber]))
-#endif /* DEBUG */
-       
-#ifndef SK_SLIM
-       for (Inexact = 0, i = 0; i < 8; i++) {
-               Inexact |= pAPort->InexactFilter.Bytes[i];
-       }
-       
-       /* Set 64-bit hash register to InexactFilter. */
-       GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1,
-               &pAPort->InexactFilter.Bytes[0]);
-       
-       if (pAPort->PromMode & SK_PROM_MODE_ALL_MC) {                           
-               
-               /* Set all bits in 64-bit hash register. */
-               GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash);
-               
-               /* Enable Hashing */
-               SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
-       }
-       else {  
-               /* Enable Hashing. */
-               SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
-       }
-       
-       if (pAPort->PromMode != SK_PROM_MODE_NONE) {
-               (void) SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode);
-       }
-#else /* SK_SLIM */
-
-       /* Set all bits in 64-bit hash register. */
-       GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash);
-
-       /* Enable Hashing */
-       SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
-       
-       (void) SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode);
-       
-#endif /* SK_SLIM */
-       
-       /* Set port's current physical MAC address. */
-       OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0];
-       GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_1L, OutAddr);
-       
-       /* Set port's current logical MAC address. */
-       OutAddr = (SK_U16 *) &pAPort->Exact[0].a[0];
-       GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_2L, OutAddr);
-       
-#ifdef DEBUG
-       SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
-               ("SkAddrGmacMcUpdate: Permanent Physical MAC Address: %02X %02X %02X %02X %02X %02X\n",
-                       pAPort->Exact[0].a[0],
-                       pAPort->Exact[0].a[1],
-                       pAPort->Exact[0].a[2],
-                       pAPort->Exact[0].a[3],
-                       pAPort->Exact[0].a[4],
-                       pAPort->Exact[0].a[5]))
-       
-       SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
-               ("SkAddrGmacMcUpdate: Physical MAC Address: %02X %02X %02X %02X %02X %02X\n",
-                       pAPort->CurrentMacAddress.a[0],
-                       pAPort->CurrentMacAddress.a[1],
-                       pAPort->CurrentMacAddress.a[2],
-                       pAPort->CurrentMacAddress.a[3],
-                       pAPort->CurrentMacAddress.a[4],
-                       pAPort->CurrentMacAddress.a[5]))
-#endif /* DEBUG */
-       
-#ifndef SK_SLIM
-       /* Determine return value. */
-       if (Inexact == 0 && pAPort->PromMode == 0) {
-               return (SK_MC_FILTERING_EXACT);
-       }
-       else {
-               return (SK_MC_FILTERING_INEXACT);
-       }
-#else /* SK_SLIM */
-       return (SK_MC_FILTERING_INEXACT);
-#endif /* SK_SLIM */
-       
-}      /* SkAddrGmacMcUpdate */
-
-#endif /* YUKON */
-
-#ifndef SK_NO_MAO
-
-/******************************************************************************
- *
- *     SkAddrOverride - override a port's MAC address
- *
- * Description:
- *     This routine overrides the MAC address of one port.
- *
- * Context:
- *     runtime, pageable
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     SK_ADDR_SUCCESS if successful.
- *     SK_ADDR_DUPLICATE_ADDRESS if duplicate MAC address.
- *     SK_ADDR_MULTICAST_ADDRESS if multicast or broadcast address.
- *     SK_ADDR_TOO_EARLY if SK_INIT_IO was not executed before.
- */
-int    SkAddrOverride(
-SK_AC          *pAC,                           /* adapter context */
-SK_IOC         IoC,                            /* I/O context */
-SK_U32         PortNumber,                     /* Port Number */
-SK_MAC_ADDR    SK_FAR *pNewAddr,       /* new MAC address */
-int                    Flags)                          /* logical/physical MAC address */
-{
-#ifndef SK_NO_RLMT
-       SK_EVPARA       Para;
-#endif /* !SK_NO_RLMT */
-       SK_U32          NetNumber;
-       SK_U32          i;
-       SK_U16          SK_FAR *OutAddr;
-
-#ifndef SK_NO_RLMT
-       NetNumber = pAC->Rlmt.Port[PortNumber].Net->NetNumber;
-#else
-       NetNumber = 0;
-#endif /* SK_NO_RLMT */
-#if (!defined(SK_SLIM) || defined(DEBUG))
-       if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
-               return (SK_ADDR_ILLEGAL_PORT);
-       }
-#endif /* !SK_SLIM || DEBUG */
-       if (pNewAddr != NULL && (pNewAddr->a[0] & SK_MC_BIT) != 0) {
-               return (SK_ADDR_MULTICAST_ADDRESS);
-       }
-
-       if (!pAC->Addr.Net[NetNumber].CurrentMacAddressSet) {
-               return (SK_ADDR_TOO_EARLY);
-       }
-
-       if (Flags & SK_ADDR_SET_LOGICAL) {      /* Activate logical MAC address. */
-               /* Parameter *pNewAddr is ignored. */
-               for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
-                       if (!pAC->Addr.Port[i].CurrentMacAddressSet) {
-                               return (SK_ADDR_TOO_EARLY);
-                       }
-               }
-#ifndef SK_NO_RLMT
-               /* Set PortNumber to number of net's active port. */
-               PortNumber = pAC->Rlmt.Net[NetNumber].
-                       Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber;
-#endif /* !SK_NO_RLMT */
-               pAC->Addr.Port[PortNumber].Exact[0] =
-                       pAC->Addr.Net[NetNumber].CurrentMacAddress;
-
-               /* Write address to first exact match entry of active port. */
-               (void) SkAddrMcUpdate(pAC, IoC, PortNumber);
-       }
-       else if (Flags & SK_ADDR_CLEAR_LOGICAL) {
-               /* Deactivate logical MAC address. */
-               /* Parameter *pNewAddr is ignored. */
-               for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
-                       if (!pAC->Addr.Port[i].CurrentMacAddressSet) {
-                               return (SK_ADDR_TOO_EARLY);
-                       }
-               }
-#ifndef SK_NO_RLMT
-               /* Set PortNumber to number of net's active port. */
-               PortNumber = pAC->Rlmt.Net[NetNumber].
-                       Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber;
-#endif /* !SK_NO_RLMT */
-               for (i = 0; i < SK_MAC_ADDR_LEN; i++ ) {
-                       pAC->Addr.Port[PortNumber].Exact[0].a[i] = 0;
-               }
-
-               /* Write address to first exact match entry of active port. */
-               (void) SkAddrMcUpdate(pAC, IoC, PortNumber);
-       }
-       else if (Flags & SK_ADDR_PHYSICAL_ADDRESS) {    /* Physical MAC address. */
-               if (SK_ADDR_EQUAL(pNewAddr->a,
-                       pAC->Addr.Net[NetNumber].CurrentMacAddress.a)) {
-                       return (SK_ADDR_DUPLICATE_ADDRESS);
-               }
-
-               for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
-                       if (!pAC->Addr.Port[i].CurrentMacAddressSet) {
-                               return (SK_ADDR_TOO_EARLY);
-                       }
-
-                       if (SK_ADDR_EQUAL(pNewAddr->a,
-                               pAC->Addr.Port[i].CurrentMacAddress.a)) {
-                               if (i == PortNumber) {
-                                       return (SK_ADDR_SUCCESS);
-                               }
-                               else {
-                                       return (SK_ADDR_DUPLICATE_ADDRESS);
-                               }
-                       }
-               }
-
-               pAC->Addr.Port[PortNumber].PreviousMacAddress =
-                       pAC->Addr.Port[PortNumber].CurrentMacAddress;
-               pAC->Addr.Port[PortNumber].CurrentMacAddress = *pNewAddr;
-
-               /* Change port's physical MAC address. */
-               OutAddr = (SK_U16 SK_FAR *) pNewAddr;
-#ifdef GENESIS
-               if (pAC->GIni.GIGenesis) {
-                       XM_OUTADDR(IoC, PortNumber, XM_SA, OutAddr);
-               }
-#endif /* GENESIS */
-#ifdef YUKON
-               if (!pAC->GIni.GIGenesis) {
-                       GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_1L, OutAddr);
-               }
-#endif /* YUKON */
-
-#ifndef SK_NO_RLMT
-               /* Report address change to RLMT. */
-               Para.Para32[0] = PortNumber;
-               Para.Para32[0] = -1;
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_PORT_ADDR, Para);
-#endif /* !SK_NO_RLMT */
-       }
-       else {  /* Logical MAC address. */
-               if (SK_ADDR_EQUAL(pNewAddr->a,
-                       pAC->Addr.Net[NetNumber].CurrentMacAddress.a)) {
-                       return (SK_ADDR_SUCCESS);
-               }
-               
-               for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
-                       if (!pAC->Addr.Port[i].CurrentMacAddressSet) {
-                               return (SK_ADDR_TOO_EARLY);
-                       }
-
-                       if (SK_ADDR_EQUAL(pNewAddr->a,
-                               pAC->Addr.Port[i].CurrentMacAddress.a)) {
-                               return (SK_ADDR_DUPLICATE_ADDRESS);
-                       }
-               }
-               
-               /*
-                * In case that the physical and the logical MAC addresses are equal
-                * we must also change the physical MAC address here.
-                * In this case we have an adapter which initially was programmed with
-                * two identical MAC addresses.
-                */
-               if (SK_ADDR_EQUAL(pAC->Addr.Port[PortNumber].CurrentMacAddress.a,
-                               pAC->Addr.Port[PortNumber].Exact[0].a)) {
-                       
-                       pAC->Addr.Port[PortNumber].PreviousMacAddress =
-                               pAC->Addr.Port[PortNumber].CurrentMacAddress;
-                       pAC->Addr.Port[PortNumber].CurrentMacAddress = *pNewAddr;
-                       
-#ifndef SK_NO_RLMT
-                       /* Report address change to RLMT. */
-                       Para.Para32[0] = PortNumber;
-                       Para.Para32[0] = -1;
-                       SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_PORT_ADDR, Para);
-#endif /* !SK_NO_RLMT */
-               }
-               
-#ifndef SK_NO_RLMT
-               /* Set PortNumber to number of net's active port. */
-               PortNumber = pAC->Rlmt.Net[NetNumber].
-                       Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber;
-#endif /* !SK_NO_RLMT */
-               pAC->Addr.Net[NetNumber].CurrentMacAddress = *pNewAddr;
-               pAC->Addr.Port[PortNumber].Exact[0] = *pNewAddr;
-#ifdef DEBUG
-               SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
-                       ("SkAddrOverride: Permanent MAC Address: %02X %02X %02X %02X %02X %02X\n",
-                               pAC->Addr.Net[NetNumber].PermanentMacAddress.a[0],
-                               pAC->Addr.Net[NetNumber].PermanentMacAddress.a[1],
-                               pAC->Addr.Net[NetNumber].PermanentMacAddress.a[2],
-                               pAC->Addr.Net[NetNumber].PermanentMacAddress.a[3],
-                               pAC->Addr.Net[NetNumber].PermanentMacAddress.a[4],
-                               pAC->Addr.Net[NetNumber].PermanentMacAddress.a[5]))
-               
-               SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
-                       ("SkAddrOverride: New logical MAC Address: %02X %02X %02X %02X %02X %02X\n",
-                               pAC->Addr.Net[NetNumber].CurrentMacAddress.a[0],
-                               pAC->Addr.Net[NetNumber].CurrentMacAddress.a[1],
-                               pAC->Addr.Net[NetNumber].CurrentMacAddress.a[2],
-                               pAC->Addr.Net[NetNumber].CurrentMacAddress.a[3],
-                               pAC->Addr.Net[NetNumber].CurrentMacAddress.a[4],
-                               pAC->Addr.Net[NetNumber].CurrentMacAddress.a[5]))
-#endif /* DEBUG */
-
-        /* Write address to first exact match entry of active port. */
-               (void) SkAddrMcUpdate(pAC, IoC, PortNumber);
-       }
-
-       return (SK_ADDR_SUCCESS);
-       
-}      /* SkAddrOverride */
-
-
-#endif /* SK_NO_MAO */
-
-/******************************************************************************
- *
- *     SkAddrPromiscuousChange - set promiscuous mode for given port
- *
- * Description:
- *     This routine manages promiscuous mode:
- *     - none
- *     - all LLC frames
- *     - all MC frames
- *
- *     It calls either SkAddrXmacPromiscuousChange or
- *     SkAddrGmacPromiscuousChange, according to the adapter in use.
- *     The real work is done there.
- *
- * Context:
- *     runtime, pageable
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     SK_ADDR_SUCCESS
- *     SK_ADDR_ILLEGAL_PORT
- */
-int    SkAddrPromiscuousChange(
-SK_AC  *pAC,                   /* adapter context */
-SK_IOC IoC,                    /* I/O context */
-SK_U32 PortNumber,             /* port whose promiscuous mode changes */
-int            NewPromMode)    /* new promiscuous mode */
-{
-       int ReturnCode = 0;
-#if (!defined(SK_SLIM) || defined(DEBUG))
-       if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
-               return (SK_ADDR_ILLEGAL_PORT);
-       }
-#endif /* !SK_SLIM || DEBUG */
-
-#ifdef GENESIS
-       if (pAC->GIni.GIGenesis) {
-               ReturnCode =
-                       SkAddrXmacPromiscuousChange(pAC, IoC, PortNumber, NewPromMode);
-       }
-#endif /* GENESIS */
-#ifdef YUKON
-       if (!pAC->GIni.GIGenesis) {
-               ReturnCode =
-                       SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, NewPromMode);
-       }
-#endif /* YUKON */
-
-       return (ReturnCode);
-
-}      /* SkAddrPromiscuousChange */
-
-#ifdef GENESIS
-
-/******************************************************************************
- *
- *     SkAddrXmacPromiscuousChange - set promiscuous mode for given port
- *
- * Description:
- *     This routine manages promiscuous mode:
- *     - none
- *     - all LLC frames
- *     - all MC frames
- *
- * Context:
- *     runtime, pageable
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     SK_ADDR_SUCCESS
- *     SK_ADDR_ILLEGAL_PORT
- */
-static int     SkAddrXmacPromiscuousChange(
-SK_AC  *pAC,                   /* adapter context */
-SK_IOC IoC,                    /* I/O context */
-SK_U32 PortNumber,             /* port whose promiscuous mode changes */
-int            NewPromMode)    /* new promiscuous mode */
-{
-       int                     i;
-       SK_BOOL         InexactModeBit;
-       SK_U8           Inexact;
-       SK_U8           HwInexact;
-       SK_FILTER64     HwInexactFilter;
-       SK_U16          LoMode;         /* Lower 16 bits of XMAC Mode Register. */
-       int                     CurPromMode = SK_PROM_MODE_NONE;
-
-       /* Read CurPromMode from Hardware. */
-       XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);
-
-       if ((LoMode & XM_MD_ENA_PROM) != 0) {
-               /* Promiscuous mode! */
-               CurPromMode |= SK_PROM_MODE_LLC;
-       }
-       
-       for (Inexact = 0xFF, i = 0; i < 8; i++) {
-               Inexact &= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i];
-       }
-       if (Inexact == 0xFF) {
-               CurPromMode |= (pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_ALL_MC);
-       }
-       else {
-               /* Get InexactModeBit (bit XM_MD_ENA_HASH in mode register) */
-               XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);
-               
-               InexactModeBit = (LoMode & XM_MD_ENA_HASH) != 0;
-
-               /* Read 64-bit hash register from XMAC */
-               XM_INHASH(IoC, PortNumber, XM_HSM, &HwInexactFilter.Bytes[0]);
-
-               for (HwInexact = 0xFF, i = 0; i < 8; i++) {
-                       HwInexact &= HwInexactFilter.Bytes[i];
-               }
-
-               if (InexactModeBit && (HwInexact == 0xFF)) {
-                       CurPromMode |= SK_PROM_MODE_ALL_MC;
-               }
-       }
-
-       pAC->Addr.Port[PortNumber].PromMode = NewPromMode;
-
-       if (NewPromMode == CurPromMode) {
-               return (SK_ADDR_SUCCESS);
-       }
-
-       if ((NewPromMode & SK_PROM_MODE_ALL_MC) &&
-               !(CurPromMode & SK_PROM_MODE_ALL_MC)) { /* All MC. */
-               
-               /* Set all bits in 64-bit hash register. */
-               XM_OUTHASH(IoC, PortNumber, XM_HSM, &OnesHash);
-
-               /* Enable Hashing */
-               SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
-       }
-       else if ((CurPromMode & SK_PROM_MODE_ALL_MC) &&
-               !(NewPromMode & SK_PROM_MODE_ALL_MC)) { /* Norm MC. */
-               for (Inexact = 0, i = 0; i < 8; i++) {
-                       Inexact |= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i];
-               }
-               if (Inexact == 0) {
-                       /* Disable Hashing */
-                       SkMacHashing(pAC, IoC, (int) PortNumber, SK_FALSE);
-               }
-               else {
-                       /* Set 64-bit hash register to InexactFilter. */
-                       XM_OUTHASH(IoC, PortNumber, XM_HSM,
-                               &pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0]);
-
-                       /* Enable Hashing */
-                       SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
-               }
-       }
-
-       if ((NewPromMode & SK_PROM_MODE_LLC) &&
-               !(CurPromMode & SK_PROM_MODE_LLC)) {    /* Prom. LLC */
-               /* Set the MAC in Promiscuous Mode */
-               SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_TRUE);
-       }
-       else if ((CurPromMode & SK_PROM_MODE_LLC) &&
-               !(NewPromMode & SK_PROM_MODE_LLC)) {    /* Norm. LLC. */
-               /* Clear Promiscuous Mode */
-               SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_FALSE);
-       }
-       
-       return (SK_ADDR_SUCCESS);
-       
-}      /* SkAddrXmacPromiscuousChange */
-
-#endif /* GENESIS */
-
-#ifdef YUKON
-
-/******************************************************************************
- *
- *     SkAddrGmacPromiscuousChange - set promiscuous mode for given port
- *
- * Description:
- *     This routine manages promiscuous mode:
- *     - none
- *     - all LLC frames
- *     - all MC frames
- *
- * Context:
- *     runtime, pageable
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     SK_ADDR_SUCCESS
- *     SK_ADDR_ILLEGAL_PORT
- */
-static int     SkAddrGmacPromiscuousChange(
-SK_AC  *pAC,                   /* adapter context */
-SK_IOC IoC,                    /* I/O context */
-SK_U32 PortNumber,             /* port whose promiscuous mode changes */
-int            NewPromMode)    /* new promiscuous mode */
-{
-       SK_U16          ReceiveControl; /* GMAC Receive Control Register */
-       int             CurPromMode = SK_PROM_MODE_NONE;
-
-       /* Read CurPromMode from Hardware. */
-       GM_IN16(IoC, PortNumber, GM_RX_CTRL, &ReceiveControl);
-
-       if ((ReceiveControl & (GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA)) == 0) {
-               /* Promiscuous mode! */
-               CurPromMode |= SK_PROM_MODE_LLC;
-       }
-
-       if ((ReceiveControl & GM_RXCR_MCF_ENA) == 0) {
-               /* All Multicast mode! */
-               CurPromMode |= (pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_ALL_MC);
-       }
-
-       pAC->Addr.Port[PortNumber].PromMode = NewPromMode;
-
-       if (NewPromMode == CurPromMode) {
-               return (SK_ADDR_SUCCESS);
-       }
-       
-       if ((NewPromMode & SK_PROM_MODE_ALL_MC) &&
-               !(CurPromMode & SK_PROM_MODE_ALL_MC)) { /* All MC */
-               
-               /* Set all bits in 64-bit hash register. */
-               GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash);
-               
-               /* Enable Hashing */
-               SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
-       }
-       
-       if ((CurPromMode & SK_PROM_MODE_ALL_MC) &&
-               !(NewPromMode & SK_PROM_MODE_ALL_MC)) { /* Norm. MC */
-
-               /* Set 64-bit hash register to InexactFilter. */
-               GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1,
-                       &pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0]);
-
-               /* Enable Hashing. */
-               SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
-       }
-
-       if ((NewPromMode & SK_PROM_MODE_LLC) &&
-               !(CurPromMode & SK_PROM_MODE_LLC)) {    /* Prom. LLC */
-               
-               /* Set the MAC to Promiscuous Mode. */
-               SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_TRUE);
-       }
-       else if ((CurPromMode & SK_PROM_MODE_LLC) &&
-               !(NewPromMode & SK_PROM_MODE_LLC)) {    /* Norm. LLC */
-               
-               /* Clear Promiscuous Mode. */
-               SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_FALSE);
-       }
-
-       return (SK_ADDR_SUCCESS);
-       
-}      /* SkAddrGmacPromiscuousChange */
-
-#endif /* YUKON */
-
-#ifndef SK_SLIM
-
-/******************************************************************************
- *
- *     SkAddrSwap - swap address info
- *
- * Description:
- *     This routine swaps address info of two ports.
- *
- * Context:
- *     runtime, pageable
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     SK_ADDR_SUCCESS
- *     SK_ADDR_ILLEGAL_PORT
- */
-int    SkAddrSwap(
-SK_AC  *pAC,                   /* adapter context */
-SK_IOC IoC,                    /* I/O context */
-SK_U32 FromPortNumber,         /* Port1 Index */
-SK_U32 ToPortNumber)           /* Port2 Index */
-{
-       int                     i;
-       SK_U8           Byte;
-       SK_MAC_ADDR     MacAddr;
-       SK_U32          DWord;
-
-       if (FromPortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
-               return (SK_ADDR_ILLEGAL_PORT);
-       }
-
-       if (ToPortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
-               return (SK_ADDR_ILLEGAL_PORT);
-       }
-
-       if (pAC->Rlmt.Port[FromPortNumber].Net != pAC->Rlmt.Port[ToPortNumber].Net) {
-               return (SK_ADDR_ILLEGAL_PORT);
-       }
-
-       /*
-        * Swap:
-        * - Exact Match Entries (GEnesis and Yukon)
-        *   Yukon uses first entry for the logical MAC
-        *   address (stored in the second GMAC register).
-        * - FirstExactMatchRlmt (GEnesis only)
-        * - NextExactMatchRlmt (GEnesis only)
-        * - FirstExactMatchDrv (GEnesis only)
-        * - NextExactMatchDrv (GEnesis only)
-        * - 64-bit filter (InexactFilter)
-        * - Promiscuous Mode
-        * of ports.
-        */
-
-       for (i = 0; i < SK_ADDR_EXACT_MATCHES; i++) {
-               MacAddr = pAC->Addr.Port[FromPortNumber].Exact[i];
-               pAC->Addr.Port[FromPortNumber].Exact[i] =
-                       pAC->Addr.Port[ToPortNumber].Exact[i];
-               pAC->Addr.Port[ToPortNumber].Exact[i] = MacAddr;
-       }
-
-       for (i = 0; i < 8; i++) {
-               Byte = pAC->Addr.Port[FromPortNumber].InexactFilter.Bytes[i];
-               pAC->Addr.Port[FromPortNumber].InexactFilter.Bytes[i] =
-                       pAC->Addr.Port[ToPortNumber].InexactFilter.Bytes[i];
-               pAC->Addr.Port[ToPortNumber].InexactFilter.Bytes[i] = Byte;
-       }
-       
-       i = pAC->Addr.Port[FromPortNumber].PromMode;
-       pAC->Addr.Port[FromPortNumber].PromMode = pAC->Addr.Port[ToPortNumber].PromMode;
-       pAC->Addr.Port[ToPortNumber].PromMode = i;
-       
-       if (pAC->GIni.GIGenesis) {
-               DWord = pAC->Addr.Port[FromPortNumber].FirstExactMatchRlmt;
-               pAC->Addr.Port[FromPortNumber].FirstExactMatchRlmt =
-                       pAC->Addr.Port[ToPortNumber].FirstExactMatchRlmt;
-               pAC->Addr.Port[ToPortNumber].FirstExactMatchRlmt = DWord;
-               
-               DWord = pAC->Addr.Port[FromPortNumber].NextExactMatchRlmt;
-               pAC->Addr.Port[FromPortNumber].NextExactMatchRlmt =
-                       pAC->Addr.Port[ToPortNumber].NextExactMatchRlmt;
-               pAC->Addr.Port[ToPortNumber].NextExactMatchRlmt = DWord;
-               
-               DWord = pAC->Addr.Port[FromPortNumber].FirstExactMatchDrv;
-               pAC->Addr.Port[FromPortNumber].FirstExactMatchDrv =
-                       pAC->Addr.Port[ToPortNumber].FirstExactMatchDrv;
-               pAC->Addr.Port[ToPortNumber].FirstExactMatchDrv = DWord;
-               
-               DWord = pAC->Addr.Port[FromPortNumber].NextExactMatchDrv;
-               pAC->Addr.Port[FromPortNumber].NextExactMatchDrv =
-                       pAC->Addr.Port[ToPortNumber].NextExactMatchDrv;
-               pAC->Addr.Port[ToPortNumber].NextExactMatchDrv = DWord;
-       }
-       
-       /* CAUTION: Solution works if only ports of one adapter are in use. */
-       for (i = 0; (SK_U32) i < pAC->Rlmt.Net[pAC->Rlmt.Port[ToPortNumber].
-               Net->NetNumber].NumPorts; i++) {
-               if (pAC->Rlmt.Net[pAC->Rlmt.Port[ToPortNumber].Net->NetNumber].
-                       Port[i]->PortNumber == ToPortNumber) {
-                       pAC->Addr.Net[pAC->Rlmt.Port[ToPortNumber].Net->NetNumber].
-                               ActivePort = i;
-                       /* 20001207 RA: Was "ToPortNumber;". */
-               }
-       }
-       
-       (void) SkAddrMcUpdate(pAC, IoC, FromPortNumber);
-       (void) SkAddrMcUpdate(pAC, IoC, ToPortNumber);
-
-       return (SK_ADDR_SUCCESS);
-       
-}      /* SkAddrSwap */
-
-#endif /* !SK_SLIM */
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
diff --git a/drivers/net/sk98lin/skdim.c b/drivers/net/sk98lin/skdim.c
deleted file mode 100644 (file)
index 37ce03f..0000000
+++ /dev/null
@@ -1,742 +0,0 @@
-/******************************************************************************
- *
- * Name:       skdim.c
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.5 $
- * Date:       $Date: 2003/11/28 12:55:40 $
- * Purpose:    All functions to maintain interrupt moderation
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect GmbH.
- *     (C)Copyright 2002-2003 Marvell.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * Description:
- *
- * This module is intended to manage the dynamic interrupt moderation on both   
- * GEnesis and Yukon adapters.
- *
- * Include File Hierarchy:
- *
- *     "skdrv1st.h"
- *     "skdrv2nd.h"
- *
- ******************************************************************************/
-
-#ifndef        lint
-static const char SysKonnectFileId[] =
-       "@(#) $Id: skdim.c,v 1.5 2003/11/28 12:55:40 rroesler Exp $ (C) SysKonnect.";
-#endif
-
-#define __SKADDR_C
-
-#ifdef __cplusplus
-#error C++ is not yet supported.
-extern "C" {
-#endif
-
-/*******************************************************************************
-**
-** Includes
-**
-*******************************************************************************/
-
-#ifndef __INC_SKDRV1ST_H
-#include "h/skdrv1st.h"
-#endif
-
-#ifndef __INC_SKDRV2ND_H
-#include "h/skdrv2nd.h"
-#endif
-
-#include       <linux/kernel_stat.h>
-
-/*******************************************************************************
-**
-** Defines
-**
-*******************************************************************************/
-
-/*******************************************************************************
-**
-** Typedefs
-**
-*******************************************************************************/
-
-/*******************************************************************************
-**
-** Local function prototypes 
-**
-*******************************************************************************/
-
-static unsigned int GetCurrentSystemLoad(SK_AC *pAC);
-static SK_U64       GetIsrCalls(SK_AC *pAC);
-static SK_BOOL      IsIntModEnabled(SK_AC *pAC);
-static void         SetCurrIntCtr(SK_AC *pAC);
-static void         EnableIntMod(SK_AC *pAC); 
-static void         DisableIntMod(SK_AC *pAC);
-static void         ResizeDimTimerDuration(SK_AC *pAC);
-static void         DisplaySelectedModerationType(SK_AC *pAC);
-static void         DisplaySelectedModerationMask(SK_AC *pAC);
-static void         DisplayDescrRatio(SK_AC *pAC);
-
-/*******************************************************************************
-**
-** Global variables
-**
-*******************************************************************************/
-
-/*******************************************************************************
-**
-** Local variables
-**
-*******************************************************************************/
-
-/*******************************************************************************
-**
-** Global functions 
-**
-*******************************************************************************/
-
-/*******************************************************************************
-** Function     : SkDimModerate
-** Description  : Called in every ISR to check if moderation is to be applied
-**                or not for the current number of interrupts
-** Programmer   : Ralph Roesler
-** Last Modified: 22-mar-03
-** Returns      : void (!)
-** Notes        : -
-*******************************************************************************/
-
-void 
-SkDimModerate(SK_AC *pAC) {
-    unsigned int CurrSysLoad    = 0;  /* expressed in percent */
-    unsigned int LoadIncrease   = 0;  /* expressed in percent */
-    SK_U64       ThresholdInts  = 0;
-    SK_U64       IsrCallsPerSec = 0;
-
-#define M_DIMINFO pAC->DynIrqModInfo
-
-    if (!IsIntModEnabled(pAC)) {
-        if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
-            CurrSysLoad = GetCurrentSystemLoad(pAC);
-            if (CurrSysLoad > 75) {
-                    /* 
-                    ** More than 75% total system load! Enable the moderation 
-                    ** to shield the system against too many interrupts.
-                    */
-                    EnableIntMod(pAC);
-            } else if (CurrSysLoad > M_DIMINFO.PrevSysLoad) {
-                LoadIncrease = (CurrSysLoad - M_DIMINFO.PrevSysLoad);
-                if (LoadIncrease > ((M_DIMINFO.PrevSysLoad *
-                                         C_INT_MOD_ENABLE_PERCENTAGE) / 100)) {
-                    if (CurrSysLoad > 10) {
-                        /* 
-                        ** More than 50% increase with respect to the 
-                        ** previous load of the system. Most likely this 
-                        ** is due to our ISR-proc...
-                        */
-                        EnableIntMod(pAC);
-                    }
-                }
-            } else {
-                /*
-                ** Neither too much system load at all nor too much increase
-                ** with respect to the previous system load. Hence, we can leave
-                ** the ISR-handling like it is without enabling moderation.
-                */
-            }
-            M_DIMINFO.PrevSysLoad = CurrSysLoad;
-        }   
-    } else {
-        if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
-            ThresholdInts  = ((M_DIMINFO.MaxModIntsPerSec *
-                                   C_INT_MOD_DISABLE_PERCENTAGE) / 100);
-            IsrCallsPerSec = GetIsrCalls(pAC);
-            if (IsrCallsPerSec <= ThresholdInts) {
-                /* 
-                ** The number of interrupts within the last second is 
-                ** lower than the disable_percentage of the desried 
-                ** maxrate. Therefore we can disable the moderation.
-                */
-                DisableIntMod(pAC);
-                M_DIMINFO.MaxModIntsPerSec = 
-                   (M_DIMINFO.MaxModIntsPerSecUpperLimit +
-                    M_DIMINFO.MaxModIntsPerSecLowerLimit) / 2;
-            } else {
-                /*
-                ** The number of interrupts per sec is the same as expected.
-                ** Evalulate the descriptor-ratio. If it has changed, a resize 
-                ** in the moderation timer might be useful
-                */
-                if (M_DIMINFO.AutoSizing) {
-                    ResizeDimTimerDuration(pAC);
-                }
-            }
-        }
-    }
-
-    /*
-    ** Some information to the log...
-    */
-    if (M_DIMINFO.DisplayStats) {
-        DisplaySelectedModerationType(pAC);
-        DisplaySelectedModerationMask(pAC);
-        DisplayDescrRatio(pAC);
-    }
-
-    M_DIMINFO.NbrProcessedDescr = 0; 
-    SetCurrIntCtr(pAC);
-}
-
-/*******************************************************************************
-** Function     : SkDimStartModerationTimer
-** Description  : Starts the audit-timer for the dynamic interrupt moderation
-** Programmer   : Ralph Roesler
-** Last Modified: 22-mar-03
-** Returns      : void (!)
-** Notes        : -
-*******************************************************************************/
-
-void 
-SkDimStartModerationTimer(SK_AC *pAC) {
-    SK_EVPARA    EventParam;   /* Event struct for timer event */
-    SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
-    EventParam.Para32[0] = SK_DRV_MODERATION_TIMER;
-    SkTimerStart(pAC, pAC->IoBase, &pAC->DynIrqModInfo.ModTimer,
-                 SK_DRV_MODERATION_TIMER_LENGTH,
-                 SKGE_DRV, SK_DRV_TIMER, EventParam);
-}
-
-/*******************************************************************************
-** Function     : SkDimEnableModerationIfNeeded
-** Description  : Either enables or disables moderation
-** Programmer   : Ralph Roesler
-** Last Modified: 22-mar-03
-** Returns      : void (!)
-** Notes        : This function is called when a particular adapter is opened
-**                There is no Disable function, because when all interrupts 
-**                might be disable, the moderation timer has no meaning at all
-******************************************************************************/
-
-void
-SkDimEnableModerationIfNeeded(SK_AC *pAC) {
-
-    if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_STATIC) {
-        EnableIntMod(pAC);   /* notification print in this function */
-    } else if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
-        SkDimStartModerationTimer(pAC);
-        if (M_DIMINFO.DisplayStats) {
-            printk("Dynamic moderation has been enabled\n");
-        }
-    } else {
-        if (M_DIMINFO.DisplayStats) {
-            printk("No moderation has been enabled\n");
-        }
-    }
-}
-
-/*******************************************************************************
-** Function     : SkDimDisplayModerationSettings
-** Description  : Displays the current settings regarding interrupt moderation
-** Programmer   : Ralph Roesler
-** Last Modified: 22-mar-03
-** Returns      : void (!)
-** Notes        : -
-*******************************************************************************/
-
-void 
-SkDimDisplayModerationSettings(SK_AC *pAC) {
-    DisplaySelectedModerationType(pAC);
-    DisplaySelectedModerationMask(pAC);
-}
-
-/*******************************************************************************
-**
-** Local functions 
-**
-*******************************************************************************/
-
-/*******************************************************************************
-** Function     : GetCurrentSystemLoad
-** Description  : Retrieves the current system load of the system. This load
-**                is evaluated for all processors within the system.
-** Programmer   : Ralph Roesler
-** Last Modified: 22-mar-03
-** Returns      : unsigned int: load expressed in percentage
-** Notes        : The possible range being returned is from 0 up to 100.
-**                Whereas 0 means 'no load at all' and 100 'system fully loaded'
-**                It is impossible to determine what actually causes the system
-**                to be in 100%, but maybe that is due to too much interrupts.
-*******************************************************************************/
-
-static unsigned int
-GetCurrentSystemLoad(SK_AC *pAC) {
-       unsigned long jif         = jiffies;
-       unsigned int  UserTime    = 0;
-       unsigned int  SystemTime  = 0;
-       unsigned int  NiceTime    = 0;
-       unsigned int  IdleTime    = 0;
-       unsigned int  TotalTime   = 0;
-       unsigned int  UsedTime    = 0;
-       unsigned int  SystemLoad  = 0;
-
-       /* unsigned int  NbrCpu      = 0; */
-
-       /*
-       ** The following lines have been commented out, because
-       ** from kernel 2.5.44 onwards, the kernel-owned structure
-       **
-       **      struct kernel_stat kstat
-       **
-       ** is not marked as an exported symbol in the file
-       **
-       **      kernel/ksyms.c 
-       **
-       ** As a consequence, using this driver as KLM is not possible
-       ** and any access of the structure kernel_stat via the 
-       ** dedicated macros kstat_cpu(i).cpustat.xxx is to be avoided.
-       **
-       ** The kstat-information might be added again in future 
-       ** versions of the 2.5.xx kernel, but for the time being, 
-       ** number of interrupts will serve as indication how much 
-       ** load we currently have... 
-       **
-       ** for (NbrCpu = 0; NbrCpu < num_online_cpus(); NbrCpu++) {
-       **      UserTime   = UserTime   + kstat_cpu(NbrCpu).cpustat.user;
-       **      NiceTime   = NiceTime   + kstat_cpu(NbrCpu).cpustat.nice;
-       **      SystemTime = SystemTime + kstat_cpu(NbrCpu).cpustat.system;
-       ** }
-       */
-       SK_U64 ThresholdInts  = 0;
-       SK_U64 IsrCallsPerSec = 0;
-
-       ThresholdInts  = ((M_DIMINFO.MaxModIntsPerSec *
-                          C_INT_MOD_ENABLE_PERCENTAGE) + 100);
-       IsrCallsPerSec = GetIsrCalls(pAC);
-       if (IsrCallsPerSec >= ThresholdInts) {
-           /*
-           ** We do not know how much the real CPU-load is!
-           ** Return 80% as a default in order to activate DIM
-           */
-           SystemLoad = 80;
-           return (SystemLoad);  
-       } 
-
-       UsedTime  = UserTime + NiceTime + SystemTime;
-
-       IdleTime  = jif * num_online_cpus() - UsedTime;
-       TotalTime = UsedTime + IdleTime;
-
-       SystemLoad = ( 100 * (UsedTime  - M_DIMINFO.PrevUsedTime) ) /
-                                               (TotalTime - M_DIMINFO.PrevTotalTime);
-
-       if (M_DIMINFO.DisplayStats) {
-               printk("Current system load is: %u\n", SystemLoad);
-       }
-
-       M_DIMINFO.PrevTotalTime = TotalTime;
-       M_DIMINFO.PrevUsedTime  = UsedTime;
-
-       return (SystemLoad);
-}
-
-/*******************************************************************************
-** Function     : GetIsrCalls
-** Description  : Depending on the selected moderation mask, this function will
-**                return the number of interrupts handled in the previous time-
-**                frame. This evaluated number is based on the current number 
-**                of interrupts stored in PNMI-context and the previous stored 
-**                interrupts.
-** Programmer   : Ralph Roesler
-** Last Modified: 23-mar-03
-** Returns      : int:   the number of interrupts being executed in the last
-**                       timeframe
-** Notes        : It makes only sense to call this function, when dynamic 
-**                interrupt moderation is applied
-*******************************************************************************/
-
-static SK_U64
-GetIsrCalls(SK_AC *pAC) {
-    SK_U64   RxPort0IntDiff = 0;
-    SK_U64   RxPort1IntDiff = 0;
-    SK_U64   TxPort0IntDiff = 0;
-    SK_U64   TxPort1IntDiff = 0;
-
-    if (pAC->DynIrqModInfo.MaskIrqModeration == IRQ_MASK_TX_ONLY) {
-        if (pAC->GIni.GIMacsFound == 2) {
-            TxPort1IntDiff = pAC->Pnmi.Port[1].TxIntrCts - 
-                             pAC->DynIrqModInfo.PrevPort1TxIntrCts;
-        }
-        TxPort0IntDiff = pAC->Pnmi.Port[0].TxIntrCts - 
-                         pAC->DynIrqModInfo.PrevPort0TxIntrCts;
-    } else if (pAC->DynIrqModInfo.MaskIrqModeration == IRQ_MASK_RX_ONLY) {
-        if (pAC->GIni.GIMacsFound == 2) {
-            RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts - 
-                             pAC->DynIrqModInfo.PrevPort1RxIntrCts;
-        }
-        RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts - 
-                         pAC->DynIrqModInfo.PrevPort0RxIntrCts;
-    } else {
-        if (pAC->GIni.GIMacsFound == 2) {
-            RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts - 
-                             pAC->DynIrqModInfo.PrevPort1RxIntrCts;
-            TxPort1IntDiff = pAC->Pnmi.Port[1].TxIntrCts - 
-                             pAC->DynIrqModInfo.PrevPort1TxIntrCts;
-        } 
-        RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts - 
-                         pAC->DynIrqModInfo.PrevPort0RxIntrCts;
-        TxPort0IntDiff = pAC->Pnmi.Port[0].TxIntrCts - 
-                         pAC->DynIrqModInfo.PrevPort0TxIntrCts;
-    }
-
-    return (RxPort0IntDiff + RxPort1IntDiff + TxPort0IntDiff + TxPort1IntDiff);
-}
-
-/*******************************************************************************
-** Function     : GetRxCalls
-** Description  : This function will return the number of times a receive inter-
-**                rupt was processed. This is needed to evaluate any resizing 
-**                factor.
-** Programmer   : Ralph Roesler
-** Last Modified: 23-mar-03
-** Returns      : SK_U64: the number of RX-ints being processed
-** Notes        : It makes only sense to call this function, when dynamic 
-**                interrupt moderation is applied
-*******************************************************************************/
-
-static SK_U64
-GetRxCalls(SK_AC *pAC) {
-    SK_U64   RxPort0IntDiff = 0;
-    SK_U64   RxPort1IntDiff = 0;
-
-    if (pAC->GIni.GIMacsFound == 2) {
-        RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts - 
-                         pAC->DynIrqModInfo.PrevPort1RxIntrCts;
-    }
-    RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts - 
-                     pAC->DynIrqModInfo.PrevPort0RxIntrCts;
-
-    return (RxPort0IntDiff + RxPort1IntDiff);
-}
-
-/*******************************************************************************
-** Function     : SetCurrIntCtr
-** Description  : Will store the current number orf occured interrupts in the 
-**                adapter context. This is needed to evaluated the number of 
-**                interrupts within a current timeframe.
-** Programmer   : Ralph Roesler
-** Last Modified: 23-mar-03
-** Returns      : void (!)
-** Notes        : -
-*******************************************************************************/
-
-static void
-SetCurrIntCtr(SK_AC *pAC) {
-    if (pAC->GIni.GIMacsFound == 2) {
-        pAC->DynIrqModInfo.PrevPort1RxIntrCts = pAC->Pnmi.Port[1].RxIntrCts;
-        pAC->DynIrqModInfo.PrevPort1TxIntrCts = pAC->Pnmi.Port[1].TxIntrCts;
-    } 
-    pAC->DynIrqModInfo.PrevPort0RxIntrCts = pAC->Pnmi.Port[0].RxIntrCts;
-    pAC->DynIrqModInfo.PrevPort0TxIntrCts = pAC->Pnmi.Port[0].TxIntrCts;
-}
-
-/*******************************************************************************
-** Function     : IsIntModEnabled()
-** Description  : Retrieves the current value of the interrupts moderation
-**                command register. Its content determines whether any 
-**                moderation is running or not.
-** Programmer   : Ralph Roesler
-** Last Modified: 23-mar-03
-** Returns      : SK_TRUE  : if mod timer running
-**                SK_FALSE : if no moderation is being performed
-** Notes        : -
-*******************************************************************************/
-
-static SK_BOOL
-IsIntModEnabled(SK_AC *pAC) {
-    unsigned long CtrCmd;
-
-    SK_IN32(pAC->IoBase, B2_IRQM_CTRL, &CtrCmd);
-    if ((CtrCmd & TIM_START) == TIM_START) {
-       return SK_TRUE;
-    } else {
-       return SK_FALSE;
-    }
-}
-
-/*******************************************************************************
-** Function     : EnableIntMod()
-** Description  : Enables the interrupt moderation using the values stored in
-**                in the pAC->DynIntMod data structure
-** Programmer   : Ralph Roesler
-** Last Modified: 22-mar-03
-** Returns      : -
-** Notes        : -
-*******************************************************************************/
-
-static void
-EnableIntMod(SK_AC *pAC) {
-    unsigned long ModBase;
-
-    if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
-       ModBase = C_CLK_FREQ_GENESIS / pAC->DynIrqModInfo.MaxModIntsPerSec;
-    } else {
-       ModBase = C_CLK_FREQ_YUKON / pAC->DynIrqModInfo.MaxModIntsPerSec;
-    }
-
-    SK_OUT32(pAC->IoBase, B2_IRQM_INI,  ModBase);
-    SK_OUT32(pAC->IoBase, B2_IRQM_MSK,  pAC->DynIrqModInfo.MaskIrqModeration);
-    SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_START);
-    if (M_DIMINFO.DisplayStats) {
-        printk("Enabled interrupt moderation (%i ints/sec)\n",
-               M_DIMINFO.MaxModIntsPerSec);
-    }
-}
-
-/*******************************************************************************
-** Function     : DisableIntMod()
-** Description  : Disables the interrupt moderation independent of what inter-
-**                rupts are running or not
-** Programmer   : Ralph Roesler
-** Last Modified: 23-mar-03
-** Returns      : -
-** Notes        : -
-*******************************************************************************/
-
-static void 
-DisableIntMod(SK_AC *pAC) {
-
-    SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_STOP);
-    if (M_DIMINFO.DisplayStats) {
-        printk("Disabled interrupt moderation\n");
-    }
-} 
-
-/*******************************************************************************
-** Function     : ResizeDimTimerDuration();
-** Description  : Checks the current used descriptor ratio and resizes the 
-**                duration timer (longer/smaller) if possible. 
-** Programmer   : Ralph Roesler
-** Last Modified: 23-mar-03
-** Returns      : -
-** Notes        : There are both maximum and minimum timer duration value. 
-**                This function assumes that interrupt moderation is already
-**                enabled!
-*******************************************************************************/
-
-static void 
-ResizeDimTimerDuration(SK_AC *pAC) {
-    SK_BOOL IncreaseTimerDuration;
-    int     TotalMaxNbrDescr;
-    int     UsedDescrRatio;
-    int     RatioDiffAbs;
-    int     RatioDiffRel;
-    int     NewMaxModIntsPerSec;
-    int     ModAdjValue;
-    long    ModBase;
-
-    /*
-    ** Check first if we are allowed to perform any modification
-    */
-    if (IsIntModEnabled(pAC)) { 
-        if (M_DIMINFO.IntModTypeSelect != C_INT_MOD_DYNAMIC) {
-            return; 
-        } else {
-            if (M_DIMINFO.ModJustEnabled) {
-                M_DIMINFO.ModJustEnabled = SK_FALSE;
-                return;
-            }
-        }
-    }
-
-    /*
-    ** If we got until here, we have to evaluate the amount of the
-    ** descriptor ratio change...
-    */
-    TotalMaxNbrDescr = pAC->RxDescrPerRing * GetRxCalls(pAC);
-    UsedDescrRatio   = (M_DIMINFO.NbrProcessedDescr * 100) / TotalMaxNbrDescr;
-
-    if (UsedDescrRatio > M_DIMINFO.PrevUsedDescrRatio) {
-        RatioDiffAbs = (UsedDescrRatio - M_DIMINFO.PrevUsedDescrRatio);
-        RatioDiffRel = (RatioDiffAbs * 100) / UsedDescrRatio;
-        M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio;
-        IncreaseTimerDuration = SK_FALSE;  /* in other words: DECREASE */
-    } else if (UsedDescrRatio < M_DIMINFO.PrevUsedDescrRatio) {
-        RatioDiffAbs = (M_DIMINFO.PrevUsedDescrRatio - UsedDescrRatio);
-        RatioDiffRel = (RatioDiffAbs * 100) / M_DIMINFO.PrevUsedDescrRatio;
-        M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio;
-        IncreaseTimerDuration = SK_TRUE;   /* in other words: INCREASE */
-    } else {
-        RatioDiffAbs = (M_DIMINFO.PrevUsedDescrRatio - UsedDescrRatio);
-        RatioDiffRel = (RatioDiffAbs * 100) / M_DIMINFO.PrevUsedDescrRatio;
-        M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio;
-        IncreaseTimerDuration = SK_TRUE;   /* in other words: INCREASE */
-    }
-
-    /*
-    ** Now we can determine the change in percent
-    */
-    if ((RatioDiffRel >= 0) && (RatioDiffRel <= 5) ) {
-       ModAdjValue = 1;  /*  1% change - maybe some other value in future */
-    } else if ((RatioDiffRel > 5) && (RatioDiffRel <= 10) ) {
-       ModAdjValue = 1;  /*  1% change - maybe some other value in future */
-    } else if ((RatioDiffRel > 10) && (RatioDiffRel <= 15) ) {
-       ModAdjValue = 1;  /*  1% change - maybe some other value in future */
-    } else {
-       ModAdjValue = 1;  /*  1% change - maybe some other value in future */
-    }
-
-    if (IncreaseTimerDuration) {
-       NewMaxModIntsPerSec =  M_DIMINFO.MaxModIntsPerSec +
-                             (M_DIMINFO.MaxModIntsPerSec * ModAdjValue) / 100;
-    } else {
-       NewMaxModIntsPerSec =  M_DIMINFO.MaxModIntsPerSec -
-                             (M_DIMINFO.MaxModIntsPerSec * ModAdjValue) / 100;
-    }
-
-    /* 
-    ** Check if we exceed boundaries...
-    */
-    if ( (NewMaxModIntsPerSec > M_DIMINFO.MaxModIntsPerSecUpperLimit) ||
-         (NewMaxModIntsPerSec < M_DIMINFO.MaxModIntsPerSecLowerLimit)) {
-        if (M_DIMINFO.DisplayStats) {
-            printk("Cannot change ModTim from %i to %i ints/sec\n",
-                   M_DIMINFO.MaxModIntsPerSec, NewMaxModIntsPerSec);
-        }
-        return;
-    } else {
-        if (M_DIMINFO.DisplayStats) {
-            printk("Resized ModTim from %i to %i ints/sec\n",
-                   M_DIMINFO.MaxModIntsPerSec, NewMaxModIntsPerSec);
-        }
-    }
-
-    M_DIMINFO.MaxModIntsPerSec = NewMaxModIntsPerSec;
-
-    if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
-        ModBase = C_CLK_FREQ_GENESIS / pAC->DynIrqModInfo.MaxModIntsPerSec;
-    } else {
-        ModBase = C_CLK_FREQ_YUKON / pAC->DynIrqModInfo.MaxModIntsPerSec;
-    }
-
-    /* 
-    ** We do not need to touch any other registers
-    */
-    SK_OUT32(pAC->IoBase, B2_IRQM_INI, ModBase);
-} 
-
-/*******************************************************************************
-** Function     : DisplaySelectedModerationType()
-** Description  : Displays what type of moderation we have
-** Programmer   : Ralph Roesler
-** Last Modified: 23-mar-03
-** Returns      : void!
-** Notes        : -
-*******************************************************************************/
-
-static void
-DisplaySelectedModerationType(SK_AC *pAC) {
-
-    if (pAC->DynIrqModInfo.DisplayStats) {
-        if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_STATIC) {
-             printk("Static int moderation runs with %i INTS/sec\n",
-                    pAC->DynIrqModInfo.MaxModIntsPerSec);
-        } else if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
-             if (IsIntModEnabled(pAC)) {
-                printk("Dynamic int moderation runs with %i INTS/sec\n",
-                       pAC->DynIrqModInfo.MaxModIntsPerSec);
-             } else {
-                printk("Dynamic int moderation currently not applied\n");
-             }
-        } else {
-             printk("No interrupt moderation selected!\n");
-        }
-    }
-}
-
-/*******************************************************************************
-** Function     : DisplaySelectedModerationMask()
-** Description  : Displays what interrupts are moderated
-** Programmer   : Ralph Roesler
-** Last Modified: 23-mar-03
-** Returns      : void!
-** Notes        : -
-*******************************************************************************/
-
-static void
-DisplaySelectedModerationMask(SK_AC *pAC) {
-
-    if (pAC->DynIrqModInfo.DisplayStats) {
-        if (pAC->DynIrqModInfo.IntModTypeSelect != C_INT_MOD_NONE) {
-            switch (pAC->DynIrqModInfo.MaskIrqModeration) {
-                case IRQ_MASK_TX_ONLY: 
-                   printk("Only Tx-interrupts are moderated\n");
-                   break;
-                case IRQ_MASK_RX_ONLY: 
-                   printk("Only Rx-interrupts are moderated\n");
-                   break;
-                case IRQ_MASK_SP_ONLY: 
-                   printk("Only special-interrupts are moderated\n");
-                   break;
-                case IRQ_MASK_TX_RX: 
-                   printk("Tx- and Rx-interrupts are moderated\n");
-                   break;
-                case IRQ_MASK_SP_RX: 
-                   printk("Special- and Rx-interrupts are moderated\n");
-                   break;
-                case IRQ_MASK_SP_TX: 
-                   printk("Special- and Tx-interrupts are moderated\n");
-                   break;
-                case IRQ_MASK_RX_TX_SP:
-                   printk("All Rx-, Tx and special-interrupts are moderated\n");
-                   break;
-                default:
-                   printk("Don't know what is moderated\n");
-                   break;
-            }
-        } else {
-            printk("No specific interrupts masked for moderation\n");
-        }
-    } 
-}
-
-/*******************************************************************************
-** Function     : DisplayDescrRatio
-** Description  : Like the name states...
-** Programmer   : Ralph Roesler
-** Last Modified: 23-mar-03
-** Returns      : void!
-** Notes        : -
-*******************************************************************************/
-
-static void
-DisplayDescrRatio(SK_AC *pAC) {
-    int TotalMaxNbrDescr = 0;
-
-    if (pAC->DynIrqModInfo.DisplayStats) {
-        TotalMaxNbrDescr = pAC->RxDescrPerRing * GetRxCalls(pAC);
-        printk("Ratio descriptors: %i/%i\n",
-               M_DIMINFO.NbrProcessedDescr, TotalMaxNbrDescr);
-    }
-}
-
-/*******************************************************************************
-**
-** End of file
-**
-*******************************************************************************/
diff --git a/drivers/net/sk98lin/skethtool.c b/drivers/net/sk98lin/skethtool.c
deleted file mode 100644 (file)
index 3646069..0000000
+++ /dev/null
@@ -1,628 +0,0 @@
-/******************************************************************************
- *
- * Name:        skethtool.c
- * Project:     GEnesis, PCI Gigabit Ethernet Adapter
- * Version:     $Revision: 1.7 $
- * Date:        $Date: 2004/09/29 13:32:07 $
- * Purpose:     All functions regarding ethtool handling
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect GmbH.
- *     (C)Copyright 2002-2004 Marvell.
- *
- *     Driver for Marvell Yukon/2 chipset and SysKonnect Gigabit Ethernet 
- *      Server Adapters.
- *
- *     Author: Ralph Roesler (rroesler@syskonnect.de)
- *             Mirko Lindner (mlindner@syskonnect.de)
- *
- *     Address all question to: linux@syskonnect.de
- *
- *     The technical manual for the adapters is available from SysKonnect's
- *     web pages: www.syskonnect.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.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- *****************************************************************************/
-
-#include "h/skdrv1st.h"
-#include "h/skdrv2nd.h"
-#include "h/skversion.h"
-
-#include <linux/ethtool.h>
-#include <linux/timer.h>
-#include <linux/delay.h>
-
-/******************************************************************************
- *
- * Defines
- *
- *****************************************************************************/
-
-#define SUPP_COPPER_ALL (SUPPORTED_10baseT_Half  | SUPPORTED_10baseT_Full  | \
-                         SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \
-                         SUPPORTED_1000baseT_Half| SUPPORTED_1000baseT_Full| \
-                         SUPPORTED_TP)
-
-#define ADV_COPPER_ALL  (ADVERTISED_10baseT_Half  | ADVERTISED_10baseT_Full  | \
-                         ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | \
-                         ADVERTISED_1000baseT_Half| ADVERTISED_1000baseT_Full| \
-                         ADVERTISED_TP)
-
-#define SUPP_FIBRE_ALL  (SUPPORTED_1000baseT_Full | \
-                         SUPPORTED_FIBRE          | \
-                         SUPPORTED_Autoneg)
-
-#define ADV_FIBRE_ALL   (ADVERTISED_1000baseT_Full | \
-                         ADVERTISED_FIBRE          | \
-                         ADVERTISED_Autoneg)
-
-
-/******************************************************************************
- *
- * Local Functions
- *
- *****************************************************************************/
-
-/*****************************************************************************
- *
- *     getSettings - retrieves the current settings of the selected adapter
- *
- * Description:
- *     The current configuration of the selected adapter is returned.
- *     This configuration involves a)speed, b)duplex and c)autoneg plus
- *     a number of other variables.
- *
- * Returns:    always 0
- *
- */
-static int getSettings(struct net_device *dev, struct ethtool_cmd *ecmd)
-{
-       const DEV_NET *pNet = netdev_priv(dev);
-       int port = pNet->PortNr;
-       const SK_AC *pAC = pNet->pAC;
-       const SK_GEPORT *pPort = &pAC->GIni.GP[port];
-
-       static int DuplexAutoNegConfMap[9][3]= {
-               { -1                     , -1         , -1              },
-               { 0                      , -1         , -1              },
-               { SK_LMODE_HALF          , DUPLEX_HALF, AUTONEG_DISABLE },
-               { SK_LMODE_FULL          , DUPLEX_FULL, AUTONEG_DISABLE },
-               { SK_LMODE_AUTOHALF      , DUPLEX_HALF, AUTONEG_ENABLE  },
-               { SK_LMODE_AUTOFULL      , DUPLEX_FULL, AUTONEG_ENABLE  },
-               { SK_LMODE_AUTOBOTH      , DUPLEX_FULL, AUTONEG_ENABLE  },
-               { SK_LMODE_AUTOSENSE     , -1         , -1              },
-               { SK_LMODE_INDETERMINATED, -1         , -1              }
-       };
-       static int SpeedConfMap[6][2] = {
-               { 0                       , -1         },
-               { SK_LSPEED_AUTO          , -1         },
-               { SK_LSPEED_10MBPS        , SPEED_10   },
-               { SK_LSPEED_100MBPS       , SPEED_100  },
-               { SK_LSPEED_1000MBPS      , SPEED_1000 },
-               { SK_LSPEED_INDETERMINATED, -1         }
-       };
-       static int AdvSpeedMap[6][2] = {
-               { 0                       , -1         },
-               { SK_LSPEED_AUTO          , -1         },
-               { SK_LSPEED_10MBPS        , ADVERTISED_10baseT_Half   | ADVERTISED_10baseT_Full },
-               { SK_LSPEED_100MBPS       , ADVERTISED_100baseT_Half  | ADVERTISED_100baseT_Full },
-               { SK_LSPEED_1000MBPS      , ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full},
-               { SK_LSPEED_INDETERMINATED, -1         }
-       };
-
-       ecmd->phy_address = port;
-       ecmd->speed       = SpeedConfMap[pPort->PLinkSpeedUsed][1];
-       ecmd->duplex      = DuplexAutoNegConfMap[pPort->PLinkModeStatus][1];
-       ecmd->autoneg     = DuplexAutoNegConfMap[pPort->PLinkModeStatus][2];
-       ecmd->transceiver = XCVR_INTERNAL;
-
-       if (pAC->GIni.GICopperType) {
-               ecmd->port        = PORT_TP;
-               ecmd->supported   = (SUPP_COPPER_ALL|SUPPORTED_Autoneg);
-               if (pAC->GIni.GIGenesis) {
-                       ecmd->supported &= ~(SUPPORTED_10baseT_Half);
-                       ecmd->supported &= ~(SUPPORTED_10baseT_Full);
-                       ecmd->supported &= ~(SUPPORTED_100baseT_Half);
-                       ecmd->supported &= ~(SUPPORTED_100baseT_Full);
-               } else {
-                       if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {
-                               ecmd->supported &= ~(SUPPORTED_1000baseT_Half);
-                       } 
-#ifdef CHIP_ID_YUKON_FE
-                       if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) {
-                               ecmd->supported &= ~(SUPPORTED_1000baseT_Half);
-                               ecmd->supported &= ~(SUPPORTED_1000baseT_Full);
-                       }
-#endif
-               }
-               if (pAC->GIni.GP[0].PLinkSpeed != SK_LSPEED_AUTO) {
-                       ecmd->advertising = AdvSpeedMap[pPort->PLinkSpeed][1];
-                       if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {
-                               ecmd->advertising &= ~(SUPPORTED_1000baseT_Half);
-                       } 
-               } else {
-                       ecmd->advertising = ecmd->supported;
-               }
-
-               if (ecmd->autoneg == AUTONEG_ENABLE) 
-                       ecmd->advertising |= ADVERTISED_Autoneg;
-       } else {
-               ecmd->port        = PORT_FIBRE;
-               ecmd->supported   = SUPP_FIBRE_ALL;
-               ecmd->advertising = ADV_FIBRE_ALL;
-       }
-       return 0;
-}
-
-/*
- * MIB infrastructure uses instance value starting at 1
- * based on board and port.
- */
-static inline u32 pnmiInstance(const DEV_NET *pNet)
-{
-       return 1 + (pNet->pAC->RlmtNets == 2) + pNet->PortNr;
-}
-
-/*****************************************************************************
- *
- *     setSettings - configures the settings of a selected adapter
- *
- * Description:
- *     Possible settings that may be altered are a)speed, b)duplex or 
- *     c)autonegotiation.
- *
- * Returns:
- *     0:      everything fine, no error
- *     <0:     the return value is the error code of the failure 
- */
-static int setSettings(struct net_device *dev, struct ethtool_cmd *ecmd)
-{
-       DEV_NET *pNet = netdev_priv(dev);
-       SK_AC *pAC = pNet->pAC;
-       u32 instance;
-       char buf[4];
-       int len = 1;
-
-       if (ecmd->speed != SPEED_10 && ecmd->speed != SPEED_100 
-           && ecmd->speed != SPEED_1000)
-               return -EINVAL;
-
-       if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL)
-               return -EINVAL;
-
-       if (ecmd->autoneg != AUTONEG_DISABLE && ecmd->autoneg != AUTONEG_ENABLE)
-               return -EINVAL;
-
-       if (ecmd->autoneg == AUTONEG_DISABLE)
-               *buf = (ecmd->duplex == DUPLEX_FULL) 
-                       ? SK_LMODE_FULL : SK_LMODE_HALF;
-       else
-               *buf = (ecmd->duplex == DUPLEX_FULL) 
-                       ? SK_LMODE_AUTOFULL : SK_LMODE_AUTOHALF;
-       
-       instance = pnmiInstance(pNet);
-       if (SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_LINK_MODE, 
-                          &buf, &len, instance, pNet->NetNr) != SK_PNMI_ERR_OK)
-               return -EINVAL;
-
-       switch(ecmd->speed) {
-       case SPEED_1000:
-               *buf = SK_LSPEED_1000MBPS;
-               break;
-       case SPEED_100:
-               *buf = SK_LSPEED_100MBPS;
-               break;
-       case SPEED_10:
-               *buf = SK_LSPEED_10MBPS;
-       }
-
-       if (SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_SPEED_MODE, 
-                        &buf, &len, instance, pNet->NetNr) != SK_PNMI_ERR_OK)
-               return -EINVAL;
-
-       return 0;
-}
-
-/*****************************************************************************
- *
- *     getDriverInfo - returns generic driver and adapter information
- *
- * Description:
- *     Generic driver information is returned via this function, such as
- *     the name of the driver, its version and and firmware version.
- *     In addition to this, the location of the selected adapter is 
- *     returned as a bus info string (e.g. '01:05.0').
- *     
- * Returns:    N/A
- *
- */
-static void getDriverInfo(struct net_device *dev, struct ethtool_drvinfo *info)
-{
-       const DEV_NET   *pNet = netdev_priv(dev);
-       const SK_AC *pAC = pNet->pAC;
-       char vers[32];
-
-       snprintf(vers, sizeof(vers)-1, VER_STRING "(v%d.%d)",
-               (pAC->GIni.GIPciHwRev >> 4) & 0xf, pAC->GIni.GIPciHwRev & 0xf);
-
-       strlcpy(info->driver, DRIVER_FILE_NAME, sizeof(info->driver));
-       strcpy(info->version, vers);
-       strcpy(info->fw_version, "N/A");
-       strlcpy(info->bus_info, pci_name(pAC->PciDev), ETHTOOL_BUSINFO_LEN);
-}
-
-/*
- * Ethtool statistics support.
- */
-static const char StringsStats[][ETH_GSTRING_LEN] = {
-       "rx_packets",   "tx_packets",
-       "rx_bytes",     "tx_bytes",
-       "rx_errors",    "tx_errors",    
-       "rx_dropped",   "tx_dropped",
-       "multicasts",   "collisions",   
-       "rx_length_errors",             "rx_buffer_overflow_errors",
-       "rx_crc_errors",                "rx_frame_errors",
-       "rx_too_short_errors",          "rx_too_long_errors",
-       "rx_carrier_extension_errors",  "rx_symbol_errors",
-       "rx_llc_mac_size_errors",       "rx_carrier_errors",    
-       "rx_jabber_errors",             "rx_missed_errors",
-       "tx_abort_collision_errors",    "tx_carrier_errors",
-       "tx_buffer_underrun_errors",    "tx_heartbeat_errors",
-       "tx_window_errors",
-};
-
-static int getStatsCount(struct net_device *dev)
-{
-       return ARRAY_SIZE(StringsStats);
-}
-
-static void getStrings(struct net_device *dev, u32 stringset, u8 *data)
-{
-       switch(stringset) {
-       case ETH_SS_STATS:
-               memcpy(data, *StringsStats, sizeof(StringsStats));
-               break;
-       }
-}
-
-static void getEthtoolStats(struct net_device *dev,
-                           struct ethtool_stats *stats, u64 *data)
-{
-       const DEV_NET   *pNet = netdev_priv(dev);
-       const SK_AC *pAC = pNet->pAC;
-       const SK_PNMI_STRUCT_DATA *pPnmiStruct = &pAC->PnmiStruct;
-
-       *data++ = pPnmiStruct->Stat[0].StatRxOkCts;
-       *data++ = pPnmiStruct->Stat[0].StatTxOkCts;
-       *data++ = pPnmiStruct->Stat[0].StatRxOctetsOkCts;
-       *data++ = pPnmiStruct->Stat[0].StatTxOctetsOkCts;
-       *data++ = pPnmiStruct->InErrorsCts;
-       *data++ = pPnmiStruct->Stat[0].StatTxSingleCollisionCts;
-       *data++ = pPnmiStruct->RxNoBufCts;
-       *data++ = pPnmiStruct->TxNoBufCts;
-       *data++ = pPnmiStruct->Stat[0].StatRxMulticastOkCts;
-       *data++ = pPnmiStruct->Stat[0].StatTxSingleCollisionCts;
-       *data++ = pPnmiStruct->Stat[0].StatRxRuntCts;
-       *data++ = pPnmiStruct->Stat[0].StatRxFifoOverflowCts;
-       *data++ = pPnmiStruct->Stat[0].StatRxFcsCts;
-       *data++ = pPnmiStruct->Stat[0].StatRxFramingCts;
-       *data++ = pPnmiStruct->Stat[0].StatRxShortsCts;
-       *data++ = pPnmiStruct->Stat[0].StatRxTooLongCts;
-       *data++ = pPnmiStruct->Stat[0].StatRxCextCts;
-       *data++ = pPnmiStruct->Stat[0].StatRxSymbolCts;
-       *data++ = pPnmiStruct->Stat[0].StatRxIRLengthCts;
-       *data++ = pPnmiStruct->Stat[0].StatRxCarrierCts;
-       *data++ = pPnmiStruct->Stat[0].StatRxJabberCts;
-       *data++ = pPnmiStruct->Stat[0].StatRxMissedCts;
-       *data++ = pAC->stats.tx_aborted_errors;
-       *data++ = pPnmiStruct->Stat[0].StatTxCarrierCts;
-       *data++ = pPnmiStruct->Stat[0].StatTxFifoUnderrunCts;
-       *data++ = pPnmiStruct->Stat[0].StatTxCarrierCts;
-       *data++ = pAC->stats.tx_window_errors;
-}
-
-
-/*****************************************************************************
- *
- *     toggleLeds - Changes the LED state of an adapter
- *
- * Description:
- *     This function changes the current state of all LEDs of an adapter so
- *     that it can be located by a user. 
- *
- * Returns:    N/A
- *
- */
-static void toggleLeds(DEV_NET *pNet, int on)
-{
-       SK_AC *pAC = pNet->pAC;
-       int port = pNet->PortNr;
-       void __iomem *io = pAC->IoBase;
-
-       if (pAC->GIni.GIGenesis) {
-               SK_OUT8(io, MR_ADDR(port,LNK_LED_REG), 
-                       on ? SK_LNK_ON : SK_LNK_OFF);
-               SkGeYellowLED(pAC, io, 
-                             on ? (LED_ON >> 1) : (LED_OFF >> 1));
-               SkGeXmitLED(pAC, io, MR_ADDR(port,RX_LED_INI),
-                           on ? SK_LED_TST : SK_LED_DIS);
-
-               if (pAC->GIni.GP[port].PhyType == SK_PHY_BCOM)
-                       SkXmPhyWrite(pAC, io, port, PHY_BCOM_P_EXT_CTRL, 
-                                    on ? PHY_B_PEC_LED_ON : PHY_B_PEC_LED_OFF);
-               else if (pAC->GIni.GP[port].PhyType == SK_PHY_LONE)
-                       SkXmPhyWrite(pAC, io, port, PHY_LONE_LED_CFG,
-                                    on ? 0x0800 : PHY_L_LC_LEDT);
-               else
-                       SkGeXmitLED(pAC, io, MR_ADDR(port,TX_LED_INI),
-                                   on ? SK_LED_TST : SK_LED_DIS);
-       } else {
-               const u16 YukLedOn = (PHY_M_LED_MO_DUP(MO_LED_ON)  |
-                                     PHY_M_LED_MO_10(MO_LED_ON)   |
-                                     PHY_M_LED_MO_100(MO_LED_ON)  |
-                                     PHY_M_LED_MO_1000(MO_LED_ON) | 
-                                     PHY_M_LED_MO_RX(MO_LED_ON));
-               const u16  YukLedOff = (PHY_M_LED_MO_DUP(MO_LED_OFF)  |
-                                       PHY_M_LED_MO_10(MO_LED_OFF)   |
-                                       PHY_M_LED_MO_100(MO_LED_OFF)  |
-                                       PHY_M_LED_MO_1000(MO_LED_OFF) | 
-                                       PHY_M_LED_MO_RX(MO_LED_OFF));
-       
-
-               SkGmPhyWrite(pAC,io,port,PHY_MARV_LED_CTRL,0);
-               SkGmPhyWrite(pAC,io,port,PHY_MARV_LED_OVER, 
-                            on ? YukLedOn : YukLedOff);
-       }
-}
-
-/*****************************************************************************
- *
- *     skGeBlinkTimer - Changes the LED state of an adapter
- *
- * Description:
- *     This function changes the current state of all LEDs of an adapter so
- *     that it can be located by a user. If the requested time interval for
- *     this test has elapsed, this function cleans up everything that was 
- *     temporarily setup during the locate NIC test. This involves of course
- *     also closing or opening any adapter so that the initial board state 
- *     is recovered.
- *
- * Returns:    N/A
- *
- */
-void SkGeBlinkTimer(unsigned long data)
-{
-       struct net_device *dev = (struct net_device *) data;
-       DEV_NET *pNet = netdev_priv(dev);
-       SK_AC *pAC = pNet->pAC;
-
-       toggleLeds(pNet, pAC->LedsOn);
-
-       pAC->LedsOn = !pAC->LedsOn;
-       mod_timer(&pAC->BlinkTimer, jiffies + HZ/4);
-}
-
-/*****************************************************************************
- *
- *     locateDevice - start the locate NIC feature of the elected adapter 
- *
- * Description:
- *     This function is used if the user want to locate a particular NIC.
- *     All LEDs are regularly switched on and off, so the NIC can easily
- *     be identified.
- *
- * Returns:    
- *     ==0:    everything fine, no error, locateNIC test was started
- *     !=0:    one locateNIC test runs already
- *
- */
-static int locateDevice(struct net_device *dev, u32 data)
-{
-       DEV_NET *pNet = netdev_priv(dev);
-       SK_AC *pAC = pNet->pAC;
-
-       if(!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ))
-               data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ);
-
-       /* start blinking */
-       pAC->LedsOn = 0;
-       mod_timer(&pAC->BlinkTimer, jiffies);
-       msleep_interruptible(data * 1000);
-       del_timer_sync(&pAC->BlinkTimer);
-       toggleLeds(pNet, 0);
-
-       return 0;
-}
-
-/*****************************************************************************
- *
- *     getPauseParams - retrieves the pause parameters
- *
- * Description:
- *     All current pause parameters of a selected adapter are placed 
- *     in the passed ethtool_pauseparam structure and are returned.
- *
- * Returns:    N/A
- *
- */
-static void getPauseParams(struct net_device *dev, struct ethtool_pauseparam *epause) 
-{
-       DEV_NET *pNet = netdev_priv(dev);
-       SK_AC *pAC = pNet->pAC;
-       SK_GEPORT *pPort = &pAC->GIni.GP[pNet->PortNr];
-
-       epause->rx_pause = (pPort->PFlowCtrlMode == SK_FLOW_MODE_SYMMETRIC) ||
-                 (pPort->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM);
-
-       epause->tx_pause = epause->rx_pause || (pPort->PFlowCtrlMode == SK_FLOW_MODE_LOC_SEND);
-       epause->autoneg = epause->rx_pause || epause->tx_pause;
-}
-
-/*****************************************************************************
- *
- *     setPauseParams - configures the pause parameters of an adapter
- *
- * Description:
- *     This function sets the Rx or Tx pause parameters 
- *
- * Returns:
- *     ==0:    everything fine, no error
- *     !=0:    the return value is the error code of the failure 
- */
-static int setPauseParams(struct net_device *dev , struct ethtool_pauseparam *epause)
-{
-       DEV_NET *pNet = netdev_priv(dev);
-       SK_AC *pAC = pNet->pAC;
-       SK_GEPORT *pPort = &pAC->GIni.GP[pNet->PortNr];
-       u32     instance = pnmiInstance(pNet);
-       struct ethtool_pauseparam old;
-       u8      oldspeed = pPort->PLinkSpeedUsed;
-       char    buf[4];
-       int     len = 1;
-       int ret;
-
-       /*
-       ** we have to determine the current settings to see if 
-       ** the operator requested any modification of the flow 
-       ** control parameters...
-       */
-       getPauseParams(dev, &old);
-
-       /*
-       ** perform modifications regarding the changes 
-       ** requested by the operator
-       */
-       if (epause->autoneg != old.autoneg) 
-               *buf = epause->autoneg ? SK_FLOW_MODE_NONE : SK_FLOW_MODE_SYMMETRIC;
-       else {
-               if (epause->rx_pause && epause->tx_pause) 
-                       *buf = SK_FLOW_MODE_SYMMETRIC;
-               else if (epause->rx_pause && !epause->tx_pause)
-                       *buf =  SK_FLOW_MODE_SYM_OR_REM;
-               else if (!epause->rx_pause && epause->tx_pause)
-                       *buf =  SK_FLOW_MODE_LOC_SEND;
-               else
-                       *buf = SK_FLOW_MODE_NONE;
-       }
-
-       ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_FLOWCTRL_MODE,
-                        &buf, &len, instance, pNet->NetNr);
-
-       if (ret != SK_PNMI_ERR_OK) {
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_CTRL,
-                          ("ethtool (sk98lin): error changing rx/tx pause (%i)\n", ret));
-               goto err;
-       }
-
-       /*
-       ** It may be that autoneg has been disabled! Therefore
-       ** set the speed to the previously used value...
-       */
-       if (!epause->autoneg) {
-               len = 1;
-               ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_SPEED_MODE, 
-                                  &oldspeed, &len, instance, pNet->NetNr);
-               if (ret != SK_PNMI_ERR_OK) 
-                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_CTRL,
-                                  ("ethtool (sk98lin): error setting speed (%i)\n", ret));
-       }
- err:
-        return ret ? -EIO : 0;
-}
-
-/* Only Yukon supports checksum offload. */
-static int setScatterGather(struct net_device *dev, u32 data)
-{
-       DEV_NET *pNet = netdev_priv(dev);
-       SK_AC *pAC = pNet->pAC;
-
-       if (pAC->GIni.GIChipId == CHIP_ID_GENESIS)
-               return -EOPNOTSUPP;
-       return ethtool_op_set_sg(dev, data);
-}
-
-static int setTxCsum(struct net_device *dev, u32 data)
-{
-       DEV_NET *pNet = netdev_priv(dev);
-       SK_AC *pAC = pNet->pAC;
-
-       if (pAC->GIni.GIChipId == CHIP_ID_GENESIS)
-               return -EOPNOTSUPP;
-
-       return ethtool_op_set_tx_csum(dev, data);
-}
-
-static u32 getRxCsum(struct net_device *dev)
-{
-       DEV_NET *pNet = netdev_priv(dev);
-       SK_AC *pAC = pNet->pAC;
-
-       return pAC->RxPort[pNet->PortNr].RxCsum;
-}
-
-static int setRxCsum(struct net_device *dev, u32 data)
-{
-       DEV_NET *pNet = netdev_priv(dev);
-       SK_AC *pAC = pNet->pAC;
-
-       if (pAC->GIni.GIChipId == CHIP_ID_GENESIS)
-               return -EOPNOTSUPP;
-
-       pAC->RxPort[pNet->PortNr].RxCsum = data != 0;
-       return 0;
-}
-
-static int getRegsLen(struct net_device *dev)
-{
-       return 0x4000;
-}
-
-/*
- * Returns copy of whole control register region
- * Note: skip RAM address register because accessing it will
- *      cause bus hangs!
- */
-static void getRegs(struct net_device *dev, struct ethtool_regs *regs,
-                         void *p)
-{
-       DEV_NET *pNet = netdev_priv(dev);
-       const void __iomem *io = pNet->pAC->IoBase;
-
-       regs->version = 1;
-       memset(p, 0, regs->len);
-       memcpy_fromio(p, io, B3_RAM_ADDR);
-
-       memcpy_fromio(p + B3_RI_WTO_R1, io + B3_RI_WTO_R1,
-                     regs->len - B3_RI_WTO_R1);
-}
-
-const struct ethtool_ops SkGeEthtoolOps = {
-       .get_settings           = getSettings,
-       .set_settings           = setSettings,
-       .get_drvinfo            = getDriverInfo,
-       .get_strings            = getStrings,
-       .get_stats_count        = getStatsCount,
-       .get_ethtool_stats      = getEthtoolStats,
-       .phys_id                = locateDevice,
-       .get_pauseparam         = getPauseParams,
-       .set_pauseparam         = setPauseParams,
-       .get_link               = ethtool_op_get_link,
-       .get_perm_addr          = ethtool_op_get_perm_addr,
-       .get_sg                 = ethtool_op_get_sg,
-       .set_sg                 = setScatterGather,
-       .get_tx_csum            = ethtool_op_get_tx_csum,
-       .set_tx_csum            = setTxCsum,
-       .get_rx_csum            = getRxCsum,
-       .set_rx_csum            = setRxCsum,
-       .get_regs               = getRegs,
-       .get_regs_len           = getRegsLen,
-};
diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c
deleted file mode 100644 (file)
index bf21862..0000000
+++ /dev/null
@@ -1,5211 +0,0 @@
-/******************************************************************************
- *
- * Name:       skge.c
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.45 $
- * Date:               $Date: 2004/02/12 14:41:02 $
- * Purpose:    The main driver source module
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect GmbH.
- *     (C)Copyright 2002-2003 Marvell.
- *
- *     Driver for Marvell Yukon chipset and SysKonnect Gigabit Ethernet 
- *      Server Adapters.
- *
- *     Created 10-Feb-1999, based on Linux' acenic.c, 3c59x.c and
- *     SysKonnects GEnesis Solaris driver
- *     Author: Christoph Goos (cgoos@syskonnect.de)
- *             Mirko Lindner (mlindner@syskonnect.de)
- *
- *     Address all question to: linux@syskonnect.de
- *
- *     The technical manual for the adapters is available from SysKonnect's
- *     web pages: www.syskonnect.com
- *     Goto "Support" and search Knowledge Base for "manual".
- *     
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * Possible compiler options (#define xxx / -Dxxx):
- *
- *     debugging can be enable by changing SK_DEBUG_CHKMOD and
- *     SK_DEBUG_CHKCAT in makefile (described there).
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * Description:
- *
- *     This is the main module of the Linux GE driver.
- *     
- *     All source files except skge.c, skdrv1st.h, skdrv2nd.h and sktypes.h
- *     are part of SysKonnect's COMMON MODULES for the SK-98xx adapters.
- *     Those are used for drivers on multiple OS', so some thing may seem
- *     unnecessary complicated on Linux. Please do not try to 'clean up'
- *     them without VERY good reasons, because this will make it more
- *     difficult to keep the Linux driver in synchronisation with the
- *     other versions.
- *
- * Include file hierarchy:
- *
- *     <linux/module.h>
- *
- *     "h/skdrv1st.h"
- *             <linux/types.h>
- *             <linux/kernel.h>
- *             <linux/string.h>
- *             <linux/errno.h>
- *             <linux/ioport.h>
- *             <linux/slab.h>
- *             <linux/interrupt.h>
- *             <linux/pci.h>
- *             <linux/bitops.h>
- *             <asm/byteorder.h>
- *             <asm/io.h>
- *             <linux/netdevice.h>
- *             <linux/etherdevice.h>
- *             <linux/skbuff.h>
- *         those three depending on kernel version used:
- *             <linux/bios32.h>
- *             <linux/init.h>
- *             <asm/uaccess.h>
- *             <net/checksum.h>
- *
- *             "h/skerror.h"
- *             "h/skdebug.h"
- *             "h/sktypes.h"
- *             "h/lm80.h"
- *             "h/xmac_ii.h"
- *
- *      "h/skdrv2nd.h"
- *             "h/skqueue.h"
- *             "h/skgehwt.h"
- *             "h/sktimer.h"
- *             "h/ski2c.h"
- *             "h/skgepnmi.h"
- *             "h/skvpd.h"
- *             "h/skgehw.h"
- *             "h/skgeinit.h"
- *             "h/skaddr.h"
- *             "h/skgesirq.h"
- *             "h/skrlmt.h"
- *
- ******************************************************************************/
-
-#include       "h/skversion.h"
-
-#include       <linux/in.h>
-#include       <linux/module.h>
-#include       <linux/moduleparam.h>
-#include       <linux/init.h>
-#include       <linux/dma-mapping.h>
-#include       <linux/ip.h>
-#include       <linux/mii.h>
-#include       <linux/mm.h>
-
-#include       "h/skdrv1st.h"
-#include       "h/skdrv2nd.h"
-
-/*******************************************************************************
- *
- * Defines
- *
- ******************************************************************************/
-
-/* for debuging on x86 only */
-/* #define BREAKPOINT() asm(" int $3"); */
-
-/* use the transmit hw checksum driver functionality */
-#define USE_SK_TX_CHECKSUM
-
-/* use the receive hw checksum driver functionality */
-#define USE_SK_RX_CHECKSUM
-
-/* use the scatter-gather functionality with sendfile() */
-#define SK_ZEROCOPY
-
-/* use of a transmit complete interrupt */
-#define USE_TX_COMPLETE
-
-/*
- * threshold for copying small receive frames
- * set to 0 to avoid copying, set to 9001 to copy all frames
- */
-#define SK_COPY_THRESHOLD      50
-
-/* number of adapters that can be configured via command line params */
-#define SK_MAX_CARD_PARAM      16
-
-
-
-/*
- * use those defines for a compile-in version of the driver instead
- * of command line parameters
- */
-// #define LINK_SPEED_A        {"Auto", }
-// #define LINK_SPEED_B        {"Auto", }
-// #define AUTO_NEG_A  {"Sense", }
-// #define AUTO_NEG_B  {"Sense", }
-// #define DUP_CAP_A   {"Both", }
-// #define DUP_CAP_B   {"Both", }
-// #define FLOW_CTRL_A {"SymOrRem", }
-// #define FLOW_CTRL_B {"SymOrRem", }
-// #define ROLE_A      {"Auto", }
-// #define ROLE_B      {"Auto", }
-// #define PREF_PORT   {"A", }
-// #define CON_TYPE    {"Auto", }
-// #define RLMT_MODE   {"CheckLinkState", }
-
-#define DEV_KFREE_SKB(skb) dev_kfree_skb(skb)
-#define DEV_KFREE_SKB_IRQ(skb) dev_kfree_skb_irq(skb)
-#define DEV_KFREE_SKB_ANY(skb) dev_kfree_skb_any(skb)
-
-
-/* Set blink mode*/
-#define OEM_CONFIG_VALUE (     SK_ACT_LED_BLINK | \
-                               SK_DUP_LED_NORMAL | \
-                               SK_LED_LINK100_ON)
-
-
-/* Isr return value */
-#define SkIsrRetVar    irqreturn_t
-#define SkIsrRetNone   IRQ_NONE
-#define SkIsrRetHandled        IRQ_HANDLED
-
-
-/*******************************************************************************
- *
- * Local Function Prototypes
- *
- ******************************************************************************/
-
-static void    FreeResources(struct SK_NET_DEVICE *dev);
-static int     SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC);
-static SK_BOOL BoardAllocMem(SK_AC *pAC);
-static void    BoardFreeMem(SK_AC *pAC);
-static void    BoardInitMem(SK_AC *pAC);
-static void    SetupRing(SK_AC*, void*, uintptr_t, RXD**, RXD**, RXD**, int*, SK_BOOL);
-static SkIsrRetVar     SkGeIsr(int irq, void *dev_id);
-static SkIsrRetVar     SkGeIsrOnePort(int irq, void *dev_id);
-static int     SkGeOpen(struct SK_NET_DEVICE *dev);
-static int     SkGeClose(struct SK_NET_DEVICE *dev);
-static int     SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev);
-static int     SkGeSetMacAddr(struct SK_NET_DEVICE *dev, void *p);
-static void    SkGeSetRxMode(struct SK_NET_DEVICE *dev);
-static struct  net_device_stats *SkGeStats(struct SK_NET_DEVICE *dev);
-static int     SkGeIoctl(struct SK_NET_DEVICE *dev, struct ifreq *rq, int cmd);
-static void    GetConfiguration(SK_AC*);
-static int     XmitFrame(SK_AC*, TX_PORT*, struct sk_buff*);
-static void    FreeTxDescriptors(SK_AC*pAC, TX_PORT*);
-static void    FillRxRing(SK_AC*, RX_PORT*);
-static SK_BOOL FillRxDescriptor(SK_AC*, RX_PORT*);
-static void    ReceiveIrq(SK_AC*, RX_PORT*, SK_BOOL);
-static void    ClearAndStartRx(SK_AC*, int);
-static void    ClearTxIrq(SK_AC*, int, int);
-static void    ClearRxRing(SK_AC*, RX_PORT*);
-static void    ClearTxRing(SK_AC*, TX_PORT*);
-static int     SkGeChangeMtu(struct SK_NET_DEVICE *dev, int new_mtu);
-static void    PortReInitBmu(SK_AC*, int);
-static int     SkGeIocMib(DEV_NET*, unsigned int, int);
-static int     SkGeInitPCI(SK_AC *pAC);
-static void    StartDrvCleanupTimer(SK_AC *pAC);
-static void    StopDrvCleanupTimer(SK_AC *pAC);
-static int     XmitFrameSG(SK_AC*, TX_PORT*, struct sk_buff*);
-
-#ifdef SK_DIAG_SUPPORT
-static SK_U32   ParseDeviceNbrFromSlotName(const char *SlotName);
-static int      SkDrvInitAdapter(SK_AC *pAC, int devNbr);
-static int      SkDrvDeInitAdapter(SK_AC *pAC, int devNbr);
-#endif
-
-/*******************************************************************************
- *
- * Extern Function Prototypes
- *
- ******************************************************************************/
-extern void SkDimEnableModerationIfNeeded(SK_AC *pAC); 
-extern void SkDimDisplayModerationSettings(SK_AC *pAC);
-extern void SkDimStartModerationTimer(SK_AC *pAC);
-extern void SkDimModerate(SK_AC *pAC);
-extern void SkGeBlinkTimer(unsigned long data);
-
-#ifdef DEBUG
-static void    DumpMsg(struct sk_buff*, char*);
-static void    DumpData(char*, int);
-static void    DumpLong(char*, int);
-#endif
-
-/* global variables *********************************************************/
-static SK_BOOL DoPrintInterfaceChange = SK_TRUE;
-extern const struct ethtool_ops SkGeEthtoolOps;
-
-/* local variables **********************************************************/
-static uintptr_t TxQueueAddr[SK_MAX_MACS][2] = {{0x680, 0x600},{0x780, 0x700}};
-static uintptr_t RxQueueAddr[SK_MAX_MACS] = {0x400, 0x480};
-
-/*****************************************************************************
- *
- *     SkPciWriteCfgDWord - write a 32 bit value to pci config space
- *
- * Description:
- *     This routine writes a 32 bit value to the pci configuration
- *     space.
- *
- * Returns:
- *     0 - indicate everything worked ok.
- *     != 0 - error indication
- */
-static inline int SkPciWriteCfgDWord(
-SK_AC *pAC,    /* Adapter Control structure pointer */
-int PciAddr,           /* PCI register address */
-SK_U32 Val)            /* pointer to store the read value */
-{
-       pci_write_config_dword(pAC->PciDev, PciAddr, Val);
-       return(0);
-} /* SkPciWriteCfgDWord */
-
-/*****************************************************************************
- *
- *     SkGeInitPCI - Init the PCI resources
- *
- * Description:
- *     This function initialize the PCI resources and IO
- *
- * Returns:
- *     0 - indicate everything worked ok.
- *     != 0 - error indication
- */
-static __devinit int SkGeInitPCI(SK_AC *pAC)
-{
-       struct SK_NET_DEVICE *dev = pAC->dev[0];
-       struct pci_dev *pdev = pAC->PciDev;
-       int retval;
-
-       dev->mem_start = pci_resource_start (pdev, 0);
-       pci_set_master(pdev);
-
-       retval = pci_request_regions(pdev, "sk98lin");
-       if (retval)
-               goto out;
-
-#ifdef SK_BIG_ENDIAN
-       /*
-        * On big endian machines, we use the adapter's aibility of
-        * reading the descriptors as big endian.
-        */
-       {
-               SK_U32          our2;
-               SkPciReadCfgDWord(pAC, PCI_OUR_REG_2, &our2);
-               our2 |= PCI_REV_DESC;
-               SkPciWriteCfgDWord(pAC, PCI_OUR_REG_2, our2);
-       }
-#endif
-
-       /*
-        * Remap the regs into kernel space.
-        */
-       pAC->IoBase = ioremap_nocache(dev->mem_start, 0x4000);
-       if (!pAC->IoBase) {
-               retval = -EIO;
-               goto out_release;
-       }
-
-       return 0;
-
- out_release:
-       pci_release_regions(pdev);
- out:
-       return retval;
-}
-
-
-/*****************************************************************************
- *
- *     FreeResources - release resources allocated for adapter
- *
- * Description:
- *     This function releases the IRQ, unmaps the IO and
- *     frees the desriptor ring.
- *
- * Returns: N/A
- *     
- */
-static void FreeResources(struct SK_NET_DEVICE *dev)
-{
-SK_U32 AllocFlag;
-DEV_NET                *pNet;
-SK_AC          *pAC;
-
-       pNet = netdev_priv(dev);
-       pAC = pNet->pAC;
-       AllocFlag = pAC->AllocFlag;
-       if (pAC->PciDev) {
-               pci_release_regions(pAC->PciDev);
-       }
-       if (AllocFlag & SK_ALLOC_IRQ) {
-               free_irq(dev->irq, dev);
-       }
-       if (pAC->IoBase) {
-               iounmap(pAC->IoBase);
-       }
-       if (pAC->pDescrMem) {
-               BoardFreeMem(pAC);
-       }
-       
-} /* FreeResources */
-
-MODULE_AUTHOR("Mirko Lindner <mlindner@syskonnect.de>");
-MODULE_DESCRIPTION("SysKonnect SK-NET Gigabit Ethernet SK-98xx driver");
-MODULE_LICENSE("GPL");
-
-#ifdef LINK_SPEED_A
-static char *Speed_A[SK_MAX_CARD_PARAM] = LINK_SPEED;
-#else
-static char *Speed_A[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-#ifdef LINK_SPEED_B
-static char *Speed_B[SK_MAX_CARD_PARAM] = LINK_SPEED;
-#else
-static char *Speed_B[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-#ifdef AUTO_NEG_A
-static char *AutoNeg_A[SK_MAX_CARD_PARAM] = AUTO_NEG_A;
-#else
-static char *AutoNeg_A[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-#ifdef DUP_CAP_A
-static char *DupCap_A[SK_MAX_CARD_PARAM] = DUP_CAP_A;
-#else
-static char *DupCap_A[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-#ifdef FLOW_CTRL_A
-static char *FlowCtrl_A[SK_MAX_CARD_PARAM] = FLOW_CTRL_A;
-#else
-static char *FlowCtrl_A[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-#ifdef ROLE_A
-static char *Role_A[SK_MAX_CARD_PARAM] = ROLE_A;
-#else
-static char *Role_A[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-#ifdef AUTO_NEG_B
-static char *AutoNeg_B[SK_MAX_CARD_PARAM] = AUTO_NEG_B;
-#else
-static char *AutoNeg_B[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-#ifdef DUP_CAP_B
-static char *DupCap_B[SK_MAX_CARD_PARAM] = DUP_CAP_B;
-#else
-static char *DupCap_B[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-#ifdef FLOW_CTRL_B
-static char *FlowCtrl_B[SK_MAX_CARD_PARAM] = FLOW_CTRL_B;
-#else
-static char *FlowCtrl_B[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-#ifdef ROLE_B
-static char *Role_B[SK_MAX_CARD_PARAM] = ROLE_B;
-#else
-static char *Role_B[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-#ifdef CON_TYPE
-static char *ConType[SK_MAX_CARD_PARAM] = CON_TYPE;
-#else
-static char *ConType[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-#ifdef PREF_PORT
-static char *PrefPort[SK_MAX_CARD_PARAM] = PREF_PORT;
-#else
-static char *PrefPort[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-#ifdef RLMT_MODE
-static char *RlmtMode[SK_MAX_CARD_PARAM] = RLMT_MODE;
-#else
-static char *RlmtMode[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-static int   IntsPerSec[SK_MAX_CARD_PARAM];
-static char *Moderation[SK_MAX_CARD_PARAM];
-static char *ModerationMask[SK_MAX_CARD_PARAM];
-static char *AutoSizing[SK_MAX_CARD_PARAM];
-static char *Stats[SK_MAX_CARD_PARAM];
-
-module_param_array(Speed_A, charp, NULL, 0);
-module_param_array(Speed_B, charp, NULL, 0);
-module_param_array(AutoNeg_A, charp, NULL, 0);
-module_param_array(AutoNeg_B, charp, NULL, 0);
-module_param_array(DupCap_A, charp, NULL, 0);
-module_param_array(DupCap_B, charp, NULL, 0);
-module_param_array(FlowCtrl_A, charp, NULL, 0);
-module_param_array(FlowCtrl_B, charp, NULL, 0);
-module_param_array(Role_A, charp, NULL, 0);
-module_param_array(Role_B, charp, NULL, 0);
-module_param_array(ConType, charp, NULL, 0);
-module_param_array(PrefPort, charp, NULL, 0);
-module_param_array(RlmtMode, charp, NULL, 0);
-/* used for interrupt moderation */
-module_param_array(IntsPerSec, int, NULL, 0);
-module_param_array(Moderation, charp, NULL, 0);
-module_param_array(Stats, charp, NULL, 0);
-module_param_array(ModerationMask, charp, NULL, 0);
-module_param_array(AutoSizing, charp, NULL, 0);
-
-/*****************************************************************************
- *
- *     SkGeBoardInit - do level 0 and 1 initialization
- *
- * Description:
- *     This function prepares the board hardware for running. The desriptor
- *     ring is set up, the IRQ is allocated and the configuration settings
- *     are examined.
- *
- * Returns:
- *     0, if everything is ok
- *     !=0, on error
- */
-static int __devinit SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC)
-{
-short  i;
-unsigned long Flags;
-char   *DescrString = "sk98lin: Driver for Linux"; /* this is given to PNMI */
-char   *VerStr = VER_STRING;
-int    Ret;                    /* return code of request_irq */
-SK_BOOL        DualNet;
-
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-               ("IoBase: %08lX\n", (unsigned long)pAC->IoBase));
-       for (i=0; i<SK_MAX_MACS; i++) {
-               pAC->TxPort[i][0].HwAddr = pAC->IoBase + TxQueueAddr[i][0];
-               pAC->TxPort[i][0].PortIndex = i;
-               pAC->RxPort[i].HwAddr = pAC->IoBase + RxQueueAddr[i];
-               pAC->RxPort[i].PortIndex = i;
-       }
-
-       /* Initialize the mutexes */
-       for (i=0; i<SK_MAX_MACS; i++) {
-               spin_lock_init(&pAC->TxPort[i][0].TxDesRingLock);
-               spin_lock_init(&pAC->RxPort[i].RxDesRingLock);
-       }
-       spin_lock_init(&pAC->SlowPathLock);
-
-       /* setup phy_id blink timer */
-       pAC->BlinkTimer.function = SkGeBlinkTimer;
-       pAC->BlinkTimer.data = (unsigned long) dev;
-       init_timer(&pAC->BlinkTimer);
-
-       /* level 0 init common modules here */
-       
-       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-       /* Does a RESET on board ...*/
-       if (SkGeInit(pAC, pAC->IoBase, SK_INIT_DATA) != 0) {
-               printk("HWInit (0) failed.\n");
-               spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-               return -EIO;
-       }
-       SkI2cInit(  pAC, pAC->IoBase, SK_INIT_DATA);
-       SkEventInit(pAC, pAC->IoBase, SK_INIT_DATA);
-       SkPnmiInit( pAC, pAC->IoBase, SK_INIT_DATA);
-       SkAddrInit( pAC, pAC->IoBase, SK_INIT_DATA);
-       SkRlmtInit( pAC, pAC->IoBase, SK_INIT_DATA);
-       SkTimerInit(pAC, pAC->IoBase, SK_INIT_DATA);
-
-       pAC->BoardLevel = SK_INIT_DATA;
-       pAC->RxBufSize  = ETH_BUF_SIZE;
-
-       SK_PNMI_SET_DRIVER_DESCR(pAC, DescrString);
-       SK_PNMI_SET_DRIVER_VER(pAC, VerStr);
-
-       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-
-       /* level 1 init common modules here (HW init) */
-       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-       if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) {
-               printk("sk98lin: HWInit (1) failed.\n");
-               spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-               return -EIO;
-       }
-       SkI2cInit(  pAC, pAC->IoBase, SK_INIT_IO);
-       SkEventInit(pAC, pAC->IoBase, SK_INIT_IO);
-       SkPnmiInit( pAC, pAC->IoBase, SK_INIT_IO);
-       SkAddrInit( pAC, pAC->IoBase, SK_INIT_IO);
-       SkRlmtInit( pAC, pAC->IoBase, SK_INIT_IO);
-       SkTimerInit(pAC, pAC->IoBase, SK_INIT_IO);
-
-       /* Set chipset type support */
-       pAC->ChipsetType = 0;
-       if ((pAC->GIni.GIChipId == CHIP_ID_YUKON) ||
-               (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE)) {
-               pAC->ChipsetType = 1;
-       }
-
-       GetConfiguration(pAC);
-       if (pAC->RlmtNets == 2) {
-               pAC->GIni.GIPortUsage = SK_MUL_LINK;
-       }
-
-       pAC->BoardLevel = SK_INIT_IO;
-       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-
-       if (pAC->GIni.GIMacsFound == 2) {
-                Ret = request_irq(dev->irq, SkGeIsr, IRQF_SHARED, "sk98lin", dev);
-       } else if (pAC->GIni.GIMacsFound == 1) {
-               Ret = request_irq(dev->irq, SkGeIsrOnePort, IRQF_SHARED,
-                       "sk98lin", dev);
-       } else {
-               printk(KERN_WARNING "sk98lin: Illegal number of ports: %d\n",
-                      pAC->GIni.GIMacsFound);
-               return -EIO;
-       }
-
-       if (Ret) {
-               printk(KERN_WARNING "sk98lin: Requested IRQ %d is busy.\n",
-                      dev->irq);
-               return Ret;
-       }
-       pAC->AllocFlag |= SK_ALLOC_IRQ;
-
-       /* Alloc memory for this board (Mem for RxD/TxD) : */
-       if(!BoardAllocMem(pAC)) {
-               printk("No memory for descriptor rings.\n");
-               return -ENOMEM;
-       }
-
-       BoardInitMem(pAC);
-       /* tschilling: New common function with minimum size check. */
-       DualNet = SK_FALSE;
-       if (pAC->RlmtNets == 2) {
-               DualNet = SK_TRUE;
-       }
-       
-       if (SkGeInitAssignRamToQueues(
-               pAC,
-               pAC->ActivePort,
-               DualNet)) {
-               BoardFreeMem(pAC);
-               printk("sk98lin: SkGeInitAssignRamToQueues failed.\n");
-               return -EIO;
-       }
-
-       return (0);
-} /* SkGeBoardInit */
-
-
-/*****************************************************************************
- *
- *     BoardAllocMem - allocate the memory for the descriptor rings
- *
- * Description:
- *     This function allocates the memory for all descriptor rings.
- *     Each ring is aligned for the desriptor alignment and no ring
- *     has a 4 GByte boundary in it (because the upper 32 bit must
- *     be constant for all descriptiors in one rings).
- *
- * Returns:
- *     SK_TRUE, if all memory could be allocated
- *     SK_FALSE, if not
- */
-static __devinit SK_BOOL BoardAllocMem(SK_AC   *pAC)
-{
-caddr_t                pDescrMem;      /* pointer to descriptor memory area */
-size_t         AllocLength;    /* length of complete descriptor area */
-int            i;              /* loop counter */
-unsigned long  BusAddr;
-
-       
-       /* rings plus one for alignment (do not cross 4 GB boundary) */
-       /* RX_RING_SIZE is assumed bigger than TX_RING_SIZE */
-#if (BITS_PER_LONG == 32)
-       AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + 8;
-#else
-       AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound
-               + RX_RING_SIZE + 8;
-#endif
-
-       pDescrMem = pci_alloc_consistent(pAC->PciDev, AllocLength,
-                                        &pAC->pDescrMemDMA);
-
-       if (pDescrMem == NULL) {
-               return (SK_FALSE);
-       }
-       pAC->pDescrMem = pDescrMem;
-       BusAddr = (unsigned long) pAC->pDescrMemDMA;
-
-       /* Descriptors need 8 byte alignment, and this is ensured
-        * by pci_alloc_consistent.
-        */
-       for (i=0; i<pAC->GIni.GIMacsFound; i++) {
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
-                       ("TX%d/A: pDescrMem: %lX,   PhysDescrMem: %lX\n",
-                       i, (unsigned long) pDescrMem,
-                       BusAddr));
-               pAC->TxPort[i][0].pTxDescrRing = pDescrMem;
-               pAC->TxPort[i][0].VTxDescrRing = BusAddr;
-               pDescrMem += TX_RING_SIZE;
-               BusAddr += TX_RING_SIZE;
-       
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
-                       ("RX%d: pDescrMem: %lX,   PhysDescrMem: %lX\n",
-                       i, (unsigned long) pDescrMem,
-                       (unsigned long)BusAddr));
-               pAC->RxPort[i].pRxDescrRing = pDescrMem;
-               pAC->RxPort[i].VRxDescrRing = BusAddr;
-               pDescrMem += RX_RING_SIZE;
-               BusAddr += RX_RING_SIZE;
-       } /* for */
-       
-       return (SK_TRUE);
-} /* BoardAllocMem */
-
-
-/****************************************************************************
- *
- *     BoardFreeMem - reverse of BoardAllocMem
- *
- * Description:
- *     Free all memory allocated in BoardAllocMem: adapter context,
- *     descriptor rings, locks.
- *
- * Returns:    N/A
- */
-static void BoardFreeMem(
-SK_AC          *pAC)
-{
-size_t         AllocLength;    /* length of complete descriptor area */
-
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-               ("BoardFreeMem\n"));
-#if (BITS_PER_LONG == 32)
-       AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + 8;
-#else
-       AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound
-               + RX_RING_SIZE + 8;
-#endif
-
-       pci_free_consistent(pAC->PciDev, AllocLength,
-                           pAC->pDescrMem, pAC->pDescrMemDMA);
-       pAC->pDescrMem = NULL;
-} /* BoardFreeMem */
-
-
-/*****************************************************************************
- *
- *     BoardInitMem - initiate the descriptor rings
- *
- * Description:
- *     This function sets the descriptor rings up in memory.
- *     The adapter is initialized with the descriptor start addresses.
- *
- * Returns:    N/A
- */
-static __devinit void BoardInitMem(SK_AC *pAC)
-{
-int    i;              /* loop counter */
-int    RxDescrSize;    /* the size of a rx descriptor rounded up to alignment*/
-int    TxDescrSize;    /* the size of a tx descriptor rounded up to alignment*/
-
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-               ("BoardInitMem\n"));
-
-       RxDescrSize = (((sizeof(RXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN;
-       pAC->RxDescrPerRing = RX_RING_SIZE / RxDescrSize;
-       TxDescrSize = (((sizeof(TXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN;
-       pAC->TxDescrPerRing = TX_RING_SIZE / RxDescrSize;
-       
-       for (i=0; i<pAC->GIni.GIMacsFound; i++) {
-               SetupRing(
-                       pAC,
-                       pAC->TxPort[i][0].pTxDescrRing,
-                       pAC->TxPort[i][0].VTxDescrRing,
-                       (RXD**)&pAC->TxPort[i][0].pTxdRingHead,
-                       (RXD**)&pAC->TxPort[i][0].pTxdRingTail,
-                       (RXD**)&pAC->TxPort[i][0].pTxdRingPrev,
-                       &pAC->TxPort[i][0].TxdRingFree,
-                       SK_TRUE);
-               SetupRing(
-                       pAC,
-                       pAC->RxPort[i].pRxDescrRing,
-                       pAC->RxPort[i].VRxDescrRing,
-                       &pAC->RxPort[i].pRxdRingHead,
-                       &pAC->RxPort[i].pRxdRingTail,
-                       &pAC->RxPort[i].pRxdRingPrev,
-                       &pAC->RxPort[i].RxdRingFree,
-                       SK_FALSE);
-       }
-} /* BoardInitMem */
-
-
-/*****************************************************************************
- *
- *     SetupRing - create one descriptor ring
- *
- * Description:
- *     This function creates one descriptor ring in the given memory area.
- *     The head, tail and number of free descriptors in the ring are set.
- *
- * Returns:
- *     none
- */
-static void SetupRing(
-SK_AC          *pAC,
-void           *pMemArea,      /* a pointer to the memory area for the ring */
-uintptr_t      VMemArea,       /* the virtual bus address of the memory area */
-RXD            **ppRingHead,   /* address where the head should be written */
-RXD            **ppRingTail,   /* address where the tail should be written */
-RXD            **ppRingPrev,   /* address where the tail should be written */
-int            *pRingFree,     /* address where the # of free descr. goes */
-SK_BOOL                IsTx)           /* flag: is this a tx ring */
-{
-int    i;              /* loop counter */
-int    DescrSize;      /* the size of a descriptor rounded up to alignment*/
-int    DescrNum;       /* number of descriptors per ring */
-RXD    *pDescr;        /* pointer to a descriptor (receive or transmit) */
-RXD    *pNextDescr;    /* pointer to the next descriptor */
-RXD    *pPrevDescr;    /* pointer to the previous descriptor */
-uintptr_t VNextDescr;  /* the virtual bus address of the next descriptor */
-
-       if (IsTx == SK_TRUE) {
-               DescrSize = (((sizeof(TXD) - 1) / DESCR_ALIGN) + 1) *
-                       DESCR_ALIGN;
-               DescrNum = TX_RING_SIZE / DescrSize;
-       } else {
-               DescrSize = (((sizeof(RXD) - 1) / DESCR_ALIGN) + 1) *
-                       DESCR_ALIGN;
-               DescrNum = RX_RING_SIZE / DescrSize;
-       }
-       
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
-               ("Descriptor size: %d   Descriptor Number: %d\n",
-               DescrSize,DescrNum));
-       
-       pDescr = (RXD*) pMemArea;
-       pPrevDescr = NULL;
-       pNextDescr = (RXD*) (((char*)pDescr) + DescrSize);
-       VNextDescr = VMemArea + DescrSize;
-       for(i=0; i<DescrNum; i++) {
-               /* set the pointers right */
-               pDescr->VNextRxd = VNextDescr & 0xffffffffULL;
-               pDescr->pNextRxd = pNextDescr;
-               if (!IsTx) pDescr->TcpSumStarts = ETH_HLEN << 16 | ETH_HLEN;
-
-               /* advance one step */
-               pPrevDescr = pDescr;
-               pDescr = pNextDescr;
-               pNextDescr = (RXD*) (((char*)pDescr) + DescrSize);
-               VNextDescr += DescrSize;
-       }
-       pPrevDescr->pNextRxd = (RXD*) pMemArea;
-       pPrevDescr->VNextRxd = VMemArea;
-       pDescr = (RXD*) pMemArea;
-       *ppRingHead = (RXD*) pMemArea;
-       *ppRingTail = *ppRingHead;
-       *ppRingPrev = pPrevDescr;
-       *pRingFree = DescrNum;
-} /* SetupRing */
-
-
-/*****************************************************************************
- *
- *     PortReInitBmu - re-initiate the descriptor rings for one port
- *
- * Description:
- *     This function reinitializes the descriptor rings of one port
- *     in memory. The port must be stopped before.
- *     The HW is initialized with the descriptor start addresses.
- *
- * Returns:
- *     none
- */
-static void PortReInitBmu(
-SK_AC  *pAC,           /* pointer to adapter context */
-int    PortIndex)      /* index of the port for which to re-init */
-{
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-               ("PortReInitBmu "));
-
-       /* set address of first descriptor of ring in BMU */
-       SK_OUT32(pAC->IoBase, TxQueueAddr[PortIndex][TX_PRIO_LOW]+ Q_DA_L,
-               (uint32_t)(((caddr_t)
-               (pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxdRingHead) -
-               pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxDescrRing +
-               pAC->TxPort[PortIndex][TX_PRIO_LOW].VTxDescrRing) &
-               0xFFFFFFFF));
-       SK_OUT32(pAC->IoBase, TxQueueAddr[PortIndex][TX_PRIO_LOW]+ Q_DA_H,
-               (uint32_t)(((caddr_t)
-               (pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxdRingHead) -
-               pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxDescrRing +
-               pAC->TxPort[PortIndex][TX_PRIO_LOW].VTxDescrRing) >> 32));
-       SK_OUT32(pAC->IoBase, RxQueueAddr[PortIndex]+Q_DA_L,
-               (uint32_t)(((caddr_t)(pAC->RxPort[PortIndex].pRxdRingHead) -
-               pAC->RxPort[PortIndex].pRxDescrRing +
-               pAC->RxPort[PortIndex].VRxDescrRing) & 0xFFFFFFFF));
-       SK_OUT32(pAC->IoBase, RxQueueAddr[PortIndex]+Q_DA_H,
-               (uint32_t)(((caddr_t)(pAC->RxPort[PortIndex].pRxdRingHead) -
-               pAC->RxPort[PortIndex].pRxDescrRing +
-               pAC->RxPort[PortIndex].VRxDescrRing) >> 32));
-} /* PortReInitBmu */
-
-
-/****************************************************************************
- *
- *     SkGeIsr - handle adapter interrupts
- *
- * Description:
- *     The interrupt routine is called when the network adapter
- *     generates an interrupt. It may also be called if another device
- *     shares this interrupt vector with the driver.
- *
- * Returns: N/A
- *
- */
-static SkIsrRetVar SkGeIsr(int irq, void *dev_id)
-{
-struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id;
-DEV_NET                *pNet;
-SK_AC          *pAC;
-SK_U32         IntSrc;         /* interrupts source register contents */       
-
-       pNet = netdev_priv(dev);
-       pAC = pNet->pAC;
-       
-       /*
-        * Check and process if its our interrupt
-        */
-       SK_IN32(pAC->IoBase, B0_SP_ISRC, &IntSrc);
-       if (IntSrc == 0) {
-               return SkIsrRetNone;
-       }
-
-       while (((IntSrc & IRQ_MASK) & ~SPECIAL_IRQS) != 0) {
-#if 0 /* software irq currently not used */
-               if (IntSrc & IS_IRQ_SW) {
-                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                               SK_DBGCAT_DRV_INT_SRC,
-                               ("Software IRQ\n"));
-               }
-#endif
-               if (IntSrc & IS_R1_F) {
-                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                               SK_DBGCAT_DRV_INT_SRC,
-                               ("EOF RX1 IRQ\n"));
-                       ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
-                       SK_PNMI_CNT_RX_INTR(pAC, 0);
-               }
-               if (IntSrc & IS_R2_F) {
-                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                               SK_DBGCAT_DRV_INT_SRC,
-                               ("EOF RX2 IRQ\n"));
-                       ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE);
-                       SK_PNMI_CNT_RX_INTR(pAC, 1);
-               }
-#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
-               if (IntSrc & IS_XA1_F) {
-                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                               SK_DBGCAT_DRV_INT_SRC,
-                               ("EOF AS TX1 IRQ\n"));
-                       SK_PNMI_CNT_TX_INTR(pAC, 0);
-                       spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
-                       FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]);
-                       spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
-               }
-               if (IntSrc & IS_XA2_F) {
-                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                               SK_DBGCAT_DRV_INT_SRC,
-                               ("EOF AS TX2 IRQ\n"));
-                       SK_PNMI_CNT_TX_INTR(pAC, 1);
-                       spin_lock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock);
-                       FreeTxDescriptors(pAC, &pAC->TxPort[1][TX_PRIO_LOW]);
-                       spin_unlock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock);
-               }
-#if 0 /* only if sync. queues used */
-               if (IntSrc & IS_XS1_F) {
-                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                               SK_DBGCAT_DRV_INT_SRC,
-                               ("EOF SY TX1 IRQ\n"));
-                       SK_PNMI_CNT_TX_INTR(pAC, 1);
-                       spin_lock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
-                       FreeTxDescriptors(pAC, 0, TX_PRIO_HIGH);
-                       spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
-                       ClearTxIrq(pAC, 0, TX_PRIO_HIGH);
-               }
-               if (IntSrc & IS_XS2_F) {
-                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                               SK_DBGCAT_DRV_INT_SRC,
-                               ("EOF SY TX2 IRQ\n"));
-                       SK_PNMI_CNT_TX_INTR(pAC, 1);
-                       spin_lock(&pAC->TxPort[1][TX_PRIO_HIGH].TxDesRingLock);
-                       FreeTxDescriptors(pAC, 1, TX_PRIO_HIGH);
-                       spin_unlock(&pAC->TxPort[1][TX_PRIO_HIGH].TxDesRingLock);
-                       ClearTxIrq(pAC, 1, TX_PRIO_HIGH);
-               }
-#endif
-#endif
-
-               /* do all IO at once */
-               if (IntSrc & IS_R1_F)
-                       ClearAndStartRx(pAC, 0);
-               if (IntSrc & IS_R2_F)
-                       ClearAndStartRx(pAC, 1);
-#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
-               if (IntSrc & IS_XA1_F)
-                       ClearTxIrq(pAC, 0, TX_PRIO_LOW);
-               if (IntSrc & IS_XA2_F)
-                       ClearTxIrq(pAC, 1, TX_PRIO_LOW);
-#endif
-               SK_IN32(pAC->IoBase, B0_ISRC, &IntSrc);
-       } /* while (IntSrc & IRQ_MASK != 0) */
-
-       IntSrc &= pAC->GIni.GIValIrqMask;
-       if ((IntSrc & SPECIAL_IRQS) || pAC->CheckQueue) {
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
-                       ("SPECIAL IRQ DP-Cards => %x\n", IntSrc));
-               pAC->CheckQueue = SK_FALSE;
-               spin_lock(&pAC->SlowPathLock);
-               if (IntSrc & SPECIAL_IRQS)
-                       SkGeSirqIsr(pAC, pAC->IoBase, IntSrc);
-
-               SkEventDispatcher(pAC, pAC->IoBase);
-               spin_unlock(&pAC->SlowPathLock);
-       }
-       /*
-        * do it all again is case we cleared an interrupt that
-        * came in after handling the ring (OUTs may be delayed
-        * in hardware buffers, but are through after IN)
-        *
-        * rroesler: has been commented out and shifted to
-        *           SkGeDrvEvent(), because it is timer
-        *           guarded now
-        *
-       ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
-       ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE);
-        */
-
-       if (pAC->CheckQueue) {
-               pAC->CheckQueue = SK_FALSE;
-               spin_lock(&pAC->SlowPathLock);
-               SkEventDispatcher(pAC, pAC->IoBase);
-               spin_unlock(&pAC->SlowPathLock);
-       }
-
-       /* IRQ is processed - Enable IRQs again*/
-       SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
-
-               return SkIsrRetHandled;
-} /* SkGeIsr */
-
-
-/****************************************************************************
- *
- *     SkGeIsrOnePort - handle adapter interrupts for single port adapter
- *
- * Description:
- *     The interrupt routine is called when the network adapter
- *     generates an interrupt. It may also be called if another device
- *     shares this interrupt vector with the driver.
- *     This is the same as above, but handles only one port.
- *
- * Returns: N/A
- *
- */
-static SkIsrRetVar SkGeIsrOnePort(int irq, void *dev_id)
-{
-struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id;
-DEV_NET                *pNet;
-SK_AC          *pAC;
-SK_U32         IntSrc;         /* interrupts source register contents */       
-
-       pNet = netdev_priv(dev);
-       pAC = pNet->pAC;
-       
-       /*
-        * Check and process if its our interrupt
-        */
-       SK_IN32(pAC->IoBase, B0_SP_ISRC, &IntSrc);
-       if (IntSrc == 0) {
-               return SkIsrRetNone;
-       }
-       
-       while (((IntSrc & IRQ_MASK) & ~SPECIAL_IRQS) != 0) {
-#if 0 /* software irq currently not used */
-               if (IntSrc & IS_IRQ_SW) {
-                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                               SK_DBGCAT_DRV_INT_SRC,
-                               ("Software IRQ\n"));
-               }
-#endif
-               if (IntSrc & IS_R1_F) {
-                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                               SK_DBGCAT_DRV_INT_SRC,
-                               ("EOF RX1 IRQ\n"));
-                       ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
-                       SK_PNMI_CNT_RX_INTR(pAC, 0);
-               }
-#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
-               if (IntSrc & IS_XA1_F) {
-                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                               SK_DBGCAT_DRV_INT_SRC,
-                               ("EOF AS TX1 IRQ\n"));
-                       SK_PNMI_CNT_TX_INTR(pAC, 0);
-                       spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
-                       FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]);
-                       spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
-               }
-#if 0 /* only if sync. queues used */
-               if (IntSrc & IS_XS1_F) {
-                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                               SK_DBGCAT_DRV_INT_SRC,
-                               ("EOF SY TX1 IRQ\n"));
-                       SK_PNMI_CNT_TX_INTR(pAC, 0);
-                       spin_lock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
-                       FreeTxDescriptors(pAC, 0, TX_PRIO_HIGH);
-                       spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
-                       ClearTxIrq(pAC, 0, TX_PRIO_HIGH);
-               }
-#endif
-#endif
-
-               /* do all IO at once */
-               if (IntSrc & IS_R1_F)
-                       ClearAndStartRx(pAC, 0);
-#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
-               if (IntSrc & IS_XA1_F)
-                       ClearTxIrq(pAC, 0, TX_PRIO_LOW);
-#endif
-               SK_IN32(pAC->IoBase, B0_ISRC, &IntSrc);
-       } /* while (IntSrc & IRQ_MASK != 0) */
-       
-       IntSrc &= pAC->GIni.GIValIrqMask;
-       if ((IntSrc & SPECIAL_IRQS) || pAC->CheckQueue) {
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
-                       ("SPECIAL IRQ SP-Cards => %x\n", IntSrc));
-               pAC->CheckQueue = SK_FALSE;
-               spin_lock(&pAC->SlowPathLock);
-               if (IntSrc & SPECIAL_IRQS)
-                       SkGeSirqIsr(pAC, pAC->IoBase, IntSrc);
-
-               SkEventDispatcher(pAC, pAC->IoBase);
-               spin_unlock(&pAC->SlowPathLock);
-       }
-       /*
-        * do it all again is case we cleared an interrupt that
-        * came in after handling the ring (OUTs may be delayed
-        * in hardware buffers, but are through after IN)
-        *
-        * rroesler: has been commented out and shifted to
-        *           SkGeDrvEvent(), because it is timer
-        *           guarded now
-        *
-       ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
-        */
-
-       /* IRQ is processed - Enable IRQs again*/
-       SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
-
-               return SkIsrRetHandled;
-} /* SkGeIsrOnePort */
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-/****************************************************************************
- *
- *     SkGePollController - polling receive, for netconsole
- *
- * Description:
- *     Polling receive - used by netconsole and other diagnostic tools
- *     to allow network i/o with interrupts disabled.
- *
- * Returns: N/A
- */
-static void SkGePollController(struct net_device *dev)
-{
-       disable_irq(dev->irq);
-       SkGeIsr(dev->irq, dev);
-       enable_irq(dev->irq);
-}
-#endif
-
-/****************************************************************************
- *
- *     SkGeOpen - handle start of initialized adapter
- *
- * Description:
- *     This function starts the initialized adapter.
- *     The board level variable is set and the adapter is
- *     brought to full functionality.
- *     The device flags are set for operation.
- *     Do all necessary level 2 initialization, enable interrupts and
- *     give start command to RLMT.
- *
- * Returns:
- *     0 on success
- *     != 0 on error
- */
-static int SkGeOpen(
-struct SK_NET_DEVICE   *dev)
-{
-       DEV_NET                 *pNet;
-       SK_AC                   *pAC;
-       unsigned long   Flags;          /* for spin lock */
-       int                             i;
-       SK_EVPARA               EvPara;         /* an event parameter union */
-
-       pNet = netdev_priv(dev);
-       pAC = pNet->pAC;
-       
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-               ("SkGeOpen: pAC=0x%lX:\n", (unsigned long)pAC));
-
-#ifdef SK_DIAG_SUPPORT
-       if (pAC->DiagModeActive == DIAG_ACTIVE) {
-               if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
-                       return (-1);   /* still in use by diag; deny actions */
-               } 
-       }
-#endif
-
-       /* Set blink mode */
-       if ((pAC->PciDev->vendor == 0x1186) || (pAC->PciDev->vendor == 0x11ab ))
-               pAC->GIni.GILedBlinkCtrl = OEM_CONFIG_VALUE;
-
-       if (pAC->BoardLevel == SK_INIT_DATA) {
-               /* level 1 init common modules here */
-               if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) {
-                       printk("%s: HWInit (1) failed.\n", pAC->dev[pNet->PortNr]->name);
-                       return (-1);
-               }
-               SkI2cInit       (pAC, pAC->IoBase, SK_INIT_IO);
-               SkEventInit     (pAC, pAC->IoBase, SK_INIT_IO);
-               SkPnmiInit      (pAC, pAC->IoBase, SK_INIT_IO);
-               SkAddrInit      (pAC, pAC->IoBase, SK_INIT_IO);
-               SkRlmtInit      (pAC, pAC->IoBase, SK_INIT_IO);
-               SkTimerInit     (pAC, pAC->IoBase, SK_INIT_IO);
-               pAC->BoardLevel = SK_INIT_IO;
-       }
-
-       if (pAC->BoardLevel != SK_INIT_RUN) {
-               /* tschilling: Level 2 init modules here, check return value. */
-               if (SkGeInit(pAC, pAC->IoBase, SK_INIT_RUN) != 0) {
-                       printk("%s: HWInit (2) failed.\n", pAC->dev[pNet->PortNr]->name);
-                       return (-1);
-               }
-               SkI2cInit       (pAC, pAC->IoBase, SK_INIT_RUN);
-               SkEventInit     (pAC, pAC->IoBase, SK_INIT_RUN);
-               SkPnmiInit      (pAC, pAC->IoBase, SK_INIT_RUN);
-               SkAddrInit      (pAC, pAC->IoBase, SK_INIT_RUN);
-               SkRlmtInit      (pAC, pAC->IoBase, SK_INIT_RUN);
-               SkTimerInit     (pAC, pAC->IoBase, SK_INIT_RUN);
-               pAC->BoardLevel = SK_INIT_RUN;
-       }
-
-       for (i=0; i<pAC->GIni.GIMacsFound; i++) {
-               /* Enable transmit descriptor polling. */
-               SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE);
-               FillRxRing(pAC, &pAC->RxPort[i]);
-       }
-       SkGeYellowLED(pAC, pAC->IoBase, 1);
-
-       StartDrvCleanupTimer(pAC);
-       SkDimEnableModerationIfNeeded(pAC);     
-       SkDimDisplayModerationSettings(pAC);
-
-       pAC->GIni.GIValIrqMask &= IRQ_MASK;
-
-       /* enable Interrupts */
-       SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
-       SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK);
-
-       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-
-       if ((pAC->RlmtMode != 0) && (pAC->MaxPorts == 0)) {
-               EvPara.Para32[0] = pAC->RlmtNets;
-               EvPara.Para32[1] = -1;
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS,
-                       EvPara);
-               EvPara.Para32[0] = pAC->RlmtMode;
-               EvPara.Para32[1] = 0;
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_MODE_CHANGE,
-                       EvPara);
-       }
-
-       EvPara.Para32[0] = pNet->NetNr;
-       EvPara.Para32[1] = -1;
-       SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
-       SkEventDispatcher(pAC, pAC->IoBase);
-       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-
-       pAC->MaxPorts++;
-
-
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-               ("SkGeOpen suceeded\n"));
-
-       return (0);
-} /* SkGeOpen */
-
-
-/****************************************************************************
- *
- *     SkGeClose - Stop initialized adapter
- *
- * Description:
- *     Close initialized adapter.
- *
- * Returns:
- *     0 - on success
- *     error code - on error
- */
-static int SkGeClose(
-struct SK_NET_DEVICE   *dev)
-{
-       DEV_NET         *pNet;
-       DEV_NET         *newPtrNet;
-       SK_AC           *pAC;
-
-       unsigned long   Flags;          /* for spin lock */
-       int             i;
-       int             PortIdx;
-       SK_EVPARA       EvPara;
-
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-               ("SkGeClose: pAC=0x%lX ", (unsigned long)pAC));
-
-       pNet = netdev_priv(dev);
-       pAC = pNet->pAC;
-
-#ifdef SK_DIAG_SUPPORT
-       if (pAC->DiagModeActive == DIAG_ACTIVE) {
-               if (pAC->DiagFlowCtrl == SK_FALSE) {
-                       /* 
-                       ** notify that the interface which has been closed
-                       ** by operator interaction must not be started up 
-                       ** again when the DIAG has finished. 
-                       */
-                       newPtrNet = netdev_priv(pAC->dev[0]);
-                       if (newPtrNet == pNet) {
-                               pAC->WasIfUp[0] = SK_FALSE;
-                       } else {
-                               pAC->WasIfUp[1] = SK_FALSE;
-                       }
-                       return 0; /* return to system everything is fine... */
-               } else {
-                       pAC->DiagFlowCtrl = SK_FALSE;
-               }
-       }
-#endif
-
-       netif_stop_queue(dev);
-
-       if (pAC->RlmtNets == 1)
-               PortIdx = pAC->ActivePort;
-       else
-               PortIdx = pNet->NetNr;
-
-        StopDrvCleanupTimer(pAC);
-
-       /*
-        * Clear multicast table, promiscuous mode ....
-        */
-       SkAddrMcClear(pAC, pAC->IoBase, PortIdx, 0);
-       SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
-               SK_PROM_MODE_NONE);
-
-       if (pAC->MaxPorts == 1) {
-               spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-               /* disable interrupts */
-               SK_OUT32(pAC->IoBase, B0_IMSK, 0);
-               EvPara.Para32[0] = pNet->NetNr;
-               EvPara.Para32[1] = -1;
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
-               SkEventDispatcher(pAC, pAC->IoBase);
-               SK_OUT32(pAC->IoBase, B0_IMSK, 0);
-               /* stop the hardware */
-               SkGeDeInit(pAC, pAC->IoBase);
-               pAC->BoardLevel = SK_INIT_DATA;
-               spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-       } else {
-
-               spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-               EvPara.Para32[0] = pNet->NetNr;
-               EvPara.Para32[1] = -1;
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
-               SkPnmiEvent(pAC, pAC->IoBase, SK_PNMI_EVT_XMAC_RESET, EvPara);
-               SkEventDispatcher(pAC, pAC->IoBase);
-               spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-               
-               /* Stop port */
-               spin_lock_irqsave(&pAC->TxPort[pNet->PortNr]
-                       [TX_PRIO_LOW].TxDesRingLock, Flags);
-               SkGeStopPort(pAC, pAC->IoBase, pNet->PortNr,
-                       SK_STOP_ALL, SK_HARD_RST);
-               spin_unlock_irqrestore(&pAC->TxPort[pNet->PortNr]
-                       [TX_PRIO_LOW].TxDesRingLock, Flags);
-       }
-
-       if (pAC->RlmtNets == 1) {
-               /* clear all descriptor rings */
-               for (i=0; i<pAC->GIni.GIMacsFound; i++) {
-                       ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE);
-                       ClearRxRing(pAC, &pAC->RxPort[i]);
-                       ClearTxRing(pAC, &pAC->TxPort[i][TX_PRIO_LOW]);
-               }
-       } else {
-               /* clear port descriptor rings */
-               ReceiveIrq(pAC, &pAC->RxPort[pNet->PortNr], SK_TRUE);
-               ClearRxRing(pAC, &pAC->RxPort[pNet->PortNr]);
-               ClearTxRing(pAC, &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW]);
-       }
-
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-               ("SkGeClose: done "));
-
-       SK_MEMSET(&(pAC->PnmiBackup), 0, sizeof(SK_PNMI_STRUCT_DATA));
-       SK_MEMCPY(&(pAC->PnmiBackup), &(pAC->PnmiStruct), 
-                       sizeof(SK_PNMI_STRUCT_DATA));
-
-       pAC->MaxPorts--;
-
-       return (0);
-} /* SkGeClose */
-
-
-/*****************************************************************************
- *
- *     SkGeXmit - Linux frame transmit function
- *
- * Description:
- *     The system calls this function to send frames onto the wire.
- *     It puts the frame in the tx descriptor ring. If the ring is
- *     full then, the 'tbusy' flag is set.
- *
- * Returns:
- *     0, if everything is ok
- *     !=0, on error
- * WARNING: returning 1 in 'tbusy' case caused system crashes (double
- *     allocated skb's) !!!
- */
-static int SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev)
-{
-DEV_NET                *pNet;
-SK_AC          *pAC;
-int                    Rc;     /* return code of XmitFrame */
-
-       pNet = netdev_priv(dev);
-       pAC = pNet->pAC;
-
-       if ((!skb_shinfo(skb)->nr_frags) ||
-               (pAC->GIni.GIChipId == CHIP_ID_GENESIS)) {
-               /* Don't activate scatter-gather and hardware checksum */
-
-               if (pAC->RlmtNets == 2)
-                       Rc = XmitFrame(
-                               pAC,
-                               &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW],
-                               skb);
-               else
-                       Rc = XmitFrame(
-                               pAC,
-                               &pAC->TxPort[pAC->ActivePort][TX_PRIO_LOW],
-                               skb);
-       } else {
-               /* scatter-gather and hardware TCP checksumming anabled*/
-               if (pAC->RlmtNets == 2)
-                       Rc = XmitFrameSG(
-                               pAC,
-                               &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW],
-                               skb);
-               else
-                       Rc = XmitFrameSG(
-                               pAC,
-                               &pAC->TxPort[pAC->ActivePort][TX_PRIO_LOW],
-                               skb);
-       }
-
-       /* Transmitter out of resources? */
-       if (Rc <= 0) {
-               netif_stop_queue(dev);
-       }
-
-       /* If not taken, give buffer ownership back to the
-        * queueing layer.
-        */
-       if (Rc < 0)
-               return (1);
-
-       dev->trans_start = jiffies;
-       return (0);
-} /* SkGeXmit */
-
-
-/*****************************************************************************
- *
- *     XmitFrame - fill one socket buffer into the transmit ring
- *
- * Description:
- *     This function puts a message into the transmit descriptor ring
- *     if there is a descriptors left.
- *     Linux skb's consist of only one continuous buffer.
- *     The first step locks the ring. It is held locked
- *     all time to avoid problems with SWITCH_../PORT_RESET.
- *     Then the descriptoris allocated.
- *     The second part is linking the buffer to the descriptor.
- *     At the very last, the Control field of the descriptor
- *     is made valid for the BMU and a start TX command is given
- *     if necessary.
- *
- * Returns:
- *     > 0 - on succes: the number of bytes in the message
- *     = 0 - on resource shortage: this frame sent or dropped, now
- *             the ring is full ( -> set tbusy)
- *     < 0 - on failure: other problems ( -> return failure to upper layers)
- */
-static int XmitFrame(
-SK_AC          *pAC,           /* pointer to adapter context           */
-TX_PORT                *pTxPort,       /* pointer to struct of port to send to */
-struct sk_buff *pMessage)      /* pointer to send-message              */
-{
-       TXD             *pTxd;          /* the rxd to fill */
-       TXD             *pOldTxd;
-       unsigned long    Flags;
-       SK_U64           PhysAddr;
-       int              BytesSend = pMessage->len;
-
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ("X"));
-
-       spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags);
-#ifndef USE_TX_COMPLETE
-       FreeTxDescriptors(pAC, pTxPort);
-#endif
-       if (pTxPort->TxdRingFree == 0) {
-               /* 
-               ** no enough free descriptors in ring at the moment.
-               ** Maybe free'ing some old one help?
-               */
-               FreeTxDescriptors(pAC, pTxPort);
-               if (pTxPort->TxdRingFree == 0) {
-                       spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
-                       SK_PNMI_CNT_NO_TX_BUF(pAC, pTxPort->PortIndex);
-                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                               SK_DBGCAT_DRV_TX_PROGRESS,
-                               ("XmitFrame failed\n"));
-                       /* 
-                       ** the desired message can not be sent
-                       ** Because tbusy seems to be set, the message 
-                       ** should not be freed here. It will be used 
-                       ** by the scheduler of the ethernet handler 
-                       */
-                       return (-1);
-               }
-       }
-
-       /*
-       ** If the passed socket buffer is of smaller MTU-size than 60,
-       ** copy everything into new buffer and fill all bytes between
-       ** the original packet end and the new packet end of 60 with 0x00.
-       ** This is to resolve faulty padding by the HW with 0xaa bytes.
-       */
-       if (BytesSend < C_LEN_ETHERNET_MINSIZE) {
-               if (skb_padto(pMessage, C_LEN_ETHERNET_MINSIZE)) {
-                       spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
-                       return 0;
-               }
-               pMessage->len = C_LEN_ETHERNET_MINSIZE;
-       }
-
-       /* 
-       ** advance head counter behind descriptor needed for this frame, 
-       ** so that needed descriptor is reserved from that on. The next
-       ** action will be to add the passed buffer to the TX-descriptor
-       */
-       pTxd = pTxPort->pTxdRingHead;
-       pTxPort->pTxdRingHead = pTxd->pNextTxd;
-       pTxPort->TxdRingFree--;
-
-#ifdef SK_DUMP_TX
-       DumpMsg(pMessage, "XmitFrame");
-#endif
-
-       /* 
-       ** First step is to map the data to be sent via the adapter onto
-       ** the DMA memory. Kernel 2.2 uses virt_to_bus(), but kernels 2.4
-       ** and 2.6 need to use pci_map_page() for that mapping.
-       */
-       PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
-                                       virt_to_page(pMessage->data),
-                                       ((unsigned long) pMessage->data & ~PAGE_MASK),
-                                       pMessage->len,
-                                       PCI_DMA_TODEVICE);
-       pTxd->VDataLow  = (SK_U32) (PhysAddr & 0xffffffff);
-       pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
-       pTxd->pMBuf     = pMessage;
-
-       if (pMessage->ip_summed == CHECKSUM_PARTIAL) {
-               u16 hdrlen = skb_transport_offset(pMessage);
-               u16 offset = hdrlen + pMessage->csum_offset;
-
-               if ((ipip_hdr(pMessage)->protocol == IPPROTO_UDP) &&
-                       (pAC->GIni.GIChipRev == 0) &&
-                       (pAC->GIni.GIChipId == CHIP_ID_YUKON)) {
-                       pTxd->TBControl = BMU_TCP_CHECK;
-               } else {
-                       pTxd->TBControl = BMU_UDP_CHECK;
-               }
-
-               pTxd->TcpSumOfs = 0;
-               pTxd->TcpSumSt  = hdrlen;
-               pTxd->TcpSumWr  = offset;
-
-               pTxd->TBControl |= BMU_OWN | BMU_STF | 
-                                  BMU_SW  | BMU_EOF |
-#ifdef USE_TX_COMPLETE
-                                  BMU_IRQ_EOF |
-#endif
-                                  pMessage->len;
-        } else {
-               pTxd->TBControl = BMU_OWN | BMU_STF | BMU_CHECK | 
-                                 BMU_SW  | BMU_EOF |
-#ifdef USE_TX_COMPLETE
-                                  BMU_IRQ_EOF |
-#endif
-                       pMessage->len;
-       }
-
-       /* 
-       ** If previous descriptor already done, give TX start cmd 
-       */
-       pOldTxd = xchg(&pTxPort->pTxdRingPrev, pTxd);
-       if ((pOldTxd->TBControl & BMU_OWN) == 0) {
-               SK_OUT8(pTxPort->HwAddr, Q_CSR, CSR_START);
-       }       
-
-       /* 
-       ** after releasing the lock, the skb may immediately be free'd 
-       */
-       spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
-       if (pTxPort->TxdRingFree != 0) {
-               return (BytesSend);
-       } else {
-               return (0);
-       }
-
-} /* XmitFrame */
-
-/*****************************************************************************
- *
- *     XmitFrameSG - fill one socket buffer into the transmit ring
- *                (use SG and TCP/UDP hardware checksumming)
- *
- * Description:
- *     This function puts a message into the transmit descriptor ring
- *     if there is a descriptors left.
- *
- * Returns:
- *     > 0 - on succes: the number of bytes in the message
- *     = 0 - on resource shortage: this frame sent or dropped, now
- *             the ring is full ( -> set tbusy)
- *     < 0 - on failure: other problems ( -> return failure to upper layers)
- */
-static int XmitFrameSG(
-SK_AC          *pAC,           /* pointer to adapter context           */
-TX_PORT                *pTxPort,       /* pointer to struct of port to send to */
-struct sk_buff *pMessage)      /* pointer to send-message              */
-{
-
-       TXD             *pTxd;
-       TXD             *pTxdFst;
-       TXD             *pTxdLst;
-       int              CurrFrag;
-       int              BytesSend;
-       skb_frag_t      *sk_frag;
-       SK_U64           PhysAddr;
-       unsigned long    Flags;
-       SK_U32           Control;
-
-       spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags);
-#ifndef USE_TX_COMPLETE
-       FreeTxDescriptors(pAC, pTxPort);
-#endif
-       if ((skb_shinfo(pMessage)->nr_frags +1) > pTxPort->TxdRingFree) {
-               FreeTxDescriptors(pAC, pTxPort);
-               if ((skb_shinfo(pMessage)->nr_frags + 1) > pTxPort->TxdRingFree) {
-                       spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
-                       SK_PNMI_CNT_NO_TX_BUF(pAC, pTxPort->PortIndex);
-                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                               SK_DBGCAT_DRV_TX_PROGRESS,
-                               ("XmitFrameSG failed - Ring full\n"));
-                               /* this message can not be sent now */
-                       return(-1);
-               }
-       }
-
-       pTxd      = pTxPort->pTxdRingHead;
-       pTxdFst   = pTxd;
-       pTxdLst   = pTxd;
-       BytesSend = 0;
-
-       /* 
-       ** Map the first fragment (header) into the DMA-space
-       */
-       PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
-                       virt_to_page(pMessage->data),
-                       ((unsigned long) pMessage->data & ~PAGE_MASK),
-                       skb_headlen(pMessage),
-                       PCI_DMA_TODEVICE);
-
-       pTxd->VDataLow  = (SK_U32) (PhysAddr & 0xffffffff);
-       pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
-
-       /* 
-       ** Does the HW need to evaluate checksum for TCP or UDP packets? 
-       */
-       if (pMessage->ip_summed == CHECKSUM_PARTIAL) {
-               u16 hdrlen = skb_transport_offset(pMessage);
-               u16 offset = hdrlen + pMessage->csum_offset;
-
-               Control = BMU_STFWD;
-
-               /* 
-               ** We have to use the opcode for tcp here,  because the
-               ** opcode for udp is not working in the hardware yet 
-               ** (Revision 2.0)
-               */
-               if ((ipip_hdr(pMessage)->protocol == IPPROTO_UDP) &&
-                       (pAC->GIni.GIChipRev == 0) &&
-                       (pAC->GIni.GIChipId == CHIP_ID_YUKON)) {
-                       Control |= BMU_TCP_CHECK;
-               } else {
-                       Control |= BMU_UDP_CHECK;
-               }
-
-               pTxd->TcpSumOfs = 0;
-               pTxd->TcpSumSt  = hdrlen;
-               pTxd->TcpSumWr  = offset;
-       } else
-               Control = BMU_CHECK | BMU_SW;
-
-       pTxd->TBControl = BMU_STF | Control | skb_headlen(pMessage);
-
-       pTxd = pTxd->pNextTxd;
-       pTxPort->TxdRingFree--;
-       BytesSend += skb_headlen(pMessage);
-
-       /* 
-       ** Browse over all SG fragments and map each of them into the DMA space
-       */
-       for (CurrFrag = 0; CurrFrag < skb_shinfo(pMessage)->nr_frags; CurrFrag++) {
-               sk_frag = &skb_shinfo(pMessage)->frags[CurrFrag];
-               /* 
-               ** we already have the proper value in entry
-               */
-               PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
-                                                sk_frag->page,
-                                                sk_frag->page_offset,
-                                                sk_frag->size,
-                                                PCI_DMA_TODEVICE);
-
-               pTxd->VDataLow  = (SK_U32) (PhysAddr & 0xffffffff);
-               pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
-               pTxd->pMBuf     = pMessage;
-               
-               pTxd->TBControl = Control | BMU_OWN | sk_frag->size;
-
-               /* 
-               ** Do we have the last fragment? 
-               */
-               if( (CurrFrag+1) == skb_shinfo(pMessage)->nr_frags )  {
-#ifdef USE_TX_COMPLETE
-                       pTxd->TBControl |= BMU_EOF | BMU_IRQ_EOF;
-#else
-                       pTxd->TBControl |= BMU_EOF;
-#endif
-                       pTxdFst->TBControl |= BMU_OWN | BMU_SW;
-               }
-               pTxdLst = pTxd;
-               pTxd    = pTxd->pNextTxd;
-               pTxPort->TxdRingFree--;
-               BytesSend += sk_frag->size;
-       }
-
-       /* 
-       ** If previous descriptor already done, give TX start cmd 
-       */
-       if ((pTxPort->pTxdRingPrev->TBControl & BMU_OWN) == 0) {
-               SK_OUT8(pTxPort->HwAddr, Q_CSR, CSR_START);
-       }
-
-       pTxPort->pTxdRingPrev = pTxdLst;
-       pTxPort->pTxdRingHead = pTxd;
-
-       spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
-
-       if (pTxPort->TxdRingFree > 0) {
-               return (BytesSend);
-       } else {
-               return (0);
-       }
-}
-
-/*****************************************************************************
- *
- *     FreeTxDescriptors - release descriptors from the descriptor ring
- *
- * Description:
- *     This function releases descriptors from a transmit ring if they
- *     have been sent by the BMU.
- *     If a descriptors is sent, it can be freed and the message can
- *     be freed, too.
- *     The SOFTWARE controllable bit is used to prevent running around a
- *     completely free ring for ever. If this bit is no set in the
- *     frame (by XmitFrame), this frame has never been sent or is
- *     already freed.
- *     The Tx descriptor ring lock must be held while calling this function !!!
- *
- * Returns:
- *     none
- */
-static void FreeTxDescriptors(
-SK_AC  *pAC,           /* pointer to the adapter context */
-TX_PORT        *pTxPort)       /* pointer to destination port structure */
-{
-TXD    *pTxd;          /* pointer to the checked descriptor */
-TXD    *pNewTail;      /* pointer to 'end' of the ring */
-SK_U32 Control;        /* TBControl field of descriptor */
-SK_U64 PhysAddr;       /* address of DMA mapping */
-
-       pNewTail = pTxPort->pTxdRingTail;
-       pTxd     = pNewTail;
-       /*
-       ** loop forever; exits if BMU_SW bit not set in start frame
-       ** or BMU_OWN bit set in any frame
-       */
-       while (1) {
-               Control = pTxd->TBControl;
-               if ((Control & BMU_SW) == 0) {
-                       /*
-                       ** software controllable bit is set in first
-                       ** fragment when given to BMU. Not set means that
-                       ** this fragment was never sent or is already
-                       ** freed ( -> ring completely free now).
-                       */
-                       pTxPort->pTxdRingTail = pTxd;
-                       netif_wake_queue(pAC->dev[pTxPort->PortIndex]);
-                       return;
-               }
-               if (Control & BMU_OWN) {
-                       pTxPort->pTxdRingTail = pTxd;
-                       if (pTxPort->TxdRingFree > 0) {
-                               netif_wake_queue(pAC->dev[pTxPort->PortIndex]);
-                       }
-                       return;
-               }
-               
-               /* 
-               ** release the DMA mapping, because until not unmapped
-               ** this buffer is considered being under control of the
-               ** adapter card!
-               */
-               PhysAddr = ((SK_U64) pTxd->VDataHigh) << (SK_U64) 32;
-               PhysAddr |= (SK_U64) pTxd->VDataLow;
-               pci_unmap_page(pAC->PciDev, PhysAddr,
-                                pTxd->pMBuf->len,
-                                PCI_DMA_TODEVICE);
-
-               if (Control & BMU_EOF)
-                       DEV_KFREE_SKB_ANY(pTxd->pMBuf); /* free message */
-
-               pTxPort->TxdRingFree++;
-               pTxd->TBControl &= ~BMU_SW;
-               pTxd = pTxd->pNextTxd; /* point behind fragment with EOF */
-       } /* while(forever) */
-} /* FreeTxDescriptors */
-
-/*****************************************************************************
- *
- *     FillRxRing - fill the receive ring with valid descriptors
- *
- * Description:
- *     This function fills the receive ring descriptors with data
- *     segments and makes them valid for the BMU.
- *     The active ring is filled completely, if possible.
- *     The non-active ring is filled only partial to save memory.
- *
- * Description of rx ring structure:
- *     head - points to the descriptor which will be used next by the BMU
- *     tail - points to the next descriptor to give to the BMU
- *     
- * Returns:    N/A
- */
-static void FillRxRing(
-SK_AC          *pAC,           /* pointer to the adapter context */
-RX_PORT                *pRxPort)       /* ptr to port struct for which the ring
-                                  should be filled */
-{
-unsigned long  Flags;
-
-       spin_lock_irqsave(&pRxPort->RxDesRingLock, Flags);
-       while (pRxPort->RxdRingFree > pRxPort->RxFillLimit) {
-               if(!FillRxDescriptor(pAC, pRxPort))
-                       break;
-       }
-       spin_unlock_irqrestore(&pRxPort->RxDesRingLock, Flags);
-} /* FillRxRing */
-
-
-/*****************************************************************************
- *
- *     FillRxDescriptor - fill one buffer into the receive ring
- *
- * Description:
- *     The function allocates a new receive buffer and
- *     puts it into the next descriptor.
- *
- * Returns:
- *     SK_TRUE - a buffer was added to the ring
- *     SK_FALSE - a buffer could not be added
- */
-static SK_BOOL FillRxDescriptor(
-SK_AC          *pAC,           /* pointer to the adapter context struct */
-RX_PORT                *pRxPort)       /* ptr to port struct of ring to fill */
-{
-struct sk_buff *pMsgBlock;     /* pointer to a new message block */
-RXD            *pRxd;          /* the rxd to fill */
-SK_U16         Length;         /* data fragment length */
-SK_U64         PhysAddr;       /* physical address of a rx buffer */
-
-       pMsgBlock = alloc_skb(pAC->RxBufSize, GFP_ATOMIC);
-       if (pMsgBlock == NULL) {
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                       SK_DBGCAT_DRV_ENTRY,
-                       ("%s: Allocation of rx buffer failed !\n",
-                       pAC->dev[pRxPort->PortIndex]->name));
-               SK_PNMI_CNT_NO_RX_BUF(pAC, pRxPort->PortIndex);
-               return(SK_FALSE);
-       }
-       skb_reserve(pMsgBlock, 2); /* to align IP frames */
-       /* skb allocated ok, so add buffer */
-       pRxd = pRxPort->pRxdRingTail;
-       pRxPort->pRxdRingTail = pRxd->pNextRxd;
-       pRxPort->RxdRingFree--;
-       Length = pAC->RxBufSize;
-       PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
-               virt_to_page(pMsgBlock->data),
-               ((unsigned long) pMsgBlock->data &
-               ~PAGE_MASK),
-               pAC->RxBufSize - 2,
-               PCI_DMA_FROMDEVICE);
-
-       pRxd->VDataLow  = (SK_U32) (PhysAddr & 0xffffffff);
-       pRxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
-       pRxd->pMBuf     = pMsgBlock;
-       pRxd->RBControl = BMU_OWN       | 
-                         BMU_STF       | 
-                         BMU_IRQ_EOF   | 
-                         BMU_TCP_CHECK | 
-                         Length;
-       return (SK_TRUE);
-
-} /* FillRxDescriptor */
-
-
-/*****************************************************************************
- *
- *     ReQueueRxBuffer - fill one buffer back into the receive ring
- *
- * Description:
- *     Fill a given buffer back into the rx ring. The buffer
- *     has been previously allocated and aligned, and its phys.
- *     address calculated, so this is no more necessary.
- *
- * Returns: N/A
- */
-static void ReQueueRxBuffer(
-SK_AC          *pAC,           /* pointer to the adapter context struct */
-RX_PORT                *pRxPort,       /* ptr to port struct of ring to fill */
-struct sk_buff *pMsg,          /* pointer to the buffer */
-SK_U32         PhysHigh,       /* phys address high dword */
-SK_U32         PhysLow)        /* phys address low dword */
-{
-RXD            *pRxd;          /* the rxd to fill */
-SK_U16         Length;         /* data fragment length */
-
-       pRxd = pRxPort->pRxdRingTail;
-       pRxPort->pRxdRingTail = pRxd->pNextRxd;
-       pRxPort->RxdRingFree--;
-       Length = pAC->RxBufSize;
-
-       pRxd->VDataLow  = PhysLow;
-       pRxd->VDataHigh = PhysHigh;
-       pRxd->pMBuf     = pMsg;
-       pRxd->RBControl = BMU_OWN       | 
-                         BMU_STF       |
-                         BMU_IRQ_EOF   | 
-                         BMU_TCP_CHECK | 
-                         Length;
-       return;
-} /* ReQueueRxBuffer */
-
-/*****************************************************************************
- *
- *     ReceiveIrq - handle a receive IRQ
- *
- * Description:
- *     This function is called when a receive IRQ is set.
- *     It walks the receive descriptor ring and sends up all
- *     frames that are complete.
- *
- * Returns:    N/A
- */
-static void ReceiveIrq(
-       SK_AC           *pAC,                   /* pointer to adapter context */
-       RX_PORT         *pRxPort,               /* pointer to receive port struct */
-       SK_BOOL         SlowPathLock)   /* indicates if SlowPathLock is needed */
-{
-RXD                            *pRxd;                  /* pointer to receive descriptors */
-SK_U32                 Control;                /* control field of descriptor */
-struct sk_buff *pMsg;                  /* pointer to message holding frame */
-struct sk_buff *pNewMsg;               /* pointer to a new message for copying frame */
-int                            FrameLength;    /* total length of received frame */
-SK_MBUF                        *pRlmtMbuf;             /* ptr to a buffer for giving a frame to rlmt */
-SK_EVPARA              EvPara;                 /* an event parameter union */  
-unsigned long  Flags;                  /* for spin lock */
-int                            PortIndex = pRxPort->PortIndex;
-unsigned int   Offset;
-unsigned int   NumBytes;
-unsigned int   ForRlmt;
-SK_BOOL                        IsBc;
-SK_BOOL                        IsMc;
-SK_BOOL  IsBadFrame;                   /* Bad frame */
-
-SK_U32                 FrameStat;
-SK_U64                 PhysAddr;
-
-rx_start:      
-       /* do forever; exit if BMU_OWN found */
-       for ( pRxd = pRxPort->pRxdRingHead ;
-                 pRxPort->RxdRingFree < pAC->RxDescrPerRing ;
-                 pRxd = pRxd->pNextRxd,
-                 pRxPort->pRxdRingHead = pRxd,
-                 pRxPort->RxdRingFree ++) {
-
-               /*
-                * For a better understanding of this loop
-                * Go through every descriptor beginning at the head
-                * Please note: the ring might be completely received so the OWN bit
-                * set is not a good crirteria to leave that loop.
-                * Therefore the RingFree counter is used.
-                * On entry of this loop pRxd is a pointer to the Rxd that needs
-                * to be checked next.
-                */
-
-               Control = pRxd->RBControl;
-       
-               /* check if this descriptor is ready */
-               if ((Control & BMU_OWN) != 0) {
-                       /* this descriptor is not yet ready */
-                       /* This is the usual end of the loop */
-                       /* We don't need to start the ring again */
-                       FillRxRing(pAC, pRxPort);
-                       return;
-               }
-                pAC->DynIrqModInfo.NbrProcessedDescr++;
-
-               /* get length of frame and check it */
-               FrameLength = Control & BMU_BBC;
-               if (FrameLength > pAC->RxBufSize) {
-                       goto rx_failed;
-               }
-
-               /* check for STF and EOF */
-               if ((Control & (BMU_STF | BMU_EOF)) != (BMU_STF | BMU_EOF)) {
-                       goto rx_failed;
-               }
-
-               /* here we have a complete frame in the ring */
-               pMsg = pRxd->pMBuf;
-
-               FrameStat = pRxd->FrameStat;
-
-               /* check for frame length mismatch */
-#define XMR_FS_LEN_SHIFT        18
-#define GMR_FS_LEN_SHIFT        16
-               if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
-                       if (FrameLength != (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT)) {
-                               SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                                       SK_DBGCAT_DRV_RX_PROGRESS,
-                                       ("skge: Frame length mismatch (%u/%u).\n",
-                                       FrameLength,
-                                       (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT)));
-                               goto rx_failed;
-                       }
-               }
-               else {
-                       if (FrameLength != (SK_U32) (FrameStat >> GMR_FS_LEN_SHIFT)) {
-                               SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                                       SK_DBGCAT_DRV_RX_PROGRESS,
-                                       ("skge: Frame length mismatch (%u/%u).\n",
-                                       FrameLength,
-                                       (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT)));
-                               goto rx_failed;
-                       }
-               }
-
-               /* Set Rx Status */
-               if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
-                       IsBc = (FrameStat & XMR_FS_BC) != 0;
-                       IsMc = (FrameStat & XMR_FS_MC) != 0;
-                       IsBadFrame = (FrameStat &
-                               (XMR_FS_ANY_ERR | XMR_FS_2L_VLAN)) != 0;
-               } else {
-                       IsBc = (FrameStat & GMR_FS_BC) != 0;
-                       IsMc = (FrameStat & GMR_FS_MC) != 0;
-                       IsBadFrame = (((FrameStat & GMR_FS_ANY_ERR) != 0) ||
-                                                       ((FrameStat & GMR_FS_RX_OK) == 0));
-               }
-
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 0,
-                       ("Received frame of length %d on port %d\n",
-                       FrameLength, PortIndex));
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 0,
-                       ("Number of free rx descriptors: %d\n",
-                       pRxPort->RxdRingFree));
-/* DumpMsg(pMsg, "Rx");        */
-
-               if ((Control & BMU_STAT_VAL) != BMU_STAT_VAL || (IsBadFrame)) {
-#if 0
-                       (FrameStat & (XMR_FS_ANY_ERR | XMR_FS_2L_VLAN)) != 0) {
-#endif
-                       /* there is a receive error in this frame */
-                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                               SK_DBGCAT_DRV_RX_PROGRESS,
-                               ("skge: Error in received frame, dropped!\n"
-                               "Control: %x\nRxStat: %x\n",
-                               Control, FrameStat));
-
-                       ReQueueRxBuffer(pAC, pRxPort, pMsg,
-                               pRxd->VDataHigh, pRxd->VDataLow);
-
-                       continue;
-               }
-
-               /*
-                * if short frame then copy data to reduce memory waste
-                */
-               if ((FrameLength < SK_COPY_THRESHOLD) &&
-                       ((pNewMsg = alloc_skb(FrameLength+2, GFP_ATOMIC)) != NULL)) {
-                       /*
-                        * Short frame detected and allocation successfull
-                        */
-                       /* use new skb and copy data */
-                       skb_reserve(pNewMsg, 2);
-                       skb_put(pNewMsg, FrameLength);
-                       PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
-                       PhysAddr |= (SK_U64) pRxd->VDataLow;
-
-                       pci_dma_sync_single_for_cpu(pAC->PciDev,
-                                                   (dma_addr_t) PhysAddr,
-                                                   FrameLength,
-                                                   PCI_DMA_FROMDEVICE);
-                       skb_copy_to_linear_data(pNewMsg, pMsg, FrameLength);
-
-                       pci_dma_sync_single_for_device(pAC->PciDev,
-                                                      (dma_addr_t) PhysAddr,
-                                                      FrameLength,
-                                                      PCI_DMA_FROMDEVICE);
-                       ReQueueRxBuffer(pAC, pRxPort, pMsg,
-                               pRxd->VDataHigh, pRxd->VDataLow);
-
-                       pMsg = pNewMsg;
-
-               }
-               else {
-                       /*
-                        * if large frame, or SKB allocation failed, pass
-                        * the SKB directly to the networking
-                        */
-
-                       PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
-                       PhysAddr |= (SK_U64) pRxd->VDataLow;
-
-                       /* release the DMA mapping */
-                       pci_unmap_single(pAC->PciDev,
-                                        PhysAddr,
-                                        pAC->RxBufSize - 2,
-                                        PCI_DMA_FROMDEVICE);
-
-                       /* set length in message */
-                       skb_put(pMsg, FrameLength);
-               } /* frame > SK_COPY_TRESHOLD */
-
-#ifdef USE_SK_RX_CHECKSUM
-               pMsg->csum = pRxd->TcpSums & 0xffff;
-               pMsg->ip_summed = CHECKSUM_COMPLETE;
-#else
-               pMsg->ip_summed = CHECKSUM_NONE;
-#endif
-
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("V"));
-               ForRlmt = SK_RLMT_RX_PROTOCOL;
-#if 0
-               IsBc = (FrameStat & XMR_FS_BC)==XMR_FS_BC;
-#endif
-               SK_RLMT_PRE_LOOKAHEAD(pAC, PortIndex, FrameLength,
-                       IsBc, &Offset, &NumBytes);
-               if (NumBytes != 0) {
-#if 0
-                       IsMc = (FrameStat & XMR_FS_MC)==XMR_FS_MC;
-#endif
-                       SK_RLMT_LOOKAHEAD(pAC, PortIndex,
-                               &pMsg->data[Offset],
-                               IsBc, IsMc, &ForRlmt);
-               }
-               if (ForRlmt == SK_RLMT_RX_PROTOCOL) {
-                                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("W"));
-                       /* send up only frames from active port */
-                       if ((PortIndex == pAC->ActivePort) ||
-                               (pAC->RlmtNets == 2)) {
-                               /* frame for upper layer */
-                               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("U"));
-#ifdef xDEBUG
-                               DumpMsg(pMsg, "Rx");
-#endif
-                               SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC,
-                                       FrameLength, pRxPort->PortIndex);
-
-                               pMsg->protocol = eth_type_trans(pMsg,
-                                       pAC->dev[pRxPort->PortIndex]);
-                               netif_rx(pMsg);
-                               pAC->dev[pRxPort->PortIndex]->last_rx = jiffies;
-                       }
-                       else {
-                               /* drop frame */
-                               SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                                       SK_DBGCAT_DRV_RX_PROGRESS,
-                                       ("D"));
-                               DEV_KFREE_SKB(pMsg);
-                       }
-                       
-               } /* if not for rlmt */
-               else {
-                       /* packet for rlmt */
-                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                               SK_DBGCAT_DRV_RX_PROGRESS, ("R"));
-                       pRlmtMbuf = SkDrvAllocRlmtMbuf(pAC,
-                               pAC->IoBase, FrameLength);
-                       if (pRlmtMbuf != NULL) {
-                               pRlmtMbuf->pNext = NULL;
-                               pRlmtMbuf->Length = FrameLength;
-                               pRlmtMbuf->PortIdx = PortIndex;
-                               EvPara.pParaPtr = pRlmtMbuf;
-                               memcpy((char*)(pRlmtMbuf->pData),
-                                          (char*)(pMsg->data),
-                                          FrameLength);
-
-                               /* SlowPathLock needed? */
-                               if (SlowPathLock == SK_TRUE) {
-                                       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-                                       SkEventQueue(pAC, SKGE_RLMT,
-                                               SK_RLMT_PACKET_RECEIVED,
-                                               EvPara);
-                                       pAC->CheckQueue = SK_TRUE;
-                                       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-                               } else {
-                                       SkEventQueue(pAC, SKGE_RLMT,
-                                               SK_RLMT_PACKET_RECEIVED,
-                                               EvPara);
-                                       pAC->CheckQueue = SK_TRUE;
-                               }
-
-                               SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-                                       SK_DBGCAT_DRV_RX_PROGRESS,
-                                       ("Q"));
-                       }
-                       if ((pAC->dev[pRxPort->PortIndex]->flags &
-                               (IFF_PROMISC | IFF_ALLMULTI)) != 0 ||
-                               (ForRlmt & SK_RLMT_RX_PROTOCOL) ==
-                               SK_RLMT_RX_PROTOCOL) {
-                               pMsg->protocol = eth_type_trans(pMsg,
-                                       pAC->dev[pRxPort->PortIndex]);
-                               netif_rx(pMsg);
-                               pAC->dev[pRxPort->PortIndex]->last_rx = jiffies;
-                       }
-                       else {
-                               DEV_KFREE_SKB(pMsg);
-                       }
-
-               } /* if packet for rlmt */
-       } /* for ... scanning the RXD ring */
-
-       /* RXD ring is empty -> fill and restart */
-       FillRxRing(pAC, pRxPort);
-       /* do not start if called from Close */
-       if (pAC->BoardLevel > SK_INIT_DATA) {
-               ClearAndStartRx(pAC, PortIndex);
-       }
-       return;
-
-rx_failed:
-       /* remove error frame */
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ERROR,
-               ("Schrottdescriptor, length: 0x%x\n", FrameLength));
-
-       /* release the DMA mapping */
-
-       PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
-       PhysAddr |= (SK_U64) pRxd->VDataLow;
-       pci_unmap_page(pAC->PciDev,
-                        PhysAddr,
-                        pAC->RxBufSize - 2,
-                        PCI_DMA_FROMDEVICE);
-       DEV_KFREE_SKB_IRQ(pRxd->pMBuf);
-       pRxd->pMBuf = NULL;
-       pRxPort->RxdRingFree++;
-       pRxPort->pRxdRingHead = pRxd->pNextRxd;
-       goto rx_start;
-
-} /* ReceiveIrq */
-
-
-/*****************************************************************************
- *
- *     ClearAndStartRx - give a start receive command to BMU, clear IRQ
- *
- * Description:
- *     This function sends a start command and a clear interrupt
- *     command for one receive queue to the BMU.
- *
- * Returns: N/A
- *     none
- */
-static void ClearAndStartRx(
-SK_AC  *pAC,           /* pointer to the adapter context */
-int    PortIndex)      /* index of the receive port (XMAC) */
-{
-       SK_OUT8(pAC->IoBase,
-               RxQueueAddr[PortIndex]+Q_CSR,
-               CSR_START | CSR_IRQ_CL_F);
-} /* ClearAndStartRx */
-
-
-/*****************************************************************************
- *
- *     ClearTxIrq - give a clear transmit IRQ command to BMU
- *
- * Description:
- *     This function sends a clear tx IRQ command for one
- *     transmit queue to the BMU.
- *
- * Returns: N/A
- */
-static void ClearTxIrq(
-SK_AC  *pAC,           /* pointer to the adapter context */
-int    PortIndex,      /* index of the transmit port (XMAC) */
-int    Prio)           /* priority or normal queue */
-{
-       SK_OUT8(pAC->IoBase, 
-               TxQueueAddr[PortIndex][Prio]+Q_CSR,
-               CSR_IRQ_CL_F);
-} /* ClearTxIrq */
-
-
-/*****************************************************************************
- *
- *     ClearRxRing - remove all buffers from the receive ring
- *
- * Description:
- *     This function removes all receive buffers from the ring.
- *     The receive BMU must be stopped before calling this function.
- *
- * Returns: N/A
- */
-static void ClearRxRing(
-SK_AC  *pAC,           /* pointer to adapter context */
-RX_PORT        *pRxPort)       /* pointer to rx port struct */
-{
-RXD            *pRxd;  /* pointer to the current descriptor */
-unsigned long  Flags;
-SK_U64         PhysAddr;
-
-       if (pRxPort->RxdRingFree == pAC->RxDescrPerRing) {
-               return;
-       }
-       spin_lock_irqsave(&pRxPort->RxDesRingLock, Flags);
-       pRxd = pRxPort->pRxdRingHead;
-       do {
-               if (pRxd->pMBuf != NULL) {
-
-                       PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
-                       PhysAddr |= (SK_U64) pRxd->VDataLow;
-                       pci_unmap_page(pAC->PciDev,
-                                        PhysAddr,
-                                        pAC->RxBufSize - 2,
-                                        PCI_DMA_FROMDEVICE);
-                       DEV_KFREE_SKB(pRxd->pMBuf);
-                       pRxd->pMBuf = NULL;
-               }
-               pRxd->RBControl &= BMU_OWN;
-               pRxd = pRxd->pNextRxd;
-               pRxPort->RxdRingFree++;
-       } while (pRxd != pRxPort->pRxdRingTail);
-       pRxPort->pRxdRingTail = pRxPort->pRxdRingHead;
-       spin_unlock_irqrestore(&pRxPort->RxDesRingLock, Flags);
-} /* ClearRxRing */
-
-/*****************************************************************************
- *
- *     ClearTxRing - remove all buffers from the transmit ring
- *
- * Description:
- *     This function removes all transmit buffers from the ring.
- *     The transmit BMU must be stopped before calling this function
- *     and transmitting at the upper level must be disabled.
- *     The BMU own bit of all descriptors is cleared, the rest is
- *     done by calling FreeTxDescriptors.
- *
- * Returns: N/A
- */
-static void ClearTxRing(
-SK_AC  *pAC,           /* pointer to adapter context */
-TX_PORT        *pTxPort)       /* pointer to tx prt struct */
-{
-TXD            *pTxd;          /* pointer to the current descriptor */
-int            i;
-unsigned long  Flags;
-
-       spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags);
-       pTxd = pTxPort->pTxdRingHead;
-       for (i=0; i<pAC->TxDescrPerRing; i++) {
-               pTxd->TBControl &= ~BMU_OWN;
-               pTxd = pTxd->pNextTxd;
-       }
-       FreeTxDescriptors(pAC, pTxPort);
-       spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
-} /* ClearTxRing */
-
-/*****************************************************************************
- *
- *     SkGeSetMacAddr - Set the hardware MAC address
- *
- * Description:
- *     This function sets the MAC address used by the adapter.
- *
- * Returns:
- *     0, if everything is ok
- *     !=0, on error
- */
-static int SkGeSetMacAddr(struct SK_NET_DEVICE *dev, void *p)
-{
-
-DEV_NET *pNet = netdev_priv(dev);
-SK_AC  *pAC = pNet->pAC;
-
-struct sockaddr        *addr = p;
-unsigned long  Flags;
-       
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-               ("SkGeSetMacAddr starts now...\n"));
-       if(netif_running(dev))
-               return -EBUSY;
-
-       memcpy(dev->dev_addr, addr->sa_data,dev->addr_len);
-       
-       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-
-       if (pAC->RlmtNets == 2)
-               SkAddrOverride(pAC, pAC->IoBase, pNet->NetNr,
-                       (SK_MAC_ADDR*)dev->dev_addr, SK_ADDR_VIRTUAL_ADDRESS);
-       else
-               SkAddrOverride(pAC, pAC->IoBase, pAC->ActivePort,
-                       (SK_MAC_ADDR*)dev->dev_addr, SK_ADDR_VIRTUAL_ADDRESS);
-
-       
-       
-       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-       return 0;
-} /* SkGeSetMacAddr */
-
-
-/*****************************************************************************
- *
- *     SkGeSetRxMode - set receive mode
- *
- * Description:
- *     This function sets the receive mode of an adapter. The adapter
- *     supports promiscuous mode, allmulticast mode and a number of
- *     multicast addresses. If more multicast addresses the available
- *     are selected, a hash function in the hardware is used.
- *
- * Returns:
- *     0, if everything is ok
- *     !=0, on error
- */
-static void SkGeSetRxMode(struct SK_NET_DEVICE *dev)
-{
-
-DEV_NET                *pNet;
-SK_AC          *pAC;
-
-struct dev_mc_list     *pMcList;
-int                    i;
-int                    PortIdx;
-unsigned long          Flags;
-
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-               ("SkGeSetRxMode starts now... "));
-
-       pNet = netdev_priv(dev);
-       pAC = pNet->pAC;
-       if (pAC->RlmtNets == 1)
-               PortIdx = pAC->ActivePort;
-       else
-               PortIdx = pNet->NetNr;
-
-       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-       if (dev->flags & IFF_PROMISC) {
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-                       ("PROMISCUOUS mode\n"));
-               SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
-                       SK_PROM_MODE_LLC);
-       } else if (dev->flags & IFF_ALLMULTI) {
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-                       ("ALLMULTI mode\n"));
-               SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
-                       SK_PROM_MODE_ALL_MC);
-       } else {
-               SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
-                       SK_PROM_MODE_NONE);
-               SkAddrMcClear(pAC, pAC->IoBase, PortIdx, 0);
-
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-                       ("Number of MC entries: %d ", dev->mc_count));
-               
-               pMcList = dev->mc_list;
-               for (i=0; i<dev->mc_count; i++, pMcList = pMcList->next) {
-                       SkAddrMcAdd(pAC, pAC->IoBase, PortIdx,
-                               (SK_MAC_ADDR*)pMcList->dmi_addr, 0);
-                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MCA,
-                               ("%02x:%02x:%02x:%02x:%02x:%02x\n",
-                               pMcList->dmi_addr[0],
-                               pMcList->dmi_addr[1],
-                               pMcList->dmi_addr[2],
-                               pMcList->dmi_addr[3],
-                               pMcList->dmi_addr[4],
-                               pMcList->dmi_addr[5]));
-               }
-               SkAddrMcUpdate(pAC, pAC->IoBase, PortIdx);
-       }
-       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-       
-       return;
-} /* SkGeSetRxMode */
-
-
-/*****************************************************************************
- *
- *     SkGeChangeMtu - set the MTU to another value
- *
- * Description:
- *     This function sets is called whenever the MTU size is changed
- *     (ifconfig mtu xxx dev ethX). If the MTU is bigger than standard
- *     ethernet MTU size, long frame support is activated.
- *
- * Returns:
- *     0, if everything is ok
- *     !=0, on error
- */
-static int SkGeChangeMtu(struct SK_NET_DEVICE *dev, int NewMtu)
-{
-DEV_NET                *pNet;
-struct net_device *pOtherDev;
-SK_AC          *pAC;
-unsigned long  Flags;
-int            i;
-SK_EVPARA      EvPara;
-
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-               ("SkGeChangeMtu starts now...\n"));
-
-       pNet = netdev_priv(dev);
-       pAC  = pNet->pAC;
-
-       if ((NewMtu < 68) || (NewMtu > SK_JUMBO_MTU)) {
-               return -EINVAL;
-       }
-
-       if(pAC->BoardLevel != SK_INIT_RUN) {
-               return -EINVAL;
-       }
-
-#ifdef SK_DIAG_SUPPORT
-       if (pAC->DiagModeActive == DIAG_ACTIVE) {
-               if (pAC->DiagFlowCtrl == SK_FALSE) {
-                       return -1; /* still in use, deny any actions of MTU */
-               } else {
-                       pAC->DiagFlowCtrl = SK_FALSE;
-               }
-       }
-#endif
-
-       pOtherDev = pAC->dev[1 - pNet->NetNr];
-
-       if ( netif_running(pOtherDev) && (pOtherDev->mtu > 1500)
-            && (NewMtu <= 1500))
-               return 0;
-
-       pAC->RxBufSize = NewMtu + 32;
-       dev->mtu = NewMtu;
-
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-               ("New MTU: %d\n", NewMtu));
-
-       /* 
-       ** Prevent any reconfiguration while changing the MTU 
-       ** by disabling any interrupts 
-       */
-       SK_OUT32(pAC->IoBase, B0_IMSK, 0);
-       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-
-       /* 
-       ** Notify RLMT that any ports are to be stopped
-       */
-       EvPara.Para32[0] =  0;
-       EvPara.Para32[1] = -1;
-       if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
-               EvPara.Para32[0] =  1;
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
-       } else {
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
-       }
-
-       /*
-       ** After calling the SkEventDispatcher(), RLMT is aware about
-       ** the stopped ports -> configuration can take place!
-       */
-       SkEventDispatcher(pAC, pAC->IoBase);
-
-       for (i=0; i<pAC->GIni.GIMacsFound; i++) {
-               spin_lock(&pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock);
-               netif_stop_queue(pAC->dev[i]);
-
-       }
-
-       /*
-       ** Depending on the desired MTU size change, a different number of 
-       ** RX buffers need to be allocated
-       */
-       if (NewMtu > 1500) {
-           /* 
-           ** Use less rx buffers 
-           */
-           for (i=0; i<pAC->GIni.GIMacsFound; i++) {
-               if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
-                   pAC->RxPort[i].RxFillLimit =  pAC->RxDescrPerRing -
-                                                (pAC->RxDescrPerRing / 4);
-               } else {
-                   if (i == pAC->ActivePort) {
-                       pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing - 
-                                                   (pAC->RxDescrPerRing / 4);
-                   } else {
-                       pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing - 
-                                                   (pAC->RxDescrPerRing / 10);
-                   }
-               }
-           }
-       } else {
-           /* 
-           ** Use the normal amount of rx buffers 
-           */
-           for (i=0; i<pAC->GIni.GIMacsFound; i++) {
-               if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
-                   pAC->RxPort[i].RxFillLimit = 1;
-               } else {
-                   if (i == pAC->ActivePort) {
-                       pAC->RxPort[i].RxFillLimit = 1;
-                   } else {
-                       pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing -
-                                                   (pAC->RxDescrPerRing / 4);
-                   }
-               }
-           }
-       }
-       
-       SkGeDeInit(pAC, pAC->IoBase);
-
-       /*
-       ** enable/disable hardware support for long frames
-       */
-       if (NewMtu > 1500) {
-// pAC->JumboActivated = SK_TRUE; /* is never set back !!! */
-               pAC->GIni.GIPortUsage = SK_JUMBO_LINK;
-       } else {
-           if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
-               pAC->GIni.GIPortUsage = SK_MUL_LINK;
-           } else {
-               pAC->GIni.GIPortUsage = SK_RED_LINK;
-           }
-       }
-
-       SkGeInit(   pAC, pAC->IoBase, SK_INIT_IO);
-       SkI2cInit(  pAC, pAC->IoBase, SK_INIT_IO);
-       SkEventInit(pAC, pAC->IoBase, SK_INIT_IO);
-       SkPnmiInit( pAC, pAC->IoBase, SK_INIT_IO);
-       SkAddrInit( pAC, pAC->IoBase, SK_INIT_IO);
-       SkRlmtInit( pAC, pAC->IoBase, SK_INIT_IO);
-       SkTimerInit(pAC, pAC->IoBase, SK_INIT_IO);
-       
-       /*
-       ** tschilling:
-       ** Speed and others are set back to default in level 1 init!
-       */
-       GetConfiguration(pAC);
-       
-       SkGeInit(   pAC, pAC->IoBase, SK_INIT_RUN);
-       SkI2cInit(  pAC, pAC->IoBase, SK_INIT_RUN);
-       SkEventInit(pAC, pAC->IoBase, SK_INIT_RUN);
-       SkPnmiInit( pAC, pAC->IoBase, SK_INIT_RUN);
-       SkAddrInit( pAC, pAC->IoBase, SK_INIT_RUN);
-       SkRlmtInit( pAC, pAC->IoBase, SK_INIT_RUN);
-       SkTimerInit(pAC, pAC->IoBase, SK_INIT_RUN);
-
-       /*
-       ** clear and reinit the rx rings here
-       */
-       for (i=0; i<pAC->GIni.GIMacsFound; i++) {
-               ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE);
-               ClearRxRing(pAC, &pAC->RxPort[i]);
-               FillRxRing(pAC, &pAC->RxPort[i]);
-
-               /* 
-               ** Enable transmit descriptor polling
-               */
-               SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE);
-               FillRxRing(pAC, &pAC->RxPort[i]);
-       };
-
-       SkGeYellowLED(pAC, pAC->IoBase, 1);
-       SkDimEnableModerationIfNeeded(pAC);     
-       SkDimDisplayModerationSettings(pAC);
-
-       netif_start_queue(pAC->dev[pNet->PortNr]);
-       for (i=pAC->GIni.GIMacsFound-1; i>=0; i--) {
-               spin_unlock(&pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock);
-       }
-
-       /* 
-       ** Enable Interrupts again 
-       */
-       SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
-       SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK);
-
-       SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
-       SkEventDispatcher(pAC, pAC->IoBase);
-
-       /* 
-       ** Notify RLMT about the changing and restarting one (or more) ports
-       */
-       if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
-               EvPara.Para32[0] = pAC->RlmtNets;
-               EvPara.Para32[1] = -1;
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS, EvPara);
-               EvPara.Para32[0] = pNet->PortNr;
-               EvPara.Para32[1] = -1;
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
-                       
-               if (netif_running(pOtherDev)) {
-                       DEV_NET *pOtherNet = netdev_priv(pOtherDev);
-                       EvPara.Para32[0] = pOtherNet->PortNr;
-                       SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
-               }
-       } else {
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
-       }
-
-       SkEventDispatcher(pAC, pAC->IoBase);
-       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-       
-       /*
-       ** While testing this driver with latest kernel 2.5 (2.5.70), it 
-       ** seems as if upper layers have a problem to handle a successful
-       ** return value of '0'. If such a zero is returned, the complete 
-       ** system hangs for several minutes (!), which is in acceptable.
-       **
-       ** Currently it is not clear, what the exact reason for this problem
-       ** is. The implemented workaround for 2.5 is to return the desired 
-       ** new MTU size if all needed changes for the new MTU size where 
-       ** performed. In kernels 2.2 and 2.4, a zero value is returned,
-       ** which indicates the successful change of the mtu-size.
-       */
-       return NewMtu;
-
-} /* SkGeChangeMtu */
-
-
-/*****************************************************************************
- *
- *     SkGeStats - return ethernet device statistics
- *
- * Description:
- *     This function return statistic data about the ethernet device
- *     to the operating system.
- *
- * Returns:
- *     pointer to the statistic structure.
- */
-static struct net_device_stats *SkGeStats(struct SK_NET_DEVICE *dev)
-{
-DEV_NET *pNet = netdev_priv(dev);
-SK_AC  *pAC = pNet->pAC;
-SK_PNMI_STRUCT_DATA *pPnmiStruct;       /* structure for all Pnmi-Data */
-SK_PNMI_STAT    *pPnmiStat;             /* pointer to virtual XMAC stat. data */
-SK_PNMI_CONF    *pPnmiConf;             /* pointer to virtual link config. */
-unsigned int    Size;                   /* size of pnmi struct */
-unsigned long  Flags;                  /* for spin lock */
-
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-               ("SkGeStats starts now...\n"));
-       pPnmiStruct = &pAC->PnmiStruct;
-
-#ifdef SK_DIAG_SUPPORT
-        if ((pAC->DiagModeActive == DIAG_NOTACTIVE) &&
-                (pAC->BoardLevel == SK_INIT_RUN)) {
-#endif
-        SK_MEMSET(pPnmiStruct, 0, sizeof(SK_PNMI_STRUCT_DATA));
-        spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-        Size = SK_PNMI_STRUCT_SIZE;
-               SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, pNet->NetNr);
-        spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-#ifdef SK_DIAG_SUPPORT
-       }
-#endif
-
-        pPnmiStat = &pPnmiStruct->Stat[0];
-        pPnmiConf = &pPnmiStruct->Conf[0];
-
-       pAC->stats.rx_packets = (SK_U32) pPnmiStruct->RxDeliveredCts & 0xFFFFFFFF;
-       pAC->stats.tx_packets = (SK_U32) pPnmiStat->StatTxOkCts & 0xFFFFFFFF;
-       pAC->stats.rx_bytes = (SK_U32) pPnmiStruct->RxOctetsDeliveredCts;
-       pAC->stats.tx_bytes = (SK_U32) pPnmiStat->StatTxOctetsOkCts;
-       
-        if (dev->mtu <= 1500) {
-                pAC->stats.rx_errors = (SK_U32) pPnmiStruct->InErrorsCts & 0xFFFFFFFF;
-        } else {
-                pAC->stats.rx_errors = (SK_U32) ((pPnmiStruct->InErrorsCts -
-                        pPnmiStat->StatRxTooLongCts) & 0xFFFFFFFF);
-       }
-
-
-       if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC && pAC->HWRevision < 12)
-               pAC->stats.rx_errors = pAC->stats.rx_errors - pPnmiStat->StatRxShortsCts;
-
-       pAC->stats.tx_errors = (SK_U32) pPnmiStat->StatTxSingleCollisionCts & 0xFFFFFFFF;
-       pAC->stats.rx_dropped = (SK_U32) pPnmiStruct->RxNoBufCts & 0xFFFFFFFF;
-       pAC->stats.tx_dropped = (SK_U32) pPnmiStruct->TxNoBufCts & 0xFFFFFFFF;
-       pAC->stats.multicast = (SK_U32) pPnmiStat->StatRxMulticastOkCts & 0xFFFFFFFF;
-       pAC->stats.collisions = (SK_U32) pPnmiStat->StatTxSingleCollisionCts & 0xFFFFFFFF;
-
-       /* detailed rx_errors: */
-       pAC->stats.rx_length_errors = (SK_U32) pPnmiStat->StatRxRuntCts & 0xFFFFFFFF;
-       pAC->stats.rx_over_errors = (SK_U32) pPnmiStat->StatRxFifoOverflowCts & 0xFFFFFFFF;
-       pAC->stats.rx_crc_errors = (SK_U32) pPnmiStat->StatRxFcsCts & 0xFFFFFFFF;
-       pAC->stats.rx_frame_errors = (SK_U32) pPnmiStat->StatRxFramingCts & 0xFFFFFFFF;
-       pAC->stats.rx_fifo_errors = (SK_U32) pPnmiStat->StatRxFifoOverflowCts & 0xFFFFFFFF;
-       pAC->stats.rx_missed_errors = (SK_U32) pPnmiStat->StatRxMissedCts & 0xFFFFFFFF;
-
-       /* detailed tx_errors */
-       pAC->stats.tx_aborted_errors = (SK_U32) 0;
-       pAC->stats.tx_carrier_errors = (SK_U32) pPnmiStat->StatTxCarrierCts & 0xFFFFFFFF;
-       pAC->stats.tx_fifo_errors = (SK_U32) pPnmiStat->StatTxFifoUnderrunCts & 0xFFFFFFFF;
-       pAC->stats.tx_heartbeat_errors = (SK_U32) pPnmiStat->StatTxCarrierCts & 0xFFFFFFFF;
-       pAC->stats.tx_window_errors = (SK_U32) 0;
-
-       return(&pAC->stats);
-} /* SkGeStats */
-
-/*
- * Basic MII register access
- */
-static int SkGeMiiIoctl(struct net_device *dev,
-                       struct mii_ioctl_data *data, int cmd)
-{
-       DEV_NET *pNet = netdev_priv(dev);
-       SK_AC *pAC = pNet->pAC;
-       SK_IOC IoC = pAC->IoBase;
-       int Port = pNet->PortNr;
-       SK_GEPORT *pPrt = &pAC->GIni.GP[Port];
-       unsigned long Flags;
-       int err = 0;
-       int reg = data->reg_num & 0x1f;
-       SK_U16 val = data->val_in;
-
-       if (!netif_running(dev))
-               return -ENODEV; /* Phy still in reset */
-
-       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-       switch(cmd) {
-       case SIOCGMIIPHY:
-               data->phy_id = pPrt->PhyAddr;
-
-               /* fallthru */
-       case SIOCGMIIREG:
-               if (pAC->GIni.GIGenesis)
-                       SkXmPhyRead(pAC, IoC, Port, reg, &val);
-               else
-                       SkGmPhyRead(pAC, IoC, Port, reg, &val);
-
-               data->val_out = val;
-               break;
-
-       case SIOCSMIIREG:
-               if (!capable(CAP_NET_ADMIN))
-                       err = -EPERM;
-
-               else if (pAC->GIni.GIGenesis)
-                       SkXmPhyWrite(pAC, IoC, Port, reg, val);
-               else
-                       SkGmPhyWrite(pAC, IoC, Port, reg, val);
-               break;
-       default:
-               err = -EOPNOTSUPP;
-       }
-        spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-       return err;
-}
-
-
-/*****************************************************************************
- *
- *     SkGeIoctl - IO-control function
- *
- * Description:
- *     This function is called if an ioctl is issued on the device.
- *     There are three subfunction for reading, writing and test-writing
- *     the private MIB data structure (useful for SysKonnect-internal tools).
- *
- * Returns:
- *     0, if everything is ok
- *     !=0, on error
- */
-static int SkGeIoctl(struct SK_NET_DEVICE *dev, struct ifreq *rq, int cmd)
-{
-DEV_NET                *pNet;
-SK_AC          *pAC;
-void           *pMemBuf;
-struct pci_dev  *pdev = NULL;
-SK_GE_IOCTL    Ioctl;
-unsigned int   Err = 0;
-int            Size = 0;
-int             Ret = 0;
-unsigned int   Length = 0;
-int            HeaderLength = sizeof(SK_U32) + sizeof(SK_U32);
-
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-               ("SkGeIoctl starts now...\n"));
-
-       pNet = netdev_priv(dev);
-       pAC = pNet->pAC;
-       
-       if (cmd == SIOCGMIIPHY || cmd == SIOCSMIIREG || cmd == SIOCGMIIREG)
-           return SkGeMiiIoctl(dev, if_mii(rq), cmd);
-
-       if(copy_from_user(&Ioctl, rq->ifr_data, sizeof(SK_GE_IOCTL))) {
-               return -EFAULT;
-       }
-
-       switch(cmd) {
-       case SK_IOCTL_SETMIB:
-       case SK_IOCTL_PRESETMIB:
-               if (!capable(CAP_NET_ADMIN)) return -EPERM;
-       case SK_IOCTL_GETMIB:
-               if(copy_from_user(&pAC->PnmiStruct, Ioctl.pData,
-                       Ioctl.Len<sizeof(pAC->PnmiStruct)?
-                       Ioctl.Len : sizeof(pAC->PnmiStruct))) {
-                       return -EFAULT;
-               }
-               Size = SkGeIocMib(pNet, Ioctl.Len, cmd);
-               if(copy_to_user(Ioctl.pData, &pAC->PnmiStruct,
-                       Ioctl.Len<Size? Ioctl.Len : Size)) {
-                       return -EFAULT;
-               }
-               Ioctl.Len = Size;
-               if(copy_to_user(rq->ifr_data, &Ioctl, sizeof(SK_GE_IOCTL))) {
-                       return -EFAULT;
-               }
-               break;
-       case SK_IOCTL_GEN:
-               if (Ioctl.Len < (sizeof(pAC->PnmiStruct) + HeaderLength)) {
-                       Length = Ioctl.Len;
-               } else {
-                       Length = sizeof(pAC->PnmiStruct) + HeaderLength;
-               }
-               if (NULL == (pMemBuf = kmalloc(Length, GFP_KERNEL))) {
-                       return -ENOMEM;
-               }
-               if(copy_from_user(pMemBuf, Ioctl.pData, Length)) {
-                       Err = -EFAULT;
-                       goto fault_gen;
-               }
-               if ((Ret = SkPnmiGenIoctl(pAC, pAC->IoBase, pMemBuf, &Length, 0)) < 0) {
-                       Err = -EFAULT;
-                       goto fault_gen;
-               }
-               if(copy_to_user(Ioctl.pData, pMemBuf, Length) ) {
-                       Err = -EFAULT;
-                       goto fault_gen;
-               }
-               Ioctl.Len = Length;
-               if(copy_to_user(rq->ifr_data, &Ioctl, sizeof(SK_GE_IOCTL))) {
-                       Err = -EFAULT;
-                       goto fault_gen;
-               }
-fault_gen:
-               kfree(pMemBuf); /* cleanup everything */
-               break;
-#ifdef SK_DIAG_SUPPORT
-       case SK_IOCTL_DIAG:
-               if (!capable(CAP_NET_ADMIN)) return -EPERM;
-               if (Ioctl.Len < (sizeof(pAC->PnmiStruct) + HeaderLength)) {
-                       Length = Ioctl.Len;
-               } else {
-                       Length = sizeof(pAC->PnmiStruct) + HeaderLength;
-               }
-               if (NULL == (pMemBuf = kmalloc(Length, GFP_KERNEL))) {
-                       return -ENOMEM;
-               }
-               if(copy_from_user(pMemBuf, Ioctl.pData, Length)) {
-                       Err = -EFAULT;
-                       goto fault_diag;
-               }
-               pdev = pAC->PciDev;
-               Length = 3 * sizeof(SK_U32);  /* Error, Bus and Device */
-               /* 
-               ** While coding this new IOCTL interface, only a few lines of code
-               ** are to to be added. Therefore no dedicated function has been 
-               ** added. If more functionality is added, a separate function 
-               ** should be used...
-               */
-               * ((SK_U32 *)pMemBuf) = 0;
-               * ((SK_U32 *)pMemBuf + 1) = pdev->bus->number;
-               * ((SK_U32 *)pMemBuf + 2) = ParseDeviceNbrFromSlotName(pci_name(pdev));
-               if(copy_to_user(Ioctl.pData, pMemBuf, Length) ) {
-                       Err = -EFAULT;
-                       goto fault_diag;
-               }
-               Ioctl.Len = Length;
-               if(copy_to_user(rq->ifr_data, &Ioctl, sizeof(SK_GE_IOCTL))) {
-                       Err = -EFAULT;
-                       goto fault_diag;
-               }
-fault_diag:
-               kfree(pMemBuf); /* cleanup everything */
-               break;
-#endif
-       default:
-               Err = -EOPNOTSUPP;
-       }
-
-       return(Err);
-
-} /* SkGeIoctl */
-
-
-/*****************************************************************************
- *
- *     SkGeIocMib - handle a GetMib, SetMib- or PresetMib-ioctl message
- *
- * Description:
- *     This function reads/writes the MIB data using PNMI (Private Network
- *     Management Interface).
- *     The destination for the data must be provided with the
- *     ioctl call and is given to the driver in the form of
- *     a user space address.
- *     Copying from the user-provided data area into kernel messages
- *     and back is done by copy_from_user and copy_to_user calls in
- *     SkGeIoctl.
- *
- * Returns:
- *     returned size from PNMI call
- */
-static int SkGeIocMib(
-DEV_NET                *pNet,  /* pointer to the adapter context */
-unsigned int   Size,   /* length of ioctl data */
-int            mode)   /* flag for set/preset */
-{
-unsigned long  Flags;  /* for spin lock */
-SK_AC          *pAC;
-
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-               ("SkGeIocMib starts now...\n"));
-       pAC = pNet->pAC;
-       /* access MIB */
-       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-       switch(mode) {
-       case SK_IOCTL_GETMIB:
-               SkPnmiGetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size,
-                       pNet->NetNr);
-               break;
-       case SK_IOCTL_PRESETMIB:
-               SkPnmiPreSetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size,
-                       pNet->NetNr);
-               break;
-       case SK_IOCTL_SETMIB:
-               SkPnmiSetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size,
-                       pNet->NetNr);
-               break;
-       default:
-               break;
-       }
-       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-               ("MIB data access succeeded\n"));
-       return (Size);
-} /* SkGeIocMib */
-
-
-/*****************************************************************************
- *
- *     GetConfiguration - read configuration information
- *
- * Description:
- *     This function reads per-adapter configuration information from
- *     the options provided on the command line.
- *
- * Returns:
- *     none
- */
-static void GetConfiguration(
-SK_AC  *pAC)   /* pointer to the adapter context structure */
-{
-SK_I32 Port;           /* preferred port */
-SK_BOOL        AutoSet;
-SK_BOOL DupSet;
-int    LinkSpeed          = SK_LSPEED_AUTO;    /* Link speed */
-int    AutoNeg            = 1;                 /* autoneg off (0) or on (1) */
-int    DuplexCap          = 0;                 /* 0=both,1=full,2=half */
-int    FlowCtrl           = SK_FLOW_MODE_SYM_OR_REM;   /* FlowControl  */
-int    MSMode             = SK_MS_MODE_AUTO;   /* master/slave mode    */
-
-SK_BOOL IsConTypeDefined   = SK_TRUE;
-SK_BOOL IsLinkSpeedDefined = SK_TRUE;
-SK_BOOL IsFlowCtrlDefined  = SK_TRUE;
-SK_BOOL IsRoleDefined      = SK_TRUE;
-SK_BOOL IsModeDefined      = SK_TRUE;
-/*
- *     The two parameters AutoNeg. and DuplexCap. map to one configuration
- *     parameter. The mapping is described by this table:
- *     DuplexCap ->    |       both    |       full    |       half    |
- *     AutoNeg         |               |               |               |
- *     -----------------------------------------------------------------
- *     Off             |    illegal    |       Full    |       Half    |
- *     -----------------------------------------------------------------
- *     On              |   AutoBoth    |   AutoFull    |   AutoHalf    |
- *     -----------------------------------------------------------------
- *     Sense           |   AutoSense   |   AutoSense   |   AutoSense   |
- */
-int    Capabilities[3][3] =
-               { {                -1, SK_LMODE_FULL     , SK_LMODE_HALF     },
-                 {SK_LMODE_AUTOBOTH , SK_LMODE_AUTOFULL , SK_LMODE_AUTOHALF },
-                 {SK_LMODE_AUTOSENSE, SK_LMODE_AUTOSENSE, SK_LMODE_AUTOSENSE} };
-
-#define DC_BOTH        0
-#define DC_FULL 1
-#define DC_HALF 2
-#define AN_OFF 0
-#define AN_ON  1
-#define AN_SENS        2
-#define M_CurrPort pAC->GIni.GP[Port]
-
-
-       /*
-       ** Set the default values first for both ports!
-       */
-       for (Port = 0; Port < SK_MAX_MACS; Port++) {
-               M_CurrPort.PLinkModeConf = Capabilities[AN_ON][DC_BOTH];
-               M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM;
-               M_CurrPort.PMSMode       = SK_MS_MODE_AUTO;
-               M_CurrPort.PLinkSpeed    = SK_LSPEED_AUTO;
-       }
-
-       /*
-       ** Check merged parameter ConType. If it has not been used,
-       ** verify any other parameter (e.g. AutoNeg) and use default values. 
-       **
-       ** Stating both ConType and other lowlevel link parameters is also
-       ** possible. If this is the case, the passed ConType-parameter is 
-       ** overwritten by the lowlevel link parameter.
-       **
-       ** The following settings are used for a merged ConType-parameter:
-       **
-       ** ConType   DupCap   AutoNeg   FlowCtrl      Role      Speed
-       ** -------   ------   -------   --------   ----------   -----
-       **  Auto      Both      On      SymOrRem      Auto       Auto
-       **  100FD     Full      Off       None      <ignored>    100
-       **  100HD     Half      Off       None      <ignored>    100
-       **  10FD      Full      Off       None      <ignored>    10
-       **  10HD      Half      Off       None      <ignored>    10
-       ** 
-       ** This ConType parameter is used for all ports of the adapter!
-       */
-        if ( (ConType != NULL)                && 
-            (pAC->Index < SK_MAX_CARD_PARAM) &&
-            (ConType[pAC->Index] != NULL) ) {
-
-                       /* Check chipset family */
-                       if ((!pAC->ChipsetType) && 
-                               (strcmp(ConType[pAC->Index],"Auto")!=0) &&
-                               (strcmp(ConType[pAC->Index],"")!=0)) {
-                               /* Set the speed parameter back */
-                                       printk("sk98lin: Illegal value \"%s\" " 
-                                                       "for ConType."
-                                                       " Using Auto.\n", 
-                                                       ConType[pAC->Index]);
-
-                                       sprintf(ConType[pAC->Index], "Auto");   
-                       }
-
-                               if (strcmp(ConType[pAC->Index],"")==0) {
-                       IsConTypeDefined = SK_FALSE; /* No ConType defined */
-                               } else if (strcmp(ConType[pAC->Index],"Auto")==0) {
-                   for (Port = 0; Port < SK_MAX_MACS; Port++) {
-                       M_CurrPort.PLinkModeConf = Capabilities[AN_ON][DC_BOTH];
-                       M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM;
-                       M_CurrPort.PMSMode       = SK_MS_MODE_AUTO;
-                       M_CurrPort.PLinkSpeed    = SK_LSPEED_AUTO;
-                   }
-                } else if (strcmp(ConType[pAC->Index],"100FD")==0) {
-                   for (Port = 0; Port < SK_MAX_MACS; Port++) {
-                       M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_FULL];
-                       M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE;
-                       M_CurrPort.PMSMode       = SK_MS_MODE_AUTO;
-                       M_CurrPort.PLinkSpeed    = SK_LSPEED_100MBPS;
-                   }
-                } else if (strcmp(ConType[pAC->Index],"100HD")==0) {
-                   for (Port = 0; Port < SK_MAX_MACS; Port++) {
-                       M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_HALF];
-                       M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE;
-                       M_CurrPort.PMSMode       = SK_MS_MODE_AUTO;
-                       M_CurrPort.PLinkSpeed    = SK_LSPEED_100MBPS;
-                   }
-                } else if (strcmp(ConType[pAC->Index],"10FD")==0) {
-                   for (Port = 0; Port < SK_MAX_MACS; Port++) {
-                       M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_FULL];
-                       M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE;
-                       M_CurrPort.PMSMode       = SK_MS_MODE_AUTO;
-                       M_CurrPort.PLinkSpeed    = SK_LSPEED_10MBPS;
-                   }
-                } else if (strcmp(ConType[pAC->Index],"10HD")==0) {
-                   for (Port = 0; Port < SK_MAX_MACS; Port++) {
-                       M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_HALF];
-                       M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE;
-                       M_CurrPort.PMSMode       = SK_MS_MODE_AUTO;
-                       M_CurrPort.PLinkSpeed    = SK_LSPEED_10MBPS;
-                   }
-                } else { 
-                   printk("sk98lin: Illegal value \"%s\" for ConType\n", 
-                       ConType[pAC->Index]);
-                   IsConTypeDefined = SK_FALSE; /* Wrong ConType defined */
-               }
-        } else {
-           IsConTypeDefined = SK_FALSE; /* No ConType defined */
-       }
-
-       /*
-       ** Parse any parameter settings for port A:
-       ** a) any LinkSpeed stated?
-       */
-       if (Speed_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
-               Speed_A[pAC->Index] != NULL) {
-               if (strcmp(Speed_A[pAC->Index],"")==0) {
-                   IsLinkSpeedDefined = SK_FALSE;
-               } else if (strcmp(Speed_A[pAC->Index],"Auto")==0) {
-                   LinkSpeed = SK_LSPEED_AUTO;
-               } else if (strcmp(Speed_A[pAC->Index],"10")==0) {
-                   LinkSpeed = SK_LSPEED_10MBPS;
-               } else if (strcmp(Speed_A[pAC->Index],"100")==0) {
-                   LinkSpeed = SK_LSPEED_100MBPS;
-               } else if (strcmp(Speed_A[pAC->Index],"1000")==0) {
-                   LinkSpeed = SK_LSPEED_1000MBPS;
-               } else {
-                   printk("sk98lin: Illegal value \"%s\" for Speed_A\n",
-                       Speed_A[pAC->Index]);
-                   IsLinkSpeedDefined = SK_FALSE;
-               }
-       } else {
-           IsLinkSpeedDefined = SK_FALSE;
-       }
-
-       /* 
-       ** Check speed parameter: 
-       **    Only copper type adapter and GE V2 cards 
-       */
-       if (((!pAC->ChipsetType) || (pAC->GIni.GICopperType != SK_TRUE)) &&
-               ((LinkSpeed != SK_LSPEED_AUTO) &&
-               (LinkSpeed != SK_LSPEED_1000MBPS))) {
-               printk("sk98lin: Illegal value for Speed_A. "
-                       "Not a copper card or GE V2 card\n    Using "
-                       "speed 1000\n");
-               LinkSpeed = SK_LSPEED_1000MBPS;
-       }
-       
-       /*      
-       ** Decide whether to set new config value if somethig valid has
-       ** been received.
-       */
-       if (IsLinkSpeedDefined) {
-               pAC->GIni.GP[0].PLinkSpeed = LinkSpeed;
-       } 
-
-       /* 
-       ** b) Any Autonegotiation and DuplexCapabilities set?
-       **    Please note that both belong together...
-       */
-       AutoNeg = AN_ON; /* tschilling: Default: Autonegotiation on! */
-       AutoSet = SK_FALSE;
-       if (AutoNeg_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
-               AutoNeg_A[pAC->Index] != NULL) {
-               AutoSet = SK_TRUE;
-               if (strcmp(AutoNeg_A[pAC->Index],"")==0) {
-                   AutoSet = SK_FALSE;
-               } else if (strcmp(AutoNeg_A[pAC->Index],"On")==0) {
-                   AutoNeg = AN_ON;
-               } else if (strcmp(AutoNeg_A[pAC->Index],"Off")==0) {
-                   AutoNeg = AN_OFF;
-               } else if (strcmp(AutoNeg_A[pAC->Index],"Sense")==0) {
-                   AutoNeg = AN_SENS;
-               } else {
-                   printk("sk98lin: Illegal value \"%s\" for AutoNeg_A\n",
-                       AutoNeg_A[pAC->Index]);
-               }
-       }
-
-       DuplexCap = DC_BOTH;
-       DupSet    = SK_FALSE;
-       if (DupCap_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
-               DupCap_A[pAC->Index] != NULL) {
-               DupSet = SK_TRUE;
-               if (strcmp(DupCap_A[pAC->Index],"")==0) {
-                   DupSet = SK_FALSE;
-               } else if (strcmp(DupCap_A[pAC->Index],"Both")==0) {
-                   DuplexCap = DC_BOTH;
-               } else if (strcmp(DupCap_A[pAC->Index],"Full")==0) {
-                   DuplexCap = DC_FULL;
-               } else if (strcmp(DupCap_A[pAC->Index],"Half")==0) {
-                   DuplexCap = DC_HALF;
-               } else {
-                   printk("sk98lin: Illegal value \"%s\" for DupCap_A\n",
-                       DupCap_A[pAC->Index]);
-               }
-       }
-
-       /* 
-       ** Check for illegal combinations 
-       */
-       if ((LinkSpeed == SK_LSPEED_1000MBPS) &&
-               ((DuplexCap == SK_LMODE_STAT_AUTOHALF) ||
-               (DuplexCap == SK_LMODE_STAT_HALF)) &&
-               (pAC->ChipsetType)) {
-                   printk("sk98lin: Half Duplex not possible with Gigabit speed!\n"
-                                       "    Using Full Duplex.\n");
-                               DuplexCap = DC_FULL;
-       }
-
-       if ( AutoSet && AutoNeg==AN_SENS && DupSet) {
-               printk("sk98lin, Port A: DuplexCapabilities"
-                       " ignored using Sense mode\n");
-       }
-
-       if (AutoSet && AutoNeg==AN_OFF && DupSet && DuplexCap==DC_BOTH){
-               printk("sk98lin: Port A: Illegal combination"
-                       " of values AutoNeg. and DuplexCap.\n    Using "
-                       "Full Duplex\n");
-               DuplexCap = DC_FULL;
-       }
-
-       if (AutoSet && AutoNeg==AN_OFF && !DupSet) {
-               DuplexCap = DC_FULL;
-       }
-       
-       if (!AutoSet && DupSet) {
-               printk("sk98lin: Port A: Duplex setting not"
-                       " possible in\n    default AutoNegotiation mode"
-                       " (Sense).\n    Using AutoNegotiation On\n");
-               AutoNeg = AN_ON;
-       }
-       
-       /* 
-       ** set the desired mode 
-       */
-       if (AutoSet || DupSet) {
-           pAC->GIni.GP[0].PLinkModeConf = Capabilities[AutoNeg][DuplexCap];
-       }
-       
-       /* 
-       ** c) Any Flowcontrol-parameter set?
-       */
-       if (FlowCtrl_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
-               FlowCtrl_A[pAC->Index] != NULL) {
-               if (strcmp(FlowCtrl_A[pAC->Index],"") == 0) {
-                   IsFlowCtrlDefined = SK_FALSE;
-               } else if (strcmp(FlowCtrl_A[pAC->Index],"SymOrRem") == 0) {
-                   FlowCtrl = SK_FLOW_MODE_SYM_OR_REM;
-               } else if (strcmp(FlowCtrl_A[pAC->Index],"Sym")==0) {
-                   FlowCtrl = SK_FLOW_MODE_SYMMETRIC;
-               } else if (strcmp(FlowCtrl_A[pAC->Index],"LocSend")==0) {
-                   FlowCtrl = SK_FLOW_MODE_LOC_SEND;
-               } else if (strcmp(FlowCtrl_A[pAC->Index],"None")==0) {
-                   FlowCtrl = SK_FLOW_MODE_NONE;
-               } else {
-                   printk("sk98lin: Illegal value \"%s\" for FlowCtrl_A\n",
-                        FlowCtrl_A[pAC->Index]);
-                   IsFlowCtrlDefined = SK_FALSE;
-               }
-       } else {
-          IsFlowCtrlDefined = SK_FALSE;
-       }
-
-       if (IsFlowCtrlDefined) {
-           if ((AutoNeg == AN_OFF) && (FlowCtrl != SK_FLOW_MODE_NONE)) {
-               printk("sk98lin: Port A: FlowControl"
-                       " impossible without AutoNegotiation,"
-                       " disabled\n");
-               FlowCtrl = SK_FLOW_MODE_NONE;
-           }
-           pAC->GIni.GP[0].PFlowCtrlMode = FlowCtrl;
-       }
-
-       /*
-       ** d) What is with the RoleParameter?
-       */
-       if (Role_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
-               Role_A[pAC->Index] != NULL) {
-               if (strcmp(Role_A[pAC->Index],"")==0) {
-                  IsRoleDefined = SK_FALSE;
-               } else if (strcmp(Role_A[pAC->Index],"Auto")==0) {
-                   MSMode = SK_MS_MODE_AUTO;
-               } else if (strcmp(Role_A[pAC->Index],"Master")==0) {
-                   MSMode = SK_MS_MODE_MASTER;
-               } else if (strcmp(Role_A[pAC->Index],"Slave")==0) {
-                   MSMode = SK_MS_MODE_SLAVE;
-               } else {
-                   printk("sk98lin: Illegal value \"%s\" for Role_A\n",
-                       Role_A[pAC->Index]);
-                   IsRoleDefined = SK_FALSE;
-               }
-       } else {
-          IsRoleDefined = SK_FALSE;
-       }
-
-       if (IsRoleDefined == SK_TRUE) {
-           pAC->GIni.GP[0].PMSMode = MSMode;
-       }
-       
-
-       
-       /* 
-       ** Parse any parameter settings for port B:
-       ** a) any LinkSpeed stated?
-       */
-       IsConTypeDefined   = SK_TRUE;
-       IsLinkSpeedDefined = SK_TRUE;
-       IsFlowCtrlDefined  = SK_TRUE;
-       IsModeDefined      = SK_TRUE;
-
-       if (Speed_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
-               Speed_B[pAC->Index] != NULL) {
-               if (strcmp(Speed_B[pAC->Index],"")==0) {
-                   IsLinkSpeedDefined = SK_FALSE;
-               } else if (strcmp(Speed_B[pAC->Index],"Auto")==0) {
-                   LinkSpeed = SK_LSPEED_AUTO;
-               } else if (strcmp(Speed_B[pAC->Index],"10")==0) {
-                   LinkSpeed = SK_LSPEED_10MBPS;
-               } else if (strcmp(Speed_B[pAC->Index],"100")==0) {
-                   LinkSpeed = SK_LSPEED_100MBPS;
-               } else if (strcmp(Speed_B[pAC->Index],"1000")==0) {
-                   LinkSpeed = SK_LSPEED_1000MBPS;
-               } else {
-                   printk("sk98lin: Illegal value \"%s\" for Speed_B\n",
-                       Speed_B[pAC->Index]);
-                   IsLinkSpeedDefined = SK_FALSE;
-               }
-       } else {
-           IsLinkSpeedDefined = SK_FALSE;
-       }
-
-       /* 
-       ** Check speed parameter:
-       **    Only copper type adapter and GE V2 cards 
-       */
-       if (((!pAC->ChipsetType) || (pAC->GIni.GICopperType != SK_TRUE)) &&
-               ((LinkSpeed != SK_LSPEED_AUTO) &&
-               (LinkSpeed != SK_LSPEED_1000MBPS))) {
-               printk("sk98lin: Illegal value for Speed_B. "
-                       "Not a copper card or GE V2 card\n    Using "
-                       "speed 1000\n");
-               LinkSpeed = SK_LSPEED_1000MBPS;
-       }
-
-       /*      
-       ** Decide whether to set new config value if somethig valid has
-       ** been received.
-       */
-        if (IsLinkSpeedDefined) {
-           pAC->GIni.GP[1].PLinkSpeed = LinkSpeed;
-       }
-
-       /* 
-       ** b) Any Autonegotiation and DuplexCapabilities set?
-       **    Please note that both belong together...
-       */
-       AutoNeg = AN_SENS; /* default: do auto Sense */
-       AutoSet = SK_FALSE;
-       if (AutoNeg_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
-               AutoNeg_B[pAC->Index] != NULL) {
-               AutoSet = SK_TRUE;
-               if (strcmp(AutoNeg_B[pAC->Index],"")==0) {
-                   AutoSet = SK_FALSE;
-               } else if (strcmp(AutoNeg_B[pAC->Index],"On")==0) {
-                   AutoNeg = AN_ON;
-               } else if (strcmp(AutoNeg_B[pAC->Index],"Off")==0) {
-                   AutoNeg = AN_OFF;
-               } else if (strcmp(AutoNeg_B[pAC->Index],"Sense")==0) {
-                   AutoNeg = AN_SENS;
-               } else {
-                   printk("sk98lin: Illegal value \"%s\" for AutoNeg_B\n",
-                       AutoNeg_B[pAC->Index]);
-               }
-       }
-
-       DuplexCap = DC_BOTH;
-       DupSet    = SK_FALSE;
-       if (DupCap_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
-               DupCap_B[pAC->Index] != NULL) {
-               DupSet = SK_TRUE;
-               if (strcmp(DupCap_B[pAC->Index],"")==0) {
-                   DupSet = SK_FALSE;
-               } else if (strcmp(DupCap_B[pAC->Index],"Both")==0) {
-                   DuplexCap = DC_BOTH;
-               } else if (strcmp(DupCap_B[pAC->Index],"Full")==0) {
-                   DuplexCap = DC_FULL;
-               } else if (strcmp(DupCap_B[pAC->Index],"Half")==0) {
-                   DuplexCap = DC_HALF;
-               } else {
-                   printk("sk98lin: Illegal value \"%s\" for DupCap_B\n",
-                       DupCap_B[pAC->Index]);
-               }
-       }
-
-       
-       /* 
-       ** Check for illegal combinations 
-       */
-       if ((LinkSpeed == SK_LSPEED_1000MBPS) &&
-               ((DuplexCap == SK_LMODE_STAT_AUTOHALF) ||
-               (DuplexCap == SK_LMODE_STAT_HALF)) &&
-               (pAC->ChipsetType)) {
-                   printk("sk98lin: Half Duplex not possible with Gigabit speed!\n"
-                                       "    Using Full Duplex.\n");
-                               DuplexCap = DC_FULL;
-       }
-
-       if (AutoSet && AutoNeg==AN_SENS && DupSet) {
-               printk("sk98lin, Port B: DuplexCapabilities"
-                       " ignored using Sense mode\n");
-       }
-
-       if (AutoSet && AutoNeg==AN_OFF && DupSet && DuplexCap==DC_BOTH){
-               printk("sk98lin: Port B: Illegal combination"
-                       " of values AutoNeg. and DuplexCap.\n    Using "
-                       "Full Duplex\n");
-               DuplexCap = DC_FULL;
-       }
-
-       if (AutoSet && AutoNeg==AN_OFF && !DupSet) {
-               DuplexCap = DC_FULL;
-       }
-       
-       if (!AutoSet && DupSet) {
-               printk("sk98lin: Port B: Duplex setting not"
-                       " possible in\n    default AutoNegotiation mode"
-                       " (Sense).\n    Using AutoNegotiation On\n");
-               AutoNeg = AN_ON;
-       }
-
-       /* 
-       ** set the desired mode 
-       */
-       if (AutoSet || DupSet) {
-           pAC->GIni.GP[1].PLinkModeConf = Capabilities[AutoNeg][DuplexCap];
-       }
-
-       /*
-       ** c) Any FlowCtrl parameter set?
-       */
-       if (FlowCtrl_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
-               FlowCtrl_B[pAC->Index] != NULL) {
-               if (strcmp(FlowCtrl_B[pAC->Index],"") == 0) {
-                   IsFlowCtrlDefined = SK_FALSE;
-               } else if (strcmp(FlowCtrl_B[pAC->Index],"SymOrRem") == 0) {
-                   FlowCtrl = SK_FLOW_MODE_SYM_OR_REM;
-               } else if (strcmp(FlowCtrl_B[pAC->Index],"Sym")==0) {
-                   FlowCtrl = SK_FLOW_MODE_SYMMETRIC;
-               } else if (strcmp(FlowCtrl_B[pAC->Index],"LocSend")==0) {
-                   FlowCtrl = SK_FLOW_MODE_LOC_SEND;
-               } else if (strcmp(FlowCtrl_B[pAC->Index],"None")==0) {
-                   FlowCtrl = SK_FLOW_MODE_NONE;
-               } else {
-                   printk("sk98lin: Illegal value \"%s\" for FlowCtrl_B\n",
-                       FlowCtrl_B[pAC->Index]);
-                   IsFlowCtrlDefined = SK_FALSE;
-               }
-       } else {
-               IsFlowCtrlDefined = SK_FALSE;
-       }
-
-       if (IsFlowCtrlDefined) {
-           if ((AutoNeg == AN_OFF) && (FlowCtrl != SK_FLOW_MODE_NONE)) {
-               printk("sk98lin: Port B: FlowControl"
-                       " impossible without AutoNegotiation,"
-                       " disabled\n");
-               FlowCtrl = SK_FLOW_MODE_NONE;
-           }
-           pAC->GIni.GP[1].PFlowCtrlMode = FlowCtrl;
-       }
-
-       /*
-       ** d) What is the RoleParameter?
-       */
-       if (Role_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
-               Role_B[pAC->Index] != NULL) {
-               if (strcmp(Role_B[pAC->Index],"")==0) {
-                   IsRoleDefined = SK_FALSE;
-               } else if (strcmp(Role_B[pAC->Index],"Auto")==0) {
-                   MSMode = SK_MS_MODE_AUTO;
-               } else if (strcmp(Role_B[pAC->Index],"Master")==0) {
-                   MSMode = SK_MS_MODE_MASTER;
-               } else if (strcmp(Role_B[pAC->Index],"Slave")==0) {
-                   MSMode = SK_MS_MODE_SLAVE;
-               } else {
-                   printk("sk98lin: Illegal value \"%s\" for Role_B\n",
-                       Role_B[pAC->Index]);
-                   IsRoleDefined = SK_FALSE;
-               }
-       } else {
-           IsRoleDefined = SK_FALSE;
-       }
-
-       if (IsRoleDefined) {
-           pAC->GIni.GP[1].PMSMode = MSMode;
-       }
-       
-       /*
-       ** Evaluate settings for both ports
-       */
-       pAC->ActivePort = 0;
-       if (PrefPort != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
-               PrefPort[pAC->Index] != NULL) {
-               if (strcmp(PrefPort[pAC->Index],"") == 0) { /* Auto */
-                       pAC->ActivePort             =  0;
-                       pAC->Rlmt.Net[0].Preference = -1; /* auto */
-                       pAC->Rlmt.Net[0].PrefPort   =  0;
-               } else if (strcmp(PrefPort[pAC->Index],"A") == 0) {
-                       /*
-                       ** do not set ActivePort here, thus a port
-                       ** switch is issued after net up.
-                       */
-                       Port                        = 0;
-                       pAC->Rlmt.Net[0].Preference = Port;
-                       pAC->Rlmt.Net[0].PrefPort   = Port;
-               } else if (strcmp(PrefPort[pAC->Index],"B") == 0) {
-                       /*
-                       ** do not set ActivePort here, thus a port
-                       ** switch is issued after net up.
-                       */
-                       if (pAC->GIni.GIMacsFound == 1) {
-                               printk("sk98lin: Illegal value \"B\" for PrefPort.\n"
-                                       "      Port B not available on single port adapters.\n");
-
-                               pAC->ActivePort             =  0;
-                               pAC->Rlmt.Net[0].Preference = -1; /* auto */
-                               pAC->Rlmt.Net[0].PrefPort   =  0;
-                       } else {
-                               Port                        = 1;
-                               pAC->Rlmt.Net[0].Preference = Port;
-                               pAC->Rlmt.Net[0].PrefPort   = Port;
-                       }
-               } else {
-                   printk("sk98lin: Illegal value \"%s\" for PrefPort\n",
-                       PrefPort[pAC->Index]);
-               }
-       }
-
-       pAC->RlmtNets = 1;
-
-       if (RlmtMode != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
-               RlmtMode[pAC->Index] != NULL) {
-               if (strcmp(RlmtMode[pAC->Index], "") == 0) {
-                       pAC->RlmtMode = 0;
-               } else if (strcmp(RlmtMode[pAC->Index], "CheckLinkState") == 0) {
-                       pAC->RlmtMode = SK_RLMT_CHECK_LINK;
-               } else if (strcmp(RlmtMode[pAC->Index], "CheckLocalPort") == 0) {
-                       pAC->RlmtMode = SK_RLMT_CHECK_LINK |
-                                       SK_RLMT_CHECK_LOC_LINK;
-               } else if (strcmp(RlmtMode[pAC->Index], "CheckSeg") == 0) {
-                       pAC->RlmtMode = SK_RLMT_CHECK_LINK     |
-                                       SK_RLMT_CHECK_LOC_LINK |
-                                       SK_RLMT_CHECK_SEG;
-               } else if ((strcmp(RlmtMode[pAC->Index], "DualNet") == 0) &&
-                       (pAC->GIni.GIMacsFound == 2)) {
-                       pAC->RlmtMode = SK_RLMT_CHECK_LINK;
-                       pAC->RlmtNets = 2;
-               } else {
-                   printk("sk98lin: Illegal value \"%s\" for"
-                       " RlmtMode, using default\n", 
-                       RlmtMode[pAC->Index]);
-                       pAC->RlmtMode = 0;
-               }
-       } else {
-               pAC->RlmtMode = 0;
-       }
-       
-       /*
-       ** Check the interrupt moderation parameters
-       */
-       if (Moderation[pAC->Index] != NULL) {
-               if (strcmp(Moderation[pAC->Index], "") == 0) {
-                       pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
-               } else if (strcmp(Moderation[pAC->Index], "Static") == 0) {
-                       pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_STATIC;
-               } else if (strcmp(Moderation[pAC->Index], "Dynamic") == 0) {
-                       pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_DYNAMIC;
-               } else if (strcmp(Moderation[pAC->Index], "None") == 0) {
-                       pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
-               } else {
-                       printk("sk98lin: Illegal value \"%s\" for Moderation.\n"
-                               "      Disable interrupt moderation.\n",
-                               Moderation[pAC->Index]);
-                       pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
-               }
-       } else {
-               pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
-       }
-
-       if (Stats[pAC->Index] != NULL) {
-               if (strcmp(Stats[pAC->Index], "Yes") == 0) {
-                       pAC->DynIrqModInfo.DisplayStats = SK_TRUE;
-               } else {
-                       pAC->DynIrqModInfo.DisplayStats = SK_FALSE;
-               }
-       } else {
-               pAC->DynIrqModInfo.DisplayStats = SK_FALSE;
-       }
-
-       if (ModerationMask[pAC->Index] != NULL) {
-               if (strcmp(ModerationMask[pAC->Index], "Rx") == 0) {
-                       pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY;
-               } else if (strcmp(ModerationMask[pAC->Index], "Tx") == 0) {
-                       pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_ONLY;
-               } else if (strcmp(ModerationMask[pAC->Index], "Sp") == 0) {
-                       pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_ONLY;
-               } else if (strcmp(ModerationMask[pAC->Index], "RxSp") == 0) {
-                       pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX;
-               } else if (strcmp(ModerationMask[pAC->Index], "SpRx") == 0) {
-                       pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX;
-               } else if (strcmp(ModerationMask[pAC->Index], "RxTx") == 0) {
-                       pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
-               } else if (strcmp(ModerationMask[pAC->Index], "TxRx") == 0) {
-                       pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
-               } else if (strcmp(ModerationMask[pAC->Index], "TxSp") == 0) {
-                       pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX;
-               } else if (strcmp(ModerationMask[pAC->Index], "SpTx") == 0) {
-                       pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX;
-               } else if (strcmp(ModerationMask[pAC->Index], "RxTxSp") == 0) {
-                       pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
-               } else if (strcmp(ModerationMask[pAC->Index], "RxSpTx") == 0) {
-                       pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
-               } else if (strcmp(ModerationMask[pAC->Index], "TxRxSp") == 0) {
-                       pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
-               } else if (strcmp(ModerationMask[pAC->Index], "TxSpRx") == 0) {
-                       pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
-               } else if (strcmp(ModerationMask[pAC->Index], "SpTxRx") == 0) {
-                       pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
-               } else if (strcmp(ModerationMask[pAC->Index], "SpRxTx") == 0) {
-                       pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
-               } else { /* some rubbish */
-                       pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY;
-               }
-       } else {  /* operator has stated nothing */
-               pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
-       }
-
-       if (AutoSizing[pAC->Index] != NULL) {
-               if (strcmp(AutoSizing[pAC->Index], "On") == 0) {
-                       pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
-               } else {
-                       pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
-               }
-       } else {  /* operator has stated nothing */
-               pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
-       }
-
-       if (IntsPerSec[pAC->Index] != 0) {
-               if ((IntsPerSec[pAC->Index]< C_INT_MOD_IPS_LOWER_RANGE) || 
-                       (IntsPerSec[pAC->Index] > C_INT_MOD_IPS_UPPER_RANGE)) {
-                       printk("sk98lin: Illegal value \"%d\" for IntsPerSec. (Range: %d - %d)\n"
-                               "      Using default value of %i.\n", 
-                               IntsPerSec[pAC->Index],
-                               C_INT_MOD_IPS_LOWER_RANGE,
-                               C_INT_MOD_IPS_UPPER_RANGE,
-                               C_INTS_PER_SEC_DEFAULT);
-                       pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT;
-               } else {
-                       pAC->DynIrqModInfo.MaxModIntsPerSec = IntsPerSec[pAC->Index];
-               }
-       } else {
-               pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT;
-       }
-
-       /*
-       ** Evaluate upper and lower moderation threshold
-       */
-       pAC->DynIrqModInfo.MaxModIntsPerSecUpperLimit =
-               pAC->DynIrqModInfo.MaxModIntsPerSec +
-               (pAC->DynIrqModInfo.MaxModIntsPerSec / 2);
-
-       pAC->DynIrqModInfo.MaxModIntsPerSecLowerLimit =
-               pAC->DynIrqModInfo.MaxModIntsPerSec -
-               (pAC->DynIrqModInfo.MaxModIntsPerSec / 2);
-
-       pAC->DynIrqModInfo.PrevTimeVal = jiffies;  /* initial value */
-
-
-} /* GetConfiguration */
-
-
-/*****************************************************************************
- *
- *     ProductStr - return a adapter identification string from vpd
- *
- * Description:
- *     This function reads the product name string from the vpd area
- *     and puts it the field pAC->DeviceString.
- *
- * Returns: N/A
- */
-static inline int ProductStr(
-       SK_AC   *pAC,           /* pointer to adapter context */
-       char    *DeviceStr,     /* result string */
-       int      StrLen         /* length of the string */
-)
-{
-char   Keyword[] = VPD_NAME;   /* vpd productname identifier */
-int    ReturnCode;             /* return code from vpd_read */
-unsigned long Flags;
-
-       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-       ReturnCode = VpdRead(pAC, pAC->IoBase, Keyword, DeviceStr, &StrLen);
-       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-
-       return ReturnCode;
-} /* ProductStr */
-
-/*****************************************************************************
- *
- *      StartDrvCleanupTimer - Start timer to check for descriptors which
- *                             might be placed in descriptor ring, but
- *                             havent been handled up to now
- *
- * Description:
- *      This function requests a HW-timer fo the Yukon card. The actions to
- *      perform when this timer expires, are located in the SkDrvEvent().
- *
- * Returns: N/A
- */
-static void
-StartDrvCleanupTimer(SK_AC *pAC) {
-    SK_EVPARA    EventParam;   /* Event struct for timer event */
-
-    SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
-    EventParam.Para32[0] = SK_DRV_RX_CLEANUP_TIMER;
-    SkTimerStart(pAC, pAC->IoBase, &pAC->DrvCleanupTimer,
-                 SK_DRV_RX_CLEANUP_TIMER_LENGTH,
-                 SKGE_DRV, SK_DRV_TIMER, EventParam);
-}
-
-/*****************************************************************************
- *
- *      StopDrvCleanupTimer - Stop timer to check for descriptors
- *
- * Description:
- *      This function requests a HW-timer fo the Yukon card. The actions to
- *      perform when this timer expires, are located in the SkDrvEvent().
- *
- * Returns: N/A
- */
-static void
-StopDrvCleanupTimer(SK_AC *pAC) {
-    SkTimerStop(pAC, pAC->IoBase, &pAC->DrvCleanupTimer);
-    SK_MEMSET((char *) &pAC->DrvCleanupTimer, 0, sizeof(SK_TIMER));
-}
-
-/****************************************************************************/
-/* functions for common modules *********************************************/
-/****************************************************************************/
-
-
-/*****************************************************************************
- *
- *     SkDrvAllocRlmtMbuf - allocate an RLMT mbuf
- *
- * Description:
- *     This routine returns an RLMT mbuf or NULL. The RLMT Mbuf structure
- *     is embedded into a socket buff data area.
- *
- * Context:
- *     runtime
- *
- * Returns:
- *     NULL or pointer to Mbuf.
- */
-SK_MBUF *SkDrvAllocRlmtMbuf(
-SK_AC          *pAC,           /* pointer to adapter context */
-SK_IOC         IoC,            /* the IO-context */
-unsigned       BufferSize)     /* size of the requested buffer */
-{
-SK_MBUF                *pRlmtMbuf;     /* pointer to a new rlmt-mbuf structure */
-struct sk_buff *pMsgBlock;     /* pointer to a new message block */
-
-       pMsgBlock = alloc_skb(BufferSize + sizeof(SK_MBUF), GFP_ATOMIC);
-       if (pMsgBlock == NULL) {
-               return (NULL);
-       }
-       pRlmtMbuf = (SK_MBUF*) pMsgBlock->data;
-       skb_reserve(pMsgBlock, sizeof(SK_MBUF));
-       pRlmtMbuf->pNext = NULL;
-       pRlmtMbuf->pOs = pMsgBlock;
-       pRlmtMbuf->pData = pMsgBlock->data;     /* Data buffer. */
-       pRlmtMbuf->Size = BufferSize;           /* Data buffer size. */
-       pRlmtMbuf->Length = 0;          /* Length of packet (<= Size). */
-       return (pRlmtMbuf);
-
-} /* SkDrvAllocRlmtMbuf */
-
-
-/*****************************************************************************
- *
- *     SkDrvFreeRlmtMbuf - free an RLMT mbuf
- *
- * Description:
- *     This routine frees one or more RLMT mbuf(s).
- *
- * Context:
- *     runtime
- *
- * Returns:
- *     Nothing
- */
-void  SkDrvFreeRlmtMbuf(
-SK_AC          *pAC,           /* pointer to adapter context */
-SK_IOC         IoC,            /* the IO-context */
-SK_MBUF                *pMbuf)         /* size of the requested buffer */
-{
-SK_MBUF                *pFreeMbuf;
-SK_MBUF                *pNextMbuf;
-
-       pFreeMbuf = pMbuf;
-       do {
-               pNextMbuf = pFreeMbuf->pNext;
-               DEV_KFREE_SKB_ANY(pFreeMbuf->pOs);
-               pFreeMbuf = pNextMbuf;
-       } while ( pFreeMbuf != NULL );
-} /* SkDrvFreeRlmtMbuf */
-
-
-/*****************************************************************************
- *
- *     SkOsGetTime - provide a time value
- *
- * Description:
- *     This routine provides a time value. The unit is 1/HZ (defined by Linux).
- *     It is not used for absolute time, but only for time differences.
- *
- *
- * Returns:
- *     Time value
- */
-SK_U64 SkOsGetTime(SK_AC *pAC)
-{
-       SK_U64  PrivateJiffies;
-       SkOsGetTimeCurrent(pAC, &PrivateJiffies);
-       return PrivateJiffies;
-} /* SkOsGetTime */
-
-
-/*****************************************************************************
- *
- *     SkPciReadCfgDWord - read a 32 bit value from pci config space
- *
- * Description:
- *     This routine reads a 32 bit value from the pci configuration
- *     space.
- *
- * Returns:
- *     0 - indicate everything worked ok.
- *     != 0 - error indication
- */
-int SkPciReadCfgDWord(
-SK_AC *pAC,            /* Adapter Control structure pointer */
-int PciAddr,           /* PCI register address */
-SK_U32 *pVal)          /* pointer to store the read value */
-{
-       pci_read_config_dword(pAC->PciDev, PciAddr, pVal);
-       return(0);
-} /* SkPciReadCfgDWord */
-
-
-/*****************************************************************************
- *
- *     SkPciReadCfgWord - read a 16 bit value from pci config space
- *
- * Description:
- *     This routine reads a 16 bit value from the pci configuration
- *     space.
- *
- * Returns:
- *     0 - indicate everything worked ok.
- *     != 0 - error indication
- */
-int SkPciReadCfgWord(
-SK_AC *pAC,    /* Adapter Control structure pointer */
-int PciAddr,           /* PCI register address */
-SK_U16 *pVal)          /* pointer to store the read value */
-{
-       pci_read_config_word(pAC->PciDev, PciAddr, pVal);
-       return(0);
-} /* SkPciReadCfgWord */
-
-
-/*****************************************************************************
- *
- *     SkPciReadCfgByte - read a 8 bit value from pci config space
- *
- * Description:
- *     This routine reads a 8 bit value from the pci configuration
- *     space.
- *
- * Returns:
- *     0 - indicate everything worked ok.
- *     != 0 - error indication
- */
-int SkPciReadCfgByte(
-SK_AC *pAC,    /* Adapter Control structure pointer */
-int PciAddr,           /* PCI register address */
-SK_U8 *pVal)           /* pointer to store the read value */
-{
-       pci_read_config_byte(pAC->PciDev, PciAddr, pVal);
-       return(0);
-} /* SkPciReadCfgByte */
-
-
-/*****************************************************************************
- *
- *     SkPciWriteCfgWord - write a 16 bit value to pci config space
- *
- * Description:
- *     This routine writes a 16 bit value to the pci configuration
- *     space. The flag PciConfigUp indicates whether the config space
- *     is accesible or must be set up first.
- *
- * Returns:
- *     0 - indicate everything worked ok.
- *     != 0 - error indication
- */
-int SkPciWriteCfgWord(
-SK_AC *pAC,    /* Adapter Control structure pointer */
-int PciAddr,           /* PCI register address */
-SK_U16 Val)            /* pointer to store the read value */
-{
-       pci_write_config_word(pAC->PciDev, PciAddr, Val);
-       return(0);
-} /* SkPciWriteCfgWord */
-
-
-/*****************************************************************************
- *
- *     SkPciWriteCfgWord - write a 8 bit value to pci config space
- *
- * Description:
- *     This routine writes a 8 bit value to the pci configuration
- *     space. The flag PciConfigUp indicates whether the config space
- *     is accesible or must be set up first.
- *
- * Returns:
- *     0 - indicate everything worked ok.
- *     != 0 - error indication
- */
-int SkPciWriteCfgByte(
-SK_AC *pAC,    /* Adapter Control structure pointer */
-int PciAddr,           /* PCI register address */
-SK_U8 Val)             /* pointer to store the read value */
-{
-       pci_write_config_byte(pAC->PciDev, PciAddr, Val);
-       return(0);
-} /* SkPciWriteCfgByte */
-
-
-/*****************************************************************************
- *
- *     SkDrvEvent - handle driver events
- *
- * Description:
- *     This function handles events from all modules directed to the driver
- *
- * Context:
- *     Is called under protection of slow path lock.
- *
- * Returns:
- *     0 if everything ok
- *     < 0  on error
- *     
- */
-int SkDrvEvent(
-SK_AC *pAC,            /* pointer to adapter context */
-SK_IOC IoC,            /* io-context */
-SK_U32 Event,          /* event-id */
-SK_EVPARA Param)       /* event-parameter */
-{
-SK_MBUF                *pRlmtMbuf;     /* pointer to a rlmt-mbuf structure */
-struct sk_buff *pMsg;          /* pointer to a message block */
-int            FromPort;       /* the port from which we switch away */
-int            ToPort;         /* the port we switch to */
-SK_EVPARA      NewPara;        /* parameter for further events */
-int            Stat;
-unsigned long  Flags;
-SK_BOOL                DualNet;
-
-       switch (Event) {
-       case SK_DRV_ADAP_FAIL:
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
-                       ("ADAPTER FAIL EVENT\n"));
-               printk("%s: Adapter failed.\n", pAC->dev[0]->name);
-               /* disable interrupts */
-               SK_OUT32(pAC->IoBase, B0_IMSK, 0);
-               /* cgoos */
-               break;
-       case SK_DRV_PORT_FAIL:
-               FromPort = Param.Para32[0];
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
-                       ("PORT FAIL EVENT, Port: %d\n", FromPort));
-               if (FromPort == 0) {
-                       printk("%s: Port A failed.\n", pAC->dev[0]->name);
-               } else {
-                       printk("%s: Port B failed.\n", pAC->dev[1]->name);
-               }
-               /* cgoos */
-               break;
-       case SK_DRV_PORT_RESET:  /* SK_U32 PortIdx */
-               /* action list 4 */
-               FromPort = Param.Para32[0];
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
-                       ("PORT RESET EVENT, Port: %d ", FromPort));
-               NewPara.Para64 = FromPort;
-               SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara);
-               spin_lock_irqsave(
-                       &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
-                       Flags);
-
-               SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_HARD_RST);
-               netif_carrier_off(pAC->dev[Param.Para32[0]]);
-               spin_unlock_irqrestore(
-                       &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
-                       Flags);
-               
-               /* clear rx ring from received frames */
-               ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE);
-               
-               ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]);
-               spin_lock_irqsave(
-                       &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
-                       Flags);
-               
-               /* tschilling: Handling of return value inserted. */
-               if (SkGeInitPort(pAC, IoC, FromPort)) {
-                       if (FromPort == 0) {
-                               printk("%s: SkGeInitPort A failed.\n", pAC->dev[0]->name);
-                       } else {
-                               printk("%s: SkGeInitPort B failed.\n", pAC->dev[1]->name);
-                       }
-               }
-               SkAddrMcUpdate(pAC,IoC, FromPort);
-               PortReInitBmu(pAC, FromPort);
-               SkGePollTxD(pAC, IoC, FromPort, SK_TRUE);
-               ClearAndStartRx(pAC, FromPort);
-               spin_unlock_irqrestore(
-                       &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
-                       Flags);
-               break;
-       case SK_DRV_NET_UP:      /* SK_U32 PortIdx */
-       {       struct net_device *dev = pAC->dev[Param.Para32[0]];
-               /* action list 5 */
-               FromPort = Param.Para32[0];
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
-                       ("NET UP EVENT, Port: %d ", Param.Para32[0]));
-               /* Mac update */
-               SkAddrMcUpdate(pAC,IoC, FromPort);
-
-               if (DoPrintInterfaceChange) {
-               printk("%s: network connection up using"
-                       " port %c\n", pAC->dev[Param.Para32[0]]->name, 'A'+Param.Para32[0]);
-
-               /* tschilling: Values changed according to LinkSpeedUsed. */
-               Stat = pAC->GIni.GP[FromPort].PLinkSpeedUsed;
-               if (Stat == SK_LSPEED_STAT_10MBPS) {
-                       printk("    speed:           10\n");
-               } else if (Stat == SK_LSPEED_STAT_100MBPS) {
-                       printk("    speed:           100\n");
-               } else if (Stat == SK_LSPEED_STAT_1000MBPS) {
-                       printk("    speed:           1000\n");
-               } else {
-                       printk("    speed:           unknown\n");
-               }
-
-
-               Stat = pAC->GIni.GP[FromPort].PLinkModeStatus;
-               if (Stat == SK_LMODE_STAT_AUTOHALF ||
-                       Stat == SK_LMODE_STAT_AUTOFULL) {
-                       printk("    autonegotiation: yes\n");
-               }
-               else {
-                       printk("    autonegotiation: no\n");
-               }
-               if (Stat == SK_LMODE_STAT_AUTOHALF ||
-                       Stat == SK_LMODE_STAT_HALF) {
-                       printk("    duplex mode:     half\n");
-               }
-               else {
-                       printk("    duplex mode:     full\n");
-               }
-               Stat = pAC->GIni.GP[FromPort].PFlowCtrlStatus;
-               if (Stat == SK_FLOW_STAT_REM_SEND ) {
-                       printk("    flowctrl:        remote send\n");
-               }
-               else if (Stat == SK_FLOW_STAT_LOC_SEND ){
-                       printk("    flowctrl:        local send\n");
-               }
-               else if (Stat == SK_FLOW_STAT_SYMMETRIC ){
-                       printk("    flowctrl:        symmetric\n");
-               }
-               else {
-                       printk("    flowctrl:        none\n");
-               }
-               
-               /* tschilling: Check against CopperType now. */
-               if ((pAC->GIni.GICopperType == SK_TRUE) &&
-                       (pAC->GIni.GP[FromPort].PLinkSpeedUsed ==
-                       SK_LSPEED_STAT_1000MBPS)) {
-                       Stat = pAC->GIni.GP[FromPort].PMSStatus;
-                       if (Stat == SK_MS_STAT_MASTER ) {
-                               printk("    role:            master\n");
-                       }
-                       else if (Stat == SK_MS_STAT_SLAVE ) {
-                               printk("    role:            slave\n");
-                       }
-                       else {
-                               printk("    role:            ???\n");
-                       }
-               }
-
-               /* 
-                  Display dim (dynamic interrupt moderation) 
-                  informations
-                */
-               if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_STATIC)
-                       printk("    irq moderation:  static (%d ints/sec)\n",
-                                       pAC->DynIrqModInfo.MaxModIntsPerSec);
-               else if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_DYNAMIC)
-                       printk("    irq moderation:  dynamic (%d ints/sec)\n",
-                                       pAC->DynIrqModInfo.MaxModIntsPerSec);
-               else
-                       printk("    irq moderation:  disabled\n");
-
-
-               printk("    scatter-gather:  %s\n",
-                      (dev->features & NETIF_F_SG) ? "enabled" : "disabled");
-               printk("    tx-checksum:     %s\n",
-                      (dev->features & NETIF_F_IP_CSUM) ? "enabled" : "disabled");
-               printk("    rx-checksum:     %s\n",
-                      pAC->RxPort[Param.Para32[0]].RxCsum ? "enabled" : "disabled");
-
-               } else {
-                        DoPrintInterfaceChange = SK_TRUE;
-                }
-       
-               if ((Param.Para32[0] != pAC->ActivePort) &&
-                       (pAC->RlmtNets == 1)) {
-                       NewPara.Para32[0] = pAC->ActivePort;
-                       NewPara.Para32[1] = Param.Para32[0];
-                       SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_INTERN,
-                               NewPara);
-               }
-
-               /* Inform the world that link protocol is up. */
-               netif_carrier_on(dev);
-               break;
-       }
-       case SK_DRV_NET_DOWN:    /* SK_U32 Reason */
-               /* action list 7 */
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
-                       ("NET DOWN EVENT "));
-               if (DoPrintInterfaceChange) {
-                       printk("%s: network connection down\n", 
-                               pAC->dev[Param.Para32[1]]->name);
-               } else {
-                       DoPrintInterfaceChange = SK_TRUE;
-               }
-               netif_carrier_off(pAC->dev[Param.Para32[1]]);
-               break;
-       case SK_DRV_SWITCH_HARD: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
-                       ("PORT SWITCH HARD "));
-       case SK_DRV_SWITCH_SOFT: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
-       /* action list 6 */
-               printk("%s: switching to port %c\n", pAC->dev[0]->name,
-                       'A'+Param.Para32[1]);
-       case SK_DRV_SWITCH_INTERN: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
-               FromPort = Param.Para32[0];
-               ToPort = Param.Para32[1];
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
-                       ("PORT SWITCH EVENT, From: %d  To: %d (Pref %d) ",
-                       FromPort, ToPort, pAC->Rlmt.Net[0].PrefPort));
-               NewPara.Para64 = FromPort;
-               SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara);
-               NewPara.Para64 = ToPort;
-               SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara);
-               spin_lock_irqsave(
-                       &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
-                       Flags);
-               spin_lock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
-               SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_SOFT_RST);
-               SkGeStopPort(pAC, IoC, ToPort, SK_STOP_ALL, SK_SOFT_RST);
-               spin_unlock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
-               spin_unlock_irqrestore(
-                       &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
-                       Flags);
-
-               ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE); /* clears rx ring */
-               ReceiveIrq(pAC, &pAC->RxPort[ToPort], SK_FALSE); /* clears rx ring */
-               
-               ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]);
-               ClearTxRing(pAC, &pAC->TxPort[ToPort][TX_PRIO_LOW]);
-               spin_lock_irqsave(
-                       &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
-                       Flags);
-               spin_lock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
-               pAC->ActivePort = ToPort;
-#if 0
-               SetQueueSizes(pAC);
-#else
-               /* tschilling: New common function with minimum size check. */
-               DualNet = SK_FALSE;
-               if (pAC->RlmtNets == 2) {
-                       DualNet = SK_TRUE;
-               }
-               
-               if (SkGeInitAssignRamToQueues(
-                       pAC,
-                       pAC->ActivePort,
-                       DualNet)) {
-                       spin_unlock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
-                       spin_unlock_irqrestore(
-                               &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
-                               Flags);
-                       printk("SkGeInitAssignRamToQueues failed.\n");
-                       break;
-               }
-#endif
-               /* tschilling: Handling of return values inserted. */
-               if (SkGeInitPort(pAC, IoC, FromPort) ||
-                       SkGeInitPort(pAC, IoC, ToPort)) {
-                       printk("%s: SkGeInitPort failed.\n", pAC->dev[0]->name);
-               }
-               if (Event == SK_DRV_SWITCH_SOFT) {
-                       SkMacRxTxEnable(pAC, IoC, FromPort);
-               }
-               SkMacRxTxEnable(pAC, IoC, ToPort);
-               SkAddrSwap(pAC, IoC, FromPort, ToPort);
-               SkAddrMcUpdate(pAC, IoC, FromPort);
-               SkAddrMcUpdate(pAC, IoC, ToPort);
-               PortReInitBmu(pAC, FromPort);
-               PortReInitBmu(pAC, ToPort);
-               SkGePollTxD(pAC, IoC, FromPort, SK_TRUE);
-               SkGePollTxD(pAC, IoC, ToPort, SK_TRUE);
-               ClearAndStartRx(pAC, FromPort);
-               ClearAndStartRx(pAC, ToPort);
-               spin_unlock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
-               spin_unlock_irqrestore(
-                       &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
-                       Flags);
-               break;
-       case SK_DRV_RLMT_SEND:   /* SK_MBUF *pMb */
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
-                       ("RLS "));
-               pRlmtMbuf = (SK_MBUF*) Param.pParaPtr;
-               pMsg = (struct sk_buff*) pRlmtMbuf->pOs;
-               skb_put(pMsg, pRlmtMbuf->Length);
-               if (XmitFrame(pAC, &pAC->TxPort[pRlmtMbuf->PortIdx][TX_PRIO_LOW],
-                       pMsg) < 0)
-
-                       DEV_KFREE_SKB_ANY(pMsg);
-               break;
-       case SK_DRV_TIMER:
-               if (Param.Para32[0] == SK_DRV_MODERATION_TIMER) {
-                       /*
-                       ** expiration of the moderation timer implies that
-                       ** dynamic moderation is to be applied
-                       */
-                       SkDimStartModerationTimer(pAC);
-                       SkDimModerate(pAC);
-                        if (pAC->DynIrqModInfo.DisplayStats) {
-                           SkDimDisplayModerationSettings(pAC);
-                        }
-                } else if (Param.Para32[0] == SK_DRV_RX_CLEANUP_TIMER) {
-                       /*
-                       ** check if we need to check for descriptors which
-                       ** haven't been handled the last millisecs
-                       */
-                       StartDrvCleanupTimer(pAC);
-                       if (pAC->GIni.GIMacsFound == 2) {
-                               ReceiveIrq(pAC, &pAC->RxPort[1], SK_FALSE);
-                       }
-                       ReceiveIrq(pAC, &pAC->RxPort[0], SK_FALSE);
-               } else {
-                       printk("Expiration of unknown timer\n");
-               }
-               break;
-       default:
-               break;
-       }
-       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
-               ("END EVENT "));
-       
-       return (0);
-} /* SkDrvEvent */
-
-
-/*****************************************************************************
- *
- *     SkErrorLog - log errors
- *
- * Description:
- *     This function logs errors to the system buffer and to the console
- *
- * Returns:
- *     0 if everything ok
- *     < 0  on error
- *     
- */
-void SkErrorLog(
-SK_AC  *pAC,
-int    ErrClass,
-int    ErrNum,
-char   *pErrorMsg)
-{
-char   ClassStr[80];
-
-       switch (ErrClass) {
-       case SK_ERRCL_OTHER:
-               strcpy(ClassStr, "Other error");
-               break;
-       case SK_ERRCL_CONFIG:
-               strcpy(ClassStr, "Configuration error");
-               break;
-       case SK_ERRCL_INIT:
-               strcpy(ClassStr, "Initialization error");
-               break;
-       case SK_ERRCL_NORES:
-               strcpy(ClassStr, "Out of resources error");
-               break;
-       case SK_ERRCL_SW:
-               strcpy(ClassStr, "internal Software error");
-               break;
-       case SK_ERRCL_HW:
-               strcpy(ClassStr, "Hardware failure");
-               break;
-       case SK_ERRCL_COMM:
-               strcpy(ClassStr, "Communication error");
-               break;
-       }
-       printk(KERN_INFO "%s: -- ERROR --\n        Class:  %s\n"
-               "        Nr:  0x%x\n        Msg:  %s\n", pAC->dev[0]->name,
-               ClassStr, ErrNum, pErrorMsg);
-
-} /* SkErrorLog */
-
-#ifdef SK_DIAG_SUPPORT
-
-/*****************************************************************************
- *
- *     SkDrvEnterDiagMode - handles DIAG attach request
- *
- * Description:
- *     Notify the kernel to NOT access the card any longer due to DIAG
- *     Deinitialize the Card
- *
- * Returns:
- *     int
- */
-int SkDrvEnterDiagMode(
-SK_AC   *pAc)   /* pointer to adapter context */
-{
-       DEV_NET *pNet = netdev_priv(pAc->dev[0]);
-       SK_AC   *pAC  = pNet->pAC;
-
-       SK_MEMCPY(&(pAc->PnmiBackup), &(pAc->PnmiStruct), 
-                       sizeof(SK_PNMI_STRUCT_DATA));
-
-       pAC->DiagModeActive = DIAG_ACTIVE;
-       if (pAC->BoardLevel > SK_INIT_DATA) {
-               if (netif_running(pAC->dev[0])) {
-                       pAC->WasIfUp[0] = SK_TRUE;
-                       pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose      */
-                       DoPrintInterfaceChange = SK_FALSE;
-                       SkDrvDeInitAdapter(pAC, 0);  /* performs SkGeClose */
-               } else {
-                       pAC->WasIfUp[0] = SK_FALSE;
-               }
-               if (pNet != netdev_priv(pAC->dev[1])) {
-                       pNet = netdev_priv(pAC->dev[1]);
-                       if (netif_running(pAC->dev[1])) {
-                               pAC->WasIfUp[1] = SK_TRUE;
-                               pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
-                               DoPrintInterfaceChange = SK_FALSE;
-                               SkDrvDeInitAdapter(pAC, 1);  /* do SkGeClose  */
-                       } else {
-                               pAC->WasIfUp[1] = SK_FALSE;
-                       }
-               }
-               pAC->BoardLevel = SK_INIT_DATA;
-       }
-       return(0);
-}
-
-/*****************************************************************************
- *
- *     SkDrvLeaveDiagMode - handles DIAG detach request
- *
- * Description:
- *     Notify the kernel to may access the card again after use by DIAG
- *     Initialize the Card
- *
- * Returns:
- *     int
- */
-int SkDrvLeaveDiagMode(
-SK_AC   *pAc)   /* pointer to adapter control context */
-{ 
-       SK_MEMCPY(&(pAc->PnmiStruct), &(pAc->PnmiBackup), 
-                       sizeof(SK_PNMI_STRUCT_DATA));
-       pAc->DiagModeActive    = DIAG_NOTACTIVE;
-       pAc->Pnmi.DiagAttached = SK_DIAG_IDLE;
-        if (pAc->WasIfUp[0] == SK_TRUE) {
-                pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
-               DoPrintInterfaceChange = SK_FALSE;
-                SkDrvInitAdapter(pAc, 0);    /* first device  */
-        }
-        if (pAc->WasIfUp[1] == SK_TRUE) {
-                pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
-               DoPrintInterfaceChange = SK_FALSE;
-                SkDrvInitAdapter(pAc, 1);    /* second device */
-        }
-       return(0);
-}
-
-/*****************************************************************************
- *
- *     ParseDeviceNbrFromSlotName - Evaluate PCI device number
- *
- * Description:
- *     This function parses the PCI slot name information string and will
- *     retrieve the devcie number out of it. The slot_name maintianed by
- *     linux is in the form of '02:0a.0', whereas the first two characters 
- *     represent the bus number in hex (in the sample above this is 
- *     pci bus 0x02) and the next two characters the device number (0x0a).
- *
- * Returns:
- *     SK_U32: The device number from the PCI slot name
- */ 
-
-static SK_U32 ParseDeviceNbrFromSlotName(
-const char *SlotName)   /* pointer to pci slot name eg. '02:0a.0' */
-{
-       char    *CurrCharPos    = (char *) SlotName;
-       int     FirstNibble     = -1;
-       int     SecondNibble    = -1;
-       SK_U32  Result          =  0;
-
-       while (*CurrCharPos != '\0') {
-               if (*CurrCharPos == ':') { 
-                       while (*CurrCharPos != '.') {
-                               CurrCharPos++;  
-                               if (    (*CurrCharPos >= '0') && 
-                                       (*CurrCharPos <= '9')) {
-                                       if (FirstNibble == -1) {
-                                               /* dec. value for '0' */
-                                               FirstNibble = *CurrCharPos - 48;
-                                       } else {
-                                               SecondNibble = *CurrCharPos - 48;
-                                       }  
-                               } else if (     (*CurrCharPos >= 'a') && 
-                                               (*CurrCharPos <= 'f')  ) {
-                                       if (FirstNibble == -1) {
-                                               FirstNibble = *CurrCharPos - 87; 
-                                       } else {
-                                               SecondNibble = *CurrCharPos - 87; 
-                                       }
-                               } else {
-                                       Result = 0;
-                               }
-                       }
-
-                       Result = FirstNibble;
-                       Result = Result << 4; /* first nibble is higher one */
-                       Result = Result | SecondNibble;
-               }
-               CurrCharPos++;   /* next character */
-       }
-       return (Result);
-}
-
-/****************************************************************************
- *
- *     SkDrvDeInitAdapter - deinitialize adapter (this function is only 
- *                             called if Diag attaches to that card)
- *
- * Description:
- *     Close initialized adapter.
- *
- * Returns:
- *     0 - on success
- *     error code - on error
- */
-static int SkDrvDeInitAdapter(
-SK_AC   *pAC,          /* pointer to adapter context   */
-int      devNbr)       /* what device is to be handled */
-{
-       struct SK_NET_DEVICE *dev;
-
-       dev = pAC->dev[devNbr];
-
-       /* On Linux 2.6 the network driver does NOT mess with reference
-       ** counts.  The driver MUST be able to be unloaded at any time
-       ** due to the possibility of hotplug.
-       */
-       if (SkGeClose(dev) != 0) {
-               return (-1);
-       }
-       return (0);
-
-} /* SkDrvDeInitAdapter() */
-
-/****************************************************************************
- *
- *     SkDrvInitAdapter - Initialize adapter (this function is only 
- *                             called if Diag deattaches from that card)
- *
- * Description:
- *     Close initialized adapter.
- *
- * Returns:
- *     0 - on success
- *     error code - on error
- */
-static int SkDrvInitAdapter(
-SK_AC   *pAC,          /* pointer to adapter context   */
-int      devNbr)       /* what device is to be handled */
-{
-       struct SK_NET_DEVICE *dev;
-
-       dev = pAC->dev[devNbr];
-
-       if (SkGeOpen(dev) != 0) {
-               return (-1);
-       }
-
-       /*
-       ** Use correct MTU size and indicate to kernel TX queue can be started
-       */ 
-       if (SkGeChangeMtu(dev, dev->mtu) != 0) {
-               return (-1);
-       } 
-       return (0);
-
-} /* SkDrvInitAdapter */
-
-#endif
-
-#ifdef DEBUG
-/****************************************************************************/
-/* "debug only" section *****************************************************/
-/****************************************************************************/
-
-
-/*****************************************************************************
- *
- *     DumpMsg - print a frame
- *
- * Description:
- *     This function prints frames to the system logfile/to the console.
- *
- * Returns: N/A
- *     
- */
-static void DumpMsg(struct sk_buff *skb, char *str)
-{
-       int     msglen;
-
-       if (skb == NULL) {
-               printk("DumpMsg(): NULL-Message\n");
-               return;
-       }
-
-       if (skb->data == NULL) {
-               printk("DumpMsg(): Message empty\n");
-               return;
-       }
-
-       msglen = skb->len;
-       if (msglen > 64)
-               msglen = 64;
-
-       printk("--- Begin of message from %s , len %d (from %d) ----\n", str, msglen, skb->len);
-
-       DumpData((char *)skb->data, msglen);
-
-       printk("------- End of message ---------\n");
-} /* DumpMsg */
-
-
-
-/*****************************************************************************
- *
- *     DumpData - print a data area
- *
- * Description:
- *     This function prints a area of data to the system logfile/to the
- *     console.
- *
- * Returns: N/A
- *     
- */
-static void DumpData(char *p, int size)
-{
-register int    i;
-int    haddr, addr;
-char   hex_buffer[180];
-char   asc_buffer[180];
-char   HEXCHAR[] = "0123456789ABCDEF";
-
-       addr = 0;
-       haddr = 0;
-       hex_buffer[0] = 0;
-       asc_buffer[0] = 0;
-       for (i=0; i < size; ) {
-               if (*p >= '0' && *p <='z')
-                       asc_buffer[addr] = *p;
-               else
-                       asc_buffer[addr] = '.';
-               addr++;
-               asc_buffer[addr] = 0;
-               hex_buffer[haddr] = HEXCHAR[(*p & 0xf0) >> 4];
-               haddr++;
-               hex_buffer[haddr] = HEXCHAR[*p & 0x0f];
-               haddr++;
-               hex_buffer[haddr] = ' ';
-               haddr++;
-               hex_buffer[haddr] = 0;
-               p++;
-               i++;
-               if (i%16 == 0) {
-                       printk("%s  %s\n", hex_buffer, asc_buffer);
-                       addr = 0;
-                       haddr = 0;
-               }
-       }
-} /* DumpData */
-
-
-/*****************************************************************************
- *
- *     DumpLong - print a data area as long values
- *
- * Description:
- *     This function prints a area of data to the system logfile/to the
- *     console.
- *
- * Returns: N/A
- *     
- */
-static void DumpLong(char *pc, int size)
-{
-register int    i;
-int    haddr, addr;
-char   hex_buffer[180];
-char   asc_buffer[180];
-char   HEXCHAR[] = "0123456789ABCDEF";
-long   *p;
-int    l;
-
-       addr = 0;
-       haddr = 0;
-       hex_buffer[0] = 0;
-       asc_buffer[0] = 0;
-       p = (long*) pc;
-       for (i=0; i < size; ) {
-               l = (long) *p;
-               hex_buffer[haddr] = HEXCHAR[(l >> 28) & 0xf];
-               haddr++;
-               hex_buffer[haddr] = HEXCHAR[(l >> 24) & 0xf];
-               haddr++;
-               hex_buffer[haddr] = HEXCHAR[(l >> 20) & 0xf];
-               haddr++;
-               hex_buffer[haddr] = HEXCHAR[(l >> 16) & 0xf];
-               haddr++;
-               hex_buffer[haddr] = HEXCHAR[(l >> 12) & 0xf];
-               haddr++;
-               hex_buffer[haddr] = HEXCHAR[(l >> 8) & 0xf];
-               haddr++;
-               hex_buffer[haddr] = HEXCHAR[(l >> 4) & 0xf];
-               haddr++;
-               hex_buffer[haddr] = HEXCHAR[l & 0x0f];
-               haddr++;
-               hex_buffer[haddr] = ' ';
-               haddr++;
-               hex_buffer[haddr] = 0;
-               p++;
-               i++;
-               if (i%8 == 0) {
-                       printk("%4x %s\n", (i-8)*4, hex_buffer);
-                       haddr = 0;
-               }
-       }
-       printk("------------------------\n");
-} /* DumpLong */
-
-#endif
-
-static int __devinit skge_probe_one(struct pci_dev *pdev,
-               const struct pci_device_id *ent)
-{
-       SK_AC                   *pAC;
-       DEV_NET                 *pNet = NULL;
-       struct net_device       *dev = NULL;
-       static int boards_found = 0;
-       int error = -ENODEV;
-       int using_dac = 0;
-       char DeviceStr[80];
-
-       if (pci_enable_device(pdev))
-               goto out;
-       /* Configure DMA attributes. */
-       if (sizeof(dma_addr_t) > sizeof(u32) &&
-           !(error = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) {
-               using_dac = 1;
-               error = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
-               if (error < 0) {
-                       printk(KERN_ERR "sk98lin %s unable to obtain 64 bit DMA "
-                              "for consistent allocations\n", pci_name(pdev));
-                       goto out_disable_device;
-               }
-       } else {
-               error = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
-               if (error) {
-                       printk(KERN_ERR "sk98lin %s no usable DMA configuration\n",
-                              pci_name(pdev));
-                       goto out_disable_device;
-               }
-       }
-
-       error = -ENOMEM;
-       dev = alloc_etherdev(sizeof(DEV_NET));
-       if (!dev) {
-               printk(KERN_ERR "sk98lin: unable to allocate etherdev "
-                      "structure!\n");
-               goto out_disable_device;
-       }
-
-       pNet = netdev_priv(dev);
-       pNet->pAC = kzalloc(sizeof(SK_AC), GFP_KERNEL);
-       if (!pNet->pAC) {
-               printk(KERN_ERR "sk98lin: unable to allocate adapter "
-                      "structure!\n");
-               goto out_free_netdev;
-       }
-
-       pAC = pNet->pAC;
-       pAC->PciDev = pdev;
-
-       pAC->dev[0] = dev;
-       pAC->dev[1] = dev;
-       pAC->CheckQueue = SK_FALSE;
-
-       dev->irq = pdev->irq;
-
-       error = SkGeInitPCI(pAC);
-       if (error) {
-               printk(KERN_ERR "sk98lin: PCI setup failed: %i\n", error);
-               goto out_free_netdev;
-       }
-
-       SET_MODULE_OWNER(dev);
-       dev->open =             &SkGeOpen;
-       dev->stop =             &SkGeClose;
-       dev->hard_start_xmit =  &SkGeXmit;
-       dev->get_stats =        &SkGeStats;
-       dev->set_multicast_list = &SkGeSetRxMode;
-       dev->set_mac_address =  &SkGeSetMacAddr;
-       dev->do_ioctl =         &SkGeIoctl;
-       dev->change_mtu =       &SkGeChangeMtu;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       dev->poll_controller =  &SkGePollController;
-#endif
-       SET_NETDEV_DEV(dev, &pdev->dev);
-       SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
-
-       /* Use only if yukon hardware */
-       if (pAC->ChipsetType) {
-#ifdef USE_SK_TX_CHECKSUM
-               dev->features |= NETIF_F_IP_CSUM;
-#endif
-#ifdef SK_ZEROCOPY
-               dev->features |= NETIF_F_SG;
-#endif
-#ifdef USE_SK_RX_CHECKSUM
-               pAC->RxPort[0].RxCsum = 1;
-#endif
-       }
-
-       if (using_dac)
-               dev->features |= NETIF_F_HIGHDMA;
-
-       pAC->Index = boards_found++;
-
-       error = SkGeBoardInit(dev, pAC);
-       if (error)
-               goto out_free_netdev;
-
-       /* Read Adapter name from VPD */
-       if (ProductStr(pAC, DeviceStr, sizeof(DeviceStr)) != 0) {
-               error = -EIO;
-               printk(KERN_ERR "sk98lin: Could not read VPD data.\n");
-               goto out_free_resources;
-       }
-
-       /* Register net device */
-       error = register_netdev(dev);
-       if (error) {
-               printk(KERN_ERR "sk98lin: Could not register device.\n");
-               goto out_free_resources;
-       }
-
-       /* Print adapter specific string from vpd */
-       printk("%s: %s\n", dev->name, DeviceStr);
-
-       /* Print configuration settings */
-       printk("      PrefPort:%c  RlmtMode:%s\n",
-               'A' + pAC->Rlmt.Net[0].Port[pAC->Rlmt.Net[0].PrefPort]->PortNumber,
-               (pAC->RlmtMode==0)  ? "Check Link State" :
-               ((pAC->RlmtMode==1) ? "Check Link State" :
-               ((pAC->RlmtMode==3) ? "Check Local Port" :
-               ((pAC->RlmtMode==7) ? "Check Segmentation" :
-               ((pAC->RlmtMode==17) ? "Dual Check Link State" :"Error")))));
-
-       SkGeYellowLED(pAC, pAC->IoBase, 1);
-
-       memcpy(&dev->dev_addr, &pAC->Addr.Net[0].CurrentMacAddress, 6);
-       memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
-
-       pNet->PortNr = 0;
-       pNet->NetNr  = 0;
-
-       boards_found++;
-
-       pci_set_drvdata(pdev, dev);
-
-       /* More then one port found */
-       if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
-               dev = alloc_etherdev(sizeof(DEV_NET));
-               if (!dev) {
-                       printk(KERN_ERR "sk98lin: unable to allocate etherdev "
-                               "structure!\n");
-                       goto single_port;
-               }
-
-               pNet          = netdev_priv(dev);
-               pNet->PortNr  = 1;
-               pNet->NetNr   = 1;
-               pNet->pAC     = pAC;
-
-               dev->open               = &SkGeOpen;
-               dev->stop               = &SkGeClose;
-               dev->hard_start_xmit    = &SkGeXmit;
-               dev->get_stats          = &SkGeStats;
-               dev->set_multicast_list = &SkGeSetRxMode;
-               dev->set_mac_address    = &SkGeSetMacAddr;
-               dev->do_ioctl           = &SkGeIoctl;
-               dev->change_mtu         = &SkGeChangeMtu;
-               SET_NETDEV_DEV(dev, &pdev->dev);
-               SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
-
-               if (pAC->ChipsetType) {
-#ifdef USE_SK_TX_CHECKSUM
-                       dev->features |= NETIF_F_IP_CSUM;
-#endif
-#ifdef SK_ZEROCOPY
-                       dev->features |= NETIF_F_SG;
-#endif
-#ifdef USE_SK_RX_CHECKSUM
-                       pAC->RxPort[1].RxCsum = 1;
-#endif
-               }
-
-               if (using_dac)
-                       dev->features |= NETIF_F_HIGHDMA;
-
-               error = register_netdev(dev);
-               if (error) {
-                       printk(KERN_ERR "sk98lin: Could not register device"
-                              " for second port. (%d)\n", error);
-                       free_netdev(dev);
-                       goto single_port;
-               }
-
-               pAC->dev[1]   = dev;
-               memcpy(&dev->dev_addr,
-                      &pAC->Addr.Net[1].CurrentMacAddress, 6);
-               memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
-
-               printk("%s: %s\n", dev->name, DeviceStr);
-               printk("      PrefPort:B  RlmtMode:Dual Check Link State\n");
-       }
-
-single_port:
-
-       /* Save the hardware revision */
-       pAC->HWRevision = (((pAC->GIni.GIPciHwRev >> 4) & 0x0F)*10) +
-               (pAC->GIni.GIPciHwRev & 0x0F);
-
-       /* Set driver globals */
-       pAC->Pnmi.pDriverFileName    = DRIVER_FILE_NAME;
-       pAC->Pnmi.pDriverReleaseDate = DRIVER_REL_DATE;
-
-       memset(&pAC->PnmiBackup, 0, sizeof(SK_PNMI_STRUCT_DATA));
-       memcpy(&pAC->PnmiBackup, &pAC->PnmiStruct, sizeof(SK_PNMI_STRUCT_DATA));
-
-       return 0;
-
- out_free_resources:
-       FreeResources(dev);
- out_free_netdev:
-       free_netdev(dev);
- out_disable_device:
-       pci_disable_device(pdev);
- out:
-       return error;
-}
-
-static void __devexit skge_remove_one(struct pci_dev *pdev)
-{
-       struct net_device *dev = pci_get_drvdata(pdev);
-       DEV_NET *pNet = netdev_priv(dev);
-       SK_AC *pAC = pNet->pAC;
-       struct net_device *otherdev = pAC->dev[1];
-
-       unregister_netdev(dev);
-
-       SkGeYellowLED(pAC, pAC->IoBase, 0);
-
-       if (pAC->BoardLevel == SK_INIT_RUN) {
-               SK_EVPARA EvPara;
-               unsigned long Flags;
-
-               /* board is still alive */
-               spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-               EvPara.Para32[0] = 0;
-               EvPara.Para32[1] = -1;
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
-               EvPara.Para32[0] = 1;
-               EvPara.Para32[1] = -1;
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
-               SkEventDispatcher(pAC, pAC->IoBase);
-               /* disable interrupts */
-               SK_OUT32(pAC->IoBase, B0_IMSK, 0);
-               SkGeDeInit(pAC, pAC->IoBase);
-               spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-               pAC->BoardLevel = SK_INIT_DATA;
-               /* We do NOT check here, if IRQ was pending, of course*/
-       }
-
-       if (pAC->BoardLevel == SK_INIT_IO) {
-               /* board is still alive */
-               SkGeDeInit(pAC, pAC->IoBase);
-               pAC->BoardLevel = SK_INIT_DATA;
-       }
-
-       FreeResources(dev);
-       free_netdev(dev);
-       if (otherdev != dev)
-               free_netdev(otherdev);
-       kfree(pAC);
-}
-
-#ifdef CONFIG_PM
-static int skge_suspend(struct pci_dev *pdev, pm_message_t state)
-{
-       struct net_device *dev = pci_get_drvdata(pdev);
-       DEV_NET *pNet = netdev_priv(dev);
-       SK_AC *pAC = pNet->pAC;
-       struct net_device *otherdev = pAC->dev[1];
-
-       if (netif_running(dev)) {
-               netif_carrier_off(dev);
-               DoPrintInterfaceChange = SK_FALSE;
-               SkDrvDeInitAdapter(pAC, 0);  /* performs SkGeClose */
-               netif_device_detach(dev);
-       }
-       if (otherdev != dev) {
-               if (netif_running(otherdev)) {
-                       netif_carrier_off(otherdev);
-                       DoPrintInterfaceChange = SK_FALSE;
-                       SkDrvDeInitAdapter(pAC, 1);  /* performs SkGeClose */
-                       netif_device_detach(otherdev);
-               }
-       }
-
-       pci_save_state(pdev);
-       pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
-       if (pAC->AllocFlag & SK_ALLOC_IRQ) {
-               free_irq(dev->irq, dev);
-       }
-       pci_disable_device(pdev);
-       pci_set_power_state(pdev, pci_choose_state(pdev, state));
-
-       return 0;
-}
-
-static int skge_resume(struct pci_dev *pdev)
-{
-       struct net_device *dev = pci_get_drvdata(pdev);
-       DEV_NET *pNet = netdev_priv(dev);
-       SK_AC *pAC = pNet->pAC;
-       struct net_device *otherdev = pAC->dev[1];
-       int ret;
-
-       pci_set_power_state(pdev, PCI_D0);
-       pci_restore_state(pdev);
-       ret = pci_enable_device(pdev);
-       if (ret) {
-               printk(KERN_WARNING "sk98lin: unable to enable device %s "
-                               "in resume\n", dev->name);
-               goto err_out;
-       }
-       pci_set_master(pdev);
-       if (pAC->GIni.GIMacsFound == 2)
-               ret = request_irq(dev->irq, SkGeIsr, IRQF_SHARED, "sk98lin", dev);
-       else
-               ret = request_irq(dev->irq, SkGeIsrOnePort, IRQF_SHARED, "sk98lin", dev);
-       if (ret) {
-               printk(KERN_WARNING "sk98lin: unable to acquire IRQ %d\n", dev->irq);
-               ret = -EBUSY;
-               goto err_out_disable_pdev;
-       }
-
-       netif_device_attach(dev);
-       if (netif_running(dev)) {
-               DoPrintInterfaceChange = SK_FALSE;
-               SkDrvInitAdapter(pAC, 0);    /* first device  */
-       }
-       if (otherdev != dev) {
-               netif_device_attach(otherdev);
-               if (netif_running(otherdev)) {
-                       DoPrintInterfaceChange = SK_FALSE;
-                       SkDrvInitAdapter(pAC, 1);    /* second device  */
-               }
-       }
-
-       return 0;
-
-err_out_disable_pdev:
-       pci_disable_device(pdev);
-err_out:
-       pAC->AllocFlag &= ~SK_ALLOC_IRQ;
-       dev->irq = 0;
-       return ret;
-}
-#else
-#define skge_suspend NULL
-#define skge_resume NULL
-#endif
-
-static struct pci_device_id skge_pci_tbl[] = {
-       { PCI_VENDOR_ID_3COM, 0x1700, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-       { PCI_VENDOR_ID_3COM, 0x80eb, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-       { PCI_VENDOR_ID_SYSKONNECT, 0x4300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-       { PCI_VENDOR_ID_SYSKONNECT, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-/* DLink card does not have valid VPD so this driver gags
- *     { PCI_VENDOR_ID_DLINK, 0x4c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- */
-       { PCI_VENDOR_ID_MARVELL, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-       { PCI_VENDOR_ID_MARVELL, 0x5005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-       { PCI_VENDOR_ID_CNET, 0x434e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-       { PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0015, },
-       { PCI_VENDOR_ID_LINKSYS, 0x1064, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-       { 0 }
-};
-
-MODULE_DEVICE_TABLE(pci, skge_pci_tbl);
-
-static struct pci_driver skge_driver = {
-       .name           = "sk98lin",
-       .id_table       = skge_pci_tbl,
-       .probe          = skge_probe_one,
-       .remove         = __devexit_p(skge_remove_one),
-       .suspend        = skge_suspend,
-       .resume         = skge_resume,
-};
-
-static int __init skge_init(void)
-{
-       printk(KERN_NOTICE "sk98lin: driver has been replaced by the skge driver"
-              " and is scheduled for removal\n");
-
-       return pci_register_driver(&skge_driver);
-}
-
-static void __exit skge_exit(void)
-{
-       pci_unregister_driver(&skge_driver);
-}
-
-module_init(skge_init);
-module_exit(skge_exit);
diff --git a/drivers/net/sk98lin/skgehwt.c b/drivers/net/sk98lin/skgehwt.c
deleted file mode 100644 (file)
index db67099..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-/******************************************************************************
- *
- * Name:       skgehwt.c
- * Project:    Gigabit Ethernet Adapters, Event Scheduler Module
- * Version:    $Revision: 1.15 $
- * Date:       $Date: 2003/09/16 13:41:23 $
- * Purpose:    Hardware Timer
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect GmbH.
- *     (C)Copyright 2002-2003 Marvell.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/*
- *     Event queue and dispatcher
- */
-#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
-static const char SysKonnectFileId[] =
-       "@(#) $Id: skgehwt.c,v 1.15 2003/09/16 13:41:23 rschmidt Exp $ (C) Marvell.";
-#endif
-
-#include "h/skdrv1st.h"                /* Driver Specific Definitions */
-#include "h/skdrv2nd.h"                /* Adapter Control- and Driver specific Def. */
-
-#ifdef __C2MAN__
-/*
- *   Hardware Timer function queue management.
- */
-intro()
-{}
-#endif
-
-/*
- * Prototypes of local functions.
- */
-#define        SK_HWT_MAX      (65000)
-
-/* correction factor */
-#define        SK_HWT_FAC      (1000 * (SK_U32)pAC->GIni.GIHstClkFact / 100)
-
-/*
- * Initialize hardware timer.
- *
- * Must be called during init level 1.
- */
-void   SkHwtInit(
-SK_AC  *pAC,   /* Adapters context */
-SK_IOC Ioc)    /* IoContext */
-{
-       pAC->Hwt.TStart = 0 ;
-       pAC->Hwt.TStop  = 0 ;
-       pAC->Hwt.TActive = SK_FALSE;
-
-       SkHwtStop(pAC, Ioc);
-}
-
-/*
- *
- * Start hardware timer (clock ticks are 16us).
- *
- */
-void   SkHwtStart(
-SK_AC  *pAC,   /* Adapters context */
-SK_IOC Ioc,    /* IoContext */
-SK_U32 Time)   /* Time in units of 16us to load the timer with. */
-{
-       SK_U32  Cnt;
-
-       if (Time > SK_HWT_MAX)
-               Time = SK_HWT_MAX;
-
-       pAC->Hwt.TStart = Time;
-       pAC->Hwt.TStop = 0L;
-
-       Cnt = Time;
-
-       /*
-        * if time < 16 us
-        *      time = 16 us
-        */
-       if (!Cnt) {
-               Cnt++;
-       }
-
-       SK_OUT32(Ioc, B2_TI_INI, Cnt * SK_HWT_FAC);
-       
-       SK_OUT16(Ioc, B2_TI_CTRL, TIM_START);   /* Start timer. */
-
-       pAC->Hwt.TActive = SK_TRUE;
-}
-
-/*
- * Stop hardware timer.
- * and clear the timer IRQ
- */
-void   SkHwtStop(
-SK_AC  *pAC,   /* Adapters context */
-SK_IOC Ioc)    /* IoContext */
-{
-       SK_OUT16(Ioc, B2_TI_CTRL, TIM_STOP);
-       
-       SK_OUT16(Ioc, B2_TI_CTRL, TIM_CLR_IRQ);
-
-       pAC->Hwt.TActive = SK_FALSE;
-}
-
-
-/*
- *     Stop hardware timer and read time elapsed since last start.
- *
- * returns
- *     The elapsed time since last start in units of 16us.
- *
- */
-SK_U32 SkHwtRead(
-SK_AC  *pAC,   /* Adapters context */
-SK_IOC Ioc)    /* IoContext */
-{
-       SK_U32  TRead;
-       SK_U32  IStatus;
-
-       if (pAC->Hwt.TActive) {
-               
-               SkHwtStop(pAC, Ioc);
-
-               SK_IN32(Ioc, B2_TI_VAL, &TRead);
-               TRead /= SK_HWT_FAC;
-
-               SK_IN32(Ioc, B0_ISRC, &IStatus);
-
-               /* Check if timer expired (or wraped around) */
-               if ((TRead > pAC->Hwt.TStart) || (IStatus & IS_TIMINT)) {
-                       
-                       SkHwtStop(pAC, Ioc);
-                       
-                       pAC->Hwt.TStop = pAC->Hwt.TStart;
-               }
-               else {
-                       
-                       pAC->Hwt.TStop = pAC->Hwt.TStart - TRead;
-               }
-       }
-       return(pAC->Hwt.TStop);
-}
-
-/*
- * interrupt source= timer
- */
-void   SkHwtIsr(
-SK_AC  *pAC,   /* Adapters context */
-SK_IOC Ioc)    /* IoContext */
-{
-       SkHwtStop(pAC, Ioc);
-       
-       pAC->Hwt.TStop = pAC->Hwt.TStart;
-       
-       SkTimerDone(pAC, Ioc);
-}
-
-/* End of file */
diff --git a/drivers/net/sk98lin/skgeinit.c b/drivers/net/sk98lin/skgeinit.c
deleted file mode 100644 (file)
index 67f1d6a..0000000
+++ /dev/null
@@ -1,2005 +0,0 @@
-/******************************************************************************
- *
- * Name:       skgeinit.c
- * Project:    Gigabit Ethernet Adapters, Common Modules
- * Version:    $Revision: 1.97 $
- * Date:       $Date: 2003/10/02 16:45:31 $
- * Purpose:    Contains functions to initialize the adapter
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect.
- *     (C)Copyright 2002-2003 Marvell.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-#include "h/skdrv1st.h"
-#include "h/skdrv2nd.h"
-
-/* global variables ***********************************************************/
-
-/* local variables ************************************************************/
-
-#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
-static const char SysKonnectFileId[] =
-       "@(#) $Id: skgeinit.c,v 1.97 2003/10/02 16:45:31 rschmidt Exp $ (C) Marvell.";
-#endif
-
-struct s_QOffTab {
-       int     RxQOff;         /* Receive Queue Address Offset */
-       int     XsQOff;         /* Sync Tx Queue Address Offset */
-       int     XaQOff;         /* Async Tx Queue Address Offset */
-};
-static struct s_QOffTab QOffTab[] = {
-       {Q_R1, Q_XS1, Q_XA1}, {Q_R2, Q_XS2, Q_XA2}
-};
-
-struct s_Config {
-       char    ScanString[8];
-       SK_U32  Value;
-};
-
-static struct s_Config OemConfig = {
-       {'O','E','M','_','C','o','n','f'},
-#ifdef SK_OEM_CONFIG
-       OEM_CONFIG_VALUE,
-#else
-       0,
-#endif
-};
-
-/******************************************************************************
- *
- *     SkGePollTxD() - Enable / Disable Descriptor Polling of TxD Rings
- *
- * Description:
- *     Enable or disable the descriptor polling of the transmit descriptor
- *     ring(s) (TxD) for port 'Port'.
- *     The new configuration is *not* saved over any SkGeStopPort() and
- *     SkGeInitPort() calls.
- *
- * Returns:
- *     nothing
- */
-void SkGePollTxD(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-SK_BOOL PollTxD)       /* SK_TRUE (enable pol.), SK_FALSE (disable pol.) */
-{
-       SK_GEPORT *pPrt;
-       SK_U32  DWord;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       DWord = (SK_U32)(PollTxD ? CSR_ENA_POL : CSR_DIS_POL);
-
-       if (pPrt->PXSQSize != 0) {
-               SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), DWord);
-       }
-       
-       if (pPrt->PXAQSize != 0) {
-               SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), DWord);
-       }
-}      /* SkGePollTxD */
-
-
-/******************************************************************************
- *
- *     SkGeYellowLED() - Switch the yellow LED on or off.
- *
- * Description:
- *     Switch the yellow LED on or off.
- *
- * Note:
- *     This function may be called any time after SkGeInit(Level 1).
- *
- * Returns:
- *     nothing
- */
-void SkGeYellowLED(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            State)          /* yellow LED state, 0 = OFF, 0 != ON */
-{
-       if (State == 0) {
-               /* Switch yellow LED OFF */
-               SK_OUT8(IoC, B0_LED, LED_STAT_OFF);
-       }
-       else {
-               /* Switch yellow LED ON */
-               SK_OUT8(IoC, B0_LED, LED_STAT_ON);
-       }
-}      /* SkGeYellowLED */
-
-
-#if (!defined(SK_SLIM) || defined(GENESIS))
-/******************************************************************************
- *
- *     SkGeXmitLED() - Modify the Operational Mode of a transmission LED.
- *
- * Description:
- *     The Rx or Tx LED which is specified by 'Led' will be
- *     enabled, disabled or switched on in test mode.
- *
- * Note:
- *     'Led' must contain the address offset of the LEDs INI register.
- *
- * Usage:
- *     SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_ENA);
- *
- * Returns:
- *     nothing
- */
-void SkGeXmitLED(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Led,            /* offset to the LED Init Value register */
-int            Mode)           /* Mode may be SK_LED_DIS, SK_LED_ENA, SK_LED_TST */
-{
-       SK_U32  LedIni;
-
-       switch (Mode) {
-       case SK_LED_ENA:
-               LedIni = SK_XMIT_DUR * (SK_U32)pAC->GIni.GIHstClkFact / 100;
-               SK_OUT32(IoC, Led + XMIT_LED_INI, LedIni);
-               SK_OUT8(IoC, Led + XMIT_LED_CTRL, LED_START);
-               break;
-       case SK_LED_TST:
-               SK_OUT8(IoC, Led + XMIT_LED_TST, LED_T_ON);
-               SK_OUT32(IoC, Led + XMIT_LED_CNT, 100);
-               SK_OUT8(IoC, Led + XMIT_LED_CTRL, LED_START);
-               break;
-       case SK_LED_DIS:
-       default:
-               /*
-                * Do NOT stop the LED Timer here. The LED might be
-                * in on state. But it needs to go off.
-                */
-               SK_OUT32(IoC, Led + XMIT_LED_CNT, 0);
-               SK_OUT8(IoC, Led + XMIT_LED_TST, LED_T_OFF);
-               break;
-       }
-                       
-       /*
-        * 1000BT: The Transmit LED is driven by the PHY.
-        * But the default LED configuration is used for
-        * Level One and Broadcom PHYs.
-        * (Broadcom: It may be that PHY_B_PEC_EN_LTR has to be set.)
-        * (In this case it has to be added here. But we will see. XXX)
-        */
-}      /* SkGeXmitLED */
-#endif /* !SK_SLIM || GENESIS */
-
-
-/******************************************************************************
- *
- *     DoCalcAddr() - Calculates the start and the end address of a queue.
- *
- * Description:
- *     This function calculates the start and the end address of a queue.
- *  Afterwards the 'StartVal' is incremented to the next start position.
- *     If the port is already initialized the calculated values
- *     will be checked against the configured values and an
- *     error will be returned, if they are not equal.
- *     If the port is not initialized the values will be written to
- *     *StartAdr and *EndAddr.
- *
- * Returns:
- *     0:      success
- *     1:      configuration error
- */
-static int DoCalcAddr(
-SK_AC          *pAC,                           /* adapter context */
-SK_GEPORT      SK_FAR *pPrt,           /* port index */
-int                    QuSize,                         /* size of the queue to configure in kB */
-SK_U32         SK_FAR *StartVal,       /* start value for address calculation */
-SK_U32         SK_FAR *QuStartAddr,/* start addr to calculate */
-SK_U32         SK_FAR *QuEndAddr)      /* end address to calculate */
-{
-       SK_U32  EndVal;
-       SK_U32  NextStart;
-       int             Rtv;
-
-       Rtv = 0;
-       if (QuSize == 0) {
-               EndVal = *StartVal;
-               NextStart = EndVal;
-       }
-       else {
-               EndVal = *StartVal + ((SK_U32)QuSize * 1024) - 1;
-               NextStart = EndVal + 1;
-       }
-
-       if (pPrt->PState >= SK_PRT_INIT) {
-               if (*StartVal != *QuStartAddr || EndVal != *QuEndAddr) {
-                       Rtv = 1;
-               }
-       }
-       else {
-               *QuStartAddr = *StartVal;
-               *QuEndAddr = EndVal;
-       }
-
-       *StartVal = NextStart;
-       return(Rtv);
-}      /* DoCalcAddr */
-
-/******************************************************************************
- *
- *     SkGeInitAssignRamToQueues() - allocate default queue sizes
- *
- * Description:
- *     This function assigns the memory to the different queues and ports.
- *     When DualNet is set to SK_TRUE all ports get the same amount of memory.
- *  Otherwise the first port gets most of the memory and all the
- *     other ports just the required minimum.
- *     This function can only be called when pAC->GIni.GIRamSize and
- *     pAC->GIni.GIMacsFound have been initialized, usually this happens
- *     at init level 1
- *
- * Returns:
- *     0 - ok
- *     1 - invalid input values
- *     2 - not enough memory
- */
-
-int SkGeInitAssignRamToQueues(
-SK_AC  *pAC,                   /* Adapter context */
-int            ActivePort,             /* Active Port in RLMT mode */
-SK_BOOL        DualNet)                /* adapter context */
-{
-       int     i;
-       int     UsedKilobytes;                  /* memory already assigned */
-       int     ActivePortKilobytes;    /* memory available for active port */
-       SK_GEPORT *pGePort;
-
-       UsedKilobytes = 0;
-
-       if (ActivePort >= pAC->GIni.GIMacsFound) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
-                       ("SkGeInitAssignRamToQueues: ActivePort (%d) invalid\n",
-                       ActivePort));
-               return(1);
-       }
-       if (((pAC->GIni.GIMacsFound * (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE)) +
-               ((RAM_QUOTA_SYNC == 0) ? 0 : SK_MIN_TXQ_SIZE)) > pAC->GIni.GIRamSize) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
-                       ("SkGeInitAssignRamToQueues: Not enough memory (%d)\n",
-                        pAC->GIni.GIRamSize));
-               return(2);
-       }
-
-       if (DualNet) {
-               /* every port gets the same amount of memory */
-               ActivePortKilobytes = pAC->GIni.GIRamSize / pAC->GIni.GIMacsFound;
-               for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
-
-                       pGePort = &pAC->GIni.GP[i];
-                       
-                       /* take away the minimum memory for active queues */
-                       ActivePortKilobytes -= (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE);
-
-                       /* receive queue gets the minimum + 80% of the rest */
-                       pGePort->PRxQSize = (int) (ROUND_QUEUE_SIZE_KB((
-                               ActivePortKilobytes * (unsigned long) RAM_QUOTA_RX) / 100))
-                               + SK_MIN_RXQ_SIZE;
-
-                       ActivePortKilobytes -= (pGePort->PRxQSize - SK_MIN_RXQ_SIZE);
-
-                       /* synchronous transmit queue */
-                       pGePort->PXSQSize = 0;
-
-                       /* asynchronous transmit queue */
-                       pGePort->PXAQSize = (int) ROUND_QUEUE_SIZE_KB(ActivePortKilobytes +
-                               SK_MIN_TXQ_SIZE);
-               }
-       }
-       else {  
-               /* Rlmt Mode or single link adapter */
-
-               /* Set standby queue size defaults for all standby ports */
-               for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
-
-                       if (i != ActivePort) {
-                               pGePort = &pAC->GIni.GP[i];
-
-                               pGePort->PRxQSize = SK_MIN_RXQ_SIZE;
-                               pGePort->PXAQSize = SK_MIN_TXQ_SIZE;
-                               pGePort->PXSQSize = 0;
-
-                               /* Count used RAM */
-                               UsedKilobytes += pGePort->PRxQSize + pGePort->PXAQSize;
-                       }
-               }
-               /* what's left? */
-               ActivePortKilobytes = pAC->GIni.GIRamSize - UsedKilobytes;
-
-               /* assign it to the active port */
-               /* first take away the minimum memory */
-               ActivePortKilobytes -= (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE);
-               pGePort = &pAC->GIni.GP[ActivePort];
-
-               /* receive queue get's the minimum + 80% of the rest */
-               pGePort->PRxQSize = (int) (ROUND_QUEUE_SIZE_KB((ActivePortKilobytes *
-                       (unsigned long) RAM_QUOTA_RX) / 100)) + SK_MIN_RXQ_SIZE;
-
-               ActivePortKilobytes -= (pGePort->PRxQSize - SK_MIN_RXQ_SIZE);
-
-               /* synchronous transmit queue */
-               pGePort->PXSQSize = 0;
-
-               /* asynchronous transmit queue */
-               pGePort->PXAQSize = (int) ROUND_QUEUE_SIZE_KB(ActivePortKilobytes) +
-                       SK_MIN_TXQ_SIZE;
-       }
-#ifdef VCPU
-       VCPUprintf(0, "PRxQSize=%u, PXSQSize=%u, PXAQSize=%u\n",
-               pGePort->PRxQSize, pGePort->PXSQSize, pGePort->PXAQSize);
-#endif /* VCPU */
-
-       return(0);
-}      /* SkGeInitAssignRamToQueues */
-
-/******************************************************************************
- *
- *     SkGeCheckQSize() - Checks the Adapters Queue Size Configuration
- *
- * Description:
- *     This function verifies the Queue Size Configuration specified
- *     in the variables PRxQSize, PXSQSize, and PXAQSize of all
- *     used ports.
- *     This requirements must be fullfilled to have a valid configuration:
- *             - The size of all queues must not exceed GIRamSize.
- *             - The queue sizes must be specified in units of 8 kB.
- *             - The size of Rx queues of available ports must not be
- *               smaller than 16 kB.
- *             - The size of at least one Tx queue (synch. or asynch.)
- *        of available ports must not be smaller than 16 kB
- *        when Jumbo Frames are used.
- *             - The RAM start and end addresses must not be changed
- *               for ports which are already initialized.
- *     Furthermore SkGeCheckQSize() defines the Start and End Addresses
- *  of all ports and stores them into the HWAC port    structure.
- *
- * Returns:
- *     0:      Queue Size Configuration valid
- *     1:      Queue Size Configuration invalid
- */
-static int SkGeCheckQSize(
-SK_AC   *pAC,          /* adapter context */
-int             Port)          /* port index */
-{
-       SK_GEPORT *pPrt;
-       int     i;
-       int     Rtv;
-       int     Rtv2;
-       SK_U32  StartAddr;
-#ifndef SK_SLIM
-       int     UsedMem;        /* total memory used (max. found ports) */
-#endif 
-
-       Rtv = 0;
-       
-#ifndef SK_SLIM
-
-       UsedMem = 0;
-       for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
-               pPrt = &pAC->GIni.GP[i];
-
-               if ((pPrt->PRxQSize & QZ_UNITS) != 0 ||
-                       (pPrt->PXSQSize & QZ_UNITS) != 0 ||
-                       (pPrt->PXAQSize & QZ_UNITS) != 0) {
-
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG);
-                       return(1);
-               }
-
-               if (i == Port && pPrt->PRxQSize < SK_MIN_RXQ_SIZE) {
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E011, SKERR_HWI_E011MSG);
-                       return(1);
-               }
-               
-               /*
-                * the size of at least one Tx queue (synch. or asynch.) has to be > 0.
-                * if Jumbo Frames are used, this size has to be >= 16 kB.
-                */
-               if ((i == Port && pPrt->PXSQSize == 0 && pPrt->PXAQSize == 0) ||
-                       (pAC->GIni.GIPortUsage == SK_JUMBO_LINK &&
-            ((pPrt->PXSQSize > 0 && pPrt->PXSQSize < SK_MIN_TXQ_SIZE) ||
-                        (pPrt->PXAQSize > 0 && pPrt->PXAQSize < SK_MIN_TXQ_SIZE)))) {
-                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E023, SKERR_HWI_E023MSG);
-                               return(1);
-               }
-               
-               UsedMem += pPrt->PRxQSize + pPrt->PXSQSize + pPrt->PXAQSize;
-       }
-       
-       if (UsedMem > pAC->GIni.GIRamSize) {
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG);
-               return(1);
-       }
-#endif /* !SK_SLIM */
-
-       /* Now start address calculation */
-       StartAddr = pAC->GIni.GIRamOffs;
-       for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
-               pPrt = &pAC->GIni.GP[i];
-
-               /* Calculate/Check values for the receive queue */
-               Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PRxQSize, &StartAddr,
-                       &pPrt->PRxQRamStart, &pPrt->PRxQRamEnd);
-               Rtv |= Rtv2;
-
-               /* Calculate/Check values for the synchronous Tx queue */
-               Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PXSQSize, &StartAddr,
-                       &pPrt->PXsQRamStart, &pPrt->PXsQRamEnd);
-               Rtv |= Rtv2;
-
-               /* Calculate/Check values for the asynchronous Tx queue */
-               Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PXAQSize, &StartAddr,
-                       &pPrt->PXaQRamStart, &pPrt->PXaQRamEnd);
-               Rtv |= Rtv2;
-
-               if (Rtv) {
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E013, SKERR_HWI_E013MSG);
-                       return(1);
-               }
-       }
-
-       return(0);
-}      /* SkGeCheckQSize */
-
-
-#ifdef GENESIS
-/******************************************************************************
- *
- *     SkGeInitMacArb() - Initialize the MAC Arbiter
- *
- * Description:
- *     This function initializes the MAC Arbiter.
- *     It must not be called if there is still an
- *     initialized or active port.
- *
- * Returns:
- *     nothing
- */
-static void SkGeInitMacArb(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC)            /* IO context */
-{
-       /* release local reset */
-       SK_OUT16(IoC, B3_MA_TO_CTRL, MA_RST_CLR);
-
-       /* configure timeout values */
-       SK_OUT8(IoC, B3_MA_TOINI_RX1, SK_MAC_TO_53);
-       SK_OUT8(IoC, B3_MA_TOINI_RX2, SK_MAC_TO_53);
-       SK_OUT8(IoC, B3_MA_TOINI_TX1, SK_MAC_TO_53);
-       SK_OUT8(IoC, B3_MA_TOINI_TX2, SK_MAC_TO_53);
-
-       SK_OUT8(IoC, B3_MA_RCINI_RX1, 0);
-       SK_OUT8(IoC, B3_MA_RCINI_RX2, 0);
-       SK_OUT8(IoC, B3_MA_RCINI_TX1, 0);
-       SK_OUT8(IoC, B3_MA_RCINI_TX2, 0);
-
-       /* recovery values are needed for XMAC II Rev. B2 only */
-       /* Fast Output Enable Mode was intended to use with Rev. B2, but now? */
-
-       /*
-        * There is no start or enable button to push, therefore
-        * the MAC arbiter is configured and enabled now.
-        */
-}      /* SkGeInitMacArb */
-
-
-/******************************************************************************
- *
- *     SkGeInitPktArb() - Initialize the Packet Arbiter
- *
- * Description:
- *     This function initializes the Packet Arbiter.
- *     It must not be called if there is still an
- *     initialized or active port.
- *
- * Returns:
- *     nothing
- */
-static void SkGeInitPktArb(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC)            /* IO context */
-{
-       /* release local reset */
-       SK_OUT16(IoC, B3_PA_CTRL, PA_RST_CLR);
-
-       /* configure timeout values */
-       SK_OUT16(IoC, B3_PA_TOINI_RX1, SK_PKT_TO_MAX);
-       SK_OUT16(IoC, B3_PA_TOINI_RX2, SK_PKT_TO_MAX);
-       SK_OUT16(IoC, B3_PA_TOINI_TX1, SK_PKT_TO_MAX);
-       SK_OUT16(IoC, B3_PA_TOINI_TX2, SK_PKT_TO_MAX);
-
-       /*
-        * enable timeout timers if jumbo frames not used
-        * NOTE: the packet arbiter timeout interrupt is needed for
-        * half duplex hangup workaround
-        */
-       if (pAC->GIni.GIPortUsage != SK_JUMBO_LINK) {
-               if (pAC->GIni.GIMacsFound == 1) {
-                       SK_OUT16(IoC, B3_PA_CTRL, PA_ENA_TO_TX1);
-               }
-               else {
-                       SK_OUT16(IoC, B3_PA_CTRL, PA_ENA_TO_TX1 | PA_ENA_TO_TX2);
-               }
-       }
-}      /* SkGeInitPktArb */
-#endif /* GENESIS */
-
-
-/******************************************************************************
- *
- *     SkGeInitMacFifo() - Initialize the MAC FIFOs
- *
- * Description:
- *     Initialize all MAC FIFOs of the specified port
- *
- * Returns:
- *     nothing
- */
-static void SkGeInitMacFifo(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-       SK_U16  Word;
-#ifdef VCPU
-       SK_U32  DWord;
-#endif /* VCPU */
-       /*
-        * For each FIFO:
-        *      - release local reset
-        *      - use default value for MAC FIFO size
-        *      - setup defaults for the control register
-        *      - enable the FIFO
-        */
-       
-#ifdef GENESIS
-       if (pAC->GIni.GIGenesis) {
-               /* Configure Rx MAC FIFO */
-               SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_CLR);
-               SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_RX_CTRL_DEF);
-               SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_ENA_OP_MD);
-       
-               /* Configure Tx MAC FIFO */
-               SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_RST_CLR);
-               SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_TX_CTRL_DEF);
-               SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_ENA_OP_MD);
-       
-               /* Enable frame flushing if jumbo frames used */
-               if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
-                       SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_ENA_FLUSH);
-               }
-       }
-#endif /* GENESIS */
-       
-#ifdef YUKON
-       if (pAC->GIni.GIYukon) {
-               /* set Rx GMAC FIFO Flush Mask */
-               SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_MSK), (SK_U16)RX_FF_FL_DEF_MSK);
-               
-               Word = (SK_U16)GMF_RX_CTRL_DEF;
-
-               /* disable Rx GMAC FIFO Flush for YUKON-Lite Rev. A0 only */
-               if (pAC->GIni.GIYukonLite && pAC->GIni.GIChipId == CHIP_ID_YUKON) {
-
-                       Word &= ~GMF_RX_F_FL_ON;
-               }
-               
-               /* Configure Rx MAC FIFO */
-               SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR);
-               SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), Word);
-               
-               /* set Rx GMAC FIFO Flush Threshold (default: 0x0a -> 56 bytes) */
-               SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF);
-               
-               /* Configure Tx MAC FIFO */
-               SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR);
-               SK_OUT16(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U16)GMF_TX_CTRL_DEF);
-               
-#ifdef VCPU
-               SK_IN32(IoC, MR_ADDR(Port, RX_GMF_AF_THR), &DWord);
-               SK_IN32(IoC, MR_ADDR(Port, TX_GMF_AE_THR), &DWord);
-#endif /* VCPU */
-               
-               /* set Tx GMAC FIFO Almost Empty Threshold */
-/*             SK_OUT32(IoC, MR_ADDR(Port, TX_GMF_AE_THR), 0); */
-       }
-#endif /* YUKON */
-
-}      /* SkGeInitMacFifo */
-
-#ifdef SK_LNK_SYNC_CNT
-/******************************************************************************
- *
- *     SkGeLoadLnkSyncCnt() - Load the Link Sync Counter and starts counting
- *
- * Description:
- *     This function starts the Link Sync Counter of the specified
- *     port and enables the generation of an Link Sync IRQ.
- *     The Link Sync Counter may be used to detect an active link,
- *     if autonegotiation is not used.
- *
- * Note:
- *     o To ensure receiving the Link Sync Event the LinkSyncCounter
- *       should be initialized BEFORE clearing the XMAC's reset!
- *     o Enable IS_LNK_SYNC_M1 and IS_LNK_SYNC_M2 after calling this
- *       function.
- *
- * Returns:
- *     nothing
- */
-void SkGeLoadLnkSyncCnt(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-SK_U32 CntVal)         /* Counter value */
-{
-       SK_U32  OrgIMsk;
-       SK_U32  NewIMsk;
-       SK_U32  ISrc;
-       SK_BOOL IrqPend;
-
-       /* stop counter */
-       SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_STOP);
-
-       /*
-        * ASIC problem:
-        * Each time starting the Link Sync Counter an IRQ is generated
-        * by the adapter. See problem report entry from 21.07.98
-        *
-        * Workaround:  Disable Link Sync IRQ and clear the unexpeced IRQ
-        *              if no IRQ is already pending.
-        */
-       IrqPend = SK_FALSE;
-       SK_IN32(IoC, B0_ISRC, &ISrc);
-       SK_IN32(IoC, B0_IMSK, &OrgIMsk);
-       if (Port == MAC_1) {
-               NewIMsk = OrgIMsk & ~IS_LNK_SYNC_M1;
-               if ((ISrc & IS_LNK_SYNC_M1) != 0) {
-                       IrqPend = SK_TRUE;
-               }
-       }
-       else {
-               NewIMsk = OrgIMsk & ~IS_LNK_SYNC_M2;
-               if ((ISrc & IS_LNK_SYNC_M2) != 0) {
-                       IrqPend = SK_TRUE;
-               }
-       }
-       if (!IrqPend) {
-               SK_OUT32(IoC, B0_IMSK, NewIMsk);
-       }
-
-       /* load counter */
-       SK_OUT32(IoC, MR_ADDR(Port, LNK_SYNC_INI), CntVal);
-
-       /* start counter */
-       SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_START);
-
-       if (!IrqPend) {
-               /* clear the unexpected IRQ, and restore the interrupt mask */
-               SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_CLR_IRQ);
-               SK_OUT32(IoC, B0_IMSK, OrgIMsk);
-       }
-}      /* SkGeLoadLnkSyncCnt*/
-#endif /* SK_LNK_SYNC_CNT */
-
-#if defined(SK_DIAG) || defined(SK_CFG_SYNC)
-/******************************************************************************
- *
- *     SkGeCfgSync() - Configure synchronous bandwidth for this port.
- *
- * Description:
- *     This function may be used to configure synchronous bandwidth
- *     to the specified port. This may be done any time after
- *     initializing the port. The configuration values are NOT saved
- *     in the HWAC port structure and will be overwritten any
- *     time when stopping and starting the port.
- *     Any values for the synchronous configuration will be ignored
- *     if the size of the synchronous queue is zero!
- *
- *     The default configuration for the synchronous service is
- *     TXA_ENA_FSYNC. This means if the size of
- *     the synchronous queue is unequal zero but no specific
- *     synchronous bandwidth is configured, the synchronous queue
- *     will always have the 'unlimited' transmit priority!
- *
- *     This mode will be restored if the synchronous bandwidth is
- *     deallocated ('IntTime' = 0 and 'LimCount' = 0).
- *
- * Returns:
- *     0:      success
- *     1:      parameter configuration error
- *     2:      try to configure quality of service although no
- *             synchronous queue is configured
- */
-int SkGeCfgSync(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-SK_U32 IntTime,        /* Interval Timer Value in units of 8ns */
-SK_U32 LimCount,       /* Number of bytes to transfer during IntTime */
-int            SyncMode)       /* Sync Mode: TXA_ENA_ALLOC | TXA_DIS_ALLOC | 0 */
-{
-       int Rtv;
-
-       Rtv = 0;
-
-       /* check the parameters */
-       if (LimCount > IntTime ||
-               (LimCount == 0 && IntTime != 0) ||
-               (LimCount != 0 && IntTime == 0)) {
-
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010, SKERR_HWI_E010MSG);
-               return(1);
-       }
-       
-       if (pAC->GIni.GP[Port].PXSQSize == 0) {
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E009, SKERR_HWI_E009MSG);
-               return(2);
-       }
-       
-       /* calculate register values */
-       IntTime = (IntTime / 2) * pAC->GIni.GIHstClkFact / 100;
-       LimCount = LimCount / 8;
-       
-       if (IntTime > TXA_MAX_VAL || LimCount > TXA_MAX_VAL) {
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010, SKERR_HWI_E010MSG);
-               return(1);
-       }
-
-       /*
-        * - Enable 'Force Sync' to ensure the synchronous queue
-        *   has the priority while configuring the new values.
-        * - Also 'disable alloc' to ensure the settings complies
-        *   to the SyncMode parameter.
-        * - Disable 'Rate Control' to configure the new values.
-        * - write IntTime and LimCount
-        * - start 'Rate Control' and disable 'Force Sync'
-        *   if Interval Timer or Limit Counter not zero.
-        */
-       SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL),
-               TXA_ENA_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);
-       
-       SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), IntTime);
-       SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), LimCount);
-       
-       SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL),
-               (SK_U8)(SyncMode & (TXA_ENA_ALLOC | TXA_DIS_ALLOC)));
-       
-       if (IntTime != 0 || LimCount != 0) {
-               SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_DIS_FSYNC | TXA_START_RC);
-       }
-
-       return(0);
-}      /* SkGeCfgSync */
-#endif /* SK_DIAG || SK_CFG_SYNC*/
-
-
-/******************************************************************************
- *
- *     DoInitRamQueue() - Initialize the RAM Buffer Address of a single Queue
- *
- * Desccription:
- *     If the queue is used, enable and initialize it.
- *     Make sure the queue is still reset, if it is not used.
- *
- * Returns:
- *     nothing
- */
-static void DoInitRamQueue(
-SK_AC  *pAC,                   /* adapter context */
-SK_IOC IoC,                    /* IO context */
-int            QuIoOffs,               /* Queue IO Address Offset */
-SK_U32 QuStartAddr,    /* Queue Start Address */
-SK_U32 QuEndAddr,              /* Queue End Address */
-int            QuType)                 /* Queue Type (SK_RX_SRAM_Q|SK_RX_BRAM_Q|SK_TX_RAM_Q) */
-{
-       SK_U32  RxUpThresVal;
-       SK_U32  RxLoThresVal;
-
-       if (QuStartAddr != QuEndAddr) {
-               /* calculate thresholds, assume we have a big Rx queue */
-               RxUpThresVal = (QuEndAddr + 1 - QuStartAddr - SK_RB_ULPP) / 8;
-               RxLoThresVal = (QuEndAddr + 1 - QuStartAddr - SK_RB_LLPP_B)/8;
-
-               /* build HW address format */
-               QuStartAddr = QuStartAddr / 8;
-               QuEndAddr = QuEndAddr / 8;
-
-               /* release local reset */
-               SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_RST_CLR);
-
-               /* configure addresses */
-               SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_START), QuStartAddr);
-               SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_END), QuEndAddr);
-               SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_WP), QuStartAddr);
-               SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RP), QuStartAddr);
-
-               switch (QuType) {
-               case SK_RX_SRAM_Q:
-                       /* configure threshold for small Rx Queue */
-                       RxLoThresVal += (SK_RB_LLPP_B - SK_RB_LLPP_S) / 8;
-
-                       /* continue with SK_RX_BRAM_Q */
-               case SK_RX_BRAM_Q:
-                       /* write threshold for Rx Queue */
-
-                       SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RX_UTPP), RxUpThresVal);
-                       SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RX_LTPP), RxLoThresVal);
-
-                       /* the high priority threshold not used */
-                       break;
-               case SK_TX_RAM_Q:
-                       /*
-                        * Do NOT use Store & Forward under normal operation due to
-                        * performance optimization (GENESIS only).
-                        * But if Jumbo Frames are configured (XMAC Tx FIFO is only 4 kB)
-                        * or YUKON is used ((GMAC Tx FIFO is only 1 kB)
-                        * we NEED Store & Forward of the RAM buffer.
-                        */
-                       if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK ||
-                               pAC->GIni.GIYukon) {
-                               /* enable Store & Forward Mode for the Tx Side */
-                               SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_ENA_STFWD);
-                       }
-                       break;
-               }
-
-               /* set queue operational */
-               SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_ENA_OP_MD);
-       }
-       else {
-               /* ensure the queue is still disabled */
-               SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_RST_SET);
-       }
-}      /* DoInitRamQueue */
-
-
-/******************************************************************************
- *
- *     SkGeInitRamBufs() - Initialize the RAM Buffer Queues
- *
- * Description:
- *     Initialize all RAM Buffer Queues of the specified port
- *
- * Returns:
- *     nothing
- */
-static void SkGeInitRamBufs(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT *pPrt;
-       int RxQType;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       if (pPrt->PRxQSize == SK_MIN_RXQ_SIZE) {
-               RxQType = SK_RX_SRAM_Q;         /* small Rx Queue */
-       }
-       else {
-               RxQType = SK_RX_BRAM_Q;         /* big Rx Queue */
-       }
-
-       DoInitRamQueue(pAC, IoC, pPrt->PRxQOff, pPrt->PRxQRamStart,
-               pPrt->PRxQRamEnd, RxQType);
-       
-       DoInitRamQueue(pAC, IoC, pPrt->PXsQOff, pPrt->PXsQRamStart,
-               pPrt->PXsQRamEnd, SK_TX_RAM_Q);
-       
-       DoInitRamQueue(pAC, IoC, pPrt->PXaQOff, pPrt->PXaQRamStart,
-               pPrt->PXaQRamEnd, SK_TX_RAM_Q);
-
-}      /* SkGeInitRamBufs */
-
-
-/******************************************************************************
- *
- *     SkGeInitRamIface() - Initialize the RAM Interface
- *
- * Description:
- *     This function initializes the Adapters RAM Interface.
- *
- * Note:
- *     This function is used in the diagnostics.
- *
- * Returns:
- *     nothing
- */
-static void SkGeInitRamIface(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC)            /* IO context */
-{
-       /* release local reset */
-       SK_OUT16(IoC, B3_RI_CTRL, RI_RST_CLR);
-
-       /* configure timeout values */
-       SK_OUT8(IoC, B3_RI_WTO_R1, SK_RI_TO_53);
-       SK_OUT8(IoC, B3_RI_WTO_XA1, SK_RI_TO_53);
-       SK_OUT8(IoC, B3_RI_WTO_XS1, SK_RI_TO_53);
-       SK_OUT8(IoC, B3_RI_RTO_R1, SK_RI_TO_53);
-       SK_OUT8(IoC, B3_RI_RTO_XA1, SK_RI_TO_53);
-       SK_OUT8(IoC, B3_RI_RTO_XS1, SK_RI_TO_53);
-       SK_OUT8(IoC, B3_RI_WTO_R2, SK_RI_TO_53);
-       SK_OUT8(IoC, B3_RI_WTO_XA2, SK_RI_TO_53);
-       SK_OUT8(IoC, B3_RI_WTO_XS2, SK_RI_TO_53);
-       SK_OUT8(IoC, B3_RI_RTO_R2, SK_RI_TO_53);
-       SK_OUT8(IoC, B3_RI_RTO_XA2, SK_RI_TO_53);
-       SK_OUT8(IoC, B3_RI_RTO_XS2, SK_RI_TO_53);
-
-}      /* SkGeInitRamIface */
-
-
-/******************************************************************************
- *
- *     SkGeInitBmu() - Initialize the BMU state machines
- *
- * Description:
- *     Initialize all BMU state machines of the specified port
- *
- * Returns:
- *     nothing
- */
-static void SkGeInitBmu(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;
-       SK_U32          RxWm;
-       SK_U32          TxWm;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       RxWm = SK_BMU_RX_WM;
-       TxWm = SK_BMU_TX_WM;
-       
-       if (!pAC->GIni.GIPciSlot64 && !pAC->GIni.GIPciClock66) {
-               /* for better performance */
-               RxWm /= 2;
-               TxWm /= 2;
-       }
-
-       /* Rx Queue: Release all local resets and set the watermark */
-       SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_CLR_RESET);
-       SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_F), RxWm);
-
-       /*
-        * Tx Queue: Release all local resets if the queue is used !
-        *              set watermark
-        */
-       if (pPrt->PXSQSize != 0) {
-               SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_CLR_RESET);
-               SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_F), TxWm);
-       }
-       
-       if (pPrt->PXAQSize != 0) {
-               SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_CLR_RESET);
-               SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_F), TxWm);
-       }
-       /*
-        * Do NOT enable the descriptor poll timers here, because
-        * the descriptor addresses are not specified yet.
-        */
-}      /* SkGeInitBmu */
-
-
-/******************************************************************************
- *
- *     TestStopBit() - Test the stop bit of the queue
- *
- * Description:
- *     Stopping a queue is not as simple as it seems to be.
- *     If descriptor polling is enabled, it may happen
- *     that RX/TX stop is done and SV idle is NOT set.
- *     In this case we have to issue another stop command.
- *
- * Returns:
- *     The queues control status register
- */
-static SK_U32 TestStopBit(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* IO Context */
-int            QuIoOffs)       /* Queue IO Address Offset */
-{
-       SK_U32  QuCsr;  /* CSR contents */
-
-       SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr);
-       
-       if ((QuCsr & (CSR_STOP | CSR_SV_IDLE)) == 0) {
-               /* Stop Descriptor overridden by start command */
-               SK_OUT32(IoC, Q_ADDR(QuIoOffs, Q_CSR), CSR_STOP);
-
-               SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr);
-       }
-       
-       return(QuCsr);
-}      /* TestStopBit */
-
-
-/******************************************************************************
- *
- *     SkGeStopPort() - Stop the Rx/Tx activity of the port 'Port'.
- *
- * Description:
- *     After calling this function the descriptor rings and Rx and Tx
- *     queues of this port may be reconfigured.
- *
- *     It is possible to stop the receive and transmit path separate or
- *     both together.
- *
- *     Dir =   SK_STOP_TX      Stops the transmit path only and resets the MAC.
- *                             The receive queue is still active and
- *                             the pending Rx frames may be still transferred
- *                             into the RxD.
- *             SK_STOP_RX      Stop the receive path. The tansmit path
- *                             has to be stopped once before.
- *             SK_STOP_ALL     SK_STOP_TX + SK_STOP_RX
- *
- *     RstMode = SK_SOFT_RST   Resets the MAC. The PHY is still alive.
- *                     SK_HARD_RST     Resets the MAC and the PHY.
- *
- * Example:
- *     1) A Link Down event was signaled for a port. Therefore the activity
- *     of this port should be stopped and a hardware reset should be issued
- *     to enable the workaround of XMAC Errata #2. But the received frames
- *     should not be discarded.
- *             ...
- *             SkGeStopPort(pAC, IoC, Port, SK_STOP_TX, SK_HARD_RST);
- *             (transfer all pending Rx frames)
- *             SkGeStopPort(pAC, IoC, Port, SK_STOP_RX, SK_HARD_RST);
- *             ...
- *
- *     2) An event was issued which request the driver to switch
- *     the 'virtual active' link to an other already active port
- *     as soon as possible. The frames in the receive queue of this
- *     port may be lost. But the PHY must not be reset during this
- *     event.
- *             ...
- *             SkGeStopPort(pAC, IoC, Port, SK_STOP_ALL, SK_SOFT_RST);
- *             ...
- *
- * Extended Description:
- *     If SK_STOP_TX is set,
- *             o disable the MAC's receive and transmitter to prevent
- *               from sending incomplete frames
- *             o stop the port's transmit queues before terminating the
- *               BMUs to prevent from performing incomplete PCI cycles
- *               on the PCI bus
- *             - The network Rx and Tx activity and PCI Tx transfer is
- *               disabled now.
- *             o reset the MAC depending on the RstMode
- *             o Stop Interval Timer and Limit Counter of Tx Arbiter,
- *               also disable Force Sync bit and Enable Alloc bit.
- *             o perform a local reset of the port's Tx path
- *                     - reset the PCI FIFO of the async Tx queue
- *                     - reset the PCI FIFO of the sync Tx queue
- *                     - reset the RAM Buffer async Tx queue
- *                     - reset the RAM Buffer sync Tx queue
- *                     - reset the MAC Tx FIFO
- *             o switch Link and Tx LED off, stop the LED counters
- *
- *     If SK_STOP_RX is set,
- *             o stop the port's receive queue
- *             - The path data transfer activity is fully stopped now.
- *             o perform a local reset of the port's Rx path
- *                     - reset the PCI FIFO of the Rx queue
- *                     - reset the RAM Buffer receive queue
- *                     - reset the MAC Rx FIFO
- *             o switch Rx LED off, stop the LED counter
- *
- *     If all ports are stopped,
- *             o reset the RAM Interface.
- *
- * Notes:
- *     o This function may be called during the driver states RESET_PORT and
- *       SWITCH_PORT.
- */
-void SkGeStopPort(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* I/O context */
-int            Port,   /* port to stop (MAC_1 + n) */
-int            Dir,    /* Direction to Stop (SK_STOP_RX, SK_STOP_TX, SK_STOP_ALL) */
-int            RstMode)/* Reset Mode (SK_SOFT_RST, SK_HARD_RST) */
-{
-#ifndef SK_DIAG
-       SK_EVPARA Para;
-#endif /* !SK_DIAG */
-       SK_GEPORT *pPrt;
-       SK_U32  DWord;
-       SK_U32  XsCsr;
-       SK_U32  XaCsr;
-       SK_U64  ToutStart;
-       int             i;
-       int             ToutCnt;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       if ((Dir & SK_STOP_TX) != 0) {
-               /* disable receiver and transmitter */
-               SkMacRxTxDisable(pAC, IoC, Port);
-               
-               /* stop both transmit queues */
-               /*
-                * If the BMU is in the reset state CSR_STOP will terminate
-                * immediately.
-                */
-               SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_STOP);
-               SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_STOP);
-
-               ToutStart = SkOsGetTime(pAC);
-               ToutCnt = 0;
-               do {
-                       /*
-                        * Clear packet arbiter timeout to make sure
-                        * this loop will terminate.
-                        */
-                       SK_OUT16(IoC, B3_PA_CTRL, (SK_U16)((Port == MAC_1) ?
-                               PA_CLR_TO_TX1 : PA_CLR_TO_TX2));
-
-                       /*
-                        * If the transfer stucks at the MAC the STOP command will not
-                        * terminate if we don't flush the XMAC's transmit FIFO !
-                        */
-                       SkMacFlushTxFifo(pAC, IoC, Port);
-
-                       XsCsr = TestStopBit(pAC, IoC, pPrt->PXsQOff);
-                       XaCsr = TestStopBit(pAC, IoC, pPrt->PXaQOff);
-
-                       if (SkOsGetTime(pAC) - ToutStart > (SK_TICKS_PER_SEC / 18)) {
-                               /*
-                                * Timeout of 1/18 second reached.
-                                * This needs to be checked at 1/18 sec only.
-                                */
-                               ToutCnt++;
-                               if (ToutCnt > 1) {
-                                       /* Might be a problem when the driver event handler
-                                        * calls StopPort again. XXX.
-                                        */
-
-                                       /* Fatal Error, Loop aborted */
-                                       SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E018,
-                                               SKERR_HWI_E018MSG);
-#ifndef SK_DIAG
-                                       Para.Para64 = Port;
-                                       SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
-#endif /* !SK_DIAG */
-                                       return;
-                               }
-                               /*
-                                * Cache incoherency workaround: Assume a start command
-                                * has been lost while sending the frame.
-                                */
-                               ToutStart = SkOsGetTime(pAC);
-
-                               if ((XsCsr & CSR_STOP) != 0) {
-                                       SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_START);
-                               }
-                               if ((XaCsr & CSR_STOP) != 0) {
-                                       SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_START);
-                               }
-                       }
-
-                       /*
-                        * Because of the ASIC problem report entry from 21.08.1998 it is
-                        * required to wait until CSR_STOP is reset and CSR_SV_IDLE is set.
-                        */
-               } while ((XsCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE ||
-                                (XaCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE);
-
-               /* Reset the MAC depending on the RstMode */
-               if (RstMode == SK_SOFT_RST) {
-                       SkMacSoftRst(pAC, IoC, Port);
-               }
-               else {
-                       SkMacHardRst(pAC, IoC, Port);
-               }
-               
-               /* Disable Force Sync bit and Enable Alloc bit */
-               SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL),
-                       TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);
-               
-               /* Stop Interval Timer and Limit Counter of Tx Arbiter */
-               SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), 0L);
-               SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), 0L);
-
-               /* Perform a local reset of the port's Tx path */
-
-               /* Reset the PCI FIFO of the async Tx queue */
-               SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_SET_RESET);
-               /* Reset the PCI FIFO of the sync Tx queue */
-               SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_SET_RESET);
-               /* Reset the RAM Buffer async Tx queue */
-               SK_OUT8(IoC, RB_ADDR(pPrt->PXaQOff, RB_CTRL), RB_RST_SET);
-               /* Reset the RAM Buffer sync Tx queue */
-               SK_OUT8(IoC, RB_ADDR(pPrt->PXsQOff, RB_CTRL), RB_RST_SET);
-               
-               /* Reset Tx MAC FIFO */
-#ifdef GENESIS
-               if (pAC->GIni.GIGenesis) {
-                       /* Note: MFF_RST_SET does NOT reset the XMAC ! */
-                       SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_RST_SET);
-
-                       /* switch Link and Tx LED off, stop the LED counters */
-                       /* Link LED is switched off by the RLMT and the Diag itself */
-                       SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_DIS);
-               }
-#endif /* GENESIS */
-       
-#ifdef YUKON
-               if (pAC->GIni.GIYukon) {
-                       /* Reset TX MAC FIFO */
-                       SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_SET);
-               }
-#endif /* YUKON */
-       }
-
-       if ((Dir & SK_STOP_RX) != 0) {
-               /*
-                * The RX Stop Command will not terminate if no buffers
-                * are queued in the RxD ring. But it will always reach
-                * the Idle state. Therefore we can use this feature to
-                * stop the transfer of received packets.
-                */
-               /* stop the port's receive queue */
-               SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_STOP);
-               
-               i = 100;
-               do {
-                       /*
-                        * Clear packet arbiter timeout to make sure
-                        * this loop will terminate
-                        */
-                       SK_OUT16(IoC, B3_PA_CTRL, (SK_U16)((Port == MAC_1) ?
-                               PA_CLR_TO_RX1 : PA_CLR_TO_RX2));
-
-                       DWord = TestStopBit(pAC, IoC, pPrt->PRxQOff);
-
-                       /* timeout if i==0 (bug fix for #10748) */
-                       if (--i == 0) {
-                               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E024,
-                                       SKERR_HWI_E024MSG);
-                               break;
-                       }
-                       /*
-                        * because of the ASIC problem report entry from 21.08.98
-                        * it is required to wait until CSR_STOP is reset and
-                        * CSR_SV_IDLE is set.
-                        */
-               } while ((DWord & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE);
-
-               /* The path data transfer activity is fully stopped now */
-
-               /* Perform a local reset of the port's Rx path */
-
-                /*     Reset the PCI FIFO of the Rx queue */
-               SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_SET_RESET);
-               /* Reset the RAM Buffer receive queue */
-               SK_OUT8(IoC, RB_ADDR(pPrt->PRxQOff, RB_CTRL), RB_RST_SET);
-
-               /* Reset Rx MAC FIFO */
-#ifdef GENESIS
-               if (pAC->GIni.GIGenesis) {
-                       
-                       SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_SET);
-
-                       /* switch Rx LED off, stop the LED counter */
-                       SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_DIS);
-               }
-#endif /* GENESIS */
-       
-#ifdef YUKON
-               if (pAC->GIni.GIYukon) {
-                       /* Reset Rx MAC FIFO */
-                       SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_SET);
-               }
-#endif /* YUKON */
-       }
-}      /* SkGeStopPort */
-
-
-/******************************************************************************
- *
- *     SkGeInit0() - Level 0 Initialization
- *
- * Description:
- *     - Initialize the BMU address offsets
- *
- * Returns:
- *     nothing
- */
-static void SkGeInit0(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC)            /* IO context */
-{
-       int i;
-       SK_GEPORT *pPrt;
-
-       for (i = 0; i < SK_MAX_MACS; i++) {
-               pPrt = &pAC->GIni.GP[i];
-
-               pPrt->PState = SK_PRT_RESET;
-               pPrt->PRxQOff = QOffTab[i].RxQOff;
-               pPrt->PXsQOff = QOffTab[i].XsQOff;
-               pPrt->PXaQOff = QOffTab[i].XaQOff;
-               pPrt->PCheckPar = SK_FALSE;
-               pPrt->PIsave = 0;
-               pPrt->PPrevShorts = 0;
-               pPrt->PLinkResCt = 0;
-               pPrt->PAutoNegTOCt = 0;
-               pPrt->PPrevRx = 0;
-               pPrt->PPrevFcs = 0;
-               pPrt->PRxLim = SK_DEF_RX_WA_LIM;
-               pPrt->PLinkMode = (SK_U8)SK_LMODE_AUTOFULL;
-               pPrt->PLinkSpeedCap = (SK_U8)SK_LSPEED_CAP_1000MBPS;
-               pPrt->PLinkSpeed = (SK_U8)SK_LSPEED_1000MBPS;
-               pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_UNKNOWN;
-               pPrt->PLinkModeConf = (SK_U8)SK_LMODE_AUTOSENSE;
-               pPrt->PFlowCtrlMode = (SK_U8)SK_FLOW_MODE_SYM_OR_REM;
-               pPrt->PLinkCap = (SK_U8)(SK_LMODE_CAP_HALF | SK_LMODE_CAP_FULL |
-                       SK_LMODE_CAP_AUTOHALF | SK_LMODE_CAP_AUTOFULL);
-               pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
-               pPrt->PFlowCtrlCap = (SK_U8)SK_FLOW_MODE_SYM_OR_REM;
-               pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE;
-               pPrt->PMSCap = 0;
-               pPrt->PMSMode = (SK_U8)SK_MS_MODE_AUTO;
-               pPrt->PMSStatus = (SK_U8)SK_MS_STAT_UNSET;
-               pPrt->PLipaAutoNeg = (SK_U8)SK_LIPA_UNKNOWN;
-               pPrt->PAutoNegFail = SK_FALSE;
-               pPrt->PHWLinkUp = SK_FALSE;
-               pPrt->PLinkBroken = SK_TRUE; /* See WA code */
-               pPrt->PPhyPowerState = PHY_PM_OPERATIONAL_MODE;
-               pPrt->PMacColThres = TX_COL_DEF;
-               pPrt->PMacJamLen = TX_JAM_LEN_DEF;
-               pPrt->PMacJamIpgVal     = TX_JAM_IPG_DEF;
-               pPrt->PMacJamIpgData = TX_IPG_JAM_DEF;
-               pPrt->PMacIpgData = IPG_DATA_DEF;
-               pPrt->PMacLimit4 = SK_FALSE;
-       }
-
-       pAC->GIni.GIPortUsage = SK_RED_LINK;
-       pAC->GIni.GILedBlinkCtrl = (SK_U16)OemConfig.Value;
-       pAC->GIni.GIValIrqMask = IS_ALL_MSK;
-
-}      /* SkGeInit0*/
-
-
-/******************************************************************************
- *
- *     SkGeInit1() - Level 1 Initialization
- *
- * Description:
- *     o Do a software reset.
- *     o Clear all reset bits.
- *     o Verify that the detected hardware is present.
- *       Return an error if not.
- *     o Get the hardware configuration
- *             + Read the number of MACs/Ports.
- *             + Read the RAM size.
- *             + Read the PCI Revision Id.
- *             + Find out the adapters host clock speed
- *             + Read and check the PHY type
- *
- * Returns:
- *     0:      success
- *     5:      Unexpected PHY type detected
- *     6:      HW self test failed
- */
-static int SkGeInit1(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC)            /* IO context */
-{
-       SK_U8   Byte;
-       SK_U16  Word;
-       SK_U16  CtrlStat;
-       SK_U32  DWord;
-       int     RetVal;
-       int     i;
-
-       RetVal = 0;
-
-       /* save CLK_RUN bits (YUKON-Lite) */
-       SK_IN16(IoC, B0_CTST, &CtrlStat);
-
-       /* do the SW-reset */
-       SK_OUT8(IoC, B0_CTST, CS_RST_SET);
-
-       /* release the SW-reset */
-       SK_OUT8(IoC, B0_CTST, CS_RST_CLR);
-
-       /* reset all error bits in the PCI STATUS register */
-       /*
-        * Note: PCI Cfg cycles cannot be used, because they are not
-        *               available on some platforms after 'boot time'.
-        */
-       SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);
-       
-       SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
-       SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS));
-       SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
-
-       /* release Master Reset */
-       SK_OUT8(IoC, B0_CTST, CS_MRST_CLR);
-
-#ifdef CLK_RUN
-       CtrlStat |= CS_CLK_RUN_ENA;
-#endif /* CLK_RUN */
-
-       /* restore CLK_RUN bits */
-       SK_OUT16(IoC, B0_CTST, (SK_U16)(CtrlStat &
-               (CS_CLK_RUN_HOT | CS_CLK_RUN_RST | CS_CLK_RUN_ENA)));
-
-       /* read Chip Identification Number */
-       SK_IN8(IoC, B2_CHIP_ID, &Byte);
-       pAC->GIni.GIChipId = Byte;
-       
-       /* read number of MACs */
-       SK_IN8(IoC, B2_MAC_CFG, &Byte);
-       pAC->GIni.GIMacsFound = (Byte & CFG_SNG_MAC) ? 1 : 2;
-       
-       /* get Chip Revision Number */
-       pAC->GIni.GIChipRev = (SK_U8)((Byte & CFG_CHIP_R_MSK) >> 4);
-
-       /* get diff. PCI parameters */
-       SK_IN16(IoC, B0_CTST, &CtrlStat);
-       
-       /* read the adapters RAM size */
-       SK_IN8(IoC, B2_E_0, &Byte);
-       
-       pAC->GIni.GIGenesis = SK_FALSE;
-       pAC->GIni.GIYukon = SK_FALSE;
-       pAC->GIni.GIYukonLite = SK_FALSE;
-
-#ifdef GENESIS
-       if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
-
-               pAC->GIni.GIGenesis = SK_TRUE;
-
-               if (Byte == (SK_U8)3) {                                         
-                       /* special case: 4 x 64k x 36, offset = 0x80000 */
-                       pAC->GIni.GIRamSize = 1024;
-                       pAC->GIni.GIRamOffs = (SK_U32)512 * 1024;
-               }
-               else {
-                       pAC->GIni.GIRamSize = (int)Byte * 512;
-                       pAC->GIni.GIRamOffs = 0;
-               }
-               /* all GE adapters work with 53.125 MHz host clock */
-               pAC->GIni.GIHstClkFact = SK_FACT_53;
-               
-               /* set Descr. Poll Timer Init Value to 250 ms */
-               pAC->GIni.GIPollTimerVal =
-                       SK_DPOLL_DEF * (SK_U32)pAC->GIni.GIHstClkFact / 100;
-       }
-#endif /* GENESIS */
-       
-#ifdef YUKON
-       if (pAC->GIni.GIChipId != CHIP_ID_GENESIS) {
-               
-               pAC->GIni.GIYukon = SK_TRUE;
-               
-               pAC->GIni.GIRamSize = (Byte == (SK_U8)0) ? 128 : (int)Byte * 4;
-               
-               pAC->GIni.GIRamOffs = 0;
-               
-               /* WA for chip Rev. A */
-               pAC->GIni.GIWolOffs = (pAC->GIni.GIChipId == CHIP_ID_YUKON &&
-                       pAC->GIni.GIChipRev == 0) ? WOL_REG_OFFS : 0;
-               
-               /* get PM Capabilities of PCI config space */
-               SK_IN16(IoC, PCI_C(PCI_PM_CAP_REG), &Word);
-
-               /* check if VAUX is available */
-               if (((CtrlStat & CS_VAUX_AVAIL) != 0) &&
-                       /* check also if PME from D3cold is set */
-                       ((Word & PCI_PME_D3C_SUP) != 0)) {
-                       /* set entry in GE init struct */
-                       pAC->GIni.GIVauxAvail = SK_TRUE;
-               }
-               
-               if (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE) {
-                       /* this is Rev. A1 */
-                       pAC->GIni.GIYukonLite = SK_TRUE;
-               }
-               else {
-                       /* save Flash-Address Register */
-                       SK_IN32(IoC, B2_FAR, &DWord);
-
-                       /* test Flash-Address Register */
-                       SK_OUT8(IoC, B2_FAR + 3, 0xff);
-                       SK_IN8(IoC, B2_FAR + 3, &Byte);
-
-                       if (Byte != 0) {
-                               /* this is Rev. A0 */
-                               pAC->GIni.GIYukonLite = SK_TRUE;
-
-                               /* restore Flash-Address Register */
-                               SK_OUT32(IoC, B2_FAR, DWord);
-                       }
-               }
-
-               /* switch power to VCC (WA for VAUX problem) */
-               SK_OUT8(IoC, B0_POWER_CTRL, (SK_U8)(PC_VAUX_ENA | PC_VCC_ENA |
-                       PC_VAUX_OFF | PC_VCC_ON));
-
-               /* read the Interrupt source */
-               SK_IN32(IoC, B0_ISRC, &DWord);
-               
-               if ((DWord & IS_HW_ERR) != 0) {
-                       /* read the HW Error Interrupt source */
-                       SK_IN32(IoC, B0_HWE_ISRC, &DWord);
-                       
-                       if ((DWord & IS_IRQ_SENSOR) != 0) {
-                               /* disable HW Error IRQ */
-                               pAC->GIni.GIValIrqMask &= ~IS_HW_ERR;
-                       }
-               }
-               
-               for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
-                       /* set GMAC Link Control reset */
-                       SK_OUT16(IoC, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_SET);
-
-                       /* clear GMAC Link Control reset */
-                       SK_OUT16(IoC, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
-               }
-               /* all YU chips work with 78.125 MHz host clock */
-               pAC->GIni.GIHstClkFact = SK_FACT_78;
-               
-               pAC->GIni.GIPollTimerVal = SK_DPOLL_MAX;        /* 215 ms */
-       }
-#endif /* YUKON */
-
-       /* check if 64-bit PCI Slot is present */
-       pAC->GIni.GIPciSlot64 = (SK_BOOL)((CtrlStat & CS_BUS_SLOT_SZ) != 0);
-       
-       /* check if 66 MHz PCI Clock is active */
-       pAC->GIni.GIPciClock66 = (SK_BOOL)((CtrlStat & CS_BUS_CLOCK) != 0);
-
-       /* read PCI HW Revision Id. */
-       SK_IN8(IoC, PCI_C(PCI_REV_ID), &Byte);
-       pAC->GIni.GIPciHwRev = Byte;
-
-       /* read the PMD type */
-       SK_IN8(IoC, B2_PMD_TYP, &Byte);
-       pAC->GIni.GICopperType = (SK_U8)(Byte == 'T');
-
-       /* read the PHY type */
-       SK_IN8(IoC, B2_E_1, &Byte);
-
-       Byte &= 0x0f;   /* the PHY type is stored in the lower nibble */
-       for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
-               
-#ifdef GENESIS
-               if (pAC->GIni.GIGenesis) {
-                       switch (Byte) {
-                       case SK_PHY_XMAC:
-                               pAC->GIni.GP[i].PhyAddr = PHY_ADDR_XMAC;
-                               break;
-                       case SK_PHY_BCOM:
-                               pAC->GIni.GP[i].PhyAddr = PHY_ADDR_BCOM;
-                               pAC->GIni.GP[i].PMSCap = (SK_U8)(SK_MS_CAP_AUTO |
-                                       SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE);
-                               break;
-#ifdef OTHER_PHY
-                       case SK_PHY_LONE:
-                               pAC->GIni.GP[i].PhyAddr = PHY_ADDR_LONE;
-                               break;
-                       case SK_PHY_NAT:
-                               pAC->GIni.GP[i].PhyAddr = PHY_ADDR_NAT;
-                               break;
-#endif /* OTHER_PHY */
-                       default:
-                               /* ERROR: unexpected PHY type detected */
-                               RetVal = 5;
-                               break;
-                       }
-               }
-#endif /* GENESIS */
-       
-#ifdef YUKON
-               if (pAC->GIni.GIYukon) {
-                       
-                       if (Byte < (SK_U8)SK_PHY_MARV_COPPER) {
-                               /* if this field is not initialized */
-                               Byte = (SK_U8)SK_PHY_MARV_COPPER;
-                               
-                               pAC->GIni.GICopperType = SK_TRUE;
-                       }
-                       
-                       pAC->GIni.GP[i].PhyAddr = PHY_ADDR_MARV;
-                       
-                       if (pAC->GIni.GICopperType) {
-
-                               pAC->GIni.GP[i].PLinkSpeedCap = (SK_U8)(SK_LSPEED_CAP_AUTO |
-                                       SK_LSPEED_CAP_10MBPS | SK_LSPEED_CAP_100MBPS |
-                                       SK_LSPEED_CAP_1000MBPS);
-                               
-                               pAC->GIni.GP[i].PLinkSpeed = (SK_U8)SK_LSPEED_AUTO;
-                               
-                               pAC->GIni.GP[i].PMSCap = (SK_U8)(SK_MS_CAP_AUTO |
-                                       SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE);
-                       }
-                       else {
-                               Byte = (SK_U8)SK_PHY_MARV_FIBER;
-                       }
-               }
-#endif /* YUKON */
-               
-               pAC->GIni.GP[i].PhyType = (int)Byte;
-               
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
-                       ("PHY type: %d  PHY addr: %04x\n", Byte,
-                       pAC->GIni.GP[i].PhyAddr));
-       }
-       
-       /* get MAC Type & set function pointers dependent on */
-#ifdef GENESIS
-       if (pAC->GIni.GIGenesis) {
-               
-               pAC->GIni.GIMacType = SK_MAC_XMAC;
-
-               pAC->GIni.GIFunc.pFnMacUpdateStats      = SkXmUpdateStats;
-               pAC->GIni.GIFunc.pFnMacStatistic        = SkXmMacStatistic;
-               pAC->GIni.GIFunc.pFnMacResetCounter     = SkXmResetCounter;
-               pAC->GIni.GIFunc.pFnMacOverflow         = SkXmOverflowStatus;
-       }
-#endif /* GENESIS */
-       
-#ifdef YUKON
-       if (pAC->GIni.GIYukon) {
-               
-               pAC->GIni.GIMacType = SK_MAC_GMAC;
-
-               pAC->GIni.GIFunc.pFnMacUpdateStats      = SkGmUpdateStats;
-               pAC->GIni.GIFunc.pFnMacStatistic        = SkGmMacStatistic;
-               pAC->GIni.GIFunc.pFnMacResetCounter     = SkGmResetCounter;
-               pAC->GIni.GIFunc.pFnMacOverflow         = SkGmOverflowStatus;
-
-#ifdef SPECIAL_HANDLING
-               if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {
-                       /* check HW self test result */
-                       SK_IN8(IoC, B2_E_3, &Byte);
-                       if (Byte & B2_E3_RES_MASK) {
-                               RetVal = 6;
-                       }
-               }
-#endif
-       }
-#endif /* YUKON */
-       
-       return(RetVal);
-}      /* SkGeInit1 */
-
-
-/******************************************************************************
- *
- *     SkGeInit2() - Level 2 Initialization
- *
- * Description:
- *     - start the Blink Source Counter
- *     - start the Descriptor Poll Timer
- *     - configure the MAC-Arbiter
- *     - configure the Packet-Arbiter
- *     - enable the Tx Arbiters
- *     - enable the RAM Interface Arbiter
- *
- * Returns:
- *     nothing
- */
-static void SkGeInit2(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC)            /* IO context */
-{
-#ifdef GENESIS
-       SK_U32  DWord;
-#endif /* GENESIS */
-       int             i;
-
-       /* start the Descriptor Poll Timer */
-       if (pAC->GIni.GIPollTimerVal != 0) {
-               if (pAC->GIni.GIPollTimerVal > SK_DPOLL_MAX) {
-                       pAC->GIni.GIPollTimerVal = SK_DPOLL_MAX;
-
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E017, SKERR_HWI_E017MSG);
-               }
-               SK_OUT32(IoC, B28_DPT_INI, pAC->GIni.GIPollTimerVal);
-               SK_OUT8(IoC, B28_DPT_CTRL, DPT_START);
-       }
-
-#ifdef GENESIS
-       if (pAC->GIni.GIGenesis) {
-               /* start the Blink Source Counter */
-               DWord = SK_BLK_DUR * (SK_U32)pAC->GIni.GIHstClkFact / 100;
-
-               SK_OUT32(IoC, B2_BSC_INI, DWord);
-               SK_OUT8(IoC, B2_BSC_CTRL, BSC_START);
-
-               /*
-                * Configure the MAC Arbiter and the Packet Arbiter.
-                * They will be started once and never be stopped.
-                */
-               SkGeInitMacArb(pAC, IoC);
-
-               SkGeInitPktArb(pAC, IoC);
-       }
-#endif /* GENESIS */
-       
-#ifdef YUKON
-       if (pAC->GIni.GIYukon) {
-               /* start Time Stamp Timer */
-               SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8)GMT_ST_START);
-       }
-#endif /* YUKON */
-
-       /* enable the Tx Arbiters */
-       for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
-               SK_OUT8(IoC, MR_ADDR(i, TXA_CTRL), TXA_ENA_ARB);
-       }
-
-       /* enable the RAM Interface Arbiter */
-       SkGeInitRamIface(pAC, IoC);
-
-}      /* SkGeInit2 */
-
-/******************************************************************************
- *
- *     SkGeInit() - Initialize the GE Adapter with the specified level.
- *
- * Description:
- *     Level   0:      Initialize the Module structures.
- *     Level   1:      Generic Hardware Initialization. The IOP/MemBase pointer has
- *                             to be set before calling this level.
- *
- *                     o Do a software reset.
- *                     o Clear all reset bits.
- *                     o Verify that the detected hardware is present.
- *                       Return an error if not.
- *                     o Get the hardware configuration
- *                             + Set GIMacsFound with the number of MACs.
- *                             + Store the RAM size in GIRamSize.
- *                             + Save the PCI Revision ID in GIPciHwRev.
- *                     o return an error
- *                             if Number of MACs > SK_MAX_MACS
- *
- *                     After returning from Level 0 the adapter
- *                     may be accessed with IO operations.
- *
- *     Level   2:      start the Blink Source Counter
- *
- * Returns:
- *     0:      success
- *     1:      Number of MACs exceeds SK_MAX_MACS      (after level 1)
- *     2:      Adapter not present or not accessible
- *     3:      Illegal initialization level
- *     4:      Initialization Level 1 Call missing
- *     5:      Unexpected PHY type detected
- *     6:      HW self test failed
- */
-int    SkGeInit(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Level)          /* initialization level */
-{
-       int             RetVal;         /* return value */
-       SK_U32  DWord;
-
-       RetVal = 0;
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
-               ("SkGeInit(Level %d)\n", Level));
-
-       switch (Level) {
-       case SK_INIT_DATA:
-               /* Initialization Level 0 */
-               SkGeInit0(pAC, IoC);
-               pAC->GIni.GILevel = SK_INIT_DATA;
-               break;
-       
-       case SK_INIT_IO:
-               /* Initialization Level 1 */
-               RetVal = SkGeInit1(pAC, IoC);
-               if (RetVal != 0) {
-                       break;
-               }
-
-               /* check if the adapter seems to be accessible */
-               SK_OUT32(IoC, B2_IRQM_INI, SK_TEST_VAL);
-               SK_IN32(IoC, B2_IRQM_INI, &DWord);
-               SK_OUT32(IoC, B2_IRQM_INI, 0L);
-               
-               if (DWord != SK_TEST_VAL) {
-                       RetVal = 2;
-                       break;
-               }
-
-               /* check if the number of GIMacsFound matches SK_MAX_MACS */
-               if (pAC->GIni.GIMacsFound > SK_MAX_MACS) {
-                       RetVal = 1;
-                       break;
-               }
-
-               /* Level 1 successfully passed */
-               pAC->GIni.GILevel = SK_INIT_IO;
-               break;
-       
-       case SK_INIT_RUN:
-               /* Initialization Level 2 */
-               if (pAC->GIni.GILevel != SK_INIT_IO) {
-#ifndef SK_DIAG
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E002, SKERR_HWI_E002MSG);
-#endif /* !SK_DIAG */
-                       RetVal = 4;
-                       break;
-               }
-               SkGeInit2(pAC, IoC);
-
-               /* Level 2 successfully passed */
-               pAC->GIni.GILevel = SK_INIT_RUN;
-               break;
-       
-       default:
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E003, SKERR_HWI_E003MSG);
-               RetVal = 3;
-               break;
-       }
-
-       return(RetVal);
-}      /* SkGeInit */
-
-
-/******************************************************************************
- *
- *     SkGeDeInit() - Deinitialize the adapter
- *
- * Description:
- *     All ports of the adapter will be stopped if not already done.
- *     Do a software reset and switch off all LEDs.
- *
- * Returns:
- *     nothing
- */
-void SkGeDeInit(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC)            /* IO context */
-{
-       int     i;
-       SK_U16  Word;
-
-#if (!defined(SK_SLIM) && !defined(VCPU))
-       /* ensure I2C is ready */
-       SkI2cWaitIrq(pAC, IoC);
-#endif 
-
-       /* stop all current transfer activity */
-       for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
-               if (pAC->GIni.GP[i].PState != SK_PRT_STOP &&
-                       pAC->GIni.GP[i].PState != SK_PRT_RESET) {
-
-                       SkGeStopPort(pAC, IoC, i, SK_STOP_ALL, SK_HARD_RST);
-               }
-       }
-
-       /* Reset all bits in the PCI STATUS register */
-       /*
-        * Note: PCI Cfg cycles cannot be used, because they are not
-        *       available on some platforms after 'boot time'.
-        */
-       SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);
-       
-       SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
-       SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS));
-       SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
-
-       /* do the reset, all LEDs are switched off now */
-       SK_OUT8(IoC, B0_CTST, CS_RST_SET);
-       
-       pAC->GIni.GILevel = SK_INIT_DATA;
-}      /* SkGeDeInit */
-
-
-/******************************************************************************
- *
- *     SkGeInitPort()  Initialize the specified port.
- *
- * Description:
- *     PRxQSize, PXSQSize, and PXAQSize has to be
- *     configured for the specified port before calling this function.
- *  The descriptor rings has to be initialized too.
- *
- *     o (Re)configure queues of the specified port.
- *     o configure the MAC of the specified port.
- *     o put ASIC and MAC(s) in operational mode.
- *     o initialize Rx/Tx and Sync LED
- *     o initialize RAM Buffers and MAC FIFOs
- *
- *     The port is ready to connect when returning.
- *
- * Note:
- *     The MAC's Rx and Tx state machine is still disabled when returning.
- *
- * Returns:
- *     0:      success
- *     1:      Queue size initialization error. The configured values
- *             for PRxQSize, PXSQSize, or PXAQSize are invalid for one
- *             or more queues. The specified port was NOT initialized.
- *             An error log entry was generated.
- *     2:      The port has to be stopped before it can be initialized again.
- */
-int SkGeInitPort(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port to configure */
-{
-       SK_GEPORT *pPrt;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       if (SkGeCheckQSize(pAC, Port) != 0) {
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E004, SKERR_HWI_E004MSG);
-               return(1);
-       }
-       
-       if (pPrt->PState == SK_PRT_INIT || pPrt->PState == SK_PRT_RUN) {
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E005, SKERR_HWI_E005MSG);
-               return(2);
-       }
-
-       /* configuration ok, initialize the Port now */
-
-#ifdef GENESIS
-       if (pAC->GIni.GIGenesis) {
-               /* initialize Rx, Tx and Link LED */
-               /*
-                * If 1000BT Phy needs LED initialization than swap
-                * LED and XMAC initialization order
-                */
-               SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_ENA);
-               SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_ENA);
-               /* The Link LED is initialized by RLMT or Diagnostics itself */
-               
-               SkXmInitMac(pAC, IoC, Port);
-       }
-#endif /* GENESIS */
-       
-#ifdef YUKON
-       if (pAC->GIni.GIYukon) {
-
-               SkGmInitMac(pAC, IoC, Port);
-       }
-#endif /* YUKON */
-       
-       /* do NOT initialize the Link Sync Counter */
-
-       SkGeInitMacFifo(pAC, IoC, Port);
-       
-       SkGeInitRamBufs(pAC, IoC, Port);
-       
-       if (pPrt->PXSQSize != 0) {
-               /* enable Force Sync bit if synchronous queue available */
-               SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_ENA_FSYNC);
-       }
-       
-       SkGeInitBmu(pAC, IoC, Port);
-
-       /* mark port as initialized */
-       pPrt->PState = SK_PRT_INIT;
-
-       return(0);
-}      /* SkGeInitPort */
diff --git a/drivers/net/sk98lin/skgemib.c b/drivers/net/sk98lin/skgemib.c
deleted file mode 100644 (file)
index 0a6f67a..0000000
+++ /dev/null
@@ -1,1075 +0,0 @@
-/*****************************************************************************
- *
- * Name:       skgemib.c
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.11 $
- * Date:       $Date: 2003/09/15 13:38:12 $
- * Purpose:    Private Network Management Interface Management Database
- *
- ****************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect GmbH.
- *     (C)Copyright 2002-2003 Marvell.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/*
- * PRIVATE OID handler function prototypes
- */
-PNMI_STATIC int Addr(SK_AC *pAC, SK_IOC IoC, int action,
-       SK_U32 Id, char *pBuf, unsigned int *pLen, SK_U32 Instance,
-       unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int CsumStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
-       char *pBuf, unsigned int *pLen, SK_U32 Instance,
-       unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int General(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
-       char *pBuf, unsigned int *pLen, SK_U32 Instance,
-       unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int Mac8023Stat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
-       char *pBuf, unsigned int *pLen, SK_U32 Instance,
-       unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int MacPrivateConf(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
-       char *pBuf, unsigned int *pLen, SK_U32 Instance,
-       unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int MacPrivateStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
-       char *pBuf, unsigned int *pLen, SK_U32 Instance,
-       unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int Monitor(SK_AC *pAC, SK_IOC IoC, int action,
-       SK_U32 Id, char *pBuf, unsigned int *pLen, SK_U32 Instance,
-       unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int OidStruct(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
-       char *pBuf, unsigned int *pLen, SK_U32 Instance,
-       unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int Perform(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
-       char *pBuf, unsigned int* pLen, SK_U32 Instance,
-       unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int Rlmt(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
-       char *pBuf, unsigned int *pLen, SK_U32 Instance,
-       unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int RlmtStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
-       char *pBuf, unsigned int *pLen, SK_U32 Instance,
-       unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int SensorStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
-       char *pBuf, unsigned int *pLen, SK_U32 Instance,
-       unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int Vpd(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
-       char *pBuf, unsigned int *pLen, SK_U32 Instance,
-       unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
-       char *pBuf, unsigned int *pLen, SK_U32 Instance,
-       unsigned int TableIndex, SK_U32 NetIndex);
-
-#ifdef SK_POWER_MGMT
-PNMI_STATIC int PowerManagement(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
-       char *pBuf, unsigned int *pLen, SK_U32 Instance,
-       unsigned int TableIndex, SK_U32 NetIndex);
-#endif /* SK_POWER_MGMT */
-
-#ifdef SK_DIAG_SUPPORT
-PNMI_STATIC int DiagActions(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
-       char *pBuf, unsigned int *pLen, SK_U32 Instance,
-       unsigned int TableIndex, SK_U32 NetIndex);
-#endif /* SK_DIAG_SUPPORT */
-
-
-/* defines *******************************************************************/
-#define ID_TABLE_SIZE (sizeof(IdTable)/sizeof(IdTable[0]))
-
-
-/* global variables **********************************************************/
-
-/*
- * Table to correlate OID with handler function and index to
- * hardware register stored in StatAddress if applicable.
- */
-PNMI_STATIC const SK_PNMI_TAB_ENTRY IdTable[] = {
-       {OID_GEN_XMIT_OK,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX},
-       {OID_GEN_RCV_OK,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX},
-       {OID_GEN_XMIT_ERROR,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, General, 0},
-       {OID_GEN_RCV_ERROR,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, General, 0},
-       {OID_GEN_RCV_NO_BUFFER,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, General, 0},
-       {OID_GEN_DIRECTED_FRAMES_XMIT,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_UNICAST},
-       {OID_GEN_MULTICAST_FRAMES_XMIT,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_MULTICAST},
-       {OID_GEN_BROADCAST_FRAMES_XMIT,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_BROADCAST},
-       {OID_GEN_DIRECTED_FRAMES_RCV,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_UNICAST},
-       {OID_GEN_MULTICAST_FRAMES_RCV,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_MULTICAST},
-       {OID_GEN_BROADCAST_FRAMES_RCV,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_BROADCAST},
-       {OID_GEN_RCV_CRC_ERROR,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_FCS},
-       {OID_GEN_TRANSMIT_QUEUE_LENGTH,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, General, 0},
-       {OID_802_3_PERMANENT_ADDRESS,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, 0},
-       {OID_802_3_CURRENT_ADDRESS,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, 0},
-       {OID_802_3_RCV_ERROR_ALIGNMENT,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_FRAMING},
-       {OID_802_3_XMIT_ONE_COLLISION,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_SINGLE_COL},
-       {OID_802_3_XMIT_MORE_COLLISIONS,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_MULTI_COL},
-       {OID_802_3_XMIT_DEFERRED,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_DEFFERAL},
-       {OID_802_3_XMIT_MAX_COLLISIONS,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_EXCESS_COL},
-       {OID_802_3_RCV_OVERRUN,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_OVERFLOW},
-       {OID_802_3_XMIT_UNDERRUN,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_UNDERRUN},
-       {OID_802_3_XMIT_TIMES_CRS_LOST,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_CARRIER},
-       {OID_802_3_XMIT_LATE_COLLISIONS,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_LATE_COL},
-#ifdef SK_POWER_MGMT
-       {OID_PNP_CAPABILITIES,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, PowerManagement, 0},
-       {OID_PNP_SET_POWER,
-               0,
-               0,
-               0,
-               SK_PNMI_WO, PowerManagement, 0},
-       {OID_PNP_QUERY_POWER,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, PowerManagement, 0},
-       {OID_PNP_ADD_WAKE_UP_PATTERN,
-               0,
-               0,
-               0,
-               SK_PNMI_WO, PowerManagement, 0},
-       {OID_PNP_REMOVE_WAKE_UP_PATTERN,
-               0,
-               0,
-               0,
-               SK_PNMI_WO, PowerManagement, 0},
-       {OID_PNP_ENABLE_WAKE_UP,
-               0,
-               0,
-               0,
-               SK_PNMI_RW, PowerManagement, 0},
-#endif /* SK_POWER_MGMT */
-#ifdef SK_DIAG_SUPPORT
-       {OID_SKGE_DIAG_MODE,
-               0,
-               0,
-               0,
-               SK_PNMI_RW, DiagActions, 0},
-#endif /* SK_DIAG_SUPPORT */
-       {OID_SKGE_MDB_VERSION,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(MgmtDBVersion),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_SUPPORTED_LIST,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_ALL_DATA,
-               0,
-               0,
-               0,
-               SK_PNMI_RW, OidStruct, 0},
-       {OID_SKGE_VPD_FREE_BYTES,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(VpdFreeBytes),
-               SK_PNMI_RO, Vpd, 0},
-       {OID_SKGE_VPD_ENTRIES_LIST,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(VpdEntriesList),
-               SK_PNMI_RO, Vpd, 0},
-       {OID_SKGE_VPD_ENTRIES_NUMBER,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(VpdEntriesNumber),
-               SK_PNMI_RO, Vpd, 0},
-       {OID_SKGE_VPD_KEY,
-               SK_PNMI_VPD_ENTRIES,
-               sizeof(SK_PNMI_VPD),
-               SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdKey),
-               SK_PNMI_RO, Vpd, 0},
-       {OID_SKGE_VPD_VALUE,
-               SK_PNMI_VPD_ENTRIES,
-               sizeof(SK_PNMI_VPD),
-               SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdValue),
-               SK_PNMI_RO, Vpd, 0},
-       {OID_SKGE_VPD_ACCESS,
-               SK_PNMI_VPD_ENTRIES,
-               sizeof(SK_PNMI_VPD),
-               SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdAccess),
-               SK_PNMI_RO, Vpd, 0},
-       {OID_SKGE_VPD_ACTION,
-               SK_PNMI_VPD_ENTRIES,
-               sizeof(SK_PNMI_VPD),
-               SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdAction),
-               SK_PNMI_RW, Vpd, 0},
-       {OID_SKGE_PORT_NUMBER,          
-               1,
-               0,
-               SK_PNMI_MAI_OFF(PortNumber),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_DEVICE_TYPE,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(DeviceType),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_DRIVER_DESCR,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(DriverDescr),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_DRIVER_VERSION,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(DriverVersion),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_DRIVER_RELDATE,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(DriverReleaseDate),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_DRIVER_FILENAME,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(DriverFileName),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_HW_DESCR,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(HwDescr),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_HW_VERSION,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(HwVersion),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_CHIPSET,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(Chipset),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_CHIPID,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(ChipId),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_RAMSIZE,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(RamSize),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_VAUXAVAIL,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(VauxAvail),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_ACTION,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(Action),
-               SK_PNMI_RW, Perform, 0},
-       {OID_SKGE_RESULT,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(TestResult),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_BUS_TYPE,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(BusType),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_BUS_SPEED,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(BusSpeed),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_BUS_WIDTH,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(BusWidth),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_TX_SW_QUEUE_LEN,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(TxSwQueueLen),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_TX_SW_QUEUE_MAX,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(TxSwQueueMax),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_TX_RETRY,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(TxRetryCts),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_RX_INTR_CTS,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(RxIntrCts),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_TX_INTR_CTS,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(TxIntrCts),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_RX_NO_BUF_CTS,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(RxNoBufCts),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_TX_NO_BUF_CTS,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(TxNoBufCts),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_TX_USED_DESCR_NO,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(TxUsedDescrNo),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_RX_DELIVERED_CTS,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(RxDeliveredCts),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_RX_OCTETS_DELIV_CTS,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(RxOctetsDeliveredCts),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_RX_HW_ERROR_CTS,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(RxHwErrorsCts),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_TX_HW_ERROR_CTS,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(TxHwErrorsCts),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_IN_ERRORS_CTS,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(InErrorsCts),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_OUT_ERROR_CTS,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(OutErrorsCts),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_ERR_RECOVERY_CTS,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(ErrRecoveryCts),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_SYSUPTIME,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(SysUpTime),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_SENSOR_NUMBER,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(SensorNumber),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_SENSOR_INDEX,
-               SK_PNMI_SENSOR_ENTRIES,
-               sizeof(SK_PNMI_SENSOR),
-               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorIndex),
-               SK_PNMI_RO, SensorStat, 0},
-       {OID_SKGE_SENSOR_DESCR,
-               SK_PNMI_SENSOR_ENTRIES,
-               sizeof(SK_PNMI_SENSOR),
-               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorDescr),
-               SK_PNMI_RO, SensorStat, 0},
-       {OID_SKGE_SENSOR_TYPE,
-               SK_PNMI_SENSOR_ENTRIES,
-               sizeof(SK_PNMI_SENSOR),
-               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorType),
-               SK_PNMI_RO, SensorStat, 0},
-       {OID_SKGE_SENSOR_VALUE,
-               SK_PNMI_SENSOR_ENTRIES,
-               sizeof(SK_PNMI_SENSOR),
-               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorValue),
-               SK_PNMI_RO, SensorStat, 0},
-       {OID_SKGE_SENSOR_WAR_THRES_LOW,
-               SK_PNMI_SENSOR_ENTRIES,
-               sizeof(SK_PNMI_SENSOR),
-               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningThresholdLow),
-               SK_PNMI_RO, SensorStat, 0},
-       {OID_SKGE_SENSOR_WAR_THRES_UPP,
-               SK_PNMI_SENSOR_ENTRIES,
-               sizeof(SK_PNMI_SENSOR),
-               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningThresholdHigh),
-               SK_PNMI_RO, SensorStat, 0},
-       {OID_SKGE_SENSOR_ERR_THRES_LOW,
-               SK_PNMI_SENSOR_ENTRIES,
-               sizeof(SK_PNMI_SENSOR),
-               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorThresholdLow),
-               SK_PNMI_RO, SensorStat, 0},
-       {OID_SKGE_SENSOR_ERR_THRES_UPP,
-               SK_PNMI_SENSOR_ENTRIES,
-               sizeof(SK_PNMI_SENSOR),
-               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorThresholdHigh),
-               SK_PNMI_RO, SensorStat, 0},
-       {OID_SKGE_SENSOR_STATUS,
-               SK_PNMI_SENSOR_ENTRIES,
-               sizeof(SK_PNMI_SENSOR),
-               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorStatus),
-               SK_PNMI_RO, SensorStat, 0},
-       {OID_SKGE_SENSOR_WAR_CTS,
-               SK_PNMI_SENSOR_ENTRIES,
-               sizeof(SK_PNMI_SENSOR),
-               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningCts),
-               SK_PNMI_RO, SensorStat, 0},
-       {OID_SKGE_SENSOR_ERR_CTS,
-               SK_PNMI_SENSOR_ENTRIES,
-               sizeof(SK_PNMI_SENSOR),
-               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorCts),
-               SK_PNMI_RO, SensorStat, 0},
-       {OID_SKGE_SENSOR_WAR_TIME,
-               SK_PNMI_SENSOR_ENTRIES,
-               sizeof(SK_PNMI_SENSOR),
-               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningTimestamp),
-               SK_PNMI_RO, SensorStat, 0},
-       {OID_SKGE_SENSOR_ERR_TIME,
-               SK_PNMI_SENSOR_ENTRIES,
-               sizeof(SK_PNMI_SENSOR),
-               SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorTimestamp),
-               SK_PNMI_RO, SensorStat, 0},
-       {OID_SKGE_CHKSM_NUMBER,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(ChecksumNumber),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_CHKSM_RX_OK_CTS,
-               SKCS_NUM_PROTOCOLS,
-               sizeof(SK_PNMI_CHECKSUM),
-               SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumRxOkCts),
-               SK_PNMI_RO, CsumStat, 0},
-       {OID_SKGE_CHKSM_RX_UNABLE_CTS,
-               SKCS_NUM_PROTOCOLS,
-               sizeof(SK_PNMI_CHECKSUM),
-               SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumRxUnableCts),
-               SK_PNMI_RO, CsumStat, 0},
-       {OID_SKGE_CHKSM_RX_ERR_CTS,
-               SKCS_NUM_PROTOCOLS,
-               sizeof(SK_PNMI_CHECKSUM),
-               SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumRxErrCts),
-               SK_PNMI_RO, CsumStat, 0},
-       {OID_SKGE_CHKSM_TX_OK_CTS,
-               SKCS_NUM_PROTOCOLS,
-               sizeof(SK_PNMI_CHECKSUM),
-               SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumTxOkCts),
-               SK_PNMI_RO, CsumStat, 0},
-       {OID_SKGE_CHKSM_TX_UNABLE_CTS,
-               SKCS_NUM_PROTOCOLS,
-               sizeof(SK_PNMI_CHECKSUM),
-               SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumTxUnableCts),
-               SK_PNMI_RO, CsumStat, 0},
-       {OID_SKGE_STAT_TX,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxOkCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX},
-       {OID_SKGE_STAT_TX_OCTETS,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxOctetsOkCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_OCTET},
-       {OID_SKGE_STAT_TX_BROADCAST,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxBroadcastOkCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_BROADCAST},
-       {OID_SKGE_STAT_TX_MULTICAST,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMulticastOkCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MULTICAST},
-       {OID_SKGE_STAT_TX_UNICAST,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxUnicastOkCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_UNICAST},
-       {OID_SKGE_STAT_TX_LONGFRAMES,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxLongFramesCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_LONGFRAMES},
-       {OID_SKGE_STAT_TX_BURST,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxBurstCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_BURST},
-       {OID_SKGE_STAT_TX_PFLOWC,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxPauseMacCtrlCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_PMACC},
-       {OID_SKGE_STAT_TX_FLOWC,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMacCtrlCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MACC},
-       {OID_SKGE_STAT_TX_SINGLE_COL,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxSingleCollisionCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_SINGLE_COL},
-       {OID_SKGE_STAT_TX_MULTI_COL,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMultipleCollisionCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MULTI_COL},
-       {OID_SKGE_STAT_TX_EXCESS_COL,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxExcessiveCollisionCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_EXCESS_COL},
-       {OID_SKGE_STAT_TX_LATE_COL,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxLateCollisionCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_LATE_COL},
-       {OID_SKGE_STAT_TX_DEFFERAL,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxDeferralCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_DEFFERAL},
-       {OID_SKGE_STAT_TX_EXCESS_DEF,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxExcessiveDeferralCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_EXCESS_DEF},
-       {OID_SKGE_STAT_TX_UNDERRUN,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxFifoUnderrunCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_UNDERRUN},
-       {OID_SKGE_STAT_TX_CARRIER,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxCarrierCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_CARRIER},
-/*     {OID_SKGE_STAT_TX_UTIL,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxUtilization),
-               SK_PNMI_RO, MacPrivateStat, (SK_U16)(-1)}, */
-       {OID_SKGE_STAT_TX_64,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx64Cts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_64},
-       {OID_SKGE_STAT_TX_127,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx127Cts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_127},
-       {OID_SKGE_STAT_TX_255,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx255Cts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_255},
-       {OID_SKGE_STAT_TX_511,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx511Cts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_511},
-       {OID_SKGE_STAT_TX_1023,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx1023Cts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_1023},
-       {OID_SKGE_STAT_TX_MAX,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMaxCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MAX},
-       {OID_SKGE_STAT_TX_SYNC,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxSyncCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_SYNC},
-       {OID_SKGE_STAT_TX_SYNC_OCTETS,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxSyncOctetsCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_SYNC_OCTET},
-       {OID_SKGE_STAT_RX,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxOkCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX},
-       {OID_SKGE_STAT_RX_OCTETS,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxOctetsOkCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_OCTET},
-       {OID_SKGE_STAT_RX_BROADCAST,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxBroadcastOkCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_BROADCAST},
-       {OID_SKGE_STAT_RX_MULTICAST,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMulticastOkCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MULTICAST},
-       {OID_SKGE_STAT_RX_UNICAST,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxUnicastOkCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_UNICAST},
-       {OID_SKGE_STAT_RX_LONGFRAMES,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxLongFramesCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_LONGFRAMES},
-       {OID_SKGE_STAT_RX_PFLOWC,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxPauseMacCtrlCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_PMACC},
-       {OID_SKGE_STAT_RX_FLOWC,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMacCtrlCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MACC},
-       {OID_SKGE_STAT_RX_PFLOWC_ERR,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxPauseMacCtrlErrorCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_PMACC_ERR},
-       {OID_SKGE_STAT_RX_FLOWC_UNKWN,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMacCtrlUnknownCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MACC_UNKWN},
-       {OID_SKGE_STAT_RX_BURST,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxBurstCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_BURST},
-       {OID_SKGE_STAT_RX_MISSED,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMissedCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MISSED},
-       {OID_SKGE_STAT_RX_FRAMING,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxFramingCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_FRAMING},
-       {OID_SKGE_STAT_RX_OVERFLOW,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxFifoOverflowCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_OVERFLOW},
-       {OID_SKGE_STAT_RX_JABBER,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxJabberCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_JABBER},
-       {OID_SKGE_STAT_RX_CARRIER,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxCarrierCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_CARRIER},
-       {OID_SKGE_STAT_RX_IR_LENGTH,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxIRLengthCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_IRLENGTH},
-       {OID_SKGE_STAT_RX_SYMBOL,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxSymbolCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_SYMBOL},
-       {OID_SKGE_STAT_RX_SHORTS,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxShortsCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_SHORTS},
-       {OID_SKGE_STAT_RX_RUNT,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxRuntCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_RUNT},
-       {OID_SKGE_STAT_RX_CEXT,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxCextCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_CEXT},
-       {OID_SKGE_STAT_RX_TOO_LONG,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxTooLongCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_TOO_LONG},
-       {OID_SKGE_STAT_RX_FCS,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxFcsCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_FCS},
-/*     {OID_SKGE_STAT_RX_UTIL,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxUtilization),
-               SK_PNMI_RO, MacPrivateStat, (SK_U16)(-1)}, */
-       {OID_SKGE_STAT_RX_64,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx64Cts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_64},
-       {OID_SKGE_STAT_RX_127,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx127Cts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_127},
-       {OID_SKGE_STAT_RX_255,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx255Cts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_255},
-       {OID_SKGE_STAT_RX_511,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx511Cts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_511},
-       {OID_SKGE_STAT_RX_1023,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx1023Cts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_1023},
-       {OID_SKGE_STAT_RX_MAX,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_STAT),
-               SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMaxCts),
-               SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MAX},
-       {OID_SKGE_PHYS_CUR_ADDR,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_CONF),
-               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfMacCurrentAddr),
-               SK_PNMI_RW, Addr, 0},
-       {OID_SKGE_PHYS_FAC_ADDR,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_CONF),
-               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfMacFactoryAddr),
-               SK_PNMI_RO, Addr, 0},
-       {OID_SKGE_PMD,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_CONF),
-               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPMD),
-               SK_PNMI_RO, MacPrivateConf, 0},
-       {OID_SKGE_CONNECTOR,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_CONF),
-               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfConnector),
-               SK_PNMI_RO, MacPrivateConf, 0},
-       {OID_SKGE_PHY_TYPE,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_CONF),
-               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyType),
-               SK_PNMI_RO, MacPrivateConf, 0},
-       {OID_SKGE_LINK_CAP,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_CONF),
-               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkCapability),
-               SK_PNMI_RO, MacPrivateConf, 0},
-       {OID_SKGE_LINK_MODE,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_CONF),
-               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkMode),
-               SK_PNMI_RW, MacPrivateConf, 0},
-       {OID_SKGE_LINK_MODE_STATUS,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_CONF),
-               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkModeStatus),
-               SK_PNMI_RO, MacPrivateConf, 0},
-       {OID_SKGE_LINK_STATUS,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_CONF),
-               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkStatus),
-               SK_PNMI_RO, MacPrivateConf, 0},
-       {OID_SKGE_FLOWCTRL_CAP,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_CONF),
-               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlCapability),
-               SK_PNMI_RO, MacPrivateConf, 0},
-       {OID_SKGE_FLOWCTRL_MODE,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_CONF),
-               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlMode),
-               SK_PNMI_RW, MacPrivateConf, 0},
-       {OID_SKGE_FLOWCTRL_STATUS,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_CONF),
-               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlStatus),
-               SK_PNMI_RO, MacPrivateConf, 0},
-       {OID_SKGE_PHY_OPERATION_CAP,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_CONF),
-               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationCapability),
-               SK_PNMI_RO, MacPrivateConf, 0},
-       {OID_SKGE_PHY_OPERATION_MODE,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_CONF),
-               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationMode),
-               SK_PNMI_RW, MacPrivateConf, 0},
-       {OID_SKGE_PHY_OPERATION_STATUS,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_CONF),
-               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationStatus),
-               SK_PNMI_RO, MacPrivateConf, 0},
-       {OID_SKGE_SPEED_CAP,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_CONF),
-               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfSpeedCapability),
-               SK_PNMI_RO, MacPrivateConf, 0},
-       {OID_SKGE_SPEED_MODE,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_CONF),
-               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfSpeedMode),
-               SK_PNMI_RW, MacPrivateConf, 0},
-       {OID_SKGE_SPEED_STATUS,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_CONF),
-               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfSpeedStatus),
-               SK_PNMI_RO, MacPrivateConf, 0},
-       {OID_SKGE_TRAP,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(Trap),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_TRAP_NUMBER,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(TrapNumber),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_RLMT_MODE,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(RlmtMode),
-               SK_PNMI_RW, Rlmt, 0},
-       {OID_SKGE_RLMT_PORT_NUMBER,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(RlmtPortNumber),
-               SK_PNMI_RO, Rlmt, 0},
-       {OID_SKGE_RLMT_PORT_ACTIVE,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(RlmtPortActive),
-               SK_PNMI_RO, Rlmt, 0},
-       {OID_SKGE_RLMT_PORT_PREFERRED,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(RlmtPortPreferred),
-               SK_PNMI_RW, Rlmt, 0},
-       {OID_SKGE_RLMT_CHANGE_CTS,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(RlmtChangeCts),
-               SK_PNMI_RO, Rlmt, 0},
-       {OID_SKGE_RLMT_CHANGE_TIME,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(RlmtChangeTime),
-               SK_PNMI_RO, Rlmt, 0},
-       {OID_SKGE_RLMT_CHANGE_ESTIM,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(RlmtChangeEstimate),
-               SK_PNMI_RO, Rlmt, 0},
-       {OID_SKGE_RLMT_CHANGE_THRES,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(RlmtChangeThreshold),
-               SK_PNMI_RW, Rlmt, 0},
-       {OID_SKGE_RLMT_PORT_INDEX,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_RLMT),
-               SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtIndex),
-               SK_PNMI_RO, RlmtStat, 0},
-       {OID_SKGE_RLMT_STATUS,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_RLMT),
-               SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtStatus),
-               SK_PNMI_RO, RlmtStat, 0},
-       {OID_SKGE_RLMT_TX_HELLO_CTS,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_RLMT),
-               SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtTxHelloCts),
-               SK_PNMI_RO, RlmtStat, 0},
-       {OID_SKGE_RLMT_RX_HELLO_CTS,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_RLMT),
-               SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtRxHelloCts),
-               SK_PNMI_RO, RlmtStat, 0},
-       {OID_SKGE_RLMT_TX_SP_REQ_CTS,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_RLMT),
-               SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtTxSpHelloReqCts),
-               SK_PNMI_RO, RlmtStat, 0},
-       {OID_SKGE_RLMT_RX_SP_CTS,
-               SK_PNMI_MAC_ENTRIES,
-               sizeof(SK_PNMI_RLMT),
-               SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtRxSpHelloCts),
-               SK_PNMI_RO, RlmtStat, 0},
-       {OID_SKGE_RLMT_MONITOR_NUMBER,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(RlmtMonitorNumber),
-               SK_PNMI_RO, General, 0},
-       {OID_SKGE_RLMT_MONITOR_INDEX,
-               SK_PNMI_MONITOR_ENTRIES,
-               sizeof(SK_PNMI_RLMT_MONITOR),
-               SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorIndex),
-               SK_PNMI_RO, Monitor, 0},
-       {OID_SKGE_RLMT_MONITOR_ADDR,
-               SK_PNMI_MONITOR_ENTRIES,
-               sizeof(SK_PNMI_RLMT_MONITOR),
-               SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorAddr),
-               SK_PNMI_RO, Monitor, 0},
-       {OID_SKGE_RLMT_MONITOR_ERRS,
-               SK_PNMI_MONITOR_ENTRIES,
-               sizeof(SK_PNMI_RLMT_MONITOR),
-               SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorErrorCts),
-               SK_PNMI_RO, Monitor, 0},
-       {OID_SKGE_RLMT_MONITOR_TIMESTAMP,
-               SK_PNMI_MONITOR_ENTRIES,
-               sizeof(SK_PNMI_RLMT_MONITOR),
-               SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorTimestamp),
-               SK_PNMI_RO, Monitor, 0},
-       {OID_SKGE_RLMT_MONITOR_ADMIN,
-               SK_PNMI_MONITOR_ENTRIES,
-               sizeof(SK_PNMI_RLMT_MONITOR),
-               SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorAdmin),
-               SK_PNMI_RW, Monitor, 0},
-       {OID_SKGE_MTU,
-               1,
-               0,
-               SK_PNMI_MAI_OFF(MtuSize),
-               SK_PNMI_RW, MacPrivateConf, 0},
-       {OID_SKGE_VCT_GET,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Vct, 0},
-       {OID_SKGE_VCT_SET,
-               0,
-               0,
-               0,
-               SK_PNMI_WO, Vct, 0},
-       {OID_SKGE_VCT_STATUS,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, Vct, 0},
-       {OID_SKGE_BOARDLEVEL,
-               0,
-               0,
-               0,
-               SK_PNMI_RO, General, 0},
-};
-
diff --git a/drivers/net/sk98lin/skgepnmi.c b/drivers/net/sk98lin/skgepnmi.c
deleted file mode 100644 (file)
index b36dd9a..0000000
+++ /dev/null
@@ -1,8210 +0,0 @@
-/*****************************************************************************
- *
- * Name:       skgepnmi.c
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.111 $
- * Date:       $Date: 2003/09/15 13:35:35 $
- * Purpose:    Private Network Management Interface
- *
- ****************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect GmbH.
- *     (C)Copyright 2002-2003 Marvell.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-
-#ifndef _lint
-static const char SysKonnectFileId[] =
-       "@(#) $Id: skgepnmi.c,v 1.111 2003/09/15 13:35:35 tschilli Exp $ (C) Marvell.";
-#endif /* !_lint */
-
-#include "h/skdrv1st.h"
-#include "h/sktypes.h"
-#include "h/xmac_ii.h"
-#include "h/skdebug.h"
-#include "h/skqueue.h"
-#include "h/skgepnmi.h"
-#include "h/skgesirq.h"
-#include "h/skcsum.h"
-#include "h/skvpd.h"
-#include "h/skgehw.h"
-#include "h/skgeinit.h"
-#include "h/skdrv2nd.h"
-#include "h/skgepnm2.h"
-#ifdef SK_POWER_MGMT
-#include "h/skgepmgt.h"
-#endif
-/* defines *******************************************************************/
-
-#ifndef DEBUG
-#define PNMI_STATIC    static
-#else  /* DEBUG */
-#define PNMI_STATIC
-#endif /* DEBUG */
-
-/*
- * Public Function prototypes
- */
-int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int level);
-int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
-       unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
-int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
-       unsigned int *pLen, SK_U32 NetIndex);
-int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
-       unsigned int *pLen, SK_U32 NetIndex);
-int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
-       unsigned int *pLen, SK_U32 NetIndex);
-int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Param);
-int SkPnmiGenIoctl(SK_AC *pAC, SK_IOC IoC, void * pBuf,
-       unsigned int * pLen, SK_U32 NetIndex);
-
-
-/*
- * Private Function prototypes
- */
-
-PNMI_STATIC SK_U8 CalculateLinkModeStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
-       PhysPortIndex);
-PNMI_STATIC SK_U8 CalculateLinkStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
-       PhysPortIndex);
-PNMI_STATIC void CopyMac(char *pDst, SK_MAC_ADDR *pMac);
-PNMI_STATIC void CopyTrapQueue(SK_AC *pAC, char *pDstBuf);
-PNMI_STATIC SK_U64 GetPhysStatVal(SK_AC *pAC, SK_IOC IoC,
-       unsigned int PhysPortIndex, unsigned int StatIndex);
-PNMI_STATIC SK_U64 GetStatVal(SK_AC *pAC, SK_IOC IoC, unsigned int LogPortIndex,
-       unsigned int StatIndex, SK_U32 NetIndex);
-PNMI_STATIC char* GetTrapEntry(SK_AC *pAC, SK_U32 TrapId, unsigned int Size);
-PNMI_STATIC void GetTrapQueueLen(SK_AC *pAC, unsigned int *pLen,
-       unsigned int *pEntries);
-PNMI_STATIC int GetVpdKeyArr(SK_AC *pAC, SK_IOC IoC, char *pKeyArr,
-       unsigned int KeyArrLen, unsigned int *pKeyNo);
-PNMI_STATIC int LookupId(SK_U32 Id);
-PNMI_STATIC int MacUpdate(SK_AC *pAC, SK_IOC IoC, unsigned int FirstMac,
-       unsigned int LastMac);
-PNMI_STATIC int PnmiStruct(SK_AC *pAC, SK_IOC IoC, int Action, char *pBuf,
-       unsigned int *pLen, SK_U32 NetIndex);
-PNMI_STATIC int PnmiVar(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id,
-       char *pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
-PNMI_STATIC void QueueRlmtNewMacTrap(SK_AC *pAC, unsigned int ActiveMac);
-PNMI_STATIC void QueueRlmtPortTrap(SK_AC *pAC, SK_U32 TrapId,
-       unsigned int PortIndex);
-PNMI_STATIC void QueueSensorTrap(SK_AC *pAC, SK_U32 TrapId,
-       unsigned int SensorIndex);
-PNMI_STATIC void QueueSimpleTrap(SK_AC *pAC, SK_U32 TrapId);
-PNMI_STATIC void ResetCounter(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
-PNMI_STATIC int RlmtUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
-PNMI_STATIC int SirqUpdate(SK_AC *pAC, SK_IOC IoC);
-PNMI_STATIC void VirtualConf(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, char *pBuf);
-PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id, char *pBuf,
-       unsigned int *pLen, SK_U32 Instance, unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC void CheckVctStatus(SK_AC *, SK_IOC, char *, SK_U32, SK_U32);
-
-/*
- * Table to correlate OID with handler function and index to
- * hardware register stored in StatAddress if applicable.
- */
-#include "skgemib.c"
-
-/* global variables **********************************************************/
-
-/*
- * Overflow status register bit table and corresponding counter
- * dependent on MAC type - the number relates to the size of overflow
- * mask returned by the pFnMacOverflow function
- */
-PNMI_STATIC const SK_U16 StatOvrflwBit[][SK_PNMI_MAC_TYPES] = {
-/* Bit0  */    { SK_PNMI_HTX,                          SK_PNMI_HTX_UNICAST},
-/* Bit1  */    { SK_PNMI_HTX_OCTETHIGH,        SK_PNMI_HTX_BROADCAST},
-/* Bit2  */    { SK_PNMI_HTX_OCTETLOW,         SK_PNMI_HTX_PMACC},
-/* Bit3  */    { SK_PNMI_HTX_BROADCAST,        SK_PNMI_HTX_MULTICAST},
-/* Bit4  */    { SK_PNMI_HTX_MULTICAST,        SK_PNMI_HTX_OCTETLOW},
-/* Bit5  */    { SK_PNMI_HTX_UNICAST,          SK_PNMI_HTX_OCTETHIGH},
-/* Bit6  */    { SK_PNMI_HTX_LONGFRAMES,       SK_PNMI_HTX_64},
-/* Bit7  */    { SK_PNMI_HTX_BURST,            SK_PNMI_HTX_127},
-/* Bit8  */    { SK_PNMI_HTX_PMACC,            SK_PNMI_HTX_255},
-/* Bit9  */    { SK_PNMI_HTX_MACC,             SK_PNMI_HTX_511},
-/* Bit10 */    { SK_PNMI_HTX_SINGLE_COL,       SK_PNMI_HTX_1023},
-/* Bit11 */    { SK_PNMI_HTX_MULTI_COL,        SK_PNMI_HTX_MAX},
-/* Bit12 */    { SK_PNMI_HTX_EXCESS_COL,       SK_PNMI_HTX_LONGFRAMES},
-/* Bit13 */    { SK_PNMI_HTX_LATE_COL,         SK_PNMI_HTX_RESERVED},
-/* Bit14 */    { SK_PNMI_HTX_DEFFERAL,         SK_PNMI_HTX_COL},
-/* Bit15 */    { SK_PNMI_HTX_EXCESS_DEF,       SK_PNMI_HTX_LATE_COL},
-/* Bit16 */    { SK_PNMI_HTX_UNDERRUN,         SK_PNMI_HTX_EXCESS_COL},
-/* Bit17 */    { SK_PNMI_HTX_CARRIER,          SK_PNMI_HTX_MULTI_COL},
-/* Bit18 */    { SK_PNMI_HTX_UTILUNDER,        SK_PNMI_HTX_SINGLE_COL},
-/* Bit19 */    { SK_PNMI_HTX_UTILOVER,         SK_PNMI_HTX_UNDERRUN},
-/* Bit20 */    { SK_PNMI_HTX_64,                       SK_PNMI_HTX_RESERVED},
-/* Bit21 */    { SK_PNMI_HTX_127,                      SK_PNMI_HTX_RESERVED},
-/* Bit22 */    { SK_PNMI_HTX_255,                      SK_PNMI_HTX_RESERVED},
-/* Bit23 */    { SK_PNMI_HTX_511,                      SK_PNMI_HTX_RESERVED},
-/* Bit24 */    { SK_PNMI_HTX_1023,             SK_PNMI_HTX_RESERVED},
-/* Bit25 */    { SK_PNMI_HTX_MAX,                      SK_PNMI_HTX_RESERVED},
-/* Bit26 */    { SK_PNMI_HTX_RESERVED,         SK_PNMI_HTX_RESERVED},
-/* Bit27 */    { SK_PNMI_HTX_RESERVED,         SK_PNMI_HTX_RESERVED},
-/* Bit28 */    { SK_PNMI_HTX_RESERVED,         SK_PNMI_HTX_RESERVED},
-/* Bit29 */    { SK_PNMI_HTX_RESERVED,         SK_PNMI_HTX_RESERVED},
-/* Bit30 */    { SK_PNMI_HTX_RESERVED,         SK_PNMI_HTX_RESERVED},
-/* Bit31 */    { SK_PNMI_HTX_RESERVED,         SK_PNMI_HTX_RESERVED},
-/* Bit32 */    { SK_PNMI_HRX,                          SK_PNMI_HRX_UNICAST},
-/* Bit33 */    { SK_PNMI_HRX_OCTETHIGH,        SK_PNMI_HRX_BROADCAST},
-/* Bit34 */    { SK_PNMI_HRX_OCTETLOW,         SK_PNMI_HRX_PMACC},
-/* Bit35 */    { SK_PNMI_HRX_BROADCAST,        SK_PNMI_HRX_MULTICAST},
-/* Bit36 */    { SK_PNMI_HRX_MULTICAST,        SK_PNMI_HRX_FCS},
-/* Bit37 */    { SK_PNMI_HRX_UNICAST,          SK_PNMI_HRX_RESERVED},
-/* Bit38 */    { SK_PNMI_HRX_PMACC,            SK_PNMI_HRX_OCTETLOW},
-/* Bit39 */    { SK_PNMI_HRX_MACC,             SK_PNMI_HRX_OCTETHIGH},
-/* Bit40 */    { SK_PNMI_HRX_PMACC_ERR,        SK_PNMI_HRX_BADOCTETLOW},
-/* Bit41 */    { SK_PNMI_HRX_MACC_UNKWN,       SK_PNMI_HRX_BADOCTETHIGH},
-/* Bit42 */    { SK_PNMI_HRX_BURST,            SK_PNMI_HRX_UNDERSIZE},
-/* Bit43 */    { SK_PNMI_HRX_MISSED,           SK_PNMI_HRX_RUNT},
-/* Bit44 */    { SK_PNMI_HRX_FRAMING,          SK_PNMI_HRX_64},
-/* Bit45 */    { SK_PNMI_HRX_OVERFLOW,         SK_PNMI_HRX_127},
-/* Bit46 */    { SK_PNMI_HRX_JABBER,           SK_PNMI_HRX_255},
-/* Bit47 */    { SK_PNMI_HRX_CARRIER,          SK_PNMI_HRX_511},
-/* Bit48 */    { SK_PNMI_HRX_IRLENGTH,         SK_PNMI_HRX_1023},
-/* Bit49 */    { SK_PNMI_HRX_SYMBOL,           SK_PNMI_HRX_MAX},
-/* Bit50 */    { SK_PNMI_HRX_SHORTS,           SK_PNMI_HRX_LONGFRAMES},
-/* Bit51 */    { SK_PNMI_HRX_RUNT,             SK_PNMI_HRX_TOO_LONG},
-/* Bit52 */    { SK_PNMI_HRX_TOO_LONG,         SK_PNMI_HRX_JABBER},
-/* Bit53 */    { SK_PNMI_HRX_FCS,                      SK_PNMI_HRX_RESERVED},
-/* Bit54 */    { SK_PNMI_HRX_RESERVED,         SK_PNMI_HRX_OVERFLOW},
-/* Bit55 */    { SK_PNMI_HRX_CEXT,             SK_PNMI_HRX_RESERVED},
-/* Bit56 */    { SK_PNMI_HRX_UTILUNDER,        SK_PNMI_HRX_RESERVED},
-/* Bit57 */    { SK_PNMI_HRX_UTILOVER,         SK_PNMI_HRX_RESERVED},
-/* Bit58 */    { SK_PNMI_HRX_64,                       SK_PNMI_HRX_RESERVED},
-/* Bit59 */    { SK_PNMI_HRX_127,                      SK_PNMI_HRX_RESERVED},
-/* Bit60 */    { SK_PNMI_HRX_255,                      SK_PNMI_HRX_RESERVED},
-/* Bit61 */    { SK_PNMI_HRX_511,                      SK_PNMI_HRX_RESERVED},
-/* Bit62 */    { SK_PNMI_HRX_1023,             SK_PNMI_HRX_RESERVED},
-/* Bit63 */    { SK_PNMI_HRX_MAX,                      SK_PNMI_HRX_RESERVED}
-};
-
-/*
- * Table for hardware register saving on resets and port switches
- */
-PNMI_STATIC const SK_PNMI_STATADDR StatAddr[SK_PNMI_MAX_IDX][SK_PNMI_MAC_TYPES] = {
-       /* SK_PNMI_HTX */
-       {{XM_TXF_OK, SK_TRUE}, {0, SK_FALSE}},
-       /* SK_PNMI_HTX_OCTETHIGH */
-       {{XM_TXO_OK_HI, SK_TRUE}, {GM_TXO_OK_HI, SK_TRUE}},
-       /* SK_PNMI_HTX_OCTETLOW */
-       {{XM_TXO_OK_LO, SK_FALSE}, {GM_TXO_OK_LO, SK_FALSE}},
-       /* SK_PNMI_HTX_BROADCAST */
-       {{XM_TXF_BC_OK, SK_TRUE}, {GM_TXF_BC_OK, SK_TRUE}},
-       /* SK_PNMI_HTX_MULTICAST */
-       {{XM_TXF_MC_OK, SK_TRUE}, {GM_TXF_MC_OK, SK_TRUE}},
-       /* SK_PNMI_HTX_UNICAST */
-       {{XM_TXF_UC_OK, SK_TRUE}, {GM_TXF_UC_OK, SK_TRUE}},
-       /* SK_PNMI_HTX_BURST */
-       {{XM_TXE_BURST, SK_TRUE}, {0, SK_FALSE}},
-       /* SK_PNMI_HTX_PMACC */
-       {{XM_TXF_MPAUSE, SK_TRUE}, {GM_TXF_MPAUSE, SK_TRUE}},
-       /* SK_PNMI_HTX_MACC */
-       {{XM_TXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
-       /* SK_PNMI_HTX_COL */
-       {{0, SK_FALSE}, {GM_TXF_COL, SK_TRUE}},
-       /* SK_PNMI_HTX_SINGLE_COL */
-       {{XM_TXF_SNG_COL, SK_TRUE}, {GM_TXF_SNG_COL, SK_TRUE}},
-       /* SK_PNMI_HTX_MULTI_COL */
-       {{XM_TXF_MUL_COL, SK_TRUE}, {GM_TXF_MUL_COL, SK_TRUE}},
-       /* SK_PNMI_HTX_EXCESS_COL */
-       {{XM_TXF_ABO_COL, SK_TRUE}, {GM_TXF_ABO_COL, SK_TRUE}},
-       /* SK_PNMI_HTX_LATE_COL */
-       {{XM_TXF_LAT_COL, SK_TRUE}, {GM_TXF_LAT_COL, SK_TRUE}},
-       /* SK_PNMI_HTX_DEFFERAL */
-       {{XM_TXF_DEF, SK_TRUE}, {0, SK_FALSE}},
-       /* SK_PNMI_HTX_EXCESS_DEF */
-       {{XM_TXF_EX_DEF, SK_TRUE}, {0, SK_FALSE}},
-       /* SK_PNMI_HTX_UNDERRUN */
-       {{XM_TXE_FIFO_UR, SK_TRUE}, {GM_TXE_FIFO_UR, SK_TRUE}},
-       /* SK_PNMI_HTX_CARRIER */
-       {{XM_TXE_CS_ERR, SK_TRUE}, {0, SK_FALSE}},
-       /* SK_PNMI_HTX_UTILUNDER */
-       {{0, SK_FALSE}, {0, SK_FALSE}},
-       /* SK_PNMI_HTX_UTILOVER */
-       {{0, SK_FALSE}, {0, SK_FALSE}},
-       /* SK_PNMI_HTX_64 */
-       {{XM_TXF_64B, SK_TRUE}, {GM_TXF_64B, SK_TRUE}},
-       /* SK_PNMI_HTX_127 */
-       {{XM_TXF_127B, SK_TRUE}, {GM_TXF_127B, SK_TRUE}},
-       /* SK_PNMI_HTX_255 */
-       {{XM_TXF_255B, SK_TRUE}, {GM_TXF_255B, SK_TRUE}},
-       /* SK_PNMI_HTX_511 */
-       {{XM_TXF_511B, SK_TRUE}, {GM_TXF_511B, SK_TRUE}},
-       /* SK_PNMI_HTX_1023 */
-       {{XM_TXF_1023B, SK_TRUE}, {GM_TXF_1023B, SK_TRUE}},
-       /* SK_PNMI_HTX_MAX */
-       {{XM_TXF_MAX_SZ, SK_TRUE}, {GM_TXF_1518B, SK_TRUE}},
-       /* SK_PNMI_HTX_LONGFRAMES  */
-       {{XM_TXF_LONG, SK_TRUE}, {GM_TXF_MAX_SZ, SK_TRUE}},
-       /* SK_PNMI_HTX_SYNC */
-       {{0, SK_FALSE}, {0, SK_FALSE}},
-       /* SK_PNMI_HTX_SYNC_OCTET */
-       {{0, SK_FALSE}, {0, SK_FALSE}},
-       /* SK_PNMI_HTX_RESERVED */
-       {{0, SK_FALSE}, {0, SK_FALSE}},
-       /* SK_PNMI_HRX */
-       {{XM_RXF_OK, SK_TRUE}, {0, SK_FALSE}},
-       /* SK_PNMI_HRX_OCTETHIGH */
-       {{XM_RXO_OK_HI, SK_TRUE}, {GM_RXO_OK_HI, SK_TRUE}},
-       /* SK_PNMI_HRX_OCTETLOW */
-       {{XM_RXO_OK_LO, SK_FALSE}, {GM_RXO_OK_LO, SK_FALSE}},
-       /* SK_PNMI_HRX_BADOCTETHIGH */
-       {{0, SK_FALSE}, {GM_RXO_ERR_HI, SK_TRUE}},
-       /* SK_PNMI_HRX_BADOCTETLOW */
-       {{0, SK_FALSE}, {GM_RXO_ERR_LO, SK_TRUE}},
-       /* SK_PNMI_HRX_BROADCAST */
-       {{XM_RXF_BC_OK, SK_TRUE}, {GM_RXF_BC_OK, SK_TRUE}},
-       /* SK_PNMI_HRX_MULTICAST */
-       {{XM_RXF_MC_OK, SK_TRUE}, {GM_RXF_MC_OK, SK_TRUE}},
-       /* SK_PNMI_HRX_UNICAST */
-       {{XM_RXF_UC_OK, SK_TRUE}, {GM_RXF_UC_OK, SK_TRUE}},
-       /* SK_PNMI_HRX_PMACC */
-       {{XM_RXF_MPAUSE, SK_TRUE}, {GM_RXF_MPAUSE, SK_TRUE}},
-       /* SK_PNMI_HRX_MACC */
-       {{XM_RXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
-       /* SK_PNMI_HRX_PMACC_ERR */
-       {{XM_RXF_INV_MP, SK_TRUE}, {0, SK_FALSE}},
-       /* SK_PNMI_HRX_MACC_UNKWN */
-       {{XM_RXF_INV_MOC, SK_TRUE}, {0, SK_FALSE}},
-       /* SK_PNMI_HRX_BURST */
-       {{XM_RXE_BURST, SK_TRUE}, {0, SK_FALSE}},
-       /* SK_PNMI_HRX_MISSED */
-       {{XM_RXE_FMISS, SK_TRUE}, {0, SK_FALSE}},
-       /* SK_PNMI_HRX_FRAMING */
-       {{XM_RXF_FRA_ERR, SK_TRUE}, {0, SK_FALSE}},
-       /* SK_PNMI_HRX_UNDERSIZE */
-       {{0, SK_FALSE}, {GM_RXF_SHT, SK_TRUE}},
-       /* SK_PNMI_HRX_OVERFLOW */
-       {{XM_RXE_FIFO_OV, SK_TRUE}, {GM_RXE_FIFO_OV, SK_TRUE}},
-       /* SK_PNMI_HRX_JABBER */
-       {{XM_RXF_JAB_PKT, SK_TRUE}, {GM_RXF_JAB_PKT, SK_TRUE}},
-       /* SK_PNMI_HRX_CARRIER */
-       {{XM_RXE_CAR_ERR, SK_TRUE}, {0, SK_FALSE}},
-       /* SK_PNMI_HRX_IRLENGTH */
-       {{XM_RXF_LEN_ERR, SK_TRUE}, {0, SK_FALSE}},
-       /* SK_PNMI_HRX_SYMBOL */
-       {{XM_RXE_SYM_ERR, SK_TRUE}, {0, SK_FALSE}},
-       /* SK_PNMI_HRX_SHORTS */
-       {{XM_RXE_SHT_ERR, SK_TRUE}, {0, SK_FALSE}},
-       /* SK_PNMI_HRX_RUNT */
-       {{XM_RXE_RUNT, SK_TRUE}, {GM_RXE_FRAG, SK_TRUE}},
-       /* SK_PNMI_HRX_TOO_LONG */
-       {{XM_RXF_LNG_ERR, SK_TRUE}, {GM_RXF_LNG_ERR, SK_TRUE}},
-       /* SK_PNMI_HRX_FCS */
-       {{XM_RXF_FCS_ERR, SK_TRUE}, {GM_RXF_FCS_ERR, SK_TRUE}},
-       /* SK_PNMI_HRX_CEXT */
-       {{XM_RXF_CEX_ERR, SK_TRUE}, {0, SK_FALSE}},
-       /* SK_PNMI_HRX_UTILUNDER */
-       {{0, SK_FALSE}, {0, SK_FALSE}},
-       /* SK_PNMI_HRX_UTILOVER */
-       {{0, SK_FALSE}, {0, SK_FALSE}},
-       /* SK_PNMI_HRX_64 */
-       {{XM_RXF_64B, SK_TRUE}, {GM_RXF_64B, SK_TRUE}},
-       /* SK_PNMI_HRX_127 */
-       {{XM_RXF_127B, SK_TRUE}, {GM_RXF_127B, SK_TRUE}},
-       /* SK_PNMI_HRX_255 */
-       {{XM_RXF_255B, SK_TRUE}, {GM_RXF_255B, SK_TRUE}},
-       /* SK_PNMI_HRX_511 */
-       {{XM_RXF_511B, SK_TRUE}, {GM_RXF_511B, SK_TRUE}},
-       /* SK_PNMI_HRX_1023 */
-       {{XM_RXF_1023B, SK_TRUE}, {GM_RXF_1023B, SK_TRUE}},
-       /* SK_PNMI_HRX_MAX */
-       {{XM_RXF_MAX_SZ, SK_TRUE}, {GM_RXF_1518B, SK_TRUE}},
-       /* SK_PNMI_HRX_LONGFRAMES */
-       {{0, SK_FALSE}, {GM_RXF_MAX_SZ, SK_TRUE}},
-       /* SK_PNMI_HRX_RESERVED */
-       {{0, SK_FALSE}, {0, SK_FALSE}}
-};
-
-
-/*****************************************************************************
- *
- * Public functions
- *
- */
-
-/*****************************************************************************
- *
- * SkPnmiInit - Init function of PNMI
- *
- * Description:
- *     SK_INIT_DATA: Initialises the data structures
- *     SK_INIT_IO:   Resets the XMAC statistics, determines the device and
- *                   connector type.
- *     SK_INIT_RUN:  Starts a timer event for port switch per hour
- *                   calculation.
- *
- * Returns:
- *     Always 0
- */
-int SkPnmiInit(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int Level)             /* Initialization level */
-{
-       unsigned int    PortMax;        /* Number of ports */
-       unsigned int    PortIndex;      /* Current port index in loop */
-       SK_U16          Val16;          /* Multiple purpose 16 bit variable */
-       SK_U8           Val8;           /* Mulitple purpose 8 bit variable */
-       SK_EVPARA       EventParam;     /* Event struct for timer event */
-       SK_PNMI_VCT     *pVctBackupData;
-
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-               ("PNMI: SkPnmiInit: Called, level=%d\n", Level));
-
-       switch (Level) {
-
-       case SK_INIT_DATA:
-               SK_MEMSET((char *)&pAC->Pnmi, 0, sizeof(pAC->Pnmi));
-               pAC->Pnmi.TrapBufFree = SK_PNMI_TRAP_QUEUE_LEN;
-               pAC->Pnmi.StartUpTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
-               pAC->Pnmi.RlmtChangeThreshold = SK_PNMI_DEF_RLMT_CHG_THRES;
-               for (PortIndex = 0; PortIndex < SK_MAX_MACS; PortIndex ++) {
-
-                       pAC->Pnmi.Port[PortIndex].ActiveFlag = SK_FALSE;
-                       pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
-               }
-
-#ifdef SK_PNMI_CHECK
-               if (SK_PNMI_MAX_IDX != SK_PNMI_CNT_NO) {
-                       
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR049, SK_PNMI_ERR049MSG);
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
-                                          ("CounterOffset struct size (%d) differs from"
-                                               "SK_PNMI_MAX_IDX (%d)\n",
-                                               SK_PNMI_CNT_NO, SK_PNMI_MAX_IDX));
-               }
-
-               if (SK_PNMI_MAX_IDX !=
-                       (sizeof(StatAddr) / (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES))) {
-                       
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR050, SK_PNMI_ERR050MSG);
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
-                                          ("StatAddr table size (%d) differs from "
-                                               "SK_PNMI_MAX_IDX (%d)\n",
-                                               (sizeof(StatAddr) /
-                                                (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES)),
-                                                SK_PNMI_MAX_IDX));
-               }
-#endif /* SK_PNMI_CHECK */
-               break;
-
-       case SK_INIT_IO:
-               /*
-                * Reset MAC counters
-                */
-               PortMax = pAC->GIni.GIMacsFound;
-
-               for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
-
-                       pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PortIndex);
-               }
-               
-               /* Initialize DSP variables for Vct() to 0xff => Never written! */              
-               for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
-                       pAC->GIni.GP[PortIndex].PCableLen = 0xff;
-                       pVctBackupData = &pAC->Pnmi.VctBackup[PortIndex];
-                       pVctBackupData->PCableLen = 0xff;
-               }
-               
-               /*
-                * Get pci bus speed
-                */
-               SK_IN16(IoC, B0_CTST, &Val16);
-               if ((Val16 & CS_BUS_CLOCK) == 0) {
-
-                       pAC->Pnmi.PciBusSpeed = 33;
-               }
-               else {
-                       pAC->Pnmi.PciBusSpeed = 66;
-               }
-
-               /*
-                * Get pci bus width
-                */
-               SK_IN16(IoC, B0_CTST, &Val16);
-               if ((Val16 & CS_BUS_SLOT_SZ) == 0) {
-
-                       pAC->Pnmi.PciBusWidth = 32;
-               }
-               else {
-                       pAC->Pnmi.PciBusWidth = 64;
-               }
-
-               /*
-                * Get chipset
-                */
-               switch (pAC->GIni.GIChipId) {
-               case CHIP_ID_GENESIS:
-                       pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_XMAC;
-                       break;
-
-               case CHIP_ID_YUKON:
-                       pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON;
-                       break;
-
-               default:
-                       break;
-               }
-
-               /*
-                * Get PMD and DeviceType
-                */
-               SK_IN8(IoC, B2_PMD_TYP, &Val8);
-               switch (Val8) {
-               case 'S':
-                       pAC->Pnmi.PMD = 3;
-                       if (pAC->GIni.GIMacsFound > 1) {
-
-                               pAC->Pnmi.DeviceType = 0x00020002;
-                       }
-                       else {
-                               pAC->Pnmi.DeviceType = 0x00020001;
-                       }
-                       break;
-
-               case 'L':
-                       pAC->Pnmi.PMD = 2;
-                       if (pAC->GIni.GIMacsFound > 1) {
-
-                               pAC->Pnmi.DeviceType = 0x00020004;
-                       }
-                       else {
-                               pAC->Pnmi.DeviceType = 0x00020003;
-                       }
-                       break;
-
-               case 'C':
-                       pAC->Pnmi.PMD = 4;
-                       if (pAC->GIni.GIMacsFound > 1) {
-
-                               pAC->Pnmi.DeviceType = 0x00020006;
-                       }
-                       else {
-                               pAC->Pnmi.DeviceType = 0x00020005;
-                       }
-                       break;
-
-               case 'T':
-                       pAC->Pnmi.PMD = 5;
-                       if (pAC->GIni.GIMacsFound > 1) {
-
-                               pAC->Pnmi.DeviceType = 0x00020008;
-                       }
-                       else {
-                               pAC->Pnmi.DeviceType = 0x00020007;
-                       }
-                       break;
-
-               default :
-                       pAC->Pnmi.PMD = 1;
-                       pAC->Pnmi.DeviceType = 0;
-                       break;
-               }
-
-               /*
-                * Get connector
-                */
-               SK_IN8(IoC, B2_CONN_TYP, &Val8);
-               switch (Val8) {
-               case 'C':
-                       pAC->Pnmi.Connector = 2;
-                       break;
-
-               case 'D':
-                       pAC->Pnmi.Connector = 3;
-                       break;
-
-               case 'F':
-                       pAC->Pnmi.Connector = 4;
-                       break;
-
-               case 'J':
-                       pAC->Pnmi.Connector = 5;
-                       break;
-
-               case 'V':
-                       pAC->Pnmi.Connector = 6;
-                       break;
-
-               default:
-                       pAC->Pnmi.Connector = 1;
-                       break;
-               }
-               break;
-
-       case SK_INIT_RUN:
-               /*
-                * Start timer for RLMT change counter
-                */
-               SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
-               SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
-                       28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
-                       EventParam);
-               break;
-
-       default:
-               break; /* Nothing todo */
-       }
-
-       return (0);
-}
-
-/*****************************************************************************
- *
- * SkPnmiGetVar - Retrieves the value of a single OID
- *
- * Description:
- *     Calls a general sub-function for all this stuff. If the instance
- *     -1 is passed, the values of all instances are returned in an
- *     array of values.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to take
- *                              the data.
- *     SK_PNMI_ERR_UNKNOWN_OID  The requested OID is unknown
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                           exist (e.g. port instance 3 on a two port
- *                              adapter.
- */
-static int SkPnmiGetVar(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-SK_U32 Id,             /* Object ID that is to be processed */
-void *pBuf,            /* Buffer to which the management data will be copied */
-unsigned int *pLen,    /* On call: buffer length. On return: used buffer */
-SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode always zero */
-{
-       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-               ("PNMI: SkPnmiGetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
-                       Id, *pLen, Instance, NetIndex));
-
-       return (PnmiVar(pAC, IoC, SK_PNMI_GET, Id, (char *)pBuf, pLen,
-               Instance, NetIndex));
-}
-
-/*****************************************************************************
- *
- * SkPnmiPreSetVar - Presets the value of a single OID
- *
- * Description:
- *     Calls a general sub-function for all this stuff. The preset does
- *     the same as a set, but returns just before finally setting the
- *     new value. This is useful to check if a set might be successfull.
- *     If the instance -1 is passed, an array of values is supposed and
- *     all instances of the OID will be set.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
- *                              value range.
- *     SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
- *     SK_PNMI_ERR_UNKNOWN_OID  The requested OID is unknown.
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                           exist (e.g. port instance 3 on a two port
- *                              adapter.
- */
-static int SkPnmiPreSetVar(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-SK_U32 Id,             /* Object ID that is to be processed */
-void *pBuf,            /* Buffer to which the management data will be copied */
-unsigned int *pLen,    /* Total length of management data */
-SK_U32 Instance,       /* Instance (1..n) that is to be set or -1 */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode always zero */
-{
-       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-               ("PNMI: SkPnmiPreSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
-                       Id, *pLen, Instance, NetIndex));
-
-
-       return (PnmiVar(pAC, IoC, SK_PNMI_PRESET, Id, (char *)pBuf, pLen,
-               Instance, NetIndex));
-}
-
-/*****************************************************************************
- *
- * SkPnmiSetVar - Sets the value of a single OID
- *
- * Description:
- *     Calls a general sub-function for all this stuff. The preset does
- *     the same as a set, but returns just before finally setting the
- *     new value. This is useful to check if a set might be successfull.
- *     If the instance -1 is passed, an array of values is supposed and
- *     all instances of the OID will be set.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
- *                              value range.
- *     SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
- *     SK_PNMI_ERR_UNKNOWN_OID  The requested OID is unknown.
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                           exist (e.g. port instance 3 on a two port
- *                              adapter.
- */
-int SkPnmiSetVar(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-SK_U32 Id,             /* Object ID that is to be processed */
-void *pBuf,            /* Buffer to which the management data will be copied */
-unsigned int *pLen,    /* Total length of management data */
-SK_U32 Instance,       /* Instance (1..n) that is to be set or -1 */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode always zero */
-{
-       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-               ("PNMI: SkPnmiSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
-                       Id, *pLen, Instance, NetIndex));
-
-       return (PnmiVar(pAC, IoC, SK_PNMI_SET, Id, (char *)pBuf, pLen,
-               Instance, NetIndex));
-}
-
-/*****************************************************************************
- *
- * SkPnmiGetStruct - Retrieves the management database in SK_PNMI_STRUCT_DATA
- *
- * Description:
- *     Runs through the IdTable, queries the single OIDs and stores the
- *     returned data into the management database structure
- *     SK_PNMI_STRUCT_DATA. The offset of the OID in the structure
- *     is stored in the IdTable. The return value of the function will also
- *     be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
- *     minimum size of SK_PNMI_MIN_STRUCT_SIZE.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to take
- *                              the data.
- *     SK_PNMI_ERR_UNKNOWN_NET  The requested NetIndex doesn't exist
- */
-int SkPnmiGetStruct(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-void *pBuf,            /* Buffer to which the management data will be copied. */
-unsigned int *pLen,    /* Length of buffer */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode always zero */
-{
-       int             Ret;
-       unsigned int    TableIndex;
-       unsigned int    DstOffset;
-       unsigned int    InstanceNo;
-       unsigned int    InstanceCnt;
-       SK_U32          Instance;
-       unsigned int    TmpLen;
-       char            KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
-
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-               ("PNMI: SkPnmiGetStruct: Called, BufLen=%d, NetIndex=%d\n",
-                       *pLen, NetIndex));
-
-       if (*pLen < SK_PNMI_STRUCT_SIZE) {
-
-               if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
-
-                       SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
-                               (SK_U32)(-1));
-               }
-
-               *pLen = SK_PNMI_STRUCT_SIZE;
-               return (SK_PNMI_ERR_TOO_SHORT);
-       }
-
-    /*
-     * Check NetIndex
-     */
-       if (NetIndex >= pAC->Rlmt.NumNets) {
-               return (SK_PNMI_ERR_UNKNOWN_NET);
-       }
-
-       /* Update statistic */
-       SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On call");
-
-       if ((Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1)) !=
-               SK_PNMI_ERR_OK) {
-
-               SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
-               *pLen = SK_PNMI_MIN_STRUCT_SIZE;
-               return (Ret);
-       }
-
-       if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
-
-               SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
-               *pLen = SK_PNMI_MIN_STRUCT_SIZE;
-               return (Ret);
-       }
-
-       if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
-
-               SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
-               *pLen = SK_PNMI_MIN_STRUCT_SIZE;
-               return (Ret);
-       }
-
-       /*
-        * Increment semaphores to indicate that an update was
-        * already done
-        */
-       pAC->Pnmi.MacUpdatedFlag ++;
-       pAC->Pnmi.RlmtUpdatedFlag ++;
-       pAC->Pnmi.SirqUpdatedFlag ++;
-
-       /* Get vpd keys for instance calculation */
-       Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &TmpLen);
-       if (Ret != SK_PNMI_ERR_OK) {
-
-               pAC->Pnmi.MacUpdatedFlag --;
-               pAC->Pnmi.RlmtUpdatedFlag --;
-               pAC->Pnmi.SirqUpdatedFlag --;
-
-               SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
-               SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
-               *pLen = SK_PNMI_MIN_STRUCT_SIZE;
-               return (SK_PNMI_ERR_GENERAL);
-       }
-
-       /* Retrieve values */
-       SK_MEMSET((char *)pBuf, 0, SK_PNMI_STRUCT_SIZE);
-       for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
-
-               InstanceNo = IdTable[TableIndex].InstanceNo;
-               for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
-                       InstanceCnt ++) {
-
-                       DstOffset = IdTable[TableIndex].Offset +
-                               (InstanceCnt - 1) *
-                               IdTable[TableIndex].StructSize;
-
-                       /*
-                        * For the VPD the instance is not an index number
-                        * but the key itself. Determin with the instance
-                        * counter the VPD key to be used.
-                        */
-                       if (IdTable[TableIndex].Id == OID_SKGE_VPD_KEY ||
-                               IdTable[TableIndex].Id == OID_SKGE_VPD_VALUE ||
-                               IdTable[TableIndex].Id == OID_SKGE_VPD_ACCESS ||
-                               IdTable[TableIndex].Id == OID_SKGE_VPD_ACTION) {
-
-                               SK_STRNCPY((char *)&Instance, KeyArr[InstanceCnt - 1], 4);
-                       }
-                       else {
-                               Instance = (SK_U32)InstanceCnt;
-                       }
-
-                       TmpLen = *pLen - DstOffset;
-                       Ret = IdTable[TableIndex].Func(pAC, IoC, SK_PNMI_GET,
-                               IdTable[TableIndex].Id, (char *)pBuf +
-                               DstOffset, &TmpLen, Instance, TableIndex, NetIndex);
-
-                       /*
-                        * An unknown instance error means that we reached
-                        * the last instance of that variable. Proceed with
-                        * the next OID in the table and ignore the return
-                        * code.
-                        */
-                       if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
-
-                break;
-                       }
-
-                       if (Ret != SK_PNMI_ERR_OK) {
-
-                               pAC->Pnmi.MacUpdatedFlag --;
-                               pAC->Pnmi.RlmtUpdatedFlag --;
-                               pAC->Pnmi.SirqUpdatedFlag --;
-
-                               SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
-                               SK_PNMI_SET_STAT(pBuf, Ret, DstOffset);
-                               *pLen = SK_PNMI_MIN_STRUCT_SIZE;
-                               return (Ret);
-                       }
-               }
-       }
-
-       pAC->Pnmi.MacUpdatedFlag --;
-       pAC->Pnmi.RlmtUpdatedFlag --;
-       pAC->Pnmi.SirqUpdatedFlag --;
-
-       *pLen = SK_PNMI_STRUCT_SIZE;
-       SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
-       SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
-       return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * SkPnmiPreSetStruct - Presets the management database in SK_PNMI_STRUCT_DATA
- *
- * Description:
- *     Calls a general sub-function for all this set stuff. The preset does
- *     the same as a set, but returns just before finally setting the
- *     new value. This is useful to check if a set might be successfull.
- *     The sub-function runs through the IdTable, checks which OIDs are able
- *     to set, and calls the handler function of the OID to perform the
- *     preset. The return value of the function will also be stored in
- *     SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
- *     SK_PNMI_MIN_STRUCT_SIZE.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
- *                              value range.
- */
-int SkPnmiPreSetStruct(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-void *pBuf,            /* Buffer which contains the data to be set */
-unsigned int *pLen,    /* Length of buffer */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode always zero */
-{
-       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-               ("PNMI: SkPnmiPreSetStruct: Called, BufLen=%d, NetIndex=%d\n",
-                       *pLen, NetIndex));
-
-       return (PnmiStruct(pAC, IoC, SK_PNMI_PRESET, (char *)pBuf,
-                                       pLen, NetIndex));
-}
-
-/*****************************************************************************
- *
- * SkPnmiSetStruct - Sets the management database in SK_PNMI_STRUCT_DATA
- *
- * Description:
- *     Calls a general sub-function for all this set stuff. The return value
- *     of the function will also be stored in SK_PNMI_STRUCT_DATA if the
- *     passed buffer has the minimum size of SK_PNMI_MIN_STRUCT_SIZE.
- *     The sub-function runs through the IdTable, checks which OIDs are able
- *     to set, and calls the handler function of the OID to perform the
- *     set. The return value of the function will also be stored in
- *     SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
- *     SK_PNMI_MIN_STRUCT_SIZE.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
- *                              value range.
- */
-int SkPnmiSetStruct(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-void *pBuf,            /* Buffer which contains the data to be set */
-unsigned int *pLen,    /* Length of buffer */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode always zero */
-{
-       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-               ("PNMI: SkPnmiSetStruct: Called, BufLen=%d, NetIndex=%d\n",
-                       *pLen, NetIndex));
-
-       return (PnmiStruct(pAC, IoC, SK_PNMI_SET, (char *)pBuf,
-                                       pLen, NetIndex));
-}
-
-/*****************************************************************************
- *
- * SkPnmiEvent - Event handler
- *
- * Description:
- *     Handles the following events:
- *     SK_PNMI_EVT_SIRQ_OVERFLOW     When a hardware counter overflows an
- *                                   interrupt will be generated which is
- *                                   first handled by SIRQ which generates a
- *                                   this event. The event increments the
- *                                   upper 32 bit of the 64 bit counter.
- *     SK_PNMI_EVT_SEN_XXX           The event is generated by the I2C module
- *                                   when a sensor reports a warning or
- *                                   error. The event will store a trap
- *                                   message in the trap buffer.
- *     SK_PNMI_EVT_CHG_EST_TIMER     The timer event was initiated by this
- *                                   module and is used to calculate the
- *                                   port switches per hour.
- *     SK_PNMI_EVT_CLEAR_COUNTER     The event clears all counters and
- *                                   timestamps.
- *     SK_PNMI_EVT_XMAC_RESET        The event is generated by the driver
- *                                   before a hard reset of the XMAC is
- *                                   performed. All counters will be saved
- *                                   and added to the hardware counter
- *                                   values after reset to grant continuous
- *                                   counter values.
- *     SK_PNMI_EVT_RLMT_PORT_UP      Generated by RLMT to notify that a port
- *                                   went logically up. A trap message will
- *                                   be stored to the trap buffer.
- *     SK_PNMI_EVT_RLMT_PORT_DOWN    Generated by RLMT to notify that a port
- *                                   went logically down. A trap message will
- *                                   be stored to the trap buffer.
- *     SK_PNMI_EVT_RLMT_SEGMENTATION Generated by RLMT to notify that two
- *                                   spanning tree root bridges were
- *                                   detected. A trap message will be stored
- *                                   to the trap buffer.
- *     SK_PNMI_EVT_RLMT_ACTIVE_DOWN  Notifies PNMI that an active port went
- *                                   down. PNMI will not further add the
- *                                   statistic values to the virtual port.
- *     SK_PNMI_EVT_RLMT_ACTIVE_UP    Notifies PNMI that a port went up and
- *                                   is now an active port. PNMI will now
- *                                   add the statistic data of this port to
- *                                   the virtual port.
- *     SK_PNMI_EVT_RLMT_SET_NETS     Notifies PNMI about the net mode. The first parameter
- *                                   contains the number of nets. 1 means single net, 2 means
- *                                   dual net. The second parameter is -1
- *
- * Returns:
- *     Always 0
- */
-int SkPnmiEvent(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-SK_U32 Event,          /* Event-Id */
-SK_EVPARA Param)       /* Event dependent parameter */
-{
-       unsigned int    PhysPortIndex;
-    unsigned int       MaxNetNumber;
-       int                     CounterIndex;
-       int                     Ret;
-       SK_U16          MacStatus;
-       SK_U64          OverflowStatus;
-       SK_U64          Mask;
-       int                     MacType;
-       SK_U64          Value;
-       SK_U32          Val32;
-       SK_U16          Register;
-       SK_EVPARA       EventParam;
-       SK_U64          NewestValue;
-       SK_U64          OldestValue;
-       SK_U64          Delta;
-       SK_PNMI_ESTIMATE *pEst;
-       SK_U32          NetIndex;
-       SK_GEPORT       *pPrt;
-       SK_PNMI_VCT     *pVctBackupData;
-       SK_U32          RetCode;
-       int             i;
-       SK_U32          CableLength;
-
-
-#ifdef DEBUG
-       if (Event != SK_PNMI_EVT_XMAC_RESET) {
-
-               SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-                       ("PNMI: SkPnmiEvent: Called, Event=0x%x, Param=0x%x\n",
-                       (unsigned int)Event, (unsigned int)Param.Para64));
-       }
-#endif /* DEBUG */
-       SK_PNMI_CHECKFLAGS("SkPnmiEvent: On call");
-
-       MacType = pAC->GIni.GIMacType;
-       
-       switch (Event) {
-
-       case SK_PNMI_EVT_SIRQ_OVERFLOW:
-               PhysPortIndex = (int)Param.Para32[0];
-               MacStatus = (SK_U16)Param.Para32[1];
-#ifdef DEBUG
-               if (PhysPortIndex >= SK_MAX_MACS) {
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SIRQ_OVERFLOW parameter"
-                                " wrong, PhysPortIndex=0x%x\n",
-                               PhysPortIndex));
-                       return (0);
-               }
-#endif /* DEBUG */
-               OverflowStatus = 0;
-
-               /*
-                * Check which source caused an overflow interrupt.
-                */
-               if ((pAC->GIni.GIFunc.pFnMacOverflow(pAC, IoC, PhysPortIndex,
-                               MacStatus, &OverflowStatus) != 0) ||
-                       (OverflowStatus == 0)) {
-
-                       SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
-                       return (0);
-               }
-
-               /*
-                * Check the overflow status register and increment
-                * the upper dword of corresponding counter.
-                */
-               for (CounterIndex = 0; CounterIndex < sizeof(Mask) * 8;
-                       CounterIndex ++) {
-
-                       Mask = (SK_U64)1 << CounterIndex;
-                       if ((OverflowStatus & Mask) == 0) {
-
-                               continue;
-                       }
-
-                       switch (StatOvrflwBit[CounterIndex][MacType]) {
-
-                       case SK_PNMI_HTX_UTILUNDER:
-                       case SK_PNMI_HTX_UTILOVER:
-                               if (MacType == SK_MAC_XMAC) {
-                                       XM_IN16(IoC, PhysPortIndex, XM_TX_CMD, &Register);
-                                       Register |= XM_TX_SAM_LINE;
-                                       XM_OUT16(IoC, PhysPortIndex, XM_TX_CMD, Register);
-                               }
-                               break;
-
-                       case SK_PNMI_HRX_UTILUNDER:
-                       case SK_PNMI_HRX_UTILOVER:
-                               if (MacType == SK_MAC_XMAC) {
-                                       XM_IN16(IoC, PhysPortIndex, XM_RX_CMD, &Register);
-                                       Register |= XM_RX_SAM_LINE;
-                                       XM_OUT16(IoC, PhysPortIndex, XM_RX_CMD, Register);
-                               }
-                               break;
-
-                       case SK_PNMI_HTX_OCTETHIGH:
-                       case SK_PNMI_HTX_OCTETLOW:
-                       case SK_PNMI_HTX_RESERVED:
-                       case SK_PNMI_HRX_OCTETHIGH:
-                       case SK_PNMI_HRX_OCTETLOW:
-                       case SK_PNMI_HRX_IRLENGTH:
-                       case SK_PNMI_HRX_RESERVED:
-                       
-                       /*
-                        * the following counters aren't be handled (id > 63)
-                        */
-                       case SK_PNMI_HTX_SYNC:
-                       case SK_PNMI_HTX_SYNC_OCTET:
-                               break;
-
-                       case SK_PNMI_HRX_LONGFRAMES:
-                               if (MacType == SK_MAC_GMAC) {
-                                       pAC->Pnmi.Port[PhysPortIndex].
-                                               CounterHigh[CounterIndex] ++;
-                               }
-                               break;
-
-                       default:
-                               pAC->Pnmi.Port[PhysPortIndex].
-                                       CounterHigh[CounterIndex] ++;
-                       }
-               }
-               break;
-
-       case SK_PNMI_EVT_SEN_WAR_LOW:
-#ifdef DEBUG
-               if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_LOW parameter wrong, SensorIndex=%d\n",
-                               (unsigned int)Param.Para64));
-                       return (0);
-               }
-#endif /* DEBUG */
-
-               /*
-                * Store a trap message in the trap buffer and generate
-                * an event for user space applications with the
-                * SK_DRIVER_SENDEVENT macro.
-                */
-               QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_LOW,
-                       (unsigned int)Param.Para64);
-               (void)SK_DRIVER_SENDEVENT(pAC, IoC);
-               break;
-
-       case SK_PNMI_EVT_SEN_WAR_UPP:
-#ifdef DEBUG
-               if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_UPP parameter wrong, SensorIndex=%d\n",
-                               (unsigned int)Param.Para64));
-                       return (0);
-               }
-#endif /* DEBUG */
-
-               /*
-                * Store a trap message in the trap buffer and generate
-                * an event for user space applications with the
-                * SK_DRIVER_SENDEVENT macro.
-                */
-               QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_UPP,
-                       (unsigned int)Param.Para64);
-               (void)SK_DRIVER_SENDEVENT(pAC, IoC);
-               break;
-
-       case SK_PNMI_EVT_SEN_ERR_LOW:
-#ifdef DEBUG
-               if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_LOW parameter wrong, SensorIndex=%d\n",
-                               (unsigned int)Param.Para64));
-                       return (0);
-               }
-#endif /* DEBUG */
-
-               /*
-                * Store a trap message in the trap buffer and generate
-                * an event for user space applications with the
-                * SK_DRIVER_SENDEVENT macro.
-                */
-               QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_LOW,
-                       (unsigned int)Param.Para64);
-               (void)SK_DRIVER_SENDEVENT(pAC, IoC);
-               break;
-       
-       case SK_PNMI_EVT_SEN_ERR_UPP:
-#ifdef DEBUG
-               if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_UPP parameter wrong, SensorIndex=%d\n",
-                               (unsigned int)Param.Para64));
-                       return (0);
-               }
-#endif /* DEBUG */
-
-               /*
-                * Store a trap message in the trap buffer and generate
-                * an event for user space applications with the
-                * SK_DRIVER_SENDEVENT macro.
-                */
-               QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_UPP,
-                       (unsigned int)Param.Para64);
-               (void)SK_DRIVER_SENDEVENT(pAC, IoC);
-               break;
-
-       case SK_PNMI_EVT_CHG_EST_TIMER:
-               /*
-                * Calculate port switch average on a per hour basis
-                *   Time interval for check       : 28125 ms
-                *   Number of values for average  : 8
-                *
-                * Be careful in changing these values, on change check
-                *   - typedef of SK_PNMI_ESTIMATE (Size of EstValue
-                *     array one less than value number)
-                *   - Timer initialization SkTimerStart() in SkPnmiInit
-                *   - Delta value below must be multiplicated with
-                *     power of 2
-                *
-                */
-               pEst = &pAC->Pnmi.RlmtChangeEstimate;
-               CounterIndex = pEst->EstValueIndex + 1;
-               if (CounterIndex == 7) {
-
-                       CounterIndex = 0;
-               }
-               pEst->EstValueIndex = CounterIndex;
-
-               NewestValue = pAC->Pnmi.RlmtChangeCts;
-               OldestValue = pEst->EstValue[CounterIndex];
-               pEst->EstValue[CounterIndex] = NewestValue;
-
-               /*
-                * Calculate average. Delta stores the number of
-                * port switches per 28125 * 8 = 225000 ms
-                */
-               if (NewestValue >= OldestValue) {
-
-                       Delta = NewestValue - OldestValue;
-               }
-               else {
-                       /* Overflow situation */
-                       Delta = (SK_U64)(0 - OldestValue) + NewestValue;
-               }
-
-               /*
-                * Extrapolate delta to port switches per hour.
-                *     Estimate = Delta * (3600000 / 225000)
-                *              = Delta * 16
-                *              = Delta << 4
-                */
-               pAC->Pnmi.RlmtChangeEstimate.Estimate = Delta << 4;
-
-               /*
-                * Check if threshold is exceeded. If the threshold is
-                * permanently exceeded every 28125 ms an event will be
-                * generated to remind the user of this condition.
-                */
-               if ((pAC->Pnmi.RlmtChangeThreshold != 0) &&
-                       (pAC->Pnmi.RlmtChangeEstimate.Estimate >=
-                       pAC->Pnmi.RlmtChangeThreshold)) {
-
-                       QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_CHANGE_THRES);
-                       (void)SK_DRIVER_SENDEVENT(pAC, IoC);
-               }
-
-               SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
-               SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
-                       28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
-                       EventParam);
-               break;
-
-       case SK_PNMI_EVT_CLEAR_COUNTER:
-               /*
-                *  Param.Para32[0] contains the NetIndex (0 ..1).
-                *  Param.Para32[1] is reserved, contains -1.
-                */
-               NetIndex = (SK_U32)Param.Para32[0];
-
-#ifdef DEBUG
-               if (NetIndex >= pAC->Rlmt.NumNets) {
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_CLEAR_COUNTER parameter wrong, NetIndex=%d\n",
-                               NetIndex));
-
-                       return (0);
-               }
-#endif /* DEBUG */
-
-               /*
-                * Set all counters and timestamps to zero.
-                * The according NetIndex is required as a
-                * parameter of the event.
-                */
-               ResetCounter(pAC, IoC, NetIndex);
-               break;
-
-       case SK_PNMI_EVT_XMAC_RESET:
-               /*
-                * To grant continuous counter values store the current
-                * XMAC statistic values to the entries 1..n of the
-                * CounterOffset array. XMAC Errata #2
-                */
-#ifdef DEBUG
-               if ((unsigned int)Param.Para64 >= SK_MAX_MACS) {
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_XMAC_RESET parameter wrong, PhysPortIndex=%d\n",
-                               (unsigned int)Param.Para64));
-                       return (0);
-               }
-#endif
-               PhysPortIndex = (unsigned int)Param.Para64;
-
-               /*
-                * Update XMAC statistic to get fresh values
-                */
-               Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
-               if (Ret != SK_PNMI_ERR_OK) {
-
-                       SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
-                       return (0);
-               }
-               /*
-                * Increment semaphore to indicate that an update was
-                * already done
-                */
-               pAC->Pnmi.MacUpdatedFlag ++;
-
-               for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
-                       CounterIndex ++) {
-
-                       if (!StatAddr[CounterIndex][MacType].GetOffset) {
-
-                               continue;
-                       }
-
-                       pAC->Pnmi.Port[PhysPortIndex].CounterOffset[CounterIndex] =
-                               GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
-                       
-                       pAC->Pnmi.Port[PhysPortIndex].CounterHigh[CounterIndex] = 0;
-               }
-
-               pAC->Pnmi.MacUpdatedFlag --;
-               break;
-
-       case SK_PNMI_EVT_RLMT_PORT_UP:
-               PhysPortIndex = (unsigned int)Param.Para32[0];
-#ifdef DEBUG
-               if (PhysPortIndex >= SK_MAX_MACS) {
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_UP parameter"
-                 " wrong, PhysPortIndex=%d\n", PhysPortIndex));
-
-                       return (0);
-               }
-#endif /* DEBUG */
-
-               /*
-                * Store a trap message in the trap buffer and generate an event for
-                * user space applications with the SK_DRIVER_SENDEVENT macro.
-                */
-               QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_UP, PhysPortIndex);
-               (void)SK_DRIVER_SENDEVENT(pAC, IoC);
-
-               /* Bugfix for XMAC errata (#10620)*/
-               if (MacType == SK_MAC_XMAC) {
-                       /* Add incremental difference to offset (#10620)*/
-                       (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                               XM_RXE_SHT_ERR, &Val32);
-                       
-                       Value = (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
-                                CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
-                       pAC->Pnmi.Port[PhysPortIndex].CounterOffset[SK_PNMI_HRX_SHORTS] +=
-                               Value - pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark;
-               }
-               
-               /* Tell VctStatus() that a link was up meanwhile. */
-               pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_LINK;         
-               break;
-
-    case SK_PNMI_EVT_RLMT_PORT_DOWN:
-               PhysPortIndex = (unsigned int)Param.Para32[0];
-
-#ifdef DEBUG
-               if (PhysPortIndex >= SK_MAX_MACS) {
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_DOWN parameter"
-                 " wrong, PhysPortIndex=%d\n", PhysPortIndex));
-
-                       return (0);
-               }
-#endif /* DEBUG */
-
-               /*
-                * Store a trap message in the trap buffer and generate an event for
-                * user space applications with the SK_DRIVER_SENDEVENT macro.
-                */
-               QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_DOWN, PhysPortIndex);
-               (void)SK_DRIVER_SENDEVENT(pAC, IoC);
-
-               /* Bugfix #10620 - get zero level for incremental difference */
-               if (MacType == SK_MAC_XMAC) {
-
-                       (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                               XM_RXE_SHT_ERR, &Val32);
-                       
-                       pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark =
-                               (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
-                                CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
-               }
-               break;
-
-       case SK_PNMI_EVT_RLMT_ACTIVE_DOWN:
-               PhysPortIndex = (unsigned int)Param.Para32[0];
-               NetIndex = (SK_U32)Param.Para32[1];
-
-#ifdef DEBUG
-               if (PhysPortIndex >= SK_MAX_MACS) {
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, PhysPort=%d\n",
-                               PhysPortIndex));
-               }
-
-               if (NetIndex >= pAC->Rlmt.NumNets) {
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, NetIndex=%d\n",
-                               NetIndex));
-               }
-#endif /* DEBUG */
-
-               /*
-                * For now, ignore event if NetIndex != 0.
-                */
-               if (Param.Para32[1] != 0) {
-
-                       return (0);
-               }
-
-               /*
-                * Nothing to do if port is already inactive
-                */
-               if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
-
-                       return (0);
-               }
-
-               /*
-                * Update statistic counters to calculate new offset for the virtual
-                * port and increment semaphore to indicate that an update was already
-                * done.
-                */
-               if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
-                       SK_PNMI_ERR_OK) {
-
-                       SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
-                       return (0);
-               }
-               pAC->Pnmi.MacUpdatedFlag ++;
-
-               /*
-                * Calculate new counter offset for virtual port to grant continous
-                * counting on port switches. The virtual port consists of all currently
-                * active ports. The port down event indicates that a port is removed
-                * from the virtual port. Therefore add the counter value of the removed
-                * port to the CounterOffset for the virtual port to grant the same
-                * counter value.
-                */
-               for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
-                       CounterIndex ++) {
-
-                       if (!StatAddr[CounterIndex][MacType].GetOffset) {
-
-                               continue;
-                       }
-
-                       Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
-
-                       pAC->Pnmi.VirtualCounterOffset[CounterIndex] += Value;
-               }
-
-               /*
-                * Set port to inactive
-                */
-               pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_FALSE;
-
-               pAC->Pnmi.MacUpdatedFlag --;
-               break;
-
-       case SK_PNMI_EVT_RLMT_ACTIVE_UP:
-               PhysPortIndex = (unsigned int)Param.Para32[0];
-               NetIndex = (SK_U32)Param.Para32[1];
-
-#ifdef DEBUG
-               if (PhysPortIndex >= SK_MAX_MACS) {
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, PhysPort=%d\n",
-                               PhysPortIndex));
-               }
-
-               if (NetIndex >= pAC->Rlmt.NumNets) {
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-                               ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, NetIndex=%d\n",
-                               NetIndex));
-               }
-#endif /* DEBUG */
-
-               /*
-                * For now, ignore event if NetIndex != 0.
-                */
-               if (Param.Para32[1] != 0) {
-
-                       return (0);
-               }
-
-               /*
-                * Nothing to do if port is already active
-                */
-               if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
-
-                       return (0);
-               }
-
-               /*
-                * Statistic maintenance
-                */
-               pAC->Pnmi.RlmtChangeCts ++;
-               pAC->Pnmi.RlmtChangeTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
-
-               /*
-                * Store a trap message in the trap buffer and generate an event for
-                * user space applications with the SK_DRIVER_SENDEVENT macro.
-                */
-               QueueRlmtNewMacTrap(pAC, PhysPortIndex);
-               (void)SK_DRIVER_SENDEVENT(pAC, IoC);
-
-               /*
-                * Update statistic counters to calculate new offset for the virtual
-                * port and increment semaphore to indicate that an update was
-                * already done.
-                */
-               if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
-                       SK_PNMI_ERR_OK) {
-
-                       SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
-                       return (0);
-               }
-               pAC->Pnmi.MacUpdatedFlag ++;
-
-               /*
-                * Calculate new counter offset for virtual port to grant continous
-                * counting on port switches. A new port is added to the virtual port.
-                * Therefore substract the counter value of the new port from the
-                * CounterOffset for the virtual port to grant the same value.
-                */
-               for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
-                       CounterIndex ++) {
-
-                       if (!StatAddr[CounterIndex][MacType].GetOffset) {
-
-                               continue;
-                       }
-
-                       Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
-
-                       pAC->Pnmi.VirtualCounterOffset[CounterIndex] -= Value;
-               }
-
-               /* Set port to active */
-               pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_TRUE;
-
-               pAC->Pnmi.MacUpdatedFlag --;
-               break;
-
-       case SK_PNMI_EVT_RLMT_SEGMENTATION:
-               /*
-                * Para.Para32[0] contains the NetIndex.
-                */
-
-               /*
-                * Store a trap message in the trap buffer and generate an event for
-                * user space applications with the SK_DRIVER_SENDEVENT macro.
-                */
-               QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_SEGMENTATION);
-               (void)SK_DRIVER_SENDEVENT(pAC, IoC);
-               break;
-
-    case SK_PNMI_EVT_RLMT_SET_NETS:
-               /*
-                *  Param.Para32[0] contains the number of Nets.
-                *  Param.Para32[1] is reserved, contains -1.
-                */
-           /*
-        * Check number of nets
-                */
-               MaxNetNumber = pAC->GIni.GIMacsFound;
-               if (((unsigned int)Param.Para32[0] < 1)
-                       || ((unsigned int)Param.Para32[0] > MaxNetNumber)) {
-                       return (SK_PNMI_ERR_UNKNOWN_NET);
-               }
-
-        if ((unsigned int)Param.Para32[0] == 1) { /* single net mode */
-               pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
-        }
-        else { /* dual net mode */
-               pAC->Pnmi.DualNetActiveFlag = SK_TRUE;
-        }
-        break;
-
-    case SK_PNMI_EVT_VCT_RESET:
-               PhysPortIndex = Param.Para32[0];
-               pPrt = &pAC->GIni.GP[PhysPortIndex];
-               pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
-               
-               if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
-                       RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
-                       if (RetCode == 2) {
-                               /*
-                                * VCT test is still running.
-                                * Start VCT timer counter again.
-                                */
-                               SK_MEMSET((char *) &Param, 0, sizeof(Param));
-                               Param.Para32[0] = PhysPortIndex;
-                               Param.Para32[1] = -1;
-                               SkTimerStart(pAC, IoC,
-                                       &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
-                               4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param);
-                               break;
-                       }
-                       pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
-                       pAC->Pnmi.VctStatus[PhysPortIndex] |=
-                               (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
-                       
-                       /* Copy results for later use to PNMI struct. */
-                       for (i = 0; i < 4; i++)  {
-                               if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
-                                       if ((pPrt->PMdiPairLen[i] > 35) &&
-                                               (pPrt->PMdiPairLen[i] < 0xff)) {
-                                               pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
-                                       }
-                               }
-                               if ((pPrt->PMdiPairLen[i] > 35) &&
-                                       (pPrt->PMdiPairLen[i] != 0xff)) {
-                                       CableLength = 1000 *
-                                               (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
-                               }
-                               else {
-                                       CableLength = 0;
-                               }
-                               pVctBackupData->PMdiPairLen[i] = CableLength;
-                               pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
-                       }
-                       
-                       Param.Para32[0] = PhysPortIndex;
-                       Param.Para32[1] = -1;
-                       SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Param);
-                       SkEventDispatcher(pAC, IoC);
-               }
-               
-               break;
-
-       default:
-               break;
-       }
-
-       SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
-       return (0);
-}
-
-
-/******************************************************************************
- *
- * Private functions
- *
- */
-
-/*****************************************************************************
- *
- * PnmiVar - Gets, presets, and sets single OIDs
- *
- * Description:
- *     Looks up the requested OID, calls the corresponding handler
- *     function, and passes the parameters with the get, preset, or
- *     set command. The function is called by SkGePnmiGetVar,
- *     SkGePnmiPreSetVar, or SkGePnmiSetVar.
- *
- * Returns:
- *     SK_PNMI_ERR_XXX. For details have a look at the description of the
- *     calling functions.
- *     SK_PNMI_ERR_UNKNOWN_NET  The requested NetIndex doesn't exist
- */
-PNMI_STATIC int PnmiVar(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int Action,            /* GET/PRESET/SET action */
-SK_U32 Id,             /* Object ID that is to be processed */
-char *pBuf,            /* Buffer used for the management data transfer */
-unsigned int *pLen,    /* Total length of pBuf management data  */
-SK_U32 Instance,       /* Instance (1..n) that is to be set or -1 */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode always zero */
-{
-       unsigned int    TableIndex;
-       int             Ret;
-
-
-       if ((TableIndex = LookupId(Id)) == (unsigned int)(-1)) {
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_UNKNOWN_OID);
-       }
-       
-    /* Check NetIndex */
-       if (NetIndex >= pAC->Rlmt.NumNets) {
-               return (SK_PNMI_ERR_UNKNOWN_NET);
-       }
-
-       SK_PNMI_CHECKFLAGS("PnmiVar: On call");
-
-       Ret = IdTable[TableIndex].Func(pAC, IoC, Action, Id, pBuf, pLen,
-               Instance, TableIndex, NetIndex);
-
-       SK_PNMI_CHECKFLAGS("PnmiVar: On return");
-
-       return (Ret);
-}
-
-/*****************************************************************************
- *
- * PnmiStruct - Presets and Sets data in structure SK_PNMI_STRUCT_DATA
- *
- * Description:
- *     The return value of the function will also be stored in
- *     SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
- *     SK_PNMI_MIN_STRUCT_SIZE. The sub-function runs through the IdTable,
- *     checks which OIDs are able to set, and calls the handler function of
- *     the OID to perform the set. The return value of the function will
- *     also be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
- *     minimum size of SK_PNMI_MIN_STRUCT_SIZE. The function is called
- *     by SkGePnmiPreSetStruct and SkGePnmiSetStruct.
- *
- * Returns:
- *     SK_PNMI_ERR_XXX. The codes are described in the calling functions.
- *     SK_PNMI_ERR_UNKNOWN_NET  The requested NetIndex doesn't exist
- */
-PNMI_STATIC int PnmiStruct(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int  Action,   /* PRESET/SET action to be performed */
-char *pBuf,            /* Buffer used for the management data transfer */
-unsigned int *pLen,    /* Length of pBuf management data buffer */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode always zero */
-{
-       int             Ret;
-       unsigned int    TableIndex;
-       unsigned int    DstOffset;
-       unsigned int    Len;
-       unsigned int    InstanceNo;
-       unsigned int    InstanceCnt;
-       SK_U32          Instance;
-       SK_U32          Id;
-
-
-       /* Check if the passed buffer has the right size */
-       if (*pLen < SK_PNMI_STRUCT_SIZE) {
-
-               /* Check if we can return the error within the buffer */
-               if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
-
-                       SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
-                               (SK_U32)(-1));
-               }
-
-               *pLen = SK_PNMI_STRUCT_SIZE;
-               return (SK_PNMI_ERR_TOO_SHORT);
-       }
-       
-    /* Check NetIndex */
-       if (NetIndex >= pAC->Rlmt.NumNets) {
-               return (SK_PNMI_ERR_UNKNOWN_NET);
-       }
-       
-       SK_PNMI_CHECKFLAGS("PnmiStruct: On call");
-
-       /*
-        * Update the values of RLMT and SIRQ and increment semaphores to
-        * indicate that an update was already done.
-        */
-       if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
-
-               SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
-               *pLen = SK_PNMI_MIN_STRUCT_SIZE;
-               return (Ret);
-       }
-
-       if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
-
-               SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
-               *pLen = SK_PNMI_MIN_STRUCT_SIZE;
-               return (Ret);
-       }
-
-       pAC->Pnmi.RlmtUpdatedFlag ++;
-       pAC->Pnmi.SirqUpdatedFlag ++;
-
-       /* Preset/Set values */
-       for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
-
-               if ((IdTable[TableIndex].Access != SK_PNMI_RW) &&
-                       (IdTable[TableIndex].Access != SK_PNMI_WO)) {
-
-                       continue;
-               }
-
-               InstanceNo = IdTable[TableIndex].InstanceNo;
-               Id = IdTable[TableIndex].Id;
-
-               for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
-                       InstanceCnt ++) {
-
-                       DstOffset = IdTable[TableIndex].Offset +
-                               (InstanceCnt - 1) *
-                               IdTable[TableIndex].StructSize;
-
-                       /*
-                        * Because VPD multiple instance variables are
-                        * not setable we do not need to evaluate VPD
-                        * instances. Have a look to VPD instance
-                        * calculation in SkPnmiGetStruct().
-                        */
-                       Instance = (SK_U32)InstanceCnt;
-
-                       /*
-                        * Evaluate needed buffer length
-                        */
-                       Len = 0;
-                       Ret = IdTable[TableIndex].Func(pAC, IoC,
-                               SK_PNMI_GET, IdTable[TableIndex].Id,
-                               NULL, &Len, Instance, TableIndex, NetIndex);
-
-                       if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
-
-                               break;
-                       }
-                       if (Ret != SK_PNMI_ERR_TOO_SHORT) {
-
-                               pAC->Pnmi.RlmtUpdatedFlag --;
-                               pAC->Pnmi.SirqUpdatedFlag --;
-
-                               SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
-                               SK_PNMI_SET_STAT(pBuf,
-                                       SK_PNMI_ERR_GENERAL, DstOffset);
-                               *pLen = SK_PNMI_MIN_STRUCT_SIZE;
-                               return (SK_PNMI_ERR_GENERAL);
-                       }
-                       if (Id == OID_SKGE_VPD_ACTION) {
-
-                               switch (*(pBuf + DstOffset)) {
-
-                               case SK_PNMI_VPD_CREATE:
-                                       Len = 3 + *(pBuf + DstOffset + 3);
-                                       break;
-
-                               case SK_PNMI_VPD_DELETE:
-                                       Len = 3;
-                                       break;
-
-                               default:
-                                       Len = 1;
-                                       break;
-                               }
-                       }
-
-                       /* Call the OID handler function */
-                       Ret = IdTable[TableIndex].Func(pAC, IoC, Action,
-                               IdTable[TableIndex].Id, pBuf + DstOffset,
-                               &Len, Instance, TableIndex, NetIndex);
-
-                       if (Ret != SK_PNMI_ERR_OK) {
-
-                               pAC->Pnmi.RlmtUpdatedFlag --;
-                               pAC->Pnmi.SirqUpdatedFlag --;
-
-                               SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
-                               SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_BAD_VALUE,
-                                       DstOffset);
-                               *pLen = SK_PNMI_MIN_STRUCT_SIZE;
-                               return (SK_PNMI_ERR_BAD_VALUE);
-                       }
-               }
-       }
-
-       pAC->Pnmi.RlmtUpdatedFlag --;
-       pAC->Pnmi.SirqUpdatedFlag --;
-
-       SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
-       SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
-       return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * LookupId - Lookup an OID in the IdTable
- *
- * Description:
- *     Scans the IdTable to find the table entry of an OID.
- *
- * Returns:
- *     The table index or -1 if not found.
- */
-PNMI_STATIC int LookupId(
-SK_U32 Id)             /* Object identifier to be searched */
-{
-       int i;
-
-       for (i = 0; i < ID_TABLE_SIZE; i++) {
-
-               if (IdTable[i].Id == Id) {
-
-                       return i;
-               }
-       }
-
-       return (-1);
-}
-
-/*****************************************************************************
- *
- * OidStruct - Handler of OID_SKGE_ALL_DATA
- *
- * Description:
- *     This OID performs a Get/Preset/SetStruct call and returns all data
- *     in a SK_PNMI_STRUCT_DATA structure.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
- *                              value range.
- *     SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                           exist (e.g. port instance 3 on a two port
- *                              adapter.
- */
-PNMI_STATIC int OidStruct(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int Action,            /* GET/PRESET/SET action */
-SK_U32 Id,             /* Object ID that is to be processed */
-char *pBuf,            /* Buffer used for the management data transfer */
-unsigned int *pLen,    /* On call: pBuf buffer length. On return: used buffer */
-SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode always zero */
-{
-       if (Id != OID_SKGE_ALL_DATA) {
-
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR003,
-                       SK_PNMI_ERR003MSG);
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_GENERAL);
-       }
-
-       /*
-        * Check instance. We only handle single instance variables
-        */
-       if (Instance != (SK_U32)(-1) && Instance != 1) {
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_UNKNOWN_INST);
-       }
-
-       switch (Action) {
-
-       case SK_PNMI_GET:
-               return (SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex));
-
-       case SK_PNMI_PRESET:
-               return (SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
-
-       case SK_PNMI_SET:
-               return (SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
-       }
-
-       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR004, SK_PNMI_ERR004MSG);
-
-       *pLen = 0;
-       return (SK_PNMI_ERR_GENERAL);
-}
-
-/*****************************************************************************
- *
- * Perform - OID handler of OID_SKGE_ACTION
- *
- * Description:
- *     None.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
- *                              value range.
- *     SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                           exist (e.g. port instance 3 on a two port
- *                              adapter.
- */
-PNMI_STATIC int Perform(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int Action,            /* GET/PRESET/SET action */
-SK_U32 Id,             /* Object ID that is to be processed */
-char *pBuf,            /* Buffer used for the management data transfer */
-unsigned int *pLen,    /* On call: pBuf buffer length. On return: used buffer */
-SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode always zero */
-{
-       int     Ret;
-       SK_U32  ActionOp;
-
-
-       /*
-        * Check instance. We only handle single instance variables
-        */
-       if (Instance != (SK_U32)(-1) && Instance != 1) {
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_UNKNOWN_INST);
-       }
-
-       if (*pLen < sizeof(SK_U32)) {
-
-               *pLen = sizeof(SK_U32);
-               return (SK_PNMI_ERR_TOO_SHORT);
-       }
-
-       /* Check if a get should be performed */
-       if (Action == SK_PNMI_GET) {
-
-               /* A get is easy. We always return the same value */
-               ActionOp = (SK_U32)SK_PNMI_ACT_IDLE;
-               SK_PNMI_STORE_U32(pBuf, ActionOp);
-               *pLen = sizeof(SK_U32);
-
-               return (SK_PNMI_ERR_OK);
-       }
-
-       /* Continue with PRESET/SET action */
-       if (*pLen > sizeof(SK_U32)) {
-
-               return (SK_PNMI_ERR_BAD_VALUE);
-       }
-
-       /* Check if the command is a known one */
-       SK_PNMI_READ_U32(pBuf, ActionOp);
-       if (*pLen > sizeof(SK_U32) ||
-               (ActionOp != SK_PNMI_ACT_IDLE &&
-               ActionOp != SK_PNMI_ACT_RESET &&
-               ActionOp != SK_PNMI_ACT_SELFTEST &&
-               ActionOp != SK_PNMI_ACT_RESETCNT)) {
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_BAD_VALUE);
-       }
-
-       /* A preset ends here */
-       if (Action == SK_PNMI_PRESET) {
-
-               return (SK_PNMI_ERR_OK);
-       }
-
-       switch (ActionOp) {
-
-       case SK_PNMI_ACT_IDLE:
-               /* Nothing to do */
-               break;
-
-       case SK_PNMI_ACT_RESET:
-               /*
-                * Perform a driver reset or something that comes near
-                * to this.
-                */
-               Ret = SK_DRIVER_RESET(pAC, IoC);
-               if (Ret != 0) {
-
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR005,
-                               SK_PNMI_ERR005MSG);
-
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-               break;
-
-       case SK_PNMI_ACT_SELFTEST:
-               /*
-                * Perform a driver selftest or something similar to this.
-                * Currently this feature is not used and will probably
-                * implemented in another way.
-                */
-               Ret = SK_DRIVER_SELFTEST(pAC, IoC);
-               pAC->Pnmi.TestResult = Ret;
-               break;
-
-       case SK_PNMI_ACT_RESETCNT:
-               /* Set all counters and timestamps to zero */
-               ResetCounter(pAC, IoC, NetIndex);
-               break;
-
-       default:
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR006,
-                       SK_PNMI_ERR006MSG);
-
-               return (SK_PNMI_ERR_GENERAL);
-       }
-
-       return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * Mac8023Stat - OID handler of OID_GEN_XXX and OID_802_3_XXX
- *
- * Description:
- *     Retrieves the statistic values of the virtual port (logical
- *     index 0). Only special OIDs of NDIS are handled which consist
- *     of a 32 bit instead of a 64 bit value. The OIDs are public
- *     because perhaps some other platform can use them too.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                           exist (e.g. port instance 3 on a two port
- *                              adapter.
- */
-PNMI_STATIC int Mac8023Stat(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int Action,            /* GET/PRESET/SET action */
-SK_U32 Id,             /* Object ID that is to be processed */
-char *pBuf,            /* Buffer used for the management data transfer */
-unsigned int *pLen,    /* On call: pBuf buffer length. On return: used buffer */
-SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex,       /* Index to the Id table */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode always zero */
-{
-       int     Ret;
-       SK_U64  StatVal;
-       SK_U32  StatVal32;
-       SK_BOOL Is64BitReq = SK_FALSE;
-
-       /*
-        * Only the active Mac is returned
-        */
-       if (Instance != (SK_U32)(-1) && Instance != 1) {
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_UNKNOWN_INST);
-       }
-
-       /*
-        * Check action type
-        */
-       if (Action != SK_PNMI_GET) {
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_READ_ONLY);
-       }
-
-       /* Check length */
-       switch (Id) {
-
-       case OID_802_3_PERMANENT_ADDRESS:
-       case OID_802_3_CURRENT_ADDRESS:
-               if (*pLen < sizeof(SK_MAC_ADDR)) {
-
-                       *pLen = sizeof(SK_MAC_ADDR);
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               break;
-
-       default:
-#ifndef SK_NDIS_64BIT_CTR
-               if (*pLen < sizeof(SK_U32)) {
-                       *pLen = sizeof(SK_U32);
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-
-#else /* SK_NDIS_64BIT_CTR */
-
-               /* for compatibility, at least 32bit are required for OID */
-               if (*pLen < sizeof(SK_U32)) {
-                       /*
-                       * but indicate handling for 64bit values,
-                       * if insufficient space is provided
-                       */
-                       *pLen = sizeof(SK_U64);
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-
-               Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
-#endif /* SK_NDIS_64BIT_CTR */
-               break;
-       }
-
-       /*
-        * Update all statistics, because we retrieve virtual MAC, which
-        * consists of multiple physical statistics and increment semaphore
-        * to indicate that an update was already done.
-        */
-       Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
-       if ( Ret != SK_PNMI_ERR_OK) {
-
-               *pLen = 0;
-               return (Ret);
-       }
-       pAC->Pnmi.MacUpdatedFlag ++;
-
-       /*
-        * Get value (MAC Index 0 identifies the virtual MAC)
-        */
-       switch (Id) {
-
-       case OID_802_3_PERMANENT_ADDRESS:
-               CopyMac(pBuf, &pAC->Addr.Net[NetIndex].PermanentMacAddress);
-               *pLen = sizeof(SK_MAC_ADDR);
-               break;
-
-       case OID_802_3_CURRENT_ADDRESS:
-               CopyMac(pBuf, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
-               *pLen = sizeof(SK_MAC_ADDR);
-               break;
-
-       default:
-               StatVal = GetStatVal(pAC, IoC, 0, IdTable[TableIndex].Param, NetIndex);
-
-               /* by default 32bit values are evaluated */
-               if (!Is64BitReq) {
-                       StatVal32 = (SK_U32)StatVal;
-                       SK_PNMI_STORE_U32(pBuf, StatVal32);
-                       *pLen = sizeof(SK_U32);
-               }
-               else {
-                       SK_PNMI_STORE_U64(pBuf, StatVal);
-                       *pLen = sizeof(SK_U64);
-               }
-               break;
-       }
-
-       pAC->Pnmi.MacUpdatedFlag --;
-
-       return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * MacPrivateStat - OID handler function of OID_SKGE_STAT_XXX
- *
- * Description:
- *     Retrieves the MAC statistic data.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                           exist (e.g. port instance 3 on a two port
- *                              adapter.
- */
-PNMI_STATIC int MacPrivateStat(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int Action,            /* GET/PRESET/SET action */
-SK_U32 Id,             /* Object ID that is to be processed */
-char *pBuf,            /* Buffer used for the management data transfer */
-unsigned int *pLen,    /* On call: pBuf buffer length. On return: used buffer */
-SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode always zero */
-{
-       unsigned int    LogPortMax;
-       unsigned int    LogPortIndex;
-       unsigned int    PhysPortMax;
-       unsigned int    Limit;
-       unsigned int    Offset;
-       int                             MacType;
-       int                             Ret;
-       SK_U64                  StatVal;
-       
-       
-
-       /* Calculate instance if wished. MAC index 0 is the virtual MAC */
-       PhysPortMax = pAC->GIni.GIMacsFound;
-       LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
-       
-       MacType = pAC->GIni.GIMacType;
-
-       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
-               LogPortMax--;
-       }
-
-       if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
-               /* Check instance range */
-               if ((Instance < 1) || (Instance > LogPortMax)) {
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_UNKNOWN_INST);
-               }
-               LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
-               Limit = LogPortIndex + 1;
-       }
-
-       else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
-
-               LogPortIndex = 0;
-               Limit = LogPortMax;
-       }
-
-       /* Check action */
-       if (Action != SK_PNMI_GET) {
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_READ_ONLY);
-       }
-
-       /* Check length */
-       if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U64)) {
-
-               *pLen = (Limit - LogPortIndex) * sizeof(SK_U64);
-               return (SK_PNMI_ERR_TOO_SHORT);
-       }
-
-       /*
-        * Update MAC statistic and increment semaphore to indicate that
-        * an update was already done.
-        */
-       Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
-       if (Ret != SK_PNMI_ERR_OK) {
-
-               *pLen = 0;
-               return (Ret);
-       }
-       pAC->Pnmi.MacUpdatedFlag ++;
-
-       /* Get value */
-       Offset = 0;
-       for (; LogPortIndex < Limit; LogPortIndex ++) {
-
-               switch (Id) {
-
-/* XXX not yet implemented due to XMAC problems
-               case OID_SKGE_STAT_TX_UTIL:
-                       return (SK_PNMI_ERR_GENERAL);
-*/
-/* XXX not yet implemented due to XMAC problems
-               case OID_SKGE_STAT_RX_UTIL:
-                       return (SK_PNMI_ERR_GENERAL);
-*/
-               case OID_SKGE_STAT_RX:
-                       if (MacType == SK_MAC_GMAC) {
-                               StatVal =
-                                       GetStatVal(pAC, IoC, LogPortIndex,
-                                                          SK_PNMI_HRX_BROADCAST, NetIndex) +
-                                       GetStatVal(pAC, IoC, LogPortIndex,
-                                                          SK_PNMI_HRX_MULTICAST, NetIndex) +
-                                       GetStatVal(pAC, IoC, LogPortIndex,
-                                                          SK_PNMI_HRX_UNICAST, NetIndex) +
-                                       GetStatVal(pAC, IoC, LogPortIndex,
-                                                          SK_PNMI_HRX_UNDERSIZE, NetIndex);
-                       }
-                       else {
-                               StatVal = GetStatVal(pAC, IoC, LogPortIndex,
-                                       IdTable[TableIndex].Param, NetIndex);
-                       }
-                       break;
-
-               case OID_SKGE_STAT_TX:
-                       if (MacType == SK_MAC_GMAC) {
-                               StatVal =
-                                       GetStatVal(pAC, IoC, LogPortIndex,
-                                                          SK_PNMI_HTX_BROADCAST, NetIndex) +
-                                       GetStatVal(pAC, IoC, LogPortIndex,
-                                                          SK_PNMI_HTX_MULTICAST, NetIndex) +
-                                       GetStatVal(pAC, IoC, LogPortIndex,
-                                                          SK_PNMI_HTX_UNICAST, NetIndex);
-                       }
-                       else {
-                               StatVal = GetStatVal(pAC, IoC, LogPortIndex,
-                                       IdTable[TableIndex].Param, NetIndex);
-                       }
-                       break;
-
-               default:
-                       StatVal = GetStatVal(pAC, IoC, LogPortIndex,
-                               IdTable[TableIndex].Param, NetIndex);
-               }
-               SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
-
-               Offset += sizeof(SK_U64);
-       }
-       *pLen = Offset;
-
-       pAC->Pnmi.MacUpdatedFlag --;
-
-       return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * Addr - OID handler function of OID_SKGE_PHYS_CUR_ADDR and _FAC_ADDR
- *
- * Description:
- *     Get/Presets/Sets the current and factory MAC address. The MAC
- *     address of the virtual port, which is reported to the OS, may
- *     not be changed, but the physical ones. A set to the virtual port
- *     will be ignored. No error should be reported because otherwise
- *     a multiple instance set (-1) would always fail.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
- *                              value range.
- *     SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                           exist (e.g. port instance 3 on a two port
- *                              adapter.
- */
-PNMI_STATIC int Addr(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int Action,            /* GET/PRESET/SET action */
-SK_U32 Id,             /* Object ID that is to be processed */
-char *pBuf,            /* Buffer used for the management data transfer */
-unsigned int *pLen,    /* On call: pBuf buffer length. On return: used buffer */
-SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode always zero */
-{
-       int             Ret;
-       unsigned int    LogPortMax;
-       unsigned int    PhysPortMax;
-       unsigned int    LogPortIndex;
-       unsigned int    PhysPortIndex;
-       unsigned int    Limit;
-       unsigned int    Offset = 0;
-
-       /*
-        * Calculate instance if wished. MAC index 0 is the virtual
-        * MAC.
-        */
-       PhysPortMax = pAC->GIni.GIMacsFound;
-       LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
-
-       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
-               LogPortMax--;
-       }
-
-       if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
-               /* Check instance range */
-               if ((Instance < 1) || (Instance > LogPortMax)) {
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_UNKNOWN_INST);
-               }
-               LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
-               Limit = LogPortIndex + 1;
-       }
-       else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
-
-               LogPortIndex = 0;
-               Limit = LogPortMax;
-       }
-
-       /*
-        * Perform Action
-        */
-       if (Action == SK_PNMI_GET) {
-
-               /* Check length */
-               if (*pLen < (Limit - LogPortIndex) * 6) {
-
-                       *pLen = (Limit - LogPortIndex) * 6;
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-
-               /*
-                * Get value
-                */
-               for (; LogPortIndex < Limit; LogPortIndex ++) {
-
-                       switch (Id) {
-
-                       case OID_SKGE_PHYS_CUR_ADDR:
-                               if (LogPortIndex == 0) {
-                                       CopyMac(pBuf + Offset, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
-                               }
-                               else {
-                                       PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
-
-                                       CopyMac(pBuf + Offset,
-                                               &pAC->Addr.Port[PhysPortIndex].CurrentMacAddress);
-                               }
-                               Offset += 6;
-                               break;
-
-                       case OID_SKGE_PHYS_FAC_ADDR:
-                               if (LogPortIndex == 0) {
-                                       CopyMac(pBuf + Offset,
-                                               &pAC->Addr.Net[NetIndex].PermanentMacAddress);
-                               }
-                               else {
-                                       PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
-                                               pAC, LogPortIndex);
-
-                                       CopyMac(pBuf + Offset,
-                                               &pAC->Addr.Port[PhysPortIndex].PermanentMacAddress);
-                               }
-                               Offset += 6;
-                               break;
-
-                       default:
-                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR008,
-                                       SK_PNMI_ERR008MSG);
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_GENERAL);
-                       }
-               }
-
-               *pLen = Offset;
-       }
-       else {
-               /*
-                * The logical MAC address may not be changed only
-                * the physical ones
-                */
-               if (Id == OID_SKGE_PHYS_FAC_ADDR) {
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_READ_ONLY);
-               }
-
-               /*
-                * Only the current address may be changed
-                */
-               if (Id != OID_SKGE_PHYS_CUR_ADDR) {
-
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR009,
-                               SK_PNMI_ERR009MSG);
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-
-               /* Check length */
-               if (*pLen < (Limit - LogPortIndex) * 6) {
-
-                       *pLen = (Limit - LogPortIndex) * 6;
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               if (*pLen > (Limit - LogPortIndex) * 6) {
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_BAD_VALUE);
-               }
-
-               /*
-                * Check Action
-                */
-               if (Action == SK_PNMI_PRESET) {
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_OK);
-               }
-
-               /*
-                * Set OID_SKGE_MAC_CUR_ADDR
-                */
-               for (; LogPortIndex < Limit; LogPortIndex ++, Offset += 6) {
-
-                       /*
-                        * A set to virtual port and set of broadcast
-                        * address will be ignored
-                        */
-                       if (LogPortIndex == 0 || SK_MEMCMP(pBuf + Offset,
-                               "\xff\xff\xff\xff\xff\xff", 6) == 0) {
-
-                               continue;
-                       }
-
-                       PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC,
-                               LogPortIndex);
-
-                       Ret = SkAddrOverride(pAC, IoC, PhysPortIndex,
-                               (SK_MAC_ADDR *)(pBuf + Offset),
-                               (LogPortIndex == 0 ? SK_ADDR_VIRTUAL_ADDRESS :
-                               SK_ADDR_PHYSICAL_ADDRESS));
-                       if (Ret != SK_ADDR_OVERRIDE_SUCCESS) {
-
-                               return (SK_PNMI_ERR_GENERAL);
-                       }
-               }
-               *pLen = Offset;
-       }
-
-       return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * CsumStat - OID handler function of OID_SKGE_CHKSM_XXX
- *
- * Description:
- *     Retrieves the statistic values of the CSUM module. The CSUM data
- *     structure must be available in the SK_AC even if the CSUM module
- *     is not included, because PNMI reads the statistic data from the
- *     CSUM part of SK_AC directly.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                           exist (e.g. port instance 3 on a two port
- *                              adapter.
- */
-PNMI_STATIC int CsumStat(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int Action,            /* GET/PRESET/SET action */
-SK_U32 Id,             /* Object ID that is to be processed */
-char *pBuf,            /* Buffer used for the management data transfer */
-unsigned int *pLen,    /* On call: pBuf buffer length. On return: used buffer */
-SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode always zero */
-{
-       unsigned int    Index;
-       unsigned int    Limit;
-       unsigned int    Offset = 0;
-       SK_U64          StatVal;
-
-
-       /*
-        * Calculate instance if wished
-        */
-       if (Instance != (SK_U32)(-1)) {
-
-               if ((Instance < 1) || (Instance > SKCS_NUM_PROTOCOLS)) {
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_UNKNOWN_INST);
-               }
-               Index = (unsigned int)Instance - 1;
-               Limit = Index + 1;
-       }
-       else {
-               Index = 0;
-               Limit = SKCS_NUM_PROTOCOLS;
-       }
-
-       /*
-        * Check action
-        */
-       if (Action != SK_PNMI_GET) {
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_READ_ONLY);
-       }
-
-       /* Check length */
-       if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
-
-               *pLen = (Limit - Index) * sizeof(SK_U64);
-               return (SK_PNMI_ERR_TOO_SHORT);
-       }
-
-       /*
-        * Get value
-        */
-       for (; Index < Limit; Index ++) {
-
-               switch (Id) {
-
-               case OID_SKGE_CHKSM_RX_OK_CTS:
-                       StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxOkCts;
-                       break;
-
-               case OID_SKGE_CHKSM_RX_UNABLE_CTS:
-                       StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxUnableCts;
-                       break;
-
-               case OID_SKGE_CHKSM_RX_ERR_CTS:
-                       StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxErrCts;
-                       break;
-
-               case OID_SKGE_CHKSM_TX_OK_CTS:
-                       StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxOkCts;
-                       break;
-
-               case OID_SKGE_CHKSM_TX_UNABLE_CTS:
-                       StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxUnableCts;
-                       break;
-
-               default:
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR010,
-                               SK_PNMI_ERR010MSG);
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-
-               SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
-               Offset += sizeof(SK_U64);
-       }
-
-       /*
-        * Store used buffer space
-        */
-       *pLen = Offset;
-
-       return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * SensorStat - OID handler function of OID_SKGE_SENSOR_XXX
- *
- * Description:
- *     Retrieves the statistic values of the I2C module, which handles
- *     the temperature and voltage sensors.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                           exist (e.g. port instance 3 on a two port
- *                              adapter.
- */
-PNMI_STATIC int SensorStat(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int Action,            /* GET/PRESET/SET action */
-SK_U32 Id,             /* Object ID that is to be processed */
-char *pBuf,            /* Buffer used for the management data transfer */
-unsigned int *pLen,    /* On call: pBuf buffer length. On return: used buffer */
-SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode always zero */
-{
-       unsigned int    i;
-       unsigned int    Index;
-       unsigned int    Limit;
-       unsigned int    Offset;
-       unsigned int    Len;
-       SK_U32          Val32;
-       SK_U64          Val64;
-
-
-       /*
-        * Calculate instance if wished
-        */
-       if ((Instance != (SK_U32)(-1))) {
-
-               if ((Instance < 1) || (Instance > (SK_U32)pAC->I2c.MaxSens)) {
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_UNKNOWN_INST);
-               }
-
-               Index = (unsigned int)Instance -1;
-               Limit = (unsigned int)Instance;
-       }
-       else {
-               Index = 0;
-               Limit = (unsigned int) pAC->I2c.MaxSens;
-       }
-
-       /*
-        * Check action
-        */
-       if (Action != SK_PNMI_GET) {
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_READ_ONLY);
-       }
-
-       /* Check length */
-       switch (Id) {
-
-       case OID_SKGE_SENSOR_VALUE:
-       case OID_SKGE_SENSOR_WAR_THRES_LOW:
-       case OID_SKGE_SENSOR_WAR_THRES_UPP:
-       case OID_SKGE_SENSOR_ERR_THRES_LOW:
-       case OID_SKGE_SENSOR_ERR_THRES_UPP:
-               if (*pLen < (Limit - Index) * sizeof(SK_U32)) {
-
-                       *pLen = (Limit - Index) * sizeof(SK_U32);
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               break;
-
-       case OID_SKGE_SENSOR_DESCR:
-               for (Offset = 0, i = Index; i < Limit; i ++) {
-
-                       Len = (unsigned int)
-                               SK_STRLEN(pAC->I2c.SenTable[i].SenDesc) + 1;
-                       if (Len >= SK_PNMI_STRINGLEN2) {
-
-                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR011,
-                                       SK_PNMI_ERR011MSG);
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_GENERAL);
-                       }
-                       Offset += Len;
-               }
-               if (*pLen < Offset) {
-
-                       *pLen = Offset;
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               break;
-
-       case OID_SKGE_SENSOR_INDEX:
-       case OID_SKGE_SENSOR_TYPE:
-       case OID_SKGE_SENSOR_STATUS:
-               if (*pLen < Limit - Index) {
-
-                       *pLen = Limit - Index;
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               break;
-
-       case OID_SKGE_SENSOR_WAR_CTS:
-       case OID_SKGE_SENSOR_WAR_TIME:
-       case OID_SKGE_SENSOR_ERR_CTS:
-       case OID_SKGE_SENSOR_ERR_TIME:
-               if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
-
-                       *pLen = (Limit - Index) * sizeof(SK_U64);
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               break;
-
-       default:
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR012,
-                       SK_PNMI_ERR012MSG);
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_GENERAL);
-
-       }
-
-       /*
-        * Get value
-        */
-       for (Offset = 0; Index < Limit; Index ++) {
-
-               switch (Id) {
-
-               case OID_SKGE_SENSOR_INDEX:
-                       *(pBuf + Offset) = (char)Index;
-                       Offset += sizeof(char);
-                       break;
-
-               case OID_SKGE_SENSOR_DESCR:
-                       Len = SK_STRLEN(pAC->I2c.SenTable[Index].SenDesc);
-                       SK_MEMCPY(pBuf + Offset + 1,
-                               pAC->I2c.SenTable[Index].SenDesc, Len);
-                       *(pBuf + Offset) = (char)Len;
-                       Offset += Len + 1;
-                       break;
-
-               case OID_SKGE_SENSOR_TYPE:
-                       *(pBuf + Offset) =
-                               (char)pAC->I2c.SenTable[Index].SenType;
-                       Offset += sizeof(char);
-                       break;
-
-               case OID_SKGE_SENSOR_VALUE:
-                       Val32 = (SK_U32)pAC->I2c.SenTable[Index].SenValue;
-                       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
-                       Offset += sizeof(SK_U32);
-                       break;
-
-               case OID_SKGE_SENSOR_WAR_THRES_LOW:
-                       Val32 = (SK_U32)pAC->I2c.SenTable[Index].
-                               SenThreWarnLow;
-                       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
-                       Offset += sizeof(SK_U32);
-                       break;
-
-               case OID_SKGE_SENSOR_WAR_THRES_UPP:
-                       Val32 = (SK_U32)pAC->I2c.SenTable[Index].
-                               SenThreWarnHigh;
-                       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
-                       Offset += sizeof(SK_U32);
-                       break;
-
-               case OID_SKGE_SENSOR_ERR_THRES_LOW:
-                       Val32 = (SK_U32)pAC->I2c.SenTable[Index].
-                               SenThreErrLow;
-                       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
-                       Offset += sizeof(SK_U32);
-                       break;
-
-               case OID_SKGE_SENSOR_ERR_THRES_UPP:
-                       Val32 = pAC->I2c.SenTable[Index].SenThreErrHigh;
-                       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
-                       Offset += sizeof(SK_U32);
-                       break;
-
-               case OID_SKGE_SENSOR_STATUS:
-                       *(pBuf + Offset) =
-                               (char)pAC->I2c.SenTable[Index].SenErrFlag;
-                       Offset += sizeof(char);
-                       break;
-
-               case OID_SKGE_SENSOR_WAR_CTS:
-                       Val64 = pAC->I2c.SenTable[Index].SenWarnCts;
-                       SK_PNMI_STORE_U64(pBuf + Offset, Val64);
-                       Offset += sizeof(SK_U64);
-                       break;
-
-               case OID_SKGE_SENSOR_ERR_CTS:
-                       Val64 = pAC->I2c.SenTable[Index].SenErrCts;
-                       SK_PNMI_STORE_U64(pBuf + Offset, Val64);
-                       Offset += sizeof(SK_U64);
-                       break;
-
-               case OID_SKGE_SENSOR_WAR_TIME:
-                       Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
-                               SenBegWarnTS);
-                       SK_PNMI_STORE_U64(pBuf + Offset, Val64);
-                       Offset += sizeof(SK_U64);
-                       break;
-
-               case OID_SKGE_SENSOR_ERR_TIME:
-                       Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
-                               SenBegErrTS);
-                       SK_PNMI_STORE_U64(pBuf + Offset, Val64);
-                       Offset += sizeof(SK_U64);
-                       break;
-
-               default:
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
-                               ("SensorStat: Unknown OID should be handled before"));
-
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-       }
-
-       /*
-        * Store used buffer space
-        */
-       *pLen = Offset;
-
-       return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * Vpd - OID handler function of OID_SKGE_VPD_XXX
- *
- * Description:
- *     Get/preset/set of VPD data. As instance the name of a VPD key
- *     can be passed. The Instance parameter is a SK_U32 and can be
- *     used as a string buffer for the VPD key, because their maximum
- *     length is 4 byte.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
- *                              value range.
- *     SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                           exist (e.g. port instance 3 on a two port
- *                              adapter.
- */
-PNMI_STATIC int Vpd(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int Action,            /* GET/PRESET/SET action */
-SK_U32 Id,             /* Object ID that is to be processed */
-char *pBuf,            /* Buffer used for the management data transfer */
-unsigned int *pLen,    /* On call: pBuf buffer length. On return: used buffer */
-SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode always zero */
-{
-       SK_VPD_STATUS   *pVpdStatus;
-       unsigned int    BufLen;
-       char            Buf[256];
-       char            KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
-       char            KeyStr[SK_PNMI_VPD_KEY_SIZE];
-       unsigned int    KeyNo;
-       unsigned int    Offset;
-       unsigned int    Index;
-       unsigned int    FirstIndex;
-       unsigned int    LastIndex;
-       unsigned int    Len;
-       int             Ret;
-       SK_U32          Val32;
-
-       /*
-        * Get array of all currently stored VPD keys
-        */
-       Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &KeyNo);
-       if (Ret != SK_PNMI_ERR_OK) {
-               *pLen = 0;
-               return (Ret);
-       }
-
-       /*
-        * If instance is not -1, try to find the requested VPD key for
-        * the multiple instance variables. The other OIDs as for example
-        * OID VPD_ACTION are single instance variables and must be
-        * handled separatly.
-        */
-       FirstIndex = 0;
-       LastIndex = KeyNo;
-
-       if ((Instance != (SK_U32)(-1))) {
-
-               if (Id == OID_SKGE_VPD_KEY || Id == OID_SKGE_VPD_VALUE ||
-                       Id == OID_SKGE_VPD_ACCESS) {
-
-                       SK_STRNCPY(KeyStr, (char *)&Instance, 4);
-                       KeyStr[4] = 0;
-
-                       for (Index = 0; Index < KeyNo; Index ++) {
-
-                               if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
-                                       FirstIndex = Index;
-                                       LastIndex = Index+1;
-                                       break;
-                               }
-                       }
-                       if (Index == KeyNo) {
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_UNKNOWN_INST);
-                       }
-               }
-               else if (Instance != 1) {
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_UNKNOWN_INST);
-               }
-       }
-
-       /*
-        * Get value, if a query should be performed
-        */
-       if (Action == SK_PNMI_GET) {
-
-               switch (Id) {
-
-               case OID_SKGE_VPD_FREE_BYTES:
-                       /* Check length of buffer */
-                       if (*pLen < sizeof(SK_U32)) {
-
-                               *pLen = sizeof(SK_U32);
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-                       /* Get number of free bytes */
-                       pVpdStatus = VpdStat(pAC, IoC);
-                       if (pVpdStatus == NULL) {
-
-                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR017,
-                                       SK_PNMI_ERR017MSG);
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_GENERAL);
-                       }
-                       if ((pVpdStatus->vpd_status & VPD_VALID) == 0) {
-
-                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR018,
-                                       SK_PNMI_ERR018MSG);
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_GENERAL);
-                       }
-                       
-                       Val32 = (SK_U32)pVpdStatus->vpd_free_rw;
-                       SK_PNMI_STORE_U32(pBuf, Val32);
-                       *pLen = sizeof(SK_U32);
-                       break;
-
-               case OID_SKGE_VPD_ENTRIES_LIST:
-                       /* Check length */
-                       for (Len = 0, Index = 0; Index < KeyNo; Index ++) {
-
-                               Len += SK_STRLEN(KeyArr[Index]) + 1;
-                       }
-                       if (*pLen < Len) {
-
-                               *pLen = Len;
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-
-                       /* Get value */
-                       *(pBuf) = (char)Len - 1;
-                       for (Offset = 1, Index = 0; Index < KeyNo; Index ++) {
-
-                               Len = SK_STRLEN(KeyArr[Index]);
-                               SK_MEMCPY(pBuf + Offset, KeyArr[Index], Len);
-
-                               Offset += Len;
-
-                               if (Index < KeyNo - 1) {
-
-                                       *(pBuf + Offset) = ' ';
-                                       Offset ++;
-                               }
-                       }
-                       *pLen = Offset;
-                       break;
-
-               case OID_SKGE_VPD_ENTRIES_NUMBER:
-                       /* Check length */
-                       if (*pLen < sizeof(SK_U32)) {
-
-                               *pLen = sizeof(SK_U32);
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-
-                       Val32 = (SK_U32)KeyNo;
-                       SK_PNMI_STORE_U32(pBuf, Val32);
-                       *pLen = sizeof(SK_U32);
-                       break;
-
-               case OID_SKGE_VPD_KEY:
-                       /* Check buffer length, if it is large enough */
-                       for (Len = 0, Index = FirstIndex;
-                               Index < LastIndex; Index ++) {
-
-                               Len += SK_STRLEN(KeyArr[Index]) + 1;
-                       }
-                       if (*pLen < Len) {
-
-                               *pLen = Len;
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-
-                       /*
-                        * Get the key to an intermediate buffer, because
-                        * we have to prepend a length byte.
-                        */
-                       for (Offset = 0, Index = FirstIndex;
-                               Index < LastIndex; Index ++) {
-
-                               Len = SK_STRLEN(KeyArr[Index]);
-
-                               *(pBuf + Offset) = (char)Len;
-                               SK_MEMCPY(pBuf + Offset + 1, KeyArr[Index],
-                                       Len);
-                               Offset += Len + 1;
-                       }
-                       *pLen = Offset;
-                       break;
-
-               case OID_SKGE_VPD_VALUE:
-                       /* Check the buffer length if it is large enough */
-                       for (Offset = 0, Index = FirstIndex;
-                               Index < LastIndex; Index ++) {
-
-                               BufLen = 256;
-                               if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
-                                       (int *)&BufLen) > 0 ||
-                                       BufLen >= SK_PNMI_VPD_DATALEN) {
-
-                                       SK_ERR_LOG(pAC, SK_ERRCL_SW,
-                                               SK_PNMI_ERR021,
-                                               SK_PNMI_ERR021MSG);
-
-                                       return (SK_PNMI_ERR_GENERAL);
-                               }
-                               Offset += BufLen + 1;
-                       }
-                       if (*pLen < Offset) {
-
-                               *pLen = Offset;
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-
-                       /*
-                        * Get the value to an intermediate buffer, because
-                        * we have to prepend a length byte.
-                        */
-                       for (Offset = 0, Index = FirstIndex;
-                               Index < LastIndex; Index ++) {
-
-                               BufLen = 256;
-                               if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
-                                       (int *)&BufLen) > 0 ||
-                                       BufLen >= SK_PNMI_VPD_DATALEN) {
-
-                                       SK_ERR_LOG(pAC, SK_ERRCL_SW,
-                                               SK_PNMI_ERR022,
-                                               SK_PNMI_ERR022MSG);
-
-                                       *pLen = 0;
-                                       return (SK_PNMI_ERR_GENERAL);
-                               }
-
-                               *(pBuf + Offset) = (char)BufLen;
-                               SK_MEMCPY(pBuf + Offset + 1, Buf, BufLen);
-                               Offset += BufLen + 1;
-                       }
-                       *pLen = Offset;
-                       break;
-
-               case OID_SKGE_VPD_ACCESS:
-                       if (*pLen < LastIndex - FirstIndex) {
-
-                               *pLen = LastIndex - FirstIndex;
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-
-                       for (Offset = 0, Index = FirstIndex;
-                               Index < LastIndex; Index ++) {
-
-                               if (VpdMayWrite(KeyArr[Index])) {
-
-                                       *(pBuf + Offset) = SK_PNMI_VPD_RW;
-                               }
-                               else {
-                                       *(pBuf + Offset) = SK_PNMI_VPD_RO;
-                               }
-                               Offset ++;
-                       }
-                       *pLen = Offset;
-                       break;
-
-               case OID_SKGE_VPD_ACTION:
-                       Offset = LastIndex - FirstIndex;
-                       if (*pLen < Offset) {
-
-                               *pLen = Offset;
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-                       SK_MEMSET(pBuf, 0, Offset);
-                       *pLen = Offset;
-                       break;
-
-               default:
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR023,
-                               SK_PNMI_ERR023MSG);
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-       }
-       else {
-               /* The only OID which can be set is VPD_ACTION */
-               if (Id != OID_SKGE_VPD_ACTION) {
-
-                       if (Id == OID_SKGE_VPD_FREE_BYTES ||
-                               Id == OID_SKGE_VPD_ENTRIES_LIST ||
-                               Id == OID_SKGE_VPD_ENTRIES_NUMBER ||
-                               Id == OID_SKGE_VPD_KEY ||
-                               Id == OID_SKGE_VPD_VALUE ||
-                               Id == OID_SKGE_VPD_ACCESS) {
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_READ_ONLY);
-                       }
-
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR024,
-                               SK_PNMI_ERR024MSG);
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-
-               /*
-                * From this point we handle VPD_ACTION. Check the buffer
-                * length. It should at least have the size of one byte.
-                */
-               if (*pLen < 1) {
-
-                       *pLen = 1;
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-
-               /*
-                * The first byte contains the VPD action type we should
-                * perform.
-                */
-               switch (*pBuf) {
-
-               case SK_PNMI_VPD_IGNORE:
-                       /* Nothing to do */
-                       break;
-
-               case SK_PNMI_VPD_CREATE:
-                       /*
-                        * We have to create a new VPD entry or we modify
-                        * an existing one. Check first the buffer length.
-                        */
-                       if (*pLen < 4) {
-
-                               *pLen = 4;
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-                       KeyStr[0] = pBuf[1];
-                       KeyStr[1] = pBuf[2];
-                       KeyStr[2] = 0;
-
-                       /*
-                        * Is the entry writable or does it belong to the
-                        * read-only area?
-                        */
-                       if (!VpdMayWrite(KeyStr)) {
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_BAD_VALUE);
-                       }
-
-                       Offset = (int)pBuf[3] & 0xFF;
-
-                       SK_MEMCPY(Buf, pBuf + 4, Offset);
-                       Buf[Offset] = 0;
-
-                       /* A preset ends here */
-                       if (Action == SK_PNMI_PRESET) {
-
-                               return (SK_PNMI_ERR_OK);
-                       }
-
-                       /* Write the new entry or modify an existing one */
-                       Ret = VpdWrite(pAC, IoC, KeyStr, Buf);
-                       if (Ret == SK_PNMI_VPD_NOWRITE ) {
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_BAD_VALUE);
-                       }
-                       else if (Ret != SK_PNMI_VPD_OK) {
-
-                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR025,
-                                       SK_PNMI_ERR025MSG);
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_GENERAL);
-                       }
-
-                       /*
-                        * Perform an update of the VPD data. This is
-                        * not mandantory, but just to be sure.
-                        */
-                       Ret = VpdUpdate(pAC, IoC);
-                       if (Ret != SK_PNMI_VPD_OK) {
-
-                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR026,
-                                       SK_PNMI_ERR026MSG);
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_GENERAL);
-                       }
-                       break;
-
-               case SK_PNMI_VPD_DELETE:
-                       /* Check if the buffer size is plausible */
-                       if (*pLen < 3) {
-
-                               *pLen = 3;
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-                       if (*pLen > 3) {
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_BAD_VALUE);
-                       }
-                       KeyStr[0] = pBuf[1];
-                       KeyStr[1] = pBuf[2];
-                       KeyStr[2] = 0;
-
-                       /* Find the passed key in the array */
-                       for (Index = 0; Index < KeyNo; Index ++) {
-
-                               if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
-
-                                       break;
-                               }
-                       }
-                       /*
-                        * If we cannot find the key it is wrong, so we
-                        * return an appropriate error value.
-                        */
-                       if (Index == KeyNo) {
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_BAD_VALUE);
-                       }
-
-                       if (Action == SK_PNMI_PRESET) {
-
-                               return (SK_PNMI_ERR_OK);
-                       }
-
-                       /* Ok, you wanted it and you will get it */
-                       Ret = VpdDelete(pAC, IoC, KeyStr);
-                       if (Ret != SK_PNMI_VPD_OK) {
-
-                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR027,
-                                       SK_PNMI_ERR027MSG);
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_GENERAL);
-                       }
-
-                       /*
-                        * Perform an update of the VPD data. This is
-                        * not mandantory, but just to be sure.
-                        */
-                       Ret = VpdUpdate(pAC, IoC);
-                       if (Ret != SK_PNMI_VPD_OK) {
-
-                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR028,
-                                       SK_PNMI_ERR028MSG);
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_GENERAL);
-                       }
-                       break;
-
-               default:
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_BAD_VALUE);
-               }
-       }
-
-       return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * General - OID handler function of various single instance OIDs
- *
- * Description:
- *     The code is simple. No description necessary.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                           exist (e.g. port instance 3 on a two port
- *                              adapter.
- */
-PNMI_STATIC int General(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int Action,            /* GET/PRESET/SET action */
-SK_U32 Id,             /* Object ID that is to be processed */
-char *pBuf,            /* Buffer used for the management data transfer */
-unsigned int *pLen,    /* On call: buffer length. On return: used buffer */
-SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode always zero */
-{
-       int             Ret;
-       unsigned int    Index;
-       unsigned int    Len;
-       unsigned int    Offset;
-       unsigned int    Val;
-       SK_U8           Val8;
-       SK_U16          Val16;
-       SK_U32          Val32;
-       SK_U64          Val64;
-       SK_U64          Val64RxHwErrs = 0;
-       SK_U64          Val64TxHwErrs = 0;
-       SK_BOOL         Is64BitReq = SK_FALSE;
-       char            Buf[256];
-       int                     MacType;
-
-       /*
-        * Check instance. We only handle single instance variables.
-        */
-       if (Instance != (SK_U32)(-1) && Instance != 1) {
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_UNKNOWN_INST);
-       }
-
-       /*
-        * Check action. We only allow get requests.
-        */
-       if (Action != SK_PNMI_GET) {
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_READ_ONLY);
-       }
-       
-       MacType = pAC->GIni.GIMacType;
-       
-       /*
-        * Check length for the various supported OIDs
-        */
-       switch (Id) {
-
-       case OID_GEN_XMIT_ERROR:
-       case OID_GEN_RCV_ERROR:
-       case OID_GEN_RCV_NO_BUFFER:
-#ifndef SK_NDIS_64BIT_CTR
-               if (*pLen < sizeof(SK_U32)) {
-                       *pLen = sizeof(SK_U32);
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-
-#else /* SK_NDIS_64BIT_CTR */
-
-               /*
-                * for compatibility, at least 32bit are required for oid
-                */
-               if (*pLen < sizeof(SK_U32)) {
-                       /*
-                       * but indicate handling for 64bit values,
-                       * if insufficient space is provided
-                       */
-                       *pLen = sizeof(SK_U64);
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-
-               Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
-#endif /* SK_NDIS_64BIT_CTR */
-               break;
-
-       case OID_SKGE_PORT_NUMBER:
-       case OID_SKGE_DEVICE_TYPE:
-       case OID_SKGE_RESULT:
-       case OID_SKGE_RLMT_MONITOR_NUMBER:
-       case OID_GEN_TRANSMIT_QUEUE_LENGTH:
-       case OID_SKGE_TRAP_NUMBER:
-       case OID_SKGE_MDB_VERSION:
-       case OID_SKGE_BOARDLEVEL:
-       case OID_SKGE_CHIPID:
-       case OID_SKGE_RAMSIZE:
-               if (*pLen < sizeof(SK_U32)) {
-
-                       *pLen = sizeof(SK_U32);
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               break;
-
-       case OID_SKGE_CHIPSET:
-               if (*pLen < sizeof(SK_U16)) {
-
-                       *pLen = sizeof(SK_U16);
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               break;
-
-       case OID_SKGE_BUS_TYPE:
-       case OID_SKGE_BUS_SPEED:
-       case OID_SKGE_BUS_WIDTH:
-       case OID_SKGE_SENSOR_NUMBER:
-       case OID_SKGE_CHKSM_NUMBER:
-       case OID_SKGE_VAUXAVAIL:
-               if (*pLen < sizeof(SK_U8)) {
-
-                       *pLen = sizeof(SK_U8);
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               break;
-
-       case OID_SKGE_TX_SW_QUEUE_LEN:
-       case OID_SKGE_TX_SW_QUEUE_MAX:
-       case OID_SKGE_TX_RETRY:
-       case OID_SKGE_RX_INTR_CTS:
-       case OID_SKGE_TX_INTR_CTS:
-       case OID_SKGE_RX_NO_BUF_CTS:
-       case OID_SKGE_TX_NO_BUF_CTS:
-       case OID_SKGE_TX_USED_DESCR_NO:
-       case OID_SKGE_RX_DELIVERED_CTS:
-       case OID_SKGE_RX_OCTETS_DELIV_CTS:
-       case OID_SKGE_RX_HW_ERROR_CTS:
-       case OID_SKGE_TX_HW_ERROR_CTS:
-       case OID_SKGE_IN_ERRORS_CTS:
-       case OID_SKGE_OUT_ERROR_CTS:
-       case OID_SKGE_ERR_RECOVERY_CTS:
-       case OID_SKGE_SYSUPTIME:
-               if (*pLen < sizeof(SK_U64)) {
-
-                       *pLen = sizeof(SK_U64);
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               break;
-
-       default:
-               /* Checked later */
-               break;
-       }
-
-       /* Update statistic */
-       if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
-               Id == OID_SKGE_TX_HW_ERROR_CTS ||
-               Id == OID_SKGE_IN_ERRORS_CTS ||
-               Id == OID_SKGE_OUT_ERROR_CTS ||
-               Id == OID_GEN_XMIT_ERROR ||
-               Id == OID_GEN_RCV_ERROR) {
-
-               /* Force the XMAC to update its statistic counters and
-                * Increment semaphore to indicate that an update was
-                * already done.
-                */
-               Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
-               if (Ret != SK_PNMI_ERR_OK) {
-
-                       *pLen = 0;
-                       return (Ret);
-               }
-               pAC->Pnmi.MacUpdatedFlag ++;
-
-               /*
-                * Some OIDs consist of multiple hardware counters. Those
-                * values which are contained in all of them will be added
-                * now.
-                */
-               switch (Id) {
-
-               case OID_SKGE_RX_HW_ERROR_CTS:
-               case OID_SKGE_IN_ERRORS_CTS:
-               case OID_GEN_RCV_ERROR:
-                       Val64RxHwErrs =
-                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_MISSED, NetIndex) +
-                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FRAMING, NetIndex) +
-                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex) +
-                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_JABBER, NetIndex) +
-                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CARRIER, NetIndex) +
-                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_IRLENGTH, NetIndex) +
-                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SYMBOL, NetIndex) +
-                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SHORTS, NetIndex) +
-                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT, NetIndex) +
-                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_TOO_LONG, NetIndex) +
-                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS, NetIndex) +
-                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CEXT, NetIndex);
-               break;
-
-               case OID_SKGE_TX_HW_ERROR_CTS:
-               case OID_SKGE_OUT_ERROR_CTS:
-               case OID_GEN_XMIT_ERROR:
-                       Val64TxHwErrs =
-                               GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_EXCESS_COL, NetIndex) +
-                               GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_LATE_COL, NetIndex) +
-                               GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_UNDERRUN, NetIndex) +
-                               GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_CARRIER, NetIndex);
-                       break;
-               }
-       }
-
-       /*
-        * Retrieve value
-        */
-       switch (Id) {
-
-       case OID_SKGE_SUPPORTED_LIST:
-               Len = ID_TABLE_SIZE * sizeof(SK_U32);
-               if (*pLen < Len) {
-
-                       *pLen = Len;
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               for (Offset = 0, Index = 0; Offset < Len;
-                       Offset += sizeof(SK_U32), Index ++) {
-
-                       Val32 = (SK_U32)IdTable[Index].Id;
-                       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
-               }
-               *pLen = Len;
-               break;
-
-       case OID_SKGE_BOARDLEVEL:
-               Val32 = (SK_U32)pAC->GIni.GILevel;
-               SK_PNMI_STORE_U32(pBuf, Val32);
-               *pLen = sizeof(SK_U32);
-               break;
-
-       case OID_SKGE_PORT_NUMBER:
-               Val32 = (SK_U32)pAC->GIni.GIMacsFound;
-               SK_PNMI_STORE_U32(pBuf, Val32);
-               *pLen = sizeof(SK_U32);
-               break;
-
-       case OID_SKGE_DEVICE_TYPE:
-               Val32 = (SK_U32)pAC->Pnmi.DeviceType;
-               SK_PNMI_STORE_U32(pBuf, Val32);
-               *pLen = sizeof(SK_U32);
-               break;
-
-       case OID_SKGE_DRIVER_DESCR:
-               if (pAC->Pnmi.pDriverDescription == NULL) {
-
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR007,
-                               SK_PNMI_ERR007MSG);
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-
-               Len = SK_STRLEN(pAC->Pnmi.pDriverDescription) + 1;
-               if (Len > SK_PNMI_STRINGLEN1) {
-
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR029,
-                               SK_PNMI_ERR029MSG);
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-
-               if (*pLen < Len) {
-
-                       *pLen = Len;
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               *pBuf = (char)(Len - 1);
-               SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverDescription, Len - 1);
-               *pLen = Len;
-               break;
-
-       case OID_SKGE_DRIVER_VERSION:
-               if (pAC->Pnmi.pDriverVersion == NULL) {
-
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
-                               SK_PNMI_ERR030MSG);
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-
-               Len = SK_STRLEN(pAC->Pnmi.pDriverVersion) + 1;
-               if (Len > SK_PNMI_STRINGLEN1) {
-
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
-                               SK_PNMI_ERR031MSG);
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-
-               if (*pLen < Len) {
-
-                       *pLen = Len;
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               *pBuf = (char)(Len - 1);
-               SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverVersion, Len - 1);
-               *pLen = Len;
-               break;
-
-       case OID_SKGE_DRIVER_RELDATE:
-               if (pAC->Pnmi.pDriverReleaseDate == NULL) {
-
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
-                               SK_PNMI_ERR053MSG);
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-
-               Len = SK_STRLEN(pAC->Pnmi.pDriverReleaseDate) + 1;
-               if (Len > SK_PNMI_STRINGLEN1) {
-
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
-                               SK_PNMI_ERR054MSG);
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-
-               if (*pLen < Len) {
-
-                       *pLen = Len;
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               *pBuf = (char)(Len - 1);
-               SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverReleaseDate, Len - 1);
-               *pLen = Len;
-               break;
-
-       case OID_SKGE_DRIVER_FILENAME:
-               if (pAC->Pnmi.pDriverFileName == NULL) {
-
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
-                               SK_PNMI_ERR055MSG);
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-
-               Len = SK_STRLEN(pAC->Pnmi.pDriverFileName) + 1;
-               if (Len > SK_PNMI_STRINGLEN1) {
-
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
-                               SK_PNMI_ERR056MSG);
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-
-               if (*pLen < Len) {
-
-                       *pLen = Len;
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               *pBuf = (char)(Len - 1);
-               SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverFileName, Len - 1);
-               *pLen = Len;
-               break;
-
-       case OID_SKGE_HW_DESCR:
-               /*
-                * The hardware description is located in the VPD. This
-                * query may move to the initialisation routine. But
-                * the VPD data is cached and therefore a call here
-                * will not make much difference.
-                */
-               Len = 256;
-               if (VpdRead(pAC, IoC, VPD_NAME, Buf, (int *)&Len) > 0) {
-
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR032,
-                               SK_PNMI_ERR032MSG);
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-               Len ++;
-               if (Len > SK_PNMI_STRINGLEN1) {
-
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR033,
-                               SK_PNMI_ERR033MSG);
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-               if (*pLen < Len) {
-
-                       *pLen = Len;
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               *pBuf = (char)(Len - 1);
-               SK_MEMCPY(pBuf + 1, Buf, Len - 1);
-               *pLen = Len;
-               break;
-
-       case OID_SKGE_HW_VERSION:
-               /* Oh, I love to do some string manipulation */
-               if (*pLen < 5) {
-
-                       *pLen = 5;
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               Val8 = (SK_U8)pAC->GIni.GIPciHwRev;
-               pBuf[0] = 4;
-               pBuf[1] = 'v';
-               pBuf[2] = (char)(0x30 | ((Val8 >> 4) & 0x0F));
-               pBuf[3] = '.';
-               pBuf[4] = (char)(0x30 | (Val8 & 0x0F));
-               *pLen = 5;
-               break;
-
-       case OID_SKGE_CHIPSET:
-               Val16 = pAC->Pnmi.Chipset;
-               SK_PNMI_STORE_U16(pBuf, Val16);
-               *pLen = sizeof(SK_U16);
-               break;
-
-       case OID_SKGE_CHIPID:
-               Val32 = pAC->GIni.GIChipId;
-               SK_PNMI_STORE_U32(pBuf, Val32);
-               *pLen = sizeof(SK_U32);
-               break;
-
-       case OID_SKGE_RAMSIZE:
-               Val32 = pAC->GIni.GIRamSize;
-               SK_PNMI_STORE_U32(pBuf, Val32);
-               *pLen = sizeof(SK_U32);
-               break;
-
-       case OID_SKGE_VAUXAVAIL:
-               *pBuf = (char) pAC->GIni.GIVauxAvail;
-               *pLen = sizeof(char);
-               break;
-
-       case OID_SKGE_BUS_TYPE:
-               *pBuf = (char) SK_PNMI_BUS_PCI;
-               *pLen = sizeof(char);
-               break;
-
-       case OID_SKGE_BUS_SPEED:
-               *pBuf = pAC->Pnmi.PciBusSpeed;
-               *pLen = sizeof(char);
-               break;
-
-       case OID_SKGE_BUS_WIDTH:
-               *pBuf = pAC->Pnmi.PciBusWidth;
-               *pLen = sizeof(char);
-               break;
-
-       case OID_SKGE_RESULT:
-               Val32 = pAC->Pnmi.TestResult;
-               SK_PNMI_STORE_U32(pBuf, Val32);
-               *pLen = sizeof(SK_U32);
-               break;
-
-       case OID_SKGE_SENSOR_NUMBER:
-               *pBuf = (char)pAC->I2c.MaxSens;
-               *pLen = sizeof(char);
-               break;
-
-       case OID_SKGE_CHKSM_NUMBER:
-               *pBuf = SKCS_NUM_PROTOCOLS;
-               *pLen = sizeof(char);
-               break;
-
-       case OID_SKGE_TRAP_NUMBER:
-               GetTrapQueueLen(pAC, &Len, &Val);
-               Val32 = (SK_U32)Val;
-               SK_PNMI_STORE_U32(pBuf, Val32);
-               *pLen = sizeof(SK_U32);
-               break;
-
-       case OID_SKGE_TRAP:
-               GetTrapQueueLen(pAC, &Len, &Val);
-               if (*pLen < Len) {
-
-                       *pLen = Len;
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               CopyTrapQueue(pAC, pBuf);
-               *pLen = Len;
-               break;
-
-       case OID_SKGE_RLMT_MONITOR_NUMBER:
-/* XXX Not yet implemented by RLMT therefore we return zero elements */
-               Val32 = 0;
-               SK_PNMI_STORE_U32(pBuf, Val32);
-               *pLen = sizeof(SK_U32);
-               break;
-
-       case OID_SKGE_TX_SW_QUEUE_LEN:
-               /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
-               if (MacType == SK_MAC_XMAC) {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueLen;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.BufPort[0].TxSwQueueLen +
-                                       pAC->Pnmi.BufPort[1].TxSwQueueLen;
-                       }                       
-               }
-               else {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.Port[0].TxSwQueueLen +
-                                       pAC->Pnmi.Port[1].TxSwQueueLen;
-                       }                       
-               }
-               SK_PNMI_STORE_U64(pBuf, Val64);
-               *pLen = sizeof(SK_U64);
-               break;
-
-
-       case OID_SKGE_TX_SW_QUEUE_MAX:
-               /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
-               if (MacType == SK_MAC_XMAC) {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueMax;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.BufPort[0].TxSwQueueMax +
-                                       pAC->Pnmi.BufPort[1].TxSwQueueMax;
-                       }
-               }
-               else {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueMax;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.Port[0].TxSwQueueMax +
-                                       pAC->Pnmi.Port[1].TxSwQueueMax;
-                       }
-               }
-               SK_PNMI_STORE_U64(pBuf, Val64);
-               *pLen = sizeof(SK_U64);
-               break;
-
-       case OID_SKGE_TX_RETRY:
-               /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
-               if (MacType == SK_MAC_XMAC) {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.BufPort[NetIndex].TxRetryCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.BufPort[0].TxRetryCts +
-                                       pAC->Pnmi.BufPort[1].TxRetryCts;
-                       }
-               }
-               else {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.Port[NetIndex].TxRetryCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.Port[0].TxRetryCts +
-                                       pAC->Pnmi.Port[1].TxRetryCts;
-                       }
-               }
-               SK_PNMI_STORE_U64(pBuf, Val64);
-               *pLen = sizeof(SK_U64);
-               break;
-
-       case OID_SKGE_RX_INTR_CTS:
-               /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
-               if (MacType == SK_MAC_XMAC) {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.BufPort[NetIndex].RxIntrCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.BufPort[0].RxIntrCts +
-                                       pAC->Pnmi.BufPort[1].RxIntrCts;
-                       }
-               }
-               else {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.Port[NetIndex].RxIntrCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.Port[0].RxIntrCts +
-                                       pAC->Pnmi.Port[1].RxIntrCts;
-                       }
-               }
-               SK_PNMI_STORE_U64(pBuf, Val64);
-               *pLen = sizeof(SK_U64);
-               break;
-
-       case OID_SKGE_TX_INTR_CTS:
-               /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
-               if (MacType == SK_MAC_XMAC) {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.BufPort[NetIndex].TxIntrCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.BufPort[0].TxIntrCts +
-                                       pAC->Pnmi.BufPort[1].TxIntrCts;
-                       }
-               }
-               else {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.Port[NetIndex].TxIntrCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.Port[0].TxIntrCts +
-                                       pAC->Pnmi.Port[1].TxIntrCts;
-                       }
-               }
-               SK_PNMI_STORE_U64(pBuf, Val64);
-               *pLen = sizeof(SK_U64);
-               break;
-
-       case OID_SKGE_RX_NO_BUF_CTS:
-               /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
-               if (MacType == SK_MAC_XMAC) {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.BufPort[0].RxNoBufCts +
-                                       pAC->Pnmi.BufPort[1].RxNoBufCts;
-                       }
-               }
-               else {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.Port[0].RxNoBufCts +
-                                       pAC->Pnmi.Port[1].RxNoBufCts;
-                       }
-               }
-               SK_PNMI_STORE_U64(pBuf, Val64);
-               *pLen = sizeof(SK_U64);
-               break;
-
-       case OID_SKGE_TX_NO_BUF_CTS:
-               /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
-               if (MacType == SK_MAC_XMAC) {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.BufPort[0].TxNoBufCts +
-                                       pAC->Pnmi.BufPort[1].TxNoBufCts;
-                       }
-               }
-               else {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.Port[NetIndex].TxNoBufCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.Port[0].TxNoBufCts +
-                                       pAC->Pnmi.Port[1].TxNoBufCts;
-                       }
-               }
-               SK_PNMI_STORE_U64(pBuf, Val64);
-               *pLen = sizeof(SK_U64);
-               break;
-
-       case OID_SKGE_TX_USED_DESCR_NO:
-               /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
-               if (MacType == SK_MAC_XMAC) {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.BufPort[NetIndex].TxUsedDescrNo;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.BufPort[0].TxUsedDescrNo +
-                                       pAC->Pnmi.BufPort[1].TxUsedDescrNo;
-                       }
-               }
-               else {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.Port[NetIndex].TxUsedDescrNo;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.Port[0].TxUsedDescrNo +
-                                       pAC->Pnmi.Port[1].TxUsedDescrNo;
-                       }
-               }
-               SK_PNMI_STORE_U64(pBuf, Val64);
-               *pLen = sizeof(SK_U64);
-               break;
-
-       case OID_SKGE_RX_DELIVERED_CTS:
-               /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
-               if (MacType == SK_MAC_XMAC) {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.BufPort[NetIndex].RxDeliveredCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.BufPort[0].RxDeliveredCts +
-                                       pAC->Pnmi.BufPort[1].RxDeliveredCts;
-                       }
-               }
-               else {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.Port[NetIndex].RxDeliveredCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.Port[0].RxDeliveredCts +
-                                       pAC->Pnmi.Port[1].RxDeliveredCts;
-                       }
-               }
-               SK_PNMI_STORE_U64(pBuf, Val64);
-               *pLen = sizeof(SK_U64);
-               break;
-
-       case OID_SKGE_RX_OCTETS_DELIV_CTS:
-               /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
-               if (MacType == SK_MAC_XMAC) {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.BufPort[NetIndex].RxOctetsDeliveredCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.BufPort[0].RxOctetsDeliveredCts +
-                                       pAC->Pnmi.BufPort[1].RxOctetsDeliveredCts;
-                       }
-               }
-               else {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.Port[0].RxOctetsDeliveredCts +
-                                       pAC->Pnmi.Port[1].RxOctetsDeliveredCts;
-                       }
-               }
-               SK_PNMI_STORE_U64(pBuf, Val64);
-               *pLen = sizeof(SK_U64);
-               break;
-
-       case OID_SKGE_RX_HW_ERROR_CTS:
-               SK_PNMI_STORE_U64(pBuf, Val64RxHwErrs);
-               *pLen = sizeof(SK_U64);
-               break;
-
-       case OID_SKGE_TX_HW_ERROR_CTS:
-               SK_PNMI_STORE_U64(pBuf, Val64TxHwErrs);
-               *pLen = sizeof(SK_U64);
-               break;
-
-       case OID_SKGE_IN_ERRORS_CTS:
-               /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
-               if (MacType == SK_MAC_XMAC) {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = Val64RxHwErrs +
-                                       pAC->Pnmi.BufPort[0].RxNoBufCts +
-                                       pAC->Pnmi.BufPort[1].RxNoBufCts;
-                       }
-               }
-               else {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = Val64RxHwErrs +
-                                       pAC->Pnmi.Port[0].RxNoBufCts +
-                                       pAC->Pnmi.Port[1].RxNoBufCts;
-                       }
-               }
-               SK_PNMI_STORE_U64(pBuf, Val64);
-               *pLen = sizeof(SK_U64);
-               break;
-
-       case OID_SKGE_OUT_ERROR_CTS:
-               /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
-               if (MacType == SK_MAC_XMAC) {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = Val64TxHwErrs +
-                                       pAC->Pnmi.BufPort[0].TxNoBufCts +
-                                       pAC->Pnmi.BufPort[1].TxNoBufCts;
-                       }
-               }
-               else {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = Val64TxHwErrs +
-                                       pAC->Pnmi.Port[0].TxNoBufCts +
-                                       pAC->Pnmi.Port[1].TxNoBufCts;
-                       }
-               }
-               SK_PNMI_STORE_U64(pBuf, Val64);
-               *pLen = sizeof(SK_U64);
-               break;
-
-       case OID_SKGE_ERR_RECOVERY_CTS:
-               /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
-               if (MacType == SK_MAC_XMAC) {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.BufPort[NetIndex].ErrRecoveryCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.BufPort[0].ErrRecoveryCts +
-                                       pAC->Pnmi.BufPort[1].ErrRecoveryCts;
-                       }
-               }
-               else {
-                       /* Dual net mode */
-                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                               Val64 = pAC->Pnmi.Port[NetIndex].ErrRecoveryCts;
-                       }
-                       /* Single net mode */
-                       else {
-                               Val64 = pAC->Pnmi.Port[0].ErrRecoveryCts +
-                                       pAC->Pnmi.Port[1].ErrRecoveryCts;
-                       }
-               }
-               SK_PNMI_STORE_U64(pBuf, Val64);
-               *pLen = sizeof(SK_U64);
-               break;
-
-       case OID_SKGE_SYSUPTIME:
-               Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
-               Val64 -= pAC->Pnmi.StartUpTime;
-               SK_PNMI_STORE_U64(pBuf, Val64);
-               *pLen = sizeof(SK_U64);
-               break;
-
-       case OID_SKGE_MDB_VERSION:
-               Val32 = SK_PNMI_MDB_VERSION;
-               SK_PNMI_STORE_U32(pBuf, Val32);
-               *pLen = sizeof(SK_U32);
-               break;
-
-       case OID_GEN_RCV_ERROR:
-               /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
-               if (MacType == SK_MAC_XMAC) {
-                       Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
-               }
-               else {
-                       Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
-               }
-
-               /*
-                * by default 32bit values are evaluated
-                */
-               if (!Is64BitReq) {
-                       Val32 = (SK_U32)Val64;
-                       SK_PNMI_STORE_U32(pBuf, Val32);
-                       *pLen = sizeof(SK_U32);
-               }
-               else {
-                       SK_PNMI_STORE_U64(pBuf, Val64);
-                       *pLen = sizeof(SK_U64);
-               }
-               break;
-
-       case OID_GEN_XMIT_ERROR:
-               /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
-               if (MacType == SK_MAC_XMAC) {
-                       Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
-               }
-               else {
-                       Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
-               }
-
-               /*
-                * by default 32bit values are evaluated
-                */
-               if (!Is64BitReq) {
-                       Val32 = (SK_U32)Val64;
-                       SK_PNMI_STORE_U32(pBuf, Val32);
-                       *pLen = sizeof(SK_U32);
-               }
-               else {
-                       SK_PNMI_STORE_U64(pBuf, Val64);
-                       *pLen = sizeof(SK_U64);
-               }
-               break;
-
-       case OID_GEN_RCV_NO_BUFFER:
-               /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
-               if (MacType == SK_MAC_XMAC) {
-                       Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
-               }
-               else {
-                       Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
-               }
-
-               /*
-                * by default 32bit values are evaluated
-                */
-               if (!Is64BitReq) {
-                       Val32 = (SK_U32)Val64;
-                       SK_PNMI_STORE_U32(pBuf, Val32);
-                       *pLen = sizeof(SK_U32);
-               }
-               else {
-                       SK_PNMI_STORE_U64(pBuf, Val64);
-                       *pLen = sizeof(SK_U64);
-               }
-               break;
-
-       case OID_GEN_TRANSMIT_QUEUE_LENGTH:
-               Val32 = (SK_U32)pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
-               SK_PNMI_STORE_U32(pBuf, Val32);
-               *pLen = sizeof(SK_U32);
-               break;
-
-       default:
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR034,
-                       SK_PNMI_ERR034MSG);
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_GENERAL);
-       }
-
-       if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
-               Id == OID_SKGE_TX_HW_ERROR_CTS ||
-               Id == OID_SKGE_IN_ERRORS_CTS ||
-               Id == OID_SKGE_OUT_ERROR_CTS ||
-               Id == OID_GEN_XMIT_ERROR ||
-               Id == OID_GEN_RCV_ERROR) {
-
-               pAC->Pnmi.MacUpdatedFlag --;
-       }
-
-       return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * Rlmt - OID handler function of OID_SKGE_RLMT_XXX single instance.
- *
- * Description:
- *     Get/Presets/Sets the RLMT OIDs.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
- *                              value range.
- *     SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                           exist (e.g. port instance 3 on a two port
- *                              adapter.
- */
-PNMI_STATIC int Rlmt(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int Action,            /* GET/PRESET/SET action */
-SK_U32 Id,             /* Object ID that is to be processed */
-char *pBuf,            /* Buffer used for the management data transfer */
-unsigned int *pLen,    /* On call: pBuf buffer length. On return: used buffer */
-SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode always zero */
-{
-       int             Ret;
-       unsigned int    PhysPortIndex;
-       unsigned int    PhysPortMax;
-       SK_EVPARA       EventParam;
-       SK_U32          Val32;
-       SK_U64          Val64;
-
-
-       /*
-        * Check instance. Only single instance OIDs are allowed here.
-        */
-       if (Instance != (SK_U32)(-1) && Instance != 1) {
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_UNKNOWN_INST);
-       }
-
-       /*
-        * Perform the requested action.
-        */
-       if (Action == SK_PNMI_GET) {
-
-               /*
-                * Check if the buffer length is large enough.
-                */
-
-               switch (Id) {
-
-               case OID_SKGE_RLMT_MODE:
-               case OID_SKGE_RLMT_PORT_ACTIVE:
-               case OID_SKGE_RLMT_PORT_PREFERRED:
-                       if (*pLen < sizeof(SK_U8)) {
-
-                               *pLen = sizeof(SK_U8);
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-                       break;
-
-               case OID_SKGE_RLMT_PORT_NUMBER:
-                       if (*pLen < sizeof(SK_U32)) {
-
-                               *pLen = sizeof(SK_U32);
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-                       break;
-
-               case OID_SKGE_RLMT_CHANGE_CTS:
-               case OID_SKGE_RLMT_CHANGE_TIME:
-               case OID_SKGE_RLMT_CHANGE_ESTIM:
-               case OID_SKGE_RLMT_CHANGE_THRES:
-                       if (*pLen < sizeof(SK_U64)) {
-
-                               *pLen = sizeof(SK_U64);
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-                       break;
-
-               default:
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR035,
-                               SK_PNMI_ERR035MSG);
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-
-               /*
-                * Update RLMT statistic and increment semaphores to indicate
-                * that an update was already done. Maybe RLMT will hold its
-                * statistic always up to date some time. Then we can
-                * remove this type of call.
-                */
-               if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
-
-                       *pLen = 0;
-                       return (Ret);
-               }
-               pAC->Pnmi.RlmtUpdatedFlag ++;
-
-               /*
-                * Retrieve Value
-               */
-               switch (Id) {
-
-               case OID_SKGE_RLMT_MODE:
-                       *pBuf = (char)pAC->Rlmt.Net[0].RlmtMode;
-                       *pLen = sizeof(char);
-                       break;
-
-               case OID_SKGE_RLMT_PORT_NUMBER:
-                       Val32 = (SK_U32)pAC->GIni.GIMacsFound;
-                       SK_PNMI_STORE_U32(pBuf, Val32);
-                       *pLen = sizeof(SK_U32);
-                       break;
-
-               case OID_SKGE_RLMT_PORT_ACTIVE:
-                       *pBuf = 0;
-                       /*
-                        * If multiple ports may become active this OID
-                        * doesn't make sense any more. A new variable in
-                        * the port structure should be created. However,
-                        * for this variable the first active port is
-                        * returned.
-                        */
-                       PhysPortMax = pAC->GIni.GIMacsFound;
-
-                       for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
-                               PhysPortIndex ++) {
-
-                               if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
-
-                                       *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(PhysPortIndex);
-                                       break;
-                               }
-                       }
-                       *pLen = sizeof(char);
-                       break;
-
-               case OID_SKGE_RLMT_PORT_PREFERRED:
-                       *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(pAC->Rlmt.Net[NetIndex].Preference);
-                       *pLen = sizeof(char);
-                       break;
-
-               case OID_SKGE_RLMT_CHANGE_CTS:
-                       Val64 = pAC->Pnmi.RlmtChangeCts;
-                       SK_PNMI_STORE_U64(pBuf, Val64);
-                       *pLen = sizeof(SK_U64);
-                       break;
-
-               case OID_SKGE_RLMT_CHANGE_TIME:
-                       Val64 = pAC->Pnmi.RlmtChangeTime;
-                       SK_PNMI_STORE_U64(pBuf, Val64);
-                       *pLen = sizeof(SK_U64);
-                       break;
-
-               case OID_SKGE_RLMT_CHANGE_ESTIM:
-                       Val64 = pAC->Pnmi.RlmtChangeEstimate.Estimate;
-                       SK_PNMI_STORE_U64(pBuf, Val64);
-                       *pLen = sizeof(SK_U64);
-                       break;
-
-               case OID_SKGE_RLMT_CHANGE_THRES:
-                       Val64 = pAC->Pnmi.RlmtChangeThreshold;
-                       SK_PNMI_STORE_U64(pBuf, Val64);
-                       *pLen = sizeof(SK_U64);
-                       break;
-
-               default:
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
-                               ("Rlmt: Unknown OID should be handled before"));
-
-                       pAC->Pnmi.RlmtUpdatedFlag --;
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-
-               pAC->Pnmi.RlmtUpdatedFlag --;
-       }
-       else {
-               /* Perform a preset or set */
-               switch (Id) {
-
-               case OID_SKGE_RLMT_MODE:
-                       /* Check if the buffer length is plausible */
-                       if (*pLen < sizeof(char)) {
-
-                               *pLen = sizeof(char);
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-                       /* Check if the value range is correct */
-                       if (*pLen != sizeof(char) ||
-                               (*pBuf & SK_PNMI_RLMT_MODE_CHK_LINK) == 0 ||
-                               *(SK_U8 *)pBuf > 15) {
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_BAD_VALUE);
-                       }
-                       /* The preset ends here */
-                       if (Action == SK_PNMI_PRESET) {
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_OK);
-                       }
-                       /* Send an event to RLMT to change the mode */
-                       SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
-                       EventParam.Para32[0] |= (SK_U32)(*pBuf);
-                       EventParam.Para32[1] = 0;
-                       if (SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE,
-                               EventParam) > 0) {
-
-                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR037,
-                                       SK_PNMI_ERR037MSG);
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_GENERAL);
-                       }
-                       break;
-
-               case OID_SKGE_RLMT_PORT_PREFERRED:
-                       /* Check if the buffer length is plausible */
-                       if (*pLen < sizeof(char)) {
-
-                               *pLen = sizeof(char);
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-                       /* Check if the value range is correct */
-                       if (*pLen != sizeof(char) || *(SK_U8 *)pBuf >
-                               (SK_U8)pAC->GIni.GIMacsFound) {
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_BAD_VALUE);
-                       }
-                       /* The preset ends here */
-                       if (Action == SK_PNMI_PRESET) {
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_OK);
-                       }
-
-                       /*
-                        * Send an event to RLMT change the preferred port.
-                        * A param of -1 means automatic mode. RLMT will
-                        * make the decision which is the preferred port.
-                        */
-                       SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
-                       EventParam.Para32[0] = (SK_U32)(*pBuf) - 1;
-                       EventParam.Para32[1] = NetIndex;
-                       if (SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE,
-                               EventParam) > 0) {
-
-                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR038,
-                                       SK_PNMI_ERR038MSG);
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_GENERAL);
-                       }
-                       break;
-
-               case OID_SKGE_RLMT_CHANGE_THRES:
-                       /* Check if the buffer length is plausible */
-                       if (*pLen < sizeof(SK_U64)) {
-
-                               *pLen = sizeof(SK_U64);
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-                       /*
-                        * There are not many restrictions to the
-                        * value range.
-                        */
-                       if (*pLen != sizeof(SK_U64)) {
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_BAD_VALUE);
-                       }
-                       /* A preset ends here */
-                       if (Action == SK_PNMI_PRESET) {
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_OK);
-                       }
-                       /*
-                        * Store the new threshold, which will be taken
-                        * on the next timer event.
-                        */
-                       SK_PNMI_READ_U64(pBuf, Val64);
-                       pAC->Pnmi.RlmtChangeThreshold = Val64;
-                       break;
-
-               default:
-                       /* The other OIDs are not be able for set */
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_READ_ONLY);
-               }
-       }
-
-       return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * RlmtStat - OID handler function of OID_SKGE_RLMT_XXX multiple instance.
- *
- * Description:
- *     Performs get requests on multiple instance variables.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                           exist (e.g. port instance 3 on a two port
- *                              adapter.
- */
-PNMI_STATIC int RlmtStat(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int Action,            /* GET/PRESET/SET action */
-SK_U32 Id,             /* Object ID that is to be processed */
-char *pBuf,            /* Buffer used for the management data transfer */
-unsigned int *pLen,    /* On call: pBuf buffer length. On return: used buffer */
-SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode always zero */
-{
-       unsigned int    PhysPortMax;
-       unsigned int    PhysPortIndex;
-       unsigned int    Limit;
-       unsigned int    Offset;
-       int             Ret;
-       SK_U32          Val32;
-       SK_U64          Val64;
-
-       /*
-        * Calculate the port indexes from the instance.
-        */
-       PhysPortMax = pAC->GIni.GIMacsFound;
-
-       if ((Instance != (SK_U32)(-1))) {
-               /* Check instance range */
-               if ((Instance < 1) || (Instance > PhysPortMax)) {
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_UNKNOWN_INST);
-               }
-
-               /* Single net mode */
-               PhysPortIndex = Instance - 1;
-
-               /* Dual net mode */
-               if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                       PhysPortIndex = NetIndex;
-               }
-
-               /* Both net modes */
-               Limit = PhysPortIndex + 1;
-       }
-       else {
-               /* Single net mode */
-               PhysPortIndex = 0;
-               Limit = PhysPortMax;
-
-               /* Dual net mode */
-               if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                       PhysPortIndex = NetIndex;
-                       Limit = PhysPortIndex + 1;
-               }
-       }
-
-       /*
-        * Currently only get requests are allowed.
-        */
-       if (Action != SK_PNMI_GET) {
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_READ_ONLY);
-       }
-
-       /*
-        * Check if the buffer length is large enough.
-        */
-       switch (Id) {
-
-       case OID_SKGE_RLMT_PORT_INDEX:
-       case OID_SKGE_RLMT_STATUS:
-               if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
-
-                       *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               break;
-
-       case OID_SKGE_RLMT_TX_HELLO_CTS:
-       case OID_SKGE_RLMT_RX_HELLO_CTS:
-       case OID_SKGE_RLMT_TX_SP_REQ_CTS:
-       case OID_SKGE_RLMT_RX_SP_CTS:
-               if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U64)) {
-
-                       *pLen = (Limit - PhysPortIndex) * sizeof(SK_U64);
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               break;
-
-       default:
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR039,
-                       SK_PNMI_ERR039MSG);
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_GENERAL);
-
-       }
-
-       /*
-        * Update statistic and increment semaphores to indicate that
-        * an update was already done.
-        */
-       if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
-
-               *pLen = 0;
-               return (Ret);
-       }
-       pAC->Pnmi.RlmtUpdatedFlag ++;
-
-       /*
-        * Get value
-        */
-       Offset = 0;
-       for (; PhysPortIndex < Limit; PhysPortIndex ++) {
-
-               switch (Id) {
-
-               case OID_SKGE_RLMT_PORT_INDEX:
-                       Val32 = PhysPortIndex;
-                       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
-                       Offset += sizeof(SK_U32);
-                       break;
-
-               case OID_SKGE_RLMT_STATUS:
-                       if (pAC->Rlmt.Port[PhysPortIndex].PortState ==
-                               SK_RLMT_PS_INIT ||
-                               pAC->Rlmt.Port[PhysPortIndex].PortState ==
-                               SK_RLMT_PS_DOWN) {
-
-                               Val32 = SK_PNMI_RLMT_STATUS_ERROR;
-                       }
-                       else if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
-
-                               Val32 = SK_PNMI_RLMT_STATUS_ACTIVE;
-                       }
-                       else {
-                               Val32 = SK_PNMI_RLMT_STATUS_STANDBY;
-                       }
-                       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
-                       Offset += sizeof(SK_U32);
-                       break;
-
-               case OID_SKGE_RLMT_TX_HELLO_CTS:
-                       Val64 = pAC->Rlmt.Port[PhysPortIndex].TxHelloCts;
-                       SK_PNMI_STORE_U64(pBuf + Offset, Val64);
-                       Offset += sizeof(SK_U64);
-                       break;
-
-               case OID_SKGE_RLMT_RX_HELLO_CTS:
-                       Val64 = pAC->Rlmt.Port[PhysPortIndex].RxHelloCts;
-                       SK_PNMI_STORE_U64(pBuf + Offset, Val64);
-                       Offset += sizeof(SK_U64);
-                       break;
-
-               case OID_SKGE_RLMT_TX_SP_REQ_CTS:
-                       Val64 = pAC->Rlmt.Port[PhysPortIndex].TxSpHelloReqCts;
-                       SK_PNMI_STORE_U64(pBuf + Offset, Val64);
-                       Offset += sizeof(SK_U64);
-                       break;
-
-               case OID_SKGE_RLMT_RX_SP_CTS:
-                       Val64 = pAC->Rlmt.Port[PhysPortIndex].RxSpHelloCts;
-                       SK_PNMI_STORE_U64(pBuf + Offset, Val64);
-                       Offset += sizeof(SK_U64);
-                       break;
-
-               default:
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
-                               ("RlmtStat: Unknown OID should be errored before"));
-
-                       pAC->Pnmi.RlmtUpdatedFlag --;
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-       }
-       *pLen = Offset;
-
-       pAC->Pnmi.RlmtUpdatedFlag --;
-
-       return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * MacPrivateConf - OID handler function of OIDs concerning the configuration
- *
- * Description:
- *     Get/Presets/Sets the OIDs concerning the configuration.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
- *                              value range.
- *     SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                           exist (e.g. port instance 3 on a two port
- *                              adapter.
- */
-PNMI_STATIC int MacPrivateConf(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int Action,            /* GET/PRESET/SET action */
-SK_U32 Id,             /* Object ID that is to be processed */
-char *pBuf,            /* Buffer used for the management data transfer */
-unsigned int *pLen,    /* On call: pBuf buffer length. On return: used buffer */
-SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode always zero */
-{
-       unsigned int    PhysPortMax;
-       unsigned int    PhysPortIndex;
-       unsigned int    LogPortMax;
-       unsigned int    LogPortIndex;
-       unsigned int    Limit;
-       unsigned int    Offset;
-       char            Val8;
-       char            *pBufPtr;
-       int                     Ret;
-       SK_EVPARA       EventParam;
-       SK_U32          Val32;
-
-       /*
-        * Calculate instance if wished. MAC index 0 is the virtual MAC.
-        */
-       PhysPortMax = pAC->GIni.GIMacsFound;
-       LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
-
-       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
-               LogPortMax--;
-       }
-
-       if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
-               /* Check instance range */
-               if ((Instance < 1) || (Instance > LogPortMax)) {
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_UNKNOWN_INST);
-               }
-               LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
-               Limit = LogPortIndex + 1;
-       }
-
-       else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
-
-               LogPortIndex = 0;
-               Limit = LogPortMax;
-       }
-
-       /*
-        * Perform action
-        */
-       if (Action == SK_PNMI_GET) {
-
-               /* Check length */
-               switch (Id) {
-
-               case OID_SKGE_PMD:
-               case OID_SKGE_CONNECTOR:
-               case OID_SKGE_LINK_CAP:
-               case OID_SKGE_LINK_MODE:
-               case OID_SKGE_LINK_MODE_STATUS:
-               case OID_SKGE_LINK_STATUS:
-               case OID_SKGE_FLOWCTRL_CAP:
-               case OID_SKGE_FLOWCTRL_MODE:
-               case OID_SKGE_FLOWCTRL_STATUS:
-               case OID_SKGE_PHY_OPERATION_CAP:
-               case OID_SKGE_PHY_OPERATION_MODE:
-               case OID_SKGE_PHY_OPERATION_STATUS:
-               case OID_SKGE_SPEED_CAP:
-               case OID_SKGE_SPEED_MODE:
-               case OID_SKGE_SPEED_STATUS:
-                       if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) {
-
-                               *pLen = (Limit - LogPortIndex) * sizeof(SK_U8);
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-                       break;
-
-        case OID_SKGE_MTU:
-        case OID_SKGE_PHY_TYPE:
-                       if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U32)) {
-
-                               *pLen = (Limit - LogPortIndex) * sizeof(SK_U32);
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-                       break;
-
-               default:
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR041,
-                               SK_PNMI_ERR041MSG);
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-
-               /*
-                * Update statistic and increment semaphore to indicate
-                * that an update was already done.
-                */
-               if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
-
-                       *pLen = 0;
-                       return (Ret);
-               }
-               pAC->Pnmi.SirqUpdatedFlag ++;
-
-               /*
-                * Get value
-                */
-               Offset = 0;
-               for (; LogPortIndex < Limit; LogPortIndex ++) {
-
-                       pBufPtr = pBuf + Offset;
-                       
-                       switch (Id) {
-
-                       case OID_SKGE_PMD:
-                               *pBufPtr = pAC->Pnmi.PMD;
-                               Offset += sizeof(char);
-                               break;
-
-                       case OID_SKGE_CONNECTOR:
-                               *pBufPtr = pAC->Pnmi.Connector;
-                               Offset += sizeof(char);
-                               break;
-
-                       case OID_SKGE_PHY_TYPE:
-                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
-                                       if (LogPortIndex == 0) {
-                                               continue;
-                                       }
-                                       else {
-                                               /* Get value for physical ports */
-                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
-                                                       pAC, LogPortIndex);
-                                               Val32 = pAC->GIni.GP[PhysPortIndex].PhyType;
-                                               SK_PNMI_STORE_U32(pBufPtr, Val32);
-                                       }
-                               }
-                               else { /* DualNetMode */
-                                       
-                                       Val32 = pAC->GIni.GP[NetIndex].PhyType;
-                                       SK_PNMI_STORE_U32(pBufPtr, Val32);
-                               }
-                               Offset += sizeof(SK_U32);
-                               break;
-
-                       case OID_SKGE_LINK_CAP:
-                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
-                                       if (LogPortIndex == 0) {
-                                               /* Get value for virtual port */
-                                               VirtualConf(pAC, IoC, Id, pBufPtr);
-                                       }
-                                       else {
-                                               /* Get value for physical ports */
-                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
-                                                       pAC, LogPortIndex);
-
-                                               *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkCap;
-                                       }
-                               }
-                               else { /* DualNetMode */
-                                       
-                                       *pBufPtr = pAC->GIni.GP[NetIndex].PLinkCap;
-                               }
-                               Offset += sizeof(char);
-                               break;
-
-                       case OID_SKGE_LINK_MODE:
-                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
-                                       if (LogPortIndex == 0) {
-                                               /* Get value for virtual port */
-                                               VirtualConf(pAC, IoC, Id, pBufPtr);
-                                       }
-                                       else {
-                                               /* Get value for physical ports */
-                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
-                                                       pAC, LogPortIndex);
-
-                                               *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkModeConf;
-                                       }
-                               }
-                               else { /* DualNetMode */
-                               
-                                       *pBufPtr = pAC->GIni.GP[NetIndex].PLinkModeConf;
-                               }
-                               Offset += sizeof(char);
-                               break;
-
-                       case OID_SKGE_LINK_MODE_STATUS:
-                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
-                                       if (LogPortIndex == 0) {
-                                               /* Get value for virtual port */
-                                               VirtualConf(pAC, IoC, Id, pBufPtr);
-                                       }
-                                       else {
-                                               /* Get value for physical port */
-                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
-                                                       pAC, LogPortIndex);
-
-                                               *pBufPtr =
-                                                       CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
-                                       }
-                               }
-                               else { /* DualNetMode */
-                                       
-                                       *pBufPtr = CalculateLinkModeStatus(pAC, IoC, NetIndex);
-                               }
-                               Offset += sizeof(char);
-                               break;
-
-                       case OID_SKGE_LINK_STATUS:
-                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
-                                       if (LogPortIndex == 0) {
-                                               /* Get value for virtual port */
-                                               VirtualConf(pAC, IoC, Id, pBufPtr);
-                                       }
-                                       else {
-                                               /* Get value for physical ports */
-                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
-                                                       pAC, LogPortIndex);
-       
-                                               *pBufPtr = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
-                                       }
-                               }
-                               else { /* DualNetMode */
-
-                                       *pBufPtr = CalculateLinkStatus(pAC, IoC, NetIndex);
-                               }
-                               Offset += sizeof(char);
-                               break;
-
-                       case OID_SKGE_FLOWCTRL_CAP:
-                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
-                                       if (LogPortIndex == 0) {
-                                               /* Get value for virtual port */
-                                               VirtualConf(pAC, IoC, Id, pBufPtr);
-                                       }
-                                       else {
-                                               /* Get value for physical ports */
-                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
-                                                       pAC, LogPortIndex);
-       
-                                               *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap;
-                                       }
-                               }
-                               else { /* DualNetMode */
-                               
-                                       *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlCap;
-                               }
-                               Offset += sizeof(char);
-                               break;
-
-                       case OID_SKGE_FLOWCTRL_MODE:
-                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
-                                       if (LogPortIndex == 0) {
-                                               /* Get value for virtual port */
-                                               VirtualConf(pAC, IoC, Id, pBufPtr);
-                                       }
-                                       else {
-                                               /* Get value for physical port */
-                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
-                                                       pAC, LogPortIndex);
-       
-                                               *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode;
-                                       }
-                               }
-                               else { /* DualNetMode */
-
-                                       *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlMode;
-                               }
-                               Offset += sizeof(char);
-                               break;
-
-                       case OID_SKGE_FLOWCTRL_STATUS:
-                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
-                                       if (LogPortIndex == 0) {
-                                               /* Get value for virtual port */
-                                               VirtualConf(pAC, IoC, Id, pBufPtr);
-                                       }
-                                       else {
-                                               /* Get value for physical port */
-                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
-                                                       pAC, LogPortIndex);
-       
-                                               *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus;
-                                       }
-                               }
-                               else { /* DualNetMode */
-
-                                       *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlStatus;
-                               }
-                               Offset += sizeof(char);
-                               break;
-
-                       case OID_SKGE_PHY_OPERATION_CAP:
-                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
-                                       if (LogPortIndex == 0) {
-                                               /* Get value for virtual port */
-                                               VirtualConf(pAC, IoC, Id, pBufPtr);
-                                       }
-                                       else {
-                                               /* Get value for physical ports */
-                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
-                                                       pAC, LogPortIndex);
-       
-                                               *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSCap;
-                                       }
-                               }
-                               else { /* DualNetMode */
-                               
-                                       *pBufPtr = pAC->GIni.GP[NetIndex].PMSCap;
-                               }
-                               Offset += sizeof(char);
-                               break;
-
-                       case OID_SKGE_PHY_OPERATION_MODE:
-                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
-                                       if (LogPortIndex == 0) {
-                                               /* Get value for virtual port */
-                                               VirtualConf(pAC, IoC, Id, pBufPtr);
-                                       }
-                                       else {
-                                               /* Get value for physical port */
-                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
-                                                       pAC, LogPortIndex);
-
-                                               *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSMode;
-                                       }
-                               }
-                               else { /* DualNetMode */
-                               
-                                       *pBufPtr = pAC->GIni.GP[NetIndex].PMSMode;
-                               }
-                               Offset += sizeof(char);
-                               break;
-
-                       case OID_SKGE_PHY_OPERATION_STATUS:
-                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
-                                       if (LogPortIndex == 0) {
-                                               /* Get value for virtual port */
-                                               VirtualConf(pAC, IoC, Id, pBufPtr);
-                                       }
-                                       else {
-                                               /* Get value for physical port */
-                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
-                                                       pAC, LogPortIndex);
-       
-                                               *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSStatus;
-                                       }
-                               }
-                               else {
-                               
-                                       *pBufPtr = pAC->GIni.GP[NetIndex].PMSStatus;
-                               }
-                               Offset += sizeof(char);
-                               break;
-
-                       case OID_SKGE_SPEED_CAP:
-                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
-                                       if (LogPortIndex == 0) {
-                                               /* Get value for virtual port */
-                                               VirtualConf(pAC, IoC, Id, pBufPtr);
-                                       }
-                                       else {
-                                               /* Get value for physical ports */
-                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
-                                                       pAC, LogPortIndex);
-       
-                                               *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedCap;
-                                       }
-                               }
-                               else { /* DualNetMode */
-                               
-                                       *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedCap;
-                               }
-                               Offset += sizeof(char);
-                               break;
-
-                       case OID_SKGE_SPEED_MODE:
-                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
-                                       if (LogPortIndex == 0) {
-                                               /* Get value for virtual port */
-                                               VirtualConf(pAC, IoC, Id, pBufPtr);
-                                       }
-                                       else {
-                                               /* Get value for physical port */
-                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
-                                                       pAC, LogPortIndex);
-       
-                                               *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeed;
-                                       }
-                               }
-                               else { /* DualNetMode */
-
-                                       *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeed;
-                               }
-                               Offset += sizeof(char);
-                               break;
-
-                       case OID_SKGE_SPEED_STATUS:
-                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
-                                       if (LogPortIndex == 0) {
-                                               /* Get value for virtual port */
-                                               VirtualConf(pAC, IoC, Id, pBufPtr);
-                                       }
-                                       else {
-                                               /* Get value for physical port */
-                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
-                                                       pAC, LogPortIndex);
-       
-                                               *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed;
-                                       }
-                               }
-                               else { /* DualNetMode */
-
-                                       *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedUsed;
-                               }
-                               Offset += sizeof(char);
-                               break;
-                       
-                       case OID_SKGE_MTU:
-                               Val32 = SK_DRIVER_GET_MTU(pAC, IoC, NetIndex);
-                               SK_PNMI_STORE_U32(pBufPtr, Val32);
-                               Offset += sizeof(SK_U32);
-                               break;
-
-                       default:
-                               SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
-                                       ("MacPrivateConf: Unknown OID should be handled before"));
-
-                               pAC->Pnmi.SirqUpdatedFlag --;
-                               return (SK_PNMI_ERR_GENERAL);
-                       }
-               }
-               *pLen = Offset;
-               pAC->Pnmi.SirqUpdatedFlag --;
-
-               return (SK_PNMI_ERR_OK);
-       }
-
-       /*
-        * From here SET or PRESET action. Check if the passed
-        * buffer length is plausible.
-        */
-       switch (Id) {
-
-       case OID_SKGE_LINK_MODE:
-       case OID_SKGE_FLOWCTRL_MODE:
-       case OID_SKGE_PHY_OPERATION_MODE:
-       case OID_SKGE_SPEED_MODE:
-               if (*pLen < Limit - LogPortIndex) {
-
-                       *pLen = Limit - LogPortIndex;
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               if (*pLen != Limit - LogPortIndex) {
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_BAD_VALUE);
-               }
-               break;
-
-       case OID_SKGE_MTU:
-               if (*pLen < sizeof(SK_U32)) {
-
-                       *pLen = sizeof(SK_U32);
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               if (*pLen != sizeof(SK_U32)) {
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_BAD_VALUE);
-               }
-               break;
-
-    default:
-               *pLen = 0;
-               return (SK_PNMI_ERR_READ_ONLY);
-       }
-
-       /*
-        * Perform preset or set
-        */
-       Offset = 0;
-       for (; LogPortIndex < Limit; LogPortIndex ++) {
-
-               switch (Id) {
-
-               case OID_SKGE_LINK_MODE:
-                       /* Check the value range */
-                       Val8 = *(pBuf + Offset);
-                       if (Val8 == 0) {
-
-                               Offset += sizeof(char);
-                               break;
-                       }
-                       if (Val8 < SK_LMODE_HALF ||
-                               (LogPortIndex != 0 && Val8 > SK_LMODE_AUTOSENSE) ||
-                               (LogPortIndex == 0 && Val8 > SK_LMODE_INDETERMINATED)) {
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_BAD_VALUE);
-                       }
-
-                       /* The preset ends here */
-                       if (Action == SK_PNMI_PRESET) {
-
-                               return (SK_PNMI_ERR_OK);
-                       }
-
-                       if (LogPortIndex == 0) {
-
-                               /*
-                                * The virtual port consists of all currently
-                                * active ports. Find them and send an event
-                                * with the new link mode to SIRQ.
-                                */
-                               for (PhysPortIndex = 0;
-                                       PhysPortIndex < PhysPortMax;
-                                       PhysPortIndex ++) {
-
-                                       if (!pAC->Pnmi.Port[PhysPortIndex].
-                                               ActiveFlag) {
-
-                                               continue;
-                                       }
-
-                                       EventParam.Para32[0] = PhysPortIndex;
-                                       EventParam.Para32[1] = (SK_U32)Val8;
-                                       if (SkGeSirqEvent(pAC, IoC,
-                                               SK_HWEV_SET_LMODE,
-                                               EventParam) > 0) {
-
-                                               SK_ERR_LOG(pAC, SK_ERRCL_SW,
-                                                       SK_PNMI_ERR043,
-                                                       SK_PNMI_ERR043MSG);
-
-                                               *pLen = 0;
-                                               return (SK_PNMI_ERR_GENERAL);
-                                       }
-                               }
-                       }
-                       else {
-                               /*
-                                * Send an event with the new link mode to
-                                * the SIRQ module.
-                                */
-                               EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
-                                       pAC, LogPortIndex);
-                               EventParam.Para32[1] = (SK_U32)Val8;
-                               if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_LMODE,
-                                       EventParam) > 0) {
-
-                                       SK_ERR_LOG(pAC, SK_ERRCL_SW,
-                                               SK_PNMI_ERR043,
-                                               SK_PNMI_ERR043MSG);
-
-                                       *pLen = 0;
-                                       return (SK_PNMI_ERR_GENERAL);
-                               }
-                       }
-                       Offset += sizeof(char);
-                       break;
-
-               case OID_SKGE_FLOWCTRL_MODE:
-                       /* Check the value range */
-                       Val8 = *(pBuf + Offset);
-                       if (Val8 == 0) {
-
-                               Offset += sizeof(char);
-                               break;
-                       }
-                       if (Val8 < SK_FLOW_MODE_NONE ||
-                               (LogPortIndex != 0 && Val8 > SK_FLOW_MODE_SYM_OR_REM) ||
-                               (LogPortIndex == 0 && Val8 > SK_FLOW_MODE_INDETERMINATED)) {
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_BAD_VALUE);
-                       }
-
-                       /* The preset ends here */
-                       if (Action == SK_PNMI_PRESET) {
-
-                               return (SK_PNMI_ERR_OK);
-                       }
-
-                       if (LogPortIndex == 0) {
-
-                               /*
-                                * The virtual port consists of all currently
-                                * active ports. Find them and send an event
-                                * with the new flow control mode to SIRQ.
-                                */
-                               for (PhysPortIndex = 0;
-                                       PhysPortIndex < PhysPortMax;
-                                       PhysPortIndex ++) {
-
-                                       if (!pAC->Pnmi.Port[PhysPortIndex].
-                                               ActiveFlag) {
-
-                                               continue;
-                                       }
-
-                                       EventParam.Para32[0] = PhysPortIndex;
-                                       EventParam.Para32[1] = (SK_U32)Val8;
-                                       if (SkGeSirqEvent(pAC, IoC,
-                                               SK_HWEV_SET_FLOWMODE,
-                                               EventParam) > 0) {
-
-                                               SK_ERR_LOG(pAC, SK_ERRCL_SW,
-                                                       SK_PNMI_ERR044,
-                                                       SK_PNMI_ERR044MSG);
-
-                                               *pLen = 0;
-                                               return (SK_PNMI_ERR_GENERAL);
-                                       }
-                               }
-                       }
-                       else {
-                               /*
-                                * Send an event with the new flow control
-                                * mode to the SIRQ module.
-                                */
-                               EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
-                                       pAC, LogPortIndex);
-                               EventParam.Para32[1] = (SK_U32)Val8;
-                               if (SkGeSirqEvent(pAC, IoC,
-                                       SK_HWEV_SET_FLOWMODE, EventParam)
-                                       > 0) {
-
-                                       SK_ERR_LOG(pAC, SK_ERRCL_SW,
-                                               SK_PNMI_ERR044,
-                                               SK_PNMI_ERR044MSG);
-
-                                       *pLen = 0;
-                                       return (SK_PNMI_ERR_GENERAL);
-                               }
-                       }
-                       Offset += sizeof(char);
-                       break;
-
-               case OID_SKGE_PHY_OPERATION_MODE :
-                       /* Check the value range */
-                       Val8 = *(pBuf + Offset);
-                       if (Val8 == 0) {
-                               /* mode of this port remains unchanged */
-                               Offset += sizeof(char);
-                               break;
-                       }
-                       if (Val8 < SK_MS_MODE_AUTO ||
-                               (LogPortIndex != 0 && Val8 > SK_MS_MODE_SLAVE) ||
-                               (LogPortIndex == 0 && Val8 > SK_MS_MODE_INDETERMINATED)) {
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_BAD_VALUE);
-                       }
-
-                       /* The preset ends here */
-                       if (Action == SK_PNMI_PRESET) {
-
-                               return (SK_PNMI_ERR_OK);
-                       }
-
-                       if (LogPortIndex == 0) {
-
-                               /*
-                                * The virtual port consists of all currently
-                                * active ports. Find them and send an event
-                                * with new master/slave (role) mode to SIRQ.
-                                */
-                               for (PhysPortIndex = 0;
-                                       PhysPortIndex < PhysPortMax;
-                                       PhysPortIndex ++) {
-
-                                       if (!pAC->Pnmi.Port[PhysPortIndex].
-                                               ActiveFlag) {
-
-                                               continue;
-                                       }
-
-                                       EventParam.Para32[0] = PhysPortIndex;
-                                       EventParam.Para32[1] = (SK_U32)Val8;
-                                       if (SkGeSirqEvent(pAC, IoC,
-                                               SK_HWEV_SET_ROLE,
-                                               EventParam) > 0) {
-
-                                               SK_ERR_LOG(pAC, SK_ERRCL_SW,
-                                                       SK_PNMI_ERR042,
-                                                       SK_PNMI_ERR042MSG);
-
-                                               *pLen = 0;
-                                               return (SK_PNMI_ERR_GENERAL);
-                                       }
-                               }
-                       }
-                       else {
-                               /*
-                                * Send an event with the new master/slave
-                                * (role) mode to the SIRQ module.
-                                */
-                               EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
-                                       pAC, LogPortIndex);
-                               EventParam.Para32[1] = (SK_U32)Val8;
-                               if (SkGeSirqEvent(pAC, IoC,
-                                       SK_HWEV_SET_ROLE, EventParam) > 0) {
-
-                                       SK_ERR_LOG(pAC, SK_ERRCL_SW,
-                                               SK_PNMI_ERR042,
-                                               SK_PNMI_ERR042MSG);
-
-                                       *pLen = 0;
-                                       return (SK_PNMI_ERR_GENERAL);
-                               }
-                       }
-
-                       Offset += sizeof(char);
-                       break;
-
-               case OID_SKGE_SPEED_MODE:
-                       /* Check the value range */
-                       Val8 = *(pBuf + Offset);
-                       if (Val8 == 0) {
-
-                               Offset += sizeof(char);
-                               break;
-                       }
-                       if (Val8 < (SK_LSPEED_AUTO) ||
-                               (LogPortIndex != 0 && Val8 > (SK_LSPEED_1000MBPS)) ||
-                               (LogPortIndex == 0 && Val8 > (SK_LSPEED_INDETERMINATED))) {
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_BAD_VALUE);
-                       }
-
-                       /* The preset ends here */
-                       if (Action == SK_PNMI_PRESET) {
-
-                               return (SK_PNMI_ERR_OK);
-                       }
-
-                       if (LogPortIndex == 0) {
-
-                               /*
-                                * The virtual port consists of all currently
-                                * active ports. Find them and send an event
-                                * with the new flow control mode to SIRQ.
-                                */
-                               for (PhysPortIndex = 0;
-                                       PhysPortIndex < PhysPortMax;
-                                       PhysPortIndex ++) {
-
-                                       if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
-
-                                               continue;
-                                       }
-
-                                       EventParam.Para32[0] = PhysPortIndex;
-                                       EventParam.Para32[1] = (SK_U32)Val8;
-                                       if (SkGeSirqEvent(pAC, IoC,
-                                               SK_HWEV_SET_SPEED,
-                                               EventParam) > 0) {
-
-                                               SK_ERR_LOG(pAC, SK_ERRCL_SW,
-                                                       SK_PNMI_ERR045,
-                                                       SK_PNMI_ERR045MSG);
-
-                                               *pLen = 0;
-                                               return (SK_PNMI_ERR_GENERAL);
-                                       }
-                               }
-                       }
-                       else {
-                               /*
-                                * Send an event with the new flow control
-                                * mode to the SIRQ module.
-                                */
-                               EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
-                                       pAC, LogPortIndex);
-                               EventParam.Para32[1] = (SK_U32)Val8;
-                               if (SkGeSirqEvent(pAC, IoC,
-                                       SK_HWEV_SET_SPEED,
-                                       EventParam) > 0) {
-
-                                       SK_ERR_LOG(pAC, SK_ERRCL_SW,
-                                               SK_PNMI_ERR045,
-                                               SK_PNMI_ERR045MSG);
-
-                                       *pLen = 0;
-                                       return (SK_PNMI_ERR_GENERAL);
-                               }
-                       }
-                       Offset += sizeof(char);
-                       break;
-
-               case OID_SKGE_MTU :
-                       /* Check the value range */
-                       Val32 = *(SK_U32*)(pBuf + Offset);
-                       if (Val32 == 0) {
-                               /* mtu of this port remains unchanged */
-                               Offset += sizeof(SK_U32);
-                               break;
-                       }
-                       if (SK_DRIVER_PRESET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_BAD_VALUE);
-                       }
-
-                       /* The preset ends here */
-                       if (Action == SK_PNMI_PRESET) {
-                               return (SK_PNMI_ERR_OK);
-                       }
-
-                       if (SK_DRIVER_SET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
-                               return (SK_PNMI_ERR_GENERAL);
-                       }
-
-                       Offset += sizeof(SK_U32);
-                       break;
-               
-               default:
-            SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
-                ("MacPrivateConf: Unknown OID should be handled before set"));
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-       }
-
-       return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * Monitor - OID handler function for RLMT_MONITOR_XXX
- *
- * Description:
- *     Because RLMT currently does not support the monitoring of
- *     remote adapter cards, we return always an empty table.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
- *                              value range.
- *     SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                           exist (e.g. port instance 3 on a two port
- *                              adapter.
- */
-PNMI_STATIC int Monitor(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int Action,            /* GET/PRESET/SET action */
-SK_U32 Id,             /* Object ID that is to be processed */
-char *pBuf,            /* Buffer used for the management data transfer */
-unsigned int *pLen,    /* On call: pBuf buffer length. On return: used buffer */
-SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode always zero */
-{
-       unsigned int    Index;
-       unsigned int    Limit;
-       unsigned int    Offset;
-       unsigned int    Entries;
-
-       
-       /*
-        * Calculate instance if wished.
-        */
-       /* XXX Not yet implemented. Return always an empty table. */
-       Entries = 0;
-
-       if ((Instance != (SK_U32)(-1))) {
-
-               if ((Instance < 1) || (Instance > Entries)) {
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_UNKNOWN_INST);
-               }
-
-               Index = (unsigned int)Instance - 1;
-               Limit = (unsigned int)Instance;
-       }
-       else {
-               Index = 0;
-               Limit = Entries;
-       }
-
-       /*
-        * Get/Set value
-       */
-       if (Action == SK_PNMI_GET) {
-
-               for (Offset=0; Index < Limit; Index ++) {
-
-                       switch (Id) {
-
-                       case OID_SKGE_RLMT_MONITOR_INDEX:
-                       case OID_SKGE_RLMT_MONITOR_ADDR:
-                       case OID_SKGE_RLMT_MONITOR_ERRS:
-                       case OID_SKGE_RLMT_MONITOR_TIMESTAMP:
-                       case OID_SKGE_RLMT_MONITOR_ADMIN:
-                               break;
-
-                       default:
-                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR046,
-                                       SK_PNMI_ERR046MSG);
-
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_GENERAL);
-                       }
-               }
-               *pLen = Offset;
-       }
-       else {
-               /* Only MONITOR_ADMIN can be set */
-               if (Id != OID_SKGE_RLMT_MONITOR_ADMIN) {
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_READ_ONLY);
-               }
-
-               /* Check if the length is plausible */
-               if (*pLen < (Limit - Index)) {
-
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               /* Okay, we have a wide value range */
-               if (*pLen != (Limit - Index)) {
-
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_BAD_VALUE);
-               }
-/*
-               for (Offset=0; Index < Limit; Index ++) {
-               }
-*/
-/*
- * XXX Not yet implemented. Return always BAD_VALUE, because the table
- * is empty.
- */
-               *pLen = 0;
-               return (SK_PNMI_ERR_BAD_VALUE);
-       }
-
-       return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * VirtualConf - Calculates the values of configuration OIDs for virtual port
- *
- * Description:
- *     We handle here the get of the configuration group OIDs, which are
- *     a little bit complicated. The virtual port consists of all currently
- *     active physical ports. If multiple ports are active and configured
- *     differently we get in some trouble to return a single value. So we
- *     get the value of the first active port and compare it with that of
- *     the other active ports. If they are not the same, we return a value
- *     that indicates that the state is indeterminated.
- *
- * Returns:
- *     Nothing
- */
-PNMI_STATIC void VirtualConf(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-SK_U32 Id,             /* Object ID that is to be processed */
-char *pBuf)            /* Buffer used for the management data transfer */
-{
-       unsigned int    PhysPortMax;
-       unsigned int    PhysPortIndex;
-       SK_U8           Val8;
-       SK_U32          Val32;
-       SK_BOOL         PortActiveFlag;
-       SK_GEPORT       *pPrt;
-
-       *pBuf = 0;
-       PortActiveFlag = SK_FALSE;
-       PhysPortMax = pAC->GIni.GIMacsFound;
-       
-       for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
-               PhysPortIndex ++) {
-
-               pPrt = &pAC->GIni.GP[PhysPortIndex];
-
-               /* Check if the physical port is active */
-               if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
-
-                       continue;
-               }
-
-               PortActiveFlag = SK_TRUE;
-
-               switch (Id) {
-
-               case OID_SKGE_PHY_TYPE:
-                       /* Check if it is the first active port */
-                       if (*pBuf == 0) {
-                               Val32 = pPrt->PhyType;
-                               SK_PNMI_STORE_U32(pBuf, Val32);
-                               continue;
-                       }
-
-               case OID_SKGE_LINK_CAP:
-
-                       /*
-                        * Different capabilities should not happen, but
-                        * in the case of the cases OR them all together.
-                        * From a curious point of view the virtual port
-                        * is capable of all found capabilities.
-                        */
-                       *pBuf |= pPrt->PLinkCap;
-                       break;
-
-               case OID_SKGE_LINK_MODE:
-                       /* Check if it is the first active port */
-                       if (*pBuf == 0) {
-
-                               *pBuf = pPrt->PLinkModeConf;
-                               continue;
-                       }
-
-                       /*
-                        * If we find an active port with a different link
-                        * mode than the first one we return a value that
-                        * indicates that the link mode is indeterminated.
-                        */
-                       if (*pBuf != pPrt->PLinkModeConf) {
-
-                               *pBuf = SK_LMODE_INDETERMINATED;
-                       }
-                       break;
-
-               case OID_SKGE_LINK_MODE_STATUS:
-                       /* Get the link mode of the physical port */
-                       Val8 = CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
-
-                       /* Check if it is the first active port */
-                       if (*pBuf == 0) {
-
-                               *pBuf = Val8;
-                               continue;
-                       }
-
-                       /*
-                        * If we find an active port with a different link
-                        * mode status than the first one we return a value
-                        * that indicates that the link mode status is
-                        * indeterminated.
-                        */
-                       if (*pBuf != Val8) {
-
-                               *pBuf = SK_LMODE_STAT_INDETERMINATED;
-                       }
-                       break;
-
-               case OID_SKGE_LINK_STATUS:
-                       /* Get the link status of the physical port */
-                       Val8 = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
-
-                       /* Check if it is the first active port */
-                       if (*pBuf == 0) {
-
-                               *pBuf = Val8;
-                               continue;
-                       }
-
-                       /*
-                        * If we find an active port with a different link
-                        * status than the first one, we return a value
-                        * that indicates that the link status is
-                        * indeterminated.
-                        */
-                       if (*pBuf != Val8) {
-
-                               *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
-                       }
-                       break;
-
-               case OID_SKGE_FLOWCTRL_CAP:
-                       /* Check if it is the first active port */
-                       if (*pBuf == 0) {
-
-                               *pBuf = pPrt->PFlowCtrlCap;
-                               continue;
-                       }
-
-                       /*
-                        * From a curious point of view the virtual port
-                        * is capable of all found capabilities.
-                        */
-                       *pBuf |= pPrt->PFlowCtrlCap;
-                       break;
-
-               case OID_SKGE_FLOWCTRL_MODE:
-                       /* Check if it is the first active port */
-                       if (*pBuf == 0) {
-
-                               *pBuf = pPrt->PFlowCtrlMode;
-                               continue;
-                       }
-
-                       /*
-                        * If we find an active port with a different flow
-                        * control mode than the first one, we return a value
-                        * that indicates that the mode is indeterminated.
-                        */
-                       if (*pBuf != pPrt->PFlowCtrlMode) {
-
-                               *pBuf = SK_FLOW_MODE_INDETERMINATED;
-                       }
-                       break;
-
-               case OID_SKGE_FLOWCTRL_STATUS:
-                       /* Check if it is the first active port */
-                       if (*pBuf == 0) {
-
-                               *pBuf = pPrt->PFlowCtrlStatus;
-                               continue;
-                       }
-
-                       /*
-                        * If we find an active port with a different flow
-                        * control status than the first one, we return a
-                        * value that indicates that the status is
-                        * indeterminated.
-                        */
-                       if (*pBuf != pPrt->PFlowCtrlStatus) {
-
-                               *pBuf = SK_FLOW_STAT_INDETERMINATED;
-                       }
-                       break;
-               
-               case OID_SKGE_PHY_OPERATION_CAP:
-                       /* Check if it is the first active port */
-                       if (*pBuf == 0) {
-
-                               *pBuf = pPrt->PMSCap;
-                               continue;
-                       }
-
-                       /*
-                        * From a curious point of view the virtual port
-                        * is capable of all found capabilities.
-                        */
-                       *pBuf |= pPrt->PMSCap;
-                       break;
-
-               case OID_SKGE_PHY_OPERATION_MODE:
-                       /* Check if it is the first active port */
-                       if (*pBuf == 0) {
-
-                               *pBuf = pPrt->PMSMode;
-                               continue;
-                       }
-
-                       /*
-                        * If we find an active port with a different master/
-                        * slave mode than the first one, we return a value
-                        * that indicates that the mode is indeterminated.
-                        */
-                       if (*pBuf != pPrt->PMSMode) {
-
-                               *pBuf = SK_MS_MODE_INDETERMINATED;
-                       }
-                       break;
-
-               case OID_SKGE_PHY_OPERATION_STATUS:
-                       /* Check if it is the first active port */
-                       if (*pBuf == 0) {
-
-                               *pBuf = pPrt->PMSStatus;
-                               continue;
-                       }
-
-                       /*
-                        * If we find an active port with a different master/
-                        * slave status than the first one, we return a
-                        * value that indicates that the status is
-                        * indeterminated.
-                        */
-                       if (*pBuf != pPrt->PMSStatus) {
-
-                               *pBuf = SK_MS_STAT_INDETERMINATED;
-                       }
-                       break;
-               
-               case OID_SKGE_SPEED_MODE:
-                       /* Check if it is the first active port */
-                       if (*pBuf == 0) {
-
-                               *pBuf = pPrt->PLinkSpeed;
-                               continue;
-                       }
-
-                       /*
-                        * If we find an active port with a different flow
-                        * control mode than the first one, we return a value
-                        * that indicates that the mode is indeterminated.
-                        */
-                       if (*pBuf != pPrt->PLinkSpeed) {
-
-                               *pBuf = SK_LSPEED_INDETERMINATED;
-                       }
-                       break;
-               
-               case OID_SKGE_SPEED_STATUS:
-                       /* Check if it is the first active port */
-                       if (*pBuf == 0) {
-
-                               *pBuf = pPrt->PLinkSpeedUsed;
-                               continue;
-                       }
-
-                       /*
-                        * If we find an active port with a different flow
-                        * control status than the first one, we return a
-                        * value that indicates that the status is
-                        * indeterminated.
-                        */
-                       if (*pBuf != pPrt->PLinkSpeedUsed) {
-
-                               *pBuf = SK_LSPEED_STAT_INDETERMINATED;
-                       }
-                       break;
-               }
-       }
-
-       /*
-        * If no port is active return an indeterminated answer
-        */
-       if (!PortActiveFlag) {
-
-               switch (Id) {
-
-               case OID_SKGE_LINK_CAP:
-                       *pBuf = SK_LMODE_CAP_INDETERMINATED;
-                       break;
-
-               case OID_SKGE_LINK_MODE:
-                       *pBuf = SK_LMODE_INDETERMINATED;
-                       break;
-
-               case OID_SKGE_LINK_MODE_STATUS:
-                       *pBuf = SK_LMODE_STAT_INDETERMINATED;
-                       break;
-
-               case OID_SKGE_LINK_STATUS:
-                       *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
-                       break;
-
-               case OID_SKGE_FLOWCTRL_CAP:
-               case OID_SKGE_FLOWCTRL_MODE:
-                       *pBuf = SK_FLOW_MODE_INDETERMINATED;
-                       break;
-
-               case OID_SKGE_FLOWCTRL_STATUS:
-                       *pBuf = SK_FLOW_STAT_INDETERMINATED;
-                       break;
-                       
-               case OID_SKGE_PHY_OPERATION_CAP:
-                       *pBuf = SK_MS_CAP_INDETERMINATED;
-                       break;
-
-               case OID_SKGE_PHY_OPERATION_MODE:
-                       *pBuf = SK_MS_MODE_INDETERMINATED;
-                       break;
-
-               case OID_SKGE_PHY_OPERATION_STATUS:
-                       *pBuf = SK_MS_STAT_INDETERMINATED;
-                       break;
-               case OID_SKGE_SPEED_CAP:
-                       *pBuf = SK_LSPEED_CAP_INDETERMINATED;
-                       break;
-
-               case OID_SKGE_SPEED_MODE:
-                       *pBuf = SK_LSPEED_INDETERMINATED;
-                       break;
-
-               case OID_SKGE_SPEED_STATUS:
-                       *pBuf = SK_LSPEED_STAT_INDETERMINATED;
-                       break;
-               }
-       }
-}
-
-/*****************************************************************************
- *
- * CalculateLinkStatus - Determins the link status of a physical port
- *
- * Description:
- *     Determins the link status the following way:
- *       LSTAT_PHY_DOWN:  Link is down
- *       LSTAT_AUTONEG:   Auto-negotiation failed
- *       LSTAT_LOG_DOWN:  Link is up but RLMT did not yet put the port
- *                        logically up.
- *       LSTAT_LOG_UP:    RLMT marked the port as up
- *
- * Returns:
- *     Link status of physical port
- */
-PNMI_STATIC SK_U8 CalculateLinkStatus(
-SK_AC *pAC,                    /* Pointer to adapter context */
-SK_IOC IoC,                    /* IO context handle */
-unsigned int PhysPortIndex)    /* Physical port index */
-{
-       SK_U8   Result;
-
-       if (!pAC->GIni.GP[PhysPortIndex].PHWLinkUp) {
-
-               Result = SK_PNMI_RLMT_LSTAT_PHY_DOWN;
-       }
-       else if (pAC->GIni.GP[PhysPortIndex].PAutoNegFail > 0) {
-
-               Result = SK_PNMI_RLMT_LSTAT_AUTONEG;
-                               }
-       else if (!pAC->Rlmt.Port[PhysPortIndex].PortDown) {
-
-               Result = SK_PNMI_RLMT_LSTAT_LOG_UP;
-       }
-       else {
-               Result = SK_PNMI_RLMT_LSTAT_LOG_DOWN;
-       }
-
-       return (Result);
-}
-
-/*****************************************************************************
- *
- * CalculateLinkModeStatus - Determins the link mode status of a phys. port
- *
- * Description:
- *     The COMMON module only tells us if the mode is half or full duplex.
- *     But in the decade of auto sensing it is useful for the user to
- *     know if the mode was negotiated or forced. Therefore we have a
- *     look to the mode, which was last used by the negotiation process.
- *
- * Returns:
- *     The link mode status
- */
-PNMI_STATIC SK_U8 CalculateLinkModeStatus(
-SK_AC *pAC,                    /* Pointer to adapter context */
-SK_IOC IoC,                    /* IO context handle */
-unsigned int PhysPortIndex)    /* Physical port index */
-{
-       SK_U8   Result;
-
-       /* Get the current mode, which can be full or half duplex */
-       Result = pAC->GIni.GP[PhysPortIndex].PLinkModeStatus;
-
-       /* Check if no valid mode could be found (link is down) */
-       if (Result < SK_LMODE_STAT_HALF) {
-
-               Result = SK_LMODE_STAT_UNKNOWN;
-       }
-       else if (pAC->GIni.GP[PhysPortIndex].PLinkMode >= SK_LMODE_AUTOHALF) {
-
-               /*
-                * Auto-negotiation was used to bring up the link. Change
-                * the already found duplex status that it indicates
-                * auto-negotiation was involved.
-                */
-               if (Result == SK_LMODE_STAT_HALF) {
-
-                       Result = SK_LMODE_STAT_AUTOHALF;
-               }
-               else if (Result == SK_LMODE_STAT_FULL) {
-
-                       Result = SK_LMODE_STAT_AUTOFULL;
-               }
-       }
-
-       return (Result);
-}
-
-/*****************************************************************************
- *
- * GetVpdKeyArr - Obtain an array of VPD keys
- *
- * Description:
- *     Read the VPD keys and build an array of VPD keys, which are
- *     easy to access.
- *
- * Returns:
- *     SK_PNMI_ERR_OK       Task successfully performed.
- *     SK_PNMI_ERR_GENERAL  Something went wrong.
- */
-PNMI_STATIC int GetVpdKeyArr(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-char *pKeyArr,         /* Ptr KeyArray */
-unsigned int KeyArrLen,        /* Length of array in bytes */
-unsigned int *pKeyNo)  /* Number of keys */
-{
-       unsigned int            BufKeysLen = SK_PNMI_VPD_BUFSIZE;
-       char                    BufKeys[SK_PNMI_VPD_BUFSIZE];
-       unsigned int            StartOffset;
-       unsigned int            Offset;
-       int                     Index;
-       int                     Ret;
-
-
-       SK_MEMSET(pKeyArr, 0, KeyArrLen);
-
-       /*
-        * Get VPD key list
-        */
-       Ret = VpdKeys(pAC, IoC, (char *)&BufKeys, (int *)&BufKeysLen,
-               (int *)pKeyNo);
-       if (Ret > 0) {
-
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR014,
-                       SK_PNMI_ERR014MSG);
-
-               return (SK_PNMI_ERR_GENERAL);
-       }
-       /* If no keys are available return now */
-       if (*pKeyNo == 0 || BufKeysLen == 0) {
-
-               return (SK_PNMI_ERR_OK);
-       }
-       /*
-        * If the key list is too long for us trunc it and give a
-        * errorlog notification. This case should not happen because
-        * the maximum number of keys is limited due to RAM limitations
-        */
-       if (*pKeyNo > SK_PNMI_VPD_ENTRIES) {
-
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR015,
-                       SK_PNMI_ERR015MSG);
-
-               *pKeyNo = SK_PNMI_VPD_ENTRIES;
-       }
-
-       /*
-        * Now build an array of fixed string length size and copy
-        * the keys together.
-        */
-       for (Index = 0, StartOffset = 0, Offset = 0; Offset < BufKeysLen;
-               Offset ++) {
-
-               if (BufKeys[Offset] != 0) {
-
-                       continue;
-               }
-
-               if (Offset - StartOffset > SK_PNMI_VPD_KEY_SIZE) {
-
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR016,
-                               SK_PNMI_ERR016MSG);
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-
-               SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
-                       &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
-
-               Index ++;
-               StartOffset = Offset + 1;
-       }
-
-       /* Last key not zero terminated? Get it anyway */
-       if (StartOffset < Offset) {
-
-               SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
-                       &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
-       }
-
-       return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * SirqUpdate - Let the SIRQ update its internal values
- *
- * Description:
- *     Just to be sure that the SIRQ module holds its internal data
- *     structures up to date, we send an update event before we make
- *     any access.
- *
- * Returns:
- *     SK_PNMI_ERR_OK       Task successfully performed.
- *     SK_PNMI_ERR_GENERAL  Something went wrong.
- */
-PNMI_STATIC int SirqUpdate(
-SK_AC *pAC,    /* Pointer to adapter context */
-SK_IOC IoC)    /* IO context handle */
-{
-       SK_EVPARA       EventParam;
-
-
-       /* Was the module already updated during the current PNMI call? */
-       if (pAC->Pnmi.SirqUpdatedFlag > 0) {
-
-               return (SK_PNMI_ERR_OK);
-       }
-
-       /* Send an synchronuous update event to the module */
-       SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
-       if (SkGeSirqEvent(pAC, IoC, SK_HWEV_UPDATE_STAT, EventParam) > 0) {
-
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR047,
-                       SK_PNMI_ERR047MSG);
-
-               return (SK_PNMI_ERR_GENERAL);
-       }
-
-       return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * RlmtUpdate - Let the RLMT update its internal values
- *
- * Description:
- *     Just to be sure that the RLMT module holds its internal data
- *     structures up to date, we send an update event before we make
- *     any access.
- *
- * Returns:
- *     SK_PNMI_ERR_OK       Task successfully performed.
- *     SK_PNMI_ERR_GENERAL  Something went wrong.
- */
-PNMI_STATIC int RlmtUpdate(
-SK_AC *pAC,    /* Pointer to adapter context */
-SK_IOC IoC,    /* IO context handle */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
-{
-       SK_EVPARA       EventParam;
-
-
-       /* Was the module already updated during the current PNMI call? */
-       if (pAC->Pnmi.RlmtUpdatedFlag > 0) {
-
-               return (SK_PNMI_ERR_OK);
-       }
-
-       /* Send an synchronuous update event to the module */
-       SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
-       EventParam.Para32[0] = NetIndex;
-       EventParam.Para32[1] = (SK_U32)-1;
-       if (SkRlmtEvent(pAC, IoC, SK_RLMT_STATS_UPDATE, EventParam) > 0) {
-
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR048,
-                       SK_PNMI_ERR048MSG);
-
-               return (SK_PNMI_ERR_GENERAL);
-       }
-
-       return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * MacUpdate - Force the XMAC to output the current statistic
- *
- * Description:
- *     The XMAC holds its statistic internally. To obtain the current
- *     values we must send a command so that the statistic data will
- *     be written to a predefined memory area on the adapter.
- *
- * Returns:
- *     SK_PNMI_ERR_OK       Task successfully performed.
- *     SK_PNMI_ERR_GENERAL  Something went wrong.
- */
-PNMI_STATIC int MacUpdate(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-unsigned int FirstMac, /* Index of the first Mac to be updated */
-unsigned int LastMac)  /* Index of the last Mac to be updated */
-{
-       unsigned int    MacIndex;
-
-       /*
-        * Were the statistics already updated during the
-        * current PNMI call?
-        */
-       if (pAC->Pnmi.MacUpdatedFlag > 0) {
-
-               return (SK_PNMI_ERR_OK);
-       }
-
-       /* Send an update command to all MACs specified */
-       for (MacIndex = FirstMac; MacIndex <= LastMac; MacIndex ++) {
-
-               /*
-                * 2002-09-13 pweber:   Freeze the current SW counters.
-                *                      (That should be done as close as
-                *                      possible to the update of the
-                *                      HW counters)
-                */
-               if (pAC->GIni.GIMacType == SK_MAC_XMAC) {
-                       pAC->Pnmi.BufPort[MacIndex] = pAC->Pnmi.Port[MacIndex];
-               }
-                       
-               /* 2002-09-13 pweber:  Update the HW counter  */
-               if (pAC->GIni.GIFunc.pFnMacUpdateStats(pAC, IoC, MacIndex) != 0) {
-
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-       }
-
-       return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * GetStatVal - Retrieve an XMAC statistic counter
- *
- * Description:
- *     Retrieves the statistic counter of a virtual or physical port. The
- *     virtual port is identified by the index 0. It consists of all
- *     currently active ports. To obtain the counter value for this port
- *     we must add the statistic counter of all active ports. To grant
- *     continuous counter values for the virtual port even when port
- *     switches occur we must additionally add a delta value, which was
- *     calculated during a SK_PNMI_EVT_RLMT_ACTIVE_UP event.
- *
- * Returns:
- *     Requested statistic value
- */
-PNMI_STATIC SK_U64 GetStatVal(
-SK_AC *pAC,                                    /* Pointer to adapter context */
-SK_IOC IoC,                                    /* IO context handle */
-unsigned int LogPortIndex,     /* Index of the logical Port to be processed */
-unsigned int StatIndex,                /* Index to statistic value */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
-{
-       unsigned int    PhysPortIndex;
-       unsigned int    PhysPortMax;
-       SK_U64                  Val = 0;
-
-
-       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {   /* Dual net mode */
-
-               PhysPortIndex = NetIndex;
-               
-               Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
-       }
-       else {  /* Single Net mode */
-
-               if (LogPortIndex == 0) {
-
-                       PhysPortMax = pAC->GIni.GIMacsFound;
-
-                       /* Add counter of all active ports */
-                       for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
-                               PhysPortIndex ++) {
-
-                               if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
-
-                                       Val += GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
-                               }
-                       }
-
-                       /* Correct value because of port switches */
-                       Val += pAC->Pnmi.VirtualCounterOffset[StatIndex];
-               }
-               else {
-                       /* Get counter value of physical port */
-                       PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
-                       
-                       Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
-               }
-       }
-       return (Val);
-}
-
-/*****************************************************************************
- *
- * GetPhysStatVal - Get counter value for physical port
- *
- * Description:
- *     Builds a 64bit counter value. Except for the octet counters
- *     the lower 32bit are counted in hardware and the upper 32bit
- *     in software by monitoring counter overflow interrupts in the
- *     event handler. To grant continous counter values during XMAC
- *     resets (caused by a workaround) we must add a delta value.
- *     The delta was calculated in the event handler when a
- *     SK_PNMI_EVT_XMAC_RESET was received.
- *
- * Returns:
- *     Counter value
- */
-PNMI_STATIC SK_U64 GetPhysStatVal(
-SK_AC *pAC,                                    /* Pointer to adapter context */
-SK_IOC IoC,                                    /* IO context handle */
-unsigned int PhysPortIndex,    /* Index of the logical Port to be processed */
-unsigned int StatIndex)                /* Index to statistic value */
-{
-       SK_U64  Val = 0;
-       SK_U32  LowVal = 0;
-       SK_U32  HighVal = 0;
-       SK_U16  Word;
-       int             MacType;
-       unsigned int HelpIndex;
-       SK_GEPORT       *pPrt;
-       
-       SK_PNMI_PORT    *pPnmiPrt;
-       SK_GEMACFUNC    *pFnMac;
-       
-       pPrt = &pAC->GIni.GP[PhysPortIndex];
-       
-       MacType = pAC->GIni.GIMacType;
-       
-       /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
-       if (MacType == SK_MAC_XMAC) {
-               pPnmiPrt = &pAC->Pnmi.BufPort[PhysPortIndex];
-       }
-       else {
-               pPnmiPrt = &pAC->Pnmi.Port[PhysPortIndex];
-       }
-       
-       pFnMac   = &pAC->GIni.GIFunc;
-
-       switch (StatIndex) {
-       case SK_PNMI_HTX:
-               if (MacType == SK_MAC_GMAC) {
-                       (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                       StatAddr[SK_PNMI_HTX_BROADCAST][MacType].Reg,
-                                                       &LowVal);
-                       (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                       StatAddr[SK_PNMI_HTX_MULTICAST][MacType].Reg,
-                                                       &HighVal);
-                       LowVal += HighVal;
-                       (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                       StatAddr[SK_PNMI_HTX_UNICAST][MacType].Reg,
-                                                       &HighVal);
-                       LowVal += HighVal;
-               }
-               else {
-                       (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                                                 StatAddr[StatIndex][MacType].Reg,
-                                                                                 &LowVal);
-               }
-               HighVal = pPnmiPrt->CounterHigh[StatIndex];
-               break;
-       
-       case SK_PNMI_HRX:
-               if (MacType == SK_MAC_GMAC) {
-                       (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                       StatAddr[SK_PNMI_HRX_BROADCAST][MacType].Reg,
-                                                       &LowVal);
-                       (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                       StatAddr[SK_PNMI_HRX_MULTICAST][MacType].Reg,
-                                                       &HighVal);
-                       LowVal += HighVal;
-                       (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                       StatAddr[SK_PNMI_HRX_UNICAST][MacType].Reg,
-                                                       &HighVal);
-                       LowVal += HighVal;
-               }
-               else {
-                       (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                                                 StatAddr[StatIndex][MacType].Reg,
-                                                                                 &LowVal);
-               }
-               HighVal = pPnmiPrt->CounterHigh[StatIndex];
-               break;
-
-       case SK_PNMI_HTX_OCTET:
-       case SK_PNMI_HRX_OCTET:
-               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                                         StatAddr[StatIndex][MacType].Reg,
-                                                                         &HighVal);
-               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                                         StatAddr[StatIndex + 1][MacType].Reg,
-                                                                         &LowVal);
-               break;
-
-       case SK_PNMI_HTX_BURST:
-       case SK_PNMI_HTX_EXCESS_DEF:
-       case SK_PNMI_HTX_CARRIER:
-               /* Not supported by GMAC */
-               if (MacType == SK_MAC_GMAC) {
-                       return (Val);
-               }
-
-               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                                         StatAddr[StatIndex][MacType].Reg,
-                                                                         &LowVal);
-               HighVal = pPnmiPrt->CounterHigh[StatIndex];
-               break;
-
-       case SK_PNMI_HTX_MACC:
-               /* GMAC only supports PAUSE MAC control frames */
-               if (MacType == SK_MAC_GMAC) {
-                       HelpIndex = SK_PNMI_HTX_PMACC;
-               }
-               else {
-                       HelpIndex = StatIndex;
-               }
-               
-               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                               StatAddr[HelpIndex][MacType].Reg,
-                                                               &LowVal);
-
-               HighVal = pPnmiPrt->CounterHigh[StatIndex];
-               break;
-
-       case SK_PNMI_HTX_COL:
-       case SK_PNMI_HRX_UNDERSIZE:
-               /* Not supported by XMAC */
-               if (MacType == SK_MAC_XMAC) {
-                       return (Val);
-               }
-
-               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                                         StatAddr[StatIndex][MacType].Reg,
-                                                                         &LowVal);
-               HighVal = pPnmiPrt->CounterHigh[StatIndex];
-               break;
-
-       case SK_PNMI_HTX_DEFFERAL:
-               /* Not supported by GMAC */
-               if (MacType == SK_MAC_GMAC) {
-                       return (Val);
-               }
-               
-               /*
-                * XMAC counts frames with deferred transmission
-                * even in full-duplex mode.
-                *
-                * In full-duplex mode the counter remains constant!
-                */
-               if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) ||
-                       (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL)) {
-
-                       LowVal = 0;
-                       HighVal = 0;
-               }
-               else {
-                       /* Otherwise get contents of hardware register */
-                       (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                                                 StatAddr[StatIndex][MacType].Reg,
-                                                                                 &LowVal);
-                       HighVal = pPnmiPrt->CounterHigh[StatIndex];
-               }
-               break;
-
-       case SK_PNMI_HRX_BADOCTET:
-               /* Not supported by XMAC */
-               if (MacType == SK_MAC_XMAC) {
-                       return (Val);
-               }
-
-               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                                         StatAddr[StatIndex][MacType].Reg,
-                                                                         &HighVal);
-               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                                         StatAddr[StatIndex + 1][MacType].Reg,
-                                      &LowVal);
-               break;
-
-       case SK_PNMI_HTX_OCTETLOW:
-       case SK_PNMI_HRX_OCTETLOW:
-       case SK_PNMI_HRX_BADOCTETLOW:
-               return (Val);
-
-       case SK_PNMI_HRX_LONGFRAMES:
-               /* For XMAC the SW counter is managed by PNMI */
-               if (MacType == SK_MAC_XMAC) {
-                       return (pPnmiPrt->StatRxLongFrameCts);
-               }
-               
-               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                                         StatAddr[StatIndex][MacType].Reg,
-                                                                         &LowVal);
-               HighVal = pPnmiPrt->CounterHigh[StatIndex];
-               break;
-               
-       case SK_PNMI_HRX_TOO_LONG:
-               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                               StatAddr[StatIndex][MacType].Reg,
-                                                               &LowVal);
-               HighVal = pPnmiPrt->CounterHigh[StatIndex];
-               
-               Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
-
-               if (MacType == SK_MAC_GMAC) {
-                       /* For GMAC the SW counter is additionally managed by PNMI */
-                       Val += pPnmiPrt->StatRxFrameTooLongCts;
-               }
-               else {
-                       /*
-                        * Frames longer than IEEE 802.3 frame max size are counted
-                        * by XMAC in frame_too_long counter even reception of long
-                        * frames was enabled and the frame was correct.
-                        * So correct the value by subtracting RxLongFrame counter.
-                        */
-                       Val -= pPnmiPrt->StatRxLongFrameCts;
-               }
-
-               LowVal = (SK_U32)Val;
-               HighVal = (SK_U32)(Val >> 32);
-               break;
-               
-       case SK_PNMI_HRX_SHORTS:
-               /* Not supported by GMAC */
-               if (MacType == SK_MAC_GMAC) {
-                       /* GM_RXE_FRAG?? */
-                       return (Val);
-               }
-               
-               /*
-                * XMAC counts short frame errors even if link down (#10620)
-                *
-                * If link-down the counter remains constant
-                */
-               if (pPrt->PLinkModeStatus != SK_LMODE_STAT_UNKNOWN) {
-
-                       /* Otherwise get incremental difference */
-                       (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                                                 StatAddr[StatIndex][MacType].Reg,
-                                                                                 &LowVal);
-                       HighVal = pPnmiPrt->CounterHigh[StatIndex];
-
-                       Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
-                       Val -= pPnmiPrt->RxShortZeroMark;
-
-                       LowVal = (SK_U32)Val;
-                       HighVal = (SK_U32)(Val >> 32);
-               }
-               break;
-
-       case SK_PNMI_HRX_MACC:
-       case SK_PNMI_HRX_MACC_UNKWN:
-       case SK_PNMI_HRX_BURST:
-       case SK_PNMI_HRX_MISSED:
-       case SK_PNMI_HRX_FRAMING:
-       case SK_PNMI_HRX_CARRIER:
-       case SK_PNMI_HRX_IRLENGTH:
-       case SK_PNMI_HRX_SYMBOL:
-       case SK_PNMI_HRX_CEXT:
-               /* Not supported by GMAC */
-               if (MacType == SK_MAC_GMAC) {
-                       return (Val);
-               }
-
-               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                                         StatAddr[StatIndex][MacType].Reg,
-                                                                         &LowVal);
-               HighVal = pPnmiPrt->CounterHigh[StatIndex];
-               break;
-
-       case SK_PNMI_HRX_PMACC_ERR:
-               /* For GMAC the SW counter is managed by PNMI */
-               if (MacType == SK_MAC_GMAC) {
-                       return (pPnmiPrt->StatRxPMaccErr);
-               }
-               
-               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                                         StatAddr[StatIndex][MacType].Reg,
-                                                                         &LowVal);
-               HighVal = pPnmiPrt->CounterHigh[StatIndex];
-               break;
-
-       /* SW counter managed by PNMI */
-       case SK_PNMI_HTX_SYNC:
-               LowVal = (SK_U32)pPnmiPrt->StatSyncCts;
-               HighVal = (SK_U32)(pPnmiPrt->StatSyncCts >> 32);
-               break;
-
-       /* SW counter managed by PNMI */
-       case SK_PNMI_HTX_SYNC_OCTET:
-               LowVal = (SK_U32)pPnmiPrt->StatSyncOctetsCts;
-               HighVal = (SK_U32)(pPnmiPrt->StatSyncOctetsCts >> 32);
-               break;
-
-       case SK_PNMI_HRX_FCS:
-               /*
-                * Broadcom filters FCS errors and counts it in
-                * Receive Error Counter register
-                */
-               if (pPrt->PhyType == SK_PHY_BCOM) {
-                       /* do not read while not initialized (PHY_READ hangs!)*/
-                       if (pPrt->PState != SK_PRT_RESET) {
-                               SkXmPhyRead(pAC, IoC, PhysPortIndex, PHY_BCOM_RE_CTR, &Word);
-                               
-                               LowVal = Word;
-                       }
-                       HighVal = pPnmiPrt->CounterHigh[StatIndex];
-               }
-               else {
-                       (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                                                 StatAddr[StatIndex][MacType].Reg,
-                                                                                 &LowVal);
-                       HighVal = pPnmiPrt->CounterHigh[StatIndex];
-               }
-               break;
-
-       default:
-               (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
-                                                                         StatAddr[StatIndex][MacType].Reg,
-                                                                         &LowVal);
-               HighVal = pPnmiPrt->CounterHigh[StatIndex];
-               break;
-       }
-
-       Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
-
-       /* Correct value because of possible XMAC reset. XMAC Errata #2 */
-       Val += pPnmiPrt->CounterOffset[StatIndex];
-
-       return (Val);
-}
-
-/*****************************************************************************
- *
- * ResetCounter - Set all counters and timestamps to zero
- *
- * Description:
- *     Notifies other common modules which store statistic data to
- *     reset their counters and finally reset our own counters.
- *
- * Returns:
- *     Nothing
- */
-PNMI_STATIC void ResetCounter(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-SK_U32 NetIndex)
-{
-       unsigned int    PhysPortIndex;
-       SK_EVPARA       EventParam;
-
-
-       SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
-
-       /* Notify sensor module */
-       SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_CLEAR, EventParam);
-
-       /* Notify RLMT module */
-       EventParam.Para32[0] = NetIndex;
-       EventParam.Para32[1] = (SK_U32)-1;
-       SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STATS_CLEAR, EventParam);
-       EventParam.Para32[1] = 0;
-
-       /* Notify SIRQ module */
-       SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_CLEAR_STAT, EventParam);
-
-       /* Notify CSUM module */
-#ifdef SK_USE_CSUM
-       EventParam.Para32[0] = NetIndex;
-       EventParam.Para32[1] = (SK_U32)-1;
-       SkEventQueue(pAC, SKGE_CSUM, SK_CSUM_EVENT_CLEAR_PROTO_STATS,
-               EventParam);
-#endif /* SK_USE_CSUM */
-       
-       /* Clear XMAC statistic */
-       for (PhysPortIndex = 0; PhysPortIndex <
-               (unsigned int)pAC->GIni.GIMacsFound; PhysPortIndex ++) {
-
-               (void)pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PhysPortIndex);
-
-               SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].CounterHigh,
-                       0, sizeof(pAC->Pnmi.Port[PhysPortIndex].CounterHigh));
-               SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
-                       CounterOffset, 0, sizeof(pAC->Pnmi.Port[
-                       PhysPortIndex].CounterOffset));
-               SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].StatSyncCts,
-                       0, sizeof(pAC->Pnmi.Port[PhysPortIndex].StatSyncCts));
-               SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
-                       StatSyncOctetsCts, 0, sizeof(pAC->Pnmi.Port[
-                       PhysPortIndex].StatSyncOctetsCts));
-               SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
-                       StatRxLongFrameCts, 0, sizeof(pAC->Pnmi.Port[
-                       PhysPortIndex].StatRxLongFrameCts));
-               SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
-                                 StatRxFrameTooLongCts, 0, sizeof(pAC->Pnmi.Port[
-                       PhysPortIndex].StatRxFrameTooLongCts));
-               SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
-                                 StatRxPMaccErr, 0, sizeof(pAC->Pnmi.Port[
-                       PhysPortIndex].StatRxPMaccErr));
-       }
-
-       /*
-        * Clear local statistics
-        */
-       SK_MEMSET((char *)&pAC->Pnmi.VirtualCounterOffset, 0,
-                 sizeof(pAC->Pnmi.VirtualCounterOffset));
-       pAC->Pnmi.RlmtChangeCts = 0;
-       pAC->Pnmi.RlmtChangeTime = 0;
-       SK_MEMSET((char *)&pAC->Pnmi.RlmtChangeEstimate.EstValue[0], 0,
-               sizeof(pAC->Pnmi.RlmtChangeEstimate.EstValue));
-       pAC->Pnmi.RlmtChangeEstimate.EstValueIndex = 0;
-       pAC->Pnmi.RlmtChangeEstimate.Estimate = 0;
-       pAC->Pnmi.Port[NetIndex].TxSwQueueMax = 0;
-       pAC->Pnmi.Port[NetIndex].TxRetryCts = 0;
-       pAC->Pnmi.Port[NetIndex].RxIntrCts = 0;
-       pAC->Pnmi.Port[NetIndex].TxIntrCts = 0;
-       pAC->Pnmi.Port[NetIndex].RxNoBufCts = 0;
-       pAC->Pnmi.Port[NetIndex].TxNoBufCts = 0;
-       pAC->Pnmi.Port[NetIndex].TxUsedDescrNo = 0;
-       pAC->Pnmi.Port[NetIndex].RxDeliveredCts = 0;
-       pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts = 0;
-       pAC->Pnmi.Port[NetIndex].ErrRecoveryCts = 0;
-}
-
-/*****************************************************************************
- *
- * GetTrapEntry - Get an entry in the trap buffer
- *
- * Description:
- *     The trap buffer stores various events. A user application somehow
- *     gets notified that an event occured and retrieves the trap buffer
- *     contens (or simply polls the buffer). The buffer is organized as
- *     a ring which stores the newest traps at the beginning. The oldest
- *     traps are overwritten by the newest ones. Each trap entry has a
- *     unique number, so that applications may detect new trap entries.
- *
- * Returns:
- *     A pointer to the trap entry
- */
-PNMI_STATIC char* GetTrapEntry(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_U32 TrapId,         /* SNMP ID of the trap */
-unsigned int Size)     /* Space needed for trap entry */
-{
-       unsigned int            BufPad = pAC->Pnmi.TrapBufPad;
-       unsigned int            BufFree = pAC->Pnmi.TrapBufFree;
-       unsigned int            Beg = pAC->Pnmi.TrapQueueBeg;
-       unsigned int            End = pAC->Pnmi.TrapQueueEnd;
-       char                    *pBuf = &pAC->Pnmi.TrapBuf[0];
-       int                     Wrap;
-       unsigned int            NeededSpace;
-       unsigned int            EntrySize;
-       SK_U32                  Val32;
-       SK_U64                  Val64;
-
-
-       /* Last byte of entry will get a copy of the entry length */
-       Size ++;
-
-       /*
-        * Calculate needed buffer space */
-       if (Beg >= Size) {
-
-               NeededSpace = Size;
-               Wrap = SK_FALSE;
-       }
-       else {
-               NeededSpace = Beg + Size;
-               Wrap = SK_TRUE;
-       }
-
-       /*
-        * Check if enough buffer space is provided. Otherwise
-        * free some entries. Leave one byte space between begin
-        * and end of buffer to make it possible to detect whether
-        * the buffer is full or empty
-        */
-       while (BufFree < NeededSpace + 1) {
-
-               if (End == 0) {
-
-                       End = SK_PNMI_TRAP_QUEUE_LEN;
-               }
-
-               EntrySize = (unsigned int)*((unsigned char *)pBuf + End - 1);
-               BufFree += EntrySize;
-               End -= EntrySize;
-#ifdef DEBUG
-               SK_MEMSET(pBuf + End, (char)(-1), EntrySize);
-#endif /* DEBUG */
-               if (End == BufPad) {
-#ifdef DEBUG
-                       SK_MEMSET(pBuf, (char)(-1), End);
-#endif /* DEBUG */
-                       BufFree += End;
-                       End = 0;
-                       BufPad = 0;
-               }
-       }
-
-       /*
-        * Insert new entry as first entry. Newest entries are
-        * stored at the beginning of the queue.
-        */
-       if (Wrap) {
-
-               BufPad = Beg;
-               Beg = SK_PNMI_TRAP_QUEUE_LEN - Size;
-       }
-       else {
-               Beg = Beg - Size;
-       }
-       BufFree -= NeededSpace;
-
-       /* Save the current offsets */
-       pAC->Pnmi.TrapQueueBeg = Beg;
-       pAC->Pnmi.TrapQueueEnd = End;
-       pAC->Pnmi.TrapBufPad = BufPad;
-       pAC->Pnmi.TrapBufFree = BufFree;
-
-       /* Initialize the trap entry */
-       *(pBuf + Beg + Size - 1) = (char)Size;
-       *(pBuf + Beg) = (char)Size;
-       Val32 = (pAC->Pnmi.TrapUnique) ++;
-       SK_PNMI_STORE_U32(pBuf + Beg + 1, Val32);
-       SK_PNMI_STORE_U32(pBuf + Beg + 1 + sizeof(SK_U32), TrapId);
-       Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
-       SK_PNMI_STORE_U64(pBuf + Beg + 1 + 2 * sizeof(SK_U32), Val64);
-
-       return (pBuf + Beg);
-}
-
-/*****************************************************************************
- *
- * CopyTrapQueue - Copies the trap buffer for the TRAP OID
- *
- * Description:
- *     On a query of the TRAP OID the trap buffer contents will be
- *     copied continuously to the request buffer, which must be large
- *     enough. No length check is performed.
- *
- * Returns:
- *     Nothing
- */
-PNMI_STATIC void CopyTrapQueue(
-SK_AC *pAC,            /* Pointer to adapter context */
-char *pDstBuf)         /* Buffer to which the queued traps will be copied */
-{
-       unsigned int    BufPad = pAC->Pnmi.TrapBufPad;
-       unsigned int    Trap = pAC->Pnmi.TrapQueueBeg;
-       unsigned int    End = pAC->Pnmi.TrapQueueEnd;
-       char            *pBuf = &pAC->Pnmi.TrapBuf[0];
-       unsigned int    Len;
-       unsigned int    DstOff = 0;
-
-
-       while (Trap != End) {
-
-               Len = (unsigned int)*(pBuf + Trap);
-
-               /*
-                * Last byte containing a copy of the length will
-                * not be copied.
-                */
-               *(pDstBuf + DstOff) = (char)(Len - 1);
-               SK_MEMCPY(pDstBuf + DstOff + 1, pBuf + Trap + 1, Len - 2);
-               DstOff += Len - 1;
-
-               Trap += Len;
-               if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
-
-                       Trap = BufPad;
-               }
-       }
-}
-
-/*****************************************************************************
- *
- * GetTrapQueueLen - Get the length of the trap buffer
- *
- * Description:
- *     Evaluates the number of currently stored traps and the needed
- *     buffer size to retrieve them.
- *
- * Returns:
- *     Nothing
- */
-PNMI_STATIC void GetTrapQueueLen(
-SK_AC *pAC,            /* Pointer to adapter context */
-unsigned int *pLen,    /* Length in Bytes of all queued traps */
-unsigned int *pEntries)        /* Returns number of trapes stored in queue */
-{
-       unsigned int    BufPad = pAC->Pnmi.TrapBufPad;
-       unsigned int    Trap = pAC->Pnmi.TrapQueueBeg;
-       unsigned int    End = pAC->Pnmi.TrapQueueEnd;
-       char            *pBuf = &pAC->Pnmi.TrapBuf[0];
-       unsigned int    Len;
-       unsigned int    Entries = 0;
-       unsigned int    TotalLen = 0;
-
-
-       while (Trap != End) {
-
-               Len = (unsigned int)*(pBuf + Trap);
-               TotalLen += Len - 1;
-               Entries ++;
-
-               Trap += Len;
-               if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
-
-                       Trap = BufPad;
-               }
-       }
-
-       *pEntries = Entries;
-       *pLen = TotalLen;
-}
-
-/*****************************************************************************
- *
- * QueueSimpleTrap - Store a simple trap to the trap buffer
- *
- * Description:
- *     A simple trap is a trap with now additional data. It consists
- *     simply of a trap code.
- *
- * Returns:
- *     Nothing
- */
-PNMI_STATIC void QueueSimpleTrap(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_U32 TrapId)         /* Type of sensor trap */
-{
-       GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_SIMPLE_LEN);
-}
-
-/*****************************************************************************
- *
- * QueueSensorTrap - Stores a sensor trap in the trap buffer
- *
- * Description:
- *     Gets an entry in the trap buffer and fills it with sensor related
- *     data.
- *
- * Returns:
- *     Nothing
- */
-PNMI_STATIC void QueueSensorTrap(
-SK_AC *pAC,                    /* Pointer to adapter context */
-SK_U32 TrapId,                 /* Type of sensor trap */
-unsigned int SensorIndex)      /* Index of sensor which caused the trap */
-{
-       char            *pBuf;
-       unsigned int    Offset;
-       unsigned int    DescrLen;
-       SK_U32          Val32;
-
-
-       /* Get trap buffer entry */
-       DescrLen = SK_STRLEN(pAC->I2c.SenTable[SensorIndex].SenDesc);
-       pBuf = GetTrapEntry(pAC, TrapId,
-               SK_PNMI_TRAP_SENSOR_LEN_BASE + DescrLen);
-       Offset = SK_PNMI_TRAP_SIMPLE_LEN;
-
-       /* Store additionally sensor trap related data */
-       Val32 = OID_SKGE_SENSOR_INDEX;
-       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
-       *(pBuf + Offset + 4) = 4;
-       Val32 = (SK_U32)SensorIndex;
-       SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
-       Offset += 9;
-       
-       Val32 = (SK_U32)OID_SKGE_SENSOR_DESCR;
-       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
-       *(pBuf + Offset + 4) = (char)DescrLen;
-       SK_MEMCPY(pBuf + Offset + 5, pAC->I2c.SenTable[SensorIndex].SenDesc,
-               DescrLen);
-       Offset += DescrLen + 5;
-
-       Val32 = OID_SKGE_SENSOR_TYPE;
-       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
-       *(pBuf + Offset + 4) = 1;
-       *(pBuf + Offset + 5) = (char)pAC->I2c.SenTable[SensorIndex].SenType;
-       Offset += 6;
-
-       Val32 = OID_SKGE_SENSOR_VALUE;
-       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
-       *(pBuf + Offset + 4) = 4;
-       Val32 = (SK_U32)pAC->I2c.SenTable[SensorIndex].SenValue;
-       SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
-}
-
-/*****************************************************************************
- *
- * QueueRlmtNewMacTrap - Store a port switch trap in the trap buffer
- *
- * Description:
- *     Nothing further to explain.
- *
- * Returns:
- *     Nothing
- */
-PNMI_STATIC void QueueRlmtNewMacTrap(
-SK_AC *pAC,            /* Pointer to adapter context */
-unsigned int ActiveMac)        /* Index (0..n) of the currently active port */
-{
-       char    *pBuf;
-       SK_U32  Val32;
-
-
-       pBuf = GetTrapEntry(pAC, OID_SKGE_TRAP_RLMT_CHANGE_PORT,
-               SK_PNMI_TRAP_RLMT_CHANGE_LEN);
-
-       Val32 = OID_SKGE_RLMT_PORT_ACTIVE;
-       SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
-       *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
-       *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)ActiveMac;
-}
-
-/*****************************************************************************
- *
- * QueueRlmtPortTrap - Store port related RLMT trap to trap buffer
- *
- * Description:
- *     Nothing further to explain.
- *
- * Returns:
- *     Nothing
- */
-PNMI_STATIC void QueueRlmtPortTrap(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_U32 TrapId,         /* Type of RLMT port trap */
-unsigned int PortIndex)        /* Index of the port, which changed its state */
-{
-       char    *pBuf;
-       SK_U32  Val32;
-
-
-       pBuf = GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_RLMT_PORT_LEN);
-
-       Val32 = OID_SKGE_RLMT_PORT_INDEX;
-       SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
-       *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
-       *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)PortIndex;
-}
-
-/*****************************************************************************
- *
- * CopyMac - Copies a MAC address
- *
- * Description:
- *     Nothing further to explain.
- *
- * Returns:
- *     Nothing
- */
-PNMI_STATIC void CopyMac(
-char *pDst,            /* Pointer to destination buffer */
-SK_MAC_ADDR *pMac)     /* Pointer of Source */
-{
-       int     i;
-
-
-       for (i = 0; i < sizeof(SK_MAC_ADDR); i ++) {
-
-               *(pDst + i) = pMac->a[i];
-       }
-}
-
-#ifdef SK_POWER_MGMT
-/*****************************************************************************
- *
- * PowerManagement - OID handler function of PowerManagement OIDs
- *
- * Description:
- *     The code is simple. No description necessary.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                               exist (e.g. port instance 3 on a two port
- *                              adapter.
- */
-
-PNMI_STATIC int PowerManagement(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int Action,            /* Get/PreSet/Set action */
-SK_U32 Id,             /* Object ID that is to be processed */
-char *pBuf,            /* Buffer to which to mgmt data will be retrieved */
-unsigned int *pLen,    /* On call: buffer length. On return: used buffer */
-SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode allways zero */
-{
-       
-       SK_U32  RetCode = SK_PNMI_ERR_GENERAL;
-
-       /*
-        * Check instance. We only handle single instance variables
-        */
-       if (Instance != (SK_U32)(-1) && Instance != 1) {
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_UNKNOWN_INST);
-       }
-       
-    
-    /* Check length */
-    switch (Id) {
-
-    case OID_PNP_CAPABILITIES:
-        if (*pLen < sizeof(SK_PNP_CAPABILITIES)) {
-
-            *pLen = sizeof(SK_PNP_CAPABILITIES);
-            return (SK_PNMI_ERR_TOO_SHORT);
-        }
-        break;
-
-       case OID_PNP_SET_POWER:
-    case OID_PNP_QUERY_POWER:
-       if (*pLen < sizeof(SK_DEVICE_POWER_STATE))
-       {
-               *pLen = sizeof(SK_DEVICE_POWER_STATE);
-               return (SK_PNMI_ERR_TOO_SHORT);
-       }
-        break;
-
-    case OID_PNP_ADD_WAKE_UP_PATTERN:
-    case OID_PNP_REMOVE_WAKE_UP_PATTERN:
-               if (*pLen < sizeof(SK_PM_PACKET_PATTERN)) {
-
-                       *pLen = sizeof(SK_PM_PACKET_PATTERN);
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               break;
-
-    case OID_PNP_ENABLE_WAKE_UP:
-        if (*pLen < sizeof(SK_U32)) {
-
-            *pLen = sizeof(SK_U32);
-            return (SK_PNMI_ERR_TOO_SHORT);
-        }
-        break;
-    }
-       
-    /*
-        * Perform action
-        */
-       if (Action == SK_PNMI_GET) {
-
-               /*
-                * Get value
-                */
-               switch (Id) {
-
-               case OID_PNP_CAPABILITIES:
-                       RetCode = SkPowerQueryPnPCapabilities(pAC, IoC, pBuf, pLen);
-                       break;
-
-               case OID_PNP_QUERY_POWER:
-                       /* The Windows DDK describes: An OID_PNP_QUERY_POWER requests
-                        the miniport to indicate whether it can transition its NIC
-                        to the low-power state.
-                        A miniport driver must always return NDIS_STATUS_SUCCESS
-                        to a query of OID_PNP_QUERY_POWER. */
-                       *pLen = sizeof(SK_DEVICE_POWER_STATE);
-            RetCode = SK_PNMI_ERR_OK;
-                       break;
-
-                       /* NDIS handles these OIDs as write-only.
-                        * So in case of get action the buffer with written length = 0
-                        * is returned
-                        */
-               case OID_PNP_SET_POWER:
-               case OID_PNP_ADD_WAKE_UP_PATTERN:
-               case OID_PNP_REMOVE_WAKE_UP_PATTERN:
-                       *pLen = 0;      
-            RetCode = SK_PNMI_ERR_NOT_SUPPORTED;
-                       break;
-
-               case OID_PNP_ENABLE_WAKE_UP:
-                       RetCode = SkPowerGetEnableWakeUp(pAC, IoC, pBuf, pLen);
-                       break;
-
-               default:
-                       RetCode = SK_PNMI_ERR_GENERAL;
-                       break;
-               }
-
-               return (RetCode);
-       }
-       
-
-       /*
-        * Perform preset or set
-        */
-       
-       /* POWER module does not support PRESET action */
-       if (Action == SK_PNMI_PRESET) {
-               return (SK_PNMI_ERR_OK);
-       }
-
-       switch (Id) {
-       case OID_PNP_SET_POWER:
-               RetCode = SkPowerSetPower(pAC, IoC, pBuf, pLen);        
-               break;
-
-       case OID_PNP_ADD_WAKE_UP_PATTERN:
-               RetCode = SkPowerAddWakeUpPattern(pAC, IoC, pBuf, pLen);        
-               break;
-               
-       case OID_PNP_REMOVE_WAKE_UP_PATTERN:
-               RetCode = SkPowerRemoveWakeUpPattern(pAC, IoC, pBuf, pLen);     
-               break;
-               
-       case OID_PNP_ENABLE_WAKE_UP:
-               RetCode = SkPowerSetEnableWakeUp(pAC, IoC, pBuf, pLen);
-               break;
-               
-       default:
-               RetCode = SK_PNMI_ERR_READ_ONLY;
-       }
-       
-       return (RetCode);
-}
-#endif /* SK_POWER_MGMT */
-
-#ifdef SK_DIAG_SUPPORT
-/*****************************************************************************
- *
- * DiagActions - OID handler function of Diagnostic driver 
- *
- * Description:
- *     The code is simple. No description necessary.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                           exist (e.g. port instance 3 on a two port
- *                              adapter.
- */
-
-PNMI_STATIC int DiagActions(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int Action,            /* GET/PRESET/SET action */
-SK_U32 Id,             /* Object ID that is to be processed */
-char *pBuf,            /* Buffer used for the management data transfer */
-unsigned int *pLen,    /* On call: pBuf buffer length. On return: used buffer */
-SK_U32 Instance,       /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode always zero */
-{
-
-       SK_U32  DiagStatus;
-       SK_U32  RetCode = SK_PNMI_ERR_GENERAL;
-
-       /*
-        * Check instance. We only handle single instance variables.
-        */
-       if (Instance != (SK_U32)(-1) && Instance != 1) {
-
-               *pLen = 0;
-               return (SK_PNMI_ERR_UNKNOWN_INST);
-       }
-
-       /*
-        * Check length.
-        */
-       switch (Id) {
-
-       case OID_SKGE_DIAG_MODE:
-               if (*pLen < sizeof(SK_U32)) {
-
-                       *pLen = sizeof(SK_U32);
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               break;
-
-       default:
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR040, SK_PNMI_ERR040MSG);
-               *pLen = 0;
-               return (SK_PNMI_ERR_GENERAL);
-       }
-
-       /* Perform action. */
-
-       /* GET value. */
-       if (Action == SK_PNMI_GET) {
-
-               switch (Id) {
-
-               case OID_SKGE_DIAG_MODE:
-                       DiagStatus = pAC->Pnmi.DiagAttached;
-                       SK_PNMI_STORE_U32(pBuf, DiagStatus);
-                       *pLen = sizeof(SK_U32); 
-                       RetCode = SK_PNMI_ERR_OK;
-                       break;
-
-               default:
-                       *pLen = 0;      
-                       RetCode = SK_PNMI_ERR_GENERAL;
-                       break;
-               }
-               return (RetCode); 
-       }
-
-       /* From here SET or PRESET value. */
-       
-       /* PRESET value is not supported. */
-       if (Action == SK_PNMI_PRESET) {
-               return (SK_PNMI_ERR_OK); 
-       }
-
-       /* SET value. */
-       switch (Id) {
-               case OID_SKGE_DIAG_MODE:
-
-                       /* Handle the SET. */
-                       switch (*pBuf) {
-
-                               /* Attach the DIAG to this adapter. */
-                               case SK_DIAG_ATTACHED:
-                                       /* Check if we come from running */
-                                       if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
-
-                                               RetCode = SkDrvLeaveDiagMode(pAC);
-
-                                       }
-                                       else if (pAC->Pnmi.DiagAttached == SK_DIAG_IDLE) {
-
-                                               RetCode = SK_PNMI_ERR_OK;
-                                       }       
-                                       
-                                       else {
-
-                                               RetCode = SK_PNMI_ERR_GENERAL;
-
-                                       }
-                                       
-                                       if (RetCode == SK_PNMI_ERR_OK) {
-
-                                               pAC->Pnmi.DiagAttached = SK_DIAG_ATTACHED;
-                                       }
-                                       break;
-
-                               /* Enter the DIAG mode in the driver. */
-                               case SK_DIAG_RUNNING:
-                                       RetCode = SK_PNMI_ERR_OK;
-                                       
-                                       /*
-                                        * If DiagAttached is set, we can tell the driver
-                                        * to enter the DIAG mode.
-                                        */
-                                       if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) {
-                                               /* If DiagMode is not active, we can enter it. */
-                                               if (!pAC->DiagModeActive) {
-
-                                                       RetCode = SkDrvEnterDiagMode(pAC); 
-                                               }
-                                               else {
-
-                                                       RetCode = SK_PNMI_ERR_GENERAL;
-                                               }
-                                       }
-                                       else {
-
-                                               RetCode = SK_PNMI_ERR_GENERAL;
-                                       }
-                                       
-                                       if (RetCode == SK_PNMI_ERR_OK) {
-
-                                               pAC->Pnmi.DiagAttached = SK_DIAG_RUNNING;
-                                       }
-                                       break;
-
-                               case SK_DIAG_IDLE:
-                                       /* Check if we come from running */
-                                       if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
-
-                                               RetCode = SkDrvLeaveDiagMode(pAC);
-
-                                       }
-                                       else if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) {
-
-                                               RetCode = SK_PNMI_ERR_OK;
-                                       }       
-                                       
-                                       else {
-
-                                               RetCode = SK_PNMI_ERR_GENERAL;
-
-                                       }
-
-                                       if (RetCode == SK_PNMI_ERR_OK) {
-
-                                               pAC->Pnmi.DiagAttached = SK_DIAG_IDLE;
-                                       }
-                                       break;
-
-                               default:
-                                       RetCode = SK_PNMI_ERR_BAD_VALUE;
-                                       break;
-                       }
-                       break;
-
-               default:
-                       RetCode = SK_PNMI_ERR_GENERAL;
-       }
-
-       if (RetCode == SK_PNMI_ERR_OK) {
-               *pLen = sizeof(SK_U32);
-       }
-       else {
-
-               *pLen = 0;
-       }
-       return (RetCode);
-}
-#endif /* SK_DIAG_SUPPORT */
-
-/*****************************************************************************
- *
- * Vct - OID handler function of  OIDs
- *
- * Description:
- *     The code is simple. No description necessary.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was performed successfully.
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured.
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
- *                              the correct data (e.g. a 32bit value is
- *                              needed, but a 16 bit value was passed).
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                           exist (e.g. port instance 3 on a two port
- *                              adapter).
- *     SK_PNMI_ERR_READ_ONLY    Only the Get action is allowed.
- *
- */
-
-PNMI_STATIC int Vct(
-SK_AC *pAC,            /* Pointer to adapter context */
-SK_IOC IoC,            /* IO context handle */
-int Action,            /* GET/PRESET/SET action */
-SK_U32 Id,             /* Object ID that is to be processed */
-char *pBuf,            /* Buffer used for the management data transfer */
-unsigned int *pLen,    /* On call: pBuf buffer length. On return: used buffer */
-SK_U32 Instance,       /* Instance (-1,2..n) that is to be queried */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex)       /* NetIndex (0..n), in single net mode always zero */
-{
-       SK_GEPORT       *pPrt;
-       SK_PNMI_VCT     *pVctBackupData;
-       SK_U32          LogPortMax;
-       SK_U32          PhysPortMax;
-       SK_U32          PhysPortIndex;
-       SK_U32          Limit;
-       SK_U32          Offset;
-       SK_BOOL         Link;
-       SK_U32          RetCode = SK_PNMI_ERR_GENERAL;
-       int             i;
-       SK_EVPARA       Para;
-       SK_U32          CableLength;
-       
-       /*
-        * Calculate the port indexes from the instance.
-        */
-       PhysPortMax = pAC->GIni.GIMacsFound;
-       LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
-       
-       /* Dual net mode? */
-       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-               LogPortMax--;
-       }
-       
-       if ((Instance != (SK_U32) (-1))) {
-               /* Check instance range. */
-               if ((Instance < 2) || (Instance > LogPortMax)) {
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_UNKNOWN_INST);
-               }
-               
-               if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
-                       PhysPortIndex = NetIndex;
-               }
-               else {
-                       PhysPortIndex = Instance - 2;
-               }
-               Limit = PhysPortIndex + 1;
-       }
-       else {
-               /*
-                * Instance == (SK_U32) (-1), get all Instances of that OID.
-                *
-                * Not implemented yet. May be used in future releases.
-                */
-               PhysPortIndex = 0;
-               Limit = PhysPortMax;
-       }
-       
-       pPrt = &pAC->GIni.GP[PhysPortIndex];
-       if (pPrt->PHWLinkUp) {
-               Link = SK_TRUE;
-       }
-       else {
-               Link = SK_FALSE;
-       }
-       
-       /* Check MAC type */
-       if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
-               *pLen = 0;
-               return (SK_PNMI_ERR_GENERAL);
-       }
-       
-       /* Initialize backup data pointer. */
-       pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
-       
-       /* Check action type */
-       if (Action == SK_PNMI_GET) {
-               /* Check length */
-               switch (Id) {
-               
-               case OID_SKGE_VCT_GET:
-                       if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT)) {
-                               *pLen = (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT);
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-                       break;
-               
-               case OID_SKGE_VCT_STATUS:
-                       if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U8)) {
-                               *pLen = (Limit - PhysPortIndex) * sizeof(SK_U8);
-                               return (SK_PNMI_ERR_TOO_SHORT);
-                       }
-                       break;
-               
-               default:
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }       
-               
-               /* Get value */
-               Offset = 0;
-               for (; PhysPortIndex < Limit; PhysPortIndex++) {
-                       switch (Id) {
-                       
-                       case OID_SKGE_VCT_GET:
-                               if ((Link == SK_FALSE) &&
-                                       (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING)) {
-                                       RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
-                                       if (RetCode == 0) {
-                                               pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
-                                               pAC->Pnmi.VctStatus[PhysPortIndex] |=
-                                                       (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
-                                               
-                                               /* Copy results for later use to PNMI struct. */
-                                               for (i = 0; i < 4; i++)  {
-                                                       if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
-                                                               if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] < 0xff)) {
-                                                                       pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
-                                                               }
-                                                       }
-                                                       if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] != 0xff)) {
-                                                               CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
-                                                       }
-                                                       else {
-                                                               CableLength = 0;
-                                                       }
-                                                       pVctBackupData->PMdiPairLen[i] = CableLength;
-                                                       pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
-                                               }
-
-                                               Para.Para32[0] = PhysPortIndex;
-                                               Para.Para32[1] = -1;
-                                               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
-                                               SkEventDispatcher(pAC, IoC);
-                                       }
-                                       else {
-                                               ; /* VCT test is running. */
-                                       }
-                               }
-                               
-                               /* Get all results. */
-                               CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
-                               Offset += sizeof(SK_U8);
-                               *(pBuf + Offset) = pPrt->PCableLen;
-                               Offset += sizeof(SK_U8);
-                               for (i = 0; i < 4; i++)  {
-                                       SK_PNMI_STORE_U32((pBuf + Offset), pVctBackupData->PMdiPairLen[i]);
-                                       Offset += sizeof(SK_U32);
-                               }
-                               for (i = 0; i < 4; i++)  {
-                                       *(pBuf + Offset) = pVctBackupData->PMdiPairSts[i];
-                                       Offset += sizeof(SK_U8);
-                               }
-                               
-                               RetCode = SK_PNMI_ERR_OK;
-                               break;
-               
-                       case OID_SKGE_VCT_STATUS:
-                               CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
-                               Offset += sizeof(SK_U8);
-                               RetCode = SK_PNMI_ERR_OK;
-                               break;
-                       
-                       default:
-                               *pLen = 0;
-                               return (SK_PNMI_ERR_GENERAL);
-                       }
-               } /* for */
-               *pLen = Offset;
-               return (RetCode);
-       
-       } /* if SK_PNMI_GET */
-       
-       /*
-        * From here SET or PRESET action. Check if the passed
-        * buffer length is plausible.
-        */
-       
-       /* Check length */
-       switch (Id) {
-       case OID_SKGE_VCT_SET:
-               if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
-                       *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
-                       return (SK_PNMI_ERR_TOO_SHORT);
-               }
-               break;
-       
-       default:
-               *pLen = 0;
-               return (SK_PNMI_ERR_GENERAL);
-       }
-       
-       /*
-        * Perform preset or set.
-        */
-       
-       /* VCT does not support PRESET action. */
-       if (Action == SK_PNMI_PRESET) {
-               return (SK_PNMI_ERR_OK);
-       }
-       
-       Offset = 0;
-       for (; PhysPortIndex < Limit; PhysPortIndex++) {
-               switch (Id) {
-               case OID_SKGE_VCT_SET: /* Start VCT test. */
-                       if (Link == SK_FALSE) {
-                               SkGeStopPort(pAC, IoC, PhysPortIndex, SK_STOP_ALL, SK_SOFT_RST);
-                               
-                               RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_TRUE);
-                               if (RetCode == 0) { /* RetCode: 0 => Start! */
-                                       pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_PENDING;
-                                       pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_NEW_VCT_DATA;
-                                       pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_LINK;
-                                       
-                                       /*
-                                        * Start VCT timer counter.
-                                        */
-                                       SK_MEMSET((char *) &Para, 0, sizeof(Para));
-                                       Para.Para32[0] = PhysPortIndex;
-                                       Para.Para32[1] = -1;
-                                       SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
-                                               4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Para);
-                                       SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
-                                       RetCode = SK_PNMI_ERR_OK;
-                               }
-                               else { /* RetCode: 2 => Running! */
-                                       SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
-                                       RetCode = SK_PNMI_ERR_OK;
-                               }
-                       }
-                       else { /* RetCode: 4 => Link! */
-                               RetCode = 4;
-                               SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
-                               RetCode = SK_PNMI_ERR_OK;
-                       }
-                       Offset += sizeof(SK_U32);
-                       break;
-       
-               default:
-                       *pLen = 0;
-                       return (SK_PNMI_ERR_GENERAL);
-               }
-       } /* for */
-       *pLen = Offset;
-       return (RetCode);
-
-} /* Vct */
-
-
-PNMI_STATIC void CheckVctStatus(
-SK_AC          *pAC,
-SK_IOC         IoC,
-char           *pBuf,
-SK_U32         Offset,
-SK_U32         PhysPortIndex)
-{
-       SK_GEPORT       *pPrt;
-       SK_PNMI_VCT     *pVctData;
-       SK_U32          RetCode;
-       
-       pPrt = &pAC->GIni.GP[PhysPortIndex];
-       
-       pVctData = (SK_PNMI_VCT *) (pBuf + Offset);
-       pVctData->VctStatus = SK_PNMI_VCT_NONE;
-       
-       if (!pPrt->PHWLinkUp) {
-               
-               /* Was a VCT test ever made before? */
-               if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
-                       if ((pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_LINK)) {
-                               pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
-                       }
-                       else {
-                               pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
-                       }
-               }
-               
-               /* Check VCT test status. */
-               RetCode = SkGmCableDiagStatus(pAC,IoC, PhysPortIndex, SK_FALSE);
-               if (RetCode == 2) { /* VCT test is running. */
-                       pVctData->VctStatus |= SK_PNMI_VCT_RUNNING;
-               }
-               else { /* VCT data was copied to pAC here. Check PENDING state. */
-                       if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
-                               pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
-                       }
-               }
-               
-               if (pPrt->PCableLen != 0xff) { /* Old DSP value. */
-                       pVctData->VctStatus |= SK_PNMI_VCT_OLD_DSP_DATA;
-               }
-       }
-       else {
-               
-               /* Was a VCT test ever made before? */
-               if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
-                       pVctData->VctStatus &= ~SK_PNMI_VCT_NEW_VCT_DATA;
-                       pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
-               }
-               
-               /* DSP only valid in 100/1000 modes. */
-               if (pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed !=
-                       SK_LSPEED_STAT_10MBPS) {        
-                       pVctData->VctStatus |= SK_PNMI_VCT_NEW_DSP_DATA;
-               }
-       }
-} /* CheckVctStatus */
-
-
-/*****************************************************************************
- *
- *      SkPnmiGenIoctl - Handles new generic PNMI IOCTL, calls the needed
- *                       PNMI function depending on the subcommand and
- *                       returns all data belonging to the complete database
- *                       or OID request.
- *
- * Description:
- *     Looks up the requested subcommand, calls the corresponding handler
- *     function and passes all required parameters to it.
- *     The function is called by the driver. It is needed to handle the new
- *  generic PNMI IOCTL. This IOCTL is given to the driver and contains both
- *  the OID and a subcommand to decide what kind of request has to be done.
- *
- * Returns:
- *     SK_PNMI_ERR_OK           The request was successfully performed
- *     SK_PNMI_ERR_GENERAL      A general severe internal error occured
- *     SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to take
- *                              the data.
- *     SK_PNMI_ERR_UNKNOWN_OID  The requested OID is unknown
- *     SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- *                           exist (e.g. port instance 3 on a two port
- *                              adapter.
- */
-int SkPnmiGenIoctl(
-SK_AC          *pAC,           /* Pointer to adapter context struct */
-SK_IOC         IoC,            /* I/O context */
-void           *pBuf,          /* Buffer used for the management data transfer */
-unsigned int *pLen,            /* Length of buffer */
-SK_U32         NetIndex)       /* NetIndex (0..n), in single net mode always zero */
-{
-SK_I32 Mode;                   /* Store value of subcommand. */
-SK_U32 Oid;                    /* Store value of OID. */
-int            ReturnCode;             /* Store return value to show status of PNMI action. */
-int    HeaderLength;   /* Length of desired action plus OID. */
-
-       ReturnCode = SK_PNMI_ERR_GENERAL;
-       
-       SK_MEMCPY(&Mode, pBuf, sizeof(SK_I32));
-       SK_MEMCPY(&Oid, (char *) pBuf + sizeof(SK_I32), sizeof(SK_U32));
-       HeaderLength = sizeof(SK_I32) + sizeof(SK_U32);
-       *pLen = *pLen - HeaderLength;
-       SK_MEMCPY((char *) pBuf + sizeof(SK_I32), (char *) pBuf + HeaderLength, *pLen);
-       
-       switch(Mode) {
-       case SK_GET_SINGLE_VAR:
-               ReturnCode = SkPnmiGetVar(pAC, IoC, Oid, 
-                               (char *) pBuf + sizeof(SK_I32), pLen,
-                               ((SK_U32) (-1)), NetIndex);
-               SK_PNMI_STORE_U32(pBuf, ReturnCode);
-               *pLen = *pLen + sizeof(SK_I32);
-               break;
-       case SK_PRESET_SINGLE_VAR:
-               ReturnCode = SkPnmiPreSetVar(pAC, IoC, Oid, 
-                               (char *) pBuf + sizeof(SK_I32), pLen,
-                               ((SK_U32) (-1)), NetIndex);
-               SK_PNMI_STORE_U32(pBuf, ReturnCode);
-               *pLen = *pLen + sizeof(SK_I32);
-               break;
-       case SK_SET_SINGLE_VAR:
-               ReturnCode = SkPnmiSetVar(pAC, IoC, Oid, 
-                               (char *) pBuf + sizeof(SK_I32), pLen,
-                               ((SK_U32) (-1)), NetIndex);
-               SK_PNMI_STORE_U32(pBuf, ReturnCode);
-               *pLen = *pLen + sizeof(SK_I32);
-               break;
-       case SK_GET_FULL_MIB:
-               ReturnCode = SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex);
-               break;
-       case SK_PRESET_FULL_MIB:
-               ReturnCode = SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex);
-               break;
-       case SK_SET_FULL_MIB:
-               ReturnCode = SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex);
-               break;
-       default:
-               break;
-       }
-       
-       return (ReturnCode);
-
-} /* SkGeIocGen */
diff --git a/drivers/net/sk98lin/skgesirq.c b/drivers/net/sk98lin/skgesirq.c
deleted file mode 100644 (file)
index 3e7aa49..0000000
+++ /dev/null
@@ -1,2229 +0,0 @@
-/******************************************************************************
- *
- * Name:       skgesirq.c
- * Project:    Gigabit Ethernet Adapters, Common Modules
- * Version:    $Revision: 1.92 $
- * Date:       $Date: 2003/09/16 14:37:07 $
- * Purpose:    Special IRQ module
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect.
- *     (C)Copyright 2002-2003 Marvell.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/*
- *     Special Interrupt handler
- *
- *     The following abstract should show how this module is included
- *     in the driver path:
- *
- *     In the ISR of the driver the bits for frame transmission complete and
- *     for receive complete are checked and handled by the driver itself.
- *     The bits of the slow path mask are checked after that and then the
- *     entry into the so-called "slow path" is prepared. It is an implementors
- *     decision whether this is executed directly or just scheduled by
- *     disabling the mask. In the interrupt service routine some events may be
- *     generated, so it would be a good idea to call the EventDispatcher
- *     right after this ISR.
- *
- *     The Interrupt source register of the adapter is NOT read by this module.
- *  SO if the drivers implementor needs a while loop around the
- *     slow data paths interrupt bits, he needs to call the SkGeSirqIsr() for
- *     each loop entered.
- *
- *     However, the MAC Interrupt status registers are read in a while loop.
- *
- */
-
-#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
-static const char SysKonnectFileId[] =
-       "@(#) $Id: skgesirq.c,v 1.92 2003/09/16 14:37:07 rschmidt Exp $ (C) Marvell.";
-#endif
-
-#include "h/skdrv1st.h"                /* Driver Specific Definitions */
-#ifndef SK_SLIM
-#include "h/skgepnmi.h"                /* PNMI Definitions */
-#include "h/skrlmt.h"          /* RLMT Definitions */
-#endif
-#include "h/skdrv2nd.h"                /* Adapter Control and Driver specific Def. */
-
-/* local function prototypes */
-#ifdef GENESIS
-static int     SkGePortCheckUpXmac(SK_AC*, SK_IOC, int, SK_BOOL);
-static int     SkGePortCheckUpBcom(SK_AC*, SK_IOC, int, SK_BOOL);
-static void    SkPhyIsrBcom(SK_AC*, SK_IOC, int, SK_U16);
-#endif /* GENESIS */
-#ifdef YUKON
-static int     SkGePortCheckUpGmac(SK_AC*, SK_IOC, int, SK_BOOL);
-static void    SkPhyIsrGmac(SK_AC*, SK_IOC, int, SK_U16);
-#endif /* YUKON */
-#ifdef OTHER_PHY
-static int     SkGePortCheckUpLone(SK_AC*, SK_IOC, int, SK_BOOL);
-static int     SkGePortCheckUpNat(SK_AC*, SK_IOC, int, SK_BOOL);
-static void    SkPhyIsrLone(SK_AC*, SK_IOC, int, SK_U16);
-#endif /* OTHER_PHY */
-
-#ifdef GENESIS
-/*
- * array of Rx counter from XMAC which are checked
- * in AutoSense mode to check whether a link is not able to auto-negotiate.
- */
-static const SK_U16 SkGeRxRegs[]= {
-       XM_RXF_64B,
-       XM_RXF_127B,
-       XM_RXF_255B,
-       XM_RXF_511B,
-       XM_RXF_1023B,
-       XM_RXF_MAX_SZ
-} ;
-#endif /* GENESIS */
-
-#ifdef __C2MAN__
-/*
- *     Special IRQ function
- *
- *     General Description:
- *
- */
-intro()
-{}
-#endif
-
-/******************************************************************************
- *
- *     SkHWInitDefSense() - Default Autosensing mode initialization
- *
- * Description: sets the PLinkMode for HWInit
- *
- * Returns: N/A
- */
-static void SkHWInitDefSense(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* IO context */
-int            Port)   /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       pPrt->PAutoNegTimeOut = 0;
-
-       if (pPrt->PLinkModeConf != SK_LMODE_AUTOSENSE) {
-               pPrt->PLinkMode = pPrt->PLinkModeConf;
-               return;
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-               ("AutoSensing: First mode %d on Port %d\n",
-               (int)SK_LMODE_AUTOFULL, Port));
-
-       pPrt->PLinkMode = (SK_U8)SK_LMODE_AUTOFULL;
-
-       return;
-}      /* SkHWInitDefSense */
-
-
-#ifdef GENESIS
-/******************************************************************************
- *
- *     SkHWSenseGetNext() - Get Next Autosensing Mode
- *
- * Description: gets the appropriate next mode
- *
- * Note:
- *
- */
-static SK_U8 SkHWSenseGetNext(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* IO context */
-int            Port)   /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       pPrt->PAutoNegTimeOut = 0;
-
-    if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) {
-               /* Leave all as configured */
-               return(pPrt->PLinkModeConf);
-       }
-
-    if (pPrt->PLinkMode == (SK_U8)SK_LMODE_AUTOFULL) {
-               /* Return next mode AUTOBOTH */
-        return ((SK_U8)SK_LMODE_AUTOBOTH);
-       }
-
-       /* Return default autofull */
-    return ((SK_U8)SK_LMODE_AUTOFULL);
-}      /* SkHWSenseGetNext */
-
-
-/******************************************************************************
- *
- *     SkHWSenseSetNext() - Autosensing Set next mode
- *
- * Description:        sets the appropriate next mode
- *
- * Returns: N/A
- */
-static void SkHWSenseSetNext(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-SK_U8  NewMode)        /* New Mode to be written in sense mode */
-{
-       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       pPrt->PAutoNegTimeOut = 0;
-
-    if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) {
-               return;
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-               ("AutoSensing: next mode %d on Port %d\n",
-               (int)NewMode, Port));
-
-       pPrt->PLinkMode = NewMode;
-
-       return;
-}      /* SkHWSenseSetNext */
-#endif /* GENESIS */
-
-
-/******************************************************************************
- *
- *     SkHWLinkDown() - Link Down handling
- *
- * Description: handles the hardware link down signal
- *
- * Returns: N/A
- */
-void SkHWLinkDown(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       /* Disable all MAC interrupts */
-       SkMacIrqDisable(pAC, IoC, Port);
-
-       /* Disable Receiver and Transmitter */
-       SkMacRxTxDisable(pAC, IoC, Port);
-       
-       /* Init default sense mode */
-       SkHWInitDefSense(pAC, IoC, Port);
-
-       if (pPrt->PHWLinkUp == SK_FALSE) {
-               return;
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-               ("Link down Port %d\n", Port));
-
-       /* Set Link to DOWN */
-       pPrt->PHWLinkUp = SK_FALSE;
-
-       /* Reset Port stati */
-    pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
-    pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE;
-       pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_INDETERMINATED;
-
-       /* Re-init Phy especially when the AutoSense default is set now */
-       SkMacInitPhy(pAC, IoC, Port, SK_FALSE);
-
-       /* GP0: used for workaround of Rev. C Errata 2 */
-
-       /* Do NOT signal to RLMT */
-
-       /* Do NOT start the timer here */
-}      /* SkHWLinkDown */
-
-
-/******************************************************************************
- *
- *     SkHWLinkUp() - Link Up handling
- *
- * Description: handles the hardware link up signal
- *
- * Returns: N/A
- */
-static void SkHWLinkUp(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* IO context */
-int            Port)   /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       if (pPrt->PHWLinkUp) {
-               /* We do NOT need to proceed on active link */
-               return;
-       }
-
-       pPrt->PHWLinkUp = SK_TRUE;
-       pPrt->PAutoNegFail = SK_FALSE;
-    pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
-
-    if (pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOHALF &&
-        pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOFULL &&
-        pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOBOTH) {
-               /* Link is up and no Auto-negotiation should be done */
-
-               /* Link speed should be the configured one */
-               switch (pPrt->PLinkSpeed) {
-               case SK_LSPEED_AUTO:
-                       /* default is 1000 Mbps */
-               case SK_LSPEED_1000MBPS:
-                       pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
-                       break;
-               case SK_LSPEED_100MBPS:
-                       pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_100MBPS;
-                       break;
-               case SK_LSPEED_10MBPS:
-                       pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_10MBPS;
-                       break;
-               }
-
-               /* Set Link Mode Status */
-               if (pPrt->PLinkMode == SK_LMODE_FULL) {
-                       pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_FULL;
-               }
-               else {
-            pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_HALF;
-               }
-
-               /* No flow control without auto-negotiation */
-        pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE;
-
-               /* enable Rx/Tx */
-        (void)SkMacRxTxEnable(pAC, IoC, Port);
-       }
-}      /* SkHWLinkUp */
-
-
-/******************************************************************************
- *
- *     SkMacParity() - MAC parity workaround
- *
- * Description: handles MAC parity errors correctly
- *
- * Returns: N/A
- */
-static void SkMacParity(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* IO context */
-int            Port)   /* Port Index of the port failed */
-{
-       SK_EVPARA       Para;
-       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
-       SK_U32          TxMax;          /* Tx Max Size Counter */
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       /* Clear IRQ Tx Parity Error */
-#ifdef GENESIS
-       if (pAC->GIni.GIGenesis) {
-
-               SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_PERR);
-       }
-#endif /* GENESIS */
-       
-#ifdef YUKON
-       if (pAC->GIni.GIYukon) {
-               /* HW-Bug #8: cleared by GMF_CLI_TX_FC instead of GMF_CLI_TX_PE */
-               SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T),
-                       (SK_U8)((pAC->GIni.GIChipId == CHIP_ID_YUKON &&
-                       pAC->GIni.GIChipRev == 0) ? GMF_CLI_TX_FC : GMF_CLI_TX_PE));
-       }
-#endif /* YUKON */
-       
-       if (pPrt->PCheckPar) {
-
-               if (Port == MAC_1) {
-                       SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E016, SKERR_SIRQ_E016MSG);
-               }
-               else {
-                       SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E017, SKERR_SIRQ_E017MSG);
-               }
-               Para.Para64 = Port;
-               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
-               
-               Para.Para32[0] = Port;
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
-
-               return;
-       }
-
-       /* Check whether frames with a size of 1k were sent */
-#ifdef GENESIS
-       if (pAC->GIni.GIGenesis) {
-               /* Snap statistic counters */
-               (void)SkXmUpdateStats(pAC, IoC, Port);
-               
-               (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXF_MAX_SZ, &TxMax);
-       }
-#endif /* GENESIS */
-       
-#ifdef YUKON
-       if (pAC->GIni.GIYukon) {
-
-               (void)SkGmMacStatistic(pAC, IoC, Port, GM_TXF_1518B, &TxMax);
-       }
-#endif /* YUKON */
-       
-       if (TxMax > 0) {
-               /* From now on check the parity */
-               pPrt->PCheckPar = SK_TRUE;
-       }
-}      /* SkMacParity */
-
-
-/******************************************************************************
- *
- *     SkGeHwErr() - Hardware Error service routine
- *
- * Description: handles all HW Error interrupts
- *
- * Returns: N/A
- */
-static void SkGeHwErr(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-SK_U32 HwStatus)       /* Interrupt status word */
-{
-       SK_EVPARA       Para;
-       SK_U16          Word;
-
-       if ((HwStatus & (IS_IRQ_MST_ERR | IS_IRQ_STAT)) != 0) {
-               /* PCI Errors occured */
-               if ((HwStatus & IS_IRQ_STAT) != 0) {
-                       SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E013, SKERR_SIRQ_E013MSG);
-               }
-               else {
-                       SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E012, SKERR_SIRQ_E012MSG);
-               }
-
-               /* Reset all bits in the PCI STATUS register */
-               SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);
-               
-               SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
-        SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS));
-               SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
-
-               Para.Para64 = 0;
-               SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
-       }
-
-#ifdef GENESIS
-       if (pAC->GIni.GIGenesis) {
-
-               if ((HwStatus & IS_NO_STAT_M1) != 0) {
-                       /* Ignore it */
-                       /* This situation is also indicated in the descriptor */
-                       SK_OUT16(IoC, MR_ADDR(MAC_1, RX_MFF_CTRL1), MFF_CLR_INSTAT);
-               }
-
-               if ((HwStatus & IS_NO_STAT_M2) != 0) {
-                       /* Ignore it */
-                       /* This situation is also indicated in the descriptor */
-                       SK_OUT16(IoC, MR_ADDR(MAC_2, RX_MFF_CTRL1), MFF_CLR_INSTAT);
-               }
-
-               if ((HwStatus & IS_NO_TIST_M1) != 0) {
-                       /* Ignore it */
-                       /* This situation is also indicated in the descriptor */
-                       SK_OUT16(IoC, MR_ADDR(MAC_1, RX_MFF_CTRL1), MFF_CLR_INTIST);
-               }
-
-               if ((HwStatus & IS_NO_TIST_M2) != 0) {
-                       /* Ignore it */
-                       /* This situation is also indicated in the descriptor */
-                       SK_OUT16(IoC, MR_ADDR(MAC_2, RX_MFF_CTRL1), MFF_CLR_INTIST);
-               }
-       }
-#endif /* GENESIS */
-       
-#ifdef YUKON
-       if (pAC->GIni.GIYukon) {
-               /* This is necessary only for Rx timing measurements */
-               if ((HwStatus & IS_IRQ_TIST_OV) != 0) {
-                       /* increment Time Stamp Timer counter (high) */
-                       pAC->GIni.GITimeStampCnt++;
-
-                       /* Clear Time Stamp Timer IRQ */
-                       SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8)GMT_ST_CLR_IRQ);
-               }
-
-               if ((HwStatus & IS_IRQ_SENSOR) != 0) {
-                       /* no sensors on 32-bit Yukon */
-                       if (pAC->GIni.GIYukon32Bit) {
-                               /* disable HW Error IRQ */
-                               pAC->GIni.GIValIrqMask &= ~IS_HW_ERR;
-                       }
-               }
-       }
-#endif /* YUKON */
-
-       if ((HwStatus & IS_RAM_RD_PAR) != 0) {
-               SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_RD_PERR);
-               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E014, SKERR_SIRQ_E014MSG);
-               Para.Para64 = 0;
-               SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
-       }
-
-       if ((HwStatus & IS_RAM_WR_PAR) != 0) {
-               SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_WR_PERR);
-               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E015, SKERR_SIRQ_E015MSG);
-               Para.Para64 = 0;
-               SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
-       }
-
-       if ((HwStatus & IS_M1_PAR_ERR) != 0) {
-               SkMacParity(pAC, IoC, MAC_1);
-       }
-
-       if ((HwStatus & IS_M2_PAR_ERR) != 0) {
-               SkMacParity(pAC, IoC, MAC_2);
-       }
-
-       if ((HwStatus & IS_R1_PAR_ERR) != 0) {
-               /* Clear IRQ */
-               SK_OUT32(IoC, B0_R1_CSR, CSR_IRQ_CL_P);
-
-               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E018, SKERR_SIRQ_E018MSG);
-               Para.Para64 = MAC_1;
-               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
-               
-               Para.Para32[0] = MAC_1;
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
-       }
-
-       if ((HwStatus & IS_R2_PAR_ERR) != 0) {
-               /* Clear IRQ */
-               SK_OUT32(IoC, B0_R2_CSR, CSR_IRQ_CL_P);
-
-               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E019, SKERR_SIRQ_E019MSG);
-               Para.Para64 = MAC_2;
-               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
-               
-               Para.Para32[0] = MAC_2;
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
-       }
-}      /* SkGeHwErr */
-
-
-/******************************************************************************
- *
- *     SkGeSirqIsr() - Special Interrupt Service Routine
- *
- * Description: handles all non data transfer specific interrupts (slow path)
- *
- * Returns: N/A
- */
-void SkGeSirqIsr(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-SK_U32 Istatus)        /* Interrupt status word */
-{
-       SK_EVPARA       Para;
-       SK_U32          RegVal32;       /* Read register value */
-       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
-       SK_U16          PhyInt;
-       int                     i;
-
-       if (((Istatus & IS_HW_ERR) & pAC->GIni.GIValIrqMask) != 0) {
-               /* read the HW Error Interrupt source */
-               SK_IN32(IoC, B0_HWE_ISRC, &RegVal32);
-               
-               SkGeHwErr(pAC, IoC, RegVal32);
-       }
-
-       /*
-        * Packet Timeout interrupts
-        */
-       /* Check whether MACs are correctly initialized */
-       if (((Istatus & (IS_PA_TO_RX1 | IS_PA_TO_TX1)) != 0) &&
-               pAC->GIni.GP[MAC_1].PState == SK_PRT_RESET) {
-               /* MAC 1 was not initialized but Packet timeout occured */
-               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E004,
-                       SKERR_SIRQ_E004MSG);
-       }
-
-       if (((Istatus & (IS_PA_TO_RX2 | IS_PA_TO_TX2)) != 0) &&
-           pAC->GIni.GP[MAC_2].PState == SK_PRT_RESET) {
-               /* MAC 2 was not initialized but Packet timeout occured */
-               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E005,
-                       SKERR_SIRQ_E005MSG);
-       }
-
-       if ((Istatus & IS_PA_TO_RX1) != 0) {
-               /* Means network is filling us up */
-               SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E002,
-                       SKERR_SIRQ_E002MSG);
-               SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_RX1);
-       }
-
-       if ((Istatus & IS_PA_TO_RX2) != 0) {
-               /* Means network is filling us up */
-               SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E003,
-                       SKERR_SIRQ_E003MSG);
-               SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_RX2);
-       }
-
-       if ((Istatus & IS_PA_TO_TX1) != 0) {
-               
-               pPrt = &pAC->GIni.GP[0];
-
-               /* May be a normal situation in a server with a slow network */
-               SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX1);
-
-#ifdef GENESIS
-               if (pAC->GIni.GIGenesis) {
-                       /*
-                        * workaround: if in half duplex mode, check for Tx hangup.
-                        * Read number of TX'ed bytes, wait for 10 ms, then compare
-                        * the number with current value. If nothing changed, we assume
-                        * that Tx is hanging and do a FIFO flush (see event routine).
-                        */
-                       if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF ||
-                               pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) &&
-                               !pPrt->HalfDupTimerActive) {
-                               /*
-                                * many more pack. arb. timeouts may come in between,
-                                * we ignore those
-                                */
-                               pPrt->HalfDupTimerActive = SK_TRUE;
-                               /* Snap statistic counters */
-                               (void)SkXmUpdateStats(pAC, IoC, 0);
-
-                               (void)SkXmMacStatistic(pAC, IoC, 0, XM_TXO_OK_HI, &RegVal32);
-
-                               pPrt->LastOctets = (SK_U64)RegVal32 << 32;
-                               
-                               (void)SkXmMacStatistic(pAC, IoC, 0, XM_TXO_OK_LO, &RegVal32);
-
-                               pPrt->LastOctets += RegVal32;
-                               
-                               Para.Para32[0] = 0;
-                               SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME,
-                                       SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para);
-                       }
-               }
-#endif /* GENESIS */
-       }
-
-       if ((Istatus & IS_PA_TO_TX2) != 0) {
-               
-               pPrt = &pAC->GIni.GP[1];
-
-               /* May be a normal situation in a server with a slow network */
-               SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX2);
-
-#ifdef GENESIS
-               if (pAC->GIni.GIGenesis) {
-                       /* workaround: see above */
-                       if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF ||
-                                pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) &&
-                               !pPrt->HalfDupTimerActive) {
-                               pPrt->HalfDupTimerActive = SK_TRUE;
-                               /* Snap statistic counters */
-                               (void)SkXmUpdateStats(pAC, IoC, 1);
-
-                               (void)SkXmMacStatistic(pAC, IoC, 1, XM_TXO_OK_HI, &RegVal32);
-
-                               pPrt->LastOctets = (SK_U64)RegVal32 << 32;
-                               
-                               (void)SkXmMacStatistic(pAC, IoC, 1, XM_TXO_OK_LO, &RegVal32);
-
-                               pPrt->LastOctets += RegVal32;
-                               
-                               Para.Para32[0] = 1;
-                               SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME,
-                                       SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para);
-                       }
-               }
-#endif /* GENESIS */
-       }
-
-       /* Check interrupts of the particular queues */
-       if ((Istatus & IS_R1_C) != 0) {
-               /* Clear IRQ */
-               SK_OUT32(IoC, B0_R1_CSR, CSR_IRQ_CL_C);
-               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E006,
-                       SKERR_SIRQ_E006MSG);
-               Para.Para64 = MAC_1;
-               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
-               Para.Para32[0] = MAC_1;
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
-       }
-
-       if ((Istatus & IS_R2_C) != 0) {
-               /* Clear IRQ */
-               SK_OUT32(IoC, B0_R2_CSR, CSR_IRQ_CL_C);
-               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E007,
-                       SKERR_SIRQ_E007MSG);
-               Para.Para64 = MAC_2;
-               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
-               Para.Para32[0] = MAC_2;
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
-       }
-
-       if ((Istatus & IS_XS1_C) != 0) {
-               /* Clear IRQ */
-               SK_OUT32(IoC, B0_XS1_CSR, CSR_IRQ_CL_C);
-               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E008,
-                       SKERR_SIRQ_E008MSG);
-               Para.Para64 = MAC_1;
-               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
-               Para.Para32[0] = MAC_1;
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
-       }
-
-       if ((Istatus & IS_XA1_C) != 0) {
-               /* Clear IRQ */
-               SK_OUT32(IoC, B0_XA1_CSR, CSR_IRQ_CL_C);
-               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E009,
-                       SKERR_SIRQ_E009MSG);
-               Para.Para64 = MAC_1;
-               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
-               Para.Para32[0] = MAC_1;
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
-       }
-
-       if ((Istatus & IS_XS2_C) != 0) {
-               /* Clear IRQ */
-               SK_OUT32(IoC, B0_XS2_CSR, CSR_IRQ_CL_C);
-               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E010,
-                       SKERR_SIRQ_E010MSG);
-               Para.Para64 = MAC_2;
-               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
-               Para.Para32[0] = MAC_2;
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
-       }
-
-       if ((Istatus & IS_XA2_C) != 0) {
-               /* Clear IRQ */
-               SK_OUT32(IoC, B0_XA2_CSR, CSR_IRQ_CL_C);
-               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E011,
-                       SKERR_SIRQ_E011MSG);
-               Para.Para64 = MAC_2;
-               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
-               Para.Para32[0] = MAC_2;
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
-       }
-
-       /* External reg interrupt */
-       if ((Istatus & IS_EXT_REG) != 0) {
-               /* Test IRQs from PHY */
-               for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
-                       
-                       pPrt = &pAC->GIni.GP[i];
-                       
-                       if (pPrt->PState == SK_PRT_RESET) {
-                               continue;
-                       }
-                       
-#ifdef GENESIS
-                       if (pAC->GIni.GIGenesis) {
-                               
-                               switch (pPrt->PhyType) {
-                               
-                               case SK_PHY_XMAC:
-                                       break;
-                               
-                               case SK_PHY_BCOM:
-                                       SkXmPhyRead(pAC, IoC, i, PHY_BCOM_INT_STAT, &PhyInt);
-       
-                                       if ((PhyInt & ~PHY_B_DEF_MSK) != 0) {
-                                               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-                                                       ("Port %d Bcom Int: 0x%04X\n",
-                                                       i, PhyInt));
-                                               SkPhyIsrBcom(pAC, IoC, i, PhyInt);
-                                       }
-                                       break;
-#ifdef OTHER_PHY
-                               case SK_PHY_LONE:
-                                       SkXmPhyRead(pAC, IoC, i, PHY_LONE_INT_STAT, &PhyInt);
-                                       
-                                       if ((PhyInt & PHY_L_DEF_MSK) != 0) {
-                                               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-                                                       ("Port %d Lone Int: %x\n",
-                                                       i, PhyInt));
-                                               SkPhyIsrLone(pAC, IoC, i, PhyInt);
-                                       }
-                                       break;
-#endif /* OTHER_PHY */
-                               }
-                       }
-#endif /* GENESIS */
-       
-#ifdef YUKON
-                       if (pAC->GIni.GIYukon) {
-                               /* Read PHY Interrupt Status */
-                               SkGmPhyRead(pAC, IoC, i, PHY_MARV_INT_STAT, &PhyInt);
-
-                               if ((PhyInt & PHY_M_DEF_MSK) != 0) {
-                                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-                                               ("Port %d Marv Int: 0x%04X\n",
-                                               i, PhyInt));
-                                       SkPhyIsrGmac(pAC, IoC, i, PhyInt);
-                               }
-                       }
-#endif /* YUKON */
-               }
-       }
-
-       /* I2C Ready interrupt */
-       if ((Istatus & IS_I2C_READY) != 0) {
-#ifdef SK_SLIM
-        SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
-#else          
-               SkI2cIsr(pAC, IoC);
-#endif         
-       }
-
-       /* SW forced interrupt */
-       if ((Istatus & IS_IRQ_SW) != 0) {
-               /* clear the software IRQ */
-               SK_OUT8(IoC, B0_CTST, CS_CL_SW_IRQ);
-       }
-
-       if ((Istatus & IS_LNK_SYNC_M1) != 0) {
-               /*
-                * We do NOT need the Link Sync interrupt, because it shows
-                * us only a link going down.
-                */
-               /* clear interrupt */
-               SK_OUT8(IoC, MR_ADDR(MAC_1, LNK_SYNC_CTRL), LED_CLR_IRQ);
-       }
-
-       /* Check MAC after link sync counter */
-       if ((Istatus & IS_MAC1) != 0) {
-               /* IRQ from MAC 1 */
-               SkMacIrq(pAC, IoC, MAC_1);
-       }
-
-       if ((Istatus & IS_LNK_SYNC_M2) != 0) {
-               /*
-                * We do NOT need the Link Sync interrupt, because it shows
-                * us only a link going down.
-                */
-               /* clear interrupt */
-               SK_OUT8(IoC, MR_ADDR(MAC_2, LNK_SYNC_CTRL), LED_CLR_IRQ);
-       }
-
-       /* Check MAC after link sync counter */
-       if ((Istatus & IS_MAC2) != 0) {
-               /* IRQ from MAC 2 */
-               SkMacIrq(pAC, IoC, MAC_2);
-       }
-
-       /* Timer interrupt (served last) */
-       if ((Istatus & IS_TIMINT) != 0) {
-               /* check for HW Errors */
-               if (((Istatus & IS_HW_ERR) & ~pAC->GIni.GIValIrqMask) != 0) {
-                       /* read the HW Error Interrupt source */
-                       SK_IN32(IoC, B0_HWE_ISRC, &RegVal32);
-
-                       SkGeHwErr(pAC, IoC, RegVal32);
-               }
-
-               SkHwtIsr(pAC, IoC);
-       }
-
-}      /* SkGeSirqIsr */
-
-
-#ifdef GENESIS
-/******************************************************************************
- *
- * SkGePortCheckShorts() - Implementing XMAC Workaround Errata # 2
- *
- * return:
- *     0       o.k. nothing needed
- *     1       Restart needed on this port
- */
-static int SkGePortCheckShorts(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* IO Context */
-int            Port)           /* Which port should be checked */
-{
-       SK_U32          Shorts;                 /* Short Event Counter */
-       SK_U32          CheckShorts;    /* Check value for Short Event Counter */
-       SK_U64          RxCts;                  /* Rx Counter (packets on network) */
-       SK_U32          RxTmp;                  /* Rx temp. Counter */
-       SK_U32          FcsErrCts;              /* FCS Error Counter */
-       SK_GEPORT       *pPrt;                  /* GIni Port struct pointer */
-       int                     Rtv;                    /* Return value */
-       int                     i;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       /* Default: no action */
-       Rtv = SK_HW_PS_NONE;
-
-       (void)SkXmUpdateStats(pAC, IoC, Port);
-
-       /* Extra precaution: check for short Event counter */
-       (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXE_SHT_ERR, &Shorts);
-
-       /*
-        * Read Rx counters (packets seen on the network and not necessarily
-        * really received.
-        */
-       RxCts = 0;
-
-       for (i = 0; i < sizeof(SkGeRxRegs)/sizeof(SkGeRxRegs[0]); i++) {
-               
-               (void)SkXmMacStatistic(pAC, IoC, Port, SkGeRxRegs[i], &RxTmp);
-               
-               RxCts += (SK_U64)RxTmp;
-       }
-
-       /* On default: check shorts against zero */
-       CheckShorts = 0;
-
-       /* Extra precaution on active links */
-       if (pPrt->PHWLinkUp) {
-               /* Reset Link Restart counter */
-               pPrt->PLinkResCt = 0;
-               pPrt->PAutoNegTOCt = 0;
-
-               /* If link is up check for 2 */
-               CheckShorts = 2;
-
-               (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXF_FCS_ERR, &FcsErrCts);
-               
-               if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
-                   pPrt->PLipaAutoNeg == SK_LIPA_UNKNOWN &&
-                   (pPrt->PLinkMode == SK_LMODE_HALF ||
-                        pPrt->PLinkMode == SK_LMODE_FULL)) {
-                       /*
-                        * This is autosensing and we are in the fallback
-                        * manual full/half duplex mode.
-                        */
-                       if (RxCts == pPrt->PPrevRx) {
-                               /* Nothing received, restart link */
-                               pPrt->PPrevFcs = FcsErrCts;
-                               pPrt->PPrevShorts = Shorts;
-                               
-                               return(SK_HW_PS_RESTART);
-                       }
-                       else {
-                               pPrt->PLipaAutoNeg = SK_LIPA_MANUAL;
-                       }
-               }
-
-               if (((RxCts - pPrt->PPrevRx) > pPrt->PRxLim) ||
-                   (!(FcsErrCts - pPrt->PPrevFcs))) {
-                       /*
-                        * Note: The compare with zero above has to be done the way shown,
-                        * otherwise the Linux driver will have a problem.
-                        */
-                       /*
-                        * We received a bunch of frames or no CRC error occured on the
-                        * network -> ok.
-                        */
-                       pPrt->PPrevRx = RxCts;
-                       pPrt->PPrevFcs = FcsErrCts;
-                       pPrt->PPrevShorts = Shorts;
-
-                       return(SK_HW_PS_NONE);
-               }
-
-               pPrt->PPrevFcs = FcsErrCts;
-       }
-
-
-       if ((Shorts - pPrt->PPrevShorts) > CheckShorts) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-                       ("Short Event Count Restart Port %d \n", Port));
-               Rtv = SK_HW_PS_RESTART;
-       }
-
-       pPrt->PPrevShorts = Shorts;
-       pPrt->PPrevRx = RxCts;
-
-       return(Rtv);
-}      /* SkGePortCheckShorts */
-#endif /* GENESIS */
-
-
-/******************************************************************************
- *
- * SkGePortCheckUp() - Check if the link is up
- *
- * return:
- *     0       o.k. nothing needed
- *     1       Restart needed on this port
- *     2       Link came up
- */
-static int SkGePortCheckUp(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* IO Context */
-int            Port)           /* Which port should be checked */
-{
-       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
-       SK_BOOL         AutoNeg;        /* Is Auto-negotiation used ? */
-       int                     Rtv;            /* Return value */
-
-       Rtv = SK_HW_PS_NONE;
-       
-       pPrt = &pAC->GIni.GP[Port];
-
-       if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
-               AutoNeg = SK_FALSE;
-       }
-       else {
-               AutoNeg = SK_TRUE;
-       }
-
-#ifdef GENESIS
-       if (pAC->GIni.GIGenesis) {
-
-               switch (pPrt->PhyType) {
-               
-               case SK_PHY_XMAC:
-                       Rtv = SkGePortCheckUpXmac(pAC, IoC, Port, AutoNeg);
-                       break;
-               case SK_PHY_BCOM:
-                       Rtv = SkGePortCheckUpBcom(pAC, IoC, Port, AutoNeg);
-                       break;
-#ifdef OTHER_PHY
-               case SK_PHY_LONE:
-                       Rtv = SkGePortCheckUpLone(pAC, IoC, Port, AutoNeg);
-                       break;
-               case SK_PHY_NAT:
-                       Rtv = SkGePortCheckUpNat(pAC, IoC, Port, AutoNeg);
-                       break;
-#endif /* OTHER_PHY */
-               }
-       }
-#endif /* GENESIS */
-       
-#ifdef YUKON
-       if (pAC->GIni.GIYukon) {
-               
-               Rtv = SkGePortCheckUpGmac(pAC, IoC, Port, AutoNeg);
-       }
-#endif /* YUKON */
-
-       return(Rtv);    
-}      /* SkGePortCheckUp */
-
-
-#ifdef GENESIS
-/******************************************************************************
- *
- * SkGePortCheckUpXmac() - Implementing of the Workaround Errata # 2
- *
- * return:
- *     0       o.k. nothing needed
- *     1       Restart needed on this port
- *     2       Link came up
- */
-static int SkGePortCheckUpXmac(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* IO Context */
-int            Port,           /* Which port should be checked */
-SK_BOOL        AutoNeg)        /* Is Auto-negotiation used ? */
-{
-       SK_U32          Shorts;         /* Short Event Counter */
-       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
-       int                     Done;
-       SK_U32          GpReg;          /* General Purpose register value */
-       SK_U16          Isrc;           /* Interrupt source register */
-       SK_U16          IsrcSum;        /* Interrupt source register sum */
-       SK_U16          LpAb;           /* Link Partner Ability */
-       SK_U16          ResAb;          /* Resolved Ability */
-       SK_U16          ExtStat;        /* Extended Status Register */
-       SK_U8           NextMode;       /* Next AutoSensing Mode */
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       if (pPrt->PHWLinkUp) {
-               if (pPrt->PhyType != SK_PHY_XMAC) {
-                       return(SK_HW_PS_NONE);
-               }
-               else {
-                       return(SkGePortCheckShorts(pAC, IoC, Port));
-               }
-       }
-
-       IsrcSum = pPrt->PIsave;
-       pPrt->PIsave = 0;
-
-       /* Now wait for each port's link */
-       if (pPrt->PLinkBroken) {
-               /* Link was broken */
-               XM_IN32(IoC, Port, XM_GP_PORT, &GpReg);
-
-               if ((GpReg & XM_GP_INP_ASS) == 0) {
-                       /* The Link is in sync */
-                       XM_IN16(IoC, Port, XM_ISRC, &Isrc);
-                       IsrcSum |= Isrc;
-                       SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum);
-                       
-                       if ((Isrc & XM_IS_INP_ASS) == 0) {
-                               /* It has been in sync since last time */
-                               /* Restart the PORT */
-                               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-                                       ("Link in sync Restart Port %d\n", Port));
-
-                               (void)SkXmUpdateStats(pAC, IoC, Port);
-
-                               /* We now need to reinitialize the PrevShorts counter */
-                               (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXE_SHT_ERR, &Shorts);
-                               pPrt->PPrevShorts = Shorts;
-
-                               pPrt->PLinkBroken = SK_FALSE;
-
-                               /*
-                                * Link Restart Workaround:
-                                *  it may be possible that the other Link side
-                                *  restarts its link as well an we detect
-                                *  another LinkBroken. To prevent this
-                                *  happening we check for a maximum number
-                                *  of consecutive restart. If those happens,
-                                *  we do NOT restart the active link and
-                                *  check whether the link is now o.k.
-                                */
-                               pPrt->PLinkResCt++;
-                               
-                               pPrt->PAutoNegTimeOut = 0;
-
-                               if (pPrt->PLinkResCt < SK_MAX_LRESTART) {
-                                       return(SK_HW_PS_RESTART);
-                               }
-
-                               pPrt->PLinkResCt = 0;
-                               
-                               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                                       ("Do NOT restart on Port %d %x %x\n", Port, Isrc, IsrcSum));
-                       }
-                       else {
-                               pPrt->PIsave = (SK_U16)(IsrcSum & XM_IS_AND);
-                               
-                               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                                       ("Save Sync/nosync Port %d %x %x\n", Port, Isrc, IsrcSum));
-
-                               /* Do nothing more if link is broken */
-                               return(SK_HW_PS_NONE);
-                       }
-               }
-               else {
-                       /* Do nothing more if link is broken */
-                       return(SK_HW_PS_NONE);
-               }
-
-       }
-       else {
-               /* Link was not broken, check if it is */
-               XM_IN16(IoC, Port, XM_ISRC, &Isrc);
-               IsrcSum |= Isrc;
-               if ((Isrc & XM_IS_INP_ASS) != 0) {
-                       XM_IN16(IoC, Port, XM_ISRC, &Isrc);
-                       IsrcSum |= Isrc;
-                       if ((Isrc & XM_IS_INP_ASS) != 0) {
-                               XM_IN16(IoC, Port, XM_ISRC, &Isrc);
-                               IsrcSum |= Isrc;
-                               if ((Isrc & XM_IS_INP_ASS) != 0) {
-                                       pPrt->PLinkBroken = SK_TRUE;
-                                       /* Re-Init Link partner Autoneg flag */
-                                       pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN;
-                                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-                                               ("Link broken Port %d\n", Port));
-
-                                       /* Cable removed-> reinit sense mode */
-                                       SkHWInitDefSense(pAC, IoC, Port);
-
-                                       return(SK_HW_PS_RESTART);
-                               }
-                       }
-               }
-               else {
-                       SkXmAutoNegLipaXmac(pAC, IoC, Port, Isrc);
-                       
-                       if (SkGePortCheckShorts(pAC, IoC, Port) == SK_HW_PS_RESTART) {
-                               return(SK_HW_PS_RESTART);
-                       }
-               }
-       }
-
-       /*
-        * here we usually can check whether the link is in sync and
-        * auto-negotiation is done.
-        */
-       XM_IN32(IoC, Port, XM_GP_PORT, &GpReg);
-       XM_IN16(IoC, Port, XM_ISRC, &Isrc);
-       IsrcSum |= Isrc;
-
-       SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum);
-       
-       if ((GpReg & XM_GP_INP_ASS) != 0 || (IsrcSum & XM_IS_INP_ASS) != 0) {
-               if ((GpReg & XM_GP_INP_ASS) == 0) {
-                       /* Save Auto-negotiation Done interrupt only if link is in sync */
-                       pPrt->PIsave = (SK_U16)(IsrcSum & XM_IS_AND);
-               }
-#ifdef DEBUG
-               if ((pPrt->PIsave & XM_IS_AND) != 0) {
-                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                               ("AutoNeg done rescheduled Port %d\n", Port));
-               }
-#endif /* DEBUG */
-               return(SK_HW_PS_NONE);
-       }
-
-       if (AutoNeg) {
-               if ((IsrcSum & XM_IS_AND) != 0) {
-                       SkHWLinkUp(pAC, IoC, Port);
-                       Done = SkMacAutoNegDone(pAC, IoC, Port);
-                       if (Done != SK_AND_OK) {
-                               /* Get PHY parameters, for debugging only */
-                               SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_LP, &LpAb);
-                               SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_RES_ABI, &ResAb);
-                               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                                       ("AutoNeg FAIL Port %d (LpAb %x, ResAb %x)\n",
-                                        Port, LpAb, ResAb));
-                                       
-                               /* Try next possible mode */
-                               NextMode = SkHWSenseGetNext(pAC, IoC, Port);
-                               SkHWLinkDown(pAC, IoC, Port);
-                               if (Done == SK_AND_DUP_CAP) {
-                                       /* GoTo next mode */
-                                       SkHWSenseSetNext(pAC, IoC, Port, NextMode);
-                               }
-
-                               return(SK_HW_PS_RESTART);
-                       }
-                       /*
-                        * Dummy Read extended status to prevent extra link down/ups
-                        * (clear Page Received bit if set)
-                        */
-                       SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_EXP, &ExtStat);
-                       
-                       return(SK_HW_PS_LINK);
-               }
-               
-               /* AutoNeg not done, but HW link is up. Check for timeouts */
-               pPrt->PAutoNegTimeOut++;
-               if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) {
-                       /* Increase the Timeout counter */
-                       pPrt->PAutoNegTOCt++;
-
-                       /* Timeout occured */
-                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-                               ("AutoNeg timeout Port %d\n", Port));
-                       if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
-                               pPrt->PLipaAutoNeg != SK_LIPA_AUTO) {
-                               /* Set Link manually up */
-                               SkHWSenseSetNext(pAC, IoC, Port, SK_LMODE_FULL);
-                               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-                                       ("Set manual full duplex Port %d\n", Port));
-                       }
-
-                       if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
-                               pPrt->PLipaAutoNeg == SK_LIPA_AUTO &&
-                               pPrt->PAutoNegTOCt >= SK_MAX_ANEG_TO) {
-                               /*
-                                * This is rather complicated.
-                                * we need to check here whether the LIPA_AUTO
-                                * we saw before is false alert. We saw at one
-                                * switch ( SR8800) that on boot time it sends
-                                * just one auto-neg packet and does no further
-                                * auto-negotiation.
-                                * Solution: we restart the autosensing after
-                                * a few timeouts.
-                                */
-                               pPrt->PAutoNegTOCt = 0;
-                               pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN;
-                               SkHWInitDefSense(pAC, IoC, Port);
-                       }
-
-                       /* Do the restart */
-                       return(SK_HW_PS_RESTART);
-               }
-       }
-       else {
-               /* Link is up and we don't need more */
-#ifdef DEBUG
-               if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
-                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                               ("ERROR: Lipa auto detected on port %d\n", Port));
-               }
-#endif /* DEBUG */
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-                       ("Link sync(GP), Port %d\n", Port));
-               SkHWLinkUp(pAC, IoC, Port);
-               
-               /*
-                * Link sync (GP) and so assume a good connection. But if not received
-                * a bunch of frames received in a time slot (maybe broken tx cable)
-                * the port is restart.
-                */
-               return(SK_HW_PS_LINK);
-       }
-
-       return(SK_HW_PS_NONE);
-}      /* SkGePortCheckUpXmac */
-
-
-/******************************************************************************
- *
- * SkGePortCheckUpBcom() - Check if the link is up on Bcom PHY
- *
- * return:
- *     0       o.k. nothing needed
- *     1       Restart needed on this port
- *     2       Link came up
- */
-static int SkGePortCheckUpBcom(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* IO Context */
-int            Port,           /* Which port should be checked */
-SK_BOOL        AutoNeg)        /* Is Auto-negotiation used ? */
-{
-       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
-       int                     Done;
-       SK_U16          Isrc;           /* Interrupt source register */
-       SK_U16          PhyStat;        /* Phy Status Register */
-       SK_U16          ResAb;          /* Master/Slave resolution */
-       SK_U16          Ctrl;           /* Broadcom control flags */
-#ifdef DEBUG
-       SK_U16          LpAb;
-       SK_U16          ExtStat;
-#endif /* DEBUG */
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       /* Check for No HCD Link events (#10523) */
-       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &Isrc);
-
-#ifdef xDEBUG
-       if ((Isrc & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) ==
-               (PHY_B_IS_SCR_S_ER | PHY_B_IS_RRS_CHANGE | PHY_B_IS_LRS_CHANGE)) {
-
-               SK_U32  Stat1, Stat2, Stat3;
-
-               Stat1 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_MASK, &Stat1);
-               CMSMPrintString(
-                       pAC->pConfigTable,
-                       MSG_TYPE_RUNTIME_INFO,
-                       "CheckUp1 - Stat: %x, Mask: %x",
-                       (void *)Isrc,
-                       (void *)Stat1);
-
-               Stat1 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Stat1);
-               Stat2 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &Stat2);
-               Stat1 = Stat1 << 16 | Stat2;
-               Stat2 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, &Stat2);
-               Stat3 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &Stat3);
-               Stat2 = Stat2 << 16 | Stat3;
-               CMSMPrintString(
-                       pAC->pConfigTable,
-                       MSG_TYPE_RUNTIME_INFO,
-                       "Ctrl/Stat: %x, AN Adv/LP: %x",
-                       (void *)Stat1,
-                       (void *)Stat2);
-
-               Stat1 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_EXP, &Stat1);
-               Stat2 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_EXT_STAT, &Stat2);
-               Stat1 = Stat1 << 16 | Stat2;
-               Stat2 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, &Stat2);
-               Stat3 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &Stat3);
-               Stat2 = Stat2 << 16 | Stat3;
-               CMSMPrintString(
-                       pAC->pConfigTable,
-                       MSG_TYPE_RUNTIME_INFO,
-                       "AN Exp/IEEE Ext: %x, 1000T Ctrl/Stat: %x",
-                       (void *)Stat1,
-                       (void *)Stat2);
-
-               Stat1 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, &Stat1);
-               Stat2 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_STAT, &Stat2);
-               Stat1 = Stat1 << 16 | Stat2;
-               Stat2 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Stat2);
-               Stat3 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &Stat3);
-               Stat2 = Stat2 << 16 | Stat3;
-               CMSMPrintString(
-                       pAC->pConfigTable,
-                       MSG_TYPE_RUNTIME_INFO,
-                       "PHY Ext Ctrl/Stat: %x, Aux Ctrl/Stat: %x",
-                       (void *)Stat1,
-                       (void *)Stat2);
-       }
-#endif /* DEBUG */
-
-       if ((Isrc & (PHY_B_IS_NO_HDCL /* | PHY_B_IS_NO_HDC */)) != 0) {
-               /*
-                * Workaround BCom Errata:
-                *      enable and disable loopback mode if "NO HCD" occurs.
-                */
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Ctrl);
-               SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL,
-                       (SK_U16)(Ctrl | PHY_CT_LOOP));
-               SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL,
-                       (SK_U16)(Ctrl & ~PHY_CT_LOOP));
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("No HCD Link event, Port %d\n", Port));
-#ifdef xDEBUG
-               CMSMPrintString(
-                       pAC->pConfigTable,
-                       MSG_TYPE_RUNTIME_INFO,
-                       "No HCD link event, port %d.",
-                       (void *)Port,
-                       (void *)NULL);
-#endif /* DEBUG */
-       }
-
-       /* Not obsolete: link status bit is latched to 0 and autoclearing! */
-       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat);
-
-       if (pPrt->PHWLinkUp) {
-               return(SK_HW_PS_NONE);
-       }
-
-#ifdef xDEBUG
-       {
-               SK_U32  Stat1, Stat2, Stat3;
-
-               Stat1 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_MASK, &Stat1);
-               CMSMPrintString(
-                       pAC->pConfigTable,
-                       MSG_TYPE_RUNTIME_INFO,
-                       "CheckUp1a - Stat: %x, Mask: %x",
-                       (void *)Isrc,
-                       (void *)Stat1);
-
-               Stat1 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Stat1);
-               Stat2 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat);
-               Stat1 = Stat1 << 16 | PhyStat;
-               Stat2 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, &Stat2);
-               Stat3 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &Stat3);
-               Stat2 = Stat2 << 16 | Stat3;
-               CMSMPrintString(
-                       pAC->pConfigTable,
-                       MSG_TYPE_RUNTIME_INFO,
-                       "Ctrl/Stat: %x, AN Adv/LP: %x",
-                       (void *)Stat1,
-                       (void *)Stat2);
-
-               Stat1 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_EXP, &Stat1);
-               Stat2 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_EXT_STAT, &Stat2);
-               Stat1 = Stat1 << 16 | Stat2;
-               Stat2 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, &Stat2);
-               Stat3 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb);
-               Stat2 = Stat2 << 16 | ResAb;
-               CMSMPrintString(
-                       pAC->pConfigTable,
-                       MSG_TYPE_RUNTIME_INFO,
-                       "AN Exp/IEEE Ext: %x, 1000T Ctrl/Stat: %x",
-                       (void *)Stat1,
-                       (void *)Stat2);
-
-               Stat1 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, &Stat1);
-               Stat2 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_STAT, &Stat2);
-               Stat1 = Stat1 << 16 | Stat2;
-               Stat2 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Stat2);
-               Stat3 = 0;
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &Stat3);
-               Stat2 = Stat2 << 16 | Stat3;
-               CMSMPrintString(
-                       pAC->pConfigTable,
-                       MSG_TYPE_RUNTIME_INFO,
-                       "PHY Ext Ctrl/Stat: %x, Aux Ctrl/Stat: %x",
-                       (void *)Stat1,
-                       (void *)Stat2);
-       }
-#endif /* DEBUG */
-
-       /*
-        * Here we usually can check whether the link is in sync and
-        * auto-negotiation is done.
-        */
-
-       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat);
-
-       SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
-       
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("CheckUp Port %d, PhyStat: 0x%04X\n", Port, PhyStat));
-
-       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb);
-
-       if ((ResAb & PHY_B_1000S_MSF) != 0) {
-               /* Error */
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("Master/Slave Fault port %d\n", Port));
-               
-               pPrt->PAutoNegFail = SK_TRUE;
-               pPrt->PMSStatus = SK_MS_STAT_FAULT;
-               
-               return(SK_HW_PS_RESTART);
-       }
-
-       if ((PhyStat & PHY_ST_LSYNC) == 0) {
-               return(SK_HW_PS_NONE);
-       }
-       
-       pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
-               SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE;
-       
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("Port %d, ResAb: 0x%04X\n", Port, ResAb));
-
-       if (AutoNeg) {
-               if ((PhyStat & PHY_ST_AN_OVER) != 0) {
-                       
-                       SkHWLinkUp(pAC, IoC, Port);
-                       
-                       Done = SkMacAutoNegDone(pAC, IoC, Port);
-                       
-                       if (Done != SK_AND_OK) {
-#ifdef DEBUG
-                               /* Get PHY parameters, for debugging only */
-                               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &LpAb);
-                               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ExtStat);
-                               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                                       ("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n",
-                                       Port, LpAb, ExtStat));
-#endif /* DEBUG */
-                               return(SK_HW_PS_RESTART);
-                       }
-                       else {
-#ifdef xDEBUG
-                               /* Dummy read ISR to prevent extra link downs/ups */
-                               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &ExtStat);
-
-                               if ((ExtStat & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) != 0) {
-                                       CMSMPrintString(
-                                               pAC->pConfigTable,
-                                               MSG_TYPE_RUNTIME_INFO,
-                                               "CheckUp2 - Stat: %x",
-                                               (void *)ExtStat,
-                                               (void *)NULL);
-                               }
-#endif /* DEBUG */
-                               return(SK_HW_PS_LINK);
-                       }
-               }
-       }
-       else {  /* !AutoNeg */
-               /* Link is up and we don't need more. */
-#ifdef DEBUG
-               if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
-                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                               ("ERROR: Lipa auto detected on port %d\n", Port));
-               }
-#endif /* DEBUG */
-
-#ifdef xDEBUG
-               /* Dummy read ISR to prevent extra link downs/ups */
-               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &ExtStat);
-
-               if ((ExtStat & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) != 0) {
-                       CMSMPrintString(
-                               pAC->pConfigTable,
-                               MSG_TYPE_RUNTIME_INFO,
-                               "CheckUp3 - Stat: %x",
-                               (void *)ExtStat,
-                               (void *)NULL);
-               }
-#endif /* DEBUG */
-               
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-                       ("Link sync(GP), Port %d\n", Port));
-               SkHWLinkUp(pAC, IoC, Port);
-               
-               return(SK_HW_PS_LINK);
-       }
-
-       return(SK_HW_PS_NONE);
-}      /* SkGePortCheckUpBcom */
-#endif /* GENESIS */
-
-
-#ifdef YUKON
-/******************************************************************************
- *
- * SkGePortCheckUpGmac() - Check if the link is up on Marvell PHY
- *
- * return:
- *     0       o.k. nothing needed
- *     1       Restart needed on this port
- *     2       Link came up
- */
-static int SkGePortCheckUpGmac(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* IO Context */
-int            Port,           /* Which port should be checked */
-SK_BOOL        AutoNeg)        /* Is Auto-negotiation used ? */
-{
-       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
-       int                     Done;
-       SK_U16          PhyIsrc;        /* PHY Interrupt source */
-       SK_U16          PhyStat;        /* PPY Status */
-       SK_U16          PhySpecStat;/* PHY Specific Status */
-       SK_U16          ResAb;          /* Master/Slave resolution */
-       SK_EVPARA       Para;
-#ifdef DEBUG
-       SK_U16          Word;           /* I/O helper */
-#endif /* DEBUG */
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       if (pPrt->PHWLinkUp) {
-               return(SK_HW_PS_NONE);
-       }
-
-       /* Read PHY Status */
-       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat);
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("CheckUp Port %d, PhyStat: 0x%04X\n", Port, PhyStat));
-
-       /* Read PHY Interrupt Status */
-       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_INT_STAT, &PhyIsrc);
-
-       if ((PhyIsrc & PHY_M_IS_AN_COMPL) != 0) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("Auto-Negotiation Completed, PhyIsrc: 0x%04X\n", PhyIsrc));
-       }
-
-       if ((PhyIsrc & PHY_M_IS_LSP_CHANGE) != 0) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("Link Speed Changed, PhyIsrc: 0x%04X\n", PhyIsrc));
-       }
-
-       SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
-       
-       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb);
-
-       if ((ResAb & PHY_B_1000S_MSF) != 0) {
-               /* Error */
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("Master/Slave Fault port %d\n", Port));
-               
-               pPrt->PAutoNegFail = SK_TRUE;
-               pPrt->PMSStatus = SK_MS_STAT_FAULT;
-               
-               return(SK_HW_PS_RESTART);
-       }
-
-       /* Read PHY Specific Status */
-       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat);
-       
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("Phy1000BT: 0x%04X, PhySpecStat: 0x%04X\n", ResAb, PhySpecStat));
-
-#ifdef DEBUG
-       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_EXP, &Word);
-
-       if ((PhyIsrc & PHY_M_IS_AN_PR) != 0 || (Word & PHY_ANE_RX_PG) != 0 ||
-               (PhySpecStat & PHY_M_PS_PAGE_REC) != 0)  {
-               /* Read PHY Next Page Link Partner */
-               SkGmPhyRead(pAC, IoC, Port, PHY_MARV_NEPG_LP, &Word);
-
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("Page Received, NextPage: 0x%04X\n", Word));
-       }
-#endif /* DEBUG */
-
-       if ((PhySpecStat & PHY_M_PS_LINK_UP) == 0) {
-               return(SK_HW_PS_NONE);
-       }
-       
-       if ((PhySpecStat & PHY_M_PS_DOWNS_STAT) != 0 ||
-               (PhyIsrc & PHY_M_IS_DOWNSH_DET) != 0) {
-               /* Downshift detected */
-               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E025, SKERR_SIRQ_E025MSG);
-               
-               Para.Para64 = Port;
-               SkEventQueue(pAC, SKGE_DRV, SK_DRV_DOWNSHIFT_DET, Para);
-               
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("Downshift detected, PhyIsrc: 0x%04X\n", PhyIsrc));
-       }
-
-       pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
-               SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE;
-       
-       pPrt->PCableLen = (SK_U8)((PhySpecStat & PHY_M_PS_CABLE_MSK) >> 7);
-       
-       if (AutoNeg) {
-               /* Auto-Negotiation Over ? */
-               if ((PhyStat & PHY_ST_AN_OVER) != 0) {
-                       
-                       SkHWLinkUp(pAC, IoC, Port);
-                       
-                       Done = SkMacAutoNegDone(pAC, IoC, Port);
-                       
-                       if (Done != SK_AND_OK) {
-                               return(SK_HW_PS_RESTART);
-                       }
-                       
-                       return(SK_HW_PS_LINK);
-               }
-       }
-       else {  /* !AutoNeg */
-               /* Link is up and we don't need more */
-#ifdef DEBUG
-               if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
-                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                               ("ERROR: Lipa auto detected on port %d\n", Port));
-               }
-#endif /* DEBUG */
-
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-                       ("Link sync, Port %d\n", Port));
-               SkHWLinkUp(pAC, IoC, Port);
-               
-               return(SK_HW_PS_LINK);
-       }
-
-       return(SK_HW_PS_NONE);
-}      /* SkGePortCheckUpGmac */
-#endif /* YUKON */
-
-
-#ifdef OTHER_PHY
-/******************************************************************************
- *
- * SkGePortCheckUpLone() - Check if the link is up on Level One PHY
- *
- * return:
- *     0       o.k. nothing needed
- *     1       Restart needed on this port
- *     2       Link came up
- */
-static int SkGePortCheckUpLone(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* IO Context */
-int            Port,           /* Which port should be checked */
-SK_BOOL        AutoNeg)        /* Is Auto-negotiation used ? */
-{
-       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
-       int                     Done;
-       SK_U16          Isrc;           /* Interrupt source register */
-       SK_U16          LpAb;           /* Link Partner Ability */
-       SK_U16          ExtStat;        /* Extended Status Register */
-       SK_U16          PhyStat;        /* Phy Status Register */
-       SK_U16          StatSum;
-       SK_U8           NextMode;       /* Next AutoSensing Mode */
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       if (pPrt->PHWLinkUp) {
-               return(SK_HW_PS_NONE);
-       }
-
-       StatSum = pPrt->PIsave;
-       pPrt->PIsave = 0;
-
-       /*
-        * here we usually can check whether the link is in sync and
-        * auto-negotiation is done.
-        */
-       SkXmPhyRead(pAC, IoC, Port, PHY_LONE_STAT, &PhyStat);
-       StatSum |= PhyStat;
-
-       SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
-       
-       if ((PhyStat & PHY_ST_LSYNC) == 0) {
-               /* Save Auto-negotiation Done bit */
-               pPrt->PIsave = (SK_U16)(StatSum & PHY_ST_AN_OVER);
-#ifdef DEBUG
-               if ((pPrt->PIsave & PHY_ST_AN_OVER) != 0) {
-                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                               ("AutoNeg done rescheduled Port %d\n", Port));
-               }
-#endif /* DEBUG */
-               return(SK_HW_PS_NONE);
-       }
-
-       if (AutoNeg) {
-               if ((StatSum & PHY_ST_AN_OVER) != 0) {
-                       SkHWLinkUp(pAC, IoC, Port);
-                       Done = SkMacAutoNegDone(pAC, IoC, Port);
-                       if (Done != SK_AND_OK) {
-                               /* Get PHY parameters, for debugging only */
-                               SkXmPhyRead(pAC, IoC, Port, PHY_LONE_AUNE_LP, &LpAb);
-                               SkXmPhyRead(pAC, IoC, Port, PHY_LONE_1000T_STAT, &ExtStat);
-                               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                                       ("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n",
-                                        Port, LpAb, ExtStat));
-                                       
-                               /* Try next possible mode */
-                               NextMode = SkHWSenseGetNext(pAC, IoC, Port);
-                               SkHWLinkDown(pAC, IoC, Port);
-                               if (Done == SK_AND_DUP_CAP) {
-                                       /* GoTo next mode */
-                                       SkHWSenseSetNext(pAC, IoC, Port, NextMode);
-                               }
-
-                               return(SK_HW_PS_RESTART);
-
-                       }
-                       else {
-                               /*
-                                * Dummy Read interrupt status to prevent
-                                * extra link down/ups
-                                */
-                               SkXmPhyRead(pAC, IoC, Port, PHY_LONE_INT_STAT, &ExtStat);
-                               return(SK_HW_PS_LINK);
-                       }
-               }
-               
-               /* AutoNeg not done, but HW link is up. Check for timeouts */
-               pPrt->PAutoNegTimeOut++;
-               if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) {
-                       /* Timeout occured */
-                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-                               ("AutoNeg timeout Port %d\n", Port));
-                       if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
-                               pPrt->PLipaAutoNeg != SK_LIPA_AUTO) {
-                               /* Set Link manually up */
-                               SkHWSenseSetNext(pAC, IoC, Port, SK_LMODE_FULL);
-                               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-                                       ("Set manual full duplex Port %d\n", Port));
-                       }
-
-                       /* Do the restart */
-                       return(SK_HW_PS_RESTART);
-               }
-       }
-       else {
-               /* Link is up and we don't need more */
-#ifdef DEBUG
-               if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
-                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                               ("ERROR: Lipa auto detected on port %d\n", Port));
-               }
-#endif /* DEBUG */
-
-               /*
-                * Dummy Read interrupt status to prevent
-                * extra link down/ups
-                */
-               SkXmPhyRead(pAC, IoC, Port, PHY_LONE_INT_STAT, &ExtStat);
-               
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-                       ("Link sync(GP), Port %d\n", Port));
-               SkHWLinkUp(pAC, IoC, Port);
-               
-               return(SK_HW_PS_LINK);
-       }
-
-       return(SK_HW_PS_NONE);
-}      /* SkGePortCheckUpLone */
-
-
-/******************************************************************************
- *
- * SkGePortCheckUpNat() - Check if the link is up on National PHY
- *
- * return:
- *     0       o.k. nothing needed
- *     1       Restart needed on this port
- *     2       Link came up
- */
-static int SkGePortCheckUpNat(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* IO Context */
-int            Port,           /* Which port should be checked */
-SK_BOOL        AutoNeg)        /* Is Auto-negotiation used ? */
-{
-       /* todo: National */
-       return(SK_HW_PS_NONE);
-}      /* SkGePortCheckUpNat */
-#endif /* OTHER_PHY */
-
-
-/******************************************************************************
- *
- *     SkGeSirqEvent() - Event Service Routine
- *
- * Description:
- *
- * Notes:
- */
-int    SkGeSirqEvent(
-SK_AC          *pAC,           /* Adapter Context */
-SK_IOC         IoC,            /* Io Context */
-SK_U32         Event,          /* Module specific Event */
-SK_EVPARA      Para)           /* Event specific Parameter */
-{
-       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
-       SK_U32          Port;
-       SK_U32          Val32;
-       int                     PortStat;
-       SK_U8           Val8;
-#ifdef GENESIS
-       SK_U64          Octets;
-#endif /* GENESIS */
-
-       Port = Para.Para32[0];
-       pPrt = &pAC->GIni.GP[Port];
-
-       switch (Event) {
-       case SK_HWEV_WATIM:
-               if (pPrt->PState == SK_PRT_RESET) {
-               
-                       PortStat = SK_HW_PS_NONE;
-               }
-               else {
-                       /* Check whether port came up */
-                       PortStat = SkGePortCheckUp(pAC, IoC, (int)Port);
-               }
-
-               switch (PortStat) {
-               case SK_HW_PS_RESTART:
-                       if (pPrt->PHWLinkUp) {
-                               /* Set Link to down */
-                               SkHWLinkDown(pAC, IoC, (int)Port);
-
-                               /*
-                                * Signal directly to RLMT to ensure correct
-                                * sequence of SWITCH and RESET event.
-                                */
-                               SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);
-                       }
-
-                       /* Restart needed */
-                       SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
-                       break;
-
-               case SK_HW_PS_LINK:
-                       /* Signal to RLMT */
-                       SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_UP, Para);
-                       break;
-               }
-               
-               /* Start again the check Timer */
-               if (pPrt->PHWLinkUp) {
-                       Val32 = SK_WA_ACT_TIME;
-               }
-               else {
-                       Val32 = SK_WA_INA_TIME;
-               }
-
-               /* Todo: still needed for non-XMAC PHYs??? */
-               /* Start workaround Errata #2 timer */
-               SkTimerStart(pAC, IoC, &pPrt->PWaTimer, Val32,
-                       SKGE_HWAC, SK_HWEV_WATIM, Para);
-               break;
-
-       case SK_HWEV_PORT_START:
-               if (pPrt->PHWLinkUp) {
-                       /*
-                        * Signal directly to RLMT to ensure correct
-                        * sequence of SWITCH and RESET event.
-                        */
-                       SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);
-               }
-
-               SkHWLinkDown(pAC, IoC, (int)Port);
-
-               /* Schedule Port RESET */
-               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
-
-               /* Start workaround Errata #2 timer */
-               SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME,
-                       SKGE_HWAC, SK_HWEV_WATIM, Para);
-               break;
-
-       case SK_HWEV_PORT_STOP:
-               if (pPrt->PHWLinkUp) {
-                       /*
-                        * Signal directly to RLMT to ensure correct
-                        * sequence of SWITCH and RESET event.
-                        */
-                       SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);
-               }
-
-               /* Stop Workaround Timer */
-               SkTimerStop(pAC, IoC, &pPrt->PWaTimer);
-
-               SkHWLinkDown(pAC, IoC, (int)Port);
-               break;
-
-       case SK_HWEV_UPDATE_STAT:
-               /* We do NOT need to update any statistics */
-               break;
-
-       case SK_HWEV_CLEAR_STAT:
-               /* We do NOT need to clear any statistics */
-               for (Port = 0; Port < (SK_U32)pAC->GIni.GIMacsFound; Port++) {
-                       pPrt->PPrevRx = 0;
-                       pPrt->PPrevFcs = 0;
-                       pPrt->PPrevShorts = 0;
-               }
-               break;
-
-       case SK_HWEV_SET_LMODE:
-               Val8 = (SK_U8)Para.Para32[1];
-               if (pPrt->PLinkModeConf != Val8) {
-                       /* Set New link mode */
-                       pPrt->PLinkModeConf = Val8;
-
-                       /* Restart Port */
-                       SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
-                       SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
-               }
-               break;
-
-       case SK_HWEV_SET_FLOWMODE:
-               Val8 = (SK_U8)Para.Para32[1];
-               if (pPrt->PFlowCtrlMode != Val8) {
-                       /* Set New Flow Control mode */
-                       pPrt->PFlowCtrlMode = Val8;
-
-                       /* Restart Port */
-                       SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
-                       SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
-               }
-               break;
-
-       case SK_HWEV_SET_ROLE:
-               /* not possible for fiber */
-               if (!pAC->GIni.GICopperType) {
-                       break;
-               }
-               Val8 = (SK_U8)Para.Para32[1];
-               if (pPrt->PMSMode != Val8) {
-                       /* Set New Role (Master/Slave) mode */
-                       pPrt->PMSMode = Val8;
-
-                       /* Restart Port */
-                       SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
-                       SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
-               }
-               break;
-
-       case SK_HWEV_SET_SPEED:
-               if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
-                       break;
-               }
-               Val8 = (SK_U8)Para.Para32[1];
-               if (pPrt->PLinkSpeed != Val8) {
-                       /* Set New Speed parameter */
-                       pPrt->PLinkSpeed = Val8;
-
-                       /* Restart Port */
-                       SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
-                       SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
-               }
-               break;
-
-#ifdef GENESIS
-       case SK_HWEV_HALFDUP_CHK:
-               if (pAC->GIni.GIGenesis) {
-                       /*
-                        * half duplex hangup workaround.
-                        * See packet arbiter timeout interrupt for description
-                        */
-                       pPrt->HalfDupTimerActive = SK_FALSE;
-                       if (pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF ||
-                               pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) {
-                               /* Snap statistic counters */
-                               (void)SkXmUpdateStats(pAC, IoC, Port);
-
-                               (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXO_OK_HI, &Val32);
-
-                               Octets = (SK_U64)Val32 << 32;
-                               
-                               (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXO_OK_LO, &Val32);
-
-                               Octets += Val32;
-                               
-                               if (pPrt->LastOctets == Octets) {
-                                       /* Tx hanging, a FIFO flush restarts it */
-                                       SkMacFlushTxFifo(pAC, IoC, Port);
-                               }
-                       }
-               }
-               break;
-#endif /* GENESIS */
-       
-       default:
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_SIRQ_E001, SKERR_SIRQ_E001MSG);
-               break;
-       }
-
-       return(0);
-}      /* SkGeSirqEvent */
-
-
-#ifdef GENESIS
-/******************************************************************************
- *
- *     SkPhyIsrBcom() - PHY interrupt service routine
- *
- * Description: handles all interrupts from BCom PHY
- *
- * Returns: N/A
- */
-static void SkPhyIsrBcom(
-SK_AC          *pAC,           /* Adapter Context */
-SK_IOC         IoC,            /* Io Context */
-int                    Port,           /* Port Num = PHY Num */
-SK_U16         IStatus)        /* Interrupt Status */
-{
-       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
-       SK_EVPARA       Para;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       if ((IStatus & PHY_B_IS_PSE) != 0) {
-               /* Incorrectable pair swap error */
-               SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E022,
-                       SKERR_SIRQ_E022MSG);
-       }
-       
-       if ((IStatus & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) != 0) {
-
-               SkHWLinkDown(pAC, IoC, Port);
-
-               Para.Para32[0] = (SK_U32)Port;
-               /* Signal to RLMT */
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
-
-               /* Start workaround Errata #2 timer */
-               SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME,
-                       SKGE_HWAC, SK_HWEV_WATIM, Para);
-       }
-
-}      /* SkPhyIsrBcom */
-#endif /* GENESIS */
-
-
-#ifdef YUKON
-/******************************************************************************
- *
- *     SkPhyIsrGmac() - PHY interrupt service routine
- *
- * Description: handles all interrupts from Marvell PHY
- *
- * Returns: N/A
- */
-static void SkPhyIsrGmac(
-SK_AC          *pAC,           /* Adapter Context */
-SK_IOC         IoC,            /* Io Context */
-int                    Port,           /* Port Num = PHY Num */
-SK_U16         IStatus)        /* Interrupt Status */
-{
-       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
-       SK_EVPARA       Para;
-       SK_U16          Word;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       if ((IStatus & (PHY_M_IS_AN_PR | PHY_M_IS_LST_CHANGE)) != 0) {
-
-               SkHWLinkDown(pAC, IoC, Port);
-
-               SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &Word);
-
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("AutoNeg.Adv: 0x%04X\n", Word));
-               
-               /* Set Auto-negotiation advertisement */
-               if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) {
-                       /* restore Asymmetric Pause bit */
-                       SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV,
-                               (SK_U16)(Word | PHY_M_AN_ASP));
-               }
-               
-               Para.Para32[0] = (SK_U32)Port;
-               /* Signal to RLMT */
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
-       }
-       
-       if ((IStatus & PHY_M_IS_AN_ERROR) != 0) {
-               /* Auto-Negotiation Error */
-               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E023, SKERR_SIRQ_E023MSG);
-       }
-       
-       if ((IStatus & PHY_M_IS_FIFO_ERROR) != 0) {
-               /* FIFO Overflow/Underrun Error */
-               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E024, SKERR_SIRQ_E024MSG);
-       }
-       
-}      /* SkPhyIsrGmac */
-#endif /* YUKON */
-
-
-#ifdef OTHER_PHY
-/******************************************************************************
- *
- *     SkPhyIsrLone() - PHY interrupt service routine
- *
- * Description: handles all interrupts from LONE PHY
- *
- * Returns: N/A
- */
-static void SkPhyIsrLone(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* Io Context */
-int            Port,           /* Port Num = PHY Num */
-SK_U16 IStatus)        /* Interrupt Status */
-{
-       SK_EVPARA       Para;
-
-       if (IStatus & (PHY_L_IS_DUP | PHY_L_IS_ISOL)) {
-               
-               SkHWLinkDown(pAC, IoC, Port);
-
-               Para.Para32[0] = (SK_U32)Port;
-               /* Signal to RLMT */
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
-       }
-
-}      /* SkPhyIsrLone */
-#endif /* OTHER_PHY */
-
-/* End of File */
diff --git a/drivers/net/sk98lin/ski2c.c b/drivers/net/sk98lin/ski2c.c
deleted file mode 100644 (file)
index 79bf57c..0000000
+++ /dev/null
@@ -1,1296 +0,0 @@
-/******************************************************************************
- *
- * Name:       ski2c.c
- * Project:    Gigabit Ethernet Adapters, TWSI-Module
- * Version:    $Revision: 1.59 $
- * Date:       $Date: 2003/10/20 09:07:25 $
- * Purpose:    Functions to access Voltage and Temperature Sensor
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect.
- *     (C)Copyright 2002-2003 Marvell.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/*
- *     I2C Protocol
- */
-#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
-static const char SysKonnectFileId[] =
-       "@(#) $Id: ski2c.c,v 1.59 2003/10/20 09:07:25 rschmidt Exp $ (C) Marvell. ";
-#endif
-
-#include "h/skdrv1st.h"                /* Driver Specific Definitions */
-#include "h/lm80.h"
-#include "h/skdrv2nd.h"                /* Adapter Control- and Driver specific Def. */
-
-#ifdef __C2MAN__
-/*
-       I2C protocol implementation.
-
-       General Description:
-
-       The I2C protocol is used for the temperature sensors and for
-       the serial EEPROM which hold the configuration.
-
-       This file covers functions that allow to read write and do
-       some bulk requests a specified I2C address.
-
-       The Genesis has 2 I2C buses. One for the EEPROM which holds
-       the VPD Data and one for temperature and voltage sensor.
-       The following picture shows the I2C buses, I2C devices and
-       their control registers.
-
-       Note: The VPD functions are in skvpd.c
-.
-.      PCI Config I2C Bus for VPD Data:
-.
-.                    +------------+
-.                    | VPD EEPROM |
-.                    +------------+
-.                           |
-.                           | <-- I2C
-.                           |
-.               +-----------+-----------+
-.               |                       |
-.      +-----------------+     +-----------------+
-.      | PCI_VPD_ADR_REG |     | PCI_VPD_DAT_REG |
-.      +-----------------+     +-----------------+
-.
-.
-.      I2C Bus for LM80 sensor:
-.
-.                      +-----------------+
-.                      | Temperature and |
-.                      | Voltage Sensor  |
-.                      |       LM80      |
-.                      +-----------------+
-.                              |
-.                              |
-.                      I2C --> |
-.                              |
-.                           +----+
-.           +-------------->| OR |<--+
-.           |               +----+   |
-.     +------+------+                |
-.     |                    |                 |
-. +--------+   +--------+      +----------+
-. | B2_I2C |   | B2_I2C |      |  B2_I2C  |
-. | _CTRL  |   | _DATA  |      |   _SW    |
-. +--------+   +--------+      +----------+
-.
-       The I2C bus may be driven by the B2_I2C_SW or by the B2_I2C_CTRL
-       and B2_I2C_DATA registers.
-       For driver software it is recommended to use the I2C control and
-       data register, because I2C bus timing is done by the ASIC and
-       an interrupt may be received when the I2C request is completed.
-
-       Clock Rate Timing:                      MIN     MAX     generated by
-               VPD EEPROM:                     50 kHz  100 kHz         HW
-               LM80 over I2C Ctrl/Data reg.    50 kHz  100 kHz         HW
-               LM80 over B2_I2C_SW register    0       400 kHz         SW
-
-       Note:   The clock generated by the hardware is dependend on the
-               PCI clock. If the PCI bus clock is 33 MHz, the I2C/VPD
-               clock is 50 kHz.
- */
-intro()
-{}
-#endif
-
-#ifdef SK_DIAG
-/*
- * I2C Fast Mode timing values used by the LM80.
- * If new devices are added to the I2C bus the timing values have to be checked.
- */
-#ifndef I2C_SLOW_TIMING
-#define        T_CLK_LOW                       1300L   /* clock low time in ns */
-#define        T_CLK_HIGH                       600L   /* clock high time in ns */
-#define T_DATA_IN_SETUP                 100L   /* data in Set-up Time */
-#define T_START_HOLD            600L   /* start condition hold time */
-#define T_START_SETUP           600L   /* start condition Set-up time */
-#define        T_STOP_SETUP             600L   /* stop condition Set-up time */
-#define T_BUS_IDLE                     1300L   /* time the bus must free after Tx */
-#define        T_CLK_2_DATA_OUT         900L   /* max. clock low to data output valid */
-#else  /* I2C_SLOW_TIMING */
-/* I2C Standard Mode Timing */
-#define        T_CLK_LOW                       4700L   /* clock low time in ns */
-#define        T_CLK_HIGH                      4000L   /* clock high time in ns */
-#define T_DATA_IN_SETUP                 250L   /* data in Set-up Time */
-#define T_START_HOLD           4000L   /* start condition hold time */
-#define T_START_SETUP          4700L   /* start condition Set-up time */
-#define        T_STOP_SETUP            4000L   /* stop condition Set-up time */
-#define T_BUS_IDLE                     4700L   /* time the bus must free after Tx */
-#endif /* !I2C_SLOW_TIMING */
-
-#define NS2BCLK(x)     (((x)*125)/10000)
-
-/*
- * I2C Wire Operations
- *
- * About I2C_CLK_LOW():
- *
- * The Data Direction bit (I2C_DATA_DIR) has to be set to input when setting
- * clock to low, to prevent the ASIC and the I2C data client from driving the
- * serial data line simultaneously (ASIC: last bit of a byte = '1', I2C client
- * send an 'ACK'). See also Concentrator Bugreport No. 10192.
- */
-#define I2C_DATA_HIGH(IoC)     SK_I2C_SET_BIT(IoC, I2C_DATA)
-#define        I2C_DATA_LOW(IoC)       SK_I2C_CLR_BIT(IoC, I2C_DATA)
-#define        I2C_DATA_OUT(IoC)       SK_I2C_SET_BIT(IoC, I2C_DATA_DIR)
-#define        I2C_DATA_IN(IoC)        SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA)
-#define        I2C_CLK_HIGH(IoC)       SK_I2C_SET_BIT(IoC, I2C_CLK)
-#define        I2C_CLK_LOW(IoC)        SK_I2C_CLR_BIT(IoC, I2C_CLK | I2C_DATA_DIR)
-#define        I2C_START_COND(IoC)     SK_I2C_CLR_BIT(IoC, I2C_CLK)
-
-#define NS2CLKT(x)     ((x*125L)/10000)
-
-/*--------------- I2C Interface Register Functions --------------- */
-
-/*
- * sending one bit
- */
-void SkI2cSndBit(
-SK_IOC IoC,    /* I/O Context */
-SK_U8  Bit)    /* Bit to send */
-{
-       I2C_DATA_OUT(IoC);
-       if (Bit) {
-               I2C_DATA_HIGH(IoC);
-       }
-       else {
-               I2C_DATA_LOW(IoC);
-       }
-       SkDgWaitTime(IoC, NS2BCLK(T_DATA_IN_SETUP));
-       I2C_CLK_HIGH(IoC);
-       SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
-       I2C_CLK_LOW(IoC);
-}      /* SkI2cSndBit*/
-
-
-/*
- * Signal a start to the I2C Bus.
- *
- * A start is signaled when data goes to low in a high clock cycle.
- *
- * Ends with Clock Low.
- *
- * Status: not tested
- */
-void SkI2cStart(
-SK_IOC IoC)    /* I/O Context */
-{
-       /* Init data and Clock to output lines */
-       /* Set Data high */
-       I2C_DATA_OUT(IoC);
-       I2C_DATA_HIGH(IoC);
-       /* Set Clock high */
-       I2C_CLK_HIGH(IoC);
-
-       SkDgWaitTime(IoC, NS2BCLK(T_START_SETUP));
-
-       /* Set Data Low */
-       I2C_DATA_LOW(IoC);
-
-       SkDgWaitTime(IoC, NS2BCLK(T_START_HOLD));
-
-       /* Clock low without Data to Input */
-       I2C_START_COND(IoC);
-
-       SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW));
-}      /* SkI2cStart */
-
-
-void SkI2cStop(
-SK_IOC IoC)    /* I/O Context */
-{
-       /* Init data and Clock to output lines */
-       /* Set Data low */
-       I2C_DATA_OUT(IoC);
-       I2C_DATA_LOW(IoC);
-
-       SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
-
-       /* Set Clock high */
-       I2C_CLK_HIGH(IoC);
-
-       SkDgWaitTime(IoC, NS2BCLK(T_STOP_SETUP));
-
-       /*
-        * Set Data High:       Do it by setting the Data Line to Input.
-        *                      Because of a pull up resistor the Data Line
-        *                      floods to high.
-        */
-       I2C_DATA_IN(IoC);
-
-       /*
-        *      When I2C activity is stopped
-        *       o      DATA should be set to input and
-        *       o      CLOCK should be set to high!
-        */
-       SkDgWaitTime(IoC, NS2BCLK(T_BUS_IDLE));
-}      /* SkI2cStop */
-
-
-/*
- * Receive just one bit via the I2C bus.
- *
- * Note:       Clock must be set to LOW before calling this function.
- *
- * Returns The received bit.
- */
-int SkI2cRcvBit(
-SK_IOC IoC)    /* I/O Context */
-{
-       int     Bit;
-       SK_U8   I2cSwCtrl;
-
-       /* Init data as input line */
-       I2C_DATA_IN(IoC);
-
-       SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
-
-       I2C_CLK_HIGH(IoC);
-
-       SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
-
-       SK_I2C_GET_SW(IoC, &I2cSwCtrl);
-       
-       Bit = (I2cSwCtrl & I2C_DATA) ? 1 : 0;
-
-       I2C_CLK_LOW(IoC);
-       SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW-T_CLK_2_DATA_OUT));
-
-       return(Bit);
-}      /* SkI2cRcvBit */
-
-
-/*
- * Receive an ACK.
- *
- * returns     0 If acknowledged
- *             1 in case of an error
- */
-int SkI2cRcvAck(
-SK_IOC IoC)    /* I/O Context */
-{
-       /*
-        * Received bit must be zero.
-        */
-       return(SkI2cRcvBit(IoC) != 0);
-}      /* SkI2cRcvAck */
-
-
-/*
- * Send an NACK.
- */
-void SkI2cSndNAck(
-SK_IOC IoC)    /* I/O Context */
-{
-       /*
-        * Received bit must be zero.
-        */
-       SkI2cSndBit(IoC, 1);
-}      /* SkI2cSndNAck */
-
-
-/*
- * Send an ACK.
- */
-void SkI2cSndAck(
-SK_IOC IoC)    /* I/O Context */
-{
-       /*
-        * Received bit must be zero.
-        */
-       SkI2cSndBit(IoC, 0);
-}      /* SkI2cSndAck */
-
-
-/*
- * Send one byte to the I2C device and wait for ACK.
- *
- * Return acknowleged status.
- */
-int SkI2cSndByte(
-SK_IOC IoC,    /* I/O Context */
-int            Byte)   /* byte to send */
-{
-       int     i;
-
-       for (i = 0; i < 8; i++) {
-               if (Byte & (1<<(7-i))) {
-                       SkI2cSndBit(IoC, 1);
-               }
-               else {
-                       SkI2cSndBit(IoC, 0);
-               }
-       }
-
-       return(SkI2cRcvAck(IoC));
-}      /* SkI2cSndByte */
-
-
-/*
- * Receive one byte and ack it.
- *
- * Return byte.
- */
-int SkI2cRcvByte(
-SK_IOC IoC,    /* I/O Context */
-int            Last)   /* Last Byte Flag */
-{
-       int     i;
-       int     Byte = 0;
-
-       for (i = 0; i < 8; i++) {
-               Byte <<= 1;
-               Byte |= SkI2cRcvBit(IoC);
-       }
-
-       if (Last) {
-               SkI2cSndNAck(IoC);
-       }
-       else {
-               SkI2cSndAck(IoC);
-       }
-
-       return(Byte);
-}      /* SkI2cRcvByte */
-
-
-/*
- * Start dialog and send device address
- *
- * Return 0 if acknowleged, 1 in case of an error
- */
-int    SkI2cSndDev(
-SK_IOC IoC,    /* I/O Context */
-int            Addr,   /* Device Address */
-int            Rw)             /* Read / Write Flag */
-{
-       SkI2cStart(IoC);
-       Rw = ~Rw;
-       Rw &= I2C_WRITE;
-       return(SkI2cSndByte(IoC, (Addr<<1) | Rw));
-}      /* SkI2cSndDev */
-
-#endif /* SK_DIAG */
-
-/*----------------- I2C CTRL Register Functions ----------*/
-
-/*
- * waits for a completion of an I2C transfer
- *
- * returns     0:      success, transfer completes
- *                     1:      error,   transfer does not complete, I2C transfer
- *                                              killed, wait loop terminated.
- */
-static int     SkI2cWait(
-SK_AC  *pAC,   /* Adapter Context */
-SK_IOC IoC,    /* I/O Context */
-int            Event)  /* complete event to wait for (I2C_READ or I2C_WRITE) */
-{
-       SK_U64  StartTime;
-       SK_U64  CurrentTime;
-       SK_U32  I2cCtrl;
-
-       StartTime = SkOsGetTime(pAC);
-       
-       do {
-               CurrentTime = SkOsGetTime(pAC);
-
-               if (CurrentTime - StartTime > SK_TICKS_PER_SEC / 8) {
-                       
-                       SK_I2C_STOP(IoC);
-#ifndef SK_DIAG
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E002, SKERR_I2C_E002MSG);
-#endif /* !SK_DIAG */
-                       return(1);
-               }
-               
-               SK_I2C_GET_CTL(IoC, &I2cCtrl);
-
-#ifdef xYUKON_DBG
-               printf("StartTime=%lu, CurrentTime=%lu\n",
-                       StartTime, CurrentTime);
-               if (kbhit()) {
-                       return(1);
-               }
-#endif /* YUKON_DBG */
-       
-       } while ((I2cCtrl & I2C_FLAG) == (SK_U32)Event << 31);
-
-       return(0);
-}      /* SkI2cWait */
-
-
-/*
- * waits for a completion of an I2C transfer
- *
- * Returns
- *     Nothing
- */
-void SkI2cWaitIrq(
-SK_AC  *pAC,   /* Adapter Context */
-SK_IOC IoC)    /* I/O Context */
-{
-       SK_SENSOR       *pSen;
-       SK_U64          StartTime;
-       SK_U32          IrqSrc;
-
-       pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
-
-       if (pSen->SenState == SK_SEN_IDLE) {
-               return;
-       }
-
-       StartTime = SkOsGetTime(pAC);
-       
-       do {
-               if (SkOsGetTime(pAC) - StartTime > SK_TICKS_PER_SEC / 8) {
-                       
-                       SK_I2C_STOP(IoC);
-#ifndef SK_DIAG
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E016, SKERR_I2C_E016MSG);
-#endif /* !SK_DIAG */
-                       return;
-               }
-               
-               SK_IN32(IoC, B0_ISRC, &IrqSrc);
-
-       } while ((IrqSrc & IS_I2C_READY) == 0);
-
-       pSen->SenState = SK_SEN_IDLE;
-       return;
-}      /* SkI2cWaitIrq */
-
-/*
- * writes a single byte or 4 bytes into the I2C device
- *
- * returns     0:      success
- *                     1:      error
- */
-static int SkI2cWrite(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* I/O Context */
-SK_U32 I2cData,        /* I2C Data to write */
-int            I2cDev,         /* I2C Device Address */
-int            I2cDevSize, /* I2C Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */
-int            I2cReg,         /* I2C Device Register Address */
-int            I2cBurst)       /* I2C Burst Flag */
-{
-       SK_OUT32(IoC, B2_I2C_DATA, I2cData);
-       
-       SK_I2C_CTL(IoC, I2C_WRITE, I2cDev, I2cDevSize, I2cReg, I2cBurst);
-       
-       return(SkI2cWait(pAC, IoC, I2C_WRITE));
-}      /* SkI2cWrite*/
-
-
-#ifdef SK_DIAG
-/*
- * reads a single byte or 4 bytes from the I2C device
- *
- * returns     the word read
- */
-SK_U32 SkI2cRead(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* I/O Context */
-int            I2cDev,         /* I2C Device Address */
-int            I2cDevSize, /* I2C Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */
-int            I2cReg,         /* I2C Device Register Address */
-int            I2cBurst)       /* I2C Burst Flag */
-{
-       SK_U32  Data;
-
-       SK_OUT32(IoC, B2_I2C_DATA, 0);
-       SK_I2C_CTL(IoC, I2C_READ, I2cDev, I2cDevSize, I2cReg, I2cBurst);
-       
-       if (SkI2cWait(pAC, IoC, I2C_READ) != 0) {
-               w_print("%s\n", SKERR_I2C_E002MSG);
-       }
-       
-       SK_IN32(IoC, B2_I2C_DATA, &Data);
-       
-       return(Data);
-}      /* SkI2cRead */
-#endif /* SK_DIAG */
-
-
-/*
- * read a sensor's value
- *
- * This function reads a sensor's value from the I2C sensor chip. The sensor
- * is defined by its index into the sensors database in the struct pAC points
- * to.
- * Returns
- *             1 if the read is completed
- *             0 if the read must be continued (I2C Bus still allocated)
- */
-static int     SkI2cReadSensor(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_SENSOR      *pSen)  /* Sensor to be read */
-{
-    if (pSen->SenRead != NULL) {
-        return((*pSen->SenRead)(pAC, IoC, pSen));
-    }
-       else {
-        return(0); /* no success */
-       }
-}      /* SkI2cReadSensor */
-
-/*
- * Do the Init state 0 initialization
- */
-static int SkI2cInit0(
-SK_AC  *pAC)   /* Adapter Context */
-{
-       int     i;
-
-       /* Begin with first sensor */
-       pAC->I2c.CurrSens = 0;
-       
-       /* Begin with timeout control for state machine */
-       pAC->I2c.TimerMode = SK_TIMER_WATCH_SM;
-       
-       /* Set sensor number to zero */
-       pAC->I2c.MaxSens = 0;
-
-#ifndef SK_DIAG
-       /* Initialize Number of Dummy Reads */
-       pAC->I2c.DummyReads = SK_MAX_SENSORS;
-#endif
-
-       for (i = 0; i < SK_MAX_SENSORS; i++) {
-               pAC->I2c.SenTable[i].SenDesc = "unknown";
-               pAC->I2c.SenTable[i].SenType = SK_SEN_UNKNOWN;
-               pAC->I2c.SenTable[i].SenThreErrHigh = 0;
-               pAC->I2c.SenTable[i].SenThreErrLow = 0;
-               pAC->I2c.SenTable[i].SenThreWarnHigh = 0;
-               pAC->I2c.SenTable[i].SenThreWarnLow = 0;
-               pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN;
-               pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_NONE;
-               pAC->I2c.SenTable[i].SenValue = 0;
-               pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_NOT_PRESENT;
-               pAC->I2c.SenTable[i].SenErrCts = 0;
-               pAC->I2c.SenTable[i].SenBegErrTS = 0;
-               pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE;
-               pAC->I2c.SenTable[i].SenRead = NULL;
-               pAC->I2c.SenTable[i].SenDev = 0;
-       }
-
-       /* Now we are "INIT data"ed */
-       pAC->I2c.InitLevel = SK_INIT_DATA;
-       return(0);
-}      /* SkI2cInit0*/
-
-
-/*
- * Do the init state 1 initialization
- *
- * initialize the following register of the LM80:
- * Configuration register:
- * - START, noINT, activeLOW, noINT#Clear, noRESET, noCI, noGPO#, noINIT
- *
- * Interrupt Mask Register 1:
- * - all interrupts are Disabled (0xff)
- *
- * Interrupt Mask Register 2:
- * - all interrupts are Disabled (0xff) Interrupt modi doesn't matter.
- *
- * Fan Divisor/RST_OUT register:
- * - Divisors set to 1 (bits 00), all others 0s.
- *
- * OS# Configuration/Temperature resolution Register:
- * - all 0s
- *
- */
-static int SkI2cInit1(
-SK_AC  *pAC,   /* Adapter Context */
-SK_IOC IoC)    /* I/O Context */
-{
-    int i;
-    SK_U8 I2cSwCtrl;
-       SK_GEPORT *pPrt;        /* GIni Port struct pointer */
-
-       if (pAC->I2c.InitLevel != SK_INIT_DATA) {
-               /* ReInit not needed in I2C module */
-               return(0);
-       }
-
-    /* Set the Direction of I2C-Data Pin to IN */
-    SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA);
-    /* Check for 32-Bit Yukon with Low at I2C-Data Pin */
-       SK_I2C_GET_SW(IoC, &I2cSwCtrl);
-
-       if ((I2cSwCtrl & I2C_DATA) == 0) {
-               /* this is a 32-Bit board */
-               pAC->GIni.GIYukon32Bit = SK_TRUE;
-        return(0);
-    }
-
-       /* Check for 64 Bit Yukon without sensors */
-       if (SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_CFG, 0) != 0) {
-        return(0);
-    }
-
-       (void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_1, 0);
-       
-       (void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_2, 0);
-       
-       (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_FAN_CTRL, 0);
-       
-       (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_TEMP_CTRL, 0);
-       
-       (void)SkI2cWrite(pAC, IoC, (SK_U32)LM80_CFG_START, LM80_ADDR, I2C_025K_DEV,
-               LM80_CFG, 0);
-       
-       /*
-        * MaxSens has to be updated here, because PhyType is not
-        * set when performing Init Level 0
-        */
-    pAC->I2c.MaxSens = 5;
-       
-       pPrt = &pAC->GIni.GP[0];
-       
-       if (pAC->GIni.GIGenesis) {
-               if (pPrt->PhyType == SK_PHY_BCOM) {
-                       if (pAC->GIni.GIMacsFound == 1) {
-                               pAC->I2c.MaxSens += 1;
-                       }
-                       else {
-                               pAC->I2c.MaxSens += 3;
-                       }
-               }
-       }
-       else {
-               pAC->I2c.MaxSens += 3;
-       }
-       
-       for (i = 0; i < pAC->I2c.MaxSens; i++) {
-               switch (i) {
-               case 0:
-                       pAC->I2c.SenTable[i].SenDesc = "Temperature";
-                       pAC->I2c.SenTable[i].SenType = SK_SEN_TEMP;
-                       pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_TEMP_HIGH_ERR;
-                       pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_TEMP_HIGH_WARN;
-                       pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_TEMP_LOW_WARN;
-                       pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_TEMP_LOW_ERR;
-                       pAC->I2c.SenTable[i].SenReg = LM80_TEMP_IN;
-                       break;
-               case 1:
-                       pAC->I2c.SenTable[i].SenDesc = "Voltage PCI";
-                       pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
-                       pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_5V_HIGH_ERR;
-                       pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_5V_HIGH_WARN;
-                       pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_5V_LOW_WARN;
-                       pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_5V_LOW_ERR;
-                       pAC->I2c.SenTable[i].SenReg = LM80_VT0_IN;
-                       break;
-               case 2:
-                       pAC->I2c.SenTable[i].SenDesc = "Voltage PCI-IO";
-                       pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
-                       pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_IO_5V_HIGH_ERR;
-                       pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_IO_5V_HIGH_WARN;
-                       pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_IO_3V3_LOW_WARN;
-                       pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_IO_3V3_LOW_ERR;
-                       pAC->I2c.SenTable[i].SenReg = LM80_VT1_IN;
-                       pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_PCI_IO;
-                       break;
-               case 3:
-                       pAC->I2c.SenTable[i].SenDesc = "Voltage ASIC";
-                       pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
-                       pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VDD_HIGH_ERR;
-                       pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VDD_HIGH_WARN;
-                       pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VDD_LOW_WARN;
-                       pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VDD_LOW_ERR;
-                       pAC->I2c.SenTable[i].SenReg = LM80_VT2_IN;
-                       break;
-               case 4:
-                       if (pAC->GIni.GIGenesis) {
-                               if (pPrt->PhyType == SK_PHY_BCOM) {
-                                       pAC->I2c.SenTable[i].SenDesc = "Voltage PHY A PLL";
-                                       pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
-                                       pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
-                                       pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
-                                       pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
-                               }
-                               else {
-                                       pAC->I2c.SenTable[i].SenDesc = "Voltage PMA";
-                                       pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
-                                       pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
-                                       pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
-                                       pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
-                               }
-                       }
-                       else {
-                               pAC->I2c.SenTable[i].SenDesc = "Voltage VAUX";
-                               pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VAUX_3V3_HIGH_ERR;
-                               pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VAUX_3V3_HIGH_WARN;
-                               if (pAC->GIni.GIVauxAvail) {
-                                       pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN;
-                                       pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR;
-                               }
-                               else {
-                                       pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_0V_WARN_ERR;
-                                       pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_0V_WARN_ERR;
-                               }
-                       }
-                       pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
-                       pAC->I2c.SenTable[i].SenReg = LM80_VT3_IN;
-                       break;
-               case 5:
-                       if (pAC->GIni.GIGenesis) {
-                               pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5";
-                               pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR;
-                               pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN;
-                               pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN;
-                               pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR;
-                       }
-                       else {
-                               pAC->I2c.SenTable[i].SenDesc = "Voltage Core 1V5";
-                               pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_CORE_1V5_HIGH_ERR;
-                               pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_CORE_1V5_HIGH_WARN;
-                               pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_CORE_1V5_LOW_WARN;
-                               pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_CORE_1V5_LOW_ERR;
-                       }
-                       pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
-                       pAC->I2c.SenTable[i].SenReg = LM80_VT4_IN;
-                       break;
-               case 6:
-                       if (pAC->GIni.GIGenesis) {
-                               pAC->I2c.SenTable[i].SenDesc = "Voltage PHY B PLL";
-                       }
-                       else {
-                               pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 3V3";
-                       }
-                       pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
-                       pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
-                       pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
-                       pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
-                       pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
-                       pAC->I2c.SenTable[i].SenReg = LM80_VT5_IN;
-                       break;
-               case 7:
-                       if (pAC->GIni.GIGenesis) {
-                               pAC->I2c.SenTable[i].SenDesc = "Speed Fan";
-                               pAC->I2c.SenTable[i].SenType = SK_SEN_FAN;
-                               pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_FAN_HIGH_ERR;
-                               pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_FAN_HIGH_WARN;
-                               pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_FAN_LOW_WARN;
-                               pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_FAN_LOW_ERR;
-                               pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN;
-                       }
-                       else {
-                               pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5";
-                               pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
-                               pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR;
-                               pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN;
-                               pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN;
-                               pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR;
-                               pAC->I2c.SenTable[i].SenReg = LM80_VT6_IN;
-                       }
-                       break;
-               default:
-                       SK_ERR_LOG(pAC, SK_ERRCL_INIT | SK_ERRCL_SW,
-                               SKERR_I2C_E001, SKERR_I2C_E001MSG);
-                       break;
-               }
-
-               pAC->I2c.SenTable[i].SenValue = 0;
-               pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK;
-               pAC->I2c.SenTable[i].SenErrCts = 0;
-               pAC->I2c.SenTable[i].SenBegErrTS = 0;
-               pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE;
-               pAC->I2c.SenTable[i].SenRead = SkLm80ReadSensor;
-               pAC->I2c.SenTable[i].SenDev = LM80_ADDR;
-       }
-
-#ifndef SK_DIAG
-       pAC->I2c.DummyReads = pAC->I2c.MaxSens;
-#endif /* !SK_DIAG */
-       
-       /* Clear I2C IRQ */
-       SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
-       
-       /* Now we are I/O initialized */
-       pAC->I2c.InitLevel = SK_INIT_IO;
-       return(0);
-}      /* SkI2cInit1 */
-
-
-/*
- * Init level 2: Start first sensor read.
- */
-static int SkI2cInit2(
-SK_AC  *pAC,   /* Adapter Context */
-SK_IOC IoC)    /* I/O Context */
-{
-       int             ReadComplete;
-       SK_SENSOR       *pSen;
-
-       if (pAC->I2c.InitLevel != SK_INIT_IO) {
-               /* ReInit not needed in I2C module */
-               /* Init0 and Init2 not permitted */
-               return(0);
-       }
-
-       pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
-       ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
-
-       if (ReadComplete) {
-               SK_ERR_LOG(pAC, SK_ERRCL_INIT, SKERR_I2C_E008, SKERR_I2C_E008MSG);
-       }
-
-       /* Now we are correctly initialized */
-       pAC->I2c.InitLevel = SK_INIT_RUN;
-
-       return(0);
-}      /* SkI2cInit2*/
-
-
-/*
- * Initialize I2C devices
- *
- * Get the first voltage value and discard it.
- * Go into temperature read mode. A default pointer is not set.
- *
- * The things to be done depend on the init level in the parameter list:
- * Level 0:
- *     Initialize only the data structures. Do NOT access hardware.
- * Level 1:
- *     Initialize hardware through SK_IN / SK_OUT commands. Do NOT use interrupts.
- * Level 2:
- *     Everything is possible. Interrupts may be used from now on.
- *
- * return:
- *     0 = success
- *     other = error.
- */
-int    SkI2cInit(
-SK_AC  *pAC,   /* Adapter Context */
-SK_IOC IoC,    /* I/O Context needed in levels 1 and 2 */
-int            Level)  /* Init Level */
-{
-
-       switch (Level) {
-       case SK_INIT_DATA:
-               return(SkI2cInit0(pAC));
-       case SK_INIT_IO:
-               return(SkI2cInit1(pAC, IoC));
-       case SK_INIT_RUN:
-               return(SkI2cInit2(pAC, IoC));
-       default:
-               break;
-       }
-
-       return(0);
-}      /* SkI2cInit */
-
-
-#ifndef SK_DIAG
-
-/*
- * Interrupt service function for the I2C Interface
- *
- * Clears the Interrupt source
- *
- * Reads the register and check it for sending a trap.
- *
- * Starts the timer if necessary.
- */
-void SkI2cIsr(
-SK_AC  *pAC,   /* Adapter Context */
-SK_IOC IoC)    /* I/O Context */
-{
-       SK_EVPARA       Para;
-
-       /* Clear I2C IRQ */
-       SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
-
-       Para.Para64 = 0;
-       SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_IRQ, Para);
-}      /* SkI2cIsr */
-
-
-/*
- * Check this sensors Value against the threshold and send events.
- */
-static void SkI2cCheckSensor(
-SK_AC          *pAC,   /* Adapter Context */
-SK_SENSOR      *pSen)
-{
-       SK_EVPARA       ParaLocal;
-       SK_BOOL         TooHigh;        /* Is sensor too high? */
-       SK_BOOL         TooLow;         /* Is sensor too low? */
-       SK_U64          CurrTime;       /* Current Time */
-       SK_BOOL         DoTrapSend;     /* We need to send a trap */
-       SK_BOOL         DoErrLog;       /* We need to log the error */
-       SK_BOOL         IsError;        /* We need to log the error */
-
-       /* Check Dummy Reads first */
-       if (pAC->I2c.DummyReads > 0) {
-               pAC->I2c.DummyReads--;
-               return;
-       }
-
-       /* Get the current time */
-       CurrTime = SkOsGetTime(pAC);
-
-       /* Set para to the most useful setting: The current sensor. */
-       ParaLocal.Para64 = (SK_U64)pAC->I2c.CurrSens;
-
-       /* Check the Value against the thresholds. First: Error Thresholds */
-       TooHigh = (pSen->SenValue > pSen->SenThreErrHigh);
-       TooLow = (pSen->SenValue < pSen->SenThreErrLow);
-               
-       IsError = SK_FALSE;
-       if (TooHigh || TooLow) {
-               /* Error condition is satisfied */
-               DoTrapSend = SK_TRUE;
-               DoErrLog = SK_TRUE;
-
-               /* Now error condition is satisfied */
-               IsError = SK_TRUE;
-
-               if (pSen->SenErrFlag == SK_SEN_ERR_ERR) {
-                       /* This state is the former one */
-
-                       /* So check first whether we have to send a trap */
-                       if (pSen->SenLastErrTrapTS + SK_SEN_ERR_TR_HOLD >
-                           CurrTime) {
-                               /*
-                                * Do NOT send the Trap. The hold back time
-                                * has to run out first.
-                                */
-                               DoTrapSend = SK_FALSE;
-                       }
-
-                       /* Check now whether we have to log an Error */
-                       if (pSen->SenLastErrLogTS + SK_SEN_ERR_LOG_HOLD >
-                           CurrTime) {
-                               /*
-                                * Do NOT log the error. The hold back time
-                                * has to run out first.
-                                */
-                               DoErrLog = SK_FALSE;
-                       }
-               }
-               else {
-                       /* We came from a different state -> Set Begin Time Stamp */
-                       pSen->SenBegErrTS = CurrTime;
-                       pSen->SenErrFlag = SK_SEN_ERR_ERR;
-               }
-
-               if (DoTrapSend) {
-                       /* Set current Time */
-                       pSen->SenLastErrTrapTS = CurrTime;
-                       pSen->SenErrCts++;
-
-                       /* Queue PNMI Event */
-                       SkEventQueue(pAC, SKGE_PNMI, (TooHigh ?
-                               SK_PNMI_EVT_SEN_ERR_UPP :
-                               SK_PNMI_EVT_SEN_ERR_LOW),
-                               ParaLocal);
-               }
-
-               if (DoErrLog) {
-                       /* Set current Time */
-                       pSen->SenLastErrLogTS = CurrTime;
-
-                       if (pSen->SenType == SK_SEN_TEMP) {
-                               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E011, SKERR_I2C_E011MSG);
-                       }
-                       else if (pSen->SenType == SK_SEN_VOLT) {
-                               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E012, SKERR_I2C_E012MSG);
-                       }
-                       else {
-                               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E015, SKERR_I2C_E015MSG);
-                       }
-               }
-       }
-
-       /* Check the Value against the thresholds */
-       /* 2nd: Warning thresholds */
-       TooHigh = (pSen->SenValue > pSen->SenThreWarnHigh);
-       TooLow = (pSen->SenValue < pSen->SenThreWarnLow);
-               
-       if (!IsError && (TooHigh || TooLow)) {
-               /* Error condition is satisfied */
-               DoTrapSend = SK_TRUE;
-               DoErrLog = SK_TRUE;
-
-               if (pSen->SenErrFlag == SK_SEN_ERR_WARN) {
-                       /* This state is the former one */
-
-                       /* So check first whether we have to send a trap */
-                       if (pSen->SenLastWarnTrapTS + SK_SEN_WARN_TR_HOLD > CurrTime) {
-                               /*
-                                * Do NOT send the Trap. The hold back time
-                                * has to run out first.
-                                */
-                               DoTrapSend = SK_FALSE;
-                       }
-
-                       /* Check now whether we have to log an Error */
-                       if (pSen->SenLastWarnLogTS + SK_SEN_WARN_LOG_HOLD > CurrTime) {
-                               /*
-                                * Do NOT log the error. The hold back time
-                                * has to run out first.
-                                */
-                               DoErrLog = SK_FALSE;
-                       }
-               }
-               else {
-                       /* We came from a different state -> Set Begin Time Stamp */
-                       pSen->SenBegWarnTS = CurrTime;
-                       pSen->SenErrFlag = SK_SEN_ERR_WARN;
-               }
-
-               if (DoTrapSend) {
-                       /* Set current Time */
-                       pSen->SenLastWarnTrapTS = CurrTime;
-                       pSen->SenWarnCts++;
-
-                       /* Queue PNMI Event */
-                       SkEventQueue(pAC, SKGE_PNMI, (TooHigh ?
-                               SK_PNMI_EVT_SEN_WAR_UPP :
-                               SK_PNMI_EVT_SEN_WAR_LOW),
-                               ParaLocal);
-               }
-
-               if (DoErrLog) {
-                       /* Set current Time */
-                       pSen->SenLastWarnLogTS = CurrTime;
-
-                       if (pSen->SenType == SK_SEN_TEMP) {
-                               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E009, SKERR_I2C_E009MSG);
-                       }
-                       else if (pSen->SenType == SK_SEN_VOLT) {
-                               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E010, SKERR_I2C_E010MSG);
-                       }
-                       else {
-                               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E014, SKERR_I2C_E014MSG);
-                       }
-               }
-       }
-
-       /* Check for NO error at all */
-       if (!IsError && !TooHigh && !TooLow) {
-               /* Set o.k. Status if no error and no warning condition */
-               pSen->SenErrFlag = SK_SEN_ERR_OK;
-       }
-
-       /* End of check against the thresholds */
-
-       /* Bug fix AF: 16.Aug.2001: Correct the init base
-        * of LM80 sensor.
-        */
-       if (pSen->SenInit == SK_SEN_DYN_INIT_PCI_IO) {
-
-        pSen->SenInit = SK_SEN_DYN_INIT_NONE;
-
-               if (pSen->SenValue > SK_SEN_PCI_IO_RANGE_LIMITER) {
-                       /* 5V PCI-IO Voltage */
-                       pSen->SenThreWarnLow = SK_SEN_PCI_IO_5V_LOW_WARN;
-                       pSen->SenThreErrLow = SK_SEN_PCI_IO_5V_LOW_ERR;
-               }
-               else {
-                       /* 3.3V PCI-IO Voltage */
-                       pSen->SenThreWarnHigh = SK_SEN_PCI_IO_3V3_HIGH_WARN;
-                       pSen->SenThreErrHigh = SK_SEN_PCI_IO_3V3_HIGH_ERR;
-               }
-       }
-       
-#ifdef TEST_ONLY
-    /* Dynamic thresholds also for VAUX of LM80 sensor */
-       if (pSen->SenInit == SK_SEN_DYN_INIT_VAUX) {
-
-        pSen->SenInit = SK_SEN_DYN_INIT_NONE;
-
-               /* 3.3V VAUX Voltage */
-               if (pSen->SenValue > SK_SEN_VAUX_RANGE_LIMITER) {
-                       pSen->SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN;
-                       pSen->SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR;
-               }
-               /* 0V VAUX Voltage */
-               else {
-                       pSen->SenThreWarnHigh = SK_SEN_VAUX_0V_WARN_ERR;
-                       pSen->SenThreErrHigh = SK_SEN_VAUX_0V_WARN_ERR;
-               }
-       }
-
-       /*
-        * Check initialization state:
-        * The VIO Thresholds need adaption
-        */
-       if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN &&
-            pSen->SenValue > SK_SEN_WARNLOW2C &&
-            pSen->SenValue < SK_SEN_WARNHIGH2) {
-               pSen->SenThreErrLow = SK_SEN_ERRLOW2C;
-               pSen->SenThreWarnLow = SK_SEN_WARNLOW2C;
-               pSen->SenInit = SK_TRUE;
-       }
-
-       if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN &&
-            pSen->SenValue > SK_SEN_WARNLOW2 &&
-            pSen->SenValue < SK_SEN_WARNHIGH2C) {
-               pSen->SenThreErrHigh = SK_SEN_ERRHIGH2C;
-               pSen->SenThreWarnHigh = SK_SEN_WARNHIGH2C;
-               pSen->SenInit = SK_TRUE;
-       }
-#endif
-
-       if (pSen->SenInit != SK_SEN_DYN_INIT_NONE) {
-               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E013, SKERR_I2C_E013MSG);
-       }
-}      /* SkI2cCheckSensor */
-
-
-/*
- * The only Event to be served is the timeout event
- *
- */
-int    SkI2cEvent(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_U32         Event,  /* Module specific Event */
-SK_EVPARA      Para)   /* Event specific Parameter */
-{
-       int                     ReadComplete;
-       SK_SENSOR       *pSen;
-       SK_U32          Time;
-       SK_EVPARA       ParaLocal;
-       int                     i;
-
-       /* New case: no sensors */
-       if (pAC->I2c.MaxSens == 0) {
-               return(0);
-       }
-
-       switch (Event) {
-       case SK_I2CEV_IRQ:
-               pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
-               ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
-
-               if (ReadComplete) {
-                       /* Check sensor against defined thresholds */
-                       SkI2cCheckSensor(pAC, pSen);
-
-                       /* Increment Current sensor and set appropriate Timeout */
-                       pAC->I2c.CurrSens++;
-                       if (pAC->I2c.CurrSens >= pAC->I2c.MaxSens) {
-                               pAC->I2c.CurrSens = 0;
-                               Time = SK_I2C_TIM_LONG;
-                       }
-                       else {
-                               Time = SK_I2C_TIM_SHORT;
-                       }
-
-                       /* Start Timer */
-                       ParaLocal.Para64 = (SK_U64)0;
-
-                       pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
-                       
-                       SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
-                               SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
-               }
-        else {
-                       /* Start Timer */
-                       ParaLocal.Para64 = (SK_U64)0;
-
-                       pAC->I2c.TimerMode = SK_TIMER_WATCH_SM;
-
-            SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, SK_I2C_TIM_WATCH,
-                               SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
-               }
-               break;
-       case SK_I2CEV_TIM:
-               if (pAC->I2c.TimerMode == SK_TIMER_NEW_GAUGING) {
-
-                       ParaLocal.Para64 = (SK_U64)0;
-                       SkTimerStop(pAC, IoC, &pAC->I2c.SenTimer);
-
-                       pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
-                       ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
-
-                       if (ReadComplete) {
-                               /* Check sensor against defined thresholds */
-                               SkI2cCheckSensor(pAC, pSen);
-
-                               /* Increment Current sensor and set appropriate Timeout */
-                               pAC->I2c.CurrSens++;
-                               if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) {
-                                       pAC->I2c.CurrSens = 0;
-                                       Time = SK_I2C_TIM_LONG;
-                               }
-                               else {
-                                       Time = SK_I2C_TIM_SHORT;
-                               }
-
-                               /* Start Timer */
-                               ParaLocal.Para64 = (SK_U64)0;
-
-                               pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
-
-                               SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
-                                       SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
-                       }
-               }
-               else {
-                       pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
-                       pSen->SenErrFlag = SK_SEN_ERR_FAULTY;
-                       SK_I2C_STOP(IoC);
-
-                       /* Increment Current sensor and set appropriate Timeout */
-                       pAC->I2c.CurrSens++;
-                       if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) {
-                               pAC->I2c.CurrSens = 0;
-                               Time = SK_I2C_TIM_LONG;
-                       }
-                       else {
-                               Time = SK_I2C_TIM_SHORT;
-                       }
-
-                       /* Start Timer */
-                       ParaLocal.Para64 = (SK_U64)0;
-
-                       pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
-
-                       SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
-                               SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
-               }
-               break;
-       case SK_I2CEV_CLEAR:
-               for (i = 0; i < SK_MAX_SENSORS; i++) {
-                       pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK;
-                       pAC->I2c.SenTable[i].SenErrCts = 0;
-                       pAC->I2c.SenTable[i].SenWarnCts = 0;
-                       pAC->I2c.SenTable[i].SenBegErrTS = 0;
-                       pAC->I2c.SenTable[i].SenBegWarnTS = 0;
-                       pAC->I2c.SenTable[i].SenLastErrTrapTS = (SK_U64)0;
-                       pAC->I2c.SenTable[i].SenLastErrLogTS = (SK_U64)0;
-                       pAC->I2c.SenTable[i].SenLastWarnTrapTS = (SK_U64)0;
-                       pAC->I2c.SenTable[i].SenLastWarnLogTS = (SK_U64)0;
-               }
-               break;
-       default:
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E006, SKERR_I2C_E006MSG);
-       }
-
-       return(0);
-}      /* SkI2cEvent*/
-
-#endif /* !SK_DIAG */
diff --git a/drivers/net/sk98lin/sklm80.c b/drivers/net/sk98lin/sklm80.c
deleted file mode 100644 (file)
index a204f5b..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-/******************************************************************************
- *
- * Name:       sklm80.c
- * Project:    Gigabit Ethernet Adapters, TWSI-Module
- * Version:    $Revision: 1.22 $
- * Date:       $Date: 2003/10/20 09:08:21 $
- * Purpose:    Functions to access Voltage and Temperature Sensor (LM80)
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect.
- *     (C)Copyright 2002-2003 Marvell.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/*
-       LM80 functions
-*/
-#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
-static const char SysKonnectFileId[] =
-       "@(#) $Id: sklm80.c,v 1.22 2003/10/20 09:08:21 rschmidt Exp $ (C) Marvell. ";
-#endif
-
-#include "h/skdrv1st.h"                /* Driver Specific Definitions */
-#include "h/lm80.h"
-#include "h/skdrv2nd.h"                /* Adapter Control- and Driver specific Def. */
-
-#define        BREAK_OR_WAIT(pAC,IoC,Event)    break
-
-/*
- * read a sensors value (LM80 specific)
- *
- * This function reads a sensors value from the I2C sensor chip LM80.
- * The sensor is defined by its index into the sensors database in the struct
- * pAC points to.
- *
- * Returns     1 if the read is completed
- *             0 if the read must be continued (I2C Bus still allocated)
- */
-int SkLm80ReadSensor(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context needed in level 1 and 2 */
-SK_SENSOR      *pSen)  /* Sensor to be read */
-{
-       SK_I32          Value;
-
-       switch (pSen->SenState) {
-       case SK_SEN_IDLE:
-               /* Send address to ADDR register */
-               SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, I2C_025K_DEV, pSen->SenReg, 0);
-
-               pSen->SenState = SK_SEN_VALUE ;
-               BREAK_OR_WAIT(pAC, IoC, I2C_READ);
-       
-       case SK_SEN_VALUE:
-               /* Read value from data register */
-               SK_IN32(IoC, B2_I2C_DATA, ((SK_U32 *)&Value));
-               
-               Value &= 0xff; /* only least significant byte is valid */
-
-               /* Do NOT check the Value against the thresholds */
-               /* Checking is done in the calling instance */
-
-               if (pSen->SenType == SK_SEN_VOLT) {
-                       /* Voltage sensor */
-                       pSen->SenValue = Value * SK_LM80_VT_LSB;
-                       pSen->SenState = SK_SEN_IDLE ;
-                       return(1);
-               }
-
-               if (pSen->SenType == SK_SEN_FAN) {
-                       if (Value != 0 && Value != 0xff) {
-                               /* Fan speed counter */
-                               pSen->SenValue = SK_LM80_FAN_FAKTOR/Value;
-                       }
-                       else {
-                               /* Indicate Fan error */
-                               pSen->SenValue = 0;
-                       }
-                       pSen->SenState = SK_SEN_IDLE ;
-                       return(1);
-               }
-
-               /* First: correct the value: it might be negative */
-               if ((Value & 0x80) != 0) {
-                       /* Value is negative */
-                       Value = Value - 256;
-               }
-
-               /* We have a temperature sensor and need to get the signed extension.
-                * For now we get the extension from the last reading, so in the normal
-                * case we won't see flickering temperatures.
-                */
-               pSen->SenValue = (Value * SK_LM80_TEMP_LSB) +
-                       (pSen->SenValue % SK_LM80_TEMP_LSB);
-
-               /* Send address to ADDR register */
-               SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, I2C_025K_DEV, LM80_TEMP_CTRL, 0);
-
-               pSen->SenState = SK_SEN_VALEXT ;
-               BREAK_OR_WAIT(pAC, IoC, I2C_READ);
-       
-       case SK_SEN_VALEXT:
-               /* Read value from data register */
-               SK_IN32(IoC, B2_I2C_DATA, ((SK_U32 *)&Value));
-               Value &= LM80_TEMP_LSB_9; /* only bit 7 is valid */
-
-               /* cut the LSB bit */
-               pSen->SenValue = ((pSen->SenValue / SK_LM80_TEMP_LSB) *
-                       SK_LM80_TEMP_LSB);
-
-               if (pSen->SenValue < 0) {
-                       /* Value negative: The bit value must be subtracted */
-                       pSen->SenValue -= ((Value >> 7) * SK_LM80_TEMPEXT_LSB);
-               }
-               else {
-                       /* Value positive: The bit value must be added */
-                       pSen->SenValue += ((Value >> 7) * SK_LM80_TEMPEXT_LSB);
-               }
-
-               pSen->SenState = SK_SEN_IDLE ;
-               return(1);
-       
-       default:
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E007, SKERR_I2C_E007MSG);
-               return(1);
-       }
-
-       /* Not completed */
-       return(0);
-}
-
diff --git a/drivers/net/sk98lin/skqueue.c b/drivers/net/sk98lin/skqueue.c
deleted file mode 100644 (file)
index 0275b4f..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-/******************************************************************************
- *
- * Name:       skqueue.c
- * Project:    Gigabit Ethernet Adapters, Event Scheduler Module
- * Version:    $Revision: 1.20 $
- * Date:       $Date: 2003/09/16 13:44:00 $
- * Purpose:    Management of an event queue.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect GmbH.
- *     (C)Copyright 2002-2003 Marvell.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-
-/*
- *     Event queue and dispatcher
- */
-#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
-static const char SysKonnectFileId[] =
-       "@(#) $Id: skqueue.c,v 1.20 2003/09/16 13:44:00 rschmidt Exp $ (C) Marvell.";
-#endif
-
-#include "h/skdrv1st.h"                /* Driver Specific Definitions */
-#include "h/skqueue.h"         /* Queue Definitions */
-#include "h/skdrv2nd.h"                /* Adapter Control- and Driver specific Def. */
-
-#ifdef __C2MAN__
-/*
-       Event queue management.
-
-       General Description:
-
- */
-intro()
-{}
-#endif
-
-#define PRINTF(a,b,c)
-
-/*
- * init event queue management
- *
- * Must be called during init level 0.
- */
-void   SkEventInit(
-SK_AC  *pAC,   /* Adapter context */
-SK_IOC Ioc,    /* IO context */
-int            Level)  /* Init level */
-{
-       switch (Level) {
-       case SK_INIT_DATA:
-               pAC->Event.EvPut = pAC->Event.EvGet = pAC->Event.EvQueue;
-               break;
-       default:
-               break;
-       }
-}
-
-/*
- * add event to queue
- */
-void   SkEventQueue(
-SK_AC          *pAC,   /* Adapters context */
-SK_U32         Class,  /* Event Class */
-SK_U32         Event,  /* Event to be queued */
-SK_EVPARA      Para)   /* Event parameter */
-{
-       pAC->Event.EvPut->Class = Class;
-       pAC->Event.EvPut->Event = Event;
-       pAC->Event.EvPut->Para = Para;
-       
-       if (++pAC->Event.EvPut == &pAC->Event.EvQueue[SK_MAX_EVENT])
-               pAC->Event.EvPut = pAC->Event.EvQueue;
-
-       if (pAC->Event.EvPut == pAC->Event.EvGet) {
-               SK_ERR_LOG(pAC, SK_ERRCL_NORES, SKERR_Q_E001, SKERR_Q_E001MSG);
-       }
-}
-
-/*
- * event dispatcher
- *     while event queue is not empty
- *             get event from queue
- *             send command to state machine
- *     end
- *     return error reported by individual Event function
- *             0 if no error occured.
- */
-int    SkEventDispatcher(
-SK_AC  *pAC,   /* Adapters Context */
-SK_IOC Ioc)    /* Io context */
-{
-       SK_EVENTELEM    *pEv;   /* pointer into queue */
-       SK_U32                  Class;
-       int                     Rtv;
-
-       pEv = pAC->Event.EvGet;
-       
-       PRINTF("dispatch get %x put %x\n", pEv, pAC->Event.ev_put);
-       
-       while (pEv != pAC->Event.EvPut) {
-               PRINTF("dispatch Class %d Event %d\n", pEv->Class, pEv->Event);
-
-               switch (Class = pEv->Class) {
-#ifndef SK_USE_LAC_EV
-#ifndef SK_SLIM
-               case SKGE_RLMT:         /* RLMT Event */
-                       Rtv = SkRlmtEvent(pAC, Ioc, pEv->Event, pEv->Para);
-                       break;
-               case SKGE_I2C:          /* I2C Event */
-                       Rtv = SkI2cEvent(pAC, Ioc, pEv->Event, pEv->Para);
-                       break;
-               case SKGE_PNMI:         /* PNMI Event */
-                       Rtv = SkPnmiEvent(pAC, Ioc, pEv->Event, pEv->Para);
-                       break;
-#endif /* not SK_SLIM */
-#endif /* not SK_USE_LAC_EV */
-               case SKGE_DRV:          /* Driver Event */
-                       Rtv = SkDrvEvent(pAC, Ioc, pEv->Event, pEv->Para);
-                       break;
-#ifndef SK_USE_SW_TIMER
-               case SKGE_HWAC:
-                       Rtv = SkGeSirqEvent(pAC, Ioc, pEv->Event, pEv->Para);
-                       break;
-#else /* !SK_USE_SW_TIMER */
-        case SKGE_SWT :
-                       Rtv = SkSwtEvent(pAC, Ioc, pEv->Event, pEv->Para);
-                       break;
-#endif /* !SK_USE_SW_TIMER */
-#ifdef SK_USE_LAC_EV
-               case SKGE_LACP :
-                       Rtv = SkLacpEvent(pAC, Ioc, pEv->Event, pEv->Para);
-                       break;
-               case SKGE_RSF :
-                       Rtv = SkRsfEvent(pAC, Ioc, pEv->Event, pEv->Para);
-                       break;
-               case SKGE_MARKER :
-                       Rtv = SkMarkerEvent(pAC, Ioc, pEv->Event, pEv->Para);
-                       break;
-               case SKGE_FD :
-                       Rtv = SkFdEvent(pAC, Ioc, pEv->Event, pEv->Para);
-                       break;
-#endif /* SK_USE_LAC_EV */
-#ifdef SK_USE_CSUM
-               case SKGE_CSUM :
-                       Rtv = SkCsEvent(pAC, Ioc, pEv->Event, pEv->Para);
-                       break;
-#endif /* SK_USE_CSUM */
-               default :
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_Q_E002, SKERR_Q_E002MSG);
-                       Rtv = 0;
-               }
-
-               if (Rtv != 0) {
-                       return(Rtv);
-               }
-
-               if (++pEv == &pAC->Event.EvQueue[SK_MAX_EVENT])
-                       pEv = pAC->Event.EvQueue;
-
-               /* Renew get: it is used in queue_events to detect overruns */
-               pAC->Event.EvGet = pEv;
-       }
-
-       return(0);
-}
-
-/* End of file */
diff --git a/drivers/net/sk98lin/skrlmt.c b/drivers/net/sk98lin/skrlmt.c
deleted file mode 100644 (file)
index be8d1cc..0000000
+++ /dev/null
@@ -1,3257 +0,0 @@
-/******************************************************************************
- *
- * Name:       skrlmt.c
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.69 $
- * Date:       $Date: 2003/04/15 09:39:22 $
- * Purpose:    Manage links on SK-NET Adapters, esp. redundant ones.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect GmbH.
- *     (C)Copyright 2002-2003 Marvell.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * Description:
- *
- * This module contains code for Link ManagemenT (LMT) of SK-NET Adapters.
- * It is mainly intended for adapters with more than one link.
- * For such adapters, this module realizes Redundant Link ManagemenT (RLMT).
- *
- * Include File Hierarchy:
- *
- *     "skdrv1st.h"
- *     "skdrv2nd.h"
- *
- ******************************************************************************/
-
-#ifndef        lint
-static const char SysKonnectFileId[] =
-       "@(#) $Id: skrlmt.c,v 1.69 2003/04/15 09:39:22 tschilli Exp $ (C) Marvell.";
-#endif /* !defined(lint) */
-
-#define __SKRLMT_C
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* cplusplus */
-
-#include "h/skdrv1st.h"
-#include "h/skdrv2nd.h"
-
-/* defines ********************************************************************/
-
-#ifndef SK_HWAC_LINK_LED
-#define SK_HWAC_LINK_LED(a,b,c,d)
-#endif /* !defined(SK_HWAC_LINK_LED) */
-
-#ifndef DEBUG
-#define RLMT_STATIC    static
-#else  /* DEBUG */
-#define RLMT_STATIC
-
-#ifndef SK_LITTLE_ENDIAN
-/* First 32 bits */
-#define OFFS_LO32      1
-
-/* Second 32 bits */
-#define OFFS_HI32      0
-#else  /* SK_LITTLE_ENDIAN */
-/* First 32 bits */
-#define OFFS_LO32      0
-
-/* Second 32 bits */
-#define OFFS_HI32      1
-#endif /* SK_LITTLE_ENDIAN */
-
-#endif /* DEBUG */
-
-/* ----- Private timeout values ----- */
-
-#define SK_RLMT_MIN_TO_VAL                        125000       /* 1/8 sec. */
-#define SK_RLMT_DEF_TO_VAL                       1000000       /* 1 sec. */
-#define SK_RLMT_PORTDOWN_TIM_VAL          900000       /* another 0.9 sec. */
-#define SK_RLMT_PORTSTART_TIM_VAL         100000       /* 0.1 sec. */
-#define SK_RLMT_PORTUP_TIM_VAL           2500000       /* 2.5 sec. */
-#define SK_RLMT_SEG_TO_VAL                     900000000       /* 15 min. */
-
-/* Assume tick counter increment is 1 - may be set OS-dependent. */
-#ifndef SK_TICK_INCR
-#define SK_TICK_INCR   SK_CONSTU64(1)
-#endif /* !defined(SK_TICK_INCR) */
-
-/*
- * Amount that a time stamp must be later to be recognized as "substantially
- * later". This is about 1/128 sec, but above 1 tick counter increment.
- */
-#define SK_RLMT_BC_DELTA               (1 + ((SK_TICKS_PER_SEC >> 7) > SK_TICK_INCR ? \
-                                                                       (SK_TICKS_PER_SEC >> 7) : SK_TICK_INCR))
-
-/* ----- Private RLMT defaults ----- */
-
-#define SK_RLMT_DEF_PREF_PORT  0                                       /* "Lower" port. */
-#define SK_RLMT_DEF_MODE               SK_RLMT_CHECK_LINK      /* Default RLMT Mode. */
-
-/* ----- Private RLMT checking states ----- */
-
-#define SK_RLMT_RCS_SEG                        1               /* RLMT Check State: check seg. */
-#define SK_RLMT_RCS_START_SEG  2               /* RLMT Check State: start check seg. */
-#define SK_RLMT_RCS_SEND_SEG   4               /* RLMT Check State: send BPDU packet */
-#define SK_RLMT_RCS_REPORT_SEG 8               /* RLMT Check State: report seg. */
-
-/* ----- Private PORT checking states ----- */
-
-#define SK_RLMT_PCS_TX                 1               /* Port Check State: check tx. */
-#define SK_RLMT_PCS_RX                 2               /* Port Check State: check rx. */
-
-/* ----- Private PORT events ----- */
-
-/* Note: Update simulation when changing these. */
-#define SK_RLMT_PORTSTART_TIM  1100    /* Port start timeout. */
-#define SK_RLMT_PORTUP_TIM             1101    /* Port can now go up. */
-#define SK_RLMT_PORTDOWN_RX_TIM        1102    /* Port did not receive once ... */
-#define SK_RLMT_PORTDOWN               1103    /* Port went down. */
-#define SK_RLMT_PORTDOWN_TX_TIM        1104    /* Partner did not receive ... */
-
-/* ----- Private RLMT events ----- */
-
-/* Note: Update simulation when changing these. */
-#define SK_RLMT_TIM                            2100    /* RLMT timeout. */
-#define SK_RLMT_SEG_TIM                        2101    /* RLMT segmentation check timeout. */
-
-#define TO_SHORTEN(tim)        ((tim) / 2)
-
-/* Error numbers and messages. */
-#define SKERR_RLMT_E001                (SK_ERRBASE_RLMT + 0)
-#define SKERR_RLMT_E001_MSG    "No Packet."
-#define SKERR_RLMT_E002                (SKERR_RLMT_E001 + 1)
-#define SKERR_RLMT_E002_MSG    "Short Packet."
-#define SKERR_RLMT_E003                (SKERR_RLMT_E002 + 1)
-#define SKERR_RLMT_E003_MSG    "Unknown RLMT event."
-#define SKERR_RLMT_E004                (SKERR_RLMT_E003 + 1)
-#define SKERR_RLMT_E004_MSG    "PortsUp incorrect."
-#define SKERR_RLMT_E005                (SKERR_RLMT_E004 + 1)
-#define SKERR_RLMT_E005_MSG    \
- "Net seems to be segmented (different root bridges are reported on the ports)."
-#define SKERR_RLMT_E006                (SKERR_RLMT_E005 + 1)
-#define SKERR_RLMT_E006_MSG    "Duplicate MAC Address detected."
-#define SKERR_RLMT_E007                (SKERR_RLMT_E006 + 1)
-#define SKERR_RLMT_E007_MSG    "LinksUp incorrect."
-#define SKERR_RLMT_E008                (SKERR_RLMT_E007 + 1)
-#define SKERR_RLMT_E008_MSG    "Port not started but link came up."
-#define SKERR_RLMT_E009                (SKERR_RLMT_E008 + 1)
-#define SKERR_RLMT_E009_MSG    "Corrected illegal setting of Preferred Port."
-#define SKERR_RLMT_E010                (SKERR_RLMT_E009 + 1)
-#define SKERR_RLMT_E010_MSG    "Ignored illegal Preferred Port."
-
-/* LLC field values. */
-#define LLC_COMMAND_RESPONSE_BIT               1
-#define LLC_TEST_COMMAND                               0xE3
-#define LLC_UI                                                 0x03
-
-/* RLMT Packet fields. */
-#define        SK_RLMT_DSAP                                    0
-#define        SK_RLMT_SSAP                                    0
-#define SK_RLMT_CTRL                                   (LLC_TEST_COMMAND)
-#define SK_RLMT_INDICATOR0                             0x53    /* S */
-#define SK_RLMT_INDICATOR1                             0x4B    /* K */
-#define SK_RLMT_INDICATOR2                             0x2D    /* - */
-#define SK_RLMT_INDICATOR3                             0x52    /* R */
-#define SK_RLMT_INDICATOR4                             0x4C    /* L */
-#define SK_RLMT_INDICATOR5                             0x4D    /* M */
-#define SK_RLMT_INDICATOR6                             0x54    /* T */
-#define SK_RLMT_PACKET_VERSION                 0
-
-/* RLMT SPT Flag values. */
-#define        SK_RLMT_SPT_FLAG_CHANGE                 0x01
-#define        SK_RLMT_SPT_FLAG_CHANGE_ACK             0x80
-
-/* RLMT SPT Packet fields. */
-#define        SK_RLMT_SPT_DSAP                                0x42
-#define        SK_RLMT_SPT_SSAP                                0x42
-#define SK_RLMT_SPT_CTRL                               (LLC_UI)
-#define        SK_RLMT_SPT_PROTOCOL_ID0                0x00
-#define        SK_RLMT_SPT_PROTOCOL_ID1                0x00
-#define        SK_RLMT_SPT_PROTOCOL_VERSION_ID 0x00
-#define        SK_RLMT_SPT_BPDU_TYPE                   0x00
-#define        SK_RLMT_SPT_FLAGS                               0x00    /* ?? */
-#define        SK_RLMT_SPT_ROOT_ID0                    0xFF    /* Lowest possible priority. */
-#define        SK_RLMT_SPT_ROOT_ID1                    0xFF    /* Lowest possible priority. */
-
-/* Remaining 6 bytes will be the current port address. */
-#define        SK_RLMT_SPT_ROOT_PATH_COST0             0x00
-#define        SK_RLMT_SPT_ROOT_PATH_COST1             0x00
-#define        SK_RLMT_SPT_ROOT_PATH_COST2             0x00
-#define        SK_RLMT_SPT_ROOT_PATH_COST3             0x00
-#define        SK_RLMT_SPT_BRIDGE_ID0                  0xFF    /* Lowest possible priority. */
-#define        SK_RLMT_SPT_BRIDGE_ID1                  0xFF    /* Lowest possible priority. */
-
-/* Remaining 6 bytes will be the current port address. */
-#define        SK_RLMT_SPT_PORT_ID0                    0xFF    /* Lowest possible priority. */
-#define        SK_RLMT_SPT_PORT_ID1                    0xFF    /* Lowest possible priority. */
-#define        SK_RLMT_SPT_MSG_AGE0                    0x00
-#define        SK_RLMT_SPT_MSG_AGE1                    0x00
-#define        SK_RLMT_SPT_MAX_AGE0                    0x00
-#define        SK_RLMT_SPT_MAX_AGE1                    0xFF
-#define        SK_RLMT_SPT_HELLO_TIME0                 0x00
-#define        SK_RLMT_SPT_HELLO_TIME1                 0xFF
-#define        SK_RLMT_SPT_FWD_DELAY0                  0x00
-#define        SK_RLMT_SPT_FWD_DELAY1                  0x40
-
-/* Size defines. */
-#define SK_RLMT_MIN_PACKET_SIZE                        34
-#define SK_RLMT_MAX_PACKET_SIZE                        (SK_RLMT_MAX_TX_BUF_SIZE)
-#define SK_PACKET_DATA_LEN                             (SK_RLMT_MAX_PACKET_SIZE - \
-                                                                               SK_RLMT_MIN_PACKET_SIZE)
-
-/* ----- RLMT packet types ----- */
-#define SK_PACKET_ANNOUNCE                             1       /* Port announcement. */
-#define SK_PACKET_ALIVE                                        2       /* Alive packet to port. */
-#define SK_PACKET_ADDR_CHANGED                 3       /* Port address changed. */
-#define SK_PACKET_CHECK_TX                             4       /* Check your tx line. */
-
-#ifdef SK_LITTLE_ENDIAN
-#define SK_U16_TO_NETWORK_ORDER(Val,Addr) { \
-       SK_U8   *_Addr = (SK_U8*)(Addr); \
-       SK_U16  _Val = (SK_U16)(Val); \
-       *_Addr++ = (SK_U8)(_Val >> 8); \
-       *_Addr = (SK_U8)(_Val & 0xFF); \
-}
-#endif /* SK_LITTLE_ENDIAN */
-
-#ifdef SK_BIG_ENDIAN
-#define SK_U16_TO_NETWORK_ORDER(Val,Addr) (*(SK_U16*)(Addr) = (SK_U16)(Val))
-#endif /* SK_BIG_ENDIAN */
-
-#define AUTONEG_FAILED SK_FALSE
-#define AUTONEG_SUCCESS        SK_TRUE
-
-
-/* typedefs *******************************************************************/
-
-/* RLMT packet.  Length: SK_RLMT_MAX_PACKET_SIZE (60) bytes. */
-typedef struct s_RlmtPacket {
-       SK_U8   DstAddr[SK_MAC_ADDR_LEN];
-       SK_U8   SrcAddr[SK_MAC_ADDR_LEN];
-       SK_U8   TypeLen[2];
-       SK_U8   DSap;
-       SK_U8   SSap;
-       SK_U8   Ctrl;
-       SK_U8   Indicator[7];
-       SK_U8   RlmtPacketType[2];
-       SK_U8   Align1[2];
-       SK_U8   Random[4];                              /* Random value of requesting(!) station. */
-       SK_U8   RlmtPacketVersion[2];   /* RLMT Packet version. */
-       SK_U8   Data[SK_PACKET_DATA_LEN];
-} SK_RLMT_PACKET;
-
-typedef struct s_SpTreeRlmtPacket {
-       SK_U8   DstAddr[SK_MAC_ADDR_LEN];
-       SK_U8   SrcAddr[SK_MAC_ADDR_LEN];
-       SK_U8   TypeLen[2];
-       SK_U8   DSap;
-       SK_U8   SSap;
-       SK_U8   Ctrl;
-       SK_U8   ProtocolId[2];
-       SK_U8   ProtocolVersionId;
-       SK_U8   BpduType;
-       SK_U8   Flags;
-       SK_U8   RootId[8];
-       SK_U8   RootPathCost[4];
-       SK_U8   BridgeId[8];
-       SK_U8   PortId[2];
-       SK_U8   MessageAge[2];
-       SK_U8   MaxAge[2];
-       SK_U8   HelloTime[2];
-       SK_U8   ForwardDelay[2];
-} SK_SPTREE_PACKET;
-
-/* global variables ***********************************************************/
-
-SK_MAC_ADDR    SkRlmtMcAddr =  {{0x01,  0x00,  0x5A,  0x52,  0x4C,  0x4D}};
-SK_MAC_ADDR    BridgeMcAddr =  {{0x01,  0x80,  0xC2,  0x00,  0x00,  0x00}};
-
-/* local variables ************************************************************/
-
-/* None. */
-
-/* functions ******************************************************************/
-
-RLMT_STATIC void       SkRlmtCheckSwitch(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       SK_U32  NetIdx);
-RLMT_STATIC void       SkRlmtCheckSeg(
-       SK_AC   *pAC,
-       SK_IOC  IoC,
-       SK_U32  NetIdx);
-RLMT_STATIC void       SkRlmtEvtSetNets(
-       SK_AC           *pAC,
-       SK_IOC          IoC,
-       SK_EVPARA       Para);
-
-/******************************************************************************
- *
- *     SkRlmtInit - initialize data, set state to init
- *
- * Description:
- *
- *     SK_INIT_DATA
- *     ============
- *
- *     This routine initializes all RLMT-related variables to a known state.
- *     The initial state is SK_RLMT_RS_INIT.
- *     All ports are initialized to SK_RLMT_PS_INIT.
- *
- *
- *     SK_INIT_IO
- *     ==========
- *
- *     Nothing.
- *
- *
- *     SK_INIT_RUN
- *     ===========
- *
- *     Determine the adapter's random value.
- *     Set the hw registers, the "logical MAC address", the
- *     RLMT multicast address, and eventually the BPDU multicast address.
- *
- * Context:
- *     init, pageable
- *
- * Returns:
- *     Nothing.
- */
-void   SkRlmtInit(
-SK_AC  *pAC,   /* Adapter Context */
-SK_IOC IoC,    /* I/O Context */
-int            Level)  /* Initialization Level */
-{
-       SK_U32          i, j;
-       SK_U64          Random;
-       SK_EVPARA       Para;
-    SK_MAC_ADDR                VirtualMacAddress;
-    SK_MAC_ADDR                PhysicalAMacAddress;
-    SK_BOOL            VirtualMacAddressSet;
-    SK_BOOL            PhysicalAMacAddressSet;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_INIT,
-               ("RLMT Init level %d.\n", Level))
-
-       switch (Level) {
-       case SK_INIT_DATA:      /* Initialize data structures. */
-               SK_MEMSET((char *)&pAC->Rlmt, 0, sizeof(SK_RLMT));
-
-               for (i = 0; i < SK_MAX_MACS; i++) {
-                       pAC->Rlmt.Port[i].PortState = SK_RLMT_PS_INIT;
-                       pAC->Rlmt.Port[i].LinkDown = SK_TRUE;
-                       pAC->Rlmt.Port[i].PortDown = SK_TRUE;
-                       pAC->Rlmt.Port[i].PortStarted = SK_FALSE;
-                       pAC->Rlmt.Port[i].PortNoRx = SK_FALSE;
-                       pAC->Rlmt.Port[i].RootIdSet = SK_FALSE;
-                       pAC->Rlmt.Port[i].PortNumber = i;
-                       pAC->Rlmt.Port[i].Net = &pAC->Rlmt.Net[0];
-                       pAC->Rlmt.Port[i].AddrPort = &pAC->Addr.Port[i];
-               }
-
-               pAC->Rlmt.NumNets = 1;
-               for (i = 0; i < SK_MAX_NETS; i++) {
-                       pAC->Rlmt.Net[i].RlmtState = SK_RLMT_RS_INIT;
-                       pAC->Rlmt.Net[i].RootIdSet = SK_FALSE;
-                       pAC->Rlmt.Net[i].PrefPort = SK_RLMT_DEF_PREF_PORT;
-                       pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF;         /* Automatic. */
-                       /* Just assuming. */
-                       pAC->Rlmt.Net[i].ActivePort = pAC->Rlmt.Net[i].PrefPort;
-                       pAC->Rlmt.Net[i].RlmtMode = SK_RLMT_DEF_MODE;
-                       pAC->Rlmt.Net[i].TimeoutValue = SK_RLMT_DEF_TO_VAL;
-                       pAC->Rlmt.Net[i].NetNumber = i;
-               }
-
-               pAC->Rlmt.Net[0].Port[0] = &pAC->Rlmt.Port[0];
-               pAC->Rlmt.Net[0].Port[1] = &pAC->Rlmt.Port[1];
-#if SK_MAX_NETS > 1
-               pAC->Rlmt.Net[1].Port[0] = &pAC->Rlmt.Port[1];
-#endif /* SK_MAX_NETS > 1 */
-               break;
-
-       case SK_INIT_IO:        /* GIMacsFound first available here. */
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_INIT,
-                       ("RLMT: %d MACs were detected.\n", pAC->GIni.GIMacsFound))
-
-               pAC->Rlmt.Net[0].NumPorts = pAC->GIni.GIMacsFound;
-
-               /* Initialize HW registers? */
-               if (pAC->GIni.GIMacsFound == 1) {
-                       Para.Para32[0] = SK_RLMT_MODE_CLS;
-                       Para.Para32[1] = 0;
-                       (void)SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE, Para);
-               }
-               break;
-
-       case SK_INIT_RUN:
-               /* Ensure RLMT is set to one net. */
-               if (pAC->Rlmt.NumNets > 1) {
-                       Para.Para32[0] = 1;
-                       Para.Para32[1] = -1;
-                       SkRlmtEvtSetNets(pAC, IoC, Para);
-               }
-
-               for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
-                       Random = SkOsGetTime(pAC);
-                       *(SK_U32*)&pAC->Rlmt.Port[i].Random = *(SK_U32*)&Random;
-
-                       for (j = 0; j < 4; j++) {
-                               pAC->Rlmt.Port[i].Random[j] ^= pAC->Rlmt.Port[i].AddrPort->
-                                       CurrentMacAddress.a[SK_MAC_ADDR_LEN - 1 - j];
-                       }
-
-                       (void)SkAddrMcClear(pAC, IoC, i, SK_ADDR_PERMANENT | SK_MC_SW_ONLY);
-                       
-                       /* Add RLMT MC address. */
-                       (void)SkAddrMcAdd(pAC, IoC, i, &SkRlmtMcAddr, SK_ADDR_PERMANENT);
-
-                       if (pAC->Rlmt.Net[0].RlmtMode & SK_RLMT_CHECK_SEG) {
-                               /* Add BPDU MC address. */
-                               (void)SkAddrMcAdd(pAC, IoC, i, &BridgeMcAddr, SK_ADDR_PERMANENT);
-                       }
-
-                       (void)SkAddrMcUpdate(pAC, IoC, i);
-               }
-
-       VirtualMacAddressSet = SK_FALSE;
-               /* Read virtual MAC address from Control Register File. */
-               for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
-                       
-            SK_IN8(IoC, B2_MAC_1 + j, &VirtualMacAddress.a[j]);
-            VirtualMacAddressSet |= VirtualMacAddress.a[j];
-               }
-       
-        PhysicalAMacAddressSet = SK_FALSE;
-               /* Read physical MAC address for MAC A from Control Register File. */
-               for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
-                       
-            SK_IN8(IoC, B2_MAC_2 + j, &PhysicalAMacAddress.a[j]);
-            PhysicalAMacAddressSet |= PhysicalAMacAddress.a[j];
-               }
-
-        /* check if the two mac addresses contain reasonable values */
-        if (!VirtualMacAddressSet || !PhysicalAMacAddressSet) {
-
-            pAC->Rlmt.RlmtOff = SK_TRUE;
-        }
-
-        /* if the two mac addresses are equal switch off the RLMT_PRE_LOOKAHEAD
-           and the RLMT_LOOKAHEAD macros */
-        else if (SK_ADDR_EQUAL(PhysicalAMacAddress.a, VirtualMacAddress.a)) {
-
-            pAC->Rlmt.RlmtOff = SK_TRUE;
-        }
-               else {
-                       pAC->Rlmt.RlmtOff = SK_FALSE;
-               }
-               break;
-
-       default:        /* error */
-               break;
-       }
-       return;
-}      /* SkRlmtInit */
-
-
-/******************************************************************************
- *
- *     SkRlmtBuildCheckChain - build the check chain
- *
- * Description:
- *     This routine builds the local check chain:
- *     - Each port that is up checks the next port.
- *     - The last port that is up checks the first port that is up.
- *
- * Notes:
- *     - Currently only local ports are considered when building the chain.
- *     - Currently the SuspectState is just reset;
- *       it would be better to save it ...
- *
- * Context:
- *     runtime, pageable?
- *
- * Returns:
- *     Nothing
- */
-RLMT_STATIC void       SkRlmtBuildCheckChain(
-SK_AC  *pAC,   /* Adapter Context */
-SK_U32 NetIdx) /* Net Number */
-{
-       SK_U32                  i;
-       SK_U32                  NumMacsUp;
-       SK_RLMT_PORT *  FirstMacUp;
-       SK_RLMT_PORT *  PrevMacUp;
-
-       FirstMacUp      = NULL;
-       PrevMacUp       = NULL;
-       
-       if (!(pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_CHECK_LOC_LINK)) {
-               for (i = 0; i < pAC->Rlmt.Net[i].NumPorts; i++) {
-                       pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked = 0;
-               }
-               return; /* Done. */
-       }
-                       
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SkRlmtBuildCheckChain.\n"))
-
-       NumMacsUp = 0;
-
-       for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) {
-               pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked = 0;
-               pAC->Rlmt.Net[NetIdx].Port[i]->PortsSuspect = 0;
-               pAC->Rlmt.Net[NetIdx].Port[i]->CheckingState &=
-                       ~(SK_RLMT_PCS_RX | SK_RLMT_PCS_TX);
-
-               /*
-                * If more than two links are detected we should consider
-                * checking at least two other ports:
-                * 1. the next port that is not LinkDown and
-                * 2. the next port that is not PortDown.
-                */
-               if (!pAC->Rlmt.Net[NetIdx].Port[i]->LinkDown) {
-                       if (NumMacsUp == 0) {
-                               FirstMacUp = pAC->Rlmt.Net[NetIdx].Port[i];
-                       }
-                       else {
-                               PrevMacUp->PortCheck[
-                                       pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked].CheckAddr =
-                                       pAC->Rlmt.Net[NetIdx].Port[i]->AddrPort->CurrentMacAddress;
-                               PrevMacUp->PortCheck[
-                                       PrevMacUp->PortsChecked].SuspectTx = SK_FALSE;
-                               PrevMacUp->PortsChecked++;
-                       }
-                       PrevMacUp = pAC->Rlmt.Net[NetIdx].Port[i];
-                       NumMacsUp++;
-               }
-       }
-
-       if (NumMacsUp > 1) {
-               PrevMacUp->PortCheck[PrevMacUp->PortsChecked].CheckAddr =
-                       FirstMacUp->AddrPort->CurrentMacAddress;
-               PrevMacUp->PortCheck[PrevMacUp->PortsChecked].SuspectTx =
-                       SK_FALSE;
-               PrevMacUp->PortsChecked++;
-       }
-
-#ifdef DEBUG
-       for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Port %d checks %d other ports: %2X.\n", i,
-                               pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked,
-                               pAC->Rlmt.Net[NetIdx].Port[i]->PortCheck[0].CheckAddr.a[5]))
-       }
-#endif /* DEBUG */
-
-       return;
-}      /* SkRlmtBuildCheckChain */
-
-
-/******************************************************************************
- *
- *     SkRlmtBuildPacket - build an RLMT packet
- *
- * Description:
- *     This routine sets up an RLMT packet.
- *
- * Context:
- *     runtime, pageable?
- *
- * Returns:
- *     NULL or pointer to RLMT mbuf
- */
-RLMT_STATIC SK_MBUF    *SkRlmtBuildPacket(
-SK_AC          *pAC,           /* Adapter Context */
-SK_IOC         IoC,            /* I/O Context */
-SK_U32         PortNumber,     /* Sending port */
-SK_U16         PacketType,     /* RLMT packet type */
-SK_MAC_ADDR    *SrcAddr,       /* Source address */
-SK_MAC_ADDR    *DestAddr)      /* Destination address */
-{
-       int             i;
-       SK_U16          Length;
-       SK_MBUF         *pMb;
-       SK_RLMT_PACKET  *pPacket;
-
-#ifdef DEBUG
-       SK_U8   CheckSrc  = 0;
-       SK_U8   CheckDest = 0;
-       
-       for (i = 0; i < SK_MAC_ADDR_LEN; ++i) {
-               CheckSrc  |= SrcAddr->a[i];
-               CheckDest |= DestAddr->a[i];
-       }
-
-       if ((CheckSrc == 0) || (CheckDest == 0)) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_ERR,
-                       ("SkRlmtBuildPacket: Invalid %s%saddr.\n",
-                        (CheckSrc == 0 ? "Src" : ""), (CheckDest == 0 ? "Dest" : "")))
-       }
-#endif
-
-       if ((pMb = SkDrvAllocRlmtMbuf(pAC, IoC, SK_RLMT_MAX_PACKET_SIZE)) != NULL) {
-               pPacket = (SK_RLMT_PACKET*)pMb->pData;
-               for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
-                       pPacket->DstAddr[i] = DestAddr->a[i];
-                       pPacket->SrcAddr[i] = SrcAddr->a[i];
-               }
-               pPacket->DSap = SK_RLMT_DSAP;
-               pPacket->SSap = SK_RLMT_SSAP;
-               pPacket->Ctrl = SK_RLMT_CTRL;
-               pPacket->Indicator[0] = SK_RLMT_INDICATOR0;
-               pPacket->Indicator[1] = SK_RLMT_INDICATOR1;
-               pPacket->Indicator[2] = SK_RLMT_INDICATOR2;
-               pPacket->Indicator[3] = SK_RLMT_INDICATOR3;
-               pPacket->Indicator[4] = SK_RLMT_INDICATOR4;
-               pPacket->Indicator[5] = SK_RLMT_INDICATOR5;
-               pPacket->Indicator[6] = SK_RLMT_INDICATOR6;
-
-               SK_U16_TO_NETWORK_ORDER(PacketType, &pPacket->RlmtPacketType[0]);
-
-               for (i = 0; i < 4; i++) {
-                       pPacket->Random[i] = pAC->Rlmt.Port[PortNumber].Random[i];
-               }
-               
-               SK_U16_TO_NETWORK_ORDER(
-                       SK_RLMT_PACKET_VERSION, &pPacket->RlmtPacketVersion[0]);
-
-               for (i = 0; i < SK_PACKET_DATA_LEN; i++) {
-                       pPacket->Data[i] = 0x00;
-               }
-
-               Length = SK_RLMT_MAX_PACKET_SIZE;       /* Or smaller. */
-               pMb->Length = Length;
-               pMb->PortIdx = PortNumber;
-               Length -= 14;
-               SK_U16_TO_NETWORK_ORDER(Length, &pPacket->TypeLen[0]);
-
-               if (PacketType == SK_PACKET_ALIVE) {
-                       pAC->Rlmt.Port[PortNumber].TxHelloCts++;
-               }
-       }
-
-       return (pMb);
-}      /* SkRlmtBuildPacket */
-
-
-/******************************************************************************
- *
- *     SkRlmtBuildSpanningTreePacket - build spanning tree check packet
- *
- * Description:
- *     This routine sets up a BPDU packet for spanning tree check.
- *
- * Context:
- *     runtime, pageable?
- *
- * Returns:
- *     NULL or pointer to RLMT mbuf
- */
-RLMT_STATIC SK_MBUF    *SkRlmtBuildSpanningTreePacket(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* I/O Context */
-SK_U32 PortNumber)     /* Sending port */
-{
-       unsigned                        i;
-       SK_U16                          Length;
-       SK_MBUF                         *pMb;
-       SK_SPTREE_PACKET        *pSPacket;
-
-       if ((pMb = SkDrvAllocRlmtMbuf(pAC, IoC, SK_RLMT_MAX_PACKET_SIZE)) !=
-               NULL) {
-               pSPacket = (SK_SPTREE_PACKET*)pMb->pData;
-               for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
-                       pSPacket->DstAddr[i] = BridgeMcAddr.a[i];
-                       pSPacket->SrcAddr[i] =
-                               pAC->Addr.Port[PortNumber].CurrentMacAddress.a[i];
-               }
-               pSPacket->DSap = SK_RLMT_SPT_DSAP;
-               pSPacket->SSap = SK_RLMT_SPT_SSAP;
-               pSPacket->Ctrl = SK_RLMT_SPT_CTRL;
-
-               pSPacket->ProtocolId[0] = SK_RLMT_SPT_PROTOCOL_ID0;
-               pSPacket->ProtocolId[1] = SK_RLMT_SPT_PROTOCOL_ID1;
-               pSPacket->ProtocolVersionId = SK_RLMT_SPT_PROTOCOL_VERSION_ID;
-               pSPacket->BpduType = SK_RLMT_SPT_BPDU_TYPE;
-               pSPacket->Flags = SK_RLMT_SPT_FLAGS;
-               pSPacket->RootId[0] = SK_RLMT_SPT_ROOT_ID0;
-               pSPacket->RootId[1] = SK_RLMT_SPT_ROOT_ID1;
-               pSPacket->RootPathCost[0] = SK_RLMT_SPT_ROOT_PATH_COST0;
-               pSPacket->RootPathCost[1] = SK_RLMT_SPT_ROOT_PATH_COST1;
-               pSPacket->RootPathCost[2] = SK_RLMT_SPT_ROOT_PATH_COST2;
-               pSPacket->RootPathCost[3] = SK_RLMT_SPT_ROOT_PATH_COST3;
-               pSPacket->BridgeId[0] = SK_RLMT_SPT_BRIDGE_ID0;
-               pSPacket->BridgeId[1] = SK_RLMT_SPT_BRIDGE_ID1;
-
-               /*
-                * Use logical MAC address as bridge ID and filter these packets
-                * on receive.
-                */
-               for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
-                       pSPacket->BridgeId[i + 2] = pSPacket->RootId[i + 2] =
-                               pAC->Addr.Net[pAC->Rlmt.Port[PortNumber].Net->NetNumber].
-                                       CurrentMacAddress.a[i];
-               }
-               pSPacket->PortId[0] = SK_RLMT_SPT_PORT_ID0;
-               pSPacket->PortId[1] = SK_RLMT_SPT_PORT_ID1;
-               pSPacket->MessageAge[0] = SK_RLMT_SPT_MSG_AGE0;
-               pSPacket->MessageAge[1] = SK_RLMT_SPT_MSG_AGE1;
-               pSPacket->MaxAge[0] = SK_RLMT_SPT_MAX_AGE0;
-               pSPacket->MaxAge[1] = SK_RLMT_SPT_MAX_AGE1;
-               pSPacket->HelloTime[0] = SK_RLMT_SPT_HELLO_TIME0;
-               pSPacket->HelloTime[1] = SK_RLMT_SPT_HELLO_TIME1;
-               pSPacket->ForwardDelay[0] = SK_RLMT_SPT_FWD_DELAY0;
-               pSPacket->ForwardDelay[1] = SK_RLMT_SPT_FWD_DELAY1;
-
-               Length = SK_RLMT_MAX_PACKET_SIZE;       /* Or smaller. */
-               pMb->Length = Length;
-               pMb->PortIdx = PortNumber;
-               Length -= 14;
-               SK_U16_TO_NETWORK_ORDER(Length, &pSPacket->TypeLen[0]);
-
-               pAC->Rlmt.Port[PortNumber].TxSpHelloReqCts++;
-       }
-
-       return (pMb);
-}      /* SkRlmtBuildSpanningTreePacket */
-
-
-/******************************************************************************
- *
- *     SkRlmtSend - build and send check packets
- *
- * Description:
- *     Depending on the RLMT state and the checking state, several packets
- *     are sent through the indicated port.
- *
- * Context:
- *     runtime, pageable?
- *
- * Returns:
- *     Nothing.
- */
-RLMT_STATIC void       SkRlmtSend(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* I/O Context */
-SK_U32 PortNumber)     /* Sending port */
-{
-       unsigned        j;
-       SK_EVPARA       Para;
-       SK_RLMT_PORT    *pRPort;
-
-       pRPort = &pAC->Rlmt.Port[PortNumber];
-       if (pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) {
-               if (pRPort->CheckingState & (SK_RLMT_PCS_TX | SK_RLMT_PCS_RX)) {
-                       /* Port is suspicious. Send the RLMT packet to the RLMT mc addr. */
-                       if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber,
-                               SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress,
-                               &SkRlmtMcAddr)) != NULL) {
-                               SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
-                       }
-               }
-               else {
-                       /*
-                        * Send a directed RLMT packet to all ports that are
-                        * checked by the indicated port.
-                        */
-                       for (j = 0; j < pRPort->PortsChecked; j++) {
-                               if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber,
-                                       SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress,
-                                       &pRPort->PortCheck[j].CheckAddr)) != NULL) {
-                                       SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
-                               }
-                       }
-               }
-       }
-
-       if ((pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG) &&
-               (pAC->Rlmt.Port[PortNumber].Net->CheckingState & SK_RLMT_RCS_SEND_SEG)) {
-               /*
-                * Send a BPDU packet to make a connected switch tell us
-                * the correct root bridge.
-                */
-               if ((Para.pParaPtr =
-                       SkRlmtBuildSpanningTreePacket(pAC, IoC, PortNumber)) != NULL) {
-                       pAC->Rlmt.Port[PortNumber].Net->CheckingState &= ~SK_RLMT_RCS_SEND_SEG;
-                       pRPort->RootIdSet = SK_FALSE;
-
-                       SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
-                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_TX,
-                               ("SkRlmtSend: BPDU Packet on Port %u.\n", PortNumber))
-               }
-       }
-       return;
-}      /* SkRlmtSend */
-
-
-/******************************************************************************
- *
- *     SkRlmtPortReceives - check if port is (going) down and bring it up
- *
- * Description:
- *     This routine checks if a port who received a non-BPDU packet
- *     needs to go up or needs to be stopped going down.
- *
- * Context:
- *     runtime, pageable?
- *
- * Returns:
- *     Nothing.
- */
-RLMT_STATIC void       SkRlmtPortReceives(
-SK_AC  *pAC,                   /* Adapter Context */
-SK_IOC IoC,                    /* I/O Context */
-SK_U32 PortNumber)             /* Port to check */
-{
-       SK_RLMT_PORT    *pRPort;
-       SK_EVPARA               Para;
-
-       pRPort = &pAC->Rlmt.Port[PortNumber];
-       pRPort->PortNoRx = SK_FALSE;
-
-       if ((pRPort->PortState == SK_RLMT_PS_DOWN) &&
-               !(pRPort->CheckingState & SK_RLMT_PCS_TX)) {
-               /*
-                * Port is marked down (rx), but received a non-BPDU packet.
-                * Bring it up.
-                */
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-                       ("SkRlmtPacketReceive: Received on PortDown.\n"))
-
-               pRPort->PortState = SK_RLMT_PS_GOING_UP;
-               pRPort->GuTimeStamp = SkOsGetTime(pAC);
-               Para.Para32[0] = PortNumber;
-               Para.Para32[1] = (SK_U32)-1;
-               SkTimerStart(pAC, IoC, &pRPort->UpTimer, SK_RLMT_PORTUP_TIM_VAL,
-                       SKGE_RLMT, SK_RLMT_PORTUP_TIM, Para);
-               pRPort->CheckingState &= ~SK_RLMT_PCS_RX;
-               /* pAC->Rlmt.CheckSwitch = SK_TRUE; */
-               SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
-       }       /* PortDown && !SuspectTx */
-       else if (pRPort->CheckingState & SK_RLMT_PCS_RX) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-                       ("SkRlmtPacketReceive: Stop bringing port down.\n"))
-               SkTimerStop(pAC, IoC, &pRPort->DownRxTimer);
-               pRPort->CheckingState &= ~SK_RLMT_PCS_RX;
-               /* pAC->Rlmt.CheckSwitch = SK_TRUE; */
-               SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
-       }       /* PortGoingDown */
-
-       return;
-}      /* SkRlmtPortReceives */
-
-
-/******************************************************************************
- *
- *     SkRlmtPacketReceive - receive a packet for closer examination
- *
- * Description:
- *     This routine examines a packet more closely than SK_RLMT_LOOKAHEAD.
- *
- * Context:
- *     runtime, pageable?
- *
- * Returns:
- *     Nothing.
- */
-RLMT_STATIC void       SkRlmtPacketReceive(
-SK_AC  *pAC,   /* Adapter Context */
-SK_IOC IoC,    /* I/O Context */
-SK_MBUF        *pMb)   /* Received packet */
-{
-#ifdef xDEBUG
-       extern  void DumpData(char *p, int size);
-#endif /* DEBUG */
-       int                                     i;
-       unsigned                        j;
-       SK_U16                          PacketType;
-       SK_U32                          PortNumber;
-       SK_ADDR_PORT            *pAPort;
-       SK_RLMT_PORT            *pRPort;
-       SK_RLMT_PACKET          *pRPacket;
-       SK_SPTREE_PACKET        *pSPacket;
-       SK_EVPARA                       Para;
-
-       PortNumber      = pMb->PortIdx;
-       pAPort = &pAC->Addr.Port[PortNumber];
-       pRPort = &pAC->Rlmt.Port[PortNumber];
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-               ("SkRlmtPacketReceive: PortNumber == %d.\n", PortNumber))
-
-       pRPacket = (SK_RLMT_PACKET*)pMb->pData;
-       pSPacket = (SK_SPTREE_PACKET*)pRPacket;
-
-#ifdef xDEBUG
-       DumpData((char *)pRPacket, 32);
-#endif /* DEBUG */
-
-       if ((pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot) != 0) {
-               SkRlmtPortReceives(pAC, IoC, PortNumber);
-       }
-       
-       /* Check destination address. */
-
-       if (!SK_ADDR_EQUAL(pAPort->CurrentMacAddress.a, pRPacket->DstAddr) &&
-               !SK_ADDR_EQUAL(SkRlmtMcAddr.a, pRPacket->DstAddr) &&
-               !SK_ADDR_EQUAL(BridgeMcAddr.a, pRPacket->DstAddr)) {
-
-               /* Not sent to current MAC or registered MC address => Trash it. */
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-                       ("SkRlmtPacketReceive: Not for me.\n"))
-
-               SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
-               return;
-       }
-       else if (SK_ADDR_EQUAL(pAPort->CurrentMacAddress.a, pRPacket->SrcAddr)) {
-
-               /*
-                * Was sent by same port (may happen during port switching
-                * or in case of duplicate MAC addresses).
-                */
-
-               /*
-                * Check for duplicate address here:
-                * If Packet.Random != My.Random => DupAddr.
-                */
-               for (i = 3; i >= 0; i--) {
-                       if (pRPort->Random[i] != pRPacket->Random[i]) {
-                               break;
-                       }
-               }
-
-               /*
-                * CAUTION: Do not check for duplicate MAC address in RLMT Alive Reply
-                * packets (they have the LLC_COMMAND_RESPONSE_BIT set in
-                * pRPacket->SSap).
-                */
-               if (i >= 0 && pRPacket->DSap == SK_RLMT_DSAP &&
-                       pRPacket->Ctrl == SK_RLMT_CTRL &&
-                       pRPacket->SSap == SK_RLMT_SSAP &&
-                       pRPacket->Indicator[0] == SK_RLMT_INDICATOR0 &&
-                       pRPacket->Indicator[1] == SK_RLMT_INDICATOR1 &&
-                       pRPacket->Indicator[2] == SK_RLMT_INDICATOR2 &&
-                       pRPacket->Indicator[3] == SK_RLMT_INDICATOR3 &&
-                       pRPacket->Indicator[4] == SK_RLMT_INDICATOR4 &&
-                       pRPacket->Indicator[5] == SK_RLMT_INDICATOR5 &&
-                       pRPacket->Indicator[6] == SK_RLMT_INDICATOR6) {
-                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-                               ("SkRlmtPacketReceive: Duplicate MAC Address.\n"))
-
-                       /* Error Log entry. */
-                       SK_ERR_LOG(pAC, SK_ERRCL_COMM, SKERR_RLMT_E006, SKERR_RLMT_E006_MSG);
-               }
-               else {
-                       /* Simply trash it. */
-                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-                               ("SkRlmtPacketReceive: Sent by me.\n"))
-               }
-
-               SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
-               return;
-       }
-
-       /* Check SuspectTx entries. */
-       if (pRPort->PortsSuspect > 0) {
-               for (j = 0; j < pRPort->PortsChecked; j++) {
-                       if (pRPort->PortCheck[j].SuspectTx &&
-                               SK_ADDR_EQUAL(
-                                       pRPacket->SrcAddr, pRPort->PortCheck[j].CheckAddr.a)) {
-                               pRPort->PortCheck[j].SuspectTx = SK_FALSE;
-                               pRPort->PortsSuspect--;
-                               break;
-                       }
-               }
-       }
-
-       /* Determine type of packet. */
-       if (pRPacket->DSap == SK_RLMT_DSAP &&
-               pRPacket->Ctrl == SK_RLMT_CTRL &&
-               (pRPacket->SSap & ~LLC_COMMAND_RESPONSE_BIT) == SK_RLMT_SSAP &&
-               pRPacket->Indicator[0] == SK_RLMT_INDICATOR0 &&
-               pRPacket->Indicator[1] == SK_RLMT_INDICATOR1 &&
-               pRPacket->Indicator[2] == SK_RLMT_INDICATOR2 &&
-               pRPacket->Indicator[3] == SK_RLMT_INDICATOR3 &&
-               pRPacket->Indicator[4] == SK_RLMT_INDICATOR4 &&
-               pRPacket->Indicator[5] == SK_RLMT_INDICATOR5 &&
-               pRPacket->Indicator[6] == SK_RLMT_INDICATOR6) {
-
-               /* It's an RLMT packet. */
-               PacketType = (SK_U16)((pRPacket->RlmtPacketType[0] << 8) |
-                       pRPacket->RlmtPacketType[1]);
-
-               switch (PacketType) {
-               case SK_PACKET_ANNOUNCE:        /* Not yet used. */
-#if 0
-                       /* Build the check chain. */
-                       SkRlmtBuildCheckChain(pAC);
-#endif /* 0 */
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-                               ("SkRlmtPacketReceive: Announce.\n"))
-
-                       SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
-                       break;
-
-               case SK_PACKET_ALIVE:
-                       if (pRPacket->SSap & LLC_COMMAND_RESPONSE_BIT) {
-                               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-                                       ("SkRlmtPacketReceive: Alive Reply.\n"))
-
-                               if (!(pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_LLC) ||
-                                       SK_ADDR_EQUAL(
-                                               pRPacket->DstAddr, pAPort->CurrentMacAddress.a)) {
-                                       /* Obviously we could send something. */
-                                       if (pRPort->CheckingState & SK_RLMT_PCS_TX) {
-                                               pRPort->CheckingState &=  ~SK_RLMT_PCS_TX;
-                                               SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
-                                       }
-
-                                       if ((pRPort->PortState == SK_RLMT_PS_DOWN) &&
-                                               !(pRPort->CheckingState & SK_RLMT_PCS_RX)) {
-                                               pRPort->PortState = SK_RLMT_PS_GOING_UP;
-                                               pRPort->GuTimeStamp = SkOsGetTime(pAC);
-
-                                               SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
-
-                                               Para.Para32[0] = PortNumber;
-                                               Para.Para32[1] = (SK_U32)-1;
-                                               SkTimerStart(pAC, IoC, &pRPort->UpTimer,
-                                                       SK_RLMT_PORTUP_TIM_VAL, SKGE_RLMT,
-                                                       SK_RLMT_PORTUP_TIM, Para);
-                                       }
-                               }
-
-                               /* Mark sending port as alive? */
-                               SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
-                       }
-                       else {  /* Alive Request Packet. */
-                               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-                                       ("SkRlmtPacketReceive: Alive Request.\n"))
-
-                               pRPort->RxHelloCts++;
-
-                               /* Answer. */
-                               for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
-                                       pRPacket->DstAddr[i] = pRPacket->SrcAddr[i];
-                                       pRPacket->SrcAddr[i] =
-                                               pAC->Addr.Port[PortNumber].CurrentMacAddress.a[i];
-                               }
-                               pRPacket->SSap |= LLC_COMMAND_RESPONSE_BIT;
-
-                               Para.pParaPtr = pMb;
-                               SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
-                       }
-                       break;
-
-               case SK_PACKET_CHECK_TX:
-                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-                               ("SkRlmtPacketReceive: Check your tx line.\n"))
-
-                       /* A port checking us requests us to check our tx line. */
-                       pRPort->CheckingState |= SK_RLMT_PCS_TX;
-
-                       /* Start PortDownTx timer. */
-                       Para.Para32[0] = PortNumber;
-                       Para.Para32[1] = (SK_U32)-1;
-                       SkTimerStart(pAC, IoC, &pRPort->DownTxTimer,
-                               SK_RLMT_PORTDOWN_TIM_VAL, SKGE_RLMT,
-                               SK_RLMT_PORTDOWN_TX_TIM, Para);
-
-                       SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
-
-                       if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber,
-                               SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress,
-                               &SkRlmtMcAddr)) != NULL) {
-                               SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
-                       }
-                       break;
-
-               case SK_PACKET_ADDR_CHANGED:
-                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-                               ("SkRlmtPacketReceive: Address Change.\n"))
-
-                       /* Build the check chain. */
-                       SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber);
-                       SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
-                       break;
-
-               default:
-                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-                               ("SkRlmtPacketReceive: Unknown RLMT packet.\n"))
-
-                       /* RA;:;: ??? */
-                       SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
-               }
-       }
-       else if (pSPacket->DSap == SK_RLMT_SPT_DSAP &&
-               pSPacket->Ctrl == SK_RLMT_SPT_CTRL &&
-               (pSPacket->SSap & ~LLC_COMMAND_RESPONSE_BIT) == SK_RLMT_SPT_SSAP) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-                       ("SkRlmtPacketReceive: BPDU Packet.\n"))
-
-               /* Spanning Tree packet. */
-               pRPort->RxSpHelloCts++;
-
-               if (!SK_ADDR_EQUAL(&pSPacket->RootId[2], &pAC->Addr.Net[pAC->Rlmt.
-                       Port[PortNumber].Net->NetNumber].CurrentMacAddress.a[0])) {
-                       /*
-                        * Check segmentation if a new root bridge is set and
-                        * the segmentation check is not currently running.
-                        */
-                       if (!SK_ADDR_EQUAL(&pSPacket->RootId[2], &pRPort->Root.Id[2]) &&
-                               (pAC->Rlmt.Port[PortNumber].Net->LinksUp > 1) &&
-                               (pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG)
-                               != 0 && (pAC->Rlmt.Port[PortNumber].Net->CheckingState &
-                               SK_RLMT_RCS_SEG) == 0) {
-                               pAC->Rlmt.Port[PortNumber].Net->CheckingState |=
-                                       SK_RLMT_RCS_START_SEG | SK_RLMT_RCS_SEND_SEG;
-                       }
-
-                       /* Store tree view of this port. */
-                       for (i = 0; i < 8; i++) {
-                               pRPort->Root.Id[i] = pSPacket->RootId[i];
-                       }
-                       pRPort->RootIdSet = SK_TRUE;
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_DUMP,
-                               ("Root ID %d: %02x %02x %02x %02x %02x %02x %02x %02x.\n",
-                                       PortNumber,
-                                       pRPort->Root.Id[0], pRPort->Root.Id[1],
-                                       pRPort->Root.Id[2], pRPort->Root.Id[3],
-                                       pRPort->Root.Id[4], pRPort->Root.Id[5],
-                                       pRPort->Root.Id[6], pRPort->Root.Id[7]))
-               }
-
-               SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
-               if ((pAC->Rlmt.Port[PortNumber].Net->CheckingState &
-                       SK_RLMT_RCS_REPORT_SEG) != 0) {
-                       SkRlmtCheckSeg(pAC, IoC, pAC->Rlmt.Port[PortNumber].Net->NetNumber);
-               }
-       }
-       else {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-                       ("SkRlmtPacketReceive: Unknown Packet Type.\n"))
-
-               /* Unknown packet. */
-               SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
-       }
-       return;
-}      /* SkRlmtPacketReceive */
-
-
-/******************************************************************************
- *
- *     SkRlmtCheckPort - check if a port works
- *
- * Description:
- *     This routine checks if a port whose link is up received something
- *     and if it seems to transmit successfully.
- *
- *     # PortState: PsInit, PsLinkDown, PsDown, PsGoingUp, PsUp
- *     # PortCheckingState (Bitfield): ChkTx, ChkRx, ChkSeg
- *     # RlmtCheckingState (Bitfield): ChkSeg, StartChkSeg, ReportSeg
- *
- *     if (Rx - RxBpdu == 0) { # No rx.
- *             if (state == PsUp) {
- *                     PortCheckingState |= ChkRx
- *             }
- *             if (ModeCheckSeg && (Timeout ==
- *                     TO_SHORTEN(RLMT_DEFAULT_TIMEOUT))) {
- *                     RlmtCheckingState |= ChkSeg)
- *                     PortCheckingState |= ChkSeg
- *             }
- *             NewTimeout = TO_SHORTEN(Timeout)
- *             if (NewTimeout < RLMT_MIN_TIMEOUT) {
- *                     NewTimeout = RLMT_MIN_TIMEOUT
- *                     PortState = PsDown
- *                     ...
- *             }
- *     }
- *     else {  # something was received
- *             # Set counter to 0 at LinkDown?
- *             #   No - rx may be reported after LinkDown ???
- *             PortCheckingState &= ~ChkRx
- *             NewTimeout = RLMT_DEFAULT_TIMEOUT
- *             if (RxAck == 0) {
- *                     possible reasons:
- *                     is my tx line bad? --
- *                             send RLMT multicast and report
- *                             back internally? (only possible
- *                             between ports on same adapter)
- *             }
- *             if (RxChk == 0) {
- *                     possible reasons:
- *                     - tx line of port set to check me
- *                       maybe bad
- *                     - no other port/adapter available or set
- *                       to check me
- *                     - adapter checking me has a longer
- *                       timeout
- *                     ??? anything that can be done here?
- *             }
- *     }
- *
- * Context:
- *     runtime, pageable?
- *
- * Returns:
- *     New timeout value.
- */
-RLMT_STATIC SK_U32     SkRlmtCheckPort(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* I/O Context */
-SK_U32 PortNumber)     /* Port to check */
-{
-       unsigned                i;
-       SK_U32                  NewTimeout;
-       SK_RLMT_PORT    *pRPort;
-       SK_EVPARA               Para;
-
-       pRPort = &pAC->Rlmt.Port[PortNumber];
-
-       if ((pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot) == 0) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SkRlmtCheckPort %d: No (%d) receives in last time slot.\n",
-                               PortNumber, pRPort->PacketsPerTimeSlot))
-
-               /*
-                * Check segmentation if there was no receive at least twice
-                * in a row (PortNoRx is already set) and the segmentation
-                * check is not currently running.
-                */
-
-               if (pRPort->PortNoRx && (pAC->Rlmt.Port[PortNumber].Net->LinksUp > 1) &&
-                       (pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG) &&
-                       !(pAC->Rlmt.Port[PortNumber].Net->CheckingState & SK_RLMT_RCS_SEG)) {
-                       pAC->Rlmt.Port[PortNumber].Net->CheckingState |=
-                               SK_RLMT_RCS_START_SEG | SK_RLMT_RCS_SEND_SEG;
-               }
-
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SkRlmtCheckPort: PortsSuspect %d, PcsRx %d.\n",
-                               pRPort->PortsSuspect, pRPort->CheckingState & SK_RLMT_PCS_RX))
-
-               if (pRPort->PortState != SK_RLMT_PS_DOWN) {
-                       NewTimeout = TO_SHORTEN(pAC->Rlmt.Port[PortNumber].Net->TimeoutValue);
-                       if (NewTimeout < SK_RLMT_MIN_TO_VAL) {
-                               NewTimeout = SK_RLMT_MIN_TO_VAL;
-                       }
-
-                       if (!(pRPort->CheckingState & SK_RLMT_PCS_RX)) {
-                               Para.Para32[0] = PortNumber;
-                               pRPort->CheckingState |= SK_RLMT_PCS_RX;
-
-                               /*
-                                * What shall we do if the port checked by this one receives
-                                * our request frames?  What's bad - our rx line or his tx line?
-                                */
-                               Para.Para32[1] = (SK_U32)-1;
-                               SkTimerStart(pAC, IoC, &pRPort->DownRxTimer,
-                                       SK_RLMT_PORTDOWN_TIM_VAL, SKGE_RLMT,
-                                       SK_RLMT_PORTDOWN_RX_TIM, Para);
-
-                               for (i = 0; i < pRPort->PortsChecked; i++) {
-                                       if (pRPort->PortCheck[i].SuspectTx) {
-                                               continue;
-                                       }
-                                       pRPort->PortCheck[i].SuspectTx = SK_TRUE;
-                                       pRPort->PortsSuspect++;
-                                       if ((Para.pParaPtr =
-                                               SkRlmtBuildPacket(pAC, IoC, PortNumber, SK_PACKET_CHECK_TX,
-                                                       &pAC->Addr.Port[PortNumber].CurrentMacAddress,
-                                                       &pRPort->PortCheck[i].CheckAddr)) != NULL) {
-                                               SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
-                                       }
-                               }
-                       }
-               }
-               else {  /* PortDown -- or all partners suspect. */
-                       NewTimeout = SK_RLMT_DEF_TO_VAL;
-               }
-               pRPort->PortNoRx = SK_TRUE;
-       }
-       else {  /* A non-BPDU packet was received. */
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SkRlmtCheckPort %d: %d (%d) receives in last time slot.\n",
-                               PortNumber,
-                               pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot,
-                               pRPort->PacketsPerTimeSlot))
-               
-               SkRlmtPortReceives(pAC, IoC, PortNumber);
-               if (pAC->Rlmt.CheckSwitch) {
-                       SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
-               }
-
-               NewTimeout = SK_RLMT_DEF_TO_VAL;
-       }
-
-       return (NewTimeout);
-}      /* SkRlmtCheckPort */
-
-
-/******************************************************************************
- *
- *     SkRlmtSelectBcRx - select new active port, criteria 1 (CLP)
- *
- * Description:
- *     This routine selects the port that received a broadcast frame
- *     substantially later than all other ports.
- *
- * Context:
- *     runtime, pageable?
- *
- * Returns:
- *     SK_BOOL
- */
-RLMT_STATIC SK_BOOL    SkRlmtSelectBcRx(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* I/O Context */
-SK_U32 Active,         /* Active port */
-SK_U32 PrefPort,       /* Preferred port */
-SK_U32 *pSelect)       /* New active port */
-{
-       SK_U64          BcTimeStamp;
-       SK_U32          i;
-       SK_BOOL         PortFound;
-
-       BcTimeStamp = 0;        /* Not totally necessary, but feeling better. */
-       PortFound = SK_FALSE;
-       
-       /* Select port with the latest TimeStamp. */
-       for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
-
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("TimeStamp Port %d (Down: %d, NoRx: %d): %08x %08x.\n",
-                               i,
-                               pAC->Rlmt.Port[i].PortDown, pAC->Rlmt.Port[i].PortNoRx,
-                               *((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_HI32),
-                               *((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_LO32)))
-
-               if (!pAC->Rlmt.Port[i].PortDown && !pAC->Rlmt.Port[i].PortNoRx) {
-                       if (!PortFound || pAC->Rlmt.Port[i].BcTimeStamp > BcTimeStamp) {
-                               BcTimeStamp = pAC->Rlmt.Port[i].BcTimeStamp;
-                               *pSelect = i;
-                               PortFound = SK_TRUE;
-                       }
-               }
-       }
-
-       if (PortFound) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Port %d received the last broadcast.\n", *pSelect))
-
-               /* Look if another port's time stamp is similar. */
-               for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
-                       if (i == *pSelect) {
-                               continue;
-                       }
-                       if (!pAC->Rlmt.Port[i].PortDown && !pAC->Rlmt.Port[i].PortNoRx &&
-                               (pAC->Rlmt.Port[i].BcTimeStamp >
-                                BcTimeStamp - SK_RLMT_BC_DELTA ||
-                               pAC->Rlmt.Port[i].BcTimeStamp +
-                                SK_RLMT_BC_DELTA > BcTimeStamp)) {
-                               PortFound = SK_FALSE;
-                               
-                               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                                       ("Port %d received a broadcast at a similar time.\n", i))
-                               break;
-                       }
-               }
-       }
-
-#ifdef DEBUG
-       if (PortFound) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_SELECT_BCRX found Port %d receiving the substantially "
-                        "latest broadcast (%u).\n",
-                               *pSelect,
-                               BcTimeStamp - pAC->Rlmt.Port[1 - *pSelect].BcTimeStamp))
-       }
-#endif /* DEBUG */
-
-       return (PortFound);
-}      /* SkRlmtSelectBcRx */
-
-
-/******************************************************************************
- *
- *     SkRlmtSelectNotSuspect - select new active port, criteria 2 (CLP)
- *
- * Description:
- *     This routine selects a good port (it is PortUp && !SuspectRx).
- *
- * Context:
- *     runtime, pageable?
- *
- * Returns:
- *     SK_BOOL
- */
-RLMT_STATIC SK_BOOL    SkRlmtSelectNotSuspect(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* I/O Context */
-SK_U32 Active,         /* Active port */
-SK_U32 PrefPort,       /* Preferred port */
-SK_U32 *pSelect)       /* New active port */
-{
-       SK_U32          i;
-       SK_BOOL         PortFound;
-
-       PortFound = SK_FALSE;
-
-       /* Select first port that is PortUp && !SuspectRx. */
-       for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
-               if (!pAC->Rlmt.Port[i].PortDown &&
-                       !(pAC->Rlmt.Port[i].CheckingState & SK_RLMT_PCS_RX)) {
-                       *pSelect = i;
-                       if (!pAC->Rlmt.Port[Active].PortDown &&
-                               !(pAC->Rlmt.Port[Active].CheckingState & SK_RLMT_PCS_RX)) {
-                               *pSelect = Active;
-                       }
-                       if (!pAC->Rlmt.Port[PrefPort].PortDown &&
-                               !(pAC->Rlmt.Port[PrefPort].CheckingState & SK_RLMT_PCS_RX)) {
-                               *pSelect = PrefPort;
-                       }
-                       PortFound = SK_TRUE;
-                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                               ("SK_RLMT_SELECT_NOTSUSPECT found Port %d up and not check RX.\n",
-                                       *pSelect))
-                       break;
-               }
-       }
-       return (PortFound);
-}      /* SkRlmtSelectNotSuspect */
-
-
-/******************************************************************************
- *
- *     SkRlmtSelectUp - select new active port, criteria 3, 4 (CLP)
- *
- * Description:
- *     This routine selects a port that is up.
- *
- * Context:
- *     runtime, pageable?
- *
- * Returns:
- *     SK_BOOL
- */
-RLMT_STATIC SK_BOOL    SkRlmtSelectUp(
-SK_AC  *pAC,                   /* Adapter Context */
-SK_IOC IoC,                    /* I/O Context */
-SK_U32 Active,                 /* Active port */
-SK_U32 PrefPort,               /* Preferred port */
-SK_U32 *pSelect,               /* New active port */
-SK_BOOL        AutoNegDone)    /* Successfully auto-negotiated? */
-{
-       SK_U32          i;
-       SK_BOOL         PortFound;
-
-       PortFound = SK_FALSE;
-
-       /* Select first port that is PortUp. */
-       for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
-               if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_UP &&
-                       pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {
-                       *pSelect = i;
-                       if (pAC->Rlmt.Port[Active].PortState == SK_RLMT_PS_UP &&
-                               pAC->GIni.GP[Active].PAutoNegFail != AutoNegDone) {
-                               *pSelect = Active;
-                       }
-                       if (pAC->Rlmt.Port[PrefPort].PortState == SK_RLMT_PS_UP &&
-                               pAC->GIni.GP[PrefPort].PAutoNegFail != AutoNegDone) {
-                               *pSelect = PrefPort;
-                       }
-                       PortFound = SK_TRUE;
-                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                               ("SK_RLMT_SELECT_UP found Port %d up.\n", *pSelect))
-                       break;
-               }
-       }
-       return (PortFound);
-}      /* SkRlmtSelectUp */
-
-
-/******************************************************************************
- *
- *     SkRlmtSelectGoingUp - select new active port, criteria 5, 6 (CLP)
- *
- * Description:
- *     This routine selects the port that is going up for the longest time.
- *
- * Context:
- *     runtime, pageable?
- *
- * Returns:
- *     SK_BOOL
- */
-RLMT_STATIC SK_BOOL    SkRlmtSelectGoingUp(
-SK_AC  *pAC,                   /* Adapter Context */
-SK_IOC IoC,                    /* I/O Context */
-SK_U32 Active,                 /* Active port */
-SK_U32 PrefPort,               /* Preferred port */
-SK_U32 *pSelect,               /* New active port */
-SK_BOOL        AutoNegDone)    /* Successfully auto-negotiated? */
-{
-       SK_U64          GuTimeStamp;
-       SK_U32          i;
-       SK_BOOL         PortFound;
-
-       GuTimeStamp = 0;
-       PortFound = SK_FALSE;
-
-       /* Select port that is PortGoingUp for the longest time. */
-       for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
-               if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_GOING_UP &&
-                       pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {
-                       GuTimeStamp = pAC->Rlmt.Port[i].GuTimeStamp;
-                       *pSelect = i;
-                       PortFound = SK_TRUE;
-                       break;
-               }
-       }
-
-       if (!PortFound) {
-               return (SK_FALSE);
-       }
-
-       for (i = *pSelect + 1; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
-               if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_GOING_UP &&
-                       pAC->Rlmt.Port[i].GuTimeStamp < GuTimeStamp &&
-                       pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {
-                       GuTimeStamp = pAC->Rlmt.Port[i].GuTimeStamp;
-                       *pSelect = i;
-               }
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_SELECT_GOINGUP found Port %d going up.\n", *pSelect))
-       return (SK_TRUE);
-}      /* SkRlmtSelectGoingUp */
-
-
-/******************************************************************************
- *
- *     SkRlmtSelectDown - select new active port, criteria 7, 8 (CLP)
- *
- * Description:
- *     This routine selects a port that is down.
- *
- * Context:
- *     runtime, pageable?
- *
- * Returns:
- *     SK_BOOL
- */
-RLMT_STATIC SK_BOOL    SkRlmtSelectDown(
-SK_AC  *pAC,                   /* Adapter Context */
-SK_IOC IoC,                    /* I/O Context */
-SK_U32 Active,                 /* Active port */
-SK_U32 PrefPort,               /* Preferred port */
-SK_U32 *pSelect,               /* New active port */
-SK_BOOL        AutoNegDone)    /* Successfully auto-negotiated? */
-{
-       SK_U32          i;
-       SK_BOOL         PortFound;
-
-       PortFound = SK_FALSE;
-
-       /* Select first port that is PortDown. */
-       for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
-               if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_DOWN &&
-                       pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {
-                       *pSelect = i;
-                       if (pAC->Rlmt.Port[Active].PortState == SK_RLMT_PS_DOWN &&
-                               pAC->GIni.GP[Active].PAutoNegFail != AutoNegDone) {
-                               *pSelect = Active;
-                       }
-                       if (pAC->Rlmt.Port[PrefPort].PortState == SK_RLMT_PS_DOWN &&
-                               pAC->GIni.GP[PrefPort].PAutoNegFail != AutoNegDone) {
-                               *pSelect = PrefPort;
-                       }
-                       PortFound = SK_TRUE;
-                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                               ("SK_RLMT_SELECT_DOWN found Port %d down.\n", *pSelect))
-                       break;
-               }
-       }
-       return (PortFound);
-}      /* SkRlmtSelectDown */
-
-
-/******************************************************************************
- *
- *     SkRlmtCheckSwitch - select new active port and switch to it
- *
- * Description:
- *     This routine decides which port should be the active one and queues
- *     port switching if necessary.
- *
- * Context:
- *     runtime, pageable?
- *
- * Returns:
- *     Nothing.
- */
-RLMT_STATIC void       SkRlmtCheckSwitch(
-SK_AC  *pAC,   /* Adapter Context */
-SK_IOC IoC,    /* I/O Context */
-SK_U32 NetIdx) /* Net index */
-{
-       SK_EVPARA       Para;
-       SK_U32          Active;
-       SK_U32          PrefPort;
-       SK_U32          i;
-       SK_BOOL         PortFound;
-
-       Active = pAC->Rlmt.Net[NetIdx].ActivePort;      /* Index of active port. */
-       PrefPort = pAC->Rlmt.Net[NetIdx].PrefPort;      /* Index of preferred port. */
-       PortFound = SK_FALSE;
-       pAC->Rlmt.CheckSwitch = SK_FALSE;
-
-#if 0  /* RW 2001/10/18 - active port becomes always prefered one */
-       if (pAC->Rlmt.Net[NetIdx].Preference == 0xFFFFFFFF) { /* Automatic */
-               /* disable auto-fail back */
-               PrefPort = Active;
-       }
-#endif
-
-       if (pAC->Rlmt.Net[NetIdx].LinksUp == 0) {
-               /* Last link went down - shut down the net. */
-               pAC->Rlmt.Net[NetIdx].RlmtState = SK_RLMT_RS_NET_DOWN;
-               Para.Para32[0] = SK_RLMT_NET_DOWN_TEMP;
-               Para.Para32[1] = NetIdx;
-               SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_DOWN, Para);
-
-               Para.Para32[0] = pAC->Rlmt.Net[NetIdx].
-                       Port[pAC->Rlmt.Net[NetIdx].ActivePort]->PortNumber;
-               Para.Para32[1] = NetIdx;
-               SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_DOWN, Para);
-               return;
-       }       /* pAC->Rlmt.LinksUp == 0 */
-       else if (pAC->Rlmt.Net[NetIdx].LinksUp == 1 &&
-               pAC->Rlmt.Net[NetIdx].RlmtState == SK_RLMT_RS_NET_DOWN) {
-               /* First link came up - get the net up. */
-               pAC->Rlmt.Net[NetIdx].RlmtState = SK_RLMT_RS_NET_UP;
-
-               /*
-                * If pAC->Rlmt.ActivePort != Para.Para32[0],
-                * the DRV switches to the port that came up.
-                */
-               for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) {
-                       if (!pAC->Rlmt.Net[NetIdx].Port[i]->LinkDown) {
-                               if (!pAC->Rlmt.Net[NetIdx].Port[Active]->LinkDown) {
-                                       i = Active;
-                               }
-                               if (!pAC->Rlmt.Net[NetIdx].Port[PrefPort]->LinkDown) {
-                                       i = PrefPort;
-                               }
-                               PortFound = SK_TRUE;
-                               break;
-                       }
-               }
-
-               if (PortFound) {
-                       Para.Para32[0] = pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber;
-                       Para.Para32[1] = NetIdx;
-                       SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_UP, Para);
-
-                       pAC->Rlmt.Net[NetIdx].ActivePort = i;
-                       Para.Para32[0] = pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber;
-                       Para.Para32[1] = NetIdx;
-                       SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_UP, Para);
-
-                       if ((pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_TRANSPARENT) == 0 &&
-                               (Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC,
-                               pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber,
-                               SK_PACKET_ANNOUNCE, &pAC->Addr.Net[NetIdx].
-                               CurrentMacAddress, &SkRlmtMcAddr)) != NULL) {
-                               /*
-                                * Send announce packet to RLMT multicast address to force
-                                * switches to learn the new location of the logical MAC address.
-                                */
-                               SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
-                       }
-               }
-               else {
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E007, SKERR_RLMT_E007_MSG);
-               }
-
-               return;
-       }       /* LinksUp == 1 && RlmtState == SK_RLMT_RS_NET_DOWN */
-       else {  /* Cannot be reached in dual-net mode. */
-               Para.Para32[0] = Active;
-
-               /*
-                * Preselection:
-                *      If RLMT Mode != CheckLinkState
-                *              select port that received a broadcast frame substantially later
-                *              than all other ports
-                *      else select first port that is not SuspectRx
-                *      else select first port that is PortUp
-                *      else select port that is PortGoingUp for the longest time
-                *      else select first port that is PortDown
-                *      else stop.
-                *
-                * For the preselected port:
-                *      If ActivePort is equal in quality, select ActivePort.
-                *
-                *      If PrefPort is equal in quality, select PrefPort.
-                *
-                *      If ActivePort != SelectedPort,
-                *              If old ActivePort is LinkDown,
-                *                      SwitchHard
-                *              else
-                *                      SwitchSoft
-                */
-               /* check of ChgBcPrio flag added */
-               if ((pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) &&
-                       (!pAC->Rlmt.Net[0].ChgBcPrio)) {
-                       
-                       if (!PortFound) {
-                               PortFound = SkRlmtSelectBcRx(
-                                       pAC, IoC, Active, PrefPort, &Para.Para32[1]);
-                       }
-
-                       if (!PortFound) {
-                               PortFound = SkRlmtSelectNotSuspect(
-                                       pAC, IoC, Active, PrefPort, &Para.Para32[1]);
-                       }
-               }       /* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */
-
-               /* with changed priority for last broadcast received */
-               if ((pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) &&
-                       (pAC->Rlmt.Net[0].ChgBcPrio)) {
-                       if (!PortFound) {
-                               PortFound = SkRlmtSelectNotSuspect(
-                                       pAC, IoC, Active, PrefPort, &Para.Para32[1]);
-                       }
-
-                       if (!PortFound) {
-                               PortFound = SkRlmtSelectBcRx(
-                                       pAC, IoC, Active, PrefPort, &Para.Para32[1]);
-                       }
-               }       /* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */
-
-               if (!PortFound) {
-                       PortFound = SkRlmtSelectUp(
-                               pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS);
-               }
-
-               if (!PortFound) {
-                       PortFound = SkRlmtSelectUp(
-                               pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED);
-               }
-
-               if (!PortFound) {
-                       PortFound = SkRlmtSelectGoingUp(
-                               pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS);
-               }
-
-               if (!PortFound) {
-                       PortFound = SkRlmtSelectGoingUp(
-                               pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED);
-               }
-
-               if (pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) {
-                       if (!PortFound) {
-                               PortFound = SkRlmtSelectDown(pAC, IoC,
-                                       Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS);
-                       }
-
-                       if (!PortFound) {
-                               PortFound = SkRlmtSelectDown(pAC, IoC,
-                                       Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED);
-                       }
-               }       /* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */
-
-               if (PortFound) {
-
-                       if (Para.Para32[1] != Active) {
-                               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                                       ("Active: %d, Para1: %d.\n", Active, Para.Para32[1]))
-                               pAC->Rlmt.Net[NetIdx].ActivePort = Para.Para32[1];
-                               Para.Para32[0] = pAC->Rlmt.Net[NetIdx].
-                                       Port[Para.Para32[0]]->PortNumber;
-                               Para.Para32[1] = pAC->Rlmt.Net[NetIdx].
-                                       Port[Para.Para32[1]]->PortNumber;
-                               SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[1], SK_LED_ACTIVE);
-                               if (pAC->Rlmt.Port[Active].LinkDown) {
-                                       SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_HARD, Para);
-                               }
-                               else {
-                                       SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_STANDBY);
-                                       SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_SOFT, Para);
-                               }
-                               Para.Para32[1] = NetIdx;
-                               Para.Para32[0] =
-                                       pAC->Rlmt.Net[NetIdx].Port[Para.Para32[0]]->PortNumber;
-                               SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_DOWN, Para);
-                               Para.Para32[0] = pAC->Rlmt.Net[NetIdx].
-                                       Port[pAC->Rlmt.Net[NetIdx].ActivePort]->PortNumber;
-                               SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_UP, Para);
-                               if ((pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_TRANSPARENT) == 0 &&
-                                       (Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, Para.Para32[0],
-                                       SK_PACKET_ANNOUNCE, &pAC->Addr.Net[NetIdx].CurrentMacAddress,
-                                       &SkRlmtMcAddr)) != NULL) {
-                                       /*
-                                        * Send announce packet to RLMT multicast address to force
-                                        * switches to learn the new location of the logical
-                                        * MAC address.
-                                        */
-                                       SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
-                               }       /* (Para.pParaPtr = SkRlmtBuildPacket(...)) != NULL */
-                       }       /* Para.Para32[1] != Active */
-               }       /* PortFound */
-               else {
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E004, SKERR_RLMT_E004_MSG);
-               }
-       }       /* LinksUp > 1 || LinksUp == 1 && RlmtState != SK_RLMT_RS_NET_DOWN */
-       return;
-}      /* SkRlmtCheckSwitch */
-
-
-/******************************************************************************
- *
- *     SkRlmtCheckSeg - Report if segmentation is detected
- *
- * Description:
- *     This routine checks if the ports see different root bridges and reports
- *     segmentation in such a case.
- *
- * Context:
- *     runtime, pageable?
- *
- * Returns:
- *     Nothing.
- */
-RLMT_STATIC void       SkRlmtCheckSeg(
-SK_AC  *pAC,   /* Adapter Context */
-SK_IOC IoC,    /* I/O Context */
-SK_U32 NetIdx) /* Net number */
-{
-       SK_EVPARA       Para;
-       SK_RLMT_NET     *pNet;
-       SK_U32          i, j;
-       SK_BOOL         Equal;
-
-       pNet = &pAC->Rlmt.Net[NetIdx];
-       pNet->RootIdSet = SK_FALSE;
-       Equal = SK_TRUE;
-
-       for (i = 0; i < pNet->NumPorts; i++) {
-               if (pNet->Port[i]->LinkDown || !pNet->Port[i]->RootIdSet) {
-                       continue;
-               }
-
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_DUMP,
-                       ("Root ID %d: %02x %02x %02x %02x %02x %02x %02x %02x.\n", i,
-                               pNet->Port[i]->Root.Id[0], pNet->Port[i]->Root.Id[1],
-                               pNet->Port[i]->Root.Id[2], pNet->Port[i]->Root.Id[3],
-                               pNet->Port[i]->Root.Id[4], pNet->Port[i]->Root.Id[5],
-                               pNet->Port[i]->Root.Id[6], pNet->Port[i]->Root.Id[7]))
-
-               if (!pNet->RootIdSet) {
-                       pNet->Root = pNet->Port[i]->Root;
-                       pNet->RootIdSet = SK_TRUE;
-                       continue;
-               }
-
-               for (j = 0; j < 8; j ++) {
-                       Equal &= pNet->Port[i]->Root.Id[j] == pNet->Root.Id[j];
-                       if (!Equal) {
-                               break;
-                       }
-               }
-               
-               if (!Equal) {
-                       SK_ERR_LOG(pAC, SK_ERRCL_COMM, SKERR_RLMT_E005, SKERR_RLMT_E005_MSG);
-                       Para.Para32[0] = NetIdx;
-                       Para.Para32[1] = (SK_U32)-1;
-                       SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SEGMENTATION, Para);
-
-                       pNet->CheckingState &= ~SK_RLMT_RCS_REPORT_SEG;
-
-                       /* 2000-03-06 RA: New. */
-                       Para.Para32[0] = NetIdx;
-                       Para.Para32[1] = (SK_U32)-1;
-                       SkTimerStart(pAC, IoC, &pNet->SegTimer, SK_RLMT_SEG_TO_VAL,
-                               SKGE_RLMT, SK_RLMT_SEG_TIM, Para);
-                       break;
-               }
-       }       /* for (i = 0; i < pNet->NumPorts; i++) */
-
-       /* 2000-03-06 RA: Moved here. */
-       /* Segmentation check not running anymore. */
-       pNet->CheckingState &= ~SK_RLMT_RCS_SEG;
-
-}      /* SkRlmtCheckSeg */
-
-
-/******************************************************************************
- *
- *     SkRlmtPortStart - initialize port variables and start port
- *
- * Description:
- *     This routine initializes a port's variables and issues a PORT_START
- *     to the HWAC module.  This handles retries if the start fails or the
- *     link eventually goes down.
- *
- * Context:
- *     runtime, pageable?
- *
- * Returns:
- *     Nothing
- */
-RLMT_STATIC void       SkRlmtPortStart(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* I/O Context */
-SK_U32 PortNumber)     /* Port number */
-{
-       SK_EVPARA       Para;
-
-       pAC->Rlmt.Port[PortNumber].PortState = SK_RLMT_PS_LINK_DOWN;
-       pAC->Rlmt.Port[PortNumber].PortStarted = SK_TRUE;
-       pAC->Rlmt.Port[PortNumber].LinkDown = SK_TRUE;
-       pAC->Rlmt.Port[PortNumber].PortDown = SK_TRUE;
-       pAC->Rlmt.Port[PortNumber].CheckingState = 0;
-       pAC->Rlmt.Port[PortNumber].RootIdSet = SK_FALSE;
-       Para.Para32[0] = PortNumber;
-       Para.Para32[1] = (SK_U32)-1;
-       SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
-}      /* SkRlmtPortStart */
-
-
-/******************************************************************************
- *
- *     SkRlmtEvtPortStartTim - PORT_START_TIM
- *
- * Description:
- *     This routine handles PORT_START_TIM events.
- *
- * Context:
- *     runtime, pageable?
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     Nothing
- */
-RLMT_STATIC void       SkRlmtEvtPortStartTim(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_EVPARA      Para)   /* SK_U32 PortNumber; SK_U32 -1 */
-{
-       SK_U32                  i;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_PORTSTART_TIMEOUT Port %d Event BEGIN.\n", Para.Para32[0]))
-
-               if (Para.Para32[1] != (SK_U32)-1) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Bad Parameter.\n"))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_PORTSTART_TIMEOUT Event EMPTY.\n"))
-               return;
-       }
-
-       /*
-        * Used to start non-preferred ports if the preferred one
-        * does not come up.
-        * This timeout needs only be set when starting the first
-        * (preferred) port.
-        */
-       if (pAC->Rlmt.Port[Para.Para32[0]].LinkDown) {
-               /* PORT_START failed. */
-               for (i = 0; i < pAC->Rlmt.Port[Para.Para32[0]].Net->NumPorts; i++) {
-                       if (!pAC->Rlmt.Port[Para.Para32[0]].Net->Port[i]->PortStarted) {
-                               SkRlmtPortStart(pAC, IoC,
-                                       pAC->Rlmt.Port[Para.Para32[0]].Net->Port[i]->PortNumber);
-                       }
-               }
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_PORTSTART_TIMEOUT Event END.\n"))
-}      /* SkRlmtEvtPortStartTim */
-
-
-/******************************************************************************
- *
- *     SkRlmtEvtLinkUp - LINK_UP
- *
- * Description:
- *     This routine handles LLINK_UP events.
- *
- * Context:
- *     runtime, pageable?
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     Nothing
- */
-RLMT_STATIC void       SkRlmtEvtLinkUp(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_EVPARA      Para)   /* SK_U32 PortNumber; SK_U32 Undefined */
-{
-       SK_U32                  i;
-       SK_RLMT_PORT    *pRPort;
-       SK_EVPARA               Para2;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_LINK_UP Port %d Event BEGIN.\n", Para.Para32[0]))
-
-       pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
-       if (!pRPort->PortStarted) {
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E008, SKERR_RLMT_E008_MSG);
-
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                               ("SK_RLMT_LINK_UP Event EMPTY.\n"))
-               return;
-       }
-
-       if (!pRPort->LinkDown) {
-               /* RA;:;: Any better solution? */
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_LINK_UP Event EMPTY.\n"))
-               return;
-       }
-
-       SkTimerStop(pAC, IoC, &pRPort->UpTimer);
-       SkTimerStop(pAC, IoC, &pRPort->DownRxTimer);
-       SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
-
-       /* Do something if timer already fired? */
-
-       pRPort->LinkDown = SK_FALSE;
-       pRPort->PortState = SK_RLMT_PS_GOING_UP;
-       pRPort->GuTimeStamp = SkOsGetTime(pAC);
-       pRPort->BcTimeStamp = 0;
-       pRPort->Net->LinksUp++;
-       if (pRPort->Net->LinksUp == 1) {
-               SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_ACTIVE);
-       }
-       else {
-               SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_STANDBY);
-       }
-
-       for (i = 0; i < pRPort->Net->NumPorts; i++) {
-               if (!pRPort->Net->Port[i]->PortStarted) {
-                       SkRlmtPortStart(pAC, IoC, pRPort->Net->Port[i]->PortNumber);
-               }
-       }
-
-       SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
-
-       if (pRPort->Net->LinksUp >= 2) {
-               if (pRPort->Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) {
-                       /* Build the check chain. */
-                       SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber);
-               }
-       }
-
-       /* If the first link comes up, start the periodical RLMT timeout. */
-       if (pRPort->Net->NumPorts > 1 && pRPort->Net->LinksUp == 1 &&
-               (pRPort->Net->RlmtMode & SK_RLMT_CHECK_OTHERS) != 0) {
-               Para2.Para32[0] = pRPort->Net->NetNumber;
-               Para2.Para32[1] = (SK_U32)-1;
-               SkTimerStart(pAC, IoC, &pRPort->Net->LocTimer,
-                       pRPort->Net->TimeoutValue, SKGE_RLMT, SK_RLMT_TIM, Para2);
-       }
-
-       Para2 = Para;
-       Para2.Para32[1] = (SK_U32)-1;
-       SkTimerStart(pAC, IoC, &pRPort->UpTimer, SK_RLMT_PORTUP_TIM_VAL,
-               SKGE_RLMT, SK_RLMT_PORTUP_TIM, Para2);
-       
-       /* Later: if (pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_LOC_LINK) && */
-       if ((pRPort->Net->RlmtMode & SK_RLMT_TRANSPARENT) == 0 &&
-               (pRPort->Net->RlmtMode & SK_RLMT_CHECK_LINK) != 0 &&
-               (Para2.pParaPtr =
-                       SkRlmtBuildPacket(pAC, IoC, Para.Para32[0], SK_PACKET_ANNOUNCE,
-                       &pAC->Addr.Port[Para.Para32[0]].CurrentMacAddress, &SkRlmtMcAddr)
-               ) != NULL) {
-               /* Send "new" packet to RLMT multicast address. */
-               SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2);
-       }
-
-       if (pRPort->Net->RlmtMode & SK_RLMT_CHECK_SEG) {
-               if ((Para2.pParaPtr =
-                       SkRlmtBuildSpanningTreePacket(pAC, IoC, Para.Para32[0])) != NULL) {
-                       pAC->Rlmt.Port[Para.Para32[0]].RootIdSet = SK_FALSE;
-                       pRPort->Net->CheckingState |=
-                               SK_RLMT_RCS_SEG | SK_RLMT_RCS_REPORT_SEG;
-
-                       SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2);
-
-                       Para.Para32[1] = (SK_U32)-1;
-                       SkTimerStart(pAC, IoC, &pRPort->Net->SegTimer,
-                               SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para);
-               }
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_LINK_UP Event END.\n"))
-}      /* SkRlmtEvtLinkUp */
-
-
-/******************************************************************************
- *
- *     SkRlmtEvtPortUpTim - PORT_UP_TIM
- *
- * Description:
- *     This routine handles PORT_UP_TIM events.
- *
- * Context:
- *     runtime, pageable?
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     Nothing
- */
-RLMT_STATIC void       SkRlmtEvtPortUpTim(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_EVPARA      Para)   /* SK_U32 PortNumber; SK_U32 -1 */
-{
-       SK_RLMT_PORT    *pRPort;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_PORTUP_TIM Port %d Event BEGIN.\n", Para.Para32[0]))
-
-       if (Para.Para32[1] != (SK_U32)-1) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Bad Parameter.\n"))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_PORTUP_TIM Event EMPTY.\n"))
-               return;
-       }
-
-       pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
-       if (pRPort->LinkDown || (pRPort->PortState == SK_RLMT_PS_UP)) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_PORTUP_TIM Port %d Event EMPTY.\n", Para.Para32[0]))
-               return;
-       }
-
-       pRPort->PortDown = SK_FALSE;
-       pRPort->PortState = SK_RLMT_PS_UP;
-       pRPort->Net->PortsUp++;
-       if (pRPort->Net->RlmtState != SK_RLMT_RS_INIT) {
-               if (pAC->Rlmt.NumNets <= 1) {
-                       SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
-               }
-               SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_PORT_UP, Para);
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_PORTUP_TIM Event END.\n"))
-}      /* SkRlmtEvtPortUpTim */
-
-
-/******************************************************************************
- *
- *     SkRlmtEvtPortDownTim - PORT_DOWN_*
- *
- * Description:
- *     This routine handles PORT_DOWN_* events.
- *
- * Context:
- *     runtime, pageable?
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     Nothing
- */
-RLMT_STATIC void       SkRlmtEvtPortDownX(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_U32         Event,  /* Event code */
-SK_EVPARA      Para)   /* SK_U32 PortNumber; SK_U32 -1 */
-{
-       SK_RLMT_PORT    *pRPort;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_PORTDOWN* Port %d Event (%d) BEGIN.\n",
-                       Para.Para32[0], Event))
-
-       if (Para.Para32[1] != (SK_U32)-1) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Bad Parameter.\n"))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_PORTDOWN* Event EMPTY.\n"))
-               return;
-       }
-
-       pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
-       if (!pRPort->PortStarted || (Event == SK_RLMT_PORTDOWN_TX_TIM &&
-               !(pRPort->CheckingState & SK_RLMT_PCS_TX))) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_PORTDOWN* Event (%d) EMPTY.\n", Event))
-               return;
-       }
-       
-       /* Stop port's timers. */
-       SkTimerStop(pAC, IoC, &pRPort->UpTimer);
-       SkTimerStop(pAC, IoC, &pRPort->DownRxTimer);
-       SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
-
-       if (pRPort->PortState != SK_RLMT_PS_LINK_DOWN) {
-               pRPort->PortState = SK_RLMT_PS_DOWN;
-       }
-
-       if (!pRPort->PortDown) {
-               pRPort->Net->PortsUp--;
-               pRPort->PortDown = SK_TRUE;
-               SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_PORT_DOWN, Para);
-       }
-
-       pRPort->PacketsPerTimeSlot = 0;
-       /* pRPort->DataPacketsPerTimeSlot = 0; */
-       pRPort->BpduPacketsPerTimeSlot = 0;
-       pRPort->BcTimeStamp = 0;
-
-       /*
-        * RA;:;: To be checked:
-        * - actions at RLMT_STOP: We should not switch anymore.
-        */
-       if (pRPort->Net->RlmtState != SK_RLMT_RS_INIT) {
-               if (Para.Para32[0] ==
-                       pRPort->Net->Port[pRPort->Net->ActivePort]->PortNumber) {
-                       /* Active Port went down. */
-                       SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
-               }
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_PORTDOWN* Event (%d) END.\n", Event))
-}      /* SkRlmtEvtPortDownX */
-
-
-/******************************************************************************
- *
- *     SkRlmtEvtLinkDown - LINK_DOWN
- *
- * Description:
- *     This routine handles LINK_DOWN events.
- *
- * Context:
- *     runtime, pageable?
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     Nothing
- */
-RLMT_STATIC void       SkRlmtEvtLinkDown(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_EVPARA      Para)   /* SK_U32 PortNumber; SK_U32 Undefined */
-{
-       SK_RLMT_PORT    *pRPort;
-
-       pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_LINK_DOWN Port %d Event BEGIN.\n", Para.Para32[0]))
-
-       if (!pAC->Rlmt.Port[Para.Para32[0]].LinkDown) {
-               pRPort->Net->LinksUp--;
-               pRPort->LinkDown = SK_TRUE;
-               pRPort->PortState = SK_RLMT_PS_LINK_DOWN;
-               SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_OFF);
-
-               if ((pRPort->Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) != 0) {
-                       /* Build the check chain. */
-                       SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber);
-               }
-
-               /* Ensure that port is marked down. */
-               Para.Para32[1] = -1;
-               (void)SkRlmtEvent(pAC, IoC, SK_RLMT_PORTDOWN, Para);
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_LINK_DOWN Event END.\n"))
-}      /* SkRlmtEvtLinkDown */
-
-
-/******************************************************************************
- *
- *     SkRlmtEvtPortAddr - PORT_ADDR
- *
- * Description:
- *     This routine handles PORT_ADDR events.
- *
- * Context:
- *     runtime, pageable?
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     Nothing
- */
-RLMT_STATIC void       SkRlmtEvtPortAddr(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_EVPARA      Para)   /* SK_U32 PortNumber; SK_U32 -1 */
-{
-       SK_U32                  i, j;
-       SK_RLMT_PORT    *pRPort;
-       SK_MAC_ADDR             *pOldMacAddr;
-       SK_MAC_ADDR             *pNewMacAddr;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_PORT_ADDR Port %d Event BEGIN.\n", Para.Para32[0]))
-
-       if (Para.Para32[1] != (SK_U32)-1) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Bad Parameter.\n"))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_PORT_ADDR Event EMPTY.\n"))
-               return;
-       }
-
-       /* Port's physical MAC address changed. */
-       pOldMacAddr = &pAC->Addr.Port[Para.Para32[0]].PreviousMacAddress;
-       pNewMacAddr = &pAC->Addr.Port[Para.Para32[0]].CurrentMacAddress;
-
-       /*
-        * NOTE: This is not scalable for solutions where ports are
-        *       checked remotely.  There, we need to send an RLMT
-        *       address change packet - and how do we ensure delivery?
-        */
-       for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
-               pRPort = &pAC->Rlmt.Port[i];
-               for (j = 0; j < pRPort->PortsChecked; j++) {
-                       if (SK_ADDR_EQUAL(
-                               pRPort->PortCheck[j].CheckAddr.a, pOldMacAddr->a)) {
-                               pRPort->PortCheck[j].CheckAddr = *pNewMacAddr;
-                       }
-               }
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_PORT_ADDR Event END.\n"))
-}      /* SkRlmtEvtPortAddr */
-
-
-/******************************************************************************
- *
- *     SkRlmtEvtStart - START
- *
- * Description:
- *     This routine handles START events.
- *
- * Context:
- *     runtime, pageable?
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     Nothing
- */
-RLMT_STATIC void       SkRlmtEvtStart(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_EVPARA      Para)   /* SK_U32 NetNumber; SK_U32 -1 */
-{
-       SK_EVPARA       Para2;
-       SK_U32          PortIdx;
-       SK_U32          PortNumber;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_START Net %d Event BEGIN.\n", Para.Para32[0]))
-
-       if (Para.Para32[1] != (SK_U32)-1) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Bad Parameter.\n"))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_START Event EMPTY.\n"))
-               return;
-       }
-
-       if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Bad NetNumber %d.\n", Para.Para32[0]))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_START Event EMPTY.\n"))
-               return;
-       }
-
-       if (pAC->Rlmt.Net[Para.Para32[0]].RlmtState != SK_RLMT_RS_INIT) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_START Event EMPTY.\n"))
-               return;
-       }
-
-       if (pAC->Rlmt.NetsStarted >= pAC->Rlmt.NumNets) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("All nets should have been started.\n"))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_START Event EMPTY.\n"))
-               return;
-       }
-
-       if (pAC->Rlmt.Net[Para.Para32[0]].PrefPort >=
-               pAC->Rlmt.Net[Para.Para32[0]].NumPorts) {
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E009, SKERR_RLMT_E009_MSG);
-
-               /* Change PrefPort to internal default. */
-               Para2.Para32[0] = 0xFFFFFFFF;
-               Para2.Para32[1] = Para.Para32[0];
-               (void)SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE, Para2);
-       }
-
-       PortIdx = pAC->Rlmt.Net[Para.Para32[0]].PrefPort;
-       PortNumber = pAC->Rlmt.Net[Para.Para32[0]].Port[PortIdx]->PortNumber;
-
-       pAC->Rlmt.Net[Para.Para32[0]].LinksUp = 0;
-       pAC->Rlmt.Net[Para.Para32[0]].PortsUp = 0;
-       pAC->Rlmt.Net[Para.Para32[0]].CheckingState = 0;
-       pAC->Rlmt.Net[Para.Para32[0]].RlmtState = SK_RLMT_RS_NET_DOWN;
-
-       /* Start preferred port. */
-       SkRlmtPortStart(pAC, IoC, PortNumber);
-
-       /* Start Timer (for first port only). */
-       Para2.Para32[0] = PortNumber;
-       Para2.Para32[1] = (SK_U32)-1;
-       SkTimerStart(pAC, IoC, &pAC->Rlmt.Port[PortNumber].UpTimer,
-               SK_RLMT_PORTSTART_TIM_VAL, SKGE_RLMT, SK_RLMT_PORTSTART_TIM, Para2);
-
-       pAC->Rlmt.NetsStarted++;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_START Event END.\n"))
-}      /* SkRlmtEvtStart */
-
-
-/******************************************************************************
- *
- *     SkRlmtEvtStop - STOP
- *
- * Description:
- *     This routine handles STOP events.
- *
- * Context:
- *     runtime, pageable?
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     Nothing
- */
-RLMT_STATIC void       SkRlmtEvtStop(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_EVPARA      Para)   /* SK_U32 NetNumber; SK_U32 -1 */
-{
-       SK_EVPARA       Para2;
-       SK_U32          PortNumber;
-       SK_U32          i;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_STOP Net %d Event BEGIN.\n", Para.Para32[0]))
-
-       if (Para.Para32[1] != (SK_U32)-1) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Bad Parameter.\n"))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_STOP Event EMPTY.\n"))
-               return;
-       }
-
-       if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Bad NetNumber %d.\n", Para.Para32[0]))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_STOP Event EMPTY.\n"))
-               return;
-       }
-
-       if (pAC->Rlmt.Net[Para.Para32[0]].RlmtState == SK_RLMT_RS_INIT) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_STOP Event EMPTY.\n"))
-               return;
-       }
-
-       if (pAC->Rlmt.NetsStarted == 0) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("All nets are stopped.\n"))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_STOP Event EMPTY.\n"))
-               return;
-       }
-
-       /* Stop RLMT timers. */
-       SkTimerStop(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].LocTimer);
-       SkTimerStop(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].SegTimer);
-
-       /* Stop net. */
-       pAC->Rlmt.Net[Para.Para32[0]].RlmtState = SK_RLMT_RS_INIT;
-       pAC->Rlmt.Net[Para.Para32[0]].RootIdSet = SK_FALSE;
-       Para2.Para32[0] = SK_RLMT_NET_DOWN_FINAL;
-       Para2.Para32[1] = Para.Para32[0];                       /* Net# */
-       SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_DOWN, Para2);
-
-       /* Stop ports. */
-       for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) {
-               PortNumber = pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber;
-               if (pAC->Rlmt.Port[PortNumber].PortState != SK_RLMT_PS_INIT) {
-                       SkTimerStop(pAC, IoC, &pAC->Rlmt.Port[PortNumber].UpTimer);
-                       SkTimerStop(pAC, IoC, &pAC->Rlmt.Port[PortNumber].DownRxTimer);
-                       SkTimerStop(pAC, IoC, &pAC->Rlmt.Port[PortNumber].DownTxTimer);
-
-                       pAC->Rlmt.Port[PortNumber].PortState = SK_RLMT_PS_INIT;
-                       pAC->Rlmt.Port[PortNumber].RootIdSet = SK_FALSE;
-                       pAC->Rlmt.Port[PortNumber].PortStarted = SK_FALSE;
-                       Para2.Para32[0] = PortNumber;
-                       Para2.Para32[1] = (SK_U32)-1;
-                       SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para2);
-               }
-       }
-
-       pAC->Rlmt.NetsStarted--;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_STOP Event END.\n"))
-}      /* SkRlmtEvtStop */
-
-
-/******************************************************************************
- *
- *     SkRlmtEvtTim - TIM
- *
- * Description:
- *     This routine handles TIM events.
- *
- * Context:
- *     runtime, pageable?
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     Nothing
- */
-RLMT_STATIC void       SkRlmtEvtTim(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_EVPARA      Para)   /* SK_U32 NetNumber; SK_U32 -1 */
-{
-       SK_RLMT_PORT    *pRPort;
-       SK_U32                  Timeout;
-       SK_U32                  NewTimeout;
-       SK_U32                  PortNumber;
-       SK_U32                  i;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_TIM Event BEGIN.\n"))
-
-       if (Para.Para32[1] != (SK_U32)-1) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Bad Parameter.\n"))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_TIM Event EMPTY.\n"))
-               return;
-       }
-
-       if ((pAC->Rlmt.Net[Para.Para32[0]].RlmtMode & SK_RLMT_CHECK_OTHERS) == 0 ||
-               pAC->Rlmt.Net[Para.Para32[0]].LinksUp == 0) {
-               /* Mode changed or all links down: No more link checking. */
-               return;
-       }
-
-#if 0
-       pAC->Rlmt.SwitchCheckCounter--;
-       if (pAC->Rlmt.SwitchCheckCounter == 0) {
-               pAC->Rlmt.SwitchCheckCounter;
-       }
-#endif /* 0 */
-
-       NewTimeout = SK_RLMT_DEF_TO_VAL;
-       for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) {
-               PortNumber = pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber;
-               pRPort = &pAC->Rlmt.Port[PortNumber];
-               if (!pRPort->LinkDown) {
-                       Timeout = SkRlmtCheckPort(pAC, IoC, PortNumber);
-                       if (Timeout < NewTimeout) {
-                               NewTimeout = Timeout;
-                       }
-
-                       /*
-                        * These counters should be set to 0 for all ports before the
-                        * first frame is sent in the next loop.
-                        */
-                       pRPort->PacketsPerTimeSlot = 0;
-                       /* pRPort->DataPacketsPerTimeSlot = 0; */
-                       pRPort->BpduPacketsPerTimeSlot = 0;
-               }
-       }
-       pAC->Rlmt.Net[Para.Para32[0]].TimeoutValue = NewTimeout;
-
-       if (pAC->Rlmt.Net[Para.Para32[0]].LinksUp > 1) {
-               /*
-                * If checking remote ports, also send packets if
-                *   (LinksUp == 1) &&
-                *   this port checks at least one (remote) port.
-                */
-
-               /*
-                * Must be new loop, as SkRlmtCheckPort can request to
-                * check segmentation when e.g. checking the last port.
-                */
-               for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) {
-                       if (!pAC->Rlmt.Net[Para.Para32[0]].Port[i]->LinkDown) {
-                               SkRlmtSend(pAC, IoC,
-                                       pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber);
-                       }
-               }
-       }
-
-       SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].LocTimer,
-               pAC->Rlmt.Net[Para.Para32[0]].TimeoutValue, SKGE_RLMT, SK_RLMT_TIM,
-               Para);
-
-       if (pAC->Rlmt.Net[Para.Para32[0]].LinksUp > 1 &&
-               (pAC->Rlmt.Net[Para.Para32[0]].RlmtMode & SK_RLMT_CHECK_SEG) &&
-               (pAC->Rlmt.Net[Para.Para32[0]].CheckingState & SK_RLMT_RCS_START_SEG)) {
-               SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].SegTimer,
-                       SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para);
-               pAC->Rlmt.Net[Para.Para32[0]].CheckingState &= ~SK_RLMT_RCS_START_SEG;
-               pAC->Rlmt.Net[Para.Para32[0]].CheckingState |=
-                       SK_RLMT_RCS_SEG | SK_RLMT_RCS_REPORT_SEG;
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_TIM Event END.\n"))
-}      /* SkRlmtEvtTim */
-
-
-/******************************************************************************
- *
- *     SkRlmtEvtSegTim - SEG_TIM
- *
- * Description:
- *     This routine handles SEG_TIM events.
- *
- * Context:
- *     runtime, pageable?
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     Nothing
- */
-RLMT_STATIC void       SkRlmtEvtSegTim(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_EVPARA      Para)   /* SK_U32 NetNumber; SK_U32 -1 */
-{
-#ifdef xDEBUG
-       int j;
-#endif /* DEBUG */
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_SEG_TIM Event BEGIN.\n"))
-
-       if (Para.Para32[1] != (SK_U32)-1) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Bad Parameter.\n"))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_SEG_TIM Event EMPTY.\n"))
-               return;
-       }
-
-#ifdef xDEBUG
-       for (j = 0; j < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; j++) {
-               SK_ADDR_PORT    *pAPort;
-               SK_U32                  k;
-               SK_U16                  *InAddr;
-               SK_U8                   InAddr8[6];
-
-               InAddr = (SK_U16 *)&InAddr8[0];
-               pAPort = pAC->Rlmt.Net[Para.Para32[0]].Port[j]->AddrPort;
-               for (k = 0; k < pAPort->NextExactMatchRlmt; k++) {
-                       /* Get exact match address k from port j. */
-                       XM_INADDR(IoC, pAC->Rlmt.Net[Para.Para32[0]].Port[j]->PortNumber,
-                               XM_EXM(k), InAddr);
-                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                               ("MC address %d on Port %u: %02x %02x %02x %02x %02x %02x --  %02x %02x %02x %02x %02x %02x.\n",
-                                       k, pAC->Rlmt.Net[Para.Para32[0]].Port[j]->PortNumber,
-                                       InAddr8[0], InAddr8[1], InAddr8[2],
-                                       InAddr8[3], InAddr8[4], InAddr8[5],
-                                       pAPort->Exact[k].a[0], pAPort->Exact[k].a[1],
-                                       pAPort->Exact[k].a[2], pAPort->Exact[k].a[3],
-                                       pAPort->Exact[k].a[4], pAPort->Exact[k].a[5]))
-               }
-       }
-#endif /* xDEBUG */
-                               
-       SkRlmtCheckSeg(pAC, IoC, Para.Para32[0]);
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_SEG_TIM Event END.\n"))
-}      /* SkRlmtEvtSegTim */
-
-
-/******************************************************************************
- *
- *     SkRlmtEvtPacketRx - PACKET_RECEIVED
- *
- * Description:
- *     This routine handles PACKET_RECEIVED events.
- *
- * Context:
- *     runtime, pageable?
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     Nothing
- */
-RLMT_STATIC void       SkRlmtEvtPacketRx(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_EVPARA      Para)   /* SK_MBUF *pMb */
-{
-       SK_MBUF *pMb;
-       SK_MBUF *pNextMb;
-       SK_U32  NetNumber;
-
-       
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_PACKET_RECEIVED Event BEGIN.\n"))
-
-       /* Should we ignore frames during port switching? */
-
-#ifdef DEBUG
-       pMb = Para.pParaPtr;
-       if (pMb == NULL) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("No mbuf.\n"))
-       }
-       else if (pMb->pNext != NULL) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("More than one mbuf or pMb->pNext not set.\n"))
-       }
-#endif /* DEBUG */
-
-       for (pMb = Para.pParaPtr; pMb != NULL; pMb = pNextMb) {
-               pNextMb = pMb->pNext;
-               pMb->pNext = NULL;
-
-               NetNumber = pAC->Rlmt.Port[pMb->PortIdx].Net->NetNumber;
-               if (pAC->Rlmt.Net[NetNumber].RlmtState == SK_RLMT_RS_INIT) {
-                       SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
-               }
-               else {
-                       SkRlmtPacketReceive(pAC, IoC, pMb);
-               }
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_PACKET_RECEIVED Event END.\n"))
-}      /* SkRlmtEvtPacketRx */
-
-
-/******************************************************************************
- *
- *     SkRlmtEvtStatsClear - STATS_CLEAR
- *
- * Description:
- *     This routine handles STATS_CLEAR events.
- *
- * Context:
- *     runtime, pageable?
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     Nothing
- */
-RLMT_STATIC void       SkRlmtEvtStatsClear(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_EVPARA      Para)   /* SK_U32 NetNumber; SK_U32 -1 */
-{
-       SK_U32                  i;
-       SK_RLMT_PORT    *pRPort;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_STATS_CLEAR Event BEGIN.\n"))
-
-       if (Para.Para32[1] != (SK_U32)-1) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Bad Parameter.\n"))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_STATS_CLEAR Event EMPTY.\n"))
-               return;
-       }
-
-       if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Bad NetNumber %d.\n", Para.Para32[0]))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_STATS_CLEAR Event EMPTY.\n"))
-               return;
-       }
-
-       /* Clear statistics for logical and physical ports. */
-       for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) {
-               pRPort =
-                       &pAC->Rlmt.Port[pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber];
-               pRPort->TxHelloCts = 0;
-               pRPort->RxHelloCts = 0;
-               pRPort->TxSpHelloReqCts = 0;
-               pRPort->RxSpHelloCts = 0;
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_STATS_CLEAR Event END.\n"))
-}      /* SkRlmtEvtStatsClear */
-
-
-/******************************************************************************
- *
- *     SkRlmtEvtStatsUpdate - STATS_UPDATE
- *
- * Description:
- *     This routine handles STATS_UPDATE events.
- *
- * Context:
- *     runtime, pageable?
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     Nothing
- */
-RLMT_STATIC void       SkRlmtEvtStatsUpdate(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_EVPARA      Para)   /* SK_U32 NetNumber; SK_U32 -1 */
-{
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_STATS_UPDATE Event BEGIN.\n"))
-
-       if (Para.Para32[1] != (SK_U32)-1) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Bad Parameter.\n"))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_STATS_UPDATE Event EMPTY.\n"))
-               return;
-       }
-
-       if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Bad NetNumber %d.\n", Para.Para32[0]))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_STATS_UPDATE Event EMPTY.\n"))
-               return;
-       }
-
-       /* Update statistics - currently always up-to-date. */
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_STATS_UPDATE Event END.\n"))
-}      /* SkRlmtEvtStatsUpdate */
-
-
-/******************************************************************************
- *
- *     SkRlmtEvtPrefportChange - PREFPORT_CHANGE
- *
- * Description:
- *     This routine handles PREFPORT_CHANGE events.
- *
- * Context:
- *     runtime, pageable?
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     Nothing
- */
-RLMT_STATIC void       SkRlmtEvtPrefportChange(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_EVPARA      Para)   /* SK_U32 PortIndex; SK_U32 NetNumber */
-{
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_PREFPORT_CHANGE to Port %d Event BEGIN.\n", Para.Para32[0]))
-
-       if (Para.Para32[1] >= pAC->Rlmt.NumNets) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Bad NetNumber %d.\n", Para.Para32[1]))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n"))
-               return;
-       }
-
-       /* 0xFFFFFFFF == auto-mode. */
-       if (Para.Para32[0] == 0xFFFFFFFF) {
-               pAC->Rlmt.Net[Para.Para32[1]].PrefPort = SK_RLMT_DEF_PREF_PORT;
-       }
-       else {
-               if (Para.Para32[0] >= pAC->Rlmt.Net[Para.Para32[1]].NumPorts) {
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E010, SKERR_RLMT_E010_MSG);
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                               ("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n"))
-                       return;
-               }
-
-               pAC->Rlmt.Net[Para.Para32[1]].PrefPort = Para.Para32[0];
-       }
-
-       pAC->Rlmt.Net[Para.Para32[1]].Preference = Para.Para32[0];
-
-       if (pAC->Rlmt.Net[Para.Para32[1]].RlmtState != SK_RLMT_RS_INIT) {
-               SkRlmtCheckSwitch(pAC, IoC, Para.Para32[1]);
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_PREFPORT_CHANGE Event END.\n"))
-}      /* SkRlmtEvtPrefportChange */
-
-
-/******************************************************************************
- *
- *     SkRlmtEvtSetNets - SET_NETS
- *
- * Description:
- *     This routine handles SET_NETS events.
- *
- * Context:
- *     runtime, pageable?
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     Nothing
- */
-RLMT_STATIC void       SkRlmtEvtSetNets(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_EVPARA      Para)   /* SK_U32 NumNets; SK_U32 -1 */
-{
-       int i;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_SET_NETS Event BEGIN.\n"))
-
-       if (Para.Para32[1] != (SK_U32)-1) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Bad Parameter.\n"))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_SET_NETS Event EMPTY.\n"))
-               return;
-       }
-
-       if (Para.Para32[0] == 0 || Para.Para32[0] > SK_MAX_NETS ||
-               Para.Para32[0] > (SK_U32)pAC->GIni.GIMacsFound) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Bad number of nets: %d.\n", Para.Para32[0]))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_SET_NETS Event EMPTY.\n"))
-               return;
-       }
-
-       if (Para.Para32[0] == pAC->Rlmt.NumNets) {      /* No change. */
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_SET_NETS Event EMPTY.\n"))
-               return;
-       }
-
-       /* Entering and leaving dual mode only allowed while nets are stopped. */
-       if (pAC->Rlmt.NetsStarted > 0) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Changing dual mode only allowed while all nets are stopped.\n"))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_SET_NETS Event EMPTY.\n"))
-               return;
-       }
-
-       if (Para.Para32[0] == 1) {
-               if (pAC->Rlmt.NumNets > 1) {
-                       /* Clear logical MAC addr from second net's active port. */
-                       (void)SkAddrOverride(pAC, IoC, pAC->Rlmt.Net[1].Port[pAC->Addr.
-                               Net[1].ActivePort]->PortNumber, NULL, SK_ADDR_CLEAR_LOGICAL);
-                       pAC->Rlmt.Net[1].NumPorts = 0;
-               }
-
-               pAC->Rlmt.NumNets = Para.Para32[0];
-               for (i = 0; (SK_U32)i < pAC->Rlmt.NumNets; i++) {
-                       pAC->Rlmt.Net[i].RlmtState = SK_RLMT_RS_INIT;
-                       pAC->Rlmt.Net[i].RootIdSet = SK_FALSE;
-                       pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF;         /* "Automatic" */
-                       pAC->Rlmt.Net[i].PrefPort = SK_RLMT_DEF_PREF_PORT;
-                       /* Just assuming. */
-                       pAC->Rlmt.Net[i].ActivePort = pAC->Rlmt.Net[i].PrefPort;
-                       pAC->Rlmt.Net[i].RlmtMode = SK_RLMT_DEF_MODE;
-                       pAC->Rlmt.Net[i].TimeoutValue = SK_RLMT_DEF_TO_VAL;
-                       pAC->Rlmt.Net[i].NetNumber = i;
-               }
-
-               pAC->Rlmt.Port[1].Net= &pAC->Rlmt.Net[0];
-               pAC->Rlmt.Net[0].NumPorts = pAC->GIni.GIMacsFound;
-
-               SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SET_NETS, Para);
-
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("RLMT: Changed to one net with two ports.\n"))
-       }
-       else if (Para.Para32[0] == 2) {
-               pAC->Rlmt.Port[1].Net= &pAC->Rlmt.Net[1];
-               pAC->Rlmt.Net[1].NumPorts = pAC->GIni.GIMacsFound - 1;
-               pAC->Rlmt.Net[0].NumPorts =
-                       pAC->GIni.GIMacsFound - pAC->Rlmt.Net[1].NumPorts;
-               
-               pAC->Rlmt.NumNets = Para.Para32[0];
-               for (i = 0; (SK_U32)i < pAC->Rlmt.NumNets; i++) {
-                       pAC->Rlmt.Net[i].RlmtState = SK_RLMT_RS_INIT;
-                       pAC->Rlmt.Net[i].RootIdSet = SK_FALSE;
-                       pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF;         /* "Automatic" */
-                       pAC->Rlmt.Net[i].PrefPort = SK_RLMT_DEF_PREF_PORT;
-                       /* Just assuming. */
-                       pAC->Rlmt.Net[i].ActivePort = pAC->Rlmt.Net[i].PrefPort;
-                       pAC->Rlmt.Net[i].RlmtMode = SK_RLMT_DEF_MODE;
-                       pAC->Rlmt.Net[i].TimeoutValue = SK_RLMT_DEF_TO_VAL;
-
-                       pAC->Rlmt.Net[i].NetNumber = i;
-               }
-
-               /* Set logical MAC addr on second net's active port. */
-               (void)SkAddrOverride(pAC, IoC, pAC->Rlmt.Net[1].Port[pAC->Addr.
-                       Net[1].ActivePort]->PortNumber, NULL, SK_ADDR_SET_LOGICAL);
-
-               SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SET_NETS, Para);
-
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("RLMT: Changed to two nets with one port each.\n"))
-       }
-       else {
-               /* Not implemented for more than two nets. */
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SetNets not implemented for more than two nets.\n"))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_SET_NETS Event EMPTY.\n"))
-               return;
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_SET_NETS Event END.\n"))
-}      /* SkRlmtSetNets */
-
-
-/******************************************************************************
- *
- *     SkRlmtEvtModeChange - MODE_CHANGE
- *
- * Description:
- *     This routine handles MODE_CHANGE events.
- *
- * Context:
- *     runtime, pageable?
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     Nothing
- */
-RLMT_STATIC void       SkRlmtEvtModeChange(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_EVPARA      Para)   /* SK_U32 NewMode; SK_U32 NetNumber */
-{
-       SK_EVPARA       Para2;
-       SK_U32          i;
-       SK_U32          PrevRlmtMode;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-               ("SK_RLMT_MODE_CHANGE Event BEGIN.\n"))
-
-       if (Para.Para32[1] >= pAC->Rlmt.NumNets) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Bad NetNumber %d.\n", Para.Para32[1]))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_MODE_CHANGE Event EMPTY.\n"))
-               return;
-       }
-
-       Para.Para32[0] |= SK_RLMT_CHECK_LINK;
-
-       if ((pAC->Rlmt.Net[Para.Para32[1]].NumPorts == 1) &&
-               Para.Para32[0] != SK_RLMT_MODE_CLS) {
-               pAC->Rlmt.Net[Para.Para32[1]].RlmtMode = SK_RLMT_MODE_CLS;
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Forced RLMT mode to CLS on single port net.\n"))
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_MODE_CHANGE Event EMPTY.\n"))
-               return;
-       }
-
-       /* Update RLMT mode. */
-       PrevRlmtMode = pAC->Rlmt.Net[Para.Para32[1]].RlmtMode;
-       pAC->Rlmt.Net[Para.Para32[1]].RlmtMode = Para.Para32[0];
-
-       if ((PrevRlmtMode & SK_RLMT_CHECK_LOC_LINK) !=
-               (pAC->Rlmt.Net[Para.Para32[1]].RlmtMode & SK_RLMT_CHECK_LOC_LINK)) {
-               /* SK_RLMT_CHECK_LOC_LINK bit changed. */
-               if ((PrevRlmtMode & SK_RLMT_CHECK_OTHERS) == 0 &&
-                       pAC->Rlmt.Net[Para.Para32[1]].NumPorts > 1 &&
-                       pAC->Rlmt.Net[Para.Para32[1]].PortsUp >= 1) {
-                       /* 20001207 RA: Was "PortsUp == 1". */
-                       Para2.Para32[0] = Para.Para32[1];
-                       Para2.Para32[1] = (SK_U32)-1;
-                       SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[1]].LocTimer,
-                               pAC->Rlmt.Net[Para.Para32[1]].TimeoutValue,
-                               SKGE_RLMT, SK_RLMT_TIM, Para2);
-               }
-       }
-
-       if ((PrevRlmtMode & SK_RLMT_CHECK_SEG) !=
-               (pAC->Rlmt.Net[Para.Para32[1]].RlmtMode & SK_RLMT_CHECK_SEG)) {
-               /* SK_RLMT_CHECK_SEG bit changed. */
-               for (i = 0; i < pAC->Rlmt.Net[Para.Para32[1]].NumPorts; i++) {
-                       (void)SkAddrMcClear(pAC, IoC,
-                               pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber,
-                               SK_ADDR_PERMANENT | SK_MC_SW_ONLY);
-
-                       /* Add RLMT MC address. */
-                       (void)SkAddrMcAdd(pAC, IoC,
-                               pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber,
-                               &SkRlmtMcAddr, SK_ADDR_PERMANENT);
-
-                       if ((pAC->Rlmt.Net[Para.Para32[1]].RlmtMode &
-                               SK_RLMT_CHECK_SEG) != 0) {
-                               /* Add BPDU MC address. */
-                               (void)SkAddrMcAdd(pAC, IoC,
-                                       pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber,
-                                       &BridgeMcAddr, SK_ADDR_PERMANENT);
-
-                               if (pAC->Rlmt.Net[Para.Para32[1]].RlmtState != SK_RLMT_RS_INIT) {
-                                       if (!pAC->Rlmt.Net[Para.Para32[1]].Port[i]->LinkDown &&
-                                               (Para2.pParaPtr = SkRlmtBuildSpanningTreePacket(
-                                               pAC, IoC, i)) != NULL) {
-                                               pAC->Rlmt.Net[Para.Para32[1]].Port[i]->RootIdSet =
-                                                       SK_FALSE;
-                                               SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2);
-                                       }
-                               }
-                       }
-                       (void)SkAddrMcUpdate(pAC, IoC,
-                               pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber);
-               }       /* for ... */
-
-               if ((pAC->Rlmt.Net[Para.Para32[1]].RlmtMode & SK_RLMT_CHECK_SEG) != 0) {
-                       Para2.Para32[0] = Para.Para32[1];
-                       Para2.Para32[1] = (SK_U32)-1;
-                       SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[1]].SegTimer,
-                               SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para2);
-               }
-       }       /* SK_RLMT_CHECK_SEG bit changed. */
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("SK_RLMT_MODE_CHANGE Event END.\n"))
-}      /* SkRlmtEvtModeChange */
-
-
-/******************************************************************************
- *
- *     SkRlmtEvent - a PORT- or an RLMT-specific event happened
- *
- * Description:
- *     This routine calls subroutines to handle PORT- and RLMT-specific events.
- *
- * Context:
- *     runtime, pageable?
- *     may be called after SK_INIT_IO
- *
- * Returns:
- *     0
- */
-int    SkRlmtEvent(
-SK_AC          *pAC,   /* Adapter Context */
-SK_IOC         IoC,    /* I/O Context */
-SK_U32         Event,  /* Event code */
-SK_EVPARA      Para)   /* Event-specific parameter */
-{
-       switch (Event) {
-       
-       /* ----- PORT events ----- */
-
-       case SK_RLMT_PORTSTART_TIM:     /* From RLMT via TIME. */
-               SkRlmtEvtPortStartTim(pAC, IoC, Para);
-               break;
-       case SK_RLMT_LINK_UP:           /* From SIRQ. */
-               SkRlmtEvtLinkUp(pAC, IoC, Para);
-               break;
-       case SK_RLMT_PORTUP_TIM:        /* From RLMT via TIME. */
-               SkRlmtEvtPortUpTim(pAC, IoC, Para);
-               break;
-       case SK_RLMT_PORTDOWN:                  /* From RLMT. */
-       case SK_RLMT_PORTDOWN_RX_TIM:   /* From RLMT via TIME. */
-       case SK_RLMT_PORTDOWN_TX_TIM:   /* From RLMT via TIME. */
-               SkRlmtEvtPortDownX(pAC, IoC, Event, Para);
-               break;
-       case SK_RLMT_LINK_DOWN:         /* From SIRQ. */
-               SkRlmtEvtLinkDown(pAC, IoC, Para);
-               break;
-       case SK_RLMT_PORT_ADDR:         /* From ADDR. */
-               SkRlmtEvtPortAddr(pAC, IoC, Para);
-               break;
-
-       /* ----- RLMT events ----- */
-
-       case SK_RLMT_START:             /* From DRV. */
-               SkRlmtEvtStart(pAC, IoC, Para);
-               break;
-       case SK_RLMT_STOP:              /* From DRV. */
-               SkRlmtEvtStop(pAC, IoC, Para);
-               break;
-       case SK_RLMT_TIM:               /* From RLMT via TIME. */
-               SkRlmtEvtTim(pAC, IoC, Para);
-               break;
-       case SK_RLMT_SEG_TIM:
-               SkRlmtEvtSegTim(pAC, IoC, Para);
-               break;
-       case SK_RLMT_PACKET_RECEIVED:   /* From DRV. */
-               SkRlmtEvtPacketRx(pAC, IoC, Para);
-               break;
-       case SK_RLMT_STATS_CLEAR:       /* From PNMI. */
-               SkRlmtEvtStatsClear(pAC, IoC, Para);
-               break;
-       case SK_RLMT_STATS_UPDATE:      /* From PNMI. */
-               SkRlmtEvtStatsUpdate(pAC, IoC, Para);
-               break;
-       case SK_RLMT_PREFPORT_CHANGE:   /* From PNMI. */
-               SkRlmtEvtPrefportChange(pAC, IoC, Para);
-               break;
-       case SK_RLMT_MODE_CHANGE:       /* From PNMI. */
-               SkRlmtEvtModeChange(pAC, IoC, Para);
-               break;
-       case SK_RLMT_SET_NETS:  /* From DRV. */
-               SkRlmtEvtSetNets(pAC, IoC, Para);
-               break;
-
-       /* ----- Unknown events ----- */
-
-       default:        /* Create error log entry. */
-               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-                       ("Unknown RLMT Event %d.\n", Event))
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E003, SKERR_RLMT_E003_MSG);
-               break;
-       }       /* switch() */
-
-       return (0);
-}      /* SkRlmtEvent */
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
diff --git a/drivers/net/sk98lin/sktimer.c b/drivers/net/sk98lin/sktimer.c
deleted file mode 100644 (file)
index 4e46295..0000000
+++ /dev/null
@@ -1,250 +0,0 @@
-/******************************************************************************
- *
- * Name:       sktimer.c
- * Project:    Gigabit Ethernet Adapters, Event Scheduler Module
- * Version:    $Revision: 1.14 $
- * Date:       $Date: 2003/09/16 13:46:51 $
- * Purpose:    High level timer functions.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect GmbH.
- *     (C)Copyright 2002-2003 Marvell.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-
-/*
- *     Event queue and dispatcher
- */
-#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
-static const char SysKonnectFileId[] =
-       "@(#) $Id: sktimer.c,v 1.14 2003/09/16 13:46:51 rschmidt Exp $ (C) Marvell.";
-#endif
-
-#include "h/skdrv1st.h"                /* Driver Specific Definitions */
-#include "h/skdrv2nd.h"                /* Adapter Control- and Driver specific Def. */
-
-#ifdef __C2MAN__
-/*
-       Event queue management.
-
-       General Description:
-
- */
-intro()
-{}
-#endif
-
-
-/* Forward declaration */
-static void timer_done(SK_AC *pAC,SK_IOC Ioc,int Restart);
-
-
-/*
- * Inits the software timer
- *
- * needs to be called during Init level 1.
- */
-void   SkTimerInit(
-SK_AC  *pAC,           /* Adapters context */
-SK_IOC Ioc,            /* IoContext */
-int            Level)          /* Init Level */
-{
-       switch (Level) {
-       case SK_INIT_DATA:
-               pAC->Tim.StQueue = NULL;
-               break;
-       case SK_INIT_IO:
-               SkHwtInit(pAC, Ioc);
-               SkTimerDone(pAC, Ioc);
-               break;
-       default:
-               break;
-       }
-}
-
-/*
- * Stops a high level timer
- * - If a timer is not in the queue the function returns normally, too.
- */
-void   SkTimerStop(
-SK_AC          *pAC,           /* Adapters context */
-SK_IOC         Ioc,            /* IoContext */
-SK_TIMER       *pTimer)        /* Timer Pointer to be started */
-{
-       SK_TIMER        **ppTimPrev;
-       SK_TIMER        *pTm;
-
-       /*
-        * remove timer from queue
-        */
-       pTimer->TmActive = SK_FALSE;
-       
-       if (pAC->Tim.StQueue == pTimer && !pTimer->TmNext) {
-               SkHwtStop(pAC, Ioc);
-       }
-       
-       for (ppTimPrev = &pAC->Tim.StQueue; (pTm = *ppTimPrev);
-               ppTimPrev = &pTm->TmNext ) {
-               
-               if (pTm == pTimer) {
-                       /*
-                        * Timer found in queue
-                        * - dequeue it and
-                        * - correct delta of the next timer
-                        */
-                       *ppTimPrev = pTm->TmNext;
-
-                       if (pTm->TmNext) {
-                               /* correct delta of next timer in queue */
-                               pTm->TmNext->TmDelta += pTm->TmDelta;
-                       }
-                       return;
-               }
-       }
-}
-
-/*
- * Start a high level software timer
- */
-void   SkTimerStart(
-SK_AC          *pAC,           /* Adapters context */
-SK_IOC         Ioc,            /* IoContext */
-SK_TIMER       *pTimer,        /* Timer Pointer to be started */
-SK_U32         Time,           /* Time value */
-SK_U32         Class,          /* Event Class for this timer */
-SK_U32         Event,          /* Event Value for this timer */
-SK_EVPARA      Para)           /* Event Parameter for this timer */
-{
-       SK_TIMER        **ppTimPrev;
-       SK_TIMER        *pTm;
-       SK_U32          Delta;
-
-       Time /= 16;             /* input is uS, clock ticks are 16uS */
-       
-       if (!Time)
-               Time = 1;
-
-       SkTimerStop(pAC, Ioc, pTimer);
-
-       pTimer->TmClass = Class;
-       pTimer->TmEvent = Event;
-       pTimer->TmPara = Para;
-       pTimer->TmActive = SK_TRUE;
-
-       if (!pAC->Tim.StQueue) {
-               /* First Timer to be started */
-               pAC->Tim.StQueue = pTimer;
-               pTimer->TmNext = NULL;
-               pTimer->TmDelta = Time;
-               
-               SkHwtStart(pAC, Ioc, Time);
-               
-               return;
-       }
-
-       /*
-        * timer correction
-        */
-       timer_done(pAC, Ioc, 0);
-
-       /*
-        * find position in queue
-        */
-       Delta = 0;
-       for (ppTimPrev = &pAC->Tim.StQueue; (pTm = *ppTimPrev);
-               ppTimPrev = &pTm->TmNext ) {
-               
-               if (Delta + pTm->TmDelta > Time) {
-                       /* Position found */
-                       /* Here the timer needs to be inserted. */
-                       break;
-               }
-               Delta += pTm->TmDelta;
-       }
-
-       /* insert in queue */
-       *ppTimPrev = pTimer;
-       pTimer->TmNext = pTm;
-       pTimer->TmDelta = Time - Delta;
-
-       if (pTm) {
-               /* There is a next timer
-                * -> correct its Delta value.
-                */
-               pTm->TmDelta -= pTimer->TmDelta;
-       }
-
-       /* restart with first */
-       SkHwtStart(pAC, Ioc, pAC->Tim.StQueue->TmDelta);
-}
-
-
-void   SkTimerDone(
-SK_AC  *pAC,           /* Adapters context */
-SK_IOC Ioc)            /* IoContext */
-{
-       timer_done(pAC, Ioc, 1);
-}
-
-
-static void    timer_done(
-SK_AC  *pAC,           /* Adapters context */
-SK_IOC Ioc,            /* IoContext */
-int            Restart)        /* Do we need to restart the Hardware timer ? */
-{
-       SK_U32          Delta;
-       SK_TIMER        *pTm;
-       SK_TIMER        *pTComp;        /* Timer completed now now */
-       SK_TIMER        **ppLast;       /* Next field of Last timer to be deq */
-       int             Done = 0;
-
-       Delta = SkHwtRead(pAC, Ioc);
-       
-       ppLast = &pAC->Tim.StQueue;
-       pTm = pAC->Tim.StQueue;
-       while (pTm && !Done) {
-               if (Delta >= pTm->TmDelta) {
-                       /* Timer ran out */
-                       pTm->TmActive = SK_FALSE;
-                       Delta -= pTm->TmDelta;
-                       ppLast = &pTm->TmNext;
-                       pTm = pTm->TmNext;
-               }
-               else {
-                       /* We found the first timer that did not run out */
-                       pTm->TmDelta -= Delta;
-                       Delta = 0;
-                       Done = 1;
-               }
-       }
-       *ppLast = NULL;
-       /*
-        * pTm points to the first Timer that did not run out.
-        * StQueue points to the first Timer that run out.
-        */
-
-       for ( pTComp = pAC->Tim.StQueue; pTComp; pTComp = pTComp->TmNext) {
-               SkEventQueue(pAC,pTComp->TmClass, pTComp->TmEvent, pTComp->TmPara);
-       }
-
-       /* Set head of timer queue to the first timer that did not run out */
-       pAC->Tim.StQueue = pTm;
-
-       if (Restart && pAC->Tim.StQueue) {
-               /* Restart HW timer */
-               SkHwtStart(pAC, Ioc, pAC->Tim.StQueue->TmDelta);
-       }
-}
-
-/* End of file */
diff --git a/drivers/net/sk98lin/skvpd.c b/drivers/net/sk98lin/skvpd.c
deleted file mode 100644 (file)
index 1e662aa..0000000
+++ /dev/null
@@ -1,1091 +0,0 @@
-/******************************************************************************
- *
- * Name:       skvpd.c
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.37 $
- * Date:       $Date: 2003/01/13 10:42:45 $
- * Purpose:    Shared software to read and write VPD data
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2003 SysKonnect GmbH.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/*
-       Please refer skvpd.txt for information how to include this module
- */
-static const char SysKonnectFileId[] =
-       "@(#)$Id: skvpd.c,v 1.37 2003/01/13 10:42:45 rschmidt Exp $ (C) SK";
-
-#include "h/skdrv1st.h"
-#include "h/sktypes.h"
-#include "h/skdebug.h"
-#include "h/skdrv2nd.h"
-
-/*
- * Static functions
- */
-#ifndef SK_KR_PROTO
-static SK_VPD_PARA     *vpd_find_para(
-       SK_AC   *pAC,
-       const char      *key,
-       SK_VPD_PARA *p);
-#else  /* SK_KR_PROTO */
-static SK_VPD_PARA     *vpd_find_para();
-#endif /* SK_KR_PROTO */
-
-/*
- * waits for a completion of a VPD transfer
- * The VPD transfer must complete within SK_TICKS_PER_SEC/16
- *
- * returns     0:      success, transfer completes
- *             error   exit(9) with a error message
- */
-static int VpdWait(
-SK_AC  *pAC,   /* Adapters context */
-SK_IOC IoC,    /* IO Context */
-int            event)  /* event to wait for (VPD_READ / VPD_write) completion*/
-{
-       SK_U64  start_time;
-       SK_U16  state;
-
-       SK_DBG_MSG(pAC,SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
-               ("VPD wait for %s\n", event?"Write":"Read"));
-       start_time = SkOsGetTime(pAC);
-       do {
-               if (SkOsGetTime(pAC) - start_time > SK_TICKS_PER_SEC) {
-
-                       /* Bug fix AF: Thu Mar 28 2002
-                        * Do not call: VPD_STOP(pAC, IoC);
-                        * A pending VPD read cycle can not be aborted by writing
-                        * VPD_WRITE to the PCI_VPD_ADR_REG (VPD address register).
-                        * Although the write threshold in the OUR-register protects
-                        * VPD read only space from being overwritten this does not
-                        * protect a VPD read from being `converted` into a VPD write
-                        * operation (on the fly). As a consequence the VPD_STOP would
-                        * delete VPD read only data. In case of any problems with the
-                        * I2C bus we exit the loop here. The I2C read operation can
-                        * not be aborted except by a reset (->LR).
-                        */
-                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_FATAL | SK_DBGCAT_ERR,
-                               ("ERROR:VPD wait timeout\n"));
-                       return(1);
-               }
-               
-               VPD_IN16(pAC, IoC, PCI_VPD_ADR_REG, &state);
-               
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
-                       ("state = %x, event %x\n",state,event));
-       } while((int)(state & PCI_VPD_FLAG) == event);
-
-       return(0);
-}
-
-#ifdef SKDIAG
-
-/*
- * Read the dword at address 'addr' from the VPD EEPROM.
- *
- * Needed Time:        MIN 1,3 ms      MAX 2,6 ms
- *
- * Note: The DWord is returned in the endianess of the machine the routine
- *       is running on.
- *
- * Returns the data read.
- */
-SK_U32 VpdReadDWord(
-SK_AC  *pAC,   /* Adapters context */
-SK_IOC IoC,    /* IO Context */
-int            addr)   /* VPD address */
-{
-       SK_U32  Rtv;
-
-       /* start VPD read */
-       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
-               ("VPD read dword at 0x%x\n",addr));
-       addr &= ~VPD_WRITE;             /* ensure the R/W bit is set to read */
-
-       VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, (SK_U16)addr);
-
-       /* ignore return code here */
-       (void)VpdWait(pAC, IoC, VPD_READ);
-
-       /* Don't swap here, it's a data stream of bytes */
-       Rtv = 0;
-
-       VPD_IN32(pAC, IoC, PCI_VPD_DAT_REG, &Rtv);
-       
-       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
-               ("VPD read dword data = 0x%x\n",Rtv));
-       return(Rtv);
-}
-
-#endif /* SKDIAG */
-
-/*
- *     Read one Stream of 'len' bytes of VPD data, starting at 'addr' from
- *     or to the I2C EEPROM.
- *
- * Returns number of bytes read / written.
- */
-static int VpdWriteStream(
-SK_AC  *pAC,   /* Adapters context */
-SK_IOC IoC,    /* IO Context */
-char   *buf,   /* data buffer */
-int            Addr,   /* VPD start address */
-int            Len)    /* number of bytes to read / to write */
-{
-       int             i;
-       int             j;
-       SK_U16  AdrReg;
-       int             Rtv;
-       SK_U8   * pComp;        /* Compare pointer */
-       SK_U8   Data;           /* Input Data for Compare */
-
-       /* Init Compare Pointer */
-       pComp = (SK_U8 *) buf;
-
-       for (i = 0; i < Len; i++, buf++) {
-               if ((i%sizeof(SK_U32)) == 0) {
-                       /*
-                        * At the begin of each cycle read the Data Reg
-                        * So it is initialized even if only a few bytes
-                        * are written.
-                        */
-                       AdrReg = (SK_U16) Addr;
-                       AdrReg &= ~VPD_WRITE;   /* READ operation */
-
-                       VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg);
-
-                       /* Wait for termination */
-                       Rtv = VpdWait(pAC, IoC, VPD_READ);
-                       if (Rtv != 0) {
-                               return(i);
-                       }
-               }
-
-               /* Write current Byte */
-               VPD_OUT8(pAC, IoC, PCI_VPD_DAT_REG + (i%sizeof(SK_U32)),
-                               *(SK_U8*)buf);
-
-               if (((i%sizeof(SK_U32)) == 3) || (i == (Len - 1))) {
-                       /* New Address needs to be written to VPD_ADDR reg */
-                       AdrReg = (SK_U16) Addr;
-                       Addr += sizeof(SK_U32);
-                       AdrReg |= VPD_WRITE;    /* WRITE operation */
-
-                       VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg);
-
-                       /* Wait for termination */
-                       Rtv = VpdWait(pAC, IoC, VPD_WRITE);
-                       if (Rtv != 0) {
-                               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                                       ("Write Timed Out\n"));
-                               return(i - (i%sizeof(SK_U32)));
-                       }
-
-                       /*
-                        * Now re-read to verify
-                        */
-                       AdrReg &= ~VPD_WRITE;   /* READ operation */
-
-                       VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg);
-
-                       /* Wait for termination */
-                       Rtv = VpdWait(pAC, IoC, VPD_READ);
-                       if (Rtv != 0) {
-                               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                                       ("Verify Timed Out\n"));
-                               return(i - (i%sizeof(SK_U32)));
-                       }
-
-                       for (j = 0; j <= (int)(i%sizeof(SK_U32)); j++, pComp++) {
-                               
-                               VPD_IN8(pAC, IoC, PCI_VPD_DAT_REG + j, &Data);
-                               
-                               if (Data != *pComp) {
-                                       /* Verify Error */
-                                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                                               ("WriteStream Verify Error\n"));
-                                       return(i - (i%sizeof(SK_U32)) + j);
-                               }
-                       }
-               }
-       }
-
-       return(Len);
-}
-       
-
-/*
- *     Read one Stream of 'len' bytes of VPD data, starting at 'addr' from
- *     or to the I2C EEPROM.
- *
- * Returns number of bytes read / written.
- */
-static int VpdReadStream(
-SK_AC  *pAC,   /* Adapters context */
-SK_IOC IoC,    /* IO Context */
-char   *buf,   /* data buffer */
-int            Addr,   /* VPD start address */
-int            Len)    /* number of bytes to read / to write */
-{
-       int             i;
-       SK_U16  AdrReg;
-       int             Rtv;
-
-       for (i = 0; i < Len; i++, buf++) {
-               if ((i%sizeof(SK_U32)) == 0) {
-                       /* New Address needs to be written to VPD_ADDR reg */
-                       AdrReg = (SK_U16) Addr;
-                       Addr += sizeof(SK_U32);
-                       AdrReg &= ~VPD_WRITE;   /* READ operation */
-
-                       VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg);
-
-                       /* Wait for termination */
-                       Rtv = VpdWait(pAC, IoC, VPD_READ);
-                       if (Rtv != 0) {
-                               return(i);
-                       }
-               }
-               VPD_IN8(pAC, IoC, PCI_VPD_DAT_REG + (i%sizeof(SK_U32)),
-                       (SK_U8 *)buf);
-       }
-
-       return(Len);
-}
-
-/*
- *     Read ore writes 'len' bytes of VPD data, starting at 'addr' from
- *     or to the I2C EEPROM.
- *
- * Returns number of bytes read / written.
- */
-static int VpdTransferBlock(
-SK_AC  *pAC,   /* Adapters context */
-SK_IOC IoC,    /* IO Context */
-char   *buf,   /* data buffer */
-int            addr,   /* VPD start address */
-int            len,    /* number of bytes to read / to write */
-int            dir)    /* transfer direction may be VPD_READ or VPD_WRITE */
-{
-       int             Rtv;    /* Return value */
-       int             vpd_rom_size;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
-               ("VPD %s block, addr = 0x%x, len = %d\n",
-               dir ? "write" : "read", addr, len));
-
-       if (len == 0)
-               return(0);
-
-       vpd_rom_size = pAC->vpd.rom_size;
-       
-       if (addr > vpd_rom_size - 4) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
-                       ("Address error: 0x%x, exp. < 0x%x\n",
-                       addr, vpd_rom_size - 4));
-               return(0);
-       }
-       
-       if (addr + len > vpd_rom_size) {
-               len = vpd_rom_size - addr;
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                       ("Warning: len was cut to %d\n", len));
-       }
-
-       if (dir == VPD_READ) {
-               Rtv = VpdReadStream(pAC, IoC, buf, addr, len);
-       }
-       else {
-               Rtv = VpdWriteStream(pAC, IoC, buf, addr, len);
-       }
-
-       return(Rtv);
-}
-
-#ifdef SKDIAG
-
-/*
- *     Read 'len' bytes of VPD data, starting at 'addr'.
- *
- * Returns number of bytes read.
- */
-int VpdReadBlock(
-SK_AC  *pAC,   /* pAC pointer */
-SK_IOC IoC,    /* IO Context */
-char   *buf,   /* buffer were the data should be stored */
-int            addr,   /* start reading at the VPD address */
-int            len)    /* number of bytes to read */
-{
-       return(VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_READ));
-}
-
-/*
- *     Write 'len' bytes of *but to the VPD EEPROM, starting at 'addr'.
- *
- * Returns number of bytes writes.
- */
-int VpdWriteBlock(
-SK_AC  *pAC,   /* pAC pointer */
-SK_IOC IoC,    /* IO Context */
-char   *buf,   /* buffer, holds the data to write */
-int            addr,   /* start writing at the VPD address */
-int            len)    /* number of bytes to write */
-{
-       return(VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_WRITE));
-}
-#endif /* SKDIAG */
-
-/*
- * (re)initialize the VPD buffer
- *
- * Reads the VPD data from the EEPROM into the VPD buffer.
- * Get the remaining read only and read / write space.
- *
- * return      0:      success
- *             1:      fatal VPD error
- */
-static int VpdInit(
-SK_AC  *pAC,   /* Adapters context */
-SK_IOC IoC)    /* IO Context */
-{
-       SK_VPD_PARA *r, rp;     /* RW or RV */
-       int             i;
-       unsigned char   x;
-       int             vpd_size;
-       SK_U16  dev_id;
-       SK_U32  our_reg2;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_INIT, ("VpdInit .. "));
-       
-       VPD_IN16(pAC, IoC, PCI_DEVICE_ID, &dev_id);
-       
-       VPD_IN32(pAC, IoC, PCI_OUR_REG_2, &our_reg2);
-       
-       pAC->vpd.rom_size = 256 << ((our_reg2 & PCI_VPD_ROM_SZ) >> 14);
-       
-       /*
-        * this function might get used before the hardware is initialized
-        * therefore we cannot always trust in GIChipId
-        */
-       if (((pAC->vpd.v.vpd_status & VPD_VALID) == 0 &&
-               dev_id != VPD_DEV_ID_GENESIS) ||
-               ((pAC->vpd.v.vpd_status & VPD_VALID) != 0 &&
-               !pAC->GIni.GIGenesis)) {
-
-               /* for Yukon the VPD size is always 256 */
-               vpd_size = VPD_SIZE_YUKON;
-       }
-       else {
-               /* Genesis uses the maximum ROM size up to 512 for VPD */
-               if (pAC->vpd.rom_size > VPD_SIZE_GENESIS) {
-                       vpd_size = VPD_SIZE_GENESIS;
-               }
-               else {
-                       vpd_size = pAC->vpd.rom_size;
-               }
-       }
-
-       /* read the VPD data into the VPD buffer */
-       if (VpdTransferBlock(pAC, IoC, pAC->vpd.vpd_buf, 0, vpd_size, VPD_READ)
-               != vpd_size) {
-
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                       ("Block Read Error\n"));
-               return(1);
-       }
-       
-       pAC->vpd.vpd_size = vpd_size;
-
-       /* Asus K8V Se Deluxe bugfix. Correct VPD content */
-       /* MBo April 2004 */
-       if (((unsigned char)pAC->vpd.vpd_buf[0x3f] == 0x38) &&
-           ((unsigned char)pAC->vpd.vpd_buf[0x40] == 0x3c) &&
-           ((unsigned char)pAC->vpd.vpd_buf[0x41] == 0x45)) {
-               printk("sk98lin: Asus mainboard with buggy VPD? "
-                               "Correcting data.\n");
-               pAC->vpd.vpd_buf[0x40] = 0x38;
-       }
-
-
-       /* find the end tag of the RO area */
-       if (!(r = vpd_find_para(pAC, VPD_RV, &rp))) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
-                       ("Encoding Error: RV Tag not found\n"));
-               return(1);
-       }
-       
-       if (r->p_val + r->p_len > pAC->vpd.vpd_buf + vpd_size/2) {
-               SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
-                       ("Encoding Error: Invalid VPD struct size\n"));
-               return(1);
-       }
-       pAC->vpd.v.vpd_free_ro = r->p_len - 1;
-
-       /* test the checksum */
-       for (i = 0, x = 0; (unsigned)i <= (unsigned)vpd_size/2 - r->p_len; i++) {
-               x += pAC->vpd.vpd_buf[i];
-       }
-       
-       if (x != 0) {
-               /* checksum error */
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
-                       ("VPD Checksum Error\n"));
-               return(1);
-       }
-
-       /* find and check the end tag of the RW area */
-       if (!(r = vpd_find_para(pAC, VPD_RW, &rp))) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
-                       ("Encoding Error: RV Tag not found\n"));
-               return(1);
-       }
-       
-       if (r->p_val < pAC->vpd.vpd_buf + vpd_size/2) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
-                       ("Encoding Error: Invalid VPD struct size\n"));
-               return(1);
-       }
-       pAC->vpd.v.vpd_free_rw = r->p_len;
-
-       /* everything seems to be ok */
-       if (pAC->GIni.GIChipId != 0) {
-               pAC->vpd.v.vpd_status |= VPD_VALID;
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_INIT,
-               ("done. Free RO = %d, Free RW = %d\n",
-               pAC->vpd.v.vpd_free_ro, pAC->vpd.v.vpd_free_rw));
-
-       return(0);
-}
-
-/*
- *     find the Keyword 'key' in the VPD buffer and fills the
- *     parameter struct 'p' with it's values
- *
- * returns     *p      success
- *             0:      parameter was not found or VPD encoding error
- */
-static SK_VPD_PARA *vpd_find_para(
-SK_AC          *pAC,   /* common data base */
-const char     *key,   /* keyword to find (e.g. "MN") */
-SK_VPD_PARA *p)                /* parameter description struct */
-{
-       char *v ;       /* points to VPD buffer */
-       int max;        /* Maximum Number of Iterations */
-
-       v = pAC->vpd.vpd_buf;
-       max = 128;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
-               ("VPD find para %s .. ",key));
-
-       /* check mandatory resource type ID string (Product Name) */
-       if (*v != (char)RES_ID) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
-                       ("Error: 0x%x missing\n", RES_ID));
-               return NULL;
-       }
-
-       if (strcmp(key, VPD_NAME) == 0) {
-               p->p_len = VPD_GET_RES_LEN(v);
-               p->p_val = VPD_GET_VAL(v);
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
-                       ("found, len = %d\n", p->p_len));
-               return(p);
-       }
-
-       v += 3 + VPD_GET_RES_LEN(v) + 3;
-       for (;; ) {
-               if (SK_MEMCMP(key,v,2) == 0) {
-                       p->p_len = VPD_GET_VPD_LEN(v);
-                       p->p_val = VPD_GET_VAL(v);
-                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
-                               ("found, len = %d\n",p->p_len));
-                       return(p);
-               }
-
-               /* exit when reaching the "RW" Tag or the maximum of itera. */
-               max--;
-               if (SK_MEMCMP(VPD_RW,v,2) == 0 || max == 0) {
-                       break;
-               }
-
-               if (SK_MEMCMP(VPD_RV,v,2) == 0) {
-                       v += 3 + VPD_GET_VPD_LEN(v) + 3;        /* skip VPD-W */
-               }
-               else {
-                       v += 3 + VPD_GET_VPD_LEN(v);
-               }
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
-                       ("scanning '%c%c' len = %d\n",v[0],v[1],v[2]));
-       }
-
-#ifdef DEBUG
-       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, ("not found\n"));
-       if (max == 0) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
-                       ("Key/Len Encoding error\n"));
-       }
-#endif /* DEBUG */
-       return NULL;
-}
-
-/*
- *     Move 'n' bytes. Begin with the last byte if 'n' is > 0,
- *     Start with the last byte if n is < 0.
- *
- * returns nothing
- */
-static void vpd_move_para(
-char   *start,         /* start of memory block */
-char   *end,           /* end of memory block to move */
-int            n)                      /* number of bytes the memory block has to be moved */
-{
-       char *p;
-       int i;          /* number of byte copied */
-
-       if (n == 0)
-               return;
-
-       i = (int) (end - start + 1);
-       if (n < 0) {
-               p = start + n;
-               while (i != 0) {
-                       *p++ = *start++;
-                       i--;
-               }
-       }
-       else {
-               p = end + n;
-               while (i != 0) {
-                       *p-- = *end--;
-                       i--;
-               }
-       }
-}
-
-/*
- *     setup the VPD keyword 'key' at 'ip'.
- *
- * returns nothing
- */
-static void vpd_insert_key(
-const char     *key,   /* keyword to insert */
-const char     *buf,   /* buffer with the keyword value */
-int            len,            /* length of the value string */
-char   *ip)            /* inseration point */
-{
-       SK_VPD_KEY *p;
-
-       p = (SK_VPD_KEY *) ip;
-       p->p_key[0] = key[0];
-       p->p_key[1] = key[1];
-       p->p_len = (unsigned char) len;
-       SK_MEMCPY(&p->p_val,buf,len);
-}
-
-/*
- *     Setup the VPD end tag "RV" / "RW".
- *     Also correct the remaining space variables vpd_free_ro / vpd_free_rw.
- *
- * returns     0:      success
- *             1:      encoding error
- */
-static int vpd_mod_endtag(
-SK_AC  *pAC,           /* common data base */
-char   *etp)           /* end pointer input position */
-{
-       SK_VPD_KEY *p;
-       unsigned char   x;
-       int     i;
-       int     vpd_size;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
-               ("VPD modify endtag at 0x%x = '%c%c'\n",etp,etp[0],etp[1]));
-
-       vpd_size = pAC->vpd.vpd_size;
-
-       p = (SK_VPD_KEY *) etp;
-
-       if (p->p_key[0] != 'R' || (p->p_key[1] != 'V' && p->p_key[1] != 'W')) {
-               /* something wrong here, encoding error */
-               SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
-                       ("Encoding Error: invalid end tag\n"));
-               return(1);
-       }
-       if (etp > pAC->vpd.vpd_buf + vpd_size/2) {
-               /* create "RW" tag */
-               p->p_len = (unsigned char)(pAC->vpd.vpd_buf+vpd_size-etp-3-1);
-               pAC->vpd.v.vpd_free_rw = (int) p->p_len;
-               i = pAC->vpd.v.vpd_free_rw;
-               etp += 3;
-       }
-       else {
-               /* create "RV" tag */
-               p->p_len = (unsigned char)(pAC->vpd.vpd_buf+vpd_size/2-etp-3);
-               pAC->vpd.v.vpd_free_ro = (int) p->p_len - 1;
-
-               /* setup checksum */
-               for (i = 0, x = 0; i < vpd_size/2 - p->p_len; i++) {
-                       x += pAC->vpd.vpd_buf[i];
-               }
-               p->p_val = (char) 0 - x;
-               i = pAC->vpd.v.vpd_free_ro;
-               etp += 4;
-       }
-       while (i) {
-               *etp++ = 0x00;
-               i--;
-       }
-
-       return(0);
-}
-
-/*
- *     Insert a VPD keyword into the VPD buffer.
- *
- *     The keyword 'key' is inserted at the position 'ip' in the
- *     VPD buffer.
- *     The keywords behind the input position will
- *     be moved. The VPD end tag "RV" or "RW" is generated again.
- *
- * returns     0:      success
- *             2:      value string was cut
- *             4:      VPD full, keyword was not written
- *             6:      fatal VPD error
- *
- */
-static int     VpdSetupPara(
-SK_AC  *pAC,           /* common data base */
-const char     *key,   /* keyword to insert */
-const char     *buf,   /* buffer with the keyword value */
-int            len,            /* length of the keyword value */
-int            type,           /* VPD_RO_KEY or VPD_RW_KEY */
-int            op)                     /* operation to do: ADD_KEY or OWR_KEY */
-{
-       SK_VPD_PARA vp;
-       char    *etp;           /* end tag position */
-       int     free;           /* remaining space in selected area */
-       char    *ip;            /* input position inside the VPD buffer */
-       int     rtv;            /* return code */
-       int     head;           /* additional haeder bytes to move */
-       int     found;          /* additinoal bytes if the keyword was found */
-       int vpd_size;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
-               ("VPD setup para key = %s, val = %s\n",key,buf));
-       
-       vpd_size = pAC->vpd.vpd_size;
-
-       rtv = 0;
-       ip = NULL;
-       if (type == VPD_RW_KEY) {
-               /* end tag is "RW" */
-               free = pAC->vpd.v.vpd_free_rw;
-               etp = pAC->vpd.vpd_buf + (vpd_size - free - 1 - 3);
-       }
-       else {
-               /* end tag is "RV" */
-               free = pAC->vpd.v.vpd_free_ro;
-               etp = pAC->vpd.vpd_buf + (vpd_size/2 - free - 4);
-       }
-       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
-               ("Free RO = %d, Free RW = %d\n",
-               pAC->vpd.v.vpd_free_ro, pAC->vpd.v.vpd_free_rw));
-
-       head = 0;
-       found = 0;
-       if (op == OWR_KEY) {
-               if (vpd_find_para(pAC, key, &vp)) {
-                       found = 3;
-                       ip = vp.p_val - 3;
-                       free += vp.p_len + 3;
-                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
-                               ("Overwrite Key\n"));
-               }
-               else {
-                       op = ADD_KEY;
-                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
-                               ("Add Key\n"));
-               }
-       }
-       if (op == ADD_KEY) {
-               ip = etp;
-               vp.p_len = 0;
-               head = 3;
-       }
-
-       if (len + 3 > free) {
-               if (free < 7) {
-                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                               ("VPD Buffer Overflow, keyword not written\n"));
-                       return(4);
-               }
-               /* cut it again */
-               len = free - 3;
-               rtv = 2;
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                       ("VPD Buffer Full, Keyword was cut\n"));
-       }
-
-       vpd_move_para(ip + vp.p_len + found, etp+2, len-vp.p_len+head);
-       vpd_insert_key(key, buf, len, ip);
-       if (vpd_mod_endtag(pAC, etp + len - vp.p_len + head)) {
-               pAC->vpd.v.vpd_status &= ~VPD_VALID;
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                       ("VPD Encoding Error\n"));
-               return(6);
-       }
-
-       return(rtv);
-}
-
-
-/*
- *     Read the contents of the VPD EEPROM and copy it to the
- *     VPD buffer if not already done.
- *
- * return:     A pointer to the vpd_status structure. The structure contains
- *             this fields.
- */
-SK_VPD_STATUS *VpdStat(
-SK_AC  *pAC,   /* Adapters context */
-SK_IOC IoC)    /* IO Context */
-{
-       if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
-               (void)VpdInit(pAC, IoC);
-       }
-       return(&pAC->vpd.v);
-}
-
-
-/*
- *     Read the contents of the VPD EEPROM and copy it to the VPD
- *     buffer if not already done.
- *     Scan the VPD buffer for VPD keywords and create the VPD
- *     keyword list by copying the keywords to 'buf', all after
- *     each other and terminated with a '\0'.
- *
- * Exceptions: o The Resource Type ID String (product name) is called "Name"
- *             o The VPD end tags 'RV' and 'RW' are not listed
- *
- *     The number of copied keywords is counted in 'elements'.
- *
- * returns     0:      success
- *             2:      buffer overfull, one or more keywords are missing
- *             6:      fatal VPD error
- *
- *     example values after returning:
- *
- *             buf =   "Name\0PN\0EC\0MN\0SN\0CP\0VF\0VL\0YA\0"
- *             *len =          30
- *             *elements =      9
- */
-int VpdKeys(
-SK_AC  *pAC,           /* common data base */
-SK_IOC IoC,            /* IO Context */
-char   *buf,           /* buffer where to copy the keywords */
-int            *len,           /* buffer length */
-int            *elements)      /* number of keywords returned */
-{
-       char *v;
-       int n;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("list VPD keys .. "));
-       *elements = 0;
-       if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
-               if (VpdInit(pAC, IoC) != 0) {
-                       *len = 0;
-                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                               ("VPD Init Error, terminated\n"));
-                       return(6);
-               }
-       }
-
-       if ((signed)strlen(VPD_NAME) + 1 <= *len) {
-               v = pAC->vpd.vpd_buf;
-               strcpy(buf,VPD_NAME);
-               n = strlen(VPD_NAME) + 1;
-               buf += n;
-               *elements = 1;
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX,
-                       ("'%c%c' ",v[0],v[1]));
-       }
-       else {
-               *len = 0;
-               SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
-                       ("buffer overflow\n"));
-               return(2);
-       }
-
-       v += 3 + VPD_GET_RES_LEN(v) + 3;
-       for (;; ) {
-               /* exit when reaching the "RW" Tag */
-               if (SK_MEMCMP(VPD_RW,v,2) == 0) {
-                       break;
-               }
-
-               if (SK_MEMCMP(VPD_RV,v,2) == 0) {
-                       v += 3 + VPD_GET_VPD_LEN(v) + 3;        /* skip VPD-W */
-                       continue;
-               }
-
-               if (n+3 <= *len) {
-                       SK_MEMCPY(buf,v,2);
-                       buf += 2;
-                       *buf++ = '\0';
-                       n += 3;
-                       v += 3 + VPD_GET_VPD_LEN(v);
-                       *elements += 1;
-                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX,
-                               ("'%c%c' ",v[0],v[1]));
-               }
-               else {
-                       *len = n;
-                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                               ("buffer overflow\n"));
-                       return(2);
-               }
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("\n"));
-       *len = n;
-       return(0);
-}
-
-
-/*
- *     Read the contents of the VPD EEPROM and copy it to the
- *     VPD buffer if not already done. Search for the VPD keyword
- *     'key' and copy its value to 'buf'. Add a terminating '\0'.
- *     If the value does not fit into the buffer cut it after
- *     'len' - 1 bytes.
- *
- * returns     0:      success
- *             1:      keyword not found
- *             2:      value string was cut
- *             3:      VPD transfer timeout
- *             6:      fatal VPD error
- */
-int VpdRead(
-SK_AC          *pAC,   /* common data base */
-SK_IOC         IoC,    /* IO Context */
-const char     *key,   /* keyword to read (e.g. "MN") */
-char           *buf,   /* buffer where to copy the keyword value */
-int                    *len)   /* buffer length */
-{
-       SK_VPD_PARA *p, vp;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("VPD read %s .. ", key));
-       if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
-               if (VpdInit(pAC, IoC) != 0) {
-                       *len = 0;
-                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                               ("VPD init error\n"));
-                       return(6);
-               }
-       }
-
-       if ((p = vpd_find_para(pAC, key, &vp)) != NULL) {
-               if (p->p_len > (*(unsigned *)len)-1) {
-                       p->p_len = *len - 1;
-               }
-               SK_MEMCPY(buf, p->p_val, p->p_len);
-               buf[p->p_len] = '\0';
-               *len = p->p_len;
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX,
-                       ("%c%c%c%c.., len = %d\n",
-                       buf[0],buf[1],buf[2],buf[3],*len));
-       }
-       else {
-               *len = 0;
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, ("not found\n"));
-               return(1);
-       }
-       return(0);
-}
-
-
-/*
- *     Check whether a given key may be written
- *
- * returns
- *     SK_TRUE         Yes it may be written
- *     SK_FALSE        No it may be written
- */
-SK_BOOL VpdMayWrite(
-char   *key)   /* keyword to write (allowed values "Yx", "Vx") */
-{
-       if ((*key != 'Y' && *key != 'V') ||
-               key[1] < '0' || key[1] > 'Z' ||
-               (key[1] > '9' && key[1] < 'A') || strlen(key) != 2) {
-
-               return(SK_FALSE);
-       }
-       return(SK_TRUE);
-}
-
-/*
- *     Read the contents of the VPD EEPROM and copy it to the VPD
- *     buffer if not already done. Insert/overwrite the keyword 'key'
- *     in the VPD buffer. Cut the keyword value if it does not fit
- *     into the VPD read / write area.
- *
- * returns     0:      success
- *             2:      value string was cut
- *             3:      VPD transfer timeout
- *             4:      VPD full, keyword was not written
- *             5:      keyword cannot be written
- *             6:      fatal VPD error
- */
-int VpdWrite(
-SK_AC          *pAC,   /* common data base */
-SK_IOC         IoC,    /* IO Context */
-const char     *key,   /* keyword to write (allowed values "Yx", "Vx") */
-const char     *buf)   /* buffer where the keyword value can be read from */
-{
-       int len;                /* length of the keyword to write */
-       int rtv;                /* return code */
-       int rtv2;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX,
-               ("VPD write %s = %s\n",key,buf));
-
-       if ((*key != 'Y' && *key != 'V') ||
-               key[1] < '0' || key[1] > 'Z' ||
-               (key[1] > '9' && key[1] < 'A') || strlen(key) != 2) {
-
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                       ("illegal key tag, keyword not written\n"));
-               return(5);
-       }
-
-       if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
-               if (VpdInit(pAC, IoC) != 0) {
-                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                               ("VPD init error\n"));
-                       return(6);
-               }
-       }
-
-       rtv = 0;
-       len = strlen(buf);
-       if (len > VPD_MAX_LEN) {
-               /* cut it */
-               len = VPD_MAX_LEN;
-               rtv = 2;
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                       ("keyword too long, cut after %d bytes\n",VPD_MAX_LEN));
-       }
-       if ((rtv2 = VpdSetupPara(pAC, key, buf, len, VPD_RW_KEY, OWR_KEY)) != 0) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                       ("VPD write error\n"));
-               return(rtv2);
-       }
-
-       return(rtv);
-}
-
-/*
- *     Read the contents of the VPD EEPROM and copy it to the
- *     VPD buffer if not already done. Remove the VPD keyword
- *     'key' from the VPD buffer.
- *     Only the keywords in the read/write area can be deleted.
- *     Keywords in the read only area cannot be deleted.
- *
- * returns     0:      success, keyword was removed
- *             1:      keyword not found
- *             5:      keyword cannot be deleted
- *             6:      fatal VPD error
- */
-int VpdDelete(
-SK_AC  *pAC,   /* common data base */
-SK_IOC IoC,    /* IO Context */
-char   *key)   /* keyword to read (e.g. "MN") */
-{
-       SK_VPD_PARA *p, vp;
-       char *etp;
-       int     vpd_size;
-
-       vpd_size = pAC->vpd.vpd_size;
-
-       SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("VPD delete key %s\n",key));
-       if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
-               if (VpdInit(pAC, IoC) != 0) {
-                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                               ("VPD init error\n"));
-                       return(6);
-               }
-       }
-
-       if ((p = vpd_find_para(pAC, key, &vp)) != NULL) {
-               if (p->p_val < pAC->vpd.vpd_buf + vpd_size/2) {
-                       /* try to delete read only keyword */
-                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                               ("cannot delete RO keyword\n"));
-                       return(5);
-               }
-
-               etp = pAC->vpd.vpd_buf + (vpd_size-pAC->vpd.v.vpd_free_rw-1-3);
-
-               vpd_move_para(vp.p_val+vp.p_len, etp+2,
-                       - ((int)(vp.p_len + 3)));
-               if (vpd_mod_endtag(pAC, etp - vp.p_len - 3)) {
-                       pAC->vpd.v.vpd_status &= ~VPD_VALID;
-                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                               ("VPD encoding error\n"));
-                       return(6);
-               }
-       }
-       else {
-               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                       ("keyword not found\n"));
-               return(1);
-       }
-
-       return(0);
-}
-
-/*
- *     If the VPD buffer contains valid data write the VPD
- *     read/write area back to the VPD EEPROM.
- *
- * returns     0:      success
- *             3:      VPD transfer timeout
- */
-int VpdUpdate(
-SK_AC  *pAC,   /* Adapters context */
-SK_IOC IoC)    /* IO Context */
-{
-       int vpd_size;
-
-       vpd_size = pAC->vpd.vpd_size;
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("VPD update .. "));
-       if ((pAC->vpd.v.vpd_status & VPD_VALID) != 0) {
-               if (VpdTransferBlock(pAC, IoC, pAC->vpd.vpd_buf + vpd_size/2,
-                       vpd_size/2, vpd_size/2, VPD_WRITE) != vpd_size/2) {
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
-                               ("transfer timed out\n"));
-                       return(3);
-               }
-       }
-       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("done\n"));
-       return(0);
-}
-
diff --git a/drivers/net/sk98lin/skxmac2.c b/drivers/net/sk98lin/skxmac2.c
deleted file mode 100644 (file)
index b4e7502..0000000
+++ /dev/null
@@ -1,4160 +0,0 @@
-/******************************************************************************
- *
- * Name:       skxmac2.c
- * Project:    Gigabit Ethernet Adapters, Common Modules
- * Version:    $Revision: 1.102 $
- * Date:       $Date: 2003/10/02 16:53:58 $
- * Purpose:    Contains functions to initialize the MACs and PHYs
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect.
- *     (C)Copyright 2002-2003 Marvell.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-#include "h/skdrv1st.h"
-#include "h/skdrv2nd.h"
-
-/* typedefs *******************************************************************/
-
-/* BCOM PHY magic pattern list */
-typedef struct s_PhyHack {
-       int             PhyReg;         /* Phy register */
-       SK_U16  PhyVal;         /* Value to write */
-} BCOM_HACK;
-
-/* local variables ************************************************************/
-
-#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
-static const char SysKonnectFileId[] =
-       "@(#) $Id: skxmac2.c,v 1.102 2003/10/02 16:53:58 rschmidt Exp $ (C) Marvell.";
-#endif
-
-#ifdef GENESIS
-static BCOM_HACK BcomRegA1Hack[] = {
- { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1104 }, { 0x17, 0x0013 },
- { 0x15, 0x0404 }, { 0x17, 0x8006 }, { 0x15, 0x0132 }, { 0x17, 0x8006 },
- { 0x15, 0x0232 }, { 0x17, 0x800D }, { 0x15, 0x000F }, { 0x18, 0x0420 },
- { 0, 0 }
-};
-static BCOM_HACK BcomRegC0Hack[] = {
- { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1204 }, { 0x17, 0x0013 },
- { 0x15, 0x0A04 }, { 0x18, 0x0420 },
- { 0, 0 }
-};
-#endif
-
-/* function prototypes ********************************************************/
-#ifdef GENESIS
-static void    SkXmInitPhyXmac(SK_AC*, SK_IOC, int, SK_BOOL);
-static void    SkXmInitPhyBcom(SK_AC*, SK_IOC, int, SK_BOOL);
-static int     SkXmAutoNegDoneXmac(SK_AC*, SK_IOC, int);
-static int     SkXmAutoNegDoneBcom(SK_AC*, SK_IOC, int);
-#endif /* GENESIS */
-#ifdef YUKON
-static void    SkGmInitPhyMarv(SK_AC*, SK_IOC, int, SK_BOOL);
-static int     SkGmAutoNegDoneMarv(SK_AC*, SK_IOC, int);
-#endif /* YUKON */
-#ifdef OTHER_PHY
-static void    SkXmInitPhyLone(SK_AC*, SK_IOC, int, SK_BOOL);
-static void    SkXmInitPhyNat (SK_AC*, SK_IOC, int, SK_BOOL);
-static int     SkXmAutoNegDoneLone(SK_AC*, SK_IOC, int);
-static int     SkXmAutoNegDoneNat (SK_AC*, SK_IOC, int);
-#endif /* OTHER_PHY */
-
-
-#ifdef GENESIS
-/******************************************************************************
- *
- *     SkXmPhyRead() - Read from XMAC PHY register
- *
- * Description:        reads a 16-bit word from XMAC PHY or ext. PHY
- *
- * Returns:
- *     nothing
- */
-void SkXmPhyRead(
-SK_AC  *pAC,                   /* Adapter Context */
-SK_IOC IoC,                    /* I/O Context */
-int            Port,                   /* Port Index (MAC_1 + n) */
-int            PhyReg,                 /* Register Address (Offset) */
-SK_U16 SK_FAR *pVal)   /* Pointer to Value */
-{
-       SK_U16          Mmu;
-       SK_GEPORT       *pPrt;
-
-       pPrt = &pAC->GIni.GP[Port];
-       
-       /* write the PHY register's address */
-       XM_OUT16(IoC, Port, XM_PHY_ADDR, PhyReg | pPrt->PhyAddr);
-       
-       /* get the PHY register's value */
-       XM_IN16(IoC, Port, XM_PHY_DATA, pVal);
-       
-       if (pPrt->PhyType != SK_PHY_XMAC) {
-               do {
-                       XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu);
-                       /* wait until 'Ready' is set */
-               } while ((Mmu & XM_MMU_PHY_RDY) == 0);
-
-               /* get the PHY register's value */
-               XM_IN16(IoC, Port, XM_PHY_DATA, pVal);
-       }
-}      /* SkXmPhyRead */
-
-
-/******************************************************************************
- *
- *     SkXmPhyWrite() - Write to XMAC PHY register
- *
- * Description:        writes a 16-bit word to XMAC PHY or ext. PHY
- *
- * Returns:
- *     nothing
- */
-void SkXmPhyWrite(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* I/O Context */
-int            Port,           /* Port Index (MAC_1 + n) */
-int            PhyReg,         /* Register Address (Offset) */
-SK_U16 Val)            /* Value */
-{
-       SK_U16          Mmu;
-       SK_GEPORT       *pPrt;
-
-       pPrt = &pAC->GIni.GP[Port];
-       
-       if (pPrt->PhyType != SK_PHY_XMAC) {
-               do {
-                       XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu);
-                       /* wait until 'Busy' is cleared */
-               } while ((Mmu & XM_MMU_PHY_BUSY) != 0);
-       }
-       
-       /* write the PHY register's address */
-       XM_OUT16(IoC, Port, XM_PHY_ADDR, PhyReg | pPrt->PhyAddr);
-       
-       /* write the PHY register's value */
-       XM_OUT16(IoC, Port, XM_PHY_DATA, Val);
-       
-       if (pPrt->PhyType != SK_PHY_XMAC) {
-               do {
-                       XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu);
-                       /* wait until 'Busy' is cleared */
-               } while ((Mmu & XM_MMU_PHY_BUSY) != 0);
-       }
-}      /* SkXmPhyWrite */
-#endif /* GENESIS */
-
-
-#ifdef YUKON
-/******************************************************************************
- *
- *     SkGmPhyRead() - Read from GPHY register
- *
- * Description:        reads a 16-bit word from GPHY through MDIO
- *
- * Returns:
- *     nothing
- */
-void SkGmPhyRead(
-SK_AC  *pAC,                   /* Adapter Context */
-SK_IOC IoC,                    /* I/O Context */
-int            Port,                   /* Port Index (MAC_1 + n) */
-int            PhyReg,                 /* Register Address (Offset) */
-SK_U16 SK_FAR *pVal)   /* Pointer to Value */
-{
-       SK_U16  Ctrl;
-       SK_GEPORT       *pPrt;
-#ifdef VCPU
-       u_long SimCyle;
-       u_long SimLowTime;
-       
-       VCPUgetTime(&SimCyle, &SimLowTime);
-       VCPUprintf(0, "SkGmPhyRead(%u), SimCyle=%u, SimLowTime=%u\n",
-               PhyReg, SimCyle, SimLowTime);
-#endif /* VCPU */
-       
-       pPrt = &pAC->GIni.GP[Port];
-       
-       /* set PHY-Register offset and 'Read' OpCode (= 1) */
-       *pVal = (SK_U16)(GM_SMI_CT_PHY_AD(pPrt->PhyAddr) |
-               GM_SMI_CT_REG_AD(PhyReg) | GM_SMI_CT_OP_RD);
-
-       GM_OUT16(IoC, Port, GM_SMI_CTRL, *pVal);
-
-       GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
-       
-       /* additional check for MDC/MDIO activity */
-       if ((Ctrl & GM_SMI_CT_BUSY) == 0) {
-               *pVal = 0;
-               return;
-       }
-
-       *pVal |= GM_SMI_CT_BUSY;
-       
-       do {
-#ifdef VCPU
-               VCPUwaitTime(1000);
-#endif /* VCPU */
-
-               GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
-
-       /* wait until 'ReadValid' is set */
-       } while (Ctrl == *pVal);
-       
-       /* get the PHY register's value */
-       GM_IN16(IoC, Port, GM_SMI_DATA, pVal);
-
-#ifdef VCPU
-       VCPUgetTime(&SimCyle, &SimLowTime);
-       VCPUprintf(0, "VCPUgetTime(), SimCyle=%u, SimLowTime=%u\n",
-               SimCyle, SimLowTime);
-#endif /* VCPU */
-
-}      /* SkGmPhyRead */
-
-
-/******************************************************************************
- *
- *     SkGmPhyWrite() - Write to GPHY register
- *
- * Description:        writes a 16-bit word to GPHY through MDIO
- *
- * Returns:
- *     nothing
- */
-void SkGmPhyWrite(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* I/O Context */
-int            Port,           /* Port Index (MAC_1 + n) */
-int            PhyReg,         /* Register Address (Offset) */
-SK_U16 Val)            /* Value */
-{
-       SK_U16  Ctrl;
-       SK_GEPORT       *pPrt;
-#ifdef VCPU
-       SK_U32  DWord;
-       u_long  SimCyle;
-       u_long  SimLowTime;
-       
-       VCPUgetTime(&SimCyle, &SimLowTime);
-       VCPUprintf(0, "SkGmPhyWrite(Reg=%u, Val=0x%04x), SimCyle=%u, SimLowTime=%u\n",
-               PhyReg, Val, SimCyle, SimLowTime);
-#endif /* VCPU */
-       
-       pPrt = &pAC->GIni.GP[Port];
-       
-       /* write the PHY register's value */
-       GM_OUT16(IoC, Port, GM_SMI_DATA, Val);
-       
-       /* set PHY-Register offset and 'Write' OpCode (= 0) */
-       Val = GM_SMI_CT_PHY_AD(pPrt->PhyAddr) | GM_SMI_CT_REG_AD(PhyReg);
-
-       GM_OUT16(IoC, Port, GM_SMI_CTRL, Val);
-
-       GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
-       
-       /* additional check for MDC/MDIO activity */
-       if ((Ctrl & GM_SMI_CT_BUSY) == 0) {
-               return;
-       }
-       
-       Val |= GM_SMI_CT_BUSY;
-
-       do {
-#ifdef VCPU
-               /* read Timer value */
-               SK_IN32(IoC, B2_TI_VAL, &DWord);
-
-               VCPUwaitTime(1000);
-#endif /* VCPU */
-
-               GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
-
-       /* wait until 'Busy' is cleared */
-       } while (Ctrl == Val);
-       
-#ifdef VCPU
-       VCPUgetTime(&SimCyle, &SimLowTime);
-       VCPUprintf(0, "VCPUgetTime(), SimCyle=%u, SimLowTime=%u\n",
-               SimCyle, SimLowTime);
-#endif /* VCPU */
-
-}      /* SkGmPhyWrite */
-#endif /* YUKON */
-
-
-#ifdef SK_DIAG
-/******************************************************************************
- *
- *     SkGePhyRead() - Read from PHY register
- *
- * Description:        calls a read PHY routine dep. on board type
- *
- * Returns:
- *     nothing
- */
-void SkGePhyRead(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* I/O Context */
-int            Port,           /* Port Index (MAC_1 + n) */
-int            PhyReg,         /* Register Address (Offset) */
-SK_U16 *pVal)          /* Pointer to Value */
-{
-       void (*r_func)(SK_AC *pAC, SK_IOC IoC, int Port, int Reg, SK_U16 *pVal);
-
-       if (pAC->GIni.GIGenesis) {
-               r_func = SkXmPhyRead;
-       }
-       else {
-               r_func = SkGmPhyRead;
-       }
-       
-       r_func(pAC, IoC, Port, PhyReg, pVal);
-}      /* SkGePhyRead */
-
-
-/******************************************************************************
- *
- *     SkGePhyWrite() - Write to PHY register
- *
- * Description:        calls a write PHY routine dep. on board type
- *
- * Returns:
- *     nothing
- */
-void SkGePhyWrite(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* I/O Context */
-int            Port,           /* Port Index (MAC_1 + n) */
-int            PhyReg,         /* Register Address (Offset) */
-SK_U16 Val)            /* Value */
-{
-       void (*w_func)(SK_AC *pAC, SK_IOC IoC, int Port, int Reg, SK_U16 Val);
-
-       if (pAC->GIni.GIGenesis) {
-               w_func = SkXmPhyWrite;
-       }
-       else {
-               w_func = SkGmPhyWrite;
-       }
-       
-       w_func(pAC, IoC, Port, PhyReg, Val);
-}      /* SkGePhyWrite */
-#endif /* SK_DIAG */
-
-
-/******************************************************************************
- *
- *     SkMacPromiscMode() - Enable / Disable Promiscuous Mode
- *
- * Description:
- *   enables / disables promiscuous mode by setting Mode Register (XMAC) or
- *   Receive Control Register (GMAC) dep. on board type        
- *
- * Returns:
- *     nothing
- */
-void SkMacPromiscMode(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* IO context */
-int            Port,   /* Port Index (MAC_1 + n) */
-SK_BOOL        Enable) /* Enable / Disable */
-{
-#ifdef YUKON
-       SK_U16  RcReg;
-#endif
-#ifdef GENESIS
-       SK_U32  MdReg;
-#endif 
-
-#ifdef GENESIS
-       if (pAC->GIni.GIGenesis) {
-               
-               XM_IN32(IoC, Port, XM_MODE, &MdReg);
-               /* enable or disable promiscuous mode */
-               if (Enable) {
-                       MdReg |= XM_MD_ENA_PROM;
-               }
-               else {
-                       MdReg &= ~XM_MD_ENA_PROM;
-               }
-               /* setup Mode Register */
-               XM_OUT32(IoC, Port, XM_MODE, MdReg);
-       }
-#endif /* GENESIS */
-       
-#ifdef YUKON
-       if (pAC->GIni.GIYukon) {
-               
-               GM_IN16(IoC, Port, GM_RX_CTRL, &RcReg);
-               
-               /* enable or disable unicast and multicast filtering */
-               if (Enable) {
-                       RcReg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
-               }
-               else {
-                       RcReg |= (GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
-               }
-               /* setup Receive Control Register */
-               GM_OUT16(IoC, Port, GM_RX_CTRL, RcReg);
-       }
-#endif /* YUKON */
-
-}      /* SkMacPromiscMode*/
-
-
-/******************************************************************************
- *
- *     SkMacHashing() - Enable / Disable Hashing
- *
- * Description:
- *   enables / disables hashing by setting Mode Register (XMAC) or
- *   Receive Control Register (GMAC) dep. on board type                
- *
- * Returns:
- *     nothing
- */
-void SkMacHashing(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* IO context */
-int            Port,   /* Port Index (MAC_1 + n) */
-SK_BOOL        Enable) /* Enable / Disable */
-{
-#ifdef YUKON
-       SK_U16  RcReg;
-#endif 
-#ifdef GENESIS
-       SK_U32  MdReg;
-#endif
-
-#ifdef GENESIS
-       if (pAC->GIni.GIGenesis) {
-               
-               XM_IN32(IoC, Port, XM_MODE, &MdReg);
-               /* enable or disable hashing */
-               if (Enable) {
-                       MdReg |= XM_MD_ENA_HASH;
-               }
-               else {
-                       MdReg &= ~XM_MD_ENA_HASH;
-               }
-               /* setup Mode Register */
-               XM_OUT32(IoC, Port, XM_MODE, MdReg);
-       }
-#endif /* GENESIS */
-       
-#ifdef YUKON
-       if (pAC->GIni.GIYukon) {
-               
-               GM_IN16(IoC, Port, GM_RX_CTRL, &RcReg);
-               
-               /* enable or disable multicast filtering */
-               if (Enable) {
-                       RcReg |= GM_RXCR_MCF_ENA;
-               }
-               else {
-                       RcReg &= ~GM_RXCR_MCF_ENA;
-               }
-               /* setup Receive Control Register */
-               GM_OUT16(IoC, Port, GM_RX_CTRL, RcReg);
-       }
-#endif /* YUKON */
-
-}      /* SkMacHashing*/
-
-
-#ifdef SK_DIAG
-/******************************************************************************
- *
- *     SkXmSetRxCmd() - Modify the value of the XMAC's Rx Command Register
- *
- * Description:
- *     The features
- *      - FCS stripping,                                       SK_STRIP_FCS_ON/OFF
- *      - pad byte stripping,                          SK_STRIP_PAD_ON/OFF
- *      - don't set XMR_FS_ERR in status       SK_LENERR_OK_ON/OFF
- *        for inrange length error frames
- *      - don't set XMR_FS_ERR in status       SK_BIG_PK_OK_ON/OFF
- *        for frames > 1514 bytes
- *   - enable Rx of own packets         SK_SELF_RX_ON/OFF
- *
- *     for incoming packets may be enabled/disabled by this function.
- *     Additional modes may be added later.
- *     Multiple modes can be enabled/disabled at the same time.
- *     The new configuration is written to the Rx Command register immediately.
- *
- * Returns:
- *     nothing
- */
-static void SkXmSetRxCmd(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-int            Mode)           /* Mode is SK_STRIP_FCS_ON/OFF, SK_STRIP_PAD_ON/OFF,
-                                          SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */
-{
-       SK_U16  OldRxCmd;
-       SK_U16  RxCmd;
-
-       XM_IN16(IoC, Port, XM_RX_CMD, &OldRxCmd);
-
-       RxCmd = OldRxCmd;
-       
-       switch (Mode & (SK_STRIP_FCS_ON | SK_STRIP_FCS_OFF)) {
-       case SK_STRIP_FCS_ON:
-               RxCmd |= XM_RX_STRIP_FCS;
-               break;
-       case SK_STRIP_FCS_OFF:
-               RxCmd &= ~XM_RX_STRIP_FCS;
-               break;
-       }
-
-       switch (Mode & (SK_STRIP_PAD_ON | SK_STRIP_PAD_OFF)) {
-       case SK_STRIP_PAD_ON:
-               RxCmd |= XM_RX_STRIP_PAD;
-               break;
-       case SK_STRIP_PAD_OFF:
-               RxCmd &= ~XM_RX_STRIP_PAD;
-               break;
-       }
-
-       switch (Mode & (SK_LENERR_OK_ON | SK_LENERR_OK_OFF)) {
-       case SK_LENERR_OK_ON:
-               RxCmd |= XM_RX_LENERR_OK;
-               break;
-       case SK_LENERR_OK_OFF:
-               RxCmd &= ~XM_RX_LENERR_OK;
-               break;
-       }
-
-       switch (Mode & (SK_BIG_PK_OK_ON | SK_BIG_PK_OK_OFF)) {
-       case SK_BIG_PK_OK_ON:
-               RxCmd |= XM_RX_BIG_PK_OK;
-               break;
-       case SK_BIG_PK_OK_OFF:
-               RxCmd &= ~XM_RX_BIG_PK_OK;
-               break;
-       }
-
-       switch (Mode & (SK_SELF_RX_ON | SK_SELF_RX_OFF)) {
-       case SK_SELF_RX_ON:
-               RxCmd |= XM_RX_SELF_RX;
-               break;
-       case SK_SELF_RX_OFF:
-               RxCmd &= ~XM_RX_SELF_RX;
-               break;
-       }
-
-       /* Write the new mode to the Rx command register if required */
-       if (OldRxCmd != RxCmd) {
-               XM_OUT16(IoC, Port, XM_RX_CMD, RxCmd);
-       }
-}      /* SkXmSetRxCmd */
-
-
-/******************************************************************************
- *
- *     SkGmSetRxCmd() - Modify the value of the GMAC's Rx Control Register
- *
- * Description:
- *     The features
- *      - FCS (CRC) stripping,                         SK_STRIP_FCS_ON/OFF
- *      - don't set GMR_FS_LONG_ERR            SK_BIG_PK_OK_ON/OFF
- *        for frames > 1514 bytes
- *   - enable Rx of own packets         SK_SELF_RX_ON/OFF
- *
- *     for incoming packets may be enabled/disabled by this function.
- *     Additional modes may be added later.
- *     Multiple modes can be enabled/disabled at the same time.
- *     The new configuration is written to the Rx Command register immediately.
- *
- * Returns:
- *     nothing
- */
-static void SkGmSetRxCmd(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-int            Mode)           /* Mode is SK_STRIP_FCS_ON/OFF, SK_STRIP_PAD_ON/OFF,
-                                          SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */
-{
-       SK_U16  OldRxCmd;
-       SK_U16  RxCmd;
-
-       if ((Mode & (SK_STRIP_FCS_ON | SK_STRIP_FCS_OFF)) != 0) {
-               
-               GM_IN16(IoC, Port, GM_RX_CTRL, &OldRxCmd);
-
-               RxCmd = OldRxCmd;
-
-               if ((Mode & SK_STRIP_FCS_ON) != 0) {
-                       RxCmd |= GM_RXCR_CRC_DIS;
-               }
-               else {
-                       RxCmd &= ~GM_RXCR_CRC_DIS;
-               }
-               /* Write the new mode to the Rx control register if required */
-               if (OldRxCmd != RxCmd) {
-                       GM_OUT16(IoC, Port, GM_RX_CTRL, RxCmd);
-               }
-       }
-
-       if ((Mode & (SK_BIG_PK_OK_ON | SK_BIG_PK_OK_OFF)) != 0) {
-               
-               GM_IN16(IoC, Port, GM_SERIAL_MODE, &OldRxCmd);
-
-               RxCmd = OldRxCmd;
-
-               if ((Mode & SK_BIG_PK_OK_ON) != 0) {
-                       RxCmd |= GM_SMOD_JUMBO_ENA;
-               }
-               else {
-                       RxCmd &= ~GM_SMOD_JUMBO_ENA;
-               }
-               /* Write the new mode to the Rx control register if required */
-               if (OldRxCmd != RxCmd) {
-                       GM_OUT16(IoC, Port, GM_SERIAL_MODE, RxCmd);
-               }
-       }
-}      /* SkGmSetRxCmd */
-
-
-/******************************************************************************
- *
- *     SkMacSetRxCmd() - Modify the value of the MAC's Rx Control Register
- *
- * Description:        modifies the MAC's Rx Control reg. dep. on board type
- *
- * Returns:
- *     nothing
- */
-void SkMacSetRxCmd(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-int            Mode)           /* Rx Mode */
-{
-       if (pAC->GIni.GIGenesis) {
-               
-               SkXmSetRxCmd(pAC, IoC, Port, Mode);
-       }
-       else {
-               
-               SkGmSetRxCmd(pAC, IoC, Port, Mode);
-       }
-
-}      /* SkMacSetRxCmd */
-
-
-/******************************************************************************
- *
- *     SkMacCrcGener() - Enable / Disable CRC Generation
- *
- * Description:        enables / disables CRC generation dep. on board type
- *
- * Returns:
- *     nothing
- */
-void SkMacCrcGener(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* IO context */
-int            Port,   /* Port Index (MAC_1 + n) */
-SK_BOOL        Enable) /* Enable / Disable */
-{
-       SK_U16  Word;
-
-       if (pAC->GIni.GIGenesis) {
-               
-               XM_IN16(IoC, Port, XM_TX_CMD, &Word);
-
-               if (Enable) {
-                       Word &= ~XM_TX_NO_CRC;
-               }
-               else {
-                       Word |= XM_TX_NO_CRC;
-               }
-               /* setup Tx Command Register */
-               XM_OUT16(IoC, Port, XM_TX_CMD, Word);
-       }
-       else {
-               
-               GM_IN16(IoC, Port, GM_TX_CTRL, &Word);
-               
-               if (Enable) {
-                       Word &= ~GM_TXCR_CRC_DIS;
-               }
-               else {
-                       Word |= GM_TXCR_CRC_DIS;
-               }
-               /* setup Tx Control Register */
-               GM_OUT16(IoC, Port, GM_TX_CTRL, Word);
-       }
-
-}      /* SkMacCrcGener*/
-
-#endif /* SK_DIAG */
-
-
-#ifdef GENESIS
-/******************************************************************************
- *
- *     SkXmClrExactAddr() - Clear Exact Match Address Registers
- *
- * Description:
- *     All Exact Match Address registers of the XMAC 'Port' will be
- *     cleared starting with 'StartNum' up to (and including) the
- *     Exact Match address number of 'StopNum'.
- *
- * Returns:
- *     nothing
- */
-void SkXmClrExactAddr(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-int            StartNum,       /* Begin with this Address Register Index (0..15) */
-int            StopNum)        /* Stop after finished with this Register Idx (0..15) */
-{
-       int             i;
-       SK_U16  ZeroAddr[3] = {0x0000, 0x0000, 0x0000};
-
-       if ((unsigned)StartNum > 15 || (unsigned)StopNum > 15 ||
-               StartNum > StopNum) {
-
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E001, SKERR_HWI_E001MSG);
-               return;
-       }
-
-       for (i = StartNum; i <= StopNum; i++) {
-               XM_OUTADDR(IoC, Port, XM_EXM(i), &ZeroAddr[0]);
-       }
-}      /* SkXmClrExactAddr */
-#endif /* GENESIS */
-
-
-/******************************************************************************
- *
- *     SkMacFlushTxFifo() - Flush the MAC's transmit FIFO
- *
- * Description:
- *     Flush the transmit FIFO of the MAC specified by the index 'Port'
- *
- * Returns:
- *     nothing
- */
-void SkMacFlushTxFifo(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* IO context */
-int            Port)   /* Port Index (MAC_1 + n) */
-{
-#ifdef GENESIS
-       SK_U32  MdReg;
-
-       if (pAC->GIni.GIGenesis) {
-               
-               XM_IN32(IoC, Port, XM_MODE, &MdReg);
-
-               XM_OUT32(IoC, Port, XM_MODE, MdReg | XM_MD_FTF);
-       }
-#endif /* GENESIS */
-       
-#ifdef YUKON
-       if (pAC->GIni.GIYukon) {
-               /* no way to flush the FIFO we have to issue a reset */
-               /* TBD */
-       }
-#endif /* YUKON */
-
-}      /* SkMacFlushTxFifo */
-
-
-/******************************************************************************
- *
- *     SkMacFlushRxFifo() - Flush the MAC's receive FIFO
- *
- * Description:
- *     Flush the receive FIFO of the MAC specified by the index 'Port'
- *
- * Returns:
- *     nothing
- */
-static void SkMacFlushRxFifo(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* IO context */
-int            Port)   /* Port Index (MAC_1 + n) */
-{
-#ifdef GENESIS
-       SK_U32  MdReg;
-
-       if (pAC->GIni.GIGenesis) {
-
-               XM_IN32(IoC, Port, XM_MODE, &MdReg);
-
-               XM_OUT32(IoC, Port, XM_MODE, MdReg | XM_MD_FRF);
-       }
-#endif /* GENESIS */
-       
-#ifdef YUKON
-       if (pAC->GIni.GIYukon) {
-               /* no way to flush the FIFO we have to issue a reset */
-               /* TBD */
-       }
-#endif /* YUKON */
-
-}      /* SkMacFlushRxFifo */
-
-
-#ifdef GENESIS
-/******************************************************************************
- *
- *     SkXmSoftRst() - Do a XMAC software reset
- *
- * Description:
- *     The PHY registers should not be destroyed during this
- *     kind of software reset. Therefore the XMAC Software Reset
- *     (XM_GP_RES_MAC bit in XM_GP_PORT) must not be used!
- *
- *     The software reset is done by
- *             - disabling the Rx and Tx state machine,
- *             - resetting the statistics module,
- *             - clear all other significant XMAC Mode,
- *               Command, and Control Registers
- *             - clearing the Hash Register and the
- *               Exact Match Address registers, and
- *             - flushing the XMAC's Rx and Tx FIFOs.
- *
- * Note:
- *     Another requirement when stopping the XMAC is to
- *     avoid sending corrupted frames on the network.
- *     Disabling the Tx state machine will NOT interrupt
- *     the currently transmitted frame. But we must take care
- *     that the Tx FIFO is cleared AFTER the current frame
- *     is complete sent to the network.
- *
- *     It takes about 12ns to send a frame with 1538 bytes.
- *     One PCI clock goes at least 15ns (66MHz). Therefore
- *     after reading XM_GP_PORT back, we are sure that the
- *     transmitter is disabled AND idle. And this means
- *     we may flush the transmit FIFO now.
- *
- * Returns:
- *     nothing
- */
-static void SkXmSoftRst(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* IO context */
-int            Port)   /* Port Index (MAC_1 + n) */
-{
-       SK_U16  ZeroAddr[4] = {0x0000, 0x0000, 0x0000, 0x0000};
-       
-       /* reset the statistics module */
-       XM_OUT32(IoC, Port, XM_GP_PORT, XM_GP_RES_STAT);
-
-       /* disable all XMAC IRQs */
-       XM_OUT16(IoC, Port, XM_IMSK, 0xffff);
-       
-       XM_OUT32(IoC, Port, XM_MODE, 0);                /* clear Mode Reg */
-       
-       XM_OUT16(IoC, Port, XM_TX_CMD, 0);              /* reset TX CMD Reg */
-       XM_OUT16(IoC, Port, XM_RX_CMD, 0);              /* reset RX CMD Reg */
-       
-       /* disable all PHY IRQs */
-       switch (pAC->GIni.GP[Port].PhyType) {
-       case SK_PHY_BCOM:
-                       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK, 0xffff);
-                       break;
-#ifdef OTHER_PHY
-               case SK_PHY_LONE:
-                       SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_INT_ENAB, 0);
-                       break;
-               case SK_PHY_NAT:
-                       /* todo: National
-                        SkXmPhyWrite(pAC, IoC, Port, PHY_NAT_INT_MASK, 0xffff); */
-                       break;
-#endif /* OTHER_PHY */
-       }
-
-       /* clear the Hash Register */
-       XM_OUTHASH(IoC, Port, XM_HSM, &ZeroAddr);
-
-       /* clear the Exact Match Address registers */
-       SkXmClrExactAddr(pAC, IoC, Port, 0, 15);
-       
-       /* clear the Source Check Address registers */
-       XM_OUTHASH(IoC, Port, XM_SRC_CHK, &ZeroAddr);
-
-}      /* SkXmSoftRst */
-
-
-/******************************************************************************
- *
- *     SkXmHardRst() - Do a XMAC hardware reset
- *
- * Description:
- *     The XMAC of the specified 'Port' and all connected devices
- *     (PHY and SERDES) will receive a reset signal on its *Reset pins.
- *     External PHYs must be reset by clearing a bit in the GPIO register
- *  (Timing requirements: Broadcom: 400ns, Level One: none, National: 80ns).
- *
- * ATTENTION:
- *     It is absolutely necessary to reset the SW_RST Bit first
- *     before calling this function.
- *
- * Returns:
- *     nothing
- */
-static void SkXmHardRst(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* IO context */
-int            Port)   /* Port Index (MAC_1 + n) */
-{
-       SK_U32  Reg;
-       int             i;
-       int             TOut;
-       SK_U16  Word;
-
-       for (i = 0; i < 4; i++) {
-               /* TX_MFF_CTRL1 has 32 bits, but only the lowest 16 bits are used */
-               SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_MAC_RST);
-
-               TOut = 0;
-               do {
-                       if (TOut++ > 10000) {
-                               /*
-                                * Adapter seems to be in RESET state.
-                                * Registers cannot be written.
-                                */
-                               return;
-                       }
-
-                       SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_SET_MAC_RST);
-                       
-                       SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &Word);
-               
-               } while ((Word & MFF_SET_MAC_RST) == 0);
-       }
-
-       /* For external PHYs there must be special handling */
-       if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) {
-               
-               SK_IN32(IoC, B2_GP_IO, &Reg);
-               
-               if (Port == 0) {
-                       Reg |= GP_DIR_0;        /* set to output */
-                       Reg &= ~GP_IO_0;        /* set PHY reset (active low) */
-               }
-               else {
-                       Reg |= GP_DIR_2;        /* set to output */
-                       Reg &= ~GP_IO_2;        /* set PHY reset (active low) */
-               }
-               /* reset external PHY */
-               SK_OUT32(IoC, B2_GP_IO, Reg);
-
-               /* short delay */
-               SK_IN32(IoC, B2_GP_IO, &Reg);
-       }
-}      /* SkXmHardRst */
-
-
-/******************************************************************************
- *
- *     SkXmClearRst() - Release the PHY & XMAC reset
- *
- * Description:
- *
- * Returns:
- *     nothing
- */
-static void SkXmClearRst(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* IO context */
-int            Port)   /* Port Index (MAC_1 + n) */
-{
-       SK_U32  DWord;
-       
-       /* clear HW reset */
-       SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_MAC_RST);
-
-       if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) {
-
-               SK_IN32(IoC, B2_GP_IO, &DWord);
-
-               if (Port == 0) {
-                       DWord |= (GP_DIR_0 | GP_IO_0); /* set to output */
-               }
-               else {
-                       DWord |= (GP_DIR_2 | GP_IO_2); /* set to output */
-               }
-               /* Clear PHY reset */
-               SK_OUT32(IoC, B2_GP_IO, DWord);
-
-               /* Enable GMII interface */
-               XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_GMII_MD);
-       }
-}      /* SkXmClearRst */
-#endif /* GENESIS */
-
-
-#ifdef YUKON
-/******************************************************************************
- *
- *     SkGmSoftRst() - Do a GMAC software reset
- *
- * Description:
- *     The GPHY registers should not be destroyed during this
- *     kind of software reset.
- *
- * Returns:
- *     nothing
- */
-static void SkGmSoftRst(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* IO context */
-int            Port)   /* Port Index (MAC_1 + n) */
-{
-       SK_U16  EmptyHash[4] = {0x0000, 0x0000, 0x0000, 0x0000};
-       SK_U16  RxCtrl;
-
-       /* reset the statistics module */
-
-       /* disable all GMAC IRQs */
-       SK_OUT8(IoC, GMAC_IRQ_MSK, 0);
-       
-       /* disable all PHY IRQs */
-       SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, 0);
-       
-       /* clear the Hash Register */
-       GM_OUTHASH(IoC, Port, GM_MC_ADDR_H1, EmptyHash);
-
-       /* Enable Unicast and Multicast filtering */
-       GM_IN16(IoC, Port, GM_RX_CTRL, &RxCtrl);
-       
-       GM_OUT16(IoC, Port, GM_RX_CTRL,
-               (SK_U16)(RxCtrl | GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA));
-
-}      /* SkGmSoftRst */
-
-
-/******************************************************************************
- *
- *     SkGmHardRst() - Do a GMAC hardware reset
- *
- * Description:
- *
- * Returns:
- *     nothing
- */
-static void SkGmHardRst(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* IO context */
-int            Port)   /* Port Index (MAC_1 + n) */
-{
-       SK_U32  DWord;
-       
-       /* WA code for COMA mode */
-       if (pAC->GIni.GIYukonLite &&
-               pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) {
-               
-               SK_IN32(IoC, B2_GP_IO, &DWord);
-
-               DWord |= (GP_DIR_9 | GP_IO_9);
-
-               /* set PHY reset */
-               SK_OUT32(IoC, B2_GP_IO, DWord);
-       }
-
-       /* set GPHY Control reset */
-       SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), GPC_RST_SET);
-
-       /* set GMAC Control reset */
-       SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);
-
-}      /* SkGmHardRst */
-
-
-/******************************************************************************
- *
- *     SkGmClearRst() - Release the GPHY & GMAC reset
- *
- * Description:
- *
- * Returns:
- *     nothing
- */
-static void SkGmClearRst(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* IO context */
-int            Port)   /* Port Index (MAC_1 + n) */
-{
-       SK_U32  DWord;
-       
-#ifdef XXX
-               /* clear GMAC Control reset */
-               SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_CLR);
-
-               /* set GMAC Control reset */
-               SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);
-#endif /* XXX */
-
-       /* WA code for COMA mode */
-       if (pAC->GIni.GIYukonLite &&
-               pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) {
-               
-               SK_IN32(IoC, B2_GP_IO, &DWord);
-
-               DWord |= GP_DIR_9;              /* set to output */
-               DWord &= ~GP_IO_9;              /* clear PHY reset (active high) */
-
-               /* clear PHY reset */
-               SK_OUT32(IoC, B2_GP_IO, DWord);
-       }
-
-       /* set HWCFG_MODE */
-       DWord = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP |
-               GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE |
-               (pAC->GIni.GICopperType ? GPC_HWCFG_GMII_COP :
-               GPC_HWCFG_GMII_FIB);
-
-       /* set GPHY Control reset */
-       SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_SET);
-
-       /* release GPHY Control reset */
-       SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_CLR);
-
-#ifdef VCPU
-       VCpuWait(9000);
-#endif /* VCPU */
-
-       /* clear GMAC Control reset */
-       SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR);
-
-#ifdef VCPU
-       VCpuWait(2000);
-       
-       SK_IN32(IoC, MR_ADDR(Port, GPHY_CTRL), &DWord);
-                       
-       SK_IN32(IoC, B0_ISRC, &DWord);
-#endif /* VCPU */
-
-}      /* SkGmClearRst */
-#endif /* YUKON */
-
-
-/******************************************************************************
- *
- *     SkMacSoftRst() - Do a MAC software reset
- *
- * Description:        calls a MAC software reset routine dep. on board type
- *
- * Returns:
- *     nothing
- */
-void SkMacSoftRst(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* IO context */
-int            Port)   /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       /* disable receiver and transmitter */
-       SkMacRxTxDisable(pAC, IoC, Port);
-
-#ifdef GENESIS
-       if (pAC->GIni.GIGenesis) {
-               
-               SkXmSoftRst(pAC, IoC, Port);
-       }
-#endif /* GENESIS */
-       
-#ifdef YUKON
-       if (pAC->GIni.GIYukon) {
-               
-               SkGmSoftRst(pAC, IoC, Port);
-       }
-#endif /* YUKON */
-
-       /* flush the MAC's Rx and Tx FIFOs */
-       SkMacFlushTxFifo(pAC, IoC, Port);
-       
-       SkMacFlushRxFifo(pAC, IoC, Port);
-
-       pPrt->PState = SK_PRT_STOP;
-
-}      /* SkMacSoftRst */
-
-
-/******************************************************************************
- *
- *     SkMacHardRst() - Do a MAC hardware reset
- *
- * Description:        calls a MAC hardware reset routine dep. on board type
- *
- * Returns:
- *     nothing
- */
-void SkMacHardRst(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* IO context */
-int            Port)   /* Port Index (MAC_1 + n) */
-{
-       
-#ifdef GENESIS
-       if (pAC->GIni.GIGenesis) {
-               
-               SkXmHardRst(pAC, IoC, Port);
-       }
-#endif /* GENESIS */
-       
-#ifdef YUKON
-       if (pAC->GIni.GIYukon) {
-               
-               SkGmHardRst(pAC, IoC, Port);
-       }
-#endif /* YUKON */
-
-       pAC->GIni.GP[Port].PState = SK_PRT_RESET;
-
-}      /* SkMacHardRst */
-
-
-#ifdef GENESIS
-/******************************************************************************
- *
- *     SkXmInitMac() - Initialize the XMAC II
- *
- * Description:
- *     Initialize the XMAC of the specified port.
- *     The XMAC must be reset or stopped before calling this function.
- *
- * Note:
- *     The XMAC's Rx and Tx state machine is still disabled when returning.
- *
- * Returns:
- *     nothing
- */
-void SkXmInitMac(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;
-       int                     i;
-       SK_U16          SWord;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       if (pPrt->PState == SK_PRT_STOP) {
-               /* Port State: SK_PRT_STOP */
-               /* Verify that the reset bit is cleared */
-               SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &SWord);
-
-               if ((SWord & MFF_SET_MAC_RST) != 0) {
-                       /* PState does not match HW state */
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E006, SKERR_HWI_E006MSG);
-                       /* Correct it */
-                       pPrt->PState = SK_PRT_RESET;
-               }
-       }
-
-       if (pPrt->PState == SK_PRT_RESET) {
-
-               SkXmClearRst(pAC, IoC, Port);
-
-               if (pPrt->PhyType != SK_PHY_XMAC) {
-                       /* read Id from external PHY (all have the same address) */
-                       SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_ID1, &pPrt->PhyId1);
-
-                       /*
-                        * Optimize MDIO transfer by suppressing preamble.
-                        * Must be done AFTER first access to BCOM chip.
-                        */
-                       XM_IN16(IoC, Port, XM_MMU_CMD, &SWord);
-                       
-                       XM_OUT16(IoC, Port, XM_MMU_CMD, SWord | XM_MMU_NO_PRE);
-
-                       if (pPrt->PhyId1 == PHY_BCOM_ID1_C0) {
-                               /*
-                                * Workaround BCOM Errata for the C0 type.
-                                * Write magic patterns to reserved registers.
-                                */
-                               i = 0;
-                               while (BcomRegC0Hack[i].PhyReg != 0) {
-                                       SkXmPhyWrite(pAC, IoC, Port, BcomRegC0Hack[i].PhyReg,
-                                               BcomRegC0Hack[i].PhyVal);
-                                       i++;
-                               }
-                       }
-                       else if (pPrt->PhyId1 == PHY_BCOM_ID1_A1) {
-                               /*
-                                * Workaround BCOM Errata for the A1 type.
-                                * Write magic patterns to reserved registers.
-                                */
-                               i = 0;
-                               while (BcomRegA1Hack[i].PhyReg != 0) {
-                                       SkXmPhyWrite(pAC, IoC, Port, BcomRegA1Hack[i].PhyReg,
-                                               BcomRegA1Hack[i].PhyVal);
-                                       i++;
-                               }
-                       }
-
-                       /*
-                        * Workaround BCOM Errata (#10523) for all BCom PHYs.
-                        * Disable Power Management after reset.
-                        */
-                       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &SWord);
-                       
-                       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL,
-                               (SK_U16)(SWord | PHY_B_AC_DIS_PM));
-
-                       /* PHY LED initialization is done in SkGeXmitLED() */
-               }
-
-               /* Dummy read the Interrupt source register */
-               XM_IN16(IoC, Port, XM_ISRC, &SWord);
-               
-               /*
-                * The auto-negotiation process starts immediately after
-                * clearing the reset. The auto-negotiation process should be
-                * started by the SIRQ, therefore stop it here immediately.
-                */
-               SkMacInitPhy(pAC, IoC, Port, SK_FALSE);
-
-#ifdef TEST_ONLY
-               /* temp. code: enable signal detect */
-               /* WARNING: do not override GMII setting above */
-               XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_COM4SIG);
-#endif
-       }
-
-       /*
-        * configure the XMACs Station Address
-        * B2_MAC_2 = xx xx xx xx xx x1 is programmed to XMAC A
-        * B2_MAC_3 = xx xx xx xx xx x2 is programmed to XMAC B
-        */
-       for (i = 0; i < 3; i++) {
-               /*
-                * The following 2 statements are together endianess
-                * independent. Remember this when changing.
-                */
-               SK_IN16(IoC, (B2_MAC_2 + Port * 8 + i * 2), &SWord);
-               
-               XM_OUT16(IoC, Port, (XM_SA + i * 2), SWord);
-       }
-
-       /* Tx Inter Packet Gap (XM_TX_IPG):     use default */
-       /* Tx High Water Mark (XM_TX_HI_WM):    use default */
-       /* Tx Low Water Mark (XM_TX_LO_WM):     use default */
-       /* Host Request Threshold (XM_HT_THR):  use default */
-       /* Rx Request Threshold (XM_RX_THR):    use default */
-       /* Rx Low Water Mark (XM_RX_LO_WM):     use default */
-
-       /* configure Rx High Water Mark (XM_RX_HI_WM) */
-       XM_OUT16(IoC, Port, XM_RX_HI_WM, SK_XM_RX_HI_WM);
-
-       /* Configure Tx Request Threshold */
-       SWord = SK_XM_THR_SL;                           /* for single port */
-
-       if (pAC->GIni.GIMacsFound > 1) {
-               switch (pAC->GIni.GIPortUsage) {
-               case SK_RED_LINK:
-                       SWord = SK_XM_THR_REDL;         /* redundant link */
-                       break;
-               case SK_MUL_LINK:
-                       SWord = SK_XM_THR_MULL;         /* load balancing */
-                       break;
-               case SK_JUMBO_LINK:
-                       SWord = SK_XM_THR_JUMBO;        /* jumbo frames */
-                       break;
-               default:
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E014, SKERR_HWI_E014MSG);
-                       break;
-               }
-       }
-       XM_OUT16(IoC, Port, XM_TX_THR, SWord);
-
-       /* setup register defaults for the Tx Command Register */
-       XM_OUT16(IoC, Port, XM_TX_CMD, XM_TX_AUTO_PAD);
-
-       /* setup register defaults for the Rx Command Register */
-       SWord = XM_RX_STRIP_FCS | XM_RX_LENERR_OK;
-
-       if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
-               SWord |= XM_RX_BIG_PK_OK;
-       }
-
-       if (pPrt->PLinkMode == SK_LMODE_HALF) {
-               /*
-                * If in manual half duplex mode the other side might be in
-                * full duplex mode, so ignore if a carrier extension is not seen
-                * on frames received
-                */
-               SWord |= XM_RX_DIS_CEXT;
-       }
-       
-       XM_OUT16(IoC, Port, XM_RX_CMD, SWord);
-
-       /*
-        * setup register defaults for the Mode Register
-        *      - Don't strip error frames to avoid Store & Forward
-        *        on the Rx side.
-        *      - Enable 'Check Station Address' bit
-        *      - Enable 'Check Address Array' bit
-        */
-       XM_OUT32(IoC, Port, XM_MODE, XM_DEF_MODE);
-
-       /*
-        * Initialize the Receive Counter Event Mask (XM_RX_EV_MSK)
-        *      - Enable all bits excepting 'Octets Rx OK Low CntOv'
-        *        and 'Octets Rx OK Hi Cnt Ov'.
-        */
-       XM_OUT32(IoC, Port, XM_RX_EV_MSK, XMR_DEF_MSK);
-
-       /*
-        * Initialize the Transmit Counter Event Mask (XM_TX_EV_MSK)
-        *      - Enable all bits excepting 'Octets Tx OK Low CntOv'
-        *        and 'Octets Tx OK Hi Cnt Ov'.
-        */
-       XM_OUT32(IoC, Port, XM_TX_EV_MSK, XMT_DEF_MSK);
-
-       /*
-        * Do NOT init XMAC interrupt mask here.
-        * All interrupts remain disable until link comes up!
-        */
-
-       /*
-        * Any additional configuration changes may be done now.
-        * The last action is to enable the Rx and Tx state machine.
-        * This should be done after the auto-negotiation process
-        * has been completed successfully.
-        */
-}      /* SkXmInitMac */
-#endif /* GENESIS */
-
-
-#ifdef YUKON
-/******************************************************************************
- *
- *     SkGmInitMac() - Initialize the GMAC
- *
- * Description:
- *     Initialize the GMAC of the specified port.
- *     The GMAC must be reset or stopped before calling this function.
- *
- * Note:
- *     The GMAC's Rx and Tx state machine is still disabled when returning.
- *
- * Returns:
- *     nothing
- */
-void SkGmInitMac(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;
-       int                     i;
-       SK_U16          SWord;
-       SK_U32          DWord;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       if (pPrt->PState == SK_PRT_STOP) {
-               /* Port State: SK_PRT_STOP */
-               /* Verify that the reset bit is cleared */
-               SK_IN32(IoC, MR_ADDR(Port, GMAC_CTRL), &DWord);
-               
-               if ((DWord & GMC_RST_SET) != 0) {
-                       /* PState does not match HW state */
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E006, SKERR_HWI_E006MSG);
-                       /* Correct it */
-                       pPrt->PState = SK_PRT_RESET;
-               }
-       }
-
-       if (pPrt->PState == SK_PRT_RESET) {
-               
-               SkGmHardRst(pAC, IoC, Port);
-
-               SkGmClearRst(pAC, IoC, Port);
-               
-               /* Auto-negotiation ? */
-               if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
-                       /* Auto-negotiation disabled */
-
-                       /* get General Purpose Control */
-                       GM_IN16(IoC, Port, GM_GP_CTRL, &SWord);
-
-                       /* disable auto-update for speed, duplex and flow-control */
-                       SWord |= GM_GPCR_AU_ALL_DIS;
-                       
-                       /* setup General Purpose Control Register */
-                       GM_OUT16(IoC, Port, GM_GP_CTRL, SWord);
-                       
-                       SWord = GM_GPCR_AU_ALL_DIS;
-               }
-               else {
-                       SWord = 0;
-               }
-
-               /* speed settings */
-               switch (pPrt->PLinkSpeed) {
-               case SK_LSPEED_AUTO:
-               case SK_LSPEED_1000MBPS:
-                       SWord |= GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100;
-                       break;
-               case SK_LSPEED_100MBPS:
-                       SWord |= GM_GPCR_SPEED_100;
-                       break;
-               case SK_LSPEED_10MBPS:
-                       break;
-               }
-
-               /* duplex settings */
-               if (pPrt->PLinkMode != SK_LMODE_HALF) {
-                       /* set full duplex */
-                       SWord |= GM_GPCR_DUP_FULL;
-               }
-
-               /* flow-control settings */
-               switch (pPrt->PFlowCtrlMode) {
-               case SK_FLOW_MODE_NONE:
-                       /* set Pause Off */
-                       SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_OFF);
-                       /* disable Tx & Rx flow-control */
-                       SWord |= GM_GPCR_FC_TX_DIS | GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS;
-                       break;
-               case SK_FLOW_MODE_LOC_SEND:
-                       /* disable Rx flow-control */
-                       SWord |= GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS;
-                       break;
-               case SK_FLOW_MODE_SYMMETRIC:
-               case SK_FLOW_MODE_SYM_OR_REM:
-                       /* enable Tx & Rx flow-control */
-                       break;
-               }
-
-               /* setup General Purpose Control Register */
-               GM_OUT16(IoC, Port, GM_GP_CTRL, SWord);
-
-               /* dummy read the Interrupt Source Register */
-               SK_IN16(IoC, GMAC_IRQ_SRC, &SWord);
-               
-#ifndef VCPU
-               /* read Id from PHY */
-               SkGmPhyRead(pAC, IoC, Port, PHY_MARV_ID1, &pPrt->PhyId1);
-               
-               SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE);
-#endif /* VCPU */
-       }
-
-       (void)SkGmResetCounter(pAC, IoC, Port);
-
-       /* setup Transmit Control Register */
-       GM_OUT16(IoC, Port, GM_TX_CTRL, TX_COL_THR(pPrt->PMacColThres));
-
-       /* setup Receive Control Register */
-       GM_OUT16(IoC, Port, GM_RX_CTRL, GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA |
-               GM_RXCR_CRC_DIS);
-
-       /* setup Transmit Flow Control Register */
-       GM_OUT16(IoC, Port, GM_TX_FLOW_CTRL, 0xffff);
-
-       /* setup Transmit Parameter Register */
-#ifdef VCPU
-       GM_IN16(IoC, Port, GM_TX_PARAM, &SWord);
-#endif /* VCPU */
-
-    SWord = TX_JAM_LEN_VAL(pPrt->PMacJamLen) |
-                       TX_JAM_IPG_VAL(pPrt->PMacJamIpgVal) |
-                       TX_IPG_JAM_DATA(pPrt->PMacJamIpgData);
-       
-       GM_OUT16(IoC, Port, GM_TX_PARAM, SWord);
-
-       /* configure the Serial Mode Register */
-#ifdef VCPU
-       GM_IN16(IoC, Port, GM_SERIAL_MODE, &SWord);
-#endif /* VCPU */
-       
-       SWord = GM_SMOD_VLAN_ENA | IPG_DATA_VAL(pPrt->PMacIpgData);
-
-       if (pPrt->PMacLimit4) {
-               /* reset of collision counter after 4 consecutive collisions */
-               SWord |= GM_SMOD_LIMIT_4;
-       }
-
-       if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
-               /* enable jumbo mode (Max. Frame Length = 9018) */
-               SWord |= GM_SMOD_JUMBO_ENA;
-       }
-       
-       GM_OUT16(IoC, Port, GM_SERIAL_MODE, SWord);
-       
-       /*
-        * configure the GMACs Station Addresses
-        * in PROM you can find our addresses at:
-        * B2_MAC_1 = xx xx xx xx xx x0 virtual address
-        * B2_MAC_2 = xx xx xx xx xx x1 is programmed to GMAC A
-        * B2_MAC_3 = xx xx xx xx xx x2 is reserved for DualPort
-        */
-
-       for (i = 0; i < 3; i++) {
-               /*
-                * The following 2 statements are together endianess
-                * independent. Remember this when changing.
-                */
-               /* physical address: will be used for pause frames */
-               SK_IN16(IoC, (B2_MAC_2 + Port * 8 + i * 2), &SWord);
-
-#ifdef WA_DEV_16
-               /* WA for deviation #16 */
-               if (pAC->GIni.GIChipId == CHIP_ID_YUKON && pAC->GIni.GIChipRev == 0) {
-                       /* swap the address bytes */
-                       SWord = ((SWord & 0xff00) >> 8) | ((SWord & 0x00ff) << 8);
-
-                       /* write to register in reversed order */
-                       GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + (2 - i) * 4), SWord);
-               }
-               else {
-                       GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + i * 4), SWord);
-               }
-#else          
-               GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + i * 4), SWord);
-#endif /* WA_DEV_16 */
-               
-               /* virtual address: will be used for data */
-               SK_IN16(IoC, (B2_MAC_1 + Port * 8 + i * 2), &SWord);
-
-               GM_OUT16(IoC, Port, (GM_SRC_ADDR_2L + i * 4), SWord);
-               
-               /* reset Multicast filtering Hash registers 1-3 */
-               GM_OUT16(IoC, Port, GM_MC_ADDR_H1 + 4*i, 0);
-       }
-
-       /* reset Multicast filtering Hash register 4 */
-       GM_OUT16(IoC, Port, GM_MC_ADDR_H4, 0);
-
-       /* enable interrupt mask for counter overflows */
-       GM_OUT16(IoC, Port, GM_TX_IRQ_MSK, 0);
-       GM_OUT16(IoC, Port, GM_RX_IRQ_MSK, 0);
-       GM_OUT16(IoC, Port, GM_TR_IRQ_MSK, 0);
-
-#if defined(SK_DIAG) || defined(DEBUG)
-       /* read General Purpose Status */
-       GM_IN16(IoC, Port, GM_GP_STAT, &SWord);
-       
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("MAC Stat Reg.=0x%04X\n", SWord));
-#endif /* SK_DIAG || DEBUG */
-
-#ifdef SK_DIAG
-       c_print("MAC Stat Reg=0x%04X\n", SWord);
-#endif /* SK_DIAG */
-
-}      /* SkGmInitMac */
-#endif /* YUKON */
-
-
-#ifdef GENESIS
-/******************************************************************************
- *
- *     SkXmInitDupMd() - Initialize the XMACs Duplex Mode
- *
- * Description:
- *     This function initializes the XMACs Duplex Mode.
- *     It should be called after successfully finishing
- *     the Auto-negotiation Process
- *
- * Returns:
- *     nothing
- */
-static void SkXmInitDupMd(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-       switch (pAC->GIni.GP[Port].PLinkModeStatus) {
-       case SK_LMODE_STAT_AUTOHALF:
-       case SK_LMODE_STAT_HALF:
-               /* Configuration Actions for Half Duplex Mode */
-               /*
-                * XM_BURST = default value. We are probable not quick
-                *      enough at the 'XMAC' bus to burst 8kB.
-                *      The XMAC stops bursting if no transmit frames
-                *      are available or the burst limit is exceeded.
-                */
-               /* XM_TX_RT_LIM = default value (15) */
-               /* XM_TX_STIME = default value (0xff = 4096 bit times) */
-               break;
-       case SK_LMODE_STAT_AUTOFULL:
-       case SK_LMODE_STAT_FULL:
-               /* Configuration Actions for Full Duplex Mode */
-               /*
-                * The duplex mode is configured by the PHY,
-                * therefore it seems to be that there is nothing
-                * to do here.
-                */
-               break;
-       case SK_LMODE_STAT_UNKNOWN:
-       default:
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E007, SKERR_HWI_E007MSG);
-               break;
-       }
-}      /* SkXmInitDupMd */
-
-
-/******************************************************************************
- *
- *     SkXmInitPauseMd() - initialize the Pause Mode to be used for this port
- *
- * Description:
- *     This function initializes the Pause Mode which should
- *     be used for this port.
- *     It should be called after successfully finishing
- *     the Auto-negotiation Process
- *
- * Returns:
- *     nothing
- */
-static void SkXmInitPauseMd(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;
-       SK_U32          DWord;
-       SK_U16          Word;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
-       
-       if (pPrt->PFlowCtrlStatus == SK_FLOW_STAT_NONE ||
-               pPrt->PFlowCtrlStatus == SK_FLOW_STAT_LOC_SEND) {
-
-               /* Disable Pause Frame Reception */
-               Word |= XM_MMU_IGN_PF;
-       }
-       else {
-               /*
-                * enabling pause frame reception is required for 1000BT
-                * because the XMAC is not reset if the link is going down
-                */
-               /* Enable Pause Frame Reception */
-               Word &= ~XM_MMU_IGN_PF;
-       }       
-       
-       XM_OUT16(IoC, Port, XM_MMU_CMD, Word);
-
-       XM_IN32(IoC, Port, XM_MODE, &DWord);
-
-       if (pPrt->PFlowCtrlStatus == SK_FLOW_STAT_SYMMETRIC ||
-               pPrt->PFlowCtrlStatus == SK_FLOW_STAT_LOC_SEND) {
-
-               /*
-                * Configure Pause Frame Generation
-                * Use internal and external Pause Frame Generation.
-                * Sending pause frames is edge triggered.
-                * Send a Pause frame with the maximum pause time if
-                * internal oder external FIFO full condition occurs.
-                * Send a zero pause time frame to re-start transmission.
-                */
-
-               /* XM_PAUSE_DA = '010000C28001' (default) */
-
-               /* XM_MAC_PTIME = 0xffff (maximum) */
-               /* remember this value is defined in big endian (!) */
-               XM_OUT16(IoC, Port, XM_MAC_PTIME, 0xffff);
-
-               /* Set Pause Mode in Mode Register */
-               DWord |= XM_PAUSE_MODE;
-
-               /* Set Pause Mode in MAC Rx FIFO */
-               SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_ENA_PAUSE);
-       }
-       else {
-               /*
-                * disable pause frame generation is required for 1000BT
-                * because the XMAC is not reset if the link is going down
-                */
-               /* Disable Pause Mode in Mode Register */
-               DWord &= ~XM_PAUSE_MODE;
-
-               /* Disable Pause Mode in MAC Rx FIFO */
-               SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_DIS_PAUSE);
-       }
-       
-       XM_OUT32(IoC, Port, XM_MODE, DWord);
-}      /* SkXmInitPauseMd*/
-
-
-/******************************************************************************
- *
- *     SkXmInitPhyXmac() - Initialize the XMAC Phy registers
- *
- * Description:        initializes all the XMACs Phy registers
- *
- * Note:
- *
- * Returns:
- *     nothing
- */
-static void SkXmInitPhyXmac(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-SK_BOOL        DoLoop)         /* Should a Phy LoopBack be set-up? */
-{
-       SK_GEPORT       *pPrt;
-       SK_U16          Ctrl;
-
-       pPrt = &pAC->GIni.GP[Port];
-       Ctrl = 0;
-       
-       /* Auto-negotiation ? */
-       if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("InitPhyXmac: no auto-negotiation Port %d\n", Port));
-               /* Set DuplexMode in Config register */
-               if (pPrt->PLinkMode == SK_LMODE_FULL) {
-                       Ctrl |= PHY_CT_DUP_MD;
-               }
-
-               /*
-                * Do NOT enable Auto-negotiation here. This would hold
-                * the link down because no IDLEs are transmitted
-                */
-       }
-       else {
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("InitPhyXmac: with auto-negotiation Port %d\n", Port));
-               /* Set Auto-negotiation advertisement */
-
-               /* Set Full/half duplex capabilities */
-               switch (pPrt->PLinkMode) {
-               case SK_LMODE_AUTOHALF:
-                       Ctrl |= PHY_X_AN_HD;
-                       break;
-               case SK_LMODE_AUTOFULL:
-                       Ctrl |= PHY_X_AN_FD;
-                       break;
-               case SK_LMODE_AUTOBOTH:
-                       Ctrl |= PHY_X_AN_FD | PHY_X_AN_HD;
-                       break;
-               default:
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
-                               SKERR_HWI_E015MSG);
-               }
-
-               /* Set Flow-control capabilities */
-               switch (pPrt->PFlowCtrlMode) {
-               case SK_FLOW_MODE_NONE:
-                       Ctrl |= PHY_X_P_NO_PAUSE;
-                       break;
-               case SK_FLOW_MODE_LOC_SEND:
-                       Ctrl |= PHY_X_P_ASYM_MD;
-                       break;
-               case SK_FLOW_MODE_SYMMETRIC:
-                       Ctrl |= PHY_X_P_SYM_MD;
-                       break;
-               case SK_FLOW_MODE_SYM_OR_REM:
-                       Ctrl |= PHY_X_P_BOTH_MD;
-                       break;
-               default:
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
-                               SKERR_HWI_E016MSG);
-               }
-
-               /* Write AutoNeg Advertisement Register */
-               SkXmPhyWrite(pAC, IoC, Port, PHY_XMAC_AUNE_ADV, Ctrl);
-
-               /* Restart Auto-negotiation */
-               Ctrl = PHY_CT_ANE | PHY_CT_RE_CFG;
-       }
-
-       if (DoLoop) {
-               /* Set the Phy Loopback bit, too */
-               Ctrl |= PHY_CT_LOOP;
-       }
-
-       /* Write to the Phy control register */
-       SkXmPhyWrite(pAC, IoC, Port, PHY_XMAC_CTRL, Ctrl);
-}      /* SkXmInitPhyXmac */
-
-
-/******************************************************************************
- *
- *     SkXmInitPhyBcom() - Initialize the Broadcom Phy registers
- *
- * Description:        initializes all the Broadcom Phy registers
- *
- * Note:
- *
- * Returns:
- *     nothing
- */
-static void SkXmInitPhyBcom(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-SK_BOOL        DoLoop)         /* Should a Phy LoopBack be set-up? */
-{
-       SK_GEPORT       *pPrt;
-       SK_U16          Ctrl1;
-       SK_U16          Ctrl2;
-       SK_U16          Ctrl3;
-       SK_U16          Ctrl4;
-       SK_U16          Ctrl5;
-
-       Ctrl1 = PHY_CT_SP1000;
-       Ctrl2 = 0;
-       Ctrl3 = PHY_SEL_TYPE;
-       Ctrl4 = PHY_B_PEC_EN_LTR;
-       Ctrl5 = PHY_B_AC_TX_TST;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       /* manually Master/Slave ? */
-       if (pPrt->PMSMode != SK_MS_MODE_AUTO) {
-               Ctrl2 |= PHY_B_1000C_MSE;
-               
-               if (pPrt->PMSMode == SK_MS_MODE_MASTER) {
-                       Ctrl2 |= PHY_B_1000C_MSC;
-               }
-       }
-       /* Auto-negotiation ? */
-       if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("InitPhyBcom: no auto-negotiation Port %d\n", Port));
-               /* Set DuplexMode in Config register */
-               if (pPrt->PLinkMode == SK_LMODE_FULL) {
-                       Ctrl1 |= PHY_CT_DUP_MD;
-               }
-
-               /* Determine Master/Slave manually if not already done */
-               if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
-                       Ctrl2 |= PHY_B_1000C_MSE;       /* set it to Slave */
-               }
-
-               /*
-                * Do NOT enable Auto-negotiation here. This would hold
-                * the link down because no IDLES are transmitted
-                */
-       }
-       else {
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("InitPhyBcom: with auto-negotiation Port %d\n", Port));
-               /* Set Auto-negotiation advertisement */
-
-               /*
-                * Workaround BCOM Errata #1 for the C5 type.
-                * 1000Base-T Link Acquisition Failure in Slave Mode
-                * Set Repeater/DTE bit 10 of the 1000Base-T Control Register
-                */
-               Ctrl2 |= PHY_B_1000C_RD;
-               
-                /* Set Full/half duplex capabilities */
-               switch (pPrt->PLinkMode) {
-               case SK_LMODE_AUTOHALF:
-                       Ctrl2 |= PHY_B_1000C_AHD;
-                       break;
-               case SK_LMODE_AUTOFULL:
-                       Ctrl2 |= PHY_B_1000C_AFD;
-                       break;
-               case SK_LMODE_AUTOBOTH:
-                       Ctrl2 |= PHY_B_1000C_AFD | PHY_B_1000C_AHD;
-                       break;
-               default:
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
-                               SKERR_HWI_E015MSG);
-               }
-
-               /* Set Flow-control capabilities */
-               switch (pPrt->PFlowCtrlMode) {
-               case SK_FLOW_MODE_NONE:
-                       Ctrl3 |= PHY_B_P_NO_PAUSE;
-                       break;
-               case SK_FLOW_MODE_LOC_SEND:
-                       Ctrl3 |= PHY_B_P_ASYM_MD;
-                       break;
-               case SK_FLOW_MODE_SYMMETRIC:
-                       Ctrl3 |= PHY_B_P_SYM_MD;
-                       break;
-               case SK_FLOW_MODE_SYM_OR_REM:
-                       Ctrl3 |= PHY_B_P_BOTH_MD;
-                       break;
-               default:
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
-                               SKERR_HWI_E016MSG);
-               }
-
-               /* Restart Auto-negotiation */
-               Ctrl1 |= PHY_CT_ANE | PHY_CT_RE_CFG;
-       }
-       
-       /* Initialize LED register here? */
-       /* No. Please do it in SkDgXmitLed() (if required) and swap
-          init order of LEDs and XMAC. (MAl) */
-       
-       /* Write 1000Base-T Control Register */
-       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, Ctrl2);
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("Set 1000B-T Ctrl Reg=0x%04X\n", Ctrl2));
-       
-       /* Write AutoNeg Advertisement Register */
-       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, Ctrl3);
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("Set Auto-Neg.Adv.Reg=0x%04X\n", Ctrl3));
-       
-       if (DoLoop) {
-               /* Set the Phy Loopback bit, too */
-               Ctrl1 |= PHY_CT_LOOP;
-       }
-
-       if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
-               /* configure FIFO to high latency for transmission of ext. packets */
-               Ctrl4 |= PHY_B_PEC_HIGH_LA;
-
-               /* configure reception of extended packets */
-               Ctrl5 |= PHY_B_AC_LONG_PACK;
-
-               SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, Ctrl5);
-       }
-
-       /* Configure LED Traffic Mode and Jumbo Frame usage if specified */
-       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, Ctrl4);
-       
-       /* Write to the Phy control register */
-       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL, Ctrl1);
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("PHY Control Reg=0x%04X\n", Ctrl1));
-}      /* SkXmInitPhyBcom */
-#endif /* GENESIS */
-
-#ifdef YUKON
-/******************************************************************************
- *
- *     SkGmInitPhyMarv() - Initialize the Marvell Phy registers
- *
- * Description:        initializes all the Marvell Phy registers
- *
- * Note:
- *
- * Returns:
- *     nothing
- */
-static void SkGmInitPhyMarv(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-SK_BOOL        DoLoop)         /* Should a Phy LoopBack be set-up? */
-{
-       SK_GEPORT       *pPrt;
-       SK_U16          PhyCtrl;
-       SK_U16          C1000BaseT;
-       SK_U16          AutoNegAdv;
-       SK_U16          ExtPhyCtrl;
-       SK_U16          LedCtrl;
-       SK_BOOL         AutoNeg;
-#if defined(SK_DIAG) || defined(DEBUG)
-       SK_U16          PhyStat;
-       SK_U16          PhyStat1;
-       SK_U16          PhySpecStat;
-#endif /* SK_DIAG || DEBUG */
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       /* Auto-negotiation ? */
-       if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
-               AutoNeg = SK_FALSE;
-       }
-       else {
-               AutoNeg = SK_TRUE;
-       }
-       
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("InitPhyMarv: Port %d, auto-negotiation %s\n",
-                Port, AutoNeg ? "ON" : "OFF"));
-
-#ifdef VCPU
-       VCPUprintf(0, "SkGmInitPhyMarv(), Port=%u, DoLoop=%u\n",
-               Port, DoLoop);
-#else /* VCPU */
-       if (DoLoop) {
-               /* Set 'MAC Power up'-bit, set Manual MDI configuration */
-               SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL,
-                       PHY_M_PC_MAC_POW_UP);
-       }
-       else if (AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_AUTO) {
-               /* Read Ext. PHY Specific Control */
-               SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl);
-               
-               ExtPhyCtrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK |
-                       PHY_M_EC_MAC_S_MSK);
-               
-               ExtPhyCtrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ) |
-                       PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1);
-       
-               SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL, ExtPhyCtrl);
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("Set Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl));
-       }
-
-       /* Read PHY Control */
-       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl);
-
-       if (!AutoNeg) {
-               /* Disable Auto-negotiation */
-               PhyCtrl &= ~PHY_CT_ANE;
-       }
-
-       PhyCtrl |= PHY_CT_RESET;
-       /* Assert software reset */
-       SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl);
-#endif /* VCPU */
-
-       PhyCtrl = 0 /* PHY_CT_COL_TST */;
-       C1000BaseT = 0;
-       AutoNegAdv = PHY_SEL_TYPE;
-
-       /* manually Master/Slave ? */
-       if (pPrt->PMSMode != SK_MS_MODE_AUTO) {
-               /* enable Manual Master/Slave */
-               C1000BaseT |= PHY_M_1000C_MSE;
-               
-               if (pPrt->PMSMode == SK_MS_MODE_MASTER) {
-                       C1000BaseT |= PHY_M_1000C_MSC;  /* set it to Master */
-               }
-       }
-       
-       /* Auto-negotiation ? */
-       if (!AutoNeg) {
-               
-               if (pPrt->PLinkMode == SK_LMODE_FULL) {
-                       /* Set Full Duplex Mode */
-                       PhyCtrl |= PHY_CT_DUP_MD;
-               }
-
-               /* Set Master/Slave manually if not already done */
-               if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
-                       C1000BaseT |= PHY_M_1000C_MSE;  /* set it to Slave */
-               }
-
-               /* Set Speed */
-               switch (pPrt->PLinkSpeed) {
-               case SK_LSPEED_AUTO:
-               case SK_LSPEED_1000MBPS:
-                       PhyCtrl |= PHY_CT_SP1000;
-                       break;
-               case SK_LSPEED_100MBPS:
-                       PhyCtrl |= PHY_CT_SP100;
-                       break;
-               case SK_LSPEED_10MBPS:
-                       break;
-               default:
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E019,
-                               SKERR_HWI_E019MSG);
-               }
-
-               if (!DoLoop) {
-                       PhyCtrl |= PHY_CT_RESET;
-               }
-       }
-       else {
-               /* Set Auto-negotiation advertisement */
-               
-               if (pAC->GIni.GICopperType) {
-                       /* Set Speed capabilities */
-                       switch (pPrt->PLinkSpeed) {
-                       case SK_LSPEED_AUTO:
-                               C1000BaseT |= PHY_M_1000C_AHD | PHY_M_1000C_AFD;
-                               AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD |
-                                       PHY_M_AN_10_FD | PHY_M_AN_10_HD;
-                               break;
-                       case SK_LSPEED_1000MBPS:
-                               C1000BaseT |= PHY_M_1000C_AHD | PHY_M_1000C_AFD;
-                               break;
-                       case SK_LSPEED_100MBPS:
-                               AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD |
-                                       /* advertise 10Base-T also */
-                                       PHY_M_AN_10_FD | PHY_M_AN_10_HD;
-                               break;
-                       case SK_LSPEED_10MBPS:
-                               AutoNegAdv |= PHY_M_AN_10_FD | PHY_M_AN_10_HD;
-                               break;
-                       default:
-                               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E019,
-                                       SKERR_HWI_E019MSG);
-                       }
-
-                       /* Set Full/half duplex capabilities */
-                       switch (pPrt->PLinkMode) {
-                       case SK_LMODE_AUTOHALF:
-                               C1000BaseT &= ~PHY_M_1000C_AFD;
-                               AutoNegAdv &= ~(PHY_M_AN_100_FD | PHY_M_AN_10_FD);
-                               break;
-                       case SK_LMODE_AUTOFULL:
-                               C1000BaseT &= ~PHY_M_1000C_AHD;
-                               AutoNegAdv &= ~(PHY_M_AN_100_HD | PHY_M_AN_10_HD);
-                               break;
-                       case SK_LMODE_AUTOBOTH:
-                               break;
-                       default:
-                               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
-                                       SKERR_HWI_E015MSG);
-                       }
-                       
-                       /* Set Flow-control capabilities */
-                       switch (pPrt->PFlowCtrlMode) {
-                       case SK_FLOW_MODE_NONE:
-                               AutoNegAdv |= PHY_B_P_NO_PAUSE;
-                               break;
-                       case SK_FLOW_MODE_LOC_SEND:
-                               AutoNegAdv |= PHY_B_P_ASYM_MD;
-                               break;
-                       case SK_FLOW_MODE_SYMMETRIC:
-                               AutoNegAdv |= PHY_B_P_SYM_MD;
-                               break;
-                       case SK_FLOW_MODE_SYM_OR_REM:
-                               AutoNegAdv |= PHY_B_P_BOTH_MD;
-                               break;
-                       default:
-                               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
-                                       SKERR_HWI_E016MSG);
-                       }
-               }
-               else {  /* special defines for FIBER (88E1011S only) */
-                       
-                       /* Set Full/half duplex capabilities */
-                       switch (pPrt->PLinkMode) {
-                       case SK_LMODE_AUTOHALF:
-                               AutoNegAdv |= PHY_M_AN_1000X_AHD;
-                               break;
-                       case SK_LMODE_AUTOFULL:
-                               AutoNegAdv |= PHY_M_AN_1000X_AFD;
-                               break;
-                       case SK_LMODE_AUTOBOTH:
-                               AutoNegAdv |= PHY_M_AN_1000X_AHD | PHY_M_AN_1000X_AFD;
-                               break;
-                       default:
-                               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
-                                       SKERR_HWI_E015MSG);
-                       }
-                       
-                       /* Set Flow-control capabilities */
-                       switch (pPrt->PFlowCtrlMode) {
-                       case SK_FLOW_MODE_NONE:
-                               AutoNegAdv |= PHY_M_P_NO_PAUSE_X;
-                               break;
-                       case SK_FLOW_MODE_LOC_SEND:
-                               AutoNegAdv |= PHY_M_P_ASYM_MD_X;
-                               break;
-                       case SK_FLOW_MODE_SYMMETRIC:
-                               AutoNegAdv |= PHY_M_P_SYM_MD_X;
-                               break;
-                       case SK_FLOW_MODE_SYM_OR_REM:
-                               AutoNegAdv |= PHY_M_P_BOTH_MD_X;
-                               break;
-                       default:
-                               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
-                                       SKERR_HWI_E016MSG);
-                       }
-               }
-
-               if (!DoLoop) {
-                       /* Restart Auto-negotiation */
-                       PhyCtrl |= PHY_CT_ANE | PHY_CT_RE_CFG;
-               }
-       }
-       
-#ifdef VCPU
-       /*
-        * E-mail from Gu Lin (08-03-2002):
-        */
-       
-       /* Program PHY register 30 as 16'h0708 for simulation speed up */
-       SkGmPhyWrite(pAC, IoC, Port, 30, 0x0700 /* 0x0708 */);
-       
-       VCpuWait(2000);
-
-#else /* VCPU */
-       
-       /* Write 1000Base-T Control Register */
-       SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_1000T_CTRL, C1000BaseT);
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("Set 1000B-T Ctrl =0x%04X\n", C1000BaseT));
-       
-       /* Write AutoNeg Advertisement Register */
-       SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV, AutoNegAdv);
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("Set Auto-Neg.Adv.=0x%04X\n", AutoNegAdv));
-#endif /* VCPU */
-       
-       if (DoLoop) {
-               /* Set the PHY Loopback bit */
-               PhyCtrl |= PHY_CT_LOOP;
-
-#ifdef XXX
-               /* Program PHY register 16 as 16'h0400 to force link good */
-               SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PHY_M_PC_FL_GOOD);
-#endif /* XXX */
-
-#ifndef VCPU
-               if (pPrt->PLinkSpeed != SK_LSPEED_AUTO) {
-                       /* Write Ext. PHY Specific Control */
-                       SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL,
-                               (SK_U16)((pPrt->PLinkSpeed + 2) << 4));
-               }
-#endif /* VCPU */
-       }
-#ifdef TEST_ONLY
-       else if (pPrt->PLinkSpeed == SK_LSPEED_10MBPS) {
-                       /* Write PHY Specific Control */
-                       SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL,
-                               PHY_M_PC_EN_DET_MSK);
-       }
-#endif
-
-       /* Write to the PHY Control register */
-       SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl);
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("Set PHY Ctrl Reg.=0x%04X\n", PhyCtrl));
-
-#ifdef VCPU
-       VCpuWait(2000);
-#else
-
-       LedCtrl = PHY_M_LED_PULS_DUR(PULS_170MS) | PHY_M_LED_BLINK_RT(BLINK_84MS);
-
-       if ((pAC->GIni.GILedBlinkCtrl & SK_ACT_LED_BLINK) != 0) {
-               LedCtrl |= PHY_M_LEDC_RX_CTRL | PHY_M_LEDC_TX_CTRL;
-       }
-
-       if ((pAC->GIni.GILedBlinkCtrl & SK_DUP_LED_NORMAL) != 0) {
-               LedCtrl |= PHY_M_LEDC_DP_CTRL;
-       }
-       
-       SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_CTRL, LedCtrl);
-
-       if ((pAC->GIni.GILedBlinkCtrl & SK_LED_LINK100_ON) != 0) {
-               /* only in forced 100 Mbps mode */
-               if (!AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_100MBPS) {
-
-                       SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_OVER,
-                               PHY_M_LED_MO_100(MO_LED_ON));
-               }
-       }
-
-#ifdef SK_DIAG
-       c_print("Set PHY Ctrl=0x%04X\n", PhyCtrl);
-       c_print("Set 1000 B-T=0x%04X\n", C1000BaseT);
-       c_print("Set Auto-Neg=0x%04X\n", AutoNegAdv);
-       c_print("Set Ext Ctrl=0x%04X\n", ExtPhyCtrl);
-#endif /* SK_DIAG */
-
-#if defined(SK_DIAG) || defined(DEBUG)
-       /* Read PHY Control */
-       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl);
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("PHY Ctrl Reg.=0x%04X\n", PhyCtrl));
-       
-       /* Read 1000Base-T Control Register */
-       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_CTRL, &C1000BaseT);
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("1000B-T Ctrl =0x%04X\n", C1000BaseT));
-       
-       /* Read AutoNeg Advertisement Register */
-       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &AutoNegAdv);
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("Auto-Neg.Adv.=0x%04X\n", AutoNegAdv));
-       
-       /* Read Ext. PHY Specific Control */
-       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl);
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl));
-       
-       /* Read PHY Status */
-       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat);
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("PHY Stat Reg.=0x%04X\n", PhyStat));
-       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat1);
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("PHY Stat Reg.=0x%04X\n", PhyStat1));
-       
-       /* Read PHY Specific Status */
-       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat);
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("PHY Spec Stat=0x%04X\n", PhySpecStat));
-#endif /* SK_DIAG || DEBUG */
-
-#ifdef SK_DIAG
-       c_print("PHY Ctrl Reg=0x%04X\n", PhyCtrl);
-       c_print("PHY 1000 Reg=0x%04X\n", C1000BaseT);
-       c_print("PHY AnAd Reg=0x%04X\n", AutoNegAdv);
-       c_print("Ext Ctrl Reg=0x%04X\n", ExtPhyCtrl);
-       c_print("PHY Stat Reg=0x%04X\n", PhyStat);
-       c_print("PHY Stat Reg=0x%04X\n", PhyStat1);
-       c_print("PHY Spec Reg=0x%04X\n", PhySpecStat);
-#endif /* SK_DIAG */
-
-#endif /* VCPU */
-
-}      /* SkGmInitPhyMarv */
-#endif /* YUKON */
-
-
-#ifdef OTHER_PHY
-/******************************************************************************
- *
- *     SkXmInitPhyLone() - Initialize the Level One Phy registers
- *
- * Description:        initializes all the Level One Phy registers
- *
- * Note:
- *
- * Returns:
- *     nothing
- */
-static void SkXmInitPhyLone(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-SK_BOOL        DoLoop)         /* Should a Phy LoopBack be set-up? */
-{
-       SK_GEPORT       *pPrt;
-       SK_U16          Ctrl1;
-       SK_U16          Ctrl2;
-       SK_U16          Ctrl3;
-
-       Ctrl1 = PHY_CT_SP1000;
-       Ctrl2 = 0;
-       Ctrl3 = PHY_SEL_TYPE;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       /* manually Master/Slave ? */
-       if (pPrt->PMSMode != SK_MS_MODE_AUTO) {
-               Ctrl2 |= PHY_L_1000C_MSE;
-               
-               if (pPrt->PMSMode == SK_MS_MODE_MASTER) {
-                       Ctrl2 |= PHY_L_1000C_MSC;
-               }
-       }
-       /* Auto-negotiation ? */
-       if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
-               /*
-                * level one spec say: "1000 Mbps: manual mode not allowed"
-                * but lets see what happens...
-                */
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("InitPhyLone: no auto-negotiation Port %d\n", Port));
-               /* Set DuplexMode in Config register */
-               if (pPrt->PLinkMode == SK_LMODE_FULL) {
-                       Ctrl1 |= PHY_CT_DUP_MD;
-               }
-
-               /* Determine Master/Slave manually if not already done */
-               if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
-                       Ctrl2 |= PHY_L_1000C_MSE;       /* set it to Slave */
-               }
-
-               /*
-                * Do NOT enable Auto-negotiation here. This would hold
-                * the link down because no IDLES are transmitted
-                */
-       }
-       else {
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("InitPhyLone: with auto-negotiation Port %d\n", Port));
-               /* Set Auto-negotiation advertisement */
-
-               /* Set Full/half duplex capabilities */
-               switch (pPrt->PLinkMode) {
-               case SK_LMODE_AUTOHALF:
-                       Ctrl2 |= PHY_L_1000C_AHD;
-                       break;
-               case SK_LMODE_AUTOFULL:
-                       Ctrl2 |= PHY_L_1000C_AFD;
-                       break;
-               case SK_LMODE_AUTOBOTH:
-                       Ctrl2 |= PHY_L_1000C_AFD | PHY_L_1000C_AHD;
-                       break;
-               default:
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
-                               SKERR_HWI_E015MSG);
-               }
-
-               /* Set Flow-control capabilities */
-               switch (pPrt->PFlowCtrlMode) {
-               case SK_FLOW_MODE_NONE:
-                       Ctrl3 |= PHY_L_P_NO_PAUSE;
-                       break;
-               case SK_FLOW_MODE_LOC_SEND:
-                       Ctrl3 |= PHY_L_P_ASYM_MD;
-                       break;
-               case SK_FLOW_MODE_SYMMETRIC:
-                       Ctrl3 |= PHY_L_P_SYM_MD;
-                       break;
-               case SK_FLOW_MODE_SYM_OR_REM:
-                       Ctrl3 |= PHY_L_P_BOTH_MD;
-                       break;
-               default:
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
-                               SKERR_HWI_E016MSG);
-               }
-
-               /* Restart Auto-negotiation */
-               Ctrl1 = PHY_CT_ANE | PHY_CT_RE_CFG;
-       }
-       
-       /* Write 1000Base-T Control Register */
-       SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_1000T_CTRL, Ctrl2);
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("1000B-T Ctrl Reg=0x%04X\n", Ctrl2));
-       
-       /* Write AutoNeg Advertisement Register */
-       SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_AUNE_ADV, Ctrl3);
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("Auto-Neg.Adv.Reg=0x%04X\n", Ctrl3));
-
-       if (DoLoop) {
-               /* Set the Phy Loopback bit, too */
-               Ctrl1 |= PHY_CT_LOOP;
-       }
-
-       /* Write to the Phy control register */
-       SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_CTRL, Ctrl1);
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("PHY Control Reg=0x%04X\n", Ctrl1));
-}      /* SkXmInitPhyLone */
-
-
-/******************************************************************************
- *
- *     SkXmInitPhyNat() - Initialize the National Phy registers
- *
- * Description:        initializes all the National Phy registers
- *
- * Note:
- *
- * Returns:
- *     nothing
- */
-static void SkXmInitPhyNat(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-SK_BOOL        DoLoop)         /* Should a Phy LoopBack be set-up? */
-{
-/* todo: National */
-}      /* SkXmInitPhyNat */
-#endif /* OTHER_PHY */
-
-
-/******************************************************************************
- *
- *     SkMacInitPhy() - Initialize the PHY registers
- *
- * Description:        calls the Init PHY routines dep. on board type
- *
- * Note:
- *
- * Returns:
- *     nothing
- */
-void SkMacInitPhy(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-SK_BOOL        DoLoop)         /* Should a Phy LoopBack be set-up? */
-{
-       SK_GEPORT       *pPrt;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-#ifdef GENESIS
-       if (pAC->GIni.GIGenesis) {
-               
-               switch (pPrt->PhyType) {
-               case SK_PHY_XMAC:
-                       SkXmInitPhyXmac(pAC, IoC, Port, DoLoop);
-                       break;
-               case SK_PHY_BCOM:
-                       SkXmInitPhyBcom(pAC, IoC, Port, DoLoop);
-                       break;
-#ifdef OTHER_PHY
-               case SK_PHY_LONE:
-                       SkXmInitPhyLone(pAC, IoC, Port, DoLoop);
-                       break;
-               case SK_PHY_NAT:
-                       SkXmInitPhyNat(pAC, IoC, Port, DoLoop);
-                       break;
-#endif /* OTHER_PHY */
-               }
-       }
-#endif /* GENESIS */
-       
-#ifdef YUKON
-       if (pAC->GIni.GIYukon) {
-               
-               SkGmInitPhyMarv(pAC, IoC, Port, DoLoop);
-       }
-#endif /* YUKON */
-
-}      /* SkMacInitPhy */
-
-
-#ifdef GENESIS
-/******************************************************************************
- *
- *     SkXmAutoNegDoneXmac() - Auto-negotiation handling
- *
- * Description:
- *     This function handles the auto-negotiation if the Done bit is set.
- *
- * Returns:
- *     SK_AND_OK       o.k.
- *     SK_AND_DUP_CAP  Duplex capability error happened
- *     SK_AND_OTHER    Other error happened
- */
-static int SkXmAutoNegDoneXmac(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;
-       SK_U16          ResAb;          /* Resolved Ability */
-       SK_U16          LPAb;           /* Link Partner Ability */
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("AutoNegDoneXmac, Port %d\n", Port));
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       /* Get PHY parameters */
-       SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_LP, &LPAb);
-       SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_RES_ABI, &ResAb);
-
-       if ((LPAb & PHY_X_AN_RFB) != 0) {
-               /* At least one of the remote fault bit is set */
-               /* Error */
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("AutoNegFail: Remote fault bit set Port %d\n", Port));
-               pPrt->PAutoNegFail = SK_TRUE;
-               return(SK_AND_OTHER);
-       }
-
-       /* Check Duplex mismatch */
-       if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_FD) {
-               pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
-       }
-       else if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_HD) {
-               pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
-       }
-       else {
-               /* Error */
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("AutoNegFail: Duplex mode mismatch Port %d\n", Port));
-               pPrt->PAutoNegFail = SK_TRUE;
-               return(SK_AND_DUP_CAP);
-       }
-
-       /* Check PAUSE mismatch */
-       /* We are NOT using chapter 4.23 of the Xaqti manual */
-       /* We are using IEEE 802.3z/D5.0 Table 37-4 */
-       if ((pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYMMETRIC ||
-            pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) &&
-           (LPAb & PHY_X_P_SYM_MD) != 0) {
-               /* Symmetric PAUSE */
-               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
-       }
-       else if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM &&
-                  (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_ASYM_MD) {
-               /* Enable PAUSE receive, disable PAUSE transmit */
-               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
-       }
-       else if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_LOC_SEND &&
-                  (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_BOTH_MD) {
-               /* Disable PAUSE receive, enable PAUSE transmit */
-               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
-       }
-       else {
-               /* PAUSE mismatch -> no PAUSE */
-               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
-       }
-       pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
-
-       return(SK_AND_OK);
-}      /* SkXmAutoNegDoneXmac */
-
-
-/******************************************************************************
- *
- *     SkXmAutoNegDoneBcom() - Auto-negotiation handling
- *
- * Description:
- *     This function handles the auto-negotiation if the Done bit is set.
- *
- * Returns:
- *     SK_AND_OK       o.k.
- *     SK_AND_DUP_CAP  Duplex capability error happened
- *     SK_AND_OTHER    Other error happened
- */
-static int SkXmAutoNegDoneBcom(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;
-       SK_U16          LPAb;           /* Link Partner Ability */
-       SK_U16          AuxStat;        /* Auxiliary Status */
-
-#ifdef TEST_ONLY
-01-Sep-2000 RA;:;:
-       SK_U16          ResAb;          /* Resolved Ability */
-#endif /* 0 */
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("AutoNegDoneBcom, Port %d\n", Port));
-       pPrt = &pAC->GIni.GP[Port];
-
-       /* Get PHY parameters */
-       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &LPAb);
-#ifdef TEST_ONLY
-01-Sep-2000 RA;:;:
-       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb);
-#endif /* 0 */
-       
-       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &AuxStat);
-
-       if ((LPAb & PHY_B_AN_RF) != 0) {
-               /* Remote fault bit is set: Error */
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("AutoNegFail: Remote fault bit set Port %d\n", Port));
-               pPrt->PAutoNegFail = SK_TRUE;
-               return(SK_AND_OTHER);
-       }
-
-       /* Check Duplex mismatch */
-       if ((AuxStat & PHY_B_AS_AN_RES_MSK) == PHY_B_RES_1000FD) {
-               pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
-       }
-       else if ((AuxStat & PHY_B_AS_AN_RES_MSK) == PHY_B_RES_1000HD) {
-               pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
-       }
-       else {
-               /* Error */
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("AutoNegFail: Duplex mode mismatch Port %d\n", Port));
-               pPrt->PAutoNegFail = SK_TRUE;
-               return(SK_AND_DUP_CAP);
-       }
-       
-#ifdef TEST_ONLY
-01-Sep-2000 RA;:;:
-       /* Check Master/Slave resolution */
-       if ((ResAb & PHY_B_1000S_MSF) != 0) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("Master/Slave Fault Port %d\n", Port));
-               pPrt->PAutoNegFail = SK_TRUE;
-               pPrt->PMSStatus = SK_MS_STAT_FAULT;
-               return(SK_AND_OTHER);
-       }
-       
-       pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
-               SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE;
-#endif /* 0 */
-
-       /* Check PAUSE mismatch ??? */
-       /* We are using IEEE 802.3z/D5.0 Table 37-4 */
-       if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PAUSE_MSK) {
-               /* Symmetric PAUSE */
-               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
-       }
-       else if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PRR) {
-               /* Enable PAUSE receive, disable PAUSE transmit */
-               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
-       }
-       else if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PRT) {
-               /* Disable PAUSE receive, enable PAUSE transmit */
-               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
-       }
-       else {
-               /* PAUSE mismatch -> no PAUSE */
-               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
-       }
-       pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
-
-       return(SK_AND_OK);
-}      /* SkXmAutoNegDoneBcom */
-#endif /* GENESIS */
-
-
-#ifdef YUKON
-/******************************************************************************
- *
- *     SkGmAutoNegDoneMarv() - Auto-negotiation handling
- *
- * Description:
- *     This function handles the auto-negotiation if the Done bit is set.
- *
- * Returns:
- *     SK_AND_OK       o.k.
- *     SK_AND_DUP_CAP  Duplex capability error happened
- *     SK_AND_OTHER    Other error happened
- */
-static int SkGmAutoNegDoneMarv(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;
-       SK_U16          LPAb;           /* Link Partner Ability */
-       SK_U16          ResAb;          /* Resolved Ability */
-       SK_U16          AuxStat;        /* Auxiliary Status */
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("AutoNegDoneMarv, Port %d\n", Port));
-       pPrt = &pAC->GIni.GP[Port];
-
-       /* Get PHY parameters */
-       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_LP, &LPAb);
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("Link P.Abil.=0x%04X\n", LPAb));
-       
-       if ((LPAb & PHY_M_AN_RF) != 0) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("AutoNegFail: Remote fault bit set Port %d\n", Port));
-               pPrt->PAutoNegFail = SK_TRUE;
-               return(SK_AND_OTHER);
-       }
-
-       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb);
-       
-       /* Check Master/Slave resolution */
-       if ((ResAb & PHY_B_1000S_MSF) != 0) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("Master/Slave Fault Port %d\n", Port));
-               pPrt->PAutoNegFail = SK_TRUE;
-               pPrt->PMSStatus = SK_MS_STAT_FAULT;
-               return(SK_AND_OTHER);
-       }
-       
-       pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
-               (SK_U8)SK_MS_STAT_MASTER : (SK_U8)SK_MS_STAT_SLAVE;
-       
-       /* Read PHY Specific Status */
-       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &AuxStat);
-       
-       /* Check Speed & Duplex resolved */
-       if ((AuxStat & PHY_M_PS_SPDUP_RES) == 0) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("AutoNegFail: Speed & Duplex not resolved, Port %d\n", Port));
-               pPrt->PAutoNegFail = SK_TRUE;
-               pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
-               return(SK_AND_DUP_CAP);
-       }
-       
-       if ((AuxStat & PHY_M_PS_FULL_DUP) != 0) {
-               pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
-       }
-       else {
-               pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
-       }
-       
-       /* Check PAUSE mismatch ??? */
-       /* We are using IEEE 802.3z/D5.0 Table 37-4 */
-       if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_PAUSE_MSK) {
-               /* Symmetric PAUSE */
-               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
-       }
-       else if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_RX_P_EN) {
-               /* Enable PAUSE receive, disable PAUSE transmit */
-               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
-       }
-       else if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_TX_P_EN) {
-               /* Disable PAUSE receive, enable PAUSE transmit */
-               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
-       }
-       else {
-               /* PAUSE mismatch -> no PAUSE */
-               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
-       }
-       
-       /* set used link speed */
-       switch ((unsigned)(AuxStat & PHY_M_PS_SPEED_MSK)) {
-       case (unsigned)PHY_M_PS_SPEED_1000:
-               pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
-               break;
-       case PHY_M_PS_SPEED_100:
-               pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_100MBPS;
-               break;
-       default:
-               pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_10MBPS;
-       }
-
-       return(SK_AND_OK);
-}      /* SkGmAutoNegDoneMarv */
-#endif /* YUKON */
-
-
-#ifdef OTHER_PHY
-/******************************************************************************
- *
- *     SkXmAutoNegDoneLone() - Auto-negotiation handling
- *
- * Description:
- *     This function handles the auto-negotiation if the Done bit is set.
- *
- * Returns:
- *     SK_AND_OK       o.k.
- *     SK_AND_DUP_CAP  Duplex capability error happened
- *     SK_AND_OTHER    Other error happened
- */
-static int SkXmAutoNegDoneLone(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;
-       SK_U16          ResAb;          /* Resolved Ability */
-       SK_U16          LPAb;           /* Link Partner Ability */
-       SK_U16          QuickStat;      /* Auxiliary Status */
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("AutoNegDoneLone, Port %d\n", Port));
-       pPrt = &pAC->GIni.GP[Port];
-
-       /* Get PHY parameters */
-       SkXmPhyRead(pAC, IoC, Port, PHY_LONE_AUNE_LP, &LPAb);
-       SkXmPhyRead(pAC, IoC, Port, PHY_LONE_1000T_STAT, &ResAb);
-       SkXmPhyRead(pAC, IoC, Port, PHY_LONE_Q_STAT, &QuickStat);
-
-       if ((LPAb & PHY_L_AN_RF) != 0) {
-               /* Remote fault bit is set */
-               /* Error */
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("AutoNegFail: Remote fault bit set Port %d\n", Port));
-               pPrt->PAutoNegFail = SK_TRUE;
-               return(SK_AND_OTHER);
-       }
-
-       /* Check Duplex mismatch */
-       if ((QuickStat & PHY_L_QS_DUP_MOD) != 0) {
-               pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
-       }
-       else {
-               pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
-       }
-       
-       /* Check Master/Slave resolution */
-       if ((ResAb & PHY_L_1000S_MSF) != 0) {
-               /* Error */
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("Master/Slave Fault Port %d\n", Port));
-               pPrt->PAutoNegFail = SK_TRUE;
-               pPrt->PMSStatus = SK_MS_STAT_FAULT;
-               return(SK_AND_OTHER);
-       }
-       else if (ResAb & PHY_L_1000S_MSR) {
-               pPrt->PMSStatus = SK_MS_STAT_MASTER;
-       }
-       else {
-               pPrt->PMSStatus = SK_MS_STAT_SLAVE;
-       }
-
-       /* Check PAUSE mismatch */
-       /* We are using IEEE 802.3z/D5.0 Table 37-4 */
-       /* we must manually resolve the abilities here */
-       pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
-       
-       switch (pPrt->PFlowCtrlMode) {
-       case SK_FLOW_MODE_NONE:
-               /* default */
-               break;
-       case SK_FLOW_MODE_LOC_SEND:
-               if ((QuickStat & (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) ==
-                       (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) {
-                       /* Disable PAUSE receive, enable PAUSE transmit */
-                       pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
-               }
-               break;
-       case SK_FLOW_MODE_SYMMETRIC:
-               if ((QuickStat & PHY_L_QS_PAUSE) != 0) {
-                       /* Symmetric PAUSE */
-                       pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
-               }
-               break;
-       case SK_FLOW_MODE_SYM_OR_REM:
-               if ((QuickStat & (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) ==
-                       PHY_L_QS_AS_PAUSE) {
-                       /* Enable PAUSE receive, disable PAUSE transmit */
-                       pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
-               }
-               else if ((QuickStat & PHY_L_QS_PAUSE) != 0) {
-                       /* Symmetric PAUSE */
-                       pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
-               }
-               break;
-       default:
-               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
-                       SKERR_HWI_E016MSG);
-       }
-       
-       return(SK_AND_OK);
-}      /* SkXmAutoNegDoneLone */
-
-
-/******************************************************************************
- *
- *     SkXmAutoNegDoneNat() - Auto-negotiation handling
- *
- * Description:
- *     This function handles the auto-negotiation if the Done bit is set.
- *
- * Returns:
- *     SK_AND_OK       o.k.
- *     SK_AND_DUP_CAP  Duplex capability error happened
- *     SK_AND_OTHER    Other error happened
- */
-static int SkXmAutoNegDoneNat(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-/* todo: National */
-       return(SK_AND_OK);
-}      /* SkXmAutoNegDoneNat */
-#endif /* OTHER_PHY */
-
-
-/******************************************************************************
- *
- *     SkMacAutoNegDone() - Auto-negotiation handling
- *
- * Description:        calls the auto-negotiation done routines dep. on board type
- *
- * Returns:
- *     SK_AND_OK       o.k.
- *     SK_AND_DUP_CAP  Duplex capability error happened
- *     SK_AND_OTHER    Other error happened
- */
-int    SkMacAutoNegDone(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;
-       int     Rtv;
-
-       Rtv = SK_AND_OK;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-#ifdef GENESIS
-       if (pAC->GIni.GIGenesis) {
-               
-               switch (pPrt->PhyType) {
-               
-               case SK_PHY_XMAC:
-                       Rtv = SkXmAutoNegDoneXmac(pAC, IoC, Port);
-                       break;
-               case SK_PHY_BCOM:
-                       Rtv = SkXmAutoNegDoneBcom(pAC, IoC, Port);
-                       break;
-#ifdef OTHER_PHY
-               case SK_PHY_LONE:
-                       Rtv = SkXmAutoNegDoneLone(pAC, IoC, Port);
-                       break;
-               case SK_PHY_NAT:
-                       Rtv = SkXmAutoNegDoneNat(pAC, IoC, Port);
-                       break;
-#endif /* OTHER_PHY */
-               default:
-                       return(SK_AND_OTHER);
-               }
-       }
-#endif /* GENESIS */
-       
-#ifdef YUKON
-       if (pAC->GIni.GIYukon) {
-               
-               Rtv = SkGmAutoNegDoneMarv(pAC, IoC, Port);
-       }
-#endif /* YUKON */
-       
-       if (Rtv != SK_AND_OK) {
-               return(Rtv);
-       }
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("AutoNeg done Port %d\n", Port));
-       
-       /* We checked everything and may now enable the link */
-       pPrt->PAutoNegFail = SK_FALSE;
-
-       SkMacRxTxEnable(pAC, IoC, Port);
-       
-       return(SK_AND_OK);
-}      /* SkMacAutoNegDone */
-
-
-/******************************************************************************
- *
- *     SkMacRxTxEnable() - Enable Rx/Tx activity if port is up
- *
- * Description:        enables Rx/Tx dep. on board type
- *
- * Returns:
- *     0       o.k.
- *     != 0    Error happened
- */
-int SkMacRxTxEnable(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;
-       SK_U16          Reg;            /* 16-bit register value */
-       SK_U16          IntMask;        /* MAC interrupt mask */
-#ifdef GENESIS
-       SK_U16          SWord;
-#endif
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       if (!pPrt->PHWLinkUp) {
-               /* The Hardware link is NOT up */
-               return(0);
-       }
-
-       if ((pPrt->PLinkMode == SK_LMODE_AUTOHALF ||
-            pPrt->PLinkMode == SK_LMODE_AUTOFULL ||
-            pPrt->PLinkMode == SK_LMODE_AUTOBOTH) &&
-            pPrt->PAutoNegFail) {
-               /* Auto-negotiation is not done or failed */
-               return(0);
-       }
-
-#ifdef GENESIS
-       if (pAC->GIni.GIGenesis) {
-               /* set Duplex Mode and Pause Mode */
-               SkXmInitDupMd(pAC, IoC, Port);
-               
-               SkXmInitPauseMd(pAC, IoC, Port);
-       
-               /*
-                * Initialize the Interrupt Mask Register. Default IRQs are...
-                *      - Link Asynchronous Event
-                *      - Link Partner requests config
-                *      - Auto Negotiation Done
-                *      - Rx Counter Event Overflow
-                *      - Tx Counter Event Overflow
-                *      - Transmit FIFO Underrun
-                */
-               IntMask = XM_DEF_MSK;
-
-#ifdef DEBUG
-               /* add IRQ for Receive FIFO Overflow */
-               IntMask &= ~XM_IS_RXF_OV;
-#endif /* DEBUG */
-               
-               if (pPrt->PhyType != SK_PHY_XMAC) {
-                       /* disable GP0 interrupt bit */
-                       IntMask |= XM_IS_INP_ASS;
-               }
-               XM_OUT16(IoC, Port, XM_IMSK, IntMask);
-       
-               /* get MMU Command Reg. */
-               XM_IN16(IoC, Port, XM_MMU_CMD, &Reg);
-               
-               if (pPrt->PhyType != SK_PHY_XMAC &&
-                       (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL ||
-                        pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL)) {
-                       /* set to Full Duplex */
-                       Reg |= XM_MMU_GMII_FD;
-               }
-               
-               switch (pPrt->PhyType) {
-               case SK_PHY_BCOM:
-                       /*
-                        * Workaround BCOM Errata (#10523) for all BCom Phys
-                        * Enable Power Management after link up
-                        */
-                       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &SWord);
-                       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL,
-                               (SK_U16)(SWord & ~PHY_B_AC_DIS_PM));
-            SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK,
-                               (SK_U16)PHY_B_DEF_MSK);
-                       break;
-#ifdef OTHER_PHY
-               case SK_PHY_LONE:
-                       SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_INT_ENAB, PHY_L_DEF_MSK);
-                       break;
-               case SK_PHY_NAT:
-                       /* todo National:
-                       SkXmPhyWrite(pAC, IoC, Port, PHY_NAT_INT_MASK, PHY_N_DEF_MSK); */
-                       /* no interrupts possible from National ??? */
-                       break;
-#endif /* OTHER_PHY */
-               }
-               
-               /* enable Rx/Tx */
-               XM_OUT16(IoC, Port, XM_MMU_CMD, Reg | XM_MMU_ENA_RX | XM_MMU_ENA_TX);
-       }
-#endif /* GENESIS */
-       
-#ifdef YUKON
-       if (pAC->GIni.GIYukon) {
-               /*
-                * Initialize the Interrupt Mask Register. Default IRQs are...
-                *      - Rx Counter Event Overflow
-                *      - Tx Counter Event Overflow
-                *      - Transmit FIFO Underrun
-                */
-               IntMask = GMAC_DEF_MSK;
-
-#ifdef DEBUG
-               /* add IRQ for Receive FIFO Overrun */
-               IntMask |= GM_IS_RX_FF_OR;
-#endif /* DEBUG */
-               
-               SK_OUT8(IoC, GMAC_IRQ_MSK, (SK_U8)IntMask);
-               
-               /* get General Purpose Control */
-               GM_IN16(IoC, Port, GM_GP_CTRL, &Reg);
-               
-               if (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL ||
-                       pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) {
-                       /* set to Full Duplex */
-                       Reg |= GM_GPCR_DUP_FULL;
-               }
-               
-               /* enable Rx/Tx */
-        GM_OUT16(IoC, Port, GM_GP_CTRL, (SK_U16)(Reg | GM_GPCR_RX_ENA |
-                       GM_GPCR_TX_ENA));
-
-#ifndef VCPU
-               /* Enable all PHY interrupts */
-        SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK,
-                       (SK_U16)PHY_M_DEF_MSK);
-#endif /* VCPU */
-       }
-#endif /* YUKON */
-                                       
-       return(0);
-
-}      /* SkMacRxTxEnable */
-
-
-/******************************************************************************
- *
- *     SkMacRxTxDisable() - Disable Receiver and Transmitter
- *
- * Description:        disables Rx/Tx dep. on board type
- *
- * Returns: N/A
- */
-void SkMacRxTxDisable(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-       SK_U16  Word;
-
-#ifdef GENESIS
-       if (pAC->GIni.GIGenesis) {
-               
-               XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
-               
-               XM_OUT16(IoC, Port, XM_MMU_CMD, Word & ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX));
-       
-               /* dummy read to ensure writing */
-               XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
-       }
-#endif /* GENESIS */
-       
-#ifdef YUKON
-       if (pAC->GIni.GIYukon) {
-               
-               GM_IN16(IoC, Port, GM_GP_CTRL, &Word);
-
-        GM_OUT16(IoC, Port, GM_GP_CTRL, (SK_U16)(Word & ~(GM_GPCR_RX_ENA |
-                       GM_GPCR_TX_ENA)));
-
-               /* dummy read to ensure writing */
-               GM_IN16(IoC, Port, GM_GP_CTRL, &Word);
-       }
-#endif /* YUKON */
-
-}      /* SkMacRxTxDisable */
-
-
-/******************************************************************************
- *
- *     SkMacIrqDisable() - Disable IRQ from MAC
- *
- * Description:        sets the IRQ-mask to disable IRQ dep. on board type
- *
- * Returns: N/A
- */
-void SkMacIrqDisable(
-SK_AC  *pAC,           /* Adapter Context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;
-#ifdef GENESIS
-       SK_U16          Word;
-#endif
-
-       pPrt = &pAC->GIni.GP[Port];
-
-#ifdef GENESIS
-       if (pAC->GIni.GIGenesis) {
-               
-               /* disable all XMAC IRQs */
-               XM_OUT16(IoC, Port, XM_IMSK, 0xffff);   
-               
-               /* Disable all PHY interrupts */
-               switch (pPrt->PhyType) {
-                       case SK_PHY_BCOM:
-                               /* Make sure that PHY is initialized */
-                               if (pPrt->PState != SK_PRT_RESET) {
-                                       /* NOT allowed if BCOM is in RESET state */
-                                       /* Workaround BCOM Errata (#10523) all BCom */
-                                       /* Disable Power Management if link is down */
-                                       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Word);
-                                       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL,
-                                               (SK_U16)(Word | PHY_B_AC_DIS_PM));
-                                       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK, 0xffff);
-                               }
-                               break;
-#ifdef OTHER_PHY
-                       case SK_PHY_LONE:
-                               SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_INT_ENAB, 0);
-                               break;
-                       case SK_PHY_NAT:
-                               /* todo: National
-                               SkXmPhyWrite(pAC, IoC, Port, PHY_NAT_INT_MASK, 0xffff); */
-                               break;
-#endif /* OTHER_PHY */
-               }
-       }
-#endif /* GENESIS */
-       
-#ifdef YUKON
-       if (pAC->GIni.GIYukon) {
-               /* disable all GMAC IRQs */
-               SK_OUT8(IoC, GMAC_IRQ_MSK, 0);
-               
-#ifndef VCPU
-               /* Disable all PHY interrupts */
-               SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, 0);
-#endif /* VCPU */
-       }
-#endif /* YUKON */
-
-}      /* SkMacIrqDisable */
-
-
-#ifdef SK_DIAG
-/******************************************************************************
- *
- *     SkXmSendCont() - Enable / Disable Send Continuous Mode
- *
- * Description:        enable / disable Send Continuous Mode on XMAC
- *
- * Returns:
- *     nothing
- */
-void SkXmSendCont(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* IO context */
-int            Port,   /* Port Index (MAC_1 + n) */
-SK_BOOL        Enable) /* Enable / Disable */
-{
-       SK_U32  MdReg;
-
-       XM_IN32(IoC, Port, XM_MODE, &MdReg);
-
-       if (Enable) {
-               MdReg |= XM_MD_TX_CONT;
-       }
-       else {
-               MdReg &= ~XM_MD_TX_CONT;
-       }
-       /* setup Mode Register */
-       XM_OUT32(IoC, Port, XM_MODE, MdReg);
-
-}      /* SkXmSendCont */
-
-
-/******************************************************************************
- *
- *     SkMacTimeStamp() - Enable / Disable Time Stamp
- *
- * Description:        enable / disable Time Stamp generation for Rx packets
- *
- * Returns:
- *     nothing
- */
-void SkMacTimeStamp(
-SK_AC  *pAC,   /* adapter context */
-SK_IOC IoC,    /* IO context */
-int            Port,   /* Port Index (MAC_1 + n) */
-SK_BOOL        Enable) /* Enable / Disable */
-{
-       SK_U32  MdReg;
-       SK_U8   TimeCtrl;
-
-       if (pAC->GIni.GIGenesis) {
-
-               XM_IN32(IoC, Port, XM_MODE, &MdReg);
-
-               if (Enable) {
-                       MdReg |= XM_MD_ATS;
-               }
-               else {
-                       MdReg &= ~XM_MD_ATS;
-               }
-               /* setup Mode Register */
-               XM_OUT32(IoC, Port, XM_MODE, MdReg);
-       }
-       else {
-               if (Enable) {
-                       TimeCtrl = GMT_ST_START | GMT_ST_CLR_IRQ;
-               }
-               else {
-                       TimeCtrl = GMT_ST_STOP | GMT_ST_CLR_IRQ;
-               }
-               /* Start/Stop Time Stamp Timer */
-               SK_OUT8(IoC, GMAC_TI_ST_CTRL, TimeCtrl);
-       }
-
-}      /* SkMacTimeStamp*/
-
-#else /* !SK_DIAG */
-
-#ifdef GENESIS
-/******************************************************************************
- *
- *     SkXmAutoNegLipaXmac() - Decides whether Link Partner could do auto-neg
- *
- *     This function analyses the Interrupt status word. If any of the
- *     Auto-negotiating interrupt bits are set, the PLipaAutoNeg variable
- *     is set true.
- */
-void SkXmAutoNegLipaXmac(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-SK_U16 IStatus)        /* Interrupt Status word to analyse */
-{
-       SK_GEPORT       *pPrt;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO &&
-               (IStatus & (XM_IS_LIPA_RC | XM_IS_RX_PAGE | XM_IS_AND)) != 0) {
-
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("AutoNegLipa: AutoNeg detected on Port %d, IStatus=0x%04X\n",
-                       Port, IStatus));
-               pPrt->PLipaAutoNeg = SK_LIPA_AUTO;
-       }
-}      /* SkXmAutoNegLipaXmac */
-#endif /* GENESIS */
-
-
-/******************************************************************************
- *
- *     SkMacAutoNegLipaPhy() - Decides whether Link Partner could do auto-neg
- *
- *     This function analyses the PHY status word.
- *  If any of the Auto-negotiating bits are set, the PLipaAutoNeg variable
- *     is set true.
- */
-void SkMacAutoNegLipaPhy(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-SK_U16 PhyStat)        /* PHY Status word to analyse */
-{
-       SK_GEPORT       *pPrt;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO &&
-               (PhyStat & PHY_ST_AN_OVER) != 0) {
-
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("AutoNegLipa: AutoNeg detected on Port %d, PhyStat=0x%04X\n",
-                       Port, PhyStat));
-               pPrt->PLipaAutoNeg = SK_LIPA_AUTO;
-       }
-}      /* SkMacAutoNegLipaPhy */
-
-
-#ifdef GENESIS
-/******************************************************************************
- *
- *     SkXmIrq() - Interrupt Service Routine
- *
- * Description:        services an Interrupt Request of the XMAC
- *
- * Note:
- *     With an external PHY, some interrupt bits are not meaningfull any more:
- *     - LinkAsyncEvent (bit #14)              XM_IS_LNK_AE
- *     - LinkPartnerReqConfig (bit #10)        XM_IS_LIPA_RC
- *     - Page Received (bit #9)                XM_IS_RX_PAGE
- *     - NextPageLoadedForXmt (bit #8)         XM_IS_TX_PAGE
- *     - AutoNegDone (bit #7)                  XM_IS_AND
- *     Also probably not valid any more is the GP0 input bit:
- *     - GPRegisterBit0set                     XM_IS_INP_ASS
- *
- * Returns:
- *     nothing
- */
-static void SkXmIrq(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;
-       SK_EVPARA       Para;
-       SK_U16          IStatus;        /* Interrupt status read from the XMAC */
-       SK_U16          IStatus2;
-#ifdef SK_SLIM
-    SK_U64      OverflowStatus;
-#endif 
-
-       pPrt = &pAC->GIni.GP[Port];
-       
-       XM_IN16(IoC, Port, XM_ISRC, &IStatus);
-       
-       /* LinkPartner Auto-negable? */
-       if (pPrt->PhyType == SK_PHY_XMAC) {
-               SkXmAutoNegLipaXmac(pAC, IoC, Port, IStatus);
-       }
-       else {
-               /* mask bits that are not used with ext. PHY */
-               IStatus &= ~(XM_IS_LNK_AE | XM_IS_LIPA_RC |
-                       XM_IS_RX_PAGE | XM_IS_TX_PAGE |
-                       XM_IS_AND | XM_IS_INP_ASS);
-       }
-       
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-               ("XmacIrq Port %d Isr 0x%04X\n", Port, IStatus));
-
-       if (!pPrt->PHWLinkUp) {
-               /* Spurious XMAC interrupt */
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-                       ("SkXmIrq: spurious interrupt on Port %d\n", Port));
-               return;
-       }
-
-       if ((IStatus & XM_IS_INP_ASS) != 0) {
-               /* Reread ISR Register if link is not in sync */
-               XM_IN16(IoC, Port, XM_ISRC, &IStatus2);
-
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-                       ("SkXmIrq: Link async. Double check Port %d 0x%04X 0x%04X\n",
-                        Port, IStatus, IStatus2));
-               IStatus &= ~XM_IS_INP_ASS;
-               IStatus |= IStatus2;
-       }
-
-       if ((IStatus & XM_IS_LNK_AE) != 0) {
-               /* not used, GP0 is used instead */
-       }
-
-       if ((IStatus & XM_IS_TX_ABORT) != 0) {
-               /* not used */
-       }
-
-       if ((IStatus & XM_IS_FRC_INT) != 0) {
-               /* not used, use ASIC IRQ instead if needed */
-       }
-
-       if ((IStatus & (XM_IS_INP_ASS | XM_IS_LIPA_RC | XM_IS_RX_PAGE)) != 0) {
-               SkHWLinkDown(pAC, IoC, Port);
-
-               /* Signal to RLMT */
-               Para.Para32[0] = (SK_U32)Port;
-               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
-
-               /* Start workaround Errata #2 timer */
-               SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME,
-                       SKGE_HWAC, SK_HWEV_WATIM, Para);
-       }
-
-       if ((IStatus & XM_IS_RX_PAGE) != 0) {
-               /* not used */
-       }
-
-       if ((IStatus & XM_IS_TX_PAGE) != 0) {
-               /* not used */
-       }
-
-       if ((IStatus & XM_IS_AND) != 0) {
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-                       ("SkXmIrq: AND on link that is up Port %d\n", Port));
-       }
-
-       if ((IStatus & XM_IS_TSC_OV) != 0) {
-               /* not used */
-       }
-
-       /* Combined Tx & Rx Counter Overflow SIRQ Event */
-       if ((IStatus & (XM_IS_RXC_OV | XM_IS_TXC_OV)) != 0) {
-#ifdef SK_SLIM
-               SkXmOverflowStatus(pAC, IoC, Port, IStatus, &OverflowStatus);
-#else
-               Para.Para32[0] = (SK_U32)Port;
-               Para.Para32[1] = (SK_U32)IStatus;
-               SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_SIRQ_OVERFLOW, Para);
-#endif /* SK_SLIM */
-       }
-
-       if ((IStatus & XM_IS_RXF_OV) != 0) {
-               /* normal situation -> no effect */
-#ifdef DEBUG
-               pPrt->PRxOverCnt++;
-#endif /* DEBUG */
-       }
-
-       if ((IStatus & XM_IS_TXF_UR) != 0) {
-               /* may NOT happen -> error log */
-               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E020, SKERR_SIRQ_E020MSG);
-       }
-
-       if ((IStatus & XM_IS_TX_COMP) != 0) {
-               /* not served here */
-       }
-
-       if ((IStatus & XM_IS_RX_COMP) != 0) {
-               /* not served here */
-       }
-}      /* SkXmIrq */
-#endif /* GENESIS */
-
-
-#ifdef YUKON
-/******************************************************************************
- *
- *     SkGmIrq() - Interrupt Service Routine
- *
- * Description:        services an Interrupt Request of the GMAC
- *
- * Note:
- *
- * Returns:
- *     nothing
- */
-static void SkGmIrq(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;
-       SK_U8           IStatus;        /* Interrupt status */
-#ifdef SK_SLIM
-    SK_U64      OverflowStatus;
-#else
-       SK_EVPARA       Para;
-#endif 
-
-       pPrt = &pAC->GIni.GP[Port];
-       
-       SK_IN8(IoC, GMAC_IRQ_SRC, &IStatus);
-       
-#ifdef XXX
-       /* LinkPartner Auto-negable? */
-       SkMacAutoNegLipaPhy(pAC, IoC, Port, IStatus);
-#endif /* XXX */
-       
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-               ("GmacIrq Port %d Isr 0x%04X\n", Port, IStatus));
-
-       /* Combined Tx & Rx Counter Overflow SIRQ Event */
-       if (IStatus & (GM_IS_RX_CO_OV | GM_IS_TX_CO_OV)) {
-               /* these IRQs will be cleared by reading GMACs register */
-#ifdef SK_SLIM
-        SkGmOverflowStatus(pAC, IoC, Port, IStatus, &OverflowStatus);
-#else
-               Para.Para32[0] = (SK_U32)Port;
-               Para.Para32[1] = (SK_U32)IStatus;
-               SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_SIRQ_OVERFLOW, Para);
-#endif         
-       }
-
-       if (IStatus & GM_IS_RX_FF_OR) {
-               /* clear GMAC Rx FIFO Overrun IRQ */
-               SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_CLI_RX_FO);
-#ifdef DEBUG
-               pPrt->PRxOverCnt++;
-#endif /* DEBUG */
-       }
-
-       if (IStatus & GM_IS_TX_FF_UR) {
-               /* clear GMAC Tx FIFO Underrun IRQ */
-               SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_CLI_TX_FU);
-               /* may NOT happen -> error log */
-               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E020, SKERR_SIRQ_E020MSG);
-       }
-
-       if (IStatus & GM_IS_TX_COMPL) {
-               /* not served here */
-       }
-
-       if (IStatus & GM_IS_RX_COMPL) {
-               /* not served here */
-       }
-}      /* SkGmIrq */
-#endif /* YUKON */
-
-
-/******************************************************************************
- *
- *     SkMacIrq() - Interrupt Service Routine for MAC
- *
- * Description:        calls the Interrupt Service Routine dep. on board type
- *
- * Returns:
- *     nothing
- */
-void SkMacIrq(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port)           /* Port Index (MAC_1 + n) */
-{
-#ifdef GENESIS
-       if (pAC->GIni.GIGenesis) {
-               /* IRQ from XMAC */
-               SkXmIrq(pAC, IoC, Port);
-       }
-#endif /* GENESIS */
-       
-#ifdef YUKON
-       if (pAC->GIni.GIYukon) {
-               /* IRQ from GMAC */
-               SkGmIrq(pAC, IoC, Port);
-       }
-#endif /* YUKON */
-
-}      /* SkMacIrq */
-
-#endif /* !SK_DIAG */
-
-#ifdef GENESIS
-/******************************************************************************
- *
- *     SkXmUpdateStats() - Force the XMAC to output the current statistic
- *
- * Description:
- *     The XMAC holds its statistic internally. To obtain the current
- *     values a command must be sent so that the statistic data will
- *     be written to a predefined memory area on the adapter.
- *
- * Returns:
- *     0:  success
- *     1:  something went wrong
- */
-int SkXmUpdateStats(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-unsigned int Port)     /* Port Index (MAC_1 + n) */
-{
-       SK_GEPORT       *pPrt;
-       SK_U16          StatReg;
-       int                     WaitIndex;
-
-       pPrt = &pAC->GIni.GP[Port];
-       WaitIndex = 0;
-
-       /* Send an update command to XMAC specified */
-       XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_SNP_TXC | XM_SC_SNP_RXC);
-
-       /*
-        * It is an auto-clearing register. If the command bits
-        * went to zero again, the statistics are transferred.
-        * Normally the command should be executed immediately.
-        * But just to be sure we execute a loop.
-        */
-       do {
-
-               XM_IN16(IoC, Port, XM_STAT_CMD, &StatReg);
-               
-               if (++WaitIndex > 10) {
-
-                       SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E021, SKERR_HWI_E021MSG);
-
-                       return(1);
-               }
-       } while ((StatReg & (XM_SC_SNP_TXC | XM_SC_SNP_RXC)) != 0);
-       
-       return(0);
-}      /* SkXmUpdateStats */
-
-
-/******************************************************************************
- *
- *     SkXmMacStatistic() - Get XMAC counter value
- *
- * Description:
- *     Gets the 32bit counter value. Except for the octet counters
- *     the lower 32bit are counted in hardware and the upper 32bit
- *     must be counted in software by monitoring counter overflow interrupts.
- *
- * Returns:
- *     0:  success
- *     1:  something went wrong
- */
-int SkXmMacStatistic(
-SK_AC  *pAC,                   /* adapter context */
-SK_IOC IoC,                    /* IO context */
-unsigned int Port,             /* Port Index (MAC_1 + n) */
-SK_U16 StatAddr,               /* MIB counter base address */
-SK_U32 SK_FAR *pVal)   /* ptr to return statistic value */
-{
-       if ((StatAddr < XM_TXF_OK) || (StatAddr > XM_RXF_MAX_SZ)) {
-               
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E022, SKERR_HWI_E022MSG);
-               
-               return(1);
-       }
-       
-       XM_IN32(IoC, Port, StatAddr, pVal);
-
-       return(0);
-}      /* SkXmMacStatistic */
-
-
-/******************************************************************************
- *
- *     SkXmResetCounter() - Clear MAC statistic counter
- *
- * Description:
- *     Force the XMAC to clear its statistic counter.
- *
- * Returns:
- *     0:  success
- *     1:  something went wrong
- */
-int SkXmResetCounter(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-unsigned int Port)     /* Port Index (MAC_1 + n) */
-{
-       XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_CLR_RXC | XM_SC_CLR_TXC);
-       /* Clear two times according to Errata #3 */
-       XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_CLR_RXC | XM_SC_CLR_TXC);
-
-       return(0);
-}      /* SkXmResetCounter */
-
-
-/******************************************************************************
- *
- *     SkXmOverflowStatus() - Gets the status of counter overflow interrupt
- *
- * Description:
- *     Checks the source causing an counter overflow interrupt. On success the
- *     resulting counter overflow status is written to <pStatus>, whereas the
- *     upper dword stores the XMAC ReceiveCounterEvent register and the lower
- *     dword the XMAC TransmitCounterEvent register.
- *
- * Note:
- *     For XMAC the interrupt source is a self-clearing register, so the source
- *     must be checked only once. SIRQ module does another check to be sure
- *     that no interrupt get lost during process time.
- *
- * Returns:
- *     0:  success
- *     1:  something went wrong
- */
-int SkXmOverflowStatus(
-SK_AC  *pAC,                           /* adapter context */
-SK_IOC IoC,                            /* IO context */
-unsigned int Port,                     /* Port Index (MAC_1 + n) */
-SK_U16 IStatus,                        /* Interupt Status from MAC */
-SK_U64 SK_FAR *pStatus)        /* ptr for return overflow status value */
-{
-       SK_U64  Status; /* Overflow status */
-       SK_U32  RegVal;
-
-       Status = 0;
-
-       if ((IStatus & XM_IS_RXC_OV) != 0) {
-
-               XM_IN32(IoC, Port, XM_RX_CNT_EV, &RegVal);
-               Status |= (SK_U64)RegVal << 32;
-       }
-       
-       if ((IStatus & XM_IS_TXC_OV) != 0) {
-
-               XM_IN32(IoC, Port, XM_TX_CNT_EV, &RegVal);
-               Status |= (SK_U64)RegVal;
-       }
-
-       *pStatus = Status;
-
-       return(0);
-}      /* SkXmOverflowStatus */
-#endif /* GENESIS */
-
-
-#ifdef YUKON
-/******************************************************************************
- *
- *     SkGmUpdateStats() - Force the GMAC to output the current statistic
- *
- * Description:
- *     Empty function for GMAC. Statistic data is accessible in direct way.
- *
- * Returns:
- *     0:  success
- *     1:  something went wrong
- */
-int SkGmUpdateStats(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-unsigned int Port)     /* Port Index (MAC_1 + n) */
-{
-       return(0);
-}
-
-
-/******************************************************************************
- *
- *     SkGmMacStatistic() - Get GMAC counter value
- *
- * Description:
- *     Gets the 32bit counter value. Except for the octet counters
- *     the lower 32bit are counted in hardware and the upper 32bit
- *     must be counted in software by monitoring counter overflow interrupts.
- *
- * Returns:
- *     0:  success
- *     1:  something went wrong
- */
-int SkGmMacStatistic(
-SK_AC  *pAC,                   /* adapter context */
-SK_IOC IoC,                    /* IO context */
-unsigned int Port,             /* Port Index (MAC_1 + n) */
-SK_U16 StatAddr,               /* MIB counter base address */
-SK_U32 SK_FAR *pVal)   /* ptr to return statistic value */
-{
-
-       if ((StatAddr < GM_RXF_UC_OK) || (StatAddr > GM_TXE_FIFO_UR)) {
-               
-               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E022, SKERR_HWI_E022MSG);
-               
-               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-                       ("SkGmMacStat: wrong MIB counter 0x%04X\n", StatAddr));
-               return(1);
-       }
-               
-       GM_IN32(IoC, Port, StatAddr, pVal);
-
-       return(0);
-}      /* SkGmMacStatistic */
-
-
-/******************************************************************************
- *
- *     SkGmResetCounter() - Clear MAC statistic counter
- *
- * Description:
- *     Force GMAC to clear its statistic counter.
- *
- * Returns:
- *     0:  success
- *     1:  something went wrong
- */
-int SkGmResetCounter(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-unsigned int Port)     /* Port Index (MAC_1 + n) */
-{
-       SK_U16  Reg;    /* Phy Address Register */
-       SK_U16  Word;
-       int             i;
-
-       GM_IN16(IoC, Port, GM_PHY_ADDR, &Reg);
-
-       /* set MIB Clear Counter Mode */
-       GM_OUT16(IoC, Port, GM_PHY_ADDR, Reg | GM_PAR_MIB_CLR);
-       
-       /* read all MIB Counters with Clear Mode set */
-       for (i = 0; i < GM_MIB_CNT_SIZE; i++) {
-               /* the reset is performed only when the lower 16 bits are read */
-               GM_IN16(IoC, Port, GM_MIB_CNT_BASE + 8*i, &Word);
-       }
-       
-       /* clear MIB Clear Counter Mode */
-       GM_OUT16(IoC, Port, GM_PHY_ADDR, Reg);
-       
-       return(0);
-}      /* SkGmResetCounter */
-
-
-/******************************************************************************
- *
- *     SkGmOverflowStatus() - Gets the status of counter overflow interrupt
- *
- * Description:
- *     Checks the source causing an counter overflow interrupt. On success the
- *     resulting counter overflow status is written to <pStatus>, whereas the
- *     the following bit coding is used:
- *     63:56 - unused
- *     55:48 - TxRx interrupt register bit7:0
- *     32:47 - Rx interrupt register
- *     31:24 - unused
- *     23:16 - TxRx interrupt register bit15:8
- *     15:0  - Tx interrupt register
- *
- * Returns:
- *     0:  success
- *     1:  something went wrong
- */
-int SkGmOverflowStatus(
-SK_AC  *pAC,                           /* adapter context */
-SK_IOC IoC,                            /* IO context */
-unsigned int Port,                     /* Port Index (MAC_1 + n) */
-SK_U16 IStatus,                        /* Interupt Status from MAC */
-SK_U64 SK_FAR *pStatus)        /* ptr for return overflow status value */
-{
-       SK_U64  Status;         /* Overflow status */
-       SK_U16  RegVal;
-
-       Status = 0;
-
-       if ((IStatus & GM_IS_RX_CO_OV) != 0) {
-               /* this register is self-clearing after read */
-               GM_IN16(IoC, Port, GM_RX_IRQ_SRC, &RegVal);
-               Status |= (SK_U64)RegVal << 32;
-       }
-       
-       if ((IStatus & GM_IS_TX_CO_OV) != 0) {
-               /* this register is self-clearing after read */
-               GM_IN16(IoC, Port, GM_TX_IRQ_SRC, &RegVal);
-               Status |= (SK_U64)RegVal;
-       }
-       
-       /* this register is self-clearing after read */
-       GM_IN16(IoC, Port, GM_TR_IRQ_SRC, &RegVal);
-       /* Rx overflow interrupt register bits (LoByte)*/
-       Status |= (SK_U64)((SK_U8)RegVal) << 48;
-       /* Tx overflow interrupt register bits (HiByte)*/
-       Status |= (SK_U64)(RegVal >> 8) << 16;
-
-       *pStatus = Status;
-
-       return(0);
-}      /* SkGmOverflowStatus */
-
-
-#ifndef SK_SLIM
-/******************************************************************************
- *
- *     SkGmCableDiagStatus() - Starts / Gets status of cable diagnostic test
- *
- * Description:
- *  starts the cable diagnostic test if 'StartTest' is true
- *  gets the results if 'StartTest' is true
- *
- * NOTE:       this test is meaningful only when link is down
- *     
- * Returns:
- *     0:  success
- *     1:      no YUKON copper
- *     2:      test in progress
- */
-int SkGmCableDiagStatus(
-SK_AC  *pAC,           /* adapter context */
-SK_IOC IoC,            /* IO context */
-int            Port,           /* Port Index (MAC_1 + n) */
-SK_BOOL        StartTest)      /* flag for start / get result */
-{
-       int             i;
-       SK_U16  RegVal;
-       SK_GEPORT       *pPrt;
-
-       pPrt = &pAC->GIni.GP[Port];
-
-       if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
-               
-               return(1);
-       }
-
-       if (StartTest) {
-               /* only start the cable test */
-               if ((pPrt->PhyId1 & PHY_I1_REV_MSK) < 4) {
-                       /* apply TDR workaround from Marvell */
-                       SkGmPhyWrite(pAC, IoC, Port, 29, 0x001e);
-                       
-                       SkGmPhyWrite(pAC, IoC, Port, 30, 0xcc00);
-                       SkGmPhyWrite(pAC, IoC, Port, 30, 0xc800);
-                       SkGmPhyWrite(pAC, IoC, Port, 30, 0xc400);
-                       SkGmPhyWrite(pAC, IoC, Port, 30, 0xc000);
-                       SkGmPhyWrite(pAC, IoC, Port, 30, 0xc100);
-               }
-
-               /* set address to 0 for MDI[0] */
-               SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 0);
-
-               /* Read Cable Diagnostic Reg */
-               SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal);
-
-               /* start Cable Diagnostic Test */
-               SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CABLE_DIAG,
-                       (SK_U16)(RegVal | PHY_M_CABD_ENA_TEST));
-       
-               return(0);
-       }
-       
-       /* Read Cable Diagnostic Reg */
-       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal);
-
-       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-               ("PHY Cable Diag.=0x%04X\n", RegVal));
-
-       if ((RegVal & PHY_M_CABD_ENA_TEST) != 0) {
-               /* test is running */
-               return(2);
-       }
-
-       /* get the test results */
-       for (i = 0; i < 4; i++)  {
-               /* set address to i for MDI[i] */
-               SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, (SK_U16)i);
-
-               /* get Cable Diagnostic values */
-               SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal);
-
-               pPrt->PMdiPairLen[i] = (SK_U8)(RegVal & PHY_M_CABD_DIST_MSK);
-
-               pPrt->PMdiPairSts[i] = (SK_U8)((RegVal & PHY_M_CABD_STAT_MSK) >> 13);
-       }
-
-       return(0);
-}      /* SkGmCableDiagStatus */
-#endif /* !SK_SLIM */
-#endif /* YUKON */
-
-/* End of file */
index fe01b961b597263dc20aad6b331b384c3830d549..a2f32151559e4e05c56293dd566059e1485419a0 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/workqueue.h>
 #include <linux/if_vlan.h>
 #include <linux/prefetch.h>
+#include <linux/debugfs.h>
 #include <linux/mii.h>
 
 #include <asm/irq.h>
@@ -50,7 +51,7 @@
 #include "sky2.h"
 
 #define DRV_NAME               "sky2"
-#define DRV_VERSION            "1.14"
+#define DRV_VERSION            "1.16"
 #define PFX                    DRV_NAME " "
 
 /*
@@ -64,7 +65,6 @@
 #define RX_MAX_PENDING         (RX_LE_SIZE/6 - 2)
 #define RX_DEF_PENDING         RX_MAX_PENDING
 #define RX_SKB_ALIGN           8
-#define RX_BUF_WRITE           16
 
 #define TX_RING_SIZE           512
 #define TX_DEF_PENDING         (TX_RING_SIZE - 1)
@@ -77,6 +77,9 @@
 #define NAPI_WEIGHT            64
 #define PHY_RETRIES            1000
 
+#define SKY2_EEPROM_MAGIC      0x9955aabb
+
+
 #define RING_NEXT(x,s) (((x)+1) & ((s)-1))
 
 static const u32 default_msg =
@@ -96,7 +99,7 @@ static int disable_msi = 0;
 module_param(disable_msi, int, 0);
 MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)");
 
-static int idle_timeout = 0;
+static int idle_timeout = 100;
 module_param(idle_timeout, int, 0);
 MODULE_PARM_DESC(idle_timeout, "Watchdog timer for lost interrupts (ms)");
 
@@ -130,7 +133,7 @@ static const struct pci_device_id sky2_id_table[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) }, /* 88EC034 */
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4369) }, /* 88EC042 */
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436A) }, /* 88E8058 */
-//     { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436B) }, /* 88E8071 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436B) }, /* 88E8071 */
        { 0 }
 };
 
@@ -217,13 +220,24 @@ static void sky2_power_on(struct sky2_hw *hw)
                sky2_write8(hw, B2_Y2_CLK_GATE, 0);
 
        if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) {
-               u32 reg1;
+               u32 reg;
 
-               sky2_pci_write32(hw, PCI_DEV_REG3, 0);
-               reg1 = sky2_pci_read32(hw, PCI_DEV_REG4);
-               reg1 &= P_ASPM_CONTROL_MSK;
-               sky2_pci_write32(hw, PCI_DEV_REG4, reg1);
-               sky2_pci_write32(hw, PCI_DEV_REG5, 0);
+               reg = sky2_pci_read32(hw, PCI_DEV_REG4);
+               /* set all bits to 0 except bits 15..12 and 8 */
+               reg &= P_ASPM_CONTROL_MSK;
+               sky2_pci_write32(hw, PCI_DEV_REG4, reg);
+
+               reg = sky2_pci_read32(hw, PCI_DEV_REG5);
+               /* set all bits to 0 except bits 28 & 27 */
+               reg &= P_CTL_TIM_VMAIN_AV_MSK;
+               sky2_pci_write32(hw, PCI_DEV_REG5, reg);
+
+               sky2_pci_write32(hw, PCI_CFG_REG_1, 0);
+
+               /* Enable workaround for dev 4.107 on Yukon-Ultra & Extreme */
+               reg = sky2_read32(hw, B2_GP_IO);
+               reg |= GLB_GPIO_STAT_RACE_DIS;
+               sky2_write32(hw, B2_GP_IO, reg);
        }
 }
 
@@ -650,6 +664,30 @@ static void sky2_wol_init(struct sky2_port *sky2)
 
 }
 
+static void sky2_set_tx_stfwd(struct sky2_hw *hw, unsigned port)
+{
+       if (hw->chip_id == CHIP_ID_YUKON_EX && hw->chip_rev != CHIP_REV_YU_EX_A0) {
+               sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
+                            TX_STFW_ENA |
+                            (hw->dev[port]->mtu > ETH_DATA_LEN) ? TX_JUMBO_ENA : TX_JUMBO_DIS);
+       } else {
+               if (hw->dev[port]->mtu > ETH_DATA_LEN) {
+                       /* set Tx GMAC FIFO Almost Empty Threshold */
+                       sky2_write32(hw, SK_REG(port, TX_GMF_AE_THR),
+                                    (ECU_JUMBO_WM << 16) | ECU_AE_THR);
+
+                       sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
+                                    TX_JUMBO_ENA | TX_STFW_DIS);
+
+                       /* Can't do offload because of lack of store/forward */
+                       hw->dev[port]->features &= ~(NETIF_F_TSO | NETIF_F_SG
+                                                    | NETIF_F_ALL_CSUM);
+               } else
+                       sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
+                                    TX_JUMBO_DIS | TX_STFW_ENA);
+       }
+}
+
 static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
 {
        struct sky2_port *sky2 = netdev_priv(hw->dev[port]);
@@ -730,8 +768,11 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
 
        /* Configure Rx MAC FIFO */
        sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR);
-       sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T),
-                    GMF_OPER_ON | GMF_RX_F_FL_ON);
+       reg = GMF_OPER_ON | GMF_RX_F_FL_ON;
+       if (hw->chip_id == CHIP_ID_YUKON_EX)
+               reg |= GMF_RX_OVER_ON;
+
+       sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), reg);
 
        /* Flush Rx MAC FIFO on any flow control or error */
        sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR);
@@ -747,16 +788,7 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
                sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 768/8);
                sky2_write8(hw, SK_REG(port, RX_GMF_UP_THR), 1024/8);
 
-               /* set Tx GMAC FIFO Almost Empty Threshold */
-               sky2_write32(hw, SK_REG(port, TX_GMF_AE_THR),
-                            (ECU_JUMBO_WM << 16) | ECU_AE_THR);
-
-               if (hw->dev[port]->mtu > ETH_DATA_LEN)
-                       sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
-                                    TX_JUMBO_ENA | TX_STFW_DIS);
-               else
-                       sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
-                                    TX_JUMBO_DIS | TX_STFW_ENA);
+               sky2_set_tx_stfwd(hw, port);
        }
 
 }
@@ -861,24 +893,18 @@ static inline struct sky2_rx_le *sky2_next_rx(struct sky2_port *sky2)
        return le;
 }
 
-/* Return high part of DMA address (could be 32 or 64 bit) */
-static inline u32 high32(dma_addr_t a)
-{
-       return sizeof(a) > sizeof(u32) ? (a >> 16) >> 16 : 0;
-}
-
 /* Build description to hardware for one receive segment */
 static void sky2_rx_add(struct sky2_port *sky2,  u8 op,
                        dma_addr_t map, unsigned len)
 {
        struct sky2_rx_le *le;
-       u32 hi = high32(map);
+       u32 hi = upper_32_bits(map);
 
        if (sky2->rx_addr64 != hi) {
                le = sky2_next_rx(sky2);
                le->addr = cpu_to_le32(hi);
                le->opcode = OP_ADDR64 | HW_OWNER;
-               sky2->rx_addr64 = high32(map + len);
+               sky2->rx_addr64 = upper_32_bits(map + len);
        }
 
        le = sky2_next_rx(sky2);
@@ -939,14 +965,16 @@ static void rx_set_checksum(struct sky2_port *sky2)
 {
        struct sky2_rx_le *le;
 
-       le = sky2_next_rx(sky2);
-       le->addr = cpu_to_le32((ETH_HLEN << 16) | ETH_HLEN);
-       le->ctrl = 0;
-       le->opcode = OP_TCPSTART | HW_OWNER;
+       if (sky2->hw->chip_id != CHIP_ID_YUKON_EX) {
+               le = sky2_next_rx(sky2);
+               le->addr = cpu_to_le32((ETH_HLEN << 16) | ETH_HLEN);
+               le->ctrl = 0;
+               le->opcode = OP_TCPSTART | HW_OWNER;
 
-       sky2_write32(sky2->hw,
-                    Q_ADDR(rxqaddr[sky2->port], Q_CSR),
-                    sky2->rx_csum ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
+               sky2_write32(sky2->hw,
+                            Q_ADDR(rxqaddr[sky2->port], Q_CSR),
+                            sky2->rx_csum ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
+       }
 
 }
 
@@ -1106,6 +1134,11 @@ nomem:
        return NULL;
 }
 
+static inline void sky2_rx_update(struct sky2_port *sky2, unsigned rxq)
+{
+       sky2_put_idx(sky2->hw, rxq, sky2->rx_put);
+}
+
 /*
  * Allocate and setup receiver buffer pool.
  * Normal case this ends up creating one list element for skb
@@ -1134,15 +1167,14 @@ static int sky2_rx_start(struct sky2_port *sky2)
        if (hw->chip_id == CHIP_ID_YUKON_EC_U &&
            (hw->chip_rev == CHIP_REV_YU_EC_U_A1
             || hw->chip_rev == CHIP_REV_YU_EC_U_B0))
-               sky2_write32(hw, Q_ADDR(rxq, Q_F), F_M_RX_RAM_DIS);
+               sky2_write32(hw, Q_ADDR(rxq, Q_TEST), F_M_RX_RAM_DIS);
 
        sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1);
 
        rx_set_checksum(sky2);
 
        /* Space needed for frame data + headers rounded up */
-       size = ALIGN(sky2->netdev->mtu + ETH_HLEN + VLAN_HLEN, 8)
-               + 8;
+       size = roundup(sky2->netdev->mtu + ETH_HLEN + VLAN_HLEN, 8);
 
        /* Stopping point for hardware truncation */
        thresh = (size - 8) / sizeof(u32);
@@ -1197,7 +1229,7 @@ static int sky2_rx_start(struct sky2_port *sky2)
        }
 
        /* Tell chip about available buffers */
-       sky2_put_idx(hw, rxq, sky2->rx_put);
+       sky2_rx_update(sky2, rxq);
        return 0;
 nomem:
        sky2_rx_clean(sky2);
@@ -1234,6 +1266,8 @@ static int sky2_up(struct net_device *dev)
        if (netif_msg_ifup(sky2))
                printk(KERN_INFO PFX "%s: enabling interface\n", dev->name);
 
+       netif_carrier_off(dev);
+
        /* must be power of 2 */
        sky2->tx_le = pci_alloc_consistent(hw->pdev,
                                           TX_RING_SIZE *
@@ -1285,6 +1319,10 @@ static int sky2_up(struct net_device *dev)
 
        sky2_qset(hw, txqaddr[port]);
 
+       /* This is copied from sk98lin 10.0.5.3; no one tells me about erratta's */
+       if (hw->chip_id == CHIP_ID_YUKON_EX && hw->chip_rev == CHIP_REV_YU_EX_B0)
+               sky2_write32(hw, Q_ADDR(txqaddr[port], Q_TEST), F_TX_CHK_AUTO_OFF);
+
        /* Set almost empty threshold */
        if (hw->chip_id == CHIP_ID_YUKON_EC_U
            && hw->chip_rev == CHIP_REV_YU_EC_U_A0)
@@ -1380,27 +1418,30 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
 
        len = skb_headlen(skb);
        mapping = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE);
-       addr64 = high32(mapping);
+       addr64 = upper_32_bits(mapping);
 
        /* Send high bits if changed or crosses boundary */
-       if (addr64 != sky2->tx_addr64 || high32(mapping + len) != sky2->tx_addr64) {
+       if (addr64 != sky2->tx_addr64 ||
+           upper_32_bits(mapping + len) != sky2->tx_addr64) {
                le = get_tx_le(sky2);
                le->addr = cpu_to_le32(addr64);
                le->opcode = OP_ADDR64 | HW_OWNER;
-               sky2->tx_addr64 = high32(mapping + len);
+               sky2->tx_addr64 = upper_32_bits(mapping + len);
        }
 
        /* Check for TCP Segmentation Offload */
        mss = skb_shinfo(skb)->gso_size;
        if (mss != 0) {
-               mss += tcp_optlen(skb); /* TCP options */
-               mss += ip_hdrlen(skb) + sizeof(struct tcphdr);
-               mss += ETH_HLEN;
-
-               if (mss != sky2->tx_last_mss) {
-                       le = get_tx_le(sky2);
-                       le->addr = cpu_to_le32(mss);
-                       le->opcode = OP_LRGLEN | HW_OWNER;
+               if (hw->chip_id != CHIP_ID_YUKON_EX)
+                       mss += ETH_HLEN + ip_hdrlen(skb) + tcp_hdrlen(skb);
+
+               if (mss != sky2->tx_last_mss) {
+                       le = get_tx_le(sky2);
+                       le->addr = cpu_to_le32(mss);
+                       if (hw->chip_id == CHIP_ID_YUKON_EX)
+                               le->opcode = OP_MSS | HW_OWNER;
+                       else
+                               le->opcode = OP_LRGLEN | HW_OWNER;
                        sky2->tx_last_mss = mss;
                }
        }
@@ -1422,24 +1463,30 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
 
        /* Handle TCP checksum offload */
        if (skb->ip_summed == CHECKSUM_PARTIAL) {
-               const unsigned offset = skb_transport_offset(skb);
-               u32 tcpsum;
-
-               tcpsum = offset << 16;          /* sum start */
-               tcpsum |= offset + skb->csum_offset;    /* sum write */
-
-               ctrl |= CALSUM | WR_SUM | INIT_SUM | LOCK_SUM;
-               if (ip_hdr(skb)->protocol == IPPROTO_UDP)
-                       ctrl |= UDPTCP;
-
-               if (tcpsum != sky2->tx_tcpsum) {
-                       sky2->tx_tcpsum = tcpsum;
-
-                       le = get_tx_le(sky2);
-                       le->addr = cpu_to_le32(tcpsum);
-                       le->length = 0; /* initial checksum value */
-                       le->ctrl = 1;   /* one packet */
-                       le->opcode = OP_TCPLISW | HW_OWNER;
+               /* On Yukon EX (some versions) encoding change. */
+               if (hw->chip_id == CHIP_ID_YUKON_EX
+                   && hw->chip_rev != CHIP_REV_YU_EX_B0)
+                       ctrl |= CALSUM; /* auto checksum */
+               else {
+                       const unsigned offset = skb_transport_offset(skb);
+                       u32 tcpsum;
+
+                       tcpsum = offset << 16;                  /* sum start */
+                       tcpsum |= offset + skb->csum_offset;    /* sum write */
+
+                       ctrl |= CALSUM | WR_SUM | INIT_SUM | LOCK_SUM;
+                       if (ip_hdr(skb)->protocol == IPPROTO_UDP)
+                               ctrl |= UDPTCP;
+
+                       if (tcpsum != sky2->tx_tcpsum) {
+                               sky2->tx_tcpsum = tcpsum;
+
+                               le = get_tx_le(sky2);
+                               le->addr = cpu_to_le32(tcpsum);
+                               le->length = 0; /* initial checksum value */
+                               le->ctrl = 1;   /* one packet */
+                               le->opcode = OP_TCPLISW | HW_OWNER;
+                       }
                }
        }
 
@@ -1459,7 +1506,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
 
                mapping = pci_map_page(hw->pdev, frag->page, frag->page_offset,
                                       frag->size, PCI_DMA_TODEVICE);
-               addr64 = high32(mapping);
+               addr64 = upper_32_bits(mapping);
                if (addr64 != sky2->tx_addr64) {
                        le = get_tx_le(sky2);
                        le->addr = cpu_to_le32(addr64);
@@ -1529,13 +1576,13 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
                        if (unlikely(netif_msg_tx_done(sky2)))
                                printk(KERN_DEBUG "%s: tx done %u\n",
                                       dev->name, idx);
+
                        sky2->net_stats.tx_packets++;
                        sky2->net_stats.tx_bytes += re->skb->len;
 
                        dev_kfree_skb_any(re->skb);
+                       sky2->tx_next = RING_NEXT(idx, TX_RING_SIZE);
                }
-
-               le->opcode = 0; /* paranoia */
        }
 
        sky2->tx_cons = idx;
@@ -1573,7 +1620,6 @@ static int sky2_down(struct net_device *dev)
 
        /* Stop more packets from being queued */
        netif_stop_queue(dev);
-       netif_carrier_off(dev);
 
        /* Disable port IRQ */
        imask = sky2_read32(hw, B0_IMSK);
@@ -1625,6 +1671,8 @@ static int sky2_down(struct net_device *dev)
 
        sky2_phy_power(hw, port, 0);
 
+       netif_carrier_off(dev);
+
        /* turn off LED's */
        sky2_write16(hw, B0_Y2LED, LED_STAT_OFF);
 
@@ -1689,7 +1737,6 @@ static void sky2_link_up(struct sky2_port *sky2)
        gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);
 
        netif_carrier_on(sky2->netdev);
-       netif_wake_queue(sky2->netdev);
 
        /* Turn on link LED */
        sky2_write8(hw, SK_REG(port, LNK_LED_REG),
@@ -1741,7 +1788,6 @@ static void sky2_link_down(struct sky2_port *sky2)
        gma_write16(hw, port, GM_GP_CTRL, reg);
 
        netif_carrier_off(sky2->netdev);
-       netif_stop_queue(sky2->netdev);
 
        /* Turn on link LED */
        sky2_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF);
@@ -1913,15 +1959,8 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu)
 
        synchronize_irq(hw->pdev->irq);
 
-       if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) {
-               if (new_mtu > ETH_DATA_LEN) {
-                       sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
-                                    TX_JUMBO_ENA | TX_STFW_DIS);
-                       dev->features &= NETIF_F_TSO | NETIF_F_SG | NETIF_F_IP_CSUM;
-               } else
-                       sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
-                                    TX_JUMBO_DIS | TX_STFW_ENA);
-       }
+       if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX)
+               sky2_set_tx_stfwd(hw, port);
 
        ctl = gma_read16(hw, port, GM_GP_CTRL);
        gma_write16(hw, port, GM_GP_CTRL, ctl & ~GM_GPCR_RX_ENA);
@@ -2019,8 +2058,6 @@ static struct sk_buff *receive_new(struct sky2_port *sky2,
        struct sk_buff *skb, *nskb;
        unsigned hdr_space = sky2->rx_data_size;
 
-       pr_debug(PFX "receive new length=%d\n", length);
-
        /* Don't be tricky about reusing pages (yet) */
        nskb = sky2_rx_alloc(sky2);
        if (unlikely(!nskb))
@@ -2064,6 +2101,9 @@ static struct sk_buff *sky2_receive(struct net_device *dev,
        if (!(status & GMR_FS_RX_OK))
                goto resubmit;
 
+       if (status >> 16 != length)
+               goto len_mismatch;
+
        if (length < copybreak)
                skb = receive_copy(sky2, re, length);
        else
@@ -2073,6 +2113,11 @@ resubmit:
 
        return skb;
 
+len_mismatch:
+       /* Truncation of overlength packets
+          causes PHY length to not match MAC length */
+       ++sky2->net_stats.rx_length_errors;
+
 error:
        ++sky2->net_stats.rx_errors;
        if (status & GMR_FS_RX_FF_OV) {
@@ -2109,15 +2154,16 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last)
 /* Process status response ring */
 static int sky2_status_intr(struct sky2_hw *hw, int to_do)
 {
-       struct sky2_port *sky2;
        int work_done = 0;
-       unsigned buf_write[2] = { 0, 0 };
+       unsigned rx[2] = { 0, 0 };
        u16 hwidx = sky2_read16(hw, STAT_PUT_IDX);
 
        rmb();
 
        while (hw->st_idx != hwidx) {
+               struct sky2_port *sky2;
                struct sky2_status_le *le  = hw->st_le + hw->st_idx;
+               unsigned port = le->css & CSS_LINK_BIT;
                struct net_device *dev;
                struct sk_buff *skb;
                u32 status;
@@ -2125,19 +2171,28 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do)
 
                hw->st_idx = RING_NEXT(hw->st_idx, STATUS_RING_SIZE);
 
-               BUG_ON(le->link >= 2);
-               dev = hw->dev[le->link];
-
+               dev = hw->dev[port];
                sky2 = netdev_priv(dev);
                length = le16_to_cpu(le->length);
                status = le32_to_cpu(le->status);
 
                switch (le->opcode & ~HW_OWNER) {
                case OP_RXSTAT:
+                       ++rx[port];
                        skb = sky2_receive(dev, length, status);
                        if (unlikely(!skb)) {
                                sky2->net_stats.rx_dropped++;
-                               goto force_update;
+                               break;
+                       }
+
+                       /* This chip reports checksum status differently */
+                       if (hw->chip_id == CHIP_ID_YUKON_EX) {
+                               if (sky2->rx_csum &&
+                                   (le->css & (CSS_ISIPV4 | CSS_ISIPV6)) &&
+                                   (le->css & CSS_TCPUDPCSOK))
+                                       skb->ip_summed = CHECKSUM_UNNECESSARY;
+                               else
+                                       skb->ip_summed = CHECKSUM_NONE;
                        }
 
                        skb->protocol = eth_type_trans(skb, dev);
@@ -2154,13 +2209,6 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do)
 #endif
                                netif_receive_skb(skb);
 
-                       /* Update receiver after 16 frames */
-                       if (++buf_write[le->link] == RX_BUF_WRITE) {
-force_update:
-                               sky2_put_idx(hw, rxqaddr[le->link], sky2->rx_put);
-                               buf_write[le->link] = 0;
-                       }
-
                        /* Stop after net poll weight */
                        if (++work_done >= to_do)
                                goto exit_loop;
@@ -2179,6 +2227,9 @@ force_update:
                        if (!sky2->rx_csum)
                                break;
 
+                       if (hw->chip_id == CHIP_ID_YUKON_EX)
+                               break;
+
                        /* Both checksum counters are programmed to start at
                         * the same offset, so unless there is a problem they
                         * should match. This failure is an early indication that
@@ -2194,7 +2245,7 @@ force_update:
                                       dev->name, status);
                                sky2->rx_csum = 0;
                                sky2_write32(sky2->hw,
-                                            Q_ADDR(rxqaddr[le->link], Q_CSR),
+                                            Q_ADDR(rxqaddr[port], Q_CSR),
                                             BMU_DIS_RX_CHKSUM);
                        }
                        break;
@@ -2213,24 +2264,18 @@ force_update:
                        if (net_ratelimit())
                                printk(KERN_WARNING PFX
                                       "unknown status opcode 0x%x\n", le->opcode);
-                       goto exit_loop;
                }
        }
 
        /* Fully processed status ring so clear irq */
        sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
-       mmiowb();
 
 exit_loop:
-       if (buf_write[0]) {
-               sky2 = netdev_priv(hw->dev[0]);
-               sky2_put_idx(hw, Q_R1, sky2->rx_put);
-       }
+       if (rx[0])
+               sky2_rx_update(netdev_priv(hw->dev[0]), Q_R1);
 
-       if (buf_write[1]) {
-               sky2 = netdev_priv(hw->dev[1]);
-               sky2_put_idx(hw, Q_R2, sky2->rx_put);
-       }
+       if (rx[1])
+               sky2_rx_update(netdev_priv(hw->dev[1]), Q_R2);
 
        return work_done;
 }
@@ -2427,8 +2472,7 @@ static void sky2_err_intr(struct sky2_hw *hw, u32 status)
 static int sky2_poll(struct net_device *dev0, int *budget)
 {
        struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw;
-       int work_limit = min(dev0->quota, *budget);
-       int work_done = 0;
+       int work_done;
        u32 status = sky2_read32(hw, B0_Y2_SP_EISR);
 
        if (unlikely(status & Y2_IS_ERROR))
@@ -2440,18 +2484,25 @@ static int sky2_poll(struct net_device *dev0, int *budget)
        if (status & Y2_IS_IRQ_PHY2)
                sky2_phy_intr(hw, 1);
 
-       work_done = sky2_status_intr(hw, work_limit);
-       if (work_done < work_limit) {
-               netif_rx_complete(dev0);
+       work_done = sky2_status_intr(hw, min(dev0->quota, *budget));
+       *budget -= work_done;
+       dev0->quota -= work_done;
 
-               /* end of interrupt, re-enables also acts as I/O synchronization */
-               sky2_read32(hw, B0_Y2_SP_LISR);
-               return 0;
-       } else {
-               *budget -= work_done;
-               dev0->quota -= work_done;
+       /* More work? */
+       if (hw->st_idx != sky2_read16(hw, STAT_PUT_IDX))
                return 1;
+
+       /* Bug/Errata workaround?
+        * Need to kick the TX irq moderation timer.
+        */
+       if (sky2_read8(hw, STAT_TX_TIMER_CTRL) == TIM_START) {
+               sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP);
+               sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
        }
+       netif_rx_complete(dev0);
+
+       sky2_read32(hw, B0_Y2_SP_LISR);
+       return 0;
 }
 
 static irqreturn_t sky2_intr(int irq, void *dev_id)
@@ -2513,6 +2564,9 @@ static int __devinit sky2_init(struct sky2_hw *hw)
 {
        u8 t8;
 
+       /* Enable all clocks */
+       sky2_pci_write32(hw, PCI_DEV_REG3, 0);
+
        sky2_write8(hw, B0_CTST, CS_RST_CLR);
 
        hw->chip_id = sky2_read8(hw, B2_CHIP_ID);
@@ -2522,14 +2576,6 @@ static int __devinit sky2_init(struct sky2_hw *hw)
                return -EOPNOTSUPP;
        }
 
-       if (hw->chip_id == CHIP_ID_YUKON_EX)
-               dev_warn(&hw->pdev->dev, "this driver not yet tested on this chip type\n"
-                        "Please report success or failure to <netdev@vger.kernel.org>\n");
-
-       /* Make sure and enable all clocks */
-       if (hw->chip_id == CHIP_ID_YUKON_EX || hw->chip_id == CHIP_ID_YUKON_EC_U)
-               sky2_pci_write32(hw, PCI_DEV_REG3, 0);
-
        hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4;
 
        /* This rev is really old, and requires untested workarounds */
@@ -2589,6 +2635,11 @@ static void sky2_reset(struct sky2_hw *hw)
        for (i = 0; i < hw->ports; i++) {
                sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET);
                sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
+
+               if (hw->chip_id == CHIP_ID_YUKON_EX)
+                       sky2_write16(hw, SK_REG(i, GMAC_CTRL),
+                                    GMC_BYP_MACSECRX_ON | GMC_BYP_MACSECTX_ON
+                                    | GMC_BYP_RETR_ON);
        }
 
        sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
@@ -2675,8 +2726,6 @@ static void sky2_restart(struct work_struct *work)
        struct net_device *dev;
        int i, err;
 
-       dev_dbg(&hw->pdev->dev, "restarting\n");
-
        del_timer_sync(&hw->idle_timer);
 
        rtnl_lock();
@@ -2735,7 +2784,7 @@ static int sky2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 
        sky2->wol = wol->wolopts;
 
-       if (hw->chip_id == CHIP_ID_YUKON_EC_U)
+       if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX)
                sky2_write32(hw, B0_CTST, sky2->wol
                             ? Y2_HW_WOL_ON : Y2_HW_WOL_OFF);
 
@@ -3330,7 +3379,7 @@ static int sky2_get_regs_len(struct net_device *dev)
 
 /*
  * Returns copy of control register region
- * Note: access to the RAM address register set will cause timeouts.
+ * Note: ethtool_get_regs always provides full size (16k) buffer
  */
 static void sky2_get_regs(struct net_device *dev, struct ethtool_regs *regs,
                          void *p)
@@ -3338,15 +3387,19 @@ static void sky2_get_regs(struct net_device *dev, struct ethtool_regs *regs,
        const struct sky2_port *sky2 = netdev_priv(dev);
        const void __iomem *io = sky2->hw->regs;
 
-       BUG_ON(regs->len < B3_RI_WTO_R1);
        regs->version = 1;
        memset(p, 0, regs->len);
 
        memcpy_fromio(p, io, B3_RAM_ADDR);
 
-       memcpy_fromio(p + B3_RI_WTO_R1,
-                     io + B3_RI_WTO_R1,
-                     regs->len - B3_RI_WTO_R1);
+       /* skip diagnostic ram region */
+       memcpy_fromio(p + B3_RI_WTO_R1, io + B3_RI_WTO_R1, 0x2000 - B3_RI_WTO_R1);
+
+       /* copy GMAC registers */
+       memcpy_fromio(p + BASE_GMAC_1, io + BASE_GMAC_1, 0x1000);
+       if (sky2->hw->ports > 1)
+               memcpy_fromio(p + BASE_GMAC_2, io + BASE_GMAC_2, 0x1000);
+
 }
 
 /* In order to do Jumbo packets on these chips, need to turn off the
@@ -3357,9 +3410,7 @@ static int no_tx_offload(struct net_device *dev)
        const struct sky2_port *sky2 = netdev_priv(dev);
        const struct sky2_hw *hw = sky2->hw;
 
-       return dev->mtu > ETH_DATA_LEN &&
-               (hw->chip_id == CHIP_ID_YUKON_EX
-                || hw->chip_id == CHIP_ID_YUKON_EC_U);
+       return dev->mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_EC_U;
 }
 
 static int sky2_set_tx_csum(struct net_device *dev, u32 data)
@@ -3379,39 +3430,315 @@ static int sky2_set_tso(struct net_device *dev, u32 data)
        return ethtool_op_set_tso(dev, data);
 }
 
+static int sky2_get_eeprom_len(struct net_device *dev)
+{
+       struct sky2_port *sky2 = netdev_priv(dev);
+       u16 reg2;
+
+       reg2 = sky2_pci_read32(sky2->hw, PCI_DEV_REG2);
+       return 1 << ( ((reg2 & PCI_VPD_ROM_SZ) >> 14) + 8);
+}
+
+static u32 sky2_vpd_read(struct sky2_hw *hw, int cap, u16 offset)
+{
+       sky2_pci_write16(hw, cap + PCI_VPD_ADDR, offset);
+
+       while (!(sky2_pci_read16(hw, cap + PCI_VPD_ADDR) & PCI_VPD_ADDR_F))
+                       cpu_relax();
+       return sky2_pci_read32(hw, cap + PCI_VPD_DATA);
+}
+
+static void sky2_vpd_write(struct sky2_hw *hw, int cap, u16 offset, u32 val)
+{
+       sky2_pci_write32(hw, cap + PCI_VPD_DATA, val);
+       sky2_pci_write16(hw, cap + PCI_VPD_ADDR, offset | PCI_VPD_ADDR_F);
+       do {
+               cpu_relax();
+       } while (sky2_pci_read16(hw, cap + PCI_VPD_ADDR) & PCI_VPD_ADDR_F);
+}
+
+static int sky2_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
+                          u8 *data)
+{
+       struct sky2_port *sky2 = netdev_priv(dev);
+       int cap = pci_find_capability(sky2->hw->pdev, PCI_CAP_ID_VPD);
+       int length = eeprom->len;
+       u16 offset = eeprom->offset;
+
+       if (!cap)
+               return -EINVAL;
+
+       eeprom->magic = SKY2_EEPROM_MAGIC;
+
+       while (length > 0) {
+               u32 val = sky2_vpd_read(sky2->hw, cap, offset);
+               int n = min_t(int, length, sizeof(val));
+
+               memcpy(data, &val, n);
+               length -= n;
+               data += n;
+               offset += n;
+       }
+       return 0;
+}
+
+static int sky2_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
+                          u8 *data)
+{
+       struct sky2_port *sky2 = netdev_priv(dev);
+       int cap = pci_find_capability(sky2->hw->pdev, PCI_CAP_ID_VPD);
+       int length = eeprom->len;
+       u16 offset = eeprom->offset;
+
+       if (!cap)
+               return -EINVAL;
+
+       if (eeprom->magic != SKY2_EEPROM_MAGIC)
+               return -EINVAL;
+
+       while (length > 0) {
+               u32 val;
+               int n = min_t(int, length, sizeof(val));
+
+               if (n < sizeof(val))
+                       val = sky2_vpd_read(sky2->hw, cap, offset);
+               memcpy(&val, data, n);
+
+               sky2_vpd_write(sky2->hw, cap, offset, val);
+
+               length -= n;
+               data += n;
+               offset += n;
+       }
+       return 0;
+}
+
+
 static const struct ethtool_ops sky2_ethtool_ops = {
-       .get_settings = sky2_get_settings,
-       .set_settings = sky2_set_settings,
-       .get_drvinfo  = sky2_get_drvinfo,
-       .get_wol      = sky2_get_wol,
-       .set_wol      = sky2_set_wol,
-       .get_msglevel = sky2_get_msglevel,
-       .set_msglevel = sky2_set_msglevel,
-       .nway_reset   = sky2_nway_reset,
-       .get_regs_len = sky2_get_regs_len,
-       .get_regs = sky2_get_regs,
-       .get_link = ethtool_op_get_link,
-       .get_sg = ethtool_op_get_sg,
-       .set_sg = ethtool_op_set_sg,
-       .get_tx_csum = ethtool_op_get_tx_csum,
-       .set_tx_csum = sky2_set_tx_csum,
-       .get_tso = ethtool_op_get_tso,
-       .set_tso = sky2_set_tso,
-       .get_rx_csum = sky2_get_rx_csum,
-       .set_rx_csum = sky2_set_rx_csum,
-       .get_strings = sky2_get_strings,
-       .get_coalesce = sky2_get_coalesce,
-       .set_coalesce = sky2_set_coalesce,
-       .get_ringparam = sky2_get_ringparam,
-       .set_ringparam = sky2_set_ringparam,
+       .get_settings   = sky2_get_settings,
+       .set_settings   = sky2_set_settings,
+       .get_drvinfo    = sky2_get_drvinfo,
+       .get_wol        = sky2_get_wol,
+       .set_wol        = sky2_set_wol,
+       .get_msglevel   = sky2_get_msglevel,
+       .set_msglevel   = sky2_set_msglevel,
+       .nway_reset     = sky2_nway_reset,
+       .get_regs_len   = sky2_get_regs_len,
+       .get_regs       = sky2_get_regs,
+       .get_link       = ethtool_op_get_link,
+       .get_eeprom_len = sky2_get_eeprom_len,
+       .get_eeprom     = sky2_get_eeprom,
+       .set_eeprom     = sky2_set_eeprom,
+       .get_sg         = ethtool_op_get_sg,
+       .set_sg         = ethtool_op_set_sg,
+       .get_tx_csum    = ethtool_op_get_tx_csum,
+       .set_tx_csum    = sky2_set_tx_csum,
+       .get_tso        = ethtool_op_get_tso,
+       .set_tso        = sky2_set_tso,
+       .get_rx_csum    = sky2_get_rx_csum,
+       .set_rx_csum    = sky2_set_rx_csum,
+       .get_strings    = sky2_get_strings,
+       .get_coalesce   = sky2_get_coalesce,
+       .set_coalesce   = sky2_set_coalesce,
+       .get_ringparam  = sky2_get_ringparam,
+       .set_ringparam  = sky2_set_ringparam,
        .get_pauseparam = sky2_get_pauseparam,
        .set_pauseparam = sky2_set_pauseparam,
-       .phys_id = sky2_phys_id,
+       .phys_id        = sky2_phys_id,
        .get_stats_count = sky2_get_stats_count,
        .get_ethtool_stats = sky2_get_ethtool_stats,
        .get_perm_addr  = ethtool_op_get_perm_addr,
 };
 
+#ifdef CONFIG_SKY2_DEBUG
+
+static struct dentry *sky2_debug;
+
+static int sky2_debug_show(struct seq_file *seq, void *v)
+{
+       struct net_device *dev = seq->private;
+       const struct sky2_port *sky2 = netdev_priv(dev);
+       const struct sky2_hw *hw = sky2->hw;
+       unsigned port = sky2->port;
+       unsigned idx, last;
+       int sop;
+
+       if (!netif_running(dev))
+               return -ENETDOWN;
+
+       seq_printf(seq, "IRQ src=%x mask=%x control=%x\n",
+                  sky2_read32(hw, B0_ISRC),
+                  sky2_read32(hw, B0_IMSK),
+                  sky2_read32(hw, B0_Y2_SP_ICR));
+
+       netif_poll_disable(hw->dev[0]);
+       last = sky2_read16(hw, STAT_PUT_IDX);
+
+       if (hw->st_idx == last)
+               seq_puts(seq, "Status ring (empty)\n");
+       else {
+               seq_puts(seq, "Status ring\n");
+               for (idx = hw->st_idx; idx != last && idx < STATUS_RING_SIZE;
+                    idx = RING_NEXT(idx, STATUS_RING_SIZE)) {
+                       const struct sky2_status_le *le = hw->st_le + idx;
+                       seq_printf(seq, "[%d] %#x %d %#x\n",
+                                  idx, le->opcode, le->length, le->status);
+               }
+               seq_puts(seq, "\n");
+       }
+
+       seq_printf(seq, "Tx ring pending=%u...%u report=%d done=%d\n",
+                  sky2->tx_cons, sky2->tx_prod,
+                  sky2_read16(hw, port == 0 ? STAT_TXA1_RIDX : STAT_TXA2_RIDX),
+                  sky2_read16(hw, Q_ADDR(txqaddr[port], Q_DONE)));
+
+       /* Dump contents of tx ring */
+       sop = 1;
+       for (idx = sky2->tx_next; idx != sky2->tx_prod && idx < TX_RING_SIZE;
+            idx = RING_NEXT(idx, TX_RING_SIZE)) {
+               const struct sky2_tx_le *le = sky2->tx_le + idx;
+               u32 a = le32_to_cpu(le->addr);
+
+               if (sop)
+                       seq_printf(seq, "%u:", idx);
+               sop = 0;
+
+               switch(le->opcode & ~HW_OWNER) {
+               case OP_ADDR64:
+                       seq_printf(seq, " %#x:", a);
+                       break;
+               case OP_LRGLEN:
+                       seq_printf(seq, " mtu=%d", a);
+                       break;
+               case OP_VLAN:
+                       seq_printf(seq, " vlan=%d", be16_to_cpu(le->length));
+                       break;
+               case OP_TCPLISW:
+                       seq_printf(seq, " csum=%#x", a);
+                       break;
+               case OP_LARGESEND:
+                       seq_printf(seq, " tso=%#x(%d)", a, le16_to_cpu(le->length));
+                       break;
+               case OP_PACKET:
+                       seq_printf(seq, " %#x(%d)", a, le16_to_cpu(le->length));
+                       break;
+               case OP_BUFFER:
+                       seq_printf(seq, " frag=%#x(%d)", a, le16_to_cpu(le->length));
+                       break;
+               default:
+                       seq_printf(seq, " op=%#x,%#x(%d)", le->opcode,
+                                  a, le16_to_cpu(le->length));
+               }
+
+               if (le->ctrl & EOP) {
+                       seq_putc(seq, '\n');
+                       sop = 1;
+               }
+       }
+
+       seq_printf(seq, "\nRx ring hw get=%d put=%d last=%d\n",
+                  sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_GET_IDX)),
+                  last = sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_PUT_IDX)),
+                  sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_LAST_IDX)));
+
+       netif_poll_enable(hw->dev[0]);
+       return 0;
+}
+
+static int sky2_debug_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, sky2_debug_show, inode->i_private);
+}
+
+static const struct file_operations sky2_debug_fops = {
+       .owner          = THIS_MODULE,
+       .open           = sky2_debug_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+/*
+ * Use network device events to create/remove/rename
+ * debugfs file entries
+ */
+static int sky2_device_event(struct notifier_block *unused,
+                            unsigned long event, void *ptr)
+{
+       struct net_device *dev = ptr;
+
+       if (dev->open == sky2_up) {
+               struct sky2_port *sky2 = netdev_priv(dev);
+
+               switch(event) {
+               case NETDEV_CHANGENAME:
+                       if (!netif_running(dev))
+                               break;
+                       /* fallthrough */
+               case NETDEV_DOWN:
+               case NETDEV_GOING_DOWN:
+                       if (sky2->debugfs) {
+                               printk(KERN_DEBUG PFX "%s: remove debugfs\n",
+                                      dev->name);
+                               debugfs_remove(sky2->debugfs);
+                               sky2->debugfs = NULL;
+                       }
+
+                       if (event != NETDEV_CHANGENAME)
+                               break;
+                       /* fallthrough for changename */
+               case NETDEV_UP:
+                       if (sky2_debug) {
+                               struct dentry *d;
+                               d = debugfs_create_file(dev->name, S_IRUGO,
+                                                       sky2_debug, dev,
+                                                       &sky2_debug_fops);
+                               if (d == NULL || IS_ERR(d))
+                                       printk(KERN_INFO PFX
+                                              "%s: debugfs create failed\n",
+                                              dev->name);
+                               else
+                                       sky2->debugfs = d;
+                       }
+                       break;
+               }
+       }
+
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block sky2_notifier = {
+       .notifier_call = sky2_device_event,
+};
+
+
+static __init void sky2_debug_init(void)
+{
+       struct dentry *ent;
+
+       ent = debugfs_create_dir("sky2", NULL);
+       if (!ent || IS_ERR(ent))
+               return;
+
+       sky2_debug = ent;
+       register_netdevice_notifier(&sky2_notifier);
+}
+
+static __exit void sky2_debug_cleanup(void)
+{
+       if (sky2_debug) {
+               unregister_netdevice_notifier(&sky2_notifier);
+               debugfs_remove(sky2_debug);
+               sky2_debug = NULL;
+       }
+}
+
+#else
+#define sky2_debug_init()
+#define sky2_debug_cleanup()
+#endif
+
+
 /* Initialize network device */
 static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
                                                     unsigned port,
@@ -3486,10 +3813,6 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
        memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port * 8, ETH_ALEN);
        memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
-       /* device is off until link detection */
-       netif_carrier_off(dev);
-       netif_stop_queue(dev);
-
        return dev;
 }
 
@@ -3906,12 +4229,14 @@ static struct pci_driver sky2_driver = {
 
 static int __init sky2_init_module(void)
 {
+       sky2_debug_init();
        return pci_register_driver(&sky2_driver);
 }
 
 static void __exit sky2_cleanup_module(void)
 {
        pci_unregister_driver(&sky2_driver);
+       sky2_debug_cleanup();
 }
 
 module_init(sky2_init_module);
index b8c4a3b5eadf9812f7bede24ebeeb20f76a41e6b..dce4d276d4435e685232c7073ae98d26b9e1f818 100644 (file)
@@ -14,6 +14,8 @@ enum {
        PCI_DEV_REG3    = 0x80,
        PCI_DEV_REG4    = 0x84,
        PCI_DEV_REG5    = 0x88,
+       PCI_CFG_REG_0   = 0x90,
+       PCI_CFG_REG_1   = 0x94,
 };
 
 enum {
@@ -28,6 +30,7 @@ enum {
 enum pci_dev_reg_1 {
        PCI_Y2_PIG_ENA   = 1<<31, /* Enable Plug-in-Go (YUKON-2) */
        PCI_Y2_DLL_DIS   = 1<<30, /* Disable PCI DLL (YUKON-2) */
+       PCI_SW_PWR_ON_RST= 1<<30, /* SW Power on Reset (Yukon-EX) */
        PCI_Y2_PHY2_COMA = 1<<29, /* Set PHY 2 to Coma Mode (YUKON-2) */
        PCI_Y2_PHY1_COMA = 1<<28, /* Set PHY 1 to Coma Mode (YUKON-2) */
        PCI_Y2_PHY2_POWD = 1<<27, /* Set PHY 2 to Power Down (YUKON-2) */
@@ -67,6 +70,80 @@ enum pci_dev_reg_4 {
                                  | P_ASPM_CLKRUN_REQUEST | P_ASPM_INT_FIFO_EMPTY,
 };
 
+/*     PCI_OUR_REG_5           32 bit  Our Register 5 (Yukon-ECU only) */
+enum pci_dev_reg_5 {
+                                       /* Bit 31..27:  for A3 & later */
+       P_CTL_DIV_CORE_CLK_ENA  = 1<<31, /* Divide Core Clock Enable */
+       P_CTL_SRESET_VMAIN_AV   = 1<<30, /* Soft Reset for Vmain_av De-Glitch */
+       P_CTL_BYPASS_VMAIN_AV   = 1<<29, /* Bypass En. for Vmain_av De-Glitch */
+       P_CTL_TIM_VMAIN_AV_MSK  = 3<<27, /* Bit 28..27: Timer Vmain_av Mask */
+                                        /* Bit 26..16: Release Clock on Event */
+       P_REL_PCIE_RST_DE_ASS   = 1<<26, /* PCIe Reset De-Asserted */
+       P_REL_GPHY_REC_PACKET   = 1<<25, /* GPHY Received Packet */
+       P_REL_INT_FIFO_N_EMPTY  = 1<<24, /* Internal FIFO Not Empty */
+       P_REL_MAIN_PWR_AVAIL    = 1<<23, /* Main Power Available */
+       P_REL_CLKRUN_REQ_REL    = 1<<22, /* CLKRUN Request Release */
+       P_REL_PCIE_RESET_ASS    = 1<<21, /* PCIe Reset Asserted */
+       P_REL_PME_ASSERTED      = 1<<20, /* PME Asserted */
+       P_REL_PCIE_EXIT_L1_ST   = 1<<19, /* PCIe Exit L1 State */
+       P_REL_LOADER_NOT_FIN    = 1<<18, /* EPROM Loader Not Finished */
+       P_REL_PCIE_RX_EX_IDLE   = 1<<17, /* PCIe Rx Exit Electrical Idle State */
+       P_REL_GPHY_LINK_UP      = 1<<16, /* GPHY Link Up */
+
+                                       /* Bit 10.. 0: Mask for Gate Clock */
+       P_GAT_PCIE_RST_ASSERTED = 1<<10,/* PCIe Reset Asserted */
+       P_GAT_GPHY_N_REC_PACKET = 1<<9, /* GPHY Not Received Packet */
+       P_GAT_INT_FIFO_EMPTY    = 1<<8, /* Internal FIFO Empty */
+       P_GAT_MAIN_PWR_N_AVAIL  = 1<<7, /* Main Power Not Available */
+       P_GAT_CLKRUN_REQ_REL    = 1<<6, /* CLKRUN Not Requested */
+       P_GAT_PCIE_RESET_ASS    = 1<<5, /* PCIe Reset Asserted */
+       P_GAT_PME_DE_ASSERTED   = 1<<4, /* PME De-Asserted */
+       P_GAT_PCIE_ENTER_L1_ST  = 1<<3, /* PCIe Enter L1 State */
+       P_GAT_LOADER_FINISHED   = 1<<2, /* EPROM Loader Finished */
+       P_GAT_PCIE_RX_EL_IDLE   = 1<<1, /* PCIe Rx Electrical Idle State */
+       P_GAT_GPHY_LINK_DOWN    = 1<<0, /* GPHY Link Down */
+
+       PCIE_OUR5_EVENT_CLK_D3_SET = P_REL_GPHY_REC_PACKET |
+                                    P_REL_INT_FIFO_N_EMPTY |
+                                    P_REL_PCIE_EXIT_L1_ST |
+                                    P_REL_PCIE_RX_EX_IDLE |
+                                    P_GAT_GPHY_N_REC_PACKET |
+                                    P_GAT_INT_FIFO_EMPTY |
+                                    P_GAT_PCIE_ENTER_L1_ST |
+                                    P_GAT_PCIE_RX_EL_IDLE,
+};
+
+#/*    PCI_CFG_REG_1                   32 bit  Config Register 1 (Yukon-Ext only) */
+enum pci_cfg_reg1 {
+       P_CF1_DIS_REL_EVT_RST   = 1<<24, /* Dis. Rel. Event during PCIE reset */
+                                                                               /* Bit 23..21: Release Clock on Event */
+       P_CF1_REL_LDR_NOT_FIN   = 1<<23, /* EEPROM Loader Not Finished */
+       P_CF1_REL_VMAIN_AVLBL   = 1<<22, /* Vmain available */
+       P_CF1_REL_PCIE_RESET    = 1<<21, /* PCI-E reset */
+                                                                               /* Bit 20..18: Gate Clock on Event */
+       P_CF1_GAT_LDR_NOT_FIN   = 1<<20, /* EEPROM Loader Finished */
+       P_CF1_GAT_PCIE_RX_IDLE  = 1<<19, /* PCI-E Rx Electrical idle */
+       P_CF1_GAT_PCIE_RESET    = 1<<18, /* PCI-E Reset */
+       P_CF1_PRST_PHY_CLKREQ   = 1<<17, /* Enable PCI-E rst & PM2PHY gen. CLKREQ */
+       P_CF1_PCIE_RST_CLKREQ   = 1<<16, /* Enable PCI-E rst generate CLKREQ */
+
+       P_CF1_ENA_CFG_LDR_DONE  = 1<<8, /* Enable core level Config loader done */
+
+       P_CF1_ENA_TXBMU_RD_IDLE = 1<<1, /* Enable TX BMU Read  IDLE for ASPM */
+       P_CF1_ENA_TXBMU_WR_IDLE = 1<<0, /* Enable TX BMU Write IDLE for ASPM */
+
+       PCIE_CFG1_EVENT_CLK_D3_SET = P_CF1_DIS_REL_EVT_RST |
+                                       P_CF1_REL_LDR_NOT_FIN |
+                                       P_CF1_REL_VMAIN_AVLBL |
+                                       P_CF1_REL_PCIE_RESET |
+                                       P_CF1_GAT_LDR_NOT_FIN |
+                                       P_CF1_GAT_PCIE_RESET |
+                                       P_CF1_PRST_PHY_CLKREQ |
+                                       P_CF1_ENA_CFG_LDR_DONE |
+                                       P_CF1_ENA_TXBMU_RD_IDLE |
+                                       P_CF1_ENA_TXBMU_WR_IDLE,
+};
+
 
 #define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \
                               PCI_STATUS_SIG_SYSTEM_ERROR | \
@@ -364,6 +441,20 @@ enum {
        TST_CFG_WRITE_OFF= 1<<0, /* Disable Config Reg WR */
 };
 
+/*     B2_GPIO */
+enum {
+       GLB_GPIO_CLK_DEB_ENA = 1<<31,   /* Clock Debug Enable */
+       GLB_GPIO_CLK_DBG_MSK = 0xf<<26, /* Clock Debug */
+
+       GLB_GPIO_INT_RST_D3_DIS = 1<<15, /* Disable Internal Reset After D3 to D0 */
+       GLB_GPIO_LED_PAD_SPEED_UP = 1<<14, /* LED PAD Speed Up */
+       GLB_GPIO_STAT_RACE_DIS  = 1<<13, /* Status Race Disable */
+       GLB_GPIO_TEST_SEL_MSK   = 3<<11, /* Testmode Select */
+       GLB_GPIO_TEST_SEL_BASE  = 1<<11,
+       GLB_GPIO_RAND_ENA       = 1<<10, /* Random Enable */
+       GLB_GPIO_RAND_BIT_1     = 1<<9,  /* Random Bit 1 */
+};
+
 /*     B2_MAC_CFG               8 bit  MAC Configuration / Chip Revision */
 enum {
        CFG_CHIP_R_MSK    = 0xf<<4,     /* Bit 7.. 4: Chip Revision */
@@ -392,6 +483,11 @@ enum {
        CHIP_REV_YU_FE_A2    = 2,
 
 };
+enum yukon_ex_rev {
+       CHIP_REV_YU_EX_A0    = 1,
+       CHIP_REV_YU_EX_B0    = 2,
+};
+
 
 /*     B2_Y2_CLK_GATE   8 bit  Clock Gating (Yukon-2 only) */
 enum {
@@ -515,23 +611,15 @@ enum {
 enum {
        B8_Q_REGS = 0x0400, /* base of Queue registers */
        Q_D     = 0x00, /* 8*32 bit     Current Descriptor */
-       Q_DA_L  = 0x20, /* 32 bit       Current Descriptor Address Low dWord */
-       Q_DA_H  = 0x24, /* 32 bit       Current Descriptor Address High dWord */
+       Q_VLAN  = 0x20, /* 16 bit       Current VLAN Tag */
+       Q_DONE  = 0x24, /* 16 bit       Done Index */
        Q_AC_L  = 0x28, /* 32 bit       Current Address Counter Low dWord */
        Q_AC_H  = 0x2c, /* 32 bit       Current Address Counter High dWord */
        Q_BC    = 0x30, /* 32 bit       Current Byte Counter */
        Q_CSR   = 0x34, /* 32 bit       BMU Control/Status Register */
-       Q_F     = 0x38, /* 32 bit       Flag Register */
-       Q_T1    = 0x3c, /* 32 bit       Test Register 1 */
-       Q_T1_TR = 0x3c, /*  8 bit       Test Register 1 Transfer SM */
-       Q_T1_WR = 0x3d, /*  8 bit       Test Register 1 Write Descriptor SM */
-       Q_T1_RD = 0x3e, /*  8 bit       Test Register 1 Read Descriptor SM */
-       Q_T1_SV = 0x3f, /*  8 bit       Test Register 1 Supervisor SM */
-       Q_T2    = 0x40, /* 32 bit       Test Register 2 */
-       Q_T3    = 0x44, /* 32 bit       Test Register 3 */
+       Q_TEST  = 0x38, /* 32 bit       Test/Control Register */
 
 /* Yukon-2 */
-       Q_DONE  = 0x24, /* 16 bit       Done Index              (Yukon-2 only) */
        Q_WM    = 0x40, /* 16 bit       FIFO Watermark */
        Q_AL    = 0x42, /*  8 bit       FIFO Alignment */
        Q_RSP   = 0x44, /* 16 bit       FIFO Read Shadow Pointer */
@@ -545,15 +633,16 @@ enum {
 };
 #define Q_ADDR(reg, offs) (B8_Q_REGS + (reg) + (offs))
 
-/*     Q_F                             32 bit  Flag Register */
+/*     Q_TEST                          32 bit  Test Register */
 enum {
-       F_ALM_FULL      = 1<<27, /* Rx FIFO: almost full */
-       F_EMPTY         = 1<<27, /* Tx FIFO: empty flag */
-       F_FIFO_EOF      = 1<<26, /* Tag (EOF Flag) bit in FIFO */
-       F_WM_REACHED    = 1<<25, /* Watermark reached */
+       /* Transmit */
+       F_TX_CHK_AUTO_OFF = 1<<31, /* Tx checksum auto calc off (Yukon EX) */
+       F_TX_CHK_AUTO_ON  = 1<<30, /* Tx checksum auto calc off (Yukon EX) */
+
+       /* Receive */
        F_M_RX_RAM_DIS  = 1<<24, /* MAC Rx RAM Read Port disable */
-       F_FIFO_LEVEL    = 0x1fL<<16, /* Bit 23..16:     # of Qwords in FIFO */
-       F_WATER_MARK    = 0x0007ffL, /* Bit 10.. 0:     Watermark */
+
+       /* Hardware testbits not used */
 };
 
 /* Queue Prefetch Unit Offsets, use Y2_QADDR() to address (Yukon-2 only)*/
@@ -1608,6 +1697,16 @@ enum {
        RX_VLAN_STRIP_ON = 1<<25,       /* enable  VLAN stripping */
        RX_VLAN_STRIP_OFF = 1<<24,      /* disable VLAN stripping */
 
+       RX_MACSEC_FLUSH_ON  = 1<<23,
+       RX_MACSEC_FLUSH_OFF = 1<<22,
+       RX_MACSEC_ASF_FLUSH_ON = 1<<21,
+       RX_MACSEC_ASF_FLUSH_OFF = 1<<20,
+
+       GMF_RX_OVER_ON      = 1<<19,    /* enable flushing on receive overrun */
+       GMF_RX_OVER_OFF     = 1<<18,    /* disable flushing on receive overrun */
+       GMF_ASF_RX_OVER_ON  = 1<<17,    /* enable flushing of ASF when overrun */
+       GMF_ASF_RX_OVER_OFF = 1<<16,    /* disable flushing of ASF when overrun */
+
        GMF_WP_TST_ON   = 1<<14,        /* Write Pointer Test On */
        GMF_WP_TST_OFF  = 1<<13,        /* Write Pointer Test Off */
        GMF_WP_STEP     = 1<<12,        /* Write Pointer Step/Increment */
@@ -1720,6 +1819,15 @@ enum {
 
 /*     GMAC_CTRL               32 bit  GMAC Control Reg (YUKON only) */
 enum {
+       GMC_SET_RST         = 1<<15,/* MAC SEC RST */
+       GMC_SEC_RST_OFF     = 1<<14,/* MAC SEC RSt OFF */
+       GMC_BYP_MACSECRX_ON = 1<<13,/* Bypass macsec RX */
+       GMC_BYP_MACSECRX_OFF= 1<<12,/* Bypass macsec RX off */
+       GMC_BYP_MACSECTX_ON = 1<<11,/* Bypass macsec TX */
+       GMC_BYP_MACSECTX_OFF= 1<<10,/* Bypass macsec TX  off*/
+       GMC_BYP_RETR_ON = 1<<9, /* Bypass retransmit FIFO On */
+       GMC_BYP_RETR_OFF= 1<<8, /* Bypass retransmit FIFO Off */
+
        GMC_H_BURST_ON  = 1<<7, /* Half Duplex Burst Mode On */
        GMC_H_BURST_OFF = 1<<6, /* Half Duplex Burst Mode Off */
        GMC_F_LOOPB_ON  = 1<<5, /* FIFO Loopback On */
@@ -1805,9 +1913,13 @@ enum {
        OP_ADDR64VLAN   = OP_ADDR64 | OP_VLAN,
        OP_LRGLEN       = 0x24,
        OP_LRGLENVLAN   = OP_LRGLEN | OP_VLAN,
+       OP_MSS          = 0x28,
+       OP_MSSVLAN      = OP_MSS | OP_VLAN,
+
        OP_BUFFER       = 0x40,
        OP_PACKET       = 0x41,
        OP_LARGESEND    = 0x43,
+       OP_LSOV2        = 0x45,
 
 /* YUKON-2 STATUS opcodes defines */
        OP_RXSTAT       = 0x60,
@@ -1818,6 +1930,19 @@ enum {
        OP_RXTIMEVLAN   = OP_RXTIMESTAMP | OP_RXVLAN,
        OP_RSS_HASH     = 0x65,
        OP_TXINDEXLE    = 0x68,
+       OP_MACSEC       = 0x6c,
+       OP_PUTIDX       = 0x70,
+};
+
+enum status_css {
+       CSS_TCPUDPCSOK  = 1<<7, /* TCP / UDP checksum is ok */
+       CSS_ISUDP       = 1<<6, /* packet is a UDP packet */
+       CSS_ISTCP       = 1<<5, /* packet is a TCP packet */
+       CSS_ISIPFRAG    = 1<<4, /* packet is a TCP/UDP frag, CS calc not done */
+       CSS_ISIPV6      = 1<<3, /* packet is a IPv6 packet */
+       CSS_IPV4CSUMOK  = 1<<2, /* IP v4: TCP header checksum is ok */
+       CSS_ISIPV4      = 1<<1, /* packet is a IPv4 packet */
+       CSS_LINK_BIT    = 1<<0, /* port number (legacy) */
 };
 
 /* Yukon 2 hardware interface */
@@ -1838,7 +1963,7 @@ struct sky2_rx_le {
 struct sky2_status_le {
        __le32  status; /* also checksum */
        __le16  length; /* also vlan tag */
-       u8      link;
+       u8      css;
        u8      opcode;
 } __attribute((packed));
 
@@ -1873,6 +1998,7 @@ struct sky2_port {
        struct sky2_tx_le    *tx_le;
        u16                  tx_cons;           /* next le to check */
        u16                  tx_prod;           /* next le to use */
+       u16                  tx_next;           /* debug only */
        u32                  tx_addr64;
        u16                  tx_pending;
        u16                  tx_last_mss;
@@ -1903,6 +2029,9 @@ struct sky2_port {
        enum flow_control    flow_mode;
        enum flow_control    flow_status;
 
+#ifdef CONFIG_SKY2_DEBUG
+       struct dentry        *debugfs;
+#endif
        struct net_device_stats net_stats;
 
 };
diff --git a/drivers/net/sni_82596.c b/drivers/net/sni_82596.c
new file mode 100644 (file)
index 0000000..2cf6794
--- /dev/null
@@ -0,0 +1,185 @@
+/*
+ * sni_82596.c -- driver for intel 82596 ethernet controller, as
+ *               used in older SNI RM machines
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/bitops.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+
+#define SNI_82596_DRIVER_VERSION "SNI RM 82596 driver - Revision: 0.01"
+
+static const char sni_82596_string[] = "snirm_82596";
+
+#define DMA_ALLOC                      dma_alloc_coherent
+#define DMA_FREE                       dma_free_coherent
+#define DMA_WBACK(priv, addr, len)     do { } while (0)
+#define DMA_INV(priv, addr, len)       do { } while (0)
+#define DMA_WBACK_INV(priv, addr, len) do { } while (0)
+
+#define SYSBUS      0x00004400
+
+/* big endian CPU, 82596 little endian */
+#define SWAP32(x)   cpu_to_le32((u32)(x))
+#define SWAP16(x)   cpu_to_le16((u16)(x))
+
+#define OPT_MPU_16BIT    0x01
+
+#include "lib82596.c"
+
+MODULE_AUTHOR("Thomas Bogendoerfer");
+MODULE_DESCRIPTION("i82596 driver");
+MODULE_LICENSE("GPL");
+module_param(i596_debug, int, 0);
+MODULE_PARM_DESC(i596_debug, "82596 debug mask");
+
+static inline void ca(struct net_device *dev)
+{
+       struct i596_private *lp = netdev_priv(dev);
+
+       writel(0, lp->ca);
+}
+
+
+static void mpu_port(struct net_device *dev, int c, dma_addr_t x)
+{
+       struct i596_private *lp = netdev_priv(dev);
+
+       u32 v = (u32) (c) | (u32) (x);
+
+       if (lp->options & OPT_MPU_16BIT) {
+               writew(v & 0xffff, lp->mpu_port);
+               wmb();  /* order writes to MPU port */
+               udelay(1);
+               writew(v >> 16, lp->mpu_port);
+       } else {
+               writel(v, lp->mpu_port);
+               wmb();  /* order writes to MPU port */
+               udelay(1);
+               writel(v, lp->mpu_port);
+       }
+}
+
+
+static int __devinit sni_82596_probe(struct platform_device *dev)
+{
+       struct  net_device *netdevice;
+       struct i596_private *lp;
+       struct  resource *res, *ca, *idprom, *options;
+       int     retval = -ENOMEM;
+       void __iomem *mpu_addr;
+       void __iomem *ca_addr;
+       u8 __iomem *eth_addr;
+
+       res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+       ca = platform_get_resource(dev, IORESOURCE_MEM, 1);
+       options = platform_get_resource(dev, 0, 0);
+       idprom = platform_get_resource(dev, IORESOURCE_MEM, 2);
+       if (!res || !ca || !options || !idprom)
+               return -ENODEV;
+       mpu_addr = ioremap_nocache(res->start, 4);
+       if (!mpu_addr)
+               return -ENOMEM;
+       ca_addr = ioremap_nocache(ca->start, 4);
+       if (!ca_addr)
+               goto probe_failed_free_mpu;
+
+       printk(KERN_INFO "Found i82596 at 0x%x\n", res->start);
+
+       netdevice = alloc_etherdev(sizeof(struct i596_private));
+       if (!netdevice)
+               goto probe_failed_free_ca;
+
+       SET_NETDEV_DEV(netdevice, &dev->dev);
+       platform_set_drvdata (dev, netdevice);
+
+       netdevice->base_addr = res->start;
+       netdevice->irq = platform_get_irq(dev, 0);
+
+       eth_addr = ioremap_nocache(idprom->start, 0x10);
+       if (!eth_addr)
+               goto probe_failed;
+
+       /* someone seems to like messed up stuff */
+       netdevice->dev_addr[0] = readb(eth_addr + 0x0b);
+       netdevice->dev_addr[1] = readb(eth_addr + 0x0a);
+       netdevice->dev_addr[2] = readb(eth_addr + 0x09);
+       netdevice->dev_addr[3] = readb(eth_addr + 0x08);
+       netdevice->dev_addr[4] = readb(eth_addr + 0x07);
+       netdevice->dev_addr[5] = readb(eth_addr + 0x06);
+       iounmap(eth_addr);
+
+       if (!netdevice->irq) {
+               printk(KERN_ERR "%s: IRQ not found for i82596 at 0x%lx\n",
+                       __FILE__, netdevice->base_addr);
+               goto probe_failed;
+       }
+
+       lp = netdev_priv(netdevice);
+       lp->options = options->flags & IORESOURCE_BITS;
+       lp->ca = ca_addr;
+       lp->mpu_port = mpu_addr;
+
+       retval = i82596_probe(netdevice);
+       if (retval == 0)
+               return 0;
+
+probe_failed:
+       free_netdev(netdevice);
+probe_failed_free_ca:
+       iounmap(ca_addr);
+probe_failed_free_mpu:
+       iounmap(mpu_addr);
+       return retval;
+}
+
+static int __devexit sni_82596_driver_remove(struct platform_device *pdev)
+{
+       struct net_device *dev = platform_get_drvdata(pdev);
+       struct i596_private *lp = netdev_priv(dev);
+
+       unregister_netdev(dev);
+       DMA_FREE(dev->dev.parent, sizeof(struct i596_private),
+                lp->dma, lp->dma_addr);
+       iounmap(lp->ca);
+       iounmap(lp->mpu_port);
+       free_netdev (dev);
+       return 0;
+}
+
+static struct platform_driver sni_82596_driver = {
+       .probe  = sni_82596_probe,
+       .remove = __devexit_p(sni_82596_driver_remove),
+       .driver = {
+               .name   = sni_82596_string,
+       },
+};
+
+static int __devinit sni_82596_init(void)
+{
+       printk(KERN_INFO SNI_82596_DRIVER_VERSION "\n");
+       return platform_driver_register(&sni_82596_driver);
+}
+
+
+static void __exit sni_82596_exit(void)
+{
+       platform_driver_unregister(&sni_82596_driver);
+}
+
+module_init(sni_82596_init);
+module_exit(sni_82596_exit);
index 7a4aa6a9f94913245f2eb7b155a363c33c1399af..590b12c7246ca44bbe33c2cb4a9eec237683c5f2 100644 (file)
@@ -434,7 +434,8 @@ spider_net_prepare_rx_descr(struct spider_net_card *card,
                                      bufsize + SPIDER_NET_RXBUF_ALIGN - 1);
        if (!descr->skb) {
                if (netif_msg_rx_err(card) && net_ratelimit())
-                       pr_err("Not enough memory to allocate rx buffer\n");
+                       dev_err(&card->netdev->dev,
+                               "Not enough memory to allocate rx buffer\n");
                card->spider_stats.alloc_rx_skb_error++;
                return -ENOMEM;
        }
@@ -455,7 +456,7 @@ spider_net_prepare_rx_descr(struct spider_net_card *card,
                dev_kfree_skb_any(descr->skb);
                descr->skb = NULL;
                if (netif_msg_rx_err(card) && net_ratelimit())
-                       pr_err("Could not iommu-map rx buffer\n");
+                       dev_err(&card->netdev->dev, "Could not iommu-map rx buffer\n");
                card->spider_stats.rx_iommu_map_error++;
                hwdescr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE;
        } else {
@@ -499,6 +500,20 @@ spider_net_enable_rxdmac(struct spider_net_card *card)
                             SPIDER_NET_DMA_RX_VALUE);
 }
 
+/**
+ * spider_net_disable_rxdmac - disables the receive DMA controller
+ * @card: card structure
+ *
+ * spider_net_disable_rxdmac terminates processing on the DMA controller
+ * by turing off the DMA controller, with the force-end flag set.
+ */
+static inline void
+spider_net_disable_rxdmac(struct spider_net_card *card)
+{
+       spider_net_write_reg(card, SPIDER_NET_GDADMACCNTR,
+                            SPIDER_NET_DMA_RX_FEND_VALUE);
+}
+
 /**
  * spider_net_refill_rx_chain - refills descriptors/skbs in the rx chains
  * @card: card structure
@@ -654,20 +669,6 @@ write_hash:
        }
 }
 
-/**
- * spider_net_disable_rxdmac - disables the receive DMA controller
- * @card: card structure
- *
- * spider_net_disable_rxdmac terminates processing on the DMA controller by
- * turing off DMA and issueing a force end
- */
-static void
-spider_net_disable_rxdmac(struct spider_net_card *card)
-{
-       spider_net_write_reg(card, SPIDER_NET_GDADMACCNTR,
-                            SPIDER_NET_DMA_RX_FEND_VALUE);
-}
-
 /**
  * spider_net_prepare_tx_descr - fill tx descriptor with skb data
  * @card: card structure
@@ -692,7 +693,7 @@ spider_net_prepare_tx_descr(struct spider_net_card *card,
        buf = pci_map_single(card->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
        if (pci_dma_mapping_error(buf)) {
                if (netif_msg_tx_err(card) && net_ratelimit())
-                       pr_err("could not iommu-map packet (%p, %i). "
+                       dev_err(&card->netdev->dev, "could not iommu-map packet (%p, %i). "
                                  "Dropping packet\n", skb->data, skb->len);
                card->spider_stats.tx_iommu_map_error++;
                return -ENOMEM;
@@ -715,7 +716,7 @@ spider_net_prepare_tx_descr(struct spider_net_card *card,
        hwdescr->data_status = 0;
 
        hwdescr->dmac_cmd_status =
-                       SPIDER_NET_DESCR_CARDOWNED | SPIDER_NET_DMAC_NOCS;
+                       SPIDER_NET_DESCR_CARDOWNED | SPIDER_NET_DMAC_TXFRMTL;
        spin_unlock_irqrestore(&chain->lock, flags);
 
        if (skb->ip_summed == CHECKSUM_PARTIAL)
@@ -832,9 +833,8 @@ spider_net_release_tx_chain(struct spider_net_card *card, int brutal)
                case SPIDER_NET_DESCR_PROTECTION_ERROR:
                case SPIDER_NET_DESCR_FORCE_END:
                        if (netif_msg_tx_err(card))
-                               pr_err("%s: forcing end of tx descriptor "
-                                      "with status x%02x\n",
-                                      card->netdev->name, status);
+                               dev_err(&card->netdev->dev, "forcing end of tx descriptor "
+                                      "with status x%02x\n", status);
                        card->netdev_stats.tx_errors++;
                        break;
 
@@ -1022,34 +1022,94 @@ spider_net_pass_skb_up(struct spider_net_descr *descr,
        netif_receive_skb(skb);
 }
 
-#ifdef DEBUG
 static void show_rx_chain(struct spider_net_card *card)
 {
        struct spider_net_descr_chain *chain = &card->rx_chain;
        struct spider_net_descr *start= chain->tail;
        struct spider_net_descr *descr= start;
+       struct spider_net_hw_descr *hwd = start->hwdescr;
+       struct device *dev = &card->netdev->dev;
+       u32 curr_desc, next_desc;
        int status;
 
+       int tot = 0;
        int cnt = 0;
-       int cstat = spider_net_get_descr_status(descr);
-       printk(KERN_INFO "RX chain tail at descr=%ld\n",
-            (start - card->descr) - card->tx_chain.num_desc);
+       int off = start - chain->ring;
+       int cstat = hwd->dmac_cmd_status;
+
+       dev_info(dev, "Total number of descrs=%d\n",
+               chain->num_desc);
+       dev_info(dev, "Chain tail located at descr=%d, status=0x%x\n",
+               off, cstat);
+
+       curr_desc = spider_net_read_reg(card, SPIDER_NET_GDACTDPA);
+       next_desc = spider_net_read_reg(card, SPIDER_NET_GDACNEXTDA);
+
        status = cstat;
        do
        {
-               status = spider_net_get_descr_status(descr);
+               hwd = descr->hwdescr;
+               off = descr - chain->ring;
+               status = hwd->dmac_cmd_status;
+
+               if (descr == chain->head)
+                       dev_info(dev, "Chain head is at %d, head status=0x%x\n",
+                                off, status);
+
+               if (curr_desc == descr->bus_addr)
+                       dev_info(dev, "HW curr desc (GDACTDPA) is at %d, status=0x%x\n",
+                                off, status);
+
+               if (next_desc == descr->bus_addr)
+                       dev_info(dev, "HW next desc (GDACNEXTDA) is at %d, status=0x%x\n",
+                                off, status);
+
+               if (hwd->next_descr_addr == 0)
+                       dev_info(dev, "chain is cut at %d\n", off);
+
                if (cstat != status) {
-                       printk(KERN_INFO "Have %d descrs with stat=x%08x\n", cnt, cstat);
+                       int from = (chain->num_desc + off - cnt) % chain->num_desc;
+                       int to = (chain->num_desc + off - 1) % chain->num_desc;
+                       dev_info(dev, "Have %d (from %d to %d) descrs "
+                                "with stat=0x%08x\n", cnt, from, to, cstat);
                        cstat = status;
                        cnt = 0;
                }
+
                cnt ++;
+               tot ++;
+               descr = descr->next;
+       } while (descr != start);
+
+       dev_info(dev, "Last %d descrs with stat=0x%08x "
+                "for a total of %d descrs\n", cnt, cstat, tot);
+
+#ifdef DEBUG
+       /* Now dump the whole ring */
+       descr = start;
+       do
+       {
+               struct spider_net_hw_descr *hwd = descr->hwdescr;
+               status = spider_net_get_descr_status(hwd);
+               cnt = descr - chain->ring;
+               dev_info(dev, "Descr %d stat=0x%08x skb=%p\n",
+                        cnt, status, descr->skb);
+               dev_info(dev, "bus addr=%08x buf addr=%08x sz=%d\n",
+                        descr->bus_addr, hwd->buf_addr, hwd->buf_size);
+               dev_info(dev, "next=%08x result sz=%d valid sz=%d\n",
+                        hwd->next_descr_addr, hwd->result_size,
+                        hwd->valid_size);
+               dev_info(dev, "dmac=%08x data stat=%08x data err=%08x\n",
+                        hwd->dmac_cmd_status, hwd->data_status,
+                        hwd->data_error);
+               dev_info(dev, "\n");
+
                descr = descr->next;
        } while (descr != start);
-       printk(KERN_INFO "Last %d descrs with stat=x%08x\n", cnt, cstat);
-}
 #endif
 
+}
+
 /**
  * spider_net_resync_head_ptr - Advance head ptr past empty descrs
  *
@@ -1127,6 +1187,7 @@ spider_net_decode_one_descr(struct spider_net_card *card)
        struct spider_net_descr_chain *chain = &card->rx_chain;
        struct spider_net_descr *descr = chain->tail;
        struct spider_net_hw_descr *hwdescr = descr->hwdescr;
+       u32 hw_buf_addr;
        int status;
 
        status = spider_net_get_descr_status(hwdescr);
@@ -1140,15 +1201,17 @@ spider_net_decode_one_descr(struct spider_net_card *card)
        chain->tail = descr->next;
 
        /* unmap descriptor */
-       pci_unmap_single(card->pdev, hwdescr->buf_addr,
+       hw_buf_addr = hwdescr->buf_addr;
+       hwdescr->buf_addr = 0xffffffff;
+       pci_unmap_single(card->pdev, hw_buf_addr,
                        SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE);
 
        if ( (status == SPIDER_NET_DESCR_RESPONSE_ERROR) ||
             (status == SPIDER_NET_DESCR_PROTECTION_ERROR) ||
             (status == SPIDER_NET_DESCR_FORCE_END) ) {
                if (netif_msg_rx_err(card))
-                       pr_err("%s: dropping RX descriptor with state %d\n",
-                              card->netdev->name, status);
+                       dev_err(&card->netdev->dev,
+                              "dropping RX descriptor with state %d\n", status);
                card->netdev_stats.rx_dropped++;
                goto bad_desc;
        }
@@ -1156,8 +1219,8 @@ spider_net_decode_one_descr(struct spider_net_card *card)
        if ( (status != SPIDER_NET_DESCR_COMPLETE) &&
             (status != SPIDER_NET_DESCR_FRAME_END) ) {
                if (netif_msg_rx_err(card))
-                       pr_err("%s: RX descriptor with unknown state %d\n",
-                              card->netdev->name, status);
+                       dev_err(&card->netdev->dev,
+                              "RX descriptor with unknown state %d\n", status);
                card->spider_stats.rx_desc_unk_state++;
                goto bad_desc;
        }
@@ -1165,18 +1228,17 @@ spider_net_decode_one_descr(struct spider_net_card *card)
        /* The cases we'll throw away the packet immediately */
        if (hwdescr->data_error & SPIDER_NET_DESTROY_RX_FLAGS) {
                if (netif_msg_rx_err(card))
-                       pr_err("%s: error in received descriptor found, "
+                       dev_err(&card->netdev->dev,
+                              "error in received descriptor found, "
                               "data_status=x%08x, data_error=x%08x\n",
-                              card->netdev->name,
                               hwdescr->data_status, hwdescr->data_error);
                goto bad_desc;
        }
 
-       if (hwdescr->dmac_cmd_status & 0xfcf4) {
-               pr_err("%s: bad status, cmd_status=x%08x\n",
-                              card->netdev->name,
+       if (hwdescr->dmac_cmd_status & SPIDER_NET_DESCR_BAD_STATUS) {
+               dev_err(&card->netdev->dev, "bad status, cmd_status=x%08x\n",
                               hwdescr->dmac_cmd_status);
-               pr_err("buf_addr=x%08x\n", hwdescr->buf_addr);
+               pr_err("buf_addr=x%08x\n", hw_buf_addr);
                pr_err("buf_size=x%08x\n", hwdescr->buf_size);
                pr_err("next_descr_addr=x%08x\n", hwdescr->next_descr_addr);
                pr_err("result_size=x%08x\n", hwdescr->result_size);
@@ -1196,6 +1258,8 @@ spider_net_decode_one_descr(struct spider_net_card *card)
        return 1;
 
 bad_desc:
+       if (netif_msg_rx_err(card))
+               show_rx_chain(card);
        dev_kfree_skb_irq(descr->skb);
        descr->skb = NULL;
        hwdescr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE;
@@ -1221,7 +1285,6 @@ spider_net_poll(struct net_device *netdev, int *budget)
        int packets_to_do, packets_done = 0;
        int no_more_packets = 0;
 
-       spider_net_cleanup_tx_ring(card);
        packets_to_do = min(*budget, netdev->quota);
 
        while (packets_to_do) {
@@ -1246,6 +1309,8 @@ spider_net_poll(struct net_device *netdev, int *budget)
        spider_net_refill_rx_chain(card);
        spider_net_enable_rxdmac(card);
 
+       spider_net_cleanup_tx_ring(card);
+
        /* if all packets are in the stack, enable interrupts and return 0 */
        /* if not, return 1 */
        if (no_more_packets) {
@@ -1376,11 +1441,17 @@ static void
 spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg)
 {
        u32 error_reg1, error_reg2;
+       u32 mask_reg1, mask_reg2;
        u32 i;
        int show_error = 1;
 
        error_reg1 = spider_net_read_reg(card, SPIDER_NET_GHIINT1STS);
        error_reg2 = spider_net_read_reg(card, SPIDER_NET_GHIINT2STS);
+       mask_reg1 = spider_net_read_reg(card, SPIDER_NET_GHIINT1MSK);
+       mask_reg2 = spider_net_read_reg(card,SPIDER_NET_GHIINT2MSK);
+
+       error_reg1 &= mask_reg1;
+       error_reg2 &= mask_reg2;
 
        /* check GHIINT0STS ************************************/
        if (status_reg)
@@ -1415,7 +1486,7 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg)
        case SPIDER_NET_GPWFFINT:
                /* PHY command queue full */
                if (netif_msg_intr(card))
-                       pr_err("PHY write queue full\n");
+                       dev_err(&card->netdev->dev, "PHY write queue full\n");
                show_error = 0;
                break;
 
@@ -1582,9 +1653,8 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg)
        }
 
        if ((show_error) && (netif_msg_intr(card)) && net_ratelimit())
-               pr_err("Got error interrupt on %s, GHIINT0STS = 0x%08x, "
+               dev_err(&card->netdev->dev, "Error interrupt, GHIINT0STS = 0x%08x, "
                       "GHIINT1STS = 0x%08x, GHIINT2STS = 0x%08x\n",
-                      card->netdev->name,
                       status_reg, error_reg1, error_reg2);
 
        /* clear interrupt sources */
@@ -1609,9 +1679,11 @@ spider_net_interrupt(int irq, void *ptr)
 {
        struct net_device *netdev = ptr;
        struct spider_net_card *card = netdev_priv(netdev);
-       u32 status_reg;
+       u32 status_reg, mask_reg;
 
        status_reg = spider_net_read_reg(card, SPIDER_NET_GHIINT0STS);
+       mask_reg = spider_net_read_reg(card, SPIDER_NET_GHIINT0MSK);
+       status_reg &= mask_reg;
 
        if (!status_reg)
                return IRQ_NONE;
@@ -1652,6 +1724,38 @@ spider_net_poll_controller(struct net_device *netdev)
 }
 #endif /* CONFIG_NET_POLL_CONTROLLER */
 
+/**
+ * spider_net_enable_interrupts - enable interrupts
+ * @card: card structure
+ *
+ * spider_net_enable_interrupt enables several interrupts
+ */
+static void 
+spider_net_enable_interrupts(struct spider_net_card *card)
+{
+       spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK,
+                            SPIDER_NET_INT0_MASK_VALUE);
+       spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK,
+                            SPIDER_NET_INT1_MASK_VALUE);
+       spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK,
+                            SPIDER_NET_INT2_MASK_VALUE);
+}
+
+/**
+ * spider_net_disable_interrupts - disable interrupts
+ * @card: card structure
+ *
+ * spider_net_disable_interrupts disables all the interrupts
+ */
+static void 
+spider_net_disable_interrupts(struct spider_net_card *card)
+{
+       spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, 0);
+       spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, 0);
+       spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, 0);
+       spider_net_write_reg(card, SPIDER_NET_GMACINTEN, 0);
+}
+
 /**
  * spider_net_init_card - initializes the card
  * @card: card structure
@@ -1672,6 +1776,7 @@ spider_net_init_card(struct spider_net_card *card)
        spider_net_write_reg(card, SPIDER_NET_GMACOPEMD,
                spider_net_read_reg(card, SPIDER_NET_GMACOPEMD) | 0x4);
 
+       spider_net_disable_interrupts(card);
 }
 
 /**
@@ -1759,14 +1864,6 @@ spider_net_enable_card(struct spider_net_card *card)
        spider_net_write_reg(card, SPIDER_NET_GMACOPEMD,
                             SPIDER_NET_OPMODE_VALUE);
 
-       /* set interrupt mask registers */
-       spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK,
-                            SPIDER_NET_INT0_MASK_VALUE);
-       spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK,
-                            SPIDER_NET_INT1_MASK_VALUE);
-       spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK,
-                            SPIDER_NET_INT2_MASK_VALUE);
-
        spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR,
                             SPIDER_NET_GDTBSTA);
 }
@@ -1849,7 +1946,8 @@ spider_net_init_firmware(struct spider_net_card *card)
                             SPIDER_NET_FIRMWARE_NAME, &card->pdev->dev) == 0) {
                if ( (firmware->size != SPIDER_NET_FIRMWARE_LEN) &&
                     netif_msg_probe(card) ) {
-                       pr_err("Incorrect size of spidernet firmware in " \
+                       dev_err(&card->netdev->dev,
+                              "Incorrect size of spidernet firmware in " \
                               "filesystem. Looking in host firmware...\n");
                        goto try_host_fw;
                }
@@ -1873,8 +1971,8 @@ try_host_fw:
 
        if ( (fw_size != SPIDER_NET_FIRMWARE_LEN) &&
             netif_msg_probe(card) ) {
-               pr_err("Incorrect size of spidernet firmware in " \
-                      "host firmware\n");
+               dev_err(&card->netdev->dev,
+                      "Incorrect size of spidernet firmware in host firmware\n");
                goto done;
        }
 
@@ -1884,7 +1982,8 @@ done:
        return err;
 out_err:
        if (netif_msg_probe(card))
-               pr_err("Couldn't find spidernet firmware in filesystem " \
+               dev_err(&card->netdev->dev,
+                      "Couldn't find spidernet firmware in filesystem " \
                       "or host firmware\n");
        return err;
 }
@@ -1941,6 +2040,8 @@ spider_net_open(struct net_device *netdev)
        netif_carrier_on(netdev);
        netif_poll_enable(netdev);
 
+       spider_net_enable_interrupts(card);
+
        return 0;
 
 register_int_failed:
@@ -2113,11 +2214,7 @@ spider_net_stop(struct net_device *netdev)
        del_timer_sync(&card->tx_timer);
        del_timer_sync(&card->aneg_timer);
 
-       /* disable/mask all interrupts */
-       spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, 0);
-       spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, 0);
-       spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, 0);
-       spider_net_write_reg(card, SPIDER_NET_GMACINTEN, 0);
+       spider_net_disable_interrupts(card);
 
        free_irq(netdev->irq, netdev);
 
@@ -2279,13 +2376,14 @@ spider_net_setup_netdev(struct spider_net_card *card)
 
        result = spider_net_set_mac(netdev, &addr);
        if ((result) && (netif_msg_probe(card)))
-               pr_err("Failed to set MAC address: %i\n", result);
+               dev_err(&card->netdev->dev,
+                       "Failed to set MAC address: %i\n", result);
 
        result = register_netdev(netdev);
        if (result) {
                if (netif_msg_probe(card))
-                       pr_err("Couldn't register net_device: %i\n",
-                                 result);
+                       dev_err(&card->netdev->dev,
+                               "Couldn't register net_device: %i\n", result);
                return result;
        }
 
@@ -2363,17 +2461,19 @@ spider_net_setup_pci_dev(struct pci_dev *pdev)
        unsigned long mmio_start, mmio_len;
 
        if (pci_enable_device(pdev)) {
-               pr_err("Couldn't enable PCI device\n");
+               dev_err(&pdev->dev, "Couldn't enable PCI device\n");
                return NULL;
        }
 
        if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
-               pr_err("Couldn't find proper PCI device base address.\n");
+               dev_err(&pdev->dev,
+                       "Couldn't find proper PCI device base address.\n");
                goto out_disable_dev;
        }
 
        if (pci_request_regions(pdev, spider_net_driver_name)) {
-               pr_err("Couldn't obtain PCI resources, aborting.\n");
+               dev_err(&pdev->dev,
+                       "Couldn't obtain PCI resources, aborting.\n");
                goto out_disable_dev;
        }
 
@@ -2381,8 +2481,8 @@ spider_net_setup_pci_dev(struct pci_dev *pdev)
 
        card = spider_net_alloc_card();
        if (!card) {
-               pr_err("Couldn't allocate net_device structure, "
-                         "aborting.\n");
+               dev_err(&pdev->dev,
+                       "Couldn't allocate net_device structure, aborting.\n");
                goto out_release_regions;
        }
        card->pdev = pdev;
@@ -2396,7 +2496,8 @@ spider_net_setup_pci_dev(struct pci_dev *pdev)
        card->regs = ioremap(mmio_start, mmio_len);
 
        if (!card->regs) {
-               pr_err("Couldn't obtain PCI resources, aborting.\n");
+               dev_err(&pdev->dev,
+                       "Couldn't obtain PCI resources, aborting.\n");
                goto out_release_regions;
        }
 
index 1d054aa715049779fde4e9b04fcd68d161e3e2d6..dbbdb8cee3c639c0be5480a161d92b3fb16174e9 100644 (file)
@@ -349,11 +349,23 @@ enum spider_net_int2_status {
 #define SPIDER_NET_GPRDAT_MASK                 0x0000ffff
 
 #define SPIDER_NET_DMAC_NOINTR_COMPLETE                0x00800000
-#define SPIDER_NET_DMAC_NOCS                   0x00040000
+#define SPIDER_NET_DMAC_TXFRMTL                0x00040000
 #define SPIDER_NET_DMAC_TCP                    0x00020000
 #define SPIDER_NET_DMAC_UDP                    0x00030000
 #define SPIDER_NET_TXDCEST                     0x08000000
 
+#define SPIDER_NET_DESCR_RXFDIS        0x00000001
+#define SPIDER_NET_DESCR_RXDCEIS       0x00000002
+#define SPIDER_NET_DESCR_RXDEN0IS      0x00000004
+#define SPIDER_NET_DESCR_RXINVDIS      0x00000008
+#define SPIDER_NET_DESCR_RXRERRIS      0x00000010
+#define SPIDER_NET_DESCR_RXFDCIMS      0x00000100
+#define SPIDER_NET_DESCR_RXDCEIMS      0x00000200
+#define SPIDER_NET_DESCR_RXDEN0IMS     0x00000400
+#define SPIDER_NET_DESCR_RXINVDIMS     0x00000800
+#define SPIDER_NET_DESCR_RXRERRMIS     0x00001000
+#define SPIDER_NET_DESCR_UNUSED        0x077fe0e0
+
 #define SPIDER_NET_DESCR_IND_PROC_MASK         0xF0000000
 #define SPIDER_NET_DESCR_COMPLETE              0x00000000 /* used in rx and tx */
 #define SPIDER_NET_DESCR_RESPONSE_ERROR                0x10000000 /* used in rx and tx */
@@ -364,6 +376,13 @@ enum spider_net_int2_status {
 #define SPIDER_NET_DESCR_NOT_IN_USE            0xF0000000
 #define SPIDER_NET_DESCR_TXDESFLG              0x00800000
 
+#define SPIDER_NET_DESCR_BAD_STATUS   (SPIDER_NET_DESCR_RXDEN0IS | \
+                                       SPIDER_NET_DESCR_RXRERRIS | \
+                                       SPIDER_NET_DESCR_RXDEN0IMS | \
+                                       SPIDER_NET_DESCR_RXINVDIMS | \
+                                       SPIDER_NET_DESCR_RXRERRMIS | \
+                                       SPIDER_NET_DESCR_UNUSED)
+
 /* Descriptor, as defined by the hardware */
 struct spider_net_hw_descr {
        u32 buf_addr;
index 786d4b9c07ecac39aab21fa877e8a63144981a1c..8b6478663a56b029c9322cb6cb239f00328cdc7f 100644 (file)
@@ -740,7 +740,7 @@ static int __devinit starfire_init_one(struct pci_dev *pdev,
        pci_set_master(pdev);
 
        /* enable MWI -- it vastly improves Rx performance on sparc64 */
-       pci_set_mwi(pdev);
+       pci_try_set_mwi(pdev);
 
 #ifdef ZEROCOPY
        /* Starfire can do TCP/UDP checksumming */
@@ -1456,7 +1456,7 @@ static int __netdev_rx(struct net_device *dev, int *quota)
                        pci_dma_sync_single_for_cpu(np->pci_dev,
                                                    np->rx_info[entry].mapping,
                                                    pkt_len, PCI_DMA_FROMDEVICE);
-                       eth_copy_and_sum(skb, np->rx_info[entry].skb->data, pkt_len, 0);
+                       skb_copy_to_linear_data(skb, np->rx_info[entry].skb->data, pkt_len);
                        pci_dma_sync_single_for_device(np->pci_dev,
                                                       np->rx_info[entry].mapping,
                                                       pkt_len, PCI_DMA_FROMDEVICE);
index a123ea87893ba8c14098ac37ad322b23bfee5fa9..b77ab6e8fd3576eb7369f14d3981872b4e8ef40c 100644 (file)
@@ -777,7 +777,7 @@ static void sun3_82586_rcv_int(struct net_device *dev)
                                        {
                                                skb_reserve(skb,2);
                                                skb_put(skb,totlen);
-                                               eth_copy_and_sum(skb,(char *) p->base+swab32((unsigned long) rbd->buffer),totlen,0);
+                                               skb_copy_to_linear_data(skb,(char *) p->base+swab32((unsigned long) rbd->buffer),totlen);
                                                skb->protocol=eth_type_trans(skb,dev);
                                                netif_rx(skb);
                                                p->stats.rx_packets++;
index 791e081fdc15be965a914707bfdda01671b586c3..f1548c033327d9a3ae3d9c50438de721d7663906 100644 (file)
@@ -853,10 +853,9 @@ static int lance_rx( struct net_device *dev )
 
                                skb_reserve( skb, 2 );  /* 16 byte align */
                                skb_put( skb, pkt_len );        /* Make room */
-//                             skb_copy_to_linear_data(skb, PKTBUF_ADDR(head), pkt_len);
-                               eth_copy_and_sum(skb,
+                               skb_copy_to_linear_data(skb,
                                                 PKTBUF_ADDR(head),
-                                                pkt_len, 0);
+                                                pkt_len);
 
                                skb->protocol = eth_type_trans( skb, dev );
                                netif_rx( skb );
index 2ad8d58dee3b5bb8049f10bab5453e084d0055e5..b3e0158def4ff9f6021b72b4d25000e61176a060 100644 (file)
@@ -860,7 +860,7 @@ static void bigmac_rx(struct bigmac *bp)
                        sbus_dma_sync_single_for_cpu(bp->bigmac_sdev,
                                                     this->rx_addr, len,
                                                     SBUS_DMA_FROMDEVICE);
-                       eth_copy_and_sum(copy_skb, (unsigned char *)skb->data, len, 0);
+                       skb_copy_to_linear_data(copy_skb, (unsigned char *)skb->data, len);
                        sbus_dma_sync_single_for_device(bp->bigmac_sdev,
                                                        this->rx_addr, len,
                                                        SBUS_DMA_FROMDEVICE);
index e1f912d04043e82c3de70201ed87d0ceb7b097f2..af0c9831074c62c4c9d14d4fad624fcd81bd0391 100644 (file)
@@ -397,7 +397,6 @@ struct netdev_private {
        unsigned char phys[MII_CNT];            /* MII device addresses, only first one used. */
        struct pci_dev *pci_dev;
        void __iomem *base;
-       unsigned char pci_rev_id;
 };
 
 /* The station address location in the EEPROM. */
@@ -544,8 +543,6 @@ static int __devinit sundance_probe1 (struct pci_dev *pdev,
        dev->change_mtu = &change_mtu;
        pci_set_drvdata(pdev, dev);
 
-       pci_read_config_byte(pdev, PCI_REVISION_ID, &np->pci_rev_id);
-
        i = register_netdev(dev);
        if (i)
                goto err_out_unmap_rx;
@@ -828,7 +825,7 @@ static int netdev_open(struct net_device *dev)
        iowrite8(100, ioaddr + RxDMAPollPeriod);
        iowrite8(127, ioaddr + TxDMAPollPeriod);
        /* Fix DFE-580TX packet drop issue */
-       if (np->pci_rev_id >= 0x14)
+       if (np->pci_dev->revision >= 0x14)
                iowrite8(0x01, ioaddr + DebugCtrl1);
        netif_start_queue(dev);
 
@@ -1194,7 +1191,7 @@ static irqreturn_t intr_handler(int irq, void *dev_instance)
                        hw_frame_id = ioread8(ioaddr + TxFrameId);
                }
 
-               if (np->pci_rev_id >= 0x14) {
+               if (np->pci_dev->revision >= 0x14) {
                        spin_lock(&np->lock);
                        for (; np->cur_tx - np->dirty_tx > 0; np->dirty_tx++) {
                                int entry = np->dirty_tx % TX_RING_SIZE;
@@ -1313,7 +1310,7 @@ static void rx_poll(unsigned long data)
                                                            np->rx_buf_sz,
                                                            PCI_DMA_FROMDEVICE);
 
-                               eth_copy_and_sum(skb, np->rx_skbuff[entry]->data, pkt_len, 0);
+                               skb_copy_to_linear_data(skb, np->rx_skbuff[entry]->data, pkt_len);
                                pci_dma_sync_single_for_device(np->pci_dev,
                                                               desc->frag[0].addr,
                                                               np->rx_buf_sz,
index 51c3fe2108a36a81c3ac285d8ff2d66c4eb1623a..8b35f13318ea4b9e02b87644ed955a897985219d 100644 (file)
@@ -2625,7 +2625,7 @@ static void quattro_sbus_free_irqs(void)
 #endif /* CONFIG_SBUS */
 
 #ifdef CONFIG_PCI
-static struct quattro * __init quattro_pci_find(struct pci_dev *pdev)
+static struct quattro * __devinit quattro_pci_find(struct pci_dev *pdev)
 {
        struct pci_dev *bdev = pdev->bus->self;
        struct quattro *qp;
@@ -3095,12 +3095,8 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev,
 
 #ifdef CONFIG_SPARC
        hp->hm_revision = of_getintprop_default(dp, "hm-rev", 0xff);
-       if (hp->hm_revision == 0xff) {
-               unsigned char prev;
-
-               pci_read_config_byte(pdev, PCI_REVISION_ID, &prev);
-               hp->hm_revision = 0xc0 | (prev & 0x0f);
-       }
+       if (hp->hm_revision == 0xff)
+               hp->hm_revision = 0xc0 | (pdev->revision & 0x0f);
 #else
        /* works with this on non-sparc hosts */
        hp->hm_revision = 0x20;
index 42722530ab24501f4ca647ea0b702f33557728e4..053b7cb0d94406fb8b3b30b3a21cf51d4494be7e 100644 (file)
@@ -549,9 +549,9 @@ static void lance_rx_dvma(struct net_device *dev)
 
                        skb_reserve(skb, 2);            /* 16 byte align */
                        skb_put(skb, len);              /* make room */
-                       eth_copy_and_sum(skb,
+                       skb_copy_to_linear_data(skb,
                                         (unsigned char *)&(ib->rx_buf [entry][0]),
-                                        len, 0);
+                                        len);
                        skb->protocol = eth_type_trans(skb, dev);
                        netif_rx(skb);
                        dev->last_rx = jiffies;
index fa70e0b78af72d3c6ba4e5051bf95ad47273dad4..1b65ae8a1c7c6e3ef778d727fc6f0be83c40c9b3 100644 (file)
@@ -439,8 +439,8 @@ static void qe_rx(struct sunqe *qep)
                        } else {
                                skb_reserve(skb, 2);
                                skb_put(skb, len);
-                               eth_copy_and_sum(skb, (unsigned char *) this_qbuf,
-                                                len, 0);
+                               skb_copy_to_linear_data(skb, (unsigned char *) this_qbuf,
+                                                len);
                                skb->protocol = eth_type_trans(skb, qep->dev);
                                netif_rx(skb);
                                qep->dev->last_rx = jiffies;
index 463d600ed83d88a1f656430ac980537ddc6d8846..75655add3f34be4ee0cd6f58f2293fe827775c3c 100644 (file)
@@ -23,9 +23,9 @@
  */
 
 #ifdef TC35815_NAPI
-#define DRV_VERSION    "1.35-NAPI"
+#define DRV_VERSION    "1.36-NAPI"
 #else
-#define DRV_VERSION    "1.35"
+#define DRV_VERSION    "1.36"
 #endif
 static const char *version = "tc35815.c:v" DRV_VERSION "\n";
 #define MODNAME                        "tc35815"
@@ -49,6 +49,7 @@ static const char *version = "tc35815.c:v" DRV_VERSION "\n";
 #include <linux/pci.h>
 #include <linux/mii.h>
 #include <linux/ethtool.h>
+#include <linux/platform_device.h>
 #include <asm/io.h>
 #include <asm/byteorder.h>
 
@@ -597,13 +598,46 @@ static int tc_mdio_read(struct net_device *dev, int phy_id, int location);
 static void tc_mdio_write(struct net_device *dev, int phy_id, int location,
                          int val);
 
-static void __devinit tc35815_init_dev_addr (struct net_device *dev)
+#ifdef CONFIG_CPU_TX49XX
+/*
+ * Find a platform_device providing a MAC address.  The platform code
+ * should provide a "tc35815-mac" device with a MAC address in its
+ * platform_data.
+ */
+static int __devinit tc35815_mac_match(struct device *dev, void *data)
+{
+       struct platform_device *plat_dev = to_platform_device(dev);
+       struct pci_dev *pci_dev = data;
+       unsigned int id = (pci_dev->bus->number << 8) | pci_dev->devfn;
+       return !strcmp(plat_dev->name, "tc35815-mac") && plat_dev->id == id;
+}
+
+static int __devinit tc35815_read_plat_dev_addr(struct net_device *dev)
+{
+       struct tc35815_local *lp = dev->priv;
+       struct device *pd = bus_find_device(&platform_bus_type, NULL,
+                                           lp->pci_dev, tc35815_mac_match);
+       if (pd) {
+               if (pd->platform_data)
+                       memcpy(dev->dev_addr, pd->platform_data, ETH_ALEN);
+               put_device(pd);
+               return is_valid_ether_addr(dev->dev_addr) ? 0 : -ENODEV;
+       }
+       return -ENODEV;
+}
+#else
+static int __devinit tc35815_read_plat_dev_addr(struct device *dev)
+{
+       return -ENODEV;
+}
+#endif
+
+static int __devinit tc35815_init_dev_addr (struct net_device *dev)
 {
        struct tc35815_regs __iomem *tr =
                (struct tc35815_regs __iomem *)dev->base_addr;
        int i;
 
-       /* dev_addr will be overwritten on NETDEV_REGISTER event */
        while (tc_readl(&tr->PROM_Ctl) & PROM_Busy)
                ;
        for (i = 0; i < 6; i += 2) {
@@ -615,6 +649,9 @@ static void __devinit tc35815_init_dev_addr (struct net_device *dev)
                dev->dev_addr[i] = data & 0xff;
                dev->dev_addr[i+1] = data >> 8;
        }
+       if (!is_valid_ether_addr(dev->dev_addr))
+               return tc35815_read_plat_dev_addr(dev);
+       return 0;
 }
 
 static int __devinit tc35815_init_one (struct pci_dev *pdev,
@@ -724,7 +761,10 @@ static int __devinit tc35815_init_one (struct pci_dev *pdev,
        tc35815_chip_reset(dev);
 
        /* Retrieve the ethernet address. */
-       tc35815_init_dev_addr(dev);
+       if (tc35815_init_dev_addr(dev)) {
+               dev_warn(&pdev->dev, "not valid ether addr\n");
+               random_ether_addr(dev->dev_addr);
+       }
 
        rc = register_netdev (dev);
        if (rc)
index 2f3184184ad9b201c82d5c38260de72d4a5f2d6a..32e4037dcb50a3ec73961e2021cac643b9f21034 100644 (file)
@@ -64,8 +64,8 @@
 
 #define DRV_MODULE_NAME                "tg3"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "3.77"
-#define DRV_MODULE_RELDATE     "May 31, 2007"
+#define DRV_MODULE_VERSION     "3.78"
+#define DRV_MODULE_RELDATE     "July 11, 2007"
 
 #define TG3_DEF_MAC_MODE       0
 #define TG3_DEF_RX_MODE                0
@@ -721,6 +721,44 @@ static int tg3_writephy(struct tg3 *tp, int reg, u32 val)
        return ret;
 }
 
+static void tg3_phy_toggle_automdix(struct tg3 *tp, int enable)
+{
+       u32 phy;
+
+       if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ||
+           (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES))
+               return;
+
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+               u32 ephy;
+
+               if (!tg3_readphy(tp, MII_TG3_EPHY_TEST, &ephy)) {
+                       tg3_writephy(tp, MII_TG3_EPHY_TEST,
+                                    ephy | MII_TG3_EPHY_SHADOW_EN);
+                       if (!tg3_readphy(tp, MII_TG3_EPHYTST_MISCCTRL, &phy)) {
+                               if (enable)
+                                       phy |= MII_TG3_EPHYTST_MISCCTRL_MDIX;
+                               else
+                                       phy &= ~MII_TG3_EPHYTST_MISCCTRL_MDIX;
+                               tg3_writephy(tp, MII_TG3_EPHYTST_MISCCTRL, phy);
+                       }
+                       tg3_writephy(tp, MII_TG3_EPHY_TEST, ephy);
+               }
+       } else {
+               phy = MII_TG3_AUXCTL_MISC_RDSEL_MISC |
+                     MII_TG3_AUXCTL_SHDWSEL_MISC;
+               if (!tg3_writephy(tp, MII_TG3_AUX_CTRL, phy) &&
+                   !tg3_readphy(tp, MII_TG3_AUX_CTRL, &phy)) {
+                       if (enable)
+                               phy |= MII_TG3_AUXCTL_MISC_FORCE_AMDIX;
+                       else
+                               phy &= ~MII_TG3_AUXCTL_MISC_FORCE_AMDIX;
+                       phy |= MII_TG3_AUXCTL_MISC_WREN;
+                       tg3_writephy(tp, MII_TG3_AUX_CTRL, phy);
+               }
+       }
+}
+
 static void tg3_phy_set_wirespeed(struct tg3 *tp)
 {
        u32 val;
@@ -1045,23 +1083,11 @@ out:
        }
 
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
-               u32 phy_reg;
-
                /* adjust output voltage */
                tg3_writephy(tp, MII_TG3_EPHY_PTEST, 0x12);
-
-               if (!tg3_readphy(tp, MII_TG3_EPHY_TEST, &phy_reg)) {
-                       u32 phy_reg2;
-
-                       tg3_writephy(tp, MII_TG3_EPHY_TEST,
-                                    phy_reg | MII_TG3_EPHY_SHADOW_EN);
-                       /* Enable auto-MDIX */
-                       if (!tg3_readphy(tp, 0x10, &phy_reg2))
-                               tg3_writephy(tp, 0x10, phy_reg2 | 0x4000);
-                       tg3_writephy(tp, MII_TG3_EPHY_TEST, phy_reg);
-               }
        }
 
+       tg3_phy_toggle_automdix(tp, 1);
        tg3_phy_set_wirespeed(tp);
        return 0;
 }
@@ -1162,6 +1188,19 @@ static void tg3_frob_aux_power(struct tg3 *tp)
        }
 }
 
+static int tg3_5700_link_polarity(struct tg3 *tp, u32 speed)
+{
+       if (tp->led_ctrl == LED_CTRL_MODE_PHY_2)
+               return 1;
+       else if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5411) {
+               if (speed != SPEED_10)
+                       return 1;
+       } else if (speed == SPEED_10)
+               return 1;
+
+       return 0;
+}
+
 static int tg3_setup_phy(struct tg3 *, int);
 
 #define RESET_KIND_SHUTDOWN    0
@@ -1320,9 +1359,17 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
                        else
                                mac_mode = MAC_MODE_PORT_MODE_MII;
 
-                       if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 ||
-                           !(tp->tg3_flags & TG3_FLAG_WOL_SPEED_100MB))
-                               mac_mode |= MAC_MODE_LINK_POLARITY;
+                       mac_mode |= tp->mac_mode & MAC_MODE_LINK_POLARITY;
+                       if (GET_ASIC_REV(tp->pci_chip_rev_id) ==
+                           ASIC_REV_5700) {
+                               u32 speed = (tp->tg3_flags &
+                                            TG3_FLAG_WOL_SPEED_100MB) ?
+                                            SPEED_100 : SPEED_10;
+                               if (tg3_5700_link_polarity(tp, speed))
+                                       mac_mode |= MAC_MODE_LINK_POLARITY;
+                               else
+                                       mac_mode &= ~MAC_MODE_LINK_POLARITY;
+                       }
                } else {
                        mac_mode = MAC_MODE_PORT_MODE_TBI;
                }
@@ -1990,15 +2037,12 @@ relink:
        if (tp->link_config.active_duplex == DUPLEX_HALF)
                tp->mac_mode |= MAC_MODE_HALF_DUPLEX;
 
-       tp->mac_mode &= ~MAC_MODE_LINK_POLARITY;
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) {
-               if ((tp->led_ctrl == LED_CTRL_MODE_PHY_2) ||
-                   (current_link_up == 1 &&
-                    tp->link_config.active_speed == SPEED_10))
-                       tp->mac_mode |= MAC_MODE_LINK_POLARITY;
-       } else {
-               if (current_link_up == 1)
+               if (current_link_up == 1 &&
+                   tg3_5700_link_polarity(tp, tp->link_config.active_speed))
                        tp->mac_mode |= MAC_MODE_LINK_POLARITY;
+               else
+                       tp->mac_mode &= ~MAC_MODE_LINK_POLARITY;
        }
 
        /* ??? Without this setting Netgear GA302T PHY does not
@@ -2639,6 +2683,9 @@ static int tg3_setup_fiber_by_hand(struct tg3 *tp, u32 mac_status)
 
                tw32_f(MAC_MODE, (tp->mac_mode | MAC_MODE_SEND_CONFIGS));
                udelay(40);
+
+               tw32_f(MAC_MODE, tp->mac_mode);
+               udelay(40);
        }
 
 out:
@@ -2698,10 +2745,6 @@ static int tg3_setup_fiber_phy(struct tg3 *tp, int force_reset)
        else
                current_link_up = tg3_setup_fiber_by_hand(tp, mac_status);
 
-       tp->mac_mode &= ~MAC_MODE_LINK_POLARITY;
-       tw32_f(MAC_MODE, tp->mac_mode);
-       udelay(40);
-
        tp->hw_status->status =
                (SD_STATUS_UPDATED |
                 (tp->hw_status->status & ~SD_STATUS_LINK_CHG));
@@ -3512,9 +3555,9 @@ static inline int tg3_irq_sync(struct tg3 *tp)
  */
 static inline void tg3_full_lock(struct tg3 *tp, int irq_sync)
 {
+       spin_lock_bh(&tp->lock);
        if (irq_sync)
                tg3_irq_quiesce(tp);
-       spin_lock_bh(&tp->lock);
 }
 
 static inline void tg3_full_unlock(struct tg3 *tp)
@@ -6444,6 +6487,10 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 
        tp->mac_mode = MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE |
                MAC_MODE_TDE_ENABLE | MAC_MODE_RDE_ENABLE | MAC_MODE_FHDE_ENABLE;
+       if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
+           !(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) &&
+           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700)
+               tp->mac_mode |= MAC_MODE_LINK_POLARITY;
        tw32_f(MAC_MODE, tp->mac_mode | MAC_MODE_RXSTAT_CLEAR | MAC_MODE_TXSTAT_CLEAR);
        udelay(40);
 
@@ -8805,7 +8852,9 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
                        return 0;
 
                mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) |
-                          MAC_MODE_PORT_INT_LPBACK | MAC_MODE_LINK_POLARITY;
+                          MAC_MODE_PORT_INT_LPBACK;
+               if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+                       mac_mode |= MAC_MODE_LINK_POLARITY;
                if (tp->tg3_flags & TG3_FLAG_10_100_ONLY)
                        mac_mode |= MAC_MODE_PORT_MODE_MII;
                else
@@ -8824,19 +8873,18 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
                                             phytest | MII_TG3_EPHY_SHADOW_EN);
                                if (!tg3_readphy(tp, 0x1b, &phy))
                                        tg3_writephy(tp, 0x1b, phy & ~0x20);
-                               if (!tg3_readphy(tp, 0x10, &phy))
-                                       tg3_writephy(tp, 0x10, phy & ~0x4000);
                                tg3_writephy(tp, MII_TG3_EPHY_TEST, phytest);
                        }
                        val = BMCR_LOOPBACK | BMCR_FULLDPLX | BMCR_SPEED100;
                } else
                        val = BMCR_LOOPBACK | BMCR_FULLDPLX | BMCR_SPEED1000;
 
+               tg3_phy_toggle_automdix(tp, 0);
+
                tg3_writephy(tp, MII_BMCR, val);
                udelay(40);
 
-               mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) |
-                          MAC_MODE_LINK_POLARITY;
+               mac_mode = tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK;
                if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
                        tg3_writephy(tp, MII_TG3_EPHY_PTEST, 0x1800);
                        mac_mode |= MAC_MODE_PORT_MODE_MII;
@@ -8849,8 +8897,11 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
                        udelay(10);
                        tw32_f(MAC_RX_MODE, tp->rx_mode);
                }
-               if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) {
-                       mac_mode &= ~MAC_MODE_LINK_POLARITY;
+               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) {
+                       if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401)
+                               mac_mode &= ~MAC_MODE_LINK_POLARITY;
+                       else if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5411)
+                               mac_mode |= MAC_MODE_LINK_POLARITY;
                        tg3_writephy(tp, MII_TG3_EXT_CTRL,
                                     MII_TG3_EXT_CTRL_LNK3_LED_MODE);
                }
@@ -9116,10 +9167,10 @@ static void tg3_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
        /* Update RX_MODE_KEEP_VLAN_TAG bit in RX_MODE register. */
        __tg3_set_rx_mode(dev);
 
-       tg3_full_unlock(tp);
-
        if (netif_running(dev))
                tg3_netif_start(tp);
+
+       tg3_full_unlock(tp);
 }
 #endif
 
@@ -9410,11 +9461,13 @@ static void __devinit tg3_get_5755_nvram_info(struct tg3 *tp)
                case FLASH_5755VENDOR_ATMEL_FLASH_1:
                case FLASH_5755VENDOR_ATMEL_FLASH_2:
                case FLASH_5755VENDOR_ATMEL_FLASH_3:
+               case FLASH_5755VENDOR_ATMEL_FLASH_5:
                        tp->nvram_jedecnum = JEDEC_ATMEL;
                        tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
                        tp->tg3_flags2 |= TG3_FLG2_FLASH;
                        tp->nvram_pagesize = 264;
-                       if (nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_1)
+                       if (nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_1 ||
+                           nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_5)
                                tp->nvram_size = (protect ? 0x3e200 : 0x80000);
                        else if (nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_2)
                                tp->nvram_size = (protect ? 0x1f200 : 0x40000);
@@ -10498,11 +10551,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                                continue;
                        }
                        if (pci_id->rev != PCI_ANY_ID) {
-                               u8 rev;
-
-                               pci_read_config_byte(bridge, PCI_REVISION_ID,
-                                                    &rev);
-                               if (rev > pci_id->rev)
+                               if (bridge->revision > pci_id->rev)
                                        continue;
                        }
                        if (bridge->subordinate &&
@@ -11944,12 +11993,11 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
         * checksumming.
         */
        if ((tp->tg3_flags & TG3_FLAG_BROKEN_CHECKSUMS) == 0) {
+               dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
                if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
                    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
-                       dev->features |= NETIF_F_HW_CSUM;
-               else
-                       dev->features |= NETIF_F_IP_CSUM;
-               dev->features |= NETIF_F_SG;
+                       dev->features |= NETIF_F_IPV6_CSUM;
+
                tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS;
        } else
                tp->tg3_flags &= ~TG3_FLAG_RX_CHECKSUMS;
index bd9f4f428e5b8895d5cc8c281302e00e0c6bdfba..d84e75e7365d5c6bb7809f3c8557cac57b5d15e1 100644 (file)
 #define  FLASH_5755VENDOR_ATMEL_FLASH_2         0x03400002
 #define  FLASH_5755VENDOR_ATMEL_FLASH_3         0x03400000
 #define  FLASH_5755VENDOR_ATMEL_FLASH_4         0x00000003
+#define  FLASH_5755VENDOR_ATMEL_FLASH_5         0x02000003
 #define  FLASH_5755VENDOR_ATMEL_EEPROM_64KHZ    0x03c00003
 #define  FLASH_5755VENDOR_ATMEL_EEPROM_376KHZ   0x03c00002
 #define  FLASH_5787VENDOR_ATMEL_EEPROM_64KHZ    0x03000003
 
 #define MII_TG3_AUX_CTRL               0x18 /* auxilliary control register */
 
+#define MII_TG3_AUXCTL_MISC_WREN       0x8000
+#define MII_TG3_AUXCTL_MISC_FORCE_AMDIX        0x0200
+#define MII_TG3_AUXCTL_MISC_RDSEL_MISC 0x7000
+#define MII_TG3_AUXCTL_SHDWSEL_MISC            0x0007
+
 #define MII_TG3_AUX_STAT               0x19 /* auxilliary status register */
 #define MII_TG3_AUX_STAT_LPASS         0x0004
 #define MII_TG3_AUX_STAT_SPDMASK       0x0700
 #define MII_TG3_EPHY_TEST              0x1f /* 5906 PHY register */
 #define MII_TG3_EPHY_SHADOW_EN         0x80
 
+#define MII_TG3_EPHYTST_MISCCTRL       0x10 /* 5906 EPHY misc ctrl shadow register */
+#define MII_TG3_EPHYTST_MISCCTRL_MDIX  0x4000
+
 #define MII_TG3_TEST1                  0x1e
 #define MII_TG3_TEST1_TRIM_EN          0x0010
 #define MII_TG3_TEST1_CRC_EN           0x8000
index 106dc1ef0acb95c37e3c8d21f2721858239c8585..74eb12107e6874c0ba101993a48f1f44094dc34a 100644 (file)
@@ -533,7 +533,6 @@ static int __devinit TLan_probe1(struct pci_dev *pdev,
 
        struct net_device  *dev;
        TLanPrivateInfo    *priv;
-       u8                 pci_rev;
        u16                device_id;
        int                reg, rc = -ENODEV;
 
@@ -577,8 +576,6 @@ static int __devinit TLan_probe1(struct pci_dev *pdev,
                        goto err_out_free_dev;
                }
 
-               pci_read_config_byte ( pdev, PCI_REVISION_ID, &pci_rev);
-
                for ( reg= 0; reg <= 5; reg ++ ) {
                        if (pci_resource_flags(pdev, reg) & IORESOURCE_IO) {
                                pci_io_base = pci_resource_start(pdev, reg);
@@ -595,7 +592,7 @@ static int __devinit TLan_probe1(struct pci_dev *pdev,
 
                dev->base_addr = pci_io_base;
                dev->irq = pdev->irq;
-               priv->adapterRev = pci_rev;
+               priv->adapterRev = pdev->revision;
                pci_set_master(pdev);
                pci_set_drvdata(pdev, dev);
 
index e22a3f5333ef40b25f7b694b79a300f310eb80b9..9f1b6ab9c228485d5d5cdc3e1b62461e597e9bdc 100644 (file)
@@ -363,7 +363,7 @@ static int __devinit xl_probe(struct pci_dev *pdev,
 }
 
 
-static int __init xl_init(struct net_device *dev) 
+static int __devinit xl_init(struct net_device *dev) 
 {
        struct xl_private *xl_priv = (struct xl_private *)dev->priv ;
 
index 8c9634a98c111f92aee2cf674e7a856de3dd48a1..1c537d5a30627bbeef1b8aebbd84692a3e08facf 100644 (file)
@@ -2,17 +2,17 @@
 # Tulip family network device configuration
 #
 
-menu "Tulip family network device support"
-       depends on NET_ETHERNET && (PCI || EISA || CARDBUS)
-
-config NET_TULIP
+menuconfig NET_TULIP
        bool "\"Tulip\" family network device support"
+       depends on PCI || EISA || CARDBUS
        help
          This selects the "Tulip" family of EISA/PCI network cards.
 
+if NET_TULIP
+
 config DE2104X
        tristate "Early DECchip Tulip (dc2104x) PCI support (EXPERIMENTAL)"
-       depends on NET_TULIP && PCI && EXPERIMENTAL
+       depends on PCI && EXPERIMENTAL
        select CRC32
        ---help---
          This driver is developed for the SMC EtherPower series Ethernet
@@ -30,7 +30,7 @@ config DE2104X
 
 config TULIP
        tristate "DECchip Tulip (dc2114x) PCI support"
-       depends on NET_TULIP && PCI
+       depends on PCI
        select CRC32
        ---help---
          This driver is developed for the SMC EtherPower series Ethernet
@@ -95,7 +95,7 @@ config TULIP_NAPI_HW_MITIGATION
 
 config DE4X5
        tristate "Generic DECchip & DIGITAL EtherWORKS PCI/EISA"
-       depends on NET_TULIP && (PCI || EISA)
+       depends on PCI || EISA
        select CRC32
        ---help---
          This is support for the DIGITAL series of PCI/EISA Ethernet cards.
@@ -112,7 +112,7 @@ config DE4X5
 
 config WINBOND_840
        tristate "Winbond W89c840 Ethernet support"
-       depends on NET_TULIP && PCI
+       depends on PCI
        select CRC32
        select MII
        help
@@ -123,7 +123,7 @@ config WINBOND_840
 
 config DM9102
        tristate "Davicom DM910x/DM980x support"
-       depends on NET_TULIP && PCI
+       depends on PCI
        select CRC32
        ---help---
          This driver is for DM9102(A)/DM9132/DM9801 compatible PCI cards from
@@ -137,7 +137,7 @@ config DM9102
 
 config ULI526X
        tristate "ULi M526x controller support"
-       depends on NET_TULIP && PCI
+       depends on PCI
        select CRC32
        ---help---
          This driver is for ULi M5261/M5263 10/100M Ethernet Controller
@@ -149,7 +149,7 @@ config ULI526X
          
 config PCMCIA_XIRCOM
        tristate "Xircom CardBus support (new driver)"
-       depends on NET_TULIP && CARDBUS
+       depends on CARDBUS
        ---help---
          This driver is for the Digital "Tulip" Ethernet CardBus adapters.
          It should work with most DEC 21*4*-based chips/ethercards, as well
@@ -162,7 +162,7 @@ config PCMCIA_XIRCOM
 
 config PCMCIA_XIRTULIP
        tristate "Xircom Tulip-like CardBus support (old driver)"
-       depends on NET_TULIP && CARDBUS && BROKEN_ON_SMP
+       depends on CARDBUS && BROKEN_ON_SMP
        select CRC32
        ---help---
          This driver is for the Digital "Tulip" Ethernet CardBus adapters.
@@ -174,5 +174,4 @@ config PCMCIA_XIRTULIP
          <file:Documentation/networking/net-modules.txt>.  The module will
          be called xircom_tulip_cb.  If unsure, say N.
 
-endmenu
-
+endif # NET_TULIP
index 861729806dc19cb3a0c6a9a6ad0480fe20dc22ef..d380e0b3f05a1fe0925eaee771b37e324dc08d70 100644 (file)
@@ -785,7 +785,6 @@ static void __de_set_rx_mode (struct net_device *dev)
 
        de->tx_head = NEXT_TX(entry);
 
-       BUG_ON(TX_BUFFS_AVAIL(de) < 0);
        if (TX_BUFFS_AVAIL(de) == 0)
                netif_stop_queue(dev);
 
index 62143f92c23136110cef20c248b48b0ddbc92b7d..09902891a6e6549541a3a0d1e904cfe9df51e53f 100644 (file)
@@ -597,7 +597,7 @@ static char *args;
 #endif
 
 struct parameters {
-    int fdx;
+    bool fdx;
     int autosense;
 };
 
@@ -809,10 +809,10 @@ struct de4x5_private {
     s32  irq_en;                            /* Summary interrupt bits       */
     int  media;                             /* Media (eg TP), mode (eg 100B)*/
     int  c_media;                           /* Remember the last media conn */
-    int  fdx;                               /* media full duplex flag       */
+    bool fdx;                               /* media full duplex flag       */
     int  linkOK;                            /* Link is OK                   */
     int  autosense;                         /* Allow/disallow autosensing   */
-    int  tx_enable;                         /* Enable descriptor polling    */
+    bool tx_enable;                         /* Enable descriptor polling    */
     int  setup_f;                           /* Setup frame filtering type   */
     int  local_state;                       /* State within a 'media' state */
     struct mii_phy phy[DE4X5_MAX_PHY];      /* List of attached PHY devices */
@@ -838,8 +838,8 @@ struct de4x5_private {
     struct de4x5_srom srom;                 /* A copy of the SROM           */
     int cfrv;                              /* Card CFRV copy */
     int rx_ovf;                             /* Check for 'RX overflow' tag  */
-    int useSROM;                            /* For non-DEC card use SROM    */
-    int useMII;                             /* Infoblock using the MII      */
+    bool useSROM;                           /* For non-DEC card use SROM    */
+    bool useMII;                            /* Infoblock using the MII      */
     int asBitValid;                         /* Autosense bits in GEP?       */
     int asPolarity;                         /* 0 => asserted high           */
     int asBit;                              /* Autosense bit number in GEP  */
@@ -928,7 +928,7 @@ static int     dc21040_state(struct net_device *dev, int csr13, int csr14, int c
 static int     test_media(struct net_device *dev, s32 irqs, s32 irq_mask, s32 csr13, s32 csr14, s32 csr15, s32 msec);
 static int     test_for_100Mb(struct net_device *dev, int msec);
 static int     wait_for_link(struct net_device *dev);
-static int     test_mii_reg(struct net_device *dev, int reg, int mask, int pol, long msec);
+static int     test_mii_reg(struct net_device *dev, int reg, int mask, bool pol, long msec);
 static int     is_spd_100(struct net_device *dev);
 static int     is_100_up(struct net_device *dev);
 static int     is_10_up(struct net_device *dev);
@@ -1109,7 +1109,7 @@ de4x5_hw_init(struct net_device *dev, u_long iobase, struct device *gendev)
     /*
     ** Now find out what kind of DC21040/DC21041/DC21140 board we have.
     */
-    lp->useSROM = FALSE;
+    lp->useSROM = false;
     if (lp->bus == PCI) {
        PCI_signature(name, lp);
     } else {
@@ -1137,7 +1137,7 @@ de4x5_hw_init(struct net_device *dev, u_long iobase, struct device *gendev)
        lp->cache.gepc = GEP_INIT;
        lp->asBit = GEP_SLNK;
        lp->asPolarity = GEP_SLNK;
-       lp->asBitValid = TRUE;
+       lp->asBitValid = ~0;
        lp->timeout = -1;
        lp->gendev = gendev;
        spin_lock_init(&lp->lock);
@@ -1463,7 +1463,7 @@ de4x5_queue_pkt(struct sk_buff *skb, struct net_device *dev)
     u_long flags = 0;
 
     netif_stop_queue(dev);
-    if (lp->tx_enable == NO) {                   /* Cannot send for now */
+    if (!lp->tx_enable) {                   /* Cannot send for now */
        return -1;
     }
 
@@ -2134,7 +2134,7 @@ srom_search(struct net_device *dev, struct pci_dev *pdev)
     u_short vendor, status;
     u_int irq = 0, device;
     u_long iobase = 0;                     /* Clear upper 32 bits in Alphas */
-    int i, j, cfrv;
+    int i, j;
     struct de4x5_private *lp = netdev_priv(dev);
     struct list_head *walk;
 
@@ -2150,7 +2150,6 @@ srom_search(struct net_device *dev, struct pci_dev *pdev)
 
        /* Get the chip configuration revision register */
        pb = this_dev->bus->number;
-       pci_read_config_dword(this_dev, PCI_REVISION_ID, &cfrv);
 
        /* Set the device number information */
        lp->device = PCI_SLOT(this_dev->devfn);
@@ -2158,7 +2157,8 @@ srom_search(struct net_device *dev, struct pci_dev *pdev)
 
        /* Set the chipset information */
        if (is_DC2114x) {
-           device = ((cfrv & CFRV_RN) < DC2114x_BRK ? DC21142 : DC21143);
+           device = ((this_dev->revision & CFRV_RN) < DC2114x_BRK
+                     ? DC21142 : DC21143);
        }
        lp->chipset = device;
 
@@ -2254,7 +2254,7 @@ static int __devinit de4x5_pci_probe (struct pci_dev *pdev,
        }
 
        /* Get the chip configuration revision register */
-       pci_read_config_dword(pdev, PCI_REVISION_ID, &lp->cfrv);
+       lp->cfrv = pdev->revision;
 
        /* Set the device number information */
        lp->device = dev_num;
@@ -2424,7 +2424,7 @@ dc21040_autoconf(struct net_device *dev)
     switch (lp->media) {
     case INIT:
        DISABLE_IRQs;
-       lp->tx_enable = NO;
+       lp->tx_enable = false;
        lp->timeout = -1;
        de4x5_save_skbs(dev);
        if ((lp->autosense == AUTO) || (lp->autosense == TP)) {
@@ -2477,7 +2477,7 @@ dc21040_autoconf(struct net_device *dev)
            lp->c_media = lp->media;
        }
        lp->media = INIT;
-       lp->tx_enable = NO;
+       lp->tx_enable = false;
        break;
     }
 
@@ -2578,7 +2578,7 @@ dc21041_autoconf(struct net_device *dev)
     switch (lp->media) {
     case INIT:
        DISABLE_IRQs;
-       lp->tx_enable = NO;
+       lp->tx_enable = false;
        lp->timeout = -1;
        de4x5_save_skbs(dev);          /* Save non transmitted skb's */
        if ((lp->autosense == AUTO) || (lp->autosense == TP_NW)) {
@@ -2757,7 +2757,7 @@ dc21041_autoconf(struct net_device *dev)
            lp->c_media = lp->media;
        }
        lp->media = INIT;
-       lp->tx_enable = NO;
+       lp->tx_enable = false;
        break;
     }
 
@@ -2781,7 +2781,7 @@ dc21140m_autoconf(struct net_device *dev)
     case INIT:
         if (lp->timeout < 0) {
            DISABLE_IRQs;
-           lp->tx_enable = FALSE;
+           lp->tx_enable = false;
            lp->linkOK = 0;
            de4x5_save_skbs(dev);          /* Save non transmitted skb's */
        }
@@ -2830,7 +2830,7 @@ dc21140m_autoconf(struct net_device *dev)
            if (lp->timeout < 0) {
                mii_wr(MII_CR_ASSE | MII_CR_RAN, MII_CR, lp->phy[lp->active].addr, DE4X5_MII);
            }
-           cr = test_mii_reg(dev, MII_CR, MII_CR_RAN, FALSE, 500);
+           cr = test_mii_reg(dev, MII_CR, MII_CR_RAN, false, 500);
            if (cr < 0) {
                next_tick = cr & ~TIMER_CB;
            } else {
@@ -2845,7 +2845,7 @@ dc21140m_autoconf(struct net_device *dev)
            break;
 
        case 1:
-           if ((sr=test_mii_reg(dev, MII_SR, MII_SR_ASSC, TRUE, 2000)) < 0) {
+           if ((sr=test_mii_reg(dev, MII_SR, MII_SR_ASSC, true, 2000)) < 0) {
                next_tick = sr & ~TIMER_CB;
            } else {
                lp->media = SPD_DET;
@@ -2857,10 +2857,10 @@ dc21140m_autoconf(struct net_device *dev)
                    if (!(anlpa & MII_ANLPA_RF) &&
                         (cap = anlpa & MII_ANLPA_TAF & ana)) {
                        if (cap & MII_ANA_100M) {
-                           lp->fdx = ((ana & anlpa & MII_ANA_FDAM & MII_ANA_100M) ? TRUE : FALSE);
+                           lp->fdx = (ana & anlpa & MII_ANA_FDAM & MII_ANA_100M) != 0;
                            lp->media = _100Mb;
                        } else if (cap & MII_ANA_10M) {
-                           lp->fdx = ((ana & anlpa & MII_ANA_FDAM & MII_ANA_10M) ? TRUE : FALSE);
+                           lp->fdx = (ana & anlpa & MII_ANA_FDAM & MII_ANA_10M) != 0;
 
                            lp->media = _10Mb;
                        }
@@ -2932,7 +2932,7 @@ dc21140m_autoconf(struct net_device *dev)
            lp->c_media = lp->media;
        }
        lp->media = INIT;
-       lp->tx_enable = FALSE;
+       lp->tx_enable = false;
        break;
     }
 
@@ -2965,7 +2965,7 @@ dc2114x_autoconf(struct net_device *dev)
     case INIT:
         if (lp->timeout < 0) {
            DISABLE_IRQs;
-           lp->tx_enable = FALSE;
+           lp->tx_enable = false;
            lp->linkOK = 0;
             lp->timeout = -1;
            de4x5_save_skbs(dev);            /* Save non transmitted skb's */
@@ -3013,7 +3013,7 @@ dc2114x_autoconf(struct net_device *dev)
            if (lp->timeout < 0) {
                mii_wr(MII_CR_ASSE | MII_CR_RAN, MII_CR, lp->phy[lp->active].addr, DE4X5_MII);
            }
-           cr = test_mii_reg(dev, MII_CR, MII_CR_RAN, FALSE, 500);
+           cr = test_mii_reg(dev, MII_CR, MII_CR_RAN, false, 500);
            if (cr < 0) {
                next_tick = cr & ~TIMER_CB;
            } else {
@@ -3028,7 +3028,8 @@ dc2114x_autoconf(struct net_device *dev)
            break;
 
        case 1:
-           if ((sr=test_mii_reg(dev, MII_SR, MII_SR_ASSC, TRUE, 2000)) < 0) {
+           sr = test_mii_reg(dev, MII_SR, MII_SR_ASSC, true, 2000);
+           if (sr < 0) {
                next_tick = sr & ~TIMER_CB;
            } else {
                lp->media = SPD_DET;
@@ -3040,10 +3041,10 @@ dc2114x_autoconf(struct net_device *dev)
                    if (!(anlpa & MII_ANLPA_RF) &&
                         (cap = anlpa & MII_ANLPA_TAF & ana)) {
                        if (cap & MII_ANA_100M) {
-                           lp->fdx = ((ana & anlpa & MII_ANA_FDAM & MII_ANA_100M) ? TRUE : FALSE);
+                           lp->fdx = (ana & anlpa & MII_ANA_FDAM & MII_ANA_100M) != 0;
                            lp->media = _100Mb;
                        } else if (cap & MII_ANA_10M) {
-                           lp->fdx = ((ana & anlpa & MII_ANA_FDAM & MII_ANA_10M) ? TRUE : FALSE);
+                           lp->fdx = (ana & anlpa & MII_ANA_FDAM & MII_ANA_10M) != 0;
                            lp->media = _10Mb;
                        }
                    }
@@ -3222,14 +3223,14 @@ srom_map_media(struct net_device *dev)
 {
     struct de4x5_private *lp = netdev_priv(dev);
 
-    lp->fdx = 0;
+    lp->fdx = false;
     if (lp->infoblock_media == lp->media)
       return 0;
 
     switch(lp->infoblock_media) {
       case SROM_10BASETF:
        if (!lp->params.fdx) return -1;
-       lp->fdx = TRUE;
+       lp->fdx = true;
       case SROM_10BASET:
        if (lp->params.fdx && !lp->fdx) return -1;
        if ((lp->chipset == DC21140) || ((lp->chipset & ~0x00ff) == DC2114x)) {
@@ -3249,7 +3250,7 @@ srom_map_media(struct net_device *dev)
 
       case SROM_100BASETF:
         if (!lp->params.fdx) return -1;
-       lp->fdx = TRUE;
+       lp->fdx = true;
       case SROM_100BASET:
        if (lp->params.fdx && !lp->fdx) return -1;
        lp->media = _100Mb;
@@ -3261,7 +3262,7 @@ srom_map_media(struct net_device *dev)
 
       case SROM_100BASEFF:
        if (!lp->params.fdx) return -1;
-       lp->fdx = TRUE;
+       lp->fdx = true;
       case SROM_100BASEF:
        if (lp->params.fdx && !lp->fdx) return -1;
        lp->media = _100Mb;
@@ -3297,7 +3298,7 @@ de4x5_init_connection(struct net_device *dev)
     spin_lock_irqsave(&lp->lock, flags);
     de4x5_rst_desc_ring(dev);
     de4x5_setup_intr(dev);
-    lp->tx_enable = YES;
+    lp->tx_enable = true;
     spin_unlock_irqrestore(&lp->lock, flags);
     outl(POLL_DEMAND, DE4X5_TPD);
 
@@ -3336,7 +3337,7 @@ de4x5_reset_phy(struct net_device *dev)
             }
         }
        if (lp->useMII) {
-           next_tick = test_mii_reg(dev, MII_CR, MII_CR_RST, FALSE, 500);
+           next_tick = test_mii_reg(dev, MII_CR, MII_CR_RST, false, 500);
        }
     } else if (lp->chipset == DC21140) {
        PHY_HARD_RESET;
@@ -3466,7 +3467,7 @@ wait_for_link(struct net_device *dev)
 **
 */
 static int
-test_mii_reg(struct net_device *dev, int reg, int mask, int pol, long msec)
+test_mii_reg(struct net_device *dev, int reg, int mask, bool pol, long msec)
 {
     struct de4x5_private *lp = netdev_priv(dev);
     int test;
@@ -3476,9 +3477,8 @@ test_mii_reg(struct net_device *dev, int reg, int mask, int pol, long msec)
        lp->timeout = msec/100;
     }
 
-    if (pol) pol = ~0;
     reg = mii_rd((u_char)reg, lp->phy[lp->active].addr, DE4X5_MII) & mask;
-    test = (reg ^ pol) & mask;
+    test = (reg ^ (pol ? ~0 : 0)) & mask;
 
     if (test && --lp->timeout) {
        reg = 100 | TIMER_CB;
@@ -3992,10 +3992,10 @@ PCI_signature(char *name, struct de4x5_private *lp)
                             )))))));
        }
        if (lp->chipset != DC21041) {
-           lp->useSROM = TRUE;             /* card is not recognisably DEC */
+           lp->useSROM = true;             /* card is not recognisably DEC */
        }
     } else if ((lp->chipset & ~0x00ff) == DC2114x) {
-       lp->useSROM = TRUE;
+       lp->useSROM = true;
     }
 
     return status;
@@ -4216,7 +4216,7 @@ srom_repair(struct net_device *dev, int card)
        memset((char *)&lp->srom, 0, sizeof(struct de4x5_srom));
        memcpy(lp->srom.ieee_addr, (char *)dev->dev_addr, ETH_ALEN);
        memcpy(lp->srom.info, (char *)&srom_repair_info[SMC-1], 100);
-       lp->useSROM = TRUE;
+       lp->useSROM = true;
        break;
     }
 
@@ -4392,7 +4392,7 @@ srom_infoleaf_info(struct net_device *dev)
        if (lp->chipset == infoleaf_array[i].chipset) break;
     }
     if (i == INFOLEAF_SIZE) {
-       lp->useSROM = FALSE;
+       lp->useSROM = false;
        printk("%s: Cannot find correct chipset for SROM decoding!\n",
                                                                  dev->name);
        return -ENXIO;
@@ -4409,7 +4409,7 @@ srom_infoleaf_info(struct net_device *dev)
            if (lp->device == *p) break;
        }
        if (i == 0) {
-           lp->useSROM = FALSE;
+           lp->useSROM = false;
            printk("%s: Cannot find correct PCI device [%d] for SROM decoding!\n",
                                                       dev->name, lp->device);
            return -ENXIO;
@@ -4542,7 +4542,7 @@ dc21140_infoleaf(struct net_device *dev)
        }
        lp->media = INIT;
        lp->tcount = 0;
-       lp->tx_enable = FALSE;
+       lp->tx_enable = false;
     }
 
     return next_tick & ~TIMER_CB;
@@ -4577,7 +4577,7 @@ dc21142_infoleaf(struct net_device *dev)
        }
        lp->media = INIT;
        lp->tcount = 0;
-       lp->tx_enable = FALSE;
+       lp->tx_enable = false;
     }
 
     return next_tick & ~TIMER_CB;
@@ -4611,7 +4611,7 @@ dc21143_infoleaf(struct net_device *dev)
        }
        lp->media = INIT;
        lp->tcount = 0;
-       lp->tx_enable = FALSE;
+       lp->tx_enable = false;
     }
 
     return next_tick & ~TIMER_CB;
@@ -4650,7 +4650,7 @@ compact_infoblock(struct net_device *dev, u_char count, u_char *p)
        lp->asBit = 1 << ((csr6 >> 1) & 0x07);
        lp->asPolarity = ((csr6 & 0x80) ? -1 : 0) & lp->asBit;
        lp->infoblock_csr6 = OMR_DEF | ((csr6 & 0x71) << 18);
-       lp->useMII = FALSE;
+       lp->useMII = false;
 
        de4x5_switch_mac_port(dev);
     }
@@ -4691,7 +4691,7 @@ type0_infoblock(struct net_device *dev, u_char count, u_char *p)
        lp->asBit = 1 << ((csr6 >> 1) & 0x07);
        lp->asPolarity = ((csr6 & 0x80) ? -1 : 0) & lp->asBit;
        lp->infoblock_csr6 = OMR_DEF | ((csr6 & 0x71) << 18);
-       lp->useMII = FALSE;
+       lp->useMII = false;
 
        de4x5_switch_mac_port(dev);
     }
@@ -4731,7 +4731,7 @@ type1_infoblock(struct net_device *dev, u_char count, u_char *p)
         lp->ibn = 1;
         lp->active = *p;
        lp->infoblock_csr6 = OMR_MII_100;
-       lp->useMII = TRUE;
+       lp->useMII = true;
        lp->infoblock_media = ANS;
 
        de4x5_switch_mac_port(dev);
@@ -4773,7 +4773,7 @@ type2_infoblock(struct net_device *dev, u_char count, u_char *p)
         lp->cache.gepc = ((s32)(TWIDDLE(p)) << 16); p += 2;
         lp->cache.gep  = ((s32)(TWIDDLE(p)) << 16);
        lp->infoblock_csr6 = OMR_SIA;
-       lp->useMII = FALSE;
+       lp->useMII = false;
 
        de4x5_switch_mac_port(dev);
     }
@@ -4814,7 +4814,7 @@ type3_infoblock(struct net_device *dev, u_char count, u_char *p)
        lp->active = *p;
        if (MOTO_SROM_BUG) lp->active = 0;
        lp->infoblock_csr6 = OMR_MII_100;
-       lp->useMII = TRUE;
+       lp->useMII = true;
        lp->infoblock_media = ANS;
 
        de4x5_switch_mac_port(dev);
@@ -4856,7 +4856,7 @@ type4_infoblock(struct net_device *dev, u_char count, u_char *p)
        lp->asBit = 1 << ((csr6 >> 1) & 0x07);
        lp->asPolarity = ((csr6 & 0x80) ? -1 : 0) & lp->asBit;
        lp->infoblock_csr6 = OMR_DEF | ((csr6 & 0x71) << 18);
-       lp->useMII = FALSE;
+       lp->useMII = false;
 
        de4x5_switch_mac_port(dev);
     }
@@ -5077,7 +5077,7 @@ mii_get_phy(struct net_device *dev)
     int id;
 
     lp->active = 0;
-    lp->useMII = TRUE;
+    lp->useMII = true;
 
     /* Search the MII address space for possible PHY devices */
     for (n=0, lp->mii_cnt=0, i=1; !((i==1) && (n==1)); i=(i+1)%DE4X5_MAX_MII) {
@@ -5127,7 +5127,7 @@ mii_get_phy(struct net_device *dev)
            de4x5_dbg_mii(dev, k);
        }
     }
-    if (!lp->mii_cnt) lp->useMII = FALSE;
+    if (!lp->mii_cnt) lp->useMII = false;
 
     return lp->mii_cnt;
 }
index 57226e5eb8a680993a9f227b2e133485b244f247..12af0cc037fbf3859ebd55f8223ebfc9899d78c6 100644 (file)
 #define ALL                  0     /* Clear out all the setup frame */
 #define PHYS_ADDR_ONLY       1     /* Update the physical address only */
 
-/*
-** Booleans
-*/
-#define NO                   0
-#define FALSE                0
-
-#define YES                  ~0
-#define TRUE                 ~0
-
 /*
 ** Adapter state
 */
index 4ed67ff0e81ef9b8329ba922e9015e0f582645e3..dab74feb44bcf125937d66d674a87c806592f64b 100644 (file)
        udelay(5);
 
 #define __CHK_IO_SIZE(pci_id, dev_rev) \
- (( ((pci_id)==PCI_DM9132_ID) || ((dev_rev) >= 0x02000030) ) ? \
+ (( ((pci_id)==PCI_DM9132_ID) || ((dev_rev) >= 0x30) ) ? \
        DM9102A_IO_SIZE: DM9102_IO_SIZE)
 
-#define CHK_IO_SIZE(pci_dev, dev_rev) \
-       (__CHK_IO_SIZE(((pci_dev)->device << 16) | (pci_dev)->vendor, dev_rev))
+#define CHK_IO_SIZE(pci_dev) \
+       (__CHK_IO_SIZE(((pci_dev)->device << 16) | (pci_dev)->vendor, \
+       (pci_dev)->revision))
 
 /* Sten Check */
 #define DEVICE net_device
@@ -205,7 +206,7 @@ struct rx_desc {
 
 struct dmfe_board_info {
        u32 chip_id;                    /* Chip vendor/Device ID */
-       u32 chip_revision;              /* Chip revision */
+       u8 chip_revision;               /* Chip revision */
        struct DEVICE *next_dev;        /* next device */
        struct pci_dev *pdev;           /* PCI device */
        spinlock_t lock;
@@ -359,7 +360,7 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev,
 {
        struct dmfe_board_info *db;     /* board information structure */
        struct net_device *dev;
-       u32 dev_rev, pci_pmr;
+       u32 pci_pmr;
        int i, err;
 
        DMFE_DBUG(0, "dmfe_init_one()", 0);
@@ -392,10 +393,7 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev,
                goto err_out_disable;
        }
 
-       /* Read Chip revision */
-       pci_read_config_dword(pdev, PCI_REVISION_ID, &dev_rev);
-
-       if (pci_resource_len(pdev, 0) < (CHK_IO_SIZE(pdev, dev_rev)) ) {
+       if (pci_resource_len(pdev, 0) < (CHK_IO_SIZE(pdev)) ) {
                printk(KERN_ERR DRV_NAME ": Allocated I/O size too small\n");
                err = -ENODEV;
                goto err_out_disable;
@@ -433,7 +431,7 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev,
 
        db->chip_id = ent->driver_data;
        db->ioaddr = pci_resource_start(pdev, 0);
-       db->chip_revision = dev_rev;
+       db->chip_revision = pdev->revision;
        db->wol_mode = 0;
 
        db->pdev = pdev;
@@ -455,7 +453,7 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev,
 
        pci_read_config_dword(pdev, 0x50, &pci_pmr);
        pci_pmr &= 0x70000;
-       if ( (pci_pmr == 0x10000) && (dev_rev == 0x02000031) )
+       if ( (pci_pmr == 0x10000) && (db->chip_revision == 0x31) )
                db->chip_type = 1;      /* DM9102A E3 */
        else
                db->chip_type = 0;
@@ -553,7 +551,7 @@ static int dmfe_open(struct DEVICE *dev)
 
        /* CR6 operation mode decision */
        if ( !chkmode || (db->chip_id == PCI_DM9132_ID) ||
-               (db->chip_revision >= 0x02000030) ) {
+               (db->chip_revision >= 0x30) ) {
                db->cr6_data |= DMFE_TXTH_256;
                db->cr0_data = CR0_DEFAULT;
                db->dm910x_chk_mode=4;          /* Enter the normal mode */
@@ -1199,9 +1197,9 @@ static void dmfe_timer(unsigned long data)
                tmp_cr12 = inb(db->ioaddr + DCR12);     /* DM9102/DM9102A */
 
        if ( ((db->chip_id == PCI_DM9102_ID) &&
-               (db->chip_revision == 0x02000030)) ||
+               (db->chip_revision == 0x30)) ||
                ((db->chip_id == PCI_DM9132_ID) &&
-               (db->chip_revision == 0x02000010)) ) {
+               (db->chip_revision == 0x10)) ) {
                /* DM9102A Chip */
                if (tmp_cr12 & 2)
                        link_ok = 0;
index ea896777bcafecc84fce5896b8256892541ea8f1..53efd6694e755e80e64504e21fd90d0666bccec5 100644 (file)
@@ -197,8 +197,8 @@ int tulip_poll(struct net_device *dev, int *budget)
                                                                   tp->rx_buffers[entry].mapping,
                                                                   pkt_len, PCI_DMA_FROMDEVICE);
 #if ! defined(__alpha__)
-                                       eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->data,
-                                                        pkt_len, 0);
+                                       skb_copy_to_linear_data(skb, tp->rx_buffers[entry].skb->data,
+                                                        pkt_len);
                                        skb_put(skb, pkt_len);
 #else
                                        memcpy(skb_put(skb, pkt_len),
@@ -420,8 +420,8 @@ static int tulip_rx(struct net_device *dev)
                                                            tp->rx_buffers[entry].mapping,
                                                            pkt_len, PCI_DMA_FROMDEVICE);
 #if ! defined(__alpha__)
-                               eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->data,
-                                                pkt_len, 0);
+                               skb_copy_to_linear_data(skb, tp->rx_buffers[entry].skb->data,
+                                                pkt_len);
                                skb_put(skb, pkt_len);
 #else
                                memcpy(skb_put(skb, pkt_len),
index 041af63f2811c4cb35ddf7f63a6dcea2c8b33412..7dcd138b0fed3be05888640047f400882c894e1b 100644 (file)
@@ -1155,7 +1155,7 @@ static void __devinit tulip_mwi_config (struct pci_dev *pdev,
        /* set or disable MWI in the standard PCI command bit.
         * Check for the case where  mwi is desired but not available
         */
-       if (csr0 & MWI) pci_set_mwi(pdev);
+       if (csr0 & MWI) pci_try_set_mwi(pdev);
        else            pci_clear_mwi(pdev);
 
        /* read result from hardware (in case bit refused to enable) */
@@ -1238,7 +1238,6 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
        };
        static int last_irq;
        static int multiport_cnt;       /* For four-port boards w/one EEPROM */
-       u8 chip_rev;
        int i, irq;
        unsigned short sum;
        unsigned char *ee_data;
@@ -1274,10 +1273,8 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
 
        if (pdev->vendor == 0x1282 && pdev->device == 0x9100)
        {
-               u32 dev_rev;
                /* Read Chip revision */
-               pci_read_config_dword(pdev, PCI_REVISION_ID, &dev_rev);
-               if(dev_rev < 0x02000030)
+               if (pdev->revision < 0x02000030)
                {
                        printk(KERN_ERR PFX "skipping early DM9100 with Crc bug (use dmfe)\n");
                        return -ENODEV;
@@ -1360,8 +1357,6 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
        if (!ioaddr)
                goto err_out_free_res;
 
-       pci_read_config_byte (pdev, PCI_REVISION_ID, &chip_rev);
-
        /*
         * initialize private data structure 'tp'
         * it is zeroed and aligned in alloc_etherdev
@@ -1382,7 +1377,7 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
        tp->flags = tulip_tbl[chip_idx].flags;
        tp->pdev = pdev;
        tp->base_addr = ioaddr;
-       tp->revision = chip_rev;
+       tp->revision = pdev->revision;
        tp->csr0 = csr0;
        spin_lock_init(&tp->lock);
        spin_lock_init(&tp->mii_lock);
@@ -1399,7 +1394,7 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
                tulip_mwi_config (pdev, dev);
 #else
        /* MWI is broken for DC21143 rev 65... */
-       if (chip_idx == DC21143 && chip_rev == 65)
+       if (chip_idx == DC21143 && pdev->revision == 65)
                tp->csr0 &= ~MWI;
 #endif
 
@@ -1640,7 +1635,7 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
 #else
                "Port"
 #endif
-               " %#llx,", dev->name, chip_name, chip_rev,
+               " %#llx,", dev->name, chip_name, pdev->revision,
                (unsigned long long) pci_resource_start(pdev, TULIP_BAR));
        pci_set_drvdata(pdev, dev);
 
index 38f3b99716b8bb8c4357d9291d00fe181f29aeec..5824f6a354950380c8e1116b0a5b537b6ecb8eff 100644 (file)
@@ -1232,7 +1232,7 @@ static int netdev_rx(struct net_device *dev)
                                pci_dma_sync_single_for_cpu(np->pci_dev,np->rx_addr[entry],
                                                            np->rx_skbuff[entry]->len,
                                                            PCI_DMA_FROMDEVICE);
-                               eth_copy_and_sum(skb, np->rx_skbuff[entry]->data, pkt_len, 0);
+                               skb_copy_to_linear_data(skb, np->rx_skbuff[entry]->data, pkt_len);
                                skb_put(skb, pkt_len);
                                pci_dma_sync_single_for_device(np->pci_dev,np->rx_addr[entry],
                                                               np->rx_skbuff[entry]->len,
index 2470b1ee33c03b2243f9ed40aa4b0071a321d949..16a54e6b8d4f002b31e1a2e967785a1fac538e91 100644 (file)
@@ -205,7 +205,6 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_
 {
        struct net_device *dev = NULL;
        struct xircom_private *private;
-       unsigned char chip_rev;
        unsigned long flags;
        unsigned short tmp16;
        enter("xircom_probe");
@@ -224,8 +223,6 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_
        pci_read_config_word (pdev,PCI_STATUS, &tmp16);
        pci_write_config_word (pdev, PCI_STATUS,tmp16);
 
-       pci_read_config_byte(pdev, PCI_REVISION_ID, &chip_rev);
-
        if (!request_region(pci_resource_start(pdev, 0), 128, "xircom_cb")) {
                printk(KERN_ERR "xircom_probe: failed to allocate io-region\n");
                return -ENODEV;
@@ -286,7 +283,7 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_
                goto reg_fail;
        }
 
-       printk(KERN_INFO "%s: Xircom cardbus revision %i at irq %i \n", dev->name, chip_rev, pdev->irq);
+       printk(KERN_INFO "%s: Xircom cardbus revision %i at irq %i \n", dev->name, pdev->revision, pdev->irq);
        /* start the transmitter to get a heartbeat */
        /* TODO: send 2 dummy packets here */
        transceiver_voodoo(private);
@@ -1208,7 +1205,7 @@ static void investigate_read_descriptor(struct net_device *dev,struct xircom_pri
                                goto out;
                        }
                        skb_reserve(skb, 2);
-                       eth_copy_and_sum(skb, (unsigned char*)&card->rx_buffer[bufferoffset / 4], pkt_len, 0);
+                       skb_copy_to_linear_data(skb, (unsigned char*)&card->rx_buffer[bufferoffset / 4], pkt_len);
                        skb_put(skb, pkt_len);
                        skb->protocol = eth_type_trans(skb, dev);
                        netif_rx(skb);
index f64172927377770549c04bee8779852a3ced2994..fc439f333350ded1eae790db6268e035e597a876 100644 (file)
@@ -524,7 +524,6 @@ static int __devinit xircom_init_one(struct pci_dev *pdev, const struct pci_devi
        int chip_idx = id->driver_data;
        long ioaddr;
        int i;
-       u8 chip_rev;
 
 /* when built into the kernel, we only print version if device is found */
 #ifndef MODULE
@@ -620,9 +619,8 @@ static int __devinit xircom_init_one(struct pci_dev *pdev, const struct pci_devi
        if (register_netdev(dev))
                goto err_out_cleardev;
 
-       pci_read_config_byte(pdev, PCI_REVISION_ID, &chip_rev);
        printk(KERN_INFO "%s: %s rev %d at %#3lx,",
-              dev->name, xircom_tbl[chip_idx].chip_name, chip_rev, ioaddr);
+              dev->name, xircom_tbl[chip_idx].chip_name, pdev->revision, ioaddr);
        for (i = 0; i < 6; i++)
                printk("%c%2.2X", i ? ':' : ' ', dev->dev_addr[i]);
        printk(", IRQ %d.\n", dev->irq);
@@ -1242,8 +1240,8 @@ xircom_rx(struct net_device *dev)
                                && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
                                skb_reserve(skb, 2);    /* 16 byte align the IP header */
 #if ! defined(__alpha__)
-                               eth_copy_and_sum(skb, bus_to_virt(tp->rx_ring[entry].buffer1),
-                                                                pkt_len, 0);
+                               skb_copy_to_linear_data(skb, bus_to_virt(tp->rx_ring[entry].buffer1),
+                                                                pkt_len);
                                skb_put(skb, pkt_len);
 #else
                                memcpy(skb_put(skb, pkt_len),
index a2c6caaaae932a672a34058619f6998ee8e7bc59..62b2b3005019c90865ef0f019f16d8d2607089f0 100644 (file)
@@ -432,6 +432,7 @@ static void tun_setup(struct net_device *dev)
        init_waitqueue_head(&tun->read_wait);
 
        tun->owner = -1;
+       tun->group = -1;
 
        SET_MODULE_OWNER(dev);
        dev->open = tun_net_open;
@@ -467,8 +468,11 @@ static int tun_set_iff(struct file *file, struct ifreq *ifr)
                        return -EBUSY;
 
                /* Check permissions */
-               if (tun->owner != -1 &&
-                   current->euid != tun->owner && !capable(CAP_NET_ADMIN))
+               if (((tun->owner != -1 &&
+                     current->euid != tun->owner) ||
+                    (tun->group != -1 &&
+                     current->egid != tun->group)) &&
+                    !capable(CAP_NET_ADMIN))
                        return -EPERM;
        }
        else if (__dev_get_by_name(ifr->ifr_name))
@@ -610,6 +614,13 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
                DBG(KERN_INFO "%s: owner set to %d\n", tun->dev->name, tun->owner);
                break;
 
+       case TUNSETGROUP:
+               /* Set group of the device */
+               tun->group= (gid_t) arg;
+
+               DBG(KERN_INFO "%s: group set to %d\n", tun->dev->name, tun->group);
+               break;
+
        case TUNSETLINK:
                /* Only allow setting the type when the interface is down */
                if (tun->dev->flags & IFF_UP) {
index 15b2fb8aa49280008f1b38925340df4495c19cdd..03587205546e71260ad81c10c76dee6d0674d719 100644 (file)
@@ -1703,7 +1703,7 @@ typhoon_rx(struct typhoon *tp, struct basic_ring *rxRing, volatile u32 * ready,
                        pci_dma_sync_single_for_cpu(tp->pdev, dma_addr,
                                                    PKT_BUF_SZ,
                                                    PCI_DMA_FROMDEVICE);
-                       eth_copy_and_sum(new_skb, skb->data, pkt_len, 0);
+                       skb_copy_to_linear_data(new_skb, skb->data, pkt_len);
                        pci_dma_sync_single_for_device(tp->pdev, dma_addr,
                                                       PKT_BUF_SZ,
                                                       PCI_DMA_FROMDEVICE);
@@ -2267,12 +2267,6 @@ need_resume:
        typhoon_resume(pdev);
        return -EBUSY;
 }
-
-static int
-typhoon_enable_wake(struct pci_dev *pdev, pci_power_t state, int enable)
-{
-       return pci_enable_wake(pdev, state, enable);
-}
 #endif
 
 static int __devinit
@@ -2636,7 +2630,6 @@ static struct pci_driver typhoon_driver = {
 #ifdef CONFIG_PM
        .suspend        = typhoon_suspend,
        .resume         = typhoon_resume,
-       .enable_wake    = typhoon_enable_wake,
 #endif
 };
 
index 18b731bb4da1a6cfe881b1c8485e9b92268fc1e4..e4736a3b1b7a4f7cc24bb0916cb33172e67a519d 100644 (file)
@@ -2276,7 +2276,7 @@ static void ucc_geth_stop(struct ucc_geth_private *ugeth)
        phy_stop(phydev);
 
        /* Mask all interrupts */
-       out_be32(ugeth->uccf->p_ucce, 0x00000000);
+       out_be32(ugeth->uccf->p_uccm, 0x00000000);
 
        /* Clear all interrupts */
        out_be32(ugeth->uccf->p_ucce, 0xffffffff);
index 86e90c59d55156473058e9ae6a2a6137da8e5283..76752d84a30f80f7cfcafc2bce6437c6f582bbe8 100644 (file)
@@ -255,7 +255,7 @@ static void catc_rx_done(struct urb *urb)
                if (!(skb = dev_alloc_skb(pkt_len)))
                        return;
 
-               eth_copy_and_sum(skb, pkt_start + pkt_offset, pkt_len, 0);
+               skb_copy_to_linear_data(skb, pkt_start + pkt_offset, pkt_len);
                skb_put(skb, pkt_len);
 
                skb->protocol = eth_type_trans(skb, catc->netdev);
index 60d29440f31643d40792263b28fdd79db0955142..524dc5f5e46ddfd197cea239e60c59caffd93374 100644 (file)
@@ -635,7 +635,7 @@ static void kaweth_usb_receive(struct urb *urb)
 
                skb_reserve(skb, 2);    /* Align IP on 16 byte boundaries */
 
-               eth_copy_and_sum(skb, kaweth->rx_buf + 2, pkt_len, 0);
+               skb_copy_to_linear_data(skb, kaweth->rx_buf + 2, pkt_len);
 
                skb_put(skb, pkt_len);
 
index a12f576391cf3150d2716b040e6bc06d1eb93844..37bf4f2c0a44c07204dcdc991cecee505462dcf1 100644 (file)
@@ -192,7 +192,7 @@ static int init_status (struct usbnet *dev, struct usb_interface *intf)
                                usb_pipeendpoint(pipe), maxp, period);
                }
        }
-       return  0;
+       return 0;
 }
 
 /* Passes this packet up the stack, updating its accounting.
@@ -326,7 +326,7 @@ static void rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
        if (netif_running (dev->net)
                        && netif_device_present (dev->net)
                        && !test_bit (EVENT_RX_HALT, &dev->flags)) {
-               switch (retval = usb_submit_urb (urb, GFP_ATOMIC)){
+               switch (retval = usb_submit_urb (urb, GFP_ATOMIC)) {
                case -EPIPE:
                        usbnet_defer_kevent (dev, EVENT_RX_HALT);
                        break;
@@ -393,8 +393,8 @@ static void rx_complete (struct urb *urb)
        entry->urb = NULL;
 
        switch (urb_status) {
-           // success
-           case 0:
+       /* success */
+       case 0:
                if (skb->len < dev->net->hard_header_len) {
                        entry->state = rx_cleanup;
                        dev->stats.rx_errors++;
@@ -404,28 +404,30 @@ static void rx_complete (struct urb *urb)
                }
                break;
 
-           // stalls need manual reset. this is rare ... except that
-           // when going through USB 2.0 TTs, unplug appears this way.
-           // we avoid the highspeed version of the ETIMEOUT/EILSEQ
-           // storm, recovering as needed.
-           case -EPIPE:
+       /* stalls need manual reset. this is rare ... except that
+        * when going through USB 2.0 TTs, unplug appears this way.
+        * we avoid the highspeed version of the ETIMEOUT/EILSEQ
+        * storm, recovering as needed.
+        */
+       case -EPIPE:
                dev->stats.rx_errors++;
                usbnet_defer_kevent (dev, EVENT_RX_HALT);
                // FALLTHROUGH
 
-           // software-driven interface shutdown
-           case -ECONNRESET:           // async unlink
-           case -ESHUTDOWN:            // hardware gone
+       /* software-driven interface shutdown */
+       case -ECONNRESET:               /* async unlink */
+       case -ESHUTDOWN:                /* hardware gone */
                if (netif_msg_ifdown (dev))
                        devdbg (dev, "rx shutdown, code %d", urb_status);
                goto block;
 
-           // we get controller i/o faults during khubd disconnect() delays.
-           // throttle down resubmits, to avoid log floods; just temporarily,
-           // so we still recover when the fault isn't a khubd delay.
-           case -EPROTO:
-           case -ETIME:
-           case -EILSEQ:
+       /* we get controller i/o faults during khubd disconnect() delays.
+        * throttle down resubmits, to avoid log floods; just temporarily,
+        * so we still recover when the fault isn't a khubd delay.
+        */
+       case -EPROTO:
+       case -ETIME:
+       case -EILSEQ:
                dev->stats.rx_errors++;
                if (!timer_pending (&dev->delay)) {
                        mod_timer (&dev->delay, jiffies + THROTTLE_JIFFIES);
@@ -438,12 +440,12 @@ block:
                urb = NULL;
                break;
 
-           // data overrun ... flush fifo?
-           case -EOVERFLOW:
+       /* data overrun ... flush fifo? */
+       case -EOVERFLOW:
                dev->stats.rx_over_errors++;
                // FALLTHROUGH
 
-           default:
+       default:
                entry->state = rx_cleanup;
                dev->stats.rx_errors++;
                if (netif_msg_rx_err (dev))
@@ -471,22 +473,22 @@ static void intr_complete (struct urb *urb)
        int             status = urb->status;
 
        switch (status) {
-           /* success */
-           case 0:
+       /* success */
+       case 0:
                dev->driver_info->status(dev, urb);
                break;
 
-           /* software-driven interface shutdown */
-           case -ENOENT:               // urb killed
-           case -ESHUTDOWN:            // hardware gone
+       /* software-driven interface shutdown */
+       case -ENOENT:           /* urb killed */
+       case -ESHUTDOWN:        /* hardware gone */
                if (netif_msg_ifdown (dev))
                        devdbg (dev, "intr shutdown, code %d", status);
                return;
 
-           /* NOTE:  not throttling like RX/TX, since this endpoint
-            * already polls infrequently
-            */
-           default:
+       /* NOTE:  not throttling like RX/TX, since this endpoint
+        * already polls infrequently
+        */
+       default:
                devdbg (dev, "intr status %d", status);
                break;
        }
@@ -569,9 +571,9 @@ static int usbnet_stop (struct net_device *net)
        temp = unlink_urbs (dev, &dev->txq) + unlink_urbs (dev, &dev->rxq);
 
        // maybe wait for deletions to finish.
-       while (!skb_queue_empty(&dev->rxq) &&
-              !skb_queue_empty(&dev->txq) &&
-              !skb_queue_empty(&dev->done)) {
+       while (!skb_queue_empty(&dev->rxq)
+                       && !skb_queue_empty(&dev->txq)
+                       && !skb_queue_empty(&dev->done)) {
                msleep(UNLINK_TIMEOUT_MS);
                if (netif_msg_ifdown (dev))
                        devdbg (dev, "waited for %d urb completions", temp);
@@ -1011,16 +1013,16 @@ static void usbnet_bh (unsigned long param)
        while ((skb = skb_dequeue (&dev->done))) {
                entry = (struct skb_data *) skb->cb;
                switch (entry->state) {
-                   case rx_done:
+               case rx_done:
                        entry->state = rx_cleanup;
                        rx_process (dev, skb);
                        continue;
-                   case tx_done:
-                   case rx_cleanup:
+               case tx_done:
+               case rx_cleanup:
                        usb_free_urb (entry->urb);
                        dev_kfree_skb (skb);
                        continue;
-                   default:
+               default:
                        devdbg (dev, "bogus skb state %d", entry->state);
                }
        }
@@ -1211,7 +1213,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
                        status = 0;
 
        }
-       if (status == 0 && dev->status)
+       if (status >= 0 && dev->status)
                status = init_status (dev, udev);
        if (status < 0)
                goto out3;
index a3f8b9e7bc00551d12690555d412ed28a9c9d55c..a6c5820767de7f52920d1904ca1149b721c2f3f3 100644 (file)
@@ -47,7 +47,7 @@ struct usbnet {
        unsigned long           data [5];
        u32                     xid;
        u32                     hard_mtu;       /* count any extra framing */
-       size_t                  rx_urb_size;    /* size for rx urbs  */
+       size_t                  rx_urb_size;    /* size for rx urbs */
        struct mii_if_info      mii;
 
        /* various kinds of pending driver work */
@@ -85,7 +85,7 @@ struct driver_info {
 #define FLAG_NO_SETINT 0x0010          /* device can't set_interface() */
 #define FLAG_ETHER     0x0020          /* maybe use "eth%d" names */
 
-#define FLAG_FRAMING_AX 0x0040          /* AX88772/178 packets */
+#define FLAG_FRAMING_AX 0x0040         /* AX88772/178 packets */
 
        /* init device ... can sleep, or cause probe() failure */
        int     (*bind)(struct usbnet *, struct usb_interface *);
@@ -146,9 +146,9 @@ extern void usbnet_cdc_unbind (struct usbnet *, struct usb_interface *);
 
 /* CDC and RNDIS support the same host-chosen packet filters for IN transfers */
 #define        DEFAULT_FILTER  (USB_CDC_PACKET_TYPE_BROADCAST \
-                       |USB_CDC_PACKET_TYPE_ALL_MULTICAST \
-                       |USB_CDC_PACKET_TYPE_PROMISCUOUS \
-                       |USB_CDC_PACKET_TYPE_DIRECTED)
+                       |USB_CDC_PACKET_TYPE_ALL_MULTICAST \
+                       |USB_CDC_PACKET_TYPE_PROMISCUOUS \
+                       |USB_CDC_PACKET_TYPE_DIRECTED)
 
 
 /* we record the state for each of our queued skbs */
index adea290a9d5e4e6f0015d2c939589d67ca98ee05..f51c2c138f1032e64a86bcadd599bb15f77ad7f0 100644 (file)
@@ -622,7 +622,6 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
        struct net_device *dev;
        struct rhine_private *rp;
        int i, rc;
-       u8 pci_rev;
        u32 quirks;
        long pioaddr;
        long memaddr;
@@ -642,27 +641,25 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
                printk(version);
 #endif
 
-       pci_read_config_byte(pdev, PCI_REVISION_ID, &pci_rev);
-
        io_size = 256;
        phy_id = 0;
        quirks = 0;
        name = "Rhine";
-       if (pci_rev < VTunknown0) {
+       if (pdev->revision < VTunknown0) {
                quirks = rqRhineI;
                io_size = 128;
        }
-       else if (pci_rev >= VT6102) {
+       else if (pdev->revision >= VT6102) {
                quirks = rqWOL | rqForceReset;
-               if (pci_rev < VT6105) {
+               if (pdev->revision < VT6105) {
                        name = "Rhine II";
                        quirks |= rqStatusWBRace;       /* Rhine-II exclusive */
                }
                else {
                        phy_id = 1;     /* Integrated PHY, phy_id fixed to 1 */
-                       if (pci_rev >= VT6105_B0)
+                       if (pdev->revision >= VT6105_B0)
                                quirks |= rq6patterns;
-                       if (pci_rev < VT6105M)
+                       if (pdev->revision < VT6105M)
                                name = "Rhine III";
                        else
                                name = "Rhine III (Management Adapter)";
@@ -1492,9 +1489,9 @@ static int rhine_rx(struct net_device *dev, int limit)
                                                            rp->rx_buf_sz,
                                                            PCI_DMA_FROMDEVICE);
 
-                               eth_copy_and_sum(skb,
+                               skb_copy_to_linear_data(skb,
                                                 rp->rx_skbuff[entry]->data,
-                                                pkt_len, 0);
+                                                pkt_len);
                                skb_put(skb, pkt_len);
                                pci_dma_sync_single_for_device(rp->pdev,
                                                               rp->rx_skbuff_dma[entry],
index b670b97bcfde488a7de7a2e4bbe47985a0597a22..f331843d1102ac80839e2a46f098a7b2b51d5f67 100644 (file)
@@ -890,8 +890,7 @@ static void __devinit velocity_init_info(struct pci_dev *pdev,
 
 static int __devinit velocity_get_pci_info(struct velocity_info *vptr, struct pci_dev *pdev)
 {
-       if (pci_read_config_byte(pdev, PCI_REVISION_ID, &vptr->rev_id) < 0)
-               return -EIO;
+       vptr->rev_id = pdev->revision;
 
        pci_set_master(pdev);
 
index 999bf71937ca55f5540304242253f51d4ed67ce0..ec1c556a47caf65c69b81504f7a1207e7e52f013 100644 (file)
@@ -3439,7 +3439,6 @@ static int __devinit
 cpc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int first_time = 1;
-       ucchar cpc_rev_id;
        int err, eeprom_outdated = 0;
        ucshort device_id;
        pc300_t *card;
@@ -3480,7 +3479,6 @@ cpc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        card->hw.falcsize = pci_resource_len(pdev, 4);
        card->hw.plxphys = pci_resource_start(pdev, 5);
        card->hw.plxsize = pci_resource_len(pdev, 5);
-       pci_read_config_byte(pdev, PCI_REVISION_ID, &cpc_rev_id);
 
        switch (device_id) {
                case PCI_DEVICE_ID_PC300_RX_1:
@@ -3498,7 +3496,7 @@ cpc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        }
 #ifdef PC300_DEBUG_PCI
        printk("cpc (bus=0x0%x,pci_id=0x%x,", pdev->bus->number, pdev->devfn);
-       printk("rev_id=%d) IRQ%d\n", cpc_rev_id, card->hw.irq);
+       printk("rev_id=%d) IRQ%d\n", pdev->revision, card->hw.irq);
        printk("cpc:found  ramaddr=0x%08lx plxaddr=0x%08lx "
               "ctladdr=0x%08lx falcaddr=0x%08lx\n",
               card->hw.ramphys, card->hw.plxphys, card->hw.scaphys,
index aff05dba720ab023983212dba42172ca65b9d53f..dfbd3b00f03b0a524084bcdeecbabded50198067 100644 (file)
@@ -311,7 +311,6 @@ static int __devinit pc300_pci_init_one(struct pci_dev *pdev,
                                        const struct pci_device_id *ent)
 {
        card_t *card;
-       u8 rev_id;
        u32 __iomem *p;
        int i;
        u32 ramsize;
@@ -366,7 +365,6 @@ static int __devinit pc300_pci_init_one(struct pci_dev *pdev,
                        return -ENOMEM;
                }
 
-       pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id);
        if (pci_resource_len(pdev, 0) != PC300_PLX_SIZE ||
            pci_resource_len(pdev, 2) != PC300_SCA_SIZE ||
            pci_resource_len(pdev, 3) < 16384) {
index ca06a00d9d864967c604c1582a346d80d512b367..7f720de2e9f08b4c6de5b6675a30572535d6ceb6 100644 (file)
@@ -289,7 +289,6 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev,
                                         const struct pci_device_id *ent)
 {
        card_t *card;
-       u8 rev_id;
        u32 __iomem *p;
        int i;
        u32 ramsize;
@@ -330,7 +329,6 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev,
                return -ENOMEM;
        }
 
-       pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id);
        if (pci_resource_len(pdev, 0) != PCI200SYN_PLX_SIZE ||
            pci_resource_len(pdev, 2) != PCI200SYN_SCA_SIZE ||
            pci_resource_len(pdev, 3) < 16384) {
index fa2399cbd5cab472074b51d64a117bff1feb1d59..ae27af0141c02ee5b6100aa7f512dfdd77c4e703 100644 (file)
@@ -546,6 +546,18 @@ config USB_ZD1201
          To compile this driver as a module, choose M here: the
          module will be called zd1201.
 
+config RTL8187
+       tristate "Realtek 8187 USB support"
+       depends on MAC80211 && USB && WLAN_80211 && EXPERIMENTAL
+       select EEPROM_93CX6
+       ---help---
+         This is a driver for RTL8187 based cards.
+         These are USB based chips found in cards such as:
+
+         Netgear WG111v2
+
+         Thanks to Realtek for their support!
+
 source "drivers/net/wireless/hostap/Kconfig"
 source "drivers/net/wireless/bcm43xx/Kconfig"
 source "drivers/net/wireless/zd1211rw/Kconfig"
index d2124602263bf8f193d575428f1fc3b11825cece..ef35bc6c4a228491723bd6c4efc9d5816dd8009b 100644 (file)
@@ -44,3 +44,6 @@ obj-$(CONFIG_PCMCIA_WL3501)   += wl3501_cs.o
 
 obj-$(CONFIG_USB_ZD1201)       += zd1201.o
 obj-$(CONFIG_LIBERTAS_USB)     += libertas/
+
+rtl8187-objs           := rtl8187_dev.o rtl8187_rtl8225.o
+obj-$(CONFIG_RTL8187)  += rtl8187.o
index ef6b253a92cec27d09039af365888cf18d3783d3..c5d6753a55ea80aa54e051b5d0ab7d671d352b4b 100644 (file)
@@ -3741,10 +3741,8 @@ static int bcm43xx_attach_board(struct bcm43xx_private *bcm)
                                  &bcm->board_type);
        if (err)
                goto err_iounmap;
-       err = bcm43xx_pci_read_config16(bcm, PCI_REVISION_ID,
-                                 &bcm->board_revision);
-       if (err)
-               goto err_iounmap;
+
+       bcm->board_revision = bcm->pci_dev->revision;
 
        err = bcm43xx_chipset_attach(bcm);
        if (err)
index b37f1e348700c9c775dce61695bd2bde12101b6e..d779199c30d056d707ea341530ce453472f09bc2 100644 (file)
@@ -1638,7 +1638,7 @@ void bcm43xx_phy_set_baseband_attenuation(struct bcm43xx_private *bcm,
                return;
        }
 
-       if (phy->analog > 1) {
+       if (phy->analog == 1) {
                value = bcm43xx_phy_read(bcm, 0x0060) & ~0x003C;
                value |= (baseband_attenuation << 2) & 0x003C;
        } else {
index 5b3abd54d0e504a03b22ff1e9f33ff46a3b17207..90900525379c045b89a6be172634694929d2b5e4 100644 (file)
@@ -326,7 +326,6 @@ static int ap_control_proc_read(char *page, char **start, off_t off,
        char *p = page;
        struct ap_data *ap = (struct ap_data *) data;
        char *policy_txt;
-       struct list_head *ptr;
        struct mac_entry *entry;
 
        if (off != 0) {
@@ -352,14 +351,12 @@ static int ap_control_proc_read(char *page, char **start, off_t off,
        p += sprintf(p, "MAC entries: %u\n", ap->mac_restrictions.entries);
        p += sprintf(p, "MAC list:\n");
        spin_lock_bh(&ap->mac_restrictions.lock);
-       for (ptr = ap->mac_restrictions.mac_list.next;
-            ptr != &ap->mac_restrictions.mac_list; ptr = ptr->next) {
+       list_for_each_entry(entry, &ap->mac_restrictions.mac_list, list) {
                if (p - page > PAGE_SIZE - 80) {
                        p += sprintf(p, "All entries did not fit one page.\n");
                        break;
                }
 
-               entry = list_entry(ptr, struct mac_entry, list);
                p += sprintf(p, MACSTR "\n", MAC2STR(entry->addr));
        }
        spin_unlock_bh(&ap->mac_restrictions.lock);
@@ -413,7 +410,6 @@ int ap_control_del_mac(struct mac_restrictions *mac_restrictions, u8 *mac)
 static int ap_control_mac_deny(struct mac_restrictions *mac_restrictions,
                               u8 *mac)
 {
-       struct list_head *ptr;
        struct mac_entry *entry;
        int found = 0;
 
@@ -421,10 +417,7 @@ static int ap_control_mac_deny(struct mac_restrictions *mac_restrictions,
                return 0;
 
        spin_lock_bh(&mac_restrictions->lock);
-       for (ptr = mac_restrictions->mac_list.next;
-            ptr != &mac_restrictions->mac_list; ptr = ptr->next) {
-               entry = list_entry(ptr, struct mac_entry, list);
-
+       list_for_each_entry(entry, &mac_restrictions->mac_list, list) {
                if (memcmp(entry->addr, mac, ETH_ALEN) == 0) {
                        found = 1;
                        break;
@@ -519,7 +512,7 @@ static int prism2_ap_proc_read(char *page, char **start, off_t off,
 {
        char *p = page;
        struct ap_data *ap = (struct ap_data *) data;
-       struct list_head *ptr;
+       struct sta_info *sta;
        int i;
 
        if (off > PROC_LIMIT) {
@@ -529,9 +522,7 @@ static int prism2_ap_proc_read(char *page, char **start, off_t off,
 
        p += sprintf(p, "# BSSID CHAN SIGNAL NOISE RATE SSID FLAGS\n");
        spin_lock_bh(&ap->sta_table_lock);
-       for (ptr = ap->sta_list.next; ptr != &ap->sta_list; ptr = ptr->next) {
-               struct sta_info *sta = (struct sta_info *) ptr;
-
+       list_for_each_entry(sta, &ap->sta_list, list) {
                if (!sta->ap)
                        continue;
 
@@ -861,7 +852,7 @@ void hostap_init_ap_proc(local_info_t *local)
 
 void hostap_free_data(struct ap_data *ap)
 {
-       struct list_head *n, *ptr;
+       struct sta_info *n, *sta;
 
        if (ap == NULL || !ap->initialized) {
                printk(KERN_DEBUG "hostap_free_data: ap has not yet been "
@@ -875,8 +866,7 @@ void hostap_free_data(struct ap_data *ap)
        ap->crypt = ap->crypt_priv = NULL;
 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
 
-       list_for_each_safe(ptr, n, &ap->sta_list) {
-               struct sta_info *sta = list_entry(ptr, struct sta_info, list);
+       list_for_each_entry_safe(sta, n, &ap->sta_list, list) {
                ap_sta_hash_del(ap, sta);
                list_del(&sta->list);
                if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap && sta->local)
@@ -2704,6 +2694,8 @@ ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx)
 
        if (hdr->addr1[0] & 0x01) {
                /* broadcast/multicast frame - no AP related processing */
+               if (local->ap->num_sta <= 0)
+                       ret = AP_TX_DROP;
                goto out;
        }
 
@@ -3198,15 +3190,14 @@ int hostap_update_rx_stats(struct ap_data *ap,
 
 void hostap_update_rates(local_info_t *local)
 {
-       struct list_head *ptr;
+       struct sta_info *sta;
        struct ap_data *ap = local->ap;
 
        if (!ap)
                return;
 
        spin_lock_bh(&ap->sta_table_lock);
-       for (ptr = ap->sta_list.next; ptr != &ap->sta_list; ptr = ptr->next) {
-               struct sta_info *sta = (struct sta_info *) ptr;
+       list_for_each_entry(sta, &ap->sta_list, list) {
                prism2_check_tx_rates(sta);
        }
        spin_unlock_bh(&ap->sta_table_lock);
@@ -3242,11 +3233,10 @@ void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent,
 void hostap_add_wds_links(local_info_t *local)
 {
        struct ap_data *ap = local->ap;
-       struct list_head *ptr;
+       struct sta_info *sta;
 
        spin_lock_bh(&ap->sta_table_lock);
-       list_for_each(ptr, &ap->sta_list) {
-               struct sta_info *sta = list_entry(ptr, struct sta_info, list);
+       list_for_each_entry(sta, &ap->sta_list, list) {
                if (sta->ap)
                        hostap_wds_link_oper(local, sta->addr, WDS_ADD);
        }
index c090a5aebb58d55f108da5fbe83a92ea9e64e5b6..30acd39d76a2892de5a684b9b716201c74b9da1f 100644 (file)
@@ -1,8 +1,6 @@
 #ifndef HOSTAP_CONFIG_H
 #define HOSTAP_CONFIG_H
 
-#define PRISM2_VERSION "0.4.4-kernel"
-
 /* In the previous versions of Host AP driver, support for user space version
  * of IEEE 802.11 management (hostapd) used to be disabled in the default
  * configuration. From now on, support for hostapd is always included and it is
index ee1532b62e42e1c8d74075cdc86f7faab09984e4..30e723f65979fafa484c4102a8e61bd19445e617 100644 (file)
@@ -22,7 +22,6 @@
 #include "hostap_wlan.h"
 
 
-static char *version = PRISM2_VERSION " (Jouni Malinen <j@w1.fi>)";
 static dev_info_t dev_info = "hostap_cs";
 
 MODULE_AUTHOR("Jouni Malinen");
@@ -30,7 +29,6 @@ MODULE_DESCRIPTION("Support for Intersil Prism2-based 802.11 wireless LAN "
                   "cards (PC Card).");
 MODULE_SUPPORTED_DEVICE("Intersil Prism2-based WLAN cards (PC Card)");
 MODULE_LICENSE("GPL");
-MODULE_VERSION(PRISM2_VERSION);
 
 
 static int ignore_cis_vcc;
@@ -910,14 +908,12 @@ static struct pcmcia_driver hostap_driver = {
 
 static int __init init_prism2_pccard(void)
 {
-       printk(KERN_INFO "%s: %s\n", dev_info, version);
        return pcmcia_register_driver(&hostap_driver);
 }
 
 static void __exit exit_prism2_pccard(void)
 {
        pcmcia_unregister_driver(&hostap_driver);
-       printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
 }
 
 
index cdea7f71b9eba7e6d01fc7637da1cd1854bd5182..8c71077d653cf10a076f1c2004c93eff5ec663aa 100644 (file)
@@ -3893,8 +3893,6 @@ static void prism2_get_drvinfo(struct net_device *dev,
        local = iface->local;
 
        strncpy(info->driver, "hostap", sizeof(info->driver) - 1);
-       strncpy(info->version, PRISM2_VERSION,
-               sizeof(info->version) - 1);
        snprintf(info->fw_version, sizeof(info->fw_version) - 1,
                 "%d.%d.%d", (local->sta_fw_ver >> 16) & 0xff,
                 (local->sta_fw_ver >> 8) & 0xff,
index 4743426cf6add721905919080ff5ab477c9542bb..446de51bab74399d8b18db7cd07e085701327693 100644 (file)
@@ -37,7 +37,6 @@
 MODULE_AUTHOR("Jouni Malinen");
 MODULE_DESCRIPTION("Host AP common routines");
 MODULE_LICENSE("GPL");
-MODULE_VERSION(PRISM2_VERSION);
 
 #define TX_TIMEOUT (2 * HZ)
 
index db4899ed4bb1211d4b4a9b0386f32a794638a041..7da3664b85156a2541728f2f68ce82d887267d0f 100644 (file)
@@ -20,7 +20,6 @@
 #include "hostap_wlan.h"
 
 
-static char *version = PRISM2_VERSION " (Jouni Malinen <j@w1.fi>)";
 static char *dev_info = "hostap_pci";
 
 
@@ -29,7 +28,6 @@ MODULE_DESCRIPTION("Support for Intersil Prism2.5-based 802.11 wireless LAN "
                   "PCI cards.");
 MODULE_SUPPORTED_DEVICE("Intersil Prism2.5-based WLAN PCI cards");
 MODULE_LICENSE("GPL");
-MODULE_VERSION(PRISM2_VERSION);
 
 
 /* struct local_info::hw_priv */
@@ -455,15 +453,11 @@ static struct pci_driver prism2_pci_drv_id = {
        .suspend        = prism2_pci_suspend,
        .resume         = prism2_pci_resume,
 #endif /* CONFIG_PM */
-       /* Linux 2.4.6 added save_state and enable_wake that are not used here
-        */
 };
 
 
 static int __init init_prism2_pci(void)
 {
-       printk(KERN_INFO "%s: %s\n", dev_info, version);
-
        return pci_register_driver(&prism2_pci_drv_id);
 }
 
@@ -471,7 +465,6 @@ static int __init init_prism2_pci(void)
 static void __exit exit_prism2_pci(void)
 {
        pci_unregister_driver(&prism2_pci_drv_id);
-       printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
 }
 
 
index f0fd5ecdb24dceb0f2ac8316afbbcbf17a875b85..040dc3e364101162bd3e7b511e3527758c1dab65 100644 (file)
@@ -23,7 +23,6 @@
 #include "hostap_wlan.h"
 
 
-static char *version = PRISM2_VERSION " (Jouni Malinen <j@w1.fi>)";
 static char *dev_info = "hostap_plx";
 
 
@@ -32,7 +31,6 @@ MODULE_DESCRIPTION("Support for Intersil Prism2-based 802.11 wireless LAN "
                   "cards (PLX).");
 MODULE_SUPPORTED_DEVICE("Intersil Prism2-based WLAN cards (PLX)");
 MODULE_LICENSE("GPL");
-MODULE_VERSION(PRISM2_VERSION);
 
 
 static int ignore_cis;
@@ -615,16 +613,11 @@ static struct pci_driver prism2_plx_drv_id = {
        .id_table       = prism2_plx_id_table,
        .probe          = prism2_plx_probe,
        .remove         = prism2_plx_remove,
-       .suspend        = NULL,
-       .resume         = NULL,
-       .enable_wake    = NULL
 };
 
 
 static int __init init_prism2_plx(void)
 {
-       printk(KERN_INFO "%s: %s\n", dev_info, version);
-
        return pci_register_driver(&prism2_plx_drv_id);
 }
 
@@ -632,7 +625,6 @@ static int __init init_prism2_plx(void)
 static void __exit exit_prism2_plx(void)
 {
        pci_unregister_driver(&prism2_plx_drv_id);
-       printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
 }
 
 
index 3dcb13bb7d5782c089da59442a15e24cf3c49ba7..af2e4f2405f2577ae0f047d37827c6eb532054f8 100644 (file)
@@ -87,7 +87,6 @@ static struct pci_driver prism54_driver = {
        .remove = prism54_remove,
        .suspend = prism54_suspend,
        .resume = prism54_resume,
-       /* .enable_wake ; we don't support this yet */
 };
 
 /******************************************************************************
@@ -167,8 +166,7 @@ prism54_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        pci_set_master(pdev);
 
        /* enable MWI */
-       if (!pci_set_mwi(pdev))
-               printk(KERN_INFO "%s: pci_set_mwi(pdev) succeeded\n", DRV_NAME);
+       pci_try_set_mwi(pdev);
 
        /* setup the network device interface and its structure */
        if (!(ndev = islpci_setup(pdev))) {
diff --git a/drivers/net/wireless/rtl8187.h b/drivers/net/wireless/rtl8187.h
new file mode 100644 (file)
index 0000000..6124e46
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * Definitions for RTL8187 hardware
+ *
+ * Copyright 2007 Michael Wu <flamingice@sourmilk.net>
+ * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
+ *
+ * Based on the r8187 driver, which is:
+ * Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef RTL8187_H
+#define RTL8187_H
+
+#include "rtl818x.h"
+
+#define RTL8187_EEPROM_TXPWR_BASE      0x05
+#define RTL8187_EEPROM_MAC_ADDR                0x07
+#define RTL8187_EEPROM_TXPWR_CHAN_1    0x16    /* 3 channels */
+#define RTL8187_EEPROM_TXPWR_CHAN_6    0x1B    /* 2 channels */
+#define RTL8187_EEPROM_TXPWR_CHAN_4    0x3D    /* 2 channels */
+
+#define RTL8187_REQT_READ      0xC0
+#define RTL8187_REQT_WRITE     0x40
+#define RTL8187_REQ_GET_REG    0x05
+#define RTL8187_REQ_SET_REG    0x05
+
+#define RTL8187_MAX_RX         0x9C4
+
+struct rtl8187_rx_info {
+       struct urb *urb;
+       struct ieee80211_hw *dev;
+};
+
+struct rtl8187_rx_hdr {
+       __le16 len;
+       __le16 rate;
+       u8 noise;
+       u8 signal;
+       u8 agc;
+       u8 reserved;
+       __le64 mac_time;
+} __attribute__((packed));
+
+struct rtl8187_tx_info {
+       struct ieee80211_tx_control *control;
+       struct urb *urb;
+       struct ieee80211_hw *dev;
+};
+
+struct rtl8187_tx_hdr {
+       __le32 flags;
+#define RTL8187_TX_FLAG_NO_ENCRYPT     (1 << 15)
+#define RTL8187_TX_FLAG_MORE_FRAG      (1 << 17)
+#define RTL8187_TX_FLAG_CTS            (1 << 18)
+#define RTL8187_TX_FLAG_RTS            (1 << 23)
+       __le16 rts_duration;
+       __le16 len;
+       __le32 retry;
+} __attribute__((packed));
+
+struct rtl8187_priv {
+       /* common between rtl818x drivers */
+       struct rtl818x_csr *map;
+       void (*rf_init)(struct ieee80211_hw *);
+       int mode;
+
+       /* rtl8187 specific */
+       struct ieee80211_channel channels[14];
+       struct ieee80211_rate rates[12];
+       struct ieee80211_hw_mode modes[2];
+       struct usb_device *udev;
+       u8 *hwaddr;
+       u16 txpwr_base;
+       u8 asic_rev;
+       struct sk_buff_head rx_queue;
+};
+
+void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data);
+
+static inline u8 rtl818x_ioread8(struct rtl8187_priv *priv, u8 *addr)
+{
+       u8 val;
+
+       usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0),
+                       RTL8187_REQ_GET_REG, RTL8187_REQT_READ,
+                       (unsigned long)addr, 0, &val, sizeof(val), HZ / 2);
+
+       return val;
+}
+
+static inline u16 rtl818x_ioread16(struct rtl8187_priv *priv, __le16 *addr)
+{
+       __le16 val;
+
+       usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0),
+                       RTL8187_REQ_GET_REG, RTL8187_REQT_READ,
+                       (unsigned long)addr, 0, &val, sizeof(val), HZ / 2);
+
+       return le16_to_cpu(val);
+}
+
+static inline u32 rtl818x_ioread32(struct rtl8187_priv *priv, __le32 *addr)
+{
+       __le32 val;
+
+       usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0),
+                       RTL8187_REQ_GET_REG, RTL8187_REQT_READ,
+                       (unsigned long)addr, 0, &val, sizeof(val), HZ / 2);
+
+       return le32_to_cpu(val);
+}
+
+static inline void rtl818x_iowrite8(struct rtl8187_priv *priv,
+                                   u8 *addr, u8 val)
+{
+       usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
+                       RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
+                       (unsigned long)addr, 0, &val, sizeof(val), HZ / 2);
+}
+
+static inline void rtl818x_iowrite16(struct rtl8187_priv *priv,
+                                    __le16 *addr, u16 val)
+{
+       __le16 buf = cpu_to_le16(val);
+
+       usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
+                       RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
+                       (unsigned long)addr, 0, &buf, sizeof(buf), HZ / 2);
+}
+
+static inline void rtl818x_iowrite32(struct rtl8187_priv *priv,
+                                    __le32 *addr, u32 val)
+{
+       __le32 buf = cpu_to_le32(val);
+
+       usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
+                       RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
+                       (unsigned long)addr, 0, &buf, sizeof(buf), HZ / 2);
+}
+
+#endif /* RTL8187_H */
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c
new file mode 100644 (file)
index 0000000..cea8589
--- /dev/null
@@ -0,0 +1,731 @@
+/*
+ * Linux device driver for RTL8187
+ *
+ * Copyright 2007 Michael Wu <flamingice@sourmilk.net>
+ * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
+ *
+ * Based on the r8187 driver, which is:
+ * Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al.
+ *
+ * Magic delays and register offsets below are taken from the original
+ * r8187 driver sources.  Thanks to Realtek for their support!
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/usb.h>
+#include <linux/delay.h>
+#include <linux/etherdevice.h>
+#include <linux/eeprom_93cx6.h>
+#include <net/mac80211.h>
+
+#include "rtl8187.h"
+#include "rtl8187_rtl8225.h"
+
+MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
+MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
+MODULE_DESCRIPTION("RTL8187 USB wireless driver");
+MODULE_LICENSE("GPL");
+
+static struct usb_device_id rtl8187_table[] __devinitdata = {
+       /* Realtek */
+       {USB_DEVICE(0x0bda, 0x8187)},
+       /* Netgear */
+       {USB_DEVICE(0x0846, 0x6100)},
+       {USB_DEVICE(0x0846, 0x6a00)},
+       {}
+};
+
+MODULE_DEVICE_TABLE(usb, rtl8187_table);
+
+void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data)
+{
+       struct rtl8187_priv *priv = dev->priv;
+
+       data <<= 8;
+       data |= addr | 0x80;
+
+       rtl818x_iowrite8(priv, &priv->map->PHY[3], (data >> 24) & 0xFF);
+       rtl818x_iowrite8(priv, &priv->map->PHY[2], (data >> 16) & 0xFF);
+       rtl818x_iowrite8(priv, &priv->map->PHY[1], (data >> 8) & 0xFF);
+       rtl818x_iowrite8(priv, &priv->map->PHY[0], data & 0xFF);
+
+       msleep(1);
+}
+
+static void rtl8187_tx_cb(struct urb *urb)
+{
+       struct ieee80211_tx_status status = { {0} };
+       struct sk_buff *skb = (struct sk_buff *)urb->context;
+       struct rtl8187_tx_info *info = (struct rtl8187_tx_info *)skb->cb;
+
+       usb_free_urb(info->urb);
+       if (info->control)
+               memcpy(&status.control, info->control, sizeof(status.control));
+       kfree(info->control);
+       skb_pull(skb, sizeof(struct rtl8187_tx_hdr));
+       status.flags |= IEEE80211_TX_STATUS_ACK;
+       ieee80211_tx_status_irqsafe(info->dev, skb, &status);
+}
+
+static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
+                     struct ieee80211_tx_control *control)
+{
+       struct rtl8187_priv *priv = dev->priv;
+       struct rtl8187_tx_hdr *hdr;
+       struct rtl8187_tx_info *info;
+       struct urb *urb;
+       u32 tmp;
+
+       urb = usb_alloc_urb(0, GFP_ATOMIC);
+       if (!urb) {
+               kfree_skb(skb);
+               return 0;
+       }
+
+       hdr = (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr));
+       tmp = skb->len - sizeof(*hdr);
+       tmp |= RTL8187_TX_FLAG_NO_ENCRYPT;
+       tmp |= control->rts_cts_rate << 19;
+       tmp |= control->tx_rate << 24;
+       if (ieee80211_get_morefrag((struct ieee80211_hdr *)skb))
+               tmp |= RTL8187_TX_FLAG_MORE_FRAG;
+       if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) {
+               tmp |= RTL8187_TX_FLAG_RTS;
+               hdr->rts_duration =
+                       ieee80211_rts_duration(dev, skb->len, control);
+       }
+       if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)
+               tmp |= RTL8187_TX_FLAG_CTS;
+       hdr->flags = cpu_to_le32(tmp);
+       hdr->len = 0;
+       tmp = control->retry_limit << 8;
+       hdr->retry = cpu_to_le32(tmp);
+
+       info = (struct rtl8187_tx_info *)skb->cb;
+       info->control = kmemdup(control, sizeof(*control), GFP_ATOMIC);
+       info->urb = urb;
+       info->dev = dev;
+       usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, 2),
+                         hdr, skb->len, rtl8187_tx_cb, skb);
+       usb_submit_urb(urb, GFP_ATOMIC);
+
+       return 0;
+}
+
+static void rtl8187_rx_cb(struct urb *urb)
+{
+       struct sk_buff *skb = (struct sk_buff *)urb->context;
+       struct rtl8187_rx_info *info = (struct rtl8187_rx_info *)skb->cb;
+       struct ieee80211_hw *dev = info->dev;
+       struct rtl8187_priv *priv = dev->priv;
+       struct rtl8187_rx_hdr *hdr;
+       struct ieee80211_rx_status rx_status = { 0 };
+       int rate, signal;
+
+       spin_lock(&priv->rx_queue.lock);
+       if (skb->next)
+               __skb_unlink(skb, &priv->rx_queue);
+       else {
+               spin_unlock(&priv->rx_queue.lock);
+               return;
+       }
+       spin_unlock(&priv->rx_queue.lock);
+
+       if (unlikely(urb->status)) {
+               usb_free_urb(urb);
+               dev_kfree_skb_irq(skb);
+               return;
+       }
+
+       skb_put(skb, urb->actual_length);
+       hdr = (struct rtl8187_rx_hdr *)(skb_tail_pointer(skb) - sizeof(*hdr));
+       skb_trim(skb, le16_to_cpu(hdr->len) & 0x0FFF);
+
+       signal = hdr->agc >> 1;
+       rate = (le16_to_cpu(hdr->rate) >> 4) & 0xF;
+       if (rate > 3) { /* OFDM rate */
+               if (signal > 90)
+                       signal = 90;
+               else if (signal < 25)
+                       signal = 25;
+               signal = 90 - signal;
+       } else {        /* CCK rate */
+               if (signal > 95)
+                       signal = 95;
+               else if (signal < 30)
+                       signal = 30;
+               signal = 95 - signal;
+       }
+
+       rx_status.antenna = (hdr->signal >> 7) & 1;
+       rx_status.signal = 64 - min(hdr->noise, (u8)64);
+       rx_status.ssi = signal;
+       rx_status.rate = rate;
+       rx_status.freq = dev->conf.freq;
+       rx_status.channel = dev->conf.channel;
+       rx_status.phymode = dev->conf.phymode;
+       rx_status.mactime = le64_to_cpu(hdr->mac_time);
+       ieee80211_rx_irqsafe(dev, skb, &rx_status);
+
+       skb = dev_alloc_skb(RTL8187_MAX_RX);
+       if (unlikely(!skb)) {
+               usb_free_urb(urb);
+               /* TODO check rx queue length and refill *somewhere* */
+               return;
+       }
+
+       info = (struct rtl8187_rx_info *)skb->cb;
+       info->urb = urb;
+       info->dev = dev;
+       urb->transfer_buffer = skb_tail_pointer(skb);
+       urb->context = skb;
+       skb_queue_tail(&priv->rx_queue, skb);
+
+       usb_submit_urb(urb, GFP_ATOMIC);
+}
+
+static int rtl8187_init_urbs(struct ieee80211_hw *dev)
+{
+       struct rtl8187_priv *priv = dev->priv;
+       struct urb *entry;
+       struct sk_buff *skb;
+       struct rtl8187_rx_info *info;
+
+       while (skb_queue_len(&priv->rx_queue) < 8) {
+               skb = __dev_alloc_skb(RTL8187_MAX_RX, GFP_KERNEL);
+               if (!skb)
+                       break;
+               entry = usb_alloc_urb(0, GFP_KERNEL);
+               if (!entry) {
+                       kfree_skb(skb);
+                       break;
+               }
+               usb_fill_bulk_urb(entry, priv->udev,
+                                 usb_rcvbulkpipe(priv->udev, 1),
+                                 skb_tail_pointer(skb),
+                                 RTL8187_MAX_RX, rtl8187_rx_cb, skb);
+               info = (struct rtl8187_rx_info *)skb->cb;
+               info->urb = entry;
+               info->dev = dev;
+               skb_queue_tail(&priv->rx_queue, skb);
+               usb_submit_urb(entry, GFP_KERNEL);
+       }
+
+       return 0;
+}
+
+static int rtl8187_init_hw(struct ieee80211_hw *dev)
+{
+       struct rtl8187_priv *priv = dev->priv;
+       u8 reg;
+       int i;
+
+       /* reset */
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
+       reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
+       rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
+       rtl818x_iowrite32(priv, &priv->map->ANAPARAM, RTL8225_ANAPARAM_ON);
+       rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON);
+       rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
+
+       rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0);
+
+       msleep(200);
+       rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x10);
+       rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x11);
+       rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x00);
+       msleep(200);
+
+       reg = rtl818x_ioread8(priv, &priv->map->CMD);
+       reg &= (1 << 1);
+       reg |= RTL818X_CMD_RESET;
+       rtl818x_iowrite8(priv, &priv->map->CMD, reg);
+
+       i = 10;
+       do {
+               msleep(2);
+               if (!(rtl818x_ioread8(priv, &priv->map->CMD) &
+                     RTL818X_CMD_RESET))
+                       break;
+       } while (--i);
+
+       if (!i) {
+               printk(KERN_ERR "%s: Reset timeout!\n", wiphy_name(dev->wiphy));
+               return -ETIMEDOUT;
+       }
+
+       /* reload registers from eeprom */
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_LOAD);
+
+       i = 10;
+       do {
+               msleep(4);
+               if (!(rtl818x_ioread8(priv, &priv->map->EEPROM_CMD) &
+                     RTL818X_EEPROM_CMD_CONFIG))
+                       break;
+       } while (--i);
+
+       if (!i) {
+               printk(KERN_ERR "%s: eeprom reset timeout!\n",
+                      wiphy_name(dev->wiphy));
+               return -ETIMEDOUT;
+       }
+
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
+       reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
+       rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
+       rtl818x_iowrite32(priv, &priv->map->ANAPARAM, RTL8225_ANAPARAM_ON);
+       rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON);
+       rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
+
+       /* setup card */
+       rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0);
+       rtl818x_iowrite8(priv, &priv->map->GPIO, 0);
+
+       rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, (4 << 8));
+       rtl818x_iowrite8(priv, &priv->map->GPIO, 1);
+       rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0);
+
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
+       for (i = 0; i < ETH_ALEN; i++)
+               rtl818x_iowrite8(priv, &priv->map->MAC[i], priv->hwaddr[i]);
+
+       rtl818x_iowrite16(priv, (__le16 *)0xFFF4, 0xFFFF);
+       reg = rtl818x_ioread8(priv, &priv->map->CONFIG1);
+       reg &= 0x3F;
+       reg |= 0x80;
+       rtl818x_iowrite8(priv, &priv->map->CONFIG1, reg);
+
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
+
+       rtl818x_iowrite32(priv, &priv->map->INT_TIMEOUT, 0);
+       rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0);
+       rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0x81);
+
+       // TODO: set RESP_RATE and BRSR properly
+       rtl818x_iowrite8(priv, &priv->map->RESP_RATE, (8 << 4) | 0);
+       rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3);
+
+       /* host_usb_init */
+       rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0);
+       rtl818x_iowrite8(priv, &priv->map->GPIO, 0);
+       reg = rtl818x_ioread8(priv, (u8 *)0xFE53);
+       rtl818x_iowrite8(priv, (u8 *)0xFE53, reg | (1 << 7));
+       rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, (4 << 8));
+       rtl818x_iowrite8(priv, &priv->map->GPIO, 0x20);
+       rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0);
+       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x80);
+       rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x80);
+       rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x80);
+       msleep(100);
+
+       rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x000a8008);
+       rtl818x_iowrite16(priv, &priv->map->BRSR, 0xFFFF);
+       rtl818x_iowrite32(priv, &priv->map->RF_PARA, 0x00100044);
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
+       rtl818x_iowrite8(priv, &priv->map->CONFIG3, 0x44);
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
+       rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FF7);
+       msleep(100);
+
+       priv->rf_init(dev);
+
+       rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3);
+       reg = rtl818x_ioread16(priv, &priv->map->PGSELECT) & 0xfffe;
+       rtl818x_iowrite16(priv, &priv->map->PGSELECT, reg | 0x1);
+       rtl818x_iowrite16(priv, (__le16 *)0xFFFE, 0x10);
+       rtl818x_iowrite8(priv, &priv->map->TALLY_SEL, 0x80);
+       rtl818x_iowrite8(priv, (u8 *)0xFFFF, 0x60);
+       rtl818x_iowrite16(priv, &priv->map->PGSELECT, reg);
+
+       return 0;
+}
+
+static void rtl8187_set_channel(struct ieee80211_hw *dev, int channel)
+{
+       u32 reg;
+       struct rtl8187_priv *priv = dev->priv;
+
+       reg = rtl818x_ioread32(priv, &priv->map->TX_CONF);
+       /* Enable TX loopback on MAC level to avoid TX during channel
+        * changes, as this has be seen to causes problems and the
+        * card will stop work until next reset
+        */
+       rtl818x_iowrite32(priv, &priv->map->TX_CONF,
+                         reg | RTL818X_TX_CONF_LOOPBACK_MAC);
+       msleep(10);
+       rtl8225_rf_set_channel(dev, channel);
+       msleep(10);
+       rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg);
+}
+
+static int rtl8187_open(struct ieee80211_hw *dev)
+{
+       struct rtl8187_priv *priv = dev->priv;
+       u32 reg;
+       int ret;
+
+       ret = rtl8187_init_hw(dev);
+       if (ret)
+               return ret;
+
+       rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF);
+
+       rtl8187_init_urbs(dev);
+
+       reg = RTL818X_RX_CONF_ONLYERLPKT |
+             RTL818X_RX_CONF_RX_AUTORESETPHY |
+             RTL818X_RX_CONF_BSSID |
+             RTL818X_RX_CONF_MGMT |
+             RTL818X_RX_CONF_CTRL |
+             RTL818X_RX_CONF_DATA |
+             (7 << 13 /* RX FIFO threshold NONE */) |
+             (7 << 10 /* MAX RX DMA */) |
+             RTL818X_RX_CONF_BROADCAST |
+             RTL818X_RX_CONF_MULTICAST |
+             RTL818X_RX_CONF_NICMAC;
+       if (priv->mode == IEEE80211_IF_TYPE_MNTR)
+               reg |= RTL818X_RX_CONF_MONITOR;
+
+       rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg);
+
+       reg = rtl818x_ioread8(priv, &priv->map->CW_CONF);
+       reg &= ~RTL818X_CW_CONF_PERPACKET_CW_SHIFT;
+       reg |= RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT;
+       rtl818x_iowrite8(priv, &priv->map->CW_CONF, reg);
+
+       reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL);
+       reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT;
+       reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT;
+       reg &= ~RTL818X_TX_AGC_CTL_FEEDBACK_ANT;
+       rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg);
+
+       reg  = RTL818X_TX_CONF_CW_MIN |
+              (7 << 21 /* MAX TX DMA */) |
+              RTL818X_TX_CONF_NO_ICV;
+       rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg);
+
+       reg = rtl818x_ioread8(priv, &priv->map->CMD);
+       reg |= RTL818X_CMD_TX_ENABLE;
+       reg |= RTL818X_CMD_RX_ENABLE;
+       rtl818x_iowrite8(priv, &priv->map->CMD, reg);
+
+       return 0;
+}
+
+static int rtl8187_stop(struct ieee80211_hw *dev)
+{
+       struct rtl8187_priv *priv = dev->priv;
+       struct rtl8187_rx_info *info;
+       struct sk_buff *skb;
+       u32 reg;
+
+       rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0);
+
+       reg = rtl818x_ioread8(priv, &priv->map->CMD);
+       reg &= ~RTL818X_CMD_TX_ENABLE;
+       reg &= ~RTL818X_CMD_RX_ENABLE;
+       rtl818x_iowrite8(priv, &priv->map->CMD, reg);
+
+       rtl8225_rf_stop(dev);
+
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
+       reg = rtl818x_ioread8(priv, &priv->map->CONFIG4);
+       rtl818x_iowrite8(priv, &priv->map->CONFIG4, reg | RTL818X_CONFIG4_VCOOFF);
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
+
+       while ((skb = skb_dequeue(&priv->rx_queue))) {
+               info = (struct rtl8187_rx_info *)skb->cb;
+               usb_kill_urb(info->urb);
+               kfree_skb(skb);
+       }
+       return 0;
+}
+
+static int rtl8187_add_interface(struct ieee80211_hw *dev,
+                                struct ieee80211_if_init_conf *conf)
+{
+       struct rtl8187_priv *priv = dev->priv;
+
+       /* NOTE: using IEEE80211_IF_TYPE_MGMT to indicate no mode selected */
+       if (priv->mode != IEEE80211_IF_TYPE_MGMT)
+               return -1;
+
+       switch (conf->type) {
+       case IEEE80211_IF_TYPE_STA:
+       case IEEE80211_IF_TYPE_MNTR:
+               priv->mode = conf->type;
+               break;
+       default:
+               return -EOPNOTSUPP;
+       }
+
+       priv->hwaddr = conf->mac_addr;
+
+       return 0;
+}
+
+static void rtl8187_remove_interface(struct ieee80211_hw *dev,
+                                    struct ieee80211_if_init_conf *conf)
+{
+       struct rtl8187_priv *priv = dev->priv;
+       priv->mode = IEEE80211_IF_TYPE_MGMT;
+}
+
+static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
+{
+       struct rtl8187_priv *priv = dev->priv;
+       rtl8187_set_channel(dev, conf->channel);
+
+       rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22);
+
+       if (conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME) {
+               rtl818x_iowrite8(priv, &priv->map->SLOT, 0x9);
+               rtl818x_iowrite8(priv, &priv->map->DIFS, 0x14);
+               rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x14);
+               rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0x73);
+       } else {
+               rtl818x_iowrite8(priv, &priv->map->SLOT, 0x14);
+               rtl818x_iowrite8(priv, &priv->map->DIFS, 0x24);
+               rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x24);
+               rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0xa5);
+       }
+
+       rtl818x_iowrite16(priv, &priv->map->ATIM_WND, 2);
+       rtl818x_iowrite16(priv, &priv->map->ATIMTR_INTERVAL, 100);
+       rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL, 100);
+       rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL_TIME, 100);
+       return 0;
+}
+
+static int rtl8187_config_interface(struct ieee80211_hw *dev, int if_id,
+                                   struct ieee80211_if_conf *conf)
+{
+       struct rtl8187_priv *priv = dev->priv;
+       int i;
+
+       for (i = 0; i < ETH_ALEN; i++)
+               rtl818x_iowrite8(priv, &priv->map->BSSID[i], conf->bssid[i]);
+
+       if (is_valid_ether_addr(conf->bssid))
+               rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_INFRA);
+       else
+               rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_NO_LINK);
+
+       return 0;
+}
+
+static const struct ieee80211_ops rtl8187_ops = {
+       .tx                     = rtl8187_tx,
+       .open                   = rtl8187_open,
+       .stop                   = rtl8187_stop,
+       .add_interface          = rtl8187_add_interface,
+       .remove_interface       = rtl8187_remove_interface,
+       .config                 = rtl8187_config,
+       .config_interface       = rtl8187_config_interface,
+};
+
+static void rtl8187_eeprom_register_read(struct eeprom_93cx6 *eeprom)
+{
+       struct ieee80211_hw *dev = eeprom->data;
+       struct rtl8187_priv *priv = dev->priv;
+       u8 reg = rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
+
+       eeprom->reg_data_in = reg & RTL818X_EEPROM_CMD_WRITE;
+       eeprom->reg_data_out = reg & RTL818X_EEPROM_CMD_READ;
+       eeprom->reg_data_clock = reg & RTL818X_EEPROM_CMD_CK;
+       eeprom->reg_chip_select = reg & RTL818X_EEPROM_CMD_CS;
+}
+
+static void rtl8187_eeprom_register_write(struct eeprom_93cx6 *eeprom)
+{
+       struct ieee80211_hw *dev = eeprom->data;
+       struct rtl8187_priv *priv = dev->priv;
+       u8 reg = RTL818X_EEPROM_CMD_PROGRAM;
+
+       if (eeprom->reg_data_in)
+               reg |= RTL818X_EEPROM_CMD_WRITE;
+       if (eeprom->reg_data_out)
+               reg |= RTL818X_EEPROM_CMD_READ;
+       if (eeprom->reg_data_clock)
+               reg |= RTL818X_EEPROM_CMD_CK;
+       if (eeprom->reg_chip_select)
+               reg |= RTL818X_EEPROM_CMD_CS;
+
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, reg);
+       udelay(10);
+}
+
+static int __devinit rtl8187_probe(struct usb_interface *intf,
+                                  const struct usb_device_id *id)
+{
+       struct usb_device *udev = interface_to_usbdev(intf);
+       struct ieee80211_hw *dev;
+       struct rtl8187_priv *priv;
+       struct eeprom_93cx6 eeprom;
+       struct ieee80211_channel *channel;
+       u16 txpwr, reg;
+       int err, i;
+
+       dev = ieee80211_alloc_hw(sizeof(*priv), &rtl8187_ops);
+       if (!dev) {
+               printk(KERN_ERR "rtl8187: ieee80211 alloc failed\n");
+               return -ENOMEM;
+       }
+
+       priv = dev->priv;
+
+       SET_IEEE80211_DEV(dev, &intf->dev);
+       usb_set_intfdata(intf, dev);
+       priv->udev = udev;
+
+       usb_get_dev(udev);
+
+       skb_queue_head_init(&priv->rx_queue);
+       memcpy(priv->channels, rtl818x_channels, sizeof(rtl818x_channels));
+       memcpy(priv->rates, rtl818x_rates, sizeof(rtl818x_rates));
+       priv->map = (struct rtl818x_csr *)0xFF00;
+       priv->modes[0].mode = MODE_IEEE80211G;
+       priv->modes[0].num_rates = ARRAY_SIZE(rtl818x_rates);
+       priv->modes[0].rates = priv->rates;
+       priv->modes[0].num_channels = ARRAY_SIZE(rtl818x_channels);
+       priv->modes[0].channels = priv->channels;
+       priv->modes[1].mode = MODE_IEEE80211B;
+       priv->modes[1].num_rates = 4;
+       priv->modes[1].rates = priv->rates;
+       priv->modes[1].num_channels = ARRAY_SIZE(rtl818x_channels);
+       priv->modes[1].channels = priv->channels;
+       priv->mode = IEEE80211_IF_TYPE_MGMT;
+       dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
+                    IEEE80211_HW_RX_INCLUDES_FCS |
+                    IEEE80211_HW_WEP_INCLUDE_IV |
+                    IEEE80211_HW_DATA_NULLFUNC_ACK;
+       dev->extra_tx_headroom = sizeof(struct rtl8187_tx_hdr);
+       dev->queues = 1;
+       dev->max_rssi = 65;
+       dev->max_signal = 64;
+
+       for (i = 0; i < 2; i++)
+               if ((err = ieee80211_register_hwmode(dev, &priv->modes[i])))
+                       goto err_free_dev;
+
+       eeprom.data = dev;
+       eeprom.register_read = rtl8187_eeprom_register_read;
+       eeprom.register_write = rtl8187_eeprom_register_write;
+       if (rtl818x_ioread32(priv, &priv->map->RX_CONF) & (1 << 6))
+               eeprom.width = PCI_EEPROM_WIDTH_93C66;
+       else
+               eeprom.width = PCI_EEPROM_WIDTH_93C46;
+
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
+       udelay(10);
+
+       eeprom_93cx6_multiread(&eeprom, RTL8187_EEPROM_MAC_ADDR,
+                              (__le16 __force *)dev->wiphy->perm_addr, 3);
+       if (!is_valid_ether_addr(dev->wiphy->perm_addr)) {
+               printk(KERN_WARNING "rtl8187: Invalid hwaddr! Using randomly "
+                      "generated MAC address\n");
+               random_ether_addr(dev->wiphy->perm_addr);
+       }
+
+       channel = priv->channels;
+       for (i = 0; i < 3; i++) {
+               eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_1 + i,
+                                 &txpwr);
+               (*channel++).val = txpwr & 0xFF;
+               (*channel++).val = txpwr >> 8;
+       }
+       for (i = 0; i < 2; i++) {
+               eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_4 + i,
+                                 &txpwr);
+               (*channel++).val = txpwr & 0xFF;
+               (*channel++).val = txpwr >> 8;
+       }
+       for (i = 0; i < 2; i++) {
+               eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_6 + i,
+                                 &txpwr);
+               (*channel++).val = txpwr & 0xFF;
+               (*channel++).val = txpwr >> 8;
+       }
+
+       eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_BASE,
+                         &priv->txpwr_base);
+
+       reg = rtl818x_ioread16(priv, &priv->map->PGSELECT) & ~1;
+       rtl818x_iowrite16(priv, &priv->map->PGSELECT, reg | 1);
+       /* 0 means asic B-cut, we should use SW 3 wire
+        * bit-by-bit banging for radio. 1 means we can use
+        * USB specific request to write radio registers */
+       priv->asic_rev = rtl818x_ioread8(priv, (u8 *)0xFFFE) & 0x3;
+       rtl818x_iowrite16(priv, &priv->map->PGSELECT, reg);
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
+
+       rtl8225_write(dev, 0, 0x1B7);
+
+       if (rtl8225_read(dev, 8) != 0x588 || rtl8225_read(dev, 9) != 0x700)
+               priv->rf_init = rtl8225_rf_init;
+       else
+               priv->rf_init = rtl8225z2_rf_init;
+
+       rtl8225_write(dev, 0, 0x0B7);
+
+       err = ieee80211_register_hw(dev);
+       if (err) {
+               printk(KERN_ERR "rtl8187: Cannot register device\n");
+               goto err_free_dev;
+       }
+
+       printk(KERN_INFO "%s: hwaddr " MAC_FMT ", rtl8187 V%d + %s\n",
+              wiphy_name(dev->wiphy), MAC_ARG(dev->wiphy->perm_addr),
+              priv->asic_rev, priv->rf_init == rtl8225_rf_init ?
+              "rtl8225" : "rtl8225z2");
+
+       return 0;
+
+ err_free_dev:
+       ieee80211_free_hw(dev);
+       usb_set_intfdata(intf, NULL);
+       usb_put_dev(udev);
+       return err;
+}
+
+static void __devexit rtl8187_disconnect(struct usb_interface *intf)
+{
+       struct ieee80211_hw *dev = usb_get_intfdata(intf);
+       struct rtl8187_priv *priv;
+
+       if (!dev)
+               return;
+
+       ieee80211_unregister_hw(dev);
+
+       priv = dev->priv;
+       usb_put_dev(interface_to_usbdev(intf));
+       ieee80211_free_hw(dev);
+}
+
+static struct usb_driver rtl8187_driver = {
+       .name           = KBUILD_MODNAME,
+       .id_table       = rtl8187_table,
+       .probe          = rtl8187_probe,
+       .disconnect     = rtl8187_disconnect,
+};
+
+static int __init rtl8187_init(void)
+{
+       return usb_register(&rtl8187_driver);
+}
+
+static void __exit rtl8187_exit(void)
+{
+       usb_deregister(&rtl8187_driver);
+}
+
+module_init(rtl8187_init);
+module_exit(rtl8187_exit);
diff --git a/drivers/net/wireless/rtl8187_rtl8225.c b/drivers/net/wireless/rtl8187_rtl8225.c
new file mode 100644 (file)
index 0000000..e25a09f
--- /dev/null
@@ -0,0 +1,745 @@
+/*
+ * Radio tuning for RTL8225 on RTL8187
+ *
+ * Copyright 2007 Michael Wu <flamingice@sourmilk.net>
+ * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
+ *
+ * Based on the r8187 driver, which is:
+ * Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al.
+ *
+ * Magic delays, register offsets, and phy value tables below are
+ * taken from the original r8187 driver sources.  Thanks to Realtek
+ * for their support!
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/usb.h>
+#include <net/mac80211.h>
+
+#include "rtl8187.h"
+#include "rtl8187_rtl8225.h"
+
+static void rtl8225_write_bitbang(struct ieee80211_hw *dev, u8 addr, u16 data)
+{
+       struct rtl8187_priv *priv = dev->priv;
+       u16 reg80, reg84, reg82;
+       u32 bangdata;
+       int i;
+
+       bangdata = (data << 4) | (addr & 0xf);
+
+       reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput) & 0xfff3;
+       reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable);
+
+       rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x7);
+
+       reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect);
+       rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x7);
+       udelay(10);
+
+       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
+       udelay(2);
+       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80);
+       udelay(10);
+
+       for (i = 15; i >= 0; i--) {
+               u16 reg = reg80 | (bangdata & (1 << i)) >> i;
+
+               if (i & 1)
+                       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
+
+               rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1));
+               rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1));
+
+               if (!(i & 1))
+                       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
+       }
+
+       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
+       udelay(10);
+
+       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
+       rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84);
+       msleep(2);
+}
+
+static void rtl8225_write_8051(struct ieee80211_hw *dev, u8 addr, u16 data)
+{
+       struct rtl8187_priv *priv = dev->priv;
+       u16 reg80, reg82, reg84;
+
+       reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput);
+       reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable);
+       reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect);
+
+       reg80 &= ~(0x3 << 2);
+       reg84 &= ~0xF;
+
+       rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x0007);
+       rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x0007);
+       udelay(10);
+
+       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
+       udelay(2);
+
+       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80);
+       udelay(10);
+
+       usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
+                       RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
+                       addr, 0x8225, &data, sizeof(data), HZ / 2);
+
+       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
+       udelay(10);
+
+       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
+       rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84);
+       msleep(2);
+}
+
+void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data)
+{
+       struct rtl8187_priv *priv = dev->priv;
+
+       if (priv->asic_rev)
+               rtl8225_write_8051(dev, addr, data);
+       else
+               rtl8225_write_bitbang(dev, addr, data);
+}
+
+u16 rtl8225_read(struct ieee80211_hw *dev, u8 addr)
+{
+       struct rtl8187_priv *priv = dev->priv;
+       u16 reg80, reg82, reg84, out;
+       int i;
+
+       reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput);
+       reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable);
+       reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect);
+
+       reg80 &= ~0xF;
+
+       rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x000F);
+       rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x000F);
+
+       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
+       udelay(4);
+       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80);
+       udelay(5);
+
+       for (i = 4; i >= 0; i--) {
+               u16 reg = reg80 | ((addr >> i) & 1);
+
+               if (!(i & 1)) {
+                       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
+                       udelay(1);
+               }
+
+               rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
+                                 reg | (1 << 1));
+               udelay(2);
+               rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
+                                 reg | (1 << 1));
+               udelay(2);
+
+               if (i & 1) {
+                       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
+                       udelay(1);
+               }
+       }
+
+       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
+                         reg80 | (1 << 3) | (1 << 1));
+       udelay(2);
+       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
+                         reg80 | (1 << 3));
+       udelay(2);
+       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
+                         reg80 | (1 << 3));
+       udelay(2);
+
+       out = 0;
+       for (i = 11; i >= 0; i--) {
+               rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
+                                 reg80 | (1 << 3));
+               udelay(1);
+               rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
+                                 reg80 | (1 << 3) | (1 << 1));
+               udelay(2);
+               rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
+                                 reg80 | (1 << 3) | (1 << 1));
+               udelay(2);
+               rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
+                                 reg80 | (1 << 3) | (1 << 1));
+               udelay(2);
+
+               if (rtl818x_ioread16(priv, &priv->map->RFPinsInput) & (1 << 1))
+                       out |= 1 << i;
+
+               rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
+                                 reg80 | (1 << 3));
+               udelay(2);
+       }
+
+       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
+                         reg80 | (1 << 3) | (1 << 2));
+       udelay(2);
+
+       rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82);
+       rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84);
+       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x03A0);
+
+       return out;
+}
+
+static const u16 rtl8225bcd_rxgain[] = {
+       0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
+       0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
+       0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
+       0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
+       0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
+       0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
+       0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
+       0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
+       0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
+       0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
+       0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
+       0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
+};
+
+static const u8 rtl8225_agc[] = {
+       0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
+       0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96,
+       0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 0x8f, 0x8e,
+       0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86,
+       0x85, 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e,
+       0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37, 0x36,
+       0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f, 0x2e,
+       0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26,
+       0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e,
+       0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16,
+       0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e,
+       0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06,
+       0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01,
+       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
+};
+
+static const u8 rtl8225_gain[] = {
+       0x23, 0x88, 0x7c, 0xa5, /* -82dBm */
+       0x23, 0x88, 0x7c, 0xb5, /* -82dBm */
+       0x23, 0x88, 0x7c, 0xc5, /* -82dBm */
+       0x33, 0x80, 0x79, 0xc5, /* -78dBm */
+       0x43, 0x78, 0x76, 0xc5, /* -74dBm */
+       0x53, 0x60, 0x73, 0xc5, /* -70dBm */
+       0x63, 0x58, 0x70, 0xc5, /* -66dBm */
+};
+
+static const u8 rtl8225_threshold[] = {
+       0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd
+};
+
+static const u8 rtl8225_tx_gain_cck_ofdm[] = {
+       0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e
+};
+
+static const u8 rtl8225_tx_power_cck[] = {
+       0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02,
+       0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02,
+       0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02,
+       0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02,
+       0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03,
+       0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03
+};
+
+static const u8 rtl8225_tx_power_cck_ch14[] = {
+       0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00,
+       0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00,
+       0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00,
+       0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00,
+       0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
+       0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00
+};
+
+static const u8 rtl8225_tx_power_ofdm[] = {
+       0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4
+};
+
+static const u32 rtl8225_chan[] = {
+       0x085c, 0x08dc, 0x095c, 0x09dc, 0x0a5c, 0x0adc, 0x0b5c,
+       0x0bdc, 0x0c5c, 0x0cdc, 0x0d5c, 0x0ddc, 0x0e5c, 0x0f72
+};
+
+static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
+{
+       struct rtl8187_priv *priv = dev->priv;
+       u8 cck_power, ofdm_power;
+       const u8 *tmp;
+       u32 reg;
+       int i;
+
+       cck_power = priv->channels[channel - 1].val & 0xF;
+       ofdm_power = priv->channels[channel - 1].val >> 4;
+
+       cck_power = min(cck_power, (u8)11);
+       ofdm_power = min(ofdm_power, (u8)35);
+
+       rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK,
+                        rtl8225_tx_gain_cck_ofdm[cck_power / 6] >> 1);
+
+       if (channel == 14)
+               tmp = &rtl8225_tx_power_cck_ch14[(cck_power % 6) * 8];
+       else
+               tmp = &rtl8225_tx_power_cck[(cck_power % 6) * 8];
+
+       for (i = 0; i < 8; i++)
+               rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++);
+
+       msleep(1); // FIXME: optional?
+
+       /* anaparam2 on */
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
+       reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
+       rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
+       rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON);
+       rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
+
+       rtl8225_write_phy_ofdm(dev, 2, 0x42);
+       rtl8225_write_phy_ofdm(dev, 6, 0x00);
+       rtl8225_write_phy_ofdm(dev, 8, 0x00);
+
+       rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM,
+                        rtl8225_tx_gain_cck_ofdm[ofdm_power / 6] >> 1);
+
+       tmp = &rtl8225_tx_power_ofdm[ofdm_power % 6];
+
+       rtl8225_write_phy_ofdm(dev, 5, *tmp);
+       rtl8225_write_phy_ofdm(dev, 7, *tmp);
+
+       msleep(1);
+}
+
+void rtl8225_rf_init(struct ieee80211_hw *dev)
+{
+       struct rtl8187_priv *priv = dev->priv;
+       int i;
+
+       rtl8225_write(dev, 0x0, 0x067); msleep(1);
+       rtl8225_write(dev, 0x1, 0xFE0); msleep(1);
+       rtl8225_write(dev, 0x2, 0x44D); msleep(1);
+       rtl8225_write(dev, 0x3, 0x441); msleep(1);
+       rtl8225_write(dev, 0x4, 0x486); msleep(1);
+       rtl8225_write(dev, 0x5, 0xBC0); msleep(1);
+       rtl8225_write(dev, 0x6, 0xAE6); msleep(1);
+       rtl8225_write(dev, 0x7, 0x82A); msleep(1);
+       rtl8225_write(dev, 0x8, 0x01F); msleep(1);
+       rtl8225_write(dev, 0x9, 0x334); msleep(1);
+       rtl8225_write(dev, 0xA, 0xFD4); msleep(1);
+       rtl8225_write(dev, 0xB, 0x391); msleep(1);
+       rtl8225_write(dev, 0xC, 0x050); msleep(1);
+       rtl8225_write(dev, 0xD, 0x6DB); msleep(1);
+       rtl8225_write(dev, 0xE, 0x029); msleep(1);
+       rtl8225_write(dev, 0xF, 0x914); msleep(100);
+
+       rtl8225_write(dev, 0x2, 0xC4D); msleep(200);
+       rtl8225_write(dev, 0x2, 0x44D); msleep(200);
+
+       if (!(rtl8225_read(dev, 6) & (1 << 7))) {
+               rtl8225_write(dev, 0x02, 0x0c4d);
+               msleep(200);
+               rtl8225_write(dev, 0x02, 0x044d);
+               msleep(100);
+               if (!(rtl8225_read(dev, 6) & (1 << 7)))
+                       printk(KERN_WARNING "%s: RF Calibration Failed! %x\n",
+                              wiphy_name(dev->wiphy), rtl8225_read(dev, 6));
+       }
+
+       rtl8225_write(dev, 0x0, 0x127);
+
+       for (i = 0; i < ARRAY_SIZE(rtl8225bcd_rxgain); i++) {
+               rtl8225_write(dev, 0x1, i + 1);
+               rtl8225_write(dev, 0x2, rtl8225bcd_rxgain[i]);
+       }
+
+       rtl8225_write(dev, 0x0, 0x027);
+       rtl8225_write(dev, 0x0, 0x22F);
+
+       for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) {
+               rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]);
+               msleep(1);
+               rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i);
+               msleep(1);
+       }
+
+       msleep(1);
+
+       rtl8225_write_phy_ofdm(dev, 0x00, 0x01); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x01, 0x02); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x02, 0x42); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x03, 0x00); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x04, 0x00); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x05, 0x00); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x06, 0x40); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x07, 0x00); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x08, 0x40); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x0a, 0x09); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x10, 0x84); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x11, 0x06); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x12, 0x20); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x13, 0x20); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x14, 0x00); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x15, 0x40); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x16, 0x00); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x17, 0x40); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x19, 0x19); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x1b, 0x76); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x1e, 0x95); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x21, 0x27); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x22, 0x16); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x24, 0x46); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x25, 0x20); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x27, 0x88); msleep(1);
+
+       rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[2 * 4]);
+       rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[2 * 4 + 2]);
+       rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[2 * 4 + 3]);
+       rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[2 * 4 + 1]);
+
+       rtl8225_write_phy_cck(dev, 0x00, 0x98); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x03, 0x20); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x04, 0x7e); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x05, 0x12); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x06, 0xfc); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x07, 0x78); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x08, 0x2e); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x11, 0x88); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x12, 0x47); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x13, 0xd0);
+       rtl8225_write_phy_cck(dev, 0x19, 0x00);
+       rtl8225_write_phy_cck(dev, 0x1a, 0xa0);
+       rtl8225_write_phy_cck(dev, 0x1b, 0x08);
+       rtl8225_write_phy_cck(dev, 0x40, 0x86);
+       rtl8225_write_phy_cck(dev, 0x41, 0x8d); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x42, 0x15); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x43, 0x18); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x44, 0x1f); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x45, 0x1e); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x46, 0x1a); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x47, 0x15); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x48, 0x10); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x49, 0x0a); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x4a, 0x05); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x4b, 0x02); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x4c, 0x05); msleep(1);
+
+       rtl818x_iowrite8(priv, &priv->map->TESTR, 0x0D);
+
+       rtl8225_rf_set_tx_power(dev, 1);
+
+       /* RX antenna default to A */
+       rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1);      /* B: 0xDB */
+       rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1);     /* B: 0x10 */
+
+       rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03);   /* B: 0x00 */
+       msleep(1);
+       rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002);
+
+       /* set sensitivity */
+       rtl8225_write(dev, 0x0c, 0x50);
+       rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[2 * 4]);
+       rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[2 * 4 + 2]);
+       rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[2 * 4 + 3]);
+       rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[2 * 4 + 1]);
+       rtl8225_write_phy_cck(dev, 0x41, rtl8225_threshold[2]);
+}
+
+static const u8 rtl8225z2_tx_power_cck_ch14[] = {
+       0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00
+};
+
+static const u8 rtl8225z2_tx_power_cck[] = {
+       0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04
+};
+
+static const u8 rtl8225z2_tx_power_ofdm[] = {
+       0x42, 0x00, 0x40, 0x00, 0x40
+};
+
+static const u8 rtl8225z2_tx_gain_cck_ofdm[] = {
+       0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
+       0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
+       0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
+       0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+       0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
+       0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23
+};
+
+static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
+{
+       struct rtl8187_priv *priv = dev->priv;
+       u8 cck_power, ofdm_power;
+       const u8 *tmp;
+       u32 reg;
+       int i;
+
+       cck_power = priv->channels[channel - 1].val & 0xF;
+       ofdm_power = priv->channels[channel - 1].val >> 4;
+
+       cck_power = min(cck_power, (u8)15);
+       cck_power += priv->txpwr_base & 0xF;
+       cck_power = min(cck_power, (u8)35);
+
+       ofdm_power = min(ofdm_power, (u8)15);
+       ofdm_power += priv->txpwr_base >> 4;
+       ofdm_power = min(ofdm_power, (u8)35);
+
+       if (channel == 14)
+               tmp = rtl8225z2_tx_power_cck_ch14;
+       else
+               tmp = rtl8225z2_tx_power_cck;
+
+       for (i = 0; i < 8; i++)
+               rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++);
+
+       rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK,
+                        rtl8225z2_tx_gain_cck_ofdm[cck_power]);
+       msleep(1);
+
+       /* anaparam2 on */
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
+       reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
+       rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
+       rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON);
+       rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
+
+       rtl8225_write_phy_ofdm(dev, 2, 0x42);
+       rtl8225_write_phy_ofdm(dev, 5, 0x00);
+       rtl8225_write_phy_ofdm(dev, 6, 0x40);
+       rtl8225_write_phy_ofdm(dev, 7, 0x00);
+       rtl8225_write_phy_ofdm(dev, 8, 0x40);
+
+       rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM,
+                        rtl8225z2_tx_gain_cck_ofdm[ofdm_power]);
+       msleep(1);
+}
+
+static const u16 rtl8225z2_rxgain[] = {
+       0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
+       0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
+       0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
+       0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
+       0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
+       0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
+       0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
+       0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
+       0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
+       0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
+       0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
+       0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
+};
+
+static const u8 rtl8225z2_gain_bg[] = {
+       0x23, 0x15, 0xa5, /* -82-1dBm */
+       0x23, 0x15, 0xb5, /* -82-2dBm */
+       0x23, 0x15, 0xc5, /* -82-3dBm */
+       0x33, 0x15, 0xc5, /* -78dBm */
+       0x43, 0x15, 0xc5, /* -74dBm */
+       0x53, 0x15, 0xc5, /* -70dBm */
+       0x63, 0x15, 0xc5  /* -66dBm */
+};
+
+void rtl8225z2_rf_init(struct ieee80211_hw *dev)
+{
+       struct rtl8187_priv *priv = dev->priv;
+       int i;
+
+       rtl8225_write(dev, 0x0, 0x2BF); msleep(1);
+       rtl8225_write(dev, 0x1, 0xEE0); msleep(1);
+       rtl8225_write(dev, 0x2, 0x44D); msleep(1);
+       rtl8225_write(dev, 0x3, 0x441); msleep(1);
+       rtl8225_write(dev, 0x4, 0x8C3); msleep(1);
+       rtl8225_write(dev, 0x5, 0xC72); msleep(1);
+       rtl8225_write(dev, 0x6, 0x0E6); msleep(1);
+       rtl8225_write(dev, 0x7, 0x82A); msleep(1);
+       rtl8225_write(dev, 0x8, 0x03F); msleep(1);
+       rtl8225_write(dev, 0x9, 0x335); msleep(1);
+       rtl8225_write(dev, 0xa, 0x9D4); msleep(1);
+       rtl8225_write(dev, 0xb, 0x7BB); msleep(1);
+       rtl8225_write(dev, 0xc, 0x850); msleep(1);
+       rtl8225_write(dev, 0xd, 0xCDF); msleep(1);
+       rtl8225_write(dev, 0xe, 0x02B); msleep(1);
+       rtl8225_write(dev, 0xf, 0x114); msleep(100);
+
+       rtl8225_write(dev, 0x0, 0x1B7);
+
+       for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) {
+               rtl8225_write(dev, 0x1, i + 1);
+               rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]);
+       }
+
+       rtl8225_write(dev, 0x3, 0x080);
+       rtl8225_write(dev, 0x5, 0x004);
+       rtl8225_write(dev, 0x0, 0x0B7);
+       rtl8225_write(dev, 0x2, 0xc4D);
+
+       msleep(200);
+       rtl8225_write(dev, 0x2, 0x44D);
+       msleep(100);
+
+       if (!(rtl8225_read(dev, 6) & (1 << 7))) {
+               rtl8225_write(dev, 0x02, 0x0C4D);
+               msleep(200);
+               rtl8225_write(dev, 0x02, 0x044D);
+               msleep(100);
+               if (!(rtl8225_read(dev, 6) & (1 << 7)))
+                       printk(KERN_WARNING "%s: RF Calibration Failed! %x\n",
+                              wiphy_name(dev->wiphy), rtl8225_read(dev, 6));
+       }
+
+       msleep(200);
+
+       rtl8225_write(dev, 0x0, 0x2BF);
+
+       for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) {
+               rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]);
+               msleep(1);
+               rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i);
+               msleep(1);
+       }
+
+       msleep(1);
+
+       rtl8225_write_phy_ofdm(dev, 0x00, 0x01); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x01, 0x02); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x02, 0x42); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x03, 0x00); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x04, 0x00); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x05, 0x00); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x06, 0x40); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x07, 0x00); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x08, 0x40); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x0a, 0x08); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x0d, 0x43);
+       rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x10, 0x84); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x11, 0x07); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x12, 0x20); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x13, 0x20); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x14, 0x00); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x15, 0x40); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x16, 0x00); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x17, 0x40); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x19, 0x19); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x1b, 0x15); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x1d, 0xc5); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x1e, 0x95); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x21, 0x17); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x22, 0x16); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x23, 0x80); msleep(1); //FIXME: not needed?
+       rtl8225_write_phy_ofdm(dev, 0x24, 0x46); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x25, 0x00); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x27, 0x88); msleep(1);
+
+       rtl8225_write_phy_ofdm(dev, 0x0b, rtl8225z2_gain_bg[4 * 3]);
+       rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225z2_gain_bg[4 * 3 + 1]);
+       rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225z2_gain_bg[4 * 3 + 2]);
+       rtl8225_write_phy_ofdm(dev, 0x21, 0x37);
+
+       rtl8225_write_phy_cck(dev, 0x00, 0x98); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x03, 0x20); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x04, 0x7e); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x05, 0x12); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x06, 0xfc); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x07, 0x78); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x08, 0x2e); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x11, 0x88); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x12, 0x47); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x13, 0xd0);
+       rtl8225_write_phy_cck(dev, 0x19, 0x00);
+       rtl8225_write_phy_cck(dev, 0x1a, 0xa0);
+       rtl8225_write_phy_cck(dev, 0x1b, 0x08);
+       rtl8225_write_phy_cck(dev, 0x40, 0x86);
+       rtl8225_write_phy_cck(dev, 0x41, 0x8d); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x42, 0x15); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x43, 0x18); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x44, 0x36); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x45, 0x35); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x46, 0x2e); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x47, 0x25); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x48, 0x1c); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x49, 0x12); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x4a, 0x09); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x4b, 0x04); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x4c, 0x05); msleep(1);
+
+       rtl818x_iowrite8(priv, (u8 *)0xFF5B, 0x0D); msleep(1);
+
+       rtl8225z2_rf_set_tx_power(dev, 1);
+
+       /* RX antenna default to A */
+       rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1);      /* B: 0xDB */
+       rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1);     /* B: 0x10 */
+
+       rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03);   /* B: 0x00 */
+       msleep(1);
+       rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002);
+}
+
+void rtl8225_rf_stop(struct ieee80211_hw *dev)
+{
+       u8 reg;
+       struct rtl8187_priv *priv = dev->priv;
+
+       rtl8225_write(dev, 0x4, 0x1f); msleep(1);
+
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
+       reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
+       rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
+       rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_OFF);
+       rtl818x_iowrite32(priv, &priv->map->ANAPARAM, RTL8225_ANAPARAM_OFF);
+       rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
+}
+
+void rtl8225_rf_set_channel(struct ieee80211_hw *dev, int channel)
+{
+       struct rtl8187_priv *priv = dev->priv;
+
+       if (priv->rf_init == rtl8225_rf_init)
+               rtl8225_rf_set_tx_power(dev, channel);
+       else
+               rtl8225z2_rf_set_tx_power(dev, channel);
+
+       rtl8225_write(dev, 0x7, rtl8225_chan[channel - 1]);
+       msleep(10);
+}
diff --git a/drivers/net/wireless/rtl8187_rtl8225.h b/drivers/net/wireless/rtl8187_rtl8225.h
new file mode 100644 (file)
index 0000000..798ba4a
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Radio tuning definitions for RTL8225 on RTL8187
+ *
+ * Copyright 2007 Michael Wu <flamingice@sourmilk.net>
+ * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
+ *
+ * Based on the r8187 driver, which is:
+ * Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef RTL8187_RTL8225_H
+#define RTL8187_RTL8225_H
+
+#define RTL8225_ANAPARAM_ON    0xa0000a59
+#define RTL8225_ANAPARAM2_ON   0x860c7312
+#define RTL8225_ANAPARAM_OFF   0xa00beb59
+#define RTL8225_ANAPARAM2_OFF  0x840dec11
+
+void rtl8225_write(struct ieee80211_hw *, u8 addr, u16 data);
+u16  rtl8225_read(struct ieee80211_hw *, u8 addr);
+
+void rtl8225_rf_init(struct ieee80211_hw *);
+void rtl8225z2_rf_init(struct ieee80211_hw *);
+void rtl8225_rf_stop(struct ieee80211_hw *);
+void rtl8225_rf_set_channel(struct ieee80211_hw *, int);
+
+
+static inline void rtl8225_write_phy_ofdm(struct ieee80211_hw *dev,
+                                         u8 addr, u32 data)
+{
+       rtl8187_write_phy(dev, addr, data);
+}
+
+static inline void rtl8225_write_phy_cck(struct ieee80211_hw *dev,
+                                        u8 addr, u32 data)
+{
+       rtl8187_write_phy(dev, addr, data | 0x10000);
+}
+
+#endif /* RTL8187_RTL8225_H */
diff --git a/drivers/net/wireless/rtl818x.h b/drivers/net/wireless/rtl818x.h
new file mode 100644 (file)
index 0000000..283de30
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * Definitions for RTL818x hardware
+ *
+ * Copyright 2007 Michael Wu <flamingice@sourmilk.net>
+ * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
+ *
+ * Based on the r8187 driver, which is:
+ * Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef RTL818X_H
+#define RTL818X_H
+
+struct rtl818x_csr {
+       u8      MAC[6];
+       u8      reserved_0[2];
+       __le32  MAR[2];
+       u8      RX_FIFO_COUNT;
+       u8      reserved_1;
+       u8      TX_FIFO_COUNT;
+       u8      BQREQ;
+       u8      reserved_2[4];
+       __le32  TSFT[2];
+       __le32  TLPDA;
+       __le32  TNPDA;
+       __le32  THPDA;
+       __le16  BRSR;
+       u8      BSSID[6];
+       u8      RESP_RATE;
+       u8      EIFS;
+       u8      reserved_3[1];
+       u8      CMD;
+#define RTL818X_CMD_TX_ENABLE          (1 << 2)
+#define RTL818X_CMD_RX_ENABLE          (1 << 3)
+#define RTL818X_CMD_RESET              (1 << 4)
+       u8      reserved_4[4];
+       __le16  INT_MASK;
+       __le16  INT_STATUS;
+#define RTL818X_INT_RX_OK              (1 <<  0)
+#define RTL818X_INT_RX_ERR             (1 <<  1)
+#define RTL818X_INT_TXL_OK             (1 <<  2)
+#define RTL818X_INT_TXL_ERR            (1 <<  3)
+#define RTL818X_INT_RX_DU              (1 <<  4)
+#define RTL818X_INT_RX_FO              (1 <<  5)
+#define RTL818X_INT_TXN_OK             (1 <<  6)
+#define RTL818X_INT_TXN_ERR            (1 <<  7)
+#define RTL818X_INT_TXH_OK             (1 <<  8)
+#define RTL818X_INT_TXH_ERR            (1 <<  9)
+#define RTL818X_INT_TXB_OK             (1 << 10)
+#define RTL818X_INT_TXB_ERR            (1 << 11)
+#define RTL818X_INT_ATIM               (1 << 12)
+#define RTL818X_INT_BEACON             (1 << 13)
+#define RTL818X_INT_TIME_OUT           (1 << 14)
+#define RTL818X_INT_TX_FO              (1 << 15)
+       __le32  TX_CONF;
+#define RTL818X_TX_CONF_LOOPBACK_MAC   (1 << 17)
+#define RTL818X_TX_CONF_NO_ICV         (1 << 19)
+#define RTL818X_TX_CONF_DISCW          (1 << 20)
+#define RTL818X_TX_CONF_R8180_ABCD     (2 << 25)
+#define RTL818X_TX_CONF_R8180_F                (3 << 25)
+#define RTL818X_TX_CONF_R8185_ABC      (4 << 25)
+#define RTL818X_TX_CONF_R8185_D                (5 << 25)
+#define RTL818X_TX_CONF_HWVER_MASK     (7 << 25)
+#define RTL818X_TX_CONF_CW_MIN         (1 << 31)
+       __le32  RX_CONF;
+#define RTL818X_RX_CONF_MONITOR                (1 <<  0)
+#define RTL818X_RX_CONF_NICMAC         (1 <<  1)
+#define RTL818X_RX_CONF_MULTICAST      (1 <<  2)
+#define RTL818X_RX_CONF_BROADCAST      (1 <<  3)
+#define RTL818X_RX_CONF_DATA           (1 << 18)
+#define RTL818X_RX_CONF_CTRL           (1 << 19)
+#define RTL818X_RX_CONF_MGMT           (1 << 20)
+#define RTL818X_RX_CONF_BSSID          (1 << 23)
+#define RTL818X_RX_CONF_RX_AUTORESETPHY        (1 << 28)
+#define RTL818X_RX_CONF_ONLYERLPKT     (1 << 31)
+       __le32  INT_TIMEOUT;
+       __le32  TBDA;
+       u8      EEPROM_CMD;
+#define RTL818X_EEPROM_CMD_READ                (1 << 0)
+#define RTL818X_EEPROM_CMD_WRITE       (1 << 1)
+#define RTL818X_EEPROM_CMD_CK          (1 << 2)
+#define RTL818X_EEPROM_CMD_CS          (1 << 3)
+#define RTL818X_EEPROM_CMD_NORMAL      (0 << 6)
+#define RTL818X_EEPROM_CMD_LOAD                (1 << 6)
+#define RTL818X_EEPROM_CMD_PROGRAM     (2 << 6)
+#define RTL818X_EEPROM_CMD_CONFIG      (3 << 6)
+       u8      CONFIG0;
+       u8      CONFIG1;
+       u8      CONFIG2;
+       __le32  ANAPARAM;
+       u8      MSR;
+#define RTL818X_MSR_NO_LINK            (0 << 2)
+#define RTL818X_MSR_ADHOC              (1 << 2)
+#define RTL818X_MSR_INFRA              (2 << 2)
+       u8      CONFIG3;
+#define RTL818X_CONFIG3_ANAPARAM_WRITE (1 << 6)
+       u8      CONFIG4;
+#define RTL818X_CONFIG4_POWEROFF       (1 << 6)
+#define RTL818X_CONFIG4_VCOOFF         (1 << 7)
+       u8      TESTR;
+       u8      reserved_9[2];
+       __le16  PGSELECT;
+       __le32  ANAPARAM2;
+       u8      reserved_10[12];
+       __le16  BEACON_INTERVAL;
+       __le16  ATIM_WND;
+       __le16  BEACON_INTERVAL_TIME;
+       __le16  ATIMTR_INTERVAL;
+       u8      reserved_11[4];
+       u8      PHY[4];
+       __le16  RFPinsOutput;
+       __le16  RFPinsEnable;
+       __le16  RFPinsSelect;
+       __le16  RFPinsInput;
+       __le32  RF_PARA;
+       __le32  RF_TIMING;
+       u8      GP_ENABLE;
+       u8      GPIO;
+       u8      reserved_12[10];
+       u8      TX_AGC_CTL;
+#define RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT                (1 << 0)
+#define RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT      (1 << 1)
+#define RTL818X_TX_AGC_CTL_FEEDBACK_ANT                        (1 << 2)
+       u8      TX_GAIN_CCK;
+       u8      TX_GAIN_OFDM;
+       u8      TX_ANTENNA;
+       u8      reserved_13[16];
+       u8      WPA_CONF;
+       u8      reserved_14[3];
+       u8      SIFS;
+       u8      DIFS;
+       u8      SLOT;
+       u8      reserved_15[5];
+       u8      CW_CONF;
+#define RTL818X_CW_CONF_PERPACKET_CW_SHIFT     (1 << 0)
+#define RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT  (1 << 1)
+       u8      CW_VAL;
+       u8      RATE_FALLBACK;
+       u8      reserved_16[25];
+       u8      CONFIG5;
+       u8      TX_DMA_POLLING;
+       u8      reserved_17[2];
+       __le16  CWR;
+       u8      RETRY_CTR;
+       u8      reserved_18[5];
+       __le32  RDSAR;
+       u8      reserved_19[18];
+       u16     TALLY_CNT;
+       u8      TALLY_SEL;
+} __attribute__((packed));
+
+static const struct ieee80211_rate rtl818x_rates[] = {
+       { .rate = 10,
+         .val = 0,
+         .flags = IEEE80211_RATE_CCK },
+       { .rate = 20,
+         .val = 1,
+         .flags = IEEE80211_RATE_CCK },
+       { .rate = 55,
+         .val = 2,
+         .flags = IEEE80211_RATE_CCK },
+       { .rate = 110,
+         .val = 3,
+         .flags = IEEE80211_RATE_CCK },
+       { .rate = 60,
+         .val = 4,
+         .flags = IEEE80211_RATE_OFDM },
+       { .rate = 90,
+         .val = 5,
+         .flags = IEEE80211_RATE_OFDM },
+       { .rate = 120,
+         .val = 6,
+         .flags = IEEE80211_RATE_OFDM },
+       { .rate = 180,
+         .val = 7,
+         .flags = IEEE80211_RATE_OFDM },
+       { .rate = 240,
+         .val = 8,
+         .flags = IEEE80211_RATE_OFDM },
+       { .rate = 360,
+         .val = 9,
+         .flags = IEEE80211_RATE_OFDM },
+       { .rate = 480,
+         .val = 10,
+         .flags = IEEE80211_RATE_OFDM },
+       { .rate = 540,
+         .val = 11,
+         .flags = IEEE80211_RATE_OFDM },
+};
+
+static const struct ieee80211_channel rtl818x_channels[] = {
+       { .chan = 1,
+         .freq = 2412},
+       { .chan = 2,
+         .freq = 2417},
+       { .chan = 3,
+         .freq = 2422},
+       { .chan = 4,
+         .freq = 2427},
+       { .chan = 5,
+         .freq = 2432},
+       { .chan = 6,
+         .freq = 2437},
+       { .chan = 7,
+         .freq = 2442},
+       { .chan = 8,
+         .freq = 2447},
+       { .chan = 9,
+         .freq = 2452},
+       { .chan = 10,
+         .freq = 2457},
+       { .chan = 11,
+         .freq = 2462},
+       { .chan = 12,
+         .freq = 2467},
+       { .chan = 13,
+         .freq = 2472},
+       { .chan = 14,
+         .freq = 2484}
+};
+
+#endif /* RTL818X_H */
index ce9230b2f630e518870c4210a987ce61f4d2c03c..c8b5c2271938348cb0890419effcb3160cb32ff6 100644 (file)
@@ -1011,7 +1011,7 @@ static inline void wl3501_md_ind_interrupt(struct net_device *dev,
        } else {
                skb->dev = dev;
                skb_reserve(skb, 2); /* IP headers on 16 bytes boundaries */
-               eth_copy_and_sum(skb, (unsigned char *)&sig.daddr, 12, 0);
+               skb_copy_to_linear_data(skb, (unsigned char *)&sig.daddr, 12);
                wl3501_receive(this, skb->data, pkt_len);
                skb_put(skb, pkt_len);
                skb->protocol   = eth_type_trans(skb, dev);
index 6603ad5be63d09a3752913775034ce570c141797..4d505903352c3f7235f494dd01196ce2bf200221 100644 (file)
@@ -3,7 +3,7 @@ obj-$(CONFIG_ZD1211RW) += zd1211rw.o
 zd1211rw-objs := zd_chip.o zd_ieee80211.o \
                zd_mac.o zd_netdev.o \
                zd_rf_al2230.o zd_rf_rf2959.o \
-               zd_rf_al7230b.o \
+               zd_rf_al7230b.o zd_rf_uw2453.o \
                zd_rf.o zd_usb.o zd_util.o
 
 ifeq ($(CONFIG_ZD1211RW_DEBUG),y)
index 95b4a2a26707b2f85cf6755d07092975450aa2a8..5b624bfc01a6037b7f76c04eba638b666038987f 100644 (file)
@@ -1253,6 +1253,9 @@ static int update_channel_integration_and_calibration(struct zd_chip *chip,
 {
        int r;
 
+       if (!zd_rf_should_update_pwr_int(&chip->rf))
+               return 0;
+
        r = update_pwr_int(chip, channel);
        if (r)
                return r;
@@ -1283,7 +1286,7 @@ static int patch_cck_gain(struct zd_chip *chip)
        int r;
        u32 value;
 
-       if (!chip->patch_cck_gain)
+       if (!chip->patch_cck_gain || !zd_rf_should_patch_cck_gain(&chip->rf))
                return 0;
 
        ZD_ASSERT(mutex_is_locked(&chip->mutex));
index ce0a5f6da0d2e3326442e1d6c913ecb681795130..79d0288c193a41f3aa31fb097f4bc3b9d8e43623 100644 (file)
@@ -608,6 +608,9 @@ enum {
 #define CR_ZD1211B_TXOP                        CTL_REG(0x0b20)
 #define CR_ZD1211B_RETRY_MAX           CTL_REG(0x0b28)
 
+/* Used to detect PLL lock */
+#define UW2453_INTR_REG                        ((zd_addr_t)0x85c1)
+
 #define CWIN_SIZE                      0x007f043f
 
 
index 549c23bcd6ccce78b752060892f0326d6b54b57d..7407409b60b19b0ee22bf3a1d6921723a31a39c4 100644 (file)
@@ -52,34 +52,38 @@ const char *zd_rf_name(u8 type)
 void zd_rf_init(struct zd_rf *rf)
 {
        memset(rf, 0, sizeof(*rf));
+
+       /* default to update channel integration, as almost all RF's do want
+        * this */
+       rf->update_channel_int = 1;
 }
 
 void zd_rf_clear(struct zd_rf *rf)
 {
+       if (rf->clear)
+               rf->clear(rf);
        ZD_MEMCLEAR(rf, sizeof(*rf));
 }
 
 int zd_rf_init_hw(struct zd_rf *rf, u8 type)
 {
-       int r, t;
+       int r = 0;
+       int t;
        struct zd_chip *chip = zd_rf_to_chip(rf);
 
        ZD_ASSERT(mutex_is_locked(&chip->mutex));
        switch (type) {
        case RF2959_RF:
                r = zd_rf_init_rf2959(rf);
-               if (r)
-                       return r;
                break;
        case AL2230_RF:
                r = zd_rf_init_al2230(rf);
-               if (r)
-                       return r;
                break;
        case AL7230B_RF:
                r = zd_rf_init_al7230b(rf);
-               if (r)
-                       return r;
+               break;
+       case UW2453_RF:
+               r = zd_rf_init_uw2453(rf);
                break;
        default:
                dev_err(zd_chip_dev(chip),
@@ -88,6 +92,9 @@ int zd_rf_init_hw(struct zd_rf *rf, u8 type)
                return -ENODEV;
        }
 
+       if (r)
+               return r;
+
        rf->type = type;
 
        r = zd_chip_lock_phy_regs(chip);
index aa9cc105ce60daf199c062952cddbfb83eeb6f48..c6dfd8227f6e78b5bc76e118668a2adefd389050 100644 (file)
@@ -48,12 +48,26 @@ struct zd_rf {
 
        u8 channel;
 
+       /* whether channel integration and calibration should be updated
+        * defaults to 1 (yes) */
+       u8 update_channel_int:1;
+
+       /* whether CR47 should be patched from the EEPROM, if the appropriate
+        * flag is set in the POD. The vendor driver suggests that this should
+        * be done for all RF's, but a bug in their code prevents but their
+        * HW_OverWritePhyRegFromE2P() routine from ever taking effect. */
+       u8 patch_cck_gain:1;
+
+       /* private RF driver data */
+       void *priv;
+
        /* RF-specific functions */
        int (*init_hw)(struct zd_rf *rf);
        int (*set_channel)(struct zd_rf *rf, u8 channel);
        int (*switch_radio_on)(struct zd_rf *rf);
        int (*switch_radio_off)(struct zd_rf *rf);
        int (*patch_6m_band_edge)(struct zd_rf *rf, u8 channel);
+       void (*clear)(struct zd_rf *rf);
 };
 
 const char *zd_rf_name(u8 type);
@@ -71,10 +85,24 @@ int zd_switch_radio_off(struct zd_rf *rf);
 int zd_rf_patch_6m_band_edge(struct zd_rf *rf, u8 channel);
 int zd_rf_generic_patch_6m(struct zd_rf *rf, u8 channel);
 
+static inline int zd_rf_should_update_pwr_int(struct zd_rf *rf)
+{
+       return rf->update_channel_int;
+}
+
+static inline int zd_rf_should_patch_cck_gain(struct zd_rf *rf)
+{
+       return rf->patch_cck_gain;
+}
+
+int zd_rf_patch_6m_band_edge(struct zd_rf *rf, u8 channel);
+int zd_rf_generic_patch_6m(struct zd_rf *rf, u8 channel);
+
 /* Functions for individual RF chips */
 
 int zd_rf_init_rf2959(struct zd_rf *rf);
 int zd_rf_init_al2230(struct zd_rf *rf);
 int zd_rf_init_al7230b(struct zd_rf *rf);
+int zd_rf_init_uw2453(struct zd_rf *rf);
 
 #endif /* _ZD_RF_H */
index 511392acfedf3f179359c840fb01b87e114f3124..e7a4ecf7b6e21483d7b4916f6c7f1c3983cd75a5 100644 (file)
@@ -432,5 +432,6 @@ int zd_rf_init_al2230(struct zd_rf *rf)
                rf->switch_radio_on = zd1211_al2230_switch_radio_on;
        }
        rf->patch_6m_band_edge = zd_rf_generic_patch_6m;
+       rf->patch_cck_gain = 1;
        return 0;
 }
index 5e5e9ddc6a7467501fe6bc891df6b3980dbb2a8b..f4e8b6ada854c54644b4ccfea7061a6ab1162c26 100644 (file)
@@ -483,6 +483,7 @@ int zd_rf_init_al7230b(struct zd_rf *rf)
                rf->switch_radio_on = zd1211_al7230b_switch_radio_on;
                rf->set_channel = zd1211_al7230b_set_channel;
                rf->patch_6m_band_edge = zd_rf_generic_patch_6m;
+               rf->patch_cck_gain = 1;
        }
 
        rf->switch_radio_off = al7230b_switch_radio_off;
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c b/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c
new file mode 100644 (file)
index 0000000..414e40d
--- /dev/null
@@ -0,0 +1,534 @@
+/* zd_rf_uw2453.c: Functions for the UW2453 RF controller
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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 "zd_rf.h"
+#include "zd_usb.h"
+#include "zd_chip.h"
+
+/* This RF programming code is based upon the code found in v2.16.0.0 of the
+ * ZyDAS vendor driver. Unlike other RF's, Ubec publish full technical specs
+ * for this RF on their website, so we're able to understand more than
+ * usual as to what is going on. Thumbs up for Ubec for doing that. */
+
+/* The 3-wire serial interface provides access to 8 write-only registers.
+ * The data format is a 4 bit register address followed by a 20 bit value. */
+#define UW2453_REGWRITE(reg, val) ((((reg) & 0xf) << 20) | ((val) & 0xfffff))
+
+/* For channel tuning, we have to configure registers 1 (synthesizer), 2 (synth
+ * fractional divide ratio) and 3 (VCO config).
+ *
+ * We configure the RF to produce an interrupt when the PLL is locked onto
+ * the configured frequency. During initialization, we run through a variety
+ * of different VCO configurations on channel 1 until we detect a PLL lock.
+ * When this happens, we remember which VCO configuration produced the lock
+ * and use it later. Actually, we use the configuration *after* the one that
+ * produced the lock, which seems odd, but it works.
+ *
+ * If we do not see a PLL lock on any standard VCO config, we fall back on an
+ * autocal configuration, which has a fixed (as opposed to per-channel) VCO
+ * config and different synth values from the standard set (divide ratio
+ * is still shared with the standard set). */
+
+/* The per-channel synth values for all standard VCO configurations. These get
+ * written to register 1. */
+static const u8 uw2453_std_synth[] = {
+       RF_CHANNEL( 1) = 0x47,
+       RF_CHANNEL( 2) = 0x47,
+       RF_CHANNEL( 3) = 0x67,
+       RF_CHANNEL( 4) = 0x67,
+       RF_CHANNEL( 5) = 0x67,
+       RF_CHANNEL( 6) = 0x67,
+       RF_CHANNEL( 7) = 0x57,
+       RF_CHANNEL( 8) = 0x57,
+       RF_CHANNEL( 9) = 0x57,
+       RF_CHANNEL(10) = 0x57,
+       RF_CHANNEL(11) = 0x77,
+       RF_CHANNEL(12) = 0x77,
+       RF_CHANNEL(13) = 0x77,
+       RF_CHANNEL(14) = 0x4f,
+};
+
+/* This table stores the synthesizer fractional divide ratio for *all* VCO
+ * configurations (both standard and autocal). These get written to register 2.
+ */
+static const u16 uw2453_synth_divide[] = {
+       RF_CHANNEL( 1) = 0x999,
+       RF_CHANNEL( 2) = 0x99b,
+       RF_CHANNEL( 3) = 0x998,
+       RF_CHANNEL( 4) = 0x99a,
+       RF_CHANNEL( 5) = 0x999,
+       RF_CHANNEL( 6) = 0x99b,
+       RF_CHANNEL( 7) = 0x998,
+       RF_CHANNEL( 8) = 0x99a,
+       RF_CHANNEL( 9) = 0x999,
+       RF_CHANNEL(10) = 0x99b,
+       RF_CHANNEL(11) = 0x998,
+       RF_CHANNEL(12) = 0x99a,
+       RF_CHANNEL(13) = 0x999,
+       RF_CHANNEL(14) = 0xccc,
+};
+
+/* Here is the data for all the standard VCO configurations. We shrink our
+ * table a little by observing that both channels in a consecutive pair share
+ * the same value. We also observe that the high 4 bits ([0:3] in the specs)
+ * are all 'Reserved' and are always set to 0x4 - we chop them off in the data
+ * below. */
+#define CHAN_TO_PAIRIDX(a) ((a - 1) / 2)
+#define RF_CHANPAIR(a,b) [CHAN_TO_PAIRIDX(a)]
+static const u16 uw2453_std_vco_cfg[][7] = {
+       { /* table 1 */
+               RF_CHANPAIR( 1,  2) = 0x664d,
+               RF_CHANPAIR( 3,  4) = 0x604d,
+               RF_CHANPAIR( 5,  6) = 0x6675,
+               RF_CHANPAIR( 7,  8) = 0x6475,
+               RF_CHANPAIR( 9, 10) = 0x6655,
+               RF_CHANPAIR(11, 12) = 0x6455,
+               RF_CHANPAIR(13, 14) = 0x6665,
+       },
+       { /* table 2 */
+               RF_CHANPAIR( 1,  2) = 0x666d,
+               RF_CHANPAIR( 3,  4) = 0x606d,
+               RF_CHANPAIR( 5,  6) = 0x664d,
+               RF_CHANPAIR( 7,  8) = 0x644d,
+               RF_CHANPAIR( 9, 10) = 0x6675,
+               RF_CHANPAIR(11, 12) = 0x6475,
+               RF_CHANPAIR(13, 14) = 0x6655,
+       },
+       { /* table 3 */
+               RF_CHANPAIR( 1,  2) = 0x665d,
+               RF_CHANPAIR( 3,  4) = 0x605d,
+               RF_CHANPAIR( 5,  6) = 0x666d,
+               RF_CHANPAIR( 7,  8) = 0x646d,
+               RF_CHANPAIR( 9, 10) = 0x664d,
+               RF_CHANPAIR(11, 12) = 0x644d,
+               RF_CHANPAIR(13, 14) = 0x6675,
+       },
+       { /* table 4 */
+               RF_CHANPAIR( 1,  2) = 0x667d,
+               RF_CHANPAIR( 3,  4) = 0x607d,
+               RF_CHANPAIR( 5,  6) = 0x665d,
+               RF_CHANPAIR( 7,  8) = 0x645d,
+               RF_CHANPAIR( 9, 10) = 0x666d,
+               RF_CHANPAIR(11, 12) = 0x646d,
+               RF_CHANPAIR(13, 14) = 0x664d,
+       },
+       { /* table 5 */
+               RF_CHANPAIR( 1,  2) = 0x6643,
+               RF_CHANPAIR( 3,  4) = 0x6043,
+               RF_CHANPAIR( 5,  6) = 0x667d,
+               RF_CHANPAIR( 7,  8) = 0x647d,
+               RF_CHANPAIR( 9, 10) = 0x665d,
+               RF_CHANPAIR(11, 12) = 0x645d,
+               RF_CHANPAIR(13, 14) = 0x666d,
+       },
+       { /* table 6 */
+               RF_CHANPAIR( 1,  2) = 0x6663,
+               RF_CHANPAIR( 3,  4) = 0x6063,
+               RF_CHANPAIR( 5,  6) = 0x6643,
+               RF_CHANPAIR( 7,  8) = 0x6443,
+               RF_CHANPAIR( 9, 10) = 0x667d,
+               RF_CHANPAIR(11, 12) = 0x647d,
+               RF_CHANPAIR(13, 14) = 0x665d,
+       },
+       { /* table 7 */
+               RF_CHANPAIR( 1,  2) = 0x6653,
+               RF_CHANPAIR( 3,  4) = 0x6053,
+               RF_CHANPAIR( 5,  6) = 0x6663,
+               RF_CHANPAIR( 7,  8) = 0x6463,
+               RF_CHANPAIR( 9, 10) = 0x6643,
+               RF_CHANPAIR(11, 12) = 0x6443,
+               RF_CHANPAIR(13, 14) = 0x667d,
+       },
+       { /* table 8 */
+               RF_CHANPAIR( 1,  2) = 0x6673,
+               RF_CHANPAIR( 3,  4) = 0x6073,
+               RF_CHANPAIR( 5,  6) = 0x6653,
+               RF_CHANPAIR( 7,  8) = 0x6453,
+               RF_CHANPAIR( 9, 10) = 0x6663,
+               RF_CHANPAIR(11, 12) = 0x6463,
+               RF_CHANPAIR(13, 14) = 0x6643,
+       },
+       { /* table 9 */
+               RF_CHANPAIR( 1,  2) = 0x664b,
+               RF_CHANPAIR( 3,  4) = 0x604b,
+               RF_CHANPAIR( 5,  6) = 0x6673,
+               RF_CHANPAIR( 7,  8) = 0x6473,
+               RF_CHANPAIR( 9, 10) = 0x6653,
+               RF_CHANPAIR(11, 12) = 0x6453,
+               RF_CHANPAIR(13, 14) = 0x6663,
+       },
+       { /* table 10 */
+               RF_CHANPAIR( 1,  2) = 0x666b,
+               RF_CHANPAIR( 3,  4) = 0x606b,
+               RF_CHANPAIR( 5,  6) = 0x664b,
+               RF_CHANPAIR( 7,  8) = 0x644b,
+               RF_CHANPAIR( 9, 10) = 0x6673,
+               RF_CHANPAIR(11, 12) = 0x6473,
+               RF_CHANPAIR(13, 14) = 0x6653,
+       },
+       { /* table 11 */
+               RF_CHANPAIR( 1,  2) = 0x665b,
+               RF_CHANPAIR( 3,  4) = 0x605b,
+               RF_CHANPAIR( 5,  6) = 0x666b,
+               RF_CHANPAIR( 7,  8) = 0x646b,
+               RF_CHANPAIR( 9, 10) = 0x664b,
+               RF_CHANPAIR(11, 12) = 0x644b,
+               RF_CHANPAIR(13, 14) = 0x6673,
+       },
+
+};
+
+/* The per-channel synth values for autocal. These get written to register 1. */
+static const u16 uw2453_autocal_synth[] = {
+       RF_CHANNEL( 1) = 0x6847,
+       RF_CHANNEL( 2) = 0x6847,
+       RF_CHANNEL( 3) = 0x6867,
+       RF_CHANNEL( 4) = 0x6867,
+       RF_CHANNEL( 5) = 0x6867,
+       RF_CHANNEL( 6) = 0x6867,
+       RF_CHANNEL( 7) = 0x6857,
+       RF_CHANNEL( 8) = 0x6857,
+       RF_CHANNEL( 9) = 0x6857,
+       RF_CHANNEL(10) = 0x6857,
+       RF_CHANNEL(11) = 0x6877,
+       RF_CHANNEL(12) = 0x6877,
+       RF_CHANNEL(13) = 0x6877,
+       RF_CHANNEL(14) = 0x684f,
+};
+
+/* The VCO configuration for autocal (all channels) */
+static const u16 UW2453_AUTOCAL_VCO_CFG = 0x6662;
+
+/* TX gain settings. The array index corresponds to the TX power integration
+ * values found in the EEPROM. The values get written to register 7. */
+static u32 uw2453_txgain[] = {
+       [0x00] = 0x0e313,
+       [0x01] = 0x0fb13,
+       [0x02] = 0x0e093,
+       [0x03] = 0x0f893,
+       [0x04] = 0x0ea93,
+       [0x05] = 0x1f093,
+       [0x06] = 0x1f493,
+       [0x07] = 0x1f693,
+       [0x08] = 0x1f393,
+       [0x09] = 0x1f35b,
+       [0x0a] = 0x1e6db,
+       [0x0b] = 0x1ff3f,
+       [0x0c] = 0x1ffff,
+       [0x0d] = 0x361d7,
+       [0x0e] = 0x37fbf,
+       [0x0f] = 0x3ff8b,
+       [0x10] = 0x3ff33,
+       [0x11] = 0x3fb3f,
+       [0x12] = 0x3ffff,
+};
+
+/* RF-specific structure */
+struct uw2453_priv {
+       /* index into synth/VCO config tables where PLL lock was found
+        * -1 means autocal */
+       int config;
+};
+
+#define UW2453_PRIV(rf) ((struct uw2453_priv *) (rf)->priv)
+
+static int uw2453_synth_set_channel(struct zd_chip *chip, int channel,
+       bool autocal)
+{
+       int r;
+       int idx = channel - 1;
+       u32 val;
+
+       if (autocal)
+               val = UW2453_REGWRITE(1, uw2453_autocal_synth[idx]);
+       else
+               val = UW2453_REGWRITE(1, uw2453_std_synth[idx]);
+
+       r = zd_rfwrite_locked(chip, val, RF_RV_BITS);
+       if (r)
+               return r;
+
+       return zd_rfwrite_locked(chip,
+               UW2453_REGWRITE(2, uw2453_synth_divide[idx]), RF_RV_BITS);
+}
+
+static int uw2453_write_vco_cfg(struct zd_chip *chip, u16 value)
+{
+       /* vendor driver always sets these upper bits even though the specs say
+        * they are reserved */
+       u32 val = 0x40000 | value;
+       return zd_rfwrite_locked(chip, UW2453_REGWRITE(3, val), RF_RV_BITS);
+}
+
+static int uw2453_init_mode(struct zd_chip *chip)
+{
+       static const u32 rv[] = {
+               UW2453_REGWRITE(0, 0x25f98), /* enter IDLE mode */
+               UW2453_REGWRITE(0, 0x25f9a), /* enter CAL_VCO mode */
+               UW2453_REGWRITE(0, 0x25f94), /* enter RX/TX mode */
+               UW2453_REGWRITE(0, 0x27fd4), /* power down RSSI circuit */
+       };
+
+       return zd_rfwritev_locked(chip, rv, ARRAY_SIZE(rv), RF_RV_BITS);
+}
+
+static int uw2453_set_tx_gain_level(struct zd_chip *chip, int channel)
+{
+       u8 int_value = chip->pwr_int_values[channel - 1];
+
+       if (int_value >= ARRAY_SIZE(uw2453_txgain)) {
+               dev_dbg_f(zd_chip_dev(chip), "can't configure TX gain for "
+                         "int value %x on channel %d\n", int_value, channel);
+               return 0;
+       }
+
+       return zd_rfwrite_locked(chip,
+               UW2453_REGWRITE(7, uw2453_txgain[int_value]), RF_RV_BITS);
+}
+
+static int uw2453_init_hw(struct zd_rf *rf)
+{
+       int i, r;
+       int found_config = -1;
+       u16 intr_status;
+       struct zd_chip *chip = zd_rf_to_chip(rf);
+
+       static const struct zd_ioreq16 ioreqs[] = {
+               { CR10,  0x89 }, { CR15,  0x20 },
+               { CR17,  0x28 }, /* 6112 no change */
+               { CR23,  0x38 }, { CR24,  0x20 }, { CR26,  0x93 },
+               { CR27,  0x15 }, { CR28,  0x3e }, { CR29,  0x00 },
+               { CR33,  0x28 }, { CR34,  0x30 },
+               { CR35,  0x43 }, /* 6112 3e->43 */
+               { CR41,  0x24 }, { CR44,  0x32 },
+               { CR46,  0x92 }, /* 6112 96->92 */
+               { CR47,  0x1e },
+               { CR48,  0x04 }, /* 5602 Roger */
+               { CR49,  0xfa }, { CR79,  0x58 }, { CR80,  0x30 },
+               { CR81,  0x30 }, { CR87,  0x0a }, { CR89,  0x04 },
+               { CR91,  0x00 }, { CR92,  0x0a }, { CR98,  0x8d },
+               { CR99,  0x28 }, { CR100, 0x02 },
+               { CR101, 0x09 }, /* 6112 13->1f 6220 1f->13 6407 13->9 */
+               { CR102, 0x27 },
+               { CR106, 0x1c }, /* 5d07 5112 1f->1c 6220 1c->1f 6221 1f->1c */
+               { CR107, 0x1c }, /* 6220 1c->1a 5221 1a->1c */
+               { CR109, 0x13 },
+               { CR110, 0x1f }, /* 6112 13->1f 6221 1f->13 6407 13->0x09 */
+               { CR111, 0x13 }, { CR112, 0x1f }, { CR113, 0x27 },
+               { CR114, 0x23 }, /* 6221 27->23 */
+               { CR115, 0x24 }, /* 6112 24->1c 6220 1c->24 */
+               { CR116, 0x24 }, /* 6220 1c->24 */
+               { CR117, 0xfa }, /* 6112 fa->f8 6220 f8->f4 6220 f4->fa */
+               { CR118, 0xf0 }, /* 5d07 6112 f0->f2 6220 f2->f0 */
+               { CR119, 0x1a }, /* 6112 1a->10 6220 10->14 6220 14->1a */
+               { CR120, 0x4f },
+               { CR121, 0x1f }, /* 6220 4f->1f */
+               { CR122, 0xf0 }, { CR123, 0x57 }, { CR125, 0xad },
+               { CR126, 0x6c }, { CR127, 0x03 },
+               { CR128, 0x14 }, /* 6302 12->11 */
+               { CR129, 0x12 }, /* 6301 10->0f */
+               { CR130, 0x10 }, { CR137, 0x50 }, { CR138, 0xa8 },
+               { CR144, 0xac }, { CR146, 0x20 }, { CR252, 0xff },
+               { CR253, 0xff },
+       };
+
+       static const u32 rv[] = {
+               UW2453_REGWRITE(4, 0x2b),    /* configure reciever gain */
+               UW2453_REGWRITE(5, 0x19e4f), /* configure transmitter gain */
+               UW2453_REGWRITE(6, 0xf81ad), /* enable RX/TX filter tuning */
+               UW2453_REGWRITE(7, 0x3fffe), /* disable TX gain in test mode */
+
+               /* enter CAL_FIL mode, TX gain set by registers, RX gain set by pins,
+                * RSSI circuit powered down, reduced RSSI range */
+               UW2453_REGWRITE(0, 0x25f9c), /* 5d01 cal_fil */
+
+               /* synthesizer configuration for channel 1 */
+               UW2453_REGWRITE(1, 0x47),
+               UW2453_REGWRITE(2, 0x999),
+
+               /* disable manual VCO band selection */
+               UW2453_REGWRITE(3, 0x7602),
+
+               /* enable manual VCO band selection, configure current level */
+               UW2453_REGWRITE(3, 0x46063),
+       };
+
+       r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
+       if (r)
+               return r;
+
+       r = zd_rfwritev_locked(chip, rv, ARRAY_SIZE(rv), RF_RV_BITS);
+       if (r)
+               return r;
+
+       r = uw2453_init_mode(chip);
+       if (r)
+               return r;
+
+       /* Try all standard VCO configuration settings on channel 1 */
+       for (i = 0; i < ARRAY_SIZE(uw2453_std_vco_cfg) - 1; i++) {
+               /* Configure synthesizer for channel 1 */
+               r = uw2453_synth_set_channel(chip, 1, false);
+               if (r)
+                       return r;
+
+               /* Write VCO config */
+               r = uw2453_write_vco_cfg(chip, uw2453_std_vco_cfg[i][0]);
+               if (r)
+                       return r;
+
+               /* ack interrupt event */
+               r = zd_iowrite16_locked(chip, 0x0f, UW2453_INTR_REG);
+               if (r)
+                       return r;
+
+               /* check interrupt status */
+               r = zd_ioread16_locked(chip, &intr_status, UW2453_INTR_REG);
+               if (r)
+                       return r;
+
+               if (!intr_status & 0xf) {
+                       dev_dbg_f(zd_chip_dev(chip),
+                               "PLL locked on configuration %d\n", i);
+                       found_config = i;
+                       break;
+               }
+       }
+
+       if (found_config == -1) {
+               /* autocal */
+               dev_dbg_f(zd_chip_dev(chip),
+                       "PLL did not lock, using autocal\n");
+
+               r = uw2453_synth_set_channel(chip, 1, true);
+               if (r)
+                       return r;
+
+               r = uw2453_write_vco_cfg(chip, UW2453_AUTOCAL_VCO_CFG);
+               if (r)
+                       return r;
+       }
+
+       /* To match the vendor driver behaviour, we use the configuration after
+        * the one that produced a lock. */
+       UW2453_PRIV(rf)->config = found_config + 1;
+
+       return zd_iowrite16_locked(chip, 0x06, CR203);
+}
+
+static int uw2453_set_channel(struct zd_rf *rf, u8 channel)
+{
+       int r;
+       u16 vco_cfg;
+       int config = UW2453_PRIV(rf)->config;
+       bool autocal = (config == -1);
+       struct zd_chip *chip = zd_rf_to_chip(rf);
+
+       static const struct zd_ioreq16 ioreqs[] = {
+               { CR80,  0x30 }, { CR81,  0x30 }, { CR79,  0x58 },
+               { CR12,  0xf0 }, { CR77,  0x1b }, { CR78,  0x58 },
+       };
+
+       r = uw2453_synth_set_channel(chip, channel, autocal);
+       if (r)
+               return r;
+
+       if (autocal)
+               vco_cfg = UW2453_AUTOCAL_VCO_CFG;
+       else
+               vco_cfg = uw2453_std_vco_cfg[config][CHAN_TO_PAIRIDX(channel)];
+
+       r = uw2453_write_vco_cfg(chip, vco_cfg);
+       if (r)
+               return r;
+
+       r = uw2453_init_mode(chip);
+       if (r)
+               return r;
+
+       r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
+       if (r)
+               return r;
+
+       r = uw2453_set_tx_gain_level(chip, channel);
+       if (r)
+               return r;
+
+       return zd_iowrite16_locked(chip, 0x06, CR203);
+}
+
+static int uw2453_switch_radio_on(struct zd_rf *rf)
+{
+       int r;
+       struct zd_chip *chip = zd_rf_to_chip(rf);
+       struct zd_ioreq16 ioreqs[] = {
+               { CR11,  0x00 }, { CR251, 0x3f },
+       };
+
+       /* enter RXTX mode */
+       r = zd_rfwrite_locked(chip, UW2453_REGWRITE(0, 0x25f94), RF_RV_BITS);
+       if (r)
+               return r;
+
+       if (chip->is_zd1211b)
+               ioreqs[1].value = 0x7f;
+
+       return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
+}
+
+static int uw2453_switch_radio_off(struct zd_rf *rf)
+{
+       int r;
+       struct zd_chip *chip = zd_rf_to_chip(rf);
+       static const struct zd_ioreq16 ioreqs[] = {
+               { CR11,  0x04 }, { CR251, 0x2f },
+       };
+
+       /* enter IDLE mode */
+       /* FIXME: shouldn't we go to SLEEP? sent email to zydas */
+       r = zd_rfwrite_locked(chip, UW2453_REGWRITE(0, 0x25f90), RF_RV_BITS);
+       if (r)
+               return r;
+
+       return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
+}
+
+static void uw2453_clear(struct zd_rf *rf)
+{
+       kfree(rf->priv);
+}
+
+int zd_rf_init_uw2453(struct zd_rf *rf)
+{
+       rf->init_hw = uw2453_init_hw;
+       rf->set_channel = uw2453_set_channel;
+       rf->switch_radio_on = uw2453_switch_radio_on;
+       rf->switch_radio_off = uw2453_switch_radio_off;
+       rf->patch_6m_band_edge = zd_rf_generic_patch_6m;
+       rf->clear = uw2453_clear;
+       /* we have our own TX integration code */
+       rf->update_channel_int = 0;
+
+       rf->priv = kmalloc(sizeof(struct uw2453_priv), GFP_KERNEL);
+       if (rf->priv == NULL)
+               return -ENOMEM;
+
+       return 0;
+}
+
index 8459549d0cee6e8c3e1375b7e3deedd9371430e4..740a2194fdde516a3196adc0e67ac3f1b627da1f 100644 (file)
@@ -54,6 +54,7 @@ static struct usb_device_id usb_ids[] = {
        { USB_DEVICE(0x0586, 0x3401), .driver_info = DEVICE_ZD1211 },
        { USB_DEVICE(0x14ea, 0xab13), .driver_info = DEVICE_ZD1211 },
        { USB_DEVICE(0x13b1, 0x001e), .driver_info = DEVICE_ZD1211 },
+       { USB_DEVICE(0x0586, 0x3407), .driver_info = DEVICE_ZD1211 },
        /* ZD1211B */
        { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B },
        { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B },
index f2a90a7fa2d6ff9fb826224342ecec58ad3b6ced..870c5393c21a0c4ecf7d926355705350d889fda4 100644 (file)
@@ -1137,7 +1137,7 @@ static int yellowfin_rx(struct net_device *dev)
                                if (skb == NULL)
                                        break;
                                skb_reserve(skb, 2);    /* 16 byte align the IP header */
-                               eth_copy_and_sum(skb, rx_skb->data, pkt_len, 0);
+                               skb_copy_to_linear_data(skb, rx_skb->data, pkt_len);
                                skb_put(skb, pkt_len);
                                pci_dma_sync_single_for_device(yp->pci_dev, desc->addr,
                                                                                           yp->rx_buf_sz,
index 924ef0609460f4a338e0423101741ab92f96c8e1..fc4bde259dc7a68da93c89640aa36db34f5744e5 100644 (file)
@@ -121,14 +121,14 @@ struct pdcspath_entry pdcspath_entry_##_name = { \
 
 #define PDCS_ATTR(_name, _mode, _show, _store) \
 struct subsys_attribute pdcs_attr_##_name = { \
-       .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE}, \
+       .attr = {.name = __stringify(_name), .mode = _mode}, \
        .show = _show, \
        .store = _store, \
 };
 
 #define PATHS_ATTR(_name, _mode, _show, _store) \
 struct pdcspath_attribute paths_attr_##_name = { \
-       .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE}, \
+       .attr = {.name = __stringify(_name), .mode = _mode}, \
        .show = _show, \
        .store = _store, \
 };
index e3beb784406f69019511cebf7d8cd33542ccb99c..006054a409958a5f7617f9b1713a0eced9381d68 100644 (file)
@@ -41,9 +41,7 @@ obj-$(CONFIG_ACPI)    += pci-acpi.o
 # Cardbus & CompactPCI use setup-bus
 obj-$(CONFIG_HOTPLUG) += setup-bus.o
 
-ifndef CONFIG_X86
-obj-y += syscall.o
-endif
+obj-$(CONFIG_PCI_SYSCALL) += syscall.o
 
 ifeq ($(CONFIG_PCI_DEBUG),y)
 EXTRA_CFLAGS += -DDEBUG
index ddbadd95387ece7340617aae7ffcfbfb9843cca1..f6cc0c5b56572715425a7a535f2c2444c25a0ca6 100644 (file)
@@ -211,6 +211,7 @@ typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data);
 
 extern int acpiphp_enable_slot (struct acpiphp_slot *slot);
 extern int acpiphp_disable_slot (struct acpiphp_slot *slot);
+extern int acpiphp_eject_slot (struct acpiphp_slot *slot);
 extern u8 acpiphp_get_power_status (struct acpiphp_slot *slot);
 extern u8 acpiphp_get_attention_status (struct acpiphp_slot *slot);
 extern u8 acpiphp_get_latch_status (struct acpiphp_slot *slot);
index fa5c0197d571c81325ace3d08d2e6c7246fa74a9..a0ca63adad5ac41c3df29fc7171b814d5db4709a 100644 (file)
@@ -156,11 +156,15 @@ static int enable_slot(struct hotplug_slot *hotplug_slot)
 static int disable_slot(struct hotplug_slot *hotplug_slot)
 {
        struct slot *slot = hotplug_slot->private;
+       int retval;
 
        dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
 
        /* disable the specified slot */
-       return acpiphp_disable_slot(slot->acpi_slot);
+       retval = acpiphp_disable_slot(slot->acpi_slot);
+       if (!retval)
+               retval = acpiphp_eject_slot(slot->acpi_slot);
+       return retval;
 }
 
 
index 9ef4e989afc43b0fc70153258ebb91821aaff82a..1e125b56c9a97ccba476eed8566b04fedaf3cd01 100644 (file)
@@ -1282,7 +1282,7 @@ static unsigned int get_slot_status(struct acpiphp_slot *slot)
 /**
  * acpiphp_eject_slot - physically eject the slot
  */
-static int acpiphp_eject_slot(struct acpiphp_slot *slot)
+int acpiphp_eject_slot(struct acpiphp_slot *slot)
 {
        acpi_status status;
        struct acpiphp_func *func;
@@ -1368,6 +1368,9 @@ static void program_hpp(struct pci_dev *dev, struct acpiphp_bridge *bridge)
                        (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
                return;
 
+       if ((dev->class >> 8) == PCI_CLASS_BRIDGE_HOST)
+               return;
+
        pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
                        bridge->hpp.t0->cache_line_size);
        pci_write_config_byte(dev, PCI_LATENCY_TIMER,
@@ -1502,6 +1505,37 @@ static void handle_bridge_insertion(acpi_handle handle, u32 type)
  * ACPI event handlers
  */
 
+static acpi_status
+count_sub_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+       int *count = (int *)context;
+       struct acpiphp_bridge *bridge;
+
+       bridge = acpiphp_handle_to_bridge(handle);
+       if (bridge)
+               (*count)++;
+       return AE_OK ;
+}
+
+static acpi_status
+check_sub_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+       struct acpiphp_bridge *bridge;
+       char objname[64];
+       struct acpi_buffer buffer = { .length = sizeof(objname),
+                                     .pointer = objname };
+
+       bridge = acpiphp_handle_to_bridge(handle);
+       if (bridge) {
+               acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
+               dbg("%s: re-enumerating slots under %s\n",
+                       __FUNCTION__, objname);
+               acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
+               acpiphp_check_bridge(bridge);
+       }
+       return AE_OK ;
+}
+
 /**
  * handle_hotplug_event_bridge - handle ACPI event on bridges
  *
@@ -1519,6 +1553,7 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont
        struct acpi_buffer buffer = { .length = sizeof(objname),
                                      .pointer = objname };
        struct acpi_device *device;
+       int num_sub_bridges = 0;
 
        if (acpi_bus_get_device(handle, &device)) {
                /* This bridge must have just been physically inserted */
@@ -1527,7 +1562,12 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont
        }
 
        bridge = acpiphp_handle_to_bridge(handle);
-       if (!bridge) {
+       if (type == ACPI_NOTIFY_BUS_CHECK) {
+               acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, ACPI_UINT32_MAX,
+                       count_sub_bridges, &num_sub_bridges, NULL);
+       }
+
+       if (!bridge && !num_sub_bridges) {
                err("cannot get bridge info\n");
                return;
        }
@@ -1538,7 +1578,14 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont
        case ACPI_NOTIFY_BUS_CHECK:
                /* bus re-enumerate */
                dbg("%s: Bus check notify on %s\n", __FUNCTION__, objname);
-               acpiphp_check_bridge(bridge);
+               if (bridge) {
+                       dbg("%s: re-enumerating slots under %s\n",
+                               __FUNCTION__, objname);
+                       acpiphp_check_bridge(bridge);
+               }
+               if (num_sub_bridges)
+                       acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
+                               ACPI_UINT32_MAX, check_sub_bridges, NULL, NULL);
                break;
 
        case ACPI_NOTIFY_DEVICE_CHECK:
index e7322c25d377e65949722fd1f71b04edabb957d2..70db38c0ced9f6586ed6356e4bc8ef78c6cd4235 100644 (file)
@@ -106,7 +106,8 @@ static int ibm_get_attention_status(struct hotplug_slot *slot, u8 *status);
 static void ibm_handle_events(acpi_handle handle, u32 event, void *context);
 static int ibm_get_table_from_acpi(char **bufp);
 static ssize_t ibm_read_apci_table(struct kobject *kobj,
-               char *buffer, loff_t pos, size_t size);
+                                  struct bin_attribute *bin_attr,
+                                  char *buffer, loff_t pos, size_t size);
 static acpi_status __init ibm_find_acpi_device(acpi_handle handle,
                u32 lvl, void *context, void **rv);
 static int __init ibm_acpiphp_init(void);
@@ -117,7 +118,6 @@ static struct notification ibm_note;
 static struct bin_attribute ibm_apci_table_attr = {
            .attr = {
                    .name = "apci_table",
-                   .owner = THIS_MODULE,
                    .mode = S_IRUGO,
            },
            .read = ibm_read_apci_table,
@@ -358,7 +358,8 @@ read_table_done:
  * our solution is to only allow reading the table in all at once
  **/
 static ssize_t ibm_read_apci_table(struct kobject *kobj,
-               char *buffer, loff_t pos, size_t size)
+                                  struct bin_attribute *bin_attr,
+                                  char *buffer, loff_t pos, size_t size)
 {
        int bytes_read = -EINVAL;
        char *table = NULL;
index 684551559d4420b7b9f436ee879ceb75cf15a296..ed4d44e3332c1fd38fcbd535b206fca54586c81d 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/smp_lock.h>
 #include <asm/atomic.h>
 #include <linux/delay.h>
+#include <linux/kthread.h>
 #include "cpci_hotplug.h"
 
 #define DRIVER_AUTHOR  "Scott Murray <scottm@somanetworks.com>"
@@ -59,9 +60,8 @@ static int slots;
 static atomic_t extracting;
 int cpci_debug;
 static struct cpci_hp_controller *controller;
-static struct semaphore event_semaphore;       /* mutex for process loop (up if something to process) */
-static struct semaphore thread_exit;           /* guard ensure thread has exited before calling it quits */
-static int thread_finished = 1;
+static struct task_struct *cpci_thread;
+static int thread_finished;
 
 static int enable_slot(struct hotplug_slot *slot);
 static int disable_slot(struct hotplug_slot *slot);
@@ -357,9 +357,7 @@ cpci_hp_intr(int irq, void *data)
        controller->ops->disable_irq();
 
        /* Trigger processing by the event thread */
-       dbg("Signal event_semaphore");
-       up(&event_semaphore);
-       dbg("exited cpci_hp_intr");
+       wake_up_process(cpci_thread);
        return IRQ_HANDLED;
 }
 
@@ -521,17 +519,12 @@ event_thread(void *data)
 {
        int rc;
 
-       lock_kernel();
-       daemonize("cpci_hp_eventd");
-       unlock_kernel();
-
        dbg("%s - event thread started", __FUNCTION__);
        while (1) {
                dbg("event thread sleeping");
-               down_interruptible(&event_semaphore);
-               dbg("event thread woken, thread_finished = %d",
-                   thread_finished);
-               if (thread_finished || signal_pending(current))
+               set_current_state(TASK_INTERRUPTIBLE);
+               schedule();
+               if (kthread_should_stop())
                        break;
                do {
                        rc = check_slots();
@@ -541,18 +534,17 @@ event_thread(void *data)
                        } else if (rc < 0) {
                                dbg("%s - error checking slots", __FUNCTION__);
                                thread_finished = 1;
-                               break;
+                               goto out;
                        }
-               } while (atomic_read(&extracting) && !thread_finished);
-               if (thread_finished)
+               } while (atomic_read(&extracting) && !kthread_should_stop());
+               if (kthread_should_stop())
                        break;
 
                /* Re-enable ENUM# interrupt */
                dbg("%s - re-enabling irq", __FUNCTION__);
                controller->ops->enable_irq();
        }
-       dbg("%s - event thread signals exit", __FUNCTION__);
-       up(&thread_exit);
+ out:
        return 0;
 }
 
@@ -562,12 +554,8 @@ poll_thread(void *data)
 {
        int rc;
 
-       lock_kernel();
-       daemonize("cpci_hp_polld");
-       unlock_kernel();
-
        while (1) {
-               if (thread_finished || signal_pending(current))
+               if (kthread_should_stop() || signal_pending(current))
                        break;
                if (controller->ops->query_enum()) {
                        do {
@@ -578,48 +566,36 @@ poll_thread(void *data)
                                } else if (rc < 0) {
                                        dbg("%s - error checking slots", __FUNCTION__);
                                        thread_finished = 1;
-                                       break;
+                                       goto out;
                                }
-                       } while (atomic_read(&extracting) && !thread_finished);
+                       } while (atomic_read(&extracting) && !kthread_should_stop());
                }
                msleep(100);
        }
-       dbg("poll thread signals exit");
-       up(&thread_exit);
+ out:
        return 0;
 }
 
 static int
 cpci_start_thread(void)
 {
-       int pid;
-
-       /* initialize our semaphores */
-       init_MUTEX_LOCKED(&event_semaphore);
-       init_MUTEX_LOCKED(&thread_exit);
-       thread_finished = 0;
-
        if (controller->irq)
-               pid = kernel_thread(event_thread, NULL, 0);
+               cpci_thread = kthread_run(event_thread, NULL, "cpci_hp_eventd");
        else
-               pid = kernel_thread(poll_thread, NULL, 0);
-       if (pid < 0) {
+               cpci_thread = kthread_run(poll_thread, NULL, "cpci_hp_polld");
+       if (IS_ERR(cpci_thread)) {
                err("Can't start up our thread");
-               return -1;
+               return PTR_ERR(cpci_thread);
        }
-       dbg("Our thread pid = %d", pid);
+       thread_finished = 0;
        return 0;
 }
 
 static void
 cpci_stop_thread(void)
 {
+       kthread_stop(cpci_thread);
        thread_finished = 1;
-       dbg("thread finish command given");
-       if (controller->irq)
-               up(&event_semaphore);
-       dbg("wait for thread to exit");
-       down(&thread_exit);
 }
 
 int
index 7b1beaad2752ef731a41e2be9d91e5189ce41fe8..5e9be44817cb5ff4daa3f8bc5b04f6f45f10e6d3 100644 (file)
@@ -45,8 +45,6 @@ extern int cpci_debug;
 #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg)
 #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
 
-#define ROUND_UP(x, a)         (((x) + (a) - 1) & ~((a) - 1))
-
 
 u8 cpci_get_attention_status(struct slot* slot)
 {
index 5617cfdadc5c64b19b49a08c041b28fb78c52919..d590a99930fa5a762f2d327faca4d10ecb7373d3 100644 (file)
@@ -796,7 +796,6 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        u8 num_of_slots = 0;
        u8 hp_slot = 0;
        u8 device;
-       u8 rev;
        u8 bus_cap;
        u16 temp_word;
        u16 vendor_id;
@@ -823,9 +822,8 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        }
        dbg("Vendor ID: %x\n", vendor_id);
 
-       rc = pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
-       dbg("revision: %d\n", rev);
-       if (rc || ((vendor_id == PCI_VENDOR_ID_COMPAQ) && (!rev))) {
+       dbg("revision: %d\n", pdev->revision);
+       if ((vendor_id == PCI_VENDOR_ID_COMPAQ) && (!pdev->revision)) {
                err(msg_HPC_rev_error);
                rc = -ENODEV;
                goto err_disable_device;
@@ -836,7 +834,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
         * For Intel, each SSID bit identifies a PHP capability.
         * Also Intel HPC's may have RID=0.
         */
-       if ((rev > 2) || (vendor_id == PCI_VENDOR_ID_INTEL)) {
+       if ((pdev->revision > 2) || (vendor_id == PCI_VENDOR_ID_INTEL)) {
                // TODO: This code can be made to support non-Compaq or Intel subsystem IDs
                rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vid);
                if (rc) {
@@ -870,7 +868,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
                switch (subsystem_vid) {
                        case PCI_VENDOR_ID_COMPAQ:
-                               if (rev >= 0x13) { /* CIOBX */
+                               if (pdev->revision >= 0x13) { /* CIOBX */
                                        ctrl->push_flag = 1;
                                        ctrl->slot_switch_type = 1;
                                        ctrl->push_button = 1;
@@ -1075,7 +1073,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        memcpy(ctrl->pci_bus, pdev->bus, sizeof(*ctrl->pci_bus));
 
        ctrl->bus = pdev->bus->number;
-       ctrl->rev = rev;
+       ctrl->rev = pdev->revision;
        dbg("bus device function rev: %d %d %d %d\n", ctrl->bus,
                PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), ctrl->rev);
 
index ccc57627201eecaf56bff44a4a7826b6ac88e68f..7959c222dc24e939c7734fc201fab8491004a3b0 100644 (file)
@@ -103,6 +103,7 @@ struct controller {
        u8 cap_base;
        struct timer_list poll_timer;
        volatile int cmd_busy;
+       spinlock_t lock;
 };
 
 #define INT_BUTTON_IGNORE              0
index 7f22caa70178c5d74393f5f9ca2a18e94c296435..98e541ffef3d5f9ae0d90d91f5c66b358bfc4783 100644 (file)
@@ -197,6 +197,12 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot)
                            __FUNCTION__);
                        return;
                }
+               /*
+                * After turning power off, we must wait for at least
+                * 1 second before taking any action that relies on
+                * power having been removed from the slot/adapter.
+                */
+               msleep(1000);
        }
 }
 
@@ -615,6 +621,12 @@ int pciehp_disable_slot(struct slot *p_slot)
                        mutex_unlock(&p_slot->ctrl->crit_sect);
                        return -EINVAL;
                }
+               /*
+                * After turning power off, we must wait for at least
+                * 1 second before taking any action that relies on
+                * power having been removed from the slot/adapter.
+                */
+               msleep(1000);
        }
 
        ret = remove_board(p_slot);
index 9aac6a87eb5393f01bc1c7e15956d1efdbb9b5b9..016eea94a8a5729d1cf6e5908a2c6a205d4b6149 100644 (file)
@@ -275,11 +275,19 @@ static inline int pcie_wait_cmd(struct controller *ctrl)
        return retval;
 }
 
-static int pcie_write_cmd(struct slot *slot, u16 cmd)
+/**
+ * pcie_write_cmd - Issue controller command
+ * @slot: slot to which the command is issued
+ * @cmd:  command value written to slot control register
+ * @mask: bitmask of slot control register to be modified
+ */
+static int pcie_write_cmd(struct slot *slot, u16 cmd, u16 mask)
 {
        struct controller *ctrl = slot->ctrl;
        int retval = 0;
        u16 slot_status;
+       u16 slot_ctrl;
+       unsigned long flags;
 
        DBG_ENTER_ROUTINE 
 
@@ -299,17 +307,29 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd)
                    __FUNCTION__);
        }
 
-       ctrl->cmd_busy = 1;
-       retval = pciehp_writew(ctrl, SLOTCTRL, (cmd | CMD_CMPL_INTR_ENABLE));
+       spin_lock_irqsave(&ctrl->lock, flags);
+       retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl);
        if (retval) {
-               err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__);
-               goto out;
+               err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__);
+               goto out_spin_unlock;
        }
 
+       slot_ctrl &= ~mask;
+       slot_ctrl |= ((cmd & mask) | CMD_CMPL_INTR_ENABLE);
+
+       ctrl->cmd_busy = 1;
+       retval = pciehp_writew(ctrl, SLOTCTRL, slot_ctrl);
+       if (retval)
+               err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__);
+
+ out_spin_unlock:
+       spin_unlock_irqrestore(&ctrl->lock, flags);
+
        /*
         * Wait for command completion.
         */
-       retval = pcie_wait_cmd(ctrl);
+       if (!retval)
+               retval = pcie_wait_cmd(ctrl);
  out:
        mutex_unlock(&ctrl->ctrl_lock);
        DBG_LEAVE_ROUTINE 
@@ -502,25 +522,20 @@ static int hpc_get_emi_status(struct slot *slot, u8 *status)
 
 static int hpc_toggle_emi(struct slot *slot)
 {
-       struct controller *ctrl = slot->ctrl;
-       u16 slot_cmd = 0;
-       u16 slot_ctrl;
-       int rc = 0;
+       u16 slot_cmd;
+       u16 cmd_mask;
+       int rc;
 
        DBG_ENTER_ROUTINE
 
-       rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl);
-       if (rc) {
-               err("%s : hp_register_read_word SLOT_CTRL failed\n",
-                       __FUNCTION__);
-               return rc;
-       }
-
-       slot_cmd = (slot_ctrl | EMI_CTRL);
-       if (!pciehp_poll_mode)
+       slot_cmd = EMI_CTRL;
+       cmd_mask = EMI_CTRL;
+       if (!pciehp_poll_mode) {
                slot_cmd = slot_cmd | HP_INTR_ENABLE;
+               cmd_mask = cmd_mask | HP_INTR_ENABLE;
+       }
 
-       pcie_write_cmd(slot, slot_cmd);
+       rc = pcie_write_cmd(slot, slot_cmd, cmd_mask);
        slot->last_emi_toggle = get_seconds();
        DBG_LEAVE_ROUTINE
        return rc;
@@ -529,35 +544,32 @@ static int hpc_toggle_emi(struct slot *slot)
 static int hpc_set_attention_status(struct slot *slot, u8 value)
 {
        struct controller *ctrl = slot->ctrl;
-       u16 slot_cmd = 0;
-       u16 slot_ctrl;
-       int rc = 0;
+       u16 slot_cmd;
+       u16 cmd_mask;
+       int rc;
 
        DBG_ENTER_ROUTINE
 
-       rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl);
-       if (rc) {
-               err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__);
-               return rc;
-       }
-
+       cmd_mask = ATTN_LED_CTRL;
        switch (value) {
                case 0 :        /* turn off */
-                       slot_cmd = (slot_ctrl & ~ATTN_LED_CTRL) | 0x00C0;
+                       slot_cmd = 0x00C0;
                        break;
                case 1:         /* turn on */
-                       slot_cmd = (slot_ctrl & ~ATTN_LED_CTRL) | 0x0040;
+                       slot_cmd = 0x0040;
                        break;
                case 2:         /* turn blink */
-                       slot_cmd = (slot_ctrl & ~ATTN_LED_CTRL) | 0x0080;
+                       slot_cmd = 0x0080;
                        break;
                default:
                        return -1;
        }
-       if (!pciehp_poll_mode)
-               slot_cmd = slot_cmd | HP_INTR_ENABLE; 
+       if (!pciehp_poll_mode) {
+               slot_cmd = slot_cmd | HP_INTR_ENABLE;
+               cmd_mask = cmd_mask | HP_INTR_ENABLE;
+       }
 
-       pcie_write_cmd(slot, slot_cmd);
+       rc = pcie_write_cmd(slot, slot_cmd, cmd_mask);
        dbg("%s: SLOTCTRL %x write cmd %x\n",
            __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd);
        
@@ -570,21 +582,18 @@ static void hpc_set_green_led_on(struct slot *slot)
 {
        struct controller *ctrl = slot->ctrl;
        u16 slot_cmd;
-       u16 slot_ctrl;
-       int rc = 0;
+       u16 cmd_mask;
                
        DBG_ENTER_ROUTINE
 
-       rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl);
-       if (rc) {
-               err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__);
-               return;
+       slot_cmd = 0x0100;
+       cmd_mask = PWR_LED_CTRL;
+       if (!pciehp_poll_mode) {
+               slot_cmd = slot_cmd | HP_INTR_ENABLE;
+               cmd_mask = cmd_mask | HP_INTR_ENABLE;
        }
-       slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0100;
-       if (!pciehp_poll_mode)
-               slot_cmd = slot_cmd | HP_INTR_ENABLE; 
 
-       pcie_write_cmd(slot, slot_cmd);
+       pcie_write_cmd(slot, slot_cmd, cmd_mask);
 
        dbg("%s: SLOTCTRL %x write cmd %x\n",
            __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd);
@@ -596,22 +605,18 @@ static void hpc_set_green_led_off(struct slot *slot)
 {
        struct controller *ctrl = slot->ctrl;
        u16 slot_cmd;
-       u16 slot_ctrl;
-       int rc = 0;
+       u16 cmd_mask;
 
        DBG_ENTER_ROUTINE
 
-       rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl);
-       if (rc) {
-               err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__);
-               return;
+       slot_cmd = 0x0300;
+       cmd_mask = PWR_LED_CTRL;
+       if (!pciehp_poll_mode) {
+               slot_cmd = slot_cmd | HP_INTR_ENABLE;
+               cmd_mask = cmd_mask | HP_INTR_ENABLE;
        }
 
-       slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0300;
-
-       if (!pciehp_poll_mode)
-               slot_cmd = slot_cmd | HP_INTR_ENABLE; 
-       pcie_write_cmd(slot, slot_cmd);
+       pcie_write_cmd(slot, slot_cmd, cmd_mask);
        dbg("%s: SLOTCTRL %x write cmd %x\n",
            __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd);
 
@@ -623,22 +628,18 @@ static void hpc_set_green_led_blink(struct slot *slot)
 {
        struct controller *ctrl = slot->ctrl;
        u16 slot_cmd;
-       u16 slot_ctrl;
-       int rc = 0; 
+       u16 cmd_mask;
        
        DBG_ENTER_ROUTINE
 
-       rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl);
-       if (rc) {
-               err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__);
-               return;
+       slot_cmd = 0x0200;
+       cmd_mask = PWR_LED_CTRL;
+       if (!pciehp_poll_mode) {
+               slot_cmd = slot_cmd | HP_INTR_ENABLE;
+               cmd_mask = cmd_mask | HP_INTR_ENABLE;
        }
 
-       slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0200;
-
-       if (!pciehp_poll_mode)
-               slot_cmd = slot_cmd | HP_INTR_ENABLE; 
-       pcie_write_cmd(slot, slot_cmd);
+       pcie_write_cmd(slot, slot_cmd, cmd_mask);
 
        dbg("%s: SLOTCTRL %x write cmd %x\n",
            __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd);
@@ -669,7 +670,8 @@ static int hpc_power_on_slot(struct slot * slot)
 {
        struct controller *ctrl = slot->ctrl;
        u16 slot_cmd;
-       u16 slot_ctrl, slot_status;
+       u16 cmd_mask;
+       u16 slot_status;
        int retval = 0;
 
        DBG_ENTER_ROUTINE 
@@ -692,23 +694,23 @@ static int hpc_power_on_slot(struct slot * slot)
                }
        }
 
-       retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl);
-       if (retval) {
-               err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__);
-               return retval;
-       }
-
-       slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_ON;
-
+       slot_cmd = POWER_ON;
+       cmd_mask = PWR_CTRL;
        /* Enable detection that we turned off at slot power-off time */
-       if (!pciehp_poll_mode)
+       if (!pciehp_poll_mode) {
                slot_cmd = slot_cmd |
                           PWR_FAULT_DETECT_ENABLE |
                           MRL_DETECT_ENABLE |
                           PRSN_DETECT_ENABLE |
                           HP_INTR_ENABLE;
+               cmd_mask = cmd_mask |
+                          PWR_FAULT_DETECT_ENABLE |
+                          MRL_DETECT_ENABLE |
+                          PRSN_DETECT_ENABLE |
+                          HP_INTR_ENABLE;
+       }
 
-       retval = pcie_write_cmd(slot, slot_cmd);
+       retval = pcie_write_cmd(slot, slot_cmd, cmd_mask);
 
        if (retval) {
                err("%s: Write %x command failed!\n", __FUNCTION__, slot_cmd);
@@ -726,21 +728,15 @@ static int hpc_power_off_slot(struct slot * slot)
 {
        struct controller *ctrl = slot->ctrl;
        u16 slot_cmd;
-       u16 slot_ctrl;
+       u16 cmd_mask;
        int retval = 0;
 
        DBG_ENTER_ROUTINE 
 
        dbg("%s: slot->hp_slot %x\n", __FUNCTION__, slot->hp_slot);
 
-       retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl);
-       if (retval) {
-               err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__);
-               return retval;
-       }
-
-       slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_OFF;
-
+       slot_cmd = POWER_OFF;
+       cmd_mask = PWR_CTRL;
        /*
         * If we get MRL or presence detect interrupts now, the isr
         * will notice the sticky power-fault bit too and issue power
@@ -748,14 +744,19 @@ static int hpc_power_off_slot(struct slot * slot)
         * of command completions, since the power-fault bit remains on
         * till the slot is powered on again.
         */
-       if (!pciehp_poll_mode)
+       if (!pciehp_poll_mode) {
                slot_cmd = (slot_cmd &
                            ~PWR_FAULT_DETECT_ENABLE &
                            ~MRL_DETECT_ENABLE &
                            ~PRSN_DETECT_ENABLE) | HP_INTR_ENABLE;
+               cmd_mask = cmd_mask |
+                          PWR_FAULT_DETECT_ENABLE |
+                          MRL_DETECT_ENABLE |
+                          PRSN_DETECT_ENABLE |
+                          HP_INTR_ENABLE;
+       }
 
-       retval = pcie_write_cmd(slot, slot_cmd);
-
+       retval = pcie_write_cmd(slot, slot_cmd, cmd_mask);
        if (retval) {
                err("%s: Write command failed!\n", __FUNCTION__);
                return -1;
@@ -775,6 +776,7 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
        u16 temp_word;
        int hp_slot = 0;        /* only 1 slot per PCI Express port */
        int rc = 0;
+       unsigned long flags;
 
        rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
        if (rc) {
@@ -794,10 +796,12 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
        dbg("%s: intr_loc %x\n", __FUNCTION__, intr_loc);
        /* Mask Hot-plug Interrupt Enable */
        if (!pciehp_poll_mode) {
+               spin_lock_irqsave(&ctrl->lock, flags);
                rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word);
                if (rc) {
                        err("%s: Cannot read SLOT_CTRL register\n",
                            __FUNCTION__);
+                       spin_unlock_irqrestore(&ctrl->lock, flags);
                        return IRQ_NONE;
                }
 
@@ -808,8 +812,10 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
                if (rc) {
                        err("%s: Cannot write to SLOTCTRL register\n",
                            __FUNCTION__);
+                       spin_unlock_irqrestore(&ctrl->lock, flags);
                        return IRQ_NONE;
                }
+               spin_unlock_irqrestore(&ctrl->lock, flags);
 
                rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
                if (rc) {
@@ -859,10 +865,12 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
        }
        /* Unmask Hot-plug Interrupt Enable */
        if (!pciehp_poll_mode) {
+               spin_lock_irqsave(&ctrl->lock, flags);
                rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word);
                if (rc) {
                        err("%s: Cannot read SLOTCTRL register\n",
                            __FUNCTION__);
+                       spin_unlock_irqrestore(&ctrl->lock, flags);
                        return IRQ_NONE;
                }
 
@@ -873,8 +881,10 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
                if (rc) {
                        err("%s: Cannot write to SLOTCTRL register\n",
                            __FUNCTION__);
+                       spin_unlock_irqrestore(&ctrl->lock, flags);
                        return IRQ_NONE;
                }
+               spin_unlock_irqrestore(&ctrl->lock, flags);
 
                rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
                if (rc) {
@@ -1237,6 +1247,7 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
 
        mutex_init(&ctrl->crit_sect);
        mutex_init(&ctrl->ctrl_lock);
+       spin_lock_init(&ctrl->lock);
 
        /* setup wait queue */
        init_waitqueue_head(&ctrl->queue);
index b5ac810404c0f19dc98318dfe8dde6212d04c2bb..c8062494009f8fdb692adbbe15bb741a870064cd 100644 (file)
@@ -55,8 +55,6 @@ acpi_query_osc (
 
        status = acpi_evaluate_object(handle, "_OSC", &input, &output);
        if (ACPI_FAILURE (status)) {
-               printk(KERN_DEBUG  
-                       "Evaluate _OSC Set fails. Status = 0x%04x\n", status);
                *ret_status = status;
                return status;
        }
@@ -124,11 +122,9 @@ acpi_run_osc (
        in_params[3].buffer.pointer     = (u8 *)context;
 
        status = acpi_evaluate_object(handle, "_OSC", &input, &output);
-       if (ACPI_FAILURE (status)) {
-               printk(KERN_DEBUG  
-                       "Evaluate _OSC Set fails. Status = 0x%04x\n", status);
+       if (ACPI_FAILURE (status))
                return status;
-       }
+
        out_obj = output.pointer;
        if (out_obj->type != ACPI_TYPE_BUFFER) {
                printk(KERN_DEBUG  
index 284e83a527f9d4564c916597f6d65b21b2cff08c..10dbdec80416dc69ce9272e37c0fbe7127d328a6 100644 (file)
@@ -213,7 +213,8 @@ struct device_attribute pci_dev_attrs[] = {
 };
 
 static ssize_t
-pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
+pci_read_config(struct kobject *kobj, struct bin_attribute *bin_attr,
+               char *buf, loff_t off, size_t count)
 {
        struct pci_dev *dev = to_pci_dev(container_of(kobj,struct device,kobj));
        unsigned int size = 64;
@@ -285,7 +286,8 @@ pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
 }
 
 static ssize_t
-pci_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
+pci_write_config(struct kobject *kobj, struct bin_attribute *bin_attr,
+                char *buf, loff_t off, size_t count)
 {
        struct pci_dev *dev = to_pci_dev(container_of(kobj,struct device,kobj));
        unsigned int size = count;
@@ -352,7 +354,8 @@ pci_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
  * callback routine (pci_legacy_read).
  */
 ssize_t
-pci_read_legacy_io(struct kobject *kobj, char *buf, loff_t off, size_t count)
+pci_read_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr,
+                  char *buf, loff_t off, size_t count)
 {
         struct pci_bus *bus = to_pci_bus(container_of(kobj,
                                                       struct class_device,
@@ -376,7 +379,8 @@ pci_read_legacy_io(struct kobject *kobj, char *buf, loff_t off, size_t count)
  * callback routine (pci_legacy_write).
  */
 ssize_t
-pci_write_legacy_io(struct kobject *kobj, char *buf, loff_t off, size_t count)
+pci_write_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr,
+                   char *buf, loff_t off, size_t count)
 {
         struct pci_bus *bus = to_pci_bus(container_of(kobj,
                                                      struct class_device,
@@ -499,7 +503,6 @@ static int pci_create_resource_files(struct pci_dev *pdev)
                        sprintf(res_attr_name, "resource%d", i);
                        res_attr->attr.name = res_attr_name;
                        res_attr->attr.mode = S_IRUSR | S_IWUSR;
-                       res_attr->attr.owner = THIS_MODULE;
                        res_attr->size = pci_resource_len(pdev, i);
                        res_attr->mmap = pci_mmap_resource;
                        res_attr->private = &pdev->resource[i];
@@ -529,7 +532,8 @@ static inline void pci_remove_resource_files(struct pci_dev *dev) { return; }
  * writing anything except 0 enables it
  */
 static ssize_t
-pci_write_rom(struct kobject *kobj, char *buf, loff_t off, size_t count)
+pci_write_rom(struct kobject *kobj, struct bin_attribute *bin_attr,
+             char *buf, loff_t off, size_t count)
 {
        struct pci_dev *pdev = to_pci_dev(container_of(kobj, struct device, kobj));
 
@@ -552,7 +556,8 @@ pci_write_rom(struct kobject *kobj, char *buf, loff_t off, size_t count)
  * device corresponding to @kobj.
  */
 static ssize_t
-pci_read_rom(struct kobject *kobj, char *buf, loff_t off, size_t count)
+pci_read_rom(struct kobject *kobj, struct bin_attribute *bin_attr,
+            char *buf, loff_t off, size_t count)
 {
        struct pci_dev *pdev = to_pci_dev(container_of(kobj, struct device, kobj));
        void __iomem *rom;
@@ -582,7 +587,6 @@ static struct bin_attribute pci_config_attr = {
        .attr = {
                .name = "config",
                .mode = S_IRUGO | S_IWUSR,
-               .owner = THIS_MODULE,
        },
        .size = 256,
        .read = pci_read_config,
@@ -593,13 +597,17 @@ static struct bin_attribute pcie_config_attr = {
        .attr = {
                .name = "config",
                .mode = S_IRUGO | S_IWUSR,
-               .owner = THIS_MODULE,
        },
        .size = 4096,
        .read = pci_read_config,
        .write = pci_write_config,
 };
 
+int __attribute__ ((weak)) pcibios_add_platform_entries(struct pci_dev *dev)
+{
+       return 0;
+}
+
 int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev)
 {
        struct bin_attribute *rom_attr = NULL;
@@ -628,7 +636,6 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev)
                        rom_attr->size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
                        rom_attr->attr.name = "rom";
                        rom_attr->attr.mode = S_IRUSR;
-                       rom_attr->attr.owner = THIS_MODULE;
                        rom_attr->read = pci_read_rom;
                        rom_attr->write = pci_write_rom;
                        retval = sysfs_create_bin_file(&pdev->dev.kobj, rom_attr);
@@ -640,10 +647,14 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev)
                }
        }
        /* add platform-specific attributes */
-       pcibios_add_platform_entries(pdev);
+       if (pcibios_add_platform_entries(pdev))
+               goto err_rom_file;
 
        return 0;
 
+err_rom_file:
+       if (pci_resource_len(pdev, PCI_ROM_RESOURCE))
+               sysfs_remove_bin_file(&pdev->dev.kobj, rom_attr);
 err_rom:
        kfree(rom_attr);
 err_resource_files:
index fd47ac0c4730a96080e22151ed186c1ec4585725..03fd59e80fef5726c73a16f1582f4fd8dbf16836 100644 (file)
@@ -406,6 +406,13 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
        if ((state == PCI_D1 || state == PCI_D2) && pci_no_d1d2(dev))
                return 0;
 
+       /* find PCI PM capability in list */
+       pm = pci_find_capability(dev, PCI_CAP_ID_PM);
+
+       /* abort if the device doesn't support PM capabilities */
+       if (!pm)
+               return -EIO;
+
        /* Validate current state:
         * Can enter D0 from any state, but if we can only go deeper 
         * to sleep if we're already in a low power state
@@ -418,13 +425,6 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
                return 0;        /* we're already there */
 
 
-       /* find PCI PM capability in list */
-       pm = pci_find_capability(dev, PCI_CAP_ID_PM);
-       
-       /* abort if the device doesn't support PM capabilities */
-       if (!pm)
-               return -EIO; 
-
        pci_read_config_word(dev,pm + PCI_PM_PMC,&pmc);
        if ((pmc & PCI_PM_CAP_VER_MASK) > 3) {
                printk(KERN_DEBUG
@@ -1186,6 +1186,11 @@ int pci_set_mwi(struct pci_dev *dev)
        return 0;
 }
 
+int pci_try_set_mwi(struct pci_dev *dev)
+{
+       return 0;
+}
+
 void pci_clear_mwi(struct pci_dev *dev)
 {
 }
@@ -1242,9 +1247,7 @@ pci_set_cacheline_size(struct pci_dev *dev)
  * pci_set_mwi - enables memory-write-invalidate PCI transaction
  * @dev: the PCI device for which MWI is enabled
  *
- * Enables the Memory-Write-Invalidate transaction in %PCI_COMMAND,
- * and then calls @pcibios_set_mwi to do the needed arch specific
- * operations or a generic mwi-prep function.
+ * Enables the Memory-Write-Invalidate transaction in %PCI_COMMAND.
  *
  * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
  */
@@ -1260,7 +1263,8 @@ pci_set_mwi(struct pci_dev *dev)
 
        pci_read_config_word(dev, PCI_COMMAND, &cmd);
        if (! (cmd & PCI_COMMAND_INVALIDATE)) {
-               pr_debug("PCI: Enabling Mem-Wr-Inval for device %s\n", pci_name(dev));
+               pr_debug("PCI: Enabling Mem-Wr-Inval for device %s\n",
+                       pci_name(dev));
                cmd |= PCI_COMMAND_INVALIDATE;
                pci_write_config_word(dev, PCI_COMMAND, cmd);
        }
@@ -1268,6 +1272,21 @@ pci_set_mwi(struct pci_dev *dev)
        return 0;
 }
 
+/**
+ * pci_try_set_mwi - enables memory-write-invalidate PCI transaction
+ * @dev: the PCI device for which MWI is enabled
+ *
+ * Enables the Memory-Write-Invalidate transaction in %PCI_COMMAND.
+ * Callers are not required to check the return value.
+ *
+ * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
+ */
+int pci_try_set_mwi(struct pci_dev *dev)
+{
+       int rc = pci_set_mwi(dev);
+       return rc;
+}
+
 /**
  * pci_clear_mwi - disables Memory-Write-Invalidate for device dev
  * @dev: the PCI device to disable
@@ -1374,6 +1393,164 @@ pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
 }
 #endif
 
+/**
+ * pcix_get_max_mmrbc - get PCI-X maximum designed memory read byte count
+ * @dev: PCI device to query
+ *
+ * Returns mmrbc: maximum designed memory read count in bytes
+ *    or appropriate error value.
+ */
+int pcix_get_max_mmrbc(struct pci_dev *dev)
+{
+       int err, cap;
+       u32 stat;
+
+       cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
+       if (!cap)
+               return -EINVAL;
+
+       err = pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat);
+       if (err)
+               return -EINVAL;
+
+       return (stat & PCI_X_STATUS_MAX_READ) >> 12;
+}
+EXPORT_SYMBOL(pcix_get_max_mmrbc);
+
+/**
+ * pcix_get_mmrbc - get PCI-X maximum memory read byte count
+ * @dev: PCI device to query
+ *
+ * Returns mmrbc: maximum memory read count in bytes
+ *    or appropriate error value.
+ */
+int pcix_get_mmrbc(struct pci_dev *dev)
+{
+       int ret, cap;
+       u32 cmd;
+
+       cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
+       if (!cap)
+               return -EINVAL;
+
+       ret = pci_read_config_dword(dev, cap + PCI_X_CMD, &cmd);
+       if (!ret)
+               ret = 512 << ((cmd & PCI_X_CMD_MAX_READ) >> 2);
+
+       return ret;
+}
+EXPORT_SYMBOL(pcix_get_mmrbc);
+
+/**
+ * pcix_set_mmrbc - set PCI-X maximum memory read byte count
+ * @dev: PCI device to query
+ * @mmrbc: maximum memory read count in bytes
+ *    valid values are 512, 1024, 2048, 4096
+ *
+ * If possible sets maximum memory read byte count, some bridges have erratas
+ * that prevent this.
+ */
+int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc)
+{
+       int cap, err = -EINVAL;
+       u32 stat, cmd, v, o;
+
+       if (mmrbc < 512 || mmrbc > 4096 || (mmrbc & (mmrbc-1)))
+               goto out;
+
+       v = ffs(mmrbc) - 10;
+
+       cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
+       if (!cap)
+               goto out;
+
+       err = pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat);
+       if (err)
+               goto out;
+
+       if (v > (stat & PCI_X_STATUS_MAX_READ) >> 21)
+               return -E2BIG;
+
+       err = pci_read_config_dword(dev, cap + PCI_X_CMD, &cmd);
+       if (err)
+               goto out;
+
+       o = (cmd & PCI_X_CMD_MAX_READ) >> 2;
+       if (o != v) {
+               if (v > o && dev->bus &&
+                  (dev->bus->bus_flags & PCI_BUS_FLAGS_NO_MMRBC))
+                       return -EIO;
+
+               cmd &= ~PCI_X_CMD_MAX_READ;
+               cmd |= v << 2;
+               err = pci_write_config_dword(dev, cap + PCI_X_CMD, cmd);
+       }
+out:
+       return err;
+}
+EXPORT_SYMBOL(pcix_set_mmrbc);
+
+/**
+ * pcie_get_readrq - get PCI Express read request size
+ * @dev: PCI device to query
+ *
+ * Returns maximum memory read request in bytes
+ *    or appropriate error value.
+ */
+int pcie_get_readrq(struct pci_dev *dev)
+{
+       int ret, cap;
+       u16 ctl;
+
+       cap = pci_find_capability(dev, PCI_CAP_ID_EXP);
+       if (!cap)
+               return -EINVAL;
+
+       ret = pci_read_config_word(dev, cap + PCI_EXP_DEVCTL, &ctl);
+       if (!ret)
+       ret = 128 << ((ctl & PCI_EXP_DEVCTL_READRQ) >> 12);
+
+       return ret;
+}
+EXPORT_SYMBOL(pcie_get_readrq);
+
+/**
+ * pcie_set_readrq - set PCI Express maximum memory read request
+ * @dev: PCI device to query
+ * @count: maximum memory read count in bytes
+ *    valid values are 128, 256, 512, 1024, 2048, 4096
+ *
+ * If possible sets maximum read byte count
+ */
+int pcie_set_readrq(struct pci_dev *dev, int rq)
+{
+       int cap, err = -EINVAL;
+       u16 ctl, v;
+
+       if (rq < 128 || rq > 4096 || (rq & (rq-1)))
+               goto out;
+
+       v = (ffs(rq) - 8) << 12;
+
+       cap = pci_find_capability(dev, PCI_CAP_ID_EXP);
+       if (!cap)
+               goto out;
+
+       err = pci_read_config_word(dev, cap + PCI_EXP_DEVCTL, &ctl);
+       if (err)
+               goto out;
+
+       if ((ctl & PCI_EXP_DEVCTL_READRQ) != v) {
+               ctl &= ~PCI_EXP_DEVCTL_READRQ;
+               ctl |= v;
+               err = pci_write_config_dword(dev, cap + PCI_EXP_DEVCTL, ctl);
+       }
+
+out:
+       return err;
+}
+EXPORT_SYMBOL(pcie_set_readrq);
+
 /**
  * pci_select_bars - Make BAR mask from the type of resource
  * @dev: the PCI device for which BAR mask is made
@@ -1442,6 +1619,7 @@ EXPORT_SYMBOL(pci_release_selected_regions);
 EXPORT_SYMBOL(pci_request_selected_regions);
 EXPORT_SYMBOL(pci_set_master);
 EXPORT_SYMBOL(pci_set_mwi);
+EXPORT_SYMBOL(pci_try_set_mwi);
 EXPORT_SYMBOL(pci_clear_mwi);
 EXPORT_SYMBOL_GPL(pci_intx);
 EXPORT_SYMBOL(pci_set_dma_mask);
index 3f37a60a6438218245dfdac675d42da21bce511c..c3bde588aa13db4d814785ee24e7bfe86ef4c6c6 100644 (file)
@@ -4,7 +4,7 @@
 
 config PCIEAER
        boolean "Root Port Advanced Error Reporting support"
-       depends on PCIEPORTBUS && ACPI
+       depends on PCIEPORTBUS
        default y
        help
          This enables PCI Express Root Port Advanced Error Reporting
index 15a4f40d520b35eccc6457c40d43653df7922953..8da3bd8455a882b334cf8d843fa4846cc9153fe3 100644 (file)
@@ -4,5 +4,6 @@
 
 obj-$(CONFIG_PCIEAER) += aerdriver.o
 
-aerdriver-objs := aerdrv_errprint.o aerdrv_core.o aerdrv.o aerdrv_acpi.o
+aerdriver-objs := aerdrv_errprint.o aerdrv_core.o aerdrv.o
+aerdriver-$(CONFIG_ACPI) += aerdrv_acpi.o
 
index db6ad8e763ac91dd7d86a4ab55469e1e1dd8128b..6846fb42b399313202ae019fecddb58d3c27eac0 100644 (file)
@@ -157,7 +157,7 @@ static struct aer_rpc* aer_alloc_rpc(struct pcie_device *dev)
         * Initialize Root lock access, e_lock, to Root Error Status Reg,
         * Root Error ID Reg, and Root error producer/consumer index.
         */
-       rpc->e_lock = SPIN_LOCK_UNLOCKED;
+       spin_lock_init(&rpc->e_lock);
 
        rpc->rpd = dev;
        INIT_WORK(&rpc->dpc_handler, aer_isr);
index 5cca394d59993b14cdd2549781ea4aafe70648cc..c7ad68b6c6d661873daa729c9609326d47e7dbea 100644 (file)
 #define AER_ERROR_MASK                 0x001fffff
 #define AER_ERROR(d)                   (d & AER_ERROR_MASK)
 
-#define OSC_METHOD_RUN_SUCCESS         0
-#define OSC_METHOD_NOT_SUPPORTED       1
-#define OSC_METHOD_RUN_FAILURE         2
-
 /* Root Error Status Register Bits */
 #define ROOT_ERR_STATUS_MASKS                  0x0f
 
@@ -121,6 +117,14 @@ extern void aer_delete_rootport(struct aer_rpc *rpc);
 extern int aer_init(struct pcie_device *dev);
 extern void aer_isr(struct work_struct *work);
 extern void aer_print_error(struct pci_dev *dev, struct aer_err_info *info);
-extern int aer_osc_setup(struct pci_dev *dev);
+
+#ifdef CONFIG_ACPI
+extern int aer_osc_setup(struct pcie_device *pciedev);
+#else
+static inline int aer_osc_setup(struct pcie_device *pciedev)
+{
+       return 0;
+}
+#endif
 
 #endif //_AERDRV_H_
index fa68e89ebec962aa4b007172a52db992f442750b..1a1eb45a779e3862f8ef634cd425d4f117444661 100644 (file)
 
 /**
  * aer_osc_setup - run ACPI _OSC method
+ * @pciedev: pcie_device which AER is being enabled on
  *
- * Return:
- *     Zero if success. Nonzero for otherwise.
+ * @return: Zero on success. Nonzero otherwise.
  *
  * Invoked when PCIE bus loads AER service driver. To avoid conflict with
  * BIOS AER support requires BIOS to yield AER control to OS native driver.
  **/
-int aer_osc_setup(struct pci_dev *dev)
+int aer_osc_setup(struct pcie_device *pciedev)
 {
-       int retval = OSC_METHOD_RUN_SUCCESS;
-       acpi_status status;
-       acpi_handle handle = DEVICE_ACPI_HANDLE(&dev->dev);
-       struct pci_dev *pdev = dev;
+       acpi_status status = AE_NOT_FOUND;
+       struct pci_dev *pdev = pciedev->port;
+       acpi_handle handle = DEVICE_ACPI_HANDLE(&pdev->dev);
        struct pci_bus *parent;
 
        while (!handle) {
@@ -50,19 +49,20 @@ int aer_osc_setup(struct pci_dev *dev)
                pdev = parent->self;
        }
 
-       if (!handle)
-               return OSC_METHOD_NOT_SUPPORTED;
+       if (handle) {
+               pci_osc_support_set(OSC_EXT_PCI_CONFIG_SUPPORT);
+               status = pci_osc_control_set(handle,
+                                       OSC_PCI_EXPRESS_AER_CONTROL |
+                                       OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
+       }
 
-       pci_osc_support_set(OSC_EXT_PCI_CONFIG_SUPPORT);
-       status = pci_osc_control_set(handle, OSC_PCI_EXPRESS_AER_CONTROL |
-               OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
        if (ACPI_FAILURE(status)) {
-               if (status == AE_SUPPORT)
-                       retval = OSC_METHOD_NOT_SUPPORTED;
-               else
-                       retval = OSC_METHOD_RUN_FAILURE;
+               printk(KERN_DEBUG "AER service couldn't init device %s - %s\n",
+                   pciedev->device.bus_id,
+                   (status == AE_SUPPORT || status == AE_NOT_FOUND) ?
+                   "no _OSC support" : "Run ACPI _OSC fails");
+               return -1;
        }
 
-       return retval;
+       return 0;
 }
-
index 08e13033ced8fc642df5565c1e9cf07867563862..92a8469b21bacecc2f161621553029ea99222d1e 100644 (file)
@@ -22,8 +22,6 @@
 #include <linux/errno.h>
 #include <linux/pm.h>
 #include <linux/suspend.h>
-#include <linux/acpi.h>
-#include <linux/pci-acpi.h>
 #include <linux/delay.h>
 #include "aerdrv.h"
 
@@ -119,6 +117,21 @@ int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev)
        return 0;
 }
 
+int pci_cleanup_aer_correct_error_status(struct pci_dev *dev)
+{
+       int pos;
+       u32 status;
+
+       pos = pci_find_aer_capability(dev);
+       if (!pos)
+               return -EIO;
+
+       pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS, &status);
+       pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, status);
+
+       return 0;
+}
+
 static int find_device_iter(struct device *device, void *data)
 {
        struct pci_dev *dev;
@@ -733,20 +746,8 @@ void aer_delete_rootport(struct aer_rpc *rpc)
  **/
 int aer_init(struct pcie_device *dev)
 {
-       int status;
-
-       /* Run _OSC Method */
-       status = aer_osc_setup(dev->port);
-
-       if(status != OSC_METHOD_RUN_SUCCESS) {
-               printk(KERN_DEBUG "%s: AER service init fails - %s\n",
-               __FUNCTION__,
-               (status == OSC_METHOD_NOT_SUPPORTED) ?
-                       "No ACPI _OSC support" : "Run ACPI _OSC fails");
-
-               if (!forceload)
-                       return status;
-       }
+       if (aer_osc_setup(dev) && !forceload)
+               return -ENXIO;
 
        return AER_SUCCESS;
 }
@@ -755,4 +756,5 @@ EXPORT_SYMBOL_GPL(pci_find_aer_capability);
 EXPORT_SYMBOL_GPL(pci_enable_pcie_error_reporting);
 EXPORT_SYMBOL_GPL(pci_disable_pcie_error_reporting);
 EXPORT_SYMBOL_GPL(pci_cleanup_aer_uncorrect_error_status);
+EXPORT_SYMBOL_GPL(pci_cleanup_aer_correct_error_status);
 
index e48fcf0896212193ace241d8f066fb8de9100feb..a7bce75c673281641bec37054c10d3def7afabe5 100644 (file)
@@ -39,7 +39,6 @@ static void pci_create_legacy_files(struct pci_bus *b)
                b->legacy_io->attr.name = "legacy_io";
                b->legacy_io->size = 0xffff;
                b->legacy_io->attr.mode = S_IRUSR | S_IWUSR;
-               b->legacy_io->attr.owner = THIS_MODULE;
                b->legacy_io->read = pci_read_legacy_io;
                b->legacy_io->write = pci_write_legacy_io;
                class_device_create_bin_file(&b->class_dev, b->legacy_io);
@@ -49,7 +48,6 @@ static void pci_create_legacy_files(struct pci_bus *b)
                b->legacy_mem->attr.name = "legacy_mem";
                b->legacy_mem->size = 1024*1024;
                b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR;
-               b->legacy_mem->attr.owner = THIS_MODULE;
                b->legacy_mem->mmap = pci_mmap_legacy_mem;
                class_device_create_bin_file(&b->class_dev, b->legacy_mem);
        }
@@ -656,7 +654,7 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass
                               pcibios_assign_all_busses() ? " " :
                               " (try 'pci=assign-busses')");
                        printk(KERN_WARNING "Please report the result to "
-                              "linux-kernel to fix this permanently\n");
+                              "<bk@suse.de> to fix this permanently\n");
                }
                bus = bus->parent;
        }
@@ -702,6 +700,7 @@ static int pci_setup_device(struct pci_dev * dev)
                dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
 
        pci_read_config_dword(dev, PCI_CLASS_REVISION, &class);
+       dev->revision = class & 0xff;
        class >>= 8;                                /* upper 3 bytes */
        dev->class = class;
        class >>= 8;
index 0425a7b7350d987760bfff76cbd0e0af6d311800..cfa0dfe61b1af384b89da6147cb75bf93d6dc70d 100644 (file)
@@ -480,7 +480,6 @@ static int __init pci_proc_init(void)
 __initcall(pci_proc_init);
 
 #ifdef CONFIG_HOTPLUG
-EXPORT_SYMBOL(pci_proc_attach_device);
 EXPORT_SYMBOL(pci_proc_detach_bus);
 #endif
 
index 01d8f8a8843c5c064250f09af7396a1e3aa7cdd0..c559085c89a50f2c0ee909191c2ef0b0ea549f66 100644 (file)
@@ -587,10 +587,7 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA,        PCI_DEVICE_ID_VIA_8237,         quirk_via_v
  */
 static void __devinit quirk_amd_ioapic(struct pci_dev *dev)
 {
-       u8 rev;
-
-       pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
-       if (rev >= 0x02) {
+       if (dev->revision >= 0x02) {
                printk(KERN_WARNING "I/O APIC: AMD Erratum #22 may be present. In the event of instability try\n");
                printk(KERN_WARNING "        : booting with the \"noapic\" option.\n");
        }
@@ -610,13 +607,12 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, PCI_ANY_ID,                     quirk_ioapic_rmw );
 #define AMD8131_NIOAMODE_BIT 0
 static void quirk_amd_8131_ioapic(struct pci_dev *dev)
 { 
-        unsigned char revid, tmp;
+        unsigned char tmp;
         
         if (nr_ioapics == 0) 
                 return;
 
-        pci_read_config_byte(dev, PCI_REVISION_ID, &revid);
-        if (revid == AMD8131_revA0 || revid == AMD8131_revB0) {
+        if (dev->revision == AMD8131_revA0 || dev->revision == AMD8131_revB0) {
                 printk(KERN_INFO "Fixing up AMD8131 IOAPIC mode\n"); 
                 pci_read_config_byte( dev, AMD8131_MISC, &tmp);
                 tmp &= ~(1 << AMD8131_NIOAMODE_BIT);
@@ -627,6 +623,22 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_
 DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic);
 #endif /* CONFIG_X86_IO_APIC */
 
+/*
+ * Some settings of MMRBC can lead to data corruption so block changes.
+ * See AMD 8131 HyperTransport PCI-X Tunnel Revision Guide
+ */
+static void __init quirk_amd_8131_mmrbc(struct pci_dev *dev)
+{
+       unsigned char revid;
+
+       pci_read_config_byte(dev, PCI_REVISION_ID, &revid);
+       if (dev->subordinate && revid <= 0x12) {
+               printk(KERN_INFO "AMD8131 rev %x detected, disabling PCI-X "
+                               "MMRBC\n", revid);
+               dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MMRBC;
+       }
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_mmrbc);
 
 /*
  * FIXME: it is questionable that quirk_via_acpi
@@ -843,10 +855,8 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_CYRIX,      PCI_DEVICE_ID_CYRIX_PCI_MASTER, qu
 static void quirk_disable_pxb(struct pci_dev *pdev)
 {
        u16 config;
-       u8 rev;
        
-       pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
-       if (rev != 0x04)                /* Only C0 requires this */
+       if (pdev->revision != 0x04)             /* Only C0 requires this */
                return;
        pci_read_config_word(pdev, 0x40, &config);
        if (config & (1<<6)) {
index d087e0817715a71a9405415d24f47220552c3533..dbbcc04abd1af1fe06eafc7be1a647d847233e25 100644 (file)
@@ -53,6 +53,49 @@ static void pci_disable_rom(struct pci_dev *pdev)
        pci_write_config_dword(pdev, pdev->rom_base_reg, rom_addr);
 }
 
+/**
+ * pci_get_rom_size - obtain the actual size of the ROM image
+ * @rom: kernel virtual pointer to image of ROM
+ * @size: size of PCI window
+ *  return: size of actual ROM image
+ *
+ * Determine the actual length of the ROM image.
+ * The PCI window size could be much larger than the
+ * actual image size.
+ */
+size_t pci_get_rom_size(void __iomem *rom, size_t size)
+{
+       void __iomem *image;
+       int last_image;
+
+       image = rom;
+       do {
+               void __iomem *pds;
+               /* Standard PCI ROMs start out with these bytes 55 AA */
+               if (readb(image) != 0x55)
+                       break;
+               if (readb(image + 1) != 0xAA)
+                       break;
+               /* get the PCI data structure and check its signature */
+               pds = image + readw(image + 24);
+               if (readb(pds) != 'P')
+                       break;
+               if (readb(pds + 1) != 'C')
+                       break;
+               if (readb(pds + 2) != 'I')
+                       break;
+               if (readb(pds + 3) != 'R')
+                       break;
+               last_image = readb(pds + 21) & 0x80;
+               /* this length is reliable */
+               image += readw(pds + 16) * 512;
+       } while (!last_image);
+
+       /* never return a size larger than the PCI resource window */
+       /* there are known ROMs that get the size wrong */
+       return min((size_t)(image - rom), size);
+}
+
 /**
  * pci_map_rom - map a PCI ROM to kernel space
  * @pdev: pointer to pci device struct
@@ -68,8 +111,6 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
        struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
        loff_t start;
        void __iomem *rom;
-       void __iomem *image;
-       int last_image;
 
        /*
         * IORESOURCE_ROM_SHADOW set on x86, x86_64 and IA64 supports legacy
@@ -117,33 +158,7 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
         * size is much larger than the actual size of the ROM.
         * True size is important if the ROM is going to be copied.
         */
-       image = rom;
-       do {
-               void __iomem *pds;
-               /* Standard PCI ROMs start out with these bytes 55 AA */
-               if (readb(image) != 0x55)
-                       break;
-               if (readb(image + 1) != 0xAA)
-                       break;
-               /* get the PCI data structure and check its signature */
-               pds = image + readw(image + 24);
-               if (readb(pds) != 'P')
-                       break;
-               if (readb(pds + 1) != 'C')
-                       break;
-               if (readb(pds + 2) != 'I')
-                       break;
-               if (readb(pds + 3) != 'R')
-                       break;
-               last_image = readb(pds + 21) & 0x80;
-               /* this length is reliable */
-               image += readw(pds + 16) * 512;
-       } while (!last_image);
-
-       /* never return a size larger than the PCI resource window */
-       /* there are known ROMs that get the size wrong */
-       *size = min((size_t)(image - rom), *size);
-
+       *size = pci_get_rom_size(rom, *size);
        return rom;
 }
 
index c13232435dc06322f824b1f4fd07d34bdce112bb..9f7090fa8771401c954782eec3e052f5e29e7770 100644 (file)
@@ -139,12 +139,14 @@ struct pci_dev * pci_get_slot(struct pci_bus *bus, unsigned int devfn)
 }
 
 /**
- * pci_get_bus_and_slot - locate PCI device from a given PCI slot
+ * pci_get_bus_and_slot - locate PCI device from a given PCI bus & slot
  * @bus: number of PCI bus on which desired PCI device resides
  * @devfn: encodes number of PCI slot in which the desired PCI
  * device resides and the logical device number within that slot
  * in case of multi-function devices.
  *
+ * Note: the bus/slot search is limited to PCI domain (segment) 0.
+ *
  * Given a PCI bus and slot/function number, the desired PCI device
  * is located in system global list of PCI devices.  If the device
  * is found, a pointer to its data structure is returned.  If no
@@ -157,7 +159,8 @@ struct pci_dev * pci_get_bus_and_slot(unsigned int bus, unsigned int devfn)
        struct pci_dev *dev = NULL;
 
        while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
-               if (dev->bus->number == bus && dev->devfn == devfn)
+               if (pci_domain_nr(dev->bus) == 0 &&
+                  (dev->bus->number == bus && dev->devfn == devfn))
                        return dev;
        }
        return NULL;
index 5ec297d7a5b4c236219a1086c0db63db7d508f56..5e5191ec8de65931f916c4659e42cf1758e49409 100644 (file)
@@ -34,8 +34,6 @@
 #define DBG(x...)
 #endif
 
-#define ROUND_UP(x, a)         (((x) + (a) - 1) & ~((a) - 1))
-
 static void pbus_assign_resources_sorted(struct pci_bus *bus)
 {
        struct pci_dev *dev;
@@ -310,7 +308,7 @@ static void pbus_size_io(struct pci_bus *bus)
 #if defined(CONFIG_ISA) || defined(CONFIG_EISA)
        size = (size & 0xff) + ((size & ~0xffUL) << 2);
 #endif
-       size = ROUND_UP(size + size1, 4096);
+       size = ALIGN(size + size1, 4096);
        if (!size) {
                b_res->flags = 0;
                return;
@@ -378,11 +376,11 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long
 
                if (!align)
                        min_align = align1;
-               else if (ROUND_UP(align + min_align, min_align) < align1)
+               else if (ALIGN(align + min_align, min_align) < align1)
                        min_align = align1 >> 1;
                align += aligns[order];
        }
-       size = ROUND_UP(size, min_align);
+       size = ALIGN(size, min_align);
        if (!size) {
                b_res->flags = 0;
                return 1;
index 9d37fec27f24668d1ede8229439b82bb36561b61..2ac050d7f8cffbc12e57384ee96894917236c73e 100644 (file)
@@ -23,14 +23,14 @@ sys_pciconfig_read(unsigned long bus, unsigned long dfn,
        u8 byte;
        u16 word;
        u32 dword;
-       long err, cfg_ret;
+       long err;
+       long cfg_ret;
 
-       err = -EPERM;
        if (!capable(CAP_SYS_ADMIN))
-               goto error;
+               return -EPERM;
 
        err = -ENODEV;
-       dev = pci_find_slot(bus, dfn);
+       dev = pci_get_bus_and_slot(bus, dfn);
        if (!dev)
                goto error;
 
@@ -66,7 +66,8 @@ sys_pciconfig_read(unsigned long bus, unsigned long dfn,
        case 4:
                err = put_user(dword, (unsigned int __user *)buf);
                break;
-       };
+       }
+       pci_dev_put(dev);
        return err;
 
 error:
@@ -83,7 +84,8 @@ error:
        case 4:
                put_user(-1, (unsigned int __user *)buf);
                break;
-       };
+       }
+       pci_dev_put(dev);
        return err;
 }
 
@@ -101,7 +103,7 @@ sys_pciconfig_write(unsigned long bus, unsigned long dfn,
        if (!capable(CAP_SYS_ADMIN))
                return -EPERM;
 
-       dev = pci_find_slot(bus, dfn);
+       dev = pci_get_bus_and_slot(bus, dfn);
        if (!dev)
                return -ENODEV;
 
@@ -137,8 +139,8 @@ sys_pciconfig_write(unsigned long bus, unsigned long dfn,
        default:
                err = -EINVAL;
                break;
-       };
+       }
        unlock_kernel();
-
+       pci_dev_put(dev);
        return err;
 }
index a2bb46526b56cdd8028a49e1394034d501a40807..b4409002b7f8415a88c4a8a823dbcd0ffa96f530 100644 (file)
@@ -283,7 +283,9 @@ static ssize_t pccard_extract_cis(struct pcmcia_socket *s, char *buf, loff_t off
        return (ret);
 }
 
-static ssize_t pccard_show_cis(struct kobject *kobj, char *buf, loff_t off, size_t count)
+static ssize_t pccard_show_cis(struct kobject *kobj,
+                              struct bin_attribute *bin_attr,
+                              char *buf, loff_t off, size_t count)
 {
        unsigned int size = 0x200;
 
@@ -311,7 +313,9 @@ static ssize_t pccard_show_cis(struct kobject *kobj, char *buf, loff_t off, size
        return (count);
 }
 
-static ssize_t pccard_store_cis(struct kobject *kobj, char *buf, loff_t off, size_t count)
+static ssize_t pccard_store_cis(struct kobject *kobj,
+                               struct bin_attribute *bin_attr,
+                               char *buf, loff_t off, size_t count)
 {
        struct pcmcia_socket *s = to_socket(container_of(kobj, struct device, kobj));
        cisdump_t *cis;
@@ -366,7 +370,7 @@ static struct device_attribute *pccard_socket_attributes[] = {
 };
 
 static struct bin_attribute pccard_cis_attr = {
-       .attr = { .name = "cis", .mode = S_IRUGO | S_IWUSR, .owner = THIS_MODULE},
+       .attr = { .name = "cis", .mode = S_IRUGO | S_IWUSR },
        .size = 0x200,
        .read = pccard_show_cis,
        .write = pccard_store_cis,
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
new file mode 100644 (file)
index 0000000..ab9c3e5
--- /dev/null
@@ -0,0 +1,51 @@
+menuconfig POWER_SUPPLY
+       tristate "Power supply class support"
+       help
+         Say Y here to enable power supply class support. This allows
+         power supply (batteries, AC, USB) monitoring by userspace
+         via sysfs and uevent (if available) and/or APM kernel interface
+         (if selected below).
+
+if POWER_SUPPLY
+
+config POWER_SUPPLY_DEBUG
+       bool "Power supply debug"
+       help
+         Say Y here to enable debugging messages for power supply class
+         and drivers.
+
+config PDA_POWER
+       tristate "Generic PDA/phone power driver"
+       help
+         Say Y here to enable generic power driver for PDAs and phones with
+         one or two external power supplies (AC/USB) connected to main and
+         backup batteries, and optional builtin charger.
+
+config APM_POWER
+       tristate "APM emulation for class batteries"
+       depends on APM_EMULATION
+       help
+         Say Y here to enable support APM status emulation using
+         battery class devices.
+
+config BATTERY_DS2760
+       tristate "DS2760 battery driver (HP iPAQ & others)"
+       select W1
+       select W1_SLAVE_DS2760
+       help
+         Say Y here to enable support for batteries with ds2760 chip.
+
+config BATTERY_PMU
+       tristate "Apple PMU battery"
+       depends on ADB_PMU
+       help
+         Say Y here to expose battery information on Apple machines
+         through the generic battery class.
+
+config BATTERY_OLPC
+       tristate "One Laptop Per Child battery"
+       depends on X86_32 && OLPC
+       help
+         Say Y to enable support for the battery on the OLPC laptop.
+
+endif # POWER_SUPPLY
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
new file mode 100644 (file)
index 0000000..6413ded
--- /dev/null
@@ -0,0 +1,22 @@
+power_supply-objs := power_supply_core.o
+
+ifeq ($(CONFIG_SYSFS),y)
+power_supply-objs += power_supply_sysfs.o
+endif
+
+ifeq ($(CONFIG_LEDS_TRIGGERS),y)
+power_supply-objs += power_supply_leds.o
+endif
+
+ifeq ($(CONFIG_POWER_SUPPLY_DEBUG),y)
+EXTRA_CFLAGS += -DDEBUG
+endif
+
+obj-$(CONFIG_POWER_SUPPLY)     += power_supply.o
+
+obj-$(CONFIG_PDA_POWER)                += pda_power.o
+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
diff --git a/drivers/power/apm_power.c b/drivers/power/apm_power.c
new file mode 100644 (file)
index 0000000..042bd95
--- /dev/null
@@ -0,0 +1,243 @@
+/*
+ * Copyright Â© 2007 Anton Vorontsov <cbou@mail.ru>
+ * Copyright Â© 2007 Eugeny Boger <eugenyboger@dgap.mipt.ru>
+ *
+ * Author: Eugeny Boger <eugenyboger@dgap.mipt.ru>
+ *
+ * Use consistent with the GNU GPL is permitted,
+ * provided that this copyright notice is
+ * preserved in its entirety in all copies and derived works.
+ */
+
+#include <linux/module.h>
+#include <linux/power_supply.h>
+#include <linux/apm-emulation.h>
+
+#define PSY_PROP(psy, prop, val) psy->get_property(psy, \
+                        POWER_SUPPLY_PROP_##prop, val)
+
+#define _MPSY_PROP(prop, val) main_battery->get_property(main_battery, \
+                                                        prop, val)
+
+#define MPSY_PROP(prop, val) _MPSY_PROP(POWER_SUPPLY_PROP_##prop, val)
+
+static struct power_supply *main_battery;
+
+static void find_main_battery(void)
+{
+       struct device *dev;
+       struct power_supply *bat, *batm;
+       union power_supply_propval full;
+       int max_charge = 0;
+
+       main_battery = NULL;
+       batm = NULL;
+       list_for_each_entry(dev, &power_supply_class->devices, node) {
+               bat = dev_get_drvdata(dev);
+               /* If none of battery devices cantains 'use_for_apm' flag,
+                  choice one with maximum design charge */
+               if (!PSY_PROP(bat, CHARGE_FULL_DESIGN, &full)) {
+                       if (full.intval > max_charge) {
+                               batm = bat;
+                               max_charge = full.intval;
+                       }
+               }
+
+               if (bat->use_for_apm)
+                       main_battery = bat;
+       }
+       if (!main_battery)
+               main_battery = batm;
+
+       return;
+}
+
+static int calculate_time(int status)
+{
+       union power_supply_propval charge_full, charge_empty;
+       union power_supply_propval charge, I;
+
+       if (MPSY_PROP(CHARGE_FULL, &charge_full)) {
+               /* if battery can't report this property, use design value */
+               if (MPSY_PROP(CHARGE_FULL_DESIGN, &charge_full))
+                       return -1;
+       }
+
+       if (MPSY_PROP(CHARGE_EMPTY, &charge_empty)) {
+               /* if battery can't report this property, use design value */
+               if (MPSY_PROP(CHARGE_EMPTY_DESIGN, &charge_empty))
+                       charge_empty.intval = 0;
+       }
+
+       if (MPSY_PROP(CHARGE_AVG, &charge)) {
+               /* if battery can't report average value, use momentary */
+               if (MPSY_PROP(CHARGE_NOW, &charge))
+                       return -1;
+       }
+
+       if (MPSY_PROP(CURRENT_AVG, &I)) {
+               /* if battery can't report average value, use momentary */
+               if (MPSY_PROP(CURRENT_NOW, &I))
+                       return -1;
+       }
+
+       if (status == POWER_SUPPLY_STATUS_CHARGING)
+               return ((charge.intval - charge_full.intval) * 60L) /
+                      I.intval;
+       else
+               return -((charge.intval - charge_empty.intval) * 60L) /
+                       I.intval;
+}
+
+static int calculate_capacity(int using_charge)
+{
+       enum power_supply_property full_prop, empty_prop;
+       enum power_supply_property full_design_prop, empty_design_prop;
+       enum power_supply_property now_prop, avg_prop;
+       union power_supply_propval empty, full, cur;
+       int ret;
+
+       if (using_charge) {
+               full_prop = POWER_SUPPLY_PROP_CHARGE_FULL;
+               empty_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY;
+               full_design_prop = POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN;
+               empty_design_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN;
+               now_prop = POWER_SUPPLY_PROP_CHARGE_NOW;
+               avg_prop = POWER_SUPPLY_PROP_CHARGE_AVG;
+       } else {
+               full_prop = POWER_SUPPLY_PROP_ENERGY_FULL;
+               empty_prop = POWER_SUPPLY_PROP_ENERGY_EMPTY;
+               full_design_prop = POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN;
+               empty_design_prop = POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN;
+               now_prop = POWER_SUPPLY_PROP_ENERGY_NOW;
+               avg_prop = POWER_SUPPLY_PROP_ENERGY_AVG;
+       }
+
+       if (_MPSY_PROP(full_prop, &full)) {
+               /* if battery can't report this property, use design value */
+               if (_MPSY_PROP(full_design_prop, &full))
+                       return -1;
+       }
+
+       if (_MPSY_PROP(avg_prop, &cur)) {
+               /* if battery can't report average value, use momentary */
+               if (_MPSY_PROP(now_prop, &cur))
+                       return -1;
+       }
+
+       if (_MPSY_PROP(empty_prop, &empty)) {
+               /* if battery can't report this property, use design value */
+               if (_MPSY_PROP(empty_design_prop, &empty))
+                       empty.intval = 0;
+       }
+
+       if (full.intval - empty.intval)
+               ret =  ((cur.intval - empty.intval) * 100L) /
+                      (full.intval - empty.intval);
+       else
+               return -1;
+
+       if (ret > 100)
+               return 100;
+       else if (ret < 0)
+               return 0;
+
+       return ret;
+}
+
+static void apm_battery_apm_get_power_status(struct apm_power_info *info)
+{
+       union power_supply_propval status;
+       union power_supply_propval capacity, time_to_full, time_to_empty;
+
+       down(&power_supply_class->sem);
+       find_main_battery();
+       if (!main_battery) {
+               up(&power_supply_class->sem);
+               return;
+       }
+
+       /* status */
+
+       if (MPSY_PROP(STATUS, &status))
+               status.intval = POWER_SUPPLY_STATUS_UNKNOWN;
+
+       /* ac line status */
+
+       if ((status.intval == POWER_SUPPLY_STATUS_CHARGING) ||
+           (status.intval == POWER_SUPPLY_STATUS_NOT_CHARGING) ||
+           (status.intval == POWER_SUPPLY_STATUS_FULL))
+               info->ac_line_status = APM_AC_ONLINE;
+       else
+               info->ac_line_status = APM_AC_OFFLINE;
+
+       /* battery life (i.e. capacity, in percents) */
+
+       if (MPSY_PROP(CAPACITY, &capacity) == 0) {
+               info->battery_life = capacity.intval;
+       } else {
+               /* try calculate using energy */
+               info->battery_life = calculate_capacity(0);
+               /* if failed try calculate using charge instead */
+               if (info->battery_life == -1)
+                       info->battery_life = calculate_capacity(1);
+       }
+
+       /* charging status */
+
+       if (status.intval == POWER_SUPPLY_STATUS_CHARGING) {
+               info->battery_status = APM_BATTERY_STATUS_CHARGING;
+       } else {
+               if (info->battery_life > 50)
+                       info->battery_status = APM_BATTERY_STATUS_HIGH;
+               else if (info->battery_life > 5)
+                       info->battery_status = APM_BATTERY_STATUS_LOW;
+               else
+                       info->battery_status = APM_BATTERY_STATUS_CRITICAL;
+       }
+       info->battery_flag = info->battery_status;
+
+       /* time */
+
+       info->units = APM_UNITS_MINS;
+
+       if (status.intval == POWER_SUPPLY_STATUS_CHARGING) {
+               if (MPSY_PROP(TIME_TO_FULL_AVG, &time_to_full)) {
+                       if (MPSY_PROP(TIME_TO_FULL_NOW, &time_to_full))
+                               info->time = calculate_time(status.intval);
+                       else
+                               info->time = time_to_full.intval / 60;
+               }
+       } else {
+               if (MPSY_PROP(TIME_TO_EMPTY_AVG, &time_to_empty)) {
+                       if (MPSY_PROP(TIME_TO_EMPTY_NOW, &time_to_empty))
+                               info->time = calculate_time(status.intval);
+                       else
+                               info->time = time_to_empty.intval / 60;
+               }
+       }
+
+       up(&power_supply_class->sem);
+       return;
+}
+
+static int __init apm_battery_init(void)
+{
+       printk(KERN_INFO "APM Battery Driver\n");
+
+       apm_get_power_status = apm_battery_apm_get_power_status;
+       return 0;
+}
+
+static void __exit apm_battery_exit(void)
+{
+       apm_get_power_status = NULL;
+       return;
+}
+
+module_init(apm_battery_init);
+module_exit(apm_battery_exit);
+
+MODULE_AUTHOR("Eugeny Boger <eugenyboger@dgap.mipt.ru>");
+MODULE_DESCRIPTION("APM emulation driver for battery monitoring class");
+MODULE_LICENSE("GPL");
diff --git a/drivers/power/ds2760_battery.c b/drivers/power/ds2760_battery.c
new file mode 100644 (file)
index 0000000..00e1ea6
--- /dev/null
@@ -0,0 +1,470 @@
+/*
+ * Driver for batteries with DS2760 chips inside.
+ *
+ * Copyright Â© 2007 Anton Vorontsov
+ *            2004-2007 Matt Reimer
+ *            2004 Szabolcs Gyurko
+ *
+ * Use consistent with the GNU GPL is permitted,
+ * provided that this copyright notice is
+ * preserved in its entirety in all copies and derived works.
+ *
+ * Author:  Anton Vorontsov <cbou@mail.ru>
+ *         February 2007
+ *
+ *         Matt Reimer <mreimer@vpop.net>
+ *         April 2004, 2005, 2007
+ *
+ *         Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>
+ *         September 2004
+ */
+
+#include <linux/module.h>
+#include <linux/param.h>
+#include <linux/jiffies.h>
+#include <linux/workqueue.h>
+#include <linux/pm.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+
+#include "../w1/w1.h"
+#include "../w1/slaves/w1_ds2760.h"
+
+struct ds2760_device_info {
+       struct device *dev;
+
+       /* DS2760 data, valid after calling ds2760_battery_read_status() */
+       unsigned long update_time;      /* jiffies when data read */
+       char raw[DS2760_DATA_SIZE];     /* raw DS2760 data */
+       int voltage_raw;                /* units of 4.88 mV */
+       int voltage_uV;                 /* units of ÂµV */
+       int current_raw;                /* units of 0.625 mA */
+       int current_uA;                 /* units of ÂµA */
+       int accum_current_raw;          /* units of 0.25 mAh */
+       int accum_current_uAh;          /* units of ÂµAh */
+       int temp_raw;                   /* units of 0.125 Â°C */
+       int temp_C;                     /* units of 0.1 Â°C */
+       int rated_capacity;             /* units of ÂµAh */
+       int rem_capacity;               /* percentage */
+       int full_active_uAh;            /* units of ÂµAh */
+       int empty_uAh;                  /* units of ÂµAh */
+       int life_sec;                   /* units of seconds */
+       int charge_status;              /* POWER_SUPPLY_STATUS_* */
+
+       int full_counter;
+       struct power_supply bat;
+       struct device *w1_dev;
+       struct workqueue_struct *monitor_wqueue;
+       struct delayed_work monitor_work;
+};
+
+static unsigned int cache_time = 1000;
+module_param(cache_time, uint, 0644);
+MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
+
+/* Some batteries have their rated capacity stored a N * 10 mAh, while
+ * others use an index into this table. */
+static int rated_capacities[] = {
+       0,
+       920,    /* Samsung */
+       920,    /* BYD */
+       920,    /* Lishen */
+       920,    /* NEC */
+       1440,   /* Samsung */
+       1440,   /* BYD */
+       1440,   /* Lishen */
+       1440,   /* NEC */
+       2880,   /* Samsung */
+       2880,   /* BYD */
+       2880,   /* Lishen */
+       2880    /* NEC */
+};
+
+/* array is level at temps 0°C, 10°C, 20°C, 30°C, 40°C
+ * temp is in Celsius */
+static int battery_interpolate(int array[], int temp)
+{
+       int index, dt;
+
+       if (temp <= 0)
+               return array[0];
+       if (temp >= 40)
+               return array[4];
+
+       index = temp / 10;
+       dt    = temp % 10;
+
+       return array[index] + (((array[index + 1] - array[index]) * dt) / 10);
+}
+
+static int ds2760_battery_read_status(struct ds2760_device_info *di)
+{
+       int ret, i, start, count, scale[5];
+
+       if (di->update_time && time_before(jiffies, di->update_time +
+                                          msecs_to_jiffies(cache_time)))
+               return 0;
+
+       /* The first time we read the entire contents of SRAM/EEPROM,
+        * but after that we just read the interesting bits that change. */
+       if (di->update_time == 0) {
+               start = 0;
+               count = DS2760_DATA_SIZE;
+       } else {
+               start = DS2760_VOLTAGE_MSB;
+               count = DS2760_TEMP_LSB - start + 1;
+       }
+
+       ret = w1_ds2760_read(di->w1_dev, di->raw + start, start, count);
+       if (ret != count) {
+               dev_warn(di->dev, "call to w1_ds2760_read failed (0x%p)\n",
+                        di->w1_dev);
+               return 1;
+       }
+
+       di->update_time = jiffies;
+
+       /* DS2760 reports voltage in units of 4.88mV, but the battery class
+        * reports in units of uV, so convert by multiplying by 4880. */
+       di->voltage_raw = (di->raw[DS2760_VOLTAGE_MSB] << 3) |
+                         (di->raw[DS2760_VOLTAGE_LSB] >> 5);
+       di->voltage_uV = di->voltage_raw * 4880;
+
+       /* DS2760 reports current in signed units of 0.625mA, but the battery
+        * class reports in units of ÂµA, so convert by multiplying by 625. */
+       di->current_raw =
+           (((signed char)di->raw[DS2760_CURRENT_MSB]) << 5) |
+                         (di->raw[DS2760_CURRENT_LSB] >> 3);
+       di->current_uA = di->current_raw * 625;
+
+       /* DS2760 reports accumulated current in signed units of 0.25mAh. */
+       di->accum_current_raw =
+           (((signed char)di->raw[DS2760_CURRENT_ACCUM_MSB]) << 8) |
+                          di->raw[DS2760_CURRENT_ACCUM_LSB];
+       di->accum_current_uAh = di->accum_current_raw * 250;
+
+       /* DS2760 reports temperature in signed units of 0.125°C, but the
+        * battery class reports in units of 1/10 Â°C, so we convert by
+        * multiplying by .125 * 10 = 1.25. */
+       di->temp_raw = (((signed char)di->raw[DS2760_TEMP_MSB]) << 3) |
+                                    (di->raw[DS2760_TEMP_LSB] >> 5);
+       di->temp_C = di->temp_raw + (di->temp_raw / 4);
+
+       /* At least some battery monitors (e.g. HP iPAQ) store the battery's
+        * maximum rated capacity. */
+       if (di->raw[DS2760_RATED_CAPACITY] < ARRAY_SIZE(rated_capacities))
+               di->rated_capacity = rated_capacities[
+                       (unsigned int)di->raw[DS2760_RATED_CAPACITY]];
+       else
+               di->rated_capacity = di->raw[DS2760_RATED_CAPACITY] * 10;
+
+       di->rated_capacity *= 1000; /* convert to ÂµAh */
+
+       /* Calculate the full level at the present temperature. */
+       di->full_active_uAh = di->raw[DS2760_ACTIVE_FULL] << 8 |
+                             di->raw[DS2760_ACTIVE_FULL + 1];
+
+       scale[0] = di->raw[DS2760_ACTIVE_FULL] << 8 |
+                  di->raw[DS2760_ACTIVE_FULL + 1];
+       for (i = 1; i < 5; i++)
+               scale[i] = scale[i - 1] + di->raw[DS2760_ACTIVE_FULL + 2 + i];
+
+       di->full_active_uAh = battery_interpolate(scale, di->temp_C / 10);
+       di->full_active_uAh *= 1000; /* convert to ÂµAh */
+
+       /* Calculate the empty level at the present temperature. */
+       scale[4] = di->raw[DS2760_ACTIVE_EMPTY + 4];
+       for (i = 3; i >= 0; i--)
+               scale[i] = scale[i + 1] + di->raw[DS2760_ACTIVE_EMPTY + i];
+
+       di->empty_uAh = battery_interpolate(scale, di->temp_C / 10);
+       di->empty_uAh *= 1000; /* convert to ÂµAh */
+
+       /* From Maxim Application Note 131: remaining capacity =
+        * ((ICA - Empty Value) / (Full Value - Empty Value)) x 100% */
+       di->rem_capacity = ((di->accum_current_uAh - di->empty_uAh) * 100L) /
+                           (di->full_active_uAh - di->empty_uAh);
+
+       if (di->rem_capacity < 0)
+               di->rem_capacity = 0;
+       if (di->rem_capacity > 100)
+               di->rem_capacity = 100;
+
+       if (di->current_uA)
+               di->life_sec = -((di->accum_current_uAh - di->empty_uAh) *
+                                3600L) / di->current_uA;
+       else
+               di->life_sec = 0;
+
+       return 0;
+}
+
+static void ds2760_battery_update_status(struct ds2760_device_info *di)
+{
+       int old_charge_status = di->charge_status;
+
+       ds2760_battery_read_status(di);
+
+       if (di->charge_status == POWER_SUPPLY_STATUS_UNKNOWN)
+               di->full_counter = 0;
+
+       if (power_supply_am_i_supplied(&di->bat)) {
+               if (di->current_uA > 10000) {
+                       di->charge_status = POWER_SUPPLY_STATUS_CHARGING;
+                       di->full_counter = 0;
+               } else if (di->current_uA < -5000) {
+                       if (di->charge_status != POWER_SUPPLY_STATUS_NOT_CHARGING)
+                               dev_notice(di->dev, "not enough power to "
+                                          "charge\n");
+                       di->charge_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
+                       di->full_counter = 0;
+               } else if (di->current_uA < 10000 &&
+                           di->charge_status != POWER_SUPPLY_STATUS_FULL) {
+
+                       /* Don't consider the battery to be full unless
+                        * we've seen the current < 10 mA at least two
+                        * consecutive times. */
+
+                       di->full_counter++;
+
+                       if (di->full_counter < 2) {
+                               di->charge_status = POWER_SUPPLY_STATUS_CHARGING;
+                       } else {
+                               unsigned char acr[2];
+                               int acr_val;
+
+                               /* acr is in units of 0.25 mAh */
+                               acr_val = di->full_active_uAh * 4L / 1000;
+
+                               acr[0] = acr_val >> 8;
+                               acr[1] = acr_val & 0xff;
+
+                               if (w1_ds2760_write(di->w1_dev, acr,
+                                   DS2760_CURRENT_ACCUM_MSB, 2) < 2)
+                                       dev_warn(di->dev,
+                                                "ACR reset failed\n");
+
+                               di->charge_status = POWER_SUPPLY_STATUS_FULL;
+                       }
+               }
+       } else {
+               di->charge_status = POWER_SUPPLY_STATUS_DISCHARGING;
+               di->full_counter = 0;
+       }
+
+       if (di->charge_status != old_charge_status)
+               power_supply_changed(&di->bat);
+
+       return;
+}
+
+static void ds2760_battery_work(struct work_struct *work)
+{
+       struct ds2760_device_info *di = container_of(work,
+               struct ds2760_device_info, monitor_work.work);
+       const int interval = HZ * 60;
+
+       dev_dbg(di->dev, "%s\n", __FUNCTION__);
+
+       ds2760_battery_update_status(di);
+       queue_delayed_work(di->monitor_wqueue, &di->monitor_work, interval);
+
+       return;
+}
+
+#define to_ds2760_device_info(x) container_of((x), struct ds2760_device_info, \
+                                             bat);
+
+static void ds2760_battery_external_power_changed(struct power_supply *psy)
+{
+       struct ds2760_device_info *di = to_ds2760_device_info(psy);
+
+       dev_dbg(di->dev, "%s\n", __FUNCTION__);
+
+       cancel_delayed_work(&di->monitor_work);
+       queue_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ/10);
+
+       return;
+}
+
+static int ds2760_battery_get_property(struct power_supply *psy,
+                                      enum power_supply_property psp,
+                                      union power_supply_propval *val)
+{
+       struct ds2760_device_info *di = to_ds2760_device_info(psy);
+
+       switch (psp) {
+       case POWER_SUPPLY_PROP_STATUS:
+               val->intval = di->charge_status;
+               return 0;
+       default:
+               break;
+       }
+
+       ds2760_battery_read_status(di);
+
+       switch (psp) {
+       case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+               val->intval = di->voltage_uV;
+               break;
+       case POWER_SUPPLY_PROP_CURRENT_NOW:
+               val->intval = di->current_uA;
+               break;
+       case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
+               val->intval = di->rated_capacity;
+               break;
+       case POWER_SUPPLY_PROP_CHARGE_FULL:
+               val->intval = di->full_active_uAh;
+               break;
+       case POWER_SUPPLY_PROP_CHARGE_EMPTY:
+               val->intval = di->empty_uAh;
+               break;
+       case POWER_SUPPLY_PROP_CHARGE_NOW:
+               val->intval = di->accum_current_uAh;
+               break;
+       case POWER_SUPPLY_PROP_TEMP:
+               val->intval = di->temp_C;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static enum power_supply_property ds2760_battery_props[] = {
+       POWER_SUPPLY_PROP_STATUS,
+       POWER_SUPPLY_PROP_VOLTAGE_NOW,
+       POWER_SUPPLY_PROP_CURRENT_NOW,
+       POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
+       POWER_SUPPLY_PROP_CHARGE_FULL,
+       POWER_SUPPLY_PROP_CHARGE_EMPTY,
+       POWER_SUPPLY_PROP_CHARGE_NOW,
+       POWER_SUPPLY_PROP_TEMP,
+};
+
+static int ds2760_battery_probe(struct platform_device *pdev)
+{
+       int retval = 0;
+       struct ds2760_device_info *di;
+       struct ds2760_platform_data *pdata;
+
+       di = kzalloc(sizeof(*di), GFP_KERNEL);
+       if (!di) {
+               retval = -ENOMEM;
+               goto di_alloc_failed;
+       }
+
+       platform_set_drvdata(pdev, di);
+
+       pdata = pdev->dev.platform_data;
+       di->dev         = &pdev->dev;
+       di->w1_dev           = pdev->dev.parent;
+       di->bat.name       = pdev->dev.bus_id;
+       di->bat.type       = POWER_SUPPLY_TYPE_BATTERY;
+       di->bat.properties     = ds2760_battery_props;
+       di->bat.num_properties = ARRAY_SIZE(ds2760_battery_props);
+       di->bat.get_property   = ds2760_battery_get_property;
+       di->bat.external_power_changed =
+                                 ds2760_battery_external_power_changed;
+
+       di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN;
+
+       retval = power_supply_register(&pdev->dev, &di->bat);
+       if (retval) {
+               dev_err(di->dev, "failed to register battery");
+               goto batt_failed;
+       }
+
+       INIT_DELAYED_WORK(&di->monitor_work, ds2760_battery_work);
+       di->monitor_wqueue = create_singlethread_workqueue(pdev->dev.bus_id);
+       if (!di->monitor_wqueue) {
+               retval = -ESRCH;
+               goto workqueue_failed;
+       }
+       queue_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ * 1);
+
+       goto success;
+
+workqueue_failed:
+       power_supply_unregister(&di->bat);
+batt_failed:
+       kfree(di);
+di_alloc_failed:
+success:
+       return retval;
+}
+
+static int ds2760_battery_remove(struct platform_device *pdev)
+{
+       struct ds2760_device_info *di = platform_get_drvdata(pdev);
+
+       cancel_rearming_delayed_workqueue(di->monitor_wqueue,
+                                         &di->monitor_work);
+       destroy_workqueue(di->monitor_wqueue);
+       power_supply_unregister(&di->bat);
+
+       return 0;
+}
+
+#ifdef CONFIG_PM
+
+static int ds2760_battery_suspend(struct platform_device *pdev,
+                                 pm_message_t state)
+{
+       struct ds2760_device_info *di = platform_get_drvdata(pdev);
+
+       di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN;
+
+       return 0;
+}
+
+static int ds2760_battery_resume(struct platform_device *pdev)
+{
+       struct ds2760_device_info *di = platform_get_drvdata(pdev);
+
+       di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN;
+       power_supply_changed(&di->bat);
+
+       cancel_delayed_work(&di->monitor_work);
+       queue_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ);
+
+       return 0;
+}
+
+#else
+
+#define ds2760_battery_suspend NULL
+#define ds2760_battery_resume NULL
+
+#endif /* CONFIG_PM */
+
+static struct platform_driver ds2760_battery_driver = {
+       .driver = {
+               .name = "ds2760-battery",
+       },
+       .probe    = ds2760_battery_probe,
+       .remove   = ds2760_battery_remove,
+       .suspend  = ds2760_battery_suspend,
+       .resume   = ds2760_battery_resume,
+};
+
+static int __init ds2760_battery_init(void)
+{
+       return platform_driver_register(&ds2760_battery_driver);
+}
+
+static void __exit ds2760_battery_exit(void)
+{
+       platform_driver_unregister(&ds2760_battery_driver);
+       return;
+}
+
+module_init(ds2760_battery_init);
+module_exit(ds2760_battery_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>, "
+             "Matt Reimer <mreimer@vpop.net>, "
+             "Anton Vorontsov <cbou@mail.ru>");
+MODULE_DESCRIPTION("ds2760 battery driver");
diff --git a/drivers/power/olpc_battery.c b/drivers/power/olpc_battery.c
new file mode 100644 (file)
index 0000000..878684d
--- /dev/null
@@ -0,0 +1,352 @@
+/*
+ * Battery driver for One Laptop Per Child board.
+ *
+ *     Copyright Â© 2006  David Woodhouse <dwmw2@infradead.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+#include <linux/jiffies.h>
+#include <linux/sched.h>
+#include <asm/olpc.h>
+
+
+#define EC_BAT_VOLTAGE 0x10    /* uint16_t,    *9.76/32,    mV   */
+#define EC_BAT_CURRENT 0x11    /* int16_t,     *15.625/120, mA   */
+#define EC_BAT_ACR     0x12
+#define EC_BAT_TEMP    0x13    /* uint16_t,    *100/256,   Â°C  */
+#define EC_AMB_TEMP    0x14    /* uint16_t,    *100/256,   Â°C  */
+#define EC_BAT_STATUS  0x15    /* uint8_t,     bitmask */
+#define EC_BAT_SOC     0x16    /* uint8_t,     percentage */
+#define EC_BAT_SERIAL  0x17    /* uint8_t[6] */
+#define EC_BAT_EEPROM  0x18    /* uint8_t adr as input, uint8_t output */
+#define EC_BAT_ERRCODE 0x1f    /* uint8_t,     bitmask */
+
+#define BAT_STAT_PRESENT       0x01
+#define BAT_STAT_FULL          0x02
+#define BAT_STAT_LOW           0x04
+#define BAT_STAT_DESTROY       0x08
+#define BAT_STAT_AC            0x10
+#define BAT_STAT_CHARGING      0x20
+#define BAT_STAT_DISCHARGING   0x40
+
+#define BAT_ERR_INFOFAIL       0x02
+#define BAT_ERR_OVERVOLTAGE    0x04
+#define BAT_ERR_OVERTEMP       0x05
+#define BAT_ERR_GAUGESTOP      0x06
+#define BAT_ERR_OUT_OF_CONTROL 0x07
+#define BAT_ERR_ID_FAIL                0x09
+#define BAT_ERR_ACR_FAIL       0x10
+
+#define BAT_ADDR_MFR_TYPE      0x5F
+
+/*********************************************************************
+ *             Power
+ *********************************************************************/
+
+static int olpc_ac_get_prop(struct power_supply *psy,
+                           enum power_supply_property psp,
+                           union power_supply_propval *val)
+{
+       int ret = 0;
+       uint8_t status;
+
+       switch (psp) {
+       case POWER_SUPPLY_PROP_ONLINE:
+               ret = olpc_ec_cmd(EC_BAT_STATUS, NULL, 0, &status, 1);
+               if (ret)
+                       return ret;
+
+               val->intval = !!(status & BAT_STAT_AC);
+               break;
+       default:
+               ret = -EINVAL;
+               break;
+       }
+       return ret;
+}
+
+static enum power_supply_property olpc_ac_props[] = {
+       POWER_SUPPLY_PROP_ONLINE,
+};
+
+static struct power_supply olpc_ac = {
+       .name = "olpc-ac",
+       .type = POWER_SUPPLY_TYPE_MAINS,
+       .properties = olpc_ac_props,
+       .num_properties = ARRAY_SIZE(olpc_ac_props),
+       .get_property = olpc_ac_get_prop,
+};
+
+/*********************************************************************
+ *             Battery properties
+ *********************************************************************/
+static int olpc_bat_get_property(struct power_supply *psy,
+                                enum power_supply_property psp,
+                                union power_supply_propval *val)
+{
+       int ret = 0;
+       int16_t ec_word;
+       uint8_t ec_byte;
+
+       ret = olpc_ec_cmd(EC_BAT_STATUS, NULL, 0, &ec_byte, 1);
+       if (ret)
+               return ret;
+
+       /* Theoretically there's a race here -- the battery could be
+          removed immediately after we check whether it's present, and
+          then we query for some other property of the now-absent battery.
+          It doesn't matter though -- the EC will return the last-known
+          information, and it's as if we just ran that _little_ bit faster
+          and managed to read it out before the battery went away. */
+       if (!(ec_byte & BAT_STAT_PRESENT) && psp != POWER_SUPPLY_PROP_PRESENT)
+               return -ENODEV;
+
+       switch (psp) {
+       case POWER_SUPPLY_PROP_STATUS:
+               if (olpc_platform_info.ecver > 0x44) {
+                       if (ec_byte & BAT_STAT_CHARGING)
+                               val->intval = POWER_SUPPLY_STATUS_CHARGING;
+                       else if (ec_byte & BAT_STAT_DISCHARGING)
+                               val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+                       else if (ec_byte & BAT_STAT_FULL)
+                               val->intval = POWER_SUPPLY_STATUS_FULL;
+                       else /* er,... */
+                               val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
+               } else {
+                       /* Older EC didn't report charge/discharge bits */
+                       if (!(ec_byte & BAT_STAT_AC)) /* No AC means discharging */
+                               val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+                       else if (ec_byte & BAT_STAT_FULL)
+                               val->intval = POWER_SUPPLY_STATUS_FULL;
+                       else /* Not _necessarily_ true but EC doesn't tell all yet */
+                               val->intval = POWER_SUPPLY_STATUS_CHARGING;
+                       break;
+               }
+       case POWER_SUPPLY_PROP_PRESENT:
+               val->intval = !!(ec_byte & BAT_STAT_PRESENT);
+               break;
+
+       case POWER_SUPPLY_PROP_HEALTH:
+               if (ec_byte & BAT_STAT_DESTROY)
+                       val->intval = POWER_SUPPLY_HEALTH_DEAD;
+               else {
+                       ret = olpc_ec_cmd(EC_BAT_ERRCODE, NULL, 0, &ec_byte, 1);
+                       if (ret)
+                               return ret;
+
+                       switch (ec_byte) {
+                       case 0:
+                               val->intval = POWER_SUPPLY_HEALTH_GOOD;
+                               break;
+
+                       case BAT_ERR_OVERTEMP:
+                               val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
+                               break;
+
+                       case BAT_ERR_OVERVOLTAGE:
+                               val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
+                               break;
+
+                       case BAT_ERR_INFOFAIL:
+                       case BAT_ERR_OUT_OF_CONTROL:
+                       case BAT_ERR_ID_FAIL:
+                       case BAT_ERR_ACR_FAIL:
+                               val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
+                               break;
+
+                       default:
+                               /* Eep. We don't know this failure code */
+                               return -EIO;
+                       }
+               }
+               break;
+
+       case POWER_SUPPLY_PROP_MANUFACTURER:
+               ec_byte = BAT_ADDR_MFR_TYPE;
+               ret = olpc_ec_cmd(EC_BAT_EEPROM, &ec_byte, 1, &ec_byte, 1);
+               if (ret)
+                       return ret;
+
+               switch (ec_byte >> 4) {
+               case 1:
+                       val->strval = "Gold Peak";
+                       break;
+               case 2:
+                       val->strval = "BYD";
+                       break;
+               default:
+                       val->strval = "Unknown";
+                       break;
+               }
+               break;
+       case POWER_SUPPLY_PROP_TECHNOLOGY:
+               ec_byte = BAT_ADDR_MFR_TYPE;
+               ret = olpc_ec_cmd(EC_BAT_EEPROM, &ec_byte, 1, &ec_byte, 1);
+               if (ret)
+                       return ret;
+
+               switch (ec_byte & 0xf) {
+               case 1:
+                       val->intval = POWER_SUPPLY_TECHNOLOGY_NiMH;
+                       break;
+               case 2:
+                       val->intval = POWER_SUPPLY_TECHNOLOGY_LiFe;
+                       break;
+               default:
+                       val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
+                       break;
+               }
+               break;
+       case POWER_SUPPLY_PROP_VOLTAGE_AVG:
+               ret = olpc_ec_cmd(EC_BAT_VOLTAGE, NULL, 0, (void *)&ec_word, 2);
+               if (ret)
+                       return ret;
+
+               ec_word = be16_to_cpu(ec_word);
+               val->intval = ec_word * 9760L / 32;
+               break;
+       case POWER_SUPPLY_PROP_CURRENT_AVG:
+               ret = olpc_ec_cmd(EC_BAT_CURRENT, NULL, 0, (void *)&ec_word, 2);
+               if (ret)
+                       return ret;
+
+               ec_word = be16_to_cpu(ec_word);
+               val->intval = ec_word * 15625L / 120;
+               break;
+       case POWER_SUPPLY_PROP_CAPACITY:
+               ret = olpc_ec_cmd(EC_BAT_SOC, NULL, 0, &ec_byte, 1);
+               if (ret)
+                       return ret;
+               val->intval = ec_byte;
+               break;
+       case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
+               if (ec_byte & BAT_STAT_FULL)
+                       val->intval = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
+               else if (ec_byte & BAT_STAT_LOW)
+                       val->intval = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
+               else
+                       val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
+               break;
+       case POWER_SUPPLY_PROP_TEMP:
+               ret = olpc_ec_cmd(EC_BAT_TEMP, NULL, 0, (void *)&ec_word, 2);
+               if (ret)
+                       return ret;
+               ec_word = be16_to_cpu(ec_word);
+               val->intval = ec_word * 100 / 256;
+               break;
+       case POWER_SUPPLY_PROP_TEMP_AMBIENT:
+               ret = olpc_ec_cmd(EC_AMB_TEMP, NULL, 0, (void *)&ec_word, 2);
+               if (ret)
+                       return ret;
+
+               ec_word = be16_to_cpu(ec_word);
+               val->intval = ec_word * 100 / 256;
+               break;
+       default:
+               ret = -EINVAL;
+               break;
+       }
+
+       return ret;
+}
+
+static enum power_supply_property olpc_bat_props[] = {
+       POWER_SUPPLY_PROP_STATUS,
+       POWER_SUPPLY_PROP_PRESENT,
+       POWER_SUPPLY_PROP_HEALTH,
+       POWER_SUPPLY_PROP_TECHNOLOGY,
+       POWER_SUPPLY_PROP_VOLTAGE_AVG,
+       POWER_SUPPLY_PROP_CURRENT_AVG,
+       POWER_SUPPLY_PROP_CAPACITY,
+       POWER_SUPPLY_PROP_CAPACITY_LEVEL,
+       POWER_SUPPLY_PROP_TEMP,
+       POWER_SUPPLY_PROP_TEMP_AMBIENT,
+       POWER_SUPPLY_PROP_MANUFACTURER,
+};
+
+/*********************************************************************
+ *             Initialisation
+ *********************************************************************/
+
+static struct platform_device *bat_pdev;
+
+static struct power_supply olpc_bat = {
+       .properties = olpc_bat_props,
+       .num_properties = ARRAY_SIZE(olpc_bat_props),
+       .get_property = olpc_bat_get_property,
+       .use_for_apm = 1,
+};
+
+void olpc_battery_trigger_uevent(unsigned long cause)
+{
+       if (cause & EC_SCI_SRC_ACPWR)
+               kobject_uevent(&olpc_ac.dev->kobj, KOBJ_CHANGE);
+       if (cause & (EC_SCI_SRC_BATERR|EC_SCI_SRC_BATSOC|EC_SCI_SRC_BATTERY))
+               kobject_uevent(&olpc_bat.dev->kobj, KOBJ_CHANGE);
+}
+
+static int __init olpc_bat_init(void)
+{
+       int ret = 0;
+       uint8_t status;
+
+       if (!olpc_platform_info.ecver)
+               return -ENXIO;
+       if (olpc_platform_info.ecver < 0x43) {
+               printk(KERN_NOTICE "OLPC EC version 0x%02x too old for battery driver.\n", olpc_platform_info.ecver);
+               return -ENXIO;
+       }
+
+       ret = olpc_ec_cmd(EC_BAT_STATUS, NULL, 0, &status, 1);
+       if (ret)
+               return ret;
+
+       /* Ignore the status. It doesn't actually matter */
+
+       bat_pdev = platform_device_register_simple("olpc-battery", 0, NULL, 0);
+       if (IS_ERR(bat_pdev))
+               return PTR_ERR(bat_pdev);
+
+       ret = power_supply_register(&bat_pdev->dev, &olpc_ac);
+       if (ret)
+               goto ac_failed;
+
+       olpc_bat.name = bat_pdev->name;
+
+       ret = power_supply_register(&bat_pdev->dev, &olpc_bat);
+       if (ret)
+               goto battery_failed;
+
+       olpc_register_battery_callback(&olpc_battery_trigger_uevent);
+       goto success;
+
+battery_failed:
+       power_supply_unregister(&olpc_ac);
+ac_failed:
+       platform_device_unregister(bat_pdev);
+success:
+       return ret;
+}
+
+static void __exit olpc_bat_exit(void)
+{
+       olpc_deregister_battery_callback();
+       power_supply_unregister(&olpc_bat);
+       power_supply_unregister(&olpc_ac);
+       platform_device_unregister(bat_pdev);
+       return;
+}
+
+module_init(olpc_bat_init);
+module_exit(olpc_bat_exit);
+
+MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Battery driver for One Laptop Per Child 'XO' machine");
diff --git a/drivers/power/pda_power.c b/drivers/power/pda_power.c
new file mode 100644 (file)
index 0000000..4e1eb04
--- /dev/null
@@ -0,0 +1,261 @@
+/*
+ * Common power driver for PDAs and phones with one or two external
+ * power supplies (AC/USB) connected to main and backup batteries,
+ * and optional builtin charger.
+ *
+ * Copyright Â© 2007 Anton Vorontsov <cbou@mail.ru>
+ *
+ * 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 <linux/interrupt.h>
+#include <linux/power_supply.h>
+#include <linux/pda_power.h>
+#include <linux/timer.h>
+#include <linux/jiffies.h>
+
+static inline unsigned int get_irq_flags(struct resource *res)
+{
+       unsigned int flags = IRQF_DISABLED | IRQF_SHARED;
+
+       flags |= res->flags & IRQF_TRIGGER_MASK;
+
+       return flags;
+}
+
+static struct device *dev;
+static struct pda_power_pdata *pdata;
+static struct resource *ac_irq, *usb_irq;
+static struct timer_list charger_timer;
+static struct timer_list supply_timer;
+
+static int pda_power_get_property(struct power_supply *psy,
+                                 enum power_supply_property psp,
+                                 union power_supply_propval *val)
+{
+       switch (psp) {
+       case POWER_SUPPLY_PROP_ONLINE:
+               if (psy->type == POWER_SUPPLY_TYPE_MAINS)
+                       val->intval = pdata->is_ac_online ?
+                                     pdata->is_ac_online() : 0;
+               else
+                       val->intval = pdata->is_usb_online ?
+                                     pdata->is_usb_online() : 0;
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static enum power_supply_property pda_power_props[] = {
+       POWER_SUPPLY_PROP_ONLINE,
+};
+
+static char *pda_power_supplied_to[] = {
+       "main-battery",
+       "backup-battery",
+};
+
+static struct power_supply pda_power_supplies[] = {
+       {
+               .name = "ac",
+               .type = POWER_SUPPLY_TYPE_MAINS,
+               .supplied_to = pda_power_supplied_to,
+               .num_supplicants = ARRAY_SIZE(pda_power_supplied_to),
+               .properties = pda_power_props,
+               .num_properties = ARRAY_SIZE(pda_power_props),
+               .get_property = pda_power_get_property,
+       },
+       {
+               .name = "usb",
+               .type = POWER_SUPPLY_TYPE_USB,
+               .supplied_to = pda_power_supplied_to,
+               .num_supplicants = ARRAY_SIZE(pda_power_supplied_to),
+               .properties = pda_power_props,
+               .num_properties = ARRAY_SIZE(pda_power_props),
+               .get_property = pda_power_get_property,
+       },
+};
+
+static void update_charger(void)
+{
+       if (!pdata->set_charge)
+               return;
+
+       if (pdata->is_ac_online && pdata->is_ac_online()) {
+               dev_dbg(dev, "charger on (AC)\n");
+               pdata->set_charge(PDA_POWER_CHARGE_AC);
+       } else if (pdata->is_usb_online && pdata->is_usb_online()) {
+               dev_dbg(dev, "charger on (USB)\n");
+               pdata->set_charge(PDA_POWER_CHARGE_USB);
+       } else {
+               dev_dbg(dev, "charger off\n");
+               pdata->set_charge(0);
+       }
+
+       return;
+}
+
+static void supply_timer_func(unsigned long irq)
+{
+       if (ac_irq && irq == ac_irq->start)
+               power_supply_changed(&pda_power_supplies[0]);
+       else if (usb_irq && irq == usb_irq->start)
+               power_supply_changed(&pda_power_supplies[1]);
+       return;
+}
+
+static void charger_timer_func(unsigned long irq)
+{
+       update_charger();
+
+       /* Okay, charger set. Now wait a bit before notifying supplicants,
+        * charge power should stabilize. */
+       supply_timer.data = irq;
+       mod_timer(&supply_timer,
+                 jiffies + msecs_to_jiffies(pdata->wait_for_charger));
+       return;
+}
+
+static irqreturn_t power_changed_isr(int irq, void *unused)
+{
+       /* Wait a bit before reading ac/usb line status and setting charger,
+        * because ac/usb status readings may lag from irq. */
+       charger_timer.data = irq;
+       mod_timer(&charger_timer,
+                 jiffies + msecs_to_jiffies(pdata->wait_for_status));
+       return IRQ_HANDLED;
+}
+
+static int pda_power_probe(struct platform_device *pdev)
+{
+       int ret = 0;
+
+       dev = &pdev->dev;
+
+       if (pdev->id != -1) {
+               dev_err(dev, "it's meaningless to register several "
+                       "pda_powers; use id = -1\n");
+               ret = -EINVAL;
+               goto wrongid;
+       }
+
+       pdata = pdev->dev.platform_data;
+
+       update_charger();
+
+       if (!pdata->wait_for_status)
+               pdata->wait_for_status = 500;
+
+       if (!pdata->wait_for_charger)
+               pdata->wait_for_charger = 500;
+
+       setup_timer(&charger_timer, charger_timer_func, 0);
+       setup_timer(&supply_timer, supply_timer_func, 0);
+
+       ac_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ac");
+       usb_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "usb");
+       if (!ac_irq && !usb_irq) {
+               dev_err(dev, "no ac/usb irq specified\n");
+               ret = -ENODEV;
+               goto noirqs;
+       }
+
+       if (pdata->supplied_to) {
+               pda_power_supplies[0].supplied_to = pdata->supplied_to;
+               pda_power_supplies[1].supplied_to = pdata->supplied_to;
+               pda_power_supplies[0].num_supplicants = pdata->num_supplicants;
+               pda_power_supplies[1].num_supplicants = pdata->num_supplicants;
+       }
+
+       ret = power_supply_register(&pdev->dev, &pda_power_supplies[0]);
+       if (ret) {
+               dev_err(dev, "failed to register %s power supply\n",
+                       pda_power_supplies[0].name);
+               goto supply0_failed;
+       }
+
+       ret = power_supply_register(&pdev->dev, &pda_power_supplies[1]);
+       if (ret) {
+               dev_err(dev, "failed to register %s power supply\n",
+                       pda_power_supplies[1].name);
+               goto supply1_failed;
+       }
+
+       if (ac_irq) {
+               ret = request_irq(ac_irq->start, power_changed_isr,
+                                 get_irq_flags(ac_irq), ac_irq->name,
+                                 &pda_power_supplies[0]);
+               if (ret) {
+                       dev_err(dev, "request ac irq failed\n");
+                       goto ac_irq_failed;
+               }
+       }
+
+       if (usb_irq) {
+               ret = request_irq(usb_irq->start, power_changed_isr,
+                                 get_irq_flags(usb_irq), usb_irq->name,
+                                 &pda_power_supplies[1]);
+               if (ret) {
+                       dev_err(dev, "request usb irq failed\n");
+                       goto usb_irq_failed;
+               }
+       }
+
+       goto success;
+
+usb_irq_failed:
+       if (ac_irq)
+               free_irq(ac_irq->start, &pda_power_supplies[0]);
+ac_irq_failed:
+       power_supply_unregister(&pda_power_supplies[1]);
+supply1_failed:
+       power_supply_unregister(&pda_power_supplies[0]);
+supply0_failed:
+noirqs:
+wrongid:
+success:
+       return ret;
+}
+
+static int pda_power_remove(struct platform_device *pdev)
+{
+       if (usb_irq)
+               free_irq(usb_irq->start, &pda_power_supplies[1]);
+       if (ac_irq)
+               free_irq(ac_irq->start, &pda_power_supplies[0]);
+       del_timer_sync(&charger_timer);
+       del_timer_sync(&supply_timer);
+       power_supply_unregister(&pda_power_supplies[1]);
+       power_supply_unregister(&pda_power_supplies[0]);
+       return 0;
+}
+
+static struct platform_driver pda_power_pdrv = {
+       .driver = {
+               .name = "pda-power",
+       },
+       .probe = pda_power_probe,
+       .remove = pda_power_remove,
+};
+
+static int __init pda_power_init(void)
+{
+       return platform_driver_register(&pda_power_pdrv);
+}
+
+static void __exit pda_power_exit(void)
+{
+       platform_driver_unregister(&pda_power_pdrv);
+       return;
+}
+
+module_init(pda_power_init);
+module_exit(pda_power_exit);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Anton Vorontsov <cbou@mail.ru>");
diff --git a/drivers/power/pmu_battery.c b/drivers/power/pmu_battery.c
new file mode 100644 (file)
index 0000000..2fea4af
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+ * Battery class driver for Apple PMU
+ *
+ *     Copyright Â© 2006  David Woodhouse <dwmw2@infradead.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/power_supply.h>
+#include <linux/adb.h>
+#include <linux/pmu.h>
+
+static struct pmu_battery_dev {
+       struct power_supply bat;
+       struct pmu_battery_info *pbi;
+       char name[16];
+       int propval;
+} *pbats[PMU_MAX_BATTERIES];
+
+#define to_pmu_battery_dev(x) container_of(x, struct pmu_battery_dev, bat)
+
+/*********************************************************************
+ *             Power
+ *********************************************************************/
+
+static int pmu_get_ac_prop(struct power_supply *psy,
+                          enum power_supply_property psp,
+                          union power_supply_propval *val)
+{
+       switch (psp) {
+       case POWER_SUPPLY_PROP_ONLINE:
+               val->intval = (!!(pmu_power_flags & PMU_PWR_AC_PRESENT)) ||
+                             (pmu_battery_count == 0);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static enum power_supply_property pmu_ac_props[] = {
+       POWER_SUPPLY_PROP_ONLINE,
+};
+
+static struct power_supply pmu_ac = {
+       .name = "pmu-ac",
+       .type = POWER_SUPPLY_TYPE_MAINS,
+       .properties = pmu_ac_props,
+       .num_properties = ARRAY_SIZE(pmu_ac_props),
+       .get_property = pmu_get_ac_prop,
+};
+
+/*********************************************************************
+ *             Battery properties
+ *********************************************************************/
+
+static char *pmu_batt_types[] = {
+       "Smart", "Comet", "Hooper", "Unknown"
+};
+
+static char *pmu_bat_get_model_name(struct pmu_battery_info *pbi)
+{
+       switch (pbi->flags & PMU_BATT_TYPE_MASK) {
+       case PMU_BATT_TYPE_SMART:
+               return pmu_batt_types[0];
+       case PMU_BATT_TYPE_COMET:
+               return pmu_batt_types[1];
+       case PMU_BATT_TYPE_HOOPER:
+               return pmu_batt_types[2];
+       default: break;
+       }
+       return pmu_batt_types[3];
+}
+
+static int pmu_bat_get_property(struct power_supply *psy,
+                               enum power_supply_property psp,
+                               union power_supply_propval *val)
+{
+       struct pmu_battery_dev *pbat = to_pmu_battery_dev(psy);
+       struct pmu_battery_info *pbi = pbat->pbi;
+
+       switch (psp) {
+       case POWER_SUPPLY_PROP_STATUS:
+               if (pbi->flags & PMU_BATT_CHARGING)
+                       val->intval = POWER_SUPPLY_STATUS_CHARGING;
+               else
+                       val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+               break;
+       case POWER_SUPPLY_PROP_PRESENT:
+               val->intval = !!(pbi->flags & PMU_BATT_PRESENT);
+               break;
+       case POWER_SUPPLY_PROP_MODEL_NAME:
+               val->strval = pmu_bat_get_model_name(pbi);
+               break;
+       case POWER_SUPPLY_PROP_ENERGY_AVG:
+               val->intval = pbi->charge     * 1000; /* mWh -> ÂµWh */
+               break;
+       case POWER_SUPPLY_PROP_ENERGY_FULL:
+               val->intval = pbi->max_charge * 1000; /* mWh -> ÂµWh */
+               break;
+       case POWER_SUPPLY_PROP_CURRENT_AVG:
+               val->intval = pbi->amperage   * 1000; /* mA -> ÂµA */
+               break;
+       case POWER_SUPPLY_PROP_VOLTAGE_AVG:
+               val->intval = pbi->voltage    * 1000; /* mV -> ÂµV */
+               break;
+       case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
+               val->intval = pbi->time_remaining;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static enum power_supply_property pmu_bat_props[] = {
+       POWER_SUPPLY_PROP_STATUS,
+       POWER_SUPPLY_PROP_PRESENT,
+       POWER_SUPPLY_PROP_MODEL_NAME,
+       POWER_SUPPLY_PROP_ENERGY_AVG,
+       POWER_SUPPLY_PROP_ENERGY_FULL,
+       POWER_SUPPLY_PROP_CURRENT_AVG,
+       POWER_SUPPLY_PROP_VOLTAGE_AVG,
+       POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
+};
+
+/*********************************************************************
+ *             Initialisation
+ *********************************************************************/
+
+static struct platform_device *bat_pdev;
+
+static int __init pmu_bat_init(void)
+{
+       int ret;
+       int i;
+
+       bat_pdev = platform_device_register_simple("pmu-battery",
+                                                  0, NULL, 0);
+       if (IS_ERR(bat_pdev)) {
+               ret = PTR_ERR(bat_pdev);
+               goto pdev_register_failed;
+       }
+
+       ret = power_supply_register(&bat_pdev->dev, &pmu_ac);
+       if (ret)
+               goto ac_register_failed;
+
+       for (i = 0; i < pmu_battery_count; i++) {
+               struct pmu_battery_dev *pbat = kzalloc(sizeof(*pbat),
+                                                      GFP_KERNEL);
+               if (!pbat)
+                       break;
+
+               sprintf(pbat->name, "PMU battery %d", i);
+               pbat->bat.name = pbat->name;
+               pbat->bat.properties = pmu_bat_props;
+               pbat->bat.num_properties = ARRAY_SIZE(pmu_bat_props);
+               pbat->bat.get_property = pmu_bat_get_property;
+               pbat->pbi = &pmu_batteries[i];
+
+               ret = power_supply_register(&bat_pdev->dev, &pbat->bat);
+               if (ret) {
+                       kfree(pbat);
+                       goto battery_register_failed;
+               }
+               pbats[i] = pbat;
+       }
+
+       goto success;
+
+battery_register_failed:
+       while (i--) {
+               if (!pbats[i])
+                       continue;
+               power_supply_unregister(&pbats[i]->bat);
+               kfree(pbats[i]);
+       }
+       power_supply_unregister(&pmu_ac);
+ac_register_failed:
+       platform_device_unregister(bat_pdev);
+pdev_register_failed:
+success:
+       return ret;
+}
+
+static void __exit pmu_bat_exit(void)
+{
+       int i;
+
+       for (i = 0; i < PMU_MAX_BATTERIES; i++) {
+               if (!pbats[i])
+                       continue;
+               power_supply_unregister(&pbats[i]->bat);
+               kfree(pbats[i]);
+       }
+       power_supply_unregister(&pmu_ac);
+       platform_device_unregister(bat_pdev);
+
+       return;
+}
+
+module_init(pmu_bat_init);
+module_exit(pmu_bat_exit);
+
+MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("PMU battery driver");
diff --git a/drivers/power/power_supply.h b/drivers/power/power_supply.h
new file mode 100644 (file)
index 0000000..a9880d4
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ *  Functions private to power supply class
+ *
+ *  Copyright Â© 2007  Anton Vorontsov <cbou@mail.ru>
+ *  Copyright Â© 2004  Szabolcs Gyurko
+ *  Copyright Â© 2003  Ian Molton <spyro@f2s.com>
+ *
+ *  Modified: 2004, Oct     Szabolcs Gyurko
+ *
+ *  You may use this code as per GPL version 2
+ */
+
+#ifdef CONFIG_SYSFS
+
+extern int power_supply_create_attrs(struct power_supply *psy);
+extern void power_supply_remove_attrs(struct power_supply *psy);
+extern int power_supply_uevent(struct device *dev, char **envp, int num_envp,
+                              char *buffer, int buffer_size);
+
+#else
+
+static inline int power_supply_create_attrs(struct power_supply *psy)
+{ return 0; }
+static inline void power_supply_remove_attrs(struct power_supply *psy) {}
+#define power_supply_uevent NULL
+
+#endif /* CONFIG_SYSFS */
+
+#ifdef CONFIG_LEDS_TRIGGERS
+
+extern void power_supply_update_leds(struct power_supply *psy);
+extern int power_supply_create_triggers(struct power_supply *psy);
+extern void power_supply_remove_triggers(struct power_supply *psy);
+
+#else
+
+static inline void power_supply_update_leds(struct power_supply *psy) {}
+static inline int power_supply_create_triggers(struct power_supply *psy)
+{ return 0; }
+static inline void power_supply_remove_triggers(struct power_supply *psy) {}
+
+#endif /* CONFIG_LEDS_TRIGGERS */
diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c
new file mode 100644 (file)
index 0000000..e87ea51
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ *  Universal power supply monitor class
+ *
+ *  Copyright Â© 2007  Anton Vorontsov <cbou@mail.ru>
+ *  Copyright Â© 2004  Szabolcs Gyurko
+ *  Copyright Â© 2003  Ian Molton <spyro@f2s.com>
+ *
+ *  Modified: 2004, Oct     Szabolcs Gyurko
+ *
+ *  You may use this code as per GPL version 2
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/power_supply.h>
+#include "power_supply.h"
+
+struct class *power_supply_class;
+
+static void power_supply_changed_work(struct work_struct *work)
+{
+       struct power_supply *psy = container_of(work, struct power_supply,
+                                               changed_work);
+       int i;
+
+       dev_dbg(psy->dev, "%s\n", __FUNCTION__);
+
+       for (i = 0; i < psy->num_supplicants; i++) {
+               struct device *dev;
+
+               down(&power_supply_class->sem);
+               list_for_each_entry(dev, &power_supply_class->devices, node) {
+                       struct power_supply *pst = dev_get_drvdata(dev);
+
+                       if (!strcmp(psy->supplied_to[i], pst->name)) {
+                               if (pst->external_power_changed)
+                                       pst->external_power_changed(pst);
+                       }
+               }
+               up(&power_supply_class->sem);
+       }
+
+       power_supply_update_leds(psy);
+
+       kobject_uevent(&psy->dev->kobj, KOBJ_CHANGE);
+
+       return;
+}
+
+void power_supply_changed(struct power_supply *psy)
+{
+       dev_dbg(psy->dev, "%s\n", __FUNCTION__);
+
+       schedule_work(&psy->changed_work);
+
+       return;
+}
+
+int power_supply_am_i_supplied(struct power_supply *psy)
+{
+       union power_supply_propval ret = {0,};
+       struct device *dev;
+
+       down(&power_supply_class->sem);
+       list_for_each_entry(dev, &power_supply_class->devices, node) {
+               struct power_supply *epsy = dev_get_drvdata(dev);
+               int i;
+
+               for (i = 0; i < epsy->num_supplicants; i++) {
+                       if (!strcmp(epsy->supplied_to[i], psy->name)) {
+                               if (epsy->get_property(epsy,
+                                         POWER_SUPPLY_PROP_ONLINE, &ret))
+                                       continue;
+                               if (ret.intval)
+                                       goto out;
+                       }
+               }
+       }
+out:
+       up(&power_supply_class->sem);
+
+       dev_dbg(psy->dev, "%s %d\n", __FUNCTION__, ret.intval);
+
+       return ret.intval;
+}
+
+int power_supply_register(struct device *parent, struct power_supply *psy)
+{
+       int rc = 0;
+
+       psy->dev = device_create(power_supply_class, parent, 0,
+                                "%s", psy->name);
+       if (IS_ERR(psy->dev)) {
+               rc = PTR_ERR(psy->dev);
+               goto dev_create_failed;
+       }
+
+       dev_set_drvdata(psy->dev, psy);
+
+       INIT_WORK(&psy->changed_work, power_supply_changed_work);
+
+       rc = power_supply_create_attrs(psy);
+       if (rc)
+               goto create_attrs_failed;
+
+       rc = power_supply_create_triggers(psy);
+       if (rc)
+               goto create_triggers_failed;
+
+       power_supply_changed(psy);
+
+       goto success;
+
+create_triggers_failed:
+       power_supply_remove_attrs(psy);
+create_attrs_failed:
+       device_unregister(psy->dev);
+dev_create_failed:
+success:
+       return rc;
+}
+
+void power_supply_unregister(struct power_supply *psy)
+{
+       flush_scheduled_work();
+       power_supply_remove_triggers(psy);
+       power_supply_remove_attrs(psy);
+       device_unregister(psy->dev);
+       return;
+}
+
+static int __init power_supply_class_init(void)
+{
+       power_supply_class = class_create(THIS_MODULE, "power_supply");
+
+       if (IS_ERR(power_supply_class))
+               return PTR_ERR(power_supply_class);
+
+       power_supply_class->dev_uevent = power_supply_uevent;
+
+       return 0;
+}
+
+static void __exit power_supply_class_exit(void)
+{
+       class_destroy(power_supply_class);
+       return;
+}
+
+EXPORT_SYMBOL_GPL(power_supply_changed);
+EXPORT_SYMBOL_GPL(power_supply_am_i_supplied);
+EXPORT_SYMBOL_GPL(power_supply_register);
+EXPORT_SYMBOL_GPL(power_supply_unregister);
+
+/* exported for the APM Power driver, APM emulation */
+EXPORT_SYMBOL_GPL(power_supply_class);
+
+subsys_initcall(power_supply_class_init);
+module_exit(power_supply_class_exit);
+
+MODULE_DESCRIPTION("Universal power supply monitor class");
+MODULE_AUTHOR("Ian Molton <spyro@f2s.com>, "
+             "Szabolcs Gyurko, "
+             "Anton Vorontsov <cbou@mail.ru>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/power/power_supply_leds.c b/drivers/power/power_supply_leds.c
new file mode 100644 (file)
index 0000000..7232490
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ *  LEDs triggers for power supply class
+ *
+ *  Copyright Â© 2007  Anton Vorontsov <cbou@mail.ru>
+ *  Copyright Â© 2004  Szabolcs Gyurko
+ *  Copyright Â© 2003  Ian Molton <spyro@f2s.com>
+ *
+ *  Modified: 2004, Oct     Szabolcs Gyurko
+ *
+ *  You may use this code as per GPL version 2
+ */
+
+#include <linux/power_supply.h>
+
+/* Battery specific LEDs triggers. */
+
+static void power_supply_update_bat_leds(struct power_supply *psy)
+{
+       union power_supply_propval status;
+
+       if (psy->get_property(psy, POWER_SUPPLY_PROP_STATUS, &status))
+               return;
+
+       dev_dbg(psy->dev, "%s %d\n", __FUNCTION__, status.intval);
+
+       switch (status.intval) {
+       case POWER_SUPPLY_STATUS_FULL:
+               led_trigger_event(psy->charging_full_trig, LED_FULL);
+               led_trigger_event(psy->charging_trig, LED_OFF);
+               led_trigger_event(psy->full_trig, LED_FULL);
+               break;
+       case POWER_SUPPLY_STATUS_CHARGING:
+               led_trigger_event(psy->charging_full_trig, LED_FULL);
+               led_trigger_event(psy->charging_trig, LED_FULL);
+               led_trigger_event(psy->full_trig, LED_OFF);
+               break;
+       default:
+               led_trigger_event(psy->charging_full_trig, LED_OFF);
+               led_trigger_event(psy->charging_trig, LED_OFF);
+               led_trigger_event(psy->full_trig, LED_OFF);
+               break;
+       }
+
+       return;
+}
+
+static int power_supply_create_bat_triggers(struct power_supply *psy)
+{
+       int rc = 0;
+
+       psy->charging_full_trig_name = kmalloc(strlen(psy->name) +
+                                 sizeof("-charging-or-full"), GFP_KERNEL);
+       if (!psy->charging_full_trig_name)
+               goto charging_full_failed;
+
+       psy->charging_trig_name = kmalloc(strlen(psy->name) +
+                                         sizeof("-charging"), GFP_KERNEL);
+       if (!psy->charging_trig_name)
+               goto charging_failed;
+
+       psy->full_trig_name = kmalloc(strlen(psy->name) +
+                                     sizeof("-full"), GFP_KERNEL);
+       if (!psy->full_trig_name)
+               goto full_failed;
+
+       strcpy(psy->charging_full_trig_name, psy->name);
+       strcat(psy->charging_full_trig_name, "-charging-or-full");
+       strcpy(psy->charging_trig_name, psy->name);
+       strcat(psy->charging_trig_name, "-charging");
+       strcpy(psy->full_trig_name, psy->name);
+       strcat(psy->full_trig_name, "-full");
+
+       led_trigger_register_simple(psy->charging_full_trig_name,
+                                   &psy->charging_full_trig);
+       led_trigger_register_simple(psy->charging_trig_name,
+                                   &psy->charging_trig);
+       led_trigger_register_simple(psy->full_trig_name,
+                                   &psy->full_trig);
+
+       goto success;
+
+full_failed:
+       kfree(psy->charging_trig_name);
+charging_failed:
+       kfree(psy->charging_full_trig_name);
+charging_full_failed:
+       rc = -ENOMEM;
+success:
+       return rc;
+}
+
+static void power_supply_remove_bat_triggers(struct power_supply *psy)
+{
+       led_trigger_unregister_simple(psy->charging_full_trig);
+       led_trigger_unregister_simple(psy->charging_trig);
+       led_trigger_unregister_simple(psy->full_trig);
+       kfree(psy->full_trig_name);
+       kfree(psy->charging_trig_name);
+       kfree(psy->charging_full_trig_name);
+       return;
+}
+
+/* Generated power specific LEDs triggers. */
+
+static void power_supply_update_gen_leds(struct power_supply *psy)
+{
+       union power_supply_propval online;
+
+       if (psy->get_property(psy, POWER_SUPPLY_PROP_ONLINE, &online))
+               return;
+
+       dev_dbg(psy->dev, "%s %d\n", __FUNCTION__, online.intval);
+
+       if (online.intval)
+               led_trigger_event(psy->online_trig, LED_FULL);
+       else
+               led_trigger_event(psy->online_trig, LED_OFF);
+
+       return;
+}
+
+static int power_supply_create_gen_triggers(struct power_supply *psy)
+{
+       int rc = 0;
+
+       psy->online_trig_name = kmalloc(strlen(psy->name) + sizeof("-online"),
+                                       GFP_KERNEL);
+       if (!psy->online_trig_name)
+               goto online_failed;
+
+       strcpy(psy->online_trig_name, psy->name);
+       strcat(psy->online_trig_name, "-online");
+
+       led_trigger_register_simple(psy->online_trig_name, &psy->online_trig);
+
+       goto success;
+
+online_failed:
+       rc = -ENOMEM;
+success:
+       return rc;
+}
+
+static void power_supply_remove_gen_triggers(struct power_supply *psy)
+{
+       led_trigger_unregister_simple(psy->online_trig);
+       kfree(psy->online_trig_name);
+       return;
+}
+
+/* Choice what triggers to create&update. */
+
+void power_supply_update_leds(struct power_supply *psy)
+{
+       if (psy->type == POWER_SUPPLY_TYPE_BATTERY)
+               power_supply_update_bat_leds(psy);
+       else
+               power_supply_update_gen_leds(psy);
+       return;
+}
+
+int power_supply_create_triggers(struct power_supply *psy)
+{
+       if (psy->type == POWER_SUPPLY_TYPE_BATTERY)
+               return power_supply_create_bat_triggers(psy);
+       return power_supply_create_gen_triggers(psy);
+}
+
+void power_supply_remove_triggers(struct power_supply *psy)
+{
+       if (psy->type == POWER_SUPPLY_TYPE_BATTERY)
+               power_supply_remove_bat_triggers(psy);
+       else
+               power_supply_remove_gen_triggers(psy);
+       return;
+}
diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c
new file mode 100644 (file)
index 0000000..c07d425
--- /dev/null
@@ -0,0 +1,299 @@
+/*
+ *  Sysfs interface for the universal power supply monitor class
+ *
+ *  Copyright Â© 2007  David Woodhouse <dwmw2@infradead.org>
+ *  Copyright Â© 2007  Anton Vorontsov <cbou@mail.ru>
+ *  Copyright Â© 2004  Szabolcs Gyurko
+ *  Copyright Â© 2003  Ian Molton <spyro@f2s.com>
+ *
+ *  Modified: 2004, Oct     Szabolcs Gyurko
+ *
+ *  You may use this code as per GPL version 2
+ */
+
+#include <linux/ctype.h>
+#include <linux/power_supply.h>
+
+/*
+ * This is because the name "current" breaks the device attr macro.
+ * The "current" word resolves to "(get_current())" so instead of
+ * "current" "(get_current())" appears in the sysfs.
+ *
+ * The source of this definition is the device.h which calls __ATTR
+ * macro in sysfs.h which calls the __stringify macro.
+ *
+ * Only modification that the name is not tried to be resolved
+ * (as a macro let's say).
+ */
+
+#define POWER_SUPPLY_ATTR(_name)                                       \
+{                                                                      \
+       .attr = { .name = #_name, .mode = 0444, .owner = THIS_MODULE }, \
+       .show = power_supply_show_property,                             \
+       .store = NULL,                                                  \
+}
+
+static struct device_attribute power_supply_attrs[];
+
+static ssize_t power_supply_show_property(struct device *dev,
+                                         struct device_attribute *attr,
+                                         char *buf) {
+       static char *status_text[] = {
+               "Unknown", "Charging", "Discharging", "Not charging", "Full"
+       };
+       static char *health_text[] = {
+               "Unknown", "Good", "Overheat", "Dead", "Over voltage",
+               "Unspecified failure"
+       };
+       static char *technology_text[] = {
+               "Unknown", "NiMH", "Li-ion", "Li-poly", "LiFe", "NiCd"
+       };
+       static char *capacity_level_text[] = {
+               "Unknown", "Critical", "Low", "Normal", "High", "Full"
+       };
+       ssize_t ret;
+       struct power_supply *psy = dev_get_drvdata(dev);
+       const ptrdiff_t off = attr - power_supply_attrs;
+       union power_supply_propval value;
+
+       ret = psy->get_property(psy, off, &value);
+
+       if (ret < 0) {
+               if (ret != -ENODEV)
+                       dev_err(dev, "driver failed to report `%s' property\n",
+                               attr->attr.name);
+               return ret;
+       }
+
+       if (off == POWER_SUPPLY_PROP_STATUS)
+               return sprintf(buf, "%s\n", status_text[value.intval]);
+       else if (off == POWER_SUPPLY_PROP_HEALTH)
+               return sprintf(buf, "%s\n", health_text[value.intval]);
+       else if (off == POWER_SUPPLY_PROP_TECHNOLOGY)
+               return sprintf(buf, "%s\n", technology_text[value.intval]);
+       else if (off == POWER_SUPPLY_PROP_CAPACITY_LEVEL)
+               return sprintf(buf, "%s\n",
+                              capacity_level_text[value.intval]);
+       else if (off >= POWER_SUPPLY_PROP_MODEL_NAME)
+               return sprintf(buf, "%s\n", value.strval);
+
+       return sprintf(buf, "%d\n", value.intval);
+}
+
+/* Must be in the same order as POWER_SUPPLY_PROP_* */
+static struct device_attribute power_supply_attrs[] = {
+       /* Properties of type `int' */
+       POWER_SUPPLY_ATTR(status),
+       POWER_SUPPLY_ATTR(health),
+       POWER_SUPPLY_ATTR(present),
+       POWER_SUPPLY_ATTR(online),
+       POWER_SUPPLY_ATTR(technology),
+       POWER_SUPPLY_ATTR(voltage_max_design),
+       POWER_SUPPLY_ATTR(voltage_min_design),
+       POWER_SUPPLY_ATTR(voltage_now),
+       POWER_SUPPLY_ATTR(voltage_avg),
+       POWER_SUPPLY_ATTR(current_now),
+       POWER_SUPPLY_ATTR(current_avg),
+       POWER_SUPPLY_ATTR(charge_full_design),
+       POWER_SUPPLY_ATTR(charge_empty_design),
+       POWER_SUPPLY_ATTR(charge_full),
+       POWER_SUPPLY_ATTR(charge_empty),
+       POWER_SUPPLY_ATTR(charge_now),
+       POWER_SUPPLY_ATTR(charge_avg),
+       POWER_SUPPLY_ATTR(energy_full_design),
+       POWER_SUPPLY_ATTR(energy_empty_design),
+       POWER_SUPPLY_ATTR(energy_full),
+       POWER_SUPPLY_ATTR(energy_empty),
+       POWER_SUPPLY_ATTR(energy_now),
+       POWER_SUPPLY_ATTR(energy_avg),
+       POWER_SUPPLY_ATTR(capacity),
+       POWER_SUPPLY_ATTR(capacity_level),
+       POWER_SUPPLY_ATTR(temp),
+       POWER_SUPPLY_ATTR(temp_ambient),
+       POWER_SUPPLY_ATTR(time_to_empty_now),
+       POWER_SUPPLY_ATTR(time_to_empty_avg),
+       POWER_SUPPLY_ATTR(time_to_full_now),
+       POWER_SUPPLY_ATTR(time_to_full_avg),
+       /* Properties of type `const char *' */
+       POWER_SUPPLY_ATTR(model_name),
+       POWER_SUPPLY_ATTR(manufacturer),
+};
+
+static ssize_t power_supply_show_static_attrs(struct device *dev,
+                                             struct device_attribute *attr,
+                                             char *buf) {
+       static char *type_text[] = { "Battery", "UPS", "Mains", "USB" };
+       struct power_supply *psy = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%s\n", type_text[psy->type]);
+}
+
+static struct device_attribute power_supply_static_attrs[] = {
+       __ATTR(type, 0444, power_supply_show_static_attrs, NULL),
+};
+
+int power_supply_create_attrs(struct power_supply *psy)
+{
+       int rc = 0;
+       int i, j;
+
+       for (i = 0; i < ARRAY_SIZE(power_supply_static_attrs); i++) {
+               rc = device_create_file(psy->dev,
+                           &power_supply_static_attrs[i]);
+               if (rc)
+                       goto statics_failed;
+       }
+
+       for (j = 0; j < psy->num_properties; j++) {
+               rc = device_create_file(psy->dev,
+                           &power_supply_attrs[psy->properties[j]]);
+               if (rc)
+                       goto dynamics_failed;
+       }
+
+       goto succeed;
+
+dynamics_failed:
+       while (j--)
+               device_remove_file(psy->dev,
+                          &power_supply_attrs[psy->properties[j]]);
+statics_failed:
+       while (i--)
+               device_remove_file(psy->dev,
+                          &power_supply_static_attrs[psy->properties[i]]);
+succeed:
+       return rc;
+}
+
+void power_supply_remove_attrs(struct power_supply *psy)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(power_supply_static_attrs); i++)
+               device_remove_file(psy->dev,
+                           &power_supply_static_attrs[i]);
+
+       for (i = 0; i < psy->num_properties; i++)
+               device_remove_file(psy->dev,
+                           &power_supply_attrs[psy->properties[i]]);
+
+       return;
+}
+
+static char *kstruprdup(const char *str, gfp_t gfp)
+{
+       char *ret, *ustr;
+
+       ustr = ret = kmalloc(strlen(str) + 1, gfp);
+
+       if (!ret)
+               return NULL;
+
+       while (*str)
+               *ustr++ = toupper(*str++);
+
+       *ustr = 0;
+
+       return ret;
+}
+
+int power_supply_uevent(struct device *dev, char **envp, int num_envp,
+                       char *buffer, int buffer_size)
+{
+       struct power_supply *psy = dev_get_drvdata(dev);
+       int i = 0, length = 0, ret = 0, j;
+       char *prop_buf;
+       char *attrname;
+
+       dev_dbg(dev, "uevent\n");
+
+       if (!psy) {
+               dev_dbg(dev, "No power supply yet\n");
+               return ret;
+       }
+
+       dev_dbg(dev, "POWER_SUPPLY_NAME=%s\n", psy->name);
+
+       ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
+                            &length, "POWER_SUPPLY_NAME=%s", psy->name);
+       if (ret)
+               return ret;
+
+       prop_buf = (char *)get_zeroed_page(GFP_KERNEL);
+       if (!prop_buf)
+               return -ENOMEM;
+
+       for (j = 0; j < ARRAY_SIZE(power_supply_static_attrs); j++) {
+               struct device_attribute *attr;
+               char *line;
+
+               attr = &power_supply_static_attrs[j];
+
+               ret = power_supply_show_static_attrs(dev, attr, prop_buf);
+               if (ret < 0)
+                       goto out;
+
+               line = strchr(prop_buf, '\n');
+               if (line)
+                       *line = 0;
+
+               attrname = kstruprdup(attr->attr.name, GFP_KERNEL);
+               if (!attrname) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+
+               dev_dbg(dev, "Static prop %s=%s\n", attrname, prop_buf);
+
+               ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
+                                    &length, "POWER_SUPPLY_%s=%s",
+                                    attrname, prop_buf);
+               kfree(attrname);
+               if (ret)
+                       goto out;
+       }
+
+       dev_dbg(dev, "%zd dynamic props\n", psy->num_properties);
+
+       for (j = 0; j < psy->num_properties; j++) {
+               struct device_attribute *attr;
+               char *line;
+
+               attr = &power_supply_attrs[psy->properties[j]];
+
+               ret = power_supply_show_property(dev, attr, prop_buf);
+               if (ret == -ENODEV) {
+                       /* When a battery is absent, we expect -ENODEV. Don't abort;
+                          send the uevent with at least the the PRESENT=0 property */
+                       ret = 0;
+                       continue;
+               }
+
+               if (ret < 0)
+                       goto out;
+
+               line = strchr(prop_buf, '\n');
+               if (line)
+                       *line = 0;
+
+               attrname = kstruprdup(attr->attr.name, GFP_KERNEL);
+               if (!attrname) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+
+               dev_dbg(dev, "prop %s=%s\n", attrname, prop_buf);
+
+               ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
+                                    &length, "POWER_SUPPLY_%s=%s",
+                                    attrname, prop_buf);
+               kfree(attrname);
+               if (ret)
+                       goto out;
+       }
+
+out:
+       free_page((unsigned long)prop_buf);
+
+       return ret;
+}
index eed91434417d7d39e86a2bca4602700e8dfe3177..659e31164cf08b3c94cb6b6d09821f79e9f97793 100644 (file)
@@ -67,7 +67,8 @@ struct device_attribute rio_dev_attrs[] = {
 };
 
 static ssize_t
-rio_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
+rio_read_config(struct kobject *kobj, struct bin_attribute *bin_attr,
+               char *buf, loff_t off, size_t count)
 {
        struct rio_dev *dev =
            to_rio_dev(container_of(kobj, struct device, kobj));
@@ -137,7 +138,8 @@ rio_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
 }
 
 static ssize_t
-rio_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
+rio_write_config(struct kobject *kobj, struct bin_attribute *bin_attr,
+                char *buf, loff_t off, size_t count)
 {
        struct rio_dev *dev =
            to_rio_dev(container_of(kobj, struct device, kobj));
@@ -197,7 +199,6 @@ static struct bin_attribute rio_config_attr = {
        .attr = {
                 .name = "config",
                 .mode = S_IRUGO | S_IWUSR,
-                .owner = THIS_MODULE,
                 },
        .size = 0x200000,
        .read = rio_read_config,
index afa64c7fa2e2d67152b50fe75b011e7cf2c8a6f2..f98a83a11aaeb66411a9083f78f887807528e732 100644 (file)
@@ -258,8 +258,9 @@ static const struct rtc_class_ops ds1553_rtc_ops = {
        .ioctl          = ds1553_rtc_ioctl,
 };
 
-static ssize_t ds1553_nvram_read(struct kobject *kobj, char *buf,
-                                loff_t pos, size_t size)
+static ssize_t ds1553_nvram_read(struct kobject *kobj,
+                                struct bin_attribute *bin_attr,
+                                char *buf, loff_t pos, size_t size)
 {
        struct platform_device *pdev =
                to_platform_device(container_of(kobj, struct device, kobj));
@@ -272,8 +273,9 @@ static ssize_t ds1553_nvram_read(struct kobject *kobj, char *buf,
        return count;
 }
 
-static ssize_t ds1553_nvram_write(struct kobject *kobj, char *buf,
-                                 loff_t pos, size_t size)
+static ssize_t ds1553_nvram_write(struct kobject *kobj,
+                                 struct bin_attribute *bin_attr,
+                                 char *buf, loff_t pos, size_t size)
 {
        struct platform_device *pdev =
                to_platform_device(container_of(kobj, struct device, kobj));
@@ -290,7 +292,6 @@ static struct bin_attribute ds1553_nvram_attr = {
        .attr = {
                .name = "nvram",
                .mode = S_IRUGO | S_IWUGO,
-               .owner = THIS_MODULE,
        },
        .size = RTC_OFFSET,
        .read = ds1553_nvram_read,
index d68288b389dc18b041c07060dac49da774da5df1..d1778ae8bca58c6e9b8a45dc534e4345b21cc7a8 100644 (file)
@@ -127,8 +127,9 @@ static const struct rtc_class_ops ds1742_rtc_ops = {
        .set_time       = ds1742_rtc_set_time,
 };
 
-static ssize_t ds1742_nvram_read(struct kobject *kobj, char *buf,
-                                loff_t pos, size_t size)
+static ssize_t ds1742_nvram_read(struct kobject *kobj,
+                                struct bin_attribute *bin_attr,
+                                char *buf, loff_t pos, size_t size)
 {
        struct platform_device *pdev =
                to_platform_device(container_of(kobj, struct device, kobj));
@@ -141,8 +142,9 @@ static ssize_t ds1742_nvram_read(struct kobject *kobj, char *buf,
        return count;
 }
 
-static ssize_t ds1742_nvram_write(struct kobject *kobj, char *buf,
-                                 loff_t pos, size_t size)
+static ssize_t ds1742_nvram_write(struct kobject *kobj,
+                                 struct bin_attribute *bin_attr,
+                                 char *buf, loff_t pos, size_t size)
 {
        struct platform_device *pdev =
                to_platform_device(container_of(kobj, struct device, kobj));
@@ -159,7 +161,6 @@ static struct bin_attribute ds1742_nvram_attr = {
        .attr = {
                .name = "nvram",
                .mode = S_IRUGO | S_IWUGO,
-               .owner = THIS_MODULE,
        },
        .read = ds1742_nvram_read,
        .write = ds1742_nvram_write,
index af7596ef29e2d837f2c9c8ea6b6d4fc7b7d37102..ce2f78de7a80b9ce2285ad7c8d4fffb02179855e 100644 (file)
  *  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/err.h>
 #include <linux/fs.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
-#include <linux/irq.h>
+#include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/rtc.h>
 #include <asm/div64.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
-#include <asm/vr41xx/irq.h>
 
 MODULE_AUTHOR("Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>");
 MODULE_DESCRIPTION("NEC VR4100 series RTC driver");
 MODULE_LICENSE("GPL");
 
-#define RTC1_TYPE1_START       0x0b0000c0UL
-#define RTC1_TYPE1_END         0x0b0000dfUL
-#define RTC2_TYPE1_START       0x0b0001c0UL
-#define RTC2_TYPE1_END         0x0b0001dfUL
-
-#define RTC1_TYPE2_START       0x0f000100UL
-#define RTC1_TYPE2_END         0x0f00011fUL
-#define RTC2_TYPE2_START       0x0f000120UL
-#define RTC2_TYPE2_END         0x0f00013fUL
-
-#define RTC1_SIZE              0x20
-#define RTC2_SIZE              0x20
-
 /* RTC 1 registers */
 #define ETIMELREG              0x00
 #define ETIMEMREG              0x02
@@ -98,13 +85,8 @@ static char rtc_name[] = "RTC";
 static unsigned long periodic_frequency;
 static unsigned long periodic_count;
 static unsigned int alarm_enabled;
-
-struct resource rtc_resource[2] = {
-       {       .name   = rtc_name,
-               .flags  = IORESOURCE_MEM,       },
-       {       .name   = rtc_name,
-               .flags  = IORESOURCE_MEM,       },
-};
+static int aie_irq = -1;
+static int pie_irq = -1;
 
 static inline unsigned long read_elapsed_second(void)
 {
@@ -150,8 +132,8 @@ static void vr41xx_rtc_release(struct device *dev)
 
        spin_unlock_irq(&rtc_lock);
 
-       disable_irq(ELAPSEDTIME_IRQ);
-       disable_irq(RTCLONG1_IRQ);
+       disable_irq(aie_irq);
+       disable_irq(pie_irq);
 }
 
 static int vr41xx_rtc_read_time(struct device *dev, struct rtc_time *time)
@@ -209,14 +191,14 @@ static int vr41xx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
        spin_lock_irq(&rtc_lock);
 
        if (alarm_enabled)
-               disable_irq(ELAPSEDTIME_IRQ);
+               disable_irq(aie_irq);
 
        rtc1_write(ECMPLREG, (uint16_t)(alarm_sec << 15));
        rtc1_write(ECMPMREG, (uint16_t)(alarm_sec >> 1));
        rtc1_write(ECMPHREG, (uint16_t)(alarm_sec >> 17));
 
        if (wkalrm->enabled)
-               enable_irq(ELAPSEDTIME_IRQ);
+               enable_irq(aie_irq);
 
        alarm_enabled = wkalrm->enabled;
 
@@ -234,7 +216,7 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long
                spin_lock_irq(&rtc_lock);
 
                if (!alarm_enabled) {
-                       enable_irq(ELAPSEDTIME_IRQ);
+                       enable_irq(aie_irq);
                        alarm_enabled = 1;
                }
 
@@ -244,17 +226,17 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long
                spin_lock_irq(&rtc_lock);
 
                if (alarm_enabled) {
-                       disable_irq(ELAPSEDTIME_IRQ);
+                       disable_irq(aie_irq);
                        alarm_enabled = 0;
                }
 
                spin_unlock_irq(&rtc_lock);
                break;
        case RTC_PIE_ON:
-               enable_irq(RTCLONG1_IRQ);
+               enable_irq(pie_irq);
                break;
        case RTC_PIE_OFF:
-               disable_irq(RTCLONG1_IRQ);
+               disable_irq(pie_irq);
                break;
        case RTC_IRQP_READ:
                return put_user(periodic_frequency, (unsigned long __user *)arg);
@@ -331,31 +313,37 @@ static const struct rtc_class_ops vr41xx_rtc_ops = {
 
 static int __devinit rtc_probe(struct platform_device *pdev)
 {
+       struct resource *res;
        struct rtc_device *rtc;
-       unsigned int irq;
        int retval;
 
-       if (pdev->num_resources != 2)
+       if (pdev->num_resources != 4)
                return -EBUSY;
 
-       rtc1_base = ioremap(pdev->resource[0].start, RTC1_SIZE);
-       if (rtc1_base == NULL)
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res)
                return -EBUSY;
 
-       rtc2_base = ioremap(pdev->resource[1].start, RTC2_SIZE);
-       if (rtc2_base == NULL) {
-               iounmap(rtc1_base);
-               rtc1_base = NULL;
+       rtc1_base = ioremap(res->start, res->end - res->start + 1);
+       if (!rtc1_base)
                return -EBUSY;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+       if (!res) {
+               retval = -EBUSY;
+               goto err_rtc1_iounmap;
+       }
+
+       rtc2_base = ioremap(res->start, res->end - res->start + 1);
+       if (!rtc2_base) {
+               retval = -EBUSY;
+               goto err_rtc1_iounmap;
        }
 
        rtc = rtc_device_register(rtc_name, &pdev->dev, &vr41xx_rtc_ops, THIS_MODULE);
        if (IS_ERR(rtc)) {
-               iounmap(rtc1_base);
-               iounmap(rtc2_base);
-               rtc1_base = NULL;
-               rtc2_base = NULL;
-               return PTR_ERR(rtc);
+               retval = PTR_ERR(rtc);
+               goto err_iounmap_all;
        }
 
        spin_lock_irq(&rtc_lock);
@@ -368,35 +356,50 @@ static int __devinit rtc_probe(struct platform_device *pdev)
 
        spin_unlock_irq(&rtc_lock);
 
-       irq = ELAPSEDTIME_IRQ;
-       retval = request_irq(irq, elapsedtime_interrupt, IRQF_DISABLED,
-                            "elapsed_time", pdev);
-       if (retval == 0) {
-               irq = RTCLONG1_IRQ;
-               retval = request_irq(irq, rtclong1_interrupt, IRQF_DISABLED,
-                                    "rtclong1", pdev);
+       aie_irq = platform_get_irq(pdev, 0);
+       if (aie_irq < 0 || aie_irq >= NR_IRQS) {
+               retval = -EBUSY;
+               goto err_device_unregister;
        }
 
-       if (retval < 0) {
-               printk(KERN_ERR "rtc: IRQ%d is busy\n", irq);
-               rtc_device_unregister(rtc);
-               if (irq == RTCLONG1_IRQ)
-                       free_irq(ELAPSEDTIME_IRQ, NULL);
-               iounmap(rtc1_base);
-               iounmap(rtc2_base);
-               rtc1_base = NULL;
-               rtc2_base = NULL;
-               return retval;
-       }
+       retval = request_irq(aie_irq, elapsedtime_interrupt, IRQF_DISABLED,
+                            "elapsed_time", pdev);
+       if (retval < 0)
+               goto err_device_unregister;
+
+       pie_irq = platform_get_irq(pdev, 1);
+       if (pie_irq < 0 || pie_irq >= NR_IRQS)
+               goto err_free_irq;
+
+       retval = request_irq(pie_irq, rtclong1_interrupt, IRQF_DISABLED,
+                            "rtclong1", pdev);
+       if (retval < 0)
+               goto err_free_irq;
 
        platform_set_drvdata(pdev, rtc);
 
-       disable_irq(ELAPSEDTIME_IRQ);
-       disable_irq(RTCLONG1_IRQ);
+       disable_irq(aie_irq);
+       disable_irq(pie_irq);
 
        printk(KERN_INFO "rtc: Real Time Clock of NEC VR4100 series\n");
 
        return 0;
+
+err_free_irq:
+       free_irq(aie_irq, pdev);
+
+err_device_unregister:
+       rtc_device_unregister(rtc);
+
+err_iounmap_all:
+       iounmap(rtc2_base);
+       rtc2_base = NULL;
+
+err_rtc1_iounmap:
+       iounmap(rtc1_base);
+       rtc1_base = NULL;
+
+       return retval;
 }
 
 static int __devexit rtc_remove(struct platform_device *pdev)
@@ -404,23 +407,21 @@ static int __devexit rtc_remove(struct platform_device *pdev)
        struct rtc_device *rtc;
 
        rtc = platform_get_drvdata(pdev);
-       if (rtc != NULL)
+       if (rtc)
                rtc_device_unregister(rtc);
 
        platform_set_drvdata(pdev, NULL);
 
-       free_irq(ELAPSEDTIME_IRQ, NULL);
-       free_irq(RTCLONG1_IRQ, NULL);
-       if (rtc1_base != NULL)
+       free_irq(aie_irq, pdev);
+       free_irq(pie_irq, pdev);
+       if (rtc1_base)
                iounmap(rtc1_base);
-       if (rtc2_base != NULL)
+       if (rtc2_base)
                iounmap(rtc2_base);
 
        return 0;
 }
 
-static struct platform_device *rtc_platform_device;
-
 static struct platform_driver rtc_platform_driver = {
        .probe          = rtc_probe,
        .remove         = __devexit_p(rtc_remove),
@@ -432,55 +433,12 @@ static struct platform_driver rtc_platform_driver = {
 
 static int __init vr41xx_rtc_init(void)
 {
-       int retval;
-
-       switch (current_cpu_data.cputype) {
-       case CPU_VR4111:
-       case CPU_VR4121:
-               rtc_resource[0].start = RTC1_TYPE1_START;
-               rtc_resource[0].end = RTC1_TYPE1_END;
-               rtc_resource[1].start = RTC2_TYPE1_START;
-               rtc_resource[1].end = RTC2_TYPE1_END;
-               break;
-       case CPU_VR4122:
-       case CPU_VR4131:
-       case CPU_VR4133:
-               rtc_resource[0].start = RTC1_TYPE2_START;
-               rtc_resource[0].end = RTC1_TYPE2_END;
-               rtc_resource[1].start = RTC2_TYPE2_START;
-               rtc_resource[1].end = RTC2_TYPE2_END;
-               break;
-       default:
-               return -ENODEV;
-               break;
-       }
-
-       rtc_platform_device = platform_device_alloc("RTC", -1);
-       if (rtc_platform_device == NULL)
-               return -ENOMEM;
-
-       retval = platform_device_add_resources(rtc_platform_device,
-                               rtc_resource, ARRAY_SIZE(rtc_resource));
-
-       if (retval == 0)
-               retval = platform_device_add(rtc_platform_device);
-
-       if (retval < 0) {
-               platform_device_put(rtc_platform_device);
-               return retval;
-       }
-
-       retval = platform_driver_register(&rtc_platform_driver);
-       if (retval < 0)
-               platform_device_unregister(rtc_platform_device);
-
-       return retval;
+       return platform_driver_register(&rtc_platform_driver);
 }
 
 static void __exit vr41xx_rtc_exit(void)
 {
        platform_driver_unregister(&rtc_platform_driver);
-       platform_device_unregister(rtc_platform_device);
 }
 
 module_init(vr41xx_rtc_init);
index 513d1a611aaba46edb1343ae0bb2ceab58683680..b3fae357ca494e52ac257e80b3eb223417811de7 100644 (file)
@@ -9,6 +9,9 @@
  *
  * based on a lot of other RTC drivers.
  *
+ * Information and datasheet:
+ * http://www.intersil.com/cda/deviceinfo/0,1477,X1205,00.html
+ *
  * 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.
@@ -26,7 +29,7 @@
  * Two bytes need to be written to read a single register,
  * while most other chips just require one and take the second
  * one as the data to be written. To prevent corrupting
- * unknown chips, the user must explicitely set the probe parameter.
+ * unknown chips, the user must explicitly set the probe parameter.
  */
 
 static unsigned short normal_i2c[] = { I2C_CLIENT_END };
index 8b3b0f4a157c09aaa23299a6cdbdfc8be2f1406f..ac7e8ef504cb98f5ae6d0c0d40efa3ac54059f75 100644 (file)
@@ -28,6 +28,7 @@ static struct proc_dir_entry *dasd_proc_root_entry = NULL;
 static struct proc_dir_entry *dasd_devices_entry = NULL;
 static struct proc_dir_entry *dasd_statistics_entry = NULL;
 
+#ifdef CONFIG_DASD_PROFILE
 static char *
 dasd_get_user_string(const char __user *user_buf, size_t user_len)
 {
@@ -47,6 +48,7 @@ dasd_get_user_string(const char __user *user_buf, size_t user_len)
                buffer[user_len] = 0;
        return buffer;
 }
+#endif /* CONFIG_DASD_PROFILE */
 
 static int
 dasd_devices_show(struct seq_file *m, void *v)
@@ -167,6 +169,7 @@ dasd_calc_metrics(char *page, char **start, off_t off,
        return len;
 }
 
+#ifdef CONFIG_DASD_PROFILE
 static char *
 dasd_statistics_array(char *str, unsigned int *array, int shift)
 {
@@ -180,6 +183,7 @@ dasd_statistics_array(char *str, unsigned int *array, int shift)
        str += sprintf(str,"\n");
        return str;
 }
+#endif /* CONFIG_DASD_PROFILE */
 
 static int
 dasd_statistics_read(char *page, char **start, off_t off,
index dbb99d1b6f57ffa814f3f8b37c48abc5413e50c6..c7318a125852e37c94f0359ba2ce0d7e7d4d8912 100644 (file)
@@ -72,6 +72,18 @@ typedef unsigned int sclp_cmdw_t;
 
 typedef u32 sccb_mask_t;       /* ATTENTION: assumes 32bit mask !!! */
 
+struct sccb_header {
+       u16     length;
+       u8      function_code;
+       u8      control_mask[3];
+       u16     response_code;
+} __attribute__((packed));
+
+extern u64 sclp_facilities;
+
+#define SCLP_HAS_CHP_INFO      (sclp_facilities & 0x8000000000000000ULL)
+#define SCLP_HAS_CHP_RECONFIG  (sclp_facilities & 0x2000000000000000ULL)
+
 struct gds_subvector {
        u8      length;
        u8      key;
index a66b914519b5c7dfeb74d780ff60148c870786e5..c68f5e7e63a08a694a61fa54507bad3be20811e6 100644 (file)
@@ -55,6 +55,8 @@ static int do_configure(sclp_cmdw_t cmd)
        struct chp_cfg_data *data;
        int rc;
 
+       if (!SCLP_HAS_CHP_RECONFIG)
+               return -EOPNOTSUPP;
        /* Prepare sccb. */
        data = (struct chp_cfg_data *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
        if (!data)
@@ -152,6 +154,8 @@ int sclp_chp_read_info(struct sclp_chp_info *info)
        struct chp_info_data *data;
        int rc;
 
+       if (!SCLP_HAS_CHP_INFO)
+               return -EOPNOTSUPP;
        /* Prepare sccb. */
        data = (struct chp_info_data *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
        if (!data)
index 7bcbe643b0870919b3332be25446e0948e3ff06a..a1136e052750565803b90ac478d69d3e46a70218 100644 (file)
 #include <asm/sclp.h>
 #include "sclp.h"
 
-struct sclp_readinfo_sccb s390_readinfo_sccb;
+struct sclp_readinfo_sccb {
+       struct  sccb_header header;     /* 0-7 */
+       u16     rnmax;                  /* 8-9 */
+       u8      rnsize;                 /* 10 */
+       u8      _reserved0[24 - 11];    /* 11-23 */
+       u8      loadparm[8];            /* 24-31 */
+       u8      _reserved1[48 - 32];    /* 32-47 */
+       u64     facilities;             /* 48-55 */
+       u8      _reserved2[91 - 56];    /* 56-90 */
+       u8      flags;                  /* 91 */
+       u8      _reserved3[100 - 92];   /* 92-99 */
+       u32     rnsize2;                /* 100-103 */
+       u64     rnmax2;                 /* 104-111 */
+       u8      _reserved4[4096 - 112]; /* 112-4095 */
+} __attribute__((packed, aligned(4096)));
+
+static struct sclp_readinfo_sccb __initdata early_readinfo_sccb;
+static int __initdata early_readinfo_sccb_valid;
+
+u64 sclp_facilities;
 
 void __init sclp_readinfo_early(void)
 {
-       sclp_cmdw_t command;
-       struct sccb_header *sccb;
        int ret;
+       int i;
+       struct sclp_readinfo_sccb *sccb;
+       sclp_cmdw_t commands[] = {SCLP_CMDW_READ_SCP_INFO_FORCED,
+                                 SCLP_CMDW_READ_SCP_INFO};
 
-       __ctl_set_bit(0, 9); /* enable service signal subclass mask */
-
-       sccb = &s390_readinfo_sccb.header;
-       command = SCLP_CMDW_READ_SCP_INFO_FORCED;
-       while (1) {
-               u16 response;
-
-               memset(&s390_readinfo_sccb, 0, sizeof(s390_readinfo_sccb));
-               sccb->length = sizeof(s390_readinfo_sccb);
-               sccb->control_mask[2] = 0x80;
-
-               ret = sclp_service_call(command, &s390_readinfo_sccb);
-
-               if (ret == -EIO)
-                       goto out;
-               if (ret == -EBUSY)
-                       continue;
+       /* Enable service signal subclass mask. */
+       __ctl_set_bit(0, 9);
+       sccb = &early_readinfo_sccb;
+       for (i = 0; i < ARRAY_SIZE(commands); i++) {
+               do {
+                       memset(sccb, 0, sizeof(*sccb));
+                       sccb->header.length = sizeof(*sccb);
+                       sccb->header.control_mask[2] = 0x80;
+                       ret = sclp_service_call(commands[i], sccb);
+               } while (ret == -EBUSY);
 
+               if (ret)
+                       break;
                __load_psw_mask(PSW_BASE_BITS | PSW_MASK_EXT |
                                PSW_MASK_WAIT | PSW_DEFAULT_KEY);
                local_irq_disable();
+               /*
+                * Contents of the sccb might have changed
+                * therefore a barrier is needed.
+                */
                barrier();
+               if (sccb->header.response_code == 0x10) {
+                       early_readinfo_sccb_valid = 1;
+                       break;
+               }
+               if (sccb->header.response_code != 0x1f0)
+                       break;
+       }
+       /* Disable service signal subclass mask again. */
+       __ctl_clear_bit(0, 9);
+}
 
-               response = sccb->response_code;
+void __init sclp_facilities_detect(void)
+{
+       if (!early_readinfo_sccb_valid)
+               return;
+       sclp_facilities = early_readinfo_sccb.facilities;
+}
 
-               if (response == 0x10)
-                       break;
+unsigned long long __init sclp_memory_detect(void)
+{
+       unsigned long long memsize;
+       struct sclp_readinfo_sccb *sccb;
 
-               if (response != 0x1f0 || command == SCLP_CMDW_READ_SCP_INFO)
-                       break;
+       if (!early_readinfo_sccb_valid)
+               return 0;
+       sccb = &early_readinfo_sccb;
+       if (sccb->rnsize)
+               memsize = sccb->rnsize << 20;
+       else
+               memsize = sccb->rnsize2 << 20;
+       if (sccb->rnmax)
+               memsize *= sccb->rnmax;
+       else
+               memsize *= sccb->rnmax2;
+       return memsize;
+}
 
-               command = SCLP_CMDW_READ_SCP_INFO;
-       }
-out:
-       __ctl_clear_bit(0, 9); /* disable service signal subclass mask */
+/*
+ * This function will be called after sclp_memory_detect(), which gets called
+ * early from early.c code. Therefore the sccb should have valid contents.
+ */
+void __init sclp_get_ipl_info(struct sclp_ipl_info *info)
+{
+       struct sclp_readinfo_sccb *sccb;
+
+       if (!early_readinfo_sccb_valid)
+               return;
+       sccb = &early_readinfo_sccb;
+       info->is_valid = 1;
+       if (sccb->flags & 0x2)
+               info->has_dump = 1;
+       memcpy(&info->loadparm, &sccb->loadparm, LOADPARM_LEN);
 }
index fce3dac5cb3ee38236ed8bff32a8e475153b2f18..82e6a6b253ebbbf9ddc8cbf3f7991fba90416340 100644 (file)
@@ -175,13 +175,12 @@ static long vmcp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 
 static const struct file_operations vmcp_fops = {
        .owner          = THIS_MODULE,
-       .open           = &vmcp_open,
-       .release        = &vmcp_release,
-       .read           = &vmcp_read,
-       .llseek         = &no_llseek,
-       .write          = &vmcp_write,
-       .unlocked_ioctl = &vmcp_ioctl,
-       .compat_ioctl   = &vmcp_ioctl
+       .open           = vmcp_open,
+       .release        = vmcp_release,
+       .read           = vmcp_read,
+       .write          = vmcp_write,
+       .unlocked_ioctl = vmcp_ioctl,
+       .compat_ioctl   = vmcp_ioctl
 };
 
 static struct miscdevice vmcp_dev = {
index a5a00e9ae4d01aacf3407a6e813f2ce3fb15623e..12f7a4ce82c121b7500b6cb20675e25392a72fe4 100644 (file)
@@ -835,7 +835,7 @@ static void vmlogrdr_cleanup(void)
 }
 
 
-static int vmlogrdr_init(void)
+static int __init vmlogrdr_init(void)
 {
        int rc;
        int i;
@@ -885,7 +885,7 @@ cleanup:
 }
 
 
-static void vmlogrdr_exit(void)
+static void __exit vmlogrdr_exit(void)
 {
        vmlogrdr_cleanup();
        printk (KERN_INFO "vmlogrdr: driver unloaded\n");
index 4e711a985d59afad90fc174eb7056c8718c78ca3..3712ede167235fcecd2ceeab4b0b9faac7f74461 100644 (file)
@@ -156,7 +156,7 @@ static int memcpy_real(void *dest, unsigned long src, size_t count)
        return rc;
 }
 
-static int memcpy_real_user(__user void *dest, unsigned long src, size_t count)
+static int memcpy_real_user(void __user *dest, unsigned long src, size_t count)
 {
        static char buf[4096];
        int offs = 0, size;
index ac289e6eadfe9ea1ef0a54c7d0de74b68c243108..b57d93d986c0fa9fc6bf6a8cf4923542899207e5 100644 (file)
@@ -141,8 +141,9 @@ static int s390_vary_chpid(struct chp_id chpid, int on)
 /*
  * Channel measurement related functions
  */
-static ssize_t chp_measurement_chars_read(struct kobject *kobj, char *buf,
-                                         loff_t off, size_t count)
+static ssize_t chp_measurement_chars_read(struct kobject *kobj,
+                                         struct bin_attribute *bin_attr,
+                                         char *buf, loff_t off, size_t count)
 {
        struct channel_path *chp;
        unsigned int size;
@@ -165,7 +166,6 @@ static struct bin_attribute chp_measurement_chars_attr = {
        .attr = {
                .name = "measurement_chars",
                .mode = S_IRUSR,
-               .owner = THIS_MODULE,
        },
        .size = sizeof(struct cmg_chars),
        .read = chp_measurement_chars_read,
@@ -193,8 +193,9 @@ static void chp_measurement_copy_block(struct cmg_entry *buf,
        } while (reference_buf.values[0] != buf->values[0]);
 }
 
-static ssize_t chp_measurement_read(struct kobject *kobj, char *buf,
-                                   loff_t off, size_t count)
+static ssize_t chp_measurement_read(struct kobject *kobj,
+                                   struct bin_attribute *bin_attr,
+                                   char *buf, loff_t off, size_t count)
 {
        struct channel_path *chp;
        struct channel_subsystem *css;
@@ -217,7 +218,6 @@ static struct bin_attribute chp_measurement_attr = {
        .attr = {
                .name = "measurement",
                .mode = S_IRUSR,
-               .owner = THIS_MODULE,
        },
        .size = sizeof(struct cmg_entry),
        .read = chp_measurement_read,
index 997f46874537fda00c4d0fc6f05da99fdf889883..60b9347f7c92da99dea4e5fd9687014b694d3bde 100644 (file)
@@ -27,7 +27,6 @@
 /*
  * diag210 is used under VM to get information about a virtual device
  */
-#ifdef CONFIG_64BIT
 int
 diag210(struct diag210 * addr)
 {
@@ -43,6 +42,7 @@ diag210(struct diag210 * addr)
        spin_lock_irqsave(&diag210_lock, flags);
        diag210_tmp = *addr;
 
+#ifdef CONFIG_64BIT
        asm volatile(
                "       lhi     %0,-1\n"
                "       sam31\n"
@@ -51,19 +51,8 @@ diag210(struct diag210 * addr)
                "       srl     %0,28\n"
                "1:     sam64\n"
                EX_TABLE(0b,1b)
-               : "=&d" (ccode) : "a" (__pa(&diag210_tmp)) : "cc", "memory");
-
-       *addr = diag210_tmp;
-       spin_unlock_irqrestore(&diag210_lock, flags);
-
-       return ccode;
-}
+               : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory");
 #else
-int
-diag210(struct diag210 * addr)
-{
-       int ccode;
-
        asm volatile(
                "       lhi     %0,-1\n"
                "       diag    %1,0,0x210\n"
@@ -71,11 +60,14 @@ diag210(struct diag210 * addr)
                "       srl     %0,28\n"
                "1:\n"
                EX_TABLE(0b,1b)
-               : "=&d" (ccode) : "a" (__pa(addr)) : "cc", "memory");
+               : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory");
+#endif
+
+       *addr = diag210_tmp;
+       spin_unlock_irqrestore(&diag210_lock, flags);
 
        return ccode;
 }
-#endif
 
 /*
  * Input :
index 5aac0ec3636848d60974230fcd132cd49ed110bb..90bd22014513e7c56d05b7dd7eefe586c982761a 100644 (file)
@@ -43,6 +43,7 @@ static void ap_poll_all(unsigned long);
 static void ap_poll_timeout(unsigned long);
 static int ap_poll_thread_start(void);
 static void ap_poll_thread_stop(void);
+static void ap_request_timeout(unsigned long);
 
 /**
  * Module description.
@@ -189,6 +190,7 @@ int ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length)
        case AP_RESPONSE_NORMAL:
                return 0;
        case AP_RESPONSE_Q_FULL:
+       case AP_RESPONSE_RESET_IN_PROGRESS:
                return -EBUSY;
        default:        /* Device is gone. */
                return -ENODEV;
@@ -252,6 +254,8 @@ int ap_recv(ap_qid_t qid, unsigned long long *psmid, void *msg, size_t length)
                if (status.queue_empty)
                        return -ENOENT;
                return -EBUSY;
+       case AP_RESPONSE_RESET_IN_PROGRESS:
+               return -EBUSY;
        default:
                return -ENODEV;
        }
@@ -326,11 +330,12 @@ static int ap_init_queue(ap_qid_t qid)
                        i = AP_MAX_RESET;       /* return with -ENODEV */
                        break;
                case AP_RESPONSE_RESET_IN_PROGRESS:
+                       rc = -EBUSY;
                case AP_RESPONSE_BUSY:
                default:
                        break;
                }
-               if (rc != -ENODEV)
+               if (rc != -ENODEV && rc != -EBUSY)
                        break;
                if (i < AP_MAX_RESET - 1) {
                        udelay(5);
@@ -340,6 +345,40 @@ static int ap_init_queue(ap_qid_t qid)
        return rc;
 }
 
+/**
+ * Arm request timeout if a AP device was idle and a new request is submitted.
+ */
+static void ap_increase_queue_count(struct ap_device *ap_dev)
+{
+       int timeout = ap_dev->drv->request_timeout;
+
+       ap_dev->queue_count++;
+       if (ap_dev->queue_count == 1) {
+               mod_timer(&ap_dev->timeout, jiffies + timeout);
+               ap_dev->reset = AP_RESET_ARMED;
+       }
+}
+
+/**
+ * AP device is still alive, re-schedule request timeout if there are still
+ * pending requests.
+ */
+static void ap_decrease_queue_count(struct ap_device *ap_dev)
+{
+       int timeout = ap_dev->drv->request_timeout;
+
+       ap_dev->queue_count--;
+       if (ap_dev->queue_count > 0)
+               mod_timer(&ap_dev->timeout, jiffies + timeout);
+       else
+               /**
+                * The timeout timer should to be disabled now - since
+                * del_timer_sync() is very expensive, we just tell via the
+                * reset flag to ignore the pending timeout timer.
+                */
+               ap_dev->reset = AP_RESET_IGNORE;
+}
+
 /**
  * AP device related attributes.
  */
@@ -498,6 +537,7 @@ static int ap_device_remove(struct device *dev)
        struct ap_driver *ap_drv = ap_dev->drv;
 
        ap_flush_queue(ap_dev);
+       del_timer_sync(&ap_dev->timeout);
        if (ap_drv->remove)
                ap_drv->remove(ap_dev);
        spin_lock_bh(&ap_device_lock);
@@ -759,17 +799,21 @@ static void ap_scan_bus(struct work_struct *unused)
                                      __ap_scan_bus);
                rc = ap_query_queue(qid, &queue_depth, &device_type);
                if (dev) {
+                       if (rc == -EBUSY) {
+                               set_current_state(TASK_UNINTERRUPTIBLE);
+                               schedule_timeout(AP_RESET_TIMEOUT);
+                               rc = ap_query_queue(qid, &queue_depth,
+                                                   &device_type);
+                       }
                        ap_dev = to_ap_dev(dev);
                        spin_lock_bh(&ap_dev->lock);
                        if (rc || ap_dev->unregistered) {
                                spin_unlock_bh(&ap_dev->lock);
-                               put_device(dev);
                                device_unregister(dev);
+                               put_device(dev);
                                continue;
-                       } else
-                               spin_unlock_bh(&ap_dev->lock);
-               }
-               if (dev) {
+                       }
+                       spin_unlock_bh(&ap_dev->lock);
                        put_device(dev);
                        continue;
                }
@@ -788,6 +832,8 @@ static void ap_scan_bus(struct work_struct *unused)
                INIT_LIST_HEAD(&ap_dev->pendingq);
                INIT_LIST_HEAD(&ap_dev->requestq);
                INIT_LIST_HEAD(&ap_dev->list);
+               setup_timer(&ap_dev->timeout, ap_request_timeout,
+                           (unsigned long) ap_dev);
                if (device_type == 0)
                        ap_probe_device_type(ap_dev);
                else
@@ -853,7 +899,7 @@ static int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags)
        switch (status.response_code) {
        case AP_RESPONSE_NORMAL:
                atomic_dec(&ap_poll_requests);
-               ap_dev->queue_count--;
+               ap_decrease_queue_count(ap_dev);
                list_for_each_entry(ap_msg, &ap_dev->pendingq, list) {
                        if (ap_msg->psmid != ap_dev->reply->psmid)
                                continue;
@@ -904,7 +950,7 @@ static int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags)
        switch (status.response_code) {
        case AP_RESPONSE_NORMAL:
                atomic_inc(&ap_poll_requests);
-               ap_dev->queue_count++;
+               ap_increase_queue_count(ap_dev);
                list_move_tail(&ap_msg->list, &ap_dev->pendingq);
                ap_dev->requestq_count--;
                ap_dev->pendingq_count++;
@@ -914,6 +960,7 @@ static int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags)
                *flags |= 2;
                break;
        case AP_RESPONSE_Q_FULL:
+       case AP_RESPONSE_RESET_IN_PROGRESS:
                *flags |= 2;
                break;
        case AP_RESPONSE_MESSAGE_TOO_BIG:
@@ -960,10 +1007,11 @@ static int __ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_ms
                        list_add_tail(&ap_msg->list, &ap_dev->pendingq);
                        atomic_inc(&ap_poll_requests);
                        ap_dev->pendingq_count++;
-                       ap_dev->queue_count++;
+                       ap_increase_queue_count(ap_dev);
                        ap_dev->total_request_count++;
                        break;
                case AP_RESPONSE_Q_FULL:
+               case AP_RESPONSE_RESET_IN_PROGRESS:
                        list_add_tail(&ap_msg->list, &ap_dev->requestq);
                        ap_dev->requestq_count++;
                        ap_dev->total_request_count++;
@@ -1045,6 +1093,25 @@ static void ap_poll_timeout(unsigned long unused)
        tasklet_schedule(&ap_tasklet);
 }
 
+/**
+ * Reset a not responding AP device and move all requests from the
+ * pending queue to the request queue.
+ */
+static void ap_reset(struct ap_device *ap_dev)
+{
+       int rc;
+
+       ap_dev->reset = AP_RESET_IGNORE;
+       atomic_sub(ap_dev->queue_count, &ap_poll_requests);
+       ap_dev->queue_count = 0;
+       list_splice_init(&ap_dev->pendingq, &ap_dev->requestq);
+       ap_dev->requestq_count += ap_dev->pendingq_count;
+       ap_dev->pendingq_count = 0;
+       rc = ap_init_queue(ap_dev->qid);
+       if (rc == -ENODEV)
+               ap_dev->unregistered = 1;
+}
+
 /**
  * Poll all AP devices on the bus in a round robin fashion. Continue
  * polling until bit 2^0 of the control flags is not set. If bit 2^1
@@ -1056,6 +1123,8 @@ static int __ap_poll_all(struct ap_device *ap_dev, unsigned long *flags)
        if (!ap_dev->unregistered) {
                if (ap_poll_queue(ap_dev, flags))
                        ap_dev->unregistered = 1;
+               if (ap_dev->reset == AP_RESET_DO)
+                       ap_reset(ap_dev);
        }
        spin_unlock(&ap_dev->lock);
        return 0;
@@ -1147,6 +1216,17 @@ static void ap_poll_thread_stop(void)
        mutex_unlock(&ap_poll_thread_mutex);
 }
 
+/**
+ * Handling of request timeouts
+ */
+static void ap_request_timeout(unsigned long data)
+{
+       struct ap_device *ap_dev = (struct ap_device *) data;
+
+       if (ap_dev->reset == AP_RESET_ARMED)
+               ap_dev->reset = AP_RESET_DO;
+}
+
 static void ap_reset_domain(void)
 {
        int i;
index 008559ea742b55537dc7c4c76ef6b2fc8c0bc50a..87c2d64428752716942fa30fa509744650d564eb 100644 (file)
@@ -33,6 +33,7 @@
 #define AP_DEVICES 64          /* Number of AP devices. */
 #define AP_DOMAINS 16          /* Number of AP domains. */
 #define AP_MAX_RESET 90                /* Maximum number of resets. */
+#define AP_RESET_TIMEOUT (HZ/2)        /* Time in ticks for reset timeouts. */
 #define AP_CONFIG_TIME 30      /* Time in seconds between AP bus rescans. */
 #define AP_POLL_TIME 1         /* Time in ticks between receive polls. */
 
@@ -83,6 +84,13 @@ struct ap_queue_status {
 #define AP_DEVICE_TYPE_CEX2A   6
 #define AP_DEVICE_TYPE_CEX2C   7
 
+/**
+ * AP reset flag states
+ */
+#define AP_RESET_IGNORE        0       /* request timeout will be ignored */
+#define AP_RESET_ARMED 1       /* request timeout timer is active */
+#define AP_RESET_DO    2       /* AP reset required */
+
 struct ap_device;
 struct ap_message;
 
@@ -95,6 +103,7 @@ struct ap_driver {
        /* receive is called from tasklet context */
        void (*receive)(struct ap_device *, struct ap_message *,
                        struct ap_message *);
+       int request_timeout;            /* request timeout in jiffies */
 };
 
 #define to_ap_drv(x) container_of((x), struct ap_driver, driver)
@@ -112,6 +121,8 @@ struct ap_device {
        int queue_depth;                /* AP queue depth.*/
        int device_type;                /* AP device type. */
        int unregistered;               /* marks AP device as unregistered */
+       struct timer_list timeout;      /* Timer for request timeouts. */
+       int reset;                      /* Reset required after req. timeout. */
 
        int queue_count;                /* # messages currently on AP queue. */
 
index 5bb13a9d08989b0544b1fc2bb23af1b296c45f44..08657f604b8c7c392397d9ae8b5aa3f6a8c18e4b 100644 (file)
@@ -70,6 +70,7 @@ static struct ap_driver zcrypt_cex2a_driver = {
        .remove = zcrypt_cex2a_remove,
        .receive = zcrypt_cex2a_receive,
        .ids = zcrypt_cex2a_ids,
+       .request_timeout = CEX2A_CLEANUP_TIME,
 };
 
 /**
@@ -306,18 +307,13 @@ static long zcrypt_cex2a_modexpo(struct zcrypt_device *zdev,
                goto out_free;
        init_completion(&work);
        ap_queue_message(zdev->ap_dev, &ap_msg);
-       rc = wait_for_completion_interruptible_timeout(
-                               &work, CEX2A_CLEANUP_TIME);
-       if (rc > 0)
+       rc = wait_for_completion_interruptible(&work);
+       if (rc == 0)
                rc = convert_response(zdev, &ap_msg, mex->outputdata,
                                      mex->outputdatalength);
-       else {
-               /* Signal pending or message timed out. */
+       else
+               /* Signal pending. */
                ap_cancel_message(zdev->ap_dev, &ap_msg);
-               if (rc == 0)
-                       /* Message timed out. */
-                       rc = -ETIME;
-       }
 out_free:
        kfree(ap_msg.message);
        return rc;
@@ -348,18 +344,13 @@ static long zcrypt_cex2a_modexpo_crt(struct zcrypt_device *zdev,
                goto out_free;
        init_completion(&work);
        ap_queue_message(zdev->ap_dev, &ap_msg);
-       rc = wait_for_completion_interruptible_timeout(
-                               &work, CEX2A_CLEANUP_TIME);
-       if (rc > 0)
+       rc = wait_for_completion_interruptible(&work);
+       if (rc == 0)
                rc = convert_response(zdev, &ap_msg, crt->outputdata,
                                      crt->outputdatalength);
-       else {
-               /* Signal pending or message timed out. */
+       else
+               /* Signal pending. */
                ap_cancel_message(zdev->ap_dev, &ap_msg);
-               if (rc == 0)
-                       /* Message timed out. */
-                       rc = -ETIME;
-       }
 out_free:
        kfree(ap_msg.message);
        return rc;
index 818ffe05ac00b0b02bc53678ffe556b15e318faf..6e93b4751782c4806501df1c2ce00f9120abf5dd 100644 (file)
@@ -70,6 +70,7 @@ static struct ap_driver zcrypt_pcica_driver = {
        .remove = zcrypt_pcica_remove,
        .receive = zcrypt_pcica_receive,
        .ids = zcrypt_pcica_ids,
+       .request_timeout = PCICA_CLEANUP_TIME,
 };
 
 /**
@@ -290,18 +291,13 @@ static long zcrypt_pcica_modexpo(struct zcrypt_device *zdev,
                goto out_free;
        init_completion(&work);
        ap_queue_message(zdev->ap_dev, &ap_msg);
-       rc = wait_for_completion_interruptible_timeout(
-                               &work, PCICA_CLEANUP_TIME);
-       if (rc > 0)
+       rc = wait_for_completion_interruptible(&work);
+       if (rc == 0)
                rc = convert_response(zdev, &ap_msg, mex->outputdata,
                                      mex->outputdatalength);
-       else {
-               /* Signal pending or message timed out. */
+       else
+               /* Signal pending. */
                ap_cancel_message(zdev->ap_dev, &ap_msg);
-               if (rc == 0)
-                       /* Message timed out. */
-                       rc = -ETIME;
-       }
 out_free:
        kfree(ap_msg.message);
        return rc;
@@ -332,18 +328,13 @@ static long zcrypt_pcica_modexpo_crt(struct zcrypt_device *zdev,
                goto out_free;
        init_completion(&work);
        ap_queue_message(zdev->ap_dev, &ap_msg);
-       rc = wait_for_completion_interruptible_timeout(
-                               &work, PCICA_CLEANUP_TIME);
-       if (rc > 0)
+       rc = wait_for_completion_interruptible(&work);
+       if (rc == 0)
                rc = convert_response(zdev, &ap_msg, crt->outputdata,
                                      crt->outputdatalength);
-       else {
-               /* Signal pending or message timed out. */
+       else
+               /* Signal pending. */
                ap_cancel_message(zdev->ap_dev, &ap_msg);
-               if (rc == 0)
-                       /* Message timed out. */
-                       rc = -ETIME;
-       }
 out_free:
        kfree(ap_msg.message);
        return rc;
index f295a403b29a9bedccfbab6abab87370b30619d5..d6d59bf9ac3832eb6b3f8afb03c73d8e25ae7001 100644 (file)
@@ -82,6 +82,7 @@ static struct ap_driver zcrypt_pcicc_driver = {
        .remove = zcrypt_pcicc_remove,
        .receive = zcrypt_pcicc_receive,
        .ids = zcrypt_pcicc_ids,
+       .request_timeout = PCICC_CLEANUP_TIME,
 };
 
 /**
@@ -501,18 +502,13 @@ static long zcrypt_pcicc_modexpo(struct zcrypt_device *zdev,
                goto out_free;
        init_completion(&work);
        ap_queue_message(zdev->ap_dev, &ap_msg);
-       rc = wait_for_completion_interruptible_timeout(
-                               &work, PCICC_CLEANUP_TIME);
-       if (rc > 0)
+       rc = wait_for_completion_interruptible(&work);
+       if (rc == 0)
                rc = convert_response(zdev, &ap_msg, mex->outputdata,
                                      mex->outputdatalength);
-       else {
-               /* Signal pending or message timed out. */
+       else
+               /* Signal pending. */
                ap_cancel_message(zdev->ap_dev, &ap_msg);
-               if (rc == 0)
-                       /* Message timed out. */
-                       rc = -ETIME;
-       }
 out_free:
        free_page((unsigned long) ap_msg.message);
        return rc;
@@ -544,18 +540,13 @@ static long zcrypt_pcicc_modexpo_crt(struct zcrypt_device *zdev,
                goto out_free;
        init_completion(&work);
        ap_queue_message(zdev->ap_dev, &ap_msg);
-       rc = wait_for_completion_interruptible_timeout(
-                               &work, PCICC_CLEANUP_TIME);
-       if (rc > 0)
+       rc = wait_for_completion_interruptible(&work);
+       if (rc == 0)
                rc = convert_response(zdev, &ap_msg, crt->outputdata,
                                      crt->outputdatalength);
-       else {
-               /* Signal pending or message timed out. */
+       else
+               /* Signal pending. */
                ap_cancel_message(zdev->ap_dev, &ap_msg);
-               if (rc == 0)
-                       /* Message timed out. */
-                       rc = -ETIME;
-       }
 out_free:
        free_page((unsigned long) ap_msg.message);
        return rc;
index 252443b6bd1b5a2d003d360235aaf7de14c1be67..64948788d30157c7237d43a68a8d3cdac509509f 100644 (file)
@@ -93,6 +93,7 @@ static struct ap_driver zcrypt_pcixcc_driver = {
        .remove = zcrypt_pcixcc_remove,
        .receive = zcrypt_pcixcc_receive,
        .ids = zcrypt_pcixcc_ids,
+       .request_timeout = PCIXCC_CLEANUP_TIME,
 };
 
 /**
@@ -641,18 +642,13 @@ static long zcrypt_pcixcc_modexpo(struct zcrypt_device *zdev,
                goto out_free;
        init_completion(&resp_type.work);
        ap_queue_message(zdev->ap_dev, &ap_msg);
-       rc = wait_for_completion_interruptible_timeout(
-                               &resp_type.work, PCIXCC_CLEANUP_TIME);
-       if (rc > 0)
+       rc = wait_for_completion_interruptible(&resp_type.work);
+       if (rc == 0)
                rc = convert_response_ica(zdev, &ap_msg, mex->outputdata,
                                          mex->outputdatalength);
-       else {
-               /* Signal pending or message timed out. */
+       else
+               /* Signal pending. */
                ap_cancel_message(zdev->ap_dev, &ap_msg);
-               if (rc == 0)
-                       /* Message timed out. */
-                       rc = -ETIME;
-       }
 out_free:
        free_page((unsigned long) ap_msg.message);
        return rc;
@@ -685,18 +681,13 @@ static long zcrypt_pcixcc_modexpo_crt(struct zcrypt_device *zdev,
                goto out_free;
        init_completion(&resp_type.work);
        ap_queue_message(zdev->ap_dev, &ap_msg);
-       rc = wait_for_completion_interruptible_timeout(
-                               &resp_type.work, PCIXCC_CLEANUP_TIME);
-       if (rc > 0)
+       rc = wait_for_completion_interruptible(&resp_type.work);
+       if (rc == 0)
                rc = convert_response_ica(zdev, &ap_msg, crt->outputdata,
                                          crt->outputdatalength);
-       else {
-               /* Signal pending or message timed out. */
+       else
+               /* Signal pending. */
                ap_cancel_message(zdev->ap_dev, &ap_msg);
-               if (rc == 0)
-                       /* Message timed out. */
-                       rc = -ETIME;
-       }
 out_free:
        free_page((unsigned long) ap_msg.message);
        return rc;
@@ -729,17 +720,12 @@ static long zcrypt_pcixcc_send_cprb(struct zcrypt_device *zdev,
                goto out_free;
        init_completion(&resp_type.work);
        ap_queue_message(zdev->ap_dev, &ap_msg);
-       rc = wait_for_completion_interruptible_timeout(
-                               &resp_type.work, PCIXCC_CLEANUP_TIME);
-       if (rc > 0)
+       rc = wait_for_completion_interruptible(&resp_type.work);
+       if (rc == 0)
                rc = convert_response_xcrb(zdev, &ap_msg, xcRB);
-       else {
-               /* Signal pending or message timed out. */
+       else
+               /* Signal pending. */
                ap_cancel_message(zdev->ap_dev, &ap_msg);
-               if (rc == 0)
-                       /* Message timed out. */
-                       rc = -ETIME;
-       }
 out_free:
        memset(ap_msg.message, 0x0, ap_msg.length);
        kfree(ap_msg.message);
index 65ffc21afc37525d53010daff7d0ccf86d9a3bb5..bb0287ad1aacff26f97cd80ecf6278ad946f003b 100644 (file)
@@ -991,7 +991,7 @@ static struct attribute_group qeth_osn_device_attr_group = {
 
 #define QETH_DEVICE_ATTR(_id,_name,_mode,_show,_store)                      \
 struct device_attribute dev_attr_##_id = {                                  \
-       .attr = {.name=__stringify(_name), .mode=_mode, .owner=THIS_MODULE },\
+       .attr = {.name=__stringify(_name), .mode=_mode, },\
        .show   = _show,                                                     \
        .store  = _store,                                                    \
 };
index 27852b43b9044a829ffc2d3c4bc3ff5fe09885a4..1c0d7578e791e8fbeaeaa147dc54360cc85e1c1a 100644 (file)
@@ -223,13 +223,8 @@ static int __devinit asd_common_setup(struct asd_ha_struct *asd_ha)
 {
        int err, i;
 
-       err = pci_read_config_byte(asd_ha->pcidev, PCI_REVISION_ID,
-                                  &asd_ha->revision_id);
-       if (err) {
-               asd_printk("couldn't read REVISION ID register of %s\n",
-                          pci_name(asd_ha->pcidev));
-               goto Err;
-       }
+       asd_ha->revision_id = asd_ha->pcidev->revision;
+
        err = -ENODEV;
        if (asd_ha->revision_id < AIC9410_DEV_REV_B0) {
                asd_printk("%s is revision %s (%X), which is not supported\n",
index 03bfed61bffcb0da68f8e94b51ccac757ef0673d..06c0dce3b83916095064eab9af2c440098a9bea3 100644 (file)
@@ -59,8 +59,9 @@
 struct class_device_attribute *arcmsr_host_attrs[];
 
 static ssize_t
-arcmsr_sysfs_iop_message_read(struct kobject *kobj, char *buf, loff_t off,
-    size_t count)
+arcmsr_sysfs_iop_message_read(struct kobject *kobj,
+                             struct bin_attribute *bin_attr,
+                             char *buf, loff_t off, size_t count)
 {
        struct class_device *cdev = container_of(kobj,struct class_device,kobj);
        struct Scsi_Host *host = class_to_shost(cdev);
@@ -105,8 +106,9 @@ arcmsr_sysfs_iop_message_read(struct kobject *kobj, char *buf, loff_t off,
 }
 
 static ssize_t
-arcmsr_sysfs_iop_message_write(struct kobject *kobj, char *buf, loff_t off,
-    size_t count)
+arcmsr_sysfs_iop_message_write(struct kobject *kobj,
+                              struct bin_attribute *bin_attr,
+                              char *buf, loff_t off, size_t count)
 {
        struct class_device *cdev = container_of(kobj,struct class_device,kobj);
        struct Scsi_Host *host = class_to_shost(cdev);
@@ -152,8 +154,9 @@ arcmsr_sysfs_iop_message_write(struct kobject *kobj, char *buf, loff_t off,
 }
 
 static ssize_t
-arcmsr_sysfs_iop_message_clear(struct kobject *kobj, char *buf, loff_t off,
-    size_t count)
+arcmsr_sysfs_iop_message_clear(struct kobject *kobj,
+                              struct bin_attribute *bin_attr,
+                              char *buf, loff_t off, size_t count)
 {
        struct class_device *cdev = container_of(kobj,struct class_device,kobj);
        struct Scsi_Host *host = class_to_shost(cdev);
@@ -188,7 +191,6 @@ static struct bin_attribute arcmsr_sysfs_message_read_attr = {
        .attr = {
                .name = "mu_read",
                .mode = S_IRUSR ,
-               .owner = THIS_MODULE,
        },
        .size = 1032,
        .read = arcmsr_sysfs_iop_message_read,
@@ -198,7 +200,6 @@ static struct bin_attribute arcmsr_sysfs_message_write_attr = {
        .attr = {
                .name = "mu_write",
                .mode = S_IWUSR,
-               .owner = THIS_MODULE,
        },
        .size = 1032,
        .write = arcmsr_sysfs_iop_message_write,
@@ -208,7 +209,6 @@ static struct bin_attribute arcmsr_sysfs_message_clear_attr = {
        .attr = {
                .name = "mu_clear",
                .mode = S_IWUSR,
-               .owner = THIS_MODULE,
        },
        .size = 1,
        .write = arcmsr_sysfs_iop_message_clear,
index fa6ff295e5683b544ceea30250de287fbdb362d6..b3bf77f1ec050e62785067b9d38826ccb52948d4 100644 (file)
@@ -2465,6 +2465,7 @@ restart:
 /**
  * ipr_read_trace - Dump the adapter trace
  * @kobj:              kobject struct
+ * @bin_attr:          bin_attribute struct
  * @buf:               buffer
  * @off:               offset
  * @count:             buffer size
@@ -2472,8 +2473,9 @@ restart:
  * Return value:
  *     number of bytes printed to buffer
  **/
-static ssize_t ipr_read_trace(struct kobject *kobj, char *buf,
-                             loff_t off, size_t count)
+static ssize_t ipr_read_trace(struct kobject *kobj,
+                             struct bin_attribute *bin_attr,
+                             char *buf, loff_t off, size_t count)
 {
        struct class_device *cdev = container_of(kobj,struct class_device,kobj);
        struct Scsi_Host *shost = class_to_shost(cdev);
@@ -3166,6 +3168,7 @@ static struct class_device_attribute *ipr_ioa_attrs[] = {
 /**
  * ipr_read_dump - Dump the adapter
  * @kobj:              kobject struct
+ * @bin_attr:          bin_attribute struct
  * @buf:               buffer
  * @off:               offset
  * @count:             buffer size
@@ -3173,8 +3176,9 @@ static struct class_device_attribute *ipr_ioa_attrs[] = {
  * Return value:
  *     number of bytes printed to buffer
  **/
-static ssize_t ipr_read_dump(struct kobject *kobj, char *buf,
-                             loff_t off, size_t count)
+static ssize_t ipr_read_dump(struct kobject *kobj,
+                            struct bin_attribute *bin_attr,
+                            char *buf, loff_t off, size_t count)
 {
        struct class_device *cdev = container_of(kobj,struct class_device,kobj);
        struct Scsi_Host *shost = class_to_shost(cdev);
@@ -3327,6 +3331,7 @@ static int ipr_free_dump(struct ipr_ioa_cfg *ioa_cfg)
 /**
  * ipr_write_dump - Setup dump state of adapter
  * @kobj:              kobject struct
+ * @bin_attr:          bin_attribute struct
  * @buf:               buffer
  * @off:               offset
  * @count:             buffer size
@@ -3334,8 +3339,9 @@ static int ipr_free_dump(struct ipr_ioa_cfg *ioa_cfg)
  * Return value:
  *     number of bytes printed to buffer
  **/
-static ssize_t ipr_write_dump(struct kobject *kobj, char *buf,
-                             loff_t off, size_t count)
+static ssize_t ipr_write_dump(struct kobject *kobj,
+                             struct bin_attribute *bin_attr,
+                             char *buf, loff_t off, size_t count)
 {
        struct class_device *cdev = container_of(kobj,struct class_device,kobj);
        struct Scsi_Host *shost = class_to_shost(cdev);
@@ -5367,18 +5373,12 @@ static const u16 ipr_blocked_processors[] = {
  **/
 static int ipr_invalid_adapter(struct ipr_ioa_cfg *ioa_cfg)
 {
-       u8 rev_id;
        int i;
 
-       if (ioa_cfg->type == 0x5702) {
-               if (pci_read_config_byte(ioa_cfg->pdev, PCI_REVISION_ID,
-                                        &rev_id) == PCIBIOS_SUCCESSFUL) {
-                       if (rev_id < 4) {
-                               for (i = 0; i < ARRAY_SIZE(ipr_blocked_processors); i++){
-                                       if (__is_processor(ipr_blocked_processors[i]))
-                                               return 1;
-                               }
-                       }
+       if ((ioa_cfg->type == 0x5702) && (ioa_cfg->pdev->revision < 4)) {
+               for (i = 0; i < ARRAY_SIZE(ipr_blocked_processors); i++){
+                       if (__is_processor(ipr_blocked_processors[i]))
+                               return 1;
                }
        }
        return 0;
@@ -7535,13 +7535,7 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev,
        else
                ioa_cfg->transop_timeout = IPR_OPERATIONAL_TIMEOUT;
 
-       rc = pci_read_config_byte(pdev, PCI_REVISION_ID, &ioa_cfg->revid);
-
-       if (rc != PCIBIOS_SUCCESSFUL) {
-               dev_err(&pdev->dev, "Failed to read PCI revision ID\n");
-               rc = -EIO;
-               goto out_scsi_host_put;
-       }
+       ioa_cfg->revid = pdev->revision;
 
        ipr_regs_pci = pci_resource_start(pdev, 0);
 
index 8b704f73055a43d075762bb1f1e4dd84fbd39b2a..40f148e0833f485034e1f30f5a93756f05abb42c 100644 (file)
@@ -7148,7 +7148,6 @@ ips_init_phase1(struct pci_dev *pci_dev, int *indexPtr)
        uint32_t mem_addr;
        uint32_t io_len;
        uint32_t mem_len;
-       uint8_t revision_id;
        uint8_t bus;
        uint8_t func;
        uint8_t irq;
@@ -7227,12 +7226,6 @@ ips_init_phase1(struct pci_dev *pci_dev, int *indexPtr)
                }
        }
 
-       /* get the revision ID */
-       if (pci_read_config_byte(pci_dev, PCI_REVISION_ID, &revision_id)) {
-               IPS_PRINTK(KERN_WARNING, pci_dev, "Can't get revision id.\n");
-               return -1;
-       }
-
        subdevice_id = pci_dev->subsystem_device;
 
        /* found a controller */
@@ -7258,7 +7251,7 @@ ips_init_phase1(struct pci_dev *pci_dev, int *indexPtr)
        ha->mem_ptr = mem_ptr;
        ha->ioremap_ptr = ioremap_ptr;
        ha->host_num = (uint32_t) index;
-       ha->revision_id = revision_id;
+       ha->revision_id = pci_dev->revision;
        ha->slot_num = PCI_SLOT(pci_dev->devfn);
        ha->device_id = pci_dev->device;
        ha->subdevice_id = subdevice_id;
index e34442e405e8a8aa96e05f0f195b20958a9a2ddb..23e90c5f8f352be326ad3b9f6ec351cac7955ad0 100644 (file)
@@ -38,8 +38,10 @@ static int sas_disable_routing(struct domain_device *dev,  u8 *sas_addr);
 
 #if 0
 /* FIXME: smp needs to migrate into the sas class */
-static ssize_t smp_portal_read(struct kobject *, char *, loff_t, size_t);
-static ssize_t smp_portal_write(struct kobject *, char *, loff_t, size_t);
+static ssize_t smp_portal_read(struct kobject *, struct bin_attribute *,
+                              char *, loff_t, size_t);
+static ssize_t smp_portal_write(struct kobject *, struct bin_attribute *,
+                               char *, loff_t, size_t);
 #endif
 
 /* ---------- SMP task management ---------- */
@@ -1368,7 +1370,6 @@ static void sas_ex_smp_hook(struct domain_device *dev)
        memset(bin_attr, 0, sizeof(*bin_attr));
 
        bin_attr->attr.name = SMP_BIN_ATTR_NAME;
-       bin_attr->attr.owner = THIS_MODULE;
        bin_attr->attr.mode = 0600;
 
        bin_attr->size = 0;
@@ -1846,8 +1847,9 @@ out:
 #if 0
 /* ---------- SMP portal ---------- */
 
-static ssize_t smp_portal_write(struct kobject *kobj, char *buf, loff_t offs,
-                               size_t size)
+static ssize_t smp_portal_write(struct kobject *kobj,
+                               struct bin_attribute *bin_attr,
+                               char *buf, loff_t offs, size_t size)
 {
        struct domain_device *dev = to_dom_device(kobj);
        struct expander_device *ex = &dev->ex_dev;
@@ -1873,8 +1875,9 @@ static ssize_t smp_portal_write(struct kobject *kobj, char *buf, loff_t offs,
        return size;
 }
 
-static ssize_t smp_portal_read(struct kobject *kobj, char *buf, loff_t offs,
-                              size_t size)
+static ssize_t smp_portal_read(struct kobject *kobj,
+                              struct bin_attribute *bin_attr,
+                              char *buf, loff_t offs, size_t size)
 {
        struct domain_device *dev = to_dom_device(kobj);
        struct expander_device *ex = &dev->ex_dev;
index 95fe77e816f80a756b937f6012b8ab989e14ac74..5dfda9778c80b009b03ca242d23c0d9614099631 100644 (file)
@@ -1133,7 +1133,8 @@ struct class_device_attribute *lpfc_host_attrs[] = {
 };
 
 static ssize_t
-sysfs_ctlreg_write(struct kobject *kobj, char *buf, loff_t off, size_t count)
+sysfs_ctlreg_write(struct kobject *kobj, struct bin_attribute *bin_attr,
+                  char *buf, loff_t off, size_t count)
 {
        size_t buf_off;
        struct Scsi_Host *host = class_to_shost(container_of(kobj,
@@ -1165,7 +1166,8 @@ sysfs_ctlreg_write(struct kobject *kobj, char *buf, loff_t off, size_t count)
 }
 
 static ssize_t
-sysfs_ctlreg_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
+sysfs_ctlreg_read(struct kobject *kobj, struct bin_attribute *bin_attr,
+                 char *buf, loff_t off, size_t count)
 {
        size_t buf_off;
        uint32_t * tmp_ptr;
@@ -1200,7 +1202,6 @@ static struct bin_attribute sysfs_ctlreg_attr = {
        .attr = {
                .name = "ctlreg",
                .mode = S_IRUSR | S_IWUSR,
-               .owner = THIS_MODULE,
        },
        .size = 256,
        .read = sysfs_ctlreg_read,
@@ -1222,7 +1223,8 @@ sysfs_mbox_idle (struct lpfc_hba * phba)
 }
 
 static ssize_t
-sysfs_mbox_write(struct kobject *kobj, char *buf, loff_t off, size_t count)
+sysfs_mbox_write(struct kobject *kobj, struct bin_attribute *bin_attr,
+                char *buf, loff_t off, size_t count)
 {
        struct Scsi_Host * host =
                class_to_shost(container_of(kobj, struct class_device, kobj));
@@ -1274,7 +1276,8 @@ sysfs_mbox_write(struct kobject *kobj, char *buf, loff_t off, size_t count)
 }
 
 static ssize_t
-sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
+sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr,
+               char *buf, loff_t off, size_t count)
 {
        struct Scsi_Host *host =
                class_to_shost(container_of(kobj, struct class_device,
@@ -1422,7 +1425,6 @@ static struct bin_attribute sysfs_mbox_attr = {
        .attr = {
                .name = "mbox",
                .mode = S_IRUSR | S_IWUSR,
-               .owner = THIS_MODULE,
        },
        .size = MAILBOX_CMD_SIZE,
        .read = sysfs_mbox_read,
index dcb4ba0ecee1825067b2344562ab0e21d4df0601..955b2e48d04192579615d6030311e43688b2aae9 100644 (file)
@@ -1578,10 +1578,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
        INIT_LIST_HEAD(&phba->fc_nodes);
 
        pci_set_master(pdev);
-       retval = pci_set_mwi(pdev);
-       if (retval)
-               dev_printk(KERN_WARNING, &pdev->dev,
-                          "Warning: pci_set_mwi returned %d\n", retval);
+       pci_try_set_mwi(pdev);
 
        if (pci_set_dma_mask(phba->pcidev, DMA_64BIT_MASK) != 0)
                if (pci_set_dma_mask(phba->pcidev, DMA_32BIT_MASK) != 0)
index f6f561d26bf0c9c317d133e9ee9110444856eb6a..3e9765f0281d948669347b1ef6e309ce36122adb 100644 (file)
@@ -3487,15 +3487,6 @@ static int nsp32_resume(struct pci_dev *pdev)
        return 0;
 }
 
-/* Enable wake event */
-static int nsp32_enable_wake(struct pci_dev *pdev, pci_power_t state, int enable)
-{
-       struct Scsi_Host *host = pci_get_drvdata(pdev);
-
-       nsp32_msg(KERN_INFO, "pci-enable_wake: stub, pdev=0x%p, enable=%d, slot=%s, host=0x%p", pdev, enable, pci_name(pdev), host);
-
-       return 0;
-}
 #endif
 
 /************************************************************************
@@ -3571,7 +3562,6 @@ static struct pci_driver nsp32_driver = {
 #ifdef CONFIG_PM
        .suspend        = nsp32_suspend, 
        .resume         = nsp32_resume, 
-       .enable_wake    = nsp32_enable_wake,
 #endif
 };
 
index 8081b637d97e06550253eb0ddb12bfba0ef27ba5..942db9de785efb274ff10aa311e93d994e1fd885 100644 (file)
@@ -11,8 +11,9 @@
 /* SYSFS attributes --------------------------------------------------------- */
 
 static ssize_t
-qla2x00_sysfs_read_fw_dump(struct kobject *kobj, char *buf, loff_t off,
-    size_t count)
+qla2x00_sysfs_read_fw_dump(struct kobject *kobj,
+                          struct bin_attribute *bin_attr,
+                          char *buf, loff_t off, size_t count)
 {
        struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
            struct device, kobj)));
@@ -31,8 +32,9 @@ qla2x00_sysfs_read_fw_dump(struct kobject *kobj, char *buf, loff_t off,
 }
 
 static ssize_t
-qla2x00_sysfs_write_fw_dump(struct kobject *kobj, char *buf, loff_t off,
-    size_t count)
+qla2x00_sysfs_write_fw_dump(struct kobject *kobj,
+                           struct bin_attribute *bin_attr,
+                           char *buf, loff_t off, size_t count)
 {
        struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
            struct device, kobj)));
@@ -73,7 +75,6 @@ static struct bin_attribute sysfs_fw_dump_attr = {
        .attr = {
                .name = "fw_dump",
                .mode = S_IRUSR | S_IWUSR,
-               .owner = THIS_MODULE,
        },
        .size = 0,
        .read = qla2x00_sysfs_read_fw_dump,
@@ -81,8 +82,9 @@ static struct bin_attribute sysfs_fw_dump_attr = {
 };
 
 static ssize_t
-qla2x00_sysfs_read_nvram(struct kobject *kobj, char *buf, loff_t off,
-    size_t count)
+qla2x00_sysfs_read_nvram(struct kobject *kobj,
+                        struct bin_attribute *bin_attr,
+                        char *buf, loff_t off, size_t count)
 {
        struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
            struct device, kobj)));
@@ -101,8 +103,9 @@ qla2x00_sysfs_read_nvram(struct kobject *kobj, char *buf, loff_t off,
 }
 
 static ssize_t
-qla2x00_sysfs_write_nvram(struct kobject *kobj, char *buf, loff_t off,
-    size_t count)
+qla2x00_sysfs_write_nvram(struct kobject *kobj,
+                         struct bin_attribute *bin_attr,
+                         char *buf, loff_t off, size_t count)
 {
        struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
            struct device, kobj)));
@@ -149,7 +152,6 @@ static struct bin_attribute sysfs_nvram_attr = {
        .attr = {
                .name = "nvram",
                .mode = S_IRUSR | S_IWUSR,
-               .owner = THIS_MODULE,
        },
        .size = 512,
        .read = qla2x00_sysfs_read_nvram,
@@ -157,8 +159,9 @@ static struct bin_attribute sysfs_nvram_attr = {
 };
 
 static ssize_t
-qla2x00_sysfs_read_optrom(struct kobject *kobj, char *buf, loff_t off,
-    size_t count)
+qla2x00_sysfs_read_optrom(struct kobject *kobj,
+                         struct bin_attribute *bin_attr,
+                         char *buf, loff_t off, size_t count)
 {
        struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
            struct device, kobj)));
@@ -176,8 +179,9 @@ qla2x00_sysfs_read_optrom(struct kobject *kobj, char *buf, loff_t off,
 }
 
 static ssize_t
-qla2x00_sysfs_write_optrom(struct kobject *kobj, char *buf, loff_t off,
-    size_t count)
+qla2x00_sysfs_write_optrom(struct kobject *kobj,
+                          struct bin_attribute *bin_attr,
+                          char *buf, loff_t off, size_t count)
 {
        struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
            struct device, kobj)));
@@ -198,7 +202,6 @@ static struct bin_attribute sysfs_optrom_attr = {
        .attr = {
                .name = "optrom",
                .mode = S_IRUSR | S_IWUSR,
-               .owner = THIS_MODULE,
        },
        .size = OPTROM_SIZE_24XX,
        .read = qla2x00_sysfs_read_optrom,
@@ -206,8 +209,9 @@ static struct bin_attribute sysfs_optrom_attr = {
 };
 
 static ssize_t
-qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj, char *buf, loff_t off,
-    size_t count)
+qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj,
+                              struct bin_attribute *bin_attr,
+                              char *buf, loff_t off, size_t count)
 {
        struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
            struct device, kobj)));
@@ -279,15 +283,15 @@ static struct bin_attribute sysfs_optrom_ctl_attr = {
        .attr = {
                .name = "optrom_ctl",
                .mode = S_IWUSR,
-               .owner = THIS_MODULE,
        },
        .size = 0,
        .write = qla2x00_sysfs_write_optrom_ctl,
 };
 
 static ssize_t
-qla2x00_sysfs_read_vpd(struct kobject *kobj, char *buf, loff_t off,
-    size_t count)
+qla2x00_sysfs_read_vpd(struct kobject *kobj,
+                      struct bin_attribute *bin_attr,
+                      char *buf, loff_t off, size_t count)
 {
        struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
            struct device, kobj)));
@@ -305,8 +309,9 @@ qla2x00_sysfs_read_vpd(struct kobject *kobj, char *buf, loff_t off,
 }
 
 static ssize_t
-qla2x00_sysfs_write_vpd(struct kobject *kobj, char *buf, loff_t off,
-    size_t count)
+qla2x00_sysfs_write_vpd(struct kobject *kobj,
+                       struct bin_attribute *bin_attr,
+                       char *buf, loff_t off, size_t count)
 {
        struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
            struct device, kobj)));
@@ -327,7 +332,6 @@ static struct bin_attribute sysfs_vpd_attr = {
        .attr = {
                .name = "vpd",
                .mode = S_IRUSR | S_IWUSR,
-               .owner = THIS_MODULE,
        },
        .size = 0,
        .read = qla2x00_sysfs_read_vpd,
@@ -335,8 +339,9 @@ static struct bin_attribute sysfs_vpd_attr = {
 };
 
 static ssize_t
-qla2x00_sysfs_read_sfp(struct kobject *kobj, char *buf, loff_t off,
-    size_t count)
+qla2x00_sysfs_read_sfp(struct kobject *kobj,
+                      struct bin_attribute *bin_attr,
+                      char *buf, loff_t off, size_t count)
 {
        struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
            struct device, kobj)));
@@ -375,7 +380,6 @@ static struct bin_attribute sysfs_sfp_attr = {
        .attr = {
                .name = "sfp",
                .mode = S_IRUSR | S_IWUSR,
-               .owner = THIS_MODULE,
        },
        .size = SFP_DEV_SIZE * 2,
        .read = qla2x00_sysfs_read_sfp,
index 2a45aec4ff29e6499a36456d24f6f496caf9ff4a..cf94f8636ba5af6b5504d5acb6995f0e9a7aaeae 100644 (file)
@@ -296,7 +296,7 @@ qla24xx_pci_config(scsi_qla_host_t *ha)
        d &= ~PCI_ROM_ADDRESS_ENABLE;
        pci_write_config_dword(ha->pdev, PCI_ROM_ADDRESS, d);
 
-       pci_read_config_word(ha->pdev, PCI_REVISION_ID, &ha->chip_revision);
+       ha->chip_revision = ha->pdev->revision;
 
        /* Get PCI bus information. */
        spin_lock_irqsave(&ha->hardware_lock, flags);
index 315ea99164566b01458c4a1d676b7b1aa37fdb83..2adbed4e10f350ac753d7db2f1be860eb01e6243 100644 (file)
@@ -556,7 +556,7 @@ choice
 
 config SERIAL_BFIN_DMA
        bool "DMA mode"
-       depends on DMA_UNCACHED_1M
+       depends on DMA_UNCACHED_1M && !KGDB_UART
        help
          This driver works under DMA mode. If this option is selected, the
          blackfin simple dma driver is also enabled.
@@ -599,7 +599,7 @@ config UART0_RTS_PIN
 
 config SERIAL_BFIN_UART1
        bool "Enable UART1"
-       depends on SERIAL_BFIN && (BF534 || BF536 || BF537)
+       depends on SERIAL_BFIN && (BF534 || BF536 || BF537 || BF54x)
        help
          Enable UART1
 
@@ -612,18 +612,58 @@ config BFIN_UART1_CTSRTS
 
 config UART1_CTS_PIN
        int "UART1 CTS pin"
-       depends on BFIN_UART1_CTSRTS
+       depends on BFIN_UART1_CTSRTS && (BF53x || BF561)
        default -1
        help
          Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.
 
 config UART1_RTS_PIN
        int "UART1 RTS pin"
-       depends on BFIN_UART1_CTSRTS
+       depends on BFIN_UART1_CTSRTS && (BF53x || BF561)
        default -1
        help
          Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.
 
+config SERIAL_BFIN_UART2
+       bool "Enable UART2"
+       depends on SERIAL_BFIN && (BF54x)
+       help
+         Enable UART2
+
+config BFIN_UART2_CTSRTS
+       bool "Enable UART2 hardware flow control"
+       depends on SERIAL_BFIN_UART2
+       help
+         Enable hardware flow control in the driver. Using GPIO emulate the CTS/RTS
+         signal.
+
+config UART2_CTS_PIN
+       int "UART2 CTS pin"
+       depends on BFIN_UART2_CTSRTS
+       default -1
+       help
+         Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.
+
+config UART2_RTS_PIN
+       int "UART2 RTS pin"
+       depends on BFIN_UART2_CTSRTS
+       default -1
+       help
+         Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.
+
+config SERIAL_BFIN_UART3
+       bool "Enable UART3"
+       depends on SERIAL_BFIN && (BF54x)
+       help
+         Enable UART3
+
+config BFIN_UART3_CTSRTS
+       bool "Enable UART3 hardware flow control"
+       depends on SERIAL_BFIN_UART3
+       help
+         Enable hardware flow control in the driver. Using GPIO emulate the CTS/RTS
+         signal.
+
 config SERIAL_IMX
        bool "IMX serial port support"
        depends on ARM && ARCH_IMX
index 22569bd5d821e37e7f0b9f5aaaf15909831032dc..66c92bc36f3d1ae51cabbada195a73300dccbf27 100644 (file)
 #include <linux/tty_flip.h>
 #include <linux/serial_core.h>
 
+#ifdef CONFIG_KGDB_UART
+#include <linux/kgdb.h>
+#include <asm/irq_regs.h>
+#endif
+
 #include <asm/gpio.h>
 #include <asm/mach/bfin_serial_5xx.h>
 
@@ -81,8 +86,21 @@ static void bfin_serial_stop_tx(struct uart_port *port)
 {
        struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
 
+#ifdef CONFIG_BF54x
+       while (!(UART_GET_LSR(uart) & TEMT))
+               continue;
+#endif
+
 #ifdef CONFIG_SERIAL_BFIN_DMA
        disable_dma(uart->tx_dma_channel);
+#else
+#ifdef CONFIG_BF54x
+       /* Waiting for Transmission Finished */
+       while (!(UART_GET_LSR(uart) & TFI))
+               continue;
+       /* Clear TFI bit */
+       UART_PUT_LSR(uart, TFI);
+       UART_CLEAR_IER(uart, ETBEI);
 #else
        unsigned short ier;
 
@@ -90,6 +108,7 @@ static void bfin_serial_stop_tx(struct uart_port *port)
        ier &= ~ETBEI;
        UART_PUT_IER(uart, ier);
 #endif
+#endif
 }
 
 /*
@@ -101,6 +120,9 @@ static void bfin_serial_start_tx(struct uart_port *port)
 
 #ifdef CONFIG_SERIAL_BFIN_DMA
        bfin_serial_dma_tx_chars(uart);
+#else
+#ifdef CONFIG_BF54x
+       UART_SET_IER(uart, ETBEI);
 #else
        unsigned short ier;
        ier = UART_GET_IER(uart);
@@ -108,6 +130,7 @@ static void bfin_serial_start_tx(struct uart_port *port)
        UART_PUT_IER(uart, ier);
        bfin_serial_tx_chars(uart);
 #endif
+#endif
 }
 
 /*
@@ -116,11 +139,18 @@ static void bfin_serial_start_tx(struct uart_port *port)
 static void bfin_serial_stop_rx(struct uart_port *port)
 {
        struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
+#ifdef CONFIG_BF54x
+       UART_CLEAR_IER(uart, ERBFI);
+#else
        unsigned short ier;
 
        ier = UART_GET_IER(uart);
+#ifdef CONFIG_KGDB_UART
+       if (uart->port.line != CONFIG_KGDB_UART_PORT)
+#endif
        ier &= ~ERBFI;
        UART_PUT_IER(uart, ier);
+#endif
 }
 
 /*
@@ -130,6 +160,49 @@ static void bfin_serial_enable_ms(struct uart_port *port)
 {
 }
 
+#ifdef CONFIG_KGDB_UART
+static int kgdb_entry_state;
+
+void kgdb_put_debug_char(int chr)
+{
+       struct bfin_serial_port *uart;
+       
+       if (CONFIG_KGDB_UART_PORT<0 || CONFIG_KGDB_UART_PORT>=NR_PORTS)
+               uart = &bfin_serial_ports[0];
+       else
+               uart = &bfin_serial_ports[CONFIG_KGDB_UART_PORT];
+       
+       while (!(UART_GET_LSR(uart) & THRE)) {
+               __builtin_bfin_ssync();
+       }
+       UART_PUT_LCR(uart, UART_GET_LCR(uart)&(~DLAB));
+       __builtin_bfin_ssync();
+       UART_PUT_CHAR(uart, (unsigned char)chr);
+       __builtin_bfin_ssync();
+}
+
+int kgdb_get_debug_char(void)
+{
+       struct bfin_serial_port *uart;
+       unsigned char chr;
+
+       if (CONFIG_KGDB_UART_PORT<0 || CONFIG_KGDB_UART_PORT>=NR_PORTS)
+               uart = &bfin_serial_ports[0];
+       else
+               uart = &bfin_serial_ports[CONFIG_KGDB_UART_PORT];
+       
+       while(!(UART_GET_LSR(uart) & DR)) {
+               __builtin_bfin_ssync();
+       }
+       UART_PUT_LCR(uart, UART_GET_LCR(uart)&(~DLAB));
+       __builtin_bfin_ssync();
+       chr = UART_GET_CHAR(uart);
+       __builtin_bfin_ssync();
+
+       return chr;
+}
+#endif
+
 #ifdef CONFIG_SERIAL_BFIN_PIO
 static void local_put_char(struct bfin_serial_port *uart, char ch)
 {
@@ -152,6 +225,9 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart)
 {
        struct tty_struct *tty = uart->port.info->tty;
        unsigned int status, ch, flg;
+#ifdef CONFIG_KGDB_UART
+       struct pt_regs *regs = get_irq_regs();
+#endif
 #ifdef BF533_FAMILY
        static int in_break = 0;
 #endif
@@ -160,6 +236,27 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart)
        ch = UART_GET_CHAR(uart);
        uart->port.icount.rx++;
 
+#ifdef CONFIG_KGDB_UART
+       if (uart->port.line == CONFIG_KGDB_UART_PORT) {
+               if (uart->port.cons->index == CONFIG_KGDB_UART_PORT && ch == 0x1) { /* Ctrl + A */
+                       kgdb_breakkey_pressed(regs);
+                       return;
+               } else if (kgdb_entry_state == 0 && ch == '$') {/* connection from KGDB */
+                       kgdb_entry_state = 1;
+               } else if (kgdb_entry_state == 1 && ch == 'q') {
+                       kgdb_entry_state = 0;
+                       kgdb_breakkey_pressed(regs);
+                       return;
+               } else if (ch == 0x3) {/* Ctrl + C */
+                       kgdb_entry_state = 0;
+                       kgdb_breakkey_pressed(regs);
+                       return;
+               } else {
+                       kgdb_entry_state = 0;
+               }
+       }
+#endif
 #ifdef BF533_FAMILY
        /* The BF533 family of processors have a nice misbehavior where
         * they continuously generate characters for a "single" break.
@@ -250,10 +347,21 @@ static irqreturn_t bfin_serial_rx_int(int irq, void *dev_id)
 {
        struct bfin_serial_port *uart = dev_id;
 
+#ifdef CONFIG_BF54x
+       unsigned short status;
+       spin_lock(&uart->port.lock);
+       status = UART_GET_LSR(uart);
+       while ((UART_GET_IER(uart) & ERBFI) && (status & DR)) {
+               bfin_serial_rx_chars(uart);
+               status = UART_GET_LSR(uart);
+       }
+       spin_unlock(&uart->port.lock);
+#else
        spin_lock(&uart->port.lock);
        while ((UART_GET_IIR(uart) & IIR_STATUS) == IIR_RX_READY)
                bfin_serial_rx_chars(uart);
        spin_unlock(&uart->port.lock);
+#endif
        return IRQ_HANDLED;
 }
 
@@ -261,10 +369,21 @@ static irqreturn_t bfin_serial_tx_int(int irq, void *dev_id)
 {
        struct bfin_serial_port *uart = dev_id;
 
+#ifdef CONFIG_BF54x
+       unsigned short status;
+       spin_lock(&uart->port.lock);
+       status = UART_GET_LSR(uart);
+       while ((UART_GET_IER(uart) & ETBEI) && (status & THRE)) {
+               bfin_serial_tx_chars(uart);
+               status = UART_GET_LSR(uart);
+       }
+       spin_unlock(&uart->port.lock);
+#else
        spin_lock(&uart->port.lock);
        while ((UART_GET_IIR(uart) & IIR_STATUS) == IIR_TX_READY)
                bfin_serial_tx_chars(uart);
        spin_unlock(&uart->port.lock);
+#endif
        return IRQ_HANDLED;
 }
 
@@ -275,7 +394,6 @@ static void bfin_serial_do_work(struct work_struct *work)
 
        bfin_serial_mctrl_check(uart);
 }
-
 #endif
 
 #ifdef CONFIG_SERIAL_BFIN_DMA
@@ -324,9 +442,13 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart)
        set_dma_x_count(uart->tx_dma_channel, uart->tx_count);
        set_dma_x_modify(uart->tx_dma_channel, 1);
        enable_dma(uart->tx_dma_channel);
+#ifdef CONFIG_BF54x
+       UART_SET_IER(uart, ETBEI);
+#else
        ier = UART_GET_IER(uart);
        ier |= ETBEI;
        UART_PUT_IER(uart, ier);
+#endif
        spin_unlock_irqrestore(&uart->port.lock, flags);
 }
 
@@ -406,9 +528,13 @@ static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id)
        if (!(get_dma_curr_irqstat(uart->tx_dma_channel)&DMA_RUN)) {
                clear_dma_irqstat(uart->tx_dma_channel);
                disable_dma(uart->tx_dma_channel);
+#ifdef CONFIG_BF54x
+               UART_CLEAR_IER(uart, ETBEI);
+#else
                ier = UART_GET_IER(uart);
                ier &= ~ETBEI;
                UART_PUT_IER(uart, ier);
+#endif
                xmit->tail = (xmit->tail+uart->tx_count) &(UART_XMIT_SIZE -1);
                uart->port.icount.tx+=uart->tx_count;
 
@@ -571,7 +697,11 @@ static int bfin_serial_startup(struct uart_port *port)
        uart->rx_dma_timer.expires = jiffies + DMA_RX_FLUSH_JIFFIES;
        add_timer(&(uart->rx_dma_timer));
 #else
+# ifdef        CONFIG_KGDB_UART
+       if (uart->port.line != CONFIG_KGDB_UART_PORT && request_irq
+# else
        if (request_irq
+# endif
            (uart->port.irq, bfin_serial_rx_int, IRQF_DISABLED,
             "BFIN_UART_RX", uart)) {
                printk(KERN_NOTICE "Unable to attach BlackFin UART RX interrupt\n");
@@ -586,7 +716,11 @@ static int bfin_serial_startup(struct uart_port *port)
                return -EBUSY;
        }
 #endif
+#ifdef CONFIG_BF54x
+       UART_SET_IER(uart, ERBFI);
+#else
        UART_PUT_IER(uart, UART_GET_IER(uart) | ERBFI);
+#endif
        return 0;
 }
 
@@ -601,6 +735,9 @@ static void bfin_serial_shutdown(struct uart_port *port)
        free_dma(uart->rx_dma_channel);
        del_timer(&(uart->rx_dma_timer));
 #else
+#ifdef CONFIG_KGDB_UART
+       if (uart->port.line != CONFIG_KGDB_UART_PORT)
+#endif
        free_irq(uart->port.irq, uart);
        free_irq(uart->port.irq+1, uart);
 #endif
@@ -674,29 +811,41 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios,
 
        /* Disable UART */
        ier = UART_GET_IER(uart);
+#ifdef CONFIG_BF54x
+       UART_CLEAR_IER(uart, 0xF);
+#else
        UART_PUT_IER(uart, 0);
+#endif
 
+#ifndef CONFIG_BF54x
        /* Set DLAB in LCR to Access DLL and DLH */
        val = UART_GET_LCR(uart);
        val |= DLAB;
        UART_PUT_LCR(uart, val);
        SSYNC();
+#endif
 
        UART_PUT_DLL(uart, quot & 0xFF);
        SSYNC();
        UART_PUT_DLH(uart, (quot >> 8) & 0xFF);
        SSYNC();
 
+#ifndef CONFIG_BF54x
        /* Clear DLAB in LCR to Access THR RBR IER */
        val = UART_GET_LCR(uart);
        val &= ~DLAB;
        UART_PUT_LCR(uart, val);
        SSYNC();
+#endif
 
        UART_PUT_LCR(uart, lcr);
 
        /* Enable UART */
+#ifdef CONFIG_BF54x
+       UART_SET_IER(uart, ier);
+#else
        UART_PUT_IER(uart, ier);
+#endif
 
        val = UART_GET_GCTL(uart);
        val |= UCEN;
@@ -808,15 +957,15 @@ static void __init bfin_serial_init_ports(void)
                        bfin_serial_resource[i].uart_rts_pin;
 #endif
                bfin_serial_hw_init(&bfin_serial_ports[i]);
-
        }
+
 }
 
 #ifdef CONFIG_SERIAL_BFIN_CONSOLE
 static void bfin_serial_console_putchar(struct uart_port *port, int ch)
 {
        struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
-       while (!(UART_GET_LSR(uart)))
+       while (!(UART_GET_LSR(uart) & THRE))
                barrier();
        UART_PUT_CHAR(uart, ch);
        SSYNC();
@@ -868,18 +1017,22 @@ bfin_serial_console_get_options(struct bfin_serial_port *uart, int *baud,
                        case 2: *bits = 7; break;
                        case 3: *bits = 8; break;
                }
+#ifndef CONFIG_BF54x
                /* Set DLAB in LCR to Access DLL and DLH */
                val = UART_GET_LCR(uart);
                val |= DLAB;
                UART_PUT_LCR(uart, val);
+#endif
 
                dll = UART_GET_DLL(uart);
                dlh = UART_GET_DLH(uart);
 
+#ifndef CONFIG_BF54x
                /* Clear DLAB in LCR to Access THR RBR IER */
                val = UART_GET_LCR(uart);
                val &= ~DLAB;
                UART_PUT_LCR(uart, val);
+#endif
 
                *baud = get_sclk() / (16*(dll | dlh << 8));
        }
@@ -931,6 +1084,10 @@ static int __init bfin_serial_rs_console_init(void)
 {
        bfin_serial_init_ports();
        register_console(&bfin_serial_console);
+#ifdef CONFIG_KGDB_UART
+       kgdb_entry_state = 0;
+       init_kgdb_uart();
+#endif
        return 0;
 }
 console_initcall(bfin_serial_rs_console_init);
@@ -1023,6 +1180,10 @@ static struct platform_driver bfin_serial_driver = {
 static int __init bfin_serial_init(void)
 {
        int ret;
+#ifdef CONFIG_KGDB_UART
+       struct bfin_serial_port *uart = &bfin_serial_ports[CONFIG_KGDB_UART_PORT];
+       struct termios t;
+#endif
 
        pr_info("Serial: Blackfin serial driver\n");
 
@@ -1036,6 +1197,21 @@ static int __init bfin_serial_init(void)
                        uart_unregister_driver(&bfin_serial_reg);
                }
        }
+#ifdef CONFIG_KGDB_UART
+       if (uart->port.cons->index != CONFIG_KGDB_UART_PORT) {
+               request_irq(uart->port.irq, bfin_serial_int,
+                       IRQF_DISABLED, "BFIN_UART_RX", uart);
+               pr_info("Request irq for kgdb uart port\n");
+               UART_PUT_IER(uart, UART_GET_IER(uart) | ERBFI);
+               __builtin_bfin_ssync();
+               t.c_cflag = CS8|B57600;
+               t.c_iflag = 0;
+               t.c_oflag = 0;
+               t.c_lflag = ICANON;
+               t.c_line = CONFIG_KGDB_UART_PORT;
+               bfin_serial_set_termios(&uart->port, &t, &t);
+       }
+#endif
        return ret;
 }
 
index 81792e6eeb2d045bf27069a10f58417a84805642..6767ee381cd1b4645056012ba3704c05177389a0 100644 (file)
@@ -88,7 +88,7 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        spin_lock_init(&brd->bd_intr_lock);
 
        /* store which revision we have */
-       pci_read_config_byte(pdev, PCI_REVISION_ID, &brd->rev);
+       brd->rev = pdev->revision;
 
        brd->irq = pdev->irq;
 
index 6b76babc7fbf5ece40cce4444c7c9438f76e7597..a0ea43598515b360115108d319d4ce25aeb3071e 100644 (file)
@@ -842,12 +842,16 @@ static struct pcmcia_device_id serial_ids[] = {
        PCMCIA_PFC_DEVICE_PROD_ID12(1, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033),
        PCMCIA_PFC_DEVICE_PROD_ID12(1, "LINKSYS", "PCMLM336", 0xf7cb0b07, 0x7a821b58),
        PCMCIA_PFC_DEVICE_PROD_ID12(1, "MEGAHERTZ", "XJEM1144/CCEM1144", 0xf510db04, 0x52d21e1e),
+       PCMCIA_PFC_DEVICE_PROD_ID12(1, "MICRO RESEARCH", "COMBO-L/M-336", 0xb2ced065, 0x3ced0555),
+       PCMCIA_PFC_DEVICE_PROD_ID12(1, "NEC", "PK-UG-J001" ,0x18df0ba0 ,0x831b1064),
        PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Diamonds Modem+Ethernet", 0xc2f80cd, 0x656947b9),
        PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Hearts Modem+Ethernet", 0xc2f80cd, 0xdc9ba5ed),
        PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "ComboCard", 0xdcfe12d3, 0xcd8906cc),
        PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "LanModem", 0xdcfe12d3, 0xc67c648f),
        PCMCIA_PFC_DEVICE_PROD_ID12(1, "TDK", "GlobalNetworker 3410/3412", 0x1eae9475, 0xd9a93bed),
        PCMCIA_PFC_DEVICE_PROD_ID12(1, "Xircom", "CreditCard Ethernet+Modem II", 0x2e3ee845, 0xeca401bf),
+       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0a05),
+       PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x1101),
        PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0104, 0x0070),
        PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0101, 0x0562),
        PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0104, 0x0070),
index cf0e663b42ed97781c353f98cd8abb779b592a3c..85309acb75f634da4e3ef3b97590dc5d559ecb79 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  Driver for NEC VR4100 series Serial Interface Unit.
  *
- *  Copyright (C) 2004-2005  Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
+ *  Copyright (C) 2004-2007  Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
  *
  *  Based on drivers/serial/8250.c, by Russell King.
  *
 #endif
 
 #include <linux/console.h>
-#include <linux/platform_device.h>
-#include <linux/err.h>
-#include <linux/ioport.h>
+#include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/ioport.h>
 #include <linux/module.h>
+#include <linux/platform_device.h>
 #include <linux/serial.h>
 #include <linux/serial_core.h>
 #include <linux/serial_reg.h>
 #include <linux/tty_flip.h>
 
 #include <asm/io.h>
-#include <asm/vr41xx/irq.h>
 #include <asm/vr41xx/siu.h>
 #include <asm/vr41xx/vr41xx.h>
 
-#define SIU_PORTS_MAX  2
 #define SIU_BAUD_BASE  1152000
 #define SIU_MAJOR      204
 #define SIU_MINOR_BASE 82
  #define IRUSESEL      0x02
  #define SIRSEL                0x01
 
-struct siu_port {
-       unsigned int type;
-       unsigned int irq;
-       unsigned long start;
-};
-
-static const struct siu_port siu_type1_ports[] = {
-       {       .type           = PORT_VR41XX_SIU,
-               .irq            = SIU_IRQ,
-               .start          = 0x0c000000UL,         },
-};
-
-#define SIU_TYPE1_NR_PORTS     (sizeof(siu_type1_ports) / sizeof(struct siu_port))
-
-static const struct siu_port siu_type2_ports[] = {
-       {       .type           = PORT_VR41XX_SIU,
-               .irq            = SIU_IRQ,
-               .start          = 0x0f000800UL,         },
-       {       .type           = PORT_VR41XX_DSIU,
-               .irq            = DSIU_IRQ,
-               .start          = 0x0f000820UL,         },
+static struct uart_port siu_uart_ports[SIU_PORTS_MAX] = {
+       [0 ... SIU_PORTS_MAX-1] = {
+               .lock   = __SPIN_LOCK_UNLOCKED(siu_uart_ports->lock),
+               .irq    = -1,
+       },
 };
 
-#define SIU_TYPE2_NR_PORTS     (sizeof(siu_type2_ports) / sizeof(struct siu_port))
-
-static struct uart_port siu_uart_ports[SIU_PORTS_MAX];
 static uint8_t lsr_break_flag[SIU_PORTS_MAX];
 
 #define siu_read(port, offset)         readb((port)->membase + (offset))
@@ -110,7 +89,6 @@ void vr41xx_select_siu_interface(siu_interface_t interface)
 
        spin_unlock_irqrestore(&port->lock, flags);
 }
-
 EXPORT_SYMBOL_GPL(vr41xx_select_siu_interface);
 
 void vr41xx_use_irda(irda_use_t use)
@@ -132,7 +110,6 @@ void vr41xx_use_irda(irda_use_t use)
 
        spin_unlock_irqrestore(&port->lock, flags);
 }
-
 EXPORT_SYMBOL_GPL(vr41xx_use_irda);
 
 void vr41xx_select_irda_module(irda_module_t module, irda_speed_t speed)
@@ -166,7 +143,6 @@ void vr41xx_select_irda_module(irda_module_t module, irda_speed_t speed)
 
        spin_unlock_irqrestore(&port->lock, flags);
 }
-
 EXPORT_SYMBOL_GPL(vr41xx_select_irda_module);
 
 static inline void siu_clear_fifo(struct uart_port *port)
@@ -177,21 +153,6 @@ static inline void siu_clear_fifo(struct uart_port *port)
        siu_write(port, UART_FCR, 0);
 }
 
-static inline int siu_probe_ports(void)
-{
-       switch (current_cpu_data.cputype) {
-       case CPU_VR4111:
-       case CPU_VR4121:
-               return SIU_TYPE1_NR_PORTS;
-       case CPU_VR4122:
-       case CPU_VR4131:
-       case CPU_VR4133:
-               return SIU_TYPE2_NR_PORTS;
-       }
-
-       return 0;
-}
-
 static inline unsigned long siu_port_size(struct uart_port *port)
 {
        switch (port->type) {
@@ -206,21 +167,10 @@ static inline unsigned long siu_port_size(struct uart_port *port)
 
 static inline unsigned int siu_check_type(struct uart_port *port)
 {
-       switch (current_cpu_data.cputype) {
-       case CPU_VR4111:
-       case CPU_VR4121:
-               if (port->line == 0)
-                       return PORT_VR41XX_SIU;
-               break;
-       case CPU_VR4122:
-       case CPU_VR4131:
-       case CPU_VR4133:
-               if (port->line == 0)
-                       return PORT_VR41XX_SIU;
-               else if (port->line == 1)
-                       return PORT_VR41XX_DSIU;
-               break;
-       }
+       if (port->line == 0)
+               return PORT_VR41XX_SIU;
+       if (port->line == 1 && port->irq != -1)
+               return PORT_VR41XX_DSIU;
 
        return PORT_UNKNOWN;
 }
@@ -751,44 +701,34 @@ static struct uart_ops siu_uart_ops = {
        .verify_port    = siu_verify_port,
 };
 
-static int siu_init_ports(void)
+static int siu_init_ports(struct platform_device *pdev)
 {
-       const struct siu_port *siu;
        struct uart_port *port;
-       int i, num;
+       struct resource *res;
+       int *type = pdev->dev.platform_data;
+       int i;
 
-       switch (current_cpu_data.cputype) {
-       case CPU_VR4111:
-       case CPU_VR4121:
-               siu = siu_type1_ports;
-               break;
-       case CPU_VR4122:
-       case CPU_VR4131:
-       case CPU_VR4133:
-               siu = siu_type2_ports;
-               break;
-       default:
+       if (!type)
                return 0;
-       }
 
        port = siu_uart_ports;
-       num = siu_probe_ports();
-       for (i = 0; i < num; i++) {
-               spin_lock_init(&port->lock);
-               port->irq = siu->irq;
+       for (i = 0; i < SIU_PORTS_MAX; i++) {
+               port->type = type[i];
+               if (port->type == PORT_UNKNOWN)
+                       continue;
+               port->irq = platform_get_irq(pdev, i);
                port->uartclk = SIU_BAUD_BASE * 16;
                port->fifosize = 16;
                port->regshift = 0;
                port->iotype = UPIO_MEM;
                port->flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF;
-               port->type = siu->type;
                port->line = i;
-               port->mapbase = siu->start;
-               siu++;
+               res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+               port->mapbase = res->start;
                port++;
        }
 
-       return num;
+       return i;
 }
 
 #ifdef CONFIG_SERIAL_VR41XX_CONSOLE
@@ -883,13 +823,9 @@ static struct console siu_console = {
 static int __devinit siu_console_init(void)
 {
        struct uart_port *port;
-       int num, i;
-
-       num = siu_init_ports();
-       if (num <= 0)
-               return -ENODEV;
+       int i;
 
-       for (i = 0; i < num; i++) {
+       for (i = 0; i < SIU_PORTS_MAX; i++) {
                port = &siu_uart_ports[i];
                port->ops = &siu_uart_ops;
        }
@@ -920,7 +856,7 @@ static int __devinit siu_probe(struct platform_device *dev)
        struct uart_port *port;
        int num, i, retval;
 
-       num = siu_init_ports();
+       num = siu_init_ports(dev);
        if (num <= 0)
                return -ENODEV;
 
@@ -998,8 +934,6 @@ static int siu_resume(struct platform_device *dev)
        return 0;
 }
 
-static struct platform_device *siu_platform_device;
-
 static struct platform_driver siu_device_driver = {
        .probe          = siu_probe,
        .remove         = __devexit_p(siu_remove),
@@ -1013,29 +947,12 @@ static struct platform_driver siu_device_driver = {
 
 static int __init vr41xx_siu_init(void)
 {
-       int retval;
-
-       siu_platform_device = platform_device_alloc("SIU", -1);
-       if (!siu_platform_device)
-               return -ENOMEM;
-
-       retval = platform_device_add(siu_platform_device);
-       if (retval < 0) {
-               platform_device_put(siu_platform_device);
-               return retval;
-       }
-
-       retval = platform_driver_register(&siu_device_driver);
-       if (retval < 0)
-               platform_device_unregister(siu_platform_device);
-
-       return retval;
+       return platform_driver_register(&siu_device_driver);
 }
 
 static void __exit vr41xx_siu_exit(void)
 {
        platform_driver_unregister(&siu_device_driver);
-       platform_device_unregister(siu_platform_device);
 }
 
 module_init(vr41xx_siu_init);
index 8efa07e8b8c2a7bef31ce118109b622e42de210d..e007833cca59adfd955b17c7dbcf5adee3b5e3b7 100644 (file)
@@ -111,7 +111,8 @@ at25_ee_read(
 }
 
 static ssize_t
-at25_bin_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
+at25_bin_read(struct kobject *kobj, struct bin_attribute *bin_attr,
+             char *buf, loff_t off, size_t count)
 {
        struct device           *dev;
        struct at25_data        *at25;
@@ -236,7 +237,8 @@ at25_ee_write(struct at25_data *at25, char *buf, loff_t off, size_t count)
 }
 
 static ssize_t
-at25_bin_write(struct kobject *kobj, char *buf, loff_t off, size_t count)
+at25_bin_write(struct kobject *kobj, struct bin_attribute *bin_attr,
+              char *buf, loff_t off, size_t count)
 {
        struct device           *dev;
        struct at25_data        *at25;
@@ -314,7 +316,6 @@ static int at25_probe(struct spi_device *spi)
         */
        at25->bin.attr.name = "eeprom";
        at25->bin.attr.mode = S_IRUSR;
-       at25->bin.attr.owner = THIS_MODULE;
        at25->bin.read = at25_bin_read;
 
        at25->bin.size = at25->chip.byte_len;
index 61de78a9f6ee76156523e7041b04fd8b3b8434dd..ed979f13908a3f358d08e97786a4a65e27138d38 100644 (file)
@@ -136,7 +136,7 @@ struct dec_serial *zs_chain;        /* list of all channels */
 struct tty_struct zs_ttys[NUM_CHANNELS];
 
 #ifdef CONFIG_SERIAL_DEC_CONSOLE
-static struct console sercons;
+static struct console zs_console;
 #endif
 #if defined(CONFIG_SERIAL_DEC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && \
    !defined(MODULE)
@@ -383,7 +383,7 @@ static void receive_chars(struct dec_serial *info)
 
 #if defined(CONFIG_SERIAL_DEC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && \
    !defined(MODULE)
-               if (break_pressed && info->line == sercons.index) {
+               if (break_pressed && info->line == zs_console.index) {
                        /* Ignore the null char got when BREAK is removed.  */
                        if (ch == 0)
                                continue;
@@ -446,7 +446,7 @@ static void status_handle(struct dec_serial *info)
        if ((stat & BRK_ABRT) && !(info->read_reg_zero & BRK_ABRT)) {
 #if defined(CONFIG_SERIAL_DEC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && \
    !defined(MODULE)
-               if (info->line == sercons.index) {
+               if (info->line == zs_console.index) {
                        if (!break_pressed)
                                break_pressed = jiffies;
                } else
@@ -1557,9 +1557,9 @@ static int rs_open(struct tty_struct *tty, struct file * filp)
        }
 
 #ifdef CONFIG_SERIAL_DEC_CONSOLE
-       if (sercons.cflag && sercons.index == line) {
-               tty->termios->c_cflag = sercons.cflag;
-               sercons.cflag = 0;
+       if (zs_console.cflag && zs_console.index == line) {
+               tty->termios->c_cflag = zs_console.cflag;
+               zs_console.cflag = 0;
                change_speed(info);
        }
 #endif
@@ -2069,7 +2069,7 @@ static int __init serial_console_setup(struct console *co, char *options)
        return 0;
 }
 
-static struct console sercons = {
+static struct console zs_console = {
        .name           = "ttyS",
        .write          = serial_console_write,
        .device         = serial_console_device,
@@ -2083,7 +2083,7 @@ static struct console sercons = {
  */
 void __init zs_serial_console_init(void)
 {
-       register_console(&sercons);
+       register_console(&zs_console);
 }
 #endif /* ifdef CONFIG_SERIAL_DEC_CONSOLE */
 
index 15499b7e33f4855b1f6bb8f440d06672a8388c86..071b9675a7819dff38f5128c1d23f635f12b26a8 100644 (file)
@@ -2,8 +2,12 @@
 # USB device configuration
 #
 
-menu "USB support"
+menuconfig USB_SUPPORT
+       bool "USB support"
        depends on HAS_IOMEM
+       default y
+
+if USB_SUPPORT
 
 # Host-side USB depends on having a host controller
 # NOTE:  dummy_hcd is always an option, but it's ignored here ...
@@ -12,6 +16,7 @@ config USB_ARCH_HAS_HCD
        boolean
        default y if USB_ARCH_HAS_OHCI
        default y if USB_ARCH_HAS_EHCI
+       default y if PCMCIA                             # sl811_cs
        default y if ARM                                # SL-811
        default PCI
 
@@ -130,5 +135,4 @@ source "drivers/usb/atm/Kconfig"
 
 source "drivers/usb/gadget/Kconfig"
 
-endmenu
-
+endif # USB_SUPPORT
index 72464b586990cdaab565bbb1958cd5212a1629ec..befff5f9d58c59ce1b5fc19545382ca8b9116b69 100644 (file)
@@ -15,7 +15,7 @@ obj-$(CONFIG_USB_OHCI_HCD)    += host/
 obj-$(CONFIG_USB_UHCI_HCD)     += host/
 obj-$(CONFIG_USB_SL811_HCD)    += host/
 obj-$(CONFIG_USB_U132_HCD)     += host/
-obj-$(CONFIG_USB_OHCI_AT91)    += host/
+obj-$(CONFIG_USB_R8A66597_HCD) += host/
 
 obj-$(CONFIG_USB_ACM)          += class/
 obj-$(CONFIG_USB_PRINTER)      += class/
index 8bcf7fe1dd80c7b531c417f5c58e565b8fd8653f..1bc884051e0f490dbae657df3bd085b5b8e568de 100644 (file)
@@ -171,7 +171,7 @@ struct cxacru_data {
        struct delayed_work poll_work;
        u32 card_info[CXINF_MAX];
        struct mutex poll_state_serialize;
-       int poll_state;
+       enum cxacru_poll_state poll_state;
 
        /* contol handles */
        struct mutex cm_serialize;
@@ -226,58 +226,48 @@ static ssize_t cxacru_sysfs_showattr_s8(s8 value, char *buf)
 
 static ssize_t cxacru_sysfs_showattr_dB(s16 value, char *buf)
 {
-       if (unlikely(value < 0)) {
-               return snprintf(buf, PAGE_SIZE, "%d.%02u\n",
-                                               value / 100, -value % 100);
-       } else {
-               return snprintf(buf, PAGE_SIZE, "%d.%02u\n",
-                                               value / 100, value % 100);
-       }
+       return snprintf(buf, PAGE_SIZE, "%d.%02u\n",
+                                       value / 100, abs(value) % 100);
 }
 
 static ssize_t cxacru_sysfs_showattr_bool(u32 value, char *buf)
 {
-       switch (value) {
-       case 0: return snprintf(buf, PAGE_SIZE, "no\n");
-       case 1: return snprintf(buf, PAGE_SIZE, "yes\n");
-       default: return 0;
-       }
+       static char *str[] = { "no", "yes" };
+       if (unlikely(value >= ARRAY_SIZE(str)))
+               return snprintf(buf, PAGE_SIZE, "%u\n", value);
+       return snprintf(buf, PAGE_SIZE, "%s\n", str[value]);
 }
 
 static ssize_t cxacru_sysfs_showattr_LINK(u32 value, char *buf)
 {
-       switch (value) {
-       case 1: return snprintf(buf, PAGE_SIZE, "not connected\n");
-       case 2: return snprintf(buf, PAGE_SIZE, "connected\n");
-       case 3: return snprintf(buf, PAGE_SIZE, "lost\n");
-       default: return snprintf(buf, PAGE_SIZE, "unknown (%u)\n", value);
-       }
+       static char *str[] = { NULL, "not connected", "connected", "lost" };
+       if (unlikely(value >= ARRAY_SIZE(str) || str[value] == NULL))
+               return snprintf(buf, PAGE_SIZE, "%u\n", value);
+       return snprintf(buf, PAGE_SIZE, "%s\n", str[value]);
 }
 
 static ssize_t cxacru_sysfs_showattr_LINE(u32 value, char *buf)
 {
-       switch (value) {
-       case 0: return snprintf(buf, PAGE_SIZE, "down\n");
-       case 1: return snprintf(buf, PAGE_SIZE, "attempting to activate\n");
-       case 2: return snprintf(buf, PAGE_SIZE, "training\n");
-       case 3: return snprintf(buf, PAGE_SIZE, "channel analysis\n");
-       case 4: return snprintf(buf, PAGE_SIZE, "exchange\n");
-       case 5: return snprintf(buf, PAGE_SIZE, "up\n");
-       case 6: return snprintf(buf, PAGE_SIZE, "waiting\n");
-       case 7: return snprintf(buf, PAGE_SIZE, "initialising\n");
-       default: return snprintf(buf, PAGE_SIZE, "unknown (%u)\n", value);
-       }
+       static char *str[] = { "down", "attempting to activate",
+               "training", "channel analysis", "exchange", "up",
+               "waiting", "initialising"
+       };
+       if (unlikely(value >= ARRAY_SIZE(str)))
+               return snprintf(buf, PAGE_SIZE, "%u\n", value);
+       return snprintf(buf, PAGE_SIZE, "%s\n", str[value]);
 }
 
 static ssize_t cxacru_sysfs_showattr_MODU(u32 value, char *buf)
 {
-       switch (value) {
-       case 0: return 0;
-       case 1: return snprintf(buf, PAGE_SIZE, "ANSI T1.413\n");
-       case 2: return snprintf(buf, PAGE_SIZE, "ITU-T G.992.1 (G.DMT)\n");
-       case 3: return snprintf(buf, PAGE_SIZE, "ITU-T G.992.2 (G.LITE)\n");
-       default: return snprintf(buf, PAGE_SIZE, "unknown (%u)\n", value);
-       }
+       static char *str[] = {
+                       NULL,
+                       "ANSI T1.413",
+                       "ITU-T G.992.1 (G.DMT)",
+                       "ITU-T G.992.2 (G.LITE)"
+       };
+       if (unlikely(value >= ARRAY_SIZE(str) || str[value] == NULL))
+               return snprintf(buf, PAGE_SIZE, "%u\n", value);
+       return snprintf(buf, PAGE_SIZE, "%s\n", str[value]);
 }
 
 /*
@@ -308,11 +298,10 @@ static ssize_t cxacru_sysfs_show_adsl_state(struct device *dev,
        struct cxacru_data *instance = usbatm_instance->driver_data;
        u32 value = instance->card_info[CXINF_LINE_STARTABLE];
 
-       switch (value) {
-       case 0: return snprintf(buf, PAGE_SIZE, "running\n");
-       case 1: return snprintf(buf, PAGE_SIZE, "stopped\n");
-       default: return snprintf(buf, PAGE_SIZE, "unknown (%u)\n", value);
-       }
+       static char *str[] = { "running", "stopped" };
+       if (unlikely(value >= ARRAY_SIZE(str)))
+               return snprintf(buf, PAGE_SIZE, "%u\n", value);
+       return snprintf(buf, PAGE_SIZE, "%s\n", str[value]);
 }
 
 static ssize_t cxacru_sysfs_store_adsl_state(struct device *dev,
index 0081c1d12687de6f8813efb11e0f338c7d7d28a5..cd51520c7e72e10286017998bf00081c8d8571cc 100644 (file)
@@ -1157,6 +1157,9 @@ static struct usb_device_id acm_ids[] = {
        { USB_DEVICE(0x0870, 0x0001), /* Metricom GS Modem */
        .driver_info = NO_UNION_NORMAL, /* has no union descriptor */
        },
+       { USB_DEVICE(0x0e8d, 0x0003), /* FIREFLY, MediaTek Inc; andrey.arapov@gmail.com */
+       .driver_info = NO_UNION_NORMAL, /* has no union descriptor */
+       },
        { USB_DEVICE(0x0482, 0x0203), /* KYOCERA AH-K3001V */
        .driver_info = NO_UNION_NORMAL, /* has no union descriptor */
        },
index 6778f9af794381ec0ae40df7253aa26f0bbddfbc..9a1478972bf5aee1cf75c5f70434d4e68c5fa83c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * usblp.c  Version 0.13
+ * usblp.c
  *
  * Copyright (c) 1999 Michael Gee      <michael@linuxspecific.com>
  * Copyright (c) 1999 Pavel Machek     <pavel@suse.cz>
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.13"
 #define DRIVER_AUTHOR "Michael Gee, Pavel Machek, Vojtech Pavlik, Randy Dunlap, Pete Zaitcev, David Paschal"
 #define DRIVER_DESC "USB Printer Device Class driver"
 
 #define USBLP_BUF_SIZE         8192
+#define USBLP_BUF_SIZE_IN      1024
 #define USBLP_DEVICE_ID_SIZE   1024
 
 /* ioctls: */
@@ -127,14 +127,22 @@ MFG:HEWLETT-PACKARD;MDL:DESKJET 970C;CMD:MLC,PCL,PML;CLASS:PRINTER;DESCRIPTION:H
  */
 #define STATUS_BUF_SIZE                8
 
+/*
+ * Locks down the locking order:
+ * ->wmut locks wstatus.
+ * ->mut locks the whole usblp, except [rw]complete, and thus, by indirection,
+ * [rw]status. We only touch status when we know the side idle.
+ * ->lock locks what interrupt accesses.
+ */
 struct usblp {
        struct usb_device       *dev;                   /* USB device */
-       struct mutex            mut;                    /* locks this struct, especially "dev" */
-       char                    *writebuf;              /* write transfer_buffer */
+       struct mutex            wmut;
+       struct mutex            mut;
+       spinlock_t              lock;           /* locks rcomplete, wcomplete */
        char                    *readbuf;               /* read transfer_buffer */
        char                    *statusbuf;             /* status transfer_buffer */
-       struct urb              *readurb, *writeurb;    /* The urbs */
-       wait_queue_head_t       wait;                   /* Zzzzz ... */
+       struct usb_anchor       urbs;
+       wait_queue_head_t       rwait, wwait;
        int                     readcount;              /* Counter for reads */
        int                     ifnum;                  /* Interface number */
        struct usb_interface    *intf;                  /* The interface */
@@ -147,8 +155,9 @@ struct usblp {
        }                       protocol[USBLP_MAX_PROTOCOLS];
        int                     current_protocol;
        int                     minor;                  /* minor number of device */
-       int                     wcomplete;              /* writing is completed */
-       int                     rcomplete;              /* reading is completed */
+       int                     wcomplete, rcomplete;
+       int                     wstatus;        /* bytes written or error */
+       int                     rstatus;        /* bytes ready or error */
        unsigned int            quirks;                 /* quirks flags */
        unsigned char           used;                   /* True if open */
        unsigned char           present;                /* True if not disconnected */
@@ -166,9 +175,6 @@ static void usblp_dump(struct usblp *usblp) {
        dbg("dev=0x%p", usblp->dev);
        dbg("present=%d", usblp->present);
        dbg("readbuf=0x%p", usblp->readbuf);
-       dbg("writebuf=0x%p", usblp->writebuf);
-       dbg("readurb=0x%p", usblp->readurb);
-       dbg("writeurb=0x%p", usblp->writeurb);
        dbg("readcount=%d", usblp->readcount);
        dbg("ifnum=%d", usblp->ifnum);
     for (p = USBLP_FIRST_PROTOCOL; p <= USBLP_LAST_PROTOCOL; p++) {
@@ -178,8 +184,8 @@ static void usblp_dump(struct usblp *usblp) {
     }
        dbg("current_protocol=%d", usblp->current_protocol);
        dbg("minor=%d", usblp->minor);
-       dbg("wcomplete=%d", usblp->wcomplete);
-       dbg("rcomplete=%d", usblp->rcomplete);
+       dbg("wstatus=%d", usblp->wstatus);
+       dbg("rstatus=%d", usblp->rstatus);
        dbg("quirks=%d", usblp->quirks);
        dbg("used=%d", usblp->used);
        dbg("bidir=%d", usblp->bidir);
@@ -222,6 +228,11 @@ static const struct quirk_printer_struct quirk_printers[] = {
        { 0, 0 }
 };
 
+static int usblp_wwait(struct usblp *usblp, int nonblock);
+static int usblp_wtest(struct usblp *usblp, int nonblock);
+static int usblp_rwait_and_lock(struct usblp *usblp, int nonblock);
+static int usblp_rtest(struct usblp *usblp, int nonblock);
+static int usblp_submit_read(struct usblp *usblp);
 static int usblp_select_alts(struct usblp *usblp);
 static int usblp_set_protocol(struct usblp *usblp, int protocol);
 static int usblp_cache_device_id_string(struct usblp *usblp);
@@ -279,33 +290,47 @@ static void usblp_bulk_read(struct urb *urb)
 {
        struct usblp *usblp = urb->context;
 
-       if (unlikely(!usblp || !usblp->dev || !usblp->used))
-               return;
-
-       if (unlikely(!usblp->present))
-               goto unplug;
-       if (unlikely(urb->status))
-               warn("usblp%d: nonzero read/write bulk status received: %d",
-                       usblp->minor, urb->status);
+       if (usblp->present && usblp->used) {
+               if (urb->status)
+                       printk(KERN_WARNING "usblp%d: "
+                           "nonzero read bulk status received: %d\n",
+                           usblp->minor, urb->status);
+       }
+       spin_lock(&usblp->lock);
+       if (urb->status < 0)
+               usblp->rstatus = urb->status;
+       else
+               usblp->rstatus = urb->actual_length;
        usblp->rcomplete = 1;
-unplug:
-       wake_up_interruptible(&usblp->wait);
+       wake_up(&usblp->rwait);
+       spin_unlock(&usblp->lock);
+
+       usb_free_urb(urb);
 }
 
 static void usblp_bulk_write(struct urb *urb)
 {
        struct usblp *usblp = urb->context;
 
-       if (unlikely(!usblp || !usblp->dev || !usblp->used))
-               return;
-       if (unlikely(!usblp->present))
-               goto unplug;
-       if (unlikely(urb->status))
-               warn("usblp%d: nonzero read/write bulk status received: %d",
-                       usblp->minor, urb->status);
+       if (usblp->present && usblp->used) {
+               if (urb->status)
+                       printk(KERN_WARNING "usblp%d: "
+                           "nonzero write bulk status received: %d\n",
+                           usblp->minor, urb->status);
+       }
+       spin_lock(&usblp->lock);
+       if (urb->status < 0)
+               usblp->wstatus = urb->status;
+       else
+               usblp->wstatus = urb->actual_length;
        usblp->wcomplete = 1;
-unplug:
-       wake_up_interruptible(&usblp->wait);
+       wake_up(&usblp->wwait);
+       spin_unlock(&usblp->lock);
+
+       /* XXX Use usb_setup_bulk_urb when available. Talk to Marcel. */
+       kfree(urb->transfer_buffer);
+       urb->transfer_buffer = NULL;    /* Not refcounted, so to be safe... */
+       usb_free_urb(urb);
 }
 
 /*
@@ -322,7 +347,8 @@ static int usblp_check_status(struct usblp *usblp, int err)
        error = usblp_read_status (usblp, usblp->statusbuf);
        if (error < 0) {
                if (printk_ratelimit())
-                       err("usblp%d: error %d reading printer status",
+                       printk(KERN_ERR
+                               "usblp%d: error %d reading printer status\n",
                                usblp->minor, error);
                return 0;
        }
@@ -336,8 +362,10 @@ static int usblp_check_status(struct usblp *usblp, int err)
        if (~status & LP_PSELECD)
                newerr = 2;
 
-       if (newerr != err)
-               info("usblp%d: %s", usblp->minor, usblp_messages[newerr]);
+       if (newerr != err) {
+               printk(KERN_INFO "usblp%d: %s\n",
+                  usblp->minor, usblp_messages[newerr]);
+       }
 
        return newerr;
 }
@@ -345,12 +373,9 @@ static int usblp_check_status(struct usblp *usblp, int err)
 static int handle_bidir (struct usblp *usblp)
 {
        if (usblp->bidir && usblp->used && !usblp->sleeping) {
-               usblp->readcount = 0;
-               usblp->readurb->dev = usblp->dev;
-               if (usb_submit_urb(usblp->readurb, GFP_KERNEL) < 0)
+               if (usblp_submit_read(usblp) < 0)
                        return -EIO;
        }
-
        return 0;
 }
 
@@ -403,11 +428,9 @@ static int usblp_open(struct inode *inode, struct file *file)
        usblp->used = 1;
        file->private_data = usblp;
 
-       usblp->writeurb->transfer_buffer_length = 0;
        usblp->wcomplete = 1; /* we begin writeable */
+       usblp->wstatus = 0;
        usblp->rcomplete = 0;
-       usblp->writeurb->status = 0;
-       usblp->readurb->status = 0;
 
        if (handle_bidir(usblp) < 0) {
                usblp->used = 0;
@@ -421,20 +444,17 @@ out:
 
 static void usblp_cleanup (struct usblp *usblp)
 {
-       info("usblp%d: removed", usblp->minor);
+       printk(KERN_INFO "usblp%d: removed\n", usblp->minor);
 
+       kfree(usblp->readbuf);
        kfree (usblp->device_id_string);
        kfree (usblp->statusbuf);
-       usb_free_urb(usblp->writeurb);
-       usb_free_urb(usblp->readurb);
        kfree (usblp);
 }
 
 static void usblp_unlink_urbs(struct usblp *usblp)
 {
-       usb_kill_urb(usblp->writeurb);
-       if (usblp->bidir)
-               usb_kill_urb(usblp->readurb);
+       usb_kill_anchored_urbs(&usblp->urbs);
 }
 
 static int usblp_release(struct inode *inode, struct file *file)
@@ -455,10 +475,18 @@ static int usblp_release(struct inode *inode, struct file *file)
 /* No kernel lock - fine */
 static unsigned int usblp_poll(struct file *file, struct poll_table_struct *wait)
 {
+       int ret;
+       unsigned long flags;
+
        struct usblp *usblp = file->private_data;
-       poll_wait(file, &usblp->wait, wait);
-       return ((!usblp->bidir || !usblp->rcomplete) ? 0 : POLLIN  | POLLRDNORM)
+       /* Should we check file->f_mode & FMODE_WRITE before poll_wait()? */
+       poll_wait(file, &usblp->rwait, wait);
+       poll_wait(file, &usblp->wwait, wait);
+       spin_lock_irqsave(&usblp->lock, flags);
+       ret = ((!usblp->bidir || !usblp->rcomplete) ? 0 : POLLIN  | POLLRDNORM)
                               | (!usblp->wcomplete ? 0 : POLLOUT | POLLWRNORM);
+       spin_unlock_irqrestore(&usblp->lock, flags);
+       return ret;
 }
 
 static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
@@ -632,10 +660,11 @@ static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                switch (cmd) {
 
                        case LPGETSTATUS:
-                               if (usblp_read_status(usblp, usblp->statusbuf)) {
+                               if ((retval = usblp_read_status(usblp, usblp->statusbuf))) {
                                        if (printk_ratelimit())
-                                               err("usblp%d: failed reading printer status",
-                                                       usblp->minor);
+                                               printk(KERN_ERR "usblp%d:"
+                                                   "failed reading printer status (%d)\n",
+                                                   usblp->minor, retval);
                                        retval = -EIO;
                                        goto done;
                                }
@@ -656,168 +685,303 @@ done:
 static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
 {
        struct usblp *usblp = file->private_data;
-       int timeout, intr, rv, err = 0, transfer_length = 0;
-       size_t writecount = 0;
+       char *writebuf;
+       struct urb *writeurb;
+       int rv;
+       int transfer_length;
+       ssize_t writecount = 0;
+
+       if (mutex_lock_interruptible(&usblp->wmut)) {
+               rv = -EINTR;
+               goto raise_biglock;
+       }
+       if ((rv = usblp_wwait(usblp, !!(file->f_flags & O_NONBLOCK))) < 0)
+               goto raise_wait;
 
        while (writecount < count) {
-               if (!usblp->wcomplete) {
-                       barrier();
-                       if (file->f_flags & O_NONBLOCK) {
-                               writecount += transfer_length;
-                               return writecount ? writecount : -EAGAIN;
-                       }
-
-                       timeout = USBLP_WRITE_TIMEOUT;
-
-                       rv = wait_event_interruptible_timeout(usblp->wait, usblp->wcomplete || !usblp->present , timeout);
-                       if (rv < 0)
-                               return writecount ? writecount : -EINTR;
-               }
-               intr = mutex_lock_interruptible (&usblp->mut);
-               if (intr)
-                       return writecount ? writecount : -EINTR;
-               if (!usblp->present) {
-                       mutex_unlock (&usblp->mut);
-                       return -ENODEV;
-               }
-
-               if (usblp->sleeping) {
-                       mutex_unlock (&usblp->mut);
-                       return writecount ? writecount : -ENODEV;
-               }
-
-               if (usblp->writeurb->status != 0) {
-                       if (usblp->quirks & USBLP_QUIRK_BIDIR) {
-                               if (!usblp->wcomplete)
-                                       err("usblp%d: error %d writing to printer",
-                                               usblp->minor, usblp->writeurb->status);
-                               err = usblp->writeurb->status;
-                       } else
-                               err = usblp_check_status(usblp, err);
-                       mutex_unlock (&usblp->mut);
-
-                       /* if the fault was due to disconnect, let khubd's
-                        * call to usblp_disconnect() grab usblp->mut ...
-                        */
-                       schedule ();
-                       continue;
-               }
-
-               /* We must increment writecount here, and not at the
-                * end of the loop. Otherwise, the final loop iteration may
-                * be skipped, leading to incomplete printer output.
+               /*
+                * Step 1: Submit next block.
                 */
-               writecount += transfer_length;
-               if (writecount == count) {
-                       mutex_unlock(&usblp->mut);
-                       break;
-               }
-
-               transfer_length=(count - writecount);
-               if (transfer_length > USBLP_BUF_SIZE)
+               if ((transfer_length = count - writecount) > USBLP_BUF_SIZE)
                        transfer_length = USBLP_BUF_SIZE;
 
-               usblp->writeurb->transfer_buffer_length = transfer_length;
-
-               if (copy_from_user(usblp->writeurb->transfer_buffer, 
+               rv = -ENOMEM;
+               if ((writebuf = kmalloc(USBLP_BUF_SIZE, GFP_KERNEL)) == NULL)
+                       goto raise_buf;
+               if ((writeurb = usb_alloc_urb(0, GFP_KERNEL)) == NULL)
+                       goto raise_urb;
+               usb_fill_bulk_urb(writeurb, usblp->dev,
+                       usb_sndbulkpipe(usblp->dev,
+                         usblp->protocol[usblp->current_protocol].epwrite->bEndpointAddress),
+                       writebuf, transfer_length, usblp_bulk_write, usblp);
+               usb_anchor_urb(writeurb, &usblp->urbs);
+
+               if (copy_from_user(writebuf,
                                   buffer + writecount, transfer_length)) {
-                       mutex_unlock(&usblp->mut);
-                       return writecount ? writecount : -EFAULT;
+                       rv = -EFAULT;
+                       goto raise_badaddr;
                }
 
-               usblp->writeurb->dev = usblp->dev;
+               spin_lock_irq(&usblp->lock);
                usblp->wcomplete = 0;
-               err = usb_submit_urb(usblp->writeurb, GFP_KERNEL);
-               if (err) {
+               spin_unlock_irq(&usblp->lock);
+               if ((rv = usb_submit_urb(writeurb, GFP_KERNEL)) < 0) {
+                       usblp->wstatus = 0;
+                       spin_lock_irq(&usblp->lock);
                        usblp->wcomplete = 1;
-                       if (err != -ENOMEM)
-                               count = -EIO;
-                       else
-                               count = writecount ? writecount : -ENOMEM;
-                       mutex_unlock (&usblp->mut);
-                       break;
+                       wake_up(&usblp->wwait);
+                       spin_unlock_irq(&usblp->lock);
+                       if (rv != -ENOMEM)
+                               rv = -EIO;
+                       goto raise_submit;
+               }
+
+               /*
+                * Step 2: Wait for transfer to end, collect results.
+                */
+               rv = usblp_wwait(usblp, !!(file->f_flags&O_NONBLOCK));
+               if (rv < 0) {
+                       /*
+                        * If interrupted, we simply leave the URB to dangle,
+                        * so the ->release will call usb_kill_urb().
+                        */
+                       goto collect_error;
                }
-               mutex_unlock (&usblp->mut);
+
+               if (usblp->wstatus < 0) {
+                       usblp_check_status(usblp, 0);
+                       rv = -EIO;
+                       goto collect_error;
+               }
+               /*
+                * This is critical: it must be our URB, not other writer's.
+                * The wmut exists mainly to cover us here.
+                */
+               writecount += usblp->wstatus;
        }
 
-       return count;
+       mutex_unlock(&usblp->wmut);
+       return writecount;
+
+raise_submit:
+raise_badaddr:
+       usb_unanchor_urb(writeurb);
+       usb_free_urb(writeurb);
+raise_urb:
+       kfree(writebuf);
+raise_buf:
+raise_wait:
+collect_error:         /* Out of raise sequence */
+       mutex_unlock(&usblp->wmut);
+raise_biglock:
+       return writecount ? writecount : rv;
 }
 
-static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
+/*
+ * Notice that we fail to restart in a few cases: on EFAULT, on restart
+ * error, etc. This is the historical behaviour. In all such cases we return
+ * EIO, and applications loop in order to get the new read going.
+ */
+static ssize_t usblp_read(struct file *file, char __user *buffer, size_t len, loff_t *ppos)
 {
        struct usblp *usblp = file->private_data;
-       int rv, intr;
+       ssize_t count;
+       ssize_t avail;
+       int rv;
 
        if (!usblp->bidir)
                return -EINVAL;
 
-       intr = mutex_lock_interruptible (&usblp->mut);
-       if (intr)
-               return -EINTR;
-       if (!usblp->present) {
-               count = -ENODEV;
+       rv = usblp_rwait_and_lock(usblp, !!(file->f_flags & O_NONBLOCK));
+       if (rv < 0)
+               return rv;
+
+       if ((avail = usblp->rstatus) < 0) {
+               printk(KERN_ERR "usblp%d: error %d reading from printer\n",
+                   usblp->minor, (int)avail);
+               usblp_submit_read(usblp);
+               count = -EIO;
                goto done;
        }
 
-       if (!usblp->rcomplete) {
-               barrier();
+       count = len < avail - usblp->readcount ? len : avail - usblp->readcount;
+       if (count != 0 &&
+           copy_to_user(buffer, usblp->readbuf + usblp->readcount, count)) {
+               count = -EFAULT;
+               goto done;
+       }
 
-               if (file->f_flags & O_NONBLOCK) {
-                       count = -EAGAIN;
-                       goto done;
-               }
-               mutex_unlock(&usblp->mut);
-               rv = wait_event_interruptible(usblp->wait, usblp->rcomplete || !usblp->present);
-               mutex_lock(&usblp->mut);
-               if (rv < 0) {
-                       count = -EINTR;
+       if ((usblp->readcount += count) == avail) {
+               if (usblp_submit_read(usblp) < 0) {
+                       /* We don't want to leak USB return codes into errno. */
+                       if (count == 0)
+                               count = -EIO;
                        goto done;
                }
        }
 
-       if (!usblp->present) {
-               count = -ENODEV;
-               goto done;
+done:
+       mutex_unlock (&usblp->mut);
+       return count;
+}
+
+/*
+ * Wait for the write path to come idle.
+ * This is called under the ->wmut, so the idle path stays idle.
+ *
+ * Our write path has a peculiar property: it does not buffer like a tty,
+ * but waits for the write to succeed. This allows our ->release to bug out
+ * without waiting for writes to drain. But it obviously does not work
+ * when O_NONBLOCK is set. So, applications setting O_NONBLOCK must use
+ * select(2) or poll(2) to wait for the buffer to drain before closing.
+ * Alternatively, set blocking mode with fcntl and issue a zero-size write.
+ *
+ * Old v0.13 code had a non-functional timeout for wait_event(). Someone forgot
+ * to check the return code for timeout expiration, so it had no effect.
+ * Apparently, it was intended to check for error conditons, such as out
+ * of paper. It is going to return when we settle things with CUPS. XXX
+ */
+static int usblp_wwait(struct usblp *usblp, int nonblock)
+{
+       DECLARE_WAITQUEUE(waita, current);
+       int rc;
+
+       add_wait_queue(&usblp->wwait, &waita);
+       for (;;) {
+               if (mutex_lock_interruptible(&usblp->mut)) {
+                       rc = -EINTR;
+                       break;
+               }
+               set_current_state(TASK_INTERRUPTIBLE);
+               if ((rc = usblp_wtest(usblp, nonblock)) < 0) {
+                       mutex_unlock(&usblp->mut);
+                       break;
+               }
+               mutex_unlock(&usblp->mut);
+               if (rc == 0)
+                       break;
+               schedule();
        }
+       set_current_state(TASK_RUNNING);
+       remove_wait_queue(&usblp->wwait, &waita);
+       return rc;
+}
 
-       if (usblp->sleeping) {
-               count = -ENODEV;
-               goto done;
+static int usblp_wtest(struct usblp *usblp, int nonblock)
+{
+       unsigned long flags;
+
+       if (!usblp->present)
+               return -ENODEV;
+       if (signal_pending(current))
+               return -EINTR;
+       spin_lock_irqsave(&usblp->lock, flags);
+       if (usblp->wcomplete) {
+               spin_unlock_irqrestore(&usblp->lock, flags);
+               return 0;
        }
+       spin_unlock_irqrestore(&usblp->lock, flags);
+       if (usblp->sleeping)
+               return -ENODEV;
+       if (nonblock)
+               return -EAGAIN;
+       return 1;
+}
 
-       if (usblp->readurb->status) {
-               err("usblp%d: error %d reading from printer",
-                       usblp->minor, usblp->readurb->status);
-               usblp->readurb->dev = usblp->dev;
-               usblp->readcount = 0;
-               usblp->rcomplete = 0;
-               if (usb_submit_urb(usblp->readurb, GFP_KERNEL) < 0)
-                       dbg("error submitting urb");
-               count = -EIO;
-               goto done;
+/*
+ * Wait for read bytes to become available. This probably should have been
+ * called usblp_r_lock_and_wait(), because we lock first. But it's a traditional
+ * name for functions which lock and return.
+ *
+ * We do not use wait_event_interruptible because it makes locking iffy.
+ */
+static int usblp_rwait_and_lock(struct usblp *usblp, int nonblock)
+{
+       DECLARE_WAITQUEUE(waita, current);
+       int rc;
+
+       add_wait_queue(&usblp->rwait, &waita);
+       for (;;) {
+               if (mutex_lock_interruptible(&usblp->mut)) {
+                       rc = -EINTR;
+                       break;
+               }
+               set_current_state(TASK_INTERRUPTIBLE);
+               if ((rc = usblp_rtest(usblp, nonblock)) < 0) {
+                       mutex_unlock(&usblp->mut);
+                       break;
+               }
+               if (rc == 0)    /* Keep it locked */
+                       break;
+               mutex_unlock(&usblp->mut);
+               schedule();
        }
+       set_current_state(TASK_RUNNING);
+       remove_wait_queue(&usblp->rwait, &waita);
+       return rc;
+}
 
-       count = count < usblp->readurb->actual_length - usblp->readcount ?
-               count : usblp->readurb->actual_length - usblp->readcount;
+static int usblp_rtest(struct usblp *usblp, int nonblock)
+{
+       unsigned long flags;
 
-       if (copy_to_user(buffer, usblp->readurb->transfer_buffer + usblp->readcount, count)) {
-               count = -EFAULT;
-               goto done;
+       if (!usblp->present)
+               return -ENODEV;
+       if (signal_pending(current))
+               return -EINTR;
+       spin_lock_irqsave(&usblp->lock, flags);
+       if (usblp->rcomplete) {
+               spin_unlock_irqrestore(&usblp->lock, flags);
+               return 0;
        }
+       spin_unlock_irqrestore(&usblp->lock, flags);
+       if (usblp->sleeping)
+               return -ENODEV;
+       if (nonblock)
+               return -EAGAIN;
+       return 1;
+}
 
-       if ((usblp->readcount += count) == usblp->readurb->actual_length) {
-               usblp->readcount = 0;
-               usblp->readurb->dev = usblp->dev;
-               usblp->rcomplete = 0;
-               if (usb_submit_urb(usblp->readurb, GFP_KERNEL)) {
-                       count = -EIO;
-                       goto done;
-               }
+/*
+ * Please check ->bidir and other such things outside for now.
+ */
+static int usblp_submit_read(struct usblp *usblp)
+{
+       struct urb *urb;
+       unsigned long flags;
+       int rc;
+
+       rc = -ENOMEM;
+       if ((urb = usb_alloc_urb(0, GFP_KERNEL)) == NULL)
+               goto raise_urb;
+
+       usb_fill_bulk_urb(urb, usblp->dev,
+               usb_rcvbulkpipe(usblp->dev,
+                 usblp->protocol[usblp->current_protocol].epread->bEndpointAddress),
+               usblp->readbuf, USBLP_BUF_SIZE_IN,
+               usblp_bulk_read, usblp);
+       usb_anchor_urb(urb, &usblp->urbs);
+
+       spin_lock_irqsave(&usblp->lock, flags);
+       usblp->readcount = 0; /* XXX Why here? */
+       usblp->rcomplete = 0;
+       spin_unlock_irqrestore(&usblp->lock, flags);
+       if ((rc = usb_submit_urb(urb, GFP_KERNEL)) < 0) {
+               dbg("error submitting urb (%d)", rc);
+               spin_lock_irqsave(&usblp->lock, flags);
+               usblp->rstatus = rc;
+               usblp->rcomplete = 1;
+               spin_unlock_irqrestore(&usblp->lock, flags);
+               goto raise_submit;
        }
 
-done:
-       mutex_unlock (&usblp->mut);
-       return count;
+       return 0;
+
+raise_submit:
+       usb_unanchor_urb(urb);
+       usb_free_urb(urb);
+raise_urb:
+       return rc;
 }
 
 /*
@@ -891,55 +1055,41 @@ static int usblp_probe(struct usb_interface *intf,
        /* Malloc and start initializing usblp structure so we can use it
         * directly. */
        if (!(usblp = kzalloc(sizeof(struct usblp), GFP_KERNEL))) {
-               err("out of memory for usblp");
+               retval = -ENOMEM;
                goto abort;
        }
        usblp->dev = dev;
+       mutex_init(&usblp->wmut);
        mutex_init (&usblp->mut);
-       init_waitqueue_head(&usblp->wait);
+       spin_lock_init(&usblp->lock);
+       init_waitqueue_head(&usblp->rwait);
+       init_waitqueue_head(&usblp->wwait);
+       init_usb_anchor(&usblp->urbs);
        usblp->ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
        usblp->intf = intf;
 
-       usblp->writeurb = usb_alloc_urb(0, GFP_KERNEL);
-       if (!usblp->writeurb) {
-               err("out of memory");
-               goto abort;
-       }
-       usblp->readurb = usb_alloc_urb(0, GFP_KERNEL);
-       if (!usblp->readurb) {
-               err("out of memory");
-               goto abort;
-       }
-
        /* Malloc device ID string buffer to the largest expected length,
         * since we can re-query it on an ioctl and a dynamic string
         * could change in length. */
        if (!(usblp->device_id_string = kmalloc(USBLP_DEVICE_ID_SIZE, GFP_KERNEL))) {
-               err("out of memory for device_id_string");
+               retval = -ENOMEM;
                goto abort;
        }
 
-       usblp->writebuf = usblp->readbuf = NULL;
-       usblp->writeurb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
-       usblp->readurb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
-       /* Malloc write & read buffers.  We somewhat wastefully
+       /*
+        * Allocate read buffer. We somewhat wastefully
         * malloc both regardless of bidirectionality, because the
-        * alternate setting can be changed later via an ioctl. */
-       if (!(usblp->writebuf = usb_buffer_alloc(dev, USBLP_BUF_SIZE,
-                               GFP_KERNEL, &usblp->writeurb->transfer_dma))) {
-               err("out of memory for write buf");
-               goto abort;
-       }
-       if (!(usblp->readbuf = usb_buffer_alloc(dev, USBLP_BUF_SIZE,
-                               GFP_KERNEL, &usblp->readurb->transfer_dma))) {
-               err("out of memory for read buf");
+        * alternate setting can be changed later via an ioctl.
+        */
+       if (!(usblp->readbuf = kmalloc(USBLP_BUF_SIZE_IN, GFP_KERNEL))) {
+               retval = -ENOMEM;
                goto abort;
        }
 
        /* Allocate buffer for printer status */
        usblp->statusbuf = kmalloc(STATUS_BUF_SIZE, GFP_KERNEL);
        if (!usblp->statusbuf) {
-               err("out of memory for statusbuf");
+               retval = -ENOMEM;
                goto abort;
        }
 
@@ -954,12 +1104,15 @@ static int usblp_probe(struct usb_interface *intf,
                dbg("incompatible printer-class device 0x%4.4X/0x%4.4X",
                        le16_to_cpu(dev->descriptor.idVendor),
                        le16_to_cpu(dev->descriptor.idProduct));
+               retval = -ENODEV;
                goto abort;
        }
 
        /* Setup the selected alternate setting and endpoints. */
-       if (usblp_set_protocol(usblp, protocol) < 0)
+       if (usblp_set_protocol(usblp, protocol) < 0) {
+               retval = -ENODEV;       /* ->probe isn't ->ioctl */
                goto abort;
+       }
 
        /* Retrieve and store the device ID string. */
        usblp_cache_device_id_string(usblp);
@@ -977,12 +1130,14 @@ static int usblp_probe(struct usb_interface *intf,
 
        retval = usb_register_dev(intf, &usblp_class);
        if (retval) {
-               err("Not able to get a minor for this device.");
+               printk(KERN_ERR "usblp: Not able to get a minor"
+                   " (base %u, slice default): %d\n",
+                   USBLP_MINOR_BASE, retval);
                goto abort_intfdata;
        }
        usblp->minor = intf->minor;
-       info("usblp%d: USB %sdirectional printer dev %d "
-               "if %d alt %d proto %d vid 0x%4.4X pid 0x%4.4X",
+       printk(KERN_INFO "usblp%d: USB %sdirectional printer dev %d "
+               "if %d alt %d proto %d vid 0x%4.4X pid 0x%4.4X\n",
                usblp->minor, usblp->bidir ? "Bi" : "Uni", dev->devnum,
                usblp->ifnum,
                usblp->protocol[usblp->current_protocol].alt_setting,
@@ -997,19 +1152,12 @@ abort_intfdata:
        device_remove_file(&intf->dev, &dev_attr_ieee1284_id);
 abort:
        if (usblp) {
-               if (usblp->writebuf)
-                       usb_buffer_free (usblp->dev, USBLP_BUF_SIZE,
-                               usblp->writebuf, usblp->writeurb->transfer_dma);
-               if (usblp->readbuf)
-                       usb_buffer_free (usblp->dev, USBLP_BUF_SIZE,
-                               usblp->readbuf, usblp->readurb->transfer_dma);
+               kfree(usblp->readbuf);
                kfree(usblp->statusbuf);
                kfree(usblp->device_id_string);
-               usb_free_urb(usblp->writeurb);
-               usb_free_urb(usblp->readurb);
                kfree(usblp);
        }
-       return -EIO;
+       return retval;
 }
 
 /*
@@ -1078,8 +1226,9 @@ static int usblp_select_alts(struct usblp *usblp)
                if (ifd->desc.bInterfaceProtocol == 1) {
                        epread = NULL;
                } else if (usblp->quirks & USBLP_QUIRK_BIDIR) {
-                       info("Disabling reads from problem bidirectional "
-                               "printer on usblp%d", usblp->minor);
+                       printk(KERN_INFO "usblp%d: Disabling reads from "
+                           "problematic bidirectional printer\n",
+                           usblp->minor);
                        epread = NULL;
                }
 
@@ -1119,25 +1268,12 @@ static int usblp_set_protocol(struct usblp *usblp, int protocol)
                return -EINVAL;
        r = usb_set_interface(usblp->dev, usblp->ifnum, alts);
        if (r < 0) {
-               err("can't set desired altsetting %d on interface %d",
+               printk(KERN_ERR "usblp: can't set desired altsetting %d on interface %d\n",
                        alts, usblp->ifnum);
                return r;
        }
 
-       usb_fill_bulk_urb(usblp->writeurb, usblp->dev,
-               usb_sndbulkpipe(usblp->dev,
-                 usblp->protocol[protocol].epwrite->bEndpointAddress),
-               usblp->writebuf, 0,
-               usblp_bulk_write, usblp);
-
        usblp->bidir = (usblp->protocol[protocol].epread != NULL);
-       if (usblp->bidir)
-               usb_fill_bulk_urb(usblp->readurb, usblp->dev,
-                       usb_rcvbulkpipe(usblp->dev,
-                         usblp->protocol[protocol].epread->bEndpointAddress),
-                       usblp->readbuf, USBLP_BUF_SIZE,
-                       usblp_bulk_read, usblp);
-
        usblp->current_protocol = protocol;
        dbg("usblp%d set protocol %d", usblp->minor, protocol);
        return 0;
@@ -1190,13 +1326,11 @@ static void usblp_disconnect(struct usb_interface *intf)
        mutex_lock (&usblp_mutex);
        mutex_lock (&usblp->mut);
        usblp->present = 0;
+       wake_up(&usblp->wwait);
+       wake_up(&usblp->rwait);
        usb_set_intfdata (intf, NULL);
 
        usblp_unlink_urbs(usblp);
-       usb_buffer_free (usblp->dev, USBLP_BUF_SIZE,
-                       usblp->writebuf, usblp->writeurb->transfer_dma);
-       usb_buffer_free (usblp->dev, USBLP_BUF_SIZE,
-                       usblp->readbuf, usblp->readurb->transfer_dma);
        mutex_unlock (&usblp->mut);
 
        if (!usblp->used)
@@ -1211,6 +1345,11 @@ static int usblp_suspend (struct usb_interface *intf, pm_message_t message)
        /* we take no more IO */
        usblp->sleeping = 1;
        usblp_unlink_urbs(usblp);
+#if 0 /* XXX Do we want this? What if someone is reading, should we fail? */
+       /* not strictly necessary, but just in case */
+       wake_up(&usblp->wwait);
+       wake_up(&usblp->rwait);
+#endif
 
        return 0;
 }
@@ -1251,12 +1390,7 @@ static struct usb_driver usblp_driver = {
 
 static int __init usblp_init(void)
 {
-       int retval;
-       retval = usb_register(&usblp_driver);
-       if (!retval)
-               info(DRIVER_VERSION ": " DRIVER_DESC);
-
-       return retval;
+       return usb_register(&usblp_driver);
 }
 
 static void __exit usblp_exit(void)
index 346fc030c929ae172b6658df8f1a2b54113e1ac3..97b09f282705bb4c4249e733d89ea3ca43876cd2 100644 (file)
@@ -86,6 +86,31 @@ config USB_SUSPEND
 
          If you are unsure about this, say N here.
 
+config USB_PERSIST
+       bool "USB device persistence during system suspend (DANGEROUS)"
+       depends on USB && PM && EXPERIMENTAL
+       default n
+       help
+
+         If you say Y here and enable the "power/persist" attribute
+         for a USB device, the device's data structures will remain
+         persistent across system suspend, even if the USB bus loses
+         power.  (This includes hibernation, also known as swsusp or
+         suspend-to-disk.)  The devices will reappear as if by magic
+         when the system wakes up, with no need to unmount USB
+         filesystems, rmmod host-controller drivers, or do anything
+         else.
+
+               WARNING: This option can be dangerous!
+
+         If a USB device is replaced by another of the same type while
+         the system is asleep, there's a good chance the kernel won't
+         detect the change.  Likewise if the media in a USB storage
+         device is replaced.  When this happens it's almost certain to
+         cause data corruption and maybe even crash your system.
+
+         If you are unsure, say N here.
+
 config USB_OTG
        bool
        depends on USB && EXPERIMENTAL
index dd3482328ad2603e7726e10d07dd4f2dc09ffc58..cb69aa1e02e8762913e1d68901fb64495b68d8d0 100644 (file)
@@ -85,15 +85,21 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
        memcpy(&endpoint->desc, d, n);
        INIT_LIST_HEAD(&endpoint->urb_list);
 
-       /* If the bInterval value is outside the legal range,
-        * set it to a default value: 32 ms */
+       /* Fix up bInterval values outside the legal range. Use 32 ms if no
+        * proper value can be guessed. */
        i = 0;          /* i = min, j = max, n = default */
        j = 255;
        if (usb_endpoint_xfer_int(d)) {
                i = 1;
                switch (to_usb_device(ddev)->speed) {
                case USB_SPEED_HIGH:
-                       n = 9;          /* 32 ms = 2^(9-1) uframes */
+                       /* Many device manufacturers are using full-speed
+                        * bInterval values in high-speed interrupt endpoint
+                        * descriptors. Try to fix those and fall back to a
+                        * 32 ms default value otherwise. */
+                       n = fls(d->bInterval*8);
+                       if (n == 0)
+                               n = 9;  /* 32 ms = 2^(9-1) uframes */
                        j = 16;
                        break;
                default:                /* USB_SPEED_FULL or _LOW */
@@ -124,6 +130,21 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
                endpoint->desc.bInterval = n;
        }
 
+       /* Some buggy low-speed devices have Bulk endpoints, which is
+        * explicitly forbidden by the USB spec.  In an attempt to make
+        * them usable, we will try treating them as Interrupt endpoints.
+        */
+       if (to_usb_device(ddev)->speed == USB_SPEED_LOW &&
+                       usb_endpoint_xfer_bulk(d)) {
+               dev_warn(ddev, "config %d interface %d altsetting %d "
+                   "endpoint 0x%X is Bulk; changing to Interrupt\n",
+                   cfgno, inum, asnum, d->bEndpointAddress);
+               endpoint->desc.bmAttributes = USB_ENDPOINT_XFER_INT;
+               endpoint->desc.bInterval = 1;
+               if (le16_to_cpu(endpoint->desc.wMaxPacketSize) > 8)
+                       endpoint->desc.wMaxPacketSize = cpu_to_le16(8);
+       }
+
        /* Skip over any Class Specific or Vendor Specific descriptors;
         * find the next endpoint or interface descriptor */
        endpoint->extra = buffer;
@@ -274,6 +295,7 @@ static int usb_parse_configuration(struct device *ddev, int cfgidx,
        struct usb_descriptor_header *header;
        int len, retval;
        u8 inums[USB_MAXINTERFACES], nalts[USB_MAXINTERFACES];
+       unsigned iad_num = 0;
 
        memcpy(&config->desc, buffer, USB_DT_CONFIG_SIZE);
        if (config->desc.bDescriptorType != USB_DT_CONFIG ||
@@ -351,6 +373,20 @@ static int usb_parse_configuration(struct device *ddev, int cfgidx,
                                ++n;
                        }
 
+               } else if (header->bDescriptorType ==
+                               USB_DT_INTERFACE_ASSOCIATION) {
+                       if (iad_num == USB_MAXIADS) {
+                               dev_warn(ddev, "found more Interface "
+                                              "Association Descriptors "
+                                              "than allocated for in "
+                                              "configuration %d\n", cfgno);
+                       } else {
+                               config->intf_assoc[iad_num] =
+                                       (struct usb_interface_assoc_descriptor
+                                       *)header;
+                               iad_num++;
+                       }
+
                } else if (header->bDescriptorType == USB_DT_DEVICE ||
                            header->bDescriptorType == USB_DT_CONFIG)
                        dev_warn(ddev, "config %d contains an unexpected "
index 6753ca059ee43808fbbeb0128d27ae54ab56687c..87c794d60aa021ee3b6f1108e2cef34fb519f4c4 100644 (file)
@@ -102,6 +102,10 @@ static const char *format_config =
 /* C:  #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA */
   "C:%c #Ifs=%2d Cfg#=%2d Atr=%02x MxPwr=%3dmA\n";
   
+static const char *format_iad =
+/* A:  FirstIf#=dd IfCount=dd Cls=xx(sssss) Sub=xx Prot=xx */
+  "A:  FirstIf#=%2d IfCount=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x\n";
+
 static const char *format_iface =
 /* I:  If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=xxxx*/
   "I:%c If#=%2d Alt=%2d #EPs=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x Driver=%s\n";
@@ -146,6 +150,7 @@ static const struct class_info clas_info[] =
        {USB_CLASS_STILL_IMAGE,         "still"},
        {USB_CLASS_CSCID,               "scard"},
        {USB_CLASS_CONTENT_SEC,         "c-sec"},
+       {USB_CLASS_VIDEO,               "video"},
        {-1,                            "unk."}         /* leave as last */
 };
 
@@ -286,6 +291,21 @@ static char *usb_dump_interface(
        return start;
 }
 
+static char *usb_dump_iad_descriptor(char *start, char *end,
+       const struct usb_interface_assoc_descriptor *iad)
+{
+       if (start > end)
+               return start;
+       start += sprintf(start, format_iad,
+                        iad->bFirstInterface,
+                        iad->bInterfaceCount,
+                        iad->bFunctionClass,
+                        class_decode(iad->bFunctionClass),
+                        iad->bFunctionSubClass,
+                        iad->bFunctionProtocol);
+       return start;
+}
+
 /* TBD:
  * 0. TBDs
  * 1. marking active interface altsettings (code lists all, but should mark
@@ -322,6 +342,12 @@ static char *usb_dump_config (
        if (!config)            /* getting these some in 2.3.7; none in 2.3.6 */
                return start + sprintf(start, "(null Cfg. desc.)\n");
        start = usb_dump_config_descriptor(start, end, &config->desc, active);
+       for (i = 0; i < USB_MAXIADS; i++) {
+               if (config->intf_assoc[i] == NULL)
+                       break;
+               start = usb_dump_iad_descriptor(start, end,
+                                       config->intf_assoc[i]);
+       }
        for (i = 0; i < config->desc.bNumInterfaces; i++) {
                intfc = config->intf_cache[i];
                interface = config->interface[i];
index 2619986e53000f95667365157193dd1dec0d3453..73c49362cd47c7d593e815d7bd3f9f194d899ff3 100644 (file)
 
 #include <linux/device.h>
 #include <linux/usb.h>
+#include <linux/usb/quirks.h>
 #include <linux/workqueue.h>
 #include "hcd.h"
 #include "usb.h"
 
+#define VERBOSE_DEBUG  0
+
+#if VERBOSE_DEBUG
+#define dev_vdbg       dev_dbg
+#else
+#define dev_vdbg(dev, fmt, args...)    do { } while (0)
+#endif
+
 #ifdef CONFIG_HOTPLUG
 
 /*
@@ -802,18 +811,17 @@ static int usb_suspend_device(struct usb_device *udev, pm_message_t msg)
                        udev->state == USB_STATE_SUSPENDED)
                goto done;
 
-       /* For devices that don't have a driver, we do a standard suspend. */
-       if (udev->dev.driver == NULL) {
+       /* For devices that don't have a driver, we do a generic suspend. */
+       if (udev->dev.driver)
+               udriver = to_usb_device_driver(udev->dev.driver);
+       else {
                udev->do_remote_wakeup = 0;
-               status = usb_port_suspend(udev);
-               goto done;
+               udriver = &usb_generic_driver;
        }
-
-       udriver = to_usb_device_driver(udev->dev.driver);
        status = udriver->suspend(udev, msg);
 
-done:
-       // dev_dbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status);
+ done:
+       dev_vdbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status);
        if (status == 0)
                udev->dev.power.power_state.event = msg.event;
        return status;
@@ -825,8 +833,9 @@ static int usb_resume_device(struct usb_device *udev)
        struct usb_device_driver        *udriver;
        int                             status = 0;
 
-       if (udev->state == USB_STATE_NOTATTACHED ||
-                       udev->state != USB_STATE_SUSPENDED)
+       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. */
@@ -835,11 +844,14 @@ static int usb_resume_device(struct usb_device *udev)
                goto done;
        }
 
+       if (udev->quirks & USB_QUIRK_RESET_RESUME)
+               udev->reset_resume = 1;
+
        udriver = to_usb_device_driver(udev->dev.driver);
        status = udriver->resume(udev);
 
-done:
-       // dev_dbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status);
+ done:
+       dev_vdbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status);
        if (status == 0) {
                udev->autoresume_disabled = 0;
                udev->dev.power.power_state.event = PM_EVENT_ON;
@@ -877,15 +889,13 @@ static int usb_suspend_interface(struct usb_interface *intf, pm_message_t msg)
                mark_quiesced(intf);
        }
 
-done:
-       // dev_dbg(&intf->dev, "%s: status %d\n", __FUNCTION__, status);
-       if (status == 0)
-               intf->dev.power.power_state.event = msg.event;
+ done:
+       dev_vdbg(&intf->dev, "%s: status %d\n", __FUNCTION__, status);
        return status;
 }
 
 /* Caller has locked intf's usb_device's pm_mutex */
-static int usb_resume_interface(struct usb_interface *intf)
+static int usb_resume_interface(struct usb_interface *intf, int reset_resume)
 {
        struct usb_driver       *driver;
        int                     status = 0;
@@ -905,23 +915,37 @@ static int usb_resume_interface(struct usb_interface *intf)
        }
        driver = to_usb_driver(intf->dev.driver);
 
-       if (driver->resume) {
-               status = driver->resume(intf);
-               if (status)
-                       dev_err(&intf->dev, "%s error %d\n",
-                                       "resume", status);
-               else
-                       mark_active(intf);
+       if (reset_resume) {
+               if (driver->reset_resume) {
+                       status = driver->reset_resume(intf);
+                       if (status)
+                               dev_err(&intf->dev, "%s error %d\n",
+                                               "reset_resume", status);
+               } else {
+                       // status = -EOPNOTSUPP;
+                       dev_warn(&intf->dev, "no %s for driver %s?\n",
+                                       "reset_resume", driver->name);
+               }
        } else {
-               dev_warn(&intf->dev, "no resume for driver %s?\n",
-                               driver->name);
-               mark_active(intf);
+               if (driver->resume) {
+                       status = driver->resume(intf);
+                       if (status)
+                               dev_err(&intf->dev, "%s error %d\n",
+                                               "resume", status);
+               } else {
+                       // status = -EOPNOTSUPP;
+                       dev_warn(&intf->dev, "no %s for driver %s?\n",
+                                       "resume", driver->name);
+               }
        }
 
 done:
-       // dev_dbg(&intf->dev, "%s: status %d\n", __FUNCTION__, status);
+       dev_vdbg(&intf->dev, "%s: status %d\n", __FUNCTION__, status);
        if (status == 0)
-               intf->dev.power.power_state.event = PM_EVENT_ON;
+               mark_active(intf);
+
+       /* FIXME: Unbind the driver and reprobe if the resume failed
+        * (not possible if auto_pm is set) */
        return status;
 }
 
@@ -958,6 +982,18 @@ static int autosuspend_check(struct usb_device *udev)
                                                "for autosuspend\n");
                                return -EOPNOTSUPP;
                        }
+
+                       /* Don't allow autosuspend if the device will need
+                        * a reset-resume and any of its interface drivers
+                        * doesn't include support.
+                        */
+                       if (udev->quirks & USB_QUIRK_RESET_RESUME) {
+                               struct usb_driver *driver;
+
+                               driver = to_usb_driver(intf->dev.driver);
+                               if (!driver->reset_resume)
+                                       return -EOPNOTSUPP;
+                       }
                }
        }
 
@@ -974,7 +1010,7 @@ static int autosuspend_check(struct usb_device *udev)
                         * or for the past.
                         */
                        queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend,
-                                       suspend_time - jiffies);
+                               round_jiffies_relative(suspend_time - jiffies));
                        }
                return -EAGAIN;
        }
@@ -1054,14 +1090,21 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
                                break;
                }
        }
-       if (status == 0)
+       if (status == 0) {
+
+               /* Non-root devices don't need to do anything for FREEZE
+                * or PRETHAW. */
+               if (udev->parent && (msg.event == PM_EVENT_FREEZE ||
+                               msg.event == PM_EVENT_PRETHAW))
+                       goto done;
                status = usb_suspend_device(udev, msg);
+       }
 
        /* If the suspend failed, resume interfaces that did get suspended */
        if (status != 0) {
                while (--i >= 0) {
                        intf = udev->actconfig->interface[i];
-                       usb_resume_interface(intf);
+                       usb_resume_interface(intf, 0);
                }
 
                /* Try another autosuspend when the interfaces aren't busy */
@@ -1076,7 +1119,7 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
        }
 
  done:
-       // dev_dbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status);
+       dev_vdbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status);
        return status;
 }
 
@@ -1131,7 +1174,8 @@ static int usb_resume_both(struct usb_device *udev)
                        status = usb_autoresume_device(parent);
                        if (status == 0) {
                                status = usb_resume_device(udev);
-                               if (status) {
+                               if (status || udev->state ==
+                                               USB_STATE_NOTATTACHED) {
                                        usb_autosuspend_device(parent);
 
                                        /* It's possible usb_resume_device()
@@ -1152,28 +1196,25 @@ static int usb_resume_both(struct usb_device *udev)
                        /* We can't progagate beyond the USB subsystem,
                         * so if a root hub's controller is suspended
                         * then we're stuck. */
-                       if (udev->dev.parent->power.power_state.event !=
-                                       PM_EVENT_ON)
-                               status = -EHOSTUNREACH;
-                       else
-                               status = usb_resume_device(udev);
+                       status = usb_resume_device(udev);
                }
        } else {
 
-               /* Needed only for setting udev->dev.power.power_state.event
-                * and for possible debugging message. */
+               /* Needed for setting udev->dev.power.power_state.event,
+                * for possible debugging message, and for reset_resume. */
                status = usb_resume_device(udev);
        }
 
        if (status == 0 && udev->actconfig) {
                for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
                        intf = udev->actconfig->interface[i];
-                       usb_resume_interface(intf);
+                       usb_resume_interface(intf, udev->reset_resume);
                }
        }
 
  done:
-       // dev_dbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status);
+       dev_vdbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status);
+       udev->reset_resume = 0;
        return status;
 }
 
@@ -1240,8 +1281,8 @@ void usb_autosuspend_device(struct usb_device *udev)
        int     status;
 
        status = usb_autopm_do_device(udev, -1);
-       // dev_dbg(&udev->dev, "%s: cnt %d\n",
-       //              __FUNCTION__, udev->pm_usage_cnt);
+       dev_vdbg(&udev->dev, "%s: cnt %d\n",
+                       __FUNCTION__, udev->pm_usage_cnt);
 }
 
 /**
@@ -1260,8 +1301,8 @@ void usb_autosuspend_device(struct usb_device *udev)
 void usb_try_autosuspend_device(struct usb_device *udev)
 {
        usb_autopm_do_device(udev, 0);
-       // dev_dbg(&udev->dev, "%s: cnt %d\n",
-       //              __FUNCTION__, udev->pm_usage_cnt);
+       dev_vdbg(&udev->dev, "%s: cnt %d\n",
+                       __FUNCTION__, udev->pm_usage_cnt);
 }
 
 /**
@@ -1288,8 +1329,8 @@ int usb_autoresume_device(struct usb_device *udev)
        int     status;
 
        status = usb_autopm_do_device(udev, 1);
-       // dev_dbg(&udev->dev, "%s: status %d cnt %d\n",
-       //              __FUNCTION__, status, udev->pm_usage_cnt);
+       dev_vdbg(&udev->dev, "%s: status %d cnt %d\n",
+                       __FUNCTION__, status, udev->pm_usage_cnt);
        return status;
 }
 
@@ -1361,8 +1402,8 @@ void usb_autopm_put_interface(struct usb_interface *intf)
        int     status;
 
        status = usb_autopm_do_interface(intf, -1);
-       // dev_dbg(&intf->dev, "%s: status %d cnt %d\n",
-       //              __FUNCTION__, status, intf->pm_usage_cnt);
+       dev_vdbg(&intf->dev, "%s: status %d cnt %d\n",
+                       __FUNCTION__, status, intf->pm_usage_cnt);
 }
 EXPORT_SYMBOL_GPL(usb_autopm_put_interface);
 
@@ -1405,8 +1446,8 @@ int usb_autopm_get_interface(struct usb_interface *intf)
        int     status;
 
        status = usb_autopm_do_interface(intf, 1);
-       // dev_dbg(&intf->dev, "%s: status %d cnt %d\n",
-       //              __FUNCTION__, status, intf->pm_usage_cnt);
+       dev_vdbg(&intf->dev, "%s: status %d cnt %d\n",
+                       __FUNCTION__, status, intf->pm_usage_cnt);
        return status;
 }
 EXPORT_SYMBOL_GPL(usb_autopm_get_interface);
@@ -1427,8 +1468,8 @@ int usb_autopm_set_interface(struct usb_interface *intf)
        int     status;
 
        status = usb_autopm_do_interface(intf, 0);
-       // dev_dbg(&intf->dev, "%s: status %d cnt %d\n",
-       //              __FUNCTION__, status, intf->pm_usage_cnt);
+       dev_vdbg(&intf->dev, "%s: status %d cnt %d\n",
+                       __FUNCTION__, status, intf->pm_usage_cnt);
        return status;
 }
 EXPORT_SYMBOL_GPL(usb_autopm_set_interface);
@@ -1508,8 +1549,15 @@ static int usb_resume(struct device *dev)
        if (!is_usb_device(dev))        /* Ignore PM for interfaces */
                return 0;
        udev = to_usb_device(dev);
-       if (udev->autoresume_disabled)
-               return -EPERM;
+
+       /* If autoresume is disabled then we also want to prevent resume
+        * during system wakeup.  However, a "persistent-device" reset-resume
+        * after power loss counts as a wakeup event.  So allow a
+        * reset-resume to occur if remote wakeup is enabled. */
+       if (udev->autoresume_disabled) {
+               if (!(udev->reset_resume && udev->do_remote_wakeup))
+                       return -EPERM;
+       }
        return usb_external_resume_device(udev);
 }
 
index 01c857ac27afc09eed98c1a190d794073b73c470..5d860bc9b42143f6729a9df40521ec42943b21b1 100644 (file)
  */
 
 #include <linux/module.h>
-#include <linux/spinlock.h>
 #include <linux/errno.h>
+#include <linux/rwsem.h>
 #include <linux/usb.h>
 
 #include "usb.h"
 
 #define MAX_USB_MINORS 256
 static const struct file_operations *usb_minors[MAX_USB_MINORS];
-static DEFINE_SPINLOCK(minor_lock);
+static DECLARE_RWSEM(minor_rwsem);
 
 static int usb_open(struct inode * inode, struct file * file)
 {
@@ -33,14 +33,11 @@ static int usb_open(struct inode * inode, struct file * file)
        int err = -ENODEV;
        const struct file_operations *old_fops, *new_fops = NULL;
 
-       spin_lock (&minor_lock);
+       down_read(&minor_rwsem);
        c = usb_minors[minor];
 
-       if (!c || !(new_fops = fops_get(c))) {
-               spin_unlock(&minor_lock);
-               return err;
-       }
-       spin_unlock(&minor_lock);
+       if (!c || !(new_fops = fops_get(c)))
+               goto done;
 
        old_fops = file->f_op;
        file->f_op = new_fops;
@@ -52,6 +49,8 @@ static int usb_open(struct inode * inode, struct file * file)
                file->f_op = fops_get(old_fops);
        }
        fops_put(old_fops);
+ done:
+       up_read(&minor_rwsem);
        return err;
 }
 
@@ -166,7 +165,7 @@ int usb_register_dev(struct usb_interface *intf,
        if (class_driver->fops == NULL)
                goto exit;
 
-       spin_lock (&minor_lock);
+       down_write(&minor_rwsem);
        for (minor = minor_base; minor < MAX_USB_MINORS; ++minor) {
                if (usb_minors[minor])
                        continue;
@@ -176,7 +175,7 @@ int usb_register_dev(struct usb_interface *intf,
                retval = 0;
                break;
        }
-       spin_unlock (&minor_lock);
+       up_write(&minor_rwsem);
 
        if (retval)
                goto exit;
@@ -197,9 +196,9 @@ int usb_register_dev(struct usb_interface *intf,
        intf->usb_dev = device_create(usb_class->class, &intf->dev,
                                      MKDEV(USB_MAJOR, minor), "%s", temp);
        if (IS_ERR(intf->usb_dev)) {
-               spin_lock (&minor_lock);
+               down_write(&minor_rwsem);
                usb_minors[intf->minor] = NULL;
-               spin_unlock (&minor_lock);
+               up_write(&minor_rwsem);
                retval = PTR_ERR(intf->usb_dev);
        }
 exit:
@@ -236,9 +235,9 @@ void usb_deregister_dev(struct usb_interface *intf,
 
        dbg ("removing %d minor", intf->minor);
 
-       spin_lock (&minor_lock);
+       down_write(&minor_rwsem);
        usb_minors[intf->minor] = NULL;
-       spin_unlock (&minor_lock);
+       up_write(&minor_rwsem);
 
        snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base);
        device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor));
@@ -247,5 +246,3 @@ void usb_deregister_dev(struct usb_interface *intf,
        destroy_usb_class();
 }
 EXPORT_SYMBOL(usb_deregister_dev);
-
-
index 9bbcb20e2d94c3bf5ca96f77d0c1050d87d14eb2..b2fc2b115256633a2f19bfd2a013ffaffedcaf28 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <linux/usb.h>
 #include "usb.h"
+#include "hcd.h"
 
 static inline const char *plural(int n)
 {
@@ -193,16 +194,34 @@ static void generic_disconnect(struct usb_device *udev)
 
 static int generic_suspend(struct usb_device *udev, pm_message_t msg)
 {
-       /* USB devices enter SUSPEND state through their hubs, but can be
-        * marked for FREEZE as soon as their children are already idled.
-        * But those semantics are useless, so we equate the two (sigh).
+       int rc;
+
+       /* Normal USB devices suspend through their upstream port.
+        * Root hubs don't have upstream ports to suspend,
+        * so we have to shut down their downstream HC-to-USB
+        * interfaces manually by doing a bus (or "global") suspend.
         */
-       return usb_port_suspend(udev);
+       if (!udev->parent)
+               rc = hcd_bus_suspend(udev);
+       else
+               rc = usb_port_suspend(udev);
+       return rc;
 }
 
 static int generic_resume(struct usb_device *udev)
 {
-       return usb_port_resume(udev);
+       int rc;
+
+       /* Normal USB devices resume/reset through their upstream port.
+        * Root hubs don't have upstream ports to resume or reset,
+        * so we have to start up their downstream HC-to-USB
+        * interfaces manually by doing a bus (or "global") resume.
+        */
+       if (!udev->parent)
+               rc = hcd_bus_resume(udev);
+       else
+               rc = usb_port_resume(udev);
+       return rc;
 }
 
 #endif /* CONFIG_PM */
index edf4300a3f7a75d748776ab3fe3d69fbf1a6f66d..5cf6d5f9acbdb749340b0f8922f5ec177afbe3f5 100644 (file)
@@ -207,7 +207,8 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message)
         * We must ignore the FREEZE vs SUSPEND distinction here, because
         * otherwise the swsusp will save (and restore) garbage state.
         */
-       if (hcd->self.root_hub->dev.power.power_state.event == PM_EVENT_ON)
+       if (!(hcd->state == HC_STATE_SUSPENDED ||
+                       hcd->state == HC_STATE_HALT))
                return -EBUSY;
 
        if (hcd->driver->suspend) {
index 8969e42434b9ca2a2b2a54ea9c7aab0bcccd642a..963520fbef9061db3a42f12d624840bab9976e92 100644 (file)
@@ -582,10 +582,12 @@ void usb_hcd_poll_rh_status(struct usb_hcd *hcd)
        }
 
        /* The USB 2.0 spec says 256 ms.  This is close enough and won't
-        * exceed that limit if HZ is 100. */
+        * exceed that limit if HZ is 100. The math is more clunky than
+        * maybe expected, this is to make sure that all timers for USB devices
+        * fire at the same time to give the CPU a break inbetween */
        if (hcd->uses_new_polling ? hcd->poll_rh :
                        (length == 0 && hcd->status_urb != NULL))
-               mod_timer (&hcd->rh_timer, jiffies + msecs_to_jiffies(250));
+               mod_timer (&hcd->rh_timer, (jiffies/(HZ/4) + 1) * (HZ/4));
 }
 EXPORT_SYMBOL_GPL(usb_hcd_poll_rh_status);
 
@@ -614,8 +616,8 @@ static int rh_queue_status (struct usb_hcd *hcd, struct urb *urb)
                urb->hcpriv = hcd;      /* indicate it's queued */
 
                if (!hcd->uses_new_polling)
-                       mod_timer (&hcd->rh_timer, jiffies +
-                                       msecs_to_jiffies(250));
+                       mod_timer (&hcd->rh_timer,
+                               (jiffies/(HZ/4) + 1) * (HZ/4));
 
                /* If a status change has already occurred, report it ASAP */
                else if (hcd->poll_pending)
@@ -901,17 +903,32 @@ EXPORT_SYMBOL (usb_calc_bus_time);
 
 /*-------------------------------------------------------------------------*/
 
-static void urb_unlink (struct urb *urb)
+static void urb_unlink(struct usb_hcd *hcd, struct urb *urb)
 {
        unsigned long           flags;
+       int at_root_hub = (urb->dev == hcd->self.root_hub);
 
        /* clear all state linking urb to this dev (and hcd) */
-
        spin_lock_irqsave (&hcd_data_lock, flags);
        list_del_init (&urb->urb_list);
        spin_unlock_irqrestore (&hcd_data_lock, flags);
-}
 
+       if (hcd->self.uses_dma && !at_root_hub) {
+               if (usb_pipecontrol (urb->pipe)
+                       && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP))
+                       dma_unmap_single (hcd->self.controller, urb->setup_dma,
+                                       sizeof (struct usb_ctrlrequest),
+                                       DMA_TO_DEVICE);
+               if (urb->transfer_buffer_length != 0
+                       && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP))
+                       dma_unmap_single (hcd->self.controller,
+                                       urb->transfer_dma,
+                                       urb->transfer_buffer_length,
+                                       usb_pipein (urb->pipe)
+                                           ? DMA_FROM_DEVICE
+                                           : DMA_TO_DEVICE);
+       }
+}
 
 /* may be called in any context with a valid urb->dev usecount
  * caller surrenders "ownership" of urb
@@ -948,19 +965,9 @@ int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags)
        else switch (hcd->state) {
        case HC_STATE_RUNNING:
        case HC_STATE_RESUMING:
-doit:
                list_add_tail (&urb->urb_list, &ep->urb_list);
                status = 0;
                break;
-       case HC_STATE_SUSPENDED:
-               /* HC upstream links (register access, wakeup signaling) can work
-                * even when the downstream links (and DMA etc) are quiesced; let
-                * usbcore talk to the root hub.
-                */
-               if (hcd->self.controller->power.power_state.event == PM_EVENT_ON
-                               && urb->dev->parent == NULL)
-                       goto doit;
-               /* FALL THROUGH */
        default:
                status = -ESHUTDOWN;
                break;
@@ -1014,7 +1021,7 @@ doit:
        status = hcd->driver->urb_enqueue (hcd, ep, urb, mem_flags);
 done:
        if (unlikely (status)) {
-               urb_unlink (urb);
+               urb_unlink(hcd, urb);
                atomic_dec (&urb->use_count);
                if (urb->reject)
                        wake_up (&usb_kill_urb_queue);
@@ -1255,42 +1262,59 @@ rescan:
 
 #ifdef CONFIG_PM
 
-int hcd_bus_suspend (struct usb_bus *bus)
+int hcd_bus_suspend(struct usb_device *rhdev)
 {
-       struct usb_hcd          *hcd;
-       int                     status;
+       struct usb_hcd  *hcd = container_of(rhdev->bus, struct usb_hcd, self);
+       int             status;
+       int             old_state = hcd->state;
 
-       hcd = container_of (bus, struct usb_hcd, self);
-       if (!hcd->driver->bus_suspend)
-               return -ENOENT;
-       hcd->state = HC_STATE_QUIESCING;
-       status = hcd->driver->bus_suspend (hcd);
-       if (status == 0)
+       dev_dbg(&rhdev->dev, "bus %s%s\n",
+                       rhdev->auto_pm ? "auto-" : "", "suspend");
+       if (!hcd->driver->bus_suspend) {
+               status = -ENOENT;
+       } else {
+               hcd->state = HC_STATE_QUIESCING;
+               status = hcd->driver->bus_suspend(hcd);
+       }
+       if (status == 0) {
+               usb_set_device_state(rhdev, USB_STATE_SUSPENDED);
                hcd->state = HC_STATE_SUSPENDED;
-       else
-               dev_dbg(&bus->root_hub->dev, "%s fail, err %d\n",
+       } else {
+               hcd->state = old_state;
+               dev_dbg(&rhdev->dev, "bus %s fail, err %d\n",
                                "suspend", status);
+       }
        return status;
 }
 
-int hcd_bus_resume (struct usb_bus *bus)
+int hcd_bus_resume(struct usb_device *rhdev)
 {
-       struct usb_hcd          *hcd;
-       int                     status;
+       struct usb_hcd  *hcd = container_of(rhdev->bus, struct usb_hcd, self);
+       int             status;
+       int             old_state = hcd->state;
 
-       hcd = container_of (bus, struct usb_hcd, self);
+       dev_dbg(&rhdev->dev, "usb %s%s\n",
+                       rhdev->auto_pm ? "auto-" : "", "resume");
        if (!hcd->driver->bus_resume)
                return -ENOENT;
        if (hcd->state == HC_STATE_RUNNING)
                return 0;
+
        hcd->state = HC_STATE_RESUMING;
-       status = hcd->driver->bus_resume (hcd);
-       if (status == 0)
+       status = hcd->driver->bus_resume(hcd);
+       if (status == 0) {
+               /* TRSMRCY = 10 msec */
+               msleep(10);
+               usb_set_device_state(rhdev, rhdev->actconfig
+                               ? USB_STATE_CONFIGURED
+                               : USB_STATE_ADDRESS);
                hcd->state = HC_STATE_RUNNING;
-       else {
-               dev_dbg(&bus->root_hub->dev, "%s fail, err %d\n",
+       } else {
+               hcd->state = old_state;
+               dev_dbg(&rhdev->dev, "bus %s fail, err %d\n",
                                "resume", status);
-               usb_hc_died(hcd);
+               if (status != -ESHUTDOWN)
+                       usb_hc_died(hcd);
        }
        return status;
 }
@@ -1384,30 +1408,10 @@ EXPORT_SYMBOL (usb_bus_start_enum);
  */
 void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb)
 {
-       int at_root_hub;
-
-       at_root_hub = (urb->dev == hcd->self.root_hub);
-       urb_unlink (urb);
-
-       /* lower level hcd code should use *_dma exclusively if the
-        * host controller does DMA */
-       if (hcd->self.uses_dma && !at_root_hub) {
-               if (usb_pipecontrol (urb->pipe)
-                       && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP))
-                       dma_unmap_single (hcd->self.controller, urb->setup_dma,
-                                       sizeof (struct usb_ctrlrequest),
-                                       DMA_TO_DEVICE);
-               if (urb->transfer_buffer_length != 0
-                       && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP))
-                       dma_unmap_single (hcd->self.controller, 
-                                       urb->transfer_dma,
-                                       urb->transfer_buffer_length,
-                                       usb_pipein (urb->pipe)
-                                           ? DMA_FROM_DEVICE
-                                           : DMA_TO_DEVICE);
-       }
-
+       urb_unlink(hcd, urb);
        usbmon_urb_complete (&hcd->self, urb);
+       usb_unanchor_urb(urb);
+
        /* pass ownership to the completion handler */
        urb->complete (urb);
        atomic_dec (&urb->use_count);
index ef50fa494e47838ec852e744bb689c9bb863065f..b5ebb73c23328cd5e65292f542d3d946e5ea9459 100644 (file)
@@ -364,23 +364,13 @@ extern int usb_find_interface_driver (struct usb_device *dev,
 #ifdef CONFIG_PM
 extern void usb_hcd_resume_root_hub (struct usb_hcd *hcd);
 extern void usb_root_hub_lost_power (struct usb_device *rhdev);
-extern int hcd_bus_suspend (struct usb_bus *bus);
-extern int hcd_bus_resume (struct usb_bus *bus);
+extern int hcd_bus_suspend(struct usb_device *rhdev);
+extern int hcd_bus_resume(struct usb_device *rhdev);
 #else
 static inline void usb_hcd_resume_root_hub(struct usb_hcd *hcd)
 {
        return;
 }
-
-static inline int hcd_bus_suspend(struct usb_bus *bus)
-{
-       return 0;
-}
-
-static inline int hcd_bus_resume (struct usb_bus *bus)
-{
-       return 0;
-}
 #endif /* CONFIG_PM */
 
 /*
index 24f10a19dbdbc1bbbf6befd31da7018078cfa186..50e79010401cd42050062d52d1c1e9876cc0aa53 100644 (file)
 #include "hcd.h"
 #include "hub.h"
 
+#ifdef CONFIG_USB_PERSIST
+#define        USB_PERSIST     1
+#else
+#define        USB_PERSIST     0
+#endif
+
 struct usb_hub {
        struct device           *intfdev;       /* the "interface" device */
        struct usb_device       *hdev;
+       struct kref             kref;
        struct urb              *urb;           /* for interrupt polling pipe */
 
        /* buffer for urb ... with extra space in case of babble */
@@ -66,6 +73,7 @@ struct usb_hub {
        unsigned                limited_power:1;
        unsigned                quiescing:1;
        unsigned                activating:1;
+       unsigned                disconnected:1;
 
        unsigned                has_indicators:1;
        u8                      indicator[USB_MAXCHILDREN];
@@ -321,7 +329,7 @@ static void kick_khubd(struct usb_hub *hub)
        to_usb_interface(hub->intfdev)->pm_usage_cnt = 1;
 
        spin_lock_irqsave(&hub_event_lock, flags);
-       if (list_empty(&hub->event_list)) {
+       if (!hub->disconnected & list_empty(&hub->event_list)) {
                list_add_tail(&hub->event_list, &hub_event_list);
                wake_up(&khubd_wait);
        }
@@ -330,6 +338,7 @@ static void kick_khubd(struct usb_hub *hub)
 
 void usb_kick_khubd(struct usb_device *hdev)
 {
+       /* FIXME: What if hdev isn't bound to the hub driver? */
        kick_khubd(hdev_to_hub(hdev));
 }
 
@@ -400,9 +409,10 @@ static void hub_tt_kevent (struct work_struct *work)
        struct usb_hub          *hub =
                container_of(work, struct usb_hub, tt.kevent);
        unsigned long           flags;
+       int                     limit = 100;
 
        spin_lock_irqsave (&hub->tt.lock, flags);
-       while (!list_empty (&hub->tt.clear_list)) {
+       while (--limit && !list_empty (&hub->tt.clear_list)) {
                struct list_head        *temp;
                struct usb_tt_clear     *clear;
                struct usb_device       *hdev = hub->hdev;
@@ -550,48 +560,68 @@ static int hub_hub_status(struct usb_hub *hub,
 static int hub_port_disable(struct usb_hub *hub, int port1, int set_state)
 {
        struct usb_device *hdev = hub->hdev;
-       int ret;
+       int ret = 0;
 
-       if (hdev->children[port1-1] && set_state) {
+       if (hdev->children[port1-1] && set_state)
                usb_set_device_state(hdev->children[port1-1],
                                USB_STATE_NOTATTACHED);
-       }
-       ret = clear_port_feature(hdev, port1, USB_PORT_FEAT_ENABLE);
+       if (!hub->error)
+               ret = clear_port_feature(hdev, port1, USB_PORT_FEAT_ENABLE);
        if (ret)
                dev_err(hub->intfdev, "cannot disable port %d (err = %d)\n",
-                       port1, ret);
-
+                               port1, ret);
        return ret;
 }
 
+/*
+ * Disable a port and mark a logical connnect-change event, so that some
+ * time later khubd will disconnect() any existing usb_device on the port
+ * and will re-enumerate if there actually is a device attached.
+ */
+static void hub_port_logical_disconnect(struct usb_hub *hub, int port1)
+{
+       dev_dbg(hub->intfdev, "logical disconnect on port %d\n", port1);
+       hub_port_disable(hub, port1, 1);
+
+       /* FIXME let caller ask to power down the port:
+        *  - some devices won't enumerate without a VBUS power cycle
+        *  - SRP saves power that way
+        *  - ... new call, TBD ...
+        * That's easy if this hub can switch power per-port, and
+        * khubd reactivates the port later (timer, SRP, etc).
+        * Powerdown must be optional, because of reset/DFU.
+        */
+
+       set_bit(port1, hub->change_bits);
+       kick_khubd(hub);
+}
 
 /* caller has locked the hub device */
-static void hub_pre_reset(struct usb_interface *intf)
+static int hub_pre_reset(struct usb_interface *intf)
 {
        struct usb_hub *hub = usb_get_intfdata(intf);
        struct usb_device *hdev = hub->hdev;
-       int port1;
+       int i;
 
-       for (port1 = 1; port1 <= hdev->maxchild; ++port1) {
-               if (hdev->children[port1 - 1]) {
-                       usb_disconnect(&hdev->children[port1 - 1]);
-                       if (hub->error == 0)
-                               hub_port_disable(hub, port1, 0);
-               }
+       /* Disconnect all the children */
+       for (i = 0; i < hdev->maxchild; ++i) {
+               if (hdev->children[i])
+                       usb_disconnect(&hdev->children[i]);
        }
        hub_quiesce(hub);
+       return 0;
 }
 
 /* caller has locked the hub device */
-static void hub_post_reset(struct usb_interface *intf)
+static int hub_post_reset(struct usb_interface *intf)
 {
        struct usb_hub *hub = usb_get_intfdata(intf);
 
-       hub_activate(hub);
        hub_power_on(hub);
+       hub_activate(hub);
+       return 0;
 }
 
-
 static int hub_configure(struct usb_hub *hub,
        struct usb_endpoint_descriptor *endpoint)
 {
@@ -845,43 +875,42 @@ fail:
        return ret;
 }
 
+static void hub_release(struct kref *kref)
+{
+       struct usb_hub *hub = container_of(kref, struct usb_hub, kref);
+
+       usb_put_intf(to_usb_interface(hub->intfdev));
+       kfree(hub);
+}
+
 static unsigned highspeed_hubs;
 
 static void hub_disconnect(struct usb_interface *intf)
 {
        struct usb_hub *hub = usb_get_intfdata (intf);
-       struct usb_device *hdev;
+
+       /* Take the hub off the event list and don't let it be added again */
+       spin_lock_irq(&hub_event_lock);
+       list_del_init(&hub->event_list);
+       hub->disconnected = 1;
+       spin_unlock_irq(&hub_event_lock);
 
        /* Disconnect all children and quiesce the hub */
        hub->error = 0;
        hub_pre_reset(intf);
 
        usb_set_intfdata (intf, NULL);
-       hdev = hub->hdev;
 
-       if (hdev->speed == USB_SPEED_HIGH)
+       if (hub->hdev->speed == USB_SPEED_HIGH)
                highspeed_hubs--;
 
        usb_free_urb(hub->urb);
-       hub->urb = NULL;
-
-       spin_lock_irq(&hub_event_lock);
-       list_del_init(&hub->event_list);
-       spin_unlock_irq(&hub_event_lock);
-
        kfree(hub->descriptor);
-       hub->descriptor = NULL;
-
        kfree(hub->status);
-       hub->status = NULL;
-
-       if (hub->buffer) {
-               usb_buffer_free(hdev, sizeof(*hub->buffer), hub->buffer,
-                               hub->buffer_dma);
-               hub->buffer = NULL;
-       }
+       usb_buffer_free(hub->hdev, sizeof(*hub->buffer), hub->buffer,
+                       hub->buffer_dma);
 
-       kfree(hub);
+       kref_put(&hub->kref, hub_release);
 }
 
 static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
@@ -929,10 +958,12 @@ descriptor_error:
                return -ENOMEM;
        }
 
+       kref_init(&hub->kref);
        INIT_LIST_HEAD(&hub->event_list);
        hub->intfdev = &intf->dev;
        hub->hdev = hdev;
        INIT_DELAYED_WORK(&hub->leds, led_work);
+       usb_get_intf(intf);
 
        usb_set_intfdata (intf, hub);
        intf->needs_remote_wakeup = 1;
@@ -982,49 +1013,6 @@ hub_ioctl(struct usb_interface *intf, unsigned int code, void *user_data)
 }
 
 
-/* grab device/port lock, returning index of that port (zero based).
- * protects the upstream link used by this device from concurrent
- * tree operations like suspend, resume, reset, and disconnect, which
- * apply to everything downstream of a given port.
- */
-static int locktree(struct usb_device *udev)
-{
-       int                     t;
-       struct usb_device       *hdev;
-
-       if (!udev)
-               return -ENODEV;
-
-       /* root hub is always the first lock in the series */
-       hdev = udev->parent;
-       if (!hdev) {
-               usb_lock_device(udev);
-               return 0;
-       }
-
-       /* on the path from root to us, lock everything from
-        * top down, dropping parent locks when not needed
-        */
-       t = locktree(hdev);
-       if (t < 0)
-               return t;
-
-       /* everything is fail-fast once disconnect
-        * processing starts
-        */
-       if (udev->state == USB_STATE_NOTATTACHED) {
-               usb_unlock_device(hdev);
-               return -ENODEV;
-       }
-
-       /* when everyone grabs locks top->bottom,
-        * non-overlapping work may be concurrent
-        */
-       usb_lock_device(udev);
-       usb_unlock_device(hdev);
-       return udev->portnum;
-}
-
 static void recursively_mark_NOTATTACHED(struct usb_device *udev)
 {
        int i;
@@ -1089,46 +1077,6 @@ void usb_set_device_state(struct usb_device *udev,
        spin_unlock_irqrestore(&device_state_lock, flags);
 }
 
-
-#ifdef CONFIG_PM
-
-/**
- * usb_root_hub_lost_power - called by HCD if the root hub lost Vbus power
- * @rhdev: struct usb_device for the root hub
- *
- * The USB host controller driver calls this function when its root hub
- * is resumed and Vbus power has been interrupted or the controller
- * has been reset.  The routine marks all the children of the root hub
- * as NOTATTACHED and marks logical connect-change events on their ports.
- */
-void usb_root_hub_lost_power(struct usb_device *rhdev)
-{
-       struct usb_hub *hub;
-       int port1;
-       unsigned long flags;
-
-       dev_warn(&rhdev->dev, "root hub lost power or was reset\n");
-
-       /* Make sure no potential wakeup events get lost,
-        * by forcing the root hub to be resumed.
-        */
-       rhdev->dev.power.prev_state.event = PM_EVENT_ON;
-
-       spin_lock_irqsave(&device_state_lock, flags);
-       hub = hdev_to_hub(rhdev);
-       for (port1 = 1; port1 <= rhdev->maxchild; ++port1) {
-               if (rhdev->children[port1 - 1]) {
-                       recursively_mark_NOTATTACHED(
-                                       rhdev->children[port1 - 1]);
-                       set_bit(port1, hub->change_bits);
-               }
-       }
-       spin_unlock_irqrestore(&device_state_lock, flags);
-}
-EXPORT_SYMBOL_GPL(usb_root_hub_lost_power);
-
-#endif /* CONFIG_PM */
-
 static void choose_address(struct usb_device *udev)
 {
        int             devnum;
@@ -1269,7 +1217,6 @@ static inline void show_string(struct usb_device *udev, char *id, char *string)
 
 #ifdef CONFIG_USB_OTG
 #include "otg_whitelist.h"
-static int __usb_port_suspend(struct usb_device *, int port1);
 #endif
 
 /**
@@ -1375,11 +1322,11 @@ int usb_new_device(struct usb_device *udev)
                 * (Includes HNP test device.)
                 */
                if (udev->bus->b_hnp_enable || udev->bus->is_b_host) {
-                       err = __usb_port_suspend(udev, udev->bus->otg_port);
+                       err = usb_port_suspend(udev);
                        if (err < 0)
                                dev_dbg(&udev->dev, "HNP fail, %d\n", err);
                }
-               err = -ENODEV;
+               err = -ENOTSUPP;
                goto fail;
        }
 #endif
@@ -1476,9 +1423,9 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1,
                if (!(portstatus & USB_PORT_STAT_CONNECTION))
                        return -ENOTCONN;
 
-               /* bomb out completely if something weird happened */
+               /* bomb out completely if the connection bounced */
                if ((portchange & USB_PORT_STAT_C_CONNECTION))
-                       return -EINVAL;
+                       return -ENOTCONN;
 
                /* if we`ve finished resetting, then break out of the loop */
                if (!(portstatus & USB_PORT_STAT_RESET) &&
@@ -1557,34 +1504,24 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
        return status;
 }
 
-/*
- * Disable a port and mark a logical connnect-change event, so that some
- * time later khubd will disconnect() any existing usb_device on the port
- * and will re-enumerate if there actually is a device attached.
- */
-static void hub_port_logical_disconnect(struct usb_hub *hub, int port1)
-{
-       dev_dbg(hub->intfdev, "logical disconnect on port %d\n", port1);
-       hub_port_disable(hub, port1, 1);
-
-       /* FIXME let caller ask to power down the port:
-        *  - some devices won't enumerate without a VBUS power cycle
-        *  - SRP saves power that way
-        *  - ... new call, TBD ...
-        * That's easy if this hub can switch power per-port, and
-        * khubd reactivates the port later (timer, SRP, etc).
-        * Powerdown must be optional, because of reset/DFU.
-        */
-
-       set_bit(port1, hub->change_bits);
-       kick_khubd(hub);
-}
-
 #ifdef CONFIG_PM
 
 #ifdef CONFIG_USB_SUSPEND
 
 /*
+ * usb_port_suspend - suspend a usb device's upstream port
+ * @udev: device that's no longer in active use, not a root hub
+ * Context: must be able to sleep; device not locked; pm locks held
+ *
+ * Suspends a USB device that isn't in active use, conserving power.
+ * Devices may wake out of a suspend, if anything important happens,
+ * using the remote wakeup mechanism.  They may also be taken out of
+ * suspend by the host, using usb_port_resume().  It's also routine
+ * to disconnect devices while they are suspended.
+ *
+ * This only affects the USB hardware for a device; its interfaces
+ * (and, for hubs, child devices) must already have been suspended.
+ *
  * Selective port suspend reduces power; most suspended devices draw
  * less than 500 uA.  It's also used in OTG, along with remote wakeup.
  * All devices below the suspended port are also suspended.
@@ -1593,11 +1530,35 @@ static void hub_port_logical_disconnect(struct usb_hub *hub, int port1)
  * also support "remote wakeup", where the device can activate the USB
  * tree above them to deliver data, such as a keypress or packet.  In
  * some cases, this wakes the USB host.
+ *
+ * Suspending OTG devices may trigger HNP, if that's been enabled
+ * between a pair of dual-role devices.  That will change roles, such
+ * as from A-Host to A-Peripheral or from B-Host back to B-Peripheral.
+ *
+ * Devices on USB hub ports have only one "suspend" state, corresponding
+ * to ACPI D2, "may cause the device to lose some context".
+ * State transitions include:
+ *
+ *   - suspend, resume ... when the VBUS power link stays live
+ *   - suspend, disconnect ... VBUS lost
+ *
+ * Once VBUS drop breaks the circuit, the port it's using has to go through
+ * normal re-enumeration procedures, starting with enabling VBUS power.
+ * Other than re-initializing the hub (plug/unplug, except for root hubs),
+ * Linux (2.6) currently has NO mechanisms to initiate that:  no khubd
+ * timer, no SRP, no requests through sysfs.
+ *
+ * If CONFIG_USB_SUSPEND isn't enabled, devices only really suspend when
+ * the root hub for their bus goes into global suspend ... so we don't
+ * (falsely) update the device power state to say it suspended.
+ *
+ * Returns 0 on success, else negative errno.
  */
-static int hub_port_suspend(struct usb_hub *hub, int port1,
-               struct usb_device *udev)
+int usb_port_suspend(struct usb_device *udev)
 {
-       int     status;
+       struct usb_hub  *hub = hdev_to_hub(udev->parent);
+       int             port1 = udev->portnum;
+       int             status;
 
        // dev_dbg(hub->intfdev, "suspend port %d\n", port1);
 
@@ -1614,17 +1575,15 @@ static int hub_port_suspend(struct usb_hub *hub, int port1,
                                NULL, 0,
                                USB_CTRL_SET_TIMEOUT);
                if (status)
-                       dev_dbg(&udev->dev,
-                               "won't remote wakeup, status %d\n",
-                               status);
+                       dev_dbg(&udev->dev, "won't remote wakeup, status %d\n",
+                                       status);
        }
 
        /* see 7.1.7.6 */
        status = set_port_feature(hub->hdev, port1, USB_PORT_FEAT_SUSPEND);
        if (status) {
-               dev_dbg(hub->intfdev,
-                       "can't suspend port %d, status %d\n",
-                       port1, status);
+               dev_dbg(hub->intfdev, "can't suspend port %d, status %d\n",
+                               port1, status);
                /* paranoia:  "should not happen" */
                (void) usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
                                USB_REQ_CLEAR_FEATURE, USB_RECIP_DEVICE,
@@ -1641,86 +1600,25 @@ static int hub_port_suspend(struct usb_hub *hub, int port1,
        return status;
 }
 
-/*
- * Devices on USB hub ports have only one "suspend" state, corresponding
- * to ACPI D2, "may cause the device to lose some context".
- * State transitions include:
- *
- *   - suspend, resume ... when the VBUS power link stays live
- *   - suspend, disconnect ... VBUS lost
- *
- * Once VBUS drop breaks the circuit, the port it's using has to go through
- * normal re-enumeration procedures, starting with enabling VBUS power.
- * Other than re-initializing the hub (plug/unplug, except for root hubs),
- * Linux (2.6) currently has NO mechanisms to initiate that:  no khubd
- * timer, no SRP, no requests through sysfs.
- *
- * If CONFIG_USB_SUSPEND isn't enabled, devices only really suspend when
- * the root hub for their bus goes into global suspend ... so we don't
- * (falsely) update the device power state to say it suspended.
- */
-static int __usb_port_suspend (struct usb_device *udev, int port1)
-{
-       int     status = 0;
-
-       /* caller owns the udev device lock */
-       if (port1 < 0)
-               return port1;
-
-       /* we change the device's upstream USB link,
-        * but root hubs have no upstream USB link.
-        */
-       if (udev->parent)
-               status = hub_port_suspend(hdev_to_hub(udev->parent), port1,
-                               udev);
-       else {
-               dev_dbg(&udev->dev, "usb %ssuspend\n",
-                               udev->auto_pm ? "auto-" : "");
-               usb_set_device_state(udev, USB_STATE_SUSPENDED);
-       }
-       return status;
-}
-
-/*
- * usb_port_suspend - suspend a usb device's upstream port
- * @udev: device that's no longer in active use
- * Context: must be able to sleep; device not locked; pm locks held
- *
- * Suspends a USB device that isn't in active use, conserving power.
- * Devices may wake out of a suspend, if anything important happens,
- * using the remote wakeup mechanism.  They may also be taken out of
- * suspend by the host, using usb_port_resume().  It's also routine
- * to disconnect devices while they are suspended.
- *
- * This only affects the USB hardware for a device; its interfaces
- * (and, for hubs, child devices) must already have been suspended.
- *
- * Suspending OTG devices may trigger HNP, if that's been enabled
- * between a pair of dual-role devices.  That will change roles, such
- * as from A-Host to A-Peripheral or from B-Host back to B-Peripheral.
- *
- * Returns 0 on success, else negative errno.
- */
-int usb_port_suspend(struct usb_device *udev)
-{
-       return __usb_port_suspend(udev, udev->portnum);
-}
-
 /*
  * If the USB "suspend" state is in use (rather than "global suspend"),
  * many devices will be individually taken out of suspend state using
- * special" resume" signaling.  These routines kick in shortly after
+ * special "resume" signaling.  This routine kicks in shortly after
  * hardware resume signaling is finished, either because of selective
  * resume (by host) or remote wakeup (by device) ... now see what changed
  * in the tree that's rooted at this device.
+ *
+ * If @udev->reset_resume is set then the device is reset before the
+ * status check is done.
  */
 static int finish_port_resume(struct usb_device *udev)
 {
-       int     status;
+       int     status = 0;
        u16     devstatus;
 
        /* caller owns the udev device lock */
-       dev_dbg(&udev->dev, "finish resume\n");
+       dev_dbg(&udev->dev, "finish %sresume\n",
+                       udev->reset_resume ? "reset-" : "");
 
        /* usb ch9 identifies four variants of SUSPENDED, based on what
         * state the device resumes to.  Linux currently won't see the
@@ -1731,22 +1629,30 @@ static int finish_port_resume(struct usb_device *udev)
                        ? USB_STATE_CONFIGURED
                        : USB_STATE_ADDRESS);
 
+       /* 10.5.4.5 says not to reset a suspended port if the attached
+        * device is enabled for remote wakeup.  Hence the reset
+        * operation is carried out here, after the port has been
+        * resumed.
+        */
+       if (udev->reset_resume)
+               status = usb_reset_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,
         * and device drivers will know about any resume quirks.
         */
-       status = usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus);
-       if (status >= 0)
-               status = (status == 2 ? 0 : -ENODEV);
+       if (status == 0) {
+               status = usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus);
+               if (status >= 0)
+                       status = (status == 2 ? 0 : -ENODEV);
+       }
 
-       if (status)
-               dev_dbg(&udev->dev,
-                       "gone after usb resume? status %d\n",
-                       status);
-       else if (udev->actconfig) {
+       if (status) {
+               dev_dbg(&udev->dev, "gone after usb resume? status %d\n",
+                               status);
+       } else if (udev->actconfig) {
                le16_to_cpus(&devstatus);
-               if ((devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP))
-                               && udev->parent) {
+               if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) {
                        status = usb_control_msg(udev,
                                        usb_sndctrlpipe(udev, 0),
                                        USB_REQ_CLEAR_FEATURE,
@@ -1759,19 +1665,52 @@ static int finish_port_resume(struct usb_device *udev)
                                        "wakeup, status %d\n", status);
                }
                status = 0;
-
-       } else if (udev->devnum <= 0) {
-               dev_dbg(&udev->dev, "bogus resume!\n");
-               status = -EINVAL;
        }
        return status;
 }
 
-static int
-hub_port_resume(struct usb_hub *hub, int port1, struct usb_device *udev)
+/*
+ * usb_port_resume - re-activate a suspended usb device's upstream port
+ * @udev: device to re-activate, not a root hub
+ * Context: must be able to sleep; device not locked; pm locks held
+ *
+ * This will re-activate the suspended device, increasing power usage
+ * while letting drivers communicate again with its endpoints.
+ * USB resume explicitly guarantees that the power session between
+ * the host and the device is the same as it was when the device
+ * suspended.
+ *
+ * If CONFIG_USB_PERSIST and @udev->reset_resume are both set then this
+ * routine won't check that the port is still enabled.  Furthermore,
+ * if @udev->reset_resume is set then finish_port_resume() above will
+ * reset @udev.  The end result is that a broken power session can be
+ * recovered and @udev will appear to persist across a loss of VBUS power.
+ *
+ * For example, if a host controller doesn't maintain VBUS suspend current
+ * during a system sleep or is reset when the system wakes up, all the USB
+ * power sessions below it will be broken.  This is especially troublesome
+ * for mass-storage devices containing mounted filesystems, since the
+ * device will appear to have disconnected and all the memory mappings
+ * 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 is inherently dangerous.  Although usb_reset_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
+ * changed.  If the user replaces a flash memory card while the system is
+ * asleep, he will have only himself to blame when the filesystem on the
+ * new card is corrupted and the system crashes.
+ *
+ * Returns 0 on success, else negative errno.
+ */
+int usb_port_resume(struct usb_device *udev)
 {
-       int     status;
-       u16     portchange, portstatus;
+       struct usb_hub  *hub = hdev_to_hub(udev->parent);
+       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);
@@ -1786,30 +1725,31 @@ hub_port_resume(struct usb_hub *hub, int port1, struct usb_device *udev)
        status = clear_port_feature(hub->hdev,
                        port1, USB_PORT_FEAT_SUSPEND);
        if (status) {
-               dev_dbg(hub->intfdev,
-                       "can't resume port %d, status %d\n",
-                       port1, status);
+               dev_dbg(hub->intfdev, "can't resume port %d, status %d\n",
+                               port1, status);
        } else {
                /* drive resume for at least 20 msec */
-               if (udev)
-                       dev_dbg(&udev->dev, "usb %sresume\n",
-                                       udev->auto_pm ? "auto-" : "");
+               dev_dbg(&udev->dev, "usb %sresume\n",
+                               udev->auto_pm ? "auto-" : "");
                msleep(25);
 
-#define LIVE_FLAGS     ( USB_PORT_STAT_POWER \
-                       | USB_PORT_STAT_ENABLE \
-                       | USB_PORT_STAT_CONNECTION)
-
                /* Virtual root hubs can trigger on GET_PORT_STATUS to
                 * stop resume signaling.  Then finish the resume
                 * sequence.
                 */
                status = hub_port_status(hub, port1, &portstatus, &portchange);
-SuspendCleared:
-               if (status < 0
-                               || (portstatus & LIVE_FLAGS) != LIVE_FLAGS
-                               || (portstatus & USB_PORT_STAT_SUSPEND) != 0
-                               ) {
+
+ SuspendCleared:
+               if (USB_PERSIST && 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;
+
+               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);
@@ -1821,51 +1761,19 @@ SuspendCleared:
                                                USB_PORT_FEAT_C_SUSPEND);
                        /* TRSMRCY = 10 msec */
                        msleep(10);
-                       if (udev)
-                               status = finish_port_resume(udev);
                }
        }
-       if (status < 0)
-               hub_port_logical_disconnect(hub, port1);
 
        clear_bit(port1, hub->busy_bits);
        if (!hub->hdev->parent && !hub->busy_bits[0])
                usb_enable_root_hub_irq(hub->hdev->bus);
 
-       return status;
-}
-
-/*
- * usb_port_resume - re-activate a suspended usb device's upstream port
- * @udev: device to re-activate
- * Context: must be able to sleep; device not locked; pm locks held
- *
- * This will re-activate the suspended device, increasing power usage
- * while letting drivers communicate again with its endpoints.
- * USB resume explicitly guarantees that the power session between
- * the host and the device is the same as it was when the device
- * suspended.
- *
- * Returns 0 on success, else negative errno.
- */
-int usb_port_resume(struct usb_device *udev)
-{
-       int     status;
-
-       /* we change the device's upstream USB link,
-        * but root hubs have no upstream USB link.
-        */
-       if (udev->parent) {
-               // NOTE this fails if parent is also suspended...
-               status = hub_port_resume(hdev_to_hub(udev->parent),
-                               udev->portnum, udev);
-       } else {
-               dev_dbg(&udev->dev, "usb %sresume\n",
-                               udev->auto_pm ? "auto-" : "");
+       if (status == 0)
                status = finish_port_resume(udev);
-       }
-       if (status < 0)
+       if (status < 0) {
                dev_dbg(&udev->dev, "can't resume, status %d\n", status);
+               hub_port_logical_disconnect(hub, port1);
+       }
        return status;
 }
 
@@ -1892,21 +1800,16 @@ int usb_port_suspend(struct usb_device *udev)
        return 0;
 }
 
-static inline int
-finish_port_resume(struct usb_device *udev)
-{
-       return 0;
-}
-
-static inline int
-hub_port_resume(struct usb_hub *hub, int port1, struct usb_device *udev)
-{
-       return 0;
-}
-
 int usb_port_resume(struct usb_device *udev)
 {
-       return 0;
+       int status = 0;
+
+       /* However we may need to do a reset-resume */
+       if (udev->reset_resume) {
+               dev_dbg(&udev->dev, "reset-resume\n");
+               status = usb_reset_device(udev);
+       }
+       return status;
 }
 
 static inline int remote_wakeup(struct usb_device *udev)
@@ -1921,7 +1824,6 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
        struct usb_hub          *hub = usb_get_intfdata (intf);
        struct usb_device       *hdev = hub->hdev;
        unsigned                port1;
-       int                     status = 0;
 
        /* fail if children aren't already suspended */
        for (port1 = 1; port1 <= hdev->maxchild; port1++) {
@@ -1947,49 +1849,75 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
 
        /* stop khubd and related activity */
        hub_quiesce(hub);
-
-       /* "global suspend" of the downstream HC-to-USB interface */
-       if (!hdev->parent) {
-               status = hcd_bus_suspend(hdev->bus);
-               if (status != 0) {
-                       dev_dbg(&hdev->dev, "'global' suspend %d\n", status);
-                       hub_activate(hub);
-               }
-       }
-       return status;
+       return 0;
 }
 
 static int hub_resume(struct usb_interface *intf)
 {
        struct usb_hub          *hub = usb_get_intfdata (intf);
-       struct usb_device       *hdev = hub->hdev;
-       int                     status;
 
        dev_dbg(&intf->dev, "%s\n", __FUNCTION__);
 
-       /* "global resume" of the downstream HC-to-USB interface */
-       if (!hdev->parent) {
-               struct usb_bus  *bus = hdev->bus;
-               if (bus) {
-                       status = hcd_bus_resume (bus);
-                       if (status) {
-                               dev_dbg(&intf->dev, "'global' resume %d\n",
-                                       status);
-                               return status;
+       /* tell khubd to look for changes on this hub */
+       hub_activate(hub);
+       return 0;
+}
+
+static int hub_reset_resume(struct usb_interface *intf)
+{
+       struct usb_hub *hub = usb_get_intfdata(intf);
+       struct usb_device *hdev = hub->hdev;
+       int port1;
+
+       hub_power_on(hub);
+
+       for (port1 = 1; port1 <= hdev->maxchild; ++port1) {
+               struct usb_device *child = hdev->children[port1-1];
+
+               if (child) {
+
+                       /* For "USB_PERSIST"-enabled children we must
+                        * mark the child device for reset-resume and
+                        * turn off the connect-change status to prevent
+                        * khubd from disconnecting it later.
+                        */
+                       if (USB_PERSIST && child->persist_enabled) {
+                               child->reset_resume = 1;
+                               clear_port_feature(hdev, port1,
+                                               USB_PORT_FEAT_C_CONNECTION);
+
+                       /* Otherwise we must disconnect the child,
+                        * but as we may not lock the child device here
+                        * we have to do a "logical" disconnect.
+                        */
+                       } else {
+                               hub_port_logical_disconnect(hub, port1);
                        }
-               } else
-                       return -EOPNOTSUPP;
-               if (status == 0) {
-                       /* TRSMRCY = 10 msec */
-                       msleep(10);
                }
        }
 
-       /* tell khubd to look for changes on this hub */
        hub_activate(hub);
        return 0;
 }
 
+/**
+ * usb_root_hub_lost_power - called by HCD if the root hub lost Vbus power
+ * @rhdev: struct usb_device for the root hub
+ *
+ * The USB host controller driver calls this function when its root hub
+ * is resumed and Vbus power has been interrupted or the controller
+ * has been reset.  The routine marks @rhdev as having lost power.  When
+ * the hub driver is resumed it will take notice; if CONFIG_USB_PERSIST
+ * is enabled then it will carry out power-session recovery, otherwise
+ * it will disconnect all the child devices.
+ */
+void usb_root_hub_lost_power(struct usb_device *rhdev)
+{
+       dev_warn(&rhdev->dev, "root hub lost power or was reset\n");
+       rhdev->reset_resume = 1;
+}
+EXPORT_SYMBOL_GPL(usb_root_hub_lost_power);
+
 #else  /* CONFIG_PM */
 
 static inline int remote_wakeup(struct usb_device *udev)
@@ -1997,8 +1925,9 @@ static inline int remote_wakeup(struct usb_device *udev)
        return 0;
 }
 
-#define hub_suspend NULL
-#define hub_resume NULL
+#define hub_suspend            NULL
+#define hub_resume             NULL
+#define hub_reset_resume       NULL
 #endif
 
 
@@ -2461,19 +2390,6 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
                return;
        }
 
-#ifdef  CONFIG_USB_SUSPEND
-       /* If something is connected, but the port is suspended, wake it up. */
-       if (portstatus & USB_PORT_STAT_SUSPEND) {
-               status = hub_port_resume(hub, port1, NULL);
-               if (status < 0) {
-                       dev_dbg(hub_dev,
-                               "can't clear suspend on port %d; %d\n",
-                               port1, status);
-                       goto done;
-               }
-       }
-#endif
-
        for (i = 0; i < SET_CONFIG_TRIES; i++) {
                struct usb_device *udev;
 
@@ -2584,7 +2500,7 @@ loop:
                ep0_reinit(udev);
                release_address(udev);
                usb_put_dev(udev);
-               if (status == -ENOTCONN)
+               if ((status == -ENOTCONN) || (status == -ENOTSUPP))
                        break;
        }
  
@@ -2625,10 +2541,12 @@ static void hub_events(void)
                list_del_init(tmp);
 
                hub = list_entry(tmp, struct usb_hub, event_list);
-               hdev = hub->hdev;
-               intf = to_usb_interface(hub->intfdev);
-               hub_dev = &intf->dev;
+               kref_get(&hub->kref);
+               spin_unlock_irq(&hub_event_lock);
 
+               hdev = hub->hdev;
+               hub_dev = hub->intfdev;
+               intf = to_usb_interface(hub_dev);
                dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x\n",
                                hdev->state, hub->descriptor
                                        ? hub->descriptor->bNbrPorts
@@ -2637,16 +2555,10 @@ static void hub_events(void)
                                (u16) hub->change_bits[0],
                                (u16) hub->event_bits[0]);
 
-               usb_get_intf(intf);
-               spin_unlock_irq(&hub_event_lock);
-
                /* Lock the device, then check to see if we were
                 * disconnected while waiting for the lock to succeed. */
-               if (locktree(hdev) < 0) {
-                       usb_put_intf(intf);
-                       continue;
-               }
-               if (hub != usb_get_intfdata(intf))
+               usb_lock_device(hdev);
+               if (unlikely(hub->disconnected))
                        goto loop;
 
                /* If the hub has died, clean up after it */
@@ -2809,7 +2721,7 @@ loop_autopm:
                        usb_autopm_enable(intf);
 loop:
                usb_unlock_device(hdev);
-               usb_put_intf(intf);
+               kref_put(&hub->kref, hub_release);
 
         } /* end while (1) */
 }
@@ -2844,6 +2756,7 @@ static struct usb_driver hub_driver = {
        .disconnect =   hub_disconnect,
        .suspend =      hub_suspend,
        .resume =       hub_resume,
+       .reset_resume = hub_reset_resume,
        .pre_reset =    hub_pre_reset,
        .post_reset =   hub_post_reset,
        .ioctl =        hub_ioctl,
@@ -2946,6 +2859,11 @@ static int config_descriptors_changed(struct usb_device *udev)
  * 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().
+ *
+ * Locking exception: This routine may also be called from within an
+ * autoresume handler.  Such usage won't conflict with other tasks
+ * 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)
 {
@@ -2976,7 +2894,7 @@ int usb_reset_device(struct usb_device *udev)
                 * Other endpoints will be handled by re-enumeration. */
                ep0_reinit(udev);
                ret = hub_port_init(parent_hub, udev, port1, i);
-               if (ret >= 0)
+               if (ret >= 0 || ret == -ENOTCONN || ret == -ENODEV)
                        break;
        }
        clear_bit(port1, parent_hub->busy_bits);
@@ -3092,6 +3010,7 @@ int usb_reset_composite_device(struct usb_device *udev,
                                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 */
                        }
                }
        }
@@ -3110,6 +3029,7 @@ int usb_reset_composite_device(struct usb_device *udev,
                                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 */
                        }
                        if (cintf != iface)
                                up(&cintf->dev.sem);
index f9fed34bf7d8b307491aee6d91c84edd686f28ed..530e854961ce99785291b399d92253151c626d9e 100644 (file)
@@ -404,8 +404,6 @@ int usb_sg_init (
 
                io->urbs [i]->complete = sg_complete;
                io->urbs [i]->context = io;
-               io->urbs [i]->status = -EINPROGRESS;
-               io->urbs [i]->actual_length = 0;
 
                /*
                 * Some systems need to revert to PIO when DMA is temporarily
@@ -499,7 +497,8 @@ void usb_sg_wait (struct usb_sg_request *io)
 
        /* queue the urbs.  */
        spin_lock_irq (&io->lock);
-       for (i = 0; i < entries && !io->status; i++) {
+       i = 0;
+       while (i < entries && !io->status) {
                int     retval;
 
                io->urbs [i]->dev = io->dev;
@@ -516,7 +515,6 @@ void usb_sg_wait (struct usb_sg_request *io)
                case -ENOMEM:
                        io->urbs[i]->dev = NULL;
                        retval = 0;
-                       i--;
                        yield ();
                        break;
 
@@ -527,6 +525,7 @@ void usb_sg_wait (struct usb_sg_request *io)
                         * URBs are queued at once; N milliseconds?
                         */
                case 0:
+                       ++i;
                        cpu_relax ();
                        break;
 
@@ -1385,6 +1384,36 @@ struct device_type usb_if_device_type = {
        .uevent =       usb_if_uevent,
 };
 
+static struct usb_interface_assoc_descriptor *find_iad(struct usb_device *dev,
+                                                      struct usb_host_config *config,
+                                                      u8 inum)
+{
+       struct usb_interface_assoc_descriptor *retval = NULL;
+       struct usb_interface_assoc_descriptor *intf_assoc;
+       int first_intf;
+       int last_intf;
+       int i;
+
+       for (i = 0; (i < USB_MAXIADS && config->intf_assoc[i]); i++) {
+               intf_assoc = config->intf_assoc[i];
+               if (intf_assoc->bInterfaceCount == 0)
+                       continue;
+
+               first_intf = intf_assoc->bFirstInterface;
+               last_intf = first_intf + (intf_assoc->bInterfaceCount - 1);
+               if (inum >= first_intf && inum <= last_intf) {
+                       if (!retval)
+                               retval = intf_assoc;
+                       else
+                               dev_err(&dev->dev, "Interface #%d referenced"
+                                       " by multiple IADs\n", inum);
+               }
+       }
+
+       return retval;
+}
+
+
 /*
  * usb_set_configuration - Makes a particular device setting be current
  * @dev: the device whose configuration is being updated
@@ -1531,6 +1560,7 @@ free_interfaces:
                intfc = cp->intf_cache[i];
                intf->altsetting = intfc->altsetting;
                intf->num_altsetting = intfc->num_altsetting;
+               intf->intf_assoc = find_iad(dev, cp, i);
                kref_get(&intfc->ref);
 
                alt = usb_altnum_to_altsetting(intf, 0);
index 739f520908aa939b30a09e54bd3a9627b6ceb0a5..aa21b38a31cee53bca3af2cb0ca9ea8fd89ac64c 100644 (file)
 static const struct usb_device_id usb_quirk_list[] = {
        /* HP 5300/5370C scanner */
        { USB_DEVICE(0x03f0, 0x0701), .driver_info = USB_QUIRK_STRING_FETCH_255 },
+       /* Benq S2W 3300U */
+       { USB_DEVICE(0x04a5, 0x20b0), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
+       /* Seiko Epson Corp. Perfection 1200 */
+       { USB_DEVICE(0x04b8, 0x0104), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
        /* Seiko Epson Corp - Perfection 1670 */
        { USB_DEVICE(0x04b8, 0x011f), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
+       /* Samsung ML-2510 Series printer */
+       { USB_DEVICE(0x04e8, 0x327e), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
        /* Elsa MicroLink 56k (V.250) */
        { USB_DEVICE(0x05cc, 0x2267), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
+       /* Ultima Electronics Corp.*/
+       { USB_DEVICE(0x05d8, 0x4005), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
+       /* Umax [hex] Astra 3400U */
+       { USB_DEVICE(0x1606, 0x0060), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
+
+       /* Philips PSC805 audio device */
+       { USB_DEVICE(0x0471, 0x0155), .driver_info = USB_QUIRK_RESET_RESUME },
+
+       /* RIM Blackberry */
+       { USB_DEVICE(0x0fca, 0x0001), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
+       { USB_DEVICE(0x0fca, 0x0004), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
+       { USB_DEVICE(0x0fca, 0x0006), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
 
        { }  /* terminating entry must be last */
 };
index be37c863fdfb18e872e553af1b8c5778a67e67a6..d47ae89154a7e7b4a2d9ab40e4e733eaebe124be 100644 (file)
@@ -169,6 +169,73 @@ show_quirks(struct device *dev, struct device_attribute *attr, char *buf)
 }
 static DEVICE_ATTR(quirks, S_IRUGO, show_quirks, NULL);
 
+
+#if defined(CONFIG_USB_PERSIST) || defined(CONFIG_USB_SUSPEND)
+static const char power_group[] = "power";
+#endif
+
+#ifdef CONFIG_USB_PERSIST
+
+static ssize_t
+show_persist(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct usb_device *udev = to_usb_device(dev);
+
+       return sprintf(buf, "%d\n", udev->persist_enabled);
+}
+
+static ssize_t
+set_persist(struct device *dev, struct device_attribute *attr,
+               const char *buf, size_t count)
+{
+       struct usb_device *udev = to_usb_device(dev);
+       int value;
+
+       /* Hubs are always enabled for USB_PERSIST */
+       if (udev->descriptor.bDeviceClass == USB_CLASS_HUB)
+               return -EPERM;
+
+       if (sscanf(buf, "%d", &value) != 1)
+               return -EINVAL;
+       usb_pm_lock(udev);
+       udev->persist_enabled = !!value;
+       usb_pm_unlock(udev);
+       return count;
+}
+
+static DEVICE_ATTR(persist, S_IRUGO | S_IWUSR, show_persist, set_persist);
+
+static int add_persist_attributes(struct device *dev)
+{
+       int rc = 0;
+
+       if (is_usb_device(dev)) {
+               struct usb_device *udev = to_usb_device(dev);
+
+               /* Hubs are automatically enabled for USB_PERSIST */
+               if (udev->descriptor.bDeviceClass == USB_CLASS_HUB)
+                       udev->persist_enabled = 1;
+               rc = sysfs_add_file_to_group(&dev->kobj,
+                               &dev_attr_persist.attr,
+                               power_group);
+       }
+       return rc;
+}
+
+static void remove_persist_attributes(struct device *dev)
+{
+       sysfs_remove_file_from_group(&dev->kobj,
+                       &dev_attr_persist.attr,
+                       power_group);
+}
+
+#else
+
+#define add_persist_attributes(dev)    0
+#define remove_persist_attributes(dev) do {} while (0)
+
+#endif /* CONFIG_USB_PERSIST */
+
 #ifdef CONFIG_USB_SUSPEND
 
 static ssize_t
@@ -276,8 +343,6 @@ set_level(struct device *dev, struct device_attribute *attr,
 
 static DEVICE_ATTR(level, S_IRUGO | S_IWUSR, show_level, set_level);
 
-static char power_group[] = "power";
-
 static int add_power_attributes(struct device *dev)
 {
        int rc = 0;
@@ -311,6 +376,7 @@ static void remove_power_attributes(struct device *dev)
 
 #endif /* CONFIG_USB_SUSPEND */
 
+
 /* Descriptor fields */
 #define usb_descriptor_attr_le16(field, format_string)                 \
 static ssize_t                                                         \
@@ -384,6 +450,10 @@ int usb_create_sysfs_dev_files(struct usb_device *udev)
        if (retval)
                return retval;
 
+       retval = add_persist_attributes(dev);
+       if (retval)
+               goto error;
+
        retval = add_power_attributes(dev);
        if (retval)
                goto error;
@@ -421,9 +491,29 @@ void usb_remove_sysfs_dev_files(struct usb_device *udev)
        device_remove_file(dev, &dev_attr_product);
        device_remove_file(dev, &dev_attr_serial);
        remove_power_attributes(dev);
+       remove_persist_attributes(dev);
        sysfs_remove_group(&dev->kobj, &dev_attr_grp);
 }
 
+/* Interface Accociation Descriptor fields */
+#define usb_intf_assoc_attr(field, format_string)                      \
+static ssize_t                                                         \
+show_iad_##field (struct device *dev, struct device_attribute *attr,   \
+               char *buf)                                              \
+{                                                                      \
+       struct usb_interface *intf = to_usb_interface (dev);            \
+                                                                       \
+       return sprintf (buf, format_string,                             \
+                       intf->intf_assoc->field);               \
+}                                                                      \
+static DEVICE_ATTR(iad_##field, S_IRUGO, show_iad_##field, NULL);
+
+usb_intf_assoc_attr (bFirstInterface, "%02x\n")
+usb_intf_assoc_attr (bInterfaceCount, "%02d\n")
+usb_intf_assoc_attr (bFunctionClass, "%02x\n")
+usb_intf_assoc_attr (bFunctionSubClass, "%02x\n")
+usb_intf_assoc_attr (bFunctionProtocol, "%02x\n")
+
 /* Interface fields */
 #define usb_intf_attr(field, format_string)                            \
 static ssize_t                                                         \
@@ -487,6 +577,18 @@ static ssize_t show_modalias(struct device *dev,
 }
 static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL);
 
+static struct attribute *intf_assoc_attrs[] = {
+       &dev_attr_iad_bFirstInterface.attr,
+       &dev_attr_iad_bInterfaceCount.attr,
+       &dev_attr_iad_bFunctionClass.attr,
+       &dev_attr_iad_bFunctionSubClass.attr,
+       &dev_attr_iad_bFunctionProtocol.attr,
+       NULL,
+};
+static struct attribute_group intf_assoc_attr_grp = {
+       .attrs = intf_assoc_attrs,
+};
+
 static struct attribute *intf_attrs[] = {
        &dev_attr_bInterfaceNumber.attr,
        &dev_attr_bAlternateSetting.attr,
@@ -538,6 +640,8 @@ int usb_create_sysfs_intf_files(struct usb_interface *intf)
                alt->string = usb_cache_string(udev, alt->desc.iInterface);
        if (alt->string)
                retval = device_create_file(dev, &dev_attr_interface);
+       if (intf->intf_assoc)
+               retval = sysfs_create_group(&dev->kobj, &intf_assoc_attr_grp);
        usb_create_intf_ep_files(intf, udev);
        return 0;
 }
@@ -549,4 +653,5 @@ void usb_remove_sysfs_intf_files(struct usb_interface *intf)
        usb_remove_intf_ep_files(intf);
        device_remove_file(dev, &dev_attr_interface);
        sysfs_remove_group(&dev->kobj, &intf_attr_grp);
+       sysfs_remove_group(&intf->dev.kobj, &intf_assoc_attr_grp);
 }
index 94ea9727ff55d4c4018acdc18f4eb7f8bca775a6..52ec44b828f3530dd8dfdb33e8452be6aa2a819f 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/usb.h>
+#include <linux/wait.h>
 #include "hcd.h"
 
 #define to_urb(d) container_of(d, struct urb, kref)
 static void urb_destroy(struct kref *kref)
 {
        struct urb *urb = to_urb(kref);
+
+       if (urb->transfer_flags & URB_FREE_BUFFER)
+               kfree(urb->transfer_buffer);
+
        kfree(urb);
 }
 
@@ -34,6 +39,7 @@ void usb_init_urb(struct urb *urb)
                memset(urb, 0, sizeof(*urb));
                kref_init(&urb->kref);
                spin_lock_init(&urb->lock);
+               INIT_LIST_HEAD(&urb->anchor_list);
        }
 }
 
@@ -100,8 +106,60 @@ struct urb * usb_get_urb(struct urb *urb)
                kref_get(&urb->kref);
        return urb;
 }
-               
-               
+
+/**
+ * usb_anchor_urb - anchors an URB while it is processed
+ * @urb: pointer to the urb to anchor
+ * @anchor: pointer to the anchor
+ *
+ * This can be called to have access to URBs which are to be executed
+ * without bothering to track them
+ */
+void usb_anchor_urb(struct urb *urb, struct usb_anchor *anchor)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&anchor->lock, flags);
+       usb_get_urb(urb);
+       list_add_tail(&urb->anchor_list, &anchor->urb_list);
+       urb->anchor = anchor;
+       spin_unlock_irqrestore(&anchor->lock, flags);
+}
+EXPORT_SYMBOL_GPL(usb_anchor_urb);
+
+/**
+ * usb_unanchor_urb - unanchors an URB
+ * @urb: pointer to the urb to anchor
+ *
+ * Call this to stop the system keeping track of this URB
+ */
+void usb_unanchor_urb(struct urb *urb)
+{
+       unsigned long flags;
+       struct usb_anchor *anchor;
+
+       if (!urb)
+               return;
+
+       anchor = urb->anchor;
+       if (!anchor)
+               return;
+
+       spin_lock_irqsave(&anchor->lock, flags);
+       if (unlikely(anchor != urb->anchor)) {
+               /* we've lost the race to another thread */
+               spin_unlock_irqrestore(&anchor->lock, flags);
+               return;
+       }
+       urb->anchor = NULL;
+       list_del(&urb->anchor_list);
+       spin_unlock_irqrestore(&anchor->lock, flags);
+       usb_put_urb(urb);
+       if (list_empty(&anchor->urb_list))
+               wake_up(&anchor->wait);
+}
+EXPORT_SYMBOL_GPL(usb_unanchor_urb);
+
 /*-------------------------------------------------------------------*/
 
 /**
@@ -478,6 +536,48 @@ void usb_kill_urb(struct urb *urb)
        spin_unlock_irq(&urb->lock);
 }
 
+/**
+ * usb_kill_anchored_urbs - cancel transfer requests en masse
+ * @anchor: anchor the requests are bound to
+ *
+ * this allows all outstanding URBs to be killed starting
+ * from the back of the queue
+ */
+void usb_kill_anchored_urbs(struct usb_anchor *anchor)
+{
+       struct urb *victim;
+
+       spin_lock_irq(&anchor->lock);
+       while (!list_empty(&anchor->urb_list)) {
+               victim = list_entry(anchor->urb_list.prev, struct urb, anchor_list);
+               /* we must make sure the URB isn't freed before we kill it*/
+               usb_get_urb(victim);
+               spin_unlock_irq(&anchor->lock);
+               /* this will unanchor the URB */
+               usb_kill_urb(victim);
+               usb_put_urb(victim);
+               spin_lock_irq(&anchor->lock);
+       }
+       spin_unlock_irq(&anchor->lock);
+}
+EXPORT_SYMBOL_GPL(usb_kill_anchored_urbs);
+
+/**
+ * usb_wait_anchor_empty_timeout - wait for an anchor to be unused
+ * @anchor: the anchor you want to become unused
+ * @timeout: how long you are willing to wait in milliseconds
+ *
+ * Call this is you want to be sure all an anchor's
+ * URBs have finished
+ */
+int usb_wait_anchor_empty_timeout(struct usb_anchor *anchor,
+                                 unsigned int timeout)
+{
+       return wait_event_timeout(anchor->wait, list_empty(&anchor->urb_list),
+                                 msecs_to_jiffies(timeout));
+}
+EXPORT_SYMBOL_GPL(usb_wait_anchor_empty_timeout);
+
 EXPORT_SYMBOL(usb_init_urb);
 EXPORT_SYMBOL(usb_alloc_urb);
 EXPORT_SYMBOL(usb_free_urb);
@@ -485,4 +585,3 @@ EXPORT_SYMBOL(usb_get_urb);
 EXPORT_SYMBOL(usb_submit_urb);
 EXPORT_SYMBOL(usb_unlink_urb);
 EXPORT_SYMBOL(usb_kill_urb);
-
index 4a6299bd00478156417a7ed757ffc0d261bdc736..0fee5c66fd64ea44ef0531453b1b0bfb60cc7614 100644 (file)
@@ -253,6 +253,7 @@ usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1)
        dev->dev.bus = &usb_bus_type;
        dev->dev.type = &usb_device_type;
        dev->dev.dma_mask = bus->controller->dma_mask;
+       set_dev_node(&dev->dev, dev_to_node(bus->controller));
        dev->state = USB_STATE_ATTACHED;
 
        INIT_LIST_HEAD(&dev->ep0.urb_list);
@@ -578,11 +579,12 @@ int __usb_get_extra_descriptor(char *buffer, unsigned size,
  * address (through the pointer provided).
  *
  * These buffers are used with URB_NO_xxx_DMA_MAP set in urb->transfer_flags
- * to avoid behaviors like using "DMA bounce buffers", or tying down I/O
- * mapping hardware for long idle periods.  The implementation varies between
+ * to avoid behaviors like using "DMA bounce buffers", or thrashing IOMMU
+ * hardware during URB completion/resubmit.  The implementation varies between
  * platforms, depending on details of how DMA will work to this device.
- * Using these buffers also helps prevent cacheline sharing problems on
- * architectures where CPU caches are not DMA-coherent.
+ * Using these buffers also eliminates cacheline sharing problems on
+ * architectures where CPU caches are not DMA-coherent.  On systems without
+ * bus-snooping caches, these buffers are uncached.
  *
  * When the buffer is no longer used, free it with usb_buffer_free().
  */
@@ -607,7 +609,7 @@ void *usb_buffer_alloc(
  *
  * This reclaims an I/O buffer, letting it be reused.  The memory must have
  * been allocated using usb_buffer_alloc(), and the parameters must match
- * those provided in that allocation request. 
+ * those provided in that allocation request.
  */
 void usb_buffer_free(
        struct usb_device *dev,
index bf2eb0dae2ecc3aeee8e08f2c941d59513c733fe..ad5fa0338f498631ca71350b198830b3f80ac3fb 100644 (file)
@@ -52,8 +52,16 @@ static inline void usb_pm_unlock(struct usb_device *udev)
 
 #else
 
-#define usb_port_suspend(dev)          0
-#define usb_port_resume(dev)           0
+static inline int usb_port_suspend(struct usb_device *udev)
+{
+       return 0;
+}
+
+static inline int usb_port_resume(struct usb_device *udev)
+{
+       return 0;
+}
+
 static inline void usb_pm_lock(struct usb_device *udev) {}
 static inline void usb_pm_unlock(struct usb_device *udev) {}
 
@@ -100,11 +108,13 @@ static inline int is_usb_device_driver(struct device_driver *drv)
 static inline void mark_active(struct usb_interface *f)
 {
        f->is_active = 1;
+       f->dev.power.power_state.event = PM_EVENT_ON;
 }
 
 static inline void mark_quiesced(struct usb_interface *f)
 {
        f->is_active = 0;
+       f->dev.power.power_state.event = PM_EVENT_SUSPEND;
 }
 
 static inline int is_active(const struct usb_interface *f)
index f771a7cae9ece36ce0085f871beac7c38199ce13..45e01e289455376b68e5f5ceca8ca3a3a2937ec3 100644 (file)
@@ -42,6 +42,20 @@ config USB_GADGET
           For more information, see <http://www.linux-usb.org/gadget> and
           the kernel DocBook documentation for this API.
 
+config USB_GADGET_DEBUG
+       boolean "Debugging messages"
+       depends on USB_GADGET && DEBUG_KERNEL && EXPERIMENTAL
+       help
+          Many controller and gadget drivers will print some debugging
+          messages if you use this option to ask for those messages.
+
+          Avoid enabling these messages, even if you're actively
+          debugging such a driver.  Many drivers will emit so many
+          messages that the driver timings are affected, which will
+          either create new failure modes or remove the one you're
+          trying to track down.  Never enable these messages for a
+          production build.
+
 config USB_GADGET_DEBUG_FILES
        boolean "Debugging information files"
        depends on USB_GADGET && PROC_FS
@@ -208,6 +222,27 @@ config USB_OTG
 
           Select this only if your OMAP board has a Mini-AB connector.
 
+config USB_GADGET_S3C2410
+       boolean "S3C2410 USB Device Controller"
+       depends on ARCH_S3C2410
+       help
+         Samsung's S3C2410 is an ARM-4 processor with an integrated
+         full speed USB 1.1 device controller.  It has 4 configurable
+         endpoints, as well as endpoint zero (for control transfers).
+
+         This driver has been tested on the S3C2410, S3C2412, and
+         S3C2440 processors.
+
+config USB_S3C2410
+       tristate
+       depends on USB_GADGET_S3C2410
+       default USB_GADGET
+       select USB_GADGET_SELECTED
+
+config USB_S3C2410_DEBUG
+       boolean "S3C2410 udc debug messages"
+       depends on USB_GADGET_S3C2410
+
 config USB_GADGET_AT91
        boolean "AT91 USB Device Port"
        depends on ARCH_AT91 && !ARCH_AT91SAM9RL
@@ -226,6 +261,24 @@ config USB_AT91
        depends on USB_GADGET_AT91
        default USB_GADGET
 
+config USB_GADGET_M66592
+       boolean "M66592 driver"
+       select USB_GADGET_DUALSPEED
+       help
+          M66592 is a USB 2.0 peripheral controller.
+
+          It has seven configurable endpoints, and endpoint zero.
+
+          Say "y" to link the driver statically, or "m" to build a
+          dynamically linked module called "m66592_udc" and force all
+          gadget drivers to also be dynamically linked.
+
+config USB_M66592
+       tristate
+       depends on USB_GADGET_M66592
+       default USB_GADGET
+       select USB_GADGET_SELECTED
+
 config USB_GADGET_DUMMY_HCD
        boolean "Dummy HCD (DEVELOPMENT)"
        depends on (USB=y || (USB=m && USB_GADGET=m)) && EXPERIMENTAL
index 5db19396631c49732ea4c0f0de94683020d78bdc..8ae76f7386355074ffba6b3d1fb1a326e323becd 100644 (file)
@@ -1,14 +1,20 @@
 #
 # USB peripheral controller drivers
 #
+ifeq ($(CONFIG_USB_GADGET_DEBUG),y)
+       EXTRA_CFLAGS            += -DDEBUG
+endif
+
 obj-$(CONFIG_USB_DUMMY_HCD)    += dummy_hcd.o
 obj-$(CONFIG_USB_NET2280)      += net2280.o
 obj-$(CONFIG_USB_PXA2XX)       += pxa2xx_udc.o
 obj-$(CONFIG_USB_GOKU)         += goku_udc.o
 obj-$(CONFIG_USB_OMAP)         += omap_udc.o
 obj-$(CONFIG_USB_LH7A40X)      += lh7a40x_udc.o
+obj-$(CONFIG_USB_S3C2410)      += s3c2410_udc.o
 obj-$(CONFIG_USB_AT91)         += at91_udc.o
 obj-$(CONFIG_USB_FSL_USB2)     += fsl_usb2_udc.o
+obj-$(CONFIG_USB_M66592)       += m66592-udc.o
 
 #
 # USB gadget drivers
index ba163f35bf21efd984431d3c3626ed85bab61989..63d7d6568699e28fad912c05c3fc4f7c601bf39d 100644 (file)
@@ -601,25 +601,6 @@ static void at91_ep_free_request(struct usb_ep *_ep, struct usb_request *_req)
        kfree(req);
 }
 
-static void *at91_ep_alloc_buffer(
-       struct usb_ep *_ep,
-       unsigned bytes,
-       dma_addr_t *dma,
-       gfp_t gfp_flags)
-{
-       *dma = ~0;
-       return kmalloc(bytes, gfp_flags);
-}
-
-static void at91_ep_free_buffer(
-       struct usb_ep *ep,
-       void *buf,
-       dma_addr_t dma,
-       unsigned bytes)
-{
-       kfree(buf);
-}
-
 static int at91_ep_queue(struct usb_ep *_ep,
                        struct usb_request *_req, gfp_t gfp_flags)
 {
@@ -788,8 +769,6 @@ static const struct usb_ep_ops at91_ep_ops = {
        .disable        = at91_ep_disable,
        .alloc_request  = at91_ep_alloc_request,
        .free_request   = at91_ep_free_request,
-       .alloc_buffer   = at91_ep_alloc_buffer,
-       .free_buffer    = at91_ep_free_buffer,
        .queue          = at91_ep_queue,
        .dequeue        = at91_ep_dequeue,
        .set_halt       = at91_ep_set_halt,
index fcb5526cb085d68658bc936fd93650af9a3e33c4..f2fbdc7fe376ddf7397f056ab78eee74bc19f427 100644 (file)
@@ -497,38 +497,6 @@ dummy_free_request (struct usb_ep *_ep, struct usb_request *_req)
        kfree (req);
 }
 
-static void *
-dummy_alloc_buffer (
-       struct usb_ep *_ep,
-       unsigned bytes,
-       dma_addr_t *dma,
-       gfp_t mem_flags
-) {
-       char                    *retval;
-       struct dummy_ep         *ep;
-       struct dummy            *dum;
-
-       ep = usb_ep_to_dummy_ep (_ep);
-       dum = ep_to_dummy (ep);
-
-       if (!dum->driver)
-               return NULL;
-       retval = kmalloc (bytes, mem_flags);
-       *dma = (dma_addr_t) retval;
-       return retval;
-}
-
-static void
-dummy_free_buffer (
-       struct usb_ep *_ep,
-       void *buf,
-       dma_addr_t dma,
-       unsigned bytes
-) {
-       if (bytes)
-               kfree (buf);
-}
-
 static void
 fifo_complete (struct usb_ep *ep, struct usb_request *req)
 {
@@ -659,10 +627,6 @@ static const struct usb_ep_ops dummy_ep_ops = {
        .alloc_request  = dummy_alloc_request,
        .free_request   = dummy_free_request,
 
-       .alloc_buffer   = dummy_alloc_buffer,
-       .free_buffer    = dummy_free_buffer,
-       /* map, unmap, ... eventually hook the "generic" dma calls */
-
        .queue          = dummy_queue,
        .dequeue        = dummy_dequeue,
 
@@ -1784,8 +1748,7 @@ static int dummy_bus_resume (struct usb_hcd *hcd)
 
        spin_lock_irq (&dum->lock);
        if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
-               dev_warn (&hcd->self.root_hub->dev, "HC isn't running!\n");
-               rc = -ENODEV;
+               rc = -ESHUTDOWN;
        } else {
                dum->rh_state = DUMMY_RH_RUNNING;
                set_link_state (dum);
index 325bf7cfb83ffd04d76ab3cccf2d984f2618db8c..dbaf867436dffbc69e3172810fd4b24a89d7c10f 100644 (file)
@@ -277,7 +277,7 @@ MODULE_PARM_DESC(host_addr, "Host Ethernet Address");
 #define DEV_CONFIG_CDC
 #endif
 
-#ifdef CONFIG_USB_GADGET_HUSB2DEV
+#ifdef CONFIG_USB_GADGET_ATMEL_USBA
 #define DEV_CONFIG_CDC
 #endif
 
@@ -292,7 +292,7 @@ MODULE_PARM_DESC(host_addr, "Host Ethernet Address");
 #define        DEV_CONFIG_SUBSET
 #endif
 
-#ifdef CONFIG_USB_GADGET_SH
+#ifdef CONFIG_USB_GADGET_SUPERH
 #define        DEV_CONFIG_SUBSET
 #endif
 
@@ -301,6 +301,10 @@ MODULE_PARM_DESC(host_addr, "Host Ethernet Address");
 #define        DEV_CONFIG_SUBSET
 #endif
 
+#ifdef CONFIG_USB_GADGET_M66592
+#define DEV_CONFIG_CDC
+#endif
+
 
 /*-------------------------------------------------------------------------*/
 
index 4639b629e60ca02af90a05756a8359342c86bda9..8712ef987179b2ca2ba4ed3c6d26df9823395ed9 100644 (file)
@@ -3733,19 +3733,12 @@ static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget)
        }
 
        /* Free the data buffers */
-       for (i = 0; i < NUM_BUFFERS; ++i) {
-               struct fsg_buffhd       *bh = &fsg->buffhds[i];
-
-               if (bh->buf)
-                       usb_ep_free_buffer(fsg->bulk_in, bh->buf, bh->dma,
-                                       mod_data.buflen);
-       }
+       for (i = 0; i < NUM_BUFFERS; ++i)
+               kfree(fsg->buffhds[i].buf);
 
        /* Free the request and buffer for endpoint 0 */
        if (req) {
-               if (req->buf)
-                       usb_ep_free_buffer(fsg->ep0, req->buf,
-                                       req->dma, EP0_BUFSIZE);
+               kfree(req->buf);
                usb_ep_free_request(fsg->ep0, req);
        }
 
@@ -3963,8 +3956,7 @@ static int __init fsg_bind(struct usb_gadget *gadget)
 #endif
 
        if (gadget->is_otg) {
-               otg_desc.bmAttributes |= USB_OTG_HNP,
-               config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+               otg_desc.bmAttributes |= USB_OTG_HNP;
        }
 
        rc = -ENOMEM;
@@ -3973,8 +3965,7 @@ static int __init fsg_bind(struct usb_gadget *gadget)
        fsg->ep0req = req = usb_ep_alloc_request(fsg->ep0, GFP_KERNEL);
        if (!req)
                goto out;
-       req->buf = usb_ep_alloc_buffer(fsg->ep0, EP0_BUFSIZE,
-                       &req->dma, GFP_KERNEL);
+       req->buf = kmalloc(EP0_BUFSIZE, GFP_KERNEL);
        if (!req->buf)
                goto out;
        req->complete = ep0_complete;
@@ -3986,8 +3977,7 @@ static int __init fsg_bind(struct usb_gadget *gadget)
                /* Allocate for the bulk-in endpoint.  We assume that
                 * the buffer will also work with the bulk-out (and
                 * interrupt-in) endpoint. */
-               bh->buf = usb_ep_alloc_buffer(fsg->bulk_in, mod_data.buflen,
-                               &bh->dma, GFP_KERNEL);
+               bh->buf = kmalloc(mod_data.buflen, GFP_KERNEL);
                if (!bh->buf)
                        goto out;
                bh->next = bh + 1;
index 3ca2b3159f00d8947a712ea45d96c09a6c72f72c..10b2b33b8698e54c48b3f2ce701cfa3c09c0406a 100644 (file)
@@ -228,7 +228,7 @@ static int dr_controller_setup(struct fsl_udc *udc)
 
        /* Config PHY interface */
        portctrl = fsl_readl(&dr_regs->portsc1);
-       portctrl &= ~(PORTSCX_PHY_TYPE_SEL & PORTSCX_PORT_WIDTH);
+       portctrl &= ~(PORTSCX_PHY_TYPE_SEL | PORTSCX_PORT_WIDTH);
        switch (udc->phy_mode) {
        case FSL_USB2_PHY_ULPI:
                portctrl |= PORTSCX_PTS_ULPI;
@@ -601,39 +601,6 @@ static void fsl_free_request(struct usb_ep *_ep, struct usb_request *_req)
                kfree(req);
 }
 
-/*------------------------------------------------------------------
- * Allocate an I/O buffer
-*---------------------------------------------------------------------*/
-static void *fsl_alloc_buffer(struct usb_ep *_ep, unsigned bytes,
-               dma_addr_t *dma, gfp_t gfp_flags)
-{
-       struct fsl_ep *ep;
-
-       if (!_ep)
-               return NULL;
-
-       ep = container_of(_ep, struct fsl_ep, ep);
-
-       return dma_alloc_coherent(ep->udc->gadget.dev.parent,
-                       bytes, dma, gfp_flags);
-}
-
-/*------------------------------------------------------------------
- * frees an i/o buffer
-*---------------------------------------------------------------------*/
-static void fsl_free_buffer(struct usb_ep *_ep, void *buf,
-               dma_addr_t dma, unsigned bytes)
-{
-       struct fsl_ep *ep;
-
-       if (!_ep)
-               return;
-
-       ep = container_of(_ep, struct fsl_ep, ep);
-
-       dma_free_coherent(ep->udc->gadget.dev.parent, bytes, buf, dma);
-}
-
 /*-------------------------------------------------------------------------*/
 static int fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
 {
@@ -1047,9 +1014,6 @@ static struct usb_ep_ops fsl_ep_ops = {
        .alloc_request = fsl_alloc_request,
        .free_request = fsl_free_request,
 
-       .alloc_buffer = fsl_alloc_buffer,
-       .free_buffer = fsl_free_buffer,
-
        .queue = fsl_ep_queue,
        .dequeue = fsl_ep_dequeue,
 
@@ -2189,27 +2153,19 @@ static void fsl_udc_release(struct device *dev)
  * init resource for globle controller
  * Return the udc handle on success or NULL on failure
  ------------------------------------------------------------------*/
-static struct fsl_udc *__init struct_udc_setup(struct platform_device *pdev)
+static int __init struct_udc_setup(struct fsl_udc *udc,
+               struct platform_device *pdev)
 {
-       struct fsl_udc *udc;
        struct fsl_usb2_platform_data *pdata;
        size_t size;
 
-       udc = kzalloc(sizeof(struct fsl_udc), GFP_KERNEL);
-       if (udc == NULL) {
-               ERR("malloc udc failed\n");
-               return NULL;
-       }
-
        pdata = pdev->dev.platform_data;
        udc->phy_mode = pdata->phy_mode;
-       /* max_ep_nr is bidirectional ep number, max_ep doubles the number */
-       udc->max_ep = pdata->max_ep_nr * 2;
 
        udc->eps = kzalloc(sizeof(struct fsl_ep) * udc->max_ep, GFP_KERNEL);
        if (!udc->eps) {
                ERR("malloc fsl_ep failed\n");
-               goto cleanup;
+               return -1;
        }
 
        /* initialized QHs, take care of alignment */
@@ -2225,7 +2181,7 @@ static struct fsl_udc *__init struct_udc_setup(struct platform_device *pdev)
        if (!udc->ep_qh) {
                ERR("malloc QHs for udc failed\n");
                kfree(udc->eps);
-               goto cleanup;
+               return -1;
        }
 
        udc->ep_qh_size = size;
@@ -2244,11 +2200,7 @@ static struct fsl_udc *__init struct_udc_setup(struct platform_device *pdev)
        udc->remote_wakeup = 0; /* default to 0 on reset */
        spin_lock_init(&udc->lock);
 
-       return udc;
-
-cleanup:
-       kfree(udc);
-       return NULL;
+       return 0;
 }
 
 /*----------------------------------------------------------------
@@ -2287,35 +2239,37 @@ static int __init struct_ep_setup(struct fsl_udc *udc, unsigned char index,
 }
 
 /* Driver probe function
- * all intialize operations implemented here except enabling usb_intr reg
+ * all intialization operations implemented here except enabling usb_intr reg
+ * board setup should have been done in the platform code
  */
 static int __init fsl_udc_probe(struct platform_device *pdev)
 {
        struct resource *res;
        int ret = -ENODEV;
        unsigned int i;
+       u32 dccparams;
 
        if (strcmp(pdev->name, driver_name)) {
                VDBG("Wrong device\n");
                return -ENODEV;
        }
 
-       /* board setup should have been done in the platform code */
-
-       /* Initialize the udc structure including QH member and other member */
-       udc_controller = struct_udc_setup(pdev);
-       if (!udc_controller) {
-               VDBG("udc_controller is NULL \n");
+       udc_controller = kzalloc(sizeof(struct fsl_udc), GFP_KERNEL);
+       if (udc_controller == NULL) {
+               ERR("malloc udc failed\n");
                return -ENOMEM;
        }
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res)
+       if (!res) {
+               kfree(udc_controller);
                return -ENXIO;
+       }
 
        if (!request_mem_region(res->start, res->end - res->start + 1,
                                driver_name)) {
                ERR("request mem region for %s failed \n", pdev->name);
+               kfree(udc_controller);
                return -EBUSY;
        }
 
@@ -2328,13 +2282,24 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
        usb_sys_regs = (struct usb_sys_interface *)
                        ((u32)dr_regs + USB_DR_SYS_OFFSET);
 
+       /* Read Device Controller Capability Parameters register */
+       dccparams = fsl_readl(&dr_regs->dccparams);
+       if (!(dccparams & DCCPARAMS_DC)) {
+               ERR("This SOC doesn't support device role\n");
+               ret = -ENODEV;
+               goto err2;
+       }
+       /* Get max device endpoints */
+       /* DEN is bidirectional ep number, max_ep doubles the number */
+       udc_controller->max_ep = (dccparams & DCCPARAMS_DEN_MASK) * 2;
+
        udc_controller->irq = platform_get_irq(pdev, 0);
        if (!udc_controller->irq) {
                ret = -ENODEV;
                goto err2;
        }
 
-       ret = request_irq(udc_controller->irq, fsl_udc_irq, SA_SHIRQ,
+       ret = request_irq(udc_controller->irq, fsl_udc_irq, IRQF_SHARED,
                        driver_name, udc_controller);
        if (ret != 0) {
                ERR("cannot request irq %d err %d \n",
@@ -2342,6 +2307,13 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
                goto err2;
        }
 
+       /* Initialize the udc structure including QH member and other member */
+       if (struct_udc_setup(udc_controller, pdev)) {
+               ERR("Can't initialize udc data structure\n");
+               ret = -ENOMEM;
+               goto err3;
+       }
+
        /* initialize usb hw reg except for regs for EP,
         * leave usbintr reg untouched */
        dr_controller_setup(udc_controller);
@@ -2403,6 +2375,7 @@ err2:
        iounmap(dr_regs);
 err1:
        release_mem_region(res->start, res->end - res->start + 1);
+       kfree(udc_controller);
        return ret;
 }
 
index c6291e046507776594fc4beecfa88b2acfdcfa23..832ab82b4882c9ad1d4ae7b5eb0e2aaff921c233 100644 (file)
@@ -101,6 +101,10 @@ struct usb_sys_interface {
 #define WAIT_FOR_OUT_STATUS     3
 #define DATA_STATE_RECV         4
 
+/* Device Controller Capability Parameter register */
+#define DCCPARAMS_DC                           0x00000080
+#define DCCPARAMS_DEN_MASK                     0x0000001f
+
 /* Frame Index Register Bit Masks */
 #define        USB_FRINDEX_MASKS                       0x3fff
 /* USB CMD  Register Bit Masks */
index d041b919e7b88ffd7f75f58e8ce7ee6040e2dd5f..53e9139ba3886137ac2f642eb72587183251a777 100644 (file)
@@ -8,6 +8,8 @@
  * (And avoiding all runtime comparisons in typical one-choice configs!)
  *
  * NOTE:  some of these controller drivers may not be available yet.
+ * Some are available on 2.4 kernels; several are available, but not
+ * yet pushed in the 2.6 mainline tree.
  */
 #ifdef CONFIG_USB_GADGET_NET2280
 #define        gadget_is_net2280(g)    !strcmp("net2280", (g)->name)
 #define        gadget_is_goku(g)       0
 #endif
 
+/* SH3 UDC -- not yet ported 2.4 --> 2.6 */
 #ifdef CONFIG_USB_GADGET_SUPERH
 #define        gadget_is_sh(g)         !strcmp("sh_udc", (g)->name)
 #else
 #define        gadget_is_sh(g)         0
 #endif
 
+/* not yet stable on 2.6 (would help "original Zaurus") */
 #ifdef CONFIG_USB_GADGET_SA1100
 #define        gadget_is_sa1100(g)     !strcmp("sa1100_udc", (g)->name)
 #else
@@ -51,6 +55,7 @@
 #define        gadget_is_lh7a40x(g)    0
 #endif
 
+/* handhelds.org tree (?) */
 #ifdef CONFIG_USB_GADGET_MQ11XX
 #define        gadget_is_mq11xx(g)     !strcmp("mq11xx_udc", (g)->name)
 #else
 #define        gadget_is_omap(g)       0
 #endif
 
+/* not yet ported 2.4 --> 2.6 */
 #ifdef CONFIG_USB_GADGET_N9604
 #define        gadget_is_n9604(g)      !strcmp("n9604_udc", (g)->name)
 #else
 #define        gadget_is_n9604(g)      0
 #endif
 
+/* various unstable versions available */
 #ifdef CONFIG_USB_GADGET_PXA27X
 #define        gadget_is_pxa27x(g)     !strcmp("pxa27x_udc", (g)->name)
 #else
 #define        gadget_is_pxa27x(g)     0
 #endif
 
-#ifdef CONFIG_USB_GADGET_HUSB2DEV
-#define gadget_is_husb2dev(g)  !strcmp("husb2_udc", (g)->name)
+#ifdef CONFIG_USB_GADGET_ATMEL_USBA
+#define gadget_is_atmel_usba(g)        !strcmp("atmel_usba_udc", (g)->name)
 #else
-#define gadget_is_husb2dev(g)  0
+#define gadget_is_atmel_usba(g)        0
 #endif
 
 #ifdef CONFIG_USB_GADGET_S3C2410
 #define gadget_is_at91(g)      0
 #endif
 
+/* status unclear */
 #ifdef CONFIG_USB_GADGET_IMX
 #define gadget_is_imx(g)       !strcmp("imx_udc", (g)->name)
 #else
 #endif
 
 /* Mentor high speed function controller */
+/* from Montavista kernel (?) */
 #ifdef CONFIG_USB_GADGET_MUSBHSFC
 #define gadget_is_musbhsfc(g)  !strcmp("musbhsfc_udc", (g)->name)
 #else
 #define gadget_is_musbhdrc(g)  0
 #endif
 
+/* from Montavista kernel (?) */
 #ifdef CONFIG_USB_GADGET_MPC8272
 #define gadget_is_mpc8272(g)   !strcmp("mpc8272_udc", (g)->name)
 #else
 #define gadget_is_mpc8272(g)   0
 #endif
 
+#ifdef CONFIG_USB_GADGET_M66592
+#define        gadget_is_m66592(g)     !strcmp("m66592_udc", (g)->name)
+#else
+#define        gadget_is_m66592(g)     0
+#endif
+
+
 // CONFIG_USB_GADGET_SX2
 // CONFIG_USB_GADGET_AU1X00
 // ...
@@ -181,9 +198,11 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget)
                return 0x16;
        else if (gadget_is_mpc8272(gadget))
                return 0x17;
-       else if (gadget_is_husb2dev(gadget))
+       else if (gadget_is_atmel_usba(gadget))
                return 0x18;
        else if (gadget_is_fsl_usb2(gadget))
                return 0x19;
+       else if (gadget_is_m66592(gadget))
+               return 0x20;
        return -ENOENT;
 }
index d08a8d0e6427dc2d3276f622a037977b590957db..1c5aa49d74327ddff868671d50466d7931c83b30 100644 (file)
@@ -1248,17 +1248,11 @@ autoconf_fail:
        tasklet_init(&dev->tasklet, gmidi_in_tasklet, (unsigned long)dev);
 
        /* preallocate control response and buffer */
-       dev->req = usb_ep_alloc_request(gadget->ep0, GFP_KERNEL);
+       dev->req = alloc_ep_req(gadget->ep0, USB_BUFSIZ);
        if (!dev->req) {
                err = -ENOMEM;
                goto fail;
        }
-       dev->req->buf = usb_ep_alloc_buffer(gadget->ep0, USB_BUFSIZ,
-                               &dev->req->dma, GFP_KERNEL);
-       if (!dev->req->buf) {
-               err = -ENOMEM;
-               goto fail;
-       }
 
        dev->req->complete = gmidi_setup_complete;
 
index ae931af05cef303521fbad67bfa858829c1fc359..d6c5f1150ae795c91cf9f7f928e81c4f8fed5040 100644 (file)
@@ -20,7 +20,6 @@
  *  - DMA works with ep1 (OUT transfers) and ep2 (IN transfers).
  */
 
-#undef DEBUG
 // #define     VERBOSE         /* extra debug messages (success too) */
 // #define     USB_TRACE       /* packet-level success messages */
 
@@ -296,51 +295,6 @@ goku_free_request(struct usb_ep *_ep, struct usb_request *_req)
 
 /*-------------------------------------------------------------------------*/
 
-/* allocating buffers this way eliminates dma mapping overhead, which
- * on some platforms will mean eliminating a per-io buffer copy.  with
- * some kinds of system caches, further tweaks may still be needed.
- */
-static void *
-goku_alloc_buffer(struct usb_ep *_ep, unsigned bytes,
-                       dma_addr_t *dma, gfp_t gfp_flags)
-{
-       void            *retval;
-       struct goku_ep  *ep;
-
-       ep = container_of(_ep, struct goku_ep, ep);
-       if (!_ep)
-               return NULL;
-       *dma = DMA_ADDR_INVALID;
-
-       if (ep->dma) {
-               /* the main problem with this call is that it wastes memory
-                * on typical 1/N page allocations: it allocates 1-N pages.
-                */
-#warning Using dma_alloc_coherent even with buffers smaller than a page.
-               retval = dma_alloc_coherent(&ep->dev->pdev->dev,
-                               bytes, dma, gfp_flags);
-       } else
-               retval = kmalloc(bytes, gfp_flags);
-       return retval;
-}
-
-static void
-goku_free_buffer(struct usb_ep *_ep, void *buf, dma_addr_t dma, unsigned bytes)
-{
-       /* free memory into the right allocator */
-       if (dma != DMA_ADDR_INVALID) {
-               struct goku_ep  *ep;
-
-               ep = container_of(_ep, struct goku_ep, ep);
-               if (!_ep)
-                       return;
-               dma_free_coherent(&ep->dev->pdev->dev, bytes, buf, dma);
-       } else
-               kfree (buf);
-}
-
-/*-------------------------------------------------------------------------*/
-
 static void
 done(struct goku_ep *ep, struct goku_request *req, int status)
 {
@@ -485,7 +439,7 @@ top:
                        /* use ep1/ep2 double-buffering for OUT */
                        if (!(size & PACKET_ACTIVE))
                                size = readl(&regs->EPxSizeLB[ep->num]);
-                       if (!(size & PACKET_ACTIVE))    // "can't happen"
+                       if (!(size & PACKET_ACTIVE))    /* "can't happen" */
                                break;
                        size &= DATASIZE;       /* EPxSizeH == 0 */
 
@@ -1026,9 +980,6 @@ static struct usb_ep_ops goku_ep_ops = {
        .alloc_request  = goku_alloc_request,
        .free_request   = goku_free_request,
 
-       .alloc_buffer   = goku_alloc_buffer,
-       .free_buffer    = goku_free_buffer,
-
        .queue          = goku_queue,
        .dequeue        = goku_dequeue,
 
@@ -1140,17 +1091,17 @@ udc_proc_read(char *buffer, char **start, off_t off, int count,
                is_usb_connected
                        ? ((tmp & PW_PULLUP) ? "full speed" : "powered")
                        : "disconnected",
-               ({char *tmp;
+               ({char *state;
                switch(dev->ep0state){
-               case EP0_DISCONNECT:    tmp = "ep0_disconnect"; break;
-               case EP0_IDLE:          tmp = "ep0_idle"; break;
-               case EP0_IN:            tmp = "ep0_in"; break;
-               case EP0_OUT:           tmp = "ep0_out"; break;
-               case EP0_STATUS:        tmp = "ep0_status"; break;
-               case EP0_STALL:         tmp = "ep0_stall"; break;
-               case EP0_SUSPEND:       tmp = "ep0_suspend"; break;
-               default:                tmp = "ep0_?"; break;
-               } tmp; })
+               case EP0_DISCONNECT:    state = "ep0_disconnect"; break;
+               case EP0_IDLE:          state = "ep0_idle"; break;
+               case EP0_IN:            state = "ep0_in"; break;
+               case EP0_OUT:           state = "ep0_out"; break;
+               case EP0_STATUS:        state = "ep0_status"; break;
+               case EP0_STALL:         state = "ep0_stall"; break;
+               case EP0_SUSPEND:       state = "ep0_suspend"; break;
+               default:                state = "ep0_?"; break;
+               } state; })
                );
        size -= t;
        next += t;
@@ -1195,7 +1146,6 @@ udc_proc_read(char *buffer, char **start, off_t off, int count,
        for (i = 0; i < 4; i++) {
                struct goku_ep          *ep = &dev->ep [i];
                struct goku_request     *req;
-               int                     t;
 
                if (i && !ep->desc)
                        continue;
@@ -1283,7 +1233,7 @@ done:
 static void udc_reinit (struct goku_udc *dev)
 {
        static char *names [] = { "ep0", "ep1-bulk", "ep2-bulk", "ep3-bulk" };
-       
+
        unsigned i;
 
        INIT_LIST_HEAD (&dev->gadget.ep_list);
@@ -1896,9 +1846,9 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 
        /* done */
        the_controller = dev;
-       device_register(&dev->gadget.dev);
-
-       return 0;
+       retval = device_register(&dev->gadget.dev);
+       if (retval == 0)
+               return 0;
 
 done:
        if (dev)
@@ -1910,8 +1860,8 @@ done:
 /*-------------------------------------------------------------------------*/
 
 static struct pci_device_id pci_ids [] = { {
-       .class =        ((PCI_CLASS_SERIAL_USB << 8) | 0xfe),
-       .class_mask =   ~0,
+       .class =        ((PCI_CLASS_SERIAL_USB << 8) | 0xfe),
+       .class_mask =   ~0,
        .vendor =       0x102f,         /* Toshiba */
        .device =       0x0107,         /* this UDC */
        .subvendor =    PCI_ANY_ID,
index ea8c8e58cabf1411382894853d2e507d2c3931d3..bc4eb1e0b507213c4da4ae1abbefdc7701340863 100644 (file)
@@ -41,8 +41,10 @@ struct goku_udc_regs {
 #define INT_SYSERROR           0x40000
 #define INT_PWRDETECT          0x80000
 
-#define        INT_DEVWIDE             (INT_PWRDETECT|INT_SYSERROR/*|INT_ERR*/|INT_USBRESET|INT_SUSPEND)
-#define        INT_EP0                 (INT_SETUP|INT_ENDPOINT0/*|INT_STATUS*/|INT_STATUSNAK)
+#define        INT_DEVWIDE \
+       (INT_PWRDETECT|INT_SYSERROR/*|INT_ERR*/|INT_USBRESET|INT_SUSPEND)
+#define        INT_EP0 \
+       (INT_SETUP|INT_ENDPOINT0/*|INT_STATUS*/|INT_STATUSNAK)
 
        u32     dma_master;
 #define MST_EOPB_DIS           0x0800
@@ -231,7 +233,7 @@ struct goku_request {
 enum ep0state {
        EP0_DISCONNECT,         /* no host */
        EP0_IDLE,               /* between STATUS ack and SETUP report */
-       EP0_IN, EP0_OUT,        /* data stage */
+       EP0_IN, EP0_OUT,        /* data stage */
        EP0_STATUS,             /* status stage */
        EP0_STALL,              /* data or status stages */
        EP0_SUSPEND,            /* usb suspend */
@@ -242,7 +244,7 @@ struct goku_udc {
        struct usb_gadget               gadget;
        spinlock_t                      lock;
        struct goku_ep                  ep[4];
-       struct usb_gadget_driver        *driver;
+       struct usb_gadget_driver        *driver;
 
        enum ep0state                   ep0state;
        unsigned                        got_irq:1,
index 46d0e52527447aea5d9f63073d964317dd0bd0a9..e60745ffaf8e382b71cab4203db168025475077b 100644 (file)
@@ -37,7 +37,7 @@
 #include <linux/device.h>
 #include <linux/moduleparam.h>
 
-#include <linux/usb_gadgetfs.h>
+#include <linux/usb/gadgetfs.h>
 #include <linux/usb_gadget.h>
 
 
@@ -923,7 +923,7 @@ static void clean_req (struct usb_ep *ep, struct usb_request *req)
        struct dev_data         *dev = ep->driver_data;
 
        if (req->buf != dev->rbuf) {
-               usb_ep_free_buffer (ep, req->buf, req->dma, req->length);
+               kfree(req->buf);
                req->buf = dev->rbuf;
                req->dma = DMA_ADDR_INVALID;
        }
@@ -963,7 +963,7 @@ static int setup_req (struct usb_ep *ep, struct usb_request *req, u16 len)
                return -EBUSY;
        }
        if (len > sizeof (dev->rbuf))
-               req->buf = usb_ep_alloc_buffer (ep, len, &req->dma, GFP_ATOMIC);
+               req->buf = kmalloc(len, GFP_ATOMIC);
        if (req->buf == 0) {
                req->buf = dev->rbuf;
                return -ENOMEM;
@@ -1505,7 +1505,7 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
                }
                break;
 
-#ifndef        CONFIG_USB_GADGETFS_PXA2XX
+#ifndef        CONFIG_USB_GADGET_PXA2XX
        /* PXA automagically handles this request too */
        case USB_REQ_GET_CONFIGURATION:
                if (ctrl->bRequestType != 0x80)
index a0a73c08a34467730f007ed6bcf27bf4d8e7ae78..e78c2ddc1f88a47e6cbd52007d088f43269e8fee 100644 (file)
@@ -75,10 +75,6 @@ static int lh7a40x_ep_enable(struct usb_ep *ep,
 static int lh7a40x_ep_disable(struct usb_ep *ep);
 static struct usb_request *lh7a40x_alloc_request(struct usb_ep *ep, gfp_t);
 static void lh7a40x_free_request(struct usb_ep *ep, struct usb_request *);
-static void *lh7a40x_alloc_buffer(struct usb_ep *ep, unsigned, dma_addr_t *,
-                                 gfp_t);
-static void lh7a40x_free_buffer(struct usb_ep *ep, void *, dma_addr_t,
-                               unsigned);
 static int lh7a40x_queue(struct usb_ep *ep, struct usb_request *, gfp_t);
 static int lh7a40x_dequeue(struct usb_ep *ep, struct usb_request *);
 static int lh7a40x_set_halt(struct usb_ep *ep, int);
@@ -104,9 +100,6 @@ static struct usb_ep_ops lh7a40x_ep_ops = {
        .alloc_request = lh7a40x_alloc_request,
        .free_request = lh7a40x_free_request,
 
-       .alloc_buffer = lh7a40x_alloc_buffer,
-       .free_buffer = lh7a40x_free_buffer,
-
        .queue = lh7a40x_queue,
        .dequeue = lh7a40x_dequeue,
 
@@ -1134,26 +1127,6 @@ static void lh7a40x_free_request(struct usb_ep *ep, struct usb_request *_req)
        kfree(req);
 }
 
-static void *lh7a40x_alloc_buffer(struct usb_ep *ep, unsigned bytes,
-                                 dma_addr_t * dma, gfp_t gfp_flags)
-{
-       char *retval;
-
-       DEBUG("%s (%p, %d, %d)\n", __FUNCTION__, ep, bytes, gfp_flags);
-
-       retval = kmalloc(bytes, gfp_flags & ~(__GFP_DMA | __GFP_HIGHMEM));
-       if (retval)
-               *dma = virt_to_bus(retval);
-       return retval;
-}
-
-static void lh7a40x_free_buffer(struct usb_ep *ep, void *buf, dma_addr_t dma,
-                               unsigned bytes)
-{
-       DEBUG("%s, %p\n", __FUNCTION__, ep);
-       kfree(buf);
-}
-
 /** Queue one request
  *  Kickstart transfer if needed
  *  NOTE: Sets INDEX register
diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c
new file mode 100644 (file)
index 0000000..c0a962b
--- /dev/null
@@ -0,0 +1,1653 @@
+/*
+ * M66592 UDC (USB gadget)
+ *
+ * Copyright (C) 2006-2007 Renesas Solutions Corp.
+ *
+ * Author : Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/timer.h>
+#include <linux/delay.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb_gadget.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+
+#include "m66592-udc.h"
+
+MODULE_DESCRIPTION("M66592 USB gadget driiver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Yoshihiro Shimoda");
+
+#define DRIVER_VERSION "29 May 2007"
+
+/* module parameters */
+static unsigned short clock = M66592_XTAL24;
+module_param(clock, ushort, 0644);
+MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0(default=16384)");
+static unsigned short vif = M66592_LDRV;
+module_param(vif, ushort, 0644);
+MODULE_PARM_DESC(vif, "input VIF: 3.3V=32768, 1.5V=0(default=32768)");
+static unsigned short endian = 0;
+module_param(endian, ushort, 0644);
+MODULE_PARM_DESC(endian, "data endian: big=256, little=0(default=0)");
+static unsigned short irq_sense = M66592_INTL;
+module_param(irq_sense, ushort, 0644);
+MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=2, falling edge=0(default=2)");
+
+static const char udc_name[] = "m66592_udc";
+static const char *m66592_ep_name[] = {
+       "ep0", "ep1", "ep2", "ep3", "ep4", "ep5", "ep6", "ep7"
+};
+
+static void disable_controller(struct m66592 *m66592);
+static void irq_ep0_write(struct m66592_ep *ep, struct m66592_request *req);
+static void irq_packet_write(struct m66592_ep *ep, struct m66592_request *req);
+static int m66592_queue(struct usb_ep *_ep, struct usb_request *_req,
+                       gfp_t gfp_flags);
+
+static void transfer_complete(struct m66592_ep *ep,
+                             struct m66592_request *req,
+                             int status);
+/*-------------------------------------------------------------------------*/
+static inline u16 get_usb_speed(struct m66592 *m66592)
+{
+       return (m66592_read(m66592, M66592_DVSTCTR) & M66592_RHST);
+}
+
+static void enable_pipe_irq(struct m66592 *m66592, u16 pipenum,
+                           unsigned long reg)
+{
+       u16 tmp;
+
+       tmp = m66592_read(m66592, M66592_INTENB0);
+       m66592_bclr(m66592, M66592_BEMPE | M66592_NRDYE | M66592_BRDYE,
+                   M66592_INTENB0);
+       m66592_bset(m66592, (1 << pipenum), reg);
+       m66592_write(m66592, tmp, M66592_INTENB0);
+}
+
+static void disable_pipe_irq(struct m66592 *m66592, u16 pipenum,
+                            unsigned long reg)
+{
+       u16 tmp;
+
+       tmp = m66592_read(m66592, M66592_INTENB0);
+       m66592_bclr(m66592, M66592_BEMPE | M66592_NRDYE | M66592_BRDYE,
+                   M66592_INTENB0);
+       m66592_bclr(m66592, (1 << pipenum), reg);
+       m66592_write(m66592, tmp, M66592_INTENB0);
+}
+
+static void m66592_usb_connect(struct m66592 *m66592)
+{
+       m66592_bset(m66592, M66592_CTRE, M66592_INTENB0);
+       m66592_bset(m66592, M66592_WDST | M66592_RDST | M66592_CMPL,
+                   M66592_INTENB0);
+       m66592_bset(m66592, M66592_BEMPE | M66592_BRDYE, M66592_INTENB0);
+
+       m66592_bset(m66592, M66592_DPRPU, M66592_SYSCFG);
+}
+
+static void m66592_usb_disconnect(struct m66592 *m66592)
+{
+       m66592_bclr(m66592, M66592_CTRE, M66592_INTENB0);
+       m66592_bclr(m66592, M66592_WDST | M66592_RDST | M66592_CMPL,
+                   M66592_INTENB0);
+       m66592_bclr(m66592, M66592_BEMPE | M66592_BRDYE, M66592_INTENB0);
+       m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG);
+
+       m66592->gadget.speed = USB_SPEED_UNKNOWN;
+       spin_unlock(&m66592->lock);
+       m66592->driver->disconnect(&m66592->gadget);
+       spin_lock(&m66592->lock);
+
+       disable_controller(m66592);
+       INIT_LIST_HEAD(&m66592->ep[0].queue);
+}
+
+static inline u16 control_reg_get_pid(struct m66592 *m66592, u16 pipenum)
+{
+       u16 pid = 0;
+       unsigned long offset;
+
+       if (pipenum == 0)
+               pid = m66592_read(m66592, M66592_DCPCTR) & M66592_PID;
+       else if (pipenum < M66592_MAX_NUM_PIPE) {
+               offset = get_pipectr_addr(pipenum);
+               pid = m66592_read(m66592, offset) & M66592_PID;
+       } else
+               printk(KERN_ERR "unexpect pipe num (%d)\n", pipenum);
+
+       return pid;
+}
+
+static inline void control_reg_set_pid(struct m66592 *m66592, u16 pipenum,
+                                      u16 pid)
+{
+       unsigned long offset;
+
+       if (pipenum == 0)
+               m66592_mdfy(m66592, pid, M66592_PID, M66592_DCPCTR);
+       else if (pipenum < M66592_MAX_NUM_PIPE) {
+               offset = get_pipectr_addr(pipenum);
+               m66592_mdfy(m66592, pid, M66592_PID, offset);
+       } else
+               printk(KERN_ERR "unexpect pipe num (%d)\n", pipenum);
+}
+
+static inline void pipe_start(struct m66592 *m66592, u16 pipenum)
+{
+       control_reg_set_pid(m66592, pipenum, M66592_PID_BUF);
+}
+
+static inline void pipe_stop(struct m66592 *m66592, u16 pipenum)
+{
+       control_reg_set_pid(m66592, pipenum, M66592_PID_NAK);
+}
+
+static inline void pipe_stall(struct m66592 *m66592, u16 pipenum)
+{
+       control_reg_set_pid(m66592, pipenum, M66592_PID_STALL);
+}
+
+static inline u16 control_reg_get(struct m66592 *m66592, u16 pipenum)
+{
+       u16 ret = 0;
+       unsigned long offset;
+
+       if (pipenum == 0)
+               ret = m66592_read(m66592, M66592_DCPCTR);
+       else if (pipenum < M66592_MAX_NUM_PIPE) {
+               offset = get_pipectr_addr(pipenum);
+               ret = m66592_read(m66592, offset);
+       } else
+               printk(KERN_ERR "unexpect pipe num (%d)\n", pipenum);
+
+       return ret;
+}
+
+static inline void control_reg_sqclr(struct m66592 *m66592, u16 pipenum)
+{
+       unsigned long offset;
+
+       pipe_stop(m66592, pipenum);
+
+       if (pipenum == 0)
+               m66592_bset(m66592, M66592_SQCLR, M66592_DCPCTR);
+       else if (pipenum < M66592_MAX_NUM_PIPE) {
+               offset = get_pipectr_addr(pipenum);
+               m66592_bset(m66592, M66592_SQCLR, offset);
+       } else
+               printk(KERN_ERR "unexpect pipe num(%d)\n", pipenum);
+}
+
+static inline int get_buffer_size(struct m66592 *m66592, u16 pipenum)
+{
+       u16 tmp;
+       int size;
+
+       if (pipenum == 0) {
+               tmp = m66592_read(m66592, M66592_DCPCFG);
+               if ((tmp & M66592_CNTMD) != 0)
+                       size = 256;
+               else {
+                       tmp = m66592_read(m66592, M66592_DCPMAXP);
+                       size = tmp & M66592_MAXP;
+               }
+       } else {
+               m66592_write(m66592, pipenum, M66592_PIPESEL);
+               tmp = m66592_read(m66592, M66592_PIPECFG);
+               if ((tmp & M66592_CNTMD) != 0) {
+                       tmp = m66592_read(m66592, M66592_PIPEBUF);
+                       size = ((tmp >> 10) + 1) * 64;
+               } else {
+                       tmp = m66592_read(m66592, M66592_PIPEMAXP);
+                       size = tmp & M66592_MXPS;
+               }
+       }
+
+       return size;
+}
+
+static inline void pipe_change(struct m66592 *m66592, u16 pipenum)
+{
+       struct m66592_ep *ep = m66592->pipenum2ep[pipenum];
+
+       if (ep->use_dma)
+               return;
+
+       m66592_mdfy(m66592, pipenum, M66592_CURPIPE, ep->fifosel);
+
+       ndelay(450);
+
+       m66592_bset(m66592, M66592_MBW, ep->fifosel);
+}
+
+static int pipe_buffer_setting(struct m66592 *m66592,
+                              struct m66592_pipe_info *info)
+{
+       u16 bufnum = 0, buf_bsize = 0;
+       u16 pipecfg = 0;
+
+       if (info->pipe == 0)
+               return -EINVAL;
+
+       m66592_write(m66592, info->pipe, M66592_PIPESEL);
+
+       if (info->dir_in)
+               pipecfg |= M66592_DIR;
+       pipecfg |= info->type;
+       pipecfg |= info->epnum;
+       switch (info->type) {
+       case M66592_INT:
+               bufnum = 4 + (info->pipe - M66592_BASE_PIPENUM_INT);
+               buf_bsize = 0;
+               break;
+       case M66592_BULK:
+               bufnum = m66592->bi_bufnum +
+                        (info->pipe - M66592_BASE_PIPENUM_BULK) * 16;
+               m66592->bi_bufnum += 16;
+               buf_bsize = 7;
+               pipecfg |= M66592_DBLB;
+               if (!info->dir_in)
+                       pipecfg |= M66592_SHTNAK;
+               break;
+       case M66592_ISO:
+               bufnum = m66592->bi_bufnum +
+                        (info->pipe - M66592_BASE_PIPENUM_ISOC) * 16;
+               m66592->bi_bufnum += 16;
+               buf_bsize = 7;
+               break;
+       }
+       if (m66592->bi_bufnum > M66592_MAX_BUFNUM) {
+               printk(KERN_ERR "m66592 pipe memory is insufficient(%d)\n",
+                      m66592->bi_bufnum);
+               return -ENOMEM;
+       }
+
+       m66592_write(m66592, pipecfg, M66592_PIPECFG);
+       m66592_write(m66592, (buf_bsize << 10) | (bufnum), M66592_PIPEBUF);
+       m66592_write(m66592, info->maxpacket, M66592_PIPEMAXP);
+       if (info->interval)
+               info->interval--;
+       m66592_write(m66592, info->interval, M66592_PIPEPERI);
+
+       return 0;
+}
+
+static void pipe_buffer_release(struct m66592 *m66592,
+                               struct m66592_pipe_info *info)
+{
+       if (info->pipe == 0)
+               return;
+
+       switch (info->type) {
+       case M66592_BULK:
+               if (is_bulk_pipe(info->pipe))
+                       m66592->bi_bufnum -= 16;
+               break;
+       case M66592_ISO:
+               if (is_isoc_pipe(info->pipe))
+                       m66592->bi_bufnum -= 16;
+               break;
+       }
+
+       if (is_bulk_pipe(info->pipe)) {
+               m66592->bulk--;
+       } else if (is_interrupt_pipe(info->pipe))
+               m66592->interrupt--;
+       else if (is_isoc_pipe(info->pipe)) {
+               m66592->isochronous--;
+               if (info->type == M66592_BULK)
+                       m66592->bulk--;
+       } else
+               printk(KERN_ERR "ep_release: unexpect pipenum (%d)\n",
+                      info->pipe);
+}
+
+static void pipe_initialize(struct m66592_ep *ep)
+{
+       struct m66592 *m66592 = ep->m66592;
+
+       m66592_mdfy(m66592, 0, M66592_CURPIPE, ep->fifosel);
+
+       m66592_write(m66592, M66592_ACLRM, ep->pipectr);
+       m66592_write(m66592, 0, ep->pipectr);
+       m66592_write(m66592, M66592_SQCLR, ep->pipectr);
+       if (ep->use_dma) {
+               m66592_mdfy(m66592, ep->pipenum, M66592_CURPIPE, ep->fifosel);
+
+               ndelay(450);
+
+               m66592_bset(m66592, M66592_MBW, ep->fifosel);
+       }
+}
+
+static void m66592_ep_setting(struct m66592 *m66592, struct m66592_ep *ep,
+                             const struct usb_endpoint_descriptor *desc,
+                             u16 pipenum, int dma)
+{
+       if ((pipenum != 0) && dma) {
+               if (m66592->num_dma == 0) {
+                       m66592->num_dma++;
+                       ep->use_dma = 1;
+                       ep->fifoaddr = M66592_D0FIFO;
+                       ep->fifosel = M66592_D0FIFOSEL;
+                       ep->fifoctr = M66592_D0FIFOCTR;
+                       ep->fifotrn = M66592_D0FIFOTRN;
+               } else if (m66592->num_dma == 1) {
+                       m66592->num_dma++;
+                       ep->use_dma = 1;
+                       ep->fifoaddr = M66592_D1FIFO;
+                       ep->fifosel = M66592_D1FIFOSEL;
+                       ep->fifoctr = M66592_D1FIFOCTR;
+                       ep->fifotrn = M66592_D1FIFOTRN;
+               } else {
+                       ep->use_dma = 0;
+                       ep->fifoaddr = M66592_CFIFO;
+                       ep->fifosel = M66592_CFIFOSEL;
+                       ep->fifoctr = M66592_CFIFOCTR;
+                       ep->fifotrn = 0;
+               }
+       } else {
+               ep->use_dma = 0;
+               ep->fifoaddr = M66592_CFIFO;
+               ep->fifosel = M66592_CFIFOSEL;
+               ep->fifoctr = M66592_CFIFOCTR;
+               ep->fifotrn = 0;
+       }
+
+       ep->pipectr = get_pipectr_addr(pipenum);
+       ep->pipenum = pipenum;
+       ep->ep.maxpacket = desc->wMaxPacketSize;
+       m66592->pipenum2ep[pipenum] = ep;
+       m66592->epaddr2ep[desc->bEndpointAddress&USB_ENDPOINT_NUMBER_MASK] = ep;
+       INIT_LIST_HEAD(&ep->queue);
+}
+
+static void m66592_ep_release(struct m66592_ep *ep)
+{
+       struct m66592 *m66592 = ep->m66592;
+       u16 pipenum = ep->pipenum;
+
+       if (pipenum == 0)
+               return;
+
+       if (ep->use_dma)
+               m66592->num_dma--;
+       ep->pipenum = 0;
+       ep->busy = 0;
+       ep->use_dma = 0;
+}
+
+static int alloc_pipe_config(struct m66592_ep *ep,
+                            const struct usb_endpoint_descriptor *desc)
+{
+       struct m66592 *m66592 = ep->m66592;
+       struct m66592_pipe_info info;
+       int dma = 0;
+       int *counter;
+       int ret;
+
+       ep->desc = desc;
+
+       BUG_ON(ep->pipenum);
+
+       switch(desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
+       case USB_ENDPOINT_XFER_BULK:
+               if (m66592->bulk >= M66592_MAX_NUM_BULK) {
+                       if (m66592->isochronous >= M66592_MAX_NUM_ISOC) {
+                               printk(KERN_ERR "bulk pipe is insufficient\n");
+                               return -ENODEV;
+                       } else {
+                               info.pipe = M66592_BASE_PIPENUM_ISOC +
+                                           m66592->isochronous;
+                               counter = &m66592->isochronous;
+                       }
+               } else {
+                       info.pipe = M66592_BASE_PIPENUM_BULK + m66592->bulk;
+                       counter = &m66592->bulk;
+               }
+               info.type = M66592_BULK;
+               dma = 1;
+               break;
+       case USB_ENDPOINT_XFER_INT:
+               if (m66592->interrupt >= M66592_MAX_NUM_INT) {
+                       printk(KERN_ERR "interrupt pipe is insufficient\n");
+                       return -ENODEV;
+               }
+               info.pipe = M66592_BASE_PIPENUM_INT + m66592->interrupt;
+               info.type = M66592_INT;
+               counter = &m66592->interrupt;
+               break;
+       case USB_ENDPOINT_XFER_ISOC:
+               if (m66592->isochronous >= M66592_MAX_NUM_ISOC) {
+                       printk(KERN_ERR "isochronous pipe is insufficient\n");
+                       return -ENODEV;
+               }
+               info.pipe = M66592_BASE_PIPENUM_ISOC + m66592->isochronous;
+               info.type = M66592_ISO;
+               counter = &m66592->isochronous;
+               break;
+       default:
+               printk(KERN_ERR "unexpect xfer type\n");
+               return -EINVAL;
+       }
+       ep->type = info.type;
+
+       info.epnum = desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+       info.maxpacket = desc->wMaxPacketSize;
+       info.interval = desc->bInterval;
+       if (desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
+               info.dir_in = 1;
+       else
+               info.dir_in = 0;
+
+       ret = pipe_buffer_setting(m66592, &info);
+       if (ret < 0) {
+               printk(KERN_ERR "pipe_buffer_setting fail\n");
+               return ret;
+       }
+
+       (*counter)++;
+       if ((counter == &m66592->isochronous) && info.type == M66592_BULK)
+               m66592->bulk++;
+
+       m66592_ep_setting(m66592, ep, desc, info.pipe, dma);
+       pipe_initialize(ep);
+
+       return 0;
+}
+
+static int free_pipe_config(struct m66592_ep *ep)
+{
+       struct m66592 *m66592 = ep->m66592;
+       struct m66592_pipe_info info;
+
+       info.pipe = ep->pipenum;
+       info.type = ep->type;
+       pipe_buffer_release(m66592, &info);
+       m66592_ep_release(ep);
+
+       return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+static void pipe_irq_enable(struct m66592 *m66592, u16 pipenum)
+{
+       enable_irq_ready(m66592, pipenum);
+       enable_irq_nrdy(m66592, pipenum);
+}
+
+static void pipe_irq_disable(struct m66592 *m66592, u16 pipenum)
+{
+       disable_irq_ready(m66592, pipenum);
+       disable_irq_nrdy(m66592, pipenum);
+}
+
+/* if complete is true, gadget driver complete function is not call */
+static void control_end(struct m66592 *m66592, unsigned ccpl)
+{
+       m66592->ep[0].internal_ccpl = ccpl;
+       pipe_start(m66592, 0);
+       m66592_bset(m66592, M66592_CCPL, M66592_DCPCTR);
+}
+
+static void start_ep0_write(struct m66592_ep *ep, struct m66592_request *req)
+{
+       struct m66592 *m66592 = ep->m66592;
+
+       pipe_change(m66592, ep->pipenum);
+       m66592_mdfy(m66592, M66592_ISEL | M66592_PIPE0,
+                   (M66592_ISEL | M66592_CURPIPE),
+                   M66592_CFIFOSEL);
+       m66592_write(m66592, M66592_BCLR, ep->fifoctr);
+       if (req->req.length == 0) {
+               m66592_bset(m66592, M66592_BVAL, ep->fifoctr);
+               pipe_start(m66592, 0);
+               transfer_complete(ep, req, 0);
+       } else {
+               m66592_write(m66592, ~M66592_BEMP0, M66592_BEMPSTS);
+               irq_ep0_write(ep, req);
+       }
+}
+
+static void start_packet_write(struct m66592_ep *ep, struct m66592_request *req)
+{
+       struct m66592 *m66592 = ep->m66592;
+       u16 tmp;
+
+       pipe_change(m66592, ep->pipenum);
+       disable_irq_empty(m66592, ep->pipenum);
+       pipe_start(m66592, ep->pipenum);
+
+       tmp = m66592_read(m66592, ep->fifoctr);
+       if (unlikely((tmp & M66592_FRDY) == 0))
+               pipe_irq_enable(m66592, ep->pipenum);
+       else
+               irq_packet_write(ep, req);
+}
+
+static void start_packet_read(struct m66592_ep *ep, struct m66592_request *req)
+{
+       struct m66592 *m66592 = ep->m66592;
+       u16 pipenum = ep->pipenum;
+
+       if (ep->pipenum == 0) {
+               m66592_mdfy(m66592, M66592_PIPE0,
+                           (M66592_ISEL | M66592_CURPIPE),
+                           M66592_CFIFOSEL);
+               m66592_write(m66592, M66592_BCLR, ep->fifoctr);
+               pipe_start(m66592, pipenum);
+               pipe_irq_enable(m66592, pipenum);
+       } else {
+               if (ep->use_dma) {
+                       m66592_bset(m66592, M66592_TRCLR, ep->fifosel);
+                       pipe_change(m66592, pipenum);
+                       m66592_bset(m66592, M66592_TRENB, ep->fifosel);
+                       m66592_write(m66592,
+                                    (req->req.length + ep->ep.maxpacket - 1) /
+                                    ep->ep.maxpacket, ep->fifotrn);
+               }
+               pipe_start(m66592, pipenum);    /* trigger once */
+               pipe_irq_enable(m66592, pipenum);
+       }
+}
+
+static void start_packet(struct m66592_ep *ep, struct m66592_request *req)
+{
+       if (ep->desc->bEndpointAddress & USB_DIR_IN)
+               start_packet_write(ep, req);
+       else
+               start_packet_read(ep, req);
+}
+
+static void start_ep0(struct m66592_ep *ep, struct m66592_request *req)
+{
+       u16 ctsq;
+
+       ctsq = m66592_read(ep->m66592, M66592_INTSTS0) & M66592_CTSQ;
+
+       switch (ctsq) {
+       case M66592_CS_RDDS:
+               start_ep0_write(ep, req);
+               break;
+       case M66592_CS_WRDS:
+               start_packet_read(ep, req);
+               break;
+
+       case M66592_CS_WRND:
+               control_end(ep->m66592, 0);
+               break;
+       default:
+               printk(KERN_ERR "start_ep0: unexpect ctsq(%x)\n", ctsq);
+               break;
+       }
+}
+
+static void init_controller(struct m66592 *m66592)
+{
+       m66592_bset(m66592, (vif & M66592_LDRV) | (endian & M66592_BIGEND),
+                   M66592_PINCFG);
+       m66592_bset(m66592, M66592_HSE, M66592_SYSCFG);         /* High spd */
+       m66592_mdfy(m66592, clock & M66592_XTAL, M66592_XTAL, M66592_SYSCFG);
+
+       m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG);
+       m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG);
+       m66592_bset(m66592, M66592_USBE, M66592_SYSCFG);
+
+       m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG);
+
+       msleep(3);
+
+       m66592_bset(m66592, M66592_RCKE | M66592_PLLC, M66592_SYSCFG);
+
+       msleep(1);
+
+       m66592_bset(m66592, M66592_SCKE, M66592_SYSCFG);
+
+       m66592_bset(m66592, irq_sense & M66592_INTL, M66592_INTENB1);
+       m66592_write(m66592, M66592_BURST | M66592_CPU_ADR_RD_WR,
+                    M66592_DMA0CFG);
+}
+
+static void disable_controller(struct m66592 *m66592)
+{
+       m66592_bclr(m66592, M66592_SCKE, M66592_SYSCFG);
+       udelay(1);
+       m66592_bclr(m66592, M66592_PLLC, M66592_SYSCFG);
+       udelay(1);
+       m66592_bclr(m66592, M66592_RCKE, M66592_SYSCFG);
+       udelay(1);
+       m66592_bclr(m66592, M66592_XCKE, M66592_SYSCFG);
+}
+
+static void m66592_start_xclock(struct m66592 *m66592)
+{
+       u16 tmp;
+
+       tmp = m66592_read(m66592, M66592_SYSCFG);
+       if (!(tmp & M66592_XCKE))
+               m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG);
+}
+
+/*-------------------------------------------------------------------------*/
+static void transfer_complete(struct m66592_ep *ep,
+                             struct m66592_request *req,
+                             int status)
+{
+       int restart = 0;
+
+       if (unlikely(ep->pipenum == 0)) {
+               if (ep->internal_ccpl) {
+                       ep->internal_ccpl = 0;
+                       return;
+               }
+       }
+
+       list_del_init(&req->queue);
+       if (ep->m66592->gadget.speed == USB_SPEED_UNKNOWN)
+               req->req.status = -ESHUTDOWN;
+       else
+               req->req.status = status;
+
+       if (!list_empty(&ep->queue))
+               restart = 1;
+
+       if (likely(req->req.complete))
+               req->req.complete(&ep->ep, &req->req);
+
+       if (restart) {
+               req = list_entry(ep->queue.next, struct m66592_request, queue);
+               if (ep->desc)
+                       start_packet(ep, req);
+       }
+}
+
+static void irq_ep0_write(struct m66592_ep *ep, struct m66592_request *req)
+{
+       int i;
+       volatile u16 tmp;
+       unsigned bufsize;
+       size_t size;
+       void *buf;
+       u16 pipenum = ep->pipenum;
+       struct m66592 *m66592 = ep->m66592;
+
+       pipe_change(m66592, pipenum);
+       m66592_bset(m66592, M66592_ISEL, ep->fifosel);
+
+       i = 0;
+       do {
+               tmp = m66592_read(m66592, ep->fifoctr);
+               if (i++ > 100000) {
+                       printk(KERN_ERR "pipe0 is busy. maybe cpu i/o bus"
+                               "conflict. please power off this controller.");
+                       return;
+               }
+               ndelay(1);
+       } while ((tmp & M66592_FRDY) == 0);
+
+       /* prepare parameters */
+       bufsize = get_buffer_size(m66592, pipenum);
+       buf = req->req.buf + req->req.actual;
+       size = min(bufsize, req->req.length - req->req.actual);
+
+       /* write fifo */
+       if (req->req.buf) {
+               if (size > 0)
+                       m66592_write_fifo(m66592, ep->fifoaddr, buf, size);
+               if ((size == 0) || ((size % ep->ep.maxpacket) != 0))
+                       m66592_bset(m66592, M66592_BVAL, ep->fifoctr);
+       }
+
+       /* update parameters */
+       req->req.actual += size;
+
+       /* check transfer finish */
+       if ((!req->req.zero && (req->req.actual == req->req.length)) ||
+           (size % ep->ep.maxpacket) || (size == 0)) {
+               disable_irq_ready(m66592, pipenum);
+               disable_irq_empty(m66592, pipenum);
+       } else {
+               disable_irq_ready(m66592, pipenum);
+               enable_irq_empty(m66592, pipenum);
+       }
+       pipe_start(m66592, pipenum);
+}
+
+static void irq_packet_write(struct m66592_ep *ep, struct m66592_request *req)
+{
+       u16 tmp;
+       unsigned bufsize;
+       size_t size;
+       void *buf;
+       u16 pipenum = ep->pipenum;
+       struct m66592 *m66592 = ep->m66592;
+
+       pipe_change(m66592, pipenum);
+       tmp = m66592_read(m66592, ep->fifoctr);
+       if (unlikely((tmp & M66592_FRDY) == 0)) {
+               pipe_stop(m66592, pipenum);
+               pipe_irq_disable(m66592, pipenum);
+               printk(KERN_ERR "write fifo not ready. pipnum=%d\n", pipenum);
+               return;
+       }
+
+       /* prepare parameters */
+       bufsize = get_buffer_size(m66592, pipenum);
+       buf = req->req.buf + req->req.actual;
+       size = min(bufsize, req->req.length - req->req.actual);
+
+       /* write fifo */
+       if (req->req.buf) {
+               m66592_write_fifo(m66592, ep->fifoaddr, buf, size);
+               if ((size == 0) || ((size % ep->ep.maxpacket) != 0) ||
+                   ((bufsize != ep->ep.maxpacket) && (bufsize > size)))
+                       m66592_bset(m66592, M66592_BVAL, ep->fifoctr);
+       }
+
+       /* update parameters */
+       req->req.actual += size;
+       /* check transfer finish */
+       if ((!req->req.zero && (req->req.actual == req->req.length)) ||
+           (size % ep->ep.maxpacket) || (size == 0)) {
+               disable_irq_ready(m66592, pipenum);
+               enable_irq_empty(m66592, pipenum);
+       } else {
+               disable_irq_empty(m66592, pipenum);
+               pipe_irq_enable(m66592, pipenum);
+       }
+}
+
+static void irq_packet_read(struct m66592_ep *ep, struct m66592_request *req)
+{
+       u16 tmp;
+       int rcv_len, bufsize, req_len;
+       int size;
+       void *buf;
+       u16 pipenum = ep->pipenum;
+       struct m66592 *m66592 = ep->m66592;
+       int finish = 0;
+
+       pipe_change(m66592, pipenum);
+       tmp = m66592_read(m66592, ep->fifoctr);
+       if (unlikely((tmp & M66592_FRDY) == 0)) {
+               req->req.status = -EPIPE;
+               pipe_stop(m66592, pipenum);
+               pipe_irq_disable(m66592, pipenum);
+               printk(KERN_ERR "read fifo not ready");
+               return;
+       }
+
+       /* prepare parameters */
+       rcv_len = tmp & M66592_DTLN;
+       bufsize = get_buffer_size(m66592, pipenum);
+
+       buf = req->req.buf + req->req.actual;
+       req_len = req->req.length - req->req.actual;
+       if (rcv_len < bufsize)
+               size = min(rcv_len, req_len);
+       else
+               size = min(bufsize, req_len);
+
+       /* update parameters */
+       req->req.actual += size;
+
+       /* check transfer finish */
+       if ((!req->req.zero && (req->req.actual == req->req.length)) ||
+           (size % ep->ep.maxpacket) || (size == 0)) {
+               pipe_stop(m66592, pipenum);
+               pipe_irq_disable(m66592, pipenum);
+               finish = 1;
+       }
+
+       /* read fifo */
+       if (req->req.buf) {
+               if (size == 0)
+                       m66592_write(m66592, M66592_BCLR, ep->fifoctr);
+               else
+                       m66592_read_fifo(m66592, ep->fifoaddr, buf, size);
+       }
+
+       if ((ep->pipenum != 0) && finish)
+               transfer_complete(ep, req, 0);
+}
+
+static void irq_pipe_ready(struct m66592 *m66592, u16 status, u16 enb)
+{
+       u16 check;
+       u16 pipenum;
+       struct m66592_ep *ep;
+       struct m66592_request *req;
+
+       if ((status & M66592_BRDY0) && (enb & M66592_BRDY0)) {
+               m66592_write(m66592, ~M66592_BRDY0, M66592_BRDYSTS);
+               m66592_mdfy(m66592, M66592_PIPE0, M66592_CURPIPE,
+                           M66592_CFIFOSEL);
+
+               ep = &m66592->ep[0];
+               req = list_entry(ep->queue.next, struct m66592_request, queue);
+               irq_packet_read(ep, req);
+       } else {
+               for (pipenum = 1; pipenum < M66592_MAX_NUM_PIPE; pipenum++) {
+                       check = 1 << pipenum;
+                       if ((status & check) && (enb & check)) {
+                               m66592_write(m66592, ~check, M66592_BRDYSTS);
+                               ep = m66592->pipenum2ep[pipenum];
+                               req = list_entry(ep->queue.next,
+                                                struct m66592_request, queue);
+                               if (ep->desc->bEndpointAddress & USB_DIR_IN)
+                                       irq_packet_write(ep, req);
+                               else
+                                       irq_packet_read(ep, req);
+                       }
+               }
+       }
+}
+
+static void irq_pipe_empty(struct m66592 *m66592, u16 status, u16 enb)
+{
+       u16 tmp;
+       u16 check;
+       u16 pipenum;
+       struct m66592_ep *ep;
+       struct m66592_request *req;
+
+       if ((status & M66592_BEMP0) && (enb & M66592_BEMP0)) {
+               m66592_write(m66592, ~M66592_BEMP0, M66592_BEMPSTS);
+
+               ep = &m66592->ep[0];
+               req = list_entry(ep->queue.next, struct m66592_request, queue);
+               irq_ep0_write(ep, req);
+       } else {
+               for (pipenum = 1; pipenum < M66592_MAX_NUM_PIPE; pipenum++) {
+                       check = 1 << pipenum;
+                       if ((status & check) && (enb & check)) {
+                               m66592_write(m66592, ~check, M66592_BEMPSTS);
+                               tmp = control_reg_get(m66592, pipenum);
+                               if ((tmp & M66592_INBUFM) == 0) {
+                                       disable_irq_empty(m66592, pipenum);
+                                       pipe_irq_disable(m66592, pipenum);
+                                       pipe_stop(m66592, pipenum);
+                                       ep = m66592->pipenum2ep[pipenum];
+                                       req = list_entry(ep->queue.next,
+                                                        struct m66592_request,
+                                                        queue);
+                                       if (!list_empty(&ep->queue))
+                                               transfer_complete(ep, req, 0);
+                               }
+                       }
+               }
+       }
+}
+
+static void get_status(struct m66592 *m66592, struct usb_ctrlrequest *ctrl)
+{
+       struct m66592_ep *ep;
+       u16 pid;
+       u16 status = 0;
+
+       switch (ctrl->bRequestType & USB_RECIP_MASK) {
+       case USB_RECIP_DEVICE:
+               status = 1;     /* selfpower */
+               break;
+       case USB_RECIP_INTERFACE:
+               status = 0;
+               break;
+       case USB_RECIP_ENDPOINT:
+               ep = m66592->epaddr2ep[ctrl->wIndex&USB_ENDPOINT_NUMBER_MASK];
+               pid = control_reg_get_pid(m66592, ep->pipenum);
+               if (pid == M66592_PID_STALL)
+                       status = 1;
+               else
+                       status = 0;
+               break;
+       default:
+               pipe_stall(m66592, 0);
+               return;         /* exit */
+       }
+
+       *m66592->ep0_buf = status;
+       m66592->ep0_req->buf = m66592->ep0_buf;
+       m66592->ep0_req->length = 2;
+       m66592_queue(m66592->gadget.ep0, m66592->ep0_req, GFP_KERNEL);
+}
+
+static void clear_feature(struct m66592 *m66592, struct usb_ctrlrequest *ctrl)
+{
+       switch (ctrl->bRequestType & USB_RECIP_MASK) {
+       case USB_RECIP_DEVICE:
+               control_end(m66592, 1);
+               break;
+       case USB_RECIP_INTERFACE:
+               control_end(m66592, 1);
+               break;
+       case USB_RECIP_ENDPOINT: {
+               struct m66592_ep *ep;
+               struct m66592_request *req;
+
+               ep = m66592->epaddr2ep[ctrl->wIndex&USB_ENDPOINT_NUMBER_MASK];
+               pipe_stop(m66592, ep->pipenum);
+               control_reg_sqclr(m66592, ep->pipenum);
+
+               control_end(m66592, 1);
+
+               req = list_entry(ep->queue.next,
+               struct m66592_request, queue);
+               if (ep->busy) {
+                       ep->busy = 0;
+                       if (list_empty(&ep->queue))
+                               break;
+                       start_packet(ep, req);
+               } else if (!list_empty(&ep->queue))
+                       pipe_start(m66592, ep->pipenum);
+               }
+               break;
+       default:
+               pipe_stall(m66592, 0);
+               break;
+       }
+}
+
+static void set_feature(struct m66592 *m66592, struct usb_ctrlrequest *ctrl)
+{
+
+       switch (ctrl->bRequestType & USB_RECIP_MASK) {
+       case USB_RECIP_DEVICE:
+               control_end(m66592, 1);
+               break;
+       case USB_RECIP_INTERFACE:
+               control_end(m66592, 1);
+               break;
+       case USB_RECIP_ENDPOINT: {
+               struct m66592_ep *ep;
+
+               ep = m66592->epaddr2ep[ctrl->wIndex&USB_ENDPOINT_NUMBER_MASK];
+               pipe_stall(m66592, ep->pipenum);
+
+               control_end(m66592, 1);
+               }
+               break;
+       default:
+               pipe_stall(m66592, 0);
+               break;
+       }
+}
+
+/* if return value is true, call class driver's setup() */
+static int setup_packet(struct m66592 *m66592, struct usb_ctrlrequest *ctrl)
+{
+       u16 *p = (u16 *)ctrl;
+       unsigned long offset = M66592_USBREQ;
+       int i, ret = 0;
+
+       /* read fifo */
+       m66592_write(m66592, ~M66592_VALID, M66592_INTSTS0);
+
+       for (i = 0; i < 4; i++)
+               p[i] = m66592_read(m66592, offset + i*2);
+
+       /* check request */
+       if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) {
+               switch (ctrl->bRequest) {
+               case USB_REQ_GET_STATUS:
+                       get_status(m66592, ctrl);
+                       break;
+               case USB_REQ_CLEAR_FEATURE:
+                       clear_feature(m66592, ctrl);
+                       break;
+               case USB_REQ_SET_FEATURE:
+                       set_feature(m66592, ctrl);
+                       break;
+               default:
+                       ret = 1;
+                       break;
+               }
+       } else
+               ret = 1;
+       return ret;
+}
+
+static void m66592_update_usb_speed(struct m66592 *m66592)
+{
+       u16 speed = get_usb_speed(m66592);
+
+       switch (speed) {
+       case M66592_HSMODE:
+               m66592->gadget.speed = USB_SPEED_HIGH;
+               break;
+       case M66592_FSMODE:
+               m66592->gadget.speed = USB_SPEED_FULL;
+               break;
+       default:
+               m66592->gadget.speed = USB_SPEED_UNKNOWN;
+               printk(KERN_ERR "USB speed unknown\n");
+       }
+}
+
+static void irq_device_state(struct m66592 *m66592)
+{
+       u16 dvsq;
+
+       dvsq = m66592_read(m66592, M66592_INTSTS0) & M66592_DVSQ;
+       m66592_write(m66592, ~M66592_DVST, M66592_INTSTS0);
+
+       if (dvsq == M66592_DS_DFLT) {   /* bus reset */
+               m66592->driver->disconnect(&m66592->gadget);
+               m66592_update_usb_speed(m66592);
+       }
+       if (m66592->old_dvsq == M66592_DS_CNFG && dvsq != M66592_DS_CNFG)
+               m66592_update_usb_speed(m66592);
+       if ((dvsq == M66592_DS_CNFG || dvsq == M66592_DS_ADDS) &&
+           m66592->gadget.speed == USB_SPEED_UNKNOWN)
+               m66592_update_usb_speed(m66592);
+
+       m66592->old_dvsq = dvsq;
+}
+
+static void irq_control_stage(struct m66592 *m66592)
+{
+       struct usb_ctrlrequest ctrl;
+       u16 ctsq;
+
+       ctsq = m66592_read(m66592, M66592_INTSTS0) & M66592_CTSQ;
+       m66592_write(m66592, ~M66592_CTRT, M66592_INTSTS0);
+
+       switch (ctsq) {
+       case M66592_CS_IDST: {
+               struct m66592_ep *ep;
+               struct m66592_request *req;
+               ep = &m66592->ep[0];
+               req = list_entry(ep->queue.next, struct m66592_request, queue);
+               transfer_complete(ep, req, 0);
+               }
+               break;
+
+       case M66592_CS_RDDS:
+       case M66592_CS_WRDS:
+       case M66592_CS_WRND:
+               if (setup_packet(m66592, &ctrl)) {
+                       if (m66592->driver->setup(&m66592->gadget, &ctrl) < 0)
+                               pipe_stall(m66592, 0);
+               }
+               break;
+       case M66592_CS_RDSS:
+       case M66592_CS_WRSS:
+               control_end(m66592, 0);
+               break;
+       default:
+               printk(KERN_ERR "ctrl_stage: unexpect ctsq(%x)\n", ctsq);
+               break;
+       }
+}
+
+static irqreturn_t m66592_irq(int irq, void *_m66592)
+{
+       struct m66592 *m66592 = _m66592;
+       u16 intsts0;
+       u16 intenb0;
+       u16 brdysts, nrdysts, bempsts;
+       u16 brdyenb, nrdyenb, bempenb;
+       u16 savepipe;
+       u16 mask0;
+
+       intsts0 = m66592_read(m66592, M66592_INTSTS0);
+       intenb0 = m66592_read(m66592, M66592_INTENB0);
+
+       savepipe = m66592_read(m66592, M66592_CFIFOSEL);
+
+       mask0 = intsts0 & intenb0;
+       if (mask0) {
+               brdysts = m66592_read(m66592, M66592_BRDYSTS);
+               nrdysts = m66592_read(m66592, M66592_NRDYSTS);
+               bempsts = m66592_read(m66592, M66592_BEMPSTS);
+               brdyenb = m66592_read(m66592, M66592_BRDYENB);
+               nrdyenb = m66592_read(m66592, M66592_NRDYENB);
+               bempenb = m66592_read(m66592, M66592_BEMPENB);
+
+               if (mask0 & M66592_VBINT) {
+                       m66592_write(m66592, (u16)~M66592_VBINT,
+                                    M66592_INTSTS0);
+                       m66592_start_xclock(m66592);
+
+                       /* start vbus sampling */
+                       m66592->old_vbus = m66592_read(m66592, M66592_INTSTS0)
+                                          & M66592_VBSTS;
+                       m66592->scount = M66592_MAX_SAMPLING;
+
+                       mod_timer(&m66592->timer,
+                                 jiffies + msecs_to_jiffies(50));
+               }
+               if (intsts0 & M66592_DVSQ)
+                       irq_device_state(m66592);
+
+               if ((intsts0 & M66592_BRDY) && (intenb0 & M66592_BRDYE) &&
+                   (brdysts & brdyenb)) {
+                       irq_pipe_ready(m66592, brdysts, brdyenb);
+               }
+               if ((intsts0 & M66592_BEMP) && (intenb0 & M66592_BEMPE) &&
+                   (bempsts & bempenb)) {
+                       irq_pipe_empty(m66592, bempsts, bempenb);
+               }
+
+               if (intsts0 & M66592_CTRT)
+                       irq_control_stage(m66592);
+       }
+
+       m66592_write(m66592, savepipe, M66592_CFIFOSEL);
+
+       return IRQ_HANDLED;
+}
+
+static void m66592_timer(unsigned long _m66592)
+{
+       struct m66592 *m66592 = (struct m66592 *)_m66592;
+       unsigned long flags;
+       u16 tmp;
+
+       spin_lock_irqsave(&m66592->lock, flags);
+       tmp = m66592_read(m66592, M66592_SYSCFG);
+       if (!(tmp & M66592_RCKE)) {
+               m66592_bset(m66592, M66592_RCKE | M66592_PLLC, M66592_SYSCFG);
+               udelay(10);
+               m66592_bset(m66592, M66592_SCKE, M66592_SYSCFG);
+       }
+       if (m66592->scount > 0) {
+               tmp = m66592_read(m66592, M66592_INTSTS0) & M66592_VBSTS;
+               if (tmp == m66592->old_vbus) {
+                       m66592->scount--;
+                       if (m66592->scount == 0) {
+                               if (tmp == M66592_VBSTS)
+                                       m66592_usb_connect(m66592);
+                               else
+                                       m66592_usb_disconnect(m66592);
+                       } else {
+                               mod_timer(&m66592->timer,
+                                         jiffies + msecs_to_jiffies(50));
+                       }
+               } else {
+                       m66592->scount = M66592_MAX_SAMPLING;
+                       m66592->old_vbus = tmp;
+                       mod_timer(&m66592->timer,
+                                 jiffies + msecs_to_jiffies(50));
+               }
+       }
+       spin_unlock_irqrestore(&m66592->lock, flags);
+}
+
+/*-------------------------------------------------------------------------*/
+static int m66592_enable(struct usb_ep *_ep,
+                        const struct usb_endpoint_descriptor *desc)
+{
+       struct m66592_ep *ep;
+
+       ep = container_of(_ep, struct m66592_ep, ep);
+       return alloc_pipe_config(ep, desc);
+}
+
+static int m66592_disable(struct usb_ep *_ep)
+{
+       struct m66592_ep *ep;
+       struct m66592_request *req;
+       unsigned long flags;
+
+       ep = container_of(_ep, struct m66592_ep, ep);
+       BUG_ON(!ep);
+
+       while (!list_empty(&ep->queue)) {
+               req = list_entry(ep->queue.next, struct m66592_request, queue);
+               spin_lock_irqsave(&ep->m66592->lock, flags);
+               transfer_complete(ep, req, -ECONNRESET);
+               spin_unlock_irqrestore(&ep->m66592->lock, flags);
+       }
+
+       pipe_irq_disable(ep->m66592, ep->pipenum);
+       return free_pipe_config(ep);
+}
+
+static struct usb_request *m66592_alloc_request(struct usb_ep *_ep,
+                                               gfp_t gfp_flags)
+{
+       struct m66592_request *req;
+
+       req = kzalloc(sizeof(struct m66592_request), gfp_flags);
+       if (!req)
+               return NULL;
+
+       INIT_LIST_HEAD(&req->queue);
+
+       return &req->req;
+}
+
+static void m66592_free_request(struct usb_ep *_ep, struct usb_request *_req)
+{
+       struct m66592_request *req;
+
+       req = container_of(_req, struct m66592_request, req);
+       kfree(req);
+}
+
+static void *m66592_alloc_buffer(struct usb_ep *_ep, unsigned bytes,
+                                dma_addr_t *dma, gfp_t gfp_flags)
+{
+       void *buf;
+
+       buf = kzalloc(bytes, gfp_flags);
+       if (dma)
+               *dma = virt_to_bus(buf);
+
+       return buf;
+}
+
+static void m66592_free_buffer(struct usb_ep *_ep, void *buf,
+                              dma_addr_t dma, unsigned bytes)
+{
+       kfree(buf);
+}
+
+static int m66592_queue(struct usb_ep *_ep, struct usb_request *_req,
+                       gfp_t gfp_flags)
+{
+       struct m66592_ep *ep;
+       struct m66592_request *req;
+       unsigned long flags;
+       int request = 0;
+
+       ep = container_of(_ep, struct m66592_ep, ep);
+       req = container_of(_req, struct m66592_request, req);
+
+       if (ep->m66592->gadget.speed == USB_SPEED_UNKNOWN)
+               return -ESHUTDOWN;
+
+       spin_lock_irqsave(&ep->m66592->lock, flags);
+
+       if (list_empty(&ep->queue))
+               request = 1;
+
+       list_add_tail(&req->queue, &ep->queue);
+       req->req.actual = 0;
+       req->req.status = -EINPROGRESS;
+
+       if (ep->desc == 0)      /* control */
+               start_ep0(ep, req);
+       else {
+               if (request && !ep->busy)
+                       start_packet(ep, req);
+       }
+
+       spin_unlock_irqrestore(&ep->m66592->lock, flags);
+
+       return 0;
+}
+
+static int m66592_dequeue(struct usb_ep *_ep, struct usb_request *_req)
+{
+       struct m66592_ep *ep;
+       struct m66592_request *req;
+       unsigned long flags;
+
+       ep = container_of(_ep, struct m66592_ep, ep);
+       req = container_of(_req, struct m66592_request, req);
+
+       spin_lock_irqsave(&ep->m66592->lock, flags);
+       if (!list_empty(&ep->queue))
+               transfer_complete(ep, req, -ECONNRESET);
+       spin_unlock_irqrestore(&ep->m66592->lock, flags);
+
+       return 0;
+}
+
+static int m66592_set_halt(struct usb_ep *_ep, int value)
+{
+       struct m66592_ep *ep;
+       struct m66592_request *req;
+       unsigned long flags;
+       int ret = 0;
+
+       ep = container_of(_ep, struct m66592_ep, ep);
+       req = list_entry(ep->queue.next, struct m66592_request, queue);
+
+       spin_lock_irqsave(&ep->m66592->lock, flags);
+       if (!list_empty(&ep->queue)) {
+               ret = -EAGAIN;
+               goto out;
+       }
+       if (value) {
+               ep->busy = 1;
+               pipe_stall(ep->m66592, ep->pipenum);
+       } else {
+               ep->busy = 0;
+               pipe_stop(ep->m66592, ep->pipenum);
+       }
+
+out:
+       spin_unlock_irqrestore(&ep->m66592->lock, flags);
+       return ret;
+}
+
+static int m66592_fifo_status(struct usb_ep *_ep)
+{
+       return -EOPNOTSUPP;
+}
+
+static void m66592_fifo_flush(struct usb_ep *_ep)
+{
+       struct m66592_ep *ep;
+       unsigned long flags;
+
+       ep = container_of(_ep, struct m66592_ep, ep);
+       spin_lock_irqsave(&ep->m66592->lock, flags);
+       if (list_empty(&ep->queue) && !ep->busy) {
+               pipe_stop(ep->m66592, ep->pipenum);
+               m66592_bclr(ep->m66592, M66592_BCLR, ep->fifoctr);
+       }
+       spin_unlock_irqrestore(&ep->m66592->lock, flags);
+}
+
+static struct usb_ep_ops m66592_ep_ops = {
+       .enable         = m66592_enable,
+       .disable        = m66592_disable,
+
+       .alloc_request  = m66592_alloc_request,
+       .free_request   = m66592_free_request,
+
+       .alloc_buffer   = m66592_alloc_buffer,
+       .free_buffer    = m66592_free_buffer,
+
+       .queue          = m66592_queue,
+       .dequeue        = m66592_dequeue,
+
+       .set_halt       = m66592_set_halt,
+       .fifo_status    = m66592_fifo_status,
+       .fifo_flush     = m66592_fifo_flush,
+};
+
+/*-------------------------------------------------------------------------*/
+static struct m66592 *the_controller;
+
+int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+{
+       struct m66592 *m66592 = the_controller;
+       int retval;
+
+       if (!driver ||
+           driver->speed != USB_SPEED_HIGH ||
+           !driver->bind ||
+           !driver->unbind ||
+           !driver->setup)
+               return -EINVAL;
+       if (!m66592)
+               return -ENODEV;
+       if (m66592->driver)
+               return -EBUSY;
+
+       /* hook up the driver */
+       driver->driver.bus = NULL;
+       m66592->driver = driver;
+       m66592->gadget.dev.driver = &driver->driver;
+
+       retval = device_add(&m66592->gadget.dev);
+       if (retval) {
+               printk(KERN_ERR "device_add error (%d)\n", retval);
+               goto error;
+       }
+
+       retval = driver->bind (&m66592->gadget);
+       if (retval) {
+               printk(KERN_ERR "bind to driver error (%d)\n", retval);
+               device_del(&m66592->gadget.dev);
+               goto error;
+       }
+
+       m66592_bset(m66592, M66592_VBSE | M66592_URST, M66592_INTENB0);
+       if (m66592_read(m66592, M66592_INTSTS0) & M66592_VBSTS) {
+               m66592_start_xclock(m66592);
+               /* start vbus sampling */
+               m66592->old_vbus = m66592_read(m66592,
+                                        M66592_INTSTS0) & M66592_VBSTS;
+               m66592->scount = M66592_MAX_SAMPLING;
+               mod_timer(&m66592->timer,
+                         jiffies + msecs_to_jiffies(50));
+       }
+
+       return 0;
+
+error:
+       m66592->driver = NULL;
+       m66592->gadget.dev.driver = NULL;
+
+       return retval;
+}
+EXPORT_SYMBOL(usb_gadget_register_driver);
+
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+{
+       struct m66592 *m66592 = the_controller;
+       unsigned long flags;
+
+       spin_lock_irqsave(&m66592->lock, flags);
+       if (m66592->gadget.speed != USB_SPEED_UNKNOWN)
+               m66592_usb_disconnect(m66592);
+       spin_unlock_irqrestore(&m66592->lock, flags);
+
+       m66592_bclr(m66592, M66592_VBSE | M66592_URST, M66592_INTENB0);
+
+       driver->unbind(&m66592->gadget);
+
+       init_controller(m66592);
+       disable_controller(m66592);
+
+       device_del(&m66592->gadget.dev);
+       m66592->driver = NULL;
+       return 0;
+}
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
+
+/*-------------------------------------------------------------------------*/
+static int m66592_get_frame(struct usb_gadget *_gadget)
+{
+       struct m66592 *m66592 = gadget_to_m66592(_gadget);
+       return m66592_read(m66592, M66592_FRMNUM) & 0x03FF;
+}
+
+static struct usb_gadget_ops m66592_gadget_ops = {
+       .get_frame              = m66592_get_frame,
+};
+
+#if defined(CONFIG_PM)
+static int m66592_suspend(struct platform_device *pdev, pm_message_t state)
+{
+       pdev->dev.power.power_state = state;
+       return 0;
+}
+
+static int m66592_resume(struct platform_device *pdev)
+{
+       pdev->dev.power.power_state = PMSG_ON;
+       return 0;
+}
+#else  /* if defined(CONFIG_PM) */
+#define m66592_suspend         NULL
+#define m66592_resume          NULL
+#endif
+
+static int __init_or_module m66592_remove(struct platform_device *pdev)
+{
+       struct m66592           *m66592 = dev_get_drvdata(&pdev->dev);
+
+       del_timer_sync(&m66592->timer);
+       iounmap(m66592->reg);
+       free_irq(platform_get_irq(pdev, 0), m66592);
+       kfree(m66592);
+       return 0;
+}
+
+#define resource_len(r) (((r)->end - (r)->start) + 1)
+static int __init m66592_probe(struct platform_device *pdev)
+{
+       struct resource *res = NULL;
+       int irq = -1;
+       void __iomem *reg = NULL;
+       struct m66592 *m66592 = NULL;
+       int ret = 0;
+       int i;
+
+       res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+                                          (char *)udc_name);
+       if (!res) {
+               ret = -ENODEV;
+               printk(KERN_ERR "platform_get_resource_byname error.\n");
+               goto clean_up;
+       }
+
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+               ret = -ENODEV;
+               printk(KERN_ERR "platform_get_irq error.\n");
+               goto clean_up;
+       }
+
+       reg = ioremap(res->start, resource_len(res));
+       if (reg == NULL) {
+               ret = -ENOMEM;
+               printk(KERN_ERR "ioremap error.\n");
+               goto clean_up;
+       }
+
+       /* initialize ucd */
+       m66592 = kzalloc(sizeof(struct m66592), GFP_KERNEL);
+       if (m66592 == NULL) {
+               printk(KERN_ERR "kzalloc error\n");
+               goto clean_up;
+       }
+
+       spin_lock_init(&m66592->lock);
+       dev_set_drvdata(&pdev->dev, m66592);
+
+       m66592->gadget.ops = &m66592_gadget_ops;
+       device_initialize(&m66592->gadget.dev);
+       strcpy(m66592->gadget.dev.bus_id, "gadget");
+       m66592->gadget.is_dualspeed = 1;
+       m66592->gadget.dev.parent = &pdev->dev;
+       m66592->gadget.dev.dma_mask = pdev->dev.dma_mask;
+       m66592->gadget.dev.release = pdev->dev.release;
+       m66592->gadget.name = udc_name;
+
+       init_timer(&m66592->timer);
+       m66592->timer.function = m66592_timer;
+       m66592->timer.data = (unsigned long)m66592;
+       m66592->reg = reg;
+
+       m66592->bi_bufnum = M66592_BASE_BUFNUM;
+
+       ret = request_irq(irq, m66592_irq, IRQF_DISABLED | IRQF_SHARED,
+                         udc_name, m66592);
+       if (ret < 0) {
+               printk(KERN_ERR "request_irq error (%d)\n", ret);
+               goto clean_up;
+       }
+
+       INIT_LIST_HEAD(&m66592->gadget.ep_list);
+       m66592->gadget.ep0 = &m66592->ep[0].ep;
+       INIT_LIST_HEAD(&m66592->gadget.ep0->ep_list);
+       for (i = 0; i < M66592_MAX_NUM_PIPE; i++) {
+               struct m66592_ep *ep = &m66592->ep[i];
+
+               if (i != 0) {
+                       INIT_LIST_HEAD(&m66592->ep[i].ep.ep_list);
+                       list_add_tail(&m66592->ep[i].ep.ep_list,
+                                     &m66592->gadget.ep_list);
+               }
+               ep->m66592 = m66592;
+               INIT_LIST_HEAD(&ep->queue);
+               ep->ep.name = m66592_ep_name[i];
+               ep->ep.ops = &m66592_ep_ops;
+               ep->ep.maxpacket = 512;
+       }
+       m66592->ep[0].ep.maxpacket = 64;
+       m66592->ep[0].pipenum = 0;
+       m66592->ep[0].fifoaddr = M66592_CFIFO;
+       m66592->ep[0].fifosel = M66592_CFIFOSEL;
+       m66592->ep[0].fifoctr = M66592_CFIFOCTR;
+       m66592->ep[0].fifotrn = 0;
+       m66592->ep[0].pipectr = get_pipectr_addr(0);
+       m66592->pipenum2ep[0] = &m66592->ep[0];
+       m66592->epaddr2ep[0] = &m66592->ep[0];
+
+       the_controller = m66592;
+
+       m66592->ep0_req = m66592_alloc_request(&m66592->ep[0].ep, GFP_KERNEL);
+       if (m66592->ep0_req == NULL)
+               goto clean_up;
+       m66592->ep0_buf = m66592_alloc_buffer(&m66592->ep[0].ep, 2, NULL,
+                                             GFP_KERNEL);
+       if (m66592->ep0_buf == NULL)
+               goto clean_up;
+
+       init_controller(m66592);
+
+       printk("driver %s, %s\n", udc_name, DRIVER_VERSION);
+       return 0;
+
+clean_up:
+       if (m66592) {
+               if (m66592->ep0_req)
+                       m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req);
+               kfree(m66592);
+       }
+       if (reg)
+               iounmap(reg);
+
+       return ret;
+}
+
+/*-------------------------------------------------------------------------*/
+static struct platform_driver m66592_driver = {
+       .probe =        m66592_probe,
+       .remove =       m66592_remove,
+       .suspend =      m66592_suspend,
+       .resume =       m66592_resume,
+       .driver         = {
+               .name = (char *) udc_name,
+       },
+};
+
+static int __init m66592_udc_init(void)
+{
+       return platform_driver_register(&m66592_driver);
+}
+module_init(m66592_udc_init);
+
+static void __exit m66592_udc_cleanup(void)
+{
+       platform_driver_unregister(&m66592_driver);
+}
+module_exit(m66592_udc_cleanup);
+
diff --git a/drivers/usb/gadget/m66592-udc.h b/drivers/usb/gadget/m66592-udc.h
new file mode 100644 (file)
index 0000000..26b54f8
--- /dev/null
@@ -0,0 +1,577 @@
+/*
+ * M66592 UDC (USB gadget)
+ *
+ * Copyright (C) 2006-2007 Renesas Solutions Corp.
+ *
+ * Author : Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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 __M66592_UDC_H__
+#define __M66592_UDC_H__
+
+#define M66592_SYSCFG          0x00
+#define        M66592_XTAL             0xC000  /* b15-14: Crystal selection */
+#define          M66592_XTAL48          0x8000           /* 48MHz */
+#define   M66592_XTAL24                 0x4000           /* 24MHz */
+#define          M66592_XTAL12          0x0000           /* 12MHz */
+#define        M66592_XCKE             0x2000  /* b13: External clock enable */
+#define        M66592_RCKE             0x1000  /* b12: Register clock enable */
+#define        M66592_PLLC             0x0800  /* b11: PLL control */
+#define        M66592_SCKE             0x0400  /* b10: USB clock enable */
+#define        M66592_ATCKM            0x0100  /* b8: Automatic supply functional enable */
+#define        M66592_HSE              0x0080  /* b7: Hi-speed enable */
+#define        M66592_DCFM             0x0040  /* b6: Controller function select  */
+#define        M66592_DMRPD            0x0020  /* b5: D- pull down control */
+#define        M66592_DPRPU            0x0010  /* b4: D+ pull up control */
+#define        M66592_FSRPC            0x0004  /* b2: Full-speed receiver enable */
+#define        M66592_PCUT             0x0002  /* b1: Low power sleep enable */
+#define        M66592_USBE             0x0001  /* b0: USB module operation enable */
+
+#define M66592_SYSSTS          0x02
+#define        M66592_LNST             0x0003  /* b1-0: D+, D- line status */
+#define          M66592_SE1             0x0003           /* SE1 */
+#define          M66592_KSTS            0x0002           /* K State */
+#define          M66592_JSTS            0x0001           /* J State */
+#define          M66592_SE0             0x0000           /* SE0 */
+
+#define M66592_DVSTCTR         0x04
+#define        M66592_WKUP             0x0100  /* b8: Remote wakeup */
+#define        M66592_RWUPE            0x0080  /* b7: Remote wakeup sense */
+#define        M66592_USBRST           0x0040  /* b6: USB reset enable */
+#define        M66592_RESUME           0x0020  /* b5: Resume enable */
+#define        M66592_UACT             0x0010  /* b4: USB bus enable */
+#define        M66592_RHST             0x0003  /* b1-0: Reset handshake status */
+#define          M66592_HSMODE          0x0003           /* Hi-Speed mode */
+#define          M66592_FSMODE          0x0002           /* Full-Speed mode */
+#define          M66592_HSPROC          0x0001           /* HS handshake is processing */
+
+#define M66592_TESTMODE                0x06
+#define        M66592_UTST             0x000F  /* b4-0: Test select */
+#define          M66592_H_TST_PACKET    0x000C           /* HOST TEST Packet */
+#define          M66592_H_TST_SE0_NAK   0x000B           /* HOST TEST SE0 NAK */
+#define          M66592_H_TST_K         0x000A           /* HOST TEST K */
+#define          M66592_H_TST_J         0x0009           /* HOST TEST J */
+#define          M66592_H_TST_NORMAL    0x0000           /* HOST Normal Mode */
+#define          M66592_P_TST_PACKET    0x0004           /* PERI TEST Packet */
+#define          M66592_P_TST_SE0_NAK   0x0003           /* PERI TEST SE0 NAK */
+#define          M66592_P_TST_K         0x0002           /* PERI TEST K */
+#define          M66592_P_TST_J         0x0001           /* PERI TEST J */
+#define          M66592_P_TST_NORMAL    0x0000           /* PERI Normal Mode */
+
+#define M66592_PINCFG          0x0A
+#define        M66592_LDRV             0x8000  /* b15: Drive Current Adjust */
+#define        M66592_BIGEND           0x0100  /* b8: Big endian mode */
+
+#define M66592_DMA0CFG         0x0C
+#define M66592_DMA1CFG         0x0E
+#define        M66592_DREQA            0x4000  /* b14: Dreq active select */
+#define        M66592_BURST            0x2000  /* b13: Burst mode */
+#define        M66592_DACKA            0x0400  /* b10: Dack active select */
+#define        M66592_DFORM            0x0380  /* b9-7: DMA mode select */
+#define          M66592_CPU_ADR_RD_WR   0x0000           /* Address + RD/WR mode (CPU bus) */
+#define          M66592_CPU_DACK_RD_WR  0x0100           /* DACK + RD/WR mode (CPU bus) */
+#define          M66592_CPU_DACK_ONLY   0x0180           /* DACK only mode (CPU bus) */
+#define          M66592_SPLIT_DACK_ONLY         0x0200           /* DACK only mode (SPLIT bus) */
+#define          M66592_SPLIT_DACK_DSTB         0x0300           /* DACK + DSTB0 mode (SPLIT bus) */
+#define        M66592_DENDA            0x0040  /* b6: Dend active select */
+#define        M66592_PKTM             0x0020  /* b5: Packet mode */
+#define        M66592_DENDE            0x0010  /* b4: Dend enable */
+#define        M66592_OBUS             0x0004  /* b2: OUTbus mode */
+
+#define M66592_CFIFO           0x10
+#define M66592_D0FIFO          0x14
+#define M66592_D1FIFO          0x18
+
+#define M66592_CFIFOSEL                0x1E
+#define M66592_D0FIFOSEL       0x24
+#define M66592_D1FIFOSEL       0x2A
+#define        M66592_RCNT             0x8000  /* b15: Read count mode */
+#define        M66592_REW              0x4000  /* b14: Buffer rewind */
+#define        M66592_DCLRM            0x2000  /* b13: DMA buffer clear mode */
+#define        M66592_DREQE            0x1000  /* b12: DREQ output enable */
+#define        M66592_MBW              0x0400  /* b10: Maximum bit width for FIFO access */
+#define          M66592_MBW_8           0x0000   /*  8bit */
+#define          M66592_MBW_16          0x0400           /* 16bit */
+#define        M66592_TRENB            0x0200  /* b9: Transaction counter enable */
+#define        M66592_TRCLR            0x0100  /* b8: Transaction counter clear */
+#define        M66592_DEZPM            0x0080  /* b7: Zero-length packet additional mode */
+#define        M66592_ISEL             0x0020  /* b5: DCP FIFO port direction select */
+#define        M66592_CURPIPE          0x0007  /* b2-0: PIPE select */
+
+#define M66592_CFIFOCTR                0x20
+#define M66592_D0FIFOCTR       0x26
+#define M66592_D1FIFOCTR       0x2c
+#define        M66592_BVAL             0x8000  /* b15: Buffer valid flag */
+#define        M66592_BCLR             0x4000  /* b14: Buffer clear */
+#define        M66592_FRDY             0x2000  /* b13: FIFO ready */
+#define        M66592_DTLN             0x0FFF  /* b11-0: FIFO received data length */
+
+#define M66592_CFIFOSIE                0x22
+#define        M66592_TGL              0x8000  /* b15: Buffer toggle */
+#define        M66592_SCLR             0x4000  /* b14: Buffer clear */
+#define        M66592_SBUSY            0x2000  /* b13: SIE_FIFO busy */
+
+#define M66592_D0FIFOTRN       0x28
+#define M66592_D1FIFOTRN       0x2E
+#define        M66592_TRNCNT           0xFFFF  /* b15-0: Transaction counter */
+
+#define M66592_INTENB0 0x30
+#define        M66592_VBSE     0x8000  /* b15: VBUS interrupt */
+#define        M66592_RSME     0x4000  /* b14: Resume interrupt */
+#define        M66592_SOFE     0x2000  /* b13: Frame update interrupt */
+#define        M66592_DVSE     0x1000  /* b12: Device state transition interrupt */
+#define        M66592_CTRE     0x0800  /* b11: Control transfer stage transition interrupt */
+#define        M66592_BEMPE    0x0400  /* b10: Buffer empty interrupt */
+#define        M66592_NRDYE    0x0200  /* b9: Buffer not ready interrupt */
+#define        M66592_BRDYE    0x0100  /* b8: Buffer ready interrupt */
+#define        M66592_URST     0x0080  /* b7: USB reset detected interrupt */
+#define        M66592_SADR     0x0040  /* b6: Set address executed interrupt */
+#define        M66592_SCFG     0x0020  /* b5: Set configuration executed interrupt */
+#define        M66592_SUSP     0x0010  /* b4: Suspend detected interrupt */
+#define        M66592_WDST     0x0008  /* b3: Control write data stage completed interrupt */
+#define        M66592_RDST     0x0004  /* b2: Control read data stage completed interrupt */
+#define        M66592_CMPL     0x0002  /* b1: Control transfer complete interrupt */
+#define        M66592_SERR     0x0001  /* b0: Sequence error interrupt */
+
+#define M66592_INTENB1 0x32
+#define        M66592_BCHGE    0x4000  /* b14: USB us chenge interrupt */
+#define        M66592_DTCHE    0x1000  /* b12: Detach sense interrupt */
+#define        M66592_SIGNE    0x0020  /* b5: SETUP IGNORE interrupt */
+#define        M66592_SACKE    0x0010  /* b4: SETUP ACK interrupt */
+#define        M66592_BRDYM    0x0004  /* b2: BRDY clear timing */
+#define        M66592_INTL     0x0002  /* b1: Interrupt sense select */
+#define        M66592_PCSE     0x0001  /* b0: PCUT enable by CS assert */
+
+#define M66592_BRDYENB         0x36
+#define M66592_BRDYSTS         0x46
+#define        M66592_BRDY7            0x0080  /* b7: PIPE7 */
+#define        M66592_BRDY6            0x0040  /* b6: PIPE6 */
+#define        M66592_BRDY5            0x0020  /* b5: PIPE5 */
+#define        M66592_BRDY4            0x0010  /* b4: PIPE4 */
+#define        M66592_BRDY3            0x0008  /* b3: PIPE3 */
+#define        M66592_BRDY2            0x0004  /* b2: PIPE2 */
+#define        M66592_BRDY1            0x0002  /* b1: PIPE1 */
+#define        M66592_BRDY0            0x0001  /* b1: PIPE0 */
+
+#define M66592_NRDYENB         0x38
+#define M66592_NRDYSTS         0x48
+#define        M66592_NRDY7            0x0080  /* b7: PIPE7 */
+#define        M66592_NRDY6            0x0040  /* b6: PIPE6 */
+#define        M66592_NRDY5            0x0020  /* b5: PIPE5 */
+#define        M66592_NRDY4            0x0010  /* b4: PIPE4 */
+#define        M66592_NRDY3            0x0008  /* b3: PIPE3 */
+#define        M66592_NRDY2            0x0004  /* b2: PIPE2 */
+#define        M66592_NRDY1            0x0002  /* b1: PIPE1 */
+#define        M66592_NRDY0            0x0001  /* b1: PIPE0 */
+
+#define M66592_BEMPENB         0x3A
+#define M66592_BEMPSTS         0x4A
+#define        M66592_BEMP7            0x0080  /* b7: PIPE7 */
+#define        M66592_BEMP6            0x0040  /* b6: PIPE6 */
+#define        M66592_BEMP5            0x0020  /* b5: PIPE5 */
+#define        M66592_BEMP4            0x0010  /* b4: PIPE4 */
+#define        M66592_BEMP3            0x0008  /* b3: PIPE3 */
+#define        M66592_BEMP2            0x0004  /* b2: PIPE2 */
+#define        M66592_BEMP1            0x0002  /* b1: PIPE1 */
+#define        M66592_BEMP0            0x0001  /* b0: PIPE0 */
+
+#define M66592_SOFCFG          0x3C
+#define        M66592_SOFM             0x000C  /* b3-2: SOF palse mode */
+#define          M66592_SOF_125US       0x0008           /* SOF OUT 125us uFrame Signal */
+#define          M66592_SOF_1MS         0x0004           /* SOF OUT 1ms Frame Signal */
+#define          M66592_SOF_DISABLE     0x0000           /* SOF OUT Disable */
+
+#define M66592_INTSTS0         0x40
+#define        M66592_VBINT            0x8000  /* b15: VBUS interrupt */
+#define        M66592_RESM             0x4000  /* b14: Resume interrupt */
+#define        M66592_SOFR             0x2000  /* b13: SOF frame update interrupt */
+#define        M66592_DVST             0x1000  /* b12: Device state transition interrupt */
+#define        M66592_CTRT             0x0800  /* b11: Control transfer stage transition interrupt */
+#define        M66592_BEMP             0x0400  /* b10: Buffer empty interrupt */
+#define        M66592_NRDY             0x0200  /* b9: Buffer not ready interrupt */
+#define        M66592_BRDY             0x0100  /* b8: Buffer ready interrupt */
+#define        M66592_VBSTS            0x0080  /* b7: VBUS input port */
+#define        M66592_DVSQ             0x0070  /* b6-4: Device state */
+#define          M66592_DS_SPD_CNFG     0x0070           /* Suspend Configured */
+#define          M66592_DS_SPD_ADDR     0x0060           /* Suspend Address */
+#define          M66592_DS_SPD_DFLT     0x0050           /* Suspend Default */
+#define          M66592_DS_SPD_POWR     0x0040           /* Suspend Powered */
+#define          M66592_DS_SUSP         0x0040           /* Suspend */
+#define          M66592_DS_CNFG         0x0030           /* Configured */
+#define          M66592_DS_ADDS         0x0020           /* Address */
+#define          M66592_DS_DFLT         0x0010           /* Default */
+#define          M66592_DS_POWR         0x0000           /* Powered */
+#define        M66592_DVSQS            0x0030  /* b5-4: Device state */
+#define        M66592_VALID            0x0008  /* b3: Setup packet detected flag */
+#define        M66592_CTSQ             0x0007  /* b2-0: Control transfer stage */
+#define          M66592_CS_SQER         0x0006           /* Sequence error */
+#define          M66592_CS_WRND         0x0005           /* Control write nodata status stage */
+#define          M66592_CS_WRSS         0x0004           /* Control write status stage */
+#define          M66592_CS_WRDS         0x0003           /* Control write data stage */
+#define          M66592_CS_RDSS         0x0002           /* Control read status stage */
+#define          M66592_CS_RDDS         0x0001           /* Control read data stage */
+#define          M66592_CS_IDST         0x0000           /* Idle or setup stage */
+
+#define M66592_INTSTS1         0x42
+#define        M66592_BCHG             0x4000  /* b14: USB bus chenge interrupt */
+#define        M66592_DTCH             0x1000  /* b12: Detach sense interrupt */
+#define        M66592_SIGN             0x0020  /* b5: SETUP IGNORE interrupt */
+#define        M66592_SACK             0x0010  /* b4: SETUP ACK interrupt */
+
+#define M66592_FRMNUM          0x4C
+#define        M66592_OVRN             0x8000  /* b15: Overrun error */
+#define        M66592_CRCE             0x4000  /* b14: Received data error */
+#define        M66592_SOFRM            0x0800  /* b11: SOF output mode */
+#define        M66592_FRNM             0x07FF  /* b10-0: Frame number */
+
+#define M66592_UFRMNUM         0x4E
+#define        M66592_UFRNM            0x0007  /* b2-0: Micro frame number */
+
+#define M66592_RECOVER         0x50
+#define        M66592_STSRECOV         0x0700  /* Status recovery */
+#define          M66592_STSR_HI         0x0400           /* FULL(0) or HI(1) Speed */
+#define          M66592_STSR_DEFAULT    0x0100           /* Default state */
+#define          M66592_STSR_ADDRESS    0x0200           /* Address state */
+#define          M66592_STSR_CONFIG     0x0300           /* Configured state */
+#define        M66592_USBADDR          0x007F  /* b6-0: USB address */
+
+#define M66592_USBREQ                  0x54
+#define        M66592_bRequest                 0xFF00  /* b15-8: bRequest */
+#define          M66592_GET_STATUS              0x0000
+#define          M66592_CLEAR_FEATURE           0x0100
+#define          M66592_ReqRESERVED             0x0200
+#define          M66592_SET_FEATURE             0x0300
+#define          M66592_ReqRESERVED1            0x0400
+#define          M66592_SET_ADDRESS             0x0500
+#define          M66592_GET_DESCRIPTOR          0x0600
+#define          M66592_SET_DESCRIPTOR          0x0700
+#define          M66592_GET_CONFIGURATION       0x0800
+#define          M66592_SET_CONFIGURATION       0x0900
+#define          M66592_GET_INTERFACE           0x0A00
+#define          M66592_SET_INTERFACE           0x0B00
+#define          M66592_SYNCH_FRAME             0x0C00
+#define        M66592_bmRequestType            0x00FF  /* b7-0: bmRequestType */
+#define        M66592_bmRequestTypeDir         0x0080  /* b7  : Data transfer direction */
+#define          M66592_HOST_TO_DEVICE          0x0000
+#define          M66592_DEVICE_TO_HOST          0x0080
+#define        M66592_bmRequestTypeType        0x0060  /* b6-5: Type */
+#define          M66592_STANDARD                0x0000
+#define          M66592_CLASS                   0x0020
+#define          M66592_VENDOR                  0x0040
+#define        M66592_bmRequestTypeRecip       0x001F  /* b4-0: Recipient */
+#define          M66592_DEVICE                  0x0000
+#define          M66592_INTERFACE               0x0001
+#define          M66592_ENDPOINT                0x0002
+
+#define M66592_USBVAL                          0x56
+#define        M66592_wValue                           0xFFFF  /* b15-0: wValue */
+/* Standard Feature Selector */
+#define          M66592_ENDPOINT_HALT                  0x0000
+#define          M66592_DEVICE_REMOTE_WAKEUP           0x0001
+#define          M66592_TEST_MODE                      0x0002
+/* Descriptor Types */
+#define        M66592_DT_TYPE                          0xFF00
+#define        M66592_GET_DT_TYPE(v)                   (((v) & DT_TYPE) >> 8)
+#define          M66592_DT_DEVICE                      0x01
+#define          M66592_DT_CONFIGURATION               0x02
+#define          M66592_DT_STRING                      0x03
+#define          M66592_DT_INTERFACE                   0x04
+#define          M66592_DT_ENDPOINT                    0x05
+#define          M66592_DT_DEVICE_QUALIFIER            0x06
+#define          M66592_DT_OTHER_SPEED_CONFIGURATION   0x07
+#define          M66592_DT_INTERFACE_POWER             0x08
+#define        M66592_DT_INDEX                         0x00FF
+#define        M66592_CONF_NUM                         0x00FF
+#define        M66592_ALT_SET                          0x00FF
+
+#define M66592_USBINDEX                        0x58
+#define        M66592_wIndex                   0xFFFF  /* b15-0: wIndex */
+#define        M66592_TEST_SELECT              0xFF00  /* b15-b8: Test Mode Selectors */
+#define          M66592_TEST_J                  0x0100           /* Test_J */
+#define          M66592_TEST_K                  0x0200           /* Test_K */
+#define          M66592_TEST_SE0_NAK            0x0300           /* Test_SE0_NAK */
+#define          M66592_TEST_PACKET             0x0400           /* Test_Packet */
+#define          M66592_TEST_FORCE_ENABLE       0x0500           /* Test_Force_Enable */
+#define          M66592_TEST_STSelectors        0x0600           /* Standard test selectors */
+#define          M66592_TEST_Reserved           0x4000           /* Reserved */
+#define          M66592_TEST_VSTModes           0xC000           /* Vendor-specific test modes */
+#define        M66592_EP_DIR                   0x0080  /* b7: Endpoint Direction */
+#define          M66592_EP_DIR_IN               0x0080
+#define          M66592_EP_DIR_OUT              0x0000
+
+#define M66592_USBLENG         0x5A
+#define        M66592_wLength          0xFFFF  /* b15-0: wLength */
+
+#define M66592_DCPCFG          0x5C
+#define        M66592_CNTMD            0x0100  /* b8: Continuous transfer mode select */
+#define        M66592_DIR              0x0010  /* b4: Control transfer DIR select */
+
+#define M66592_DCPMAXP         0x5E
+#define        M66592_DEVSEL           0xC000  /* b15-14: Device address select */
+#define          M66592_DEVICE_0        0x0000           /* Device address 0 */
+#define          M66592_DEVICE_1        0x4000           /* Device address 1 */
+#define          M66592_DEVICE_2        0x8000           /* Device address 2 */
+#define          M66592_DEVICE_3        0xC000           /* Device address 3 */
+#define        M66592_MAXP             0x007F  /* b6-0: Maxpacket size of default control pipe */
+
+#define M66592_DCPCTR          0x60
+#define        M66592_BSTS             0x8000  /* b15: Buffer status */
+#define        M66592_SUREQ            0x4000  /* b14: Send USB request  */
+#define        M66592_SQCLR            0x0100  /* b8: Sequence toggle bit clear */
+#define        M66592_SQSET            0x0080  /* b7: Sequence toggle bit set */
+#define        M66592_SQMON            0x0040  /* b6: Sequence toggle bit monitor */
+#define        M66592_CCPL             0x0004  /* b2: Enable control transfer complete */
+#define        M66592_PID              0x0003  /* b1-0: Response PID */
+#define          M66592_PID_STALL       0x0002           /* STALL */
+#define          M66592_PID_BUF         0x0001           /* BUF */
+#define          M66592_PID_NAK         0x0000           /* NAK */
+
+#define M66592_PIPESEL         0x64
+#define        M66592_PIPENM           0x0007  /* b2-0: Pipe select */
+#define          M66592_PIPE0           0x0000           /* PIPE 0 */
+#define          M66592_PIPE1           0x0001           /* PIPE 1 */
+#define          M66592_PIPE2           0x0002           /* PIPE 2 */
+#define          M66592_PIPE3           0x0003           /* PIPE 3 */
+#define          M66592_PIPE4           0x0004           /* PIPE 4 */
+#define          M66592_PIPE5           0x0005           /* PIPE 5 */
+#define          M66592_PIPE6           0x0006           /* PIPE 6 */
+#define          M66592_PIPE7           0x0007           /* PIPE 7 */
+
+#define M66592_PIPECFG         0x66
+#define        M66592_TYP              0xC000  /* b15-14: Transfer type */
+#define          M66592_ISO             0xC000           /* Isochronous */
+#define          M66592_INT             0x8000           /* Interrupt */
+#define          M66592_BULK            0x4000           /* Bulk */
+#define        M66592_BFRE             0x0400  /* b10: Buffer ready interrupt mode select */
+#define        M66592_DBLB             0x0200  /* b9: Double buffer mode select */
+#define        M66592_CNTMD            0x0100  /* b8: Continuous transfer mode select */
+#define        M66592_SHTNAK           0x0080  /* b7: Transfer end NAK */
+#define        M66592_DIR              0x0010  /* b4: Transfer direction select */
+#define          M66592_DIR_H_OUT       0x0010           /* HOST OUT */
+#define          M66592_DIR_P_IN        0x0010           /* PERI IN */
+#define          M66592_DIR_H_IN        0x0000           /* HOST IN */
+#define          M66592_DIR_P_OUT       0x0000           /* PERI OUT */
+#define        M66592_EPNUM            0x000F  /* b3-0: Eendpoint number select */
+#define          M66592_EP1             0x0001
+#define          M66592_EP2             0x0002
+#define          M66592_EP3             0x0003
+#define          M66592_EP4             0x0004
+#define          M66592_EP5             0x0005
+#define          M66592_EP6             0x0006
+#define          M66592_EP7             0x0007
+#define          M66592_EP8             0x0008
+#define          M66592_EP9             0x0009
+#define          M66592_EP10            0x000A
+#define          M66592_EP11            0x000B
+#define          M66592_EP12            0x000C
+#define          M66592_EP13            0x000D
+#define          M66592_EP14            0x000E
+#define          M66592_EP15            0x000F
+
+#define M66592_PIPEBUF         0x68
+#define        M66592_BUFSIZE          0x7C00  /* b14-10: Pipe buffer size */
+#define        M66592_BUF_SIZE(x)      ((((x) / 64) - 1) << 10)
+#define        M66592_BUFNMB           0x00FF  /* b7-0: Pipe buffer number */
+
+#define M66592_PIPEMAXP                0x6A
+#define        M66592_MXPS             0x07FF  /* b10-0: Maxpacket size */
+
+#define M66592_PIPEPERI                0x6C
+#define        M66592_IFIS             0x1000  /* b12: Isochronous in-buffer flush mode select */
+#define        M66592_IITV             0x0007  /* b2-0: Isochronous interval */
+
+#define M66592_PIPE1CTR                0x70
+#define M66592_PIPE2CTR                0x72
+#define M66592_PIPE3CTR                0x74
+#define M66592_PIPE4CTR                0x76
+#define M66592_PIPE5CTR                0x78
+#define M66592_PIPE6CTR                0x7A
+#define M66592_PIPE7CTR                0x7C
+#define        M66592_BSTS             0x8000  /* b15: Buffer status */
+#define        M66592_INBUFM           0x4000  /* b14: IN buffer monitor (Only for PIPE1 to 5) */
+#define        M66592_ACLRM            0x0200  /* b9: Out buffer auto clear mode */
+#define        M66592_SQCLR            0x0100  /* b8: Sequence toggle bit clear */
+#define        M66592_SQSET            0x0080  /* b7: Sequence toggle bit set */
+#define        M66592_SQMON            0x0040  /* b6: Sequence toggle bit monitor */
+#define        M66592_PID              0x0003  /* b1-0: Response PID */
+
+#define M66592_INVALID_REG     0x7E
+
+
+#define __iomem
+
+#define get_pipectr_addr(pipenum)      (M66592_PIPE1CTR + (pipenum - 1) * 2)
+
+#define M66592_MAX_SAMPLING    10
+
+#define M66592_MAX_NUM_PIPE    8
+#define M66592_MAX_NUM_BULK    3
+#define M66592_MAX_NUM_ISOC    2
+#define M66592_MAX_NUM_INT     2
+
+#define M66592_BASE_PIPENUM_BULK       3
+#define M66592_BASE_PIPENUM_ISOC       1
+#define M66592_BASE_PIPENUM_INT                6
+
+#define M66592_BASE_BUFNUM     6
+#define M66592_MAX_BUFNUM      0x4F
+
+struct m66592_pipe_info {
+       u16     pipe;
+       u16     epnum;
+       u16     maxpacket;
+       u16     type;
+       u16     interval;
+       u16     dir_in;
+};
+
+struct m66592_request {
+       struct usb_request      req;
+       struct list_head        queue;
+};
+
+struct m66592_ep {
+       struct usb_ep           ep;
+       struct m66592           *m66592;
+
+       struct list_head        queue;
+       unsigned                busy:1;
+       unsigned                internal_ccpl:1;        /* use only control */
+
+       /* this member can able to after m66592_enable */
+       unsigned                use_dma:1;
+       u16                     pipenum;
+       u16                     type;
+       const struct usb_endpoint_descriptor    *desc;
+       /* register address */
+       unsigned long           fifoaddr;
+       unsigned long           fifosel;
+       unsigned long           fifoctr;
+       unsigned long           fifotrn;
+       unsigned long           pipectr;
+};
+
+struct m66592 {
+       spinlock_t              lock;
+       void __iomem            *reg;
+
+       struct usb_gadget               gadget;
+       struct usb_gadget_driver        *driver;
+
+       struct m66592_ep        ep[M66592_MAX_NUM_PIPE];
+       struct m66592_ep        *pipenum2ep[M66592_MAX_NUM_PIPE];
+       struct m66592_ep        *epaddr2ep[16];
+
+       struct usb_request      *ep0_req;       /* for internal request */
+       u16                     *ep0_buf;       /* for internal request */
+
+       struct timer_list       timer;
+
+       u16                     old_vbus;
+       int                     scount;
+
+       int                     old_dvsq;
+
+       /* pipe config */
+       int bulk;
+       int interrupt;
+       int isochronous;
+       int num_dma;
+       int bi_bufnum;  /* bulk and isochronous's bufnum */
+};
+
+#define gadget_to_m66592(_gadget) container_of(_gadget, struct m66592, gadget)
+#define m66592_to_gadget(m66592) (&m66592->gadget)
+
+#define is_bulk_pipe(pipenum)  \
+       ((pipenum >= M66592_BASE_PIPENUM_BULK) && \
+        (pipenum < (M66592_BASE_PIPENUM_BULK + M66592_MAX_NUM_BULK)))
+#define is_interrupt_pipe(pipenum)     \
+       ((pipenum >= M66592_BASE_PIPENUM_INT) && \
+        (pipenum < (M66592_BASE_PIPENUM_INT + M66592_MAX_NUM_INT)))
+#define is_isoc_pipe(pipenum)  \
+       ((pipenum >= M66592_BASE_PIPENUM_ISOC) && \
+        (pipenum < (M66592_BASE_PIPENUM_ISOC + M66592_MAX_NUM_ISOC)))
+
+#define enable_irq_ready(m66592, pipenum)      \
+       enable_pipe_irq(m66592, pipenum, M66592_BRDYENB)
+#define disable_irq_ready(m66592, pipenum)     \
+       disable_pipe_irq(m66592, pipenum, M66592_BRDYENB)
+#define enable_irq_empty(m66592, pipenum)      \
+       enable_pipe_irq(m66592, pipenum, M66592_BEMPENB)
+#define disable_irq_empty(m66592, pipenum)     \
+       disable_pipe_irq(m66592, pipenum, M66592_BEMPENB)
+#define enable_irq_nrdy(m66592, pipenum)       \
+       enable_pipe_irq(m66592, pipenum, M66592_NRDYENB)
+#define disable_irq_nrdy(m66592, pipenum)      \
+       disable_pipe_irq(m66592, pipenum, M66592_NRDYENB)
+
+/*-------------------------------------------------------------------------*/
+static inline u16 m66592_read(struct m66592 *m66592, unsigned long offset)
+{
+       return inw((unsigned long)m66592->reg + offset);
+}
+
+static inline void m66592_read_fifo(struct m66592 *m66592,
+                                   unsigned long offset,
+                                   void *buf, unsigned long len)
+{
+       unsigned long fifoaddr = (unsigned long)m66592->reg + offset;
+
+       len = (len + 1) / 2;
+       insw(fifoaddr, buf, len);
+}
+
+static inline void m66592_write(struct m66592 *m66592, u16 val,
+                               unsigned long offset)
+{
+       outw(val, (unsigned long)m66592->reg + offset);
+}
+
+static inline void m66592_write_fifo(struct m66592 *m66592,
+                                    unsigned long offset,
+                                    void *buf, unsigned long len)
+{
+       unsigned long fifoaddr = (unsigned long)m66592->reg + offset;
+       unsigned long odd = len & 0x0001;
+
+       len = len / 2;
+       outsw(fifoaddr, buf, len);
+       if (odd) {
+               unsigned char *p = buf + len*2;
+               outb(*p, fifoaddr);
+       }
+}
+
+static inline void m66592_mdfy(struct m66592 *m66592, u16 val, u16 pat,
+                              unsigned long offset)
+{
+       u16 tmp;
+       tmp = m66592_read(m66592, offset);
+       tmp = tmp & (~pat);
+       tmp = tmp | val;
+       m66592_write(m66592, tmp, offset);
+}
+
+#define m66592_bclr(m66592, val, offset)       \
+                       m66592_mdfy(m66592, 0, val, offset)
+#define m66592_bset(m66592, val, offset)       \
+                       m66592_mdfy(m66592, val, 0, offset)
+
+#endif /* ifndef __M66592_UDC_H__ */
+
+
index d975ecf18e00537bb6a67895f04f4a5bd00b6ee5..c3d364ecd4f8e48dbd6f3236bf2eb520f2906272 100644 (file)
@@ -450,100 +450,6 @@ net2280_free_request (struct usb_ep *_ep, struct usb_request *_req)
 
 /*-------------------------------------------------------------------------*/
 
-/*
- * dma-coherent memory allocation (for dma-capable endpoints)
- *
- * NOTE: the dma_*_coherent() API calls suck.  Most implementations are
- * (a) page-oriented, so small buffers lose big; and (b) asymmetric with
- * respect to calls with irqs disabled:  alloc is safe, free is not.
- * We currently work around (b), but not (a).
- */
-
-static void *
-net2280_alloc_buffer (
-       struct usb_ep           *_ep,
-       unsigned                bytes,
-       dma_addr_t              *dma,
-       gfp_t                   gfp_flags
-)
-{
-       void                    *retval;
-       struct net2280_ep       *ep;
-
-       ep = container_of (_ep, struct net2280_ep, ep);
-       if (!_ep)
-               return NULL;
-       *dma = DMA_ADDR_INVALID;
-
-       if (ep->dma)
-               retval = dma_alloc_coherent(&ep->dev->pdev->dev,
-                               bytes, dma, gfp_flags);
-       else
-               retval = kmalloc(bytes, gfp_flags);
-       return retval;
-}
-
-static DEFINE_SPINLOCK(buflock);
-static LIST_HEAD(buffers);
-
-struct free_record {
-       struct list_head        list;
-       struct device           *dev;
-       unsigned                bytes;
-       dma_addr_t              dma;
-};
-
-static void do_free(unsigned long ignored)
-{
-       spin_lock_irq(&buflock);
-       while (!list_empty(&buffers)) {
-               struct free_record      *buf;
-
-               buf = list_entry(buffers.next, struct free_record, list);
-               list_del(&buf->list);
-               spin_unlock_irq(&buflock);
-
-               dma_free_coherent(buf->dev, buf->bytes, buf, buf->dma);
-
-               spin_lock_irq(&buflock);
-       }
-       spin_unlock_irq(&buflock);
-}
-
-static DECLARE_TASKLET(deferred_free, do_free, 0);
-
-static void
-net2280_free_buffer (
-       struct usb_ep *_ep,
-       void *address,
-       dma_addr_t dma,
-       unsigned bytes
-) {
-       /* free memory into the right allocator */
-       if (dma != DMA_ADDR_INVALID) {
-               struct net2280_ep       *ep;
-               struct free_record      *buf = address;
-               unsigned long           flags;
-
-               ep = container_of(_ep, struct net2280_ep, ep);
-               if (!_ep)
-                       return;
-
-               ep = container_of (_ep, struct net2280_ep, ep);
-               buf->dev = &ep->dev->pdev->dev;
-               buf->bytes = bytes;
-               buf->dma = dma;
-
-               spin_lock_irqsave(&buflock, flags);
-               list_add_tail(&buf->list, &buffers);
-               tasklet_schedule(&deferred_free);
-               spin_unlock_irqrestore(&buflock, flags);
-       } else
-               kfree (address);
-}
-
-/*-------------------------------------------------------------------------*/
-
 /* load a packet into the fifo we use for usb IN transfers.
  * works for all endpoints.
  *
@@ -1392,9 +1298,6 @@ static const struct usb_ep_ops net2280_ep_ops = {
        .alloc_request  = net2280_alloc_request,
        .free_request   = net2280_free_request,
 
-       .alloc_buffer   = net2280_alloc_buffer,
-       .free_buffer    = net2280_free_buffer,
-
        .queue          = net2280_queue,
        .dequeue        = net2280_dequeue,
 
@@ -2964,7 +2867,7 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id)
                        , &dev->pci->pcimstctl);
        /* erratum 0115 shouldn't appear: Linux inits PCI_LATENCY_TIMER */
        pci_set_master (pdev);
-       pci_set_mwi (pdev);
+       pci_try_set_mwi (pdev);
 
        /* ... also flushes any posted pci writes */
        dev->chiprev = get_idx_reg (dev->regs, REG_CHIPREV) & 0xffff;
index c4975a6cf7774cc32fcd0ff3500462694b2c0f7b..9b0f0925dddf644259865cb9f54ac1a8a2c534cc 100644 (file)
@@ -296,111 +296,6 @@ omap_free_request(struct usb_ep *ep, struct usb_request *_req)
 
 /*-------------------------------------------------------------------------*/
 
-/*
- * dma-coherent memory allocation (for dma-capable endpoints)
- *
- * NOTE: the dma_*_coherent() API calls suck.  Most implementations are
- * (a) page-oriented, so small buffers lose big; and (b) asymmetric with
- * respect to calls with irqs disabled:  alloc is safe, free is not.
- * We currently work around (b), but not (a).
- */
-
-static void *
-omap_alloc_buffer(
-       struct usb_ep   *_ep,
-       unsigned        bytes,
-       dma_addr_t      *dma,
-       gfp_t           gfp_flags
-)
-{
-       void            *retval;
-       struct omap_ep  *ep;
-
-       if (!_ep)
-               return NULL;
-
-       ep = container_of(_ep, struct omap_ep, ep);
-       if (use_dma && ep->has_dma) {
-               static int      warned;
-               if (!warned && bytes < PAGE_SIZE) {
-                       dev_warn(ep->udc->gadget.dev.parent,
-                               "using dma_alloc_coherent for "
-                               "small allocations wastes memory\n");
-                       warned++;
-               }
-               return dma_alloc_coherent(ep->udc->gadget.dev.parent,
-                               bytes, dma, gfp_flags);
-       }
-
-       retval = kmalloc(bytes, gfp_flags);
-       if (retval)
-               *dma = virt_to_phys(retval);
-       return retval;
-}
-
-static DEFINE_SPINLOCK(buflock);
-static LIST_HEAD(buffers);
-
-struct free_record {
-       struct list_head        list;
-       struct device           *dev;
-       unsigned                bytes;
-       dma_addr_t              dma;
-};
-
-static void do_free(unsigned long ignored)
-{
-       spin_lock_irq(&buflock);
-       while (!list_empty(&buffers)) {
-               struct free_record      *buf;
-
-               buf = list_entry(buffers.next, struct free_record, list);
-               list_del(&buf->list);
-               spin_unlock_irq(&buflock);
-
-               dma_free_coherent(buf->dev, buf->bytes, buf, buf->dma);
-
-               spin_lock_irq(&buflock);
-       }
-       spin_unlock_irq(&buflock);
-}
-
-static DECLARE_TASKLET(deferred_free, do_free, 0);
-
-static void omap_free_buffer(
-       struct usb_ep   *_ep,
-       void            *buf,
-       dma_addr_t      dma,
-       unsigned        bytes
-)
-{
-       if (!_ep) {
-               WARN_ON(1);
-               return;
-       }
-
-       /* free memory into the right allocator */
-       if (dma != DMA_ADDR_INVALID) {
-               struct omap_ep          *ep;
-               struct free_record      *rec = buf;
-               unsigned long           flags;
-
-               ep = container_of(_ep, struct omap_ep, ep);
-
-               rec->dev = ep->udc->gadget.dev.parent;
-               rec->bytes = bytes;
-               rec->dma = dma;
-
-               spin_lock_irqsave(&buflock, flags);
-               list_add_tail(&rec->list, &buffers);
-               tasklet_schedule(&deferred_free);
-               spin_unlock_irqrestore(&buflock, flags);
-       } else
-               kfree(buf);
-}
-
-/*-------------------------------------------------------------------------*/
-
 static void
 done(struct omap_ep *ep, struct omap_req *req, int status)
 {
@@ -1271,9 +1166,6 @@ static struct usb_ep_ops omap_ep_ops = {
        .alloc_request  = omap_alloc_request,
        .free_request   = omap_free_request,
 
-       .alloc_buffer   = omap_alloc_buffer,
-       .free_buffer    = omap_free_buffer,
-
        .queue          = omap_ep_queue,
        .dequeue        = omap_ep_dequeue,
 
index 84392e835d5f12c598bec4823b9d3b352bd7b4ca..63b9521c1322018a4c494f32c0174cb190a11181 100644 (file)
@@ -24,9 +24,9 @@
  *
  */
 
-#undef DEBUG
 // #define     VERBOSE DBG_VERBOSE
 
+#include <linux/device.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/ioport.h>
 
 #include <asm/byteorder.h>
 #include <asm/dma.h>
+#include <asm/gpio.h>
 #include <asm/io.h>
 #include <asm/system.h>
 #include <asm/mach-types.h>
 #include <asm/unaligned.h>
 #include <asm/hardware.h>
-#ifdef CONFIG_ARCH_PXA
-#include <asm/arch/pxa-regs.h>
-#endif
 
 #include <linux/usb/ch9.h>
 #include <linux/usb_gadget.h>
 
-#include <asm/arch/udc.h>
+#include <asm/mach/udc_pxa2xx.h>
 
 
 /*
  * it constrains the sorts of USB configuration change events that work.
  * The errata for these chips are misleading; some "fixed" bugs from
  * pxa250 a0/a1 b0/b1/b2 sure act like they're still there.
+ *
+ * Note that the UDC hardware supports DMA (except on IXP) but that's
+ * not used here.  IN-DMA (to host) is simple enough, when the data is
+ * suitably aligned (16 bytes) ... the network stack doesn't do that,
+ * other software can.  OUT-DMA is buggy in most chip versions, as well
+ * as poorly designed (data toggle not automatic).  So this driver won't
+ * bother using DMA.  (Mostly-working IN-DMA support was available in
+ * kernels before 2.6.23, but was never enabled or well tested.)
  */
 
-#define        DRIVER_VERSION  "4-May-2005"
+#define        DRIVER_VERSION  "30-June-2007"
 #define        DRIVER_DESC     "PXA 25x USB Device Controller driver"
 
 
@@ -87,12 +93,9 @@ static const char driver_name [] = "pxa2xx_udc";
 static const char ep0name [] = "ep0";
 
 
-// #define     USE_DMA
-// #define     USE_OUT_DMA
 // #define     DISABLE_TEST_MODE
 
 #ifdef CONFIG_ARCH_IXP4XX
-#undef USE_DMA
 
 /* cpu-specific register addresses are compiled in to this code */
 #ifdef CONFIG_ARCH_PXA
@@ -104,25 +107,6 @@ static const char ep0name [] = "ep0";
 #include "pxa2xx_udc.h"
 
 
-#ifdef USE_DMA
-static int use_dma = 1;
-module_param(use_dma, bool, 0);
-MODULE_PARM_DESC (use_dma, "true to use dma");
-
-static void dma_nodesc_handler (int dmach, void *_ep);
-static void kick_dma(struct pxa2xx_ep *ep, struct pxa2xx_request *req);
-
-#ifdef USE_OUT_DMA
-#define        DMASTR " (dma support)"
-#else
-#define        DMASTR " (dma in)"
-#endif
-
-#else  /* !USE_DMA */
-#define        DMASTR " (pio only)"
-#undef USE_OUT_DMA
-#endif
-
 #ifdef CONFIG_USB_PXA2XX_SMALL
 #define SIZE_STR       " (small)"
 #else
@@ -155,7 +139,7 @@ static int is_vbus_present(void)
        struct pxa2xx_udc_mach_info             *mach = the_controller->mach;
 
        if (mach->gpio_vbus)
-               return udc_gpio_get(mach->gpio_vbus);
+               return gpio_get_value(mach->gpio_vbus);
        if (mach->udc_is_connected)
                return mach->udc_is_connected();
        return 1;
@@ -167,7 +151,7 @@ static void pullup_off(void)
        struct pxa2xx_udc_mach_info             *mach = the_controller->mach;
 
        if (mach->gpio_pullup)
-               udc_gpio_set(mach->gpio_pullup, 0);
+               gpio_set_value(mach->gpio_pullup, 0);
        else if (mach->udc_command)
                mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT);
 }
@@ -177,7 +161,7 @@ static void pullup_on(void)
        struct pxa2xx_udc_mach_info             *mach = the_controller->mach;
 
        if (mach->gpio_pullup)
-               udc_gpio_set(mach->gpio_pullup, 1);
+               gpio_set_value(mach->gpio_pullup, 1);
        else if (mach->udc_command)
                mach->udc_command(PXA2XX_UDC_CMD_CONNECT);
 }
@@ -281,9 +265,8 @@ static int pxa2xx_ep_enable (struct usb_ep *_ep,
        }
 
        ep->desc = desc;
-       ep->dma = -1;
        ep->stopped = 0;
-       ep->pio_irqs = ep->dma_irqs = 0;
+       ep->pio_irqs = 0;
        ep->ep.maxpacket = le16_to_cpu (desc->wMaxPacketSize);
 
        /* flush fifo (mostly for OUT buffers) */
@@ -291,30 +274,6 @@ static int pxa2xx_ep_enable (struct usb_ep *_ep,
 
        /* ... reset halt state too, if we could ... */
 
-#ifdef USE_DMA
-       /* for (some) bulk and ISO endpoints, try to get a DMA channel and
-        * bind it to the endpoint.  otherwise use PIO.
-        */
-       switch (ep->bmAttributes) {
-       case USB_ENDPOINT_XFER_ISOC:
-               if (le16_to_cpu(desc->wMaxPacketSize) % 32)
-                       break;
-               // fall through
-       case USB_ENDPOINT_XFER_BULK:
-               if (!use_dma || !ep->reg_drcmr)
-                       break;
-               ep->dma = pxa_request_dma ((char *)_ep->name,
-                               (le16_to_cpu (desc->wMaxPacketSize) > 64)
-                                       ? DMA_PRIO_MEDIUM /* some iso */
-                                       : DMA_PRIO_LOW,
-                               dma_nodesc_handler, ep);
-               if (ep->dma >= 0) {
-                       *ep->reg_drcmr = DRCMR_MAPVLD | ep->dma;
-                       DMSG("%s using dma%d\n", _ep->name, ep->dma);
-               }
-       }
-#endif
-
        DBG(DBG_VERBOSE, "enabled %s\n", _ep->name);
        return 0;
 }
@@ -334,14 +293,6 @@ static int pxa2xx_ep_disable (struct usb_ep *_ep)
 
        nuke (ep, -ESHUTDOWN);
 
-#ifdef USE_DMA
-       if (ep->dma >= 0) {
-               *ep->reg_drcmr = 0;
-               pxa_free_dma (ep->dma);
-               ep->dma = -1;
-       }
-#endif
-
        /* flush fifo (mostly for IN buffers) */
        pxa2xx_ep_fifo_flush (_ep);
 
@@ -390,35 +341,6 @@ pxa2xx_ep_free_request (struct usb_ep *_ep, struct usb_request *_req)
        kfree(req);
 }
 
-
-/* PXA cache needs flushing with DMA I/O (it's dma-incoherent), but there's
- * no device-affinity and the heap works perfectly well for i/o buffers.
- * It wastes much less memory than dma_alloc_coherent() would, and even
- * prevents cacheline (32 bytes wide) sharing problems.
- */
-static void *
-pxa2xx_ep_alloc_buffer(struct usb_ep *_ep, unsigned bytes,
-       dma_addr_t *dma, gfp_t gfp_flags)
-{
-       char                    *retval;
-
-       retval = kmalloc (bytes, gfp_flags & ~(__GFP_DMA|__GFP_HIGHMEM));
-       if (retval)
-#ifdef USE_DMA
-               *dma = virt_to_bus (retval);
-#else
-               *dma = (dma_addr_t)~0;
-#endif
-       return retval;
-}
-
-static void
-pxa2xx_ep_free_buffer(struct usb_ep *_ep, void *buf, dma_addr_t dma,
-               unsigned bytes)
-{
-       kfree (buf);
-}
-
 /*-------------------------------------------------------------------------*/
 
 /*
@@ -518,18 +440,8 @@ write_fifo (struct pxa2xx_ep *ep, struct pxa2xx_request *req)
                /* requests complete when all IN data is in the FIFO */
                if (is_last) {
                        done (ep, req, 0);
-                       if (list_empty(&ep->queue) || unlikely(ep->dma >= 0)) {
+                       if (list_empty(&ep->queue))
                                pio_irq_disable (ep->bEndpointAddress);
-#ifdef USE_DMA
-                               /* unaligned data and zlps couldn't use dma */
-                               if (unlikely(!list_empty(&ep->queue))) {
-                                       req = list_entry(ep->queue.next,
-                                               struct pxa2xx_request, queue);
-                                       kick_dma(ep,req);
-                                       return 0;
-                               }
-#endif
-                       }
                        return 1;
                }
 
@@ -728,182 +640,6 @@ read_ep0_fifo (struct pxa2xx_ep *ep, struct pxa2xx_request *req)
        return 0;
 }
 
-#ifdef USE_DMA
-
-#define        MAX_IN_DMA      ((DCMD_LENGTH + 1) - BULK_FIFO_SIZE)
-
-static void
-start_dma_nodesc(struct pxa2xx_ep *ep, struct pxa2xx_request *req, int is_in)
-{
-       u32     dcmd = req->req.length;
-       u32     buf = req->req.dma;
-       u32     fifo = io_v2p ((u32)ep->reg_uddr);
-
-       /* caller guarantees there's a packet or more remaining
-        *  - IN may end with a short packet (TSP set separately),
-        *  - OUT is always full length
-        */
-       buf += req->req.actual;
-       dcmd -= req->req.actual;
-       ep->dma_fixup = 0;
-
-       /* no-descriptor mode can be simple for bulk-in, iso-in, iso-out */
-       DCSR(ep->dma) = DCSR_NODESC;
-       if (is_in) {
-               DSADR(ep->dma) = buf;
-               DTADR(ep->dma) = fifo;
-               if (dcmd > MAX_IN_DMA)
-                       dcmd = MAX_IN_DMA;
-               else
-                       ep->dma_fixup = (dcmd % ep->ep.maxpacket) != 0;
-               dcmd |= DCMD_BURST32 | DCMD_WIDTH1
-                       | DCMD_FLOWTRG | DCMD_INCSRCADDR;
-       } else {
-#ifdef USE_OUT_DMA
-               DSADR(ep->dma) = fifo;
-               DTADR(ep->dma) = buf;
-               if (ep->bmAttributes != USB_ENDPOINT_XFER_ISOC)
-                       dcmd = ep->ep.maxpacket;
-               dcmd |= DCMD_BURST32 | DCMD_WIDTH1
-                       | DCMD_FLOWSRC | DCMD_INCTRGADDR;
-#endif
-       }
-       DCMD(ep->dma) = dcmd;
-       DCSR(ep->dma) = DCSR_RUN | DCSR_NODESC
-               | (unlikely(is_in)
-                       ? DCSR_STOPIRQEN        /* use dma_nodesc_handler() */
-                       : 0);                   /* use handle_ep() */
-}
-
-static void kick_dma(struct pxa2xx_ep *ep, struct pxa2xx_request *req)
-{
-       int     is_in = ep->bEndpointAddress & USB_DIR_IN;
-
-       if (is_in) {
-               /* unaligned tx buffers and zlps only work with PIO */
-               if ((req->req.dma & 0x0f) != 0
-                               || unlikely((req->req.length - req->req.actual)
-                                               == 0)) {
-                       pio_irq_enable(ep->bEndpointAddress);
-                       if ((*ep->reg_udccs & UDCCS_BI_TFS) != 0)
-                               (void) write_fifo(ep, req);
-               } else {
-                       start_dma_nodesc(ep, req, USB_DIR_IN);
-               }
-       } else {
-               if ((req->req.length - req->req.actual) < ep->ep.maxpacket) {
-                       DMSG("%s short dma read...\n", ep->ep.name);
-                       /* we're always set up for pio out */
-                       read_fifo (ep, req);
-               } else {
-                       *ep->reg_udccs = UDCCS_BO_DME
-                               | (*ep->reg_udccs & UDCCS_BO_FST);
-                       start_dma_nodesc(ep, req, USB_DIR_OUT);
-               }
-       }
-}
-
-static void cancel_dma(struct pxa2xx_ep *ep)
-{
-       struct pxa2xx_request   *req;
-       u32                     tmp;
-
-       if (DCSR(ep->dma) == 0 || list_empty(&ep->queue))
-               return;
-
-       DCSR(ep->dma) = 0;
-       while ((DCSR(ep->dma) & DCSR_STOPSTATE) == 0)
-               cpu_relax();
-
-       req = list_entry(ep->queue.next, struct pxa2xx_request, queue);
-       tmp = DCMD(ep->dma) & DCMD_LENGTH;
-       req->req.actual = req->req.length - (tmp & DCMD_LENGTH);
-
-       /* the last tx packet may be incomplete, so flush the fifo.
-        * FIXME correct req.actual if we can
-        */
-       if (ep->bEndpointAddress & USB_DIR_IN)
-               *ep->reg_udccs = UDCCS_BI_FTF;
-}
-
-/* dma channel stopped ... normal tx end (IN), or on error (IN/OUT) */
-static void dma_nodesc_handler(int dmach, void *_ep)
-{
-       struct pxa2xx_ep        *ep = _ep;
-       struct pxa2xx_request   *req;
-       u32                     tmp, completed;
-
-       local_irq_disable();
-
-       req = list_entry(ep->queue.next, struct pxa2xx_request, queue);
-
-       ep->dma_irqs++;
-       ep->dev->stats.irqs++;
-       HEX_DISPLAY(ep->dev->stats.irqs);
-
-       /* ack/clear */
-       tmp = DCSR(ep->dma);
-       DCSR(ep->dma) = tmp;
-       if ((tmp & DCSR_STOPSTATE) == 0
-                       || (DDADR(ep->dma) & DDADR_STOP) != 0) {
-               DBG(DBG_VERBOSE, "%s, dcsr %08x ddadr %08x\n",
-                       ep->ep.name, DCSR(ep->dma), DDADR(ep->dma));
-               goto done;
-       }
-       DCSR(ep->dma) = 0;      /* clear DCSR_STOPSTATE */
-
-       /* update transfer status */
-       completed = tmp & DCSR_BUSERR;
-       if (ep->bEndpointAddress & USB_DIR_IN)
-               tmp = DSADR(ep->dma);
-       else
-               tmp = DTADR(ep->dma);
-       req->req.actual = tmp - req->req.dma;
-
-       /* FIXME seems we sometimes see partial transfers... */
-
-       if (unlikely(completed != 0))
-               req->req.status = -EIO;
-       else if (req->req.actual) {
-               /* these registers have zeroes in low bits; they miscount
-                * some (end-of-transfer) short packets:  tx 14 as tx 12
-                */
-               if (ep->dma_fixup)
-                       req->req.actual = min(req->req.actual + 3,
-                                               req->req.length);
-
-               tmp = (req->req.length - req->req.actual);
-               completed = (tmp == 0);
-               if (completed && (ep->bEndpointAddress & USB_DIR_IN)) {
-
-                       /* maybe validate final short packet ... */
-                       if ((req->req.actual % ep->ep.maxpacket) != 0)
-                               *ep->reg_udccs = UDCCS_BI_TSP/*|UDCCS_BI_TPC*/;
-
-                       /* ... or zlp, using pio fallback */
-                       else if (ep->bmAttributes == USB_ENDPOINT_XFER_BULK
-                                       && req->req.zero) {
-                               DMSG("%s zlp terminate ...\n", ep->ep.name);
-                               completed = 0;
-                       }
-               }
-       }
-
-       if (likely(completed)) {
-               done(ep, req, 0);
-
-               /* maybe re-activate after completion */
-               if (ep->stopped || list_empty(&ep->queue))
-                       goto done;
-               req = list_entry(ep->queue.next, struct pxa2xx_request, queue);
-       }
-       kick_dma(ep, req);
-done:
-       local_irq_enable();
-}
-
-#endif
-
 /*-------------------------------------------------------------------------*/
 
 static int
@@ -942,19 +678,8 @@ pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
                                                (ep->desc->wMaxPacketSize)))
                return -EMSGSIZE;
 
-#ifdef USE_DMA
-       // FIXME caller may already have done the dma mapping
-       if (ep->dma >= 0) {
-               _req->dma = dma_map_single(dev->dev,
-                       _req->buf, _req->length,
-                       ((ep->bEndpointAddress & USB_DIR_IN) != 0)
-                               ? DMA_TO_DEVICE
-                               : DMA_FROM_DEVICE);
-       }
-#endif
-
        DBG(DBG_NOISY, "%s queue req %p, len %d buf %p\n",
-            _ep->name, _req, _req->length, _req->buf);
+               _ep->name, _req, _req->length, _req->buf);
 
        local_irq_save(flags);
 
@@ -1002,11 +727,6 @@ pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
                                local_irq_restore (flags);
                                return -EL2HLT;
                        }
-#ifdef USE_DMA
-               /* either start dma or prime pio pump */
-               } else if (ep->dma >= 0) {
-                       kick_dma(ep, req);
-#endif
                /* can the FIFO can satisfy the request immediately? */
                } else if ((ep->bEndpointAddress & USB_DIR_IN) != 0) {
                        if ((*ep->reg_udccs & UDCCS_BI_TFS) != 0
@@ -1017,7 +737,7 @@ pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
                        req = NULL;
                }
 
-               if (likely (req && ep->desc) && ep->dma < 0)
+               if (likely (req && ep->desc))
                        pio_irq_enable(ep->bEndpointAddress);
        }
 
@@ -1038,10 +758,6 @@ static void nuke(struct pxa2xx_ep *ep, int status)
        struct pxa2xx_request *req;
 
        /* called with irqs blocked */
-#ifdef USE_DMA
-       if (ep->dma >= 0 && !ep->stopped)
-               cancel_dma(ep);
-#endif
        while (!list_empty(&ep->queue)) {
                req = list_entry(ep->queue.next,
                                struct pxa2xx_request,
@@ -1076,19 +792,7 @@ static int pxa2xx_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
                return -EINVAL;
        }
 
-#ifdef USE_DMA
-       if (ep->dma >= 0 && ep->queue.next == &req->queue && !ep->stopped) {
-               cancel_dma(ep);
-               done(ep, req, -ECONNRESET);
-               /* restart i/o */
-               if (!list_empty(&ep->queue)) {
-                       req = list_entry(ep->queue.next,
-                                       struct pxa2xx_request, queue);
-                       kick_dma(ep, req);
-               }
-       } else
-#endif
-               done(ep, req, -ECONNRESET);
+       done(ep, req, -ECONNRESET);
 
        local_irq_restore(flags);
        return 0;
@@ -1203,9 +907,6 @@ static struct usb_ep_ops pxa2xx_ep_ops = {
        .alloc_request  = pxa2xx_ep_alloc_request,
        .free_request   = pxa2xx_ep_free_request,
 
-       .alloc_buffer   = pxa2xx_ep_alloc_buffer,
-       .free_buffer    = pxa2xx_ep_free_buffer,
-
        .queue          = pxa2xx_ep_queue,
        .dequeue        = pxa2xx_ep_dequeue,
 
@@ -1325,7 +1026,7 @@ udc_proc_read(char *page, char **start, off_t off, int count,
        /* basic device status */
        t = scnprintf(next, size, DRIVER_DESC "\n"
                "%s version: %s\nGadget driver: %s\nHost %s\n\n",
-               driver_name, DRIVER_VERSION SIZE_STR DMASTR,
+               driver_name, DRIVER_VERSION SIZE_STR "(pio)",
                dev->driver ? dev->driver->driver.name : "(none)",
                is_vbus_present() ? "full speed" : "disconnected");
        size -= t;
@@ -1390,7 +1091,6 @@ udc_proc_read(char *page, char **start, off_t off, int count,
        for (i = 0; i < PXA_UDC_NUM_ENDPOINTS; i++) {
                struct pxa2xx_ep        *ep = &dev->ep [i];
                struct pxa2xx_request   *req;
-               int                     t;
 
                if (i != 0) {
                        const struct usb_endpoint_descriptor    *d;
@@ -1400,10 +1100,9 @@ udc_proc_read(char *page, char **start, off_t off, int count,
                                continue;
                        tmp = *dev->ep [i].reg_udccs;
                        t = scnprintf(next, size,
-                               "%s max %d %s udccs %02x irqs %lu/%lu\n",
+                               "%s max %d %s udccs %02x irqs %lu\n",
                                ep->ep.name, le16_to_cpu (d->wMaxPacketSize),
-                               (ep->dma >= 0) ? "dma" : "pio", tmp,
-                               ep->pio_irqs, ep->dma_irqs);
+                               "pio", tmp, ep->pio_irqs);
                        /* TODO translate all five groups of udccs bits! */
 
                } else /* ep0 should only have one transfer queued */
@@ -1423,19 +1122,7 @@ udc_proc_read(char *page, char **start, off_t off, int count,
                        continue;
                }
                list_for_each_entry(req, &ep->queue, queue) {
-#ifdef USE_DMA
-                       if (ep->dma >= 0 && req->queue.prev == &ep->queue)
-                               t = scnprintf(next, size,
-                                       "\treq %p len %d/%d "
-                                       "buf %p (dma%d dcmd %08x)\n",
-                                       &req->req, req->req.actual,
-                                       req->req.length, req->req.buf,
-                                       ep->dma, DCMD(ep->dma)
-                                       // low 13 bits == bytes-to-go
-                                       );
-                       else
-#endif
-                               t = scnprintf(next, size,
+                       t = scnprintf(next, size,
                                        "\treq %p len %d/%d buf %p\n",
                                        &req->req, req->req.actual,
                                        req->req.length, req->req.buf);
@@ -1488,7 +1175,6 @@ static void udc_disable(struct pxa2xx_udc *dev)
 
        ep0_idle (dev);
        dev->gadget.speed = USB_SPEED_UNKNOWN;
-       LED_CONNECTED_OFF;
 }
 
 
@@ -1514,7 +1200,7 @@ static void udc_reinit(struct pxa2xx_udc *dev)
                ep->desc = NULL;
                ep->stopped = 0;
                INIT_LIST_HEAD (&ep->queue);
-               ep->pio_irqs = ep->dma_irqs = 0;
+               ep->pio_irqs = 0;
        }
 
        /* the rest was statically initialized, and is read-only */
@@ -1666,7 +1352,6 @@ stop_activity(struct pxa2xx_udc *dev, struct usb_gadget_driver *driver)
        del_timer_sync(&dev->timer);
 
        /* report disconnect; the driver is already quiesced */
-       LED_CONNECTED_OFF;
        if (driver)
                driver->disconnect(&dev->gadget);
 
@@ -1715,16 +1400,13 @@ lubbock_vbus_irq(int irq, void *_dev)
        int                     vbus;
 
        dev->stats.irqs++;
-       HEX_DISPLAY(dev->stats.irqs);
        switch (irq) {
        case LUBBOCK_USB_IRQ:
-               LED_CONNECTED_ON;
                vbus = 1;
                disable_irq(LUBBOCK_USB_IRQ);
                enable_irq(LUBBOCK_USB_DISC_IRQ);
                break;
        case LUBBOCK_USB_DISC_IRQ:
-               LED_CONNECTED_OFF;
                vbus = 0;
                disable_irq(LUBBOCK_USB_DISC_IRQ);
                enable_irq(LUBBOCK_USB_IRQ);
@@ -1742,7 +1424,7 @@ lubbock_vbus_irq(int irq, void *_dev)
 static irqreturn_t udc_vbus_irq(int irq, void *_dev)
 {
        struct pxa2xx_udc       *dev = _dev;
-       int                     vbus = udc_gpio_get(dev->mach->gpio_vbus);
+       int                     vbus = gpio_get_value(dev->mach->gpio_vbus);
 
        pxa2xx_udc_vbus_session(&dev->gadget, vbus);
        return IRQ_HANDLED;
@@ -2040,18 +1722,6 @@ static void handle_ep(struct pxa2xx_ep *ep)
 
                        /* fifos can hold packets, ready for reading... */
                        if (likely(req)) {
-#ifdef USE_OUT_DMA
-// TODO didn't yet debug out-dma.  this approach assumes
-// the worst about short packets and RPC; it might be better.
-
-                               if (likely(ep->dma >= 0)) {
-                                       if (!(udccs & UDCCS_BO_RSP)) {
-                                               *ep->reg_udccs = UDCCS_BO_RPC;
-                                               ep->dma_irqs++;
-                                               return;
-                                       }
-                               }
-#endif
                                completed = read_fifo(ep, req);
                        } else
                                pio_irq_disable (ep->bEndpointAddress);
@@ -2074,7 +1744,6 @@ pxa2xx_udc_irq(int irq, void *_dev)
        int                     handled;
 
        dev->stats.irqs++;
-       HEX_DISPLAY(dev->stats.irqs);
        do {
                u32             udccr = UDCCR;
 
@@ -2125,7 +1794,6 @@ pxa2xx_udc_irq(int irq, void *_dev)
                        } else {
                                DBG(DBG_VERBOSE, "USB reset end\n");
                                dev->gadget.speed = USB_SPEED_FULL;
-                               LED_CONNECTED_ON;
                                memset(&dev->stats, 0, sizeof dev->stats);
                                /* driver and endpoints are still reset */
                        }
@@ -2217,7 +1885,6 @@ static struct pxa2xx_udc memory = {
                .bmAttributes   = USB_ENDPOINT_XFER_BULK,
                .reg_udccs      = &UDCCS1,
                .reg_uddr       = &UDDR1,
-               drcmr (25)
        },
        .ep[2] = {
                .ep = {
@@ -2232,7 +1899,6 @@ static struct pxa2xx_udc memory = {
                .reg_udccs      = &UDCCS2,
                .reg_ubcr       = &UBCR2,
                .reg_uddr       = &UDDR2,
-               drcmr (26)
        },
 #ifndef CONFIG_USB_PXA2XX_SMALL
        .ep[3] = {
@@ -2247,7 +1913,6 @@ static struct pxa2xx_udc memory = {
                .bmAttributes   = USB_ENDPOINT_XFER_ISOC,
                .reg_udccs      = &UDCCS3,
                .reg_uddr       = &UDDR3,
-               drcmr (27)
        },
        .ep[4] = {
                .ep = {
@@ -2262,7 +1927,6 @@ static struct pxa2xx_udc memory = {
                .reg_udccs      = &UDCCS4,
                .reg_ubcr       = &UBCR4,
                .reg_uddr       = &UDDR4,
-               drcmr (28)
        },
        .ep[5] = {
                .ep = {
@@ -2291,7 +1955,6 @@ static struct pxa2xx_udc memory = {
                .bmAttributes   = USB_ENDPOINT_XFER_BULK,
                .reg_udccs      = &UDCCS6,
                .reg_uddr       = &UDDR6,
-               drcmr (30)
        },
        .ep[7] = {
                .ep = {
@@ -2306,7 +1969,6 @@ static struct pxa2xx_udc memory = {
                .reg_udccs      = &UDCCS7,
                .reg_ubcr       = &UBCR7,
                .reg_uddr       = &UDDR7,
-               drcmr (31)
        },
        .ep[8] = {
                .ep = {
@@ -2320,7 +1982,6 @@ static struct pxa2xx_udc memory = {
                .bmAttributes   = USB_ENDPOINT_XFER_ISOC,
                .reg_udccs      = &UDCCS8,
                .reg_uddr       = &UDDR8,
-               drcmr (32)
        },
        .ep[9] = {
                .ep = {
@@ -2335,7 +1996,6 @@ static struct pxa2xx_udc memory = {
                .reg_udccs      = &UDCCS9,
                .reg_ubcr       = &UBCR9,
                .reg_uddr       = &UDDR9,
-               drcmr (33)
        },
        .ep[10] = {
                .ep = {
@@ -2364,7 +2024,6 @@ static struct pxa2xx_udc memory = {
                .bmAttributes   = USB_ENDPOINT_XFER_BULK,
                .reg_udccs      = &UDCCS11,
                .reg_uddr       = &UDDR11,
-               drcmr (35)
        },
        .ep[12] = {
                .ep = {
@@ -2379,7 +2038,6 @@ static struct pxa2xx_udc memory = {
                .reg_udccs      = &UDCCS12,
                .reg_ubcr       = &UBCR12,
                .reg_uddr       = &UDDR12,
-               drcmr (36)
        },
        .ep[13] = {
                .ep = {
@@ -2393,7 +2051,6 @@ static struct pxa2xx_udc memory = {
                .bmAttributes   = USB_ENDPOINT_XFER_ISOC,
                .reg_udccs      = &UDCCS13,
                .reg_uddr       = &UDDR13,
-               drcmr (37)
        },
        .ep[14] = {
                .ep = {
@@ -2408,7 +2065,6 @@ static struct pxa2xx_udc memory = {
                .reg_udccs      = &UDCCS14,
                .reg_ubcr       = &UBCR14,
                .reg_uddr       = &UDDR14,
-               drcmr (38)
        },
        .ep[15] = {
                .ep = {
@@ -2466,7 +2122,7 @@ static struct pxa2xx_udc memory = {
 static int __init pxa2xx_udc_probe(struct platform_device *pdev)
 {
        struct pxa2xx_udc *dev = &memory;
-       int retval, out_dma = 1, vbus_irq, irq;
+       int retval, vbus_irq, irq;
        u32 chiprev;
 
        /* insist on Intel/ARM/XScale */
@@ -2489,7 +2145,7 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev)
        case PXA250_B2: case PXA210_B2:
        case PXA250_B1: case PXA210_B1:
        case PXA250_B0: case PXA210_B0:
-               out_dma = 0;
+               /* OUT-DMA is broken ... */
                /* fall through */
        case PXA250_C0: case PXA210_C0:
                break;
@@ -2498,11 +2154,9 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev)
        case IXP425_B0:
        case IXP465_AD:
                dev->has_cfr = 1;
-               out_dma = 0;
                break;
 #endif
        default:
-               out_dma = 0;
                printk(KERN_ERR "%s: unrecognized processor: %08x\n",
                        driver_name, chiprev);
                /* iop3xx, ixp4xx, ... */
@@ -2513,36 +2167,41 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev)
        if (irq < 0)
                return -ENODEV;
 
-       pr_debug("%s: IRQ %d%s%s%s\n", driver_name, irq,
+       pr_debug("%s: IRQ %d%s%s\n", driver_name, irq,
                dev->has_cfr ? "" : " (!cfr)",
-               out_dma ? "" : " (broken dma-out)",
-               SIZE_STR DMASTR
+               SIZE_STR "(pio)"
                );
 
-#ifdef USE_DMA
-#ifndef        USE_OUT_DMA
-       out_dma = 0;
-#endif
-       /* pxa 250 erratum 130 prevents using OUT dma (fixed C0) */
-       if (!out_dma) {
-               DMSG("disabled OUT dma\n");
-               dev->ep[ 2].reg_drcmr = dev->ep[ 4].reg_drcmr = 0;
-               dev->ep[ 7].reg_drcmr = dev->ep[ 9].reg_drcmr = 0;
-               dev->ep[12].reg_drcmr = dev->ep[14].reg_drcmr = 0;
-       }
-#endif
-
        /* other non-static parts of init */
        dev->dev = &pdev->dev;
        dev->mach = pdev->dev.platform_data;
+
        if (dev->mach->gpio_vbus) {
-               udc_gpio_init_vbus(dev->mach->gpio_vbus);
-               vbus_irq = udc_gpio_to_irq(dev->mach->gpio_vbus);
+               if ((retval = gpio_request(dev->mach->gpio_vbus,
+                               "pxa2xx_udc GPIO VBUS"))) {
+                       dev_dbg(&pdev->dev,
+                               "can't get vbus gpio %d, err: %d\n",
+                               dev->mach->gpio_vbus, retval);
+                       return -EBUSY;
+               }
+               gpio_direction_input(dev->mach->gpio_vbus);
+               vbus_irq = gpio_to_irq(dev->mach->gpio_vbus);
                set_irq_type(vbus_irq, IRQT_BOTHEDGE);
        } else
                vbus_irq = 0;
-       if (dev->mach->gpio_pullup)
-               udc_gpio_init_pullup(dev->mach->gpio_pullup);
+
+       if (dev->mach->gpio_pullup) {
+               if ((retval = gpio_request(dev->mach->gpio_pullup,
+                               "pca2xx_udc GPIO PULLUP"))) {
+                       dev_dbg(&pdev->dev,
+                               "can't get pullup gpio %d, err: %d\n",
+                               dev->mach->gpio_pullup, retval);
+                       if (dev->mach->gpio_vbus)
+                               gpio_free(dev->mach->gpio_vbus);
+                       return -EBUSY;
+               }
+               gpio_direction_output(dev->mach->gpio_pullup, 0);
+       }
 
        init_timer(&dev->timer);
        dev->timer.function = udc_watchdog;
@@ -2566,6 +2225,10 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev)
        if (retval != 0) {
                printk(KERN_ERR "%s: can't get irq %d, err %d\n",
                        driver_name, irq, retval);
+               if (dev->mach->gpio_pullup)
+                       gpio_free(dev->mach->gpio_pullup);
+               if (dev->mach->gpio_vbus)
+                       gpio_free(dev->mach->gpio_vbus);
                return -EBUSY;
        }
        dev->got_irq = 1;
@@ -2581,6 +2244,10 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev)
                                driver_name, LUBBOCK_USB_DISC_IRQ, retval);
 lubbock_fail0:
                        free_irq(irq, dev);
+                       if (dev->mach->gpio_pullup)
+                               gpio_free(dev->mach->gpio_pullup);
+                       if (dev->mach->gpio_vbus)
+                               gpio_free(dev->mach->gpio_vbus);
                        return -EBUSY;
                }
                retval = request_irq(LUBBOCK_USB_IRQ,
@@ -2593,11 +2260,6 @@ lubbock_fail0:
                        free_irq(LUBBOCK_USB_DISC_IRQ, dev);
                        goto lubbock_fail0;
                }
-#ifdef DEBUG
-               /* with U-Boot (but not BLOB), hex is off by default */
-               HEX_DISPLAY(dev->stats.irqs);
-               LUB_DISC_BLNK_LED &= 0xff;
-#endif
        } else
 #endif
        if (vbus_irq) {
@@ -2608,6 +2270,10 @@ lubbock_fail0:
                        printk(KERN_ERR "%s: can't get irq %i, err %d\n",
                                driver_name, vbus_irq, retval);
                        free_irq(irq, dev);
+                       if (dev->mach->gpio_pullup)
+                               gpio_free(dev->mach->gpio_pullup);
+                       if (dev->mach->gpio_vbus)
+                               gpio_free(dev->mach->gpio_vbus);
                        return -EBUSY;
                }
        }
@@ -2641,8 +2307,13 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev)
                free_irq(LUBBOCK_USB_IRQ, dev);
        }
 #endif
-       if (dev->mach->gpio_vbus)
-               free_irq(IRQ_GPIO(dev->mach->gpio_vbus), dev);
+       if (dev->mach->gpio_vbus) {
+               free_irq(gpio_to_irq(dev->mach->gpio_vbus), dev);
+               gpio_free(dev->mach->gpio_vbus);
+       }
+       if (dev->mach->gpio_pullup)
+               gpio_free(dev->mach->gpio_pullup);
+
        platform_set_drvdata(pdev, NULL);
        the_controller = NULL;
        return 0;
index 773e549aff3f721eb1f7b0ace82b45ff51b4c470..0e5d0e6fb0e2a26eb49e8bcc48a809fca81fbe23 100644 (file)
@@ -54,8 +54,6 @@ struct pxa2xx_ep {
        const struct usb_endpoint_descriptor    *desc;
        struct list_head                        queue;
        unsigned long                           pio_irqs;
-       unsigned long                           dma_irqs;
-       short                                   dma; 
 
        unsigned short                          fifo_size;
        u8                                      bEndpointAddress;
@@ -63,7 +61,7 @@ struct pxa2xx_ep {
 
        unsigned                                stopped : 1;
        unsigned                                dma_fixup : 1;
-                                                        
+
        /* UDCCS = UDC Control/Status for this EP
         * UBCR = UDC Byte Count Remaining (contents of OUT fifo)
         * UDDR = UDC Endpoint Data Register (the fifo)
@@ -72,12 +70,6 @@ struct pxa2xx_ep {
        volatile u32                            *reg_udccs;
        volatile u32                            *reg_ubcr;
        volatile u32                            *reg_uddr;
-#ifdef USE_DMA
-       volatile u32                    *reg_drcmr;
-#define        drcmr(n)  .reg_drcmr = & DRCMR ## n ,
-#else
-#define        drcmr(n)  
-#endif
 };
 
 struct pxa2xx_request {
@@ -85,7 +77,7 @@ struct pxa2xx_request {
        struct list_head                        queue;
 };
 
-enum ep0_state { 
+enum ep0_state {
        EP0_IDLE,
        EP0_IN_DATA_PHASE,
        EP0_OUT_DATA_PHASE,
@@ -108,7 +100,6 @@ struct udc_stats {
 
 #ifdef CONFIG_USB_PXA2XX_SMALL
 /* when memory's tight, SMALL config saves code+data.  */
-#undef USE_DMA
 #define        PXA_UDC_NUM_ENDPOINTS   3
 #endif
 
@@ -144,37 +135,8 @@ struct pxa2xx_udc {
 #ifdef CONFIG_ARCH_LUBBOCK
 #include <asm/arch/lubbock.h>
 /* lubbock can also report usb connect/disconnect irqs */
-
-#ifdef DEBUG
-#define HEX_DISPLAY(n) if (machine_is_lubbock()) { LUB_HEXLED = (n); }
 #endif
 
-#endif
-
-/*-------------------------------------------------------------------------*/
-
-/* LEDs are only for debug */
-#ifndef HEX_DISPLAY
-#define HEX_DISPLAY(n)         do {} while(0)
-#endif
-
-#ifdef DEBUG
-#include <asm/leds.h>
-
-#define LED_CONNECTED_ON       leds_event(led_green_on)
-#define LED_CONNECTED_OFF      do { \
-                                       leds_event(led_green_off); \
-                                       HEX_DISPLAY(0); \
-                               } while(0)
-#endif
-
-#ifndef LED_CONNECTED_ON
-#define LED_CONNECTED_ON       do {} while(0)
-#define LED_CONNECTED_OFF      do {} while(0)
-#endif
-
-/*-------------------------------------------------------------------------*/
-
 static struct pxa2xx_udc *the_controller;
 
 /*-------------------------------------------------------------------------*/
@@ -204,7 +166,7 @@ static const char *state_name[] = {
 #    define UDC_DEBUG DBG_NORMAL
 #endif
 
-static void __attribute__ ((__unused__))
+static void __maybe_unused
 dump_udccr(const char *label)
 {
        u32     udccr = UDCCR;
@@ -220,7 +182,7 @@ dump_udccr(const char *label)
                (udccr & UDCCR_UDE) ? " ude" : "");
 }
 
-static void __attribute__ ((__unused__))
+static void __maybe_unused
 dump_udccs0(const char *label)
 {
        u32             udccs0 = UDCCS0;
@@ -237,7 +199,7 @@ dump_udccs0(const char *label)
                (udccs0 & UDCCS0_OPR) ? " opr" : "");
 }
 
-static void __attribute__ ((__unused__))
+static void __maybe_unused
 dump_state(struct pxa2xx_udc *dev)
 {
        u32             tmp;
index 708657c89132068f2bfdbb8cc7f3552cbc182cbe..db1b2bfcee4e65eb91cc0c9070f55cea556a76bc 100644 (file)
@@ -53,7 +53,7 @@
  */
 
 #if 0
-#define DEBUG(str,args...) do { \
+#define DBG(str,args...) do { \
        if (rndis_debug) \
                printk(KERN_DEBUG str , ## args ); \
        } while (0)
@@ -65,7 +65,7 @@ MODULE_PARM_DESC (rndis_debug, "enable debugging");
 #else
 
 #define rndis_debug            0
-#define DEBUG(str,args...)     do{}while(0)
+#define DBG(str,args...)       do{}while(0)
 #endif
 
 #define RNDIS_MAX_CONFIGS      1
@@ -183,9 +183,9 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
        if (!resp) return -ENOMEM;
 
        if (buf_len && rndis_debug > 1) {
-               DEBUG("query OID %08x value, len %d:\n", OID, buf_len);
+               DBG("query OID %08x value, len %d:\n", OID, buf_len);
                for (i = 0; i < buf_len; i += 16) {
-                       DEBUG ("%03d: %08x %08x %08x %08x\n", i,
+                       DBG("%03d: %08x %08x %08x %08x\n", i,
                                le32_to_cpu(get_unaligned((__le32 *)
                                        &buf[i])),
                                le32_to_cpu(get_unaligned((__le32 *)
@@ -207,7 +207,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
 
        /* mandatory */
        case OID_GEN_SUPPORTED_LIST:
-               DEBUG ("%s: OID_GEN_SUPPORTED_LIST\n", __FUNCTION__);
+               DBG("%s: OID_GEN_SUPPORTED_LIST\n", __FUNCTION__);
                length = sizeof (oid_supported_list);
                count  = length / sizeof (u32);
                for (i = 0; i < count; i++)
@@ -217,7 +217,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
 
        /* mandatory */
        case OID_GEN_HARDWARE_STATUS:
-               DEBUG("%s: OID_GEN_HARDWARE_STATUS\n", __FUNCTION__);
+               DBG("%s: OID_GEN_HARDWARE_STATUS\n", __FUNCTION__);
                /* Bogus question!
                 * Hardware must be ready to receive high level protocols.
                 * BTW:
@@ -230,14 +230,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
 
        /* mandatory */
        case OID_GEN_MEDIA_SUPPORTED:
-               DEBUG("%s: OID_GEN_MEDIA_SUPPORTED\n", __FUNCTION__);
+               DBG("%s: OID_GEN_MEDIA_SUPPORTED\n", __FUNCTION__);
                *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium);
                retval = 0;
                break;
 
        /* mandatory */
        case OID_GEN_MEDIA_IN_USE:
-               DEBUG("%s: OID_GEN_MEDIA_IN_USE\n", __FUNCTION__);
+               DBG("%s: OID_GEN_MEDIA_IN_USE\n", __FUNCTION__);
                /* one medium, one transport... (maybe you do it better) */
                *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium);
                retval = 0;
@@ -245,7 +245,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
 
        /* mandatory */
        case OID_GEN_MAXIMUM_FRAME_SIZE:
-               DEBUG("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __FUNCTION__);
+               DBG("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].dev) {
                        *outbuf = cpu_to_le32 (
                                rndis_per_dev_params [configNr].dev->mtu);
@@ -256,7 +256,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
        /* mandatory */
        case OID_GEN_LINK_SPEED:
                if (rndis_debug > 1)
-                       DEBUG("%s: OID_GEN_LINK_SPEED\n", __FUNCTION__);
+                       DBG("%s: OID_GEN_LINK_SPEED\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].media_state
                                == NDIS_MEDIA_STATE_DISCONNECTED)
                        *outbuf = __constant_cpu_to_le32 (0);
@@ -268,7 +268,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
 
        /* mandatory */
        case OID_GEN_TRANSMIT_BLOCK_SIZE:
-               DEBUG("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __FUNCTION__);
+               DBG("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].dev) {
                        *outbuf = cpu_to_le32 (
                                rndis_per_dev_params [configNr].dev->mtu);
@@ -278,7 +278,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
 
        /* mandatory */
        case OID_GEN_RECEIVE_BLOCK_SIZE:
-               DEBUG("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __FUNCTION__);
+               DBG("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].dev) {
                        *outbuf = cpu_to_le32 (
                                rndis_per_dev_params [configNr].dev->mtu);
@@ -288,7 +288,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
 
        /* mandatory */
        case OID_GEN_VENDOR_ID:
-               DEBUG("%s: OID_GEN_VENDOR_ID\n", __FUNCTION__);
+               DBG("%s: OID_GEN_VENDOR_ID\n", __FUNCTION__);
                *outbuf = cpu_to_le32 (
                        rndis_per_dev_params [configNr].vendorID);
                retval = 0;
@@ -296,7 +296,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
 
        /* mandatory */
        case OID_GEN_VENDOR_DESCRIPTION:
-               DEBUG("%s: OID_GEN_VENDOR_DESCRIPTION\n", __FUNCTION__);
+               DBG("%s: OID_GEN_VENDOR_DESCRIPTION\n", __FUNCTION__);
                length = strlen (rndis_per_dev_params [configNr].vendorDescr);
                memcpy (outbuf,
                        rndis_per_dev_params [configNr].vendorDescr, length);
@@ -304,7 +304,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
                break;
 
        case OID_GEN_VENDOR_DRIVER_VERSION:
-               DEBUG("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __FUNCTION__);
+               DBG("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __FUNCTION__);
                /* Created as LE */
                *outbuf = rndis_driver_version;
                retval = 0;
@@ -312,14 +312,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
 
        /* mandatory */
        case OID_GEN_CURRENT_PACKET_FILTER:
-               DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __FUNCTION__);
+               DBG("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __FUNCTION__);
                *outbuf = cpu_to_le32 (*rndis_per_dev_params[configNr].filter);
                retval = 0;
                break;
 
        /* mandatory */
        case OID_GEN_MAXIMUM_TOTAL_SIZE:
-               DEBUG("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __FUNCTION__);
+               DBG("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __FUNCTION__);
                *outbuf = __constant_cpu_to_le32(RNDIS_MAX_TOTAL_SIZE);
                retval = 0;
                break;
@@ -327,14 +327,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
        /* mandatory */
        case OID_GEN_MEDIA_CONNECT_STATUS:
                if (rndis_debug > 1)
-                       DEBUG("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __FUNCTION__);
+                       DBG("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __FUNCTION__);
                *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
                                                .media_state);
                retval = 0;
                break;
 
        case OID_GEN_PHYSICAL_MEDIUM:
-               DEBUG("%s: OID_GEN_PHYSICAL_MEDIUM\n", __FUNCTION__);
+               DBG("%s: OID_GEN_PHYSICAL_MEDIUM\n", __FUNCTION__);
                *outbuf = __constant_cpu_to_le32 (0);
                retval = 0;
                break;
@@ -344,7 +344,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
         * versions emit undefined RNDIS messages. DOCUMENT ALL THESE!
         */
        case OID_GEN_MAC_OPTIONS:               /* from WinME */
-               DEBUG("%s: OID_GEN_MAC_OPTIONS\n", __FUNCTION__);
+               DBG("%s: OID_GEN_MAC_OPTIONS\n", __FUNCTION__);
                *outbuf = __constant_cpu_to_le32(
                          NDIS_MAC_OPTION_RECEIVE_SERIALIZED
                        | NDIS_MAC_OPTION_FULL_DUPLEX);
@@ -356,7 +356,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
        /* mandatory */
        case OID_GEN_XMIT_OK:
                if (rndis_debug > 1)
-                       DEBUG("%s: OID_GEN_XMIT_OK\n", __FUNCTION__);
+                       DBG("%s: OID_GEN_XMIT_OK\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].stats) {
                        *outbuf = cpu_to_le32 (
                            rndis_per_dev_params [configNr].stats->tx_packets -
@@ -369,7 +369,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
        /* mandatory */
        case OID_GEN_RCV_OK:
                if (rndis_debug > 1)
-                       DEBUG("%s: OID_GEN_RCV_OK\n", __FUNCTION__);
+                       DBG("%s: OID_GEN_RCV_OK\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].stats) {
                        *outbuf = cpu_to_le32 (
                            rndis_per_dev_params [configNr].stats->rx_packets -
@@ -382,7 +382,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
        /* mandatory */
        case OID_GEN_XMIT_ERROR:
                if (rndis_debug > 1)
-                       DEBUG("%s: OID_GEN_XMIT_ERROR\n", __FUNCTION__);
+                       DBG("%s: OID_GEN_XMIT_ERROR\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].stats) {
                        *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
                                        .stats->tx_errors);
@@ -393,7 +393,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
        /* mandatory */
        case OID_GEN_RCV_ERROR:
                if (rndis_debug > 1)
-                       DEBUG("%s: OID_GEN_RCV_ERROR\n", __FUNCTION__);
+                       DBG("%s: OID_GEN_RCV_ERROR\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].stats) {
                        *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
                                        .stats->rx_errors);
@@ -403,7 +403,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
 
        /* mandatory */
        case OID_GEN_RCV_NO_BUFFER:
-               DEBUG("%s: OID_GEN_RCV_NO_BUFFER\n", __FUNCTION__);
+               DBG("%s: OID_GEN_RCV_NO_BUFFER\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].stats) {
                        *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
                                        .stats->rx_dropped);
@@ -413,7 +413,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
 
 #ifdef RNDIS_OPTIONAL_STATS
        case OID_GEN_DIRECTED_BYTES_XMIT:
-               DEBUG("%s: OID_GEN_DIRECTED_BYTES_XMIT\n", __FUNCTION__);
+               DBG("%s: OID_GEN_DIRECTED_BYTES_XMIT\n", __FUNCTION__);
                /*
                 * Aunt Tilly's size of shoes
                 * minus antarctica count of penguins
@@ -433,7 +433,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
                break;
 
        case OID_GEN_DIRECTED_FRAMES_XMIT:
-               DEBUG("%s: OID_GEN_DIRECTED_FRAMES_XMIT\n", __FUNCTION__);
+               DBG("%s: OID_GEN_DIRECTED_FRAMES_XMIT\n", __FUNCTION__);
                /* dito */
                if (rndis_per_dev_params [configNr].stats) {
                        *outbuf = cpu_to_le32 (
@@ -449,7 +449,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
                break;
 
        case OID_GEN_MULTICAST_BYTES_XMIT:
-               DEBUG("%s: OID_GEN_MULTICAST_BYTES_XMIT\n", __FUNCTION__);
+               DBG("%s: OID_GEN_MULTICAST_BYTES_XMIT\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].stats) {
                        *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
                                        .stats->multicast*1234);
@@ -458,7 +458,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
                break;
 
        case OID_GEN_MULTICAST_FRAMES_XMIT:
-               DEBUG("%s: OID_GEN_MULTICAST_FRAMES_XMIT\n", __FUNCTION__);
+               DBG("%s: OID_GEN_MULTICAST_FRAMES_XMIT\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].stats) {
                        *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
                                        .stats->multicast);
@@ -467,7 +467,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
                break;
 
        case OID_GEN_BROADCAST_BYTES_XMIT:
-               DEBUG("%s: OID_GEN_BROADCAST_BYTES_XMIT\n", __FUNCTION__);
+               DBG("%s: OID_GEN_BROADCAST_BYTES_XMIT\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].stats) {
                        *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
                                        .stats->tx_packets/42*255);
@@ -476,7 +476,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
                break;
 
        case OID_GEN_BROADCAST_FRAMES_XMIT:
-               DEBUG("%s: OID_GEN_BROADCAST_FRAMES_XMIT\n", __FUNCTION__);
+               DBG("%s: OID_GEN_BROADCAST_FRAMES_XMIT\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].stats) {
                        *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
                                        .stats->tx_packets/42);
@@ -485,19 +485,19 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
                break;
 
        case OID_GEN_DIRECTED_BYTES_RCV:
-               DEBUG("%s: OID_GEN_DIRECTED_BYTES_RCV\n", __FUNCTION__);
+               DBG("%s: OID_GEN_DIRECTED_BYTES_RCV\n", __FUNCTION__);
                *outbuf = __constant_cpu_to_le32 (0);
                retval = 0;
                break;
 
        case OID_GEN_DIRECTED_FRAMES_RCV:
-               DEBUG("%s: OID_GEN_DIRECTED_FRAMES_RCV\n", __FUNCTION__);
+               DBG("%s: OID_GEN_DIRECTED_FRAMES_RCV\n", __FUNCTION__);
                *outbuf = __constant_cpu_to_le32 (0);
                retval = 0;
                break;
 
        case OID_GEN_MULTICAST_BYTES_RCV:
-               DEBUG("%s: OID_GEN_MULTICAST_BYTES_RCV\n", __FUNCTION__);
+               DBG("%s: OID_GEN_MULTICAST_BYTES_RCV\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].stats) {
                        *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
                                        .stats->multicast * 1111);
@@ -506,7 +506,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
                break;
 
        case OID_GEN_MULTICAST_FRAMES_RCV:
-               DEBUG("%s: OID_GEN_MULTICAST_FRAMES_RCV\n", __FUNCTION__);
+               DBG("%s: OID_GEN_MULTICAST_FRAMES_RCV\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].stats) {
                        *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
                                        .stats->multicast);
@@ -515,7 +515,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
                break;
 
        case OID_GEN_BROADCAST_BYTES_RCV:
-               DEBUG("%s: OID_GEN_BROADCAST_BYTES_RCV\n", __FUNCTION__);
+               DBG("%s: OID_GEN_BROADCAST_BYTES_RCV\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].stats) {
                        *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
                                        .stats->rx_packets/42*255);
@@ -524,7 +524,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
                break;
 
        case OID_GEN_BROADCAST_FRAMES_RCV:
-               DEBUG("%s: OID_GEN_BROADCAST_FRAMES_RCV\n", __FUNCTION__);
+               DBG("%s: OID_GEN_BROADCAST_FRAMES_RCV\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].stats) {
                        *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
                                        .stats->rx_packets/42);
@@ -533,7 +533,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
                break;
 
        case OID_GEN_RCV_CRC_ERROR:
-               DEBUG("%s: OID_GEN_RCV_CRC_ERROR\n", __FUNCTION__);
+               DBG("%s: OID_GEN_RCV_CRC_ERROR\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].stats) {
                        *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
                                        .stats->rx_crc_errors);
@@ -542,7 +542,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
                break;
 
        case OID_GEN_TRANSMIT_QUEUE_LENGTH:
-               DEBUG("%s: OID_GEN_TRANSMIT_QUEUE_LENGTH\n", __FUNCTION__);
+               DBG("%s: OID_GEN_TRANSMIT_QUEUE_LENGTH\n", __FUNCTION__);
                *outbuf = __constant_cpu_to_le32 (0);
                retval = 0;
                break;
@@ -552,7 +552,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
 
        /* mandatory */
        case OID_802_3_PERMANENT_ADDRESS:
-               DEBUG("%s: OID_802_3_PERMANENT_ADDRESS\n", __FUNCTION__);
+               DBG("%s: OID_802_3_PERMANENT_ADDRESS\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].dev) {
                        length = ETH_ALEN;
                        memcpy (outbuf,
@@ -564,7 +564,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
 
        /* mandatory */
        case OID_802_3_CURRENT_ADDRESS:
-               DEBUG("%s: OID_802_3_CURRENT_ADDRESS\n", __FUNCTION__);
+               DBG("%s: OID_802_3_CURRENT_ADDRESS\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].dev) {
                        length = ETH_ALEN;
                        memcpy (outbuf,
@@ -576,7 +576,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
 
        /* mandatory */
        case OID_802_3_MULTICAST_LIST:
-               DEBUG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__);
+               DBG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__);
                /* Multicast base address only */
                *outbuf = __constant_cpu_to_le32 (0xE0000000);
                retval = 0;
@@ -584,21 +584,21 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
 
        /* mandatory */
        case OID_802_3_MAXIMUM_LIST_SIZE:
-               DEBUG("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __FUNCTION__);
+               DBG("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __FUNCTION__);
                /* Multicast base address only */
                *outbuf = __constant_cpu_to_le32 (1);
                retval = 0;
                break;
 
        case OID_802_3_MAC_OPTIONS:
-               DEBUG("%s: OID_802_3_MAC_OPTIONS\n", __FUNCTION__);
+               DBG("%s: OID_802_3_MAC_OPTIONS\n", __FUNCTION__);
                break;
 
        /* ieee802.3 statistics OIDs (table 4-4) */
 
        /* mandatory */
        case OID_802_3_RCV_ERROR_ALIGNMENT:
-               DEBUG("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __FUNCTION__);
+               DBG("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __FUNCTION__);
                if (rndis_per_dev_params [configNr].stats) {
                        *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
                                        .stats->rx_frame_errors);
@@ -608,51 +608,51 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
 
        /* mandatory */
        case OID_802_3_XMIT_ONE_COLLISION:
-               DEBUG("%s: OID_802_3_XMIT_ONE_COLLISION\n", __FUNCTION__);
+               DBG("%s: OID_802_3_XMIT_ONE_COLLISION\n", __FUNCTION__);
                *outbuf = __constant_cpu_to_le32 (0);
                retval = 0;
                break;
 
        /* mandatory */
        case OID_802_3_XMIT_MORE_COLLISIONS:
-               DEBUG("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __FUNCTION__);
+               DBG("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __FUNCTION__);
                *outbuf = __constant_cpu_to_le32 (0);
                retval = 0;
                break;
 
 #ifdef RNDIS_OPTIONAL_STATS
        case OID_802_3_XMIT_DEFERRED:
-               DEBUG("%s: OID_802_3_XMIT_DEFERRED\n", __FUNCTION__);
+               DBG("%s: OID_802_3_XMIT_DEFERRED\n", __FUNCTION__);
                /* TODO */
                break;
 
        case OID_802_3_XMIT_MAX_COLLISIONS:
-               DEBUG("%s: OID_802_3_XMIT_MAX_COLLISIONS\n", __FUNCTION__);
+               DBG("%s: OID_802_3_XMIT_MAX_COLLISIONS\n", __FUNCTION__);
                /* TODO */
                break;
 
        case OID_802_3_RCV_OVERRUN:
-               DEBUG("%s: OID_802_3_RCV_OVERRUN\n", __FUNCTION__);
+               DBG("%s: OID_802_3_RCV_OVERRUN\n", __FUNCTION__);
                /* TODO */
                break;
 
        case OID_802_3_XMIT_UNDERRUN:
-               DEBUG("%s: OID_802_3_XMIT_UNDERRUN\n", __FUNCTION__);
+               DBG("%s: OID_802_3_XMIT_UNDERRUN\n", __FUNCTION__);
                /* TODO */
                break;
 
        case OID_802_3_XMIT_HEARTBEAT_FAILURE:
-               DEBUG("%s: OID_802_3_XMIT_HEARTBEAT_FAILURE\n", __FUNCTION__);
+               DBG("%s: OID_802_3_XMIT_HEARTBEAT_FAILURE\n", __FUNCTION__);
                /* TODO */
                break;
 
        case OID_802_3_XMIT_TIMES_CRS_LOST:
-               DEBUG("%s: OID_802_3_XMIT_TIMES_CRS_LOST\n", __FUNCTION__);
+               DBG("%s: OID_802_3_XMIT_TIMES_CRS_LOST\n", __FUNCTION__);
                /* TODO */
                break;
 
        case OID_802_3_XMIT_LATE_COLLISIONS:
-               DEBUG("%s: OID_802_3_XMIT_LATE_COLLISIONS\n", __FUNCTION__);
+               DBG("%s: OID_802_3_XMIT_LATE_COLLISIONS\n", __FUNCTION__);
                /* TODO */
                break;
 #endif /* RNDIS_OPTIONAL_STATS */
@@ -660,7 +660,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
 #ifdef RNDIS_PM
        /* power management OIDs (table 4-5) */
        case OID_PNP_CAPABILITIES:
-               DEBUG("%s: OID_PNP_CAPABILITIES\n", __FUNCTION__);
+               DBG("%s: OID_PNP_CAPABILITIES\n", __FUNCTION__);
 
                /* for now, no wakeup capabilities */
                length = sizeof (struct NDIS_PNP_CAPABILITIES);
@@ -668,7 +668,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
                retval = 0;
                break;
        case OID_PNP_QUERY_POWER:
-               DEBUG("%s: OID_PNP_QUERY_POWER D%d\n", __FUNCTION__,
+               DBG("%s: OID_PNP_QUERY_POWER D%d\n", __FUNCTION__,
                                le32_to_cpu(get_unaligned((__le32 *)buf)) - 1);
                /* only suspend is a real power state, and
                 * it can't be entered by OID_PNP_SET_POWER...
@@ -705,9 +705,9 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
                return -ENOMEM;
 
        if (buf_len && rndis_debug > 1) {
-               DEBUG("set OID %08x value, len %d:\n", OID, buf_len);
+               DBG("set OID %08x value, len %d:\n", OID, buf_len);
                for (i = 0; i < buf_len; i += 16) {
-                       DEBUG ("%03d: %08x %08x %08x %08x\n", i,
+                       DBG("%03d: %08x %08x %08x %08x\n", i,
                                le32_to_cpu(get_unaligned((__le32 *)
                                        &buf[i])),
                                le32_to_cpu(get_unaligned((__le32 *)
@@ -731,7 +731,7 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
                 */
                *params->filter = (u16) le32_to_cpu(get_unaligned(
                                (__le32 *)buf));
-               DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n",
+               DBG("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n",
                        __FUNCTION__, *params->filter);
 
                /* this call has a significant side effect:  it's
@@ -756,7 +756,7 @@ update_linkstate:
 
        case OID_802_3_MULTICAST_LIST:
                /* I think we can ignore this */
-               DEBUG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__);
+               DBG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__);
                retval = 0;
                break;
 #if 0
@@ -764,7 +764,7 @@ update_linkstate:
                {
                struct rndis_config_parameter   *param;
                param = (struct rndis_config_parameter *) buf;
-               DEBUG("%s: OID_GEN_RNDIS_CONFIG_PARAMETER '%*s'\n",
+               DBG("%s: OID_GEN_RNDIS_CONFIG_PARAMETER '%*s'\n",
                        __FUNCTION__,
                        min(cpu_to_le32(param->ParameterNameLength),80),
                        buf + param->ParameterNameOffset);
@@ -781,7 +781,7 @@ update_linkstate:
                 * FIXME ... then things go batty; Windows wedges itself.
                 */
                i = le32_to_cpu(get_unaligned((__le32 *)buf));
-               DEBUG("%s: OID_PNP_SET_POWER D%d\n", __FUNCTION__, i - 1);
+               DBG("%s: OID_PNP_SET_POWER D%d\n", __FUNCTION__, i - 1);
                switch (i) {
                case NdisDeviceStateD0:
                        *params->filter = params->saved_filter;
@@ -858,7 +858,7 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf)
        rndis_query_cmplt_type *resp;
        rndis_resp_t            *r;
 
-       // DEBUG("%s: OID = %08X\n", __FUNCTION__, cpu_to_le32(buf->OID));
+       // DBG("%s: OID = %08X\n", __FUNCTION__, cpu_to_le32(buf->OID));
        if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP;
 
        /*
@@ -911,15 +911,15 @@ static int rndis_set_response (int configNr, rndis_set_msg_type *buf)
        BufOffset = le32_to_cpu (buf->InformationBufferOffset);
 
 #ifdef VERBOSE
-       DEBUG("%s: Length: %d\n", __FUNCTION__, BufLength);
-       DEBUG("%s: Offset: %d\n", __FUNCTION__, BufOffset);
-       DEBUG("%s: InfoBuffer: ", __FUNCTION__);
+       DBG("%s: Length: %d\n", __FUNCTION__, BufLength);
+       DBG("%s: Offset: %d\n", __FUNCTION__, BufOffset);
+       DBG("%s: InfoBuffer: ", __FUNCTION__);
 
        for (i = 0; i < BufLength; i++) {
-               DEBUG ("%02x ", *(((u8 *) buf) + i + 8 + BufOffset));
+               DBG("%02x ", *(((u8 *) buf) + i + 8 + BufOffset));
        }
 
-       DEBUG ("\n");
+       DBG("\n");
 #endif
 
        resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_SET_CMPLT);
@@ -1082,14 +1082,14 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
        /* For USB: responses may take up to 10 seconds */
        switch (MsgType) {
        case REMOTE_NDIS_INITIALIZE_MSG:
-               DEBUG("%s: REMOTE_NDIS_INITIALIZE_MSG\n",
+               DBG("%s: REMOTE_NDIS_INITIALIZE_MSG\n",
                        __FUNCTION__ );
                params->state = RNDIS_INITIALIZED;
                return  rndis_init_response (configNr,
                                        (rndis_init_msg_type *) buf);
 
        case REMOTE_NDIS_HALT_MSG:
-               DEBUG("%s: REMOTE_NDIS_HALT_MSG\n",
+               DBG("%s: REMOTE_NDIS_HALT_MSG\n",
                        __FUNCTION__ );
                params->state = RNDIS_UNINITIALIZED;
                if (params->dev) {
@@ -1107,7 +1107,7 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
                                        (rndis_set_msg_type *) buf);
 
        case REMOTE_NDIS_RESET_MSG:
-               DEBUG("%s: REMOTE_NDIS_RESET_MSG\n",
+               DBG("%s: REMOTE_NDIS_RESET_MSG\n",
                        __FUNCTION__ );
                return rndis_reset_response (configNr,
                                        (rndis_reset_msg_type *) buf);
@@ -1115,7 +1115,7 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
        case REMOTE_NDIS_KEEPALIVE_MSG:
                /* For USB: host does this every 5 seconds */
                if (rndis_debug > 1)
-                       DEBUG("%s: REMOTE_NDIS_KEEPALIVE_MSG\n",
+                       DBG("%s: REMOTE_NDIS_KEEPALIVE_MSG\n",
                                __FUNCTION__ );
                return rndis_keepalive_response (configNr,
                                                 (rndis_keepalive_msg_type *)
@@ -1132,7 +1132,7 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
                {
                        unsigned i;
                        for (i = 0; i < MsgLength; i += 16) {
-                               DEBUG ("%03d: "
+                               DBG("%03d: "
                                        " %02x %02x %02x %02x"
                                        " %02x %02x %02x %02x"
                                        " %02x %02x %02x %02x"
@@ -1163,18 +1163,18 @@ int rndis_register (int (* rndis_control_ack) (struct net_device *))
                if (!rndis_per_dev_params [i].used) {
                        rndis_per_dev_params [i].used = 1;
                        rndis_per_dev_params [i].ack = rndis_control_ack;
-                       DEBUG("%s: configNr = %d\n", __FUNCTION__, i);
+                       DBG("%s: configNr = %d\n", __FUNCTION__, i);
                        return i;
                }
        }
-       DEBUG("failed\n");
+       DBG("failed\n");
 
        return -1;
 }
 
 void rndis_deregister (int configNr)
 {
-       DEBUG("%s: \n", __FUNCTION__ );
+       DBG("%s: \n", __FUNCTION__ );
 
        if (configNr >= RNDIS_MAX_CONFIGS) return;
        rndis_per_dev_params [configNr].used = 0;
@@ -1186,7 +1186,7 @@ int rndis_set_param_dev (u8 configNr, struct net_device *dev,
                         struct net_device_stats *stats,
                         u16 *cdc_filter)
 {
-       DEBUG("%s:\n", __FUNCTION__ );
+       DBG("%s:\n", __FUNCTION__ );
        if (!dev || !stats) return -1;
        if (configNr >= RNDIS_MAX_CONFIGS) return -1;
 
@@ -1199,7 +1199,7 @@ int rndis_set_param_dev (u8 configNr, struct net_device *dev,
 
 int rndis_set_param_vendor (u8 configNr, u32 vendorID, const char *vendorDescr)
 {
-       DEBUG("%s:\n", __FUNCTION__ );
+       DBG("%s:\n", __FUNCTION__ );
        if (!vendorDescr) return -1;
        if (configNr >= RNDIS_MAX_CONFIGS) return -1;
 
@@ -1211,7 +1211,7 @@ int rndis_set_param_vendor (u8 configNr, u32 vendorID, const char *vendorDescr)
 
 int rndis_set_param_medium (u8 configNr, u32 medium, u32 speed)
 {
-       DEBUG("%s: %u %u\n", __FUNCTION__, medium, speed);
+       DBG("%s: %u %u\n", __FUNCTION__, medium, speed);
        if (configNr >= RNDIS_MAX_CONFIGS) return -1;
 
        rndis_per_dev_params [configNr].medium = medium;
@@ -1390,7 +1390,7 @@ static int rndis_proc_write (struct file *file, const char __user *buffer,
                        break;
                default:
                        if (fl_speed) p->speed = speed;
-                       else DEBUG ("%c is not valid\n", c);
+                       else DBG("%c is not valid\n", c);
                        break;
                }
 
@@ -1419,12 +1419,12 @@ int __devinit rndis_init (void)
                if (!(rndis_connect_state [i]
                                = create_proc_entry (name, 0660, NULL)))
                {
-                       DEBUG ("%s :remove entries", __FUNCTION__);
+                       DBG("%s :remove entries", __FUNCTION__);
                        while (i) {
                                sprintf (name, NAME_TEMPLATE, --i);
                                remove_proc_entry (name, NULL);
                        }
-                       DEBUG ("\n");
+                       DBG("\n");
                        return -EIO;
                }
 
diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c
new file mode 100644 (file)
index 0000000..0be80c6
--- /dev/null
@@ -0,0 +1,2045 @@
+/*
+ * linux/drivers/usb/gadget/s3c2410_udc.c
+ *
+ * Samsung S3C24xx series on-chip full speed USB device controllers
+ *
+ * Copyright (C) 2004-2007 Herbert Pötzl - Arnaud Patard
+ *     Additional cleanups by Ben Dooks <ben-linux@fluff.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/smp_lock.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/timer.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/version.h>
+#include <linux/clk.h>
+
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+#include <linux/usb.h>
+#include <linux/usb_gadget.h>
+
+#include <asm/byteorder.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/unaligned.h>
+#include <asm/arch/irqs.h>
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/regs-clock.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-udc.h>
+#include <asm/arch/udc.h>
+
+#include <asm/mach-types.h>
+
+#include "s3c2410_udc.h"
+
+#define DRIVER_DESC    "S3C2410 USB Device Controller Gadget"
+#define DRIVER_VERSION "29 Apr 2007"
+#define DRIVER_AUTHOR  "Herbert Pötzl <herbert@13thfloor.at>, " \
+                       "Arnaud Patard <arnaud.patard@rtp-net.org>"
+
+static const char              gadget_name[] = "s3c2410_udc";
+static const char              driver_desc[] = DRIVER_DESC;
+
+static struct s3c2410_udc      *the_controller;
+static struct clk              *udc_clock;
+static struct clk              *usb_bus_clock;
+static void __iomem            *base_addr;
+static u64                     rsrc_start;
+static u64                     rsrc_len;
+static struct dentry           *s3c2410_udc_debugfs_root;
+
+static inline u32 udc_read(u32 reg)
+{
+       return readb(base_addr + reg);
+}
+
+static inline void udc_write(u32 value, u32 reg)
+{
+       writeb(value, base_addr + reg);
+}
+
+static inline void udc_writeb(void __iomem *base, u32 value, u32 reg)
+{
+       writeb(value, base + reg);
+}
+
+static struct s3c2410_udc_mach_info *udc_info;
+
+/*************************** DEBUG FUNCTION ***************************/
+#define DEBUG_NORMAL   1
+#define DEBUG_VERBOSE  2
+
+#ifdef CONFIG_USB_S3C2410_DEBUG
+#define USB_S3C2410_DEBUG_LEVEL 0
+
+static uint32_t s3c2410_ticks = 0;
+
+static int dprintk(int level, const char *fmt, ...)
+{
+       static char printk_buf[1024];
+       static long prevticks;
+       static int invocation;
+       va_list args;
+       int len;
+
+       if (level > USB_S3C2410_DEBUG_LEVEL)
+               return 0;
+
+       if (s3c2410_ticks != prevticks) {
+               prevticks = s3c2410_ticks;
+               invocation = 0;
+       }
+
+       len = scnprintf(printk_buf,
+                       sizeof(printk_buf), "%1lu.%02d USB: ",
+                       prevticks, invocation++);
+
+       va_start(args, fmt);
+       len = vscnprintf(printk_buf+len,
+                       sizeof(printk_buf)-len, fmt, args);
+       va_end(args);
+
+       return printk(KERN_DEBUG "%s", printk_buf);
+}
+#else
+static int dprintk(int level, const char *fmt, ...)
+{
+       return 0;
+}
+#endif
+static int s3c2410_udc_debugfs_seq_show(struct seq_file *m, void *p)
+{
+       u32 addr_reg,pwr_reg,ep_int_reg,usb_int_reg;
+       u32 ep_int_en_reg, usb_int_en_reg, ep0_csr;
+       u32 ep1_i_csr1,ep1_i_csr2,ep1_o_csr1,ep1_o_csr2;
+       u32 ep2_i_csr1,ep2_i_csr2,ep2_o_csr1,ep2_o_csr2;
+
+       addr_reg       = udc_read(S3C2410_UDC_FUNC_ADDR_REG);
+       pwr_reg        = udc_read(S3C2410_UDC_PWR_REG);
+       ep_int_reg     = udc_read(S3C2410_UDC_EP_INT_REG);
+       usb_int_reg    = udc_read(S3C2410_UDC_USB_INT_REG);
+       ep_int_en_reg  = udc_read(S3C2410_UDC_EP_INT_EN_REG);
+       usb_int_en_reg = udc_read(S3C2410_UDC_USB_INT_EN_REG);
+       udc_write(0, S3C2410_UDC_INDEX_REG);
+       ep0_csr        = udc_read(S3C2410_UDC_IN_CSR1_REG);
+       udc_write(1, S3C2410_UDC_INDEX_REG);
+       ep1_i_csr1     = udc_read(S3C2410_UDC_IN_CSR1_REG);
+       ep1_i_csr2     = udc_read(S3C2410_UDC_IN_CSR2_REG);
+       ep1_o_csr1     = udc_read(S3C2410_UDC_IN_CSR1_REG);
+       ep1_o_csr2     = udc_read(S3C2410_UDC_IN_CSR2_REG);
+       udc_write(2, S3C2410_UDC_INDEX_REG);
+       ep2_i_csr1     = udc_read(S3C2410_UDC_IN_CSR1_REG);
+       ep2_i_csr2     = udc_read(S3C2410_UDC_IN_CSR2_REG);
+       ep2_o_csr1     = udc_read(S3C2410_UDC_IN_CSR1_REG);
+       ep2_o_csr2     = udc_read(S3C2410_UDC_IN_CSR2_REG);
+
+       seq_printf(m, "FUNC_ADDR_REG  : 0x%04X\n"
+                "PWR_REG        : 0x%04X\n"
+                "EP_INT_REG     : 0x%04X\n"
+                "USB_INT_REG    : 0x%04X\n"
+                "EP_INT_EN_REG  : 0x%04X\n"
+                "USB_INT_EN_REG : 0x%04X\n"
+                "EP0_CSR        : 0x%04X\n"
+                "EP1_I_CSR1     : 0x%04X\n"
+                "EP1_I_CSR2     : 0x%04X\n"
+                "EP1_O_CSR1     : 0x%04X\n"
+                "EP1_O_CSR2     : 0x%04X\n"
+                "EP2_I_CSR1     : 0x%04X\n"
+                "EP2_I_CSR2     : 0x%04X\n"
+                "EP2_O_CSR1     : 0x%04X\n"
+                "EP2_O_CSR2     : 0x%04X\n",
+                       addr_reg,pwr_reg,ep_int_reg,usb_int_reg,
+                       ep_int_en_reg, usb_int_en_reg, ep0_csr,
+                       ep1_i_csr1,ep1_i_csr2,ep1_o_csr1,ep1_o_csr2,
+                       ep2_i_csr1,ep2_i_csr2,ep2_o_csr1,ep2_o_csr2
+               );
+
+       return 0;
+}
+
+static int s3c2410_udc_debugfs_fops_open(struct inode *inode,
+                                        struct file *file)
+{
+       return single_open(file, s3c2410_udc_debugfs_seq_show, NULL);
+}
+
+static const struct file_operations s3c2410_udc_debugfs_fops = {
+       .open           = s3c2410_udc_debugfs_fops_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+       .owner          = THIS_MODULE,
+};
+
+/* io macros */
+
+static inline void s3c2410_udc_clear_ep0_opr(void __iomem *base)
+{
+       udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG);
+       udc_writeb(base, S3C2410_UDC_EP0_CSR_SOPKTRDY,
+                       S3C2410_UDC_EP0_CSR_REG);
+}
+
+static inline void s3c2410_udc_clear_ep0_sst(void __iomem *base)
+{
+       udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG);
+       writeb(0x00, base + S3C2410_UDC_EP0_CSR_REG);
+}
+
+static inline void s3c2410_udc_clear_ep0_se(void __iomem *base)
+{
+       udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG);
+       udc_writeb(base, S3C2410_UDC_EP0_CSR_SSE, S3C2410_UDC_EP0_CSR_REG);
+}
+
+static inline void s3c2410_udc_set_ep0_ipr(void __iomem *base)
+{
+       udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG);
+       udc_writeb(base, S3C2410_UDC_EP0_CSR_IPKRDY, S3C2410_UDC_EP0_CSR_REG);
+}
+
+static inline void s3c2410_udc_set_ep0_de(void __iomem *base)
+{
+       udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG);
+       udc_writeb(base, S3C2410_UDC_EP0_CSR_DE, S3C2410_UDC_EP0_CSR_REG);
+}
+
+inline void s3c2410_udc_set_ep0_ss(void __iomem *b)
+{
+       udc_writeb(b, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG);
+       udc_writeb(b, S3C2410_UDC_EP0_CSR_SENDSTL, S3C2410_UDC_EP0_CSR_REG);
+}
+
+static inline void s3c2410_udc_set_ep0_de_out(void __iomem *base)
+{
+       udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG);
+
+       udc_writeb(base,(S3C2410_UDC_EP0_CSR_SOPKTRDY
+                               | S3C2410_UDC_EP0_CSR_DE),
+                       S3C2410_UDC_EP0_CSR_REG);
+}
+
+static inline void s3c2410_udc_set_ep0_sse_out(void __iomem *base)
+{
+       udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG);
+       udc_writeb(base, (S3C2410_UDC_EP0_CSR_SOPKTRDY
+                               | S3C2410_UDC_EP0_CSR_SSE),
+                       S3C2410_UDC_EP0_CSR_REG);
+}
+
+static inline void s3c2410_udc_set_ep0_de_in(void __iomem *base)
+{
+       udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG);
+       udc_writeb(base, (S3C2410_UDC_EP0_CSR_IPKRDY
+                       | S3C2410_UDC_EP0_CSR_DE),
+               S3C2410_UDC_EP0_CSR_REG);
+}
+
+/*------------------------- I/O ----------------------------------*/
+
+/*
+ *     s3c2410_udc_done
+ */
+static void s3c2410_udc_done(struct s3c2410_ep *ep,
+               struct s3c2410_request *req, int status)
+{
+       unsigned halted = ep->halted;
+
+       list_del_init(&req->queue);
+
+       if (likely (req->req.status == -EINPROGRESS))
+               req->req.status = status;
+       else
+               status = req->req.status;
+
+       ep->halted = 1;
+       req->req.complete(&ep->ep, &req->req);
+       ep->halted = halted;
+}
+
+static void s3c2410_udc_nuke(struct s3c2410_udc *udc,
+               struct s3c2410_ep *ep, int status)
+{
+       /* Sanity check */
+       if (&ep->queue == NULL)
+               return;
+
+       while (!list_empty (&ep->queue)) {
+               struct s3c2410_request *req;
+               req = list_entry (ep->queue.next, struct s3c2410_request,
+                               queue);
+               s3c2410_udc_done(ep, req, status);
+       }
+}
+
+static inline void s3c2410_udc_clear_ep_state(struct s3c2410_udc *dev)
+{
+       unsigned i;
+
+       /* hardware SET_{CONFIGURATION,INTERFACE} automagic resets endpoint
+        * fifos, and pending transactions mustn't be continued in any case.
+        */
+
+       for (i = 1; i < S3C2410_ENDPOINTS; i++)
+               s3c2410_udc_nuke(dev, &dev->ep[i], -ECONNABORTED);
+}
+
+static inline int s3c2410_udc_fifo_count_out(void)
+{
+       int tmp;
+
+       tmp = udc_read(S3C2410_UDC_OUT_FIFO_CNT2_REG) << 8;
+       tmp |= udc_read(S3C2410_UDC_OUT_FIFO_CNT1_REG);
+       return tmp;
+}
+
+/*
+ *     s3c2410_udc_write_packet
+ */
+static inline int s3c2410_udc_write_packet(int fifo,
+               struct s3c2410_request *req,
+               unsigned max)
+{
+       unsigned len = min(req->req.length - req->req.actual, max);
+       u8 *buf = req->req.buf + req->req.actual;
+
+       prefetch(buf);
+
+       dprintk(DEBUG_VERBOSE, "%s %d %d %d %d\n", __func__,
+               req->req.actual, req->req.length, len, req->req.actual + len);
+
+       req->req.actual += len;
+
+       udelay(5);
+       writesb(base_addr + fifo, buf, len);
+       return len;
+}
+
+/*
+ *     s3c2410_udc_write_fifo
+ *
+ * return:  0 = still running, 1 = completed, negative = errno
+ */
+static int s3c2410_udc_write_fifo(struct s3c2410_ep *ep,
+               struct s3c2410_request *req)
+{
+       unsigned        count;
+       int             is_last;
+       u32             idx;
+       int             fifo_reg;
+       u32             ep_csr;
+
+       idx = ep->bEndpointAddress & 0x7F;
+       switch (idx) {
+       default:
+               idx = 0;
+       case 0:
+               fifo_reg = S3C2410_UDC_EP0_FIFO_REG;
+               break;
+       case 1:
+               fifo_reg = S3C2410_UDC_EP1_FIFO_REG;
+               break;
+       case 2:
+               fifo_reg = S3C2410_UDC_EP2_FIFO_REG;
+               break;
+       case 3:
+               fifo_reg = S3C2410_UDC_EP3_FIFO_REG;
+               break;
+       case 4:
+               fifo_reg = S3C2410_UDC_EP4_FIFO_REG;
+               break;
+       }
+
+       count = s3c2410_udc_write_packet(fifo_reg, req, ep->ep.maxpacket);
+
+       /* last packet is often short (sometimes a zlp) */
+       if (count != ep->ep.maxpacket)
+               is_last = 1;
+       else if (req->req.length != req->req.actual || req->req.zero)
+               is_last = 0;
+       else
+               is_last = 2;
+
+       /* Only ep0 debug messages are interesting */
+       if (idx == 0)
+               dprintk(DEBUG_NORMAL,
+                       "Written ep%d %d.%d of %d b [last %d,z %d]\n",
+                       idx, count, req->req.actual, req->req.length,
+                       is_last, req->req.zero);
+
+       if (is_last) {
+               /* The order is important. It prevents sending 2 packets
+                * at the same time */
+
+               if (idx == 0) {
+                       /* Reset signal => no need to say 'data sent' */
+                       if (! (udc_read(S3C2410_UDC_USB_INT_REG)
+                                       & S3C2410_UDC_USBINT_RESET))
+                               s3c2410_udc_set_ep0_de_in(base_addr);
+                       ep->dev->ep0state=EP0_IDLE;
+               } else {
+                       udc_write(idx, S3C2410_UDC_INDEX_REG);
+                       ep_csr = udc_read(S3C2410_UDC_IN_CSR1_REG);
+                       udc_write(idx, S3C2410_UDC_INDEX_REG);
+                       udc_write(ep_csr | S3C2410_UDC_ICSR1_PKTRDY,
+                                       S3C2410_UDC_IN_CSR1_REG);
+               }
+
+               s3c2410_udc_done(ep, req, 0);
+               is_last = 1;
+       } else {
+               if (idx == 0) {
+                       /* Reset signal => no need to say 'data sent' */
+                       if (! (udc_read(S3C2410_UDC_USB_INT_REG)
+                                       & S3C2410_UDC_USBINT_RESET))
+                               s3c2410_udc_set_ep0_ipr(base_addr);
+               } else {
+                       udc_write(idx, S3C2410_UDC_INDEX_REG);
+                       ep_csr = udc_read(S3C2410_UDC_IN_CSR1_REG);
+                       udc_write(idx, S3C2410_UDC_INDEX_REG);
+                       udc_write(ep_csr | S3C2410_UDC_ICSR1_PKTRDY,
+                                       S3C2410_UDC_IN_CSR1_REG);
+               }
+       }
+
+       return is_last;
+}
+
+static inline int s3c2410_udc_read_packet(int fifo, u8 *buf,
+               struct s3c2410_request *req, unsigned avail)
+{
+       unsigned len;
+
+       len = min(req->req.length - req->req.actual, avail);
+       req->req.actual += len;
+
+       readsb(fifo + base_addr, buf, len);
+       return len;
+}
+
+/*
+ * return:  0 = still running, 1 = queue empty, negative = errno
+ */
+static int s3c2410_udc_read_fifo(struct s3c2410_ep *ep,
+                                struct s3c2410_request *req)
+{
+       u8              *buf;
+       u32             ep_csr;
+       unsigned        bufferspace;
+       int             is_last=1;
+       unsigned        avail;
+       int             fifo_count = 0;
+       u32             idx;
+       int             fifo_reg;
+
+       idx = ep->bEndpointAddress & 0x7F;
+
+       switch (idx) {
+       default:
+               idx = 0;
+       case 0:
+               fifo_reg = S3C2410_UDC_EP0_FIFO_REG;
+               break;
+       case 1:
+               fifo_reg = S3C2410_UDC_EP1_FIFO_REG;
+               break;
+       case 2:
+               fifo_reg = S3C2410_UDC_EP2_FIFO_REG;
+               break;
+       case 3:
+               fifo_reg = S3C2410_UDC_EP3_FIFO_REG;
+               break;
+       case 4:
+               fifo_reg = S3C2410_UDC_EP4_FIFO_REG;
+               break;
+       }
+
+       if (!req->req.length)
+               return 1;
+
+       buf = req->req.buf + req->req.actual;
+       bufferspace = req->req.length - req->req.actual;
+       if (!bufferspace) {
+               dprintk(DEBUG_NORMAL, "%s: buffer full!\n", __func__);
+               return -1;
+       }
+
+       udc_write(idx, S3C2410_UDC_INDEX_REG);
+
+       fifo_count = s3c2410_udc_fifo_count_out();
+       dprintk(DEBUG_NORMAL, "%s fifo count : %d\n", __func__, fifo_count);
+
+       if (fifo_count > ep->ep.maxpacket)
+               avail = ep->ep.maxpacket;
+       else
+               avail = fifo_count;
+
+       fifo_count = s3c2410_udc_read_packet(fifo_reg, buf, req, avail);
+
+       /* checking this with ep0 is not accurate as we already
+        * read a control request
+        **/
+       if (idx != 0 && fifo_count < ep->ep.maxpacket) {
+               is_last = 1;
+               /* overflowed this request?  flush extra data */
+               if (fifo_count != avail)
+                       req->req.status = -EOVERFLOW;
+       } else {
+               is_last = (req->req.length <= req->req.actual) ? 1 : 0;
+       }
+
+       udc_write(idx, S3C2410_UDC_INDEX_REG);
+       fifo_count = s3c2410_udc_fifo_count_out();
+
+       /* Only ep0 debug messages are interesting */
+       if (idx == 0)
+               dprintk(DEBUG_VERBOSE, "%s fifo count : %d [last %d]\n",
+                       __func__, fifo_count,is_last);
+
+       if (is_last) {
+               if (idx == 0) {
+                       s3c2410_udc_set_ep0_de_out(base_addr);
+                       ep->dev->ep0state = EP0_IDLE;
+               } else {
+                       udc_write(idx, S3C2410_UDC_INDEX_REG);
+                       ep_csr = udc_read(S3C2410_UDC_OUT_CSR1_REG);
+                       udc_write(idx, S3C2410_UDC_INDEX_REG);
+                       udc_write(ep_csr & ~S3C2410_UDC_OCSR1_PKTRDY,
+                                       S3C2410_UDC_OUT_CSR1_REG);
+               }
+
+               s3c2410_udc_done(ep, req, 0);
+       } else {
+               if (idx == 0) {
+                       s3c2410_udc_clear_ep0_opr(base_addr);
+               } else {
+                       udc_write(idx, S3C2410_UDC_INDEX_REG);
+                       ep_csr = udc_read(S3C2410_UDC_OUT_CSR1_REG);
+                       udc_write(idx, S3C2410_UDC_INDEX_REG);
+                       udc_write(ep_csr & ~S3C2410_UDC_OCSR1_PKTRDY,
+                                       S3C2410_UDC_OUT_CSR1_REG);
+               }
+       }
+
+       return is_last;
+}
+
+static int s3c2410_udc_read_fifo_crq(struct usb_ctrlrequest *crq)
+{
+       unsigned char *outbuf = (unsigned char*)crq;
+       int bytes_read = 0;
+
+       udc_write(0, S3C2410_UDC_INDEX_REG);
+
+       bytes_read = s3c2410_udc_fifo_count_out();
+
+       dprintk(DEBUG_NORMAL, "%s: fifo_count=%d\n", __func__, bytes_read);
+
+       if (bytes_read > sizeof(struct usb_ctrlrequest))
+               bytes_read = sizeof(struct usb_ctrlrequest);
+
+       readsb(S3C2410_UDC_EP0_FIFO_REG + base_addr, outbuf, bytes_read);
+
+       dprintk(DEBUG_VERBOSE, "%s: len=%d %02x:%02x {%x,%x,%x}\n", __func__,
+               bytes_read, crq->bRequest, crq->bRequestType,
+               crq->wValue, crq->wIndex, crq->wLength);
+
+       return bytes_read;
+}
+
+static int s3c2410_udc_get_status(struct s3c2410_udc *dev,
+               struct usb_ctrlrequest *crq)
+{
+       u16 status = 0;
+       u8 ep_num = crq->wIndex & 0x7F;
+       u8 is_in = crq->wIndex & USB_DIR_IN;
+
+       switch (crq->bRequestType & USB_RECIP_MASK) {
+       case USB_RECIP_INTERFACE:
+               break;
+
+       case USB_RECIP_DEVICE:
+               status = dev->devstatus;
+               break;
+
+       case USB_RECIP_ENDPOINT:
+               if (ep_num > 4 || crq->wLength > 2)
+                       return 1;
+
+               if (ep_num == 0) {
+                       udc_write(0, S3C2410_UDC_INDEX_REG);
+                       status = udc_read(S3C2410_UDC_IN_CSR1_REG);
+                       status = status & S3C2410_UDC_EP0_CSR_SENDSTL;
+               } else {
+                       udc_write(ep_num, S3C2410_UDC_INDEX_REG);
+                       if (is_in) {
+                               status = udc_read(S3C2410_UDC_IN_CSR1_REG);
+                               status = status & S3C2410_UDC_ICSR1_SENDSTL;
+                       } else {
+                               status = udc_read(S3C2410_UDC_OUT_CSR1_REG);
+                               status = status & S3C2410_UDC_OCSR1_SENDSTL;
+                       }
+               }
+
+               status = status ? 1 : 0;
+               break;
+
+       default:
+               return 1;
+       }
+
+       /* Seems to be needed to get it working. ouch :( */
+       udelay(5);
+       udc_write(status & 0xFF, S3C2410_UDC_EP0_FIFO_REG);
+       udc_write(status >> 8, S3C2410_UDC_EP0_FIFO_REG);
+       s3c2410_udc_set_ep0_de_in(base_addr);
+
+       return 0;
+}
+/*------------------------- usb state machine -------------------------------*/
+static int s3c2410_udc_set_halt(struct usb_ep *_ep, int value);
+
+static void s3c2410_udc_handle_ep0_idle(struct s3c2410_udc *dev,
+                                       struct s3c2410_ep *ep,
+                                       struct usb_ctrlrequest *crq,
+                                       u32 ep0csr)
+{
+       int len, ret, tmp;
+
+       /* start control request? */
+       if (!(ep0csr & S3C2410_UDC_EP0_CSR_OPKRDY))
+               return;
+
+       s3c2410_udc_nuke(dev, ep, -EPROTO);
+
+       len = s3c2410_udc_read_fifo_crq(crq);
+       if (len != sizeof(*crq)) {
+               dprintk(DEBUG_NORMAL, "setup begin: fifo READ ERROR"
+                       " wanted %d bytes got %d. Stalling out...\n",
+                       sizeof(*crq), len);
+               s3c2410_udc_set_ep0_ss(base_addr);
+               return;
+       }
+
+       dprintk(DEBUG_NORMAL, "bRequest = %d bRequestType %d wLength = %d\n",
+               crq->bRequest, crq->bRequestType, crq->wLength);
+
+       /* cope with automagic for some standard requests. */
+       dev->req_std = (crq->bRequestType & USB_TYPE_MASK)
+               == USB_TYPE_STANDARD;
+       dev->req_config = 0;
+       dev->req_pending = 1;
+
+       switch (crq->bRequest) {
+       case USB_REQ_SET_CONFIGURATION:
+               dprintk(DEBUG_NORMAL, "USB_REQ_SET_CONFIGURATION ... \n");
+
+               if (crq->bRequestType == USB_RECIP_DEVICE) {
+                       dev->req_config = 1;
+                       s3c2410_udc_set_ep0_de_out(base_addr);
+               }
+               break;
+
+       case USB_REQ_SET_INTERFACE:
+               dprintk(DEBUG_NORMAL, "USB_REQ_SET_INTERFACE ... \n");
+
+               if (crq->bRequestType == USB_RECIP_INTERFACE) {
+                       dev->req_config = 1;
+                       s3c2410_udc_set_ep0_de_out(base_addr);
+               }
+               break;
+
+       case USB_REQ_SET_ADDRESS:
+               dprintk(DEBUG_NORMAL, "USB_REQ_SET_ADDRESS ... \n");
+
+               if (crq->bRequestType == USB_RECIP_DEVICE) {
+                       tmp = crq->wValue & 0x7F;
+                       dev->address = tmp;
+                       udc_write((tmp | S3C2410_UDC_FUNCADDR_UPDATE),
+                                       S3C2410_UDC_FUNC_ADDR_REG);
+                       s3c2410_udc_set_ep0_de_out(base_addr);
+                       return;
+               }
+               break;
+
+       case USB_REQ_GET_STATUS:
+               dprintk(DEBUG_NORMAL, "USB_REQ_GET_STATUS ... \n");
+               s3c2410_udc_clear_ep0_opr(base_addr);
+
+               if (dev->req_std) {
+                       if (!s3c2410_udc_get_status(dev, crq)) {
+                               return;
+                       }
+               }
+               break;
+
+       case USB_REQ_CLEAR_FEATURE:
+               s3c2410_udc_clear_ep0_opr(base_addr);
+
+               if (crq->bRequestType != USB_RECIP_ENDPOINT)
+                       break;
+
+               if (crq->wValue != USB_ENDPOINT_HALT || crq->wLength != 0)
+                       break;
+
+               s3c2410_udc_set_halt(&dev->ep[crq->wIndex & 0x7f].ep, 0);
+               s3c2410_udc_set_ep0_de_out(base_addr);
+               return;
+
+       case USB_REQ_SET_FEATURE:
+               s3c2410_udc_clear_ep0_opr(base_addr);
+
+               if (crq->bRequestType != USB_RECIP_ENDPOINT)
+                       break;
+
+               if (crq->wValue != USB_ENDPOINT_HALT || crq->wLength != 0)
+                       break;
+
+               s3c2410_udc_set_halt(&dev->ep[crq->wIndex & 0x7f].ep, 1);
+               s3c2410_udc_set_ep0_de_out(base_addr);
+               return;
+
+       default:
+               s3c2410_udc_clear_ep0_opr(base_addr);
+               break;
+       }
+
+       if (crq->bRequestType & USB_DIR_IN)
+               dev->ep0state = EP0_IN_DATA_PHASE;
+       else
+               dev->ep0state = EP0_OUT_DATA_PHASE;
+
+       ret = dev->driver->setup(&dev->gadget, crq);
+       if (ret < 0) {
+               if (dev->req_config) {
+                       dprintk(DEBUG_NORMAL, "config change %02x fail %d?\n",
+                               crq->bRequest, ret);
+                       return;
+               }
+
+               if (ret == -EOPNOTSUPP)
+                       dprintk(DEBUG_NORMAL, "Operation not supported\n");
+               else
+                       dprintk(DEBUG_NORMAL,
+                               "dev->driver->setup failed. (%d)\n", ret);
+
+               udelay(5);
+               s3c2410_udc_set_ep0_ss(base_addr);
+               s3c2410_udc_set_ep0_de_out(base_addr);
+               dev->ep0state = EP0_IDLE;
+               /* deferred i/o == no response yet */
+       } else if (dev->req_pending) {
+               dprintk(DEBUG_VERBOSE, "dev->req_pending... what now?\n");
+               dev->req_pending=0;
+       }
+
+       dprintk(DEBUG_VERBOSE, "ep0state %s\n", ep0states[dev->ep0state]);
+}
+
+static void s3c2410_udc_handle_ep0(struct s3c2410_udc *dev)
+{
+       u32                     ep0csr;
+       struct s3c2410_ep       *ep = &dev->ep[0];
+       struct s3c2410_request  *req;
+       struct usb_ctrlrequest  crq;
+
+       if (list_empty(&ep->queue))
+               req = NULL;
+       else
+               req = list_entry(ep->queue.next, struct s3c2410_request, queue);
+
+       /* We make the assumption that S3C2410_UDC_IN_CSR1_REG equal to
+        * S3C2410_UDC_EP0_CSR_REG when index is zero */
+
+       udc_write(0, S3C2410_UDC_INDEX_REG);
+       ep0csr = udc_read(S3C2410_UDC_IN_CSR1_REG);
+
+       dprintk(DEBUG_NORMAL, "ep0csr %x ep0state %s\n",
+               ep0csr, ep0states[dev->ep0state]);
+
+       /* clear stall status */
+       if (ep0csr & S3C2410_UDC_EP0_CSR_SENTSTL) {
+               s3c2410_udc_nuke(dev, ep, -EPIPE);
+               dprintk(DEBUG_NORMAL, "... clear SENT_STALL ...\n");
+               s3c2410_udc_clear_ep0_sst(base_addr);
+               dev->ep0state = EP0_IDLE;
+               return;
+       }
+
+       /* clear setup end */
+       if (ep0csr & S3C2410_UDC_EP0_CSR_SE) {
+               dprintk(DEBUG_NORMAL, "... serviced SETUP_END ...\n");
+               s3c2410_udc_nuke(dev, ep, 0);
+               s3c2410_udc_clear_ep0_se(base_addr);
+               dev->ep0state = EP0_IDLE;
+       }
+
+       switch (dev->ep0state) {
+       case EP0_IDLE:
+               s3c2410_udc_handle_ep0_idle(dev, ep, &crq, ep0csr);
+               break;
+
+       case EP0_IN_DATA_PHASE:                 /* GET_DESCRIPTOR etc */
+               dprintk(DEBUG_NORMAL, "EP0_IN_DATA_PHASE ... what now?\n");
+               if (!(ep0csr & S3C2410_UDC_EP0_CSR_IPKRDY) && req) {
+                       s3c2410_udc_write_fifo(ep, req);
+               }
+               break;
+
+       case EP0_OUT_DATA_PHASE:                /* SET_DESCRIPTOR etc */
+               dprintk(DEBUG_NORMAL, "EP0_OUT_DATA_PHASE ... what now?\n");
+               if ((ep0csr & S3C2410_UDC_EP0_CSR_OPKRDY) && req ) {
+                       s3c2410_udc_read_fifo(ep,req);
+               }
+               break;
+
+       case EP0_END_XFER:
+               dprintk(DEBUG_NORMAL, "EP0_END_XFER ... what now?\n");
+               dev->ep0state = EP0_IDLE;
+               break;
+
+       case EP0_STALL:
+               dprintk(DEBUG_NORMAL, "EP0_STALL ... what now?\n");
+               dev->ep0state = EP0_IDLE;
+               break;
+       }
+}
+
+/*
+ *     handle_ep - Manage I/O endpoints
+ */
+
+static void s3c2410_udc_handle_ep(struct s3c2410_ep *ep)
+{
+       struct s3c2410_request  *req;
+       int                     is_in = ep->bEndpointAddress & USB_DIR_IN;
+       u32                     ep_csr1;
+       u32                     idx;
+
+       if (likely (!list_empty(&ep->queue)))
+               req = list_entry(ep->queue.next,
+                               struct s3c2410_request, queue);
+       else
+               req = NULL;
+
+       idx = ep->bEndpointAddress & 0x7F;
+
+       if (is_in) {
+               udc_write(idx, S3C2410_UDC_INDEX_REG);
+               ep_csr1 = udc_read(S3C2410_UDC_IN_CSR1_REG);
+               dprintk(DEBUG_VERBOSE, "ep%01d write csr:%02x %d\n",
+                       idx, ep_csr1, req ? 1 : 0);
+
+               if (ep_csr1 & S3C2410_UDC_ICSR1_SENTSTL) {
+                       dprintk(DEBUG_VERBOSE, "st\n");
+                       udc_write(idx, S3C2410_UDC_INDEX_REG);
+                       udc_write(ep_csr1 & ~S3C2410_UDC_ICSR1_SENTSTL,
+                                       S3C2410_UDC_IN_CSR1_REG);
+                       return;
+               }
+
+               if (!(ep_csr1 & S3C2410_UDC_ICSR1_PKTRDY) && req) {
+                       s3c2410_udc_write_fifo(ep,req);
+               }
+       } else {
+               udc_write(idx, S3C2410_UDC_INDEX_REG);
+               ep_csr1 = udc_read(S3C2410_UDC_OUT_CSR1_REG);
+               dprintk(DEBUG_VERBOSE, "ep%01d rd csr:%02x\n", idx, ep_csr1);
+
+               if (ep_csr1 & S3C2410_UDC_OCSR1_SENTSTL) {
+                       udc_write(idx, S3C2410_UDC_INDEX_REG);
+                       udc_write(ep_csr1 & ~S3C2410_UDC_OCSR1_SENTSTL,
+                                       S3C2410_UDC_OUT_CSR1_REG);
+                       return;
+               }
+
+               if ((ep_csr1 & S3C2410_UDC_OCSR1_PKTRDY) && req) {
+                       s3c2410_udc_read_fifo(ep,req);
+               }
+       }
+}
+
+#include <asm/arch/regs-irq.h>
+
+/*
+ *     s3c2410_udc_irq - interrupt handler
+ */
+static irqreturn_t s3c2410_udc_irq(int irq, void *_dev)
+{
+       struct s3c2410_udc *dev = _dev;
+       int usb_status;
+       int usbd_status;
+       int pwr_reg;
+       int ep0csr;
+       int i;
+       u32 idx;
+       unsigned long flags;
+
+       spin_lock_irqsave(&dev->lock, flags);
+
+       /* Driver connected ? */
+       if (!dev->driver) {
+               /* Clear interrupts */
+               udc_write(udc_read(S3C2410_UDC_USB_INT_REG),
+                               S3C2410_UDC_USB_INT_REG);
+               udc_write(udc_read(S3C2410_UDC_EP_INT_REG),
+                               S3C2410_UDC_EP_INT_REG);
+       }
+
+       /* Save index */
+       idx = udc_read(S3C2410_UDC_INDEX_REG);
+
+       /* Read status registers */
+       usb_status = udc_read(S3C2410_UDC_USB_INT_REG);
+       usbd_status = udc_read(S3C2410_UDC_EP_INT_REG);
+       pwr_reg = udc_read(S3C2410_UDC_PWR_REG);
+
+       udc_writeb(base_addr, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG);
+       ep0csr = udc_read(S3C2410_UDC_IN_CSR1_REG);
+
+       dprintk(DEBUG_NORMAL, "usbs=%02x, usbds=%02x, pwr=%02x ep0csr=%02x\n",
+               usb_status, usbd_status, pwr_reg, ep0csr);
+
+       /*
+        * Now, handle interrupts. There's two types :
+        * - Reset, Resume, Suspend coming -> usb_int_reg
+        * - EP -> ep_int_reg
+        */
+
+       /* RESET */
+       if (usb_status & S3C2410_UDC_USBINT_RESET) {
+               /* two kind of reset :
+                * - reset start -> pwr reg = 8
+                * - reset end   -> pwr reg = 0
+                **/
+               dprintk(DEBUG_NORMAL, "USB reset csr %x pwr %x\n",
+                       ep0csr, pwr_reg);
+
+               dev->gadget.speed = USB_SPEED_UNKNOWN;
+               udc_write(0x00, S3C2410_UDC_INDEX_REG);
+               udc_write((dev->ep[0].ep.maxpacket & 0x7ff) >> 3,
+                               S3C2410_UDC_MAXP_REG);
+               dev->address = 0;
+
+               dev->ep0state = EP0_IDLE;
+               dev->gadget.speed = USB_SPEED_FULL;
+
+               /* clear interrupt */
+               udc_write(S3C2410_UDC_USBINT_RESET,
+                               S3C2410_UDC_USB_INT_REG);
+
+               udc_write(idx, S3C2410_UDC_INDEX_REG);
+               spin_unlock_irqrestore(&dev->lock, flags);
+               return IRQ_HANDLED;
+       }
+
+       /* RESUME */
+       if (usb_status & S3C2410_UDC_USBINT_RESUME) {
+               dprintk(DEBUG_NORMAL, "USB resume\n");
+
+               /* clear interrupt */
+               udc_write(S3C2410_UDC_USBINT_RESUME,
+                               S3C2410_UDC_USB_INT_REG);
+
+               if (dev->gadget.speed != USB_SPEED_UNKNOWN
+                               && dev->driver
+                               && dev->driver->resume)
+                       dev->driver->resume(&dev->gadget);
+       }
+
+       /* SUSPEND */
+       if (usb_status & S3C2410_UDC_USBINT_SUSPEND) {
+               dprintk(DEBUG_NORMAL, "USB suspend\n");
+
+               /* clear interrupt */
+               udc_write(S3C2410_UDC_USBINT_SUSPEND,
+                               S3C2410_UDC_USB_INT_REG);
+
+               if (dev->gadget.speed != USB_SPEED_UNKNOWN
+                               && dev->driver
+                               && dev->driver->suspend)
+                       dev->driver->suspend(&dev->gadget);
+
+               dev->ep0state = EP0_IDLE;
+       }
+
+       /* EP */
+       /* control traffic */
+       /* check on ep0csr != 0 is not a good idea as clearing in_pkt_ready
+        * generate an interrupt
+        */
+       if (usbd_status & S3C2410_UDC_INT_EP0) {
+               dprintk(DEBUG_VERBOSE, "USB ep0 irq\n");
+               /* Clear the interrupt bit by setting it to 1 */
+               udc_write(S3C2410_UDC_INT_EP0, S3C2410_UDC_EP_INT_REG);
+               s3c2410_udc_handle_ep0(dev);
+       }
+
+       /* endpoint data transfers */
+       for (i = 1; i < S3C2410_ENDPOINTS; i++) {
+               u32 tmp = 1 << i;
+               if (usbd_status & tmp) {
+                       dprintk(DEBUG_VERBOSE, "USB ep%d irq\n", i);
+
+                       /* Clear the interrupt bit by setting it to 1 */
+                       udc_write(tmp, S3C2410_UDC_EP_INT_REG);
+                       s3c2410_udc_handle_ep(&dev->ep[i]);
+               }
+       }
+
+       dprintk(DEBUG_VERBOSE, "irq: %d s3c2410_udc_done.\n", irq);
+
+       /* Restore old index */
+       udc_write(idx, S3C2410_UDC_INDEX_REG);
+
+       spin_unlock_irqrestore(&dev->lock, flags);
+
+       return IRQ_HANDLED;
+}
+/*------------------------- s3c2410_ep_ops ----------------------------------*/
+
+static inline struct s3c2410_ep *to_s3c2410_ep(struct usb_ep *ep)
+{
+       return container_of(ep, struct s3c2410_ep, ep);
+}
+
+static inline struct s3c2410_udc *to_s3c2410_udc(struct usb_gadget *gadget)
+{
+       return container_of(gadget, struct s3c2410_udc, gadget);
+}
+
+static inline struct s3c2410_request *to_s3c2410_req(struct usb_request *req)
+{
+       return container_of(req, struct s3c2410_request, req);
+}
+
+/*
+ *     s3c2410_udc_ep_enable
+ */
+static int s3c2410_udc_ep_enable(struct usb_ep *_ep,
+                                const struct usb_endpoint_descriptor *desc)
+{
+       struct s3c2410_udc      *dev;
+       struct s3c2410_ep       *ep;
+       u32                     max, tmp;
+       unsigned long           flags;
+       u32                     csr1,csr2;
+       u32                     int_en_reg;
+
+       ep = to_s3c2410_ep(_ep);
+
+       if (!_ep || !desc || ep->desc
+                       || _ep->name == ep0name
+                       || desc->bDescriptorType != USB_DT_ENDPOINT)
+               return -EINVAL;
+
+       dev = ep->dev;
+       if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)
+               return -ESHUTDOWN;
+
+       max = le16_to_cpu(desc->wMaxPacketSize) & 0x1fff;
+
+       local_irq_save (flags);
+       _ep->maxpacket = max & 0x7ff;
+       ep->desc = desc;
+       ep->halted = 0;
+       ep->bEndpointAddress = desc->bEndpointAddress;
+
+       /* set max packet */
+       udc_write(ep->num, S3C2410_UDC_INDEX_REG);
+       udc_write(max >> 3, S3C2410_UDC_MAXP_REG);
+
+       /* set type, direction, address; reset fifo counters */
+       if (desc->bEndpointAddress & USB_DIR_IN) {
+               csr1 = S3C2410_UDC_ICSR1_FFLUSH|S3C2410_UDC_ICSR1_CLRDT;
+               csr2 = S3C2410_UDC_ICSR2_MODEIN|S3C2410_UDC_ICSR2_DMAIEN;
+
+               udc_write(ep->num, S3C2410_UDC_INDEX_REG);
+               udc_write(csr1, S3C2410_UDC_IN_CSR1_REG);
+               udc_write(ep->num, S3C2410_UDC_INDEX_REG);
+               udc_write(csr2, S3C2410_UDC_IN_CSR2_REG);
+       } else {
+               /* don't flush in fifo or it will cause endpoint interrupt */
+               csr1 = S3C2410_UDC_ICSR1_CLRDT;
+               csr2 = S3C2410_UDC_ICSR2_DMAIEN;
+
+               udc_write(ep->num, S3C2410_UDC_INDEX_REG);
+               udc_write(csr1, S3C2410_UDC_IN_CSR1_REG);
+               udc_write(ep->num, S3C2410_UDC_INDEX_REG);
+               udc_write(csr2, S3C2410_UDC_IN_CSR2_REG);
+
+               csr1 = S3C2410_UDC_OCSR1_FFLUSH | S3C2410_UDC_OCSR1_CLRDT;
+               csr2 = S3C2410_UDC_OCSR2_DMAIEN;
+
+               udc_write(ep->num, S3C2410_UDC_INDEX_REG);
+               udc_write(csr1, S3C2410_UDC_OUT_CSR1_REG);
+               udc_write(ep->num, S3C2410_UDC_INDEX_REG);
+               udc_write(csr2, S3C2410_UDC_OUT_CSR2_REG);
+       }
+
+       /* enable irqs */
+       int_en_reg = udc_read(S3C2410_UDC_EP_INT_EN_REG);
+       udc_write(int_en_reg | (1 << ep->num), S3C2410_UDC_EP_INT_EN_REG);
+
+       /* print some debug message */
+       tmp = desc->bEndpointAddress;
+       dprintk (DEBUG_NORMAL, "enable %s(%d) ep%x%s-blk max %02x\n",
+                _ep->name,ep->num, tmp,
+                desc->bEndpointAddress & USB_DIR_IN ? "in" : "out", max);
+
+       local_irq_restore (flags);
+       s3c2410_udc_set_halt(_ep, 0);
+
+       return 0;
+}
+
+/*
+ * s3c2410_udc_ep_disable
+ */
+static int s3c2410_udc_ep_disable(struct usb_ep *_ep)
+{
+       struct s3c2410_ep *ep = to_s3c2410_ep(_ep);
+       unsigned long flags;
+       u32 int_en_reg;
+
+       if (!_ep || !ep->desc) {
+               dprintk(DEBUG_NORMAL, "%s not enabled\n",
+                       _ep ? ep->ep.name : NULL);
+               return -EINVAL;
+       }
+
+       local_irq_save(flags);
+
+       dprintk(DEBUG_NORMAL, "ep_disable: %s\n", _ep->name);
+
+       ep->desc = NULL;
+       ep->halted = 1;
+
+       s3c2410_udc_nuke (ep->dev, ep, -ESHUTDOWN);
+
+       /* disable irqs */
+       int_en_reg = udc_read(S3C2410_UDC_EP_INT_EN_REG);
+       udc_write(int_en_reg & ~(1<<ep->num), S3C2410_UDC_EP_INT_EN_REG);
+
+       local_irq_restore(flags);
+
+       dprintk(DEBUG_NORMAL, "%s disabled\n", _ep->name);
+
+       return 0;
+}
+
+/*
+ * s3c2410_udc_alloc_request
+ */
+static struct usb_request *
+s3c2410_udc_alloc_request(struct usb_ep *_ep, gfp_t mem_flags)
+{
+       struct s3c2410_request *req;
+
+       dprintk(DEBUG_VERBOSE,"%s(%p,%d)\n", __func__, _ep, mem_flags);
+
+       if (!_ep)
+               return NULL;
+
+       req = kzalloc (sizeof(struct s3c2410_request), mem_flags);
+       if (!req)
+               return NULL;
+
+       INIT_LIST_HEAD (&req->queue);
+       return &req->req;
+}
+
+/*
+ * s3c2410_udc_free_request
+ */
+static void
+s3c2410_udc_free_request(struct usb_ep *_ep, struct usb_request *_req)
+{
+       struct s3c2410_ep       *ep = to_s3c2410_ep(_ep);
+       struct s3c2410_request  *req = to_s3c2410_req(_req);
+
+       dprintk(DEBUG_VERBOSE, "%s(%p,%p)\n", __func__, _ep, _req);
+
+       if (!ep || !_req || (!ep->desc && _ep->name != ep0name))
+               return;
+
+       WARN_ON (!list_empty (&req->queue));
+       kfree(req);
+}
+
+/*
+ *     s3c2410_udc_queue
+ */
+static int s3c2410_udc_queue(struct usb_ep *_ep, struct usb_request *_req,
+               gfp_t gfp_flags)
+{
+       struct s3c2410_request  *req = to_s3c2410_req(_req);
+       struct s3c2410_ep       *ep = to_s3c2410_ep(_ep);
+       struct s3c2410_udc      *dev;
+       u32                     ep_csr = 0;
+       int                     fifo_count = 0;
+       unsigned long           flags;
+
+       if (unlikely (!_ep || (!ep->desc && ep->ep.name != ep0name))) {
+               dprintk(DEBUG_NORMAL, "%s: invalid args\n", __func__);
+               return -EINVAL;
+       }
+
+       dev = ep->dev;
+       if (unlikely (!dev->driver
+                       || dev->gadget.speed == USB_SPEED_UNKNOWN)) {
+               return -ESHUTDOWN;
+       }
+
+       local_irq_save (flags);
+
+       if (unlikely(!_req || !_req->complete
+                       || !_req->buf || !list_empty(&req->queue))) {
+               if (!_req)
+                       dprintk(DEBUG_NORMAL, "%s: 1 X X X\n", __func__);
+               else {
+                       dprintk(DEBUG_NORMAL, "%s: 0 %01d %01d %01d\n",
+                               __func__, !_req->complete,!_req->buf,
+                               !list_empty(&req->queue));
+               }
+
+               local_irq_restore(flags);
+               return -EINVAL;
+       }
+
+       _req->status = -EINPROGRESS;
+       _req->actual = 0;
+
+       dprintk(DEBUG_VERBOSE, "%s: ep%x len %d\n",
+                __func__, ep->bEndpointAddress, _req->length);
+
+       if (ep->bEndpointAddress) {
+               udc_write(ep->bEndpointAddress & 0x7F, S3C2410_UDC_INDEX_REG);
+
+               ep_csr = udc_read((ep->bEndpointAddress & USB_DIR_IN)
+                               ? S3C2410_UDC_IN_CSR1_REG
+                               : S3C2410_UDC_OUT_CSR1_REG);
+               fifo_count = s3c2410_udc_fifo_count_out();
+       } else {
+               udc_write(0, S3C2410_UDC_INDEX_REG);
+               ep_csr = udc_read(S3C2410_UDC_IN_CSR1_REG);
+               fifo_count = s3c2410_udc_fifo_count_out();
+       }
+
+       /* kickstart this i/o queue? */
+       if (list_empty(&ep->queue) && !ep->halted) {
+               if (ep->bEndpointAddress == 0 /* ep0 */) {
+                       switch (dev->ep0state) {
+                       case EP0_IN_DATA_PHASE:
+                               if (!(ep_csr&S3C2410_UDC_EP0_CSR_IPKRDY)
+                                               && s3c2410_udc_write_fifo(ep,
+                                                       req)) {
+                                       dev->ep0state = EP0_IDLE;
+                                       req = NULL;
+                               }
+                               break;
+
+                       case EP0_OUT_DATA_PHASE:
+                               if ((!_req->length)
+                                       || ((ep_csr & S3C2410_UDC_OCSR1_PKTRDY)
+                                               && s3c2410_udc_read_fifo(ep,
+                                                       req))) {
+                                       dev->ep0state = EP0_IDLE;
+                                       req = NULL;
+                               }
+                               break;
+
+                       default:
+                               local_irq_restore(flags);
+                               return -EL2HLT;
+                       }
+               } else if ((ep->bEndpointAddress & USB_DIR_IN) != 0
+                               && (!(ep_csr&S3C2410_UDC_OCSR1_PKTRDY))
+                               && s3c2410_udc_write_fifo(ep, req)) {
+                       req = NULL;
+               } else if ((ep_csr & S3C2410_UDC_OCSR1_PKTRDY)
+                               && fifo_count
+                               && s3c2410_udc_read_fifo(ep, req)) {
+                       req = NULL;
+               }
+       }
+
+       /* pio or dma irq handler advances the queue. */
+       if (likely (req != 0))
+               list_add_tail(&req->queue, &ep->queue);
+
+       local_irq_restore(flags);
+
+       dprintk(DEBUG_VERBOSE, "%s ok\n", __func__);
+       return 0;
+}
+
+/*
+ *     s3c2410_udc_dequeue
+ */
+static int s3c2410_udc_dequeue(struct usb_ep *_ep, struct usb_request *_req)
+{
+       struct s3c2410_ep       *ep = to_s3c2410_ep(_ep);
+       struct s3c2410_udc      *udc;
+       int                     retval = -EINVAL;
+       unsigned long           flags;
+       struct s3c2410_request  *req = NULL;
+
+       dprintk(DEBUG_VERBOSE, "%s(%p,%p)\n", __func__, _ep, _req);
+
+       if (!the_controller->driver)
+               return -ESHUTDOWN;
+
+       if (!_ep || !_req)
+               return retval;
+
+       udc = to_s3c2410_udc(ep->gadget);
+
+       local_irq_save (flags);
+
+       list_for_each_entry (req, &ep->queue, queue) {
+               if (&req->req == _req) {
+                       list_del_init (&req->queue);
+                       _req->status = -ECONNRESET;
+                       retval = 0;
+                       break;
+               }
+       }
+
+       if (retval == 0) {
+               dprintk(DEBUG_VERBOSE,
+                       "dequeued req %p from %s, len %d buf %p\n",
+                       req, _ep->name, _req->length, _req->buf);
+
+               s3c2410_udc_done(ep, req, -ECONNRESET);
+       }
+
+       local_irq_restore (flags);
+       return retval;
+}
+
+/*
+ * s3c2410_udc_set_halt
+ */
+static int s3c2410_udc_set_halt(struct usb_ep *_ep, int value)
+{
+       struct s3c2410_ep       *ep = to_s3c2410_ep(_ep);
+       u32                     ep_csr = 0;
+       unsigned long           flags;
+       u32                     idx;
+
+       if (unlikely (!_ep || (!ep->desc && ep->ep.name != ep0name))) {
+               dprintk(DEBUG_NORMAL, "%s: inval 2\n", __func__);
+               return -EINVAL;
+       }
+
+       local_irq_save (flags);
+
+       idx = ep->bEndpointAddress & 0x7F;
+
+       if (idx == 0) {
+               s3c2410_udc_set_ep0_ss(base_addr);
+               s3c2410_udc_set_ep0_de_out(base_addr);
+       } else {
+               udc_write(idx, S3C2410_UDC_INDEX_REG);
+               ep_csr = udc_read((ep->bEndpointAddress &USB_DIR_IN)
+                               ? S3C2410_UDC_IN_CSR1_REG
+                               : S3C2410_UDC_OUT_CSR1_REG);
+
+               if ((ep->bEndpointAddress & USB_DIR_IN) != 0) {
+                       if (value)
+                               udc_write(ep_csr | S3C2410_UDC_ICSR1_SENDSTL,
+                                       S3C2410_UDC_IN_CSR1_REG);
+                       else {
+                               ep_csr &= ~S3C2410_UDC_ICSR1_SENDSTL;
+                               udc_write(ep_csr, S3C2410_UDC_IN_CSR1_REG);
+                               ep_csr |= S3C2410_UDC_ICSR1_CLRDT;
+                               udc_write(ep_csr, S3C2410_UDC_IN_CSR1_REG);
+                       }
+               } else {
+                       if (value)
+                               udc_write(ep_csr | S3C2410_UDC_OCSR1_SENDSTL,
+                                       S3C2410_UDC_OUT_CSR1_REG);
+                       else {
+                               ep_csr &= ~S3C2410_UDC_OCSR1_SENDSTL;
+                               udc_write(ep_csr, S3C2410_UDC_OUT_CSR1_REG);
+                               ep_csr |= S3C2410_UDC_OCSR1_CLRDT;
+                               udc_write(ep_csr, S3C2410_UDC_OUT_CSR1_REG);
+                       }
+               }
+       }
+
+       ep->halted = value ? 1 : 0;
+       local_irq_restore (flags);
+
+       return 0;
+}
+
+static const struct usb_ep_ops s3c2410_ep_ops = {
+       .enable         = s3c2410_udc_ep_enable,
+       .disable        = s3c2410_udc_ep_disable,
+
+       .alloc_request  = s3c2410_udc_alloc_request,
+       .free_request   = s3c2410_udc_free_request,
+
+       .queue          = s3c2410_udc_queue,
+       .dequeue        = s3c2410_udc_dequeue,
+
+       .set_halt       = s3c2410_udc_set_halt,
+};
+
+/*------------------------- usb_gadget_ops ----------------------------------*/
+
+/*
+ *     s3c2410_udc_get_frame
+ */
+static int s3c2410_udc_get_frame(struct usb_gadget *_gadget)
+{
+       int tmp;
+
+       dprintk(DEBUG_VERBOSE, "%s()\n", __func__);
+
+       tmp = udc_read(S3C2410_UDC_FRAME_NUM2_REG) << 8;
+       tmp |= udc_read(S3C2410_UDC_FRAME_NUM1_REG);
+       return tmp;
+}
+
+/*
+ *     s3c2410_udc_wakeup
+ */
+static int s3c2410_udc_wakeup(struct usb_gadget *_gadget)
+{
+       dprintk(DEBUG_NORMAL, "%s()\n", __func__);
+       return 0;
+}
+
+/*
+ *     s3c2410_udc_set_selfpowered
+ */
+static int s3c2410_udc_set_selfpowered(struct usb_gadget *gadget, int value)
+{
+       struct s3c2410_udc *udc = to_s3c2410_udc(gadget);
+
+       dprintk(DEBUG_NORMAL, "%s()\n", __func__);
+
+       if (value)
+               udc->devstatus |= (1 << USB_DEVICE_SELF_POWERED);
+       else
+               udc->devstatus &= ~(1 << USB_DEVICE_SELF_POWERED);
+
+       return 0;
+}
+
+static void s3c2410_udc_disable(struct s3c2410_udc *dev);
+static void s3c2410_udc_enable(struct s3c2410_udc *dev);
+
+static int s3c2410_udc_set_pullup(struct s3c2410_udc *udc, int is_on)
+{
+       dprintk(DEBUG_NORMAL, "%s()\n", __func__);
+
+       if (udc_info && udc_info->udc_command) {
+               if (is_on)
+                       s3c2410_udc_enable(udc);
+               else {
+                       if (udc->gadget.speed != USB_SPEED_UNKNOWN) {
+                               if (udc->driver && udc->driver->disconnect)
+                                       udc->driver->disconnect(&udc->gadget);
+
+                       }
+                       s3c2410_udc_disable(udc);
+               }
+       }
+       else
+               return -EOPNOTSUPP;
+
+       return 0;
+}
+
+static int s3c2410_udc_vbus_session(struct usb_gadget *gadget, int is_active)
+{
+       struct s3c2410_udc *udc = to_s3c2410_udc(gadget);
+
+       dprintk(DEBUG_NORMAL, "%s()\n", __func__);
+
+       udc->vbus = (is_active != 0);
+       s3c2410_udc_set_pullup(udc, is_active);
+       return 0;
+}
+
+static int s3c2410_udc_pullup(struct usb_gadget *gadget, int is_on)
+{
+       struct s3c2410_udc *udc = to_s3c2410_udc(gadget);
+
+       dprintk(DEBUG_NORMAL, "%s()\n", __func__);
+
+       s3c2410_udc_set_pullup(udc, is_on ? 0 : 1);
+       return 0;
+}
+
+static irqreturn_t s3c2410_udc_vbus_irq(int irq, void *_dev)
+{
+       struct s3c2410_udc      *dev = _dev;
+       unsigned int            value;
+
+       dprintk(DEBUG_NORMAL, "%s()\n", __func__);
+       value = s3c2410_gpio_getpin(udc_info->vbus_pin);
+
+       if (udc_info->vbus_pin_inverted)
+               value = !value;
+
+       if (value != dev->vbus)
+               s3c2410_udc_vbus_session(&dev->gadget, value);
+
+       return IRQ_HANDLED;
+}
+
+static int s3c2410_vbus_draw(struct usb_gadget *_gadget, unsigned ma)
+{
+       dprintk(DEBUG_NORMAL, "%s()\n", __func__);
+
+       if (udc_info && udc_info->vbus_draw) {
+               udc_info->vbus_draw(ma);
+               return 0;
+       }
+
+       return -ENOTSUPP;
+}
+
+static const struct usb_gadget_ops s3c2410_ops = {
+       .get_frame              = s3c2410_udc_get_frame,
+       .wakeup                 = s3c2410_udc_wakeup,
+       .set_selfpowered        = s3c2410_udc_set_selfpowered,
+       .pullup                 = s3c2410_udc_pullup,
+       .vbus_session           = s3c2410_udc_vbus_session,
+       .vbus_draw              = s3c2410_vbus_draw,
+};
+
+/*------------------------- gadget driver handling---------------------------*/
+/*
+ * s3c2410_udc_disable
+ */
+static void s3c2410_udc_disable(struct s3c2410_udc *dev)
+{
+       dprintk(DEBUG_NORMAL, "%s()\n", __func__);
+
+       /* Disable all interrupts */
+       udc_write(0x00, S3C2410_UDC_USB_INT_EN_REG);
+       udc_write(0x00, S3C2410_UDC_EP_INT_EN_REG);
+
+       /* Clear the interrupt registers */
+       udc_write(S3C2410_UDC_USBINT_RESET
+                               | S3C2410_UDC_USBINT_RESUME
+                               | S3C2410_UDC_USBINT_SUSPEND,
+                       S3C2410_UDC_USB_INT_REG);
+
+       udc_write(0x1F, S3C2410_UDC_EP_INT_REG);
+
+       /* Good bye, cruel world */
+       if (udc_info && udc_info->udc_command)
+               udc_info->udc_command(S3C2410_UDC_P_DISABLE);
+
+       /* Set speed to unknown */
+       dev->gadget.speed = USB_SPEED_UNKNOWN;
+}
+
+/*
+ * s3c2410_udc_reinit
+ */
+static void s3c2410_udc_reinit(struct s3c2410_udc *dev)
+{
+       u32 i;
+
+       /* device/ep0 records init */
+       INIT_LIST_HEAD (&dev->gadget.ep_list);
+       INIT_LIST_HEAD (&dev->gadget.ep0->ep_list);
+       dev->ep0state = EP0_IDLE;
+
+       for (i = 0; i < S3C2410_ENDPOINTS; i++) {
+               struct s3c2410_ep *ep = &dev->ep[i];
+
+               if (i != 0)
+                       list_add_tail (&ep->ep.ep_list, &dev->gadget.ep_list);
+
+               ep->dev = dev;
+               ep->desc = NULL;
+               ep->halted = 0;
+               INIT_LIST_HEAD (&ep->queue);
+       }
+}
+
+/*
+ * s3c2410_udc_enable
+ */
+static void s3c2410_udc_enable(struct s3c2410_udc *dev)
+{
+       int i;
+
+       dprintk(DEBUG_NORMAL, "s3c2410_udc_enable called\n");
+
+       /* dev->gadget.speed = USB_SPEED_UNKNOWN; */
+       dev->gadget.speed = USB_SPEED_FULL;
+
+       /* Set MAXP for all endpoints */
+       for (i = 0; i < S3C2410_ENDPOINTS; i++) {
+               udc_write(i, S3C2410_UDC_INDEX_REG);
+               udc_write((dev->ep[i].ep.maxpacket & 0x7ff) >> 3,
+                               S3C2410_UDC_MAXP_REG);
+       }
+
+       /* Set default power state */
+       udc_write(DEFAULT_POWER_STATE, S3C2410_UDC_PWR_REG);
+
+       /* Enable reset and suspend interrupt interrupts */
+       udc_write(S3C2410_UDC_USBINT_RESET | S3C2410_UDC_USBINT_SUSPEND,
+                       S3C2410_UDC_USB_INT_EN_REG);
+
+       /* Enable ep0 interrupt */
+       udc_write(S3C2410_UDC_INT_EP0, S3C2410_UDC_EP_INT_EN_REG);
+
+       /* time to say "hello, world" */
+       if (udc_info && udc_info->udc_command)
+               udc_info->udc_command(S3C2410_UDC_P_ENABLE);
+}
+
+/*
+ *     usb_gadget_register_driver
+ */
+int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+{
+       struct s3c2410_udc *udc = the_controller;
+       int             retval;
+
+       dprintk(DEBUG_NORMAL, "usb_gadget_register_driver() '%s'\n",
+               driver->driver.name);
+
+       /* Sanity checks */
+       if (!udc)
+               return -ENODEV;
+
+       if (udc->driver)
+               return -EBUSY;
+
+       if (!driver->bind || !driver->setup
+                       || driver->speed != USB_SPEED_FULL) {
+               printk(KERN_ERR "Invalid driver: bind %p setup %p speed %d\n",
+                       driver->bind, driver->setup, driver->speed);
+               return -EINVAL;
+       }
+#if defined(MODULE)
+       if (!driver->unbind) {
+               printk(KERN_ERR "Invalid driver: no unbind method\n");
+               return -EINVAL;
+       }
+#endif
+
+       /* Hook the driver */
+       udc->driver = driver;
+       udc->gadget.dev.driver = &driver->driver;
+
+       /* Bind the driver */
+       if ((retval = device_add(&udc->gadget.dev)) != 0) {
+               printk(KERN_ERR "Error in device_add() : %d\n",retval);
+               goto register_error;
+       }
+
+       dprintk(DEBUG_NORMAL, "binding gadget driver '%s'\n",
+               driver->driver.name);
+
+       if ((retval = driver->bind (&udc->gadget)) != 0) {
+               device_del(&udc->gadget.dev);
+               goto register_error;
+       }
+
+       /* Enable udc */
+       s3c2410_udc_enable(udc);
+
+       return 0;
+
+register_error:
+       udc->driver = NULL;
+       udc->gadget.dev.driver = NULL;
+       return retval;
+}
+
+/*
+ *     usb_gadget_unregister_driver
+ */
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+{
+       struct s3c2410_udc *udc = the_controller;
+
+       if (!udc)
+               return -ENODEV;
+
+       if (!driver || driver != udc->driver || !driver->unbind)
+               return -EINVAL;
+
+       dprintk(DEBUG_NORMAL,"usb_gadget_register_driver() '%s'\n",
+               driver->driver.name);
+
+       if (driver->disconnect)
+               driver->disconnect(&udc->gadget);
+
+       device_del(&udc->gadget.dev);
+       udc->driver = NULL;
+
+       /* Disable udc */
+       s3c2410_udc_disable(udc);
+
+       return 0;
+}
+
+/*---------------------------------------------------------------------------*/
+static struct s3c2410_udc memory = {
+       .gadget = {
+               .ops            = &s3c2410_ops,
+               .ep0            = &memory.ep[0].ep,
+               .name           = gadget_name,
+               .dev = {
+                       .bus_id         = "gadget",
+               },
+       },
+
+       /* control endpoint */
+       .ep[0] = {
+               .num            = 0,
+               .ep = {
+                       .name           = ep0name,
+                       .ops            = &s3c2410_ep_ops,
+                       .maxpacket      = EP0_FIFO_SIZE,
+               },
+               .dev            = &memory,
+       },
+
+       /* first group of endpoints */
+       .ep[1] = {
+               .num            = 1,
+               .ep = {
+                       .name           = "ep1-bulk",
+                       .ops            = &s3c2410_ep_ops,
+                       .maxpacket      = EP_FIFO_SIZE,
+               },
+               .dev            = &memory,
+               .fifo_size      = EP_FIFO_SIZE,
+               .bEndpointAddress = 1,
+               .bmAttributes   = USB_ENDPOINT_XFER_BULK,
+       },
+       .ep[2] = {
+               .num            = 2,
+               .ep = {
+                       .name           = "ep2-bulk",
+                       .ops            = &s3c2410_ep_ops,
+                       .maxpacket      = EP_FIFO_SIZE,
+               },
+               .dev            = &memory,
+               .fifo_size      = EP_FIFO_SIZE,
+               .bEndpointAddress = 2,
+               .bmAttributes   = USB_ENDPOINT_XFER_BULK,
+       },
+       .ep[3] = {
+               .num            = 3,
+               .ep = {
+                       .name           = "ep3-bulk",
+                       .ops            = &s3c2410_ep_ops,
+                       .maxpacket      = EP_FIFO_SIZE,
+               },
+               .dev            = &memory,
+               .fifo_size      = EP_FIFO_SIZE,
+               .bEndpointAddress = 3,
+               .bmAttributes   = USB_ENDPOINT_XFER_BULK,
+       },
+       .ep[4] = {
+               .num            = 4,
+               .ep = {
+                       .name           = "ep4-bulk",
+                       .ops            = &s3c2410_ep_ops,
+                       .maxpacket      = EP_FIFO_SIZE,
+               },
+               .dev            = &memory,
+               .fifo_size      = EP_FIFO_SIZE,
+               .bEndpointAddress = 4,
+               .bmAttributes   = USB_ENDPOINT_XFER_BULK,
+       }
+
+};
+
+/*
+ *     probe - binds to the platform device
+ */
+static int s3c2410_udc_probe(struct platform_device *pdev)
+{
+       struct s3c2410_udc *udc = &memory;
+       struct device *dev = &pdev->dev;
+       int retval;
+       unsigned int irq;
+
+       dev_dbg(dev, "%s()\n", __func__);
+
+       usb_bus_clock = clk_get(NULL, "usb-bus-gadget");
+       if (IS_ERR(usb_bus_clock)) {
+               dev_err(dev, "failed to get usb bus clock source\n");
+               return PTR_ERR(usb_bus_clock);
+       }
+
+       clk_enable(usb_bus_clock);
+
+       udc_clock = clk_get(NULL, "usb-device");
+       if (IS_ERR(udc_clock)) {
+               dev_err(dev, "failed to get udc clock source\n");
+               return PTR_ERR(udc_clock);
+       }
+
+       clk_enable(udc_clock);
+
+       mdelay(10);
+
+       dev_dbg(dev, "got and enabled clocks\n");
+
+       if (strncmp(pdev->name, "s3c2440", 7) == 0) {
+               dev_info(dev, "S3C2440: increasing FIFO to 128 bytes\n");
+               memory.ep[1].fifo_size = S3C2440_EP_FIFO_SIZE;
+               memory.ep[2].fifo_size = S3C2440_EP_FIFO_SIZE;
+               memory.ep[3].fifo_size = S3C2440_EP_FIFO_SIZE;
+               memory.ep[4].fifo_size = S3C2440_EP_FIFO_SIZE;
+       }
+
+       spin_lock_init (&udc->lock);
+       udc_info = pdev->dev.platform_data;
+
+       rsrc_start = S3C2410_PA_USBDEV;
+       rsrc_len   = S3C24XX_SZ_USBDEV;
+
+       if (!request_mem_region(rsrc_start, rsrc_len, gadget_name))
+               return -EBUSY;
+
+       base_addr = ioremap(rsrc_start, rsrc_len);
+       if (!base_addr) {
+               retval = -ENOMEM;
+               goto err_mem;
+       }
+
+       device_initialize(&udc->gadget.dev);
+       udc->gadget.dev.parent = &pdev->dev;
+       udc->gadget.dev.dma_mask = pdev->dev.dma_mask;
+
+       the_controller = udc;
+       platform_set_drvdata(pdev, udc);
+
+       s3c2410_udc_disable(udc);
+       s3c2410_udc_reinit(udc);
+
+       /* irq setup after old hardware state is cleaned up */
+       retval = request_irq(IRQ_USBD, s3c2410_udc_irq,
+                       IRQF_DISABLED, gadget_name, udc);
+
+       if (retval != 0) {
+               dev_err(dev, "cannot get irq %i, err %d\n", IRQ_USBD, retval);
+               retval = -EBUSY;
+               goto err_map;
+       }
+
+       dev_dbg(dev, "got irq %i\n", IRQ_USBD);
+
+       if (udc_info && udc_info->vbus_pin > 0) {
+               irq = s3c2410_gpio_getirq(udc_info->vbus_pin);
+               retval = request_irq(irq, s3c2410_udc_vbus_irq,
+                               IRQF_DISABLED | IRQF_TRIGGER_RISING
+                               | IRQF_TRIGGER_FALLING,
+                               gadget_name, udc);
+
+               if (retval != 0) {
+                       dev_err(dev, "can't get vbus irq %i, err %d\n",
+                               irq, retval);
+                       retval = -EBUSY;
+                       goto err_int;
+               }
+
+               dev_dbg(dev, "got irq %i\n", irq);
+       } else {
+               udc->vbus = 1;
+       }
+
+       if (s3c2410_udc_debugfs_root) {
+               udc->regs_info = debugfs_create_file("registers", S_IRUGO,
+                               s3c2410_udc_debugfs_root,
+                               udc, &s3c2410_udc_debugfs_fops);
+               if (IS_ERR(udc->regs_info)) {
+                       dev_warn(dev, "debugfs file creation failed %ld\n",
+                                PTR_ERR(udc->regs_info));
+                       udc->regs_info = NULL;
+               }
+       }
+
+       dev_dbg(dev, "probe ok\n");
+
+       return 0;
+
+err_int:
+       free_irq(IRQ_USBD, udc);
+err_map:
+       iounmap(base_addr);
+err_mem:
+       release_mem_region(rsrc_start, rsrc_len);
+
+       return retval;
+}
+
+/*
+ *     s3c2410_udc_remove
+ */
+static int s3c2410_udc_remove(struct platform_device *pdev)
+{
+       struct s3c2410_udc *udc = platform_get_drvdata(pdev);
+       unsigned int irq;
+
+       dev_dbg(&pdev->dev, "%s()\n", __func__);
+       if (udc->driver)
+               return -EBUSY;
+
+       debugfs_remove(udc->regs_info);
+
+       if (udc_info && udc_info->vbus_pin > 0) {
+               irq = s3c2410_gpio_getirq(udc_info->vbus_pin);
+               free_irq(irq, udc);
+       }
+
+       free_irq(IRQ_USBD, udc);
+
+       iounmap(base_addr);
+       release_mem_region(rsrc_start, rsrc_len);
+
+       platform_set_drvdata(pdev, NULL);
+
+       if (!IS_ERR(udc_clock) && udc_clock != NULL) {
+               clk_disable(udc_clock);
+               clk_put(udc_clock);
+               udc_clock = NULL;
+       }
+
+       if (!IS_ERR(usb_bus_clock) && usb_bus_clock != NULL) {
+               clk_disable(usb_bus_clock);
+               clk_put(usb_bus_clock);
+               usb_bus_clock = NULL;
+       }
+
+       dev_dbg(&pdev->dev, "%s: remove ok\n", __func__);
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int s3c2410_udc_suspend(struct platform_device *pdev, pm_message_t message)
+{
+       if (udc_info && udc_info->udc_command)
+               udc_info->udc_command(S3C2410_UDC_P_DISABLE);
+
+       return 0;
+}
+
+static int s3c2410_udc_resume(struct platform_device *pdev)
+{
+       if (udc_info && udc_info->udc_command)
+               udc_info->udc_command(S3C2410_UDC_P_ENABLE);
+
+       return 0;
+}
+#else
+#define s3c2410_udc_suspend    NULL
+#define s3c2410_udc_resume     NULL
+#endif
+
+static struct platform_driver udc_driver_2410 = {
+       .driver         = {
+               .name   = "s3c2410-usbgadget",
+               .owner  = THIS_MODULE,
+       },
+       .probe          = s3c2410_udc_probe,
+       .remove         = s3c2410_udc_remove,
+       .suspend        = s3c2410_udc_suspend,
+       .resume         = s3c2410_udc_resume,
+};
+
+static struct platform_driver udc_driver_2440 = {
+       .driver         = {
+               .name   = "s3c2440-usbgadget",
+               .owner  = THIS_MODULE,
+       },
+       .probe          = s3c2410_udc_probe,
+       .remove         = s3c2410_udc_remove,
+       .suspend        = s3c2410_udc_suspend,
+       .resume         = s3c2410_udc_resume,
+};
+
+static int __init udc_init(void)
+{
+       int retval;
+
+       dprintk(DEBUG_NORMAL, "%s: version %s\n", gadget_name, DRIVER_VERSION);
+
+       s3c2410_udc_debugfs_root = debugfs_create_dir(gadget_name, NULL);
+       if (IS_ERR(s3c2410_udc_debugfs_root)) {
+               printk(KERN_ERR "%s: debugfs dir creation failed %ld\n",
+                       gadget_name, PTR_ERR(s3c2410_udc_debugfs_root));
+               s3c2410_udc_debugfs_root = NULL;
+       }
+
+       retval = platform_driver_register(&udc_driver_2410);
+       if (retval)
+               goto err;
+
+       retval = platform_driver_register(&udc_driver_2440);
+       if (retval)
+               goto err;
+
+       return 0;
+
+err:
+       debugfs_remove(s3c2410_udc_debugfs_root);
+       return retval;
+}
+
+static void __exit udc_exit(void)
+{
+       platform_driver_unregister(&udc_driver_2410);
+       platform_driver_unregister(&udc_driver_2440);
+       debugfs_remove(s3c2410_udc_debugfs_root);
+}
+
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
+EXPORT_SYMBOL(usb_gadget_register_driver);
+
+module_init(udc_init);
+module_exit(udc_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_VERSION(DRIVER_VERSION);
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/gadget/s3c2410_udc.h b/drivers/usb/gadget/s3c2410_udc.h
new file mode 100644 (file)
index 0000000..9e0bece
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * linux/drivers/usb/gadget/s3c2410_udc.h
+ * Samsung on-chip full speed USB device controllers
+ *
+ * Copyright (C) 2004-2007 Herbert Pötzl - Arnaud Patard
+ *     Additional cleanups by Ben Dooks <ben-linux@fluff.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef _S3C2410_UDC_H
+#define _S3C2410_UDC_H
+
+struct s3c2410_ep {
+       struct list_head                queue;
+       unsigned long                   last_io;        /* jiffies timestamp */
+       struct usb_gadget               *gadget;
+       struct s3c2410_udc              *dev;
+       const struct usb_endpoint_descriptor *desc;
+       struct usb_ep                   ep;
+       u8                              num;
+
+       unsigned short                  fifo_size;
+       u8                              bEndpointAddress;
+       u8                              bmAttributes;
+
+       unsigned                        halted : 1;
+       unsigned                        already_seen : 1;
+       unsigned                        setup_stage : 1;
+};
+
+
+/* Warning : ep0 has a fifo of 16 bytes */
+/* Don't try to set 32 or 64            */
+/* also testusb 14 fails  wit 16 but is */
+/* fine with 8                          */
+#define EP0_FIFO_SIZE           8
+#define EP_FIFO_SIZE           64
+#define DEFAULT_POWER_STATE    0x00
+
+#define S3C2440_EP_FIFO_SIZE   128
+
+static const char ep0name [] = "ep0";
+
+static const char *const ep_name[] = {
+       ep0name,                                /* everyone has ep0 */
+       /* s3c2410 four bidirectional bulk endpoints */
+       "ep1-bulk", "ep2-bulk", "ep3-bulk", "ep4-bulk",
+};
+
+#define S3C2410_ENDPOINTS       ARRAY_SIZE(ep_name)
+
+struct s3c2410_request {
+       struct list_head                queue;          /* ep's requests */
+       struct usb_request              req;
+};
+
+enum ep0_state {
+        EP0_IDLE,
+        EP0_IN_DATA_PHASE,
+        EP0_OUT_DATA_PHASE,
+        EP0_END_XFER,
+        EP0_STALL,
+};
+
+static const char *ep0states[]= {
+        "EP0_IDLE",
+        "EP0_IN_DATA_PHASE",
+        "EP0_OUT_DATA_PHASE",
+        "EP0_END_XFER",
+        "EP0_STALL",
+};
+
+struct s3c2410_udc {
+       spinlock_t                      lock;
+
+       struct s3c2410_ep               ep[S3C2410_ENDPOINTS];
+       int                             address;
+       struct usb_gadget               gadget;
+       struct usb_gadget_driver        *driver;
+       struct s3c2410_request          fifo_req;
+       u8                              fifo_buf[EP_FIFO_SIZE];
+       u16                             devstatus;
+
+       u32                             port_status;
+       int                             ep0state;
+
+       unsigned                        got_irq : 1;
+
+       unsigned                        req_std : 1;
+       unsigned                        req_config : 1;
+       unsigned                        req_pending : 1;
+       u8                              vbus;
+       struct dentry                   *regs_info;
+};
+
+#endif
index f847c3414be31ac372d42e91ed20451675b6dab1..dd33ff0ae4cecb6984b5ac503c7567d7260857fc 100644 (file)
@@ -2215,7 +2215,7 @@ static struct gs_buf *gs_buf_alloc(unsigned int size, gfp_t kmalloc_flags)
  *
  * Free the buffer and all associated memory.
  */
-void gs_buf_free(struct gs_buf *gb)
+static void gs_buf_free(struct gs_buf *gb)
 {
        if (gb) {
                kfree(gb->buf_buf);
@@ -2228,7 +2228,7 @@ void gs_buf_free(struct gs_buf *gb)
  *
  * Clear out all data in the circular buffer.
  */
-void gs_buf_clear(struct gs_buf *gb)
+static void gs_buf_clear(struct gs_buf *gb)
 {
        if (gb != NULL)
                gb->buf_get = gb->buf_put;
@@ -2241,7 +2241,7 @@ void gs_buf_clear(struct gs_buf *gb)
  * Return the number of bytes of data available in the circular
  * buffer.
  */
-unsigned int gs_buf_data_avail(struct gs_buf *gb)
+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;
@@ -2255,7 +2255,7 @@ unsigned int gs_buf_data_avail(struct gs_buf *gb)
  * Return the number of bytes of space available in the circular
  * buffer.
  */
-unsigned int gs_buf_space_avail(struct gs_buf *gb)
+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;
@@ -2271,7 +2271,8 @@ unsigned int gs_buf_space_avail(struct gs_buf *gb)
  *
  * Return the number of bytes copied.
  */
-unsigned int gs_buf_put(struct gs_buf *gb, const char *buf, unsigned int count)
+static unsigned int
+gs_buf_put(struct gs_buf *gb, const char *buf, unsigned int count)
 {
        unsigned int len;
 
@@ -2309,7 +2310,8 @@ unsigned int gs_buf_put(struct gs_buf *gb, const char *buf, unsigned int count)
  *
  * Return the number of bytes copied.
  */
-unsigned int gs_buf_get(struct gs_buf *gb, char *buf, unsigned int count)
+static unsigned int
+gs_buf_get(struct gs_buf *gb, char *buf, unsigned int count)
 {
        unsigned int len;
 
index 7078374d0b79d0ba36b5b6b297a05e412bf4302b..a2e6e3fc8c8d731b516ec3880ea3a987f3098438 100644 (file)
@@ -481,8 +481,7 @@ alloc_ep_req (struct usb_ep *ep, unsigned length)
        req = usb_ep_alloc_request (ep, GFP_ATOMIC);
        if (req) {
                req->length = length;
-               req->buf = usb_ep_alloc_buffer (ep, length,
-                               &req->dma, GFP_ATOMIC);
+               req->buf = kmalloc(length, GFP_ATOMIC);
                if (!req->buf) {
                        usb_ep_free_request (ep, req);
                        req = NULL;
@@ -493,8 +492,7 @@ alloc_ep_req (struct usb_ep *ep, unsigned length)
 
 static void free_ep_req (struct usb_ep *ep, struct usb_request *req)
 {
-       if (req->buf)
-               usb_ep_free_buffer (ep, req->buf, req->dma, req->length);
+       kfree(req->buf);
        usb_ep_free_request (ep, req);
 }
 
@@ -1199,8 +1197,7 @@ autoconf_fail:
        dev->req = usb_ep_alloc_request (gadget->ep0, GFP_KERNEL);
        if (!dev->req)
                goto enomem;
-       dev->req->buf = usb_ep_alloc_buffer (gadget->ep0, USB_BUFSIZ,
-                               &dev->req->dma, GFP_KERNEL);
+       dev->req->buf = kmalloc(USB_BUFSIZ, GFP_KERNEL);
        if (!dev->req->buf)
                goto enomem;
 
index 62711870f8ee1fd5dbb8d974ad3b2a74466c7ea5..2f529828c74d23232a0d060b8d00108e6834ccea 100644 (file)
@@ -69,8 +69,20 @@ config USB_EHCI_TT_NEWSCHED
 
 config USB_EHCI_BIG_ENDIAN_MMIO
        bool
-       depends on USB_EHCI_HCD
-       default n
+       depends on USB_EHCI_HCD && (PPC_CELLEB || PPC_PS3 || 440EPX)
+       default y
+
+config USB_EHCI_BIG_ENDIAN_DESC
+       bool
+       depends on USB_EHCI_HCD && 440EPX
+       default y
+
+config USB_EHCI_FSL
+       bool
+       select USB_EHCI_ROOT_HUB_TT
+       default y if MPC834x || PPC_MPC831x
+       ---help---
+         Variation of ARC USB block used in some Freescale chips.
 
 config USB_ISP116X_HCD
        tristate "ISP116X HCD support"
@@ -224,3 +236,15 @@ config USB_SL811_CS
          To compile this driver as a module, choose M here: the
          module will be called "sl811_cs".
 
+config USB_R8A66597_HCD
+       tristate "R8A66597 HCD suppoort"
+       depends on USB
+       help
+         The R8A66597 is a USB 2.0 host and peripheral controller.
+
+         Enable this option if your board has this chip, and you want
+         to use it as a host controller.  If unsure, say N.
+
+         To compile this driver as a module, choose M here: the
+         module will be called r8a66597-hcd.
+
index 2ff396bd180fe514fab9c83395e773db066b8209..bb8e9d44f371243c91097cae75ac3c5b931a757d 100644 (file)
@@ -15,3 +15,5 @@ obj-$(CONFIG_USB_UHCI_HCD)    += uhci-hcd.o
 obj-$(CONFIG_USB_SL811_HCD)    += sl811-hcd.o
 obj-$(CONFIG_USB_SL811_CS)     += sl811_cs.o
 obj-$(CONFIG_USB_U132_HCD)     += u132-hcd.o
+obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o
+
index 43eddaecc3dd520da48e9dcb7367157d8f7ff565..c9cc4413198e15d977a5d1e8b4d671eb2d72188a 100644 (file)
@@ -52,7 +52,7 @@ static void dbg_hcs_params (struct ehci_hcd *ehci, char *label)
                HCS_INDICATOR (params) ? " ind" : "",
                HCS_N_CC (params),
                HCS_N_PCC (params),
-               HCS_PORTROUTED (params) ? "" : " ordered",
+               HCS_PORTROUTED (params) ? "" : " ordered",
                HCS_PPC (params) ? "" : " !ppc",
                HCS_N_PORTS (params)
                );
@@ -91,20 +91,20 @@ static void dbg_hcc_params (struct ehci_hcd *ehci, char *label)
 
        if (HCC_ISOC_CACHE (params)) {
                ehci_dbg (ehci,
-                    "%s hcc_params %04x caching frame %s%s%s\n",
-                    label, params,
-                    HCC_PGM_FRAMELISTLEN (params) ? "256/512/1024" : "1024",
-                    HCC_CANPARK (params) ? " park" : "",
-                    HCC_64BIT_ADDR (params) ? " 64 bit addr" : "");
+                       "%s hcc_params %04x caching frame %s%s%s\n",
+                       label, params,
+                       HCC_PGM_FRAMELISTLEN(params) ? "256/512/1024" : "1024",
+                       HCC_CANPARK(params) ? " park" : "",
+                       HCC_64BIT_ADDR(params) ? " 64 bit addr" : "");
        } else {
                ehci_dbg (ehci,
-                    "%s hcc_params %04x thresh %d uframes %s%s%s\n",
-                    label,
-                    params,
-                    HCC_ISOC_THRES (params),
-                    HCC_PGM_FRAMELISTLEN (params) ? "256/512/1024" : "1024",
-                    HCC_CANPARK (params) ? " park" : "",
-                    HCC_64BIT_ADDR (params) ? " 64 bit addr" : "");
+                       "%s hcc_params %04x thresh %d uframes %s%s%s\n",
+                       label,
+                       params,
+                       HCC_ISOC_THRES(params),
+                       HCC_PGM_FRAMELISTLEN(params) ? "256/512/1024" : "1024",
+                       HCC_CANPARK(params) ? " park" : "",
+                       HCC_64BIT_ADDR(params) ? " 64 bit addr" : "");
        }
 }
 #else
@@ -115,23 +115,23 @@ static inline void dbg_hcc_params (struct ehci_hcd *ehci, char *label) {}
 
 #ifdef DEBUG
 
-static void __attribute__((__unused__))
+static void __maybe_unused
 dbg_qtd (const char *label, struct ehci_hcd *ehci, struct ehci_qtd *qtd)
 {
-       ehci_dbg (ehci, "%s td %p n%08x %08x t%08x p0=%08x\n", label, qtd,
-               le32_to_cpup (&qtd->hw_next),
-               le32_to_cpup (&qtd->hw_alt_next),
-               le32_to_cpup (&qtd->hw_token),
-               le32_to_cpup (&qtd->hw_buf [0]));
+       ehci_dbg(ehci, "%s td %p n%08x %08x t%08x p0=%08x\n", label, qtd,
+               hc32_to_cpup(ehci, &qtd->hw_next),
+               hc32_to_cpup(ehci, &qtd->hw_alt_next),
+               hc32_to_cpup(ehci, &qtd->hw_token),
+               hc32_to_cpup(ehci, &qtd->hw_buf [0]));
        if (qtd->hw_buf [1])
-               ehci_dbg (ehci, "  p1=%08x p2=%08x p3=%08x p4=%08x\n",
-                       le32_to_cpup (&qtd->hw_buf [1]),
-                       le32_to_cpup (&qtd->hw_buf [2]),
-                       le32_to_cpup (&qtd->hw_buf [3]),
-                       le32_to_cpup (&qtd->hw_buf [4]));
+               ehci_dbg(ehci, "  p1=%08x p2=%08x p3=%08x p4=%08x\n",
+                       hc32_to_cpup(ehci, &qtd->hw_buf[1]),
+                       hc32_to_cpup(ehci, &qtd->hw_buf[2]),
+                       hc32_to_cpup(ehci, &qtd->hw_buf[3]),
+                       hc32_to_cpup(ehci, &qtd->hw_buf[4]));
 }
 
-static void __attribute__((__unused__))
+static void __maybe_unused
 dbg_qh (const char *label, struct ehci_hcd *ehci, struct ehci_qh *qh)
 {
        ehci_dbg (ehci, "%s qh %p n%08x info %x %x qtd %x\n", label,
@@ -140,51 +140,53 @@ dbg_qh (const char *label, struct ehci_hcd *ehci, struct ehci_qh *qh)
        dbg_qtd ("overlay", ehci, (struct ehci_qtd *) &qh->hw_qtd_next);
 }
 
-static void __attribute__((__unused__))
+static void __maybe_unused
 dbg_itd (const char *label, struct ehci_hcd *ehci, struct ehci_itd *itd)
 {
        ehci_dbg (ehci, "%s [%d] itd %p, next %08x, urb %p\n",
-               label, itd->frame, itd, le32_to_cpu(itd->hw_next), itd->urb);
+               label, itd->frame, itd, hc32_to_cpu(ehci, itd->hw_next),
+               itd->urb);
        ehci_dbg (ehci,
                "  trans: %08x %08x %08x %08x %08x %08x %08x %08x\n",
-               le32_to_cpu(itd->hw_transaction[0]),
-               le32_to_cpu(itd->hw_transaction[1]),
-               le32_to_cpu(itd->hw_transaction[2]),
-               le32_to_cpu(itd->hw_transaction[3]),
-               le32_to_cpu(itd->hw_transaction[4]),
-               le32_to_cpu(itd->hw_transaction[5]),
-               le32_to_cpu(itd->hw_transaction[6]),
-               le32_to_cpu(itd->hw_transaction[7]));
+               hc32_to_cpu(ehci, itd->hw_transaction[0]),
+               hc32_to_cpu(ehci, itd->hw_transaction[1]),
+               hc32_to_cpu(ehci, itd->hw_transaction[2]),
+               hc32_to_cpu(ehci, itd->hw_transaction[3]),
+               hc32_to_cpu(ehci, itd->hw_transaction[4]),
+               hc32_to_cpu(ehci, itd->hw_transaction[5]),
+               hc32_to_cpu(ehci, itd->hw_transaction[6]),
+               hc32_to_cpu(ehci, itd->hw_transaction[7]));
        ehci_dbg (ehci,
                "  buf:   %08x %08x %08x %08x %08x %08x %08x\n",
-               le32_to_cpu(itd->hw_bufp[0]),
-               le32_to_cpu(itd->hw_bufp[1]),
-               le32_to_cpu(itd->hw_bufp[2]),
-               le32_to_cpu(itd->hw_bufp[3]),
-               le32_to_cpu(itd->hw_bufp[4]),
-               le32_to_cpu(itd->hw_bufp[5]),
-               le32_to_cpu(itd->hw_bufp[6]));
+               hc32_to_cpu(ehci, itd->hw_bufp[0]),
+               hc32_to_cpu(ehci, itd->hw_bufp[1]),
+               hc32_to_cpu(ehci, itd->hw_bufp[2]),
+               hc32_to_cpu(ehci, itd->hw_bufp[3]),
+               hc32_to_cpu(ehci, itd->hw_bufp[4]),
+               hc32_to_cpu(ehci, itd->hw_bufp[5]),
+               hc32_to_cpu(ehci, itd->hw_bufp[6]));
        ehci_dbg (ehci, "  index: %d %d %d %d %d %d %d %d\n",
                itd->index[0], itd->index[1], itd->index[2],
                itd->index[3], itd->index[4], itd->index[5],
                itd->index[6], itd->index[7]);
 }
 
-static void __attribute__((__unused__))
+static void __maybe_unused
 dbg_sitd (const char *label, struct ehci_hcd *ehci, struct ehci_sitd *sitd)
 {
        ehci_dbg (ehci, "%s [%d] sitd %p, next %08x, urb %p\n",
-               label, sitd->frame, sitd, le32_to_cpu(sitd->hw_next), sitd->urb);
+               label, sitd->frame, sitd, hc32_to_cpu(ehci, sitd->hw_next),
+               sitd->urb);
        ehci_dbg (ehci,
                "  addr %08x sched %04x result %08x buf %08x %08x\n",
-               le32_to_cpu(sitd->hw_fullspeed_ep),
-               le32_to_cpu(sitd->hw_uframe),
-               le32_to_cpu(sitd->hw_results),
-               le32_to_cpu(sitd->hw_buf [0]),
-               le32_to_cpu(sitd->hw_buf [1]));
+               hc32_to_cpu(ehci, sitd->hw_fullspeed_ep),
+               hc32_to_cpu(ehci, sitd->hw_uframe),
+               hc32_to_cpu(ehci, sitd->hw_results),
+               hc32_to_cpu(ehci, sitd->hw_buf[0]),
+               hc32_to_cpu(ehci, sitd->hw_buf[1]));
 }
 
-static int __attribute__((__unused__))
+static int __maybe_unused
 dbg_status_buf (char *buf, unsigned len, const char *label, u32 status)
 {
        return scnprintf (buf, len,
@@ -203,7 +205,7 @@ dbg_status_buf (char *buf, unsigned len, const char *label, u32 status)
                );
 }
 
-static int __attribute__((__unused__))
+static int __maybe_unused
 dbg_intr_buf (char *buf, unsigned len, const char *label, u32 enable)
 {
        return scnprintf (buf, len,
@@ -267,28 +269,27 @@ dbg_port_buf (char *buf, unsigned len, const char *label, int port, u32 status)
                (status & PORT_PEC) ? " PEC" : "",
                (status & PORT_PE) ? " PE" : "",
                (status & PORT_CSC) ? " CSC" : "",
-               (status & PORT_CONNECT) ? " CONNECT" : ""
-           );
+               (status & PORT_CONNECT) ? " CONNECT" : "");
 }
 
 #else
-static inline void __attribute__((__unused__))
+static inline void __maybe_unused
 dbg_qh (char *label, struct ehci_hcd *ehci, struct ehci_qh *qh)
 {}
 
-static inline int __attribute__((__unused__))
+static inline int __maybe_unused
 dbg_status_buf (char *buf, unsigned len, const char *label, u32 status)
 { return 0; }
 
-static inline int __attribute__((__unused__))
+static inline int __maybe_unused
 dbg_command_buf (char *buf, unsigned len, const char *label, u32 command)
 { return 0; }
 
-static inline int __attribute__((__unused__))
+static inline int __maybe_unused
 dbg_intr_buf (char *buf, unsigned len, const char *label, u32 enable)
 { return 0; }
 
-static inline int __attribute__((__unused__))
+static inline int __maybe_unused
 dbg_port_buf (char *buf, unsigned len, const char *label, int port, u32 status)
 { return 0; }
 
@@ -332,9 +333,10 @@ static inline void remove_debug_files (struct ehci_hcd *bus) { }
                default: tmp = '?'; break; \
                }; tmp; })
 
-static inline char token_mark (__le32 token)
+static inline char token_mark(struct ehci_hcd *ehci, __hc32 token)
 {
-       __u32 v = le32_to_cpu (token);
+       __u32 v = hc32_to_cpu(ehci, token);
+
        if (v & QTD_STS_ACTIVE)
                return '*';
        if (v & QTD_STS_HALT)
@@ -360,46 +362,48 @@ static void qh_lines (
        unsigned                size = *sizep;
        char                    *next = *nextp;
        char                    mark;
+       u32                     list_end = EHCI_LIST_END(ehci);
 
-       if (qh->hw_qtd_next == EHCI_LIST_END)   /* NEC does this */
+       if (qh->hw_qtd_next == list_end)        /* NEC does this */
                mark = '@';
        else
-               mark = token_mark (qh->hw_token);
+               mark = token_mark(ehci, qh->hw_token);
        if (mark == '/') {      /* qh_alt_next controls qh advance? */
-               if ((qh->hw_alt_next & QTD_MASK) == ehci->async->hw_alt_next)
+               if ((qh->hw_alt_next & QTD_MASK(ehci))
+                               == ehci->async->hw_alt_next)
                        mark = '#';     /* blocked */
-               else if (qh->hw_alt_next == EHCI_LIST_END)
+               else if (qh->hw_alt_next == list_end)
                        mark = '.';     /* use hw_qtd_next */
                /* else alt_next points to some other qtd */
        }
-       scratch = le32_to_cpup (&qh->hw_info1);
-       hw_curr = (mark == '*') ? le32_to_cpup (&qh->hw_current) : 0;
+       scratch = hc32_to_cpup(ehci, &qh->hw_info1);
+       hw_curr = (mark == '*') ? hc32_to_cpup(ehci, &qh->hw_current) : 0;
        temp = scnprintf (next, size,
                        "qh/%p dev%d %cs ep%d %08x %08x (%08x%c %s nak%d)",
                        qh, scratch & 0x007f,
                        speed_char (scratch),
                        (scratch >> 8) & 0x000f,
-                       scratch, le32_to_cpup (&qh->hw_info2),
-                       le32_to_cpup (&qh->hw_token), mark,
-                       (__constant_cpu_to_le32 (QTD_TOGGLE) & qh->hw_token)
+                       scratch, hc32_to_cpup(ehci, &qh->hw_info2),
+                       hc32_to_cpup(ehci, &qh->hw_token), mark,
+                       (cpu_to_hc32(ehci, QTD_TOGGLE) & qh->hw_token)
                                ? "data1" : "data0",
-                       (le32_to_cpup (&qh->hw_alt_next) >> 1) & 0x0f);
+                       (hc32_to_cpup(ehci, &qh->hw_alt_next) >> 1) & 0x0f);
        size -= temp;
        next += temp;
 
        /* hc may be modifying the list as we read it ... */
        list_for_each (entry, &qh->qtd_list) {
                td = list_entry (entry, struct ehci_qtd, qtd_list);
-               scratch = le32_to_cpup (&td->hw_token);
+               scratch = hc32_to_cpup(ehci, &td->hw_token);
                mark = ' ';
                if (hw_curr == td->qtd_dma)
                        mark = '*';
-               else if (qh->hw_qtd_next == cpu_to_le32(td->qtd_dma))
+               else if (qh->hw_qtd_next == cpu_to_hc32(ehci, td->qtd_dma))
                        mark = '+';
                else if (QTD_LENGTH (scratch)) {
                        if (td->hw_alt_next == ehci->async->hw_alt_next)
                                mark = '#';
-                       else if (td->hw_alt_next != EHCI_LIST_END)
+                       else if (td->hw_alt_next != list_end)
                                mark = '/';
                }
                temp = snprintf (next, size,
@@ -490,7 +494,7 @@ show_periodic (struct class_device *class_dev, char *buf)
        unsigned                temp, size, seen_count;
        char                    *next;
        unsigned                i;
-       __le32                  tag;
+       __hc32                  tag;
 
        if (!(seen = kmalloc (DBG_SCHED_LIMIT * sizeof *seen, GFP_ATOMIC)))
                return 0;
@@ -514,18 +518,19 @@ show_periodic (struct class_device *class_dev, char *buf)
                p = ehci->pshadow [i];
                if (likely (!p.ptr))
                        continue;
-               tag = Q_NEXT_TYPE (ehci->periodic [i]);
+               tag = Q_NEXT_TYPE(ehci, ehci->periodic [i]);
 
                temp = scnprintf (next, size, "%4d: ", i);
                size -= temp;
                next += temp;
 
                do {
-                       switch (tag) {
+                       switch (hc32_to_cpu(ehci, tag)) {
                        case Q_TYPE_QH:
                                temp = scnprintf (next, size, " qh%d-%04x/%p",
                                                p.qh->period,
-                                               le32_to_cpup (&p.qh->hw_info2)
+                                               hc32_to_cpup(ehci,
+                                                               &p.qh->hw_info2)
                                                        /* uframe masks */
                                                        & (QH_CMASK | QH_SMASK),
                                                p.qh);
@@ -543,7 +548,7 @@ show_periodic (struct class_device *class_dev, char *buf)
                                }
                                /* show more info the first time around */
                                if (temp == seen_count && p.ptr) {
-                                       u32     scratch = le32_to_cpup (
+                                       u32     scratch = hc32_to_cpup(ehci,
                                                        &p.qh->hw_info1);
                                        struct ehci_qtd *qtd;
                                        char            *type = "";
@@ -554,7 +559,8 @@ show_periodic (struct class_device *class_dev, char *buf)
                                                        &p.qh->qtd_list,
                                                        qtd_list) {
                                                temp++;
-                                               switch (0x03 & (le32_to_cpu (
+                                               switch (0x03 & (hc32_to_cpu(
+                                                       ehci,
                                                        qtd->hw_token) >> 8)) {
                                                case 0: type = "out"; continue;
                                                case 1: type = "in"; continue;
@@ -576,7 +582,7 @@ show_periodic (struct class_device *class_dev, char *buf)
                                } else
                                        temp = 0;
                                if (p.qh) {
-                                       tag = Q_NEXT_TYPE (p.qh->hw_next);
+                                       tag = Q_NEXT_TYPE(ehci, p.qh->hw_next);
                                        p = p.qh->qh_next;
                                }
                                break;
@@ -584,23 +590,23 @@ show_periodic (struct class_device *class_dev, char *buf)
                                temp = scnprintf (next, size,
                                        " fstn-%8x/%p", p.fstn->hw_prev,
                                        p.fstn);
-                               tag = Q_NEXT_TYPE (p.fstn->hw_next);
+                               tag = Q_NEXT_TYPE(ehci, p.fstn->hw_next);
                                p = p.fstn->fstn_next;
                                break;
                        case Q_TYPE_ITD:
                                temp = scnprintf (next, size,
                                        " itd/%p", p.itd);
-                               tag = Q_NEXT_TYPE (p.itd->hw_next);
+                               tag = Q_NEXT_TYPE(ehci, p.itd->hw_next);
                                p = p.itd->itd_next;
                                break;
                        case Q_TYPE_SITD:
                                temp = scnprintf (next, size,
                                        " sitd%d-%04x/%p",
                                        p.sitd->stream->interval,
-                                       le32_to_cpup (&p.sitd->hw_uframe)
+                                       hc32_to_cpup(ehci, &p.sitd->hw_uframe)
                                                & 0x0000ffff,
                                        p.sitd);
-                               tag = Q_NEXT_TYPE (p.sitd->hw_next);
+                               tag = Q_NEXT_TYPE(ehci, p.sitd->hw_next);
                                p = p.sitd->sitd_next;
                                break;
                        }
@@ -673,7 +679,8 @@ show_registers (struct class_device *class_dev, char *buf)
                unsigned        count = 256/4;
 
                pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller);
-               offset = HCC_EXT_CAPS (ehci_readl(ehci, &ehci->caps->hcc_params));
+               offset = HCC_EXT_CAPS(ehci_readl(ehci,
+                               &ehci->caps->hcc_params));
                while (offset && count--) {
                        pci_read_config_dword (pdev, offset, &cap);
                        switch (cap & 0xff) {
@@ -740,14 +747,16 @@ show_registers (struct class_device *class_dev, char *buf)
 
        for (i = 1; i <= HCS_N_PORTS (ehci->hcs_params); i++) {
                temp = dbg_port_buf (scratch, sizeof scratch, label, i,
-                               ehci_readl(ehci, &ehci->regs->port_status [i - 1]));
+                               ehci_readl(ehci,
+                                       &ehci->regs->port_status[i - 1]));
                temp = scnprintf (next, size, fmt, temp, scratch);
                size -= temp;
                next += temp;
                if (i == HCS_DEBUG_PORT(ehci->hcs_params) && ehci->debug) {
                        temp = scnprintf (next, size,
                                        "    debug control %08x\n",
-                                       ehci_readl(ehci, &ehci->debug->control));
+                                       ehci_readl(ehci,
+                                               &ehci->debug->control));
                        size -= temp;
                        next += temp;
                }
index c7a7c590426fd2d54812a46f45a6a495a22b0ca2..b7b7bfbce527e057c7f509d0260b98609a7eeca5 100644 (file)
@@ -67,7 +67,8 @@ int usb_hcd_fsl_probe(const struct hc_driver *driver,
         * in host mode.
         */
        if (!((pdata->operating_mode == FSL_USB2_DR_HOST) ||
-             (pdata->operating_mode == FSL_USB2_MPH_HOST))) {
+             (pdata->operating_mode == FSL_USB2_MPH_HOST) ||
+             (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);
@@ -185,12 +186,14 @@ static void mpc83xx_usb_setup(struct usb_hcd *hcd)
        struct ehci_hcd *ehci = hcd_to_ehci(hcd);
        struct fsl_usb2_platform_data *pdata;
        void __iomem *non_ehci = hcd->regs;
+       u32 temp;
 
        pdata =
            (struct fsl_usb2_platform_data *)hcd->self.controller->
            platform_data;
        /* Enable PHY interface in the control reg. */
-       out_be32(non_ehci + FSL_SOC_USB_CTRL, 0x00000004);
+       temp = in_be32(non_ehci + FSL_SOC_USB_CTRL);
+       out_be32(non_ehci + FSL_SOC_USB_CTRL, temp | 0x00000004);
        out_be32(non_ehci + FSL_SOC_USB_SNOOP1, 0x0000001b);
 
 #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
@@ -206,7 +209,8 @@ static void mpc83xx_usb_setup(struct usb_hcd *hcd)
        out_be32(non_ehci + FSL_SOC_USB_SNOOP2, 0x80000000 | SNOOP_SIZE_2GB);
 #endif
 
-       if (pdata->operating_mode == FSL_USB2_DR_HOST)
+       if ((pdata->operating_mode == FSL_USB2_DR_HOST) ||
+                       (pdata->operating_mode == FSL_USB2_DR_OTG))
                mpc83xx_setup_phy(ehci, pdata->phy_mode, 0);
 
        if (pdata->operating_mode == FSL_USB2_MPH_HOST) {
index 099aff64f5361de4cb87c25bb37e8f45d3afbd98..c4e15ed1405a96eaa85003ae796ba316b37f9714 100644 (file)
 #include <asm/irq.h>
 #include <asm/system.h>
 #include <asm/unaligned.h>
-#ifdef CONFIG_PPC_PS3
-#include <asm/firmware.h>
-#endif
-
 
 /*-------------------------------------------------------------------------*/
 
@@ -201,9 +197,15 @@ static void tdi_reset (struct ehci_hcd *ehci)
        u32 __iomem     *reg_ptr;
        u32             tmp;
 
-       reg_ptr = (u32 __iomem *)(((u8 __iomem *)ehci->regs) + 0x68);
+       reg_ptr = (u32 __iomem *)(((u8 __iomem *)ehci->regs) + USBMODE);
        tmp = ehci_readl(ehci, reg_ptr);
-       tmp |= 0x3;
+       tmp |= USBMODE_CM_HC;
+       /* The default byte access to MMR space is LE after
+        * controller reset. Set the required endian mode
+        * for transfer buffers to match the host microprocessor
+        */
+       if (ehci_big_endian_mmio(ehci))
+               tmp |= USBMODE_BE;
        ehci_writel(ehci, tmp, reg_ptr);
 }
 
@@ -273,6 +275,58 @@ static void ehci_work(struct ehci_hcd *ehci);
 
 /*-------------------------------------------------------------------------*/
 
+#ifdef CONFIG_CPU_FREQ
+
+#include <linux/cpufreq.h>
+
+static void ehci_cpufreq_pause (struct ehci_hcd *ehci)
+{
+       unsigned long   flags;
+
+       spin_lock_irqsave(&ehci->lock, flags);
+       if (!ehci->cpufreq_changing++)
+               qh_inactivate_split_intr_qhs(ehci);
+       spin_unlock_irqrestore(&ehci->lock, flags);
+}
+
+static void ehci_cpufreq_unpause (struct ehci_hcd *ehci)
+{
+       unsigned long   flags;
+
+       spin_lock_irqsave(&ehci->lock, flags);
+       if (!--ehci->cpufreq_changing)
+               qh_reactivate_split_intr_qhs(ehci);
+       spin_unlock_irqrestore(&ehci->lock, flags);
+}
+
+/*
+ * ehci_cpufreq_notifier is needed to avoid MMF errors that occur when
+ * EHCI controllers that don't cache many uframes get delayed trying to
+ * read main memory during CPU frequency transitions.  This can cause
+ * split interrupt transactions to not be completed in the required uframe.
+ * This has been observed on the Broadcom/ServerWorks HT1000 controller.
+ */
+static int ehci_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
+                                void *data)
+{
+       struct ehci_hcd *ehci = container_of(nb, struct ehci_hcd,
+                                            cpufreq_transition);
+
+       switch (val) {
+       case CPUFREQ_PRECHANGE:
+               ehci_cpufreq_pause(ehci);
+               break;
+       case CPUFREQ_POSTCHANGE:
+               ehci_cpufreq_unpause(ehci);
+               break;
+       }
+       return 0;
+}
+
+#endif
+
+/*-------------------------------------------------------------------------*/
+
 static void ehci_watchdog (unsigned long param)
 {
        struct ehci_hcd         *ehci = (struct ehci_hcd *) param;
@@ -347,6 +401,8 @@ static void ehci_port_power (struct ehci_hcd *ehci, int is_on)
                                is_on ? SetPortFeature : ClearPortFeature,
                                USB_PORT_FEAT_POWER,
                                port--, NULL, 0);
+       /* Flush those writes */
+       ehci_readl(ehci, &ehci->regs->command);
        msleep(20);
 }
 
@@ -404,6 +460,10 @@ static void ehci_stop (struct usb_hcd *hcd)
        ehci_writel(ehci, 0, &ehci->regs->intr_enable);
        spin_unlock_irq(&ehci->lock);
 
+#ifdef CONFIG_CPU_FREQ
+       cpufreq_unregister_notifier(&ehci->cpufreq_transition,
+                                   CPUFREQ_TRANSITION_NOTIFIER);
+#endif
        /* let companion controllers work when we aren't */
        ehci_writel(ehci, 0, &ehci->regs->configured_flag);
 
@@ -470,12 +530,12 @@ static int ehci_init(struct usb_hcd *hcd)
         * from automatically advancing to the next td after short reads.
         */
        ehci->async->qh_next.qh = NULL;
-       ehci->async->hw_next = QH_NEXT(ehci->async->qh_dma);
-       ehci->async->hw_info1 = cpu_to_le32(QH_HEAD);
-       ehci->async->hw_token = cpu_to_le32(QTD_STS_HALT);
-       ehci->async->hw_qtd_next = EHCI_LIST_END;
+       ehci->async->hw_next = QH_NEXT(ehci, ehci->async->qh_dma);
+       ehci->async->hw_info1 = cpu_to_hc32(ehci, QH_HEAD);
+       ehci->async->hw_token = cpu_to_hc32(ehci, QTD_STS_HALT);
+       ehci->async->hw_qtd_next = EHCI_LIST_END(ehci);
        ehci->async->qh_state = QH_STATE_LINKED;
-       ehci->async->hw_alt_next = QTD_NEXT(ehci->async->dummy->qtd_dma);
+       ehci->async->hw_alt_next = QTD_NEXT(ehci, ehci->async->dummy->qtd_dma);
 
        /* clear interrupt enables, set irq latency */
        if (log2_irq_thresh < 0 || log2_irq_thresh > 6)
@@ -509,6 +569,17 @@ static int ehci_init(struct usb_hcd *hcd)
        }
        ehci->command = temp;
 
+#ifdef CONFIG_CPU_FREQ
+       INIT_LIST_HEAD(&ehci->split_intr_qhs);
+       /*
+        * If the EHCI controller caches enough uframes, this probably
+        * isn't needed unless there are so many low/full speed devices
+        * that the controller's can't cache it all.
+        */
+       ehci->cpufreq_transition.notifier_call = ehci_cpufreq_notifier;
+       cpufreq_register_notifier(&ehci->cpufreq_transition,
+                                 CPUFREQ_TRANSITION_NOTIFIER);
+#endif
        return 0;
 }
 
@@ -925,7 +996,7 @@ MODULE_LICENSE ("GPL");
 #define        PCI_DRIVER              ehci_pci_driver
 #endif
 
-#ifdef CONFIG_MPC834x
+#ifdef CONFIG_USB_EHCI_FSL
 #include "ehci-fsl.c"
 #define        PLATFORM_DRIVER         ehci_fsl_driver
 #endif
@@ -937,7 +1008,12 @@ MODULE_LICENSE ("GPL");
 
 #ifdef CONFIG_PPC_PS3
 #include "ehci-ps3.c"
-#define        PS3_SYSTEM_BUS_DRIVER   ps3_ehci_sb_driver
+#define        PS3_SYSTEM_BUS_DRIVER   ps3_ehci_driver
+#endif
+
+#ifdef CONFIG_440EPX
+#include "ehci-ppc-soc.c"
+#define        PLATFORM_DRIVER         ehci_ppc_soc_driver
 #endif
 
 #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
@@ -971,18 +1047,15 @@ static int __init ehci_hcd_init(void)
 #endif
 
 #ifdef PS3_SYSTEM_BUS_DRIVER
-       if (firmware_has_feature(FW_FEATURE_PS3_LV1)) {
-               retval = ps3_system_bus_driver_register(
-                               &PS3_SYSTEM_BUS_DRIVER);
-               if (retval < 0) {
+       retval = ps3_ehci_driver_register(&PS3_SYSTEM_BUS_DRIVER);
+       if (retval < 0) {
 #ifdef PLATFORM_DRIVER
-                       platform_driver_unregister(&PLATFORM_DRIVER);
+               platform_driver_unregister(&PLATFORM_DRIVER);
 #endif
 #ifdef PCI_DRIVER
-                       pci_unregister_driver(&PCI_DRIVER);
+               pci_unregister_driver(&PCI_DRIVER);
 #endif
-                       return retval;
-               }
+               return retval;
        }
 #endif
 
@@ -999,8 +1072,7 @@ static void __exit ehci_hcd_cleanup(void)
        pci_unregister_driver(&PCI_DRIVER);
 #endif
 #ifdef PS3_SYSTEM_BUS_DRIVER
-       if (firmware_has_feature(FW_FEATURE_PS3_LV1))
-               ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
+       ps3_ehci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
 #endif
 }
 module_exit(ehci_hcd_cleanup);
index f4d301bc83b9c8bf82d6a434fa2833f6aa3b1b13..0dcb4164dc8368a9187b670c2a303c39cfdfa109 100644 (file)
 
 /*-------------------------------------------------------------------------*/
 
+#ifdef CONFIG_USB_PERSIST
+
+static int ehci_hub_control(
+       struct usb_hcd  *hcd,
+       u16             typeReq,
+       u16             wValue,
+       u16             wIndex,
+       char            *buf,
+       u16             wLength
+);
+
+/* After a power loss, ports that were owned by the companion must be
+ * reset so that the companion can still own them.
+ */
+static void ehci_handover_companion_ports(struct ehci_hcd *ehci)
+{
+       u32 __iomem     *reg;
+       u32             status;
+       int             port;
+       __le32          buf;
+       struct usb_hcd  *hcd = ehci_to_hcd(ehci);
+
+       if (!ehci->owned_ports)
+               return;
+
+       /* Give the connections some time to appear */
+       msleep(20);
+
+       port = HCS_N_PORTS(ehci->hcs_params);
+       while (port--) {
+               if (test_bit(port, &ehci->owned_ports)) {
+                       reg = &ehci->regs->port_status[port];
+                       status = ehci_readl(ehci, reg) & ~PORT_RWC_BITS;
+
+                       /* Port already owned by companion? */
+                       if (status & PORT_OWNER)
+                               clear_bit(port, &ehci->owned_ports);
+                       else if (test_bit(port, &ehci->companion_ports))
+                               ehci_writel(ehci, status & ~PORT_PE, reg);
+                       else
+                               ehci_hub_control(hcd, SetPortFeature,
+                                               USB_PORT_FEAT_RESET, port + 1,
+                                               NULL, 0);
+               }
+       }
+
+       if (!ehci->owned_ports)
+               return;
+       msleep(90);             /* Wait for resets to complete */
+
+       port = HCS_N_PORTS(ehci->hcs_params);
+       while (port--) {
+               if (test_bit(port, &ehci->owned_ports)) {
+                       ehci_hub_control(hcd, GetPortStatus,
+                                       0, port + 1,
+                                       (char *) &buf, sizeof(buf));
+
+                       /* The companion should now own the port,
+                        * but if something went wrong the port must not
+                        * remain enabled.
+                        */
+                       reg = &ehci->regs->port_status[port];
+                       status = ehci_readl(ehci, reg) & ~PORT_RWC_BITS;
+                       if (status & PORT_OWNER)
+                               ehci_writel(ehci, status | PORT_CSC, reg);
+                       else {
+                               ehci_dbg(ehci, "failed handover port %d: %x\n",
+                                               port + 1, status);
+                               ehci_writel(ehci, status & ~PORT_PE, reg);
+                       }
+               }
+       }
+
+       ehci->owned_ports = 0;
+}
+
+#else  /* CONFIG_USB_PERSIST */
+
+static inline void ehci_handover_companion_ports(struct ehci_hcd *ehci)
+{ }
+
+#endif
+
 #ifdef CONFIG_PM
 
 static int ehci_bus_suspend (struct usb_hcd *hcd)
@@ -60,14 +143,16 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
         * then manually resume them in the bus_resume() routine.
         */
        ehci->bus_suspended = 0;
+       ehci->owned_ports = 0;
        while (port--) {
                u32 __iomem     *reg = &ehci->regs->port_status [port];
                u32             t1 = ehci_readl(ehci, reg) & ~PORT_RWC_BITS;
                u32             t2 = t1;
 
                /* keep track of which ports we suspend */
-               if ((t1 & PORT_PE) && !(t1 & PORT_OWNER) &&
-                               !(t1 & PORT_SUSPEND)) {
+               if (t1 & PORT_OWNER)
+                       set_bit(port, &ehci->owned_ports);
+               else if ((t1 & PORT_PE) && !(t1 & PORT_SUSPEND)) {
                        t2 |= PORT_SUSPEND;
                        set_bit(port, &ehci->bus_suspended);
                }
@@ -108,11 +193,16 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
 {
        struct ehci_hcd         *ehci = hcd_to_ehci (hcd);
        u32                     temp;
+       u32                     power_okay;
        int                     i;
 
        if (time_before (jiffies, ehci->next_statechange))
                msleep(5);
        spin_lock_irq (&ehci->lock);
+       if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
+               spin_unlock_irq(&ehci->lock);
+               return -ESHUTDOWN;
+       }
 
        /* Ideally and we've got a real resume here, and no port's power
         * was lost.  (For PCI, that means Vaux was maintained.)  But we
@@ -120,8 +210,9 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
         * the last user of the controller, not reset/pm hardware keeping
         * state we gave to it.
         */
-       temp = ehci_readl(ehci, &ehci->regs->intr_enable);
-       ehci_dbg(ehci, "resume root hub%s\n", temp ? "" : " after power loss");
+       power_okay = ehci_readl(ehci, &ehci->regs->intr_enable);
+       ehci_dbg(ehci, "resume root hub%s\n",
+                       power_okay ? "" : " after power loss");
 
        /* at least some APM implementations will try to deliver
         * IRQs right away, so delay them until we're ready.
@@ -184,6 +275,9 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
        ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable);
 
        spin_unlock_irq (&ehci->lock);
+
+       if (!power_okay)
+               ehci_handover_companion_ports(ehci);
        return 0;
 }
 
@@ -448,7 +542,8 @@ static int ehci_hub_control (
 ) {
        struct ehci_hcd *ehci = hcd_to_ehci (hcd);
        int             ports = HCS_N_PORTS (ehci->hcs_params);
-       u32 __iomem     *status_reg = &ehci->regs->port_status[wIndex - 1];
+       u32 __iomem     *status_reg = &ehci->regs->port_status[
+                               (wIndex & 0xff) - 1];
        u32             temp, status;
        unsigned long   flags;
        int             retval = 0;
@@ -556,9 +651,24 @@ static int ehci_hub_control (
                        status |= 1 << USB_PORT_FEAT_C_CONNECTION;
                if (temp & PORT_PEC)
                        status |= 1 << USB_PORT_FEAT_C_ENABLE;
-               if ((temp & PORT_OCC) && !ignore_oc)
+
+               if ((temp & PORT_OCC) && !ignore_oc){
                        status |= 1 << USB_PORT_FEAT_C_OVER_CURRENT;
 
+                       /*
+                        * Hubs should disable port power on over-current.
+                        * However, not all EHCI implementations do this
+                        * automatically, even if they _do_ support per-port
+                        * power switching; they're allowed to just limit the
+                        * current.  khubd will turn the power back on.
+                        */
+                       if (HCS_PPC (ehci->hcs_params)){
+                               ehci_writel(ehci,
+                                       temp & ~(PORT_RWC_BITS | PORT_POWER),
+                                       status_reg);
+                       }
+               }
+
                /* whoever resumes must GetPortStatus to complete it!! */
                if (temp & PORT_RESUME) {
 
index a8ba2e1497a4fb6d9f7b46bc6068b0cc6fd56371..8816d09903d0b11317e1ddcbaacc479158365c1d 100644 (file)
@@ -27,7 +27,7 @@
  *       need to use dma_pool or dma_alloc_coherent
  *     - driver buffers, read/written by HC ... single shot DMA mapped
  *
- * There's also PCI "register" data, which is memory mapped.
+ * There's also "register" data (e.g. PCI or SOC), which is memory mapped.
  * No memory seen by this driver is pageable.
  */
 
 
 /* Allocate the key transfer structures from the previously allocated pool */
 
-static inline void ehci_qtd_init (struct ehci_qtd *qtd, dma_addr_t dma)
+static inline void ehci_qtd_init(struct ehci_hcd *ehci, struct ehci_qtd *qtd,
+                                 dma_addr_t dma)
 {
        memset (qtd, 0, sizeof *qtd);
        qtd->qtd_dma = dma;
        qtd->hw_token = cpu_to_le32 (QTD_STS_HALT);
-       qtd->hw_next = EHCI_LIST_END;
-       qtd->hw_alt_next = EHCI_LIST_END;
+       qtd->hw_next = EHCI_LIST_END(ehci);
+       qtd->hw_alt_next = EHCI_LIST_END(ehci);
        INIT_LIST_HEAD (&qtd->qtd_list);
 }
 
@@ -52,7 +53,7 @@ static struct ehci_qtd *ehci_qtd_alloc (struct ehci_hcd *ehci, gfp_t flags)
 
        qtd = dma_pool_alloc (ehci->qtd_pool, flags, &dma);
        if (qtd != NULL) {
-               ehci_qtd_init (qtd, dma);
+               ehci_qtd_init(ehci, qtd, dma);
        }
        return qtd;
 }
@@ -63,9 +64,8 @@ static inline void ehci_qtd_free (struct ehci_hcd *ehci, struct ehci_qtd *qtd)
 }
 
 
-static void qh_destroy (struct kref *kref)
+static void qh_destroy(struct ehci_qh *qh)
 {
-       struct ehci_qh *qh = container_of(kref, struct ehci_qh, kref);
        struct ehci_hcd *ehci = qh->ehci;
 
        /* clean qtds first, and know this is not linked */
@@ -89,11 +89,14 @@ static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags)
                return qh;
 
        memset (qh, 0, sizeof *qh);
-       kref_init(&qh->kref);
+       qh->refcount = 1;
        qh->ehci = ehci;
        qh->qh_dma = dma;
        // INIT_LIST_HEAD (&qh->qh_list);
        INIT_LIST_HEAD (&qh->qtd_list);
+#ifdef CONFIG_CPU_FREQ
+       INIT_LIST_HEAD (&qh->split_intr_qhs);
+#endif
 
        /* dummy td enables safe urb queuing */
        qh->dummy = ehci_qtd_alloc (ehci, flags);
@@ -108,13 +111,15 @@ static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags)
 /* to share a qh (cpu threads, or hc) */
 static inline struct ehci_qh *qh_get (struct ehci_qh *qh)
 {
-       kref_get(&qh->kref);
+       WARN_ON(!qh->refcount);
+       qh->refcount++;
        return qh;
 }
 
 static inline void qh_put (struct ehci_qh *qh)
 {
-       kref_put(&qh->kref, qh_destroy);
+       if (!--qh->refcount)
+               qh_destroy(qh);
 }
 
 /*-------------------------------------------------------------------------*/
@@ -217,7 +222,7 @@ static int ehci_mem_init (struct ehci_hcd *ehci, gfp_t flags)
                goto fail;
        }
        for (i = 0; i < ehci->periodic_size; i++)
-               ehci->periodic [i] = EHCI_LIST_END;
+               ehci->periodic [i] = EHCI_LIST_END(ehci);
 
        /* software shadow of hardware table */
        ehci->pshadow = kcalloc(ehci->periodic_size, sizeof(void *), flags);
index 12edc723ec73e41261be2eb1bf25aee451fc1a92..a7816e392a8520fb264ee961aafbf4ba14b993eb 100644 (file)
@@ -149,8 +149,7 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
                 * fixed in newer silicon.
                 */
                case 0x0068:
-                       pci_read_config_dword(pdev, PCI_REVISION_ID, &temp);
-                       if ((temp & 0xff) < 0xa4)
+                       if (pdev->revision < 0xa4)
                                ehci->no_selective_suspend = 1;
                        break;
                }
@@ -313,13 +312,14 @@ static int ehci_pci_resume(struct usb_hcd *hcd)
        ehci_work(ehci);
        spin_unlock_irq(&ehci->lock);
 
-       /* here we "know" root ports should always stay powered */
-       ehci_port_power(ehci, 1);
-
        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);
+       ehci_handover_companion_ports(ehci);
+
        hcd->state = HC_STATE_SUSPENDED;
        return 0;
 }
diff --git a/drivers/usb/host/ehci-ppc-soc.c b/drivers/usb/host/ehci-ppc-soc.c
new file mode 100644 (file)
index 0000000..c2cedb0
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ * EHCI HCD (Host Controller Driver) for USB.
+ *
+ * (C) Copyright 2006-2007 Stefan Roese <sr@denx.de>, DENX Software Engineering
+ *
+ * Bus Glue for PPC On-Chip EHCI driver
+ * Tested on AMCC 440EPx
+ *
+ * Based on "ehci-au12xx.c" by David Brownell <dbrownell@users.sourceforge.net>
+ *
+ * This file is licenced under the GPL.
+ */
+
+#include <linux/platform_device.h>
+
+extern int usb_disabled(void);
+
+/**
+ * usb_ehci_ppc_soc_probe - initialize PPC-SoC-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_ppc_soc_probe(const struct hc_driver *driver,
+                          struct usb_hcd **hcd_out,
+                          struct platform_device *dev)
+{
+       int retval;
+       struct usb_hcd *hcd;
+       struct ehci_hcd *ehci;
+
+       if (dev->resource[1].flags != IORESOURCE_IRQ) {
+               pr_debug("resource[1] is not IORESOURCE_IRQ");
+               retval = -ENOMEM;
+       }
+       hcd = usb_create_hcd(driver, &dev->dev, "PPC-SOC EHCI");
+       if (!hcd)
+               return -ENOMEM;
+       hcd->rsrc_start = dev->resource[0].start;
+       hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1;
+
+       if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
+               pr_debug("request_mem_region failed");
+               retval = -EBUSY;
+               goto err1;
+       }
+
+       hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+       if (!hcd->regs) {
+               pr_debug("ioremap failed");
+               retval = -ENOMEM;
+               goto err2;
+       }
+
+       ehci = hcd_to_ehci(hcd);
+       ehci->big_endian_mmio = 1;
+       ehci->big_endian_desc = 1;
+       ehci->caps = hcd->regs;
+       ehci->regs = hcd->regs + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
+
+       /* cache this readonly data; minimize chip reads */
+       ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
+
+#if defined(CONFIG_440EPX)
+       /*
+        * 440EPx Errata USBH_3
+        * Fix: Enable Break Memory Transfer (BMT) in INSNREG3
+        */
+       out_be32((void *)((ulong)(&ehci->regs->command) + 0x8c), (1 << 0));
+       ehci_dbg(ehci, "Break Memory Transfer (BMT) has beed enabled!\n");
+#endif
+
+       retval = usb_add_hcd(hcd, dev->resource[1].start, IRQF_DISABLED);
+       if (retval == 0)
+               return retval;
+
+       iounmap(hcd->regs);
+err2:
+       release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+err1:
+       usb_put_hcd(hcd);
+       return retval;
+}
+
+/* may be called without controller electrically present */
+/* may be called with controller, bus, and devices active */
+
+/**
+ * usb_ehci_hcd_ppc_soc_remove - shutdown processing for PPC-SoC-based HCDs
+ * @dev: USB Host Controller being removed
+ * Context: !in_interrupt()
+ *
+ * Reverses the effect of usb_ehci_hcd_ppc_soc_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_ppc_soc_remove(struct usb_hcd *hcd, struct platform_device *dev)
+{
+       usb_remove_hcd(hcd);
+       iounmap(hcd->regs);
+       release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+       usb_put_hcd(hcd);
+}
+
+static const struct hc_driver ehci_ppc_soc_hc_driver = {
+       .description = hcd_name,
+       .product_desc = "PPC-SOC EHCI",
+       .hcd_priv_size = sizeof(struct ehci_hcd),
+
+       /*
+        * generic hardware linkage
+        */
+       .irq = ehci_irq,
+       .flags = HCD_MEMORY | HCD_USB2,
+
+       /*
+        * basic lifecycle operations
+        */
+       .reset = ehci_init,
+       .start = ehci_run,
+       .stop = ehci_stop,
+       .shutdown = ehci_shutdown,
+
+       /*
+        * managing i/o requests and associated device resources
+        */
+       .urb_enqueue = ehci_urb_enqueue,
+       .urb_dequeue = ehci_urb_dequeue,
+       .endpoint_disable = ehci_endpoint_disable,
+
+       /*
+        * scheduling support
+        */
+       .get_frame_number = ehci_get_frame,
+
+       /*
+        * root hub support
+        */
+       .hub_status_data = ehci_hub_status_data,
+       .hub_control = ehci_hub_control,
+#ifdef CONFIG_PM
+       .hub_suspend = ehci_hub_suspend,
+       .hub_resume = ehci_hub_resume,
+#endif
+};
+
+static int ehci_hcd_ppc_soc_drv_probe(struct platform_device *pdev)
+{
+       struct usb_hcd *hcd = NULL;
+       int ret;
+
+       pr_debug("In ehci_hcd_ppc_soc_drv_probe\n");
+
+       if (usb_disabled())
+               return -ENODEV;
+
+       ret = usb_ehci_ppc_soc_probe(&ehci_ppc_soc_hc_driver, &hcd, pdev);
+       return ret;
+}
+
+static int ehci_hcd_ppc_soc_drv_remove(struct platform_device *pdev)
+{
+       struct usb_hcd *hcd = platform_get_drvdata(pdev);
+
+       usb_ehci_ppc_soc_remove(hcd, pdev);
+       return 0;
+}
+
+MODULE_ALIAS("ppc-soc-ehci");
+static struct platform_driver ehci_ppc_soc_driver = {
+       .probe = ehci_hcd_ppc_soc_drv_probe,
+       .remove = ehci_hcd_ppc_soc_drv_remove,
+       .shutdown = usb_hcd_platform_shutdown,
+       .driver = {
+               .name = "ppc-soc-ehci",
+               .bus = &platform_bus_type
+       }
+};
index 37b83ba099695d7cc5dc51fb6ebb94ee8e26c8ec..829fe649a981fdc03ad6f5cb64df4f9f0b8e4024 100644 (file)
@@ -18,6 +18,7 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <asm/firmware.h>
 #include <asm/ps3.h>
 
 static int ps3_ehci_hc_reset(struct usb_hcd *hcd)
@@ -73,7 +74,7 @@ static const struct hc_driver ps3_ehci_hc_driver = {
 #endif
 };
 
-static int ps3_ehci_sb_probe(struct ps3_system_bus_device *dev)
+static int ps3_ehci_probe(struct ps3_system_bus_device *dev)
 {
        int result;
        struct usb_hcd *hcd;
@@ -85,13 +86,30 @@ static int ps3_ehci_sb_probe(struct ps3_system_bus_device *dev)
                goto fail_start;
        }
 
+       result = ps3_open_hv_device(dev);
+
+       if (result) {
+               dev_dbg(&dev->core, "%s:%d: ps3_open_hv_device failed\n",
+                       __func__, __LINE__);
+               goto fail_open;
+       }
+
+       result = ps3_dma_region_create(dev->d_region);
+
+       if (result) {
+               dev_dbg(&dev->core, "%s:%d: ps3_dma_region_create failed: "
+                       "(%d)\n", __func__, __LINE__, result);
+               BUG_ON("check region type");
+               goto fail_dma_region;
+       }
+
        result = ps3_mmio_region_create(dev->m_region);
 
        if (result) {
                dev_dbg(&dev->core, "%s:%d: ps3_map_mmio_region failed\n",
                        __func__, __LINE__);
                result = -EPERM;
-               goto fail_mmio;
+               goto fail_mmio_region;
        }
 
        dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__,
@@ -120,6 +138,11 @@ static int ps3_ehci_sb_probe(struct ps3_system_bus_device *dev)
 
        hcd->rsrc_start = dev->m_region->lpar_addr;
        hcd->rsrc_len = dev->m_region->len;
+
+       if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name))
+               dev_dbg(&dev->core, "%s:%d: request_mem_region failed\n",
+                       __func__, __LINE__);
+
        hcd->regs = ioremap(dev->m_region->lpar_addr, dev->m_region->len);
 
        if (!hcd->regs) {
@@ -153,34 +176,73 @@ static int ps3_ehci_sb_probe(struct ps3_system_bus_device *dev)
 fail_add_hcd:
        iounmap(hcd->regs);
 fail_ioremap:
+       release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
        usb_put_hcd(hcd);
 fail_create_hcd:
        ps3_io_irq_destroy(virq);
 fail_irq:
        ps3_free_mmio_region(dev->m_region);
-fail_mmio:
+fail_mmio_region:
+       ps3_dma_region_free(dev->d_region);
+fail_dma_region:
+       ps3_close_hv_device(dev);
+fail_open:
 fail_start:
        return result;
 }
 
-static int ps3_ehci_sb_remove(struct ps3_system_bus_device *dev)
+static int ps3_ehci_remove(struct ps3_system_bus_device *dev)
 {
+       unsigned int tmp;
        struct usb_hcd *hcd =
                (struct usb_hcd *)ps3_system_bus_get_driver_data(dev);
 
-       usb_put_hcd(hcd);
+       BUG_ON(!hcd);
+
+       dev_dbg(&dev->core, "%s:%d: regs %p\n", __func__, __LINE__, hcd->regs);
+       dev_dbg(&dev->core, "%s:%d: irq %u\n", __func__, __LINE__, hcd->irq);
+
+       tmp = hcd->irq;
+
+       usb_remove_hcd(hcd);
+
        ps3_system_bus_set_driver_data(dev, NULL);
 
+       BUG_ON(!hcd->regs);
+       iounmap(hcd->regs);
+
+       release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+       usb_put_hcd(hcd);
+
+       ps3_io_irq_destroy(tmp);
+       ps3_free_mmio_region(dev->m_region);
+
+       ps3_dma_region_free(dev->d_region);
+       ps3_close_hv_device(dev);
+
        return 0;
 }
 
-MODULE_ALIAS("ps3-ehci");
+static int ps3_ehci_driver_register(struct ps3_system_bus_driver *drv)
+{
+       return firmware_has_feature(FW_FEATURE_PS3_LV1)
+               ? ps3_system_bus_driver_register(drv)
+               : 0;
+}
+
+static void ps3_ehci_driver_unregister(struct ps3_system_bus_driver *drv)
+{
+       if (firmware_has_feature(FW_FEATURE_PS3_LV1))
+               ps3_system_bus_driver_unregister(drv);
+}
+
+MODULE_ALIAS(PS3_MODULE_ALIAS_EHCI);
 
-static struct ps3_system_bus_driver ps3_ehci_sb_driver = {
+static struct ps3_system_bus_driver ps3_ehci_driver = {
+       .core.name = "ps3-ehci-driver",
+       .core.owner = THIS_MODULE,
        .match_id = PS3_MATCH_ID_EHCI,
-       .core = {
-               .name = "ps3-ehci-driver",
-       },
-       .probe = ps3_ehci_sb_probe,
-       .remove = ps3_ehci_sb_remove,
+       .probe = ps3_ehci_probe,
+       .remove = ps3_ehci_remove,
+       .shutdown = ps3_ehci_remove,
 };
index e7fbbd00e7cd78a95776264a7c12033d5fa2a3a9..2284028f8aa5e2056d0d309effb03173c9b4ea3f 100644 (file)
 /* fill a qtd, returning how much of the buffer we were able to queue up */
 
 static int
-qtd_fill (struct ehci_qtd *qtd, dma_addr_t buf, size_t len,
-               int token, int maxpacket)
+qtd_fill(struct ehci_hcd *ehci, struct ehci_qtd *qtd, dma_addr_t buf,
+                 size_t len, int token, int maxpacket)
 {
        int     i, count;
        u64     addr = buf;
 
        /* one buffer entry per 4K ... first might be short or unaligned */
-       qtd->hw_buf [0] = cpu_to_le32 ((u32)addr);
-       qtd->hw_buf_hi [0] = cpu_to_le32 ((u32)(addr >> 32));
+       qtd->hw_buf[0] = cpu_to_hc32(ehci, (u32)addr);
+       qtd->hw_buf_hi[0] = cpu_to_hc32(ehci, (u32)(addr >> 32));
        count = 0x1000 - (buf & 0x0fff);        /* rest of that page */
        if (likely (len < count))               /* ... iff needed */
                count = len;
@@ -62,8 +62,9 @@ qtd_fill (struct ehci_qtd *qtd, dma_addr_t buf, size_t len,
                /* per-qtd limit: from 16K to 20K (best alignment) */
                for (i = 1; count < len && i < 5; i++) {
                        addr = buf;
-                       qtd->hw_buf [i] = cpu_to_le32 ((u32)addr);
-                       qtd->hw_buf_hi [i] = cpu_to_le32 ((u32)(addr >> 32));
+                       qtd->hw_buf[i] = cpu_to_hc32(ehci, (u32)addr);
+                       qtd->hw_buf_hi[i] = cpu_to_hc32(ehci,
+                                       (u32)(addr >> 32));
                        buf += 0x1000;
                        if ((count + 0x1000) < len)
                                count += 0x1000;
@@ -75,7 +76,7 @@ qtd_fill (struct ehci_qtd *qtd, dma_addr_t buf, size_t len,
                if (count != len)
                        count -= (count % maxpacket);
        }
-       qtd->hw_token = cpu_to_le32 ((count << 16) | token);
+       qtd->hw_token = cpu_to_hc32(ehci, (count << 16) | token);
        qtd->length = count;
 
        return count;
@@ -89,28 +90,28 @@ qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd)
        /* writes to an active overlay are unsafe */
        BUG_ON(qh->qh_state != QH_STATE_IDLE);
 
-       qh->hw_qtd_next = QTD_NEXT (qtd->qtd_dma);
-       qh->hw_alt_next = EHCI_LIST_END;
+       qh->hw_qtd_next = QTD_NEXT(ehci, qtd->qtd_dma);
+       qh->hw_alt_next = EHCI_LIST_END(ehci);
 
        /* Except for control endpoints, we make hardware maintain data
         * toggle (like OHCI) ... here (re)initialize the toggle in the QH,
         * and set the pseudo-toggle in udev. Only usb_clear_halt() will
         * ever clear it.
         */
-       if (!(qh->hw_info1 & cpu_to_le32(1 << 14))) {
+       if (!(qh->hw_info1 & cpu_to_hc32(ehci, 1 << 14))) {
                unsigned        is_out, epnum;
 
-               is_out = !(qtd->hw_token & cpu_to_le32(1 << 8));
-               epnum = (le32_to_cpup(&qh->hw_info1) >> 8) & 0x0f;
+               is_out = !(qtd->hw_token & cpu_to_hc32(ehci, 1 << 8));
+               epnum = (hc32_to_cpup(ehci, &qh->hw_info1) >> 8) & 0x0f;
                if (unlikely (!usb_gettoggle (qh->dev, epnum, is_out))) {
-                       qh->hw_token &= ~__constant_cpu_to_le32 (QTD_TOGGLE);
+                       qh->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE);
                        usb_settoggle (qh->dev, epnum, is_out, 1);
                }
        }
 
        /* HC must see latest qtd and qh data before we clear ACTIVE+HALT */
        wmb ();
-       qh->hw_token &= __constant_cpu_to_le32 (QTD_TOGGLE | QTD_STS_PING);
+       qh->hw_token &= cpu_to_hc32(ehci, QTD_TOGGLE | QTD_STS_PING);
 }
 
 /* if it weren't for a common silicon quirk (writing the dummy into the qh
@@ -128,7 +129,7 @@ qh_refresh (struct ehci_hcd *ehci, struct ehci_qh *qh)
                qtd = list_entry (qh->qtd_list.next,
                                struct ehci_qtd, qtd_list);
                /* first qtd may already be partially processed */
-               if (cpu_to_le32 (qtd->qtd_dma) == qh->hw_current)
+               if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw_current)
                        qtd = NULL;
        }
 
@@ -222,7 +223,7 @@ __acquires(ehci->lock)
                struct ehci_qh  *qh = (struct ehci_qh *) urb->hcpriv;
 
                /* S-mask in a QH means it's an interrupt urb */
-               if ((qh->hw_info2 & __constant_cpu_to_le32 (QH_SMASK)) != 0) {
+               if ((qh->hw_info2 & cpu_to_hc32(ehci, QH_SMASK)) != 0) {
 
                        /* ... update hc-wide periodic stats (for usbfs) */
                        ehci_to_hcd(ehci)->self.bandwidth_int_reqs--;
@@ -277,7 +278,6 @@ static int qh_schedule (struct ehci_hcd *ehci, struct ehci_qh *qh);
  * Chases up to qh->hw_current.  Returns number of completions called,
  * indicating how much "real" work we did.
  */
-#define HALT_BIT __constant_cpu_to_le32(QTD_STS_HALT)
 static unsigned
 qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
 {
@@ -287,6 +287,7 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
        unsigned                count = 0;
        int                     do_status = 0;
        u8                      state;
+       u32                     halt = HALT_BIT(ehci);
 
        if (unlikely (list_empty (&qh->qtd_list)))
                return count;
@@ -311,6 +312,10 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
                struct urb      *urb;
                u32             token = 0;
 
+               /* ignore QHs that are currently inactive */
+               if (qh->hw_info1 & __constant_cpu_to_le32(QH_INACTIVATE))
+                       break;
+
                qtd = list_entry (entry, struct ehci_qtd, qtd_list);
                urb = qtd->urb;
 
@@ -330,7 +335,7 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
 
                /* hardware copies qtd out of qh overlay */
                rmb ();
-               token = le32_to_cpu (qtd->hw_token);
+               token = hc32_to_cpu(ehci, qtd->hw_token);
 
                /* always clean up qtds the hc de-activated */
                if ((token & QTD_STS_ACTIVE) == 0) {
@@ -342,7 +347,8 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
                         * that silicon quirk can kick in with this dummy too.
                         */
                        } else if (IS_SHORT_READ (token)
-                                       && !(qtd->hw_alt_next & EHCI_LIST_END)) {
+                                       && !(qtd->hw_alt_next
+                                               & EHCI_LIST_END(ehci))) {
                                stopped = 1;
                                goto halt;
                        }
@@ -374,17 +380,17 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
 
                        /* token in overlay may be most current */
                        if (state == QH_STATE_IDLE
-                                       && cpu_to_le32 (qtd->qtd_dma)
+                                       && cpu_to_hc32(ehci, qtd->qtd_dma)
                                                == qh->hw_current)
-                               token = le32_to_cpu (qh->hw_token);
+                               token = hc32_to_cpu(ehci, qh->hw_token);
 
                        /* force halt for unlinked or blocked qh, so we'll
                         * patch the qh later and so that completions can't
                         * activate it while we "know" it's stopped.
                         */
-                       if ((HALT_BIT & qh->hw_token) == 0) {
+                       if ((halt & qh->hw_token) == 0) {
 halt:
-                               qh->hw_token |= HALT_BIT;
+                               qh->hw_token |= halt;
                                wmb ();
                        }
                }
@@ -419,7 +425,7 @@ halt:
         * it after fault cleanup, or recovering from silicon wrongly
         * overlaying the dummy qtd (which reduces DMA chatter).
         */
-       if (stopped != 0 || qh->hw_qtd_next == EHCI_LIST_END) {
+       if (stopped != 0 || qh->hw_qtd_next == EHCI_LIST_END(ehci)) {
                switch (state) {
                case QH_STATE_IDLE:
                        qh_refresh(ehci, qh);
@@ -428,7 +434,7 @@ halt:
                        /* should be rare for periodic transfers,
                         * except maybe high bandwidth ...
                         */
-                       if ((__constant_cpu_to_le32 (QH_SMASK)
+                       if ((cpu_to_hc32(ehci, QH_SMASK)
                                        & qh->hw_info2) != 0) {
                                intr_deschedule (ehci, qh);
                                (void) qh_schedule (ehci, qh);
@@ -502,8 +508,9 @@ qh_urb_transaction (
        is_input = usb_pipein (urb->pipe);
        if (usb_pipecontrol (urb->pipe)) {
                /* SETUP pid */
-               qtd_fill (qtd, urb->setup_dma, sizeof (struct usb_ctrlrequest),
-                       token | (2 /* "setup" */ << 8), 8);
+               qtd_fill(ehci, qtd, urb->setup_dma,
+                               sizeof (struct usb_ctrlrequest),
+                               token | (2 /* "setup" */ << 8), 8);
 
                /* ... and always at least one more pid */
                token ^= QTD_TOGGLE;
@@ -512,7 +519,7 @@ qh_urb_transaction (
                if (unlikely (!qtd))
                        goto cleanup;
                qtd->urb = urb;
-               qtd_prev->hw_next = QTD_NEXT (qtd->qtd_dma);
+               qtd_prev->hw_next = QTD_NEXT(ehci, qtd->qtd_dma);
                list_add_tail (&qtd->qtd_list, head);
 
                /* for zero length DATA stages, STATUS is always IN */
@@ -539,7 +546,7 @@ qh_urb_transaction (
        for (;;) {
                int this_qtd_len;
 
-               this_qtd_len = qtd_fill (qtd, buf, len, token, maxpacket);
+               this_qtd_len = qtd_fill(ehci, qtd, buf, len, token, maxpacket);
                len -= this_qtd_len;
                buf += this_qtd_len;
                if (is_input)
@@ -557,7 +564,7 @@ qh_urb_transaction (
                if (unlikely (!qtd))
                        goto cleanup;
                qtd->urb = urb;
-               qtd_prev->hw_next = QTD_NEXT (qtd->qtd_dma);
+               qtd_prev->hw_next = QTD_NEXT(ehci, qtd->qtd_dma);
                list_add_tail (&qtd->qtd_list, head);
        }
 
@@ -566,7 +573,7 @@ qh_urb_transaction (
         */
        if (likely ((urb->transfer_flags & URB_SHORT_NOT_OK) == 0
                                || usb_pipecontrol (urb->pipe)))
-               qtd->hw_alt_next = EHCI_LIST_END;
+               qtd->hw_alt_next = EHCI_LIST_END(ehci);
 
        /*
         * control requests may need a terminating data "status" ack;
@@ -590,17 +597,17 @@ qh_urb_transaction (
                        if (unlikely (!qtd))
                                goto cleanup;
                        qtd->urb = urb;
-                       qtd_prev->hw_next = QTD_NEXT (qtd->qtd_dma);
+                       qtd_prev->hw_next = QTD_NEXT(ehci, qtd->qtd_dma);
                        list_add_tail (&qtd->qtd_list, head);
 
                        /* never any data in such packets */
-                       qtd_fill (qtd, 0, 0, token, 0);
+                       qtd_fill(ehci, qtd, 0, 0, token, 0);
                }
        }
 
        /* by default, enable interrupt on urb completion */
        if (likely (!(urb->transfer_flags & URB_NO_INTERRUPT)))
-               qtd->hw_token |= __constant_cpu_to_le32 (QTD_IOC);
+               qtd->hw_token |= cpu_to_hc32(ehci, QTD_IOC);
        return head;
 
 cleanup:
@@ -769,8 +776,8 @@ done:
 
        /* init as live, toggle clear, advance to dummy */
        qh->qh_state = QH_STATE_IDLE;
-       qh->hw_info1 = cpu_to_le32 (info1);
-       qh->hw_info2 = cpu_to_le32 (info2);
+       qh->hw_info1 = cpu_to_hc32(ehci, info1);
+       qh->hw_info2 = cpu_to_hc32(ehci, info2);
        usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, 1);
        qh_refresh (ehci, qh);
        return qh;
@@ -782,7 +789,7 @@ done:
 
 static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
 {
-       __le32          dma = QH_NEXT (qh->qh_dma);
+       __hc32          dma = QH_NEXT(ehci, qh->qh_dma);
        struct ehci_qh  *head;
 
        /* (re)start the async schedule? */
@@ -820,8 +827,6 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
 
 /*-------------------------------------------------------------------------*/
 
-#define        QH_ADDR_MASK    __constant_cpu_to_le32(0x7f)
-
 /*
  * For control/bulk/interrupt, return QH with these TDs appended.
  * Allocates and initializes the QH if necessary.
@@ -837,6 +842,7 @@ static struct ehci_qh *qh_append_tds (
 )
 {
        struct ehci_qh          *qh = NULL;
+       u32                     qh_addr_mask = cpu_to_hc32(ehci, 0x7f);
 
        qh = (struct ehci_qh *) *ptr;
        if (unlikely (qh == NULL)) {
@@ -858,7 +864,7 @@ static struct ehci_qh *qh_append_tds (
 
                         /* usb_reset_device() briefly reverts to address 0 */
                         if (usb_pipedevice (urb->pipe) == 0)
-                                qh->hw_info1 &= ~QH_ADDR_MASK;
+                                qh->hw_info1 &= ~qh_addr_mask;
                }
 
                /* just one way to queue requests: swap with the dummy qtd.
@@ -867,7 +873,7 @@ static struct ehci_qh *qh_append_tds (
                if (likely (qtd != NULL)) {
                        struct ehci_qtd         *dummy;
                        dma_addr_t              dma;
-                       __le32                  token;
+                       __hc32                  token;
 
                        /* to avoid racing the HC, use the dummy td instead of
                         * the first td of our list (becomes new dummy).  both
@@ -875,7 +881,7 @@ static struct ehci_qh *qh_append_tds (
                         * HC is allowed to fetch the old dummy (4.10.2).
                         */
                        token = qtd->hw_token;
-                       qtd->hw_token = HALT_BIT;
+                       qtd->hw_token = HALT_BIT(ehci);
                        wmb ();
                        dummy = qh->dummy;
 
@@ -887,14 +893,14 @@ static struct ehci_qh *qh_append_tds (
                        list_add (&dummy->qtd_list, qtd_list);
                        __list_splice (qtd_list, qh->qtd_list.prev);
 
-                       ehci_qtd_init (qtd, qtd->qtd_dma);
+                       ehci_qtd_init(ehci, qtd, qtd->qtd_dma);
                        qh->dummy = qtd;
 
                        /* hc must see the new dummy at list end */
                        dma = qtd->qtd_dma;
                        qtd = list_entry (qh->qtd_list.prev,
                                        struct ehci_qtd, qtd_list);
-                       qtd->hw_next = QTD_NEXT (dma);
+                       qtd->hw_next = QTD_NEXT(ehci, dma);
 
                        /* let the hc process these next qtds */
                        wmb ();
@@ -970,7 +976,7 @@ static void end_unlink_async (struct ehci_hcd *ehci)
 
        timer_action_done (ehci, TIMER_IAA_WATCHDOG);
 
-       // qh->hw_next = cpu_to_le32 (qh->qh_dma);
+       // qh->hw_next = cpu_to_hc32(qh->qh_dma);
        qh->qh_state = QH_STATE_IDLE;
        qh->qh_next.qh = NULL;
        qh_put (qh);                    // refcount from reclaim
index 7b5ae7111f2311609436a2b403f1eec60fdaecd0..d4a8ace496769308338bce8e081511d80032e1d6 100644 (file)
@@ -44,9 +44,10 @@ static int ehci_get_frame (struct usb_hcd *hcd);
  * @tag: hardware tag for type of this record
  */
 static union ehci_shadow *
-periodic_next_shadow (union ehci_shadow *periodic, __le32 tag)
+periodic_next_shadow(struct ehci_hcd *ehci, union ehci_shadow *periodic,
+               __hc32 tag)
 {
-       switch (tag) {
+       switch (hc32_to_cpu(ehci, tag)) {
        case Q_TYPE_QH:
                return &periodic->qh->qh_next;
        case Q_TYPE_FSTN:
@@ -62,13 +63,14 @@ periodic_next_shadow (union ehci_shadow *periodic, __le32 tag)
 /* caller must hold ehci->lock */
 static void periodic_unlink (struct ehci_hcd *ehci, unsigned frame, void *ptr)
 {
-       union ehci_shadow       *prev_p = &ehci->pshadow [frame];
-       __le32                  *hw_p = &ehci->periodic [frame];
+       union ehci_shadow       *prev_p = &ehci->pshadow[frame];
+       __hc32                  *hw_p = &ehci->periodic[frame];
        union ehci_shadow       here = *prev_p;
 
        /* find predecessor of "ptr"; hw and shadow lists are in sync */
        while (here.ptr && here.ptr != ptr) {
-               prev_p = periodic_next_shadow (prev_p, Q_NEXT_TYPE (*hw_p));
+               prev_p = periodic_next_shadow(ehci, prev_p,
+                               Q_NEXT_TYPE(ehci, *hw_p));
                hw_p = here.hw_next;
                here = *prev_p;
        }
@@ -79,7 +81,8 @@ static void periodic_unlink (struct ehci_hcd *ehci, unsigned frame, void *ptr)
        /* update shadow and hardware lists ... the old "next" pointers
         * from ptr may still be in use, the caller updates them.
         */
-       *prev_p = *periodic_next_shadow (&here, Q_NEXT_TYPE (*hw_p));
+       *prev_p = *periodic_next_shadow(ehci, &here,
+                       Q_NEXT_TYPE(ehci, *hw_p));
        *hw_p = *here.hw_next;
 }
 
@@ -87,18 +90,19 @@ static void periodic_unlink (struct ehci_hcd *ehci, unsigned frame, void *ptr)
 static unsigned short
 periodic_usecs (struct ehci_hcd *ehci, unsigned frame, unsigned uframe)
 {
-       __le32                  *hw_p = &ehci->periodic [frame];
+       __hc32                  *hw_p = &ehci->periodic [frame];
        union ehci_shadow       *q = &ehci->pshadow [frame];
        unsigned                usecs = 0;
 
        while (q->ptr) {
-               switch (Q_NEXT_TYPE (*hw_p)) {
+               switch (hc32_to_cpu(ehci, Q_NEXT_TYPE(ehci, *hw_p))) {
                case Q_TYPE_QH:
                        /* is it in the S-mask? */
-                       if (q->qh->hw_info2 & cpu_to_le32 (1 << uframe))
+                       if (q->qh->hw_info2 & cpu_to_hc32(ehci, 1 << uframe))
                                usecs += q->qh->usecs;
                        /* ... or C-mask? */
-                       if (q->qh->hw_info2 & cpu_to_le32 (1 << (8 + uframe)))
+                       if (q->qh->hw_info2 & cpu_to_hc32(ehci,
+                                       1 << (8 + uframe)))
                                usecs += q->qh->c_usecs;
                        hw_p = &q->qh->hw_next;
                        q = &q->qh->qh_next;
@@ -108,7 +112,7 @@ periodic_usecs (struct ehci_hcd *ehci, unsigned frame, unsigned uframe)
                        /* for "save place" FSTNs, count the relevant INTR
                         * bandwidth from the previous frame
                         */
-                       if (q->fstn->hw_prev != EHCI_LIST_END) {
+                       if (q->fstn->hw_prev != EHCI_LIST_END(ehci)) {
                                ehci_dbg (ehci, "ignoring FSTN cost ...\n");
                        }
                        hw_p = &q->fstn->hw_next;
@@ -121,9 +125,10 @@ periodic_usecs (struct ehci_hcd *ehci, unsigned frame, unsigned uframe)
                        break;
                case Q_TYPE_SITD:
                        /* is it in the S-mask?  (count SPLIT, DATA) */
-                       if (q->sitd->hw_uframe & cpu_to_le32 (1 << uframe)) {
+                       if (q->sitd->hw_uframe & cpu_to_hc32(ehci,
+                                       1 << uframe)) {
                                if (q->sitd->hw_fullspeed_ep &
-                                               __constant_cpu_to_le32 (1<<31))
+                                               cpu_to_hc32(ehci, 1<<31))
                                        usecs += q->sitd->stream->usecs;
                                else    /* worst case for OUT start-split */
                                        usecs += HS_USECS_ISO (188);
@@ -131,7 +136,7 @@ periodic_usecs (struct ehci_hcd *ehci, unsigned frame, unsigned uframe)
 
                        /* ... C-mask?  (count CSPLIT, DATA) */
                        if (q->sitd->hw_uframe &
-                                       cpu_to_le32 (1 << (8 + uframe))) {
+                                       cpu_to_hc32(ehci, 1 << (8 + uframe))) {
                                /* worst case for IN complete-split */
                                usecs += q->sitd->stream->c_usecs;
                        }
@@ -173,9 +178,9 @@ static int same_tt (struct usb_device *dev1, struct usb_device *dev2)
  * will cause a transfer in "B-frame" uframe 0.  "B-frames" lag
  * "H-frames" by 1 uframe.  See the EHCI spec sec 4.5 and figure 4.7.
  */
-static inline unsigned char tt_start_uframe(struct ehci_hcd *ehci, __le32 mask)
+static inline unsigned char tt_start_uframe(struct ehci_hcd *ehci, __hc32 mask)
 {
-       unsigned char smask = QH_SMASK & le32_to_cpu(mask);
+       unsigned char smask = QH_SMASK & hc32_to_cpu(ehci, mask);
        if (!smask) {
                ehci_err(ehci, "invalid empty smask!\n");
                /* uframe 7 can't have bw so this will indicate failure */
@@ -217,14 +222,14 @@ periodic_tt_usecs (
        unsigned short tt_usecs[8]
 )
 {
-       __le32                  *hw_p = &ehci->periodic [frame];
+       __hc32                  *hw_p = &ehci->periodic [frame];
        union ehci_shadow       *q = &ehci->pshadow [frame];
        unsigned char           uf;
 
        memset(tt_usecs, 0, 16);
 
        while (q->ptr) {
-               switch (Q_NEXT_TYPE(*hw_p)) {
+               switch (hc32_to_cpu(ehci, Q_NEXT_TYPE(ehci, *hw_p))) {
                case Q_TYPE_ITD:
                        hw_p = &q->itd->hw_next;
                        q = &q->itd->itd_next;
@@ -247,8 +252,8 @@ periodic_tt_usecs (
                        continue;
                // case Q_TYPE_FSTN:
                default:
-                       ehci_dbg(ehci,
-                                 "ignoring periodic frame %d FSTN\n", frame);
+                       ehci_dbg(ehci, "ignoring periodic frame %d FSTN\n",
+                                       frame);
                        hw_p = &q->fstn->hw_next;
                        q = &q->fstn->fstn_next;
                }
@@ -368,41 +373,42 @@ static int tt_no_collision (
         */
        for (; frame < ehci->periodic_size; frame += period) {
                union ehci_shadow       here;
-               __le32                  type;
+               __hc32                  type;
 
                here = ehci->pshadow [frame];
-               type = Q_NEXT_TYPE (ehci->periodic [frame]);
+               type = Q_NEXT_TYPE(ehci, ehci->periodic [frame]);
                while (here.ptr) {
-                       switch (type) {
+                       switch (hc32_to_cpu(ehci, type)) {
                        case Q_TYPE_ITD:
-                               type = Q_NEXT_TYPE (here.itd->hw_next);
+                               type = Q_NEXT_TYPE(ehci, here.itd->hw_next);
                                here = here.itd->itd_next;
                                continue;
                        case Q_TYPE_QH:
                                if (same_tt (dev, here.qh->dev)) {
                                        u32             mask;
 
-                                       mask = le32_to_cpu (here.qh->hw_info2);
+                                       mask = hc32_to_cpu(ehci,
+                                                       here.qh->hw_info2);
                                        /* "knows" no gap is needed */
                                        mask |= mask >> 8;
                                        if (mask & uf_mask)
                                                break;
                                }
-                               type = Q_NEXT_TYPE (here.qh->hw_next);
+                               type = Q_NEXT_TYPE(ehci, here.qh->hw_next);
                                here = here.qh->qh_next;
                                continue;
                        case Q_TYPE_SITD:
                                if (same_tt (dev, here.sitd->urb->dev)) {
                                        u16             mask;
 
-                                       mask = le32_to_cpu (here.sitd
+                                       mask = hc32_to_cpu(ehci, here.sitd
                                                                ->hw_uframe);
                                        /* FIXME assumes no gap for IN! */
                                        mask |= mask >> 8;
                                        if (mask & uf_mask)
                                                break;
                                }
-                               type = Q_NEXT_TYPE (here.sitd->hw_next);
+                               type = Q_NEXT_TYPE(ehci, here.sitd->hw_next);
                                here = here.sitd->sitd_next;
                                continue;
                        // case Q_TYPE_FSTN:
@@ -473,6 +479,109 @@ static int disable_periodic (struct ehci_hcd *ehci)
 }
 
 /*-------------------------------------------------------------------------*/
+#ifdef CONFIG_CPU_FREQ
+
+static int safe_to_modify_i (struct ehci_hcd *ehci, struct ehci_qh *qh)
+{
+       int now; /* current (frame * 8) + uframe */
+       int prev_start, next_start; /* uframes from/to split start */
+       int start_uframe = ffs(le32_to_cpup (&qh->hw_info2) & QH_SMASK);
+       int end_uframe = fls((le32_to_cpup (&qh->hw_info2) & QH_CMASK) >> 8);
+       int split_duration = end_uframe - start_uframe;
+
+       now = readl(&ehci->regs->frame_index) % (ehci->periodic_size << 3);
+
+       next_start = ((1024 << 3) + (qh->start << 3) + start_uframe - now)
+                       % (qh->period << 3);
+       prev_start = (qh->period << 3) - next_start;
+
+       /*
+        * Make sure there will be at least one uframe when qh is safe.
+        */
+       if ((qh->period << 3) <= (ehci->i_thresh + 2 + split_duration))
+               /* never safe */
+               return -EINVAL;
+
+       /*
+        * Wait 1 uframe after transaction should have started, to make
+        * sure controller has time to write back overlay, so we can
+        * check QTD_STS_STS to see if transaction is in progress.
+        */
+       if ((next_start > ehci->i_thresh) && (prev_start > 1))
+               /* safe to set "i" bit if split isn't in progress */
+               return (qh->hw_token & STATUS_BIT(ehci)) ? 0 : 1;
+       else
+               return 0;
+}
+
+/* Set inactivate bit for all the split interrupt QHs. */
+static void qh_inactivate_split_intr_qhs (struct ehci_hcd *ehci)
+{
+       struct ehci_qh  *qh;
+       int             not_done, safe;
+       u32             inactivate = INACTIVATE_BIT(ehci);
+       u32             active = ACTIVE_BIT(ehci);
+
+       do {
+               not_done = 0;
+               list_for_each_entry(qh, &ehci->split_intr_qhs,
+                               split_intr_qhs) {
+                       if (qh->hw_info1 & inactivate)
+                               /* already off */
+                               continue;
+                       /*
+                        * To avoid setting "I" after the start split happens,
+                        * don't set it if the QH might be cached in the
+                        * controller.  Some HCs (Broadcom/ServerWorks HT1000)
+                        * will stop in the middle of a split transaction when
+                        * the "I" bit is set.
+                        */
+                       safe = safe_to_modify_i(ehci, qh);
+                       if (safe == 0) {
+                               not_done = 1;
+                       } else if (safe > 0) {
+                               qh->was_active = qh->hw_token & active;
+                               qh->hw_info1 |= inactivate;
+                       }
+               }
+       } while (not_done);
+       wmb();
+}
+
+static void qh_reactivate_split_intr_qhs (struct ehci_hcd *ehci)
+{
+       struct ehci_qh  *qh;
+       u32             token;
+       int             not_done, safe;
+       u32             inactivate = INACTIVATE_BIT(ehci);
+       u32             active = ACTIVE_BIT(ehci);
+       u32             halt = HALT_BIT(ehci);
+
+       do {
+               not_done = 0;
+               list_for_each_entry(qh, &ehci->split_intr_qhs, split_intr_qhs) {
+                       if (!(qh->hw_info1 & inactivate)) /* already on */
+                               continue;
+                       /*
+                        * Don't reactivate if cached, or controller might
+                        * overwrite overlay after we modify it!
+                        */
+                       safe = safe_to_modify_i(ehci, qh);
+                       if (safe == 0) {
+                               not_done = 1;
+                       } else if (safe > 0) {
+                               /* See EHCI 1.0 section 4.15.2.4. */
+                               token = qh->hw_token;
+                               qh->hw_token = (token | halt) & ~active;
+                               wmb();
+                               qh->hw_info1 &= ~inactivate;
+                               wmb();
+                               qh->hw_token = (token & ~halt) | qh->was_active;
+                       }
+               }
+       } while (not_done);
+}
+#endif
 
 /* periodic schedule slots have iso tds (normal or split) first, then a
  * sparse tree for active interrupt transfers.
@@ -487,25 +596,36 @@ static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh)
 
        dev_dbg (&qh->dev->dev,
                "link qh%d-%04x/%p start %d [%d/%d us]\n",
-               period, le32_to_cpup (&qh->hw_info2) & (QH_CMASK | QH_SMASK),
+               period, hc32_to_cpup(ehci, &qh->hw_info2) & (QH_CMASK | QH_SMASK),
                qh, qh->start, qh->usecs, qh->c_usecs);
 
+#ifdef CONFIG_CPU_FREQ
+       /*
+        * If low/full speed interrupt QHs are inactive (because of
+        * cpufreq changing processor speeds), start QH with I flag set--
+        * it will automatically be cleared when cpufreq is done.
+        */
+       if (ehci->cpufreq_changing)
+               if (!(qh->hw_info1 & (cpu_to_le32(1 << 13))))
+                       qh->hw_info1 |= INACTIVATE_BIT(ehci);
+#endif
+
        /* high bandwidth, or otherwise every microframe */
        if (period == 0)
                period = 1;
 
        for (i = qh->start; i < ehci->periodic_size; i += period) {
-               union ehci_shadow       *prev = &ehci->pshadow [i];
-               __le32                  *hw_p = &ehci->periodic [i];
+               union ehci_shadow       *prev = &ehci->pshadow[i];
+               __hc32                  *hw_p = &ehci->periodic[i];
                union ehci_shadow       here = *prev;
-               __le32                  type = 0;
+               __hc32                  type = 0;
 
                /* skip the iso nodes at list head */
                while (here.ptr) {
-                       type = Q_NEXT_TYPE (*hw_p);
-                       if (type == Q_TYPE_QH)
+                       type = Q_NEXT_TYPE(ehci, *hw_p);
+                       if (type == cpu_to_hc32(ehci, Q_TYPE_QH))
                                break;
-                       prev = periodic_next_shadow (prev, type);
+                       prev = periodic_next_shadow(ehci, prev, type);
                        hw_p = &here.qh->hw_next;
                        here = *prev;
                }
@@ -527,7 +647,7 @@ static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh)
                                qh->hw_next = *hw_p;
                        wmb ();
                        prev->qh = qh;
-                       *hw_p = QH_NEXT (qh->qh_dma);
+                       *hw_p = QH_NEXT (ehci, qh->qh_dma);
                }
        }
        qh->qh_state = QH_STATE_LINKED;
@@ -538,6 +658,12 @@ static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh)
                ? ((qh->usecs + qh->c_usecs) / qh->period)
                : (qh->usecs * 8);
 
+#ifdef CONFIG_CPU_FREQ
+       /* add qh to list of low/full speed interrupt QHs, if applicable */
+       if (!(qh->hw_info1 & (cpu_to_le32(1 << 13)))) {
+               list_add(&qh->split_intr_qhs, &ehci->split_intr_qhs);
+       }
+#endif
        /* maybe enable periodic schedule processing */
        if (!ehci->periodic_sched++)
                return enable_periodic (ehci);
@@ -555,7 +681,14 @@ static void qh_unlink_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh)
        //   and this qh is active in the current uframe
        //   (and overlay token SplitXstate is false?)
        // THEN
-       //   qh->hw_info1 |= __constant_cpu_to_le32 (1 << 7 /* "ignore" */);
+       //   qh->hw_info1 |= __constant_cpu_to_hc32(1 << 7 /* "ignore" */);
+
+#ifdef CONFIG_CPU_FREQ
+       /* remove qh from list of low/full speed interrupt QHs */
+       if (!(qh->hw_info1 & (cpu_to_le32(1 << 13)))) {
+               list_del_init(&qh->split_intr_qhs);
+       }
+#endif
 
        /* high bandwidth, or otherwise part of every microframe */
        if ((period = qh->period) == 0)
@@ -572,7 +705,7 @@ static void qh_unlink_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh)
        dev_dbg (&qh->dev->dev,
                "unlink qh%d-%04x/%p start %d [%d/%d us]\n",
                qh->period,
-               le32_to_cpup (&qh->hw_info2) & (QH_CMASK | QH_SMASK),
+               hc32_to_cpup(ehci, &qh->hw_info2) & (QH_CMASK | QH_SMASK),
                qh, qh->start, qh->usecs, qh->c_usecs);
 
        /* qh->qh_next still "live" to HC */
@@ -598,7 +731,7 @@ static void intr_deschedule (struct ehci_hcd *ehci, struct ehci_qh *qh)
         * active high speed queues may need bigger delays...
         */
        if (list_empty (&qh->qtd_list)
-                       || (__constant_cpu_to_le32 (QH_CMASK)
+                       || (cpu_to_hc32(ehci, QH_CMASK)
                                        & qh->hw_info2) != 0)
                wait = 2;
        else
@@ -606,7 +739,7 @@ static void intr_deschedule (struct ehci_hcd *ehci, struct ehci_qh *qh)
 
        udelay (wait);
        qh->qh_state = QH_STATE_IDLE;
-       qh->hw_next = EHCI_LIST_END;
+       qh->hw_next = EHCI_LIST_END(ehci);
        wmb ();
 }
 
@@ -663,7 +796,7 @@ static int check_intr_schedule (
        unsigned                frame,
        unsigned                uframe,
        const struct ehci_qh    *qh,
-       __le32                  *c_maskp
+       __hc32                  *c_maskp
 )
 {
        int             retval = -ENOSPC;
@@ -695,7 +828,7 @@ static int check_intr_schedule (
 
                retval = 0;
 
-               *c_maskp = cpu_to_le32 (mask << 8);
+               *c_maskp = cpu_to_hc32(ehci, mask << 8);
        }
 #else
        /* Make sure this tt's buffer is also available for CSPLITs.
@@ -706,7 +839,7 @@ static int check_intr_schedule (
         * one smart pass...
         */
        mask = 0x03 << (uframe + qh->gap_uf);
-       *c_maskp = cpu_to_le32 (mask << 8);
+       *c_maskp = cpu_to_hc32(ehci, mask << 8);
 
        mask |= 1 << uframe;
        if (tt_no_collision (ehci, qh->period, qh->dev, frame, mask)) {
@@ -726,20 +859,20 @@ done:
 /* "first fit" scheduling policy used the first time through,
  * or when the previous schedule slot can't be re-used.
  */
-static int qh_schedule (struct ehci_hcd *ehci, struct ehci_qh *qh)
+static int qh_schedule(struct ehci_hcd *ehci, struct ehci_qh *qh)
 {
        int             status;
        unsigned        uframe;
-       __le32          c_mask;
+       __hc32          c_mask;
        unsigned        frame;          /* 0..(qh->period - 1), or NO_FRAME */
 
        qh_refresh(ehci, qh);
-       qh->hw_next = EHCI_LIST_END;
+       qh->hw_next = EHCI_LIST_END(ehci);
        frame = qh->start;
 
        /* reuse the previous schedule slots, if we can */
        if (frame < qh->period) {
-               uframe = ffs (le32_to_cpup (&qh->hw_info2) & QH_SMASK);
+               uframe = ffs(hc32_to_cpup(ehci, &qh->hw_info2) & QH_SMASK);
                status = check_intr_schedule (ehci, frame, --uframe,
                                qh, &c_mask);
        } else {
@@ -775,10 +908,10 @@ static int qh_schedule (struct ehci_hcd *ehci, struct ehci_qh *qh)
                qh->start = frame;
 
                /* reset S-frame and (maybe) C-frame masks */
-               qh->hw_info2 &= __constant_cpu_to_le32(~(QH_CMASK | QH_SMASK));
+               qh->hw_info2 &= cpu_to_hc32(ehci, ~(QH_CMASK | QH_SMASK));
                qh->hw_info2 |= qh->period
-                       ? cpu_to_le32 (1 << uframe)
-                       : __constant_cpu_to_le32 (QH_SMASK);
+                       ? cpu_to_hc32(ehci, 1 << uframe)
+                       : cpu_to_hc32(ehci, QH_SMASK);
                qh->hw_info2 |= c_mask;
        } else
                ehci_dbg (ehci, "reused qh %p schedule\n", qh);
@@ -808,7 +941,7 @@ static int intr_submit (
        spin_lock_irqsave (&ehci->lock, flags);
 
        if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE,
-                              &ehci_to_hcd(ehci)->flags))) {
+                       &ehci_to_hcd(ehci)->flags))) {
                status = -ESHUTDOWN;
                goto done;
        }
@@ -898,9 +1031,9 @@ iso_stream_init (
                buf1 |= maxp;
                maxp *= multi;
 
-               stream->buf0 = cpu_to_le32 ((epnum << 8) | dev->devnum);
-               stream->buf1 = cpu_to_le32 (buf1);
-               stream->buf2 = cpu_to_le32 (multi);
+               stream->buf0 = cpu_to_hc32(ehci, (epnum << 8) | dev->devnum);
+               stream->buf1 = cpu_to_hc32(ehci, buf1);
+               stream->buf2 = cpu_to_hc32(ehci, multi);
 
                /* usbfs wants to report the average usecs per frame tied up
                 * when transfers on this endpoint are scheduled ...
@@ -943,7 +1076,7 @@ iso_stream_init (
                bandwidth /= 1 << (interval + 2);
 
                /* stream->splits gets created from raw_mask later */
-               stream->address = cpu_to_le32 (addr);
+               stream->address = cpu_to_hc32(ehci, addr);
        }
        stream->bandwidth = bandwidth;
 
@@ -1077,7 +1210,8 @@ iso_sched_alloc (unsigned packets, gfp_t mem_flags)
 }
 
 static inline void
-itd_sched_init (
+itd_sched_init(
+       struct ehci_hcd         *ehci,
        struct ehci_iso_sched   *iso_sched,
        struct ehci_iso_stream  *stream,
        struct urb              *urb
@@ -1107,7 +1241,7 @@ itd_sched_init (
                                && !(urb->transfer_flags & URB_NO_INTERRUPT))
                        trans |= EHCI_ITD_IOC;
                trans |= length << 16;
-               uframe->transaction = cpu_to_le32 (trans);
+               uframe->transaction = cpu_to_hc32(ehci, trans);
 
                /* might need to cross a buffer page within a uframe */
                uframe->bufp = (buf & ~(u64)0x0fff);
@@ -1149,7 +1283,7 @@ itd_urb_transaction (
        if (unlikely (sched == NULL))
                return -ENOMEM;
 
-       itd_sched_init (sched, stream, urb);
+       itd_sched_init(ehci, sched, stream, urb);
 
        if (urb->interval < 8)
                num_itds = 1 + (sched->span + 7) / 8;
@@ -1167,7 +1301,7 @@ itd_urb_transaction (
                /* prefer previously-allocated itds */
                if (likely (!list_empty(&stream->free_list))) {
                        itd = list_entry (stream->free_list.prev,
-                                        struct ehci_itd, itd_list);
+                                       struct ehci_itd, itd_list);
                        list_del (&itd->itd_list);
                        itd_dma = itd->itd_dma;
                } else
@@ -1294,7 +1428,7 @@ sitd_slot_ok (
                uframe += period_uframes;
        } while (uframe < mod);
 
-       stream->splits = cpu_to_le32(stream->raw_mask << (uframe & 7));
+       stream->splits = cpu_to_hc32(ehci, stream->raw_mask << (uframe & 7));
        return 1;
 }
 
@@ -1415,12 +1549,13 @@ ready:
 /*-------------------------------------------------------------------------*/
 
 static inline void
-itd_init (struct ehci_iso_stream *stream, struct ehci_itd *itd)
+itd_init(struct ehci_hcd *ehci, struct ehci_iso_stream *stream,
+               struct ehci_itd *itd)
 {
        int i;
 
        /* it's been recently zeroed */
-       itd->hw_next = EHCI_LIST_END;
+       itd->hw_next = EHCI_LIST_END(ehci);
        itd->hw_bufp [0] = stream->buf0;
        itd->hw_bufp [1] = stream->buf1;
        itd->hw_bufp [2] = stream->buf2;
@@ -1432,7 +1567,8 @@ itd_init (struct ehci_iso_stream *stream, struct ehci_itd *itd)
 }
 
 static inline void
-itd_patch (
+itd_patch(
+       struct ehci_hcd         *ehci,
        struct ehci_itd         *itd,
        struct ehci_iso_sched   *iso_sched,
        unsigned                index,
@@ -1447,17 +1583,18 @@ itd_patch (
        uframe &= 0x07;
        itd->index [uframe] = index;
 
-       itd->hw_transaction [uframe] = uf->transaction;
-       itd->hw_transaction [uframe] |= cpu_to_le32 (pg << 12);
-       itd->hw_bufp [pg] |= cpu_to_le32 (uf->bufp & ~(u32)0);
-       itd->hw_bufp_hi [pg] |= cpu_to_le32 ((u32)(uf->bufp >> 32));
+       itd->hw_transaction[uframe] = uf->transaction;
+       itd->hw_transaction[uframe] |= cpu_to_hc32(ehci, pg << 12);
+       itd->hw_bufp[pg] |= cpu_to_hc32(ehci, uf->bufp & ~(u32)0);
+       itd->hw_bufp_hi[pg] |= cpu_to_hc32(ehci, (u32)(uf->bufp >> 32));
 
        /* iso_frame_desc[].offset must be strictly increasing */
        if (unlikely (uf->cross)) {
                u64     bufp = uf->bufp + 4096;
+
                itd->pg = ++pg;
-               itd->hw_bufp [pg] |= cpu_to_le32 (bufp & ~(u32)0);
-               itd->hw_bufp_hi [pg] |= cpu_to_le32 ((u32)(bufp >> 32));
+               itd->hw_bufp[pg] |= cpu_to_hc32(ehci, bufp & ~(u32)0);
+               itd->hw_bufp_hi[pg] |= cpu_to_hc32(ehci, (u32)(bufp >> 32));
        }
 }
 
@@ -1470,7 +1607,7 @@ itd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_itd *itd)
        ehci->pshadow [frame].itd = itd;
        itd->frame = frame;
        wmb ();
-       ehci->periodic [frame] = cpu_to_le32 (itd->itd_dma) | Q_TYPE_ITD;
+       ehci->periodic[frame] = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD);
 }
 
 /* fit urb's itds into the selected schedule slot; activate as needed */
@@ -1515,14 +1652,14 @@ itd_link_urb (
                        list_move_tail (&itd->itd_list, &stream->td_list);
                        itd->stream = iso_stream_get (stream);
                        itd->urb = usb_get_urb (urb);
-                       itd_init (stream, itd);
+                       itd_init (ehci, stream, itd);
                }
 
                uframe = next_uframe & 0x07;
                frame = next_uframe >> 3;
 
                itd->usecs [uframe] = stream->usecs;
-               itd_patch (itd, iso_sched, packet, uframe);
+               itd_patch(ehci, itd, iso_sched, packet, uframe);
 
                next_uframe += stream->interval;
                stream->depth += stream->interval;
@@ -1570,7 +1707,7 @@ itd_complete (
                urb_index = itd->index[uframe];
                desc = &urb->iso_frame_desc [urb_index];
 
-               t = le32_to_cpup (&itd->hw_transaction [uframe]);
+               t = hc32_to_cpup(ehci, &itd->hw_transaction [uframe]);
                itd->hw_transaction [uframe] = 0;
                stream->depth -= stream->interval;
 
@@ -1700,7 +1837,8 @@ done:
  */
 
 static inline void
-sitd_sched_init (
+sitd_sched_init(
+       struct ehci_hcd         *ehci,
        struct ehci_iso_sched   *iso_sched,
        struct ehci_iso_stream  *stream,
        struct urb              *urb
@@ -1729,7 +1867,7 @@ sitd_sched_init (
                                && !(urb->transfer_flags & URB_NO_INTERRUPT))
                        trans |= SITD_IOC;
                trans |= length << 16;
-               packet->transaction = cpu_to_le32 (trans);
+               packet->transaction = cpu_to_hc32(ehci, trans);
 
                /* might need to cross a buffer page within a td */
                packet->bufp = buf;
@@ -1765,7 +1903,7 @@ sitd_urb_transaction (
        if (iso_sched == NULL)
                return -ENOMEM;
 
-       sitd_sched_init (iso_sched, stream, urb);
+       sitd_sched_init(ehci, iso_sched, stream, urb);
 
        /* allocate/init sITDs */
        spin_lock_irqsave (&ehci->lock, flags);
@@ -1817,7 +1955,8 @@ sitd_urb_transaction (
 /*-------------------------------------------------------------------------*/
 
 static inline void
-sitd_patch (
+sitd_patch(
+       struct ehci_hcd         *ehci,
        struct ehci_iso_stream  *stream,
        struct ehci_sitd        *sitd,
        struct ehci_iso_sched   *iso_sched,
@@ -1827,20 +1966,20 @@ sitd_patch (
        struct ehci_iso_packet  *uf = &iso_sched->packet [index];
        u64                     bufp = uf->bufp;
 
-       sitd->hw_next = EHCI_LIST_END;
+       sitd->hw_next = EHCI_LIST_END(ehci);
        sitd->hw_fullspeed_ep = stream->address;
        sitd->hw_uframe = stream->splits;
        sitd->hw_results = uf->transaction;
-       sitd->hw_backpointer = EHCI_LIST_END;
+       sitd->hw_backpointer = EHCI_LIST_END(ehci);
 
        bufp = uf->bufp;
-       sitd->hw_buf [0] = cpu_to_le32 (bufp);
-       sitd->hw_buf_hi [0] = cpu_to_le32 (bufp >> 32);
+       sitd->hw_buf[0] = cpu_to_hc32(ehci, bufp);
+       sitd->hw_buf_hi[0] = cpu_to_hc32(ehci, bufp >> 32);
 
-       sitd->hw_buf [1] = cpu_to_le32 (uf->buf1);
+       sitd->hw_buf[1] = cpu_to_hc32(ehci, uf->buf1);
        if (uf->cross)
                bufp += 4096;
-       sitd->hw_buf_hi [1] = cpu_to_le32 (bufp >> 32);
+       sitd->hw_buf_hi[1] = cpu_to_hc32(ehci, bufp >> 32);
        sitd->index = index;
 }
 
@@ -1853,7 +1992,7 @@ sitd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_sitd *sitd)
        ehci->pshadow [frame].sitd = sitd;
        sitd->frame = frame;
        wmb ();
-       ehci->periodic [frame] = cpu_to_le32 (sitd->sitd_dma) | Q_TYPE_SITD;
+       ehci->periodic[frame] = cpu_to_hc32(ehci, sitd->sitd_dma | Q_TYPE_SITD);
 }
 
 /* fit urb's sitds into the selected schedule slot; activate as needed */
@@ -1881,7 +2020,7 @@ sitd_link_urb (
                        urb->dev->devpath, stream->bEndpointAddress & 0x0f,
                        (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out",
                        (next_uframe >> 3) % ehci->periodic_size,
-                       stream->interval, le32_to_cpu (stream->splits));
+                       stream->interval, hc32_to_cpu(ehci, stream->splits));
                stream->start = jiffies;
        }
        ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++;
@@ -1902,7 +2041,7 @@ sitd_link_urb (
                sitd->stream = iso_stream_get (stream);
                sitd->urb = usb_get_urb (urb);
 
-               sitd_patch (stream, sitd, sched, packet);
+               sitd_patch(ehci, stream, sitd, sched, packet);
                sitd_link (ehci, (next_uframe >> 3) % ehci->periodic_size,
                                sitd);
 
@@ -1940,7 +2079,7 @@ sitd_complete (
 
        urb_index = sitd->index;
        desc = &urb->iso_frame_desc [urb_index];
-       t = le32_to_cpup (&sitd->hw_results);
+       t = hc32_to_cpup(ehci, &sitd->hw_results);
 
        /* report transfer status */
        if (t & SITD_ERRS) {
@@ -2095,7 +2234,7 @@ scan_periodic (struct ehci_hcd *ehci)
 
        for (;;) {
                union ehci_shadow       q, *q_p;
-               __le32                  type, *hw_p;
+               __hc32                  type, *hw_p;
                unsigned                uframes;
 
                /* don't scan past the live uframe */
@@ -2113,7 +2252,7 @@ restart:
                q_p = &ehci->pshadow [frame];
                hw_p = &ehci->periodic [frame];
                q.ptr = q_p->ptr;
-               type = Q_NEXT_TYPE (*hw_p);
+               type = Q_NEXT_TYPE(ehci, *hw_p);
                modified = 0;
 
                while (q.ptr != NULL) {
@@ -2122,11 +2261,11 @@ restart:
                        int                     live;
 
                        live = HC_IS_RUNNING (ehci_to_hcd(ehci)->state);
-                       switch (type) {
+                       switch (hc32_to_cpu(ehci, type)) {
                        case Q_TYPE_QH:
                                /* handle any completions */
                                temp.qh = qh_get (q.qh);
-                               type = Q_NEXT_TYPE (q.qh->hw_next);
+                               type = Q_NEXT_TYPE(ehci, q.qh->hw_next);
                                q = q.qh->qh_next;
                                modified = qh_completions (ehci, temp.qh);
                                if (unlikely (list_empty (&temp.qh->qtd_list)))
@@ -2137,10 +2276,10 @@ restart:
                                /* for "save place" FSTNs, look at QH entries
                                 * in the previous frame for completions.
                                 */
-                               if (q.fstn->hw_prev != EHCI_LIST_END) {
+                               if (q.fstn->hw_prev != EHCI_LIST_END(ehci)) {
                                        dbg ("ignoring completions from FSTNs");
                                }
-                               type = Q_NEXT_TYPE (q.fstn->hw_next);
+                               type = Q_NEXT_TYPE(ehci, q.fstn->hw_next);
                                q = q.fstn->fstn_next;
                                break;
                        case Q_TYPE_ITD:
@@ -2148,11 +2287,12 @@ restart:
                                rmb ();
                                for (uf = live ? uframes : 8; uf < 8; uf++) {
                                        if (0 == (q.itd->hw_transaction [uf]
-                                                       & ITD_ACTIVE))
+                                                       & ITD_ACTIVE(ehci)))
                                                continue;
                                        q_p = &q.itd->itd_next;
                                        hw_p = &q.itd->hw_next;
-                                       type = Q_NEXT_TYPE (q.itd->hw_next);
+                                       type = Q_NEXT_TYPE(ehci,
+                                                       q.itd->hw_next);
                                        q = *q_p;
                                        break;
                                }
@@ -2164,23 +2304,24 @@ restart:
                                 */
                                *q_p = q.itd->itd_next;
                                *hw_p = q.itd->hw_next;
-                               type = Q_NEXT_TYPE (q.itd->hw_next);
+                               type = Q_NEXT_TYPE(ehci, q.itd->hw_next);
                                wmb();
                                modified = itd_complete (ehci, q.itd);
                                q = *q_p;
                                break;
                        case Q_TYPE_SITD:
-                               if ((q.sitd->hw_results & SITD_ACTIVE)
+                               if ((q.sitd->hw_results & SITD_ACTIVE(ehci))
                                                && live) {
                                        q_p = &q.sitd->sitd_next;
                                        hw_p = &q.sitd->hw_next;
-                                       type = Q_NEXT_TYPE (q.sitd->hw_next);
+                                       type = Q_NEXT_TYPE(ehci,
+                                                       q.sitd->hw_next);
                                        q = *q_p;
                                        break;
                                }
                                *q_p = q.sitd->sitd_next;
                                *hw_p = q.sitd->hw_next;
-                               type = Q_NEXT_TYPE (q.sitd->hw_next);
+                               type = Q_NEXT_TYPE(ehci, q.sitd->hw_next);
                                wmb();
                                modified = sitd_complete (ehci, q.sitd);
                                q = *q_p;
index 46fa57a520d0d6b37a83c459bf1c2ec869369922..2c68a04230c18f822a72cfce68d79f53fd6cd2f6 100644 (file)
 
 /* definitions used for the EHCI driver */
 
+/*
+ * __hc32 and __hc16 are "Host Controller" types, they may be equivalent to
+ * __leXX (normally) or __beXX (given EHCI_BIG_ENDIAN_DESC), depending on
+ * the host controller implementation.
+ *
+ * To facilitate the strongest possible byte-order checking from "sparse"
+ * and so on, we use __leXX unless that's not practical.
+ */
+#ifdef CONFIG_USB_EHCI_BIG_ENDIAN_DESC
+typedef __u32 __bitwise __hc32;
+typedef __u16 __bitwise __hc16;
+#else
+#define __hc32 __le32
+#define __hc16 __le16
+#endif
+
 /* statistics can be kept for for tuning/monitoring */
 struct ehci_stats {
        /* irq usage */
@@ -55,6 +71,12 @@ struct ehci_hcd {                    /* one per controller */
        __u32                   hcs_params;     /* cached register copy */
        spinlock_t              lock;
 
+#ifdef CONFIG_CPU_FREQ
+       struct notifier_block   cpufreq_transition;
+       int                     cpufreq_changing;
+       struct list_head        split_intr_qhs;
+#endif
+
        /* async schedule support */
        struct ehci_qh          *async;
        struct ehci_qh          *reclaim;
@@ -64,7 +86,7 @@ struct ehci_hcd {                     /* one per controller */
        /* periodic schedule support */
 #define        DEFAULT_I_TDPS          1024            /* some HCs can do less */
        unsigned                periodic_size;
-       __le32                  *periodic;      /* hw periodic table */
+       __hc32                  *periodic;      /* hw periodic table */
        dma_addr_t              periodic_dma;
        unsigned                i_thresh;       /* uframes HC might cache */
 
@@ -74,11 +96,14 @@ struct ehci_hcd {                   /* one per controller */
 
        /* per root hub port */
        unsigned long           reset_done [EHCI_MAX_ROOT_PORTS];
+
        /* bit vectors (one bit per port) */
        unsigned long           bus_suspended;          /* which ports were
                        already suspended at the start of a bus suspend */
        unsigned long           companion_ports;        /* which ports are
                        dedicated to the companion controller */
+       unsigned long           owned_ports;            /* which ports are
+                       owned by the companion during a bus suspend */
 
        /* per-HC memory pools (could be per-bus, but ...) */
        struct dma_pool         *qh_pool;       /* qh per active urb */
@@ -97,6 +122,7 @@ struct ehci_hcd {                    /* one per controller */
        unsigned                no_selective_suspend:1;
        unsigned                has_fsl_port_bug:1; /* FreeScale */
        unsigned                big_endian_mmio:1;
+       unsigned                big_endian_desc:1;
 
        u8                      sbrn;           /* packed release number */
 
@@ -276,6 +302,12 @@ struct ehci_regs {
 #define PORT_RWC_BITS   (PORT_CSC | PORT_PEC | PORT_OCC)
 } __attribute__ ((packed));
 
+#define USBMODE                0x68            /* USB Device mode */
+#define USBMODE_SDIS   (1<<3)          /* Stream disable */
+#define USBMODE_BE     (1<<2)          /* BE/LE endianness select */
+#define USBMODE_CM_HC  (3<<0)          /* host controller mode */
+#define USBMODE_CM_IDLE        (0<<0)          /* idle state */
+
 /* Appendix C, Debug port ... intended for use with special "debug devices"
  * that can help if there's no serial console.  (nonstandard enumeration.)
  */
@@ -303,7 +335,7 @@ struct ehci_dbg_port {
 
 /*-------------------------------------------------------------------------*/
 
-#define        QTD_NEXT(dma)   cpu_to_le32((u32)dma)
+#define        QTD_NEXT(ehci, dma)     cpu_to_hc32(ehci, (u32)dma)
 
 /*
  * EHCI Specification 0.95 Section 3.5
@@ -315,9 +347,9 @@ struct ehci_dbg_port {
  */
 struct ehci_qtd {
        /* first part defined by EHCI spec */
-       __le32                  hw_next;          /* see EHCI 3.5.1 */
-       __le32                  hw_alt_next;      /* see EHCI 3.5.2 */
-       __le32                  hw_token;         /* see EHCI 3.5.3 */
+       __hc32                  hw_next;        /* see EHCI 3.5.1 */
+       __hc32                  hw_alt_next;    /* see EHCI 3.5.2 */
+       __hc32                  hw_token;       /* see EHCI 3.5.3 */
 #define        QTD_TOGGLE      (1 << 31)       /* data toggle */
 #define        QTD_LENGTH(tok) (((tok)>>16) & 0x7fff)
 #define        QTD_IOC         (1 << 15)       /* interrupt on complete */
@@ -331,8 +363,13 @@ struct ehci_qtd {
 #define        QTD_STS_MMF     (1 << 2)        /* incomplete split transaction */
 #define        QTD_STS_STS     (1 << 1)        /* split transaction state */
 #define        QTD_STS_PING    (1 << 0)        /* issue PING? */
-       __le32                  hw_buf [5];        /* see EHCI 3.5.4 */
-       __le32                  hw_buf_hi [5];        /* Appendix B */
+
+#define ACTIVE_BIT(ehci)       cpu_to_hc32(ehci, QTD_STS_ACTIVE)
+#define HALT_BIT(ehci)         cpu_to_hc32(ehci, QTD_STS_HALT)
+#define STATUS_BIT(ehci)       cpu_to_hc32(ehci, QTD_STS_STS)
+
+       __hc32                  hw_buf [5];        /* see EHCI 3.5.4 */
+       __hc32                  hw_buf_hi [5];        /* Appendix B */
 
        /* the rest is HCD-private */
        dma_addr_t              qtd_dma;                /* qtd address */
@@ -342,26 +379,33 @@ struct ehci_qtd {
 } __attribute__ ((aligned (32)));
 
 /* mask NakCnt+T in qh->hw_alt_next */
-#define QTD_MASK __constant_cpu_to_le32 (~0x1f)
+#define QTD_MASK(ehci) cpu_to_hc32 (ehci, ~0x1f)
 
 #define IS_SHORT_READ(token) (QTD_LENGTH (token) != 0 && QTD_PID (token) == 1)
 
 /*-------------------------------------------------------------------------*/
 
 /* type tag from {qh,itd,sitd,fstn}->hw_next */
-#define Q_NEXT_TYPE(dma) ((dma) & __constant_cpu_to_le32 (3 << 1))
+#define Q_NEXT_TYPE(ehci,dma)  ((dma) & cpu_to_hc32(ehci, 3 << 1))
 
+/*
+ * Now the following defines are not converted using the
+ * __constant_cpu_to_le32() macro anymore, since we have to support
+ * "dynamic" switching between be and le support, so that the driver
+ * can be used on one system with SoC EHCI controller using big-endian
+ * descriptors as well as a normal little-endian PCI EHCI controller.
+ */
 /* values for that type tag */
-#define Q_TYPE_ITD     __constant_cpu_to_le32 (0 << 1)
-#define Q_TYPE_QH      __constant_cpu_to_le32 (1 << 1)
-#define Q_TYPE_SITD    __constant_cpu_to_le32 (2 << 1)
-#define Q_TYPE_FSTN    __constant_cpu_to_le32 (3 << 1)
+#define Q_TYPE_ITD     (0 << 1)
+#define Q_TYPE_QH      (1 << 1)
+#define Q_TYPE_SITD    (2 << 1)
+#define Q_TYPE_FSTN    (3 << 1)
 
 /* next async queue entry, or pointer to interrupt/periodic QH */
-#define        QH_NEXT(dma)    (cpu_to_le32(((u32)dma)&~0x01f)|Q_TYPE_QH)
+#define QH_NEXT(ehci,dma)      (cpu_to_hc32(ehci, (((u32)dma)&~0x01f)|Q_TYPE_QH))
 
 /* for periodic/async schedules and qtd lists, mark end of list */
-#define        EHCI_LIST_END   __constant_cpu_to_le32(1) /* "null pointer" to hw */
+#define EHCI_LIST_END(ehci)    cpu_to_hc32(ehci, 1) /* "null pointer" to hw */
 
 /*
  * Entries in periodic shadow table are pointers to one of four kinds
@@ -376,7 +420,7 @@ union ehci_shadow {
        struct ehci_itd         *itd;           /* Q_TYPE_ITD */
        struct ehci_sitd        *sitd;          /* Q_TYPE_SITD */
        struct ehci_fstn        *fstn;          /* Q_TYPE_FSTN */
-       __le32                  *hw_next;       /* (all types) */
+       __hc32                  *hw_next;       /* (all types) */
        void                    *ptr;
 };
 
@@ -392,23 +436,27 @@ union ehci_shadow {
 
 struct ehci_qh {
        /* first part defined by EHCI spec */
-       __le32                  hw_next;         /* see EHCI 3.6.1 */
-       __le32                  hw_info1;        /* see EHCI 3.6.2 */
+       __hc32                  hw_next;        /* see EHCI 3.6.1 */
+       __hc32                  hw_info1;       /* see EHCI 3.6.2 */
 #define        QH_HEAD         0x00008000
-       __le32                  hw_info2;        /* see EHCI 3.6.2 */
+#define        QH_INACTIVATE   0x00000080
+
+#define INACTIVATE_BIT(ehci)   cpu_to_hc32(ehci, QH_INACTIVATE)
+
+       __hc32                  hw_info2;        /* see EHCI 3.6.2 */
 #define        QH_SMASK        0x000000ff
 #define        QH_CMASK        0x0000ff00
 #define        QH_HUBADDR      0x007f0000
 #define        QH_HUBPORT      0x3f800000
 #define        QH_MULT         0xc0000000
-       __le32                  hw_current;      /* qtd list - see EHCI 3.6.4 */
+       __hc32                  hw_current;     /* qtd list - see EHCI 3.6.4 */
 
        /* qtd overlay (hardware parts of a struct ehci_qtd) */
-       __le32                  hw_qtd_next;
-       __le32                  hw_alt_next;
-       __le32                  hw_token;
-       __le32                  hw_buf [5];
-       __le32                  hw_buf_hi [5];
+       __hc32                  hw_qtd_next;
+       __hc32                  hw_alt_next;
+       __hc32                  hw_token;
+       __hc32                  hw_buf [5];
+       __hc32                  hw_buf_hi [5];
 
        /* the rest is HCD-private */
        dma_addr_t              qh_dma;         /* address of qh */
@@ -418,7 +466,14 @@ struct ehci_qh {
        struct ehci_qh          *reclaim;       /* next to reclaim */
 
        struct ehci_hcd         *ehci;
-       struct kref             kref;
+
+       /*
+        * Do NOT use atomic operations for QH refcounting. On some CPUs
+        * (PPC7448 for example), atomic operations cannot be performed on
+        * memory that is cache-inhibited (i.e. being used for DMA).
+        * Spinlocks are used to protect all QH fields.
+        */
+       u32                     refcount;
        unsigned                stamp;
 
        u8                      qh_state;
@@ -437,6 +492,10 @@ struct ehci_qh {
        unsigned short          start;          /* where polling starts */
 #define NO_FRAME ((unsigned short)~0)                  /* pick new start */
        struct usb_device       *dev;           /* access to TT */
+#ifdef CONFIG_CPU_FREQ
+       struct list_head        split_intr_qhs; /* list of split qhs */
+       __le32                  was_active;     /* active bit before "i" set */
+#endif
 } __attribute__ ((aligned (32)));
 
 /*-------------------------------------------------------------------------*/
@@ -445,7 +504,7 @@ struct ehci_qh {
 struct ehci_iso_packet {
        /* These will be copied to iTD when scheduling */
        u64                     bufp;           /* itd->hw_bufp{,_hi}[pg] |= */
-       __le32                  transaction;    /* itd->hw_transaction[i] |= */
+       __hc32                  transaction;    /* itd->hw_transaction[i] |= */
        u8                      cross;          /* buf crosses pages */
        /* for full speed OUT splits */
        u32                     buf1;
@@ -467,8 +526,8 @@ struct ehci_iso_sched {
  */
 struct ehci_iso_stream {
        /* first two fields match QH, but info1 == 0 */
-       __le32                  hw_next;
-       __le32                  hw_info1;
+       __hc32                  hw_next;
+       __hc32                  hw_info1;
 
        u32                     refcount;
        u8                      bEndpointAddress;
@@ -483,7 +542,7 @@ struct ehci_iso_stream {
        unsigned long           start;          /* jiffies */
        unsigned long           rescheduled;
        int                     next_uframe;
-       __le32                  splits;
+       __hc32                  splits;
 
        /* the rest is derived from the endpoint descriptor,
         * trusting urb->interval == f(epdesc->bInterval) and
@@ -497,12 +556,12 @@ struct ehci_iso_stream {
        unsigned                bandwidth;
 
        /* This is used to initialize iTD's hw_bufp fields */
-       __le32                  buf0;
-       __le32                  buf1;
-       __le32                  buf2;
+       __hc32                  buf0;
+       __hc32                  buf1;
+       __hc32                  buf2;
 
        /* this is used to initialize sITD's tt info */
-       __le32                  address;
+       __hc32                  address;
 };
 
 /*-------------------------------------------------------------------------*/
@@ -515,8 +574,8 @@ struct ehci_iso_stream {
  */
 struct ehci_itd {
        /* first part defined by EHCI spec */
-       __le32                  hw_next;           /* see EHCI 3.3.1 */
-       __le32                  hw_transaction [8]; /* see EHCI 3.3.2 */
+       __hc32                  hw_next;           /* see EHCI 3.3.1 */
+       __hc32                  hw_transaction [8]; /* see EHCI 3.3.2 */
 #define EHCI_ISOC_ACTIVE        (1<<31)        /* activate transfer this slot */
 #define EHCI_ISOC_BUF_ERR       (1<<30)        /* Data buffer error */
 #define EHCI_ISOC_BABBLE        (1<<29)        /* babble detected */
@@ -524,10 +583,10 @@ struct ehci_itd {
 #define        EHCI_ITD_LENGTH(tok)    (((tok)>>16) & 0x0fff)
 #define        EHCI_ITD_IOC            (1 << 15)       /* interrupt on complete */
 
-#define ITD_ACTIVE     __constant_cpu_to_le32(EHCI_ISOC_ACTIVE)
+#define ITD_ACTIVE(ehci)       cpu_to_hc32(ehci, EHCI_ISOC_ACTIVE)
 
-       __le32                  hw_bufp [7];    /* see EHCI 3.3.3 */
-       __le32                  hw_bufp_hi [7]; /* Appendix B */
+       __hc32                  hw_bufp [7];    /* see EHCI 3.3.3 */
+       __hc32                  hw_bufp_hi [7]; /* Appendix B */
 
        /* the rest is HCD-private */
        dma_addr_t              itd_dma;        /* for this itd */
@@ -554,11 +613,11 @@ struct ehci_itd {
  */
 struct ehci_sitd {
        /* first part defined by EHCI spec */
-       __le32                  hw_next;
+       __hc32                  hw_next;
 /* uses bit field macros above - see EHCI 0.95 Table 3-8 */
-       __le32                  hw_fullspeed_ep;        /* EHCI table 3-9 */
-       __le32                  hw_uframe;              /* EHCI table 3-10 */
-       __le32                  hw_results;             /* EHCI table 3-11 */
+       __hc32                  hw_fullspeed_ep;        /* EHCI table 3-9 */
+       __hc32                  hw_uframe;              /* EHCI table 3-10 */
+       __hc32                  hw_results;             /* EHCI table 3-11 */
 #define        SITD_IOC        (1 << 31)       /* interrupt on completion */
 #define        SITD_PAGE       (1 << 30)       /* buffer 0/1 */
 #define        SITD_LENGTH(x)  (0x3ff & ((x)>>16))
@@ -570,11 +629,11 @@ struct ehci_sitd {
 #define        SITD_STS_MMF    (1 << 2)        /* incomplete split transaction */
 #define        SITD_STS_STS    (1 << 1)        /* split transaction state */
 
-#define SITD_ACTIVE    __constant_cpu_to_le32(SITD_STS_ACTIVE)
+#define SITD_ACTIVE(ehci)      cpu_to_hc32(ehci, SITD_STS_ACTIVE)
 
-       __le32                  hw_buf [2];             /* EHCI table 3-12 */
-       __le32                  hw_backpointer;         /* EHCI table 3-13 */
-       __le32                  hw_buf_hi [2];          /* Appendix B */
+       __hc32                  hw_buf [2];             /* EHCI table 3-12 */
+       __hc32                  hw_backpointer;         /* EHCI table 3-13 */
+       __hc32                  hw_buf_hi [2];          /* Appendix B */
 
        /* the rest is HCD-private */
        dma_addr_t              sitd_dma;
@@ -599,8 +658,8 @@ struct ehci_sitd {
  * it hits a "restore" FSTN; then it returns to finish other uframe 0/1 work.
  */
 struct ehci_fstn {
-       __le32                  hw_next;        /* any periodic q entry */
-       __le32                  hw_prev;        /* qh or EHCI_LIST_END */
+       __hc32                  hw_next;        /* any periodic q entry */
+       __hc32                  hw_prev;        /* qh or EHCI_LIST_END */
 
        /* the rest is HCD-private */
        dma_addr_t              fstn_dma;
@@ -672,8 +731,21 @@ ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc)
 #define ehci_big_endian_mmio(e)                0
 #endif
 
-static inline unsigned int ehci_readl (const struct ehci_hcd *ehci,
-                                      __u32 __iomem * regs)
+/*
+ * Big-endian read/write functions are arch-specific.
+ * Other arches can be added if/when they're needed.
+ *
+ * REVISIT: arch/powerpc now has readl/writel_be, so the
+ * definition below can die once the 4xx support is
+ * finally ported over.
+ */
+#if defined(CONFIG_PPC)
+#define readl_be(addr)         in_be32((__force unsigned *)addr)
+#define writel_be(val, addr)   out_be32((__force unsigned *)addr, val)
+#endif
+
+static inline unsigned int ehci_readl(const struct ehci_hcd *ehci,
+               __u32 __iomem * regs)
 {
 #ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO
        return ehci_big_endian_mmio(ehci) ?
@@ -684,8 +756,8 @@ static inline unsigned int ehci_readl (const struct ehci_hcd *ehci,
 #endif
 }
 
-static inline void ehci_writel (const struct ehci_hcd *ehci,
-                               const unsigned int val, __u32 __iomem *regs)
+static inline void ehci_writel(const struct ehci_hcd *ehci,
+               const unsigned int val, __u32 __iomem *regs)
 {
 #ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO
        ehci_big_endian_mmio(ehci) ?
@@ -698,6 +770,62 @@ static inline void ehci_writel (const struct ehci_hcd *ehci,
 
 /*-------------------------------------------------------------------------*/
 
+/*
+ * The AMCC 440EPx not only implements its EHCI registers in big-endian
+ * format, but also its DMA data structures (descriptors).
+ *
+ * EHCI controllers accessed through PCI work normally (little-endian
+ * everywhere), so we won't bother supporting a BE-only mode for now.
+ */
+#ifdef CONFIG_USB_EHCI_BIG_ENDIAN_DESC
+#define ehci_big_endian_desc(e)                ((e)->big_endian_desc)
+
+/* cpu to ehci */
+static inline __hc32 cpu_to_hc32 (const struct ehci_hcd *ehci, const u32 x)
+{
+       return ehci_big_endian_desc(ehci)
+               ? (__force __hc32)cpu_to_be32(x)
+               : (__force __hc32)cpu_to_le32(x);
+}
+
+/* ehci to cpu */
+static inline u32 hc32_to_cpu (const struct ehci_hcd *ehci, const __hc32 x)
+{
+       return ehci_big_endian_desc(ehci)
+               ? be32_to_cpu((__force __be32)x)
+               : le32_to_cpu((__force __le32)x);
+}
+
+static inline u32 hc32_to_cpup (const struct ehci_hcd *ehci, const __hc32 *x)
+{
+       return ehci_big_endian_desc(ehci)
+               ? be32_to_cpup((__force __be32 *)x)
+               : le32_to_cpup((__force __le32 *)x);
+}
+
+#else
+
+/* cpu to ehci */
+static inline __hc32 cpu_to_hc32 (const struct ehci_hcd *ehci, const u32 x)
+{
+       return cpu_to_le32(x);
+}
+
+/* ehci to cpu */
+static inline u32 hc32_to_cpu (const struct ehci_hcd *ehci, const __hc32 x)
+{
+       return le32_to_cpu(x);
+}
+
+static inline u32 hc32_to_cpup (const struct ehci_hcd *ehci, const __hc32 *x)
+{
+       return le32_to_cpup(x);
+}
+
+#endif
+
+/*-------------------------------------------------------------------------*/
+
 #ifndef DEBUG
 #define STUB_DEBUG_FILES
 #endif /* DEBUG */
index 273d5ddb72be27ce794c59c3f742409ebf3284b8..6f9e43e9a6cab69072fe420a460d74074f77e6b7 100644 (file)
@@ -23,7 +23,7 @@
 /* debug| print the main components of an URB
  * small: 0) header + data packets 1) just header
  */
-static void __attribute__((unused))
+static void __maybe_unused
 urb_print (struct urb * urb, char * str, int small)
 {
        unsigned int pipe= urb->pipe;
@@ -338,7 +338,7 @@ static void ohci_dump_td (const struct ohci_hcd *ohci, const char *label,
 }
 
 /* caller MUST own hcd spinlock if verbose is set! */
-static void __attribute__((unused))
+static void __maybe_unused
 ohci_dump_ed (const struct ohci_hcd *ohci, const char *label,
                const struct ed *ed, int verbose)
 {
index a66637e725f3e763b11bbc4257ee55bd64a91c0d..2038125b7f8cf19143d0994b747220648a497282 100644 (file)
 #include <linux/dma-mapping.h>
 #include <linux/dmapool.h>
 #include <linux/reboot.h>
+#include <linux/workqueue.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/system.h>
 #include <asm/unaligned.h>
 #include <asm/byteorder.h>
-#ifdef CONFIG_PPC_PS3
-#include <asm/firmware.h>
-#endif
 
 #include "../core/hcd.h"
 
@@ -82,6 +80,8 @@ static const char     hcd_name [] = "ohci_hcd";
 static void ohci_dump (struct ohci_hcd *ohci, int verbose);
 static int ohci_init (struct ohci_hcd *ohci);
 static void ohci_stop (struct usb_hcd *hcd);
+static int ohci_restart (struct ohci_hcd *ohci);
+static void ohci_quirk_nec_worker (struct work_struct *work);
 
 #include "ohci-hub.c"
 #include "ohci-dbg.c"
@@ -510,15 +510,7 @@ static int ohci_run (struct ohci_hcd *ohci)
        // flush the writes
        (void) ohci_readl (ohci, &ohci->regs->control);
        msleep(temp);
-       temp = roothub_a (ohci);
-       if (!(temp & RH_A_NPS)) {
-               /* power down each port */
-               for (temp = 0; temp < ohci->num_ports; temp++)
-                       ohci_writel (ohci, RH_PS_LSDA,
-                               &ohci->regs->roothub.portstatus [temp]);
-       }
-       // flush those writes
-       (void) ohci_readl (ohci, &ohci->regs->control);
+
        memset (ohci->hcca, 0, sizeof (struct ohci_hcca));
 
        /* 2msec timelimit here means no irqs/preempt */
@@ -659,9 +651,20 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd)
        }
 
        if (ints & OHCI_INTR_UE) {
-               disable (ohci);
-               ohci_err (ohci, "OHCI Unrecoverable Error, disabled\n");
                // e.g. due to PCI Master/Target Abort
+               if (ohci->flags & OHCI_QUIRK_NEC) {
+                       /* Workaround for a silicon bug in some NEC chips used
+                        * in Apple's PowerBooks. Adapted from Darwin code.
+                        */
+                       ohci_err (ohci, "OHCI Unrecoverable Error, scheduling NEC chip restart\n");
+
+                       ohci_writel (ohci, OHCI_INTR_UE, &regs->intrdisable);
+
+                       schedule_work (&ohci->nec_work);
+               } else {
+                       disable (ohci);
+                       ohci_err (ohci, "OHCI Unrecoverable Error, disabled\n");
+               }
 
                ohci_dump (ohci, 1);
                ohci_usb_reset (ohci);
@@ -763,23 +766,16 @@ static void ohci_stop (struct usb_hcd *hcd)
 /*-------------------------------------------------------------------------*/
 
 /* must not be called from interrupt context */
-
-#ifdef CONFIG_PM
-
 static int ohci_restart (struct ohci_hcd *ohci)
 {
        int temp;
        int i;
        struct urb_priv *priv;
 
-       /* mark any devices gone, so they do nothing till khubd disconnects.
-        * recycle any "live" eds/tds (and urbs) right away.
-        * later, khubd disconnect processing will recycle the other state,
-        * (either as disconnect/reconnect, or maybe someday as a reset).
-        */
        spin_lock_irq(&ohci->lock);
        disable (ohci);
-       usb_root_hub_lost_power(ohci_to_hcd(ohci)->self.root_hub);
+
+       /* Recycle any "live" eds/tds (and urbs). */
        if (!list_empty (&ohci->pending))
                ohci_dbg(ohci, "abort schedule...\n");
        list_for_each_entry (priv, &ohci->pending, pending) {
@@ -826,20 +822,31 @@ static int ohci_restart (struct ohci_hcd *ohci)
        if ((temp = ohci_run (ohci)) < 0) {
                ohci_err (ohci, "can't restart, %d\n", temp);
                return temp;
-       } else {
-               /* here we "know" root ports should always stay powered,
-                * and that if we try to turn them back on the root hub
-                * will respond to CSC processing.
-                */
-               i = ohci->num_ports;
-               while (i--)
-                       ohci_writel (ohci, RH_PS_PSS,
-                               &ohci->regs->roothub.portstatus [i]);
-               ohci_dbg (ohci, "restart complete\n");
        }
+       ohci_dbg(ohci, "restart complete\n");
        return 0;
 }
-#endif
+
+/*-------------------------------------------------------------------------*/
+
+/* NEC workaround */
+static void ohci_quirk_nec_worker(struct work_struct *work)
+{
+       struct ohci_hcd *ohci = container_of(work, struct ohci_hcd, nec_work);
+       int status;
+
+       status = ohci_init(ohci);
+       if (status != 0) {
+               ohci_err(ohci, "Restarting NEC controller failed "
+                        "in ohci_init, %d\n", status);
+               return;
+       }
+
+       status = ohci_restart(ohci);
+       if (status != 0)
+               ohci_err(ohci, "Restarting NEC controller failed "
+                        "in ohci_restart, %d\n", status);
+}
 
 /*-------------------------------------------------------------------------*/
 
@@ -917,7 +924,7 @@ MODULE_LICENSE ("GPL");
 
 #ifdef CONFIG_PPC_PS3
 #include "ohci-ps3.c"
-#define PS3_SYSTEM_BUS_DRIVER  ps3_ohci_sb_driver
+#define PS3_SYSTEM_BUS_DRIVER  ps3_ohci_driver
 #endif
 
 #if    !defined(PCI_DRIVER) &&         \
@@ -940,12 +947,9 @@ static int __init ohci_hcd_mod_init(void)
                sizeof (struct ed), sizeof (struct td));
 
 #ifdef PS3_SYSTEM_BUS_DRIVER
-       if (firmware_has_feature(FW_FEATURE_PS3_LV1)) {
-               retval = ps3_system_bus_driver_register(
-                               &PS3_SYSTEM_BUS_DRIVER);
-               if (retval < 0)
-                       goto error_ps3;
-       }
+       retval = ps3_ohci_driver_register(&PS3_SYSTEM_BUS_DRIVER);
+       if (retval < 0)
+               goto error_ps3;
 #endif
 
 #ifdef PLATFORM_DRIVER
@@ -991,8 +995,7 @@ static int __init ohci_hcd_mod_init(void)
  error_platform:
 #endif
 #ifdef PS3_SYSTEM_BUS_DRIVER
-       if (firmware_has_feature(FW_FEATURE_PS3_LV1))
-               ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
+       ps3_ohci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
  error_ps3:
 #endif
        return retval;
@@ -1014,8 +1017,7 @@ static void __exit ohci_hcd_mod_exit(void)
        platform_driver_unregister(&PLATFORM_DRIVER);
 #endif
 #ifdef PS3_SYSTEM_BUS_DRIVER
-       if (firmware_has_feature(FW_FEATURE_PS3_LV1))
-               ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
+       ps3_ohci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
 #endif
 }
 module_exit(ohci_hcd_mod_exit);
index bb9cc595219e84cb0582250dc857d9892a503c0a..48e4b11f4d3ea53a2d837636e5ae72de4a0724af 100644 (file)
@@ -55,8 +55,6 @@ static void dl_done_list (struct ohci_hcd *);
 static void finish_unlinks (struct ohci_hcd *, u16);
 
 #ifdef CONFIG_PM
-static int ohci_restart(struct ohci_hcd *ohci);
-
 static int ohci_rh_suspend (struct ohci_hcd *ohci, int autostop)
 __releases(ohci->lock)
 __acquires(ohci->lock)
@@ -191,6 +189,9 @@ __acquires(ohci->lock)
                        spin_unlock_irq (&ohci->lock);
                        (void) ohci_init (ohci);
                        status = ohci_restart (ohci);
+
+                       usb_root_hub_lost_power(hcd->self.root_hub);
+
                        spin_lock_irq (&ohci->lock);
                }
                return status;
index 2f20d3dc895b8b4a959459573f4089e2014f27f8..450c7b460c5ab092e62ab13828ec41874f483b95 100644 (file)
@@ -28,6 +28,7 @@ static void ohci_hcd_init (struct ohci_hcd *ohci)
        ohci->next_statechange = jiffies;
        spin_lock_init (&ohci->lock);
        INIT_LIST_HEAD (&ohci->pending);
+       INIT_WORK (&ohci->nec_work, ohci_quirk_nec_worker);
 }
 
 /*-------------------------------------------------------------------------*/
index ca62cb583221a877e0f819b27de91a6d7e62d066..a5e2eb85d073bd69cb9e356cffc5f202e489d305 100644 (file)
@@ -111,6 +111,18 @@ static int ohci_quirk_toshiba_scc(struct usb_hcd *hcd)
 #endif
 }
 
+/* Check for NEC chip and apply quirk for allegedly lost interrupts.
+ */
+static int ohci_quirk_nec(struct usb_hcd *hcd)
+{
+       struct ohci_hcd *ohci = hcd_to_ohci (hcd);
+
+       ohci->flags |= OHCI_QUIRK_NEC;
+       ohci_dbg (ohci, "enabled NEC chipset lost interrupt quirk\n");
+
+       return 0;
+}
+
 /* List of quirks for OHCI */
 static const struct pci_device_id ohci_pci_quirks[] = {
        {
@@ -133,6 +145,10 @@ static const struct pci_device_id ohci_pci_quirks[] = {
                PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA_2, 0x01b6),
                .driver_data = (unsigned long)ohci_quirk_toshiba_scc,
        },
+       {
+               PCI_DEVICE(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB),
+               .driver_data = (unsigned long)ohci_quirk_nec,
+       },
        {
                /* Toshiba portege 4000 */
                .vendor         = PCI_VENDOR_ID_AL,
@@ -202,6 +218,42 @@ static int __devinit ohci_pci_start (struct usb_hcd *hcd)
        return ret;
 }
 
+#if    defined(CONFIG_USB_PERSIST) && (defined(CONFIG_USB_EHCI_HCD) || \
+               defined(CONFIG_USB_EHCI_HCD_MODULE))
+
+/* Following a power loss, we must prepare to regain control of the ports
+ * we used to own.  This means turning on the port power before ehci-hcd
+ * tries to switch ownership.
+ *
+ * This isn't a 100% perfect solution.  On most systems the OHCI controllers
+ * lie at lower PCI addresses than the EHCI controller, so they will be
+ * discovered (and hence resumed) first.  But there is no guarantee things
+ * will always work this way.  If the EHCI controller is resumed first and
+ * the OHCI ports are unpowered, then the handover will fail.
+ */
+static void prepare_for_handover(struct usb_hcd *hcd)
+{
+       struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+       int             port;
+
+       /* Here we "know" root ports should always stay powered */
+       ohci_dbg(ohci, "powerup ports\n");
+       for (port = 0; port < ohci->num_ports; port++)
+               ohci_writel(ohci, RH_PS_PPS,
+                               &ohci->regs->roothub.portstatus[port]);
+
+       /* Flush those writes */
+       ohci_readl(ohci, &ohci->regs->control);
+       msleep(20);
+}
+
+#else
+
+static inline void prepare_for_handover(struct usb_hcd *hcd)
+{ }
+
+#endif /* CONFIG_USB_PERSIST etc. */
+
 #ifdef CONFIG_PM
 
 static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message)
@@ -241,7 +293,10 @@ static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message)
 static int ohci_pci_resume (struct usb_hcd *hcd)
 {
        set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
-       usb_hcd_resume_root_hub(hcd);
+
+       /* FIXME: we should try to detect loss of VBUS power here */
+       prepare_for_handover(hcd);
+
        return 0;
 }
 
index d601bbb9387bb5205d6c29aed3208a405c186bfc..ca2a6abbc1172e21ab2924920268894f5566dd1e 100644 (file)
@@ -134,7 +134,7 @@ static int isp1301_attach(struct i2c_adapter *adap, int addr, int kind)
 {
        struct i2c_client *c;
 
-       c = (struct i2c_client *)kzalloc(sizeof(*c), GFP_KERNEL);
+       c = kzalloc(sizeof(*c), GFP_KERNEL);
 
        if (!c)
                return -ENOMEM;
index d7cf07288b0bdbea54e444e9d7e862349eaf1b8d..01a0caeaa6bcc9345b74131baa03d3acfb956439 100644 (file)
@@ -18,6 +18,7 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <asm/firmware.h>
 #include <asm/ps3.h>
 
 static int ps3_ohci_hc_reset(struct usb_hcd *hcd)
@@ -75,7 +76,7 @@ static const struct hc_driver ps3_ohci_hc_driver = {
 #endif
 };
 
-static int ps3_ohci_sb_probe(struct ps3_system_bus_device *dev)
+static int ps3_ohci_probe(struct ps3_system_bus_device *dev)
 {
        int result;
        struct usb_hcd *hcd;
@@ -87,13 +88,31 @@ static int ps3_ohci_sb_probe(struct ps3_system_bus_device *dev)
                goto fail_start;
        }
 
+       result = ps3_open_hv_device(dev);
+
+       if (result) {
+               dev_dbg(&dev->core, "%s:%d: ps3_open_hv_device failed: %s\n",
+                       __func__, __LINE__, ps3_result(result));
+               result = -EPERM;
+               goto fail_open;
+       }
+
+       result = ps3_dma_region_create(dev->d_region);
+
+       if (result) {
+               dev_dbg(&dev->core, "%s:%d: ps3_dma_region_create failed: "
+                       "(%d)\n", __func__, __LINE__, result);
+               BUG_ON("check region type");
+               goto fail_dma_region;
+       }
+
        result = ps3_mmio_region_create(dev->m_region);
 
        if (result) {
                dev_dbg(&dev->core, "%s:%d: ps3_map_mmio_region failed\n",
                        __func__, __LINE__);
                result = -EPERM;
-               goto fail_mmio;
+               goto fail_mmio_region;
        }
 
        dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__,
@@ -122,6 +141,11 @@ static int ps3_ohci_sb_probe(struct ps3_system_bus_device *dev)
 
        hcd->rsrc_start = dev->m_region->lpar_addr;
        hcd->rsrc_len = dev->m_region->len;
+
+       if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name))
+               dev_dbg(&dev->core, "%s:%d: request_mem_region failed\n",
+                       __func__, __LINE__);
+
        hcd->regs = ioremap(dev->m_region->lpar_addr, dev->m_region->len);
 
        if (!hcd->regs) {
@@ -155,34 +179,73 @@ static int ps3_ohci_sb_probe(struct ps3_system_bus_device *dev)
 fail_add_hcd:
        iounmap(hcd->regs);
 fail_ioremap:
+       release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
        usb_put_hcd(hcd);
 fail_create_hcd:
        ps3_io_irq_destroy(virq);
 fail_irq:
        ps3_free_mmio_region(dev->m_region);
-fail_mmio:
+fail_mmio_region:
+       ps3_dma_region_free(dev->d_region);
+fail_dma_region:
+       ps3_close_hv_device(dev);
+fail_open:
 fail_start:
        return result;
 }
 
-static int ps3_ohci_sb_remove (struct ps3_system_bus_device *dev)
+static int ps3_ohci_remove (struct ps3_system_bus_device *dev)
 {
+       unsigned int tmp;
        struct usb_hcd *hcd =
                (struct usb_hcd *)ps3_system_bus_get_driver_data(dev);
 
-       usb_put_hcd(hcd);
+       BUG_ON(!hcd);
+
+       dev_dbg(&dev->core, "%s:%d: regs %p\n", __func__, __LINE__, hcd->regs);
+       dev_dbg(&dev->core, "%s:%d: irq %u\n", __func__, __LINE__, hcd->irq);
+
+       tmp = hcd->irq;
+
+       usb_remove_hcd(hcd);
+
        ps3_system_bus_set_driver_data(dev, NULL);
 
+       BUG_ON(!hcd->regs);
+       iounmap(hcd->regs);
+
+       release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+       usb_put_hcd(hcd);
+
+       ps3_io_irq_destroy(tmp);
+       ps3_free_mmio_region(dev->m_region);
+
+       ps3_dma_region_free(dev->d_region);
+       ps3_close_hv_device(dev);
+
        return 0;
 }
 
-MODULE_ALIAS("ps3-ohci");
+static int ps3_ohci_driver_register(struct ps3_system_bus_driver *drv)
+{
+       return firmware_has_feature(FW_FEATURE_PS3_LV1)
+               ? ps3_system_bus_driver_register(drv)
+               : 0;
+}
+
+static void ps3_ohci_driver_unregister(struct ps3_system_bus_driver *drv)
+{
+       if (firmware_has_feature(FW_FEATURE_PS3_LV1))
+               ps3_system_bus_driver_unregister(drv);
+}
+
+MODULE_ALIAS(PS3_MODULE_ALIAS_OHCI);
 
-static struct ps3_system_bus_driver ps3_ohci_sb_driver = {
+static struct ps3_system_bus_driver ps3_ohci_driver = {
+       .core.name = "ps3-ohci-driver",
+       .core.owner = THIS_MODULE,
        .match_id = PS3_MATCH_ID_OHCI,
-       .core = {
-               .name = "ps3-ohci-driver",
-       },
-       .probe = ps3_ohci_sb_probe,
-       .remove = ps3_ohci_sb_remove,
+       .probe = ps3_ohci_probe,
+       .remove = ps3_ohci_remove,
+       .shutdown = ps3_ohci_remove,
 };
index c2b5ecfe5e9fa8ca88b33a28b792dd15e3a43fb8..4ada43cf1387db28fefe811f18f5e02ac098666c 100644 (file)
@@ -397,8 +397,10 @@ struct ohci_hcd {
 #define        OHCI_QUIRK_BE_DESC      0x08                    /* BE descriptors */
 #define        OHCI_QUIRK_BE_MMIO      0x10                    /* BE registers */
 #define        OHCI_QUIRK_ZFMICRO      0x20                    /* Compaq ZFMicro chipset*/
+#define        OHCI_QUIRK_NEC          0x40                    /* lost interrupts */
        // there are also chip quirks/bugs in init logic
 
+       struct work_struct      nec_work;       /* Worker for NEC quirk */
 };
 
 /* convert between an hcd pointer and the corresponding ohci_hcd */
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
new file mode 100644 (file)
index 0000000..a7a7070
--- /dev/null
@@ -0,0 +1,2244 @@
+/*
+ * R8A66597 HCD (Host Controller Driver)
+ *
+ * Copyright (C) 2006-2007 Renesas Solutions Corp.
+ * Portions Copyright (C) 2004 Psion Teklogix (for NetBook PRO)
+ * Portions Copyright (C) 2004-2005 David Brownell
+ * Portions Copyright (C) 1999 Roman Weissgaerber
+ *
+ * Author : Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/timer.h>
+#include <linux/delay.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/usb.h>
+#include <linux/platform_device.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+
+#include "../core/hcd.h"
+#include "r8a66597.h"
+
+MODULE_DESCRIPTION("R8A66597 USB Host Controller Driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Yoshihiro Shimoda");
+
+#define DRIVER_VERSION "29 May 2007"
+
+static const char hcd_name[] = "r8a66597_hcd";
+
+/* module parameters */
+static unsigned short clock = XTAL12;
+module_param(clock, ushort, 0644);
+MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0(default=0)");
+static unsigned short vif = LDRV;
+module_param(vif, ushort, 0644);
+MODULE_PARM_DESC(vif, "input VIF: 3.3V=32768, 1.5V=0(default=32768)");
+static unsigned short endian = 0;
+module_param(endian, ushort, 0644);
+MODULE_PARM_DESC(endian, "data endian: big=256, little=0(default=0)");
+static unsigned short irq_sense = INTL;
+module_param(irq_sense, ushort, 0644);
+MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=32, falling edge=0(default=32)");
+
+static void packet_write(struct r8a66597 *r8a66597, u16 pipenum);
+static int r8a66597_get_frame(struct usb_hcd *hcd);
+
+/* this function must be called with interrupt disabled */
+static void enable_pipe_irq(struct r8a66597 *r8a66597, u16 pipenum,
+                           unsigned long reg)
+{
+       u16 tmp;
+
+       tmp = r8a66597_read(r8a66597, INTENB0);
+       r8a66597_bclr(r8a66597, BEMPE | NRDYE | BRDYE, INTENB0);
+       r8a66597_bset(r8a66597, 1 << pipenum, reg);
+       r8a66597_write(r8a66597, tmp, INTENB0);
+}
+
+/* this function must be called with interrupt disabled */
+static void disable_pipe_irq(struct r8a66597 *r8a66597, u16 pipenum,
+                            unsigned long reg)
+{
+       u16 tmp;
+
+       tmp = r8a66597_read(r8a66597, INTENB0);
+       r8a66597_bclr(r8a66597, BEMPE | NRDYE | BRDYE, INTENB0);
+       r8a66597_bclr(r8a66597, 1 << pipenum, reg);
+       r8a66597_write(r8a66597, tmp, INTENB0);
+}
+
+static void set_devadd_reg(struct r8a66597 *r8a66597, u8 r8a66597_address,
+                          u16 usbspd, u8 upphub, u8 hubport, int port)
+{
+       u16 val;
+       unsigned long devadd_reg = get_devadd_addr(r8a66597_address);
+
+       val = (upphub << 11) | (hubport << 8) | (usbspd << 6) | (port & 0x0001);
+       r8a66597_write(r8a66597, val, devadd_reg);
+}
+
+static int enable_controller(struct r8a66597 *r8a66597)
+{
+       u16 tmp;
+       int i = 0;
+
+       do {
+               r8a66597_write(r8a66597, USBE, SYSCFG0);
+               tmp = r8a66597_read(r8a66597, SYSCFG0);
+               if (i++ > 1000) {
+                       err("register access fail.");
+                       return -ENXIO;
+               }
+       } while ((tmp & USBE) != USBE);
+       r8a66597_bclr(r8a66597, USBE, SYSCFG0);
+       r8a66597_mdfy(r8a66597, clock, XTAL, SYSCFG0);
+
+       i = 0;
+       r8a66597_bset(r8a66597, XCKE, SYSCFG0);
+       do {
+               msleep(1);
+               tmp = r8a66597_read(r8a66597, SYSCFG0);
+               if (i++ > 500) {
+                       err("register access fail.");
+                       return -ENXIO;
+               }
+       } while ((tmp & SCKE) != SCKE);
+
+       r8a66597_bset(r8a66597, DCFM | DRPD, SYSCFG0);
+       r8a66597_bset(r8a66597, DRPD, SYSCFG1);
+
+       r8a66597_bset(r8a66597, vif & LDRV, PINCFG);
+       r8a66597_bset(r8a66597, HSE, SYSCFG0);
+       r8a66597_bset(r8a66597, HSE, SYSCFG1);
+       r8a66597_bset(r8a66597, USBE, SYSCFG0);
+
+       r8a66597_bset(r8a66597, BEMPE | NRDYE | BRDYE, INTENB0);
+       r8a66597_bset(r8a66597, irq_sense & INTL, SOFCFG);
+       r8a66597_bset(r8a66597, BRDY0, BRDYENB);
+       r8a66597_bset(r8a66597, BEMP0, BEMPENB);
+
+       r8a66597_write(r8a66597, BURST | CPU_ADR_RD_WR, DMA0CFG);
+       r8a66597_write(r8a66597, BURST | CPU_ADR_RD_WR, DMA1CFG);
+
+       r8a66597_bset(r8a66597, endian & BIGEND, CFIFOSEL);
+       r8a66597_bset(r8a66597, endian & BIGEND, D0FIFOSEL);
+       r8a66597_bset(r8a66597, endian & BIGEND, D1FIFOSEL);
+
+       r8a66597_bset(r8a66597, TRNENSEL, SOFCFG);
+
+       r8a66597_bset(r8a66597, SIGNE | SACKE, INTENB1);
+       r8a66597_bclr(r8a66597, DTCHE, INTENB1);
+       r8a66597_bset(r8a66597, ATTCHE, INTENB1);
+       r8a66597_bclr(r8a66597, DTCHE, INTENB2);
+       r8a66597_bset(r8a66597, ATTCHE, INTENB2);
+
+       return 0;
+}
+
+static void disable_controller(struct r8a66597 *r8a66597)
+{
+       u16 tmp;
+
+       r8a66597_write(r8a66597, 0, INTENB0);
+       r8a66597_write(r8a66597, 0, INTENB1);
+       r8a66597_write(r8a66597, 0, INTENB2);
+       r8a66597_write(r8a66597, 0, INTSTS0);
+       r8a66597_write(r8a66597, 0, INTSTS1);
+       r8a66597_write(r8a66597, 0, INTSTS2);
+
+       r8a66597_port_power(r8a66597, 0, 0);
+       r8a66597_port_power(r8a66597, 1, 0);
+
+       do {
+               tmp = r8a66597_read(r8a66597, SOFCFG) & EDGESTS;
+               udelay(640);
+       } while (tmp == EDGESTS);
+
+       r8a66597_bclr(r8a66597, DCFM | DRPD, SYSCFG0);
+       r8a66597_bclr(r8a66597, DRPD, SYSCFG1);
+       r8a66597_bclr(r8a66597, HSE, SYSCFG0);
+       r8a66597_bclr(r8a66597, HSE, SYSCFG1);
+
+       r8a66597_bclr(r8a66597, SCKE, SYSCFG0);
+       udelay(1);
+       r8a66597_bclr(r8a66597, PLLC, SYSCFG0);
+       r8a66597_bclr(r8a66597, XCKE, SYSCFG0);
+       r8a66597_bclr(r8a66597, USBE, SYSCFG0);
+}
+
+static int get_parent_r8a66597_address(struct r8a66597 *r8a66597,
+                                      struct usb_device *udev)
+{
+       struct r8a66597_device *dev;
+
+       if (udev->parent && udev->parent->devnum != 1)
+               udev = udev->parent;
+
+       dev = dev_get_drvdata(&udev->dev);
+       if (dev)
+               return dev->address;
+       else
+               return 0;
+}
+
+static int is_child_device(char *devpath)
+{
+       return (devpath[2] ? 1 : 0);
+}
+
+static int is_hub_limit(char *devpath)
+{
+       return ((strlen(devpath) >= 4) ? 1 : 0);
+}
+
+static void get_port_number(char *devpath, u16 *root_port, u16 *hub_port)
+{
+       if (root_port) {
+               *root_port = (devpath[0] & 0x0F) - 1;
+               if (*root_port >= R8A66597_MAX_ROOT_HUB)
+                       err("illegal root port number");
+       }
+       if (hub_port)
+               *hub_port = devpath[2] & 0x0F;
+}
+
+static u16 get_r8a66597_usb_speed(enum usb_device_speed speed)
+{
+       u16 usbspd = 0;
+
+       switch (speed) {
+       case USB_SPEED_LOW:
+               usbspd = LSMODE;
+               break;
+       case USB_SPEED_FULL:
+               usbspd = FSMODE;
+               break;
+       case USB_SPEED_HIGH:
+               usbspd = HSMODE;
+               break;
+       default:
+               err("unknown speed");
+               break;
+       }
+
+       return usbspd;
+}
+
+static void set_child_connect_map(struct r8a66597 *r8a66597, int address)
+{
+       int idx;
+
+       idx = address / 32;
+       r8a66597->child_connect_map[idx] |= 1 << (address % 32);
+}
+
+static void put_child_connect_map(struct r8a66597 *r8a66597, int address)
+{
+       int idx;
+
+       idx = address / 32;
+       r8a66597->child_connect_map[idx] &= ~(1 << (address % 32));
+}
+
+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};
+
+       if (dma_ch > R8A66597_PIPE_NO_DMA)      /* dma fifo not use? */
+               dma_ch = R8A66597_PIPE_NO_DMA;
+
+       pipe->fifoaddr = fifoaddr[dma_ch];
+       pipe->fifosel = fifosel[dma_ch];
+       pipe->fifoctr = fifoctr[dma_ch];
+
+       if (pipenum == 0)
+               pipe->pipectr = DCPCTR;
+       else
+               pipe->pipectr = get_pipectr_addr(pipenum);
+
+       if (check_bulk_or_isoc(pipenum)) {
+               pipe->pipetre = get_pipetre_addr(pipenum);
+               pipe->pipetrn = get_pipetrn_addr(pipenum);
+       } else {
+               pipe->pipetre = 0;
+               pipe->pipetrn = 0;
+       }
+}
+
+static struct r8a66597_device *
+get_urb_to_r8a66597_dev(struct r8a66597 *r8a66597, struct urb *urb)
+{
+       if (usb_pipedevice(urb->pipe) == 0)
+               return &r8a66597->device0;
+
+       return dev_get_drvdata(&urb->dev->dev);
+}
+
+static int make_r8a66597_device(struct r8a66597 *r8a66597,
+                               struct urb *urb, u8 addr)
+{
+       struct r8a66597_device *dev;
+       int usb_address = urb->setup_packet[2]; /* urb->pipe is address 0 */
+
+       dev = kzalloc(sizeof(struct r8a66597_device), GFP_KERNEL);
+       if (dev == NULL)
+               return -ENOMEM;
+
+       dev_set_drvdata(&urb->dev->dev, dev);
+       dev->udev = urb->dev;
+       dev->address = addr;
+       dev->usb_address = usb_address;
+       dev->state = USB_STATE_ADDRESS;
+       dev->ep_in_toggle = 0;
+       dev->ep_out_toggle = 0;
+       INIT_LIST_HEAD(&dev->device_list);
+       list_add_tail(&dev->device_list, &r8a66597->child_device);
+
+       get_port_number(urb->dev->devpath, &dev->root_port, &dev->hub_port);
+       if (!is_child_device(urb->dev->devpath))
+               r8a66597->root_hub[dev->root_port].dev = dev;
+
+       set_devadd_reg(r8a66597, dev->address,
+                      get_r8a66597_usb_speed(urb->dev->speed),
+                      get_parent_r8a66597_address(r8a66597, urb->dev),
+                      dev->hub_port, dev->root_port);
+
+       return 0;
+}
+
+/* this function must be called with interrupt disabled */
+static u8 alloc_usb_address(struct r8a66597 *r8a66597, struct urb *urb)
+{
+       u8 addr;        /* R8A66597's address */
+       struct r8a66597_device *dev;
+
+       if (is_hub_limit(urb->dev->devpath)) {
+               err("Externel hub limit reached.");
+               return 0;
+       }
+
+       dev = get_urb_to_r8a66597_dev(r8a66597, urb);
+       if (dev && dev->state >= USB_STATE_ADDRESS)
+               return dev->address;
+
+       for (addr = 1; addr <= R8A66597_MAX_DEVICE; addr++) {
+               if (r8a66597->address_map & (1 << addr))
+                       continue;
+
+               dbg("alloc_address: r8a66597_addr=%d", addr);
+               r8a66597->address_map |= 1 << addr;
+
+               if (make_r8a66597_device(r8a66597, urb, addr) < 0)
+                       return 0;
+
+               return addr;
+       }
+
+       err("cannot communicate with a USB device more than 10.(%x)",
+           r8a66597->address_map);
+
+       return 0;
+}
+
+/* this function must be called with interrupt disabled */
+static void free_usb_address(struct r8a66597 *r8a66597,
+                            struct r8a66597_device *dev)
+{
+       int port;
+
+       if (!dev)
+               return;
+
+       dbg("free_addr: addr=%d", dev->address);
+
+       dev->state = USB_STATE_DEFAULT;
+       r8a66597->address_map &= ~(1 << dev->address);
+       dev->address = 0;
+       dev_set_drvdata(&dev->udev->dev, NULL);
+       list_del(&dev->device_list);
+       kfree(dev);
+
+       for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) {
+               if (r8a66597->root_hub[port].dev == dev) {
+                       r8a66597->root_hub[port].dev = NULL;
+                       break;
+               }
+       }
+}
+
+static void r8a66597_reg_wait(struct r8a66597 *r8a66597, unsigned long reg,
+                             u16 mask, u16 loop)
+{
+       u16 tmp;
+       int i = 0;
+
+       do {
+               tmp = r8a66597_read(r8a66597, reg);
+               if (i++ > 1000000) {
+                       err("register%lx, loop %x is timeout", reg, loop);
+                       break;
+               }
+               ndelay(1);
+       } while ((tmp & mask) != loop);
+}
+
+/* this function must be called with interrupt disabled */
+static void pipe_start(struct r8a66597 *r8a66597, struct r8a66597_pipe *pipe)
+{
+       u16 tmp;
+
+       tmp = r8a66597_read(r8a66597, pipe->pipectr) & PID;
+       if ((pipe->info.pipenum != 0) & ((tmp & PID_STALL) != 0)) /* stall? */
+               r8a66597_mdfy(r8a66597, PID_NAK, PID, pipe->pipectr);
+       r8a66597_mdfy(r8a66597, PID_BUF, PID, pipe->pipectr);
+}
+
+/* this function must be called with interrupt disabled */
+static void pipe_stop(struct r8a66597 *r8a66597, struct r8a66597_pipe *pipe)
+{
+       u16 tmp;
+
+       tmp = r8a66597_read(r8a66597, pipe->pipectr) & PID;
+       if ((tmp & PID_STALL11) != PID_STALL11) /* force stall? */
+               r8a66597_mdfy(r8a66597, PID_STALL, PID, pipe->pipectr);
+       r8a66597_mdfy(r8a66597, PID_NAK, PID, pipe->pipectr);
+       r8a66597_reg_wait(r8a66597, pipe->pipectr, PBUSY, 0);
+}
+
+/* this function must be called with interrupt disabled */
+static void clear_all_buffer(struct r8a66597 *r8a66597,
+                            struct r8a66597_pipe *pipe)
+{
+       u16 tmp;
+
+       if (!pipe || pipe->info.pipenum == 0)
+               return;
+
+       pipe_stop(r8a66597, pipe);
+       r8a66597_bset(r8a66597, ACLRM, pipe->pipectr);
+       tmp = r8a66597_read(r8a66597, pipe->pipectr);
+       tmp = r8a66597_read(r8a66597, pipe->pipectr);
+       tmp = r8a66597_read(r8a66597, pipe->pipectr);
+       r8a66597_bclr(r8a66597, ACLRM, pipe->pipectr);
+}
+
+/* this function must be called with interrupt disabled */
+static void r8a66597_pipe_toggle(struct r8a66597 *r8a66597,
+                                struct r8a66597_pipe *pipe, int toggle)
+{
+       if (toggle)
+               r8a66597_bset(r8a66597, SQSET, pipe->pipectr);
+       else
+               r8a66597_bset(r8a66597, SQCLR, pipe->pipectr);
+}
+
+/* this function must be called with interrupt disabled */
+static inline void cfifo_change(struct r8a66597 *r8a66597, u16 pipenum)
+{
+       r8a66597_mdfy(r8a66597, MBW | pipenum, MBW | CURPIPE, CFIFOSEL);
+       r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, pipenum);
+}
+
+/* this function must be called with interrupt disabled */
+static inline void fifo_change_from_pipe(struct r8a66597 *r8a66597,
+                                        struct r8a66597_pipe *pipe)
+{
+       cfifo_change(r8a66597, 0);
+       r8a66597_mdfy(r8a66597, MBW | 0, MBW | CURPIPE, D0FIFOSEL);
+       r8a66597_mdfy(r8a66597, MBW | 0, MBW | CURPIPE, D1FIFOSEL);
+
+       r8a66597_mdfy(r8a66597, MBW | pipe->info.pipenum, MBW | CURPIPE,
+                     pipe->fifosel);
+       r8a66597_reg_wait(r8a66597, pipe->fifosel, CURPIPE, pipe->info.pipenum);
+}
+
+static u16 r8a66597_get_pipenum(struct urb *urb, struct usb_host_endpoint *hep)
+{
+       struct r8a66597_pipe *pipe = hep->hcpriv;
+
+       if (usb_pipeendpoint(urb->pipe) == 0)
+               return 0;
+       else
+               return pipe->info.pipenum;
+}
+
+static u16 get_urb_to_r8a66597_addr(struct r8a66597 *r8a66597, struct urb *urb)
+{
+       struct r8a66597_device *dev = get_urb_to_r8a66597_dev(r8a66597, urb);
+
+       return (usb_pipedevice(urb->pipe) == 0) ? 0 : dev->address;
+}
+
+static unsigned short *get_toggle_pointer(struct r8a66597_device *dev,
+                                         int urb_pipe)
+{
+       if (!dev)
+               return NULL;
+
+       return usb_pipein(urb_pipe) ? &dev->ep_in_toggle : &dev->ep_out_toggle;
+}
+
+/* this function must be called with interrupt disabled */
+static void pipe_toggle_set(struct r8a66597 *r8a66597,
+                           struct r8a66597_pipe *pipe,
+                           struct urb *urb, int set)
+{
+       struct r8a66597_device *dev = get_urb_to_r8a66597_dev(r8a66597, urb);
+       unsigned char endpoint = usb_pipeendpoint(urb->pipe);
+       unsigned short *toggle = get_toggle_pointer(dev, urb->pipe);
+
+       if (!toggle)
+               return;
+
+       if (set)
+               *toggle |= 1 << endpoint;
+       else
+               *toggle &= ~(1 << endpoint);
+}
+
+/* this function must be called with interrupt disabled */
+static void pipe_toggle_save(struct r8a66597 *r8a66597,
+                            struct r8a66597_pipe *pipe,
+                            struct urb *urb)
+{
+       if (r8a66597_read(r8a66597, pipe->pipectr) & SQMON)
+               pipe_toggle_set(r8a66597, pipe, urb, 1);
+       else
+               pipe_toggle_set(r8a66597, pipe, urb, 0);
+}
+
+/* this function must be called with interrupt disabled */
+static void pipe_toggle_restore(struct r8a66597 *r8a66597,
+                               struct r8a66597_pipe *pipe,
+                               struct urb *urb)
+{
+       struct r8a66597_device *dev = get_urb_to_r8a66597_dev(r8a66597, urb);
+       unsigned char endpoint = usb_pipeendpoint(urb->pipe);
+       unsigned short *toggle = get_toggle_pointer(dev, urb->pipe);
+
+       if (!toggle)
+               return;
+
+       r8a66597_pipe_toggle(r8a66597, pipe, *toggle & (1 << endpoint));
+}
+
+/* this function must be called with interrupt disabled */
+static void pipe_buffer_setting(struct r8a66597 *r8a66597,
+                               struct r8a66597_pipe_info *info)
+{
+       u16 val = 0;
+
+       if (info->pipenum == 0)
+               return;
+
+       r8a66597_bset(r8a66597, ACLRM, get_pipectr_addr(info->pipenum));
+       r8a66597_bclr(r8a66597, ACLRM, get_pipectr_addr(info->pipenum));
+       r8a66597_write(r8a66597, info->pipenum, PIPESEL);
+       if (!info->dir_in)
+               val |= R8A66597_DIR;
+       if (info->type == R8A66597_BULK && info->dir_in)
+               val |= R8A66597_DBLB | R8A66597_SHTNAK;
+       val |= info->type | info->epnum;
+       r8a66597_write(r8a66597, val, PIPECFG);
+
+       r8a66597_write(r8a66597, (info->buf_bsize << 10) | (info->bufnum),
+                      PIPEBUF);
+       r8a66597_write(r8a66597, make_devsel(info->address) | info->maxpacket,
+                      PIPEMAXP);
+       if (info->interval)
+               info->interval--;
+       r8a66597_write(r8a66597, info->interval, PIPEPERI);
+}
+
+
+
+/* this function must be called with interrupt disabled */
+static void pipe_setting(struct r8a66597 *r8a66597, struct r8a66597_td *td)
+{
+       struct r8a66597_pipe_info *info;
+       struct urb *urb = td->urb;
+
+       if (td->pipenum > 0) {
+               info = &td->pipe->info;
+               cfifo_change(r8a66597, 0);
+               pipe_buffer_setting(r8a66597, info);
+
+               if (!usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe),
+                                  usb_pipeout(urb->pipe)) &&
+                   !usb_pipecontrol(urb->pipe)) {
+                       r8a66597_pipe_toggle(r8a66597, td->pipe, 0);
+                       pipe_toggle_set(r8a66597, td->pipe, urb, 0);
+                       clear_all_buffer(r8a66597, td->pipe);
+                       usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
+                                     usb_pipeout(urb->pipe), 1);
+               }
+               pipe_toggle_restore(r8a66597, td->pipe, urb);
+       }
+}
+
+/* this function must be called with interrupt disabled */
+static u16 get_empty_pipenum(struct r8a66597 *r8a66597,
+                            struct usb_endpoint_descriptor *ep)
+{
+       u16 array[R8A66597_MAX_NUM_PIPE], i = 0, min;
+
+       memset(array, 0, sizeof(array));
+        switch(ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
+        case USB_ENDPOINT_XFER_BULK:
+               if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
+                       array[i++] = 4;
+               else {
+                       array[i++] = 3;
+                       array[i++] = 5;
+               }
+                break;
+        case USB_ENDPOINT_XFER_INT:
+               if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) {
+                       array[i++] = 6;
+                       array[i++] = 7;
+                       array[i++] = 8;
+               } else
+                       array[i++] = 9;
+                break;
+        case USB_ENDPOINT_XFER_ISOC:
+               if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
+                       array[i++] = 2;
+               else
+                       array[i++] = 1;
+                break;
+        default:
+                err("Illegal type");
+                return 0;
+        }
+
+       i = 1;
+       min = array[0];
+       while (array[i] != 0) {
+               if (r8a66597->pipe_cnt[min] > r8a66597->pipe_cnt[array[i]])
+                       min = array[i];
+               i++;
+       }
+
+       return min;
+}
+
+static u16 get_r8a66597_type(__u8 type)
+{
+       u16 r8a66597_type;
+
+       switch(type) {
+       case USB_ENDPOINT_XFER_BULK:
+               r8a66597_type = R8A66597_BULK;
+               break;
+       case USB_ENDPOINT_XFER_INT:
+               r8a66597_type = R8A66597_INT;
+               break;
+       case USB_ENDPOINT_XFER_ISOC:
+               r8a66597_type = R8A66597_ISO;
+               break;
+       default:
+               err("Illegal type");
+               r8a66597_type = 0x0000;
+               break;
+       }
+
+       return r8a66597_type;
+}
+
+static u16 get_bufnum(u16 pipenum)
+{
+       u16 bufnum = 0;
+
+       if (pipenum == 0)
+               bufnum = 0;
+       else if (check_bulk_or_isoc(pipenum))
+               bufnum = 8 + (pipenum - 1) * R8A66597_BUF_BSIZE*2;
+       else if (check_interrupt(pipenum))
+               bufnum = 4 + (pipenum - 6);
+       else
+               err("Illegal pipenum (%d)", pipenum);
+
+       return bufnum;
+}
+
+static u16 get_buf_bsize(u16 pipenum)
+{
+       u16 buf_bsize = 0;
+
+       if (pipenum == 0)
+               buf_bsize = 3;
+       else if (check_bulk_or_isoc(pipenum))
+               buf_bsize = R8A66597_BUF_BSIZE - 1;
+       else if (check_interrupt(pipenum))
+               buf_bsize = 0;
+       else
+               err("Illegal pipenum (%d)", pipenum);
+
+       return buf_bsize;
+}
+
+/* this function must be called with interrupt disabled */
+static void enable_r8a66597_pipe_dma(struct r8a66597 *r8a66597,
+                                    struct r8a66597_device *dev,
+                                    struct r8a66597_pipe *pipe,
+                                    struct urb *urb)
+{
+       int i;
+       struct r8a66597_pipe_info *info = &pipe->info;
+
+       if ((pipe->info.pipenum != 0) && (info->type != R8A66597_INT)) {
+               for (i = 0; i < R8A66597_MAX_DMA_CHANNEL; i++) {
+                       if ((r8a66597->dma_map & (1 << i)) != 0)
+                               continue;
+
+                       info("address %d, EndpointAddress 0x%02x use DMA FIFO",
+                            usb_pipedevice(urb->pipe),
+                            info->dir_in ? USB_ENDPOINT_DIR_MASK + info->epnum
+                                           : info->epnum);
+
+                       r8a66597->dma_map |= 1 << i;
+                       dev->dma_map |= 1 << i;
+                       set_pipe_reg_addr(pipe, i);
+
+                       cfifo_change(r8a66597, 0);
+                       r8a66597_mdfy(r8a66597, MBW | pipe->info.pipenum,
+                                     MBW | CURPIPE, pipe->fifosel);
+
+                       r8a66597_reg_wait(r8a66597, pipe->fifosel, CURPIPE,
+                                         pipe->info.pipenum);
+                       r8a66597_bset(r8a66597, BCLR, pipe->fifoctr);
+                       break;
+               }
+       }
+}
+
+/* this function must be called with interrupt disabled */
+static void enable_r8a66597_pipe(struct r8a66597 *r8a66597, struct urb *urb,
+                                struct usb_host_endpoint *hep,
+                                struct r8a66597_pipe_info *info)
+{
+       struct r8a66597_device *dev = get_urb_to_r8a66597_dev(r8a66597, urb);
+       struct r8a66597_pipe *pipe = hep->hcpriv;
+
+       dbg("enable_pipe:");
+
+       pipe->info = *info;
+       set_pipe_reg_addr(pipe, R8A66597_PIPE_NO_DMA);
+       r8a66597->pipe_cnt[pipe->info.pipenum]++;
+       dev->pipe_cnt[pipe->info.pipenum]++;
+
+       enable_r8a66597_pipe_dma(r8a66597, dev, pipe, urb);
+}
+
+/* this function must be called with interrupt disabled */
+static void force_dequeue(struct r8a66597 *r8a66597, u16 pipenum, u16 address)
+{
+       struct r8a66597_td *td, *next;
+       struct urb *urb;
+       struct list_head *list = &r8a66597->pipe_queue[pipenum];
+
+       if (list_empty(list))
+               return;
+
+       list_for_each_entry_safe(td, next, list, queue) {
+               if (!td)
+                       continue;
+               if (td->address != address)
+                       continue;
+
+               urb = td->urb;
+               list_del(&td->queue);
+               kfree(td);
+
+               if (urb) {
+                       urb->status = -ENODEV;
+                       urb->hcpriv = NULL;
+                       spin_unlock(&r8a66597->lock);
+                       usb_hcd_giveback_urb(r8a66597_to_hcd(r8a66597), urb);
+                       spin_lock(&r8a66597->lock);
+               }
+               break;
+       }
+}
+
+/* this function must be called with interrupt disabled */
+static void disable_r8a66597_pipe_all(struct r8a66597 *r8a66597,
+                                     struct r8a66597_device *dev)
+{
+       int check_ep0 = 0;
+       u16 pipenum;
+
+       if (!dev)
+               return;
+
+       for (pipenum = 1; pipenum < R8A66597_MAX_NUM_PIPE; pipenum++) {
+               if (!dev->pipe_cnt[pipenum])
+                       continue;
+
+               if (!check_ep0) {
+                       check_ep0 = 1;
+                       force_dequeue(r8a66597, 0, dev->address);
+               }
+
+               r8a66597->pipe_cnt[pipenum] -= dev->pipe_cnt[pipenum];
+               dev->pipe_cnt[pipenum] = 0;
+               force_dequeue(r8a66597, pipenum, dev->address);
+       }
+
+       dbg("disable_pipe");
+
+       r8a66597->dma_map &= ~(dev->dma_map);
+       dev->dma_map = 0;
+}
+
+/* this function must be called with interrupt disabled */
+static void init_pipe_info(struct r8a66597 *r8a66597, struct urb *urb,
+                          struct usb_host_endpoint *hep,
+                          struct usb_endpoint_descriptor *ep)
+{
+       struct r8a66597_pipe_info info;
+
+       info.pipenum = get_empty_pipenum(r8a66597, ep);
+       info.address = get_urb_to_r8a66597_addr(r8a66597, urb);
+       info.epnum = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+       info.maxpacket = ep->wMaxPacketSize;
+       info.type = get_r8a66597_type(ep->bmAttributes
+                                     & USB_ENDPOINT_XFERTYPE_MASK);
+       info.bufnum = get_bufnum(info.pipenum);
+       info.buf_bsize = get_buf_bsize(info.pipenum);
+       info.interval = ep->bInterval;
+       if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
+               info.dir_in = 1;
+       else
+               info.dir_in = 0;
+
+       enable_r8a66597_pipe(r8a66597, urb, hep, &info);
+}
+
+static void init_pipe_config(struct r8a66597 *r8a66597, struct urb *urb)
+{
+       struct r8a66597_device *dev;
+
+       dev = get_urb_to_r8a66597_dev(r8a66597, urb);
+       dev->state = USB_STATE_CONFIGURED;
+}
+
+static void pipe_irq_enable(struct r8a66597 *r8a66597, struct urb *urb,
+                           u16 pipenum)
+{
+       if (pipenum == 0 && usb_pipeout(urb->pipe))
+               enable_irq_empty(r8a66597, pipenum);
+       else
+               enable_irq_ready(r8a66597, pipenum);
+
+       if (!usb_pipeisoc(urb->pipe))
+               enable_irq_nrdy(r8a66597, pipenum);
+}
+
+static void pipe_irq_disable(struct r8a66597 *r8a66597, u16 pipenum)
+{
+       disable_irq_ready(r8a66597, pipenum);
+       disable_irq_nrdy(r8a66597, pipenum);
+}
+
+/* this function must be called with interrupt disabled */
+static void r8a66597_usb_preconnect(struct r8a66597 *r8a66597, int port)
+{
+       r8a66597->root_hub[port].port |= (1 << USB_PORT_FEAT_CONNECTION)
+                                        | (1 << USB_PORT_FEAT_C_CONNECTION);
+       r8a66597_write(r8a66597, (u16)~DTCH, get_intsts_reg(port));
+       r8a66597_bset(r8a66597, DTCHE, get_intenb_reg(port));
+}
+
+/* this function must be called with interrupt disabled */
+static void r8a66597_usb_connect(struct r8a66597 *r8a66597, int port)
+{
+       u16 speed = get_rh_usb_speed(r8a66597, port);
+       struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
+
+       if (speed == HSMODE)
+               rh->port |= (1 << USB_PORT_FEAT_HIGHSPEED);
+       else if (speed == LSMODE)
+               rh->port |= (1 << USB_PORT_FEAT_LOWSPEED);
+
+       rh->port &= ~(1 << USB_PORT_FEAT_RESET);
+       rh->port |= 1 << USB_PORT_FEAT_ENABLE;
+}
+
+/* this function must be called with interrupt disabled */
+static void r8a66597_usb_disconnect(struct r8a66597 *r8a66597, int port)
+{
+       struct r8a66597_device *dev = r8a66597->root_hub[port].dev;
+
+       r8a66597->root_hub[port].port &= ~(1 << USB_PORT_FEAT_CONNECTION);
+       r8a66597->root_hub[port].port |= (1 << USB_PORT_FEAT_C_CONNECTION);
+
+       disable_r8a66597_pipe_all(r8a66597, dev);
+       free_usb_address(r8a66597, dev);
+
+       r8a66597_bset(r8a66597, ATTCHE, get_intenb_reg(port));
+}
+
+/* this function must be called with interrupt disabled */
+static void prepare_setup_packet(struct r8a66597 *r8a66597,
+                                struct r8a66597_td *td)
+{
+       int i;
+       u16 *p = (u16 *)td->urb->setup_packet;
+       unsigned long setup_addr = USBREQ;
+
+       r8a66597_write(r8a66597, make_devsel(td->address) | td->maxpacket,
+                      DCPMAXP);
+       r8a66597_write(r8a66597, (u16)~(SIGN | SACK), INTSTS1);
+
+       for (i = 0; i < 4; i++) {
+               r8a66597_write(r8a66597, p[i], setup_addr);
+               setup_addr += 2;
+       }
+       r8a66597_write(r8a66597, SUREQ, DCPCTR);
+}
+
+/* this function must be called with interrupt disabled */
+static void prepare_packet_read(struct r8a66597 *r8a66597,
+                               struct r8a66597_td *td)
+{
+       struct urb *urb = td->urb;
+
+       if (usb_pipecontrol(urb->pipe)) {
+               r8a66597_bclr(r8a66597, R8A66597_DIR, DCPCFG);
+               r8a66597_mdfy(r8a66597, 0, ISEL | CURPIPE, CFIFOSEL);
+               r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, 0);
+               if (urb->actual_length == 0) {
+                       r8a66597_pipe_toggle(r8a66597, td->pipe, 1);
+                       r8a66597_write(r8a66597, BCLR, CFIFOCTR);
+               }
+               pipe_irq_disable(r8a66597, td->pipenum);
+               pipe_start(r8a66597, td->pipe);
+               pipe_irq_enable(r8a66597, urb, td->pipenum);
+       } else {
+               if (urb->actual_length == 0) {
+                       pipe_irq_disable(r8a66597, td->pipenum);
+                       pipe_setting(r8a66597, td);
+                       pipe_stop(r8a66597, td->pipe);
+                       r8a66597_write(r8a66597, (u16)~(1 << td->pipenum),
+                                      BRDYSTS);
+
+                       if (td->pipe->pipetre) {
+                               r8a66597_write(r8a66597, TRCLR,
+                                               td->pipe->pipetre);
+                               r8a66597_write(r8a66597,
+                                              (urb->transfer_buffer_length
+                                              + td->maxpacket - 1)
+                                              / td->maxpacket,
+                                              td->pipe->pipetrn);
+                               r8a66597_bset(r8a66597, TRENB,
+                                             td->pipe->pipetre);
+                       }
+
+                       pipe_start(r8a66597, td->pipe);
+                       pipe_irq_enable(r8a66597, urb, td->pipenum);
+               }
+       }
+}
+
+/* this function must be called with interrupt disabled */
+static void prepare_packet_write(struct r8a66597 *r8a66597,
+                                struct r8a66597_td *td)
+{
+       u16 tmp;
+       struct urb *urb = td->urb;
+
+       if (usb_pipecontrol(urb->pipe)) {
+               pipe_stop(r8a66597, td->pipe);
+               r8a66597_bset(r8a66597, R8A66597_DIR, DCPCFG);
+               r8a66597_mdfy(r8a66597, ISEL, ISEL | CURPIPE, CFIFOSEL);
+               r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, 0);
+               if (urb->actual_length == 0) {
+                       r8a66597_pipe_toggle(r8a66597, td->pipe, 1);
+                       r8a66597_write(r8a66597, BCLR, CFIFOCTR);
+               }
+       } else {
+               if (urb->actual_length == 0)
+                       pipe_setting(r8a66597, td);
+               if (td->pipe->pipetre)
+                       r8a66597_bclr(r8a66597, TRENB, td->pipe->pipetre);
+       }
+       r8a66597_write(r8a66597, (u16)~(1 << td->pipenum), BRDYSTS);
+
+       fifo_change_from_pipe(r8a66597, td->pipe);
+       tmp = r8a66597_read(r8a66597, td->pipe->fifoctr);
+       if (unlikely((tmp & FRDY) == 0))
+               pipe_irq_enable(r8a66597, urb, td->pipenum);
+       else
+               packet_write(r8a66597, td->pipenum);
+       pipe_start(r8a66597, td->pipe);
+}
+
+/* this function must be called with interrupt disabled */
+static void prepare_status_packet(struct r8a66597 *r8a66597,
+                                 struct r8a66597_td *td)
+{
+       struct urb *urb = td->urb;
+
+       r8a66597_pipe_toggle(r8a66597, td->pipe, 1);
+
+       if (urb->setup_packet[0] & USB_ENDPOINT_DIR_MASK) {
+               r8a66597_bset(r8a66597, R8A66597_DIR, DCPCFG);
+               r8a66597_mdfy(r8a66597, ISEL, ISEL | CURPIPE, CFIFOSEL);
+               r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, 0);
+               r8a66597_write(r8a66597, BVAL | BCLR, CFIFOCTR);
+               r8a66597_write(r8a66597, (u16)~BEMP0, BEMPSTS);
+               enable_irq_empty(r8a66597, 0);
+       } else {
+               r8a66597_bclr(r8a66597, R8A66597_DIR, DCPCFG);
+               r8a66597_mdfy(r8a66597, 0, ISEL | CURPIPE, CFIFOSEL);
+               r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, 0);
+               r8a66597_write(r8a66597, BCLR, CFIFOCTR);
+               r8a66597_write(r8a66597, (u16)~BRDY0, BRDYSTS);
+               r8a66597_write(r8a66597, (u16)~BEMP0, BEMPSTS);
+               enable_irq_ready(r8a66597, 0);
+       }
+       enable_irq_nrdy(r8a66597, 0);
+       pipe_start(r8a66597, td->pipe);
+}
+
+/* this function must be called with interrupt disabled */
+static int start_transfer(struct r8a66597 *r8a66597, struct r8a66597_td *td)
+{
+       BUG_ON(!td);
+
+       switch (td->type) {
+       case USB_PID_SETUP:
+               if (td->urb->setup_packet[1] == USB_REQ_SET_ADDRESS) {
+                       td->set_address = 1;
+                       td->urb->setup_packet[2] = alloc_usb_address(r8a66597,
+                                                                    td->urb);
+                       if (td->urb->setup_packet[2] == 0)
+                               return -EPIPE;
+               }
+               prepare_setup_packet(r8a66597, td);
+               break;
+       case USB_PID_IN:
+               prepare_packet_read(r8a66597, td);
+               break;
+       case USB_PID_OUT:
+               prepare_packet_write(r8a66597, td);
+               break;
+       case USB_PID_ACK:
+               prepare_status_packet(r8a66597, td);
+               break;
+       default:
+               err("invalid type.");
+               break;
+       }
+
+       return 0;
+}
+
+static int check_transfer_finish(struct r8a66597_td *td, struct urb *urb)
+{
+       if (usb_pipeisoc(urb->pipe)) {
+               if (urb->number_of_packets == td->iso_cnt)
+                       return 1;
+       }
+
+       /* control or bulk or interrupt */
+       if ((urb->transfer_buffer_length <= urb->actual_length) ||
+           (td->short_packet) || (td->zero_packet))
+               return 1;
+
+       return 0;
+}
+
+/* this function must be called with interrupt disabled */
+static void set_td_timer(struct r8a66597 *r8a66597, struct r8a66597_td *td)
+{
+       unsigned long time;
+
+       BUG_ON(!td);
+
+       if (!list_empty(&r8a66597->pipe_queue[td->pipenum]) &&
+           !usb_pipecontrol(td->urb->pipe) && usb_pipein(td->urb->pipe)) {
+               r8a66597->timeout_map |= 1 << td->pipenum;
+               switch (usb_pipetype(td->urb->pipe)) {
+               case PIPE_INTERRUPT:
+               case PIPE_ISOCHRONOUS:
+                       time = 30;
+                       break;
+               default:
+                       time = 300;
+                       break;
+               }
+
+               mod_timer(&r8a66597->td_timer[td->pipenum],
+                         jiffies + msecs_to_jiffies(time));
+       }
+}
+
+/* this function must be called with interrupt disabled */
+static void done(struct r8a66597 *r8a66597, struct r8a66597_td *td,
+                u16 pipenum, struct urb *urb)
+{
+       int restart = 0;
+       struct usb_hcd *hcd = r8a66597_to_hcd(r8a66597);
+
+       r8a66597->timeout_map &= ~(1 << pipenum);
+
+       if (likely(td)) {
+               if (td->set_address && urb->status != 0)
+                       r8a66597->address_map &= ~(1 << urb->setup_packet[2]);
+
+               pipe_toggle_save(r8a66597, td->pipe, urb);
+               list_del(&td->queue);
+               kfree(td);
+       }
+
+       if (!list_empty(&r8a66597->pipe_queue[pipenum]))
+               restart = 1;
+
+       if (likely(urb)) {
+               if (usb_pipeisoc(urb->pipe))
+                       urb->start_frame = r8a66597_get_frame(hcd);
+
+               urb->hcpriv = NULL;
+               spin_unlock(&r8a66597->lock);
+               usb_hcd_giveback_urb(hcd, urb);
+               spin_lock(&r8a66597->lock);
+       }
+
+       if (restart) {
+               td = r8a66597_get_td(r8a66597, pipenum);
+               if (unlikely(!td))
+                       return;
+
+               start_transfer(r8a66597, td);
+               set_td_timer(r8a66597, td);
+       }
+}
+
+/* this function must be called with interrupt disabled */
+static void finish_request(struct r8a66597 *r8a66597, struct r8a66597_td *td,
+                          u16 pipenum, struct urb *urb)
+__releases(r8a66597->lock) __acquires(r8a66597->lock)
+{
+       done(r8a66597, td, pipenum, urb);
+}
+
+static void packet_read(struct r8a66597 *r8a66597, u16 pipenum)
+{
+       u16 tmp;
+       int rcv_len, bufsize, urb_len, size;
+       u16 *buf;
+       struct r8a66597_td *td = r8a66597_get_td(r8a66597, pipenum);
+       struct urb *urb;
+       int finish = 0;
+
+       if (unlikely(!td))
+               return;
+       urb = td->urb;
+
+       fifo_change_from_pipe(r8a66597, td->pipe);
+       tmp = r8a66597_read(r8a66597, td->pipe->fifoctr);
+       if (unlikely((tmp & FRDY) == 0)) {
+               urb->status = -EPIPE;
+               pipe_stop(r8a66597, td->pipe);
+               pipe_irq_disable(r8a66597, pipenum);
+               err("in fifo not ready (%d)", pipenum);
+               finish_request(r8a66597, td, pipenum, td->urb);
+               return;
+       }
+
+       /* prepare parameters */
+       rcv_len = tmp & DTLN;
+       bufsize = td->maxpacket;
+       if (usb_pipeisoc(urb->pipe)) {
+               buf = (u16 *)(urb->transfer_buffer +
+                               urb->iso_frame_desc[td->iso_cnt].offset);
+               urb_len = urb->iso_frame_desc[td->iso_cnt].length;
+       } else {
+               buf = (void *)urb->transfer_buffer + urb->actual_length;
+               urb_len = urb->transfer_buffer_length - urb->actual_length;
+       }
+       if (rcv_len < bufsize)
+               size = min(rcv_len, urb_len);
+       else
+               size = min(bufsize, urb_len);
+
+       /* update parameters */
+       urb->actual_length += size;
+       if (rcv_len == 0)
+               td->zero_packet = 1;
+       if ((size % td->maxpacket) > 0) {
+               td->short_packet = 1;
+               if (urb->transfer_buffer_length != urb->actual_length &&
+                   urb->transfer_flags & URB_SHORT_NOT_OK)
+                       td->urb->status = -EREMOTEIO;
+       }
+       if (usb_pipeisoc(urb->pipe)) {
+               urb->iso_frame_desc[td->iso_cnt].actual_length = size;
+               urb->iso_frame_desc[td->iso_cnt].status = 0;
+               td->iso_cnt++;
+       }
+
+       /* check transfer finish */
+       if (check_transfer_finish(td, urb)) {
+               pipe_stop(r8a66597, td->pipe);
+               pipe_irq_disable(r8a66597, pipenum);
+               finish = 1;
+       }
+
+       /* read fifo */
+       if (urb->transfer_buffer) {
+               if (size == 0)
+                       r8a66597_write(r8a66597, BCLR, td->pipe->fifoctr);
+               else
+                       r8a66597_read_fifo(r8a66597, td->pipe->fifoaddr,
+                                          buf, size);
+       }
+
+       if (finish && pipenum != 0) {
+               if (td->urb->status == -EINPROGRESS)
+                       td->urb->status = 0;
+               finish_request(r8a66597, td, pipenum, urb);
+       }
+}
+
+static void packet_write(struct r8a66597 *r8a66597, u16 pipenum)
+{
+       u16 tmp;
+       int bufsize, size;
+       u16 *buf;
+       struct r8a66597_td *td = r8a66597_get_td(r8a66597, pipenum);
+       struct urb *urb;
+
+       if (unlikely(!td))
+               return;
+       urb = td->urb;
+
+       fifo_change_from_pipe(r8a66597, td->pipe);
+       tmp = r8a66597_read(r8a66597, td->pipe->fifoctr);
+       if (unlikely((tmp & FRDY) == 0)) {
+               urb->status = -EPIPE;
+               pipe_stop(r8a66597, td->pipe);
+               pipe_irq_disable(r8a66597, pipenum);
+               err("out write fifo not ready. (%d)", pipenum);
+               finish_request(r8a66597, td, pipenum, td->urb);
+               return;
+       }
+
+       /* prepare parameters */
+       bufsize = td->maxpacket;
+       if (usb_pipeisoc(urb->pipe)) {
+               buf = (u16 *)(urb->transfer_buffer +
+                               urb->iso_frame_desc[td->iso_cnt].offset);
+               size = min(bufsize,
+                          (int)urb->iso_frame_desc[td->iso_cnt].length);
+       } else {
+               buf = (u16 *)(urb->transfer_buffer + urb->actual_length);
+               size = min((int)bufsize,
+                          urb->transfer_buffer_length - urb->actual_length);
+       }
+
+       /* write fifo */
+       if (pipenum > 0)
+               r8a66597_write(r8a66597, (u16)~(1 << pipenum), BEMPSTS);
+       if (urb->transfer_buffer) {
+               r8a66597_write_fifo(r8a66597, td->pipe->fifoaddr, buf, size);
+               if (!usb_pipebulk(urb->pipe) || td->maxpacket != size)
+                       r8a66597_write(r8a66597, BVAL, td->pipe->fifoctr);
+       }
+
+       /* update parameters */
+       urb->actual_length += size;
+       if (usb_pipeisoc(urb->pipe)) {
+               urb->iso_frame_desc[td->iso_cnt].actual_length = size;
+               urb->iso_frame_desc[td->iso_cnt].status = 0;
+               td->iso_cnt++;
+       }
+
+       /* check transfer finish */
+       if (check_transfer_finish(td, urb)) {
+               disable_irq_ready(r8a66597, pipenum);
+               enable_irq_empty(r8a66597, pipenum);
+               if (!usb_pipeisoc(urb->pipe))
+                       enable_irq_nrdy(r8a66597, pipenum);
+       } else
+               pipe_irq_enable(r8a66597, urb, pipenum);
+}
+
+
+static void check_next_phase(struct r8a66597 *r8a66597)
+{
+       struct r8a66597_td *td = r8a66597_get_td(r8a66597, 0);
+       struct urb *urb;
+       u8 finish = 0;
+
+       if (unlikely(!td))
+               return;
+       urb = td->urb;
+
+       switch (td->type) {
+       case USB_PID_IN:
+       case USB_PID_OUT:
+               if (urb->status != -EINPROGRESS) {
+                       finish = 1;
+                       break;
+               }
+               if (check_transfer_finish(td, urb))
+                       td->type = USB_PID_ACK;
+               break;
+       case USB_PID_SETUP:
+               if (urb->status != -EINPROGRESS)
+                       finish = 1;
+               else if (urb->transfer_buffer_length == urb->actual_length) {
+                       td->type = USB_PID_ACK;
+                       urb->status = 0;
+               } else if (usb_pipeout(urb->pipe))
+                       td->type = USB_PID_OUT;
+               else
+                       td->type = USB_PID_IN;
+               break;
+       case USB_PID_ACK:
+               finish = 1;
+               if (urb->status == -EINPROGRESS)
+                       urb->status = 0;
+               break;
+       }
+
+       if (finish)
+               finish_request(r8a66597, td, 0, urb);
+       else
+               start_transfer(r8a66597, td);
+}
+
+static void set_urb_error(struct r8a66597 *r8a66597, u16 pipenum)
+{
+       struct r8a66597_td *td = r8a66597_get_td(r8a66597, pipenum);
+
+       if (td && td->urb) {
+               u16 pid = r8a66597_read(r8a66597, td->pipe->pipectr) & PID;
+
+               if (pid == PID_NAK)
+                       td->urb->status = -ECONNRESET;
+               else
+                       td->urb->status = -EPIPE;
+       }
+}
+
+static void irq_pipe_ready(struct r8a66597 *r8a66597)
+{
+       u16 check;
+       u16 pipenum;
+       u16 mask;
+       struct r8a66597_td *td;
+
+       mask = r8a66597_read(r8a66597, BRDYSTS)
+              & r8a66597_read(r8a66597, BRDYENB);
+       r8a66597_write(r8a66597, (u16)~mask, BRDYSTS);
+       if (mask & BRDY0) {
+               td = r8a66597_get_td(r8a66597, 0);
+               if (td && td->type == USB_PID_IN)
+                       packet_read(r8a66597, 0);
+               else
+                       pipe_irq_disable(r8a66597, 0);
+               check_next_phase(r8a66597);
+       }
+
+       for (pipenum = 1; pipenum < R8A66597_MAX_NUM_PIPE; pipenum++) {
+               check = 1 << pipenum;
+               if (mask & check) {
+                       td = r8a66597_get_td(r8a66597, pipenum);
+                       if (unlikely(!td))
+                               continue;
+
+                       if (td->type == USB_PID_IN)
+                               packet_read(r8a66597, pipenum);
+                       else if (td->type == USB_PID_OUT)
+                               packet_write(r8a66597, pipenum);
+               }
+       }
+}
+
+static void irq_pipe_empty(struct r8a66597 *r8a66597)
+{
+       u16 tmp;
+       u16 check;
+       u16 pipenum;
+       u16 mask;
+       struct r8a66597_td *td;
+
+       mask = r8a66597_read(r8a66597, BEMPSTS)
+              & r8a66597_read(r8a66597, BEMPENB);
+       r8a66597_write(r8a66597, (u16)~mask, BEMPSTS);
+       if (mask & BEMP0) {
+               cfifo_change(r8a66597, 0);
+               td = r8a66597_get_td(r8a66597, 0);
+               if (td && td->type != USB_PID_OUT)
+                       disable_irq_empty(r8a66597, 0);
+               check_next_phase(r8a66597);
+       }
+
+       for (pipenum = 1; pipenum < R8A66597_MAX_NUM_PIPE; pipenum++) {
+               check = 1 << pipenum;
+               if (mask &  check) {
+                       struct r8a66597_td *td;
+                       td = r8a66597_get_td(r8a66597, pipenum);
+                       if (unlikely(!td))
+                               continue;
+
+                       tmp = r8a66597_read(r8a66597, td->pipe->pipectr);
+                       if ((tmp & INBUFM) == 0) {
+                               disable_irq_empty(r8a66597, pipenum);
+                               pipe_irq_disable(r8a66597, pipenum);
+                               if (td->urb->status == -EINPROGRESS)
+                                       td->urb->status = 0;
+                               finish_request(r8a66597, td, pipenum, td->urb);
+                       }
+               }
+       }
+}
+
+static void irq_pipe_nrdy(struct r8a66597 *r8a66597)
+{
+       u16 check;
+       u16 pipenum;
+       u16 mask;
+
+       mask = r8a66597_read(r8a66597, NRDYSTS)
+              & r8a66597_read(r8a66597, NRDYENB);
+       r8a66597_write(r8a66597, (u16)~mask, NRDYSTS);
+       if (mask & NRDY0) {
+               cfifo_change(r8a66597, 0);
+               set_urb_error(r8a66597, 0);
+               pipe_irq_disable(r8a66597, 0);
+               check_next_phase(r8a66597);
+       }
+
+       for (pipenum = 1; pipenum < R8A66597_MAX_NUM_PIPE; pipenum++) {
+               check = 1 << pipenum;
+               if (mask & check) {
+                       struct r8a66597_td *td;
+                       td = r8a66597_get_td(r8a66597, pipenum);
+                       if (unlikely(!td))
+                               continue;
+
+                       set_urb_error(r8a66597, pipenum);
+                       pipe_irq_disable(r8a66597, pipenum);
+                       pipe_stop(r8a66597, td->pipe);
+                       finish_request(r8a66597, td, pipenum, td->urb);
+               }
+       }
+}
+
+static void start_root_hub_sampling(struct r8a66597 *r8a66597, int port)
+{
+       struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
+
+       rh->old_syssts = r8a66597_read(r8a66597, get_syssts_reg(port)) & LNST;
+       rh->scount = R8A66597_MAX_SAMPLING;
+       mod_timer(&r8a66597->rh_timer, jiffies + msecs_to_jiffies(50));
+}
+
+static irqreturn_t r8a66597_irq(struct usb_hcd *hcd)
+{
+       struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd);
+       u16 intsts0, intsts1, intsts2;
+       u16 intenb0, intenb1, intenb2;
+       u16 mask0, mask1, mask2;
+
+       spin_lock(&r8a66597->lock);
+
+       intsts0 = r8a66597_read(r8a66597, INTSTS0);
+       intsts1 = r8a66597_read(r8a66597, INTSTS1);
+       intsts2 = r8a66597_read(r8a66597, INTSTS2);
+       intenb0 = r8a66597_read(r8a66597, INTENB0);
+       intenb1 = r8a66597_read(r8a66597, INTENB1);
+       intenb2 = r8a66597_read(r8a66597, INTENB2);
+
+       mask2 = intsts2 & intenb2;
+       mask1 = intsts1 & intenb1;
+       mask0 = intsts0 & intenb0 & (BEMP | NRDY | BRDY);
+       if (mask2) {
+               if (mask2 & ATTCH) {
+                       r8a66597_write(r8a66597, (u16)~ATTCH, INTSTS2);
+                       r8a66597_bclr(r8a66597, ATTCHE, INTENB2);
+
+                       /* start usb bus sampling */
+                       start_root_hub_sampling(r8a66597, 1);
+               }
+               if (mask2 & DTCH) {
+                       r8a66597_write(r8a66597, (u16)~DTCH, INTSTS2);
+                       r8a66597_bclr(r8a66597, DTCHE, INTENB2);
+                       r8a66597_usb_disconnect(r8a66597, 1);
+               }
+       }
+
+       if (mask1) {
+               if (mask1 & ATTCH) {
+                       r8a66597_write(r8a66597, (u16)~ATTCH, INTSTS1);
+                       r8a66597_bclr(r8a66597, ATTCHE, INTENB1);
+
+                       /* start usb bus sampling */
+                       start_root_hub_sampling(r8a66597, 0);
+               }
+               if (mask1 & DTCH) {
+                       r8a66597_write(r8a66597, (u16)~DTCH, INTSTS1);
+                       r8a66597_bclr(r8a66597, DTCHE, INTENB1);
+                       r8a66597_usb_disconnect(r8a66597, 0);
+               }
+               if (mask1 & SIGN) {
+                       r8a66597_write(r8a66597, (u16)~SIGN, INTSTS1);
+                       set_urb_error(r8a66597, 0);
+                       check_next_phase(r8a66597);
+               }
+               if (mask1 & SACK) {
+                       r8a66597_write(r8a66597, (u16)~SACK, INTSTS1);
+                       check_next_phase(r8a66597);
+               }
+       }
+       if (mask0) {
+               if (mask0 & BRDY)
+                       irq_pipe_ready(r8a66597);
+               if (mask0 & BEMP)
+                       irq_pipe_empty(r8a66597);
+               if (mask0 & NRDY)
+                       irq_pipe_nrdy(r8a66597);
+       }
+
+       spin_unlock(&r8a66597->lock);
+       return IRQ_HANDLED;
+}
+
+/* this function must be called with interrupt disabled */
+static void r8a66597_root_hub_control(struct r8a66597 *r8a66597, int port)
+{
+       u16 tmp;
+       struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
+
+       if (rh->port & (1 << USB_PORT_FEAT_RESET)) {
+               unsigned long dvstctr_reg = get_dvstctr_reg(port);
+
+               tmp = r8a66597_read(r8a66597, dvstctr_reg);
+               if ((tmp & USBRST) == USBRST) {
+                       r8a66597_mdfy(r8a66597, UACT, USBRST | UACT,
+                                     dvstctr_reg);
+                       mod_timer(&r8a66597->rh_timer,
+                                 jiffies + msecs_to_jiffies(50));
+               } else
+                       r8a66597_usb_connect(r8a66597, port);
+       }
+
+       if (rh->scount > 0) {
+               tmp = r8a66597_read(r8a66597, get_syssts_reg(port)) & LNST;
+               if (tmp == rh->old_syssts) {
+                       rh->scount--;
+                       if (rh->scount == 0) {
+                               if (tmp == FS_JSTS) {
+                                       r8a66597_bset(r8a66597, HSE,
+                                                     get_syscfg_reg(port));
+                                       r8a66597_usb_preconnect(r8a66597, port);
+                               } else if (tmp == LS_JSTS) {
+                                       r8a66597_bclr(r8a66597, HSE,
+                                                     get_syscfg_reg(port));
+                                       r8a66597_usb_preconnect(r8a66597, port);
+                               } else if (tmp == SE0)
+                                       r8a66597_bset(r8a66597, ATTCHE,
+                                                     get_intenb_reg(port));
+                       } else {
+                               mod_timer(&r8a66597->rh_timer,
+                                         jiffies + msecs_to_jiffies(50));
+                       }
+               } else {
+                       rh->scount = R8A66597_MAX_SAMPLING;
+                       rh->old_syssts = tmp;
+                       mod_timer(&r8a66597->rh_timer,
+                                 jiffies + msecs_to_jiffies(50));
+               }
+       }
+}
+
+static void r8a66597_td_timer(unsigned long _r8a66597)
+{
+       struct r8a66597 *r8a66597 = (struct r8a66597 *)_r8a66597;
+       unsigned long flags;
+       u16 pipenum;
+       struct r8a66597_td *td, *new_td = NULL;
+       struct r8a66597_pipe *pipe;
+
+       spin_lock_irqsave(&r8a66597->lock, flags);
+       for (pipenum = 0; pipenum < R8A66597_MAX_NUM_PIPE; pipenum++) {
+               if (!(r8a66597->timeout_map & (1 << pipenum)))
+                       continue;
+               if (timer_pending(&r8a66597->td_timer[pipenum]))
+                       continue;
+
+               td = r8a66597_get_td(r8a66597, pipenum);
+               if (!td) {
+                       r8a66597->timeout_map &= ~(1 << pipenum);
+                       continue;
+               }
+
+               if (td->urb->actual_length) {
+                       set_td_timer(r8a66597, td);
+                       break;
+               }
+
+               pipe = td->pipe;
+               pipe_stop(r8a66597, pipe);
+
+               new_td = td;
+               do {
+                       list_move_tail(&new_td->queue,
+                                      &r8a66597->pipe_queue[pipenum]);
+                       new_td = r8a66597_get_td(r8a66597, pipenum);
+                       if (!new_td) {
+                               new_td = td;
+                               break;
+                       }
+               } while (td != new_td && td->address == new_td->address);
+
+               start_transfer(r8a66597, new_td);
+
+               if (td == new_td)
+                       r8a66597->timeout_map &= ~(1 << pipenum);
+               else
+                       set_td_timer(r8a66597, new_td);
+               break;
+       }
+       spin_unlock_irqrestore(&r8a66597->lock, flags);
+}
+
+static void r8a66597_timer(unsigned long _r8a66597)
+{
+       struct r8a66597 *r8a66597 = (struct r8a66597 *)_r8a66597;
+       unsigned long flags;
+
+       spin_lock_irqsave(&r8a66597->lock, flags);
+
+       r8a66597_root_hub_control(r8a66597, 0);
+       r8a66597_root_hub_control(r8a66597, 1);
+
+       spin_unlock_irqrestore(&r8a66597->lock, flags);
+}
+
+static int check_pipe_config(struct r8a66597 *r8a66597, struct urb *urb)
+{
+       struct r8a66597_device *dev = get_urb_to_r8a66597_dev(r8a66597, urb);
+
+       if (dev && dev->address && dev->state != USB_STATE_CONFIGURED &&
+           (urb->dev->state == USB_STATE_CONFIGURED))
+               return 1;
+       else
+               return 0;
+}
+
+static int r8a66597_start(struct usb_hcd *hcd)
+{
+       struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd);
+       int ret;
+
+       hcd->state = HC_STATE_RUNNING;
+       if ((ret = enable_controller(r8a66597)) < 0)
+               return ret;
+
+       return 0;
+}
+
+static void r8a66597_stop(struct usb_hcd *hcd)
+{
+       struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd);
+
+       disable_controller(r8a66597);
+}
+
+static void set_address_zero(struct r8a66597 *r8a66597, struct urb *urb)
+{
+       unsigned int usb_address = usb_pipedevice(urb->pipe);
+       u16 root_port, hub_port;
+
+       if (usb_address == 0) {
+               get_port_number(urb->dev->devpath,
+                               &root_port, &hub_port);
+               set_devadd_reg(r8a66597, 0,
+                              get_r8a66597_usb_speed(urb->dev->speed),
+                              get_parent_r8a66597_address(r8a66597, urb->dev),
+                              hub_port, root_port);
+       }
+}
+
+static struct r8a66597_td *r8a66597_make_td(struct r8a66597 *r8a66597,
+                                           struct urb *urb,
+                                           struct usb_host_endpoint *hep,
+                                           gfp_t mem_flags)
+{
+       struct r8a66597_td *td;
+       u16 pipenum;
+
+       td = kzalloc(sizeof(struct r8a66597_td), mem_flags);
+       if (td == NULL)
+               return NULL;
+
+       pipenum = r8a66597_get_pipenum(urb, hep);
+       td->pipenum = pipenum;
+       td->pipe = hep->hcpriv;
+       td->urb = urb;
+       td->address = get_urb_to_r8a66597_addr(r8a66597, urb);
+       td->maxpacket = usb_maxpacket(urb->dev, urb->pipe,
+                                     !usb_pipein(urb->pipe));
+       if (usb_pipecontrol(urb->pipe))
+               td->type = USB_PID_SETUP;
+       else if (usb_pipein(urb->pipe))
+               td->type = USB_PID_IN;
+       else
+               td->type = USB_PID_OUT;
+       INIT_LIST_HEAD(&td->queue);
+
+       return td;
+}
+
+static int r8a66597_urb_enqueue(struct usb_hcd *hcd,
+                               struct usb_host_endpoint *hep,
+                               struct urb *urb,
+                               gfp_t mem_flags)
+{
+       struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd);
+       struct r8a66597_td *td = NULL;
+       int ret = 0, request = 0;
+       unsigned long flags;
+
+       spin_lock_irqsave(&r8a66597->lock, flags);
+       if (!get_urb_to_r8a66597_dev(r8a66597, urb)) {
+               ret = -ENODEV;
+               goto error;
+       }
+
+       if (!hep->hcpriv) {
+               hep->hcpriv = kzalloc(sizeof(struct r8a66597_pipe), mem_flags);
+               if (!hep->hcpriv) {
+                       ret = -ENOMEM;
+                       goto error;
+               }
+               set_pipe_reg_addr(hep->hcpriv, R8A66597_PIPE_NO_DMA);
+               if (usb_pipeendpoint(urb->pipe))
+                       init_pipe_info(r8a66597, urb, hep, &hep->desc);
+       }
+
+       if (unlikely(check_pipe_config(r8a66597, urb)))
+               init_pipe_config(r8a66597, urb);
+
+       set_address_zero(r8a66597, urb);
+       td = r8a66597_make_td(r8a66597, urb, hep, mem_flags);
+       if (td == NULL) {
+               ret = -ENOMEM;
+               goto error;
+       }
+       if (list_empty(&r8a66597->pipe_queue[td->pipenum]))
+               request = 1;
+       list_add_tail(&td->queue, &r8a66597->pipe_queue[td->pipenum]);
+
+       spin_lock(&urb->lock);
+       if (urb->status != -EINPROGRESS) {
+               spin_unlock(&urb->lock);
+               ret = -EPIPE;
+               goto error;
+       }
+       urb->hcpriv = td;
+       spin_unlock(&urb->lock);
+
+       if (request) {
+               ret = start_transfer(r8a66597, td);
+               if (ret < 0) {
+                       list_del(&td->queue);
+                       kfree(td);
+               }
+       } else
+               set_td_timer(r8a66597, td);
+
+error:
+       spin_unlock_irqrestore(&r8a66597->lock, flags);
+       return ret;
+}
+
+static int r8a66597_urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
+{
+       struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd);
+       struct r8a66597_td *td;
+       unsigned long flags;
+
+       spin_lock_irqsave(&r8a66597->lock, flags);
+       if (urb->hcpriv) {
+               td = urb->hcpriv;
+               pipe_stop(r8a66597, td->pipe);
+               pipe_irq_disable(r8a66597, td->pipenum);
+               disable_irq_empty(r8a66597, td->pipenum);
+               done(r8a66597, td, td->pipenum, urb);
+       }
+       spin_unlock_irqrestore(&r8a66597->lock, flags);
+       return 0;
+}
+
+static void r8a66597_endpoint_disable(struct usb_hcd *hcd,
+                                     struct usb_host_endpoint *hep)
+{
+       struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd);
+       struct r8a66597_pipe *pipe = (struct r8a66597_pipe *)hep->hcpriv;
+       struct r8a66597_td *td;
+       struct urb *urb = NULL;
+       u16 pipenum;
+       unsigned long flags;
+
+       if (pipe == NULL)
+               return;
+       pipenum = pipe->info.pipenum;
+
+       if (pipenum == 0) {
+               kfree(hep->hcpriv);
+               hep->hcpriv = NULL;
+               return;
+       }
+
+       spin_lock_irqsave(&r8a66597->lock, flags);
+       pipe_stop(r8a66597, pipe);
+       pipe_irq_disable(r8a66597, pipenum);
+       disable_irq_empty(r8a66597, pipenum);
+       td = r8a66597_get_td(r8a66597, pipenum);
+       if (td)
+               urb = td->urb;
+       done(r8a66597, td, pipenum, urb);
+       kfree(hep->hcpriv);
+       hep->hcpriv = NULL;
+       spin_unlock_irqrestore(&r8a66597->lock, flags);
+}
+
+static int r8a66597_get_frame(struct usb_hcd *hcd)
+{
+       struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd);
+       return r8a66597_read(r8a66597, FRMNUM) & 0x03FF;
+}
+
+static void collect_usb_address_map(struct usb_device *udev, unsigned long *map)
+{
+       int chix;
+
+       if (udev->state == USB_STATE_CONFIGURED &&
+           udev->parent && udev->parent->devnum > 1 &&
+           udev->parent->descriptor.bDeviceClass == USB_CLASS_HUB)
+               map[udev->devnum/32] |= (1 << (udev->devnum % 32));
+
+       for (chix = 0; chix < udev->maxchild; chix++) {
+               struct usb_device *childdev = udev->children[chix];
+
+               if (childdev)
+                       collect_usb_address_map(childdev, map);
+       }
+}
+
+/* this function must be called with interrupt disabled */
+static struct r8a66597_device *get_r8a66597_device(struct r8a66597 *r8a66597,
+                                                  int addr)
+{
+       struct r8a66597_device *dev;
+       struct list_head *list = &r8a66597->child_device;
+
+       list_for_each_entry(dev, list, device_list) {
+               if (!dev)
+                       continue;
+               if (dev->usb_address != addr)
+                       continue;
+
+               return dev;
+       }
+
+       err("get_r8a66597_device fail.(%d)\n", addr);
+       return NULL;
+}
+
+static void update_usb_address_map(struct r8a66597 *r8a66597,
+                                  struct usb_device *root_hub,
+                                  unsigned long *map)
+{
+       int i, j, addr;
+       unsigned long diff;
+       unsigned long flags;
+
+       for (i = 0; i < 4; i++) {
+               diff = r8a66597->child_connect_map[i] ^ map[i];
+               if (!diff)
+                       continue;
+
+               for (j = 0; j < 32; j++) {
+                       if (!(diff & (1 << j)))
+                               continue;
+
+                       addr = i * 32 + j;
+                       if (map[i] & (1 << j))
+                               set_child_connect_map(r8a66597, addr);
+                       else {
+                               struct r8a66597_device *dev;
+
+                               spin_lock_irqsave(&r8a66597->lock, flags);
+                               dev = get_r8a66597_device(r8a66597, addr);
+                               disable_r8a66597_pipe_all(r8a66597, dev);
+                               free_usb_address(r8a66597, dev);
+                               put_child_connect_map(r8a66597, addr);
+                               spin_unlock_irqrestore(&r8a66597->lock, flags);
+                       }
+               }
+       }
+}
+
+static void r8a66597_check_detect_child(struct r8a66597 *r8a66597,
+                                       struct usb_hcd *hcd)
+{
+       struct usb_bus *bus;
+       unsigned long now_map[4];
+
+       memset(now_map, 0, sizeof(now_map));
+
+       list_for_each_entry(bus, &usb_bus_list, bus_list) {
+               if (!bus->root_hub)
+                       continue;
+
+               if (bus->busnum != hcd->self.busnum)
+                       continue;
+
+               collect_usb_address_map(bus->root_hub, now_map);
+               update_usb_address_map(r8a66597, bus->root_hub, now_map);
+       }
+}
+
+static int r8a66597_hub_status_data(struct usb_hcd *hcd, char *buf)
+{
+       struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd);
+       unsigned long flags;
+       int i;
+
+       r8a66597_check_detect_child(r8a66597, hcd);
+
+       spin_lock_irqsave(&r8a66597->lock, flags);
+
+       *buf = 0;       /* initialize (no change) */
+
+       for (i = 0; i < R8A66597_MAX_ROOT_HUB; i++) {
+               if (r8a66597->root_hub[i].port & 0xffff0000)
+                       *buf |= 1 << (i + 1);
+       }
+
+       spin_unlock_irqrestore(&r8a66597->lock, flags);
+
+       return (*buf != 0);
+}
+
+static void r8a66597_hub_descriptor(struct r8a66597 *r8a66597,
+                                   struct usb_hub_descriptor *desc)
+{
+       desc->bDescriptorType = 0x29;
+       desc->bHubContrCurrent = 0;
+       desc->bNbrPorts = R8A66597_MAX_ROOT_HUB;
+       desc->bDescLength = 9;
+       desc->bPwrOn2PwrGood = 0;
+       desc->wHubCharacteristics = cpu_to_le16(0x0011);
+       desc->bitmap[0] = ((1 << R8A66597_MAX_ROOT_HUB) - 1) << 1;
+       desc->bitmap[1] = ~0;
+}
+
+static int r8a66597_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
+                               u16 wIndex, char *buf, u16 wLength)
+{
+       struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd);
+       int ret;
+       int port = (wIndex & 0x00FF) - 1;
+       struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
+       unsigned long flags;
+
+       ret = 0;
+
+       spin_lock_irqsave(&r8a66597->lock, flags);
+       switch (typeReq) {
+       case ClearHubFeature:
+       case SetHubFeature:
+               switch (wValue) {
+               case C_HUB_OVER_CURRENT:
+               case C_HUB_LOCAL_POWER:
+                       break;
+               default:
+                       goto error;
+               }
+               break;
+       case ClearPortFeature:
+               if (wIndex > R8A66597_MAX_ROOT_HUB)
+                       goto error;
+               if (wLength != 0)
+                       goto error;
+
+               switch (wValue) {
+               case USB_PORT_FEAT_ENABLE:
+                       rh->port &= (1 << USB_PORT_FEAT_POWER);
+                       break;
+               case USB_PORT_FEAT_SUSPEND:
+                       break;
+               case USB_PORT_FEAT_POWER:
+                       r8a66597_port_power(r8a66597, port, 0);
+                       break;
+               case USB_PORT_FEAT_C_ENABLE:
+               case USB_PORT_FEAT_C_SUSPEND:
+               case USB_PORT_FEAT_C_CONNECTION:
+               case USB_PORT_FEAT_C_OVER_CURRENT:
+               case USB_PORT_FEAT_C_RESET:
+                       break;
+               default:
+                       goto error;
+               }
+               rh->port &= ~(1 << wValue);
+               break;
+       case GetHubDescriptor:
+               r8a66597_hub_descriptor(r8a66597,
+                                       (struct usb_hub_descriptor *)buf);
+               break;
+       case GetHubStatus:
+               *buf = 0x00;
+               break;
+       case GetPortStatus:
+               if (wIndex > R8A66597_MAX_ROOT_HUB)
+                       goto error;
+               *(u32 *)buf = rh->port;
+               break;
+       case SetPortFeature:
+               if (wIndex > R8A66597_MAX_ROOT_HUB)
+                       goto error;
+               if (wLength != 0)
+                       goto error;
+
+               switch (wValue) {
+               case USB_PORT_FEAT_SUSPEND:
+                       break;
+               case USB_PORT_FEAT_POWER:
+                       r8a66597_port_power(r8a66597, port, 1);
+                       rh->port |= (1 << USB_PORT_FEAT_POWER);
+                       break;
+               case USB_PORT_FEAT_RESET: {
+                       struct r8a66597_device *dev = rh->dev;
+
+                       rh->port |= (1 << USB_PORT_FEAT_RESET);
+
+                       disable_r8a66597_pipe_all(r8a66597, dev);
+                       free_usb_address(r8a66597, dev);
+
+                       r8a66597_mdfy(r8a66597, USBRST, USBRST | UACT,
+                                     get_dvstctr_reg(port));
+                       mod_timer(&r8a66597->rh_timer,
+                                 jiffies + msecs_to_jiffies(50));
+                       }
+                       break;
+               default:
+                       goto error;
+               }
+               rh->port |= 1 << wValue;
+               break;
+       default:
+error:
+               ret = -EPIPE;
+               break;
+       }
+
+       spin_unlock_irqrestore(&r8a66597->lock, flags);
+       return ret;
+}
+
+static struct hc_driver r8a66597_hc_driver = {
+       .description =          hcd_name,
+       .hcd_priv_size =        sizeof(struct r8a66597),
+       .irq =                  r8a66597_irq,
+
+       /*
+        * generic hardware linkage
+        */
+       .flags =                HCD_USB2,
+
+       .start =                r8a66597_start,
+       .stop =                 r8a66597_stop,
+
+       /*
+        * managing i/o requests and associated device resources
+        */
+       .urb_enqueue =          r8a66597_urb_enqueue,
+       .urb_dequeue =          r8a66597_urb_dequeue,
+       .endpoint_disable =     r8a66597_endpoint_disable,
+
+       /*
+        * periodic schedule support
+        */
+       .get_frame_number =     r8a66597_get_frame,
+
+       /*
+        * root hub support
+        */
+       .hub_status_data =      r8a66597_hub_status_data,
+       .hub_control =          r8a66597_hub_control,
+};
+
+#if defined(CONFIG_PM)
+static int r8a66597_suspend(struct platform_device *pdev, pm_message_t state)
+{
+       pdev->dev.power.power_state = state;
+       return 0;
+}
+
+static int r8a66597_resume(struct platform_device *pdev)
+{
+       pdev->dev.power.power_state = PMSG_ON;
+       return 0;
+}
+#else  /* if defined(CONFIG_PM) */
+#define r8a66597_suspend       NULL
+#define r8a66597_resume                NULL
+#endif
+
+static int __init_or_module r8a66597_remove(struct platform_device *pdev)
+{
+       struct r8a66597         *r8a66597 = dev_get_drvdata(&pdev->dev);
+       struct usb_hcd          *hcd = r8a66597_to_hcd(r8a66597);
+
+       del_timer_sync(&r8a66597->rh_timer);
+       iounmap((void *)r8a66597->reg);
+       usb_remove_hcd(hcd);
+       usb_put_hcd(hcd);
+       return 0;
+}
+
+#define resource_len(r) (((r)->end - (r)->start) + 1)
+static int __init r8a66597_probe(struct platform_device *pdev)
+{
+       struct resource *res = NULL;
+       int irq = -1;
+       void __iomem *reg = NULL;
+       struct usb_hcd *hcd = NULL;
+       struct r8a66597 *r8a66597;
+       int ret = 0;
+       int i;
+
+       if (pdev->dev.dma_mask) {
+               ret = -EINVAL;
+               err("dma not support");
+               goto clean_up;
+       }
+
+       res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+                                          (char *)hcd_name);
+       if (!res) {
+               ret = -ENODEV;
+               err("platform_get_resource_byname error.");
+               goto clean_up;
+       }
+
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+               ret = -ENODEV;
+               err("platform_get_irq error.");
+               goto clean_up;
+       }
+
+       reg = ioremap(res->start, resource_len(res));
+       if (reg == NULL) {
+               ret = -ENOMEM;
+               err("ioremap error.");
+               goto clean_up;
+       }
+
+       /* initialize hcd */
+       hcd = usb_create_hcd(&r8a66597_hc_driver, &pdev->dev, (char *)hcd_name);
+       if (!hcd) {
+               ret = -ENOMEM;
+               err("Failed to create hcd");
+               goto clean_up;
+       }
+       r8a66597 = hcd_to_r8a66597(hcd);
+       memset(r8a66597, 0, sizeof(struct r8a66597));
+       dev_set_drvdata(&pdev->dev, r8a66597);
+
+       spin_lock_init(&r8a66597->lock);
+       init_timer(&r8a66597->rh_timer);
+       r8a66597->rh_timer.function = r8a66597_timer;
+       r8a66597->rh_timer.data = (unsigned long)r8a66597;
+       r8a66597->reg = (unsigned long)reg;
+
+       for (i = 0; i < R8A66597_MAX_NUM_PIPE; i++) {
+               INIT_LIST_HEAD(&r8a66597->pipe_queue[i]);
+               init_timer(&r8a66597->td_timer[i]);
+               r8a66597->td_timer[i].function = r8a66597_td_timer;
+               r8a66597->td_timer[i].data = (unsigned long)r8a66597;
+       }
+       INIT_LIST_HEAD(&r8a66597->child_device);
+
+       hcd->rsrc_start = res->start;
+       ret = usb_add_hcd(hcd, irq, 0);
+       if (ret != 0) {
+               err("Failed to add hcd");
+               goto clean_up;
+       }
+
+       return 0;
+
+clean_up:
+       if (reg)
+               iounmap(reg);
+       if (res)
+               release_mem_region(res->start, 1);
+
+       return ret;
+}
+
+static struct platform_driver r8a66597_driver = {
+       .probe =        r8a66597_probe,
+       .remove =       r8a66597_remove,
+       .suspend =      r8a66597_suspend,
+       .resume =       r8a66597_resume,
+       .driver         = {
+               .name = (char *) hcd_name,
+       },
+};
+
+static int __init r8a66597_init(void)
+{
+       if (usb_disabled())
+               return -ENODEV;
+
+       info("driver %s, %s", hcd_name, DRIVER_VERSION);
+       return platform_driver_register(&r8a66597_driver);
+}
+module_init(r8a66597_init);
+
+static void __exit r8a66597_cleanup(void)
+{
+       platform_driver_unregister(&r8a66597_driver);
+}
+module_exit(r8a66597_cleanup);
+
diff --git a/drivers/usb/host/r8a66597.h b/drivers/usb/host/r8a66597.h
new file mode 100644 (file)
index 0000000..97c2a71
--- /dev/null
@@ -0,0 +1,634 @@
+/*
+ * R8A66597 HCD (Host Controller Driver)
+ *
+ * Copyright (C) 2006-2007 Renesas Solutions Corp.
+ * Portions Copyright (C) 2004 Psion Teklogix (for NetBook PRO)
+ * Portions Copyright (C) 2004-2005 David Brownell
+ * Portions Copyright (C) 1999 Roman Weissgaerber
+ *
+ * Author : Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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 __R8A66597_H__
+#define __R8A66597_H__
+
+#define SYSCFG0                0x00
+#define SYSCFG1                0x02
+#define SYSSTS0                0x04
+#define SYSSTS1                0x06
+#define DVSTCTR0       0x08
+#define DVSTCTR1       0x0A
+#define TESTMODE       0x0C
+#define PINCFG         0x0E
+#define DMA0CFG                0x10
+#define DMA1CFG                0x12
+#define CFIFO          0x14
+#define D0FIFO         0x18
+#define D1FIFO         0x1C
+#define CFIFOSEL       0x20
+#define CFIFOCTR       0x22
+#define CFIFOSIE       0x24
+#define D0FIFOSEL      0x28
+#define D0FIFOCTR      0x2A
+#define D1FIFOSEL      0x2C
+#define D1FIFOCTR      0x2E
+#define INTENB0                0x30
+#define INTENB1                0x32
+#define INTENB2                0x34
+#define BRDYENB                0x36
+#define NRDYENB                0x38
+#define BEMPENB                0x3A
+#define SOFCFG         0x3C
+#define INTSTS0                0x40
+#define INTSTS1                0x42
+#define INTSTS2                0x44
+#define BRDYSTS                0x46
+#define NRDYSTS                0x48
+#define BEMPSTS                0x4A
+#define FRMNUM         0x4C
+#define UFRMNUM                0x4E
+#define USBADDR                0x50
+#define USBREQ         0x54
+#define USBVAL         0x56
+#define USBINDX                0x58
+#define USBLENG                0x5A
+#define DCPCFG         0x5C
+#define DCPMAXP                0x5E
+#define DCPCTR         0x60
+#define PIPESEL                0x64
+#define PIPECFG                0x68
+#define PIPEBUF                0x6A
+#define PIPEMAXP       0x6C
+#define PIPEPERI       0x6E
+#define PIPE1CTR       0x70
+#define PIPE2CTR       0x72
+#define PIPE3CTR       0x74
+#define PIPE4CTR       0x76
+#define PIPE5CTR       0x78
+#define PIPE6CTR       0x7A
+#define PIPE7CTR       0x7C
+#define PIPE8CTR       0x7E
+#define PIPE9CTR       0x80
+#define PIPE1TRE       0x90
+#define PIPE1TRN       0x92
+#define PIPE2TRE       0x94
+#define PIPE2TRN       0x96
+#define PIPE3TRE       0x98
+#define PIPE3TRN       0x9A
+#define PIPE4TRE       0x9C
+#define        PIPE4TRN        0x9E
+#define        PIPE5TRE        0xA0
+#define        PIPE5TRN        0xA2
+#define DEVADD0                0xD0
+#define DEVADD1                0xD2
+#define DEVADD2                0xD4
+#define DEVADD3                0xD6
+#define DEVADD4                0xD8
+#define DEVADD5                0xDA
+#define DEVADD6                0xDC
+#define DEVADD7                0xDE
+#define DEVADD8                0xE0
+#define DEVADD9                0xE2
+#define DEVADDA                0xE4
+
+/* System Configuration Control Register */
+#define        XTAL            0xC000  /* b15-14: Crystal selection */
+#define          XTAL48         0x8000   /* 48MHz */
+#define          XTAL24         0x4000   /* 24MHz */
+#define          XTAL12         0x0000   /* 12MHz */
+#define        XCKE            0x2000  /* b13: External clock enable */
+#define        PLLC            0x0800  /* b11: PLL control */
+#define        SCKE            0x0400  /* b10: USB clock enable */
+#define        PCSDIS          0x0200  /* b9: not CS wakeup */
+#define        LPSME           0x0100  /* b8: Low power sleep mode */
+#define        HSE             0x0080  /* b7: Hi-speed enable */
+#define        DCFM            0x0040  /* b6: Controller function select  */
+#define        DRPD            0x0020  /* b5: D+/- pull down control */
+#define        DPRPU           0x0010  /* b4: D+ pull up control */
+#define        USBE            0x0001  /* b0: USB module operation enable */
+
+/* System Configuration Status Register */
+#define        OVCBIT          0x8000  /* b15-14: Over-current bit */
+#define        OVCMON          0xC000  /* b15-14: Over-current monitor */
+#define        SOFEA           0x0020  /* b5: SOF monitor */
+#define        IDMON           0x0004  /* b3: ID-pin monitor */
+#define        LNST            0x0003  /* b1-0: D+, D- line status */
+#define          SE1            0x0003   /* SE1 */
+#define          FS_KSTS        0x0002   /* Full-Speed K State */
+#define          FS_JSTS        0x0001   /* Full-Speed J State */
+#define          LS_JSTS        0x0002   /* Low-Speed J State */
+#define          LS_KSTS        0x0001   /* Low-Speed K State */
+#define          SE0            0x0000   /* SE0 */
+
+/* Device State Control Register */
+#define        EXTLP0          0x0400  /* b10: External port */
+#define        VBOUT           0x0200  /* b9: VBUS output */
+#define        WKUP            0x0100  /* b8: Remote wakeup */
+#define        RWUPE           0x0080  /* b7: Remote wakeup sense */
+#define        USBRST          0x0040  /* b6: USB reset enable */
+#define        RESUME          0x0020  /* b5: Resume enable */
+#define        UACT            0x0010  /* b4: USB bus enable */
+#define        RHST            0x0007  /* b1-0: Reset handshake status */
+#define          HSPROC         0x0004   /* HS handshake is processing */
+#define          HSMODE         0x0003   /* Hi-Speed mode */
+#define          FSMODE         0x0002   /* Full-Speed mode */
+#define          LSMODE         0x0001   /* Low-Speed mode */
+#define          UNDECID        0x0000   /* Undecided */
+
+/* Test Mode Register */
+#define        UTST                    0x000F  /* b3-0: Test select */
+#define          H_TST_PACKET           0x000C   /* HOST TEST Packet */
+#define          H_TST_SE0_NAK          0x000B   /* HOST TEST SE0 NAK */
+#define          H_TST_K                0x000A   /* HOST TEST K */
+#define          H_TST_J                0x0009   /* HOST TEST J */
+#define          H_TST_NORMAL           0x0000   /* HOST Normal Mode */
+#define          P_TST_PACKET           0x0004   /* PERI TEST Packet */
+#define          P_TST_SE0_NAK          0x0003   /* PERI TEST SE0 NAK */
+#define          P_TST_K                0x0002   /* PERI TEST K */
+#define          P_TST_J                0x0001   /* PERI TEST J */
+#define          P_TST_NORMAL           0x0000   /* PERI Normal Mode */
+
+/* Data Pin Configuration Register */
+#define        LDRV                    0x8000  /* b15: Drive Current Adjust */
+#define          VIF1                    0x0000                /* VIF = 1.8V */
+#define          VIF3                    0x8000                /* VIF = 3.3V */
+#define        INTA                    0x0001  /* b1: USB INT-pin active */
+
+/* DMAx Pin Configuration Register */
+#define        DREQA                   0x4000  /* b14: Dreq active select */
+#define        BURST                   0x2000  /* b13: Burst mode */
+#define        DACKA                   0x0400  /* b10: Dack active select */
+#define        DFORM                   0x0380  /* b9-7: DMA mode select */
+#define          CPU_ADR_RD_WR          0x0000   /* Address + RD/WR mode (CPU bus) */
+#define          CPU_DACK_RD_WR         0x0100   /* DACK + RD/WR mode (CPU bus) */
+#define          CPU_DACK_ONLY          0x0180   /* DACK only mode (CPU bus) */
+#define          SPLIT_DACK_ONLY        0x0200   /* DACK only mode (SPLIT bus) */
+#define        DENDA                   0x0040  /* b6: Dend active select */
+#define        PKTM                    0x0020  /* b5: Packet mode */
+#define        DENDE                   0x0010  /* b4: Dend enable */
+#define        OBUS                    0x0004  /* b2: OUTbus mode */
+
+/* CFIFO/DxFIFO Port Select Register */
+#define        RCNT            0x8000  /* b15: Read count mode */
+#define        REW             0x4000  /* b14: Buffer rewind */
+#define        DCLRM           0x2000  /* b13: DMA buffer clear mode */
+#define        DREQE           0x1000  /* b12: DREQ output enable */
+#define        MBW             0x0400  /* b10: Maximum bit width for FIFO access */
+#define          MBW_8          0x0000   /*  8bit */
+#define          MBW_16         0x0400   /* 16bit */
+#define        BIGEND          0x0100  /* b8: Big endian mode */
+#define          BYTE_LITTLE    0x0000         /* little dendian */
+#define          BYTE_BIG       0x0100         /* big endifan */
+#define        ISEL            0x0020  /* b5: DCP FIFO port direction select */
+#define        CURPIPE         0x000F  /* b2-0: PIPE select */
+
+/* CFIFO/DxFIFO Port Control Register */
+#define        BVAL            0x8000  /* b15: Buffer valid flag */
+#define        BCLR            0x4000  /* b14: Buffer clear */
+#define        FRDY            0x2000  /* b13: FIFO ready */
+#define        DTLN            0x0FFF  /* b11-0: FIFO received data length */
+
+/* Interrupt Enable Register 0 */
+#define        VBSE            0x8000  /* b15: VBUS interrupt */
+#define        RSME            0x4000  /* b14: Resume interrupt */
+#define        SOFE            0x2000  /* b13: Frame update interrupt */
+#define        DVSE            0x1000  /* b12: Device state transition interrupt */
+#define        CTRE            0x0800  /* b11: Control transfer stage transition interrupt */
+#define        BEMPE           0x0400  /* b10: Buffer empty interrupt */
+#define        NRDYE           0x0200  /* b9: Buffer not ready interrupt */
+#define        BRDYE           0x0100  /* b8: Buffer ready interrupt */
+
+/* Interrupt Enable Register 1 */
+#define        OVRCRE          0x8000  /* b15: Over-current interrupt */
+#define        BCHGE           0x4000  /* b14: USB us chenge interrupt */
+#define        DTCHE           0x1000  /* b12: Detach sense interrupt */
+#define        ATTCHE          0x0800  /* b11: Attach sense interrupt */
+#define        EOFERRE         0x0040  /* b6: EOF error interrupt */
+#define        SIGNE           0x0020  /* b5: SETUP IGNORE interrupt */
+#define        SACKE           0x0010  /* b4: SETUP ACK interrupt */
+
+/* BRDY Interrupt Enable/Status Register */
+#define        BRDY9           0x0200  /* b9: PIPE9 */
+#define        BRDY8           0x0100  /* b8: PIPE8 */
+#define        BRDY7           0x0080  /* b7: PIPE7 */
+#define        BRDY6           0x0040  /* b6: PIPE6 */
+#define        BRDY5           0x0020  /* b5: PIPE5 */
+#define        BRDY4           0x0010  /* b4: PIPE4 */
+#define        BRDY3           0x0008  /* b3: PIPE3 */
+#define        BRDY2           0x0004  /* b2: PIPE2 */
+#define        BRDY1           0x0002  /* b1: PIPE1 */
+#define        BRDY0           0x0001  /* b1: PIPE0 */
+
+/* NRDY Interrupt Enable/Status Register */
+#define        NRDY9           0x0200  /* b9: PIPE9 */
+#define        NRDY8           0x0100  /* b8: PIPE8 */
+#define        NRDY7           0x0080  /* b7: PIPE7 */
+#define        NRDY6           0x0040  /* b6: PIPE6 */
+#define        NRDY5           0x0020  /* b5: PIPE5 */
+#define        NRDY4           0x0010  /* b4: PIPE4 */
+#define        NRDY3           0x0008  /* b3: PIPE3 */
+#define        NRDY2           0x0004  /* b2: PIPE2 */
+#define        NRDY1           0x0002  /* b1: PIPE1 */
+#define        NRDY0           0x0001  /* b1: PIPE0 */
+
+/* BEMP Interrupt Enable/Status Register */
+#define        BEMP9           0x0200  /* b9: PIPE9 */
+#define        BEMP8           0x0100  /* b8: PIPE8 */
+#define        BEMP7           0x0080  /* b7: PIPE7 */
+#define        BEMP6           0x0040  /* b6: PIPE6 */
+#define        BEMP5           0x0020  /* b5: PIPE5 */
+#define        BEMP4           0x0010  /* b4: PIPE4 */
+#define        BEMP3           0x0008  /* b3: PIPE3 */
+#define        BEMP2           0x0004  /* b2: PIPE2 */
+#define        BEMP1           0x0002  /* b1: PIPE1 */
+#define        BEMP0           0x0001  /* b0: PIPE0 */
+
+/* SOF Pin Configuration Register */
+#define        TRNENSEL        0x0100  /* b8: Select transaction enable period */
+#define        BRDYM           0x0040  /* b6: BRDY clear timing */
+#define        INTL            0x0020  /* b5: Interrupt sense select */
+#define        EDGESTS         0x0010  /* b4:  */
+#define        SOFMODE         0x000C  /* b3-2: SOF pin select */
+#define          SOF_125US      0x0008   /* SOF OUT 125us Frame Signal */
+#define          SOF_1MS        0x0004   /* SOF OUT 1ms Frame Signal */
+#define          SOF_DISABLE    0x0000   /* SOF OUT Disable */
+
+/* Interrupt Status Register 0 */
+#define        VBINT           0x8000  /* b15: VBUS interrupt */
+#define        RESM            0x4000  /* b14: Resume interrupt */
+#define        SOFR            0x2000  /* b13: SOF frame update interrupt */
+#define        DVST            0x1000  /* b12: Device state transition interrupt */
+#define        CTRT            0x0800  /* b11: Control transfer stage transition interrupt */
+#define        BEMP            0x0400  /* b10: Buffer empty interrupt */
+#define        NRDY            0x0200  /* b9: Buffer not ready interrupt */
+#define        BRDY            0x0100  /* b8: Buffer ready interrupt */
+#define        VBSTS           0x0080  /* b7: VBUS input port */
+#define        DVSQ            0x0070  /* b6-4: Device state */
+#define          DS_SPD_CNFG    0x0070   /* Suspend Configured */
+#define          DS_SPD_ADDR    0x0060   /* Suspend Address */
+#define          DS_SPD_DFLT    0x0050   /* Suspend Default */
+#define          DS_SPD_POWR    0x0040   /* Suspend Powered */
+#define          DS_SUSP        0x0040   /* Suspend */
+#define          DS_CNFG        0x0030   /* Configured */
+#define          DS_ADDS        0x0020   /* Address */
+#define          DS_DFLT        0x0010   /* Default */
+#define          DS_POWR        0x0000   /* Powered */
+#define        DVSQS           0x0030  /* b5-4: Device state */
+#define        VALID           0x0008  /* b3: Setup packet detected flag */
+#define        CTSQ            0x0007  /* b2-0: Control transfer stage */
+#define          CS_SQER        0x0006   /* Sequence error */
+#define          CS_WRND        0x0005   /* Control write nodata status stage */
+#define          CS_WRSS        0x0004   /* Control write status stage */
+#define          CS_WRDS        0x0003   /* Control write data stage */
+#define          CS_RDSS        0x0002   /* Control read status stage */
+#define          CS_RDDS        0x0001   /* Control read data stage */
+#define          CS_IDST        0x0000   /* Idle or setup stage */
+
+/* Interrupt Status Register 1 */
+#define        OVRCR           0x8000  /* b15: Over-current interrupt */
+#define        BCHG            0x4000  /* b14: USB bus chenge interrupt */
+#define        DTCH            0x1000  /* b12: Detach sense interrupt */
+#define        ATTCH           0x0800  /* b11: Attach sense interrupt */
+#define        EOFERR          0x0040  /* b6: EOF-error interrupt */
+#define        SIGN            0x0020  /* b5: Setup ignore interrupt */
+#define        SACK            0x0010  /* b4: Setup acknowledge interrupt */
+
+/* Frame Number Register */
+#define        OVRN            0x8000  /* b15: Overrun error */
+#define        CRCE            0x4000  /* b14: Received data error */
+#define        FRNM            0x07FF  /* b10-0: Frame number */
+
+/* Micro Frame Number Register */
+#define        UFRNM           0x0007  /* b2-0: Micro frame number */
+
+/* USB Address / Low Power Status Recovery Register */
+//#define      USBADDR         0x007F  /* b6-0: USB address */
+
+/* Default Control Pipe Maxpacket Size Register */
+/* Pipe Maxpacket Size Register */
+#define        DEVSEL          0xF000  /* b15-14: Device address select */
+#define        MAXP            0x007F  /* b6-0: Maxpacket size of default control pipe */
+
+/* Default Control Pipe Control Register */
+#define        BSTS            0x8000  /* b15: Buffer status */
+#define        SUREQ           0x4000  /* b14: Send USB request  */
+#define        CSCLR           0x2000  /* b13: complete-split status clear */
+#define        CSSTS           0x1000  /* b12: complete-split status */
+#define        SUREQCLR        0x0800  /* b11: stop setup request */
+#define        SQCLR           0x0100  /* b8: Sequence toggle bit clear */
+#define        SQSET           0x0080  /* b7: Sequence toggle bit set */
+#define        SQMON           0x0040  /* b6: Sequence toggle bit monitor */
+#define        PBUSY           0x0020  /* b5: pipe busy */
+#define        PINGE           0x0010  /* b4: ping enable */
+#define        CCPL            0x0004  /* b2: Enable control transfer complete */
+#define        PID             0x0003  /* b1-0: Response PID */
+#define          PID_STALL11    0x0003   /* STALL */
+#define          PID_STALL      0x0002   /* STALL */
+#define          PID_BUF        0x0001   /* BUF */
+#define          PID_NAK        0x0000   /* NAK */
+
+/* Pipe Window Select Register */
+#define        PIPENM          0x0007  /* b2-0: Pipe select */
+
+/* Pipe Configuration Register */
+#define        R8A66597_TYP    0xC000  /* b15-14: Transfer type */
+#define          R8A66597_ISO   0xC000           /* Isochronous */
+#define          R8A66597_INT   0x8000           /* Interrupt */
+#define          R8A66597_BULK  0x4000           /* Bulk */
+#define        R8A66597_BFRE   0x0400  /* b10: Buffer ready interrupt mode select */
+#define        R8A66597_DBLB   0x0200  /* b9: Double buffer mode select */
+#define        R8A66597_CNTMD  0x0100  /* b8: Continuous transfer mode select */
+#define        R8A66597_SHTNAK 0x0080  /* b7: Transfer end NAK */
+#define        R8A66597_DIR    0x0010  /* b4: Transfer direction select */
+#define        R8A66597_EPNUM  0x000F  /* b3-0: Eendpoint number select */
+
+/* Pipe Buffer Configuration Register */
+#define        BUFSIZE         0x7C00  /* b14-10: Pipe buffer size */
+#define        BUFNMB          0x007F  /* b6-0: Pipe buffer number */
+#define        PIPE0BUF        256
+#define        PIPExBUF        64
+
+/* Pipe Maxpacket Size Register */
+#define        MXPS            0x07FF  /* b10-0: Maxpacket size */
+
+/* Pipe Cycle Configuration Register */
+#define        IFIS            0x1000  /* b12: Isochronous in-buffer flush mode select */
+#define        IITV            0x0007  /* b2-0: Isochronous interval */
+
+/* Pipex Control Register */
+#define        BSTS            0x8000  /* b15: Buffer status */
+#define        INBUFM          0x4000  /* b14: IN buffer monitor (Only for PIPE1 to 5) */
+#define        CSCLR           0x2000  /* b13: complete-split status clear */
+#define        CSSTS           0x1000  /* b12: complete-split status */
+#define        ATREPM          0x0400  /* b10: Auto repeat mode */
+#define        ACLRM           0x0200  /* b9: Out buffer auto clear mode */
+#define        SQCLR           0x0100  /* b8: Sequence toggle bit clear */
+#define        SQSET           0x0080  /* b7: Sequence toggle bit set */
+#define        SQMON           0x0040  /* b6: Sequence toggle bit monitor */
+#define        PBUSY           0x0020  /* b5: pipe busy */
+#define        PID             0x0003  /* b1-0: Response PID */
+
+/* PIPExTRE */
+#define        TRENB           0x0200  /* b9: Transaction counter enable */
+#define        TRCLR           0x0100  /* b8: Transaction counter clear */
+
+/* PIPExTRN */
+#define        TRNCNT          0xFFFF  /* b15-0: Transaction counter */
+
+/* DEVADDx */
+#define        UPPHUB          0x7800
+#define        HUBPORT         0x0700
+#define        USBSPD          0x00C0
+#define        RTPORT          0x0001
+
+#define R8A66597_MAX_NUM_PIPE          10
+#define R8A66597_BUF_BSIZE             8
+#define R8A66597_MAX_DEVICE            10
+#define R8A66597_MAX_ROOT_HUB          2
+#define R8A66597_MAX_SAMPLING          10
+#define R8A66597_MAX_DMA_CHANNEL       2
+#define R8A66597_PIPE_NO_DMA           R8A66597_MAX_DMA_CHANNEL
+#define check_bulk_or_isoc(pipenum)    ((pipenum >= 1 && pipenum <= 5))
+#define check_interrupt(pipenum)       ((pipenum >= 6 && pipenum <= 9))
+#define make_devsel(addr)              (addr << 12)
+
+struct r8a66597_pipe_info {
+        u16 pipenum;
+        u16 address;   /* R8A66597 HCD usb addres */
+        u16 epnum;
+        u16 maxpacket;
+        u16 type;
+        u16 bufnum;
+        u16 buf_bsize;
+        u16 interval;
+        u16 dir_in;
+};
+
+struct r8a66597_pipe {
+       struct r8a66597_pipe_info info;
+
+       unsigned long fifoaddr;
+       unsigned long fifosel;
+       unsigned long fifoctr;
+       unsigned long pipectr;
+       unsigned long pipetre;
+       unsigned long pipetrn;
+};
+
+struct r8a66597_td {
+       struct r8a66597_pipe *pipe;
+       struct urb *urb;
+       struct list_head queue;
+
+       u16 type;
+       u16 pipenum;
+       int iso_cnt;
+
+       u16 address;            /* R8A66597's USB address */
+       u16 maxpacket;
+
+       unsigned zero_packet:1;
+       unsigned short_packet:1;
+       unsigned set_address:1;
+};
+
+struct r8a66597_device {
+       u16     address;        /* R8A66597's USB address */
+       u16     hub_port;
+       u16     root_port;
+
+       unsigned short ep_in_toggle;
+       unsigned short ep_out_toggle;
+       unsigned char pipe_cnt[R8A66597_MAX_NUM_PIPE];
+       unsigned char dma_map;
+
+       enum usb_device_state state;
+
+       struct usb_device *udev;
+       int usb_address;
+       struct list_head device_list;
+};
+
+struct r8a66597_root_hub {
+       u32 port;
+       u16 old_syssts;
+       int scount;
+
+       struct r8a66597_device  *dev;
+};
+
+struct r8a66597 {
+       spinlock_t lock;
+       unsigned long reg;
+
+       struct r8a66597_device          device0;
+       struct r8a66597_root_hub        root_hub[R8A66597_MAX_ROOT_HUB];
+       struct list_head                pipe_queue[R8A66597_MAX_NUM_PIPE];
+
+       struct timer_list rh_timer;
+       struct timer_list td_timer[R8A66597_MAX_NUM_PIPE];
+
+       unsigned short address_map;
+       unsigned short timeout_map;
+       unsigned char pipe_cnt[R8A66597_MAX_NUM_PIPE];
+       unsigned char dma_map;
+
+       struct list_head child_device;
+       unsigned long child_connect_map[4];
+};
+
+static inline struct r8a66597 *hcd_to_r8a66597(struct usb_hcd *hcd)
+{
+       return (struct r8a66597 *)(hcd->hcd_priv);
+}
+
+static inline struct usb_hcd *r8a66597_to_hcd(struct r8a66597 *r8a66597)
+{
+       return container_of((void *)r8a66597, struct usb_hcd, hcd_priv);
+}
+
+static inline struct r8a66597_td *r8a66597_get_td(struct r8a66597 *r8a66597,
+                                                 u16 pipenum)
+{
+       if (unlikely(list_empty(&r8a66597->pipe_queue[pipenum])))
+               return NULL;
+
+       return list_entry(r8a66597->pipe_queue[pipenum].next,
+                         struct r8a66597_td, queue);
+}
+
+static inline struct urb *r8a66597_get_urb(struct r8a66597 *r8a66597,
+                                          u16 pipenum)
+{
+       struct r8a66597_td *td;
+
+       td = r8a66597_get_td(r8a66597, pipenum);
+       return (td ? td->urb : NULL);
+}
+
+static inline u16 r8a66597_read(struct r8a66597 *r8a66597, unsigned long offset)
+{
+       return inw(r8a66597->reg + offset);
+}
+
+static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597,
+                                     unsigned long offset, u16 *buf,
+                                     int len)
+{
+       len = (len + 1) / 2;
+       insw(r8a66597->reg + offset, buf, len);
+}
+
+static inline void r8a66597_write(struct r8a66597 *r8a66597, u16 val,
+                                 unsigned long offset)
+{
+       outw(val, r8a66597->reg + offset);
+}
+
+static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597,
+                                      unsigned long offset, u16 *buf,
+                                      int len)
+{
+       unsigned long fifoaddr = r8a66597->reg + offset;
+       int odd = len & 0x0001;
+
+       len = len / 2;
+       outsw(fifoaddr, buf, len);
+       if (unlikely(odd)) {
+               buf = &buf[len];
+               outb((unsigned char)*buf, fifoaddr);
+       }
+}
+
+static inline void r8a66597_mdfy(struct r8a66597 *r8a66597,
+                                u16 val, u16 pat, unsigned long offset)
+{
+       u16 tmp;
+       tmp = r8a66597_read(r8a66597, offset);
+       tmp = tmp & (~pat);
+       tmp = tmp | val;
+       r8a66597_write(r8a66597, tmp, offset);
+}
+
+#define r8a66597_bclr(r8a66597, val, offset)   \
+                       r8a66597_mdfy(r8a66597, 0, val, offset)
+#define r8a66597_bset(r8a66597, val, offset)   \
+                       r8a66597_mdfy(r8a66597, val, 0, offset)
+
+static inline unsigned long get_syscfg_reg(int port)
+{
+       return port == 0 ? SYSCFG0 : SYSCFG1;
+}
+
+static inline unsigned long get_syssts_reg(int port)
+{
+       return port == 0 ? SYSSTS0 : SYSSTS1;
+}
+
+static inline unsigned long get_dvstctr_reg(int port)
+{
+       return port == 0 ? DVSTCTR0 : DVSTCTR1;
+}
+
+static inline unsigned long get_intenb_reg(int port)
+{
+       return port == 0 ? INTENB1 : INTENB2;
+}
+
+static inline unsigned long get_intsts_reg(int port)
+{
+       return port == 0 ? INTSTS1 : INTSTS2;
+}
+
+static inline u16 get_rh_usb_speed(struct r8a66597 *r8a66597, int port)
+{
+       unsigned long dvstctr_reg = get_dvstctr_reg(port);
+
+       return r8a66597_read(r8a66597, dvstctr_reg) & RHST;
+}
+
+static inline void r8a66597_port_power(struct r8a66597 *r8a66597, int port,
+                                      int power)
+{
+       unsigned long dvstctr_reg = get_dvstctr_reg(port);
+
+       if (power)
+               r8a66597_bset(r8a66597, VBOUT, dvstctr_reg);
+       else
+               r8a66597_bclr(r8a66597, VBOUT, dvstctr_reg);
+}
+
+#define get_pipectr_addr(pipenum)      (PIPE1CTR + (pipenum - 1) * 2)
+#define get_pipetre_addr(pipenum)      (PIPE1TRE + (pipenum - 1) * 4)
+#define get_pipetrn_addr(pipenum)      (PIPE1TRN + (pipenum - 1) * 4)
+#define get_devadd_addr(address)       (DEVADD0 + address * 2)
+
+#define enable_irq_ready(r8a66597, pipenum)    \
+       enable_pipe_irq(r8a66597, pipenum, BRDYENB)
+#define disable_irq_ready(r8a66597, pipenum)   \
+       disable_pipe_irq(r8a66597, pipenum, BRDYENB)
+#define enable_irq_empty(r8a66597, pipenum)    \
+       enable_pipe_irq(r8a66597, pipenum, BEMPENB)
+#define disable_irq_empty(r8a66597, pipenum)   \
+       disable_pipe_irq(r8a66597, pipenum, BEMPENB)
+#define enable_irq_nrdy(r8a66597, pipenum)     \
+       enable_pipe_irq(r8a66597, pipenum, NRDYENB)
+#define disable_irq_nrdy(r8a66597, pipenum)    \
+       disable_pipe_irq(r8a66597, pipenum, NRDYENB)
+
+#endif /* __R8A66597_H__ */
+
index d22da26ff1675d6a4f9f8e9a4b40520ff720d443..76c555a67dacc3931649d40f706f94ad2405dc68 100644 (file)
@@ -730,10 +730,9 @@ static int uhci_rh_resume(struct usb_hcd *hcd)
        int rc = 0;
 
        spin_lock_irq(&uhci->lock);
-       if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
-               dev_warn(&hcd->self.root_hub->dev, "HC isn't running!\n");
+       if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))
                rc = -ESHUTDOWN;
-       else if (!uhci->dead)
+       else if (!uhci->dead)
                wakeup_rh(uhci);
        spin_unlock_irq(&uhci->lock);
        return rc;
index 77145f9db0431e47c2cb861c836881a85b3d8740..d72c42e5f22d0a8f1434b9d36c864d177bd0c34a 100644 (file)
@@ -108,8 +108,6 @@ struct adu_device {
        struct urb*             interrupt_out_urb;
 };
 
-/* prevent races between open() and disconnect */
-static DEFINE_MUTEX(disconnect_mutex);
 static struct usb_driver adu_driver;
 
 static void adu_debug_data(int level, const char *function, int size,
@@ -256,8 +254,6 @@ static int adu_open(struct inode *inode, struct file *file)
 
        subminor = iminor(inode);
 
-       mutex_lock(&disconnect_mutex);
-
        interface = usb_find_interface(&adu_driver, subminor);
        if (!interface) {
                err("%s - error, can't find device for minor %d",
@@ -306,7 +302,6 @@ static int adu_open(struct inode *inode, struct file *file)
        up(&dev->sem);
 
 exit_no_device:
-       mutex_unlock(&disconnect_mutex);
        dbg(2,"%s : leave, return value %d ", __FUNCTION__, retval);
 
        return retval;
@@ -318,12 +313,6 @@ static int adu_release_internal(struct adu_device *dev)
 
        dbg(2," %s : enter", __FUNCTION__);
 
-       if (dev->udev == NULL) {
-               /* the device was unplugged before the file was released */
-               adu_delete(dev);
-               goto exit;
-       }
-
        /* decrement our usage count for the device */
        --dev->open_count;
        dbg(2," %s : open count %d", __FUNCTION__, dev->open_count);
@@ -332,7 +321,6 @@ static int adu_release_internal(struct adu_device *dev)
                dev->open_count = 0;
        }
 
-exit:
        dbg(2," %s : leave", __FUNCTION__);
        return retval;
 }
@@ -367,8 +355,15 @@ static int adu_release(struct inode *inode, struct file *file)
                goto exit;
        }
 
-       /* do the work */
-       retval = adu_release_internal(dev);
+       if (dev->udev == NULL) {
+               /* the device was unplugged before the file was released */
+               up(&dev->sem);
+               adu_delete(dev);
+               dev = NULL;
+       } else {
+               /* do the work */
+               retval = adu_release_internal(dev);
+       }
 
 exit:
        if (dev)
@@ -831,19 +826,17 @@ static void adu_disconnect(struct usb_interface *interface)
 
        dbg(2," %s : enter", __FUNCTION__);
 
-       mutex_lock(&disconnect_mutex); /* not interruptible */
-
        dev = usb_get_intfdata(interface);
        usb_set_intfdata(interface, NULL);
 
-       down(&dev->sem); /* not interruptible */
-
        minor = dev->minor;
 
        /* give back our minor */
        usb_deregister_dev(interface, &adu_class);
        dev->minor = 0;
 
+       down(&dev->sem); /* not interruptible */
+
        /* if the device is not opened, then we clean up right now */
        dbg(2," %s : open count %d", __FUNCTION__, dev->open_count);
        if (!dev->open_count) {
@@ -854,8 +847,6 @@ static void adu_disconnect(struct usb_interface *interface)
                up(&dev->sem);
        }
 
-       mutex_unlock(&disconnect_mutex);
-
        dev_info(&interface->dev, "ADU device adutux%d now disconnected",
                 (minor - ADU_MINOR_BASE));
 
index cac1500cba62b8528faca6e1a370f8c769e2b1af..1fd5fc220cd7ee9ac81c08af66e10466e5bb3821 100644 (file)
@@ -2034,12 +2034,12 @@ static void auerswald_disconnect (struct usb_interface *intf)
        if (!cp)
                return;
 
-       down (&cp->mutex);
-       info ("device /dev/%s now disconnecting", cp->name);
-
        /* give back our USB minor number */
        usb_deregister_dev(intf, &auerswald_class);
 
+       down (&cp->mutex);
+       info ("device /dev/%s now disconnecting", cp->name);
+
        /* Stop the interrupt endpoint */
        auerswald_int_release (cp);
 
index b15f2fd8dab459b7ef4ea581f4192e7aae4c5c75..92c1d2768df9680afb7050d74b09b30c10db1d65 100644 (file)
 
 #define RIM_VENDOR             0x0fca
 #define BLACKBERRY             0x0001
+#define BLACKBERRY_PEARL_DUAL   0x0004
+#define BLACKBERRY_PEARL        0x0006
 
 static int debug;
+static int pearl_dual_mode = 1;
 
 #ifdef dbg
 #undef dbg
@@ -38,6 +41,8 @@ static int debug;
 
 static struct usb_device_id id_table [] = {
        { USB_DEVICE(RIM_VENDOR, BLACKBERRY) },
+       { USB_DEVICE(RIM_VENDOR, BLACKBERRY_PEARL) },
+       { USB_DEVICE(RIM_VENDOR, BLACKBERRY_PEARL_DUAL) },
        { },                                    /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, id_table);
@@ -86,6 +91,30 @@ static int magic_charge(struct usb_device *udev)
        return retval;
 }
 
+static int magic_dual_mode(struct usb_device *udev)
+{
+       char *dummy_buffer = kzalloc(2, GFP_KERNEL);
+       int retval;
+
+       if (!dummy_buffer)
+               return -ENOMEM;
+
+       /* send magic command so that the Blackberry Pearl device exposes
+        * two interfaces: both the USB mass-storage one and one which can
+        * be used for database access. */
+       dbg(&udev->dev, "Sending magic pearl command\n");
+       retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+                                0xa9, 0xc0, 1, 1, dummy_buffer, 2, 100);
+       dbg(&udev->dev, "Magic pearl command returned %d\n", retval);
+
+       dbg(&udev->dev, "Calling set_configuration\n");
+       retval = usb_driver_set_configuration(udev, 1);
+       if (retval)
+               dev_err(&udev->dev, "Set Configuration failed :%d.\n", retval);
+
+       return retval;
+}
+
 static int berry_probe(struct usb_interface *intf,
                       const struct usb_device_id *id)
 {
@@ -105,6 +134,10 @@ static int berry_probe(struct usb_interface *intf,
        /* turn the power on */
        magic_charge(udev);
 
+       if ((le16_to_cpu(udev->descriptor.idProduct) == BLACKBERRY_PEARL) &&
+           (pearl_dual_mode))
+               magic_dual_mode(udev);
+
        /* we don't really want to bind to the device, userspace programs can
         * handle the syncing just fine, so get outta here. */
        return -ENODEV;
@@ -138,3 +171,5 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Greg Kroah-Hartman <gregkh@suse.de>");
 module_param(debug, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Debug enabled or not");
+module_param(pearl_dual_mode, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(pearl_dual_mode, "Change Blackberry Pearl to run in dual mode");
index 8d0e360636e64e65ce5db737e9d23a892bf7b9f6..e6fd024024f50c1c317bba53328cd553bef7dd7b 100644 (file)
@@ -119,9 +119,6 @@ static struct usb_driver idmouse_driver = {
        .id_table = idmouse_table,
 };
 
-/* prevent races between open() and disconnect() */
-static DEFINE_MUTEX(disconnect_mutex);
-
 static int idmouse_create_image(struct usb_idmouse *dev)
 {
        int bytes_read;
@@ -211,21 +208,15 @@ static int idmouse_open(struct inode *inode, struct file *file)
        struct usb_interface *interface;
        int result;
 
-       /* prevent disconnects */
-       mutex_lock(&disconnect_mutex);
-
        /* get the interface from minor number and driver information */
        interface = usb_find_interface (&idmouse_driver, iminor (inode));
-       if (!interface) {
-               mutex_unlock(&disconnect_mutex);
+       if (!interface)
                return -ENODEV;
-       }
+
        /* get the device information block from the interface */
        dev = usb_get_intfdata(interface);
-       if (!dev) {
-               mutex_unlock(&disconnect_mutex);
+       if (!dev)
                return -ENODEV;
-       }
 
        /* lock this device */
        down(&dev->sem);
@@ -255,9 +246,6 @@ error:
 
        /* unlock this device */
        up(&dev->sem);
-
-       /* unlock the disconnect semaphore */
-       mutex_unlock(&disconnect_mutex);
        return result;
 }
 
@@ -265,15 +253,10 @@ static int idmouse_release(struct inode *inode, struct file *file)
 {
        struct usb_idmouse *dev;
 
-       /* prevent a race condition with open() */
-       mutex_lock(&disconnect_mutex);
-
        dev = file->private_data;
 
-       if (dev == NULL) {
-               mutex_unlock(&disconnect_mutex);
+       if (dev == NULL)
                return -ENODEV;
-       }
 
        /* lock our device */
        down(&dev->sem);
@@ -281,7 +264,6 @@ static int idmouse_release(struct inode *inode, struct file *file)
        /* are we really open? */
        if (dev->open <= 0) {
                up(&dev->sem);
-               mutex_unlock(&disconnect_mutex);
                return -ENODEV;
        }
 
@@ -291,12 +273,9 @@ static int idmouse_release(struct inode *inode, struct file *file)
                /* the device was unplugged before the file was released */
                up(&dev->sem);
                idmouse_delete(dev);
-               mutex_unlock(&disconnect_mutex);
-               return 0;
+       } else {
+               up(&dev->sem);
        }
-
-       up(&dev->sem);
-       mutex_unlock(&disconnect_mutex);
        return 0;
 }
 
@@ -391,30 +370,27 @@ static void idmouse_disconnect(struct usb_interface *interface)
 {
        struct usb_idmouse *dev;
 
-       /* prevent races with open() */
-       mutex_lock(&disconnect_mutex);
-
        /* get device structure */
        dev = usb_get_intfdata(interface);
        usb_set_intfdata(interface, NULL);
 
-       /* lock it */
-       down(&dev->sem);
-
        /* give back our minor */
        usb_deregister_dev(interface, &idmouse_class);
 
+       /* lock it */
+       down(&dev->sem);
+
        /* prevent device read, write and ioctl */
        dev->present = 0;
 
-       /* unlock */
-       up(&dev->sem);
-
        /* if the device is opened, idmouse_release will clean this up */
-       if (!dev->open)
+       if (!dev->open) {
+               up(&dev->sem);
                idmouse_delete(dev);
-
-       mutex_unlock(&disconnect_mutex);
+       } else {
+               /* unlock */
+               up(&dev->sem);
+       }
 
        info("%s disconnected", DRIVER_DESC);
 }
index 3bb33f7bfa3626ee027218832d409e9dbc2cdb2a..28548d186712ab24872eb15be6d69c86452b8db9 100644 (file)
@@ -100,8 +100,6 @@ struct iowarrior {
 /*--------------*/
 /*    globals   */
 /*--------------*/
-/* prevent races between open() and disconnect() */
-static DECLARE_MUTEX(disconnect_sem);
 
 /*
  *  USB spec identifies 5 second timeouts.
@@ -600,22 +598,18 @@ static int iowarrior_open(struct inode *inode, struct file *file)
 
        subminor = iminor(inode);
 
-       /* prevent disconnects */
-       down(&disconnect_sem);
-
        interface = usb_find_interface(&iowarrior_driver, subminor);
        if (!interface) {
                err("%s - error, can't find device for minor %d", __FUNCTION__,
                    subminor);
-               retval = -ENODEV;
-               goto out;
+               return -ENODEV;
        }
 
        dev = usb_get_intfdata(interface);
-       if (!dev) {
-               retval = -ENODEV;
-               goto out;
-       }
+       if (!dev)
+               return -ENODEV;
+
+       mutex_lock(&dev->mutex);
 
        /* Only one process can open each device, no sharing. */
        if (dev->opened) {
@@ -636,7 +630,7 @@ static int iowarrior_open(struct inode *inode, struct file *file)
        retval = 0;
 
 out:
-       up(&disconnect_sem);
+       mutex_unlock(&dev->mutex);
        return retval;
 }
 
@@ -868,19 +862,16 @@ static void iowarrior_disconnect(struct usb_interface *interface)
        struct iowarrior *dev;
        int minor;
 
-       /* prevent races with open() */
-       down(&disconnect_sem);
-
        dev = usb_get_intfdata(interface);
        usb_set_intfdata(interface, NULL);
 
-       mutex_lock(&dev->mutex);
-
        minor = dev->minor;
 
        /* give back our minor */
        usb_deregister_dev(interface, &iowarrior_class);
 
+       mutex_lock(&dev->mutex);
+
        /* prevent device read, write and ioctl */
        dev->present = 0;
 
@@ -898,7 +889,6 @@ static void iowarrior_disconnect(struct usb_interface *interface)
                /* no process is using the device, cleanup now */
                iowarrior_delete(dev);
        }
-       up(&disconnect_sem);
 
        dev_info(&interface->dev, "I/O-Warror #%d now disconnected\n",
                 minor - IOWARRIOR_MINOR_BASE);
index 7bad494047621a38f61bd8cf90057f2d40870ea7..5e950b90c5414900fb1f7f8fe91a750660dda56d 100644 (file)
@@ -176,9 +176,6 @@ struct ld_usb {
        int                     interrupt_out_busy;
 };
 
-/* prevent races between open() and disconnect() */
-static DEFINE_MUTEX(disconnect_mutex);
-
 static struct usb_driver ld_usb_driver;
 
 /**
@@ -298,35 +295,28 @@ static int ld_usb_open(struct inode *inode, struct file *file)
 {
        struct ld_usb *dev;
        int subminor;
-       int retval = 0;
+       int retval;
        struct usb_interface *interface;
 
        nonseekable_open(inode, file);
        subminor = iminor(inode);
 
-       mutex_lock(&disconnect_mutex);
-
        interface = usb_find_interface(&ld_usb_driver, subminor);
 
        if (!interface) {
                err("%s - error, can't find device for minor %d\n",
                     __FUNCTION__, subminor);
-               retval = -ENODEV;
-               goto unlock_disconnect_exit;
+               return -ENODEV;
        }
 
        dev = usb_get_intfdata(interface);
 
-       if (!dev) {
-               retval = -ENODEV;
-               goto unlock_disconnect_exit;
-       }
+       if (!dev)
+               return -ENODEV;
 
        /* lock this device */
-       if (down_interruptible(&dev->sem)) {
-               retval = -ERESTARTSYS;
-               goto unlock_disconnect_exit;
-       }
+       if (down_interruptible(&dev->sem))
+               return -ERESTARTSYS;
 
        /* allow opening only once */
        if (dev->open_count) {
@@ -366,9 +356,6 @@ static int ld_usb_open(struct inode *inode, struct file *file)
 unlock_exit:
        up(&dev->sem);
 
-unlock_disconnect_exit:
-       mutex_unlock(&disconnect_mutex);
-
        return retval;
 }
 
@@ -766,18 +753,16 @@ static void ld_usb_disconnect(struct usb_interface *intf)
        struct ld_usb *dev;
        int minor;
 
-       mutex_lock(&disconnect_mutex);
-
        dev = usb_get_intfdata(intf);
        usb_set_intfdata(intf, NULL);
 
-       down(&dev->sem);
-
        minor = intf->minor;
 
        /* give back our minor */
        usb_deregister_dev(intf, &ld_usb_class);
 
+       down(&dev->sem);
+
        /* if the device is not opened, then we clean up right now */
        if (!dev->open_count) {
                up(&dev->sem);
@@ -787,8 +772,6 @@ static void ld_usb_disconnect(struct usb_interface *intf)
                up(&dev->sem);
        }
 
-       mutex_unlock(&disconnect_mutex);
-
        dev_info(&intf->dev, "LD USB Device #%d now disconnected\n",
                 (minor - USB_LD_MINOR_BASE));
 }
index 1713e19a789974b086fe96cd458136f37df5175f..2ed0daea894c8c93e5c7313d8dd6558634171095 100644 (file)
@@ -254,9 +254,6 @@ static int  tower_probe     (struct usb_interface *interface, const struct usb_devic
 static void tower_disconnect   (struct usb_interface *interface);
 
 
-/* prevent races between open() and disconnect */
-static DEFINE_MUTEX (disconnect_mutex);
-
 /* file operations needed when we register this driver */
 static const struct file_operations tower_fops = {
        .owner =        THIS_MODULE,
@@ -344,28 +341,26 @@ static int tower_open (struct inode *inode, struct file *file)
        nonseekable_open(inode, file);
        subminor = iminor(inode);
 
-       mutex_lock (&disconnect_mutex);
-
        interface = usb_find_interface (&tower_driver, subminor);
 
        if (!interface) {
                err ("%s - error, can't find device for minor %d",
                     __FUNCTION__, subminor);
                retval = -ENODEV;
-               goto unlock_disconnect_exit;
+               goto exit;
        }
 
        dev = usb_get_intfdata(interface);
 
        if (!dev) {
                retval = -ENODEV;
-               goto unlock_disconnect_exit;
+               goto exit;
        }
 
        /* lock this device */
        if (down_interruptible (&dev->sem)) {
                retval = -ERESTARTSYS;
-               goto unlock_disconnect_exit;
+               goto exit;
        }
 
        /* allow opening only once */
@@ -421,9 +416,7 @@ static int tower_open (struct inode *inode, struct file *file)
 unlock_exit:
        up (&dev->sem);
 
-unlock_disconnect_exit:
-       mutex_unlock (&disconnect_mutex);
-
+exit:
        dbg(2, "%s: leave, return value %d ", __FUNCTION__, retval);
 
        return retval;
@@ -993,19 +986,16 @@ static void tower_disconnect (struct usb_interface *interface)
 
        dbg(2, "%s: enter", __FUNCTION__);
 
-       mutex_lock (&disconnect_mutex);
-
        dev = usb_get_intfdata (interface);
        usb_set_intfdata (interface, NULL);
 
-
-       down (&dev->sem);
-
        minor = dev->minor;
 
        /* give back our minor */
        usb_deregister_dev (interface, &tower_class);
 
+       down (&dev->sem);
+
        /* if the device is not opened, then we clean up right now */
        if (!dev->open_count) {
                up (&dev->sem);
@@ -1015,8 +1005,6 @@ static void tower_disconnect (struct usb_interface *interface)
                up (&dev->sem);
        }
 
-       mutex_unlock (&disconnect_mutex);
-
        info("LEGO USB Tower #%d now disconnected", (minor - LEGO_USB_TOWER_MINOR_BASE));
 
        dbg(2, "%s: leave", __FUNCTION__);
index 6f8b134a79cb8c89d495cb81ad75fc65401cdc39..9f37ba44c132d1cbbabb41f235b320dd155b92b3 100644 (file)
@@ -72,8 +72,6 @@ MODULE_PARM_DESC(last, "Number of last console to take over (1 - MAX_NR_CONSOLES
 
 static struct usb_driver sisusb_driver;
 
-DEFINE_MUTEX(disconnect_mutex);
-
 static void
 sisusb_free_buffers(struct sisusb_usb_data *sisusb)
 {
@@ -2511,31 +2509,24 @@ sisusb_open(struct inode *inode, struct file *file)
        struct usb_interface *interface;
        int subminor = iminor(inode);
 
-       mutex_lock(&disconnect_mutex);
-
        if (!(interface = usb_find_interface(&sisusb_driver, subminor))) {
                printk(KERN_ERR "sisusb[%d]: Failed to find interface\n",
                                subminor);
-               mutex_unlock(&disconnect_mutex);
                return -ENODEV;
        }
 
-       if (!(sisusb = usb_get_intfdata(interface))) {
-               mutex_unlock(&disconnect_mutex);
+       if (!(sisusb = usb_get_intfdata(interface)))
                return -ENODEV;
-       }
 
        mutex_lock(&sisusb->lock);
 
        if (!sisusb->present || !sisusb->ready) {
                mutex_unlock(&sisusb->lock);
-               mutex_unlock(&disconnect_mutex);
                return -ENODEV;
        }
 
        if (sisusb->isopen) {
                mutex_unlock(&sisusb->lock);
-               mutex_unlock(&disconnect_mutex);
                return -EBUSY;
        }
 
@@ -2543,7 +2534,6 @@ sisusb_open(struct inode *inode, struct file *file)
                if (sisusb->sisusb_dev->speed == USB_SPEED_HIGH) {
                        if (sisusb_init_gfxdevice(sisusb, 0)) {
                                mutex_unlock(&sisusb->lock);
-                               mutex_unlock(&disconnect_mutex);
                                printk(KERN_ERR
                                        "sisusbvga[%d]: Failed to initialize "
                                        "device\n",
@@ -2552,7 +2542,6 @@ sisusb_open(struct inode *inode, struct file *file)
                        }
                } else {
                        mutex_unlock(&sisusb->lock);
-                       mutex_unlock(&disconnect_mutex);
                        printk(KERN_ERR
                                "sisusbvga[%d]: Device not attached to "
                                "USB 2.0 hub\n",
@@ -2570,8 +2559,6 @@ sisusb_open(struct inode *inode, struct file *file)
 
        mutex_unlock(&sisusb->lock);
 
-       mutex_unlock(&disconnect_mutex);
-
        return 0;
 }
 
@@ -2601,12 +2588,8 @@ sisusb_release(struct inode *inode, struct file *file)
        struct sisusb_usb_data *sisusb;
        int myminor;
 
-       mutex_lock(&disconnect_mutex);
-
-       if (!(sisusb = (struct sisusb_usb_data *)file->private_data)) {
-               mutex_unlock(&disconnect_mutex);
+       if (!(sisusb = (struct sisusb_usb_data *)file->private_data))
                return -ENODEV;
-       }
 
        mutex_lock(&sisusb->lock);
 
@@ -2626,8 +2609,6 @@ sisusb_release(struct inode *inode, struct file *file)
        /* decrement the usage count on our device */
        kref_put(&sisusb->kref, sisusb_delete);
 
-       mutex_unlock(&disconnect_mutex);
-
        return 0;
 }
 
@@ -3383,12 +3364,9 @@ static void sisusb_disconnect(struct usb_interface *intf)
        sisusb_console_exit(sisusb);
 #endif
 
-       /* The above code doesn't need the disconnect
-        * semaphore to be down; its meaning is to
-        * protect all other routines from the disconnect
-        * case, not the other way round.
-        */
-       mutex_lock(&disconnect_mutex);
+       minor = sisusb->minor;
+
+       usb_deregister_dev(intf, &usb_sisusb_class);
 
        mutex_lock(&sisusb->lock);
 
@@ -3396,12 +3374,8 @@ static void sisusb_disconnect(struct usb_interface *intf)
        if (!sisusb_wait_all_out_complete(sisusb))
                sisusb_kill_all_busy(sisusb);
 
-       minor = sisusb->minor;
-
        usb_set_intfdata(intf, NULL);
 
-       usb_deregister_dev(intf, &usb_sisusb_class);
-
 #ifdef SISUSB_OLD_CONFIG_COMPAT
        if (sisusb->ioctl32registered) {
                int ret;
@@ -3426,8 +3400,6 @@ static void sisusb_disconnect(struct usb_interface *intf)
        /* decrement our usage count */
        kref_put(&sisusb->kref, sisusb_delete);
 
-       mutex_unlock(&disconnect_mutex);
-
        printk(KERN_INFO "sisusbvga[%d]: Disconnected\n", minor);
 }
 
index 5947afb0017ef49159d4b6558a1b740bd0160a83..8d0edc867f3316b969106dfb468d9f8bf249388b 100644 (file)
@@ -214,18 +214,13 @@ sisusbcon_init(struct vc_data *c, int init)
         * are set up/restored.
         */
 
-       mutex_lock(&disconnect_mutex);
-
-       if (!(sisusb = sisusb_get_sisusb(c->vc_num))) {
-               mutex_unlock(&disconnect_mutex);
+       if (!(sisusb = sisusb_get_sisusb(c->vc_num)))
                return;
-       }
 
        mutex_lock(&sisusb->lock);
 
        if (!sisusb_sisusb_valid(sisusb)) {
                mutex_unlock(&sisusb->lock);
-               mutex_unlock(&disconnect_mutex);
                return;
        }
 
@@ -264,8 +259,6 @@ sisusbcon_init(struct vc_data *c, int init)
 
        mutex_unlock(&sisusb->lock);
 
-       mutex_unlock(&disconnect_mutex);
-
        if (init) {
                c->vc_cols = cols;
                c->vc_rows = rows;
@@ -284,12 +277,8 @@ sisusbcon_deinit(struct vc_data *c)
         * and others, ie not under our control.
         */
 
-       mutex_lock(&disconnect_mutex);
-
-       if (!(sisusb = sisusb_get_sisusb(c->vc_num))) {
-               mutex_unlock(&disconnect_mutex);
+       if (!(sisusb = sisusb_get_sisusb(c->vc_num)))
                return;
-       }
 
        mutex_lock(&sisusb->lock);
 
@@ -314,8 +303,6 @@ sisusbcon_deinit(struct vc_data *c)
 
        /* decrement the usage count on our sisusb */
        kref_put(&sisusb->kref, sisusb_delete);
-
-       mutex_unlock(&disconnect_mutex);
 }
 
 /* interface routine */
@@ -1490,14 +1477,11 @@ sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last)
 {
        int i, ret, minor = sisusb->minor;
 
-       mutex_lock(&disconnect_mutex);
-
        mutex_lock(&sisusb->lock);
 
        /* Erm.. that should not happen */
        if (sisusb->haveconsole || !sisusb->SiS_Pr) {
                mutex_unlock(&sisusb->lock);
-               mutex_unlock(&disconnect_mutex);
                return 1;
        }
 
@@ -1508,14 +1492,12 @@ sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last)
            first > MAX_NR_CONSOLES ||
            last > MAX_NR_CONSOLES) {
                mutex_unlock(&sisusb->lock);
-               mutex_unlock(&disconnect_mutex);
                return 1;
        }
 
        /* If gfxcore not initialized or no consoles given, quit graciously */
        if (!sisusb->gfxinit || first < 1 || last < 1) {
                mutex_unlock(&sisusb->lock);
-               mutex_unlock(&disconnect_mutex);
                return 0;
        }
 
@@ -1526,7 +1508,6 @@ sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last)
        /* Set up text mode (and upload  default font) */
        if (sisusb_reset_text_mode(sisusb, 1)) {
                mutex_unlock(&sisusb->lock);
-               mutex_unlock(&disconnect_mutex);
                printk(KERN_ERR
                        "sisusbvga[%d]: Failed to set up text mode\n",
                        minor);
@@ -1550,7 +1531,6 @@ sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last)
        /* Allocate screen buffer */
        if (!(sisusb->scrbuf = (unsigned long)vmalloc(sisusb->scrbuf_size))) {
                mutex_unlock(&sisusb->lock);
-               mutex_unlock(&disconnect_mutex);
                printk(KERN_ERR
                        "sisusbvga[%d]: Failed to allocate screen buffer\n",
                        minor);
@@ -1558,7 +1538,6 @@ sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last)
        }
 
        mutex_unlock(&sisusb->lock);
-       mutex_unlock(&disconnect_mutex);
 
        /* Now grab the desired console(s) */
        ret = take_over_console(&sisusb_con, first - 1, last - 1, 0);
index f05f83268af41df9ccce52a6d99e244d819b4cc1..864bc0e96591afcedfe351342964041c6fee833d 100644 (file)
@@ -808,8 +808,6 @@ static const struct SiS_VCLKData SiSUSB_VCLKData[] =
        { 0x2b,0xc2, 35}  /* 0x71 768@576@60 */
 };
 
-extern struct mutex disconnect_mutex;
-
 int            SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo);
 int            SiSUSBSetVESAMode(struct SiS_Private *SiS_Pr, unsigned short VModeNo);
 
index 12bad8a205a75cc9fc8d8e7f2b4e55b3d092ebc7..504f7221b0d095e8847b902cc6e8955c6517172f 100644 (file)
@@ -45,13 +45,13 @@ struct usb_lcd {
        struct kref             kref;
        struct semaphore        limit_sem;              /* to stop writes at full throttle from
                                                         * using up all RAM */
+       struct usb_anchor       submitted;              /* URBs to wait for before suspend */
 };
 #define to_lcd_dev(d) container_of(d, struct usb_lcd, kref)
 
 #define USB_LCD_CONCURRENT_WRITES      5
 
 static struct usb_driver lcd_driver;
-static DEFINE_MUTEX(usb_lcd_open_mutex);
 
 
 static void lcd_delete(struct kref *kref)
@@ -68,35 +68,35 @@ static int lcd_open(struct inode *inode, struct file *file)
 {
        struct usb_lcd *dev;
        struct usb_interface *interface;
-       int subminor;
-       int retval = 0;
+       int subminor, r;
 
        subminor = iminor(inode);
 
-       mutex_lock(&usb_lcd_open_mutex);
        interface = usb_find_interface(&lcd_driver, subminor);
        if (!interface) {
                err ("USBLCD: %s - error, can't find device for minor %d",
                     __FUNCTION__, subminor);
-               retval = -ENODEV;
-               goto exit;
+               return -ENODEV;
        }
 
        dev = usb_get_intfdata(interface);
-       if (!dev) {
-               retval = -ENODEV;
-               goto exit;
-       }
+       if (!dev)
+               return -ENODEV;
 
        /* increment our usage count for the device */
        kref_get(&dev->kref);
 
+       /* grab a power reference */
+       r = usb_autopm_get_interface(interface);
+       if (r < 0) {
+               kref_put(&dev->kref, lcd_delete);
+               return r;
+       }
+
        /* save our object in the file's private structure */
        file->private_data = dev;
 
-exit:
-       mutex_unlock(&usb_lcd_open_mutex);
-       return retval;
+       return 0;
 }
 
 static int lcd_release(struct inode *inode, struct file *file)
@@ -108,6 +108,7 @@ static int lcd_release(struct inode *inode, struct file *file)
                return -ENODEV;
 
        /* decrement the count on our device */
+       usb_autopm_put_interface(dev->interface);
        kref_put(&dev->kref, lcd_delete);
        return 0;
 }
@@ -233,12 +234,14 @@ static ssize_t lcd_write(struct file *file, const char __user * user_buffer, siz
                          usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),
                          buf, count, lcd_write_bulk_callback, dev);
        urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+       usb_anchor_urb(urb, &dev->submitted);
        
        /* send the data out the bulk port */
        retval = usb_submit_urb(urb, GFP_KERNEL);
        if (retval) {
                err("USBLCD: %s - failed submitting write urb, error %d", __FUNCTION__, retval);
-               goto error;
+               goto error_unanchor;
        }
        
        /* release our reference to this urb, the USB core will eventually free it entirely */
@@ -246,7 +249,8 @@ static ssize_t lcd_write(struct file *file, const char __user * user_buffer, siz
 
 exit:
        return count;
-
+error_unanchor:
+       usb_unanchor_urb(urb);
 error:
        usb_buffer_free(dev->udev, count, buf, urb->transfer_dma);
        usb_free_urb(urb);
@@ -291,6 +295,7 @@ static int lcd_probe(struct usb_interface *interface, const struct usb_device_id
        }
        kref_init(&dev->kref);
        sema_init(&dev->limit_sem, USB_LCD_CONCURRENT_WRITES);
+       init_usb_anchor(&dev->submitted);
 
        dev->udev = usb_get_dev(interface_to_usbdev(interface));
        dev->interface = interface;
@@ -358,22 +363,41 @@ error:
        return retval;
 }
 
+static void lcd_draw_down(struct usb_lcd *dev)
+{
+       int time;
+
+       time = usb_wait_anchor_empty_timeout(&dev->submitted, 1000);
+       if (!time)
+               usb_kill_anchored_urbs(&dev->submitted);
+}
+
+static int lcd_suspend(struct usb_interface *intf, pm_message_t message)
+{
+       struct usb_lcd *dev = usb_get_intfdata(intf);
+
+       if (!dev)
+               return 0;
+       lcd_draw_down(dev);
+       return 0;
+}
+
+static int lcd_resume (struct usb_interface *intf)
+{
+       return 0;
+}
+
 static void lcd_disconnect(struct usb_interface *interface)
 {
        struct usb_lcd *dev;
         int minor = interface->minor;
 
-        /* prevent skel_open() from racing skel_disconnect() */
-        mutex_lock(&usb_lcd_open_mutex);
-
         dev = usb_get_intfdata(interface);
         usb_set_intfdata(interface, NULL);
 
         /* give back our minor */
         usb_deregister_dev(interface, &lcd_class);
  
-       mutex_unlock(&usb_lcd_open_mutex);
-
        /* decrement our usage count */
        kref_put(&dev->kref, lcd_delete);
 
@@ -384,7 +408,10 @@ static struct usb_driver lcd_driver = {
        .name =         "usblcd",
        .probe =        lcd_probe,
        .disconnect =   lcd_disconnect,
+       .suspend =      lcd_suspend,
+       .resume =       lcd_resume,
        .id_table =     id_table,
+       .supports_autosuspend = 1,
 };
 
 static int __init usb_lcd_init(void)
index 0af11a66207cf3e88bb151f2e067c024c5eeea46..c03dfd7a9d36f8fe460869158d78f2a599e1f28e 100644 (file)
@@ -4,7 +4,7 @@
  * This is a binary format reader.
  *
  * Copyright (C) 2006 Paolo Abeni (paolo.abeni@email.it)
- * Copyright (C) 2006 Pete Zaitcev (zaitcev@redhat.com)
+ * Copyright (C) 2006,2007 Pete Zaitcev (zaitcev@redhat.com)
  */
 
 #include <linux/kernel.h>
@@ -172,6 +172,7 @@ static inline struct mon_bin_hdr *MON_OFF2HDR(const struct mon_reader_bin *rp,
 
 #define MON_RING_EMPTY(rp)     ((rp)->b_cnt == 0)
 
+static struct class *mon_bin_class;
 static dev_t mon_bin_dev0;
 static struct cdev mon_bin_cdev;
 
@@ -1144,10 +1145,38 @@ static void mon_free_buff(struct mon_pgmap *map, int npages)
                free_page((unsigned long) map[n].ptr);
 }
 
+int mon_bin_add(struct mon_bus *mbus, const struct usb_bus *ubus)
+{
+       struct device *dev;
+       unsigned minor = ubus? ubus->busnum: 0;
+
+       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);
+       if (IS_ERR(dev))
+               return 0;
+
+       mbus->classdev = dev;
+       return 1;
+}
+
+void mon_bin_del(struct mon_bus *mbus)
+{
+       device_destroy(mon_bin_class, mbus->classdev->devt);
+}
+
 int __init mon_bin_init(void)
 {
        int rc;
 
+       mon_bin_class = class_create(THIS_MODULE, "usbmon");
+       if (IS_ERR(mon_bin_class)) {
+               rc = PTR_ERR(mon_bin_class);
+               goto err_class;
+       }
+
        rc = alloc_chrdev_region(&mon_bin_dev0, 0, MON_BIN_MAX_MINOR, "usbmon");
        if (rc < 0)
                goto err_dev;
@@ -1164,6 +1193,8 @@ int __init mon_bin_init(void)
 err_add:
        unregister_chrdev_region(mon_bin_dev0, MON_BIN_MAX_MINOR);
 err_dev:
+       class_destroy(mon_bin_class);
+err_class:
        return rc;
 }
 
@@ -1171,4 +1202,5 @@ void mon_bin_exit(void)
 {
        cdev_del(&mon_bin_cdev);
        unregister_chrdev_region(mon_bin_dev0, MON_BIN_MAX_MINOR);
+       class_destroy(mon_bin_class);
 }
index 8977ec0d0f9928218ada7a44fdb62cfd142aa072..ce61d8b0fd866b4ea91346296d828667d30a9468 100644 (file)
@@ -220,6 +220,8 @@ static void mon_bus_remove(struct usb_bus *ubus)
        list_del(&mbus->bus_link);
        if (mbus->text_inited)
                mon_text_del(mbus);
+       if (mbus->bin_inited)
+               mon_bin_del(mbus);
 
        mon_dissolve(mbus, ubus);
        kref_put(&mbus->ref, mon_bus_drop);
@@ -301,8 +303,8 @@ static void mon_bus_init(struct usb_bus *ubus)
        mbus->u_bus = ubus;
        ubus->mon_bus = mbus;
 
-       mbus->text_inited = mon_text_add(mbus, ubus->busnum);
-       // mon_bin_add(...)
+       mbus->text_inited = mon_text_add(mbus, ubus);
+       mbus->bin_inited = mon_bin_add(mbus, ubus);
 
        mutex_lock(&mon_lock);
        list_add_tail(&mbus->bus_link, &mon_buses);
@@ -321,8 +323,8 @@ static void mon_bus0_init(void)
        spin_lock_init(&mbus->lock);
        INIT_LIST_HEAD(&mbus->r_list);
 
-       mbus->text_inited = mon_text_add(mbus, 0);
-       // mbus->bin_inited = mon_bin_add(mbus, 0);
+       mbus->text_inited = mon_text_add(mbus, NULL);
+       mbus->bin_inited = mon_bin_add(mbus, NULL);
 }
 
 /*
@@ -403,6 +405,8 @@ static void __exit mon_exit(void)
 
                if (mbus->text_inited)
                        mon_text_del(mbus);
+               if (mbus->bin_inited)
+                       mon_bin_del(mbus);
 
                /*
                 * This never happens, because the open/close paths in
@@ -423,6 +427,8 @@ static void __exit mon_exit(void)
        mbus = &mon_bus0;
        if (mbus->text_inited)
                mon_text_del(mbus);
+       if (mbus->bin_inited)
+               mon_bin_del(mbus);
 
        mutex_unlock(&mon_lock);
 
index ec0cc51e39acc42b0576b15c99bced374228fc2e..982b773d71e69f186210322e98c434ba78425d21 100644 (file)
@@ -655,20 +655,24 @@ static const struct file_operations mon_fops_text_u = {
        .release =      mon_text_release,
 };
 
-int mon_text_add(struct mon_bus *mbus, int busnum)
+int mon_text_add(struct mon_bus *mbus, const struct usb_bus *ubus)
 {
        struct dentry *d;
        enum { NAMESZ = 10 };
        char name[NAMESZ];
+       int busnum = ubus? ubus->busnum: 0;
        int rc;
 
-       rc = snprintf(name, NAMESZ, "%dt", busnum);
-       if (rc <= 0 || rc >= NAMESZ)
-               goto err_print_t;
-       d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_text_t);
-       if (d == NULL)
-               goto err_create_t;
-       mbus->dent_t = d;
+       if (ubus != NULL) {
+               rc = snprintf(name, NAMESZ, "%dt", busnum);
+               if (rc <= 0 || rc >= NAMESZ)
+                       goto err_print_t;
+               d = debugfs_create_file(name, 0600, mon_dir, mbus,
+                                                            &mon_fops_text_t);
+               if (d == NULL)
+                       goto err_create_t;
+               mbus->dent_t = d;
+       }
 
        rc = snprintf(name, NAMESZ, "%du", busnum);
        if (rc <= 0 || rc >= NAMESZ)
@@ -694,8 +698,10 @@ err_print_s:
        mbus->dent_u = NULL;
 err_create_u:
 err_print_u:
-       debugfs_remove(mbus->dent_t);
-       mbus->dent_t = NULL;
+       if (ubus != NULL) {
+               debugfs_remove(mbus->dent_t);
+               mbus->dent_t = NULL;
+       }
 err_create_t:
 err_print_t:
        return 0;
@@ -704,7 +710,8 @@ err_print_t:
 void mon_text_del(struct mon_bus *mbus)
 {
        debugfs_remove(mbus->dent_u);
-       debugfs_remove(mbus->dent_t);
+       if (mbus->dent_t != NULL)
+               debugfs_remove(mbus->dent_t);
        debugfs_remove(mbus->dent_s);
 }
 
index 13d63255283e8682e2c4fe032f80be2dcc5248fa..f68ad6d99ad7563581919fb024c37a4c5259a6e7 100644 (file)
@@ -20,9 +20,11 @@ struct mon_bus {
        struct usb_bus *u_bus;
 
        int text_inited;
+       int bin_inited;
        struct dentry *dent_s;          /* Debugging file */
        struct dentry *dent_t;          /* Text interface file */
        struct dentry *dent_u;          /* Second text interface file */
+       struct device *classdev;        /* Device in usbmon class */
 
        /* Ref */
        int nreaders;                   /* Under mon_lock AND mbus->lock */
@@ -52,9 +54,10 @@ void mon_reader_del(struct mon_bus *mbus, struct mon_reader *r);
 
 struct mon_bus *mon_bus_lookup(unsigned int num);
 
-int /*bool*/ mon_text_add(struct mon_bus *mbus, int busnum);
+int /*bool*/ mon_text_add(struct mon_bus *mbus, const struct usb_bus *ubus);
 void mon_text_del(struct mon_bus *mbus);
-// void mon_bin_add(struct mon_bus *);
+int /*bool*/ mon_bin_add(struct mon_bus *mbus, const struct usb_bus *ubus);
+void mon_bin_del(struct mon_bus *mbus);
 
 int __init mon_text_init(void);
 void mon_text_exit(void);
index 3efe67092f15b85c1db4c4a145b83a79270789e6..43d6db696f905cc7361cee823ccb60d2ed99d4d6 100644 (file)
@@ -464,6 +464,16 @@ config USB_SERIAL_PL2303
          To compile this driver as a module, choose M here: the
          module will be called pl2303.
 
+config USB_SERIAL_OTI6858
+       tristate "USB Ours Technology Inc. OTi-6858 USB To RS232 Bridge Controller (EXPERIMENTAL)"
+       depends on USB_SERIAL
+       help
+         Say Y here if you want to use the OTi-6858 single port USB to serial
+          converter device.
+
+         To compile this driver as a module, choose M here: the
+         module will be called oti6858.
+
 config USB_SERIAL_HP4X
         tristate "USB HP4x Calculators support"
         depends on USB_SERIAL
index 61166ad450e607f97a1f68b13ce1e398ea3a9b94..07a976eca6b7eed0e2a81c6f6724c7db2c9a5544 100644 (file)
@@ -40,6 +40,7 @@ obj-$(CONFIG_USB_SERIAL_MOS7840)              += mos7840.o
 obj-$(CONFIG_USB_SERIAL_NAVMAN)                        += navman.o
 obj-$(CONFIG_USB_SERIAL_OMNINET)               += omninet.o
 obj-$(CONFIG_USB_SERIAL_OPTION)                        += option.o
+obj-$(CONFIG_USB_SERIAL_OTI6858)               += oti6858.o
 obj-$(CONFIG_USB_SERIAL_PL2303)                        += pl2303.o
 obj-$(CONFIG_USB_SERIAL_SAFE)                  += safe_serial.o
 obj-$(CONFIG_USB_SERIAL_SIERRAWIRELESS)                += sierra.o
index fbc8c27d5d994763b842a718d8df2406a62881e7..1cd29cd6bd00c46f524db37a8f21da42be9598f9 100644 (file)
@@ -411,12 +411,13 @@ static int aircable_write(struct usb_serial_port *port,
 static void aircable_write_bulk_callback(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
+       int status = urb->status;
        int result;
 
-       dbg("%s - urb->status: %d", __FUNCTION__ , urb->status);
+       dbg("%s - urb status: %d", __FUNCTION__ , status);
 
        /* This has been taken from cypress_m8.c cypress_write_int_callback */
-       switch (urb->status) {
+       switch (status) {
                case 0:
                        /* success */
                        break;
@@ -425,14 +426,14 @@ static void aircable_write_bulk_callback(struct urb *urb)
                case -ESHUTDOWN:
                        /* this urb is terminated, clean up */
                        dbg("%s - urb shutting down with status: %d",
-                           __FUNCTION__, urb->status);
+                           __FUNCTION__, status);
                        port->write_urb_busy = 0;
                        return;
                default:
                        /* error in the urb, so we have to resubmit it */
                        dbg("%s - Overflow in write", __FUNCTION__);
                        dbg("%s - nonzero write bulk status received: %d",
-                           __FUNCTION__, urb->status);
+                           __FUNCTION__, status);
                        port->write_urb->transfer_buffer_length = 1;
                        port->write_urb->dev = port->serial->dev;
                        result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
@@ -457,16 +458,17 @@ static void aircable_read_bulk_callback(struct urb *urb)
        unsigned long no_packages, remaining, package_length, i;
        int result, shift = 0;
        unsigned char *temp;
+       int status = urb->status;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
-       if (urb->status) {
-               dbg("%s - urb->status = %d", __FUNCTION__, urb->status);
+       if (status) {
+               dbg("%s - urb status = %d", __FUNCTION__, status);
                if (!port->open_count) {
                        dbg("%s - port is closed, exiting.", __FUNCTION__);
                        return;
                }
-               if (urb->status == -EPROTO) {
+               if (status == -EPROTO) {
                        dbg("%s - caught -EPROTO, resubmitting the urb",
                            __FUNCTION__);
                        usb_fill_bulk_urb(port->read_urb, port->serial->dev,
index 39a49836259405605eb041f847e248d63a1728b8..cff6fd190a28273869c4f9b1203e75ccee1ccc85 100644 (file)
@@ -82,12 +82,13 @@ static void airprime_read_bulk_callback(struct urb *urb)
        unsigned char *data = urb->transfer_buffer;
        struct tty_struct *tty;
        int result;
+       int status = urb->status;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
-       if (urb->status) {
+       if (status) {
                dbg("%s - nonzero read bulk status received: %d",
-                   __FUNCTION__, urb->status);
+                   __FUNCTION__, status);
                return;
        }
        usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
@@ -109,6 +110,7 @@ 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", __FUNCTION__, port->number);
@@ -116,9 +118,9 @@ static void airprime_write_bulk_callback(struct urb *urb)
        /* free up the transfer buffer, as usb_free_urb() does not do this */
        kfree (urb->transfer_buffer);
 
-       if (urb->status)
+       if (status)
                dbg("%s - nonzero write bulk status received: %d",
-                   __FUNCTION__, urb->status);
+                   __FUNCTION__, status);
        spin_lock_irqsave(&priv->lock, flags);
        --priv->outstanding_urbs;
        spin_unlock_irqrestore(&priv->lock, flags);
index fe437125f14bc9f86cdb2b4352c04c2c2528aca6..c9fd486c1c7d7a030b9d5b039caabe2a9f3f5c56 100644 (file)
@@ -172,7 +172,7 @@ static void ark3116_set_termios(struct usb_serial_port *port,
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
-       if ((!port->tty) || (!port->tty->termios)) {
+       if (!port->tty || !port->tty->termios) {
                dbg("%s - no tty structures", __FUNCTION__);
                return;
        }
@@ -188,16 +188,6 @@ static void ark3116_set_termios(struct usb_serial_port *port,
 
        cflag = port->tty->termios->c_cflag;
 
-       /* check that they really want us to change something: */
-       if (old_termios) {
-               if ((cflag == old_termios->c_cflag) &&
-                   (RELEVANT_IFLAG(port->tty->termios->c_iflag) ==
-                    RELEVANT_IFLAG(old_termios->c_iflag))) {
-                       dbg("%s - nothing to change...", __FUNCTION__);
-                       return;
-               }
-       }
-
        buf = kmalloc(1, GFP_KERNEL);
        if (!buf) {
                dbg("error kmalloc");
@@ -220,7 +210,7 @@ static void ark3116_set_termios(struct usb_serial_port *port,
                        dbg("setting CS7");
                        break;
                default:
-                       err("CSIZE was set but not CS5-CS8, using CS8!");
+                       dbg("CSIZE was set but not CS5-CS8, using CS8!");
                        /* fall through */
                case CS8:
                        config |= 0x03;
@@ -251,38 +241,33 @@ static void ark3116_set_termios(struct usb_serial_port *port,
        }
 
        /* set baudrate */
-       baud = 0;
-       switch (cflag & CBAUD) {
-               case B0:
-                       err("can't set 0 baud, using 9600 instead");
+       baud = tty_get_baud_rate(port->tty);
+
+       switch (baud) {
+               case 75:
+               case 150:
+               case 300:
+               case 600:
+               case 1200:
+               case 1800:
+               case 2400:
+               case 4800:
+               case 9600:
+               case 19200:
+               case 38400:
+               case 57600:
+               case 115200:
+               case 230400:
+               case 460800:
                        break;
-               case B75:       baud = 75;      break;
-               case B150:      baud = 150;     break;
-               case B300:      baud = 300;     break;
-               case B600:      baud = 600;     break;
-               case B1200:     baud = 1200;    break;
-               case B1800:     baud = 1800;    break;
-               case B2400:     baud = 2400;    break;
-               case B4800:     baud = 4800;    break;
-               case B9600:     baud = 9600;    break;
-               case B19200:    baud = 19200;   break;
-               case B38400:    baud = 38400;   break;
-               case B57600:    baud = 57600;   break;
-               case B115200:   baud = 115200;  break;
-               case B230400:   baud = 230400;  break;
-               case B460800:   baud = 460800;  break;
+               /* set 9600 as default (if given baudrate is invalid for example) */
                default:
-                       dbg("does not support the baudrate requested (fix it)");
-                       break;
+                       baud = 9600;
        }
 
-       /* set 9600 as default (if given baudrate is invalid for example) */
-       if (baud == 0)
-               baud = 9600;
-
        /*
         * found by try'n'error, be careful, maybe there are other options
-        * for multiplicator etc!
+        * for multiplicator etc! (3.5 for example)
         */
        if (baud == 460800)
                /* strange, for 460800 the formula is wrong
index 3b800d277c4b90849a693d8092b421d297eadd82..e67ce25f7512627dad57bf4930d2ca26c6bc413a 100644 (file)
@@ -255,9 +255,10 @@ static void belkin_sa_read_int_callback (struct urb *urb)
        struct belkin_sa_private *priv;
        unsigned char *data = urb->transfer_buffer;
        int retval;
+       int status = urb->status;
        unsigned long flags;
 
-       switch (urb->status) {
+       switch (status) {
        case 0:
                /* success */
                break;
@@ -265,10 +266,12 @@ static void belkin_sa_read_int_callback (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",
+                   __FUNCTION__, status);
                return;
        default:
-               dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
+               dbg("%s - nonzero urb status received: %d",
+                   __FUNCTION__, status);
                goto exit;
        }
 
@@ -346,6 +349,7 @@ static void belkin_sa_set_termios (struct usb_serial_port *port, struct ktermios
        unsigned long flags;
        unsigned long control_state;
        int bad_flow_control;
+       speed_t baud;
        
        if ((!port->tty) || (!port->tty->termios)) {
                dbg ("%s - no tty or termios structure", __FUNCTION__);
@@ -361,16 +365,8 @@ static void belkin_sa_set_termios (struct usb_serial_port *port, struct ktermios
        bad_flow_control = priv->bad_flow_control;
        spin_unlock_irqrestore(&priv->lock, flags);
        
-       /* check that they really want us to change something */
-       if (old_termios) {
-               if ((cflag == old_termios->c_cflag) &&
-                   (RELEVANT_IFLAG(port->tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) {
-                       dbg("%s - nothing to change...", __FUNCTION__);
-                       return;
-               }
-               old_iflag = old_termios->c_iflag;
-               old_cflag = old_termios->c_cflag;
-       }
+       old_iflag = old_termios->c_iflag;
+       old_cflag = old_termios->c_cflag;
 
        /* Set the baud rate */
        if( (cflag&CBAUD) != (old_cflag&CBAUD) ) {
@@ -384,38 +380,30 @@ static void belkin_sa_set_termios (struct usb_serial_port *port, struct ktermios
                                if (BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, 1) < 0)
                                        err("Set RTS error");
                }
+       }
 
-               switch(cflag & CBAUD) {
-                       case B0: /* handled below */ break;
-                       case B300: urb_value = BELKIN_SA_BAUD(300); break;
-                       case B600: urb_value = BELKIN_SA_BAUD(600); break;
-                       case B1200: urb_value = BELKIN_SA_BAUD(1200); break;
-                       case B2400: urb_value = BELKIN_SA_BAUD(2400); break;
-                       case B4800: urb_value = BELKIN_SA_BAUD(4800); break;
-                       case B9600: urb_value = BELKIN_SA_BAUD(9600); break;
-                       case B19200: urb_value = BELKIN_SA_BAUD(19200); break;
-                       case B38400: urb_value = BELKIN_SA_BAUD(38400); break;
-                       case B57600: urb_value = BELKIN_SA_BAUD(57600); break;
-                       case B115200: urb_value = BELKIN_SA_BAUD(115200); break;
-                       case B230400: urb_value = BELKIN_SA_BAUD(230400); break;
-                       default: err("BELKIN USB Serial Adapter: unsupported baudrate request, using default of 9600");
-                               urb_value = BELKIN_SA_BAUD(9600); break;
-               }
-               if ((cflag & CBAUD) != B0 ) {
-                       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)
-                               err("Disable flowcontrol error");
-
-                       /* Drop RTS and DTR */
-                       control_state &= ~(TIOCM_DTR | TIOCM_RTS);
-                       if (BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, 0) < 0)
-                               err("DTR LOW error");
-                       if (BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, 0) < 0)
-                               err("RTS LOW error");
-               }
+       baud = tty_get_baud_rate(port->tty);
+       urb_value = BELKIN_SA_BAUD(baud);
+       /* Clip to maximum speed */
+       if (urb_value == 0)
+               urb_value = 1;
+       /* Turn it back into a resulting real baud rate */
+       baud = BELKIN_SA_BAUD(urb_value);
+       /* FIXME: Once the tty updates are done then push this back to the tty */
+
+       if ((cflag & CBAUD) != B0 ) {
+               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)
+                       err("Disable flowcontrol error");
+               /* Drop RTS and DTR */
+               control_state &= ~(TIOCM_DTR | TIOCM_RTS);
+               if (BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, 0) < 0)
+                       err("DTR LOW error");
+               if (BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, 0) < 0)
+                       err("RTS LOW error");
        }
 
        /* set the parity */
@@ -435,7 +423,7 @@ static void belkin_sa_set_termios (struct usb_serial_port *port, struct ktermios
                        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: err("CSIZE was not CS5-CS8, using default of 8");
+                       default: dbg("CSIZE was not CS5-CS8, using default of 8");
                                urb_value = BELKIN_SA_DATA_BITS(8);
                                break;
                }
index 4167753ed31fc3efa401bb1366c4e1991e04358b..4353df92487f528256ca27bb8169d287d3f85b63 100644 (file)
@@ -305,12 +305,13 @@ static void cyberjack_read_int_callback( struct urb *urb )
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        struct cyberjack_private *priv = usb_get_serial_port_data(port);
        unsigned char *data = urb->transfer_buffer;
+       int status = urb->status;
        int result;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
        /* the urb might have been killed. */
-       if (urb->status)
+       if (status)
                return;
 
        usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
@@ -365,12 +366,14 @@ static void cyberjack_read_bulk_callback (struct urb *urb)
        unsigned char *data = urb->transfer_buffer;
        short todo;
        int result;
+       int status = urb->status;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
-       
+
        usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
-       if (urb->status) {
-               dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status);
+       if (status) {
+               dbg("%s - nonzero read bulk status received: %d",
+                   __FUNCTION__, status);
                return;
        }
 
@@ -411,12 +414,14 @@ static void cyberjack_write_bulk_callback (struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        struct cyberjack_private *priv = usb_get_serial_port_data(port);
+       int status = urb->status;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
        port->write_urb_busy = 0;
-       if (urb->status) {
-               dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
+       if (status) {
+               dbg("%s - nonzero write bulk status received: %d",
+                   __FUNCTION__, status);
                return;
        }
 
index 57b8e27285fc007dda4805d0447d51fb0096e43a..163386336a5daa76852eda408974ace308bf2176 100644 (file)
@@ -1275,10 +1275,11 @@ static void cypress_read_int_callback(struct urb *urb)
        int bytes = 0;
        int result;
        int i = 0;
+       int status = urb->status;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
-       switch (urb->status) {
+       switch (status) {
        case 0: /* success */
                break;
        case -ECONNRESET:
@@ -1292,7 +1293,7 @@ static void cypress_read_int_callback(struct urb *urb)
        default:
                /* something ugly is going on... */
                dev_err(&urb->dev->dev,"%s - unexpected nonzero read status received: %d\n",
-                       __FUNCTION__,urb->status);
+                       __FUNCTION__, status);
                cypress_set_dead(port);
                return;
        }
@@ -1419,10 +1420,11 @@ static void cypress_write_int_callback(struct urb *urb)
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        struct cypress_private *priv = usb_get_serial_port_data(port);
        int result;
+       int status = urb->status;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
-       
-       switch (urb->status) {
+
+       switch (status) {
                case 0:
                        /* success */
                        break;
@@ -1430,7 +1432,8 @@ static void cypress_write_int_callback(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",
+                           __FUNCTION__, status);
                        priv->write_urb_in_use = 0;
                        return;
                case -EPIPE: /* no break needed; clear halt and resubmit */
@@ -1438,7 +1441,8 @@ static void cypress_write_int_callback(struct urb *urb)
                                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", __FUNCTION__, urb->status);
+                       dbg("%s - nonzero write bulk status received: %d",
+                           __FUNCTION__, 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);
@@ -1450,7 +1454,7 @@ static void cypress_write_int_callback(struct urb *urb)
                        break;
                default:
                        dev_err(&urb->dev->dev,"%s - unexpected nonzero write status received: %d\n",
-                               __FUNCTION__,urb->status);
+                               __FUNCTION__, status);
                        cypress_set_dead(port);
                        break;
        }
index d78692c01cfa3ca9a75749ee9a3fec6f5e92762f..976f54ec26e66e0529f10a2c6d6879953a1b7f67 100644 (file)
@@ -416,9 +416,6 @@ struct digi_port {
        int dp_port_num;
        int dp_out_buf_len;
        unsigned char dp_out_buf[DIGI_OUT_BUF_SIZE];
-       int dp_in_buf_len;
-       unsigned char dp_in_buf[DIGI_IN_BUF_SIZE];
-       unsigned char dp_in_flag_buf[DIGI_IN_BUF_SIZE];
        int dp_write_urb_in_use;
        unsigned int dp_modem_signals;
        wait_queue_head_t dp_modem_change_wait;
@@ -920,7 +917,6 @@ dbg( "digi_rx_throttle: TOP: port=%d", priv->dp_port_num );
        spin_lock_irqsave( &priv->dp_port_lock, flags );
        priv->dp_throttled = 1;
        priv->dp_throttle_restart = 0;
-       priv->dp_in_buf_len = 0;
        spin_unlock_irqrestore( &priv->dp_port_lock, flags );
 
 }
@@ -930,23 +926,16 @@ static void digi_rx_unthrottle( struct usb_serial_port *port )
 {
 
        int ret = 0;
-       int len;
        unsigned long flags;
        struct digi_port *priv = usb_get_serial_port_data(port);
-       struct tty_struct *tty = port->tty;
-
 
 dbg( "digi_rx_unthrottle: TOP: port=%d", priv->dp_port_num );
 
        spin_lock_irqsave( &priv->dp_port_lock, flags );
 
-       /* send any buffered chars from throttle time on to tty subsystem */
-
-       len = tty_buffer_request_room(tty, priv->dp_in_buf_len);
-       if( len > 0 ) {
-               tty_insert_flip_string_flags(tty, priv->dp_in_buf, priv->dp_in_flag_buf, len);
-               tty_flip_buffer_push( tty );
-       }
+       /* turn throttle off */
+       priv->dp_throttled = 0;
+       priv->dp_throttle_restart = 0;
 
        /* restart read chain */
        if( priv->dp_throttle_restart ) {
@@ -954,11 +943,6 @@ dbg( "digi_rx_unthrottle: TOP: port=%d", priv->dp_port_num );
                ret = usb_submit_urb( port->read_urb, GFP_ATOMIC );
        }
 
-       /* turn throttle off */
-       priv->dp_throttled = 0;
-       priv->dp_in_buf_len = 0;
-       priv->dp_throttle_restart = 0;
-
        spin_unlock_irqrestore( &priv->dp_port_lock, flags );
 
        if( ret ) {
@@ -1340,19 +1324,21 @@ static void digi_write_bulk_callback( struct urb *urb )
        struct digi_port *priv;
        struct digi_serial *serial_priv;
        int ret = 0;
+       int status = urb->status;
 
 
-dbg( "digi_write_bulk_callback: TOP, urb->status=%d", urb->status );
+       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 ) {
-               err("%s: port or port->private is NULL, status=%d", __FUNCTION__,
-                       urb->status );
+               err("%s: port or port->private is NULL, status=%d",
+                   __FUNCTION__, status);
                return;
        }
        serial = port->serial;
        if( serial == NULL || (serial_priv=usb_get_serial_data(serial)) == NULL ) {
-               err("%s: serial or serial->private is NULL, status=%d", __FUNCTION__, urb->status );
+               err("%s: serial or serial->private is NULL, status=%d",
+                   __FUNCTION__, status);
                return;
        }
 
@@ -1687,7 +1673,6 @@ dbg( "digi_startup: TOP" );
                spin_lock_init( &priv->dp_port_lock );
                priv->dp_port_num = i;
                priv->dp_out_buf_len = 0;
-               priv->dp_in_buf_len = 0;
                priv->dp_write_urb_in_use = 0;
                priv->dp_modem_signals = 0;
                init_waitqueue_head( &priv->dp_modem_change_wait );
@@ -1757,25 +1742,28 @@ static void digi_read_bulk_callback( struct urb *urb )
        struct digi_port *priv;
        struct digi_serial *serial_priv;
        int ret;
+       int status = urb->status;
 
 
 dbg( "digi_read_bulk_callback: TOP" );
 
        /* port sanity check, do not resubmit if port is not valid */
        if( port == NULL || (priv=usb_get_serial_port_data(port)) == NULL ) {
-               err("%s: port or port->private is NULL, status=%d", __FUNCTION__,
-                       urb->status );
+               err("%s: port or port->private is NULL, status=%d",
+                   __FUNCTION__, status);
                return;
        }
        if( port->serial == NULL
        || (serial_priv=usb_get_serial_data(port->serial)) == NULL ) {
-               err("%s: serial is bad or serial->private is NULL, status=%d", __FUNCTION__, urb->status );
+               err("%s: serial is bad or serial->private is NULL, status=%d",
+                   __FUNCTION__, status);
                return;
        }
 
        /* do not resubmit urb if it has any status error */
-       if( urb->status ) {
-               err("%s: nonzero read bulk status: status=%d, port=%d", __FUNCTION__, urb->status, priv->dp_port_num );
+       if (status) {
+               err("%s: nonzero read bulk status: status=%d, port=%d",
+                   __FUNCTION__, status, priv->dp_port_num);
                return;
        }
 
@@ -1816,10 +1804,11 @@ static int digi_read_inb_callback( struct urb *urb )
        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 status = ((unsigned char *)urb->transfer_buffer)[2];
+       int port_status = ((unsigned char *)urb->transfer_buffer)[2];
        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 */
@@ -1828,7 +1817,10 @@ static int digi_read_inb_callback( struct urb *urb )
 
        /* short/multiple packet check */
        if( urb->actual_length != len + 2 ) {
-               err("%s: INCOMPLETE OR MULTIPLE PACKET, urb->status=%d, port=%d, opcode=%d, len=%d, actual_length=%d, status=%d", __FUNCTION__, urb->status, priv->dp_port_num, opcode, len, urb->actual_length, status );
+               err("%s: INCOMPLETE OR MULTIPLE PACKET, urb status=%d, "
+                   "port=%d, opcode=%d, len=%d, actual_length=%d, "
+                   "port_status=%d", __FUNCTION__, status, priv->dp_port_num,
+                   opcode, len, urb->actual_length, port_status);
                return( -1 );
        }
 
@@ -1843,52 +1835,37 @@ static int digi_read_inb_callback( struct urb *urb )
        /* receive data */
        if( opcode == DIGI_CMD_RECEIVE_DATA ) {
 
-               /* get flag from status */
+               /* get flag from port_status */
                flag = 0;
 
                /* overrun is special, not associated with a char */
-               if( status & DIGI_OVERRUN_ERROR ) {
+               if (port_status & DIGI_OVERRUN_ERROR) {
                        tty_insert_flip_char( tty, 0, TTY_OVERRUN );
                }
 
                /* break takes precedence over parity, */
                /* which takes precedence over framing errors */
-               if( status & DIGI_BREAK_ERROR ) {
+               if (port_status & DIGI_BREAK_ERROR) {
                        flag = TTY_BREAK;
-               } else if( status & DIGI_PARITY_ERROR ) {
+               } else if (port_status & DIGI_PARITY_ERROR) {
                        flag = TTY_PARITY;
-               } else if( status & DIGI_FRAMING_ERROR ) {
+               } else if (port_status & DIGI_FRAMING_ERROR) {
                        flag = TTY_FRAME;
                }
 
-               /* data length is len-1 (one byte of len is status) */
+               /* data length is len-1 (one byte of len is port_status) */
                --len;
 
-               if( throttled ) {
-
-                       len = min( len,
-                               DIGI_IN_BUF_SIZE - priv->dp_in_buf_len );
-
-                       if( len > 0 ) {
-                               memcpy( priv->dp_in_buf + priv->dp_in_buf_len,
-                                       data, len );
-                               memset( priv->dp_in_flag_buf
-                                       + priv->dp_in_buf_len, flag, len );
-                               priv->dp_in_buf_len += len;
-                       }
-
-               } else {
-                       len = tty_buffer_request_room(tty, len);
-                       if( len > 0 ) {
-                               /* Hot path */
-                               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);
-                               }
-                               tty_flip_buffer_push( tty );
+               len = tty_buffer_request_room(tty, len);
+               if( len > 0 ) {
+                       /* Hot path */
+                       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);
                        }
+                       tty_flip_buffer_push( tty );
                }
        }
 
index 4703c8f853837431616249f846647d07b344546b..050fcc996f5600d2984b6c84c2b4b71d61ecb70d 100644 (file)
@@ -326,12 +326,14 @@ static int empeg_chars_in_buffer (struct usb_serial_port *port)
 
 static void empeg_write_bulk_callback (struct urb *urb)
 {
-       struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+       struct usb_serial_port *port = urb->context;
+       int status = urb->status;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
-       if (urb->status) {
-               dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
+       if (status) {
+               dbg("%s - nonzero write bulk status received: %d",
+                   __FUNCTION__, status);
                return;
        }
 
@@ -345,11 +347,13 @@ static void empeg_read_bulk_callback (struct urb *urb)
        struct tty_struct *tty;
        unsigned char *data = urb->transfer_buffer;
        int result;
+       int status = urb->status;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
-       if (urb->status) {
-               dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status);
+       if (status) {
+               dbg("%s - nonzero read bulk status received: %d",
+                   __FUNCTION__, status);
                return;
        }
 
index da1c6f7f82b8123aba7e089c4133b5f7beace4f0..7b1673a440775aaef3673915432cbed74c508051 100644 (file)
@@ -271,26 +271,58 @@ static int debug;
 static __u16 vendor = FTDI_VID;
 static __u16 product;
 
+struct ftdi_private {
+       ftdi_chip_type_t chip_type;
+                               /* type of the 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!) */
+       __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
+                                */
+       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 */
+       char prev_status, diff_status;        /* Used for TIOCMIWAIT */
+       __u8 rx_flags;          /* receive state flags (throttling) */
+       spinlock_t rx_lock;     /* spinlock for receive state */
+       struct delayed_work rx_work;
+       struct usb_serial_port *port;
+       int rx_processed;
+       unsigned long rx_bytes;
+
+       __u16 interface;        /* FT2232C port interface (0 for FT232/245) */
+
+       int 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;
+       unsigned long tx_outstanding_bytes;
+       unsigned long tx_outstanding_urbs;
+};
+
 /* struct ftdi_sio_quirk is used by devices requiring special attention. */
 struct ftdi_sio_quirk {
        int (*probe)(struct usb_serial *);
-       void (*setup)(struct usb_serial *); /* Special settings during startup. */
+       void (*port_probe)(struct ftdi_private *); /* Special settings for probed ports. */
 };
 
 static int   ftdi_olimex_probe         (struct usb_serial *serial);
-static void  ftdi_USB_UIRT_setup       (struct usb_serial *serial);
-static void  ftdi_HE_TIRA1_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_olimex_quirk = {
        .probe  = ftdi_olimex_probe,
 };
 
 static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = {
-       .setup = ftdi_USB_UIRT_setup,
+       .port_probe = ftdi_USB_UIRT_setup,
 };
 
 static struct ftdi_sio_quirk ftdi_HE_TIRA1_quirk = {
-       .setup = ftdi_HE_TIRA1_setup,
+       .port_probe = ftdi_HE_TIRA1_setup,
 };
 
 /*
@@ -567,38 +599,6 @@ static const char *ftdi_chip_name[] = {
 #define THROTTLED              0x01
 #define ACTUALLY_THROTTLED     0x02
 
-struct ftdi_private {
-       ftdi_chip_type_t chip_type;
-                               /* type of the 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!) */
-       __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
-                                */
-       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 */
-       char prev_status, diff_status;        /* Used for TIOCMIWAIT */
-       __u8 rx_flags;          /* receive state flags (throttling) */
-       spinlock_t rx_lock;     /* spinlock for receive state */
-       struct delayed_work rx_work;
-       struct usb_serial_port *port;
-       int rx_processed;
-       unsigned long rx_bytes;
-
-       __u16 interface;        /* FT2232C port interface (0 for FT232/245) */
-
-       int 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;
-       unsigned long tx_outstanding_bytes;
-       unsigned long tx_outstanding_urbs;
-};
-
 /* Used for TIOCMIWAIT */
 #define FTDI_STATUS_B0_MASK    (FTDI_RS0_CTS | FTDI_RS0_DSR | FTDI_RS0_RI | FTDI_RS0_RLSD)
 #define FTDI_STATUS_B1_MASK    (FTDI_RS_BI)
@@ -609,7 +609,6 @@ struct ftdi_private {
 
 /* function prototypes for a FTDI serial converter */
 static int  ftdi_sio_probe     (struct usb_serial *serial, const struct usb_device_id *id);
-static int  ftdi_sio_attach            (struct usb_serial *serial);
 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);
@@ -663,7 +662,6 @@ static struct usb_serial_driver ftdi_sio_device = {
        .ioctl =                ftdi_ioctl,
        .set_termios =          ftdi_set_termios,
        .break_ctl =            ftdi_break_ctl,
-       .attach =               ftdi_sio_attach,
        .shutdown =             ftdi_shutdown,
 };
 
@@ -1149,7 +1147,9 @@ static int create_sysfs_attrs(struct usb_serial_port *port)
                dbg("sysfs attributes for %s", ftdi_chip_name[priv->chip_type]);
                retval = device_create_file(&port->dev, &dev_attr_event_char);
                if ((!retval) &&
-                   (priv->chip_type == FT232BM || priv->chip_type == FT2232C)) {
+                   (priv->chip_type == FT232BM ||
+                    priv->chip_type == FT2232C ||
+                    priv->chip_type == FT232RL)) {
                        retval = device_create_file(&port->dev,
                                                    &dev_attr_latency_timer);
                }
@@ -1198,6 +1198,8 @@ static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id
 static int ftdi_sio_port_probe(struct usb_serial_port *port)
 {
        struct ftdi_private *priv;
+       struct ftdi_sio_quirk *quirk = usb_get_serial_data(port->serial);
+
 
        dbg("%s",__FUNCTION__);
 
@@ -1214,6 +1216,9 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
           than queue a task to deliver them */
        priv->flags = ASYNC_LOW_LATENCY;
 
+       if (quirk && quirk->port_probe)
+               quirk->port_probe(priv);
+
        /* Increase the size of read buffers */
        kfree(port->bulk_in_buffer);
        port->bulk_in_buffer = kmalloc (BUFSZ, GFP_KERNEL);
@@ -1244,29 +1249,13 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
        return 0;
 }
 
-/* attach subroutine */
-static int ftdi_sio_attach (struct usb_serial *serial)
-{
-       /* Check for device requiring special set up. */
-       struct ftdi_sio_quirk *quirk = usb_get_serial_data(serial);
-
-       if (quirk && quirk->setup)
-               quirk->setup(serial);
-
-       return 0;
-} /* ftdi_sio_attach */
-
-
 /* 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 usb_serial *serial)
+static void ftdi_USB_UIRT_setup (struct ftdi_private *priv)
 {
-       struct ftdi_private *priv;
-
        dbg("%s",__FUNCTION__);
 
-       priv = usb_get_serial_port_data(serial->port[0]);
        priv->flags |= ASYNC_SPD_CUST;
        priv->custom_divisor = 77;
        priv->force_baud = B38400;
@@ -1274,13 +1263,10 @@ static void ftdi_USB_UIRT_setup (struct usb_serial *serial)
 
 /* 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 usb_serial *serial)
+static void ftdi_HE_TIRA1_setup (struct ftdi_private *priv)
 {
-       struct ftdi_private *priv;
-
        dbg("%s",__FUNCTION__);
 
-       priv = usb_get_serial_port_data(serial->port[0]);
        priv->flags |= ASYNC_SPD_CUST;
        priv->custom_divisor = 240;
        priv->force_baud = B38400;
@@ -1574,14 +1560,15 @@ static void ftdi_write_bulk_callback (struct urb *urb)
        struct ftdi_private *priv;
        int data_offset;       /* will be 1 for the SIO and 0 otherwise */
        unsigned long countback;
+       int status = urb->status;
 
        /* free up the transfer buffer, as usb_free_urb() does not do this */
        kfree (urb->transfer_buffer);
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
-       if (urb->status) {
-               dbg("nonzero write bulk status received: %d", urb->status);
+       if (status) {
+               dbg("nonzero write bulk status received: %d", status);
                return;
        }
 
@@ -1657,6 +1644,7 @@ static void ftdi_read_bulk_callback (struct urb *urb)
        struct ftdi_private *priv;
        unsigned long countread;
        unsigned long flags;
+       int status = urb->status;
 
        if (urb->number_of_packets > 0) {
                err("%s transfer_buffer_length %d actual_length %d number of packets %d",__FUNCTION__,
@@ -1685,9 +1673,10 @@ static void ftdi_read_bulk_callback (struct urb *urb)
                err("%s - Not my urb!", __FUNCTION__);
        }
 
-       if (urb->status) {
+       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", urb->status);
+               dbg("(this is ok on close) nonzero read bulk status received: "
+                   "%d", status);
                return;
        }
 
index 74660a3aa6708f3221738b8acea686af4313a80f..04bd3b7a298516a4f4409033df182ddfaf54ea80 100644 (file)
@@ -1036,15 +1036,16 @@ static void garmin_write_bulk_callback (struct urb *urb)
        unsigned long flags;
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+       int status = urb->status;
 
        /* free up the transfer buffer, as usb_free_urb() does not do this */
        kfree (urb->transfer_buffer);
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
-       if (urb->status) {
+       if (status) {
                dbg("%s - nonzero write bulk status received: %d",
-                       __FUNCTION__, urb->status);
+                       __FUNCTION__, status);
                spin_lock_irqsave(&garmin_data_p->lock, flags);
                garmin_data_p->flags |= CLEAR_HALT_REQUIRED;
                spin_unlock_irqrestore(&garmin_data_p->lock, flags);
@@ -1281,7 +1282,8 @@ static void garmin_read_bulk_callback (struct urb *urb)
        struct usb_serial *serial =  port->serial;
        struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
        unsigned char *data = urb->transfer_buffer;
-       int status;
+       int status = urb->status;
+       int retval;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
@@ -1290,9 +1292,9 @@ static void garmin_read_bulk_callback (struct urb *urb)
                return;
        }
 
-       if (urb->status) {
+       if (status) {
                dbg("%s - nonzero read bulk status received: %d",
-                       __FUNCTION__, urb->status);
+                       __FUNCTION__, status);
                return;
        }
 
@@ -1306,19 +1308,19 @@ static void garmin_read_bulk_callback (struct urb *urb)
                spin_lock_irqsave(&garmin_data_p->lock, flags);
                garmin_data_p->flags &= ~FLAGS_BULK_IN_RESTART;
                spin_unlock_irqrestore(&garmin_data_p->lock, flags);
-               status = usb_submit_urb(port->read_urb, GFP_ATOMIC);
-               if (status)
+               retval = usb_submit_urb(port->read_urb, GFP_ATOMIC);
+               if (retval)
                        dev_err(&port->dev,
                                "%s - failed resubmitting read urb, error %d\n",
-                               __FUNCTION__, status);
+                               __FUNCTION__, retval);
        } else if (urb->actual_length > 0) {
                /* Continue trying to read until nothing more is received  */
                if (0 == (garmin_data_p->flags & FLAGS_THROTTLED)) {
-                       status = usb_submit_urb(port->read_urb, GFP_ATOMIC);
-                       if (status)
+                       retval = usb_submit_urb(port->read_urb, GFP_ATOMIC);
+                       if (retval)
                                dev_err(&port->dev,
-                                       "%s - failed resubmitting read urb, error %d\n",
-                                       __FUNCTION__, status);
+                                       "%s - failed resubmitting read urb, "
+                                       "error %d\n", __FUNCTION__, retval);
                }
        } else {
                dbg("%s - end of bulk data", __FUNCTION__);
@@ -1333,13 +1335,14 @@ static void garmin_read_bulk_callback (struct urb *urb)
 static void garmin_read_int_callback (struct urb *urb)
 {
        unsigned long flags;
-       int status;
+       int retval;
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        struct usb_serial *serial = port->serial;
        struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
        unsigned char *data = urb->transfer_buffer;
+       int status = urb->status;
 
-       switch (urb->status) {
+       switch (status) {
        case 0:
                /* success */
                break;
@@ -1348,11 +1351,11 @@ static void garmin_read_int_callback (struct urb *urb)
        case -ESHUTDOWN:
                /* this urb is terminated, clean up */
                dbg("%s - urb shutting down with status: %d",
-                       __FUNCTION__, urb->status);
+                       __FUNCTION__, status);
                return;
        default:
                dbg("%s - nonzero urb status received: %d",
-                       __FUNCTION__, urb->status);
+                       __FUNCTION__, status);
                return;
        }
 
@@ -1374,11 +1377,11 @@ static void garmin_read_int_callback (struct urb *urb)
                                        port->read_urb->transfer_buffer,
                                        port->read_urb->transfer_buffer_length,
                                        garmin_read_bulk_callback, port);
-                       status = usb_submit_urb(port->read_urb, GFP_ATOMIC);
-                       if (status) {
+                       retval = usb_submit_urb(port->read_urb, GFP_ATOMIC);
+                       if (retval) {
                                dev_err(&port->dev,
                                        "%s - failed submitting read urb, error %d\n",
-                               __FUNCTION__, status);
+                               __FUNCTION__, retval);
                        } else {
                                spin_lock_irqsave(&garmin_data_p->lock, flags);
                                garmin_data_p->flags |= FLAGS_BULK_IN_ACTIVE;
@@ -1422,11 +1425,11 @@ static void garmin_read_int_callback (struct urb *urb)
        }
 
        port->interrupt_in_urb->dev = port->serial->dev;
-       status = usb_submit_urb (urb, GFP_ATOMIC);
-       if (status)
+       retval = usb_submit_urb (urb, GFP_ATOMIC);
+       if (retval)
                dev_err(&urb->dev->dev,
                        "%s - Error %d submitting interrupt urb\n",
-                       __FUNCTION__, status);
+                       __FUNCTION__, retval);
 }
 
 
index 4f8282ad77208b66e4c406f826100cb300b5247a..88a2c7dce335f9b1cde151ae457bf1d55054132d 100644 (file)
@@ -69,6 +69,7 @@ struct usb_serial_driver usb_serial_generic_device = {
        .shutdown =             usb_serial_generic_shutdown,
        .throttle =             usb_serial_generic_throttle,
        .unthrottle =           usb_serial_generic_unthrottle,
+       .resume =               usb_serial_generic_resume,
 };
 
 static int generic_probe(struct usb_interface *interface,
@@ -169,6 +170,23 @@ static void generic_cleanup (struct usb_serial_port *port)
        }
 }
 
+int usb_serial_generic_resume(struct usb_serial *serial)
+{
+       struct usb_serial_port *port;
+       int i, c = 0, r;
+
+       for (i = 0; i < serial->num_ports; i++) {
+               port = serial->port[i];
+               if (port->open_count && port->read_urb) {
+                       r = usb_submit_urb(port->read_urb, GFP_NOIO);
+                       if (r < 0)
+                               c++;
+               }
+       }
+
+       return c ? -EIO : 0;
+}
+
 void usb_serial_generic_close (struct usb_serial_port *port, struct file * filp)
 {
        dbg("%s - port %d", __FUNCTION__, port->number);
@@ -263,79 +281,82 @@ int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port)
        return (chars);
 }
 
-/* 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 resubmit_read_urb(struct usb_serial_port *port, gfp_t mem_flags)
 {
-       struct usb_serial *serial = port->serial;
        struct urb *urb = port->read_urb;
-       struct tty_struct *tty = port->tty;
+       struct usb_serial *serial = port->serial;
        int result;
 
-       /* Push data to tty */
-       if (tty && urb->actual_length) {
-               tty_buffer_request_room(tty, urb->actual_length);
-               tty_insert_flip_string(tty, urb->transfer_buffer, urb->actual_length);
-               tty_flip_buffer_push(tty); /* is this allowed from an URB callback ? */
-       }
-
        /* Continue reading from device */
-       usb_fill_bulk_urb (port->read_urb, serial->dev,
+       usb_fill_bulk_urb (urb, serial->dev,
                           usb_rcvbulkpipe (serial->dev,
                                            port->bulk_in_endpointAddress),
-                          port->read_urb->transfer_buffer,
-                          port->read_urb->transfer_buffer_length,
+                          urb->transfer_buffer,
+                          urb->transfer_buffer_length,
                           ((serial->type->read_bulk_callback) ? 
                             serial->type->read_bulk_callback : 
                             usb_serial_generic_read_bulk_callback), port);
-       result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
+       result = usb_submit_urb(urb, mem_flags);
        if (result)
                dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result);
 }
 
+/* Push data to tty layer and resubmit the bulk read URB */
+static void flush_and_resubmit_read_urb (struct usb_serial_port *port)
+{
+       struct urb *urb = port->read_urb;
+       struct tty_struct *tty = port->tty;
+       int room;
+
+       /* Push data to tty */
+       if (tty && urb->actual_length) {
+               room = tty_buffer_request_room(tty, urb->actual_length);
+               if (room) {
+                       tty_insert_flip_string(tty, urb->transfer_buffer, room);
+                       tty_flip_buffer_push(tty); /* is this allowed from an URB callback ? */
+               }
+       }
+
+       resubmit_read_urb(port, GFP_ATOMIC);
+}
+
 void usb_serial_generic_read_bulk_callback (struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        unsigned char *data = urb->transfer_buffer;
-       int is_throttled;
-       unsigned long flags;
+       int status = urb->status;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
-       if (urb->status) {
-               dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status);
+       if (unlikely(status != 0)) {
+               dbg("%s - nonzero read bulk status received: %d",
+                   __FUNCTION__, status);
                return;
        }
 
        usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
 
        /* Throttle the device if requested by tty */
-       if (urb->actual_length) {
-               spin_lock_irqsave(&port->lock, flags);
-               is_throttled = port->throttled = port->throttle_req;
-               spin_unlock_irqrestore(&port->lock, flags);
-               if (is_throttled) {
-                       /* Let the received data linger in the read URB;
-                        * usb_serial_generic_unthrottle() will pick it
-                        * up later. */
-                       dbg("%s - throttling device", __FUNCTION__);
-                       return;
-               }
-       }
-
-       /* Handle data and continue reading from device */
-       flush_and_resubmit_read_urb(port);
+       spin_lock(&port->lock);
+       if (!(port->throttled = port->throttle_req))
+               /* Handle data and continue reading from device */
+               flush_and_resubmit_read_urb(port);
+       spin_unlock(&port->lock);
 }
 EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback);
 
 void usb_serial_generic_write_bulk_callback (struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+       int status = urb->status;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
        port->write_urb_busy = 0;
-       if (urb->status) {
-               dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
+       if (status) {
+               dbg("%s - nonzero write bulk status received: %d",
+                   __FUNCTION__, status);
                return;
        }
 
@@ -370,8 +391,8 @@ void usb_serial_generic_unthrottle (struct usb_serial_port *port)
        spin_unlock_irqrestore(&port->lock, flags);
 
        if (was_throttled) {
-               /* Handle pending data and resume reading from device */
-               flush_and_resubmit_read_urb(port);
+               /* Resume reading from device */
+               resubmit_read_urb(port, GFP_KERNEL);
        }
 }
 
index 056e1923c4de16134bb15b96c9f23e3c694809f6..dd42f57089ffea3a97ee86357113079d00a972a9 100644 (file)
@@ -599,10 +599,11 @@ static void edge_interrupt_callback (struct urb *urb)
        int txCredits;
        int portNumber;
        int result;
+       int status = urb->status;
 
        dbg("%s", __FUNCTION__);
 
-       switch (urb->status) {
+       switch (status) {
        case 0:
                /* success */
                break;
@@ -610,10 +611,12 @@ static void edge_interrupt_callback (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",
+                   __FUNCTION__, status);
                return;
        default:
-               dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
+               dbg("%s - nonzero urb status received: %d",
+                   __FUNCTION__, status);
                goto exit;
        }
 
@@ -688,13 +691,15 @@ static void edge_bulk_in_callback (struct urb *urb)
 {
        struct edgeport_serial  *edge_serial = (struct edgeport_serial *)urb->context;
        unsigned char           *data = urb->transfer_buffer;
-       int                     status;
+       int                     retval;
        __u16                   raw_data_length;
+       int status = urb->status;
 
        dbg("%s", __FUNCTION__);
 
-       if (urb->status) {
-               dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status);
+       if (status) {
+               dbg("%s - nonzero read bulk status received: %d",
+                   __FUNCTION__, status);
                edge_serial->read_in_progress = false;
                return;
        }
@@ -722,9 +727,11 @@ static void edge_bulk_in_callback (struct urb *urb)
        if (edge_serial->rxBytesAvail > 0) {
                dbg("%s - posting a read", __FUNCTION__);
                edge_serial->read_urb->dev = edge_serial->serial->dev;
-               status = usb_submit_urb(edge_serial->read_urb, GFP_ATOMIC);
-               if (status) {
-                       dev_err(&urb->dev->dev, "%s - usb_submit_urb(read bulk) failed, status = %d\n", __FUNCTION__, status);
+               retval = usb_submit_urb(edge_serial->read_urb, GFP_ATOMIC);
+               if (retval) {
+                       dev_err(&urb->dev->dev,
+                               "%s - usb_submit_urb(read bulk) failed, "
+                               "retval = %d\n", __FUNCTION__, retval);
                        edge_serial->read_in_progress = false;
                }
        } else {
@@ -744,11 +751,13 @@ static void edge_bulk_out_data_callback (struct urb *urb)
 {
        struct edgeport_port *edge_port = (struct edgeport_port *)urb->context;
        struct tty_struct *tty;
+       int status = urb->status;
 
        dbg("%s", __FUNCTION__);
 
-       if (urb->status) {
-               dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
+       if (status) {
+               dbg("%s - nonzero write bulk status received: %d",
+                   __FUNCTION__, status);
        }
 
        tty = edge_port->port->tty;
@@ -1504,15 +1513,6 @@ static void edge_set_termios (struct usb_serial_port *port, struct ktermios *old
        }
 
        cflag = tty->termios->c_cflag;
-       /* check that they really want us to change something */
-       if (old_termios) {
-               if (cflag == old_termios->c_cflag &&
-                   tty->termios->c_iflag == old_termios->c_iflag) {
-                       dbg("%s - nothing to change", __FUNCTION__);
-                       return;
-               }
-       }
-
        dbg("%s - clfag %08x iflag %08x", __FUNCTION__, 
            tty->termios->c_cflag, tty->termios->c_iflag);
        if (old_termios) {
index 93b56d68a27b9c009edfefdbc8b82955399eee57..4496b068c50f4597da1897240508f18b5a6c9008 100644 (file)
@@ -5,7 +5,7 @@
 //**************************************************************
 
 
-static int IMAGE_SIZE = 12749;
+static int IMAGE_SIZE = 12938;
 
 struct EDGE_FIRMWARE_VERSION_INFO
 {
@@ -16,7 +16,7 @@ struct EDGE_FIRMWARE_VERSION_INFO
 
 static struct EDGE_FIRMWARE_VERSION_INFO IMAGE_VERSION_NAME =
 {
-       4, 10, 0                // Major, Minor, Build
+       4, 80, 0                // Major, Minor, Build
 
 };
 
@@ -27,16 +27,16 @@ static unsigned char IMAGE_ARRAY_NAME[] =
 //      WORD    Length;
 //      BYTE    CheckSum;
 //  };
-0xca, 0x31, 
-0xa8, 
+0x87, 0x32,
+0x9a,
 
-0x02, 0x26, 0xfe, 0x02, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x1e, 0x00, 0x00, 
+0x02, 0x27, 0xbf, 0x02, 0x21, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x1e, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x1a, 0x85, 0x3f, 
 0x8c, 0x85, 0x40, 0x8a, 0xc0, 0xe0, 0xc0, 0xd0, 0xc0, 0xf0, 0xc0, 0x82, 0xc0, 0x83, 0xc0, 0x00, 
 0xc0, 0x01, 0xc0, 0x02, 0xc0, 0x03, 0xc0, 0x04, 0xc0, 0x05, 0xc0, 0x06, 0xc0, 0x07, 0xe5, 0x3e, 
 0x24, 0x08, 0xf8, 0xe6, 0x60, 0x2b, 0xe5, 0x3e, 0x24, 0x10, 0xf8, 0xa6, 0x81, 0xe5, 0x3e, 0x75, 
 0xf0, 0x21, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x34, 0xf8, 0xf5, 0x83, 0x78, 0x8c, 0xe5, 0x81, 
-0x04, 0xc3, 0x98, 0xf9, 0x94, 0x22, 0x40, 0x03, 0x02, 0x11, 0x94, 0xe6, 0xf0, 0x08, 0xa3, 0xd9, 
+0x04, 0xc3, 0x98, 0xf9, 0x94, 0x22, 0x40, 0x03, 0x02, 0x11, 0xdc, 0xe6, 0xf0, 0x08, 0xa3, 0xd9,
 0xfa, 0x74, 0x08, 0x25, 0x3e, 0xf8, 0x05, 0x3e, 0x08, 0xe6, 0x54, 0x80, 0x70, 0x0c, 0xe5, 0x3e, 
 0xb4, 0x07, 0xf3, 0x78, 0x08, 0x75, 0x3e, 0x00, 0x80, 0xef, 0xe5, 0x3e, 0x24, 0x10, 0xf8, 0x86, 
 0x81, 0xe5, 0x3e, 0x75, 0xf0, 0x21, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x34, 0xf8, 0xf5, 0x83, 
@@ -49,387 +49,398 @@ static unsigned char IMAGE_ARRAY_NAME[] =
 0xc9, 0xf0, 0x69, 0x60, 0x02, 0x7e, 0x04, 0xa3, 0xe0, 0xca, 0xf0, 0x6a, 0x60, 0x02, 0x7e, 0x04, 
 0xa3, 0xe0, 0xcb, 0xf0, 0x6b, 0x60, 0x02, 0x7e, 0x04, 0x22, 0xc0, 0xe0, 0xc0, 0xd0, 0xc0, 0xf0, 
 0xc0, 0x82, 0xc0, 0x83, 0xc0, 0x00, 0xc0, 0x01, 0xc0, 0x02, 0xc0, 0x03, 0xc0, 0x04, 0xc0, 0x05, 
-0xc0, 0x06, 0xc0, 0x07, 0x90, 0xff, 0x93, 0x74, 0x01, 0xf0, 0xe5, 0x81, 0x94, 0xfd, 0x40, 0x03, 
-0x02, 0x11, 0x94, 0x85, 0x41, 0x8d, 0x85, 0x42, 0x8b, 0x74, 0xaf, 0xf5, 0x82, 0x74, 0xfa, 0xf5, 
-0x83, 0xe0, 0xb4, 0x01, 0x1b, 0xc0, 0x82, 0xc0, 0x83, 0x90, 0xff, 0x4a, 0xe0, 0x30, 0xe7, 0x2c, 
-0x90, 0xff, 0x4e, 0xe0, 0x30, 0xe7, 0x25, 0xd0, 0x83, 0xd0, 0x82, 0x74, 0x02, 0xf0, 0x80, 0x20, 
-0xb4, 0x02, 0x1d, 0xc0, 0x82, 0xc0, 0x83, 0x90, 0xff, 0x7a, 0xe0, 0x30, 0xe7, 0x05, 0x12, 0x27, 
-0x8d, 0x80, 0x09, 0xd0, 0x83, 0xd0, 0x82, 0x74, 0x03, 0xf0, 0x80, 0x04, 0xd0, 0x83, 0xd0, 0x82, 
-0xa3, 0xe0, 0xb4, 0x01, 0x1b, 0xc0, 0x82, 0xc0, 0x83, 0x90, 0xff, 0x52, 0xe0, 0x30, 0xe7, 0x2c, 
-0x90, 0xff, 0x56, 0xe0, 0x30, 0xe7, 0x25, 0xd0, 0x83, 0xd0, 0x82, 0x74, 0x02, 0xf0, 0x80, 0x25, 
-0xb4, 0x02, 0x22, 0xc0, 0x82, 0xc0, 0x83, 0x90, 0xff, 0x7a, 0xe0, 0x30, 0xe7, 0x05, 0x12, 0x27, 
-0x8d, 0x80, 0x09, 0xd0, 0x83, 0xd0, 0x82, 0x74, 0x03, 0xf0, 0x80, 0x09, 0xd0, 0x83, 0xd0, 0x82, 
-0x80, 0x03, 0x02, 0x02, 0x62, 0x74, 0x15, 0xf5, 0x82, 0x74, 0xf9, 0xf5, 0x83, 0xe0, 0x20, 0x04, 
-0xf1, 0x20, 0x02, 0x03, 0x30, 0x01, 0xeb, 0x74, 0x18, 0xf5, 0x82, 0x74, 0xf9, 0xf5, 0x83, 0xe0, 
-0x14, 0xfc, 0xf0, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0x64, 0x04, 0x70, 0x0f, 0xec, 0x70, 0x62, 
-0x7e, 0x01, 0x12, 0x00, 0xc9, 0x7c, 0x0a, 0x7d, 0xfa, 0x02, 0x02, 0x33, 0x12, 0x00, 0xc9, 0xee, 
-0x64, 0x04, 0x60, 0x1d, 0xec, 0x70, 0x4b, 0x7c, 0x0a, 0xed, 0x14, 0xfd, 0x70, 0x15, 0xee, 0x64, 
-0x02, 0x60, 0x07, 0x7e, 0x02, 0x7d, 0x32, 0x02, 0x02, 0x33, 0x7e, 0x01, 0x7d, 0xfa, 0x02, 0x02, 
-0x33, 0x7c, 0x0a, 0x74, 0x18, 0xf5, 0x82, 0x74, 0xf9, 0xf5, 0x83, 0xec, 0xf0, 0xa3, 0xed, 0xf0, 
-0xa3, 0xee, 0xf0, 0x14, 0x60, 0x18, 0x20, 0xe1, 0x0f, 0x20, 0x01, 0x06, 0xd2, 0xb1, 0xc2, 0xb0, 
-0x80, 0x10, 0xc2, 0xb1, 0xd2, 0xb0, 0x80, 0x0a, 0xc2, 0xb1, 0xc2, 0xb0, 0x80, 0x04, 0xd2, 0xb0, 
-0xd2, 0xb1, 0x78, 0x19, 0x79, 0x09, 0x7a, 0x07, 0xe7, 0x70, 0x04, 0xa6, 0x00, 0x80, 0x0b, 0xe6, 
-0x60, 0x08, 0x16, 0xe6, 0x70, 0x04, 0xe7, 0x44, 0x80, 0xf7, 0x08, 0x09, 0xda, 0xea, 0xe5, 0x3d, 
-0x60, 0x13, 0x14, 0xf5, 0x3d, 0x70, 0x0e, 0xe5, 0x3e, 0x24, 0x08, 0xf8, 0x76, 0x00, 0x12, 0x11, 
-0x0f, 0xd2, 0x8c, 0xd2, 0x8d, 0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x05, 0xd0, 0x04, 0xd0, 0x03, 0xd0, 
-0x02, 0xd0, 0x01, 0xd0, 0x00, 0xd0, 0x83, 0xd0, 0x82, 0xd0, 0xf0, 0xd0, 0xd0, 0xd0, 0xe0, 0x32, 
-0x90, 0xff, 0x04, 0xe0, 0x90, 0xfa, 0xb6, 0xf0, 0x90, 0xff, 0x06, 0xe0, 0xfc, 0xa3, 0xe0, 0xfa, 
-0xec, 0xff, 0xea, 0xfe, 0xef, 0xc3, 0x94, 0x08, 0xee, 0x94, 0x01, 0x50, 0x02, 0x80, 0x04, 0x7e, 
-0x01, 0x7f, 0x08, 0x8e, 0x3b, 0x8f, 0x3c, 0x90, 0xff, 0x02, 0xe0, 0xfc, 0xa3, 0xe0, 0xfa, 0xec, 
-0xff, 0xea, 0x90, 0xfa, 0xba, 0xf0, 0xef, 0xa3, 0xf0, 0x12, 0x1c, 0x30, 0xe4, 0xf5, 0x4d, 0xe5, 
-0x4d, 0xc3, 0x94, 0x02, 0x50, 0x0f, 0x12, 0x1c, 0x11, 0xe4, 0x12, 0x1a, 0x38, 0x05, 0x4d, 0x04, 
-0x12, 0x1c, 0x02, 0x80, 0xea, 0x12, 0x1c, 0x30, 0x90, 0xff, 0x00, 0xe0, 0xff, 0x54, 0x60, 0x24, 
-0xc0, 0x70, 0x03, 0x02, 0x08, 0xc5, 0x24, 0x40, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x90, 0xfa, 0xb6, 
-0xe0, 0xfe, 0x54, 0x0f, 0xf5, 0x4d, 0xee, 0x30, 0xe7, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x0a, 
-0x90, 0xff, 0x01, 0xe0, 0x12, 0x1b, 0x4c, 0x03, 0x56, 0x00, 0x04, 0x29, 0x01, 0x05, 0x3c, 0x03, 
-0x06, 0x03, 0x05, 0x06, 0x45, 0x06, 0x07, 0xa7, 0x08, 0x07, 0xef, 0x09, 0x08, 0x4b, 0x0a, 0x08, 
-0x8b, 0x0b, 0x00, 0x00, 0x0f, 0x26, 0xe5, 0x35, 0x20, 0xe7, 0x03, 0x02, 0x0f, 0x26, 0x90, 0xfa, 
-0xba, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x60, 0x03, 0x02, 0x0f, 0x26, 0xe5, 0x3c, 0x64, 0x02, 0x45, 
-0x3b, 0x60, 0x03, 0x02, 0x0f, 0x26, 0xef, 0x54, 0x1f, 0x14, 0x60, 0x2b, 0x14, 0x60, 0x47, 0x24, 
-0x02, 0x60, 0x03, 0x02, 0x0f, 0x26, 0xee, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x12, 0x1c, 0x11, 0x74, 
-0x01, 0x12, 0x1a, 0x38, 0x78, 0x67, 0xe6, 0x30, 0xe0, 0x08, 0x12, 0x1c, 0x11, 0x74, 0x02, 0x12, 
-0x1a, 0x38, 0x7f, 0x02, 0x02, 0x31, 0xb1, 0xe5, 0x35, 0x20, 0xe1, 0x09, 0x90, 0xfa, 0xb6, 0xe0, 
-0x60, 0x03, 0x02, 0x0f, 0x26, 0x90, 0xfa, 0xb6, 0xe0, 0xd3, 0x94, 0x01, 0x40, 0x03, 0x02, 0x0f, 
-0x26, 0x7f, 0x02, 0x02, 0x31, 0xb1, 0xe5, 0x35, 0x20, 0xe1, 0x0e, 0x90, 0xfa, 0xb6, 0xe0, 0xff, 
-0x60, 0x07, 0x64, 0x80, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x12, 0x0f, 0xb2, 0x40, 0x03, 0x02, 0x0f, 
-0x26, 0xe5, 0x4d, 0x70, 0x19, 0x30, 0x0a, 0x0b, 0x90, 0xff, 0x80, 0x12, 0x1c, 0x0e, 0x12, 0x1a, 
-0x38, 0x80, 0x24, 0x90, 0xff, 0x82, 0x12, 0x1c, 0x0e, 0x12, 0x1a, 0x38, 0x80, 0x19, 0x15, 0x4d, 
-0x30, 0x0a, 0x0b, 0x12, 0x1c, 0xa5, 0x12, 0x1c, 0x0c, 0x12, 0x1a, 0x38, 0x80, 0x09, 0x12, 0x1c, 
-0xb3, 0x12, 0x1c, 0x0c, 0x12, 0x1a, 0x38, 0x12, 0x1c, 0x11, 0x12, 0x19, 0xf2, 0x60, 0x05, 0x74, 
-0x01, 0x12, 0x1a, 0x38, 0x7f, 0x02, 0x02, 0x31, 0xb1, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02, 0x0f, 
-0x26, 0xe5, 0x3c, 0x45, 0x3b, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x12, 0x1c, 0xc9, 0x14, 0x60, 0x2d, 
-0x14, 0x60, 0x59, 0x24, 0x02, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x90, 0xfa, 0xba, 0xe0, 0x70, 0x04, 
-0xa3, 0xe0, 0x64, 0x01, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x90, 0xfa, 0xb6, 0xe0, 0x60, 0x03, 0x02, 
-0x0f, 0x26, 0x78, 0x67, 0xe6, 0x54, 0xfe, 0xf6, 0xe4, 0xff, 0x02, 0x31, 0xb1, 0xe5, 0x35, 0x20, 
-0xe1, 0x06, 0x20, 0xe0, 0x03, 0x02, 0x0f, 0x26, 0xe5, 0x35, 0x30, 0xe0, 0x09, 0x90, 0xfa, 0xb6, 
-0xe0, 0x60, 0x03, 0x02, 0x0f, 0x26, 0xe5, 0x35, 0x30, 0xe1, 0x0c, 0x90, 0xfa, 0xb6, 0xe0, 0xd3, 
-0x94, 0x01, 0x40, 0x03, 0x02, 0x0f, 0x26, 0xe4, 0xff, 0x02, 0x31, 0xb1, 0x90, 0xfa, 0xba, 0xe0, 
-0x70, 0x02, 0xa3, 0xe0, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x12, 0x0f, 0xb2, 0x40, 0x03, 0x02, 0x0f, 
-0x26, 0xe5, 0x35, 0x20, 0xe1, 0x06, 0x20, 0xe0, 0x03, 0x02, 0x0f, 0x26, 0xe5, 0x35, 0x30, 0xe0, 
-0x07, 0xe5, 0x4d, 0x60, 0x03, 0x02, 0x0f, 0x26, 0xe5, 0x4d, 0x70, 0x0f, 0x90, 0xff, 0x82, 0xe0, 
-0x54, 0xf7, 0xf0, 0x90, 0xff, 0x80, 0xe0, 0x54, 0xf7, 0xf0, 0x22, 0xe5, 0x4d, 0x24, 0xfe, 0x60, 
-0x20, 0x24, 0xfb, 0x60, 0x34, 0x24, 0x06, 0x70, 0x35, 0x30, 0x0a, 0x0c, 0xa2, 0x0a, 0xe4, 0x33, 
-0xfd, 0x7f, 0x03, 0x12, 0x2d, 0xa8, 0x80, 0x26, 0xe4, 0xfd, 0x7f, 0x03, 0x12, 0x2d, 0xa8, 0x80, 
-0x1d, 0x30, 0x0a, 0x0c, 0xa2, 0x0a, 0xe4, 0x33, 0xfd, 0x7f, 0x04, 0x12, 0x2d, 0xa8, 0x80, 0x0e, 
-0xe4, 0xfd, 0x7f, 0x04, 0x12, 0x2d, 0xa8, 0x80, 0x05, 0x7f, 0x87, 0x12, 0x31, 0x32, 0x15, 0x4d, 
-0x30, 0x0a, 0x0b, 0x12, 0x1c, 0xa5, 0xf5, 0x83, 0xe0, 0x54, 0xf7, 0xf0, 0x80, 0x09, 0x12, 0x1c, 
-0xb3, 0xf5, 0x83, 0xe0, 0x54, 0xf7, 0xf0, 0xe4, 0xff, 0x02, 0x31, 0xb1, 0xe5, 0x35, 0x30, 0xe7, 
-0x03, 0x02, 0x0f, 0x26, 0xe5, 0x3c, 0x45, 0x3b, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x12, 0x1c, 0xc9, 
-0x14, 0x60, 0x2d, 0x14, 0x60, 0x55, 0x24, 0x02, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x90, 0xfa, 0xba, 
-0xe0, 0x70, 0x04, 0xa3, 0xe0, 0x64, 0x01, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x90, 0xfa, 0xb6, 0xe0, 
-0x60, 0x03, 0x02, 0x0f, 0x26, 0x78, 0x67, 0xe6, 0x44, 0x01, 0xf6, 0xe4, 0xff, 0x02, 0x31, 0xb1, 
-0xe5, 0x35, 0x20, 0xe1, 0x06, 0x20, 0xe0, 0x03, 0x02, 0x0f, 0x26, 0xe5, 0x35, 0x30, 0xe0, 0x07, 
-0xe5, 0x4d, 0x60, 0x03, 0x02, 0x0f, 0x26, 0xe5, 0x35, 0x30, 0xe1, 0x0a, 0xe5, 0x4d, 0xd3, 0x94, 
-0x01, 0x40, 0x03, 0x02, 0x0f, 0x26, 0xe4, 0xff, 0x02, 0x31, 0xb1, 0x90, 0xfa, 0xba, 0xe0, 0x70, 
-0x02, 0xa3, 0xe0, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x90, 0xfa, 0xb6, 0xe0, 0xff, 0x12, 0x31, 0x82, 
-0x40, 0x03, 0x02, 0x0f, 0x26, 0xe5, 0x35, 0x20, 0xe1, 0x06, 0x20, 0xe0, 0x03, 0x02, 0x0f, 0x26, 
-0xe5, 0x4d, 0x70, 0x09, 0x30, 0x0a, 0x03, 0x02, 0x1d, 0x64, 0x02, 0x1d, 0x2f, 0xe5, 0x35, 0x20, 
-0xe1, 0x03, 0x02, 0x0f, 0x26, 0x15, 0x4d, 0x30, 0x0a, 0x0b, 0x12, 0x1c, 0xa5, 0xf5, 0x83, 0xe0, 
-0x44, 0x08, 0xf0, 0x80, 0x09, 0x12, 0x1c, 0xb3, 0xf5, 0x83, 0xe0, 0x44, 0x08, 0xf0, 0xe4, 0xff, 
-0x02, 0x31, 0xb1, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02, 0x0f, 0x26, 0xe5, 0x3c, 0x45, 0x3b, 0x60, 
-0x03, 0x02, 0x0f, 0x26, 0x90, 0xfa, 0xb6, 0xe0, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x12, 0x1c, 0xc9, 
-0x60, 0x03, 0x02, 0x0f, 0x26, 0xe5, 0x35, 0x30, 0xe1, 0x03, 0x02, 0x0f, 0x26, 0x90, 0xfa, 0xbb, 
-0xe0, 0x90, 0xff, 0xff, 0xf0, 0xe0, 0x60, 0x05, 0x43, 0x35, 0x01, 0x80, 0x03, 0x53, 0x35, 0xfe, 
-0xe4, 0xff, 0x02, 0x31, 0xb1, 0xe5, 0x35, 0x20, 0xe7, 0x03, 0x02, 0x0f, 0x26, 0xe5, 0x3c, 0x45, 
-0x3b, 0x70, 0x03, 0x02, 0x0f, 0x26, 0x12, 0x1c, 0xc9, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x90, 0xfa, 
-0xba, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xec, 0x24, 0xfe, 0x60, 0x3a, 0x14, 0x60, 0x75, 0x24, 0x02, 
-0x60, 0x03, 0x02, 0x0f, 0x26, 0xed, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x12, 0x1c, 0x30, 0x12, 0x1d, 
-0x5d, 0x7d, 0x03, 0x12, 0x0f, 0x6d, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x12, 0x0f, 0x2a, 0x90, 0xfa, 
-0xb3, 0xe0, 0xfd, 0xa3, 0x12, 0x1c, 0x7b, 0x12, 0x0f, 0x89, 0x50, 0x02, 0x80, 0x04, 0xae, 0x3b, 
-0xaf, 0x3c, 0x02, 0x0f, 0xba, 0x12, 0x1c, 0x30, 0x90, 0xf9, 0x15, 0xe0, 0x30, 0xe4, 0x0d, 0x12, 
-0x1d, 0x5d, 0x7d, 0x14, 0x12, 0x0f, 0x6d, 0x60, 0x10, 0x02, 0x0f, 0x26, 0x12, 0x1d, 0x5d, 0x7d, 
-0x04, 0x12, 0x0f, 0xc1, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x12, 0x0f, 0x2a, 0x90, 0xfa, 0xb3, 0xe0, 
-0xfd, 0xa3, 0x12, 0x1c, 0x7b, 0x12, 0x0f, 0x89, 0x50, 0x02, 0x80, 0x04, 0xae, 0x3b, 0xaf, 0x3c, 
-0x02, 0x0f, 0xba, 0x12, 0x1d, 0x5d, 0x7d, 0x05, 0x12, 0x0f, 0xc1, 0x60, 0x03, 0x02, 0x0f, 0x26, 
-0x7b, 0x01, 0x7a, 0xfa, 0x79, 0xb3, 0x12, 0x1c, 0x78, 0x7d, 0x01, 0x12, 0x25, 0xd7, 0x90, 0xfa, 
-0xb4, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0x1a, 0x6c, 0x90, 0xfa, 0xbb, 0xe0, 0x90, 0xfa, 0xb2, 0xf0, 
-0xe4, 0xf5, 0x4c, 0x90, 0xfa, 0xb2, 0xe0, 0xff, 0xe5, 0x4c, 0xc3, 0x9f, 0x50, 0x24, 0x12, 0x1c, 
-0x72, 0x12, 0x0f, 0xcc, 0xff, 0xfd, 0x90, 0xfa, 0xb4, 0xe4, 0x8d, 0xf0, 0x12, 0x1a, 0x6c, 0x90, 
-0xfa, 0xb3, 0xe0, 0xc3, 0x9f, 0xf0, 0xd3, 0x94, 0x00, 0x50, 0x03, 0x02, 0x0f, 0x26, 0x05, 0x4c, 
-0x80, 0xd1, 0x12, 0x1c, 0x72, 0x12, 0x0f, 0xcc, 0x24, 0xfe, 0xff, 0x90, 0xfa, 0xb3, 0xf0, 0xfd, 
-0xa3, 0xe4, 0x75, 0xf0, 0x02, 0x12, 0x1a, 0x6c, 0x7a, 0xf9, 0x79, 0x6f, 0x7b, 0x01, 0x8b, 0x36, 
-0x8a, 0x37, 0x89, 0x38, 0xe9, 0x24, 0x02, 0xf9, 0xe4, 0x3a, 0xfa, 0x12, 0x1c, 0x78, 0x12, 0x25, 
-0xd7, 0x8f, 0x4c, 0x05, 0x4c, 0x05, 0x4c, 0x12, 0x1c, 0x11, 0xe5, 0x4c, 0x12, 0x1a, 0x38, 0x12, 
-0x1c, 0x11, 0x90, 0x00, 0x01, 0x74, 0x03, 0x12, 0x1a, 0x4a, 0xaf, 0x4c, 0x7e, 0x00, 0xc3, 0xef, 
-0x95, 0x3c, 0xee, 0x95, 0x3b, 0x50, 0x02, 0x80, 0x04, 0xae, 0x3b, 0xaf, 0x3c, 0x8e, 0x39, 0x8f, 
-0x3a, 0x02, 0x2c, 0x07, 0x02, 0x0f, 0x26, 0xe5, 0x35, 0x20, 0xe7, 0x03, 0x02, 0x0f, 0x26, 0xe5, 
-0x3c, 0x64, 0x01, 0x45, 0x3b, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x90, 0xfa, 0xb6, 0xe0, 0x60, 0x03, 
-0x02, 0x0f, 0x26, 0x90, 0xfa, 0xba, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x60, 0x03, 0x02, 0x0f, 0x26, 
-0x12, 0x1c, 0xc9, 0x60, 0x03, 0x02, 0x0f, 0x26, 0xe5, 0x35, 0x20, 0xe0, 0x06, 0x20, 0xe1, 0x03, 
-0x02, 0x0f, 0x26, 0x75, 0x36, 0x00, 0x75, 0x37, 0x00, 0x75, 0x38, 0x32, 0x02, 0x0f, 0xa9, 0xe5, 
-0x35, 0x30, 0xe7, 0x03, 0x02, 0x0f, 0x26, 0xe5, 0x3c, 0x45, 0x3b, 0x60, 0x03, 0x02, 0x0f, 0x26, 
-0x90, 0xfa, 0xb6, 0xe0, 0x60, 0x03, 0x02, 0x0f, 0x26, 0xd3, 0x90, 0xfa, 0xbb, 0xe0, 0x94, 0x01, 
-0x90, 0xfa, 0xba, 0xe0, 0x94, 0x00, 0x40, 0x03, 0x02, 0x0f, 0x26, 0x12, 0x1c, 0xc9, 0x60, 0x03, 
-0x02, 0x0f, 0x26, 0xe5, 0x35, 0x20, 0xe0, 0x06, 0x20, 0xe1, 0x03, 0x02, 0x0f, 0x26, 0x90, 0xfa, 
-0xbb, 0xe0, 0xf5, 0x32, 0xe5, 0x32, 0x70, 0x08, 0x43, 0x35, 0x01, 0x53, 0x35, 0xfd, 0x80, 0x06, 
-0x53, 0x35, 0xfe, 0x43, 0x35, 0x02, 0xe4, 0xff, 0x02, 0x31, 0xb1, 0xe5, 0x35, 0x20, 0xe7, 0x03, 
-0x02, 0x0f, 0x26, 0xe5, 0x3c, 0x64, 0x01, 0x45, 0x3b, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x90, 0xfa, 
-0xb6, 0xe0, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x90, 0xfa, 0xba, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x60, 
-0x03, 0x02, 0x0f, 0x26, 0x12, 0x1c, 0xc9, 0x64, 0x01, 0x60, 0x03, 0x02, 0x0f, 0x26, 0xe5, 0x35, 
-0x20, 0xe1, 0x03, 0x02, 0x0f, 0x26, 0x7f, 0x01, 0x02, 0x31, 0xb1, 0xe5, 0x35, 0x30, 0xe7, 0x03, 
-0x02, 0x0f, 0x26, 0xe5, 0x3c, 0x45, 0x3b, 0x60, 0x03, 0x02, 0x0f, 0x26, 0xd3, 0x90, 0xfa, 0xbb, 
-0xe0, 0x94, 0x00, 0x90, 0xfa, 0xba, 0xe0, 0x94, 0x00, 0x40, 0x03, 0x02, 0x0f, 0x26, 0x12, 0x1c, 
-0xc9, 0x64, 0x01, 0x60, 0x03, 0x02, 0x0f, 0x26, 0xe5, 0x35, 0x20, 0xe1, 0x03, 0x02, 0x0f, 0x26, 
-0xe4, 0xff, 0x02, 0x31, 0xb1, 0x90, 0xff, 0x01, 0x12, 0x1d, 0x74, 0xef, 0x12, 0x1a, 0x38, 0x90, 
-0xfa, 0xb6, 0x12, 0x1d, 0x74, 0x90, 0x00, 0x01, 0xef, 0x12, 0x1a, 0x4a, 0x90, 0x00, 0x02, 0xe4, 
-0x12, 0x1a, 0x4a, 0x74, 0x03, 0x12, 0x1c, 0x02, 0x90, 0xfa, 0xba, 0xe0, 0xff, 0xa3, 0xe0, 0x85, 
-0x38, 0x82, 0x85, 0x37, 0x83, 0xcf, 0xf0, 0xa3, 0xef, 0xf0, 0x90, 0xff, 0x01, 0xe0, 0x12, 0x1b, 
-0x4c, 0x09, 0x4a, 0x02, 0x09, 0x6c, 0x04, 0x09, 0x8e, 0x05, 0x09, 0xba, 0x06, 0x09, 0xd8, 0x07, 
-0x09, 0xf6, 0x08, 0x0a, 0x14, 0x09, 0x0a, 0x32, 0x0b, 0x0a, 0xe7, 0x80, 0x0d, 0x6f, 0x81, 0x0d, 
-0xa0, 0x82, 0x0b, 0x2e, 0x83, 0x0b, 0x77, 0x84, 0x0b, 0x96, 0x85, 0x0b, 0xdb, 0x86, 0x0c, 0x26, 
-0x87, 0x0c, 0xb7, 0x88, 0x0d, 0x42, 0x89, 0x0a, 0x50, 0x92, 0x0a, 0x50, 0x93, 0x0e, 0x53, 0xc0, 
-0x0e, 0x7f, 0xc1, 0x0e, 0x90, 0xc2, 0x00, 0x00, 0x0f, 0x15, 0xe5, 0x35, 0x20, 0xe7, 0x05, 0x7f, 
-0x05, 0x02, 0x30, 0xec, 0x12, 0x1c, 0xc1, 0x60, 0x03, 0x04, 0x70, 0x09, 0xef, 0xfd, 0x7c, 0x00, 
-0x7f, 0x07, 0x02, 0x11, 0x16, 0xe4, 0xfd, 0x7f, 0x07, 0x02, 0x2f, 0x18, 0xe5, 0x35, 0x20, 0xe7, 
-0x05, 0x7f, 0x05, 0x02, 0x30, 0xec, 0x12, 0x1c, 0xc1, 0x60, 0x03, 0x04, 0x70, 0x09, 0xef, 0xfd, 
-0x7c, 0x00, 0x7f, 0x0c, 0x02, 0x11, 0x16, 0xe4, 0xfd, 0x7f, 0x07, 0x02, 0x2f, 0x18, 0xe5, 0x35, 
-0x30, 0xe7, 0x03, 0x02, 0x0f, 0x29, 0x12, 0x1d, 0x92, 0x50, 0x06, 0xe5, 0x3c, 0x45, 0x3b, 0x70, 
-0x05, 0x7f, 0x02, 0x02, 0x30, 0xec, 0x90, 0xfa, 0xb6, 0xe0, 0x24, 0xfe, 0x24, 0xfd, 0x50, 0x02, 
-0x80, 0x03, 0x02, 0x31, 0x6f, 0x7f, 0x07, 0x02, 0x30, 0xec, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02, 
-0x0f, 0x29, 0x12, 0x1c, 0xc1, 0x60, 0x03, 0x04, 0x70, 0x09, 0xef, 0xfd, 0x7c, 0x00, 0x7f, 0x08, 
-0x02, 0x11, 0x16, 0x7f, 0x07, 0x02, 0x30, 0xec, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02, 0x0f, 0x29, 
-0x12, 0x1c, 0xc1, 0x60, 0x03, 0x04, 0x70, 0x09, 0xef, 0xfd, 0x7c, 0x00, 0x7f, 0x09, 0x02, 0x11, 
-0x16, 0x7f, 0x07, 0x02, 0x30, 0xec, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02, 0x0f, 0x29, 0x12, 0x1c, 
-0xc1, 0x60, 0x03, 0x04, 0x70, 0x09, 0xef, 0xfd, 0x7c, 0x00, 0x7f, 0x0a, 0x02, 0x11, 0x16, 0x7f, 
-0x07, 0x02, 0x30, 0xec, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02, 0x0f, 0x29, 0x12, 0x1c, 0xc1, 0x60, 
-0x03, 0x04, 0x70, 0x09, 0xef, 0xfd, 0x7c, 0x00, 0x7f, 0x0b, 0x02, 0x11, 0x16, 0x7f, 0x07, 0x02, 
-0x30, 0xec, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02, 0x0f, 0x29, 0x12, 0x1c, 0xc1, 0x60, 0x03, 0x04, 
-0x70, 0x09, 0xef, 0xfd, 0x7c, 0x00, 0x7f, 0x0e, 0x02, 0x11, 0x16, 0x7f, 0x07, 0x02, 0x30, 0xec, 
-0xe5, 0x35, 0x30, 0xe7, 0x56, 0x12, 0x1c, 0xc9, 0x70, 0x4a, 0x90, 0xff, 0x02, 0xe0, 0xf5, 0x4c, 
-0xe5, 0x4c, 0xb4, 0x82, 0x05, 0x75, 0x4c, 0x61, 0x80, 0x12, 0xe5, 0x4c, 0xb4, 0x83, 0x05, 0x75, 
-0x4c, 0x62, 0x80, 0x08, 0xe5, 0x4c, 0xc4, 0x54, 0xf0, 0x04, 0xf5, 0x4c, 0x12, 0x1b, 0x72, 0x12, 
-0x1d, 0x8b, 0x12, 0x25, 0x39, 0x12, 0x1c, 0xd9, 0x12, 0x1a, 0x0b, 0x60, 0x05, 0x12, 0x31, 0xbd, 
-0x80, 0x06, 0x85, 0x33, 0x39, 0x85, 0x34, 0x3a, 0x75, 0x36, 0x01, 0x75, 0x37, 0xf9, 0x75, 0x38, 
-0x72, 0x02, 0x2c, 0x07, 0xe4, 0xfd, 0x7f, 0x05, 0x02, 0x2f, 0x18, 0x12, 0x1c, 0xc9, 0x60, 0x05, 
-0x7f, 0x05, 0x02, 0x30, 0xec, 0x12, 0x1d, 0x92, 0x40, 0x05, 0x7f, 0x03, 0x02, 0x30, 0xec, 0x90, 
-0xff, 0x02, 0xe0, 0xf5, 0x4c, 0xe5, 0x4c, 0xb4, 0x82, 0x05, 0x75, 0x4c, 0x61, 0x80, 0x12, 0xe5, 
-0x4c, 0xb4, 0x83, 0x05, 0x75, 0x4c, 0x62, 0x80, 0x08, 0xe5, 0x4c, 0xc4, 0x54, 0xf0, 0x04, 0xf5, 
-0x4c, 0x12, 0x1b, 0x72, 0x02, 0x31, 0x6f, 0x12, 0x1d, 0x9c, 0x12, 0x2a, 0x06, 0x12, 0x1c, 0x83, 
-0xe0, 0x54, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0xe0, 0x90, 0xfa, 0xb7, 0xf0, 0x78, 0x68, 0x12, 0x1b, 
-0x28, 0x90, 0x00, 0x02, 0x12, 0x1a, 0x0b, 0x30, 0xe7, 0xf2, 0x90, 0x00, 0x02, 0xe4, 0x12, 0x1a, 
-0x4a, 0x90, 0xfa, 0xb7, 0xe0, 0x44, 0x80, 0xff, 0xf0, 0x78, 0x7c, 0xe6, 0xfc, 0x08, 0xe6, 0x8c, 
-0x83, 0x12, 0x1c, 0x8b, 0xef, 0xf0, 0x12, 0x31, 0xc7, 0xe4, 0xff, 0x02, 0x30, 0xec, 0x90, 0xfa, 
-0xb6, 0xe0, 0x64, 0x01, 0x70, 0x1f, 0x90, 0xfa, 0xba, 0xe0, 0xff, 0x7e, 0x00, 0x70, 0x06, 0xa3, 
-0xe0, 0xf5, 0x90, 0x80, 0x2d, 0xc2, 0xaf, 0xef, 0xf4, 0x52, 0x90, 0x90, 0xfa, 0xbb, 0xe0, 0x42, 
-0x90, 0xd2, 0xaf, 0x80, 0x1d, 0x90, 0xfa, 0xba, 0xe0, 0xff, 0x7e, 0x00, 0x70, 0x06, 0xa3, 0xe0, 
-0xf5, 0xb0, 0x80, 0x0e, 0xc2, 0xaf, 0xef, 0xf4, 0x52, 0xb0, 0x90, 0xfa, 0xbb, 0xe0, 0x42, 0xb0, 
-0xd2, 0xaf, 0xe4, 0xff, 0x02, 0x30, 0xec, 0x12, 0x1c, 0x30, 0x90, 0xfa, 0xb6, 0xe0, 0xb4, 0x01, 
-0x0a, 0x12, 0x1c, 0x11, 0xe5, 0x90, 0x12, 0x1a, 0x38, 0x80, 0x08, 0x12, 0x1c, 0x11, 0xe5, 0xb0, 
-0x12, 0x1a, 0x38, 0x02, 0x0f, 0xa9, 0x90, 0xfa, 0xb6, 0xe0, 0xff, 0x24, 0x12, 0x12, 0x1c, 0x41, 
-0x20, 0xe1, 0x33, 0x12, 0x1c, 0xd0, 0xef, 0x24, 0xfc, 0x60, 0x18, 0x04, 0x70, 0x28, 0x90, 0xfa, 
-0xb7, 0xe0, 0x60, 0x09, 0x90, 0xff, 0xa4, 0xe0, 0x44, 0x10, 0xf0, 0x80, 0x19, 0x12, 0x1d, 0xa6, 
-0xf0, 0x80, 0x13, 0x90, 0xfa, 0xb7, 0xe0, 0x60, 0x09, 0x90, 0xff, 0xb4, 0xe0, 0x44, 0x10, 0xf0, 
-0x80, 0x04, 0x12, 0x1d, 0xad, 0xf0, 0xe4, 0xff, 0x02, 0x30, 0xec, 0x90, 0xfa, 0xb6, 0xe0, 0xff, 
-0x24, 0x12, 0x12, 0x1c, 0x41, 0x20, 0xe1, 0x39, 0x12, 0x1c, 0xd0, 0xef, 0x24, 0xfc, 0x60, 0x1b, 
-0x04, 0x70, 0x2e, 0x90, 0xfa, 0xb7, 0xe0, 0x60, 0x09, 0x90, 0xff, 0xa4, 0xe0, 0x44, 0x20, 0xf0, 
-0x80, 0x1f, 0x90, 0xff, 0xa4, 0xe0, 0x54, 0xdf, 0xf0, 0x80, 0x16, 0x90, 0xfa, 0xb7, 0xe0, 0x60, 
-0x09, 0x90, 0xff, 0xb4, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x07, 0x90, 0xff, 0xb4, 0xe0, 0x54, 0xdf, 
-0xf0, 0xe4, 0xff, 0x02, 0x30, 0xec, 0x12, 0x1c, 0xd0, 0x12, 0x1c, 0xc1, 0x60, 0x4d, 0x04, 0x60, 
-0x03, 0x02, 0x0c, 0xb2, 0x90, 0xfa, 0xb7, 0xe0, 0x60, 0x0f, 0x90, 0xff, 0xa4, 0x12, 0x1c, 0x3a, 
-0x30, 0xe1, 0x6f, 0x12, 0x1d, 0x7c, 0x02, 0x0c, 0xb2, 0x90, 0xff, 0xa4, 0xe0, 0x54, 0xfb, 0x12, 
-0x1c, 0x3d, 0xfe, 0x30, 0xe1, 0x5c, 0x30, 0xe2, 0x11, 0x30, 0xb4, 0x05, 0x12, 0x1d, 0x7c, 0x80, 
-0x51, 0x90, 0xff, 0xa4, 0xe0, 0x54, 0xfd, 0xf0, 0x80, 0x48, 0x30, 0x95, 0x05, 0x12, 0x1d, 0x7c, 
-0x80, 0x40, 0x90, 0xff, 0xa4, 0xe0, 0x54, 0xfd, 0xf0, 0x80, 0x37, 0x90, 0xfa, 0xb7, 0xe0, 0x60, 
-0x12, 0x90, 0xff, 0xb4, 0x12, 0x1c, 0x3a, 0x30, 0xe1, 0x28, 0x90, 0xff, 0xb4, 0xe0, 0x44, 0x02, 
-0xf0, 0x80, 0x1f, 0x90, 0xff, 0xb4, 0xe0, 0x54, 0xfb, 0x12, 0x1c, 0x3d, 0x30, 0xe1, 0x13, 0x30, 
-0x93, 0x09, 0x90, 0xff, 0xb4, 0xe0, 0x44, 0x02, 0xf0, 0x80, 0x07, 0x90, 0xff, 0xb4, 0xe0, 0x54, 
-0xfd, 0xf0, 0xe4, 0xff, 0x02, 0x30, 0xec, 0x12, 0x1c, 0xd0, 0x90, 0xfa, 0xb6, 0xe0, 0x24, 0xfc, 
-0x60, 0x40, 0x04, 0x70, 0x78, 0x90, 0xfa, 0xb7, 0xe0, 0x60, 0x1d, 0x90, 0xff, 0xa2, 0xe0, 0x44, 
-0x40, 0xf0, 0xa3, 0xe0, 0xff, 0x30, 0xe7, 0x65, 0xd2, 0x03, 0xa3, 0xe0, 0x54, 0xdf, 0xf0, 0x90, 
-0xff, 0xa3, 0xef, 0x54, 0x7f, 0xf0, 0x80, 0x55, 0x30, 0x03, 0x0e, 0x90, 0xff, 0xa3, 0xe0, 0x44, 
-0x80, 0xf0, 0xc2, 0x03, 0xa3, 0xe0, 0x44, 0x20, 0xf0, 0x90, 0xff, 0xa2, 0xe0, 0x54, 0xbf, 0xf0, 
-0x80, 0x3b, 0x90, 0xfa, 0xb7, 0xe0, 0x60, 0x1d, 0x90, 0xff, 0xb2, 0xe0, 0x44, 0x40, 0xf0, 0xa3, 
-0xe0, 0xff, 0x30, 0xe7, 0x28, 0xd2, 0x04, 0xa3, 0xe0, 0x54, 0xdf, 0xf0, 0x90, 0xff, 0xb3, 0xef, 
-0x54, 0x7f, 0xf0, 0x80, 0x18, 0x30, 0x04, 0x0e, 0x90, 0xff, 0xb3, 0xe0, 0x44, 0x80, 0xf0, 0xc2, 
-0x04, 0xa3, 0xe0, 0x44, 0x20, 0xf0, 0x90, 0xff, 0xb2, 0xe0, 0x54, 0xbf, 0xf0, 0xe4, 0xff, 0x02, 
-0x30, 0xec, 0x12, 0x1c, 0x30, 0x90, 0xfa, 0xb6, 0xe0, 0x24, 0xfc, 0x60, 0x0f, 0x04, 0x70, 0x16, 
-0x90, 0xff, 0xa6, 0xe0, 0x12, 0x1c, 0x11, 0x12, 0x1a, 0x38, 0x80, 0x0a, 0x90, 0xff, 0xb6, 0xe0, 
-0x12, 0x1c, 0x11, 0x12, 0x1a, 0x38, 0x75, 0x39, 0x00, 0x75, 0x3a, 0x01, 0x02, 0x2c, 0x07, 0xe4, 
-0xff, 0x12, 0x30, 0xec, 0x12, 0x1d, 0x37, 0x7f, 0x03, 0x12, 0x12, 0x19, 0x90, 0xf9, 0x15, 0xe0, 
-0x30, 0xe4, 0x08, 0x90, 0xff, 0x93, 0x74, 0x80, 0xf0, 0x80, 0x10, 0x90, 0xff, 0xfc, 0xe0, 0x54, 
-0x7f, 0xf0, 0x7f, 0xff, 0x7e, 0x00, 0x12, 0x30, 0x16, 0xc2, 0x90, 0xc2, 0xaf, 0x00, 0x80, 0xfd, 
-0xe4, 0xf5, 0x4e, 0xf5, 0x4f, 0x90, 0xfa, 0xbc, 0x74, 0x3e, 0xf0, 0xa3, 0xe4, 0xf0, 0x90, 0xfa, 
-0xb4, 0xf0, 0xa3, 0x74, 0x15, 0xf0, 0xe0, 0x54, 0x3f, 0xff, 0xc3, 0x74, 0x40, 0x9f, 0x90, 0xfa, 
-0xb9, 0xf0, 0xd3, 0x94, 0x00, 0xe4, 0x94, 0x3e, 0x40, 0x08, 0x90, 0xfa, 0xbd, 0xe0, 0x90, 0xfa, 
-0xb9, 0xf0, 0x12, 0x0f, 0x50, 0xe5, 0x31, 0x45, 0x30, 0x70, 0x73, 0x12, 0x1c, 0x4a, 0x90, 0xfa, 
-0xbc, 0x12, 0x1d, 0x56, 0x60, 0x27, 0xd3, 0xef, 0x94, 0x40, 0xee, 0x94, 0x00, 0x40, 0x08, 0x90, 
-0xfa, 0xb9, 0x74, 0x40, 0xf0, 0x80, 0x08, 0x90, 0xfa, 0xbd, 0xe0, 0x90, 0xfa, 0xb9, 0xf0, 0x12, 
-0x0f, 0x50, 0xe5, 0x31, 0x45, 0x30, 0x70, 0x46, 0x12, 0x1c, 0x4a, 0x80, 0xd1, 0x75, 0x4c, 0x02, 
-0x90, 0xfa, 0xbc, 0xe4, 0xf0, 0xa3, 0x04, 0xf0, 0x90, 0xfa, 0xb4, 0xe4, 0xf0, 0xa3, 0x74, 0x0f, 
-0xf0, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x4c, 0x90, 0xfa, 0xbd, 0xe0, 0xf5, 0x4a, 0x7d, 0x0f, 0x7c, 
-0x00, 0x12, 0x28, 0x9f, 0x75, 0x30, 0x00, 0x8f, 0x31, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x4c, 0xe4, 
-0xf5, 0x2d, 0xf5, 0x2e, 0x7d, 0x01, 0x12, 0x25, 0xd7, 0xe4, 0xf5, 0x30, 0xf5, 0x31, 0xaf, 0x31, 
-0x02, 0x30, 0xec, 0x12, 0x1c, 0xd0, 0x30, 0xe7, 0x10, 0xe0, 0x54, 0x0f, 0x90, 0xf9, 0x64, 0xf0, 
-0xd3, 0x94, 0x00, 0x40, 0x15, 0xc2, 0x95, 0x80, 0x11, 0x90, 0xfa, 0xb7, 0xe0, 0x54, 0x0f, 0x90, 
-0xf9, 0x63, 0xf0, 0xd3, 0x94, 0x00, 0x40, 0x02, 0xc2, 0x94, 0xe4, 0xff, 0x02, 0x30, 0xec, 0x12, 
-0x1d, 0x9c, 0xbf, 0x01, 0x04, 0xd2, 0x93, 0x80, 0x02, 0xc2, 0x93, 0xe4, 0xff, 0x02, 0x30, 0xec, 
-0x12, 0x1c, 0xd0, 0x54, 0x03, 0x14, 0x60, 0x0a, 0x14, 0x60, 0x0f, 0x14, 0x60, 0x08, 0x24, 0x03, 
-0x70, 0x2b, 0xd2, 0x91, 0x80, 0x27, 0xc2, 0x91, 0x80, 0x23, 0x12, 0x1d, 0xa6, 0x12, 0x0f, 0x78, 
-0x60, 0x04, 0xd2, 0x91, 0x80, 0x17, 0x90, 0xff, 0xa4, 0xe0, 0x44, 0x10, 0x12, 0x0f, 0x78, 0xff, 
-0xbf, 0xa0, 0x04, 0xc2, 0x91, 0x80, 0x02, 0xd2, 0x91, 0x12, 0x1d, 0xa6, 0xf0, 0x90, 0xfa, 0xb7, 
-0xe0, 0x54, 0x0c, 0xff, 0x13, 0x13, 0x54, 0x3f, 0x14, 0x60, 0x0a, 0x14, 0x60, 0x0f, 0x14, 0x60, 
-0x08, 0x24, 0x03, 0x70, 0x2b, 0xd2, 0x92, 0x80, 0x27, 0xc2, 0x92, 0x80, 0x23, 0x12, 0x1d, 0xad, 
-0x12, 0x0f, 0x98, 0x60, 0x04, 0xd2, 0x92, 0x80, 0x17, 0x90, 0xff, 0xb4, 0xe0, 0x44, 0x10, 0x12, 
-0x0f, 0x98, 0xff, 0xbf, 0xa0, 0x04, 0xc2, 0x92, 0x80, 0x02, 0xd2, 0x92, 0x12, 0x1d, 0xad, 0xf0, 
-0xe4, 0xff, 0x02, 0x30, 0xec, 0xe5, 0x35, 0x30, 0xe7, 0x07, 0xe4, 0xfd, 0x7f, 0x05, 0x02, 0x2f, 
-0x18, 0x7f, 0x05, 0x02, 0x30, 0xec, 0x12, 0x31, 0xbd, 0x22, 0x7b, 0x01, 0x7a, 0xfa, 0x79, 0xb3, 
-0x90, 0xfa, 0xb4, 0xe0, 0xf5, 0x2d, 0xa3, 0xe0, 0xf5, 0x2e, 0x7d, 0x01, 0x12, 0x25, 0xd7, 0x90, 
-0xfa, 0xb4, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0x1a, 0x6c, 0xab, 0x36, 0xaa, 0x37, 0xa9, 0x38, 0x22, 
-0xaa, 0x4e, 0xa9, 0x4f, 0x7b, 0xff, 0x90, 0xfa, 0xb4, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0x90, 0xfa, 
-0xb9, 0xe0, 0xf5, 0x4a, 0x12, 0x28, 0x9f, 0x75, 0x30, 0x00, 0x8f, 0x31, 0x22, 0x12, 0x22, 0xa0, 
-0x7e, 0x00, 0x8e, 0x30, 0x8f, 0x31, 0xef, 0x22, 0xf0, 0x7f, 0x01, 0x12, 0x12, 0x19, 0x90, 0xff, 
-0xa6, 0xe0, 0x90, 0xfa, 0xb8, 0xf0, 0x54, 0xa0, 0x22, 0x12, 0x25, 0xd7, 0x8f, 0x4c, 0x7e, 0x00, 
-0xc3, 0xef, 0x95, 0x3c, 0xee, 0x95, 0x3b, 0x22, 0xf0, 0x7f, 0x01, 0x12, 0x12, 0x19, 0x90, 0xff, 
-0xb6, 0xe0, 0x90, 0xfa, 0xb8, 0xf0, 0x54, 0xa0, 0x22, 0x75, 0x39, 0x00, 0x75, 0x3a, 0x01, 0x02, 
-0x2c, 0x07, 0x90, 0xfa, 0xb6, 0xe0, 0xff, 0x02, 0x31, 0x82, 0x8e, 0x39, 0x8f, 0x3a, 0x02, 0x2c, 
-0x07, 0x12, 0x22, 0xa0, 0x7e, 0x00, 0x8e, 0x30, 0x8f, 0x31, 0xef, 0x22, 0x7d, 0x01, 0x12, 0x25, 
-0xd7, 0x90, 0xfa, 0xb1, 0xe0, 0x22, 0xef, 0x90, 0xf8, 0x04, 0xf0, 0x22, 0xc0, 0xa8, 0xc2, 0xaf, 
-0xee, 0x60, 0x0a, 0xc0, 0x05, 0x7d, 0x7f, 0xdd, 0xfe, 0xde, 0xfa, 0xd0, 0x05, 0xef, 0xc3, 0x94, 
-0x15, 0x50, 0x03, 0xd0, 0xa8, 0x22, 0x13, 0x70, 0x03, 0xd0, 0xa8, 0x22, 0xff, 0xd5, 0x07, 0xfd, 
-0xd0, 0xa8, 0x22, 0xc0, 0x00, 0xc0, 0x01, 0xc0, 0x02, 0xc0, 0x04, 0xc0, 0x05, 0xe5, 0x3e, 0x24, 
-0x08, 0xf8, 0x86, 0x05, 0x53, 0x05, 0x7f, 0x7c, 0xff, 0x12, 0x10, 0x78, 0x7f, 0x00, 0x7e, 0x00, 
-0xe5, 0x43, 0x60, 0x46, 0xfc, 0x90, 0xf9, 0x1b, 0xe0, 0x54, 0x7f, 0x6d, 0x70, 0x0f, 0xc0, 0x83, 
-0xc0, 0x82, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xa3, 0x15, 0x43, 0x80, 0x07, 0xa3, 0xa3, 0xa3, 
-0xdc, 0xe6, 0x80, 0x26, 0xdc, 0x06, 0xd0, 0x82, 0xd0, 0x83, 0x80, 0x1e, 0xe0, 0xf8, 0xa3, 0xe0, 
-0xf9, 0xa3, 0xe0, 0xfa, 0xd0, 0x82, 0xd0, 0x83, 0xe8, 0xf0, 0xa3, 0xe9, 0xf0, 0xa3, 0xea, 0xf0, 
-0xa3, 0xc0, 0x83, 0xc0, 0x82, 0xa3, 0xa3, 0xa3, 0x80, 0xda, 0x12, 0x11, 0x0f, 0xd0, 0x05, 0xd0, 
-0x04, 0xd0, 0x02, 0xd0, 0x01, 0xd0, 0x00, 0x22, 0x85, 0xa8, 0x44, 0x75, 0xa8, 0x88, 0xec, 0x70, 
-0x02, 0x7c, 0x3f, 0x8c, 0x3d, 0x22, 0xe5, 0x3e, 0x24, 0x08, 0xf8, 0x76, 0x00, 0x12, 0x11, 0x66, 
-0x80, 0xfb, 0xc0, 0x00, 0xc0, 0x01, 0xc0, 0x02, 0xc0, 0x04, 0xc0, 0x06, 0x7c, 0xff, 0x12, 0x10, 
-0x78, 0xe5, 0x43, 0x60, 0x42, 0xfe, 0x90, 0xf9, 0x1b, 0xe0, 0x54, 0x7f, 0x6f, 0x70, 0x0b, 0xc0, 
-0x83, 0xc0, 0x82, 0xa3, 0xa3, 0xa3, 0x15, 0x43, 0x80, 0x07, 0xa3, 0xa3, 0xa3, 0xde, 0xea, 0x80, 
-0x26, 0xde, 0x06, 0xd0, 0x82, 0xd0, 0x83, 0x80, 0xd8, 0xe0, 0xf8, 0xa3, 0xe0, 0xf9, 0xa3, 0xe0, 
-0xfa, 0xd0, 0x82, 0xd0, 0x83, 0xe8, 0xf0, 0xa3, 0xe9, 0xf0, 0xa3, 0xea, 0xf0, 0xa3, 0xc0, 0x83, 
-0xc0, 0x82, 0xa3, 0xa3, 0xa3, 0x80, 0xda, 0x78, 0x08, 0x08, 0x79, 0x18, 0x09, 0x7c, 0x01, 0xe6, 
-0x54, 0x7f, 0x6f, 0x70, 0x06, 0x76, 0x00, 0x77, 0x00, 0x80, 0x06, 0x08, 0x09, 0x0c, 0xbc, 0x08, 
-0xee, 0x12, 0x11, 0x0f, 0xd0, 0x06, 0xd0, 0x04, 0xd0, 0x02, 0xd0, 0x01, 0xd0, 0x00, 0x22, 0x75, 
-0x3d, 0x00, 0x85, 0x44, 0xa8, 0x22, 0xc0, 0xf0, 0xc0, 0x82, 0xc0, 0x83, 0xc3, 0xe5, 0x43, 0x24, 
-0xe8, 0x50, 0x05, 0x12, 0x11, 0x66, 0x80, 0xf4, 0xef, 0x60, 0x31, 0x90, 0x30, 0x54, 0xe4, 0x93, 
-0xc3, 0x9f, 0x40, 0x2f, 0xc0, 0x04, 0x7c, 0xff, 0x12, 0x10, 0x78, 0xd0, 0x04, 0x43, 0x07, 0x80, 
-0xe5, 0x43, 0x75, 0xf0, 0x03, 0xa4, 0x24, 0x1b, 0xf5, 0x82, 0xe4, 0x34, 0xf9, 0xf5, 0x83, 0xef, 
-0xf0, 0xec, 0xa3, 0xf0, 0xed, 0xa3, 0xf0, 0x05, 0x43, 0x12, 0x11, 0x0f, 0xd0, 0x83, 0xd0, 0x82, 
-0xd0, 0xf0, 0x22, 0x02, 0x11, 0x94, 0xc0, 0x04, 0x7c, 0x20, 0xd2, 0x8c, 0xd2, 0x8d, 0xd5, 0x04, 
-0xfd, 0xd0, 0x04, 0x22, 0x75, 0xa8, 0x00, 0x75, 0x88, 0x00, 0x75, 0xb8, 0x00, 0x75, 0xf0, 0x00, 
-0x75, 0xd0, 0x00, 0xe4, 0xf8, 0x90, 0xf8, 0x04, 0xf0, 0x90, 0x00, 0x00, 0xf6, 0x08, 0xb8, 0x00, 
-0xfb, 0x02, 0x00, 0x00, 0xc2, 0xaf, 0xe4, 0x90, 0xff, 0x48, 0xf0, 0x90, 0xff, 0x50, 0xf0, 0x90, 
-0xff, 0x08, 0xf0, 0x90, 0xff, 0x10, 0xf0, 0x90, 0xff, 0x80, 0xf0, 0xa3, 0xa3, 0xf0, 0xd2, 0xb1, 
-0xc2, 0xb0, 0x7e, 0xff, 0x7f, 0xff, 0x12, 0x0f, 0xdc, 0x7e, 0xff, 0x7f, 0xff, 0x12, 0x0f, 0xdc, 
-0x7e, 0xff, 0x7f, 0xff, 0x12, 0x0f, 0xdc, 0xd2, 0xb0, 0xd2, 0xb1, 0x7e, 0xff, 0x7f, 0xff, 0x12, 
-0x0f, 0xdc, 0x7e, 0xff, 0x7f, 0xff, 0x12, 0x0f, 0xdc, 0x7e, 0xff, 0x7f, 0xff, 0x12, 0x0f, 0xdc, 
-0x80, 0xcc, 0xc3, 0xee, 0x94, 0x02, 0x50, 0x04, 0x7e, 0x03, 0x7f, 0xe8, 0xef, 0xf4, 0xff, 0xee, 
-0xf4, 0xfe, 0x0f, 0xbf, 0x00, 0x01, 0x0e, 0x8f, 0x42, 0x8e, 0x41, 0x22, 0xc3, 0xef, 0x94, 0xbc, 
-0xee, 0x94, 0x02, 0x50, 0x04, 0x7e, 0x07, 0x7f, 0xd0, 0xef, 0xf4, 0xff, 0xee, 0xf4, 0xfe, 0x0f, 
-0xbf, 0x00, 0x01, 0x0e, 0x8f, 0x40, 0x8e, 0x3f, 0x22, 0xef, 0x70, 0x01, 0x22, 0xc0, 0x00, 0xc0, 
-0xa8, 0xc2, 0xaf, 0xe5, 0x3e, 0x24, 0x18, 0xf8, 0xa6, 0x07, 0xe5, 0x3e, 0x24, 0x08, 0xf8, 0xc6, 
-0x54, 0x7f, 0xf6, 0xd0, 0xa8, 0xe6, 0x30, 0xe7, 0x03, 0xd0, 0x00, 0x22, 0x12, 0x11, 0x66, 0x80, 
-0xf4, 0xc0, 0x00, 0x7f, 0x01, 0xef, 0x24, 0x08, 0xf8, 0xe6, 0x60, 0x09, 0x0f, 0xbf, 0x08, 0xf5, 
-0x12, 0x11, 0x66, 0x80, 0xee, 0xd0, 0x00, 0x22, 0xc0, 0xf0, 0xc0, 0x82, 0xc0, 0x83, 0xc0, 0x00, 
-0xc0, 0x06, 0xc0, 0x04, 0xed, 0x24, 0x10, 0xf8, 0x76, 0x9a, 0xed, 0x75, 0xf0, 0x21, 0xa4, 0x24, 
-0x05, 0xf5, 0x82, 0xe4, 0x34, 0xf8, 0xf5, 0x83, 0xc0, 0x82, 0xc0, 0x83, 0xa3, 0xa3, 0xe4, 0x78, 
-0x0d, 0xf0, 0xa3, 0xd8, 0xfc, 0xef, 0x54, 0x7f, 0x75, 0xf0, 0x02, 0xa4, 0x24, 0x36, 0xf5, 0x82, 
-0xe5, 0xf0, 0x34, 0x30, 0xf5, 0x83, 0xe4, 0x93, 0xfe, 0x74, 0x01, 0x93, 0xfc, 0xd0, 0x83, 0xd0, 
-0x82, 0xec, 0xf0, 0xa3, 0xee, 0xf0, 0xed, 0x24, 0x08, 0xf8, 0xef, 0x44, 0x80, 0xf6, 0xd0, 0x04, 
-0xd0, 0x06, 0xd0, 0x00, 0xd0, 0x83, 0xd0, 0x82, 0xd0, 0xf0, 0x22, 0x75, 0x3e, 0x00, 0x75, 0x43, 
-0x00, 0x7a, 0x08, 0x79, 0x18, 0x78, 0x08, 0x76, 0x00, 0x77, 0x00, 0x08, 0x09, 0xda, 0xf8, 0x90, 
-0xf8, 0x04, 0xe0, 0xfc, 0x90, 0x30, 0x54, 0xe4, 0x93, 0xc3, 0x9c, 0x50, 0x05, 0xe4, 0x90, 0xf8, 
-0x04, 0xf0, 0x78, 0x08, 0x74, 0x80, 0x44, 0x7f, 0xf6, 0x74, 0x01, 0x44, 0x10, 0xf5, 0x89, 0x75, 
-0xb8, 0x00, 0xd2, 0xab, 0xd2, 0xa9, 0x22, 0x75, 0x81, 0x8b, 0xd2, 0x8e, 0xd2, 0x8c, 0xd2, 0xaf, 
-0xe5, 0x43, 0x60, 0x36, 0xff, 0x90, 0xf9, 0x1b, 0xe0, 0x54, 0x80, 0x60, 0x28, 0x78, 0x08, 0x79, 
-0x08, 0xe0, 0x54, 0x7f, 0xfa, 0x7b, 0x00, 0xe6, 0x54, 0x7f, 0xb5, 0x02, 0x02, 0x7b, 0xff, 0x08, 
-0xd9, 0xf5, 0xeb, 0x70, 0x10, 0xea, 0xf0, 0xc0, 0x07, 0x12, 0x12, 0x41, 0xad, 0x07, 0xaf, 0x02, 
-0x12, 0x12, 0x58, 0xd0, 0x07, 0xa3, 0xa3, 0xa3, 0xdf, 0xce, 0x12, 0x11, 0x66, 0x80, 0xc1, 0x8f, 
-0x24, 0x12, 0x2a, 0x06, 0x78, 0x80, 0xe6, 0xfe, 0x08, 0xe6, 0xff, 0x8e, 0x83, 0x24, 0x08, 0x12, 
-0x21, 0xf3, 0xe0, 0xfd, 0x12, 0x22, 0x8a, 0x8a, 0x83, 0x24, 0x0a, 0x12, 0x21, 0xf3, 0xed, 0xf0, 
-0x12, 0x22, 0x56, 0x24, 0x07, 0x12, 0x21, 0xf3, 0xe0, 0xff, 0x12, 0x22, 0x99, 0x24, 0x09, 0x12, 
-0x21, 0xf3, 0xef, 0xf0, 0x90, 0xf9, 0x15, 0xe0, 0x30, 0xe4, 0x20, 0x08, 0x12, 0x22, 0x09, 0xc0, 
-0x83, 0xc0, 0x82, 0xa3, 0xe0, 0x25, 0xe0, 0xff, 0x05, 0x82, 0xd5, 0x82, 0x02, 0x15, 0x83, 0x15, 
-0x82, 0xe0, 0x33, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0xa3, 0xef, 0xf0, 0x78, 0x80, 0x12, 0x22, 0x09, 
-0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xec, 0xff, 0x12, 0x22, 0x8a, 0x8a, 0x83, 0x24, 0x08, 0x12, 0x21, 
-0xf3, 0xef, 0xf0, 0xed, 0x12, 0x22, 0x99, 0x24, 0x07, 0x12, 0x21, 0xf3, 0xed, 0xf0, 0x12, 0x21, 
-0xfb, 0xe0, 0xff, 0x30, 0xe7, 0x19, 0x12, 0x22, 0x6e, 0x12, 0x21, 0xf3, 0xe0, 0x60, 0x09, 0x12, 
-0x21, 0xfb, 0xef, 0x44, 0x02, 0xf0, 0x80, 0x07, 0x12, 0x21, 0xfb, 0xef, 0x54, 0xfd, 0xf0, 0x78, 
-0x7e, 0x12, 0x22, 0x09, 0xa3, 0xa3, 0xe0, 0xff, 0x53, 0x07, 0xc7, 0x08, 0xe6, 0xfc, 0x08, 0xe6, 
-0xfd, 0x12, 0x22, 0x43, 0xa3, 0xe0, 0x30, 0xe3, 0x12, 0x8d, 0x82, 0x8c, 0x83, 0xe5, 0x82, 0x24, 
-0x05, 0x12, 0x21, 0xf3, 0xe0, 0x90, 0x31, 0x94, 0x93, 0x42, 0x07, 0x53, 0x07, 0xfb, 0x78, 0x80, 
-0xe6, 0xfc, 0x08, 0xe6, 0x8c, 0x83, 0x24, 0x06, 0x12, 0x21, 0xf3, 0xe0, 0x60, 0x03, 0x43, 0x07, 
-0x04, 0x53, 0x07, 0xfc, 0x78, 0x80, 0x12, 0x22, 0x7a, 0x24, 0x04, 0x12, 0x21, 0xf3, 0xe0, 0x42, 
-0x07, 0x43, 0x07, 0x80, 0x12, 0x22, 0x8a, 0xf5, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xef, 0xf0, 0x12, 
-0x22, 0x99, 0x24, 0x04, 0x12, 0x21, 0xf3, 0xe0, 0xff, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xa3, 0xe0, 
-0xfc, 0xa3, 0xe0, 0xfd, 0x30, 0xe1, 0x05, 0x53, 0x07, 0xdf, 0x80, 0x03, 0x43, 0x07, 0x20, 0xec, 
-0x30, 0xe4, 0x05, 0x53, 0x07, 0xef, 0x80, 0x03, 0x43, 0x07, 0x10, 0x12, 0x21, 0xfb, 0xe0, 0xfe, 
-0x54, 0x03, 0x60, 0x73, 0x53, 0x07, 0xdf, 0xee, 0x30, 0xe1, 0x69, 0x78, 0x80, 0x12, 0x22, 0x6f, 
-0x12, 0x21, 0xf3, 0xe0, 0x12, 0x1b, 0x4c, 0x14, 0xa6, 0x00, 0x14, 0xda, 0x01, 0x14, 0xdf, 0x03, 
-0x14, 0xda, 0x05, 0x14, 0xdf, 0x07, 0x14, 0xda, 0x09, 0x14, 0xdf, 0x0b, 0x14, 0xda, 0x0d, 0x14, 
-0xdf, 0x0f, 0x00, 0x00, 0x14, 0xe7, 0xe5, 0x24, 0x64, 0x03, 0x70, 0x21, 0x90, 0xf9, 0x15, 0xe0, 
-0x30, 0xe2, 0x0d, 0x30, 0xb4, 0x05, 0x43, 0x07, 0x02, 0x80, 0x2c, 0x53, 0x07, 0xfd, 0x80, 0x27, 
-0x30, 0x95, 0x05, 0x43, 0x07, 0x02, 0x80, 0x1f, 0x53, 0x07, 0xfd, 0x80, 0x1a, 0x30, 0x93, 0x05, 
-0x43, 0x07, 0x02, 0x80, 0x12, 0x53, 0x07, 0xfd, 0x80, 0x0d, 0x43, 0x07, 0x02, 0x80, 0x08, 0x53, 
-0x07, 0xfd, 0x80, 0x03, 0x53, 0x07, 0xfd, 0x12, 0x22, 0x78, 0x24, 0x04, 0x12, 0x21, 0xf3, 0xef, 
-0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0xff, 0x12, 0x21, 0xfb, 0xe0, 0xfe, 0x54, 
-0x03, 0x70, 0x03, 0x02, 0x15, 0xd7, 0xee, 0x20, 0xe1, 0x03, 0x02, 0x15, 0xd4, 0x12, 0x22, 0x6e, 
-0x12, 0x21, 0xf3, 0xe0, 0x12, 0x1b, 0x4c, 0x15, 0x36, 0x00, 0x15, 0x6c, 0x01, 0x15, 0x6c, 0x03, 
-0x15, 0xa0, 0x05, 0x15, 0xa0, 0x07, 0x15, 0x86, 0x09, 0x15, 0x86, 0x0b, 0x15, 0xba, 0x0d, 0x15, 
-0xba, 0x0f, 0x00, 0x00, 0x15, 0xd7, 0xe5, 0x24, 0x64, 0x03, 0x70, 0x23, 0x90, 0xf9, 0x15, 0xe0, 
-0x30, 0xe2, 0x0f, 0x30, 0xb1, 0x06, 0x53, 0x07, 0x7f, 0x02, 0x15, 0xd7, 0x43, 0x07, 0x80, 0x02, 
-0x15, 0xd7, 0x30, 0x94, 0x05, 0x53, 0x07, 0x7f, 0x80, 0x7d, 0x43, 0x07, 0x80, 0x80, 0x78, 0x30, 
-0x92, 0x05, 0x53, 0x07, 0x7f, 0x80, 0x70, 0x43, 0x07, 0x80, 0x80, 0x6b, 0xe5, 0x24, 0xb4, 0x03, 
-0x09, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xef, 0xf0, 0x80, 0x07, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xdf, 
-0xf0, 0x53, 0x07, 0x7f, 0x80, 0x51, 0xe5, 0x24, 0xb4, 0x03, 0x09, 0x90, 0xff, 0x9e, 0xe0, 0x44, 
-0x10, 0xf0, 0x80, 0x07, 0x90, 0xff, 0x9e, 0xe0, 0x44, 0x20, 0xf0, 0x53, 0x07, 0x7f, 0x80, 0x37, 
-0xe5, 0x24, 0xb4, 0x03, 0x09, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xef, 0xf0, 0x80, 0x07, 0x90, 0xff, 
-0x9e, 0xe0, 0x54, 0xdf, 0xf0, 0x43, 0x07, 0x80, 0x80, 0x1d, 0xe5, 0x24, 0xb4, 0x03, 0x09, 0x90, 
-0xff, 0x9e, 0xe0, 0x44, 0x10, 0xf0, 0x80, 0x07, 0x90, 0xff, 0x9e, 0xe0, 0x44, 0x20, 0xf0, 0x43, 
-0x07, 0x80, 0x80, 0x03, 0x53, 0x07, 0x7f, 0x78, 0x80, 0x12, 0x22, 0x3f, 0xe0, 0xfc, 0xa3, 0xe0, 
-0xfd, 0x30, 0xe0, 0x05, 0x43, 0x07, 0x20, 0x80, 0x03, 0x53, 0x07, 0xdf, 0xec, 0x30, 0xe3, 0x05, 
-0x43, 0x07, 0x40, 0x80, 0x03, 0x53, 0x07, 0xbf, 0xec, 0x30, 0xe0, 0x05, 0x43, 0x07, 0x10, 0x80, 
-0x03, 0x53, 0x07, 0xef, 0xed, 0x30, 0xe4, 0x05, 0x43, 0x07, 0x08, 0x80, 0x03, 0x53, 0x07, 0xf7, 
-0xed, 0x30, 0xe5, 0x05, 0x43, 0x07, 0x04, 0x80, 0x03, 0x53, 0x07, 0xfb, 0xed, 0x30, 0xe6, 0x05, 
-0x43, 0x07, 0x01, 0x80, 0x03, 0x53, 0x07, 0xfe, 0xed, 0x30, 0xe7, 0x05, 0x43, 0x07, 0x02, 0x80, 
-0x03, 0x53, 0x07, 0xfd, 0x78, 0x7e, 0x12, 0x22, 0x3f, 0xa3, 0xef, 0xf0, 0x12, 0x31, 0xc7, 0x7f, 
-0x00, 0x22, 0x90, 0xff, 0xfa, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x16, 0xf0, 0x90, 0xff, 0xf9, 0x74, 
-0x02, 0xf0, 0x7b, 0x01, 0x7a, 0xfa, 0x79, 0xcc, 0xe4, 0xfd, 0x12, 0x22, 0xa0, 0x90, 0xfa, 0xcc, 
-0xe4, 0x75, 0xf0, 0x03, 0x12, 0x1a, 0x6c, 0x12, 0x18, 0xe2, 0xe5, 0x23, 0x30, 0xe7, 0x02, 0xd2, 
-0x02, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x24, 0x90, 0xfa, 0xcc, 0xe0, 0xf5, 0x2d, 0xa3, 0xe0, 0xf5, 
-0x2e, 0x7d, 0x01, 0x12, 0x25, 0xd7, 0x90, 0xfa, 0xcc, 0xe4, 0xf0, 0xa3, 0x74, 0x0b, 0xf0, 0x7b, 
-0x00, 0x7a, 0x00, 0x79, 0x23, 0x75, 0x2d, 0x00, 0xf5, 0x2e, 0x7d, 0x01, 0x12, 0x25, 0xd7, 0xe5, 
-0x23, 0x24, 0x80, 0x90, 0xff, 0xf8, 0xf0, 0xe5, 0x23, 0x64, 0x07, 0x60, 0x1e, 0xe5, 0x23, 0x64, 
-0x06, 0x60, 0x18, 0xe5, 0x23, 0x64, 0x14, 0x60, 0x12, 0xe5, 0x23, 0x64, 0x41, 0x60, 0x0c, 0xe5, 
-0x23, 0x64, 0x1a, 0x70, 0x46, 0xe5, 0x24, 0x64, 0x02, 0x70, 0x40, 0xe5, 0x23, 0xb4, 0x07, 0x16, 
-0xd2, 0x94, 0xd2, 0x95, 0xd2, 0x92, 0xd2, 0x93, 0x90, 0xf9, 0x15, 0xe0, 0x44, 0x02, 0xf0, 0xa3, 
-0xe0, 0x44, 0x02, 0xf0, 0x80, 0x1e, 0xe5, 0x23, 0xb4, 0x41, 0x12, 0x90, 0xf9, 0x15, 0xe0, 0x44, 
-0x06, 0xf0, 0xa3, 0xe0, 0x44, 0x06, 0xf0, 0xd2, 0xb1, 0xd2, 0xb4, 0x80, 0x07, 0x90, 0xf9, 0x15, 
-0xe0, 0x44, 0x01, 0xf0, 0x90, 0xf9, 0x16, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x23, 0x64, 0x42, 0x60, 
-0x05, 0xe5, 0x23, 0xb4, 0x43, 0x0c, 0x90, 0xf9, 0x15, 0xe0, 0x44, 0x80, 0xf0, 0xa3, 0xe0, 0x44, 
-0x80, 0xf0, 0x90, 0xfa, 0xcc, 0xe4, 0xf0, 0xa3, 0x74, 0x0d, 0xf0, 0x12, 0x18, 0xe2, 0x90, 0xff, 
-0xf5, 0xe5, 0x23, 0xf0, 0xe4, 0xf5, 0x35, 0xf5, 0x33, 0xf5, 0x34, 0xf5, 0x32, 0x12, 0x1d, 0x84, 
-0x12, 0x1c, 0x30, 0x12, 0x1d, 0x8b, 0x90, 0xf9, 0x67, 0x12, 0x1b, 0x43, 0x90, 0xf9, 0x6c, 0x12, 
-0x1b, 0x43, 0x90, 0xff, 0xff, 0xe4, 0xf0, 0x90, 0xff, 0x83, 0xe0, 0xe4, 0xf0, 0x90, 0xff, 0x81, 
+0xc0, 0x06, 0xc0, 0x07, 0x74, 0x15, 0xf5, 0x82, 0x74, 0xf9, 0xf5, 0x83, 0xe0, 0x60, 0x23, 0x74,
+0x66, 0xf5, 0x82, 0x74, 0xf9, 0xf5, 0x83, 0xe0, 0x14, 0xf0, 0x70, 0x16, 0x74, 0xff, 0xf0, 0x74,
+0x1c, 0xf5, 0x82, 0x74, 0xf9, 0xf5, 0x83, 0xe0, 0x60, 0x04, 0x14, 0xf0, 0x70, 0x04, 0xc2, 0x90,
+0x80, 0xfc, 0x90, 0xff, 0x93, 0x74, 0x81, 0xf0, 0xe5, 0x81, 0x94, 0xfd, 0x40, 0x03, 0x02, 0x11,
+0xdc, 0x85, 0x41, 0x8d, 0x85, 0x42, 0x8b, 0x74, 0xb2, 0xf5, 0x82, 0x74, 0xfa, 0xf5, 0x83, 0xe0,
+0xb4, 0x01, 0x1b, 0xc0, 0x82, 0xc0, 0x83, 0x90, 0xff, 0x4a, 0xe0, 0x30, 0xe7, 0x2c, 0x90, 0xff,
+0x4e, 0xe0, 0x30, 0xe7, 0x25, 0xd0, 0x83, 0xd0, 0x82, 0x74, 0x02, 0xf0, 0x80, 0x20, 0xb4, 0x02,
+0x1d, 0xc0, 0x82, 0xc0, 0x83, 0x90, 0xff, 0x7a, 0xe0, 0x30, 0xe7, 0x05, 0x12, 0x28, 0x4e, 0x80,
+0x09, 0xd0, 0x83, 0xd0, 0x82, 0x74, 0x03, 0xf0, 0x80, 0x04, 0xd0, 0x83, 0xd0, 0x82, 0xa3, 0xe0,
+0xb4, 0x01, 0x1b, 0xc0, 0x82, 0xc0, 0x83, 0x90, 0xff, 0x52, 0xe0, 0x30, 0xe7, 0x2c, 0x90, 0xff,
+0x56, 0xe0, 0x30, 0xe7, 0x25, 0xd0, 0x83, 0xd0, 0x82, 0x74, 0x02, 0xf0, 0x80, 0x25, 0xb4, 0x02,
+0x22, 0xc0, 0x82, 0xc0, 0x83, 0x90, 0xff, 0x7a, 0xe0, 0x30, 0xe7, 0x05, 0x12, 0x28, 0x4e, 0x80,
+0x09, 0xd0, 0x83, 0xd0, 0x82, 0x74, 0x03, 0xf0, 0x80, 0x09, 0xd0, 0x83, 0xd0, 0x82, 0x80, 0x03,
+0x02, 0x02, 0x90, 0x74, 0x16, 0xf5, 0x82, 0x74, 0xf9, 0xf5, 0x83, 0xe0, 0x20, 0x04, 0xf1, 0x20,
+0x02, 0x03, 0x30, 0x01, 0xeb, 0x74, 0x19, 0xf5, 0x82, 0x74, 0xf9, 0xf5, 0x83, 0xe0, 0x14, 0xfc,
+0xf0, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0x64, 0x04, 0x70, 0x0f, 0xec, 0x70, 0x62, 0x7e, 0x01,
+0x12, 0x00, 0xc9, 0x7c, 0x0a, 0x7d, 0xfa, 0x02, 0x02, 0x61, 0x12, 0x00, 0xc9, 0xee, 0x64, 0x04,
+0x60, 0x1d, 0xec, 0x70, 0x4b, 0x7c, 0x0a, 0xed, 0x14, 0xfd, 0x70, 0x15, 0xee, 0x64, 0x02, 0x60,
+0x07, 0x7e, 0x02, 0x7d, 0x32, 0x02, 0x02, 0x61, 0x7e, 0x01, 0x7d, 0xfa, 0x02, 0x02, 0x61, 0x7c,
+0x0a, 0x74, 0x19, 0xf5, 0x82, 0x74, 0xf9, 0xf5, 0x83, 0xec, 0xf0, 0xa3, 0xed, 0xf0, 0xa3, 0xee,
+0xf0, 0x14, 0x60, 0x18, 0x20, 0xe1, 0x0f, 0x20, 0x01, 0x06, 0xd2, 0xb1, 0xc2, 0xb0, 0x80, 0x10,
+0xc2, 0xb1, 0xd2, 0xb0, 0x80, 0x0a, 0xc2, 0xb1, 0xc2, 0xb0, 0x80, 0x04, 0xd2, 0xb0, 0xd2, 0xb1,
+0x78, 0x19, 0x79, 0x09, 0x7a, 0x07, 0xe7, 0x70, 0x04, 0xa6, 0x00, 0x80, 0x0b, 0xe6, 0x60, 0x08,
+0x16, 0xe6, 0x70, 0x04, 0xe7, 0x44, 0x80, 0xf7, 0x08, 0x09, 0xda, 0xea, 0xe5, 0x3d, 0x60, 0x13,
+0x14, 0xf5, 0x3d, 0x70, 0x0e, 0xe5, 0x3e, 0x24, 0x08, 0xf8, 0x76, 0x00, 0x12, 0x11, 0x57, 0xd2,
+0x8c, 0xd2, 0x8d, 0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x05, 0xd0, 0x04, 0xd0, 0x03, 0xd0, 0x02, 0xd0,
+0x01, 0xd0, 0x00, 0xd0, 0x83, 0xd0, 0x82, 0xd0, 0xf0, 0xd0, 0xd0, 0xd0, 0xe0, 0x32, 0x90, 0xff,
+0x04, 0xe0, 0x90, 0xfa, 0xb9, 0xf0, 0x90, 0xff, 0x06, 0xe0, 0xfc, 0xa3, 0xe0, 0xfa, 0xec, 0xff,
+0xea, 0xfe, 0xef, 0xc3, 0x94, 0x08, 0xee, 0x94, 0x01, 0x50, 0x02, 0x80, 0x04, 0x7e, 0x01, 0x7f,
+0x08, 0x8e, 0x3b, 0x8f, 0x3c, 0x90, 0xff, 0x02, 0xe0, 0xfc, 0xa3, 0xe0, 0xfa, 0xec, 0xff, 0xea,
+0x90, 0xfa, 0xbd, 0xf0, 0xef, 0xa3, 0xf0, 0x12, 0x1c, 0xe0, 0xe4, 0xf5, 0x4d, 0xe5, 0x4d, 0xc3,
+0x94, 0x02, 0x50, 0x0f, 0x12, 0x1c, 0xc1, 0xe4, 0x12, 0x1a, 0xe8, 0x05, 0x4d, 0x04, 0x12, 0x1c,
+0xb2, 0x80, 0xea, 0x12, 0x1c, 0xe0, 0x90, 0xff, 0x00, 0xe0, 0xff, 0x54, 0x60, 0x24, 0xc0, 0x70,
+0x03, 0x02, 0x08, 0xf3, 0x24, 0x40, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xb9, 0xe0, 0xfe,
+0x54, 0x0f, 0xf5, 0x4d, 0xee, 0x30, 0xe7, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x0a, 0x90, 0xff,
+0x01, 0xe0, 0x12, 0x1b, 0xfc, 0x03, 0x84, 0x00, 0x04, 0x57, 0x01, 0x05, 0x6a, 0x03, 0x06, 0x31,
+0x05, 0x06, 0x73, 0x06, 0x07, 0xd5, 0x08, 0x08, 0x1d, 0x09, 0x08, 0x79, 0x0a, 0x08, 0xb9, 0x0b,
+0x00, 0x00, 0x0f, 0x6e, 0xe5, 0x35, 0x20, 0xe7, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xbd, 0xe0,
+0x70, 0x02, 0xa3, 0xe0, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x3c, 0x64, 0x02, 0x45, 0x3b, 0x60,
+0x03, 0x02, 0x0f, 0x6e, 0xef, 0x54, 0x1f, 0x14, 0x60, 0x2b, 0x14, 0x60, 0x47, 0x24, 0x02, 0x60,
+0x03, 0x02, 0x0f, 0x6e, 0xee, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x12, 0x1c, 0xc1, 0x74, 0x01, 0x12,
+0x1a, 0xe8, 0x78, 0x67, 0xe6, 0x30, 0xe0, 0x08, 0x12, 0x1c, 0xc1, 0x74, 0x02, 0x12, 0x1a, 0xe8,
+0x7f, 0x02, 0x02, 0x32, 0x6e, 0xe5, 0x35, 0x20, 0xe1, 0x09, 0x90, 0xfa, 0xb9, 0xe0, 0x60, 0x03,
+0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xb9, 0xe0, 0xd3, 0x94, 0x01, 0x40, 0x03, 0x02, 0x0f, 0x6e, 0x7f,
+0x02, 0x02, 0x32, 0x6e, 0xe5, 0x35, 0x20, 0xe1, 0x0e, 0x90, 0xfa, 0xb9, 0xe0, 0xff, 0x60, 0x07,
+0x64, 0x80, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x12, 0x0f, 0xfa, 0x40, 0x03, 0x02, 0x0f, 0x6e, 0xe5,
+0x4d, 0x70, 0x19, 0x30, 0x0a, 0x0b, 0x90, 0xff, 0x80, 0x12, 0x1c, 0xbe, 0x12, 0x1a, 0xe8, 0x80,
+0x24, 0x90, 0xff, 0x82, 0x12, 0x1c, 0xbe, 0x12, 0x1a, 0xe8, 0x80, 0x19, 0x15, 0x4d, 0x30, 0x0a,
+0x0b, 0x12, 0x1d, 0x55, 0x12, 0x1c, 0xbc, 0x12, 0x1a, 0xe8, 0x80, 0x09, 0x12, 0x1d, 0x63, 0x12,
+0x1c, 0xbc, 0x12, 0x1a, 0xe8, 0x12, 0x1c, 0xc1, 0x12, 0x1a, 0xa2, 0x60, 0x05, 0x74, 0x01, 0x12,
+0x1a, 0xe8, 0x7f, 0x02, 0x02, 0x32, 0x6e, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02, 0x0f, 0x6e, 0xe5,
+0x3c, 0x45, 0x3b, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x12, 0x1d, 0x79, 0x14, 0x60, 0x2d, 0x14, 0x60,
+0x59, 0x24, 0x02, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xbd, 0xe0, 0x70, 0x04, 0xa3, 0xe0,
+0x64, 0x01, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xb9, 0xe0, 0x60, 0x03, 0x02, 0x0f, 0x6e,
+0x78, 0x67, 0xe6, 0x54, 0xfe, 0xf6, 0xe4, 0xff, 0x02, 0x32, 0x6e, 0xe5, 0x35, 0x20, 0xe1, 0x06,
+0x20, 0xe0, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x35, 0x30, 0xe0, 0x09, 0x90, 0xfa, 0xb9, 0xe0, 0x60,
+0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x35, 0x30, 0xe1, 0x0c, 0x90, 0xfa, 0xb9, 0xe0, 0xd3, 0x94, 0x01,
+0x40, 0x03, 0x02, 0x0f, 0x6e, 0xe4, 0xff, 0x02, 0x32, 0x6e, 0x90, 0xfa, 0xbd, 0xe0, 0x70, 0x02,
+0xa3, 0xe0, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x12, 0x0f, 0xfa, 0x40, 0x03, 0x02, 0x0f, 0x6e, 0xe5,
+0x35, 0x20, 0xe1, 0x06, 0x20, 0xe0, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x35, 0x30, 0xe0, 0x07, 0xe5,
+0x4d, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x4d, 0x70, 0x0f, 0x90, 0xff, 0x82, 0xe0, 0x54, 0xf7,
+0xf0, 0x90, 0xff, 0x80, 0xe0, 0x54, 0xf7, 0xf0, 0x22, 0xe5, 0x4d, 0x24, 0xfe, 0x60, 0x20, 0x24,
+0xfb, 0x60, 0x34, 0x24, 0x06, 0x70, 0x35, 0x30, 0x0a, 0x0c, 0xa2, 0x0a, 0xe4, 0x33, 0xfd, 0x7f,
+0x03, 0x12, 0x2e, 0x79, 0x80, 0x26, 0xe4, 0xfd, 0x7f, 0x03, 0x12, 0x2e, 0x79, 0x80, 0x1d, 0x30,
+0x0a, 0x0c, 0xa2, 0x0a, 0xe4, 0x33, 0xfd, 0x7f, 0x04, 0x12, 0x2e, 0x79, 0x80, 0x0e, 0xe4, 0xfd,
+0x7f, 0x04, 0x12, 0x2e, 0x79, 0x80, 0x05, 0x7f, 0x87, 0x12, 0x31, 0xef, 0x15, 0x4d, 0x30, 0x0a,
+0x0b, 0x12, 0x1d, 0x55, 0xf5, 0x83, 0xe0, 0x54, 0xf7, 0xf0, 0x80, 0x09, 0x12, 0x1d, 0x63, 0xf5,
+0x83, 0xe0, 0x54, 0xf7, 0xf0, 0xe4, 0xff, 0x02, 0x32, 0x6e, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02,
+0x0f, 0x6e, 0xe5, 0x3c, 0x45, 0x3b, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x12, 0x1d, 0x79, 0x14, 0x60,
+0x2d, 0x14, 0x60, 0x55, 0x24, 0x02, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xbd, 0xe0, 0x70,
+0x04, 0xa3, 0xe0, 0x64, 0x01, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xb9, 0xe0, 0x60, 0x03,
+0x02, 0x0f, 0x6e, 0x78, 0x67, 0xe6, 0x44, 0x01, 0xf6, 0xe4, 0xff, 0x02, 0x32, 0x6e, 0xe5, 0x35,
+0x20, 0xe1, 0x06, 0x20, 0xe0, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x35, 0x30, 0xe0, 0x07, 0xe5, 0x4d,
+0x60, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x35, 0x30, 0xe1, 0x0a, 0xe5, 0x4d, 0xd3, 0x94, 0x01, 0x40,
+0x03, 0x02, 0x0f, 0x6e, 0xe4, 0xff, 0x02, 0x32, 0x6e, 0x90, 0xfa, 0xbd, 0xe0, 0x70, 0x02, 0xa3,
+0xe0, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xb9, 0xe0, 0xff, 0x12, 0x32, 0x3f, 0x40, 0x03,
+0x02, 0x0f, 0x6e, 0xe5, 0x35, 0x20, 0xe1, 0x06, 0x20, 0xe0, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x4d,
+0x70, 0x09, 0x30, 0x0a, 0x03, 0x02, 0x1e, 0x14, 0x02, 0x1d, 0xdf, 0xe5, 0x35, 0x20, 0xe1, 0x03,
+0x02, 0x0f, 0x6e, 0x15, 0x4d, 0x30, 0x0a, 0x0b, 0x12, 0x1d, 0x55, 0xf5, 0x83, 0xe0, 0x44, 0x08,
+0xf0, 0x80, 0x09, 0x12, 0x1d, 0x63, 0xf5, 0x83, 0xe0, 0x44, 0x08, 0xf0, 0xe4, 0xff, 0x02, 0x32,
+0x6e, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x3c, 0x45, 0x3b, 0x60, 0x03, 0x02,
+0x0f, 0x6e, 0x90, 0xfa, 0xb9, 0xe0, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x12, 0x1d, 0x79, 0x60, 0x03,
+0x02, 0x0f, 0x6e, 0xe5, 0x35, 0x30, 0xe1, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xbe, 0xe0, 0x90,
+0xff, 0xff, 0xf0, 0xe0, 0x60, 0x05, 0x43, 0x35, 0x01, 0x80, 0x03, 0x53, 0x35, 0xfe, 0xe4, 0xff,
+0x02, 0x32, 0x6e, 0xe5, 0x35, 0x20, 0xe7, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x3c, 0x45, 0x3b, 0x70,
+0x03, 0x02, 0x0f, 0x6e, 0x12, 0x1d, 0x79, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xbd, 0xe0,
+0xfc, 0xa3, 0xe0, 0xfd, 0xec, 0x24, 0xfe, 0x60, 0x3a, 0x14, 0x60, 0x75, 0x24, 0x02, 0x60, 0x03,
+0x02, 0x0f, 0x6e, 0xed, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x12, 0x1c, 0xe0, 0x12, 0x1e, 0x0d, 0x7d,
+0x03, 0x12, 0x0f, 0xb5, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x12, 0x0f, 0x72, 0x90, 0xfa, 0xb6, 0xe0,
+0xfd, 0xa3, 0x12, 0x1d, 0x2b, 0x12, 0x0f, 0xd1, 0x50, 0x02, 0x80, 0x04, 0xae, 0x3b, 0xaf, 0x3c,
+0x02, 0x10, 0x02, 0x12, 0x1c, 0xe0, 0x90, 0xf9, 0x16, 0xe0, 0x30, 0xe4, 0x0d, 0x12, 0x1e, 0x0d,
+0x7d, 0x14, 0x12, 0x0f, 0xb5, 0x60, 0x10, 0x02, 0x0f, 0x6e, 0x12, 0x1e, 0x0d, 0x7d, 0x04, 0x12,
+0x10, 0x09, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x12, 0x0f, 0x72, 0x90, 0xfa, 0xb6, 0xe0, 0xfd, 0xa3,
+0x12, 0x1d, 0x2b, 0x12, 0x0f, 0xd1, 0x50, 0x02, 0x80, 0x04, 0xae, 0x3b, 0xaf, 0x3c, 0x02, 0x10,
+0x02, 0x12, 0x1e, 0x0d, 0x7d, 0x05, 0x12, 0x10, 0x09, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x7b, 0x01,
+0x7a, 0xfa, 0x79, 0xb6, 0x12, 0x1d, 0x28, 0x7d, 0x01, 0x12, 0x26, 0x98, 0x90, 0xfa, 0xb7, 0xe4,
+0x75, 0xf0, 0x03, 0x12, 0x1b, 0x1c, 0x90, 0xfa, 0xbe, 0xe0, 0x90, 0xfa, 0xb5, 0xf0, 0xe4, 0xf5,
+0x4c, 0x90, 0xfa, 0xb5, 0xe0, 0xff, 0xe5, 0x4c, 0xc3, 0x9f, 0x50, 0x24, 0x12, 0x1d, 0x22, 0x12,
+0x10, 0x14, 0xff, 0xfd, 0x90, 0xfa, 0xb7, 0xe4, 0x8d, 0xf0, 0x12, 0x1b, 0x1c, 0x90, 0xfa, 0xb6,
+0xe0, 0xc3, 0x9f, 0xf0, 0xd3, 0x94, 0x00, 0x50, 0x03, 0x02, 0x0f, 0x6e, 0x05, 0x4c, 0x80, 0xd1,
+0x12, 0x1d, 0x22, 0x12, 0x10, 0x14, 0x24, 0xfe, 0xff, 0x90, 0xfa, 0xb6, 0xf0, 0xfd, 0xa3, 0xe4,
+0x75, 0xf0, 0x02, 0x12, 0x1b, 0x1c, 0x7a, 0xf9, 0x79, 0x72, 0x7b, 0x01, 0x8b, 0x36, 0x8a, 0x37,
+0x89, 0x38, 0xe9, 0x24, 0x02, 0xf9, 0xe4, 0x3a, 0xfa, 0x12, 0x1d, 0x28, 0x12, 0x26, 0x98, 0x8f,
+0x4c, 0x05, 0x4c, 0x05, 0x4c, 0x12, 0x1c, 0xc1, 0xe5, 0x4c, 0x12, 0x1a, 0xe8, 0x12, 0x1c, 0xc1,
+0x90, 0x00, 0x01, 0x74, 0x03, 0x12, 0x1a, 0xfa, 0xaf, 0x4c, 0x7e, 0x00, 0xc3, 0xef, 0x95, 0x3c,
+0xee, 0x95, 0x3b, 0x50, 0x02, 0x80, 0x04, 0xae, 0x3b, 0xaf, 0x3c, 0x8e, 0x39, 0x8f, 0x3a, 0x02,
+0x2c, 0xd8, 0x02, 0x0f, 0x6e, 0xe5, 0x35, 0x20, 0xe7, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x3c, 0x64,
+0x01, 0x45, 0x3b, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xb9, 0xe0, 0x60, 0x03, 0x02, 0x0f,
+0x6e, 0x90, 0xfa, 0xbd, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x12, 0x1d,
+0x79, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x35, 0x20, 0xe0, 0x06, 0x20, 0xe1, 0x03, 0x02, 0x0f,
+0x6e, 0x75, 0x36, 0x00, 0x75, 0x37, 0x00, 0x75, 0x38, 0x32, 0x02, 0x0f, 0xf1, 0xe5, 0x35, 0x30,
+0xe7, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x3c, 0x45, 0x3b, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa,
+0xb9, 0xe0, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0xd3, 0x90, 0xfa, 0xbe, 0xe0, 0x94, 0x01, 0x90, 0xfa,
+0xbd, 0xe0, 0x94, 0x00, 0x40, 0x03, 0x02, 0x0f, 0x6e, 0x12, 0x1d, 0x79, 0x60, 0x03, 0x02, 0x0f,
+0x6e, 0xe5, 0x35, 0x20, 0xe0, 0x06, 0x20, 0xe1, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xbe, 0xe0,
+0xf5, 0x32, 0xe5, 0x32, 0x70, 0x08, 0x43, 0x35, 0x01, 0x53, 0x35, 0xfd, 0x80, 0x06, 0x53, 0x35,
+0xfe, 0x43, 0x35, 0x02, 0xe4, 0xff, 0x02, 0x32, 0x6e, 0xe5, 0x35, 0x20, 0xe7, 0x03, 0x02, 0x0f,
+0x6e, 0xe5, 0x3c, 0x64, 0x01, 0x45, 0x3b, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xb9, 0xe0,
+0x60, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xbd, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x60, 0x03, 0x02,
+0x0f, 0x6e, 0x12, 0x1d, 0x79, 0x64, 0x01, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x35, 0x20, 0xe1,
+0x03, 0x02, 0x0f, 0x6e, 0x7f, 0x01, 0x02, 0x32, 0x6e, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02, 0x0f,
+0x6e, 0xe5, 0x3c, 0x45, 0x3b, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0xd3, 0x90, 0xfa, 0xbe, 0xe0, 0x94,
+0x00, 0x90, 0xfa, 0xbd, 0xe0, 0x94, 0x00, 0x40, 0x03, 0x02, 0x0f, 0x6e, 0x12, 0x1d, 0x79, 0x64,
+0x01, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x35, 0x20, 0xe1, 0x03, 0x02, 0x0f, 0x6e, 0xe4, 0xff,
+0x02, 0x32, 0x6e, 0x90, 0xff, 0x01, 0x12, 0x1e, 0x24, 0xef, 0x12, 0x1a, 0xe8, 0x90, 0xfa, 0xb9,
+0x12, 0x1e, 0x24, 0x90, 0x00, 0x01, 0xef, 0x12, 0x1a, 0xfa, 0x90, 0x00, 0x02, 0xe4, 0x12, 0x1a,
+0xfa, 0x74, 0x03, 0x12, 0x1c, 0xb2, 0x90, 0xfa, 0xbd, 0xe0, 0xff, 0xa3, 0xe0, 0x85, 0x38, 0x82,
+0x85, 0x37, 0x83, 0xcf, 0xf0, 0xa3, 0xef, 0xf0, 0x90, 0xff, 0x01, 0xe0, 0x12, 0x1b, 0xfc, 0x09,
+0x7b, 0x02, 0x09, 0x9d, 0x04, 0x09, 0xbf, 0x05, 0x09, 0xeb, 0x06, 0x0a, 0x09, 0x07, 0x0a, 0x27,
+0x08, 0x0a, 0x45, 0x09, 0x0a, 0x63, 0x0b, 0x0b, 0x18, 0x80, 0x0d, 0xb7, 0x81, 0x0d, 0xe8, 0x82,
+0x0b, 0x5f, 0x83, 0x0b, 0xa8, 0x84, 0x0b, 0xc7, 0x85, 0x0c, 0x0c, 0x86, 0x0c, 0x57, 0x87, 0x0c,
+0xe8, 0x88, 0x0d, 0x73, 0x89, 0x0a, 0x81, 0x92, 0x0a, 0x81, 0x93, 0x0d, 0xa0, 0xb0, 0x0e, 0x9b,
+0xc0, 0x0e, 0xc7, 0xc1, 0x0e, 0xd8, 0xc2, 0x00, 0x00, 0x0f, 0x5d, 0xe5, 0x35, 0x20, 0xe7, 0x05,
+0x7f, 0x05, 0x02, 0x31, 0xa9, 0x12, 0x1d, 0x71, 0x60, 0x03, 0x04, 0x70, 0x09, 0xef, 0xfd, 0x7c,
+0x00, 0x7f, 0x07, 0x02, 0x11, 0x5e, 0xe4, 0xfd, 0x7f, 0x07, 0x02, 0x2f, 0xb4, 0xe5, 0x35, 0x20,
+0xe7, 0x05, 0x7f, 0x05, 0x02, 0x31, 0xa9, 0x12, 0x1d, 0x71, 0x60, 0x03, 0x04, 0x70, 0x09, 0xef,
+0xfd, 0x7c, 0x00, 0x7f, 0x0c, 0x02, 0x11, 0x5e, 0xe4, 0xfd, 0x7f, 0x07, 0x02, 0x2f, 0xb4, 0xe5,
+0x35, 0x30, 0xe7, 0x03, 0x02, 0x0f, 0x71, 0x12, 0x1e, 0x42, 0x50, 0x06, 0xe5, 0x3c, 0x45, 0x3b,
+0x70, 0x05, 0x7f, 0x02, 0x02, 0x31, 0xa9, 0x90, 0xfa, 0xb9, 0xe0, 0x24, 0xfe, 0x24, 0xfd, 0x50,
+0x02, 0x80, 0x03, 0x02, 0x32, 0x2c, 0x7f, 0x07, 0x02, 0x31, 0xa9, 0xe5, 0x35, 0x30, 0xe7, 0x03,
+0x02, 0x0f, 0x71, 0x12, 0x1d, 0x71, 0x60, 0x03, 0x04, 0x70, 0x09, 0xef, 0xfd, 0x7c, 0x00, 0x7f,
+0x08, 0x02, 0x11, 0x5e, 0x7f, 0x07, 0x02, 0x31, 0xa9, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02, 0x0f,
+0x71, 0x12, 0x1d, 0x71, 0x60, 0x03, 0x04, 0x70, 0x09, 0xef, 0xfd, 0x7c, 0x00, 0x7f, 0x09, 0x02,
+0x11, 0x5e, 0x7f, 0x07, 0x02, 0x31, 0xa9, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02, 0x0f, 0x71, 0x12,
+0x1d, 0x71, 0x60, 0x03, 0x04, 0x70, 0x09, 0xef, 0xfd, 0x7c, 0x00, 0x7f, 0x0a, 0x02, 0x11, 0x5e,
+0x7f, 0x07, 0x02, 0x31, 0xa9, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02, 0x0f, 0x71, 0x12, 0x1d, 0x71,
+0x60, 0x03, 0x04, 0x70, 0x09, 0xef, 0xfd, 0x7c, 0x00, 0x7f, 0x0b, 0x02, 0x11, 0x5e, 0x7f, 0x07,
+0x02, 0x31, 0xa9, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02, 0x0f, 0x71, 0x12, 0x1d, 0x71, 0x60, 0x03,
+0x04, 0x70, 0x09, 0xef, 0xfd, 0x7c, 0x00, 0x7f, 0x0e, 0x02, 0x11, 0x5e, 0x7f, 0x07, 0x02, 0x31,
+0xa9, 0xe5, 0x35, 0x30, 0xe7, 0x56, 0x12, 0x1d, 0x79, 0x70, 0x4a, 0x90, 0xff, 0x02, 0xe0, 0xf5,
+0x4c, 0xe5, 0x4c, 0xb4, 0x82, 0x05, 0x75, 0x4c, 0x61, 0x80, 0x12, 0xe5, 0x4c, 0xb4, 0x83, 0x05,
+0x75, 0x4c, 0x62, 0x80, 0x08, 0xe5, 0x4c, 0xc4, 0x54, 0xf0, 0x04, 0xf5, 0x4c, 0x12, 0x1c, 0x22,
+0x12, 0x1e, 0x3b, 0x12, 0x25, 0xfa, 0x12, 0x1d, 0x89, 0x12, 0x1a, 0xbb, 0x60, 0x05, 0x12, 0x32,
+0x7a, 0x80, 0x06, 0x85, 0x33, 0x39, 0x85, 0x34, 0x3a, 0x75, 0x36, 0x01, 0x75, 0x37, 0xf9, 0x75,
+0x38, 0x75, 0x02, 0x2c, 0xd8, 0xe4, 0xfd, 0x7f, 0x05, 0x02, 0x2f, 0xb4, 0x12, 0x1d, 0x79, 0x60,
+0x05, 0x7f, 0x05, 0x02, 0x31, 0xa9, 0x12, 0x1e, 0x42, 0x40, 0x05, 0x7f, 0x03, 0x02, 0x31, 0xa9,
+0x90, 0xff, 0x02, 0xe0, 0xf5, 0x4c, 0xe5, 0x4c, 0xb4, 0x82, 0x05, 0x75, 0x4c, 0x61, 0x80, 0x12,
+0xe5, 0x4c, 0xb4, 0x83, 0x05, 0x75, 0x4c, 0x62, 0x80, 0x08, 0xe5, 0x4c, 0xc4, 0x54, 0xf0, 0x04,
+0xf5, 0x4c, 0x12, 0x1c, 0x22, 0x02, 0x32, 0x2c, 0x12, 0x1e, 0x4c, 0x12, 0x2a, 0xc7, 0x12, 0x1d,
+0x33, 0xe0, 0x54, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0xe0, 0x90, 0xfa, 0xba, 0xf0, 0x78, 0x68, 0x12,
+0x1b, 0xd8, 0x90, 0x00, 0x02, 0x12, 0x1a, 0xbb, 0x30, 0xe7, 0xf2, 0x90, 0x00, 0x02, 0xe4, 0x12,
+0x1a, 0xfa, 0x90, 0xfa, 0xba, 0xe0, 0x44, 0x80, 0xff, 0xf0, 0x78, 0x7c, 0xe6, 0xfc, 0x08, 0xe6,
+0x8c, 0x83, 0x12, 0x1d, 0x3b, 0xef, 0xf0, 0x12, 0x32, 0x84, 0xe4, 0xff, 0x02, 0x31, 0xa9, 0x90,
+0xfa, 0xb9, 0xe0, 0x64, 0x01, 0x70, 0x1f, 0x90, 0xfa, 0xbd, 0xe0, 0xff, 0x7e, 0x00, 0x70, 0x06,
+0xa3, 0xe0, 0xf5, 0x90, 0x80, 0x2d, 0xc2, 0xaf, 0xef, 0xf4, 0x52, 0x90, 0x90, 0xfa, 0xbe, 0xe0,
+0x42, 0x90, 0xd2, 0xaf, 0x80, 0x1d, 0x90, 0xfa, 0xbd, 0xe0, 0xff, 0x7e, 0x00, 0x70, 0x06, 0xa3,
+0xe0, 0xf5, 0xb0, 0x80, 0x0e, 0xc2, 0xaf, 0xef, 0xf4, 0x52, 0xb0, 0x90, 0xfa, 0xbe, 0xe0, 0x42,
+0xb0, 0xd2, 0xaf, 0xe4, 0xff, 0x02, 0x31, 0xa9, 0x12, 0x1c, 0xe0, 0x90, 0xfa, 0xb9, 0xe0, 0xb4,
+0x01, 0x0a, 0x12, 0x1c, 0xc1, 0xe5, 0x90, 0x12, 0x1a, 0xe8, 0x80, 0x08, 0x12, 0x1c, 0xc1, 0xe5,
+0xb0, 0x12, 0x1a, 0xe8, 0x02, 0x0f, 0xf1, 0x90, 0xfa, 0xb9, 0xe0, 0xff, 0x24, 0x13, 0x12, 0x1c,
+0xf1, 0x20, 0xe1, 0x33, 0x12, 0x1d, 0x80, 0xef, 0x24, 0xfc, 0x60, 0x18, 0x04, 0x70, 0x28, 0x90,
+0xfa, 0xba, 0xe0, 0x60, 0x09, 0x90, 0xff, 0xa4, 0xe0, 0x44, 0x10, 0xf0, 0x80, 0x19, 0x12, 0x1e,
+0x56, 0xf0, 0x80, 0x13, 0x90, 0xfa, 0xba, 0xe0, 0x60, 0x09, 0x90, 0xff, 0xb4, 0xe0, 0x44, 0x10,
+0xf0, 0x80, 0x04, 0x12, 0x1e, 0x5d, 0xf0, 0xe4, 0xff, 0x02, 0x31, 0xa9, 0x90, 0xfa, 0xb9, 0xe0,
+0xff, 0x24, 0x13, 0x12, 0x1c, 0xf1, 0x20, 0xe1, 0x39, 0x12, 0x1d, 0x80, 0xef, 0x24, 0xfc, 0x60,
+0x1b, 0x04, 0x70, 0x2e, 0x90, 0xfa, 0xba, 0xe0, 0x60, 0x09, 0x90, 0xff, 0xa4, 0xe0, 0x44, 0x20,
+0xf0, 0x80, 0x1f, 0x90, 0xff, 0xa4, 0xe0, 0x54, 0xdf, 0xf0, 0x80, 0x16, 0x90, 0xfa, 0xba, 0xe0,
+0x60, 0x09, 0x90, 0xff, 0xb4, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x07, 0x90, 0xff, 0xb4, 0xe0, 0x54,
+0xdf, 0xf0, 0xe4, 0xff, 0x02, 0x31, 0xa9, 0x12, 0x1d, 0x80, 0x12, 0x1d, 0x71, 0x60, 0x4d, 0x04,
+0x60, 0x03, 0x02, 0x0c, 0xe3, 0x90, 0xfa, 0xba, 0xe0, 0x60, 0x0f, 0x90, 0xff, 0xa4, 0x12, 0x1c,
+0xea, 0x30, 0xe1, 0x6f, 0x12, 0x1e, 0x2c, 0x02, 0x0c, 0xe3, 0x90, 0xff, 0xa4, 0xe0, 0x54, 0xfb,
+0x12, 0x1c, 0xed, 0xfe, 0x30, 0xe1, 0x5c, 0x30, 0xe2, 0x11, 0x30, 0xb4, 0x05, 0x12, 0x1e, 0x2c,
+0x80, 0x51, 0x90, 0xff, 0xa4, 0xe0, 0x54, 0xfd, 0xf0, 0x80, 0x48, 0x30, 0x95, 0x05, 0x12, 0x1e,
+0x2c, 0x80, 0x40, 0x90, 0xff, 0xa4, 0xe0, 0x54, 0xfd, 0xf0, 0x80, 0x37, 0x90, 0xfa, 0xba, 0xe0,
+0x60, 0x12, 0x90, 0xff, 0xb4, 0x12, 0x1c, 0xea, 0x30, 0xe1, 0x28, 0x90, 0xff, 0xb4, 0xe0, 0x44,
+0x02, 0xf0, 0x80, 0x1f, 0x90, 0xff, 0xb4, 0xe0, 0x54, 0xfb, 0x12, 0x1c, 0xed, 0x30, 0xe1, 0x13,
+0x30, 0x93, 0x09, 0x90, 0xff, 0xb4, 0xe0, 0x44, 0x02, 0xf0, 0x80, 0x07, 0x90, 0xff, 0xb4, 0xe0,
+0x54, 0xfd, 0xf0, 0xe4, 0xff, 0x02, 0x31, 0xa9, 0x12, 0x1d, 0x80, 0x90, 0xfa, 0xb9, 0xe0, 0x24,
+0xfc, 0x60, 0x40, 0x04, 0x70, 0x78, 0x90, 0xfa, 0xba, 0xe0, 0x60, 0x1d, 0x90, 0xff, 0xa2, 0xe0,
+0x44, 0x40, 0xf0, 0xa3, 0xe0, 0xff, 0x30, 0xe7, 0x65, 0xd2, 0x03, 0xa3, 0xe0, 0x54, 0xdf, 0xf0,
+0x90, 0xff, 0xa3, 0xef, 0x54, 0x7f, 0xf0, 0x80, 0x55, 0x30, 0x03, 0x0e, 0x90, 0xff, 0xa3, 0xe0,
+0x44, 0x80, 0xf0, 0xc2, 0x03, 0xa3, 0xe0, 0x44, 0x20, 0xf0, 0x90, 0xff, 0xa2, 0xe0, 0x54, 0xbf,
+0xf0, 0x80, 0x3b, 0x90, 0xfa, 0xba, 0xe0, 0x60, 0x1d, 0x90, 0xff, 0xb2, 0xe0, 0x44, 0x40, 0xf0,
+0xa3, 0xe0, 0xff, 0x30, 0xe7, 0x28, 0xd2, 0x04, 0xa3, 0xe0, 0x54, 0xdf, 0xf0, 0x90, 0xff, 0xb3,
+0xef, 0x54, 0x7f, 0xf0, 0x80, 0x18, 0x30, 0x04, 0x0e, 0x90, 0xff, 0xb3, 0xe0, 0x44, 0x80, 0xf0,
+0xc2, 0x04, 0xa3, 0xe0, 0x44, 0x20, 0xf0, 0x90, 0xff, 0xb2, 0xe0, 0x54, 0xbf, 0xf0, 0xe4, 0xff,
+0x02, 0x31, 0xa9, 0x12, 0x1c, 0xe0, 0x90, 0xfa, 0xb9, 0xe0, 0x24, 0xfc, 0x60, 0x0f, 0x04, 0x70,
+0x16, 0x90, 0xff, 0xa6, 0xe0, 0x12, 0x1c, 0xc1, 0x12, 0x1a, 0xe8, 0x80, 0x0a, 0x90, 0xff, 0xb6,
+0xe0, 0x12, 0x1c, 0xc1, 0x12, 0x1a, 0xe8, 0x75, 0x39, 0x00, 0x75, 0x3a, 0x01, 0x02, 0x2c, 0xd8,
+0x90, 0xf9, 0x15, 0x74, 0x01, 0xf0, 0x90, 0xf9, 0x1c, 0x74, 0x19, 0xf0, 0x90, 0xf9, 0x66, 0x74,
+0xff, 0xf0, 0xe4, 0xff, 0x02, 0x31, 0xa9, 0xe4, 0xff, 0x12, 0x31, 0xa9, 0x12, 0x1d, 0xe7, 0x7f,
+0x03, 0x12, 0x12, 0x61, 0x90, 0xf9, 0x16, 0xe0, 0x30, 0xe4, 0x08, 0x90, 0xff, 0x93, 0x74, 0x80,
+0xf0, 0x80, 0x10, 0x90, 0xff, 0xfc, 0xe0, 0x54, 0x7f, 0xf0, 0x7f, 0xff, 0x7e, 0x00, 0x12, 0x30,
+0xd3, 0xc2, 0x90, 0xc2, 0xaf, 0x00, 0x80, 0xfd, 0xe4, 0xf5, 0x4e, 0xf5, 0x4f, 0x90, 0xfa, 0xbf,
+0x74, 0x3e, 0xf0, 0xa3, 0xe4, 0xf0, 0x90, 0xfa, 0xb7, 0xf0, 0xa3, 0x74, 0x15, 0xf0, 0xe0, 0x54,
+0x3f, 0xff, 0xc3, 0x74, 0x40, 0x9f, 0x90, 0xfa, 0xbc, 0xf0, 0xd3, 0x94, 0x00, 0xe4, 0x94, 0x3e,
+0x40, 0x08, 0x90, 0xfa, 0xc0, 0xe0, 0x90, 0xfa, 0xbc, 0xf0, 0x12, 0x0f, 0x98, 0xe5, 0x31, 0x45,
+0x30, 0x70, 0x73, 0x12, 0x1c, 0xfa, 0x90, 0xfa, 0xbf, 0x12, 0x1e, 0x06, 0x60, 0x27, 0xd3, 0xef,
+0x94, 0x40, 0xee, 0x94, 0x00, 0x40, 0x08, 0x90, 0xfa, 0xbc, 0x74, 0x40, 0xf0, 0x80, 0x08, 0x90,
+0xfa, 0xc0, 0xe0, 0x90, 0xfa, 0xbc, 0xf0, 0x12, 0x0f, 0x98, 0xe5, 0x31, 0x45, 0x30, 0x70, 0x46,
+0x12, 0x1c, 0xfa, 0x80, 0xd1, 0x75, 0x4c, 0x02, 0x90, 0xfa, 0xbf, 0xe4, 0xf0, 0xa3, 0x04, 0xf0,
+0x90, 0xfa, 0xb7, 0xe4, 0xf0, 0xa3, 0x74, 0x0f, 0xf0, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x4c, 0x90,
+0xfa, 0xc0, 0xe0, 0xf5, 0x4a, 0x7d, 0x0f, 0x7c, 0x00, 0x12, 0x29, 0x60, 0x75, 0x30, 0x00, 0x8f,
+0x31, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x4c, 0xe4, 0xf5, 0x2d, 0xf5, 0x2e, 0x7d, 0x01, 0x12, 0x26,
+0x98, 0xe4, 0xf5, 0x30, 0xf5, 0x31, 0xaf, 0x31, 0x02, 0x31, 0xa9, 0x12, 0x1d, 0x80, 0x30, 0xe7,
+0x10, 0xe0, 0x54, 0x0f, 0x90, 0xf9, 0x67, 0xf0, 0xd3, 0x94, 0x00, 0x40, 0x15, 0xc2, 0x95, 0x80,
+0x11, 0x90, 0xfa, 0xba, 0xe0, 0x54, 0x0f, 0x90, 0xf9, 0x65, 0xf0, 0xd3, 0x94, 0x00, 0x40, 0x02,
+0xc2, 0x94, 0xe4, 0xff, 0x02, 0x31, 0xa9, 0x12, 0x1e, 0x4c, 0xbf, 0x01, 0x04, 0xd2, 0x93, 0x80,
+0x02, 0xc2, 0x93, 0xe4, 0xff, 0x02, 0x31, 0xa9, 0x12, 0x1d, 0x80, 0x54, 0x03, 0x14, 0x60, 0x0a,
+0x14, 0x60, 0x0f, 0x14, 0x60, 0x08, 0x24, 0x03, 0x70, 0x2b, 0xd2, 0x91, 0x80, 0x27, 0xc2, 0x91,
+0x80, 0x23, 0x12, 0x1e, 0x56, 0x12, 0x0f, 0xc0, 0x60, 0x04, 0xd2, 0x91, 0x80, 0x17, 0x90, 0xff,
+0xa4, 0xe0, 0x44, 0x10, 0x12, 0x0f, 0xc0, 0xff, 0xbf, 0xa0, 0x04, 0xc2, 0x91, 0x80, 0x02, 0xd2,
+0x91, 0x12, 0x1e, 0x56, 0xf0, 0x90, 0xfa, 0xba, 0xe0, 0x54, 0x0c, 0xff, 0x13, 0x13, 0x54, 0x3f,
+0x14, 0x60, 0x0a, 0x14, 0x60, 0x0f, 0x14, 0x60, 0x08, 0x24, 0x03, 0x70, 0x2b, 0xd2, 0x92, 0x80,
+0x27, 0xc2, 0x92, 0x80, 0x23, 0x12, 0x1e, 0x5d, 0x12, 0x0f, 0xe0, 0x60, 0x04, 0xd2, 0x92, 0x80,
+0x17, 0x90, 0xff, 0xb4, 0xe0, 0x44, 0x10, 0x12, 0x0f, 0xe0, 0xff, 0xbf, 0xa0, 0x04, 0xc2, 0x92,
+0x80, 0x02, 0xd2, 0x92, 0x12, 0x1e, 0x5d, 0xf0, 0xe4, 0xff, 0x02, 0x31, 0xa9, 0xe5, 0x35, 0x30,
+0xe7, 0x07, 0xe4, 0xfd, 0x7f, 0x05, 0x02, 0x2f, 0xb4, 0x7f, 0x05, 0x02, 0x31, 0xa9, 0x12, 0x32,
+0x7a, 0x22, 0x7b, 0x01, 0x7a, 0xfa, 0x79, 0xb6, 0x90, 0xfa, 0xb7, 0xe0, 0xf5, 0x2d, 0xa3, 0xe0,
+0xf5, 0x2e, 0x7d, 0x01, 0x12, 0x26, 0x98, 0x90, 0xfa, 0xb7, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0x1b,
+0x1c, 0xab, 0x36, 0xaa, 0x37, 0xa9, 0x38, 0x22, 0xaa, 0x4e, 0xa9, 0x4f, 0x7b, 0xff, 0x90, 0xfa,
+0xb7, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0x90, 0xfa, 0xbc, 0xe0, 0xf5, 0x4a, 0x12, 0x29, 0x60, 0x75,
+0x30, 0x00, 0x8f, 0x31, 0x22, 0x12, 0x23, 0x61, 0x7e, 0x00, 0x8e, 0x30, 0x8f, 0x31, 0xef, 0x22,
+0xf0, 0x7f, 0x01, 0x12, 0x12, 0x61, 0x90, 0xff, 0xa6, 0xe0, 0x90, 0xfa, 0xbb, 0xf0, 0x54, 0xa0,
+0x22, 0x12, 0x26, 0x98, 0x8f, 0x4c, 0x7e, 0x00, 0xc3, 0xef, 0x95, 0x3c, 0xee, 0x95, 0x3b, 0x22,
+0xf0, 0x7f, 0x01, 0x12, 0x12, 0x61, 0x90, 0xff, 0xb6, 0xe0, 0x90, 0xfa, 0xbb, 0xf0, 0x54, 0xa0,
+0x22, 0x75, 0x39, 0x00, 0x75, 0x3a, 0x01, 0x02, 0x2c, 0xd8, 0x90, 0xfa, 0xb9, 0xe0, 0xff, 0x02,
+0x32, 0x3f, 0x8e, 0x39, 0x8f, 0x3a, 0x02, 0x2c, 0xd8, 0x12, 0x23, 0x61, 0x7e, 0x00, 0x8e, 0x30,
+0x8f, 0x31, 0xef, 0x22, 0x7d, 0x01, 0x12, 0x26, 0x98, 0x90, 0xfa, 0xb4, 0xe0, 0x22, 0xef, 0x90,
+0xf8, 0x04, 0xf0, 0x22, 0xc0, 0xa8, 0xc2, 0xaf, 0xee, 0x60, 0x0a, 0xc0, 0x05, 0x7d, 0x7f, 0xdd,
+0xfe, 0xde, 0xfa, 0xd0, 0x05, 0xef, 0xc3, 0x94, 0x15, 0x50, 0x03, 0xd0, 0xa8, 0x22, 0x13, 0x70,
+0x03, 0xd0, 0xa8, 0x22, 0xff, 0xd5, 0x07, 0xfd, 0xd0, 0xa8, 0x22, 0xc0, 0x00, 0xc0, 0x01, 0xc0,
+0x02, 0xc0, 0x04, 0xc0, 0x05, 0xe5, 0x3e, 0x24, 0x08, 0xf8, 0x86, 0x05, 0x53, 0x05, 0x7f, 0x7c,
+0xff, 0x12, 0x10, 0xc0, 0x7f, 0x00, 0x7e, 0x00, 0xe5, 0x43, 0x60, 0x46, 0xfc, 0x90, 0xf9, 0x1d,
+0xe0, 0x54, 0x7f, 0x6d, 0x70, 0x0f, 0xc0, 0x83, 0xc0, 0x82, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff,
+0xa3, 0x15, 0x43, 0x80, 0x07, 0xa3, 0xa3, 0xa3, 0xdc, 0xe6, 0x80, 0x26, 0xdc, 0x06, 0xd0, 0x82,
+0xd0, 0x83, 0x80, 0x1e, 0xe0, 0xf8, 0xa3, 0xe0, 0xf9, 0xa3, 0xe0, 0xfa, 0xd0, 0x82, 0xd0, 0x83,
+0xe8, 0xf0, 0xa3, 0xe9, 0xf0, 0xa3, 0xea, 0xf0, 0xa3, 0xc0, 0x83, 0xc0, 0x82, 0xa3, 0xa3, 0xa3,
+0x80, 0xda, 0x12, 0x11, 0x57, 0xd0, 0x05, 0xd0, 0x04, 0xd0, 0x02, 0xd0, 0x01, 0xd0, 0x00, 0x22,
+0x85, 0xa8, 0x44, 0x75, 0xa8, 0x88, 0xec, 0x70, 0x02, 0x7c, 0x3f, 0x8c, 0x3d, 0x22, 0xe5, 0x3e,
+0x24, 0x08, 0xf8, 0x76, 0x00, 0x12, 0x11, 0xae, 0x80, 0xfb, 0xc0, 0x00, 0xc0, 0x01, 0xc0, 0x02,
+0xc0, 0x04, 0xc0, 0x06, 0x7c, 0xff, 0x12, 0x10, 0xc0, 0xe5, 0x43, 0x60, 0x42, 0xfe, 0x90, 0xf9,
+0x1d, 0xe0, 0x54, 0x7f, 0x6f, 0x70, 0x0b, 0xc0, 0x83, 0xc0, 0x82, 0xa3, 0xa3, 0xa3, 0x15, 0x43,
+0x80, 0x07, 0xa3, 0xa3, 0xa3, 0xde, 0xea, 0x80, 0x26, 0xde, 0x06, 0xd0, 0x82, 0xd0, 0x83, 0x80,
+0xd8, 0xe0, 0xf8, 0xa3, 0xe0, 0xf9, 0xa3, 0xe0, 0xfa, 0xd0, 0x82, 0xd0, 0x83, 0xe8, 0xf0, 0xa3,
+0xe9, 0xf0, 0xa3, 0xea, 0xf0, 0xa3, 0xc0, 0x83, 0xc0, 0x82, 0xa3, 0xa3, 0xa3, 0x80, 0xda, 0x78,
+0x08, 0x08, 0x79, 0x18, 0x09, 0x7c, 0x01, 0xe6, 0x54, 0x7f, 0x6f, 0x70, 0x06, 0x76, 0x00, 0x77,
+0x00, 0x80, 0x06, 0x08, 0x09, 0x0c, 0xbc, 0x08, 0xee, 0x12, 0x11, 0x57, 0xd0, 0x06, 0xd0, 0x04,
+0xd0, 0x02, 0xd0, 0x01, 0xd0, 0x00, 0x22, 0x75, 0x3d, 0x00, 0x85, 0x44, 0xa8, 0x22, 0xc0, 0xf0,
+0xc0, 0x82, 0xc0, 0x83, 0xc3, 0xe5, 0x43, 0x24, 0xe8, 0x50, 0x05, 0x12, 0x11, 0xae, 0x80, 0xf4,
+0xef, 0x60, 0x31, 0x90, 0x31, 0x11, 0xe4, 0x93, 0xc3, 0x9f, 0x40, 0x2f, 0xc0, 0x04, 0x7c, 0xff,
+0x12, 0x10, 0xc0, 0xd0, 0x04, 0x43, 0x07, 0x80, 0xe5, 0x43, 0x75, 0xf0, 0x03, 0xa4, 0x24, 0x1d,
+0xf5, 0x82, 0xe4, 0x34, 0xf9, 0xf5, 0x83, 0xef, 0xf0, 0xec, 0xa3, 0xf0, 0xed, 0xa3, 0xf0, 0x05,
+0x43, 0x12, 0x11, 0x57, 0xd0, 0x83, 0xd0, 0x82, 0xd0, 0xf0, 0x22, 0x02, 0x11, 0xdc, 0xc0, 0x04,
+0x7c, 0x20, 0xd2, 0x8c, 0xd2, 0x8d, 0xd5, 0x04, 0xfd, 0xd0, 0x04, 0x22, 0x75, 0xa8, 0x00, 0x75,
+0x88, 0x00, 0x75, 0xb8, 0x00, 0x75, 0xf0, 0x00, 0x75, 0xd0, 0x00, 0xe4, 0xf8, 0x90, 0xf8, 0x04,
+0xf0, 0x90, 0x00, 0x00, 0xf6, 0x08, 0xb8, 0x00, 0xfb, 0x02, 0x00, 0x00, 0xc2, 0xaf, 0xe4, 0x90,
+0xff, 0x48, 0xf0, 0x90, 0xff, 0x50, 0xf0, 0x90, 0xff, 0x08, 0xf0, 0x90, 0xff, 0x10, 0xf0, 0x90,
+0xff, 0x80, 0xf0, 0xa3, 0xa3, 0xf0, 0xd2, 0xb1, 0xc2, 0xb0, 0x7e, 0xff, 0x7f, 0xff, 0x12, 0x10,
+0x24, 0x7e, 0xff, 0x7f, 0xff, 0x12, 0x10, 0x24, 0x7e, 0xff, 0x7f, 0xff, 0x12, 0x10, 0x24, 0xd2,
+0xb0, 0xd2, 0xb1, 0x7e, 0xff, 0x7f, 0xff, 0x12, 0x10, 0x24, 0x7e, 0xff, 0x7f, 0xff, 0x12, 0x10,
+0x24, 0x7e, 0xff, 0x7f, 0xff, 0x12, 0x10, 0x24, 0x80, 0xcc, 0xc3, 0xee, 0x94, 0x02, 0x50, 0x04,
+0x7e, 0x03, 0x7f, 0xe8, 0xef, 0xf4, 0xff, 0xee, 0xf4, 0xfe, 0x0f, 0xbf, 0x00, 0x01, 0x0e, 0x8f,
+0x42, 0x8e, 0x41, 0x22, 0xc3, 0xef, 0x94, 0xbc, 0xee, 0x94, 0x02, 0x50, 0x04, 0x7e, 0x07, 0x7f,
+0xd0, 0xef, 0xf4, 0xff, 0xee, 0xf4, 0xfe, 0x0f, 0xbf, 0x00, 0x01, 0x0e, 0x8f, 0x40, 0x8e, 0x3f,
+0x22, 0xef, 0x70, 0x01, 0x22, 0xc0, 0x00, 0xc0, 0xa8, 0xc2, 0xaf, 0xe5, 0x3e, 0x24, 0x18, 0xf8,
+0xa6, 0x07, 0xe5, 0x3e, 0x24, 0x08, 0xf8, 0xc6, 0x54, 0x7f, 0xf6, 0xd0, 0xa8, 0xe6, 0x30, 0xe7,
+0x03, 0xd0, 0x00, 0x22, 0x12, 0x11, 0xae, 0x80, 0xf4, 0xc0, 0x00, 0x7f, 0x01, 0xef, 0x24, 0x08,
+0xf8, 0xe6, 0x60, 0x09, 0x0f, 0xbf, 0x08, 0xf5, 0x12, 0x11, 0xae, 0x80, 0xee, 0xd0, 0x00, 0x22,
+0xc0, 0xf0, 0xc0, 0x82, 0xc0, 0x83, 0xc0, 0x00, 0xc0, 0x06, 0xc0, 0x04, 0xed, 0x24, 0x10, 0xf8,
+0x76, 0x9a, 0xed, 0x75, 0xf0, 0x21, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x34, 0xf8, 0xf5, 0x83,
+0xc0, 0x82, 0xc0, 0x83, 0xa3, 0xa3, 0xe4, 0x78, 0x0d, 0xf0, 0xa3, 0xd8, 0xfc, 0xef, 0x54, 0x7f,
+0x75, 0xf0, 0x02, 0xa4, 0x24, 0xf3, 0xf5, 0x82, 0xe5, 0xf0, 0x34, 0x30, 0xf5, 0x83, 0xe4, 0x93,
+0xfe, 0x74, 0x01, 0x93, 0xfc, 0xd0, 0x83, 0xd0, 0x82, 0xec, 0xf0, 0xa3, 0xee, 0xf0, 0xed, 0x24,
+0x08, 0xf8, 0xef, 0x44, 0x80, 0xf6, 0xd0, 0x04, 0xd0, 0x06, 0xd0, 0x00, 0xd0, 0x83, 0xd0, 0x82,
+0xd0, 0xf0, 0x22, 0x75, 0x3e, 0x00, 0x75, 0x43, 0x00, 0x7a, 0x08, 0x79, 0x18, 0x78, 0x08, 0x76,
+0x00, 0x77, 0x00, 0x08, 0x09, 0xda, 0xf8, 0x90, 0xf8, 0x04, 0xe0, 0xfc, 0x90, 0x31, 0x11, 0xe4,
+0x93, 0xc3, 0x9c, 0x50, 0x05, 0xe4, 0x90, 0xf8, 0x04, 0xf0, 0x78, 0x08, 0x74, 0x80, 0x44, 0x7f,
+0xf6, 0x74, 0x01, 0x44, 0x10, 0xf5, 0x89, 0x75, 0xb8, 0x00, 0xd2, 0xab, 0xd2, 0xa9, 0x22, 0x75,
+0x81, 0x8b, 0xd2, 0x8e, 0xd2, 0x8c, 0xd2, 0xaf, 0xe5, 0x43, 0x60, 0x36, 0xff, 0x90, 0xf9, 0x1d,
+0xe0, 0x54, 0x80, 0x60, 0x28, 0x78, 0x08, 0x79, 0x08, 0xe0, 0x54, 0x7f, 0xfa, 0x7b, 0x00, 0xe6,
+0x54, 0x7f, 0xb5, 0x02, 0x02, 0x7b, 0xff, 0x08, 0xd9, 0xf5, 0xeb, 0x70, 0x10, 0xea, 0xf0, 0xc0,
+0x07, 0x12, 0x12, 0x89, 0xad, 0x07, 0xaf, 0x02, 0x12, 0x12, 0xa0, 0xd0, 0x07, 0xa3, 0xa3, 0xa3,
+0xdf, 0xce, 0x12, 0x11, 0xae, 0x80, 0xc1, 0x8f, 0x24, 0x12, 0x2a, 0xc7, 0x12, 0x22, 0xb5, 0xa3,
+0xa3, 0xe0, 0xa3, 0x30, 0xe7, 0x28, 0x78, 0x7e, 0x12, 0x22, 0x99, 0xe0, 0x44, 0x01, 0xf0, 0x12,
+0x22, 0xfa, 0x12, 0x22, 0x9d, 0xe0, 0x20, 0xe0, 0xf6, 0x12, 0x23, 0x50, 0x74, 0x02, 0xf0, 0x12,
+0x22, 0xda, 0xe0, 0xa3, 0x30, 0xe5, 0x07, 0x12, 0x23, 0x50, 0xe0, 0x44, 0x01, 0xf0, 0x78, 0x80,
+0xe6, 0xfe, 0x08, 0xe6, 0xff, 0x8e, 0x83, 0x24, 0x08, 0x12, 0x22, 0xa1, 0xe0, 0xfd, 0x12, 0x23,
+0x39, 0x8a, 0x83, 0x24, 0x0a, 0x12, 0x22, 0xa1, 0xed, 0xf0, 0x12, 0x23, 0x06, 0x24, 0x07, 0x12,
+0x22, 0xa1, 0xe0, 0xff, 0x12, 0x23, 0x5a, 0x24, 0x09, 0x12, 0x22, 0xa1, 0xef, 0xf0, 0x90, 0xf9,
+0x16, 0xe0, 0x30, 0xe4, 0x20, 0x08, 0x12, 0x22, 0xb7, 0xc0, 0x83, 0xc0, 0x82, 0xa3, 0xe0, 0x25,
+0xe0, 0xff, 0x05, 0x82, 0xd5, 0x82, 0x02, 0x15, 0x83, 0x15, 0x82, 0xe0, 0x33, 0xd0, 0x82, 0xd0,
+0x83, 0xf0, 0xa3, 0xef, 0xf0, 0x12, 0x22, 0xb5, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xec, 0xff, 0x12,
+0x23, 0x39, 0x8a, 0x83, 0x24, 0x08, 0x12, 0x22, 0xa1, 0xef, 0xf0, 0xed, 0x12, 0x23, 0x5a, 0x24,
+0x07, 0x12, 0x22, 0xa1, 0xed, 0xf0, 0x12, 0x22, 0xa9, 0xe0, 0x30, 0xe6, 0x0a, 0x12, 0x23, 0x41,
+0x24, 0x09, 0x12, 0x22, 0xa1, 0xe4, 0xf0, 0x12, 0x22, 0xa9, 0xe0, 0xff, 0x30, 0xe7, 0x1b, 0x12,
+0x23, 0x1e, 0x24, 0x09, 0x12, 0x22, 0xa1, 0xe0, 0x60, 0x09, 0x12, 0x22, 0xa9, 0xef, 0x44, 0x02,
+0xf0, 0x80, 0x07, 0x12, 0x22, 0xa9, 0xef, 0x54, 0xfd, 0xf0, 0x78, 0x7e, 0x12, 0x22, 0xb7, 0xa3,
+0xa3, 0xe0, 0xff, 0x53, 0x07, 0xc7, 0x08, 0xe6, 0xfc, 0x08, 0xe6, 0xfd, 0x12, 0x22, 0xe0, 0xa3,
+0xe0, 0x30, 0xe3, 0x12, 0x8d, 0x82, 0x8c, 0x83, 0xe5, 0x82, 0x24, 0x05, 0x12, 0x22, 0xa1, 0xe0,
+0x90, 0x32, 0x51, 0x93, 0x42, 0x07, 0x53, 0x07, 0xfb, 0x12, 0x23, 0x1e, 0x24, 0x06, 0x12, 0x22,
+0xa1, 0xe0, 0x60, 0x03, 0x43, 0x07, 0x04, 0x53, 0x07, 0xfc, 0x78, 0x80, 0x12, 0x23, 0x29, 0x24,
+0x04, 0x12, 0x22, 0xa1, 0xe0, 0x42, 0x07, 0x43, 0x07, 0x80, 0x12, 0x23, 0x39, 0xf5, 0x82, 0x8a,
+0x83, 0xa3, 0xa3, 0xef, 0xf0, 0x12, 0x23, 0x5a, 0x24, 0x04, 0x12, 0x22, 0xa1, 0xe0, 0xff, 0x8d,
+0x82, 0x8c, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0x30, 0xe1, 0x05, 0x53, 0x07, 0xdf,
+0x80, 0x03, 0x43, 0x07, 0x20, 0xec, 0x30, 0xe4, 0x05, 0x53, 0x07, 0xef, 0x80, 0x03, 0x43, 0x07,
+0x10, 0x12, 0x22, 0xa9, 0xe0, 0xfe, 0x54, 0x03, 0x60, 0x73, 0x53, 0x07, 0xdf, 0xee, 0x30, 0xe1,
+0x69, 0x12, 0x23, 0x1e, 0x24, 0x09, 0x12, 0x22, 0xa1, 0xe0, 0x12, 0x1b, 0xfc, 0x15, 0x2c, 0x00,
+0x15, 0x60, 0x01, 0x15, 0x65, 0x03, 0x15, 0x60, 0x05, 0x15, 0x65, 0x07, 0x15, 0x60, 0x09, 0x15,
+0x65, 0x0b, 0x15, 0x60, 0x0d, 0x15, 0x65, 0x0f, 0x00, 0x00, 0x15, 0x6d, 0xe5, 0x24, 0x64, 0x03,
+0x70, 0x21, 0x90, 0xf9, 0x16, 0xe0, 0x30, 0xe2, 0x0d, 0x30, 0xb4, 0x05, 0x43, 0x07, 0x02, 0x80,
+0x2c, 0x53, 0x07, 0xfd, 0x80, 0x27, 0x30, 0x95, 0x05, 0x43, 0x07, 0x02, 0x80, 0x1f, 0x53, 0x07,
+0xfd, 0x80, 0x1a, 0x30, 0x93, 0x05, 0x43, 0x07, 0x02, 0x80, 0x12, 0x53, 0x07, 0xfd, 0x80, 0x0d,
+0x43, 0x07, 0x02, 0x80, 0x08, 0x53, 0x07, 0xfd, 0x80, 0x03, 0x53, 0x07, 0xfd, 0x12, 0x23, 0x27,
+0x24, 0x04, 0x12, 0x22, 0xa1, 0xef, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0xff,
+0x12, 0x22, 0xa9, 0xe0, 0xfe, 0x54, 0x03, 0x70, 0x03, 0x02, 0x16, 0x60, 0xee, 0x20, 0xe1, 0x03,
+0x02, 0x16, 0x5d, 0x08, 0x12, 0x23, 0x20, 0x24, 0x09, 0x12, 0x22, 0xa1, 0xe0, 0x12, 0x1b, 0xfc,
+0x15, 0xbf, 0x00, 0x15, 0xf5, 0x01, 0x15, 0xf5, 0x03, 0x16, 0x29, 0x05, 0x16, 0x29, 0x07, 0x16,
+0x0f, 0x09, 0x16, 0x0f, 0x0b, 0x16, 0x43, 0x0d, 0x16, 0x43, 0x0f, 0x00, 0x00, 0x16, 0x60, 0xe5,
+0x24, 0x64, 0x03, 0x70, 0x23, 0x90, 0xf9, 0x16, 0xe0, 0x30, 0xe2, 0x0f, 0x30, 0xb1, 0x06, 0x53,
+0x07, 0x7f, 0x02, 0x16, 0x60, 0x43, 0x07, 0x80, 0x02, 0x16, 0x60, 0x30, 0x94, 0x05, 0x53, 0x07,
+0x7f, 0x80, 0x7d, 0x43, 0x07, 0x80, 0x80, 0x78, 0x30, 0x92, 0x05, 0x53, 0x07, 0x7f, 0x80, 0x70,
+0x43, 0x07, 0x80, 0x80, 0x6b, 0xe5, 0x24, 0xb4, 0x03, 0x09, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xef,
+0xf0, 0x80, 0x07, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xdf, 0xf0, 0x53, 0x07, 0x7f, 0x80, 0x51, 0xe5,
+0x24, 0xb4, 0x03, 0x09, 0x90, 0xff, 0x9e, 0xe0, 0x44, 0x10, 0xf0, 0x80, 0x07, 0x90, 0xff, 0x9e,
+0xe0, 0x44, 0x20, 0xf0, 0x53, 0x07, 0x7f, 0x80, 0x37, 0xe5, 0x24, 0xb4, 0x03, 0x09, 0x90, 0xff,
+0x9e, 0xe0, 0x54, 0xef, 0xf0, 0x80, 0x07, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xdf, 0xf0, 0x43, 0x07,
+0x80, 0x80, 0x1d, 0xe5, 0x24, 0xb4, 0x03, 0x09, 0x90, 0xff, 0x9e, 0xe0, 0x44, 0x10, 0xf0, 0x80,
+0x07, 0x90, 0xff, 0x9e, 0xe0, 0x44, 0x20, 0xf0, 0x43, 0x07, 0x80, 0x80, 0x03, 0x53, 0x07, 0x7f,
+0x12, 0x22, 0xda, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0x30, 0xe0, 0x05, 0x43, 0x07, 0x20, 0x80, 0x03,
+0x53, 0x07, 0xdf, 0xec, 0x30, 0xe3, 0x05, 0x43, 0x07, 0x40, 0x80, 0x03, 0x53, 0x07, 0xbf, 0xec,
+0x30, 0xe0, 0x05, 0x43, 0x07, 0x10, 0x80, 0x03, 0x53, 0x07, 0xef, 0xed, 0x30, 0xe4, 0x05, 0x43,
+0x07, 0x08, 0x80, 0x03, 0x53, 0x07, 0xf7, 0xed, 0x30, 0xe5, 0x05, 0x43, 0x07, 0x04, 0x80, 0x03,
+0x53, 0x07, 0xfb, 0xed, 0x30, 0xe6, 0x05, 0x43, 0x07, 0x01, 0x80, 0x03, 0x53, 0x07, 0xfe, 0xed,
+0x30, 0xe7, 0x05, 0x43, 0x07, 0x02, 0x80, 0x03, 0x53, 0x07, 0xfd, 0x78, 0x7e, 0x12, 0x22, 0xdc,
+0xa3, 0xef, 0xf0, 0x12, 0x32, 0x84, 0x7f, 0x00, 0x22, 0x90, 0xff, 0xfa, 0x74, 0x08, 0xf0, 0xa3,
+0x74, 0x16, 0xf0, 0x90, 0xff, 0xf9, 0x74, 0x02, 0xf0, 0x7b, 0x01, 0x7a, 0xfa, 0x79, 0xcf, 0xe4,
+0xfd, 0x12, 0x23, 0x61, 0x90, 0xfa, 0xcf, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0x1b, 0x1c, 0x12, 0x19,
+0x92, 0xe5, 0x23, 0x30, 0xe7, 0x02, 0xd2, 0x02, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x24, 0x90, 0xfa,
+0xcf, 0xe0, 0xf5, 0x2d, 0xa3, 0xe0, 0xf5, 0x2e, 0x7d, 0x01, 0x12, 0x26, 0x98, 0x90, 0xfa, 0xcf,
+0xe4, 0xf0, 0xa3, 0x74, 0x0b, 0xf0, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x23, 0x75, 0x2d, 0x00, 0xf5,
+0x2e, 0x7d, 0x01, 0x12, 0x26, 0x98, 0xe5, 0x23, 0x24, 0x80, 0x90, 0xff, 0xf8, 0xf0, 0xe5, 0x23,
+0x64, 0x07, 0x60, 0x1e, 0xe5, 0x23, 0x64, 0x06, 0x60, 0x18, 0xe5, 0x23, 0x64, 0x14, 0x60, 0x12,
+0xe5, 0x23, 0x64, 0x41, 0x60, 0x0c, 0xe5, 0x23, 0x64, 0x1a, 0x70, 0x46, 0xe5, 0x24, 0x64, 0x02,
+0x70, 0x40, 0xe5, 0x23, 0xb4, 0x07, 0x16, 0xd2, 0x94, 0xd2, 0x95, 0xd2, 0x92, 0xd2, 0x93, 0x90,
+0xf9, 0x16, 0xe0, 0x44, 0x02, 0xf0, 0xa3, 0xe0, 0x44, 0x02, 0xf0, 0x80, 0x1e, 0xe5, 0x23, 0xb4,
+0x41, 0x12, 0x90, 0xf9, 0x16, 0xe0, 0x44, 0x06, 0xf0, 0xa3, 0xe0, 0x44, 0x06, 0xf0, 0xd2, 0xb1,
+0xd2, 0xb4, 0x80, 0x07, 0x90, 0xf9, 0x16, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0xf9, 0x17, 0xe0, 0x44,
+0x01, 0xf0, 0xe5, 0x23, 0x64, 0x42, 0x60, 0x0c, 0xe5, 0x23, 0x64, 0x43, 0x60, 0x06, 0xe5, 0x23,
+0x64, 0x44, 0x70, 0x2e, 0x90, 0xf9, 0x16, 0xe0, 0xff, 0xe5, 0x23, 0xb4, 0x44, 0x04, 0x7e, 0x40,
+0x80, 0x02, 0x7e, 0x00, 0xee, 0x24, 0x80, 0x4f, 0x90, 0xf9, 0x16, 0xf0, 0xa3, 0xe0, 0xff, 0xe5,
+0x23, 0xb4, 0x44, 0x04, 0x7e, 0x40, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x24, 0x80, 0x4f, 0x90, 0xf9,
+0x17, 0xf0, 0x90, 0xfa, 0xcf, 0xe4, 0xf0, 0xa3, 0x74, 0x0d, 0xf0, 0x12, 0x19, 0x92, 0x90, 0xff,
+0xf5, 0xe5, 0x23, 0xf0, 0xe4, 0xf5, 0x35, 0xf5, 0x33, 0xf5, 0x34, 0xf5, 0x32, 0x12, 0x1e, 0x34,
+0x12, 0x1c, 0xe0, 0x12, 0x1e, 0x3b, 0x90, 0xf9, 0x6a, 0x12, 0x1b, 0xf3, 0x90, 0xf9, 0x6f, 0x12,
+0x1b, 0xf3, 0x90, 0xff, 0xff, 0xe4, 0xf0, 0x90, 0xff, 0x83, 0xe0, 0xe4, 0xf0, 0x90, 0xff, 0x81,
 0x74, 0x80, 0xf0, 0xa3, 0x74, 0x84, 0xf0, 0x90, 0xff, 0x80, 0xf0, 0xe4, 0xf5, 0x23, 0xe5, 0x23, 
-0x12, 0x1c, 0xa7, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x23, 0x12, 0x1c, 0xb5, 0xf5, 0x83, 0xe4, 0xf0, 
-0x05, 0x23, 0xe5, 0x23, 0xb4, 0x07, 0xe7, 0x78, 0x7a, 0x76, 0xfe, 0x08, 0x76, 0xf0, 0x90, 0x31, 
-0x4d, 0xe4, 0x93, 0xff, 0x78, 0x78, 0xf6, 0xfd, 0xad, 0x07, 0x90, 0x31, 0x5a, 0xe4, 0x93, 0xff, 
-0x08, 0xf6, 0xff, 0xed, 0x54, 0x0f, 0xfd, 0x12, 0x1c, 0x97, 0x74, 0x84, 0xf0, 0xed, 0x75, 0xf0, 
+0x12, 0x1d, 0x57, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x23, 0x12, 0x1d, 0x65, 0xf5, 0x83, 0xe4, 0xf0,
+0x05, 0x23, 0xe5, 0x23, 0xb4, 0x07, 0xe7, 0x78, 0x7a, 0x76, 0xfe, 0x08, 0x76, 0xf0, 0x90, 0x32,
+0x0a, 0xe4, 0x93, 0xff, 0x78, 0x78, 0xf6, 0xfd, 0xad, 0x07, 0x90, 0x32, 0x17, 0xe4, 0x93, 0xff,
+0x08, 0xf6, 0xff, 0xed, 0x54, 0x0f, 0xfd, 0x12, 0x1d, 0x47, 0x74, 0x84, 0xf0, 0xed, 0x75, 0xf0,
 0x08, 0xa4, 0x24, 0x47, 0xf5, 0x82, 0xe4, 0x34, 0xff, 0xf5, 0x83, 0xef, 0xf0, 0xc3, 0x74, 0xf0, 
-0x9f, 0x78, 0x7b, 0xf6, 0x74, 0xfe, 0x94, 0x00, 0x18, 0x12, 0x1c, 0x28, 0xce, 0xc3, 0x13, 0xce, 
-0x13, 0xd8, 0xf9, 0xff, 0xed, 0x12, 0x1c, 0xf8, 0xef, 0xf0, 0xed, 0x12, 0x1d, 0x1e, 0xe4, 0xf5, 
-0x23, 0xe5, 0x23, 0x90, 0x31, 0x47, 0x93, 0xff, 0x78, 0x78, 0xf6, 0xfd, 0xe5, 0x23, 0x25, 0xe0, 
-0x24, 0x4e, 0xf5, 0x82, 0xe4, 0x34, 0x31, 0xf5, 0x83, 0xe4, 0x93, 0x08, 0xf6, 0xed, 0x30, 0xe7, 
-0x53, 0x18, 0xe6, 0x54, 0x0f, 0xf9, 0x12, 0x1c, 0x97, 0x12, 0x1d, 0x06, 0x24, 0x47, 0xf5, 0x82, 
-0xe4, 0x34, 0xff, 0x12, 0x1c, 0x18, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0xff, 0xe9, 0x12, 
-0x1c, 0xf8, 0xef, 0xf0, 0x12, 0x1c, 0x1f, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0x12, 0x1d, 
-0x0b, 0x24, 0x45, 0xf5, 0x82, 0xe4, 0x34, 0xff, 0xf5, 0x83, 0xef, 0xf0, 0xe9, 0x12, 0x1d, 0x1e, 
+0x9f, 0x78, 0x7b, 0xf6, 0x74, 0xfe, 0x94, 0x00, 0x18, 0x12, 0x1c, 0xd8, 0xce, 0xc3, 0x13, 0xce,
+0x13, 0xd8, 0xf9, 0xff, 0xed, 0x12, 0x1d, 0xa8, 0xef, 0xf0, 0xed, 0x12, 0x1d, 0xce, 0xe4, 0xf5,
+0x23, 0xe5, 0x23, 0x90, 0x32, 0x04, 0x93, 0xff, 0x78, 0x78, 0xf6, 0xfd, 0xe5, 0x23, 0x25, 0xe0,
+0x24, 0x0b, 0xf5, 0x82, 0xe4, 0x34, 0x32, 0xf5, 0x83, 0xe4, 0x93, 0x08, 0xf6, 0xed, 0x30, 0xe7,
+0x53, 0x18, 0xe6, 0x54, 0x0f, 0xf9, 0x12, 0x1d, 0x47, 0x12, 0x1d, 0xb6, 0x24, 0x47, 0xf5, 0x82,
+0xe4, 0x34, 0xff, 0x12, 0x1c, 0xc8, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0xff, 0xe9, 0x12,
+0x1d, 0xa8, 0xef, 0xf0, 0x12, 0x1c, 0xcf, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0x12, 0x1d,
+0xbb, 0x24, 0x45, 0xf5, 0x82, 0xe4, 0x34, 0xff, 0xf5, 0x83, 0xef, 0xf0, 0xe9, 0x12, 0x1d, 0xce,
 0xe9, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x46, 0xf5, 0x82, 0xe4, 0x34, 0xff, 0xf5, 0x83, 0x74, 0x80, 
-0xf0, 0x02, 0x18, 0xb7, 0x78, 0x78, 0xe6, 0x54, 0x0f, 0xf9, 0x12, 0x1c, 0xea, 0x12, 0x1d, 0x06, 
-0x24, 0x07, 0xf5, 0x82, 0xe4, 0x34, 0xff, 0x12, 0x1c, 0x18, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 
-0xf9, 0x12, 0x1d, 0x0b, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34, 0xff, 0xf5, 0x83, 0xef, 0xf0, 0x12, 
-0x1c, 0x1f, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0x12, 0x1d, 0x0b, 0x24, 0x05, 0xf5, 0x82, 
+0xf0, 0x02, 0x19, 0x67, 0x78, 0x78, 0xe6, 0x54, 0x0f, 0xf9, 0x12, 0x1d, 0x9a, 0x12, 0x1d, 0xb6,
+0x24, 0x07, 0xf5, 0x82, 0xe4, 0x34, 0xff, 0x12, 0x1c, 0xc8, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8,
+0xf9, 0x12, 0x1d, 0xbb, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34, 0xff, 0xf5, 0x83, 0xef, 0xf0, 0x12,
+0x1c, 0xcf, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0x12, 0x1d, 0xbb, 0x24, 0x05, 0xf5, 0x82,
 0xe4, 0x34, 0xff, 0xf5, 0x83, 0xef, 0xf0, 0xe9, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x02, 0xf5, 0x82, 
 0xe4, 0x34, 0xff, 0xf5, 0x83, 0xe4, 0xf0, 0xe9, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x06, 0xf5, 0x82, 
 0xe4, 0x34, 0xff, 0xf5, 0x83, 0xe4, 0xf0, 0x05, 0x23, 0xe5, 0x23, 0x64, 0x04, 0x60, 0x03, 0x02, 
-0x17, 0xe1, 0x90, 0x31, 0x4c, 0xe4, 0x93, 0xff, 0x78, 0x78, 0xf6, 0x12, 0x1c, 0xe8, 0xe4, 0xf0, 
-0x90, 0x31, 0x4b, 0x93, 0xff, 0xf6, 0x12, 0x1c, 0x95, 0xe4, 0xf0, 0x90, 0xff, 0xfd, 0x74, 0x05, 
-0xf0, 0x22, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x23, 0x90, 0xfa, 0xcc, 0xe4, 0x75, 0xf0, 0x01, 0x12, 
-0x1a, 0x82, 0x85, 0xf0, 0x2e, 0xf5, 0x2d, 0x7d, 0x01, 0x02, 0x25, 0xd7, 0xe7, 0x09, 0xf6, 0x08, 
+0x18, 0x91, 0x90, 0x32, 0x09, 0xe4, 0x93, 0xff, 0x78, 0x78, 0xf6, 0x12, 0x1d, 0x98, 0xe4, 0xf0,
+0x90, 0x32, 0x08, 0x93, 0xff, 0xf6, 0x12, 0x1d, 0x45, 0xe4, 0xf0, 0x90, 0xff, 0xfd, 0x74, 0x05,
+0xf0, 0x22, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x23, 0x90, 0xfa, 0xcf, 0xe4, 0x75, 0xf0, 0x01, 0x12,
+0x1b, 0x32, 0x85, 0xf0, 0x2e, 0xf5, 0x2d, 0x7d, 0x01, 0x02, 0x26, 0x98, 0xe7, 0x09, 0xf6, 0x08,
 0xdf, 0xfa, 0x80, 0x46, 0xe7, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x3e, 0x88, 0x82, 0x8c, 0x83, 
 0xe7, 0x09, 0xf0, 0xa3, 0xdf, 0xfa, 0x80, 0x32, 0xe3, 0x09, 0xf6, 0x08, 0xdf, 0xfa, 0x80, 0x78, 
 0xe3, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x70, 0x88, 0x82, 0x8c, 0x83, 0xe3, 0x09, 0xf0, 0xa3, 
@@ -445,7 +456,7 @@ static unsigned char IMAGE_ARRAY_NAME[] =
 0x82, 0x8a, 0x83, 0xe4, 0x93, 0xa3, 0xf2, 0x08, 0xdf, 0xf9, 0x80, 0xcc, 0x88, 0xf0, 0xef, 0x60, 
 0x01, 0x0e, 0x4e, 0x60, 0xc3, 0x88, 0xf0, 0xed, 0x24, 0x02, 0xb4, 0x04, 0x00, 0x50, 0xb9, 0xf5, 
 0x82, 0xeb, 0x24, 0x02, 0xb4, 0x04, 0x00, 0x50, 0xaf, 0x23, 0x23, 0x45, 0x82, 0x23, 0x90, 0x19, 
-0x4c, 0x73, 0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22, 0xbb, 
+0xfc, 0x73, 0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22, 0xbb,
 0xfe, 0x02, 0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22, 0xbb, 0x01, 0x0c, 0xe5, 0x82, 
 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50, 0x06, 0xe9, 0x25, 0x82, 0xf8, 
 0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22, 0xe5, 0x82, 0x29, 0xf5, 0x82, 
@@ -469,364 +480,365 @@ static unsigned char IMAGE_ARRAY_NAME[] =
 0xe0, 0xf9, 0x22, 0xeb, 0xf0, 0xa3, 0xea, 0xf0, 0xa3, 0xe9, 0xf0, 0x22, 0xd0, 0x83, 0xd0, 0x82, 
 0xf8, 0xe4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3, 0x93, 0xf8, 0x74, 0x01, 
 0x93, 0xf5, 0x82, 0x88, 0x83, 0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xef, 0xa3, 0xa3, 0xa3, 
-0x80, 0xdf, 0xab, 0x36, 0xaa, 0x37, 0xa9, 0x38, 0xe5, 0x4c, 0x12, 0x1a, 0x38, 0x74, 0x01, 0x25, 
+0x80, 0xdf, 0xab, 0x36, 0xaa, 0x37, 0xa9, 0x38, 0xe5, 0x4c, 0x12, 0x1a, 0xe8, 0x74, 0x01, 0x25,
 0x38, 0xf5, 0x38, 0xe4, 0x35, 0x37, 0xf5, 0x37, 0xab, 0x36, 0xfa, 0xa9, 0x38, 0x74, 0x11, 0x12, 
-0x1a, 0x38, 0x74, 0x01, 0x25, 0x38, 0xf5, 0x38, 0xe4, 0x35, 0x37, 0xf5, 0x37, 0x90, 0xff, 0x06, 
-0xe0, 0xab, 0x36, 0xaa, 0x37, 0xa9, 0x38, 0x12, 0x1a, 0x38, 0x74, 0x01, 0x25, 0x38, 0xf5, 0x38, 
-0xe4, 0x35, 0x37, 0xf5, 0x37, 0xab, 0x36, 0xfa, 0xa9, 0x38, 0xe4, 0x12, 0x1a, 0x38, 0x04, 0x25, 
+0x1a, 0xe8, 0x74, 0x01, 0x25, 0x38, 0xf5, 0x38, 0xe4, 0x35, 0x37, 0xf5, 0x37, 0x90, 0xff, 0x06,
+0xe0, 0xab, 0x36, 0xaa, 0x37, 0xa9, 0x38, 0x12, 0x1a, 0xe8, 0x74, 0x01, 0x25, 0x38, 0xf5, 0x38,
+0xe4, 0x35, 0x37, 0xf5, 0x37, 0xab, 0x36, 0xfa, 0xa9, 0x38, 0xe4, 0x12, 0x1a, 0xe8, 0x04, 0x25,
 0x38, 0xf5, 0x38, 0xe4, 0x35, 0x37, 0xf5, 0x37, 0xab, 0x36, 0xfa, 0xa9, 0x38, 0xe4, 0x12, 0x1a, 
-0x38, 0x04, 0x25, 0x38, 0xf5, 0x38, 0xe4, 0x35, 0x37, 0xf5, 0x37, 0x90, 0xff, 0x04, 0xe0, 0xab, 
-0x36, 0xaa, 0x37, 0xa9, 0x38, 0x12, 0x1a, 0x38, 0x74, 0x01, 0x25, 0x38, 0xf5, 0x38, 0xe4, 0x35, 
-0x37, 0xf5, 0x37, 0x90, 0xff, 0x05, 0xe0, 0xab, 0x36, 0xaa, 0x37, 0xa9, 0x38, 0x12, 0x1a, 0x38, 
+0xe8, 0x04, 0x25, 0x38, 0xf5, 0x38, 0xe4, 0x35, 0x37, 0xf5, 0x37, 0x90, 0xff, 0x04, 0xe0, 0xab,
+0x36, 0xaa, 0x37, 0xa9, 0x38, 0x12, 0x1a, 0xe8, 0x74, 0x01, 0x25, 0x38, 0xf5, 0x38, 0xe4, 0x35,
+0x37, 0xf5, 0x37, 0x90, 0xff, 0x05, 0xe0, 0xab, 0x36, 0xaa, 0x37, 0xa9, 0x38, 0x12, 0x1a, 0xe8,
 0x74, 0x01, 0x25, 0x38, 0xf5, 0x38, 0xe4, 0x35, 0x37, 0xf5, 0x37, 0x22, 0xf5, 0x83, 0xe0, 0x54, 
 0x08, 0xab, 0x36, 0xaa, 0x37, 0xa9, 0x38, 0x22, 0xf5, 0x83, 0xef, 0xf0, 0xfd, 0x7c, 0x00, 0xc3, 
 0x78, 0x7b, 0xe6, 0x9d, 0xf6, 0x18, 0xe6, 0x9c, 0xf6, 0xe6, 0xfe, 0x08, 0xe6, 0x78, 0x03, 0x22, 
-0x75, 0x36, 0x01, 0x75, 0x37, 0xf9, 0x75, 0x38, 0x6f, 0x22, 0xe0, 0x44, 0x04, 0xf0, 0x74, 0x12, 
-0x2f, 0xf5, 0x82, 0xe4, 0x34, 0xf9, 0xf5, 0x83, 0xe0, 0x22, 0x90, 0xfa, 0xb9, 0xe0, 0xff, 0x7e, 
-0x00, 0xc3, 0x90, 0xfa, 0xbd, 0xe0, 0x9f, 0xf0, 0x90, 0xfa, 0xbc, 0xe0, 0x9e, 0xf0, 0x90, 0xfa, 
-0xb4, 0xee, 0x8f, 0xf0, 0x12, 0x1a, 0x6c, 0xef, 0x25, 0x4f, 0xf5, 0x4f, 0xee, 0x35, 0x4e, 0xf5, 
-0x4e, 0x22, 0x7b, 0x01, 0x7a, 0xfa, 0x79, 0xb1, 0x90, 0xfa, 0xb4, 0xe0, 0xf5, 0x2d, 0xa3, 0xe0, 
+0x75, 0x36, 0x01, 0x75, 0x37, 0xf9, 0x75, 0x38, 0x72, 0x22, 0xe0, 0x44, 0x04, 0xf0, 0x74, 0x13,
+0x2f, 0xf5, 0x82, 0xe4, 0x34, 0xf9, 0xf5, 0x83, 0xe0, 0x22, 0x90, 0xfa, 0xbc, 0xe0, 0xff, 0x7e,
+0x00, 0xc3, 0x90, 0xfa, 0xc0, 0xe0, 0x9f, 0xf0, 0x90, 0xfa, 0xbf, 0xe0, 0x9e, 0xf0, 0x90, 0xfa,
+0xb7, 0xee, 0x8f, 0xf0, 0x12, 0x1b, 0x1c, 0xef, 0x25, 0x4f, 0xf5, 0x4f, 0xee, 0x35, 0x4e, 0xf5,
+0x4e, 0x22, 0x7b, 0x01, 0x7a, 0xfa, 0x79, 0xb4, 0x90, 0xfa, 0xb7, 0xe0, 0xf5, 0x2d, 0xa3, 0xe0,
 0xf5, 0x2e, 0x22, 0x78, 0x7c, 0xe6, 0xfe, 0x08, 0xe6, 0x8e, 0x83, 0x24, 0x04, 0xf5, 0x82, 0xe4, 
 0x35, 0x83, 0xf5, 0x83, 0x22, 0x54, 0x0f, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x40, 0xf5, 0x82, 0xe4, 
 0x34, 0xff, 0xf5, 0x83, 0x22, 0xe5, 0x4d, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x48, 0xf5, 0x82, 0xe4, 
 0x34, 0xff, 0x22, 0xe5, 0x4d, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x08, 0xf5, 0x82, 0xe4, 0x34, 0xff, 
-0x22, 0x90, 0xfa, 0xb6, 0xe0, 0xff, 0x24, 0xfc, 0x22, 0x90, 0xff, 0x00, 0xe0, 0x54, 0x1f, 0x22, 
-0x90, 0xfa, 0xbb, 0xe0, 0x90, 0xfa, 0xb7, 0xf0, 0x22, 0x75, 0x33, 0x00, 0x8f, 0x34, 0x90, 0xf9, 
-0x6c, 0x12, 0x1b, 0x3a, 0x90, 0x00, 0x02, 0x22, 0x54, 0x0f, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 
+0x22, 0x90, 0xfa, 0xb9, 0xe0, 0xff, 0x24, 0xfc, 0x22, 0x90, 0xff, 0x00, 0xe0, 0x54, 0x1f, 0x22,
+0x90, 0xfa, 0xbe, 0xe0, 0x90, 0xfa, 0xba, 0xf0, 0x22, 0x75, 0x33, 0x00, 0x8f, 0x34, 0x90, 0xf9,
+0x6f, 0x12, 0x1b, 0xea, 0x90, 0x00, 0x02, 0x22, 0x54, 0x0f, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00,
 0xf5, 0x82, 0xe4, 0x34, 0xff, 0xf5, 0x83, 0x22, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x41, 0xf5, 0x82, 
 0xe4, 0x34, 0xff, 0xf5, 0x83, 0x22, 0x74, 0x80, 0xf0, 0x08, 0xe6, 0xff, 0xe9, 0x75, 0xf0, 0x08, 
-0xa4, 0x22, 0x74, 0xaf, 0x25, 0x22, 0xf5, 0x82, 0xe4, 0x34, 0xfa, 0xf5, 0x83, 0x22, 0x75, 0xf0, 
+0xa4, 0x22, 0x74, 0xb2, 0x25, 0x22, 0xf5, 0x82, 0xe4, 0x34, 0xfa, 0xf5, 0x83, 0x22, 0x75, 0xf0,
 0x08, 0xa4, 0x24, 0x42, 0xf5, 0x82, 0xe4, 0x34, 0xff, 0xf5, 0x83, 0x74, 0x80, 0xf0, 0x22, 0x90, 
 0xff, 0x82, 0xe0, 0x44, 0x08, 0xf0, 0x22, 0x90, 0xff, 0xfe, 0xe0, 0x44, 0x03, 0xf0, 0x90, 0xff, 
 0xfc, 0xe0, 0x54, 0xfd, 0xf0, 0x22, 0x78, 0x67, 0xe6, 0x54, 0xfd, 0xf6, 0x90, 0xff, 0xfd, 0x74, 
-0x65, 0xf0, 0x22, 0x12, 0x1b, 0x1c, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x4e, 0x22, 0x7b, 0x01, 0x7a, 
-0xfa, 0x79, 0xb4, 0x22, 0x90, 0xff, 0x80, 0xe0, 0x44, 0x08, 0xf0, 0x22, 0x90, 0xff, 0x83, 0xe0, 
-0x54, 0x7f, 0xf0, 0x22, 0xe0, 0xff, 0x90, 0xf9, 0x67, 0x02, 0x1b, 0x3a, 0x90, 0xff, 0xa4, 0xe0, 
+0x65, 0xf0, 0x22, 0x12, 0x1b, 0xcc, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x4e, 0x22, 0x7b, 0x01, 0x7a,
+0xfa, 0x79, 0xb7, 0x22, 0x90, 0xff, 0x80, 0xe0, 0x44, 0x08, 0xf0, 0x22, 0x90, 0xff, 0x83, 0xe0,
+0x54, 0x7f, 0xf0, 0x22, 0xe0, 0xff, 0x90, 0xf9, 0x6a, 0x02, 0x1b, 0xea, 0x90, 0xff, 0xa4, 0xe0,
 0x44, 0x02, 0xf0, 0x22, 0x75, 0x39, 0x01, 0x75, 0x3a, 0x09, 0x22, 0x7b, 0x01, 0x7a, 0xf9, 0x79, 
-0x6f, 0x22, 0xd3, 0xe5, 0x3c, 0x94, 0x08, 0xe5, 0x3b, 0x94, 0x01, 0x22, 0x90, 0xfa, 0xbb, 0xe0, 
-0xff, 0x90, 0xfa, 0xb7, 0xf0, 0x22, 0x90, 0xff, 0xa4, 0xe0, 0x54, 0xef, 0x22, 0x90, 0xff, 0xb4, 
-0xe0, 0x54, 0xef, 0x22, 0x12, 0x10, 0x03, 0x78, 0x88, 0xef, 0xf6, 0x12, 0x2a, 0x06, 0x12, 0x22, 
-0x4a, 0x8e, 0x83, 0x24, 0x09, 0x12, 0x21, 0xf3, 0xe0, 0xfd, 0x12, 0x22, 0x2d, 0x90, 0x00, 0x0a, 
-0x12, 0x22, 0x52, 0x24, 0x0a, 0x12, 0x21, 0xf3, 0xe0, 0x90, 0x00, 0x0b, 0x12, 0x1a, 0x4a, 0x12, 
-0x22, 0x4a, 0xf5, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0xf5, 0x53, 0x12, 0x22, 0x56, 0x24, 
-0x04, 0x12, 0x21, 0xf3, 0xe0, 0xf5, 0x54, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xe0, 0xf5, 0x55, 
+0x72, 0x22, 0xd3, 0xe5, 0x3c, 0x94, 0x08, 0xe5, 0x3b, 0x94, 0x01, 0x22, 0x90, 0xfa, 0xbe, 0xe0,
+0xff, 0x90, 0xfa, 0xba, 0xf0, 0x22, 0x90, 0xff, 0xa4, 0xe0, 0x54, 0xef, 0x22, 0x90, 0xff, 0xb4,
+0xe0, 0x54, 0xef, 0x22, 0x12, 0x10, 0x4b, 0x78, 0x88, 0xef, 0xf6, 0x12, 0x2a, 0xc7, 0x12, 0x22,
+0xfa, 0x8e, 0x83, 0x24, 0x09, 0x12, 0x22, 0xa1, 0xe0, 0xfd, 0x12, 0x22, 0xe8, 0x90, 0x00, 0x0a,
+0x12, 0x23, 0x02, 0x24, 0x0a, 0x12, 0x22, 0xa1, 0xe0, 0x90, 0x00, 0x0b, 0x12, 0x1a, 0xfa, 0x12,
+0x22, 0xfa, 0xf5, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0xf5, 0x53, 0x12, 0x23, 0x06, 0x24,
+0x04, 0x12, 0x22, 0xa1, 0xe0, 0xf5, 0x54, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xe0, 0xf5, 0x55,
 0xe5, 0x53, 0xc4, 0x13, 0x13, 0x13, 0x54, 0x01, 0x78, 0x88, 0xf6, 0xd3, 0x94, 0x00, 0x40, 0x06, 
-0xe5, 0x54, 0x30, 0xe1, 0x01, 0x06, 0x78, 0x88, 0xe6, 0x12, 0x22, 0x2c, 0x90, 0x00, 0x0c, 0xef, 
-0x12, 0x1a, 0x4a, 0x78, 0x80, 0x12, 0x22, 0x09, 0xa3, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x53, 
-0x07, 0x0c, 0x53, 0x06, 0xe6, 0xe5, 0x53, 0x30, 0xe5, 0x03, 0x43, 0x07, 0x01, 0xe5, 0x54, 0x20, 
-0xe5, 0x0e, 0xe5, 0x53, 0x54, 0x7f, 0x70, 0x08, 0xe5, 0x53, 0x20, 0xe7, 0x03, 0x43, 0x07, 0x02, 
-0xe5, 0x53, 0x30, 0xe3, 0x03, 0x43, 0x07, 0x10, 0xe5, 0x53, 0x30, 0xe2, 0x03, 0x43, 0x07, 0x20, 
-0xe5, 0x53, 0x54, 0x03, 0x60, 0x03, 0x43, 0x07, 0x40, 0xe5, 0x53, 0x30, 0xe1, 0x03, 0x43, 0x07, 
-0x80, 0xe5, 0x53, 0x30, 0xe4, 0x03, 0x43, 0x06, 0x01, 0xe5, 0x53, 0x30, 0xe6, 0x03, 0x43, 0x06, 
-0x08, 0xe5, 0x54, 0x20, 0xe4, 0x0e, 0xe5, 0x53, 0x54, 0x7f, 0x70, 0x08, 0xe5, 0x53, 0x20, 0xe7, 
-0x03, 0x43, 0x06, 0x10, 0x53, 0x07, 0xfb, 0x53, 0x06, 0x79, 0x90, 0x00, 0x05, 0xee, 0x8f, 0xf0, 
-0x12, 0x1a, 0xef, 0xe5, 0x55, 0x30, 0xe3, 0x12, 0x54, 0x30, 0xff, 0xc4, 0x54, 0x0f, 0x12, 0x22, 
-0x2c, 0x90, 0x00, 0x08, 0xef, 0x12, 0x1a, 0x4a, 0x80, 0x0a, 0x12, 0x22, 0x2d, 0x90, 0x00, 0x08, 
-0xe4, 0x12, 0x1a, 0x4a, 0xe5, 0x55, 0x54, 0x03, 0x12, 0x22, 0x2c, 0x90, 0x00, 0x07, 0xef, 0x12, 
-0x1a, 0x4a, 0xe5, 0x55, 0x54, 0x04, 0xff, 0xc3, 0x13, 0x90, 0x00, 0x09, 0x12, 0x1a, 0x4a, 0x90, 
-0x00, 0x07, 0x12, 0x1a, 0x0b, 0x70, 0x13, 0x12, 0x22, 0x2d, 0xe9, 0x24, 0x09, 0xf9, 0xe4, 0x3a, 
-0xfa, 0x12, 0x19, 0xf2, 0xff, 0xc3, 0x13, 0x12, 0x1a, 0x38, 0x12, 0x22, 0x78, 0x24, 0x08, 0x12, 
-0x21, 0xf3, 0xe0, 0xfe, 0x8d, 0x82, 0x8c, 0x83, 0xe5, 0x82, 0x24, 0x07, 0x12, 0x21, 0xf3, 0xe0, 
-0xfd, 0xee, 0xed, 0x12, 0x22, 0x2c, 0x90, 0x00, 0x03, 0xee, 0x8f, 0xf0, 0x12, 0x1a, 0xef, 0x12, 
-0x31, 0xc7, 0x7d, 0x0a, 0xe4, 0xff, 0x12, 0x2f, 0x18, 0x02, 0x10, 0x86, 0x90, 0xfa, 0xe3, 0xe0, 
-0xb4, 0x03, 0x06, 0x7e, 0x00, 0x7f, 0x40, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x08, 0x90, 0xfa, 0xd7, 
-0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x90, 0x00, 0x05, 0x12, 0x1a, 0x0b, 0xff, 0x7e, 0x00, 0x90, 0xfa, 
-0xd3, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x70, 0x03, 0x7f, 0x08, 0x22, 0x90, 0x00, 0x08, 0x12, 0x1a, 
-0x98, 0xff, 0x90, 0xfa, 0xd5, 0xe5, 0xf0, 0xf0, 0xa3, 0xef, 0xf0, 0xae, 0x02, 0xaf, 0x01, 0x8e, 
-0x50, 0x8f, 0x51, 0x74, 0x0a, 0x25, 0x51, 0xf5, 0x51, 0xe4, 0x35, 0x50, 0xf5, 0x50, 0x90, 0xfa, 
-0xd8, 0xe0, 0xff, 0x14, 0xfe, 0x90, 0xfa, 0xd6, 0xe0, 0x5e, 0xfe, 0xc3, 0xef, 0x9e, 0xff, 0x90, 
-0xfa, 0xda, 0xf0, 0xc3, 0x90, 0xfa, 0xd4, 0xe0, 0x9f, 0x90, 0xfa, 0xd3, 0xe0, 0x94, 0x00, 0x50, 
-0x06, 0xa3, 0xe0, 0x90, 0xfa, 0xda, 0xf0, 0x12, 0x1f, 0xfb, 0x60, 0x03, 0xe0, 0xff, 0x22, 0x12, 
-0x2d, 0x5a, 0x90, 0xfa, 0xd3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x4e, 0x60, 0x2b, 0x90, 0xfa, 0xd7, 
-0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xd3, 0xef, 0x9d, 0xee, 0x9c, 0x40, 0x07, 0xe0, 0x90, 0xfa, 0xda, 
-0xf0, 0x80, 0x08, 0x90, 0xfa, 0xd4, 0xe0, 0x90, 0xfa, 0xda, 0xf0, 0x12, 0x1f, 0xfb, 0x60, 0x03, 
-0xe0, 0xff, 0x22, 0x12, 0x2d, 0x5a, 0x80, 0xca, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x52, 0xe4, 0xf5, 
-0x2d, 0xf5, 0x2e, 0x7d, 0x01, 0x12, 0x25, 0xd7, 0x7f, 0x00, 0x22, 0xaa, 0x50, 0xa9, 0x51, 0x7b, 
-0x01, 0x90, 0xfa, 0xd5, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0x90, 0xfa, 0xda, 0xe0, 0xf5, 0x4a, 0x12, 
-0x28, 0x9f, 0x90, 0xfa, 0xd9, 0xef, 0xf0, 0x22, 0xef, 0x24, 0xae, 0x60, 0x52, 0x24, 0xfe, 0x60, 
-0x2e, 0x24, 0xfe, 0x70, 0x03, 0x02, 0x20, 0xbb, 0x24, 0x06, 0x60, 0x03, 0x02, 0x21, 0x03, 0x78, 
-0x71, 0xe6, 0x54, 0xfb, 0xf6, 0x90, 0xff, 0xa5, 0xe0, 0xf5, 0x22, 0x44, 0x0f, 0xf0, 0x74, 0x33, 
-0x90, 0xfa, 0x91, 0xf0, 0xe5, 0x22, 0xa3, 0xf0, 0x90, 0xfa, 0xaf, 0x74, 0x01, 0xf0, 0x22, 0x78, 
-0x72, 0xe6, 0x54, 0xfb, 0xf6, 0x90, 0xff, 0xb5, 0xe0, 0xf5, 0x22, 0x44, 0x0f, 0xf0, 0x74, 0x43, 
-0x90, 0xfa, 0x93, 0xf0, 0xe5, 0x22, 0xa3, 0xf0, 0x90, 0xfa, 0xb0, 0x74, 0x01, 0xf0, 0x22, 0x90, 
-0xfa, 0x9d, 0xe0, 0xa3, 0x20, 0xe5, 0x03, 0x02, 0x21, 0x03, 0x90, 0xff, 0xa6, 0xe0, 0x90, 0xfa, 
-0xca, 0xf0, 0xa3, 0xf0, 0x90, 0xfa, 0xca, 0xe0, 0xff, 0x54, 0x0f, 0xfe, 0x60, 0x10, 0x90, 0xff, 
-0xa6, 0x12, 0x22, 0x5d, 0x90, 0xff, 0xa6, 0xe0, 0x90, 0xfa, 0xca, 0xf0, 0x80, 0xe6, 0x90, 0xfa, 
-0xcb, 0xe0, 0xff, 0x74, 0x34, 0xfe, 0x12, 0x2c, 0xb4, 0xef, 0x70, 0x57, 0x90, 0xfa, 0xcb, 0xe0, 
-0xff, 0x74, 0x34, 0x90, 0xfa, 0x95, 0xf0, 0xef, 0xa3, 0xf0, 0x22, 0x90, 0xfa, 0xa7, 0xe0, 0xa3, 
-0x30, 0xe5, 0x40, 0x90, 0xff, 0xb6, 0xe0, 0x90, 0xfa, 0xca, 0xf0, 0xa3, 0xf0, 0x90, 0xfa, 0xca, 
-0xe0, 0xff, 0x54, 0x0f, 0xfe, 0x60, 0x10, 0x90, 0xff, 0xb6, 0x12, 0x22, 0x5d, 0x90, 0xff, 0xb6, 
-0xe0, 0x90, 0xfa, 0xca, 0xf0, 0x80, 0xe6, 0x90, 0xfa, 0xcb, 0xe0, 0xff, 0x74, 0x44, 0xfe, 0x12, 
-0x2c, 0xb4, 0xef, 0x70, 0x0e, 0x90, 0xfa, 0xcb, 0xe0, 0xff, 0x74, 0x44, 0x90, 0xfa, 0x97, 0xf0, 
-0xef, 0xa3, 0xf0, 0x22, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 
-0x00, 0xc0, 0x00, 0xc0, 0x01, 0xc0, 0x02, 0xc0, 0x03, 0xc0, 0x04, 0xc0, 0x05, 0xc0, 0x06, 0xc0, 
-0x07, 0x90, 0xff, 0x92, 0xe0, 0xff, 0x90, 0xfa, 0xc9, 0xf0, 0x90, 0xff, 0x92, 0xe4, 0xf0, 0xef, 
-0x12, 0x1b, 0x4c, 0x21, 0xbb, 0x26, 0x21, 0xbb, 0x2e, 0x21, 0x5e, 0x30, 0x21, 0x5e, 0x32, 0x21, 
-0x6c, 0x38, 0x21, 0x7e, 0x3a, 0x21, 0xb0, 0x3e, 0x21, 0x9b, 0x44, 0x21, 0x90, 0x46, 0x21, 0xa6, 
-0x50, 0x21, 0xa6, 0x52, 0x21, 0xa6, 0x54, 0x21, 0xa6, 0x56, 0x00, 0x00, 0x21, 0xc0, 0x90, 0xfa, 
-0xc9, 0xe0, 0xfd, 0x7c, 0x00, 0x7f, 0x01, 0x12, 0x11, 0x16, 0x80, 0x62, 0x7c, 0x00, 0x7d, 0x01, 
-0x7f, 0x03, 0x12, 0x11, 0x16, 0x90, 0xff, 0xfe, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x50, 0x7c, 0x00, 
-0x7d, 0x01, 0x7f, 0x02, 0x12, 0x11, 0x16, 0x90, 0xff, 0xfe, 0xe0, 0x44, 0x40, 0xf0, 0x80, 0x3e, 
-0x7c, 0x00, 0x7d, 0x01, 0x7f, 0x05, 0x12, 0x11, 0x16, 0x80, 0x33, 0x7c, 0x00, 0x7d, 0x01, 0x7f, 
-0x06, 0x12, 0x11, 0x16, 0x80, 0x28, 0x90, 0xfa, 0xc9, 0xe0, 0xff, 0x12, 0x20, 0x18, 0x80, 0x1e, 
-0x7c, 0x00, 0x7d, 0x01, 0x7f, 0x04, 0x12, 0x11, 0x16, 0x80, 0x13, 0x12, 0x27, 0x8d, 0x80, 0x0e, 
-0x90, 0xfa, 0xc9, 0xe0, 0x24, 0x00, 0xff, 0xe4, 0x34, 0xff, 0xfe, 0x12, 0x2c, 0xb4, 0xd0, 0x07, 
-0xd0, 0x06, 0xd0, 0x05, 0xd0, 0x04, 0xd0, 0x03, 0xd0, 0x02, 0xd0, 0x01, 0xd0, 0x00, 0xd0, 0xd0, 
-0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0x78, 0x7c, 0xe6, 0xfe, 0x08, 0xe6, 0x24, 
-0x04, 0x8e, 0x83, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0x22, 0x74, 0x12, 0x25, 0x24, 0xf5, 
-0x82, 0xe4, 0x34, 0xf9, 0xf5, 0x83, 0x22, 0x78, 0x7c, 0xe6, 0xfe, 0x08, 0xe6, 0xf5, 0x82, 0x8e, 
-0x83, 0x22, 0x78, 0x80, 0xe6, 0xfe, 0x08, 0xe6, 0xaa, 0x06, 0xf8, 0xac, 0x02, 0x7d, 0x01, 0x7b, 
-0xff, 0x7a, 0x31, 0x79, 0x99, 0x7e, 0x00, 0x7f, 0x0a, 0x02, 0x19, 0xcc, 0xff, 0x90, 0xf9, 0x6c, 
-0x02, 0x1b, 0x3a, 0x90, 0xf9, 0x67, 0x12, 0x1b, 0x3a, 0x90, 0x00, 0x04, 0x02, 0x1a, 0x0b, 0xe6, 
-0xfc, 0x08, 0xe6, 0xf5, 0x82, 0x8c, 0x83, 0xa3, 0xa3, 0x22, 0x78, 0x7e, 0xe6, 0xfe, 0x08, 0xe6, 
-0xff, 0x22, 0xed, 0x12, 0x1a, 0x4a, 0x8f, 0x82, 0x8e, 0x83, 0xe5, 0x82, 0x22, 0xef, 0xf0, 0x90, 
-0xfa, 0xcb, 0xe0, 0x54, 0x0f, 0x4e, 0xfe, 0xf0, 0xef, 0x54, 0xf0, 0x4e, 0xf0, 0x22, 0x08, 0xe6, 
-0xfc, 0x08, 0xe6, 0x8c, 0x83, 0x24, 0x09, 0x22, 0x78, 0x7e, 0xe6, 0xfc, 0x08, 0xe6, 0xfd, 0x8c, 
-0x83, 0x22, 0xa6, 0x07, 0xe6, 0x24, 0x6e, 0xf8, 0xe6, 0x22, 0x78, 0x7e, 0xe6, 0xfa, 0x08, 0xe6, 
-0xfb, 0x22, 0x26, 0xf6, 0x18, 0xee, 0x36, 0xf6, 0x22, 0x8b, 0x82, 0x8a, 0x83, 0xe5, 0x82, 0x22, 
-0x8b, 0x25, 0x8a, 0x26, 0x89, 0x27, 0x8d, 0x28, 0x90, 0xfa, 0xcf, 0xe4, 0xf0, 0xa3, 0x74, 0x02, 
-0xf0, 0x7b, 0x01, 0x7a, 0xfa, 0x79, 0xce, 0x90, 0xfa, 0xcf, 0xe0, 0xf5, 0x2d, 0xa3, 0xe0, 0xf5, 
-0x2e, 0x7d, 0x01, 0x12, 0x25, 0xd7, 0x90, 0xfa, 0xce, 0xe0, 0x65, 0x28, 0x60, 0x46, 0xa3, 0xe0, 
-0xff, 0xa3, 0xe0, 0xa3, 0xcf, 0xf0, 0xa3, 0xef, 0xf0, 0x12, 0x23, 0x2f, 0x90, 0xfa, 0xce, 0xe0, 
-0xff, 0x90, 0xfa, 0xd1, 0xe4, 0x8f, 0xf0, 0x12, 0x1a, 0x6c, 0x12, 0x23, 0x2f, 0x90, 0xfa, 0xd1, 
-0xe0, 0xff, 0xa3, 0xe0, 0x90, 0xfa, 0xcf, 0xcf, 0xf0, 0xa3, 0xef, 0xf0, 0x90, 0xfa, 0xce, 0xe0, 
-0xa3, 0x75, 0xf0, 0x00, 0x12, 0x1a, 0x6c, 0x90, 0xfa, 0xcf, 0xe4, 0x75, 0xf0, 0x04, 0x12, 0x1a, 
-0x6c, 0x02, 0x22, 0xb1, 0x90, 0xfa, 0xd0, 0xe0, 0x24, 0x01, 0xff, 0x90, 0xfa, 0xcf, 0xe0, 0x34, 
-0x00, 0xab, 0x25, 0xaa, 0x26, 0xa9, 0x27, 0x8f, 0xf0, 0x12, 0x1a, 0xd0, 0x7f, 0x00, 0x22, 0x7b, 
-0x01, 0x7a, 0xfa, 0x79, 0xce, 0x90, 0xfa, 0xcf, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x1a, 0x6c, 0x85, 
-0xf0, 0x2e, 0xf5, 0x2d, 0x7d, 0x01, 0x02, 0x25, 0xd7, 0x8f, 0x62, 0x12, 0x2a, 0x06, 0x12, 0x22, 
-0x4a, 0x8e, 0x83, 0x24, 0x0b, 0x12, 0x21, 0xf3, 0xe0, 0x54, 0xfb, 0xf0, 0x44, 0x02, 0xf0, 0x08, 
-0x12, 0x22, 0x3f, 0xe0, 0xa3, 0x30, 0xe5, 0x0c, 0x12, 0x22, 0x56, 0x24, 0x0b, 0x12, 0x21, 0xf3, 
-0xe0, 0x44, 0x01, 0xf0, 0x78, 0x7c, 0xe6, 0xfe, 0x08, 0xe6, 0xff, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 
-0x54, 0xb8, 0xfd, 0xf0, 0xe5, 0x62, 0x24, 0xfe, 0x44, 0x20, 0xfc, 0x4d, 0xf0, 0xe5, 0x82, 0x24, 
-0x04, 0x12, 0x21, 0xf3, 0xe0, 0x54, 0xb8, 0xf0, 0x4c, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0x74, 
-0x03, 0xf0, 0x18, 0xe6, 0xfe, 0x08, 0xe6, 0xff, 0x8e, 0x83, 0x24, 0x05, 0x12, 0x21, 0xf3, 0xc0, 
-0x83, 0xc0, 0x82, 0xe0, 0xfd, 0x74, 0x96, 0x25, 0x62, 0xf5, 0x82, 0xe4, 0x34, 0xfa, 0xf5, 0x83, 
-0xe0, 0x54, 0xfc, 0x44, 0x03, 0xfc, 0xed, 0x4c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 
-0x83, 0xe0, 0x44, 0x80, 0xf0, 0xe5, 0x82, 0x24, 0x04, 0x12, 0x21, 0xf3, 0xe0, 0x44, 0x80, 0xf0, 
-0x12, 0x31, 0xc7, 0x74, 0x6e, 0x25, 0x62, 0xf8, 0x74, 0x04, 0x46, 0xf6, 0x7f, 0x00, 0x22, 0x12, 
-0x10, 0x03, 0x7f, 0x02, 0x12, 0x12, 0x19, 0x78, 0x67, 0xe6, 0x44, 0x02, 0xf6, 0xd2, 0xb0, 0xd2, 
-0xb1, 0x90, 0xf9, 0x15, 0xe0, 0x30, 0xe7, 0x07, 0x90, 0xff, 0x9e, 0xe4, 0xf0, 0x80, 0x36, 0xd2, 
-0xb3, 0x90, 0xff, 0xa4, 0xe0, 0x90, 0xfa, 0x7b, 0xf0, 0x90, 0xff, 0xb4, 0xe0, 0x90, 0xfa, 0x7c, 
-0xf0, 0x90, 0xff, 0xa2, 0xe0, 0x90, 0xfa, 0x79, 0xf0, 0x90, 0xff, 0xb2, 0xe0, 0x90, 0xfa, 0x7a, 
-0xf0, 0x90, 0xff, 0xa4, 0x74, 0x30, 0xf0, 0x90, 0xff, 0xb4, 0xf0, 0x90, 0xff, 0xa2, 0x74, 0x40, 
-0xf0, 0x90, 0xff, 0xb2, 0xf0, 0x90, 0xfa, 0xe4, 0xe5, 0xa8, 0xf0, 0x75, 0xa8, 0x81, 0x90, 0xff, 
-0x92, 0xe0, 0x60, 0x04, 0xe4, 0xf0, 0x80, 0xf6, 0x90, 0xff, 0xfd, 0x74, 0x3a, 0xf0, 0x43, 0x87, 
-0x01, 0x00, 0x00, 0x00, 0x90, 0xfa, 0x7b, 0xe0, 0x90, 0xff, 0xa4, 0xf0, 0x90, 0xfa, 0x7c, 0xe0, 
-0x90, 0xff, 0xb4, 0xf0, 0x90, 0xfa, 0x79, 0xe0, 0x90, 0xff, 0xa2, 0xf0, 0x90, 0xfa, 0x7a, 0xe0, 
-0x90, 0xff, 0xb2, 0xf0, 0x90, 0xf9, 0x17, 0xe0, 0x60, 0x02, 0xc2, 0xb3, 0x90, 0xfa, 0xe4, 0xe0, 
-0xf5, 0xa8, 0x02, 0x10, 0x86, 0x8b, 0x5c, 0x8a, 0x5d, 0x89, 0x5e, 0x12, 0x2d, 0x3c, 0x90, 0xfa, 
-0xc0, 0x12, 0x1b, 0x43, 0xaa, 0x5d, 0xa9, 0x5e, 0x90, 0xfa, 0xc3, 0x12, 0x1b, 0x43, 0x90, 0xfa, 
-0xc4, 0xe4, 0x75, 0xf0, 0x0a, 0x12, 0x1a, 0x6c, 0x90, 0xfa, 0xc3, 0x12, 0x1b, 0x3a, 0xe9, 0x24, 
-0x01, 0xf9, 0xe4, 0x3a, 0xfa, 0x90, 0xfa, 0xc6, 0x12, 0x1b, 0x43, 0xab, 0x5c, 0xaa, 0x5d, 0xa9, 
-0x5e, 0x12, 0x2d, 0x48, 0xe0, 0xff, 0xc3, 0x13, 0xf0, 0xe4, 0x78, 0x82, 0xf6, 0x90, 0xfa, 0xbe, 
-0xe0, 0xff, 0x78, 0x82, 0xe6, 0xc3, 0x9f, 0x50, 0x4a, 0x90, 0xfa, 0xc0, 0x12, 0x2d, 0x1d, 0xff, 
-0x78, 0x83, 0xf6, 0x90, 0xfa, 0xc3, 0x12, 0x2d, 0x1d, 0xfe, 0xf4, 0x5f, 0xff, 0x78, 0x83, 0xf6, 
-0x12, 0x2d, 0x1a, 0x5e, 0x4f, 0xff, 0x78, 0x83, 0xf6, 0x12, 0x2d, 0x23, 0x75, 0xf0, 0x02, 0x12, 
-0x1a, 0x6c, 0x90, 0xfa, 0xc4, 0xe4, 0x75, 0xf0, 0x02, 0x12, 0x1a, 0x6c, 0xab, 0x5c, 0xaa, 0x5d, 
-0xa9, 0x5e, 0x90, 0x00, 0x04, 0x12, 0x1a, 0x0b, 0x30, 0xe4, 0x03, 0x12, 0x2d, 0x32, 0x78, 0x82, 
-0x06, 0x80, 0xaa, 0xe4, 0x90, 0xfa, 0xbf, 0xf0, 0x22, 0x8b, 0x56, 0x8a, 0x57, 0x89, 0x58, 0x90, 
-0xfa, 0xbf, 0x74, 0x06, 0xf0, 0xe4, 0x90, 0xfa, 0xbe, 0xf0, 0x12, 0x19, 0xf2, 0x24, 0x6e, 0x60, 
-0x26, 0x14, 0x70, 0x70, 0x12, 0x2d, 0x09, 0x60, 0x09, 0x24, 0x30, 0x70, 0x12, 0x12, 0x24, 0x95, 
-0x80, 0x62, 0x12, 0x2d, 0x53, 0x12, 0x1f, 0x2c, 0x90, 0xfa, 0xbf, 0xef, 0xf0, 0x80, 0x55, 0x90, 
-0xfa, 0xbf, 0x74, 0x81, 0xf0, 0x80, 0x4d, 0x12, 0x2d, 0x09, 0x60, 0x09, 0x24, 0x30, 0x70, 0x3e, 
-0x12, 0x2c, 0x5f, 0x80, 0x3f, 0xe5, 0x58, 0x24, 0x03, 0xf9, 0xe4, 0x35, 0x57, 0xfa, 0x7b, 0x01, 
-0xc0, 0x03, 0xc0, 0x02, 0xc0, 0x01, 0x12, 0x2d, 0x53, 0x90, 0x00, 0x05, 0x12, 0x1a, 0x0b, 0xfd, 
-0x90, 0x00, 0x08, 0x12, 0x1a, 0x98, 0xf5, 0x2e, 0x85, 0xf0, 0x2d, 0xd0, 0x01, 0xd0, 0x02, 0xd0, 
-0x03, 0x12, 0x25, 0xd7, 0x90, 0xfa, 0xbe, 0xef, 0xf0, 0xe4, 0xa3, 0xf0, 0x80, 0x06, 0x90, 0xfa, 
-0xbf, 0x74, 0x81, 0xf0, 0x90, 0xfa, 0xbf, 0xe0, 0x12, 0x2d, 0x53, 0x90, 0x00, 0x02, 0x12, 0x1a, 
-0x4a, 0x90, 0xfa, 0xbe, 0xe0, 0xff, 0x22, 0x8b, 0x29, 0x8a, 0x2a, 0x89, 0x2b, 0x8d, 0x2c, 0xe5, 
-0x2c, 0x70, 0x03, 0xaf, 0x2c, 0x22, 0x12, 0x2d, 0x82, 0x70, 0x16, 0x12, 0x2d, 0xa1, 0xe5, 0x2d, 
-0x90, 0xff, 0xf1, 0xf0, 0x12, 0x31, 0x1b, 0x50, 0xf2, 0x12, 0x26, 0x64, 0x40, 0x0b, 0x7f, 0x00, 
-0x22, 0x12, 0x2d, 0xa1, 0x12, 0x26, 0x64, 0x50, 0xf8, 0x90, 0xff, 0xf3, 0x74, 0xa1, 0xf0, 0xe5, 
-0x2c, 0xb4, 0x01, 0x07, 0x90, 0xff, 0xf0, 0xe0, 0x44, 0x02, 0xf0, 0x90, 0xff, 0xf1, 0xe4, 0xf0, 
-0xf5, 0x2f, 0xe5, 0x2c, 0x14, 0xff, 0xe5, 0x2f, 0xc3, 0x9f, 0x50, 0x2a, 0x12, 0x31, 0x04, 0x40, 
-0x03, 0xaf, 0x2f, 0x22, 0xc3, 0xe5, 0x2c, 0x95, 0x2f, 0xff, 0xbf, 0x02, 0x07, 0x90, 0xff, 0xf0, 
-0xe0, 0x44, 0x02, 0xf0, 0x12, 0x2d, 0x94, 0x05, 0x2f, 0x74, 0x01, 0x25, 0x2b, 0xf5, 0x2b, 0xe4, 
-0x35, 0x2a, 0xf5, 0x2a, 0x80, 0xcc, 0x12, 0x31, 0x04, 0x40, 0x03, 0x7f, 0x18, 0x22, 0x12, 0x2d, 
-0x94, 0xaf, 0x2c, 0x22, 0x90, 0xff, 0xf1, 0xe5, 0x2e, 0xf0, 0x02, 0x31, 0x1b, 0x12, 0x10, 0x03, 
-0x78, 0x84, 0x12, 0x22, 0x82, 0x30, 0xe1, 0x08, 0x7f, 0x13, 0x12, 0x30, 0xec, 0x02, 0x26, 0xfb, 
-0x78, 0x84, 0xe6, 0xf9, 0x24, 0x12, 0x12, 0x21, 0xff, 0xe0, 0xff, 0x30, 0xe7, 0x40, 0x54, 0x03, 
-0x60, 0x1e, 0xe9, 0xb4, 0x03, 0x0d, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xfe, 0xf0, 0xe0, 0x44, 0x04, 
-0xf0, 0x80, 0x46, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xfd, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x80, 0x39, 
-0xe9, 0xb4, 0x03, 0x0d, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x01, 0xf0, 0x80, 
-0x28, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xf7, 0xf0, 0xe0, 0x44, 0x02, 0xf0, 0x80, 0x1b, 0xef, 0x54, 
-0x03, 0x60, 0x14, 0xe9, 0xb4, 0x03, 0x09, 0x90, 0xff, 0xa4, 0xe0, 0x54, 0xdf, 0xf0, 0x80, 0x07, 
-0x90, 0xff, 0xb4, 0xe0, 0x54, 0xdf, 0xf0, 0xc2, 0xb3, 0x90, 0xf9, 0x17, 0xe0, 0x04, 0xf0, 0xaf, 
-0x01, 0x12, 0x22, 0x33, 0xfd, 0x12, 0x2f, 0x49, 0x12, 0x30, 0xec, 0x02, 0x10, 0x86, 0x75, 0xa8, 
-0x40, 0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x8b, 0x02, 0x27, 0x48, 0x02, 0x30, 0xcf, 
-0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0x40, 0x03, 0xf6, 0x80, 0x01, 0xf2, 0x08, 0xdf, 0xf4, 
-0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, 0x33, 0xc4, 0x54, 0x0f, 
-0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4, 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf, 0xe4, 0x80, 0x0b, 
-0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x2b, 0x4c, 0xe4, 0x7e, 0x01, 0x93, 0x60, 
-0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09, 0x54, 0x1f, 0xfe, 0xe4, 0x93, 0xa3, 0x60, 0x01, 
-0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3, 0xfa, 0xe4, 0x93, 
-0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xf0, 0xa3, 0xc8, 
-0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe, 0xe4, 0xf5, 0x22, 
-0x12, 0x1d, 0x12, 0xe0, 0xb4, 0x04, 0x0d, 0xe5, 0x22, 0x24, 0x03, 0xff, 0x12, 0x2f, 0x77, 0x12, 
-0x1d, 0x12, 0xe4, 0xf0, 0x05, 0x22, 0xe5, 0x22, 0xc3, 0x94, 0x02, 0x40, 0xe3, 0xe4, 0xf5, 0x22, 
-0x75, 0xf0, 0x02, 0xe5, 0x22, 0x90, 0xfa, 0x91, 0x12, 0x1d, 0x53, 0x60, 0x2c, 0x12, 0x2c, 0xb4, 
-0xef, 0x60, 0x52, 0x75, 0xf0, 0x02, 0xe5, 0x22, 0x90, 0xfa, 0x91, 0x12, 0x1b, 0x1c, 0xe4, 0xf0, 
-0xa3, 0xf0, 0x75, 0xf0, 0x0a, 0xe5, 0x22, 0x90, 0xfa, 0x9d, 0x12, 0x1b, 0x1c, 0xe0, 0xa3, 0x30, 
-0xe6, 0x33, 0x12, 0x1d, 0x12, 0x74, 0x04, 0xf0, 0x22, 0x75, 0xf0, 0x02, 0xe5, 0x22, 0x90, 0xfa, 
-0x95, 0x12, 0x1d, 0x53, 0x60, 0x16, 0x12, 0x2c, 0xb4, 0xef, 0x60, 0x19, 0x75, 0xf0, 0x02, 0xe5, 
-0x22, 0x90, 0xfa, 0x95, 0x12, 0x1b, 0x1c, 0xe4, 0xf0, 0xa3, 0xf0, 0x22, 0x05, 0x22, 0xe5, 0x22, 
-0xc3, 0x94, 0x02, 0x40, 0x9b, 0x22, 0xe4, 0xff, 0x90, 0xff, 0x83, 0xe0, 0x54, 0x0f, 0xfe, 0xef, 
-0xc3, 0x9e, 0x50, 0x17, 0x74, 0xf0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0xfe, 0xf5, 0x83, 0xe0, 0x12, 
-0x1c, 0x11, 0x12, 0x1a, 0x38, 0x0f, 0x12, 0x1c, 0x00, 0x80, 0xdd, 0xef, 0xfd, 0xc3, 0xe5, 0x3a, 
-0x9d, 0xf5, 0x3a, 0xe5, 0x39, 0x94, 0x00, 0xf5, 0x39, 0xd3, 0xe5, 0x3a, 0x94, 0x00, 0xe5, 0x39, 
-0x94, 0x00, 0x40, 0x06, 0xe4, 0x90, 0xff, 0x83, 0xf0, 0x22, 0x12, 0x1d, 0x2f, 0x12, 0x1d, 0x84, 
-0x12, 0x1d, 0x76, 0x12, 0x19, 0xf2, 0x24, 0x6e, 0x60, 0x1e, 0x14, 0x60, 0x1b, 0x24, 0x8e, 0x70, 
-0x2d, 0x90, 0x00, 0x01, 0x12, 0x1a, 0x0b, 0xff, 0x24, 0xfc, 0x60, 0x03, 0x04, 0x70, 0x1f, 0xef, 
-0xfd, 0x7c, 0x00, 0x7f, 0x0d, 0x02, 0x11, 0x16, 0x12, 0x1d, 0x8b, 0x12, 0x25, 0x39, 0x12, 0x1c, 
-0xd9, 0x12, 0x1a, 0x0b, 0x60, 0x03, 0x02, 0x31, 0xbd, 0xe4, 0xff, 0x12, 0x31, 0xb1, 0x22, 0x8b, 
-0x45, 0x8a, 0x46, 0x89, 0x47, 0x8c, 0x48, 0x8d, 0x49, 0xd2, 0x00, 0x12, 0x2d, 0x82, 0x70, 0x16, 
-0x12, 0x2d, 0xa1, 0xe5, 0x48, 0x90, 0xff, 0xf1, 0xf0, 0x12, 0x31, 0x1b, 0x50, 0xf2, 0x12, 0x29, 
-0x14, 0x40, 0x0b, 0x7f, 0x18, 0x22, 0x12, 0x2d, 0xa1, 0x12, 0x29, 0x14, 0x50, 0xf8, 0xe4, 0xf5, 
-0x4b, 0xe5, 0x4a, 0x14, 0xff, 0xe5, 0x4b, 0xc3, 0x9f, 0x50, 0x17, 0x12, 0x29, 0x04, 0x40, 0x03, 
-0x7f, 0x18, 0x22, 0x05, 0x4b, 0x74, 0x01, 0x25, 0x47, 0xf5, 0x47, 0xe4, 0x35, 0x46, 0xf5, 0x46, 
-0x80, 0xdf, 0x90, 0xff, 0xf0, 0xe0, 0x44, 0x01, 0xf0, 0x12, 0x29, 0x04, 0x40, 0x03, 0x7f, 0x18, 
-0x22, 0x7f, 0x00, 0x22, 0xab, 0x45, 0xaa, 0x46, 0xa9, 0x47, 0x12, 0x19, 0xf2, 0x90, 0xff, 0xf1, 
-0xf0, 0x02, 0x31, 0x1b, 0x90, 0xff, 0xf1, 0xe5, 0x49, 0xf0, 0x02, 0x31, 0x1b, 0x7b, 0x01, 0x7a, 
-0xfa, 0x79, 0xcc, 0xe4, 0xfd, 0x12, 0x22, 0xa0, 0x90, 0xfa, 0xcc, 0xe4, 0x75, 0xf0, 0x09, 0x12, 
-0x1a, 0x6c, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x23, 0x90, 0xfa, 0xcc, 0xe4, 0x75, 0xf0, 0x01, 0x12, 
-0x1a, 0x82, 0x85, 0xf0, 0x2e, 0xf5, 0x2d, 0x7d, 0x01, 0x12, 0x25, 0xd7, 0x90, 0xff, 0xf7, 0xe5, 
-0x23, 0x12, 0x29, 0x78, 0x90, 0xff, 0xf6, 0xe5, 0x23, 0xf0, 0x90, 0xfa, 0xcc, 0xe4, 0xf0, 0xa3, 
-0x74, 0x06, 0x12, 0x29, 0x78, 0xe5, 0x23, 0x30, 0xe0, 0x07, 0x90, 0xff, 0xfc, 0x74, 0x94, 0xf0, 
-0x22, 0x90, 0xff, 0xfc, 0x74, 0x90, 0xf0, 0x22, 0xf0, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x23, 0x90, 
-0xfa, 0xcc, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x1a, 0x82, 0x85, 0xf0, 0x2e, 0xf5, 0x2d, 0x7d, 0x01, 
-0x02, 0x25, 0xd7, 0x90, 0xff, 0x93, 0x74, 0x2a, 0xf0, 0x90, 0xff, 0xff, 0xe0, 0x60, 0x06, 0x90, 
-0xff, 0xfc, 0x74, 0x10, 0xf0, 0x90, 0xff, 0x91, 0xe0, 0x44, 0x90, 0xf0, 0xe4, 0x90, 0xf9, 0x15, 
-0xf0, 0xa3, 0xf0, 0x12, 0x2a, 0x78, 0x12, 0x16, 0x42, 0x12, 0x2f, 0xcd, 0x7e, 0x07, 0x7f, 0xd0, 
-0x12, 0x11, 0xe2, 0x7e, 0x0f, 0x7f, 0xa0, 0x12, 0x11, 0xfc, 0xe4, 0x78, 0x77, 0xf6, 0x78, 0x77, 
-0xe6, 0xff, 0xc3, 0x94, 0x06, 0x50, 0x0b, 0x74, 0x6e, 0x2f, 0xf8, 0xe4, 0xf6, 0x78, 0x77, 0x06, 
-0x80, 0xec, 0x7f, 0x03, 0x12, 0x2e, 0xb3, 0x90, 0xf9, 0x15, 0xe0, 0x20, 0xe4, 0x05, 0x7f, 0x04, 
-0x12, 0x2e, 0xb3, 0x90, 0xff, 0x9b, 0xe4, 0xf0, 0x90, 0xff, 0x9a, 0xf0, 0x90, 0xff, 0xe8, 0xe0, 
-0x54, 0x1f, 0xf0, 0xd2, 0xa8, 0x22, 0x15, 0x65, 0xa8, 0x65, 0xa6, 0x07, 0x30, 0x08, 0x05, 0x12, 
-0x11, 0x66, 0x80, 0xf8, 0xd2, 0x08, 0xa8, 0x65, 0xe6, 0xff, 0xb4, 0x03, 0x0f, 0x78, 0x7c, 0x76, 
-0xff, 0x08, 0x76, 0xe0, 0x08, 0x76, 0xff, 0x08, 0x76, 0xa0, 0x80, 0x0d, 0x78, 0x7c, 0x76, 0xff, 
-0x08, 0x76, 0xe2, 0x08, 0x76, 0xff, 0x08, 0x76, 0xb0, 0x78, 0x80, 0x76, 0xfa, 0x08, 0x76, 0x9b, 
-0xef, 0x24, 0xfd, 0x75, 0xf0, 0x0a, 0xa4, 0xae, 0xf0, 0x12, 0x22, 0x92, 0x7b, 0x01, 0x7a, 0xff, 
-0x79, 0x48, 0x78, 0x68, 0x12, 0x1b, 0x31, 0xa8, 0x65, 0xe6, 0x24, 0xfd, 0x75, 0xf0, 0x08, 0xa4, 
-0xff, 0xae, 0xf0, 0x78, 0x6a, 0x12, 0x22, 0x92, 0x79, 0x08, 0x78, 0x6b, 0x12, 0x1b, 0x31, 0x78, 
-0x6d, 0xef, 0x12, 0x22, 0x92, 0x05, 0x65, 0x22, 0x90, 0xff, 0xf0, 0xe0, 0x54, 0xab, 0xf0, 0xe0, 
-0x44, 0x20, 0xf0, 0x90, 0xfa, 0xe3, 0x74, 0x02, 0xf0, 0x7b, 0x01, 0x7a, 0xfa, 0x79, 0xcc, 0xe4, 
-0xf5, 0x2d, 0xf5, 0x2e, 0x7d, 0x01, 0x12, 0x25, 0xd7, 0x7e, 0x00, 0x90, 0xfa, 0xe1, 0xee, 0xf0, 
-0xa3, 0xef, 0xf0, 0x64, 0x01, 0x70, 0x10, 0x90, 0xfa, 0xcc, 0xe0, 0xb4, 0x52, 0x09, 0x90, 0xf9, 
-0x15, 0xe0, 0x54, 0xef, 0xf0, 0x80, 0x29, 0x90, 0xfa, 0xe1, 0xe0, 0x70, 0x04, 0xa3, 0xe0, 0x64, 
-0x01, 0x70, 0x10, 0x90, 0xfa, 0xcc, 0xe0, 0xb4, 0x10, 0x09, 0x90, 0xf9, 0x15, 0xe0, 0x44, 0x10, 
-0xf0, 0x80, 0x0d, 0x90, 0xfa, 0xe3, 0x74, 0x03, 0xf0, 0x90, 0xf9, 0x15, 0xe0, 0x54, 0xef, 0xf0, 
-0x90, 0xff, 0xf0, 0xe0, 0x44, 0x20, 0xf0, 0x22, 0x12, 0x10, 0x03, 0x78, 0x8a, 0xef, 0xf6, 0x12, 
-0x2a, 0x06, 0x12, 0x22, 0x33, 0x30, 0xe0, 0x25, 0x12, 0x22, 0x07, 0xe0, 0x54, 0x7f, 0xf0, 0x78, 
-0x6b, 0x12, 0x1b, 0x28, 0x90, 0x00, 0x02, 0x12, 0x1a, 0x0b, 0x30, 0xe7, 0x09, 0x90, 0x00, 0x02, 
-0xe4, 0x12, 0x1a, 0x4a, 0x80, 0xe9, 0x12, 0x22, 0x07, 0xe0, 0x44, 0x80, 0xf0, 0x12, 0x22, 0x33, 
-0x30, 0xe1, 0x1e, 0x12, 0x21, 0xe9, 0xe0, 0x54, 0x7f, 0xf0, 0x12, 0x31, 0x5c, 0x78, 0x68, 0x12, 
-0x1b, 0x28, 0x90, 0x00, 0x02, 0x74, 0x80, 0x12, 0x1a, 0x4a, 0x12, 0x21, 0xe9, 0xe0, 0x44, 0x80, 
-0xf0, 0x12, 0x31, 0xc7, 0xe4, 0xff, 0x12, 0x30, 0xec, 0x02, 0x10, 0x86, 0x03, 0x68, 0x01, 0xff, 
-0x48, 0x03, 0x6b, 0x01, 0xff, 0x08, 0x02, 0x66, 0x00, 0x00, 0x44, 0xfa, 0x95, 0x00, 0x00, 0x00, 
-0x00, 0x44, 0xfa, 0x91, 0x00, 0x00, 0x00, 0x00, 0x42, 0xfa, 0xaf, 0x00, 0x00, 0x42, 0xfa, 0x7b, 
-0x00, 0x00, 0x42, 0xfa, 0x79, 0x00, 0x00, 0x42, 0xf9, 0x6a, 0xff, 0xff, 0x42, 0xfa, 0x77, 0x00, 
-0x00, 0x43, 0xf9, 0x18, 0x0a, 0x32, 0x02, 0x41, 0xf9, 0x65, 0x20, 0x41, 0xf9, 0x66, 0x20, 0x41, 
-0xf9, 0x63, 0x00, 0x41, 0xf9, 0x64, 0x00, 0x44, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf9, 
-0x15, 0x00, 0x00, 0x41, 0xf9, 0x17, 0x00, 0x01, 0x20, 0x00, 0x41, 0xf8, 0x04, 0x00, 0x00, 0x12, 
-0x10, 0x03, 0x78, 0x85, 0xef, 0xf6, 0x12, 0x30, 0x93, 0x12, 0x30, 0xec, 0x78, 0x85, 0xe6, 0xff, 
-0x24, 0x12, 0x12, 0x21, 0xff, 0xe0, 0xfe, 0x30, 0xe7, 0x16, 0xef, 0xb4, 0x03, 0x09, 0x90, 0xff, 
-0x9e, 0xe0, 0x54, 0xfa, 0xf0, 0x80, 0x22, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xf5, 0xf0, 0x80, 0x19, 
-0xee, 0x54, 0x03, 0x60, 0x14, 0xef, 0xb4, 0x03, 0x09, 0x90, 0xff, 0xa4, 0xe0, 0x44, 0x20, 0xf0, 
-0x80, 0x07, 0x90, 0xff, 0xb4, 0xe0, 0x44, 0x20, 0xf0, 0x90, 0xf9, 0x17, 0xe0, 0x14, 0xf0, 0xe0, 
-0x70, 0x02, 0xd2, 0xb3, 0x02, 0x10, 0x86, 0x12, 0x1d, 0x6c, 0xe5, 0x3a, 0x64, 0x09, 0x70, 0x04, 
-0xe5, 0x39, 0x64, 0x01, 0x60, 0x48, 0xc3, 0xe5, 0x3a, 0x94, 0x08, 0xe5, 0x39, 0x94, 0x00, 0x40, 
-0x11, 0x7f, 0x08, 0xef, 0xe5, 0x3a, 0x94, 0x08, 0xf5, 0x3a, 0xe5, 0x39, 0x94, 0x00, 0xf5, 0x39, 
-0x80, 0x05, 0xaf, 0x3a, 0x12, 0x1d, 0x84, 0xe4, 0xfe, 0xee, 0xc3, 0x9f, 0x50, 0x19, 0x12, 0x1c, 
-0x11, 0x12, 0x19, 0xf2, 0xfd, 0x74, 0xf8, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0xfe, 0xf5, 0x83, 0xed, 
-0xf0, 0x0e, 0x12, 0x1c, 0x00, 0x80, 0xe2, 0xef, 0x54, 0x7f, 0x90, 0xff, 0x81, 0xf0, 0x22, 0x8b, 
-0x59, 0x8a, 0x5a, 0x89, 0x5b, 0x12, 0x2d, 0x48, 0x70, 0x05, 0xa3, 0x74, 0x08, 0xf0, 0x22, 0xab, 
-0x59, 0xaa, 0x5a, 0xa9, 0x5b, 0x12, 0x2d, 0x3c, 0x90, 0xfa, 0xc6, 0x12, 0x1b, 0x43, 0xe5, 0x5b, 
-0x24, 0x03, 0xf9, 0xe4, 0x35, 0x5a, 0xfa, 0x90, 0xfa, 0xc0, 0x12, 0x1b, 0x43, 0xe4, 0x90, 0xfa, 
-0xbf, 0xf0, 0x78, 0x8b, 0xf6, 0x90, 0xfa, 0xbe, 0xe0, 0xff, 0x78, 0x8b, 0xe6, 0xc3, 0x9f, 0x50, 
-0x12, 0x12, 0x2d, 0x1a, 0xff, 0x12, 0x2d, 0x23, 0x12, 0x2d, 0x36, 0x78, 0x8b, 0x06, 0x12, 0x2d, 
-0x32, 0x80, 0xe2, 0x22, 0xad, 0x07, 0xac, 0x06, 0x90, 0x31, 0x4d, 0xe4, 0x93, 0xff, 0x78, 0x74, 
-0xf6, 0x54, 0x0f, 0x12, 0x1c, 0xf8, 0xe0, 0x08, 0x76, 0x00, 0x08, 0xf6, 0x18, 0x12, 0x1c, 0x29, 
-0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff, 0x78, 0x75, 0xee, 0xf6, 0x08, 0xef, 0xf6, 0xee, 
-0x44, 0xf8, 0x18, 0xf6, 0xef, 0x08, 0xf6, 0x90, 0xff, 0x7a, 0xe0, 0x20, 0xe7, 0x03, 0x7f, 0x00, 
-0x22, 0x78, 0x75, 0xe6, 0xfe, 0x08, 0xe6, 0xf5, 0x82, 0x8e, 0x83, 0xec, 0xf0, 0xa3, 0xed, 0xf0, 
-0x90, 0xff, 0x7a, 0x74, 0x02, 0xf0, 0x7f, 0x01, 0x22, 0xab, 0x56, 0xaa, 0x57, 0xa9, 0x58, 0x90, 
-0x00, 0x03, 0x12, 0x1a, 0x0b, 0x54, 0xf0, 0x24, 0xa0, 0x22, 0x90, 0xfa, 0xc6, 0x12, 0x1b, 0x3a, 
-0x02, 0x19, 0xf2, 0x90, 0xfa, 0xc0, 0x12, 0x1b, 0x3a, 0xef, 0x12, 0x1a, 0x38, 0x90, 0xfa, 0xc7, 
-0xe4, 0x22, 0x90, 0xfa, 0xc1, 0xe4, 0x75, 0xf0, 0x01, 0x02, 0x1a, 0x6c, 0x90, 0x00, 0x08, 0x12, 
-0x1a, 0x98, 0xaa, 0xf0, 0xf9, 0x7b, 0x01, 0x22, 0x90, 0x00, 0x05, 0x12, 0x1a, 0x0b, 0x90, 0xfa, 
-0xbe, 0xf0, 0x22, 0xab, 0x56, 0xaa, 0x57, 0xa9, 0x58, 0x22, 0x90, 0xfa, 0xda, 0xe0, 0xff, 0x7e, 
-0x00, 0xc3, 0x90, 0xfa, 0xd4, 0xe0, 0x9f, 0xf0, 0x90, 0xfa, 0xd3, 0xe0, 0x9e, 0xf0, 0x90, 0xfa, 
-0xd5, 0xee, 0x8f, 0xf0, 0x12, 0x1a, 0x6c, 0xef, 0x25, 0x51, 0xf5, 0x51, 0xee, 0x35, 0x50, 0xf5, 
-0x50, 0x22, 0x90, 0xff, 0xf0, 0xe0, 0x54, 0xfe, 0xf0, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0xfa, 0xe3, 
-0xe0, 0x64, 0x03, 0x22, 0x90, 0xff, 0xf2, 0xe0, 0xab, 0x29, 0xaa, 0x2a, 0xa9, 0x2b, 0x02, 0x1a, 
-0x38, 0x90, 0xff, 0xf3, 0x74, 0xa0, 0xf0, 0x22, 0x8f, 0x64, 0xed, 0x70, 0x0f, 0xe5, 0x64, 0xb4, 
-0x03, 0x05, 0x7f, 0x01, 0x02, 0x31, 0x32, 0x7f, 0x02, 0x02, 0x31, 0x32, 0xaf, 0x64, 0x12, 0x2a, 
-0x06, 0x74, 0x6e, 0x25, 0x64, 0xf8, 0xe6, 0x30, 0xe2, 0x0b, 0xd2, 0x09, 0x12, 0x1c, 0x83, 0xe0, 
-0x54, 0x7f, 0xf0, 0x80, 0x02, 0xc2, 0x09, 0xe5, 0x64, 0xb4, 0x03, 0x07, 0x7f, 0x81, 0x12, 0x31, 
-0x32, 0x80, 0x05, 0x7f, 0x82, 0x12, 0x31, 0x32, 0x30, 0x09, 0x07, 0x12, 0x1c, 0x83, 0xe0, 0x44, 
-0x80, 0xf0, 0x12, 0x31, 0xc7, 0x22, 0x12, 0x10, 0x03, 0x90, 0xff, 0xfd, 0xe0, 0x44, 0x60, 0xf0, 
-0xd2, 0x01, 0x90, 0xff, 0xfc, 0xe0, 0x44, 0x02, 0xf0, 0x90, 0xff, 0x00, 0xe0, 0x30, 0xe7, 0x13, 
-0x90, 0xff, 0x83, 0xe0, 0x44, 0x80, 0xf0, 0x43, 0x35, 0x80, 0x90, 0xff, 0xfc, 0xe0, 0x44, 0x01, 
-0xf0, 0x80, 0x0d, 0x12, 0x1d, 0x2f, 0x53, 0x35, 0x7f, 0x90, 0xff, 0xfc, 0xe0, 0x54, 0xfe, 0xf0, 
-0x90, 0xff, 0x81, 0xe0, 0x44, 0x80, 0xf0, 0x12, 0x02, 0xb0, 0x12, 0x1d, 0x37, 0x02, 0x10, 0x86, 
-0x12, 0x10, 0x03, 0x78, 0x89, 0xef, 0xf6, 0xd2, 0x00, 0x12, 0x2a, 0x06, 0x90, 0xf9, 0x67, 0x12, 
-0x1b, 0x3a, 0xe9, 0x24, 0x03, 0xf9, 0xe4, 0x3a, 0xfa, 0xc0, 0x02, 0x78, 0x80, 0xe6, 0xfe, 0x08, 
-0xe6, 0xaa, 0x06, 0xf8, 0xac, 0x02, 0x7d, 0x01, 0xd0, 0x02, 0x12, 0x22, 0x25, 0x12, 0x31, 0xc7, 
-0x78, 0x89, 0xe6, 0xff, 0x12, 0x13, 0x3f, 0x12, 0x30, 0xec, 0x02, 0x10, 0x86, 0x8f, 0x63, 0x12, 
-0x2a, 0x06, 0x12, 0x22, 0x07, 0xe0, 0x54, 0x3f, 0xf0, 0xe5, 0x82, 0x24, 0x04, 0x12, 0x21, 0xf3, 
-0xe0, 0x54, 0x3f, 0xf0, 0x08, 0xe6, 0xfe, 0x08, 0xe6, 0x8e, 0x83, 0x24, 0x0b, 0x12, 0x21, 0xf3, 
-0xe0, 0x54, 0xf8, 0xf0, 0x12, 0x31, 0xc7, 0x74, 0x6e, 0x25, 0x63, 0xf8, 0x74, 0xfb, 0x56, 0xf6, 
-0x7f, 0x00, 0x22, 0x8f, 0x23, 0xc2, 0x08, 0x12, 0x2a, 0x06, 0x12, 0x22, 0x12, 0x78, 0x7e, 0x12, 
-0x21, 0xeb, 0xe0, 0x44, 0x01, 0xf0, 0x12, 0x22, 0x4a, 0x12, 0x21, 0xef, 0xe0, 0x20, 0xe0, 0xf6, 
-0xef, 0x24, 0x0b, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0x54, 0xf8, 0xf0, 0x12, 0x31, 0xc7, 
-0xaf, 0x23, 0x12, 0x13, 0x3f, 0x22, 0x12, 0x10, 0x03, 0x12, 0x2a, 0x06, 0x12, 0x22, 0x4a, 0x24, 
-0x06, 0x12, 0x21, 0xf1, 0xe0, 0xfd, 0x12, 0x22, 0x2d, 0x90, 0x00, 0x03, 0x12, 0x22, 0x52, 0x24, 
-0x05, 0x12, 0x21, 0xf3, 0xe0, 0x90, 0x00, 0x04, 0x12, 0x1a, 0x4a, 0x12, 0x31, 0xc7, 0x7d, 0x02, 
-0xe4, 0xff, 0x12, 0x2f, 0x18, 0x02, 0x10, 0x86, 0xae, 0x05, 0x12, 0x1c, 0xde, 0xef, 0x12, 0x1a, 
-0x4a, 0x0e, 0x0e, 0x0e, 0xee, 0xd3, 0x95, 0x3c, 0xe4, 0x95, 0x3b, 0x40, 0x02, 0xae, 0x3c, 0xee, 
-0xd3, 0x94, 0x08, 0x74, 0x80, 0x94, 0x81, 0x40, 0x0a, 0x7e, 0x03, 0x90, 0x00, 0x02, 0x74, 0x02, 
-0x12, 0x1a, 0x4a, 0xaf, 0x06, 0x12, 0x31, 0xb1, 0x22, 0xae, 0x07, 0xed, 0x54, 0x03, 0x64, 0x01, 
-0x60, 0x03, 0x7f, 0x10, 0x22, 0xed, 0x54, 0x7c, 0xc3, 0x94, 0x04, 0x50, 0x03, 0x7f, 0x0b, 0x22, 
-0x74, 0x6e, 0x2e, 0xf8, 0x74, 0x02, 0x46, 0xf6, 0x74, 0x96, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0xfa, 
-0xf5, 0x83, 0xed, 0xf0, 0x7f, 0x00, 0x22, 0xbf, 0x03, 0x06, 0x7c, 0xff, 0x7d, 0xe0, 0x80, 0x04, 
-0x7c, 0xff, 0x7d, 0xe2, 0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x44, 0x80, 0xf0, 0xe5, 0x82, 0x24, 0x04, 
-0x12, 0x21, 0xf3, 0xe0, 0x44, 0x80, 0xf0, 0x74, 0x6e, 0x2f, 0xf8, 0x74, 0x04, 0x46, 0xf6, 0x7f, 
-0x00, 0x22, 0x12, 0x10, 0x03, 0xe5, 0x3a, 0x64, 0x09, 0x70, 0x04, 0xe5, 0x39, 0x64, 0x01, 0x60, 
-0x16, 0x90, 0xff, 0x83, 0xe0, 0x54, 0x0f, 0xff, 0xc3, 0xe5, 0x3a, 0x9f, 0xe5, 0x39, 0x94, 0x00, 
-0x40, 0x05, 0x12, 0x28, 0x16, 0x80, 0x03, 0x12, 0x31, 0xbd, 0x02, 0x10, 0x86, 0x90, 0xff, 0xfc, 
-0xe0, 0x20, 0xe7, 0x1f, 0xc2, 0xaf, 0x7d, 0xff, 0xac, 0x05, 0x1d, 0xec, 0x60, 0x15, 0x7e, 0x04, 
-0x7f, 0x00, 0xef, 0x1f, 0xaa, 0x06, 0x70, 0x01, 0x1e, 0x4a, 0x60, 0xec, 0x90, 0xff, 0x92, 0xe4, 
-0xf0, 0x80, 0xef, 0x22, 0x12, 0x10, 0x03, 0x78, 0x66, 0xe6, 0xfe, 0x08, 0xe6, 0xff, 0x30, 0xe0, 
-0x12, 0x30, 0xe1, 0x0f, 0x90, 0xff, 0xfc, 0xe0, 0x44, 0x20, 0xf0, 0x7f, 0x04, 0x12, 0x12, 0x19, 
-0x12, 0x1d, 0x46, 0x02, 0x10, 0x86, 0x8e, 0x5f, 0x8f, 0x60, 0xe5, 0x60, 0x15, 0x60, 0xae, 0x5f, 
-0x70, 0x02, 0x15, 0x5f, 0xd3, 0x94, 0x00, 0xee, 0x94, 0x00, 0x40, 0x09, 0x7e, 0x07, 0x7f, 0xd0, 
-0x12, 0x0f, 0xdc, 0x80, 0xe5, 0x22, 0x11, 0x94, 0x2d, 0xf6, 0x23, 0xef, 0x31, 0xa3, 0x2f, 0xf4, 
-0x2f, 0xa2, 0x30, 0xb2, 0x2e, 0xe6, 0x26, 0x6d, 0x2b, 0xaf, 0x30, 0x55, 0x30, 0x74, 0x1d, 0xb4, 
-0x2e, 0x40, 0x2a, 0xe8, 0x0e, 0x12, 0x10, 0x03, 0x78, 0x86, 0x12, 0x22, 0x82, 0x20, 0xe1, 0x07, 
-0x7f, 0x12, 0x12, 0x30, 0xec, 0x80, 0x0a, 0x78, 0x86, 0xe6, 0xff, 0x12, 0x23, 0x49, 0x12, 0x30, 
-0xec, 0x02, 0x10, 0x86, 0x12, 0x10, 0x03, 0x78, 0x87, 0x12, 0x22, 0x82, 0x20, 0xe2, 0x07, 0x7f, 
-0x11, 0x12, 0x30, 0xec, 0x80, 0x0a, 0x78, 0x87, 0xe6, 0xff, 0x12, 0x2e, 0x7d, 0x12, 0x30, 0xec, 
-0x02, 0x10, 0x86, 0x8f, 0x61, 0x12, 0x2e, 0x7d, 0xaf, 0x61, 0x12, 0x2a, 0x06, 0x12, 0x22, 0x12, 
-0x12, 0x31, 0xc7, 0x74, 0x6e, 0x25, 0x61, 0xf8, 0x74, 0xfd, 0x56, 0xf6, 0xaf, 0x61, 0x12, 0x13, 
-0x3f, 0x22, 0x12, 0x10, 0x03, 0xe5, 0x3a, 0x64, 0x09, 0x70, 0x04, 0xe5, 0x39, 0x64, 0x01, 0x60, 
-0x05, 0x12, 0x2c, 0x07, 0x80, 0x06, 0x12, 0x1d, 0x64, 0x12, 0x1d, 0x6c, 0x02, 0x10, 0x86, 0x12, 
-0x29, 0x93, 0x12, 0x12, 0xbb, 0x90, 0xf8, 0x04, 0xe0, 0xff, 0x60, 0x05, 0x7d, 0x01, 0x12, 0x12, 
-0x58, 0x12, 0x29, 0x1d, 0x12, 0x12, 0xf7, 0x12, 0x11, 0x74, 0x80, 0xe3, 0x12, 0x1c, 0xde, 0xef, 
-0x12, 0x1a, 0x4a, 0xe4, 0xf5, 0x33, 0xf5, 0x34, 0xef, 0x60, 0x03, 0x02, 0x31, 0xbd, 0xe4, 0xff, 
-0x12, 0x31, 0xb1, 0x22, 0x90, 0xff, 0xf0, 0xe0, 0xff, 0x54, 0xa0, 0x60, 0xf7, 0xef, 0x30, 0xe5, 
-0x08, 0x90, 0xff, 0xf0, 0x44, 0x20, 0xf0, 0xc3, 0x22, 0xd3, 0x22, 0x90, 0xff, 0xf0, 0xe0, 0xff, 
-0x54, 0x28, 0x60, 0xf7, 0xef, 0x30, 0xe5, 0x08, 0x90, 0xff, 0xf0, 0x44, 0x20, 0xf0, 0xc3, 0x22, 
-0xd3, 0x22, 0xef, 0x30, 0xe7, 0x08, 0x12, 0x1c, 0x95, 0xe0, 0x54, 0xdf, 0xf0, 0x22, 0xef, 0x12, 
-0x1c, 0xe8, 0xe0, 0x54, 0xdf, 0xf0, 0x22, 0x81, 0x01, 0x82, 0x02, 0x83, 0x03, 0x87, 0x40, 0x00, 
-0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x08, 0x00, 0x78, 0x7e, 0x12, 0x22, 
-0x09, 0xa3, 0xa3, 0xe0, 0xff, 0x30, 0xe7, 0x06, 0x54, 0x7f, 0xf0, 0x44, 0x80, 0xf0, 0x22, 0x85, 
-0x3b, 0x39, 0x85, 0x3c, 0x3a, 0x90, 0xff, 0x82, 0xe0, 0x54, 0xf7, 0xf0, 0xa3, 0xe0, 0x54, 0x7f, 
-0xf0, 0x22, 0xe4, 0xfe, 0xee, 0x90, 0x31, 0x47, 0x93, 0xb5, 0x07, 0x02, 0xd3, 0x22, 0x0e, 0xbe, 
-0x07, 0xf2, 0xc3, 0x22, 0x00, 0x08, 0x18, 0x28, 0x38, 0x01, 0x81, 0x10, 0x0a, 0x02, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x12, 0x10, 0x03, 0x7f, 0x02, 0x12, 0x10, 0x92, 0x12, 0x1d, 0x46, 0x02, 0x10, 
-0x86, 0x75, 0x39, 0x00, 0x8f, 0x3a, 0x12, 0x1c, 0x30, 0x12, 0x2c, 0x07, 0x22, 0x12, 0x1d, 0x6c, 
-0x12, 0x1d, 0x2f, 0x12, 0x1d, 0x64, 0x22, 0xc2, 0x08, 0x22, 
+0xe5, 0x54, 0x30, 0xe1, 0x01, 0x06, 0x78, 0x88, 0xe6, 0x12, 0x22, 0xe7, 0x90, 0x00, 0x0c, 0xef,
+0x12, 0x1a, 0xfa, 0x12, 0x22, 0xb5, 0xa3, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x53, 0x07, 0x0c,
+0x53, 0x06, 0xe6, 0xe5, 0x53, 0x30, 0xe5, 0x03, 0x43, 0x07, 0x01, 0xe5, 0x54, 0x20, 0xe5, 0x0e,
+0xe5, 0x53, 0x54, 0x7f, 0x70, 0x08, 0xe5, 0x53, 0x20, 0xe7, 0x03, 0x43, 0x07, 0x02, 0xe5, 0x53,
+0x30, 0xe3, 0x03, 0x43, 0x07, 0x10, 0xe5, 0x53, 0x30, 0xe2, 0x03, 0x43, 0x07, 0x20, 0xe5, 0x53,
+0x54, 0x03, 0x60, 0x03, 0x43, 0x07, 0x40, 0xe5, 0x53, 0x30, 0xe1, 0x03, 0x43, 0x07, 0x80, 0xe5,
+0x53, 0x30, 0xe4, 0x03, 0x43, 0x06, 0x01, 0xe5, 0x53, 0x30, 0xe6, 0x03, 0x43, 0x06, 0x08, 0xe5,
+0x54, 0x20, 0xe4, 0x0e, 0xe5, 0x53, 0x54, 0x7f, 0x70, 0x08, 0xe5, 0x53, 0x20, 0xe7, 0x03, 0x43,
+0x06, 0x10, 0x53, 0x07, 0xfb, 0x53, 0x06, 0x79, 0x90, 0x00, 0x05, 0xee, 0x8f, 0xf0, 0x12, 0x1b,
+0x9f, 0xe5, 0x55, 0x30, 0xe3, 0x12, 0x54, 0x30, 0xff, 0xc4, 0x54, 0x0f, 0x12, 0x22, 0xe7, 0x90,
+0x00, 0x08, 0xef, 0x12, 0x1a, 0xfa, 0x80, 0x0a, 0x12, 0x22, 0xe8, 0x90, 0x00, 0x08, 0xe4, 0x12,
+0x1a, 0xfa, 0xe5, 0x55, 0x54, 0x03, 0x12, 0x22, 0xe7, 0x90, 0x00, 0x07, 0xef, 0x12, 0x1a, 0xfa,
+0xe5, 0x55, 0x54, 0x04, 0xff, 0xc3, 0x13, 0x90, 0x00, 0x09, 0x12, 0x1a, 0xfa, 0x90, 0x00, 0x07,
+0x12, 0x1a, 0xbb, 0x70, 0x13, 0x12, 0x22, 0xe8, 0xe9, 0x24, 0x09, 0xf9, 0xe4, 0x3a, 0xfa, 0x12,
+0x1a, 0xa2, 0xff, 0xc3, 0x13, 0x12, 0x1a, 0xe8, 0x12, 0x23, 0x27, 0x24, 0x08, 0x12, 0x22, 0xa1,
+0xe0, 0xfe, 0x8d, 0x82, 0x8c, 0x83, 0xe5, 0x82, 0x24, 0x07, 0x12, 0x22, 0xa1, 0xe0, 0xfd, 0xee,
+0xed, 0x12, 0x22, 0xe7, 0x90, 0x00, 0x03, 0xee, 0x8f, 0xf0, 0x12, 0x1b, 0x9f, 0x12, 0x32, 0x84,
+0x7d, 0x0a, 0xe4, 0xff, 0x12, 0x2f, 0xb4, 0x02, 0x10, 0xce, 0x90, 0xfa, 0xe6, 0xe0, 0xb4, 0x03,
+0x06, 0x7e, 0x00, 0x7f, 0x40, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x08, 0x90, 0xfa, 0xda, 0xee, 0xf0,
+0xa3, 0xef, 0xf0, 0x90, 0x00, 0x05, 0x12, 0x1a, 0xbb, 0xff, 0x7e, 0x00, 0x90, 0xfa, 0xd6, 0xee,
+0xf0, 0xa3, 0xef, 0xf0, 0x70, 0x03, 0x7f, 0x08, 0x22, 0x90, 0x00, 0x08, 0x12, 0x1b, 0x48, 0xff,
+0x90, 0xfa, 0xd8, 0xe5, 0xf0, 0xf0, 0xa3, 0xef, 0xf0, 0xae, 0x02, 0xaf, 0x01, 0x8e, 0x50, 0x8f,
+0x51, 0x74, 0x0a, 0x25, 0x51, 0xf5, 0x51, 0xe4, 0x35, 0x50, 0xf5, 0x50, 0x90, 0xfa, 0xdb, 0xe0,
+0xff, 0x14, 0xfe, 0x90, 0xfa, 0xd9, 0xe0, 0x5e, 0xfe, 0xc3, 0xef, 0x9e, 0xff, 0x90, 0xfa, 0xdd,
+0xf0, 0xc3, 0x90, 0xfa, 0xd7, 0xe0, 0x9f, 0x90, 0xfa, 0xd6, 0xe0, 0x94, 0x00, 0x50, 0x06, 0xa3,
+0xe0, 0x90, 0xfa, 0xdd, 0xf0, 0x12, 0x20, 0xa9, 0x60, 0x03, 0xe0, 0xff, 0x22, 0x12, 0x2e, 0x2b,
+0x90, 0xfa, 0xd6, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x4e, 0x60, 0x2b, 0x90, 0xfa, 0xda, 0xe0, 0xfc,
+0xa3, 0xe0, 0xfd, 0xd3, 0xef, 0x9d, 0xee, 0x9c, 0x40, 0x07, 0xe0, 0x90, 0xfa, 0xdd, 0xf0, 0x80,
+0x08, 0x90, 0xfa, 0xd7, 0xe0, 0x90, 0xfa, 0xdd, 0xf0, 0x12, 0x20, 0xa9, 0x60, 0x03, 0xe0, 0xff,
+0x22, 0x12, 0x2e, 0x2b, 0x80, 0xca, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x52, 0xe4, 0xf5, 0x2d, 0xf5,
+0x2e, 0x7d, 0x01, 0x12, 0x26, 0x98, 0x7f, 0x00, 0x22, 0xaa, 0x50, 0xa9, 0x51, 0x7b, 0x01, 0x90,
+0xfa, 0xd8, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0x90, 0xfa, 0xdd, 0xe0, 0xf5, 0x4a, 0x12, 0x29, 0x60,
+0x90, 0xfa, 0xdc, 0xef, 0xf0, 0x22, 0xef, 0x24, 0xae, 0x60, 0x52, 0x24, 0xfe, 0x60, 0x2e, 0x24,
+0xfe, 0x70, 0x03, 0x02, 0x21, 0x69, 0x24, 0x06, 0x60, 0x03, 0x02, 0x21, 0xb1, 0x78, 0x71, 0xe6,
+0x54, 0xfb, 0xf6, 0x90, 0xff, 0xa5, 0xe0, 0xf5, 0x22, 0x44, 0x0f, 0xf0, 0x74, 0x33, 0x90, 0xfa,
+0x94, 0xf0, 0xe5, 0x22, 0xa3, 0xf0, 0x90, 0xfa, 0xb2, 0x74, 0x01, 0xf0, 0x22, 0x78, 0x72, 0xe6,
+0x54, 0xfb, 0xf6, 0x90, 0xff, 0xb5, 0xe0, 0xf5, 0x22, 0x44, 0x0f, 0xf0, 0x74, 0x43, 0x90, 0xfa,
+0x96, 0xf0, 0xe5, 0x22, 0xa3, 0xf0, 0x90, 0xfa, 0xb3, 0x74, 0x01, 0xf0, 0x22, 0x90, 0xfa, 0xa0,
+0xe0, 0xa3, 0x20, 0xe5, 0x03, 0x02, 0x21, 0xb1, 0x90, 0xff, 0xa6, 0xe0, 0x90, 0xfa, 0xcd, 0xf0,
+0xa3, 0xf0, 0x90, 0xfa, 0xcd, 0xe0, 0xff, 0x54, 0x0f, 0xfe, 0x60, 0x10, 0x90, 0xff, 0xa6, 0x12,
+0x23, 0x0d, 0x90, 0xff, 0xa6, 0xe0, 0x90, 0xfa, 0xcd, 0xf0, 0x80, 0xe6, 0x90, 0xfa, 0xce, 0xe0,
+0xff, 0x74, 0x34, 0xfe, 0x12, 0x2d, 0x85, 0xef, 0x70, 0x57, 0x90, 0xfa, 0xce, 0xe0, 0xff, 0x74,
+0x34, 0x90, 0xfa, 0x98, 0xf0, 0xef, 0xa3, 0xf0, 0x22, 0x90, 0xfa, 0xaa, 0xe0, 0xa3, 0x30, 0xe5,
+0x40, 0x90, 0xff, 0xb6, 0xe0, 0x90, 0xfa, 0xcd, 0xf0, 0xa3, 0xf0, 0x90, 0xfa, 0xcd, 0xe0, 0xff,
+0x54, 0x0f, 0xfe, 0x60, 0x10, 0x90, 0xff, 0xb6, 0x12, 0x23, 0x0d, 0x90, 0xff, 0xb6, 0xe0, 0x90,
+0xfa, 0xcd, 0xf0, 0x80, 0xe6, 0x90, 0xfa, 0xce, 0xe0, 0xff, 0x74, 0x44, 0xfe, 0x12, 0x2d, 0x85,
+0xef, 0x70, 0x0e, 0x90, 0xfa, 0xce, 0xe0, 0xff, 0x74, 0x44, 0x90, 0xfa, 0x9a, 0xf0, 0xef, 0xa3,
+0xf0, 0x22, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x00, 0xc0,
+0x00, 0xc0, 0x01, 0xc0, 0x02, 0xc0, 0x03, 0xc0, 0x04, 0xc0, 0x05, 0xc0, 0x06, 0xc0, 0x07, 0x90,
+0xff, 0x92, 0xe0, 0xff, 0x90, 0xfa, 0xcc, 0xf0, 0x90, 0xff, 0x92, 0xe4, 0xf0, 0xef, 0x12, 0x1b,
+0xfc, 0x22, 0x69, 0x26, 0x22, 0x69, 0x2e, 0x22, 0x0c, 0x30, 0x22, 0x0c, 0x32, 0x22, 0x1a, 0x38,
+0x22, 0x2c, 0x3a, 0x22, 0x5e, 0x3e, 0x22, 0x49, 0x44, 0x22, 0x3e, 0x46, 0x22, 0x54, 0x50, 0x22,
+0x54, 0x52, 0x22, 0x54, 0x54, 0x22, 0x54, 0x56, 0x00, 0x00, 0x22, 0x6e, 0x90, 0xfa, 0xcc, 0xe0,
+0xfd, 0x7c, 0x00, 0x7f, 0x01, 0x12, 0x11, 0x5e, 0x80, 0x62, 0x7c, 0x00, 0x7d, 0x01, 0x7f, 0x03,
+0x12, 0x11, 0x5e, 0x90, 0xff, 0xfe, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x50, 0x7c, 0x00, 0x7d, 0x01,
+0x7f, 0x02, 0x12, 0x11, 0x5e, 0x90, 0xff, 0xfe, 0xe0, 0x44, 0x40, 0xf0, 0x80, 0x3e, 0x7c, 0x00,
+0x7d, 0x01, 0x7f, 0x05, 0x12, 0x11, 0x5e, 0x80, 0x33, 0x7c, 0x00, 0x7d, 0x01, 0x7f, 0x06, 0x12,
+0x11, 0x5e, 0x80, 0x28, 0x90, 0xfa, 0xcc, 0xe0, 0xff, 0x12, 0x20, 0xc6, 0x80, 0x1e, 0x7c, 0x00,
+0x7d, 0x01, 0x7f, 0x04, 0x12, 0x11, 0x5e, 0x80, 0x13, 0x12, 0x28, 0x4e, 0x80, 0x0e, 0x90, 0xfa,
+0xcc, 0xe0, 0x24, 0x00, 0xff, 0xe4, 0x34, 0xff, 0xfe, 0x12, 0x2d, 0x85, 0xd0, 0x07, 0xd0, 0x06,
+0xd0, 0x05, 0xd0, 0x04, 0xd0, 0x03, 0xd0, 0x02, 0xd0, 0x01, 0xd0, 0x00, 0xd0, 0xd0, 0xd0, 0x82,
+0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0x78, 0x7c, 0xe6, 0xfe, 0x08, 0xe6, 0x24, 0x04, 0x8e,
+0x83, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0x22, 0x74, 0x13, 0x25, 0x24, 0xf5, 0x82, 0xe4,
+0x34, 0xf9, 0xf5, 0x83, 0x22, 0x78, 0x80, 0xe6, 0xfe, 0x08, 0xe6, 0xf5, 0x82, 0x8e, 0x83, 0x22,
+0x78, 0x80, 0xe6, 0xfe, 0x08, 0xe6, 0xaa, 0x06, 0xf8, 0xac, 0x02, 0x7d, 0x01, 0x7b, 0xff, 0x7a,
+0x32, 0x79, 0x56, 0x7e, 0x00, 0x7f, 0x0a, 0x02, 0x1a, 0x7c, 0x78, 0x80, 0xe6, 0xfc, 0x08, 0xe6,
+0xf5, 0x82, 0x8c, 0x83, 0xa3, 0xa3, 0x22, 0xff, 0x90, 0xf9, 0x6f, 0x02, 0x1b, 0xea, 0x90, 0xf9,
+0x6a, 0x12, 0x1b, 0xea, 0x90, 0x00, 0x04, 0x02, 0x1a, 0xbb, 0x78, 0x7e, 0xe6, 0xfe, 0x08, 0xe6,
+0xff, 0x22, 0xed, 0x12, 0x1a, 0xfa, 0x8f, 0x82, 0x8e, 0x83, 0xe5, 0x82, 0x22, 0xef, 0xf0, 0x90,
+0xfa, 0xce, 0xe0, 0x54, 0x0f, 0x4e, 0xfe, 0xf0, 0xef, 0x54, 0xf0, 0x4e, 0xf0, 0x22, 0x78, 0x80,
+0xe6, 0xfc, 0x08, 0xe6, 0x8c, 0x83, 0x22, 0x78, 0x7e, 0xe6, 0xfc, 0x08, 0xe6, 0xfd, 0x8c, 0x83,
+0x22, 0xa6, 0x07, 0xe6, 0x24, 0x6e, 0xf8, 0xe6, 0x22, 0x78, 0x7e, 0xe6, 0xfa, 0x08, 0xe6, 0xfb,
+0x22, 0x08, 0xe6, 0xfe, 0x08, 0xe6, 0x8e, 0x83, 0x22, 0x26, 0xf6, 0x18, 0xee, 0x36, 0xf6, 0x22,
+0xef, 0x24, 0x0b, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0x22, 0x8b, 0x82, 0x8a, 0x83, 0xe5, 0x82,
+0x22, 0x8b, 0x25, 0x8a, 0x26, 0x89, 0x27, 0x8d, 0x28, 0x90, 0xfa, 0xd2, 0xe4, 0xf0, 0xa3, 0x74,
+0x02, 0xf0, 0x7b, 0x01, 0x7a, 0xfa, 0x79, 0xd1, 0x90, 0xfa, 0xd2, 0xe0, 0xf5, 0x2d, 0xa3, 0xe0,
+0xf5, 0x2e, 0x7d, 0x01, 0x12, 0x26, 0x98, 0x90, 0xfa, 0xd1, 0xe0, 0x65, 0x28, 0x60, 0x46, 0xa3,
+0xe0, 0xff, 0xa3, 0xe0, 0xa3, 0xcf, 0xf0, 0xa3, 0xef, 0xf0, 0x12, 0x23, 0xf0, 0x90, 0xfa, 0xd1,
+0xe0, 0xff, 0x90, 0xfa, 0xd4, 0xe4, 0x8f, 0xf0, 0x12, 0x1b, 0x1c, 0x12, 0x23, 0xf0, 0x90, 0xfa,
+0xd4, 0xe0, 0xff, 0xa3, 0xe0, 0x90, 0xfa, 0xd2, 0xcf, 0xf0, 0xa3, 0xef, 0xf0, 0x90, 0xfa, 0xd1,
+0xe0, 0xa3, 0x75, 0xf0, 0x00, 0x12, 0x1b, 0x1c, 0x90, 0xfa, 0xd2, 0xe4, 0x75, 0xf0, 0x04, 0x12,
+0x1b, 0x1c, 0x02, 0x23, 0x72, 0x90, 0xfa, 0xd3, 0xe0, 0x24, 0x01, 0xff, 0x90, 0xfa, 0xd2, 0xe0,
+0x34, 0x00, 0xab, 0x25, 0xaa, 0x26, 0xa9, 0x27, 0x8f, 0xf0, 0x12, 0x1b, 0x80, 0x7f, 0x00, 0x22,
+0x7b, 0x01, 0x7a, 0xfa, 0x79, 0xd1, 0x90, 0xfa, 0xd2, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x1b, 0x1c,
+0x85, 0xf0, 0x2e, 0xf5, 0x2d, 0x7d, 0x01, 0x02, 0x26, 0x98, 0x8f, 0x62, 0x12, 0x2a, 0xc7, 0x12,
+0x22, 0xfa, 0x8e, 0x83, 0x24, 0x0b, 0x12, 0x22, 0xa1, 0xe0, 0x54, 0xfb, 0xf0, 0x44, 0x02, 0xf0,
+0x08, 0x12, 0x22, 0xdc, 0xe0, 0xa3, 0x30, 0xe5, 0x0c, 0x12, 0x23, 0x06, 0x24, 0x0b, 0x12, 0x22,
+0xa1, 0xe0, 0x44, 0x01, 0xf0, 0x78, 0x7c, 0xe6, 0xfe, 0x08, 0xe6, 0xff, 0xf5, 0x82, 0x8e, 0x83,
+0xe0, 0x54, 0xb8, 0xfd, 0xf0, 0xe5, 0x62, 0x24, 0xfe, 0x44, 0x20, 0xfc, 0x4d, 0xf0, 0xe5, 0x82,
+0x24, 0x04, 0x12, 0x22, 0xa1, 0xe0, 0x54, 0xb8, 0xf0, 0x4c, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3,
+0x74, 0x03, 0xf0, 0x18, 0xe6, 0xfe, 0x08, 0xe6, 0xff, 0x8e, 0x83, 0x24, 0x05, 0x12, 0x22, 0xa1,
+0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0x74, 0x99, 0x25, 0x62, 0xf5, 0x82, 0xe4, 0x34, 0xfa, 0xf5,
+0x83, 0xe0, 0x54, 0xfc, 0x44, 0x03, 0xfc, 0xed, 0x4c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82,
+0x8e, 0x83, 0xe0, 0x44, 0x80, 0xf0, 0xe5, 0x82, 0x24, 0x04, 0x12, 0x22, 0xa1, 0xe0, 0x44, 0x80,
+0xf0, 0x12, 0x32, 0x84, 0x74, 0x6e, 0x25, 0x62, 0xf8, 0x74, 0x04, 0x46, 0xf6, 0x7f, 0x00, 0x22,
+0x12, 0x10, 0x4b, 0x7f, 0x02, 0x12, 0x12, 0x61, 0x78, 0x67, 0xe6, 0x44, 0x02, 0xf6, 0xd2, 0xb0,
+0xd2, 0xb1, 0x90, 0xf9, 0x16, 0xe0, 0x30, 0xe7, 0x07, 0x90, 0xff, 0x9e, 0xe4, 0xf0, 0x80, 0x36,
+0xd2, 0xb3, 0x90, 0xff, 0xa4, 0xe0, 0x90, 0xfa, 0x7e, 0xf0, 0x90, 0xff, 0xb4, 0xe0, 0x90, 0xfa,
+0x7f, 0xf0, 0x90, 0xff, 0xa2, 0xe0, 0x90, 0xfa, 0x7c, 0xf0, 0x90, 0xff, 0xb2, 0xe0, 0x90, 0xfa,
+0x7d, 0xf0, 0x90, 0xff, 0xa4, 0x74, 0x30, 0xf0, 0x90, 0xff, 0xb4, 0xf0, 0x90, 0xff, 0xa2, 0x74,
+0x40, 0xf0, 0x90, 0xff, 0xb2, 0xf0, 0x90, 0xfa, 0xe7, 0xe5, 0xa8, 0xf0, 0x75, 0xa8, 0x81, 0x90,
+0xff, 0x92, 0xe0, 0x60, 0x04, 0xe4, 0xf0, 0x80, 0xf6, 0x90, 0xff, 0xfd, 0x74, 0x3a, 0xf0, 0x43,
+0x87, 0x01, 0x00, 0x00, 0x00, 0x90, 0xfa, 0x7e, 0xe0, 0x90, 0xff, 0xa4, 0xf0, 0x90, 0xfa, 0x7f,
+0xe0, 0x90, 0xff, 0xb4, 0xf0, 0x90, 0xfa, 0x7c, 0xe0, 0x90, 0xff, 0xa2, 0xf0, 0x90, 0xfa, 0x7d,
+0xe0, 0x90, 0xff, 0xb2, 0xf0, 0x90, 0xf9, 0x18, 0xe0, 0x60, 0x02, 0xc2, 0xb3, 0x90, 0xfa, 0xe7,
+0xe0, 0xf5, 0xa8, 0x02, 0x10, 0xce, 0x8b, 0x5c, 0x8a, 0x5d, 0x89, 0x5e, 0x12, 0x2e, 0x0d, 0x90,
+0xfa, 0xc3, 0x12, 0x1b, 0xf3, 0xaa, 0x5d, 0xa9, 0x5e, 0x90, 0xfa, 0xc6, 0x12, 0x1b, 0xf3, 0x90,
+0xfa, 0xc7, 0xe4, 0x75, 0xf0, 0x0a, 0x12, 0x1b, 0x1c, 0x90, 0xfa, 0xc6, 0x12, 0x1b, 0xea, 0xe9,
+0x24, 0x01, 0xf9, 0xe4, 0x3a, 0xfa, 0x90, 0xfa, 0xc9, 0x12, 0x1b, 0xf3, 0xab, 0x5c, 0xaa, 0x5d,
+0xa9, 0x5e, 0x12, 0x2e, 0x19, 0xe0, 0xff, 0xc3, 0x13, 0xf0, 0xe4, 0x78, 0x82, 0xf6, 0x90, 0xfa,
+0xc1, 0xe0, 0xff, 0x78, 0x82, 0xe6, 0xc3, 0x9f, 0x50, 0x4a, 0x90, 0xfa, 0xc3, 0x12, 0x2d, 0xee,
+0xff, 0x78, 0x83, 0xf6, 0x90, 0xfa, 0xc6, 0x12, 0x2d, 0xee, 0xfe, 0xf4, 0x5f, 0xff, 0x78, 0x83,
+0xf6, 0x12, 0x2d, 0xeb, 0x5e, 0x4f, 0xff, 0x78, 0x83, 0xf6, 0x12, 0x2d, 0xf4, 0x75, 0xf0, 0x02,
+0x12, 0x1b, 0x1c, 0x90, 0xfa, 0xc7, 0xe4, 0x75, 0xf0, 0x02, 0x12, 0x1b, 0x1c, 0xab, 0x5c, 0xaa,
+0x5d, 0xa9, 0x5e, 0x90, 0x00, 0x04, 0x12, 0x1a, 0xbb, 0x30, 0xe4, 0x03, 0x12, 0x2e, 0x03, 0x78,
+0x82, 0x06, 0x80, 0xaa, 0xe4, 0x90, 0xfa, 0xc2, 0xf0, 0x22, 0x8b, 0x56, 0x8a, 0x57, 0x89, 0x58,
+0x90, 0xfa, 0xc2, 0x74, 0x06, 0xf0, 0xe4, 0x90, 0xfa, 0xc1, 0xf0, 0x12, 0x1a, 0xa2, 0x24, 0x6e,
+0x60, 0x26, 0x14, 0x70, 0x70, 0x12, 0x2d, 0xda, 0x60, 0x09, 0x24, 0x30, 0x70, 0x12, 0x12, 0x25,
+0x56, 0x80, 0x62, 0x12, 0x2e, 0x24, 0x12, 0x1f, 0xda, 0x90, 0xfa, 0xc2, 0xef, 0xf0, 0x80, 0x55,
+0x90, 0xfa, 0xc2, 0x74, 0x81, 0xf0, 0x80, 0x4d, 0x12, 0x2d, 0xda, 0x60, 0x09, 0x24, 0x30, 0x70,
+0x3e, 0x12, 0x2d, 0x30, 0x80, 0x3f, 0xe5, 0x58, 0x24, 0x03, 0xf9, 0xe4, 0x35, 0x57, 0xfa, 0x7b,
+0x01, 0xc0, 0x03, 0xc0, 0x02, 0xc0, 0x01, 0x12, 0x2e, 0x24, 0x90, 0x00, 0x05, 0x12, 0x1a, 0xbb,
+0xfd, 0x90, 0x00, 0x08, 0x12, 0x1b, 0x48, 0xf5, 0x2e, 0x85, 0xf0, 0x2d, 0xd0, 0x01, 0xd0, 0x02,
+0xd0, 0x03, 0x12, 0x26, 0x98, 0x90, 0xfa, 0xc1, 0xef, 0xf0, 0xe4, 0xa3, 0xf0, 0x80, 0x06, 0x90,
+0xfa, 0xc2, 0x74, 0x81, 0xf0, 0x90, 0xfa, 0xc2, 0xe0, 0x12, 0x2e, 0x24, 0x90, 0x00, 0x02, 0x12,
+0x1a, 0xfa, 0x90, 0xfa, 0xc1, 0xe0, 0xff, 0x22, 0x8b, 0x29, 0x8a, 0x2a, 0x89, 0x2b, 0x8d, 0x2c,
+0xe5, 0x2c, 0x70, 0x03, 0xaf, 0x2c, 0x22, 0x12, 0x2e, 0x53, 0x70, 0x16, 0x12, 0x2e, 0x72, 0xe5,
+0x2d, 0x90, 0xff, 0xf1, 0xf0, 0x12, 0x31, 0xd8, 0x50, 0xf2, 0x12, 0x27, 0x25, 0x40, 0x0b, 0x7f,
+0x00, 0x22, 0x12, 0x2e, 0x72, 0x12, 0x27, 0x25, 0x50, 0xf8, 0x90, 0xff, 0xf3, 0x74, 0xa1, 0xf0,
+0xe5, 0x2c, 0xb4, 0x01, 0x07, 0x90, 0xff, 0xf0, 0xe0, 0x44, 0x02, 0xf0, 0x90, 0xff, 0xf1, 0xe4,
+0xf0, 0xf5, 0x2f, 0xe5, 0x2c, 0x14, 0xff, 0xe5, 0x2f, 0xc3, 0x9f, 0x50, 0x2a, 0x12, 0x31, 0xc1,
+0x40, 0x03, 0xaf, 0x2f, 0x22, 0xc3, 0xe5, 0x2c, 0x95, 0x2f, 0xff, 0xbf, 0x02, 0x07, 0x90, 0xff,
+0xf0, 0xe0, 0x44, 0x02, 0xf0, 0x12, 0x2e, 0x65, 0x05, 0x2f, 0x74, 0x01, 0x25, 0x2b, 0xf5, 0x2b,
+0xe4, 0x35, 0x2a, 0xf5, 0x2a, 0x80, 0xcc, 0x12, 0x31, 0xc1, 0x40, 0x03, 0x7f, 0x18, 0x22, 0x12,
+0x2e, 0x65, 0xaf, 0x2c, 0x22, 0x90, 0xff, 0xf1, 0xe5, 0x2e, 0xf0, 0x02, 0x31, 0xd8, 0x12, 0x10,
+0x4b, 0x78, 0x84, 0x12, 0x23, 0x31, 0x30, 0xe1, 0x08, 0x7f, 0x13, 0x12, 0x31, 0xa9, 0x02, 0x27,
+0xbc, 0x78, 0x84, 0xe6, 0xf9, 0x24, 0x13, 0x12, 0x22, 0xad, 0xe0, 0xff, 0x30, 0xe7, 0x40, 0x54,
+0x03, 0x60, 0x1e, 0xe9, 0xb4, 0x03, 0x0d, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xfe, 0xf0, 0xe0, 0x44,
+0x04, 0xf0, 0x80, 0x46, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xfd, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x80,
+0x39, 0xe9, 0xb4, 0x03, 0x0d, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x01, 0xf0,
+0x80, 0x28, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xf7, 0xf0, 0xe0, 0x44, 0x02, 0xf0, 0x80, 0x1b, 0xef,
+0x54, 0x03, 0x60, 0x14, 0xe9, 0xb4, 0x03, 0x09, 0x90, 0xff, 0xa4, 0xe0, 0x54, 0xdf, 0xf0, 0x80,
+0x07, 0x90, 0xff, 0xb4, 0xe0, 0x54, 0xdf, 0xf0, 0xc2, 0xb3, 0x90, 0xf9, 0x18, 0xe0, 0x04, 0xf0,
+0xaf, 0x01, 0x12, 0x22, 0xee, 0xfd, 0x12, 0x2f, 0xe5, 0x12, 0x31, 0xa9, 0x02, 0x10, 0xce, 0x75,
+0xa8, 0x40, 0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x8b, 0x02, 0x28, 0x09, 0x02, 0x31,
+0x8c, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0x40, 0x03, 0xf6, 0x80, 0x01, 0xf2, 0x08, 0xdf,
+0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, 0x33, 0xc4, 0x54,
+0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4, 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf, 0xe4, 0x80,
+0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x2b, 0xa9, 0xe4, 0x7e, 0x01, 0x93,
+0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09, 0x54, 0x1f, 0xfe, 0xe4, 0x93, 0xa3, 0x60,
+0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3, 0xfa, 0xe4,
+0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xf0, 0xa3,
+0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe, 0xe4, 0xf5,
+0x22, 0x12, 0x1d, 0xc2, 0xe0, 0xb4, 0x04, 0x0d, 0xe5, 0x22, 0x24, 0x03, 0xff, 0x12, 0x30, 0x13,
+0x12, 0x1d, 0xc2, 0xe4, 0xf0, 0x05, 0x22, 0xe5, 0x22, 0xc3, 0x94, 0x02, 0x40, 0xe3, 0xe4, 0xf5,
+0x22, 0x75, 0xf0, 0x02, 0xe5, 0x22, 0x90, 0xfa, 0x94, 0x12, 0x1e, 0x03, 0x60, 0x2c, 0x12, 0x2d,
+0x85, 0xef, 0x60, 0x52, 0x75, 0xf0, 0x02, 0xe5, 0x22, 0x90, 0xfa, 0x94, 0x12, 0x1b, 0xcc, 0xe4,
+0xf0, 0xa3, 0xf0, 0x75, 0xf0, 0x0a, 0xe5, 0x22, 0x90, 0xfa, 0xa0, 0x12, 0x1b, 0xcc, 0xe0, 0xa3,
+0x30, 0xe6, 0x33, 0x12, 0x1d, 0xc2, 0x74, 0x04, 0xf0, 0x22, 0x75, 0xf0, 0x02, 0xe5, 0x22, 0x90,
+0xfa, 0x98, 0x12, 0x1e, 0x03, 0x60, 0x16, 0x12, 0x2d, 0x85, 0xef, 0x60, 0x19, 0x75, 0xf0, 0x02,
+0xe5, 0x22, 0x90, 0xfa, 0x98, 0x12, 0x1b, 0xcc, 0xe4, 0xf0, 0xa3, 0xf0, 0x22, 0x05, 0x22, 0xe5,
+0x22, 0xc3, 0x94, 0x02, 0x40, 0x9b, 0x22, 0xe4, 0xff, 0x90, 0xff, 0x83, 0xe0, 0x54, 0x0f, 0xfe,
+0xef, 0xc3, 0x9e, 0x50, 0x17, 0x74, 0xf0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0xfe, 0xf5, 0x83, 0xe0,
+0x12, 0x1c, 0xc1, 0x12, 0x1a, 0xe8, 0x0f, 0x12, 0x1c, 0xb0, 0x80, 0xdd, 0xef, 0xfd, 0xc3, 0xe5,
+0x3a, 0x9d, 0xf5, 0x3a, 0xe5, 0x39, 0x94, 0x00, 0xf5, 0x39, 0xd3, 0xe5, 0x3a, 0x94, 0x00, 0xe5,
+0x39, 0x94, 0x00, 0x40, 0x06, 0xe4, 0x90, 0xff, 0x83, 0xf0, 0x22, 0x12, 0x1d, 0xdf, 0x12, 0x1e,
+0x34, 0x12, 0x1e, 0x26, 0x12, 0x1a, 0xa2, 0x24, 0x6e, 0x60, 0x1e, 0x14, 0x60, 0x1b, 0x24, 0x8e,
+0x70, 0x2d, 0x90, 0x00, 0x01, 0x12, 0x1a, 0xbb, 0xff, 0x24, 0xfc, 0x60, 0x03, 0x04, 0x70, 0x1f,
+0xef, 0xfd, 0x7c, 0x00, 0x7f, 0x0d, 0x02, 0x11, 0x5e, 0x12, 0x1e, 0x3b, 0x12, 0x25, 0xfa, 0x12,
+0x1d, 0x89, 0x12, 0x1a, 0xbb, 0x60, 0x03, 0x02, 0x32, 0x7a, 0xe4, 0xff, 0x12, 0x32, 0x6e, 0x22,
+0x8b, 0x45, 0x8a, 0x46, 0x89, 0x47, 0x8c, 0x48, 0x8d, 0x49, 0xd2, 0x00, 0x12, 0x2e, 0x53, 0x70,
+0x16, 0x12, 0x2e, 0x72, 0xe5, 0x48, 0x90, 0xff, 0xf1, 0xf0, 0x12, 0x31, 0xd8, 0x50, 0xf2, 0x12,
+0x29, 0xd5, 0x40, 0x0b, 0x7f, 0x18, 0x22, 0x12, 0x2e, 0x72, 0x12, 0x29, 0xd5, 0x50, 0xf8, 0xe4,
+0xf5, 0x4b, 0xe5, 0x4a, 0x14, 0xff, 0xe5, 0x4b, 0xc3, 0x9f, 0x50, 0x17, 0x12, 0x29, 0xc5, 0x40,
+0x03, 0x7f, 0x18, 0x22, 0x05, 0x4b, 0x74, 0x01, 0x25, 0x47, 0xf5, 0x47, 0xe4, 0x35, 0x46, 0xf5,
+0x46, 0x80, 0xdf, 0x90, 0xff, 0xf0, 0xe0, 0x44, 0x01, 0xf0, 0x12, 0x29, 0xc5, 0x40, 0x03, 0x7f,
+0x18, 0x22, 0x7f, 0x00, 0x22, 0xab, 0x45, 0xaa, 0x46, 0xa9, 0x47, 0x12, 0x1a, 0xa2, 0x90, 0xff,
+0xf1, 0xf0, 0x02, 0x31, 0xd8, 0x90, 0xff, 0xf1, 0xe5, 0x49, 0xf0, 0x02, 0x31, 0xd8, 0x7b, 0x01,
+0x7a, 0xfa, 0x79, 0xcf, 0xe4, 0xfd, 0x12, 0x23, 0x61, 0x90, 0xfa, 0xcf, 0xe4, 0x75, 0xf0, 0x09,
+0x12, 0x1b, 0x1c, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x23, 0x90, 0xfa, 0xcf, 0xe4, 0x75, 0xf0, 0x01,
+0x12, 0x1b, 0x32, 0x85, 0xf0, 0x2e, 0xf5, 0x2d, 0x7d, 0x01, 0x12, 0x26, 0x98, 0x90, 0xff, 0xf7,
+0xe5, 0x23, 0x12, 0x2a, 0x39, 0x90, 0xff, 0xf6, 0xe5, 0x23, 0xf0, 0x90, 0xfa, 0xcf, 0xe4, 0xf0,
+0xa3, 0x74, 0x06, 0x12, 0x2a, 0x39, 0xe5, 0x23, 0x30, 0xe0, 0x07, 0x90, 0xff, 0xfc, 0x74, 0x94,
+0xf0, 0x22, 0x90, 0xff, 0xfc, 0x74, 0x90, 0xf0, 0x22, 0xf0, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x23,
+0x90, 0xfa, 0xcf, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x1b, 0x32, 0x85, 0xf0, 0x2e, 0xf5, 0x2d, 0x7d,
+0x01, 0x02, 0x26, 0x98, 0x90, 0xff, 0x93, 0x74, 0x81, 0xf0, 0x90, 0xff, 0xff, 0xe0, 0x60, 0x06,
+0x90, 0xff, 0xfc, 0x74, 0x10, 0xf0, 0x90, 0xff, 0x91, 0xe0, 0x44, 0x90, 0xf0, 0xe4, 0x90, 0xf9,
+0x16, 0xf0, 0xa3, 0xf0, 0x12, 0x2b, 0x39, 0x12, 0x16, 0xc9, 0x12, 0x30, 0x69, 0x7e, 0x07, 0x7f,
+0xd0, 0x12, 0x12, 0x2a, 0x7e, 0x0f, 0x7f, 0xa0, 0x12, 0x12, 0x44, 0xe4, 0x78, 0x77, 0xf6, 0x78,
+0x77, 0xe6, 0xff, 0xc3, 0x94, 0x06, 0x50, 0x0b, 0x74, 0x6e, 0x2f, 0xf8, 0xe4, 0xf6, 0x78, 0x77,
+0x06, 0x80, 0xec, 0x7f, 0x03, 0x12, 0x30, 0xb2, 0x90, 0xf9, 0x16, 0xe0, 0x20, 0xe4, 0x05, 0x7f,
+0x04, 0x12, 0x30, 0xb2, 0x90, 0xff, 0x9b, 0xe4, 0xf0, 0x90, 0xff, 0x9a, 0xf0, 0x90, 0xff, 0xe8,
+0xe0, 0x54, 0x1f, 0xf0, 0xd2, 0xa8, 0x22, 0x15, 0x65, 0xa8, 0x65, 0xa6, 0x07, 0x30, 0x08, 0x05,
+0x12, 0x11, 0xae, 0x80, 0xf8, 0xd2, 0x08, 0xa8, 0x65, 0xe6, 0xff, 0xb4, 0x03, 0x0f, 0x78, 0x7c,
+0x76, 0xff, 0x08, 0x76, 0xe0, 0x08, 0x76, 0xff, 0x08, 0x76, 0xa0, 0x80, 0x0d, 0x78, 0x7c, 0x76,
+0xff, 0x08, 0x76, 0xe2, 0x08, 0x76, 0xff, 0x08, 0x76, 0xb0, 0x78, 0x80, 0x76, 0xfa, 0x08, 0x76,
+0x9e, 0xef, 0x24, 0xfd, 0x75, 0xf0, 0x0a, 0xa4, 0xae, 0xf0, 0x12, 0x23, 0x49, 0x7b, 0x01, 0x7a,
+0xff, 0x79, 0x48, 0x78, 0x68, 0x12, 0x1b, 0xe1, 0xa8, 0x65, 0xe6, 0x24, 0xfd, 0x75, 0xf0, 0x08,
+0xa4, 0xff, 0xae, 0xf0, 0x78, 0x6a, 0x12, 0x23, 0x49, 0x79, 0x08, 0x78, 0x6b, 0x12, 0x1b, 0xe1,
+0x78, 0x6d, 0xef, 0x12, 0x23, 0x49, 0x05, 0x65, 0x22, 0x90, 0xff, 0xf0, 0xe0, 0x54, 0xab, 0xf0,
+0xe0, 0x44, 0x20, 0xf0, 0x90, 0xfa, 0xe6, 0x74, 0x02, 0xf0, 0x7b, 0x01, 0x7a, 0xfa, 0x79, 0xcf,
+0xe4, 0xf5, 0x2d, 0xf5, 0x2e, 0x7d, 0x01, 0x12, 0x26, 0x98, 0x7e, 0x00, 0x90, 0xfa, 0xe4, 0xee,
+0xf0, 0xa3, 0xef, 0xf0, 0x64, 0x01, 0x70, 0x10, 0x90, 0xfa, 0xcf, 0xe0, 0xb4, 0x52, 0x09, 0x90,
+0xf9, 0x16, 0xe0, 0x54, 0xef, 0xf0, 0x80, 0x29, 0x90, 0xfa, 0xe4, 0xe0, 0x70, 0x04, 0xa3, 0xe0,
+0x64, 0x01, 0x70, 0x10, 0x90, 0xfa, 0xcf, 0xe0, 0xb4, 0x10, 0x09, 0x90, 0xf9, 0x16, 0xe0, 0x44,
+0x10, 0xf0, 0x80, 0x0d, 0x90, 0xfa, 0xe6, 0x74, 0x03, 0xf0, 0x90, 0xf9, 0x16, 0xe0, 0x54, 0xef,
+0xf0, 0x90, 0xff, 0xf0, 0xe0, 0x44, 0x20, 0xf0, 0x22, 0x03, 0x68, 0x01, 0xff, 0x48, 0x03, 0x6b,
+0x01, 0xff, 0x08, 0x02, 0x66, 0x00, 0x00, 0x44, 0xfa, 0x98, 0x00, 0x00, 0x00, 0x00, 0x44, 0xfa,
+0x94, 0x00, 0x00, 0x00, 0x00, 0x42, 0xfa, 0xb2, 0x00, 0x00, 0x42, 0xfa, 0x7e, 0x00, 0x00, 0x42,
+0xfa, 0x7c, 0x00, 0x00, 0x42, 0xf9, 0x6d, 0xff, 0xff, 0x42, 0xfa, 0x7a, 0x00, 0x00, 0x41, 0xf9,
+0x66, 0xff, 0x41, 0xf9, 0x1c, 0x19, 0x41, 0xf9, 0x15, 0x00, 0x43, 0xf9, 0x19, 0x0a, 0x32, 0x02,
+0x41, 0xf9, 0x68, 0x20, 0x41, 0xf9, 0x69, 0x20, 0x41, 0xf9, 0x65, 0x00, 0x41, 0xf9, 0x67, 0x00,
+0x44, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf9, 0x16, 0x00, 0x00, 0x41, 0xf9, 0x18, 0x00,
+0x01, 0x20, 0x00, 0x41, 0xf8, 0x04, 0x00, 0x00, 0x12, 0x10, 0x4b, 0x78, 0x8a, 0xef, 0xf6, 0x12,
+0x2a, 0xc7, 0x12, 0x22, 0xee, 0x30, 0xe0, 0x29, 0x78, 0x7c, 0x12, 0x22, 0xb7, 0xe0, 0x54, 0x7f,
+0xf0, 0x78, 0x6b, 0x12, 0x1b, 0xd8, 0x90, 0x00, 0x02, 0x12, 0x1a, 0xbb, 0x30, 0xe7, 0x09, 0x90,
+0x00, 0x02, 0xe4, 0x12, 0x1a, 0xfa, 0x80, 0xe9, 0x78, 0x7c, 0x12, 0x22, 0xb7, 0xe0, 0x44, 0x80,
+0xf0, 0x12, 0x22, 0xee, 0x30, 0xe1, 0x1e, 0x12, 0x22, 0x97, 0xe0, 0x54, 0x7f, 0xf0, 0x12, 0x32,
+0x19, 0x78, 0x68, 0x12, 0x1b, 0xd8, 0x90, 0x00, 0x02, 0x74, 0x80, 0x12, 0x1a, 0xfa, 0x12, 0x22,
+0x97, 0xe0, 0x44, 0x80, 0xf0, 0x12, 0x32, 0x84, 0xe4, 0xff, 0x12, 0x31, 0xa9, 0x02, 0x10, 0xce,
+0x12, 0x10, 0x4b, 0x78, 0x85, 0xef, 0xf6, 0x12, 0x31, 0x50, 0x12, 0x31, 0xa9, 0x78, 0x85, 0xe6,
+0xff, 0x24, 0x13, 0x12, 0x22, 0xad, 0xe0, 0xfe, 0x30, 0xe7, 0x16, 0xef, 0xb4, 0x03, 0x09, 0x90,
+0xff, 0x9e, 0xe0, 0x54, 0xfa, 0xf0, 0x80, 0x22, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xf5, 0xf0, 0x80,
+0x19, 0xee, 0x54, 0x03, 0x60, 0x14, 0xef, 0xb4, 0x03, 0x09, 0x90, 0xff, 0xa4, 0xe0, 0x44, 0x20,
+0xf0, 0x80, 0x07, 0x90, 0xff, 0xb4, 0xe0, 0x44, 0x20, 0xf0, 0x90, 0xf9, 0x18, 0xe0, 0x14, 0xf0,
+0xe0, 0x70, 0x02, 0xd2, 0xb3, 0x02, 0x10, 0xce, 0x12, 0x1e, 0x1c, 0xe5, 0x3a, 0x64, 0x09, 0x70,
+0x04, 0xe5, 0x39, 0x64, 0x01, 0x60, 0x48, 0xc3, 0xe5, 0x3a, 0x94, 0x08, 0xe5, 0x39, 0x94, 0x00,
+0x40, 0x11, 0x7f, 0x08, 0xef, 0xe5, 0x3a, 0x94, 0x08, 0xf5, 0x3a, 0xe5, 0x39, 0x94, 0x00, 0xf5,
+0x39, 0x80, 0x05, 0xaf, 0x3a, 0x12, 0x1e, 0x34, 0xe4, 0xfe, 0xee, 0xc3, 0x9f, 0x50, 0x19, 0x12,
+0x1c, 0xc1, 0x12, 0x1a, 0xa2, 0xfd, 0x74, 0xf8, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0xfe, 0xf5, 0x83,
+0xed, 0xf0, 0x0e, 0x12, 0x1c, 0xb0, 0x80, 0xe2, 0xef, 0x54, 0x7f, 0x90, 0xff, 0x81, 0xf0, 0x22,
+0x8b, 0x59, 0x8a, 0x5a, 0x89, 0x5b, 0x12, 0x2e, 0x19, 0x70, 0x05, 0xa3, 0x74, 0x08, 0xf0, 0x22,
+0xab, 0x59, 0xaa, 0x5a, 0xa9, 0x5b, 0x12, 0x2e, 0x0d, 0x90, 0xfa, 0xc9, 0x12, 0x1b, 0xf3, 0xe5,
+0x5b, 0x24, 0x03, 0xf9, 0xe4, 0x35, 0x5a, 0xfa, 0x90, 0xfa, 0xc3, 0x12, 0x1b, 0xf3, 0xe4, 0x90,
+0xfa, 0xc2, 0xf0, 0x78, 0x8b, 0xf6, 0x90, 0xfa, 0xc1, 0xe0, 0xff, 0x78, 0x8b, 0xe6, 0xc3, 0x9f,
+0x50, 0x12, 0x12, 0x2d, 0xeb, 0xff, 0x12, 0x2d, 0xf4, 0x12, 0x2e, 0x07, 0x78, 0x8b, 0x06, 0x12,
+0x2e, 0x03, 0x80, 0xe2, 0x22, 0xad, 0x07, 0xac, 0x06, 0x90, 0x32, 0x0a, 0xe4, 0x93, 0xff, 0x78,
+0x74, 0xf6, 0x54, 0x0f, 0x12, 0x1d, 0xa8, 0xe0, 0x08, 0x76, 0x00, 0x08, 0xf6, 0x18, 0x12, 0x1c,
+0xd9, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff, 0x78, 0x75, 0xee, 0xf6, 0x08, 0xef, 0xf6,
+0xee, 0x44, 0xf8, 0x18, 0xf6, 0xef, 0x08, 0xf6, 0x90, 0xff, 0x7a, 0xe0, 0x20, 0xe7, 0x03, 0x7f,
+0x00, 0x22, 0x78, 0x75, 0xe6, 0xfe, 0x08, 0xe6, 0xf5, 0x82, 0x8e, 0x83, 0xec, 0xf0, 0xa3, 0xed,
+0xf0, 0x90, 0xff, 0x7a, 0x74, 0x02, 0xf0, 0x7f, 0x01, 0x22, 0xab, 0x56, 0xaa, 0x57, 0xa9, 0x58,
+0x90, 0x00, 0x03, 0x12, 0x1a, 0xbb, 0x54, 0xf0, 0x24, 0xa0, 0x22, 0x90, 0xfa, 0xc9, 0x12, 0x1b,
+0xea, 0x02, 0x1a, 0xa2, 0x90, 0xfa, 0xc3, 0x12, 0x1b, 0xea, 0xef, 0x12, 0x1a, 0xe8, 0x90, 0xfa,
+0xca, 0xe4, 0x22, 0x90, 0xfa, 0xc4, 0xe4, 0x75, 0xf0, 0x01, 0x02, 0x1b, 0x1c, 0x90, 0x00, 0x08,
+0x12, 0x1b, 0x48, 0xaa, 0xf0, 0xf9, 0x7b, 0x01, 0x22, 0x90, 0x00, 0x05, 0x12, 0x1a, 0xbb, 0x90,
+0xfa, 0xc1, 0xf0, 0x22, 0xab, 0x56, 0xaa, 0x57, 0xa9, 0x58, 0x22, 0x90, 0xfa, 0xdd, 0xe0, 0xff,
+0x7e, 0x00, 0xc3, 0x90, 0xfa, 0xd7, 0xe0, 0x9f, 0xf0, 0x90, 0xfa, 0xd6, 0xe0, 0x9e, 0xf0, 0x90,
+0xfa, 0xd8, 0xee, 0x8f, 0xf0, 0x12, 0x1b, 0x1c, 0xef, 0x25, 0x51, 0xf5, 0x51, 0xee, 0x35, 0x50,
+0xf5, 0x50, 0x22, 0x90, 0xff, 0xf0, 0xe0, 0x54, 0xfe, 0xf0, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0xfa,
+0xe6, 0xe0, 0x64, 0x03, 0x22, 0x90, 0xff, 0xf2, 0xe0, 0xab, 0x29, 0xaa, 0x2a, 0xa9, 0x2b, 0x02,
+0x1a, 0xe8, 0x90, 0xff, 0xf3, 0x74, 0xa0, 0xf0, 0x22, 0x8f, 0x64, 0xed, 0x70, 0x0f, 0xe5, 0x64,
+0xb4, 0x03, 0x05, 0x7f, 0x01, 0x02, 0x31, 0xef, 0x7f, 0x02, 0x02, 0x31, 0xef, 0xaf, 0x64, 0x12,
+0x2a, 0xc7, 0x74, 0x6e, 0x25, 0x64, 0xf8, 0xe6, 0x30, 0xe2, 0x0b, 0xd2, 0x09, 0x12, 0x1d, 0x33,
+0xe0, 0x54, 0x7f, 0xf0, 0x80, 0x02, 0xc2, 0x09, 0xe5, 0x64, 0xb4, 0x03, 0x07, 0x7f, 0x81, 0x12,
+0x31, 0xef, 0x80, 0x05, 0x7f, 0x82, 0x12, 0x31, 0xef, 0x30, 0x09, 0x07, 0x12, 0x1d, 0x33, 0xe0,
+0x44, 0x80, 0xf0, 0x12, 0x32, 0x84, 0x22, 0x12, 0x10, 0x4b, 0x90, 0xff, 0xfd, 0xe0, 0x44, 0x60,
+0xf0, 0xd2, 0x01, 0x90, 0xff, 0xfc, 0xe0, 0x44, 0x02, 0xf0, 0x90, 0xff, 0x00, 0xe0, 0x30, 0xe7,
+0x13, 0x90, 0xff, 0x83, 0xe0, 0x44, 0x80, 0xf0, 0x43, 0x35, 0x80, 0x90, 0xff, 0xfc, 0xe0, 0x44,
+0x01, 0xf0, 0x80, 0x0d, 0x12, 0x1d, 0xdf, 0x53, 0x35, 0x7f, 0x90, 0xff, 0xfc, 0xe0, 0x54, 0xfe,
+0xf0, 0x90, 0xff, 0x81, 0xe0, 0x44, 0x80, 0xf0, 0x12, 0x02, 0xde, 0x12, 0x1d, 0xe7, 0x02, 0x10,
+0xce, 0x12, 0x10, 0x4b, 0x78, 0x89, 0xef, 0xf6, 0xd2, 0x00, 0x12, 0x2a, 0xc7, 0x90, 0xf9, 0x6a,
+0x12, 0x1b, 0xea, 0xe9, 0x24, 0x03, 0xf9, 0xe4, 0x3a, 0xfa, 0xc0, 0x02, 0x78, 0x80, 0xe6, 0xfe,
+0x08, 0xe6, 0xaa, 0x06, 0xf8, 0xac, 0x02, 0x7d, 0x01, 0xd0, 0x02, 0x12, 0x22, 0xd3, 0x12, 0x32,
+0x84, 0x78, 0x89, 0xe6, 0xff, 0x12, 0x13, 0x87, 0x12, 0x31, 0xa9, 0x02, 0x10, 0xce, 0x8f, 0x63,
+0x12, 0x2a, 0xc7, 0x78, 0x7c, 0x12, 0x22, 0xb7, 0xe0, 0x54, 0x3f, 0xf0, 0xe5, 0x82, 0x24, 0x04,
+0x12, 0x22, 0xa1, 0xe0, 0x54, 0x3f, 0xf0, 0x12, 0x23, 0x41, 0x24, 0x0b, 0x12, 0x22, 0xa1, 0xe0,
+0x54, 0xf8, 0xf0, 0x12, 0x32, 0x84, 0x74, 0x6e, 0x25, 0x63, 0xf8, 0x74, 0xfb, 0x56, 0xf6, 0x7f,
+0x00, 0x22, 0x12, 0x10, 0x4b, 0x12, 0x2a, 0xc7, 0x12, 0x22, 0xfa, 0x24, 0x06, 0x12, 0x22, 0x9f,
+0xe0, 0xfd, 0x12, 0x22, 0xe8, 0x90, 0x00, 0x03, 0x12, 0x23, 0x02, 0x24, 0x05, 0x12, 0x22, 0xa1,
+0xe0, 0x90, 0x00, 0x04, 0x12, 0x1a, 0xfa, 0x12, 0x32, 0x84, 0x7d, 0x02, 0xe4, 0xff, 0x12, 0x2f,
+0xb4, 0x02, 0x10, 0xce, 0xae, 0x05, 0x12, 0x1d, 0x8e, 0xef, 0x12, 0x1a, 0xfa, 0x0e, 0x0e, 0x0e,
+0xee, 0xd3, 0x95, 0x3c, 0xe4, 0x95, 0x3b, 0x40, 0x02, 0xae, 0x3c, 0xee, 0xd3, 0x94, 0x08, 0x74,
+0x80, 0x94, 0x81, 0x40, 0x0a, 0x7e, 0x03, 0x90, 0x00, 0x02, 0x74, 0x02, 0x12, 0x1a, 0xfa, 0xaf,
+0x06, 0x12, 0x32, 0x6e, 0x22, 0xae, 0x07, 0xed, 0x54, 0x03, 0x64, 0x01, 0x60, 0x03, 0x7f, 0x10,
+0x22, 0xed, 0x54, 0x7c, 0xc3, 0x94, 0x04, 0x50, 0x03, 0x7f, 0x0b, 0x22, 0x74, 0x6e, 0x2e, 0xf8,
+0x74, 0x02, 0x46, 0xf6, 0x74, 0x99, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0xfa, 0xf5, 0x83, 0xed, 0xf0,
+0x7f, 0x00, 0x22, 0xbf, 0x03, 0x06, 0x7c, 0xff, 0x7d, 0xe0, 0x80, 0x04, 0x7c, 0xff, 0x7d, 0xe2,
+0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x44, 0x80, 0xf0, 0xe5, 0x82, 0x24, 0x04, 0x12, 0x22, 0xa1, 0xe0,
+0x44, 0x80, 0xf0, 0x74, 0x6e, 0x2f, 0xf8, 0x74, 0x04, 0x46, 0xf6, 0x7f, 0x00, 0x22, 0x12, 0x10,
+0x4b, 0xe5, 0x3a, 0x64, 0x09, 0x70, 0x04, 0xe5, 0x39, 0x64, 0x01, 0x60, 0x16, 0x90, 0xff, 0x83,
+0xe0, 0x54, 0x0f, 0xff, 0xc3, 0xe5, 0x3a, 0x9f, 0xe5, 0x39, 0x94, 0x00, 0x40, 0x05, 0x12, 0x28,
+0xd7, 0x80, 0x03, 0x12, 0x32, 0x7a, 0x02, 0x10, 0xce, 0x90, 0xff, 0xfc, 0xe0, 0x20, 0xe7, 0x1f,
+0xc2, 0xaf, 0x7d, 0xff, 0xac, 0x05, 0x1d, 0xec, 0x60, 0x15, 0x7e, 0x04, 0x7f, 0x00, 0xef, 0x1f,
+0xaa, 0x06, 0x70, 0x01, 0x1e, 0x4a, 0x60, 0xec, 0x90, 0xff, 0x92, 0xe4, 0xf0, 0x80, 0xef, 0x22,
+0x12, 0x10, 0x4b, 0x78, 0x66, 0xe6, 0xfe, 0x08, 0xe6, 0xff, 0x30, 0xe0, 0x12, 0x30, 0xe1, 0x0f,
+0x90, 0xff, 0xfc, 0xe0, 0x44, 0x20, 0xf0, 0x7f, 0x04, 0x12, 0x12, 0x61, 0x12, 0x1d, 0xf6, 0x02,
+0x10, 0xce, 0x8f, 0x23, 0xc2, 0x08, 0x12, 0x2a, 0xc7, 0x12, 0x22, 0xc0, 0x78, 0x7e, 0x12, 0x23,
+0x42, 0x24, 0x0b, 0x12, 0x22, 0xa1, 0xe0, 0x54, 0xf8, 0xf0, 0x12, 0x32, 0x84, 0xaf, 0x23, 0x12,
+0x13, 0x87, 0x22, 0x8e, 0x5f, 0x8f, 0x60, 0xe5, 0x60, 0x15, 0x60, 0xae, 0x5f, 0x70, 0x02, 0x15,
+0x5f, 0xd3, 0x94, 0x00, 0xee, 0x94, 0x00, 0x40, 0x09, 0x7e, 0x07, 0x7f, 0xd0, 0x12, 0x10, 0x24,
+0x80, 0xe5, 0x22, 0x11, 0xdc, 0x2e, 0xc7, 0x24, 0xb0, 0x32, 0x60, 0x30, 0x90, 0x30, 0x3e, 0x31,
+0x6f, 0x2f, 0x82, 0x27, 0x2e, 0x2c, 0x80, 0x31, 0x12, 0x31, 0x31, 0x1e, 0x64, 0x2f, 0x11, 0x2c,
+0x18, 0x0e, 0x12, 0x10, 0x4b, 0x78, 0x86, 0x12, 0x23, 0x31, 0x20, 0xe1, 0x07, 0x7f, 0x12, 0x12,
+0x31, 0xa9, 0x80, 0x0a, 0x78, 0x86, 0xe6, 0xff, 0x12, 0x24, 0x0a, 0x12, 0x31, 0xa9, 0x02, 0x10,
+0xce, 0x12, 0x10, 0x4b, 0x78, 0x87, 0x12, 0x23, 0x31, 0x20, 0xe2, 0x07, 0x7f, 0x11, 0x12, 0x31,
+0xa9, 0x80, 0x0a, 0x78, 0x87, 0xe6, 0xff, 0x12, 0x2f, 0x4e, 0x12, 0x31, 0xa9, 0x02, 0x10, 0xce,
+0x8f, 0x61, 0x12, 0x2f, 0x4e, 0xaf, 0x61, 0x12, 0x2a, 0xc7, 0x12, 0x22, 0xc0, 0x12, 0x32, 0x84,
+0x74, 0x6e, 0x25, 0x61, 0xf8, 0x74, 0xfd, 0x56, 0xf6, 0xaf, 0x61, 0x12, 0x13, 0x87, 0x22, 0x12,
+0x10, 0x4b, 0xe5, 0x3a, 0x64, 0x09, 0x70, 0x04, 0xe5, 0x39, 0x64, 0x01, 0x60, 0x05, 0x12, 0x2c,
+0xd8, 0x80, 0x06, 0x12, 0x1e, 0x14, 0x12, 0x1e, 0x1c, 0x02, 0x10, 0xce, 0x12, 0x2a, 0x54, 0x12,
+0x13, 0x03, 0x90, 0xf8, 0x04, 0xe0, 0xff, 0x60, 0x05, 0x7d, 0x01, 0x12, 0x12, 0xa0, 0x12, 0x29,
+0xde, 0x12, 0x13, 0x3f, 0x12, 0x11, 0xbc, 0x80, 0xe3, 0x12, 0x1d, 0x8e, 0xef, 0x12, 0x1a, 0xfa,
+0xe4, 0xf5, 0x33, 0xf5, 0x34, 0xef, 0x60, 0x03, 0x02, 0x32, 0x7a, 0xe4, 0xff, 0x12, 0x32, 0x6e,
+0x22, 0x90, 0xff, 0xf0, 0xe0, 0xff, 0x54, 0xa0, 0x60, 0xf7, 0xef, 0x30, 0xe5, 0x08, 0x90, 0xff,
+0xf0, 0x44, 0x20, 0xf0, 0xc3, 0x22, 0xd3, 0x22, 0x90, 0xff, 0xf0, 0xe0, 0xff, 0x54, 0x28, 0x60,
+0xf7, 0xef, 0x30, 0xe5, 0x08, 0x90, 0xff, 0xf0, 0x44, 0x20, 0xf0, 0xc3, 0x22, 0xd3, 0x22, 0xef,
+0x30, 0xe7, 0x08, 0x12, 0x1d, 0x45, 0xe0, 0x54, 0xdf, 0xf0, 0x22, 0xef, 0x12, 0x1d, 0x98, 0xe0,
+0x54, 0xdf, 0xf0, 0x22, 0x81, 0x01, 0x82, 0x02, 0x83, 0x03, 0x87, 0x40, 0x00, 0x40, 0x00, 0x40,
+0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x08, 0x00, 0x78, 0x7e, 0x12, 0x22, 0xb7, 0xa3, 0xa3,
+0xe0, 0xff, 0x30, 0xe7, 0x06, 0x54, 0x7f, 0xf0, 0x44, 0x80, 0xf0, 0x22, 0x85, 0x3b, 0x39, 0x85,
+0x3c, 0x3a, 0x90, 0xff, 0x82, 0xe0, 0x54, 0xf7, 0xf0, 0xa3, 0xe0, 0x54, 0x7f, 0xf0, 0x22, 0xe4,
+0xfe, 0xee, 0x90, 0x32, 0x04, 0x93, 0xb5, 0x07, 0x02, 0xd3, 0x22, 0x0e, 0xbe, 0x07, 0xf2, 0xc3,
+0x22, 0x00, 0x08, 0x18, 0x28, 0x38, 0x01, 0x81, 0x90, 0x0a, 0x02, 0x00, 0x00, 0x11, 0x13, 0x00,
+0x12, 0x10, 0x4b, 0x7f, 0x02, 0x12, 0x10, 0xda, 0x12, 0x1d, 0xf6, 0x02, 0x10, 0xce, 0x75, 0x39,
+0x00, 0x8f, 0x3a, 0x12, 0x1c, 0xe0, 0x12, 0x2c, 0xd8, 0x22, 0x12, 0x1e, 0x1c, 0x12, 0x1d, 0xdf,
+0x12, 0x1e, 0x14, 0x22, 0xc2, 0x08, 0x22,
 };
 
 #undef IMAGE_VERSION_NAME
index 544098d2b775178651ebeccdb2ec4893ca42da2e..0d3903691e8c4a03a048c0c65e8c064e2ed52a49 100644 (file)
@@ -48,7 +48,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.7"
+#define DRIVER_VERSION "v0.7mode043006"
 #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com> and David Iacovelli"
 #define DRIVER_DESC "Edgeport USB Serial Driver"
 
@@ -173,8 +173,12 @@ static struct usb_device_id edgeport_2port_id_table [] = {
        { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_221C) },
        { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_22C) },
        { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_21C) },
-// The 4-port shows up as two 2-port devices
+       /* The 4, 8 and 16 port devices show up as multiple 2 port devices */
        { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_4S) },
+       { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_8) },
+       { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_8S) },
+       { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416) },
+       { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416B) },
        { }
 };
 
@@ -209,6 +213,10 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_22C) },
        { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_21C) },
        { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_4S) },
+       { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_8) },
+       { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_8S) },
+       { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416) },
+       { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416B) },
        { }
 };
 
@@ -231,6 +239,7 @@ 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 void edge_tty_recv(struct device *dev, struct tty_struct *tty, unsigned char *data, int length);
@@ -241,6 +250,10 @@ 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);
 
+/* sysfs attributes */
+static int edge_create_sysfs_attrs(struct usb_serial_port *port);
+static int edge_remove_sysfs_attrs(struct usb_serial_port *port);
+
 /* circular buffer */
 static struct edge_buf *edge_buf_alloc(unsigned int size);
 static void edge_buf_free(struct edge_buf *eb);
@@ -1706,13 +1719,14 @@ static void edge_interrupt_callback (struct urb *urb)
        int length = urb->actual_length;
        int port_number;
        int function;
-       int status;
+       int retval;
        __u8 lsr;
        __u8 msr;
+       int status = urb->status;
 
        dbg("%s", __FUNCTION__);
 
-       switch (urb->status) {
+       switch (status) {
        case 0:
                /* success */
                break;
@@ -1720,10 +1734,12 @@ static void edge_interrupt_callback (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",
+                   __FUNCTION__, status);
                return;
        default:
-               dev_err(&urb->dev->dev, "%s - nonzero urb status received: %d\n", __FUNCTION__, urb->status);
+               dev_err(&urb->dev->dev, "%s - nonzero urb status received: "
+                       "%d\n", __FUNCTION__, status);
                goto exit;
        }
 
@@ -1781,10 +1797,10 @@ static void edge_interrupt_callback (struct urb *urb)
        }
 
 exit:
-       status = usb_submit_urb (urb, GFP_ATOMIC);
-       if (status)
+       retval = usb_submit_urb (urb, GFP_ATOMIC);
+       if (retval)
                dev_err (&urb->dev->dev, "%s - usb_submit_urb failed with result %d\n",
-                        __FUNCTION__, status);
+                        __FUNCTION__, retval);
 }
 
 static void edge_bulk_in_callback (struct urb *urb)
@@ -1792,12 +1808,13 @@ static void edge_bulk_in_callback (struct urb *urb)
        struct edgeport_port *edge_port = (struct edgeport_port *)urb->context;
        unsigned char *data = urb->transfer_buffer;
        struct tty_struct *tty;
-       int status = 0;
+       int retval = 0;
        int port_number;
+       int status = urb->status;
 
        dbg("%s", __FUNCTION__);
 
-       switch (urb->status) {
+       switch (status) {
        case 0:
                /* success */
                break;
@@ -1805,17 +1822,18 @@ static void edge_bulk_in_callback (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",
+                   __FUNCTION__, status);
                return;
        default:
                dev_err (&urb->dev->dev,"%s - nonzero read bulk status received: %d\n",
-                    __FUNCTION__, urb->status );
+                    __FUNCTION__, status);
        }
 
-       if (urb->status == -EPIPE)
+       if (status == -EPIPE)
                goto exit;
 
-       if (urb->status) {
+       if (status) {
                dev_err(&urb->dev->dev,"%s - stopping read!\n", __FUNCTION__);
                return;
        }
@@ -1849,14 +1867,14 @@ exit:
        spin_lock(&edge_port->ep_lock);
        if (edge_port->ep_read_urb_state == EDGE_READ_URB_RUNNING) {
                urb->dev = edge_port->port->serial->dev;
-               status = usb_submit_urb(urb, GFP_ATOMIC);
+               retval = usb_submit_urb(urb, GFP_ATOMIC);
        } else if (edge_port->ep_read_urb_state == EDGE_READ_URB_STOPPING) {
                edge_port->ep_read_urb_state = EDGE_READ_URB_STOPPED;
        }
        spin_unlock(&edge_port->ep_lock);
-       if (status)
+       if (retval)
                dev_err (&urb->dev->dev, "%s - usb_submit_urb failed with result %d\n",
-                        __FUNCTION__, status);
+                        __FUNCTION__, retval);
 }
 
 static void edge_tty_recv(struct device *dev, struct tty_struct *tty, unsigned char *data, int length)
@@ -1883,12 +1901,13 @@ static void edge_bulk_out_callback (struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        struct edgeport_port *edge_port = usb_get_serial_port_data(port);
+       int status = urb->status;
 
        dbg ("%s - port %d", __FUNCTION__, port->number);
 
        edge_port->ep_write_urb_in_use = 0;
 
-       switch (urb->status) {
+       switch (status) {
        case 0:
                /* success */
                break;
@@ -1896,11 +1915,12 @@ static void edge_bulk_out_callback (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",
+                   __FUNCTION__, status);
                return;
        default:
-               dev_err (&urb->dev->dev,"%s - nonzero write bulk status received: %d\n",
-                    __FUNCTION__, urb->status);
+               dev_err(&urb->dev->dev, "%s - nonzero write bulk status "
+                       "received: %d\n", __FUNCTION__, status);
        }
 
        /* send any buffered data */
@@ -2351,7 +2371,7 @@ static int restart_read(struct edgeport_port *edge_port)
                urb->complete = edge_bulk_in_callback;
                urb->context = edge_port;
                urb->dev = edge_port->port->serial->dev;
-               status = usb_submit_urb(urb, GFP_KERNEL);
+               status = usb_submit_urb(urb, GFP_ATOMIC);
        }
        edge_port->ep_read_urb_state = EDGE_READ_URB_RUNNING;
        edge_port->shadow_mcr |= MCR_RTS;
@@ -2524,14 +2544,6 @@ static void edge_set_termios (struct usb_serial_port *port, struct ktermios *old
        }
 
        cflag = tty->termios->c_cflag;
-       /* check that they really want us to change something */
-       if (old_termios) {
-               if (cflag == old_termios->c_cflag &&
-                   tty->termios->c_iflag == old_termios->c_iflag) {
-                       dbg ("%s - nothing to change", __FUNCTION__);
-                       return;
-               }
-       }
 
        dbg("%s - clfag %08x iflag %08x", __FUNCTION__, 
            tty->termios->c_cflag, tty->termios->c_iflag);
@@ -2758,7 +2770,7 @@ static int edge_startup (struct usb_serial *serial)
                edge_port->port = serial->port[i];
                edge_port->edge_serial = edge_serial;
                usb_set_serial_port_data(serial->port[i], edge_port);
-               edge_port->bUartMode = 0;       /* Default is RS232 */
+               edge_port->bUartMode = default_uart_mode;
        }
        
        return 0;
@@ -2784,6 +2796,7 @@ static void edge_shutdown (struct usb_serial *serial)
 
        for (i=0; i < serial->num_ports; ++i) {
                edge_port = usb_get_serial_port_data(serial->port[i]);
+               edge_remove_sysfs_attrs(edge_port->port);
                if (edge_port) {
                        edge_buf_free(edge_port->ep_out_buf);
                        kfree(edge_port);
@@ -2795,6 +2808,48 @@ static void edge_shutdown (struct usb_serial *serial)
 }
 
 
+/* Sysfs Attributes */
+
+static ssize_t show_uart_mode(struct device *dev,
+       struct device_attribute *attr, char *buf)
+{
+       struct usb_serial_port *port = to_usb_serial_port(dev);
+       struct edgeport_port *edge_port = usb_get_serial_port_data(port);
+
+       return sprintf(buf, "%d\n", edge_port->bUartMode);
+}
+
+static ssize_t store_uart_mode(struct device *dev,
+       struct device_attribute *attr, const char *valbuf, size_t count)
+{
+       struct usb_serial_port *port = to_usb_serial_port(dev);
+       struct edgeport_port *edge_port = usb_get_serial_port_data(port);
+       unsigned int v = simple_strtoul(valbuf, NULL, 0);
+
+       dbg("%s: setting uart_mode = %d", __FUNCTION__, v);
+
+       if (v < 256)
+               edge_port->bUartMode = v;
+       else
+               dev_err(dev, "%s - uart_mode %d is invalid\n", __FUNCTION__, v);
+
+       return count;
+}
+
+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)
+{
+       return device_create_file(&port->dev, &dev_attr_uart_mode);
+}
+
+static int edge_remove_sysfs_attrs(struct usb_serial_port *port)
+{
+       device_remove_file(&port->dev, &dev_attr_uart_mode);
+       return 0;
+}
+
+
 /* Circular Buffer */
 
 /*
@@ -2991,6 +3046,7 @@ static struct usb_serial_driver edgeport_1port_device = {
        .unthrottle             = edge_unthrottle,
        .attach                 = edge_startup,
        .shutdown               = edge_shutdown,
+       .port_probe             = edge_create_sysfs_attrs,
        .ioctl                  = edge_ioctl,
        .set_termios            = edge_set_termios,
        .tiocmget               = edge_tiocmget,
@@ -3022,6 +3078,7 @@ static struct usb_serial_driver edgeport_2port_device = {
        .unthrottle             = edge_unthrottle,
        .attach                 = edge_startup,
        .shutdown               = edge_shutdown,
+       .port_probe             = edge_create_sysfs_attrs,
        .ioctl                  = edge_ioctl,
        .set_termios            = edge_set_termios,
        .tiocmget               = edge_tiocmget,
@@ -3085,3 +3142,6 @@ 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_param(default_uart_mode, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(default_uart_mode, "Default uart_mode, 0=RS232, ...");
+
index e57fa117e48639abf58a71fce3e92d0b66e7b7fd..8e1a491e52a99d72f84ddf5a72d2f5e642b0be2d 100644 (file)
 #define ION_DEVICE_ID_TI_EDGEPORT_2I           0x0207  // Edgeport/2i RS422/RS485
 #define ION_DEVICE_ID_TI_EDGEPORT_421          0x020C  // Edgeport/421 4 hub 2 RS232 + Parallel (lucent on a different hub port)
 #define ION_DEVICE_ID_TI_EDGEPORT_21           0x020D  // Edgeport/21 2 RS232 + Parallel (lucent on a different hub port)
-#define ION_DEVICE_ID_TI_EDGEPORT_8            0x020F  // Edgeport/8 (single-CPU)
+#define ION_DEVICE_ID_TI_EDGEPORT_416          0x0212  // Edgeport/416
 #define ION_DEVICE_ID_TI_EDGEPORT_1            0x0215  // Edgeport/1 RS232
 #define ION_DEVICE_ID_TI_EDGEPORT_42           0x0217  // Edgeport/42 4 hub 2 RS232
 #define ION_DEVICE_ID_TI_EDGEPORT_22I                  0x021A  // Edgeport/22I is an Edgeport/4 with ports 1&2 RS422 and ports 3&4 RS232
 #define ION_DEVICE_ID_TI_EDGEPORT_21C          0x021E  // Edgeport/21c is a TI based Edgeport/2 with lucent chip
 
 // Generation 3 devices -- 3410 based edgport/1 (256 byte I2C) 
-#define ION_DEVICE_ID_TI_TI3410_EDGEPORT_1     0x240   // Edgeport/1 RS232
-#define ION_DEVICE_ID_TI_TI3410_EDGEPORT_1I    0x241   // Edgeport/1i- RS422 model
+#define ION_DEVICE_ID_TI_TI3410_EDGEPORT_1     0x0240  // Edgeport/1 RS232
+#define ION_DEVICE_ID_TI_TI3410_EDGEPORT_1I    0x0241  // Edgeport/1i- RS422 model
 
 // Ti based software switchable RS232/RS422/RS485 devices
-#define ION_DEVICE_ID_TI_EDGEPORT_4S           0x242   // Edgeport/4s - software switchable model
-#define ION_DEVICE_ID_IT_EDGEPORT_8S           0x243   // Edgeport/8s - software switchable model
+#define ION_DEVICE_ID_TI_EDGEPORT_4S           0x0242  // Edgeport/4s - software switchable model
+#define ION_DEVICE_ID_TI_EDGEPORT_8S           0x0243  // Edgeport/8s - software switchable model
+#define ION_DEVICE_ID_TI_EDGEPORT_8            0x0244  // Edgeport/8 (single-CPU)
+#define ION_DEVICE_ID_TI_EDGEPORT_416B         0x0247  // Edgeport/416
 
 
 /************************************************************************
index 4df0ec74e0b1c0c908d3cc45852296933c98ca55..0455c1552ae90e9e00dde3f8bc52bd63625c66f4 100644 (file)
@@ -732,11 +732,13 @@ static void ipaq_read_bulk_callback(struct urb *urb)
        struct tty_struct       *tty;
        unsigned char           *data = urb->transfer_buffer;
        int                     result;
+       int status = urb->status;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
-       if (urb->status) {
-               dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status);
+       if (status) {
+               dbg("%s - nonzero read bulk status received: %d",
+                   __FUNCTION__, status);
                return;
        }
 
@@ -870,11 +872,13 @@ static void ipaq_write_bulk_callback(struct urb *urb)
        struct ipaq_private     *priv = usb_get_serial_port_data(port);
        unsigned long           flags;
        int                     result;
+       int status = urb->status;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
-       
-       if (urb->status) {
-               dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
+
+       if (status) {
+               dbg("%s - nonzero write bulk status received: %d",
+                   __FUNCTION__, status);
                return;
        }
 
index 1bc586064c771b3c70a141b52b64d8e2a6fd8ce2..1b94daa615845f50f185328b2ecf3326f71bdffa 100644 (file)
@@ -167,11 +167,13 @@ static void ipw_read_bulk_callback(struct urb *urb)
        unsigned char *data = urb->transfer_buffer;
        struct tty_struct *tty;
        int result;
+       int status = urb->status;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
-       if (urb->status) {
-               dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status);
+       if (status) {
+               dbg("%s - nonzero read bulk status received: %d",
+                   __FUNCTION__, status);
                return;
        }
 
@@ -369,13 +371,15 @@ static void ipw_close(struct usb_serial_port *port, struct file * filp)
 static void ipw_write_bulk_callback(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
+       int status = urb->status;
 
        dbg("%s", __FUNCTION__);
 
        port->write_urb_busy = 0;
 
-       if (urb->status)
-               dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
+       if (status)
+               dbg("%s - nonzero write bulk status received: %d",
+                   __FUNCTION__, status);
 
        usb_serial_port_softint(port);
 }
index 9d847f69291cacb69aac6816cca2c24a2078e4c0..5ab6a0c5ac52c3fbb663ee4989338490988c779c 100644 (file)
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  *
+ * 2007_Jun_21  Alan Cox <alan@redhat.com>
+ *     Minimal cleanups for some of the driver problens and tty layer abuse.
+ *     Still needs fixing to allow multiple dongles.
+ *
  * 2002_Mar_07 greg kh
  *     moved some needed structures and #define values from the
  *     net/irda/irda-usb.h file into our file, as we don't want to depend on
@@ -109,6 +113,7 @@ 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);
 
+/* 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;
@@ -392,12 +397,14 @@ static int ir_write (struct usb_serial_port *port, const unsigned char *buf, int
 static void ir_write_bulk_callback (struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+       int status = urb->status;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
        port->write_urb_busy = 0;
-       if (urb->status) {
-               dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
+       if (status) {
+               dbg("%s - nonzero write bulk status received: %d",
+                   __FUNCTION__, status);
                return;
        }
 
@@ -417,6 +424,7 @@ static void ir_read_bulk_callback (struct urb *urb)
        struct tty_struct *tty;
        unsigned char *data = urb->transfer_buffer;
        int result;
+       int status = urb->status;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
@@ -425,8 +433,7 @@ static void ir_read_bulk_callback (struct urb *urb)
                return;
        }
 
-       switch (urb->status) {
-
+       switch (status) {
                case 0: /* Successful */
 
                        /*
@@ -444,22 +451,12 @@ static void ir_read_bulk_callback (struct urb *urb)
                                urb->actual_length,
                                data);
 
-                       /*
-                        * Bypass flip-buffers, and feed the ldisc directly
-                        * due to our potentially large buffer size.  Since we
-                        * used to set low_latency, this is exactly what the
-                        * tty layer did anyway :)
-                        */
                        tty = port->tty;
 
-                       /*
-                        *      FIXME: must not do this in IRQ context
-                        */
-                       tty->ldisc.receive_buf(
-                               tty,
-                               data+1,
-                               NULL,
-                               urb->actual_length-1);
+                       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.
@@ -490,7 +487,7 @@ static void ir_read_bulk_callback (struct urb *urb)
                default:
                        dbg("%s - nonzero read bulk status received: %d",
                                __FUNCTION__, 
-                               urb->status);
+                               status);
                        break ;
 
        }
@@ -501,8 +498,9 @@ static void ir_read_bulk_callback (struct urb *urb)
 static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
 {
        unsigned char *transfer_buffer;
-       unsigned int cflag;
        int result;
+       speed_t baud;
+       int ir_baud;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
@@ -511,77 +509,59 @@ static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_t
                return;
        }
 
-       cflag = port->tty->termios->c_cflag;
-       /* check that they really want us to change something */
-       if (old_termios) {
-               if ((cflag == old_termios->c_cflag) &&
-                   (RELEVANT_IFLAG(port->tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) {
-                       dbg("%s - nothing to change...", __FUNCTION__);
-                       return;
-               }
+       baud = tty_get_baud_rate(port->tty);
+
+       /*
+        * FIXME, we should compare the baud request against the
+        * capability stated in the IR header that we got in the
+        * startup function.
+        */
+
+       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;
+                       /* And once the new tty stuff is all done we need to
+                          call back to correct the baud bits */
        }
 
-       /* All we can change is the baud rate */
-       if (cflag & CBAUD) {
-
-               dbg ("%s - asking for baud %d",
-                       __FUNCTION__,
-                       tty_get_baud_rate(port->tty));
-
-               /* 
-                * FIXME, we should compare the baud request against the
-                * capability stated in the IR header that we got in the
-                * startup function.
-                */
-               switch (cflag & CBAUD) {
-                       case B2400:    ir_baud = SPEED_2400;    break;
-                       default:
-                       case B9600:    ir_baud = SPEED_9600;    break;
-                       case B19200:   ir_baud = SPEED_19200;   break;
-                       case B38400:   ir_baud = SPEED_38400;   break;
-                       case B57600:   ir_baud = SPEED_57600;   break;
-                       case B115200:  ir_baud = SPEED_115200;  break;
-                       case B576000:  ir_baud = SPEED_576000;  break;
-                       case B1152000: ir_baud = SPEED_1152000; break;
-#ifdef B4000000
-                       case B4000000: ir_baud = SPEED_4000000; break;
-#endif
-               }
+       if (xbof == -1)
+               ir_xbof = ir_xbof_change(ir_add_bof);
+       else
+               ir_xbof = ir_xbof_change(xbof) ;
 
-               if (xbof == -1) {
-                       ir_xbof = ir_xbof_change(ir_add_bof);
-               } else {
-                       ir_xbof = ir_xbof_change(xbof) ;
-               }
+       /* FIXME need to check to see if our write urb is busy right
+        * now, or use a urb pool.
+        *
+        * send the baud change out on an "empty" data packet
+        */
+       transfer_buffer = port->write_urb->transfer_buffer;
+       *transfer_buffer = ir_xbof | ir_baud;
 
-               /* Notify the tty driver that the termios have changed. */
-               port->tty->ldisc.set_termios(port->tty, NULL);
-
-               /* FIXME need to check to see if our write urb is busy right
-                * now, or use a urb pool.
-                *
-                * send the baud change out on an "empty" data packet
-                */
-               transfer_buffer = port->write_urb->transfer_buffer;
-               *transfer_buffer = ir_xbof | ir_baud;
-
-               usb_fill_bulk_urb (
-                       port->write_urb,
-                       port->serial->dev,
-                       usb_sndbulkpipe(port->serial->dev,
-                               port->bulk_out_endpointAddress),
-                       port->write_urb->transfer_buffer,
-                       1,
-                       ir_write_bulk_callback,
-                       port);
-
-               port->write_urb->transfer_flags = URB_ZERO_PACKET;
-
-               result = usb_submit_urb (port->write_urb, GFP_KERNEL);
-               if (result)
-                       dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result);
-       }
-       return;
+       usb_fill_bulk_urb (
+               port->write_urb,
+               port->serial->dev,
+               usb_sndbulkpipe(port->serial->dev, port->bulk_out_endpointAddress),
+               port->write_urb->transfer_buffer,
+               1,
+               ir_write_bulk_callback,
+               port);
+
+       port->write_urb->transfer_flags = URB_ZERO_PACKET;
+
+       result = usb_submit_urb (port->write_urb, GFP_KERNEL);
+       if (result)
+               dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result);
 }
 
 
index e6966f12ed5aacdace21a8d14fe79d649f09e406..f2a6fce5de1e9fe688b32004364e8589a1f0e8e3 100644 (file)
@@ -115,12 +115,13 @@ static int debug;
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.1.4"
+#define DRIVER_VERSION "v1.1.5"
 #define DRIVER_AUTHOR "Hugh Blemings <hugh@misc.nu"
 #define DRIVER_DESC "Keyspan USB to Serial Converter Driver"
 
 #define INSTAT_BUFLEN  32
 #define GLOCONT_BUFLEN 64
+#define INDAT49W_BUFLEN        512
 
        /* Per device and per port private data */
 struct keyspan_serial_private {
@@ -129,9 +130,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 */
+       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
 };
 
 struct keyspan_port_private {
@@ -179,12 +186,13 @@ struct keyspan_port_private {
 
        
 /* Include Keyspan message headers.  All current Keyspan Adapters
-   make use of one of four message formats which are referred
-   to as USA-26, USA-28 and USA-49, USA-90 by Keyspan and within this driver. */
+   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. */
 #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. */
@@ -419,14 +427,15 @@ static void       usa26_indat_callback(struct urb *urb)
        struct usb_serial_port  *port;
        struct tty_struct       *tty;
        unsigned char           *data = urb->transfer_buffer;
+       int status = urb->status;
 
        dbg ("%s", __FUNCTION__); 
 
        endpoint = usb_pipeendpoint(urb->pipe);
 
-       if (urb->status) {
+       if (status) {
                dbg("%s - nonzero status: %x on endpoint %d.",
-                   __FUNCTION__, urb->status, endpoint);
+                   __FUNCTION__, status, endpoint);
                return;
        }
 
@@ -511,11 +520,12 @@ static void       usa26_instat_callback(struct urb *urb)
        struct usb_serial_port                  *port;
        struct keyspan_port_private             *p_priv;
        int old_dcd_state, err;
+       int status = urb->status;
 
        serial = (struct usb_serial *) urb->context;
 
-       if (urb->status) {
-               dbg("%s - nonzero status: %x", __FUNCTION__, urb->status);
+       if (status) {
+               dbg("%s - nonzero status: %x", __FUNCTION__, status);
                return;
        }
        if (urb->actual_length != 9) {
@@ -579,6 +589,7 @@ static void usa28_indat_callback(struct urb *urb)
        struct tty_struct       *tty;
        unsigned char           *data;
        struct keyspan_port_private             *p_priv;
+       int status = urb->status;
 
        dbg ("%s", __FUNCTION__);
 
@@ -590,9 +601,9 @@ static void usa28_indat_callback(struct urb *urb)
                return;
 
        do {
-               if (urb->status) {
+               if (status) {
                        dbg("%s - nonzero status: %x on endpoint %d.",
-                           __FUNCTION__, urb->status, usb_pipeendpoint(urb->pipe));
+                           __FUNCTION__, status, usb_pipeendpoint(urb->pipe));
                        return;
                }
 
@@ -648,11 +659,12 @@ static void       usa28_instat_callback(struct urb *urb)
        struct usb_serial_port                  *port;
        struct keyspan_port_private             *p_priv;
        int old_dcd_state;
+       int status = urb->status;
 
        serial = (struct usb_serial *) urb->context;
 
-       if (urb->status) {
-               dbg("%s - nonzero status: %x", __FUNCTION__, urb->status);
+       if (status) {
+               dbg("%s - nonzero status: %x", __FUNCTION__, status);
                return;
        }
 
@@ -739,13 +751,14 @@ static void       usa49_instat_callback(struct urb *urb)
        struct usb_serial_port                  *port;
        struct keyspan_port_private             *p_priv;
        int old_dcd_state;
+       int status = urb->status;
 
        dbg ("%s", __FUNCTION__);
 
        serial = (struct usb_serial *) urb->context;
 
-       if (urb->status) {
-               dbg("%s - nonzero status: %x", __FUNCTION__, urb->status);
+       if (status) {
+               dbg("%s - nonzero status: %x", __FUNCTION__, status);
                return;
        }
 
@@ -805,14 +818,15 @@ static void       usa49_indat_callback(struct urb *urb)
        struct usb_serial_port  *port;
        struct tty_struct       *tty;
        unsigned char           *data = urb->transfer_buffer;
+       int status = urb->status;
 
        dbg ("%s", __FUNCTION__);
 
        endpoint = usb_pipeendpoint(urb->pipe);
 
-       if (urb->status) {
+       if (status) {
                dbg("%s - nonzero status: %x on endpoint %d.", __FUNCTION__,
-                   urb->status, endpoint);
+                   status, endpoint);
                return;
        }
 
@@ -850,13 +864,90 @@ static void       usa49_indat_callback(struct urb *urb)
                }
 }
 
+static void usa49wg_indat_callback(struct urb *urb)
+{
+       int                     i, len, x, err;
+       struct usb_serial       *serial;
+       struct usb_serial_port  *port;
+       struct tty_struct       *tty;
+       unsigned char           *data = urb->transfer_buffer;
+       int status = urb->status;
+
+       dbg ("%s", __FUNCTION__);
+
+       serial = urb->context;
+
+       if (status) {
+               dbg("%s - nonzero status: %x", __FUNCTION__, status);
+               return;
+       }
+
+       /* inbound data is in the form P#, len, status, data */
+       i = 0;
+       len = 0;
+
+       if (urb->actual_length) {
+               while (i < urb->actual_length) {
+
+                       /* Check port number from message*/
+                       if (data[i] >= serial->num_ports) {
+                               dbg ("%s - Unexpected port number %d",
+                                       __FUNCTION__, data[i]);
+                               return;
+                       }
+                       port = serial->port[data[i++]];
+                       tty = port->tty;
+                       len = data[i++];
+
+                       /* 0x80 bit is error flag */
+                       if ((data[i] & 0x80) == 0) {
+                               /* no error on any byte */
+                               i++;
+                               for (x = 1; x < len ; ++x)
+                                       if (port->open_count)
+                                               tty_insert_flip_char(tty,
+                                                               data[i++], 0);
+                                       else
+                                               i++;
+                       } else {
+                               /*
+                                * some bytes had errors, every byte has status
+                                */
+                               for (x = 0; x + 1 < len; x += 2) {
+                                       int stat = data[i], flag = 0;
+                                       if (stat & RXERROR_OVERRUN)
+                                               flag |= TTY_OVERRUN;
+                                       if (stat & RXERROR_FRAMING)
+                                               flag |= TTY_FRAME;
+                                       if (stat & RXERROR_PARITY)
+                                               flag |= TTY_PARITY;
+                                       /* XXX should handle break (0x10) */
+                                       if (port->open_count)
+                                               tty_insert_flip_char(tty,
+                                                       data[i+1], flag);
+                                       i += 2;
+                               }
+                       }
+                       if (port->open_count)
+                               tty_flip_buffer_push(tty);
+               }
+       }
+
+       /* Resubmit urb so we continue receiving */
+       urb->dev = serial->dev;
+
+       err = usb_submit_urb(urb, GFP_ATOMIC);
+       if (err != 0)
+               dbg("%s - resubmit read urb failed. (%d)", __FUNCTION__, err);
+}
+
 /* not used, usa-49 doesn't have per-port control endpoints */
-static void    usa49_outcont_callback(struct urb *urb)
+static void usa49_outcont_callback(struct urb *urb)
 {
        dbg ("%s", __FUNCTION__);
 }
 
-static void    usa90_indat_callback(struct urb *urb)
+static void usa90_indat_callback(struct urb *urb)
 {
        int                     i, err;
        int                     endpoint;
@@ -864,15 +955,15 @@ static void       usa90_indat_callback(struct urb *urb)
        struct keyspan_port_private             *p_priv;
        struct tty_struct       *tty;
        unsigned char           *data = urb->transfer_buffer;
+       int status = urb->status;
 
        dbg ("%s", __FUNCTION__); 
 
        endpoint = usb_pipeendpoint(urb->pipe);
 
-
-       if (urb->status) {
+       if (status) {
                dbg("%s - nonzero status: %x on endpoint %d.",
-                   __FUNCTION__, urb->status, endpoint);
+                   __FUNCTION__, status, endpoint);
                return;
        }
 
@@ -938,11 +1029,12 @@ static void      usa90_instat_callback(struct urb *urb)
        struct usb_serial_port                  *port;
        struct keyspan_port_private             *p_priv;
        int old_dcd_state, err;
+       int status = urb->status;
 
        serial = (struct usb_serial *) urb->context;
 
-       if (urb->status) {
-               dbg("%s - nonzero status: %x", __FUNCTION__, urb->status);
+       if (status) {
+               dbg("%s - nonzero status: %x", __FUNCTION__, status);
                return;
        }
        if (urb->actual_length < 14) {
@@ -995,6 +1087,88 @@ static void       usa90_outcont_callback(struct urb *urb)
        }
 }
 
+/* Status messages from the 28xg */
+static void    usa67_instat_callback(struct urb *urb)
+{
+       int                                     err;
+       unsigned char                           *data = urb->transfer_buffer;
+       struct keyspan_usa67_portStatusMessage  *msg;
+       struct usb_serial                       *serial;
+       struct usb_serial_port                  *port;
+       struct keyspan_port_private             *p_priv;
+       int old_dcd_state;
+       int status = urb->status;
+
+       dbg ("%s", __FUNCTION__);
+
+       serial = urb->context;
+
+       if (status) {
+               dbg("%s - nonzero status: %x", __FUNCTION__, status);
+               return;
+       }
+
+       if (urb->actual_length != sizeof(struct keyspan_usa67_portStatusMessage)) {
+               dbg("%s - bad length %d", __FUNCTION__, urb->actual_length);
+               return;
+       }
+
+
+       /* Now do something useful with the data */
+       msg = (struct keyspan_usa67_portStatusMessage *)data;
+
+       /* Check port number from message and retrieve private data */
+       if (msg->port >= serial->num_ports) {
+               dbg ("%s - Unexpected port number %d", __FUNCTION__, msg->port);
+               return;
+       }
+
+       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);
+       p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0);
+
+       if (port->tty && !C_CLOCAL(port->tty)
+           && old_dcd_state != p_priv->dcd_state) {
+               if (old_dcd_state)
+                       tty_hangup(port->tty);
+               /*  else */
+               /*      wake_up_interruptible(&p_priv->open_wait); */
+       }
+
+       /* Resubmit urb so we continue receiving */
+       urb->dev = serial->dev;
+       err = usb_submit_urb(urb, GFP_ATOMIC);
+       if (err != 0)
+               dbg("%s - resubmit read urb failed. (%d)", __FUNCTION__, err);
+}
+
+static void usa67_glocont_callback(struct urb *urb)
+{
+       struct usb_serial *serial;
+       struct usb_serial_port *port;
+       struct keyspan_port_private *p_priv;
+       int i;
+
+       dbg ("%s", __FUNCTION__);
+
+       serial = urb->context;
+       for (i = 0; i < serial->num_ports; ++i) {
+               port = serial->port[i];
+               p_priv = usb_get_serial_port_data(port);
+
+               if (p_priv->resend_cont) {
+                       dbg ("%s - sending setup", __FUNCTION__);
+                       keyspan_usa67_send_setup(serial, port,
+                                               p_priv->resend_cont - 1);
+                       break;
+               }
+       }
+}
+
 static int keyspan_write_room (struct usb_serial_port *port)
 {
        struct keyspan_port_private     *p_priv;
@@ -1311,6 +1485,11 @@ static struct urb *keyspan_setup_urb (struct usb_serial *serial, int endpoint,
                return NULL;
        }
 
+       if (endpoint == 0) {
+               /* control EP filled in when used */
+               return urb;
+       }
+
        ep_desc = find_ep(serial, endpoint);
        if (!ep_desc) {
                /* leak the urb, something's wrong and the callers don't care */
@@ -1380,6 +1559,14 @@ static struct callbacks {
                .outdat_callback =      usa2x_outdat_callback,
                .inack_callback =       usa28_inack_callback,
                .outcont_callback =     usa90_outcont_callback,
+       }, {
+               /* msg_usa67 callbacks */
+               .instat_callback =      usa67_instat_callback,
+               .glocont_callback =     usa67_glocont_callback,
+               .indat_callback =       usa26_indat_callback,
+               .outdat_callback =      usa2x_outdat_callback,
+               .inack_callback =       usa26_inack_callback,
+               .outcont_callback =     usa26_outcont_callback,
        }
 };
 
@@ -1410,6 +1597,11 @@ static void keyspan_setup_urbs(struct usb_serial *serial)
                 serial, s_priv->instat_buf, INSTAT_BUFLEN,
                 cback->instat_callback);
 
+       s_priv->indat_urb = keyspan_setup_urb
+               (serial, d_details->indat_endpoint, USB_DIR_IN,
+                serial, s_priv->indat_buf, INDAT49W_BUFLEN,
+                usa49wg_indat_callback);
+
        s_priv->glocont_urb = keyspan_setup_urb
                (serial, d_details->glocont_endpoint, USB_DIR_OUT,
                 serial, s_priv->glocont_buf, GLOCONT_BUFLEN,
@@ -1685,8 +1877,8 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial,
        }
 
        /* Save reset port val for resend.
-       Don't overwrite resend for close condition. */
-       if (p_priv->resend_cont != 3)
+          Don't overwrite resend for open/close condition. */
+       if ((reset_port + 1) > p_priv->resend_cont)
                p_priv->resend_cont = reset_port + 1;
        if (this_urb->status == -EINPROGRESS) {
                /*  dbg ("%s - already writing", __FUNCTION__); */
@@ -1836,8 +2028,8 @@ static int keyspan_usa28_send_setup(struct usb_serial *serial,
        }
 
        /* Save reset port val for resend.
-          Don't overwrite resend for close condition. */
-       if (p_priv->resend_cont != 3)
+          Don't overwrite resend for open/close condition. */
+       if ((reset_port + 1) > p_priv->resend_cont)
                p_priv->resend_cont = reset_port + 1;
        if (this_urb->status == -EINPROGRESS) {
                dbg ("%s already writing", __FUNCTION__);
@@ -1940,11 +2132,11 @@ static int keyspan_usa49_send_setup(struct usb_serial *serial,
                                    struct usb_serial_port *port,
                                    int reset_port)
 {
-       struct keyspan_usa49_portControlMessage msg;            
+       struct keyspan_usa49_portControlMessage msg;
+       struct usb_ctrlrequest                  *dr = NULL;
        struct keyspan_serial_private           *s_priv;
        struct keyspan_port_private             *p_priv;
        const struct keyspan_device_details     *d_details;
-       int                                     glocont_urb;
        struct urb                              *this_urb;
        int                                     err, device_port;
 
@@ -1954,10 +2146,9 @@ static int keyspan_usa49_send_setup(struct usb_serial *serial,
        p_priv = usb_get_serial_port_data(port);
        d_details = s_priv->device_details;
 
-       glocont_urb = d_details->glocont_endpoint;
        this_urb = s_priv->glocont_urb;
 
-               /* Work out which port within the device is being setup */
+       /* Work out which port within the device is being setup */
        device_port = port->number - port->serial->minor;
 
        dbg("%s - endpoint %d port %d (%d)",__FUNCTION__, usb_pipeendpoint(this_urb->pipe), port->number, device_port);
@@ -1969,9 +2160,10 @@ static int keyspan_usa49_send_setup(struct usb_serial *serial,
        }
 
        /* Save reset port val for resend.
-          Don't overwrite resend for close condition. */
-       if (p_priv->resend_cont != 3)
+          Don't overwrite resend for open/close condition. */
+       if ((reset_port + 1) > p_priv->resend_cont)
                p_priv->resend_cont = reset_port + 1;
+
        if (this_urb->status == -EINPROGRESS) {
                /*  dbg ("%s - already writing", __FUNCTION__); */
                mdelay(5);
@@ -2083,20 +2275,39 @@ static int keyspan_usa49_send_setup(struct usb_serial *serial,
        msg.dtr = p_priv->dtr_state;
                
        p_priv->resend_cont = 0;
-       memcpy (this_urb->transfer_buffer, &msg, sizeof(msg));
+
+       /* 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);
+               dr->bRequestType = USB_TYPE_VENDOR | USB_DIR_OUT;
+               dr->bRequest = 0xB0;    /* 49wg control message */;
+               dr->wValue = 0;
+               dr->wIndex = 0;
+               dr->wLength = cpu_to_le16(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);
+
+       } 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);
+               /* send the data out the device on control endpoint */
+               this_urb->transfer_buffer_length = sizeof(msg);
 
-       this_urb->dev = serial->dev;
+               this_urb->dev = serial->dev;
+       }
        if ((err = usb_submit_urb(this_urb, GFP_ATOMIC)) != 0) {
                dbg("%s - usb_submit_urb(setup) failed (%d)", __FUNCTION__, err);
        }
 #if 0
        else {
                dbg("%s - usb_submit_urb(%d) OK %d bytes (end %d)", __FUNCTION__,
-                   outcont_urb, this_urb->transfer_buffer_length,
-                   usb_pipeendpoint(this_urb->pipe));
+                          outcont_urb, this_urb->transfer_buffer_length,
+                          usb_pipeendpoint(this_urb->pipe));
        }
 #endif
 
@@ -2241,6 +2452,154 @@ static int keyspan_usa90_send_setup(struct usb_serial *serial,
        return (0);
 }
 
+static int keyspan_usa67_send_setup(struct usb_serial *serial,
+                                   struct usb_serial_port *port,
+                                   int reset_port)
+{
+       struct keyspan_usa67_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                                     err, device_port;
+
+       dbg ("%s", __FUNCTION__);
+
+       s_priv = usb_get_serial_data(serial);
+       p_priv = usb_get_serial_port_data(port);
+       d_details = s_priv->device_details;
+
+       this_urb = s_priv->glocont_urb;
+
+       /* Work out which port within the device is being setup */
+       device_port = port->number - port->serial->minor;
+
+       /* Make sure we have an urb then send the message */
+       if (this_urb == NULL) {
+               dbg("%s - oops no urb for port %d.", __FUNCTION__,
+                       port->number);
+               return -1;
+       }
+
+       /* Save reset port val for resend.
+          Don't overwrite resend for open/close condition. */
+       if ((reset_port + 1) > p_priv->resend_cont)
+               p_priv->resend_cont = reset_port + 1;
+       if (this_urb->status == -EINPROGRESS) {
+               /*  dbg ("%s - already writing", __FUNCTION__); */
+               mdelay(5);
+               return(-1);
+       }
+
+       memset(&msg, 0, sizeof(struct keyspan_usa67_portControlMessage));
+
+       msg.port = device_port;
+
+       /* 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.", __FUNCTION__,
+                           p_priv->baud);
+                       msg.baudLo = 0;
+                       msg.baudHi = 125;       /* Values for 9600 baud */
+                       msg.prescaler = 10;
+               }
+               msg.setPrescaler = 0xff;
+       }
+
+       msg.lcr = (p_priv->cflag & CSTOPB) ? STOPBITS_678_2 : STOPBITS_5678_1;
+       switch (p_priv->cflag & CSIZE) {
+       case CS5:
+               msg.lcr |= USA_DATABITS_5;
+               break;
+       case CS6:
+               msg.lcr |= USA_DATABITS_6;
+               break;
+       case CS7:
+               msg.lcr |= USA_DATABITS_7;
+               break;
+       case CS8:
+               msg.lcr |= USA_DATABITS_8;
+               break;
+       }
+       if (p_priv->cflag & PARENB) {
+               /* note USA_PARITY_NONE == 0 */
+               msg.lcr |= (p_priv->cflag & PARODD)?
+                       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;
+
+       if (reset_port == 1) {
+               /* Opening port */
+               msg._txOn = 1;
+               msg._txOff = 0;
+               msg.txFlush = 0;
+               msg.txBreak = 0;
+               msg.rxOn = 1;
+               msg.rxOff = 0;
+               msg.rxFlush = 1;
+               msg.rxForward = 0;
+               msg.returnStatus = 0;
+               msg.resetDataToggle = 0xff;
+       } else if (reset_port == 2) {
+               /* Closing port */
+               msg._txOn = 0;
+               msg._txOff = 1;
+               msg.txFlush = 0;
+               msg.txBreak = 0;
+               msg.rxOn = 0;
+               msg.rxOff = 1;
+               msg.rxFlush = 1;
+               msg.rxForward = 0;
+               msg.returnStatus = 0;
+               msg.resetDataToggle = 0;
+       } else {
+               /* Sending intermediate configs */
+               msg._txOn = (! p_priv->break_on);
+               msg._txOff = 0;
+               msg.txFlush = 0;
+               msg.txBreak = (p_priv->break_on);
+               msg.rxOn = 0;
+               msg.rxOff = 0;
+               msg.rxFlush = 0;
+               msg.rxForward = 0;
+               msg.returnStatus = 0;
+               msg.resetDataToggle = 0x0;
+       }
+
+       /* 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));
+
+       /* send the data out the device on control endpoint */
+       this_urb->transfer_buffer_length = sizeof(msg);
+       this_urb->dev = serial->dev;
+
+       err = usb_submit_urb(this_urb, GFP_ATOMIC);
+       if (err != 0)
+               dbg("%s - usb_submit_urb(setup) failed (%d)", __FUNCTION__,
+                               err);
+       return (0);
+}
+
 static void keyspan_send_setup(struct usb_serial_port *port, int reset_port)
 {
        struct usb_serial *serial = port->serial;
@@ -2265,6 +2624,9 @@ static void keyspan_send_setup(struct usb_serial_port *port, int reset_port)
        case msg_usa90:
                keyspan_usa90_send_setup(serial, port, reset_port);
                break;
+       case msg_usa67:
+               keyspan_usa67_send_setup(serial, port, reset_port);
+               break;
        }
 }
 
@@ -2313,9 +2675,19 @@ static int keyspan_startup (struct usb_serial *serial)
 
        keyspan_setup_urbs(serial);
 
-       s_priv->instat_urb->dev = serial->dev;
-       if ((err = usb_submit_urb(s_priv->instat_urb, GFP_KERNEL)) != 0) {
-               dbg("%s - submit instat urb failed %d", __FUNCTION__, err);
+       if (s_priv->instat_urb != NULL) {
+               s_priv->instat_urb->dev = serial->dev;
+               err = usb_submit_urb(s_priv->instat_urb, GFP_KERNEL);
+               if (err != 0)
+                       dbg("%s - submit instat urb failed %d", __FUNCTION__,
+                               err);
+       }
+       if (s_priv->indat_urb != NULL) {
+               s_priv->indat_urb->dev = serial->dev;
+               err = usb_submit_urb(s_priv->indat_urb, GFP_KERNEL);
+               if (err != 0)
+                       dbg("%s - submit indat urb failed %d", __FUNCTION__,
+                               err);
        }
                        
        return (0);
@@ -2335,6 +2707,7 @@ static void keyspan_shutdown (struct usb_serial *serial)
        /* Stop reading/writing urbs */
        stop_urb(s_priv->instat_urb);
        stop_urb(s_priv->glocont_urb);
+       stop_urb(s_priv->indat_urb);
        for (i = 0; i < serial->num_ports; ++i) {
                port = serial->port[i];
                p_priv = usb_get_serial_port_data(port);
@@ -2348,6 +2721,7 @@ static void keyspan_shutdown (struct usb_serial *serial)
 
        /* Now free them */
        usb_free_urb(s_priv->instat_urb);
+       usb_free_urb(s_priv->indat_urb);
        usb_free_urb(s_priv->glocont_urb);
        for (i = 0; i < serial->num_ports; ++i) {
                port = serial->port[i];
index c6830cbdc6df32740b43901090a826f361a06aae..8a0d17401529986b077da08a15a292d1e2de14af 100644 (file)
@@ -99,6 +99,10 @@ static int  keyspan_usa90_send_setup (struct usb_serial *serial,
                                         struct usb_serial_port *port,
                                         int reset_port);
 
+static int  keyspan_usa67_send_setup   (struct usb_serial *serial,
+                                        struct usb_serial_port *port,
+                                        int reset_port);
+
 /* Struct used for firmware - increased size of data section
    to allow Keyspan's 'C' firmware struct to be used unmodified */
 struct ezusb_hex_record {
@@ -229,15 +233,17 @@ struct ezusb_hex_record {
 #define        keyspan_usa28_product_id                0x010f
 #define        keyspan_usa28x_product_id               0x0110
 #define        keyspan_usa28xa_product_id              0x0115
+#define        keyspan_usa28xb_product_id              0x0110
+#define        keyspan_usa28xg_product_id              0x0135
 #define        keyspan_usa49w_product_id               0x010a
 #define        keyspan_usa49wlc_product_id             0x012a
-
+#define        keyspan_usa49wg_product_id              0x0131
 
 struct keyspan_device_details {
        /* product ID value */
        int     product_id;
 
-       enum    {msg_usa26, msg_usa28, msg_usa49, msg_usa90} msg_format;
+       enum    {msg_usa26, msg_usa28, msg_usa49, msg_usa90, msg_usa67} msg_format;
 
                /* Number of physical ports */
        int     num_ports;
@@ -264,6 +270,9 @@ struct keyspan_device_details {
                /* Endpoint used for input status */
        int     instat_endpoint;
 
+               /* Endpoint used for input data 49WG only */
+       int     indat_endpoint;
+
                /* Endpoint used for global control functions */
        int     glocont_endpoint;
 
@@ -287,6 +296,7 @@ static const struct keyspan_device_details usa18x_device_details = {
        .inack_endpoints        = {0x85},
        .outcont_endpoints      = {0x05},
        .instat_endpoint        = 0x87,
+       .indat_endpoint         = -1,
        .glocont_endpoint       = 0x07,
        .calculate_baud_rate    = keyspan_usa19w_calc_baud,
        .baudclk                = KEYSPAN_USA18X_BAUDCLK,
@@ -303,6 +313,7 @@ static const struct keyspan_device_details usa19_device_details = {
        .inack_endpoints        = {0x83},
        .outcont_endpoints      = {0x03},
        .instat_endpoint        = 0x84,
+       .indat_endpoint         = -1,
        .glocont_endpoint       = -1,
        .calculate_baud_rate    = keyspan_usa19_calc_baud,
        .baudclk                = KEYSPAN_USA19_BAUDCLK,
@@ -319,6 +330,7 @@ static const struct keyspan_device_details usa19qi_device_details = {
        .inack_endpoints        = {0x83},
        .outcont_endpoints      = {0x03},
        .instat_endpoint        = 0x84,
+       .indat_endpoint         = -1,
        .glocont_endpoint       = -1,
        .calculate_baud_rate    = keyspan_usa28_calc_baud,
        .baudclk                = KEYSPAN_USA19_BAUDCLK,
@@ -335,6 +347,7 @@ static const struct keyspan_device_details mpr_device_details = {
        .inack_endpoints        = {0x83},
        .outcont_endpoints      = {0x03},
        .instat_endpoint        = 0x84,
+       .indat_endpoint         = -1,
        .glocont_endpoint       = -1,
        .calculate_baud_rate    = keyspan_usa28_calc_baud,
        .baudclk                = KEYSPAN_USA19_BAUDCLK,
@@ -351,6 +364,7 @@ static const struct keyspan_device_details usa19qw_device_details = {
        .inack_endpoints        = {0x85},
        .outcont_endpoints      = {0x05},
        .instat_endpoint        = 0x87,
+       .indat_endpoint         = -1,
        .glocont_endpoint       = 0x07,
        .calculate_baud_rate    = keyspan_usa19w_calc_baud,
        .baudclk                = KEYSPAN_USA19W_BAUDCLK,
@@ -367,6 +381,7 @@ static const struct keyspan_device_details usa19w_device_details = {
        .inack_endpoints        = {0x85},
        .outcont_endpoints      = {0x05},
        .instat_endpoint        = 0x87,
+       .indat_endpoint         = -1,
        .glocont_endpoint       = 0x07,
        .calculate_baud_rate    = keyspan_usa19w_calc_baud,
        .baudclk                = KEYSPAN_USA19W_BAUDCLK,
@@ -383,6 +398,7 @@ static const struct keyspan_device_details usa19hs_device_details = {
        .inack_endpoints        = {-1},
        .outcont_endpoints      = {0x02},
        .instat_endpoint        = 0x82,
+       .indat_endpoint         = -1,
        .glocont_endpoint       = -1,
        .calculate_baud_rate    = keyspan_usa19hs_calc_baud,
        .baudclk                = KEYSPAN_USA19HS_BAUDCLK,
@@ -399,6 +415,7 @@ static const struct keyspan_device_details usa28_device_details = {
        .inack_endpoints        = {0x85, 0x86},
        .outcont_endpoints      = {0x05, 0x06},
        .instat_endpoint        = 0x87,
+       .indat_endpoint         = -1,
        .glocont_endpoint       = 0x07,
        .calculate_baud_rate    = keyspan_usa28_calc_baud,
        .baudclk                = KEYSPAN_USA28_BAUDCLK,                
@@ -415,6 +432,7 @@ static const struct keyspan_device_details usa28x_device_details = {
        .inack_endpoints        = {0x85, 0x86},
        .outcont_endpoints      = {0x05, 0x06},
        .instat_endpoint        = 0x87,
+       .indat_endpoint         = -1,
        .glocont_endpoint       = 0x07,
        .calculate_baud_rate    = keyspan_usa19w_calc_baud,
        .baudclk                = KEYSPAN_USA28X_BAUDCLK,
@@ -431,11 +449,28 @@ static const struct keyspan_device_details usa28xa_device_details = {
        .inack_endpoints        = {0x85, 0x86},
        .outcont_endpoints      = {0x05, 0x06},
        .instat_endpoint        = 0x87,
+       .indat_endpoint         = -1,
        .glocont_endpoint       = 0x07,
        .calculate_baud_rate    = keyspan_usa19w_calc_baud,
        .baudclk                = KEYSPAN_USA28X_BAUDCLK,
 };
 
+static const struct keyspan_device_details usa28xg_device_details = {
+       .product_id             = keyspan_usa28xg_product_id,
+       .msg_format             = msg_usa67,
+       .num_ports              = 2,
+       .indat_endp_flip        = 0,
+       .outdat_endp_flip       = 0,
+       .indat_endpoints        = {0x84, 0x88},
+       .outdat_endpoints       = {0x02, 0x06},
+       .inack_endpoints        = {-1, -1},
+       .outcont_endpoints      = {-1, -1},
+       .instat_endpoint        = 0x81,
+       .indat_endpoint         = -1,
+       .glocont_endpoint       = 0x01,
+       .calculate_baud_rate    = keyspan_usa19w_calc_baud,
+       .baudclk                = KEYSPAN_USA28X_BAUDCLK,
+};
 /* We don't need a separate entry for the usa28xb as it appears as a 28x anyway */
 
 static const struct keyspan_device_details usa49w_device_details = {
@@ -449,6 +484,7 @@ static const struct keyspan_device_details usa49w_device_details = {
        .inack_endpoints        = {-1, -1, -1, -1},
        .outcont_endpoints      = {-1, -1, -1, -1},
        .instat_endpoint        = 0x87,
+       .indat_endpoint         = -1,
        .glocont_endpoint       = 0x07,
        .calculate_baud_rate    = keyspan_usa19w_calc_baud,
        .baudclk                = KEYSPAN_USA49W_BAUDCLK,
@@ -465,11 +501,29 @@ static const struct keyspan_device_details usa49wlc_device_details = {
        .inack_endpoints        = {-1, -1, -1, -1},
        .outcont_endpoints      = {-1, -1, -1, -1},
        .instat_endpoint        = 0x87,
+       .indat_endpoint         = -1,
        .glocont_endpoint       = 0x07,
        .calculate_baud_rate    = keyspan_usa19w_calc_baud,
        .baudclk                = KEYSPAN_USA19W_BAUDCLK,
 };
 
+static const struct keyspan_device_details usa49wg_device_details = {
+       .product_id             = keyspan_usa49wg_product_id,
+       .msg_format             = msg_usa49,
+       .num_ports              = 4,
+       .indat_endp_flip        = 0,
+       .outdat_endp_flip       = 0,
+       .indat_endpoints        = {-1, -1, -1, -1},             /* single 'global' data in EP */
+       .outdat_endpoints       = {0x01, 0x02, 0x04, 0x06},
+       .inack_endpoints        = {-1, -1, -1, -1},
+       .outcont_endpoints      = {-1, -1, -1, -1},
+       .instat_endpoint        = 0x81,
+       .indat_endpoint         = 0x88,
+       .glocont_endpoint       = 0x00,                         /* uses control EP */
+       .calculate_baud_rate    = keyspan_usa19w_calc_baud,
+       .baudclk                = KEYSPAN_USA19W_BAUDCLK,
+};
+
 static const struct keyspan_device_details *keyspan_devices[] = {
        &usa18x_device_details,
        &usa19_device_details,
@@ -481,9 +535,11 @@ static const struct keyspan_device_details *keyspan_devices[] = {
        &usa28_device_details,
        &usa28x_device_details,
        &usa28xa_device_details,
+       &usa28xg_device_details,
        /* 28xb not required as it renumerates as a 28x */
        &usa49w_device_details,
        &usa49wlc_device_details,
+       &usa49wg_device_details,
        NULL,
 };
 
@@ -510,8 +566,11 @@ 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)},
+       { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wg_product_id)},
        { } /* Terminating entry */
 };
 
@@ -557,12 +616,15 @@ 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 */
 };
 
 static struct usb_device_id keyspan_4port_ids[] = {
        { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49w_product_id) },
        { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wlc_product_id)},
+       { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wg_product_id)},
        { } /* Terminating entry */
 };
 
@@ -573,7 +635,6 @@ static struct usb_serial_driver keyspan_pre_device = {
                .name           = "keyspan_no_firm",
        },
        .description            = "Keyspan - (without firmware)",
-       .usb_driver             = &keyspan_driver,
        .id_table               = keyspan_pre_ids,
        .num_interrupt_in       = NUM_DONT_CARE,
        .num_bulk_in            = NUM_DONT_CARE,
@@ -588,7 +649,6 @@ static struct usb_serial_driver keyspan_1port_device = {
                .name           = "keyspan_1",
        },
        .description            = "Keyspan 1 port adapter",
-       .usb_driver             = &keyspan_driver,
        .id_table               = keyspan_1port_ids,
        .num_interrupt_in       = NUM_DONT_CARE,
        .num_bulk_in            = NUM_DONT_CARE,
@@ -616,7 +676,6 @@ static struct usb_serial_driver keyspan_2port_device = {
                .name           = "keyspan_2",
        },
        .description            = "Keyspan 2 port adapter",
-       .usb_driver             = &keyspan_driver,
        .id_table               = keyspan_2port_ids,
        .num_interrupt_in       = NUM_DONT_CARE,
        .num_bulk_in            = NUM_DONT_CARE,
@@ -644,11 +703,10 @@ static struct usb_serial_driver keyspan_4port_device = {
                .name           = "keyspan_4",
        },
        .description            = "Keyspan 4 port adapter",
-       .usb_driver             = &keyspan_driver,
        .id_table               = keyspan_4port_ids,
        .num_interrupt_in       = NUM_DONT_CARE,
-       .num_bulk_in            = 5,
-       .num_bulk_out           = 5,
+       .num_bulk_in            = NUM_DONT_CARE,
+       .num_bulk_out           = NUM_DONT_CARE,
        .num_ports              = 4,
        .open                   = keyspan_open,
        .close                  = keyspan_close,
index dd0b66a6ed5d00825a93c571d867f31abd61a183..be9ac20a8f10b3adeb456192f84246da79206419 100644 (file)
@@ -218,11 +218,12 @@ static void keyspan_pda_rx_interrupt (struct urb *urb)
                struct tty_struct *tty = port->tty;
        unsigned char *data = urb->transfer_buffer;
        int i;
-       int status;
+       int retval;
+       int status = urb->status;
        struct keyspan_pda_private *priv;
        priv = usb_get_serial_port_data(port);
 
-       switch (urb->status) {
+       switch (status) {
        case 0:
                /* success */
                break;
@@ -230,10 +231,12 @@ static void keyspan_pda_rx_interrupt (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",
+                   __FUNCTION__, status);
                return;
        default:
-               dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
+               dbg("%s - nonzero urb status received: %d",
+                   __FUNCTION__, status);
                goto exit;
        }
 
@@ -268,10 +271,10 @@ static void keyspan_pda_rx_interrupt (struct urb *urb)
        }
 
 exit:
-       status = usb_submit_urb (urb, GFP_ATOMIC);
-       if (status)
+       retval = usb_submit_urb (urb, GFP_ATOMIC);
+       if (retval)
                err ("%s - usb_submit_urb failed with result %d",
-                    __FUNCTION__, status);
+                    __FUNCTION__, retval);
 }
 
 
diff --git a/drivers/usb/serial/keyspan_usa67msg.h b/drivers/usb/serial/keyspan_usa67msg.h
new file mode 100644 (file)
index 0000000..20fa3e2
--- /dev/null
@@ -0,0 +1,254 @@
+/*
+       usa67msg.h
+
+       Copyright (c) 1998-2007 InnoSys Incorporated.  All Rights Reserved
+       This file is available under a BSD-style copyright
+
+       Keyspan USB Async Firmware to run on Anchor FX1
+
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are
+       met:
+
+       1. Redistributions of source code must retain this licence text
+       without modification, this list of conditions, and the following
+       disclaimer.  The following copyright notice must appear immediately at
+       the beginning of all source files:
+
+               Copyright (c) 1998-2007 InnoSys Incorporated.  All Rights Reserved
+
+               This file is available under a BSD-style copyright
+
+       2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+       3. The name of InnoSys Incorprated may not be used to endorse or promote
+       products derived from this software without specific prior written
+       permission.
+
+       THIS SOFTWARE IS PROVIDED BY INNOSYS CORP. ``AS IS'' AND ANY EXPRESS OR
+       IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+       OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+       NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+       INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+       (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+       SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+       CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+       LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+       OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+       SUCH DAMAGE.
+
+       Fourth revision: This message format supports the USA28XG
+
+       Buffer formats for RX/TX data messages are not defined by
+       a structure, but are described here:
+
+       USB OUT (host -> USAxx, transmit) messages contain a
+       REQUEST_ACK indicator (set to 0xff to request an ACK at the
+       completion of transmit; 0x00 otherwise), followed by data:
+
+               RQSTACK DAT DAT DAT ...
+
+       with a total data length of up to 63.
+
+       USB IN (USAxx -> host, receive) messages begin with a status
+       byte in which the 0x80 bit is either:
+
+               (a)     0x80 bit clear
+                       indicates that the bytes following it are all data
+                       bytes:
+
+                               STAT DATA DATA DATA DATA DATA ...
+
+                       for a total of up to 63 DATA bytes,
+
+       or:
+
+               (b)     0x80 bit set
+                       indiates that the bytes following alternate data and
+                       status bytes:
+
+                               STAT DATA STAT DATA STAT DATA STAT DATA ...
+
+                       for a total of up to 32 DATA bytes.
+
+       The valid bits in the STAT bytes are:
+
+               OVERRUN 0x02
+               PARITY  0x04
+               FRAMING 0x08
+               BREAK   0x10
+
+       Notes:
+
+       (1) The OVERRUN bit can appear in either (a) or (b) format
+               messages, but the but the PARITY/FRAMING/BREAK bits
+               only appear in (b) format messages.
+       (2) For the host to determine the exact point at which the
+               overrun occurred (to identify the point in the data
+               stream at which the data was lost), it needs to count
+               128 characters, starting at the first character of the
+               message in which OVERRUN was reported; the lost character(s)
+               would have been received between the 128th and 129th
+               characters.
+       (3)     An RX data message in which the first byte has 0x80 clear
+               serves as a "break off" indicator.
+
+       revision history:
+
+       1999feb10       add reportHskiaChanges to allow us to ignore them
+       1999feb10       add txAckThreshold for fast+loose throughput enhancement
+       1999mar30       beef up support for RX error reporting
+       1999apr14       add resetDataToggle to control message
+       2000jan04       merge with usa17msg.h
+       2000jun01       add extended BSD-style copyright text
+       2001jul05       change message format to improve OVERRUN case
+       2002jun05       update copyright date, improve comments
+       2006feb06       modify for FX1 chip
+
+*/
+
+#ifndef        __USA67MSG__
+#define        __USA67MSG__
+
+
+// all things called "ControlMessage" are sent on the 'control' endpoint
+
+typedef struct keyspan_usa67_portControlMessage
+{
+       u8      port;           // 0 or 1 (selects port)
+       /*
+               there are three types of "commands" sent in the control message:
+
+               1.      configuration changes which must be requested by setting
+                       the corresponding "set" flag (and should only be requested
+                       when necessary, to reduce overhead on the device):
+       */
+       u8      setClocking,    // host requests baud rate be set
+               baudLo,                 // host does baud divisor calculation
+               baudHi,                 // baudHi is only used for first port (gives lower rates)
+               externalClock_txClocking,
+                                               // 0=internal, other=external
+
+               setLcr,                 // host requests lcr be set
+               lcr,                    // use PARITY, STOPBITS, DATABITS below
+
+               setFlowControl, // host requests flow control be set
+               ctsFlowControl, // 1=use CTS flow control, 0=don't
+               xonFlowControl, // 1=use XON/XOFF flow control, 0=don't
+               xonChar,                // specified in current character format
+               xoffChar,               // specified in current character format
+
+               setTxTriState_setRts,
+                                               // host requests TX tri-state be set
+               txTriState_rts, // 1=active (normal), 0=tristate (off)
+
+               setHskoa_setDtr,
+                                               // host requests HSKOA output be set
+               hskoa_dtr,              // 1=on, 0=off
+
+               setPrescaler,   // host requests prescalar be set (default: 13)
+               prescaler;              // specified as N/8; values 8-ff are valid
+                                               // must be set any time internal baud rate is set;
+                                               // must not be set when external clocking is used
+
+       /*
+               3.      configuration data which is simply used as is (no overhead,
+                       but must be specified correctly in every host message).
+       */
+       u8      forwardingLength,  // forward when this number of chars available
+               reportHskiaChanges_dsrFlowControl,
+                                               // 1=normal; 0=ignore external clock
+                                               // 1=use DSR flow control, 0=don't
+               txAckThreshold, // 0=not allowed, 1=normal, 2-255 deliver ACK faster
+               loopbackMode;   // 0=no loopback, 1=loopback enabled
+
+       /*
+               4.      commands which are flags only; these are processed in order
+                       (so that, e.g., if both _txOn and _txOff flags are set, the
+                       port ends in a TX_OFF state); any non-zero value is respected
+       */
+       u8      _txOn,                  // enable transmitting (and continue if there's data)
+               _txOff,                 // stop transmitting
+               txFlush,                // toss outbound data
+               txBreak,                // turn on break (cleared by _txOn)
+               rxOn,                   // turn on receiver
+               rxOff,                  // turn off receiver
+               rxFlush,                // toss inbound data
+               rxForward,              // forward all inbound data, NOW (as if fwdLen==1)
+               returnStatus,   // return current status (even if it hasn't changed)
+               resetDataToggle;// reset data toggle state to DATA0
+
+} keyspan_usa67_portControlMessage;
+
+// defines for bits in lcr
+#define        USA_DATABITS_5          0x00
+#define        USA_DATABITS_6          0x01
+#define        USA_DATABITS_7          0x02
+#define        USA_DATABITS_8          0x03
+#define        STOPBITS_5678_1         0x00    // 1 stop bit for all byte sizes
+#define        STOPBITS_5_1p5          0x04    // 1.5 stop bits for 5-bit byte
+#define        STOPBITS_678_2          0x04    // 2 stop bits for 6/7/8-bit byte
+#define        USA_PARITY_NONE         0x00
+#define        USA_PARITY_ODD          0x08
+#define        USA_PARITY_EVEN         0x18
+#define        PARITY_1                        0x28
+#define        PARITY_0                        0x38
+
+// all things called "StatusMessage" are sent on the status endpoint
+
+typedef struct keyspan_usa67_portStatusMessage // one for each port
+{
+       u8      port,                   // 0=first, 1=second, other=see below
+               hskia_cts,              // reports HSKIA pin
+               gpia_dcd,               // reports GPIA pin
+               _txOff,                 // port has been disabled (by host)
+               _txXoff,                // port is in XOFF state (either host or RX XOFF)
+               txAck,                  // indicates a TX message acknowledgement
+               rxEnabled,              // as configured by rxOn/rxOff 1=on, 0=off
+               controlResponse;// 1=a control message has been processed
+} keyspan_usa67_portStatusMessage;
+
+// bits in RX data message when STAT byte is included
+#define        RXERROR_OVERRUN 0x02
+#define        RXERROR_PARITY  0x04
+#define        RXERROR_FRAMING 0x08
+#define        RXERROR_BREAK   0x10
+
+typedef struct keyspan_usa67_globalControlMessage
+{
+       u8      port,                           // 3
+               sendGlobalStatus,       // 2=request for two status responses
+               resetStatusToggle,      // 1=reset global status toggle
+               resetStatusCount;       // a cycling value
+} keyspan_usa67_globalControlMessage;
+
+typedef struct keyspan_usa67_globalStatusMessage
+{
+       u8      port,                           // 3
+               sendGlobalStatus,       // from request, decremented
+               resetStatusCount;       // as in request
+} keyspan_usa67_globalStatusMessage;
+
+typedef struct keyspan_usa67_globalDebugMessage
+{
+       u8      port,                           // 2
+               a,
+               b,
+               c,
+               d;
+} keyspan_usa67_globalDebugMessage;
+
+// ie: the maximum length of an FX1 endpoint buffer
+#define        MAX_DATA_LEN                    64
+
+// update status approx. 60 times a second (16.6666 ms)
+#define        STATUS_UPDATE_INTERVAL  16
+
+// status rationing tuning value (each port gets checked each n ms)
+#define        STATUS_RATION   10
+
+#endif
+
+
index 7b085f334cebe2de693b21a58a67a6f809d8f52a..5a4127e62c4ad4f08089eafd3fa4d4e131cd578d 100644 (file)
@@ -567,12 +567,13 @@ exit:
 static void klsi_105_write_bulk_callback ( struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+       int status = urb->status;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
-       
-       if (urb->status) {
+
+       if (status) {
                dbg("%s - nonzero write bulk status received: %d", __FUNCTION__,
-                   urb->status);
+                   status);
                return;
        }
 
@@ -631,16 +632,17 @@ static void klsi_105_read_bulk_callback (struct urb *urb)
        struct tty_struct *tty;
        unsigned char *data = urb->transfer_buffer;
        int rc;
+       int status = urb->status;
 
-        dbg("%s - port %d", __FUNCTION__, port->number);
+       dbg("%s - port %d", __FUNCTION__, port->number);
 
        /* The urb might have been killed. */
-        if (urb->status) {
-                dbg("%s - nonzero read bulk status received: %d", __FUNCTION__,
-                   urb->status);
-                return;
-        }
-       
+       if (status) {
+               dbg("%s - nonzero read bulk status received: %d", __FUNCTION__,
+                   status);
+               return;
+       }
+
        /* The data received is again preceded by a length double-byte in LSB-
         * first order (see klsi_105_write() )
         */
index 0683b51f0932f15a783d4d96dfb53fd3edef75cd..02a86dbc0e9759673000eeb4521a8d0bafabc5ed 100644 (file)
@@ -358,24 +358,26 @@ static void kobil_close (struct usb_serial_port *port, struct file *filp)
 }
 
 
-static void kobil_read_int_callback( struct urb *purb)
+static void kobil_read_int_callback(struct urb *urb)
 {
        int result;
-       struct usb_serial_port *port = (struct usb_serial_port *) purb->context;
+       struct usb_serial_port *port = urb->context;
        struct tty_struct *tty;
-       unsigned char *data = purb->transfer_buffer;
+       unsigned char *data = urb->transfer_buffer;
+       int status = urb->status;
 //     char *dbg_data;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
-       if (purb->status) {
-               dbg("%s - port %d Read int status not zero: %d", __FUNCTION__, port->number, purb->status);
+       if (status) {
+               dbg("%s - port %d Read int status not zero: %d",
+                   __FUNCTION__, port->number, status);
                return;
        }
-       
-       tty = port->tty; 
-       if (purb->actual_length) {
-               
+
+       tty = port->tty;
+       if (urb->actual_length) {
+
                // BEGIN DEBUG
                /*
                  dbg_data = kzalloc((3 *  purb->actual_length + 10) * sizeof(char), GFP_KERNEL);
@@ -390,15 +392,15 @@ static void kobil_read_int_callback( struct urb *purb)
                */
                // END DEBUG
 
-               tty_buffer_request_room(tty, purb->actual_length);
-               tty_insert_flip_string(tty, data, purb->actual_length);
+               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
        port->interrupt_in_urb->dev = port->serial->dev;
 
-       result = usb_submit_urb( port->interrupt_in_urb, GFP_ATOMIC ); 
+       result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
        dbg("%s - port %d Send read URB returns: %i", __FUNCTION__, port->number, result);
 }
 
index 3db1adc25f842d30934b9b07c6cfd626f55a12fa..2a3fabcf5186aa2179b88f4cc64acaa90fba1411 100644 (file)
@@ -81,7 +81,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "z2.0"          /* Linux in-kernel version */
+#define DRIVER_VERSION "z2.1"          /* Linux in-kernel version */
 #define DRIVER_AUTHOR "Wolfgang Grandegger <wolfgang@ces.ch>"
 #define DRIVER_DESC "Magic Control Technology USB-RS232 converter driver"
 
@@ -110,6 +110,10 @@ static int  mct_u232_tiocmget               (struct usb_serial_port *port,
 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);
+
+
 /*
  * All of the device info needed for the MCT USB-RS232 converter.
  */
@@ -145,6 +149,8 @@ static struct usb_serial_driver mct_u232_device = {
        .num_ports =         1,
        .open =              mct_u232_open,
        .close =             mct_u232_close,
+       .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,
@@ -162,8 +168,11 @@ struct mct_u232_private {
        unsigned char        last_lcr;      /* Line Control Register */
        unsigned char        last_lsr;      /* Line Status Register */
        unsigned char        last_msr;      /* Modem Status Register */
+       unsigned int         rx_flags;      /* Throttling flags */
 };
 
+#define THROTTLED              0x01
+
 /*
  * Handle vendor specific USB requests
  */
@@ -216,11 +225,13 @@ static int mct_u232_calculate_baud_rate(struct usb_serial *serial, int value)
        }
 }
 
-static int mct_u232_set_baud_rate(struct usb_serial *serial, int value)
+static int mct_u232_set_baud_rate(struct usb_serial *serial, struct usb_serial_port *port,
+                                 int value)
 {
        __le32 divisor;
         int rc;
         unsigned char zero_byte = 0;
+        unsigned char cts_enable_byte = 0;
 
        divisor = cpu_to_le32(mct_u232_calculate_baud_rate(serial, value));
 
@@ -238,10 +249,17 @@ static int mct_u232_set_baud_rate(struct usb_serial *serial, int value)
           'baud rate change' message.  The actual functionality of the
           request codes in these messages is not fully understood but these
           particular codes are never seen in any operation besides a baud
-          rate change.  Both of these messages send a single byte of data
-          whose value is always zero.  The second of these two extra messages
-          is required in order for data to be properly written to an RS-232
-          device which does not assert the 'CTS' signal. */
+          rate change.  Both of these messages send a single byte of data.
+          In the first message, the value of this byte is always zero.
+
+          The second message has been determined experimentally to control
+          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'.
+       */
 
        rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
                             MCT_U232_SET_UNKNOWN1_REQUEST, 
@@ -252,14 +270,19 @@ static int mct_u232_set_baud_rate(struct usb_serial *serial, int value)
                err("Sending USB device request code %d failed (error = %d)", 
                    MCT_U232_SET_UNKNOWN1_REQUEST, rc);
 
+       if (port && C_CRTSCTS(port->tty)) {
+          cts_enable_byte = 1;
+       }
+
+        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_UNKNOWN2_REQUEST, 
+                            MCT_U232_SET_CTS_REQUEST,
                             MCT_U232_SET_REQUEST_TYPE,
-                            0, 0, &zero_byte, MCT_U232_SET_UNKNOWN2_SIZE, 
+                            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_UNKNOWN2_REQUEST, rc);
+         err("Sending USB device request code %d failed (error = %d)",
+             MCT_U232_SET_CTS_REQUEST, rc);
 
         return rc;
 } /* mct_u232_set_baud_rate */
@@ -458,8 +481,25 @@ error:
 
 static void mct_u232_close (struct usb_serial_port *port, struct file *filp)
 {
+       unsigned int c_cflag;
+       unsigned long flags;
+       unsigned int control_state;
+       struct mct_u232_private *priv = usb_get_serial_port_data(port);
        dbg("%s port %d", __FUNCTION__, port->number);
 
+       if (port->tty) {
+               c_cflag = port->tty->termios->c_cflag;
+               if (c_cflag & HUPCL) {
+                  /* drop DTR and RTS */
+                  spin_lock_irqsave(&priv->lock, flags);
+                  priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS);
+                  control_state = priv->control_state;
+                  spin_unlock_irqrestore(&priv->lock, flags);
+                  mct_u232_set_modem_ctrl(port->serial, control_state);
+               }
+       }
+
+
        if (port->serial->dev) {
                /* shutdown our urbs */
                usb_kill_urb(port->write_urb);
@@ -476,10 +516,11 @@ static void mct_u232_read_int_callback (struct urb *urb)
        struct usb_serial *serial = port->serial;
        struct tty_struct *tty;
        unsigned char *data = urb->transfer_buffer;
-       int status;
+       int retval;
+       int status = urb->status;
        unsigned long flags;
 
-       switch (urb->status) {
+       switch (status) {
        case 0:
                /* success */
                break;
@@ -487,10 +528,12 @@ static void mct_u232_read_int_callback (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",
+                   __FUNCTION__, status);
                return;
        default:
-               dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
+               dbg("%s - nonzero urb status received: %d",
+                   __FUNCTION__, status);
                goto exit;
        }
 
@@ -554,10 +597,10 @@ static void mct_u232_read_int_callback (struct urb *urb)
 #endif
        spin_unlock_irqrestore(&priv->lock, flags);
 exit:
-       status = usb_submit_urb (urb, GFP_ATOMIC);
-       if (status)
+       retval = usb_submit_urb (urb, GFP_ATOMIC);
+       if (retval)
                err ("%s - usb_submit_urb failed with result %d",
-                    __FUNCTION__, status);
+                    __FUNCTION__, retval);
 } /* mct_u232_read_int_callback */
 
 static void mct_u232_set_termios (struct usb_serial_port *port,
@@ -565,11 +608,10 @@ static void mct_u232_set_termios (struct usb_serial_port *port,
 {
        struct usb_serial *serial = port->serial;
        struct mct_u232_private *priv = usb_get_serial_port_data(port);
-       unsigned int iflag = port->tty->termios->c_iflag;
        unsigned int cflag = port->tty->termios->c_cflag;
        unsigned int old_cflag = old_termios->c_cflag;
        unsigned long flags;
-       unsigned int control_state, new_state;
+       unsigned int control_state;
        unsigned char last_lcr;
 
        /* get a local copy of the current port settings */
@@ -585,18 +627,14 @@ static void mct_u232_set_termios (struct usb_serial_port *port,
         * Premature optimization is the root of all evil.
         */
 
-        /* reassert DTR and (maybe) RTS on transition from B0 */
+        /* reassert DTR and RTS on transition from B0 */
        if ((old_cflag & CBAUD) == B0) {
                dbg("%s: baud was B0", __FUNCTION__);
-               control_state |= TIOCM_DTR;
-               /* don't set RTS if using hardware flow control */
-               if (!(old_cflag & CRTSCTS)) {
-                       control_state |= TIOCM_RTS;
-               }
+               control_state |= TIOCM_DTR | TIOCM_RTS;
                mct_u232_set_modem_ctrl(serial, control_state);
        }
 
-       mct_u232_set_baud_rate(serial, cflag & CBAUD);
+       mct_u232_set_baud_rate(serial, port, cflag & CBAUD);
 
        if ((cflag & CBAUD) == B0 ) {
                dbg("%s: baud is B0", __FUNCTION__);
@@ -638,21 +676,6 @@ static void mct_u232_set_termios (struct usb_serial_port *port,
 
        mct_u232_set_line_ctrl(serial, last_lcr);
 
-       /*
-        * Set flow control: well, I do not really now how to handle DTR/RTS.
-        * Just do what we have seen with SniffUSB on Win98.
-        */
-       /* Drop DTR/RTS if no flow control otherwise assert */
-       new_state = control_state;
-       if ((iflag & IXOFF) || (iflag & IXON) || (cflag & CRTSCTS))
-               new_state |= TIOCM_DTR | TIOCM_RTS;
-       else
-               new_state &= ~(TIOCM_DTR | TIOCM_RTS);
-       if (new_state != control_state) {
-               mct_u232_set_modem_ctrl(serial, new_state);
-               control_state = new_state;
-       }
-
        /* save off the modified port settings */
        spin_lock_irqsave(&priv->lock, flags);
        priv->control_state = control_state;
@@ -747,6 +770,50 @@ static int mct_u232_ioctl (struct usb_serial_port *port, struct file * file,
        return 0;
 } /* mct_u232_ioctl */
 
+static void mct_u232_throttle (struct usb_serial_port *port)
+{
+       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", __FUNCTION__, 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);
+       } else {
+         spin_unlock_irqrestore(&priv->lock, flags);
+       }
+}
+
+
+static void mct_u232_unthrottle (struct usb_serial_port *port)
+{
+       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", __FUNCTION__, 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);
+       } else {
+         spin_unlock_irqrestore(&priv->lock, flags);
+       }
+}
 
 static int __init mct_u232_init (void)
 {
index 73dd0d984cd358e8f022ce8467327a407afc208f..a61bac8f224aded9acfca8b794d385c6bcf79811 100644 (file)
 #define MCT_U232_SET_UNKNOWN1_REQUEST   11  /* Unknown functionality */
 #define MCT_U232_SET_UNKNOWN1_SIZE       1
 
-/* This USB device request code is not well understood.  It is transmitted by
-   the MCT-supplied Windows driver whenever the baud rate changes. 
+/* This USB device request code appears to control whether CTS is required
+   during transmission.
    
-   Without this USB device request, the USB/RS-232 adapter will not write to
-   RS-232 devices which do not assert the 'CTS' signal.
+   Sending a zero byte allows data transmission to a device which is not
+   asserting CTS.  Sending a '1' byte will cause transmission to be deferred
+   until the device asserts CTS.
 */
-#define MCT_U232_SET_UNKNOWN2_REQUEST   12  /* Unknown functionality */
-#define MCT_U232_SET_UNKNOWN2_SIZE       1
+#define MCT_U232_SET_CTS_REQUEST   12
+#define MCT_U232_SET_CTS_SIZE       1
 
 /*
  * Baud rate (divisor)
@@ -439,7 +440,7 @@ static int mct_u232_calculate_baud_rate(struct usb_serial *serial, int value);
  * which says "U232-P9" ;-)
  * 
  * The circuit board inside the adaptor contains a Philips PDIUSBD12
- * USB endpoint chip and a Phillips P87C52UBAA microcontroller with
+ * USB endpoint chip and a Philips P87C52UBAA microcontroller with
  * embedded UART.  Exhaustive documentation for these is available at:
  *
  *   http://www.semiconductors.philips.com/pip/p87c52ubaa
index b563e2ad8728ebe261065ec7ebc6430e7c78b8b8..231b584f6d0f22b5a5e7c27a91289f2d5619e7d6 100644 (file)
@@ -9,9 +9,9 @@
  * the Free Software Foundation, version 2 of the License.
  *
  * Developed by:
- *     VijayaKumar.G.N. <vijaykumar@aspirecom.net>
- *     AjayKumar <ajay@aspirecom.net>
- *     Gurudeva.N. <gurudev@aspirecom.net>
+ *     Vijaya Kumar <vijaykumar.gn@gmail.com>
+ *     Ajay Kumar <naanuajay@yahoo.com>
+ *     Gurudeva <ngurudeva@yahoo.com>
  *
  * Cleaned up from the original by:
  *     Greg Kroah-Hartman <gregkh@suse.de>
@@ -103,6 +103,7 @@ static void mos7720_interrupt_callback(struct urb *urb)
 {
        int result;
        int length;
+       int status = urb->status;
        __u8 *data;
        __u8 sp1;
        __u8 sp2;
@@ -114,7 +115,7 @@ static void mos7720_interrupt_callback(struct urb *urb)
                return;
        }
 
-       switch (urb->status) {
+       switch (status) {
        case 0:
                /* success */
                break;
@@ -123,11 +124,11 @@ static void mos7720_interrupt_callback(struct urb *urb)
        case -ESHUTDOWN:
                /* this urb is terminated, clean up */
                dbg("%s - urb shutting down with status: %d", __FUNCTION__,
-                   urb->status);
+                   status);
                return;
        default:
                dbg("%s - nonzero urb status received: %d", __FUNCTION__,
-                   urb->status);
+                   status);
                goto exit;
        }
 
@@ -198,14 +199,15 @@ exit:
  */
 static void mos7720_bulk_in_callback(struct urb *urb)
 {
-       int status;
+       int retval;
        unsigned char *data ;
        struct usb_serial_port *port;
        struct moschip_port *mos7720_port;
        struct tty_struct *tty;
+       int status = urb->status;
 
-       if (urb->status) {
-               dbg("nonzero read bulk status received: %d",urb->status);
+       if (status) {
+               dbg("nonzero read bulk status received: %d", status);
                return;
        }
 
@@ -236,10 +238,10 @@ static void mos7720_bulk_in_callback(struct urb *urb)
        if (port->read_urb->status != -EINPROGRESS) {
                port->read_urb->dev = port->serial->dev;
 
-               status = usb_submit_urb(port->read_urb, GFP_ATOMIC);
-               if (status)
-                       dbg("usb_submit_urb(read bulk) failed, status = %d",
-                           status);
+               retval = usb_submit_urb(port->read_urb, GFP_ATOMIC);
+               if (retval)
+                       dbg("usb_submit_urb(read bulk) failed, retval = %d",
+                           retval);
        }
 }
 
@@ -252,9 +254,10 @@ static void mos7720_bulk_out_data_callback(struct urb *urb)
 {
        struct moschip_port *mos7720_port;
        struct tty_struct *tty;
+       int status = urb->status;
 
-       if (urb->status) {
-               dbg("nonzero write bulk status received:%d", urb->status);
+       if (status) {
+               dbg("nonzero write bulk status received:%d", status);
                return;
        }
 
@@ -1235,16 +1238,6 @@ static void mos7720_set_termios(struct usb_serial_port *port,
                return;
        }
 
-       /* check that they really want us to change something */
-       if (old_termios) {
-               if ((cflag == old_termios->c_cflag) &&
-                   (RELEVANT_IFLAG(tty->termios->c_iflag) ==
-                    RELEVANT_IFLAG(old_termios->c_iflag))) {
-                       dbg("Nothing to change");
-                       return;
-               }
-       }
-
        dbg("%s - clfag %08x iflag %08x", __FUNCTION__,
            tty->termios->c_cflag,
            RELEVANT_IFLAG(tty->termios->c_iflag));
index 36620c651079ccb4b20e8bde21e0f2df6581c226..37f41f576d3d9db9d2fee3ec412c69a0ad4441a4 100644 (file)
@@ -434,6 +434,7 @@ static void mos7840_control_callback(struct urb *urb)
        struct moschip_port *mos7840_port;
        __u8 regval = 0x0;
        int result = 0;
+       int status = urb->status;
 
        if (!urb) {
                dbg("%s", "Invalid Pointer !!!!:\n");
@@ -442,7 +443,7 @@ static void mos7840_control_callback(struct urb *urb)
 
        mos7840_port = (struct moschip_port *)urb->context;
 
-       switch (urb->status) {
+       switch (status) {
        case 0:
                /* success */
                break;
@@ -451,11 +452,11 @@ static void mos7840_control_callback(struct urb *urb)
        case -ESHUTDOWN:
                /* this urb is terminated, clean up */
                dbg("%s - urb shutting down with status: %d", __FUNCTION__,
-                   urb->status);
+                   status);
                return;
        default:
                dbg("%s - nonzero urb status received: %d", __FUNCTION__,
-                   urb->status);
+                   status);
                goto exit;
        }
 
@@ -521,6 +522,7 @@ static void mos7840_interrupt_callback(struct urb *urb)
        __u8 sp[5], st;
        int i, rv = 0;
        __u16 wval, wreg = 0;
+       int status = urb->status;
 
        dbg("%s", " : Entering\n");
        if (!urb) {
@@ -528,7 +530,7 @@ static void mos7840_interrupt_callback(struct urb *urb)
                return;
        }
 
-       switch (urb->status) {
+       switch (status) {
        case 0:
                /* success */
                break;
@@ -537,11 +539,11 @@ static void mos7840_interrupt_callback(struct urb *urb)
        case -ESHUTDOWN:
                /* this urb is terminated, clean up */
                dbg("%s - urb shutting down with status: %d", __FUNCTION__,
-                   urb->status);
+                   status);
                return;
        default:
                dbg("%s - nonzero urb status received: %d", __FUNCTION__,
-                   urb->status);
+                   status);
                goto exit;
        }
 
@@ -666,20 +668,21 @@ static struct usb_serial *mos7840_get_usb_serial(struct usb_serial_port *port,
 
 static void mos7840_bulk_in_callback(struct urb *urb)
 {
-       int status;
+       int retval;
        unsigned char *data;
        struct usb_serial *serial;
        struct usb_serial_port *port;
        struct moschip_port *mos7840_port;
        struct tty_struct *tty;
+       int status = urb->status;
 
        if (!urb) {
                dbg("%s", "Invalid Pointer !!!!:\n");
                return;
        }
 
-       if (urb->status) {
-               dbg("nonzero read bulk status received: %d", urb->status);
+       if (status) {
+               dbg("nonzero read bulk status received: %d", status);
                return;
        }
 
@@ -729,11 +732,11 @@ static void mos7840_bulk_in_callback(struct urb *urb)
 
        mos7840_port->read_urb->dev = serial->dev;
 
-       status = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC);
+       retval = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC);
 
-       if (status) {
-               dbg(" usb_submit_urb(read bulk) failed, status = %d",
-                status);
+       if (retval) {
+               dbg(" usb_submit_urb(read bulk) failed, retval = %d",
+                retval);
        }
 }
 
@@ -747,6 +750,7 @@ static void mos7840_bulk_out_data_callback(struct urb *urb)
 {
        struct moschip_port *mos7840_port;
        struct tty_struct *tty;
+       int status = urb->status;
        int i;
 
        if (!urb) {
@@ -764,8 +768,8 @@ static void mos7840_bulk_out_data_callback(struct urb *urb)
        }
        spin_unlock(&mos7840_port->pool_lock);
 
-       if (urb->status) {
-               dbg("nonzero write bulk status received:%d\n", urb->status);
+       if (status) {
+               dbg("nonzero write bulk status received:%d\n", status);
                return;
        }
 
@@ -2185,16 +2189,6 @@ static void mos7840_set_termios(struct usb_serial_port *port,
                return;
        }
 
-       /* check that they really want us to change something */
-       if (old_termios) {
-               if ((cflag == old_termios->c_cflag) &&
-                   (RELEVANT_IFLAG(tty->termios->c_iflag) ==
-                    RELEVANT_IFLAG(old_termios->c_iflag))) {
-                       dbg("%s\n", "Nothing to change");
-                       return;
-               }
-       }
-
        dbg("%s - clfag %08x iflag %08x", __FUNCTION__,
            tty->termios->c_cflag, RELEVANT_IFLAG(tty->termios->c_iflag));
 
@@ -2253,30 +2247,6 @@ static int mos7840_get_lsr_info(struct moschip_port *mos7840_port,
        return 0;
 }
 
-/*****************************************************************************
- * mos7840_get_bytes_avail - get number of bytes available
- *
- * Purpose: Let user call ioctl to get the count of number of bytes available.
- *****************************************************************************/
-
-static int mos7840_get_bytes_avail(struct moschip_port *mos7840_port,
-                                  unsigned int __user *value)
-{
-       unsigned int result = 0;
-       struct tty_struct *tty = mos7840_port->port->tty;
-
-       if (!tty)
-               return -ENOIOCTLCMD;
-
-       result = tty->read_cnt;
-
-       dbg("%s(%d) = %d", __FUNCTION__, mos7840_port->port->number, result);
-       if (copy_to_user(value, &result, sizeof(int)))
-               return -EFAULT;
-
-       return -ENOIOCTLCMD;
-}
-
 /*****************************************************************************
  * mos7840_set_modem_info
  *      function to set modem info
@@ -2425,8 +2395,6 @@ static int mos7840_ioctl(struct usb_serial_port *port, struct file *file,
        struct async_icount cprev;
        struct serial_icounter_struct icount;
        int mosret = 0;
-       int retval;
-       struct tty_ldisc *ld;
 
        if (mos7840_port_paranoia_check(port, __FUNCTION__)) {
                dbg("%s", "Invalid port \n");
@@ -2445,42 +2413,6 @@ static int mos7840_ioctl(struct usb_serial_port *port, struct file *file,
        switch (cmd) {
                /* return number of bytes available */
 
-       case TIOCINQ:
-               dbg("%s (%d) TIOCINQ", __FUNCTION__, port->number);
-               return mos7840_get_bytes_avail(mos7840_port, argp);
-
-       case TIOCOUTQ:
-               dbg("%s (%d) TIOCOUTQ", __FUNCTION__, port->number);
-               return put_user(tty->driver->chars_in_buffer ?
-                               tty->driver->chars_in_buffer(tty) : 0,
-                               (int __user *)arg);
-
-       case TCFLSH:
-               retval = tty_check_change(tty);
-               if (retval)
-                       return retval;
-
-               ld = tty_ldisc_ref(tty);
-               switch (arg) {
-               case TCIFLUSH:
-                       if (ld && ld->flush_buffer)
-                               ld->flush_buffer(tty);
-                       break;
-               case TCIOFLUSH:
-                       if (ld && ld->flush_buffer)
-                               ld->flush_buffer(tty);
-                       /* fall through */
-               case TCOFLUSH:
-                       if (tty->driver->flush_buffer)
-                               tty->driver->flush_buffer(tty);
-                       break;
-               default:
-                       tty_ldisc_deref(ld);
-                       return -EINVAL;
-               }
-               tty_ldisc_deref(ld);
-               return 0;
-
        case TIOCSERGETLSR:
                dbg("%s (%d) TIOCSERGETLSR", __FUNCTION__, port->number);
                return mos7840_get_lsr_info(mos7840_port, argp);
index 90701111d746158e3a444340928621e66e5d4861..7f337c9aeb5fe9ba13c5c58dd2bf1b3f2c5e4052 100644 (file)
@@ -37,9 +37,10 @@ static void navman_read_int_callback(struct urb *urb)
        struct usb_serial_port *port = urb->context;
        unsigned char *data = urb->transfer_buffer;
        struct tty_struct *tty;
+       int status = urb->status;
        int result;
 
-       switch (urb->status) {
+       switch (status) {
        case 0:
                /* success */
                break;
@@ -48,11 +49,11 @@ static void navman_read_int_callback(struct urb *urb)
        case -ESHUTDOWN:
                /* this urb is terminated, clean up */
                dbg("%s - urb shutting down with status: %d",
-                   __FUNCTION__, urb->status);
+                   __FUNCTION__, status);
                return;
        default:
                dbg("%s - nonzero urb status received: %d",
-                   __FUNCTION__, urb->status);
+                   __FUNCTION__, status);
                goto exit;
        }
 
index 00afc1712c391336163f4f0b72b83a115cb5aeb5..ee94d9616d82c8ff64869b58b46c56d08e5599aa 100644 (file)
@@ -1,10 +1,9 @@
 /*
  * USB ZyXEL omni.net LCD PLUS driver
  *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License version
+ *     2 as published by the Free Software Foundation.
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  *
@@ -201,14 +200,15 @@ static void omninet_read_bulk_callback (struct urb *urb)
        struct usb_serial_port  *port   = (struct usb_serial_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;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
-       if (urb->status) {
-               dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status);
+       if (status) {
+               dbg("%s - nonzero read bulk status received: %d",
+                   __FUNCTION__, status);
                return;
        }
 
@@ -312,12 +312,14 @@ static void omninet_write_bulk_callback (struct urb *urb)
 {
 /*     struct omninet_header   *header = (struct omninet_header  *) urb->transfer_buffer; */
        struct usb_serial_port  *port   = (struct usb_serial_port *) urb->context;
+       int status = urb->status;
 
        dbg("%s - port %0x\n", __FUNCTION__, port->number);
 
        port->write_urb_busy = 0;
-       if (urb->status) {
-               dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
+       if (status) {
+               dbg("%s - nonzero write bulk status received: %d",
+                   __FUNCTION__, status);
                return;
        }
 
index 5d3999e3ff614663dd8dab01f1c794b7c5b7a2d6..84c12b5f12715675148551bbee25ca5be5ae2b19 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
 #include <linux/module.h>
+#include <linux/bitops.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
 
@@ -240,6 +241,7 @@ struct option_port_private {
        /* Output endpoints and buffer for this port */
        struct urb *out_urbs[N_OUT_URB];
        char out_buffer[N_OUT_URB][OUT_BUFLEN];
+       unsigned long out_busy;         /* Bit vector of URBs in use */
 
        /* Settings for the port */
        int rts_state;  /* Handshaking pins (outputs) */
@@ -370,7 +372,7 @@ static int option_write(struct usb_serial_port *port,
                        todo = OUT_BUFLEN;
 
                this_urb = portdata->out_urbs[i];
-               if (this_urb->status == -EINPROGRESS) {
+               if (test_and_set_bit(i, &portdata->out_busy)) {
                        if (time_before(jiffies,
                                        portdata->tx_start_time[i] + 10 * HZ))
                                continue;
@@ -394,6 +396,7 @@ static int option_write(struct usb_serial_port *port,
                        dbg("usb_submit_urb %p (write bulk) failed "
                                "(%d, has %d)", this_urb,
                                err, this_urb->status);
+                       clear_bit(i, &portdata->out_busy);
                        continue;
                }
                portdata->tx_start_time[i] = jiffies;
@@ -413,15 +416,16 @@ static void option_indat_callback(struct urb *urb)
        struct usb_serial_port *port;
        struct tty_struct *tty;
        unsigned char *data = urb->transfer_buffer;
+       int status = urb->status;
 
        dbg("%s: %p", __FUNCTION__, urb);
 
        endpoint = usb_pipeendpoint(urb->pipe);
        port = (struct usb_serial_port *) urb->context;
 
-       if (urb->status) {
+       if (status) {
                dbg("%s: nonzero status: %d on endpoint %02x.",
-                   __FUNCTION__, urb->status, endpoint);
+                   __FUNCTION__, status, endpoint);
        } else {
                tty = port->tty;
                if (urb->actual_length) {
@@ -433,7 +437,7 @@ static void option_indat_callback(struct urb *urb)
                }
 
                /* Resubmit urb so we continue receiving */
-               if (port->open_count && urb->status != -ESHUTDOWN) {
+               if (port->open_count && status != -ESHUTDOWN) {
                        err = usb_submit_urb(urb, GFP_ATOMIC);
                        if (err)
                                printk(KERN_ERR "%s: resubmit read urb failed. "
@@ -446,17 +450,29 @@ static void option_indat_callback(struct urb *urb)
 static void option_outdat_callback(struct urb *urb)
 {
        struct usb_serial_port *port;
+       struct option_port_private *portdata;
+       int i;
 
        dbg("%s", __FUNCTION__);
 
        port = (struct usb_serial_port *) urb->context;
 
        usb_serial_port_softint(port);
+
+       portdata = usb_get_serial_port_data(port);
+       for (i = 0; i < N_OUT_URB; ++i) {
+               if (portdata->out_urbs[i] == urb) {
+                       smp_mb__before_clear_bit();
+                       clear_bit(i, &portdata->out_busy);
+                       break;
+               }
+       }
 }
 
 static void option_instat_callback(struct urb *urb)
 {
        int err;
+       int status = urb->status;
        struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
        struct option_port_private *portdata = usb_get_serial_port_data(port);
        struct usb_serial *serial = port->serial;
@@ -464,7 +480,7 @@ static void option_instat_callback(struct urb *urb)
        dbg("%s", __FUNCTION__);
        dbg("%s: urb %p port %p has data %p", __FUNCTION__,urb,port,portdata);
 
-       if (urb->status == 0) {
+       if (status == 0) {
                struct usb_ctrlrequest *req_pkt =
                                (struct usb_ctrlrequest *)urb->transfer_buffer;
 
@@ -495,10 +511,10 @@ static void option_instat_callback(struct urb *urb)
                                req_pkt->bRequestType,req_pkt->bRequest);
                }
        } else
-               dbg("%s: error %d", __FUNCTION__, urb->status);
+               dbg("%s: error %d", __FUNCTION__, status);
 
        /* Resubmit urb so we continue receiving IRQ data */
-       if (urb->status != -ESHUTDOWN) {
+       if (status != -ESHUTDOWN) {
                urb->dev = serial->dev;
                err = usb_submit_urb(urb, GFP_ATOMIC);
                if (err)
@@ -518,7 +534,7 @@ static int option_write_room(struct usb_serial_port *port)
 
        for (i=0; i < N_OUT_URB; i++) {
                this_urb = portdata->out_urbs[i];
-               if (this_urb && this_urb->status != -EINPROGRESS)
+               if (this_urb && !test_bit(i, &portdata->out_busy))
                        data_len += OUT_BUFLEN;
        }
 
@@ -537,7 +553,7 @@ static int option_chars_in_buffer(struct usb_serial_port *port)
 
        for (i=0; i < N_OUT_URB; i++) {
                this_urb = portdata->out_urbs[i];
-               if (this_urb && this_urb->status == -EINPROGRESS)
+               if (this_urb && test_bit(i, &portdata->out_busy))
                        data_len += this_urb->transfer_buffer_length;
        }
        dbg("%s: %d", __FUNCTION__, data_len);
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c
new file mode 100644 (file)
index 0000000..d7db71e
--- /dev/null
@@ -0,0 +1,1342 @@
+/*
+ * Ours Technology Inc. OTi-6858 USB to serial adapter driver.
+ *
+ * Copyleft  (C) 2007 Kees Lemmens (adapted for kernel 2.6.20)
+ * Copyright (C) 2006 Tomasz Michal Lukaszewski (FIXME: add e-mail)
+ * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (C) 2003 IBM Corp.
+ *
+ * Many thanks to the authors of pl2303 driver: all functions in this file
+ * are heavily based on pl2303 code, buffering code is a 1-to-1 copy.
+ *
+ * Warning! You use this driver on your own risk! The only official
+ * description of this device I have is datasheet from manufacturer,
+ * and it doesn't contain almost any information needed to write a driver.
+ * Almost all knowlegde used while writing this driver was gathered by:
+ *  - analyzing traffic between device and the M$ Windows 2000 driver,
+ *  - trying different bit combinations and checking pin states
+ *    with a voltmeter,
+ *  - receiving malformed frames and producing buffer overflows
+ *    to learn how errors are reported,
+ * So, THIS CODE CAN DESTROY OTi-6858 AND ANY OTHER DEVICES, THAT ARE
+ * CONNECTED TO IT!
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ *
+ * See Documentation/usb/usb-serial.txt for more information on using this driver
+ *
+ * TODO:
+ *  - implement correct flushing for ioctls and oti6858_close()
+ *  - check how errors (rx overflow, parity error, framing error) are reported
+ *  - implement oti6858_break_ctl()
+ *  - implement more ioctls
+ *  - test/implement flow control
+ *  - allow setting custom baud rates
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/serial.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/spinlock.h>
+#include <linux/usb.h>
+#include <linux/usb/serial.h>
+#include <asm/uaccess.h>
+#include "oti6858.h"
+
+#define OTI6858_DESCRIPTION \
+       "Ours Technology Inc. OTi-6858 USB to serial adapter driver"
+#define OTI6858_AUTHOR "Tomasz Michal Lukaszewski <FIXME@FIXME>"
+#define OTI6858_VERSION "0.1"
+
+static struct usb_device_id id_table [] = {
+       { USB_DEVICE(OTI6858_VENDOR_ID, OTI6858_PRODUCT_ID) },
+       { }
+};
+
+MODULE_DEVICE_TABLE(usb, id_table);
+
+static struct usb_driver oti6858_driver = {
+       .name =         "oti6858",
+       .probe =        usb_serial_probe,
+       .disconnect =   usb_serial_disconnect,
+       .id_table =     id_table,
+       .no_dynamic_id =        1,
+};
+
+static int debug;
+
+
+/* buffering code, copied from pl2303 driver */
+#define PL2303_BUF_SIZE                1024
+#define PL2303_TMP_BUF_SIZE    1024
+
+struct pl2303_buf {
+       unsigned int    buf_size;
+       char            *buf_buf;
+       char            *buf_get;
+       char            *buf_put;
+};
+
+/* requests */
+#define        OTI6858_REQ_GET_STATUS          (USB_DIR_IN | USB_TYPE_VENDOR | 0x00)
+#define        OTI6858_REQ_T_GET_STATUS        0x01
+
+#define        OTI6858_REQ_SET_LINE            (USB_DIR_OUT | USB_TYPE_VENDOR | 0x00)
+#define        OTI6858_REQ_T_SET_LINE          0x00
+
+#define        OTI6858_REQ_CHECK_TXBUFF        (USB_DIR_IN | USB_TYPE_VENDOR | 0x01)
+#define        OTI6858_REQ_T_CHECK_TXBUFF      0x00
+
+/* format of the control packet */
+struct oti6858_control_pkt {
+       u16     divisor;        /* baud rate = 96000000 / (16 * divisor), LE */
+#define OTI6858_MAX_BAUD_RATE  3000000
+       u8      frame_fmt;
+#define FMT_STOP_BITS_MASK     0xc0
+#define FMT_STOP_BITS_1                0x00
+#define FMT_STOP_BITS_2                0x40    /* 1.5 stop bits if FMT_DATA_BITS_5 */
+#define FMT_PARITY_MASK                0x38
+#define FMT_PARITY_NONE                0x00
+#define FMT_PARITY_ODD         0x08
+#define FMT_PARITY_EVEN                0x18
+#define FMT_PARITY_MARK                0x28
+#define FMT_PARITY_SPACE       0x38
+#define FMT_DATA_BITS_MASK     0x03
+#define FMT_DATA_BITS_5                0x00
+#define FMT_DATA_BITS_6                0x01
+#define FMT_DATA_BITS_7                0x02
+#define FMT_DATA_BITS_8                0x03
+       u8      something;      /* always equals 0x43 */
+       u8      control;        /* settings of flow control lines */
+#define CONTROL_MASK           0x0c
+#define CONTROL_DTR_HIGH       0x08
+#define CONTROL_RTS_HIGH       0x04
+       u8      tx_status;
+#define        TX_BUFFER_EMPTIED       0x09
+       u8      pin_state;
+#define PIN_MASK               0x3f
+#define PIN_RTS                        0x20    /* output pin */
+#define PIN_CTS                        0x10    /* input pin, active low */
+#define PIN_DSR                        0x08    /* input pin, active low */
+#define PIN_DTR                        0x04    /* output pin */
+#define PIN_RI                 0x02    /* input pin, active low */
+#define PIN_DCD                        0x01    /* input pin, active low */
+       u8      rx_bytes_avail;         /* number of bytes in rx buffer */;
+};
+
+#define OTI6858_CTRL_PKT_SIZE  sizeof(struct oti6858_control_pkt)
+#define OTI6858_CTRL_EQUALS_PENDING(a, priv) \
+       (    ((a)->divisor == (priv)->pending_setup.divisor) \
+         && ((a)->control == (priv)->pending_setup.control) \
+         && ((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,
+                       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,
+                       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,
+                               unsigned int set, unsigned int clear);
+static int oti6858_startup(struct usb_serial *serial);
+static void oti6858_shutdown(struct usb_serial *serial);
+
+/* functions operating on buffers */
+static struct pl2303_buf *pl2303_buf_alloc(unsigned int size);
+static void pl2303_buf_free(struct pl2303_buf *pb);
+static void pl2303_buf_clear(struct pl2303_buf *pb);
+static unsigned int pl2303_buf_data_avail(struct pl2303_buf *pb);
+static unsigned int pl2303_buf_space_avail(struct pl2303_buf *pb);
+static unsigned int pl2303_buf_put(struct pl2303_buf *pb, const char *buf,
+                                       unsigned int count);
+static unsigned int pl2303_buf_get(struct pl2303_buf *pb, char *buf,
+                                       unsigned int count);
+
+
+/* device info */
+static struct usb_serial_driver oti6858_device = {
+       .driver = {
+               .owner =        THIS_MODULE,
+               .name =         "oti6858",
+       },
+       .id_table =             id_table,
+       .num_interrupt_in =     1,
+       .num_bulk_in =          1,
+       .num_bulk_out =         1,
+       .num_ports =            1,
+       .open =                 oti6858_open,
+       .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,
+       .read_bulk_callback =   oti6858_read_bulk_callback,
+       .read_int_callback =    oti6858_read_int_callback,
+       .write_bulk_callback =  oti6858_write_bulk_callback,
+       .write_room =           oti6858_write_room,
+       .chars_in_buffer =      oti6858_chars_in_buffer,
+       .attach =               oti6858_startup,
+       .shutdown =             oti6858_shutdown,
+};
+
+struct oti6858_private {
+       spinlock_t lock;
+
+       struct pl2303_buf *buf;
+       struct oti6858_control_pkt status;
+
+       struct {
+               u8 read_urb_in_use;
+               u8 write_urb_in_use;
+               u8 termios_initialized;
+       } flags;
+       struct delayed_work delayed_write_work;
+
+       struct {
+               u16 divisor;
+               u8 frame_fmt;
+               u8 control;
+       } pending_setup;
+       u8 transient;
+       u8 setup_done;
+       struct delayed_work delayed_setup_work;
+
+       wait_queue_head_t intr_wait;
+        struct usb_serial_port *port;   /* USB port with which associated */
+};
+
+#undef dbg
+/* #define dbg(format, arg...) printk(KERN_INFO "%s: " format "\n", __FILE__, ## arg) */
+#define dbg(format, arg...) printk(KERN_INFO "" format "\n", ## arg)
+
+static void setup_line(struct work_struct *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;
+       int result;
+
+       dbg("%s(port = %d)", __FUNCTION__, port->number);
+
+       if ((new_setup = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL)) == NULL) {
+               dev_err(&port->dev, "%s(): out of memory!\n", __FUNCTION__);
+               /* we will try again */
+               schedule_delayed_work(&priv->delayed_setup_work, msecs_to_jiffies(2));
+               return;
+       }
+
+       result = usb_control_msg(port->serial->dev,
+                               usb_rcvctrlpipe(port->serial->dev, 0),
+                               OTI6858_REQ_T_GET_STATUS,
+                               OTI6858_REQ_GET_STATUS,
+                               0, 0,
+                               new_setup, OTI6858_CTRL_PKT_SIZE,
+                               100);
+
+       if (result != OTI6858_CTRL_PKT_SIZE) {
+               dev_err(&port->dev, "%s(): error reading status", __FUNCTION__);
+               kfree(new_setup);
+               /* we will try again */
+               schedule_delayed_work(&priv->delayed_setup_work, msecs_to_jiffies(2));
+               return;
+       }
+
+       spin_lock_irqsave(&priv->lock, flags);
+       if (!OTI6858_CTRL_EQUALS_PENDING(new_setup, priv)) {
+               new_setup->divisor = priv->pending_setup.divisor;
+               new_setup->control = priv->pending_setup.control;
+               new_setup->frame_fmt = priv->pending_setup.frame_fmt;
+
+               spin_unlock_irqrestore(&priv->lock, flags);
+               result = usb_control_msg(port->serial->dev,
+                                       usb_sndctrlpipe(port->serial->dev, 0),
+                                       OTI6858_REQ_T_SET_LINE,
+                                       OTI6858_REQ_SET_LINE,
+                                       0, 0,
+                                       new_setup, OTI6858_CTRL_PKT_SIZE,
+                                       100);
+       } else {
+               spin_unlock_irqrestore(&priv->lock, flags);
+               result = 0;
+       }
+       kfree(new_setup);
+
+       spin_lock_irqsave(&priv->lock, flags);
+       if (result != OTI6858_CTRL_PKT_SIZE)
+               priv->transient = 0;
+       priv->setup_done = 1;
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       dbg("%s(): submitting interrupt urb", __FUNCTION__);
+       port->interrupt_in_urb->dev = port->serial->dev;
+       result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
+       if (result != 0) {
+               dev_err(&port->dev, "%s(): usb_submit_urb() failed"
+                               " with error %d\n", __FUNCTION__, result);
+       }
+}
+
+void send_data(struct work_struct *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;
+       unsigned char allow;
+
+       dbg("%s(port = %d)", __FUNCTION__, port->number);
+
+       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));
+               return;
+       }
+       priv->flags.write_urb_in_use = 1;
+
+       count = pl2303_buf_data_avail(priv->buf);
+       spin_unlock_irqrestore(&priv->lock, flags);
+       if (count > port->bulk_out_size)
+               count = port->bulk_out_size;
+
+       if (count != 0) {
+               result = usb_control_msg(port->serial->dev,
+                               usb_rcvctrlpipe(port->serial->dev, 0),
+                               OTI6858_REQ_T_CHECK_TXBUFF,
+                               OTI6858_REQ_CHECK_TXBUFF,
+                               count, 0, &allow, 1, 100);
+               if (result != 1 || allow != 0)
+                       count = 0;
+       }
+
+       if (count == 0) {
+               priv->flags.write_urb_in_use = 0;
+
+               dbg("%s(): submitting interrupt urb", __FUNCTION__);
+               port->interrupt_in_urb->dev = port->serial->dev;
+               result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
+               if (result != 0) {
+                       dev_err(&port->dev, "%s(): usb_submit_urb() failed"
+                               " with error %d\n", __FUNCTION__, result);
+               }
+               return;
+       }
+
+       spin_lock_irqsave(&priv->lock, flags);
+       pl2303_buf_get(priv->buf, port->write_urb->transfer_buffer, count);
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       port->write_urb->transfer_buffer_length = count;
+       port->write_urb->dev = port->serial->dev;
+       result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
+       if (result != 0) {
+               dev_err(&port->dev, "%s(): usb_submit_urb() failed"
+                              " with error %d\n", __FUNCTION__, result);
+               priv->flags.write_urb_in_use = 0;
+       }
+
+       usb_serial_port_softint(port);
+}
+
+static int oti6858_startup(struct usb_serial *serial)
+{
+        struct usb_serial_port *port = serial->port[0];
+        struct oti6858_private *priv;
+       int i;
+
+       for (i = 0; i < serial->num_ports; ++i) {
+               priv = kzalloc(sizeof(struct oti6858_private), GFP_KERNEL);
+               if (!priv)
+                       break;
+               priv->buf = pl2303_buf_alloc(PL2303_BUF_SIZE);
+               if (priv->buf == NULL) {
+                       kfree(priv);
+                       break;
+               }
+
+               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]);
+               priv->port = port;
+               INIT_DELAYED_WORK(&priv->delayed_setup_work, setup_line);
+               INIT_DELAYED_WORK(&priv->delayed_write_work, send_data);
+
+               usb_set_serial_port_data(serial->port[i], priv);
+       }
+       if (i == serial->num_ports)
+               return 0;
+
+       for (--i; i >= 0; --i) {
+               priv = usb_get_serial_port_data(serial->port[i]);
+               pl2303_buf_free(priv->buf);
+               kfree(priv);
+               usb_set_serial_port_data(serial->port[i], NULL);
+       }
+       return -ENOMEM;
+}
+
+static int oti6858_write(struct usb_serial_port *port,
+                       const unsigned char *buf, int count)
+{
+       struct oti6858_private *priv = usb_get_serial_port_data(port);
+       unsigned long flags;
+
+       dbg("%s(port = %d, count = %d)", __FUNCTION__, port->number, count);
+
+       if (!count)
+               return count;
+
+       spin_lock_irqsave(&priv->lock, flags);
+       count = pl2303_buf_put(priv->buf, buf, count);
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       return count;
+}
+
+static int oti6858_write_room(struct usb_serial_port *port)
+{
+       struct oti6858_private *priv = usb_get_serial_port_data(port);
+       int room = 0;
+       unsigned long flags;
+
+       dbg("%s(port = %d)", __FUNCTION__, port->number);
+
+       spin_lock_irqsave(&priv->lock, flags);
+       room = pl2303_buf_space_avail(priv->buf);
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       return room;
+}
+
+static int oti6858_chars_in_buffer(struct usb_serial_port *port)
+{
+       struct oti6858_private *priv = usb_get_serial_port_data(port);
+       int chars = 0;
+       unsigned long flags;
+
+       dbg("%s(port = %d)", __FUNCTION__, port->number);
+
+       spin_lock_irqsave(&priv->lock, flags);
+       chars = pl2303_buf_data_avail(priv->buf);
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       return chars;
+}
+
+static void oti6858_set_termios(struct usb_serial_port *port,
+                               struct ktermios *old_termios)
+{
+       struct oti6858_private *priv = usb_get_serial_port_data(port);
+       unsigned long flags;
+       unsigned int cflag;
+       u8 frame_fmt, control;
+       u16 divisor;
+       int br;
+
+       dbg("%s(port = %d)", __FUNCTION__, port->number);
+
+       if ((!port->tty) || (!port->tty->termios)) {
+               dbg("%s(): no tty structures", __FUNCTION__);
+               return;
+       }
+
+       spin_lock_irqsave(&priv->lock, flags);
+       if (!priv->flags.termios_initialized) {
+               *(port->tty->termios) = tty_std_termios;
+               port->tty->termios->c_cflag = B38400 | CS8 | CREAD | HUPCL | CLOCAL;
+               priv->flags.termios_initialized = 1;
+       }
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       cflag = port->tty->termios->c_cflag;
+
+       spin_lock_irqsave(&priv->lock, flags);
+       divisor = priv->pending_setup.divisor;
+       frame_fmt = priv->pending_setup.frame_fmt;
+       control = priv->pending_setup.control;
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       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;
+       }
+
+       /* manufacturer claims that this device can work with baud rates
+        * up to 3 Mbps; I've tested it only on 115200 bps, so I can't
+        * guarantee that any other baud rate will work (especially
+        * the higher ones)
+        */
+       br = tty_get_baud_rate(port->tty);
+       if (br == 0) {
+               divisor = 0;
+       } else if (br <= OTI6858_MAX_BAUD_RATE) {
+               int real_br;
+
+               divisor = (96000000 + 8 * br) / (16 * br);
+               real_br = 96000000 / (16 * divisor);
+               if ((((real_br - br) * 100 + br - 1) / br) > 2) {
+                       dbg("%s(): baud rate %d is invalid", __FUNCTION__, br);
+                       return;
+               }
+               divisor = cpu_to_le16(divisor);
+       } else {
+               dbg("%s(): baud rate %d is too high", __FUNCTION__, br);
+               return;
+       }
+
+       frame_fmt &= ~FMT_STOP_BITS_MASK;
+       if ((cflag & CSTOPB) != 0) {
+               frame_fmt |= FMT_STOP_BITS_2;
+       } else {
+               frame_fmt |= FMT_STOP_BITS_1;
+       }
+
+       frame_fmt &= ~FMT_PARITY_MASK;
+       if ((cflag & PARENB) != 0) {
+               if ((cflag & PARODD) != 0) {
+                       frame_fmt |= FMT_PARITY_ODD;
+               } else {
+                       frame_fmt |= FMT_PARITY_EVEN;
+               }
+       } else {
+               frame_fmt |= FMT_PARITY_NONE;
+       }
+
+       control &= ~CONTROL_MASK;
+       if ((cflag & CRTSCTS) != 0)
+               control |= (CONTROL_DTR_HIGH | CONTROL_RTS_HIGH);
+
+       /* change control lines if we are switching to or from B0 */
+       /* FIXME:
+       spin_lock_irqsave(&priv->lock, flags);
+       control = priv->line_control;
+       if ((cflag & CBAUD) == B0)
+               priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS);
+       else
+               priv->line_control |= (CONTROL_DTR | CONTROL_RTS);
+       if (control != priv->line_control) {
+               control = priv->line_control;
+               spin_unlock_irqrestore(&priv->lock, flags);
+               set_control_lines(serial->dev, control);
+       } else {
+               spin_unlock_irqrestore(&priv->lock, flags);
+       }
+       */
+
+       spin_lock_irqsave(&priv->lock, flags);
+       if (divisor != priv->pending_setup.divisor
+                       || control != priv->pending_setup.control
+                       || frame_fmt != priv->pending_setup.frame_fmt) {
+               priv->pending_setup.divisor = divisor;
+               priv->pending_setup.control = control;
+               priv->pending_setup.frame_fmt = frame_fmt;
+       }
+       spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static int oti6858_open(struct usb_serial_port *port, struct file *filp)
+{
+       struct oti6858_private *priv = usb_get_serial_port_data(port);
+       struct ktermios tmp_termios;
+       struct usb_serial *serial = port->serial;
+       struct oti6858_control_pkt *buf;
+       unsigned long flags;
+       int result;
+
+       dbg("%s(port = %d)", __FUNCTION__, port->number);
+
+       usb_clear_halt(serial->dev, port->write_urb->pipe);
+       usb_clear_halt(serial->dev, port->read_urb->pipe);
+
+       if (port->open_count != 1)
+               return 0;
+
+       if ((buf = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL)) == NULL) {
+               dev_err(&port->dev, "%s(): out of memory!\n", __FUNCTION__);
+               return -ENOMEM;
+       }
+
+       result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+                               OTI6858_REQ_T_GET_STATUS,
+                               OTI6858_REQ_GET_STATUS,
+                               0, 0,
+                               buf, OTI6858_CTRL_PKT_SIZE,
+                               100);
+       if (result != OTI6858_CTRL_PKT_SIZE) {
+               /* assume default (after power-on reset) values */
+               buf->divisor = cpu_to_le16(0x009c);     /* 38400 bps */
+               buf->frame_fmt = 0x03;  /* 8N1 */
+               buf->something = 0x43;
+               buf->control = 0x4c;    /* DTR, RTS */
+               buf->tx_status = 0x00;
+               buf->pin_state = 0x5b;  /* RTS, CTS, DSR, DTR, RI, DCD */
+               buf->rx_bytes_avail = 0x00;
+       }
+
+       spin_lock_irqsave(&priv->lock, flags);
+       memcpy(&priv->status, buf, OTI6858_CTRL_PKT_SIZE);
+       priv->pending_setup.divisor = buf->divisor;
+       priv->pending_setup.frame_fmt = buf->frame_fmt;
+       priv->pending_setup.control = buf->control;
+       spin_unlock_irqrestore(&priv->lock, flags);
+       kfree(buf);
+
+       dbg("%s(): submitting interrupt urb", __FUNCTION__);
+       port->interrupt_in_urb->dev = serial->dev;
+       result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
+       if (result != 0) {
+               dev_err(&port->dev, "%s(): usb_submit_urb() failed"
+                              " with error %d\n", __FUNCTION__, result);
+               oti6858_close(port, NULL);
+               return -EPROTO;
+       }
+
+       /* setup termios */
+       if (port->tty)
+               oti6858_set_termios(port, &tmp_termios);
+
+       return 0;
+}
+
+static void oti6858_close(struct usb_serial_port *port, struct file *filp)
+{
+       struct oti6858_private *priv = usb_get_serial_port_data(port);
+       unsigned long flags;
+       long timeout;
+       wait_queue_t wait;
+
+       dbg("%s(port = %d)", __FUNCTION__, port->number);
+
+       /* wait for data to drain from the buffer */
+       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);
+       dbg("%s(): entering wait loop", __FUNCTION__);
+       for (;;) {
+               set_current_state(TASK_INTERRUPTIBLE);
+               if (pl2303_buf_data_avail(priv->buf) == 0
+               || timeout == 0 || signal_pending(current)
+               || !usb_get_intfdata(port->serial->interface))  /* disconnect */
+                       break;
+               spin_unlock_irqrestore(&priv->lock, flags);
+               timeout = schedule_timeout(timeout);
+               spin_lock_irqsave(&priv->lock, flags);
+       }
+       set_current_state(TASK_RUNNING);
+       remove_wait_queue(&port->tty->write_wait, &wait);
+       dbg("%s(): after wait loop", __FUNCTION__);
+
+       /* clear out any remaining data in the buffer */
+       pl2303_buf_clear(priv->buf);
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       /* wait for characters to drain from the device */
+       /* (this is long enough for the entire 256 byte */
+       /* pl2303 hardware buffer to drain with no 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) */
+       /* FIXME
+       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);
+       dbg("%s(): after schedule_timeout_interruptible()", __FUNCTION__);
+
+       /* cancel scheduled setup */
+       cancel_delayed_work(&priv->delayed_setup_work);
+       cancel_delayed_work(&priv->delayed_write_work);
+       flush_scheduled_work();
+
+       /* shutdown our urbs */
+       dbg("%s(): shutting down urbs", __FUNCTION__);
+       usb_kill_urb(port->write_urb);
+       usb_kill_urb(port->read_urb);
+       usb_kill_urb(port->interrupt_in_urb);
+
+       /*
+       if (port->tty && (port->tty->termios->c_cflag) & HUPCL) {
+               // drop DTR and RTS
+               spin_lock_irqsave(&priv->lock, flags);
+               priv->pending_setup.control &= ~CONTROL_MASK;
+               spin_unlock_irqrestore(&priv->lock, flags);
+       }
+       */
+}
+
+static int oti6858_tiocmset(struct usb_serial_port *port, struct file *file,
+                               unsigned int set, unsigned int clear)
+{
+       struct oti6858_private *priv = usb_get_serial_port_data(port);
+       unsigned long flags;
+       u8 control;
+
+       dbg("%s(port = %d, set = 0x%08x, clear = 0x%08x)",
+                               __FUNCTION__, port->number, set, clear);
+
+       if (!usb_get_intfdata(port->serial->interface))
+               return -ENODEV;
+
+       /* FIXME: check if this is correct (active high/low) */
+       spin_lock_irqsave(&priv->lock, flags);
+       control = priv->pending_setup.control;
+       if ((set & TIOCM_RTS) != 0)
+               control |= CONTROL_RTS_HIGH;
+       if ((set & TIOCM_DTR) != 0)
+               control |= CONTROL_DTR_HIGH;
+       if ((clear & TIOCM_RTS) != 0)
+               control &= ~CONTROL_RTS_HIGH;
+       if ((clear & TIOCM_DTR) != 0)
+               control &= ~CONTROL_DTR_HIGH;
+
+       if (control != priv->pending_setup.control) {
+               priv->pending_setup.control = control;
+       }
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       return 0;
+}
+
+static int oti6858_tiocmget(struct usb_serial_port *port, struct file *file)
+{
+       struct oti6858_private *priv = usb_get_serial_port_data(port);
+       unsigned long flags;
+       unsigned pin_state;
+       unsigned result = 0;
+
+       dbg("%s(port = %d)", __FUNCTION__, port->number);
+
+       if (!usb_get_intfdata(port->serial->interface))
+               return -ENODEV;
+
+       spin_lock_irqsave(&priv->lock, flags);
+       pin_state = priv->status.pin_state & PIN_MASK;
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       /* FIXME: check if this is correct (active high/low) */
+       if ((pin_state & PIN_RTS) != 0)
+               result |= TIOCM_RTS;
+       if ((pin_state & PIN_CTS) != 0)
+               result |= TIOCM_CTS;
+       if ((pin_state & PIN_DSR) != 0)
+               result |= TIOCM_DSR;
+       if ((pin_state & PIN_DTR) != 0)
+               result |= TIOCM_DTR;
+       if ((pin_state & PIN_RI) != 0)
+               result |= TIOCM_RI;
+       if ((pin_state & PIN_DCD) != 0)
+               result |= TIOCM_CD;
+
+       dbg("%s() = 0x%08x", __FUNCTION__, result);
+
+       return result;
+}
+
+static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
+{
+       struct oti6858_private *priv = usb_get_serial_port_data(port);
+       unsigned long flags;
+       unsigned int prev, status;
+       unsigned int changed;
+
+       spin_lock_irqsave(&priv->lock, flags);
+       prev = priv->status.pin_state;
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       while (1) {
+               wait_event_interruptible(priv->intr_wait, priv->status.pin_state != prev);
+               if (signal_pending(current))
+                       return -ERESTARTSYS;
+
+               spin_lock_irqsave(&priv->lock, flags);
+               status = priv->status.pin_state & PIN_MASK;
+               spin_unlock_irqrestore(&priv->lock, flags);
+
+               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;
+               }
+               prev = status;
+       }
+
+       /* NOTREACHED */
+       return 0;
+}
+
+static int oti6858_ioctl(struct usb_serial_port *port, struct file *file,
+                       unsigned int cmd, unsigned long arg)
+{
+       void __user *user_arg = (void __user *) arg;
+       unsigned int x;
+
+       dbg("%s(port = %d, cmd = 0x%04x, arg = 0x%08lx)",
+                               __FUNCTION__, port->number, cmd, arg);
+
+       switch (cmd) {
+               case TCGETS:
+                       if (copy_to_user(user_arg, port->tty->termios,
+                                               sizeof(struct ktermios))) {
+                               return -EFAULT;
+                       }
+                       return 0;
+
+               case TCSETS:
+               case TCSETSW:   /* FIXME: this is not the same! */
+               case TCSETSF:   /* FIXME: this is not the same! */
+                       if (copy_from_user(port->tty->termios, user_arg,
+                                               sizeof(struct ktermios))) {
+                               return -EFAULT;
+                       }
+                       oti6858_set_termios(port, NULL);
+                       return 0;
+
+               case TCFLSH:
+                       /* FIXME */
+                       return 0;
+
+               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 TIOCGSERIAL:
+                       if (copy_to_user(user_arg, port->tty->termios,
+                                               sizeof(struct ktermios))) {
+                               return -EFAULT;
+                       }
+                        return 0;
+
+               case TIOCSSERIAL:
+                       if (copy_from_user(port->tty->termios, user_arg,
+                                               sizeof(struct ktermios))) {
+                               return -EFAULT;
+                       }
+                       oti6858_set_termios(port, NULL);
+                       return 0;
+
+               case TIOCMIWAIT:
+                       dbg("%s(): TIOCMIWAIT", __FUNCTION__);
+                       return wait_modem_info(port, arg);
+
+               default:
+                       dbg("%s(): 0x%04x not supported", __FUNCTION__, cmd);
+                       break;
+       }
+
+       return -ENOIOCTLCMD;
+}
+
+static void oti6858_break_ctl(struct usb_serial_port *port, int break_state)
+{
+       int state;
+
+       dbg("%s(port = %d)", __FUNCTION__, port->number);
+
+       state = (break_state == 0) ? 0 : 1;
+       dbg("%s(): turning break %s", __FUNCTION__, 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", __FUNCTION__);
+ */
+}
+
+static void oti6858_shutdown(struct usb_serial *serial)
+{
+       struct oti6858_private *priv;
+       int i;
+
+       dbg("%s()", __FUNCTION__);
+
+       for (i = 0; i < serial->num_ports; ++i) {
+               priv = usb_get_serial_port_data(serial->port[i]);
+               if (priv) {
+                       pl2303_buf_free(priv->buf);
+                       kfree(priv);
+                       usb_set_serial_port_data(serial->port[i], NULL);
+               }
+       }
+}
+
+static void oti6858_read_int_callback(struct urb *urb)
+{
+       struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
+       struct oti6858_private *priv = usb_get_serial_port_data(port);
+       int transient = 0, can_recv = 0, resubmit = 1;
+       int status = urb->status;
+
+       dbg("%s(port = %d, status = %d)",
+                               __FUNCTION__, port->number, status);
+
+       switch (status) {
+       case 0:
+               /* success */
+               break;
+       case -ECONNRESET:
+       case -ENOENT:
+       case -ESHUTDOWN:
+               /* this urb is terminated, clean up */
+               dbg("%s(): urb shutting down with status: %d",
+                                       __FUNCTION__, status);
+               return;
+       default:
+               dbg("%s(): nonzero urb status received: %d",
+                                       __FUNCTION__, status);
+               break;
+       }
+
+       if (status == 0 && urb->actual_length == OTI6858_CTRL_PKT_SIZE) {
+               struct oti6858_control_pkt *xs = urb->transfer_buffer;
+               unsigned long flags;
+
+               spin_lock_irqsave(&priv->lock, flags);
+
+               if (!priv->transient) {
+                       if (!OTI6858_CTRL_EQUALS_PENDING(xs, priv)) {
+                               if (xs->rx_bytes_avail == 0) {
+                                       priv->transient = 4;
+                                       priv->setup_done = 0;
+                                       resubmit = 0;
+                                       dbg("%s(): scheduling setup_line()",
+                                           __FUNCTION__);
+                                       schedule_delayed_work(&priv->delayed_setup_work, 0);
+                               }
+                       }
+               } else {
+                       if (OTI6858_CTRL_EQUALS_PENDING(xs, priv)) {
+                               priv->transient = 0;
+                       } else if (!priv->setup_done) {
+                               resubmit = 0;
+                       } else if (--priv->transient == 0) {
+                               if (xs->rx_bytes_avail == 0) {
+                                       priv->transient = 4;
+                                       priv->setup_done = 0;
+                                       resubmit = 0;
+                                       dbg("%s(): scheduling setup_line()",
+                                           __FUNCTION__);
+                                       schedule_delayed_work(&priv->delayed_setup_work, 0);
+                               }
+                       }
+               }
+
+               if (!priv->transient) {
+                       if (xs->pin_state != priv->status.pin_state)
+                               wake_up_interruptible(&priv->intr_wait);
+                       memcpy(&priv->status, xs, OTI6858_CTRL_PKT_SIZE);
+               }
+
+               if (!priv->transient && xs->rx_bytes_avail != 0) {
+                       can_recv = xs->rx_bytes_avail;
+                       priv->flags.read_urb_in_use = 1;
+               }
+
+               transient = priv->transient;
+               spin_unlock_irqrestore(&priv->lock, flags);
+       }
+
+       if (can_recv) {
+               int result;
+
+               port->read_urb->dev = port->serial->dev;
+               result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
+               if (result != 0) {
+                       priv->flags.read_urb_in_use = 0;
+                       dev_err(&port->dev, "%s(): usb_submit_urb() failed,"
+                                       " error %d\n", __FUNCTION__, result);
+               } else {
+                       resubmit = 0;
+               }
+       } else if (!transient) {
+               unsigned long flags;
+
+               spin_lock_irqsave(&priv->lock, flags);
+               if (priv->flags.write_urb_in_use == 0
+                               && pl2303_buf_data_avail(priv->buf) != 0) {
+                       schedule_delayed_work(&priv->delayed_write_work,0);
+                       resubmit = 0;
+               }
+               spin_unlock_irqrestore(&priv->lock, flags);
+       }
+
+       if (resubmit) {
+               int result;
+
+//             dbg("%s(): submitting interrupt urb", __FUNCTION__);
+               urb->dev = port->serial->dev;
+               result = usb_submit_urb(urb, GFP_ATOMIC);
+               if (result != 0) {
+                       dev_err(&urb->dev->dev,
+                                       "%s(): usb_submit_urb() failed with"
+                                       " error %d\n", __FUNCTION__, result);
+               }
+       }
+}
+
+static void oti6858_read_bulk_callback(struct urb *urb)
+{
+       struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
+       struct oti6858_private *priv = usb_get_serial_port_data(port);
+       struct tty_struct *tty;
+       unsigned char *data = urb->transfer_buffer;
+       unsigned long flags;
+       int i, result;
+       int status = urb->status;
+       char tty_flag;
+
+       dbg("%s(port = %d, status = %d)",
+                               __FUNCTION__, port->number, status);
+
+       spin_lock_irqsave(&priv->lock, flags);
+       priv->flags.read_urb_in_use = 0;
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       if (status != 0) {
+               if (!port->open_count) {
+                       dbg("%s(): port is closed, exiting", __FUNCTION__);
+                       return;
+               }
+               /*
+               if (status == -EPROTO) {
+                       // PL2303 mysteriously fails with -EPROTO reschedule the read
+                       dbg("%s - caught -EPROTO, resubmitting the urb", __FUNCTION__);
+                       result = usb_submit_urb(urb, GFP_ATOMIC);
+                       if (result)
+                               dev_err(&urb->dev->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result);
+                       return;
+               }
+               */
+               dbg("%s(): unable to handle the error, exiting", __FUNCTION__);
+               return;
+       }
+
+       // get tty_flag from status
+       tty_flag = TTY_NORMAL;
+
+/* FIXME: probably, errors will be signalled using interrupt pipe! */
+/*
+       // break takes precedence over parity,
+       // which takes precedence over framing errors
+       if (status & UART_BREAK_ERROR )
+               tty_flag = TTY_BREAK;
+       else if (status & UART_PARITY_ERROR)
+               tty_flag = TTY_PARITY;
+       else if (status & UART_FRAME_ERROR)
+               tty_flag = TTY_FRAME;
+       dbg("%s - tty_flag = %d", __FUNCTION__, tty_flag);
+*/
+
+       tty = port->tty;
+       if (tty != NULL && urb->actual_length > 0) {
+               tty_buffer_request_room(tty, urb->actual_length);
+               for (i = 0; i < urb->actual_length; ++i)
+                       tty_insert_flip_char(tty, data[i], tty_flag);
+               tty_flip_buffer_push(tty);
+       }
+
+       // schedule the interrupt urb if we are still open */
+       if (port->open_count != 0) {
+               port->interrupt_in_urb->dev = port->serial->dev;
+               result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
+               if (result != 0) {
+                       dev_err(&port->dev, "%s(): usb_submit_urb() failed,"
+                                       " error %d\n", __FUNCTION__, result);
+               }
+       }
+}
+
+static void oti6858_write_bulk_callback(struct urb *urb)
+{
+       struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
+       struct oti6858_private *priv = usb_get_serial_port_data(port);
+       int status = urb->status;
+       int result;
+
+       dbg("%s(port = %d, status = %d)",
+                               __FUNCTION__, port->number, status);
+
+       switch (status) {
+       case 0:
+               /* success */
+               break;
+       case -ECONNRESET:
+       case -ENOENT:
+       case -ESHUTDOWN:
+               /* this urb is terminated, clean up */
+               dbg("%s(): urb shutting down with status: %d",
+                                       __FUNCTION__, status);
+               priv->flags.write_urb_in_use = 0;
+               return;
+       default:
+               /* error in the urb, so we have to resubmit it */
+               dbg("%s(): nonzero write bulk status received: %d",
+                                       __FUNCTION__, status);
+               dbg("%s(): overflow in write", __FUNCTION__);
+
+               port->write_urb->transfer_buffer_length = 1;
+               port->write_urb->dev = port->serial->dev;
+               result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
+               if (result) {
+                       dev_err(&port->dev, "%s(): usb_submit_urb() failed,"
+                                       " error %d\n", __FUNCTION__, result);
+               } else {
+                       return;
+               }
+       }
+
+       priv->flags.write_urb_in_use = 0;
+
+       // schedule the interrupt urb if we are still open */
+       port->interrupt_in_urb->dev = port->serial->dev;
+       dbg("%s(): submitting interrupt urb", __FUNCTION__);
+       result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
+       if (result != 0) {
+               dev_err(&port->dev, "%s(): failed submitting int urb,"
+                                       " error %d\n", __FUNCTION__, result);
+       }
+}
+
+
+/*
+ * pl2303_buf_alloc
+ *
+ * Allocate a circular buffer and all associated memory.
+ */
+static struct pl2303_buf *pl2303_buf_alloc(unsigned int size)
+{
+       struct pl2303_buf *pb;
+
+       if (size == 0)
+               return NULL;
+
+       pb = (struct pl2303_buf *)kmalloc(sizeof(struct pl2303_buf), GFP_KERNEL);
+       if (pb == NULL)
+               return NULL;
+
+       pb->buf_buf = kmalloc(size, GFP_KERNEL);
+       if (pb->buf_buf == NULL) {
+               kfree(pb);
+               return NULL;
+       }
+
+       pb->buf_size = size;
+       pb->buf_get = pb->buf_put = pb->buf_buf;
+
+       return pb;
+}
+
+/*
+ * pl2303_buf_free
+ *
+ * Free the buffer and all associated memory.
+ */
+static void pl2303_buf_free(struct pl2303_buf *pb)
+{
+       if (pb) {
+               kfree(pb->buf_buf);
+               kfree(pb);
+       }
+}
+
+/*
+ * pl2303_buf_clear
+ *
+ * Clear out all data in the circular buffer.
+ */
+static void pl2303_buf_clear(struct pl2303_buf *pb)
+{
+       if (pb != NULL) {
+               /* equivalent to a get of all data available */
+               pb->buf_get = pb->buf_put;
+       }
+}
+
+/*
+ * pl2303_buf_data_avail
+ *
+ * Return the number of bytes of data available in the circular
+ * buffer.
+ */
+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);
+}
+
+/*
+ * pl2303_buf_space_avail
+ *
+ * Return the number of bytes of space available in the circular
+ * buffer.
+ */
+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);
+}
+
+/*
+ * pl2303_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 pl2303_buf_put(struct pl2303_buf *pb, const char *buf,
+                                       unsigned int count)
+{
+       unsigned int len;
+
+       if (pb == NULL)
+               return 0;
+
+       len  = pl2303_buf_space_avail(pb);
+       if (count > len)
+               count = len;
+
+       if (count == 0)
+               return 0;
+
+       len = pb->buf_buf + pb->buf_size - pb->buf_put;
+       if (count > len) {
+               memcpy(pb->buf_put, buf, len);
+               memcpy(pb->buf_buf, buf+len, count - len);
+               pb->buf_put = pb->buf_buf + count - len;
+       } else {
+               memcpy(pb->buf_put, buf, count);
+               if (count < len)
+                       pb->buf_put += count;
+               else /* count == len */
+                       pb->buf_put = pb->buf_buf;
+       }
+
+       return count;
+}
+
+/*
+ * pl2303_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 pl2303_buf_get(struct pl2303_buf *pb, char *buf,
+                                       unsigned int count)
+{
+       unsigned int len;
+
+       if (pb == NULL)
+               return 0;
+
+       len = pl2303_buf_data_avail(pb);
+       if (count > len)
+               count = len;
+
+       if (count == 0)
+               return 0;
+
+       len = pb->buf_buf + pb->buf_size - pb->buf_get;
+       if (count > len) {
+               memcpy(buf, pb->buf_get, len);
+               memcpy(buf+len, pb->buf_buf, count - len);
+               pb->buf_get = pb->buf_buf + count - len;
+       } else {
+               memcpy(buf, pb->buf_get, count);
+               if (count < len)
+                       pb->buf_get += count;
+               else /* count == len */
+                       pb->buf_get = pb->buf_buf;
+       }
+
+       return count;
+}
+
+/* module description and (de)initialization */
+
+static int __init oti6858_init(void)
+{
+       int retval;
+
+       if ((retval = usb_serial_register(&oti6858_device)) == 0) {
+               if ((retval = usb_register(&oti6858_driver)) != 0)
+                       usb_serial_deregister(&oti6858_device);
+               else
+                       return 0;
+       }
+
+       return retval;
+}
+
+static void __exit oti6858_exit(void)
+{
+       usb_deregister(&oti6858_driver);
+       usb_serial_deregister(&oti6858_device);
+}
+
+module_init(oti6858_init);
+module_exit(oti6858_exit);
+
+MODULE_DESCRIPTION(OTI6858_DESCRIPTION);
+MODULE_AUTHOR(OTI6858_AUTHOR);
+MODULE_VERSION(OTI6858_VERSION);
+MODULE_LICENSE("GPL");
+
+module_param(debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "enable debug output");
+
diff --git a/drivers/usb/serial/oti6858.h b/drivers/usb/serial/oti6858.h
new file mode 100644 (file)
index 0000000..704ac3a
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * Ours Technology Inc. OTi-6858 USB to serial adapter driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#ifndef __LINUX_USB_SERIAL_OTI6858_H
+#define __LINUX_USB_SERIAL_OTI6858_H
+
+#define OTI6858_VENDOR_ID      0x0ea0
+#define OTI6858_PRODUCT_ID     0x6858
+
+#endif
index 83dfae93a45db37278ee130e3b99fb30a2328a23..f9f85f56f0db48a0c3f67262be1f64a0e81ee6f2 100644 (file)
@@ -1,14 +1,14 @@
 /*
  * Prolific PL2303 USB to serial adaptor driver
  *
- * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (C) 2001-2007 Greg Kroah-Hartman (greg@kroah.com)
  * Copyright (C) 2003 IBM Corp.
  *
  * Original driver for 2.2.x by anonymous
  *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License.
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License version
+ *     2 as published by the Free Software Foundation.
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  *
@@ -484,15 +484,6 @@ static void pl2303_set_termios(struct usb_serial_port *port,
        spin_unlock_irqrestore(&priv->lock, flags);
 
        cflag = port->tty->termios->c_cflag;
-       /* check that they really want us to change something */
-       if (old_termios) {
-               if ((cflag == old_termios->c_cflag) &&
-                   (RELEVANT_IFLAG(port->tty->termios->c_iflag) ==
-                    RELEVANT_IFLAG(old_termios->c_iflag))) {
-                       dbg("%s - nothing to change...", __FUNCTION__);
-                       return;
-               }
-       }
 
        buf = kzalloc(7, GFP_KERNEL);
        if (!buf) {
@@ -517,29 +508,7 @@ static void pl2303_set_termios(struct usb_serial_port *port,
                dbg("%s - data bits = %d", __FUNCTION__, buf[6]);
        }
 
-       baud = 0;
-       switch (cflag & CBAUD) {
-               case B0:        baud = 0;       break;
-               case B75:       baud = 75;      break;
-               case B150:      baud = 150;     break;
-               case B300:      baud = 300;     break;
-               case B600:      baud = 600;     break;
-               case B1200:     baud = 1200;    break;
-               case B1800:     baud = 1800;    break;
-               case B2400:     baud = 2400;    break;
-               case B4800:     baud = 4800;    break;
-               case B9600:     baud = 9600;    break;
-               case B19200:    baud = 19200;   break;
-               case B38400:    baud = 38400;   break;
-               case B57600:    baud = 57600;   break;
-               case B115200:   baud = 115200;  break;
-               case B230400:   baud = 230400;  break;
-               case B460800:   baud = 460800;  break;
-               default:
-                       dev_err(&port->dev, "pl2303 driver does not support"
-                               " the baudrate requested (fix it)\n");
-                       break;
-       }
+       baud = tty_get_baud_rate(port->tty);;
        dbg("%s - baud = %d", __FUNCTION__, baud);
        if (baud) {
                buf[0] = baud & 0xff;
@@ -617,6 +586,13 @@ static void pl2303_set_termios(struct usb_serial_port *port,
                                    VENDOR_WRITE_REQUEST_TYPE,
                                    0x0, index, NULL, 0, 100);
                dbg("0x40:0x1:0x0:0x%x  %d", index, i);
+       } else {
+               i = usb_control_msg(serial->dev,
+                                   usb_sndctrlpipe(serial->dev, 0),
+                                   VENDOR_WRITE_REQUEST,
+                                   VENDOR_WRITE_REQUEST_TYPE,
+                                   0x0, 0x0, NULL, 0, 100);
+               dbg ("0x40:0x1:0x0:0x0  %d", i);
        }
 
        kfree(buf);
@@ -954,11 +930,12 @@ static void pl2303_read_int_callback(struct urb *urb)
        struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
        unsigned char *data = urb->transfer_buffer;
        unsigned int actual_length = urb->actual_length;
-       int status;
+       int status = urb->status;
+       int retval;
 
        dbg("%s (%d)", __FUNCTION__, port->number);
 
-       switch (urb->status) {
+       switch (status) {
        case 0:
                /* success */
                break;
@@ -967,11 +944,11 @@ static void pl2303_read_int_callback(struct urb *urb)
        case -ESHUTDOWN:
                /* this urb is terminated, clean up */
                dbg("%s - urb shutting down with status: %d", __FUNCTION__,
-                   urb->status);
+                   status);
                return;
        default:
                dbg("%s - nonzero urb status received: %d", __FUNCTION__,
-                   urb->status);
+                   status);
                goto exit;
        }
 
@@ -981,11 +958,11 @@ static void pl2303_read_int_callback(struct urb *urb)
        pl2303_update_line_status(port, data, actual_length);
 
 exit:
-       status = usb_submit_urb(urb, GFP_ATOMIC);
-       if (status)
+       retval = usb_submit_urb(urb, GFP_ATOMIC);
+       if (retval)
                dev_err(&urb->dev->dev,
                        "%s - usb_submit_urb failed with result %d\n",
-                       __FUNCTION__, status);
+                       __FUNCTION__, retval);
 }
 
 static void pl2303_read_bulk_callback(struct urb *urb)
@@ -997,23 +974,23 @@ static void pl2303_read_bulk_callback(struct urb *urb)
        unsigned long flags;
        int i;
        int result;
-       u8 status;
+       int status = urb->status;
+       u8 line_status;
        char tty_flag;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
-       if (urb->status) {
-               dbg("%s - urb->status = %d", __FUNCTION__, urb->status);
+       if (status) {
+               dbg("%s - urb status = %d", __FUNCTION__, status);
                if (!port->open_count) {
                        dbg("%s - port is closed, exiting.", __FUNCTION__);
                        return;
                }
-               if (urb->status == -EPROTO) {
+               if (status == -EPROTO) {
                        /* PL2303 mysteriously fails with -EPROTO reschedule
                         * the read */
                        dbg("%s - caught -EPROTO, resubmitting the urb",
                            __FUNCTION__);
-                       urb->status = 0;
                        urb->dev = port->serial->dev;
                        result = usb_submit_urb(urb, GFP_ATOMIC);
                        if (result)
@@ -1033,18 +1010,18 @@ static void pl2303_read_bulk_callback(struct urb *urb)
        tty_flag = TTY_NORMAL;
 
        spin_lock_irqsave(&priv->lock, flags);
-       status = priv->line_status;
+       line_status = priv->line_status;
        priv->line_status &= ~UART_STATE_TRANSIENT_MASK;
        spin_unlock_irqrestore(&priv->lock, flags);
        wake_up_interruptible(&priv->delta_msr_wait);
 
        /* break takes precedence over parity, */
        /* which takes precedence over framing errors */
-       if (status & UART_BREAK_ERROR )
+       if (line_status & UART_BREAK_ERROR )
                tty_flag = TTY_BREAK;
-       else if (status & UART_PARITY_ERROR)
+       else if (line_status & UART_PARITY_ERROR)
                tty_flag = TTY_PARITY;
-       else if (status & UART_FRAME_ERROR)
+       else if (line_status & UART_FRAME_ERROR)
                tty_flag = TTY_FRAME;
        dbg("%s - tty_flag = %d", __FUNCTION__, tty_flag);
 
@@ -1052,7 +1029,7 @@ static void pl2303_read_bulk_callback(struct urb *urb)
        if (tty && urb->actual_length) {
                tty_buffer_request_room(tty, urb->actual_length + 1);
                /* overrun is special, not associated with a char */
-               if (status & UART_OVERRUN_ERROR)
+               if (line_status & UART_OVERRUN_ERROR)
                        tty_insert_flip_char(tty, 0, TTY_OVERRUN);
                for (i = 0; i < urb->actual_length; ++i)
                        tty_insert_flip_char(tty, data[i], tty_flag);
@@ -1076,10 +1053,11 @@ static void pl2303_write_bulk_callback(struct urb *urb)
        struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
        struct pl2303_private *priv = usb_get_serial_port_data(port);
        int result;
+       int status = urb->status;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
-       switch (urb->status) {
+       switch (status) {
        case 0:
                /* success */
                break;
@@ -1088,14 +1066,14 @@ static void pl2303_write_bulk_callback(struct urb *urb)
        case -ESHUTDOWN:
                /* this urb is terminated, clean up */
                dbg("%s - urb shutting down with status: %d", __FUNCTION__,
-                   urb->status);
+                   status);
                priv->write_urb_in_use = 0;
                return;
        default:
                /* error in the urb, so we have to resubmit it */
                dbg("%s - Overflow in write", __FUNCTION__);
                dbg("%s - nonzero write bulk status received: %d", __FUNCTION__,
-                   urb->status);
+                   status);
                port->write_urb->transfer_buffer_length = 1;
                port->write_urb->dev = port->serial->dev;
                result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
index 5a03a3fc938693b1056031dd046015d1ce9d6631..86899d55d8d818fcc0b81e7cd0a67c2d7ec19c0b 100644 (file)
@@ -211,11 +211,13 @@ static void safe_read_bulk_callback (struct urb *urb)
        unsigned char length = urb->actual_length;
        int i;
        int result;
+       int status = urb->status;
 
        dbg ("%s", __FUNCTION__);
 
-       if (urb->status) {
-               dbg ("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status);
+       if (status) {
+               dbg("%s - nonzero read bulk status received: %d",
+                   __FUNCTION__, status);
                return;
        }
 
index ac1829c6e8f02da29aecc3a5383a0c1dfa7a2b2e..e7db20343d1a156a898fe51e27754d8929a8f890 100644 (file)
@@ -86,15 +86,14 @@ static int debug;
 #define N_IN_URB       4
 #define N_OUT_URB      4
 #define IN_BUFLEN      4096
-#define OUT_BUFLEN     128
 
 struct sierra_port_private {
+       spinlock_t lock;        /* lock the structure */
+       int outstanding_urbs;   /* number of out urbs in flight */
+
        /* Input endpoints and buffer for this port */
        struct urb *in_urbs[N_IN_URB];
        char in_buffer[N_IN_URB][IN_BUFLEN];
-       /* Output endpoints and buffer for this port */
-       struct urb *out_urbs[N_OUT_URB];
-       char out_buffer[N_OUT_URB][OUT_BUFLEN];
 
        /* Settings for the port */
        int rts_state;  /* Handshaking pins (outputs) */
@@ -103,8 +102,6 @@ struct sierra_port_private {
        int dsr_state;
        int dcd_state;
        int ri_state;
-
-       unsigned long tx_start_time[N_OUT_URB];
 };
 
 static int sierra_send_setup(struct usb_serial_port *port)
@@ -197,61 +194,98 @@ static int sierra_ioctl(struct usb_serial_port *port, struct file *file,
        return -ENOIOCTLCMD;
 }
 
+static void sierra_outdat_callback(struct urb *urb)
+{
+       struct usb_serial_port *port = urb->context;
+       struct sierra_port_private *portdata = usb_get_serial_port_data(port);
+       int status = urb->status;
+       unsigned long flags;
+
+       dbg("%s - port %d", __FUNCTION__, 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",
+                   __FUNCTION__, status);
+
+       spin_lock_irqsave(&portdata->lock, flags);
+       --portdata->outstanding_urbs;
+       spin_unlock_irqrestore(&portdata->lock, flags);
+
+       usb_serial_port_softint(port);
+}
+
 /* Write */
 static int sierra_write(struct usb_serial_port *port,
                        const unsigned char *buf, int count)
 {
-       struct sierra_port_private *portdata;
-       int i;
-       int left, todo;
-       struct urb *this_urb = NULL; /* spurious */
-       int err;
+       struct sierra_port_private *portdata = usb_get_serial_port_data(port);
+       struct usb_serial *serial = port->serial;
+       unsigned long flags;
+       unsigned char *buffer;
+       struct urb *urb;
+       int status;
 
        portdata = usb_get_serial_port_data(port);
 
        dbg("%s: write (%d chars)", __FUNCTION__, count);
 
-       i = 0;
-       left = count;
-       for (i=0; left > 0 && i < N_OUT_URB; i++) {
-               todo = left;
-               if (todo > OUT_BUFLEN)
-                       todo = OUT_BUFLEN;
-
-               this_urb = portdata->out_urbs[i];
-               if (this_urb->status == -EINPROGRESS) {
-                       if (time_before(jiffies,
-                                       portdata->tx_start_time[i] + 10 * HZ))
-                               continue;
-                       usb_unlink_urb(this_urb);
-                       continue;
-               }
-               if (this_urb->status != 0)
-                       dbg("usb_write %p failed (err=%d)",
-                               this_urb, this_urb->status);
-
-               dbg("%s: endpoint %d buf %d", __FUNCTION__,
-                       usb_pipeendpoint(this_urb->pipe), i);
-
-               /* send the data */
-               memcpy (this_urb->transfer_buffer, buf, todo);
-               this_urb->transfer_buffer_length = todo;
-
-               this_urb->dev = port->serial->dev;
-               err = usb_submit_urb(this_urb, GFP_ATOMIC);
-               if (err) {
-                       dbg("usb_submit_urb %p (write bulk) failed "
-                               "(%d, has %d)", this_urb,
-                               err, this_urb->status);
-                       continue;
-               }
-               portdata->tx_start_time[i] = jiffies;
-               buf += todo;
-               left -= todo;
+       spin_lock_irqsave(&portdata->lock, flags);
+       if (portdata->outstanding_urbs > N_OUT_URB) {
+               spin_unlock_irqrestore(&portdata->lock, flags);
+               dbg("%s - write limit hit\n", __FUNCTION__);
+               return 0;
+       }
+       portdata->outstanding_urbs++;
+       spin_unlock_irqrestore(&portdata->lock, flags);
+
+       buffer = kmalloc(count, GFP_ATOMIC);
+       if (!buffer) {
+               dev_err(&port->dev, "out of memory\n");
+               count = -ENOMEM;
+               goto error_no_buffer;
+       }
+
+       urb = usb_alloc_urb(0, GFP_ATOMIC);
+       if (!urb) {
+               dev_err(&port->dev, "no more free urbs\n");
+               count = -ENOMEM;
+               goto error_no_urb;
+       }
+
+       memcpy(buffer, buf, count);
+
+       usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, buffer);
+
+       usb_fill_bulk_urb(urb, serial->dev,
+                         usb_sndbulkpipe(serial->dev,
+                                         port->bulk_out_endpointAddress),
+                         buffer, count, sierra_outdat_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", __FUNCTION__, status);
+               count = status;
+               goto error;
        }
 
-       count -= left;
-       dbg("%s: wrote (did %d)", __FUNCTION__, count);
+       /* 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;
+error:
+       usb_free_urb(urb);
+error_no_urb:
+       kfree(buffer);
+error_no_buffer:
+       spin_lock_irqsave(&portdata->lock, flags);
+       --portdata->outstanding_urbs;
+       spin_unlock_irqrestore(&portdata->lock, flags);
        return count;
 }
 
@@ -262,15 +296,16 @@ static void sierra_indat_callback(struct urb *urb)
        struct usb_serial_port *port;
        struct tty_struct *tty;
        unsigned char *data = urb->transfer_buffer;
+       int status = urb->status;
 
        dbg("%s: %p", __FUNCTION__, urb);
 
        endpoint = usb_pipeendpoint(urb->pipe);
        port = (struct usb_serial_port *) urb->context;
 
-       if (urb->status) {
+       if (status) {
                dbg("%s: nonzero status: %d on endpoint %02x.",
-                   __FUNCTION__, urb->status, endpoint);
+                   __FUNCTION__, status, endpoint);
        } else {
                tty = port->tty;
                if (urb->actual_length) {
@@ -282,30 +317,20 @@ static void sierra_indat_callback(struct urb *urb)
                }
 
                /* Resubmit urb so we continue receiving */
-               if (port->open_count && urb->status != -ESHUTDOWN) {
+               if (port->open_count && status != -ESHUTDOWN) {
                        err = usb_submit_urb(urb, GFP_ATOMIC);
                        if (err)
-                               printk(KERN_ERR "%s: resubmit read urb failed. "
-                                       "(%d)", __FUNCTION__, err);
+                               dev_err(&port->dev, "resubmit read urb failed."
+                                       "(%d)", err);
                }
        }
        return;
 }
 
-static void sierra_outdat_callback(struct urb *urb)
-{
-       struct usb_serial_port *port;
-
-       dbg("%s", __FUNCTION__);
-
-       port = (struct usb_serial_port *) urb->context;
-
-       usb_serial_port_softint(port);
-}
-
 static void sierra_instat_callback(struct urb *urb)
 {
        int err;
+       int status = urb->status;
        struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
        struct sierra_port_private *portdata = usb_get_serial_port_data(port);
        struct usb_serial *serial = port->serial;
@@ -313,7 +338,7 @@ static void sierra_instat_callback(struct urb *urb)
        dbg("%s", __FUNCTION__);
        dbg("%s: urb %p port %p has data %p", __FUNCTION__,urb,port,portdata);
 
-       if (urb->status == 0) {
+       if (status == 0) {
                struct usb_ctrlrequest *req_pkt =
                                (struct usb_ctrlrequest *)urb->transfer_buffer;
 
@@ -344,10 +369,10 @@ static void sierra_instat_callback(struct urb *urb)
                                req_pkt->bRequestType,req_pkt->bRequest);
                }
        } else
-               dbg("%s: error %d", __FUNCTION__, urb->status);
+               dbg("%s: error %d", __FUNCTION__, status);
 
        /* Resubmit urb so we continue receiving IRQ data */
-       if (urb->status != -ESHUTDOWN) {
+       if (status != -ESHUTDOWN) {
                urb->dev = serial->dev;
                err = usb_submit_urb(urb, GFP_ATOMIC);
                if (err)
@@ -358,46 +383,42 @@ static void sierra_instat_callback(struct urb *urb)
 
 static int sierra_write_room(struct usb_serial_port *port)
 {
-       struct sierra_port_private *portdata;
-       int i;
-       int data_len = 0;
-       struct urb *this_urb;
+       struct sierra_port_private *portdata = usb_get_serial_port_data(port);
+       unsigned long flags;
 
-       portdata = usb_get_serial_port_data(port);
+       dbg("%s - port %d", __FUNCTION__, port->number);
 
-       for (i=0; i < N_OUT_URB; i++) {
-               this_urb = portdata->out_urbs[i];
-               if (this_urb && this_urb->status != -EINPROGRESS)
-                       data_len += OUT_BUFLEN;
+       /* try to give a good number back based on if we have any free urbs at
+        * this point in time */
+       spin_lock_irqsave(&portdata->lock, flags);
+       if (portdata->outstanding_urbs > N_OUT_URB * 2 / 3) {
+               spin_unlock_irqrestore(&portdata->lock, flags);
+               dbg("%s - write limit hit\n", __FUNCTION__);
+               return 0;
        }
+       spin_unlock_irqrestore(&portdata->lock, flags);
 
-       dbg("%s: %d", __FUNCTION__, data_len);
-       return data_len;
+       return 2048;
 }
 
 static int sierra_chars_in_buffer(struct usb_serial_port *port)
 {
-       struct sierra_port_private *portdata;
-       int i;
-       int data_len = 0;
-       struct urb *this_urb;
-
-       portdata = usb_get_serial_port_data(port);
-
-       for (i=0; i < N_OUT_URB; i++) {
-               this_urb = portdata->out_urbs[i];
-               if (this_urb && this_urb->status == -EINPROGRESS)
-                       data_len += this_urb->transfer_buffer_length;
-       }
-       dbg("%s: %d", __FUNCTION__, data_len);
-       return data_len;
+       dbg("%s - port %d", __FUNCTION__, 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.
+        */
+       return 0;
 }
 
 static int sierra_open(struct usb_serial_port *port, struct file *filp)
 {
        struct sierra_port_private *portdata;
        struct usb_serial *serial = port->serial;
-       int i, err;
+       int i;
        struct urb *urb;
        int result;
        __u16 set_mode_dzero = 0x0000;
@@ -413,7 +434,7 @@ static int sierra_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", __FUNCTION__,
@@ -427,24 +448,13 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp)
                 */
                usb_clear_halt(urb->dev, urb->pipe);
 
-               err = usb_submit_urb(urb, GFP_KERNEL);
-               if (err) {
-                       dbg("%s: submit urb %d failed (%d) %d",
-                               __FUNCTION__, i, err,
-                               urb->transfer_buffer_length);
+               result = usb_submit_urb(urb, GFP_KERNEL);
+               if (result) {
+                       dev_err(&port->dev, "submit urb %d failed (%d) %d",
+                               i, result, urb->transfer_buffer_length);
                }
        }
 
-       /* Reset low level data toggle on out endpoints */
-       for (i = 0; i < N_OUT_URB; i++) {
-               urb = portdata->out_urbs[i];
-               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;
 
        /* set mode to D0 */
@@ -455,7 +465,14 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp)
 
        sierra_send_setup(port);
 
-       return (0);
+       /* start up the interrupt endpoint if we have one */
+       if (port->interrupt_in_urb) {
+               result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
+               if (result)
+                       dev_err(&port->dev, "submit irq_in urb failed %d",
+                               result);
+       }
+       return 0;
 }
 
 static void sierra_close(struct usb_serial_port *port, struct file *filp)
@@ -475,71 +492,21 @@ static void sierra_close(struct usb_serial_port *port, struct file *filp)
 
                /* Stop reading/writing urbs */
                for (i = 0; i < N_IN_URB; i++)
-                       usb_unlink_urb(portdata->in_urbs[i]);
-               for (i = 0; i < N_OUT_URB; i++)
-                       usb_unlink_urb(portdata->out_urbs[i]);
+                       usb_kill_urb(portdata->in_urbs[i]);
        }
-       port->tty = NULL;
-}
-
-/* Helper functions used by sierra_setup_urbs */
-static struct urb *sierra_setup_urb(struct usb_serial *serial, int endpoint,
-                                   int dir, void *ctx, char *buf, int len,
-                                   usb_complete_t callback)
-{
-       struct urb *urb;
-
-       if (endpoint == -1)
-               return NULL;            /* endpoint not needed */
-
-       urb = usb_alloc_urb(0, GFP_KERNEL);             /* No ISO */
-       if (urb == NULL) {
-               dbg("%s: alloc for endpoint %d failed.", __FUNCTION__, endpoint);
-               return NULL;
-       }
-
-               /* Fill URB using supplied data. */
-       usb_fill_bulk_urb(urb, serial->dev,
-                     usb_sndbulkpipe(serial->dev, endpoint) | dir,
-                     buf, len, callback, ctx);
-
-       return urb;
-}
 
-/* Setup urbs */
-static void sierra_setup_urbs(struct usb_serial *serial)
-{
-       int i,j;
-       struct usb_serial_port *port;
-       struct sierra_port_private *portdata;
-
-       dbg("%s", __FUNCTION__);
+       usb_kill_urb(port->interrupt_in_urb);
 
-       for (i = 0; i < serial->num_ports; i++) {
-               port = serial->port[i];
-               portdata = usb_get_serial_port_data(port);
-
-       /* Do indat endpoints first */
-               for (j = 0; j < N_IN_URB; ++j) {
-                       portdata->in_urbs[j] = sierra_setup_urb (serial,
-                       port->bulk_in_endpointAddress, USB_DIR_IN, port,
-                       portdata->in_buffer[j], IN_BUFLEN, sierra_indat_callback);
-               }
-
-               /* outdat endpoints */
-               for (j = 0; j < N_OUT_URB; ++j) {
-                       portdata->out_urbs[j] = sierra_setup_urb (serial,
-                       port->bulk_out_endpointAddress, USB_DIR_OUT, port,
-                       portdata->out_buffer[j], OUT_BUFLEN, sierra_outdat_callback);
-               }
-       }
+       port->tty = NULL;
 }
 
 static int sierra_startup(struct usb_serial *serial)
 {
-       int i, err;
        struct usb_serial_port *port;
        struct sierra_port_private *portdata;
+       struct urb *urb;
+       int i;
+       int j;
 
        dbg("%s", __FUNCTION__);
 
@@ -550,22 +517,31 @@ static int sierra_startup(struct usb_serial *serial)
                if (!portdata) {
                        dbg("%s: kmalloc for sierra_port_private (%d) failed!.",
                                        __FUNCTION__, i);
-                       return (1);
+                       return -ENOMEM;
                }
+               spin_lock_init(&portdata->lock);
 
                usb_set_serial_port_data(port, portdata);
 
-               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",
-                               __FUNCTION__, err);
+               /* initialize the in urbs */
+               for (j = 0; j < N_IN_URB; ++j) {
+                       urb = usb_alloc_urb(0, GFP_KERNEL);
+                       if (urb == NULL) {
+                               dbg("%s: alloc for in port failed.",
+                                   __FUNCTION__);
+                               continue;
+                       }
+                       /* Fill URB using supplied data. */
+                       usb_fill_bulk_urb(urb, serial->dev,
+                                         usb_rcvbulkpipe(serial->dev,
+                                               port->bulk_in_endpointAddress),
+                                         portdata->in_buffer[j], IN_BUFLEN,
+                                         sierra_indat_callback, port);
+                       portdata->in_urbs[j] = urb;
+               }
        }
 
-       sierra_setup_urbs(serial);
-
-       return (0);
+       return 0;
 }
 
 static void sierra_shutdown(struct usb_serial *serial)
@@ -576,22 +552,6 @@ static void sierra_shutdown(struct usb_serial *serial)
 
        dbg("%s", __FUNCTION__);
 
-       /* Stop reading/writing urbs */
-       for (i = 0; i < serial->num_ports; ++i) {
-               port = serial->port[i];
-               if (!port)
-                       continue;
-               portdata = usb_get_serial_port_data(port);
-               if (!portdata)
-                       continue;
-
-               for (j = 0; j < N_IN_URB; j++)
-                       usb_unlink_urb(portdata->in_urbs[j]);
-               for (j = 0; j < N_OUT_URB; j++)
-                       usb_unlink_urb(portdata->out_urbs[j]);
-       }
-
-       /* Now free them */
        for (i = 0; i < serial->num_ports; ++i) {
                port = serial->port[i];
                if (!port)
@@ -601,25 +561,12 @@ static void sierra_shutdown(struct usb_serial *serial)
                        continue;
 
                for (j = 0; j < N_IN_URB; j++) {
-                       if (portdata->in_urbs[j]) {
-                               usb_free_urb(portdata->in_urbs[j]);
-                               portdata->in_urbs[j] = NULL;
-                       }
+                       usb_kill_urb(portdata->in_urbs[j]);
+                       usb_free_urb(portdata->in_urbs[j]);
+                       portdata->in_urbs[j] = NULL;
                }
-               for (j = 0; j < N_OUT_URB; j++) {
-                       if (portdata->out_urbs[j]) {
-                               usb_free_urb(portdata->out_urbs[j]);
-                               portdata->out_urbs[j] = NULL;
-                       }
-               }
-       }
-
-       /* Now free per port private data */
-       for (i = 0; i < serial->num_ports; i++) {
-               port = serial->port[i];
-               if (!port)
-                       continue;
-               kfree(usb_get_serial_port_data(port));
+               kfree(portdata);
+               usb_set_serial_port_data(port, NULL);
        }
 }
 
index 3d505fd0645b04e5740c1f597ef827b57ac68666..f98626ae75fea01a773d379f85b94af4acefea07 100644 (file)
@@ -1112,22 +1112,24 @@ static void ti_interrupt_callback(struct urb *urb)
        int length = urb->actual_length;
        int port_number;
        int function;
-       int status;
+       int status = urb->status;
+       int retval;
        __u8 msr;
 
        dbg("%s", __FUNCTION__);
 
-       switch (urb->status) {
+       switch (status) {
        case 0:
                break;
        case -ECONNRESET:
        case -ENOENT:
        case -ESHUTDOWN:
-               dbg("%s - urb shutting down, %d", __FUNCTION__, urb->status);
+               dbg("%s - urb shutting down, %d", __FUNCTION__, status);
                tdev->td_urb_error = 1;
                return;
        default:
-               dev_err(dev, "%s - nonzero urb status, %d\n", __FUNCTION__, urb->status);
+               dev_err(dev, "%s - nonzero urb status, %d\n",
+                       __FUNCTION__, status);
                tdev->td_urb_error = 1;
                goto exit;
        }
@@ -1175,9 +1177,10 @@ static void ti_interrupt_callback(struct urb *urb)
        }
 
 exit:
-       status = usb_submit_urb(urb, GFP_ATOMIC);
-       if (status)
-               dev_err(dev, "%s - resubmit interrupt urb failed, %d\n", __FUNCTION__, status);
+       retval = usb_submit_urb(urb, GFP_ATOMIC);
+       if (retval)
+               dev_err(dev, "%s - resubmit interrupt urb failed, %d\n",
+                       __FUNCTION__, retval);
 }
 
 
@@ -1186,30 +1189,32 @@ static void ti_bulk_in_callback(struct urb *urb)
        struct ti_port *tport = (struct ti_port *)urb->context;
        struct usb_serial_port *port = tport->tp_port;
        struct device *dev = &urb->dev->dev;
-       int status = 0;
+       int status = urb->status;
+       int retval = 0;
 
        dbg("%s", __FUNCTION__);
 
-       switch (urb->status) {
+       switch (status) {
        case 0:
                break;
        case -ECONNRESET:
        case -ENOENT:
        case -ESHUTDOWN:
-               dbg("%s - urb shutting down, %d", __FUNCTION__, urb->status);
+               dbg("%s - urb shutting down, %d", __FUNCTION__, status);
                tport->tp_tdev->td_urb_error = 1;
                wake_up_interruptible(&tport->tp_write_wait);
                return;
        default:
-               dev_err(dev, "%s - nonzero urb status, %d\n", __FUNCTION__, urb->status );
+               dev_err(dev, "%s - nonzero urb status, %d\n",
+                       __FUNCTION__, status );
                tport->tp_tdev->td_urb_error = 1;
                wake_up_interruptible(&tport->tp_write_wait);
        }
 
-       if (urb->status == -EPIPE)
+       if (status == -EPIPE)
                goto exit;
 
-       if (urb->status) {
+       if (status) {
                dev_err(dev, "%s - stopping read!\n", __FUNCTION__);
                return;
        }
@@ -1234,13 +1239,14 @@ exit:
        spin_lock(&tport->tp_lock);
        if (tport->tp_read_urb_state == TI_READ_URB_RUNNING) {
                urb->dev = port->serial->dev;
-               status = usb_submit_urb(urb, GFP_ATOMIC);
+               retval = usb_submit_urb(urb, GFP_ATOMIC);
        } else if (tport->tp_read_urb_state == TI_READ_URB_STOPPING) {
                tport->tp_read_urb_state = TI_READ_URB_STOPPED;
        }
        spin_unlock(&tport->tp_lock);
-       if (status)
-               dev_err(dev, "%s - resubmit read urb failed, %d\n", __FUNCTION__, status);
+       if (retval)
+               dev_err(dev, "%s - resubmit read urb failed, %d\n",
+                       __FUNCTION__, retval);
 }
 
 
@@ -1249,23 +1255,25 @@ static void ti_bulk_out_callback(struct urb *urb)
        struct ti_port *tport = (struct ti_port *)urb->context;
        struct usb_serial_port *port = tport->tp_port;
        struct device *dev = &urb->dev->dev;
+       int status = urb->status;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
        tport->tp_write_urb_in_use = 0;
 
-       switch (urb->status) {
+       switch (status) {
        case 0:
                break;
        case -ECONNRESET:
        case -ENOENT:
        case -ESHUTDOWN:
-               dbg("%s - urb shutting down, %d", __FUNCTION__, urb->status);
+               dbg("%s - urb shutting down, %d", __FUNCTION__, status);
                tport->tp_tdev->td_urb_error = 1;
                wake_up_interruptible(&tport->tp_write_wait);
                return;
        default:
-               dev_err(dev, "%s - nonzero urb status, %d\n", __FUNCTION__, urb->status);
+               dev_err(dev, "%s - nonzero urb status, %d\n",
+                       __FUNCTION__, status);
                tport->tp_tdev->td_urb_error = 1;
                wake_up_interruptible(&tport->tp_write_wait);
        }
index 87f378806db645d5d7897e0f56ecb7ceb885e092..a3665659d13b32636914368429c0be0d6998e35d 100644 (file)
@@ -46,6 +46,8 @@ static struct usb_driver usb_serial_driver = {
        .name =         "usbserial",
        .probe =        usb_serial_probe,
        .disconnect =   usb_serial_disconnect,
+       .suspend =      usb_serial_suspend,
+       .resume =       usb_serial_resume,
        .no_dynamic_id =        1,
 };
 
@@ -120,11 +122,9 @@ static void return_serial(struct usb_serial *serial)
        if (serial == NULL)
                return;
 
-       spin_lock(&table_lock);
        for (i = 0; i < serial->num_ports; ++i) {
                serial_table[serial->minor + i] = NULL;
        }
-       spin_unlock(&table_lock);
 }
 
 static void destroy_serial(struct kref *kref)
@@ -172,7 +172,9 @@ static void destroy_serial(struct kref *kref)
 
 void usb_serial_put(struct usb_serial *serial)
 {
+       spin_lock(&table_lock);
        kref_put(&serial->kref, destroy_serial);
+       spin_unlock(&table_lock);
 }
 
 /*****************************************************************************
@@ -1069,6 +1071,35 @@ void usb_serial_disconnect(struct usb_interface *interface)
        dev_info(dev, "device disconnected\n");
 }
 
+int usb_serial_suspend(struct usb_interface *intf, pm_message_t message)
+{
+       struct usb_serial *serial = usb_get_intfdata(intf);
+       struct usb_serial_port *port;
+       int i, r = 0;
+
+       if (serial) {
+               for (i = 0; i < serial->num_ports; ++i) {
+                       port = serial->port[i];
+                       if (port)
+                               kill_traffic(port);
+               }
+       }
+
+       if (serial->type->suspend)
+               serial->type->suspend(serial, message);
+
+       return r;
+}
+EXPORT_SYMBOL(usb_serial_suspend);
+
+int usb_serial_resume(struct usb_interface *intf)
+{
+       struct usb_serial *serial = usb_get_intfdata(intf);
+
+       return serial->type->resume(serial);
+}
+EXPORT_SYMBOL(usb_serial_resume);
+
 static const struct tty_operations serial_ops = {
        .open =                 serial_open,
        .close =                serial_close,
index ffbe601cde2a563d34f3921eaee2934b92c56f53..7d84a7647e81efeec0c025df2ecf783ade3b16aa 100644 (file)
@@ -5,9 +5,9 @@
  *     Copyright (C) 1999 - 2004
  *         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.
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License version
+ *     2 as published by the Free Software Foundation.
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  *
@@ -273,7 +273,8 @@ struct visor_private {
        int bytes_in;
        int bytes_out;
        int outstanding_urbs;
-       int throttled;
+       unsigned char throttled;
+       unsigned char actually_throttled;
 };
 
 /* number of outstanding urbs to prevent userspace DoS from happening */
@@ -484,16 +485,17 @@ static void visor_write_bulk_callback (struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        struct visor_private *priv = usb_get_serial_port_data(port);
+       int status = urb->status;
        unsigned long flags;
 
        /* free up the transfer buffer, as usb_free_urb() does not do this */
        kfree (urb->transfer_buffer);
 
        dbg("%s - port %d", __FUNCTION__, port->number);
-       
-       if (urb->status)
+
+       if (status)
                dbg("%s - nonzero write bulk status received: %d",
-                   __FUNCTION__, urb->status);
+                   __FUNCTION__, status);
 
        spin_lock_irqsave(&priv->lock, flags);
        --priv->outstanding_urbs;
@@ -508,15 +510,16 @@ static void visor_read_bulk_callback (struct urb *urb)
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        struct visor_private *priv = usb_get_serial_port_data(port);
        unsigned char *data = urb->transfer_buffer;
+       int status = urb->status;
        struct tty_struct *tty;
-       unsigned long flags;
-       int throttled;
        int result;
+       int available_room;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
-       if (urb->status) {
-               dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status);
+       if (status) {
+               dbg("%s - nonzero read bulk status received: %d",
+                   __FUNCTION__, status);
                return;
        }
 
@@ -524,17 +527,20 @@ static void visor_read_bulk_callback (struct urb *urb)
 
        tty = port->tty;
        if (tty && urb->actual_length) {
-               tty_buffer_request_room(tty, urb->actual_length);
-               tty_insert_flip_string(tty, data, urb->actual_length);
-               tty_flip_buffer_push(tty);
+               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);
+               }
+               spin_lock(&priv->lock);
+               priv->bytes_in += available_room;
+
+       } else {
+               spin_lock(&priv->lock);
        }
-       spin_lock_irqsave(&priv->lock, flags);
-       priv->bytes_in += urb->actual_length;
-       throttled = priv->throttled;
-       spin_unlock_irqrestore(&priv->lock, flags);
 
        /* Continue trying to always read if we should */
-       if (!throttled) {
+       if (!priv->throttled) {
                usb_fill_bulk_urb (port->read_urb, port->serial->dev,
                                   usb_rcvbulkpipe(port->serial->dev,
                                                   port->bulk_in_endpointAddress),
@@ -544,16 +550,19 @@ static void visor_read_bulk_callback (struct urb *urb)
                result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
                if (result)
                        dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result);
+       } else {
+               priv->actually_throttled = 1;
        }
-       return;
+       spin_unlock(&priv->lock);
 }
 
 static void visor_read_int_callback (struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+       int status = urb->status;
        int result;
 
-       switch (urb->status) {
+       switch (status) {
        case 0:
                /* success */
                break;
@@ -562,11 +571,11 @@ static void visor_read_int_callback (struct urb *urb)
        case -ESHUTDOWN:
                /* this urb is terminated, clean up */
                dbg("%s - urb shutting down with status: %d",
-                   __FUNCTION__, urb->status);
+                   __FUNCTION__, status);
                return;
        default:
                dbg("%s - nonzero urb status received: %d",
-                   __FUNCTION__, urb->status);
+                   __FUNCTION__, status);
                goto exit;
        }
 
@@ -608,6 +617,7 @@ static void visor_unthrottle (struct usb_serial_port *port)
        dbg("%s - port %d", __FUNCTION__, port->number);
        spin_lock_irqsave(&priv->lock, flags);
        priv->throttled = 0;
+       priv->actually_throttled = 0;
        spin_unlock_irqrestore(&priv->lock, flags);
 
        port->read_urb->dev = port->serial->dev;
@@ -938,14 +948,6 @@ static void visor_set_termios (struct usb_serial_port *port, struct ktermios *ol
        }
 
        cflag = port->tty->termios->c_cflag;
-       /* check that they really want us to change something */
-       if (old_termios) {
-               if ((cflag == old_termios->c_cflag) &&
-                   (RELEVANT_IFLAG(port->tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) {
-                       dbg("%s - nothing to change...", __FUNCTION__);
-                       return;
-               }
-       }
 
        /* get the byte size */
        switch (cflag & CSIZE) {
index 27c5f8f9a2d5e9907f49e094826167eb8c5ddd6d..cc8b44c08712c67c1c41448c18b17ff23950228a 100644 (file)
@@ -74,6 +74,7 @@
 #include <linux/tty_flip.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
+#include <linux/mutex.h>
 #include <asm/uaccess.h>
 #include <asm/termbits.h>
 #include <linux/usb.h>
@@ -203,7 +204,7 @@ static struct usb_serial_driver whiteheat_device = {
 
 
 struct whiteheat_command_private {
-       spinlock_t              lock;
+       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 */
@@ -232,6 +233,7 @@ struct whiteheat_private {
        struct usb_serial_port  *port;
        struct list_head        tx_urbs_free;
        struct list_head        tx_urbs_submitted;
+       struct mutex            deathwarrant;
 };
 
 
@@ -425,6 +427,7 @@ static int whiteheat_attach (struct usb_serial *serial)
                }
 
                spin_lock_init(&info->lock);
+               mutex_init(&info->deathwarrant);
                info->flags = 0;
                info->mcr = 0;
                INIT_WORK(&info->rx_work, rx_data_softint);
@@ -495,7 +498,7 @@ static int whiteheat_attach (struct usb_serial *serial)
                goto no_command_private;
        }
 
-       spin_lock_init(&command_info->lock);
+       mutex_init(&command_info->mutex);
        command_info->port_running = 0;
        init_waitqueue_head(&command_info->wait_command);
        usb_set_serial_port_data(command_port, command_info);
@@ -654,7 +657,6 @@ static void whiteheat_close(struct usb_serial_port *port, struct file * filp)
        struct urb *urb;
        struct list_head *tmp;
        struct list_head *tmp2;
-       unsigned long flags;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
        
@@ -683,24 +685,32 @@ static void whiteheat_close(struct usb_serial_port *port, struct file * filp)
 
        firm_close(port);
 
+printk(KERN_ERR"Before processing rx_urbs_submitted.\n");
        /* shutdown our bulk reads and writes */
-       spin_lock_irqsave(&info->lock, flags);
+       mutex_lock(&info->deathwarrant);
+       spin_lock_irq(&info->lock);
        list_for_each_safe(tmp, tmp2, &info->rx_urbs_submitted) {
                wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
                urb = wrap->urb;
+               list_del(tmp);
+               spin_unlock_irq(&info->lock);
                usb_kill_urb(urb);
-               list_move(tmp, &info->rx_urbs_free);
+               spin_lock_irq(&info->lock);
+               list_add(tmp, &info->rx_urbs_free);
        }
        list_for_each_safe(tmp, tmp2, &info->rx_urb_q)
                list_move(tmp, &info->rx_urbs_free);
-
        list_for_each_safe(tmp, tmp2, &info->tx_urbs_submitted) {
                wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
                urb = wrap->urb;
+               list_del(tmp);
+               spin_unlock_irq(&info->lock);
                usb_kill_urb(urb);
-               list_move(tmp, &info->tx_urbs_free);
+               spin_lock_irq(&info->lock);
+               list_add(tmp, &info->tx_urbs_free);
        }
-       spin_unlock_irqrestore(&info->lock, flags);
+       spin_unlock_irq(&info->lock);
+       mutex_unlock(&info->deathwarrant);
 
        stop_command_port(port->serial);
 
@@ -872,7 +882,7 @@ static int whiteheat_ioctl (struct usb_serial_port *port, struct file * file, un
 }
 
 
-static void whiteheat_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
+static void whiteheat_set_termios(struct usb_serial_port *port, struct ktermios *old_termios)
 {
        dbg("%s -port %d", __FUNCTION__, port->number);
 
@@ -881,15 +891,6 @@ static void whiteheat_set_termios (struct usb_serial_port *port, struct ktermios
                goto exit;
        }
        
-       /* check that they really want us to change something */
-       if (old_termios) {
-               if ((port->tty->termios->c_cflag == old_termios->c_cflag) &&
-                   (port->tty->termios->c_iflag == old_termios->c_iflag)) {
-                       dbg("%s - nothing to change...", __FUNCTION__);
-                       goto exit;
-               }
-       }
-
        firm_setup_port(port);
 
 exit:
@@ -920,7 +921,7 @@ static int whiteheat_chars_in_buffer(struct usb_serial_port *port)
        spin_unlock_irqrestore(&info->lock, flags);
 
        dbg ("%s - returns %d", __FUNCTION__, chars);
-       return (chars);
+       return chars;
 }
 
 
@@ -962,54 +963,57 @@ static void whiteheat_unthrottle (struct usb_serial_port *port)
 /*****************************************************************************
  * Connect Tech's White Heat callback routines
  *****************************************************************************/
-static void command_port_write_callback (struct urb *urb)
+static void command_port_write_callback(struct urb *urb)
 {
+       int status = urb->status;
+
        dbg("%s", __FUNCTION__);
 
-       if (urb->status) {
-               dbg ("nonzero urb status: %d", urb->status);
+       if (status) {
+               dbg("nonzero urb status: %d", status);
                return;
        }
 }
 
 
-static void command_port_read_callback (struct urb *urb)
+static void command_port_read_callback(struct urb *urb)
 {
        struct usb_serial_port *command_port = (struct usb_serial_port *)urb->context;
        struct whiteheat_command_private *command_info;
+       int status = urb->status;
        unsigned char *data = urb->transfer_buffer;
        int result;
-       unsigned long flags;
 
        dbg("%s", __FUNCTION__);
 
-       if (urb->status) {
-               dbg("%s - nonzero urb status: %d", __FUNCTION__, urb->status);
-               return;
-       }
-
-       usb_serial_debug_data(debug, &command_port->dev, __FUNCTION__, urb->actual_length, data);
-
        command_info = usb_get_serial_port_data(command_port);
        if (!command_info) {
                dbg ("%s - command_info is NULL, exiting.", __FUNCTION__);
                return;
        }
-       spin_lock_irqsave(&command_info->lock, flags);
+       if (status) {
+               dbg("%s - nonzero urb status: %d", __FUNCTION__, status);
+               if (status != -ENOENT)
+                       command_info->command_finished = WHITEHEAT_CMD_FAILURE;
+               wake_up(&command_info->wait_command);
+               return;
+       }
+
+       usb_serial_debug_data(debug, &command_port->dev, __FUNCTION__, urb->actual_length, data);
 
        if (data[0] == WHITEHEAT_CMD_COMPLETE) {
                command_info->command_finished = WHITEHEAT_CMD_COMPLETE;
-               wake_up_interruptible(&command_info->wait_command);
+               wake_up(&command_info->wait_command);
        } else if (data[0] == WHITEHEAT_CMD_FAILURE) {
                command_info->command_finished = WHITEHEAT_CMD_FAILURE;
-               wake_up_interruptible(&command_info->wait_command);
+               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 */
                dbg("%s - event received", __FUNCTION__);
        } else if (data[0] == WHITEHEAT_GET_DTR_RTS) {
                memcpy(command_info->result_buffer, &data[1], urb->actual_length - 1);
                command_info->command_finished = WHITEHEAT_CMD_COMPLETE;
-               wake_up_interruptible(&command_info->wait_command);
+               wake_up(&command_info->wait_command);
        } else {
                dbg("%s - bad reply from firmware", __FUNCTION__);
        }
@@ -1017,7 +1021,6 @@ static void command_port_read_callback (struct urb *urb)
        /* Continue trying to always read */
        command_port->read_urb->dev = command_port->serial->dev;
        result = usb_submit_urb(command_port->read_urb, GFP_ATOMIC);
-       spin_unlock_irqrestore(&command_info->lock, flags);
        if (result)
                dbg("%s - failed resubmitting read urb, error %d", __FUNCTION__, result);
 }
@@ -1029,6 +1032,7 @@ static void whiteheat_read_callback(struct urb *urb)
        struct whiteheat_urb_wrap *wrap;
        unsigned char *data = urb->transfer_buffer;
        struct whiteheat_private *info = usb_get_serial_port_data(port);
+       int status = urb->status;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
@@ -1042,8 +1046,9 @@ static void whiteheat_read_callback(struct urb *urb)
        list_del(&wrap->list);
        spin_unlock(&info->lock);
 
-       if (urb->status) {
-               dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status);
+       if (status) {
+               dbg("%s - nonzero read bulk status received: %d",
+                   __FUNCTION__, status);
                spin_lock(&info->lock);
                list_add(&wrap->list, &info->rx_urbs_free);
                spin_unlock(&info->lock);
@@ -1070,6 +1075,7 @@ static void whiteheat_write_callback(struct urb *urb)
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        struct whiteheat_private *info = usb_get_serial_port_data(port);
        struct whiteheat_urb_wrap *wrap;
+       int status = urb->status;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
@@ -1083,8 +1089,9 @@ static void whiteheat_write_callback(struct urb *urb)
        list_move(&wrap->list, &info->tx_urbs_free);
        spin_unlock(&info->lock);
 
-       if (urb->status) {
-               dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
+       if (status) {
+               dbg("%s - nonzero write bulk status received: %d",
+                   __FUNCTION__, status);
                return;
        }
 
@@ -1095,20 +1102,20 @@ 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;
        struct whiteheat_private *info;
        __u8 *transfer_buffer;
        int retval = 0;
-       unsigned long flags;
+       int t;
 
        dbg("%s - command %d", __FUNCTION__, command);
 
        command_port = port->serial->port[COMMAND_PORT];
        command_info = usb_get_serial_port_data(command_port);
-       spin_lock_irqsave(&command_info->lock, flags);
+       mutex_lock(&command_info->mutex);
        command_info->command_finished = false;
        
        transfer_buffer = (__u8 *)command_port->write_urb->transfer_buffer;
@@ -1116,18 +1123,17 @@ static int firm_send_command (struct usb_serial_port *port, __u8 command, __u8 *
        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_KERNEL);
+       retval = usb_submit_urb (command_port->write_urb, GFP_NOIO);
        if (retval) {
                dbg("%s - submit urb failed", __FUNCTION__);
                goto exit;
        }
-       spin_unlock_irqrestore(&command_info->lock, flags);
 
        /* wait for the command to complete */
-       wait_event_interruptible_timeout(command_info->wait_command,
+       t = wait_event_timeout(command_info->wait_command,
                (bool)command_info->command_finished, COMMAND_TIMEOUT);
-
-       spin_lock_irqsave(&command_info->lock, flags);
+       if (!t)
+               usb_kill_urb(command_port->write_urb);
 
        if (command_info->command_finished == false) {
                dbg("%s - command timed out.", __FUNCTION__);
@@ -1152,7 +1158,7 @@ static int firm_send_command (struct usb_serial_port *port, __u8 command, __u8 *
        }
 
 exit:
-       spin_unlock_irqrestore(&command_info->lock, flags);
+       mutex_unlock(&command_info->mutex);
        return retval;
 }
 
@@ -1305,12 +1311,11 @@ static int start_command_port(struct usb_serial *serial)
 {
        struct usb_serial_port *command_port;
        struct whiteheat_command_private *command_info;
-       unsigned long flags;
        int retval = 0;
        
        command_port = serial->port[COMMAND_PORT];
        command_info = usb_get_serial_port_data(command_port);
-       spin_lock_irqsave(&command_info->lock, flags);
+       mutex_lock(&command_info->mutex);
        if (!command_info->port_running) {
                /* Work around HCD bugs */
                usb_clear_halt(serial->dev, command_port->read_urb->pipe);
@@ -1325,7 +1330,7 @@ static int start_command_port(struct usb_serial *serial)
        command_info->port_running++;
 
 exit:
-       spin_unlock_irqrestore(&command_info->lock, flags);
+       mutex_unlock(&command_info->mutex);
        return retval;
 }
 
@@ -1334,15 +1339,14 @@ static void stop_command_port(struct usb_serial *serial)
 {
        struct usb_serial_port *command_port;
        struct whiteheat_command_private *command_info;
-       unsigned long flags;
 
        command_port = serial->port[COMMAND_PORT];
        command_info = usb_get_serial_port_data(command_port);
-       spin_lock_irqsave(&command_info->lock, flags);
+       mutex_lock(&command_info->mutex);
        command_info->port_running--;
        if (!command_info->port_running)
                usb_kill_urb(command_port->read_urb);
-       spin_unlock_irqrestore(&command_info->lock, flags);
+       mutex_unlock(&command_info->mutex);
 }
 
 
@@ -1363,17 +1367,23 @@ static int start_port_read(struct usb_serial_port *port)
                wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
                urb = wrap->urb;
                urb->dev = port->serial->dev;
+               spin_unlock_irqrestore(&info->lock, flags);
                retval = usb_submit_urb(urb, GFP_KERNEL);
                if (retval) {
+                       spin_lock_irqsave(&info->lock, flags);
                        list_add(tmp, &info->rx_urbs_free);
                        list_for_each_safe(tmp, tmp2, &info->rx_urbs_submitted) {
                                wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
                                urb = wrap->urb;
+                               list_del(tmp);
+                               spin_unlock_irqrestore(&info->lock, flags);
                                usb_kill_urb(urb);
-                               list_move(tmp, &info->rx_urbs_free);
+                               spin_lock_irqsave(&info->lock, flags);
+                               list_add(tmp, &info->rx_urbs_free);
                        }
                        break;
                }
+               spin_lock_irqsave(&info->lock, flags);
                list_add(tmp, &info->rx_urbs_submitted);
        }
 
index e227f64d5641be64dc009c34da147be8c0a61a69..47e56079925dfbf8d222024c9cca704ce9ff21e2 100644 (file)
@@ -285,10 +285,15 @@ static int device_reset(struct scsi_cmnd *srb)
 
        US_DEBUGP("%s called\n", __FUNCTION__);
 
-       /* lock the device pointers and do the reset */
-       mutex_lock(&(us->dev_mutex));
-       result = us->transport_reset(us);
-       mutex_unlock(&us->dev_mutex);
+       result = usb_autopm_get_interface(us->pusb_intf);
+       if (result == 0) {
+
+               /* lock the device pointers and do the reset */
+               mutex_lock(&(us->dev_mutex));
+               result = us->transport_reset(us);
+               mutex_unlock(&us->dev_mutex);
+               usb_autopm_put_interface(us->pusb_intf);
+       }
 
        return result < 0 ? FAILED : SUCCESS;
 }
@@ -321,10 +326,14 @@ void usb_stor_report_device_reset(struct us_data *us)
 
 /* Report a driver-initiated bus reset to the SCSI layer.
  * Calling this for a SCSI-initiated reset is unnecessary but harmless.
- * The caller must own the SCSI host lock. */
+ * The caller must not own the SCSI host lock. */
 void usb_stor_report_bus_reset(struct us_data *us)
 {
-       scsi_report_bus_reset(us_to_host(us), 0);
+       struct Scsi_Host *host = us_to_host(us);
+
+       scsi_lock(host);
+       scsi_report_bus_reset(host, 0);
+       scsi_unlock(host);
 }
 
 /***********************************************************************
index 54979c239c6329d7382176e7996a5384c371b160..b6bf31a97b60d46bff07725cc7eec98b1a5e7c65 100644 (file)
 /* patch submitted by Vivian Bregier <Vivian.Bregier@imag.fr>
  */
 UNUSUAL_DEV(  0x03eb, 0x2002, 0x0100, 0x0100,
-                "ATMEL",
-                "SND1 Storage",
-                US_SC_DEVICE, US_PR_DEVICE, NULL,
-                US_FL_IGNORE_RESIDUE),
+               "ATMEL",
+               "SND1 Storage",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_IGNORE_RESIDUE),
 
 /* modified by Tobias Lorenz <tobias.lorenz@gmx.net> */
 UNUSUAL_DEV(  0x03ee, 0x6901, 0x0000, 0x0200,
@@ -69,18 +69,18 @@ UNUSUAL_DEV(  0x03ee, 0x6906, 0x0003, 0x0003,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_IGNORE_RESIDUE ),
 
-UNUSUAL_DEV(  0x03f0, 0x0107, 0x0200, 0x0200, 
+UNUSUAL_DEV(  0x03f0, 0x0107, 0x0200, 0x0200,
                "HP",
                "CD-Writer+",
-               US_SC_8070, US_PR_CB, NULL, 0), 
+               US_SC_8070, US_PR_CB, NULL, 0),
 
 #ifdef CONFIG_USB_STORAGE_USBAT
-UNUSUAL_DEV(  0x03f0, 0x0207, 0x0001, 0x0001, 
+UNUSUAL_DEV(  0x03f0, 0x0207, 0x0001, 0x0001,
                "HP",
                "CD-Writer+ 8200e",
                US_SC_8070, US_PR_USBAT, init_usbat_cd, 0),
 
-UNUSUAL_DEV(  0x03f0, 0x0307, 0x0001, 0x0001, 
+UNUSUAL_DEV(  0x03f0, 0x0307, 0x0001, 0x0001,
                "HP",
                "CD-Writer+ CD-4e",
                US_SC_8070, US_PR_USBAT, init_usbat_cd, 0),
@@ -115,10 +115,10 @@ UNUSUAL_DEV(  0x0411, 0x001c, 0x0113, 0x0113,
 
 /* Submitted by Ernestas Vaiciukevicius <ernisv@gmail.com> */
 UNUSUAL_DEV(  0x0419, 0x0100, 0x0100, 0x0100,
-                "Samsung Info. Systems America, Inc.",
-                "MP3 Player",
-                US_SC_DEVICE, US_PR_DEVICE, NULL,
-                US_FL_IGNORE_RESIDUE ),
+               "Samsung Info. Systems America, Inc.",
+               "MP3 Player",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_IGNORE_RESIDUE ),
 
 /* Reported by Orgad Shaneh <orgads@gmail.com> */
 UNUSUAL_DEV(  0x0419, 0xaace, 0x0100, 0x0100,
@@ -256,10 +256,10 @@ UNUSUAL_DEV(  0x0457, 0x0150, 0x0100, 0x0100,
 * the revision to my model only
 */
 UNUSUAL_DEV(  0x0457, 0x0151, 0x0100, 0x0100,
-                "USB 2.0",
-                "Flash Disk",
-                US_SC_DEVICE, US_PR_DEVICE, NULL,
-                US_FL_NOT_LOCKABLE ),
+               "USB 2.0",
+               "Flash Disk",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_NOT_LOCKABLE ),
 
 #ifdef CONFIG_USB_STORAGE_KARMA
 UNUSUAL_DEV(  0x045a, 0x5210, 0x0101, 0x0101,
@@ -408,19 +408,19 @@ UNUSUAL_DEV(  0x04da, 0x2373, 0x0000, 0x9999,
 /* Most of the following entries were developed with the help of
  * Shuttle/SCM directly.
  */
-UNUSUAL_DEV(  0x04e6, 0x0001, 0x0200, 0x0200, 
+UNUSUAL_DEV(  0x04e6, 0x0001, 0x0200, 0x0200,
                "Matshita",
                "LS-120",
                US_SC_8020, US_PR_CB, NULL, 0),
 
-UNUSUAL_DEV(  0x04e6, 0x0002, 0x0100, 0x0100, 
+UNUSUAL_DEV(  0x04e6, 0x0002, 0x0100, 0x0100,
                "Shuttle",
                "eUSCSI Bridge",
                US_SC_DEVICE, US_PR_DEVICE, usb_stor_euscsi_init, 
-               US_FL_SCM_MULT_TARG ), 
+               US_FL_SCM_MULT_TARG ),
 
 #ifdef CONFIG_USB_STORAGE_SDDR09
-UNUSUAL_DEV(  0x04e6, 0x0003, 0x0000, 0x9999, 
+UNUSUAL_DEV(  0x04e6, 0x0003, 0x0000, 0x9999,
                "Sandisk",
                "ImageMate SDDR09",
                US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init,
@@ -431,52 +431,52 @@ UNUSUAL_DEV(  0x04e6, 0x0005, 0x0100, 0x0208,
                "SCM Microsystems",
                "eUSB SmartMedia / CompactFlash Adapter",
                US_SC_SCSI, US_PR_DPCM_USB, usb_stor_sddr09_dpcm_init,
-               0), 
+               0),
 #endif
 
 /* Reported by Markus Demleitner <msdemlei@cl.uni-heidelberg.de> */
-UNUSUAL_DEV(  0x04e6, 0x0006, 0x0100, 0x0100, 
+UNUSUAL_DEV(  0x04e6, 0x0006, 0x0100, 0x0100,
                "SCM Microsystems Inc.",
                "eUSB MMC Adapter",
-               US_SC_SCSI, US_PR_CB, NULL, 
-               US_FL_SINGLE_LUN), 
+               US_SC_SCSI, US_PR_CB, NULL,
+               US_FL_SINGLE_LUN),
 
 /* Reported by Daniel Nouri <dpunktnpunkt@web.de> */
-UNUSUAL_DEV(  0x04e6, 0x0006, 0x0205, 0x0205, 
+UNUSUAL_DEV(  0x04e6, 0x0006, 0x0205, 0x0205,
                "Shuttle",
                "eUSB MMC Adapter",
-               US_SC_SCSI, US_PR_DEVICE, NULL, 
-               US_FL_SINGLE_LUN), 
+               US_SC_SCSI, US_PR_DEVICE, NULL,
+               US_FL_SINGLE_LUN),
 
-UNUSUAL_DEV(  0x04e6, 0x0007, 0x0100, 0x0200, 
+UNUSUAL_DEV(  0x04e6, 0x0007, 0x0100, 0x0200,
                "Sony",
                "Hifd",
-               US_SC_SCSI, US_PR_CB, NULL, 
-               US_FL_SINGLE_LUN), 
+               US_SC_SCSI, US_PR_CB, NULL,
+               US_FL_SINGLE_LUN),
 
-UNUSUAL_DEV(  0x04e6, 0x0009, 0x0200, 0x0200, 
+UNUSUAL_DEV(  0x04e6, 0x0009, 0x0200, 0x0200,
                "Shuttle",
                "eUSB ATA/ATAPI Adapter",
                US_SC_8020, US_PR_CB, NULL, 0),
 
-UNUSUAL_DEV(  0x04e6, 0x000a, 0x0200, 0x0200, 
+UNUSUAL_DEV(  0x04e6, 0x000a, 0x0200, 0x0200,
                "Shuttle",
                "eUSB CompactFlash Adapter",
                US_SC_8020, US_PR_CB, NULL, 0),
 
-UNUSUAL_DEV(  0x04e6, 0x000B, 0x0100, 0x0100, 
+UNUSUAL_DEV(  0x04e6, 0x000B, 0x0100, 0x0100,
                "Shuttle",
                "eUSCSI Bridge",
-               US_SC_SCSI, US_PR_BULK, usb_stor_euscsi_init, 
+               US_SC_SCSI, US_PR_BULK, usb_stor_euscsi_init,
                US_FL_SCM_MULT_TARG ), 
 
-UNUSUAL_DEV(  0x04e6, 0x000C, 0x0100, 0x0100, 
+UNUSUAL_DEV(  0x04e6, 0x000C, 0x0100, 0x0100,
                "Shuttle",
                "eUSCSI Bridge",
-               US_SC_SCSI, US_PR_BULK, usb_stor_euscsi_init, 
-               US_FL_SCM_MULT_TARG ), 
+               US_SC_SCSI, US_PR_BULK, usb_stor_euscsi_init,
+               US_FL_SCM_MULT_TARG ),
 
-UNUSUAL_DEV(  0x04e6, 0x0101, 0x0200, 0x0200, 
+UNUSUAL_DEV(  0x04e6, 0x0101, 0x0200, 0x0200,
                "Shuttle",
                "CD-RW Device",
                US_SC_8020, US_PR_CB, NULL, 0),
@@ -556,9 +556,9 @@ UNUSUAL_DEV(  0x052b, 0x1911, 0x0100, 0x0100,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_IGNORE_RESIDUE ),
 
-UNUSUAL_DEV(  0x054c, 0x0010, 0x0106, 0x0450, 
+UNUSUAL_DEV(  0x054c, 0x0010, 0x0106, 0x0450,
                "Sony",
-               "DSC-S30/S70/S75/505V/F505/F707/F717/P8", 
+               "DSC-S30/S70/S75/505V/F505/F707/F717/P8",
                US_SC_SCSI, US_PR_DEVICE, NULL,
                US_FL_SINGLE_LUN | US_FL_NOT_LOCKABLE | US_FL_NO_WP_DETECT ),
 
@@ -572,7 +572,7 @@ UNUSUAL_DEV(  0x054c, 0x0010, 0x0500, 0x0610,
 
 
 /* Reported by wim@geeks.nl */
-UNUSUAL_DEV(  0x054c, 0x0025, 0x0100, 0x0100, 
+UNUSUAL_DEV(  0x054c, 0x0025, 0x0100, 0x0100,
                "Sony",
                "Memorystick NW-MS7",
                US_SC_DEVICE, US_PR_DEVICE, NULL,
@@ -593,21 +593,21 @@ UNUSUAL_DEV(  0x054c, 0x002c, 0x0501, 0x2000,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_SINGLE_LUN ),
 
-UNUSUAL_DEV(  0x054c, 0x002d, 0x0100, 0x0100, 
+UNUSUAL_DEV(  0x054c, 0x002d, 0x0100, 0x0100,
                "Sony",
                "Memorystick MSAC-US1",
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_SINGLE_LUN ),
 
 /* Submitted by Klaus Mueller <k.mueller@intershop.de> */
-UNUSUAL_DEV(  0x054c, 0x002e, 0x0106, 0x0310, 
+UNUSUAL_DEV(  0x054c, 0x002e, 0x0106, 0x0310,
                "Sony",
                "Handycam",
                US_SC_SCSI, US_PR_DEVICE, NULL,
                US_FL_SINGLE_LUN ),
 
 /* Submitted by Rajesh Kumble Nayak <nayak@obs-nice.fr> */
-UNUSUAL_DEV(  0x054c, 0x002e, 0x0500, 0x0500, 
+UNUSUAL_DEV(  0x054c, 0x002e, 0x0500, 0x0500,
                "Sony",
                "Handycam HC-85",
                US_SC_UFI, US_PR_DEVICE, NULL,
@@ -648,26 +648,26 @@ UNUSUAL_DEV(  0x054c, 0x016a, 0x0000, 0x9999,
                
 /* Submitted by Frank Engel <frankie@cse.unsw.edu.au> */
 UNUSUAL_DEV(  0x054c, 0x0099, 0x0000, 0x9999,
-                "Sony",
-                "PEG Mass Storage",
-                US_SC_DEVICE, US_PR_DEVICE, NULL,
-                US_FL_FIX_INQUIRY ),
+               "Sony",
+               "PEG Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_FIX_INQUIRY ),
 
 /* floppy reports multiple luns */
 UNUSUAL_DEV(  0x055d, 0x2020, 0x0000, 0x0210,
-               "SAMSUNG",
-               "SFD-321U [FW 0C]",
-               US_SC_DEVICE, US_PR_DEVICE, NULL,
-               US_FL_SINGLE_LUN ),
+               "SAMSUNG",
+               "SFD-321U [FW 0C]",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_SINGLE_LUN ),
 
                
-UNUSUAL_DEV(  0x057b, 0x0000, 0x0000, 0x0299, 
+UNUSUAL_DEV(  0x057b, 0x0000, 0x0000, 0x0299,
                "Y-E Data",
                "Flashbuster-U",
                US_SC_DEVICE,  US_PR_CB, NULL,
                US_FL_SINGLE_LUN),
 
-UNUSUAL_DEV(  0x057b, 0x0000, 0x0300, 0x9999, 
+UNUSUAL_DEV(  0x057b, 0x0000, 0x0300, 0x9999,
                "Y-E Data",
                "Flashbuster-U",
                US_SC_DEVICE,  US_PR_DEVICE, NULL,
@@ -677,7 +677,7 @@ UNUSUAL_DEV(  0x057b, 0x0000, 0x0300, 0x9999,
  * This entry is needed only because the device reports
  * bInterfaceClass = 0xff (vendor-specific)
  */
-UNUSUAL_DEV(  0x057b, 0x0022, 0x0000, 0x9999, 
+UNUSUAL_DEV(  0x057b, 0x0022, 0x0000, 0x9999,
                "Y-E Data",
                "Silicon Media R/W",
                US_SC_DEVICE, US_PR_DEVICE, NULL, 0),
@@ -825,13 +825,13 @@ UNUSUAL_DEV(  0x0636, 0x0003, 0x0000, 0x9999,
                US_SC_SCSI, US_PR_BULK, NULL,
                US_FL_FIX_INQUIRY ),
 
-UNUSUAL_DEV(  0x0644, 0x0000, 0x0100, 0x0100, 
+UNUSUAL_DEV(  0x0644, 0x0000, 0x0100, 0x0100,
                "TEAC",
                "Floppy Drive",
-               US_SC_UFI, US_PR_CB, NULL, 0 ), 
+               US_SC_UFI, US_PR_CB, NULL, 0 ),
 
 #ifdef CONFIG_USB_STORAGE_SDDR09
-UNUSUAL_DEV(  0x066b, 0x0105, 0x0100, 0x0100, 
+UNUSUAL_DEV(  0x066b, 0x0105, 0x0100, 0x0100,
                "Olympus",
                "Camedia MAUSB-2",
                US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init,
@@ -867,14 +867,14 @@ UNUSUAL_DEV( 0x0686, 0x4011, 0x0001, 0x0001,
 
 /* Reported by Miguel A. Fosas <amn3s1a@ono.com> */
 UNUSUAL_DEV(  0x0686, 0x4017, 0x0001, 0x0001,
-                "Minolta",
-                "DIMAGE E223",
-                US_SC_SCSI, US_PR_DEVICE, NULL, 0 ),
+               "Minolta",
+               "DIMAGE E223",
+               US_SC_SCSI, US_PR_DEVICE, NULL, 0 ),
 
 UNUSUAL_DEV(  0x0693, 0x0005, 0x0100, 0x0100,
                "Hagiwara",
                "Flashgate",
-               US_SC_SCSI, US_PR_BULK, NULL, 0 ), 
+               US_SC_SCSI, US_PR_BULK, NULL, 0 ),
 
 /* Reported by David Hamilton <niftimusmaximus@lycos.com> */
 UNUSUAL_DEV(  0x069b, 0x3004, 0x0001, 0x0001,
@@ -918,7 +918,7 @@ UNUSUAL_DEV(  0x0781, 0x0100, 0x0100, 0x0100,
                US_FL_SINGLE_LUN ),
 
 #ifdef CONFIG_USB_STORAGE_SDDR09
-UNUSUAL_DEV(  0x0781, 0x0200, 0x0000, 0x9999, 
+UNUSUAL_DEV(  0x0781, 0x0200, 0x0000, 0x9999,
                "Sandisk",
                "ImageMate SDDR-09",
                US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init,
@@ -939,17 +939,17 @@ UNUSUAL_DEV(  0x07ab, 0xfccd, 0x0000, 0x9999,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_FIX_CAPACITY),
 
-UNUSUAL_DEV(  0x07af, 0x0004, 0x0100, 0x0133, 
+UNUSUAL_DEV(  0x07af, 0x0004, 0x0100, 0x0133,
                "Microtech",
                "USB-SCSI-DB25",
                US_SC_SCSI, US_PR_BULK, usb_stor_euscsi_init,
                US_FL_SCM_MULT_TARG ), 
 
-UNUSUAL_DEV(  0x07af, 0x0005, 0x0100, 0x0100, 
+UNUSUAL_DEV(  0x07af, 0x0005, 0x0100, 0x0100,
                "Microtech",
                "USB-SCSI-HD50",
                US_SC_DEVICE, US_PR_DEVICE, usb_stor_euscsi_init,
-               US_FL_SCM_MULT_TARG ), 
+               US_FL_SCM_MULT_TARG ),
 
 #ifdef CONFIG_USB_STORAGE_DPCM
 UNUSUAL_DEV(  0x07af, 0x0006, 0x0100, 0x0100,
@@ -1053,10 +1053,10 @@ UNUSUAL_DEV(  0x07c4, 0xa109, 0x0000, 0xffff,
  * as "DualSlot CompactFlash(TM) & MStick Drive USB"
  */
 UNUSUAL_DEV(  0x07c4, 0xa10b, 0x0000, 0xffff,
-                "DataFab Systems Inc.",
-                "USB CF+MS",
-                US_SC_SCSI, US_PR_DATAFAB, NULL,
-                0 ),
+               "DataFab Systems Inc.",
+               "USB CF+MS",
+               US_SC_SCSI, US_PR_DATAFAB, NULL,
+               0 ),
 
 #endif
 
@@ -1119,10 +1119,10 @@ UNUSUAL_DEV(  0x08bd, 0x1100, 0x0000, 0x0000,
  * US_FL_IGNORE_RESIDUE Needed
  */
 UNUSUAL_DEV(  0x08ca, 0x3103, 0x0100, 0x0100,
-                "AIPTEK",
-                "Aiptek USB Keychain MP3 Player",
-                US_SC_DEVICE, US_PR_DEVICE, NULL,
-                US_FL_IGNORE_RESIDUE),
+               "AIPTEK",
+               "Aiptek USB Keychain MP3 Player",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_IGNORE_RESIDUE),
 
 /* Entry needed for flags. Moreover, all devices with this ID use
  * bulk-only transport, but _some_ falsely report Control/Bulk instead.
@@ -1166,26 +1166,26 @@ UNUSUAL_DEV( 0x090c, 0x1132, 0x0000, 0xffff,
  * Submitted by James Courtier-Dutton <James@superbug.demon.co.uk>
  */
 UNUSUAL_DEV( 0x0a17, 0x0004, 0x1000, 0x1000,
-                "Pentax",
-                "Optio 2/3/400",
-                US_SC_DEVICE, US_PR_DEVICE, NULL,
-                US_FL_FIX_INQUIRY ),
+               "Pentax",
+               "Optio 2/3/400",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_FIX_INQUIRY ),
 
 
 /* Submitted by Per Winkvist <per.winkvist@uk.com> */
 UNUSUAL_DEV( 0x0a17, 0x006, 0x0000, 0xffff,
-                "Pentax",
-                "Optio S/S4",
-                US_SC_DEVICE, US_PR_DEVICE, NULL,
-                US_FL_FIX_INQUIRY ),
+               "Pentax",
+               "Optio S/S4",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_FIX_INQUIRY ),
 
 /* These are virtual windows driver CDs, which the zd1211rw driver
  * automatically converts into WLAN devices. */
 UNUSUAL_DEV( 0x0ace, 0x2011, 0x0101, 0x0101,
-                "ZyXEL",
-                "G-220F USB-WLAN Install",
-                US_SC_DEVICE, US_PR_DEVICE, NULL,
-                US_FL_IGNORE_DEVICE ),
+               "ZyXEL",
+               "G-220F USB-WLAN Install",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_IGNORE_DEVICE ),
 
 UNUSUAL_DEV( 0x0ace, 0x20ff, 0x0101, 0x0101,
                "SiteCom",
@@ -1211,17 +1211,17 @@ UNUSUAL_DEV(  0x0bf6, 0xa001, 0x0100, 0x0110,
 
 #ifdef CONFIG_USB_STORAGE_DATAFAB
 UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xffff,
-              "Acomdata",
-              "CF",
-              US_SC_SCSI, US_PR_DATAFAB, NULL,
-              US_FL_SINGLE_LUN ),
+               "Acomdata",
+               "CF",
+               US_SC_SCSI, US_PR_DATAFAB, NULL,
+               US_FL_SINGLE_LUN ),
 #endif
 #ifdef CONFIG_USB_STORAGE_SDDR55
 UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xffff,
-              "Acomdata",
-              "SM",
-              US_SC_SCSI, US_PR_SDDR55, NULL,
-              US_FL_SINGLE_LUN ),
+               "Acomdata",
+               "SM",
+               US_SC_SCSI, US_PR_SDDR55, NULL,
+               US_FL_SINGLE_LUN ),
 #endif
 
 /* Submitted by: Nick Sillik <n.sillik@temple.edu>
index 8e898e3d861ea477153ce8f782230ede58e1292f..bef8bcd9bd9824fa428c6108a1010d6c2e5e479b 100644 (file)
@@ -191,16 +191,13 @@ static int storage_suspend(struct usb_interface *iface, pm_message_t message)
 {
        struct us_data *us = usb_get_intfdata(iface);
 
+       US_DEBUGP("%s\n", __FUNCTION__);
+
        /* Wait until no command is running */
        mutex_lock(&us->dev_mutex);
 
-       US_DEBUGP("%s\n", __FUNCTION__);
        if (us->suspend_resume_hook)
                (us->suspend_resume_hook)(us, US_SUSPEND);
-       iface->dev.power.power_state.event = message.event;
-
-       /* When runtime PM is working, we'll set a flag to indicate
-        * whether we should autoresume when a SCSI request arrives. */
 
        mutex_unlock(&us->dev_mutex);
        return 0;
@@ -210,14 +207,25 @@ static int storage_resume(struct usb_interface *iface)
 {
        struct us_data *us = usb_get_intfdata(iface);
 
-       mutex_lock(&us->dev_mutex);
-
        US_DEBUGP("%s\n", __FUNCTION__);
+
        if (us->suspend_resume_hook)
                (us->suspend_resume_hook)(us, US_RESUME);
-       iface->dev.power.power_state.event = PM_EVENT_ON;
 
-       mutex_unlock(&us->dev_mutex);
+       return 0;
+}
+
+static int storage_reset_resume(struct usb_interface *iface)
+{
+       struct us_data *us = usb_get_intfdata(iface);
+
+       US_DEBUGP("%s\n", __FUNCTION__);
+
+       /* Report the reset to the SCSI core */
+       usb_stor_report_bus_reset(us);
+
+       /* FIXME: Notify the subdrivers that they need to reinitialize
+        * the device */
        return 0;
 }
 
@@ -228,7 +236,7 @@ static int storage_resume(struct usb_interface *iface)
  * a USB port reset, whether from this driver or a different one.
  */
 
-static void storage_pre_reset(struct usb_interface *iface)
+static int storage_pre_reset(struct usb_interface *iface)
 {
        struct us_data *us = usb_get_intfdata(iface);
 
@@ -236,22 +244,23 @@ static void storage_pre_reset(struct usb_interface *iface)
 
        /* Make sure no command runs during the reset */
        mutex_lock(&us->dev_mutex);
+       return 0;
 }
 
-static void storage_post_reset(struct usb_interface *iface)
+static int storage_post_reset(struct usb_interface *iface)
 {
        struct us_data *us = usb_get_intfdata(iface);
 
        US_DEBUGP("%s\n", __FUNCTION__);
 
        /* Report the reset to the SCSI core */
-       scsi_lock(us_to_host(us));
        usb_stor_report_bus_reset(us);
-       scsi_unlock(us_to_host(us));
 
        /* FIXME: Notify the subdrivers that they need to reinitialize
         * the device */
+
        mutex_unlock(&us->dev_mutex);
+       return 0;
 }
 
 /*
@@ -300,6 +309,7 @@ static int usb_stor_control_thread(void * __us)
 {
        struct us_data *us = (struct us_data *)__us;
        struct Scsi_Host *host = us_to_host(us);
+       int autopm_rc;
 
        current->flags |= PF_NOFREEZE;
 
@@ -310,6 +320,9 @@ static int usb_stor_control_thread(void * __us)
                        
                US_DEBUGP("*** thread awakened.\n");
 
+               /* Autoresume the device */
+               autopm_rc = usb_autopm_get_interface(us->pusb_intf);
+
                /* lock the device pointers */
                mutex_lock(&(us->dev_mutex));
 
@@ -368,6 +381,12 @@ static int usb_stor_control_thread(void * __us)
                        us->srb->result = SAM_STAT_GOOD;
                }
 
+               /* Did the autoresume fail? */
+               else if (autopm_rc < 0) {
+                       US_DEBUGP("Could not wake device\n");
+                       us->srb->result = DID_ERROR << 16;
+               }
+
                /* we've got a command, let's do it! */
                else {
                        US_DEBUG(usb_stor_show_command(us->srb));
@@ -410,25 +429,21 @@ SkipForAbort:
 
                /* unlock the device pointers */
                mutex_unlock(&us->dev_mutex);
-       } /* for (;;) */
 
-       scsi_host_put(host);
+               /* Start an autosuspend */
+               if (autopm_rc == 0)
+                       usb_autopm_put_interface(us->pusb_intf);
+       } /* for (;;) */
 
-       /* notify the exit routine that we're actually exiting now 
-        *
-        * complete()/wait_for_completion() is similar to up()/down(),
-        * except that complete() is safe in the case where the structure
-        * is getting deleted in a parallel mode of execution (i.e. just
-        * after the down() -- that's necessary for the thread-shutdown
-        * case.
-        *
-        * complete_and_exit() goes even further than this -- it is safe in
-        * the case that the thread of the caller is going away (not just
-        * the structure) -- this is necessary for the module-remove case.
-        * This is important in preemption kernels, which transfer the flow
-        * of execution immediately upon a complete().
-        */
-       complete_and_exit(&threads_gone, 0);
+       /* Wait until we are told to stop */
+       for (;;) {
+               set_current_state(TASK_INTERRUPTIBLE);
+               if (kthread_should_stop())
+                       break;
+               schedule();
+       }
+       __set_current_state(TASK_RUNNING);
+       return 0;
 }      
 
 /***********************************************************************
@@ -796,19 +811,13 @@ static int usb_stor_acquire_resources(struct us_data *us)
        }
 
        /* Start up our control thread */
-       th = kthread_create(usb_stor_control_thread, us, "usb-storage");
+       th = kthread_run(usb_stor_control_thread, us, "usb-storage");
        if (IS_ERR(th)) {
                printk(KERN_WARNING USB_STORAGE 
                       "Unable to start control thread\n");
                return PTR_ERR(th);
        }
-
-       /* Take a reference to the host for the control thread and
-        * count it among all the threads we have launched.  Then
-        * start it up. */
-       scsi_host_get(us_to_host(us));
-       atomic_inc(&total_threads);
-       wake_up_process(th);
+       us->ctl_thread = th;
 
        return 0;
 }
@@ -825,6 +834,8 @@ static void usb_stor_release_resources(struct us_data *us)
        US_DEBUGP("-- sending exit command to thread\n");
        set_bit(US_FLIDX_DISCONNECTING, &us->flags);
        up(&us->sema);
+       if (us->ctl_thread)
+               kthread_stop(us->ctl_thread);
 
        /* Call the destructor routine, if it exists */
        if (us->extra_destructor) {
@@ -938,6 +949,7 @@ retry:
        }
 
        scsi_host_put(us_to_host(us));
+       usb_autopm_put_interface(us->pusb_intf);
        complete_and_exit(&threads_gone, 0);
 }
 
@@ -1027,6 +1039,7 @@ static int storage_probe(struct usb_interface *intf,
         * start it up. */
        scsi_host_get(us_to_host(us));
        atomic_inc(&total_threads);
+       usb_autopm_get_interface(intf); /* dropped in the scanning thread */
        wake_up_process(th);
 
        return 0;
@@ -1059,10 +1072,12 @@ static struct usb_driver usb_storage_driver = {
 #ifdef CONFIG_PM
        .suspend =      storage_suspend,
        .resume =       storage_resume,
+       .reset_resume = storage_reset_resume,
 #endif
        .pre_reset =    storage_pre_reset,
        .post_reset =   storage_post_reset,
        .id_table =     storage_usb_ids,
+       .supports_autosuspend = 1,
 };
 
 static int __init usb_stor_init(void)
index 6dac1ffdde86203ed6972679e0432848d47521d3..6445665b1577c258d3a722e19e9a56fac549267a 100644 (file)
@@ -144,6 +144,7 @@ struct us_data {
        unsigned char           *sensebuf;       /* sense data buffer    */
        dma_addr_t              cr_dma;          /* buffer DMA addresses */
        dma_addr_t              iobuf_dma;
+       struct task_struct      *ctl_thread;     /* the control thread   */
 
        /* mutual exclusion and synchronization structures */
        struct semaphore        sema;            /* to sleep thread on      */
index 8432bf171d2e8468a6e608e550152bcb25cd76bf..8de11deb5d1429dffb16febcd1d834623b59d0c5 100644 (file)
@@ -34,9 +34,6 @@ static struct usb_device_id skel_table [] = {
 };
 MODULE_DEVICE_TABLE(usb, skel_table);
 
-/* to prevent a race between open and disconnect */
-static DEFINE_MUTEX(skel_open_lock);
-
 
 /* Get a minor range for your devices from the usb maintainer */
 #define USB_SKEL_MINOR_BASE    192
@@ -54,16 +51,21 @@ struct usb_skel {
        struct usb_device       *udev;                  /* the usb device for this device */
        struct usb_interface    *interface;             /* the interface for this device */
        struct semaphore        limit_sem;              /* limiting the number of writes in progress */
+       struct usb_anchor       submitted;              /* in case we need to retract our submissions */
        unsigned char           *bulk_in_buffer;        /* the buffer to receive data */
        size_t                  bulk_in_size;           /* the size of the receive buffer */
        __u8                    bulk_in_endpointAddr;   /* the address of the bulk in endpoint */
        __u8                    bulk_out_endpointAddr;  /* the address of the bulk out endpoint */
+       int                     errors;                 /* the last request tanked */
+       int                     open_count;             /* count the number of openers */
+       spinlock_t              err_lock;               /* lock for errors */
        struct kref             kref;
        struct mutex            io_mutex;               /* synchronize I/O with disconnect */
 };
 #define to_skel_dev(d) container_of(d, struct usb_skel, kref)
 
 static struct usb_driver skel_driver;
+static void skel_draw_down(struct usb_skel *dev);
 
 static void skel_delete(struct kref *kref)
 {
@@ -83,10 +85,8 @@ static int skel_open(struct inode *inode, struct file *file)
 
        subminor = iminor(inode);
 
-       mutex_lock(&skel_open_lock);
        interface = usb_find_interface(&skel_driver, subminor);
        if (!interface) {
-               mutex_unlock(&skel_open_lock);
                err ("%s - error, can't find device for minor %d",
                     __FUNCTION__, subminor);
                retval = -ENODEV;
@@ -95,22 +95,33 @@ static int skel_open(struct inode *inode, struct file *file)
 
        dev = usb_get_intfdata(interface);
        if (!dev) {
-               mutex_unlock(&skel_open_lock);
                retval = -ENODEV;
                goto exit;
        }
 
        /* increment our usage count for the device */
        kref_get(&dev->kref);
-       /* now we can drop the lock */
-       mutex_unlock(&skel_open_lock);
 
-       /* prevent the device from being autosuspended */
-       retval = usb_autopm_get_interface(interface);
-       if (retval) {
+       /* lock the device to allow correctly handling errors
+        * in resumption */
+       mutex_lock(&dev->io_mutex);
+
+       if (!dev->open_count++) {
+               retval = usb_autopm_get_interface(interface);
+                       if (retval) {
+                               dev->open_count--;
+                               mutex_unlock(&dev->io_mutex);
+                               kref_put(&dev->kref, skel_delete);
+                               goto exit;
+                       }
+       } /* else { //uncomment this block if you want exclusive open
+               retval = -EBUSY;
+               dev->open_count--;
+               mutex_unlock(&dev->io_mutex);
                kref_put(&dev->kref, skel_delete);
                goto exit;
-       }
+       } */
+       /* prevent the device from being autosuspended */
 
        /* save our object in the file's private structure */
        file->private_data = dev;
@@ -129,7 +140,7 @@ static int skel_release(struct inode *inode, struct file *file)
 
        /* allow the device to be autosuspended */
        mutex_lock(&dev->io_mutex);
-       if (dev->interface)
+       if (!--dev->open_count && dev->interface)
                usb_autopm_put_interface(dev->interface);
        mutex_unlock(&dev->io_mutex);
 
@@ -138,6 +149,30 @@ static int skel_release(struct inode *inode, struct file *file)
        return 0;
 }
 
+static int skel_flush(struct file *file, fl_owner_t id)
+{
+       struct usb_skel *dev;
+       int res;
+
+       dev = (struct usb_skel *)file->private_data;
+       if (dev == NULL)
+               return -ENODEV;
+
+       /* wait for io to stop */
+       mutex_lock(&dev->io_mutex);
+       skel_draw_down(dev);
+
+       /* read out errors, leave subsequent opens a clean slate */
+       spin_lock_irq(&dev->err_lock);
+       res = dev->errors ? (dev->errors == -EPIPE ? -EPIPE : -EIO) : 0;
+       dev->errors = 0;
+       spin_unlock_irq(&dev->err_lock);
+
+       mutex_unlock(&dev->io_mutex);
+
+       return res;
+}
+
 static ssize_t skel_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
 {
        struct usb_skel *dev;
@@ -179,12 +214,16 @@ static void skel_write_bulk_callback(struct urb *urb)
        dev = (struct usb_skel *)urb->context;
 
        /* sync/async unlink faults aren't errors */
-       if (urb->status &&
-           !(urb->status == -ENOENT ||
-             urb->status == -ECONNRESET ||
-             urb->status == -ESHUTDOWN)) {
-               err("%s - nonzero write bulk status received: %d",
-                   __FUNCTION__, urb->status);
+       if (urb->status) {
+               if(!(urb->status == -ENOENT ||
+                   urb->status == -ECONNRESET ||
+                   urb->status == -ESHUTDOWN))
+                       err("%s - nonzero write bulk status received: %d",
+                           __FUNCTION__, urb->status);
+
+               spin_lock(&dev->err_lock);
+               dev->errors = urb->status;
+               spin_unlock(&dev->err_lock);
        }
 
        /* free up our allocated buffer */
@@ -213,6 +252,17 @@ static ssize_t skel_write(struct file *file, const char *user_buffer, size_t cou
                goto exit;
        }
 
+       spin_lock_irq(&dev->err_lock);
+       if ((retval = dev->errors) < 0) {
+               /* any error is reported once */
+               dev->errors = 0;
+               /* to preserve notifications about reset */
+               retval = (retval == -EPIPE) ? retval : -EIO;
+       }
+       spin_unlock_irq(&dev->err_lock);
+       if (retval < 0)
+               goto error;
+
        /* create a urb, and a buffer for it, and copy the data to the urb */
        urb = usb_alloc_urb(0, GFP_KERNEL);
        if (!urb) {
@@ -244,13 +294,14 @@ static ssize_t skel_write(struct file *file, const char *user_buffer, size_t cou
                          usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),
                          buf, writesize, skel_write_bulk_callback, dev);
        urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+       usb_anchor_urb(urb, &dev->submitted);
 
        /* send the data out the bulk port */
        retval = usb_submit_urb(urb, GFP_KERNEL);
        mutex_unlock(&dev->io_mutex);
        if (retval) {
                err("%s - failed submitting write urb, error %d", __FUNCTION__, retval);
-               goto error;
+               goto error_unanchor;
        }
 
        /* release our reference to this urb, the USB core will eventually free it entirely */
@@ -259,6 +310,8 @@ static ssize_t skel_write(struct file *file, const char *user_buffer, size_t cou
 
        return writesize;
 
+error_unanchor:
+       usb_unanchor_urb(urb);
 error:
        if (urb) {
                usb_buffer_free(dev->udev, writesize, buf, urb->transfer_dma);
@@ -276,6 +329,7 @@ static const struct file_operations skel_fops = {
        .write =        skel_write,
        .open =         skel_open,
        .release =      skel_release,
+       .flush =        skel_flush,
 };
 
 /*
@@ -306,6 +360,8 @@ static int skel_probe(struct usb_interface *interface, const struct usb_device_i
        kref_init(&dev->kref);
        sema_init(&dev->limit_sem, WRITES_IN_FLIGHT);
        mutex_init(&dev->io_mutex);
+       spin_lock_init(&dev->err_lock);
+       init_usb_anchor(&dev->submitted);
 
        dev->udev = usb_get_dev(interface_to_usbdev(interface));
        dev->interface = interface;
@@ -368,22 +424,18 @@ static void skel_disconnect(struct usb_interface *interface)
        struct usb_skel *dev;
        int minor = interface->minor;
 
-       /* prevent skel_open() from racing skel_disconnect() */
-       mutex_lock(&skel_open_lock);
-
        dev = usb_get_intfdata(interface);
        usb_set_intfdata(interface, NULL);
 
        /* give back our minor */
        usb_deregister_dev(interface, &skel_class);
-       mutex_unlock(&skel_open_lock);
 
        /* prevent more I/O from starting */
        mutex_lock(&dev->io_mutex);
        dev->interface = NULL;
        mutex_unlock(&dev->io_mutex);
 
-
+       usb_kill_anchored_urbs(&dev->submitted);
 
        /* decrement our usage count */
        kref_put(&dev->kref, skel_delete);
@@ -391,10 +443,59 @@ static void skel_disconnect(struct usb_interface *interface)
        info("USB Skeleton #%d now disconnected", minor);
 }
 
+static void skel_draw_down(struct usb_skel *dev)
+{
+       int time;
+
+       time = usb_wait_anchor_empty_timeout(&dev->submitted, 1000);
+       if (!time)
+               usb_kill_anchored_urbs(&dev->submitted);
+}
+
+static int skel_suspend(struct usb_interface *intf, pm_message_t message)
+{
+       struct usb_skel *dev = usb_get_intfdata(intf);
+
+       if (!dev)
+               return 0;
+       skel_draw_down(dev);
+       return 0;
+}
+
+static int skel_resume (struct usb_interface *intf)
+{
+       return 0;
+}
+
+static int skel_pre_reset(struct usb_interface *intf)
+{
+       struct usb_skel *dev = usb_get_intfdata(intf);
+
+       mutex_lock(&dev->io_mutex);
+       skel_draw_down(dev);
+
+       return 0;
+}
+
+static int skel_post_reset(struct usb_interface *intf)
+{
+       struct usb_skel *dev = usb_get_intfdata(intf);
+
+       /* we are sure no URBs are active - no locking needed */
+       dev->errors = -EPIPE;
+       mutex_unlock(&dev->io_mutex);
+
+       return 0;
+}
+
 static struct usb_driver skel_driver = {
        .name =         "skeleton",
        .probe =        skel_probe,
        .disconnect =   skel_disconnect,
+       .suspend =      skel_suspend,
+       .resume =       skel_resume,
+       .pre_reset =    skel_pre_reset,
+       .post_reset =   skel_post_reset,
        .id_table =     skel_table,
        .supports_autosuspend = 1,
 };
index 2ce05019301892d9a0420f97ef2b803f8742100a..2349e71b0083f60f87d8dd45b740f81ff1616520 100644 (file)
@@ -2102,7 +2102,9 @@ static ssize_t radeon_show_one_edid(char *buf, loff_t off, size_t count, const u
 }
 
 
-static ssize_t radeon_show_edid1(struct kobject *kobj, char *buf, loff_t off, size_t count)
+static ssize_t radeon_show_edid1(struct kobject *kobj,
+                                struct bin_attribute *bin_attr,
+                                char *buf, loff_t off, size_t count)
 {
        struct device *dev = container_of(kobj, struct device, kobj);
        struct pci_dev *pdev = to_pci_dev(dev);
@@ -2113,7 +2115,9 @@ static ssize_t radeon_show_edid1(struct kobject *kobj, char *buf, loff_t off, si
 }
 
 
-static ssize_t radeon_show_edid2(struct kobject *kobj, char *buf, loff_t off, size_t count)
+static ssize_t radeon_show_edid2(struct kobject *kobj,
+                                struct bin_attribute *bin_attr,
+                                char *buf, loff_t off, size_t count)
 {
        struct device *dev = container_of(kobj, struct device, kobj);
        struct pci_dev *pdev = to_pci_dev(dev);
@@ -2126,7 +2130,6 @@ static ssize_t radeon_show_edid2(struct kobject *kobj, char *buf, loff_t off, si
 static struct bin_attribute edid1_attr = {
        .attr   = {
                .name   = "edid1",
-               .owner  = THIS_MODULE,
                .mode   = 0444,
        },
        .size   = EDID_LENGTH,
@@ -2136,7 +2139,6 @@ static struct bin_attribute edid1_attr = {
 static struct bin_attribute edid2_attr = {
        .attr   = {
                .name   = "edid2",
-               .owner  = THIS_MODULE,
                .mode   = 0444,
        },
        .size   = EDID_LENGTH,
index c65e81ff3578fedb1ff1e00bde752f252f77a8e0..7e06223bca9494178632f444b989a554f3e5180f 100644 (file)
@@ -172,7 +172,7 @@ static struct class backlight_class = {
 
 #define DECLARE_ATTR(_name,_mode,_show,_store)                 \
 {                                                              \
-       .attr   = { .name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE },  \
+       .attr   = { .name = __stringify(_name), .mode = _mode }, \
        .show   = _show,                                        \
        .store  = _store,                                       \
 }
index 6ef8f0a7a137612deb25cbb3377f49e31e8aa93e..648b53c1fdea7f7f2687f8f5d6b60c179f61007a 100644 (file)
@@ -157,7 +157,7 @@ static struct class lcd_class = {
 
 #define DECLARE_ATTR(_name,_mode,_show,_store)                 \
 {                                                              \
-       .attr   = { .name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE },  \
+       .attr   = { .name = __stringify(_name), .mode = _mode }, \
        .show   = _show,                                        \
        .store  = _store,                                       \
 }
index 63b85bf81a651d808ab486ebb37b2bc3703c423c..d3b8a6be29163bcfa9523613c8fafb5cc433d7ef 100644 (file)
@@ -6,7 +6,7 @@ menu "Console display driver support"
 
 config VGA_CONSOLE
        bool "VGA text console" if EMBEDDED || !X86
-       depends on !ARCH_ACORN && !ARCH_EBSA110 && !4xx && !8xx && !SPARC && !M68K && !PARISC && !FRV && !ARCH_VERSATILE && !SUPERH
+       depends on !ARCH_ACORN && !ARCH_EBSA110 && !4xx && !8xx && !SPARC && !M68K && !PARISC && !FRV && !ARCH_VERSATILE && !SUPERH && !BFIN
        default y
        help
          Saying Y here will allow you to use Linux in text mode through a
index ab5285a7f1d6b1de4beff23674b8e93981dc28d7..1d3f2080aa6f4ab8ba8eb1fda6bcfc0fae1317f5 100644 (file)
@@ -247,7 +247,6 @@ int SetCoreClockPLL(volatile STG4000REG __iomem *pSTGReg, struct pci_dev *pDev)
        u32 ulCoreClock;
        u32 tmp;
        u32 ulChipSpeed;
-       u8 rev;
 
        STG_WRITE_REG(IntMask, 0xFFFF);
 
@@ -276,9 +275,9 @@ int SetCoreClockPLL(volatile STG4000REG __iomem *pSTGReg, struct pci_dev *pDev)
                      PMX2_SOFTRESET_ROM_RST);
 
        pci_read_config_word(pDev, PCI_CONFIG_SUBSYS_ID, &sub);
-       pci_read_config_byte(pDev, PCI_REVISION_ID, &rev);
 
-       ulChipSpeed = InitSDRAMRegisters(pSTGReg, (u32)sub, (u32)rev);
+       ulChipSpeed = InitSDRAMRegisters(pSTGReg, (u32)sub,
+                                        (u32)pDev->revision);
 
        if (ulChipSpeed == 0)
                return -EINVAL;
index c8559a756b75ff5bbe017c43cea941160d002168..886e475f22f28e395d45066eae6106aa3f4e6c30 100644 (file)
@@ -1994,7 +1994,6 @@ static void matroxfb_unregister_device(struct matrox_fb_info* minfo) {
 
 static int matroxfb_probe(struct pci_dev* pdev, const struct pci_device_id* dummy) {
        struct board* b;
-       u_int8_t rev;
        u_int16_t svid;
        u_int16_t sid;
        struct matrox_fb_info* minfo;
@@ -2005,11 +2004,10 @@ static int matroxfb_probe(struct pci_dev* pdev, const struct pci_device_id* dumm
 #endif
        DBG(__FUNCTION__)
 
-       pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
        svid = pdev->subsystem_vendor;
        sid = pdev->subsystem_device;
        for (b = dev_list; b->vendor; b++) {
-               if ((b->vendor != pdev->vendor) || (b->device != pdev->device) || (b->rev < rev)) continue;
+               if ((b->vendor != pdev->vendor) || (b->device != pdev->device) || (b->rev < pdev->revision)) continue;
                if (b->svid)
                        if ((b->svid != svid) || (b->sid != sid)) continue;
                break;
index 608e40bb20e9992368a228aae0f5cbf974503745..177177609be77c095fbbd721e5489d53d96e3396 100644 (file)
@@ -2,8 +2,6 @@
 #define __MATROXFB_CRTC2_H__
 
 #include <linux/ioctl.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
 #include "matroxfb_base.h"
 
 struct matroxfb_dh_fb_info {
index a30e1e13d8be87c7c8135ed79c57a54f3e0c691e..93d07ef852762e8d9198adc1d1a3e03a93f8a1ed 100644 (file)
@@ -5789,7 +5789,7 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        ivideo->warncount = 0;
        ivideo->chip_id = pdev->device;
        ivideo->chip_vendor = pdev->vendor;
-       pci_read_config_byte(pdev, PCI_REVISION_ID, &ivideo->revision_id);
+       ivideo->revision_id = pdev->revision;
        ivideo->SiS_Pr.ChipRevision = ivideo->revision_id;
        pci_read_config_word(pdev, PCI_COMMAND, &reg16);
        ivideo->sisvga_enabled = reg16 & 0x01;
index 62fa5500361d2a1b8a1ce7418c1b81f9d1044d1b..5eff28ce4f4dcfc967583cc2afec2d36ff7eaba6 100644 (file)
@@ -1348,7 +1348,7 @@ static int __devinit sstfb_probe(struct pci_dev *pdev,
        f_ddprintk("found device : %s\n", spec->name);
 
        par->dev = pdev;
-       pci_read_config_byte(pdev, PCI_REVISION_ID, &par->revision);
+       par->revision = pdev->revision;
 
        fix->mmio_start = pci_resource_start(pdev,0);
        fix->mmio_len   = 0x400000;
index f0fde6ea7c36e252f5f6dec8d205664d5ce8b023..5c0dab62809972b2b28bc3bd1929e8994e915cae 100644 (file)
@@ -1625,8 +1625,7 @@ tgafb_register(struct device *dev)
        par->tga_regs_base = mem_base + TGA_REGS_OFFSET;
        par->tga_type = tga_type;
        if (tga_bus_pci)
-               pci_read_config_byte(to_pci_dev(dev), PCI_REVISION_ID,
-                                    &par->tga_chip_rev);
+               par->tga_chip_rev = (to_pci_dev(dev))->revision;
        if (tga_bus_tc)
                par->tga_chip_rev = TGA_READ_REG(par, TGA_START_REG) & 0xff;
 
index 904e5aeb696c41a8692dab99c6851f8eb0cb78f0..df95d6c2cefa01124b1513d2b5a07514cfb21c48 100644 (file)
@@ -35,4 +35,17 @@ config W1_SLAVE_DS2433_CRC
          Each block has 30 bytes of data and a two byte CRC16.
          Full block writes are only allowed if the CRC is valid.
 
+config W1_SLAVE_DS2760
+       tristate "Dallas 2760 battery monitor chip (HP iPAQ & others)"
+       depends on W1
+       help
+         If you enable this you will have the DS2760 battery monitor
+         chip support.
+
+         The battery monitor chip is used in many batteries/devices
+         as the one who is responsible for charging/discharging/monitoring
+         Li+ batteries.
+
+         If you are unsure, say N.
+
 endmenu
index 725dcfdfddb412d2de253cfc142e08b7cccf66af..a8eb7524df1db2c0c4db0dbe8a4097d9f65fcff6 100644 (file)
@@ -5,4 +5,5 @@
 obj-$(CONFIG_W1_SLAVE_THERM)   += w1_therm.o
 obj-$(CONFIG_W1_SLAVE_SMEM)    += w1_smem.o
 obj-$(CONFIG_W1_SLAVE_DS2433)  += w1_ds2433.o
+obj-$(CONFIG_W1_SLAVE_DS2760)  += w1_ds2760.o
 
index 8ea17a53eed853223be23df1e78878009ebf5577..cab56005dd49c3d10c90ccaeabe703f877ac8851 100644 (file)
@@ -91,8 +91,9 @@ static int w1_f23_refresh_block(struct w1_slave *sl, struct w1_f23_data *data,
 }
 #endif /* CONFIG_W1_SLAVE_DS2433_CRC */
 
-static ssize_t w1_f23_read_bin(struct kobject *kobj, char *buf, loff_t off,
-                              size_t count)
+static ssize_t w1_f23_read_bin(struct kobject *kobj,
+                              struct bin_attribute *bin_attr,
+                              char *buf, loff_t off, size_t count)
 {
        struct w1_slave *sl = kobj_to_w1_slave(kobj);
 #ifdef CONFIG_W1_SLAVE_DS2433_CRC
@@ -199,8 +200,9 @@ static int w1_f23_write(struct w1_slave *sl, int addr, int len, const u8 *data)
        return 0;
 }
 
-static ssize_t w1_f23_write_bin(struct kobject *kobj, char *buf, loff_t off,
-                               size_t count)
+static ssize_t w1_f23_write_bin(struct kobject *kobj,
+                               struct bin_attribute *bin_attr,
+                               char *buf, loff_t off, size_t count)
 {
        struct w1_slave *sl = kobj_to_w1_slave(kobj);
        int addr, len, idx;
@@ -252,7 +254,6 @@ static struct bin_attribute w1_f23_bin_attr = {
        .attr = {
                .name = "eeprom",
                .mode = S_IRUGO | S_IWUSR,
-               .owner = THIS_MODULE,
        },
        .size = W1_EEPROM_SIZE,
        .read = w1_f23_read_bin,
diff --git a/drivers/w1/slaves/w1_ds2760.c b/drivers/w1/slaves/w1_ds2760.c
new file mode 100644 (file)
index 0000000..88a37fb
--- /dev/null
@@ -0,0 +1,213 @@
+/*
+ * 1-Wire implementation for the ds2760 chip
+ *
+ * Copyright Â© 2004-2005, Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>
+ *
+ * Use consistent with the GNU GPL is permitted,
+ * provided that this copyright notice is
+ * preserved in its entirety in all copies and derived works.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/idr.h>
+
+#include "../w1.h"
+#include "../w1_int.h"
+#include "../w1_family.h"
+#include "w1_ds2760.h"
+
+static int w1_ds2760_io(struct device *dev, char *buf, int addr, size_t count,
+                       int io)
+{
+       struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
+
+       if (!dev)
+               return 0;
+
+       mutex_lock(&sl->master->mutex);
+
+       if (addr > DS2760_DATA_SIZE || addr < 0) {
+               count = 0;
+               goto out;
+       }
+       if (addr + count > DS2760_DATA_SIZE)
+               count = DS2760_DATA_SIZE - addr;
+
+       if (!w1_reset_select_slave(sl)) {
+               if (!io) {
+                       w1_write_8(sl->master, W1_DS2760_READ_DATA);
+                       w1_write_8(sl->master, addr);
+                       count = w1_read_block(sl->master, buf, count);
+               } else {
+                       w1_write_8(sl->master, W1_DS2760_WRITE_DATA);
+                       w1_write_8(sl->master, addr);
+                       w1_write_block(sl->master, buf, count);
+                       /* XXX w1_write_block returns void, not n_written */
+               }
+       }
+
+out:
+       mutex_unlock(&sl->master->mutex);
+
+       return count;
+}
+
+int w1_ds2760_read(struct device *dev, char *buf, int addr, size_t count)
+{
+       return w1_ds2760_io(dev, buf, addr, count, 0);
+}
+
+int w1_ds2760_write(struct device *dev, char *buf, int addr, size_t count)
+{
+       return w1_ds2760_io(dev, buf, addr, count, 1);
+}
+
+static ssize_t w1_ds2760_read_bin(struct kobject *kobj, char *buf, loff_t off,
+                                 size_t count)
+{
+       struct device *dev = container_of(kobj, struct device, kobj);
+       return w1_ds2760_read(dev, buf, off, count);
+}
+
+static struct bin_attribute w1_ds2760_bin_attr = {
+       .attr = {
+               .name = "w1_slave",
+               .mode = S_IRUGO,
+               .owner = THIS_MODULE,
+       },
+       .size = DS2760_DATA_SIZE,
+       .read = w1_ds2760_read_bin,
+};
+
+static DEFINE_IDR(bat_idr);
+static DEFINE_MUTEX(bat_idr_lock);
+
+static int new_bat_id(void)
+{
+       int ret;
+
+       while (1) {
+               int id;
+
+               ret = idr_pre_get(&bat_idr, GFP_KERNEL);
+               if (ret == 0)
+                       return -ENOMEM;
+
+               mutex_lock(&bat_idr_lock);
+               ret = idr_get_new(&bat_idr, NULL, &id);
+               mutex_unlock(&bat_idr_lock);
+
+               if (ret == 0) {
+                       ret = id & MAX_ID_MASK;
+                       break;
+               } else if (ret == -EAGAIN) {
+                       continue;
+               } else {
+                       break;
+               }
+       }
+
+       return ret;
+}
+
+static void release_bat_id(int id)
+{
+       mutex_lock(&bat_idr_lock);
+       idr_remove(&bat_idr, id);
+       mutex_unlock(&bat_idr_lock);
+
+       return;
+}
+
+static int w1_ds2760_add_slave(struct w1_slave *sl)
+{
+       int ret;
+       int id;
+       struct platform_device *pdev;
+
+       id = new_bat_id();
+       if (id < 0) {
+               ret = id;
+               goto noid;
+       }
+
+       pdev = platform_device_alloc("ds2760-battery", id);
+       if (!pdev) {
+               ret = -ENOMEM;
+               goto pdev_alloc_failed;
+       }
+       pdev->dev.parent = &sl->dev;
+
+       ret = platform_device_add(pdev);
+       if (ret)
+               goto pdev_add_failed;
+
+       ret = sysfs_create_bin_file(&sl->dev.kobj, &w1_ds2760_bin_attr);
+       if (ret)
+               goto bin_attr_failed;
+
+       dev_set_drvdata(&sl->dev, pdev);
+
+       goto success;
+
+bin_attr_failed:
+pdev_add_failed:
+       platform_device_unregister(pdev);
+pdev_alloc_failed:
+       release_bat_id(id);
+noid:
+success:
+       return ret;
+}
+
+static void w1_ds2760_remove_slave(struct w1_slave *sl)
+{
+       struct platform_device *pdev = dev_get_drvdata(&sl->dev);
+       int id = pdev->id;
+
+       platform_device_unregister(pdev);
+       release_bat_id(id);
+       sysfs_remove_bin_file(&sl->dev.kobj, &w1_ds2760_bin_attr);
+
+       return;
+}
+
+static struct w1_family_ops w1_ds2760_fops = {
+       .add_slave    = w1_ds2760_add_slave,
+       .remove_slave = w1_ds2760_remove_slave,
+};
+
+static struct w1_family w1_ds2760_family = {
+       .fid = W1_FAMILY_DS2760,
+       .fops = &w1_ds2760_fops,
+};
+
+static int __init w1_ds2760_init(void)
+{
+       printk(KERN_INFO "1-Wire driver for the DS2760 battery monitor "
+              " chip  - (c) 2004-2005, Szabolcs Gyurko\n");
+       idr_init(&bat_idr);
+       return w1_register_family(&w1_ds2760_family);
+}
+
+static void __exit w1_ds2760_exit(void)
+{
+       w1_unregister_family(&w1_ds2760_family);
+       idr_destroy(&bat_idr);
+}
+
+EXPORT_SYMBOL(w1_ds2760_read);
+EXPORT_SYMBOL(w1_ds2760_write);
+
+module_init(w1_ds2760_init);
+module_exit(w1_ds2760_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>");
+MODULE_DESCRIPTION("1-wire Driver Dallas 2760 battery monitor chip");
diff --git a/drivers/w1/slaves/w1_ds2760.h b/drivers/w1/slaves/w1_ds2760.h
new file mode 100644 (file)
index 0000000..f130242
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * 1-Wire implementation for the ds2760 chip
+ *
+ * Copyright Â© 2004-2005, Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>
+ *
+ * Use consistent with the GNU GPL is permitted,
+ * provided that this copyright notice is
+ * preserved in its entirety in all copies and derived works.
+ *
+ */
+
+#ifndef __w1_ds2760_h__
+#define __w1_ds2760_h__
+
+/* Known commands to the DS2760 chip */
+#define W1_DS2760_SWAP                 0xAA
+#define W1_DS2760_READ_DATA            0x69
+#define W1_DS2760_WRITE_DATA           0x6C
+#define W1_DS2760_COPY_DATA            0x48
+#define W1_DS2760_RECALL_DATA          0xB8
+#define W1_DS2760_LOCK                 0x6A
+
+/* Number of valid register addresses */
+#define DS2760_DATA_SIZE               0x40
+
+#define DS2760_PROTECTION_REG          0x00
+#define DS2760_STATUS_REG              0x01
+#define DS2760_EEPROM_REG              0x07
+#define DS2760_SPECIAL_FEATURE_REG     0x08
+#define DS2760_VOLTAGE_MSB             0x0c
+#define DS2760_VOLTAGE_LSB             0x0d
+#define DS2760_CURRENT_MSB             0x0e
+#define DS2760_CURRENT_LSB             0x0f
+#define DS2760_CURRENT_ACCUM_MSB       0x10
+#define DS2760_CURRENT_ACCUM_LSB       0x11
+#define DS2760_TEMP_MSB                        0x18
+#define DS2760_TEMP_LSB                        0x19
+#define DS2760_EEPROM_BLOCK0           0x20
+#define DS2760_ACTIVE_FULL             0x20
+#define DS2760_EEPROM_BLOCK1           0x30
+#define DS2760_RATED_CAPACITY          0x32
+#define DS2760_CURRENT_OFFSET_BIAS     0x33
+#define DS2760_ACTIVE_EMPTY            0x3b
+
+extern int w1_ds2760_read(struct device *dev, char *buf, int addr,
+                         size_t count);
+extern int w1_ds2760_write(struct device *dev, char *buf, int addr,
+                          size_t count);
+
+#endif /* !__w1_ds2760_h__ */
index 1a6937dc190b777369eac30ace6ea0aa665963bc..4318935678c5f68ad1559e4540f233fc30551a35 100644 (file)
@@ -42,13 +42,13 @@ static u8 bad_roms[][9] = {
                                {}
                        };
 
-static ssize_t w1_therm_read_bin(struct kobject *, char *, loff_t, size_t);
+static ssize_t w1_therm_read_bin(struct kobject *, struct bin_attribute *,
+                                char *, loff_t, size_t);
 
 static struct bin_attribute w1_therm_bin_attr = {
        .attr = {
                .name = "w1_slave",
                .mode = S_IRUGO,
-               .owner = THIS_MODULE,
        },
        .size = W1_SLAVE_DATA_SIZE,
        .read = w1_therm_read_bin,
@@ -159,7 +159,9 @@ static int w1_therm_check_rom(u8 rom[9])
        return 0;
 }
 
-static ssize_t w1_therm_read_bin(struct kobject *kobj, char *buf, loff_t off, size_t count)
+static ssize_t w1_therm_read_bin(struct kobject *kobj,
+                                struct bin_attribute *bin_attr,
+                                char *buf, loff_t off, size_t count)
 {
        struct w1_slave *sl = kobj_to_w1_slave(kobj);
        struct w1_master *dev = sl->master;
index 7d6876dbcc96a6dcf5cb85f12eb3a10045e52123..f5c5b760ed7b7d9554b7fc3a7f31ee9fc5b27a4c 100644 (file)
@@ -105,7 +105,9 @@ static ssize_t w1_slave_read_name(struct device *dev, struct device_attribute *a
        return sprintf(buf, "%s\n", sl->name);
 }
 
-static ssize_t w1_slave_read_id(struct kobject *kobj, char *buf, loff_t off, size_t count)
+static ssize_t w1_slave_read_id(struct kobject *kobj,
+                               struct bin_attribute *bin_attr,
+                               char *buf, loff_t off, size_t count)
 {
        struct w1_slave *sl = kobj_to_w1_slave(kobj);
 
@@ -128,7 +130,6 @@ static struct bin_attribute w1_slave_attr_bin_id = {
       .attr = {
               .name = "id",
               .mode = S_IRUGO,
-              .owner = THIS_MODULE,
       },
       .size = 8,
       .read = w1_slave_read_id,
@@ -136,7 +137,9 @@ static struct bin_attribute w1_slave_attr_bin_id = {
 
 /* Default family */
 
-static ssize_t w1_default_write(struct kobject *kobj, char *buf, loff_t off, size_t count)
+static ssize_t w1_default_write(struct kobject *kobj,
+                               struct bin_attribute *bin_attr,
+                               char *buf, loff_t off, size_t count)
 {
        struct w1_slave *sl = kobj_to_w1_slave(kobj);
 
@@ -153,7 +156,9 @@ out_up:
        return count;
 }
 
-static ssize_t w1_default_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
+static ssize_t w1_default_read(struct kobject *kobj,
+                              struct bin_attribute *bin_attr,
+                              char *buf, loff_t off, size_t count)
 {
        struct w1_slave *sl = kobj_to_w1_slave(kobj);
 
@@ -167,7 +172,6 @@ static struct bin_attribute w1_default_attr = {
       .attr = {
               .name = "rw",
               .mode = S_IRUGO | S_IWUSR,
-              .owner = THIS_MODULE,
       },
       .size = PAGE_SIZE,
       .read = w1_default_read,
index 1e2ac40c2c14a3c93894a1a15c1e741a8416b6ac..ef1e1dafa19a36c61a24d2fa126d9f9bd4cda118 100644 (file)
@@ -33,6 +33,7 @@
 #define W1_THERM_DS1822        0x22
 #define W1_EEPROM_DS2433       0x23
 #define W1_THERM_DS18B20       0x28
+#define W1_FAMILY_DS2760       0x30
 
 #define MAXNAMELEN             32
 
index c3ba0ec334c45a419513343d7abd505633364482..9130f1c12c265887d02633ef932fe31fadc5526f 100644 (file)
@@ -49,8 +49,9 @@ static ssize_t zorro_show_resource(struct device *dev, struct device_attribute *
 
 static DEVICE_ATTR(resource, S_IRUGO, zorro_show_resource, NULL);
 
-static ssize_t zorro_read_config(struct kobject *kobj, char *buf, loff_t off,
-                                size_t count)
+static ssize_t zorro_read_config(struct kobject *kobj,
+                                struct bin_attribute *bin_attr,
+                                char *buf, loff_t off, size_t count)
 {
        struct zorro_dev *z = to_zorro_dev(container_of(kobj, struct device,
                                           kobj));
@@ -78,7 +79,6 @@ static struct bin_attribute zorro_config_attr = {
        .attr = {
                .name = "config",
                .mode = S_IRUGO | S_IWUSR,
-               .owner = THIS_MODULE
        },
        .size = sizeof(struct ConfigDev),
        .read = zorro_read_config,
index f544a285592343d4ac4cb9d1455a2c4e602cc2b9..36e381c6a99a69a761973cf3e61c38f226e00ee3 100644 (file)
@@ -33,7 +33,7 @@ const struct file_operations adfs_file_operations = {
        .fsync          = file_fsync,
        .write          = do_sync_write,
        .aio_write      = generic_file_aio_write,
-       .sendfile       = generic_file_sendfile,
+       .splice_read    = generic_file_splice_read,
 };
 
 const struct inode_operations adfs_file_inode_operations = {
index c8796906f584bdb2bffe406e186b4f17e6aa5c75..c314a35f09187bac060460a2fe948b4434f36c71 100644 (file)
@@ -35,7 +35,7 @@ const struct file_operations affs_file_operations = {
        .open           = affs_file_open,
        .release        = affs_file_release,
        .fsync          = file_fsync,
-       .sendfile       = generic_file_sendfile,
+       .splice_read    = generic_file_splice_read,
 };
 
 const struct inode_operations affs_file_inode_operations = {
index 9c0e721d9fc219fff078507b879b92b7ae41b1fb..aede7eb66dd4f970a74021b41487a5a0a70c0616 100644 (file)
@@ -32,7 +32,7 @@ const struct file_operations afs_file_operations = {
        .aio_read       = generic_file_aio_read,
        .aio_write      = afs_file_write,
        .mmap           = generic_file_readonly_mmap,
-       .sendfile       = generic_file_sendfile,
+       .splice_read    = generic_file_splice_read,
        .fsync          = afs_fsync,
 };
 
index 329ee473eede9514d2b6511aa9d41fc3e3884beb..521ff7caadbd687ada5ed347edc696d70168392f 100644 (file)
@@ -114,12 +114,6 @@ static int bad_file_lock(struct file *file, int cmd, struct file_lock *fl)
        return -EIO;
 }
 
-static ssize_t bad_file_sendfile(struct file *in_file, loff_t *ppos,
-                       size_t count, read_actor_t actor, void *target)
-{
-       return -EIO;
-}
-
 static ssize_t bad_file_sendpage(struct file *file, struct page *page,
                        int off, size_t len, loff_t *pos, int more)
 {
@@ -182,7 +176,6 @@ static const struct file_operations bad_file_ops =
        .aio_fsync      = bad_file_aio_fsync,
        .fasync         = bad_file_fasync,
        .lock           = bad_file_lock,
-       .sendfile       = bad_file_sendfile,
        .sendpage       = bad_file_sendpage,
        .get_unmapped_area = bad_file_get_unmapped_area,
        .check_flags    = bad_file_check_flags,
index ef4d1fa04e654f3f792840cff4db34ab82b9a1f0..24310e9ee05ad343245c0d9e881f150006c8e69f 100644 (file)
@@ -24,7 +24,7 @@ const struct file_operations bfs_file_operations = {
        .write          = do_sync_write,
        .aio_write      = generic_file_aio_write,
        .mmap           = generic_file_mmap,
-       .sendfile       = generic_file_sendfile,
+       .splice_read    = generic_file_splice_read,
 };
 
 static int bfs_move_block(unsigned long from, unsigned long to, struct super_block *sb)
index 093345f00128b841cd7a4026378f1021e2e9785d..33e46340a76666ebca0bc1b8aa3a40f44d6d1535 100644 (file)
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -1223,8 +1223,6 @@ EXPORT_SYMBOL(bio_hw_segments);
 EXPORT_SYMBOL(bio_add_page);
 EXPORT_SYMBOL(bio_add_pc_page);
 EXPORT_SYMBOL(bio_get_nr_vecs);
-EXPORT_SYMBOL(bio_map_user);
-EXPORT_SYMBOL(bio_unmap_user);
 EXPORT_SYMBOL(bio_map_kern);
 EXPORT_SYMBOL(bio_pair_release);
 EXPORT_SYMBOL(bio_split);
index ea1480a16f517d85d12de02bfde8afa53a43037c..b3e9bfa748cf99971567913492428524aa847e2b 100644 (file)
@@ -1346,7 +1346,6 @@ const struct file_operations def_blk_fops = {
 #ifdef CONFIG_COMPAT
        .compat_ioctl   = compat_blkdev_ioctl,
 #endif
-       .sendfile       = generic_file_sendfile,
        .splice_read    = generic_file_splice_read,
        .splice_write   = generic_file_splice_write,
 };
index 7c04752b76cb88f1678e3f76cd4a2642a4a1a929..8b0cbf4a4ad0aa33dfecf6100afeb139151e5b03 100644 (file)
@@ -616,7 +616,7 @@ const struct file_operations cifs_file_ops = {
        .fsync = cifs_fsync,
        .flush = cifs_flush,
        .mmap  = cifs_file_mmap,
-       .sendfile = generic_file_sendfile,
+       .splice_read = generic_file_splice_read,
        .llseek = cifs_llseek,
 #ifdef CONFIG_CIFS_POSIX
        .ioctl  = cifs_ioctl,
@@ -637,7 +637,7 @@ const struct file_operations cifs_file_direct_ops = {
        .lock = cifs_lock,
        .fsync = cifs_fsync,
        .flush = cifs_flush,
-       .sendfile = generic_file_sendfile, /* BB removeme BB */
+       .splice_read = generic_file_splice_read,
 #ifdef CONFIG_CIFS_POSIX
        .ioctl  = cifs_ioctl,
 #endif /* CONFIG_CIFS_POSIX */
@@ -656,7 +656,7 @@ const struct file_operations cifs_file_nobrl_ops = {
        .fsync = cifs_fsync,
        .flush = cifs_flush,
        .mmap  = cifs_file_mmap,
-       .sendfile = generic_file_sendfile,
+       .splice_read = generic_file_splice_read,
        .llseek = cifs_llseek,
 #ifdef CONFIG_CIFS_POSIX
        .ioctl  = cifs_ioctl,
@@ -676,7 +676,7 @@ const struct file_operations cifs_file_direct_nobrl_ops = {
        .release = cifs_close,
        .fsync = cifs_fsync,
        .flush = cifs_flush,
-       .sendfile = generic_file_sendfile, /* BB removeme BB */
+       .splice_read = generic_file_splice_read,
 #ifdef CONFIG_CIFS_POSIX
        .ioctl  = cifs_ioctl,
 #endif /* CONFIG_CIFS_POSIX */
index 5ef2b609ec7dd3164f3f70bfac44a281105f2691..99dbe866816d277ba5c90ccbf04ff92567725bee 100644 (file)
@@ -47,8 +47,9 @@ coda_file_read(struct file *coda_file, char __user *buf, size_t count, loff_t *p
 }
 
 static ssize_t
-coda_file_sendfile(struct file *coda_file, loff_t *ppos, size_t count,
-                  read_actor_t actor, void *target)
+coda_file_splice_read(struct file *coda_file, loff_t *ppos,
+                     struct pipe_inode_info *pipe, size_t count,
+                     unsigned int flags)
 {
        struct coda_file_info *cfi;
        struct file *host_file;
@@ -57,10 +58,10 @@ coda_file_sendfile(struct file *coda_file, loff_t *ppos, size_t count,
        BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
        host_file = cfi->cfi_container;
 
-       if (!host_file->f_op || !host_file->f_op->sendfile)
+       if (!host_file->f_op || !host_file->f_op->splice_read)
                return -EINVAL;
 
-       return host_file->f_op->sendfile(host_file, ppos, count, actor, target);
+       return host_file->f_op->splice_read(host_file, ppos, pipe, count,flags);
 }
 
 static ssize_t
@@ -295,6 +296,6 @@ const struct file_operations coda_file_operations = {
        .flush          = coda_flush,
        .release        = coda_release,
        .fsync          = coda_fsync,
-       .sendfile       = coda_file_sendfile,
+       .splice_read    = coda_file_splice_read,
 };
 
index ec8896b264de53759f119769cf158daacb1d068c..1d533a2ec3a6df41433ba9662c4d3867097902f5 100644 (file)
@@ -368,6 +368,69 @@ void debugfs_remove(struct dentry *dentry)
 }
 EXPORT_SYMBOL_GPL(debugfs_remove);
 
+/**
+ * debugfs_rename - rename a file/directory in the debugfs filesystem
+ * @old_dir: a pointer to the parent dentry for the renamed object. This
+ *          should be a directory dentry.
+ * @old_dentry: dentry of an object to be renamed.
+ * @new_dir: a pointer to the parent dentry where the object should be
+ *          moved. This should be a directory dentry.
+ * @new_name: a pointer to a string containing the target name.
+ *
+ * This function renames a file/directory in debugfs.  The target must not
+ * exist for rename to succeed.
+ *
+ * This function will return a pointer to old_dentry (which is updated to
+ * reflect renaming) if it succeeds. If an error occurs, %NULL will be
+ * returned.
+ *
+ * If debugfs is not enabled in the kernel, the value -%ENODEV will be
+ * returned.
+ */
+struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
+               struct dentry *new_dir, const char *new_name)
+{
+       int error;
+       struct dentry *dentry = NULL, *trap;
+       const char *old_name;
+
+       trap = lock_rename(new_dir, old_dir);
+       /* Source or destination directories don't exist? */
+       if (!old_dir->d_inode || !new_dir->d_inode)
+               goto exit;
+       /* Source does not exist, cyclic rename, or mountpoint? */
+       if (!old_dentry->d_inode || old_dentry == trap ||
+           d_mountpoint(old_dentry))
+               goto exit;
+       dentry = lookup_one_len(new_name, new_dir, strlen(new_name));
+       /* Lookup failed, cyclic rename or target exists? */
+       if (IS_ERR(dentry) || dentry == trap || dentry->d_inode)
+               goto exit;
+
+       old_name = fsnotify_oldname_init(old_dentry->d_name.name);
+
+       error = simple_rename(old_dir->d_inode, old_dentry, new_dir->d_inode,
+               dentry);
+       if (error) {
+               fsnotify_oldname_free(old_name);
+               goto exit;
+       }
+       d_move(old_dentry, dentry);
+       fsnotify_move(old_dir->d_inode, new_dir->d_inode, old_name,
+               old_dentry->d_name.name, S_ISDIR(old_dentry->d_inode->i_mode),
+               NULL, old_dentry->d_inode);
+       fsnotify_oldname_free(old_name);
+       unlock_rename(new_dir, old_dir);
+       dput(dentry);
+       return old_dentry;
+exit:
+       if (dentry && !IS_ERR(dentry))
+               dput(dentry);
+       unlock_rename(new_dir, old_dir);
+       return NULL;
+}
+EXPORT_SYMBOL_GPL(debugfs_rename);
+
 static decl_subsys(debug, NULL, NULL);
 
 static int __init debugfs_init(void)
index 604cf7dc5f39856e558b8f8362867e1aaf12323f..d248e60951bac0ce8d04b19f291e380814f3826c 100644 (file)
@@ -8,6 +8,7 @@ dlm-y :=                        ast.o \
                                member.o \
                                memory.o \
                                midcomms.o \
+                               netlink.o \
                                lowcomms.o \
                                rcom.o \
                                recover.o \
index 822abdcd1434ad94638b6ec652e5720bddd74532..5069b2cb5a1f6e3fe109d148e3a7e8cd8b0930c7 100644 (file)
@@ -90,6 +90,7 @@ struct cluster {
        unsigned int cl_scan_secs;
        unsigned int cl_log_debug;
        unsigned int cl_protocol;
+       unsigned int cl_timewarn_cs;
 };
 
 enum {
@@ -103,6 +104,7 @@ enum {
        CLUSTER_ATTR_SCAN_SECS,
        CLUSTER_ATTR_LOG_DEBUG,
        CLUSTER_ATTR_PROTOCOL,
+       CLUSTER_ATTR_TIMEWARN_CS,
 };
 
 struct cluster_attribute {
@@ -162,6 +164,7 @@ CLUSTER_ATTR(toss_secs, 1);
 CLUSTER_ATTR(scan_secs, 1);
 CLUSTER_ATTR(log_debug, 0);
 CLUSTER_ATTR(protocol, 0);
+CLUSTER_ATTR(timewarn_cs, 1);
 
 static struct configfs_attribute *cluster_attrs[] = {
        [CLUSTER_ATTR_TCP_PORT] = &cluster_attr_tcp_port.attr,
@@ -174,6 +177,7 @@ static struct configfs_attribute *cluster_attrs[] = {
        [CLUSTER_ATTR_SCAN_SECS] = &cluster_attr_scan_secs.attr,
        [CLUSTER_ATTR_LOG_DEBUG] = &cluster_attr_log_debug.attr,
        [CLUSTER_ATTR_PROTOCOL] = &cluster_attr_protocol.attr,
+       [CLUSTER_ATTR_TIMEWARN_CS] = &cluster_attr_timewarn_cs.attr,
        NULL,
 };
 
@@ -429,6 +433,8 @@ static struct config_group *make_cluster(struct config_group *g,
        cl->cl_toss_secs = dlm_config.ci_toss_secs;
        cl->cl_scan_secs = dlm_config.ci_scan_secs;
        cl->cl_log_debug = dlm_config.ci_log_debug;
+       cl->cl_protocol = dlm_config.ci_protocol;
+       cl->cl_timewarn_cs = dlm_config.ci_timewarn_cs;
 
        space_list = &sps->ss_group;
        comm_list = &cms->cs_group;
@@ -748,9 +754,16 @@ static ssize_t node_weight_write(struct node *nd, const char *buf, size_t len)
 
 static struct space *get_space(char *name)
 {
+       struct config_item *i;
+
        if (!space_list)
                return NULL;
-       return to_space(config_group_find_obj(space_list, name));
+
+       down(&space_list->cg_subsys->su_sem);
+       i = config_group_find_obj(space_list, name);
+       up(&space_list->cg_subsys->su_sem);
+
+       return to_space(i);
 }
 
 static void put_space(struct space *sp)
@@ -776,20 +789,20 @@ static struct comm *get_comm(int nodeid, struct sockaddr_storage *addr)
                        if (cm->nodeid != nodeid)
                                continue;
                        found = 1;
+                       config_item_get(i);
                        break;
                } else {
                        if (!cm->addr_count ||
                            memcmp(cm->addr[0], addr, sizeof(*addr)))
                                continue;
                        found = 1;
+                       config_item_get(i);
                        break;
                }
        }
        up(&clusters_root.subsys.su_sem);
 
-       if (found)
-               config_item_get(i);
-       else
+       if (!found)
                cm = NULL;
        return cm;
 }
@@ -909,6 +922,7 @@ int dlm_our_addr(struct sockaddr_storage *addr, int num)
 #define DEFAULT_SCAN_SECS          5
 #define DEFAULT_LOG_DEBUG          0
 #define DEFAULT_PROTOCOL           0
+#define DEFAULT_TIMEWARN_CS      500 /* 5 sec = 500 centiseconds */
 
 struct dlm_config_info dlm_config = {
        .ci_tcp_port = DEFAULT_TCP_PORT,
@@ -920,6 +934,7 @@ struct dlm_config_info dlm_config = {
        .ci_toss_secs = DEFAULT_TOSS_SECS,
        .ci_scan_secs = DEFAULT_SCAN_SECS,
        .ci_log_debug = DEFAULT_LOG_DEBUG,
-       .ci_protocol = DEFAULT_PROTOCOL
+       .ci_protocol = DEFAULT_PROTOCOL,
+       .ci_timewarn_cs = DEFAULT_TIMEWARN_CS
 };
 
index 967cc3d72e5e844a893eb2aab1bf7e23ef966fb3..a3170fe22090589198b21dd6cb7476ff397229ca 100644 (file)
@@ -27,6 +27,7 @@ struct dlm_config_info {
        int ci_scan_secs;
        int ci_log_debug;
        int ci_protocol;
+       int ci_timewarn_cs;
 };
 
 extern struct dlm_config_info dlm_config;
index 61ba670b9e025fde7f8cedb28fd96ceee483de67..12c3bfd5e660fca4ebfac6e1b4146ccc1d9640f5 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/debugfs.h>
 
 #include "dlm_internal.h"
+#include "lock.h"
 
 #define DLM_DEBUG_BUF_LEN 4096
 static char debug_buf[DLM_DEBUG_BUF_LEN];
@@ -26,6 +27,8 @@ static struct dentry *dlm_root;
 
 struct rsb_iter {
        int entry;
+       int locks;
+       int header;
        struct dlm_ls *ls;
        struct list_head *next;
        struct dlm_rsb *rsb;
@@ -57,8 +60,8 @@ static char *print_lockmode(int mode)
        }
 }
 
-static void print_lock(struct seq_file *s, struct dlm_lkb *lkb,
-                      struct dlm_rsb *res)
+static void print_resource_lock(struct seq_file *s, struct dlm_lkb *lkb,
+                               struct dlm_rsb *res)
 {
        seq_printf(s, "%08x %s", lkb->lkb_id, print_lockmode(lkb->lkb_grmode));
 
@@ -85,6 +88,8 @@ static int print_resource(struct dlm_rsb *res, struct seq_file *s)
        struct dlm_lkb *lkb;
        int i, lvblen = res->res_ls->ls_lvblen, recover_list, root_list;
 
+       lock_rsb(res);
+
        seq_printf(s, "\nResource %p Name (len=%d) \"", res, res->res_length);
        for (i = 0; i < res->res_length; i++) {
                if (isprint(res->res_name[i]))
@@ -129,15 +134,15 @@ static int print_resource(struct dlm_rsb *res, struct seq_file *s)
        /* Print the locks attached to this resource */
        seq_printf(s, "Granted Queue\n");
        list_for_each_entry(lkb, &res->res_grantqueue, lkb_statequeue)
-               print_lock(s, lkb, res);
+               print_resource_lock(s, lkb, res);
 
        seq_printf(s, "Conversion Queue\n");
        list_for_each_entry(lkb, &res->res_convertqueue, lkb_statequeue)
-               print_lock(s, lkb, res);
+               print_resource_lock(s, lkb, res);
 
        seq_printf(s, "Waiting Queue\n");
        list_for_each_entry(lkb, &res->res_waitqueue, lkb_statequeue)
-               print_lock(s, lkb, res);
+               print_resource_lock(s, lkb, res);
 
        if (list_empty(&res->res_lookup))
                goto out;
@@ -151,6 +156,61 @@ static int print_resource(struct dlm_rsb *res, struct seq_file *s)
                seq_printf(s, "\n");
        }
  out:
+       unlock_rsb(res);
+       return 0;
+}
+
+static void print_lock(struct seq_file *s, struct dlm_lkb *lkb, struct dlm_rsb *r)
+{
+       struct dlm_user_args *ua;
+       unsigned int waiting = 0;
+       uint64_t xid = 0;
+
+       if (lkb->lkb_flags & DLM_IFL_USER) {
+               ua = (struct dlm_user_args *) lkb->lkb_astparam;
+               if (ua)
+                       xid = ua->xid;
+       }
+
+       if (lkb->lkb_timestamp)
+               waiting = jiffies_to_msecs(jiffies - lkb->lkb_timestamp);
+
+       /* id nodeid remid pid xid exflags flags sts grmode rqmode time_ms
+          r_nodeid r_len r_name */
+
+       seq_printf(s, "%x %d %x %u %llu %x %x %d %d %d %u %u %d \"%s\"\n",
+                  lkb->lkb_id,
+                  lkb->lkb_nodeid,
+                  lkb->lkb_remid,
+                  lkb->lkb_ownpid,
+                  (unsigned long long)xid,
+                  lkb->lkb_exflags,
+                  lkb->lkb_flags,
+                  lkb->lkb_status,
+                  lkb->lkb_grmode,
+                  lkb->lkb_rqmode,
+                  waiting,
+                  r->res_nodeid,
+                  r->res_length,
+                  r->res_name);
+}
+
+static int print_locks(struct dlm_rsb *r, struct seq_file *s)
+{
+       struct dlm_lkb *lkb;
+
+       lock_rsb(r);
+
+       list_for_each_entry(lkb, &r->res_grantqueue, lkb_statequeue)
+               print_lock(s, lkb, r);
+
+       list_for_each_entry(lkb, &r->res_convertqueue, lkb_statequeue)
+               print_lock(s, lkb, r);
+
+       list_for_each_entry(lkb, &r->res_waitqueue, lkb_statequeue)
+               print_lock(s, lkb, r);
+
+       unlock_rsb(r);
        return 0;
 }
 
@@ -166,6 +226,9 @@ static int rsb_iter_next(struct rsb_iter *ri)
                        read_lock(&ls->ls_rsbtbl[i].lock);
                        if (!list_empty(&ls->ls_rsbtbl[i].list)) {
                                ri->next = ls->ls_rsbtbl[i].list.next;
+                               ri->rsb = list_entry(ri->next, struct dlm_rsb,
+                                                       res_hashchain);
+                               dlm_hold_rsb(ri->rsb);
                                read_unlock(&ls->ls_rsbtbl[i].lock);
                                break;
                        }
@@ -176,6 +239,7 @@ static int rsb_iter_next(struct rsb_iter *ri)
                if (ri->entry >= ls->ls_rsbtbl_size)
                        return 1;
        } else {
+               struct dlm_rsb *old = ri->rsb;
                i = ri->entry;
                read_lock(&ls->ls_rsbtbl[i].lock);
                ri->next = ri->next->next;
@@ -184,11 +248,14 @@ static int rsb_iter_next(struct rsb_iter *ri)
                        ri->next = NULL;
                        ri->entry++;
                        read_unlock(&ls->ls_rsbtbl[i].lock);
+                       dlm_put_rsb(old);
                        goto top;
                 }
+               ri->rsb = list_entry(ri->next, struct dlm_rsb, res_hashchain);
+               dlm_hold_rsb(ri->rsb);
                read_unlock(&ls->ls_rsbtbl[i].lock);
+               dlm_put_rsb(old);
        }
-       ri->rsb = list_entry(ri->next, struct dlm_rsb, res_hashchain);
 
        return 0;
 }
@@ -202,7 +269,7 @@ static struct rsb_iter *rsb_iter_init(struct dlm_ls *ls)
 {
        struct rsb_iter *ri;
 
-       ri = kmalloc(sizeof *ri, GFP_KERNEL);
+       ri = kzalloc(sizeof *ri, GFP_KERNEL);
        if (!ri)
                return NULL;
 
@@ -260,7 +327,17 @@ static int rsb_seq_show(struct seq_file *file, void *iter_ptr)
 {
        struct rsb_iter *ri = iter_ptr;
 
-       print_resource(ri->rsb, file);
+       if (ri->locks) {
+               if (ri->header) {
+                       seq_printf(file, "id nodeid remid pid xid exflags flags "
+                                        "sts grmode rqmode time_ms r_nodeid "
+                                        "r_len r_name\n");
+                       ri->header = 0;
+               }
+               print_locks(ri->rsb, file);
+       } else {
+               print_resource(ri->rsb, file);
+       }
 
        return 0;
 }
@@ -295,6 +372,83 @@ static const struct file_operations rsb_fops = {
        .release = seq_release
 };
 
+/*
+ * Dump state in compact per-lock listing
+ */
+
+static struct rsb_iter *locks_iter_init(struct dlm_ls *ls, loff_t *pos)
+{
+       struct rsb_iter *ri;
+
+       ri = kzalloc(sizeof *ri, GFP_KERNEL);
+       if (!ri)
+               return NULL;
+
+       ri->ls = ls;
+       ri->entry = 0;
+       ri->next = NULL;
+       ri->locks = 1;
+
+       if (*pos == 0)
+               ri->header = 1;
+
+       if (rsb_iter_next(ri)) {
+               rsb_iter_free(ri);
+               return NULL;
+       }
+
+       return ri;
+}
+
+static void *locks_seq_start(struct seq_file *file, loff_t *pos)
+{
+       struct rsb_iter *ri;
+       loff_t n = *pos;
+
+       ri = locks_iter_init(file->private, pos);
+       if (!ri)
+               return NULL;
+
+       while (n--) {
+               if (rsb_iter_next(ri)) {
+                       rsb_iter_free(ri);
+                       return NULL;
+               }
+       }
+
+       return ri;
+}
+
+static struct seq_operations locks_seq_ops = {
+       .start = locks_seq_start,
+       .next  = rsb_seq_next,
+       .stop  = rsb_seq_stop,
+       .show  = rsb_seq_show,
+};
+
+static int locks_open(struct inode *inode, struct file *file)
+{
+       struct seq_file *seq;
+       int ret;
+
+       ret = seq_open(file, &locks_seq_ops);
+       if (ret)
+               return ret;
+
+       seq = file->private_data;
+       seq->private = inode->i_private;
+
+       return 0;
+}
+
+static const struct file_operations locks_fops = {
+       .owner   = THIS_MODULE,
+       .open    = locks_open,
+       .read    = seq_read,
+       .llseek  = seq_lseek,
+       .release = seq_release
+};
+
 /*
  * dump lkb's on the ls_waiters list
  */
@@ -362,6 +516,20 @@ int dlm_create_debug_file(struct dlm_ls *ls)
                return -ENOMEM;
        }
 
+       memset(name, 0, sizeof(name));
+       snprintf(name, DLM_LOCKSPACE_LEN+8, "%s_locks", ls->ls_name);
+
+       ls->ls_debug_locks_dentry = debugfs_create_file(name,
+                                                       S_IFREG | S_IRUGO,
+                                                       dlm_root,
+                                                       ls,
+                                                       &locks_fops);
+       if (!ls->ls_debug_locks_dentry) {
+               debugfs_remove(ls->ls_debug_waiters_dentry);
+               debugfs_remove(ls->ls_debug_rsb_dentry);
+               return -ENOMEM;
+       }
+
        return 0;
 }
 
@@ -371,6 +539,8 @@ void dlm_delete_debug_file(struct dlm_ls *ls)
                debugfs_remove(ls->ls_debug_rsb_dentry);
        if (ls->ls_debug_waiters_dentry)
                debugfs_remove(ls->ls_debug_waiters_dentry);
+       if (ls->ls_debug_locks_dentry)
+               debugfs_remove(ls->ls_debug_locks_dentry);
 }
 
 int dlm_register_debugfs(void)
index 30994d68f6a078d7e87e0a46429093b11fc4f631..74901e981e1089363bdc501fefc9c4ed106c70bb 100644 (file)
@@ -151,6 +151,7 @@ struct dlm_args {
        void                    *bastaddr;
        int                     mode;
        struct dlm_lksb         *lksb;
+       unsigned long           timeout;
 };
 
 
@@ -213,6 +214,9 @@ struct dlm_args {
 #define DLM_IFL_OVERLAP_UNLOCK  0x00080000
 #define DLM_IFL_OVERLAP_CANCEL  0x00100000
 #define DLM_IFL_ENDOFLIFE      0x00200000
+#define DLM_IFL_WATCH_TIMEWARN 0x00400000
+#define DLM_IFL_TIMEOUT_CANCEL 0x00800000
+#define DLM_IFL_DEADLOCK_CANCEL        0x01000000
 #define DLM_IFL_USER           0x00000001
 #define DLM_IFL_ORPHAN         0x00000002
 
@@ -243,6 +247,9 @@ struct dlm_lkb {
        struct list_head        lkb_wait_reply; /* waiting for remote reply */
        struct list_head        lkb_astqueue;   /* need ast to be sent */
        struct list_head        lkb_ownqueue;   /* list of locks for a process */
+       struct list_head        lkb_time_list;
+       unsigned long           lkb_timestamp;
+       unsigned long           lkb_timeout_cs;
 
        char                    *lkb_lvbptr;
        struct dlm_lksb         *lkb_lksb;      /* caller's status block */
@@ -447,12 +454,16 @@ struct dlm_ls {
        struct mutex            ls_orphans_mutex;
        struct list_head        ls_orphans;
 
+       struct mutex            ls_timeout_mutex;
+       struct list_head        ls_timeout;
+
        struct list_head        ls_nodes;       /* current nodes in ls */
        struct list_head        ls_nodes_gone;  /* dead node list, recovery */
        int                     ls_num_nodes;   /* number of nodes in ls */
        int                     ls_low_nodeid;
        int                     ls_total_weight;
        int                     *ls_node_array;
+       gfp_t                   ls_allocation;
 
        struct dlm_rsb          ls_stub_rsb;    /* for returning errors */
        struct dlm_lkb          ls_stub_lkb;    /* for returning errors */
@@ -460,9 +471,12 @@ struct dlm_ls {
 
        struct dentry           *ls_debug_rsb_dentry; /* debugfs */
        struct dentry           *ls_debug_waiters_dentry; /* debugfs */
+       struct dentry           *ls_debug_locks_dentry; /* debugfs */
 
        wait_queue_head_t       ls_uevent_wait; /* user part of join/leave */
        int                     ls_uevent_result;
+       struct completion       ls_members_done;
+       int                     ls_members_result;
 
        struct miscdevice       ls_device;
 
@@ -472,6 +486,7 @@ struct dlm_ls {
        struct task_struct      *ls_recoverd_task;
        struct mutex            ls_recoverd_active;
        spinlock_t              ls_recover_lock;
+       unsigned long           ls_recover_begin; /* jiffies timestamp */
        uint32_t                ls_recover_status; /* DLM_RS_ */
        uint64_t                ls_recover_seq;
        struct dlm_recover      *ls_recover_args;
@@ -501,6 +516,7 @@ struct dlm_ls {
 #define LSFL_RCOM_READY                3
 #define LSFL_RCOM_WAIT         4
 #define LSFL_UEVENT_WAIT       5
+#define LSFL_TIMEWARN          6
 
 /* much of this is just saving user space pointers associated with the
    lock that we pass back to the user lib with an ast */
@@ -518,6 +534,7 @@ struct dlm_user_args {
        void __user             *castaddr;
        void __user             *bastparam;
        void __user             *bastaddr;
+       uint64_t                xid;
 };
 
 #define DLM_PROC_FLAGS_CLOSING 1
index d8d6e729f96b669b5a6ed16bfb92c776cfc4744c..b455919c19984ad408d4ca498ad72f40a7d33d1f 100644 (file)
@@ -82,10 +82,13 @@ static int send_bast(struct dlm_rsb *r, struct dlm_lkb *lkb, int mode);
 static int send_lookup(struct dlm_rsb *r, struct dlm_lkb *lkb);
 static int send_remove(struct dlm_rsb *r);
 static int _request_lock(struct dlm_rsb *r, struct dlm_lkb *lkb);
+static int _cancel_lock(struct dlm_rsb *r, struct dlm_lkb *lkb);
 static void __receive_convert_reply(struct dlm_rsb *r, struct dlm_lkb *lkb,
                                    struct dlm_message *ms);
 static int receive_extralen(struct dlm_message *ms);
 static void do_purge(struct dlm_ls *ls, int nodeid, int pid);
+static void del_timeout(struct dlm_lkb *lkb);
+void dlm_timeout_warn(struct dlm_lkb *lkb);
 
 /*
  * Lock compatibilty matrix - thanks Steve
@@ -194,17 +197,17 @@ void dlm_dump_rsb(struct dlm_rsb *r)
 
 /* Threads cannot use the lockspace while it's being recovered */
 
-static inline void lock_recovery(struct dlm_ls *ls)
+static inline void dlm_lock_recovery(struct dlm_ls *ls)
 {
        down_read(&ls->ls_in_recovery);
 }
 
-static inline void unlock_recovery(struct dlm_ls *ls)
+void dlm_unlock_recovery(struct dlm_ls *ls)
 {
        up_read(&ls->ls_in_recovery);
 }
 
-static inline int lock_recovery_try(struct dlm_ls *ls)
+int dlm_lock_recovery_try(struct dlm_ls *ls)
 {
        return down_read_trylock(&ls->ls_in_recovery);
 }
@@ -286,8 +289,22 @@ static void queue_cast(struct dlm_rsb *r, struct dlm_lkb *lkb, int rv)
        if (is_master_copy(lkb))
                return;
 
+       del_timeout(lkb);
+
        DLM_ASSERT(lkb->lkb_lksb, dlm_print_lkb(lkb););
 
+       /* if the operation was a cancel, then return -DLM_ECANCEL, if a
+          timeout caused the cancel then return -ETIMEDOUT */
+       if (rv == -DLM_ECANCEL && (lkb->lkb_flags & DLM_IFL_TIMEOUT_CANCEL)) {
+               lkb->lkb_flags &= ~DLM_IFL_TIMEOUT_CANCEL;
+               rv = -ETIMEDOUT;
+       }
+
+       if (rv == -DLM_ECANCEL && (lkb->lkb_flags & DLM_IFL_DEADLOCK_CANCEL)) {
+               lkb->lkb_flags &= ~DLM_IFL_DEADLOCK_CANCEL;
+               rv = -EDEADLK;
+       }
+
        lkb->lkb_lksb->sb_status = rv;
        lkb->lkb_lksb->sb_flags = lkb->lkb_sbflags;
 
@@ -581,6 +598,7 @@ static int create_lkb(struct dlm_ls *ls, struct dlm_lkb **lkb_ret)
        kref_init(&lkb->lkb_ref);
        INIT_LIST_HEAD(&lkb->lkb_ownqueue);
        INIT_LIST_HEAD(&lkb->lkb_rsb_lookup);
+       INIT_LIST_HEAD(&lkb->lkb_time_list);
 
        get_random_bytes(&bucket, sizeof(bucket));
        bucket &= (ls->ls_lkbtbl_size - 1);
@@ -985,15 +1003,136 @@ void dlm_scan_rsbs(struct dlm_ls *ls)
 {
        int i;
 
-       if (dlm_locking_stopped(ls))
-               return;
-
        for (i = 0; i < ls->ls_rsbtbl_size; i++) {
                shrink_bucket(ls, i);
+               if (dlm_locking_stopped(ls))
+                       break;
                cond_resched();
        }
 }
 
+static void add_timeout(struct dlm_lkb *lkb)
+{
+       struct dlm_ls *ls = lkb->lkb_resource->res_ls;
+
+       if (is_master_copy(lkb)) {
+               lkb->lkb_timestamp = jiffies;
+               return;
+       }
+
+       if (test_bit(LSFL_TIMEWARN, &ls->ls_flags) &&
+           !(lkb->lkb_exflags & DLM_LKF_NODLCKWT)) {
+               lkb->lkb_flags |= DLM_IFL_WATCH_TIMEWARN;
+               goto add_it;
+       }
+       if (lkb->lkb_exflags & DLM_LKF_TIMEOUT)
+               goto add_it;
+       return;
+
+ add_it:
+       DLM_ASSERT(list_empty(&lkb->lkb_time_list), dlm_print_lkb(lkb););
+       mutex_lock(&ls->ls_timeout_mutex);
+       hold_lkb(lkb);
+       lkb->lkb_timestamp = jiffies;
+       list_add_tail(&lkb->lkb_time_list, &ls->ls_timeout);
+       mutex_unlock(&ls->ls_timeout_mutex);
+}
+
+static void del_timeout(struct dlm_lkb *lkb)
+{
+       struct dlm_ls *ls = lkb->lkb_resource->res_ls;
+
+       mutex_lock(&ls->ls_timeout_mutex);
+       if (!list_empty(&lkb->lkb_time_list)) {
+               list_del_init(&lkb->lkb_time_list);
+               unhold_lkb(lkb);
+       }
+       mutex_unlock(&ls->ls_timeout_mutex);
+}
+
+/* FIXME: is it safe to look at lkb_exflags, lkb_flags, lkb_timestamp, and
+   lkb_lksb_timeout without lock_rsb?  Note: we can't lock timeout_mutex
+   and then lock rsb because of lock ordering in add_timeout.  We may need
+   to specify some special timeout-related bits in the lkb that are just to
+   be accessed under the timeout_mutex. */
+
+void dlm_scan_timeout(struct dlm_ls *ls)
+{
+       struct dlm_rsb *r;
+       struct dlm_lkb *lkb;
+       int do_cancel, do_warn;
+
+       for (;;) {
+               if (dlm_locking_stopped(ls))
+                       break;
+
+               do_cancel = 0;
+               do_warn = 0;
+               mutex_lock(&ls->ls_timeout_mutex);
+               list_for_each_entry(lkb, &ls->ls_timeout, lkb_time_list) {
+
+                       if ((lkb->lkb_exflags & DLM_LKF_TIMEOUT) &&
+                           time_after_eq(jiffies, lkb->lkb_timestamp +
+                                         lkb->lkb_timeout_cs * HZ/100))
+                               do_cancel = 1;
+
+                       if ((lkb->lkb_flags & DLM_IFL_WATCH_TIMEWARN) &&
+                           time_after_eq(jiffies, lkb->lkb_timestamp +
+                                          dlm_config.ci_timewarn_cs * HZ/100))
+                               do_warn = 1;
+
+                       if (!do_cancel && !do_warn)
+                               continue;
+                       hold_lkb(lkb);
+                       break;
+               }
+               mutex_unlock(&ls->ls_timeout_mutex);
+
+               if (!do_cancel && !do_warn)
+                       break;
+
+               r = lkb->lkb_resource;
+               hold_rsb(r);
+               lock_rsb(r);
+
+               if (do_warn) {
+                       /* clear flag so we only warn once */
+                       lkb->lkb_flags &= ~DLM_IFL_WATCH_TIMEWARN;
+                       if (!(lkb->lkb_exflags & DLM_LKF_TIMEOUT))
+                               del_timeout(lkb);
+                       dlm_timeout_warn(lkb);
+               }
+
+               if (do_cancel) {
+                       log_debug(ls, "timeout cancel %x node %d %s",
+                                 lkb->lkb_id, lkb->lkb_nodeid, r->res_name);
+                       lkb->lkb_flags &= ~DLM_IFL_WATCH_TIMEWARN;
+                       lkb->lkb_flags |= DLM_IFL_TIMEOUT_CANCEL;
+                       del_timeout(lkb);
+                       _cancel_lock(r, lkb);
+               }
+
+               unlock_rsb(r);
+               unhold_rsb(r);
+               dlm_put_lkb(lkb);
+       }
+}
+
+/* This is only called by dlm_recoverd, and we rely on dlm_ls_stop() stopping
+   dlm_recoverd before checking/setting ls_recover_begin. */
+
+void dlm_adjust_timeouts(struct dlm_ls *ls)
+{
+       struct dlm_lkb *lkb;
+       long adj = jiffies - ls->ls_recover_begin;
+
+       ls->ls_recover_begin = 0;
+       mutex_lock(&ls->ls_timeout_mutex);
+       list_for_each_entry(lkb, &ls->ls_timeout, lkb_time_list)
+               lkb->lkb_timestamp += adj;
+       mutex_unlock(&ls->ls_timeout_mutex);
+}
+
 /* lkb is master or local copy */
 
 static void set_lvb_lock(struct dlm_rsb *r, struct dlm_lkb *lkb)
@@ -1275,10 +1414,8 @@ static int queue_conflict(struct list_head *head, struct dlm_lkb *lkb)
  * queue for one resource.  The granted mode of each lock blocks the requested
  * mode of the other lock."
  *
- * Part 2: if the granted mode of lkb is preventing the first lkb in the
- * convert queue from being granted, then demote lkb (set grmode to NL).
- * This second form requires that we check for conv-deadlk even when
- * now == 0 in _can_be_granted().
+ * Part 2: if the granted mode of lkb is preventing an earlier lkb in the
+ * convert queue from being granted, then deadlk/demote lkb.
  *
  * Example:
  * Granted Queue: empty
@@ -1287,41 +1424,52 @@ static int queue_conflict(struct list_head *head, struct dlm_lkb *lkb)
  *
  * The first lock can't be granted because of the granted mode of the second
  * lock and the second lock can't be granted because it's not first in the
- * list.  We demote the granted mode of the second lock (the lkb passed to this
- * function).
+ * list.  We either cancel lkb's conversion (PR->EX) and return EDEADLK, or we
+ * demote the granted mode of lkb (from PR to NL) if it has the CONVDEADLK
+ * flag set and return DEMOTED in the lksb flags.
+ *
+ * Originally, this function detected conv-deadlk in a more limited scope:
+ * - if !modes_compat(lkb1, lkb2) && !modes_compat(lkb2, lkb1), or
+ * - if lkb1 was the first entry in the queue (not just earlier), and was
+ *   blocked by the granted mode of lkb2, and there was nothing on the
+ *   granted queue preventing lkb1 from being granted immediately, i.e.
+ *   lkb2 was the only thing preventing lkb1 from being granted.
+ *
+ * That second condition meant we'd only say there was conv-deadlk if
+ * resolving it (by demotion) would lead to the first lock on the convert
+ * queue being granted right away.  It allowed conversion deadlocks to exist
+ * between locks on the convert queue while they couldn't be granted anyway.
  *
- * After the resolution, the "grant pending" function needs to go back and try
- * to grant locks on the convert queue again since the first lock can now be
- * granted.
+ * Now, we detect and take action on conversion deadlocks immediately when
+ * they're created, even if they may not be immediately consequential.  If
+ * lkb1 exists anywhere in the convert queue and lkb2 comes in with a granted
+ * mode that would prevent lkb1's conversion from being granted, we do a
+ * deadlk/demote on lkb2 right away and don't let it onto the convert queue.
+ * I think this means that the lkb_is_ahead condition below should always
+ * be zero, i.e. there will never be conv-deadlk between two locks that are
+ * both already on the convert queue.
  */
 
-static int conversion_deadlock_detect(struct dlm_rsb *rsb, struct dlm_lkb *lkb)
+static int conversion_deadlock_detect(struct dlm_rsb *r, struct dlm_lkb *lkb2)
 {
-       struct dlm_lkb *this, *first = NULL, *self = NULL;
+       struct dlm_lkb *lkb1;
+       int lkb_is_ahead = 0;
 
-       list_for_each_entry(this, &rsb->res_convertqueue, lkb_statequeue) {
-               if (!first)
-                       first = this;
-               if (this == lkb) {
-                       self = lkb;
+       list_for_each_entry(lkb1, &r->res_convertqueue, lkb_statequeue) {
+               if (lkb1 == lkb2) {
+                       lkb_is_ahead = 1;
                        continue;
                }
 
-               if (!modes_compat(this, lkb) && !modes_compat(lkb, this))
-                       return 1;
-       }
-
-       /* if lkb is on the convert queue and is preventing the first
-          from being granted, then there's deadlock and we demote lkb.
-          multiple converting locks may need to do this before the first
-          converting lock can be granted. */
-
-       if (self && self != first) {
-               if (!modes_compat(lkb, first) &&
-                   !queue_conflict(&rsb->res_grantqueue, first))
-                       return 1;
+               if (!lkb_is_ahead) {
+                       if (!modes_compat(lkb2, lkb1))
+                               return 1;
+               } else {
+                       if (!modes_compat(lkb2, lkb1) &&
+                           !modes_compat(lkb1, lkb2))
+                               return 1;
+               }
        }
-
        return 0;
 }
 
@@ -1450,42 +1598,57 @@ static int _can_be_granted(struct dlm_rsb *r, struct dlm_lkb *lkb, int now)
        if (!now && !conv && list_empty(&r->res_convertqueue) &&
            first_in_list(lkb, &r->res_waitqueue))
                return 1;
-
  out:
-       /*
-        * The following, enabled by CONVDEADLK, departs from VMS.
-        */
-
-       if (conv && (lkb->lkb_exflags & DLM_LKF_CONVDEADLK) &&
-           conversion_deadlock_detect(r, lkb)) {
-               lkb->lkb_grmode = DLM_LOCK_NL;
-               lkb->lkb_sbflags |= DLM_SBF_DEMOTED;
-       }
-
        return 0;
 }
 
-/*
- * The ALTPR and ALTCW flags aren't traditional lock manager flags, but are a
- * simple way to provide a big optimization to applications that can use them.
- */
-
-static int can_be_granted(struct dlm_rsb *r, struct dlm_lkb *lkb, int now)
+static int can_be_granted(struct dlm_rsb *r, struct dlm_lkb *lkb, int now,
+                         int *err)
 {
-       uint32_t flags = lkb->lkb_exflags;
        int rv;
        int8_t alt = 0, rqmode = lkb->lkb_rqmode;
+       int8_t is_convert = (lkb->lkb_grmode != DLM_LOCK_IV);
+
+       if (err)
+               *err = 0;
 
        rv = _can_be_granted(r, lkb, now);
        if (rv)
                goto out;
 
-       if (lkb->lkb_sbflags & DLM_SBF_DEMOTED)
+       /*
+        * The CONVDEADLK flag is non-standard and tells the dlm to resolve
+        * conversion deadlocks by demoting grmode to NL, otherwise the dlm
+        * cancels one of the locks.
+        */
+
+       if (is_convert && can_be_queued(lkb) &&
+           conversion_deadlock_detect(r, lkb)) {
+               if (lkb->lkb_exflags & DLM_LKF_CONVDEADLK) {
+                       lkb->lkb_grmode = DLM_LOCK_NL;
+                       lkb->lkb_sbflags |= DLM_SBF_DEMOTED;
+               } else if (!(lkb->lkb_exflags & DLM_LKF_NODLCKWT)) {
+                       if (err)
+                               *err = -EDEADLK;
+                       else {
+                               log_print("can_be_granted deadlock %x now %d",
+                                         lkb->lkb_id, now);
+                               dlm_dump_rsb(r);
+                       }
+               }
                goto out;
+       }
 
-       if (rqmode != DLM_LOCK_PR && flags & DLM_LKF_ALTPR)
+       /*
+        * The ALTPR and ALTCW flags are non-standard and tell the dlm to try
+        * to grant a request in a mode other than the normal rqmode.  It's a
+        * simple way to provide a big optimization to applications that can
+        * use them.
+        */
+
+       if (rqmode != DLM_LOCK_PR && (lkb->lkb_exflags & DLM_LKF_ALTPR))
                alt = DLM_LOCK_PR;
-       else if (rqmode != DLM_LOCK_CW && flags & DLM_LKF_ALTCW)
+       else if (rqmode != DLM_LOCK_CW && (lkb->lkb_exflags & DLM_LKF_ALTCW))
                alt = DLM_LOCK_CW;
 
        if (alt) {
@@ -1500,10 +1663,20 @@ static int can_be_granted(struct dlm_rsb *r, struct dlm_lkb *lkb, int now)
        return rv;
 }
 
+/* FIXME: I don't think that can_be_granted() can/will demote or find deadlock
+   for locks pending on the convert list.  Once verified (watch for these
+   log_prints), we should be able to just call _can_be_granted() and not
+   bother with the demote/deadlk cases here (and there's no easy way to deal
+   with a deadlk here, we'd have to generate something like grant_lock with
+   the deadlk error.) */
+
+/* returns the highest requested mode of all blocked conversions */
+
 static int grant_pending_convert(struct dlm_rsb *r, int high)
 {
        struct dlm_lkb *lkb, *s;
        int hi, demoted, quit, grant_restart, demote_restart;
+       int deadlk;
 
        quit = 0;
  restart:
@@ -1513,14 +1686,29 @@ static int grant_pending_convert(struct dlm_rsb *r, int high)
 
        list_for_each_entry_safe(lkb, s, &r->res_convertqueue, lkb_statequeue) {
                demoted = is_demoted(lkb);
-               if (can_be_granted(r, lkb, 0)) {
+               deadlk = 0;
+
+               if (can_be_granted(r, lkb, 0, &deadlk)) {
                        grant_lock_pending(r, lkb);
                        grant_restart = 1;
-               } else {
-                       hi = max_t(int, lkb->lkb_rqmode, hi);
-                       if (!demoted && is_demoted(lkb))
-                               demote_restart = 1;
+                       continue;
                }
+
+               if (!demoted && is_demoted(lkb)) {
+                       log_print("WARN: pending demoted %x node %d %s",
+                                 lkb->lkb_id, lkb->lkb_nodeid, r->res_name);
+                       demote_restart = 1;
+                       continue;
+               }
+
+               if (deadlk) {
+                       log_print("WARN: pending deadlock %x node %d %s",
+                                 lkb->lkb_id, lkb->lkb_nodeid, r->res_name);
+                       dlm_dump_rsb(r);
+                       continue;
+               }
+
+               hi = max_t(int, lkb->lkb_rqmode, hi);
        }
 
        if (grant_restart)
@@ -1538,7 +1726,7 @@ static int grant_pending_wait(struct dlm_rsb *r, int high)
        struct dlm_lkb *lkb, *s;
 
        list_for_each_entry_safe(lkb, s, &r->res_waitqueue, lkb_statequeue) {
-               if (can_be_granted(r, lkb, 0))
+               if (can_be_granted(r, lkb, 0, NULL))
                        grant_lock_pending(r, lkb);
                 else
                        high = max_t(int, lkb->lkb_rqmode, high);
@@ -1733,7 +1921,7 @@ static void confirm_master(struct dlm_rsb *r, int error)
 }
 
 static int set_lock_args(int mode, struct dlm_lksb *lksb, uint32_t flags,
-                        int namelen, uint32_t parent_lkid, void *ast,
+                        int namelen, unsigned long timeout_cs, void *ast,
                         void *astarg, void *bast, struct dlm_args *args)
 {
        int rv = -EINVAL;
@@ -1776,10 +1964,6 @@ static int set_lock_args(int mode, struct dlm_lksb *lksb, uint32_t flags,
        if (flags & DLM_LKF_VALBLK && !lksb->sb_lvbptr)
                goto out;
 
-       /* parent/child locks not yet supported */
-       if (parent_lkid)
-               goto out;
-
        if (flags & DLM_LKF_CONVERT && !lksb->sb_lkid)
                goto out;
 
@@ -1791,6 +1975,7 @@ static int set_lock_args(int mode, struct dlm_lksb *lksb, uint32_t flags,
        args->astaddr = ast;
        args->astparam = (long) astarg;
        args->bastaddr = bast;
+       args->timeout = timeout_cs;
        args->mode = mode;
        args->lksb = lksb;
        rv = 0;
@@ -1845,6 +2030,7 @@ static int validate_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
        lkb->lkb_lksb = args->lksb;
        lkb->lkb_lvbptr = args->lksb->sb_lvbptr;
        lkb->lkb_ownpid = (int) current->pid;
+       lkb->lkb_timeout_cs = args->timeout;
        rv = 0;
  out:
        return rv;
@@ -1903,6 +2089,9 @@ static int validate_unlock_args(struct dlm_lkb *lkb, struct dlm_args *args)
                if (is_overlap(lkb))
                        goto out;
 
+               /* don't let scand try to do a cancel */
+               del_timeout(lkb);
+
                if (lkb->lkb_flags & DLM_IFL_RESEND) {
                        lkb->lkb_flags |= DLM_IFL_OVERLAP_CANCEL;
                        rv = -EBUSY;
@@ -1934,6 +2123,9 @@ static int validate_unlock_args(struct dlm_lkb *lkb, struct dlm_args *args)
                if (is_overlap_unlock(lkb))
                        goto out;
 
+               /* don't let scand try to do a cancel */
+               del_timeout(lkb);
+
                if (lkb->lkb_flags & DLM_IFL_RESEND) {
                        lkb->lkb_flags |= DLM_IFL_OVERLAP_UNLOCK;
                        rv = -EBUSY;
@@ -1984,7 +2176,7 @@ static int do_request(struct dlm_rsb *r, struct dlm_lkb *lkb)
 {
        int error = 0;
 
-       if (can_be_granted(r, lkb, 1)) {
+       if (can_be_granted(r, lkb, 1, NULL)) {
                grant_lock(r, lkb);
                queue_cast(r, lkb, 0);
                goto out;
@@ -1994,6 +2186,7 @@ static int do_request(struct dlm_rsb *r, struct dlm_lkb *lkb)
                error = -EINPROGRESS;
                add_lkb(r, lkb, DLM_LKSTS_WAITING);
                send_blocking_asts(r, lkb);
+               add_timeout(lkb);
                goto out;
        }
 
@@ -2009,16 +2202,32 @@ static int do_request(struct dlm_rsb *r, struct dlm_lkb *lkb)
 static int do_convert(struct dlm_rsb *r, struct dlm_lkb *lkb)
 {
        int error = 0;
+       int deadlk = 0;
 
        /* changing an existing lock may allow others to be granted */
 
-       if (can_be_granted(r, lkb, 1)) {
+       if (can_be_granted(r, lkb, 1, &deadlk)) {
                grant_lock(r, lkb);
                queue_cast(r, lkb, 0);
                grant_pending_locks(r);
                goto out;
        }
 
+       /* can_be_granted() detected that this lock would block in a conversion
+          deadlock, so we leave it on the granted queue and return EDEADLK in
+          the ast for the convert. */
+
+       if (deadlk) {
+               /* it's left on the granted queue */
+               log_debug(r->res_ls, "deadlock %x node %d sts%d g%d r%d %s",
+                         lkb->lkb_id, lkb->lkb_nodeid, lkb->lkb_status,
+                         lkb->lkb_grmode, lkb->lkb_rqmode, r->res_name);
+               revert_lock(r, lkb);
+               queue_cast(r, lkb, -EDEADLK);
+               error = -EDEADLK;
+               goto out;
+       }
+
        /* is_demoted() means the can_be_granted() above set the grmode
           to NL, and left us on the granted queue.  This auto-demotion
           (due to CONVDEADLK) might mean other locks, and/or this lock, are
@@ -2041,6 +2250,7 @@ static int do_convert(struct dlm_rsb *r, struct dlm_lkb *lkb)
                del_lkb(r, lkb);
                add_lkb(r, lkb, DLM_LKSTS_CONVERT);
                send_blocking_asts(r, lkb);
+               add_timeout(lkb);
                goto out;
        }
 
@@ -2274,7 +2484,7 @@ int dlm_lock(dlm_lockspace_t *lockspace,
        if (!ls)
                return -EINVAL;
 
-       lock_recovery(ls);
+       dlm_lock_recovery(ls);
 
        if (convert)
                error = find_lkb(ls, lksb->sb_lkid, &lkb);
@@ -2284,7 +2494,7 @@ int dlm_lock(dlm_lockspace_t *lockspace,
        if (error)
                goto out;
 
-       error = set_lock_args(mode, lksb, flags, namelen, parent_lkid, ast,
+       error = set_lock_args(mode, lksb, flags, namelen, 0, ast,
                              astarg, bast, &args);
        if (error)
                goto out_put;
@@ -2299,10 +2509,10 @@ int dlm_lock(dlm_lockspace_t *lockspace,
  out_put:
        if (convert || error)
                __put_lkb(ls, lkb);
-       if (error == -EAGAIN)
+       if (error == -EAGAIN || error == -EDEADLK)
                error = 0;
  out:
-       unlock_recovery(ls);
+       dlm_unlock_recovery(ls);
        dlm_put_lockspace(ls);
        return error;
 }
@@ -2322,7 +2532,7 @@ int dlm_unlock(dlm_lockspace_t *lockspace,
        if (!ls)
                return -EINVAL;
 
-       lock_recovery(ls);
+       dlm_lock_recovery(ls);
 
        error = find_lkb(ls, lkid, &lkb);
        if (error)
@@ -2344,7 +2554,7 @@ int dlm_unlock(dlm_lockspace_t *lockspace,
  out_put:
        dlm_put_lkb(lkb);
  out:
-       unlock_recovery(ls);
+       dlm_unlock_recovery(ls);
        dlm_put_lockspace(ls);
        return error;
 }
@@ -2384,7 +2594,7 @@ static int _create_message(struct dlm_ls *ls, int mb_len,
           pass into lowcomms_commit and a message buffer (mb) that we
           write our data into */
 
-       mh = dlm_lowcomms_get_buffer(to_nodeid, mb_len, GFP_KERNEL, &mb);
+       mh = dlm_lowcomms_get_buffer(to_nodeid, mb_len, ls->ls_allocation, &mb);
        if (!mh)
                return -ENOBUFS;
 
@@ -3111,9 +3321,10 @@ static void receive_request_reply(struct dlm_ls *ls, struct dlm_message *ms)
                lkb->lkb_remid = ms->m_lkid;
                if (is_altmode(lkb))
                        munge_altmode(lkb, ms);
-               if (result)
+               if (result) {
                        add_lkb(r, lkb, DLM_LKSTS_WAITING);
-               else {
+                       add_timeout(lkb);
+               } else {
                        grant_lock_pc(r, lkb, ms);
                        queue_cast(r, lkb, 0);
                }
@@ -3172,6 +3383,12 @@ static void __receive_convert_reply(struct dlm_rsb *r, struct dlm_lkb *lkb,
                queue_cast(r, lkb, -EAGAIN);
                break;
 
+       case -EDEADLK:
+               receive_flags_reply(lkb, ms);
+               revert_lock_pc(r, lkb);
+               queue_cast(r, lkb, -EDEADLK);
+               break;
+
        case -EINPROGRESS:
                /* convert was queued on remote master */
                receive_flags_reply(lkb, ms);
@@ -3179,6 +3396,7 @@ static void __receive_convert_reply(struct dlm_rsb *r, struct dlm_lkb *lkb,
                        munge_demoted(lkb, ms);
                del_lkb(r, lkb);
                add_lkb(r, lkb, DLM_LKSTS_CONVERT);
+               add_timeout(lkb);
                break;
 
        case 0:
@@ -3298,8 +3516,7 @@ static void _receive_cancel_reply(struct dlm_lkb *lkb, struct dlm_message *ms)
        case -DLM_ECANCEL:
                receive_flags_reply(lkb, ms);
                revert_lock_pc(r, lkb);
-               if (ms->m_result)
-                       queue_cast(r, lkb, -DLM_ECANCEL);
+               queue_cast(r, lkb, -DLM_ECANCEL);
                break;
        case 0:
                break;
@@ -3424,7 +3641,7 @@ int dlm_receive_message(struct dlm_header *hd, int nodeid, int recovery)
                        }
                }
 
-               if (lock_recovery_try(ls))
+               if (dlm_lock_recovery_try(ls))
                        break;
                schedule();
        }
@@ -3503,7 +3720,7 @@ int dlm_receive_message(struct dlm_header *hd, int nodeid, int recovery)
                log_error(ls, "unknown message type %d", ms->m_type);
        }
 
-       unlock_recovery(ls);
+       dlm_unlock_recovery(ls);
  out:
        dlm_put_lockspace(ls);
        dlm_astd_wake();
@@ -4034,13 +4251,13 @@ int dlm_recover_process_copy(struct dlm_ls *ls, struct dlm_rcom *rc)
 
 int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua,
                     int mode, uint32_t flags, void *name, unsigned int namelen,
-                    uint32_t parent_lkid)
+                    unsigned long timeout_cs)
 {
        struct dlm_lkb *lkb;
        struct dlm_args args;
        int error;
 
-       lock_recovery(ls);
+       dlm_lock_recovery(ls);
 
        error = create_lkb(ls, &lkb);
        if (error) {
@@ -4062,7 +4279,7 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua,
           When DLM_IFL_USER is set, the dlm knows that this is a userspace
           lock and that lkb_astparam is the dlm_user_args structure. */
 
-       error = set_lock_args(mode, &ua->lksb, flags, namelen, parent_lkid,
+       error = set_lock_args(mode, &ua->lksb, flags, namelen, timeout_cs,
                              DLM_FAKE_USER_AST, ua, DLM_FAKE_USER_AST, &args);
        lkb->lkb_flags |= DLM_IFL_USER;
        ua->old_mode = DLM_LOCK_IV;
@@ -4094,19 +4311,20 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua,
        list_add_tail(&lkb->lkb_ownqueue, &ua->proc->locks);
        spin_unlock(&ua->proc->locks_spin);
  out:
-       unlock_recovery(ls);
+       dlm_unlock_recovery(ls);
        return error;
 }
 
 int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
-                    int mode, uint32_t flags, uint32_t lkid, char *lvb_in)
+                    int mode, uint32_t flags, uint32_t lkid, char *lvb_in,
+                    unsigned long timeout_cs)
 {
        struct dlm_lkb *lkb;
        struct dlm_args args;
        struct dlm_user_args *ua;
        int error;
 
-       lock_recovery(ls);
+       dlm_lock_recovery(ls);
 
        error = find_lkb(ls, lkid, &lkb);
        if (error)
@@ -4127,6 +4345,7 @@ int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
        if (lvb_in && ua->lksb.sb_lvbptr)
                memcpy(ua->lksb.sb_lvbptr, lvb_in, DLM_USER_LVB_LEN);
 
+       ua->xid = ua_tmp->xid;
        ua->castparam = ua_tmp->castparam;
        ua->castaddr = ua_tmp->castaddr;
        ua->bastparam = ua_tmp->bastparam;
@@ -4134,19 +4353,19 @@ int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
        ua->user_lksb = ua_tmp->user_lksb;
        ua->old_mode = lkb->lkb_grmode;
 
-       error = set_lock_args(mode, &ua->lksb, flags, 0, 0, DLM_FAKE_USER_AST,
-                             ua, DLM_FAKE_USER_AST, &args);
+       error = set_lock_args(mode, &ua->lksb, flags, 0, timeout_cs,
+                             DLM_FAKE_USER_AST, ua, DLM_FAKE_USER_AST, &args);
        if (error)
                goto out_put;
 
        error = convert_lock(ls, lkb, &args);
 
-       if (error == -EINPROGRESS || error == -EAGAIN)
+       if (error == -EINPROGRESS || error == -EAGAIN || error == -EDEADLK)
                error = 0;
  out_put:
        dlm_put_lkb(lkb);
  out:
-       unlock_recovery(ls);
+       dlm_unlock_recovery(ls);
        kfree(ua_tmp);
        return error;
 }
@@ -4159,7 +4378,7 @@ int dlm_user_unlock(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
        struct dlm_user_args *ua;
        int error;
 
-       lock_recovery(ls);
+       dlm_lock_recovery(ls);
 
        error = find_lkb(ls, lkid, &lkb);
        if (error)
@@ -4194,7 +4413,7 @@ int dlm_user_unlock(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
  out_put:
        dlm_put_lkb(lkb);
  out:
-       unlock_recovery(ls);
+       dlm_unlock_recovery(ls);
        kfree(ua_tmp);
        return error;
 }
@@ -4207,7 +4426,7 @@ int dlm_user_cancel(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
        struct dlm_user_args *ua;
        int error;
 
-       lock_recovery(ls);
+       dlm_lock_recovery(ls);
 
        error = find_lkb(ls, lkid, &lkb);
        if (error)
@@ -4231,11 +4450,59 @@ int dlm_user_cancel(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
  out_put:
        dlm_put_lkb(lkb);
  out:
-       unlock_recovery(ls);
+       dlm_unlock_recovery(ls);
        kfree(ua_tmp);
        return error;
 }
 
+int dlm_user_deadlock(struct dlm_ls *ls, uint32_t flags, uint32_t lkid)
+{
+       struct dlm_lkb *lkb;
+       struct dlm_args args;
+       struct dlm_user_args *ua;
+       struct dlm_rsb *r;
+       int error;
+
+       dlm_lock_recovery(ls);
+
+       error = find_lkb(ls, lkid, &lkb);
+       if (error)
+               goto out;
+
+       ua = (struct dlm_user_args *)lkb->lkb_astparam;
+
+       error = set_unlock_args(flags, ua, &args);
+       if (error)
+               goto out_put;
+
+       /* same as cancel_lock(), but set DEADLOCK_CANCEL after lock_rsb */
+
+       r = lkb->lkb_resource;
+       hold_rsb(r);
+       lock_rsb(r);
+
+       error = validate_unlock_args(lkb, &args);
+       if (error)
+               goto out_r;
+       lkb->lkb_flags |= DLM_IFL_DEADLOCK_CANCEL;
+
+       error = _cancel_lock(r, lkb);
+ out_r:
+       unlock_rsb(r);
+       put_rsb(r);
+
+       if (error == -DLM_ECANCEL)
+               error = 0;
+       /* from validate_unlock_args() */
+       if (error == -EBUSY)
+               error = 0;
+ out_put:
+       dlm_put_lkb(lkb);
+ out:
+       dlm_unlock_recovery(ls);
+       return error;
+}
+
 /* lkb's that are removed from the waiters list by revert are just left on the
    orphans list with the granted orphan locks, to be freed by purge */
 
@@ -4314,12 +4581,13 @@ void dlm_clear_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc)
 {
        struct dlm_lkb *lkb, *safe;
 
-       lock_recovery(ls);
+       dlm_lock_recovery(ls);
 
        while (1) {
                lkb = del_proc_lock(ls, proc);
                if (!lkb)
                        break;
+               del_timeout(lkb);
                if (lkb->lkb_exflags & DLM_LKF_PERSISTENT)
                        orphan_proc_lock(ls, lkb);
                else
@@ -4347,7 +4615,7 @@ void dlm_clear_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc)
        }
 
        mutex_unlock(&ls->ls_clear_proc_locks);
-       unlock_recovery(ls);
+       dlm_unlock_recovery(ls);
 }
 
 static void purge_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc)
@@ -4429,12 +4697,12 @@ int dlm_user_purge(struct dlm_ls *ls, struct dlm_user_proc *proc,
        if (nodeid != dlm_our_nodeid()) {
                error = send_purge(ls, nodeid, pid);
        } else {
-               lock_recovery(ls);
+               dlm_lock_recovery(ls);
                if (pid == current->pid)
                        purge_proc_locks(ls, proc);
                else
                        do_purge(ls, nodeid, pid);
-               unlock_recovery(ls);
+               dlm_unlock_recovery(ls);
        }
        return error;
 }
index 64fc4ec406683b2b855a4e7b059f442c8c7e34c6..1720313c22dfc455fd6c25f47d94fc02db075a64 100644 (file)
@@ -1,7 +1,7 @@
 /******************************************************************************
 *******************************************************************************
 **
-**  Copyright (C) 2005 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2005-2007 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
@@ -24,6 +24,10 @@ void dlm_put_rsb(struct dlm_rsb *r);
 void dlm_hold_rsb(struct dlm_rsb *r);
 int dlm_put_lkb(struct dlm_lkb *lkb);
 void dlm_scan_rsbs(struct dlm_ls *ls);
+int dlm_lock_recovery_try(struct dlm_ls *ls);
+void dlm_unlock_recovery(struct dlm_ls *ls);
+void dlm_scan_timeout(struct dlm_ls *ls);
+void dlm_adjust_timeouts(struct dlm_ls *ls);
 
 int dlm_purge_locks(struct dlm_ls *ls);
 void dlm_purge_mstcpy_locks(struct dlm_rsb *r);
@@ -34,15 +38,18 @@ int dlm_recover_master_copy(struct dlm_ls *ls, struct dlm_rcom *rc);
 int dlm_recover_process_copy(struct dlm_ls *ls, struct dlm_rcom *rc);
 
 int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua, int mode,
-       uint32_t flags, void *name, unsigned int namelen, uint32_t parent_lkid);
+       uint32_t flags, void *name, unsigned int namelen,
+       unsigned long timeout_cs);
 int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
-       int mode, uint32_t flags, uint32_t lkid, char *lvb_in);
+       int mode, uint32_t flags, uint32_t lkid, char *lvb_in,
+       unsigned long timeout_cs);
 int dlm_user_unlock(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
        uint32_t flags, uint32_t lkid, char *lvb_in);
 int dlm_user_cancel(struct dlm_ls *ls,  struct dlm_user_args *ua_tmp,
        uint32_t flags, uint32_t lkid);
 int dlm_user_purge(struct dlm_ls *ls, struct dlm_user_proc *proc,
        int nodeid, int pid);
+int dlm_user_deadlock(struct dlm_ls *ls, uint32_t flags, uint32_t lkid);
 void dlm_clear_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc);
 
 static inline int is_master(struct dlm_rsb *r)
index a677b2a5eed4dff8cc40be9c6f41c298565fa3bf..1dc72105ab125171b4bb3356ea0a09577178ec77 100644 (file)
@@ -197,13 +197,24 @@ static int do_uevent(struct dlm_ls *ls, int in)
        else
                kobject_uevent(&ls->ls_kobj, KOBJ_OFFLINE);
 
+       log_debug(ls, "%s the lockspace group...", in ? "joining" : "leaving");
+
+       /* dlm_controld will see the uevent, do the necessary group management
+          and then write to sysfs to wake us */
+
        error = wait_event_interruptible(ls->ls_uevent_wait,
                        test_and_clear_bit(LSFL_UEVENT_WAIT, &ls->ls_flags));
+
+       log_debug(ls, "group event done %d %d", error, ls->ls_uevent_result);
+
        if (error)
                goto out;
 
        error = ls->ls_uevent_result;
  out:
+       if (error)
+               log_error(ls, "group %s failed %d %d", in ? "join" : "leave",
+                         error, ls->ls_uevent_result);
        return error;
 }
 
@@ -234,8 +245,13 @@ static int dlm_scand(void *data)
        struct dlm_ls *ls;
 
        while (!kthread_should_stop()) {
-               list_for_each_entry(ls, &lslist, ls_list)
-                       dlm_scan_rsbs(ls);
+               list_for_each_entry(ls, &lslist, ls_list) {
+                       if (dlm_lock_recovery_try(ls)) {
+                               dlm_scan_rsbs(ls);
+                               dlm_scan_timeout(ls);
+                               dlm_unlock_recovery(ls);
+                       }
+               }
                schedule_timeout_interruptible(dlm_config.ci_scan_secs * HZ);
        }
        return 0;
@@ -395,6 +411,7 @@ static int new_lockspace(char *name, int namelen, void **lockspace,
 {
        struct dlm_ls *ls;
        int i, size, error = -ENOMEM;
+       int do_unreg = 0;
 
        if (namelen > DLM_LOCKSPACE_LEN)
                return -EINVAL;
@@ -417,11 +434,22 @@ static int new_lockspace(char *name, int namelen, void **lockspace,
                goto out;
        memcpy(ls->ls_name, name, namelen);
        ls->ls_namelen = namelen;
-       ls->ls_exflags = flags;
        ls->ls_lvblen = lvblen;
        ls->ls_count = 0;
        ls->ls_flags = 0;
 
+       if (flags & DLM_LSFL_TIMEWARN)
+               set_bit(LSFL_TIMEWARN, &ls->ls_flags);
+
+       if (flags & DLM_LSFL_FS)
+               ls->ls_allocation = GFP_NOFS;
+       else
+               ls->ls_allocation = GFP_KERNEL;
+
+       /* ls_exflags are forced to match among nodes, and we don't
+          need to require all nodes to have TIMEWARN or FS set */
+       ls->ls_exflags = (flags & ~(DLM_LSFL_TIMEWARN | DLM_LSFL_FS));
+
        size = dlm_config.ci_rsbtbl_size;
        ls->ls_rsbtbl_size = size;
 
@@ -461,6 +489,8 @@ static int new_lockspace(char *name, int namelen, void **lockspace,
        mutex_init(&ls->ls_waiters_mutex);
        INIT_LIST_HEAD(&ls->ls_orphans);
        mutex_init(&ls->ls_orphans_mutex);
+       INIT_LIST_HEAD(&ls->ls_timeout);
+       mutex_init(&ls->ls_timeout_mutex);
 
        INIT_LIST_HEAD(&ls->ls_nodes);
        INIT_LIST_HEAD(&ls->ls_nodes_gone);
@@ -477,6 +507,8 @@ static int new_lockspace(char *name, int namelen, void **lockspace,
 
        init_waitqueue_head(&ls->ls_uevent_wait);
        ls->ls_uevent_result = 0;
+       init_completion(&ls->ls_members_done);
+       ls->ls_members_result = -1;
 
        ls->ls_recoverd_task = NULL;
        mutex_init(&ls->ls_recoverd_active);
@@ -513,32 +545,49 @@ static int new_lockspace(char *name, int namelen, void **lockspace,
        error = dlm_recoverd_start(ls);
        if (error) {
                log_error(ls, "can't start dlm_recoverd %d", error);
-               goto out_rcomfree;
+               goto out_delist;
        }
 
-       dlm_create_debug_file(ls);
-
        error = kobject_setup(ls);
        if (error)
-               goto out_del;
+               goto out_stop;
 
        error = kobject_register(&ls->ls_kobj);
        if (error)
-               goto out_del;
+               goto out_stop;
+
+       /* let kobject handle freeing of ls if there's an error */
+       do_unreg = 1;
+
+       /* This uevent triggers dlm_controld in userspace to add us to the
+          group of nodes that are members of this lockspace (managed by the
+          cluster infrastructure.)  Once it's done that, it tells us who the
+          current lockspace members are (via configfs) and then tells the
+          lockspace to start running (via sysfs) in dlm_ls_start(). */
 
        error = do_uevent(ls, 1);
        if (error)
-               goto out_unreg;
+               goto out_stop;
+
+       wait_for_completion(&ls->ls_members_done);
+       error = ls->ls_members_result;
+       if (error)
+               goto out_members;
+
+       dlm_create_debug_file(ls);
+
+       log_debug(ls, "join complete");
 
        *lockspace = ls;
        return 0;
 
- out_unreg:
-       kobject_unregister(&ls->ls_kobj);
- out_del:
-       dlm_delete_debug_file(ls);
+ out_members:
+       do_uevent(ls, 0);
+       dlm_clear_members(ls);
+       kfree(ls->ls_node_array);
+ out_stop:
        dlm_recoverd_stop(ls);
- out_rcomfree:
+ out_delist:
        spin_lock(&lslist_lock);
        list_del(&ls->ls_list);
        spin_unlock(&lslist_lock);
@@ -550,7 +599,10 @@ static int new_lockspace(char *name, int namelen, void **lockspace,
  out_rsbfree:
        kfree(ls->ls_rsbtbl);
  out_lsfree:
-       kfree(ls);
+       if (do_unreg)
+               kobject_unregister(&ls->ls_kobj);
+       else
+               kfree(ls);
  out:
        module_put(THIS_MODULE);
        return error;
@@ -570,6 +622,8 @@ int dlm_new_lockspace(char *name, int namelen, void **lockspace,
        error = new_lockspace(name, namelen, lockspace, flags, lvblen);
        if (!error)
                ls_count++;
+       else if (!ls_count)
+               threads_stop();
  out:
        mutex_unlock(&ls_lock);
        return error;
@@ -696,7 +750,7 @@ static int release_lockspace(struct dlm_ls *ls, int force)
        dlm_clear_members_gone(ls);
        kfree(ls->ls_node_array);
        kobject_unregister(&ls->ls_kobj);
-        /* The ls structure will be freed when the kobject is done with */
+       /* The ls structure will be freed when the kobject is done with */
 
        mutex_lock(&ls_lock);
        ls_count--;
index 27970a58d29b255aa1d09ebb71a9c11697f9e0c5..0553a6158dcbcf1bcc89d4e5d0733419ffc88214 100644 (file)
@@ -260,7 +260,7 @@ static int nodeid_to_addr(int nodeid, struct sockaddr *retaddr)
 static void lowcomms_data_ready(struct sock *sk, int count_unused)
 {
        struct connection *con = sock2con(sk);
-       if (!test_and_set_bit(CF_READ_PENDING, &con->flags))
+       if (con && !test_and_set_bit(CF_READ_PENDING, &con->flags))
                queue_work(recv_workqueue, &con->rwork);
 }
 
@@ -268,7 +268,7 @@ static void lowcomms_write_space(struct sock *sk)
 {
        struct connection *con = sock2con(sk);
 
-       if (!test_and_set_bit(CF_WRITE_PENDING, &con->flags))
+       if (con && !test_and_set_bit(CF_WRITE_PENDING, &con->flags))
                queue_work(send_workqueue, &con->swork);
 }
 
@@ -720,11 +720,17 @@ static int tcp_accept_from_sock(struct connection *con)
                        INIT_WORK(&othercon->rwork, process_recv_sockets);
                        set_bit(CF_IS_OTHERCON, &othercon->flags);
                        newcon->othercon = othercon;
+                       othercon->sock = newsock;
+                       newsock->sk->sk_user_data = othercon;
+                       add_sock(newsock, othercon);
+                       addcon = othercon;
+               }
+               else {
+                       printk("Extra connection from node %d attempted\n", nodeid);
+                       result = -EAGAIN;
+                       mutex_unlock(&newcon->sock_mutex);
+                       goto accept_err;
                }
-               othercon->sock = newsock;
-               newsock->sk->sk_user_data = othercon;
-               add_sock(newsock, othercon);
-               addcon = othercon;
        }
        else {
                newsock->sk->sk_user_data = newcon;
@@ -1400,8 +1406,11 @@ void dlm_lowcomms_stop(void)
        down(&connections_lock);
        for (i = 0; i <= max_nodeid; i++) {
                con = __nodeid2con(i, 0);
-               if (con)
+               if (con) {
                        con->flags |= 0xFF;
+                       if (con->sock)
+                               con->sock->sk->sk_user_data = NULL;
+               }
        }
        up(&connections_lock);
 
index 162fbae58fe556df3150f96a8423718e47261d9a..eca2907f2386da93396d19d5195bd59101614b54 100644 (file)
@@ -2,7 +2,7 @@
 *******************************************************************************
 **
 **  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
-**  Copyright (C) 2004-2005 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2004-2007 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
@@ -25,6 +25,8 @@ void dlm_unregister_debugfs(void);
 static inline int dlm_register_debugfs(void) { return 0; }
 static inline void dlm_unregister_debugfs(void) { }
 #endif
+int dlm_netlink_init(void);
+void dlm_netlink_exit(void);
 
 static int __init init_dlm(void)
 {
@@ -50,10 +52,16 @@ static int __init init_dlm(void)
        if (error)
                goto out_debug;
 
+       error = dlm_netlink_init();
+       if (error)
+               goto out_user;
+
        printk("DLM (built %s %s) installed\n", __DATE__, __TIME__);
 
        return 0;
 
+ out_user:
+       dlm_user_exit();
  out_debug:
        dlm_unregister_debugfs();
  out_config:
@@ -68,6 +76,7 @@ static int __init init_dlm(void)
 
 static void __exit exit_dlm(void)
 {
+       dlm_netlink_exit();
        dlm_user_exit();
        dlm_config_exit();
        dlm_memory_exit();
index 85e2897bd7400fc4155948fc8eb1c81cb1ff8e01..073599dced2ab4b2562f8f7df44db66aeaa079cc 100644 (file)
@@ -1,7 +1,7 @@
 /******************************************************************************
 *******************************************************************************
 **
-**  Copyright (C) 2005 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2005-2007 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
@@ -233,6 +233,12 @@ int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv, int *neg_out)
        *neg_out = neg;
 
        error = ping_members(ls);
+       if (!error || error == -EPROTO) {
+               /* new_lockspace() may be waiting to know if the config
+                  is good or bad */
+               ls->ls_members_result = error;
+               complete(&ls->ls_members_done);
+       }
        if (error)
                goto out;
 
@@ -284,6 +290,9 @@ int dlm_ls_stop(struct dlm_ls *ls)
        dlm_recoverd_suspend(ls);
        ls->ls_recover_status = 0;
        dlm_recoverd_resume(ls);
+
+       if (!ls->ls_recover_begin)
+               ls->ls_recover_begin = jiffies;
        return 0;
 }
 
diff --git a/fs/dlm/netlink.c b/fs/dlm/netlink.c
new file mode 100644 (file)
index 0000000..863b87d
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2007 Red Hat, Inc.  All rights reserved.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ */
+
+#include <net/genetlink.h>
+#include <linux/dlm.h>
+#include <linux/dlm_netlink.h>
+
+#include "dlm_internal.h"
+
+static uint32_t dlm_nl_seqnum;
+static uint32_t listener_nlpid;
+
+static struct genl_family family = {
+       .id             = GENL_ID_GENERATE,
+       .name           = DLM_GENL_NAME,
+       .version        = DLM_GENL_VERSION,
+};
+
+static int prepare_data(u8 cmd, struct sk_buff **skbp, size_t size)
+{
+       struct sk_buff *skb;
+       void *data;
+
+       skb = genlmsg_new(size, GFP_KERNEL);
+       if (!skb)
+               return -ENOMEM;
+
+       /* add the message headers */
+       data = genlmsg_put(skb, 0, dlm_nl_seqnum++, &family, 0, cmd);
+       if (!data) {
+               nlmsg_free(skb);
+               return -EINVAL;
+       }
+
+       *skbp = skb;
+       return 0;
+}
+
+static struct dlm_lock_data *mk_data(struct sk_buff *skb)
+{
+       struct nlattr *ret;
+
+       ret = nla_reserve(skb, DLM_TYPE_LOCK, sizeof(struct dlm_lock_data));
+       if (!ret)
+               return NULL;
+       return nla_data(ret);
+}
+
+static int send_data(struct sk_buff *skb)
+{
+       struct genlmsghdr *genlhdr = nlmsg_data((struct nlmsghdr *)skb->data);
+       void *data = genlmsg_data(genlhdr);
+       int rv;
+
+       rv = genlmsg_end(skb, data);
+       if (rv < 0) {
+               nlmsg_free(skb);
+               return rv;
+       }
+
+       return genlmsg_unicast(skb, listener_nlpid);
+}
+
+static int user_cmd(struct sk_buff *skb, struct genl_info *info)
+{
+       listener_nlpid = info->snd_pid;
+       printk("user_cmd nlpid %u\n", listener_nlpid);
+       return 0;
+}
+
+static struct genl_ops dlm_nl_ops = {
+       .cmd            = DLM_CMD_HELLO,
+       .doit           = user_cmd,
+};
+
+int dlm_netlink_init(void)
+{
+       int rv;
+
+       rv = genl_register_family(&family);
+       if (rv)
+               return rv;
+
+       rv = genl_register_ops(&family, &dlm_nl_ops);
+       if (rv < 0)
+               goto err;
+       return 0;
+ err:
+       genl_unregister_family(&family);
+       return rv;
+}
+
+void dlm_netlink_exit(void)
+{
+       genl_unregister_ops(&family, &dlm_nl_ops);
+       genl_unregister_family(&family);
+}
+
+static void fill_data(struct dlm_lock_data *data, struct dlm_lkb *lkb)
+{
+       struct dlm_rsb *r = lkb->lkb_resource;
+       struct dlm_user_args *ua = (struct dlm_user_args *) lkb->lkb_astparam;
+
+       memset(data, 0, sizeof(struct dlm_lock_data));
+
+       data->version = DLM_LOCK_DATA_VERSION;
+       data->nodeid = lkb->lkb_nodeid;
+       data->ownpid = lkb->lkb_ownpid;
+       data->id = lkb->lkb_id;
+       data->remid = lkb->lkb_remid;
+       data->status = lkb->lkb_status;
+       data->grmode = lkb->lkb_grmode;
+       data->rqmode = lkb->lkb_rqmode;
+       data->timestamp = lkb->lkb_timestamp;
+       if (ua)
+               data->xid = ua->xid;
+       if (r) {
+               data->lockspace_id = r->res_ls->ls_global_id;
+               data->resource_namelen = r->res_length;
+               memcpy(data->resource_name, r->res_name, r->res_length);
+       }
+}
+
+void dlm_timeout_warn(struct dlm_lkb *lkb)
+{
+       struct dlm_lock_data *data;
+       struct sk_buff *send_skb;
+       size_t size;
+       int rv;
+
+       size = nla_total_size(sizeof(struct dlm_lock_data)) +
+              nla_total_size(0); /* why this? */
+
+       rv = prepare_data(DLM_CMD_TIMEOUT, &send_skb, size);
+       if (rv < 0)
+               return;
+
+       data = mk_data(send_skb);
+       if (!data) {
+               nlmsg_free(send_skb);
+               return;
+       }
+
+       fill_data(data, lkb);
+
+       send_data(send_skb);
+}
+
index 6bfbd61538094f72cb1001bc782cc246faf55552..e3a1527cbdbe7c8cd4bb0a8b6605e486b8ea538c 100644 (file)
@@ -38,7 +38,7 @@ static int create_rcom(struct dlm_ls *ls, int to_nodeid, int type, int len,
        char *mb;
        int mb_len = sizeof(struct dlm_rcom) + len;
 
-       mh = dlm_lowcomms_get_buffer(to_nodeid, mb_len, GFP_KERNEL, &mb);
+       mh = dlm_lowcomms_get_buffer(to_nodeid, mb_len, ls->ls_allocation, &mb);
        if (!mh) {
                log_print("create_rcom to %d type %d len %d ENOBUFS",
                          to_nodeid, type, len);
@@ -90,7 +90,7 @@ static int check_config(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid)
                log_error(ls, "version mismatch: %x nodeid %d: %x",
                          DLM_HEADER_MAJOR | DLM_HEADER_MINOR, nodeid,
                          rc->rc_header.h_version);
-               return -EINVAL;
+               return -EPROTO;
        }
 
        if (rf->rf_lvblen != ls->ls_lvblen ||
@@ -98,7 +98,7 @@ static int check_config(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid)
                log_error(ls, "config mismatch: %d,%x nodeid %d: %d,%x",
                          ls->ls_lvblen, ls->ls_exflags,
                          nodeid, rf->rf_lvblen, rf->rf_lsflags);
-               return -EINVAL;
+               return -EPROTO;
        }
        return 0;
 }
@@ -386,7 +386,8 @@ static void receive_rcom_lock_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in)
        dlm_recover_process_copy(ls, rc_in);
 }
 
-static int send_ls_not_ready(int nodeid, struct dlm_rcom *rc_in)
+static int send_ls_not_ready(struct dlm_ls *ls, int nodeid,
+                            struct dlm_rcom *rc_in)
 {
        struct dlm_rcom *rc;
        struct rcom_config *rf;
@@ -394,7 +395,7 @@ static int send_ls_not_ready(int nodeid, struct dlm_rcom *rc_in)
        char *mb;
        int mb_len = sizeof(struct dlm_rcom) + sizeof(struct rcom_config);
 
-       mh = dlm_lowcomms_get_buffer(nodeid, mb_len, GFP_KERNEL, &mb);
+       mh = dlm_lowcomms_get_buffer(nodeid, mb_len, ls->ls_allocation, &mb);
        if (!mh)
                return -ENOBUFS;
        memset(mb, 0, mb_len);
@@ -464,7 +465,7 @@ void dlm_receive_rcom(struct dlm_header *hd, int nodeid)
                log_print("lockspace %x from %d type %x not found",
                          hd->h_lockspace, nodeid, rc->rc_type);
                if (rc->rc_type == DLM_RCOM_STATUS)
-                       send_ls_not_ready(nodeid, rc);
+                       send_ls_not_ready(ls, nodeid, rc);
                return;
        }
 
index 3cb636d6024912b8aa96b55f6e0c731c11d56b82..66575997861cad1da5e02e9528deaaf6240751b7 100644 (file)
@@ -2,7 +2,7 @@
 *******************************************************************************
 **
 **  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
-**  Copyright (C) 2004-2005 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2004-2007 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
@@ -190,6 +190,8 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
 
        dlm_clear_members_gone(ls);
 
+       dlm_adjust_timeouts(ls);
+
        error = enable_locking(ls, rv->seq);
        if (error) {
                log_debug(ls, "enable_locking failed %d", error);
index b0201ec325a79578761a686c85ab376944ec2abe..6438941ab1f8baf21e4ca88ce5d05b120b525f8b 100644 (file)
@@ -33,16 +33,17 @@ static const struct file_operations device_fops;
 struct dlm_lock_params32 {
        __u8 mode;
        __u8 namelen;
-       __u16 flags;
+       __u16 unused;
+       __u32 flags;
        __u32 lkid;
        __u32 parent;
-
+       __u64 xid;
+       __u64 timeout;
        __u32 castparam;
        __u32 castaddr;
        __u32 bastparam;
        __u32 bastaddr;
        __u32 lksb;
-
        char lvb[DLM_USER_LVB_LEN];
        char name[0];
 };
@@ -68,6 +69,7 @@ struct dlm_lksb32 {
 };
 
 struct dlm_lock_result32 {
+       __u32 version[3];
        __u32 length;
        __u32 user_astaddr;
        __u32 user_astparam;
@@ -102,6 +104,8 @@ static void compat_input(struct dlm_write_request *kb,
                kb->i.lock.flags = kb32->i.lock.flags;
                kb->i.lock.lkid = kb32->i.lock.lkid;
                kb->i.lock.parent = kb32->i.lock.parent;
+               kb->i.lock.xid = kb32->i.lock.xid;
+               kb->i.lock.timeout = kb32->i.lock.timeout;
                kb->i.lock.castparam = (void *)(long)kb32->i.lock.castparam;
                kb->i.lock.castaddr = (void *)(long)kb32->i.lock.castaddr;
                kb->i.lock.bastparam = (void *)(long)kb32->i.lock.bastparam;
@@ -115,6 +119,10 @@ static void compat_input(struct dlm_write_request *kb,
 static void compat_output(struct dlm_lock_result *res,
                          struct dlm_lock_result32 *res32)
 {
+       res32->version[0] = res->version[0];
+       res32->version[1] = res->version[1];
+       res32->version[2] = res->version[2];
+
        res32->user_astaddr = (__u32)(long)res->user_astaddr;
        res32->user_astparam = (__u32)(long)res->user_astparam;
        res32->user_lksb = (__u32)(long)res->user_lksb;
@@ -130,6 +138,36 @@ static void compat_output(struct dlm_lock_result *res,
 }
 #endif
 
+/* Figure out if this lock is at the end of its life and no longer
+   available for the application to use.  The lkb still exists until
+   the final ast is read.  A lock becomes EOL in three situations:
+     1. a noqueue request fails with EAGAIN
+     2. an unlock completes with EUNLOCK
+     3. a cancel of a waiting request completes with ECANCEL/EDEADLK
+   An EOL lock needs to be removed from the process's list of locks.
+   And we can't allow any new operation on an EOL lock.  This is
+   not related to the lifetime of the lkb struct which is managed
+   entirely by refcount. */
+
+static int lkb_is_endoflife(struct dlm_lkb *lkb, int sb_status, int type)
+{
+       switch (sb_status) {
+       case -DLM_EUNLOCK:
+               return 1;
+       case -DLM_ECANCEL:
+       case -ETIMEDOUT:
+       case -EDEADLK:
+               if (lkb->lkb_grmode == DLM_LOCK_IV)
+                       return 1;
+               break;
+       case -EAGAIN:
+               if (type == AST_COMP && lkb->lkb_grmode == DLM_LOCK_IV)
+                       return 1;
+               break;
+       }
+       return 0;
+}
+
 /* we could possibly check if the cancel of an orphan has resulted in the lkb
    being removed and then remove that lkb from the orphans list and free it */
 
@@ -176,25 +214,7 @@ void dlm_user_add_ast(struct dlm_lkb *lkb, int type)
                log_debug(ls, "ast overlap %x status %x %x",
                          lkb->lkb_id, ua->lksb.sb_status, lkb->lkb_flags);
 
-       /* Figure out if this lock is at the end of its life and no longer
-          available for the application to use.  The lkb still exists until
-          the final ast is read.  A lock becomes EOL in three situations:
-            1. a noqueue request fails with EAGAIN
-            2. an unlock completes with EUNLOCK
-            3. a cancel of a waiting request completes with ECANCEL
-          An EOL lock needs to be removed from the process's list of locks.
-          And we can't allow any new operation on an EOL lock.  This is
-          not related to the lifetime of the lkb struct which is managed
-          entirely by refcount. */
-
-       if (type == AST_COMP &&
-           lkb->lkb_grmode == DLM_LOCK_IV &&
-           ua->lksb.sb_status == -EAGAIN)
-               eol = 1;
-       else if (ua->lksb.sb_status == -DLM_EUNLOCK ||
-           (ua->lksb.sb_status == -DLM_ECANCEL &&
-            lkb->lkb_grmode == DLM_LOCK_IV))
-               eol = 1;
+       eol = lkb_is_endoflife(lkb, ua->lksb.sb_status, type);
        if (eol) {
                lkb->lkb_ast_type &= ~AST_BAST;
                lkb->lkb_flags |= DLM_IFL_ENDOFLIFE;
@@ -252,16 +272,18 @@ static int device_user_lock(struct dlm_user_proc *proc,
        ua->castaddr = params->castaddr;
        ua->bastparam = params->bastparam;
        ua->bastaddr = params->bastaddr;
+       ua->xid = params->xid;
 
        if (params->flags & DLM_LKF_CONVERT)
                error = dlm_user_convert(ls, ua,
                                         params->mode, params->flags,
-                                        params->lkid, params->lvb);
+                                        params->lkid, params->lvb,
+                                        (unsigned long) params->timeout);
        else {
                error = dlm_user_request(ls, ua,
                                         params->mode, params->flags,
                                         params->name, params->namelen,
-                                        params->parent);
+                                        (unsigned long) params->timeout);
                if (!error)
                        error = ua->lksb.sb_lkid;
        }
@@ -299,6 +321,22 @@ static int device_user_unlock(struct dlm_user_proc *proc,
        return error;
 }
 
+static int device_user_deadlock(struct dlm_user_proc *proc,
+                               struct dlm_lock_params *params)
+{
+       struct dlm_ls *ls;
+       int error;
+
+       ls = dlm_find_lockspace_local(proc->lockspace);
+       if (!ls)
+               return -ENOENT;
+
+       error = dlm_user_deadlock(ls, params->flags, params->lkid);
+
+       dlm_put_lockspace(ls);
+       return error;
+}
+
 static int create_misc_device(struct dlm_ls *ls, char *name)
 {
        int error, len;
@@ -348,7 +386,7 @@ static int device_create_lockspace(struct dlm_lspace_params *params)
                return -EPERM;
 
        error = dlm_new_lockspace(params->name, strlen(params->name),
-                                 &lockspace, 0, DLM_USER_LVB_LEN);
+                                 &lockspace, params->flags, DLM_USER_LVB_LEN);
        if (error)
                return error;
 
@@ -524,6 +562,14 @@ static ssize_t device_write(struct file *file, const char __user *buf,
                error = device_user_unlock(proc, &kbuf->i.lock);
                break;
 
+       case DLM_USER_DEADLOCK:
+               if (!proc) {
+                       log_print("no locking on control device");
+                       goto out_sig;
+               }
+               error = device_user_deadlock(proc, &kbuf->i.lock);
+               break;
+
        case DLM_USER_CREATE_LOCKSPACE:
                if (proc) {
                        log_print("create/remove only on control device");
@@ -641,6 +687,9 @@ static int copy_result_to_user(struct dlm_user_args *ua, int compat, int type,
        int struct_len;
 
        memset(&result, 0, sizeof(struct dlm_lock_result));
+       result.version[0] = DLM_DEVICE_VERSION_MAJOR;
+       result.version[1] = DLM_DEVICE_VERSION_MINOR;
+       result.version[2] = DLM_DEVICE_VERSION_PATCH;
        memcpy(&result.lksb, &ua->lksb, sizeof(struct dlm_lksb));
        result.user_lksb = ua->user_lksb;
 
@@ -699,6 +748,20 @@ static int copy_result_to_user(struct dlm_user_args *ua, int compat, int type,
        return error;
 }
 
+static int copy_version_to_user(char __user *buf, size_t count)
+{
+       struct dlm_device_version ver;
+
+       memset(&ver, 0, sizeof(struct dlm_device_version));
+       ver.version[0] = DLM_DEVICE_VERSION_MAJOR;
+       ver.version[1] = DLM_DEVICE_VERSION_MINOR;
+       ver.version[2] = DLM_DEVICE_VERSION_PATCH;
+
+       if (copy_to_user(buf, &ver, sizeof(struct dlm_device_version)))
+               return -EFAULT;
+       return sizeof(struct dlm_device_version);
+}
+
 /* a read returns a single ast described in a struct dlm_lock_result */
 
 static ssize_t device_read(struct file *file, char __user *buf, size_t count,
@@ -710,6 +773,16 @@ static ssize_t device_read(struct file *file, char __user *buf, size_t count,
        DECLARE_WAITQUEUE(wait, current);
        int error, type=0, bmode=0, removed = 0;
 
+       if (count == sizeof(struct dlm_device_version)) {
+               error = copy_version_to_user(buf, count);
+               return error;
+       }
+
+       if (!proc) {
+               log_print("non-version read from control device %zu", count);
+               return -EINVAL;
+       }
+
 #ifdef CONFIG_COMPAT
        if (count < sizeof(struct dlm_lock_result32))
 #else
@@ -747,11 +820,6 @@ static ssize_t device_read(struct file *file, char __user *buf, size_t count,
                }
        }
 
-       if (list_empty(&proc->asts)) {
-               spin_unlock(&proc->asts_spin);
-               return -EAGAIN;
-       }
-
        /* there may be both completion and blocking asts to return for
           the lkb, don't remove lkb from asts list unless no asts remain */
 
@@ -823,6 +891,7 @@ static const struct file_operations device_fops = {
 static const struct file_operations ctl_device_fops = {
        .open    = ctl_device_open,
        .release = ctl_device_close,
+       .read    = device_read,
        .write   = device_write,
        .owner   = THIS_MODULE,
 };
index 59288d817078879ad36c1ece17a51208488d571e..94f456fe4d9b70487686a707b9954d49895a3fb4 100644 (file)
@@ -338,16 +338,17 @@ static int ecryptfs_fasync(int fd, struct file *file, int flag)
        return rc;
 }
 
-static ssize_t ecryptfs_sendfile(struct file *file, loff_t * ppos,
-                                size_t count, read_actor_t actor, void *target)
+static ssize_t ecryptfs_splice_read(struct file *file, loff_t * ppos,
+                                   struct pipe_inode_info *pipe, size_t count,
+                                   unsigned int flags)
 {
        struct file *lower_file = NULL;
        int rc = -EINVAL;
 
        lower_file = ecryptfs_file_to_lower(file);
-       if (lower_file->f_op && lower_file->f_op->sendfile)
-               rc = lower_file->f_op->sendfile(lower_file, ppos, count,
-                                               actor, target);
+       if (lower_file->f_op && lower_file->f_op->splice_read)
+               rc = lower_file->f_op->splice_read(lower_file, ppos, pipe,
+                                               count, flags);
 
        return rc;
 }
@@ -364,7 +365,7 @@ const struct file_operations ecryptfs_dir_fops = {
        .release = ecryptfs_release,
        .fsync = ecryptfs_fsync,
        .fasync = ecryptfs_fasync,
-       .sendfile = ecryptfs_sendfile,
+       .splice_read = ecryptfs_splice_read,
 };
 
 const struct file_operations ecryptfs_main_fops = {
@@ -381,7 +382,7 @@ const struct file_operations ecryptfs_main_fops = {
        .release = ecryptfs_release,
        .fsync = ecryptfs_fsync,
        .fasync = ecryptfs_fasync,
-       .sendfile = ecryptfs_sendfile,
+       .splice_read = ecryptfs_splice_read,
 };
 
 static int
index 606128f5c927d3697c04f4f84ee64718e9cfd71b..02ca6f1e55d77d09ddd4d057c9e02bdc8c33ef5a 100644 (file)
@@ -840,8 +840,6 @@ static int __init ecryptfs_init(void)
                goto out;
        }
        kobj_set_kset_s(&ecryptfs_subsys, fs_subsys);
-       sysfs_attr_version.attr.owner = THIS_MODULE;
-       sysfs_attr_version_str.attr.owner = THIS_MODULE;
        rc = do_sysfs_registration();
        if (rc) {
                printk(KERN_ERR "sysfs registration failed\n");
index 566d4e2d3852353d4e54032c417b6bd593d72fa2..04afeecaaef31acde466b50f48ea6057ac3f98a9 100644 (file)
@@ -53,7 +53,6 @@ const struct file_operations ext2_file_operations = {
        .open           = generic_file_open,
        .release        = ext2_release_file,
        .fsync          = ext2_sync_file,
-       .sendfile       = generic_file_sendfile,
        .splice_read    = generic_file_splice_read,
        .splice_write   = generic_file_splice_write,
 };
@@ -71,7 +70,6 @@ const struct file_operations ext2_xip_file_operations = {
        .open           = generic_file_open,
        .release        = ext2_release_file,
        .fsync          = ext2_sync_file,
-       .sendfile       = xip_file_sendfile,
 };
 #endif
 
index 1e6f13864536e7180a465ace2ce6555256d7292f..acc4913d30199079007726e8c4a49b4a07dd77cc 100644 (file)
@@ -120,7 +120,6 @@ const struct file_operations ext3_file_operations = {
        .open           = generic_file_open,
        .release        = ext3_release_file,
        .fsync          = ext3_sync_file,
-       .sendfile       = generic_file_sendfile,
        .splice_read    = generic_file_splice_read,
        .splice_write   = generic_file_splice_write,
 };
index 3c6c1fd2be902524eb1901776aa8a0b45db4a167..d4c8186aed646f6a4439b17d0b0cda9655aadf55 100644 (file)
@@ -120,7 +120,6 @@ const struct file_operations ext4_file_operations = {
        .open           = generic_file_open,
        .release        = ext4_release_file,
        .fsync          = ext4_sync_file,
-       .sendfile       = generic_file_sendfile,
        .splice_read    = generic_file_splice_read,
        .splice_write   = generic_file_splice_write,
 };
index 55d3c7461c5b9acb50b851fae64df4a68dcd3d01..69a83b59dce80bdc84f1d4507e1ad74195c38690 100644 (file)
@@ -134,7 +134,7 @@ const struct file_operations fat_file_operations = {
        .release        = fat_file_release,
        .ioctl          = fat_generic_ioctl,
        .fsync          = file_fsync,
-       .sendfile       = generic_file_sendfile,
+       .splice_read    = generic_file_splice_read,
 };
 
 static int fat_cont_expand(struct inode *inode, loff_t size)
index adf7995232b8b851250ed83839fdd5436c85c143..f79de7c8cdfaae3260009c86127f88ae4283cc22 100644 (file)
@@ -802,7 +802,7 @@ static const struct file_operations fuse_file_operations = {
        .release        = fuse_release,
        .fsync          = fuse_fsync,
        .lock           = fuse_file_lock,
-       .sendfile       = generic_file_sendfile,
+       .splice_read    = generic_file_splice_read,
 };
 
 static const struct file_operations fuse_direct_io_file_operations = {
@@ -814,7 +814,7 @@ static const struct file_operations fuse_direct_io_file_operations = {
        .release        = fuse_release,
        .fsync          = fuse_fsync,
        .lock           = fuse_file_lock,
-       /* no mmap and sendfile */
+       /* no mmap and splice_read */
 };
 
 static const struct address_space_operations fuse_file_aops  = {
index e3f1ada643ac110008cfdfdfe28f65d7e4374172..04ad0caebedb40ff302eaf56dbbdd90232d45c83 100644 (file)
@@ -1,7 +1,7 @@
 obj-$(CONFIG_GFS2_FS) += gfs2.o
 gfs2-y := acl.o bmap.o daemon.o dir.o eaops.o eattr.o glock.o \
        glops.o inode.o lm.o log.o lops.o locking.o main.o meta_io.o \
-       mount.o ondisk.o ops_address.o ops_dentry.o ops_export.o ops_file.o \
+       mount.o ops_address.o ops_dentry.o ops_export.o ops_file.o \
        ops_fstype.o ops_inode.o ops_super.o ops_vm.o quota.o \
        recovery.o rgrp.o super.o sys.o trans.o util.o
 
index c53a5d2d0590ea0a90fc38ff5d470df88736b57e..cd805a66880ddd3f24459be574bd868d29f2d801 100644 (file)
@@ -718,7 +718,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,
        for (x = 0; x < rlist.rl_rgrps; x++) {
                struct gfs2_rgrpd *rgd;
                rgd = rlist.rl_ghs[x].gh_gl->gl_object;
-               rg_blocks += rgd->rd_ri.ri_length;
+               rg_blocks += rgd->rd_length;
        }
 
        error = gfs2_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs);
@@ -772,7 +772,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,
                        gfs2_free_data(ip, bstart, blen);
        }
 
-       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
 
        gfs2_dinode_out(ip, dibh->b_data);
 
@@ -824,7 +824,7 @@ static int do_grow(struct gfs2_inode *ip, u64 size)
                goto out_gunlock_q;
 
        error = gfs2_trans_begin(sdp,
-                       sdp->sd_max_height + al->al_rgd->rd_ri.ri_length +
+                       sdp->sd_max_height + al->al_rgd->rd_length +
                        RES_JDATA + RES_DINODE + RES_STATFS + RES_QUOTA, 0);
        if (error)
                goto out_ipres;
@@ -847,7 +847,7 @@ static int do_grow(struct gfs2_inode *ip, u64 size)
        }
 
        ip->i_di.di_size = size;
-       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
 
        error = gfs2_meta_inode_buffer(ip, &dibh);
        if (error)
@@ -885,7 +885,6 @@ static int gfs2_block_truncate_page(struct address_space *mapping)
        unsigned blocksize, iblock, length, pos;
        struct buffer_head *bh;
        struct page *page;
-       void *kaddr;
        int err;
 
        page = grab_cache_page(mapping, index);
@@ -928,15 +927,13 @@ static int gfs2_block_truncate_page(struct address_space *mapping)
                /* Uhhuh. Read error. Complain and punt. */
                if (!buffer_uptodate(bh))
                        goto unlock;
+               err = 0;
        }
 
        if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip))
                gfs2_trans_add_bh(ip->i_gl, bh, 0);
 
-       kaddr = kmap_atomic(page, KM_USER0);
-       memset(kaddr + offset, 0, length);
-       flush_dcache_page(page);
-       kunmap_atomic(kaddr, KM_USER0);
+       zero_user_page(page, offset, length, KM_USER0);
 
 unlock:
        unlock_page(page);
@@ -962,7 +959,7 @@ static int trunc_start(struct gfs2_inode *ip, u64 size)
 
        if (gfs2_is_stuffed(ip)) {
                ip->i_di.di_size = size;
-               ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+               ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
                gfs2_trans_add_bh(ip->i_gl, dibh, 1);
                gfs2_dinode_out(ip, dibh->b_data);
                gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode) + size);
@@ -974,7 +971,7 @@ static int trunc_start(struct gfs2_inode *ip, u64 size)
 
                if (!error) {
                        ip->i_di.di_size = size;
-                       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+                       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
                        ip->i_di.di_flags |= GFS2_DIF_TRUNC_IN_PROG;
                        gfs2_trans_add_bh(ip->i_gl, dibh, 1);
                        gfs2_dinode_out(ip, dibh->b_data);
@@ -1044,10 +1041,10 @@ static int trunc_end(struct gfs2_inode *ip)
                ip->i_di.di_height = 0;
                ip->i_di.di_goal_meta =
                        ip->i_di.di_goal_data =
-                       ip->i_num.no_addr;
+                       ip->i_no_addr;
                gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode));
        }
-       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
        ip->i_di.di_flags &= ~GFS2_DIF_TRUNC_IN_PROG;
 
        gfs2_trans_add_bh(ip->i_gl, dibh, 1);
index 683cb5bda870fc372e79500c105ddf16c9ab93b9..3548d9f31e0d5c6918d74115a5fd0f9f2b133f48 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/delay.h>
 #include <linux/gfs2_ondisk.h>
 #include <linux/lm_interface.h>
+#include <linux/freezer.h>
 
 #include "gfs2.h"
 #include "incore.h"
@@ -49,6 +50,8 @@ int gfs2_scand(void *data)
        while (!kthread_should_stop()) {
                gfs2_scand_internal(sdp);
                t = gfs2_tune_get(sdp, gt_scand_secs) * HZ;
+               if (freezing(current))
+                       refrigerator();
                schedule_timeout_interruptible(t);
        }
 
@@ -74,6 +77,8 @@ int gfs2_glockd(void *data)
                wait_event_interruptible(sdp->sd_reclaim_wq,
                                         (atomic_read(&sdp->sd_reclaim_count) ||
                                         kthread_should_stop()));
+               if (freezing(current))
+                       refrigerator();
        }
 
        return 0;
@@ -93,6 +98,8 @@ int gfs2_recoverd(void *data)
        while (!kthread_should_stop()) {
                gfs2_check_journals(sdp);
                t = gfs2_tune_get(sdp,  gt_recoverd_secs) * HZ;
+               if (freezing(current))
+                       refrigerator();
                schedule_timeout_interruptible(t);
        }
 
@@ -141,6 +148,8 @@ int gfs2_logd(void *data)
                }
 
                t = gfs2_tune_get(sdp, gt_logd_secs) * HZ;
+               if (freezing(current))
+                       refrigerator();
                schedule_timeout_interruptible(t);
        }
 
@@ -191,6 +200,8 @@ int gfs2_quotad(void *data)
                gfs2_quota_scan(sdp);
 
                t = gfs2_tune_get(sdp, gt_quotad_secs) * HZ;
+               if (freezing(current))
+                       refrigerator();
                schedule_timeout_interruptible(t);
        }
 
index a96fa07b3f3bfdd382b0e41c565bfb26be71f82e..2beb2f401aa24a2b23cf511d813d21db06e521b7 100644 (file)
@@ -130,7 +130,7 @@ static int gfs2_dir_write_stuffed(struct gfs2_inode *ip, const char *buf,
        memcpy(dibh->b_data + offset + sizeof(struct gfs2_dinode), buf, size);
        if (ip->i_di.di_size < offset + size)
                ip->i_di.di_size = offset + size;
-       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
        gfs2_dinode_out(ip, dibh->b_data);
 
        brelse(dibh);
@@ -228,7 +228,7 @@ out:
 
        if (ip->i_di.di_size < offset + copied)
                ip->i_di.di_size = offset + copied;
-       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
 
        gfs2_trans_add_bh(ip->i_gl, dibh, 1);
        gfs2_dinode_out(ip, dibh->b_data);
@@ -1456,7 +1456,7 @@ int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque,
                if (dip->i_di.di_entries != g.offset) {
                        fs_warn(sdp, "Number of entries corrupt in dir %llu, "
                                "ip->i_di.di_entries (%u) != g.offset (%u)\n",
-                               (unsigned long long)dip->i_num.no_addr,
+                               (unsigned long long)dip->i_no_addr,
                                dip->i_di.di_entries,
                                g.offset);
                        error = -EIO;
@@ -1488,24 +1488,55 @@ out:
  * Returns: errno
  */
 
-int gfs2_dir_search(struct inode *dir, const struct qstr *name,
-                   struct gfs2_inum_host *inum, unsigned int *type)
+struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *name)
 {
        struct buffer_head *bh;
        struct gfs2_dirent *dent;
+       struct inode *inode;
+
+       dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh);
+       if (dent) {
+               if (IS_ERR(dent))
+                       return ERR_PTR(PTR_ERR(dent));
+               inode = gfs2_inode_lookup(dir->i_sb, 
+                               be16_to_cpu(dent->de_type),
+                               be64_to_cpu(dent->de_inum.no_addr),
+                               be64_to_cpu(dent->de_inum.no_formal_ino));
+               brelse(bh);
+               return inode;
+       }
+       return ERR_PTR(-ENOENT);
+}
+
+int gfs2_dir_check(struct inode *dir, const struct qstr *name,
+                  const struct gfs2_inode *ip)
+{
+       struct buffer_head *bh;
+       struct gfs2_dirent *dent;
+       int ret = -ENOENT;
 
        dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh);
        if (dent) {
                if (IS_ERR(dent))
                        return PTR_ERR(dent);
-               if (inum)
-                       gfs2_inum_in(inum, (char *)&dent->de_inum);
-               if (type)
-                       *type = be16_to_cpu(dent->de_type);
+               if (ip) {
+                       if (be64_to_cpu(dent->de_inum.no_addr) != ip->i_no_addr)
+                               goto out;
+                       if (be64_to_cpu(dent->de_inum.no_formal_ino) !=
+                           ip->i_no_formal_ino)
+                               goto out;
+                       if (unlikely(IF2DT(ip->i_inode.i_mode) !=
+                           be16_to_cpu(dent->de_type))) {
+                               gfs2_consist_inode(GFS2_I(dir));
+                               ret = -EIO;
+                               goto out;
+                       }
+               }
+               ret = 0;
+out:
                brelse(bh);
-               return 0;
        }
-       return -ENOENT;
+       return ret;
 }
 
 static int dir_new_leaf(struct inode *inode, const struct qstr *name)
@@ -1565,7 +1596,7 @@ static int dir_new_leaf(struct inode *inode, const struct qstr *name)
  */
 
 int gfs2_dir_add(struct inode *inode, const struct qstr *name,
-                const struct gfs2_inum_host *inum, unsigned type)
+                const struct gfs2_inode *nip, unsigned type)
 {
        struct gfs2_inode *ip = GFS2_I(inode);
        struct buffer_head *bh;
@@ -1580,7 +1611,7 @@ int gfs2_dir_add(struct inode *inode, const struct qstr *name,
                        if (IS_ERR(dent))
                                return PTR_ERR(dent);
                        dent = gfs2_init_dirent(inode, dent, name, bh);
-                       gfs2_inum_out(inum, (char *)&dent->de_inum);
+                       gfs2_inum_out(nip, dent);
                        dent->de_type = cpu_to_be16(type);
                        if (ip->i_di.di_flags & GFS2_DIF_EXHASH) {
                                leaf = (struct gfs2_leaf *)bh->b_data;
@@ -1592,7 +1623,7 @@ int gfs2_dir_add(struct inode *inode, const struct qstr *name,
                                break;
                        gfs2_trans_add_bh(ip->i_gl, bh, 1);
                        ip->i_di.di_entries++;
-                       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+                       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
                        gfs2_dinode_out(ip, bh->b_data);
                        brelse(bh);
                        error = 0;
@@ -1678,7 +1709,7 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name)
                gfs2_consist_inode(dip);
        gfs2_trans_add_bh(dip->i_gl, bh, 1);
        dip->i_di.di_entries--;
-       dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME_SEC;
+       dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME;
        gfs2_dinode_out(dip, bh->b_data);
        brelse(bh);
        mark_inode_dirty(&dip->i_inode);
@@ -1700,7 +1731,7 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name)
  */
 
 int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
-                  struct gfs2_inum_host *inum, unsigned int new_type)
+                  const struct gfs2_inode *nip, unsigned int new_type)
 {
        struct buffer_head *bh;
        struct gfs2_dirent *dent;
@@ -1715,7 +1746,7 @@ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
                return PTR_ERR(dent);
 
        gfs2_trans_add_bh(dip->i_gl, bh, 1);
-       gfs2_inum_out(inum, (char *)&dent->de_inum);
+       gfs2_inum_out(nip, dent);
        dent->de_type = cpu_to_be16(new_type);
 
        if (dip->i_di.di_flags & GFS2_DIF_EXHASH) {
@@ -1726,7 +1757,7 @@ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
                gfs2_trans_add_bh(dip->i_gl, bh, 1);
        }
 
-       dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME_SEC;
+       dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME;
        gfs2_dinode_out(dip, bh->b_data);
        brelse(bh);
        return 0;
@@ -1867,7 +1898,7 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len,
        for (x = 0; x < rlist.rl_rgrps; x++) {
                struct gfs2_rgrpd *rgd;
                rgd = rlist.rl_ghs[x].gh_gl->gl_object;
-               rg_blocks += rgd->rd_ri.ri_length;
+               rg_blocks += rgd->rd_length;
        }
 
        error = gfs2_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs);
index 48fe89046bbad39af0277bb3a38d0e1f7f5de813..8a468cac9328abaa4a3b0444bf553caddcdac1ed 100644 (file)
@@ -16,15 +16,16 @@ struct inode;
 struct gfs2_inode;
 struct gfs2_inum;
 
-int gfs2_dir_search(struct inode *dir, const struct qstr *filename,
-                   struct gfs2_inum_host *inum, unsigned int *type);
+struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *filename);
+int gfs2_dir_check(struct inode *dir, const struct qstr *filename,
+                  const struct gfs2_inode *ip);
 int gfs2_dir_add(struct inode *inode, const struct qstr *filename,
-                const struct gfs2_inum_host *inum, unsigned int type);
+                const struct gfs2_inode *ip, unsigned int type);
 int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *filename);
 int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque,
                  filldir_t filldir);
 int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
-                  struct gfs2_inum_host *new_inum, unsigned int new_type);
+                  const struct gfs2_inode *nip, unsigned int new_type);
 
 int gfs2_dir_exhash_dealloc(struct gfs2_inode *dip);
 
index 5b83ca6acab1e5f93829722844a7333f43c305fd..2a7435b5c4dc54442fd464d2053742bea923a56d 100644 (file)
@@ -254,7 +254,7 @@ static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh,
        if (error)
                return error;
 
-       error = gfs2_trans_begin(sdp, rgd->rd_ri.ri_length + RES_DINODE +
+       error = gfs2_trans_begin(sdp, rgd->rd_length + RES_DINODE +
                                 RES_EATTR + RES_STATFS + RES_QUOTA, blks);
        if (error)
                goto out_gunlock;
@@ -300,7 +300,7 @@ static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh,
 
        error = gfs2_meta_inode_buffer(ip, &dibh);
        if (!error) {
-               ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+               ip->i_inode.i_ctime = CURRENT_TIME;
                gfs2_trans_add_bh(ip->i_gl, dibh, 1);
                gfs2_dinode_out(ip, dibh->b_data);
                brelse(dibh);
@@ -700,7 +700,7 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er,
                goto out_gunlock_q;
 
        error = gfs2_trans_begin(GFS2_SB(&ip->i_inode),
-                                blks + al->al_rgd->rd_ri.ri_length +
+                                blks + al->al_rgd->rd_length +
                                 RES_DINODE + RES_STATFS + RES_QUOTA, 0);
        if (error)
                goto out_ipres;
@@ -717,7 +717,7 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er,
                                            (er->er_mode & S_IFMT));
                        ip->i_inode.i_mode = er->er_mode;
                }
-               ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+               ip->i_inode.i_ctime = CURRENT_TIME;
                gfs2_trans_add_bh(ip->i_gl, dibh, 1);
                gfs2_dinode_out(ip, dibh->b_data);
                brelse(dibh);
@@ -852,7 +852,7 @@ static int ea_set_simple_noalloc(struct gfs2_inode *ip, struct buffer_head *bh,
                        (ip->i_inode.i_mode & S_IFMT) == (er->er_mode & S_IFMT));
                ip->i_inode.i_mode = er->er_mode;
        }
-       ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+       ip->i_inode.i_ctime = CURRENT_TIME;
        gfs2_trans_add_bh(ip->i_gl, dibh, 1);
        gfs2_dinode_out(ip, dibh->b_data);
        brelse(dibh);
@@ -1133,7 +1133,7 @@ static int ea_remove_stuffed(struct gfs2_inode *ip, struct gfs2_ea_location *el)
 
        error = gfs2_meta_inode_buffer(ip, &dibh);
        if (!error) {
-               ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+               ip->i_inode.i_ctime = CURRENT_TIME;
                gfs2_trans_add_bh(ip->i_gl, dibh, 1);
                gfs2_dinode_out(ip, dibh->b_data);
                brelse(dibh);
@@ -1352,7 +1352,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip)
        for (x = 0; x < rlist.rl_rgrps; x++) {
                struct gfs2_rgrpd *rgd;
                rgd = rlist.rl_ghs[x].gh_gl->gl_object;
-               rg_blocks += rgd->rd_ri.ri_length;
+               rg_blocks += rgd->rd_length;
        }
 
        error = gfs2_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs);
index 1815429a29789c7c507752cbb1be118b9954c832..3f0974e1afef8bbd2b706a418f616f38e2817f71 100644 (file)
@@ -422,11 +422,11 @@ void gfs2_holder_uninit(struct gfs2_holder *gh)
 static void gfs2_holder_wake(struct gfs2_holder *gh)
 {
        clear_bit(HIF_WAIT, &gh->gh_iflags);
-       smp_mb();
+       smp_mb__after_clear_bit();
        wake_up_bit(&gh->gh_iflags, HIF_WAIT);
 }
 
-static int holder_wait(void *word)
+static int just_schedule(void *word)
 {
         schedule();
         return 0;
@@ -435,7 +435,20 @@ static int holder_wait(void *word)
 static void wait_on_holder(struct gfs2_holder *gh)
 {
        might_sleep();
-       wait_on_bit(&gh->gh_iflags, HIF_WAIT, holder_wait, TASK_UNINTERRUPTIBLE);
+       wait_on_bit(&gh->gh_iflags, HIF_WAIT, just_schedule, TASK_UNINTERRUPTIBLE);
+}
+
+static void gfs2_demote_wake(struct gfs2_glock *gl)
+{
+        clear_bit(GLF_DEMOTE, &gl->gl_flags);
+        smp_mb__after_clear_bit();
+        wake_up_bit(&gl->gl_flags, GLF_DEMOTE);
+}
+
+static void wait_on_demote(struct gfs2_glock *gl)
+{
+       might_sleep();
+       wait_on_bit(&gl->gl_flags, GLF_DEMOTE, just_schedule, TASK_UNINTERRUPTIBLE);
 }
 
 /**
@@ -528,7 +541,7 @@ static int rq_demote(struct gfs2_glock *gl)
 
        if (gl->gl_state == gl->gl_demote_state ||
            gl->gl_state == LM_ST_UNLOCKED) {
-               clear_bit(GLF_DEMOTE, &gl->gl_flags);
+               gfs2_demote_wake(gl);
                return 0;
        }
        set_bit(GLF_LOCK, &gl->gl_flags);
@@ -666,12 +679,22 @@ static void gfs2_glmutex_unlock(struct gfs2_glock *gl)
  * practise: LM_ST_SHARED and LM_ST_UNLOCKED
  */
 
-static void handle_callback(struct gfs2_glock *gl, unsigned int state)
+static void handle_callback(struct gfs2_glock *gl, unsigned int state, int remote)
 {
        spin_lock(&gl->gl_spin);
        if (test_and_set_bit(GLF_DEMOTE, &gl->gl_flags) == 0) {
                gl->gl_demote_state = state;
                gl->gl_demote_time = jiffies;
+               if (remote && gl->gl_ops->go_type == LM_TYPE_IOPEN &&
+                   gl->gl_object) {
+                       struct inode *inode = igrab(gl->gl_object);
+                       spin_unlock(&gl->gl_spin);
+                       if (inode) {
+                               d_prune_aliases(inode);
+                               iput(inode);
+                       }
+                       return;
+               }
        } else if (gl->gl_demote_state != LM_ST_UNLOCKED) {
                gl->gl_demote_state = state;
        }
@@ -740,7 +763,7 @@ static void xmote_bh(struct gfs2_glock *gl, unsigned int ret)
                if (ret & LM_OUT_CANCELED)
                        op_done = 0;
                else
-                       clear_bit(GLF_DEMOTE, &gl->gl_flags);
+                       gfs2_demote_wake(gl);
        } else {
                spin_lock(&gl->gl_spin);
                list_del_init(&gh->gh_list);
@@ -848,7 +871,7 @@ static void drop_bh(struct gfs2_glock *gl, unsigned int ret)
        gfs2_assert_warn(sdp, !ret);
 
        state_change(gl, LM_ST_UNLOCKED);
-       clear_bit(GLF_DEMOTE, &gl->gl_flags);
+       gfs2_demote_wake(gl);
 
        if (glops->go_inval)
                glops->go_inval(gl, DIO_METADATA);
@@ -1174,7 +1197,7 @@ void gfs2_glock_dq(struct gfs2_holder *gh)
        const struct gfs2_glock_operations *glops = gl->gl_ops;
 
        if (gh->gh_flags & GL_NOCACHE)
-               handle_callback(gl, LM_ST_UNLOCKED);
+               handle_callback(gl, LM_ST_UNLOCKED, 0);
 
        gfs2_glmutex_lock(gl);
 
@@ -1196,6 +1219,13 @@ void gfs2_glock_dq(struct gfs2_holder *gh)
        spin_unlock(&gl->gl_spin);
 }
 
+void gfs2_glock_dq_wait(struct gfs2_holder *gh)
+{
+       struct gfs2_glock *gl = gh->gh_gl;
+       gfs2_glock_dq(gh);
+       wait_on_demote(gl);
+}
+
 /**
  * gfs2_glock_dq_uninit - dequeue a holder from a glock and initialize it
  * @gh: the holder structure
@@ -1297,10 +1327,6 @@ static int nq_m_sync(unsigned int num_gh, struct gfs2_holder *ghs,
  * @num_gh: the number of structures
  * @ghs: an array of struct gfs2_holder structures
  *
- * Figure out how big an impact this function has.  Either:
- * 1) Replace this code with code that calls gfs2_glock_prefetch()
- * 2) Forget async stuff and just call nq_m_sync()
- * 3) Leave it like it is
  *
  * Returns: 0 on success (all glocks acquired),
  *          errno on failure (no glocks acquired)
@@ -1308,62 +1334,28 @@ static int nq_m_sync(unsigned int num_gh, struct gfs2_holder *ghs,
 
 int gfs2_glock_nq_m(unsigned int num_gh, struct gfs2_holder *ghs)
 {
-       int *e;
-       unsigned int x;
-       int borked = 0, serious = 0;
+       struct gfs2_holder *tmp[4];
+       struct gfs2_holder **pph = tmp;
        int error = 0;
 
-       if (!num_gh)
+       switch(num_gh) {
+       case 0:
                return 0;
-
-       if (num_gh == 1) {
+       case 1:
                ghs->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC);
                return gfs2_glock_nq(ghs);
-       }
-
-       e = kcalloc(num_gh, sizeof(struct gfs2_holder *), GFP_KERNEL);
-       if (!e)
-               return -ENOMEM;
-
-       for (x = 0; x < num_gh; x++) {
-               ghs[x].gh_flags |= LM_FLAG_TRY | GL_ASYNC;
-               error = gfs2_glock_nq(&ghs[x]);
-               if (error) {
-                       borked = 1;
-                       serious = error;
-                       num_gh = x;
+       default:
+               if (num_gh <= 4)
                        break;
-               }
-       }
-
-       for (x = 0; x < num_gh; x++) {
-               error = e[x] = glock_wait_internal(&ghs[x]);
-               if (error) {
-                       borked = 1;
-                       if (error != GLR_TRYFAILED && error != GLR_CANCELED)
-                               serious = error;
-               }
+               pph = kmalloc(num_gh * sizeof(struct gfs2_holder *), GFP_NOFS);
+               if (!pph)
+                       return -ENOMEM;
        }
 
-       if (!borked) {
-               kfree(e);
-               return 0;
-       }
-
-       for (x = 0; x < num_gh; x++)
-               if (!e[x])
-                       gfs2_glock_dq(&ghs[x]);
-
-       if (serious)
-               error = serious;
-       else {
-               for (x = 0; x < num_gh; x++)
-                       gfs2_holder_reinit(ghs[x].gh_state, ghs[x].gh_flags,
-                                         &ghs[x]);
-               error = nq_m_sync(num_gh, ghs, (struct gfs2_holder **)e);
-       }
+       error = nq_m_sync(num_gh, ghs, pph);
 
-       kfree(e);
+       if (pph != tmp)
+               kfree(pph);
 
        return error;
 }
@@ -1456,7 +1448,7 @@ static void blocking_cb(struct gfs2_sbd *sdp, struct lm_lockname *name,
        if (!gl)
                return;
 
-       handle_callback(gl, state);
+       handle_callback(gl, state, 1);
 
        spin_lock(&gl->gl_spin);
        run_queue(gl);
@@ -1596,7 +1588,7 @@ void gfs2_reclaim_glock(struct gfs2_sbd *sdp)
        if (gfs2_glmutex_trylock(gl)) {
                if (list_empty(&gl->gl_holders) &&
                    gl->gl_state != LM_ST_UNLOCKED && demote_ok(gl))
-                       handle_callback(gl, LM_ST_UNLOCKED);
+                       handle_callback(gl, LM_ST_UNLOCKED, 0);
                gfs2_glmutex_unlock(gl);
        }
 
@@ -1709,7 +1701,7 @@ static void clear_glock(struct gfs2_glock *gl)
        if (gfs2_glmutex_trylock(gl)) {
                if (list_empty(&gl->gl_holders) &&
                    gl->gl_state != LM_ST_UNLOCKED)
-                       handle_callback(gl, LM_ST_UNLOCKED);
+                       handle_callback(gl, LM_ST_UNLOCKED, 0);
                gfs2_glmutex_unlock(gl);
        }
 }
@@ -1823,7 +1815,8 @@ static int dump_inode(struct glock_iter *gi, struct gfs2_inode *ip)
 
        print_dbg(gi, "  Inode:\n");
        print_dbg(gi, "    num = %llu/%llu\n",
-                   ip->i_num.no_formal_ino, ip->i_num.no_addr);
+                 (unsigned long long)ip->i_no_formal_ino,
+                 (unsigned long long)ip->i_no_addr);
        print_dbg(gi, "    type = %u\n", IF2DT(ip->i_inode.i_mode));
        print_dbg(gi, "    i_flags =");
        for (x = 0; x < 32; x++)
@@ -1909,8 +1902,8 @@ static int dump_glock(struct glock_iter *gi, struct gfs2_glock *gl)
        }
        if (test_bit(GLF_DEMOTE, &gl->gl_flags)) {
                print_dbg(gi, "  Demotion req to state %u (%llu uS ago)\n",
-                         gl->gl_demote_state,
-                         (u64)(jiffies - gl->gl_demote_time)*(1000000/HZ));
+                         gl->gl_demote_state, (unsigned long long)
+                         (jiffies - gl->gl_demote_time)*(1000000/HZ));
        }
        if (gl->gl_ops == &gfs2_inode_glops && gl->gl_object) {
                if (!test_bit(GLF_LOCK, &gl->gl_flags) &&
index b3e152db70c8b9b993bd7a03c845495967cf37b4..7721ca3fff9eee2c4789d141f209949a819f21e2 100644 (file)
@@ -87,6 +87,7 @@ int gfs2_glock_nq(struct gfs2_holder *gh);
 int gfs2_glock_poll(struct gfs2_holder *gh);
 int gfs2_glock_wait(struct gfs2_holder *gh);
 void gfs2_glock_dq(struct gfs2_holder *gh);
+void gfs2_glock_dq_wait(struct gfs2_holder *gh);
 
 void gfs2_glock_dq_uninit(struct gfs2_holder *gh);
 int gfs2_glock_nq_num(struct gfs2_sbd *sdp,
index 7b82657a991096bea7291522f2bd357a5213d24e..777ca46010e875907a49d5972f937cf5f83cdba1 100644 (file)
@@ -156,9 +156,9 @@ static void inode_go_sync(struct gfs2_glock *gl)
                ip = NULL;
 
        if (test_bit(GLF_DIRTY, &gl->gl_flags)) {
-               gfs2_log_flush(gl->gl_sbd, gl);
                if (ip)
                        filemap_fdatawrite(ip->i_inode.i_mapping);
+               gfs2_log_flush(gl->gl_sbd, gl);
                gfs2_meta_sync(gl);
                if (ip) {
                        struct address_space *mapping = ip->i_inode.i_mapping;
index d995441373abb5132dc4baf792a9ef14c27b985e..170ba93829c037881996c944fc8ae02adfcd2c52 100644 (file)
@@ -28,6 +28,14 @@ struct gfs2_sbd;
 
 typedef void (*gfs2_glop_bh_t) (struct gfs2_glock *gl, unsigned int ret);
 
+struct gfs2_log_header_host {
+       u64 lh_sequence;        /* Sequence number of this transaction */
+       u32 lh_flags;           /* GFS2_LOG_HEAD_... */
+       u32 lh_tail;            /* Block number of log tail */
+       u32 lh_blkno;
+       u32 lh_hash;
+};
+
 /*
  * Structure of operations that are associated with each
  * type of element in the log.
@@ -60,12 +68,23 @@ struct gfs2_bitmap {
        u32 bi_len;
 };
 
+struct gfs2_rgrp_host {
+       u32 rg_flags;
+       u32 rg_free;
+       u32 rg_dinodes;
+       u64 rg_igeneration;
+};
+
 struct gfs2_rgrpd {
        struct list_head rd_list;       /* Link with superblock */
        struct list_head rd_list_mru;
        struct list_head rd_recent;     /* Recently used rgrps */
        struct gfs2_glock *rd_gl;       /* Glock for this rgrp */
-       struct gfs2_rindex_host rd_ri;
+       u64 rd_addr;                    /* grp block disk address */
+       u64 rd_data0;                   /* first data location */
+       u32 rd_length;                  /* length of rgrp header in fs blocks */
+       u32 rd_data;                    /* num of data blocks in rgrp */
+       u32 rd_bitbytes;                /* number of bytes in data bitmaps */
        struct gfs2_rgrp_host rd_rg;
        u64 rd_rg_vn;
        struct gfs2_bitmap *rd_bits;
@@ -76,6 +95,8 @@ struct gfs2_rgrpd {
        u32 rd_last_alloc_data;
        u32 rd_last_alloc_meta;
        struct gfs2_sbd *rd_sbd;
+       unsigned long rd_flags;
+#define GFS2_RDF_CHECK        0x0001          /* Need to check for unlinked inodes */
 };
 
 enum gfs2_state_bits {
@@ -211,10 +232,24 @@ enum {
        GIF_SW_PAGED            = 3,
 };
 
+struct gfs2_dinode_host {
+       u64 di_size;            /* number of bytes in file */
+       u64 di_blocks;          /* number of blocks in file */
+       u64 di_goal_meta;       /* rgrp to alloc from next */
+       u64 di_goal_data;       /* data block goal */
+       u64 di_generation;      /* generation number for NFS */
+       u32 di_flags;           /* GFS2_DIF_... */
+       u16 di_height;          /* height of metadata */
+       /* These only apply to directories  */
+       u16 di_depth;           /* Number of bits in the table */
+       u32 di_entries;         /* The number of entries in the directory */
+       u64 di_eattr;           /* extended attribute block number */
+};
+
 struct gfs2_inode {
        struct inode i_inode;
-       struct gfs2_inum_host i_num;
-
+       u64 i_no_addr;
+       u64 i_no_formal_ino;
        unsigned long i_flags;          /* GIF_... */
 
        struct gfs2_dinode_host i_di; /* To be replaced by ref to block */
@@ -275,14 +310,6 @@ enum {
        QDF_LOCKED              = 2,
 };
 
-struct gfs2_quota_lvb {
-        __be32 qb_magic;
-        u32 __pad;
-        __be64 qb_limit;      /* Hard limit of # blocks to alloc */
-        __be64 qb_warn;       /* Warn user when alloc is above this # */
-        __be64 qb_value;       /* Current # blocks allocated */
-};
-
 struct gfs2_quota_data {
        struct list_head qd_list;
        unsigned int qd_count;
@@ -327,7 +354,9 @@ struct gfs2_trans {
 
        unsigned int tr_num_buf;
        unsigned int tr_num_buf_new;
+       unsigned int tr_num_databuf_new;
        unsigned int tr_num_buf_rm;
+       unsigned int tr_num_databuf_rm;
        struct list_head tr_list_buf;
 
        unsigned int tr_num_revoke;
@@ -354,6 +383,12 @@ struct gfs2_jdesc {
        unsigned int jd_blocks;
 };
 
+struct gfs2_statfs_change_host {
+       s64 sc_total;
+       s64 sc_free;
+       s64 sc_dinodes;
+};
+
 #define GFS2_GLOCKD_DEFAULT    1
 #define GFS2_GLOCKD_MAX                16
 
@@ -426,6 +461,28 @@ enum {
 
 #define GFS2_FSNAME_LEN                256
 
+struct gfs2_inum_host {
+       u64 no_formal_ino;
+       u64 no_addr;
+};
+
+struct gfs2_sb_host {
+       u32 sb_magic;
+       u32 sb_type;
+       u32 sb_format;
+
+       u32 sb_fs_format;
+       u32 sb_multihost_format;
+       u32 sb_bsize;
+       u32 sb_bsize_shift;
+
+       struct gfs2_inum_host sb_master_dir;
+       struct gfs2_inum_host sb_root_dir;
+
+       char sb_lockproto[GFS2_LOCKNAME_LEN];
+       char sb_locktable[GFS2_LOCKNAME_LEN];
+};
+
 struct gfs2_sbd {
        struct super_block *sd_vfs;
        struct super_block *sd_vfs_meta;
@@ -544,6 +601,7 @@ struct gfs2_sbd {
 
        unsigned int sd_log_blks_reserved;
        unsigned int sd_log_commited_buf;
+       unsigned int sd_log_commited_databuf;
        unsigned int sd_log_commited_revoke;
 
        unsigned int sd_log_num_gl;
@@ -552,7 +610,6 @@ struct gfs2_sbd {
        unsigned int sd_log_num_rg;
        unsigned int sd_log_num_databuf;
        unsigned int sd_log_num_jdata;
-       unsigned int sd_log_num_hdrs;
 
        struct list_head sd_log_le_gl;
        struct list_head sd_log_le_buf;
index df0b8b3018b934e72a30830b5a2936498c969be9..34f7bcdea1e972e00187013eddd98272d65a40f0 100644 (file)
 #include "trans.h"
 #include "util.h"
 
+struct gfs2_inum_range_host {
+       u64 ir_start;
+       u64 ir_length;
+};
+
 static int iget_test(struct inode *inode, void *opaque)
 {
        struct gfs2_inode *ip = GFS2_I(inode);
-       struct gfs2_inum_host *inum = opaque;
+       u64 *no_addr = opaque;
 
-       if (ip->i_num.no_addr == inum->no_addr &&
+       if (ip->i_no_addr == *no_addr &&
            inode->i_private != NULL)
                return 1;
 
@@ -53,37 +58,70 @@ static int iget_test(struct inode *inode, void *opaque)
 static int iget_set(struct inode *inode, void *opaque)
 {
        struct gfs2_inode *ip = GFS2_I(inode);
-       struct gfs2_inum_host *inum = opaque;
+       u64 *no_addr = opaque;
 
-       ip->i_num = *inum;
-       inode->i_ino = inum->no_addr;
+       inode->i_ino = (unsigned long)*no_addr;
+       ip->i_no_addr = *no_addr;
        return 0;
 }
 
-struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum_host *inum)
+struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr)
+{
+       unsigned long hash = (unsigned long)no_addr;
+       return ilookup5(sb, hash, iget_test, &no_addr);
+}
+
+static struct inode *gfs2_iget(struct super_block *sb, u64 no_addr)
 {
-       return ilookup5(sb, (unsigned long)inum->no_addr,
-                       iget_test, inum);
+       unsigned long hash = (unsigned long)no_addr;
+       return iget5_locked(sb, hash, iget_test, iget_set, &no_addr);
 }
 
-static struct inode *gfs2_iget(struct super_block *sb, struct gfs2_inum_host *inum)
+/**
+ * GFS2 lookup code fills in vfs inode contents based on info obtained
+ * from directory entry inside gfs2_inode_lookup(). This has caused issues
+ * with NFS code path since its get_dentry routine doesn't have the relevant
+ * directory entry when gfs2_inode_lookup() is invoked. Part of the code
+ * segment inside gfs2_inode_lookup code needs to get moved around.
+ *
+ * Clean up I_LOCK and I_NEW as well.
+ **/
+
+void gfs2_set_iop(struct inode *inode)
 {
-       return iget5_locked(sb, (unsigned long)inum->no_addr,
-                    iget_test, iget_set, inum);
+       umode_t mode = inode->i_mode;
+
+       if (S_ISREG(mode)) {
+               inode->i_op = &gfs2_file_iops;
+               inode->i_fop = &gfs2_file_fops;
+               inode->i_mapping->a_ops = &gfs2_file_aops;
+       } else if (S_ISDIR(mode)) {
+               inode->i_op = &gfs2_dir_iops;
+               inode->i_fop = &gfs2_dir_fops;
+       } else if (S_ISLNK(mode)) {
+               inode->i_op = &gfs2_symlink_iops;
+       } else {
+               inode->i_op = &gfs2_dev_iops;
+       }
+
+       unlock_new_inode(inode);
 }
 
 /**
  * gfs2_inode_lookup - Lookup an inode
  * @sb: The super block
- * @inum: The inode number
+ * @no_addr: The inode number
  * @type: The type of the inode
  *
  * Returns: A VFS inode, or an error
  */
 
-struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum_host *inum, unsigned int type)
+struct inode *gfs2_inode_lookup(struct super_block *sb, 
+                               unsigned int type,
+                               u64 no_addr,
+                               u64 no_formal_ino)
 {
-       struct inode *inode = gfs2_iget(sb, inum);
+       struct inode *inode = gfs2_iget(sb, no_addr);
        struct gfs2_inode *ip = GFS2_I(inode);
        struct gfs2_glock *io_gl;
        int error;
@@ -93,29 +131,15 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum_host *i
 
        if (inode->i_state & I_NEW) {
                struct gfs2_sbd *sdp = GFS2_SB(inode);
-               umode_t mode = DT2IF(type);
                inode->i_private = ip;
-               inode->i_mode = mode;
-
-               if (S_ISREG(mode)) {
-                       inode->i_op = &gfs2_file_iops;
-                       inode->i_fop = &gfs2_file_fops;
-                       inode->i_mapping->a_ops = &gfs2_file_aops;
-               } else if (S_ISDIR(mode)) {
-                       inode->i_op = &gfs2_dir_iops;
-                       inode->i_fop = &gfs2_dir_fops;
-               } else if (S_ISLNK(mode)) {
-                       inode->i_op = &gfs2_symlink_iops;
-               } else {
-                       inode->i_op = &gfs2_dev_iops;
-               }
+               ip->i_no_formal_ino = no_formal_ino;
 
-               error = gfs2_glock_get(sdp, inum->no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl);
+               error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl);
                if (unlikely(error))
                        goto fail;
                ip->i_gl->gl_object = ip;
 
-               error = gfs2_glock_get(sdp, inum->no_addr, &gfs2_iopen_glops, CREATE, &io_gl);
+               error = gfs2_glock_get(sdp, no_addr, &gfs2_iopen_glops, CREATE, &io_gl);
                if (unlikely(error))
                        goto fail_put;
 
@@ -123,12 +147,38 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum_host *i
                error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh);
                if (unlikely(error))
                        goto fail_iopen;
+               ip->i_iopen_gh.gh_gl->gl_object = ip;
 
                gfs2_glock_put(io_gl);
-               unlock_new_inode(inode);
+
+               if ((type == DT_UNKNOWN) && (no_formal_ino == 0))
+                       goto gfs2_nfsbypass;
+
+               inode->i_mode = DT2IF(type);
+
+               /*
+                * We must read the inode in order to work out its type in
+                * this case. Note that this doesn't happen often as we normally
+                * know the type beforehand. This code path only occurs during
+                * unlinked inode recovery (where it is safe to do this glock,
+                * which is not true in the general case).
+                */
+               if (type == DT_UNKNOWN) {
+                       struct gfs2_holder gh;
+                       error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
+                       if (unlikely(error))
+                               goto fail_glock;
+                       /* Inode is now uptodate */
+                       gfs2_glock_dq_uninit(&gh);
+               }
+
+               gfs2_set_iop(inode);
        }
 
+gfs2_nfsbypass:
        return inode;
+fail_glock:
+       gfs2_glock_dq(&ip->i_iopen_gh);
 fail_iopen:
        gfs2_glock_put(io_gl);
 fail_put:
@@ -144,14 +194,12 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
        struct gfs2_dinode_host *di = &ip->i_di;
        const struct gfs2_dinode *str = buf;
 
-       if (ip->i_num.no_addr != be64_to_cpu(str->di_num.no_addr)) {
+       if (ip->i_no_addr != be64_to_cpu(str->di_num.no_addr)) {
                if (gfs2_consist_inode(ip))
                        gfs2_dinode_print(ip);
                return -EIO;
        }
-       if (ip->i_num.no_formal_ino != be64_to_cpu(str->di_num.no_formal_ino))
-               return -ESTALE;
-
+       ip->i_no_formal_ino = be64_to_cpu(str->di_num.no_formal_ino);
        ip->i_inode.i_mode = be32_to_cpu(str->di_mode);
        ip->i_inode.i_rdev = 0;
        switch (ip->i_inode.i_mode & S_IFMT) {
@@ -175,11 +223,11 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
        di->di_blocks = be64_to_cpu(str->di_blocks);
        gfs2_set_inode_blocks(&ip->i_inode);
        ip->i_inode.i_atime.tv_sec = be64_to_cpu(str->di_atime);
-       ip->i_inode.i_atime.tv_nsec = 0;
+       ip->i_inode.i_atime.tv_nsec = be32_to_cpu(str->di_atime_nsec);
        ip->i_inode.i_mtime.tv_sec = be64_to_cpu(str->di_mtime);
-       ip->i_inode.i_mtime.tv_nsec = 0;
+       ip->i_inode.i_mtime.tv_nsec = be32_to_cpu(str->di_mtime_nsec);
        ip->i_inode.i_ctime.tv_sec = be64_to_cpu(str->di_ctime);
-       ip->i_inode.i_ctime.tv_nsec = 0;
+       ip->i_inode.i_ctime.tv_nsec = be32_to_cpu(str->di_ctime_nsec);
 
        di->di_goal_meta = be64_to_cpu(str->di_goal_meta);
        di->di_goal_data = be64_to_cpu(str->di_goal_data);
@@ -247,7 +295,7 @@ int gfs2_dinode_dealloc(struct gfs2_inode *ip)
        if (error)
                goto out_qs;
 
-       rgd = gfs2_blk2rgrpd(sdp, ip->i_num.no_addr);
+       rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr);
        if (!rgd) {
                gfs2_consist_inode(ip);
                error = -EIO;
@@ -314,7 +362,7 @@ int gfs2_change_nlink(struct gfs2_inode *ip, int diff)
        else
                drop_nlink(&ip->i_inode);
 
-       ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+       ip->i_inode.i_ctime = CURRENT_TIME;
 
        gfs2_trans_add_bh(ip->i_gl, dibh, 1);
        gfs2_dinode_out(ip, dibh->b_data);
@@ -366,9 +414,7 @@ struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name,
        struct super_block *sb = dir->i_sb;
        struct gfs2_inode *dip = GFS2_I(dir);
        struct gfs2_holder d_gh;
-       struct gfs2_inum_host inum;
-       unsigned int type;
-       int error;
+       int error = 0;
        struct inode *inode = NULL;
        int unlock = 0;
 
@@ -395,12 +441,9 @@ struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name,
                        goto out;
        }
 
-       error = gfs2_dir_search(dir, name, &inum, &type);
-       if (error)
-               goto out;
-
-       inode = gfs2_inode_lookup(sb, &inum, type);
-
+       inode = gfs2_dir_search(dir, name);
+       if (IS_ERR(inode))
+               error = PTR_ERR(inode);
 out:
        if (unlock)
                gfs2_glock_dq_uninit(&d_gh);
@@ -409,6 +452,22 @@ out:
        return inode ? inode : ERR_PTR(error);
 }
 
+static void gfs2_inum_range_in(struct gfs2_inum_range_host *ir, const void *buf)
+{
+       const struct gfs2_inum_range *str = buf;
+
+       ir->ir_start = be64_to_cpu(str->ir_start);
+       ir->ir_length = be64_to_cpu(str->ir_length);
+}
+
+static void gfs2_inum_range_out(const struct gfs2_inum_range_host *ir, void *buf)
+{
+       struct gfs2_inum_range *str = buf;
+
+       str->ir_start = cpu_to_be64(ir->ir_start);
+       str->ir_length = cpu_to_be64(ir->ir_length);
+}
+
 static int pick_formal_ino_1(struct gfs2_sbd *sdp, u64 *formal_ino)
 {
        struct gfs2_inode *ip = GFS2_I(sdp->sd_ir_inode);
@@ -548,7 +607,7 @@ static int create_ok(struct gfs2_inode *dip, const struct qstr *name,
        if (!dip->i_inode.i_nlink)
                return -EPERM;
 
-       error = gfs2_dir_search(&dip->i_inode, name, NULL, NULL);
+       error = gfs2_dir_check(&dip->i_inode, name, NULL);
        switch (error) {
        case -ENOENT:
                error = 0;
@@ -588,8 +647,7 @@ static void munge_mode_uid_gid(struct gfs2_inode *dip, unsigned int *mode,
                *gid = current->fsgid;
 }
 
-static int alloc_dinode(struct gfs2_inode *dip, struct gfs2_inum_host *inum,
-                       u64 *generation)
+static int alloc_dinode(struct gfs2_inode *dip, u64 *no_addr, u64 *generation)
 {
        struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
        int error;
@@ -605,7 +663,7 @@ static int alloc_dinode(struct gfs2_inode *dip, struct gfs2_inum_host *inum,
        if (error)
                goto out_ipreserv;
 
-       inum->no_addr = gfs2_alloc_di(dip, generation);
+       *no_addr = gfs2_alloc_di(dip, generation);
 
        gfs2_trans_end(sdp);
 
@@ -635,6 +693,7 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl,
        struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
        struct gfs2_dinode *di;
        struct buffer_head *dibh;
+       struct timespec tv = CURRENT_TIME;
 
        dibh = gfs2_meta_new(gl, inum->no_addr);
        gfs2_trans_add_bh(gl, dibh, 1);
@@ -650,7 +709,7 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl,
        di->di_nlink = 0;
        di->di_size = 0;
        di->di_blocks = cpu_to_be64(1);
-       di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(get_seconds());
+       di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(tv.tv_sec);
        di->di_major = cpu_to_be32(MAJOR(dev));
        di->di_minor = cpu_to_be32(MINOR(dev));
        di->di_goal_meta = di->di_goal_data = cpu_to_be64(inum->no_addr);
@@ -680,6 +739,9 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl,
        di->di_entries = 0;
        memset(&di->__pad4, 0, sizeof(di->__pad4));
        di->di_eattr = 0;
+       di->di_atime_nsec = cpu_to_be32(tv.tv_nsec);
+       di->di_mtime_nsec = cpu_to_be32(tv.tv_nsec);
+       di->di_ctime_nsec = cpu_to_be32(tv.tv_nsec);
        memset(&di->di_reserved, 0, sizeof(di->di_reserved));
 
        brelse(dibh);
@@ -749,7 +811,7 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name,
                        goto fail_quota_locks;
 
                error = gfs2_trans_begin(sdp, sdp->sd_max_dirres +
-                                        al->al_rgd->rd_ri.ri_length +
+                                        al->al_rgd->rd_length +
                                         2 * RES_DINODE +
                                         RES_STATFS + RES_QUOTA, 0);
                if (error)
@@ -760,7 +822,7 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name,
                        goto fail_quota_locks;
        }
 
-       error = gfs2_dir_add(&dip->i_inode, name, &ip->i_num, IF2DT(ip->i_inode.i_mode));
+       error = gfs2_dir_add(&dip->i_inode, name, ip, IF2DT(ip->i_inode.i_mode));
        if (error)
                goto fail_end_trans;
 
@@ -840,11 +902,11 @@ static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip)
 struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
                           unsigned int mode, dev_t dev)
 {
-       struct inode *inode;
+       struct inode *inode = NULL;
        struct gfs2_inode *dip = ghs->gh_gl->gl_object;
        struct inode *dir = &dip->i_inode;
        struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
-       struct gfs2_inum_host inum;
+       struct gfs2_inum_host inum = { .no_addr = 0, .no_formal_ino = 0 };
        int error;
        u64 generation;
 
@@ -864,7 +926,7 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
        if (error)
                goto fail_gunlock;
 
-       error = alloc_dinode(dip, &inum, &generation);
+       error = alloc_dinode(dip, &inum.no_addr, &generation);
        if (error)
                goto fail_gunlock;
 
@@ -877,34 +939,36 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
        if (error)
                goto fail_gunlock2;
 
-       inode = gfs2_inode_lookup(dir->i_sb, &inum, IF2DT(mode));
+       inode = gfs2_inode_lookup(dir->i_sb, IF2DT(mode),
+                                       inum.no_addr,
+                                       inum.no_formal_ino);
        if (IS_ERR(inode))
                goto fail_gunlock2;
 
        error = gfs2_inode_refresh(GFS2_I(inode));
        if (error)
-               goto fail_iput;
+               goto fail_gunlock2;
 
        error = gfs2_acl_create(dip, GFS2_I(inode));
        if (error)
-               goto fail_iput;
+               goto fail_gunlock2;
 
        error = gfs2_security_init(dip, GFS2_I(inode));
        if (error)
-               goto fail_iput;
+               goto fail_gunlock2;
 
        error = link_dinode(dip, name, GFS2_I(inode));
        if (error)
-               goto fail_iput;
+               goto fail_gunlock2;
 
        if (!inode)
                return ERR_PTR(-ENOMEM);
        return inode;
 
-fail_iput:
-       iput(inode);
 fail_gunlock2:
        gfs2_glock_dq_uninit(ghs + 1);
+       if (inode)
+               iput(inode);
 fail_gunlock:
        gfs2_glock_dq(ghs);
 fail:
@@ -976,10 +1040,8 @@ int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name,
  */
 
 int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name,
-                  struct gfs2_inode *ip)
+                  const struct gfs2_inode *ip)
 {
-       struct gfs2_inum_host inum;
-       unsigned int type;
        int error;
 
        if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode))
@@ -997,18 +1059,10 @@ int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name,
        if (error)
                return error;
 
-       error = gfs2_dir_search(&dip->i_inode, name, &inum, &type);
+       error = gfs2_dir_check(&dip->i_inode, name, ip);
        if (error)
                return error;
 
-       if (!gfs2_inum_equal(&inum, &ip->i_num))
-               return -ENOENT;
-
-       if (IF2DT(ip->i_inode.i_mode) != type) {
-               gfs2_consist_inode(dip);
-               return -EIO;
-       }
-
        return 0;
 }
 
@@ -1132,10 +1186,11 @@ int gfs2_glock_nq_atime(struct gfs2_holder *gh)
        struct gfs2_glock *gl = gh->gh_gl;
        struct gfs2_sbd *sdp = gl->gl_sbd;
        struct gfs2_inode *ip = gl->gl_object;
-       s64 curtime, quantum = gfs2_tune_get(sdp, gt_atime_quantum);
+       s64 quantum = gfs2_tune_get(sdp, gt_atime_quantum);
        unsigned int state;
        int flags;
        int error;
+       struct timespec tv = CURRENT_TIME;
 
        if (gfs2_assert_warn(sdp, gh->gh_flags & GL_ATIME) ||
            gfs2_assert_warn(sdp, !(gh->gh_flags & GL_ASYNC)) ||
@@ -1153,8 +1208,7 @@ int gfs2_glock_nq_atime(struct gfs2_holder *gh)
            (sdp->sd_vfs->s_flags & MS_RDONLY))
                return 0;
 
-       curtime = get_seconds();
-       if (curtime - ip->i_inode.i_atime.tv_sec >= quantum) {
+       if (tv.tv_sec - ip->i_inode.i_atime.tv_sec >= quantum) {
                gfs2_glock_dq(gh);
                gfs2_holder_reinit(LM_ST_EXCLUSIVE, gh->gh_flags & ~LM_FLAG_ANY,
                                   gh);
@@ -1165,8 +1219,8 @@ int gfs2_glock_nq_atime(struct gfs2_holder *gh)
                /* Verify that atime hasn't been updated while we were
                   trying to get exclusive lock. */
 
-               curtime = get_seconds();
-               if (curtime - ip->i_inode.i_atime.tv_sec >= quantum) {
+               tv = CURRENT_TIME;
+               if (tv.tv_sec - ip->i_inode.i_atime.tv_sec >= quantum) {
                        struct buffer_head *dibh;
                        struct gfs2_dinode *di;
 
@@ -1180,11 +1234,12 @@ int gfs2_glock_nq_atime(struct gfs2_holder *gh)
                        if (error)
                                goto fail_end_trans;
 
-                       ip->i_inode.i_atime.tv_sec = curtime;
+                       ip->i_inode.i_atime = tv;
 
                        gfs2_trans_add_bh(ip->i_gl, dibh, 1);
                        di = (struct gfs2_dinode *)dibh->b_data;
                        di->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec);
+                       di->di_atime_nsec = cpu_to_be32(ip->i_inode.i_atime.tv_nsec);
                        brelse(dibh);
 
                        gfs2_trans_end(sdp);
@@ -1252,3 +1307,66 @@ int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr)
        return error;
 }
 
+void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf)
+{
+       const struct gfs2_dinode_host *di = &ip->i_di;
+       struct gfs2_dinode *str = buf;
+
+       str->di_header.mh_magic = cpu_to_be32(GFS2_MAGIC);
+       str->di_header.mh_type = cpu_to_be32(GFS2_METATYPE_DI);
+       str->di_header.__pad0 = 0;
+       str->di_header.mh_format = cpu_to_be32(GFS2_FORMAT_DI);
+       str->di_header.__pad1 = 0;
+       str->di_num.no_addr = cpu_to_be64(ip->i_no_addr);
+       str->di_num.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino);
+       str->di_mode = cpu_to_be32(ip->i_inode.i_mode);
+       str->di_uid = cpu_to_be32(ip->i_inode.i_uid);
+       str->di_gid = cpu_to_be32(ip->i_inode.i_gid);
+       str->di_nlink = cpu_to_be32(ip->i_inode.i_nlink);
+       str->di_size = cpu_to_be64(di->di_size);
+       str->di_blocks = cpu_to_be64(di->di_blocks);
+       str->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec);
+       str->di_mtime = cpu_to_be64(ip->i_inode.i_mtime.tv_sec);
+       str->di_ctime = cpu_to_be64(ip->i_inode.i_ctime.tv_sec);
+
+       str->di_goal_meta = cpu_to_be64(di->di_goal_meta);
+       str->di_goal_data = cpu_to_be64(di->di_goal_data);
+       str->di_generation = cpu_to_be64(di->di_generation);
+
+       str->di_flags = cpu_to_be32(di->di_flags);
+       str->di_height = cpu_to_be16(di->di_height);
+       str->di_payload_format = cpu_to_be32(S_ISDIR(ip->i_inode.i_mode) &&
+                                            !(ip->i_di.di_flags & GFS2_DIF_EXHASH) ?
+                                            GFS2_FORMAT_DE : 0);
+       str->di_depth = cpu_to_be16(di->di_depth);
+       str->di_entries = cpu_to_be32(di->di_entries);
+
+       str->di_eattr = cpu_to_be64(di->di_eattr);
+       str->di_atime_nsec = cpu_to_be32(ip->i_inode.i_atime.tv_nsec);
+       str->di_mtime_nsec = cpu_to_be32(ip->i_inode.i_mtime.tv_nsec);
+       str->di_ctime_nsec = cpu_to_be32(ip->i_inode.i_ctime.tv_nsec);
+}
+
+void gfs2_dinode_print(const struct gfs2_inode *ip)
+{
+       const struct gfs2_dinode_host *di = &ip->i_di;
+
+       printk(KERN_INFO "  no_formal_ino = %llu\n",
+              (unsigned long long)ip->i_no_formal_ino);
+       printk(KERN_INFO "  no_addr = %llu\n",
+              (unsigned long long)ip->i_no_addr);
+       printk(KERN_INFO "  di_size = %llu\n", (unsigned long long)di->di_size);
+       printk(KERN_INFO "  di_blocks = %llu\n",
+              (unsigned long long)di->di_blocks);
+       printk(KERN_INFO "  di_goal_meta = %llu\n",
+              (unsigned long long)di->di_goal_meta);
+       printk(KERN_INFO "  di_goal_data = %llu\n",
+              (unsigned long long)di->di_goal_data);
+       printk(KERN_INFO "  di_flags = 0x%.8X\n", di->di_flags);
+       printk(KERN_INFO "  di_height = %u\n", di->di_height);
+       printk(KERN_INFO "  di_depth = %u\n", di->di_depth);
+       printk(KERN_INFO "  di_entries = %u\n", di->di_entries);
+       printk(KERN_INFO "  di_eattr = %llu\n",
+              (unsigned long long)di->di_eattr);
+}
+
index b57f448b15bc42e09c18c2889fe866bdc2efacc6..4517ac82c01c7953b75bc65375e45328262b86dc 100644 (file)
 #ifndef __INODE_DOT_H__
 #define __INODE_DOT_H__
 
-static inline int gfs2_is_stuffed(struct gfs2_inode *ip)
+static inline int gfs2_is_stuffed(const struct gfs2_inode *ip)
 {
        return !ip->i_di.di_height;
 }
 
-static inline int gfs2_is_jdata(struct gfs2_inode *ip)
+static inline int gfs2_is_jdata(const struct gfs2_inode *ip)
 {
        return ip->i_di.di_flags & GFS2_DIF_JDATA;
 }
 
-static inline int gfs2_is_dir(struct gfs2_inode *ip)
+static inline int gfs2_is_dir(const struct gfs2_inode *ip)
 {
        return S_ISDIR(ip->i_inode.i_mode);
 }
@@ -32,9 +32,25 @@ static inline void gfs2_set_inode_blocks(struct inode *inode)
                (GFS2_SB(inode)->sd_sb.sb_bsize_shift - GFS2_BASIC_BLOCK_SHIFT);
 }
 
+static inline int gfs2_check_inum(const struct gfs2_inode *ip, u64 no_addr,
+                                 u64 no_formal_ino)
+{
+       return ip->i_no_addr == no_addr && ip->i_no_formal_ino == no_formal_ino;
+}
+
+static inline void gfs2_inum_out(const struct gfs2_inode *ip,
+                                struct gfs2_dirent *dent)
+{
+       dent->de_inum.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino);
+       dent->de_inum.no_addr = cpu_to_be64(ip->i_no_addr);
+}
+
+
 void gfs2_inode_attr_in(struct gfs2_inode *ip);
-struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum_host *inum, unsigned type);
-struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum_host *inum);
+void gfs2_set_iop(struct inode *inode);
+struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type, 
+                               u64 no_addr, u64 no_formal_ino);
+struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr);
 
 int gfs2_inode_refresh(struct gfs2_inode *ip);
 
@@ -47,12 +63,14 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
 int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name,
                struct gfs2_inode *ip);
 int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name,
-                  struct gfs2_inode *ip);
+                  const struct gfs2_inode *ip);
 int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to);
 int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len);
 int gfs2_glock_nq_atime(struct gfs2_holder *gh);
 int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr);
 struct inode *gfs2_lookup_simple(struct inode *dip, const char *name);
+void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf);
+void gfs2_dinode_print(const struct gfs2_inode *ip);
 
 #endif /* __INODE_DOT_H__ */
 
index c305255bfe8ade71b4e53b8d0b7c5389da0623a0..542a797ac89a453f8cf9d691ad56c8888ac092cb 100644 (file)
@@ -174,7 +174,6 @@ static int gdlm_create_lp(struct gdlm_ls *ls, struct lm_lockname *name,
        lp->cur = DLM_LOCK_IV;
        lp->lvb = NULL;
        lp->hold_null = NULL;
-       init_completion(&lp->ast_wait);
        INIT_LIST_HEAD(&lp->clist);
        INIT_LIST_HEAD(&lp->blist);
        INIT_LIST_HEAD(&lp->delay_list);
@@ -399,6 +398,12 @@ static void gdlm_del_lvb(struct gdlm_lock *lp)
        lp->lksb.sb_lvbptr = NULL;
 }
 
+static int gdlm_ast_wait(void *word)
+{
+       schedule();
+       return 0;
+}
+
 /* This can do a synchronous dlm request (requiring a lock_dlm thread to get
    the completion) because gfs won't call hold_lvb() during a callback (from
    the context of a lock_dlm thread). */
@@ -424,10 +429,10 @@ static int hold_null_lock(struct gdlm_lock *lp)
        lpn->lkf = DLM_LKF_VALBLK | DLM_LKF_EXPEDITE;
        set_bit(LFL_NOBAST, &lpn->flags);
        set_bit(LFL_INLOCK, &lpn->flags);
+       set_bit(LFL_AST_WAIT, &lpn->flags);
 
-       init_completion(&lpn->ast_wait);
        gdlm_do_lock(lpn);
-       wait_for_completion(&lpn->ast_wait);
+       wait_on_bit(&lpn->flags, LFL_AST_WAIT, gdlm_ast_wait, TASK_UNINTERRUPTIBLE);
        error = lpn->lksb.sb_status;
        if (error) {
                printk(KERN_INFO "lock_dlm: hold_null_lock dlm error %d\n",
index d074c6e6f9bfc0cacbbaff393f9c4f6c4a4fd454..24d70f73b65124f3a6960099a82dcf5544b0416d 100644 (file)
@@ -101,6 +101,7 @@ enum {
        LFL_NOBAST              = 10,
        LFL_HEADQUE             = 11,
        LFL_UNLOCK_DELETE       = 12,
+       LFL_AST_WAIT            = 13,
 };
 
 struct gdlm_lock {
@@ -117,7 +118,6 @@ struct gdlm_lock {
        unsigned long           flags;          /* lock_dlm flags LFL_ */
 
        int                     bast_mode;      /* protected by async_lock */
-       struct completion       ast_wait;
 
        struct list_head        clist;          /* complete */
        struct list_head        blist;          /* blocking */
index 1d8faa3da8af1f984168de88796f89281c8773ea..41c5b04caaba4194712fe955a76750462066d4b2 100644 (file)
@@ -147,7 +147,7 @@ static int gdlm_mount(char *table_name, char *host_data,
 
        error = dlm_new_lockspace(ls->fsname, strlen(ls->fsname),
                                  &ls->dlm_lockspace,
-                                 nodir ? DLM_LSFL_NODIR : 0,
+                                 DLM_LSFL_FS | (nodir ? DLM_LSFL_NODIR : 0),
                                  GDLM_LVB_SIZE);
        if (error) {
                log_error("dlm_new_lockspace error %d", error);
index f82495e18c2d7b32686bbf611177396ff6b10da5..fba1f1d87e4fbe92cceb66fd44eb7ee40a8a6d84 100644 (file)
@@ -242,7 +242,7 @@ int gdlm_plock_get(void *lockspace, struct lm_lockname *name,
        op->info.number         = name->ln_number;
        op->info.start          = fl->fl_start;
        op->info.end            = fl->fl_end;
-
+       op->info.owner          = (__u64)(long) fl->fl_owner;
 
        send_op(op);
        wait_event(recv_wq, (op->done != 0));
@@ -254,16 +254,20 @@ int gdlm_plock_get(void *lockspace, struct lm_lockname *name,
        }
        spin_unlock(&ops_lock);
 
+       /* info.rv from userspace is 1 for conflict, 0 for no-conflict,
+          -ENOENT if there are no locks on the file */
+
        rv = op->info.rv;
 
        fl->fl_type = F_UNLCK;
        if (rv == -ENOENT)
                rv = 0;
-       else if (rv == 0 && op->info.pid != fl->fl_pid) {
+       else if (rv > 0) {
                fl->fl_type = (op->info.ex) ? F_WRLCK : F_RDLCK;
                fl->fl_pid = op->info.pid;
                fl->fl_start = op->info.start;
                fl->fl_end = op->info.end;
+               rv = 0;
        }
 
        kfree(op);
index 9cf1f168eaf8b281eacf00778f2c1b3d36642edb..1aca51e45092e0eb6c37691ccfa6c0af3cf51682 100644 (file)
@@ -44,6 +44,13 @@ static void process_blocking(struct gdlm_lock *lp, int bast_mode)
        ls->fscb(ls->sdp, cb, &lp->lockname);
 }
 
+static void wake_up_ast(struct gdlm_lock *lp)
+{
+       clear_bit(LFL_AST_WAIT, &lp->flags);
+       smp_mb__after_clear_bit();
+       wake_up_bit(&lp->flags, LFL_AST_WAIT);
+}
+
 static void process_complete(struct gdlm_lock *lp)
 {
        struct gdlm_ls *ls = lp->ls;
@@ -136,7 +143,7 @@ static void process_complete(struct gdlm_lock *lp)
         */
 
        if (test_and_clear_bit(LFL_SYNC_LVB, &lp->flags)) {
-               complete(&lp->ast_wait);
+               wake_up_ast(lp);
                return;
        }
 
@@ -214,7 +221,7 @@ out:
        if (test_bit(LFL_INLOCK, &lp->flags)) {
                clear_bit(LFL_NOBLOCK, &lp->flags);
                lp->cur = lp->req;
-               complete(&lp->ast_wait);
+               wake_up_ast(lp);
                return;
        }
 
index 291415ddfe51cb291ccd66b23703e63a58b089d7..f49a12e24086d36e6975a733c3c1a8b9793c244d 100644 (file)
@@ -83,6 +83,11 @@ static void gfs2_ail1_start_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai)
 
                        gfs2_assert(sdp, bd->bd_ail == ai);
 
+                       if (!bh){
+                               list_move(&bd->bd_ail_st_list, &ai->ai_ail2_list);
+                                continue;
+                        }
+
                        if (!buffer_busy(bh)) {
                                if (!buffer_uptodate(bh)) {
                                        gfs2_log_unlock(sdp);
@@ -125,6 +130,11 @@ static int gfs2_ail1_empty_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai, int fl
                                         bd_ail_st_list) {
                bh = bd->bd_bh;
 
+               if (!bh){
+                       list_move(&bd->bd_ail_st_list, &ai->ai_ail2_list);
+                       continue;
+               }
+
                gfs2_assert(sdp, bd->bd_ail == ai);
 
                if (buffer_busy(bh)) {
@@ -262,8 +272,8 @@ static void ail2_empty(struct gfs2_sbd *sdp, unsigned int new_tail)
  * @sdp: The GFS2 superblock
  * @blks: The number of blocks to reserve
  *
- * Note that we never give out the last 6 blocks of the journal. Thats
- * due to the fact that there is are a small number of header blocks
+ * Note that we never give out the last few blocks of the journal. Thats
+ * due to the fact that there is a small number of header blocks
  * associated with each log flush. The exact number can't be known until
  * flush time, so we ensure that we have just enough free blocks at all
  * times to avoid running out during a log flush.
@@ -274,6 +284,7 @@ static void ail2_empty(struct gfs2_sbd *sdp, unsigned int new_tail)
 int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks)
 {
        unsigned int try = 0;
+       unsigned reserved_blks = 6 * (4096 / sdp->sd_vfs->s_blocksize);
 
        if (gfs2_assert_warn(sdp, blks) ||
            gfs2_assert_warn(sdp, blks <= sdp->sd_jdesc->jd_blocks))
@@ -281,7 +292,7 @@ int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks)
 
        mutex_lock(&sdp->sd_log_reserve_mutex);
        gfs2_log_lock(sdp);
-       while(sdp->sd_log_blks_free <= (blks + 6)) {
+       while(sdp->sd_log_blks_free <= (blks + reserved_blks)) {
                gfs2_log_unlock(sdp);
                gfs2_ail1_empty(sdp, 0);
                gfs2_log_flush(sdp, NULL);
@@ -357,6 +368,58 @@ static inline unsigned int log_distance(struct gfs2_sbd *sdp, unsigned int newer
        return dist;
 }
 
+/**
+ * calc_reserved - Calculate the number of blocks to reserve when
+ *                 refunding a transaction's unused buffers.
+ * @sdp: The GFS2 superblock
+ *
+ * This is complex.  We need to reserve room for all our currently used
+ * metadata buffers (e.g. normal file I/O rewriting file time stamps) and 
+ * all our journaled data buffers for journaled files (e.g. files in the 
+ * meta_fs like rindex, or files for which chattr +j was done.)
+ * If we don't reserve enough space, gfs2_log_refund and gfs2_log_flush
+ * will count it as free space (sd_log_blks_free) and corruption will follow.
+ *
+ * We can have metadata bufs and jdata bufs in the same journal.  So each
+ * type gets its own log header, for which we need to reserve a block.
+ * In fact, each type has the potential for needing more than one header 
+ * in cases where we have more buffers than will fit on a journal page.
+ * Metadata journal entries take up half the space of journaled buffer entries.
+ * Thus, metadata entries have buf_limit (502) and journaled buffers have
+ * databuf_limit (251) before they cause a wrap around.
+ *
+ * Also, we need to reserve blocks for revoke journal entries and one for an
+ * overall header for the lot.
+ *
+ * Returns: the number of blocks reserved
+ */
+static unsigned int calc_reserved(struct gfs2_sbd *sdp)
+{
+       unsigned int reserved = 0;
+       unsigned int mbuf_limit, metabufhdrs_needed;
+       unsigned int dbuf_limit, databufhdrs_needed;
+       unsigned int revokes = 0;
+
+       mbuf_limit = buf_limit(sdp);
+       metabufhdrs_needed = (sdp->sd_log_commited_buf +
+                             (mbuf_limit - 1)) / mbuf_limit;
+       dbuf_limit = databuf_limit(sdp);
+       databufhdrs_needed = (sdp->sd_log_commited_databuf +
+                             (dbuf_limit - 1)) / dbuf_limit;
+
+       if (sdp->sd_log_commited_revoke)
+               revokes = gfs2_struct2blk(sdp, sdp->sd_log_commited_revoke,
+                                         sizeof(u64));
+
+       reserved = sdp->sd_log_commited_buf + metabufhdrs_needed +
+               sdp->sd_log_commited_databuf + databufhdrs_needed +
+               revokes;
+       /* One for the overall header */
+       if (reserved)
+               reserved++;
+       return reserved;
+}
+
 static unsigned int current_tail(struct gfs2_sbd *sdp)
 {
        struct gfs2_ail *ai;
@@ -447,14 +510,14 @@ struct buffer_head *gfs2_log_fake_buf(struct gfs2_sbd *sdp,
        return bh;
 }
 
-static void log_pull_tail(struct gfs2_sbd *sdp, unsigned int new_tail, int pull)
+static void log_pull_tail(struct gfs2_sbd *sdp, unsigned int new_tail)
 {
        unsigned int dist = log_distance(sdp, new_tail, sdp->sd_log_tail);
 
        ail2_empty(sdp, new_tail);
 
        gfs2_log_lock(sdp);
-       sdp->sd_log_blks_free += dist - (pull ? 1 : 0);
+       sdp->sd_log_blks_free += dist;
        gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free <= sdp->sd_jdesc->jd_blocks);
        gfs2_log_unlock(sdp);
 
@@ -504,7 +567,7 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags, int pull)
        brelse(bh);
 
        if (sdp->sd_log_tail != tail)
-               log_pull_tail(sdp, tail, pull);
+               log_pull_tail(sdp, tail);
        else
                gfs2_assert_withdraw(sdp, !pull);
 
@@ -517,6 +580,7 @@ static void log_flush_commit(struct gfs2_sbd *sdp)
        struct list_head *head = &sdp->sd_log_flush_list;
        struct gfs2_log_buf *lb;
        struct buffer_head *bh;
+       int flushcount = 0;
 
        while (!list_empty(head)) {
                lb = list_entry(head->next, struct gfs2_log_buf, lb_list);
@@ -533,9 +597,20 @@ static void log_flush_commit(struct gfs2_sbd *sdp)
                } else
                        brelse(bh);
                kfree(lb);
+               flushcount++;
        }
 
-       log_write_header(sdp, 0, 0);
+       /* If nothing was journaled, the header is unplanned and unwanted. */
+       if (flushcount) {
+               log_write_header(sdp, 0, 0);
+       } else {
+               unsigned int tail;
+               tail = current_tail(sdp);
+
+               gfs2_ail1_empty(sdp, 0);
+               if (sdp->sd_log_tail != tail)
+                       log_pull_tail(sdp, tail);
+       }
 }
 
 /**
@@ -565,7 +640,10 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl)
        INIT_LIST_HEAD(&ai->ai_ail1_list);
        INIT_LIST_HEAD(&ai->ai_ail2_list);
 
-       gfs2_assert_withdraw(sdp, sdp->sd_log_num_buf == sdp->sd_log_commited_buf);
+       gfs2_assert_withdraw(sdp,
+                            sdp->sd_log_num_buf + sdp->sd_log_num_jdata ==
+                            sdp->sd_log_commited_buf +
+                            sdp->sd_log_commited_databuf);
        gfs2_assert_withdraw(sdp,
                        sdp->sd_log_num_revoke == sdp->sd_log_commited_revoke);
 
@@ -576,16 +654,19 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl)
        lops_before_commit(sdp);
        if (!list_empty(&sdp->sd_log_flush_list))
                log_flush_commit(sdp);
-       else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle)
+       else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle){
+               gfs2_log_lock(sdp);
+               sdp->sd_log_blks_free--; /* Adjust for unreserved buffer */
+               gfs2_log_unlock(sdp);
                log_write_header(sdp, 0, PULL);
+       }
        lops_after_commit(sdp, ai);
 
        gfs2_log_lock(sdp);
        sdp->sd_log_head = sdp->sd_log_flush_head;
-       sdp->sd_log_blks_free -= sdp->sd_log_num_hdrs;
        sdp->sd_log_blks_reserved = 0;
        sdp->sd_log_commited_buf = 0;
-       sdp->sd_log_num_hdrs = 0;
+       sdp->sd_log_commited_databuf = 0;
        sdp->sd_log_commited_revoke = 0;
 
        if (!list_empty(&ai->ai_ail1_list)) {
@@ -602,32 +683,26 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl)
 
 static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
 {
-       unsigned int reserved = 0;
+       unsigned int reserved;
        unsigned int old;
 
        gfs2_log_lock(sdp);
 
        sdp->sd_log_commited_buf += tr->tr_num_buf_new - tr->tr_num_buf_rm;
-       gfs2_assert_withdraw(sdp, ((int)sdp->sd_log_commited_buf) >= 0);
+       sdp->sd_log_commited_databuf += tr->tr_num_databuf_new -
+               tr->tr_num_databuf_rm;
+       gfs2_assert_withdraw(sdp, (((int)sdp->sd_log_commited_buf) >= 0) ||
+                            (((int)sdp->sd_log_commited_databuf) >= 0));
        sdp->sd_log_commited_revoke += tr->tr_num_revoke - tr->tr_num_revoke_rm;
        gfs2_assert_withdraw(sdp, ((int)sdp->sd_log_commited_revoke) >= 0);
-
-       if (sdp->sd_log_commited_buf)
-               reserved += sdp->sd_log_commited_buf;
-       if (sdp->sd_log_commited_revoke)
-               reserved += gfs2_struct2blk(sdp, sdp->sd_log_commited_revoke,
-                                           sizeof(u64));
-       if (reserved)
-               reserved++;
-
+       reserved = calc_reserved(sdp);
        old = sdp->sd_log_blks_free;
        sdp->sd_log_blks_free += tr->tr_reserved -
                                 (reserved - sdp->sd_log_blks_reserved);
 
        gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free >= old);
-       gfs2_assert_withdraw(sdp,
-                            sdp->sd_log_blks_free <= sdp->sd_jdesc->jd_blocks +
-                            sdp->sd_log_num_hdrs);
+       gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free <=
+                            sdp->sd_jdesc->jd_blocks);
 
        sdp->sd_log_blks_reserved = reserved;
 
@@ -673,13 +748,13 @@ void gfs2_log_shutdown(struct gfs2_sbd *sdp)
        gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke);
        gfs2_assert_withdraw(sdp, !sdp->sd_log_num_rg);
        gfs2_assert_withdraw(sdp, !sdp->sd_log_num_databuf);
-       gfs2_assert_withdraw(sdp, !sdp->sd_log_num_hdrs);
        gfs2_assert_withdraw(sdp, list_empty(&sdp->sd_ail1_list));
 
        sdp->sd_log_flush_head = sdp->sd_log_head;
        sdp->sd_log_flush_wrapped = 0;
 
-       log_write_header(sdp, GFS2_LOG_HEAD_UNMOUNT, 0);
+       log_write_header(sdp, GFS2_LOG_HEAD_UNMOUNT,
+                        (sdp->sd_log_tail == current_tail(sdp)) ? 0 : PULL);
 
        gfs2_assert_warn(sdp, sdp->sd_log_blks_free == sdp->sd_jdesc->jd_blocks);
        gfs2_assert_warn(sdp, sdp->sd_log_head == sdp->sd_log_tail);
index f82d84d05d233d99806b21c3eb93550759ddbac5..aff70f0698fdd887799e3d23a0057ea715714112 100644 (file)
@@ -17,6 +17,7 @@
 
 #include "gfs2.h"
 #include "incore.h"
+#include "inode.h"
 #include "glock.h"
 #include "log.h"
 #include "lops.h"
@@ -117,15 +118,13 @@ static void buf_lo_before_commit(struct gfs2_sbd *sdp)
        struct gfs2_log_descriptor *ld;
        struct gfs2_bufdata *bd1 = NULL, *bd2;
        unsigned int total = sdp->sd_log_num_buf;
-       unsigned int offset = sizeof(struct gfs2_log_descriptor);
+       unsigned int offset = BUF_OFFSET;
        unsigned int limit;
        unsigned int num;
        unsigned n;
        __be64 *ptr;
 
-       offset += sizeof(__be64) - 1;
-       offset &= ~(sizeof(__be64) - 1);
-       limit = (sdp->sd_sb.sb_bsize - offset)/sizeof(__be64);
+       limit = buf_limit(sdp);
        /* for 4k blocks, limit = 503 */
 
        bd1 = bd2 = list_prepare_entry(bd1, &sdp->sd_log_le_buf, bd_le.le_list);
@@ -134,7 +133,6 @@ static void buf_lo_before_commit(struct gfs2_sbd *sdp)
                if (total > limit)
                        num = limit;
                bh = gfs2_log_get_buf(sdp);
-               sdp->sd_log_num_hdrs++;
                ld = (struct gfs2_log_descriptor *)bh->b_data;
                ptr = (__be64 *)(bh->b_data + offset);
                ld->ld_header.mh_magic = cpu_to_be32(GFS2_MAGIC);
@@ -469,25 +467,28 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
        struct gfs2_inode *ip = GFS2_I(mapping->host);
 
        gfs2_log_lock(sdp);
+       if (!list_empty(&bd->bd_list_tr)) {
+               gfs2_log_unlock(sdp);
+               return;
+       }
        tr->tr_touched = 1;
-       if (list_empty(&bd->bd_list_tr) &&
-           (ip->i_di.di_flags & GFS2_DIF_JDATA)) {
+       if (gfs2_is_jdata(ip)) {
                tr->tr_num_buf++;
                list_add(&bd->bd_list_tr, &tr->tr_list_buf);
-               gfs2_log_unlock(sdp);
-               gfs2_pin(sdp, bd->bd_bh);
-               tr->tr_num_buf_new++;
-       } else {
-               gfs2_log_unlock(sdp);
        }
+       gfs2_log_unlock(sdp);
+       if (!list_empty(&le->le_list))
+               return;
+
        gfs2_trans_add_gl(bd->bd_gl);
-       gfs2_log_lock(sdp);
-       if (list_empty(&le->le_list)) {
-               if (ip->i_di.di_flags & GFS2_DIF_JDATA)
-                       sdp->sd_log_num_jdata++;
-               sdp->sd_log_num_databuf++;
-               list_add(&le->le_list, &sdp->sd_log_le_databuf);
+       if (gfs2_is_jdata(ip)) {
+               sdp->sd_log_num_jdata++;
+               gfs2_pin(sdp, bd->bd_bh);
+               tr->tr_num_databuf_new++;
        }
+       sdp->sd_log_num_databuf++;
+       gfs2_log_lock(sdp);
+       list_add(&le->le_list, &sdp->sd_log_le_databuf);
        gfs2_log_unlock(sdp);
 }
 
@@ -520,7 +521,6 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp)
        LIST_HEAD(started);
        struct gfs2_bufdata *bd1 = NULL, *bd2, *bdt;
        struct buffer_head *bh = NULL,*bh1 = NULL;
-       unsigned int offset = sizeof(struct gfs2_log_descriptor);
        struct gfs2_log_descriptor *ld;
        unsigned int limit;
        unsigned int total_dbuf = sdp->sd_log_num_databuf;
@@ -528,9 +528,7 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp)
        unsigned int num, n;
        __be64 *ptr = NULL;
 
-       offset += 2*sizeof(__be64) - 1;
-       offset &= ~(2*sizeof(__be64) - 1);
-       limit = (sdp->sd_sb.sb_bsize - offset)/sizeof(__be64);
+       limit = databuf_limit(sdp);
 
        /*
         * Start writing ordered buffers, write journaled buffers
@@ -581,10 +579,10 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp)
                                gfs2_log_unlock(sdp);
                                if (!bh) {
                                        bh = gfs2_log_get_buf(sdp);
-                                       sdp->sd_log_num_hdrs++;
                                        ld = (struct gfs2_log_descriptor *)
                                             bh->b_data;
-                                       ptr = (__be64 *)(bh->b_data + offset);
+                                       ptr = (__be64 *)(bh->b_data +
+                                                        DATABUF_OFFSET);
                                        ld->ld_header.mh_magic =
                                                cpu_to_be32(GFS2_MAGIC);
                                        ld->ld_header.mh_type =
@@ -605,7 +603,7 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp)
                                if (unlikely(magic != 0))
                                        set_buffer_escaped(bh1);
                                gfs2_log_lock(sdp);
-                               if (n++ > num)
+                               if (++n >= num)
                                        break;
                        } else if (!bh1) {
                                total_dbuf--;
@@ -622,6 +620,7 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp)
                }
                gfs2_log_unlock(sdp);
                if (bh) {
+                       set_buffer_mapped(bh);
                        set_buffer_dirty(bh);
                        ll_rw_block(WRITE, 1, &bh);
                        bh = NULL;
index 965bc65c7c6432b9f47f3937d4dbd27f5b4c9446..41a00df755879dea4018ae332f40a45155bc9fb6 100644 (file)
 #include <linux/list.h>
 #include "incore.h"
 
+#define BUF_OFFSET \
+       ((sizeof(struct gfs2_log_descriptor) + sizeof(__be64) - 1) & \
+        ~(sizeof(__be64) - 1))
+#define DATABUF_OFFSET \
+       ((sizeof(struct gfs2_log_descriptor) + (2 * sizeof(__be64) - 1)) & \
+        ~(2 * sizeof(__be64) - 1))
+
 extern const struct gfs2_log_operations gfs2_glock_lops;
 extern const struct gfs2_log_operations gfs2_buf_lops;
 extern const struct gfs2_log_operations gfs2_revoke_lops;
@@ -21,6 +28,22 @@ extern const struct gfs2_log_operations gfs2_databuf_lops;
 
 extern const struct gfs2_log_operations *gfs2_log_ops[];
 
+static inline unsigned int buf_limit(struct gfs2_sbd *sdp)
+{
+       unsigned int limit;
+
+       limit = (sdp->sd_sb.sb_bsize - BUF_OFFSET) / sizeof(__be64);
+       return limit;
+}
+
+static inline unsigned int databuf_limit(struct gfs2_sbd *sdp)
+{
+       unsigned int limit;
+
+       limit = (sdp->sd_sb.sb_bsize - DATABUF_OFFSET) / (2 * sizeof(__be64));
+       return limit;
+}
+
 static inline void lops_init_le(struct gfs2_log_element *le,
                                const struct gfs2_log_operations *lops)
 {
index e62d4f620c5841c73b177f2022324b09442e1a13..8da343b34ae733de759c09cefa64e84b71a887c7 100644 (file)
@@ -387,12 +387,18 @@ void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen)
 
                        if (test_clear_buffer_pinned(bh)) {
                                struct gfs2_trans *tr = current->journal_info;
+                               struct gfs2_inode *bh_ip =
+                                       GFS2_I(bh->b_page->mapping->host);
+
                                gfs2_log_lock(sdp);
                                list_del_init(&bd->bd_le.le_list);
                                gfs2_assert_warn(sdp, sdp->sd_log_num_buf);
                                sdp->sd_log_num_buf--;
                                gfs2_log_unlock(sdp);
-                               tr->tr_num_buf_rm++;
+                               if (bh_ip->i_inode.i_private != NULL)
+                                       tr->tr_num_databuf_rm++;
+                               else
+                                       tr->tr_num_buf_rm++;
                                brelse(bh);
                        }
                        if (bd) {
index e037425bc0427e6cff31c6bda1bae2daa16cf626..527bf19d9690f5c58203e1ca1c3fbb0b1e5fa8ae 100644 (file)
@@ -63,7 +63,7 @@ int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num,
 static inline int gfs2_meta_inode_buffer(struct gfs2_inode *ip,
                                         struct buffer_head **bhp)
 {
-       return gfs2_meta_indirect_buffer(ip, 0, ip->i_num.no_addr, 0, bhp);
+       return gfs2_meta_indirect_buffer(ip, 0, ip->i_no_addr, 0, bhp);
 }
 
 struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen);
index 4864659555d4f94d49132a2727a4acd0b5e1d5e4..6f006a804db33c48310c5af608ed4aa53805625c 100644 (file)
@@ -82,20 +82,19 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, char *data_arg, int remount)
        char *options, *o, *v;
        int error = 0;
 
-       if (!remount) {
-               /*  If someone preloaded options, use those instead  */
-               spin_lock(&gfs2_sys_margs_lock);
-               if (gfs2_sys_margs) {
-                       data = gfs2_sys_margs;
-                       gfs2_sys_margs = NULL;
-               }
-               spin_unlock(&gfs2_sys_margs_lock);
-
-               /*  Set some defaults  */
-               args->ar_num_glockd = GFS2_GLOCKD_DEFAULT;
-               args->ar_quota = GFS2_QUOTA_DEFAULT;
-               args->ar_data = GFS2_DATA_DEFAULT;
+       /*  If someone preloaded options, use those instead  */
+       spin_lock(&gfs2_sys_margs_lock);
+       if (!remount && gfs2_sys_margs) {
+               data = gfs2_sys_margs;
+               gfs2_sys_margs = NULL;
        }
+       spin_unlock(&gfs2_sys_margs_lock);
+
+       /*  Set some defaults  */
+       memset(args, 0, sizeof(struct gfs2_args));
+       args->ar_num_glockd = GFS2_GLOCKD_DEFAULT;
+       args->ar_quota = GFS2_QUOTA_DEFAULT;
+       args->ar_data = GFS2_DATA_DEFAULT;
 
        /* Split the options into tokens with the "," character and
           process them */
diff --git a/fs/gfs2/ondisk.c b/fs/gfs2/ondisk.c
deleted file mode 100644 (file)
index d9ecfd2..0000000
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
- * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
- *
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU General Public License version 2.
- */
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/completion.h>
-#include <linux/buffer_head.h>
-
-#include "gfs2.h"
-#include <linux/gfs2_ondisk.h>
-#include <linux/lm_interface.h>
-#include "incore.h"
-
-#define pv(struct, member, fmt) printk(KERN_INFO "  "#member" = "fmt"\n", \
-                                      struct->member);
-
-/*
- * gfs2_xxx_in - read in an xxx struct
- * first arg: the cpu-order structure
- * buf: the disk-order buffer
- *
- * gfs2_xxx_out - write out an xxx struct
- * first arg: the cpu-order structure
- * buf: the disk-order buffer
- *
- * gfs2_xxx_print - print out an xxx struct
- * first arg: the cpu-order structure
- */
-
-void gfs2_inum_in(struct gfs2_inum_host *no, const void *buf)
-{
-       const struct gfs2_inum *str = buf;
-
-       no->no_formal_ino = be64_to_cpu(str->no_formal_ino);
-       no->no_addr = be64_to_cpu(str->no_addr);
-}
-
-void gfs2_inum_out(const struct gfs2_inum_host *no, void *buf)
-{
-       struct gfs2_inum *str = buf;
-
-       str->no_formal_ino = cpu_to_be64(no->no_formal_ino);
-       str->no_addr = cpu_to_be64(no->no_addr);
-}
-
-static void gfs2_inum_print(const struct gfs2_inum_host *no)
-{
-       printk(KERN_INFO "  no_formal_ino = %llu\n", (unsigned long long)no->no_formal_ino);
-       printk(KERN_INFO "  no_addr = %llu\n", (unsigned long long)no->no_addr);
-}
-
-static void gfs2_meta_header_in(struct gfs2_meta_header_host *mh, const void *buf)
-{
-       const struct gfs2_meta_header *str = buf;
-
-       mh->mh_magic = be32_to_cpu(str->mh_magic);
-       mh->mh_type = be32_to_cpu(str->mh_type);
-       mh->mh_format = be32_to_cpu(str->mh_format);
-}
-
-void gfs2_sb_in(struct gfs2_sb_host *sb, const void *buf)
-{
-       const struct gfs2_sb *str = buf;
-
-       gfs2_meta_header_in(&sb->sb_header, buf);
-
-       sb->sb_fs_format = be32_to_cpu(str->sb_fs_format);
-       sb->sb_multihost_format = be32_to_cpu(str->sb_multihost_format);
-       sb->sb_bsize = be32_to_cpu(str->sb_bsize);
-       sb->sb_bsize_shift = be32_to_cpu(str->sb_bsize_shift);
-
-       gfs2_inum_in(&sb->sb_master_dir, (char *)&str->sb_master_dir);
-       gfs2_inum_in(&sb->sb_root_dir, (char *)&str->sb_root_dir);
-
-       memcpy(sb->sb_lockproto, str->sb_lockproto, GFS2_LOCKNAME_LEN);
-       memcpy(sb->sb_locktable, str->sb_locktable, GFS2_LOCKNAME_LEN);
-}
-
-void gfs2_rindex_in(struct gfs2_rindex_host *ri, const void *buf)
-{
-       const struct gfs2_rindex *str = buf;
-
-       ri->ri_addr = be64_to_cpu(str->ri_addr);
-       ri->ri_length = be32_to_cpu(str->ri_length);
-       ri->ri_data0 = be64_to_cpu(str->ri_data0);
-       ri->ri_data = be32_to_cpu(str->ri_data);
-       ri->ri_bitbytes = be32_to_cpu(str->ri_bitbytes);
-
-}
-
-void gfs2_rindex_print(const struct gfs2_rindex_host *ri)
-{
-       printk(KERN_INFO "  ri_addr = %llu\n", (unsigned long long)ri->ri_addr);
-       pv(ri, ri_length, "%u");
-
-       printk(KERN_INFO "  ri_data0 = %llu\n", (unsigned long long)ri->ri_data0);
-       pv(ri, ri_data, "%u");
-
-       pv(ri, ri_bitbytes, "%u");
-}
-
-void gfs2_rgrp_in(struct gfs2_rgrp_host *rg, const void *buf)
-{
-       const struct gfs2_rgrp *str = buf;
-
-       rg->rg_flags = be32_to_cpu(str->rg_flags);
-       rg->rg_free = be32_to_cpu(str->rg_free);
-       rg->rg_dinodes = be32_to_cpu(str->rg_dinodes);
-       rg->rg_igeneration = be64_to_cpu(str->rg_igeneration);
-}
-
-void gfs2_rgrp_out(const struct gfs2_rgrp_host *rg, void *buf)
-{
-       struct gfs2_rgrp *str = buf;
-
-       str->rg_flags = cpu_to_be32(rg->rg_flags);
-       str->rg_free = cpu_to_be32(rg->rg_free);
-       str->rg_dinodes = cpu_to_be32(rg->rg_dinodes);
-       str->__pad = cpu_to_be32(0);
-       str->rg_igeneration = cpu_to_be64(rg->rg_igeneration);
-       memset(&str->rg_reserved, 0, sizeof(str->rg_reserved));
-}
-
-void gfs2_quota_in(struct gfs2_quota_host *qu, const void *buf)
-{
-       const struct gfs2_quota *str = buf;
-
-       qu->qu_limit = be64_to_cpu(str->qu_limit);
-       qu->qu_warn = be64_to_cpu(str->qu_warn);
-       qu->qu_value = be64_to_cpu(str->qu_value);
-}
-
-void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf)
-{
-       const struct gfs2_dinode_host *di = &ip->i_di;
-       struct gfs2_dinode *str = buf;
-
-       str->di_header.mh_magic = cpu_to_be32(GFS2_MAGIC);
-       str->di_header.mh_type = cpu_to_be32(GFS2_METATYPE_DI);
-       str->di_header.__pad0 = 0;
-       str->di_header.mh_format = cpu_to_be32(GFS2_FORMAT_DI);
-       str->di_header.__pad1 = 0;
-
-       gfs2_inum_out(&ip->i_num, &str->di_num);
-
-       str->di_mode = cpu_to_be32(ip->i_inode.i_mode);
-       str->di_uid = cpu_to_be32(ip->i_inode.i_uid);
-       str->di_gid = cpu_to_be32(ip->i_inode.i_gid);
-       str->di_nlink = cpu_to_be32(ip->i_inode.i_nlink);
-       str->di_size = cpu_to_be64(di->di_size);
-       str->di_blocks = cpu_to_be64(di->di_blocks);
-       str->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec);
-       str->di_mtime = cpu_to_be64(ip->i_inode.i_mtime.tv_sec);
-       str->di_ctime = cpu_to_be64(ip->i_inode.i_ctime.tv_sec);
-
-       str->di_goal_meta = cpu_to_be64(di->di_goal_meta);
-       str->di_goal_data = cpu_to_be64(di->di_goal_data);
-       str->di_generation = cpu_to_be64(di->di_generation);
-
-       str->di_flags = cpu_to_be32(di->di_flags);
-       str->di_height = cpu_to_be16(di->di_height);
-       str->di_payload_format = cpu_to_be32(S_ISDIR(ip->i_inode.i_mode) &&
-                                            !(ip->i_di.di_flags & GFS2_DIF_EXHASH) ?
-                                            GFS2_FORMAT_DE : 0);
-       str->di_depth = cpu_to_be16(di->di_depth);
-       str->di_entries = cpu_to_be32(di->di_entries);
-
-       str->di_eattr = cpu_to_be64(di->di_eattr);
-}
-
-void gfs2_dinode_print(const struct gfs2_inode *ip)
-{
-       const struct gfs2_dinode_host *di = &ip->i_di;
-
-       gfs2_inum_print(&ip->i_num);
-
-       printk(KERN_INFO "  di_size = %llu\n", (unsigned long long)di->di_size);
-       printk(KERN_INFO "  di_blocks = %llu\n", (unsigned long long)di->di_blocks);
-       printk(KERN_INFO "  di_goal_meta = %llu\n", (unsigned long long)di->di_goal_meta);
-       printk(KERN_INFO "  di_goal_data = %llu\n", (unsigned long long)di->di_goal_data);
-
-       pv(di, di_flags, "0x%.8X");
-       pv(di, di_height, "%u");
-
-       pv(di, di_depth, "%u");
-       pv(di, di_entries, "%u");
-
-       printk(KERN_INFO "  di_eattr = %llu\n", (unsigned long long)di->di_eattr);
-}
-
-void gfs2_log_header_in(struct gfs2_log_header_host *lh, const void *buf)
-{
-       const struct gfs2_log_header *str = buf;
-
-       gfs2_meta_header_in(&lh->lh_header, buf);
-       lh->lh_sequence = be64_to_cpu(str->lh_sequence);
-       lh->lh_flags = be32_to_cpu(str->lh_flags);
-       lh->lh_tail = be32_to_cpu(str->lh_tail);
-       lh->lh_blkno = be32_to_cpu(str->lh_blkno);
-       lh->lh_hash = be32_to_cpu(str->lh_hash);
-}
-
-void gfs2_inum_range_in(struct gfs2_inum_range_host *ir, const void *buf)
-{
-       const struct gfs2_inum_range *str = buf;
-
-       ir->ir_start = be64_to_cpu(str->ir_start);
-       ir->ir_length = be64_to_cpu(str->ir_length);
-}
-
-void gfs2_inum_range_out(const struct gfs2_inum_range_host *ir, void *buf)
-{
-       struct gfs2_inum_range *str = buf;
-
-       str->ir_start = cpu_to_be64(ir->ir_start);
-       str->ir_length = cpu_to_be64(ir->ir_length);
-}
-
-void gfs2_statfs_change_in(struct gfs2_statfs_change_host *sc, const void *buf)
-{
-       const struct gfs2_statfs_change *str = buf;
-
-       sc->sc_total = be64_to_cpu(str->sc_total);
-       sc->sc_free = be64_to_cpu(str->sc_free);
-       sc->sc_dinodes = be64_to_cpu(str->sc_dinodes);
-}
-
-void gfs2_statfs_change_out(const struct gfs2_statfs_change_host *sc, void *buf)
-{
-       struct gfs2_statfs_change *str = buf;
-
-       str->sc_total = cpu_to_be64(sc->sc_total);
-       str->sc_free = cpu_to_be64(sc->sc_free);
-       str->sc_dinodes = cpu_to_be64(sc->sc_dinodes);
-}
-
-void gfs2_quota_change_in(struct gfs2_quota_change_host *qc, const void *buf)
-{
-       const struct gfs2_quota_change *str = buf;
-
-       qc->qc_change = be64_to_cpu(str->qc_change);
-       qc->qc_flags = be32_to_cpu(str->qc_flags);
-       qc->qc_id = be32_to_cpu(str->qc_id);
-}
-
index 30c15622174fdbc59f3b94ab8cec331001b2a943..26c888890c245bf562931a2ddd54619ac582d36c 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
- * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
+ * Copyright (C) 2004-2007 Red Hat, Inc.  All rights reserved.
  *
  * This copyrighted material is made available to anyone wishing to use,
  * modify, copy, or redistribute it subject to the terms and conditions
@@ -32,6 +32,7 @@
 #include "trans.h"
 #include "rgrp.h"
 #include "ops_file.h"
+#include "super.h"
 #include "util.h"
 #include "glops.h"
 
@@ -49,6 +50,8 @@ static void gfs2_page_add_databufs(struct gfs2_inode *ip, struct page *page,
                end = start + bsize;
                if (end <= from || start >= to)
                        continue;
+               if (gfs2_is_jdata(ip))
+                       set_buffer_uptodate(bh);
                gfs2_trans_add_bh(ip->i_gl, bh, 0);
        }
 }
@@ -134,7 +137,9 @@ static int gfs2_writepage(struct page *page, struct writeback_control *wbc)
                return 0; /* don't care */
        }
 
-       if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip)) {
+       if ((sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip)) &&
+           PageChecked(page)) {
+               ClearPageChecked(page);
                error = gfs2_trans_begin(sdp, RES_DINODE + 1, 0);
                if (error)
                        goto out_ignore;
@@ -203,11 +208,7 @@ static int stuffed_readpage(struct gfs2_inode *ip, struct page *page)
         * so we need to supply one here. It doesn't happen often.
         */
        if (unlikely(page->index)) {
-               kaddr = kmap_atomic(page, KM_USER0);
-               memset(kaddr, 0, PAGE_CACHE_SIZE);
-               kunmap_atomic(kaddr, KM_USER0);
-               flush_dcache_page(page);
-               SetPageUptodate(page);
+               zero_user_page(page, 0, PAGE_CACHE_SIZE, KM_USER0);
                return 0;
        }
 
@@ -449,6 +450,31 @@ out_uninit:
        return error;
 }
 
+/**
+ * adjust_fs_space - Adjusts the free space available due to gfs2_grow
+ * @inode: the rindex inode
+ */
+static void adjust_fs_space(struct inode *inode)
+{
+       struct gfs2_sbd *sdp = inode->i_sb->s_fs_info;
+       struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master;
+       struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local;
+       u64 fs_total, new_free;
+
+       /* Total up the file system space, according to the latest rindex. */
+       fs_total = gfs2_ri_total(sdp);
+
+       spin_lock(&sdp->sd_statfs_spin);
+       if (fs_total > (m_sc->sc_total + l_sc->sc_total))
+               new_free = fs_total - (m_sc->sc_total + l_sc->sc_total);
+       else
+               new_free = 0;
+       spin_unlock(&sdp->sd_statfs_spin);
+       fs_warn(sdp, "File system extended by %llu blocks.\n",
+               (unsigned long long)new_free);
+       gfs2_statfs_change(sdp, new_free, new_free, 0);
+}
+
 /**
  * gfs2_commit_write - Commit write to a file
  * @file: The file to write to
@@ -511,6 +537,9 @@ static int gfs2_commit_write(struct file *file, struct page *page,
                di->di_size = cpu_to_be64(inode->i_size);
        }
 
+       if (inode == sdp->sd_rindex)
+               adjust_fs_space(inode);
+
        brelse(dibh);
        gfs2_trans_end(sdp);
        if (al->al_requested) {
@@ -542,6 +571,23 @@ fail_nounlock:
        return error;
 }
 
+/**
+ * gfs2_set_page_dirty - Page dirtying function
+ * @page: The page to dirty
+ *
+ * Returns: 1 if it dirtyed the page, or 0 otherwise
+ */
+static int gfs2_set_page_dirty(struct page *page)
+{
+       struct gfs2_inode *ip = GFS2_I(page->mapping->host);
+       struct gfs2_sbd *sdp = GFS2_SB(page->mapping->host);
+
+       if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip))
+               SetPageChecked(page);
+       return __set_page_dirty_buffers(page);
+}
+
 /**
  * gfs2_bmap - Block map function
  * @mapping: Address space info
@@ -578,6 +624,8 @@ static void discard_buffer(struct gfs2_sbd *sdp, struct buffer_head *bh)
        if (bd) {
                bd->bd_bh = NULL;
                bh->b_private = NULL;
+               if (!bd->bd_ail && list_empty(&bd->bd_le.le_list))
+                       kmem_cache_free(gfs2_bufdata_cachep, bd);
        }
        gfs2_log_unlock(sdp);
 
@@ -598,6 +646,8 @@ static void gfs2_invalidatepage(struct page *page, unsigned long offset)
        unsigned int curr_off = 0;
 
        BUG_ON(!PageLocked(page));
+       if (offset == 0)
+               ClearPageChecked(page);
        if (!page_has_buffers(page))
                return;
 
@@ -728,8 +778,8 @@ static unsigned limit = 0;
                        return;
 
                fs_warn(sdp, "ip = %llu %llu\n",
-                       (unsigned long long)ip->i_num.no_formal_ino,
-                       (unsigned long long)ip->i_num.no_addr);
+                       (unsigned long long)ip->i_no_formal_ino,
+                       (unsigned long long)ip->i_no_addr);
 
                for (x = 0; x < GFS2_MAX_META_HEIGHT; x++)
                        fs_warn(sdp, "ip->i_cache[%u] = %s\n",
@@ -810,6 +860,7 @@ const struct address_space_operations gfs2_file_aops = {
        .sync_page = block_sync_page,
        .prepare_write = gfs2_prepare_write,
        .commit_write = gfs2_commit_write,
+       .set_page_dirty = gfs2_set_page_dirty,
        .bmap = gfs2_bmap,
        .invalidatepage = gfs2_invalidatepage,
        .releasepage = gfs2_releasepage,
index 35aaee4aa7e1323aea5824948c6ee99529ac2184..fa1b5b3d28b99b50c08d428de760dc6c260b2098 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
- * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
+ * Copyright (C) 2004-2007 Red Hat, Inc.  All rights reserved.
  *
  * This copyrighted material is made available to anyone wishing to use,
  * modify, copy, or redistribute it subject to the terms and conditions
index a6fdc52f554a43d5d195a8282319028d63d54873..793e334d098e19518957371c116f8d9c6f75178d 100644 (file)
@@ -21,6 +21,7 @@
 #include "glock.h"
 #include "ops_dentry.h"
 #include "util.h"
+#include "inode.h"
 
 /**
  * gfs2_drevalidate - Check directory lookup consistency
@@ -40,14 +41,15 @@ static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd)
        struct gfs2_inode *dip = GFS2_I(parent->d_inode);
        struct inode *inode = dentry->d_inode;
        struct gfs2_holder d_gh;
-       struct gfs2_inode *ip;
-       struct gfs2_inum_host inum;
-       unsigned int type;
+       struct gfs2_inode *ip = NULL;
        int error;
        int had_lock=0;
 
-       if (inode && is_bad_inode(inode))
-               goto invalid;
+       if (inode) {
+               if (is_bad_inode(inode))
+                       goto invalid;
+               ip = GFS2_I(inode);
+       }
 
        if (sdp->sd_args.ar_localcaching)
                goto valid;
@@ -59,7 +61,7 @@ static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd)
                        goto fail;
        } 
 
-       error = gfs2_dir_search(parent->d_inode, &dentry->d_name, &inum, &type);
+       error = gfs2_dir_check(parent->d_inode, &dentry->d_name, ip);
        switch (error) {
        case 0:
                if (!inode)
@@ -73,16 +75,6 @@ static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd)
                goto fail_gunlock;
        }
 
-       ip = GFS2_I(inode);
-
-       if (!gfs2_inum_equal(&ip->i_num, &inum))
-               goto invalid_gunlock;
-
-       if (IF2DT(ip->i_inode.i_mode) != type) {
-               gfs2_consist_inode(dip);
-               goto fail_gunlock;
-       }
-
 valid_gunlock:
        if (!had_lock)
                gfs2_glock_dq_uninit(&d_gh);
index aad918337a469136778f32e5367c3fb586da82b2..99ea5659bc2c58a5a41f482043ef25db8b6284ea 100644 (file)
 #include "glops.h"
 #include "inode.h"
 #include "ops_dentry.h"
-#include "ops_export.h"
+#include "ops_fstype.h"
 #include "rgrp.h"
 #include "util.h"
 
+#define GFS2_SMALL_FH_SIZE 4
+#define GFS2_LARGE_FH_SIZE 8
+#define GFS2_OLD_FH_SIZE 10
+
 static struct dentry *gfs2_decode_fh(struct super_block *sb,
                                     __u32 *p,
                                     int fh_len,
@@ -35,31 +39,28 @@ static struct dentry *gfs2_decode_fh(struct super_block *sb,
                                     void *context)
 {
        __be32 *fh = (__force __be32 *)p;
-       struct gfs2_fh_obj fh_obj;
-       struct gfs2_inum_host *this, parent;
+       struct gfs2_inum_host inum, parent;
 
-       this            = &fh_obj.this;
-       fh_obj.imode    = DT_UNKNOWN;
        memset(&parent, 0, sizeof(struct gfs2_inum));
 
        switch (fh_len) {
        case GFS2_LARGE_FH_SIZE:
+       case GFS2_OLD_FH_SIZE:
                parent.no_formal_ino = ((u64)be32_to_cpu(fh[4])) << 32;
                parent.no_formal_ino |= be32_to_cpu(fh[5]);
                parent.no_addr = ((u64)be32_to_cpu(fh[6])) << 32;
                parent.no_addr |= be32_to_cpu(fh[7]);
-               fh_obj.imode = be32_to_cpu(fh[8]);
        case GFS2_SMALL_FH_SIZE:
-               this->no_formal_ino = ((u64)be32_to_cpu(fh[0])) << 32;
-               this->no_formal_ino |= be32_to_cpu(fh[1]);
-               this->no_addr = ((u64)be32_to_cpu(fh[2])) << 32;
-               this->no_addr |= be32_to_cpu(fh[3]);
+               inum.no_formal_ino = ((u64)be32_to_cpu(fh[0])) << 32;
+               inum.no_formal_ino |= be32_to_cpu(fh[1]);
+               inum.no_addr = ((u64)be32_to_cpu(fh[2])) << 32;
+               inum.no_addr |= be32_to_cpu(fh[3]);
                break;
        default:
                return NULL;
        }
 
-       return gfs2_export_ops.find_exported_dentry(sb, &fh_obj, &parent,
+       return gfs2_export_ops.find_exported_dentry(sb, &inum, &parent,
                                                    acceptable, context);
 }
 
@@ -75,10 +76,10 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len,
            (connectable && *len < GFS2_LARGE_FH_SIZE))
                return 255;
 
-       fh[0] = cpu_to_be32(ip->i_num.no_formal_ino >> 32);
-       fh[1] = cpu_to_be32(ip->i_num.no_formal_ino & 0xFFFFFFFF);
-       fh[2] = cpu_to_be32(ip->i_num.no_addr >> 32);
-       fh[3] = cpu_to_be32(ip->i_num.no_addr & 0xFFFFFFFF);
+       fh[0] = cpu_to_be32(ip->i_no_formal_ino >> 32);
+       fh[1] = cpu_to_be32(ip->i_no_formal_ino & 0xFFFFFFFF);
+       fh[2] = cpu_to_be32(ip->i_no_addr >> 32);
+       fh[3] = cpu_to_be32(ip->i_no_addr & 0xFFFFFFFF);
        *len = GFS2_SMALL_FH_SIZE;
 
        if (!connectable || inode == sb->s_root->d_inode)
@@ -90,13 +91,10 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len,
        igrab(inode);
        spin_unlock(&dentry->d_lock);
 
-       fh[4] = cpu_to_be32(ip->i_num.no_formal_ino >> 32);
-       fh[5] = cpu_to_be32(ip->i_num.no_formal_ino & 0xFFFFFFFF);
-       fh[6] = cpu_to_be32(ip->i_num.no_addr >> 32);
-       fh[7] = cpu_to_be32(ip->i_num.no_addr & 0xFFFFFFFF);
-
-       fh[8]  = cpu_to_be32(inode->i_mode);
-       fh[9]  = 0;     /* pad to double word */
+       fh[4] = cpu_to_be32(ip->i_no_formal_ino >> 32);
+       fh[5] = cpu_to_be32(ip->i_no_formal_ino & 0xFFFFFFFF);
+       fh[6] = cpu_to_be32(ip->i_no_addr >> 32);
+       fh[7] = cpu_to_be32(ip->i_no_addr & 0xFFFFFFFF);
        *len = GFS2_LARGE_FH_SIZE;
 
        iput(inode);
@@ -144,7 +142,8 @@ static int gfs2_get_name(struct dentry *parent, char *name,
        ip = GFS2_I(inode);
 
        *name = 0;
-       gnfd.inum = ip->i_num;
+       gnfd.inum.no_addr = ip->i_no_addr;
+       gnfd.inum.no_formal_ino = ip->i_no_formal_ino;
        gnfd.name = name;
 
        error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &gh);
@@ -192,8 +191,7 @@ static struct dentry *gfs2_get_parent(struct dentry *child)
 static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj)
 {
        struct gfs2_sbd *sdp = sb->s_fs_info;
-       struct gfs2_fh_obj *fh_obj = (struct gfs2_fh_obj *)inum_obj;
-       struct gfs2_inum_host *inum = &fh_obj->this;
+       struct gfs2_inum_host *inum = inum_obj;
        struct gfs2_holder i_gh, ri_gh, rgd_gh;
        struct gfs2_rgrpd *rgd;
        struct inode *inode;
@@ -202,9 +200,9 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj)
 
        /* System files? */
 
-       inode = gfs2_ilookup(sb, inum);
+       inode = gfs2_ilookup(sb, inum->no_addr);
        if (inode) {
-               if (GFS2_I(inode)->i_num.no_formal_ino != inum->no_formal_ino) {
+               if (GFS2_I(inode)->i_no_formal_ino != inum->no_formal_ino) {
                        iput(inode);
                        return ERR_PTR(-ESTALE);
                }
@@ -236,7 +234,9 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj)
        gfs2_glock_dq_uninit(&rgd_gh);
        gfs2_glock_dq_uninit(&ri_gh);
 
-       inode = gfs2_inode_lookup(sb, inum, fh_obj->imode);
+       inode = gfs2_inode_lookup(sb, DT_UNKNOWN,
+                                       inum->no_addr,
+                                       0);
        if (!inode)
                goto fail;
        if (IS_ERR(inode)) {
@@ -250,6 +250,15 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj)
                goto fail;
        }
 
+       /* Pick up the works we bypass in gfs2_inode_lookup */
+       if (inode->i_state & I_NEW) 
+               gfs2_set_iop(inode);
+
+       if (GFS2_I(inode)->i_no_formal_ino != inum->no_formal_ino) {
+               iput(inode);
+               goto fail;
+       }
+
        error = -EIO;
        if (GFS2_I(inode)->i_di.di_flags & GFS2_DIF_SYSTEM) {
                iput(inode);
diff --git a/fs/gfs2/ops_export.h b/fs/gfs2/ops_export.h
deleted file mode 100644 (file)
index f925a95..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
- * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
- *
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU General Public License version 2.
- */
-
-#ifndef __OPS_EXPORT_DOT_H__
-#define __OPS_EXPORT_DOT_H__
-
-#define GFS2_SMALL_FH_SIZE 4
-#define GFS2_LARGE_FH_SIZE 10
-
-extern struct export_operations gfs2_export_ops;
-struct gfs2_fh_obj {
-       struct gfs2_inum_host this;
-       __u32            imode;
-};
-
-#endif /* __OPS_EXPORT_DOT_H__ */
index 064df8804582b1f99b9003a78fb2ff39b2a2c254..196d83266e34348a66ce2042449a803568d7c07b 100644 (file)
@@ -502,7 +502,7 @@ static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl)
        struct gfs2_inode *ip = GFS2_I(file->f_mapping->host);
        struct gfs2_sbd *sdp = GFS2_SB(file->f_mapping->host);
        struct lm_lockname name =
-               { .ln_number = ip->i_num.no_addr,
+               { .ln_number = ip->i_no_addr,
                  .ln_type = LM_TYPE_PLOCK };
 
        if (!(fl->fl_flags & FL_POSIX))
@@ -557,7 +557,7 @@ static int do_flock(struct file *file, int cmd, struct file_lock *fl)
                gfs2_glock_dq_uninit(fl_gh);
        } else {
                error = gfs2_glock_get(GFS2_SB(&ip->i_inode),
-                                     ip->i_num.no_addr, &gfs2_flock_glops,
+                                     ip->i_no_addr, &gfs2_flock_glops,
                                      CREATE, &gl);
                if (error)
                        goto out;
@@ -635,7 +635,6 @@ const struct file_operations gfs2_file_fops = {
        .release        = gfs2_close,
        .fsync          = gfs2_fsync,
        .lock           = gfs2_lock,
-       .sendfile       = generic_file_sendfile,
        .flock          = gfs2_flock,
        .splice_read    = generic_file_splice_read,
        .splice_write   = generic_file_splice_write,
index 2c5f8e7def0dc21413ccd5e1fb2e38939d36d907..cf5aa50505488d95a62719f9728660e742728575 100644 (file)
@@ -27,7 +27,6 @@
 #include "inode.h"
 #include "lm.h"
 #include "mount.h"
-#include "ops_export.h"
 #include "ops_fstype.h"
 #include "ops_super.h"
 #include "recovery.h"
@@ -105,6 +104,7 @@ static void init_vfs(struct super_block *sb, unsigned noatime)
        sb->s_magic = GFS2_MAGIC;
        sb->s_op = &gfs2_super_ops;
        sb->s_export_op = &gfs2_export_ops;
+       sb->s_time_gran = 1;
        sb->s_maxbytes = MAX_LFS_FILESIZE;
 
        if (sb->s_flags & (MS_NOATIME | MS_NODIRATIME))
@@ -116,7 +116,6 @@ static void init_vfs(struct super_block *sb, unsigned noatime)
 
 static int init_names(struct gfs2_sbd *sdp, int silent)
 {
-       struct page *page;
        char *proto, *table;
        int error = 0;
 
@@ -126,14 +125,9 @@ static int init_names(struct gfs2_sbd *sdp, int silent)
        /*  Try to autodetect  */
 
        if (!proto[0] || !table[0]) {
-               struct gfs2_sb *sb;
-               page = gfs2_read_super(sdp->sd_vfs, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift);
-               if (!page)
-                       return -ENOBUFS;
-               sb = kmap(page);
-               gfs2_sb_in(&sdp->sd_sb, sb);
-               kunmap(page);
-               __free_page(page);
+               error = gfs2_read_super(sdp, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift);
+               if (error)
+                       return error;
 
                error = gfs2_check_sb(sdp, &sdp->sd_sb, silent);
                if (error)
@@ -151,6 +145,9 @@ static int init_names(struct gfs2_sbd *sdp, int silent)
        snprintf(sdp->sd_proto_name, GFS2_FSNAME_LEN, "%s", proto);
        snprintf(sdp->sd_table_name, GFS2_FSNAME_LEN, "%s", table);
 
+       while ((table = strchr(sdp->sd_table_name, '/')))
+               *table = '_';
+
 out:
        return error;
 }
@@ -236,17 +233,17 @@ fail:
        return error;
 }
 
-static struct inode *gfs2_lookup_root(struct super_block *sb,
-                                     struct gfs2_inum_host *inum)
+static inline struct inode *gfs2_lookup_root(struct super_block *sb,
+                                            u64 no_addr)
 {
-       return gfs2_inode_lookup(sb, inum, DT_DIR);
+       return gfs2_inode_lookup(sb, DT_DIR, no_addr, 0);
 }
 
 static int init_sb(struct gfs2_sbd *sdp, int silent, int undo)
 {
        struct super_block *sb = sdp->sd_vfs;
        struct gfs2_holder sb_gh;
-       struct gfs2_inum_host *inum;
+       u64 no_addr;
        struct inode *inode;
        int error = 0;
 
@@ -289,10 +286,10 @@ static int init_sb(struct gfs2_sbd *sdp, int silent, int undo)
        sb_set_blocksize(sb, sdp->sd_sb.sb_bsize);
 
        /* Get the root inode */
-       inum = &sdp->sd_sb.sb_root_dir;
+       no_addr = sdp->sd_sb.sb_root_dir.no_addr;
        if (sb->s_type == &gfs2meta_fs_type)
-               inum = &sdp->sd_sb.sb_master_dir;
-       inode = gfs2_lookup_root(sb, inum);
+               no_addr = sdp->sd_sb.sb_master_dir.no_addr;
+       inode = gfs2_lookup_root(sb, no_addr);
        if (IS_ERR(inode)) {
                error = PTR_ERR(inode);
                fs_err(sdp, "can't read in root inode: %d\n", error);
@@ -449,7 +446,7 @@ static int init_inodes(struct gfs2_sbd *sdp, int undo)
        if (undo)
                goto fail_qinode;
 
-       inode = gfs2_lookup_root(sdp->sd_vfs, &sdp->sd_sb.sb_master_dir);
+       inode = gfs2_lookup_root(sdp->sd_vfs, sdp->sd_sb.sb_master_dir.no_addr);
        if (IS_ERR(inode)) {
                error = PTR_ERR(inode);
                fs_err(sdp, "can't read in master directory: %d\n", error);
index 7cc2c296271be2d7930879a981013c85c90c49a9..407029b3b2b3857b6564126fe191d1bc96094c67 100644 (file)
@@ -14,5 +14,6 @@
 
 extern struct file_system_type gfs2_fs_type;
 extern struct file_system_type gfs2meta_fs_type;
+extern struct export_operations gfs2_export_ops;
 
 #endif /* __OPS_FSTYPE_DOT_H__ */
index d85f6e05cb955d99cebcad6aa3bd660871cef49f..911c115b5c6c29ecf16aabe087c2be507bb58f71 100644 (file)
@@ -157,7 +157,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
        if (error)
                goto out_gunlock;
 
-       error = gfs2_dir_search(dir, &dentry->d_name, NULL, NULL);
+       error = gfs2_dir_check(dir, &dentry->d_name, NULL);
        switch (error) {
        case -ENOENT:
                break;
@@ -206,7 +206,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
                        goto out_gunlock_q;
 
                error = gfs2_trans_begin(sdp, sdp->sd_max_dirres +
-                                        al->al_rgd->rd_ri.ri_length +
+                                        al->al_rgd->rd_length +
                                         2 * RES_DINODE + RES_STATFS +
                                         RES_QUOTA, 0);
                if (error)
@@ -217,8 +217,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
                        goto out_ipres;
        }
 
-       error = gfs2_dir_add(dir, &dentry->d_name, &ip->i_num,
-                            IF2DT(inode->i_mode));
+       error = gfs2_dir_add(dir, &dentry->d_name, ip, IF2DT(inode->i_mode));
        if (error)
                goto out_end_trans;
 
@@ -275,7 +274,7 @@ static int gfs2_unlink(struct inode *dir, struct dentry *dentry)
        gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
        gfs2_holder_init(ip->i_gl,  LM_ST_EXCLUSIVE, 0, ghs + 1);
 
-       rgd = gfs2_blk2rgrpd(sdp, ip->i_num.no_addr);
+       rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr);
        gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2);
 
 
@@ -420,7 +419,7 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode)
                dent = (struct gfs2_dirent *)((char*)dent + GFS2_DIRENT_SIZE(1));
                gfs2_qstr2dirent(&str, dibh->b_size - GFS2_DIRENT_SIZE(1) - sizeof(struct gfs2_dinode), dent);
 
-               gfs2_inum_out(&dip->i_num, &dent->de_inum);
+               gfs2_inum_out(dip, dent);
                dent->de_type = cpu_to_be16(DT_DIR);
 
                gfs2_dinode_out(ip, di);
@@ -472,7 +471,7 @@ static int gfs2_rmdir(struct inode *dir, struct dentry *dentry)
        gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
        gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1);
 
-       rgd = gfs2_blk2rgrpd(sdp, ip->i_num.no_addr);
+       rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr);
        gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2);
 
        error = gfs2_glock_nq_m(3, ghs);
@@ -614,7 +613,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
                 * this is the case of the target file already existing
                 * so we unlink before doing the rename
                 */
-               nrgd = gfs2_blk2rgrpd(sdp, nip->i_num.no_addr);
+               nrgd = gfs2_blk2rgrpd(sdp, nip->i_no_addr);
                if (nrgd)
                        gfs2_holder_init(nrgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh++);
        }
@@ -653,7 +652,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
                if (error)
                        goto out_gunlock;
 
-               error = gfs2_dir_search(ndir, &ndentry->d_name, NULL, NULL);
+               error = gfs2_dir_check(ndir, &ndentry->d_name, NULL);
                switch (error) {
                case -ENOENT:
                        error = 0;
@@ -712,7 +711,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
                        goto out_gunlock_q;
 
                error = gfs2_trans_begin(sdp, sdp->sd_max_dirres +
-                                        al->al_rgd->rd_ri.ri_length +
+                                        al->al_rgd->rd_length +
                                         4 * RES_DINODE + 4 * RES_LEAF +
                                         RES_STATFS + RES_QUOTA + 4, 0);
                if (error)
@@ -750,7 +749,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
                if (error)
                        goto out_end_trans;
 
-               error = gfs2_dir_mvino(ip, &name, &ndip->i_num, DT_DIR);
+               error = gfs2_dir_mvino(ip, &name, ndip, DT_DIR);
                if (error)
                        goto out_end_trans;
        } else {
@@ -758,7 +757,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
                error = gfs2_meta_inode_buffer(ip, &dibh);
                if (error)
                        goto out_end_trans;
-               ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+               ip->i_inode.i_ctime = CURRENT_TIME;
                gfs2_trans_add_bh(ip->i_gl, dibh, 1);
                gfs2_dinode_out(ip, dibh->b_data);
                brelse(dibh);
@@ -768,8 +767,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
        if (error)
                goto out_end_trans;
 
-       error = gfs2_dir_add(ndir, &ndentry->d_name, &ip->i_num,
-                            IF2DT(ip->i_inode.i_mode));
+       error = gfs2_dir_add(ndir, &ndentry->d_name, ip, IF2DT(ip->i_inode.i_mode));
        if (error)
                goto out_end_trans;
 
@@ -905,8 +903,8 @@ static int setattr_size(struct inode *inode, struct iattr *attr)
        }
 
        error = gfs2_truncatei(ip, attr->ia_size);
-       if (error)
-               return error;
+       if (error && (inode->i_size != ip->i_di.di_size))
+               i_size_write(inode, ip->i_di.di_size);
 
        return error;
 }
index 485ce3d499230c08b7e741e338e569f454dea88c..603d940f1159c2c6612d4e2c4d65cc08a946d327 100644 (file)
@@ -326,8 +326,10 @@ static void gfs2_clear_inode(struct inode *inode)
                gfs2_glock_schedule_for_reclaim(ip->i_gl);
                gfs2_glock_put(ip->i_gl);
                ip->i_gl = NULL;
-               if (ip->i_iopen_gh.gh_gl)
+               if (ip->i_iopen_gh.gh_gl) {
+                       ip->i_iopen_gh.gh_gl->gl_object = NULL;
                        gfs2_glock_dq_uninit(&ip->i_iopen_gh);
+               }
        }
 }
 
@@ -422,13 +424,13 @@ static void gfs2_delete_inode(struct inode *inode)
        if (!inode->i_private)
                goto out;
 
-       error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB, &gh);
+       error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
        if (unlikely(error)) {
                gfs2_glock_dq_uninit(&ip->i_iopen_gh);
                goto out;
        }
 
-       gfs2_glock_dq(&ip->i_iopen_gh);
+       gfs2_glock_dq_wait(&ip->i_iopen_gh);
        gfs2_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, &ip->i_iopen_gh);
        error = gfs2_glock_nq(&ip->i_iopen_gh);
        if (error)
index aa0dbd2aac1bd31bdd3cb4ebf8265fe9b874d47d..404b7cc9f8c4887803d10437c91783a18e655fa0 100644 (file)
@@ -66,7 +66,7 @@ static int alloc_page_backing(struct gfs2_inode *ip, struct page *page)
        if (error)
                goto out_gunlock_q;
 
-       error = gfs2_trans_begin(sdp, al->al_rgd->rd_ri.ri_length +
+       error = gfs2_trans_begin(sdp, al->al_rgd->rd_length +
                                 ind_blocks + RES_DINODE +
                                 RES_STATFS + RES_QUOTA, 0);
        if (error)
index c186857e48a80a49433b81fe2f11986b58c188f7..6e546ee8f3d4d237e01f44aac67db0a35dc0f296 100644 (file)
 #define QUOTA_USER 1
 #define QUOTA_GROUP 0
 
+struct gfs2_quota_host {
+       u64 qu_limit;
+       u64 qu_warn;
+       s64 qu_value;
+};
+
+struct gfs2_quota_change_host {
+       u64 qc_change;
+       u32 qc_flags; /* GFS2_QCF_... */
+       u32 qc_id;
+};
+
 static u64 qd2offset(struct gfs2_quota_data *qd)
 {
        u64 offset;
@@ -561,6 +573,25 @@ static void do_qc(struct gfs2_quota_data *qd, s64 change)
        mutex_unlock(&sdp->sd_quota_mutex);
 }
 
+static void gfs2_quota_in(struct gfs2_quota_host *qu, const void *buf)
+{
+       const struct gfs2_quota *str = buf;
+
+       qu->qu_limit = be64_to_cpu(str->qu_limit);
+       qu->qu_warn = be64_to_cpu(str->qu_warn);
+       qu->qu_value = be64_to_cpu(str->qu_value);
+}
+
+static void gfs2_quota_out(const struct gfs2_quota_host *qu, void *buf)
+{
+       struct gfs2_quota *str = buf;
+
+       str->qu_limit = cpu_to_be64(qu->qu_limit);
+       str->qu_warn = cpu_to_be64(qu->qu_warn);
+       str->qu_value = cpu_to_be64(qu->qu_value);
+       memset(&str->qu_reserved, 0, sizeof(str->qu_reserved));
+}
+
 /**
  * gfs2_adjust_quota
  *
@@ -573,12 +604,13 @@ static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc,
        struct inode *inode = &ip->i_inode;
        struct address_space *mapping = inode->i_mapping;
        unsigned long index = loc >> PAGE_CACHE_SHIFT;
-       unsigned offset = loc & (PAGE_CACHE_SHIFT - 1);
+       unsigned offset = loc & (PAGE_CACHE_SIZE - 1);
        unsigned blocksize, iblock, pos;
        struct buffer_head *bh;
        struct page *page;
        void *kaddr;
-       __be64 *ptr;
+       char *ptr;
+       struct gfs2_quota_host qp;
        s64 value;
        int err = -EIO;
 
@@ -620,13 +652,17 @@ static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc,
 
        kaddr = kmap_atomic(page, KM_USER0);
        ptr = kaddr + offset;
-       value = (s64)be64_to_cpu(*ptr) + change;
-       *ptr = cpu_to_be64(value);
+       gfs2_quota_in(&qp, ptr);
+       qp.qu_value += change;
+       value = qp.qu_value;
+       gfs2_quota_out(&qp, ptr);
        flush_dcache_page(page);
        kunmap_atomic(kaddr, KM_USER0);
        err = 0;
        qd->qd_qb.qb_magic = cpu_to_be32(GFS2_MAGIC);
        qd->qd_qb.qb_value = cpu_to_be64(value);
+       ((struct gfs2_quota_lvb*)(qd->qd_gl->gl_lvb))->qb_magic = cpu_to_be32(GFS2_MAGIC);
+       ((struct gfs2_quota_lvb*)(qd->qd_gl->gl_lvb))->qb_value = cpu_to_be64(value);
 unlock:
        unlock_page(page);
        page_cache_release(page);
@@ -689,7 +725,7 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
                        goto out_alloc;
 
                error = gfs2_trans_begin(sdp,
-                                        al->al_rgd->rd_ri.ri_length +
+                                        al->al_rgd->rd_length +
                                         num_qd * data_blocks +
                                         nalloc * ind_blocks +
                                         RES_DINODE + num_qd +
@@ -709,7 +745,7 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
                offset = qd2offset(qd);
                error = gfs2_adjust_quota(ip, offset, qd->qd_change_sync,
                                          (struct gfs2_quota_data *)
-                                         qd->qd_gl->gl_lvb);
+                                         qd);
                if (error)
                        goto out_end_trans;
 
@@ -1050,6 +1086,15 @@ int gfs2_quota_refresh(struct gfs2_sbd *sdp, int user, u32 id)
        return error;
 }
 
+static void gfs2_quota_change_in(struct gfs2_quota_change_host *qc, const void *buf)
+{
+       const struct gfs2_quota_change *str = buf;
+
+       qc->qc_change = be64_to_cpu(str->qc_change);
+       qc->qc_flags = be32_to_cpu(str->qc_flags);
+       qc->qc_id = be32_to_cpu(str->qc_id);
+}
+
 int gfs2_quota_init(struct gfs2_sbd *sdp)
 {
        struct gfs2_inode *ip = GFS2_I(sdp->sd_qc_inode);
index 8bc182c7e2ef22c2bad269743f15bab5f27a4914..5ada38c99a2c95e49a1abb99a828fa0f860306eb 100644 (file)
@@ -116,6 +116,22 @@ void gfs2_revoke_clean(struct gfs2_sbd *sdp)
        }
 }
 
+static int gfs2_log_header_in(struct gfs2_log_header_host *lh, const void *buf)
+{
+       const struct gfs2_log_header *str = buf;
+
+       if (str->lh_header.mh_magic != cpu_to_be32(GFS2_MAGIC) ||
+           str->lh_header.mh_type != cpu_to_be32(GFS2_METATYPE_LH))
+               return 1;
+
+       lh->lh_sequence = be64_to_cpu(str->lh_sequence);
+       lh->lh_flags = be32_to_cpu(str->lh_flags);
+       lh->lh_tail = be32_to_cpu(str->lh_tail);
+       lh->lh_blkno = be32_to_cpu(str->lh_blkno);
+       lh->lh_hash = be32_to_cpu(str->lh_hash);
+       return 0;
+}
+
 /**
  * get_log_header - read the log header for a given segment
  * @jd: the journal
@@ -147,12 +163,10 @@ static int get_log_header(struct gfs2_jdesc *jd, unsigned int blk,
                                             sizeof(u32));
        hash = crc32_le(hash, (unsigned char const *)&nothing, sizeof(nothing));
        hash ^= (u32)~0;
-       gfs2_log_header_in(&lh, bh->b_data);
+       error = gfs2_log_header_in(&lh, bh->b_data);
        brelse(bh);
 
-       if (lh.lh_header.mh_magic != GFS2_MAGIC ||
-           lh.lh_header.mh_type != GFS2_METATYPE_LH ||
-           lh.lh_blkno != blk || lh.lh_hash != hash)
+       if (error || lh.lh_blkno != blk || lh.lh_hash != hash)
                return 1;
 
        *head = lh;
index 1727f5012efec89ee5724000f7e97ce0c31d2570..e4e040625153aa29b2254e51276eb6ac9807380e 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
- * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
+ * Copyright (C) 2004-2007 Red Hat, Inc.  All rights reserved.
  *
  * This copyrighted material is made available to anyone wishing to use,
  * modify, copy, or redistribute it subject to the terms and conditions
@@ -28,6 +28,7 @@
 #include "ops_file.h"
 #include "util.h"
 #include "log.h"
+#include "inode.h"
 
 #define BFITNOENT ((u32)~0)
 
@@ -50,6 +51,9 @@ static const char valid_change[16] = {
                1, 0, 0, 0
 };
 
+static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal,
+                        unsigned char old_state, unsigned char new_state);
+
 /**
  * gfs2_setbit - Set a bit in the bitmaps
  * @buffer: the buffer that holds the bitmaps
@@ -204,7 +208,7 @@ void gfs2_rgrp_verify(struct gfs2_rgrpd *rgd)
 {
        struct gfs2_sbd *sdp = rgd->rd_sbd;
        struct gfs2_bitmap *bi = NULL;
-       u32 length = rgd->rd_ri.ri_length;
+       u32 length = rgd->rd_length;
        u32 count[4], tmp;
        int buf, x;
 
@@ -227,7 +231,7 @@ void gfs2_rgrp_verify(struct gfs2_rgrpd *rgd)
                return;
        }
 
-       tmp = rgd->rd_ri.ri_data -
+       tmp = rgd->rd_data -
                rgd->rd_rg.rg_free -
                rgd->rd_rg.rg_dinodes;
        if (count[1] + count[2] != tmp) {
@@ -253,10 +257,10 @@ void gfs2_rgrp_verify(struct gfs2_rgrpd *rgd)
 
 }
 
-static inline int rgrp_contains_block(struct gfs2_rindex_host *ri, u64 block)
+static inline int rgrp_contains_block(struct gfs2_rgrpd *rgd, u64 block)
 {
-       u64 first = ri->ri_data0;
-       u64 last = first + ri->ri_data;
+       u64 first = rgd->rd_data0;
+       u64 last = first + rgd->rd_data;
        return first <= block && block < last;
 }
 
@@ -275,7 +279,7 @@ struct gfs2_rgrpd *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, u64 blk)
        spin_lock(&sdp->sd_rindex_spin);
 
        list_for_each_entry(rgd, &sdp->sd_rindex_mru_list, rd_list_mru) {
-               if (rgrp_contains_block(&rgd->rd_ri, blk)) {
+               if (rgrp_contains_block(rgd, blk)) {
                        list_move(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list);
                        spin_unlock(&sdp->sd_rindex_spin);
                        return rgd;
@@ -354,6 +358,15 @@ void gfs2_clear_rgrpd(struct gfs2_sbd *sdp)
        mutex_unlock(&sdp->sd_rindex_mutex);
 }
 
+static void gfs2_rindex_print(const struct gfs2_rgrpd *rgd)
+{
+       printk(KERN_INFO "  ri_addr = %llu\n", (unsigned long long)rgd->rd_addr);
+       printk(KERN_INFO "  ri_length = %u\n", rgd->rd_length);
+       printk(KERN_INFO "  ri_data0 = %llu\n", (unsigned long long)rgd->rd_data0);
+       printk(KERN_INFO "  ri_data = %u\n", rgd->rd_data);
+       printk(KERN_INFO "  ri_bitbytes = %u\n", rgd->rd_bitbytes);
+}
+
 /**
  * gfs2_compute_bitstructs - Compute the bitmap sizes
  * @rgd: The resource group descriptor
@@ -367,7 +380,7 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd)
 {
        struct gfs2_sbd *sdp = rgd->rd_sbd;
        struct gfs2_bitmap *bi;
-       u32 length = rgd->rd_ri.ri_length; /* # blocks in hdr & bitmap */
+       u32 length = rgd->rd_length; /* # blocks in hdr & bitmap */
        u32 bytes_left, bytes;
        int x;
 
@@ -378,7 +391,7 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd)
        if (!rgd->rd_bits)
                return -ENOMEM;
 
-       bytes_left = rgd->rd_ri.ri_bitbytes;
+       bytes_left = rgd->rd_bitbytes;
 
        for (x = 0; x < length; x++) {
                bi = rgd->rd_bits + x;
@@ -399,14 +412,14 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd)
                } else if (x + 1 == length) {
                        bytes = bytes_left;
                        bi->bi_offset = sizeof(struct gfs2_meta_header);
-                       bi->bi_start = rgd->rd_ri.ri_bitbytes - bytes_left;
+                       bi->bi_start = rgd->rd_bitbytes - bytes_left;
                        bi->bi_len = bytes;
                /* other blocks */
                } else {
                        bytes = sdp->sd_sb.sb_bsize -
                                sizeof(struct gfs2_meta_header);
                        bi->bi_offset = sizeof(struct gfs2_meta_header);
-                       bi->bi_start = rgd->rd_ri.ri_bitbytes - bytes_left;
+                       bi->bi_start = rgd->rd_bitbytes - bytes_left;
                        bi->bi_len = bytes;
                }
 
@@ -418,9 +431,9 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd)
                return -EIO;
        }
        bi = rgd->rd_bits + (length - 1);
-       if ((bi->bi_start + bi->bi_len) * GFS2_NBBY != rgd->rd_ri.ri_data) {
+       if ((bi->bi_start + bi->bi_len) * GFS2_NBBY != rgd->rd_data) {
                if (gfs2_consist_rgrpd(rgd)) {
-                       gfs2_rindex_print(&rgd->rd_ri);
+                       gfs2_rindex_print(rgd);
                        fs_err(sdp, "start=%u len=%u offset=%u\n",
                               bi->bi_start, bi->bi_len, bi->bi_offset);
                }
@@ -431,9 +444,104 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd)
 }
 
 /**
- * gfs2_ri_update - Pull in a new resource index from the disk
+ * gfs2_ri_total - Total up the file system space, according to the rindex.
+ *
+ */
+u64 gfs2_ri_total(struct gfs2_sbd *sdp)
+{
+       u64 total_data = 0;     
+       struct inode *inode = sdp->sd_rindex;
+       struct gfs2_inode *ip = GFS2_I(inode);
+       char buf[sizeof(struct gfs2_rindex)];
+       struct file_ra_state ra_state;
+       int error, rgrps;
+
+       mutex_lock(&sdp->sd_rindex_mutex);
+       file_ra_state_init(&ra_state, inode->i_mapping);
+       for (rgrps = 0;; rgrps++) {
+               loff_t pos = rgrps * sizeof(struct gfs2_rindex);
+
+               if (pos + sizeof(struct gfs2_rindex) >= ip->i_di.di_size)
+                       break;
+               error = gfs2_internal_read(ip, &ra_state, buf, &pos,
+                                          sizeof(struct gfs2_rindex));
+               if (error != sizeof(struct gfs2_rindex))
+                       break;
+               total_data += be32_to_cpu(((struct gfs2_rindex *)buf)->ri_data);
+       }
+       mutex_unlock(&sdp->sd_rindex_mutex);
+       return total_data;
+}
+
+static void gfs2_rindex_in(struct gfs2_rgrpd *rgd, const void *buf)
+{
+       const struct gfs2_rindex *str = buf;
+
+       rgd->rd_addr = be64_to_cpu(str->ri_addr);
+       rgd->rd_length = be32_to_cpu(str->ri_length);
+       rgd->rd_data0 = be64_to_cpu(str->ri_data0);
+       rgd->rd_data = be32_to_cpu(str->ri_data);
+       rgd->rd_bitbytes = be32_to_cpu(str->ri_bitbytes);
+}
+
+/**
+ * read_rindex_entry - Pull in a new resource index entry from the disk
  * @gl: The glock covering the rindex inode
  *
+ * Returns: 0 on success, error code otherwise
+ */
+
+static int read_rindex_entry(struct gfs2_inode *ip,
+                            struct file_ra_state *ra_state)
+{
+       struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
+       loff_t pos = sdp->sd_rgrps * sizeof(struct gfs2_rindex);
+       char buf[sizeof(struct gfs2_rindex)];
+       int error;
+       struct gfs2_rgrpd *rgd;
+
+       error = gfs2_internal_read(ip, ra_state, buf, &pos,
+                                  sizeof(struct gfs2_rindex));
+       if (!error)
+               return 0;
+       if (error != sizeof(struct gfs2_rindex)) {
+               if (error > 0)
+                       error = -EIO;
+               return error;
+       }
+
+       rgd = kzalloc(sizeof(struct gfs2_rgrpd), GFP_NOFS);
+       error = -ENOMEM;
+       if (!rgd)
+               return error;
+
+       mutex_init(&rgd->rd_mutex);
+       lops_init_le(&rgd->rd_le, &gfs2_rg_lops);
+       rgd->rd_sbd = sdp;
+
+       list_add_tail(&rgd->rd_list, &sdp->sd_rindex_list);
+       list_add_tail(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list);
+
+       gfs2_rindex_in(rgd, buf);
+       error = compute_bitstructs(rgd);
+       if (error)
+               return error;
+
+       error = gfs2_glock_get(sdp, rgd->rd_addr,
+                              &gfs2_rgrp_glops, CREATE, &rgd->rd_gl);
+       if (error)
+               return error;
+
+       rgd->rd_gl->gl_object = rgd;
+       rgd->rd_rg_vn = rgd->rd_gl->gl_vn - 1;
+       rgd->rd_flags |= GFS2_RDF_CHECK;
+       return error;
+}
+
+/**
+ * gfs2_ri_update - Pull in a new resource index from the disk
+ * @ip: pointer to the rindex inode
+ *
  * Returns: 0 on successful update, error code otherwise
  */
 
@@ -441,13 +549,11 @@ static int gfs2_ri_update(struct gfs2_inode *ip)
 {
        struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
        struct inode *inode = &ip->i_inode;
-       struct gfs2_rgrpd *rgd;
-       char buf[sizeof(struct gfs2_rindex)];
        struct file_ra_state ra_state;
-       u64 junk = ip->i_di.di_size;
+       u64 rgrp_count = ip->i_di.di_size;
        int error;
 
-       if (do_div(junk, sizeof(struct gfs2_rindex))) {
+       if (do_div(rgrp_count, sizeof(struct gfs2_rindex))) {
                gfs2_consist_inode(ip);
                return -EIO;
        }
@@ -455,50 +561,50 @@ static int gfs2_ri_update(struct gfs2_inode *ip)
        clear_rgrpdi(sdp);
 
        file_ra_state_init(&ra_state, inode->i_mapping);
-       for (sdp->sd_rgrps = 0;; sdp->sd_rgrps++) {
-               loff_t pos = sdp->sd_rgrps * sizeof(struct gfs2_rindex);
-               error = gfs2_internal_read(ip, &ra_state, buf, &pos,
-                                           sizeof(struct gfs2_rindex));
-               if (!error)
-                       break;
-               if (error != sizeof(struct gfs2_rindex)) {
-                       if (error > 0)
-                               error = -EIO;
-                       goto fail;
+       for (sdp->sd_rgrps = 0; sdp->sd_rgrps < rgrp_count; sdp->sd_rgrps++) {
+               error = read_rindex_entry(ip, &ra_state);
+               if (error) {
+                       clear_rgrpdi(sdp);
+                       return error;
                }
+       }
 
-               rgd = kzalloc(sizeof(struct gfs2_rgrpd), GFP_NOFS);
-               error = -ENOMEM;
-               if (!rgd)
-                       goto fail;
-
-               mutex_init(&rgd->rd_mutex);
-               lops_init_le(&rgd->rd_le, &gfs2_rg_lops);
-               rgd->rd_sbd = sdp;
-
-               list_add_tail(&rgd->rd_list, &sdp->sd_rindex_list);
-               list_add_tail(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list);
-
-               gfs2_rindex_in(&rgd->rd_ri, buf);
-               error = compute_bitstructs(rgd);
-               if (error)
-                       goto fail;
+       sdp->sd_rindex_vn = ip->i_gl->gl_vn;
+       return 0;
+}
 
-               error = gfs2_glock_get(sdp, rgd->rd_ri.ri_addr,
-                                      &gfs2_rgrp_glops, CREATE, &rgd->rd_gl);
-               if (error)
-                       goto fail;
+/**
+ * gfs2_ri_update_special - Pull in a new resource index from the disk
+ *
+ * This is a special version that's safe to call from gfs2_inplace_reserve_i.
+ * In this case we know that we don't have any resource groups in memory yet.
+ *
+ * @ip: pointer to the rindex inode
+ *
+ * Returns: 0 on successful update, error code otherwise
+ */
+static int gfs2_ri_update_special(struct gfs2_inode *ip)
+{
+       struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
+       struct inode *inode = &ip->i_inode;
+       struct file_ra_state ra_state;
+       int error;
 
-               rgd->rd_gl->gl_object = rgd;
-               rgd->rd_rg_vn = rgd->rd_gl->gl_vn - 1;
+       file_ra_state_init(&ra_state, inode->i_mapping);
+       for (sdp->sd_rgrps = 0;; sdp->sd_rgrps++) {
+               /* Ignore partials */
+               if ((sdp->sd_rgrps + 1) * sizeof(struct gfs2_rindex) >
+                   ip->i_di.di_size)
+                       break;
+               error = read_rindex_entry(ip, &ra_state);
+               if (error) {
+                       clear_rgrpdi(sdp);
+                       return error;
+               }
        }
 
        sdp->sd_rindex_vn = ip->i_gl->gl_vn;
        return 0;
-
-fail:
-       clear_rgrpdi(sdp);
-       return error;
 }
 
 /**
@@ -543,6 +649,28 @@ int gfs2_rindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ri_gh)
        return error;
 }
 
+static void gfs2_rgrp_in(struct gfs2_rgrp_host *rg, const void *buf)
+{
+       const struct gfs2_rgrp *str = buf;
+
+       rg->rg_flags = be32_to_cpu(str->rg_flags);
+       rg->rg_free = be32_to_cpu(str->rg_free);
+       rg->rg_dinodes = be32_to_cpu(str->rg_dinodes);
+       rg->rg_igeneration = be64_to_cpu(str->rg_igeneration);
+}
+
+static void gfs2_rgrp_out(const struct gfs2_rgrp_host *rg, void *buf)
+{
+       struct gfs2_rgrp *str = buf;
+
+       str->rg_flags = cpu_to_be32(rg->rg_flags);
+       str->rg_free = cpu_to_be32(rg->rg_free);
+       str->rg_dinodes = cpu_to_be32(rg->rg_dinodes);
+       str->__pad = cpu_to_be32(0);
+       str->rg_igeneration = cpu_to_be64(rg->rg_igeneration);
+       memset(&str->rg_reserved, 0, sizeof(str->rg_reserved));
+}
+
 /**
  * gfs2_rgrp_bh_get - Read in a RG's header and bitmaps
  * @rgd: the struct gfs2_rgrpd describing the RG to read in
@@ -557,7 +685,7 @@ int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd)
 {
        struct gfs2_sbd *sdp = rgd->rd_sbd;
        struct gfs2_glock *gl = rgd->rd_gl;
-       unsigned int length = rgd->rd_ri.ri_length;
+       unsigned int length = rgd->rd_length;
        struct gfs2_bitmap *bi;
        unsigned int x, y;
        int error;
@@ -575,7 +703,7 @@ int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd)
 
        for (x = 0; x < length; x++) {
                bi = rgd->rd_bits + x;
-               error = gfs2_meta_read(gl, rgd->rd_ri.ri_addr + x, 0, &bi->bi_bh);
+               error = gfs2_meta_read(gl, rgd->rd_addr + x, 0, &bi->bi_bh);
                if (error)
                        goto fail;
        }
@@ -637,7 +765,7 @@ void gfs2_rgrp_bh_hold(struct gfs2_rgrpd *rgd)
 void gfs2_rgrp_bh_put(struct gfs2_rgrpd *rgd)
 {
        struct gfs2_sbd *sdp = rgd->rd_sbd;
-       int x, length = rgd->rd_ri.ri_length;
+       int x, length = rgd->rd_length;
 
        spin_lock(&sdp->sd_rindex_spin);
        gfs2_assert_warn(rgd->rd_sbd, rgd->rd_bh_count);
@@ -660,7 +788,7 @@ void gfs2_rgrp_bh_put(struct gfs2_rgrpd *rgd)
 void gfs2_rgrp_repolish_clones(struct gfs2_rgrpd *rgd)
 {
        struct gfs2_sbd *sdp = rgd->rd_sbd;
-       unsigned int length = rgd->rd_ri.ri_length;
+       unsigned int length = rgd->rd_length;
        unsigned int x;
 
        for (x = 0; x < length; x++) {
@@ -721,6 +849,38 @@ static int try_rgrp_fit(struct gfs2_rgrpd *rgd, struct gfs2_alloc *al)
        return ret;
 }
 
+/**
+ * try_rgrp_unlink - Look for any unlinked, allocated, but unused inodes
+ * @rgd: The rgrp
+ *
+ * Returns: The inode, if one has been found
+ */
+
+static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked)
+{
+       struct inode *inode;
+       u32 goal = 0;
+       u64 no_addr;
+
+       for(;;) {
+               goal = rgblk_search(rgd, goal, GFS2_BLKST_UNLINKED,
+                                   GFS2_BLKST_UNLINKED);
+               if (goal == 0)
+                       return 0;
+               no_addr = goal + rgd->rd_data0;
+               if (no_addr <= *last_unlinked)
+                       continue;
+               *last_unlinked = no_addr;
+               inode = gfs2_inode_lookup(rgd->rd_sbd->sd_vfs, DT_UNKNOWN,
+                                       no_addr, -1);
+               if (!IS_ERR(inode))
+                       return inode;
+       }
+
+       rgd->rd_flags &= ~GFS2_RDF_CHECK;
+       return NULL;
+}
+
 /**
  * recent_rgrp_first - get first RG from "recent" list
  * @sdp: The GFS2 superblock
@@ -743,7 +903,7 @@ static struct gfs2_rgrpd *recent_rgrp_first(struct gfs2_sbd *sdp,
                goto first;
 
        list_for_each_entry(rgd, &sdp->sd_rindex_recent_list, rd_recent) {
-               if (rgd->rd_ri.ri_addr == rglast)
+               if (rgd->rd_addr == rglast)
                        goto out;
        }
 
@@ -882,8 +1042,9 @@ static void forward_rgrp_set(struct gfs2_sbd *sdp, struct gfs2_rgrpd *rgd)
  * Returns: errno
  */
 
-static int get_local_rgrp(struct gfs2_inode *ip)
+static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
 {
+       struct inode *inode = NULL;
        struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
        struct gfs2_rgrpd *rgd, *begin = NULL;
        struct gfs2_alloc *al = &ip->i_alloc;
@@ -903,7 +1064,11 @@ static int get_local_rgrp(struct gfs2_inode *ip)
                case 0:
                        if (try_rgrp_fit(rgd, al))
                                goto out;
+                       if (rgd->rd_flags & GFS2_RDF_CHECK)
+                               inode = try_rgrp_unlink(rgd, last_unlinked);
                        gfs2_glock_dq_uninit(&al->al_rgd_gh);
+                       if (inode)
+                               return inode;
                        rgd = recent_rgrp_next(rgd, 1);
                        break;
 
@@ -912,7 +1077,7 @@ static int get_local_rgrp(struct gfs2_inode *ip)
                        break;
 
                default:
-                       return error;
+                       return ERR_PTR(error);
                }
        }
 
@@ -927,7 +1092,11 @@ static int get_local_rgrp(struct gfs2_inode *ip)
                case 0:
                        if (try_rgrp_fit(rgd, al))
                                goto out;
+                       if (rgd->rd_flags & GFS2_RDF_CHECK)
+                               inode = try_rgrp_unlink(rgd, last_unlinked);
                        gfs2_glock_dq_uninit(&al->al_rgd_gh);
+                       if (inode)
+                               return inode;
                        break;
 
                case GLR_TRYFAILED:
@@ -935,7 +1104,7 @@ static int get_local_rgrp(struct gfs2_inode *ip)
                        break;
 
                default:
-                       return error;
+                       return ERR_PTR(error);
                }
 
                rgd = gfs2_rgrpd_get_next(rgd);
@@ -944,7 +1113,7 @@ static int get_local_rgrp(struct gfs2_inode *ip)
 
                if (rgd == begin) {
                        if (++loops >= 3)
-                               return -ENOSPC;
+                               return ERR_PTR(-ENOSPC);
                        if (!skipped)
                                loops++;
                        flags = 0;
@@ -954,7 +1123,7 @@ static int get_local_rgrp(struct gfs2_inode *ip)
        }
 
 out:
-       ip->i_last_rg_alloc = rgd->rd_ri.ri_addr;
+       ip->i_last_rg_alloc = rgd->rd_addr;
 
        if (begin) {
                recent_rgrp_add(rgd);
@@ -964,7 +1133,7 @@ out:
                forward_rgrp_set(sdp, rgd);
        }
 
-       return 0;
+       return NULL;
 }
 
 /**
@@ -978,19 +1147,33 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line)
 {
        struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
        struct gfs2_alloc *al = &ip->i_alloc;
-       int error;
+       struct inode *inode;
+       int error = 0;
+       u64 last_unlinked = 0;
 
        if (gfs2_assert_warn(sdp, al->al_requested))
                return -EINVAL;
 
-       error = gfs2_rindex_hold(sdp, &al->al_ri_gh);
+try_again:
+       /* We need to hold the rindex unless the inode we're using is
+          the rindex itself, in which case it's already held. */
+       if (ip != GFS2_I(sdp->sd_rindex))
+               error = gfs2_rindex_hold(sdp, &al->al_ri_gh);
+       else if (!sdp->sd_rgrps) /* We may not have the rindex read in, so: */
+               error = gfs2_ri_update_special(ip);
+
        if (error)
                return error;
 
-       error = get_local_rgrp(ip);
-       if (error) {
-               gfs2_glock_dq_uninit(&al->al_ri_gh);
-               return error;
+       inode = get_local_rgrp(ip, &last_unlinked);
+       if (inode) {
+               if (ip != GFS2_I(sdp->sd_rindex))
+                       gfs2_glock_dq_uninit(&al->al_ri_gh);
+               if (IS_ERR(inode))
+                       return PTR_ERR(inode);
+               iput(inode);
+               gfs2_log_flush(sdp, NULL);
+               goto try_again;
        }
 
        al->al_file = file;
@@ -1019,7 +1202,8 @@ void gfs2_inplace_release(struct gfs2_inode *ip)
 
        al->al_rgd = NULL;
        gfs2_glock_dq_uninit(&al->al_rgd_gh);
-       gfs2_glock_dq_uninit(&al->al_ri_gh);
+       if (ip != GFS2_I(sdp->sd_rindex))
+               gfs2_glock_dq_uninit(&al->al_ri_gh);
 }
 
 /**
@@ -1037,8 +1221,8 @@ unsigned char gfs2_get_block_type(struct gfs2_rgrpd *rgd, u64 block)
        unsigned int buf;
        unsigned char type;
 
-       length = rgd->rd_ri.ri_length;
-       rgrp_block = block - rgd->rd_ri.ri_data0;
+       length = rgd->rd_length;
+       rgrp_block = block - rgd->rd_data0;
 
        for (buf = 0; buf < length; buf++) {
                bi = rgd->rd_bits + buf;
@@ -1077,10 +1261,10 @@ unsigned char gfs2_get_block_type(struct gfs2_rgrpd *rgd, u64 block)
  */
 
 static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal,
-                            unsigned char old_state, unsigned char new_state)
+                       unsigned char old_state, unsigned char new_state)
 {
        struct gfs2_bitmap *bi = NULL;
-       u32 length = rgd->rd_ri.ri_length;
+       u32 length = rgd->rd_length;
        u32 blk = 0;
        unsigned int buf, x;
 
@@ -1118,17 +1302,18 @@ static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal,
                goal = 0;
        }
 
-       if (gfs2_assert_withdraw(rgd->rd_sbd, x <= length))
-               blk = 0;
+       if (old_state != new_state) {
+               gfs2_assert_withdraw(rgd->rd_sbd, blk != BFITNOENT);
 
-       gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1);
-       gfs2_setbit(rgd, bi->bi_bh->b_data + bi->bi_offset,
-                   bi->bi_len, blk, new_state);
-       if (bi->bi_clone)
-               gfs2_setbit(rgd, bi->bi_clone + bi->bi_offset,
+               gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1);
+               gfs2_setbit(rgd, bi->bi_bh->b_data + bi->bi_offset,
                            bi->bi_len, blk, new_state);
+               if (bi->bi_clone)
+                       gfs2_setbit(rgd, bi->bi_clone + bi->bi_offset,
+                                   bi->bi_len, blk, new_state);
+       }
 
-       return bi->bi_start * GFS2_NBBY + blk;
+       return (blk == BFITNOENT) ? 0 : (bi->bi_start * GFS2_NBBY) + blk;
 }
 
 /**
@@ -1156,9 +1341,9 @@ static struct gfs2_rgrpd *rgblk_free(struct gfs2_sbd *sdp, u64 bstart,
                return NULL;
        }
 
-       length = rgd->rd_ri.ri_length;
+       length = rgd->rd_length;
 
-       rgrp_blk = bstart - rgd->rd_ri.ri_data0;
+       rgrp_blk = bstart - rgd->rd_data0;
 
        while (blen--) {
                for (buf = 0; buf < length; buf++) {
@@ -1202,15 +1387,15 @@ u64 gfs2_alloc_data(struct gfs2_inode *ip)
        u32 goal, blk;
        u64 block;
 
-       if (rgrp_contains_block(&rgd->rd_ri, ip->i_di.di_goal_data))
-               goal = ip->i_di.di_goal_data - rgd->rd_ri.ri_data0;
+       if (rgrp_contains_block(rgd, ip->i_di.di_goal_data))
+               goal = ip->i_di.di_goal_data - rgd->rd_data0;
        else
                goal = rgd->rd_last_alloc_data;
 
        blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED);
        rgd->rd_last_alloc_data = blk;
 
-       block = rgd->rd_ri.ri_data0 + blk;
+       block = rgd->rd_data0 + blk;
        ip->i_di.di_goal_data = block;
 
        gfs2_assert_withdraw(sdp, rgd->rd_rg.rg_free);
@@ -1246,15 +1431,15 @@ u64 gfs2_alloc_meta(struct gfs2_inode *ip)
        u32 goal, blk;
        u64 block;
 
-       if (rgrp_contains_block(&rgd->rd_ri, ip->i_di.di_goal_meta))
-               goal = ip->i_di.di_goal_meta - rgd->rd_ri.ri_data0;
+       if (rgrp_contains_block(rgd, ip->i_di.di_goal_meta))
+               goal = ip->i_di.di_goal_meta - rgd->rd_data0;
        else
                goal = rgd->rd_last_alloc_meta;
 
        blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED);
        rgd->rd_last_alloc_meta = blk;
 
-       block = rgd->rd_ri.ri_data0 + blk;
+       block = rgd->rd_data0 + blk;
        ip->i_di.di_goal_meta = block;
 
        gfs2_assert_withdraw(sdp, rgd->rd_rg.rg_free);
@@ -1296,7 +1481,7 @@ u64 gfs2_alloc_di(struct gfs2_inode *dip, u64 *generation)
 
        rgd->rd_last_alloc_meta = blk;
 
-       block = rgd->rd_ri.ri_data0 + blk;
+       block = rgd->rd_data0 + blk;
 
        gfs2_assert_withdraw(sdp, rgd->rd_rg.rg_free);
        rgd->rd_rg.rg_free--;
@@ -1379,7 +1564,7 @@ void gfs2_unlink_di(struct inode *inode)
        struct gfs2_inode *ip = GFS2_I(inode);
        struct gfs2_sbd *sdp = GFS2_SB(inode);
        struct gfs2_rgrpd *rgd;
-       u64 blkno = ip->i_num.no_addr;
+       u64 blkno = ip->i_no_addr;
 
        rgd = rgblk_free(sdp, blkno, 1, GFS2_BLKST_UNLINKED);
        if (!rgd)
@@ -1414,9 +1599,9 @@ static void gfs2_free_uninit_di(struct gfs2_rgrpd *rgd, u64 blkno)
 
 void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip)
 {
-       gfs2_free_uninit_di(rgd, ip->i_num.no_addr);
+       gfs2_free_uninit_di(rgd, ip->i_no_addr);
        gfs2_quota_change(ip, -1, ip->i_inode.i_uid, ip->i_inode.i_gid);
-       gfs2_meta_wipe(ip, ip->i_num.no_addr, 1);
+       gfs2_meta_wipe(ip, ip->i_no_addr, 1);
 }
 
 /**
index b01e0cfc99b5fc8d38a3b04d059b66fa2c7c4542..b4c6adfc6f2ebe447697c9bdadf8f7837ea7170e 100644 (file)
@@ -65,5 +65,6 @@ void gfs2_rlist_add(struct gfs2_sbd *sdp, struct gfs2_rgrp_list *rlist,
 void gfs2_rlist_alloc(struct gfs2_rgrp_list *rlist, unsigned int state,
                      int flags);
 void gfs2_rlist_free(struct gfs2_rgrp_list *rlist);
+u64 gfs2_ri_total(struct gfs2_sbd *sdp);
 
 #endif /* __RGRP_DOT_H__ */
index 4fdda974dc837e03d930091ba10fdef0adbe7c63..f916b9740c75b454b28aba4aa6157d10d8f8af14 100644 (file)
@@ -95,8 +95,8 @@ int gfs2_check_sb(struct gfs2_sbd *sdp, struct gfs2_sb_host *sb, int silent)
 {
        unsigned int x;
 
-       if (sb->sb_header.mh_magic != GFS2_MAGIC ||
-           sb->sb_header.mh_type != GFS2_METATYPE_SB) {
+       if (sb->sb_magic != GFS2_MAGIC ||
+           sb->sb_type != GFS2_METATYPE_SB) {
                if (!silent)
                        printk(KERN_WARNING "GFS2: not a GFS2 filesystem\n");
                return -EINVAL;
@@ -174,10 +174,31 @@ static int end_bio_io_page(struct bio *bio, unsigned int bytes_done, int error)
        return 0;
 }
 
+static void gfs2_sb_in(struct gfs2_sb_host *sb, const void *buf)
+{
+       const struct gfs2_sb *str = buf;
+
+       sb->sb_magic = be32_to_cpu(str->sb_header.mh_magic);
+       sb->sb_type = be32_to_cpu(str->sb_header.mh_type);
+       sb->sb_format = be32_to_cpu(str->sb_header.mh_format);
+       sb->sb_fs_format = be32_to_cpu(str->sb_fs_format);
+       sb->sb_multihost_format = be32_to_cpu(str->sb_multihost_format);
+       sb->sb_bsize = be32_to_cpu(str->sb_bsize);
+       sb->sb_bsize_shift = be32_to_cpu(str->sb_bsize_shift);
+       sb->sb_master_dir.no_addr = be64_to_cpu(str->sb_master_dir.no_addr);
+       sb->sb_master_dir.no_formal_ino = be64_to_cpu(str->sb_master_dir.no_formal_ino);
+       sb->sb_root_dir.no_addr = be64_to_cpu(str->sb_root_dir.no_addr);
+       sb->sb_root_dir.no_formal_ino = be64_to_cpu(str->sb_root_dir.no_formal_ino);
+
+       memcpy(sb->sb_lockproto, str->sb_lockproto, GFS2_LOCKNAME_LEN);
+       memcpy(sb->sb_locktable, str->sb_locktable, GFS2_LOCKNAME_LEN);
+}
+
 /**
  * gfs2_read_super - Read the gfs2 super block from disk
- * @sb: The VFS super block
+ * @sdp: The GFS2 super block
  * @sector: The location of the super block
+ * @error: The error code to return
  *
  * This uses the bio functions to read the super block from disk
  * because we want to be 100% sure that we never read cached data.
@@ -189,17 +210,19 @@ static int end_bio_io_page(struct bio *bio, unsigned int bytes_done, int error)
  * the master directory (contains pointers to journals etc) and the
  * root directory.
  *
- * Returns: A page containing the sb or NULL
+ * Returns: 0 on success or error
  */
 
-struct page *gfs2_read_super(struct super_block *sb, sector_t sector)
+int gfs2_read_super(struct gfs2_sbd *sdp, sector_t sector)
 {
+       struct super_block *sb = sdp->sd_vfs;
+       struct gfs2_sb *p;
        struct page *page;
        struct bio *bio;
 
        page = alloc_page(GFP_KERNEL);
        if (unlikely(!page))
-               return NULL;
+               return -ENOBUFS;
 
        ClearPageUptodate(page);
        ClearPageDirty(page);
@@ -208,7 +231,7 @@ struct page *gfs2_read_super(struct super_block *sb, sector_t sector)
        bio = bio_alloc(GFP_KERNEL, 1);
        if (unlikely(!bio)) {
                __free_page(page);
-               return NULL;
+               return -ENOBUFS;
        }
 
        bio->bi_sector = sector * (sb->s_blocksize >> 9);
@@ -222,9 +245,13 @@ struct page *gfs2_read_super(struct super_block *sb, sector_t sector)
        bio_put(bio);
        if (!PageUptodate(page)) {
                __free_page(page);
-               return NULL;
+               return -EIO;
        }
-       return page;
+       p = kmap(page);
+       gfs2_sb_in(&sdp->sd_sb, p);
+       kunmap(page);
+       __free_page(page);
+       return 0;
 }
 
 /**
@@ -241,19 +268,13 @@ int gfs2_read_sb(struct gfs2_sbd *sdp, struct gfs2_glock *gl, int silent)
        u32 tmp_blocks;
        unsigned int x;
        int error;
-       struct page *page;
-       char *sb;
 
-       page = gfs2_read_super(sdp->sd_vfs, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift);
-       if (!page) {
+       error = gfs2_read_super(sdp, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift);
+       if (error) {
                if (!silent)
                        fs_err(sdp, "can't read superblock\n");
-               return -EIO;
+               return error;
        }
-       sb = kmap(page);
-       gfs2_sb_in(&sdp->sd_sb, sb);
-       kunmap(page);
-       __free_page(page);
 
        error = gfs2_check_sb(sdp, &sdp->sd_sb, silent);
        if (error)
@@ -360,7 +381,7 @@ int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh)
                name.len = sprintf(buf, "journal%u", sdp->sd_journals);
                name.hash = gfs2_disk_hash(name.name, name.len);
 
-               error = gfs2_dir_search(sdp->sd_jindex, &name, NULL, NULL);
+               error = gfs2_dir_check(sdp->sd_jindex, &name, NULL);
                if (error == -ENOENT) {
                        error = 0;
                        break;
@@ -593,6 +614,24 @@ int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
        return error;
 }
 
+static void gfs2_statfs_change_in(struct gfs2_statfs_change_host *sc, const void *buf)
+{
+       const struct gfs2_statfs_change *str = buf;
+
+       sc->sc_total = be64_to_cpu(str->sc_total);
+       sc->sc_free = be64_to_cpu(str->sc_free);
+       sc->sc_dinodes = be64_to_cpu(str->sc_dinodes);
+}
+
+static void gfs2_statfs_change_out(const struct gfs2_statfs_change_host *sc, void *buf)
+{
+       struct gfs2_statfs_change *str = buf;
+
+       str->sc_total = cpu_to_be64(sc->sc_total);
+       str->sc_free = cpu_to_be64(sc->sc_free);
+       str->sc_dinodes = cpu_to_be64(sc->sc_dinodes);
+}
+
 int gfs2_statfs_init(struct gfs2_sbd *sdp)
 {
        struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
@@ -772,7 +811,7 @@ static int statfs_slow_fill(struct gfs2_rgrpd *rgd,
                            struct gfs2_statfs_change_host *sc)
 {
        gfs2_rgrp_verify(rgd);
-       sc->sc_total += rgd->rd_ri.ri_data;
+       sc->sc_total += rgd->rd_data;
        sc->sc_free += rgd->rd_rg.rg_free;
        sc->sc_dinodes += rgd->rd_rg.rg_dinodes;
        return 0;
index e590b2df11dc1c88343743132a64ece6ae83ddd9..60a870e430be921da125b2aee7a412d66231dc9f 100644 (file)
@@ -16,7 +16,7 @@ void gfs2_tune_init(struct gfs2_tune *gt);
 
 int gfs2_check_sb(struct gfs2_sbd *sdp, struct gfs2_sb_host *sb, int silent);
 int gfs2_read_sb(struct gfs2_sbd *sdp, struct gfs2_glock *gl, int silent);
-struct page *gfs2_read_super(struct super_block *sb, sector_t sector);
+int gfs2_read_super(struct gfs2_sbd *sdp, sector_t sector);
 
 static inline unsigned int gfs2_jindex_size(struct gfs2_sbd *sdp)
 {
index 601eaa1b9ed63f9c50dc72b104af2985cf01a276..424a0774eda81268b1daf3eff28ae82a636c6ad8 100644 (file)
@@ -115,8 +115,8 @@ int gfs2_consist_inode_i(struct gfs2_inode *ip, int cluster_wide,
                "GFS2: fsid=%s:   inode = %llu %llu\n"
                "GFS2: fsid=%s:   function = %s, file = %s, line = %u\n",
                sdp->sd_fsname,
-               sdp->sd_fsname, (unsigned long long)ip->i_num.no_formal_ino,
-               (unsigned long long)ip->i_num.no_addr,
+               sdp->sd_fsname, (unsigned long long)ip->i_no_formal_ino,
+               (unsigned long long)ip->i_no_addr,
                sdp->sd_fsname, function, file, line);
        return rv;
 }
@@ -137,7 +137,7 @@ int gfs2_consist_rgrpd_i(struct gfs2_rgrpd *rgd, int cluster_wide,
                "GFS2: fsid=%s:   RG = %llu\n"
                "GFS2: fsid=%s:   function = %s, file = %s, line = %u\n",
                sdp->sd_fsname,
-               sdp->sd_fsname, (unsigned long long)rgd->rd_ri.ri_addr,
+               sdp->sd_fsname, (unsigned long long)rgd->rd_addr,
                sdp->sd_fsname, function, file, line);
        return rv;
 }
index 9a934db0bd8ae927509a9c168ff1ee07cc167562..bc835f272a6e0a9e017aac7517e672a4ea0db5bb 100644 (file)
@@ -607,7 +607,7 @@ static const struct file_operations hfs_file_operations = {
        .write          = do_sync_write,
        .aio_write      = generic_file_aio_write,
        .mmap           = generic_file_mmap,
-       .sendfile       = generic_file_sendfile,
+       .splice_read    = generic_file_splice_read,
        .fsync          = file_fsync,
        .open           = hfs_file_open,
        .release        = hfs_file_release,
index 45dab5d6cc10a25f7e37a80d847566f6c4001a66..409ce5429c91ccb8b53d5a9fff6ef0118546722d 100644 (file)
@@ -288,7 +288,7 @@ static const struct file_operations hfsplus_file_operations = {
        .write          = do_sync_write,
        .aio_write      = generic_file_aio_write,
        .mmap           = generic_file_mmap,
-       .sendfile       = generic_file_sendfile,
+       .splice_read    = generic_file_splice_read,
        .fsync          = file_fsync,
        .open           = hfsplus_file_open,
        .release        = hfsplus_file_release,
index 8286491dbf31dbccca606b241ae755d5cd77cee8..c77862032e844262a199549d01ca16489b0578f8 100644 (file)
@@ -390,7 +390,7 @@ int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync)
 static const struct file_operations hostfs_file_fops = {
        .llseek         = generic_file_llseek,
        .read           = do_sync_read,
-       .sendfile       = generic_file_sendfile,
+       .splice_read    = generic_file_splice_read,
        .aio_read       = generic_file_aio_read,
        .aio_write      = generic_file_aio_write,
        .write          = do_sync_write,
index b4eafc0f1e54b40007b9831a6661012cfaa0ebe0..5b53e5c5d8dfb4cbdd4808efa6fa945a4ec4a51f 100644 (file)
@@ -129,7 +129,7 @@ const struct file_operations hpfs_file_ops =
        .mmap           = generic_file_mmap,
        .release        = hpfs_file_release,
        .fsync          = hpfs_file_fsync,
-       .sendfile       = generic_file_sendfile,
+       .splice_read    = generic_file_splice_read,
 };
 
 const struct inode_operations hpfs_file_iops =
index 99871279a1edf167aa6abd63c9c1d948a56bb4e3..c2530197be0c8d6db52a3fcf2ada23ca33196a02 100644 (file)
@@ -47,7 +47,7 @@ const struct file_operations jffs2_file_operations =
        .ioctl =        jffs2_ioctl,
        .mmap =         generic_file_readonly_mmap,
        .fsync =        jffs2_fsync,
-       .sendfile =     generic_file_sendfile
+       .splice_read =  generic_file_splice_read,
 };
 
 /* jffs2_file_inode_operations */
index 79494c4f2b10c2601c20044085d10815661d34a9..fa92f7f1d0d0d709d0edeb910dd95bf3bcd8bcee 100644 (file)
@@ -29,7 +29,7 @@
        __u32 __x = (x); \
        ((__u32)( \
                ((__x & (__u32)0x000000ffUL) << 16) | \
-                (__x & (__u32)0x0000ff00UL)        | \
+                (__x & (__u32)0x0000ff00UL)        | \
                ((__x & (__u32)0x00ff0000UL) >> 16) )); \
 })
 
index f7f8eff19b7b2c4358fc58053b827fb5becd8d37..87eb93694af75832c792f1863c3edbe13d6c5c56 100644 (file)
@@ -108,7 +108,6 @@ const struct file_operations jfs_file_operations = {
        .aio_read       = generic_file_aio_read,
        .aio_write      = generic_file_aio_write,
        .mmap           = generic_file_mmap,
-       .sendfile       = generic_file_sendfile,
        .splice_read    = generic_file_splice_read,
        .splice_write   = generic_file_splice_write,
        .fsync          = jfs_fsync,
index 9c5d59632aac98730aea6df4f5a50cac665e7a2c..887f5759e53643bdba5086363d587d82a789c5d3 100644 (file)
 #include "jfs_filsys.h"
 #include "jfs_debug.h"
 
-#ifdef CONFIG_JFS_DEBUG
-void dump_mem(char *label, void *data, int length)
-{
-       int i, j;
-       int *intptr = data;
-       char *charptr = data;
-       char buf[10], line[80];
-
-       printk("%s: dump of %d bytes of data at 0x%p\n\n", label, length,
-              data);
-       for (i = 0; i < length; i += 16) {
-               line[0] = 0;
-               for (j = 0; (j < 4) && (i + j * 4 < length); j++) {
-                       sprintf(buf, " %08x", intptr[i / 4 + j]);
-                       strcat(line, buf);
-               }
-               buf[0] = ' ';
-               buf[2] = 0;
-               for (j = 0; (j < 16) && (i + j < length); j++) {
-                       buf[1] =
-                           isprint(charptr[i + j]) ? charptr[i + j] : '.';
-                       strcat(line, buf);
-               }
-               printk("%s\n", line);
-       }
-}
-#endif
-
 #ifdef PROC_FS_JFS /* see jfs_debug.h */
 
 static struct proc_dir_entry *base;
index 7378798f0b2151c1a0df6e9146ac9cf6b08995b1..044c1e654cc00e4f1790bd16e67ecc053944a213 100644 (file)
@@ -62,7 +62,6 @@ extern void jfs_proc_clean(void);
 
 extern int jfsloglevel;
 
-extern void dump_mem(char *label, void *data, int length);
 extern int jfs_txanchor_read(char *, char **, off_t, int, int *, void *);
 
 /* information message: e.g., configuration, major event */
@@ -94,7 +93,6 @@ extern int jfs_txanchor_read(char *, char **, off_t, int, int *, void *);
  *     ---------
  */
 #else                          /* CONFIG_JFS_DEBUG */
-#define dump_mem(label,data,length) do {} while (0)
 #define ASSERT(p) do {} while (0)
 #define jfs_info(fmt, arg...) do {} while (0)
 #define jfs_debug(fmt, arg...) do {} while (0)
index 40b20111383c5f2c07419ab41cb5103fbed57a41..c387540d34255334431ef4f02a995ae7399cb273 100644 (file)
 #define _H_JFS_DINODE
 
 /*
- *      jfs_dinode.h: on-disk inode manager
+ *     jfs_dinode.h: on-disk inode manager
  */
 
-#define INODESLOTSIZE           128
-#define L2INODESLOTSIZE         7
-#define log2INODESIZE           9      /* log2(bytes per dinode) */
+#define INODESLOTSIZE          128
+#define L2INODESLOTSIZE                7
+#define log2INODESIZE                /* log2(bytes per dinode) */
 
 
 /*
- *      on-disk inode : 512 bytes
+ *     on-disk inode : 512 bytes
  *
  * note: align 64-bit fields on 8-byte boundary.
  */
 struct dinode {
        /*
-        *      I. base area (128 bytes)
-        *      ------------------------
+        *      I. base area (128 bytes)
+        *      ------------------------
         *
         * define generic/POSIX attributes
         */
@@ -70,16 +70,16 @@ struct dinode {
        __le32 di_acltype;      /* 4: Type of ACL */
 
        /*
-        *      Extension Areas.
+        *      Extension Areas.
         *
-        *      Historically, the inode was partitioned into 4 128-byte areas,
-        *      the last 3 being defined as unions which could have multiple
-        *      uses.  The first 96 bytes had been completely unused until
-        *      an index table was added to the directory.  It is now more
-        *      useful to describe the last 3/4 of the inode as a single
-        *      union.  We would probably be better off redesigning the
-        *      entire structure from scratch, but we don't want to break
-        *      commonality with OS/2's JFS at this time.
+        *      Historically, the inode was partitioned into 4 128-byte areas,
+        *      the last 3 being defined as unions which could have multiple
+        *      uses.  The first 96 bytes had been completely unused until
+        *      an index table was added to the directory.  It is now more
+        *      useful to describe the last 3/4 of the inode as a single
+        *      union.  We would probably be better off redesigning the
+        *      entire structure from scratch, but we don't want to break
+        *      commonality with OS/2's JFS at this time.
         */
        union {
                struct {
@@ -95,7 +95,7 @@ struct dinode {
                } _dir;                                 /* (384) */
 #define di_dirtable    u._dir._table
 #define di_dtroot      u._dir._dtroot
-#define di_parent       di_dtroot.header.idotdot
+#define di_parent      di_dtroot.header.idotdot
 #define di_DASD                di_dtroot.header.DASD
 
                struct {
@@ -127,14 +127,14 @@ struct dinode {
 #define di_inlinedata  u._file._u2._special._u
 #define di_rdev                u._file._u2._special._u._rdev
 #define di_fastsymlink u._file._u2._special._u._fastsymlink
-#define di_inlineea     u._file._u2._special._inlineea
+#define di_inlineea    u._file._u2._special._inlineea
        } u;
 };
 
 /* extended mode bits (on-disk inode di_mode) */
-#define IFJOURNAL       0x00010000     /* journalled file */
-#define ISPARSE         0x00020000     /* sparse file enabled */
-#define INLINEEA        0x00040000     /* inline EA area free */
+#define IFJOURNAL      0x00010000      /* journalled file */
+#define ISPARSE                0x00020000      /* sparse file enabled */
+#define INLINEEA       0x00040000      /* inline EA area free */
 #define ISWAPFILE      0x00800000      /* file open for pager swap space */
 
 /* more extended mode bits: attributes for OS/2 */
index f3b1ebb2228036ba4fbdb2a483f0b958323ca16a..e1985066b1c63273cf5bf568ea6f9a417abb0a7a 100644 (file)
@@ -154,12 +154,12 @@ static const s8 budtab[256] = {
  *             the in-core descriptor is initialized from disk.
  *
  * PARAMETERS:
- *      ipbmap -  pointer to in-core inode for the block map.
+ *     ipbmap  - pointer to in-core inode for the block map.
  *
  * RETURN VALUES:
- *      0      - success
- *      -ENOMEM        - insufficient memory
- *      -EIO   - i/o error
+ *           - success
+ *     -ENOMEM - insufficient memory
+ *     -EIO    - i/o error
  */
 int dbMount(struct inode *ipbmap)
 {
@@ -232,11 +232,11 @@ int dbMount(struct inode *ipbmap)
  *             the memory for this descriptor is freed.
  *
  * PARAMETERS:
- *      ipbmap -  pointer to in-core inode for the block map.
+ *     ipbmap  - pointer to in-core inode for the block map.
  *
  * RETURN VALUES:
- *      0      - success
- *      -EIO   - i/o error
+ *           - success
+ *     -EIO    - i/o error
  */
 int dbUnmount(struct inode *ipbmap, int mounterror)
 {
@@ -320,13 +320,13 @@ int dbSync(struct inode *ipbmap)
  *             at a time.
  *
  * PARAMETERS:
- *      ip     -  pointer to in-core inode;
- *      blkno  -  starting block number to be freed.
- *      nblocks        -  number of blocks to be freed.
+ *     ip      - pointer to in-core inode;
+ *     blkno   - starting block number to be freed.
+ *     nblocks - number of blocks to be freed.
  *
  * RETURN VALUES:
- *      0      - success
- *      -EIO   - i/o error
+ *           - success
+ *     -EIO    - i/o error
  */
 int dbFree(struct inode *ip, s64 blkno, s64 nblocks)
 {
@@ -395,23 +395,23 @@ int dbFree(struct inode *ip, s64 blkno, s64 nblocks)
 /*
  * NAME:       dbUpdatePMap()
  *
- * FUNCTION:    update the allocation state (free or allocate) of the
+ * FUNCTION:   update the allocation state (free or allocate) of the
  *             specified block range in the persistent block allocation map.
  *
  *             the blocks will be updated in the persistent map one
  *             dmap at a time.
  *
  * PARAMETERS:
- *      ipbmap -  pointer to in-core inode for the block map.
- *      free   -  'true' if block range is to be freed from the persistent
- *                map; 'false' if it is to   be allocated.
- *      blkno  -  starting block number of the range.
- *      nblocks        -  number of contiguous blocks in the range.
- *      tblk   -  transaction block;
+ *     ipbmap  - pointer to in-core inode for the block map.
+ *     free    - 'true' if block range is to be freed from the persistent
+ *               map; 'false' if it is to be allocated.
+ *     blkno   - starting block number of the range.
+ *     nblocks - number of contiguous blocks in the range.
+ *     tblk    - transaction block;
  *
  * RETURN VALUES:
- *      0      - success
- *      -EIO   - i/o error
+ *           - success
+ *     -EIO    - i/o error
  */
 int
 dbUpdatePMap(struct inode *ipbmap,
@@ -573,7 +573,7 @@ dbUpdatePMap(struct inode *ipbmap,
 /*
  * NAME:       dbNextAG()
  *
- * FUNCTION:    find the preferred allocation group for new allocations.
+ * FUNCTION:   find the preferred allocation group for new allocations.
  *
  *             Within the allocation groups, we maintain a preferred
  *             allocation group which consists of a group with at least
@@ -589,10 +589,10 @@ dbUpdatePMap(struct inode *ipbmap,
  *             empty ags around for large allocations.
  *
  * PARAMETERS:
- *      ipbmap -  pointer to in-core inode for the block map.
+ *     ipbmap  - pointer to in-core inode for the block map.
  *
  * RETURN VALUES:
- *      the preferred allocation group number.
+ *     the preferred allocation group number.
  */
 int dbNextAG(struct inode *ipbmap)
 {
@@ -656,7 +656,7 @@ unlock:
 /*
  * NAME:       dbAlloc()
  *
- * FUNCTION:    attempt to allocate a specified number of contiguous free
+ * FUNCTION:   attempt to allocate a specified number of contiguous free
  *             blocks from the working allocation block map.
  *
  *             the block allocation policy uses hints and a multi-step
@@ -680,16 +680,16 @@ unlock:
  *             size or requests that specify no hint value.
  *
  * PARAMETERS:
- *      ip     -  pointer to in-core inode;
- *      hint   - allocation hint.
- *      nblocks        - number of contiguous blocks in the range.
- *      results        - on successful return, set to the starting block number
+ *     ip      - pointer to in-core inode;
+ *     hint    - allocation hint.
+ *     nblocks - number of contiguous blocks in the range.
+ *     results - on successful return, set to the starting block number
  *               of the newly allocated contiguous range.
  *
  * RETURN VALUES:
- *      0      - success
- *      -ENOSPC        - insufficient disk resources
- *      -EIO   - i/o error
+ *           - success
+ *     -ENOSPC - insufficient disk resources
+ *     -EIO    - i/o error
  */
 int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results)
 {
@@ -706,12 +706,6 @@ int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results)
        /* assert that nblocks is valid */
        assert(nblocks > 0);
 
-#ifdef _STILL_TO_PORT
-       /* DASD limit check                                     F226941 */
-       if (OVER_LIMIT(ip, nblocks))
-               return -ENOSPC;
-#endif                         /* _STILL_TO_PORT */
-
        /* get the log2 number of blocks to be allocated.
         * if the number of blocks is not a log2 multiple,
         * it will be rounded up to the next log2 multiple.
@@ -720,7 +714,6 @@ int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results)
 
        bmp = JFS_SBI(ip->i_sb)->bmap;
 
-//retry:        /* serialize w.r.t.extendfs() */
        mapSize = bmp->db_mapsize;
 
        /* the hint should be within the map */
@@ -879,17 +872,17 @@ int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results)
 /*
  * NAME:       dbAllocExact()
  *
- * FUNCTION:    try to allocate the requested extent;
+ * FUNCTION:   try to allocate the requested extent;
  *
  * PARAMETERS:
- *      ip     - pointer to in-core inode;
- *      blkno  - extent address;
- *      nblocks        - extent length;
+ *     ip      - pointer to in-core inode;
+ *     blkno   - extent address;
+ *     nblocks - extent length;
  *
  * RETURN VALUES:
- *      0      - success
- *      -ENOSPC        - insufficient disk resources
- *      -EIO   - i/o error
+ *           - success
+ *     -ENOSPC - insufficient disk resources
+ *     -EIO    - i/o error
  */
 int dbAllocExact(struct inode *ip, s64 blkno, int nblocks)
 {
@@ -946,7 +939,7 @@ int dbAllocExact(struct inode *ip, s64 blkno, int nblocks)
 /*
  * NAME:       dbReAlloc()
  *
- * FUNCTION:    attempt to extend a current allocation by a specified
+ * FUNCTION:   attempt to extend a current allocation by a specified
  *             number of blocks.
  *
  *             this routine attempts to satisfy the allocation request
@@ -959,21 +952,21 @@ int dbAllocExact(struct inode *ip, s64 blkno, int nblocks)
  *             number of blocks required.
  *
  * PARAMETERS:
- *      ip         -  pointer to in-core inode requiring allocation.
- *      blkno      -  starting block of the current allocation.
- *      nblocks            -  number of contiguous blocks within the current
+ *     ip          -  pointer to in-core inode requiring allocation.
+ *     blkno       -  starting block of the current allocation.
+ *     nblocks     -  number of contiguous blocks within the current
  *                    allocation.
- *      addnblocks  -  number of blocks to add to the allocation.
- *      results        -      on successful return, set to the starting block number
+ *     addnblocks  -  number of blocks to add to the allocation.
+ *     results -      on successful return, set to the starting block number
  *                    of the existing allocation if the existing allocation
  *                    was extended in place or to a newly allocated contiguous
  *                    range if the existing allocation could not be extended
  *                    in place.
  *
  * RETURN VALUES:
- *      0      - success
- *      -ENOSPC        - insufficient disk resources
- *      -EIO   - i/o error
+ *           - success
+ *     -ENOSPC - insufficient disk resources
+ *     -EIO    - i/o error
  */
 int
 dbReAlloc(struct inode *ip,
@@ -1004,7 +997,7 @@ dbReAlloc(struct inode *ip,
 /*
  * NAME:       dbExtend()
  *
- * FUNCTION:    attempt to extend a current allocation by a specified
+ * FUNCTION:   attempt to extend a current allocation by a specified
  *             number of blocks.
  *
  *             this routine attempts to satisfy the allocation request
@@ -1013,16 +1006,16 @@ dbReAlloc(struct inode *ip,
  *             immediately following the current allocation.
  *
  * PARAMETERS:
- *      ip         -  pointer to in-core inode requiring allocation.
- *      blkno      -  starting block of the current allocation.
- *      nblocks            -  number of contiguous blocks within the current
+ *     ip          -  pointer to in-core inode requiring allocation.
+ *     blkno       -  starting block of the current allocation.
+ *     nblocks     -  number of contiguous blocks within the current
  *                    allocation.
- *      addnblocks  -  number of blocks to add to the allocation.
+ *     addnblocks  -  number of blocks to add to the allocation.
  *
  * RETURN VALUES:
- *      0      - success
- *      -ENOSPC        - insufficient disk resources
- *      -EIO   - i/o error
+ *           - success
+ *     -ENOSPC - insufficient disk resources
+ *     -EIO    - i/o error
  */
 static int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks)
 {
@@ -1109,19 +1102,19 @@ static int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks)
 /*
  * NAME:       dbAllocNext()
  *
- * FUNCTION:    attempt to allocate the blocks of the specified block
+ * FUNCTION:   attempt to allocate the blocks of the specified block
  *             range within a dmap.
  *
  * PARAMETERS:
- *      bmp    -  pointer to bmap descriptor
- *      dp     -  pointer to dmap.
- *      blkno  -  starting block number of the range.
- *      nblocks        -  number of contiguous free blocks of the range.
+ *     bmp     -  pointer to bmap descriptor
+ *     dp      -  pointer to dmap.
+ *     blkno   -  starting block number of the range.
+ *     nblocks -  number of contiguous free blocks of the range.
  *
  * RETURN VALUES:
- *      0      - success
- *      -ENOSPC        - insufficient disk resources
- *      -EIO   - i/o error
+ *           - success
+ *     -ENOSPC - insufficient disk resources
+ *     -EIO    - i/o error
  *
  * serialization: IREAD_LOCK(ipbmap) held on entry/exit;
  */
@@ -1233,7 +1226,7 @@ static int dbAllocNext(struct bmap * bmp, struct dmap * dp, s64 blkno,
 /*
  * NAME:       dbAllocNear()
  *
- * FUNCTION:    attempt to allocate a number of contiguous free blocks near
+ * FUNCTION:   attempt to allocate a number of contiguous free blocks near
  *             a specified block (hint) within a dmap.
  *
  *             starting with the dmap leaf that covers the hint, we'll
@@ -1242,18 +1235,18 @@ static int dbAllocNext(struct bmap * bmp, struct dmap * dp, s64 blkno,
  *             the desired free space.
  *
  * PARAMETERS:
- *      bmp    -  pointer to bmap descriptor
- *      dp     -  pointer to dmap.
- *      blkno  -  block number to allocate near.
- *      nblocks        -  actual number of contiguous free blocks desired.
- *      l2nb   -  log2 number of contiguous free blocks desired.
- *      results        -  on successful return, set to the starting block number
+ *     bmp     -  pointer to bmap descriptor
+ *     dp      -  pointer to dmap.
+ *     blkno   -  block number to allocate near.
+ *     nblocks -  actual number of contiguous free blocks desired.
+ *     l2nb    -  log2 number of contiguous free blocks desired.
+ *     results -  on successful return, set to the starting block number
  *                of the newly allocated range.
  *
  * RETURN VALUES:
- *      0      - success
- *      -ENOSPC        - insufficient disk resources
- *      -EIO   - i/o error
+ *           - success
+ *     -ENOSPC - insufficient disk resources
+ *     -EIO    - i/o error
  *
  * serialization: IREAD_LOCK(ipbmap) held on entry/exit;
  */
@@ -1316,7 +1309,7 @@ dbAllocNear(struct bmap * bmp,
 /*
  * NAME:       dbAllocAG()
  *
- * FUNCTION:    attempt to allocate the specified number of contiguous
+ * FUNCTION:   attempt to allocate the specified number of contiguous
  *             free blocks within the specified allocation group.
  *
  *             unless the allocation group size is equal to the number
@@ -1353,17 +1346,17 @@ dbAllocNear(struct bmap * bmp,
  *             the allocation group.
  *
  * PARAMETERS:
- *      bmp    -  pointer to bmap descriptor
+ *     bmp     -  pointer to bmap descriptor
  *     agno    - allocation group number.
- *      nblocks        -  actual number of contiguous free blocks desired.
- *      l2nb   -  log2 number of contiguous free blocks desired.
- *      results        -  on successful return, set to the starting block number
+ *     nblocks -  actual number of contiguous free blocks desired.
+ *     l2nb    -  log2 number of contiguous free blocks desired.
+ *     results -  on successful return, set to the starting block number
  *                of the newly allocated range.
  *
  * RETURN VALUES:
- *      0      - success
- *      -ENOSPC        - insufficient disk resources
- *      -EIO   - i/o error
+ *           - success
+ *     -ENOSPC - insufficient disk resources
+ *     -EIO    - i/o error
  *
  * note: IWRITE_LOCK(ipmap) held on entry/exit;
  */
@@ -1546,7 +1539,7 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results)
 /*
  * NAME:       dbAllocAny()
  *
- * FUNCTION:    attempt to allocate the specified number of contiguous
+ * FUNCTION:   attempt to allocate the specified number of contiguous
  *             free blocks anywhere in the file system.
  *
  *             dbAllocAny() attempts to find the sufficient free space by
@@ -1556,16 +1549,16 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results)
  *             desired free space is allocated.
  *
  * PARAMETERS:
- *      bmp    -  pointer to bmap descriptor
- *      nblocks         -  actual number of contiguous free blocks desired.
- *      l2nb    -  log2 number of contiguous free blocks desired.
- *      results        -  on successful return, set to the starting block number
+ *     bmp     -  pointer to bmap descriptor
+ *     nblocks  -  actual number of contiguous free blocks desired.
+ *     l2nb     -  log2 number of contiguous free blocks desired.
+ *     results -  on successful return, set to the starting block number
  *                of the newly allocated range.
  *
  * RETURN VALUES:
- *      0      - success
- *      -ENOSPC        - insufficient disk resources
- *      -EIO   - i/o error
+ *           - success
+ *     -ENOSPC - insufficient disk resources
+ *     -EIO    - i/o error
  *
  * serialization: IWRITE_LOCK(ipbmap) held on entry/exit;
  */
@@ -1598,9 +1591,9 @@ static int dbAllocAny(struct bmap * bmp, s64 nblocks, int l2nb, s64 * results)
 /*
  * NAME:       dbFindCtl()
  *
- * FUNCTION:    starting at a specified dmap control page level and block
+ * FUNCTION:   starting at a specified dmap control page level and block
  *             number, search down the dmap control levels for a range of
- *             contiguous free blocks large enough to satisfy an allocation
+ *             contiguous free blocks large enough to satisfy an allocation
  *             request for the specified number of free blocks.
  *
  *             if sufficient contiguous free blocks are found, this routine
@@ -1609,17 +1602,17 @@ static int dbAllocAny(struct bmap * bmp, s64 nblocks, int l2nb, s64 * results)
  *             is sufficient in size.
  *
  * PARAMETERS:
- *      bmp    -  pointer to bmap descriptor
- *      level  -  starting dmap control page level.
- *      l2nb   -  log2 number of contiguous free blocks desired.
- *      *blkno -  on entry, starting block number for conducting the search.
+ *     bmp     -  pointer to bmap descriptor
+ *     level   -  starting dmap control page level.
+ *     l2nb    -  log2 number of contiguous free blocks desired.
+ *     *blkno  -  on entry, starting block number for conducting the search.
  *                on successful return, the first block within a dmap page
  *                that contains or starts a range of contiguous free blocks.
  *
  * RETURN VALUES:
- *      0      - success
- *      -ENOSPC        - insufficient disk resources
- *      -EIO   - i/o error
+ *           - success
+ *     -ENOSPC - insufficient disk resources
+ *     -EIO    - i/o error
  *
  * serialization: IWRITE_LOCK(ipbmap) held on entry/exit;
  */
@@ -1699,7 +1692,7 @@ static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno)
 /*
  * NAME:       dbAllocCtl()
  *
- * FUNCTION:    attempt to allocate a specified number of contiguous
+ * FUNCTION:   attempt to allocate a specified number of contiguous
  *             blocks starting within a specific dmap.
  *
  *             this routine is called by higher level routines that search
@@ -1726,18 +1719,18 @@ static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno)
  *             first dmap (i.e. blkno).
  *
  * PARAMETERS:
- *      bmp    -  pointer to bmap descriptor
- *      nblocks         -  actual number of contiguous free blocks to allocate.
- *      l2nb    -  log2 number of contiguous free blocks to allocate.
- *      blkno   -  starting block number of the dmap to start the allocation
+ *     bmp     -  pointer to bmap descriptor
+ *     nblocks  -  actual number of contiguous free blocks to allocate.
+ *     l2nb     -  log2 number of contiguous free blocks to allocate.
+ *     blkno    -  starting block number of the dmap to start the allocation
  *                 from.
- *      results        -  on successful return, set to the starting block number
+ *     results -  on successful return, set to the starting block number
  *                of the newly allocated range.
  *
  * RETURN VALUES:
- *      0      - success
- *      -ENOSPC        - insufficient disk resources
- *      -EIO   - i/o error
+ *           - success
+ *     -ENOSPC - insufficient disk resources
+ *     -EIO    - i/o error
  *
  * serialization: IWRITE_LOCK(ipbmap) held on entry/exit;
  */
@@ -1870,7 +1863,7 @@ dbAllocCtl(struct bmap * bmp, s64 nblocks, int l2nb, s64 blkno, s64 * results)
 /*
  * NAME:       dbAllocDmapLev()
  *
- * FUNCTION:    attempt to allocate a specified number of contiguous blocks
+ * FUNCTION:   attempt to allocate a specified number of contiguous blocks
  *             from a specified dmap.
  *
  *             this routine checks if the contiguous blocks are available.
@@ -1878,17 +1871,17 @@ dbAllocCtl(struct bmap * bmp, s64 nblocks, int l2nb, s64 blkno, s64 * results)
  *             returned.
  *
  * PARAMETERS:
- *      mp     -  pointer to bmap descriptor
- *      dp     -  pointer to dmap to attempt to allocate blocks from.
- *      l2nb   -  log2 number of contiguous block desired.
- *      nblocks        -  actual number of contiguous block desired.
- *      results        -  on successful return, set to the starting block number
+ *     mp      -  pointer to bmap descriptor
+ *     dp      -  pointer to dmap to attempt to allocate blocks from.
+ *     l2nb    -  log2 number of contiguous block desired.
+ *     nblocks -  actual number of contiguous block desired.
+ *     results -  on successful return, set to the starting block number
  *                of the newly allocated range.
  *
  * RETURN VALUES:
- *      0      - success
- *      -ENOSPC        - insufficient disk resources
- *      -EIO   - i/o error
+ *           - success
+ *     -ENOSPC - insufficient disk resources
+ *     -EIO    - i/o error
  *
  * serialization: IREAD_LOCK(ipbmap), e.g., from dbAlloc(), or
  *     IWRITE_LOCK(ipbmap), e.g., dbAllocCtl(), held on entry/exit;
@@ -1933,7 +1926,7 @@ dbAllocDmapLev(struct bmap * bmp,
 /*
  * NAME:       dbAllocDmap()
  *
- * FUNCTION:    adjust the disk allocation map to reflect the allocation
+ * FUNCTION:   adjust the disk allocation map to reflect the allocation
  *             of a specified block range within a dmap.
  *
  *             this routine allocates the specified blocks from the dmap
@@ -1946,14 +1939,14 @@ dbAllocDmapLev(struct bmap * bmp,
  *             covers this dmap.
  *
  * PARAMETERS:
- *      bmp    -  pointer to bmap descriptor
- *      dp     -  pointer to dmap to allocate the block range from.
- *      blkno  -  starting block number of the block to be allocated.
- *      nblocks        -  number of blocks to be allocated.
+ *     bmp     -  pointer to bmap descriptor
+ *     dp      -  pointer to dmap to allocate the block range from.
+ *     blkno   -  starting block number of the block to be allocated.
+ *     nblocks -  number of blocks to be allocated.
  *
  * RETURN VALUES:
- *      0      - success
- *      -EIO   - i/o error
+ *           - success
+ *     -EIO    - i/o error
  *
  * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit;
  */
@@ -1989,7 +1982,7 @@ static int dbAllocDmap(struct bmap * bmp, struct dmap * dp, s64 blkno,
 /*
  * NAME:       dbFreeDmap()
  *
- * FUNCTION:    adjust the disk allocation map to reflect the allocation
+ * FUNCTION:   adjust the disk allocation map to reflect the allocation
  *             of a specified block range within a dmap.
  *
  *             this routine frees the specified blocks from the dmap through
@@ -1997,18 +1990,18 @@ static int dbAllocDmap(struct bmap * bmp, struct dmap * dp, s64 blkno,
  *             causes the maximum string of free blocks within the dmap to
  *             change (i.e. the value of the root of the dmap's dmtree), this
  *             routine will cause this change to be reflected up through the
- *             appropriate levels of the dmap control pages by a call to
+ *             appropriate levels of the dmap control pages by a call to
  *             dbAdjCtl() for the L0 dmap control page that covers this dmap.
  *
  * PARAMETERS:
- *      bmp    -  pointer to bmap descriptor
- *      dp     -  pointer to dmap to free the block range from.
- *      blkno  -  starting block number of the block to be freed.
- *      nblocks        -  number of blocks to be freed.
+ *     bmp     -  pointer to bmap descriptor
+ *     dp      -  pointer to dmap to free the block range from.
+ *     blkno   -  starting block number of the block to be freed.
+ *     nblocks -  number of blocks to be freed.
  *
  * RETURN VALUES:
- *      0      - success
- *      -EIO   - i/o error
+ *           - success
+ *     -EIO    - i/o error
  *
  * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit;
  */
@@ -2055,7 +2048,7 @@ static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno,
 /*
  * NAME:       dbAllocBits()
  *
- * FUNCTION:    allocate a specified block range from a dmap.
+ * FUNCTION:   allocate a specified block range from a dmap.
  *
  *             this routine updates the dmap to reflect the working
  *             state allocation of the specified block range. it directly
@@ -2065,10 +2058,10 @@ static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno,
  *             dmap's dmtree, as a whole, to reflect the allocated range.
  *
  * PARAMETERS:
- *      bmp    -  pointer to bmap descriptor
- *      dp     -  pointer to dmap to allocate bits from.
- *      blkno  -  starting block number of the bits to be allocated.
- *      nblocks        -  number of bits to be allocated.
+ *     bmp     -  pointer to bmap descriptor
+ *     dp      -  pointer to dmap to allocate bits from.
+ *     blkno   -  starting block number of the bits to be allocated.
+ *     nblocks -  number of bits to be allocated.
  *
  * RETURN VALUES: none
  *
@@ -2149,7 +2142,7 @@ static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
                         * the allocated words.
                         */
                        for (; nwords > 0; nwords -= nw) {
-                               if (leaf[word] < BUDMIN) {
+                               if (leaf[word] < BUDMIN) {
                                        jfs_error(bmp->db_ipbmap->i_sb,
                                                  "dbAllocBits: leaf page "
                                                  "corrupt");
@@ -2202,7 +2195,7 @@ static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
 /*
  * NAME:       dbFreeBits()
  *
- * FUNCTION:    free a specified block range from a dmap.
+ * FUNCTION:   free a specified block range from a dmap.
  *
  *             this routine updates the dmap to reflect the working
  *             state allocation of the specified block range. it directly
@@ -2212,10 +2205,10 @@ static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
  *             dmtree, as a whole, to reflect the deallocated range.
  *
  * PARAMETERS:
- *      bmp    -  pointer to bmap descriptor
- *      dp     -  pointer to dmap to free bits from.
- *      blkno  -  starting block number of the bits to be freed.
- *      nblocks        -  number of bits to be freed.
+ *     bmp     -  pointer to bmap descriptor
+ *     dp      -  pointer to dmap to free bits from.
+ *     blkno   -  starting block number of the bits to be freed.
+ *     nblocks -  number of bits to be freed.
  *
  * RETURN VALUES: 0 for success
  *
@@ -2388,19 +2381,19 @@ static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
  *             the new root value and the next dmap control page level to
  *             be adjusted.
  * PARAMETERS:
- *      bmp    -  pointer to bmap descriptor
- *      blkno  -  the first block of a block range within a dmap.  it is
+ *     bmp     -  pointer to bmap descriptor
+ *     blkno   -  the first block of a block range within a dmap.  it is
  *                the allocation or deallocation of this block range that
  *                requires the dmap control page to be adjusted.
- *      newval -  the new value of the lower level dmap or dmap control
+ *     newval  -  the new value of the lower level dmap or dmap control
  *                page root.
- *      alloc  -  'true' if adjustment is due to an allocation.
- *      level  -  current level of dmap control page (i.e. L0, L1, L2) to
+ *     alloc   -  'true' if adjustment is due to an allocation.
+ *     level   -  current level of dmap control page (i.e. L0, L1, L2) to
  *                be adjusted.
  *
  * RETURN VALUES:
- *      0      - success
- *      -EIO   - i/o error
+ *           - success
+ *     -EIO    - i/o error
  *
  * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit;
  */
@@ -2544,16 +2537,16 @@ dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc, int level)
 /*
  * NAME:       dbSplit()
  *
- * FUNCTION:    update the leaf of a dmtree with a new value, splitting
+ * FUNCTION:   update the leaf of a dmtree with a new value, splitting
  *             the leaf from the binary buddy system of the dmtree's
  *             leaves, as required.
  *
  * PARAMETERS:
- *      tp     - pointer to the tree containing the leaf.
- *      leafno - the number of the leaf to be updated.
- *      splitsz        - the size the binary buddy system starting at the leaf
+ *     tp      - pointer to the tree containing the leaf.
+ *     leafno  - the number of the leaf to be updated.
+ *     splitsz - the size the binary buddy system starting at the leaf
  *               must be split to, specified as the log2 number of blocks.
- *      newval - the new value for the leaf.
+ *     newval  - the new value for the leaf.
  *
  * RETURN VALUES: none
  *
@@ -2600,7 +2593,7 @@ static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval)
 /*
  * NAME:       dbBackSplit()
  *
- * FUNCTION:    back split the binary buddy system of dmtree leaves
+ * FUNCTION:   back split the binary buddy system of dmtree leaves
  *             that hold a specified leaf until the specified leaf
  *             starts its own binary buddy system.
  *
@@ -2617,8 +2610,8 @@ static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval)
  *             in which a previous join operation must be backed out.
  *
  * PARAMETERS:
- *      tp     - pointer to the tree containing the leaf.
- *      leafno - the number of the leaf to be updated.
+ *     tp      - pointer to the tree containing the leaf.
+ *     leafno  - the number of the leaf to be updated.
  *
  * RETURN VALUES: none
  *
@@ -2692,14 +2685,14 @@ static int dbBackSplit(dmtree_t * tp, int leafno)
 /*
  * NAME:       dbJoin()
  *
- * FUNCTION:    update the leaf of a dmtree with a new value, joining
+ * FUNCTION:   update the leaf of a dmtree with a new value, joining
  *             the leaf with other leaves of the dmtree into a multi-leaf
  *             binary buddy system, as required.
  *
  * PARAMETERS:
- *      tp     - pointer to the tree containing the leaf.
- *      leafno - the number of the leaf to be updated.
- *      newval - the new value for the leaf.
+ *     tp      - pointer to the tree containing the leaf.
+ *     leafno  - the number of the leaf to be updated.
+ *     newval  - the new value for the leaf.
  *
  * RETURN VALUES: none
  */
@@ -2785,15 +2778,15 @@ static int dbJoin(dmtree_t * tp, int leafno, int newval)
 /*
  * NAME:       dbAdjTree()
  *
- * FUNCTION:    update a leaf of a dmtree with a new value, adjusting
+ * FUNCTION:   update a leaf of a dmtree with a new value, adjusting
  *             the dmtree, as required, to reflect the new leaf value.
  *             the combination of any buddies must already be done before
  *             this is called.
  *
  * PARAMETERS:
- *      tp     - pointer to the tree to be adjusted.
- *      leafno - the number of the leaf to be updated.
- *      newval - the new value for the leaf.
+ *     tp      - pointer to the tree to be adjusted.
+ *     leafno  - the number of the leaf to be updated.
+ *     newval  - the new value for the leaf.
  *
  * RETURN VALUES: none
  */
@@ -2852,7 +2845,7 @@ static void dbAdjTree(dmtree_t * tp, int leafno, int newval)
 /*
  * NAME:       dbFindLeaf()
  *
- * FUNCTION:    search a dmtree_t for sufficient free blocks, returning
+ * FUNCTION:   search a dmtree_t for sufficient free blocks, returning
  *             the index of a leaf describing the free blocks if
  *             sufficient free blocks are found.
  *
@@ -2861,15 +2854,15 @@ static void dbAdjTree(dmtree_t * tp, int leafno, int newval)
  *             free space.
  *
  * PARAMETERS:
- *      tp     - pointer to the tree to be searched.
- *      l2nb   - log2 number of free blocks to search for.
+ *     tp      - pointer to the tree to be searched.
+ *     l2nb    - log2 number of free blocks to search for.
  *     leafidx - return pointer to be set to the index of the leaf
  *               describing at least l2nb free blocks if sufficient
  *               free blocks are found.
  *
  * RETURN VALUES:
- *      0      - success
- *      -ENOSPC        - insufficient free blocks.
+ *           - success
+ *     -ENOSPC - insufficient free blocks.
  */
 static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx)
 {
@@ -2916,18 +2909,18 @@ static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx)
 /*
  * NAME:       dbFindBits()
  *
- * FUNCTION:    find a specified number of binary buddy free bits within a
+ * FUNCTION:   find a specified number of binary buddy free bits within a
  *             dmap bitmap word value.
  *
  *             this routine searches the bitmap value for (1 << l2nb) free
  *             bits at (1 << l2nb) alignments within the value.
  *
  * PARAMETERS:
- *      word   -  dmap bitmap word value.
- *      l2nb   -  number of free bits specified as a log2 number.
+ *     word    -  dmap bitmap word value.
+ *     l2nb    -  number of free bits specified as a log2 number.
  *
  * RETURN VALUES:
- *      starting bit number of free bits.
+ *     starting bit number of free bits.
  */
 static int dbFindBits(u32 word, int l2nb)
 {
@@ -2963,14 +2956,14 @@ static int dbFindBits(u32 word, int l2nb)
 /*
  * NAME:       dbMaxBud(u8 *cp)
  *
- * FUNCTION:    determine the largest binary buddy string of free
+ * FUNCTION:   determine the largest binary buddy string of free
  *             bits within 32-bits of the map.
  *
  * PARAMETERS:
- *      cp     -  pointer to the 32-bit value.
+ *     cp      -  pointer to the 32-bit value.
  *
  * RETURN VALUES:
- *      largest binary buddy of free bits within a dmap word.
+ *     largest binary buddy of free bits within a dmap word.
  */
 static int dbMaxBud(u8 * cp)
 {
@@ -3000,14 +2993,14 @@ static int dbMaxBud(u8 * cp)
 /*
  * NAME:       cnttz(uint word)
  *
- * FUNCTION:    determine the number of trailing zeros within a 32-bit
+ * FUNCTION:   determine the number of trailing zeros within a 32-bit
  *             value.
  *
  * PARAMETERS:
- *      value  -  32-bit value to be examined.
+ *     value   -  32-bit value to be examined.
  *
  * RETURN VALUES:
- *      count of trailing zeros
+ *     count of trailing zeros
  */
 static int cnttz(u32 word)
 {
@@ -3025,14 +3018,14 @@ static int cnttz(u32 word)
 /*
  * NAME:       cntlz(u32 value)
  *
- * FUNCTION:    determine the number of leading zeros within a 32-bit
+ * FUNCTION:   determine the number of leading zeros within a 32-bit
  *             value.
  *
  * PARAMETERS:
- *      value  -  32-bit value to be examined.
+ *     value   -  32-bit value to be examined.
  *
  * RETURN VALUES:
- *      count of leading zeros
+ *     count of leading zeros
  */
 static int cntlz(u32 value)
 {
@@ -3050,14 +3043,14 @@ static int cntlz(u32 value)
  * NAME:       blkstol2(s64 nb)
  *
  * FUNCTION:   convert a block count to its log2 value. if the block
- *             count is not a l2 multiple, it is rounded up to the next
+ *             count is not a l2 multiple, it is rounded up to the next
  *             larger l2 multiple.
  *
  * PARAMETERS:
- *      nb     -  number of blocks
+ *     nb      -  number of blocks
  *
  * RETURN VALUES:
- *      log2 number of blocks
+ *     log2 number of blocks
  */
 static int blkstol2(s64 nb)
 {
@@ -3099,13 +3092,13 @@ static int blkstol2(s64 nb)
  *             at a time.
  *
  * PARAMETERS:
- *      ip     -  pointer to in-core inode;
- *      blkno  -  starting block number to be freed.
- *      nblocks        -  number of blocks to be freed.
+ *     ip      -  pointer to in-core inode;
+ *     blkno   -  starting block number to be freed.
+ *     nblocks -  number of blocks to be freed.
  *
  * RETURN VALUES:
- *      0      - success
- *      -EIO   - i/o error
+ *           - success
+ *     -EIO    - i/o error
  */
 int dbAllocBottomUp(struct inode *ip, s64 blkno, s64 nblocks)
 {
@@ -3278,10 +3271,10 @@ static int dbAllocDmapBU(struct bmap * bmp, struct dmap * dp, s64 blkno,
  * L2
  *  |
  *   L1---------------------------------L1
- *    |                                  |
- *     L0---------L0---------L0           L0---------L0---------L0
- *      |          |          |            |          |          |
- *       d0,...,dn  d0,...,dn  d0,...,dn    d0,...,dn  d0,...,dn  d0,.,dm;
+ *    |                                         |
+ *     L0---------L0---------L0                  L0---------L0---------L0
+ *      |         |          |            |          |          |
+ *      d0,...,dn  d0,...,dn  d0,...,dn    d0,...,dn  d0,...,dn  d0,.,dm;
  * L2L1L0d0,...,dnL0d0,...,dnL0d0,...,dnL1L0d0,...,dnL0d0,...,dnL0d0,..dm
  *
  * <---old---><----------------------------extend----------------------->
@@ -3307,7 +3300,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno,   s64 nblocks)
                 (long long) blkno, (long long) nblocks, (long long) newsize);
 
        /*
-        *      initialize bmap control page.
+        *      initialize bmap control page.
         *
         * all the data in bmap control page should exclude
         * the mkfs hidden dmap page.
@@ -3330,7 +3323,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno,   s64 nblocks)
        bmp->db_numag += ((u32) newsize % (u32) bmp->db_agsize) ? 1 : 0;
 
        /*
-        *      reconfigure db_agfree[]
+        *      reconfigure db_agfree[]
         * from old AG configuration to new AG configuration;
         *
         * coalesce contiguous k (newAGSize/oldAGSize) AGs;
@@ -3362,7 +3355,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno,   s64 nblocks)
        bmp->db_maxag = bmp->db_maxag / k;
 
        /*
-        *      extend bmap
+        *      extend bmap
         *
         * update bit maps and corresponding level control pages;
         * global control page db_nfree, db_agfree[agno], db_maxfreebud;
@@ -3410,7 +3403,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno,   s64 nblocks)
                        /* compute start L0 */
                        j = 0;
                        l1leaf = l1dcp->stree + CTLLEAFIND;
-                       p += nbperpage; /* 1st L0 of L1.k  */
+                       p += nbperpage; /* 1st L0 of L1.k */
                }
 
                /*
@@ -3548,7 +3541,7 @@ errout:
        return -EIO;
 
        /*
-        *      finalize bmap control page
+        *      finalize bmap control page
         */
 finalize:
 
@@ -3567,7 +3560,7 @@ void dbFinalizeBmap(struct inode *ipbmap)
        int i, n;
 
        /*
-        *      finalize bmap control page
+        *      finalize bmap control page
         */
 //finalize:
        /*
@@ -3953,8 +3946,8 @@ static int dbGetL2AGSize(s64 nblocks)
  * convert number of map pages to the zero origin top dmapctl level
  */
 #define BMAPPGTOLEV(npages)    \
-       (((npages) <= 3 + MAXL0PAGES) ? 0 \
-       : ((npages) <= 2 + MAXL1PAGES) ? 1 : 2)
+       (((npages) <= 3 + MAXL0PAGES) ? 0 \
+        ((npages) <= 2 + MAXL1PAGES) ? 1 : 2)
 
 s64 dbMapFileSizeToMapSize(struct inode * ipbmap)
 {
@@ -3981,8 +3974,8 @@ s64 dbMapFileSizeToMapSize(struct inode * ipbmap)
                factor =
                    (i == 2) ? MAXL1PAGES : ((i == 1) ? MAXL0PAGES : 1);
                complete = (u32) npages / factor;
-               ndmaps += complete * ((i == 2) ? LPERCTL * LPERCTL
-                                     ((i == 1) ? LPERCTL : 1));
+               ndmaps += complete * ((i == 2) ? LPERCTL * LPERCTL :
+                                     ((i == 1) ? LPERCTL : 1));
 
                /* pages in last/incomplete child */
                npages = (u32) npages % factor;
index 45ea454c74bd03f615fac463793ace154d9a7b1f..11e6d471b364260e00ef7ebd672e106240799e7b 100644 (file)
@@ -83,7 +83,7 @@ static __inline signed char TREEMAX(signed char *cp)
  *     - 1 is added to account for the control page of the map.
  */
 #define BLKTODMAP(b,s)    \
-        ((((b) >> 13) + ((b) >> 23) + ((b) >> 33) + 3 + 1) << (s))
+       ((((b) >> 13) + ((b) >> 23) + ((b) >> 33) + 3 + 1) << (s))
 
 /*
  * convert disk block number to the logical block number of the LEVEL 0
@@ -98,7 +98,7 @@ static __inline signed char TREEMAX(signed char *cp)
  *     - 1 is added to account for the control page of the map.
  */
 #define BLKTOL0(b,s)      \
-        (((((b) >> 23) << 10) + ((b) >> 23) + ((b) >> 33) + 2 + 1) << (s))
+       (((((b) >> 23) << 10) + ((b) >> 23) + ((b) >> 33) + 2 + 1) << (s))
 
 /*
  * convert disk block number to the logical block number of the LEVEL 1
@@ -120,7 +120,7 @@ static __inline signed char TREEMAX(signed char *cp)
  * at the specified level which describes the disk block.
  */
 #define BLKTOCTL(b,s,l)   \
-        (((l) == 2) ? 1 : ((l) == 1) ? BLKTOL1((b),(s)) : BLKTOL0((b),(s)))
+       (((l) == 2) ? 1 : ((l) == 1) ? BLKTOL1((b),(s)) : BLKTOL0((b),(s)))
 
 /*
  * convert aggregate map size to the zero origin dmapctl level of the
@@ -145,27 +145,27 @@ static __inline signed char TREEMAX(signed char *cp)
  * dmaptree must be consistent with dmapctl.
  */
 struct dmaptree {
-       __le32 nleafs;          /* 4: number of tree leafs      */
-       __le32 l2nleafs;        /* 4: l2 number of tree leafs   */
-       __le32 leafidx;         /* 4: index of first tree leaf  */
-       __le32 height;          /* 4: height of the tree        */
+       __le32 nleafs;          /* 4: number of tree leafs      */
+       __le32 l2nleafs;        /* 4: l2 number of tree leafs   */
+       __le32 leafidx;         /* 4: index of first tree leaf  */
+       __le32 height;          /* 4: height of the tree        */
        s8 budmin;              /* 1: min l2 tree leaf value to combine */
-       s8 stree[TREESIZE];     /* TREESIZE: tree               */
-       u8 pad[2];              /* 2: pad to word boundary      */
-};                             /* - 360 -                      */
+       s8 stree[TREESIZE];     /* TREESIZE: tree               */
+       u8 pad[2];              /* 2: pad to word boundary      */
+};                             /* - 360 -                      */
 
 /*
  *     dmap page per 8K blocks bitmap
  */
 struct dmap {
-       __le32 nblocks;         /* 4: num blks covered by this dmap     */
-       __le32 nfree;           /* 4: num of free blks in this dmap     */
-       __le64 start;           /* 8: starting blkno for this dmap      */
-       struct dmaptree tree;   /* 360: dmap tree                       */
-       u8 pad[1672];           /* 1672: pad to 2048 bytes              */
-       __le32 wmap[LPERDMAP];  /* 1024: bits of the working map        */
-       __le32 pmap[LPERDMAP];  /* 1024: bits of the persistent map     */
-};                             /* - 4096 -                             */
+       __le32 nblocks;         /* 4: num blks covered by this dmap     */
+       __le32 nfree;           /* 4: num of free blks in this dmap     */
+       __le64 start;           /* 8: starting blkno for this dmap      */
+       struct dmaptree tree;   /* 360: dmap tree                       */
+       u8 pad[1672];           /* 1672: pad to 2048 bytes              */
+       __le32 wmap[LPERDMAP];  /* 1024: bits of the working map        */
+       __le32 pmap[LPERDMAP];  /* 1024: bits of the persistent map     */
+};                             /* - 4096 -                             */
 
 /*
  *     disk map control page per level.
@@ -173,14 +173,14 @@ struct dmap {
  * dmapctl must be consistent with dmaptree.
  */
 struct dmapctl {
-       __le32 nleafs;          /* 4: number of tree leafs      */
-       __le32 l2nleafs;        /* 4: l2 number of tree leafs   */
-       __le32 leafidx;         /* 4: index of the first tree leaf      */
-       __le32 height;          /* 4: height of tree            */
-       s8 budmin;              /* 1: minimum l2 tree leaf value        */
-       s8 stree[CTLTREESIZE];  /* CTLTREESIZE: dmapctl tree    */
-       u8 pad[2714];           /* 2714: pad to 4096            */
-};                             /* - 4096 -                     */
+       __le32 nleafs;          /* 4: number of tree leafs      */
+       __le32 l2nleafs;        /* 4: l2 number of tree leafs   */
+       __le32 leafidx;         /* 4: index of the first tree leaf      */
+       __le32 height;          /* 4: height of tree            */
+       s8 budmin;              /* 1: minimum l2 tree leaf value        */
+       s8 stree[CTLTREESIZE];  /* CTLTREESIZE: dmapctl tree    */
+       u8 pad[2714];           /* 2714: pad to 4096            */
+};                             /* - 4096 -                     */
 
 /*
  *     common definition for dmaptree within dmap and dmapctl
@@ -202,41 +202,41 @@ typedef union dmtree {
  *     on-disk aggregate disk allocation map descriptor.
  */
 struct dbmap_disk {
-       __le64 dn_mapsize;      /* 8: number of blocks in aggregate     */
-       __le64 dn_nfree;        /* 8: num free blks in aggregate map    */
-       __le32 dn_l2nbperpage;  /* 4: number of blks per page           */
-       __le32 dn_numag;        /* 4: total number of ags               */
-       __le32 dn_maxlevel;     /* 4: number of active ags              */
-       __le32 dn_maxag;        /* 4: max active alloc group number     */
-       __le32 dn_agpref;       /* 4: preferred alloc group (hint)      */
-       __le32 dn_aglevel;      /* 4: dmapctl level holding the AG      */
-       __le32 dn_agheigth;     /* 4: height in dmapctl of the AG       */
-       __le32 dn_agwidth;      /* 4: width in dmapctl of the AG        */
-       __le32 dn_agstart;      /* 4: start tree index at AG height     */
-       __le32 dn_agl2size;     /* 4: l2 num of blks per alloc group    */
-       __le64 dn_agfree[MAXAG];/* 8*MAXAG: per AG free count           */
-       __le64 dn_agsize;       /* 8: num of blks per alloc group       */
-       s8 dn_maxfreebud;       /* 1: max free buddy system             */
-       u8 pad[3007];           /* 3007: pad to 4096                    */
-};                             /* - 4096 -                             */
+       __le64 dn_mapsize;      /* 8: number of blocks in aggregate     */
+       __le64 dn_nfree;        /* 8: num free blks in aggregate map    */
+       __le32 dn_l2nbperpage;  /* 4: number of blks per page           */
+       __le32 dn_numag;        /* 4: total number of ags               */
+       __le32 dn_maxlevel;     /* 4: number of active ags              */
+       __le32 dn_maxag;        /* 4: max active alloc group number     */
+       __le32 dn_agpref;       /* 4: preferred alloc group (hint)      */
+       __le32 dn_aglevel;      /* 4: dmapctl level holding the AG      */
+       __le32 dn_agheigth;     /* 4: height in dmapctl of the AG       */
+       __le32 dn_agwidth;      /* 4: width in dmapctl of the AG        */
+       __le32 dn_agstart;      /* 4: start tree index at AG height     */
+       __le32 dn_agl2size;     /* 4: l2 num of blks per alloc group    */
+       __le64 dn_agfree[MAXAG];/* 8*MAXAG: per AG free count           */
+       __le64 dn_agsize;       /* 8: num of blks per alloc group       */
+       s8 dn_maxfreebud;       /* 1: max free buddy system             */
+       u8 pad[3007];           /* 3007: pad to 4096                    */
+};                             /* - 4096 -                             */
 
 struct dbmap {
-       s64 dn_mapsize;         /* number of blocks in aggregate     */
-       s64 dn_nfree;           /* num free blks in aggregate map    */
-       int dn_l2nbperpage;     /* number of blks per page           */
-       int dn_numag;           /* total number of ags               */
-       int dn_maxlevel;        /* number of active ags              */
-       int dn_maxag;           /* max active alloc group number     */
-       int dn_agpref;          /* preferred alloc group (hint)      */
-       int dn_aglevel;         /* dmapctl level holding the AG      */
-       int dn_agheigth;        /* height in dmapctl of the AG       */
-       int dn_agwidth;         /* width in dmapctl of the AG        */
-       int dn_agstart;         /* start tree index at AG height     */
-       int dn_agl2size;        /* l2 num of blks per alloc group    */
-       s64 dn_agfree[MAXAG];   /* per AG free count           */
-       s64 dn_agsize;          /* num of blks per alloc group       */
-       signed char dn_maxfreebud;      /* max free buddy system             */
-};                             /* - 4096 -                             */
+       s64 dn_mapsize;         /* number of blocks in aggregate        */
+       s64 dn_nfree;           /* num free blks in aggregate map       */
+       int dn_l2nbperpage;     /* number of blks per page              */
+       int dn_numag;           /* total number of ags                  */
+       int dn_maxlevel;        /* number of active ags                 */
+       int dn_maxag;           /* max active alloc group number        */
+       int dn_agpref;          /* preferred alloc group (hint)         */
+       int dn_aglevel;         /* dmapctl level holding the AG         */
+       int dn_agheigth;        /* height in dmapctl of the AG          */
+       int dn_agwidth;         /* width in dmapctl of the AG           */
+       int dn_agstart;         /* start tree index at AG height        */
+       int dn_agl2size;        /* l2 num of blks per alloc group       */
+       s64 dn_agfree[MAXAG];   /* per AG free count                    */
+       s64 dn_agsize;          /* num of blks per alloc group          */
+       signed char dn_maxfreebud;      /* max free buddy system        */
+};                             /* - 4096 -                             */
 /*
  *     in-memory aggregate disk allocation map descriptor.
  */
index 6d62f3222892cd1fd6c74ce679c724f941e0bda2..c14ba3cfa8189f04910b02ebb305601ffef0a853 100644 (file)
@@ -315,8 +315,8 @@ static inline void lock_index(tid_t tid, struct inode *ip, struct metapage * mp,
        lv = &llck->lv[llck->index];
 
        /*
-        *      Linelock slot size is twice the size of directory table
-        *      slot size.  512 entries per page.
+        *      Linelock slot size is twice the size of directory table
+        *      slot size.  512 entries per page.
         */
        lv->offset = ((index - 2) & 511) >> 1;
        lv->length = 1;
@@ -615,7 +615,7 @@ int dtSearch(struct inode *ip, struct component_name * key, ino_t * data,
        btstack->nsplit = 1;
 
        /*
-        *      search down tree from root:
+        *      search down tree from root:
         *
         * between two consecutive entries of <Ki, Pi> and <Kj, Pj> of
         * internal page, child page Pi contains entry with k, Ki <= K < Kj.
@@ -659,7 +659,7 @@ int dtSearch(struct inode *ip, struct component_name * key, ino_t * data,
                        }
                        if (cmp == 0) {
                                /*
-                                *      search hit
+                                *      search hit
                                 */
                                /* search hit - leaf page:
                                 * return the entry found
@@ -723,7 +723,7 @@ int dtSearch(struct inode *ip, struct component_name * key, ino_t * data,
                }
 
                /*
-                *      search miss
+                *      search miss
                 *
                 * base is the smallest index with key (Kj) greater than
                 * search key (K) and may be zero or (maxindex + 1) index.
@@ -834,7 +834,7 @@ int dtInsert(tid_t tid, struct inode *ip,
        struct lv *lv;
 
        /*
-        *      retrieve search result
+        *      retrieve search result
         *
         * dtSearch() returns (leaf page pinned, index at which to insert).
         * n.b. dtSearch() may return index of (maxindex + 1) of
@@ -843,7 +843,7 @@ int dtInsert(tid_t tid, struct inode *ip,
        DT_GETSEARCH(ip, btstack->top, bn, mp, p, index);
 
        /*
-        *      insert entry for new key
+        *      insert entry for new key
         */
        if (DO_INDEX(ip)) {
                if (JFS_IP(ip)->next_index == DIREND) {
@@ -860,9 +860,9 @@ int dtInsert(tid_t tid, struct inode *ip,
        data.leaf.ino = *fsn;
 
        /*
-        *      leaf page does not have enough room for new entry:
+        *      leaf page does not have enough room for new entry:
         *
-        *      extend/split the leaf page;
+        *      extend/split the leaf page;
         *
         * dtSplitUp() will insert the entry and unpin the leaf page.
         */
@@ -877,9 +877,9 @@ int dtInsert(tid_t tid, struct inode *ip,
        }
 
        /*
-        *      leaf page does have enough room for new entry:
+        *      leaf page does have enough room for new entry:
         *
-        *      insert the new data entry into the leaf page;
+        *      insert the new data entry into the leaf page;
         */
        BT_MARK_DIRTY(mp, ip);
        /*
@@ -967,13 +967,13 @@ static int dtSplitUp(tid_t tid,
        }
 
        /*
-        *      split leaf page
+        *      split leaf page
         *
         * The split routines insert the new entry, and
         * acquire txLock as appropriate.
         */
        /*
-        *      split root leaf page:
+        *      split root leaf page:
         */
        if (sp->header.flag & BT_ROOT) {
                /*
@@ -1012,7 +1012,7 @@ static int dtSplitUp(tid_t tid,
        }
 
        /*
-        *      extend first leaf page
+        *      extend first leaf page
         *
         * extend the 1st extent if less than buffer page size
         * (dtExtendPage() reurns leaf page unpinned)
@@ -1068,7 +1068,7 @@ static int dtSplitUp(tid_t tid,
        }
 
        /*
-        *      split leaf page <sp> into <sp> and a new right page <rp>.
+        *      split leaf page <sp> into <sp> and a new right page <rp>.
         *
         * return <rp> pinned and its extent descriptor <rpxd>
         */
@@ -1433,7 +1433,7 @@ static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split,
        rp->header.freecnt = rp->header.maxslot - fsi;
 
        /*
-        *      sequential append at tail: append without split
+        *      sequential append at tail: append without split
         *
         * If splitting the last page on a level because of appending
         * a entry to it (skip is maxentry), it's likely that the access is
@@ -1467,7 +1467,7 @@ static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split,
        }
 
        /*
-        *      non-sequential insert (at possibly middle page)
+        *      non-sequential insert (at possibly middle page)
         */
 
        /*
@@ -1508,7 +1508,7 @@ static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split,
        left = 0;
 
        /*
-        *      compute fill factor for split pages
+        *      compute fill factor for split pages
         *
         * <nxt> traces the next entry to move to rp
         * <off> traces the next entry to stay in sp
@@ -1551,7 +1551,7 @@ static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split,
        /* <nxt> poins to the 1st entry to move */
 
        /*
-        *      move entries to right page
+        *      move entries to right page
         *
         * dtMoveEntry() initializes rp and reserves entry for insertion
         *
@@ -1677,7 +1677,7 @@ static int dtExtendPage(tid_t tid,
                return (rc);
 
        /*
-        *      extend the extent
+        *      extend the extent
         */
        pxdlist = split->pxdlist;
        pxd = &pxdlist->pxd[pxdlist->npxd];
@@ -1722,7 +1722,7 @@ static int dtExtendPage(tid_t tid,
        }
 
        /*
-        *      extend the page
+        *      extend the page
         */
        sp->header.self = *pxd;
 
@@ -1739,9 +1739,6 @@ static int dtExtendPage(tid_t tid,
        /* update buffer extent descriptor of extended page */
        xlen = lengthPXD(pxd);
        xsize = xlen << JFS_SBI(sb)->l2bsize;
-#ifdef _STILL_TO_PORT
-       bmSetXD(smp, xaddr, xsize);
-#endif                         /*  _STILL_TO_PORT */
 
        /*
         * copy old stbl to new stbl at start of extended area
@@ -1836,7 +1833,7 @@ static int dtExtendPage(tid_t tid,
        }
 
        /*
-        *      update parent entry on the parent/root page
+        *      update parent entry on the parent/root page
         */
        /*
         * acquire a transaction lock on the parent/root page
@@ -1904,7 +1901,7 @@ static int dtSplitRoot(tid_t tid,
        sp = &JFS_IP(ip)->i_dtroot;
 
        /*
-        *      allocate/initialize a single (right) child page
+        *      allocate/initialize a single (right) child page
         *
         * N.B. at first split, a one (or two) block to fit new entry
         * is allocated; at subsequent split, a full page is allocated;
@@ -1943,7 +1940,7 @@ static int dtSplitRoot(tid_t tid,
        rp->header.prev = 0;
 
        /*
-        *      move in-line root page into new right page extent
+        *      move in-line root page into new right page extent
         */
        /* linelock header + copied entries + new stbl (1st slot) in new page */
        ASSERT(dtlck->index == 0);
@@ -2016,7 +2013,7 @@ static int dtSplitRoot(tid_t tid,
        dtInsertEntry(rp, split->index, split->key, split->data, &dtlck);
 
        /*
-        *      reset parent/root page
+        *      reset parent/root page
         *
         * set the 1st entry offset to 0, which force the left-most key
         * at any level of the tree to be less than any search key.
@@ -2102,7 +2099,7 @@ int dtDelete(tid_t tid,
        dtpage_t *np;
 
        /*
-        *      search for the entry to delete:
+        *      search for the entry to delete:
         *
         * dtSearch() returns (leaf page pinned, index at which to delete).
         */
@@ -2253,7 +2250,7 @@ static int dtDeleteUp(tid_t tid, struct inode *ip,
        int i;
 
        /*
-        *      keep the root leaf page which has become empty
+        *      keep the root leaf page which has become empty
         */
        if (BT_IS_ROOT(fmp)) {
                /*
@@ -2269,7 +2266,7 @@ static int dtDeleteUp(tid_t tid, struct inode *ip,
        }
 
        /*
-        *      free the non-root leaf page
+        *      free the non-root leaf page
         */
        /*
         * acquire a transaction lock on the page
@@ -2299,7 +2296,7 @@ static int dtDeleteUp(tid_t tid, struct inode *ip,
        discard_metapage(fmp);
 
        /*
-        *      propagate page deletion up the directory tree
+        *      propagate page deletion up the directory tree
         *
         * If the delete from the parent page makes it empty,
         * continue all the way up the tree.
@@ -2440,10 +2437,10 @@ static int dtDeleteUp(tid_t tid, struct inode *ip,
 
 #ifdef _NOTYET
 /*
- * NAME:        dtRelocate()
+ * NAME:       dtRelocate()
  *
- * FUNCTION:    relocate dtpage (internal or leaf) of directory;
- *              This function is mainly used by defragfs utility.
+ * FUNCTION:   relocate dtpage (internal or leaf) of directory;
+ *             This function is mainly used by defragfs utility.
  */
 int dtRelocate(tid_t tid, struct inode *ip, s64 lmxaddr, pxd_t * opxd,
               s64 nxaddr)
@@ -2471,8 +2468,8 @@ int dtRelocate(tid_t tid, struct inode *ip, s64 lmxaddr, pxd_t * opxd,
                   xlen);
 
        /*
-        *      1. get the internal parent dtpage covering
-        *      router entry for the tartget page to be relocated;
+        *      1. get the internal parent dtpage covering
+        *      router entry for the tartget page to be relocated;
         */
        rc = dtSearchNode(ip, lmxaddr, opxd, &btstack);
        if (rc)
@@ -2483,7 +2480,7 @@ int dtRelocate(tid_t tid, struct inode *ip, s64 lmxaddr, pxd_t * opxd,
        jfs_info("dtRelocate: parent router entry validated.");
 
        /*
-        *      2. relocate the target dtpage
+        *      2. relocate the target dtpage
         */
        /* read in the target page from src extent */
        DT_GETPAGE(ip, oxaddr, mp, PSIZE, p, rc);
@@ -2581,9 +2578,7 @@ int dtRelocate(tid_t tid, struct inode *ip, s64 lmxaddr, pxd_t * opxd,
 
        /* update the buffer extent descriptor of the dtpage */
        xsize = xlen << JFS_SBI(ip->i_sb)->l2bsize;
-#ifdef _STILL_TO_PORT
-       bmSetXD(mp, nxaddr, xsize);
-#endif /* _STILL_TO_PORT */
+
        /* unpin the relocated page */
        DT_PUTPAGE(mp);
        jfs_info("dtRelocate: target dtpage relocated.");
@@ -2594,7 +2589,7 @@ int dtRelocate(tid_t tid, struct inode *ip, s64 lmxaddr, pxd_t * opxd,
         */
 
        /*
-        *      3. acquire maplock for the source extent to be freed;
+        *      3. acquire maplock for the source extent to be freed;
         */
        /* for dtpage relocation, write a LOG_NOREDOPAGE record
         * for the source dtpage (logredo() will init NoRedoPage
@@ -2609,7 +2604,7 @@ int dtRelocate(tid_t tid, struct inode *ip, s64 lmxaddr, pxd_t * opxd,
        pxdlock->index = 1;
 
        /*
-        *      4. update the parent router entry for relocation;
+        *      4. update the parent router entry for relocation;
         *
         * acquire tlck for the parent entry covering the target dtpage;
         * write LOG_REDOPAGE to apply after image only;
@@ -2637,7 +2632,7 @@ int dtRelocate(tid_t tid, struct inode *ip, s64 lmxaddr, pxd_t * opxd,
  * NAME:       dtSearchNode()
  *
  * FUNCTION:   Search for an dtpage containing a specified address
- *              This function is mainly used by defragfs utility.
+ *             This function is mainly used by defragfs utility.
  *
  * NOTE:       Search result on stack, the found page is pinned at exit.
  *             The result page must be an internal dtpage.
@@ -2660,7 +2655,7 @@ static int dtSearchNode(struct inode *ip, s64 lmxaddr, pxd_t * kpxd,
        BT_CLR(btstack);        /* reset stack */
 
        /*
-        *      descend tree to the level with specified leftmost page
+        *      descend tree to the level with specified leftmost page
         *
         *  by convention, root bn = 0.
         */
@@ -2699,7 +2694,7 @@ static int dtSearchNode(struct inode *ip, s64 lmxaddr, pxd_t * kpxd,
        }
 
        /*
-        *      search each page at the current levevl
+        *      search each page at the current levevl
         */
       loop:
        stbl = DT_GETSTBL(p);
@@ -3044,9 +3039,9 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
        if (DO_INDEX(ip)) {
                /*
                 * persistent index is stored in directory entries.
-                * Special cases:        0 = .
-                *                       1 = ..
-                *                      -1 = End of directory
+                * Special cases:        0 = .
+                *                       1 = ..
+                *                      -1 = End of directory
                 */
                do_index = 1;
 
@@ -3128,10 +3123,10 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
                /*
                 * Legacy filesystem - OS/2 & Linux JFS < 0.3.6
                 *
-                * pn = index = 0:      First entry "."
-                * pn = 0; index = 1:   Second entry ".."
-                * pn > 0:              Real entries, pn=1 -> leftmost page
-                * pn = index = -1:     No more entries
+                * pn = index = 0:      First entry "."
+                * pn = 0; index = 1:   Second entry ".."
+                * pn > 0:              Real entries, pn=1 -> leftmost page
+                * pn = index = -1:     No more entries
                 */
                dtpos = filp->f_pos;
                if (dtpos == 0) {
@@ -3351,7 +3346,7 @@ static int dtReadFirst(struct inode *ip, struct btstack * btstack)
        BT_CLR(btstack);        /* reset stack */
 
        /*
-        *      descend leftmost path of the tree
+        *      descend leftmost path of the tree
         *
         * by convention, root bn = 0.
         */
@@ -4531,7 +4526,7 @@ int dtModify(tid_t tid, struct inode *ip,
        struct ldtentry *entry;
 
        /*
-        *      search for the entry to modify:
+        *      search for the entry to modify:
         *
         * dtSearch() returns (leaf page pinned, index at which to modify).
         */
index af8513f78648336f8bda39c8e5c271b943a43535..8561c6ecece096648a7ea054d013686f58ab7fd1 100644 (file)
@@ -35,7 +35,7 @@ typedef union {
 
 
 /*
- *      entry segment/slot
+ *     entry segment/slot
  *
  * an entry consists of type dependent head/only segment/slot and
  * additional segments/slots linked vi next field;
index a35bdca6a805b81b2fe2bf4b379a27d55c02dd5f..7ae1e3281de938b85432417863aa341f7483af54 100644 (file)
@@ -34,8 +34,8 @@ static int extBrealloc(struct inode *, s64, s64, s64 *, s64 *);
 #endif
 static s64 extRoundDown(s64 nb);
 
-#define DPD(a)          (printk("(a): %d\n",(a)))
-#define DPC(a)          (printk("(a): %c\n",(a)))
+#define DPD(a)         (printk("(a): %d\n",(a)))
+#define DPC(a)         (printk("(a): %c\n",(a)))
 #define DPL1(a)                                        \
 {                                              \
        if ((a) >> 32)                          \
@@ -51,19 +51,19 @@ static s64 extRoundDown(s64 nb);
                printk("(a): %x\n",(a) << 32);  \
 }
 
-#define DPD1(a)         (printk("(a): %d  ",(a)))
-#define DPX(a)          (printk("(a): %08x\n",(a)))
-#define DPX1(a)         (printk("(a): %08x  ",(a)))
-#define DPS(a)          (printk("%s\n",(a)))
-#define DPE(a)          (printk("\nENTERING: %s\n",(a)))
-#define DPE1(a)          (printk("\nENTERING: %s",(a)))
-#define DPS1(a)         (printk("  %s  ",(a)))
+#define DPD1(a)                (printk("(a): %d  ",(a)))
+#define DPX(a)         (printk("(a): %08x\n",(a)))
+#define DPX1(a)                (printk("(a): %08x  ",(a)))
+#define DPS(a)         (printk("%s\n",(a)))
+#define DPE(a)         (printk("\nENTERING: %s\n",(a)))
+#define DPE1(a)                (printk("\nENTERING: %s",(a)))
+#define DPS1(a)                (printk("  %s  ",(a)))
 
 
 /*
  * NAME:       extAlloc()
  *
- * FUNCTION:    allocate an extent for a specified page range within a
+ * FUNCTION:   allocate an extent for a specified page range within a
  *             file.
  *
  * PARAMETERS:
@@ -78,9 +78,9 @@ static s64 extRoundDown(s64 nb);
  *               should be marked as allocated but not recorded.
  *
  * RETURN VALUES:
- *      0       - success
- *      -EIO   - i/o error.
- *      -ENOSPC        - insufficient disk resources.
+ *     0       - success
+ *     -EIO    - i/o error.
+ *     -ENOSPC - insufficient disk resources.
  */
 int
 extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, bool abnr)
@@ -192,9 +192,9 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, bool abnr)
 
 #ifdef _NOTYET
 /*
- * NAME:        extRealloc()
+ * NAME:       extRealloc()
  *
- * FUNCTION:    extend the allocation of a file extent containing a
+ * FUNCTION:   extend the allocation of a file extent containing a
  *             partial back last page.
  *
  * PARAMETERS:
@@ -207,9 +207,9 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, bool abnr)
  *               should be marked as allocated but not recorded.
  *
  * RETURN VALUES:
- *      0       - success
- *      -EIO   - i/o error.
- *      -ENOSPC        - insufficient disk resources.
+ *     0       - success
+ *     -EIO    - i/o error.
+ *     -ENOSPC - insufficient disk resources.
  */
 int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, bool abnr)
 {
@@ -345,9 +345,9 @@ exit:
 
 
 /*
- * NAME:        extHint()
+ * NAME:       extHint()
  *
- * FUNCTION:    produce an extent allocation hint for a file offset.
+ * FUNCTION:   produce an extent allocation hint for a file offset.
  *
  * PARAMETERS:
  *     ip      - the inode of the file.
@@ -356,8 +356,8 @@ exit:
  *               the hint.
  *
  * RETURN VALUES:
- *      0       - success
- *      -EIO   - i/o error.
+ *     0       - success
+ *     -EIO    - i/o error.
  */
 int extHint(struct inode *ip, s64 offset, xad_t * xp)
 {
@@ -387,7 +387,7 @@ int extHint(struct inode *ip, s64 offset, xad_t * xp)
        lxdl.nlxd = 1;
        lxdl.lxd = &lxd;
        LXDoffset(&lxd, prev)
-           LXDlength(&lxd, nbperpage);
+       LXDlength(&lxd, nbperpage);
 
        xadl.maxnxad = 1;
        xadl.nxad = 0;
@@ -397,11 +397,11 @@ int extHint(struct inode *ip, s64 offset, xad_t * xp)
        if ((rc = xtLookupList(ip, &lxdl, &xadl, 0)))
                return (rc);
 
-       /* check if not extent exists for the previous page.
+       /* check if no extent exists for the previous page.
         * this is possible for sparse files.
         */
        if (xadl.nxad == 0) {
-//              assert(ISSPARSE(ip));
+//             assert(ISSPARSE(ip));
                return (0);
        }
 
@@ -410,28 +410,28 @@ int extHint(struct inode *ip, s64 offset, xad_t * xp)
         */
        xp->flag &= XAD_NOTRECORDED;
 
-        if(xadl.nxad != 1 || lengthXAD(xp) != nbperpage) {
+       if(xadl.nxad != 1 || lengthXAD(xp) != nbperpage) {
                jfs_error(ip->i_sb, "extHint: corrupt xtree");
                return -EIO;
-        }
+       }
 
        return (0);
 }
 
 
 /*
- * NAME:        extRecord()
+ * NAME:       extRecord()
  *
- * FUNCTION:    change a page with a file from not recorded to recorded.
+ * FUNCTION:   change a page with a file from not recorded to recorded.
  *
  * PARAMETERS:
  *     ip      - inode of the file.
  *     cp      - cbuf of the file page.
  *
  * RETURN VALUES:
- *      0       - success
- *      -EIO   - i/o error.
- *      -ENOSPC        - insufficient disk resources.
+ *     0       - success
+ *     -EIO    - i/o error.
+ *     -ENOSPC - insufficient disk resources.
  */
 int extRecord(struct inode *ip, xad_t * xp)
 {
@@ -451,9 +451,9 @@ int extRecord(struct inode *ip, xad_t * xp)
 
 #ifdef _NOTYET
 /*
- * NAME:        extFill()
+ * NAME:       extFill()
  *
- * FUNCTION:    allocate disk space for a file page that represents
+ * FUNCTION:   allocate disk space for a file page that represents
  *             a file hole.
  *
  * PARAMETERS:
@@ -461,16 +461,16 @@ int extRecord(struct inode *ip, xad_t * xp)
  *     cp      - cbuf of the file page represent the hole.
  *
  * RETURN VALUES:
- *      0       - success
- *      -EIO   - i/o error.
- *      -ENOSPC        - insufficient disk resources.
+ *     0       - success
+ *     -EIO    - i/o error.
+ *     -ENOSPC - insufficient disk resources.
  */
 int extFill(struct inode *ip, xad_t * xp)
 {
        int rc, nbperpage = JFS_SBI(ip->i_sb)->nbperpage;
        s64 blkno = offsetXAD(xp) >> ip->i_blkbits;
 
-//      assert(ISSPARSE(ip));
+//     assert(ISSPARSE(ip));
 
        /* initialize the extent allocation hint */
        XADaddress(xp, 0);
@@ -489,7 +489,7 @@ int extFill(struct inode *ip, xad_t * xp)
 /*
  * NAME:       extBalloc()
  *
- * FUNCTION:    allocate disk blocks to form an extent.
+ * FUNCTION:   allocate disk blocks to form an extent.
  *
  *             initially, we will try to allocate disk blocks for the
  *             requested size (nblocks).  if this fails (nblocks
@@ -513,9 +513,9 @@ int extFill(struct inode *ip, xad_t * xp)
  *                allocated block range.
  *
  * RETURN VALUES:
- *      0       - success
- *      -EIO   - i/o error.
- *      -ENOSPC        - insufficient disk resources.
+ *     0       - success
+ *     -EIO    - i/o error.
+ *     -ENOSPC - insufficient disk resources.
  */
 static int
 extBalloc(struct inode *ip, s64 hint, s64 * nblocks, s64 * blkno)
@@ -580,7 +580,7 @@ extBalloc(struct inode *ip, s64 hint, s64 * nblocks, s64 * blkno)
 /*
  * NAME:       extBrealloc()
  *
- * FUNCTION:    attempt to extend an extent's allocation.
+ * FUNCTION:   attempt to extend an extent's allocation.
  *
  *             Initially, we will try to extend the extent's allocation
  *             in place.  If this fails, we'll try to move the extent
@@ -597,8 +597,8 @@ extBalloc(struct inode *ip, s64 hint, s64 * nblocks, s64 * blkno)
  *
  * PARAMETERS:
  *     ip       - the inode of the file.
- *     blkno    - starting block number of the extents current allocation.
- *     nblks    - number of blocks within the extents current allocation.
+ *     blkno    - starting block number of the extents current allocation.
+ *     nblks    - number of blocks within the extents current allocation.
  *     newnblks - pointer to a s64 value.  on entry, this value is the
  *                the new desired extent size (number of blocks).  on
  *                successful exit, this value is set to the extent's actual
@@ -606,9 +606,9 @@ extBalloc(struct inode *ip, s64 hint, s64 * nblocks, s64 * blkno)
  *     newblkno - the starting block number of the extents new allocation.
  *
  * RETURN VALUES:
- *      0       - success
- *      -EIO   - i/o error.
- *      -ENOSPC        - insufficient disk resources.
+ *     0       - success
+ *     -EIO    - i/o error.
+ *     -ENOSPC - insufficient disk resources.
  */
 static int
 extBrealloc(struct inode *ip,
@@ -634,16 +634,16 @@ extBrealloc(struct inode *ip,
 
 
 /*
- * NAME:        extRoundDown()
+ * NAME:       extRoundDown()
  *
- * FUNCTION:    round down a specified number of blocks to the next
+ * FUNCTION:   round down a specified number of blocks to the next
  *             smallest power of 2 number.
  *
  * PARAMETERS:
  *     nb      - the inode of the file.
  *
  * RETURN VALUES:
- *      next smallest power of 2 number.
+ *     next smallest power of 2 number.
  */
 static s64 extRoundDown(s64 nb)
 {
index 38f70ac03becfacda7fff453c58d750f1df4f861..b3f5463fbe5233a4c5cd45a411bf10bea3843d4a 100644 (file)
@@ -34,9 +34,9 @@
 #define JFS_UNICODE    0x00000001      /* unicode name */
 
 /* mount time flags for error handling */
-#define JFS_ERR_REMOUNT_RO 0x00000002   /* remount read-only */
-#define JFS_ERR_CONTINUE   0x00000004   /* continue */
-#define JFS_ERR_PANIC      0x00000008   /* panic */
+#define JFS_ERR_REMOUNT_RO 0x00000002  /* remount read-only */
+#define JFS_ERR_CONTINUE   0x00000004  /* continue */
+#define JFS_ERR_PANIC      0x00000008  /* panic */
 
 /* Quota support */
 #define        JFS_USRQUOTA    0x00000010
@@ -83,7 +83,6 @@
 /*     case-insensitive name/directory support */
 
 #define JFS_AIX                0x80000000      /* AIX support */
-/*     POSIX name/directory  support - Never implemented*/
 
 /*
  *     buffer cache configuration
 #define IDATASIZE      256     /* inode inline data size */
 #define        IXATTRSIZE      128     /* inode inline extended attribute size */
 
-#define XTPAGE_SIZE     4096
-#define log2_PAGESIZE     12
+#define XTPAGE_SIZE    4096
+#define log2_PAGESIZE  12
 
-#define IAG_SIZE        4096
+#define IAG_SIZE       4096
 #define IAG_EXTENT_SIZE 4096
 #define        INOSPERIAG      4096    /* number of disk inodes per iag */
 #define        L2INOSPERIAG    12      /* l2 number of disk inodes per iag */
index c6530227cda66d10b2e18816c419a8f391b0a764..3870ba8b9086b8f2c1c481eaf6a1eb2c79497238 100644 (file)
@@ -93,21 +93,21 @@ static int copy_from_dinode(struct dinode *, struct inode *);
 static void copy_to_dinode(struct dinode *, struct inode *);
 
 /*
- * NAME:        diMount()
+ * NAME:       diMount()
  *
- * FUNCTION:    initialize the incore inode map control structures for
+ * FUNCTION:   initialize the incore inode map control structures for
  *             a fileset or aggregate init time.
  *
- *              the inode map's control structure (dinomap) is
- *              brought in from disk and placed in virtual memory.
+ *             the inode map's control structure (dinomap) is
+ *             brought in from disk and placed in virtual memory.
  *
  * PARAMETERS:
- *      ipimap  - pointer to inode map inode for the aggregate or fileset.
+ *     ipimap  - pointer to inode map inode for the aggregate or fileset.
  *
  * RETURN VALUES:
- *      0       - success
- *      -ENOMEM  - insufficient free virtual memory.
- *      -EIO   - i/o error.
+ *     0       - success
+ *     -ENOMEM - insufficient free virtual memory.
+ *     -EIO    - i/o error.
  */
 int diMount(struct inode *ipimap)
 {
@@ -180,18 +180,18 @@ int diMount(struct inode *ipimap)
 
 
 /*
- * NAME:        diUnmount()
+ * NAME:       diUnmount()
  *
- * FUNCTION:    write to disk the incore inode map control structures for
+ * FUNCTION:   write to disk the incore inode map control structures for
  *             a fileset or aggregate at unmount time.
  *
  * PARAMETERS:
- *      ipimap  - pointer to inode map inode for the aggregate or fileset.
+ *     ipimap  - pointer to inode map inode for the aggregate or fileset.
  *
  * RETURN VALUES:
- *      0       - success
- *      -ENOMEM  - insufficient free virtual memory.
- *      -EIO   - i/o error.
+ *     0       - success
+ *     -ENOMEM - insufficient free virtual memory.
+ *     -EIO    - i/o error.
  */
 int diUnmount(struct inode *ipimap, int mounterror)
 {
@@ -274,9 +274,9 @@ int diSync(struct inode *ipimap)
 
 
 /*
- * NAME:        diRead()
+ * NAME:       diRead()
  *
- * FUNCTION:    initialize an incore inode from disk.
+ * FUNCTION:   initialize an incore inode from disk.
  *
  *             on entry, the specifed incore inode should itself
  *             specify the disk inode number corresponding to the
@@ -285,7 +285,7 @@ int diSync(struct inode *ipimap)
  *             this routine handles incore inode initialization for
  *             both "special" and "regular" inodes.  special inodes
  *             are those required early in the mount process and
- *             require special handling since much of the file system
+ *             require special handling since much of the file system
  *             is not yet initialized.  these "special" inodes are
  *             identified by a NULL inode map inode pointer and are
  *             actually initialized by a call to diReadSpecial().
@@ -298,12 +298,12 @@ int diSync(struct inode *ipimap)
  *             incore inode.
  *
  * PARAMETERS:
- *      ip  -  pointer to incore inode to be initialized from disk.
+ *     ip      -  pointer to incore inode to be initialized from disk.
  *
  * RETURN VALUES:
- *      0       - success
- *      -EIO   - i/o error.
- *      -ENOMEM        - insufficient memory
+ *     0       - success
+ *     -EIO    - i/o error.
+ *     -ENOMEM - insufficient memory
  *
  */
 int diRead(struct inode *ip)
@@ -410,26 +410,26 @@ int diRead(struct inode *ip)
 
 
 /*
- * NAME:        diReadSpecial()
+ * NAME:       diReadSpecial()
  *
- * FUNCTION:    initialize a 'special' inode from disk.
+ * FUNCTION:   initialize a 'special' inode from disk.
  *
  *             this routines handles aggregate level inodes.  The
  *             inode cache cannot differentiate between the
  *             aggregate inodes and the filesystem inodes, so we
  *             handle these here.  We don't actually use the aggregate
- *             inode map, since these inodes are at a fixed location
+ *             inode map, since these inodes are at a fixed location
  *             and in some cases the aggregate inode map isn't initialized
  *             yet.
  *
  * PARAMETERS:
- *      sb - filesystem superblock
+ *     sb - filesystem superblock
  *     inum - aggregate inode number
  *     secondary - 1 if secondary aggregate inode table
  *
  * RETURN VALUES:
- *      new inode      - success
- *      NULL           - i/o error.
+ *     new inode       - success
+ *     NULL            - i/o error.
  */
 struct inode *diReadSpecial(struct super_block *sb, ino_t inum, int secondary)
 {
@@ -502,12 +502,12 @@ struct inode *diReadSpecial(struct super_block *sb, ino_t inum, int secondary)
 }
 
 /*
- * NAME:        diWriteSpecial()
+ * NAME:       diWriteSpecial()
  *
- * FUNCTION:    Write the special inode to disk
+ * FUNCTION:   Write the special inode to disk
  *
  * PARAMETERS:
- *      ip - special inode
+ *     ip - special inode
  *     secondary - 1 if secondary aggregate inode table
  *
  * RETURN VALUES: none
@@ -554,9 +554,9 @@ void diWriteSpecial(struct inode *ip, int secondary)
 }
 
 /*
- * NAME:        diFreeSpecial()
+ * NAME:       diFreeSpecial()
  *
- * FUNCTION:    Free allocated space for special inode
+ * FUNCTION:   Free allocated space for special inode
  */
 void diFreeSpecial(struct inode *ip)
 {
@@ -572,9 +572,9 @@ void diFreeSpecial(struct inode *ip)
 
 
 /*
- * NAME:        diWrite()
+ * NAME:       diWrite()
  *
- * FUNCTION:    write the on-disk inode portion of the in-memory inode
+ * FUNCTION:   write the on-disk inode portion of the in-memory inode
  *             to its corresponding on-disk inode.
  *
  *             on entry, the specifed incore inode should itself
@@ -589,11 +589,11 @@ void diFreeSpecial(struct inode *ip)
  *
  * PARAMETERS:
  *     tid -  transacation id
- *      ip  -  pointer to incore inode to be written to the inode extent.
+ *     ip  -  pointer to incore inode to be written to the inode extent.
  *
  * RETURN VALUES:
- *      0       - success
- *      -EIO   - i/o error.
+ *     0       - success
+ *     -EIO    - i/o error.
  */
 int diWrite(tid_t tid, struct inode *ip)
 {
@@ -730,7 +730,7 @@ int diWrite(tid_t tid, struct inode *ip)
        ilinelock = (struct linelock *) & tlck->lock;
 
        /*
-        *      regular file: 16 byte (XAD slot) granularity
+        *      regular file: 16 byte (XAD slot) granularity
         */
        if (type & tlckXTREE) {
                xtpage_t *p, *xp;
@@ -755,7 +755,7 @@ int diWrite(tid_t tid, struct inode *ip)
                                xad->flag &= ~(XAD_NEW | XAD_EXTENDED);
        }
        /*
-        *      directory: 32 byte (directory entry slot) granularity
+        *      directory: 32 byte (directory entry slot) granularity
         */
        else if (type & tlckDTREE) {
                dtpage_t *p, *xp;
@@ -800,9 +800,8 @@ int diWrite(tid_t tid, struct inode *ip)
        }
 
        /*
-        *      lock/copy inode base: 128 byte slot granularity
+        *      lock/copy inode base: 128 byte slot granularity
         */
-// baseDinode:
        lv = & dilinelock->lv[dilinelock->index];
        lv->offset = dioffset >> L2INODESLOTSIZE;
        copy_to_dinode(dp, ip);
@@ -813,17 +812,6 @@ int diWrite(tid_t tid, struct inode *ip)
                lv->length = 1;
        dilinelock->index++;
 
-#ifdef _JFS_FASTDASD
-       /*
-        * We aren't logging changes to the DASD used in directory inodes,
-        * but we need to write them to disk.  If we don't unmount cleanly,
-        * mount will recalculate the DASD used.
-        */
-       if (S_ISDIR(ip->i_mode)
-           && (ip->i_ipmnt->i_mntflag & JFS_DASD_ENABLED))
-               memcpy(&dp->di_DASD, &ip->i_DASD, sizeof(struct dasd));
-#endif                         /*  _JFS_FASTDASD */
-
        /* release the buffer holding the updated on-disk inode.
         * the buffer will be later written by commit processing.
         */
@@ -834,9 +822,9 @@ int diWrite(tid_t tid, struct inode *ip)
 
 
 /*
- * NAME:        diFree(ip)
+ * NAME:       diFree(ip)
  *
- * FUNCTION:    free a specified inode from the inode working map
+ * FUNCTION:   free a specified inode from the inode working map
  *             for a fileset or aggregate.
  *
  *             if the inode to be freed represents the first (only)
@@ -865,11 +853,11 @@ int diWrite(tid_t tid, struct inode *ip)
  *             any updates and are held until all updates are complete.
  *
  * PARAMETERS:
- *      ip     - inode to be freed.
+ *     ip      - inode to be freed.
  *
  * RETURN VALUES:
- *      0       - success
- *      -EIO   - i/o error.
+ *     0       - success
+ *     -EIO    - i/o error.
  */
 int diFree(struct inode *ip)
 {
@@ -902,7 +890,8 @@ int diFree(struct inode *ip)
         * the map.
         */
        if (iagno >= imap->im_nextiag) {
-               dump_mem("imap", imap, 32);
+               print_hex_dump(KERN_ERR, "imap: ", DUMP_PREFIX_ADDRESS, 16, 4,
+                              imap, 32, 0);
                jfs_error(ip->i_sb,
                          "diFree: inum = %d, iagno = %d, nextiag = %d",
                          (uint) inum, iagno, imap->im_nextiag);
@@ -964,8 +953,8 @@ int diFree(struct inode *ip)
                return -EIO;
        }
        /*
-        *      inode extent still has some inodes or below low water mark:
-        *      keep the inode extent;
+        *      inode extent still has some inodes or below low water mark:
+        *      keep the inode extent;
         */
        if (bitmap ||
            imap->im_agctl[agno].numfree < 96 ||
@@ -1047,12 +1036,12 @@ int diFree(struct inode *ip)
 
 
        /*
-        *      inode extent has become free and above low water mark:
-        *      free the inode extent;
+        *      inode extent has become free and above low water mark:
+        *      free the inode extent;
         */
 
        /*
-        *      prepare to update iag list(s) (careful update step 1)
+        *      prepare to update iag list(s) (careful update step 1)
         */
        amp = bmp = cmp = dmp = NULL;
        fwd = back = -1;
@@ -1152,7 +1141,7 @@ int diFree(struct inode *ip)
        invalidate_pxd_metapages(ip, freepxd);
 
        /*
-        *      update iag list(s) (careful update step 2)
+        *      update iag list(s) (careful update step 2)
         */
        /* add the iag to the ag extent free list if this is the
         * first free extent for the iag.
@@ -1338,20 +1327,20 @@ diInitInode(struct inode *ip, int iagno, int ino, int extno, struct iag * iagp)
 
 
 /*
- * NAME:        diAlloc(pip,dir,ip)
+ * NAME:       diAlloc(pip,dir,ip)
  *
- * FUNCTION:    allocate a disk inode from the inode working map
+ * FUNCTION:   allocate a disk inode from the inode working map
  *             for a fileset or aggregate.
  *
  * PARAMETERS:
- *      pip    - pointer to incore inode for the parent inode.
- *      dir    - 'true' if the new disk inode is for a directory.
- *      ip     - pointer to a new inode
+ *     pip     - pointer to incore inode for the parent inode.
+ *     dir     - 'true' if the new disk inode is for a directory.
+ *     ip      - pointer to a new inode
  *
  * RETURN VALUES:
- *      0       - success.
- *      -ENOSPC        - insufficient disk resources.
- *      -EIO   - i/o error.
+ *     0       - success.
+ *     -ENOSPC - insufficient disk resources.
+ *     -EIO    - i/o error.
  */
 int diAlloc(struct inode *pip, bool dir, struct inode *ip)
 {
@@ -1433,7 +1422,7 @@ int diAlloc(struct inode *pip, bool dir, struct inode *ip)
        addext = (imap->im_agctl[agno].numfree < 32 && iagp->nfreeexts);
 
        /*
-        *      try to allocate from the IAG
+        *      try to allocate from the IAG
         */
        /* check if the inode may be allocated from the iag
         * (i.e. the inode has free inodes or new extent can be added).
@@ -1633,9 +1622,9 @@ int diAlloc(struct inode *pip, bool dir, struct inode *ip)
 
 
 /*
- * NAME:        diAllocAG(imap,agno,dir,ip)
+ * NAME:       diAllocAG(imap,agno,dir,ip)
  *
- * FUNCTION:    allocate a disk inode from the allocation group.
+ * FUNCTION:   allocate a disk inode from the allocation group.
  *
  *             this routine first determines if a new extent of free
  *             inodes should be added for the allocation group, with
@@ -1649,17 +1638,17 @@ int diAlloc(struct inode *pip, bool dir, struct inode *ip)
  * PRE CONDITION: Already have the AG lock for this AG.
  *
  * PARAMETERS:
- *      imap   - pointer to inode map control structure.
- *      agno   - allocation group to allocate from.
- *      dir    - 'true' if the new disk inode is for a directory.
- *      ip     - pointer to the new inode to be filled in on successful return
+ *     imap    - pointer to inode map control structure.
+ *     agno    - allocation group to allocate from.
+ *     dir     - 'true' if the new disk inode is for a directory.
+ *     ip      - pointer to the new inode to be filled in on successful return
  *               with the disk inode number allocated, its extent address
  *               and the start of the ag.
  *
  * RETURN VALUES:
- *      0       - success.
- *      -ENOSPC        - insufficient disk resources.
- *      -EIO   - i/o error.
+ *     0       - success.
+ *     -ENOSPC - insufficient disk resources.
+ *     -EIO    - i/o error.
  */
 static int
 diAllocAG(struct inomap * imap, int agno, bool dir, struct inode *ip)
@@ -1709,9 +1698,9 @@ diAllocAG(struct inomap * imap, int agno, bool dir, struct inode *ip)
 
 
 /*
- * NAME:        diAllocAny(imap,agno,dir,iap)
+ * NAME:       diAllocAny(imap,agno,dir,iap)
  *
- * FUNCTION:    allocate a disk inode from any other allocation group.
+ * FUNCTION:   allocate a disk inode from any other allocation group.
  *
  *             this routine is called when an allocation attempt within
  *             the primary allocation group has failed. if attempts to
@@ -1719,17 +1708,17 @@ diAllocAG(struct inomap * imap, int agno, bool dir, struct inode *ip)
  *             specified primary group.
  *
  * PARAMETERS:
- *      imap   - pointer to inode map control structure.
- *      agno   - primary allocation group (to avoid).
- *      dir    - 'true' if the new disk inode is for a directory.
- *      ip     - pointer to a new inode to be filled in on successful return
+ *     imap    - pointer to inode map control structure.
+ *     agno    - primary allocation group (to avoid).
+ *     dir     - 'true' if the new disk inode is for a directory.
+ *     ip      - pointer to a new inode to be filled in on successful return
  *               with the disk inode number allocated, its extent address
  *               and the start of the ag.
  *
  * RETURN VALUES:
- *      0       - success.
- *      -ENOSPC        - insufficient disk resources.
- *      -EIO   - i/o error.
+ *     0       - success.
+ *     -ENOSPC - insufficient disk resources.
+ *     -EIO    - i/o error.
  */
 static int
 diAllocAny(struct inomap * imap, int agno, bool dir, struct inode *ip)
@@ -1772,9 +1761,9 @@ diAllocAny(struct inomap * imap, int agno, bool dir, struct inode *ip)
 
 
 /*
- * NAME:        diAllocIno(imap,agno,ip)
+ * NAME:       diAllocIno(imap,agno,ip)
  *
- * FUNCTION:    allocate a disk inode from the allocation group's free
+ * FUNCTION:   allocate a disk inode from the allocation group's free
  *             inode list, returning an error if this free list is
  *             empty (i.e. no iags on the list).
  *
@@ -1785,16 +1774,16 @@ diAllocAny(struct inomap * imap, int agno, bool dir, struct inode *ip)
  * PRE CONDITION: Already have AG lock for this AG.
  *
  * PARAMETERS:
- *      imap   - pointer to inode map control structure.
- *      agno   - allocation group.
- *      ip     - pointer to new inode to be filled in on successful return
+ *     imap    - pointer to inode map control structure.
+ *     agno    - allocation group.
+ *     ip      - pointer to new inode to be filled in on successful return
  *               with the disk inode number allocated, its extent address
  *               and the start of the ag.
  *
  * RETURN VALUES:
- *      0       - success.
- *      -ENOSPC        - insufficient disk resources.
- *      -EIO   - i/o error.
+ *     0       - success.
+ *     -ENOSPC - insufficient disk resources.
+ *     -EIO    - i/o error.
  */
 static int diAllocIno(struct inomap * imap, int agno, struct inode *ip)
 {
@@ -1890,7 +1879,7 @@ static int diAllocIno(struct inomap * imap, int agno, struct inode *ip)
 
 
 /*
- * NAME:        diAllocExt(imap,agno,ip)
+ * NAME:       diAllocExt(imap,agno,ip)
  *
  * FUNCTION:   add a new extent of free inodes to an iag, allocating
  *             an inode from this extent to satisfy the current allocation
@@ -1910,16 +1899,16 @@ static int diAllocIno(struct inomap * imap, int agno, struct inode *ip)
  *             for the purpose of satisfying this request.
  *
  * PARAMETERS:
- *      imap   - pointer to inode map control structure.
- *      agno   - allocation group number.
- *      ip     - pointer to new inode to be filled in on successful return
+ *     imap    - pointer to inode map control structure.
+ *     agno    - allocation group number.
+ *     ip      - pointer to new inode to be filled in on successful return
  *               with the disk inode number allocated, its extent address
  *               and the start of the ag.
  *
  * RETURN VALUES:
- *      0       - success.
- *      -ENOSPC        - insufficient disk resources.
- *      -EIO   - i/o error.
+ *     0       - success.
+ *     -ENOSPC - insufficient disk resources.
+ *     -EIO    - i/o error.
  */
 static int diAllocExt(struct inomap * imap, int agno, struct inode *ip)
 {
@@ -2010,7 +1999,7 @@ static int diAllocExt(struct inomap * imap, int agno, struct inode *ip)
 
 
 /*
- * NAME:        diAllocBit(imap,iagp,ino)
+ * NAME:       diAllocBit(imap,iagp,ino)
  *
  * FUNCTION:   allocate a backed inode from an iag.
  *
@@ -2030,14 +2019,14 @@ static int diAllocExt(struct inomap * imap, int agno, struct inode *ip)
  *     this AG.  Must have read lock on imap inode.
  *
  * PARAMETERS:
- *      imap   - pointer to inode map control structure.
- *      iagp   - pointer to iag.
- *      ino    - inode number to be allocated within the iag.
+ *     imap    - pointer to inode map control structure.
+ *     iagp    - pointer to iag.
+ *     ino     - inode number to be allocated within the iag.
  *
  * RETURN VALUES:
- *      0       - success.
- *      -ENOSPC        - insufficient disk resources.
- *      -EIO   - i/o error.
+ *     0       - success.
+ *     -ENOSPC - insufficient disk resources.
+ *     -EIO    - i/o error.
  */
 static int diAllocBit(struct inomap * imap, struct iag * iagp, int ino)
 {
@@ -2144,11 +2133,11 @@ static int diAllocBit(struct inomap * imap, struct iag * iagp, int ino)
 
 
 /*
- * NAME:        diNewExt(imap,iagp,extno)
+ * NAME:       diNewExt(imap,iagp,extno)
  *
- * FUNCTION:    initialize a new extent of inodes for an iag, allocating
- *             the first inode of the extent for use for the current
- *             allocation request.
+ * FUNCTION:   initialize a new extent of inodes for an iag, allocating
+ *             the first inode of the extent for use for the current
+ *             allocation request.
  *
  *             disk resources are allocated for the new extent of inodes
  *             and the inodes themselves are initialized to reflect their
@@ -2177,14 +2166,14 @@ static int diAllocBit(struct inomap * imap, struct iag * iagp, int ino)
  *     this AG.  Must have read lock on imap inode.
  *
  * PARAMETERS:
- *      imap   - pointer to inode map control structure.
- *      iagp   - pointer to iag.
- *      extno  - extent number.
+ *     imap    - pointer to inode map control structure.
+ *     iagp    - pointer to iag.
+ *     extno   - extent number.
  *
  * RETURN VALUES:
- *      0       - success.
- *      -ENOSPC        - insufficient disk resources.
- *      -EIO   - i/o error.
+ *     0       - success.
+ *     -ENOSPC - insufficient disk resources.
+ *     -EIO    - i/o error.
  */
 static int diNewExt(struct inomap * imap, struct iag * iagp, int extno)
 {
@@ -2430,7 +2419,7 @@ static int diNewExt(struct inomap * imap, struct iag * iagp, int extno)
 
 
 /*
- * NAME:        diNewIAG(imap,iagnop,agno)
+ * NAME:       diNewIAG(imap,iagnop,agno)
  *
  * FUNCTION:   allocate a new iag for an allocation group.
  *
@@ -2443,16 +2432,16 @@ static int diNewExt(struct inomap * imap, struct iag * iagp, int extno)
  *             and returned to satisfy the request.
  *
  * PARAMETERS:
- *      imap   - pointer to inode map control structure.
- *      iagnop - pointer to an iag number set with the number of the
+ *     imap    - pointer to inode map control structure.
+ *     iagnop  - pointer to an iag number set with the number of the
  *               newly allocated iag upon successful return.
- *      agno   - allocation group number.
+ *     agno    - allocation group number.
  *     bpp     - Buffer pointer to be filled in with new IAG's buffer
  *
  * RETURN VALUES:
- *      0       - success.
- *      -ENOSPC        - insufficient disk resources.
- *      -EIO   - i/o error.
+ *     0       - success.
+ *     -ENOSPC - insufficient disk resources.
+ *     -EIO    - i/o error.
  *
  * serialization:
  *     AG lock held on entry/exit;
@@ -2461,7 +2450,7 @@ static int diNewExt(struct inomap * imap, struct iag * iagp, int extno)
  *
  * note: new iag transaction:
  * . synchronously write iag;
- * . write log of xtree and inode  of imap;
+ * . write log of xtree and inode of imap;
  * . commit;
  * . synchronous write of xtree (right to left, bottom to top);
  * . at start of logredo(): init in-memory imap with one additional iag page;
@@ -2481,9 +2470,6 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp)
        s64 xaddr = 0;
        s64 blkno;
        tid_t tid;
-#ifdef _STILL_TO_PORT
-       xad_t xad;
-#endif                         /*  _STILL_TO_PORT */
        struct inode *iplist[1];
 
        /* pick up pointers to the inode map and mount inodes */
@@ -2674,15 +2660,15 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp)
 }
 
 /*
- * NAME:        diIAGRead()
+ * NAME:       diIAGRead()
  *
- * FUNCTION:    get the buffer for the specified iag within a fileset
+ * FUNCTION:   get the buffer for the specified iag within a fileset
  *             or aggregate inode map.
  *
  * PARAMETERS:
- *      imap   - pointer to inode map control structure.
- *      iagno  - iag number.
- *      bpp    - point to buffer pointer to be filled in on successful
+ *     imap    - pointer to inode map control structure.
+ *     iagno   - iag number.
+ *     bpp     - point to buffer pointer to be filled in on successful
  *               exit.
  *
  * SERIALIZATION:
@@ -2691,8 +2677,8 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp)
  *      the read lock is unnecessary.)
  *
  * RETURN VALUES:
- *      0       - success.
- *      -EIO   - i/o error.
+ *     0       - success.
+ *     -EIO    - i/o error.
  */
 static int diIAGRead(struct inomap * imap, int iagno, struct metapage ** mpp)
 {
@@ -2712,17 +2698,17 @@ static int diIAGRead(struct inomap * imap, int iagno, struct metapage ** mpp)
 }
 
 /*
- * NAME:        diFindFree()
+ * NAME:       diFindFree()
  *
- * FUNCTION:    find the first free bit in a word starting at
+ * FUNCTION:   find the first free bit in a word starting at
  *             the specified bit position.
  *
  * PARAMETERS:
- *      word   - word to be examined.
- *      start  - starting bit position.
+ *     word    - word to be examined.
+ *     start   - starting bit position.
  *
  * RETURN VALUES:
- *      bit position of first free bit in the word or 32 if
+ *     bit position of first free bit in the word or 32 if
  *     no free bits were found.
  */
 static int diFindFree(u32 word, int start)
@@ -2897,7 +2883,7 @@ int diExtendFS(struct inode *ipimap, struct inode *ipbmap)
                   atomic_read(&imap->im_numfree));
 
        /*
-        *      reconstruct imap
+        *      reconstruct imap
         *
         * coalesce contiguous k (newAGSize/oldAGSize) AGs;
         * i.e., (AGi, ..., AGj) where i = k*n and j = k*(n+1) - 1 to AGn;
@@ -2913,7 +2899,7 @@ int diExtendFS(struct inode *ipimap, struct inode *ipbmap)
        }
 
        /*
-        *      process each iag page of the map.
+        *      process each iag page of the map.
         *
         * rebuild AG Free Inode List, AG Free Inode Extent List;
         */
@@ -2932,7 +2918,7 @@ int diExtendFS(struct inode *ipimap, struct inode *ipbmap)
 
                /* leave free iag in the free iag list */
                if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) {
-                       release_metapage(bp);
+                       release_metapage(bp);
                        continue;
                }
 
@@ -3063,13 +3049,13 @@ static void duplicateIXtree(struct super_block *sb, s64 blkno,
 }
 
 /*
- * NAME:        copy_from_dinode()
+ * NAME:       copy_from_dinode()
  *
- * FUNCTION:    Copies inode info from disk inode to in-memory inode
+ * FUNCTION:   Copies inode info from disk inode to in-memory inode
  *
  * RETURN VALUES:
- *      0       - success
- *      -ENOMEM        - insufficient memory
+ *     0       - success
+ *     -ENOMEM - insufficient memory
  */
 static int copy_from_dinode(struct dinode * dip, struct inode *ip)
 {
@@ -3151,9 +3137,9 @@ static int copy_from_dinode(struct dinode * dip, struct inode *ip)
 }
 
 /*
- * NAME:        copy_to_dinode()
+ * NAME:       copy_to_dinode()
  *
- * FUNCTION:    Copies inode info from in-memory inode to disk inode
+ * FUNCTION:   Copies inode info from in-memory inode to disk inode
  */
 static void copy_to_dinode(struct dinode * dip, struct inode *ip)
 {
index 4f9c346ed49868eaa6f9546a3be6299bdac0c294..610a0e9d8941ad955e9f6c8bf6df1eceb5e126d5 100644 (file)
  *     jfs_imap.h: disk inode manager
  */
 
-#define        EXTSPERIAG      128     /* number of disk inode extent per iag  */
-#define IMAPBLKNO      0       /* lblkno of dinomap within inode map   */
-#define SMAPSZ         4       /* number of words per summary map      */
+#define        EXTSPERIAG      128     /* number of disk inode extent per iag  */
+#define IMAPBLKNO      0       /* lblkno of dinomap within inode map   */
+#define SMAPSZ         4       /* number of words per summary map      */
 #define        EXTSPERSUM      32      /* number of extents per summary map entry */
 #define        L2EXTSPERSUM    5       /* l2 number of extents per summary map */
 #define        PGSPERIEXT      4       /* number of 4K pages per dinode extent */
-#define        MAXIAGS         ((1<<20)-1)     /* maximum number of iags       */
-#define        MAXAG           128     /* maximum number of allocation groups  */
+#define        MAXIAGS         ((1<<20)-1)     /* maximum number of iags       */
+#define        MAXAG           128     /* maximum number of allocation groups  */
 
-#define AMAPSIZE      512      /* bytes in the IAG allocation maps */
-#define SMAPSIZE      16       /* bytes in the IAG summary maps */
+#define AMAPSIZE       512     /* bytes in the IAG allocation maps */
+#define SMAPSIZE       16      /* bytes in the IAG summary maps */
 
 /* convert inode number to iag number */
 #define        INOTOIAG(ino)   ((ino) >> L2INOSPERIAG)
  *     inode allocation group page (per 4096 inodes of an AG)
  */
 struct iag {
-       __le64 agstart;         /* 8: starting block of ag              */
-       __le32 iagnum;          /* 4: inode allocation group number     */
-       __le32 inofreefwd;      /* 4: ag inode free list forward        */
-       __le32 inofreeback;     /* 4: ag inode free list back           */
-       __le32 extfreefwd;      /* 4: ag inode extent free list forward */
-       __le32 extfreeback;     /* 4: ag inode extent free list back    */
-       __le32 iagfree;         /* 4: iag free list                     */
+       __le64 agstart;         /* 8: starting block of ag              */
+       __le32 iagnum;          /* 4: inode allocation group number     */
+       __le32 inofreefwd;      /* 4: ag inode free list forward        */
+       __le32 inofreeback;     /* 4: ag inode free list back           */
+       __le32 extfreefwd;      /* 4: ag inode extent free list forward */
+       __le32 extfreeback;     /* 4: ag inode extent free list back    */
+       __le32 iagfree;         /* 4: iag free list                     */
 
        /* summary map: 1 bit per inode extent */
        __le32 inosmap[SMAPSZ]; /* 16: sum map of mapwords w/ free inodes;
-                                *      note: this indicates free and backed
-                                *      inodes, if the extent is not backed the
-                                *      value will be 1.  if the extent is
-                                *      backed but all inodes are being used the
-                                *      value will be 1.  if the extent is
-                                *      backed but at least one of the inodes is
-                                *      free the value will be 0.
+                                *      note: this indicates free and backed
+                                *      inodes, if the extent is not backed the
+                                *      value will be 1.  if the extent is
+                                *      backed but all inodes are being used the
+                                *      value will be 1.  if the extent is
+                                *      backed but at least one of the inodes is
+                                *      free the value will be 0.
                                 */
        __le32 extsmap[SMAPSZ]; /* 16: sum map of mapwords w/ free extents */
-       __le32 nfreeinos;               /* 4: number of free inodes             */
-       __le32 nfreeexts;               /* 4: number of free extents            */
+       __le32 nfreeinos;       /* 4: number of free inodes             */
+       __le32 nfreeexts;       /* 4: number of free extents            */
        /* (72) */
        u8 pad[1976];           /* 1976: pad to 2048 bytes */
        /* allocation bit map: 1 bit per inode (0 - free, 1 - allocated) */
-       __le32 wmap[EXTSPERIAG];        /* 512: working allocation map  */
+       __le32 wmap[EXTSPERIAG];        /* 512: working allocation map */
        __le32 pmap[EXTSPERIAG];        /* 512: persistent allocation map */
        pxd_t inoext[EXTSPERIAG];       /* 1024: inode extent addresses */
 };                             /* (4096) */
@@ -93,44 +93,44 @@ struct iag {
  *     per AG control information (in inode map control page)
  */
 struct iagctl_disk {
-       __le32 inofree;         /* 4: free inode list anchor            */
-       __le32 extfree;         /* 4: free extent list anchor           */
-       __le32 numinos;         /* 4: number of backed inodes           */
-       __le32 numfree;         /* 4: number of free inodes             */
+       __le32 inofree;         /* 4: free inode list anchor            */
+       __le32 extfree;         /* 4: free extent list anchor           */
+       __le32 numinos;         /* 4: number of backed inodes           */
+       __le32 numfree;         /* 4: number of free inodes             */
 };                             /* (16) */
 
 struct iagctl {
-       int inofree;            /* free inode list anchor            */
-       int extfree;            /* free extent list anchor           */
-       int numinos;            /* number of backed inodes           */
-       int numfree;            /* number of free inodes             */
+       int inofree;            /* free inode list anchor               */
+       int extfree;            /* free extent list anchor              */
+       int numinos;            /* number of backed inodes              */
+       int numfree;            /* number of free inodes                */
 };
 
 /*
  *     per fileset/aggregate inode map control page
  */
 struct dinomap_disk {
-       __le32 in_freeiag;      /* 4: free iag list anchor     */
-       __le32 in_nextiag;      /* 4: next free iag number     */
-       __le32 in_numinos;      /* 4: num of backed inodes */
+       __le32 in_freeiag;      /* 4: free iag list anchor      */
+       __le32 in_nextiag;      /* 4: next free iag number      */
+       __le32 in_numinos;      /* 4: num of backed inodes      */
        __le32 in_numfree;      /* 4: num of free backed inodes */
        __le32 in_nbperiext;    /* 4: num of blocks per inode extent */
-       __le32 in_l2nbperiext;  /* 4: l2 of in_nbperiext */
-       __le32 in_diskblock;    /* 4: for standalone test driver  */
-       __le32 in_maxag;        /* 4: for standalone test driver  */
-       u8 pad[2016];           /* 2016: pad to 2048 */
+       __le32 in_l2nbperiext;  /* 4: l2 of in_nbperiext        */
+       __le32 in_diskblock;    /* 4: for standalone test driver */
+       __le32 in_maxag;        /* 4: for standalone test driver */
+       u8 pad[2016];           /* 2016: pad to 2048            */
        struct iagctl_disk in_agctl[MAXAG]; /* 2048: AG control information */
 };                             /* (4096) */
 
 struct dinomap {
-       int in_freeiag;         /* free iag list anchor     */
-       int in_nextiag;         /* next free iag number     */
-       int in_numinos;         /* num of backed inodes */
-       int in_numfree;         /* num of free backed inodes */
+       int in_freeiag;         /* free iag list anchor         */
+       int in_nextiag;         /* next free iag number         */
+       int in_numinos;         /* num of backed inodes         */
+       int in_numfree;         /* num of free backed inodes    */
        int in_nbperiext;       /* num of blocks per inode extent */
-       int in_l2nbperiext;     /* l2 of in_nbperiext */
-       int in_diskblock;       /* for standalone test driver  */
-       int in_maxag;           /* for standalone test driver  */
+       int in_l2nbperiext;     /* l2 of in_nbperiext           */
+       int in_diskblock;       /* for standalone test driver   */
+       int in_maxag;           /* for standalone test driver   */
        struct iagctl in_agctl[MAXAG];  /* AG control information */
 };
 
@@ -139,9 +139,9 @@ struct dinomap {
  */
 struct inomap {
        struct dinomap im_imap;         /* 4096: inode allocation control */
-       struct inode *im_ipimap;        /* 4: ptr to inode for imap   */
-       struct mutex im_freelock;       /* 4: iag free list lock      */
-       struct mutex im_aglock[MAXAG];  /* 512: per AG locks          */
+       struct inode *im_ipimap;        /* 4: ptr to inode for imap     */
+       struct mutex im_freelock;       /* 4: iag free list lock        */
+       struct mutex im_aglock[MAXAG];  /* 512: per AG locks            */
        u32 *im_DBGdimap;
        atomic_t im_numinos;    /* num of backed inodes */
        atomic_t im_numfree;    /* num of free backed inodes */
index 8f453eff3c838a974da6178861716673745a66ff..cb8f30985ad160e38f244e3cb45ab9b377240865 100644 (file)
@@ -40,7 +40,7 @@ struct jfs_inode_info {
        uint    mode2;          /* jfs-specific mode            */
        uint    saved_uid;      /* saved for uid mount option */
        uint    saved_gid;      /* saved for gid mount option */
-       pxd_t   ixpxd;          /* inode extent descriptor      */
+       pxd_t   ixpxd;          /* inode extent descriptor      */
        dxd_t   acl;            /* dxd describing acl   */
        dxd_t   ea;             /* dxd describing ea    */
        time_t  otime;          /* time created */
@@ -190,7 +190,7 @@ struct jfs_sb_info {
        uint            gengen;         /* inode generation generator*/
        uint            inostamp;       /* shows inode belongs to fileset*/
 
-        /* Formerly in ipbmap */
+       /* Formerly in ipbmap */
        struct bmap     *bmap;          /* incore bmap descriptor       */
        struct nls_table *nls_tab;      /* current codepage             */
        struct inode *direct_inode;     /* metadata inode */
index 44a2f33cb98d5d7e3e81ebe7cb0f7c2a12270d29..de3e4a506dbcb7e88623fadac976756382b2c3b2 100644 (file)
@@ -244,7 +244,7 @@ int lmLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
                goto writeRecord;
 
        /*
-        *      initialize/update page/transaction recovery lsn
+        *      initialize/update page/transaction recovery lsn
         */
        lsn = log->lsn;
 
@@ -263,7 +263,7 @@ int lmLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
        }
 
        /*
-        *      initialize/update lsn of tblock of the page
+        *      initialize/update lsn of tblock of the page
         *
         * transaction inherits oldest lsn of pages associated
         * with allocation/deallocation of resources (their
@@ -307,7 +307,7 @@ int lmLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
        LOGSYNC_UNLOCK(log, flags);
 
        /*
-        *      write the log record
+        *      write the log record
         */
       writeRecord:
        lsn = lmWriteRecord(log, tblk, lrd, tlck);
@@ -372,7 +372,7 @@ lmWriteRecord(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
                goto moveLrd;
 
        /*
-        *      move log record data
+        *      move log record data
         */
        /* retrieve source meta-data page to log */
        if (tlck->flag & tlckPAGELOCK) {
@@ -465,7 +465,7 @@ lmWriteRecord(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
        }
 
        /*
-        *      move log record descriptor
+        *      move log record descriptor
         */
       moveLrd:
        lrd->length = cpu_to_le16(len);
@@ -574,7 +574,7 @@ static int lmNextPage(struct jfs_log * log)
        LOGGC_LOCK(log);
 
        /*
-        *      write or queue the full page at the tail of write queue
+        *      write or queue the full page at the tail of write queue
         */
        /* get the tail tblk on commit queue */
        if (list_empty(&log->cqueue))
@@ -625,7 +625,7 @@ static int lmNextPage(struct jfs_log * log)
        LOGGC_UNLOCK(log);
 
        /*
-        *      allocate/initialize next page
+        *      allocate/initialize next page
         */
        /* if log wraps, the first data page of log is 2
         * (0 never used, 1 is superblock).
@@ -953,7 +953,7 @@ static int lmLogSync(struct jfs_log * log, int hard_sync)
                }
 
        /*
-        *      forward syncpt
+        *      forward syncpt
         */
        /* if last sync is same as last syncpt,
         * invoke sync point forward processing to update sync.
@@ -989,7 +989,7 @@ static int lmLogSync(struct jfs_log * log, int hard_sync)
                lsn = log->lsn;
 
        /*
-        *      setup next syncpt trigger (SWAG)
+        *      setup next syncpt trigger (SWAG)
         */
        logsize = log->logsize;
 
@@ -1000,11 +1000,11 @@ static int lmLogSync(struct jfs_log * log, int hard_sync)
        if (more < 2 * LOGPSIZE) {
                jfs_warn("\n ... Log Wrap ... Log Wrap ... Log Wrap ...\n");
                /*
-                *      log wrapping
+                *      log wrapping
                 *
                 * option 1 - panic ? No.!
                 * option 2 - shutdown file systems
-                *            associated with log ?
+                *            associated with log ?
                 * option 3 - extend log ?
                 */
                /*
@@ -1062,7 +1062,7 @@ void jfs_syncpt(struct jfs_log *log, int hard_sync)
 /*
  * NAME:       lmLogOpen()
  *
- * FUNCTION:    open the log on first open;
+ * FUNCTION:   open the log on first open;
  *     insert filesystem in the active list of the log.
  *
  * PARAMETER:  ipmnt   - file system mount inode
@@ -1113,7 +1113,7 @@ int lmLogOpen(struct super_block *sb)
        init_waitqueue_head(&log->syncwait);
 
        /*
-        *      external log as separate logical volume
+        *      external log as separate logical volume
         *
         * file systems to log may have n-to-1 relationship;
         */
@@ -1155,7 +1155,7 @@ journal_found:
        return 0;
 
        /*
-        *      unwind on error
+        *      unwind on error
         */
       shutdown:                /* unwind lbmLogInit() */
        list_del(&log->journal_list);
@@ -1427,7 +1427,7 @@ int lmLogInit(struct jfs_log * log)
        return 0;
 
        /*
-        *      unwind on error
+        *      unwind on error
         */
       errout30:                /* release log page */
        log->wqueue = NULL;
@@ -1480,7 +1480,7 @@ int lmLogClose(struct super_block *sb)
 
        if (test_bit(log_INLINELOG, &log->flag)) {
                /*
-                *      in-line log in host file system
+                *      in-line log in host file system
                 */
                rc = lmLogShutdown(log);
                kfree(log);
@@ -1504,7 +1504,7 @@ int lmLogClose(struct super_block *sb)
                goto out;
 
        /*
-        *      external log as separate logical volume
+        *      external log as separate logical volume
         */
        list_del(&log->journal_list);
        bdev = log->bdev;
@@ -1622,20 +1622,26 @@ void jfs_flush_journal(struct jfs_log *log, int wait)
        if (!list_empty(&log->synclist)) {
                struct logsyncblk *lp;
 
+               printk(KERN_ERR "jfs_flush_journal: synclist not empty\n");
                list_for_each_entry(lp, &log->synclist, synclist) {
                        if (lp->xflag & COMMIT_PAGE) {
                                struct metapage *mp = (struct metapage *)lp;
-                               dump_mem("orphan metapage", lp,
-                                        sizeof(struct metapage));
-                               dump_mem("page", mp->page, sizeof(struct page));
-                       }
-                       else
-                               dump_mem("orphan tblock", lp,
-                                        sizeof(struct tblock));
+                               print_hex_dump(KERN_ERR, "metapage: ",
+                                              DUMP_PREFIX_ADDRESS, 16, 4,
+                                              mp, sizeof(struct metapage), 0);
+                               print_hex_dump(KERN_ERR, "page: ",
+                                              DUMP_PREFIX_ADDRESS, 16,
+                                              sizeof(long), mp->page,
+                                              sizeof(struct page), 0);
+                       } else
+                               print_hex_dump(KERN_ERR, "tblock:",
+                                              DUMP_PREFIX_ADDRESS, 16, 4,
+                                              lp, sizeof(struct tblock), 0);
                }
        }
+#else
+       WARN_ON(!list_empty(&log->synclist));
 #endif
-       //assert(list_empty(&log->synclist));
        clear_bit(log_FLUSH, &log->flag);
 }
 
@@ -1723,7 +1729,7 @@ int lmLogShutdown(struct jfs_log * log)
  *
  * PARAMETE:   log     - pointer to logs inode.
  *             fsdev   - kdev_t of filesystem.
- *             serial  - pointer to returned log serial number
+ *             serial  - pointer to returned log serial number
  *             activate - insert/remove device from active list.
  *
  * RETURN:     0       - success
@@ -1963,7 +1969,7 @@ static void lbmfree(struct lbuf * bp)
  * FUNCTION:   add a log buffer to the log redrive list
  *
  * PARAMETER:
- *     bp      - log buffer
+ *     bp      - log buffer
  *
  * NOTES:
  *     Takes log_redrive_lock.
@@ -2054,7 +2060,7 @@ static void lbmWrite(struct jfs_log * log, struct lbuf * bp, int flag,
        bp->l_flag = flag;
 
        /*
-        *      insert bp at tail of write queue associated with log
+        *      insert bp at tail of write queue associated with log
         *
         * (request is either for bp already/currently at head of queue
         * or new bp to be inserted at tail)
@@ -2117,7 +2123,7 @@ static void lbmDirectWrite(struct jfs_log * log, struct lbuf * bp, int flag)
            log->base + (bp->l_pn << (L2LOGPSIZE - log->l2bsize));
 
        /*
-        *      initiate pageout of the page
+        *      initiate pageout of the page
         */
        lbmStartIO(bp);
 }
@@ -2128,7 +2134,7 @@ static void lbmDirectWrite(struct jfs_log * log, struct lbuf * bp, int flag)
  *
  * FUNCTION:   Interface to DD strategy routine
  *
- * RETURN:      none
+ * RETURN:     none
  *
  * serialization: LCACHE_LOCK() is NOT held during log i/o;
  */
@@ -2222,7 +2228,7 @@ static int lbmIODone(struct bio *bio, unsigned int bytes_done, int error)
        bio_put(bio);
 
        /*
-        *      pagein completion
+        *      pagein completion
         */
        if (bp->l_flag & lbmREAD) {
                bp->l_flag &= ~lbmREAD;
@@ -2236,7 +2242,7 @@ static int lbmIODone(struct bio *bio, unsigned int bytes_done, int error)
        }
 
        /*
-        *      pageout completion
+        *      pageout completion
         *
         * the bp at the head of write queue has completed pageout.
         *
@@ -2302,7 +2308,7 @@ static int lbmIODone(struct bio *bio, unsigned int bytes_done, int error)
        }
 
        /*
-        *      synchronous pageout:
+        *      synchronous pageout:
         *
         * buffer has not necessarily been removed from write queue
         * (e.g., synchronous write of partial-page with COMMIT):
@@ -2316,7 +2322,7 @@ static int lbmIODone(struct bio *bio, unsigned int bytes_done, int error)
        }
 
        /*
-        *      Group Commit pageout:
+        *      Group Commit pageout:
         */
        else if (bp->l_flag & lbmGC) {
                LCACHE_UNLOCK(flags);
@@ -2324,7 +2330,7 @@ static int lbmIODone(struct bio *bio, unsigned int bytes_done, int error)
        }
 
        /*
-        *      asynchronous pageout:
+        *      asynchronous pageout:
         *
         * buffer must have been removed from write queue:
         * insert buffer at head of freelist where it can be recycled
@@ -2375,7 +2381,7 @@ int jfsIOWait(void *arg)
  * FUNCTION:   format file system log
  *
  * PARAMETERS:
- *      log    - volume log
+ *     log     - volume log
  *     logAddress - start address of log space in FS block
  *     logSize - length of log space in FS block;
  *
@@ -2407,16 +2413,16 @@ int lmLogFormat(struct jfs_log *log, s64 logAddress, int logSize)
        npages = logSize >> sbi->l2nbperpage;
 
        /*
-        *      log space:
+        *      log space:
         *
         * page 0 - reserved;
         * page 1 - log superblock;
         * page 2 - log data page: A SYNC log record is written
-        *          into this page at logform time;
+        *          into this page at logform time;
         * pages 3-N - log data page: set to empty log data pages;
         */
        /*
-        *      init log superblock: log page 1
+        *      init log superblock: log page 1
         */
        logsuper = (struct logsuper *) bp->l_ldata;
 
@@ -2436,7 +2442,7 @@ int lmLogFormat(struct jfs_log *log, s64 logAddress, int logSize)
                goto exit;
 
        /*
-        *      init pages 2 to npages-1 as log data pages:
+        *      init pages 2 to npages-1 as log data pages:
         *
         * log page sequence number (lpsn) initialization:
         *
@@ -2479,7 +2485,7 @@ int lmLogFormat(struct jfs_log *log, s64 logAddress, int logSize)
                goto exit;
 
        /*
-        *      initialize succeeding log pages: lpsn = 0, 1, ..., (N-2)
+        *      initialize succeeding log pages: lpsn = 0, 1, ..., (N-2)
         */
        for (lspn = 0; lspn < npages - 3; lspn++) {
                lp->h.page = lp->t.page = cpu_to_le32(lspn);
@@ -2495,7 +2501,7 @@ int lmLogFormat(struct jfs_log *log, s64 logAddress, int logSize)
        rc = 0;
 exit:
        /*
-        *      finalize log
+        *      finalize log
         */
        /* release the buffer */
        lbmFree(bp);
index a53fb17ea219eeb8bc6e0bd903954b0fa0e724f6..1f85ef0ec0456afbe937be2b03ac215473ceb3fa 100644 (file)
@@ -144,7 +144,7 @@ struct logpage {
  *
  * (this comment should be rewritten !)
  * jfs uses only "after" log records (only a single writer is allowed
- * in a  page, pages are written to temporary paging space if
+ * in a page, pages are written to temporary paging space if
  * if they must be written to disk before commit, and i/o is
  * scheduled for modified pages to their home location after
  * the log records containing the after values and the commit
@@ -153,7 +153,7 @@ struct logpage {
  *
  * a log record consists of a data area of variable length followed by
  * a descriptor of fixed size LOGRDSIZE bytes.
- * the  data area is rounded up to an integral number of 4-bytes and
+ * the data area is rounded up to an integral number of 4-bytes and
  * must be no longer than LOGPSIZE.
  * the descriptor is of size of multiple of 4-bytes and aligned on a
  * 4-byte boundary.
@@ -215,13 +215,13 @@ struct lrd {
        union {
 
                /*
-                *      COMMIT: commit
+                *      COMMIT: commit
                 *
                 * transaction commit: no type-dependent information;
                 */
 
                /*
-                *      REDOPAGE: after-image
+                *      REDOPAGE: after-image
                 *
                 * apply after-image;
                 *
@@ -236,7 +236,7 @@ struct lrd {
                } redopage;     /* (20) */
 
                /*
-                *      NOREDOPAGE: the page is freed
+                *      NOREDOPAGE: the page is freed
                 *
                 * do not apply after-image records which precede this record
                 * in the log with the same page block number to this page.
@@ -252,7 +252,7 @@ struct lrd {
                } noredopage;   /* (20) */
 
                /*
-                *      UPDATEMAP: update block allocation map
+                *      UPDATEMAP: update block allocation map
                 *
                 * either in-line PXD,
                 * or     out-of-line  XADLIST;
@@ -268,7 +268,7 @@ struct lrd {
                } updatemap;    /* (20) */
 
                /*
-                *      NOREDOINOEXT: the inode extent is freed
+                *      NOREDOINOEXT: the inode extent is freed
                 *
                 * do not apply after-image records which precede this
                 * record in the log with the any of the 4 page block
@@ -286,7 +286,7 @@ struct lrd {
                } noredoinoext; /* (20) */
 
                /*
-                *      SYNCPT: log sync point
+                *      SYNCPT: log sync point
                 *
                 * replay log upto syncpt address specified;
                 */
@@ -295,13 +295,13 @@ struct lrd {
                } syncpt;
 
                /*
-                *      MOUNT: file system mount
+                *      MOUNT: file system mount
                 *
                 * file system mount: no type-dependent information;
                 */
 
                /*
-                *      ? FREEXTENT: free specified extent(s)
+                *      ? FREEXTENT: free specified extent(s)
                 *
                 * free specified extent(s) from block allocation map
                 * N.B.: nextents should be length of data/sizeof(xad_t)
@@ -314,7 +314,7 @@ struct lrd {
                } freextent;
 
                /*
-                *      ? NOREDOFILE: this file is freed
+                *      ? NOREDOFILE: this file is freed
                 *
                 * do not apply records which precede this record in the log
                 * with the same inode number.
@@ -330,7 +330,7 @@ struct lrd {
                } noredofile;
 
                /*
-                *      ? NEWPAGE:
+                *      ? NEWPAGE:
                 *
                 * metadata type dependent
                 */
@@ -342,7 +342,7 @@ struct lrd {
                } newpage;
 
                /*
-                *      ? DUMMY: filler
+                *      ? DUMMY: filler
                 *
                 * no type-dependent information
                 */
index 43d4f69afbeca923878a45d77fa68d4eb53a55f9..77c7f1129dde636e734f6e354218c72eff5ed0d9 100644 (file)
@@ -472,7 +472,8 @@ add_failed:
        printk(KERN_ERR "JFS: bio_add_page failed unexpectedly\n");
        goto skip;
 dump_bio:
-       dump_mem("bio", bio, sizeof(*bio));
+       print_hex_dump(KERN_ERR, "JFS: dump of bio: ", DUMP_PREFIX_ADDRESS, 16,
+                      4, bio, sizeof(*bio), 0);
 skip:
        bio_put(bio);
        unlock_page(page);
index 4dd479834897be20d7e8ee4d5b7b66eccf1d0137..644429acb8c05d92d49e2129df8d155d37792c4b 100644 (file)
@@ -80,7 +80,7 @@ static int logMOUNT(struct super_block *sb);
  */
 int jfs_mount(struct super_block *sb)
 {
-       int rc = 0;             /* Return code          */
+       int rc = 0;             /* Return code */
        struct jfs_sb_info *sbi = JFS_SBI(sb);
        struct inode *ipaimap = NULL;
        struct inode *ipaimap2 = NULL;
@@ -169,7 +169,7 @@ int jfs_mount(struct super_block *sb)
                sbi->ipaimap2 = NULL;
 
        /*
-        *      mount (the only/single) fileset
+        *      mount (the only/single) fileset
         */
        /*
         * open fileset inode allocation map (aka fileset inode)
@@ -195,7 +195,7 @@ int jfs_mount(struct super_block *sb)
        goto out;
 
        /*
-        *      unwind on error
+        *      unwind on error
         */
       errout41:                /* close fileset inode allocation map inode */
        diFreeSpecial(ipimap);
index 25430d0b0d593a4576cbe9028a5c7c8bdb353d8c..7aa1f7004eaf9f54aded2f394e8e0bcda21057fe 100644 (file)
@@ -18,7 +18,7 @@
  */
 
 /*
- *      jfs_txnmgr.c: transaction manager
+ *     jfs_txnmgr.c: transaction manager
  *
  * notes:
  * transaction starts with txBegin() and ends with txCommit()
@@ -60,7 +60,7 @@
 #include "jfs_debug.h"
 
 /*
- *      transaction management structures
+ *     transaction management structures
  */
 static struct {
        int freetid;            /* index of a free tid structure */
@@ -103,19 +103,19 @@ module_param(nTxLock, int, 0);
 MODULE_PARM_DESC(nTxLock,
                 "Number of transaction locks (max:65536)");
 
-struct tblock *TxBlock;                /* transaction block table */
-static int TxLockLWM;          /* Low water mark for number of txLocks used */
-static int TxLockHWM;          /* High water mark for number of txLocks used */
-static int TxLockVHWM;         /* Very High water mark */
-struct tlock *TxLock;           /* transaction lock table */
+struct tblock *TxBlock;        /* transaction block table */
+static int TxLockLWM;  /* Low water mark for number of txLocks used */
+static int TxLockHWM;  /* High water mark for number of txLocks used */
+static int TxLockVHWM; /* Very High water mark */
+struct tlock *TxLock;  /* transaction lock table */
 
 /*
- *      transaction management lock
+ *     transaction management lock
  */
 static DEFINE_SPINLOCK(jfsTxnLock);
 
-#define TXN_LOCK()              spin_lock(&jfsTxnLock)
-#define TXN_UNLOCK()            spin_unlock(&jfsTxnLock)
+#define TXN_LOCK()             spin_lock(&jfsTxnLock)
+#define TXN_UNLOCK()           spin_unlock(&jfsTxnLock)
 
 #define LAZY_LOCK_INIT()       spin_lock_init(&TxAnchor.LazyLock);
 #define LAZY_LOCK(flags)       spin_lock_irqsave(&TxAnchor.LazyLock, flags)
@@ -148,7 +148,7 @@ static inline void TXN_SLEEP_DROP_LOCK(wait_queue_head_t * event)
 #define TXN_WAKEUP(event) wake_up_all(event)
 
 /*
- *      statistics
+ *     statistics
  */
 static struct {
        tid_t maxtid;           /* 4: biggest tid ever used */
@@ -181,8 +181,8 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
 static void LogSyncRelease(struct metapage * mp);
 
 /*
- *              transaction block/lock management
- *              ---------------------------------
+ *             transaction block/lock management
+ *             ---------------------------------
  */
 
 /*
@@ -227,9 +227,9 @@ static void txLockFree(lid_t lid)
 }
 
 /*
- * NAME:        txInit()
+ * NAME:       txInit()
  *
- * FUNCTION:    initialize transaction management structures
+ * FUNCTION:   initialize transaction management structures
  *
  * RETURN:
  *
@@ -333,9 +333,9 @@ int txInit(void)
 }
 
 /*
- * NAME:        txExit()
+ * NAME:       txExit()
  *
- * FUNCTION:    clean up when module is unloaded
+ * FUNCTION:   clean up when module is unloaded
  */
 void txExit(void)
 {
@@ -346,12 +346,12 @@ void txExit(void)
 }
 
 /*
- * NAME:        txBegin()
+ * NAME:       txBegin()
  *
- * FUNCTION:    start a transaction.
+ * FUNCTION:   start a transaction.
  *
- * PARAMETER:   sb     - superblock
- *              flag   - force for nested tx;
+ * PARAMETER:  sb      - superblock
+ *             flag    - force for nested tx;
  *
  * RETURN:     tid     - transaction id
  *
@@ -447,13 +447,13 @@ tid_t txBegin(struct super_block *sb, int flag)
 }
 
 /*
- * NAME:        txBeginAnon()
+ * NAME:       txBeginAnon()
  *
- * FUNCTION:    start an anonymous transaction.
+ * FUNCTION:   start an anonymous transaction.
  *             Blocks if logsync or available tlocks are low to prevent
  *             anonymous tlocks from depleting supply.
  *
- * PARAMETER:   sb     - superblock
+ * PARAMETER:  sb      - superblock
  *
  * RETURN:     none
  */
@@ -489,11 +489,11 @@ void txBeginAnon(struct super_block *sb)
 }
 
 /*
- *      txEnd()
+ *     txEnd()
  *
  * function: free specified transaction block.
  *
- *      logsync barrier processing:
+ *     logsync barrier processing:
  *
  * serialization:
  */
@@ -577,13 +577,13 @@ wakeup:
 }
 
 /*
- *      txLock()
+ *     txLock()
  *
  * function: acquire a transaction lock on the specified <mp>
  *
  * parameter:
  *
- * return:      transaction lock id
+ * return:     transaction lock id
  *
  * serialization:
  */
@@ -829,12 +829,16 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp,
        /* Only locks on ipimap or ipaimap should reach here */
        /* assert(jfs_ip->fileset == AGGREGATE_I); */
        if (jfs_ip->fileset != AGGREGATE_I) {
-               jfs_err("txLock: trying to lock locked page!");
-               dump_mem("ip", ip, sizeof(struct inode));
-               dump_mem("mp", mp, sizeof(struct metapage));
-               dump_mem("Locker's tblk", tid_to_tblock(tid),
-                        sizeof(struct tblock));
-               dump_mem("Tlock", tlck, sizeof(struct tlock));
+               printk(KERN_ERR "txLock: trying to lock locked page!");
+               print_hex_dump(KERN_ERR, "ip: ", DUMP_PREFIX_ADDRESS, 16, 4,
+                              ip, sizeof(*ip), 0);
+               print_hex_dump(KERN_ERR, "mp: ", DUMP_PREFIX_ADDRESS, 16, 4,
+                              mp, sizeof(*mp), 0);
+               print_hex_dump(KERN_ERR, "Locker's tblock: ",
+                              DUMP_PREFIX_ADDRESS, 16, 4, tid_to_tblock(tid),
+                              sizeof(struct tblock), 0);
+               print_hex_dump(KERN_ERR, "Tlock: ", DUMP_PREFIX_ADDRESS, 16, 4,
+                              tlck, sizeof(*tlck), 0);
                BUG();
        }
        INCREMENT(stattx.waitlock);     /* statistics */
@@ -857,17 +861,17 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp,
 }
 
 /*
- * NAME:        txRelease()
+ * NAME:       txRelease()
  *
- * FUNCTION:    Release buffers associated with transaction locks, but don't
+ * FUNCTION:   Release buffers associated with transaction locks, but don't
  *             mark homeok yet.  The allows other transactions to modify
  *             buffers, but won't let them go to disk until commit record
  *             actually gets written.
  *
  * PARAMETER:
- *              tblk    -
+ *             tblk    -
  *
- * RETURN:      Errors from subroutines.
+ * RETURN:     Errors from subroutines.
  */
 static void txRelease(struct tblock * tblk)
 {
@@ -896,10 +900,10 @@ static void txRelease(struct tblock * tblk)
 }
 
 /*
- * NAME:        txUnlock()
+ * NAME:       txUnlock()
  *
- * FUNCTION:    Initiates pageout of pages modified by tid in journalled
- *              objects and frees their lockwords.
+ * FUNCTION:   Initiates pageout of pages modified by tid in journalled
+ *             objects and frees their lockwords.
  */
 static void txUnlock(struct tblock * tblk)
 {
@@ -983,10 +987,10 @@ static void txUnlock(struct tblock * tblk)
 }
 
 /*
- *      txMaplock()
+ *     txMaplock()
  *
  * function: allocate a transaction lock for freed page/entry;
- *      for freed page, maplock is used as xtlock/dtlock type;
+ *     for freed page, maplock is used as xtlock/dtlock type;
  */
 struct tlock *txMaplock(tid_t tid, struct inode *ip, int type)
 {
@@ -1057,7 +1061,7 @@ struct tlock *txMaplock(tid_t tid, struct inode *ip, int type)
 }
 
 /*
- *      txLinelock()
+ *     txLinelock()
  *
  * function: allocate a transaction lock for log vector list
  */
@@ -1092,39 +1096,39 @@ struct linelock *txLinelock(struct linelock * tlock)
 }
 
 /*
- *              transaction commit management
- *              -----------------------------
+ *             transaction commit management
+ *             -----------------------------
  */
 
 /*
- * NAME:        txCommit()
- *
- * FUNCTION:    commit the changes to the objects specified in
- *              clist.  For journalled segments only the
- *              changes of the caller are committed, ie by tid.
- *              for non-journalled segments the data are flushed to
- *              disk and then the change to the disk inode and indirect
- *              blocks committed (so blocks newly allocated to the
- *              segment will be made a part of the segment atomically).
- *
- *              all of the segments specified in clist must be in
- *              one file system. no more than 6 segments are needed
- *              to handle all unix svcs.
- *
- *              if the i_nlink field (i.e. disk inode link count)
- *              is zero, and the type of inode is a regular file or
- *              directory, or symbolic link , the inode is truncated
- *              to zero length. the truncation is committed but the
- *              VM resources are unaffected until it is closed (see
- *              iput and iclose).
+ * NAME:       txCommit()
+ *
+ * FUNCTION:   commit the changes to the objects specified in
+ *             clist.  For journalled segments only the
+ *             changes of the caller are committed, ie by tid.
+ *             for non-journalled segments the data are flushed to
+ *             disk and then the change to the disk inode and indirect
+ *             blocks committed (so blocks newly allocated to the
+ *             segment will be made a part of the segment atomically).
+ *
+ *             all of the segments specified in clist must be in
+ *             one file system. no more than 6 segments are needed
+ *             to handle all unix svcs.
+ *
+ *             if the i_nlink field (i.e. disk inode link count)
+ *             is zero, and the type of inode is a regular file or
+ *             directory, or symbolic link , the inode is truncated
+ *             to zero length. the truncation is committed but the
+ *             VM resources are unaffected until it is closed (see
+ *             iput and iclose).
  *
  * PARAMETER:
  *
  * RETURN:
  *
  * serialization:
- *              on entry the inode lock on each segment is assumed
- *              to be held.
+ *             on entry the inode lock on each segment is assumed
+ *             to be held.
  *
  * i/o error:
  */
@@ -1175,7 +1179,7 @@ int txCommit(tid_t tid,           /* transaction identifier */
        if ((flag & (COMMIT_FORCE | COMMIT_SYNC)) == 0)
                tblk->xflag |= COMMIT_LAZY;
        /*
-        *      prepare non-journaled objects for commit
+        *      prepare non-journaled objects for commit
         *
         * flush data pages of non-journaled file
         * to prevent the file getting non-initialized disk blocks
@@ -1186,7 +1190,7 @@ int txCommit(tid_t tid,           /* transaction identifier */
        cd.nip = nip;
 
        /*
-        *      acquire transaction lock on (on-disk) inodes
+        *      acquire transaction lock on (on-disk) inodes
         *
         * update on-disk inode from in-memory inode
         * acquiring transaction locks for AFTER records
@@ -1262,7 +1266,7 @@ int txCommit(tid_t tid,           /* transaction identifier */
        }
 
        /*
-        *      write log records from transaction locks
+        *      write log records from transaction locks
         *
         * txUpdateMap() resets XAD_NEW in XAD.
         */
@@ -1294,7 +1298,7 @@ int txCommit(tid_t tid,           /* transaction identifier */
                !test_cflag(COMMIT_Nolink, tblk->u.ip)));
 
        /*
-        *      write COMMIT log record
+        *      write COMMIT log record
         */
        lrd->type = cpu_to_le16(LOG_COMMIT);
        lrd->length = 0;
@@ -1303,7 +1307,7 @@ int txCommit(tid_t tid,           /* transaction identifier */
        lmGroupCommit(log, tblk);
 
        /*
-        *      - transaction is now committed -
+        *      - transaction is now committed -
         */
 
        /*
@@ -1314,11 +1318,11 @@ int txCommit(tid_t tid,         /* transaction identifier */
                txForce(tblk);
 
        /*
-        *      update allocation map.
+        *      update allocation map.
         *
         * update inode allocation map and inode:
         * free pager lock on memory object of inode if any.
-        * update  block allocation map.
+        * update block allocation map.
         *
         * txUpdateMap() resets XAD_NEW in XAD.
         */
@@ -1326,7 +1330,7 @@ int txCommit(tid_t tid,           /* transaction identifier */
                txUpdateMap(tblk);
 
        /*
-        *      free transaction locks and pageout/free pages
+        *      free transaction locks and pageout/free pages
         */
        txRelease(tblk);
 
@@ -1335,7 +1339,7 @@ int txCommit(tid_t tid,           /* transaction identifier */
 
 
        /*
-        *      reset in-memory object state
+        *      reset in-memory object state
         */
        for (k = 0; k < cd.nip; k++) {
                ip = cd.iplist[k];
@@ -1358,11 +1362,11 @@ int txCommit(tid_t tid,         /* transaction identifier */
 }
 
 /*
- * NAME:        txLog()
+ * NAME:       txLog()
  *
- * FUNCTION:    Writes AFTER log records for all lines modified
- *              by tid for segments specified by inodes in comdata.
- *              Code assumes only WRITELOCKS are recorded in lockwords.
+ * FUNCTION:   Writes AFTER log records for all lines modified
+ *             by tid for segments specified by inodes in comdata.
+ *             Code assumes only WRITELOCKS are recorded in lockwords.
  *
  * PARAMETERS:
  *
@@ -1421,12 +1425,12 @@ static int txLog(struct jfs_log * log, struct tblock * tblk, struct commit * cd)
 }
 
 /*
- *      diLog()
+ *     diLog()
  *
- * function:    log inode tlock and format maplock to update bmap;
+ * function:   log inode tlock and format maplock to update bmap;
  */
 static int diLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
-         struct tlock * tlck, struct commit * cd)
+                struct tlock * tlck, struct commit * cd)
 {
        int rc = 0;
        struct metapage *mp;
@@ -1442,7 +1446,7 @@ static int diLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
        pxd = &lrd->log.redopage.pxd;
 
        /*
-        *      inode after image
+        *      inode after image
         */
        if (tlck->type & tlckENTRY) {
                /* log after-image for logredo(): */
@@ -1456,7 +1460,7 @@ static int diLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
                tlck->flag |= tlckWRITEPAGE;
        } else if (tlck->type & tlckFREE) {
                /*
-                *      free inode extent
+                *      free inode extent
                 *
                 * (pages of the freed inode extent have been invalidated and
                 * a maplock for free of the extent has been formatted at
@@ -1498,7 +1502,7 @@ static int diLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
                jfs_err("diLog: UFO type tlck:0x%p", tlck);
 #ifdef  _JFS_WIP
        /*
-        *      alloc/free external EA extent
+        *      alloc/free external EA extent
         *
         * a maplock for txUpdateMap() to update bPWMAP for alloc/free
         * of the extent has been formatted at txLock() time;
@@ -1534,9 +1538,9 @@ static int diLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
 }
 
 /*
- *      dataLog()
+ *     dataLog()
  *
- * function:    log data tlock
+ * function:   log data tlock
  */
 static int dataLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
            struct tlock * tlck)
@@ -1580,9 +1584,9 @@ static int dataLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
 }
 
 /*
- *      dtLog()
+ *     dtLog()
  *
- * function:    log dtree tlock and format maplock to update bmap;
+ * function:   log dtree tlock and format maplock to update bmap;
  */
 static void dtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
           struct tlock * tlck)
@@ -1603,10 +1607,10 @@ static void dtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
                lrd->log.redopage.type |= cpu_to_le16(LOG_BTROOT);
 
        /*
-        *      page extension via relocation: entry insertion;
-        *      page extension in-place: entry insertion;
-        *      new right page from page split, reinitialized in-line
-        *      root from root page split: entry insertion;
+        *      page extension via relocation: entry insertion;
+        *      page extension in-place: entry insertion;
+        *      new right page from page split, reinitialized in-line
+        *      root from root page split: entry insertion;
         */
        if (tlck->type & (tlckNEW | tlckEXTEND)) {
                /* log after-image of the new page for logredo():
@@ -1641,8 +1645,8 @@ static void dtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
        }
 
        /*
-        *      entry insertion/deletion,
-        *      sibling page link update (old right page before split);
+        *      entry insertion/deletion,
+        *      sibling page link update (old right page before split);
         */
        if (tlck->type & (tlckENTRY | tlckRELINK)) {
                /* log after-image for logredo(): */
@@ -1658,11 +1662,11 @@ static void dtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
        }
 
        /*
-        *      page deletion: page has been invalidated
-        *      page relocation: source extent
+        *      page deletion: page has been invalidated
+        *      page relocation: source extent
         *
-        *      a maplock for free of the page has been formatted
-        *      at txLock() time);
+        *      a maplock for free of the page has been formatted
+        *      at txLock() time);
         */
        if (tlck->type & (tlckFREE | tlckRELOCATE)) {
                /* log LOG_NOREDOPAGE of the deleted page for logredo()
@@ -1683,9 +1687,9 @@ static void dtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
 }
 
 /*
- *      xtLog()
+ *     xtLog()
  *
- * function:    log xtree tlock and format maplock to update bmap;
+ * function:   log xtree tlock and format maplock to update bmap;
  */
 static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
           struct tlock * tlck)
@@ -1725,8 +1729,8 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
        xadlock = (struct xdlistlock *) maplock;
 
        /*
-        *      entry insertion/extension;
-        *      sibling page link update (old right page before split);
+        *      entry insertion/extension;
+        *      sibling page link update (old right page before split);
         */
        if (tlck->type & (tlckNEW | tlckGROW | tlckRELINK)) {
                /* log after-image for logredo():
@@ -1801,7 +1805,7 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
        }
 
        /*
-        *      page deletion: file deletion/truncation (ref. xtTruncate())
+        *      page deletion: file deletion/truncation (ref. xtTruncate())
         *
         * (page will be invalidated after log is written and bmap
         * is updated from the page);
@@ -1908,13 +1912,13 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
        }
 
        /*
-        *      page/entry truncation: file truncation (ref. xtTruncate())
+        *      page/entry truncation: file truncation (ref. xtTruncate())
         *
-        *     |----------+------+------+---------------|
-        *                |      |      |
-        *                |      |     hwm - hwm before truncation
-        *                |     next - truncation point
-        *               lwm - lwm before truncation
+        *      |----------+------+------+---------------|
+        *                 |      |      |
+        *                 |      |     hwm - hwm before truncation
+        *                 |     next - truncation point
+        *                lwm - lwm before truncation
         * header ?
         */
        if (tlck->type & tlckTRUNCATE) {
@@ -1937,7 +1941,7 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
                twm = xtlck->twm.offset;
 
                /*
-                *      write log records
+                *      write log records
                 */
                /* log after-image for logredo():
                 *
@@ -1997,7 +2001,7 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
                }
 
                /*
-                *      format maplock(s) for txUpdateMap() to update bmap
+                *      format maplock(s) for txUpdateMap() to update bmap
                 */
                maplock->index = 0;
 
@@ -2069,9 +2073,9 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
 }
 
 /*
- *      mapLog()
+ *     mapLog()
  *
- * function:    log from maplock of freed data extents;
+ * function:   log from maplock of freed data extents;
  */
 static void mapLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
                   struct tlock * tlck)
@@ -2081,7 +2085,7 @@ static void mapLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
        pxd_t *pxd;
 
        /*
-        *      page relocation: free the source page extent
+        *      page relocation: free the source page extent
         *
         * a maplock for txUpdateMap() for free of the page
         * has been formatted at txLock() time saving the src
@@ -2155,10 +2159,10 @@ static void mapLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
 }
 
 /*
- *      txEA()
+ *     txEA()
  *
- * function:    acquire maplock for EA/ACL extents or
- *              set COMMIT_INLINE flag;
+ * function:   acquire maplock for EA/ACL extents or
+ *             set COMMIT_INLINE flag;
  */
 void txEA(tid_t tid, struct inode *ip, dxd_t * oldea, dxd_t * newea)
 {
@@ -2207,10 +2211,10 @@ void txEA(tid_t tid, struct inode *ip, dxd_t * oldea, dxd_t * newea)
 }
 
 /*
- *      txForce()
+ *     txForce()
  *
  * function: synchronously write pages locked by transaction
- *              after txLog() but before txUpdateMap();
+ *          after txLog() but before txUpdateMap();
  */
 static void txForce(struct tblock * tblk)
 {
@@ -2273,10 +2277,10 @@ static void txForce(struct tblock * tblk)
 }
 
 /*
- *      txUpdateMap()
+ *     txUpdateMap()
  *
- * function:    update persistent allocation map (and working map
- *              if appropriate);
+ * function:   update persistent allocation map (and working map
+ *             if appropriate);
  *
  * parameter:
  */
@@ -2298,7 +2302,7 @@ static void txUpdateMap(struct tblock * tblk)
 
 
        /*
-        *      update block allocation map
+        *      update block allocation map
         *
         * update allocation state in pmap (and wmap) and
         * update lsn of the pmap page;
@@ -2382,7 +2386,7 @@ static void txUpdateMap(struct tblock * tblk)
                }
        }
        /*
-        *      update inode allocation map
+        *      update inode allocation map
         *
         * update allocation state in pmap and
         * update lsn of the pmap page;
@@ -2407,24 +2411,24 @@ static void txUpdateMap(struct tblock * tblk)
 }
 
 /*
- *      txAllocPMap()
+ *     txAllocPMap()
  *
  * function: allocate from persistent map;
  *
  * parameter:
- *      ipbmap  -
- *      malock -
- *              xad list:
- *              pxd:
- *
- *      maptype -
- *              allocate from persistent map;
- *              free from persistent map;
- *              (e.g., tmp file - free from working map at releae
- *               of last reference);
- *              free from persistent and working map;
- *
- *      lsn     - log sequence number;
+ *     ipbmap  -
+ *     malock  -
+ *             xad list:
+ *             pxd:
+ *
+ *     maptype -
+ *             allocate from persistent map;
+ *             free from persistent map;
+ *             (e.g., tmp file - free from working map at releae
+ *              of last reference);
+ *             free from persistent and working map;
+ *
+ *     lsn     - log sequence number;
  */
 static void txAllocPMap(struct inode *ip, struct maplock * maplock,
                        struct tblock * tblk)
@@ -2478,9 +2482,9 @@ static void txAllocPMap(struct inode *ip, struct maplock * maplock,
 }
 
 /*
- *      txFreeMap()
+ *     txFreeMap()
  *
- * function:    free from persistent and/or working map;
+ * function:   free from persistent and/or working map;
  *
  * todo: optimization
  */
@@ -2579,9 +2583,9 @@ void txFreeMap(struct inode *ip,
 }
 
 /*
- *      txFreelock()
+ *     txFreelock()
  *
- * function:    remove tlock from inode anonymous locklist
+ * function:   remove tlock from inode anonymous locklist
  */
 void txFreelock(struct inode *ip)
 {
@@ -2619,7 +2623,7 @@ void txFreelock(struct inode *ip)
 }
 
 /*
- *      txAbort()
+ *     txAbort()
  *
  * function: abort tx before commit;
  *
@@ -2679,7 +2683,7 @@ void txAbort(tid_t tid, int dirty)
 }
 
 /*
- *      txLazyCommit(void)
+ *     txLazyCommit(void)
  *
  *     All transactions except those changing ipimap (COMMIT_FORCE) are
  *     processed by this routine.  This insures that the inode and block
@@ -2728,7 +2732,7 @@ static void txLazyCommit(struct tblock * tblk)
 }
 
 /*
- *      jfs_lazycommit(void)
+ *     jfs_lazycommit(void)
  *
  *     To be run as a kernel daemon.  If lbmIODone is called in an interrupt
  *     context, or where blocking is not wanted, this routine will process
@@ -2913,7 +2917,7 @@ void txResume(struct super_block *sb)
 }
 
 /*
- *      jfs_sync(void)
+ *     jfs_sync(void)
  *
  *     To be run as a kernel daemon.  This is awakened when tlocks run low.
  *     We write any inodes that have anonymous tlocks so they will become
index 7863cf21afcac82ef586c97541697f14d2640eaa..ab7288937019c7b718acbd9c19957d7131c0427b 100644 (file)
@@ -94,7 +94,7 @@ extern struct tblock *TxBlock;        /* transaction block table */
  */
 struct tlock {
        lid_t next;             /* 2: index next lockword on tid locklist
-                                *          next lockword on freelist
+                                *          next lockword on freelist
                                 */
        tid_t tid;              /* 2: transaction id holding lock */
 
index 09b2529586874159c550978ea46410285738035a..649f9817accd05f5899e54dca2ecb0dcb406c6d6 100644 (file)
@@ -21,7 +21,7 @@
 /*
  *     jfs_types.h:
  *
- * basic type/utility  definitions
+ * basic type/utility definitions
  *
  * note: this header file must be the 1st include file
  * of JFS include list in all JFS .c file.
@@ -54,8 +54,8 @@ struct timestruc_t {
  */
 
 #define LEFTMOSTONE    0x80000000
-#define        HIGHORDER       0x80000000u     /* high order bit on            */
-#define        ONES            0xffffffffu     /* all bit on                   */
+#define        HIGHORDER       0x80000000u     /* high order bit on    */
+#define        ONES            0xffffffffu     /* all bit on           */
 
 /*
  *     logical xd (lxd)
@@ -148,7 +148,7 @@ typedef struct {
 #define sizeDXD(dxd)   le32_to_cpu((dxd)->size)
 
 /*
- *      directory entry argument
+ *     directory entry argument
  */
 struct component_name {
        int namlen;
@@ -160,14 +160,14 @@ struct component_name {
  *     DASD limit information - stored in directory inode
  */
 struct dasd {
-       u8 thresh;              /* Alert Threshold (in percent) */
-       u8 delta;               /* Alert Threshold delta (in percent)   */
+       u8 thresh;              /* Alert Threshold (in percent)         */
+       u8 delta;               /* Alert Threshold delta (in percent)   */
        u8 rsrvd1;
-       u8 limit_hi;            /* DASD limit (in logical blocks)       */
-       __le32 limit_lo;        /* DASD limit (in logical blocks)       */
+       u8 limit_hi;            /* DASD limit (in logical blocks)       */
+       __le32 limit_lo;        /* DASD limit (in logical blocks)       */
        u8 rsrvd2[3];
-       u8 used_hi;             /* DASD usage (in logical blocks)       */
-       __le32 used_lo;         /* DASD usage (in logical blocks)       */
+       u8 used_hi;             /* DASD usage (in logical blocks)       */
+       __le32 used_lo;         /* DASD usage (in logical blocks)       */
 };
 
 #define DASDLIMIT(dasdp) \
index a386f48c73fcb5270bfcf90ac067d172792280f6..7971f37534a359e0dcfed248cb56e56a14c7fac7 100644 (file)
@@ -60,7 +60,7 @@ int jfs_umount(struct super_block *sb)
        jfs_info("UnMount JFS: sb:0x%p", sb);
 
        /*
-        *      update superblock and close log
+        *      update superblock and close log
         *
         * if mounted read-write and log based recovery was enabled
         */
index acc97c46d8a4096125ce4e2355a12e779d7aa376..1543906a2e0dd29ac7008ac1204c490b765ba14b 100644 (file)
@@ -16,7 +16,7 @@
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 /*
- *      jfs_xtree.c: extent allocation descriptor B+-tree manager
+ *     jfs_xtree.c: extent allocation descriptor B+-tree manager
  */
 
 #include <linux/fs.h>
 /*
  * xtree local flag
  */
-#define XT_INSERT       0x00000001
+#define XT_INSERT      0x00000001
 
 /*
- *       xtree key/entry comparison: extent offset
+ *     xtree key/entry comparison: extent offset
  *
  * return:
- *      -1: k < start of extent
- *       0: start_of_extent <= k <= end_of_extent
- *       1: k > end_of_extent
+ *     -1: k < start of extent
+ *      0: start_of_extent <= k <= end_of_extent
+ *      1: k > end_of_extent
  */
 #define XT_CMP(CMP, K, X, OFFSET64)\
 {\
-        OFFSET64 = offsetXAD(X);\
-        (CMP) = ((K) >= OFFSET64 + lengthXAD(X)) ? 1 :\
-              ((K) < OFFSET64) ? -1 : 0;\
+       OFFSET64 = offsetXAD(X);\
+       (CMP) = ((K) >= OFFSET64 + lengthXAD(X)) ? 1 :\
+               ((K) < OFFSET64) ? -1 : 0;\
 }
 
 /* write a xad entry */
 #define XT_PUTENTRY(XAD, FLAG, OFF, LEN, ADDR)\
 {\
-        (XAD)->flag = (FLAG);\
-        XADoffset((XAD), (OFF));\
-        XADlength((XAD), (LEN));\
-        XADaddress((XAD), (ADDR));\
+       (XAD)->flag = (FLAG);\
+       XADoffset((XAD), (OFF));\
+       XADlength((XAD), (LEN));\
+       XADaddress((XAD), (ADDR));\
 }
 
 #define XT_PAGE(IP, MP) BT_PAGE(IP, MP, xtpage_t, i_xtroot)
                        MP = NULL;\
                        RC = -EIO;\
                }\
-        }\
+       }\
 }
 
 /* for consistency */
 #define XT_PUTPAGE(MP) BT_PUTPAGE(MP)
 
-#define XT_GETSEARCH(IP, LEAF, BN, MP,  P, INDEX) \
+#define XT_GETSEARCH(IP, LEAF, BN, MP, P, INDEX) \
        BT_GETSEARCH(IP, LEAF, BN, MP, xtpage_t, P, INDEX, i_xtroot)
 /* xtree entry parameter descriptor */
 struct xtsplit {
@@ -97,7 +97,7 @@ struct xtsplit {
 
 
 /*
- *      statistics
+ *     statistics
  */
 #ifdef CONFIG_JFS_STATISTICS
 static struct {
@@ -136,7 +136,7 @@ static int xtRelink(tid_t tid, struct inode *ip, xtpage_t * fp);
 #endif                         /*  _STILL_TO_PORT */
 
 /*
- *      xtLookup()
+ *     xtLookup()
  *
  * function: map a single page into a physical extent;
  */
@@ -179,7 +179,7 @@ int xtLookup(struct inode *ip, s64 lstart,
        }
 
        /*
-        *      compute the physical extent covering logical extent
+        *      compute the physical extent covering logical extent
         *
         * N.B. search may have failed (e.g., hole in sparse file),
         * and returned the index of the next entry.
@@ -220,27 +220,27 @@ int xtLookup(struct inode *ip, s64 lstart,
 
 
 /*
- *      xtLookupList()
+ *     xtLookupList()
  *
  * function: map a single logical extent into a list of physical extent;
  *
  * parameter:
- *      struct inode    *ip,
- *      struct lxdlist  *lxdlist,       lxd list (in)
- *      struct xadlist  *xadlist,       xad list (in/out)
- *      int            flag)
+ *     struct inode    *ip,
+ *     struct lxdlist  *lxdlist,       lxd list (in)
+ *     struct xadlist  *xadlist,       xad list (in/out)
+ *     int             flag)
  *
  * coverage of lxd by xad under assumption of
  * . lxd's are ordered and disjoint.
  * . xad's are ordered and disjoint.
  *
  * return:
- *      0:      success
+ *     0:      success
  *
  * note: a page being written (even a single byte) is backed fully,
- *      except the last page which is only backed with blocks
- *      required to cover the last byte;
- *      the extent backing a page is fully contained within an xad;
+ *     except the last page which is only backed with blocks
+ *     required to cover the last byte;
+ *     the extent backing a page is fully contained within an xad;
  */
 int xtLookupList(struct inode *ip, struct lxdlist * lxdlist,
                 struct xadlist * xadlist, int flag)
@@ -284,7 +284,7 @@ int xtLookupList(struct inode *ip, struct lxdlist * lxdlist,
                return rc;
 
        /*
-        *      compute the physical extent covering logical extent
+        *      compute the physical extent covering logical extent
         *
         * N.B. search may have failed (e.g., hole in sparse file),
         * and returned the index of the next entry.
@@ -343,7 +343,7 @@ int xtLookupList(struct inode *ip, struct lxdlist * lxdlist,
                if (lstart >= size)
                        goto mapend;
 
-               /* compare with the current xad  */
+               /* compare with the current xad */
                goto compare1;
        }
        /* lxd is covered by xad */
@@ -430,7 +430,7 @@ int xtLookupList(struct inode *ip, struct lxdlist * lxdlist,
        /*
         * lxd is partially covered by xad
         */
-       else {                  /* (xend < lend)  */
+       else {                  /* (xend < lend) */
 
                /*
                 * get next xad
@@ -477,22 +477,22 @@ int xtLookupList(struct inode *ip, struct lxdlist * lxdlist,
 
 
 /*
- *      xtSearch()
+ *     xtSearch()
  *
- * function:    search for the xad entry covering specified offset.
+ * function:   search for the xad entry covering specified offset.
  *
  * parameters:
- *      ip      - file object;
- *      xoff    - extent offset;
- *      nextp  - address of next extent (if any) for search miss
- *      cmpp    - comparison result:
- *      btstack - traverse stack;
- *      flag    - search process flag (XT_INSERT);
+ *     ip      - file object;
+ *     xoff    - extent offset;
+ *     nextp   - address of next extent (if any) for search miss
+ *     cmpp    - comparison result:
+ *     btstack - traverse stack;
+ *     flag    - search process flag (XT_INSERT);
  *
  * returns:
- *      btstack contains (bn, index) of search path traversed to the entry.
- *      *cmpp is set to result of comparison with the entry returned.
- *      the page containing the entry is pinned at exit.
+ *     btstack contains (bn, index) of search path traversed to the entry.
+ *     *cmpp is set to result of comparison with the entry returned.
+ *     the page containing the entry is pinned at exit.
  */
 static int xtSearch(struct inode *ip, s64 xoff,        s64 *nextp,
                    int *cmpp, struct btstack * btstack, int flag)
@@ -517,7 +517,7 @@ static int xtSearch(struct inode *ip, s64 xoff,     s64 *nextp,
        btstack->nsplit = 0;
 
        /*
-        *      search down tree from root:
+        *      search down tree from root:
         *
         * between two consecutive entries of <Ki, Pi> and <Kj, Pj> of
         * internal page, child page Pi contains entry with k, Ki <= K < Kj.
@@ -642,7 +642,7 @@ static int xtSearch(struct inode *ip, s64 xoff,     s64 *nextp,
                        XT_CMP(cmp, xoff, &p->xad[index], t64);
                        if (cmp == 0) {
                                /*
-                                *      search hit
+                                *      search hit
                                 */
                                /* search hit - leaf page:
                                 * return the entry found
@@ -692,7 +692,7 @@ static int xtSearch(struct inode *ip, s64 xoff,     s64 *nextp,
                }
 
                /*
-                *      search miss
+                *      search miss
                 *
                 * base is the smallest index with key (Kj) greater than
                 * search key (K) and may be zero or maxentry index.
@@ -773,22 +773,22 @@ static int xtSearch(struct inode *ip, s64 xoff,   s64 *nextp,
 }
 
 /*
- *      xtInsert()
+ *     xtInsert()
  *
  * function:
  *
  * parameter:
- *      tid     - transaction id;
- *      ip      - file object;
- *      xflag   - extent flag (XAD_NOTRECORDED):
- *      xoff    - extent offset;
- *      xlen    - extent length;
- *      xaddrp  - extent address pointer (in/out):
- *              if (*xaddrp)
- *                      caller allocated data extent at *xaddrp;
- *              else
- *                      allocate data extent and return its xaddr;
- *      flag    -
+ *     tid     - transaction id;
+ *     ip      - file object;
+ *     xflag   - extent flag (XAD_NOTRECORDED):
+ *     xoff    - extent offset;
+ *     xlen    - extent length;
+ *     xaddrp  - extent address pointer (in/out):
+ *             if (*xaddrp)
+ *                     caller allocated data extent at *xaddrp;
+ *             else
+ *                     allocate data extent and return its xaddr;
+ *     flag    -
  *
  * return:
  */
@@ -813,7 +813,7 @@ int xtInsert(tid_t tid,             /* transaction id */
        jfs_info("xtInsert: nxoff:0x%lx nxlen:0x%x", (ulong) xoff, xlen);
 
        /*
-        *      search for the entry location at which to insert:
+        *      search for the entry location at which to insert:
         *
         * xtFastSearch() and xtSearch() both returns (leaf page
         * pinned, index at which to insert).
@@ -853,13 +853,13 @@ int xtInsert(tid_t tid,           /* transaction id */
        }
 
        /*
-        *      insert entry for new extent
+        *      insert entry for new extent
         */
        xflag |= XAD_NEW;
 
        /*
-        *      if the leaf page is full, split the page and
-        *      propagate up the router entry for the new page from split
+        *      if the leaf page is full, split the page and
+        *      propagate up the router entry for the new page from split
         *
         * The xtSplitUp() will insert the entry and unpin the leaf page.
         */
@@ -886,7 +886,7 @@ int xtInsert(tid_t tid,             /* transaction id */
        }
 
        /*
-        *      insert the new entry into the leaf page
+        *      insert the new entry into the leaf page
         */
        /*
         * acquire a transaction lock on the leaf page;
@@ -930,16 +930,16 @@ int xtInsert(tid_t tid,           /* transaction id */
 
 
 /*
- *      xtSplitUp()
+ *     xtSplitUp()
  *
  * function:
- *      split full pages as propagating insertion up the tree
+ *     split full pages as propagating insertion up the tree
  *
  * parameter:
- *      tid     - transaction id;
- *      ip      - file object;
- *      split   - entry parameter descriptor;
- *      btstack - traverse stack from xtSearch()
+ *     tid     - transaction id;
+ *     ip      - file object;
+ *     split   - entry parameter descriptor;
+ *     btstack - traverse stack from xtSearch()
  *
  * return:
  */
@@ -1199,22 +1199,22 @@ xtSplitUp(tid_t tid,
 
 
 /*
- *      xtSplitPage()
+ *     xtSplitPage()
  *
  * function:
- *      split a full non-root page into
- *      original/split/left page and new right page
- *      i.e., the original/split page remains as left page.
+ *     split a full non-root page into
+ *     original/split/left page and new right page
+ *     i.e., the original/split page remains as left page.
  *
  * parameter:
- *      int            tid,
- *      struct inode    *ip,
- *      struct xtsplit  *split,
- *      struct metapage        **rmpp,
- *      u64            *rbnp,
+ *     int             tid,
+ *     struct inode    *ip,
+ *     struct xtsplit  *split,
+ *     struct metapage **rmpp,
+ *     u64             *rbnp,
  *
  * return:
- *      Pointer to page in which to insert or NULL on error.
+ *     Pointer to page in which to insert or NULL on error.
  */
 static int
 xtSplitPage(tid_t tid, struct inode *ip,
@@ -1248,9 +1248,9 @@ xtSplitPage(tid_t tid, struct inode *ip,
        rbn = addressPXD(pxd);
 
        /* Allocate blocks to quota. */
-       if (DQUOT_ALLOC_BLOCK(ip, lengthPXD(pxd))) {
-              rc = -EDQUOT;
-              goto clean_up;
+       if (DQUOT_ALLOC_BLOCK(ip, lengthPXD(pxd))) {
+               rc = -EDQUOT;
+               goto clean_up;
        }
 
        quota_allocation += lengthPXD(pxd);
@@ -1304,7 +1304,7 @@ xtSplitPage(tid_t tid, struct inode *ip,
        skip = split->index;
 
        /*
-        *      sequential append at tail (after last entry of last page)
+        *      sequential append at tail (after last entry of last page)
         *
         * if splitting the last page on a level because of appending
         * a entry to it (skip is maxentry), it's likely that the access is
@@ -1342,7 +1342,7 @@ xtSplitPage(tid_t tid, struct inode *ip,
        }
 
        /*
-        *      non-sequential insert (at possibly middle page)
+        *      non-sequential insert (at possibly middle page)
         */
 
        /*
@@ -1465,25 +1465,24 @@ xtSplitPage(tid_t tid, struct inode *ip,
 
 
 /*
- *      xtSplitRoot()
+ *     xtSplitRoot()
  *
  * function:
- *      split the full root page into
- *      original/root/split page and new right page
- *      i.e., root remains fixed in tree anchor (inode) and
- *      the root is copied to a single new right child page
- *      since root page << non-root page, and
- *      the split root page contains a single entry for the
- *      new right child page.
+ *     split the full root page into original/root/split page and new
+ *     right page
+ *     i.e., root remains fixed in tree anchor (inode) and the root is
+ *     copied to a single new right child page since root page <<
+ *     non-root page, and the split root page contains a single entry
+ *     for the new right child page.
  *
  * parameter:
- *      int            tid,
- *      struct inode    *ip,
- *      struct xtsplit  *split,
- *      struct metapage        **rmpp)
+ *     int             tid,
+ *     struct inode    *ip,
+ *     struct xtsplit  *split,
+ *     struct metapage **rmpp)
  *
  * return:
- *      Pointer to page in which to insert or NULL on error.
+ *     Pointer to page in which to insert or NULL on error.
  */
 static int
 xtSplitRoot(tid_t tid,
@@ -1505,7 +1504,7 @@ xtSplitRoot(tid_t tid,
        INCREMENT(xtStat.split);
 
        /*
-        *      allocate a single (right) child page
+        *      allocate a single (right) child page
         */
        pxdlist = split->pxdlist;
        pxd = &pxdlist->pxd[pxdlist->npxd];
@@ -1573,7 +1572,7 @@ xtSplitRoot(tid_t tid,
        }
 
        /*
-        *      reset the root
+        *      reset the root
         *
         * init root with the single entry for the new right page
         * set the 1st entry offset to 0, which force the left-most key
@@ -1610,7 +1609,7 @@ xtSplitRoot(tid_t tid,
 
 
 /*
- *      xtExtend()
+ *     xtExtend()
  *
  * function: extend in-place;
  *
@@ -1677,7 +1676,7 @@ int xtExtend(tid_t tid,           /* transaction id */
                goto extendOld;
 
        /*
-        *      extent overflow: insert entry for new extent
+        *      extent overflow: insert entry for new extent
         */
 //insertNew:
        xoff = offsetXAD(xad) + MAXXLEN;
@@ -1685,8 +1684,8 @@ int xtExtend(tid_t tid,           /* transaction id */
        nextindex = le16_to_cpu(p->header.nextindex);
 
        /*
-        *      if the leaf page is full, insert the new entry and
-        *      propagate up the router entry for the new page from split
+        *      if the leaf page is full, insert the new entry and
+        *      propagate up the router entry for the new page from split
         *
         * The xtSplitUp() will insert the entry and unpin the leaf page.
         */
@@ -1731,7 +1730,7 @@ int xtExtend(tid_t tid,           /* transaction id */
                }
        }
        /*
-        *      insert the new entry into the leaf page
+        *      insert the new entry into the leaf page
         */
        else {
                /* insert the new entry: mark the entry NEW */
@@ -1771,11 +1770,11 @@ int xtExtend(tid_t tid,         /* transaction id */
 
 #ifdef _NOTYET
 /*
- *      xtTailgate()
+ *     xtTailgate()
  *
  * function: split existing 'tail' extent
- *      (split offset >= start offset of tail extent), and
- *      relocate and extend the split tail half;
+ *     (split offset >= start offset of tail extent), and
+ *     relocate and extend the split tail half;
  *
  * note: existing extent may or may not have been committed.
  * caller is responsible for pager buffer cache update, and
@@ -1804,7 +1803,7 @@ int xtTailgate(tid_t tid,         /* transaction id */
 
 /*
 printf("xtTailgate: nxoff:0x%lx nxlen:0x%x nxaddr:0x%lx\n",
-        (ulong)xoff, xlen, (ulong)xaddr);
+       (ulong)xoff, xlen, (ulong)xaddr);
 */
 
        /* there must exist extent to be tailgated */
@@ -1842,18 +1841,18 @@ printf("xtTailgate: nxoff:0x%lx nxlen:0x%x nxaddr:0x%lx\n",
        xad = &p->xad[index];
 /*
 printf("xtTailgate: xoff:0x%lx xlen:0x%x xaddr:0x%lx\n",
-        (ulong)offsetXAD(xad), lengthXAD(xad), (ulong)addressXAD(xad));
+       (ulong)offsetXAD(xad), lengthXAD(xad), (ulong)addressXAD(xad));
 */
        if ((llen = xoff - offsetXAD(xad)) == 0)
                goto updateOld;
 
        /*
-        *      partially replace extent: insert entry for new extent
+        *      partially replace extent: insert entry for new extent
         */
 //insertNew:
        /*
-        *      if the leaf page is full, insert the new entry and
-        *      propagate up the router entry for the new page from split
+        *      if the leaf page is full, insert the new entry and
+        *      propagate up the router entry for the new page from split
         *
         * The xtSplitUp() will insert the entry and unpin the leaf page.
         */
@@ -1898,7 +1897,7 @@ printf("xtTailgate: xoff:0x%lx xlen:0x%x xaddr:0x%lx\n",
                }
        }
        /*
-        *      insert the new entry into the leaf page
+        *      insert the new entry into the leaf page
         */
        else {
                /* insert the new entry: mark the entry NEW */
@@ -1955,17 +1954,17 @@ printf("xtTailgate: xoff:0x%lx xlen:0x%x xaddr:0x%lx\n",
 #endif /* _NOTYET */
 
 /*
- *      xtUpdate()
+ *     xtUpdate()
  *
  * function: update XAD;
  *
- *      update extent for allocated_but_not_recorded or
- *      compressed extent;
+ *     update extent for allocated_but_not_recorded or
+ *     compressed extent;
  *
  * parameter:
- *      nxad    - new XAD;
- *                logical extent of the specified XAD must be completely
- *                contained by an existing XAD;
+ *     nxad    - new XAD;
+ *             logical extent of the specified XAD must be completely
+ *             contained by an existing XAD;
  */
 int xtUpdate(tid_t tid, struct inode *ip, xad_t * nxad)
 {                              /* new XAD */
@@ -2416,19 +2415,19 @@ printf("xtUpdate.updateLeft.split p:0x%p\n", p);
 
 
 /*
- *      xtAppend()
+ *     xtAppend()
  *
  * function: grow in append mode from contiguous region specified ;
  *
  * parameter:
- *      tid             - transaction id;
- *      ip              - file object;
- *      xflag           - extent flag:
- *      xoff            - extent offset;
- *      maxblocks       - max extent length;
- *      xlen            - extent length (in/out);
- *      xaddrp          - extent address pointer (in/out):
- *      flag            -
+ *     tid             - transaction id;
+ *     ip              - file object;
+ *     xflag           - extent flag:
+ *     xoff            - extent offset;
+ *     maxblocks       - max extent length;
+ *     xlen            - extent length (in/out);
+ *     xaddrp          - extent address pointer (in/out):
+ *     flag            -
  *
  * return:
  */
@@ -2460,7 +2459,7 @@ int xtAppend(tid_t tid,           /* transaction id */
                 (ulong) xoff, maxblocks, xlen, (ulong) xaddr);
 
        /*
-        *      search for the entry location at which to insert:
+        *      search for the entry location at which to insert:
         *
         * xtFastSearch() and xtSearch() both returns (leaf page
         * pinned, index at which to insert).
@@ -2482,13 +2481,13 @@ int xtAppend(tid_t tid,         /* transaction id */
                xlen = min(xlen, (int)(next - xoff));
 //insert:
        /*
-        *      insert entry for new extent
+        *      insert entry for new extent
         */
        xflag |= XAD_NEW;
 
        /*
-        *      if the leaf page is full, split the page and
-        *      propagate up the router entry for the new page from split
+        *      if the leaf page is full, split the page and
+        *      propagate up the router entry for the new page from split
         *
         * The xtSplitUp() will insert the entry and unpin the leaf page.
         */
@@ -2545,7 +2544,7 @@ int xtAppend(tid_t tid,           /* transaction id */
        return 0;
 
        /*
-        *      insert the new entry into the leaf page
+        *      insert the new entry into the leaf page
         */
       insertLeaf:
        /*
@@ -2589,17 +2588,17 @@ int xtAppend(tid_t tid,         /* transaction id */
 
 /* - TBD for defragmentaion/reorganization -
  *
- *      xtDelete()
+ *     xtDelete()
  *
  * function:
- *      delete the entry with the specified key.
+ *     delete the entry with the specified key.
  *
- *      N.B.: whole extent of the entry is assumed to be deleted.
+ *     N.B.: whole extent of the entry is assumed to be deleted.
  *
  * parameter:
  *
  * return:
- *       ENOENT: if the entry is not found.
+ *     ENOENT: if the entry is not found.
  *
  * exception:
  */
@@ -2665,10 +2664,10 @@ int xtDelete(tid_t tid, struct inode *ip, s64 xoff, s32 xlen, int flag)
 
 /* - TBD for defragmentaion/reorganization -
  *
- *      xtDeleteUp()
+ *     xtDeleteUp()
  *
  * function:
- *      free empty pages as propagating deletion up the tree
+ *     free empty pages as propagating deletion up the tree
  *
  * parameter:
  *
@@ -2815,15 +2814,15 @@ xtDeleteUp(tid_t tid, struct inode *ip,
 
 
 /*
- * NAME:        xtRelocate()
+ * NAME:       xtRelocate()
  *
- * FUNCTION:    relocate xtpage or data extent of regular file;
- *              This function is mainly used by defragfs utility.
+ * FUNCTION:   relocate xtpage or data extent of regular file;
+ *             This function is mainly used by defragfs utility.
  *
- * NOTE:        This routine does not have the logic to handle
- *              uncommitted allocated extent. The caller should call
- *              txCommit() to commit all the allocation before call
- *              this routine.
+ * NOTE:       This routine does not have the logic to handle
+ *             uncommitted allocated extent. The caller should call
+ *             txCommit() to commit all the allocation before call
+ *             this routine.
  */
 int
 xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */
@@ -2865,8 +2864,8 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad,    /* old XAD */
                 xtype, (ulong) xoff, xlen, (ulong) oxaddr, (ulong) nxaddr);
 
        /*
-        *      1. get and validate the parent xtpage/xad entry
-        *      covering the source extent to be relocated;
+        *      1. get and validate the parent xtpage/xad entry
+        *      covering the source extent to be relocated;
         */
        if (xtype == DATAEXT) {
                /* search in leaf entry */
@@ -2910,7 +2909,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad,    /* old XAD */
        jfs_info("xtRelocate: parent xad entry validated.");
 
        /*
-        *      2. relocate the extent
+        *      2. relocate the extent
         */
        if (xtype == DATAEXT) {
                /* if the extent is allocated-but-not-recorded
@@ -2923,7 +2922,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad,    /* old XAD */
                        XT_PUTPAGE(pmp);
 
                /*
-                *      cmRelocate()
+                *      cmRelocate()
                 *
                 * copy target data pages to be relocated;
                 *
@@ -2945,8 +2944,8 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad,    /* old XAD */
                pno = offset >> CM_L2BSIZE;
                npages = (nbytes + (CM_BSIZE - 1)) >> CM_L2BSIZE;
 /*
-                npages = ((offset + nbytes - 1) >> CM_L2BSIZE) -
-                         (offset >> CM_L2BSIZE) + 1;
+               npages = ((offset + nbytes - 1) >> CM_L2BSIZE) -
+                         (offset >> CM_L2BSIZE) + 1;
 */
                sxaddr = oxaddr;
                dxaddr = nxaddr;
@@ -2981,7 +2980,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad,    /* old XAD */
 
                XT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index);
                jfs_info("xtRelocate: target data extent relocated.");
-       } else {                /* (xtype  == XTPAGE) */
+       } else {                /* (xtype == XTPAGE) */
 
                /*
                 * read in the target xtpage from the source extent;
@@ -3026,16 +3025,14 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad,  /* old XAD */
                 */
                if (lmp) {
                        BT_MARK_DIRTY(lmp, ip);
-                       tlck =
-                           txLock(tid, ip, lmp, tlckXTREE | tlckRELINK);
+                       tlck = txLock(tid, ip, lmp, tlckXTREE | tlckRELINK);
                        lp->header.next = cpu_to_le64(nxaddr);
                        XT_PUTPAGE(lmp);
                }
 
                if (rmp) {
                        BT_MARK_DIRTY(rmp, ip);
-                       tlck =
-                           txLock(tid, ip, rmp, tlckXTREE | tlckRELINK);
+                       tlck = txLock(tid, ip, rmp, tlckXTREE | tlckRELINK);
                        rp->header.prev = cpu_to_le64(nxaddr);
                        XT_PUTPAGE(rmp);
                }
@@ -3062,7 +3059,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad,    /* old XAD */
                 * scan may be skipped by commit() and logredo();
                 */
                BT_MARK_DIRTY(mp, ip);
-               /* tlckNEW init  xtlck->lwm.offset = XTENTRYSTART; */
+               /* tlckNEW init xtlck->lwm.offset = XTENTRYSTART; */
                tlck = txLock(tid, ip, mp, tlckXTREE | tlckNEW);
                xtlck = (struct xtlock *) & tlck->lock;
 
@@ -3084,7 +3081,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad,    /* old XAD */
        }
 
        /*
-        *      3. acquire maplock for the source extent to be freed;
+        *      3. acquire maplock for the source extent to be freed;
         *
         * acquire a maplock saving the src relocated extent address;
         * to free of the extent at commit time;
@@ -3105,7 +3102,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad,    /* old XAD */
         *      is no buffer associated with this lock since the buffer
         *      has been redirected to the target location.
         */
-       else                    /* (xtype  == XTPAGE) */
+       else                    /* (xtype == XTPAGE) */
                tlck = txMaplock(tid, ip, tlckMAP | tlckRELOCATE);
 
        pxdlock = (struct pxd_lock *) & tlck->lock;
@@ -3115,7 +3112,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad,    /* old XAD */
        pxdlock->index = 1;
 
        /*
-        *      4. update the parent xad entry for relocation;
+        *      4. update the parent xad entry for relocation;
         *
         * acquire tlck for the parent entry with XAD_NEW as entry
         * update which will write LOG_REDOPAGE and update bmap for
@@ -3143,22 +3140,22 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad,  /* old XAD */
 
 
 /*
- *      xtSearchNode()
+ *     xtSearchNode()
  *
- * function:    search for the internal xad entry covering specified extent.
- *              This function is mainly used by defragfs utility.
+ * function:   search for the internal xad entry covering specified extent.
+ *             This function is mainly used by defragfs utility.
  *
  * parameters:
- *      ip      - file object;
- *      xad     - extent to find;
- *      cmpp    - comparison result:
- *      btstack - traverse stack;
- *      flag    - search process flag;
+ *     ip      - file object;
+ *     xad     - extent to find;
+ *     cmpp    - comparison result:
+ *     btstack - traverse stack;
+ *     flag    - search process flag;
  *
  * returns:
- *      btstack contains (bn, index) of search path traversed to the entry.
- *      *cmpp is set to result of comparison with the entry returned.
- *      the page containing the entry is pinned at exit.
+ *     btstack contains (bn, index) of search path traversed to the entry.
+ *     *cmpp is set to result of comparison with the entry returned.
+ *     the page containing the entry is pinned at exit.
  */
 static int xtSearchNode(struct inode *ip, xad_t * xad, /* required XAD entry */
                        int *cmpp, struct btstack * btstack, int flag)
@@ -3181,7 +3178,7 @@ static int xtSearchNode(struct inode *ip, xad_t * xad,    /* required XAD entry */
        xaddr = addressXAD(xad);
 
        /*
-        *      search down tree from root:
+        *      search down tree from root:
         *
         * between two consecutive entries of <Ki, Pi> and <Kj, Pj> of
         * internal page, child page Pi contains entry with k, Ki <= K < Kj.
@@ -3217,7 +3214,7 @@ static int xtSearchNode(struct inode *ip, xad_t * xad,    /* required XAD entry */
                        XT_CMP(cmp, xoff, &p->xad[index], t64);
                        if (cmp == 0) {
                                /*
-                                *      search hit
+                                *      search hit
                                 *
                                 * verify for exact match;
                                 */
@@ -3245,7 +3242,7 @@ static int xtSearchNode(struct inode *ip, xad_t * xad,    /* required XAD entry */
                }
 
                /*
-                *      search miss - non-leaf page:
+                *      search miss - non-leaf page:
                 *
                 * base is the smallest index with key (Kj) greater than
                 * search key (K) and may be zero or maxentry index.
@@ -3268,15 +3265,15 @@ static int xtSearchNode(struct inode *ip, xad_t * xad,  /* required XAD entry */
 
 
 /*
- *      xtRelink()
+ *     xtRelink()
  *
  * function:
- *      link around a freed page.
+ *     link around a freed page.
  *
  * Parameter:
- *      int           tid,
- *      struct inode    *ip,
- *      xtpage_t        *p)
+ *     int             tid,
+ *     struct inode    *ip,
+ *     xtpage_t        *p)
  *
  * returns:
  */
@@ -3338,7 +3335,7 @@ static int xtRelink(tid_t tid, struct inode *ip, xtpage_t * p)
 
 
 /*
- *      xtInitRoot()
+ *     xtInitRoot()
  *
  * initialize file root (inline in inode)
  */
@@ -3385,42 +3382,42 @@ void xtInitRoot(tid_t tid, struct inode *ip)
 #define MAX_TRUNCATE_LEAVES 50
 
 /*
- *      xtTruncate()
+ *     xtTruncate()
  *
  * function:
- *      traverse for truncation logging backward bottom up;
- *      terminate at the last extent entry at the current subtree
- *      root page covering new down size.
- *      truncation may occur within the last extent entry.
+ *     traverse for truncation logging backward bottom up;
+ *     terminate at the last extent entry at the current subtree
+ *     root page covering new down size.
+ *     truncation may occur within the last extent entry.
  *
  * parameter:
- *      int           tid,
- *      struct inode    *ip,
- *      s64           newsize,
- *      int           type)   {PWMAP, PMAP, WMAP; DELETE, TRUNCATE}
+ *     int             tid,
+ *     struct inode    *ip,
+ *     s64             newsize,
+ *     int             type)   {PWMAP, PMAP, WMAP; DELETE, TRUNCATE}
  *
  * return:
  *
  * note:
- *      PWMAP:
- *       1. truncate (non-COMMIT_NOLINK file)
- *          by jfs_truncate() or jfs_open(O_TRUNC):
- *          xtree is updated;
+ *     PWMAP:
+ *      1. truncate (non-COMMIT_NOLINK file)
+ *         by jfs_truncate() or jfs_open(O_TRUNC):
+ *         xtree is updated;
  *      2. truncate index table of directory when last entry removed
- *       map update via tlock at commit time;
- *      PMAP:
+ *     map update via tlock at commit time;
+ *     PMAP:
  *      Call xtTruncate_pmap instead
- *      WMAP:
- *       1. remove (free zero link count) on last reference release
- *          (pmap has been freed at commit zero link count);
- *       2. truncate (COMMIT_NOLINK file, i.e., tmp file):
- *          xtree is updated;
- *       map update directly at truncation time;
+ *     WMAP:
+ *      1. remove (free zero link count) on last reference release
+ *         (pmap has been freed at commit zero link count);
+ *      2. truncate (COMMIT_NOLINK file, i.e., tmp file):
+ *         xtree is updated;
+ *      map update directly at truncation time;
  *
- *      if (DELETE)
- *              no LOG_NOREDOPAGE is required (NOREDOFILE is sufficient);
- *      else if (TRUNCATE)
- *              must write LOG_NOREDOPAGE for deleted index page;
+ *     if (DELETE)
+ *             no LOG_NOREDOPAGE is required (NOREDOFILE is sufficient);
+ *     else if (TRUNCATE)
+ *             must write LOG_NOREDOPAGE for deleted index page;
  *
  * pages may already have been tlocked by anonymous transactions
  * during file growth (i.e., write) before truncation;
@@ -3493,7 +3490,7 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag)
         * retained in the new sized file.
         * if type is PMAP, the data and index pages are NOT
         * freed, and the data and index blocks are NOT freed
-        * from  working map.
+        * from working map.
         * (this will allow continued access of data/index of
         * temporary file (zerolink count file truncated to zero-length)).
         */
@@ -3542,7 +3539,7 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag)
                goto getChild;
 
        /*
-        *      leaf page
+        *      leaf page
         */
        freed = 0;
 
@@ -3916,7 +3913,7 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag)
        }
 
        /*
-        *      internal page: go down to child page of current entry
+        *      internal page: go down to child page of current entry
         */
       getChild:
        /* save current parent entry for the child page */
@@ -3965,7 +3962,7 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag)
 
 
 /*
- *      xtTruncate_pmap()
+ *     xtTruncate_pmap()
  *
  * function:
  *     Perform truncate to zero lenghth for deleted file, leaving the
@@ -3974,9 +3971,9 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag)
  *     is committed to disk.
  *
  * parameter:
- *      tid_t          tid,
- *      struct inode   *ip,
- *      s64            committed_size)
+ *     tid_t           tid,
+ *     struct inode    *ip,
+ *     s64             committed_size)
  *
  * return: new committed size
  *
@@ -4050,7 +4047,7 @@ s64 xtTruncate_pmap(tid_t tid, struct inode *ip, s64 committed_size)
        }
 
        /*
-        *      leaf page
+        *      leaf page
         */
 
        if (++locked_leaves > MAX_TRUNCATE_LEAVES) {
@@ -4062,7 +4059,7 @@ s64 xtTruncate_pmap(tid_t tid, struct inode *ip, s64 committed_size)
                xoff = offsetXAD(xad);
                xlen = lengthXAD(xad);
                XT_PUTPAGE(mp);
-               return  (xoff + xlen) << JFS_SBI(ip->i_sb)->l2bsize;
+               return (xoff + xlen) << JFS_SBI(ip->i_sb)->l2bsize;
        }
        tlck = txLock(tid, ip, mp, tlckXTREE);
        tlck->type = tlckXTREE | tlckFREE;
@@ -4099,8 +4096,7 @@ s64 xtTruncate_pmap(tid_t tid, struct inode *ip, s64 committed_size)
                 */
                tlck = txLock(tid, ip, mp, tlckXTREE);
                xtlck = (struct xtlock *) & tlck->lock;
-               xtlck->hwm.offset =
-                   le16_to_cpu(p->header.nextindex) - 1;
+               xtlck->hwm.offset = le16_to_cpu(p->header.nextindex) - 1;
                tlck->type = tlckXTREE | tlckFREE;
 
                XT_PUTPAGE(mp);
@@ -4118,7 +4114,7 @@ s64 xtTruncate_pmap(tid_t tid, struct inode *ip, s64 committed_size)
        else
                index--;
        /*
-        *      internal page: go down to child page of current entry
+        *      internal page: go down to child page of current entry
         */
       getChild:
        /* save current parent entry for the child page */
index 164f6f2b10191055bdb10522e9d1ff17603f3df5..70815c8a3d6a9114c481e6276b5fe8d35aacbfb2 100644 (file)
 #define _H_JFS_XTREE
 
 /*
- *      jfs_xtree.h: extent allocation descriptor B+-tree manager
+ *     jfs_xtree.h: extent allocation descriptor B+-tree manager
  */
 
 #include "jfs_btree.h"
 
 
 /*
- *      extent allocation descriptor (xad)
+ *     extent allocation descriptor (xad)
  */
 typedef struct xad {
        unsigned flag:8;        /* 1: flag */
@@ -38,30 +38,30 @@ typedef struct xad {
        __le32 addr2;           /* 4: address in unit of fsblksize */
 } xad_t;                       /* (16) */
 
-#define MAXXLEN         ((1 << 24) - 1)
+#define MAXXLEN                ((1 << 24) - 1)
 
-#define XTSLOTSIZE      16
-#define L2XTSLOTSIZE    4
+#define XTSLOTSIZE     16
+#define L2XTSLOTSIZE   4
 
 /* xad_t field construction */
 #define XADoffset(xad, offset64)\
 {\
-        (xad)->off1 = ((u64)offset64) >> 32;\
-        (xad)->off2 = __cpu_to_le32((offset64) & 0xffffffff);\
+       (xad)->off1 = ((u64)offset64) >> 32;\
+       (xad)->off2 = __cpu_to_le32((offset64) & 0xffffffff);\
 }
 #define XADaddress(xad, address64)\
 {\
-        (xad)->addr1 = ((u64)address64) >> 32;\
-        (xad)->addr2 = __cpu_to_le32((address64) & 0xffffffff);\
+       (xad)->addr1 = ((u64)address64) >> 32;\
+       (xad)->addr2 = __cpu_to_le32((address64) & 0xffffffff);\
 }
-#define XADlength(xad, length32)        (xad)->len = __cpu_to_le24(length32)
+#define XADlength(xad, length32)       (xad)->len = __cpu_to_le24(length32)
 
 /* xad_t field extraction */
 #define offsetXAD(xad)\
-        ( ((s64)((xad)->off1)) << 32 | __le32_to_cpu((xad)->off2))
+       ( ((s64)((xad)->off1)) << 32 | __le32_to_cpu((xad)->off2))
 #define addressXAD(xad)\
-        ( ((s64)((xad)->addr1)) << 32 | __le32_to_cpu((xad)->addr2))
-#define lengthXAD(xad)  __le24_to_cpu((xad)->len)
+       ( ((s64)((xad)->addr1)) << 32 | __le32_to_cpu((xad)->addr2))
+#define lengthXAD(xad) __le24_to_cpu((xad)->len)
 
 /* xad list */
 struct xadlist {
@@ -71,22 +71,22 @@ struct xadlist {
 };
 
 /* xad_t flags */
-#define XAD_NEW         0x01   /* new */
-#define XAD_EXTENDED    0x02   /* extended */
-#define XAD_COMPRESSED  0x04   /* compressed with recorded length */
+#define XAD_NEW                0x01    /* new */
+#define XAD_EXTENDED   0x02    /* extended */
+#define XAD_COMPRESSED 0x04    /* compressed with recorded length */
 #define XAD_NOTRECORDED 0x08   /* allocated but not recorded */
-#define XAD_COW         0x10   /* copy-on-write */
+#define XAD_COW                0x10    /* copy-on-write */
 
 
 /* possible values for maxentry */
-#define XTROOTINITSLOT_DIR  6
-#define XTROOTINITSLOT  10
-#define XTROOTMAXSLOT   18
-#define XTPAGEMAXSLOT   256
-#define XTENTRYSTART    2
+#define XTROOTINITSLOT_DIR 6
+#define XTROOTINITSLOT 10
+#define XTROOTMAXSLOT  18
+#define XTPAGEMAXSLOT  256
+#define XTENTRYSTART   2
 
 /*
- *      xtree page:
+ *     xtree page:
  */
 typedef union {
        struct xtheader {
@@ -106,7 +106,7 @@ typedef union {
 } xtpage_t;
 
 /*
- *      external declaration
+ *     external declaration
  */
 extern int xtLookup(struct inode *ip, s64 lstart, s64 llen,
                    int *pflag, s64 * paddr, int *plen, int flag);
index 41c20477126237384bcf4421a0a6ae42765adbe7..25161c4121e4ba4f677bd1ed73abc8dcbc003d3d 100644 (file)
@@ -328,7 +328,7 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
  *             dentry  - child directory dentry
  *
  * RETURN:     -EINVAL - if name is . or ..
- *             -EINVAL  - if . or .. exist but are invalid.
+ *             -EINVAL - if . or .. exist but are invalid.
  *             errors from subroutines
  *
  * note:
@@ -517,7 +517,7 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry)
        inode_dec_link_count(ip);
 
        /*
-        *      commit zero link count object
+        *      commit zero link count object
         */
        if (ip->i_nlink == 0) {
                assert(!test_cflag(COMMIT_Nolink, ip));
@@ -596,7 +596,7 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry)
 /*
  * NAME:       commitZeroLink()
  *
- * FUNCTION:    for non-directory, called by jfs_remove(),
+ * FUNCTION:   for non-directory, called by jfs_remove(),
  *             truncate a regular file, directory or symbolic
  *             link to zero length. return 0 if type is not
  *             one of these.
@@ -676,7 +676,7 @@ static s64 commitZeroLink(tid_t tid, struct inode *ip)
 /*
  * NAME:       jfs_free_zero_link()
  *
- * FUNCTION:    for non-directory, called by iClose(),
+ * FUNCTION:   for non-directory, called by iClose(),
  *             free resources of a file from cache and WORKING map
  *             for a file previously committed with zero link count
  *             while associated with a pager object,
@@ -855,12 +855,12 @@ static int jfs_link(struct dentry *old_dentry,
  * NAME:       jfs_symlink(dip, dentry, name)
  *
  * FUNCTION:   creates a symbolic link to <symlink> by name <name>
- *                     in directory <dip>
+ *                     in directory <dip>
  *
- * PARAMETER:  dip         - parent directory vnode
- *                     dentry  - dentry of symbolic link
- *                     name    - the path name of the existing object
- *                                   that will be the source of the link
+ * PARAMETER:  dip     - parent directory vnode
+ *             dentry  - dentry of symbolic link
+ *             name    - the path name of the existing object
+ *                       that will be the source of the link
  *
  * RETURN:     errors from subroutines
  *
@@ -1052,9 +1052,9 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
 
 
 /*
- * NAME:        jfs_rename
+ * NAME:       jfs_rename
  *
- * FUNCTION:    rename a file or directory
+ * FUNCTION:   rename a file or directory
  */
 static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
               struct inode *new_dir, struct dentry *new_dentry)
@@ -1331,9 +1331,9 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
 
 
 /*
- * NAME:        jfs_mknod
+ * NAME:       jfs_mknod
  *
- * FUNCTION:    Create a special file (device)
+ * FUNCTION:   Create a special file (device)
  */
 static int jfs_mknod(struct inode *dir, struct dentry *dentry,
                int mode, dev_t rdev)
index 79d625f3f7336f555acb604ca30966819b97e5d0..71984ee95346cd214cdab467e71a646cc496b279 100644 (file)
 #include "jfs_txnmgr.h"
 #include "jfs_debug.h"
 
-#define BITSPERPAGE     (PSIZE << 3)
-#define L2MEGABYTE      20
-#define MEGABYTE        (1 << L2MEGABYTE)
-#define MEGABYTE32     (MEGABYTE << 5)
+#define BITSPERPAGE    (PSIZE << 3)
+#define L2MEGABYTE     20
+#define MEGABYTE       (1 << L2MEGABYTE)
+#define MEGABYTE32     (MEGABYTE << 5)
 
 /* convert block number to bmap file page number */
 #define BLKTODMAPN(b)\
-        (((b) >> 13) + ((b) >> 23) + ((b) >> 33) + 3 + 1)
+       (((b) >> 13) + ((b) >> 23) + ((b) >> 33) + 3 + 1)
 
 /*
- *      jfs_extendfs()
+ *     jfs_extendfs()
  *
  * function: extend file system;
  *
@@ -48,9 +48,9 @@
  *                                   workspace  space
  *
  * input:
- *      new LVSize: in LV blocks (required)
- *      new LogSize: in LV blocks (optional)
- *      new FSSize: in LV blocks (optional)
+ *     new LVSize: in LV blocks (required)
+ *     new LogSize: in LV blocks (optional)
+ *     new FSSize: in LV blocks (optional)
  *
  * new configuration:
  * 1. set new LogSize as specified or default from new LVSize;
@@ -125,8 +125,8 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
        }
 
        /*
-        *      reconfigure LV spaces
-        *      ---------------------
+        *      reconfigure LV spaces
+        *      ---------------------
         *
         * validate new size, or, if not specified, determine new size
         */
@@ -198,7 +198,7 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
                log_formatted = 1;
        }
        /*
-        *      quiesce file system
+        *      quiesce file system
         *
         * (prepare to move the inline log and to prevent map update)
         *
@@ -270,8 +270,8 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
        }
 
        /*
-        *      extend block allocation map
-        *      ---------------------------
+        *      extend block allocation map
+        *      ---------------------------
         *
         * extendfs() for new extension, retry after crash recovery;
         *
@@ -283,7 +283,7 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
         *  s_size: aggregate size in physical blocks;
         */
        /*
-        *      compute the new block allocation map configuration
+        *      compute the new block allocation map configuration
         *
         * map dinode:
         *  di_size: map file size in byte;
@@ -301,7 +301,7 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
        newNpages = BLKTODMAPN(t64) + 1;
 
        /*
-        *      extend map from current map (WITHOUT growing mapfile)
+        *      extend map from current map (WITHOUT growing mapfile)
         *
         * map new extension with unmapped part of the last partial
         * dmap page, if applicable, and extra page(s) allocated
@@ -341,8 +341,8 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
        XSize -= nblocks;
 
        /*
-        *      grow map file to cover remaining extension
-        *      and/or one extra dmap page for next extendfs();
+        *      grow map file to cover remaining extension
+        *      and/or one extra dmap page for next extendfs();
         *
         * allocate new map pages and its backing blocks, and
         * update map file xtree
@@ -422,8 +422,8 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
        dbFinalizeBmap(ipbmap);
 
        /*
-        *      update inode allocation map
-        *      ---------------------------
+        *      update inode allocation map
+        *      ---------------------------
         *
         * move iag lists from old to new iag;
         * agstart field is not updated for logredo() to reconstruct
@@ -442,8 +442,8 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
        }
 
        /*
-        *      finalize
-        *      --------
+        *      finalize
+        *      --------
         *
         * extension is committed when on-disk super block is
         * updated with new descriptors: logredo will recover
@@ -480,7 +480,7 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
        diFreeSpecial(ipbmap2);
 
        /*
-        *      update superblock
+        *      update superblock
         */
        if ((rc = readSuper(sb, &bh)))
                goto error_out;
@@ -530,7 +530,7 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
 
       resume:
        /*
-        *      resume file system transactions
+        *      resume file system transactions
         */
        txResume(sb);
 
index b753ba2164508a997763ae09d60d3e59a1725ce3..b2375f0774b72c89cb602358735a0fed289206f7 100644 (file)
@@ -63,9 +63,9 @@
  *
  *   On-disk:
  *
- *     FEALISTs are stored on disk using blocks allocated by dbAlloc() and
- *     written directly. An EA list may be in-lined in the inode if there is
- *     sufficient room available.
+ *     FEALISTs are stored on disk using blocks allocated by dbAlloc() and
+ *     written directly. An EA list may be in-lined in the inode if there is
+ *     sufficient room available.
  */
 
 struct ea_buffer {
@@ -590,7 +590,8 @@ static int ea_get(struct inode *inode, struct ea_buffer *ea_buf, int min_size)
       size_check:
        if (EALIST_SIZE(ea_buf->xattr) != ea_size) {
                printk(KERN_ERR "ea_get: invalid extended attribute\n");
-               dump_mem("xattr", ea_buf->xattr, ea_size);
+               print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 16, 1,
+                                    ea_buf->xattr, ea_size, 1);
                ea_release(inode, ea_buf);
                rc = -EIO;
                goto clean_up;
index f92baa1d757053cd7f1b3964bf73cafcd74f7047..17765f697e50f68f7a29906b8f4aef36709abb29 100644 (file)
@@ -23,7 +23,7 @@ const struct file_operations minix_file_operations = {
        .aio_write      = generic_file_aio_write,
        .mmap           = generic_file_mmap,
        .fsync          = minix_sync_file,
-       .sendfile       = generic_file_sendfile,
+       .splice_read    = generic_file_splice_read,
 };
 
 const struct inode_operations minix_file_inode_operations = {
index 9eb8eb4e4a08df9db62c8301d8c4622df45bf10c..8689b736fdd98cfa8b648f92e9922c52499a6fb3 100644 (file)
@@ -41,7 +41,9 @@ static int nfs_file_open(struct inode *, struct file *);
 static int nfs_file_release(struct inode *, struct file *);
 static loff_t nfs_file_llseek(struct file *file, loff_t offset, int origin);
 static int  nfs_file_mmap(struct file *, struct vm_area_struct *);
-static ssize_t nfs_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *);
+static ssize_t nfs_file_splice_read(struct file *filp, loff_t *ppos,
+                                       struct pipe_inode_info *pipe,
+                                       size_t count, unsigned int flags);
 static ssize_t nfs_file_read(struct kiocb *, const struct iovec *iov,
                                unsigned long nr_segs, loff_t pos);
 static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov,
@@ -65,7 +67,7 @@ const struct file_operations nfs_file_operations = {
        .fsync          = nfs_fsync,
        .lock           = nfs_lock,
        .flock          = nfs_flock,
-       .sendfile       = nfs_file_sendfile,
+       .splice_read    = nfs_file_splice_read,
        .check_flags    = nfs_check_flags,
 };
 
@@ -224,20 +226,21 @@ nfs_file_read(struct kiocb *iocb, const struct iovec *iov,
 }
 
 static ssize_t
-nfs_file_sendfile(struct file *filp, loff_t *ppos, size_t count,
-               read_actor_t actor, void *target)
+nfs_file_splice_read(struct file *filp, loff_t *ppos,
+                    struct pipe_inode_info *pipe, size_t count,
+                    unsigned int flags)
 {
        struct dentry *dentry = filp->f_path.dentry;
        struct inode *inode = dentry->d_inode;
        ssize_t res;
 
-       dfprintk(VFS, "nfs: sendfile(%s/%s, %lu@%Lu)\n",
+       dfprintk(VFS, "nfs: splice_read(%s/%s, %lu@%Lu)\n",
                dentry->d_parent->d_name.name, dentry->d_name.name,
                (unsigned long) count, (unsigned long long) *ppos);
 
        res = nfs_revalidate_mapping(inode, filp->f_mapping);
        if (!res)
-               res = generic_file_sendfile(filp, ppos, count, actor, target);
+               res = generic_file_splice_read(filp, ppos, pipe, count, flags);
        return res;
 }
 
index 7e6aa245b5d5f30b270c5336267eb77760be41ac..8604e35bd48e2d5966a244f1763f62def303dc0a 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/file.h>
 #include <linux/mount.h>
 #include <linux/major.h>
-#include <linux/ext2_fs.h>
+#include <linux/splice.h>
 #include <linux/proc_fs.h>
 #include <linux/stat.h>
 #include <linux/fcntl.h>
@@ -801,26 +801,32 @@ found:
 }
 
 /*
- * Grab and keep cached pages assosiated with a file in the svc_rqst
- * so that they can be passed to the netowork sendmsg/sendpage routines
- * directrly. They will be released after the sending has completed.
+ * Grab and keep cached pages associated with a file in the svc_rqst
+ * so that they can be passed to the network sendmsg/sendpage routines
+ * directly. They will be released after the sending has completed.
  */
 static int
-nfsd_read_actor(read_descriptor_t *desc, struct page *page, unsigned long offset , unsigned long size)
+nfsd_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
+                 struct splice_desc *sd)
 {
-       unsigned long count = desc->count;
-       struct svc_rqst *rqstp = desc->arg.data;
+       struct svc_rqst *rqstp = sd->u.data;
        struct page **pp = rqstp->rq_respages + rqstp->rq_resused;
+       struct page *page = buf->page;
+       size_t size;
+       int ret;
+
+       ret = buf->ops->confirm(pipe, buf);
+       if (unlikely(ret))
+               return ret;
 
-       if (size > count)
-               size = count;
+       size = sd->len;
 
        if (rqstp->rq_res.page_len == 0) {
                get_page(page);
                put_page(*pp);
                *pp = page;
                rqstp->rq_resused++;
-               rqstp->rq_res.page_base = offset;
+               rqstp->rq_res.page_base = buf->offset;
                rqstp->rq_res.page_len = size;
        } else if (page != pp[-1]) {
                get_page(page);
@@ -832,11 +838,15 @@ nfsd_read_actor(read_descriptor_t *desc, struct page *page, unsigned long offset
        } else
                rqstp->rq_res.page_len += size;
 
-       desc->count = count - size;
-       desc->written += size;
        return size;
 }
 
+static int nfsd_direct_splice_actor(struct pipe_inode_info *pipe,
+                                   struct splice_desc *sd)
+{
+       return __splice_from_pipe(pipe, sd, nfsd_splice_actor);
+}
+
 static __be32
 nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
               loff_t offset, struct kvec *vec, int vlen, unsigned long *count)
@@ -861,10 +871,15 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
        if (ra && ra->p_set)
                file->f_ra = ra->p_ra;
 
-       if (file->f_op->sendfile && rqstp->rq_sendfile_ok) {
-               rqstp->rq_resused = 1;
-               host_err = file->f_op->sendfile(file, &offset, *count,
-                                                nfsd_read_actor, rqstp);
+       if (file->f_op->splice_read && rqstp->rq_splice_ok) {
+               struct splice_desc sd = {
+                       .len            = 0,
+                       .total_len      = *count,
+                       .pos            = offset,
+                       .u.data         = rqstp,
+               };
+
+               host_err = splice_direct_to_actor(file, &sd, nfsd_direct_splice_actor);
        } else {
                oldfs = get_fs();
                set_fs(KERNEL_DS);
index 7ed56390b5826798f3d67bded0781b7382fe25b3..ffcc504a1667be04daea41339c53cd16d7ca84e4 100644 (file)
@@ -2276,7 +2276,7 @@ const struct file_operations ntfs_file_ops = {
                                                    mounted filesystem. */
        .mmap           = generic_file_mmap,     /* Mmap file. */
        .open           = ntfs_file_open,        /* Open file. */
-       .sendfile       = generic_file_sendfile, /* Zero-copy data send with
+       .splice_read    = generic_file_splice_read /* Zero-copy data send with
                                                    the data source being on
                                                    the ntfs partition.  We do
                                                    not need to care about the
index 2b205f5d5790e73d281f6fbf7e298d2f7dc3b782..e9e042b93dbf520ed9dc2c4b64a0e1b96590c0a1 100644 (file)
@@ -74,7 +74,6 @@ struct mlog_attribute {
 #define define_mask(_name) {                   \
        .attr = {                               \
                .name = #_name,                 \
-               .owner = THIS_MODULE,           \
                .mode = S_IRUGO | S_IWUSR,      \
        },                                      \
        .mask = ML_##_name,                     \
index ac6c96431bbcb3a7687b522465e456d68246c002..4979b667571734c151a88b2a03f01db5e2b8c761 100644 (file)
@@ -31,7 +31,7 @@
 #include <linux/pagemap.h>
 #include <linux/uio.h>
 #include <linux/sched.h>
-#include <linux/pipe_fs_i.h>
+#include <linux/splice.h>
 #include <linux/mount.h>
 #include <linux/writeback.h>
 
@@ -1583,7 +1583,7 @@ static int ocfs2_splice_write_actor(struct pipe_inode_info *pipe,
        ssize_t copied = 0;
        struct ocfs2_splice_write_priv sp;
 
-       ret = buf->ops->pin(pipe, buf);
+       ret = buf->ops->confirm(pipe, buf);
        if (ret)
                goto out;
 
@@ -1604,7 +1604,7 @@ static int ocfs2_splice_write_actor(struct pipe_inode_info *pipe,
                 * might enter ocfs2_buffered_write_cluster() more
                 * than once, so keep track of our progress here.
                 */
-               copied = ocfs2_buffered_write_cluster(sd->file,
+               copied = ocfs2_buffered_write_cluster(sd->u.file,
                                                      (loff_t)sd->pos + total,
                                                      count,
                                                      ocfs2_map_and_write_splice_data,
@@ -1636,9 +1636,14 @@ static ssize_t __ocfs2_file_splice_write(struct pipe_inode_info *pipe,
        int ret, err;
        struct address_space *mapping = out->f_mapping;
        struct inode *inode = mapping->host;
-
-       ret = __splice_from_pipe(pipe, out, ppos, len, flags,
-                                ocfs2_splice_write_actor);
+       struct splice_desc sd = {
+               .total_len = len,
+               .flags = flags,
+               .pos = *ppos,
+               .u.file = out,
+       };
+
+       ret = __splice_from_pipe(pipe, &sd, ocfs2_splice_write_actor);
        if (ret > 0) {
                *ppos += ret;
 
@@ -1817,7 +1822,6 @@ const struct inode_operations ocfs2_special_file_iops = {
 const struct file_operations ocfs2_fops = {
        .read           = do_sync_read,
        .write          = do_sync_write,
-       .sendfile       = generic_file_sendfile,
        .mmap           = ocfs2_mmap,
        .fsync          = ocfs2_sync_file,
        .release        = ocfs2_file_release,
index 9a3a058f355365405911c3f1173209cfac30150d..98e0b85a9bb268cd6677af538dc153a61af2f7f6 100644 (file)
@@ -397,7 +397,6 @@ void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len,
                static struct attribute addpartattr = {
                        .name = "whole_disk",
                        .mode = S_IRUSR | S_IRGRP | S_IROTH,
-                       .owner = THIS_MODULE,
                };
 
                sysfs_create_file(&p->kobj, &addpartattr);
index 9f7ad4244f63d64ed723939c568fc88de53ae7c3..1e064c4a4f86017ed8fa8832fee08c2224cd09b6 100644 (file)
@@ -45,7 +45,7 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
 {
        int blocksize, offset, size,res;
        loff_t i_size;
-       dasd_information_t *info;
+       dasd_information2_t *info;
        struct hd_geometry *geo;
        char type[5] = {0,};
        char name[7] = {0,};
@@ -64,14 +64,17 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
        if (i_size == 0)
                goto out_exit;
 
-       if ((info = kmalloc(sizeof(dasd_information_t), GFP_KERNEL)) == NULL)
+       info = kmalloc(sizeof(dasd_information2_t), GFP_KERNEL);
+       if (info == NULL)
                goto out_exit;
-       if ((geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL)) == NULL)
+       geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL);
+       if (geo == NULL)
                goto out_nogeo;
-       if ((label = kmalloc(sizeof(union label_t), GFP_KERNEL)) == NULL)
+       label = kmalloc(sizeof(union label_t), GFP_KERNEL);
+       if (label == NULL)
                goto out_nolab;
 
-       if (ioctl_by_bdev(bdev, BIODASDINFO, (unsigned long)info) != 0 ||
+       if (ioctl_by_bdev(bdev, BIODASDINFO2, (unsigned long)info) != 0 ||
            ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)geo) != 0)
                goto out_freeall;
 
@@ -96,84 +99,108 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
        res = 1;
 
        /*
-        * Three different types: CMS1, VOL1 and LNX1/unlabeled
+        * Three different formats: LDL, CDL and unformated disk
+        *
+        * identified by info->format
+        *
+        * unformated disks we do not have to care about
         */
-       if (strncmp(type, "CMS1", 4) == 0) {
-               /*
-                * VM style CMS1 labeled disk
-                */
-               if (label->cms.disk_offset != 0) {
-                       printk("CMS1/%8s(MDSK):", name);
-                       /* disk is reserved minidisk */
-                       blocksize = label->cms.block_size;
-                       offset = label->cms.disk_offset;
-                       size = (label->cms.block_count - 1) * (blocksize >> 9);
+       if (info->format == DASD_FORMAT_LDL) {
+               if (strncmp(type, "CMS1", 4) == 0) {
+                       /*
+                        * VM style CMS1 labeled disk
+                        */
+                       if (label->cms.disk_offset != 0) {
+                               printk("CMS1/%8s(MDSK):", name);
+                               /* disk is reserved minidisk */
+                               blocksize = label->cms.block_size;
+                               offset = label->cms.disk_offset;
+                               size = (label->cms.block_count - 1)
+                                       * (blocksize >> 9);
+                       } else {
+                               printk("CMS1/%8s:", name);
+                               offset = (info->label_block + 1);
+                               size = i_size >> 9;
+                       }
                } else {
-                       printk("CMS1/%8s:", name);
+                       /*
+                        * Old style LNX1 or unlabeled disk
+                        */
+                       if (strncmp(type, "LNX1", 4) == 0)
+                               printk ("LNX1/%8s:", name);
+                       else
+                               printk("(nonl)");
                        offset = (info->label_block + 1);
                        size = i_size >> 9;
                }
                put_partition(state, 1, offset*(blocksize >> 9),
-                                size-offset*(blocksize >> 9));
-       } else if ((strncmp(type, "VOL1", 4) == 0) &&
-               (!info->FBA_layout) && (!strcmp(info->type, "ECKD"))) {
+                                     size-offset*(blocksize >> 9));
+       } else if (info->format == DASD_FORMAT_CDL) {
                /*
-                * New style VOL1 labeled disk
+                * New style CDL formatted disk
                 */
                unsigned int blk;
                int counter;
 
-               printk("VOL1/%8s:", name);
-
-               /* get block number and read then go through format1 labels */
-               blk = cchhb2blk(&label->vol.vtoc, geo) + 1;
-               counter = 0;
-               while ((data = read_dev_sector(bdev, blk*(blocksize/512),
-                                              &sect)) != NULL) {
-                       struct vtoc_format1_label f1;
-
-                       memcpy(&f1, data, sizeof(struct vtoc_format1_label));
-                       put_dev_sector(sect);
-
-                       /* skip FMT4 / FMT5 / FMT7 labels */
-                       if (f1.DS1FMTID == _ascebc['4']
-                           || f1.DS1FMTID == _ascebc['5']
-                           || f1.DS1FMTID == _ascebc['7']) {
-                               blk++;
-                               continue;
-                       }
-
-                       /* only FMT1 valid at this point */
-                       if (f1.DS1FMTID != _ascebc['1'])
-                               break;
-
-                       /* OK, we got valid partition data */
-                       offset = cchh2blk(&f1.DS1EXT1.llimit, geo);
-                       size  = cchh2blk(&f1.DS1EXT1.ulimit, geo) -
-                               offset + geo->sectors;
-                       if (counter >= state->limit)
-                               break;
-                       put_partition(state, counter + 1,
-                                     offset * (blocksize >> 9),
-                                     size * (blocksize >> 9));
-                       counter++;
-                       blk++;
-               }
-               if (!data)
-               /* Are we not supposed to report this ? */
-                       goto out_readerr;
-       } else {
                /*
-                * Old style LNX1 or unlabeled disk
+                * check if VOL1 label is available
+                * if not, something is wrong, skipping partition detection
                 */
-               if (strncmp(type, "LNX1", 4) == 0)
-                       printk ("LNX1/%8s:", name);
-               else
-                       printk("(nonl)/%8s:", name);
-               offset = (info->label_block + 1);
-               size = i_size >> 9;
-               put_partition(state, 1, offset*(blocksize >> 9),
-                             size-offset*(blocksize >> 9));
+               if (strncmp(type, "VOL1",  4) == 0) {
+                       printk("VOL1/%8s:", name);
+                       /*
+                        * get block number and read then go through format1
+                        * labels
+                        */
+                       blk = cchhb2blk(&label->vol.vtoc, geo) + 1;
+                       counter = 0;
+                       data = read_dev_sector(bdev, blk * (blocksize/512),
+                                              &sect);
+                       while (data != NULL) {
+                               struct vtoc_format1_label f1;
+
+                               memcpy(&f1, data,
+                                      sizeof(struct vtoc_format1_label));
+                               put_dev_sector(sect);
+
+                               /* skip FMT4 / FMT5 / FMT7 labels */
+                               if (f1.DS1FMTID == _ascebc['4']
+                                   || f1.DS1FMTID == _ascebc['5']
+                                   || f1.DS1FMTID == _ascebc['7']) {
+                                       blk++;
+                                       data = read_dev_sector(bdev, blk *
+                                                              (blocksize/512),
+                                                               &sect);
+                                       continue;
+                               }
+
+                               /* only FMT1 valid at this point */
+                               if (f1.DS1FMTID != _ascebc['1'])
+                                       break;
+
+                               /* OK, we got valid partition data */
+                               offset = cchh2blk(&f1.DS1EXT1.llimit, geo);
+                               size  = cchh2blk(&f1.DS1EXT1.ulimit, geo) -
+                                       offset + geo->sectors;
+                               if (counter >= state->limit)
+                                       break;
+                               put_partition(state, counter + 1,
+                                             offset * (blocksize >> 9),
+                                             size * (blocksize >> 9));
+                               counter++;
+                               blk++;
+                               data = read_dev_sector(bdev,
+                                                      blk * (blocksize/512),
+                                                      &sect);
+                       }
+
+                       if (!data)
+                               /* Are we not supposed to report this ? */
+                               goto out_readerr;
+               } else
+                       printk(KERN_WARNING "Warning, expected Label VOL1 not "
+                              "found, treating as CDL formated Disk");
+
        }
 
        printk("\n");
index 3a89592bdf577930b4c1698c4811261aa467cbf2..d007830d9c870fabb4b887d3f81afcb8e7160642 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -164,6 +164,20 @@ static void anon_pipe_buf_release(struct pipe_inode_info *pipe,
                page_cache_release(page);
 }
 
+/**
+ * generic_pipe_buf_map - virtually map a pipe buffer
+ * @pipe:      the pipe that the buffer belongs to
+ * @buf:       the buffer that should be mapped
+ * @atomic:    whether to use an atomic map
+ *
+ * Description:
+ *     This function returns a kernel virtual address mapping for the
+ *     passed in @pipe_buffer. If @atomic is set, an atomic map is provided
+ *     and the caller has to be careful not to fault before calling
+ *     the unmap function.
+ *
+ *     Note that this function occupies KM_USER0 if @atomic != 0.
+ */
 void *generic_pipe_buf_map(struct pipe_inode_info *pipe,
                           struct pipe_buffer *buf, int atomic)
 {
@@ -175,6 +189,15 @@ void *generic_pipe_buf_map(struct pipe_inode_info *pipe,
        return kmap(buf->page);
 }
 
+/**
+ * generic_pipe_buf_unmap - unmap a previously mapped pipe buffer
+ * @pipe:      the pipe that the buffer belongs to
+ * @buf:       the buffer that should be unmapped
+ * @map_data:  the data that the mapping function returned
+ *
+ * Description:
+ *     This function undoes the mapping that ->map() provided.
+ */
 void generic_pipe_buf_unmap(struct pipe_inode_info *pipe,
                            struct pipe_buffer *buf, void *map_data)
 {
@@ -185,11 +208,28 @@ void generic_pipe_buf_unmap(struct pipe_inode_info *pipe,
                kunmap(buf->page);
 }
 
+/**
+ * generic_pipe_buf_steal - attempt to take ownership of a @pipe_buffer
+ * @pipe:      the pipe that the buffer belongs to
+ * @buf:       the buffer to attempt to steal
+ *
+ * Description:
+ *     This function attempts to steal the @struct page attached to
+ *     @buf. If successful, this function returns 0 and returns with
+ *     the page locked. The caller may then reuse the page for whatever
+ *     he wishes, the typical use is insertion into a different file
+ *     page cache.
+ */
 int generic_pipe_buf_steal(struct pipe_inode_info *pipe,
                           struct pipe_buffer *buf)
 {
        struct page *page = buf->page;
 
+       /*
+        * A reference of one is golden, that means that the owner of this
+        * page is the only one holding a reference to it. lock the page
+        * and return OK.
+        */
        if (page_count(page) == 1) {
                lock_page(page);
                return 0;
@@ -198,12 +238,32 @@ int generic_pipe_buf_steal(struct pipe_inode_info *pipe,
        return 1;
 }
 
-void generic_pipe_buf_get(struct pipe_inode_info *info, struct pipe_buffer *buf)
+/**
+ * generic_pipe_buf_get - get a reference to a @struct pipe_buffer
+ * @pipe:      the pipe that the buffer belongs to
+ * @buf:       the buffer to get a reference to
+ *
+ * Description:
+ *     This function grabs an extra reference to @buf. It's used in
+ *     in the tee() system call, when we duplicate the buffers in one
+ *     pipe into another.
+ */
+void generic_pipe_buf_get(struct pipe_inode_info *pipe, struct pipe_buffer *buf)
 {
        page_cache_get(buf->page);
 }
 
-int generic_pipe_buf_pin(struct pipe_inode_info *info, struct pipe_buffer *buf)
+/**
+ * generic_pipe_buf_confirm - verify contents of the pipe buffer
+ * @pipe:      the pipe that the buffer belongs to
+ * @buf:       the buffer to confirm
+ *
+ * Description:
+ *     This function does nothing, because the generic pipe code uses
+ *     pages that are always good when inserted into the pipe.
+ */
+int generic_pipe_buf_confirm(struct pipe_inode_info *info,
+                            struct pipe_buffer *buf)
 {
        return 0;
 }
@@ -212,7 +272,7 @@ static const struct pipe_buf_operations anon_pipe_buf_ops = {
        .can_merge = 1,
        .map = generic_pipe_buf_map,
        .unmap = generic_pipe_buf_unmap,
-       .pin = generic_pipe_buf_pin,
+       .confirm = generic_pipe_buf_confirm,
        .release = anon_pipe_buf_release,
        .steal = generic_pipe_buf_steal,
        .get = generic_pipe_buf_get,
@@ -252,7 +312,7 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov,
                        if (chars > total_len)
                                chars = total_len;
 
-                       error = ops->pin(pipe, buf);
+                       error = ops->confirm(pipe, buf);
                        if (error) {
                                if (!ret)
                                        error = ret;
@@ -373,7 +433,7 @@ pipe_write(struct kiocb *iocb, const struct iovec *_iov,
                        int error, atomic = 1;
                        void *addr;
 
-                       error = ops->pin(pipe, buf);
+                       error = ops->confirm(pipe, buf);
                        if (error)
                                goto out;
 
index 74f30e0c0381041d95fc3657077dd22ab3466105..98e78e2f18d66cb4331d394c8543c3e8db4445a4 100644 (file)
@@ -165,7 +165,6 @@ static inline char * task_state(struct task_struct *p, char *buffer)
        rcu_read_lock();
        buffer += sprintf(buffer,
                "State:\t%s\n"
-               "SleepAVG:\t%lu%%\n"
                "Tgid:\t%d\n"
                "Pid:\t%d\n"
                "PPid:\t%d\n"
@@ -173,7 +172,6 @@ static inline char * task_state(struct task_struct *p, char *buffer)
                "Uid:\t%d\t%d\t%d\t%d\n"
                "Gid:\t%d\t%d\t%d\t%d\n",
                get_task_state(p),
-               (p->sleep_avg/1024)*100/(1020000000/1024),
                p->tgid, p->pid,
                pid_alive(p) ? rcu_dereference(p->real_parent)->tgid : 0,
                pid_alive(p) && p->ptrace ? rcu_dereference(p->parent)->pid : 0,
@@ -312,6 +310,41 @@ int proc_pid_status(struct task_struct *task, char * buffer)
        return buffer - orig;
 }
 
+static clock_t task_utime(struct task_struct *p)
+{
+       clock_t utime = cputime_to_clock_t(p->utime),
+               total = utime + cputime_to_clock_t(p->stime);
+       u64 temp;
+
+       /*
+        * Use CFS's precise accounting:
+        */
+       temp = (u64)nsec_to_clock_t(p->se.sum_exec_runtime);
+
+       if (total) {
+               temp *= utime;
+               do_div(temp, total);
+       }
+       utime = (clock_t)temp;
+
+       return utime;
+}
+
+static clock_t task_stime(struct task_struct *p)
+{
+       clock_t stime = cputime_to_clock_t(p->stime);
+
+       /*
+        * Use CFS's precise accounting. (we subtract utime from
+        * the total, to make sure the total observed by userspace
+        * grows monotonically - apps rely on that):
+        */
+       stime = nsec_to_clock_t(p->se.sum_exec_runtime) - task_utime(p);
+
+       return stime;
+}
+
+
 static int do_task_stat(struct task_struct *task, char * buffer, int whole)
 {
        unsigned long vsize, eip, esp, wchan = ~0UL;
@@ -326,7 +359,8 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
        unsigned long long start_time;
        unsigned long cmin_flt = 0, cmaj_flt = 0;
        unsigned long  min_flt = 0,  maj_flt = 0;
-       cputime_t cutime, cstime, utime, stime;
+       cputime_t cutime, cstime;
+       clock_t utime, stime;
        unsigned long rsslim = 0;
        char tcomm[sizeof(task->comm)];
        unsigned long flags;
@@ -344,7 +378,8 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
 
        sigemptyset(&sigign);
        sigemptyset(&sigcatch);
-       cutime = cstime = utime = stime = cputime_zero;
+       cutime = cstime = cputime_zero;
+       utime = stime = 0;
 
        rcu_read_lock();
        if (lock_task_sighand(task, &flags)) {
@@ -370,15 +405,15 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
                        do {
                                min_flt += t->min_flt;
                                maj_flt += t->maj_flt;
-                               utime = cputime_add(utime, t->utime);
-                               stime = cputime_add(stime, t->stime);
+                               utime += task_utime(t);
+                               stime += task_stime(t);
                                t = next_thread(t);
                        } while (t != task);
 
                        min_flt += sig->min_flt;
                        maj_flt += sig->maj_flt;
-                       utime = cputime_add(utime, sig->utime);
-                       stime = cputime_add(stime, sig->stime);
+                       utime += cputime_to_clock_t(sig->utime);
+                       stime += cputime_to_clock_t(sig->stime);
                }
 
                sid = signal_session(sig);
@@ -394,8 +429,8 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
        if (!whole) {
                min_flt = task->min_flt;
                maj_flt = task->maj_flt;
-               utime = task->utime;
-               stime = task->stime;
+               utime = task_utime(task);
+               stime = task_stime(task);
        }
 
        /* scale priority and nice values from timeslices to -20..20 */
@@ -426,8 +461,8 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
                cmin_flt,
                maj_flt,
                cmaj_flt,
-               cputime_to_clock_t(utime),
-               cputime_to_clock_t(stime),
+               utime,
+               stime,
                cputime_to_clock_t(cutime),
                cputime_to_clock_t(cstime),
                priority,
index a5fa1fdafc4e6df68df2cc87626f0d8d85bd95a6..46ea5d56e1bb9bd7a3cf60e163d2e9951832d50d 100644 (file)
@@ -296,7 +296,7 @@ static int proc_pid_wchan(struct task_struct *task, char *buffer)
  */
 static int proc_pid_schedstat(struct task_struct *task, char *buffer)
 {
-       return sprintf(buffer, "%lu %lu %lu\n",
+       return sprintf(buffer, "%llu %llu %lu\n",
                        task->sched_info.cpu_time,
                        task->sched_info.run_delay,
                        task->sched_info.pcnt);
@@ -929,6 +929,69 @@ static const struct file_operations proc_fault_inject_operations = {
 };
 #endif
 
+#ifdef CONFIG_SCHED_DEBUG
+/*
+ * Print out various scheduling related per-task fields:
+ */
+static int sched_show(struct seq_file *m, void *v)
+{
+       struct inode *inode = m->private;
+       struct task_struct *p;
+
+       WARN_ON(!inode);
+
+       p = get_proc_task(inode);
+       if (!p)
+               return -ESRCH;
+       proc_sched_show_task(p, m);
+
+       put_task_struct(p);
+
+       return 0;
+}
+
+static ssize_t
+sched_write(struct file *file, const char __user *buf,
+           size_t count, loff_t *offset)
+{
+       struct inode *inode = file->f_path.dentry->d_inode;
+       struct task_struct *p;
+
+       WARN_ON(!inode);
+
+       p = get_proc_task(inode);
+       if (!p)
+               return -ESRCH;
+       proc_sched_set_task(p);
+
+       put_task_struct(p);
+
+       return count;
+}
+
+static int sched_open(struct inode *inode, struct file *filp)
+{
+       int ret;
+
+       ret = single_open(filp, sched_show, NULL);
+       if (!ret) {
+               struct seq_file *m = filp->private_data;
+
+               m->private = inode;
+       }
+       return ret;
+}
+
+static const struct file_operations proc_pid_sched_operations = {
+       .open           = sched_open,
+       .read           = seq_read,
+       .write          = sched_write,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
+#endif
+
 static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
        struct inode *inode = dentry->d_inode;
@@ -1963,6 +2026,9 @@ static const struct pid_entry tgid_base_stuff[] = {
        INF("environ",    S_IRUSR, pid_environ),
        INF("auxv",       S_IRUSR, pid_auxv),
        INF("status",     S_IRUGO, pid_status),
+#ifdef CONFIG_SCHED_DEBUG
+       REG("sched",      S_IRUGO|S_IWUSR, pid_sched),
+#endif
        INF("cmdline",    S_IRUGO, pid_cmdline),
        INF("stat",       S_IRUGO, tgid_stat),
        INF("statm",      S_IRUGO, pid_statm),
@@ -2247,6 +2313,9 @@ static const struct pid_entry tid_base_stuff[] = {
        INF("environ",   S_IRUSR, pid_environ),
        INF("auxv",      S_IRUSR, pid_auxv),
        INF("status",    S_IRUGO, pid_status),
+#ifdef CONFIG_SCHED_DEBUG
+       REG("sched",     S_IRUGO|S_IWUSR, pid_sched),
+#endif
        INF("cmdline",   S_IRUGO, pid_cmdline),
        INF("stat",      S_IRUGO, tid_stat),
        INF("statm",     S_IRUGO, pid_statm),
index 44649981bbc8b08b7c1830d903432bb3fb583701..867f42b02035dd6621f681a6730d90c2a3a3c4ae 100644 (file)
@@ -25,7 +25,7 @@ const struct file_operations qnx4_file_operations =
        .read           = do_sync_read,
        .aio_read       = generic_file_aio_read,
        .mmap           = generic_file_mmap,
-       .sendfile       = generic_file_sendfile,
+       .splice_read    = generic_file_splice_read,
 #ifdef CONFIG_QNX4FS_RW
        .write          = do_sync_write,
        .aio_write      = generic_file_aio_write,
index 2f14774a124fc05e5c995f1c9dd02926440de009..97bdc0b2f9d29b0d253048874dfaa388ae3ec830 100644 (file)
@@ -41,7 +41,7 @@ const struct file_operations ramfs_file_operations = {
        .aio_write      = generic_file_aio_write,
        .mmap           = generic_file_mmap,
        .fsync          = simple_sync_file,
-       .sendfile       = generic_file_sendfile,
+       .splice_read    = generic_file_splice_read,
        .llseek         = generic_file_llseek,
 };
 
index 5d258c40a2fd9c59fead95c4d3d84d7a4092bce3..cad2b7ace63033bc4aa0e78393e07d3527f296c9 100644 (file)
@@ -42,7 +42,7 @@ const struct file_operations ramfs_file_operations = {
        .write                  = do_sync_write,
        .aio_write              = generic_file_aio_write,
        .fsync                  = simple_sync_file,
-       .sendfile               = generic_file_sendfile,
+       .splice_read            = generic_file_splice_read,
        .llseek                 = generic_file_llseek,
 };
 
index 4d03008f015b9ae6d2565cdbc179d034687c3d08..507ddff48a9a9e673d75d161d0fc8ad09c00faef 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/module.h>
 #include <linux/syscalls.h>
 #include <linux/pagemap.h>
+#include <linux/splice.h>
 #include "read_write.h"
 
 #include <asm/uaccess.h>
@@ -25,7 +26,7 @@ const struct file_operations generic_ro_fops = {
        .read           = do_sync_read,
        .aio_read       = generic_file_aio_read,
        .mmap           = generic_file_readonly_mmap,
-       .sendfile       = generic_file_sendfile,
+       .splice_read    = generic_file_splice_read,
 };
 
 EXPORT_SYMBOL(generic_ro_fops);
@@ -708,7 +709,7 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
        struct inode * in_inode, * out_inode;
        loff_t pos;
        ssize_t retval;
-       int fput_needed_in, fput_needed_out;
+       int fput_needed_in, fput_needed_out, fl;
 
        /*
         * Get input file, and verify that it is ok..
@@ -723,7 +724,7 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
        in_inode = in_file->f_path.dentry->d_inode;
        if (!in_inode)
                goto fput_in;
-       if (!in_file->f_op || !in_file->f_op->sendfile)
+       if (!in_file->f_op || !in_file->f_op->splice_read)
                goto fput_in;
        retval = -ESPIPE;
        if (!ppos)
@@ -776,7 +777,18 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
                count = max - pos;
        }
 
-       retval = in_file->f_op->sendfile(in_file, ppos, count, file_send_actor, out_file);
+       fl = 0;
+#if 0
+       /*
+        * We need to debate whether we can enable this or not. The
+        * man page documents EAGAIN return for the output at least,
+        * and the application is arguably buggy if it doesn't expect
+        * EAGAIN on a non-blocking file descriptor.
+        */
+       if (in_file->f_flags & O_NONBLOCK)
+               fl = SPLICE_F_NONBLOCK;
+#endif
+       retval = do_splice_direct(in_file, ppos, out_file, count, fl);
 
        if (retval > 0) {
                add_rchar(current, retval);
index 9e451a68580f6eef3ab4ba8c6eb729ae843d071b..30eebfb1b2d8d7e9cf26474329d28fd28f401665 100644 (file)
@@ -1531,7 +1531,6 @@ const struct file_operations reiserfs_file_operations = {
        .open = generic_file_open,
        .release = reiserfs_file_release,
        .fsync = reiserfs_sync_file,
-       .sendfile = generic_file_sendfile,
        .aio_read = generic_file_aio_read,
        .aio_write = generic_file_aio_write,
        .splice_read = generic_file_splice_read,
index 0ac22af7afe5f2b31ea2d289f68b5ee13e1b9040..49194a4e6b91ba9dcd22c3aa7fe81f794aca4413 100644 (file)
@@ -447,3 +447,37 @@ int seq_puts(struct seq_file *m, const char *s)
        return -1;
 }
 EXPORT_SYMBOL(seq_puts);
+
+struct list_head *seq_list_start(struct list_head *head, loff_t pos)
+{
+       struct list_head *lh;
+
+       list_for_each(lh, head)
+               if (pos-- == 0)
+                       return lh;
+
+       return NULL;
+}
+
+EXPORT_SYMBOL(seq_list_start);
+
+struct list_head *seq_list_start_head(struct list_head *head, loff_t pos)
+{
+       if (!pos)
+               return head;
+
+       return seq_list_start(head, pos - 1);
+}
+
+EXPORT_SYMBOL(seq_list_start_head);
+
+struct list_head *seq_list_next(void *v, struct list_head *head, loff_t *ppos)
+{
+       struct list_head *lh;
+
+       lh = ((struct list_head *)v)->next;
+       ++*ppos;
+       return lh == head ? NULL : lh;
+}
+
+EXPORT_SYMBOL(seq_list_next);
index aea3f8aa54c0911e80110937f9d26ef03694a9ee..c5d78a7e492b40b7dae9dde99b42698522485565 100644 (file)
@@ -262,8 +262,9 @@ out:
 }
 
 static ssize_t
-smb_file_sendfile(struct file *file, loff_t *ppos,
-                 size_t count, read_actor_t actor, void *target)
+smb_file_splice_read(struct file *file, loff_t *ppos,
+                    struct pipe_inode_info *pipe, size_t count,
+                    unsigned int flags)
 {
        struct dentry *dentry = file->f_path.dentry;
        ssize_t status;
@@ -277,7 +278,7 @@ smb_file_sendfile(struct file *file, loff_t *ppos,
                         DENTRY_PATH(dentry), status);
                goto out;
        }
-       status = generic_file_sendfile(file, ppos, count, actor, target);
+       status = generic_file_splice_read(file, ppos, pipe, count, flags);
 out:
        return status;
 }
@@ -416,7 +417,7 @@ const struct file_operations smb_file_operations =
        .open           = smb_file_open,
        .release        = smb_file_release,
        .fsync          = smb_fsync,
-       .sendfile       = smb_file_sendfile,
+       .splice_read    = smb_file_splice_read,
 };
 
 const struct inode_operations smb_file_inode_operations =
index e7d7080de2f9799860a475a4df50a7742561d09f..6c9828651e6f5cdec78ce99d5169bb238c61f0ea 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/fs.h>
 #include <linux/file.h>
 #include <linux/pagemap.h>
-#include <linux/pipe_fs_i.h>
+#include <linux/splice.h>
 #include <linux/mm_inline.h>
 #include <linux/swap.h>
 #include <linux/writeback.h>
 #include <linux/module.h>
 #include <linux/syscalls.h>
 #include <linux/uio.h>
-
-struct partial_page {
-       unsigned int offset;
-       unsigned int len;
-};
-
-/*
- * Passed to splice_to_pipe
- */
-struct splice_pipe_desc {
-       struct page **pages;            /* page map */
-       struct partial_page *partial;   /* pages[] may not be contig */
-       int nr_pages;                   /* number of pages in map */
-       unsigned int flags;             /* splice flags */
-       const struct pipe_buf_operations *ops;/* ops associated with output pipe */
-};
+#include <linux/security.h>
 
 /*
  * Attempt to steal a page from a pipe buffer. This should perhaps go into
@@ -101,8 +86,12 @@ static void page_cache_pipe_buf_release(struct pipe_inode_info *pipe,
        buf->flags &= ~PIPE_BUF_FLAG_LRU;
 }
 
-static int page_cache_pipe_buf_pin(struct pipe_inode_info *pipe,
-                                  struct pipe_buffer *buf)
+/*
+ * Check whether the contents of buf is OK to access. Since the content
+ * is a page cache page, IO may be in flight.
+ */
+static int page_cache_pipe_buf_confirm(struct pipe_inode_info *pipe,
+                                      struct pipe_buffer *buf)
 {
        struct page *page = buf->page;
        int err;
@@ -143,7 +132,7 @@ static const struct pipe_buf_operations page_cache_pipe_buf_ops = {
        .can_merge = 0,
        .map = generic_pipe_buf_map,
        .unmap = generic_pipe_buf_unmap,
-       .pin = page_cache_pipe_buf_pin,
+       .confirm = page_cache_pipe_buf_confirm,
        .release = page_cache_pipe_buf_release,
        .steal = page_cache_pipe_buf_steal,
        .get = generic_pipe_buf_get,
@@ -163,18 +152,25 @@ static const struct pipe_buf_operations user_page_pipe_buf_ops = {
        .can_merge = 0,
        .map = generic_pipe_buf_map,
        .unmap = generic_pipe_buf_unmap,
-       .pin = generic_pipe_buf_pin,
+       .confirm = generic_pipe_buf_confirm,
        .release = page_cache_pipe_buf_release,
        .steal = user_page_pipe_buf_steal,
        .get = generic_pipe_buf_get,
 };
 
-/*
- * Pipe output worker. This sets up our pipe format with the page cache
- * pipe buffer operations. Otherwise very similar to the regular pipe_writev().
+/**
+ * splice_to_pipe - fill passed data into a pipe
+ * @pipe:      pipe to fill
+ * @spd:       data to fill
+ *
+ * Description:
+ *    @spd contains a map of pages and len/offset tupples, a long with
+ *    the struct pipe_buf_operations associated with these pages. This
+ *    function will link that data to the pipe.
+ *
  */
-static ssize_t splice_to_pipe(struct pipe_inode_info *pipe,
-                             struct splice_pipe_desc *spd)
+ssize_t splice_to_pipe(struct pipe_inode_info *pipe,
+                      struct splice_pipe_desc *spd)
 {
        unsigned int spd_pages = spd->nr_pages;
        int ret, do_wakeup, page_nr;
@@ -201,6 +197,7 @@ static ssize_t splice_to_pipe(struct pipe_inode_info *pipe,
                        buf->page = spd->pages[page_nr];
                        buf->offset = spd->partial[page_nr].offset;
                        buf->len = spd->partial[page_nr].len;
+                       buf->private = spd->partial[page_nr].private;
                        buf->ops = spd->ops;
                        if (spd->flags & SPLICE_F_GIFT)
                                buf->flags |= PIPE_BUF_FLAG_GIFT;
@@ -295,11 +292,6 @@ __generic_file_splice_read(struct file *in, loff_t *ppos,
         */
        page_cache_readahead(mapping, &in->f_ra, in, index, nr_pages);
 
-       /*
-        * Now fill in the holes:
-        */
-       error = 0;
-
        /*
         * Lookup the (hopefully) full range of pages we need.
         */
@@ -307,8 +299,9 @@ __generic_file_splice_read(struct file *in, loff_t *ppos,
 
        /*
         * If find_get_pages_contig() returned fewer pages than we needed,
-        * allocate the rest.
+        * allocate the rest and fill in the holes.
         */
+       error = 0;
        index += spd.nr_pages;
        while (spd.nr_pages < nr_pages) {
                /*
@@ -470,11 +463,16 @@ fill_it:
 /**
  * generic_file_splice_read - splice data from file to a pipe
  * @in:                file to splice from
+ * @ppos:      position in @in
  * @pipe:      pipe to splice to
  * @len:       number of bytes to splice
  * @flags:     splice modifier flags
  *
- * Will read pages from given file and fill them into a pipe.
+ * Description:
+ *    Will read pages from given file and fill them into a pipe. Can be
+ *    used as long as the address_space operations for the source implements
+ *    a readpage() hook.
+ *
  */
 ssize_t generic_file_splice_read(struct file *in, loff_t *ppos,
                                 struct pipe_inode_info *pipe, size_t len,
@@ -494,7 +492,7 @@ ssize_t generic_file_splice_read(struct file *in, loff_t *ppos,
 
        ret = 0;
        spliced = 0;
-       while (len) {
+       while (len && !spliced) {
                ret = __generic_file_splice_read(in, ppos, pipe, len, flags);
 
                if (ret < 0)
@@ -528,11 +526,11 @@ EXPORT_SYMBOL(generic_file_splice_read);
 static int pipe_to_sendpage(struct pipe_inode_info *pipe,
                            struct pipe_buffer *buf, struct splice_desc *sd)
 {
-       struct file *file = sd->file;
+       struct file *file = sd->u.file;
        loff_t pos = sd->pos;
        int ret, more;
 
-       ret = buf->ops->pin(pipe, buf);
+       ret = buf->ops->confirm(pipe, buf);
        if (!ret) {
                more = (sd->flags & SPLICE_F_MORE) || sd->len < sd->total_len;
 
@@ -566,7 +564,7 @@ static int pipe_to_sendpage(struct pipe_inode_info *pipe,
 static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
                        struct splice_desc *sd)
 {
-       struct file *file = sd->file;
+       struct file *file = sd->u.file;
        struct address_space *mapping = file->f_mapping;
        unsigned int offset, this_len;
        struct page *page;
@@ -576,7 +574,7 @@ static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
        /*
         * make sure the data in this buffer is uptodate
         */
-       ret = buf->ops->pin(pipe, buf);
+       ret = buf->ops->confirm(pipe, buf);
        if (unlikely(ret))
                return ret;
 
@@ -663,36 +661,37 @@ out_ret:
        return ret;
 }
 
-/*
- * Pipe input worker. Most of this logic works like a regular pipe, the
- * key here is the 'actor' worker passed in that actually moves the data
- * to the wanted destination. See pipe_to_file/pipe_to_sendpage above.
+/**
+ * __splice_from_pipe - splice data from a pipe to given actor
+ * @pipe:      pipe to splice from
+ * @sd:                information to @actor
+ * @actor:     handler that splices the data
+ *
+ * Description:
+ *    This function does little more than loop over the pipe and call
+ *    @actor to do the actual moving of a single struct pipe_buffer to
+ *    the desired destination. See pipe_to_file, pipe_to_sendpage, or
+ *    pipe_to_user.
+ *
  */
-ssize_t __splice_from_pipe(struct pipe_inode_info *pipe,
-                          struct file *out, loff_t *ppos, size_t len,
-                          unsigned int flags, splice_actor *actor)
+ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, struct splice_desc *sd,
+                          splice_actor *actor)
 {
        int ret, do_wakeup, err;
-       struct splice_desc sd;
 
        ret = 0;
        do_wakeup = 0;
 
-       sd.total_len = len;
-       sd.flags = flags;
-       sd.file = out;
-       sd.pos = *ppos;
-
        for (;;) {
                if (pipe->nrbufs) {
                        struct pipe_buffer *buf = pipe->bufs + pipe->curbuf;
                        const struct pipe_buf_operations *ops = buf->ops;
 
-                       sd.len = buf->len;
-                       if (sd.len > sd.total_len)
-                               sd.len = sd.total_len;
+                       sd->len = buf->len;
+                       if (sd->len > sd->total_len)
+                               sd->len = sd->total_len;
 
-                       err = actor(pipe, buf, &sd);
+                       err = actor(pipe, buf, sd);
                        if (err <= 0) {
                                if (!ret && err != -ENODATA)
                                        ret = err;
@@ -704,10 +703,10 @@ ssize_t __splice_from_pipe(struct pipe_inode_info *pipe,
                        buf->offset += err;
                        buf->len -= err;
 
-                       sd.len -= err;
-                       sd.pos += err;
-                       sd.total_len -= err;
-                       if (sd.len)
+                       sd->len -= err;
+                       sd->pos += err;
+                       sd->total_len -= err;
+                       if (sd->len)
                                continue;
 
                        if (!buf->len) {
@@ -719,7 +718,7 @@ ssize_t __splice_from_pipe(struct pipe_inode_info *pipe,
                                        do_wakeup = 1;
                        }
 
-                       if (!sd.total_len)
+                       if (!sd->total_len)
                                break;
                }
 
@@ -732,7 +731,7 @@ ssize_t __splice_from_pipe(struct pipe_inode_info *pipe,
                                break;
                }
 
-               if (flags & SPLICE_F_NONBLOCK) {
+               if (sd->flags & SPLICE_F_NONBLOCK) {
                        if (!ret)
                                ret = -EAGAIN;
                        break;
@@ -766,12 +765,32 @@ ssize_t __splice_from_pipe(struct pipe_inode_info *pipe,
 }
 EXPORT_SYMBOL(__splice_from_pipe);
 
+/**
+ * splice_from_pipe - splice data from a pipe to a file
+ * @pipe:      pipe to splice from
+ * @out:       file to splice to
+ * @ppos:      position in @out
+ * @len:       how many bytes to splice
+ * @flags:     splice modifier flags
+ * @actor:     handler that splices the data
+ *
+ * Description:
+ *    See __splice_from_pipe. This function locks the input and output inodes,
+ *    otherwise it's identical to __splice_from_pipe().
+ *
+ */
 ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
                         loff_t *ppos, size_t len, unsigned int flags,
                         splice_actor *actor)
 {
        ssize_t ret;
        struct inode *inode = out->f_mapping->host;
+       struct splice_desc sd = {
+               .total_len = len,
+               .flags = flags,
+               .pos = *ppos,
+               .u.file = out,
+       };
 
        /*
         * The actor worker might be calling ->prepare_write and
@@ -780,7 +799,7 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
         * pipe->inode, we have to order lock acquiry here.
         */
        inode_double_lock(inode, pipe->inode);
-       ret = __splice_from_pipe(pipe, out, ppos, len, flags, actor);
+       ret = __splice_from_pipe(pipe, &sd, actor);
        inode_double_unlock(inode, pipe->inode);
 
        return ret;
@@ -790,12 +809,14 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
  * generic_file_splice_write_nolock - generic_file_splice_write without mutexes
  * @pipe:      pipe info
  * @out:       file to write to
+ * @ppos:      position in @out
  * @len:       number of bytes to splice
  * @flags:     splice modifier flags
  *
- * Will either move or copy pages (determined by @flags options) from
- * the given pipe inode to the given file. The caller is responsible
- * for acquiring i_mutex on both inodes.
+ * Description:
+ *    Will either move or copy pages (determined by @flags options) from
+ *    the given pipe inode to the given file. The caller is responsible
+ *    for acquiring i_mutex on both inodes.
  *
  */
 ssize_t
@@ -804,6 +825,12 @@ generic_file_splice_write_nolock(struct pipe_inode_info *pipe, struct file *out,
 {
        struct address_space *mapping = out->f_mapping;
        struct inode *inode = mapping->host;
+       struct splice_desc sd = {
+               .total_len = len,
+               .flags = flags,
+               .pos = *ppos,
+               .u.file = out,
+       };
        ssize_t ret;
        int err;
 
@@ -811,7 +838,7 @@ generic_file_splice_write_nolock(struct pipe_inode_info *pipe, struct file *out,
        if (unlikely(err))
                return err;
 
-       ret = __splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file);
+       ret = __splice_from_pipe(pipe, &sd, pipe_to_file);
        if (ret > 0) {
                unsigned long nr_pages;
 
@@ -841,11 +868,13 @@ EXPORT_SYMBOL(generic_file_splice_write_nolock);
  * generic_file_splice_write - splice data from a pipe to a file
  * @pipe:      pipe info
  * @out:       file to write to
+ * @ppos:      position in @out
  * @len:       number of bytes to splice
  * @flags:     splice modifier flags
  *
- * Will either move or copy pages (determined by @flags options) from
- * the given pipe inode to the given file.
+ * Description:
+ *    Will either move or copy pages (determined by @flags options) from
+ *    the given pipe inode to the given file.
  *
  */
 ssize_t
@@ -896,13 +925,15 @@ EXPORT_SYMBOL(generic_file_splice_write);
 
 /**
  * generic_splice_sendpage - splice data from a pipe to a socket
- * @inode:     pipe inode
+ * @pipe:      pipe to splice from
  * @out:       socket to write to
+ * @ppos:      position in @out
  * @len:       number of bytes to splice
  * @flags:     splice modifier flags
  *
- * Will send @len bytes from the pipe to a network socket. No data copying
- * is involved.
+ * Description:
+ *    Will send @len bytes from the pipe to a network socket. No data copying
+ *    is involved.
  *
  */
 ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, struct file *out,
@@ -931,6 +962,10 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
        if (unlikely(ret < 0))
                return ret;
 
+       ret = security_file_permission(out, MAY_WRITE);
+       if (unlikely(ret < 0))
+               return ret;
+
        return out->f_op->splice_write(pipe, out, ppos, len, flags);
 }
 
@@ -953,17 +988,34 @@ static long do_splice_to(struct file *in, loff_t *ppos,
        if (unlikely(ret < 0))
                return ret;
 
+       ret = security_file_permission(in, MAY_READ);
+       if (unlikely(ret < 0))
+               return ret;
+
        return in->f_op->splice_read(in, ppos, pipe, len, flags);
 }
 
-long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
-                     size_t len, unsigned int flags)
+/**
+ * splice_direct_to_actor - splices data directly between two non-pipes
+ * @in:                file to splice from
+ * @sd:                actor information on where to splice to
+ * @actor:     handles the data splicing
+ *
+ * Description:
+ *    This is a special case helper to splice directly between two
+ *    points, without requiring an explicit pipe. Internally an allocated
+ *    pipe is cached in the process, and reused during the life time of
+ *    that process.
+ *
+ */
+ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
+                              splice_direct_actor *actor)
 {
        struct pipe_inode_info *pipe;
        long ret, bytes;
-       loff_t out_off;
        umode_t i_mode;
-       int i;
+       size_t len;
+       int i, flags;
 
        /*
         * We require the input being a regular file, as we don't want to
@@ -999,49 +1051,41 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
         */
        ret = 0;
        bytes = 0;
-       out_off = 0;
+       len = sd->total_len;
+       flags = sd->flags;
 
-       while (len) {
-               size_t read_len, max_read_len;
+       /*
+        * Don't block on output, we have to drain the direct pipe.
+        */
+       sd->flags &= ~SPLICE_F_NONBLOCK;
 
-               /*
-                * Do at most PIPE_BUFFERS pages worth of transfer:
-                */
-               max_read_len = min(len, (size_t)(PIPE_BUFFERS*PAGE_SIZE));
+       while (len) {
+               size_t read_len;
 
-               ret = do_splice_to(in, ppos, pipe, max_read_len, flags);
-               if (unlikely(ret < 0))
+               ret = do_splice_to(in, &sd->pos, pipe, len, flags);
+               if (unlikely(ret <= 0))
                        goto out_release;
 
                read_len = ret;
+               sd->total_len = read_len;
 
                /*
                 * NOTE: nonblocking mode only applies to the input. We
                 * must not do the output in nonblocking mode as then we
                 * could get stuck data in the internal pipe:
                 */
-               ret = do_splice_from(pipe, out, &out_off, read_len,
-                                    flags & ~SPLICE_F_NONBLOCK);
-               if (unlikely(ret < 0))
+               ret = actor(pipe, sd);
+               if (unlikely(ret <= 0))
                        goto out_release;
 
                bytes += ret;
                len -= ret;
 
-               /*
-                * In nonblocking mode, if we got back a short read then
-                * that was due to either an IO error or due to the
-                * pagecache entry not being there. In the IO error case
-                * the _next_ splice attempt will produce a clean IO error
-                * return value (not a short read), so in both cases it's
-                * correct to break out of the loop here:
-                */
-               if ((flags & SPLICE_F_NONBLOCK) && (read_len < max_read_len))
-                       break;
+               if (ret < read_len)
+                       goto out_release;
        }
 
        pipe->nrbufs = pipe->curbuf = 0;
-
        return bytes;
 
 out_release:
@@ -1066,6 +1110,50 @@ out_release:
                return bytes;
 
        return ret;
+
+}
+EXPORT_SYMBOL(splice_direct_to_actor);
+
+static int direct_splice_actor(struct pipe_inode_info *pipe,
+                              struct splice_desc *sd)
+{
+       struct file *file = sd->u.file;
+
+       return do_splice_from(pipe, file, &sd->pos, sd->total_len, sd->flags);
+}
+
+/**
+ * do_splice_direct - splices data directly between two files
+ * @in:                file to splice from
+ * @ppos:      input file offset
+ * @out:       file to splice to
+ * @len:       number of bytes to splice
+ * @flags:     splice modifier flags
+ *
+ * Description:
+ *    For use by do_sendfile(). splice can easily emulate sendfile, but
+ *    doing it in the application would incur an extra system call
+ *    (splice in + splice out, as compared to just sendfile()). So this helper
+ *    can splice directly through a process-private pipe.
+ *
+ */
+long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
+                     size_t len, unsigned int flags)
+{
+       struct splice_desc sd = {
+               .len            = len,
+               .total_len      = len,
+               .flags          = flags,
+               .pos            = *ppos,
+               .u.file         = out,
+       };
+       long ret;
+
+       ret = splice_direct_to_actor(in, &sd, direct_splice_actor);
+       if (ret > 0)
+               *ppos += ret;
+
+       return ret;
 }
 
 /*
@@ -1248,28 +1336,131 @@ static int get_iovec_page_array(const struct iovec __user *iov,
        return error;
 }
 
+static int pipe_to_user(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
+                       struct splice_desc *sd)
+{
+       char *src;
+       int ret;
+
+       ret = buf->ops->confirm(pipe, buf);
+       if (unlikely(ret))
+               return ret;
+
+       /*
+        * See if we can use the atomic maps, by prefaulting in the
+        * pages and doing an atomic copy
+        */
+       if (!fault_in_pages_writeable(sd->u.userptr, sd->len)) {
+               src = buf->ops->map(pipe, buf, 1);
+               ret = __copy_to_user_inatomic(sd->u.userptr, src + buf->offset,
+                                                       sd->len);
+               buf->ops->unmap(pipe, buf, src);
+               if (!ret) {
+                       ret = sd->len;
+                       goto out;
+               }
+       }
+
+       /*
+        * No dice, use slow non-atomic map and copy
+        */
+       src = buf->ops->map(pipe, buf, 0);
+
+       ret = sd->len;
+       if (copy_to_user(sd->u.userptr, src + buf->offset, sd->len))
+               ret = -EFAULT;
+
+out:
+       if (ret > 0)
+               sd->u.userptr += ret;
+       buf->ops->unmap(pipe, buf, src);
+       return ret;
+}
+
+/*
+ * For lack of a better implementation, implement vmsplice() to userspace
+ * as a simple copy of the pipes pages to the user iov.
+ */
+static long vmsplice_to_user(struct file *file, const struct iovec __user *iov,
+                            unsigned long nr_segs, unsigned int flags)
+{
+       struct pipe_inode_info *pipe;
+       struct splice_desc sd;
+       ssize_t size;
+       int error;
+       long ret;
+
+       pipe = pipe_info(file->f_path.dentry->d_inode);
+       if (!pipe)
+               return -EBADF;
+
+       if (pipe->inode)
+               mutex_lock(&pipe->inode->i_mutex);
+
+       error = ret = 0;
+       while (nr_segs) {
+               void __user *base;
+               size_t len;
+
+               /*
+                * Get user address base and length for this iovec.
+                */
+               error = get_user(base, &iov->iov_base);
+               if (unlikely(error))
+                       break;
+               error = get_user(len, &iov->iov_len);
+               if (unlikely(error))
+                       break;
+
+               /*
+                * Sanity check this iovec. 0 read succeeds.
+                */
+               if (unlikely(!len))
+                       break;
+               if (unlikely(!base)) {
+                       error = -EFAULT;
+                       break;
+               }
+
+               sd.len = 0;
+               sd.total_len = len;
+               sd.flags = flags;
+               sd.u.userptr = base;
+               sd.pos = 0;
+
+               size = __splice_from_pipe(pipe, &sd, pipe_to_user);
+               if (size < 0) {
+                       if (!ret)
+                               ret = size;
+
+                       break;
+               }
+
+               ret += size;
+
+               if (size < len)
+                       break;
+
+               nr_segs--;
+               iov++;
+       }
+
+       if (pipe->inode)
+               mutex_unlock(&pipe->inode->i_mutex);
+
+       if (!ret)
+               ret = error;
+
+       return ret;
+}
+
 /*
  * vmsplice splices a user address range into a pipe. It can be thought of
  * as splice-from-memory, where the regular splice is splice-from-file (or
  * to file). In both cases the output is a pipe, naturally.
- *
- * Note that vmsplice only supports splicing _from_ user memory to a pipe,
- * not the other way around. Splicing from user memory is a simple operation
- * that can be supported without any funky alignment restrictions or nasty
- * vm tricks. We simply map in the user memory and fill them into a pipe.
- * The reverse isn't quite as easy, though. There are two possible solutions
- * for that:
- *
- *     - memcpy() the data internally, at which point we might as well just
- *       do a regular read() on the buffer anyway.
- *     - Lots of nasty vm tricks, that are neither fast nor flexible (it
- *       has restriction limitations on both ends of the pipe).
- *
- * Alas, it isn't here.
- *
  */
-static long do_vmsplice(struct file *file, const struct iovec __user *iov,
-                       unsigned long nr_segs, unsigned int flags)
+static long vmsplice_to_pipe(struct file *file, const struct iovec __user *iov,
+                            unsigned long nr_segs, unsigned int flags)
 {
        struct pipe_inode_info *pipe;
        struct page *pages[PIPE_BUFFERS];
@@ -1284,10 +1475,6 @@ static long do_vmsplice(struct file *file, const struct iovec __user *iov,
        pipe = pipe_info(file->f_path.dentry->d_inode);
        if (!pipe)
                return -EBADF;
-       if (unlikely(nr_segs > UIO_MAXIOV))
-               return -EINVAL;
-       else if (unlikely(!nr_segs))
-               return 0;
 
        spd.nr_pages = get_iovec_page_array(iov, nr_segs, pages, partial,
                                            flags & SPLICE_F_GIFT);
@@ -1297,6 +1484,22 @@ static long do_vmsplice(struct file *file, const struct iovec __user *iov,
        return splice_to_pipe(pipe, &spd);
 }
 
+/*
+ * Note that vmsplice only really supports true splicing _from_ user memory
+ * to a pipe, not the other way around. Splicing from user memory is a simple
+ * operation that can be supported without any funky alignment restrictions
+ * or nasty vm tricks. We simply map in the user memory and fill them into
+ * a pipe. The reverse isn't quite as easy, though. There are two possible
+ * solutions for that:
+ *
+ *     - memcpy() the data internally, at which point we might as well just
+ *       do a regular read() on the buffer anyway.
+ *     - Lots of nasty vm tricks, that are neither fast nor flexible (it
+ *       has restriction limitations on both ends of the pipe).
+ *
+ * Currently we punt and implement it as a normal copy, see pipe_to_user().
+ *
+ */
 asmlinkage long sys_vmsplice(int fd, const struct iovec __user *iov,
                             unsigned long nr_segs, unsigned int flags)
 {
@@ -1304,11 +1507,18 @@ asmlinkage long sys_vmsplice(int fd, const struct iovec __user *iov,
        long error;
        int fput;
 
+       if (unlikely(nr_segs > UIO_MAXIOV))
+               return -EINVAL;
+       else if (unlikely(!nr_segs))
+               return 0;
+
        error = -EBADF;
        file = fget_light(fd, &fput);
        if (file) {
                if (file->f_mode & FMODE_WRITE)
-                       error = do_vmsplice(file, iov, nr_segs, flags);
+                       error = vmsplice_to_pipe(file, iov, nr_segs, flags);
+               else if (file->f_mode & FMODE_READ)
+                       error = vmsplice_to_user(file, iov, nr_segs, flags);
 
                fput_light(file, fput);
        }
index d3b9f5f07db149a38ecb03d0a44370d365ffb5d5..135353f8a296773605fe9ca744fe4612fff0f678 100644 (file)
 
 #include "sysfs.h"
 
+struct bin_buffer {
+       struct mutex    mutex;
+       void            *buffer;
+       int             mmapped;
+};
+
 static int
 fill_read(struct dentry *dentry, char *buffer, loff_t off, size_t count)
 {
-       struct bin_attribute * attr = to_bin_attr(dentry);
-       struct kobject * kobj = to_kobj(dentry->d_parent);
+       struct sysfs_dirent *attr_sd = dentry->d_fsdata;
+       struct bin_attribute *attr = attr_sd->s_elem.bin_attr.bin_attr;
+       struct kobject *kobj = attr_sd->s_parent->s_elem.dir.kobj;
+       int rc;
+
+       /* need attr_sd for attr, its parent for kobj */
+       if (!sysfs_get_active_two(attr_sd))
+               return -ENODEV;
 
-       if (!attr->read)
-               return -EIO;
+       rc = -EIO;
+       if (attr->read)
+               rc = attr->read(kobj, attr, buffer, off, count);
 
-       return attr->read(kobj, buffer, off, count);
+       sysfs_put_active_two(attr_sd);
+
+       return rc;
 }
 
 static ssize_t
-read(struct file * file, char __user * userbuf, size_t count, loff_t * off)
+read(struct file *file, char __user *userbuf, size_t bytes, loff_t *off)
 {
-       char *buffer = file->private_data;
+       struct bin_buffer *bb = file->private_data;
        struct dentry *dentry = file->f_path.dentry;
        int size = dentry->d_inode->i_size;
        loff_t offs = *off;
-       int ret;
-
-       if (count > PAGE_SIZE)
-               count = PAGE_SIZE;
+       int count = min_t(size_t, bytes, PAGE_SIZE);
 
        if (size) {
                if (offs > size)
@@ -51,43 +63,56 @@ read(struct file * file, char __user * userbuf, size_t count, loff_t * off)
                        count = size - offs;
        }
 
-       ret = fill_read(dentry, buffer, offs, count);
-       if (ret < 0) 
-               return ret;
-       count = ret;
+       mutex_lock(&bb->mutex);
+
+       count = fill_read(dentry, bb->buffer, offs, count);
+       if (count < 0)
+               goto out_unlock;
 
-       if (copy_to_user(userbuf, buffer, count))
-               return -EFAULT;
+       if (copy_to_user(userbuf, bb->buffer, count)) {
+               count = -EFAULT;
+               goto out_unlock;
+       }
 
-       pr_debug("offs = %lld, *off = %lld, count = %zd\n", offs, *off, count);
+       pr_debug("offs = %lld, *off = %lld, count = %d\n", offs, *off, count);
 
        *off = offs + count;
 
+ out_unlock:
+       mutex_unlock(&bb->mutex);
        return count;
 }
 
 static int
 flush_write(struct dentry *dentry, char *buffer, loff_t offset, size_t count)
 {
-       struct bin_attribute *attr = to_bin_attr(dentry);
-       struct kobject *kobj = to_kobj(dentry->d_parent);
+       struct sysfs_dirent *attr_sd = dentry->d_fsdata;
+       struct bin_attribute *attr = attr_sd->s_elem.bin_attr.bin_attr;
+       struct kobject *kobj = attr_sd->s_parent->s_elem.dir.kobj;
+       int rc;
+
+       /* need attr_sd for attr, its parent for kobj */
+       if (!sysfs_get_active_two(attr_sd))
+               return -ENODEV;
+
+       rc = -EIO;
+       if (attr->write)
+               rc = attr->write(kobj, attr, buffer, offset, count);
 
-       if (!attr->write)
-               return -EIO;
+       sysfs_put_active_two(attr_sd);
 
-       return attr->write(kobj, buffer, offset, count);
+       return rc;
 }
 
-static ssize_t write(struct file * file, const char __user * userbuf,
-                    size_t count, loff_t * off)
+static ssize_t write(struct file *file, const char __user *userbuf,
+                    size_t bytes, loff_t *off)
 {
-       char *buffer = file->private_data;
+       struct bin_buffer *bb = file->private_data;
        struct dentry *dentry = file->f_path.dentry;
        int size = dentry->d_inode->i_size;
        loff_t offs = *off;
+       int count = min_t(size_t, bytes, PAGE_SIZE);
 
-       if (count > PAGE_SIZE)
-               count = PAGE_SIZE;
        if (size) {
                if (offs > size)
                        return 0;
@@ -95,72 +120,100 @@ static ssize_t write(struct file * file, const char __user * userbuf,
                        count = size - offs;
        }
 
-       if (copy_from_user(buffer, userbuf, count))
-               return -EFAULT;
+       mutex_lock(&bb->mutex);
 
-       count = flush_write(dentry, buffer, offs, count);
+       if (copy_from_user(bb->buffer, userbuf, count)) {
+               count = -EFAULT;
+               goto out_unlock;
+       }
+
+       count = flush_write(dentry, bb->buffer, offs, count);
        if (count > 0)
                *off = offs + count;
+
+ out_unlock:
+       mutex_unlock(&bb->mutex);
        return count;
 }
 
 static int mmap(struct file *file, struct vm_area_struct *vma)
 {
-       struct dentry *dentry = file->f_path.dentry;
-       struct bin_attribute *attr = to_bin_attr(dentry);
-       struct kobject *kobj = to_kobj(dentry->d_parent);
+       struct bin_buffer *bb = file->private_data;
+       struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
+       struct bin_attribute *attr = attr_sd->s_elem.bin_attr.bin_attr;
+       struct kobject *kobj = attr_sd->s_parent->s_elem.dir.kobj;
+       int rc;
+
+       mutex_lock(&bb->mutex);
+
+       /* need attr_sd for attr, its parent for kobj */
+       if (!sysfs_get_active_two(attr_sd))
+               return -ENODEV;
 
-       if (!attr->mmap)
-               return -EINVAL;
+       rc = -EINVAL;
+       if (attr->mmap)
+               rc = attr->mmap(kobj, attr, vma);
 
-       return attr->mmap(kobj, attr, vma);
+       if (rc == 0 && !bb->mmapped)
+               bb->mmapped = 1;
+       else
+               sysfs_put_active_two(attr_sd);
+
+       mutex_unlock(&bb->mutex);
+
+       return rc;
 }
 
 static int open(struct inode * inode, struct file * file)
 {
-       struct kobject *kobj = sysfs_get_kobject(file->f_path.dentry->d_parent);
-       struct bin_attribute * attr = to_bin_attr(file->f_path.dentry);
-       int error = -EINVAL;
-
-       if (!kobj || !attr)
-               goto Done;
+       struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
+       struct bin_attribute *attr = attr_sd->s_elem.bin_attr.bin_attr;
+       struct bin_buffer *bb = NULL;
+       int error;
 
-       /* Grab the module reference for this attribute if we have one */
-       error = -ENODEV;
-       if (!try_module_get(attr->attr.owner)) 
-               goto Done;
+       /* need attr_sd for attr */
+       if (!sysfs_get_active(attr_sd))
+               return -ENODEV;
 
        error = -EACCES;
        if ((file->f_mode & FMODE_WRITE) && !(attr->write || attr->mmap))
-               goto Error;
+               goto err_out;
        if ((file->f_mode & FMODE_READ) && !(attr->read || attr->mmap))
-               goto Error;
+               goto err_out;
 
        error = -ENOMEM;
-       file->private_data = kmalloc(PAGE_SIZE, GFP_KERNEL);
-       if (!file->private_data)
-               goto Error;
-
-       error = 0;
-    goto Done;
-
- Error:
-       module_put(attr->attr.owner);
- Done:
-       if (error)
-               kobject_put(kobj);
+       bb = kzalloc(sizeof(*bb), GFP_KERNEL);
+       if (!bb)
+               goto err_out;
+
+       bb->buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);
+       if (!bb->buffer)
+               goto err_out;
+
+       mutex_init(&bb->mutex);
+       file->private_data = bb;
+
+       /* open succeeded, put active reference and pin attr_sd */
+       sysfs_put_active(attr_sd);
+       sysfs_get(attr_sd);
+       return 0;
+
+ err_out:
+       sysfs_put_active(attr_sd);
+       kfree(bb);
        return error;
 }
 
 static int release(struct inode * inode, struct file * file)
 {
-       struct kobject * kobj = to_kobj(file->f_path.dentry->d_parent);
-       struct bin_attribute * attr = to_bin_attr(file->f_path.dentry);
-       u8 * buffer = file->private_data;
-
-       kobject_put(kobj);
-       module_put(attr->attr.owner);
-       kfree(buffer);
+       struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
+       struct bin_buffer *bb = file->private_data;
+
+       if (bb->mmapped)
+               sysfs_put_active_two(attr_sd);
+       sysfs_put(attr_sd);
+       kfree(bb->buffer);
+       kfree(bb);
        return 0;
 }
 
@@ -181,9 +234,9 @@ const struct file_operations bin_fops = {
 
 int sysfs_create_bin_file(struct kobject * kobj, struct bin_attribute * attr)
 {
-       BUG_ON(!kobj || !kobj->dentry || !attr);
+       BUG_ON(!kobj || !kobj->sd || !attr);
 
-       return sysfs_add_file(kobj->dentry, &attr->attr, SYSFS_KOBJ_BIN_ATTR);
+       return sysfs_add_file(kobj->sd, &attr->attr, SYSFS_KOBJ_BIN_ATTR);
 }
 
 
@@ -195,7 +248,7 @@ int sysfs_create_bin_file(struct kobject * kobj, struct bin_attribute * attr)
 
 void sysfs_remove_bin_file(struct kobject * kobj, struct bin_attribute * attr)
 {
-       if (sysfs_hash_and_remove(kobj->dentry, attr->attr.name) < 0) {
+       if (sysfs_hash_and_remove(kobj->sd, attr->attr.name) < 0) {
                printk(KERN_ERR "%s: "
                        "bad dentry or inode or no such file: \"%s\"\n",
                        __FUNCTION__, attr->attr.name);
index c4342a0199727b19fe832c4eaff371c0c8e1b9ee..aee966c44aacd1a0c7c89847cca9d0966595f62b 100644 (file)
 #include <linux/module.h>
 #include <linux/kobject.h>
 #include <linux/namei.h>
+#include <linux/idr.h>
+#include <linux/completion.h>
 #include <asm/semaphore.h>
 #include "sysfs.h"
 
-DECLARE_RWSEM(sysfs_rename_sem);
-spinlock_t sysfs_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_MUTEX(sysfs_mutex);
+spinlock_t sysfs_assoc_lock = SPIN_LOCK_UNLOCKED;
+
+static spinlock_t sysfs_ino_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_IDA(sysfs_ino_ida);
+
+/**
+ *     sysfs_link_sibling - link sysfs_dirent into sibling list
+ *     @sd: sysfs_dirent of interest
+ *
+ *     Link @sd into its sibling list which starts from
+ *     sd->s_parent->s_children.
+ *
+ *     Locking:
+ *     mutex_lock(sysfs_mutex)
+ */
+void sysfs_link_sibling(struct sysfs_dirent *sd)
+{
+       struct sysfs_dirent *parent_sd = sd->s_parent;
+
+       BUG_ON(sd->s_sibling);
+       sd->s_sibling = parent_sd->s_children;
+       parent_sd->s_children = sd;
+}
+
+/**
+ *     sysfs_unlink_sibling - unlink sysfs_dirent from sibling list
+ *     @sd: sysfs_dirent of interest
+ *
+ *     Unlink @sd from its sibling list which starts from
+ *     sd->s_parent->s_children.
+ *
+ *     Locking:
+ *     mutex_lock(sysfs_mutex)
+ */
+void sysfs_unlink_sibling(struct sysfs_dirent *sd)
+{
+       struct sysfs_dirent **pos;
+
+       for (pos = &sd->s_parent->s_children; *pos; pos = &(*pos)->s_sibling) {
+               if (*pos == sd) {
+                       *pos = sd->s_sibling;
+                       sd->s_sibling = NULL;
+                       break;
+               }
+       }
+}
+
+/**
+ *     sysfs_get_dentry - get dentry for the given sysfs_dirent
+ *     @sd: sysfs_dirent of interest
+ *
+ *     Get dentry for @sd.  Dentry is looked up if currently not
+ *     present.  This function climbs sysfs_dirent tree till it
+ *     reaches a sysfs_dirent with valid dentry attached and descends
+ *     down from there looking up dentry for each step.
+ *
+ *     LOCKING:
+ *     Kernel thread context (may sleep)
+ *
+ *     RETURNS:
+ *     Pointer to found dentry on success, ERR_PTR() value on error.
+ */
+struct dentry *sysfs_get_dentry(struct sysfs_dirent *sd)
+{
+       struct sysfs_dirent *cur;
+       struct dentry *parent_dentry, *dentry;
+       int i, depth;
+
+       /* Find the first parent which has valid s_dentry and get the
+        * dentry.
+        */
+       mutex_lock(&sysfs_mutex);
+ restart0:
+       spin_lock(&sysfs_assoc_lock);
+ restart1:
+       spin_lock(&dcache_lock);
+
+       dentry = NULL;
+       depth = 0;
+       cur = sd;
+       while (!cur->s_dentry || !cur->s_dentry->d_inode) {
+               if (cur->s_flags & SYSFS_FLAG_REMOVED) {
+                       dentry = ERR_PTR(-ENOENT);
+                       depth = 0;
+                       break;
+               }
+               cur = cur->s_parent;
+               depth++;
+       }
+       if (!IS_ERR(dentry))
+               dentry = dget_locked(cur->s_dentry);
+
+       spin_unlock(&dcache_lock);
+       spin_unlock(&sysfs_assoc_lock);
+
+       /* from the found dentry, look up depth times */
+       while (depth--) {
+               /* find and get depth'th ancestor */
+               for (cur = sd, i = 0; cur && i < depth; i++)
+                       cur = cur->s_parent;
+
+               /* This can happen if tree structure was modified due
+                * to move/rename.  Restart.
+                */
+               if (i != depth) {
+                       dput(dentry);
+                       goto restart0;
+               }
+
+               sysfs_get(cur);
+
+               mutex_unlock(&sysfs_mutex);
+
+               /* look it up */
+               parent_dentry = dentry;
+               dentry = lookup_one_len_kern(cur->s_name, parent_dentry,
+                                            strlen(cur->s_name));
+               dput(parent_dentry);
+
+               if (IS_ERR(dentry)) {
+                       sysfs_put(cur);
+                       return dentry;
+               }
+
+               mutex_lock(&sysfs_mutex);
+               spin_lock(&sysfs_assoc_lock);
+
+               /* This, again, can happen if tree structure has
+                * changed and we looked up the wrong thing.  Restart.
+                */
+               if (cur->s_dentry != dentry) {
+                       dput(dentry);
+                       sysfs_put(cur);
+                       goto restart1;
+               }
+
+               spin_unlock(&sysfs_assoc_lock);
+
+               sysfs_put(cur);
+       }
+
+       mutex_unlock(&sysfs_mutex);
+       return dentry;
+}
+
+/**
+ *     sysfs_get_active - get an active reference to sysfs_dirent
+ *     @sd: sysfs_dirent to get an active reference to
+ *
+ *     Get an active reference of @sd.  This function is noop if @sd
+ *     is NULL.
+ *
+ *     RETURNS:
+ *     Pointer to @sd on success, NULL on failure.
+ */
+struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd)
+{
+       if (unlikely(!sd))
+               return NULL;
+
+       while (1) {
+               int v, t;
+
+               v = atomic_read(&sd->s_active);
+               if (unlikely(v < 0))
+                       return NULL;
+
+               t = atomic_cmpxchg(&sd->s_active, v, v + 1);
+               if (likely(t == v))
+                       return sd;
+               if (t < 0)
+                       return NULL;
+
+               cpu_relax();
+       }
+}
+
+/**
+ *     sysfs_put_active - put an active reference to sysfs_dirent
+ *     @sd: sysfs_dirent to put an active reference to
+ *
+ *     Put an active reference to @sd.  This function is noop if @sd
+ *     is NULL.
+ */
+void sysfs_put_active(struct sysfs_dirent *sd)
+{
+       struct completion *cmpl;
+       int v;
+
+       if (unlikely(!sd))
+               return;
+
+       v = atomic_dec_return(&sd->s_active);
+       if (likely(v != SD_DEACTIVATED_BIAS))
+               return;
+
+       /* atomic_dec_return() is a mb(), we'll always see the updated
+        * sd->s_sibling.
+        */
+       cmpl = (void *)sd->s_sibling;
+       complete(cmpl);
+}
+
+/**
+ *     sysfs_get_active_two - get active references to sysfs_dirent and parent
+ *     @sd: sysfs_dirent of interest
+ *
+ *     Get active reference to @sd and its parent.  Parent's active
+ *     reference is grabbed first.  This function is noop if @sd is
+ *     NULL.
+ *
+ *     RETURNS:
+ *     Pointer to @sd on success, NULL on failure.
+ */
+struct sysfs_dirent *sysfs_get_active_two(struct sysfs_dirent *sd)
+{
+       if (sd) {
+               if (sd->s_parent && unlikely(!sysfs_get_active(sd->s_parent)))
+                       return NULL;
+               if (unlikely(!sysfs_get_active(sd))) {
+                       sysfs_put_active(sd->s_parent);
+                       return NULL;
+               }
+       }
+       return sd;
+}
+
+/**
+ *     sysfs_put_active_two - put active references to sysfs_dirent and parent
+ *     @sd: sysfs_dirent of interest
+ *
+ *     Put active references to @sd and its parent.  This function is
+ *     noop if @sd is NULL.
+ */
+void sysfs_put_active_two(struct sysfs_dirent *sd)
+{
+       if (sd) {
+               sysfs_put_active(sd);
+               sysfs_put_active(sd->s_parent);
+       }
+}
+
+/**
+ *     sysfs_deactivate - deactivate sysfs_dirent
+ *     @sd: sysfs_dirent to deactivate
+ *
+ *     Deny new active references and drain existing ones.
+ */
+static void sysfs_deactivate(struct sysfs_dirent *sd)
+{
+       DECLARE_COMPLETION_ONSTACK(wait);
+       int v;
+
+       BUG_ON(sd->s_sibling || !(sd->s_flags & SYSFS_FLAG_REMOVED));
+       sd->s_sibling = (void *)&wait;
+
+       /* atomic_add_return() is a mb(), put_active() will always see
+        * the updated sd->s_sibling.
+        */
+       v = atomic_add_return(SD_DEACTIVATED_BIAS, &sd->s_active);
+
+       if (v != SD_DEACTIVATED_BIAS)
+               wait_for_completion(&wait);
+
+       sd->s_sibling = NULL;
+}
+
+static int sysfs_alloc_ino(ino_t *pino)
+{
+       int ino, rc;
+
+ retry:
+       spin_lock(&sysfs_ino_lock);
+       rc = ida_get_new_above(&sysfs_ino_ida, 2, &ino);
+       spin_unlock(&sysfs_ino_lock);
+
+       if (rc == -EAGAIN) {
+               if (ida_pre_get(&sysfs_ino_ida, GFP_KERNEL))
+                       goto retry;
+               rc = -ENOMEM;
+       }
+
+       *pino = ino;
+       return rc;
+}
+
+static void sysfs_free_ino(ino_t ino)
+{
+       spin_lock(&sysfs_ino_lock);
+       ida_remove(&sysfs_ino_ida, ino);
+       spin_unlock(&sysfs_ino_lock);
+}
+
+void release_sysfs_dirent(struct sysfs_dirent * sd)
+{
+       struct sysfs_dirent *parent_sd;
+
+ repeat:
+       /* Moving/renaming is always done while holding reference.
+        * sd->s_parent won't change beneath us.
+        */
+       parent_sd = sd->s_parent;
+
+       if (sysfs_type(sd) == SYSFS_KOBJ_LINK)
+               sysfs_put(sd->s_elem.symlink.target_sd);
+       if (sysfs_type(sd) & SYSFS_COPY_NAME)
+               kfree(sd->s_name);
+       kfree(sd->s_iattr);
+       sysfs_free_ino(sd->s_ino);
+       kmem_cache_free(sysfs_dir_cachep, sd);
+
+       sd = parent_sd;
+       if (sd && atomic_dec_and_test(&sd->s_count))
+               goto repeat;
+}
 
 static void sysfs_d_iput(struct dentry * dentry, struct inode * inode)
 {
        struct sysfs_dirent * sd = dentry->d_fsdata;
 
        if (sd) {
-               /* sd->s_dentry is protected with sysfs_lock.  This
-                * allows sysfs_drop_dentry() to dereference it.
+               /* sd->s_dentry is protected with sysfs_assoc_lock.
+                * This allows sysfs_drop_dentry() to dereference it.
                 */
-               spin_lock(&sysfs_lock);
+               spin_lock(&sysfs_assoc_lock);
 
                /* The dentry might have been deleted or another
                 * lookup could have happened updating sd->s_dentry to
@@ -32,7 +348,7 @@ static void sysfs_d_iput(struct dentry * dentry, struct inode * inode)
                 */
                if (sd->s_dentry == dentry)
                        sd->s_dentry = NULL;
-               spin_unlock(&sysfs_lock);
+               spin_unlock(&sysfs_assoc_lock);
                sysfs_put(sd);
        }
        iput(inode);
@@ -42,260 +358,402 @@ static struct dentry_operations sysfs_dentry_ops = {
        .d_iput         = sysfs_d_iput,
 };
 
-static unsigned int sysfs_inode_counter;
-ino_t sysfs_get_inum(void)
+struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type)
 {
-       if (unlikely(sysfs_inode_counter < 3))
-               sysfs_inode_counter = 3;
-       return sysfs_inode_counter++;
-}
+       char *dup_name = NULL;
+       struct sysfs_dirent *sd = NULL;
 
-/*
- * Allocates a new sysfs_dirent and links it to the parent sysfs_dirent
- */
-static struct sysfs_dirent * __sysfs_new_dirent(void * element)
-{
-       struct sysfs_dirent * sd;
+       if (type & SYSFS_COPY_NAME) {
+               name = dup_name = kstrdup(name, GFP_KERNEL);
+               if (!name)
+                       goto err_out;
+       }
 
        sd = kmem_cache_zalloc(sysfs_dir_cachep, GFP_KERNEL);
        if (!sd)
-               return NULL;
+               goto err_out;
+
+       if (sysfs_alloc_ino(&sd->s_ino))
+               goto err_out;
 
-       sd->s_ino = sysfs_get_inum();
        atomic_set(&sd->s_count, 1);
+       atomic_set(&sd->s_active, 0);
        atomic_set(&sd->s_event, 1);
-       INIT_LIST_HEAD(&sd->s_children);
-       INIT_LIST_HEAD(&sd->s_sibling);
-       sd->s_element = element;
+
+       sd->s_name = name;
+       sd->s_mode = mode;
+       sd->s_flags = type;
 
        return sd;
+
+ err_out:
+       kfree(dup_name);
+       kmem_cache_free(sysfs_dir_cachep, sd);
+       return NULL;
 }
 
-static void __sysfs_list_dirent(struct sysfs_dirent *parent_sd,
-                             struct sysfs_dirent *sd)
+/**
+ *     sysfs_attach_dentry - associate sysfs_dirent with dentry
+ *     @sd: target sysfs_dirent
+ *     @dentry: dentry to associate
+ *
+ *     Associate @sd with @dentry.  This is protected by
+ *     sysfs_assoc_lock to avoid race with sysfs_d_iput().
+ *
+ *     LOCKING:
+ *     mutex_lock(sysfs_mutex)
+ */
+static void sysfs_attach_dentry(struct sysfs_dirent *sd, struct dentry *dentry)
 {
-       if (sd)
-               list_add(&sd->s_sibling, &parent_sd->s_children);
+       dentry->d_op = &sysfs_dentry_ops;
+       dentry->d_fsdata = sysfs_get(sd);
+
+       /* protect sd->s_dentry against sysfs_d_iput */
+       spin_lock(&sysfs_assoc_lock);
+       sd->s_dentry = dentry;
+       spin_unlock(&sysfs_assoc_lock);
+
+       d_rehash(dentry);
 }
 
-static struct sysfs_dirent * sysfs_new_dirent(struct sysfs_dirent *parent_sd,
-                                               void * element)
+static int sysfs_ilookup_test(struct inode *inode, void *arg)
 {
-       struct sysfs_dirent *sd;
-       sd = __sysfs_new_dirent(element);
-       __sysfs_list_dirent(parent_sd, sd);
-       return sd;
+       struct sysfs_dirent *sd = arg;
+       return inode->i_ino == sd->s_ino;
 }
 
-/*
+/**
+ *     sysfs_addrm_start - prepare for sysfs_dirent add/remove
+ *     @acxt: pointer to sysfs_addrm_cxt to be used
+ *     @parent_sd: parent sysfs_dirent
  *
- * Return -EEXIST if there is already a sysfs element with the same name for
- * the same parent.
+ *     This function is called when the caller is about to add or
+ *     remove sysfs_dirent under @parent_sd.  This function acquires
+ *     sysfs_mutex, grabs inode for @parent_sd if available and lock
+ *     i_mutex of it.  @acxt is used to keep and pass context to
+ *     other addrm functions.
  *
- * called with parent inode's i_mutex held
+ *     LOCKING:
+ *     Kernel thread context (may sleep).  sysfs_mutex is locked on
+ *     return.  i_mutex of parent inode is locked on return if
+ *     available.
  */
-int sysfs_dirent_exist(struct sysfs_dirent *parent_sd,
-                         const unsigned char *new)
+void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
+                      struct sysfs_dirent *parent_sd)
 {
-       struct sysfs_dirent * sd;
+       struct inode *inode;
 
-       list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
-               if (sd->s_element) {
-                       const unsigned char *existing = sysfs_get_name(sd);
-                       if (strcmp(existing, new))
-                               continue;
-                       else
-                               return -EEXIST;
-               }
-       }
+       memset(acxt, 0, sizeof(*acxt));
+       acxt->parent_sd = parent_sd;
 
-       return 0;
+       /* Lookup parent inode.  inode initialization and I_NEW
+        * clearing are protected by sysfs_mutex.  By grabbing it and
+        * looking up with _nowait variant, inode state can be
+        * determined reliably.
+        */
+       mutex_lock(&sysfs_mutex);
+
+       inode = ilookup5_nowait(sysfs_sb, parent_sd->s_ino, sysfs_ilookup_test,
+                               parent_sd);
+
+       if (inode && !(inode->i_state & I_NEW)) {
+               /* parent inode available */
+               acxt->parent_inode = inode;
+
+               /* sysfs_mutex is below i_mutex in lock hierarchy.
+                * First, trylock i_mutex.  If fails, unlock
+                * sysfs_mutex and lock them in order.
+                */
+               if (!mutex_trylock(&inode->i_mutex)) {
+                       mutex_unlock(&sysfs_mutex);
+                       mutex_lock(&inode->i_mutex);
+                       mutex_lock(&sysfs_mutex);
+               }
+       } else
+               iput(inode);
 }
 
+/**
+ *     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.  @sd is NOT
+ *     linked into the children list of the parent.  The caller
+ *     should invoke sysfs_link_sibling() after this function
+ *     completes if @sd needs to be on the children list.
+ *
+ *     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().
+ */
+void sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
+{
+       sd->s_parent = sysfs_get(acxt->parent_sd);
+
+       if (sysfs_type(sd) == SYSFS_DIR && acxt->parent_inode)
+               inc_nlink(acxt->parent_inode);
+
+       acxt->cnt++;
+}
 
-static struct sysfs_dirent *
-__sysfs_make_dirent(struct dentry *dentry, void *element, mode_t mode, int type)
+/**
+ *     sysfs_remove_one - remove sysfs_dirent from parent
+ *     @acxt: addrm context to use
+ *     @sd: sysfs_dirent to be added
+ *
+ *     Mark @sd removed and drop nlink of parent inode if @sd is a
+ *     directory.  @sd is NOT unlinked from the children list of the
+ *     parent.  The caller is repsonsible for removing @sd from the
+ *     children list before calling this function.
+ *
+ *     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().
+ */
+void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
 {
-       struct sysfs_dirent * sd;
+       BUG_ON(sd->s_sibling || (sd->s_flags & SYSFS_FLAG_REMOVED));
 
-       sd = __sysfs_new_dirent(element);
-       if (!sd)
-               goto out;
+       sd->s_flags |= SYSFS_FLAG_REMOVED;
+       sd->s_sibling = acxt->removed;
+       acxt->removed = sd;
 
-       sd->s_mode = mode;
-       sd->s_type = type;
-       sd->s_dentry = dentry;
-       if (dentry) {
-               dentry->d_fsdata = sysfs_get(sd);
-               dentry->d_op = &sysfs_dentry_ops;
-       }
+       if (sysfs_type(sd) == SYSFS_DIR && acxt->parent_inode)
+               drop_nlink(acxt->parent_inode);
 
-out:
-       return sd;
+       acxt->cnt++;
 }
 
-int sysfs_make_dirent(struct sysfs_dirent * parent_sd, struct dentry * dentry,
-                       void * element, umode_t mode, int type)
+/**
+ *     sysfs_drop_dentry - drop dentry for the specified sysfs_dirent
+ *     @sd: target sysfs_dirent
+ *
+ *     Drop dentry for @sd.  @sd must have been unlinked from its
+ *     parent on entry to this function such that it can't be looked
+ *     up anymore.
+ *
+ *     @sd->s_dentry which is protected with sysfs_assoc_lock points
+ *     to the currently associated dentry but we're not holding a
+ *     reference to it and racing with dput().  Grab dcache_lock and
+ *     verify dentry before dropping it.  If @sd->s_dentry is NULL or
+ *     dput() beats us, no need to bother.
+ */
+static void sysfs_drop_dentry(struct sysfs_dirent *sd)
 {
-       struct sysfs_dirent *sd;
+       struct dentry *dentry = NULL;
+       struct inode *inode;
+
+       /* We're not holding a reference to ->s_dentry dentry but the
+        * field will stay valid as long as sysfs_assoc_lock is held.
+        */
+       spin_lock(&sysfs_assoc_lock);
+       spin_lock(&dcache_lock);
+
+       /* drop dentry if it's there and dput() didn't kill it yet */
+       if (sd->s_dentry && sd->s_dentry->d_inode) {
+               dentry = dget_locked(sd->s_dentry);
+               spin_lock(&dentry->d_lock);
+               __d_drop(dentry);
+               spin_unlock(&dentry->d_lock);
+       }
 
-       sd = __sysfs_make_dirent(dentry, element, mode, type);
-       __sysfs_list_dirent(parent_sd, sd);
+       spin_unlock(&dcache_lock);
+       spin_unlock(&sysfs_assoc_lock);
 
-       return sd ? 0 : -ENOMEM;
+       /* dentries for shadowed inodes are pinned, unpin */
+       if (dentry && sysfs_is_shadowed_inode(dentry->d_inode))
+               dput(dentry);
+       dput(dentry);
+
+       /* adjust nlink and update timestamp */
+       inode = ilookup(sysfs_sb, sd->s_ino);
+       if (inode) {
+               mutex_lock(&inode->i_mutex);
+
+               inode->i_ctime = CURRENT_TIME;
+               drop_nlink(inode);
+               if (sysfs_type(sd) == SYSFS_DIR)
+                       drop_nlink(inode);
+
+               mutex_unlock(&inode->i_mutex);
+               iput(inode);
+       }
 }
 
-static int init_dir(struct inode * inode)
+/**
+ *     sysfs_addrm_finish - finish up sysfs_dirent add/remove
+ *     @acxt: addrm context to finish up
+ *
+ *     Finish up sysfs_dirent add/remove.  Resources acquired by
+ *     sysfs_addrm_start() are released and removed sysfs_dirents are
+ *     cleaned up.  Timestamps on the parent inode are updated.
+ *
+ *     LOCKING:
+ *     All mutexes acquired by sysfs_addrm_start() are released.
+ *
+ *     RETURNS:
+ *     Number of added/removed sysfs_dirents since sysfs_addrm_start().
+ */
+int sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt)
 {
-       inode->i_op = &sysfs_dir_inode_operations;
-       inode->i_fop = &sysfs_dir_operations;
+       /* release resources acquired by sysfs_addrm_start() */
+       mutex_unlock(&sysfs_mutex);
+       if (acxt->parent_inode) {
+               struct inode *inode = acxt->parent_inode;
 
-       /* directory inodes start off with i_nlink == 2 (for "." entry) */
-       inc_nlink(inode);
-       return 0;
+               /* if added/removed, update timestamps on the parent */
+               if (acxt->cnt)
+                       inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+
+               mutex_unlock(&inode->i_mutex);
+               iput(inode);
+       }
+
+       /* kill removed sysfs_dirents */
+       while (acxt->removed) {
+               struct sysfs_dirent *sd = acxt->removed;
+
+               acxt->removed = sd->s_sibling;
+               sd->s_sibling = NULL;
+
+               sysfs_drop_dentry(sd);
+               sysfs_deactivate(sd);
+               sysfs_put(sd);
+       }
+
+       return acxt->cnt;
 }
 
-static int init_file(struct inode * inode)
+/**
+ *     sysfs_find_dirent - find sysfs_dirent with the given name
+ *     @parent_sd: sysfs_dirent to search under
+ *     @name: name to look for
+ *
+ *     Look for sysfs_dirent with name @name under @parent_sd.
+ *
+ *     LOCKING:
+ *     mutex_lock(sysfs_mutex)
+ *
+ *     RETURNS:
+ *     Pointer to sysfs_dirent if found, NULL if not.
+ */
+struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
+                                      const unsigned char *name)
 {
-       inode->i_size = PAGE_SIZE;
-       inode->i_fop = &sysfs_file_operations;
-       return 0;
+       struct sysfs_dirent *sd;
+
+       for (sd = parent_sd->s_children; sd; sd = sd->s_sibling)
+               if (sysfs_type(sd) && !strcmp(sd->s_name, name))
+                       return sd;
+       return NULL;
 }
 
-static int init_symlink(struct inode * inode)
+/**
+ *     sysfs_get_dirent - find and get sysfs_dirent with the given name
+ *     @parent_sd: sysfs_dirent to search under
+ *     @name: name to look for
+ *
+ *     Look for sysfs_dirent with name @name under @parent_sd and get
+ *     it if found.
+ *
+ *     LOCKING:
+ *     Kernel thread context (may sleep).  Grabs sysfs_mutex.
+ *
+ *     RETURNS:
+ *     Pointer to sysfs_dirent if found, NULL if not.
+ */
+struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd,
+                                     const unsigned char *name)
 {
-       inode->i_op = &sysfs_symlink_inode_operations;
-       return 0;
+       struct sysfs_dirent *sd;
+
+       mutex_lock(&sysfs_mutex);
+       sd = sysfs_find_dirent(parent_sd, name);
+       sysfs_get(sd);
+       mutex_unlock(&sysfs_mutex);
+
+       return sd;
 }
 
-static int create_dir(struct kobject * k, struct dentry * p,
-                     const char * n, struct dentry ** d)
+static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd,
+                     const char *name, struct sysfs_dirent **p_sd)
 {
-       int error;
        umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO;
+       struct sysfs_addrm_cxt acxt;
+       struct sysfs_dirent *sd;
 
-       mutex_lock(&p->d_inode->i_mutex);
-       *d = lookup_one_len(n, p, strlen(n));
-       if (!IS_ERR(*d)) {
-               if (sysfs_dirent_exist(p->d_fsdata, n))
-                       error = -EEXIST;
-               else
-                       error = sysfs_make_dirent(p->d_fsdata, *d, k, mode,
-                                                               SYSFS_DIR);
-               if (!error) {
-                       error = sysfs_create(*d, mode, init_dir);
-                       if (!error) {
-                               inc_nlink(p->d_inode);
-                               (*d)->d_op = &sysfs_dentry_ops;
-                               d_rehash(*d);
-                       }
-               }
-               if (error && (error != -EEXIST)) {
-                       struct sysfs_dirent *sd = (*d)->d_fsdata;
-                       if (sd) {
-                               list_del_init(&sd->s_sibling);
-                               sysfs_put(sd);
-                       }
-                       d_drop(*d);
-               }
-               dput(*d);
-       } else
-               error = PTR_ERR(*d);
-       mutex_unlock(&p->d_inode->i_mutex);
-       return error;
-}
+       /* allocate */
+       sd = sysfs_new_dirent(name, mode, SYSFS_DIR);
+       if (!sd)
+               return -ENOMEM;
+       sd->s_elem.dir.kobj = kobj;
 
+       /* link in */
+       sysfs_addrm_start(&acxt, parent_sd);
+       if (!sysfs_find_dirent(parent_sd, name)) {
+               sysfs_add_one(&acxt, sd);
+               sysfs_link_sibling(sd);
+       }
+       if (sysfs_addrm_finish(&acxt)) {
+               *p_sd = sd;
+               return 0;
+       }
 
-int sysfs_create_subdir(struct kobject * k, const char * n, struct dentry ** d)
+       sysfs_put(sd);
+       return -EEXIST;
+}
+
+int sysfs_create_subdir(struct kobject *kobj, const char *name,
+                       struct sysfs_dirent **p_sd)
 {
-       return create_dir(k,k->dentry,n,d);
+       return create_dir(kobj, kobj->sd, name, p_sd);
 }
 
 /**
  *     sysfs_create_dir - create a directory for an object.
  *     @kobj:          object we're creating directory for. 
- *     @shadow_parent: parent parent object.
+ *     @shadow_parent: parent object.
  */
-
-int sysfs_create_dir(struct kobject * kobj, struct dentry *shadow_parent)
+int sysfs_create_dir(struct kobject *kobj,
+                    struct sysfs_dirent *shadow_parent_sd)
 {
-       struct dentry * dentry = NULL;
-       struct dentry * parent;
+       struct sysfs_dirent *parent_sd, *sd;
        int error = 0;
 
        BUG_ON(!kobj);
 
-       if (shadow_parent)
-               parent = shadow_parent;
+       if (shadow_parent_sd)
+               parent_sd = shadow_parent_sd;
        else if (kobj->parent)
-               parent = kobj->parent->dentry;
+               parent_sd = kobj->parent->sd;
        else if (sysfs_mount && sysfs_mount->mnt_sb)
-               parent = sysfs_mount->mnt_sb->s_root;
+               parent_sd = sysfs_mount->mnt_sb->s_root->d_fsdata;
        else
                return -EFAULT;
 
-       error = create_dir(kobj,parent,kobject_name(kobj),&dentry);
+       error = create_dir(kobj, parent_sd, kobject_name(kobj), &sd);
        if (!error)
-               kobj->dentry = dentry;
+               kobj->sd = sd;
        return error;
 }
 
-/* attaches attribute's sysfs_dirent to the dentry corresponding to the
- * attribute file
- */
-static int sysfs_attach_attr(struct sysfs_dirent * sd, struct dentry * dentry)
+static int sysfs_count_nlink(struct sysfs_dirent *sd)
 {
-       struct attribute * attr = NULL;
-       struct bin_attribute * bin_attr = NULL;
-       int (* init) (struct inode *) = NULL;
-       int error = 0;
-
-        if (sd->s_type & SYSFS_KOBJ_BIN_ATTR) {
-                bin_attr = sd->s_element;
-                attr = &bin_attr->attr;
-        } else {
-                attr = sd->s_element;
-                init = init_file;
-        }
+       struct sysfs_dirent *child;
+       int nr = 0;
 
-       dentry->d_fsdata = sysfs_get(sd);
-       /* protect sd->s_dentry against sysfs_d_iput */
-       spin_lock(&sysfs_lock);
-       sd->s_dentry = dentry;
-       spin_unlock(&sysfs_lock);
-       error = sysfs_create(dentry, (attr->mode & S_IALLUGO) | S_IFREG, init);
-       if (error) {
-               sysfs_put(sd);
-               return error;
-       }
-
-        if (bin_attr) {
-               dentry->d_inode->i_size = bin_attr->size;
-               dentry->d_inode->i_fop = &bin_fops;
-       }
-       dentry->d_op = &sysfs_dentry_ops;
-       d_rehash(dentry);
-
-       return 0;
-}
-
-static int sysfs_attach_link(struct sysfs_dirent * sd, struct dentry * dentry)
-{
-       int err = 0;
-
-       dentry->d_fsdata = sysfs_get(sd);
-       /* protect sd->s_dentry against sysfs_d_iput */
-       spin_lock(&sysfs_lock);
-       sd->s_dentry = dentry;
-       spin_unlock(&sysfs_lock);
-       err = sysfs_create(dentry, S_IFLNK|S_IRWXUGO, init_symlink);
-       if (!err) {
-               dentry->d_op = &sysfs_dentry_ops;
-               d_rehash(dentry);
-       } else
-               sysfs_put(sd);
-
-       return err;
+       for (child = sd->s_children; child; child = child->s_sibling)
+               if (sysfs_type(child) == SYSFS_DIR)
+                       nr++;
+       return nr + 2;
 }
 
 static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry,
@@ -303,24 +761,60 @@ static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry,
 {
        struct sysfs_dirent * parent_sd = dentry->d_parent->d_fsdata;
        struct sysfs_dirent * sd;
-       int err = 0;
+       struct bin_attribute *bin_attr;
+       struct inode *inode;
+       int found = 0;
 
-       list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
-               if (sd->s_type & SYSFS_NOT_PINNED) {
-                       const unsigned char * name = sysfs_get_name(sd);
+       for (sd = parent_sd->s_children; sd; sd = sd->s_sibling) {
+               if (sysfs_type(sd) &&
+                   !strcmp(sd->s_name, dentry->d_name.name)) {
+                       found = 1;
+                       break;
+               }
+       }
 
-                       if (strcmp(name, dentry->d_name.name))
-                               continue;
+       /* no such entry */
+       if (!found)
+               return NULL;
 
-                       if (sd->s_type & SYSFS_KOBJ_LINK)
-                               err = sysfs_attach_link(sd, dentry);
-                       else
-                               err = sysfs_attach_attr(sd, dentry);
+       /* attach dentry and inode */
+       inode = sysfs_get_inode(sd);
+       if (!inode)
+               return ERR_PTR(-ENOMEM);
+
+       mutex_lock(&sysfs_mutex);
+
+       if (inode->i_state & I_NEW) {
+               /* initialize inode according to type */
+               switch (sysfs_type(sd)) {
+               case SYSFS_DIR:
+                       inode->i_op = &sysfs_dir_inode_operations;
+                       inode->i_fop = &sysfs_dir_operations;
+                       inode->i_nlink = sysfs_count_nlink(sd);
+                       break;
+               case SYSFS_KOBJ_ATTR:
+                       inode->i_size = PAGE_SIZE;
+                       inode->i_fop = &sysfs_file_operations;
+                       break;
+               case SYSFS_KOBJ_BIN_ATTR:
+                       bin_attr = sd->s_elem.bin_attr.bin_attr;
+                       inode->i_size = bin_attr->size;
+                       inode->i_fop = &bin_fops;
                        break;
+               case SYSFS_KOBJ_LINK:
+                       inode->i_op = &sysfs_symlink_inode_operations;
+                       break;
+               default:
+                       BUG();
                }
        }
 
-       return ERR_PTR(err);
+       sysfs_instantiate(dentry, inode);
+       sysfs_attach_dentry(sd, dentry);
+
+       mutex_unlock(&sysfs_mutex);
+
+       return NULL;
 }
 
 const struct inode_operations sysfs_dir_inode_operations = {
@@ -328,58 +822,46 @@ const struct inode_operations sysfs_dir_inode_operations = {
        .setattr        = sysfs_setattr,
 };
 
-static void remove_dir(struct dentry * d)
+static void remove_dir(struct sysfs_dirent *sd)
 {
-       struct dentry * parent = dget(d->d_parent);
-       struct sysfs_dirent * sd;
-
-       mutex_lock(&parent->d_inode->i_mutex);
-       d_delete(d);
-       sd = d->d_fsdata;
-       list_del_init(&sd->s_sibling);
-       sysfs_put(sd);
-       if (d->d_inode)
-               simple_rmdir(parent->d_inode,d);
-
-       pr_debug(" o %s removing done (%d)\n",d->d_name.name,
-                atomic_read(&d->d_count));
+       struct sysfs_addrm_cxt acxt;
 
-       mutex_unlock(&parent->d_inode->i_mutex);
-       dput(parent);
+       sysfs_addrm_start(&acxt, sd->s_parent);
+       sysfs_unlink_sibling(sd);
+       sysfs_remove_one(&acxt, sd);
+       sysfs_addrm_finish(&acxt);
 }
 
-void sysfs_remove_subdir(struct dentry * d)
+void sysfs_remove_subdir(struct sysfs_dirent *sd)
 {
-       remove_dir(d);
+       remove_dir(sd);
 }
 
 
-static void __sysfs_remove_dir(struct dentry *dentry)
+static void __sysfs_remove_dir(struct sysfs_dirent *dir_sd)
 {
-       struct sysfs_dirent * parent_sd;
-       struct sysfs_dirent * sd, * tmp;
+       struct sysfs_addrm_cxt acxt;
+       struct sysfs_dirent **pos;
 
-       dget(dentry);
-       if (!dentry)
+       if (!dir_sd)
                return;
 
-       pr_debug("sysfs %s: removing dir\n",dentry->d_name.name);
-       mutex_lock(&dentry->d_inode->i_mutex);
-       parent_sd = dentry->d_fsdata;
-       list_for_each_entry_safe(sd, tmp, &parent_sd->s_children, s_sibling) {
-               if (!sd->s_element || !(sd->s_type & SYSFS_NOT_PINNED))
-                       continue;
-               list_del_init(&sd->s_sibling);
-               sysfs_drop_dentry(sd, dentry);
-               sysfs_put(sd);
+       pr_debug("sysfs %s: removing dir\n", dir_sd->s_name);
+       sysfs_addrm_start(&acxt, dir_sd);
+       pos = &dir_sd->s_children;
+       while (*pos) {
+               struct sysfs_dirent *sd = *pos;
+
+               if (sysfs_type(sd) && sysfs_type(sd) != SYSFS_DIR) {
+                       *pos = sd->s_sibling;
+                       sd->s_sibling = NULL;
+                       sysfs_remove_one(&acxt, sd);
+               } else
+                       pos = &(*pos)->s_sibling;
        }
-       mutex_unlock(&dentry->d_inode->i_mutex);
+       sysfs_addrm_finish(&acxt);
 
-       remove_dir(dentry);
-       /**
-        * Drop reference from dget() on entrance.
-        */
-       dput(dentry);
+       remove_dir(dir_sd);
 }
 
 /**
@@ -393,102 +875,166 @@ static void __sysfs_remove_dir(struct dentry *dentry)
 
 void sysfs_remove_dir(struct kobject * kobj)
 {
-       __sysfs_remove_dir(kobj->dentry);
-       kobj->dentry = NULL;
+       struct sysfs_dirent *sd = kobj->sd;
+
+       spin_lock(&sysfs_assoc_lock);
+       kobj->sd = NULL;
+       spin_unlock(&sysfs_assoc_lock);
+
+       __sysfs_remove_dir(sd);
 }
 
-int sysfs_rename_dir(struct kobject * kobj, struct dentry *new_parent,
+int sysfs_rename_dir(struct kobject *kobj, struct sysfs_dirent *new_parent_sd,
                     const char *new_name)
 {
-       int error = 0;
-       struct dentry * new_dentry;
+       struct sysfs_dirent *sd = kobj->sd;
+       struct dentry *new_parent = NULL;
+       struct dentry *old_dentry = NULL, *new_dentry = NULL;
+       const char *dup_name = NULL;
+       int error;
 
-       if (!new_parent)
-               return -EFAULT;
+       /* get dentries */
+       old_dentry = sysfs_get_dentry(sd);
+       if (IS_ERR(old_dentry)) {
+               error = PTR_ERR(old_dentry);
+               goto out_dput;
+       }
 
-       down_write(&sysfs_rename_sem);
+       new_parent = sysfs_get_dentry(new_parent_sd);
+       if (IS_ERR(new_parent)) {
+               error = PTR_ERR(new_parent);
+               goto out_dput;
+       }
+
+       /* lock new_parent and get dentry for new name */
        mutex_lock(&new_parent->d_inode->i_mutex);
 
        new_dentry = lookup_one_len(new_name, new_parent, strlen(new_name));
-       if (!IS_ERR(new_dentry)) {
-               /* By allowing two different directories with the
-                * same d_parent we allow this routine to move
-                * between different shadows of the same directory
-                */
-               if (kobj->dentry->d_parent->d_inode != new_parent->d_inode)
-                       return -EINVAL;
-               else if (new_dentry->d_parent->d_inode != new_parent->d_inode)
-                       error = -EINVAL;
-               else if (new_dentry == kobj->dentry)
-                       error = -EINVAL;
-               else if (!new_dentry->d_inode) {
-                       error = kobject_set_name(kobj, "%s", new_name);
-                       if (!error) {
-                               struct sysfs_dirent *sd, *parent_sd;
-
-                               d_add(new_dentry, NULL);
-                               d_move(kobj->dentry, new_dentry);
-
-                               sd = kobj->dentry->d_fsdata;
-                               parent_sd = new_parent->d_fsdata;
-
-                               list_del_init(&sd->s_sibling);
-                               list_add(&sd->s_sibling, &parent_sd->s_children);
-                       }
-                       else
-                               d_drop(new_dentry);
-               } else
-                       error = -EEXIST;
-               dput(new_dentry);
+       if (IS_ERR(new_dentry)) {
+               error = PTR_ERR(new_dentry);
+               goto out_unlock;
        }
-       mutex_unlock(&new_parent->d_inode->i_mutex);
-       up_write(&sysfs_rename_sem);
 
+       /* By allowing two different directories with the same
+        * d_parent we allow this routine to move between different
+        * shadows of the same directory
+        */
+       error = -EINVAL;
+       if (old_dentry->d_parent->d_inode != new_parent->d_inode ||
+           new_dentry->d_parent->d_inode != new_parent->d_inode ||
+           old_dentry == new_dentry)
+               goto out_unlock;
+
+       error = -EEXIST;
+       if (new_dentry->d_inode)
+               goto out_unlock;
+
+       /* rename kobject and sysfs_dirent */
+       error = -ENOMEM;
+       new_name = dup_name = kstrdup(new_name, GFP_KERNEL);
+       if (!new_name)
+               goto out_drop;
+
+       error = kobject_set_name(kobj, "%s", new_name);
+       if (error)
+               goto out_drop;
+
+       dup_name = sd->s_name;
+       sd->s_name = new_name;
+
+       /* move under the new parent */
+       d_add(new_dentry, NULL);
+       d_move(sd->s_dentry, new_dentry);
+
+       mutex_lock(&sysfs_mutex);
+
+       sysfs_unlink_sibling(sd);
+       sysfs_get(new_parent_sd);
+       sysfs_put(sd->s_parent);
+       sd->s_parent = new_parent_sd;
+       sysfs_link_sibling(sd);
+
+       mutex_unlock(&sysfs_mutex);
+
+       error = 0;
+       goto out_unlock;
+
+ out_drop:
+       d_drop(new_dentry);
+ out_unlock:
+       mutex_unlock(&new_parent->d_inode->i_mutex);
+ out_dput:
+       kfree(dup_name);
+       dput(new_parent);
+       dput(old_dentry);
+       dput(new_dentry);
        return error;
 }
 
-int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent)
+int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent_kobj)
 {
-       struct dentry *old_parent_dentry, *new_parent_dentry, *new_dentry;
-       struct sysfs_dirent *new_parent_sd, *sd;
+       struct sysfs_dirent *sd = kobj->sd;
+       struct sysfs_dirent *new_parent_sd;
+       struct dentry *old_parent, *new_parent = NULL;
+       struct dentry *old_dentry = NULL, *new_dentry = NULL;
        int error;
 
-       old_parent_dentry = kobj->parent ?
-               kobj->parent->dentry : sysfs_mount->mnt_sb->s_root;
-       new_parent_dentry = new_parent ?
-               new_parent->dentry : sysfs_mount->mnt_sb->s_root;
+       BUG_ON(!sd->s_parent);
+       new_parent_sd = new_parent_kobj->sd ? new_parent_kobj->sd : &sysfs_root;
+
+       /* get dentries */
+       old_dentry = sysfs_get_dentry(sd);
+       if (IS_ERR(old_dentry)) {
+               error = PTR_ERR(old_dentry);
+               goto out_dput;
+       }
+       old_parent = sd->s_parent->s_dentry;
+
+       new_parent = sysfs_get_dentry(new_parent_sd);
+       if (IS_ERR(new_parent)) {
+               error = PTR_ERR(new_parent);
+               goto out_dput;
+       }
 
-       if (old_parent_dentry->d_inode == new_parent_dentry->d_inode)
-               return 0;       /* nothing to move */
+       if (old_parent->d_inode == new_parent->d_inode) {
+               error = 0;
+               goto out_dput;  /* nothing to move */
+       }
 again:
-       mutex_lock(&old_parent_dentry->d_inode->i_mutex);
-       if (!mutex_trylock(&new_parent_dentry->d_inode->i_mutex)) {
-               mutex_unlock(&old_parent_dentry->d_inode->i_mutex);
+       mutex_lock(&old_parent->d_inode->i_mutex);
+       if (!mutex_trylock(&new_parent->d_inode->i_mutex)) {
+               mutex_unlock(&old_parent->d_inode->i_mutex);
                goto again;
        }
 
-       new_parent_sd = new_parent_dentry->d_fsdata;
-       sd = kobj->dentry->d_fsdata;
-
-       new_dentry = lookup_one_len(kobj->name, new_parent_dentry,
-                                   strlen(kobj->name));
+       new_dentry = lookup_one_len(kobj->name, new_parent, strlen(kobj->name));
        if (IS_ERR(new_dentry)) {
                error = PTR_ERR(new_dentry);
-               goto out;
+               goto out_unlock;
        } else
                error = 0;
        d_add(new_dentry, NULL);
-       d_move(kobj->dentry, new_dentry);
+       d_move(sd->s_dentry, new_dentry);
        dput(new_dentry);
 
        /* Remove from old parent's list and insert into new parent's list. */
-       list_del_init(&sd->s_sibling);
-       list_add(&sd->s_sibling, &new_parent_sd->s_children);
+       mutex_lock(&sysfs_mutex);
+
+       sysfs_unlink_sibling(sd);
+       sysfs_get(new_parent_sd);
+       sysfs_put(sd->s_parent);
+       sd->s_parent = new_parent_sd;
+       sysfs_link_sibling(sd);
 
-out:
-       mutex_unlock(&new_parent_dentry->d_inode->i_mutex);
-       mutex_unlock(&old_parent_dentry->d_inode->i_mutex);
+       mutex_unlock(&sysfs_mutex);
 
+ out_unlock:
+       mutex_unlock(&new_parent->d_inode->i_mutex);
+       mutex_unlock(&old_parent->d_inode->i_mutex);
+ out_dput:
+       dput(new_parent);
+       dput(old_dentry);
+       dput(new_dentry);
        return error;
 }
 
@@ -496,23 +1042,27 @@ static int sysfs_dir_open(struct inode *inode, struct file *file)
 {
        struct dentry * dentry = file->f_path.dentry;
        struct sysfs_dirent * parent_sd = dentry->d_fsdata;
+       struct sysfs_dirent * sd;
 
-       mutex_lock(&dentry->d_inode->i_mutex);
-       file->private_data = sysfs_new_dirent(parent_sd, NULL);
-       mutex_unlock(&dentry->d_inode->i_mutex);
-
-       return file->private_data ? 0 : -ENOMEM;
+       sd = sysfs_new_dirent("_DIR_", 0, 0);
+       if (sd) {
+               mutex_lock(&sysfs_mutex);
+               sd->s_parent = sysfs_get(parent_sd);
+               sysfs_link_sibling(sd);
+               mutex_unlock(&sysfs_mutex);
+       }
 
+       file->private_data = sd;
+       return sd ? 0 : -ENOMEM;
 }
 
 static int sysfs_dir_close(struct inode *inode, struct file *file)
 {
-       struct dentry * dentry = file->f_path.dentry;
        struct sysfs_dirent * cursor = file->private_data;
 
-       mutex_lock(&dentry->d_inode->i_mutex);
-       list_del_init(&cursor->s_sibling);
-       mutex_unlock(&dentry->d_inode->i_mutex);
+       mutex_lock(&sysfs_mutex);
+       sysfs_unlink_sibling(cursor);
+       mutex_unlock(&sysfs_mutex);
 
        release_sysfs_dirent(cursor);
 
@@ -530,7 +1080,7 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
        struct dentry *dentry = filp->f_path.dentry;
        struct sysfs_dirent * parent_sd = dentry->d_fsdata;
        struct sysfs_dirent *cursor = filp->private_data;
-       struct list_head *p, *q = &cursor->s_sibling;
+       struct sysfs_dirent **pos;
        ino_t ino;
        int i = filp->f_pos;
 
@@ -543,38 +1093,52 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
                        i++;
                        /* fallthrough */
                case 1:
-                       ino = parent_ino(dentry);
+                       if (parent_sd->s_parent)
+                               ino = parent_sd->s_parent->s_ino;
+                       else
+                               ino = parent_sd->s_ino;
                        if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0)
                                break;
                        filp->f_pos++;
                        i++;
                        /* fallthrough */
                default:
+                       mutex_lock(&sysfs_mutex);
+
+                       pos = &parent_sd->s_children;
+                       while (*pos != cursor)
+                               pos = &(*pos)->s_sibling;
+
+                       /* unlink cursor */
+                       *pos = cursor->s_sibling;
+
                        if (filp->f_pos == 2)
-                               list_move(q, &parent_sd->s_children);
+                               pos = &parent_sd->s_children;
 
-                       for (p=q->next; p!= &parent_sd->s_children; p=p->next) {
-                               struct sysfs_dirent *next;
+                       for ( ; *pos; pos = &(*pos)->s_sibling) {
+                               struct sysfs_dirent *next = *pos;
                                const char * name;
                                int len;
 
-                               next = list_entry(p, struct sysfs_dirent,
-                                                  s_sibling);
-                               if (!next->s_element)
+                               if (!sysfs_type(next))
                                        continue;
 
-                               name = sysfs_get_name(next);
+                               name = next->s_name;
                                len = strlen(name);
                                ino = next->s_ino;
 
                                if (filldir(dirent, name, len, filp->f_pos, ino,
                                                 dt_type(next)) < 0)
-                                       return 0;
+                                       break;
 
-                               list_move(q, p);
-                               p = q;
                                filp->f_pos++;
                        }
+
+                       /* put cursor back in */
+                       cursor->s_sibling = *pos;
+                       *pos = cursor;
+
+                       mutex_unlock(&sysfs_mutex);
        }
        return 0;
 }
@@ -583,7 +1147,6 @@ static loff_t sysfs_dir_lseek(struct file * file, loff_t offset, int origin)
 {
        struct dentry * dentry = file->f_path.dentry;
 
-       mutex_lock(&dentry->d_inode->i_mutex);
        switch (origin) {
                case 1:
                        offset += file->f_pos;
@@ -591,31 +1154,35 @@ static loff_t sysfs_dir_lseek(struct file * file, loff_t offset, int origin)
                        if (offset >= 0)
                                break;
                default:
-                       mutex_unlock(&file->f_path.dentry->d_inode->i_mutex);
                        return -EINVAL;
        }
        if (offset != file->f_pos) {
+               mutex_lock(&sysfs_mutex);
+
                file->f_pos = offset;
                if (file->f_pos >= 2) {
                        struct sysfs_dirent *sd = dentry->d_fsdata;
                        struct sysfs_dirent *cursor = file->private_data;
-                       struct list_head *p;
+                       struct sysfs_dirent **pos;
                        loff_t n = file->f_pos - 2;
 
-                       list_del(&cursor->s_sibling);
-                       p = sd->s_children.next;
-                       while (n && p != &sd->s_children) {
-                               struct sysfs_dirent *next;
-                               next = list_entry(p, struct sysfs_dirent,
-                                                  s_sibling);
-                               if (next->s_element)
+                       sysfs_unlink_sibling(cursor);
+
+                       pos = &sd->s_children;
+                       while (n && *pos) {
+                               struct sysfs_dirent *next = *pos;
+                               if (sysfs_type(next))
                                        n--;
-                               p = p->next;
+                               pos = &(*pos)->s_sibling;
                        }
-                       list_add_tail(&cursor->s_sibling, p);
+
+                       cursor->s_sibling = *pos;
+                       *pos = cursor;
                }
+
+               mutex_unlock(&sysfs_mutex);
        }
-       mutex_unlock(&dentry->d_inode->i_mutex);
+
        return offset;
 }
 
@@ -628,12 +1195,20 @@ static loff_t sysfs_dir_lseek(struct file * file, loff_t offset, int origin)
 int sysfs_make_shadowed_dir(struct kobject *kobj,
        void * (*follow_link)(struct dentry *, struct nameidata *))
 {
+       struct dentry *dentry;
        struct inode *inode;
        struct inode_operations *i_op;
 
-       inode = kobj->dentry->d_inode;
-       if (inode->i_op != &sysfs_dir_inode_operations)
+       /* get dentry for @kobj->sd, dentry of a shadowed dir is pinned */
+       dentry = sysfs_get_dentry(kobj->sd);
+       if (IS_ERR(dentry))
+               return PTR_ERR(dentry);
+
+       inode = dentry->d_inode;
+       if (inode->i_op != &sysfs_dir_inode_operations) {
+               dput(dentry);
                return -EINVAL;
+       }
 
        i_op = kmalloc(sizeof(*i_op), GFP_KERNEL);
        if (!i_op)
@@ -658,54 +1233,72 @@ int sysfs_make_shadowed_dir(struct kobject *kobj,
  *     directory.
  */
 
-struct dentry *sysfs_create_shadow_dir(struct kobject *kobj)
+struct sysfs_dirent *sysfs_create_shadow_dir(struct kobject *kobj)
 {
-       struct sysfs_dirent *sd;
-       struct dentry *parent, *dir, *shadow;
+       struct sysfs_dirent *parent_sd = kobj->sd->s_parent;
+       struct dentry *dir, *parent, *shadow;
        struct inode *inode;
+       struct sysfs_dirent *sd;
+       struct sysfs_addrm_cxt acxt;
 
-       dir = kobj->dentry;
-       inode = dir->d_inode;
+       dir = sysfs_get_dentry(kobj->sd);
+       if (IS_ERR(dir)) {
+               sd = (void *)dir;
+               goto out;
+       }
        parent = dir->d_parent;
-       shadow = ERR_PTR(-EINVAL);
+
+       inode = dir->d_inode;
+       sd = ERR_PTR(-EINVAL);
        if (!sysfs_is_shadowed_inode(inode))
-               goto out;
+               goto out_dput;
 
        shadow = d_alloc(parent, &dir->d_name);
        if (!shadow)
                goto nomem;
 
-       sd = __sysfs_make_dirent(shadow, kobj, inode->i_mode, SYSFS_DIR);
+       sd = sysfs_new_dirent("_SHADOW_", inode->i_mode, SYSFS_DIR);
        if (!sd)
                goto nomem;
+       sd->s_elem.dir.kobj = kobj;
 
+       sysfs_addrm_start(&acxt, parent_sd);
+
+       /* add but don't link into children list */
+       sysfs_add_one(&acxt, sd);
+
+       /* attach and instantiate dentry */
+       sysfs_attach_dentry(sd, shadow);
        d_instantiate(shadow, igrab(inode));
-       inc_nlink(inode);
-       inc_nlink(parent->d_inode);
-       shadow->d_op = &sysfs_dentry_ops;
+       inc_nlink(inode);       /* tj: synchronization? */
+
+       sysfs_addrm_finish(&acxt);
 
        dget(shadow);           /* Extra count - pin the dentry in core */
 
-out:
-       return shadow;
-nomem:
+       goto out_dput;
+
+ nomem:
        dput(shadow);
-       shadow = ERR_PTR(-ENOMEM);
-       goto out;
+       sd = ERR_PTR(-ENOMEM);
+ out_dput:
+       dput(dir);
+ out:
+       return sd;
 }
 
 /**
  *     sysfs_remove_shadow_dir - remove an object's directory.
- *     @shadow: dentry of shadow directory
+ *     @shadow_sd: sysfs_dirent of shadow directory
  *
  *     The only thing special about this is that we remove any files in
  *     the directory before we remove the directory, and we've inlined
  *     what used to be sysfs_rmdir() below, instead of calling separately.
  */
 
-void sysfs_remove_shadow_dir(struct dentry *shadow)
+void sysfs_remove_shadow_dir(struct sysfs_dirent *shadow_sd)
 {
-       __sysfs_remove_dir(shadow);
+       __sysfs_remove_dir(shadow_sd);
 }
 
 const struct file_operations sysfs_dir_operations = {
index b502c7197ec063777d90af4c49f038e95acd0c9e..cc497994b2a83dd91931d8d8b2f67bcc30aea80c 100644 (file)
@@ -50,29 +50,15 @@ static struct sysfs_ops subsys_sysfs_ops = {
        .store  = subsys_attr_store,
 };
 
-/**
- *     add_to_collection - add buffer to a collection
- *     @buffer:        buffer to be added
- *     @node:          inode of set to add to
- */
-
-static inline void
-add_to_collection(struct sysfs_buffer *buffer, struct inode *node)
-{
-       struct sysfs_buffer_collection *set = node->i_private;
-
-       mutex_lock(&node->i_mutex);
-       list_add(&buffer->associates, &set->associates);
-       mutex_unlock(&node->i_mutex);
-}
-
-static inline void
-remove_from_collection(struct sysfs_buffer *buffer, struct inode *node)
-{
-       mutex_lock(&node->i_mutex);
-       list_del(&buffer->associates);
-       mutex_unlock(&node->i_mutex);
-}
+struct sysfs_buffer {
+       size_t                  count;
+       loff_t                  pos;
+       char                    * page;
+       struct sysfs_ops        * ops;
+       struct semaphore        sem;
+       int                     needs_read_fill;
+       int                     event;
+};
 
 /**
  *     fill_read_buffer - allocate and fill buffer from object.
@@ -87,9 +73,8 @@ remove_from_collection(struct sysfs_buffer *buffer, struct inode *node)
  */
 static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer)
 {
-       struct sysfs_dirent * sd = dentry->d_fsdata;
-       struct attribute * attr = to_attr(dentry);
-       struct kobject * kobj = to_kobj(dentry->d_parent);
+       struct sysfs_dirent *attr_sd = dentry->d_fsdata;
+       struct kobject *kobj = attr_sd->s_parent->s_elem.dir.kobj;
        struct sysfs_ops * ops = buffer->ops;
        int ret = 0;
        ssize_t count;
@@ -99,8 +84,15 @@ static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer
        if (!buffer->page)
                return -ENOMEM;
 
-       buffer->event = atomic_read(&sd->s_event);
-       count = ops->show(kobj,attr,buffer->page);
+       /* need attr_sd for attr and ops, its parent for kobj */
+       if (!sysfs_get_active_two(attr_sd))
+               return -ENODEV;
+
+       buffer->event = atomic_read(&attr_sd->s_event);
+       count = ops->show(kobj, attr_sd->s_elem.attr.attr, buffer->page);
+
+       sysfs_put_active_two(attr_sd);
+
        BUG_ON(count > (ssize_t)PAGE_SIZE);
        if (count >= 0) {
                buffer->needs_read_fill = 0;
@@ -138,10 +130,7 @@ sysfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos)
 
        down(&buffer->sem);
        if (buffer->needs_read_fill) {
-               if (buffer->orphaned)
-                       retval = -ENODEV;
-               else
-                       retval = fill_read_buffer(file->f_path.dentry,buffer);
+               retval = fill_read_buffer(file->f_path.dentry,buffer);
                if (retval)
                        goto out;
        }
@@ -196,14 +185,23 @@ fill_write_buffer(struct sysfs_buffer * buffer, const char __user * buf, size_t
  *     passing the buffer that we acquired in fill_write_buffer().
  */
 
-static int 
+static int
 flush_write_buffer(struct dentry * dentry, struct sysfs_buffer * buffer, size_t count)
 {
-       struct attribute * attr = to_attr(dentry);
-       struct kobject * kobj = to_kobj(dentry->d_parent);
+       struct sysfs_dirent *attr_sd = dentry->d_fsdata;
+       struct kobject *kobj = attr_sd->s_parent->s_elem.dir.kobj;
        struct sysfs_ops * ops = buffer->ops;
+       int rc;
+
+       /* need attr_sd for attr and ops, its parent for kobj */
+       if (!sysfs_get_active_two(attr_sd))
+               return -ENODEV;
+
+       rc = ops->store(kobj, attr_sd->s_elem.attr.attr, buffer->page, count);
 
-       return ops->store(kobj,attr,buffer->page,count);
+       sysfs_put_active_two(attr_sd);
+
+       return rc;
 }
 
 
@@ -231,37 +229,26 @@ sysfs_write_file(struct file *file, const char __user *buf, size_t count, loff_t
        ssize_t len;
 
        down(&buffer->sem);
-       if (buffer->orphaned) {
-               len = -ENODEV;
-               goto out;
-       }
        len = fill_write_buffer(buffer, buf, count);
        if (len > 0)
                len = flush_write_buffer(file->f_path.dentry, buffer, len);
        if (len > 0)
                *ppos += len;
-out:
        up(&buffer->sem);
        return len;
 }
 
 static int sysfs_open_file(struct inode *inode, struct file *file)
 {
-       struct kobject *kobj = sysfs_get_kobject(file->f_path.dentry->d_parent);
-       struct attribute * attr = to_attr(file->f_path.dentry);
-       struct sysfs_buffer_collection *set;
+       struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
+       struct kobject *kobj = attr_sd->s_parent->s_elem.dir.kobj;
        struct sysfs_buffer * buffer;
        struct sysfs_ops * ops = NULL;
-       int error = 0;
-
-       if (!kobj || !attr)
-               goto Einval;
+       int error;
 
-       /* Grab the module reference for this attribute if we have one */
-       if (!try_module_get(attr->owner)) {
-               error = -ENODEV;
-               goto Done;
-       }
+       /* need attr_sd for attr and ops, its parent for kobj */
+       if (!sysfs_get_active_two(attr_sd))
+               return -ENODEV;
 
        /* if the kobject has no ktype, then we assume that it is a subsystem
         * itself, and use ops for it.
@@ -273,33 +260,21 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
        else
                ops = &subsys_sysfs_ops;
 
+       error = -EACCES;
+
        /* No sysfs operations, either from having no subsystem,
         * or the subsystem have no operations.
         */
        if (!ops)
-               goto Eaccess;
-
-       /* make sure we have a collection to add our buffers to */
-       mutex_lock(&inode->i_mutex);
-       if (!(set = inode->i_private)) {
-               if (!(set = inode->i_private = kmalloc(sizeof(struct sysfs_buffer_collection), GFP_KERNEL))) {
-                       error = -ENOMEM;
-                       goto Done;
-               } else {
-                       INIT_LIST_HEAD(&set->associates);
-               }
-       }
-       mutex_unlock(&inode->i_mutex);
+               goto err_out;
 
        /* File needs write support.
         * The inode's perms must say it's ok, 
         * and we must have a store method.
         */
        if (file->f_mode & FMODE_WRITE) {
-
                if (!(inode->i_mode & S_IWUGO) || !ops->store)
-                       goto Eaccess;
-
+                       goto err_out;
        }
 
        /* File needs read support.
@@ -308,48 +283,38 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
         */
        if (file->f_mode & FMODE_READ) {
                if (!(inode->i_mode & S_IRUGO) || !ops->show)
-                       goto Eaccess;
+                       goto err_out;
        }
 
        /* No error? Great, allocate a buffer for the file, and store it
         * it in file->private_data for easy access.
         */
+       error = -ENOMEM;
        buffer = kzalloc(sizeof(struct sysfs_buffer), GFP_KERNEL);
-       if (buffer) {
-               INIT_LIST_HEAD(&buffer->associates);
-               init_MUTEX(&buffer->sem);
-               buffer->needs_read_fill = 1;
-               buffer->ops = ops;
-               add_to_collection(buffer, inode);
-               file->private_data = buffer;
-       } else
-               error = -ENOMEM;
-       goto Done;
-
- Einval:
-       error = -EINVAL;
-       goto Done;
- Eaccess:
-       error = -EACCES;
-       module_put(attr->owner);
- Done:
-       if (error)
-               kobject_put(kobj);
+       if (!buffer)
+               goto err_out;
+
+       init_MUTEX(&buffer->sem);
+       buffer->needs_read_fill = 1;
+       buffer->ops = ops;
+       file->private_data = buffer;
+
+       /* open succeeded, put active references and pin attr_sd */
+       sysfs_put_active_two(attr_sd);
+       sysfs_get(attr_sd);
+       return 0;
+
+ err_out:
+       sysfs_put_active_two(attr_sd);
        return error;
 }
 
 static int sysfs_release(struct inode * inode, struct file * filp)
 {
-       struct kobject * kobj = to_kobj(filp->f_path.dentry->d_parent);
-       struct attribute * attr = to_attr(filp->f_path.dentry);
-       struct module * owner = attr->owner;
-       struct sysfs_buffer * buffer = filp->private_data;
+       struct sysfs_dirent *attr_sd = filp->f_path.dentry->d_fsdata;
+       struct sysfs_buffer *buffer = filp->private_data;
 
-       if (buffer)
-               remove_from_collection(buffer, inode);
-       kobject_put(kobj);
-       /* After this point, attr should not be accessed. */
-       module_put(owner);
+       sysfs_put(attr_sd);
 
        if (buffer) {
                if (buffer->page)
@@ -376,57 +341,43 @@ static int sysfs_release(struct inode * inode, struct file * filp)
 static unsigned int sysfs_poll(struct file *filp, poll_table *wait)
 {
        struct sysfs_buffer * buffer = filp->private_data;
-       struct kobject * kobj = to_kobj(filp->f_path.dentry->d_parent);
-       struct sysfs_dirent * sd = filp->f_path.dentry->d_fsdata;
-       int res = 0;
+       struct sysfs_dirent *attr_sd = filp->f_path.dentry->d_fsdata;
+       struct kobject *kobj = attr_sd->s_parent->s_elem.dir.kobj;
+
+       /* need parent for the kobj, grab both */
+       if (!sysfs_get_active_two(attr_sd))
+               goto trigger;
 
        poll_wait(filp, &kobj->poll, wait);
 
-       if (buffer->event != atomic_read(&sd->s_event)) {
-               res = POLLERR|POLLPRI;
-               buffer->needs_read_fill = 1;
-       }
+       sysfs_put_active_two(attr_sd);
 
-       return res;
-}
+       if (buffer->event != atomic_read(&attr_sd->s_event))
+               goto trigger;
 
+       return 0;
 
-static struct dentry *step_down(struct dentry *dir, const char * name)
-{
-       struct dentry * de;
-
-       if (dir == NULL || dir->d_inode == NULL)
-               return NULL;
-
-       mutex_lock(&dir->d_inode->i_mutex);
-       de = lookup_one_len(name, dir, strlen(name));
-       mutex_unlock(&dir->d_inode->i_mutex);
-       dput(dir);
-       if (IS_ERR(de))
-               return NULL;
-       if (de->d_inode == NULL) {
-               dput(de);
-               return NULL;
-       }
-       return de;
+ trigger:
+       buffer->needs_read_fill = 1;
+       return POLLERR|POLLPRI;
 }
 
-void sysfs_notify(struct kobject * k, char *dir, char *attr)
+void sysfs_notify(struct kobject *k, char *dir, char *attr)
 {
-       struct dentry *de = k->dentry;
-       if (de)
-               dget(de);
-       if (de && dir)
-               de = step_down(de, dir);
-       if (de && attr)
-               de = step_down(de, attr);
-       if (de) {
-               struct sysfs_dirent * sd = de->d_fsdata;
-               if (sd)
-                       atomic_inc(&sd->s_event);
+       struct sysfs_dirent *sd = k->sd;
+
+       mutex_lock(&sysfs_mutex);
+
+       if (sd && dir)
+               sd = sysfs_find_dirent(sd, dir);
+       if (sd && attr)
+               sd = sysfs_find_dirent(sd, attr);
+       if (sd) {
+               atomic_inc(&sd->s_event);
                wake_up_interruptible(&k->poll);
-               dput(de);
        }
+
+       mutex_unlock(&sysfs_mutex);
 }
 EXPORT_SYMBOL_GPL(sysfs_notify);
 
@@ -440,19 +391,30 @@ const struct file_operations sysfs_file_operations = {
 };
 
 
-int sysfs_add_file(struct dentry * dir, const struct attribute * attr, int type)
+int sysfs_add_file(struct sysfs_dirent *dir_sd, const struct attribute *attr,
+                  int type)
 {
-       struct sysfs_dirent * parent_sd = dir->d_fsdata;
        umode_t mode = (attr->mode & S_IALLUGO) | S_IFREG;
-       int error = -EEXIST;
+       struct sysfs_addrm_cxt acxt;
+       struct sysfs_dirent *sd;
 
-       mutex_lock(&dir->d_inode->i_mutex);
-       if (!sysfs_dirent_exist(parent_sd, attr->name))
-               error = sysfs_make_dirent(parent_sd, NULL, (void *)attr,
-                                         mode, type);
-       mutex_unlock(&dir->d_inode->i_mutex);
+       sd = sysfs_new_dirent(attr->name, mode, type);
+       if (!sd)
+               return -ENOMEM;
+       sd->s_elem.attr.attr = (void *)attr;
 
-       return error;
+       sysfs_addrm_start(&acxt, dir_sd);
+
+       if (!sysfs_find_dirent(dir_sd, attr->name)) {
+               sysfs_add_one(&acxt, sd);
+               sysfs_link_sibling(sd);
+       }
+
+       if (sysfs_addrm_finish(&acxt))
+               return 0;
+
+       sysfs_put(sd);
+       return -EEXIST;
 }
 
 
@@ -464,9 +426,9 @@ int sysfs_add_file(struct dentry * dir, const struct attribute * attr, int type)
 
 int sysfs_create_file(struct kobject * kobj, const struct attribute * attr)
 {
-       BUG_ON(!kobj || !kobj->dentry || !attr);
+       BUG_ON(!kobj || !kobj->sd || !attr);
 
-       return sysfs_add_file(kobj->dentry, attr, SYSFS_KOBJ_ATTR);
+       return sysfs_add_file(kobj->sd, attr, SYSFS_KOBJ_ATTR);
 
 }
 
@@ -480,16 +442,16 @@ int sysfs_create_file(struct kobject * kobj, const struct attribute * attr)
 int sysfs_add_file_to_group(struct kobject *kobj,
                const struct attribute *attr, const char *group)
 {
-       struct dentry *dir;
+       struct sysfs_dirent *dir_sd;
        int error;
 
-       dir = lookup_one_len(group, kobj->dentry, strlen(group));
-       if (IS_ERR(dir))
-               error = PTR_ERR(dir);
-       else {
-               error = sysfs_add_file(dir, attr, SYSFS_KOBJ_ATTR);
-               dput(dir);
-       }
+       dir_sd = sysfs_get_dirent(kobj->sd, group);
+       if (!dir_sd)
+               return -ENOENT;
+
+       error = sysfs_add_file(dir_sd, attr, SYSFS_KOBJ_ATTR);
+       sysfs_put(dir_sd);
+
        return error;
 }
 EXPORT_SYMBOL_GPL(sysfs_add_file_to_group);
@@ -502,30 +464,31 @@ EXPORT_SYMBOL_GPL(sysfs_add_file_to_group);
  */
 int sysfs_update_file(struct kobject * kobj, const struct attribute * attr)
 {
-       struct dentry * dir = kobj->dentry;
-       struct dentry * victim;
-       int res = -ENOENT;
-
-       mutex_lock(&dir->d_inode->i_mutex);
-       victim = lookup_one_len(attr->name, dir, strlen(attr->name));
-       if (!IS_ERR(victim)) {
-               /* make sure dentry is really there */
-               if (victim->d_inode && 
-                   (victim->d_parent->d_inode == dir->d_inode)) {
-                       victim->d_inode->i_mtime = CURRENT_TIME;
-                       fsnotify_modify(victim);
-                       res = 0;
-               } else
-                       d_drop(victim);
-               
-               /**
-                * Drop the reference acquired from lookup_one_len() above.
-                */
-               dput(victim);
+       struct sysfs_dirent *victim_sd = NULL;
+       struct dentry *victim = NULL;
+       int rc;
+
+       rc = -ENOENT;
+       victim_sd = sysfs_get_dirent(kobj->sd, attr->name);
+       if (!victim_sd)
+               goto out;
+
+       victim = sysfs_get_dentry(victim_sd);
+       if (IS_ERR(victim)) {
+               rc = PTR_ERR(victim);
+               victim = NULL;
+               goto out;
        }
-       mutex_unlock(&dir->d_inode->i_mutex);
 
-       return res;
+       mutex_lock(&victim->d_inode->i_mutex);
+       victim->d_inode->i_mtime = CURRENT_TIME;
+       fsnotify_modify(victim);
+       mutex_unlock(&victim->d_inode->i_mutex);
+       rc = 0;
+ out:
+       dput(victim);
+       sysfs_put(victim_sd);
+       return rc;
 }
 
 
@@ -538,30 +501,34 @@ int sysfs_update_file(struct kobject * kobj, const struct attribute * attr)
  */
 int sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode)
 {
-       struct dentry *dir = kobj->dentry;
-       struct dentry *victim;
+       struct sysfs_dirent *victim_sd = NULL;
+       struct dentry *victim = NULL;
        struct inode * inode;
        struct iattr newattrs;
-       int res = -ENOENT;
-
-       mutex_lock(&dir->d_inode->i_mutex);
-       victim = lookup_one_len(attr->name, dir, strlen(attr->name));
-       if (!IS_ERR(victim)) {
-               if (victim->d_inode &&
-                   (victim->d_parent->d_inode == dir->d_inode)) {
-                       inode = victim->d_inode;
-                       mutex_lock(&inode->i_mutex);
-                       newattrs.ia_mode = (mode & S_IALLUGO) |
-                                               (inode->i_mode & ~S_IALLUGO);
-                       newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
-                       res = notify_change(victim, &newattrs);
-                       mutex_unlock(&inode->i_mutex);
-               }
-               dput(victim);
+       int rc;
+
+       rc = -ENOENT;
+       victim_sd = sysfs_get_dirent(kobj->sd, attr->name);
+       if (!victim_sd)
+               goto out;
+
+       victim = sysfs_get_dentry(victim_sd);
+       if (IS_ERR(victim)) {
+               rc = PTR_ERR(victim);
+               victim = NULL;
+               goto out;
        }
-       mutex_unlock(&dir->d_inode->i_mutex);
 
-       return res;
+       inode = victim->d_inode;
+       mutex_lock(&inode->i_mutex);
+       newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
+       newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
+       rc = notify_change(victim, &newattrs);
+       mutex_unlock(&inode->i_mutex);
+ out:
+       dput(victim);
+       sysfs_put(victim_sd);
+       return rc;
 }
 EXPORT_SYMBOL_GPL(sysfs_chmod_file);
 
@@ -576,7 +543,7 @@ EXPORT_SYMBOL_GPL(sysfs_chmod_file);
 
 void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr)
 {
-       sysfs_hash_and_remove(kobj->dentry, attr->name);
+       sysfs_hash_and_remove(kobj->sd, attr->name);
 }
 
 
@@ -589,12 +556,12 @@ void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr)
 void sysfs_remove_file_from_group(struct kobject *kobj,
                const struct attribute *attr, const char *group)
 {
-       struct dentry *dir;
+       struct sysfs_dirent *dir_sd;
 
-       dir = lookup_one_len(group, kobj->dentry, strlen(group));
-       if (!IS_ERR(dir)) {
-               sysfs_hash_and_remove(dir, attr->name);
-               dput(dir);
+       dir_sd = sysfs_get_dirent(kobj->sd, group);
+       if (dir_sd) {
+               sysfs_hash_and_remove(dir_sd, attr->name);
+               sysfs_put(dir_sd);
        }
 }
 EXPORT_SYMBOL_GPL(sysfs_remove_file_from_group);
index 52eed2a7a5efbf91061362b11ca54794d22e0c25..f318b73c790c8d2b058bd68ac6646b2adb550802 100644 (file)
 #include "sysfs.h"
 
 
-static void remove_files(struct dentry * dir, 
-                        const struct attribute_group * grp)
+static void remove_files(struct sysfs_dirent *dir_sd,
+                        const struct attribute_group *grp)
 {
        struct attribute *const* attr;
 
        for (attr = grp->attrs; *attr; attr++)
-               sysfs_hash_and_remove(dir,(*attr)->name);
+               sysfs_hash_and_remove(dir_sd, (*attr)->name);
 }
 
-static int create_files(struct dentry * dir,
-                       const struct attribute_group * grp)
+static int create_files(struct sysfs_dirent *dir_sd,
+                       const struct attribute_group *grp)
 {
        struct attribute *const* attr;
        int error = 0;
 
-       for (attr = grp->attrs; *attr && !error; attr++) {
-               error = sysfs_add_file(dir, *attr, SYSFS_KOBJ_ATTR);
-       }
+       for (attr = grp->attrs; *attr && !error; attr++)
+               error = sysfs_add_file(dir_sd, *attr, SYSFS_KOBJ_ATTR);
        if (error)
-               remove_files(dir,grp);
+               remove_files(dir_sd, grp);
        return error;
 }
 
@@ -45,44 +44,44 @@ static int create_files(struct dentry * dir,
 int sysfs_create_group(struct kobject * kobj, 
                       const struct attribute_group * grp)
 {
-       struct dentry * dir;
+       struct sysfs_dirent *sd;
        int error;
 
-       BUG_ON(!kobj || !kobj->dentry);
+       BUG_ON(!kobj || !kobj->sd);
 
        if (grp->name) {
-               error = sysfs_create_subdir(kobj,grp->name,&dir);
+               error = sysfs_create_subdir(kobj, grp->name, &sd);
                if (error)
                        return error;
        } else
-               dir = kobj->dentry;
-       dir = dget(dir);
-       if ((error = create_files(dir,grp))) {
+               sd = kobj->sd;
+       sysfs_get(sd);
+       error = create_files(sd, grp);
+       if (error) {
                if (grp->name)
-                       sysfs_remove_subdir(dir);
+                       sysfs_remove_subdir(sd);
        }
-       dput(dir);
+       sysfs_put(sd);
        return error;
 }
 
 void sysfs_remove_group(struct kobject * kobj, 
                        const struct attribute_group * grp)
 {
-       struct dentry * dir;
+       struct sysfs_dirent *dir_sd = kobj->sd;
+       struct sysfs_dirent *sd;
 
        if (grp->name) {
-               dir = lookup_one_len_kern(grp->name, kobj->dentry,
-                               strlen(grp->name));
-               BUG_ON(IS_ERR(dir));
-       }
-       else
-               dir = dget(kobj->dentry);
+               sd = sysfs_get_dirent(dir_sd, grp->name);
+               BUG_ON(!sd);
+       } else
+               sd = sysfs_get(dir_sd);
 
-       remove_files(dir,grp);
+       remove_files(sd, grp);
        if (grp->name)
-               sysfs_remove_subdir(dir);
-       /* release the ref. taken in this routine */
-       dput(dir);
+               sysfs_remove_subdir(sd);
+
+       sysfs_put(sd);
 }
 
 
index 5266eec15f6e35766c84939f1c7663690d6c3930..3756e152285ab0ea219c90a698f4391040f17940 100644 (file)
@@ -133,187 +133,94 @@ static inline void set_inode_attr(struct inode * inode, struct iattr * iattr)
  */
 static struct lock_class_key sysfs_inode_imutex_key;
 
-struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent * sd)
+void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode)
 {
-       struct inode * inode = new_inode(sysfs_sb);
-       if (inode) {
-               inode->i_blocks = 0;
-               inode->i_mapping->a_ops = &sysfs_aops;
-               inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info;
-               inode->i_op = &sysfs_inode_operations;
-               inode->i_ino = sd->s_ino;
-               lockdep_set_class(&inode->i_mutex, &sysfs_inode_imutex_key);
-
-               if (sd->s_iattr) {
-                       /* sysfs_dirent has non-default attributes
-                        * get them for the new inode from persistent copy
-                        * in sysfs_dirent
-                        */
-                       set_inode_attr(inode, sd->s_iattr);
-               } else
-                       set_default_inode_attr(inode, mode);
-       }
-       return inode;
-}
-
-int sysfs_create(struct dentry * dentry, int mode, int (*init)(struct inode *))
-{
-       int error = 0;
-       struct inode * inode = NULL;
-       if (dentry) {
-               if (!dentry->d_inode) {
-                       struct sysfs_dirent * sd = dentry->d_fsdata;
-                       if ((inode = sysfs_new_inode(mode, sd))) {
-                               if (dentry->d_parent && dentry->d_parent->d_inode) {
-                                       struct inode *p_inode = dentry->d_parent->d_inode;
-                                       p_inode->i_mtime = p_inode->i_ctime = CURRENT_TIME;
-                               }
-                               goto Proceed;
-                       }
-                       else 
-                               error = -ENOMEM;
-               } else
-                       error = -EEXIST;
-       } else 
-               error = -ENOENT;
-       goto Done;
-
- Proceed:
-       if (init)
-               error = init(inode);
-       if (!error) {
-               d_instantiate(dentry, inode);
-               if (S_ISDIR(mode))
-                       dget(dentry);  /* pin only directory dentry in core */
+       inode->i_blocks = 0;
+       inode->i_mapping->a_ops = &sysfs_aops;
+       inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info;
+       inode->i_op = &sysfs_inode_operations;
+       inode->i_ino = sd->s_ino;
+       lockdep_set_class(&inode->i_mutex, &sysfs_inode_imutex_key);
+
+       if (sd->s_iattr) {
+               /* sysfs_dirent has non-default attributes
+                * get them for the new inode from persistent copy
+                * in sysfs_dirent
+                */
+               set_inode_attr(inode, sd->s_iattr);
        } else
-               iput(inode);
- Done:
-       return error;
+               set_default_inode_attr(inode, sd->s_mode);
 }
 
-/*
- * Get the name for corresponding element represented by the given sysfs_dirent
+/**
+ *     sysfs_get_inode - get inode for sysfs_dirent
+ *     @sd: sysfs_dirent to allocate inode for
+ *
+ *     Get inode for @sd.  If such inode doesn't exist, a new inode
+ *     is allocated and basics are initialized.  New inode is
+ *     returned locked.
+ *
+ *     LOCKING:
+ *     Kernel thread context (may sleep).
+ *
+ *     RETURNS:
+ *     Pointer to allocated inode on success, NULL on failure.
  */
-const unsigned char * sysfs_get_name(struct sysfs_dirent *sd)
+struct inode * sysfs_get_inode(struct sysfs_dirent *sd)
 {
-       struct attribute * attr;
-       struct bin_attribute * bin_attr;
-       struct sysfs_symlink  * sl;
-
-       BUG_ON(!sd || !sd->s_element);
-
-       switch (sd->s_type) {
-               case SYSFS_DIR:
-                       /* Always have a dentry so use that */
-                       return sd->s_dentry->d_name.name;
-
-               case SYSFS_KOBJ_ATTR:
-                       attr = sd->s_element;
-                       return attr->name;
-
-               case SYSFS_KOBJ_BIN_ATTR:
-                       bin_attr = sd->s_element;
-                       return bin_attr->attr.name;
+       struct inode *inode;
 
-               case SYSFS_KOBJ_LINK:
-                       sl = sd->s_element;
-                       return sl->link_name;
-       }
-       return NULL;
-}
+       inode = iget_locked(sysfs_sb, sd->s_ino);
+       if (inode && (inode->i_state & I_NEW))
+               sysfs_init_inode(sd, inode);
 
-static inline void orphan_all_buffers(struct inode *node)
-{
-       struct sysfs_buffer_collection *set;
-       struct sysfs_buffer *buf;
-
-       mutex_lock_nested(&node->i_mutex, I_MUTEX_CHILD);
-       set = node->i_private;
-       if (set) {
-               list_for_each_entry(buf, &set->associates, associates) {
-                       down(&buf->sem);
-                       buf->orphaned = 1;
-                       up(&buf->sem);
-               }
-       }
-       mutex_unlock(&node->i_mutex);
+       return inode;
 }
 
-
-/*
- * Unhashes the dentry corresponding to given sysfs_dirent
- * Called with parent inode's i_mutex held.
+/**
+ *     sysfs_instantiate - instantiate dentry
+ *     @dentry: dentry to be instantiated
+ *     @inode: inode associated with @sd
+ *
+ *     Unlock @inode if locked and instantiate @dentry with @inode.
+ *
+ *     LOCKING:
+ *     None.
  */
-void sysfs_drop_dentry(struct sysfs_dirent * sd, struct dentry * parent)
+void sysfs_instantiate(struct dentry *dentry, struct inode *inode)
 {
-       struct dentry *dentry = NULL;
-       struct inode *inode;
+       BUG_ON(!dentry || dentry->d_inode);
 
-       /* We're not holding a reference to ->s_dentry dentry but the
-        * field will stay valid as long as sysfs_lock is held.
-        */
-       spin_lock(&sysfs_lock);
-       spin_lock(&dcache_lock);
-
-       /* dget dentry if it's still alive */
-       if (sd->s_dentry && sd->s_dentry->d_inode)
-               dentry = dget_locked(sd->s_dentry);
-
-       spin_unlock(&dcache_lock);
-       spin_unlock(&sysfs_lock);
-
-       /* drop dentry */
-       if (dentry) {
-               spin_lock(&dcache_lock);
-               spin_lock(&dentry->d_lock);
-               if (!d_unhashed(dentry) && dentry->d_inode) {
-                       inode = dentry->d_inode;
-                       spin_lock(&inode->i_lock);
-                       __iget(inode);
-                       spin_unlock(&inode->i_lock);
-                       dget_locked(dentry);
-                       __d_drop(dentry);
-                       spin_unlock(&dentry->d_lock);
-                       spin_unlock(&dcache_lock);
-                       simple_unlink(parent->d_inode, dentry);
-                       orphan_all_buffers(inode);
-                       iput(inode);
-               } else {
-                       spin_unlock(&dentry->d_lock);
-                       spin_unlock(&dcache_lock);
-               }
+       if (inode->i_state & I_NEW)
+               unlock_new_inode(inode);
 
-               dput(dentry);
-       }
+       d_instantiate(dentry, inode);
 }
 
-int sysfs_hash_and_remove(struct dentry * dir, const char * name)
+int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name)
 {
-       struct sysfs_dirent * sd;
-       struct sysfs_dirent * parent_sd;
-       int found = 0;
+       struct sysfs_addrm_cxt acxt;
+       struct sysfs_dirent **pos, *sd;
 
-       if (!dir)
+       if (!dir_sd)
                return -ENOENT;
 
-       if (dir->d_inode == NULL)
-               /* no inode means this hasn't been made visible yet */
-               return -ENOENT;
+       sysfs_addrm_start(&acxt, dir_sd);
+
+       for (pos = &dir_sd->s_children; *pos; pos = &(*pos)->s_sibling) {
+               sd = *pos;
 
-       parent_sd = dir->d_fsdata;
-       mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
-       list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
-               if (!sd->s_element)
+               if (!sysfs_type(sd))
                        continue;
-               if (!strcmp(sysfs_get_name(sd), name)) {
-                       list_del_init(&sd->s_sibling);
-                       sysfs_drop_dentry(sd, dir);
-                       sysfs_put(sd);
-                       found = 1;
+               if (!strcmp(sd->s_name, name)) {
+                       *pos = sd->s_sibling;
+                       sd->s_sibling = NULL;
+                       sysfs_remove_one(&acxt, sd);
                        break;
                }
        }
-       mutex_unlock(&dir->d_inode->i_mutex);
 
-       return found ? 0 : -ENOENT;
+       if (sysfs_addrm_finish(&acxt))
+               return 0;
+       return -ENOENT;
 }
index 00ab9125d398984efa12496fa3b48ff405f62bad..402cc356203c9ac89f3325f320be5f5c5026312f 100644 (file)
@@ -19,28 +19,18 @@ struct vfsmount *sysfs_mount;
 struct super_block * sysfs_sb = NULL;
 struct kmem_cache *sysfs_dir_cachep;
 
-static void sysfs_clear_inode(struct inode *inode);
-
 static const struct super_operations sysfs_ops = {
        .statfs         = simple_statfs,
        .drop_inode     = sysfs_delete_inode,
-       .clear_inode    = sysfs_clear_inode,
 };
 
-static struct sysfs_dirent sysfs_root = {
-       .s_sibling      = LIST_HEAD_INIT(sysfs_root.s_sibling),
-       .s_children     = LIST_HEAD_INIT(sysfs_root.s_children),
-       .s_element      = NULL,
-       .s_type         = SYSFS_ROOT,
-       .s_iattr        = NULL,
+struct sysfs_dirent sysfs_root = {
+       .s_count        = ATOMIC_INIT(1),
+       .s_flags        = SYSFS_ROOT,
+       .s_mode         = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
        .s_ino          = 1,
 };
 
-static void sysfs_clear_inode(struct inode *inode)
-{
-       kfree(inode->i_private);
-}
-
 static int sysfs_fill_super(struct super_block *sb, void *data, int silent)
 {
        struct inode *inode;
@@ -53,24 +43,26 @@ static int sysfs_fill_super(struct super_block *sb, void *data, int silent)
        sb->s_time_gran = 1;
        sysfs_sb = sb;
 
-       inode = sysfs_new_inode(S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
-                                &sysfs_root);
-       if (inode) {
-               inode->i_op = &sysfs_dir_inode_operations;
-               inode->i_fop = &sysfs_dir_operations;
-               /* directory inodes start off with i_nlink == 2 (for "." entry) */
-               inc_nlink(inode);
-       } else {
+       inode = new_inode(sysfs_sb);
+       if (!inode) {
                pr_debug("sysfs: could not get root inode\n");
                return -ENOMEM;
        }
 
+       sysfs_init_inode(&sysfs_root, inode);
+
+       inode->i_op = &sysfs_dir_inode_operations;
+       inode->i_fop = &sysfs_dir_operations;
+       /* directory inodes start off with i_nlink == 2 (for "." entry) */
+       inc_nlink(inode);
+
        root = d_alloc_root(inode);
        if (!root) {
                pr_debug("%s: could not get root dentry!\n",__FUNCTION__);
                iput(inode);
                return -ENOMEM;
        }
+       sysfs_root.s_dentry = root;
        root->d_fsdata = &sysfs_root;
        sb->s_root = root;
        return 0;
index 7b9c5bfde920fb1ea30af8f81d4313f84bf981ec..2f86e04222907b2c19aab03adf6d2f2cabe092d1 100644 (file)
 
 #include "sysfs.h"
 
-static int object_depth(struct kobject * kobj)
+static int object_depth(struct sysfs_dirent *sd)
 {
-       struct kobject * p = kobj;
        int depth = 0;
-       do { depth++; } while ((p = p->parent));
+
+       for (; sd->s_parent; sd = sd->s_parent)
+               depth++;
+
        return depth;
 }
 
-static int object_path_length(struct kobject * kobj)
+static int object_path_length(struct sysfs_dirent * sd)
 {
-       struct kobject * p = kobj;
        int length = 1;
-       do {
-               length += strlen(kobject_name(p)) + 1;
-               p = p->parent;
-       } while (p);
+
+       for (; sd->s_parent; sd = sd->s_parent)
+               length += strlen(sd->s_name) + 1;
+
        return length;
 }
 
-static void fill_object_path(struct kobject * kobj, char * buffer, int length)
+static void fill_object_path(struct sysfs_dirent *sd, char *buffer, int length)
 {
-       struct kobject * p;
-
        --length;
-       for (p = kobj; p; p = p->parent) {
-               int cur = strlen(kobject_name(p));
+       for (; sd->s_parent; sd = sd->s_parent) {
+               int cur = strlen(sd->s_name);
 
                /* back up enough to print this bus id with '/' */
                length -= cur;
-               strncpy(buffer + length,kobject_name(p),cur);
+               strncpy(buffer + length, sd->s_name, cur);
                *(buffer + --length) = '/';
        }
 }
 
-static int sysfs_add_link(struct dentry * parent, const char * name, struct kobject * target)
-{
-       struct sysfs_dirent * parent_sd = parent->d_fsdata;
-       struct sysfs_symlink * sl;
-       int error = 0;
-
-       error = -ENOMEM;
-       sl = kmalloc(sizeof(*sl), GFP_KERNEL);
-       if (!sl)
-               goto exit1;
-
-       sl->link_name = kmalloc(strlen(name) + 1, GFP_KERNEL);
-       if (!sl->link_name)
-               goto exit2;
-
-       strcpy(sl->link_name, name);
-       sl->target_kobj = kobject_get(target);
-
-       error = sysfs_make_dirent(parent_sd, NULL, sl, S_IFLNK|S_IRWXUGO,
-                               SYSFS_KOBJ_LINK);
-       if (!error)
-               return 0;
-
-       kobject_put(target);
-       kfree(sl->link_name);
-exit2:
-       kfree(sl);
-exit1:
-       return error;
-}
-
 /**
  *     sysfs_create_link - create symlink between two objects.
  *     @kobj:  object whose directory we're creating the link in.
@@ -84,24 +52,57 @@ exit1:
  */
 int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char * name)
 {
-       struct dentry *dentry = NULL;
-       int error = -EEXIST;
+       struct sysfs_dirent *parent_sd = NULL;
+       struct sysfs_dirent *target_sd = NULL;
+       struct sysfs_dirent *sd = NULL;
+       struct sysfs_addrm_cxt acxt;
+       int error;
 
        BUG_ON(!name);
 
        if (!kobj) {
                if (sysfs_mount && sysfs_mount->mnt_sb)
-                       dentry = sysfs_mount->mnt_sb->s_root;
+                       parent_sd = sysfs_mount->mnt_sb->s_root->d_fsdata;
        } else
-               dentry = kobj->dentry;
+               parent_sd = kobj->sd;
+
+       error = -EFAULT;
+       if (!parent_sd)
+               goto out_put;
+
+       /* target->sd can go away beneath us but is protected with
+        * sysfs_assoc_lock.  Fetch target_sd from it.
+        */
+       spin_lock(&sysfs_assoc_lock);
+       if (target->sd)
+               target_sd = sysfs_get(target->sd);
+       spin_unlock(&sysfs_assoc_lock);
+
+       error = -ENOENT;
+       if (!target_sd)
+               goto out_put;
+
+       error = -ENOMEM;
+       sd = sysfs_new_dirent(name, S_IFLNK|S_IRWXUGO, SYSFS_KOBJ_LINK);
+       if (!sd)
+               goto out_put;
+       sd->s_elem.symlink.target_sd = target_sd;
 
-       if (!dentry)
-               return -EFAULT;
+       sysfs_addrm_start(&acxt, parent_sd);
 
-       mutex_lock(&dentry->d_inode->i_mutex);
-       if (!sysfs_dirent_exist(dentry->d_fsdata, name))
-               error = sysfs_add_link(dentry, name, target);
-       mutex_unlock(&dentry->d_inode->i_mutex);
+       if (!sysfs_find_dirent(parent_sd, name)) {
+               sysfs_add_one(&acxt, sd);
+               sysfs_link_sibling(sd);
+       }
+
+       if (sysfs_addrm_finish(&acxt))
+               return 0;
+
+       error = -EEXIST;
+       /* fall through */
+ out_put:
+       sysfs_put(target_sd);
+       sysfs_put(sd);
        return error;
 }
 
@@ -114,17 +115,17 @@ int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char
 
 void sysfs_remove_link(struct kobject * kobj, const char * name)
 {
-       sysfs_hash_and_remove(kobj->dentry,name);
+       sysfs_hash_and_remove(kobj->sd, name);
 }
 
-static int sysfs_get_target_path(struct kobject * kobj, struct kobject * target,
-                                char *path)
+static int sysfs_get_target_path(struct sysfs_dirent * parent_sd,
+                                struct sysfs_dirent * target_sd, char *path)
 {
        char * s;
        int depth, size;
 
-       depth = object_depth(kobj);
-       size = object_path_length(target) + depth * 3 - 1;
+       depth = object_depth(parent_sd);
+       size = object_path_length(target_sd) + depth * 3 - 1;
        if (size > PATH_MAX)
                return -ENAMETOOLONG;
 
@@ -133,7 +134,7 @@ static int sysfs_get_target_path(struct kobject * kobj, struct kobject * target,
        for (s = path; depth--; s += 3)
                strcpy(s,"../");
 
-       fill_object_path(target, path, size);
+       fill_object_path(target_sd, path, size);
        pr_debug("%s: path = '%s'\n", __FUNCTION__, path);
 
        return 0;
@@ -141,27 +142,16 @@ static int sysfs_get_target_path(struct kobject * kobj, struct kobject * target,
 
 static int sysfs_getlink(struct dentry *dentry, char * path)
 {
-       struct kobject *kobj, *target_kobj;
-       int error = 0;
+       struct sysfs_dirent *sd = dentry->d_fsdata;
+       struct sysfs_dirent *parent_sd = sd->s_parent;
+       struct sysfs_dirent *target_sd = sd->s_elem.symlink.target_sd;
+       int error;
 
-       kobj = sysfs_get_kobject(dentry->d_parent);
-       if (!kobj)
-               return -EINVAL;
+       mutex_lock(&sysfs_mutex);
+       error = sysfs_get_target_path(parent_sd, target_sd, path);
+       mutex_unlock(&sysfs_mutex);
 
-       target_kobj = sysfs_get_kobject(dentry);
-       if (!target_kobj) {
-               kobject_put(kobj);
-               return -EINVAL;
-       }
-
-       down_read(&sysfs_rename_sem);
-       error = sysfs_get_target_path(kobj, target_kobj, path);
-       up_read(&sysfs_rename_sem);
-       
-       kobject_put(kobj);
-       kobject_put(target_kobj);
        return error;
-
 }
 
 static void *sysfs_follow_link(struct dentry *dentry, struct nameidata *nd)
index 502c949c402d9dd3de49ac922d9f1e1db2543e2a..6a37f2386a8d6621eb5dcff2de9e5e986b99e167 100644 (file)
@@ -1,9 +1,40 @@
+struct sysfs_elem_dir {
+       struct kobject          * kobj;
+};
+
+struct sysfs_elem_symlink {
+       struct sysfs_dirent     * target_sd;
+};
+
+struct sysfs_elem_attr {
+       struct attribute        * attr;
+};
+
+struct sysfs_elem_bin_attr {
+       struct bin_attribute    * bin_attr;
+};
+
+/*
+ * As long as s_count reference is held, the sysfs_dirent itself is
+ * accessible.  Dereferencing s_elem or any other outer entity
+ * requires s_active reference.
+ */
 struct sysfs_dirent {
        atomic_t                s_count;
-       struct list_head        s_sibling;
-       struct list_head        s_children;
-       void                    * s_element;
-       int                     s_type;
+       atomic_t                s_active;
+       struct sysfs_dirent     * s_parent;
+       struct sysfs_dirent     * s_sibling;
+       struct sysfs_dirent     * s_children;
+       const char              * s_name;
+
+       union {
+               struct sysfs_elem_dir           dir;
+               struct sysfs_elem_symlink       symlink;
+               struct sysfs_elem_attr          attr;
+               struct sysfs_elem_bin_attr      bin_attr;
+       }                       s_elem;
+
+       unsigned int            s_flags;
        umode_t                 s_mode;
        ino_t                   s_ino;
        struct dentry           * s_dentry;
@@ -11,30 +42,60 @@ struct sysfs_dirent {
        atomic_t                s_event;
 };
 
+#define SD_DEACTIVATED_BIAS    INT_MIN
+
+struct sysfs_addrm_cxt {
+       struct sysfs_dirent     *parent_sd;
+       struct inode            *parent_inode;
+       struct sysfs_dirent     *removed;
+       int                     cnt;
+};
+
 extern struct vfsmount * sysfs_mount;
+extern struct sysfs_dirent sysfs_root;
 extern struct kmem_cache *sysfs_dir_cachep;
 
-extern void sysfs_delete_inode(struct inode *inode);
-extern struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent *);
-extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *));
+extern struct dentry *sysfs_get_dentry(struct sysfs_dirent *sd);
+extern void sysfs_link_sibling(struct sysfs_dirent *sd);
+extern void sysfs_unlink_sibling(struct sysfs_dirent *sd);
+extern struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd);
+extern void sysfs_put_active(struct sysfs_dirent *sd);
+extern struct sysfs_dirent *sysfs_get_active_two(struct sysfs_dirent *sd);
+extern void sysfs_put_active_two(struct sysfs_dirent *sd);
+extern void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
+                             struct sysfs_dirent *parent_sd);
+extern void sysfs_add_one(struct sysfs_addrm_cxt *acxt,
+                         struct sysfs_dirent *sd);
+extern void sysfs_remove_one(struct sysfs_addrm_cxt *acxt,
+                            struct sysfs_dirent *sd);
+extern int sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt);
 
-extern int sysfs_dirent_exist(struct sysfs_dirent *, const unsigned char *);
-extern int sysfs_make_dirent(struct sysfs_dirent *, struct dentry *, void *,
-                               umode_t, int);
-
-extern int sysfs_add_file(struct dentry *, const struct attribute *, int);
-extern int sysfs_hash_and_remove(struct dentry * dir, const char * name);
+extern void sysfs_delete_inode(struct inode *inode);
+extern void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode);
+extern struct inode * sysfs_get_inode(struct sysfs_dirent *sd);
+extern void sysfs_instantiate(struct dentry *dentry, struct inode *inode);
+
+extern void release_sysfs_dirent(struct sysfs_dirent * sd);
+extern struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
+                                             const unsigned char *name);
+extern struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd,
+                                            const unsigned char *name);
+extern struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode,
+                                            int type);
+
+extern int sysfs_add_file(struct sysfs_dirent *dir_sd,
+                         const struct attribute *attr, int type);
+extern int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name);
 extern struct sysfs_dirent *sysfs_find(struct sysfs_dirent *dir, const char * name);
 
-extern int sysfs_create_subdir(struct kobject *, const char *, struct dentry **);
-extern void sysfs_remove_subdir(struct dentry *);
+extern int sysfs_create_subdir(struct kobject *kobj, const char *name,
+                              struct sysfs_dirent **p_sd);
+extern void sysfs_remove_subdir(struct sysfs_dirent *sd);
 
-extern const unsigned char * sysfs_get_name(struct sysfs_dirent *sd);
-extern void sysfs_drop_dentry(struct sysfs_dirent *sd, struct dentry *parent);
 extern int sysfs_setattr(struct dentry *dentry, struct iattr *iattr);
 
-extern spinlock_t sysfs_lock;
-extern struct rw_semaphore sysfs_rename_sem;
+extern spinlock_t sysfs_assoc_lock;
+extern struct mutex sysfs_mutex;
 extern struct super_block * sysfs_sb;
 extern const struct file_operations sysfs_dir_operations;
 extern const struct file_operations sysfs_file_operations;
@@ -42,73 +103,9 @@ extern const struct file_operations bin_fops;
 extern const struct inode_operations sysfs_dir_inode_operations;
 extern const struct inode_operations sysfs_symlink_inode_operations;
 
-struct sysfs_symlink {
-       char * link_name;
-       struct kobject * target_kobj;
-};
-
-struct sysfs_buffer {
-       struct list_head                associates;
-       size_t                          count;
-       loff_t                          pos;
-       char                            * page;
-       struct sysfs_ops                * ops;
-       struct semaphore                sem;
-       int                             orphaned;
-       int                             needs_read_fill;
-       int                             event;
-};
-
-struct sysfs_buffer_collection {
-       struct list_head        associates;
-};
-
-static inline struct kobject * to_kobj(struct dentry * dentry)
-{
-       struct sysfs_dirent * sd = dentry->d_fsdata;
-       return ((struct kobject *) sd->s_element);
-}
-
-static inline struct attribute * to_attr(struct dentry * dentry)
+static inline unsigned int sysfs_type(struct sysfs_dirent *sd)
 {
-       struct sysfs_dirent * sd = dentry->d_fsdata;
-       return ((struct attribute *) sd->s_element);
-}
-
-static inline struct bin_attribute * to_bin_attr(struct dentry * dentry)
-{
-       struct sysfs_dirent * sd = dentry->d_fsdata;
-       return ((struct bin_attribute *) sd->s_element);
-}
-
-static inline struct kobject *sysfs_get_kobject(struct dentry *dentry)
-{
-       struct kobject * kobj = NULL;
-
-       spin_lock(&dcache_lock);
-       if (!d_unhashed(dentry)) {
-               struct sysfs_dirent * sd = dentry->d_fsdata;
-               if (sd->s_type & SYSFS_KOBJ_LINK) {
-                       struct sysfs_symlink * sl = sd->s_element;
-                       kobj = kobject_get(sl->target_kobj);
-               } else
-                       kobj = kobject_get(sd->s_element);
-       }
-       spin_unlock(&dcache_lock);
-
-       return kobj;
-}
-
-static inline void release_sysfs_dirent(struct sysfs_dirent * sd)
-{
-       if (sd->s_type & SYSFS_KOBJ_LINK) {
-               struct sysfs_symlink * sl = sd->s_element;
-               kfree(sl->link_name);
-               kobject_put(sl->target_kobj);
-               kfree(sl);
-       }
-       kfree(sd->s_iattr);
-       kmem_cache_free(sysfs_dir_cachep, sd);
+       return sd->s_flags & SYSFS_TYPE_MASK;
 }
 
 static inline struct sysfs_dirent * sysfs_get(struct sysfs_dirent * sd)
@@ -122,7 +119,7 @@ static inline struct sysfs_dirent * sysfs_get(struct sysfs_dirent * sd)
 
 static inline void sysfs_put(struct sysfs_dirent * sd)
 {
-       if (atomic_dec_and_test(&sd->s_count))
+       if (sd && atomic_dec_and_test(&sd->s_count))
                release_sysfs_dirent(sd);
 }
 
index 0732ddb9020beddba8e0c8caf0a71a43ed3c7eb8..589be21d884e362d17433f4e55999d73b537203a 100644 (file)
@@ -27,7 +27,7 @@ const struct file_operations sysv_file_operations = {
        .aio_write      = generic_file_aio_write,
        .mmap           = generic_file_mmap,
        .fsync          = sysv_sync_file,
-       .sendfile       = generic_file_sendfile,
+       .splice_read    = generic_file_splice_read,
 };
 
 const struct inode_operations sysv_file_inode_operations = {
index 51b5764685e777f5b3489c9c6e83aac898233559..df070bee8d4f83f3a6966c6fe2485541e217accc 100644 (file)
@@ -261,7 +261,7 @@ const struct file_operations udf_file_operations = {
        .aio_write              = udf_file_aio_write,
        .release                = udf_release_file,
        .fsync                  = udf_fsync_file,
-       .sendfile               = generic_file_sendfile,
+       .splice_read            = generic_file_splice_read,
 };
 
 const struct inode_operations udf_file_inode_operations = {
index 1e096323bad47f240bdbc30191922d46638a5612..6705d74c6d2d9b836dcdd3d3be1d40b65b3bf8e1 100644 (file)
@@ -60,5 +60,5 @@ const struct file_operations ufs_file_operations = {
        .mmap           = generic_file_mmap,
        .open           = generic_file_open,
        .fsync          = ufs_sync_file,
-       .sendfile       = generic_file_sendfile,
+       .splice_read    = generic_file_splice_read,
 };
index cb51dc9613555b6c8a37160b0d45d727359235bd..8c43cd2e237a5f15b18c743e2c13a10fd8c0f51f 100644 (file)
@@ -123,30 +123,6 @@ xfs_file_aio_write_invis(
        return __xfs_file_write(iocb, iov, nr_segs, IO_ISAIO|IO_INVIS, pos);
 }
 
-STATIC ssize_t
-xfs_file_sendfile(
-       struct file             *filp,
-       loff_t                  *pos,
-       size_t                  count,
-       read_actor_t            actor,
-       void                    *target)
-{
-       return bhv_vop_sendfile(vn_from_inode(filp->f_path.dentry->d_inode),
-                               filp, pos, 0, count, actor, target, NULL);
-}
-
-STATIC ssize_t
-xfs_file_sendfile_invis(
-       struct file             *filp,
-       loff_t                  *pos,
-       size_t                  count,
-       read_actor_t            actor,
-       void                    *target)
-{
-       return bhv_vop_sendfile(vn_from_inode(filp->f_path.dentry->d_inode),
-                               filp, pos, IO_INVIS, count, actor, target, NULL);
-}
-
 STATIC ssize_t
 xfs_file_splice_read(
        struct file             *infilp,
@@ -452,7 +428,6 @@ const struct file_operations xfs_file_operations = {
        .write          = do_sync_write,
        .aio_read       = xfs_file_aio_read,
        .aio_write      = xfs_file_aio_write,
-       .sendfile       = xfs_file_sendfile,
        .splice_read    = xfs_file_splice_read,
        .splice_write   = xfs_file_splice_write,
        .unlocked_ioctl = xfs_file_ioctl,
@@ -475,7 +450,6 @@ const struct file_operations xfs_invis_file_operations = {
        .write          = do_sync_write,
        .aio_read       = xfs_file_aio_read_invis,
        .aio_write      = xfs_file_aio_write_invis,
-       .sendfile       = xfs_file_sendfile_invis,
        .splice_read    = xfs_file_splice_read_invis,
        .splice_write   = xfs_file_splice_write_invis,
        .unlocked_ioctl = xfs_file_ioctl_invis,
index 715adad7dd4dd07607edda8aae8e30bb31697899..af24a457d3a33efebe55719cb3dd1bc0e755fe5d 100644 (file)
  * Feature macros (disable/enable)
  */
 #undef  HAVE_REFCACHE  /* reference cache not needed for NFS in 2.6 */
-#define HAVE_SENDFILE  /* sendfile(2) exists in 2.6, but not in 2.4 */
 #define HAVE_SPLICE    /* a splice(2) exists in 2.6, but not in 2.4 */
 #ifdef CONFIG_SMP
 #define HAVE_PERCPU_SB /* per cpu superblock counters are a 2.6 feature */
index ed90403f0ee71dcfaefc4ae03d84990d59155f3e..765ec16a6e392d3406d1891c6a58bfc456f1d23a 100644 (file)
@@ -286,50 +286,6 @@ xfs_read(
        return ret;
 }
 
-ssize_t
-xfs_sendfile(
-       bhv_desc_t              *bdp,
-       struct file             *filp,
-       loff_t                  *offset,
-       int                     ioflags,
-       size_t                  count,
-       read_actor_t            actor,
-       void                    *target,
-       cred_t                  *credp)
-{
-       xfs_inode_t             *ip = XFS_BHVTOI(bdp);
-       xfs_mount_t             *mp = ip->i_mount;
-       ssize_t                 ret;
-
-       XFS_STATS_INC(xs_read_calls);
-       if (XFS_FORCED_SHUTDOWN(mp))
-               return -EIO;
-
-       xfs_ilock(ip, XFS_IOLOCK_SHARED);
-
-       if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) &&
-           (!(ioflags & IO_INVIS))) {
-               bhv_vrwlock_t locktype = VRWLOCK_READ;
-               int error;
-
-               error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp),
-                                     *offset, count,
-                                     FILP_DELAY_FLAG(filp), &locktype);
-               if (error) {
-                       xfs_iunlock(ip, XFS_IOLOCK_SHARED);
-                       return -error;
-               }
-       }
-       xfs_rw_enter_trace(XFS_SENDFILE_ENTER, &ip->i_iocore,
-                  (void *)(unsigned long)target, count, *offset, ioflags);
-       ret = generic_file_sendfile(filp, offset, count, actor, target);
-       if (ret > 0)
-               XFS_STATS_ADD(xs_read_bytes, ret);
-
-       xfs_iunlock(ip, XFS_IOLOCK_SHARED);
-       return ret;
-}
-
 ssize_t
 xfs_splice_read(
        bhv_desc_t              *bdp,
index 7ac51b1d2161c6b9d2033dc3d3ea96d3e1ff38d7..7c60a1eed88ba6c347d5ba383147d56e077f459c 100644 (file)
@@ -90,9 +90,6 @@ extern ssize_t xfs_read(struct bhv_desc *, struct kiocb *,
 extern ssize_t xfs_write(struct bhv_desc *, struct kiocb *,
                                const struct iovec *, unsigned int,
                                loff_t *, int, struct cred *);
-extern ssize_t xfs_sendfile(struct bhv_desc *, struct file *,
-                               loff_t *, int, size_t, read_actor_t,
-                               void *, struct cred *);
 extern ssize_t xfs_splice_read(struct bhv_desc *, struct file *, loff_t *,
                                struct pipe_inode_info *, size_t, int, int,
                                struct cred *);
index d1b2d01843d177d2f75b8bed5f0c07d3061ba519..013048a92643d1adb1001b652b07c948add850dc 100644 (file)
@@ -139,9 +139,6 @@ typedef ssize_t (*vop_read_t)(bhv_desc_t *, struct kiocb *,
 typedef ssize_t (*vop_write_t)(bhv_desc_t *, struct kiocb *,
                                const struct iovec *, unsigned int,
                                loff_t *, int, struct cred *);
-typedef ssize_t (*vop_sendfile_t)(bhv_desc_t *, struct file *,
-                               loff_t *, int, size_t, read_actor_t,
-                               void *, struct cred *);
 typedef ssize_t (*vop_splice_read_t)(bhv_desc_t *, struct file *, loff_t *,
                                struct pipe_inode_info *, size_t, int, int,
                                struct cred *);
@@ -206,7 +203,6 @@ typedef struct bhv_vnodeops {
        vop_close_t             vop_close;
        vop_read_t              vop_read;
        vop_write_t             vop_write;
-       vop_sendfile_t          vop_sendfile;
        vop_splice_read_t       vop_splice_read;
        vop_splice_write_t      vop_splice_write;
        vop_ioctl_t             vop_ioctl;
@@ -254,8 +250,6 @@ typedef struct bhv_vnodeops {
                VOP(vop_read, vp)(VNHEAD(vp),file,iov,segs,offset,ioflags,cr)
 #define bhv_vop_write(vp,file,iov,segs,offset,ioflags,cr)              \
                VOP(vop_write, vp)(VNHEAD(vp),file,iov,segs,offset,ioflags,cr)
-#define bhv_vop_sendfile(vp,f,off,ioflags,cnt,act,targ,cr)             \
-               VOP(vop_sendfile, vp)(VNHEAD(vp),f,off,ioflags,cnt,act,targ,cr)
 #define bhv_vop_splice_read(vp,f,o,pipe,cnt,fl,iofl,cr)                        \
                VOP(vop_splice_read, vp)(VNHEAD(vp),f,o,pipe,cnt,fl,iofl,cr)
 #define bhv_vop_splice_write(vp,f,o,pipe,cnt,fl,iofl,cr)               \
index de17aed578f04878d7942cd113103fc19ef5619f..70bc82f65311e3b2a57a7cda2fd292256f8201f6 100644 (file)
@@ -4680,9 +4680,6 @@ bhv_vnodeops_t xfs_vnodeops = {
        .vop_open               = xfs_open,
        .vop_close              = xfs_close,
        .vop_read               = xfs_read,
-#ifdef HAVE_SENDFILE
-       .vop_sendfile           = xfs_sendfile,
-#endif
 #ifdef HAVE_SPLICE
        .vop_splice_read        = xfs_splice_read,
        .vop_splice_write       = xfs_splice_write,
index 85aa1127c903f832282ba843e3a163de8563dbed..30ee7669b19f9622703478bd77c45aab598c628e 100644 (file)
@@ -199,30 +199,6 @@ pci_dma_sync_sg_for_device(struct pci_dev *dev, struct scatterlist *sg,
 
 extern int pci_dma_supported(struct pci_dev *hwdev, u64 mask);
 
-/* True if the machine supports DAC addressing, and DEV can
-   make use of it given MASK.  */
-extern int pci_dac_dma_supported(struct pci_dev *hwdev, u64 mask);
-
-/* Convert to/from DAC dma address and struct page.  */
-extern dma64_addr_t pci_dac_page_to_dma(struct pci_dev *, struct page *,
-                                       unsigned long, int);
-extern struct page *pci_dac_dma_to_page(struct pci_dev *, dma64_addr_t);
-extern unsigned long pci_dac_dma_to_offset(struct pci_dev *, dma64_addr_t);
-
-static inline void
-pci_dac_dma_sync_single_for_cpu(struct pci_dev *pdev, dma64_addr_t dma_addr,
-                               size_t len, int direction)
-{
-       /* Nothing to do. */
-}
-
-static inline void
-pci_dac_dma_sync_single_for_device(struct pci_dev *pdev, dma64_addr_t dma_addr,
-                                  size_t len, int direction)
-{
-       /* Nothing to do. */
-}
-
 #ifdef CONFIG_PCI
 static inline void pci_dma_burst_advice(struct pci_dev *pdev,
                                        enum pci_dma_burst_strategy *strat,
@@ -275,11 +251,6 @@ static inline int pci_proc_domain(struct pci_bus *bus)
        return hose->need_domain_info;
 }
 
-static inline void
-pcibios_add_platform_entries(struct pci_dev *dev)
-{
-}
-
 struct pci_dev *alpha_gendev_to_pci(struct device *dev);
 
 #endif /* __KERNEL__ */
index c68e1680da0173d5754d1a1df4944120a5239e58..73237bd130a28b16f35709fa432c2457f8c0191c 100644 (file)
@@ -1 +1,3 @@
 include include/asm-generic/Kbuild.asm
+
+unifdef-y += hwcap.h
index b0369e176f7bbd95a3fa333498a77a43b5f136dc..8019ffd0ad3b61a23ee920a3b6b79e2009b16ec6 100644 (file)
@@ -16,6 +16,7 @@
 #ifndef AT91_DBGU_H
 #define AT91_DBGU_H
 
+#ifdef AT91_DBGU
 #define AT91_DBGU_CR           (AT91_DBGU + 0x00)      /* Control Register */
 #define AT91_DBGU_MR           (AT91_DBGU + 0x04)      /* Mode Register */
 #define AT91_DBGU_IER          (AT91_DBGU + 0x08)      /* Interrupt Enable Register */
 
 #define AT91_DBGU_CIDR         (AT91_DBGU + 0x40)      /* Chip ID Register */
 #define AT91_DBGU_EXID         (AT91_DBGU + 0x44)      /* Chip ID Extension Register */
+#define AT91_DBGU_FNR          (AT91_DBGU + 0x48)      /* Force NTRST Register [SAM9 only] */
+#define                AT91_DBGU_FNTRST        (1 << 0)                /* Force NTRST */
+
+#endif /* AT91_DBGU */
+
+/*
+ * Some AT91 parts that don't have full DEBUG units still support the ID
+ * and extensions register.
+ */
 #define                AT91_CIDR_VERSION       (0x1f << 0)             /* Version of the Device */
 #define                AT91_CIDR_EPROC         (7    << 5)             /* Embedded Processor */
 #define                AT91_CIDR_NVPSIZ        (0xf  << 8)             /* Nonvolatile Program Memory Size */
@@ -53,7 +63,4 @@
 #define                AT91_CIDR_NVPTYP        (7    << 28)            /* Nonvolatile Program Memory Type */
 #define                AT91_CIDR_EXT           (1    << 31)            /* Extension Flag */
 
-#define AT91_DBGU_FNR          (AT91_DBGU + 0x48)      /* Force NTRST Register [SAM9 only] */
-#define                AT91_DBGU_FNTRST        (1 << 0)                /* Force NTRST */
-
 #endif
diff --git a/include/asm-arm/arch-at91/at91x40.h b/include/asm-arm/arch-at91/at91x40.h
new file mode 100644 (file)
index 0000000..612203e
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * include/asm-arm/arch-at91/at91x40.h
+ *
+ * (C) Copyright 2007, Greg Ungerer <gerg@snapgear.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef AT91X40_H
+#define AT91X40_H
+
+/*
+ *     IRQ list.
+ */
+#define AT91_ID_FIQ            0       /* FIQ */
+#define AT91_ID_SYS            1       /* System Peripheral */
+#define AT91X40_ID_USART0      2       /* USART port 0 */
+#define AT91X40_ID_USART1      3       /* USART port 1 */
+#define AT91X40_ID_TC0         4       /* Timer/Counter 0 */
+#define AT91X40_ID_TC1         5       /* Timer/Counter 1*/
+#define AT91X40_ID_TC2         6       /* Timer/Counter 2*/
+#define AT91X40_ID_WD          7       /* Watchdog? */
+#define AT91X40_ID_PIOA                8       /* Parallel IO Controller A */
+
+#define AT91X40_ID_IRQ0                16      /* External IRQ 0 */
+#define AT91X40_ID_IRQ1                17      /* External IRQ 1 */
+#define AT91X40_ID_IRQ2                18      /* External IRQ 2 */
+
+/*
+ * System Peripherals (offset from AT91_BASE_SYS)
+ */
+#define AT91_BASE_SYS  0xffc00000
+
+#define AT91_EBI       (0xffe00000 - AT91_BASE_SYS)    /* External Bus Interface */
+#define AT91_SF                (0xfff00000 - AT91_BASE_SYS)    /* Special Function */
+#define AT91_USART1    (0xfffcc000 - AT91_BASE_SYS)    /* USART 1 */
+#define AT91_USART0    (0xfffd0000 - AT91_BASE_SYS)    /* USART 0 */
+#define AT91_TC                (0xfffe0000 - AT91_BASE_SYS)    /* Timer Counter */
+#define AT91_PIOA      (0xffff0000 - AT91_BASE_SYS)    /* PIO Controller A */
+#define AT91_PS                (0xffff4000 - AT91_BASE_SYS)    /* Power Save */
+#define AT91_WD                (0xffff8000 - AT91_BASE_SYS)    /* Watchdog Timer */
+#define AT91_AIC       (0xfffff000 - AT91_BASE_SYS)    /* Advanced Interrupt Controller */
+
+/*
+ * The AT91x40 series doesn't have a debug unit like the other AT91 parts.
+ * But it does have a chip identify register and extension ID, so define at
+ * least these here.
+ */
+#define AT91_DBGU_CIDR (AT91_SF + 0)   /* CIDR in PS segment */
+#define AT91_DBGU_EXID (AT91_SF + 4)   /* EXID in PS segment */
+
+#endif /* AT91X40_H */
index ef93c30a9c5fd17fd642c35be4c5f51c9ecdb98b..080cbb401a874efd1e7e2e6b056e4f2ddd73287a 100644 (file)
 
 #define ARCH_ID_AT91SAM9RL64   0x019b03a0
 
+#define ARCH_ID_AT91M40800     0x14080044
+#define ARCH_ID_AT91R40807     0x44080746
+#define ARCH_ID_AT91M40807     0x14080745
+#define ARCH_ID_AT91R40008     0x44000840
+
 static inline unsigned long at91_cpu_identify(void)
 {
        return (at91_sys_read(AT91_DBGU_CIDR) & ~AT91_CIDR_VERSION);
index 46835e945aea0b875a9e5f252155c0d27355f381..8f1cdd38a96986fe31f9ce47a34fac0a236ca053 100644 (file)
 #include <asm/arch/at91sam9263.h>
 #elif defined(CONFIG_ARCH_AT91SAM9RL)
 #include <asm/arch/at91sam9rl.h>
+#elif defined(CONFIG_ARCH_AT91X40)
+#include <asm/arch/at91x40.h>
 #else
 #error "Unsupported AT91 processor"
 #endif
 
 
+#ifdef CONFIG_MMU
 /*
  * Remap the peripherals from address 0xFFF78000 .. 0xFFFFFFFF
  * to 0xFEF78000 .. 0xFF000000.  (544Kb)
  */
 #define AT91_IO_PHYS_BASE      0xFFF78000
-#define AT91_IO_SIZE           (0xFFFFFFFF - AT91_IO_PHYS_BASE + 1)
 #define AT91_IO_VIRT_BASE      (0xFF000000 - AT91_IO_SIZE)
+#else
+/*
+ * Identity mapping for the non MMU case.
+ */
+#define AT91_IO_PHYS_BASE      AT91_BASE_SYS
+#define AT91_IO_VIRT_BASE      AT91_IO_PHYS_BASE
+#endif
+
+#define AT91_IO_SIZE           (0xFFFFFFFF - AT91_IO_PHYS_BASE + 1)
 
  /* Convert a physical IO address to virtual IO address */
 #define AT91_IO_P2V(x)         ((x) - AT91_IO_PHYS_BASE + AT91_IO_VIRT_BASE)
 #define AT91_CHIPSELECT_7      0x80000000
 
 /* SDRAM */
+#ifdef CONFIG_DRAM_BASE
+#define AT91_SDRAM_BASE                CONFIG_DRAM_BASE
+#else
 #define AT91_SDRAM_BASE                AT91_CHIPSELECT_1
+#endif
 
 /* Clocks */
 #define AT91_SLOW_CLOCK                32768           /* slow clock */
index 2df1ee12dfb797a1a70adc3a7cb4f5015eeea8b3..a310698fb4da9eb04e32b3772dd1f52a75732a8e 100644 (file)
 #define AT91SAM9_MASTER_CLOCK  100000000
 #define CLOCK_TICK_RATE                (AT91SAM9_MASTER_CLOCK/16)
 
+#elif defined(CONFIG_ARCH_AT91X40)
+
+#define AT91X40_MASTER_CLOCK   40000000
+#define CLOCK_TICK_RATE                (AT91X40_MASTER_CLOCK)
+
 #endif
 
 #endif
index 30ac587b3b41d415eeb4d11739488ec33d649314..272a7e0dc6cf928c11a4328741a03e5302441c8e 100644 (file)
  */
 static void putc(int c)
 {
+#ifdef AT91_DBGU
        void __iomem *sys = (void __iomem *) AT91_BASE_SYS;     /* physical address */
 
        while (!(__raw_readl(sys + AT91_DBGU_SR) & AT91_DBGU_TXRDY))
                barrier();
        __raw_writel(c, sys + AT91_DBGU_THR);
+#endif
 }
 
 static inline void flush(void)
 {
+#ifdef AT91_DBGU
        void __iomem *sys = (void __iomem *) AT91_BASE_SYS;     /* physical address */
 
        /* wait for transmission to complete */
        while (!(__raw_readl(sys + AT91_DBGU_SR) & AT91_DBGU_TXEMPTY))
                barrier();
+#endif
 }
 
 #define arch_decomp_setup()
diff --git a/include/asm-arm/arch-davinci/clock.h b/include/asm-arm/arch-davinci/clock.h
new file mode 100644 (file)
index 0000000..cc168b7
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * include/asm-arm/arch-davinci/clock.h
+ *
+ * Clock control driver for DaVinci - header file
+ *
+ * Authors: Vladimir Barinov <source@mvista.com>
+ *
+ * 2007 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#ifndef __ASM_ARCH_DAVINCI_CLOCK_H
+#define __ASM_ARCH_DAVINCI_CLOCK_H
+
+struct clk;
+
+extern int clk_register(struct clk *clk);
+extern void clk_unregister(struct clk *clk);
+extern int davinci_clk_init(void);
+
+#endif
diff --git a/include/asm-arm/arch-davinci/gpio.h b/include/asm-arm/arch-davinci/gpio.h
new file mode 100644 (file)
index 0000000..ea24a0e
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * TI DaVinci GPIO Support
+ *
+ * Copyright (c) 2006 David Brownell
+ * Copyright (c) 2007, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef        __DAVINCI_GPIO_H
+#define        __DAVINCI_GPIO_H
+
+/*
+ * basic gpio routines
+ *
+ * board-specific init should be done by arch/.../.../board-XXX.c (maybe
+ * initializing banks together) rather than boot loaders; kexec() won't
+ * go through boot loaders.
+ *
+ * the gpio clock will be turned on when gpios are used, and you may also
+ * need to pay attention to PINMUX0 and PINMUX1 to be sure those pins are
+ * used as gpios, not with other peripherals.
+ *
+ * GPIOs are numbered 0..(DAVINCI_N_GPIO-1).  For documentation, and maybe
+ * for later updates, code should write GPIO(N) or:
+ *  - GPIOV18(N) for 1.8V pins, N in 0..53; same as GPIO(0)..GPIO(53)
+ *  - GPIOV33(N) for 3.3V pins, N in 0..17; same as GPIO(54)..GPIO(70)
+ *
+ * For GPIO IRQs use gpio_to_irq(GPIO(N)) or gpio_to_irq(GPIOV33(N)) etc
+ * for now, that's != GPIO(N)
+ */
+#define        GPIO(X)         (X)             /* 0 <= X <= 70 */
+#define        GPIOV18(X)      (X)             /* 1.8V i/o; 0 <= X <= 53 */
+#define        GPIOV33(X)      ((X)+54)        /* 3.3V i/o; 0 <= X <= 17 */
+
+struct gpio_controller {
+       u32     dir;
+       u32     out_data;
+       u32     set_data;
+       u32     clr_data;
+       u32     in_data;
+       u32     set_rising;
+       u32     clr_rising;
+       u32     set_falling;
+       u32     clr_falling;
+       u32     intstat;
+};
+
+/* The __gpio_to_controller() and __gpio_mask() functions inline to constants
+ * with constant parameters; or in outlined code they execute at runtime.
+ *
+ * You'd access the controller directly when reading or writing more than
+ * one gpio value at a time, and to support wired logic where the value
+ * being driven by the cpu need not match the value read back.
+ *
+ * These are NOT part of the cross-platform GPIO interface
+ */
+static inline struct gpio_controller *__iomem
+__gpio_to_controller(unsigned gpio)
+{
+       void *__iomem ptr;
+
+       if (gpio < 32)
+               ptr = (void *__iomem)IO_ADDRESS(DAVINCI_GPIO_BASE + 0x10);
+       else if (gpio < 64)
+               ptr = (void *__iomem)IO_ADDRESS(DAVINCI_GPIO_BASE + 0x38);
+       else if (gpio < DAVINCI_N_GPIO)
+               ptr = (void *__iomem)IO_ADDRESS(DAVINCI_GPIO_BASE + 0x60);
+       else
+               ptr = NULL;
+       return ptr;
+}
+
+static inline u32 __gpio_mask(unsigned gpio)
+{
+       return 1 << (gpio % 32);
+}
+
+/* The get/set/clear functions will inline when called with constant
+ * parameters, for low-overhead bitbanging.  Illegal constant parameters
+ * cause link-time errors.
+ *
+ * Otherwise, calls with variable parameters use outlined functions.
+ */
+extern int __error_inval_gpio(void);
+
+extern void __gpio_set(unsigned gpio, int value);
+extern int __gpio_get(unsigned gpio);
+
+static inline void gpio_set_value(unsigned gpio, int value)
+{
+       if (__builtin_constant_p(value)) {
+               struct gpio_controller  *__iomem g;
+               u32                     mask;
+
+               if (gpio >= DAVINCI_N_GPIO)
+                       __error_inval_gpio();
+
+               g = __gpio_to_controller(gpio);
+               mask = __gpio_mask(gpio);
+               if (value)
+                       __raw_writel(mask, &g->set_data);
+               else
+                       __raw_writel(mask, &g->clr_data);
+               return;
+       }
+
+       __gpio_set(gpio, value);
+}
+
+/* Returns zero or nonzero; works for gpios configured as inputs OR
+ * as outputs.
+ *
+ * NOTE: changes in reported values are synchronized to the GPIO clock.
+ * This is most easily seen after calling gpio_set_value() and then immediatly
+ * gpio_get_value(), where the gpio_get_value() would return the old value
+ * until the GPIO clock ticks and the new value gets latched.
+ */
+
+static inline int gpio_get_value(unsigned gpio)
+{
+       struct gpio_controller *__iomem g;
+
+       if (!__builtin_constant_p(gpio))
+               return __gpio_get(gpio);
+
+       if (gpio >= DAVINCI_N_GPIO)
+               return __error_inval_gpio();
+
+       g = __gpio_to_controller(gpio);
+       return !!(__gpio_mask(gpio) & __raw_readl(&g->in_data));
+}
+
+/* powerup default direction is IN */
+extern int gpio_direction_input(unsigned gpio);
+extern int gpio_direction_output(unsigned gpio, int value);
+
+#include <asm-generic/gpio.h>  /* cansleep wrappers */
+
+extern int gpio_request(unsigned gpio, const char *tag);
+extern void gpio_free(unsigned gpio);
+
+static inline int gpio_to_irq(unsigned gpio)
+{
+       return DAVINCI_N_AINTC_IRQ + gpio;
+}
+
+static inline int irq_to_gpio(unsigned irq)
+{
+       return irq - DAVINCI_N_AINTC_IRQ;
+}
+
+#endif                         /* __DAVINCI_GPIO_H */
index 60362d80229e66f6a12c69ec4e2455096763b15c..a2e8969afaca913c263dbb98f419dab6c3fa3799 100644 (file)
 #ifndef __ASM_ARCH_HARDWARE_H
 #define __ASM_ARCH_HARDWARE_H
 
+/*
+ * Base register addresses
+ */
+#define DAVINCI_DMA_3PCC_BASE                  (0x01C00000)
+#define DAVINCI_DMA_3PTC0_BASE                 (0x01C10000)
+#define DAVINCI_DMA_3PTC1_BASE                 (0x01C10400)
+#define DAVINCI_I2C_BASE                       (0x01C21000)
+#define DAVINCI_PWM0_BASE                      (0x01C22000)
+#define DAVINCI_PWM1_BASE                      (0x01C22400)
+#define DAVINCI_PWM2_BASE                      (0x01C22800)
+#define DAVINCI_SYSTEM_MODULE_BASE             (0x01C40000)
+#define DAVINCI_PLL_CNTRL0_BASE                        (0x01C40800)
+#define DAVINCI_PLL_CNTRL1_BASE                        (0x01C40C00)
+#define DAVINCI_PWR_SLEEP_CNTRL_BASE           (0x01C41000)
+#define DAVINCI_SYSTEM_DFT_BASE                        (0x01C42000)
+#define DAVINCI_IEEE1394_BASE                  (0x01C60000)
+#define DAVINCI_USB_OTG_BASE                   (0x01C64000)
+#define DAVINCI_CFC_ATA_BASE                   (0x01C66000)
+#define DAVINCI_SPI_BASE                       (0x01C66800)
+#define DAVINCI_GPIO_BASE                      (0x01C67000)
+#define DAVINCI_UHPI_BASE                      (0x01C67800)
+#define DAVINCI_VPSS_REGS_BASE                 (0x01C70000)
+#define DAVINCI_EMAC_CNTRL_REGS_BASE           (0x01C80000)
+#define DAVINCI_EMAC_WRAPPER_CNTRL_REGS_BASE   (0x01C81000)
+#define DAVINCI_EMAC_WRAPPER_RAM_BASE          (0x01C82000)
+#define DAVINCI_MDIO_CNTRL_REGS_BASE           (0x01C84000)
+#define DAVINCI_IMCOP_BASE                     (0x01CC0000)
+#define DAVINCI_ASYNC_EMIF_CNTRL_BASE          (0x01E00000)
+#define DAVINCI_VLYNQ_BASE                     (0x01E01000)
+#define DAVINCI_MCBSP_BASE                     (0x01E02000)
+#define DAVINCI_MMC_SD_BASE                    (0x01E10000)
+#define DAVINCI_MS_BASE                                (0x01E20000)
+#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE       (0x02000000)
+#define DAVINCI_ASYNC_EMIF_DATA_CE1_BASE       (0x04000000)
+#define DAVINCI_ASYNC_EMIF_DATA_CE2_BASE       (0x06000000)
+#define DAVINCI_ASYNC_EMIF_DATA_CE3_BASE       (0x08000000)
+#define DAVINCI_VLYNQ_REMOTE_BASE              (0x0C000000)
+
 #endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/include/asm-arm/arch-davinci/mux.h b/include/asm-arm/arch-davinci/mux.h
new file mode 100644 (file)
index 0000000..c24b678
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * DaVinci pin multiplexing defines
+ *
+ * Author: Vladimir Barinov, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * 2007 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#ifndef __ASM_ARCH_MUX_H
+#define __ASM_ARCH_MUX_H
+
+#define DAVINCI_MUX_AEAW0      0
+#define DAVINCI_MUX_AEAW1      1
+#define DAVINCI_MUX_AEAW2      2
+#define DAVINCI_MUX_AEAW3      3
+#define DAVINCI_MUX_AEAW4      4
+#define DAVINCI_MUX_AECS4      10
+#define DAVINCI_MUX_AECS5      11
+#define DAVINCI_MUX_VLYNQWD0   12
+#define DAVINCI_MUX_VLYNQWD1   13
+#define DAVINCI_MUX_VLSCREN    14
+#define DAVINCI_MUX_VLYNQEN    15
+#define DAVINCI_MUX_HDIREN     16
+#define DAVINCI_MUX_ATAEN      17
+#define DAVINCI_MUX_RGB666     22
+#define DAVINCI_MUX_RGB888     23
+#define DAVINCI_MUX_LOEEN      24
+#define DAVINCI_MUX_LFLDEN     25
+#define DAVINCI_MUX_CWEN       26
+#define DAVINCI_MUX_CFLDEN     27
+#define DAVINCI_MUX_HPIEN      29
+#define DAVINCI_MUX_1394EN     30
+#define DAVINCI_MUX_EMACEN     31
+
+#define DAVINCI_MUX_LEVEL2     32
+#define DAVINCI_MUX_UART0      (DAVINCI_MUX_LEVEL2 + 0)
+#define DAVINCI_MUX_UART1      (DAVINCI_MUX_LEVEL2 + 1)
+#define DAVINCI_MUX_UART2      (DAVINCI_MUX_LEVEL2 + 2)
+#define DAVINCI_MUX_U2FLO      (DAVINCI_MUX_LEVEL2 + 3)
+#define DAVINCI_MUX_PWM0       (DAVINCI_MUX_LEVEL2 + 4)
+#define DAVINCI_MUX_PWM1       (DAVINCI_MUX_LEVEL2 + 5)
+#define DAVINCI_MUX_PWM2       (DAVINCI_MUX_LEVEL2 + 6)
+#define DAVINCI_MUX_I2C                (DAVINCI_MUX_LEVEL2 + 7)
+#define DAVINCI_MUX_SPI                (DAVINCI_MUX_LEVEL2 + 8)
+#define DAVINCI_MUX_MSTK       (DAVINCI_MUX_LEVEL2 + 9)
+#define DAVINCI_MUX_ASP                (DAVINCI_MUX_LEVEL2 + 10)
+#define DAVINCI_MUX_CLK0       (DAVINCI_MUX_LEVEL2 + 16)
+#define DAVINCI_MUX_CLK1       (DAVINCI_MUX_LEVEL2 + 17)
+#define DAVINCI_MUX_TIMIN      (DAVINCI_MUX_LEVEL2 + 18)
+
+extern void davinci_mux_peripheral(unsigned int mux, unsigned int enable);
+
+#endif /* __ASM_ARCH_MUX_H */
diff --git a/include/asm-arm/arch-imx/gpio.h b/include/asm-arm/arch-imx/gpio.h
new file mode 100644 (file)
index 0000000..4860232
--- /dev/null
@@ -0,0 +1,102 @@
+#ifndef _IMX_GPIO_H
+
+#include <asm/arch/imx-regs.h>
+
+#define IMX_GPIO_ALLOC_MODE_NORMAL     0
+#define IMX_GPIO_ALLOC_MODE_NO_ALLOC   1
+#define IMX_GPIO_ALLOC_MODE_TRY_ALLOC  2
+#define IMX_GPIO_ALLOC_MODE_ALLOC_ONLY 4
+#define IMX_GPIO_ALLOC_MODE_RELEASE    8
+
+extern int imx_gpio_request(unsigned gpio, const char *label);
+
+extern void imx_gpio_free(unsigned gpio);
+
+extern int imx_gpio_setup_multiple_pins(const int *pin_list, unsigned count,
+                                       int alloc_mode, const char *label);
+
+extern int imx_gpio_direction_input(unsigned gpio);
+
+extern int imx_gpio_direction_output(unsigned gpio, int value);
+
+extern void __imx_gpio_set_value(unsigned gpio, int value);
+
+static inline int imx_gpio_get_value(unsigned gpio)
+{
+       return SSR(gpio >> GPIO_PORT_SHIFT) & (1 << (gpio & GPIO_PIN_MASK));
+}
+
+static inline void imx_gpio_set_value_inline(unsigned gpio, int value)
+{
+       unsigned long flags;
+
+       raw_local_irq_save(flags);
+       if(value)
+               DR(gpio >> GPIO_PORT_SHIFT) |= (1 << (gpio & GPIO_PIN_MASK));
+       else
+               DR(gpio >> GPIO_PORT_SHIFT) &= ~(1 << (gpio & GPIO_PIN_MASK));
+       raw_local_irq_restore(flags);
+}
+
+static inline void imx_gpio_set_value(unsigned gpio, int value)
+{
+       if(__builtin_constant_p(gpio))
+               imx_gpio_set_value_inline(gpio, value);
+       else
+               __imx_gpio_set_value(gpio, value);
+}
+
+extern int imx_gpio_to_irq(unsigned gpio);
+
+extern int imx_irq_to_gpio(unsigned irq);
+
+/*-------------------------------------------------------------------------*/
+
+/* Wrappers for "new style" GPIO calls. These calls i.MX specific versions
+ * to allow future extension of GPIO logic.
+ */
+
+static inline int gpio_request(unsigned gpio, const char *label)
+{
+       return imx_gpio_request(gpio, label);
+}
+
+static inline void gpio_free(unsigned gpio)
+{
+       imx_gpio_free(gpio);
+}
+
+static inline  int gpio_direction_input(unsigned gpio)
+{
+       return imx_gpio_direction_input(gpio);
+}
+
+static inline int gpio_direction_output(unsigned gpio, int value)
+{
+       return imx_gpio_direction_output(gpio, value);
+}
+
+static inline int gpio_get_value(unsigned gpio)
+{
+       return imx_gpio_get_value(gpio);
+}
+
+static inline void gpio_set_value(unsigned gpio, int value)
+{
+       imx_gpio_set_value(gpio, value);
+}
+
+#include <asm-generic/gpio.h>          /* cansleep wrappers */
+
+static inline int gpio_to_irq(unsigned gpio)
+{
+       return imx_gpio_to_irq(gpio);
+}
+
+static inline int irq_to_gpio(unsigned irq)
+{
+       return imx_irq_to_gpio(irq);
+}
+
+
+#endif
index 30de404c61f5ef71e1243e0dada38cbed8e277c9..fb9de27338796ab23d480cc250b86c55c27d8ed6 100644 (file)
@@ -77,6 +77,8 @@
 #define SWR(x)     __REG2(IMX_GPIO_BASE + 0x3c, ((x) & 3) << 8)
 #define PUEN(x)    __REG2(IMX_GPIO_BASE + 0x40, ((x) & 3) << 8)
 
+#define GPIO_PORT_MAX  3
+
 #define GPIO_PIN_MASK 0x1f
 #define GPIO_PORT_MASK (0x3 << 5)
 
index 3d3820d7ba09f71847bb9256aac2c6a7bb71b1ea..e0791af3bfead32bd7483965281dc68b353d9c47 100644 (file)
@@ -32,4 +32,8 @@
 #define        IXDP425_PCI_INTC_PIN    9
 #define        IXDP425_PCI_INTD_PIN    8
 
+/* NAND Flash pins */
+#define        IXDP425_NAND_NCE_PIN    12
 
+#define        IXDP425_NAND_CMD_BYTE   0x01
+#define        IXDP425_NAND_ADDR_BYTE  0x02
index 79b850a3be475cdb96422c85be26d3170d8e8307..dbdec36ff0d1bc7642dd64c662ea17262a52a13a 100644 (file)
@@ -6,25 +6,3 @@
 
 extern void ixp4xx_set_udc_info(struct pxa2xx_udc_mach_info *info);
 
-static inline int udc_gpio_to_irq(unsigned gpio)
-{
-       return 0;
-}
-
-static inline void udc_gpio_init_vbus(unsigned gpio)
-{
-}
-
-static inline void udc_gpio_init_pullup(unsigned gpio)
-{
-}
-
-static inline int udc_gpio_get(unsigned gpio)
-{
-       return 0;
-}
-
-static inline void udc_gpio_set(unsigned gpio, int is_on)
-{
-}
-
index 09ae6c91be60b075c3e972b383841515a9506900..f7a35b78823ff0227c44c6e4d9cc4d6052408ddd 100644 (file)
@@ -38,9 +38,10 @@ static void flush(void)
 static __inline__ void __arch_decomp_setup(unsigned long arch_id)
 {
        /*
-        * Coyote and gtwx5715 only have UART2 connected
+        * Some boards are using UART2 as console
         */
-       if (machine_is_adi_coyote() || machine_is_gtwx5715())
+       if (machine_is_adi_coyote() || machine_is_gtwx5715() ||
+                        machine_is_gateway7001() || machine_is_wg302v2())
                uart_base = (volatile u32*) IXP4XX_UART2_BASE_PHYS;
        else
                uart_base = (volatile u32*) IXP4XX_UART1_BASE_PHYS;
diff --git a/include/asm-arm/arch-ks8695/gpio.h b/include/asm-arm/arch-ks8695/gpio.h
new file mode 100644 (file)
index 0000000..65ceea2
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * include/asm-arm/arch-ks8695/gpio.h
+ *
+ * Copyright (C) 2006 Andrew Victor
+ *
+ * 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_GPIO_H_
+#define __ASM_ARCH_GPIO_H_
+
+#define KS8695_GPIO_0          0
+#define KS8695_GPIO_1          1
+#define KS8695_GPIO_2          2
+#define KS8695_GPIO_3          3
+#define KS8695_GPIO_4          4
+#define KS8695_GPIO_5          5
+#define KS8695_GPIO_6          6
+#define KS8695_GPIO_7          7
+#define KS8695_GPIO_8          8
+#define KS8695_GPIO_9          9
+#define KS8695_GPIO_10         10
+#define KS8695_GPIO_11         11
+#define KS8695_GPIO_12         12
+#define KS8695_GPIO_13         13
+#define KS8695_GPIO_14         14
+#define KS8695_GPIO_15         15
+
+
+/*
+ * Configure GPIO pin as external interrupt source.
+ */
+int __init_or_module ks8695_gpio_interrupt(unsigned int pin, unsigned int type);
+
+/*
+ * Configure the GPIO line as an input.
+ */
+int __init_or_module gpio_direction_input(unsigned int pin);
+
+/*
+ * Configure the GPIO line as an output, with default state.
+ */
+int __init_or_module gpio_direction_output(unsigned int pin, unsigned int state);
+
+/*
+ * Set the state of an output GPIO line.
+ */
+void gpio_set_value(unsigned int pin, unsigned int state);
+
+/*
+ * Read the state of a GPIO line.
+ */
+int gpio_get_value(unsigned int pin);
+
+/*
+ * Map GPIO line to IRQ number.
+ */
+int gpio_to_irq(unsigned int pin);
+
+/*
+ * Map IRQ number to GPIO line.
+ */
+int irq_to_gpio(unsigned int irq);
+
+
+#include <asm-generic/gpio.h>
+
+static inline int gpio_request(unsigned int pin, const char *label)
+{
+       return 0;
+}
+
+static inline void gpio_free(unsigned int pin)
+{
+}
+
+#endif
index bed042d71d68dd7154e5cf5ed0c4035230858706..3280ee2ddfa591cbbbe42e1336c7b89f4627e2aa 100644 (file)
@@ -30,30 +30,12 @@ typedef enum {
        DMA_PRIO_LOW = 2
 } pxa_dma_prio;
 
-#if defined(CONFIG_PXA27x)
-
-#define PXA_DMA_CHANNELS       32
-
-#define pxa_for_each_dma_prio(ch, prio)                                        \
-for (                                                                  \
-       ch = prio * 4;                                                  \
-       ch != (4 << prio) + 16;                                         \
-       ch = (ch + 1 == (4 << prio)) ? (prio * 4 + 16) : (ch + 1)       \
-)
-
-#elif defined(CONFIG_PXA25x)
-
-#define PXA_DMA_CHANNELS       16
-
-#define pxa_for_each_dma_prio(ch, prio)                                        \
-       for (ch = prio * 4; ch != (4 << prio); ch++)
-
-#endif
-
 /*
  * DMA registration
  */
 
+int __init pxa_init_dma(int num_ch);
+
 int pxa_request_dma (char *name,
                         pxa_dma_prio prio,
                         void (*irq_handler)(int, void *),
index 1d5fbb9b379a03652b3c8347ef1adaed15bce146..b7e730851461d635f38eff192b9ab6011053f98f 100644 (file)
                .endm
 
                .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-#ifdef CONFIG_PXA27x
-               mrc     p6, 0, \irqstat, c0, c0, 0              @ ICIP
-               mrc     p6, 0, \irqnr, c1, c0, 0                @ ICMR
-#else
+               mrc     p15, 0, \tmp, c0, c0, 0         @ CPUID
+               mov     \tmp, \tmp, lsr #13
+               and     \tmp, \tmp, #0x7                @ Core G
+               cmp     \tmp, #1
+               bhi     1004f
+
                mov     \base, #io_p2v(0x40000000)      @ IIR Ctl = 0x40d00000
                add     \base, \base, #0x00d00000
                ldr     \irqstat, [\base, #0]           @ ICIP
                ldr     \irqnr, [\base, #4]             @ ICMR
-#endif
+               b       1002f
+
+1004:
+               mrc     p6, 0, \irqstat, c6, c0, 0      @ ICIP2
+               mrc     p6, 0, \irqnr, c7, c0, 0        @ ICMR2
+               ands    \irqstat, \irqstat, \irqnr
+               beq     1003f
+               rsb     \irqstat, \irqnr, #0
+               and     \irqstat, \irqstat, \irqnr
+               clz     \irqnr, \irqstat
+               rsb     \irqnr, \irqnr, #31
+               add     \irqnr, \irqnr, #32
+               b       1001f
+1003:
+               mrc     p6, 0, \irqstat, c0, c0, 0      @ ICIP
+               mrc     p6, 0, \irqnr, c1, c0, 0        @ ICMR
+1002:
                ands    \irqnr, \irqstat, \irqnr
                beq     1001f
                rsb     \irqstat, \irqnr, #0
                and     \irqstat, \irqstat, \irqnr
                clz     \irqnr, \irqstat
-               rsb     \irqnr, \irqnr, #(31 - PXA_IRQ_SKIP)
+               rsb     \irqnr, \irqnr, #31
 1001:
                .endm
index e2bdc2fbede1efdd52e1a393601edb3c2f5f4e91..386121746417093c90d6807bda3cc90d3d2c7e91 100644 (file)
 
 #ifndef __ASSEMBLY__
 
+#define __cpu_is_pxa21x(id)                            \
+       ({                                              \
+               unsigned int _id = (id) >> 4 & 0xf3f;   \
+               _id == 0x212;                           \
+       })
+
+#define __cpu_is_pxa25x(id)                            \
+       ({                                              \
+               unsigned int _id = (id) >> 4 & 0xfff;   \
+               _id == 0x2d0 || _id == 0x290;           \
+       })
+
+#define __cpu_is_pxa27x(id)                            \
+       ({                                              \
+               unsigned int _id = (id) >> 4 & 0xfff;   \
+               _id == 0x411;                           \
+       })
+
+#define cpu_is_pxa21x()                                        \
+       ({                                              \
+               unsigned int id = read_cpuid(CPUID_ID); \
+               __cpu_is_pxa21x(id);                    \
+       })
+
+#define cpu_is_pxa25x()                                        \
+       ({                                              \
+               unsigned int id = read_cpuid(CPUID_ID); \
+               __cpu_is_pxa25x(id);                    \
+       })
+
+#define cpu_is_pxa27x()                                        \
+       ({                                              \
+               unsigned int id = read_cpuid(CPUID_ID); \
+               __cpu_is_pxa27x(id);                    \
+       })
+
 /*
  * Handy routine to set GPIO alternate functions
  */
index 67ed43674c635a66a3a947accb3a757810fdd260..a07fe0f928cd1f4fdea379338ba18d5d4f0675ae 100644 (file)
  */
 
 
-#ifdef CONFIG_PXA27x
-#define PXA_IRQ_SKIP   0
-#else
-#define PXA_IRQ_SKIP   7
-#endif
-
-#define PXA_IRQ(x)     ((x) - PXA_IRQ_SKIP)
+#define PXA_IRQ(x)     (x)
 
+#ifdef CONFIG_PXA27x
 #define IRQ_SSP3       PXA_IRQ(0)      /* SSP3 service request */
 #define IRQ_MSL                PXA_IRQ(1)      /* MSL Interface interrupt */
 #define IRQ_USBH2      PXA_IRQ(2)      /* USB Host interrupt 1 (OHCI) */
@@ -26,6 +21,8 @@
 #define IRQ_KEYPAD     PXA_IRQ(4)      /* Key pad controller */
 #define IRQ_MEMSTK     PXA_IRQ(5)      /* Memory Stick interrupt */
 #define IRQ_PWRI2C     PXA_IRQ(6)      /* Power I2C interrupt */
+#endif
+
 #define IRQ_HWUART     PXA_IRQ(7)      /* HWUART Transmit/Receive/Error (PXA26x) */
 #define IRQ_OST_4_11   PXA_IRQ(7)      /* OS timer 4-11 matches (PXA27x) */
 #define        IRQ_GPIO0       PXA_IRQ(8)      /* GPIO0 Edge Detect */
 #ifdef CONFIG_PXA27x
 #define IRQ_TPM                PXA_IRQ(32)     /* TPM interrupt */
 #define IRQ_CAMERA     PXA_IRQ(33)     /* Camera Interface */
-
-#define PXA_INTERNAL_IRQS 34
-#else
-#define PXA_INTERNAL_IRQS 32
 #endif
 
-#define GPIO_2_x_TO_IRQ(x)     \
-                       PXA_IRQ((x) - 2 + PXA_INTERNAL_IRQS)
+#define PXA_GPIO_IRQ_BASE      (64)
+#define PXA_GPIO_IRQ_NUM       (128)
+
+#define GPIO_2_x_TO_IRQ(x)     (PXA_GPIO_IRQ_BASE + (x))
 #define IRQ_GPIO(x)    (((x) < 2) ? (IRQ_GPIO0 + (x)) : GPIO_2_x_TO_IRQ(x))
 
-#define IRQ_TO_GPIO_2_x(i)     \
-                       ((i) - IRQ_GPIO(2) + 2)
+#define IRQ_TO_GPIO_2_x(i)     ((i) - PXA_GPIO_IRQ_BASE)
 #define IRQ_TO_GPIO(i) (((i) < IRQ_GPIO(2)) ? ((i) - IRQ_GPIO0) : IRQ_TO_GPIO_2_x(i))
 
 #if defined(CONFIG_PXA25x)
@@ -84,7 +78,7 @@
  * these.  If you need more, increase IRQ_BOARD_END, but keep it
  * within sensible limits.
  */
-#define IRQ_BOARD_START                (IRQ_GPIO(PXA_LAST_GPIO) + 1)
+#define IRQ_BOARD_START                (PXA_GPIO_IRQ_BASE + PXA_GPIO_IRQ_NUM)
 #define IRQ_BOARD_END          (IRQ_BOARD_START + 16)
 
 #define IRQ_SA1111_START       (IRQ_BOARD_END)
index 7a8a1cdf430ddaaf80d1bf9939b5975fa49d9e7b..52243a62c4e76de36fbe21f8aa10d4846684e283 100644 (file)
@@ -9,4 +9,3 @@
 
 extern int pxa_pm_prepare(suspend_state_t state);
 extern int pxa_pm_enter(suspend_state_t state);
-extern int pxa_pm_finish(suspend_state_t state);
index dbcc9298b0c89b7cc5880fd3d9a420fe4d89f3fc..e68b593d69da28638390fa3d89b55425fc032ea9 100644 (file)
 #define SSACD_P(x) (*(((x) == 1) ? &SSACD_P1 : ((x) == 2) ? &SSACD_P2 : ((x) == 3) ? &SSACD_P3 : NULL))
 
 /*
- * MultiMediaCard (MMC) controller
+ * MultiMediaCard (MMC) controller - see drivers/mmc/host/pxamci.h
  */
 
-#define MMC_STRPCL     __REG(0x41100000)  /* Control to start and stop MMC clock */
-#define MMC_STAT       __REG(0x41100004)  /* MMC Status Register (read only) */
-#define MMC_CLKRT      __REG(0x41100008)  /* MMC clock rate */
-#define MMC_SPI                __REG(0x4110000c)  /* SPI mode control bits */
-#define MMC_CMDAT      __REG(0x41100010)  /* Command/response/data sequence control */
-#define MMC_RESTO      __REG(0x41100014)  /* Expected response time out */
-#define MMC_RDTO       __REG(0x41100018)  /* Expected data read time out */
-#define MMC_BLKLEN     __REG(0x4110001c)  /* Block length of data transaction */
-#define MMC_NOB                __REG(0x41100020)  /* Number of blocks, for block mode */
-#define MMC_PRTBUF     __REG(0x41100024)  /* Partial MMC_TXFIFO FIFO written */
-#define MMC_I_MASK     __REG(0x41100028)  /* Interrupt Mask */
-#define MMC_I_REG      __REG(0x4110002c)  /* Interrupt Register (read only) */
-#define MMC_CMD                __REG(0x41100030)  /* Index of current command */
-#define MMC_ARGH       __REG(0x41100034)  /* MSW part of the current command argument */
-#define MMC_ARGL       __REG(0x41100038)  /* LSW part of the current command argument */
-#define MMC_RES                __REG(0x4110003c)  /* Response FIFO (read only) */
-#define MMC_RXFIFO     __REG(0x41100040)  /* Receive FIFO (read only) */
-#define MMC_TXFIFO     __REG(0x41100044)  /* Transmit FIFO (write only) */
-
-
 /*
  * Core Clock
  */
index 8bc6f9c3e3ea2c130b271b46359e7b0a34f7d3bc..27aa3a91012f88ac966edfa7a38a1c1e895fcc03 100644 (file)
@@ -1,41 +1,8 @@
 /*
  * linux/include/asm-arm/arch-pxa/udc.h
  *
- * This supports machine-specific differences in how the PXA2xx
- * USB Device Controller (UDC) is wired.
- *
  */
 #include <asm/mach/udc_pxa2xx.h>
 
 extern void pxa_set_udc_info(struct pxa2xx_udc_mach_info *info);
 
-static inline int udc_gpio_to_irq(unsigned gpio)
-{
-       return IRQ_GPIO(gpio & GPIO_MD_MASK_NR);
-}
-
-static inline void udc_gpio_init_vbus(unsigned gpio)
-{
-       pxa_gpio_mode((gpio & GPIO_MD_MASK_NR) | GPIO_IN);
-}
-
-static inline void udc_gpio_init_pullup(unsigned gpio)
-{
-       pxa_gpio_mode((gpio & GPIO_MD_MASK_NR) | GPIO_OUT | GPIO_DFLT_LOW);
-}
-
-static inline int udc_gpio_get(unsigned gpio)
-{
-       return (GPLR(gpio) & GPIO_bit(gpio)) != 0;
-}
-
-static inline void udc_gpio_set(unsigned gpio, int is_on)
-{
-       int mask = GPIO_bit(gpio);
-
-       if (is_on)
-               GPSR(gpio) = mask;
-       else
-               GPCR(gpio) = mask;
-}
-
index 3679a8a8922ee97778818e9fe75e7dd6ba4cf195..d7a777f05088d6332a3a723a7308f3c82070a7cd 100644 (file)
@@ -7,6 +7,7 @@
  */
 #include <asm/ptrace.h>
 #include <asm/user.h>
+#include <asm/hwcap.h>
 
 typedef unsigned long elf_greg_t;
 typedef unsigned long elf_freg_t[3];
@@ -39,30 +40,8 @@ typedef struct user_fp elf_fpregset_t;
 #endif
 #define ELF_ARCH       EM_ARM
 
-/*
- * HWCAP flags - for elf_hwcap (in kernel) and AT_HWCAP
- */
-#define HWCAP_SWP      1
-#define HWCAP_HALF     2
-#define HWCAP_THUMB    4
-#define HWCAP_26BIT    8       /* Play it safe */
-#define HWCAP_FAST_MULT        16
-#define HWCAP_FPA      32
-#define HWCAP_VFP      64
-#define HWCAP_EDSP     128
-#define HWCAP_JAVA     256
-#define HWCAP_IWMMXT   512
-#define HWCAP_CRUNCH   1024
-
 #ifdef __KERNEL__
 #ifndef __ASSEMBLY__
-/*
- * This yields a mask that user programs can use to figure out what
- * instruction set this cpu supports.
- */
-#define ELF_HWCAP      (elf_hwcap)
-extern unsigned int elf_hwcap;
-
 /*
  * This yields a string that ld.so will use to load implementation
  * specific libraries for optimization.  This is more specific in
diff --git a/include/asm-arm/hwcap.h b/include/asm-arm/hwcap.h
new file mode 100644 (file)
index 0000000..01a1391
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef __ASMARM_HWCAP_H
+#define __ASMARM_HWCAP_H
+
+/*
+ * HWCAP flags - for elf_hwcap (in kernel) and AT_HWCAP
+ */
+#define HWCAP_SWP      1
+#define HWCAP_HALF     2
+#define HWCAP_THUMB    4
+#define HWCAP_26BIT    8       /* Play it safe */
+#define HWCAP_FAST_MULT        16
+#define HWCAP_FPA      32
+#define HWCAP_VFP      64
+#define HWCAP_EDSP     128
+#define HWCAP_JAVA     256
+#define HWCAP_IWMMXT   512
+#define HWCAP_CRUNCH   1024
+
+#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
+/*
+ * This yields a mask that user programs can use to figure out what
+ * instruction set this cpu supports.
+ */
+#define ELF_HWCAP      (elf_hwcap)
+extern unsigned int elf_hwcap;
+#endif
+
+#endif
index f21abd4ddac61b8915fb6c437d45378c48b38b0f..ed3f898191f4d4b0eeb347a3e47df5966b23c186 100644 (file)
@@ -25,11 +25,6 @@ static inline void pcibios_penalize_isa_irq(int irq, int active)
  */
 #define PCI_DMA_BUS_IS_PHYS     (0)
 
-/*
- * We don't support DAC DMA cycles.
- */
-#define pci_dac_dma_supported(pci_dev, mask)   (0)
-
 /*
  * Whether pci_unmap_{single,page} is a nop depends upon the
  * configuration.
@@ -76,10 +71,6 @@ pcibios_select_root(struct pci_dev *pdev, struct resource *res)
        return root;
 }
 
-static inline void pcibios_add_platform_entries(struct pci_dev *dev)
-{
-}
-
 #endif /* __KERNEL__ */
  
 #endif
index ee3d93c281d809900cd13086932755a368f18e40..7aaa206cb54ef22e8a45d92822b31bc8bda18782 100644 (file)
@@ -10,6 +10,8 @@
 #ifndef __ASM_ARM_PTRACE_H
 #define __ASM_ARM_PTRACE_H
 
+#include <asm/hwcap.h>
+
 #define PTRACE_GETREGS         12
 #define PTRACE_SETREGS         13
 #define PTRACE_GETFPREGS       14
@@ -45,6 +47,7 @@
 #define PSR_T_BIT      0x00000020
 #define PSR_F_BIT      0x00000040
 #define PSR_I_BIT      0x00000080
+#define PSR_A_BIT      0x00000100
 #define PSR_J_BIT      0x01000000
 #define PSR_Q_BIT      0x08000000
 #define PSR_V_BIT      0x10000000
@@ -103,6 +106,10 @@ struct pt_regs {
 #define thumb_mode(regs) (0)
 #endif
 
+#define isa_mode(regs) \
+       ((((regs)->ARM_cpsr & PSR_J_BIT) >> 23) | \
+        (((regs)->ARM_cpsr & PSR_T_BIT) >> 5))
+
 #define processor_mode(regs) \
        ((regs)->ARM_cpsr & MODE_MASK)
 
@@ -117,14 +124,17 @@ struct pt_regs {
  */
 static inline int valid_user_regs(struct pt_regs *regs)
 {
-       if (user_mode(regs) &&
-           (regs->ARM_cpsr & (PSR_F_BIT|PSR_I_BIT)) == 0)
+       if (user_mode(regs) && (regs->ARM_cpsr & PSR_I_BIT) == 0) {
+               regs->ARM_cpsr &= ~(PSR_F_BIT | PSR_A_BIT);
                return 1;
+       }
 
        /*
         * Force CPSR to something logical...
         */
-       regs->ARM_cpsr &= PSR_f | PSR_s | PSR_x | PSR_T_BIT | MODE32_BIT;
+       regs->ARM_cpsr &= PSR_f | PSR_s | (PSR_x & ~PSR_A_BIT) | PSR_T_BIT | MODE32_BIT;
+       if (!(elf_hwcap & HWCAP_26BIT))
+               regs->ARM_cpsr |= USR_MODE;
 
        return 0;
 }
index a3f4fe1742d0ac84abb7a3dc9c2996579ab3e123..f66b51804736988e4323ec4f299f41aa272a66dd 100644 (file)
@@ -15,7 +15,7 @@ struct termios {
        cc_t c_cc[NCCS];                /* control characters */
 };
 
-struct ktermios {
+struct termios2 {
        tcflag_t c_iflag;               /* input mode flags */
        tcflag_t c_oflag;               /* output mode flags */
        tcflag_t c_cflag;               /* control mode flags */
@@ -26,6 +26,16 @@ struct ktermios {
        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 */
+       speed_t c_ispeed;               /* input speed */
+       speed_t c_ospeed;               /* output speed */
+};
 
 /* c_cc characters */
 #define VINTR 0
index c215fafdae4d66e9960c0daa7a75a09c1dbd220b..db2daab31fdb55d961cb2803dd90a740e55c0e97 100644 (file)
@@ -17,6 +17,17 @@ struct termios {
        cc_t c_cc[NCCS];                /* control characters */
 };
 
+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 */
+       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 */
index c68e1680da0173d5754d1a1df4944120a5239e58..71f8fe7832581b41a60014ba2895e1d9c5cfff10 100644 (file)
@@ -1 +1,3 @@
 include include/asm-generic/Kbuild.asm
+
+header-y += fixed_code.h
index 57f37ccdcdf1db421f25921c8db7bbdc34274671..c4d6cbbf96d490283df0a12fb6375f63f16a16b1 100644 (file)
@@ -67,6 +67,18 @@ extern void evt14_softirq(void);
 extern asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs);
 extern void bfin_gpio_interrupt_setup(int irq, int irq_pfx, int type);
 
+extern asmlinkage void finish_atomic_sections (struct pt_regs *regs);
+extern char fixed_code_start;
+extern char fixed_code_end;
+extern int atomic_xchg32(void);
+extern int atomic_cas32(void);
+extern int atomic_add32(void);
+extern int atomic_sub32(void);
+extern int atomic_ior32(void);
+extern int atomic_and32(void);
+extern int atomic_xor32(void);
+extern void sigreturn_stub(void);
+
 extern void *l1_data_A_sram_alloc(size_t);
 extern void *l1_data_B_sram_alloc(size_t);
 extern void *l1_inst_sram_alloc(size_t);
index 3bad2d1e6a8cd87da60bf12a0a4ef122d62714ea..bec6ecdf1bdbc5cd23a5421c28f194132fbaa9f6 100644 (file)
@@ -57,8 +57,8 @@ struct cplb_tab {
        u16 size;
 };
 
-u_long icplb_table[MAX_CPLBS+1];
-u_long dcplb_table[MAX_CPLBS+1];
+extern u_long icplb_table[MAX_CPLBS+1];
+extern u_long dcplb_table[MAX_CPLBS+1];
 
 /* Till here we are discussing about the static memory management model.
  * However, the operating envoronments commonly define more CPLB
@@ -70,134 +70,27 @@ u_long dcplb_table[MAX_CPLBS+1];
  */
 
 #ifdef CONFIG_CPLB_SWITCH_TAB_L1
-u_long ipdt_table[MAX_SWITCH_I_CPLBS+1]__attribute__((l1_data));
-u_long dpdt_table[MAX_SWITCH_D_CPLBS+1]__attribute__((l1_data));
+extern u_long ipdt_table[MAX_SWITCH_I_CPLBS+1]__attribute__((l1_data));
+extern u_long dpdt_table[MAX_SWITCH_D_CPLBS+1]__attribute__((l1_data));
 
 #ifdef CONFIG_CPLB_INFO
-u_long ipdt_swapcount_table[MAX_SWITCH_I_CPLBS]__attribute__((l1_data));
-u_long dpdt_swapcount_table[MAX_SWITCH_D_CPLBS]__attribute__((l1_data));
+extern u_long ipdt_swapcount_table[MAX_SWITCH_I_CPLBS]__attribute__((l1_data));
+extern u_long dpdt_swapcount_table[MAX_SWITCH_D_CPLBS]__attribute__((l1_data));
 #endif /* CONFIG_CPLB_INFO */
 
 #else
 
-u_long ipdt_table[MAX_SWITCH_I_CPLBS+1];
-u_long dpdt_table[MAX_SWITCH_D_CPLBS+1];
+extern u_long ipdt_table[MAX_SWITCH_I_CPLBS+1];
+extern u_long dpdt_table[MAX_SWITCH_D_CPLBS+1];
 
 #ifdef CONFIG_CPLB_INFO
-u_long ipdt_swapcount_table[MAX_SWITCH_I_CPLBS];
-u_long dpdt_swapcount_table[MAX_SWITCH_D_CPLBS];
+extern u_long ipdt_swapcount_table[MAX_SWITCH_I_CPLBS];
+extern u_long dpdt_swapcount_table[MAX_SWITCH_D_CPLBS];
 #endif /* CONFIG_CPLB_INFO */
 
 #endif /*CONFIG_CPLB_SWITCH_TAB_L1*/
 
-struct s_cplb {
-       struct cplb_tab init_i;
-       struct cplb_tab init_d;
-       struct cplb_tab switch_i;
-       struct cplb_tab switch_d;
-};
+extern unsigned long reserved_mem_dcache_on;
+extern unsigned long reserved_mem_icache_on;
 
-#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE)
-static struct cplb_desc cplb_data[] = {
-       {
-               .start = 0,
-               .end = SIZE_4K,
-               .psize = SIZE_4K,
-               .attr = INITIAL_T | SWITCH_T | I_CPLB | D_CPLB,
-               .i_conf = SDRAM_OOPS,
-               .d_conf = SDRAM_OOPS,
-#if defined(CONFIG_DEBUG_HUNT_FOR_ZERO)
-               .valid = 1,
-#else
-               .valid = 0,
-#endif
-               .name = "ZERO Pointer Saveguard",
-       },
-       {
-               .start = L1_CODE_START,
-               .end = L1_CODE_START + L1_CODE_LENGTH,
-               .psize = SIZE_4M,
-               .attr = INITIAL_T | SWITCH_T | I_CPLB,
-               .i_conf = L1_IMEMORY,
-               .d_conf = 0,
-               .valid = 1,
-               .name = "L1 I-Memory",
-       },
-       {
-               .start = L1_DATA_A_START,
-               .end = L1_DATA_B_START + L1_DATA_B_LENGTH,
-               .psize = SIZE_4M,
-               .attr = INITIAL_T | SWITCH_T | D_CPLB,
-               .i_conf = 0,
-               .d_conf = L1_DMEMORY,
-#if ((L1_DATA_A_LENGTH > 0) || (L1_DATA_B_LENGTH > 0))
-               .valid = 1,
-#else
-               .valid = 0,
-#endif
-               .name = "L1 D-Memory",
-       },
-       {
-               .start = 0,
-               .end = 0,  /* dynamic */
-               .psize = 0,
-               .attr = INITIAL_T | SWITCH_T | I_CPLB | D_CPLB,
-               .i_conf =  SDRAM_IGENERIC,
-               .d_conf =  SDRAM_DGENERIC,
-               .valid = 1,
-               .name = "SDRAM Kernel",
-       },
-       {
-               .start = 0, /* dynamic */
-               .end = 0, /* dynamic */
-               .psize = 0,
-               .attr = INITIAL_T | SWITCH_T | D_CPLB,
-               .i_conf =  SDRAM_IGENERIC,
-               .d_conf =  SDRAM_DNON_CHBL,
-               .valid = 1,
-               .name = "SDRAM RAM MTD",
-       },
-       {
-               .start = 0, /* dynamic */
-               .end = 0,   /* dynamic */
-               .psize = SIZE_1M,
-               .attr = INITIAL_T | SWITCH_T | D_CPLB,
-               .d_conf = SDRAM_DNON_CHBL,
-               .valid = 1,//(DMA_UNCACHED_REGION > 0),
-               .name = "SDRAM Uncached DMA ZONE",
-       },
-       {
-               .start = 0, /* dynamic */
-               .end = 0, /* dynamic */
-               .psize = 0,
-               .attr = SWITCH_T | D_CPLB,
-               .i_conf = 0, /* dynamic */
-               .d_conf = 0, /* dynamic */
-               .valid = 1,
-               .name = "SDRAM Reserved Memory",
-       },
-       {
-               .start = ASYNC_BANK0_BASE,
-               .end = ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE,
-               .psize = 0,
-               .attr = SWITCH_T | D_CPLB,
-               .d_conf = SDRAM_EBIU,
-               .valid = 1,
-               .name = "ASYNC Memory",
-       },
-       {
-#if defined(CONFIG_BF561)
-               .start = L2_SRAM,
-               .end = L2_SRAM_END,
-               .psize = SIZE_1M,
-               .attr = SWITCH_T | D_CPLB,
-               .i_conf = L2_MEMORY,
-               .d_conf = L2_MEMORY,
-               .valid = 1,
-#else
-               .valid = 0,
-#endif
-               .name = "L2 Memory",
-       }
-};
-#endif
+extern void generate_cpl_tables(void);
diff --git a/include/asm-blackfin/fixed_code.h b/include/asm-blackfin/fixed_code.h
new file mode 100644 (file)
index 0000000..e6df84e
--- /dev/null
@@ -0,0 +1,20 @@
+/* This file defines the fixed addresses where userspace programs can find
+   atomic code sequences.  */
+
+#define FIXED_CODE_START       0x400
+
+#define SIGRETURN_STUB         0x400
+
+#define ATOMIC_SEQS_START      0x410
+
+#define ATOMIC_XCHG32          0x410
+#define ATOMIC_CAS32           0x420
+#define ATOMIC_ADD32           0x430
+#define ATOMIC_SUB32           0x440
+#define ATOMIC_IOR32           0x450
+#define ATOMIC_AND32           0x460
+#define ATOMIC_XOR32           0x470
+
+#define ATOMIC_SEQS_END                0x480
+
+#define FIXED_CODE_END         0x480
index d98d77ad71f76ac48a1525eeb1f9c668cbb7d6eb..7480cfa7e2d64304c58ff924b05fbfc385ad8bf6 100644 (file)
 
 #endif
 
+#ifdef BF548_FAMILY
+#include <asm-blackfin/mach-bf548/gpio.h>
+#endif
+
 #ifdef BF561_FAMILY
 #define MAX_BLACKFIN_GPIOS 48
+
+#define        GPIO_PF0        0
+#define        GPIO_PF1        1
+#define        GPIO_PF2        2
+#define        GPIO_PF3        3
+#define        GPIO_PF4        4
+#define        GPIO_PF5        5
+#define        GPIO_PF6        6
+#define        GPIO_PF7        7
+#define        GPIO_PF8        8
+#define        GPIO_PF9        9
+#define        GPIO_PF10       10
+#define        GPIO_PF11       11
+#define        GPIO_PF12       12
+#define        GPIO_PF13       13
+#define        GPIO_PF14       14
+#define        GPIO_PF15       15
+#define        GPIO_PF16       16
+#define        GPIO_PF17       17
+#define        GPIO_PF18       18
+#define        GPIO_PF19       19
+#define        GPIO_PF20       20
+#define        GPIO_PF21       21
+#define        GPIO_PF22       22
+#define        GPIO_PF23       23
+#define        GPIO_PF24       24
+#define        GPIO_PF25       25
+#define        GPIO_PF26       26
+#define        GPIO_PF27       27
+#define        GPIO_PF28       28
+#define        GPIO_PF29       29
+#define        GPIO_PF30       30
+#define        GPIO_PF31       31
+#define        GPIO_PF32       32
+#define        GPIO_PF33       33
+#define        GPIO_PF34       34
+#define        GPIO_PF35       35
+#define        GPIO_PF36       36
+#define        GPIO_PF37       37
+#define        GPIO_PF38       38
+#define        GPIO_PF39       39
+#define        GPIO_PF40       40
+#define        GPIO_PF41       41
+#define        GPIO_PF42       42
+#define        GPIO_PF43       43
+#define        GPIO_PF44       44
+#define        GPIO_PF45       45
+#define        GPIO_PF46       46
+#define        GPIO_PF47       47
+
 #define PORT_FIO0 GPIO_0
 #define PORT_FIO1 GPIO_16
 #define PORT_FIO2 GPIO_32
 * MODIFICATION HISTORY :
 **************************************************************/
 
+#ifndef BF548_FAMILY
 void set_gpio_dir(unsigned short, unsigned short);
 void set_gpio_inen(unsigned short, unsigned short);
 void set_gpio_polar(unsigned short, unsigned short);
@@ -299,6 +354,7 @@ struct gpio_port_t {
        unsigned short dummy16;
        unsigned short inen;
 };
+#endif
 
 #ifdef CONFIG_PM
 #define PM_WAKE_RISING 0x1
@@ -357,8 +413,10 @@ void gpio_free(unsigned short);
 void gpio_set_value(unsigned short gpio, unsigned short arg);
 unsigned short gpio_get_value(unsigned short gpio);
 
+#ifndef BF548_FAMILY
 #define gpio_get_value(gpio)           get_gpio_data(gpio)
 #define gpio_set_value(gpio, value)    set_gpio_data(gpio, value)
+#endif
 
 void gpio_direction_input(unsigned short gpio);
 void gpio_direction_output(unsigned short gpio);
index 0cab0d35badc42a7622ae816a058814097114b8e..b6b19f1b9dab56dc1aad604208ba960eea8567f0 100644 (file)
@@ -28,7 +28,11 @@ typedef struct {
  * SOFTIRQ_MASK: 0x00ff0000
  */
 
+#if NR_IRQS > 256
+#define HARDIRQ_BITS   9
+#else
 #define HARDIRQ_BITS   8
+#endif
 
 #ifdef NR_IRQS
 # if (1 << HARDIRQ_BITS) < NR_IRQS
diff --git a/include/asm-blackfin/kgdb.h b/include/asm-blackfin/kgdb.h
new file mode 100644 (file)
index 0000000..532bd90
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * File:         include/asm-blackfin/kgdb.h
+ * Based on:
+ * Author:       Sonic Zhang
+ *
+ * Created:
+ * Description:
+ *
+ * Rev:          $Id: kgdb_bfin_linux-2.6.x.patch 4934 2007-02-13 09:32:11Z sonicz $
+ *
+ * Modified:
+ *               Copyright 2005-2006 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef __ASM_BLACKFIN_KGDB_H__
+#define __ASM_BLACKFIN_KGDB_H__
+
+#include <linux/ptrace.h>
+
+/* gdb locks */
+#define KGDB_MAX_NO_CPUS 8
+
+/************************************************************************/
+/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
+/* at least NUMREGBYTES*2 are needed for register packets */
+/* Longer buffer is needed to list all threads */
+#define BUFMAX 2048
+
+/*
+ *  Note that this register image is different from
+ *  the register image that Linux produces at interrupt time.
+ *  
+ *  Linux's register image is defined by struct pt_regs in ptrace.h.
+ */
+enum regnames {
+  /* Core Registers */
+  BFIN_R0 = 0,
+  BFIN_R1,
+  BFIN_R2,
+  BFIN_R3,
+  BFIN_R4,
+  BFIN_R5,
+  BFIN_R6,
+  BFIN_R7,
+  BFIN_P0,
+  BFIN_P1,
+  BFIN_P2,
+  BFIN_P3,
+  BFIN_P4,
+  BFIN_P5,
+  BFIN_SP,
+  BFIN_FP,
+  BFIN_I0,
+  BFIN_I1,
+  BFIN_I2,
+  BFIN_I3,
+  BFIN_M0,
+  BFIN_M1,
+  BFIN_M2,
+  BFIN_M3,
+  BFIN_B0,
+  BFIN_B1,
+  BFIN_B2,
+  BFIN_B3,
+  BFIN_L0,
+  BFIN_L1,
+  BFIN_L2,
+  BFIN_L3,
+  BFIN_A0_DOT_X,
+  BFIN_A0_DOT_W,
+  BFIN_A1_DOT_X,
+  BFIN_A1_DOT_W,
+  BFIN_ASTAT,
+  BFIN_RETS,
+  BFIN_LC0,
+  BFIN_LT0,
+  BFIN_LB0,
+  BFIN_LC1,
+  BFIN_LT1,
+  BFIN_LB1,
+  BFIN_CYCLES,
+  BFIN_CYCLES2,
+  BFIN_USP,
+  BFIN_SEQSTAT,
+  BFIN_SYSCFG,
+  BFIN_RETI,
+  BFIN_RETX,
+  BFIN_RETN,
+  BFIN_RETE,
+  
+  /* Pseudo Registers */
+  BFIN_PC,
+  BFIN_CC,
+  BFIN_EXTRA1,         /* Address of .text section.  */
+  BFIN_EXTRA2,         /* Address of .data section.  */
+  BFIN_EXTRA3,         /* Address of .bss section.  */
+  BFIN_FDPIC_EXEC, 
+  BFIN_FDPIC_INTERP,
+
+  /* MMRs */
+  BFIN_IPEND,
+
+  /* LAST ENTRY SHOULD NOT BE CHANGED.  */
+  BFIN_NUM_REGS                /* The number of all registers.  */
+};
+
+/* Number of bytes of registers.  */
+#define NUMREGBYTES BFIN_NUM_REGS*4
+
+#define BREAKPOINT() asm("   EXCPT 2;");
+#define BREAK_INSTR_SIZE       2
+#define HW_BREAKPOINT_NUM              6
+
+/* Instruction watchpoint address control register bits mask */
+#define WPPWR          0x1
+#define WPIREN01       0x2
+#define WPIRINV01      0x4
+#define WPIAEN0                0x8
+#define WPIAEN1                0x10
+#define WPICNTEN0      0x20
+#define WPICNTEN1      0x40
+#define EMUSW0         0x80
+#define EMUSW1         0x100
+#define WPIREN23       0x200
+#define WPIRINV23      0x400
+#define WPIAEN2                0x800
+#define WPIAEN3                0x1000
+#define WPICNTEN2      0x2000
+#define WPICNTEN3      0x4000
+#define EMUSW2         0x8000
+#define EMUSW3         0x10000
+#define WPIREN45       0x20000
+#define WPIRINV45      0x40000
+#define WPIAEN4                0x80000
+#define WPIAEN5                0x100000
+#define WPICNTEN4      0x200000
+#define WPICNTEN5      0x400000
+#define EMUSW4         0x800000
+#define EMUSW5         0x1000000
+#define WPAND          0x2000000
+
+/* Data watchpoint address control register bits mask */
+#define WPDREN01       0x1
+#define WPDRINV01      0x2
+#define WPDAEN0                0x4
+#define WPDAEN1                0x8
+#define WPDCNTEN0      0x10
+#define WPDCNTEN1      0x20
+#define WPDSRC0                0xc0
+#define WPDACC0                0x300
+#define WPDSRC1                0xc00
+#define WPDACC1                0x3000
+
+/* Watchpoint status register bits mask */
+#define STATIA0                0x1
+#define STATIA1                0x2
+#define STATIA2                0x4
+#define STATIA3                0x8
+#define STATIA4                0x10
+#define STATIA5                0x20
+#define STATDA0                0x40
+#define STATDA1                0x80
+
+extern void kgdb_print(const char *fmt, ...);
+
+#endif
index bd9d5e94307d0ca7823ff50c88bf19d0f74c94f0..16c672c01d80cb490d2dc0fceff35ed6d67947f7 100644 (file)
@@ -51,4 +51,7 @@
 #define CH_MEM_STREAM1_DEST     10      /* TX */
 #define CH_MEM_STREAM1_SRC      11      /* RX */
 
+extern int channel2irq(unsigned int channel);
+extern struct dma_register *base_addr[];
+
 #endif
diff --git a/include/asm-blackfin/mach-bf533/portmux.h b/include/asm-blackfin/mach-bf533/portmux.h
new file mode 100644 (file)
index 0000000..b88d7a0
--- /dev/null
@@ -0,0 +1,65 @@
+#ifndef _MACH_PORTMUX_H_
+#define _MACH_PORTMUX_H_
+
+#define P_PPI0_CLK     (P_DONTCARE)
+#define P_PPI0_FS1     (P_DONTCARE)
+#define P_PPI0_FS2     (P_DONTCARE)
+#define P_PPI0_FS3     (P_DEFINED | P_IDENT(GPIO_PF3))
+#define P_PPI0_D15     (P_DEFINED | P_IDENT(GPIO_PF4))
+#define P_PPI0_D14     (P_DEFINED | P_IDENT(GPIO_PF5))
+#define P_PPI0_D13     (P_DEFINED | P_IDENT(GPIO_PF6))
+#define P_PPI0_D12     (P_DEFINED | P_IDENT(GPIO_PF7))
+#define P_PPI0_D11     (P_DEFINED | P_IDENT(GPIO_PF8))
+#define P_PPI0_D10     (P_DEFINED | P_IDENT(GPIO_PF9))
+#define P_PPI0_D9      (P_DEFINED | P_IDENT(GPIO_PF10))
+#define P_PPI0_D8      (P_DEFINED | P_IDENT(GPIO_PF11))
+#define P_PPI0_D0      (P_DONTCARE)
+#define P_PPI0_D1      (P_DONTCARE)
+#define P_PPI0_D2      (P_DONTCARE)
+#define P_PPI0_D3      (P_DONTCARE)
+#define P_PPI0_D4      (P_DEFINED | P_IDENT(GPIO_PF15))
+#define P_PPI0_D5      (P_DEFINED | P_IDENT(GPIO_PF14))
+#define P_PPI0_D6      (P_DEFINED | P_IDENT(GPIO_PF13))
+#define P_PPI0_D7      (P_DEFINED | P_IDENT(GPIO_PF12))
+
+#define P_SPORT1_TSCLK (P_DONTCARE)
+#define P_SPORT1_RSCLK (P_DONTCARE)
+#define P_SPORT0_TSCLK (P_DONTCARE)
+#define P_SPORT0_RSCLK (P_DONTCARE)
+#define P_UART0_RX     (P_DONTCARE)
+#define P_UART0_TX     (P_DONTCARE)
+#define P_SPORT1_DRSEC (P_DONTCARE)
+#define P_SPORT1_RFS   (P_DONTCARE)
+#define P_SPORT1_DTPRI (P_DONTCARE)
+#define P_SPORT1_DTSEC (P_DONTCARE)
+#define P_SPORT1_TFS   (P_DONTCARE)
+#define P_SPORT1_DRPRI (P_DONTCARE)
+#define P_SPORT0_DRSEC (P_DONTCARE)
+#define P_SPORT0_RFS   (P_DONTCARE)
+#define P_SPORT0_DTPRI (P_DONTCARE)
+#define P_SPORT0_DTSEC (P_DONTCARE)
+#define P_SPORT0_TFS   (P_DONTCARE)
+#define P_SPORT0_DRPRI (P_DONTCARE)
+
+#define P_SPI0_MOSI    (P_DONTCARE)
+#define P_SPI0_MIS0    (P_DONTCARE)
+#define P_SPI0_SCK     (P_DONTCARE)
+#define P_SPI0_SSEL7   (P_DEFINED | P_IDENT(GPIO_PF7))
+#define P_SPI0_SSEL6   (P_DEFINED | P_IDENT(GPIO_PF6))
+#define P_SPI0_SSEL5   (P_DEFINED | P_IDENT(GPIO_PF5))
+#define P_SPI0_SSEL4   (P_DEFINED | P_IDENT(GPIO_PF4))
+#define P_SPI0_SSEL3   (P_DEFINED | P_IDENT(GPIO_PF3))
+#define P_SPI0_SSEL2   (P_DEFINED | P_IDENT(GPIO_PF2))
+#define P_SPI0_SSEL1   (P_DEFINED | P_IDENT(GPIO_PF1))
+#define P_SPI0_SS      (P_DEFINED | P_IDENT(GPIO_PF0))
+
+#define P_TMR2         (P_DONTCARE)
+#define P_TMR1         (P_DONTCARE)
+#define P_TMR0         (P_DONTCARE)
+#define P_TMRCLK       (P_DEFINED | P_IDENT(GPIO_PF1))
+
+
+
+
+
+#endif /* _MACH_PORTMUX_H_ */
index 7a964040870a047292f84678c3788dc2c2bff07f..021991984e6e7ce4f5ae7adc197396d954bf83ca 100644 (file)
@@ -52,4 +52,7 @@
 #define CH_MEM_STREAM1_DEST    14       /* TX */
 #define CH_MEM_STREAM1_SRC     15       /* RX */
 
+extern int channel2irq(unsigned int channel);
+extern struct dma_register *base_addr[];
+
 #endif
diff --git a/include/asm-blackfin/mach-bf537/portmux.h b/include/asm-blackfin/mach-bf537/portmux.h
new file mode 100644 (file)
index 0000000..23e13c5
--- /dev/null
@@ -0,0 +1,109 @@
+#ifndef _MACH_PORTMUX_H_
+#define _MACH_PORTMUX_H_
+
+#define P_UART0_TX     (P_DEFINED | P_IDENT(GPIO_PF0) | P_FUNCT(0))
+#define P_UART0_RX     (P_DEFINED | P_IDENT(GPIO_PF1) | P_FUNCT(0))
+#define P_UART1_TX     (P_DEFINED | P_IDENT(GPIO_PF2) | P_FUNCT(0))
+#define P_UART1_RX     (P_DEFINED | P_IDENT(GPIO_PF3) | P_FUNCT(0))
+#define P_TMR5         (P_DEFINED | P_IDENT(GPIO_PF4) | P_FUNCT(0))
+#define P_TMR4         (P_DEFINED | P_IDENT(GPIO_PF5) | P_FUNCT(0))
+#define P_TMR3         (P_DEFINED | P_IDENT(GPIO_PF6) | P_FUNCT(0))
+#define P_TMR2         (P_DEFINED | P_IDENT(GPIO_PF7) | P_FUNCT(0))
+#define P_TMR1         (P_DEFINED | P_IDENT(GPIO_PF8) | P_FUNCT(0))
+#define P_TMR0         (P_DEFINED | P_IDENT(GPIO_PF9) | P_FUNCT(0))
+#define P_SPI0_SSEL1   (P_DEFINED | P_IDENT(GPIO_PF10) | P_FUNCT(0))
+#define P_SPI0_MOSI    (P_DEFINED | P_IDENT(GPIO_PF11) | P_FUNCT(0))
+#define P_SPI0_MISO    (P_DEFINED | P_IDENT(GPIO_PF12) | P_FUNCT(0))
+#define P_SPI0_SCK     (P_DEFINED | P_IDENT(GPIO_PF13) | P_FUNCT(0))
+#define P_SPI0_SS      (P_DEFINED | P_IDENT(GPIO_PF14) | P_FUNCT(0))
+#define P_PPI0_CLK     (P_DEFINED | P_IDENT(GPIO_PF15) | P_FUNCT(0))
+#define P_DMAR0                (P_DEFINED | P_IDENT(GPIO_PF0) | P_FUNCT(1))
+#define P_DMAR1                (P_DEFINED | P_IDENT(GPIO_PF1) | P_FUNCT(1))
+#define P_TMR7         (P_DEFINED | P_IDENT(GPIO_PF2) | P_FUNCT(1))
+#define P_TMR6         (P_DEFINED | P_IDENT(GPIO_PF3) | P_FUNCT(1))
+#define P_SPI0_SSEL6   (P_DEFINED | P_IDENT(GPIO_PF4) | P_FUNCT(1))
+#define P_SPI0_SSEL5   (P_DEFINED | P_IDENT(GPIO_PF5) | P_FUNCT(1))
+#define P_SPI0_SSEL4   (P_DEFINED | P_IDENT(GPIO_PF6) | P_FUNCT(1))
+#define P_PPI0_FS3     (P_DEFINED | P_IDENT(GPIO_PF7) | P_FUNCT(1))
+#define P_PPI0_FS2     (P_DEFINED | P_IDENT(GPIO_PF8) | P_FUNCT(1))
+#define P_PPI0_FS1     (P_DEFINED | P_IDENT(GPIO_PF9) | P_FUNCT(1))
+#define P_TACLK0       (P_DEFINED | P_IDENT(GPIO_PF14) | P_FUNCT(1))
+#define P_TMRCLK       (P_DEFINED | P_IDENT(GPIO_PF15) | P_FUNCT(1))
+
+#define P_PPI0_D0      (P_DEFINED | P_IDENT(GPIO_PG0) | P_FUNCT(0))
+#define P_PPI0_D1      (P_DEFINED | P_IDENT(GPIO_PG1) | P_FUNCT(0))
+#define P_PPI0_D2      (P_DEFINED | P_IDENT(GPIO_PG2) | P_FUNCT(0))
+#define P_PPI0_D3      (P_DEFINED | P_IDENT(GPIO_PG3) | P_FUNCT(0))
+#define P_PPI0_D4      (P_DEFINED | P_IDENT(GPIO_PG4) | P_FUNCT(0))
+#define P_PPI0_D5      (P_DEFINED | P_IDENT(GPIO_PG5) | P_FUNCT(0))
+#define P_PPI0_D6      (P_DEFINED | P_IDENT(GPIO_PG6) | P_FUNCT(0))
+#define P_PPI0_D7      (P_DEFINED | P_IDENT(GPIO_PG7) | P_FUNCT(0))
+#define P_PPI0_D8      (P_DEFINED | P_IDENT(GPIO_PG8) | P_FUNCT(0))
+#define P_PPI0_D9      (P_DEFINED | P_IDENT(GPIO_PG9) | P_FUNCT(0))
+#define P_PPI0_D10     (P_DEFINED | P_IDENT(GPIO_PG10) | P_FUNCT(0))
+#define P_PPI0_D11     (P_DEFINED | P_IDENT(GPIO_PG11) | P_FUNCT(0))
+#define P_PPI0_D12     (P_DEFINED | P_IDENT(GPIO_PG12) | P_FUNCT(0))
+#define P_PPI0_D13     (P_DEFINED | P_IDENT(GPIO_PG13) | P_FUNCT(0))
+#define P_PPI0_D14     (P_DEFINED | P_IDENT(GPIO_PG14) | P_FUNCT(0))
+#define P_PPI0_D15     (P_DEFINED | P_IDENT(GPIO_PG15) | P_FUNCT(0))
+#define P_SPORT1_DRSEC (P_DEFINED | P_IDENT(GPIO_PG8) | P_FUNCT(1))
+#define P_SPORT1_DTSEC (P_DEFINED | P_IDENT(GPIO_PG9) | P_FUNCT(1))
+#define P_SPORT1_RSCLK (P_DEFINED | P_IDENT(GPIO_PG10) | P_FUNCT(1))
+#define P_SPORT1_RFS   (P_DEFINED | P_IDENT(GPIO_PG11) | P_FUNCT(1))
+#define P_SPORT1_DRPRI (P_DEFINED | P_IDENT(GPIO_PG12) | P_FUNCT(1))
+#define P_SPORT1_TSCLK (P_DEFINED | P_IDENT(GPIO_PG13) | P_FUNCT(1))
+#define P_SPORT1_TFS   (P_DEFINED | P_IDENT(GPIO_PG14) | P_FUNCT(1))
+#define P_SPORT1_DTPRI (P_DEFINED | P_IDENT(GPIO_PG15) | P_FUNCT(1))
+
+#define P_MII0_ETxD0   (P_DEFINED | P_IDENT(GPIO_PH0) | P_FUNCT(0))
+#define P_MII0_ETxD1   (P_DEFINED | P_IDENT(GPIO_PH1) | P_FUNCT(0))
+#define P_MII0_ETxD2   (P_DEFINED | P_IDENT(GPIO_PH2) | P_FUNCT(0))
+#define P_MII0_ETxD3   (P_DEFINED | P_IDENT(GPIO_PH3) | P_FUNCT(0))
+#define P_MII0_ETxEN   (P_DEFINED | P_IDENT(GPIO_PH4) | P_FUNCT(0))
+#define P_MII0_TxCLK   (P_DEFINED | P_IDENT(GPIO_PH5) | P_FUNCT(0))
+#define P_MII0_PHYINT  (P_DEFINED | P_IDENT(GPIO_PH6) | P_FUNCT(0))
+#define P_MII0_COL     (P_DEFINED | P_IDENT(GPIO_PH7) | P_FUNCT(0))
+#define P_MII0_ERxD0   (P_DEFINED | P_IDENT(GPIO_PH8) | P_FUNCT(0))
+#define P_MII0_ERxD1   (P_DEFINED | P_IDENT(GPIO_PH9) | P_FUNCT(0))
+#define P_MII0_ERxD2   (P_DEFINED | P_IDENT(GPIO_PH10) | P_FUNCT(0))
+#define P_MII0_ERxD3   (P_DEFINED | P_IDENT(GPIO_PH11) | P_FUNCT(0))
+#define P_MII0_ERxDV   (P_DEFINED | P_IDENT(GPIO_PH12) | P_FUNCT(0))
+#define P_MII0_ERxCLK  (P_DEFINED | P_IDENT(GPIO_PH13) | P_FUNCT(0))
+#define P_MII0_ERxER   (P_DEFINED | P_IDENT(GPIO_PH14) | P_FUNCT(0))
+#define P_MII0_CRS     (P_DEFINED | P_IDENT(GPIO_PH15) | P_FUNCT(0))
+#define P_RMII0_REF_CLK        (P_DEFINED | P_IDENT(GPIO_PH5) | P_FUNCT(1))
+#define P_RMII0_MDINT  (P_DEFINED | P_IDENT(GPIO_PH6) | P_FUNCT(1))
+#define P_RMII0_CRS_DV (P_DEFINED | P_IDENT(GPIO_PH15) | P_FUNCT(1))
+
+#define PORT_PJ0       (GPIO_PH15 + 1)
+#define PORT_PJ1       (GPIO_PH15 + 2)
+#define PORT_PJ2       (GPIO_PH15 + 3)
+#define PORT_PJ3       (GPIO_PH15 + 4)
+#define PORT_PJ4       (GPIO_PH15 + 5)
+#define PORT_PJ5       (GPIO_PH15 + 6)
+#define PORT_PJ6       (GPIO_PH15 + 7)
+#define PORT_PJ7       (GPIO_PH15 + 8)
+#define PORT_PJ8       (GPIO_PH15 + 9)
+#define PORT_PJ9       (GPIO_PH15 + 10)
+#define PORT_PJ10      (GPIO_PH15 + 11)
+#define PORT_PJ11      (GPIO_PH15 + 12)
+
+#define P_MDC          (P_DEFINED | P_IDENT(PORT_PJ0) | P_FUNCT(0))
+#define P_MDIO         (P_DEFINED | P_IDENT(PORT_PJ1) | P_FUNCT(0))
+#define P_TWI0_SCL     (P_DEFINED | P_IDENT(PORT_PJ2) | P_FUNCT(0))
+#define P_TWI0_SDA     (P_DEFINED | P_IDENT(PORT_PJ3) | P_FUNCT(0))
+#define P_SPORT0_DRSEC (P_DEFINED | P_IDENT(PORT_PJ4) | P_FUNCT(0))
+#define P_SPORT0_DTSEC (P_DEFINED | P_IDENT(PORT_PJ5) | P_FUNCT(0))
+#define P_SPORT0_RSCLK (P_DEFINED | P_IDENT(PORT_PJ6) | P_FUNCT(0))
+#define P_SPORT0_RFS   (P_DEFINED | P_IDENT(PORT_PJ7) | P_FUNCT(0))
+#define P_SPORT0_DRPRI (P_DEFINED | P_IDENT(PORT_PJ8) | P_FUNCT(0))
+#define P_SPORT0_TSCLK (P_DEFINED | P_IDENT(PORT_PJ9) | P_FUNCT(0))
+#define P_SPORT0_TFS   (P_DEFINED | P_IDENT(PORT_PJ10) | P_FUNCT(0))
+#define P_SPORT0_DTPRI (P_DEFINED | P_IDENT(PORT_PJ11) | P_FUNCT(1))
+#define P_CAN0_RX      (P_DEFINED | P_IDENT(PORT_PJ4) | P_FUNCT(1))
+#define P_CAN0_TX      (P_DEFINED | P_IDENT(PORT_PJ5) | P_FUNCT(1))
+#define P_SPI0_SSEL3   (P_DEFINED | P_IDENT(PORT_PJ10) | P_FUNCT(1))
+#define P_SPI0_SSEL2   (P_DEFINED | P_IDENT(PORT_PJ11) | P_FUNCT(1))
+#define P_SPI0_SSEL7   (P_DEFINED | P_IDENT(PORT_PJ5) | P_FUNCT(2))
+
+#endif /* _MACH_PORTMUX_H_ */
diff --git a/include/asm-blackfin/mach-bf548/anomaly.h b/include/asm-blackfin/mach-bf548/anomaly.h
new file mode 100644 (file)
index 0000000..aca1d4b
--- /dev/null
@@ -0,0 +1,74 @@
+
+/*
+ * File:         include/asm-blackfin/mach-bf548/anomaly.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Rev:
+ *
+ * Modified:
+ *
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _MACH_ANOMALY_H_
+#define _MACH_ANOMALY_H_
+#define ANOMALY_05000074 /* A multi issue instruction with dsp32shiftimm in
+                           slot1 and store of a P register in slot 2 is not
+                           supported */
+#define ANOMALY_05000119 /* DMA_RUN bit is not valid after a Peripheral Receive
+                           Channel DMA stops */
+#define ANOMALY_05000122 /* Rx.H can not be used to access 16-bit System MMR
+                           registers. */
+#define ANOMALY_05000245 /* Spurious Hardware Error from an Access in the
+                           Shadow of a Conditional Branch */
+#define ANOMALY_05000255 /* Entering Hibernate Mode with RTC Seconds event
+                           interrupt not functional */
+#define ANOMALY_05000265 /* Sensitivity to noise with slow input edge rates on
+                           SPORT external receive and transmit clocks. */
+#define ANOMALY_05000272 /* Certain data cache write through modes fail for
+                           VDDint <=0.9V */
+#define ANOMALY_05000281 /* False Hardware Error Exception when ISR context is
+                           not restored */
+#define ANOMALY_05000310 /* False Hardware Errors Caused by Fetches at the
+                           Boundary of Reserved Memory */
+#define ANOMALY_05000312 /* Errors When SSYNC, CSYNC, or Loads to LT, LB and
+                           LC Registers Are Interrupted */
+#define ANOMALY_05000324 /* TWI Slave Boot Mode Is Not Functional */
+#define ANOMALY_05000325 /* External FIFO Boot Mode Is Not Functional */
+#define ANOMALY_05000327 /* Data Lost When Core and DMA Accesses Are Made to
+                           the USB FIFO Simultaneously */
+#define ANOMALY_05000328 /* Incorrect Access of OTP_STATUS During otp_write()
+                           function */
+#define ANOMALY_05000329 /* Synchronous Burst Flash Boot Mode Is Not Functional
+                           */
+#define ANOMALY_05000330 /* Host DMA Boot Mode Is Not Functional */
+#define ANOMALY_05000334 /* Inadequate Timing Margins on DDR DQS to DQ and DQM
+                           Skew */
+#define ANOMALY_05000335 /* Inadequate Rotary Debounce Logic Duration */
+#define ANOMALY_05000336 /* Phantom Interrupt Occurs After First Configuration
+                           of Host DMA Port */
+#define ANOMALY_05000337 /* Disallowed Configuration Prevents Subsequent
+                           Allowed Configuration on Host DMA Port */
+#define ANOMALY_05000338 /* Slave-Mode SPI0 MISO Failure With CPHA = 0 */
+
+#endif /* _MACH_ANOMALY_H_ */
diff --git a/include/asm-blackfin/mach-bf548/bf548.h b/include/asm-blackfin/mach-bf548/bf548.h
new file mode 100644 (file)
index 0000000..9498313
--- /dev/null
@@ -0,0 +1,271 @@
+/*
+ * File:         include/asm-blackfin/mach-bf548/bf548.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:  System MMR register and memory map for ADSP-BF548
+ *
+ * Modified:
+ *               Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef __MACH_BF548_H__
+#define __MACH_BF548_H__
+
+#define SUPPORTED_REVID 0
+
+#define OFFSET_(x) ((x) & 0x0000FFFF)
+
+/*some misc defines*/
+#define IMASK_IVG15            0x8000
+#define IMASK_IVG14            0x4000
+#define IMASK_IVG13            0x2000
+#define IMASK_IVG12            0x1000
+
+#define IMASK_IVG11            0x0800
+#define IMASK_IVG10            0x0400
+#define IMASK_IVG9             0x0200
+#define IMASK_IVG8             0x0100
+
+#define IMASK_IVG7             0x0080
+#define IMASK_IVGTMR   0x0040
+#define IMASK_IVGHW            0x0020
+
+/***************************/
+
+
+#define BLKFIN_DSUBBANKS       4
+#define BLKFIN_DWAYS           2
+#define BLKFIN_DLINES          64
+#define BLKFIN_ISUBBANKS       4
+#define BLKFIN_IWAYS           4
+#define BLKFIN_ILINES          32
+
+#define WAY0_L                 0x1
+#define WAY1_L                 0x2
+#define WAY01_L                        0x3
+#define WAY2_L                 0x4
+#define WAY02_L                        0x5
+#define        WAY12_L                 0x6
+#define        WAY012_L                0x7
+
+#define        WAY3_L                  0x8
+#define        WAY03_L                 0x9
+#define        WAY13_L                 0xA
+#define        WAY013_L                0xB
+
+#define        WAY32_L                 0xC
+#define        WAY320_L                0xD
+#define        WAY321_L                0xE
+#define        WAYALL_L                0xF
+
+#define DMC_ENABLE (2<<2)      /*yes, 2, not 1 */
+
+/********************************* EBIU Settings ************************************/
+#define AMBCTL0VAL     ((CONFIG_BANK_1 << 16) | CONFIG_BANK_0)
+#define AMBCTL1VAL     ((CONFIG_BANK_3 << 16) | CONFIG_BANK_2)
+
+#ifdef CONFIG_C_AMBEN_ALL
+#define V_AMBEN AMBEN_ALL
+#endif
+#ifdef CONFIG_C_AMBEN
+#define V_AMBEN 0x0
+#endif
+#ifdef CONFIG_C_AMBEN_B0
+#define V_AMBEN AMBEN_B0
+#endif
+#ifdef CONFIG_C_AMBEN_B0_B1
+#define V_AMBEN AMBEN_B0_B1
+#endif
+#ifdef CONFIG_C_AMBEN_B0_B1_B2
+#define V_AMBEN AMBEN_B0_B1_B2
+#endif
+#ifdef CONFIG_C_AMCKEN
+#define V_AMCKEN AMCKEN
+#else
+#define V_AMCKEN 0x0
+#endif
+
+#define AMGCTLVAL      (V_AMBEN | V_AMCKEN)
+
+#define MAX_VC 650000000
+#define MIN_VC 50000000
+
+/********************************PLL Settings **************************************/
+#ifdef CONFIG_BFIN_KERNEL_CLOCK
+#if (CONFIG_VCO_MULT < 0)
+#error "VCO Multiplier is less than 0. Please select a different value"
+#endif
+
+#if (CONFIG_VCO_MULT == 0)
+#error "VCO Multiplier should be greater than 0. Please select a different value"
+#endif
+
+#if (CONFIG_VCO_MULT > 64)
+#error "VCO Multiplier is more than 64. Please select a different value"
+#endif
+
+#ifndef CONFIG_CLKIN_HALF
+#define CONFIG_VCO_HZ  (CONFIG_CLKIN_HZ * CONFIG_VCO_MULT)
+#else
+#define CONFIG_VCO_HZ  ((CONFIG_CLKIN_HZ * CONFIG_VCO_MULT)/2)
+#endif
+
+#ifndef CONFIG_PLL_BYPASS
+#define CONFIG_CCLK_HZ (CONFIG_VCO_HZ/CONFIG_CCLK_DIV)
+#define CONFIG_SCLK_HZ (CONFIG_VCO_HZ/CONFIG_SCLK_DIV)
+#else
+#define CONFIG_CCLK_HZ CONFIG_CLKIN_HZ
+#define CONFIG_SCLK_HZ CONFIG_CLKIN_HZ
+#endif
+
+#if (CONFIG_SCLK_DIV < 1)
+#error "SCLK DIV cannot be less than 1 or more than 15. Please select a proper value"
+#endif
+
+#if (CONFIG_SCLK_DIV > 15)
+#error "SCLK DIV cannot be less than 1 or more than 15. Please select a proper value"
+#endif
+
+#if (CONFIG_CCLK_DIV != 1)
+#if (CONFIG_CCLK_DIV != 2)
+#if (CONFIG_CCLK_DIV != 4)
+#if (CONFIG_CCLK_DIV != 8)
+#error "CCLK DIV can be 1,2,4 or 8 only. Please select a proper value"
+#endif
+#endif
+#endif
+#endif
+
+#if (CONFIG_VCO_HZ > MAX_VC)
+#error "VCO selected is more than maximum value. Please change the VCO multipler"
+#endif
+
+#if (CONFIG_SCLK_HZ > 133000000)
+#error "Sclk value selected is more than maximum. Please select a proper value for SCLK multiplier"
+#endif
+
+#if (CONFIG_SCLK_HZ < 27000000)
+#error "Sclk value selected is less than minimum. Please select a proper value for SCLK multiplier"
+#endif
+
+#if (CONFIG_SCLK_HZ >= CONFIG_CCLK_HZ)
+#if (CONFIG_SCLK_HZ != CONFIG_CLKIN_HZ)
+#if (CONFIG_CCLK_HZ != CONFIG_CLKIN_HZ)
+#error "Please select sclk less than cclk"
+#endif
+#endif
+#endif
+
+#if (CONFIG_CCLK_DIV == 1)
+#define CONFIG_CCLK_ACT_DIV   CCLK_DIV1
+#endif
+#if (CONFIG_CCLK_DIV == 2)
+#define CONFIG_CCLK_ACT_DIV   CCLK_DIV2
+#endif
+#if (CONFIG_CCLK_DIV == 4)
+#define CONFIG_CCLK_ACT_DIV   CCLK_DIV4
+#endif
+#if (CONFIG_CCLK_DIV == 8)
+#define CONFIG_CCLK_ACT_DIV   CCLK_DIV8
+#endif
+#ifndef CONFIG_CCLK_ACT_DIV
+#define CONFIG_CCLK_ACT_DIV   CONFIG_CCLK_DIV_not_defined_properly
+#endif
+
+#endif /* CONFIG_BFIN_KERNEL_CLOCK */
+
+#ifdef CONFIG_BF542
+#define CPU "BF542"
+#define CPUID 0x027c8000
+#endif
+#ifdef CONFIG_BF544
+#define CPU "BF544"
+#define CPUID 0x027c8000
+#endif
+#ifdef CONFIG_BF548
+#define CPU "BF548"
+#define CPUID 0x027c6000
+#endif
+#ifdef CONFIG_BF549
+#define CPU "BF549"
+#endif
+#ifndef CPU
+#define        CPU "UNKNOWN"
+#define CPUID 0x0
+#endif
+
+#if (CONFIG_MEM_SIZE % 4)
+#error "SDRAM mem size must be multible of 4MB"
+#endif
+
+#define SDRAM_IGENERIC    (CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID | CPLB_PORTPRIO)
+#define SDRAM_IKERNEL     (SDRAM_IGENERIC | CPLB_LOCK)
+#define L1_IMEMORY        (               CPLB_USER_RD | CPLB_VALID | CPLB_LOCK)
+#define SDRAM_INON_CHBL   (               CPLB_USER_RD | CPLB_VALID)
+
+/*Use the menuconfig cache policy here - CONFIG_BLKFIN_WT/CONFIG_BLKFIN_WB*/
+
+#define ANOMALY_05000158_WORKAROUND            0x200
+#ifdef CONFIG_BLKFIN_WB                /*Write Back Policy */
+#define SDRAM_DGENERIC   (CPLB_L1_CHBL | CPLB_DIRTY \
+                       | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND)
+#else                          /*Write Through */
+#define SDRAM_DGENERIC   (CPLB_L1_CHBL | CPLB_WT | CPLB_L1_AOW \
+                       | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY )
+#endif
+
+
+#define L1_DMEMORY       (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_LOCK | CPLB_DIRTY )
+#define SDRAM_DNON_CHBL  (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY )
+#define SDRAM_EBIU       (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY )
+#define SDRAM_OOPS      (CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_LOCK | CPLB_DIRTY )
+
+#define SIZE_1K 0x00000400     /* 1K */
+#define SIZE_4K 0x00001000     /* 4K */
+#define SIZE_1M 0x00100000     /* 1M */
+#define SIZE_4M 0x00400000     /* 4M */
+
+#define MAX_CPLBS (16 * 2)
+
+/*
+* Number of required data CPLB switchtable entries
+* MEMSIZE / 4 (we mostly install 4M page size CPLBs
+* approx 16 for smaller 1MB page size CPLBs for allignment purposes
+* 1 for L1 Data Memory
+* 1 for CONFIG_DEBUG_HUNT_FOR_ZERO
+* 1 for ASYNC Memory
+*/
+
+
+#define MAX_SWITCH_D_CPLBS (((CONFIG_MEM_SIZE / 4) + 16 + 1 + 1 + 1) * 2)
+
+/*
+* Number of required instruction CPLB switchtable entries
+* MEMSIZE / 4 (we mostly install 4M page size CPLBs
+* approx 12 for smaller 1MB page size CPLBs for allignment purposes
+* 1 for L1 Instruction Memory
+* 1 for CONFIG_DEBUG_HUNT_FOR_ZERO
+*/
+
+#define MAX_SWITCH_I_CPLBS (((CONFIG_MEM_SIZE / 4) + 12 + 1 + 1) * 2)
+
+#endif /* __MACH_BF48_H__  */
diff --git a/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h
new file mode 100644 (file)
index 0000000..2f4afc9
--- /dev/null
@@ -0,0 +1,193 @@
+#include <linux/serial.h>
+#include <asm/dma.h>
+
+#define NR_PORTS               4
+
+#define OFFSET_DLL              0x00   /* Divisor Latch (Low-Byte)             */
+#define OFFSET_DLH              0x04   /* Divisor Latch (High-Byte)            */
+#define OFFSET_GCTL             0x08   /* Global Control Register              */
+#define OFFSET_LCR              0x0C   /* Line Control Register                */
+#define OFFSET_MCR              0x10   /* Modem Control Register               */
+#define OFFSET_LSR              0x14   /* Line Status Register                 */
+#define OFFSET_MSR              0x18   /* Modem Status Register                */
+#define OFFSET_SCR              0x1C   /* SCR Scratch Register                 */
+#define OFFSET_IER_SET          0x20   /* Set Interrupt Enable Register        */
+#define OFFSET_IER_CLEAR        0x24   /* Clear Interrupt Enable Register      */
+#define OFFSET_THR              0x28   /* Transmit Holding register            */
+#define OFFSET_RBR              0x2C   /* Receive Buffer register              */
+
+#define UART_GET_CHAR(uart)     bfin_read16(((uart)->port.membase + OFFSET_RBR))
+#define UART_GET_DLL(uart)     bfin_read16(((uart)->port.membase + OFFSET_DLL))
+#define UART_GET_DLH(uart)     bfin_read16(((uart)->port.membase + OFFSET_DLH))
+#define UART_GET_IER(uart)      bfin_read16(((uart)->port.membase + OFFSET_IER_SET))
+#define UART_GET_LCR(uart)      bfin_read16(((uart)->port.membase + OFFSET_LCR))
+#define UART_GET_LSR(uart)      bfin_read16(((uart)->port.membase + OFFSET_LSR))
+#define UART_GET_GCTL(uart)     bfin_read16(((uart)->port.membase + OFFSET_GCTL))
+
+#define UART_PUT_CHAR(uart,v)   bfin_write16(((uart)->port.membase + OFFSET_THR),v)
+#define UART_PUT_DLL(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_DLL),v)
+#define UART_SET_IER(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_IER_SET),v)
+#define UART_CLEAR_IER(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_IER_CLEAR),v)
+#define UART_PUT_DLH(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_DLH),v)
+#define UART_PUT_LSR(uart,v)   bfin_write16(((uart)->port.membase + OFFSET_LSR),v)
+#define UART_PUT_LCR(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_LCR),v)
+#define UART_PUT_GCTL(uart,v)   bfin_write16(((uart)->port.membase + OFFSET_GCTL),v)
+
+#if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS)
+# define CONFIG_SERIAL_BFIN_CTSRTS
+
+# ifndef CONFIG_UART0_CTS_PIN
+#  define CONFIG_UART0_CTS_PIN -1
+# endif
+
+# ifndef CONFIG_UART0_RTS_PIN
+#  define CONFIG_UART0_RTS_PIN -1
+# endif
+
+# ifndef CONFIG_UART1_CTS_PIN
+#  define CONFIG_UART1_CTS_PIN -1
+# endif
+
+# ifndef CONFIG_UART1_RTS_PIN
+#  define CONFIG_UART1_RTS_PIN -1
+# endif
+#endif
+/*
+ * The pin configuration is different from schematic
+ */
+struct bfin_serial_port {
+        struct uart_port        port;
+        unsigned int            old_status;
+#ifdef CONFIG_SERIAL_BFIN_DMA
+       int                     tx_done;
+       int                     tx_count;
+       struct circ_buf         rx_dma_buf;
+       struct timer_list       rx_dma_timer;
+       int                     rx_dma_nrows;
+       unsigned int            tx_dma_channel;
+       unsigned int            rx_dma_channel;
+       struct work_struct      tx_dma_workqueue;
+#else
+       struct work_struct      cts_workqueue;
+#endif
+#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+       int             cts_pin;
+       int             rts_pin;
+#endif
+};
+
+struct bfin_serial_port bfin_serial_ports[NR_PORTS];
+struct bfin_serial_res {
+       unsigned long   uart_base_addr;
+       int             uart_irq;
+#ifdef CONFIG_SERIAL_BFIN_DMA
+       unsigned int    uart_tx_dma_channel;
+       unsigned int    uart_rx_dma_channel;
+#endif
+#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+       int     uart_cts_pin;
+       int     uart_rts_pin;
+#endif
+};
+
+struct bfin_serial_res bfin_serial_resource[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       {
+       0xFFC00400,
+       IRQ_UART0_RX,
+#ifdef CONFIG_SERIAL_BFIN_DMA
+       CH_UART0_TX,
+       CH_UART0_RX,
+#endif
+#ifdef CONFIG_BFIN_UART0_CTSRTS
+       CONFIG_UART0_CTS_PIN,
+       CONFIG_UART0_RTS_PIN,
+#endif
+       },
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+       {
+       0xFFC02000,
+       IRQ_UART1_RX,
+#ifdef CONFIG_SERIAL_BFIN_DMA
+       CH_UART1_TX,
+       CH_UART1_RX,
+#endif
+       },
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART2
+       {
+       0xFFC02100,
+       IRQ_UART2_RX,
+#ifdef CONFIG_SERIAL_BFIN_DMA
+       CH_UART2_TX,
+       CH_UART2_RX,
+#endif
+#ifdef CONFIG_BFIN_UART2_CTSRTS
+       CONFIG_UART2_CTS_PIN,
+       CONFIG_UART2_RTS_PIN,
+#endif
+       },
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART3
+       {
+       0xFFC03100,
+       IRQ_UART3_RX,
+#ifdef CONFIG_SERIAL_BFIN_DMA
+       CH_UART3_TX,
+       CH_UART3_RX,
+#endif
+       },
+#endif
+};
+
+int nr_ports = ARRAY_SIZE(bfin_serial_resource);
+
+static void bfin_serial_hw_init(struct bfin_serial_port *uart)
+{
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       /* Enable UART0 RX and TX on pin 7 & 8 of PORT E */
+       bfin_write_PORTE_FER(0x180 | bfin_read_PORTE_FER());
+       bfin_write_PORTE_MUX(0x3C000 | bfin_read_PORTE_MUX());
+#endif
+
+#ifdef CONFIG_SERIAL_BFIN_UART1
+       /* Enable UART1 RX and TX on pin 0 & 1 of PORT H */
+       bfin_write_PORTH_FER(0x3 | bfin_read_PORTH_FER());
+       bfin_write_PORTH_MUX(~0xF & bfin_read_PORTH_MUX());
+#ifdef CONFIG_BFIN_UART1_CTSRTS
+       /* Enable UART1 RTS and CTS on pin 9 & 10 of PORT E */
+       bfin_write_PORTE_FER(0x600 | bfin_read_PORTE_FER());
+       bfin_write_PORTE_MUX(~0x3C0000 & bfin_read_PORTE_MUX());
+#endif
+#endif
+
+#ifdef CONFIG_SERIAL_BFIN_UART2
+       /* Enable UART2 RX and TX on pin 4 & 5 of PORT B */
+       bfin_write_PORTB_FER(0x30 | bfin_read_PORTB_FER());
+       bfin_write_PORTB_MUX(~0xF00 & bfin_read_PORTB_MUX());
+#endif
+
+#ifdef CONFIG_SERIAL_BFIN_UART3
+       /* Enable UART3 RX and TX on pin 6 & 7 of PORT B */
+       bfin_write_PORTB_FER(0xC0 | bfin_read_PORTB_FER());
+       bfin_write_PORTB_MUX(~0xF000 | bfin_read_PORTB_MUX());
+#ifdef CONFIG_BFIN_UART3_CTSRTS
+       /* Enable UART3 RTS and CTS on pin 2 & 3 of PORT B */
+       bfin_write_PORTB_FER(0xC | bfin_read_PORTB_FER());
+       bfin_write_PORTB_MUX(~0xF0 | bfin_read_PORTB_MUX());
+#endif
+#endif
+       SSYNC();
+#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+       if (uart->cts_pin >= 0) {
+               gpio_request(uart->cts_pin, NULL);
+               gpio_direction_input(uart->cts_pin);
+       }
+
+       if (uart->rts_pin >= 0) {
+               gpio_request(uart->rts_pin, NULL);
+               gpio_direction_output(uart->rts_pin);
+       }
+#endif
+}
diff --git a/include/asm-blackfin/mach-bf548/blackfin.h b/include/asm-blackfin/mach-bf548/blackfin.h
new file mode 100644 (file)
index 0000000..791218f
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * File:         include/asm-blackfin/mach-bf548/blackfin.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Rev:
+ *
+ * Modified:
+ *
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _MACH_BLACKFIN_H_
+#define _MACH_BLACKFIN_H_
+
+#define BF548_FAMILY
+
+#include "bf548.h"
+#include "mem_map.h"
+#include "anomaly.h"
+
+#ifdef CONFIG_BF542
+#include "defBF542.h"
+#endif
+
+#ifdef CONFIG_BF544
+#include "defBF544.h"
+#endif
+
+#ifdef CONFIG_BF548
+#include "defBF548.h"
+#endif
+
+#ifdef CONFIG_BF549
+#include "defBF549.h"
+#endif
+
+#if !(defined(__ASSEMBLY__) || defined(ASSEMBLY))
+#ifdef CONFIG_BF542
+#include "cdefBF542.h"
+#endif
+
+#ifdef CONFIG_BF544
+#include "cdefBF544.h"
+#endif
+#ifdef CONFIG_BF548
+#include "cdefBF548.h"
+#endif
+#ifdef CONFIG_BF549
+#include "cdefBF549.h"
+#endif
+
+/* UART 1*/
+#define bfin_read_UART_THR()           bfin_read_UART1_THR()
+#define bfin_write_UART_THR(val)       bfin_write_UART1_THR(val)
+#define bfin_read_UART_RBR()           bfin_read_UART1_RBR()
+#define bfin_write_UART_RBR(val)       bfin_write_UART1_RBR(val)
+#define bfin_read_UART_DLL()           bfin_read_UART1_DLL()
+#define bfin_write_UART_DLL(val)       bfin_write_UART1_DLL(val)
+#define bfin_read_UART_IER()           bfin_read_UART1_IER()
+#define bfin_write_UART_IER(val)       bfin_write_UART1_IER(val)
+#define bfin_read_UART_DLH()           bfin_read_UART1_DLH()
+#define bfin_write_UART_DLH(val)       bfin_write_UART1_DLH(val)
+#define bfin_read_UART_IIR()           bfin_read_UART1_IIR()
+#define bfin_write_UART_IIR(val)       bfin_write_UART1_IIR(val)
+#define bfin_read_UART_LCR()           bfin_read_UART1_LCR()
+#define bfin_write_UART_LCR(val)       bfin_write_UART1_LCR(val)
+#define bfin_read_UART_MCR()           bfin_read_UART1_MCR()
+#define bfin_write_UART_MCR(val)       bfin_write_UART1_MCR(val)
+#define bfin_read_UART_LSR()           bfin_read_UART1_LSR()
+#define bfin_write_UART_LSR(val)       bfin_write_UART1_LSR(val)
+#define bfin_read_UART_SCR()           bfin_read_UART1_SCR()
+#define bfin_write_UART_SCR(val)       bfin_write_UART1_SCR(val)
+#define bfin_read_UART_GCTL()          bfin_read_UART1_GCTL()
+#define bfin_write_UART_GCTL(val)      bfin_write_UART1_GCTL(val)
+
+#endif
+
+/* MAP used DEFINES from BF533 to BF54x - so we don't need to change 
+ * them in the driver, kernel, etc. */
+
+/* UART_IIR Register */
+#define STATUS(x)      ((x << 1) & 0x06)
+#define STATUS_P1      0x02
+#define STATUS_P0      0x01
+
+/* UART 0*/
+
+/* DMA Channnel */
+#define bfin_read_CH_UART_RX()         bfin_read_CH_UART1_RX()
+#define bfin_write_CH_UART_RX(val)     bfin_write_CH_UART1_RX(val)
+#define bfin_read_CH_UART_TX()         bfin_read_CH_UART1_TX()
+#define bfin_write_CH_UART_TX(val)     bfin_write_CH_UART1_TX(val)
+#define CH_UART_RX                     CH_UART1_RX
+#define CH_UART_TX                     CH_UART1_TX
+
+/* System Interrupt Controller */
+#define bfin_read_IRQ_UART_RX()                bfin_read_IRQ_UART1_RX()
+#define bfin_write_IRQ_UART_RX(val)    bfin_write_IRQ_UART1_RX(val)
+#define bfin_read_IRQ_UART_TX()                bfin_read_IRQ_UART1_TX()
+#define bfin_write_IRQ_UART_TX(val)    bfin_write_IRQ_UART1_TX(val)
+#define bfin_read_IRQ_UART_ERROR()     bfin_read_IRQ_UART1_ERROR()
+#define bfin_write_IRQ_UART_ERROR(val) bfin_write_IRQ_UART1_ERROR(val)
+#define IRQ_UART_RX                    IRQ_UART1_RX
+#define        IRQ_UART_TX                     IRQ_UART1_TX
+#define        IRQ_UART_ERROR                  IRQ_UART1_ERROR
+
+/* MMR Registers*/
+#define bfin_read_UART_THR()           bfin_read_UART1_THR()
+#define bfin_write_UART_THR(val)       bfin_write_UART1_THR(val)
+#define bfin_read_UART_RBR()           bfin_read_UART1_RBR()
+#define bfin_write_UART_RBR(val)       bfin_write_UART1_RBR(val)
+#define bfin_read_UART_DLL()           bfin_read_UART1_DLL()
+#define bfin_write_UART_DLL(val)       bfin_write_UART1_DLL(val)
+#define bfin_read_UART_IER()           bfin_read_UART1_IER()
+#define bfin_write_UART_IER(val)       bfin_write_UART1_IER(val)
+#define bfin_read_UART_DLH()           bfin_read_UART1_DLH()
+#define bfin_write_UART_DLH(val)       bfin_write_UART1_DLH(val)
+#define bfin_read_UART_IIR()           bfin_read_UART1_IIR()
+#define bfin_write_UART_IIR(val)       bfin_write_UART1_IIR(val)
+#define bfin_read_UART_LCR()           bfin_read_UART1_LCR()
+#define bfin_write_UART_LCR(val)       bfin_write_UART1_LCR(val)
+#define bfin_read_UART_MCR()           bfin_read_UART1_MCR()
+#define bfin_write_UART_MCR(val)       bfin_write_UART1_MCR(val)
+#define bfin_read_UART_LSR()           bfin_read_UART1_LSR()
+#define bfin_write_UART_LSR(val)       bfin_write_UART1_LSR(val)
+#define bfin_read_UART_SCR()           bfin_read_UART1_SCR()
+#define bfin_write_UART_SCR(val)       bfin_write_UART1_SCR(val)
+#define bfin_read_UART_GCTL()          bfin_read_UART1_GCTL()
+#define bfin_write_UART_GCTL(val)      bfin_write_UART1_GCTL(val)
+#define UART_THR                       UART1_THR
+#define UART_RBR                       UART1_RBR
+#define UART_DLL                       UART1_DLL
+#define UART_IER                       UART1_IER
+#define UART_DLH                       UART1_DLH
+#define UART_IIR                       UART1_IIR
+#define UART_LCR                       UART1_LCR
+#define UART_MCR                       UART1_MCR
+#define UART_LSR                       UART1_LSR
+#define UART_SCR                       UART1_SCR
+#define UART_GCTL                      UART1_GCTL
+
+/* PLL_DIV Masks */
+#define CCLK_DIV1 CSEL_DIV1    /* CCLK = VCO / 1 */
+#define CCLK_DIV2 CSEL_DIV2    /* CCLK = VCO / 2 */
+#define CCLK_DIV4 CSEL_DIV4    /* CCLK = VCO / 4 */
+#define CCLK_DIV8 CSEL_DIV8    /* CCLK = VCO / 8 */
+
+#endif
index 6bbcefeb3627c161e0a156bb467b2cda87109b6a..98d35a9291165d61cacc8167ac24b48d5724be1b 100644 (file)
@@ -31,7 +31,8 @@
 #ifndef _CDEF_BF54X_H
 #define _CDEF_BF54X_H
 
-#include <defBF54x_base.h>
+#include "defBF54x_base.h"
+#include <asm/system.h>
 
 /* ************************************************************** */
 /* SYSTEM & MMR ADDRESS DEFINITIONS COMMON TO ALL ADSP-BF54x    */
 #define bfin_read_PLL_DIV()            bfin_read16(PLL_DIV)
 #define bfin_write_PLL_DIV(val)                bfin_write16(PLL_DIV, val)
 #define bfin_read_VR_CTL()             bfin_read16(VR_CTL)
-#define bfin_write_VR_CTL(val)         bfin_write16(VR_CTL, val)
+/* Writing to VR_CTL initiates a PLL relock sequence. */
+static __inline__ void bfin_write_VR_CTL(unsigned int val)
+{
+       unsigned long flags, iwr0, iwr1, iwr2;
+
+       /* Enable the PLL Wakeup bit in SIC IWR */
+       iwr0 = bfin_read32(SIC_IWR0);
+       iwr1 = bfin_read32(SIC_IWR1);
+       iwr2 = bfin_read32(SIC_IWR2);
+       /* Only allow PPL Wakeup) */
+       bfin_write32(SIC_IWR0, IWR_ENABLE(0));
+       bfin_write32(SIC_IWR1, 0);
+       bfin_write32(SIC_IWR2, 0);
+
+       bfin_write16(VR_CTL, val);
+       __builtin_bfin_ssync();
+
+       local_irq_save(flags);
+       asm("IDLE;");
+       local_irq_restore(flags);
+       bfin_write32(SIC_IWR0, iwr0);
+       bfin_write32(SIC_IWR1, iwr1);
+       bfin_write32(SIC_IWR2, iwr2);
+}
 #define bfin_read_PLL_STAT()           bfin_read16(PLL_STAT)
 #define bfin_write_PLL_STAT(val)       bfin_write16(PLL_STAT, val)
 #define bfin_read_PLL_LOCKCNT()                bfin_read16(PLL_LOCKCNT)
 #define bfin_write_SIC_IMASK1(val)     bfin_write32(SIC_IMASK1, val)
 #define bfin_read_SIC_IMASK2()         bfin_read32(SIC_IMASK2)
 #define bfin_write_SIC_IMASK2(val)     bfin_write32(SIC_IMASK2, val)
+#define bfin_read_SIC_IMASK(x)         bfin_read32(SIC_IMASK0 + (x << 2))
+#define bfin_write_SIC_IMASK(x, val)   bfin_write32((SIC_IMASK0 + (x << 2)), val)
+
 #define bfin_read_SIC_ISR0()           bfin_read32(SIC_ISR0)
 #define bfin_write_SIC_ISR0(val)       bfin_write32(SIC_ISR0, val)
 #define bfin_read_SIC_ISR1()           bfin_read32(SIC_ISR1)
 #define bfin_write_SIC_ISR1(val)       bfin_write32(SIC_ISR1, val)
 #define bfin_read_SIC_ISR2()           bfin_read32(SIC_ISR2)
 #define bfin_write_SIC_ISR2(val)       bfin_write32(SIC_ISR2, val)
+#define bfin_read_SIC_ISR(x)           bfin_read32(SIC_ISR0 + (x << 2))
+#define bfin_write_SIC_ISR(x, val)     bfin_write32((SIC_ISR0 + (x << 2)), val)
+
 #define bfin_read_SIC_IWR0()           bfin_read32(SIC_IWR0)
 #define bfin_write_SIC_IWR0(val)       bfin_write32(SIC_IWR0, val)
 #define bfin_read_SIC_IWR1()           bfin_read32(SIC_IWR1)
 #define bfin_read_MDMA_D0_NEXT_DESC_PTR()      bfin_read32(MDMA_D0_NEXT_DESC_PTR)
 #define bfin_write_MDMA_D0_NEXT_DESC_PTR(val)  bfin_write32(MDMA_D0_NEXT_DESC_PTR)
 #define bfin_read_MDMA_D0_START_ADDR()                 bfin_read32(MDMA_D0_START_ADDR)
-#define bfin_write_MDMA_D0_START_ADDR(val)     bfin_write32(MDMA_D0_START_ADDR)
+#define bfin_write_MDMA_D0_START_ADDR(val)     bfin_write32(MDMA_D0_START_ADDR, val)
 #define bfin_read_MDMA_D0_CONFIG()             bfin_read16(MDMA_D0_CONFIG)
 #define bfin_write_MDMA_D0_CONFIG(val)         bfin_write16(MDMA_D0_CONFIG, val)
 #define bfin_read_MDMA_D0_X_COUNT()            bfin_read16(MDMA_D0_X_COUNT)
 #define bfin_write_MDMA_D0_X_COUNT(val)                bfin_write16(MDMA_D0_X_COUNT, val)
 #define bfin_read_MDMA_D0_X_MODIFY()           bfin_read16(MDMA_D0_X_MODIFY)
-#define bfin_write_MDMA_D0_X_MODIFY(val)       bfin_write16(MDMA_D0_X_MODIFY)
+#define bfin_write_MDMA_D0_X_MODIFY(val)       bfin_write16(MDMA_D0_X_MODIFY, val)
 #define bfin_read_MDMA_D0_Y_COUNT()            bfin_read16(MDMA_D0_Y_COUNT)
 #define bfin_write_MDMA_D0_Y_COUNT(val)                bfin_write16(MDMA_D0_Y_COUNT, val)
 #define bfin_read_MDMA_D0_Y_MODIFY()           bfin_read16(MDMA_D0_Y_MODIFY)
-#define bfin_write_MDMA_D0_Y_MODIFY(val)       bfin_write16(MDMA_D0_Y_MODIFY)
+#define bfin_write_MDMA_D0_Y_MODIFY(val)       bfin_write16(MDMA_D0_Y_MODIFY, val)
 #define bfin_read_MDMA_D0_CURR_DESC_PTR()      bfin_read32(MDMA_D0_CURR_DESC_PTR)
-#define bfin_write_MDMA_D0_CURR_DESC_PTR(val)  bfin_write32(MDMA_D0_CURR_DESC_PTR)
+#define bfin_write_MDMA_D0_CURR_DESC_PTR(val)  bfin_write32(MDMA_D0_CURR_DESC_PTR, val)
 #define bfin_read_MDMA_D0_CURR_ADDR()          bfin_read32(MDMA_D0_CURR_ADDR)
-#define bfin_write_MDMA_D0_CURR_ADDR(val)      bfin_write32(MDMA_D0_CURR_ADDR)
+#define bfin_write_MDMA_D0_CURR_ADDR(val)      bfin_write32(MDMA_D0_CURR_ADDR, val)
 #define bfin_read_MDMA_D0_IRQ_STATUS()         bfin_read16(MDMA_D0_IRQ_STATUS)
 #define bfin_write_MDMA_D0_IRQ_STATUS(val)     bfin_write16(MDMA_D0_IRQ_STATUS, val)
 #define bfin_read_MDMA_D0_PERIPHERAL_MAP()     bfin_read16(MDMA_D0_PERIPHERAL_MAP)
 #define bfin_read_MDMA_D0_CURR_Y_COUNT()       bfin_read16(MDMA_D0_CURR_Y_COUNT)
 #define bfin_write_MDMA_D0_CURR_Y_COUNT(val)   bfin_write16(MDMA_D0_CURR_Y_COUNT, val)
 #define bfin_read_MDMA_S0_NEXT_DESC_PTR()      bfin_read32(MDMA_S0_NEXT_DESC_PTR)
-#define bfin_write_MDMA_S0_NEXT_DESC_PTR(val)  bfin_write32(MDMA_S0_NEXT_DESC_PTR)
+#define bfin_write_MDMA_S0_NEXT_DESC_PTR(val)  bfin_write32(MDMA_S0_NEXT_DESC_PTR, val)
 #define bfin_read_MDMA_S0_START_ADDR()                 bfin_read32(MDMA_S0_START_ADDR)
-#define bfin_write_MDMA_S0_START_ADDR(val)     bfin_write32(MDMA_S0_START_ADDR)
+#define bfin_write_MDMA_S0_START_ADDR(val)     bfin_write32(MDMA_S0_START_ADDR, val)
 #define bfin_read_MDMA_S0_CONFIG()             bfin_read16(MDMA_S0_CONFIG)
 #define bfin_write_MDMA_S0_CONFIG(val)         bfin_write16(MDMA_S0_CONFIG, val)
 #define bfin_read_MDMA_S0_X_COUNT()            bfin_read16(MDMA_S0_X_COUNT)
 #define bfin_write_MDMA_S0_X_COUNT(val)                bfin_write16(MDMA_S0_X_COUNT, val)
 #define bfin_read_MDMA_S0_X_MODIFY()           bfin_read16(MDMA_S0_X_MODIFY)
-#define bfin_write_MDMA_S0_X_MODIFY(val)       bfin_write16(MDMA_S0_X_MODIFY)
+#define bfin_write_MDMA_S0_X_MODIFY(val)       bfin_write16(MDMA_S0_X_MODIFY, val)
 #define bfin_read_MDMA_S0_Y_COUNT()            bfin_read16(MDMA_S0_Y_COUNT)
 #define bfin_write_MDMA_S0_Y_COUNT(val)                bfin_write16(MDMA_S0_Y_COUNT, val)
 #define bfin_read_MDMA_S0_Y_MODIFY()           bfin_read16(MDMA_S0_Y_MODIFY)
-#define bfin_write_MDMA_S0_Y_MODIFY(val)       bfin_write16(MDMA_S0_Y_MODIFY)
+#define bfin_write_MDMA_S0_Y_MODIFY(val)       bfin_write16(MDMA_S0_Y_MODIFY, val)
 #define bfin_read_MDMA_S0_CURR_DESC_PTR()      bfin_read32(MDMA_S0_CURR_DESC_PTR)
-#define bfin_write_MDMA_S0_CURR_DESC_PTR(val)  bfin_write32(MDMA_S0_CURR_DESC_PTR)
+#define bfin_write_MDMA_S0_CURR_DESC_PTR(val)  bfin_write32(MDMA_S0_CURR_DESC_PTR, val)
 #define bfin_read_MDMA_S0_CURR_ADDR()          bfin_read32(MDMA_S0_CURR_ADDR)
-#define bfin_write_MDMA_S0_CURR_ADDR(val)      bfin_write32(MDMA_S0_CURR_ADDR)
+#define bfin_write_MDMA_S0_CURR_ADDR(val)      bfin_write32(MDMA_S0_CURR_ADDR, val)
 #define bfin_read_MDMA_S0_IRQ_STATUS()         bfin_read16(MDMA_S0_IRQ_STATUS)
 #define bfin_write_MDMA_S0_IRQ_STATUS(val)     bfin_write16(MDMA_S0_IRQ_STATUS, val)
 #define bfin_read_MDMA_S0_PERIPHERAL_MAP()     bfin_read16(MDMA_S0_PERIPHERAL_MAP)
 /* MDMA Stream 1 Registers */
 
 #define bfin_read_MDMA_D1_NEXT_DESC_PTR()      bfin_read32(MDMA_D1_NEXT_DESC_PTR)
-#define bfin_write_MDMA_D1_NEXT_DESC_PTR(val)  bfin_write32(MDMA_D1_NEXT_DESC_PTR)
+#define bfin_write_MDMA_D1_NEXT_DESC_PTR(val)  bfin_write32(MDMA_D1_NEXT_DESC_PTR, val)
 #define bfin_read_MDMA_D1_START_ADDR()                 bfin_read32(MDMA_D1_START_ADDR)
-#define bfin_write_MDMA_D1_START_ADDR(val)     bfin_write32(MDMA_D1_START_ADDR)
+#define bfin_write_MDMA_D1_START_ADDR(val)     bfin_write32(MDMA_D1_START_ADDR, val)
 #define bfin_read_MDMA_D1_CONFIG()             bfin_read16(MDMA_D1_CONFIG)
 #define bfin_write_MDMA_D1_CONFIG(val)         bfin_write16(MDMA_D1_CONFIG, val)
 #define bfin_read_MDMA_D1_X_COUNT()            bfin_read16(MDMA_D1_X_COUNT)
 #define bfin_read_MDMA_D1_Y_MODIFY()           bfin_read16(MDMA_D1_Y_MODIFY)
 #define bfin_write_MDMA_D1_Y_MODIFY(val)       bfin_write16(MDMA_D1_Y_MODIFY)
 #define bfin_read_MDMA_D1_CURR_DESC_PTR()      bfin_read32(MDMA_D1_CURR_DESC_PTR)
-#define bfin_write_MDMA_D1_CURR_DESC_PTR(val)  bfin_write32(MDMA_D1_CURR_DESC_PTR)
+#define bfin_write_MDMA_D1_CURR_DESC_PTR(val)  bfin_write32(MDMA_D1_CURR_DESC_PTR, val)
 #define bfin_read_MDMA_D1_CURR_ADDR()          bfin_read32(MDMA_D1_CURR_ADDR)
-#define bfin_write_MDMA_D1_CURR_ADDR(val)      bfin_write32(MDMA_D1_CURR_ADDR)
+#define bfin_write_MDMA_D1_CURR_ADDR(val)      bfin_write32(MDMA_D1_CURR_ADDR, val)
 #define bfin_read_MDMA_D1_IRQ_STATUS()         bfin_read16(MDMA_D1_IRQ_STATUS)
 #define bfin_write_MDMA_D1_IRQ_STATUS(val)     bfin_write16(MDMA_D1_IRQ_STATUS, val)
 #define bfin_read_MDMA_D1_PERIPHERAL_MAP()     bfin_read16(MDMA_D1_PERIPHERAL_MAP)
 #define bfin_read_MDMA_D1_CURR_Y_COUNT()       bfin_read16(MDMA_D1_CURR_Y_COUNT)
 #define bfin_write_MDMA_D1_CURR_Y_COUNT(val)   bfin_write16(MDMA_D1_CURR_Y_COUNT, val)
 #define bfin_read_MDMA_S1_NEXT_DESC_PTR()      bfin_read32(MDMA_S1_NEXT_DESC_PTR)
-#define bfin_write_MDMA_S1_NEXT_DESC_PTR(val)  bfin_write32(MDMA_S1_NEXT_DESC_PTR)
+#define bfin_write_MDMA_S1_NEXT_DESC_PTR(val)  bfin_write32(MDMA_S1_NEXT_DESC_PTR, val)
 #define bfin_read_MDMA_S1_START_ADDR()                 bfin_read32(MDMA_S1_START_ADDR)
-#define bfin_write_MDMA_S1_START_ADDR(val)     bfin_write32(MDMA_S1_START_ADDR)
+#define bfin_write_MDMA_S1_START_ADDR(val)     bfin_write32(MDMA_S1_START_ADDR, val)
 #define bfin_read_MDMA_S1_CONFIG()             bfin_read16(MDMA_S1_CONFIG)
 #define bfin_write_MDMA_S1_CONFIG(val)         bfin_write16(MDMA_S1_CONFIG, val)
 #define bfin_read_MDMA_S1_X_COUNT()            bfin_read16(MDMA_S1_X_COUNT)
 #define bfin_read_MDMA_S1_Y_MODIFY()           bfin_read16(MDMA_S1_Y_MODIFY)
 #define bfin_write_MDMA_S1_Y_MODIFY(val)       bfin_write16(MDMA_S1_Y_MODIFY)
 #define bfin_read_MDMA_S1_CURR_DESC_PTR()      bfin_read32(MDMA_S1_CURR_DESC_PTR)
-#define bfin_write_MDMA_S1_CURR_DESC_PTR(val)  bfin_write32(MDMA_S1_CURR_DESC_PTR)
+#define bfin_write_MDMA_S1_CURR_DESC_PTR(val)  bfin_write32(MDMA_S1_CURR_DESC_PTR, val)
 #define bfin_read_MDMA_S1_CURR_ADDR()          bfin_read32(MDMA_S1_CURR_ADDR)
-#define bfin_write_MDMA_S1_CURR_ADDR(val)      bfin_write32(MDMA_S1_CURR_ADDR)
+#define bfin_write_MDMA_S1_CURR_ADDR(val)      bfin_write32(MDMA_S1_CURR_ADDR, val)
 #define bfin_read_MDMA_S1_IRQ_STATUS()         bfin_read16(MDMA_S1_IRQ_STATUS)
 #define bfin_write_MDMA_S1_IRQ_STATUS(val)     bfin_write16(MDMA_S1_IRQ_STATUS, val)
 #define bfin_read_MDMA_S1_PERIPHERAL_MAP()     bfin_read16(MDMA_S1_PERIPHERAL_MAP)
index ac968fca5cc549bbb0e19555d6f9c4eb0961deb1..32d07130200c980587a0ef8d840b026f375b6fbd 100644 (file)
 /* Bit masks for KPAD_CTL */
 
 #define                   KPAD_EN  0x1        /* Keypad Enable */
-#define                  nKPAD_EN  0x0       
 #define              KPAD_IRQMODE  0x6        /* Key Press Interrupt Enable */
 #define                KPAD_ROWEN  0x1c00     /* Row Enable Width */
 #define                KPAD_COLEN  0xe000     /* Column Enable Width */
 /* Bit masks for KPAD_STAT */
 
 #define                  KPAD_IRQ  0x1        /* Keypad Interrupt Status */
-#define                 nKPAD_IRQ  0x0       
 #define              KPAD_MROWCOL  0x6        /* Multiple Row/Column Keypress Status */
 #define              KPAD_PRESSED  0x8        /* Key press current status */
-#define             nKPAD_PRESSED  0x0       
 
 /* Bit masks for KPAD_SOFTEVAL */
 
 #define           KPAD_SOFTEVAL_E  0x2        /* Software Programmable Force Evaluate */
-#define          nKPAD_SOFTEVAL_E  0x0       
 
 /* Bit masks for SDH_COMMAND */
 
 #define                   CMD_IDX  0x3f       /* Command Index */
 #define                   CMD_RSP  0x40       /* Response */
-#define                  nCMD_RSP  0x0       
 #define                 CMD_L_RSP  0x80       /* Long Response */
-#define                nCMD_L_RSP  0x0       
 #define                 CMD_INT_E  0x100      /* Command Interrupt */
-#define                nCMD_INT_E  0x0       
 #define                CMD_PEND_E  0x200      /* Command Pending */
-#define               nCMD_PEND_E  0x0       
 #define                     CMD_E  0x400      /* Command Enable */
-#define                    nCMD_E  0x0       
 
 /* Bit masks for SDH_PWR_CTL */
 
 #define                       TBD  0x3c       /* TBD */
 #endif
 #define                 SD_CMD_OD  0x40       /* Open Drain Output */
-#define                nSD_CMD_OD  0x0       
 #define                   ROD_CTL  0x80       /* Rod Control */
-#define                  nROD_CTL  0x0       
 
 /* Bit masks for SDH_CLK_CTL */
 
 #define                    CLKDIV  0xff       /* MC_CLK Divisor */
 #define                     CLK_E  0x100      /* MC_CLK Bus Clock Enable */
-#define                    nCLK_E  0x0       
 #define                  PWR_SV_E  0x200      /* Power Save Enable */
-#define                 nPWR_SV_E  0x0       
 #define             CLKDIV_BYPASS  0x400      /* Bypass Divisor */
-#define            nCLKDIV_BYPASS  0x0       
 #define                  WIDE_BUS  0x800      /* Wide Bus Mode Enable */
-#define                 nWIDE_BUS  0x0       
 
 /* Bit masks for SDH_RESP_CMD */
 
 /* Bit masks for SDH_DATA_CTL */
 
 #define                     DTX_E  0x1        /* Data Transfer Enable */
-#define                    nDTX_E  0x0       
 #define                   DTX_DIR  0x2        /* Data Transfer Direction */
-#define                  nDTX_DIR  0x0       
 #define                  DTX_MODE  0x4        /* Data Transfer Mode */
-#define                 nDTX_MODE  0x0       
 #define                 DTX_DMA_E  0x8        /* Data Transfer DMA Enable */
-#define                nDTX_DMA_E  0x0       
 #define              DTX_BLK_LGTH  0xf0       /* Data Transfer Block Length */
 
 /* Bit masks for SDH_STATUS */
 
 #define              CMD_CRC_FAIL  0x1        /* CMD CRC Fail */
-#define             nCMD_CRC_FAIL  0x0       
 #define              DAT_CRC_FAIL  0x2        /* Data CRC Fail */
-#define             nDAT_CRC_FAIL  0x0       
 #define               CMD_TIMEOUT  0x4        /* CMD Time Out */
-#define              nCMD_TIMEOUT  0x0       
 #define               DAT_TIMEOUT  0x8        /* Data Time Out */
-#define              nDAT_TIMEOUT  0x0       
 #define               TX_UNDERRUN  0x10       /* Transmit Underrun */
-#define              nTX_UNDERRUN  0x0       
 #define                RX_OVERRUN  0x20       /* Receive Overrun */
-#define               nRX_OVERRUN  0x0       
 #define              CMD_RESP_END  0x40       /* CMD Response End */
-#define             nCMD_RESP_END  0x0       
 #define                  CMD_SENT  0x80       /* CMD Sent */
-#define                 nCMD_SENT  0x0       
 #define                   DAT_END  0x100      /* Data End */
-#define                  nDAT_END  0x0       
 #define             START_BIT_ERR  0x200      /* Start Bit Error */
-#define            nSTART_BIT_ERR  0x0       
 #define               DAT_BLK_END  0x400      /* Data Block End */
-#define              nDAT_BLK_END  0x0       
 #define                   CMD_ACT  0x800      /* CMD Active */
-#define                  nCMD_ACT  0x0       
 #define                    TX_ACT  0x1000     /* Transmit Active */
-#define                   nTX_ACT  0x0       
 #define                    RX_ACT  0x2000     /* Receive Active */
-#define                   nRX_ACT  0x0       
 #define              TX_FIFO_STAT  0x4000     /* Transmit FIFO Status */
-#define             nTX_FIFO_STAT  0x0       
 #define              RX_FIFO_STAT  0x8000     /* Receive FIFO Status */
-#define             nRX_FIFO_STAT  0x0       
 #define              TX_FIFO_FULL  0x10000    /* Transmit FIFO Full */
-#define             nTX_FIFO_FULL  0x0       
 #define              RX_FIFO_FULL  0x20000    /* Receive FIFO Full */
-#define             nRX_FIFO_FULL  0x0       
 #define              TX_FIFO_ZERO  0x40000    /* Transmit FIFO Empty */
-#define             nTX_FIFO_ZERO  0x0       
 #define               RX_DAT_ZERO  0x80000    /* Receive FIFO Empty */
-#define              nRX_DAT_ZERO  0x0       
 #define                TX_DAT_RDY  0x100000   /* Transmit Data Available */
-#define               nTX_DAT_RDY  0x0       
 #define               RX_FIFO_RDY  0x200000   /* Receive Data Available */
-#define              nRX_FIFO_RDY  0x0       
 
 /* Bit masks for SDH_STATUS_CLR */
 
 #define         CMD_CRC_FAIL_STAT  0x1        /* CMD CRC Fail Status */
-#define        nCMD_CRC_FAIL_STAT  0x0       
 #define         DAT_CRC_FAIL_STAT  0x2        /* Data CRC Fail Status */
-#define        nDAT_CRC_FAIL_STAT  0x0       
 #define          CMD_TIMEOUT_STAT  0x4        /* CMD Time Out Status */
-#define         nCMD_TIMEOUT_STAT  0x0       
 #define          DAT_TIMEOUT_STAT  0x8        /* Data Time Out status */
-#define         nDAT_TIMEOUT_STAT  0x0       
 #define          TX_UNDERRUN_STAT  0x10       /* Transmit Underrun Status */
-#define         nTX_UNDERRUN_STAT  0x0       
 #define           RX_OVERRUN_STAT  0x20       /* Receive Overrun Status */
-#define          nRX_OVERRUN_STAT  0x0       
 #define         CMD_RESP_END_STAT  0x40       /* CMD Response End Status */
-#define        nCMD_RESP_END_STAT  0x0       
 #define             CMD_SENT_STAT  0x80       /* CMD Sent Status */
-#define            nCMD_SENT_STAT  0x0       
 #define              DAT_END_STAT  0x100      /* Data End Status */
-#define             nDAT_END_STAT  0x0       
 #define        START_BIT_ERR_STAT  0x200      /* Start Bit Error Status */
-#define       nSTART_BIT_ERR_STAT  0x0       
 #define          DAT_BLK_END_STAT  0x400      /* Data Block End Status */
-#define         nDAT_BLK_END_STAT  0x0       
 
 /* Bit masks for SDH_MASK0 */
 
 #define         CMD_CRC_FAIL_MASK  0x1        /* CMD CRC Fail Mask */
-#define        nCMD_CRC_FAIL_MASK  0x0       
 #define         DAT_CRC_FAIL_MASK  0x2        /* Data CRC Fail Mask */
-#define        nDAT_CRC_FAIL_MASK  0x0       
 #define          CMD_TIMEOUT_MASK  0x4        /* CMD Time Out Mask */
-#define         nCMD_TIMEOUT_MASK  0x0       
 #define          DAT_TIMEOUT_MASK  0x8        /* Data Time Out Mask */
-#define         nDAT_TIMEOUT_MASK  0x0       
 #define          TX_UNDERRUN_MASK  0x10       /* Transmit Underrun Mask */
-#define         nTX_UNDERRUN_MASK  0x0       
 #define           RX_OVERRUN_MASK  0x20       /* Receive Overrun Mask */
-#define          nRX_OVERRUN_MASK  0x0       
 #define         CMD_RESP_END_MASK  0x40       /* CMD Response End Mask */
-#define        nCMD_RESP_END_MASK  0x0       
 #define             CMD_SENT_MASK  0x80       /* CMD Sent Mask */
-#define            nCMD_SENT_MASK  0x0       
 #define              DAT_END_MASK  0x100      /* Data End Mask */
-#define             nDAT_END_MASK  0x0       
 #define        START_BIT_ERR_MASK  0x200      /* Start Bit Error Mask */
-#define       nSTART_BIT_ERR_MASK  0x0       
 #define          DAT_BLK_END_MASK  0x400      /* Data Block End Mask */
-#define         nDAT_BLK_END_MASK  0x0       
 #define              CMD_ACT_MASK  0x800      /* CMD Active Mask */
-#define             nCMD_ACT_MASK  0x0       
 #define               TX_ACT_MASK  0x1000     /* Transmit Active Mask */
-#define              nTX_ACT_MASK  0x0       
 #define               RX_ACT_MASK  0x2000     /* Receive Active Mask */
-#define              nRX_ACT_MASK  0x0       
 #define         TX_FIFO_STAT_MASK  0x4000     /* Transmit FIFO Status Mask */
-#define        nTX_FIFO_STAT_MASK  0x0       
 #define         RX_FIFO_STAT_MASK  0x8000     /* Receive FIFO Status Mask */
-#define        nRX_FIFO_STAT_MASK  0x0       
 #define         TX_FIFO_FULL_MASK  0x10000    /* Transmit FIFO Full Mask */
-#define        nTX_FIFO_FULL_MASK  0x0       
 #define         RX_FIFO_FULL_MASK  0x20000    /* Receive FIFO Full Mask */
-#define        nRX_FIFO_FULL_MASK  0x0       
 #define         TX_FIFO_ZERO_MASK  0x40000    /* Transmit FIFO Empty Mask */
-#define        nTX_FIFO_ZERO_MASK  0x0       
 #define          RX_DAT_ZERO_MASK  0x80000    /* Receive FIFO Empty Mask */
-#define         nRX_DAT_ZERO_MASK  0x0       
 #define           TX_DAT_RDY_MASK  0x100000   /* Transmit Data Available Mask */
-#define          nTX_DAT_RDY_MASK  0x0       
 #define          RX_FIFO_RDY_MASK  0x200000   /* Receive Data Available Mask */
-#define         nRX_FIFO_RDY_MASK  0x0       
 
 /* Bit masks for SDH_FIFO_CNT */
 
 /* Bit masks for SDH_E_STATUS */
 
 #define              SDIO_INT_DET  0x2        /* SDIO Int Detected */
-#define             nSDIO_INT_DET  0x0       
 #define               SD_CARD_DET  0x10       /* SD Card Detect */
-#define              nSD_CARD_DET  0x0       
 
 /* Bit masks for SDH_E_MASK */
 
 #define                  SDIO_MSK  0x2        /* Mask SDIO Int Detected */
-#define                 nSDIO_MSK  0x0       
 #define                   SCD_MSK  0x40       /* Mask Card Detect */
-#define                  nSCD_MSK  0x0       
 
 /* Bit masks for SDH_CFG */
 
 #define                   CLKS_EN  0x1        /* Clocks Enable */
-#define                  nCLKS_EN  0x0       
 #define                      SD4E  0x4        /* SDIO 4-Bit Enable */
-#define                     nSD4E  0x0       
 #define                       MWE  0x8        /* Moving Window Enable */
-#define                      nMWE  0x0       
 #define                    SD_RST  0x10       /* SDMMC Reset */
-#define                   nSD_RST  0x0       
 #define                 PUP_SDDAT  0x20       /* Pull-up SD_DAT */
-#define                nPUP_SDDAT  0x0       
 #define                PUP_SDDAT3  0x40       /* Pull-up SD_DAT3 */
-#define               nPUP_SDDAT3  0x0       
 #define                 PD_SDDAT3  0x80       /* Pull-down SD_DAT3 */
-#define                nPD_SDDAT3  0x0       
 
 /* Bit masks for SDH_RD_WAIT_EN */
 
 #define                       RWR  0x1        /* Read Wait Request */
-#define                      nRWR  0x0       
 
 /* Bit masks for ATAPI_CONTROL */
 
 #define                 PIO_START  0x1        /* Start PIO/Reg Op */
-#define                nPIO_START  0x0       
 #define               MULTI_START  0x2        /* Start Multi-DMA Op */
-#define              nMULTI_START  0x0       
 #define               ULTRA_START  0x4        /* Start Ultra-DMA Op */
-#define              nULTRA_START  0x0       
 #define                  XFER_DIR  0x8        /* Transfer Direction */
-#define                 nXFER_DIR  0x0       
 #define                  IORDY_EN  0x10       /* IORDY Enable */
-#define                 nIORDY_EN  0x0       
 #define                FIFO_FLUSH  0x20       /* Flush FIFOs */
-#define               nFIFO_FLUSH  0x0       
 #define                  SOFT_RST  0x40       /* Soft Reset */
-#define                 nSOFT_RST  0x0       
 #define                   DEV_RST  0x80       /* Device Reset */
-#define                  nDEV_RST  0x0       
 #define                TFRCNT_RST  0x100      /* Trans Count Reset */
-#define               nTFRCNT_RST  0x0       
 #define               END_ON_TERM  0x200      /* End/Terminate Select */
-#define              nEND_ON_TERM  0x0       
 #define               PIO_USE_DMA  0x400      /* PIO-DMA Enable */
-#define              nPIO_USE_DMA  0x0       
 #define          UDMAIN_FIFO_THRS  0xf000     /* Ultra DMA-IN FIFO Threshold */
 
 /* Bit masks for ATAPI_STATUS */
 
 #define               PIO_XFER_ON  0x1        /* PIO transfer in progress */
-#define              nPIO_XFER_ON  0x0       
 #define             MULTI_XFER_ON  0x2        /* Multi-word DMA transfer in progress */
-#define            nMULTI_XFER_ON  0x0       
 #define             ULTRA_XFER_ON  0x4        /* Ultra DMA transfer in progress */
-#define            nULTRA_XFER_ON  0x0       
 #define               ULTRA_IN_FL  0xf0       /* Ultra DMA Input FIFO Level */
 
 /* Bit masks for ATAPI_DEV_ADDR */
 /* Bit masks for ATAPI_INT_MASK */
 
 #define        ATAPI_DEV_INT_MASK  0x1        /* Device interrupt mask */
-#define       nATAPI_DEV_INT_MASK  0x0       
 #define             PIO_DONE_MASK  0x2        /* PIO transfer done interrupt mask */
-#define            nPIO_DONE_MASK  0x0       
 #define           MULTI_DONE_MASK  0x4        /* Multi-DMA transfer done interrupt mask */
-#define          nMULTI_DONE_MASK  0x0       
 #define          UDMAIN_DONE_MASK  0x8        /* Ultra-DMA in transfer done interrupt mask */
-#define         nUDMAIN_DONE_MASK  0x0       
 #define         UDMAOUT_DONE_MASK  0x10       /* Ultra-DMA out transfer done interrupt mask */
-#define        nUDMAOUT_DONE_MASK  0x0       
 #define       HOST_TERM_XFER_MASK  0x20       /* Host terminate current transfer interrupt mask */
-#define      nHOST_TERM_XFER_MASK  0x0       
 #define           MULTI_TERM_MASK  0x40       /* Device terminate Multi-DMA transfer interrupt mask */
-#define          nMULTI_TERM_MASK  0x0       
 #define          UDMAIN_TERM_MASK  0x80       /* Device terminate Ultra-DMA-in transfer interrupt mask */
-#define         nUDMAIN_TERM_MASK  0x0       
 #define         UDMAOUT_TERM_MASK  0x100      /* Device terminate Ultra-DMA-out transfer interrupt mask */
-#define        nUDMAOUT_TERM_MASK  0x0       
 
 /* Bit masks for ATAPI_INT_STATUS */
 
 #define             ATAPI_DEV_INT  0x1        /* Device interrupt status */
-#define            nATAPI_DEV_INT  0x0       
 #define              PIO_DONE_INT  0x2        /* PIO transfer done interrupt status */
-#define             nPIO_DONE_INT  0x0       
 #define            MULTI_DONE_INT  0x4        /* Multi-DMA transfer done interrupt status */
-#define           nMULTI_DONE_INT  0x0       
 #define           UDMAIN_DONE_INT  0x8        /* Ultra-DMA in transfer done interrupt status */
-#define          nUDMAIN_DONE_INT  0x0       
 #define          UDMAOUT_DONE_INT  0x10       /* Ultra-DMA out transfer done interrupt status */
-#define         nUDMAOUT_DONE_INT  0x0       
 #define        HOST_TERM_XFER_INT  0x20       /* Host terminate current transfer interrupt status */
-#define       nHOST_TERM_XFER_INT  0x0       
 #define            MULTI_TERM_INT  0x40       /* Device terminate Multi-DMA transfer interrupt status */
-#define           nMULTI_TERM_INT  0x0       
 #define           UDMAIN_TERM_INT  0x80       /* Device terminate Ultra-DMA-in transfer interrupt status */
-#define          nUDMAIN_TERM_INT  0x0       
 #define          UDMAOUT_TERM_INT  0x100      /* Device terminate Ultra-DMA-out transfer interrupt status */
-#define         nUDMAOUT_TERM_INT  0x0       
 
 /* Bit masks for ATAPI_LINE_STATUS */
 
 #define                ATAPI_INTR  0x1        /* Device interrupt to host line status */
-#define               nATAPI_INTR  0x0       
 #define                ATAPI_DASP  0x2        /* Device dasp to host line status */
-#define               nATAPI_DASP  0x0       
 #define                ATAPI_CS0N  0x4        /* ATAPI chip select 0 line status */
-#define               nATAPI_CS0N  0x0       
 #define                ATAPI_CS1N  0x8        /* ATAPI chip select 1 line status */
-#define               nATAPI_CS1N  0x0       
 #define                ATAPI_ADDR  0x70       /* ATAPI address line status */
 #define              ATAPI_DMAREQ  0x80       /* ATAPI DMA request line status */
-#define             nATAPI_DMAREQ  0x0       
 #define             ATAPI_DMAACKN  0x100      /* ATAPI DMA acknowledge line status */
-#define            nATAPI_DMAACKN  0x0       
 #define               ATAPI_DIOWN  0x200      /* ATAPI write line status */
-#define              nATAPI_DIOWN  0x0       
 #define               ATAPI_DIORN  0x400      /* ATAPI read line status */
-#define              nATAPI_DIORN  0x0       
 #define               ATAPI_IORDY  0x800      /* ATAPI IORDY line status */
-#define              nATAPI_IORDY  0x0       
 
 /* Bit masks for ATAPI_SM_STATE */
 
 /* Bit masks for ATAPI_TERMINATE */
 
 #define           ATAPI_HOST_TERM  0x1        /* Host terminationation */
-#define          nATAPI_HOST_TERM  0x0       
 
 /* Bit masks for ATAPI_REG_TIM_0 */
 
 /* Bit masks for USB_POWER */
 
 #define           ENABLE_SUSPENDM  0x1        /* enable SuspendM output */
-#define          nENABLE_SUSPENDM  0x0       
 #define              SUSPEND_MODE  0x2        /* Suspend Mode indicator */
-#define             nSUSPEND_MODE  0x0       
 #define               RESUME_MODE  0x4        /* DMA Mode */
-#define              nRESUME_MODE  0x0       
 #define                     RESET  0x8        /* Reset indicator */
-#define                    nRESET  0x0       
 #define                   HS_MODE  0x10       /* High Speed mode indicator */
-#define                  nHS_MODE  0x0       
 #define                 HS_ENABLE  0x20       /* high Speed Enable */
-#define                nHS_ENABLE  0x0       
 #define                 SOFT_CONN  0x40       /* Soft connect */
-#define                nSOFT_CONN  0x0       
 #define                ISO_UPDATE  0x80       /* Isochronous update */
-#define               nISO_UPDATE  0x0       
 
 /* Bit masks for USB_INTRTX */
 
 #define                    EP0_TX  0x1        /* Tx Endpoint 0 interrupt */
-#define                   nEP0_TX  0x0       
 #define                    EP1_TX  0x2        /* Tx Endpoint 1 interrupt */
-#define                   nEP1_TX  0x0       
 #define                    EP2_TX  0x4        /* Tx Endpoint 2 interrupt */
-#define                   nEP2_TX  0x0       
 #define                    EP3_TX  0x8        /* Tx Endpoint 3 interrupt */
-#define                   nEP3_TX  0x0       
 #define                    EP4_TX  0x10       /* Tx Endpoint 4 interrupt */
-#define                   nEP4_TX  0x0       
 #define                    EP5_TX  0x20       /* Tx Endpoint 5 interrupt */
-#define                   nEP5_TX  0x0       
 #define                    EP6_TX  0x40       /* Tx Endpoint 6 interrupt */
-#define                   nEP6_TX  0x0       
 #define                    EP7_TX  0x80       /* Tx Endpoint 7 interrupt */
-#define                   nEP7_TX  0x0       
 
 /* Bit masks for USB_INTRRX */
 
 #define                    EP1_RX  0x2        /* Rx Endpoint 1 interrupt */
-#define                   nEP1_RX  0x0       
 #define                    EP2_RX  0x4        /* Rx Endpoint 2 interrupt */
-#define                   nEP2_RX  0x0       
 #define                    EP3_RX  0x8        /* Rx Endpoint 3 interrupt */
-#define                   nEP3_RX  0x0       
 #define                    EP4_RX  0x10       /* Rx Endpoint 4 interrupt */
-#define                   nEP4_RX  0x0       
 #define                    EP5_RX  0x20       /* Rx Endpoint 5 interrupt */
-#define                   nEP5_RX  0x0       
 #define                    EP6_RX  0x40       /* Rx Endpoint 6 interrupt */
-#define                   nEP6_RX  0x0       
 #define                    EP7_RX  0x80       /* Rx Endpoint 7 interrupt */
-#define                   nEP7_RX  0x0       
 
 /* Bit masks for USB_INTRTXE */
 
 #define                  EP0_TX_E  0x1        /* Endpoint 0 interrupt Enable */
-#define                 nEP0_TX_E  0x0       
 #define                  EP1_TX_E  0x2        /* Tx Endpoint 1 interrupt  Enable */
-#define                 nEP1_TX_E  0x0       
 #define                  EP2_TX_E  0x4        /* Tx Endpoint 2 interrupt  Enable */
-#define                 nEP2_TX_E  0x0       
 #define                  EP3_TX_E  0x8        /* Tx Endpoint 3 interrupt  Enable */
-#define                 nEP3_TX_E  0x0       
 #define                  EP4_TX_E  0x10       /* Tx Endpoint 4 interrupt  Enable */
-#define                 nEP4_TX_E  0x0       
 #define                  EP5_TX_E  0x20       /* Tx Endpoint 5 interrupt  Enable */
-#define                 nEP5_TX_E  0x0       
 #define                  EP6_TX_E  0x40       /* Tx Endpoint 6 interrupt  Enable */
-#define                 nEP6_TX_E  0x0       
 #define                  EP7_TX_E  0x80       /* Tx Endpoint 7 interrupt  Enable */
-#define                 nEP7_TX_E  0x0       
 
 /* Bit masks for USB_INTRRXE */
 
 #define                  EP1_RX_E  0x2        /* Rx Endpoint 1 interrupt  Enable */
-#define                 nEP1_RX_E  0x0       
 #define                  EP2_RX_E  0x4        /* Rx Endpoint 2 interrupt  Enable */
-#define                 nEP2_RX_E  0x0       
 #define                  EP3_RX_E  0x8        /* Rx Endpoint 3 interrupt  Enable */
-#define                 nEP3_RX_E  0x0       
 #define                  EP4_RX_E  0x10       /* Rx Endpoint 4 interrupt  Enable */
-#define                 nEP4_RX_E  0x0       
 #define                  EP5_RX_E  0x20       /* Rx Endpoint 5 interrupt  Enable */
-#define                 nEP5_RX_E  0x0       
 #define                  EP6_RX_E  0x40       /* Rx Endpoint 6 interrupt  Enable */
-#define                 nEP6_RX_E  0x0       
 #define                  EP7_RX_E  0x80       /* Rx Endpoint 7 interrupt  Enable */
-#define                 nEP7_RX_E  0x0       
 
 /* Bit masks for USB_INTRUSB */
 
 #define                 SUSPEND_B  0x1        /* Suspend indicator */
-#define                nSUSPEND_B  0x0       
 #define                  RESUME_B  0x2        /* Resume indicator */
-#define                 nRESUME_B  0x0       
 #define          RESET_OR_BABLE_B  0x4        /* Reset/babble indicator */
-#define         nRESET_OR_BABLE_B  0x0       
 #define                     SOF_B  0x8        /* Start of frame */
-#define                    nSOF_B  0x0       
 #define                    CONN_B  0x10       /* Connection indicator */
-#define                   nCONN_B  0x0       
 #define                  DISCON_B  0x20       /* Disconnect indicator */
-#define                 nDISCON_B  0x0       
 #define             SESSION_REQ_B  0x40       /* Session Request */
-#define            nSESSION_REQ_B  0x0       
 #define              VBUS_ERROR_B  0x80       /* Vbus threshold indicator */
-#define             nVBUS_ERROR_B  0x0       
 
 /* Bit masks for USB_INTRUSBE */
 
 #define                SUSPEND_BE  0x1        /* Suspend indicator int enable */
-#define               nSUSPEND_BE  0x0       
 #define                 RESUME_BE  0x2        /* Resume indicator int enable */
-#define                nRESUME_BE  0x0       
 #define         RESET_OR_BABLE_BE  0x4        /* Reset/babble indicator int enable */
-#define        nRESET_OR_BABLE_BE  0x0       
 #define                    SOF_BE  0x8        /* Start of frame int enable */
-#define                   nSOF_BE  0x0       
 #define                   CONN_BE  0x10       /* Connection indicator int enable */
-#define                  nCONN_BE  0x0       
 #define                 DISCON_BE  0x20       /* Disconnect indicator int enable */
-#define                nDISCON_BE  0x0       
 #define            SESSION_REQ_BE  0x40       /* Session Request int enable */
-#define           nSESSION_REQ_BE  0x0       
 #define             VBUS_ERROR_BE  0x80       /* Vbus threshold indicator int enable */
-#define            nVBUS_ERROR_BE  0x0       
 
 /* Bit masks for USB_FRAME */
 
 /* Bit masks for USB_GLOBAL_CTL */
 
 #define                GLOBAL_ENA  0x1        /* enables USB module */
-#define               nGLOBAL_ENA  0x0       
 #define                EP1_TX_ENA  0x2        /* Transmit endpoint 1 enable */
-#define               nEP1_TX_ENA  0x0       
 #define                EP2_TX_ENA  0x4        /* Transmit endpoint 2 enable */
-#define               nEP2_TX_ENA  0x0       
 #define                EP3_TX_ENA  0x8        /* Transmit endpoint 3 enable */
-#define               nEP3_TX_ENA  0x0       
 #define                EP4_TX_ENA  0x10       /* Transmit endpoint 4 enable */
-#define               nEP4_TX_ENA  0x0       
 #define                EP5_TX_ENA  0x20       /* Transmit endpoint 5 enable */
-#define               nEP5_TX_ENA  0x0       
 #define                EP6_TX_ENA  0x40       /* Transmit endpoint 6 enable */
-#define               nEP6_TX_ENA  0x0       
 #define                EP7_TX_ENA  0x80       /* Transmit endpoint 7 enable */
-#define               nEP7_TX_ENA  0x0       
 #define                EP1_RX_ENA  0x100      /* Receive endpoint 1 enable */
-#define               nEP1_RX_ENA  0x0       
 #define                EP2_RX_ENA  0x200      /* Receive endpoint 2 enable */
-#define               nEP2_RX_ENA  0x0       
 #define                EP3_RX_ENA  0x400      /* Receive endpoint 3 enable */
-#define               nEP3_RX_ENA  0x0       
 #define                EP4_RX_ENA  0x800      /* Receive endpoint 4 enable */
-#define               nEP4_RX_ENA  0x0       
 #define                EP5_RX_ENA  0x1000     /* Receive endpoint 5 enable */
-#define               nEP5_RX_ENA  0x0       
 #define                EP6_RX_ENA  0x2000     /* Receive endpoint 6 enable */
-#define               nEP6_RX_ENA  0x0       
 #define                EP7_RX_ENA  0x4000     /* Receive endpoint 7 enable */
-#define               nEP7_RX_ENA  0x0       
 
 /* Bit masks for USB_OTG_DEV_CTL */
 
 #define                   SESSION  0x1        /* session indicator */
-#define                  nSESSION  0x0       
 #define                  HOST_REQ  0x2        /* Host negotiation request */
-#define                 nHOST_REQ  0x0       
 #define                 HOST_MODE  0x4        /* indicates USBDRC is a host */
-#define                nHOST_MODE  0x0       
 #define                     VBUS0  0x8        /* Vbus level indicator[0] */
-#define                    nVBUS0  0x0       
 #define                     VBUS1  0x10       /* Vbus level indicator[1] */
-#define                    nVBUS1  0x0       
 #define                     LSDEV  0x20       /* Low-speed indicator */
-#define                    nLSDEV  0x0       
 #define                     FSDEV  0x40       /* Full or High-speed indicator */
-#define                    nFSDEV  0x0       
 #define                  B_DEVICE  0x80       /* A' or 'B' device indicator */
-#define                 nB_DEVICE  0x0       
 
 /* Bit masks for USB_OTG_VBUS_IRQ */
 
 #define             DRIVE_VBUS_ON  0x1        /* indicator to drive VBUS control circuit */
-#define            nDRIVE_VBUS_ON  0x0       
 #define            DRIVE_VBUS_OFF  0x2        /* indicator to shut off charge pump */
-#define           nDRIVE_VBUS_OFF  0x0       
 #define           CHRG_VBUS_START  0x4        /* indicator for external circuit to start charging VBUS */
-#define          nCHRG_VBUS_START  0x0       
 #define             CHRG_VBUS_END  0x8        /* indicator for external circuit to end charging VBUS */
-#define            nCHRG_VBUS_END  0x0       
 #define        DISCHRG_VBUS_START  0x10       /* indicator to start discharging VBUS */
-#define       nDISCHRG_VBUS_START  0x0       
 #define          DISCHRG_VBUS_END  0x20       /* indicator to stop discharging VBUS */
-#define         nDISCHRG_VBUS_END  0x0       
 
 /* Bit masks for USB_OTG_VBUS_MASK */
 
 #define         DRIVE_VBUS_ON_ENA  0x1        /* enable DRIVE_VBUS_ON interrupt */
-#define        nDRIVE_VBUS_ON_ENA  0x0       
 #define        DRIVE_VBUS_OFF_ENA  0x2        /* enable DRIVE_VBUS_OFF interrupt */
-#define       nDRIVE_VBUS_OFF_ENA  0x0       
 #define       CHRG_VBUS_START_ENA  0x4        /* enable CHRG_VBUS_START interrupt */
-#define      nCHRG_VBUS_START_ENA  0x0       
 #define         CHRG_VBUS_END_ENA  0x8        /* enable CHRG_VBUS_END interrupt */
-#define        nCHRG_VBUS_END_ENA  0x0       
 #define    DISCHRG_VBUS_START_ENA  0x10       /* enable DISCHRG_VBUS_START interrupt */
-#define   nDISCHRG_VBUS_START_ENA  0x0       
 #define      DISCHRG_VBUS_END_ENA  0x20       /* enable DISCHRG_VBUS_END interrupt */
-#define     nDISCHRG_VBUS_END_ENA  0x0       
 
 /* Bit masks for USB_CSR0 */
 
 #define                  RXPKTRDY  0x1        /* data packet receive indicator */
-#define                 nRXPKTRDY  0x0       
 #define                  TXPKTRDY  0x2        /* data packet in FIFO indicator */
-#define                 nTXPKTRDY  0x0       
 #define                STALL_SENT  0x4        /* STALL handshake sent */
-#define               nSTALL_SENT  0x0       
 #define                   DATAEND  0x8        /* Data end indicator */
-#define                  nDATAEND  0x0       
 #define                  SETUPEND  0x10       /* Setup end */
-#define                 nSETUPEND  0x0       
 #define                 SENDSTALL  0x20       /* Send STALL handshake */
-#define                nSENDSTALL  0x0       
 #define         SERVICED_RXPKTRDY  0x40       /* used to clear the RxPktRdy bit */
-#define        nSERVICED_RXPKTRDY  0x0       
 #define         SERVICED_SETUPEND  0x80       /* used to clear the SetupEnd bit */
-#define        nSERVICED_SETUPEND  0x0       
 #define                 FLUSHFIFO  0x100      /* flush endpoint FIFO */
-#define                nFLUSHFIFO  0x0       
 #define          STALL_RECEIVED_H  0x4        /* STALL handshake received host mode */
-#define         nSTALL_RECEIVED_H  0x0       
 #define                SETUPPKT_H  0x8        /* send Setup token host mode */
-#define               nSETUPPKT_H  0x0       
 #define                   ERROR_H  0x10       /* timeout error indicator host mode */
-#define                  nERROR_H  0x0       
 #define                  REQPKT_H  0x20       /* Request an IN transaction host mode */
-#define                 nREQPKT_H  0x0       
 #define               STATUSPKT_H  0x40       /* Status stage transaction host mode */
-#define              nSTATUSPKT_H  0x0       
 #define             NAK_TIMEOUT_H  0x80       /* EP0 halted after a NAK host mode */
-#define            nNAK_TIMEOUT_H  0x0       
 
 /* Bit masks for USB_COUNT0 */
 
 /* Bit masks for USB_TXCSR */
 
 #define                TXPKTRDY_T  0x1        /* data packet in FIFO indicator */
-#define               nTXPKTRDY_T  0x0       
 #define          FIFO_NOT_EMPTY_T  0x2        /* FIFO not empty */
-#define         nFIFO_NOT_EMPTY_T  0x0       
 #define                UNDERRUN_T  0x4        /* TxPktRdy not set  for an IN token */
-#define               nUNDERRUN_T  0x0       
 #define               FLUSHFIFO_T  0x8        /* flush endpoint FIFO */
-#define              nFLUSHFIFO_T  0x0       
 #define              STALL_SEND_T  0x10       /* issue a Stall handshake */
-#define             nSTALL_SEND_T  0x0       
 #define              STALL_SENT_T  0x20       /* Stall handshake transmitted */
-#define             nSTALL_SENT_T  0x0       
 #define        CLEAR_DATATOGGLE_T  0x40       /* clear endpoint data toggle */
-#define       nCLEAR_DATATOGGLE_T  0x0       
 #define                INCOMPTX_T  0x80       /* indicates that a large packet is split */
-#define               nINCOMPTX_T  0x0       
 #define              DMAREQMODE_T  0x400      /* DMA mode (0 or 1) selection */
-#define             nDMAREQMODE_T  0x0       
 #define        FORCE_DATATOGGLE_T  0x800      /* Force data toggle */
-#define       nFORCE_DATATOGGLE_T  0x0       
 #define              DMAREQ_ENA_T  0x1000     /* Enable DMA request for Tx EP */
-#define             nDMAREQ_ENA_T  0x0       
 #define                     ISO_T  0x4000     /* enable Isochronous transfers */
-#define                    nISO_T  0x0       
 #define                 AUTOSET_T  0x8000     /* allows TxPktRdy to be set automatically */
-#define                nAUTOSET_T  0x0       
 #define                  ERROR_TH  0x4        /* error condition host mode */
-#define                 nERROR_TH  0x0       
 #define         STALL_RECEIVED_TH  0x20       /* Stall handshake received host mode */
-#define        nSTALL_RECEIVED_TH  0x0       
 #define            NAK_TIMEOUT_TH  0x80       /* NAK timeout host mode */
-#define           nNAK_TIMEOUT_TH  0x0       
 
 /* Bit masks for USB_TXCOUNT */
 
 /* Bit masks for USB_RXCSR */
 
 #define                RXPKTRDY_R  0x1        /* data packet in FIFO indicator */
-#define               nRXPKTRDY_R  0x0       
 #define               FIFO_FULL_R  0x2        /* FIFO not empty */
-#define              nFIFO_FULL_R  0x0       
 #define                 OVERRUN_R  0x4        /* TxPktRdy not set  for an IN token */
-#define                nOVERRUN_R  0x0       
 #define               DATAERROR_R  0x8        /* Out packet cannot be loaded into Rx  FIFO */
-#define              nDATAERROR_R  0x0       
 #define               FLUSHFIFO_R  0x10       /* flush endpoint FIFO */
-#define              nFLUSHFIFO_R  0x0       
 #define              STALL_SEND_R  0x20       /* issue a Stall handshake */
-#define             nSTALL_SEND_R  0x0       
 #define              STALL_SENT_R  0x40       /* Stall handshake transmitted */
-#define             nSTALL_SENT_R  0x0       
 #define        CLEAR_DATATOGGLE_R  0x80       /* clear endpoint data toggle */
-#define       nCLEAR_DATATOGGLE_R  0x0       
 #define                INCOMPRX_R  0x100      /* indicates that a large packet is split */
-#define               nINCOMPRX_R  0x0       
 #define              DMAREQMODE_R  0x800      /* DMA mode (0 or 1) selection */
-#define             nDMAREQMODE_R  0x0       
 #define                 DISNYET_R  0x1000     /* disable Nyet handshakes */
-#define                nDISNYET_R  0x0       
 #define              DMAREQ_ENA_R  0x2000     /* Enable DMA request for Tx EP */
-#define             nDMAREQ_ENA_R  0x0       
 #define                     ISO_R  0x4000     /* enable Isochronous transfers */
-#define                    nISO_R  0x0       
 #define               AUTOCLEAR_R  0x8000     /* allows TxPktRdy to be set automatically */
-#define              nAUTOCLEAR_R  0x0       
 #define                  ERROR_RH  0x4        /* TxPktRdy not set  for an IN token host mode */
-#define                 nERROR_RH  0x0       
 #define                 REQPKT_RH  0x20       /* request an IN transaction host mode */
-#define                nREQPKT_RH  0x0       
 #define         STALL_RECEIVED_RH  0x40       /* Stall handshake received host mode */
-#define        nSTALL_RECEIVED_RH  0x0       
 #define               INCOMPRX_RH  0x100      /* indicates that a large packet is split host mode */
-#define              nINCOMPRX_RH  0x0       
 #define             DMAREQMODE_RH  0x800      /* DMA mode (0 or 1) selection host mode */
-#define            nDMAREQMODE_RH  0x0       
 #define                AUTOREQ_RH  0x4000     /* sets ReqPkt automatically host mode */
-#define               nAUTOREQ_RH  0x0       
 
 /* Bit masks for USB_RXCOUNT */
 
 /* Bit masks for USB_DMA_INTERRUPT */
 
 #define                  DMA0_INT  0x1        /* DMA0 pending interrupt */
-#define                 nDMA0_INT  0x0       
 #define                  DMA1_INT  0x2        /* DMA1 pending interrupt */
-#define                 nDMA1_INT  0x0       
 #define                  DMA2_INT  0x4        /* DMA2 pending interrupt */
-#define                 nDMA2_INT  0x0       
 #define                  DMA3_INT  0x8        /* DMA3 pending interrupt */
-#define                 nDMA3_INT  0x0       
 #define                  DMA4_INT  0x10       /* DMA4 pending interrupt */
-#define                 nDMA4_INT  0x0       
 #define                  DMA5_INT  0x20       /* DMA5 pending interrupt */
-#define                 nDMA5_INT  0x0       
 #define                  DMA6_INT  0x40       /* DMA6 pending interrupt */
-#define                 nDMA6_INT  0x0       
 #define                  DMA7_INT  0x80       /* DMA7 pending interrupt */
-#define                 nDMA7_INT  0x0       
 
 /* Bit masks for USB_DMAxCONTROL */
 
 #define                   DMA_ENA  0x1        /* DMA enable */
-#define                  nDMA_ENA  0x0       
 #define                 DIRECTION  0x2        /* direction of DMA transfer */
-#define                nDIRECTION  0x0       
 #define                      MODE  0x4        /* DMA Bus error */
-#define                     nMODE  0x0       
 #define                   INT_ENA  0x8        /* Interrupt enable */
-#define                  nINT_ENA  0x0       
 #define                     EPNUM  0xf0       /* EP number */
 #define                  BUSERROR  0x100      /* DMA Bus error */
-#define                 nBUSERROR  0x0       
 
 /* Bit masks for USB_DMAxADDRHIGH */
 
index 8fc77ea12aa91a6bd16cb8c90c92f603d9adda0c..dd955dcd39b8949cb4aafd20e52b333c80386b32 100644 (file)
 /* Bit masks for PIXC_CTL */
 
 #define                   PIXC_EN  0x1        /* Pixel Compositor Enable */
-#define                  nPIXC_EN  0x0       
 #define                  OVR_A_EN  0x2        /* Overlay A Enable */
-#define                 nOVR_A_EN  0x0       
 #define                  OVR_B_EN  0x4        /* Overlay B Enable */
-#define                 nOVR_B_EN  0x0       
 #define                  IMG_FORM  0x8        /* Image Data Format */
-#define                 nIMG_FORM  0x0       
 #define                  OVR_FORM  0x10       /* Overlay Data Format */
-#define                 nOVR_FORM  0x0       
 #define                  OUT_FORM  0x20       /* Output Data Format */
-#define                 nOUT_FORM  0x0       
 #define                   UDS_MOD  0x40       /* Resampling Mode */
-#define                  nUDS_MOD  0x0       
 #define                     TC_EN  0x80       /* Transparent Color Enable */
-#define                    nTC_EN  0x0       
 #define                  IMG_STAT  0x300      /* Image FIFO Status */
 #define                  OVR_STAT  0xc00      /* Overlay FIFO Status */
 #define                    WM_LVL  0x3000     /* FIFO Watermark Level */
 /* Bit masks for PIXC_INTRSTAT */
 
 #define                OVR_INT_EN  0x1        /* Interrupt at End of Last Valid Overlay */
-#define               nOVR_INT_EN  0x0       
 #define                FRM_INT_EN  0x2        /* Interrupt at End of Frame */
-#define               nFRM_INT_EN  0x0       
 #define              OVR_INT_STAT  0x4        /* Overlay Interrupt Status */
-#define             nOVR_INT_STAT  0x0       
 #define              FRM_INT_STAT  0x8        /* Frame Interrupt Status */
-#define             nFRM_INT_STAT  0x0       
 
 /* Bit masks for PIXC_RYCON */
 
 #define                       A12  0xffc00    /* A12 in the Coefficient Matrix */
 #define                       A13  0x3ff00000 /* A13 in the Coefficient Matrix */
 #define                  RY_MULT4  0x40000000 /* Multiply Row by 4 */
-#define                 nRY_MULT4  0x0       
 
 /* Bit masks for PIXC_GUCON */
 
 #define                       A22  0xffc00    /* A22 in the Coefficient Matrix */
 #define                       A23  0x3ff00000 /* A23 in the Coefficient Matrix */
 #define                  GU_MULT4  0x40000000 /* Multiply Row by 4 */
-#define                 nGU_MULT4  0x0       
 
 /* Bit masks for PIXC_BVCON */
 
 #define                       A32  0xffc00    /* A32 in the Coefficient Matrix */
 #define                       A33  0x3ff00000 /* A33 in the Coefficient Matrix */
 #define                  BV_MULT4  0x40000000 /* Multiply Row by 4 */
-#define                 nBV_MULT4  0x0       
 
 /* Bit masks for PIXC_CCBIAS */
 
 /* Bit masks for HOST_CONTROL */
 
 #define                   HOST_EN  0x1        /* Host Enable */
-#define                  nHOST_EN  0x0       
 #define                  HOST_END  0x2        /* Host Endianess */
-#define                 nHOST_END  0x0       
 #define                 DATA_SIZE  0x4        /* Data Size */
-#define                nDATA_SIZE  0x0       
 #define                  HOST_RST  0x8        /* Host Reset */
-#define                 nHOST_RST  0x0       
 #define                  HRDY_OVR  0x20       /* Host Ready Override */
-#define                 nHRDY_OVR  0x0       
 #define                  INT_MODE  0x40       /* Interrupt Mode */
-#define                 nINT_MODE  0x0       
 #define                     BT_EN  0x80       /* Bus Timeout Enable */
-#define                    nBT_EN  0x0       
 #define                       EHW  0x100      /* Enable Host Write */
-#define                      nEHW  0x0       
 #define                       EHR  0x200      /* Enable Host Read */
-#define                      nEHR  0x0       
 #define                       BDR  0x400      /* Burst DMA Requests */
-#define                      nBDR  0x0       
 
 /* Bit masks for HOST_STATUS */
 
 #define                     READY  0x1        /* DMA Ready */
-#define                    nREADY  0x0       
 #define                  FIFOFULL  0x2        /* FIFO Full */
-#define                 nFIFOFULL  0x0       
 #define                 FIFOEMPTY  0x4        /* FIFO Empty */
-#define                nFIFOEMPTY  0x0       
 #define                  COMPLETE  0x8        /* DMA Complete */
-#define                 nCOMPLETE  0x0       
 #define                      HSHK  0x10       /* Host Handshake */
-#define                     nHSHK  0x0       
 #define                   TIMEOUT  0x20       /* Host Timeout */
-#define                  nTIMEOUT  0x0       
 #define                      HIRQ  0x40       /* Host Interrupt Request */
-#define                     nHIRQ  0x0       
 #define                ALLOW_CNFG  0x80       /* Allow New Configuration */
-#define               nALLOW_CNFG  0x0       
 #define                   DMA_DIR  0x100      /* DMA Direction */
-#define                  nDMA_DIR  0x0       
 #define                       BTE  0x200      /* Bus Timeout Enabled */
-#define                      nBTE  0x0       
 
 /* Bit masks for HOST_TIMEOUT */
 
 /* Bit masks for TIMER_ENABLE1 */
 
 #define                    TIMEN8  0x1        /* Timer 8 Enable */
-#define                   nTIMEN8  0x0       
 #define                    TIMEN9  0x2        /* Timer 9 Enable */
-#define                   nTIMEN9  0x0       
 #define                   TIMEN10  0x4        /* Timer 10 Enable */
-#define                  nTIMEN10  0x0       
 
 /* Bit masks for TIMER_DISABLE1 */
 
 #define                   TIMDIS8  0x1        /* Timer 8 Disable */
-#define                  nTIMDIS8  0x0       
 #define                   TIMDIS9  0x2        /* Timer 9 Disable */
-#define                  nTIMDIS9  0x0       
 #define                  TIMDIS10  0x4        /* Timer 10 Disable */
-#define                 nTIMDIS10  0x0       
 
 /* Bit masks for TIMER_STATUS1 */
 
 #define                    TIMIL8  0x1        /* Timer 8 Interrupt */
-#define                   nTIMIL8  0x0       
 #define                    TIMIL9  0x2        /* Timer 9 Interrupt */
-#define                   nTIMIL9  0x0       
 #define                   TIMIL10  0x4        /* Timer 10 Interrupt */
-#define                  nTIMIL10  0x0       
 #define                 TOVF_ERR8  0x10       /* Timer 8 Counter Overflow */
-#define                nTOVF_ERR8  0x0       
 #define                 TOVF_ERR9  0x20       /* Timer 9 Counter Overflow */
-#define                nTOVF_ERR9  0x0       
 #define                TOVF_ERR10  0x40       /* Timer 10 Counter Overflow */
-#define               nTOVF_ERR10  0x0       
 #define                     TRUN8  0x1000     /* Timer 8 Slave Enable Status */
-#define                    nTRUN8  0x0       
 #define                     TRUN9  0x2000     /* Timer 9 Slave Enable Status */
-#define                    nTRUN9  0x0       
 #define                    TRUN10  0x4000     /* Timer 10 Slave Enable Status */
-#define                   nTRUN10  0x0       
 
 /* Bit masks for EPPI0 are obtained from common base header for EPPIx (EPPI1 and EPPI2) */
 
 /* Bit masks for HMDMAx_CONTROL */
 
 #define                   HMDMAEN  0x1        /* Handshake MDMA Enable */
-#define                  nHMDMAEN  0x0       
 #define                       REP  0x2        /* Handshake MDMA Request Polarity */
-#define                      nREP  0x0       
 #define                       UTE  0x8        /* Urgency Threshold Enable */
-#define                      nUTE  0x0       
 #define                       OIE  0x10       /* Overflow Interrupt Enable */
-#define                      nOIE  0x0       
 #define                      BDIE  0x20       /* Block Done Interrupt Enable */
-#define                     nBDIE  0x0       
 #define                      MBDI  0x40       /* Mask Block Done Interrupt */
-#define                     nMBDI  0x0       
 #define                       DRQ  0x300      /* Handshake MDMA Request Type */
 #define                       RBC  0x1000     /* Force Reload of BCOUNT */
-#define                      nRBC  0x0       
 #define                        PS  0x2000     /* Pin Status */
-#define                       nPS  0x0       
 #define                        OI  0x4000     /* Overflow Interrupt Generated */
-#define                       nOI  0x0       
 #define                       BDI  0x8000     /* Block Done Interrupt Generated */
-#define                      nBDI  0x0       
 
 /* ******************************************* */
 /*     MULTI BIT MACRO ENUMERATIONS            */
index d9e3062a9117d061e97482c95b65fab8870d0cea..8d4214e0807ccac3d58b90b5ae277f5b21569d9a 100644 (file)
 /* Bit masks for PIXC_CTL */
 
 #define                   PIXC_EN  0x1        /* Pixel Compositor Enable */
-#define                  nPIXC_EN  0x0       
 #define                  OVR_A_EN  0x2        /* Overlay A Enable */
-#define                 nOVR_A_EN  0x0       
 #define                  OVR_B_EN  0x4        /* Overlay B Enable */
-#define                 nOVR_B_EN  0x0       
 #define                  IMG_FORM  0x8        /* Image Data Format */
-#define                 nIMG_FORM  0x0       
 #define                  OVR_FORM  0x10       /* Overlay Data Format */
-#define                 nOVR_FORM  0x0       
 #define                  OUT_FORM  0x20       /* Output Data Format */
-#define                 nOUT_FORM  0x0       
 #define                   UDS_MOD  0x40       /* Resampling Mode */
-#define                  nUDS_MOD  0x0       
 #define                     TC_EN  0x80       /* Transparent Color Enable */
-#define                    nTC_EN  0x0       
 #define                  IMG_STAT  0x300      /* Image FIFO Status */
 #define                  OVR_STAT  0xc00      /* Overlay FIFO Status */
 #define                    WM_LVL  0x3000     /* FIFO Watermark Level */
 /* Bit masks for PIXC_INTRSTAT */
 
 #define                OVR_INT_EN  0x1        /* Interrupt at End of Last Valid Overlay */
-#define               nOVR_INT_EN  0x0       
 #define                FRM_INT_EN  0x2        /* Interrupt at End of Frame */
-#define               nFRM_INT_EN  0x0       
 #define              OVR_INT_STAT  0x4        /* Overlay Interrupt Status */
-#define             nOVR_INT_STAT  0x0       
 #define              FRM_INT_STAT  0x8        /* Frame Interrupt Status */
-#define             nFRM_INT_STAT  0x0       
 
 /* Bit masks for PIXC_RYCON */
 
 #define                       A12  0xffc00    /* A12 in the Coefficient Matrix */
 #define                       A13  0x3ff00000 /* A13 in the Coefficient Matrix */
 #define                  RY_MULT4  0x40000000 /* Multiply Row by 4 */
-#define                 nRY_MULT4  0x0       
 
 /* Bit masks for PIXC_GUCON */
 
 #define                       A22  0xffc00    /* A22 in the Coefficient Matrix */
 #define                       A23  0x3ff00000 /* A23 in the Coefficient Matrix */
 #define                  GU_MULT4  0x40000000 /* Multiply Row by 4 */
-#define                 nGU_MULT4  0x0       
 
 /* Bit masks for PIXC_BVCON */
 
 #define                       A32  0xffc00    /* A32 in the Coefficient Matrix */
 #define                       A33  0x3ff00000 /* A33 in the Coefficient Matrix */
 #define                  BV_MULT4  0x40000000 /* Multiply Row by 4 */
-#define                 nBV_MULT4  0x0       
 
 /* Bit masks for PIXC_CCBIAS */
 
 /* Bit masks for HOST_CONTROL */
 
 #define                   HOST_EN  0x1        /* Host Enable */
-#define                  nHOST_EN  0x0       
 #define                  HOST_END  0x2        /* Host Endianess */
-#define                 nHOST_END  0x0       
 #define                 DATA_SIZE  0x4        /* Data Size */
-#define                nDATA_SIZE  0x0       
 #define                  HOST_RST  0x8        /* Host Reset */
-#define                 nHOST_RST  0x0       
 #define                  HRDY_OVR  0x20       /* Host Ready Override */
-#define                 nHRDY_OVR  0x0       
 #define                  INT_MODE  0x40       /* Interrupt Mode */
-#define                 nINT_MODE  0x0       
 #define                     BT_EN  0x80       /* Bus Timeout Enable */
-#define                    nBT_EN  0x0       
 #define                       EHW  0x100      /* Enable Host Write */
-#define                      nEHW  0x0       
 #define                       EHR  0x200      /* Enable Host Read */
-#define                      nEHR  0x0       
 #define                       BDR  0x400      /* Burst DMA Requests */
-#define                      nBDR  0x0       
 
 /* Bit masks for HOST_STATUS */
 
 #define                     READY  0x1        /* DMA Ready */
-#define                    nREADY  0x0       
 #define                  FIFOFULL  0x2        /* FIFO Full */
-#define                 nFIFOFULL  0x0       
 #define                 FIFOEMPTY  0x4        /* FIFO Empty */
-#define                nFIFOEMPTY  0x0       
 #define                  COMPLETE  0x8        /* DMA Complete */
-#define                 nCOMPLETE  0x0       
 #define                      HSHK  0x10       /* Host Handshake */
-#define                     nHSHK  0x0       
 #define                   TIMEOUT  0x20       /* Host Timeout */
-#define                  nTIMEOUT  0x0       
 #define                      HIRQ  0x40       /* Host Interrupt Request */
-#define                     nHIRQ  0x0       
 #define                ALLOW_CNFG  0x80       /* Allow New Configuration */
-#define               nALLOW_CNFG  0x0       
 #define                   DMA_DIR  0x100      /* DMA Direction */
-#define                  nDMA_DIR  0x0       
 #define                       BTE  0x200      /* Bus Timeout Enabled */
-#define                      nBTE  0x0       
 
 /* Bit masks for HOST_TIMEOUT */
 
 /* Bit masks for KPAD_CTL */
 
 #define                   KPAD_EN  0x1        /* Keypad Enable */
-#define                  nKPAD_EN  0x0       
 #define              KPAD_IRQMODE  0x6        /* Key Press Interrupt Enable */
 #define                KPAD_ROWEN  0x1c00     /* Row Enable Width */
 #define                KPAD_COLEN  0xe000     /* Column Enable Width */
 /* Bit masks for KPAD_STAT */
 
 #define                  KPAD_IRQ  0x1        /* Keypad Interrupt Status */
-#define                 nKPAD_IRQ  0x0       
 #define              KPAD_MROWCOL  0x6        /* Multiple Row/Column Keypress Status */
 #define              KPAD_PRESSED  0x8        /* Key press current status */
-#define             nKPAD_PRESSED  0x0       
 
 /* Bit masks for KPAD_SOFTEVAL */
 
 #define           KPAD_SOFTEVAL_E  0x2        /* Software Programmable Force Evaluate */
-#define          nKPAD_SOFTEVAL_E  0x0       
 
 /* Bit masks for SDH_COMMAND */
 
 #define                   CMD_IDX  0x3f       /* Command Index */
 #define                   CMD_RSP  0x40       /* Response */
-#define                  nCMD_RSP  0x0       
 #define                 CMD_L_RSP  0x80       /* Long Response */
-#define                nCMD_L_RSP  0x0       
 #define                 CMD_INT_E  0x100      /* Command Interrupt */
-#define                nCMD_INT_E  0x0       
 #define                CMD_PEND_E  0x200      /* Command Pending */
-#define               nCMD_PEND_E  0x0       
 #define                     CMD_E  0x400      /* Command Enable */
-#define                    nCMD_E  0x0       
 
 /* Bit masks for SDH_PWR_CTL */
 
 #define                       TBD  0x3c       /* TBD */
 #endif
 #define                 SD_CMD_OD  0x40       /* Open Drain Output */
-#define                nSD_CMD_OD  0x0       
 #define                   ROD_CTL  0x80       /* Rod Control */
-#define                  nROD_CTL  0x0       
 
 /* Bit masks for SDH_CLK_CTL */
 
 #define                    CLKDIV  0xff       /* MC_CLK Divisor */
 #define                     CLK_E  0x100      /* MC_CLK Bus Clock Enable */
-#define                    nCLK_E  0x0       
 #define                  PWR_SV_E  0x200      /* Power Save Enable */
-#define                 nPWR_SV_E  0x0       
 #define             CLKDIV_BYPASS  0x400      /* Bypass Divisor */
-#define            nCLKDIV_BYPASS  0x0       
 #define                  WIDE_BUS  0x800      /* Wide Bus Mode Enable */
-#define                 nWIDE_BUS  0x0       
 
 /* Bit masks for SDH_RESP_CMD */
 
 /* Bit masks for SDH_DATA_CTL */
 
 #define                     DTX_E  0x1        /* Data Transfer Enable */
-#define                    nDTX_E  0x0       
 #define                   DTX_DIR  0x2        /* Data Transfer Direction */
-#define                  nDTX_DIR  0x0       
 #define                  DTX_MODE  0x4        /* Data Transfer Mode */
-#define                 nDTX_MODE  0x0       
 #define                 DTX_DMA_E  0x8        /* Data Transfer DMA Enable */
-#define                nDTX_DMA_E  0x0       
 #define              DTX_BLK_LGTH  0xf0       /* Data Transfer Block Length */
 
 /* Bit masks for SDH_STATUS */
 
 #define              CMD_CRC_FAIL  0x1        /* CMD CRC Fail */
-#define             nCMD_CRC_FAIL  0x0       
 #define              DAT_CRC_FAIL  0x2        /* Data CRC Fail */
-#define             nDAT_CRC_FAIL  0x0       
 #define               CMD_TIMEOUT  0x4        /* CMD Time Out */
-#define              nCMD_TIMEOUT  0x0       
 #define               DAT_TIMEOUT  0x8        /* Data Time Out */
-#define              nDAT_TIMEOUT  0x0       
 #define               TX_UNDERRUN  0x10       /* Transmit Underrun */
-#define              nTX_UNDERRUN  0x0       
 #define                RX_OVERRUN  0x20       /* Receive Overrun */
-#define               nRX_OVERRUN  0x0       
 #define              CMD_RESP_END  0x40       /* CMD Response End */
-#define             nCMD_RESP_END  0x0       
 #define                  CMD_SENT  0x80       /* CMD Sent */
-#define                 nCMD_SENT  0x0       
 #define                   DAT_END  0x100      /* Data End */
-#define                  nDAT_END  0x0       
 #define             START_BIT_ERR  0x200      /* Start Bit Error */
-#define            nSTART_BIT_ERR  0x0       
 #define               DAT_BLK_END  0x400      /* Data Block End */
-#define              nDAT_BLK_END  0x0       
 #define                   CMD_ACT  0x800      /* CMD Active */
-#define                  nCMD_ACT  0x0       
 #define                    TX_ACT  0x1000     /* Transmit Active */
-#define                   nTX_ACT  0x0       
 #define                    RX_ACT  0x2000     /* Receive Active */
-#define                   nRX_ACT  0x0       
 #define              TX_FIFO_STAT  0x4000     /* Transmit FIFO Status */
-#define             nTX_FIFO_STAT  0x0       
 #define              RX_FIFO_STAT  0x8000     /* Receive FIFO Status */
-#define             nRX_FIFO_STAT  0x0       
 #define              TX_FIFO_FULL  0x10000    /* Transmit FIFO Full */
-#define             nTX_FIFO_FULL  0x0       
 #define              RX_FIFO_FULL  0x20000    /* Receive FIFO Full */
-#define             nRX_FIFO_FULL  0x0       
 #define              TX_FIFO_ZERO  0x40000    /* Transmit FIFO Empty */
-#define             nTX_FIFO_ZERO  0x0       
 #define               RX_DAT_ZERO  0x80000    /* Receive FIFO Empty */
-#define              nRX_DAT_ZERO  0x0       
 #define                TX_DAT_RDY  0x100000   /* Transmit Data Available */
-#define               nTX_DAT_RDY  0x0       
 #define               RX_FIFO_RDY  0x200000   /* Receive Data Available */
-#define              nRX_FIFO_RDY  0x0       
 
 /* Bit masks for SDH_STATUS_CLR */
 
 #define         CMD_CRC_FAIL_STAT  0x1        /* CMD CRC Fail Status */
-#define        nCMD_CRC_FAIL_STAT  0x0       
 #define         DAT_CRC_FAIL_STAT  0x2        /* Data CRC Fail Status */
-#define        nDAT_CRC_FAIL_STAT  0x0       
 #define          CMD_TIMEOUT_STAT  0x4        /* CMD Time Out Status */
-#define         nCMD_TIMEOUT_STAT  0x0       
 #define          DAT_TIMEOUT_STAT  0x8        /* Data Time Out status */
-#define         nDAT_TIMEOUT_STAT  0x0       
 #define          TX_UNDERRUN_STAT  0x10       /* Transmit Underrun Status */
-#define         nTX_UNDERRUN_STAT  0x0       
 #define           RX_OVERRUN_STAT  0x20       /* Receive Overrun Status */
-#define          nRX_OVERRUN_STAT  0x0       
 #define         CMD_RESP_END_STAT  0x40       /* CMD Response End Status */
-#define        nCMD_RESP_END_STAT  0x0       
 #define             CMD_SENT_STAT  0x80       /* CMD Sent Status */
-#define            nCMD_SENT_STAT  0x0       
 #define              DAT_END_STAT  0x100      /* Data End Status */
-#define             nDAT_END_STAT  0x0       
 #define        START_BIT_ERR_STAT  0x200      /* Start Bit Error Status */
-#define       nSTART_BIT_ERR_STAT  0x0       
 #define          DAT_BLK_END_STAT  0x400      /* Data Block End Status */
-#define         nDAT_BLK_END_STAT  0x0       
 
 /* Bit masks for SDH_MASK0 */
 
 #define         CMD_CRC_FAIL_MASK  0x1        /* CMD CRC Fail Mask */
-#define        nCMD_CRC_FAIL_MASK  0x0       
 #define         DAT_CRC_FAIL_MASK  0x2        /* Data CRC Fail Mask */
-#define        nDAT_CRC_FAIL_MASK  0x0       
 #define          CMD_TIMEOUT_MASK  0x4        /* CMD Time Out Mask */
-#define         nCMD_TIMEOUT_MASK  0x0       
 #define          DAT_TIMEOUT_MASK  0x8        /* Data Time Out Mask */
-#define         nDAT_TIMEOUT_MASK  0x0       
 #define          TX_UNDERRUN_MASK  0x10       /* Transmit Underrun Mask */
-#define         nTX_UNDERRUN_MASK  0x0       
 #define           RX_OVERRUN_MASK  0x20       /* Receive Overrun Mask */
-#define          nRX_OVERRUN_MASK  0x0       
 #define         CMD_RESP_END_MASK  0x40       /* CMD Response End Mask */
-#define        nCMD_RESP_END_MASK  0x0       
 #define             CMD_SENT_MASK  0x80       /* CMD Sent Mask */
-#define            nCMD_SENT_MASK  0x0       
 #define              DAT_END_MASK  0x100      /* Data End Mask */
-#define             nDAT_END_MASK  0x0       
 #define        START_BIT_ERR_MASK  0x200      /* Start Bit Error Mask */
-#define       nSTART_BIT_ERR_MASK  0x0       
 #define          DAT_BLK_END_MASK  0x400      /* Data Block End Mask */
-#define         nDAT_BLK_END_MASK  0x0       
 #define              CMD_ACT_MASK  0x800      /* CMD Active Mask */
-#define             nCMD_ACT_MASK  0x0       
 #define               TX_ACT_MASK  0x1000     /* Transmit Active Mask */
-#define              nTX_ACT_MASK  0x0       
 #define               RX_ACT_MASK  0x2000     /* Receive Active Mask */
-#define              nRX_ACT_MASK  0x0       
 #define         TX_FIFO_STAT_MASK  0x4000     /* Transmit FIFO Status Mask */
-#define        nTX_FIFO_STAT_MASK  0x0       
 #define         RX_FIFO_STAT_MASK  0x8000     /* Receive FIFO Status Mask */
-#define        nRX_FIFO_STAT_MASK  0x0       
 #define         TX_FIFO_FULL_MASK  0x10000    /* Transmit FIFO Full Mask */
-#define        nTX_FIFO_FULL_MASK  0x0       
 #define         RX_FIFO_FULL_MASK  0x20000    /* Receive FIFO Full Mask */
-#define        nRX_FIFO_FULL_MASK  0x0       
 #define         TX_FIFO_ZERO_MASK  0x40000    /* Transmit FIFO Empty Mask */
-#define        nTX_FIFO_ZERO_MASK  0x0       
 #define          RX_DAT_ZERO_MASK  0x80000    /* Receive FIFO Empty Mask */
-#define         nRX_DAT_ZERO_MASK  0x0       
 #define           TX_DAT_RDY_MASK  0x100000   /* Transmit Data Available Mask */
-#define          nTX_DAT_RDY_MASK  0x0       
 #define          RX_FIFO_RDY_MASK  0x200000   /* Receive Data Available Mask */
-#define         nRX_FIFO_RDY_MASK  0x0       
 
 /* Bit masks for SDH_FIFO_CNT */
 
 /* Bit masks for SDH_E_STATUS */
 
 #define              SDIO_INT_DET  0x2        /* SDIO Int Detected */
-#define             nSDIO_INT_DET  0x0       
 #define               SD_CARD_DET  0x10       /* SD Card Detect */
-#define              nSD_CARD_DET  0x0       
 
 /* Bit masks for SDH_E_MASK */
 
 #define                  SDIO_MSK  0x2        /* Mask SDIO Int Detected */
-#define                 nSDIO_MSK  0x0       
 #define                   SCD_MSK  0x40       /* Mask Card Detect */
-#define                  nSCD_MSK  0x0       
 
 /* Bit masks for SDH_CFG */
 
 #define                   CLKS_EN  0x1        /* Clocks Enable */
-#define                  nCLKS_EN  0x0       
 #define                      SD4E  0x4        /* SDIO 4-Bit Enable */
-#define                     nSD4E  0x0       
 #define                       MWE  0x8        /* Moving Window Enable */
-#define                      nMWE  0x0       
 #define                    SD_RST  0x10       /* SDMMC Reset */
-#define                   nSD_RST  0x0       
 #define                 PUP_SDDAT  0x20       /* Pull-up SD_DAT */
-#define                nPUP_SDDAT  0x0       
 #define                PUP_SDDAT3  0x40       /* Pull-up SD_DAT3 */
-#define               nPUP_SDDAT3  0x0       
 #define                 PD_SDDAT3  0x80       /* Pull-down SD_DAT3 */
-#define                nPD_SDDAT3  0x0       
 
 /* Bit masks for SDH_RD_WAIT_EN */
 
 #define                       RWR  0x1        /* Read Wait Request */
-#define                      nRWR  0x0       
 
 /* Bit masks for ATAPI_CONTROL */
 
 #define                 PIO_START  0x1        /* Start PIO/Reg Op */
-#define                nPIO_START  0x0       
 #define               MULTI_START  0x2        /* Start Multi-DMA Op */
-#define              nMULTI_START  0x0       
 #define               ULTRA_START  0x4        /* Start Ultra-DMA Op */
-#define              nULTRA_START  0x0       
 #define                  XFER_DIR  0x8        /* Transfer Direction */
-#define                 nXFER_DIR  0x0       
 #define                  IORDY_EN  0x10       /* IORDY Enable */
-#define                 nIORDY_EN  0x0       
 #define                FIFO_FLUSH  0x20       /* Flush FIFOs */
-#define               nFIFO_FLUSH  0x0       
 #define                  SOFT_RST  0x40       /* Soft Reset */
-#define                 nSOFT_RST  0x0       
 #define                   DEV_RST  0x80       /* Device Reset */
-#define                  nDEV_RST  0x0       
 #define                TFRCNT_RST  0x100      /* Trans Count Reset */
-#define               nTFRCNT_RST  0x0       
 #define               END_ON_TERM  0x200      /* End/Terminate Select */
-#define              nEND_ON_TERM  0x0       
 #define               PIO_USE_DMA  0x400      /* PIO-DMA Enable */
-#define              nPIO_USE_DMA  0x0       
 #define          UDMAIN_FIFO_THRS  0xf000     /* Ultra DMA-IN FIFO Threshold */
 
 /* Bit masks for ATAPI_STATUS */
 
 #define               PIO_XFER_ON  0x1        /* PIO transfer in progress */
-#define              nPIO_XFER_ON  0x0       
 #define             MULTI_XFER_ON  0x2        /* Multi-word DMA transfer in progress */
-#define            nMULTI_XFER_ON  0x0       
 #define             ULTRA_XFER_ON  0x4        /* Ultra DMA transfer in progress */
-#define            nULTRA_XFER_ON  0x0       
 #define               ULTRA_IN_FL  0xf0       /* Ultra DMA Input FIFO Level */
 
 /* Bit masks for ATAPI_DEV_ADDR */
 /* Bit masks for ATAPI_INT_MASK */
 
 #define        ATAPI_DEV_INT_MASK  0x1        /* Device interrupt mask */
-#define       nATAPI_DEV_INT_MASK  0x0       
 #define             PIO_DONE_MASK  0x2        /* PIO transfer done interrupt mask */
-#define            nPIO_DONE_MASK  0x0       
 #define           MULTI_DONE_MASK  0x4        /* Multi-DMA transfer done interrupt mask */
-#define          nMULTI_DONE_MASK  0x0       
 #define          UDMAIN_DONE_MASK  0x8        /* Ultra-DMA in transfer done interrupt mask */
-#define         nUDMAIN_DONE_MASK  0x0       
 #define         UDMAOUT_DONE_MASK  0x10       /* Ultra-DMA out transfer done interrupt mask */
-#define        nUDMAOUT_DONE_MASK  0x0       
 #define       HOST_TERM_XFER_MASK  0x20       /* Host terminate current transfer interrupt mask */
-#define      nHOST_TERM_XFER_MASK  0x0       
 #define           MULTI_TERM_MASK  0x40       /* Device terminate Multi-DMA transfer interrupt mask */
-#define          nMULTI_TERM_MASK  0x0       
 #define          UDMAIN_TERM_MASK  0x80       /* Device terminate Ultra-DMA-in transfer interrupt mask */
-#define         nUDMAIN_TERM_MASK  0x0       
 #define         UDMAOUT_TERM_MASK  0x100      /* Device terminate Ultra-DMA-out transfer interrupt mask */
-#define        nUDMAOUT_TERM_MASK  0x0       
 
 /* Bit masks for ATAPI_INT_STATUS */
 
 #define             ATAPI_DEV_INT  0x1        /* Device interrupt status */
-#define            nATAPI_DEV_INT  0x0       
 #define              PIO_DONE_INT  0x2        /* PIO transfer done interrupt status */
-#define             nPIO_DONE_INT  0x0       
 #define            MULTI_DONE_INT  0x4        /* Multi-DMA transfer done interrupt status */
-#define           nMULTI_DONE_INT  0x0       
 #define           UDMAIN_DONE_INT  0x8        /* Ultra-DMA in transfer done interrupt status */
-#define          nUDMAIN_DONE_INT  0x0       
 #define          UDMAOUT_DONE_INT  0x10       /* Ultra-DMA out transfer done interrupt status */
-#define         nUDMAOUT_DONE_INT  0x0       
 #define        HOST_TERM_XFER_INT  0x20       /* Host terminate current transfer interrupt status */
-#define       nHOST_TERM_XFER_INT  0x0       
 #define            MULTI_TERM_INT  0x40       /* Device terminate Multi-DMA transfer interrupt status */
-#define           nMULTI_TERM_INT  0x0       
 #define           UDMAIN_TERM_INT  0x80       /* Device terminate Ultra-DMA-in transfer interrupt status */
-#define          nUDMAIN_TERM_INT  0x0       
 #define          UDMAOUT_TERM_INT  0x100      /* Device terminate Ultra-DMA-out transfer interrupt status */
-#define         nUDMAOUT_TERM_INT  0x0       
 
 /* Bit masks for ATAPI_LINE_STATUS */
 
 #define                ATAPI_INTR  0x1        /* Device interrupt to host line status */
-#define               nATAPI_INTR  0x0       
 #define                ATAPI_DASP  0x2        /* Device dasp to host line status */
-#define               nATAPI_DASP  0x0       
 #define                ATAPI_CS0N  0x4        /* ATAPI chip select 0 line status */
-#define               nATAPI_CS0N  0x0       
 #define                ATAPI_CS1N  0x8        /* ATAPI chip select 1 line status */
-#define               nATAPI_CS1N  0x0       
 #define                ATAPI_ADDR  0x70       /* ATAPI address line status */
 #define              ATAPI_DMAREQ  0x80       /* ATAPI DMA request line status */
-#define             nATAPI_DMAREQ  0x0       
 #define             ATAPI_DMAACKN  0x100      /* ATAPI DMA acknowledge line status */
-#define            nATAPI_DMAACKN  0x0       
 #define               ATAPI_DIOWN  0x200      /* ATAPI write line status */
-#define              nATAPI_DIOWN  0x0       
 #define               ATAPI_DIORN  0x400      /* ATAPI read line status */
-#define              nATAPI_DIORN  0x0       
 #define               ATAPI_IORDY  0x800      /* ATAPI IORDY line status */
-#define              nATAPI_IORDY  0x0       
 
 /* Bit masks for ATAPI_SM_STATE */
 
 /* Bit masks for ATAPI_TERMINATE */
 
 #define           ATAPI_HOST_TERM  0x1        /* Host terminationation */
-#define          nATAPI_HOST_TERM  0x0       
 
 /* Bit masks for ATAPI_REG_TIM_0 */
 
 /* Bit masks for TIMER_ENABLE1 */
 
 #define                    TIMEN8  0x1        /* Timer 8 Enable */
-#define                   nTIMEN8  0x0       
 #define                    TIMEN9  0x2        /* Timer 9 Enable */
-#define                   nTIMEN9  0x0       
 #define                   TIMEN10  0x4        /* Timer 10 Enable */
-#define                  nTIMEN10  0x0       
 
 /* Bit masks for TIMER_DISABLE1 */
 
 #define                   TIMDIS8  0x1        /* Timer 8 Disable */
-#define                  nTIMDIS8  0x0       
 #define                   TIMDIS9  0x2        /* Timer 9 Disable */
-#define                  nTIMDIS9  0x0       
 #define                  TIMDIS10  0x4        /* Timer 10 Disable */
-#define                 nTIMDIS10  0x0       
 
 /* Bit masks for TIMER_STATUS1 */
 
 #define                    TIMIL8  0x1        /* Timer 8 Interrupt */
-#define                   nTIMIL8  0x0       
 #define                    TIMIL9  0x2        /* Timer 9 Interrupt */
-#define                   nTIMIL9  0x0       
 #define                   TIMIL10  0x4        /* Timer 10 Interrupt */
-#define                  nTIMIL10  0x0       
 #define                 TOVF_ERR8  0x10       /* Timer 8 Counter Overflow */
-#define                nTOVF_ERR8  0x0       
 #define                 TOVF_ERR9  0x20       /* Timer 9 Counter Overflow */
-#define                nTOVF_ERR9  0x0       
 #define                TOVF_ERR10  0x40       /* Timer 10 Counter Overflow */
-#define               nTOVF_ERR10  0x0       
 #define                     TRUN8  0x1000     /* Timer 8 Slave Enable Status */
-#define                    nTRUN8  0x0       
 #define                     TRUN9  0x2000     /* Timer 9 Slave Enable Status */
-#define                    nTRUN9  0x0       
 #define                    TRUN10  0x4000     /* Timer 10 Slave Enable Status */
-#define                   nTRUN10  0x0       
 
 /* Bit masks for EPPI0 are obtained from common base header for EPPIx (EPPI1 and EPPI2) */
 
 /* Bit masks for USB_POWER */
 
 #define           ENABLE_SUSPENDM  0x1        /* enable SuspendM output */
-#define          nENABLE_SUSPENDM  0x0       
 #define              SUSPEND_MODE  0x2        /* Suspend Mode indicator */
-#define             nSUSPEND_MODE  0x0       
 #define               RESUME_MODE  0x4        /* DMA Mode */
-#define              nRESUME_MODE  0x0       
 #define                     RESET  0x8        /* Reset indicator */
-#define                    nRESET  0x0       
 #define                   HS_MODE  0x10       /* High Speed mode indicator */
-#define                  nHS_MODE  0x0       
 #define                 HS_ENABLE  0x20       /* high Speed Enable */
-#define                nHS_ENABLE  0x0       
 #define                 SOFT_CONN  0x40       /* Soft connect */
-#define                nSOFT_CONN  0x0       
 #define                ISO_UPDATE  0x80       /* Isochronous update */
-#define               nISO_UPDATE  0x0       
 
 /* Bit masks for USB_INTRTX */
 
 #define                    EP0_TX  0x1        /* Tx Endpoint 0 interrupt */
-#define                   nEP0_TX  0x0       
 #define                    EP1_TX  0x2        /* Tx Endpoint 1 interrupt */
-#define                   nEP1_TX  0x0       
 #define                    EP2_TX  0x4        /* Tx Endpoint 2 interrupt */
-#define                   nEP2_TX  0x0       
 #define                    EP3_TX  0x8        /* Tx Endpoint 3 interrupt */
-#define                   nEP3_TX  0x0       
 #define                    EP4_TX  0x10       /* Tx Endpoint 4 interrupt */
-#define                   nEP4_TX  0x0       
 #define                    EP5_TX  0x20       /* Tx Endpoint 5 interrupt */
-#define                   nEP5_TX  0x0       
 #define                    EP6_TX  0x40       /* Tx Endpoint 6 interrupt */
-#define                   nEP6_TX  0x0       
 #define                    EP7_TX  0x80       /* Tx Endpoint 7 interrupt */
-#define                   nEP7_TX  0x0       
 
 /* Bit masks for USB_INTRRX */
 
 #define                    EP1_RX  0x2        /* Rx Endpoint 1 interrupt */
-#define                   nEP1_RX  0x0       
 #define                    EP2_RX  0x4        /* Rx Endpoint 2 interrupt */
-#define                   nEP2_RX  0x0       
 #define                    EP3_RX  0x8        /* Rx Endpoint 3 interrupt */
-#define                   nEP3_RX  0x0       
 #define                    EP4_RX  0x10       /* Rx Endpoint 4 interrupt */
-#define                   nEP4_RX  0x0       
 #define                    EP5_RX  0x20       /* Rx Endpoint 5 interrupt */
-#define                   nEP5_RX  0x0       
 #define                    EP6_RX  0x40       /* Rx Endpoint 6 interrupt */
-#define                   nEP6_RX  0x0       
 #define                    EP7_RX  0x80       /* Rx Endpoint 7 interrupt */
-#define                   nEP7_RX  0x0       
 
 /* Bit masks for USB_INTRTXE */
 
 #define                  EP0_TX_E  0x1        /* Endpoint 0 interrupt Enable */
-#define                 nEP0_TX_E  0x0       
 #define                  EP1_TX_E  0x2        /* Tx Endpoint 1 interrupt  Enable */
-#define                 nEP1_TX_E  0x0       
 #define                  EP2_TX_E  0x4        /* Tx Endpoint 2 interrupt  Enable */
-#define                 nEP2_TX_E  0x0       
 #define                  EP3_TX_E  0x8        /* Tx Endpoint 3 interrupt  Enable */
-#define                 nEP3_TX_E  0x0       
 #define                  EP4_TX_E  0x10       /* Tx Endpoint 4 interrupt  Enable */
-#define                 nEP4_TX_E  0x0       
 #define                  EP5_TX_E  0x20       /* Tx Endpoint 5 interrupt  Enable */
-#define                 nEP5_TX_E  0x0       
 #define                  EP6_TX_E  0x40       /* Tx Endpoint 6 interrupt  Enable */
-#define                 nEP6_TX_E  0x0       
 #define                  EP7_TX_E  0x80       /* Tx Endpoint 7 interrupt  Enable */
-#define                 nEP7_TX_E  0x0       
 
 /* Bit masks for USB_INTRRXE */
 
 #define                  EP1_RX_E  0x2        /* Rx Endpoint 1 interrupt  Enable */
-#define                 nEP1_RX_E  0x0       
 #define                  EP2_RX_E  0x4        /* Rx Endpoint 2 interrupt  Enable */
-#define                 nEP2_RX_E  0x0       
 #define                  EP3_RX_E  0x8        /* Rx Endpoint 3 interrupt  Enable */
-#define                 nEP3_RX_E  0x0       
 #define                  EP4_RX_E  0x10       /* Rx Endpoint 4 interrupt  Enable */
-#define                 nEP4_RX_E  0x0       
 #define                  EP5_RX_E  0x20       /* Rx Endpoint 5 interrupt  Enable */
-#define                 nEP5_RX_E  0x0       
 #define                  EP6_RX_E  0x40       /* Rx Endpoint 6 interrupt  Enable */
-#define                 nEP6_RX_E  0x0       
 #define                  EP7_RX_E  0x80       /* Rx Endpoint 7 interrupt  Enable */
-#define                 nEP7_RX_E  0x0       
 
 /* Bit masks for USB_INTRUSB */
 
 #define                 SUSPEND_B  0x1        /* Suspend indicator */
-#define                nSUSPEND_B  0x0       
 #define                  RESUME_B  0x2        /* Resume indicator */
-#define                 nRESUME_B  0x0       
 #define          RESET_OR_BABLE_B  0x4        /* Reset/babble indicator */
-#define         nRESET_OR_BABLE_B  0x0       
 #define                     SOF_B  0x8        /* Start of frame */
-#define                    nSOF_B  0x0       
 #define                    CONN_B  0x10       /* Connection indicator */
-#define                   nCONN_B  0x0       
 #define                  DISCON_B  0x20       /* Disconnect indicator */
-#define                 nDISCON_B  0x0       
 #define             SESSION_REQ_B  0x40       /* Session Request */
-#define            nSESSION_REQ_B  0x0       
 #define              VBUS_ERROR_B  0x80       /* Vbus threshold indicator */
-#define             nVBUS_ERROR_B  0x0       
 
 /* Bit masks for USB_INTRUSBE */
 
 #define                SUSPEND_BE  0x1        /* Suspend indicator int enable */
-#define               nSUSPEND_BE  0x0       
 #define                 RESUME_BE  0x2        /* Resume indicator int enable */
-#define                nRESUME_BE  0x0       
 #define         RESET_OR_BABLE_BE  0x4        /* Reset/babble indicator int enable */
-#define        nRESET_OR_BABLE_BE  0x0       
 #define                    SOF_BE  0x8        /* Start of frame int enable */
-#define                   nSOF_BE  0x0       
 #define                   CONN_BE  0x10       /* Connection indicator int enable */
-#define                  nCONN_BE  0x0       
 #define                 DISCON_BE  0x20       /* Disconnect indicator int enable */
-#define                nDISCON_BE  0x0       
 #define            SESSION_REQ_BE  0x40       /* Session Request int enable */
-#define           nSESSION_REQ_BE  0x0       
 #define             VBUS_ERROR_BE  0x80       /* Vbus threshold indicator int enable */
-#define            nVBUS_ERROR_BE  0x0       
 
 /* Bit masks for USB_FRAME */
 
 /* Bit masks for USB_GLOBAL_CTL */
 
 #define                GLOBAL_ENA  0x1        /* enables USB module */
-#define               nGLOBAL_ENA  0x0       
 #define                EP1_TX_ENA  0x2        /* Transmit endpoint 1 enable */
-#define               nEP1_TX_ENA  0x0       
 #define                EP2_TX_ENA  0x4        /* Transmit endpoint 2 enable */
-#define               nEP2_TX_ENA  0x0       
 #define                EP3_TX_ENA  0x8        /* Transmit endpoint 3 enable */
-#define               nEP3_TX_ENA  0x0       
 #define                EP4_TX_ENA  0x10       /* Transmit endpoint 4 enable */
-#define               nEP4_TX_ENA  0x0       
 #define                EP5_TX_ENA  0x20       /* Transmit endpoint 5 enable */
-#define               nEP5_TX_ENA  0x0       
 #define                EP6_TX_ENA  0x40       /* Transmit endpoint 6 enable */
-#define               nEP6_TX_ENA  0x0       
 #define                EP7_TX_ENA  0x80       /* Transmit endpoint 7 enable */
-#define               nEP7_TX_ENA  0x0       
 #define                EP1_RX_ENA  0x100      /* Receive endpoint 1 enable */
-#define               nEP1_RX_ENA  0x0       
 #define                EP2_RX_ENA  0x200      /* Receive endpoint 2 enable */
-#define               nEP2_RX_ENA  0x0       
 #define                EP3_RX_ENA  0x400      /* Receive endpoint 3 enable */
-#define               nEP3_RX_ENA  0x0       
 #define                EP4_RX_ENA  0x800      /* Receive endpoint 4 enable */
-#define               nEP4_RX_ENA  0x0       
 #define                EP5_RX_ENA  0x1000     /* Receive endpoint 5 enable */
-#define               nEP5_RX_ENA  0x0       
 #define                EP6_RX_ENA  0x2000     /* Receive endpoint 6 enable */
-#define               nEP6_RX_ENA  0x0       
 #define                EP7_RX_ENA  0x4000     /* Receive endpoint 7 enable */
-#define               nEP7_RX_ENA  0x0       
 
 /* Bit masks for USB_OTG_DEV_CTL */
 
 #define                   SESSION  0x1        /* session indicator */
-#define                  nSESSION  0x0       
 #define                  HOST_REQ  0x2        /* Host negotiation request */
-#define                 nHOST_REQ  0x0       
 #define                 HOST_MODE  0x4        /* indicates USBDRC is a host */
-#define                nHOST_MODE  0x0       
 #define                     VBUS0  0x8        /* Vbus level indicator[0] */
-#define                    nVBUS0  0x0       
 #define                     VBUS1  0x10       /* Vbus level indicator[1] */
-#define                    nVBUS1  0x0       
 #define                     LSDEV  0x20       /* Low-speed indicator */
-#define                    nLSDEV  0x0       
 #define                     FSDEV  0x40       /* Full or High-speed indicator */
-#define                    nFSDEV  0x0       
 #define                  B_DEVICE  0x80       /* A' or 'B' device indicator */
-#define                 nB_DEVICE  0x0       
 
 /* Bit masks for USB_OTG_VBUS_IRQ */
 
 #define             DRIVE_VBUS_ON  0x1        /* indicator to drive VBUS control circuit */
-#define            nDRIVE_VBUS_ON  0x0       
 #define            DRIVE_VBUS_OFF  0x2        /* indicator to shut off charge pump */
-#define           nDRIVE_VBUS_OFF  0x0       
 #define           CHRG_VBUS_START  0x4        /* indicator for external circuit to start charging VBUS */
-#define          nCHRG_VBUS_START  0x0       
 #define             CHRG_VBUS_END  0x8        /* indicator for external circuit to end charging VBUS */
-#define            nCHRG_VBUS_END  0x0       
 #define        DISCHRG_VBUS_START  0x10       /* indicator to start discharging VBUS */
-#define       nDISCHRG_VBUS_START  0x0       
 #define          DISCHRG_VBUS_END  0x20       /* indicator to stop discharging VBUS */
-#define         nDISCHRG_VBUS_END  0x0       
 
 /* Bit masks for USB_OTG_VBUS_MASK */
 
 #define         DRIVE_VBUS_ON_ENA  0x1        /* enable DRIVE_VBUS_ON interrupt */
-#define        nDRIVE_VBUS_ON_ENA  0x0       
 #define        DRIVE_VBUS_OFF_ENA  0x2        /* enable DRIVE_VBUS_OFF interrupt */
-#define       nDRIVE_VBUS_OFF_ENA  0x0       
 #define       CHRG_VBUS_START_ENA  0x4        /* enable CHRG_VBUS_START interrupt */
-#define      nCHRG_VBUS_START_ENA  0x0       
 #define         CHRG_VBUS_END_ENA  0x8        /* enable CHRG_VBUS_END interrupt */
-#define        nCHRG_VBUS_END_ENA  0x0       
 #define    DISCHRG_VBUS_START_ENA  0x10       /* enable DISCHRG_VBUS_START interrupt */
-#define   nDISCHRG_VBUS_START_ENA  0x0       
 #define      DISCHRG_VBUS_END_ENA  0x20       /* enable DISCHRG_VBUS_END interrupt */
-#define     nDISCHRG_VBUS_END_ENA  0x0       
 
 /* Bit masks for USB_CSR0 */
 
 #define                  RXPKTRDY  0x1        /* data packet receive indicator */
-#define                 nRXPKTRDY  0x0       
 #define                  TXPKTRDY  0x2        /* data packet in FIFO indicator */
-#define                 nTXPKTRDY  0x0       
 #define                STALL_SENT  0x4        /* STALL handshake sent */
-#define               nSTALL_SENT  0x0       
 #define                   DATAEND  0x8        /* Data end indicator */
-#define                  nDATAEND  0x0       
 #define                  SETUPEND  0x10       /* Setup end */
-#define                 nSETUPEND  0x0       
 #define                 SENDSTALL  0x20       /* Send STALL handshake */
-#define                nSENDSTALL  0x0       
 #define         SERVICED_RXPKTRDY  0x40       /* used to clear the RxPktRdy bit */
-#define        nSERVICED_RXPKTRDY  0x0       
 #define         SERVICED_SETUPEND  0x80       /* used to clear the SetupEnd bit */
-#define        nSERVICED_SETUPEND  0x0       
 #define                 FLUSHFIFO  0x100      /* flush endpoint FIFO */
-#define                nFLUSHFIFO  0x0       
 #define          STALL_RECEIVED_H  0x4        /* STALL handshake received host mode */
-#define         nSTALL_RECEIVED_H  0x0       
 #define                SETUPPKT_H  0x8        /* send Setup token host mode */
-#define               nSETUPPKT_H  0x0       
 #define                   ERROR_H  0x10       /* timeout error indicator host mode */
-#define                  nERROR_H  0x0       
 #define                  REQPKT_H  0x20       /* Request an IN transaction host mode */
-#define                 nREQPKT_H  0x0       
 #define               STATUSPKT_H  0x40       /* Status stage transaction host mode */
-#define              nSTATUSPKT_H  0x0       
 #define             NAK_TIMEOUT_H  0x80       /* EP0 halted after a NAK host mode */
-#define            nNAK_TIMEOUT_H  0x0       
 
 /* Bit masks for USB_COUNT0 */
 
 /* Bit masks for USB_TXCSR */
 
 #define                TXPKTRDY_T  0x1        /* data packet in FIFO indicator */
-#define               nTXPKTRDY_T  0x0       
 #define          FIFO_NOT_EMPTY_T  0x2        /* FIFO not empty */
-#define         nFIFO_NOT_EMPTY_T  0x0       
 #define                UNDERRUN_T  0x4        /* TxPktRdy not set  for an IN token */
-#define               nUNDERRUN_T  0x0       
 #define               FLUSHFIFO_T  0x8        /* flush endpoint FIFO */
-#define              nFLUSHFIFO_T  0x0       
 #define              STALL_SEND_T  0x10       /* issue a Stall handshake */
-#define             nSTALL_SEND_T  0x0       
 #define              STALL_SENT_T  0x20       /* Stall handshake transmitted */
-#define             nSTALL_SENT_T  0x0       
 #define        CLEAR_DATATOGGLE_T  0x40       /* clear endpoint data toggle */
-#define       nCLEAR_DATATOGGLE_T  0x0       
 #define                INCOMPTX_T  0x80       /* indicates that a large packet is split */
-#define               nINCOMPTX_T  0x0       
 #define              DMAREQMODE_T  0x400      /* DMA mode (0 or 1) selection */
-#define             nDMAREQMODE_T  0x0       
 #define        FORCE_DATATOGGLE_T  0x800      /* Force data toggle */
-#define       nFORCE_DATATOGGLE_T  0x0       
 #define              DMAREQ_ENA_T  0x1000     /* Enable DMA request for Tx EP */
-#define             nDMAREQ_ENA_T  0x0       
 #define                     ISO_T  0x4000     /* enable Isochronous transfers */
-#define                    nISO_T  0x0       
 #define                 AUTOSET_T  0x8000     /* allows TxPktRdy to be set automatically */
-#define                nAUTOSET_T  0x0       
 #define                  ERROR_TH  0x4        /* error condition host mode */
-#define                 nERROR_TH  0x0       
 #define         STALL_RECEIVED_TH  0x20       /* Stall handshake received host mode */
-#define        nSTALL_RECEIVED_TH  0x0       
 #define            NAK_TIMEOUT_TH  0x80       /* NAK timeout host mode */
-#define           nNAK_TIMEOUT_TH  0x0       
 
 /* Bit masks for USB_TXCOUNT */
 
 /* Bit masks for USB_RXCSR */
 
 #define                RXPKTRDY_R  0x1        /* data packet in FIFO indicator */
-#define               nRXPKTRDY_R  0x0       
 #define               FIFO_FULL_R  0x2        /* FIFO not empty */
-#define              nFIFO_FULL_R  0x0       
 #define                 OVERRUN_R  0x4        /* TxPktRdy not set  for an IN token */
-#define                nOVERRUN_R  0x0       
 #define               DATAERROR_R  0x8        /* Out packet cannot be loaded into Rx  FIFO */
-#define              nDATAERROR_R  0x0       
 #define               FLUSHFIFO_R  0x10       /* flush endpoint FIFO */
-#define              nFLUSHFIFO_R  0x0       
 #define              STALL_SEND_R  0x20       /* issue a Stall handshake */
-#define             nSTALL_SEND_R  0x0       
 #define              STALL_SENT_R  0x40       /* Stall handshake transmitted */
-#define             nSTALL_SENT_R  0x0       
 #define        CLEAR_DATATOGGLE_R  0x80       /* clear endpoint data toggle */
-#define       nCLEAR_DATATOGGLE_R  0x0       
 #define                INCOMPRX_R  0x100      /* indicates that a large packet is split */
-#define               nINCOMPRX_R  0x0       
 #define              DMAREQMODE_R  0x800      /* DMA mode (0 or 1) selection */
-#define             nDMAREQMODE_R  0x0       
 #define                 DISNYET_R  0x1000     /* disable Nyet handshakes */
-#define                nDISNYET_R  0x0       
 #define              DMAREQ_ENA_R  0x2000     /* Enable DMA request for Tx EP */
-#define             nDMAREQ_ENA_R  0x0       
 #define                     ISO_R  0x4000     /* enable Isochronous transfers */
-#define                    nISO_R  0x0       
 #define               AUTOCLEAR_R  0x8000     /* allows TxPktRdy to be set automatically */
-#define              nAUTOCLEAR_R  0x0       
 #define                  ERROR_RH  0x4        /* TxPktRdy not set  for an IN token host mode */
-#define                 nERROR_RH  0x0       
 #define                 REQPKT_RH  0x20       /* request an IN transaction host mode */
-#define                nREQPKT_RH  0x0       
 #define         STALL_RECEIVED_RH  0x40       /* Stall handshake received host mode */
-#define        nSTALL_RECEIVED_RH  0x0       
 #define               INCOMPRX_RH  0x100      /* indicates that a large packet is split host mode */
-#define              nINCOMPRX_RH  0x0       
 #define             DMAREQMODE_RH  0x800      /* DMA mode (0 or 1) selection host mode */
-#define            nDMAREQMODE_RH  0x0       
 #define                AUTOREQ_RH  0x4000     /* sets ReqPkt automatically host mode */
-#define               nAUTOREQ_RH  0x0       
 
 /* Bit masks for USB_RXCOUNT */
 
 /* Bit masks for USB_DMA_INTERRUPT */
 
 #define                  DMA0_INT  0x1        /* DMA0 pending interrupt */
-#define                 nDMA0_INT  0x0       
 #define                  DMA1_INT  0x2        /* DMA1 pending interrupt */
-#define                 nDMA1_INT  0x0       
 #define                  DMA2_INT  0x4        /* DMA2 pending interrupt */
-#define                 nDMA2_INT  0x0       
 #define                  DMA3_INT  0x8        /* DMA3 pending interrupt */
-#define                 nDMA3_INT  0x0       
 #define                  DMA4_INT  0x10       /* DMA4 pending interrupt */
-#define                 nDMA4_INT  0x0       
 #define                  DMA5_INT  0x20       /* DMA5 pending interrupt */
-#define                 nDMA5_INT  0x0       
 #define                  DMA6_INT  0x40       /* DMA6 pending interrupt */
-#define                 nDMA6_INT  0x0       
 #define                  DMA7_INT  0x80       /* DMA7 pending interrupt */
-#define                 nDMA7_INT  0x0       
 
 /* Bit masks for USB_DMAxCONTROL */
 
 #define                   DMA_ENA  0x1        /* DMA enable */
-#define                  nDMA_ENA  0x0       
 #define                 DIRECTION  0x2        /* direction of DMA transfer */
-#define                nDIRECTION  0x0       
 #define                      MODE  0x4        /* DMA Bus error */
-#define                     nMODE  0x0       
 #define                   INT_ENA  0x8        /* Interrupt enable */
-#define                  nINT_ENA  0x0       
 #define                     EPNUM  0xf0       /* EP number */
 #define                  BUSERROR  0x100      /* DMA Bus error */
-#define                 nBUSERROR  0x0       
 
 /* Bit masks for USB_DMAxADDRHIGH */
 
 /* Bit masks for HMDMAx_CONTROL */
 
 #define                   HMDMAEN  0x1        /* Handshake MDMA Enable */
-#define                  nHMDMAEN  0x0       
 #define                       REP  0x2        /* Handshake MDMA Request Polarity */
-#define                      nREP  0x0       
 #define                       UTE  0x8        /* Urgency Threshold Enable */
-#define                      nUTE  0x0       
 #define                       OIE  0x10       /* Overflow Interrupt Enable */
-#define                      nOIE  0x0       
 #define                      BDIE  0x20       /* Block Done Interrupt Enable */
-#define                     nBDIE  0x0       
 #define                      MBDI  0x40       /* Mask Block Done Interrupt */
-#define                     nMBDI  0x0       
 #define                       DRQ  0x300      /* Handshake MDMA Request Type */
 #define                       RBC  0x1000     /* Force Reload of BCOUNT */
-#define                      nRBC  0x0       
 #define                        PS  0x2000     /* Pin Status */
-#define                       nPS  0x0       
 #define                        OI  0x4000     /* Overflow Interrupt Generated */
-#define                       nOI  0x0       
 #define                       BDI  0x8000     /* Block Done Interrupt Generated */
-#define                      nBDI  0x0       
 
 /* ******************************************* */
 /*     MULTI BIT MACRO ENUMERATIONS            */
index b1cc1c073b4115f5cf41b160beabcfe6bf517991..c2f4734da48df9ca9d96a02d868c2af734e6a9a9 100644 (file)
 /* Bit masks for PIXC_CTL */
 
 #define                   PIXC_EN  0x1        /* Pixel Compositor Enable */
-#define                  nPIXC_EN  0x0       
 #define                  OVR_A_EN  0x2        /* Overlay A Enable */
-#define                 nOVR_A_EN  0x0       
 #define                  OVR_B_EN  0x4        /* Overlay B Enable */
-#define                 nOVR_B_EN  0x0       
 #define                  IMG_FORM  0x8        /* Image Data Format */
-#define                 nIMG_FORM  0x0       
 #define                  OVR_FORM  0x10       /* Overlay Data Format */
-#define                 nOVR_FORM  0x0       
 #define                  OUT_FORM  0x20       /* Output Data Format */
-#define                 nOUT_FORM  0x0       
 #define                   UDS_MOD  0x40       /* Resampling Mode */
-#define                  nUDS_MOD  0x0       
 #define                     TC_EN  0x80       /* Transparent Color Enable */
-#define                    nTC_EN  0x0       
 #define                  IMG_STAT  0x300      /* Image FIFO Status */
 #define                  OVR_STAT  0xc00      /* Overlay FIFO Status */
 #define                    WM_LVL  0x3000     /* FIFO Watermark Level */
 /* Bit masks for PIXC_INTRSTAT */
 
 #define                OVR_INT_EN  0x1        /* Interrupt at End of Last Valid Overlay */
-#define               nOVR_INT_EN  0x0       
 #define                FRM_INT_EN  0x2        /* Interrupt at End of Frame */
-#define               nFRM_INT_EN  0x0       
 #define              OVR_INT_STAT  0x4        /* Overlay Interrupt Status */
-#define             nOVR_INT_STAT  0x0       
 #define              FRM_INT_STAT  0x8        /* Frame Interrupt Status */
-#define             nFRM_INT_STAT  0x0       
 
 /* Bit masks for PIXC_RYCON */
 
 #define                       A12  0xffc00    /* A12 in the Coefficient Matrix */
 #define                       A13  0x3ff00000 /* A13 in the Coefficient Matrix */
 #define                  RY_MULT4  0x40000000 /* Multiply Row by 4 */
-#define                 nRY_MULT4  0x0       
 
 /* Bit masks for PIXC_GUCON */
 
 #define                       A22  0xffc00    /* A22 in the Coefficient Matrix */
 #define                       A23  0x3ff00000 /* A23 in the Coefficient Matrix */
 #define                  GU_MULT4  0x40000000 /* Multiply Row by 4 */
-#define                 nGU_MULT4  0x0       
 
 /* Bit masks for PIXC_BVCON */
 
 #define                       A32  0xffc00    /* A32 in the Coefficient Matrix */
 #define                       A33  0x3ff00000 /* A33 in the Coefficient Matrix */
 #define                  BV_MULT4  0x40000000 /* Multiply Row by 4 */
-#define                 nBV_MULT4  0x0       
 
 /* Bit masks for PIXC_CCBIAS */
 
 /* Bit masks for HOST_CONTROL */
 
 #define                   HOST_EN  0x1        /* Host Enable */
-#define                  nHOST_EN  0x0       
 #define                  HOST_END  0x2        /* Host Endianess */
-#define                 nHOST_END  0x0       
 #define                 DATA_SIZE  0x4        /* Data Size */
-#define                nDATA_SIZE  0x0       
 #define                  HOST_RST  0x8        /* Host Reset */
-#define                 nHOST_RST  0x0       
 #define                  HRDY_OVR  0x20       /* Host Ready Override */
-#define                 nHRDY_OVR  0x0       
 #define                  INT_MODE  0x40       /* Interrupt Mode */
-#define                 nINT_MODE  0x0       
 #define                     BT_EN  0x80       /* Bus Timeout Enable */
-#define                    nBT_EN  0x0       
 #define                       EHW  0x100      /* Enable Host Write */
-#define                      nEHW  0x0       
 #define                       EHR  0x200      /* Enable Host Read */
-#define                      nEHR  0x0       
 #define                       BDR  0x400      /* Burst DMA Requests */
-#define                      nBDR  0x0       
 
 /* Bit masks for HOST_STATUS */
 
 #define                     READY  0x1        /* DMA Ready */
-#define                    nREADY  0x0       
 #define                  FIFOFULL  0x2        /* FIFO Full */
-#define                 nFIFOFULL  0x0       
 #define                 FIFOEMPTY  0x4        /* FIFO Empty */
-#define                nFIFOEMPTY  0x0       
-#define                  COMPLETE  0x8        /* DMA Complete */
-#define                 nCOMPLETE  0x0       
+#define              DMA_COMPLETE  0x8        /* DMA Complete */
 #define                      HSHK  0x10       /* Host Handshake */
-#define                     nHSHK  0x0       
 #define                   TIMEOUT  0x20       /* Host Timeout */
-#define                  nTIMEOUT  0x0       
 #define                      HIRQ  0x40       /* Host Interrupt Request */
-#define                     nHIRQ  0x0       
 #define                ALLOW_CNFG  0x80       /* Allow New Configuration */
-#define               nALLOW_CNFG  0x0       
 #define                   DMA_DIR  0x100      /* DMA Direction */
-#define                  nDMA_DIR  0x0       
 #define                       BTE  0x200      /* Bus Timeout Enabled */
-#define                      nBTE  0x0       
 
 /* Bit masks for HOST_TIMEOUT */
 
 /* Bit masks for MXVR_CONFIG */
 
 #define                    MXVREN  0x1        /* MXVR Enable */
-#define                   nMXVREN  0x0       
 #define                      MMSM  0x2        /* MXVR Master/Slave Mode Select */
-#define                     nMMSM  0x0       
 #define                    ACTIVE  0x4        /* Active Mode */
-#define                   nACTIVE  0x0       
 #define                    SDELAY  0x8        /* Synchronous Data Delay */
-#define                   nSDELAY  0x0       
 #define                   NCMRXEN  0x10       /* Normal Control Message Receive Enable */
-#define                  nNCMRXEN  0x0       
 #define                   RWRRXEN  0x20       /* Remote Write Receive Enable */
-#define                  nRWRRXEN  0x0       
 #define                     MTXEN  0x40       /* MXVR Transmit Data Enable */
-#define                    nMTXEN  0x0       
 #define                    MTXONB  0x80       /* MXVR Phy Transmitter On */
-#define                   nMTXONB  0x0       
 #define                   EPARITY  0x100      /* Even Parity Select */
-#define                  nEPARITY  0x0       
 #define                       MSB  0x1e00     /* Master Synchronous Boundary */
 #define                    APRXEN  0x2000     /* Asynchronous Packet Receive Enable */
-#define                   nAPRXEN  0x0       
 #define                    WAKEUP  0x4000     /* Wake-Up */
-#define                   nWAKEUP  0x0       
 #define                     LMECH  0x8000     /* Lock Mechanism Select */
-#define                    nLMECH  0x0       
 
 /* Bit masks for MXVR_STATE_0 */
 
 #define                      NACT  0x1        /* Network Activity */
-#define                     nNACT  0x0       
 #define                    SBLOCK  0x2        /* Super Block Lock */
-#define                   nSBLOCK  0x0       
 #define                   FMPLLST  0xc        /* Frequency Multiply PLL SM State */
 #define                  CDRPLLST  0xe0       /* Clock/Data Recovery PLL SM State */
 #define                     APBSY  0x100      /* Asynchronous Packet Transmit Buffer Busy */
-#define                    nAPBSY  0x0       
 #define                     APARB  0x200      /* Asynchronous Packet Arbitrating */
-#define                    nAPARB  0x0       
 #define                      APTX  0x400      /* Asynchronous Packet Transmitting */
-#define                     nAPTX  0x0       
 #define                      APRX  0x800      /* Receiving Asynchronous Packet */
-#define                     nAPRX  0x0       
 #define                     CMBSY  0x1000     /* Control Message Transmit Buffer Busy */
-#define                    nCMBSY  0x0       
 #define                     CMARB  0x2000     /* Control Message Arbitrating */
-#define                    nCMARB  0x0       
 #define                      CMTX  0x4000     /* Control Message Transmitting */
-#define                     nCMTX  0x0       
 #define                      CMRX  0x8000     /* Receiving Control Message */
-#define                     nCMRX  0x0       
 #define                    MRXONB  0x10000    /* MRXONB Pin State */
-#define                   nMRXONB  0x0       
 #define                     RGSIP  0x20000    /* Remote Get Source In Progress */
-#define                    nRGSIP  0x0       
 #define                     DALIP  0x40000    /* Resource Deallocate In Progress */
-#define                    nDALIP  0x0       
 #define                      ALIP  0x80000    /* Resource Allocate In Progress */
-#define                     nALIP  0x0       
 #define                     RRDIP  0x100000   /* Remote Read In Progress */
-#define                    nRRDIP  0x0       
 #define                     RWRIP  0x200000   /* Remote Write In Progress */
-#define                    nRWRIP  0x0       
 #define                     FLOCK  0x400000   /* Frame Lock */
-#define                    nFLOCK  0x0       
 #define                     BLOCK  0x800000   /* Block Lock */
-#define                    nBLOCK  0x0       
 #define                       RSB  0xf000000  /* Received Synchronous Boundary */
 #define                   DERRNUM  0xf0000000 /* DMA Error Channel Number */
 
 #define                   SRXNUMB  0xf        /* Synchronous Receive FIFO Number of Bytes */
 #define                   STXNUMB  0xf0       /* Synchronous Transmit FIFO Number of Bytes */
 #define                    APCONT  0x100      /* Asynchronous Packet Continuation */
-#define                   nAPCONT  0x0       
 #define                  OBERRNUM  0xe00      /* DMA Out of Bounds Error Channel Number */
 #define                DMAACTIVE0  0x10000    /* DMA0 Active */
-#define               nDMAACTIVE0  0x0       
 #define                DMAACTIVE1  0x20000    /* DMA1 Active */
-#define               nDMAACTIVE1  0x0       
 #define                DMAACTIVE2  0x40000    /* DMA2 Active */
-#define               nDMAACTIVE2  0x0       
 #define                DMAACTIVE3  0x80000    /* DMA3 Active */
-#define               nDMAACTIVE3  0x0       
 #define                DMAACTIVE4  0x100000   /* DMA4 Active */
-#define               nDMAACTIVE4  0x0       
 #define                DMAACTIVE5  0x200000   /* DMA5 Active */
-#define               nDMAACTIVE5  0x0       
 #define                DMAACTIVE6  0x400000   /* DMA6 Active */
-#define               nDMAACTIVE6  0x0       
 #define                DMAACTIVE7  0x800000   /* DMA7 Active */
-#define               nDMAACTIVE7  0x0       
 #define                  DMAPMEN0  0x1000000  /* DMA0 Pattern Matching Enabled */
-#define                 nDMAPMEN0  0x0       
 #define                  DMAPMEN1  0x2000000  /* DMA1 Pattern Matching Enabled */
-#define                 nDMAPMEN1  0x0       
 #define                  DMAPMEN2  0x4000000  /* DMA2 Pattern Matching Enabled */
-#define                 nDMAPMEN2  0x0       
 #define                  DMAPMEN3  0x8000000  /* DMA3 Pattern Matching Enabled */
-#define                 nDMAPMEN3  0x0       
 #define                  DMAPMEN4  0x10000000 /* DMA4 Pattern Matching Enabled */
-#define                 nDMAPMEN4  0x0       
 #define                  DMAPMEN5  0x20000000 /* DMA5 Pattern Matching Enabled */
-#define                 nDMAPMEN5  0x0       
 #define                  DMAPMEN6  0x40000000 /* DMA6 Pattern Matching Enabled */
-#define                 nDMAPMEN6  0x0       
 #define                  DMAPMEN7  0x80000000 /* DMA7 Pattern Matching Enabled */
-#define                 nDMAPMEN7  0x0       
 
 /* Bit masks for MXVR_INT_STAT_0 */
 
 #define                      NI2A  0x1        /* Network Inactive to Active */
-#define                     nNI2A  0x0       
 #define                      NA2I  0x2        /* Network Active to Inactive */
-#define                     nNA2I  0x0       
 #define                     SBU2L  0x4        /* Super Block Unlock to Lock */
-#define                    nSBU2L  0x0       
 #define                     SBL2U  0x8        /* Super Block Lock to Unlock */
-#define                    nSBL2U  0x0       
 #define                       PRU  0x10       /* Position Register Updated */
-#define                      nPRU  0x0       
 #define                      MPRU  0x20       /* Maximum Position Register Updated */
-#define                     nMPRU  0x0       
 #define                       DRU  0x40       /* Delay Register Updated */
-#define                      nDRU  0x0       
 #define                      MDRU  0x80       /* Maximum Delay Register Updated */
-#define                     nMDRU  0x0       
 #define                       SBU  0x100      /* Synchronous Boundary Updated */
-#define                      nSBU  0x0       
 #define                       ATU  0x200      /* Allocation Table Updated */
-#define                      nATU  0x0       
 #define                      FCZ0  0x400      /* Frame Counter 0 Zero */
-#define                     nFCZ0  0x0       
 #define                      FCZ1  0x800      /* Frame Counter 1 Zero */
-#define                     nFCZ1  0x0       
 #define                      PERR  0x1000     /* Parity Error */
-#define                     nPERR  0x0       
 #define                      MH2L  0x2000     /* MRXONB High to Low */
-#define                     nMH2L  0x0       
 #define                      ML2H  0x4000     /* MRXONB Low to High */
-#define                     nML2H  0x0       
 #define                       WUP  0x8000     /* Wake-Up Preamble Received */
-#define                      nWUP  0x0       
 #define                      FU2L  0x10000    /* Frame Unlock to Lock */
-#define                     nFU2L  0x0       
 #define                      FL2U  0x20000    /* Frame Lock to Unlock */
-#define                     nFL2U  0x0       
 #define                      BU2L  0x40000    /* Block Unlock to Lock */
-#define                     nBU2L  0x0       
 #define                      BL2U  0x80000    /* Block Lock to Unlock */
-#define                     nBL2U  0x0       
 #define                     OBERR  0x100000   /* DMA Out of Bounds Error */
-#define                    nOBERR  0x0       
 #define                       PFL  0x200000   /* PLL Frequency Locked */
-#define                      nPFL  0x0       
 #define                       SCZ  0x400000   /* System Clock Counter Zero */
-#define                      nSCZ  0x0       
 #define                      FERR  0x800000   /* FIFO Error */
-#define                     nFERR  0x0       
 #define                       CMR  0x1000000  /* Control Message Received */
-#define                      nCMR  0x0       
 #define                     CMROF  0x2000000  /* Control Message Receive Buffer Overflow */
-#define                    nCMROF  0x0       
 #define                      CMTS  0x4000000  /* Control Message Transmit Buffer Successfully Sent */
-#define                     nCMTS  0x0       
 #define                      CMTC  0x8000000  /* Control Message Transmit Buffer Successfully Cancelled */
-#define                     nCMTC  0x0       
 #define                      RWRC  0x10000000 /* Remote Write Control Message Completed */
-#define                     nRWRC  0x0       
 #define                       BCZ  0x20000000 /* Block Counter Zero */
-#define                      nBCZ  0x0       
 #define                     BMERR  0x40000000 /* Biphase Mark Coding Error */
-#define                    nBMERR  0x0       
 #define                      DERR  0x80000000 /* DMA Error */
-#define                     nDERR  0x0       
 
 /* Bit masks for MXVR_INT_STAT_1 */
 
 #define                    HDONE0  0x1        /* DMA0 Half Done */
-#define                   nHDONE0  0x0       
 #define                     DONE0  0x2        /* DMA0 Done */
-#define                    nDONE0  0x0       
 #define                       APR  0x4        /* Asynchronous Packet Received */
-#define                      nAPR  0x0       
 #define                     APROF  0x8        /* Asynchronous Packet Receive Buffer Overflow */
-#define                    nAPROF  0x0       
 #define                    HDONE1  0x10       /* DMA1 Half Done */
-#define                   nHDONE1  0x0       
 #define                     DONE1  0x20       /* DMA1 Done */
-#define                    nDONE1  0x0       
 #define                      APTS  0x40       /* Asynchronous Packet Transmit Buffer Successfully Sent */
-#define                     nAPTS  0x0       
 #define                      APTC  0x80       /* Asynchronous Packet Transmit Buffer Successfully Cancelled */
-#define                     nAPTC  0x0       
 #define                    HDONE2  0x100      /* DMA2 Half Done */
-#define                   nHDONE2  0x0       
 #define                     DONE2  0x200      /* DMA2 Done */
-#define                    nDONE2  0x0       
 #define                     APRCE  0x400      /* Asynchronous Packet Receive CRC Error */
-#define                    nAPRCE  0x0       
 #define                     APRPE  0x800      /* Asynchronous Packet Receive Packet Error */
-#define                    nAPRPE  0x0       
 #define                    HDONE3  0x1000     /* DMA3 Half Done */
-#define                   nHDONE3  0x0       
 #define                     DONE3  0x2000     /* DMA3 Done */
-#define                    nDONE3  0x0       
 #define                    HDONE4  0x10000    /* DMA4 Half Done */
-#define                   nHDONE4  0x0       
 #define                     DONE4  0x20000    /* DMA4 Done */
-#define                    nDONE4  0x0       
 #define                    HDONE5  0x100000   /* DMA5 Half Done */
-#define                   nHDONE5  0x0       
 #define                     DONE5  0x200000   /* DMA5 Done */
-#define                    nDONE5  0x0       
 #define                    HDONE6  0x1000000  /* DMA6 Half Done */
-#define                   nHDONE6  0x0       
 #define                     DONE6  0x2000000  /* DMA6 Done */
-#define                    nDONE6  0x0       
 #define                    HDONE7  0x10000000 /* DMA7 Half Done */
-#define                   nHDONE7  0x0       
 #define                     DONE7  0x20000000 /* DMA7 Done */
-#define                    nDONE7  0x0       
 
 /* Bit masks for MXVR_INT_EN_0 */
 
 #define                    NI2AEN  0x1        /* Network Inactive to Active Interrupt Enable */
-#define                   nNI2AEN  0x0       
 #define                    NA2IEN  0x2        /* Network Active to Inactive Interrupt Enable */
-#define                   nNA2IEN  0x0       
 #define                   SBU2LEN  0x4        /* Super Block Unlock to Lock Interrupt Enable */
-#define                  nSBU2LEN  0x0       
 #define                   SBL2UEN  0x8        /* Super Block Lock to Unlock Interrupt Enable */
-#define                  nSBL2UEN  0x0       
 #define                     PRUEN  0x10       /* Position Register Updated Interrupt Enable */
-#define                    nPRUEN  0x0       
 #define                    MPRUEN  0x20       /* Maximum Position Register Updated Interrupt Enable */
-#define                   nMPRUEN  0x0       
 #define                     DRUEN  0x40       /* Delay Register Updated Interrupt Enable */
-#define                    nDRUEN  0x0       
 #define                    MDRUEN  0x80       /* Maximum Delay Register Updated Interrupt Enable */
-#define                   nMDRUEN  0x0       
 #define                     SBUEN  0x100      /* Synchronous Boundary Updated Interrupt Enable */
-#define                    nSBUEN  0x0       
 #define                     ATUEN  0x200      /* Allocation Table Updated Interrupt Enable */
-#define                    nATUEN  0x0       
 #define                    FCZ0EN  0x400      /* Frame Counter 0 Zero Interrupt Enable */
-#define                   nFCZ0EN  0x0       
 #define                    FCZ1EN  0x800      /* Frame Counter 1 Zero Interrupt Enable */
-#define                   nFCZ1EN  0x0       
 #define                    PERREN  0x1000     /* Parity Error Interrupt Enable */
-#define                   nPERREN  0x0       
 #define                    MH2LEN  0x2000     /* MRXONB High to Low Interrupt Enable */
-#define                   nMH2LEN  0x0       
 #define                    ML2HEN  0x4000     /* MRXONB Low to High Interrupt Enable */
-#define                   nML2HEN  0x0       
 #define                     WUPEN  0x8000     /* Wake-Up Preamble Received Interrupt Enable */
-#define                    nWUPEN  0x0       
 #define                    FU2LEN  0x10000    /* Frame Unlock to Lock Interrupt Enable */
-#define                   nFU2LEN  0x0       
 #define                    FL2UEN  0x20000    /* Frame Lock to Unlock Interrupt Enable */
-#define                   nFL2UEN  0x0       
 #define                    BU2LEN  0x40000    /* Block Unlock to Lock Interrupt Enable */
-#define                   nBU2LEN  0x0       
 #define                    BL2UEN  0x80000    /* Block Lock to Unlock Interrupt Enable */
-#define                   nBL2UEN  0x0       
 #define                   OBERREN  0x100000   /* DMA Out of Bounds Error Interrupt Enable */
-#define                  nOBERREN  0x0       
 #define                     PFLEN  0x200000   /* PLL Frequency Locked Interrupt Enable */
-#define                    nPFLEN  0x0       
 #define                     SCZEN  0x400000   /* System Clock Counter Zero Interrupt Enable */
-#define                    nSCZEN  0x0       
 #define                    FERREN  0x800000   /* FIFO Error Interrupt Enable */
-#define                   nFERREN  0x0       
 #define                     CMREN  0x1000000  /* Control Message Received Interrupt Enable */
-#define                    nCMREN  0x0       
 #define                   CMROFEN  0x2000000  /* Control Message Receive Buffer Overflow Interrupt Enable */
-#define                  nCMROFEN  0x0       
 #define                    CMTSEN  0x4000000  /* Control Message Transmit Buffer Successfully Sent Interrupt Enable */
-#define                   nCMTSEN  0x0       
 #define                    CMTCEN  0x8000000  /* Control Message Transmit Buffer Successfully Cancelled Interrupt Enable */
-#define                   nCMTCEN  0x0       
 #define                    RWRCEN  0x10000000 /* Remote Write Control Message Completed Interrupt Enable */
-#define                   nRWRCEN  0x0       
 #define                     BCZEN  0x20000000 /* Block Counter Zero Interrupt Enable */
-#define                    nBCZEN  0x0       
 #define                   BMERREN  0x40000000 /* Biphase Mark Coding Error Interrupt Enable */
-#define                  nBMERREN  0x0       
 #define                    DERREN  0x80000000 /* DMA Error Interrupt Enable */
-#define                   nDERREN  0x0       
 
 /* Bit masks for MXVR_INT_EN_1 */
 
 #define                  HDONEEN0  0x1        /* DMA0 Half Done Interrupt Enable */
-#define                 nHDONEEN0  0x0       
 #define                   DONEEN0  0x2        /* DMA0 Done Interrupt Enable */
-#define                  nDONEEN0  0x0       
 #define                     APREN  0x4        /* Asynchronous Packet Received Interrupt Enable */
-#define                    nAPREN  0x0       
 #define                   APROFEN  0x8        /* Asynchronous Packet Receive Buffer Overflow Interrupt Enable */
-#define                  nAPROFEN  0x0       
 #define                  HDONEEN1  0x10       /* DMA1 Half Done Interrupt Enable */
-#define                 nHDONEEN1  0x0       
 #define                   DONEEN1  0x20       /* DMA1 Done Interrupt Enable */
-#define                  nDONEEN1  0x0       
 #define                    APTSEN  0x40       /* Asynchronous Packet Transmit Buffer Successfully Sent Interrupt Enable */
-#define                   nAPTSEN  0x0       
 #define                    APTCEN  0x80       /* Asynchronous Packet Transmit Buffer Successfully Cancelled Interrupt Enable */
-#define                   nAPTCEN  0x0       
 #define                  HDONEEN2  0x100      /* DMA2 Half Done Interrupt Enable */
-#define                 nHDONEEN2  0x0       
 #define                   DONEEN2  0x200      /* DMA2 Done Interrupt Enable */
-#define                  nDONEEN2  0x0       
 #define                   APRCEEN  0x400      /* Asynchronous Packet Receive CRC Error Interrupt Enable */
-#define                  nAPRCEEN  0x0       
 #define                   APRPEEN  0x800      /* Asynchronous Packet Receive Packet Error Interrupt Enable */
-#define                  nAPRPEEN  0x0       
 #define                  HDONEEN3  0x1000     /* DMA3 Half Done Interrupt Enable */
-#define                 nHDONEEN3  0x0       
 #define                   DONEEN3  0x2000     /* DMA3 Done Interrupt Enable */
-#define                  nDONEEN3  0x0       
 #define                  HDONEEN4  0x10000    /* DMA4 Half Done Interrupt Enable */
-#define                 nHDONEEN4  0x0       
 #define                   DONEEN4  0x20000    /* DMA4 Done Interrupt Enable */
-#define                  nDONEEN4  0x0       
 #define                  HDONEEN5  0x100000   /* DMA5 Half Done Interrupt Enable */
-#define                 nHDONEEN5  0x0       
 #define                   DONEEN5  0x200000   /* DMA5 Done Interrupt Enable */
-#define                  nDONEEN5  0x0       
 #define                  HDONEEN6  0x1000000  /* DMA6 Half Done Interrupt Enable */
-#define                 nHDONEEN6  0x0       
 #define                   DONEEN6  0x2000000  /* DMA6 Done Interrupt Enable */
-#define                  nDONEEN6  0x0       
 #define                  HDONEEN7  0x10000000 /* DMA7 Half Done Interrupt Enable */
-#define                 nHDONEEN7  0x0       
 #define                   DONEEN7  0x20000000 /* DMA7 Done Interrupt Enable */
-#define                  nDONEEN7  0x0       
 
 /* Bit masks for MXVR_POSITION */
 
 #define                  POSITION  0x3f       /* Node Position */
 #define                    PVALID  0x8000     /* Node Position Valid */
-#define                   nPVALID  0x0       
 
 /* Bit masks for MXVR_MAX_POSITION */
 
 #define                 MPOSITION  0x3f       /* Maximum Node Position */
 #define                   MPVALID  0x8000     /* Maximum Node Position Valid */
-#define                  nMPVALID  0x0       
 
 /* Bit masks for MXVR_DELAY */
 
 #define                     DELAY  0x3f       /* Node Frame Delay */
 #define                    DVALID  0x8000     /* Node Frame Delay Valid */
-#define                   nDVALID  0x0       
 
 /* Bit masks for MXVR_MAX_DELAY */
 
 #define                    MDELAY  0x3f       /* Maximum Node Frame Delay */
 #define                   MDVALID  0x8000     /* Maximum Node Frame Delay Valid */
-#define                  nMDVALID  0x0       
 
 /* Bit masks for MXVR_LADDR */
 
 #define                     LADDR  0xffff     /* Logical Address */
 #define                    LVALID  0x80000000 /* Logical Address Valid */
-#define                   nLVALID  0x0       
 
 /* Bit masks for MXVR_GADDR */
 
 #define                    GADDRL  0xff       /* Group Address Lower Byte */
 #define                    GVALID  0x8000     /* Group Address Valid */
-#define                   nGVALID  0x0       
 
 /* Bit masks for MXVR_AADDR */
 
 #define                     AADDR  0xffff     /* Alternate Address */
 #define                    AVALID  0x80000000 /* Alternate Address Valid */
-#define                   nAVALID  0x0       
 
 /* Bit masks for MXVR_ALLOC_0 */
 
 #define                       CL0  0x7f       /* Channel 0 Connection Label */
 #define                      CIU0  0x80       /* Channel 0 In Use */
-#define                     nCIU0  0x0       
 #define                       CL1  0x7f00     /* Channel 0 Connection Label */
 #define                      CIU1  0x8000     /* Channel 0 In Use */
-#define                     nCIU1  0x0       
 #define                       CL2  0x7f0000   /* Channel 0 Connection Label */
 #define                      CIU2  0x800000   /* Channel 0 In Use */
-#define                     nCIU2  0x0       
 #define                       CL3  0x7f000000 /* Channel 0 Connection Label */
 #define                      CIU3  0x80000000 /* Channel 0 In Use */
-#define                     nCIU3  0x0       
 
 /* Bit masks for MXVR_ALLOC_1 */
 
 #define                       CL4  0x7f       /* Channel 4 Connection Label */
 #define                      CIU4  0x80       /* Channel 4 In Use */
-#define                     nCIU4  0x0       
 #define                       CL5  0x7f00     /* Channel 5 Connection Label */
 #define                      CIU5  0x8000     /* Channel 5 In Use */
-#define                     nCIU5  0x0       
 #define                       CL6  0x7f0000   /* Channel 6 Connection Label */
 #define                      CIU6  0x800000   /* Channel 6 In Use */
-#define                     nCIU6  0x0       
 #define                       CL7  0x7f000000 /* Channel 7 Connection Label */
 #define                      CIU7  0x80000000 /* Channel 7 In Use */
-#define                     nCIU7  0x0       
 
 /* Bit masks for MXVR_ALLOC_2 */
 
 #define                       CL8  0x7f       /* Channel 8 Connection Label */
 #define                      CIU8  0x80       /* Channel 8 In Use */
-#define                     nCIU8  0x0       
 #define                       CL9  0x7f00     /* Channel 9 Connection Label */
 #define                      CIU9  0x8000     /* Channel 9 In Use */
-#define                     nCIU9  0x0       
 #define                      CL10  0x7f0000   /* Channel 10 Connection Label */
 #define                     CIU10  0x800000   /* Channel 10 In Use */
-#define                    nCIU10  0x0       
 #define                      CL11  0x7f000000 /* Channel 11 Connection Label */
 #define                     CIU11  0x80000000 /* Channel 11 In Use */
-#define                    nCIU11  0x0       
 
 /* Bit masks for MXVR_ALLOC_3 */
 
 #define                      CL12  0x7f       /* Channel 12 Connection Label */
 #define                     CIU12  0x80       /* Channel 12 In Use */
-#define                    nCIU12  0x0       
 #define                      CL13  0x7f00     /* Channel 13 Connection Label */
 #define                     CIU13  0x8000     /* Channel 13 In Use */
-#define                    nCIU13  0x0       
 #define                      CL14  0x7f0000   /* Channel 14 Connection Label */
 #define                     CIU14  0x800000   /* Channel 14 In Use */
-#define                    nCIU14  0x0       
 #define                      CL15  0x7f000000 /* Channel 15 Connection Label */
 #define                     CIU15  0x80000000 /* Channel 15 In Use */
-#define                    nCIU15  0x0       
 
 /* Bit masks for MXVR_ALLOC_4 */
 
 #define                      CL16  0x7f       /* Channel 16 Connection Label */
 #define                     CIU16  0x80       /* Channel 16 In Use */
-#define                    nCIU16  0x0       
 #define                      CL17  0x7f00     /* Channel 17 Connection Label */
 #define                     CIU17  0x8000     /* Channel 17 In Use */
-#define                    nCIU17  0x0       
 #define                      CL18  0x7f0000   /* Channel 18 Connection Label */
 #define                     CIU18  0x800000   /* Channel 18 In Use */
-#define                    nCIU18  0x0       
 #define                      CL19  0x7f000000 /* Channel 19 Connection Label */
 #define                     CIU19  0x80000000 /* Channel 19 In Use */
-#define                    nCIU19  0x0       
 
 /* Bit masks for MXVR_ALLOC_5 */
 
 #define                      CL20  0x7f       /* Channel 20 Connection Label */
 #define                     CIU20  0x80       /* Channel 20 In Use */
-#define                    nCIU20  0x0       
 #define                      CL21  0x7f00     /* Channel 21 Connection Label */
 #define                     CIU21  0x8000     /* Channel 21 In Use */
-#define                    nCIU21  0x0       
 #define                      CL22  0x7f0000   /* Channel 22 Connection Label */
 #define                     CIU22  0x800000   /* Channel 22 In Use */
-#define                    nCIU22  0x0       
 #define                      CL23  0x7f000000 /* Channel 23 Connection Label */
 #define                     CIU23  0x80000000 /* Channel 23 In Use */
-#define                    nCIU23  0x0       
 
 /* Bit masks for MXVR_ALLOC_6 */
 
 #define                      CL24  0x7f       /* Channel 24 Connection Label */
 #define                     CIU24  0x80       /* Channel 24 In Use */
-#define                    nCIU24  0x0       
 #define                      CL25  0x7f00     /* Channel 25 Connection Label */
 #define                     CIU25  0x8000     /* Channel 25 In Use */
-#define                    nCIU25  0x0       
 #define                      CL26  0x7f0000   /* Channel 26 Connection Label */
 #define                     CIU26  0x800000   /* Channel 26 In Use */
-#define                    nCIU26  0x0       
 #define                      CL27  0x7f000000 /* Channel 27 Connection Label */
 #define                     CIU27  0x80000000 /* Channel 27 In Use */
-#define                    nCIU27  0x0       
 
 /* Bit masks for MXVR_ALLOC_7 */
 
 #define                      CL28  0x7f       /* Channel 28 Connection Label */
 #define                     CIU28  0x80       /* Channel 28 In Use */
-#define                    nCIU28  0x0       
 #define                      CL29  0x7f00     /* Channel 29 Connection Label */
 #define                     CIU29  0x8000     /* Channel 29 In Use */
-#define                    nCIU29  0x0       
 #define                      CL30  0x7f0000   /* Channel 30 Connection Label */
 #define                     CIU30  0x800000   /* Channel 30 In Use */
-#define                    nCIU30  0x0       
 #define                      CL31  0x7f000000 /* Channel 31 Connection Label */
 #define                     CIU31  0x80000000 /* Channel 31 In Use */
-#define                    nCIU31  0x0       
 
 /* Bit masks for MXVR_ALLOC_8 */
 
 #define                      CL32  0x7f       /* Channel 32 Connection Label */
 #define                     CIU32  0x80       /* Channel 32 In Use */
-#define                    nCIU32  0x0       
 #define                      CL33  0x7f00     /* Channel 33 Connection Label */
 #define                     CIU33  0x8000     /* Channel 33 In Use */
-#define                    nCIU33  0x0       
 #define                      CL34  0x7f0000   /* Channel 34 Connection Label */
 #define                     CIU34  0x800000   /* Channel 34 In Use */
-#define                    nCIU34  0x0       
 #define                      CL35  0x7f000000 /* Channel 35 Connection Label */
 #define                     CIU35  0x80000000 /* Channel 35 In Use */
-#define                    nCIU35  0x0       
 
 /* Bit masks for MXVR_ALLOC_9 */
 
 #define                      CL36  0x7f       /* Channel 36 Connection Label */
 #define                     CIU36  0x80       /* Channel 36 In Use */
-#define                    nCIU36  0x0       
 #define                      CL37  0x7f00     /* Channel 37 Connection Label */
 #define                     CIU37  0x8000     /* Channel 37 In Use */
-#define                    nCIU37  0x0       
 #define                      CL38  0x7f0000   /* Channel 38 Connection Label */
 #define                     CIU38  0x800000   /* Channel 38 In Use */
-#define                    nCIU38  0x0       
 #define                      CL39  0x7f000000 /* Channel 39 Connection Label */
 #define                     CIU39  0x80000000 /* Channel 39 In Use */
-#define                    nCIU39  0x0       
 
 /* Bit masks for MXVR_ALLOC_10 */
 
 #define                      CL40  0x7f       /* Channel 40 Connection Label */
 #define                     CIU40  0x80       /* Channel 40 In Use */
-#define                    nCIU40  0x0       
 #define                      CL41  0x7f00     /* Channel 41 Connection Label */
 #define                     CIU41  0x8000     /* Channel 41 In Use */
-#define                    nCIU41  0x0       
 #define                      CL42  0x7f0000   /* Channel 42 Connection Label */
 #define                     CIU42  0x800000   /* Channel 42 In Use */
-#define                    nCIU42  0x0       
 #define                      CL43  0x7f000000 /* Channel 43 Connection Label */
 #define                     CIU43  0x80000000 /* Channel 43 In Use */
-#define                    nCIU43  0x0       
 
 /* Bit masks for MXVR_ALLOC_11 */
 
 #define                      CL44  0x7f       /* Channel 44 Connection Label */
 #define                     CIU44  0x80       /* Channel 44 In Use */
-#define                    nCIU44  0x0       
 #define                      CL45  0x7f00     /* Channel 45 Connection Label */
 #define                     CIU45  0x8000     /* Channel 45 In Use */
-#define                    nCIU45  0x0       
 #define                      CL46  0x7f0000   /* Channel 46 Connection Label */
 #define                     CIU46  0x800000   /* Channel 46 In Use */
-#define                    nCIU46  0x0       
 #define                      CL47  0x7f000000 /* Channel 47 Connection Label */
 #define                     CIU47  0x80000000 /* Channel 47 In Use */
-#define                    nCIU47  0x0       
 
 /* Bit masks for MXVR_ALLOC_12 */
 
 #define                      CL48  0x7f       /* Channel 48 Connection Label */
 #define                     CIU48  0x80       /* Channel 48 In Use */
-#define                    nCIU48  0x0       
 #define                      CL49  0x7f00     /* Channel 49 Connection Label */
 #define                     CIU49  0x8000     /* Channel 49 In Use */
-#define                    nCIU49  0x0       
 #define                      CL50  0x7f0000   /* Channel 50 Connection Label */
 #define                     CIU50  0x800000   /* Channel 50 In Use */
-#define                    nCIU50  0x0       
 #define                      CL51  0x7f000000 /* Channel 51 Connection Label */
 #define                     CIU51  0x80000000 /* Channel 51 In Use */
-#define                    nCIU51  0x0       
 
 /* Bit masks for MXVR_ALLOC_13 */
 
 #define                      CL52  0x7f       /* Channel 52 Connection Label */
 #define                     CIU52  0x80       /* Channel 52 In Use */
-#define                    nCIU52  0x0       
 #define                      CL53  0x7f00     /* Channel 53 Connection Label */
 #define                     CIU53  0x8000     /* Channel 53 In Use */
-#define                    nCIU53  0x0       
 #define                      CL54  0x7f0000   /* Channel 54 Connection Label */
 #define                     CIU54  0x800000   /* Channel 54 In Use */
-#define                    nCIU54  0x0       
 #define                      CL55  0x7f000000 /* Channel 55 Connection Label */
 #define                     CIU55  0x80000000 /* Channel 55 In Use */
-#define                    nCIU55  0x0       
 
 /* Bit masks for MXVR_ALLOC_14 */
 
 #define                      CL56  0x7f       /* Channel 56 Connection Label */
 #define                     CIU56  0x80       /* Channel 56 In Use */
-#define                    nCIU56  0x0       
 #define                      CL57  0x7f00     /* Channel 57 Connection Label */
 #define                     CIU57  0x8000     /* Channel 57 In Use */
-#define                    nCIU57  0x0       
 #define                      CL58  0x7f0000   /* Channel 58 Connection Label */
 #define                     CIU58  0x800000   /* Channel 58 In Use */
-#define                    nCIU58  0x0       
 #define                      CL59  0x7f000000 /* Channel 59 Connection Label */
 #define                     CIU59  0x80000000 /* Channel 59 In Use */
-#define                    nCIU59  0x0       
 
 /* MXVR_SYNC_LCHAN_0 Masks */
 
 /* Bit masks for MXVR_DMAx_CONFIG */
 
 #define                    MDMAEN  0x1        /* DMA Channel Enable */
-#define                   nMDMAEN  0x0       
 #define                        DD  0x2        /* DMA Channel Direction */
-#define                       nDD  0x0       
 #define                 BY4SWAPEN  0x20       /* DMA Channel Four Byte Swap Enable */
-#define                nBY4SWAPEN  0x0       
 #define                     LCHAN  0x3c0      /* DMA Channel Logical Channel */
 #define                 BITSWAPEN  0x400      /* DMA Channel Bit Swap Enable */
-#define                nBITSWAPEN  0x0       
 #define                 BY2SWAPEN  0x800      /* DMA Channel Two Byte Swap Enable */
-#define                nBY2SWAPEN  0x0       
 #define                     MFLOW  0x7000     /* DMA Channel Operation Flow */
 #define                   FIXEDPM  0x80000    /* DMA Channel Fixed Pattern Matching Select */
-#define                  nFIXEDPM  0x0       
 #define                  STARTPAT  0x300000   /* DMA Channel Start Pattern Select */
 #define                   STOPPAT  0xc00000   /* DMA Channel Stop Pattern Select */
 #define                  COUNTPOS  0x1c000000 /* DMA Channel Count Position */
 /* Bit masks for MXVR_AP_CTL */
 
 #define                   STARTAP  0x1        /* Start Asynchronous Packet Transmission */
-#define                  nSTARTAP  0x0       
 #define                  CANCELAP  0x2        /* Cancel Asynchronous Packet Transmission */
-#define                 nCANCELAP  0x0       
 #define                   RESETAP  0x4        /* Reset Asynchronous Packet Arbitration */
-#define                  nRESETAP  0x0       
 #define                    APRBE0  0x4000     /* Asynchronous Packet Receive Buffer Entry 0 */
-#define                   nAPRBE0  0x0       
 #define                    APRBE1  0x8000     /* Asynchronous Packet Receive Buffer Entry 1 */
-#define                   nAPRBE1  0x0       
 
 /* Bit masks for MXVR_APRB_START_ADDR */
 
-#define      MXVR_APRB_START_ADDR  0x1fffffe  /* Asynchronous Packet Receive Buffer Start Address */
+#define      MXVR_APRB_START_ADDR_MASK  0x1fffffe  /* Asynchronous Packet Receive Buffer Start Address */
 
 /* Bit masks for MXVR_APRB_CURR_ADDR */
 
-#define       MXVR_APRB_CURR_ADDR  0xffffffff /* Asynchronous Packet Receive Buffer Current Address */
+#define       MXVR_APRB_CURR_ADDR_MASK  0xffffffff /* Asynchronous Packet Receive Buffer Current Address */
 
 /* Bit masks for MXVR_APTB_START_ADDR */
 
-#define       MXVR_APTB_START_ADDR  0x1fffffe  /* Asynchronous Packet Transmit Buffer Start Address */
+#define       MXVR_APTB_START_ADDR_MASK  0x1fffffe  /* Asynchronous Packet Transmit Buffer Start Address */
 
 /* Bit masks for MXVR_APTB_CURR_ADDR */
 
-#define        MXVR_APTB_CURR_ADDR  0xffffffff /* Asynchronous Packet Transmit Buffer Current Address */
+#define        MXVR_APTB_CURR_ADDR_MASK  0xffffffff /* Asynchronous Packet Transmit Buffer Current Address */
 
 /* Bit masks for MXVR_CM_CTL */
 
 #define                   STARTCM  0x1        /* Start Control Message Transmission */
-#define                  nSTARTCM  0x0       
 #define                  CANCELCM  0x2        /* Cancel Control Message Transmission */
-#define                 nCANCELCM  0x0       
 #define                    CMRBE0  0x10000    /* Control Message Receive Buffer Entry 0 */
-#define                   nCMRBE0  0x0       
 #define                    CMRBE1  0x20000    /* Control Message Receive Buffer Entry 1 */
-#define                   nCMRBE1  0x0       
 #define                    CMRBE2  0x40000    /* Control Message Receive Buffer Entry 2 */
-#define                   nCMRBE2  0x0       
 #define                    CMRBE3  0x80000    /* Control Message Receive Buffer Entry 3 */
-#define                   nCMRBE3  0x0       
 #define                    CMRBE4  0x100000   /* Control Message Receive Buffer Entry 4 */
-#define                   nCMRBE4  0x0       
 #define                    CMRBE5  0x200000   /* Control Message Receive Buffer Entry 5 */
-#define                   nCMRBE5  0x0       
 #define                    CMRBE6  0x400000   /* Control Message Receive Buffer Entry 6 */
-#define                   nCMRBE6  0x0       
 #define                    CMRBE7  0x800000   /* Control Message Receive Buffer Entry 7 */
-#define                   nCMRBE7  0x0       
 #define                    CMRBE8  0x1000000  /* Control Message Receive Buffer Entry 8 */
-#define                   nCMRBE8  0x0       
 #define                    CMRBE9  0x2000000  /* Control Message Receive Buffer Entry 9 */
-#define                   nCMRBE9  0x0       
 #define                   CMRBE10  0x4000000  /* Control Message Receive Buffer Entry 10 */
-#define                  nCMRBE10  0x0       
 #define                   CMRBE11  0x8000000  /* Control Message Receive Buffer Entry 11 */
-#define                  nCMRBE11  0x0       
 #define                   CMRBE12  0x10000000 /* Control Message Receive Buffer Entry 12 */
-#define                  nCMRBE12  0x0       
 #define                   CMRBE13  0x20000000 /* Control Message Receive Buffer Entry 13 */
-#define                  nCMRBE13  0x0       
 #define                   CMRBE14  0x40000000 /* Control Message Receive Buffer Entry 14 */
-#define                  nCMRBE14  0x0       
 #define                   CMRBE15  0x80000000 /* Control Message Receive Buffer Entry 15 */
-#define                  nCMRBE15  0x0       
 
 /* Bit masks for MXVR_CMRB_START_ADDR */
 
-#define      MXVR_CMRB_START_ADDR  0x1fffffe  /* Control Message Receive Buffer Start Address */
+#define      MXVR_CMRB_START_ADDR_MASK  0x1fffffe  /* Control Message Receive Buffer Start Address */
 
 /* Bit masks for MXVR_CMRB_CURR_ADDR */
 
-#define       MXVR_CMRB_CURR_ADDR  0xffffffff /* Control Message Receive Buffer Current Address */
+#define       MXVR_CMRB_CURR_ADDR_MASK  0xffffffff /* Control Message Receive Buffer Current Address */
 
 /* Bit masks for MXVR_CMTB_START_ADDR */
 
-#define      MXVR_CMTB_START_ADDR  0x1fffffe  /* Control Message Transmit Buffer Start Address */
+#define      MXVR_CMTB_START_ADDR_MASK  0x1fffffe  /* Control Message Transmit Buffer Start Address */
 
 /* Bit masks for MXVR_CMTB_CURR_ADDR */
 
-#define       MXVR_CMTB_CURR_ADDR  0xffffffff /* Control Message Transmit Buffer Current Address */
+#define       MXVR_CMTB_CURR_ADDR_MASK  0xffffffff /* Control Message Transmit Buffer Current Address */
 
 /* Bit masks for MXVR_RRDB_START_ADDR */
 
-#define      MXVR_RRDB_START_ADDR  0x1fffffe  /* Remote Read Buffer Start Address */
+#define      MXVR_RRDB_START_ADDR_MASK  0x1fffffe  /* Remote Read Buffer Start Address */
 
 /* Bit masks for MXVR_RRDB_CURR_ADDR */
 
-#define       MXVR_RRDB_CURR_ADDR  0xffffffff /* Remote Read Buffer Current Address */
+#define       MXVR_RRDB_CURR_ADDR_MASK  0xffffffff /* Remote Read Buffer Current Address */
 
 /* Bit masks for MXVR_PAT_DATAx */
 
 /* Bit masks for MXVR_PAT_EN_0 */
 
 #define              MATCH_EN_0_0  0x1        /* Pattern Match Enable Byte 0 Bit 0 */
-#define             nMATCH_EN_0_0  0x0       
 #define              MATCH_EN_0_1  0x2        /* Pattern Match Enable Byte 0 Bit 1 */
-#define             nMATCH_EN_0_1  0x0       
 #define              MATCH_EN_0_2  0x4        /* Pattern Match Enable Byte 0 Bit 2 */
-#define             nMATCH_EN_0_2  0x0       
 #define              MATCH_EN_0_3  0x8        /* Pattern Match Enable Byte 0 Bit 3 */
-#define             nMATCH_EN_0_3  0x0       
 #define              MATCH_EN_0_4  0x10       /* Pattern Match Enable Byte 0 Bit 4 */
-#define             nMATCH_EN_0_4  0x0       
 #define              MATCH_EN_0_5  0x20       /* Pattern Match Enable Byte 0 Bit 5 */
-#define             nMATCH_EN_0_5  0x0       
 #define              MATCH_EN_0_6  0x40       /* Pattern Match Enable Byte 0 Bit 6 */
-#define             nMATCH_EN_0_6  0x0       
 #define              MATCH_EN_0_7  0x80       /* Pattern Match Enable Byte 0 Bit 7 */
-#define             nMATCH_EN_0_7  0x0       
 #define              MATCH_EN_1_0  0x100      /* Pattern Match Enable Byte 1 Bit 0 */
-#define             nMATCH_EN_1_0  0x0       
 #define              MATCH_EN_1_1  0x200      /* Pattern Match Enable Byte 1 Bit 1 */
-#define             nMATCH_EN_1_1  0x0       
 #define              MATCH_EN_1_2  0x400      /* Pattern Match Enable Byte 1 Bit 2 */
-#define             nMATCH_EN_1_2  0x0       
 #define              MATCH_EN_1_3  0x800      /* Pattern Match Enable Byte 1 Bit 3 */
-#define             nMATCH_EN_1_3  0x0       
 #define              MATCH_EN_1_4  0x1000     /* Pattern Match Enable Byte 1 Bit 4 */
-#define             nMATCH_EN_1_4  0x0       
 #define              MATCH_EN_1_5  0x2000     /* Pattern Match Enable Byte 1 Bit 5 */
-#define             nMATCH_EN_1_5  0x0       
 #define              MATCH_EN_1_6  0x4000     /* Pattern Match Enable Byte 1 Bit 6 */
-#define             nMATCH_EN_1_6  0x0       
 #define              MATCH_EN_1_7  0x8000     /* Pattern Match Enable Byte 1 Bit 7 */
-#define             nMATCH_EN_1_7  0x0       
 #define              MATCH_EN_2_0  0x10000    /* Pattern Match Enable Byte 2 Bit 0 */
-#define             nMATCH_EN_2_0  0x0       
 #define              MATCH_EN_2_1  0x20000    /* Pattern Match Enable Byte 2 Bit 1 */
-#define             nMATCH_EN_2_1  0x0       
 #define              MATCH_EN_2_2  0x40000    /* Pattern Match Enable Byte 2 Bit 2 */
-#define             nMATCH_EN_2_2  0x0       
 #define              MATCH_EN_2_3  0x80000    /* Pattern Match Enable Byte 2 Bit 3 */
-#define             nMATCH_EN_2_3  0x0       
 #define              MATCH_EN_2_4  0x100000   /* Pattern Match Enable Byte 2 Bit 4 */
-#define             nMATCH_EN_2_4  0x0       
 #define              MATCH_EN_2_5  0x200000   /* Pattern Match Enable Byte 2 Bit 5 */
-#define             nMATCH_EN_2_5  0x0       
 #define              MATCH_EN_2_6  0x400000   /* Pattern Match Enable Byte 2 Bit 6 */
-#define             nMATCH_EN_2_6  0x0       
 #define              MATCH_EN_2_7  0x800000   /* Pattern Match Enable Byte 2 Bit 7 */
-#define             nMATCH_EN_2_7  0x0       
 #define              MATCH_EN_3_0  0x1000000  /* Pattern Match Enable Byte 3 Bit 0 */
-#define             nMATCH_EN_3_0  0x0       
 #define              MATCH_EN_3_1  0x2000000  /* Pattern Match Enable Byte 3 Bit 1 */
-#define             nMATCH_EN_3_1  0x0       
 #define              MATCH_EN_3_2  0x4000000  /* Pattern Match Enable Byte 3 Bit 2 */
-#define             nMATCH_EN_3_2  0x0       
 #define              MATCH_EN_3_3  0x8000000  /* Pattern Match Enable Byte 3 Bit 3 */
-#define             nMATCH_EN_3_3  0x0       
 #define              MATCH_EN_3_4  0x10000000 /* Pattern Match Enable Byte 3 Bit 4 */
-#define             nMATCH_EN_3_4  0x0       
 #define              MATCH_EN_3_5  0x20000000 /* Pattern Match Enable Byte 3 Bit 5 */
-#define             nMATCH_EN_3_5  0x0       
 #define              MATCH_EN_3_6  0x40000000 /* Pattern Match Enable Byte 3 Bit 6 */
-#define             nMATCH_EN_3_6  0x0       
 #define              MATCH_EN_3_7  0x80000000 /* Pattern Match Enable Byte 3 Bit 7 */
-#define             nMATCH_EN_3_7  0x0       
 
 /* Bit masks for MXVR_PAT_EN_1 */
 
 #define              MATCH_EN_0_0  0x1        /* Pattern Match Enable Byte 0 Bit 0 */
-#define             nMATCH_EN_0_0  0x0       
 #define              MATCH_EN_0_1  0x2        /* Pattern Match Enable Byte 0 Bit 1 */
-#define             nMATCH_EN_0_1  0x0       
 #define              MATCH_EN_0_2  0x4        /* Pattern Match Enable Byte 0 Bit 2 */
-#define             nMATCH_EN_0_2  0x0       
 #define              MATCH_EN_0_3  0x8        /* Pattern Match Enable Byte 0 Bit 3 */
-#define             nMATCH_EN_0_3  0x0       
 #define              MATCH_EN_0_4  0x10       /* Pattern Match Enable Byte 0 Bit 4 */
-#define             nMATCH_EN_0_4  0x0       
 #define              MATCH_EN_0_5  0x20       /* Pattern Match Enable Byte 0 Bit 5 */
-#define             nMATCH_EN_0_5  0x0       
 #define              MATCH_EN_0_6  0x40       /* Pattern Match Enable Byte 0 Bit 6 */
-#define             nMATCH_EN_0_6  0x0       
 #define              MATCH_EN_0_7  0x80       /* Pattern Match Enable Byte 0 Bit 7 */
-#define             nMATCH_EN_0_7  0x0       
 #define              MATCH_EN_1_0  0x100      /* Pattern Match Enable Byte 1 Bit 0 */
-#define             nMATCH_EN_1_0  0x0       
 #define              MATCH_EN_1_1  0x200      /* Pattern Match Enable Byte 1 Bit 1 */
-#define             nMATCH_EN_1_1  0x0       
 #define              MATCH_EN_1_2  0x400      /* Pattern Match Enable Byte 1 Bit 2 */
-#define             nMATCH_EN_1_2  0x0       
 #define              MATCH_EN_1_3  0x800      /* Pattern Match Enable Byte 1 Bit 3 */
-#define             nMATCH_EN_1_3  0x0       
 #define              MATCH_EN_1_4  0x1000     /* Pattern Match Enable Byte 1 Bit 4 */
-#define             nMATCH_EN_1_4  0x0       
 #define              MATCH_EN_1_5  0x2000     /* Pattern Match Enable Byte 1 Bit 5 */
-#define             nMATCH_EN_1_5  0x0       
 #define              MATCH_EN_1_6  0x4000     /* Pattern Match Enable Byte 1 Bit 6 */
-#define             nMATCH_EN_1_6  0x0       
 #define              MATCH_EN_1_7  0x8000     /* Pattern Match Enable Byte 1 Bit 7 */
-#define             nMATCH_EN_1_7  0x0       
 #define              MATCH_EN_2_0  0x10000    /* Pattern Match Enable Byte 2 Bit 0 */
-#define             nMATCH_EN_2_0  0x0       
 #define              MATCH_EN_2_1  0x20000    /* Pattern Match Enable Byte 2 Bit 1 */
-#define             nMATCH_EN_2_1  0x0       
 #define              MATCH_EN_2_2  0x40000    /* Pattern Match Enable Byte 2 Bit 2 */
-#define             nMATCH_EN_2_2  0x0       
 #define              MATCH_EN_2_3  0x80000    /* Pattern Match Enable Byte 2 Bit 3 */
-#define             nMATCH_EN_2_3  0x0       
 #define              MATCH_EN_2_4  0x100000   /* Pattern Match Enable Byte 2 Bit 4 */
-#define             nMATCH_EN_2_4  0x0       
 #define              MATCH_EN_2_5  0x200000   /* Pattern Match Enable Byte 2 Bit 5 */
-#define             nMATCH_EN_2_5  0x0       
 #define              MATCH_EN_2_6  0x400000   /* Pattern Match Enable Byte 2 Bit 6 */
-#define             nMATCH_EN_2_6  0x0       
 #define              MATCH_EN_2_7  0x800000   /* Pattern Match Enable Byte 2 Bit 7 */
-#define             nMATCH_EN_2_7  0x0       
 #define              MATCH_EN_3_0  0x1000000  /* Pattern Match Enable Byte 3 Bit 0 */
-#define             nMATCH_EN_3_0  0x0       
 #define              MATCH_EN_3_1  0x2000000  /* Pattern Match Enable Byte 3 Bit 1 */
-#define             nMATCH_EN_3_1  0x0       
 #define              MATCH_EN_3_2  0x4000000  /* Pattern Match Enable Byte 3 Bit 2 */
-#define             nMATCH_EN_3_2  0x0       
 #define              MATCH_EN_3_3  0x8000000  /* Pattern Match Enable Byte 3 Bit 3 */
-#define             nMATCH_EN_3_3  0x0       
 #define              MATCH_EN_3_4  0x10000000 /* Pattern Match Enable Byte 3 Bit 4 */
-#define             nMATCH_EN_3_4  0x0       
 #define              MATCH_EN_3_5  0x20000000 /* Pattern Match Enable Byte 3 Bit 5 */
-#define             nMATCH_EN_3_5  0x0       
 #define              MATCH_EN_3_6  0x40000000 /* Pattern Match Enable Byte 3 Bit 6 */
-#define             nMATCH_EN_3_6  0x0       
 #define              MATCH_EN_3_7  0x80000000 /* Pattern Match Enable Byte 3 Bit 7 */
-#define             nMATCH_EN_3_7  0x0       
 
 /* Bit masks for MXVR_FRAME_CNT_0 */
 
 
 #define                    TX_CH0  0x3f       /* Transmit Channel 0 */
 #define                  MUTE_CH0  0x80       /* Mute Channel 0 */
-#define                 nMUTE_CH0  0x0       
 #define                    TX_CH1  0x3f00     /* Transmit Channel 0 */
 #define                  MUTE_CH1  0x8000     /* Mute Channel 0 */
-#define                 nMUTE_CH1  0x0       
 #define                    TX_CH2  0x3f0000   /* Transmit Channel 0 */
 #define                  MUTE_CH2  0x800000   /* Mute Channel 0 */
-#define                 nMUTE_CH2  0x0       
 #define                    TX_CH3  0x3f000000 /* Transmit Channel 0 */
 #define                  MUTE_CH3  0x80000000 /* Mute Channel 0 */
-#define                 nMUTE_CH3  0x0       
 
 /* Bit masks for MXVR_ROUTING_1 */
 
 #define                    TX_CH4  0x3f       /* Transmit Channel 4 */
 #define                  MUTE_CH4  0x80       /* Mute Channel 4 */
-#define                 nMUTE_CH4  0x0       
 #define                    TX_CH5  0x3f00     /* Transmit Channel 5 */
 #define                  MUTE_CH5  0x8000     /* Mute Channel 5 */
-#define                 nMUTE_CH5  0x0       
 #define                    TX_CH6  0x3f0000   /* Transmit Channel 6 */
 #define                  MUTE_CH6  0x800000   /* Mute Channel 6 */
-#define                 nMUTE_CH6  0x0       
 #define                    TX_CH7  0x3f000000 /* Transmit Channel 7 */
 #define                  MUTE_CH7  0x80000000 /* Mute Channel 7 */
-#define                 nMUTE_CH7  0x0       
 
 /* Bit masks for MXVR_ROUTING_2 */
 
 #define                    TX_CH8  0x3f       /* Transmit Channel 8 */
 #define                  MUTE_CH8  0x80       /* Mute Channel 8 */
-#define                 nMUTE_CH8  0x0       
 #define                    TX_CH9  0x3f00     /* Transmit Channel 9 */
 #define                  MUTE_CH9  0x8000     /* Mute Channel 9 */
-#define                 nMUTE_CH9  0x0       
 #define                   TX_CH10  0x3f0000   /* Transmit Channel 10 */
 #define                 MUTE_CH10  0x800000   /* Mute Channel 10 */
-#define                nMUTE_CH10  0x0       
 #define                   TX_CH11  0x3f000000 /* Transmit Channel 11 */
 #define                 MUTE_CH11  0x80000000 /* Mute Channel 11 */
-#define                nMUTE_CH11  0x0       
 
 /* Bit masks for MXVR_ROUTING_3 */
 
 #define                   TX_CH12  0x3f       /* Transmit Channel 12 */
 #define                 MUTE_CH12  0x80       /* Mute Channel 12 */
-#define                nMUTE_CH12  0x0       
 #define                   TX_CH13  0x3f00     /* Transmit Channel 13 */
 #define                 MUTE_CH13  0x8000     /* Mute Channel 13 */
-#define                nMUTE_CH13  0x0       
 #define                   TX_CH14  0x3f0000   /* Transmit Channel 14 */
 #define                 MUTE_CH14  0x800000   /* Mute Channel 14 */
-#define                nMUTE_CH14  0x0       
 #define                   TX_CH15  0x3f000000 /* Transmit Channel 15 */
 #define                 MUTE_CH15  0x80000000 /* Mute Channel 15 */
-#define                nMUTE_CH15  0x0       
 
 /* Bit masks for MXVR_ROUTING_4 */
 
 #define                   TX_CH16  0x3f       /* Transmit Channel 16 */
 #define                 MUTE_CH16  0x80       /* Mute Channel 16 */
-#define                nMUTE_CH16  0x0       
 #define                   TX_CH17  0x3f00     /* Transmit Channel 17 */
 #define                 MUTE_CH17  0x8000     /* Mute Channel 17 */
-#define                nMUTE_CH17  0x0       
 #define                   TX_CH18  0x3f0000   /* Transmit Channel 18 */
 #define                 MUTE_CH18  0x800000   /* Mute Channel 18 */
-#define                nMUTE_CH18  0x0       
 #define                   TX_CH19  0x3f000000 /* Transmit Channel 19 */
 #define                 MUTE_CH19  0x80000000 /* Mute Channel 19 */
-#define                nMUTE_CH19  0x0       
 
 /* Bit masks for MXVR_ROUTING_5 */
 
 #define                   TX_CH20  0x3f       /* Transmit Channel 20 */
 #define                 MUTE_CH20  0x80       /* Mute Channel 20 */
-#define                nMUTE_CH20  0x0       
 #define                   TX_CH21  0x3f00     /* Transmit Channel 21 */
 #define                 MUTE_CH21  0x8000     /* Mute Channel 21 */
-#define                nMUTE_CH21  0x0       
 #define                   TX_CH22  0x3f0000   /* Transmit Channel 22 */
 #define                 MUTE_CH22  0x800000   /* Mute Channel 22 */
-#define                nMUTE_CH22  0x0       
 #define                   TX_CH23  0x3f000000 /* Transmit Channel 23 */
 #define                 MUTE_CH23  0x80000000 /* Mute Channel 23 */
-#define                nMUTE_CH23  0x0       
 
 /* Bit masks for MXVR_ROUTING_6 */
 
 #define                   TX_CH24  0x3f       /* Transmit Channel 24 */
 #define                 MUTE_CH24  0x80       /* Mute Channel 24 */
-#define                nMUTE_CH24  0x0       
 #define                   TX_CH25  0x3f00     /* Transmit Channel 25 */
 #define                 MUTE_CH25  0x8000     /* Mute Channel 25 */
-#define                nMUTE_CH25  0x0       
 #define                   TX_CH26  0x3f0000   /* Transmit Channel 26 */
 #define                 MUTE_CH26  0x800000   /* Mute Channel 26 */
-#define                nMUTE_CH26  0x0       
 #define                   TX_CH27  0x3f000000 /* Transmit Channel 27 */
 #define                 MUTE_CH27  0x80000000 /* Mute Channel 27 */
-#define                nMUTE_CH27  0x0       
 
 /* Bit masks for MXVR_ROUTING_7 */
 
 #define                   TX_CH28  0x3f       /* Transmit Channel 28 */
 #define                 MUTE_CH28  0x80       /* Mute Channel 28 */
-#define                nMUTE_CH28  0x0       
 #define                   TX_CH29  0x3f00     /* Transmit Channel 29 */
 #define                 MUTE_CH29  0x8000     /* Mute Channel 29 */
-#define                nMUTE_CH29  0x0       
 #define                   TX_CH30  0x3f0000   /* Transmit Channel 30 */
 #define                 MUTE_CH30  0x800000   /* Mute Channel 30 */
-#define                nMUTE_CH30  0x0       
 #define                   TX_CH31  0x3f000000 /* Transmit Channel 31 */
 #define                 MUTE_CH31  0x80000000 /* Mute Channel 31 */
-#define                nMUTE_CH31  0x0       
 
 /* Bit masks for MXVR_ROUTING_8 */
 
 #define                   TX_CH32  0x3f       /* Transmit Channel 32 */
 #define                 MUTE_CH32  0x80       /* Mute Channel 32 */
-#define                nMUTE_CH32  0x0       
 #define                   TX_CH33  0x3f00     /* Transmit Channel 33 */
 #define                 MUTE_CH33  0x8000     /* Mute Channel 33 */
-#define                nMUTE_CH33  0x0       
 #define                   TX_CH34  0x3f0000   /* Transmit Channel 34 */
 #define                 MUTE_CH34  0x800000   /* Mute Channel 34 */
-#define                nMUTE_CH34  0x0       
 #define                   TX_CH35  0x3f000000 /* Transmit Channel 35 */
 #define                 MUTE_CH35  0x80000000 /* Mute Channel 35 */
-#define                nMUTE_CH35  0x0       
 
 /* Bit masks for MXVR_ROUTING_9 */
 
 #define                   TX_CH36  0x3f       /* Transmit Channel 36 */
 #define                 MUTE_CH36  0x80       /* Mute Channel 36 */
-#define                nMUTE_CH36  0x0       
 #define                   TX_CH37  0x3f00     /* Transmit Channel 37 */
 #define                 MUTE_CH37  0x8000     /* Mute Channel 37 */
-#define                nMUTE_CH37  0x0       
 #define                   TX_CH38  0x3f0000   /* Transmit Channel 38 */
 #define                 MUTE_CH38  0x800000   /* Mute Channel 38 */
-#define                nMUTE_CH38  0x0       
 #define                   TX_CH39  0x3f000000 /* Transmit Channel 39 */
 #define                 MUTE_CH39  0x80000000 /* Mute Channel 39 */
-#define                nMUTE_CH39  0x0       
 
 /* Bit masks for MXVR_ROUTING_10 */
 
 #define                   TX_CH40  0x3f       /* Transmit Channel 40 */
 #define                 MUTE_CH40  0x80       /* Mute Channel 40 */
-#define                nMUTE_CH40  0x0       
 #define                   TX_CH41  0x3f00     /* Transmit Channel 41 */
 #define                 MUTE_CH41  0x8000     /* Mute Channel 41 */
-#define                nMUTE_CH41  0x0       
 #define                   TX_CH42  0x3f0000   /* Transmit Channel 42 */
 #define                 MUTE_CH42  0x800000   /* Mute Channel 42 */
-#define                nMUTE_CH42  0x0       
 #define                   TX_CH43  0x3f000000 /* Transmit Channel 43 */
 #define                 MUTE_CH43  0x80000000 /* Mute Channel 43 */
-#define                nMUTE_CH43  0x0       
 
 /* Bit masks for MXVR_ROUTING_11 */
 
 #define                   TX_CH44  0x3f       /* Transmit Channel 44 */
 #define                 MUTE_CH44  0x80       /* Mute Channel 44 */
-#define                nMUTE_CH44  0x0       
 #define                   TX_CH45  0x3f00     /* Transmit Channel 45 */
 #define                 MUTE_CH45  0x8000     /* Mute Channel 45 */
-#define                nMUTE_CH45  0x0       
 #define                   TX_CH46  0x3f0000   /* Transmit Channel 46 */
 #define                 MUTE_CH46  0x800000   /* Mute Channel 46 */
-#define                nMUTE_CH46  0x0       
 #define                   TX_CH47  0x3f000000 /* Transmit Channel 47 */
 #define                 MUTE_CH47  0x80000000 /* Mute Channel 47 */
-#define                nMUTE_CH47  0x0       
 
 /* Bit masks for MXVR_ROUTING_12 */
 
 #define                   TX_CH48  0x3f       /* Transmit Channel 48 */
 #define                 MUTE_CH48  0x80       /* Mute Channel 48 */
-#define                nMUTE_CH48  0x0       
 #define                   TX_CH49  0x3f00     /* Transmit Channel 49 */
 #define                 MUTE_CH49  0x8000     /* Mute Channel 49 */
-#define                nMUTE_CH49  0x0       
 #define                   TX_CH50  0x3f0000   /* Transmit Channel 50 */
 #define                 MUTE_CH50  0x800000   /* Mute Channel 50 */
-#define                nMUTE_CH50  0x0       
 #define                   TX_CH51  0x3f000000 /* Transmit Channel 51 */
 #define                 MUTE_CH51  0x80000000 /* Mute Channel 51 */
-#define                nMUTE_CH51  0x0       
 
 /* Bit masks for MXVR_ROUTING_13 */
 
 #define                   TX_CH52  0x3f       /* Transmit Channel 52 */
 #define                 MUTE_CH52  0x80       /* Mute Channel 52 */
-#define                nMUTE_CH52  0x0       
 #define                   TX_CH53  0x3f00     /* Transmit Channel 53 */
 #define                 MUTE_CH53  0x8000     /* Mute Channel 53 */
-#define                nMUTE_CH53  0x0       
 #define                   TX_CH54  0x3f0000   /* Transmit Channel 54 */
 #define                 MUTE_CH54  0x800000   /* Mute Channel 54 */
-#define                nMUTE_CH54  0x0       
 #define                   TX_CH55  0x3f000000 /* Transmit Channel 55 */
 #define                 MUTE_CH55  0x80000000 /* Mute Channel 55 */
-#define                nMUTE_CH55  0x0       
 
 /* Bit masks for MXVR_ROUTING_14 */
 
 #define                   TX_CH56  0x3f       /* Transmit Channel 56 */
 #define                 MUTE_CH56  0x80       /* Mute Channel 56 */
-#define                nMUTE_CH56  0x0       
 #define                   TX_CH57  0x3f00     /* Transmit Channel 57 */
 #define                 MUTE_CH57  0x8000     /* Mute Channel 57 */
-#define                nMUTE_CH57  0x0       
 #define                   TX_CH58  0x3f0000   /* Transmit Channel 58 */
 #define                 MUTE_CH58  0x800000   /* Mute Channel 58 */
-#define                nMUTE_CH58  0x0       
 #define                   TX_CH59  0x3f000000 /* Transmit Channel 59 */
 #define                 MUTE_CH59  0x80000000 /* Mute Channel 59 */
-#define                nMUTE_CH59  0x0       
 
 /* Bit masks for MXVR_BLOCK_CNT */
 
 /* Bit masks for MXVR_CLK_CTL */
 
 #define                  MXTALCEN  0x1        /* MXVR Crystal Oscillator Clock Enable */
-#define                 nMXTALCEN  0x0       
 #define                  MXTALFEN  0x2        /* MXVR Crystal Oscillator Feedback Enable */
-#define                 nMXTALFEN  0x0       
 #define                  MXTALMUL  0x30       /* MXVR Crystal Multiplier */
 #define                  CLKX3SEL  0x80       /* Clock Generation Source Select */
-#define                 nCLKX3SEL  0x0       
 #define                   MMCLKEN  0x100      /* Master Clock Enable */
-#define                  nMMCLKEN  0x0       
 #define                  MMCLKMUL  0x1e00     /* Master Clock Multiplication Factor */
 #define                   PLLSMPS  0xe000     /* MXVR PLL State Machine Prescaler */
 #define                   MBCLKEN  0x10000    /* Bit Clock Enable */
-#define                  nMBCLKEN  0x0       
 #define                  MBCLKDIV  0x1e0000   /* Bit Clock Divide Factor */
 #define                     INVRX  0x800000   /* Invert Receive Data */
-#define                    nINVRX  0x0       
 #define                     MFSEN  0x1000000  /* Frame Sync Enable */
-#define                    nMFSEN  0x0       
 #define                    MFSDIV  0x1e000000 /* Frame Sync Divide Factor */
 #define                    MFSSEL  0x60000000 /* Frame Sync Select */
 #define                   MFSSYNC  0x80000000 /* Frame Sync Synchronization Select */
-#define                  nMFSSYNC  0x0       
 
 /* Bit masks for MXVR_CDRPLL_CTL */
 
 #define                   CDRSMEN  0x1        /* MXVR CDRPLL State Machine Enable */
-#define                  nCDRSMEN  0x0       
 #define                   CDRRSTB  0x2        /* MXVR CDRPLL Reset */
-#define                  nCDRRSTB  0x0       
 #define                   CDRSVCO  0x4        /* MXVR CDRPLL Start VCO */
-#define                  nCDRSVCO  0x0       
 #define                   CDRMODE  0x8        /* MXVR CDRPLL CDR Mode Select */
-#define                  nCDRMODE  0x0       
 #define                   CDRSCNT  0x3f0      /* MXVR CDRPLL Start Counter */
 #define                   CDRLCNT  0xfc00     /* MXVR CDRPLL Lock Counter */
 #define                 CDRSHPSEL  0x3f0000   /* MXVR CDRPLL Shaper Select */
 #define                  CDRSHPEN  0x800000   /* MXVR CDRPLL Shaper Enable */
-#define                 nCDRSHPEN  0x0       
 #define                  CDRCPSEL  0xff000000 /* MXVR CDRPLL Charge Pump Current Select */
 
 /* Bit masks for MXVR_FMPLL_CTL */
 
 #define                    FMSMEN  0x1        /* MXVR FMPLL State Machine Enable */
-#define                   nFMSMEN  0x0       
 #define                    FMRSTB  0x2        /* MXVR FMPLL Reset */
-#define                   nFMRSTB  0x0       
 #define                    FMSVCO  0x4        /* MXVR FMPLL Start VCO */
-#define                   nFMSVCO  0x0       
 #define                    FMSCNT  0x3f0      /* MXVR FMPLL Start Counter */
 #define                    FMLCNT  0xfc00     /* MXVR FMPLL Lock Counter */
 #define                   FMCPSEL  0xff000000 /* MXVR FMPLL Charge Pump Current Select */
 /* Bit masks for MXVR_PIN_CTL */
 
 #define                  MTXONBOD  0x1        /* MTXONB Open Drain Select */
-#define                 nMTXONBOD  0x0       
 #define                   MTXONBG  0x2        /* MTXONB Gates MTX Select */
-#define                  nMTXONBG  0x0       
 #define                     MFSOE  0x10       /* MFS Output Enable */
-#define                    nMFSOE  0x0       
 #define                  MFSGPSEL  0x20       /* MFS General Purpose Output Select */
-#define                 nMFSGPSEL  0x0       
 #define                  MFSGPDAT  0x40       /* MFS General Purpose Output Data */
-#define                 nMFSGPDAT  0x0       
 
 /* Bit masks for MXVR_SCLK_CNT */
 
 /* Bit masks for KPAD_CTL */
 
 #define                   KPAD_EN  0x1        /* Keypad Enable */
-#define                  nKPAD_EN  0x0       
 #define              KPAD_IRQMODE  0x6        /* Key Press Interrupt Enable */
 #define                KPAD_ROWEN  0x1c00     /* Row Enable Width */
 #define                KPAD_COLEN  0xe000     /* Column Enable Width */
 /* Bit masks for KPAD_STAT */
 
 #define                  KPAD_IRQ  0x1        /* Keypad Interrupt Status */
-#define                 nKPAD_IRQ  0x0       
 #define              KPAD_MROWCOL  0x6        /* Multiple Row/Column Keypress Status */
 #define              KPAD_PRESSED  0x8        /* Key press current status */
-#define             nKPAD_PRESSED  0x0       
 
 /* Bit masks for KPAD_SOFTEVAL */
 
 #define           KPAD_SOFTEVAL_E  0x2        /* Software Programmable Force Evaluate */
-#define          nKPAD_SOFTEVAL_E  0x0       
 
 /* Bit masks for SDH_COMMAND */
 
 #define                   CMD_IDX  0x3f       /* Command Index */
 #define                   CMD_RSP  0x40       /* Response */
-#define                  nCMD_RSP  0x0       
 #define                 CMD_L_RSP  0x80       /* Long Response */
-#define                nCMD_L_RSP  0x0       
 #define                 CMD_INT_E  0x100      /* Command Interrupt */
-#define                nCMD_INT_E  0x0       
 #define                CMD_PEND_E  0x200      /* Command Pending */
-#define               nCMD_PEND_E  0x0       
 #define                     CMD_E  0x400      /* Command Enable */
-#define                    nCMD_E  0x0       
 
 /* Bit masks for SDH_PWR_CTL */
 
 #define                       TBD  0x3c       /* TBD */
 #endif
 #define                 SD_CMD_OD  0x40       /* Open Drain Output */
-#define                nSD_CMD_OD  0x0       
 #define                   ROD_CTL  0x80       /* Rod Control */
-#define                  nROD_CTL  0x0       
 
 /* Bit masks for SDH_CLK_CTL */
 
 #define                    CLKDIV  0xff       /* MC_CLK Divisor */
 #define                     CLK_E  0x100      /* MC_CLK Bus Clock Enable */
-#define                    nCLK_E  0x0       
 #define                  PWR_SV_E  0x200      /* Power Save Enable */
-#define                 nPWR_SV_E  0x0       
 #define             CLKDIV_BYPASS  0x400      /* Bypass Divisor */
-#define            nCLKDIV_BYPASS  0x0       
 #define                  WIDE_BUS  0x800      /* Wide Bus Mode Enable */
-#define                 nWIDE_BUS  0x0       
 
 /* Bit masks for SDH_RESP_CMD */
 
 /* Bit masks for SDH_DATA_CTL */
 
 #define                     DTX_E  0x1        /* Data Transfer Enable */
-#define                    nDTX_E  0x0       
 #define                   DTX_DIR  0x2        /* Data Transfer Direction */
-#define                  nDTX_DIR  0x0       
 #define                  DTX_MODE  0x4        /* Data Transfer Mode */
-#define                 nDTX_MODE  0x0       
 #define                 DTX_DMA_E  0x8        /* Data Transfer DMA Enable */
-#define                nDTX_DMA_E  0x0       
 #define              DTX_BLK_LGTH  0xf0       /* Data Transfer Block Length */
 
 /* Bit masks for SDH_STATUS */
 
 #define              CMD_CRC_FAIL  0x1        /* CMD CRC Fail */
-#define             nCMD_CRC_FAIL  0x0       
 #define              DAT_CRC_FAIL  0x2        /* Data CRC Fail */
-#define             nDAT_CRC_FAIL  0x0       
-#define               CMD_TIMEOUT  0x4        /* CMD Time Out */
-#define              nCMD_TIMEOUT  0x0       
-#define               DAT_TIMEOUT  0x8        /* Data Time Out */
-#define              nDAT_TIMEOUT  0x0       
+#define               CMD_TIME_OUT  0x4        /* CMD Time Out */
+#define               DAT_TIME_OUT  0x8        /* Data Time Out */
 #define               TX_UNDERRUN  0x10       /* Transmit Underrun */
-#define              nTX_UNDERRUN  0x0       
 #define                RX_OVERRUN  0x20       /* Receive Overrun */
-#define               nRX_OVERRUN  0x0       
 #define              CMD_RESP_END  0x40       /* CMD Response End */
-#define             nCMD_RESP_END  0x0       
 #define                  CMD_SENT  0x80       /* CMD Sent */
-#define                 nCMD_SENT  0x0       
 #define                   DAT_END  0x100      /* Data End */
-#define                  nDAT_END  0x0       
 #define             START_BIT_ERR  0x200      /* Start Bit Error */
-#define            nSTART_BIT_ERR  0x0       
 #define               DAT_BLK_END  0x400      /* Data Block End */
-#define              nDAT_BLK_END  0x0       
 #define                   CMD_ACT  0x800      /* CMD Active */
-#define                  nCMD_ACT  0x0       
 #define                    TX_ACT  0x1000     /* Transmit Active */
-#define                   nTX_ACT  0x0       
 #define                    RX_ACT  0x2000     /* Receive Active */
-#define                   nRX_ACT  0x0       
 #define              TX_FIFO_STAT  0x4000     /* Transmit FIFO Status */
-#define             nTX_FIFO_STAT  0x0       
 #define              RX_FIFO_STAT  0x8000     /* Receive FIFO Status */
-#define             nRX_FIFO_STAT  0x0       
 #define              TX_FIFO_FULL  0x10000    /* Transmit FIFO Full */
-#define             nTX_FIFO_FULL  0x0       
 #define              RX_FIFO_FULL  0x20000    /* Receive FIFO Full */
-#define             nRX_FIFO_FULL  0x0       
 #define              TX_FIFO_ZERO  0x40000    /* Transmit FIFO Empty */
-#define             nTX_FIFO_ZERO  0x0       
 #define               RX_DAT_ZERO  0x80000    /* Receive FIFO Empty */
-#define              nRX_DAT_ZERO  0x0       
 #define                TX_DAT_RDY  0x100000   /* Transmit Data Available */
-#define               nTX_DAT_RDY  0x0       
 #define               RX_FIFO_RDY  0x200000   /* Receive Data Available */
-#define              nRX_FIFO_RDY  0x0       
 
 /* Bit masks for SDH_STATUS_CLR */
 
 #define         CMD_CRC_FAIL_STAT  0x1        /* CMD CRC Fail Status */
-#define        nCMD_CRC_FAIL_STAT  0x0       
 #define         DAT_CRC_FAIL_STAT  0x2        /* Data CRC Fail Status */
-#define        nDAT_CRC_FAIL_STAT  0x0       
 #define          CMD_TIMEOUT_STAT  0x4        /* CMD Time Out Status */
-#define         nCMD_TIMEOUT_STAT  0x0       
 #define          DAT_TIMEOUT_STAT  0x8        /* Data Time Out status */
-#define         nDAT_TIMEOUT_STAT  0x0       
 #define          TX_UNDERRUN_STAT  0x10       /* Transmit Underrun Status */
-#define         nTX_UNDERRUN_STAT  0x0       
 #define           RX_OVERRUN_STAT  0x20       /* Receive Overrun Status */
-#define          nRX_OVERRUN_STAT  0x0       
 #define         CMD_RESP_END_STAT  0x40       /* CMD Response End Status */
-#define        nCMD_RESP_END_STAT  0x0       
 #define             CMD_SENT_STAT  0x80       /* CMD Sent Status */
-#define            nCMD_SENT_STAT  0x0       
 #define              DAT_END_STAT  0x100      /* Data End Status */
-#define             nDAT_END_STAT  0x0       
 #define        START_BIT_ERR_STAT  0x200      /* Start Bit Error Status */
-#define       nSTART_BIT_ERR_STAT  0x0       
 #define          DAT_BLK_END_STAT  0x400      /* Data Block End Status */
-#define         nDAT_BLK_END_STAT  0x0       
 
 /* Bit masks for SDH_MASK0 */
 
 #define         CMD_CRC_FAIL_MASK  0x1        /* CMD CRC Fail Mask */
-#define        nCMD_CRC_FAIL_MASK  0x0       
 #define         DAT_CRC_FAIL_MASK  0x2        /* Data CRC Fail Mask */
-#define        nDAT_CRC_FAIL_MASK  0x0       
 #define          CMD_TIMEOUT_MASK  0x4        /* CMD Time Out Mask */
-#define         nCMD_TIMEOUT_MASK  0x0       
 #define          DAT_TIMEOUT_MASK  0x8        /* Data Time Out Mask */
-#define         nDAT_TIMEOUT_MASK  0x0       
 #define          TX_UNDERRUN_MASK  0x10       /* Transmit Underrun Mask */
-#define         nTX_UNDERRUN_MASK  0x0       
 #define           RX_OVERRUN_MASK  0x20       /* Receive Overrun Mask */
-#define          nRX_OVERRUN_MASK  0x0       
 #define         CMD_RESP_END_MASK  0x40       /* CMD Response End Mask */
-#define        nCMD_RESP_END_MASK  0x0       
 #define             CMD_SENT_MASK  0x80       /* CMD Sent Mask */
-#define            nCMD_SENT_MASK  0x0       
 #define              DAT_END_MASK  0x100      /* Data End Mask */
-#define             nDAT_END_MASK  0x0       
 #define        START_BIT_ERR_MASK  0x200      /* Start Bit Error Mask */
-#define       nSTART_BIT_ERR_MASK  0x0       
 #define          DAT_BLK_END_MASK  0x400      /* Data Block End Mask */
-#define         nDAT_BLK_END_MASK  0x0       
 #define              CMD_ACT_MASK  0x800      /* CMD Active Mask */
-#define             nCMD_ACT_MASK  0x0       
 #define               TX_ACT_MASK  0x1000     /* Transmit Active Mask */
-#define              nTX_ACT_MASK  0x0       
 #define               RX_ACT_MASK  0x2000     /* Receive Active Mask */
-#define              nRX_ACT_MASK  0x0       
 #define         TX_FIFO_STAT_MASK  0x4000     /* Transmit FIFO Status Mask */
-#define        nTX_FIFO_STAT_MASK  0x0       
 #define         RX_FIFO_STAT_MASK  0x8000     /* Receive FIFO Status Mask */
-#define        nRX_FIFO_STAT_MASK  0x0       
 #define         TX_FIFO_FULL_MASK  0x10000    /* Transmit FIFO Full Mask */
-#define        nTX_FIFO_FULL_MASK  0x0       
 #define         RX_FIFO_FULL_MASK  0x20000    /* Receive FIFO Full Mask */
-#define        nRX_FIFO_FULL_MASK  0x0       
 #define         TX_FIFO_ZERO_MASK  0x40000    /* Transmit FIFO Empty Mask */
-#define        nTX_FIFO_ZERO_MASK  0x0       
 #define          RX_DAT_ZERO_MASK  0x80000    /* Receive FIFO Empty Mask */
-#define         nRX_DAT_ZERO_MASK  0x0       
 #define           TX_DAT_RDY_MASK  0x100000   /* Transmit Data Available Mask */
-#define          nTX_DAT_RDY_MASK  0x0       
 #define          RX_FIFO_RDY_MASK  0x200000   /* Receive Data Available Mask */
-#define         nRX_FIFO_RDY_MASK  0x0       
 
 /* Bit masks for SDH_FIFO_CNT */
 
 /* Bit masks for SDH_E_STATUS */
 
 #define              SDIO_INT_DET  0x2        /* SDIO Int Detected */
-#define             nSDIO_INT_DET  0x0       
 #define               SD_CARD_DET  0x10       /* SD Card Detect */
-#define              nSD_CARD_DET  0x0       
 
 /* Bit masks for SDH_E_MASK */
 
 #define                  SDIO_MSK  0x2        /* Mask SDIO Int Detected */
-#define                 nSDIO_MSK  0x0       
 #define                   SCD_MSK  0x40       /* Mask Card Detect */
-#define                  nSCD_MSK  0x0       
 
 /* Bit masks for SDH_CFG */
 
 #define                   CLKS_EN  0x1        /* Clocks Enable */
-#define                  nCLKS_EN  0x0       
 #define                      SD4E  0x4        /* SDIO 4-Bit Enable */
-#define                     nSD4E  0x0       
 #define                       MWE  0x8        /* Moving Window Enable */
-#define                      nMWE  0x0       
 #define                    SD_RST  0x10       /* SDMMC Reset */
-#define                   nSD_RST  0x0       
 #define                 PUP_SDDAT  0x20       /* Pull-up SD_DAT */
-#define                nPUP_SDDAT  0x0       
 #define                PUP_SDDAT3  0x40       /* Pull-up SD_DAT3 */
-#define               nPUP_SDDAT3  0x0       
 #define                 PD_SDDAT3  0x80       /* Pull-down SD_DAT3 */
-#define                nPD_SDDAT3  0x0       
 
 /* Bit masks for SDH_RD_WAIT_EN */
 
 #define                       RWR  0x1        /* Read Wait Request */
-#define                      nRWR  0x0       
 
 /* Bit masks for ATAPI_CONTROL */
 
 #define                 PIO_START  0x1        /* Start PIO/Reg Op */
-#define                nPIO_START  0x0       
 #define               MULTI_START  0x2        /* Start Multi-DMA Op */
-#define              nMULTI_START  0x0       
 #define               ULTRA_START  0x4        /* Start Ultra-DMA Op */
-#define              nULTRA_START  0x0       
 #define                  XFER_DIR  0x8        /* Transfer Direction */
-#define                 nXFER_DIR  0x0       
 #define                  IORDY_EN  0x10       /* IORDY Enable */
-#define                 nIORDY_EN  0x0       
 #define                FIFO_FLUSH  0x20       /* Flush FIFOs */
-#define               nFIFO_FLUSH  0x0       
 #define                  SOFT_RST  0x40       /* Soft Reset */
-#define                 nSOFT_RST  0x0       
 #define                   DEV_RST  0x80       /* Device Reset */
-#define                  nDEV_RST  0x0       
 #define                TFRCNT_RST  0x100      /* Trans Count Reset */
-#define               nTFRCNT_RST  0x0       
 #define               END_ON_TERM  0x200      /* End/Terminate Select */
-#define              nEND_ON_TERM  0x0       
 #define               PIO_USE_DMA  0x400      /* PIO-DMA Enable */
-#define              nPIO_USE_DMA  0x0       
 #define          UDMAIN_FIFO_THRS  0xf000     /* Ultra DMA-IN FIFO Threshold */
 
 /* Bit masks for ATAPI_STATUS */
 
 #define               PIO_XFER_ON  0x1        /* PIO transfer in progress */
-#define              nPIO_XFER_ON  0x0       
 #define             MULTI_XFER_ON  0x2        /* Multi-word DMA transfer in progress */
-#define            nMULTI_XFER_ON  0x0       
 #define             ULTRA_XFER_ON  0x4        /* Ultra DMA transfer in progress */
-#define            nULTRA_XFER_ON  0x0       
 #define               ULTRA_IN_FL  0xf0       /* Ultra DMA Input FIFO Level */
 
 /* Bit masks for ATAPI_DEV_ADDR */
 /* Bit masks for ATAPI_INT_MASK */
 
 #define        ATAPI_DEV_INT_MASK  0x1        /* Device interrupt mask */
-#define       nATAPI_DEV_INT_MASK  0x0       
 #define             PIO_DONE_MASK  0x2        /* PIO transfer done interrupt mask */
-#define            nPIO_DONE_MASK  0x0       
 #define           MULTI_DONE_MASK  0x4        /* Multi-DMA transfer done interrupt mask */
-#define          nMULTI_DONE_MASK  0x0       
 #define          UDMAIN_DONE_MASK  0x8        /* Ultra-DMA in transfer done interrupt mask */
-#define         nUDMAIN_DONE_MASK  0x0       
 #define         UDMAOUT_DONE_MASK  0x10       /* Ultra-DMA out transfer done interrupt mask */
-#define        nUDMAOUT_DONE_MASK  0x0       
 #define       HOST_TERM_XFER_MASK  0x20       /* Host terminate current transfer interrupt mask */
-#define      nHOST_TERM_XFER_MASK  0x0       
 #define           MULTI_TERM_MASK  0x40       /* Device terminate Multi-DMA transfer interrupt mask */
-#define          nMULTI_TERM_MASK  0x0       
 #define          UDMAIN_TERM_MASK  0x80       /* Device terminate Ultra-DMA-in transfer interrupt mask */
-#define         nUDMAIN_TERM_MASK  0x0       
 #define         UDMAOUT_TERM_MASK  0x100      /* Device terminate Ultra-DMA-out transfer interrupt mask */
-#define        nUDMAOUT_TERM_MASK  0x0       
 
 /* Bit masks for ATAPI_INT_STATUS */
 
 #define             ATAPI_DEV_INT  0x1        /* Device interrupt status */
-#define            nATAPI_DEV_INT  0x0       
 #define              PIO_DONE_INT  0x2        /* PIO transfer done interrupt status */
-#define             nPIO_DONE_INT  0x0       
 #define            MULTI_DONE_INT  0x4        /* Multi-DMA transfer done interrupt status */
-#define           nMULTI_DONE_INT  0x0       
 #define           UDMAIN_DONE_INT  0x8        /* Ultra-DMA in transfer done interrupt status */
-#define          nUDMAIN_DONE_INT  0x0       
 #define          UDMAOUT_DONE_INT  0x10       /* Ultra-DMA out transfer done interrupt status */
-#define         nUDMAOUT_DONE_INT  0x0       
 #define        HOST_TERM_XFER_INT  0x20       /* Host terminate current transfer interrupt status */
-#define       nHOST_TERM_XFER_INT  0x0       
 #define            MULTI_TERM_INT  0x40       /* Device terminate Multi-DMA transfer interrupt status */
-#define           nMULTI_TERM_INT  0x0       
 #define           UDMAIN_TERM_INT  0x80       /* Device terminate Ultra-DMA-in transfer interrupt status */
-#define          nUDMAIN_TERM_INT  0x0       
 #define          UDMAOUT_TERM_INT  0x100      /* Device terminate Ultra-DMA-out transfer interrupt status */
-#define         nUDMAOUT_TERM_INT  0x0       
 
 /* Bit masks for ATAPI_LINE_STATUS */
 
 #define                ATAPI_INTR  0x1        /* Device interrupt to host line status */
-#define               nATAPI_INTR  0x0       
 #define                ATAPI_DASP  0x2        /* Device dasp to host line status */
-#define               nATAPI_DASP  0x0       
 #define                ATAPI_CS0N  0x4        /* ATAPI chip select 0 line status */
-#define               nATAPI_CS0N  0x0       
 #define                ATAPI_CS1N  0x8        /* ATAPI chip select 1 line status */
-#define               nATAPI_CS1N  0x0       
 #define                ATAPI_ADDR  0x70       /* ATAPI address line status */
 #define              ATAPI_DMAREQ  0x80       /* ATAPI DMA request line status */
-#define             nATAPI_DMAREQ  0x0       
 #define             ATAPI_DMAACKN  0x100      /* ATAPI DMA acknowledge line status */
-#define            nATAPI_DMAACKN  0x0       
 #define               ATAPI_DIOWN  0x200      /* ATAPI write line status */
-#define              nATAPI_DIOWN  0x0       
 #define               ATAPI_DIORN  0x400      /* ATAPI read line status */
-#define              nATAPI_DIORN  0x0       
 #define               ATAPI_IORDY  0x800      /* ATAPI IORDY line status */
-#define              nATAPI_IORDY  0x0       
 
 /* Bit masks for ATAPI_SM_STATE */
 
 /* Bit masks for ATAPI_TERMINATE */
 
 #define           ATAPI_HOST_TERM  0x1        /* Host terminationation */
-#define          nATAPI_HOST_TERM  0x0       
 
 /* Bit masks for ATAPI_REG_TIM_0 */
 
 /* Bit masks for TIMER_ENABLE1 */
 
 #define                    TIMEN8  0x1        /* Timer 8 Enable */
-#define                   nTIMEN8  0x0       
 #define                    TIMEN9  0x2        /* Timer 9 Enable */
-#define                   nTIMEN9  0x0       
 #define                   TIMEN10  0x4        /* Timer 10 Enable */
-#define                  nTIMEN10  0x0       
 
 /* Bit masks for TIMER_DISABLE1 */
 
 #define                   TIMDIS8  0x1        /* Timer 8 Disable */
-#define                  nTIMDIS8  0x0       
 #define                   TIMDIS9  0x2        /* Timer 9 Disable */
-#define                  nTIMDIS9  0x0       
 #define                  TIMDIS10  0x4        /* Timer 10 Disable */
-#define                 nTIMDIS10  0x0       
 
 /* Bit masks for TIMER_STATUS1 */
 
 #define                    TIMIL8  0x1        /* Timer 8 Interrupt */
-#define                   nTIMIL8  0x0       
 #define                    TIMIL9  0x2        /* Timer 9 Interrupt */
-#define                   nTIMIL9  0x0       
 #define                   TIMIL10  0x4        /* Timer 10 Interrupt */
-#define                  nTIMIL10  0x0       
 #define                 TOVF_ERR8  0x10       /* Timer 8 Counter Overflow */
-#define                nTOVF_ERR8  0x0       
 #define                 TOVF_ERR9  0x20       /* Timer 9 Counter Overflow */
-#define                nTOVF_ERR9  0x0       
 #define                TOVF_ERR10  0x40       /* Timer 10 Counter Overflow */
-#define               nTOVF_ERR10  0x0       
 #define                     TRUN8  0x1000     /* Timer 8 Slave Enable Status */
-#define                    nTRUN8  0x0       
 #define                     TRUN9  0x2000     /* Timer 9 Slave Enable Status */
-#define                    nTRUN9  0x0       
 #define                    TRUN10  0x4000     /* Timer 10 Slave Enable Status */
-#define                   nTRUN10  0x0       
 
 /* Bit masks for EPPI0 are obtained from common base header for EPPIx (EPPI1 and EPPI2) */
 
 /* Bit masks for USB_POWER */
 
 #define           ENABLE_SUSPENDM  0x1        /* enable SuspendM output */
-#define          nENABLE_SUSPENDM  0x0       
 #define              SUSPEND_MODE  0x2        /* Suspend Mode indicator */
-#define             nSUSPEND_MODE  0x0       
 #define               RESUME_MODE  0x4        /* DMA Mode */
-#define              nRESUME_MODE  0x0       
 #define                     RESET  0x8        /* Reset indicator */
-#define                    nRESET  0x0       
 #define                   HS_MODE  0x10       /* High Speed mode indicator */
-#define                  nHS_MODE  0x0       
 #define                 HS_ENABLE  0x20       /* high Speed Enable */
-#define                nHS_ENABLE  0x0       
 #define                 SOFT_CONN  0x40       /* Soft connect */
-#define                nSOFT_CONN  0x0       
 #define                ISO_UPDATE  0x80       /* Isochronous update */
-#define               nISO_UPDATE  0x0       
 
 /* Bit masks for USB_INTRTX */
 
 #define                    EP0_TX  0x1        /* Tx Endpoint 0 interrupt */
-#define                   nEP0_TX  0x0       
 #define                    EP1_TX  0x2        /* Tx Endpoint 1 interrupt */
-#define                   nEP1_TX  0x0       
 #define                    EP2_TX  0x4        /* Tx Endpoint 2 interrupt */
-#define                   nEP2_TX  0x0       
 #define                    EP3_TX  0x8        /* Tx Endpoint 3 interrupt */
-#define                   nEP3_TX  0x0       
 #define                    EP4_TX  0x10       /* Tx Endpoint 4 interrupt */
-#define                   nEP4_TX  0x0       
 #define                    EP5_TX  0x20       /* Tx Endpoint 5 interrupt */
-#define                   nEP5_TX  0x0       
 #define                    EP6_TX  0x40       /* Tx Endpoint 6 interrupt */
-#define                   nEP6_TX  0x0       
 #define                    EP7_TX  0x80       /* Tx Endpoint 7 interrupt */
-#define                   nEP7_TX  0x0       
 
 /* Bit masks for USB_INTRRX */
 
 #define                    EP1_RX  0x2        /* Rx Endpoint 1 interrupt */
-#define                   nEP1_RX  0x0       
 #define                    EP2_RX  0x4        /* Rx Endpoint 2 interrupt */
-#define                   nEP2_RX  0x0       
 #define                    EP3_RX  0x8        /* Rx Endpoint 3 interrupt */
-#define                   nEP3_RX  0x0       
 #define                    EP4_RX  0x10       /* Rx Endpoint 4 interrupt */
-#define                   nEP4_RX  0x0       
 #define                    EP5_RX  0x20       /* Rx Endpoint 5 interrupt */
-#define                   nEP5_RX  0x0       
 #define                    EP6_RX  0x40       /* Rx Endpoint 6 interrupt */
-#define                   nEP6_RX  0x0       
 #define                    EP7_RX  0x80       /* Rx Endpoint 7 interrupt */
-#define                   nEP7_RX  0x0       
 
 /* Bit masks for USB_INTRTXE */
 
 #define                  EP0_TX_E  0x1        /* Endpoint 0 interrupt Enable */
-#define                 nEP0_TX_E  0x0       
 #define                  EP1_TX_E  0x2        /* Tx Endpoint 1 interrupt  Enable */
-#define                 nEP1_TX_E  0x0       
 #define                  EP2_TX_E  0x4        /* Tx Endpoint 2 interrupt  Enable */
-#define                 nEP2_TX_E  0x0       
 #define                  EP3_TX_E  0x8        /* Tx Endpoint 3 interrupt  Enable */
-#define                 nEP3_TX_E  0x0       
 #define                  EP4_TX_E  0x10       /* Tx Endpoint 4 interrupt  Enable */
-#define                 nEP4_TX_E  0x0       
 #define                  EP5_TX_E  0x20       /* Tx Endpoint 5 interrupt  Enable */
-#define                 nEP5_TX_E  0x0       
 #define                  EP6_TX_E  0x40       /* Tx Endpoint 6 interrupt  Enable */
-#define                 nEP6_TX_E  0x0       
 #define                  EP7_TX_E  0x80       /* Tx Endpoint 7 interrupt  Enable */
-#define                 nEP7_TX_E  0x0       
 
 /* Bit masks for USB_INTRRXE */
 
 #define                  EP1_RX_E  0x2        /* Rx Endpoint 1 interrupt  Enable */
-#define                 nEP1_RX_E  0x0       
 #define                  EP2_RX_E  0x4        /* Rx Endpoint 2 interrupt  Enable */
-#define                 nEP2_RX_E  0x0       
 #define                  EP3_RX_E  0x8        /* Rx Endpoint 3 interrupt  Enable */
-#define                 nEP3_RX_E  0x0       
 #define                  EP4_RX_E  0x10       /* Rx Endpoint 4 interrupt  Enable */
-#define                 nEP4_RX_E  0x0       
 #define                  EP5_RX_E  0x20       /* Rx Endpoint 5 interrupt  Enable */
-#define                 nEP5_RX_E  0x0       
 #define                  EP6_RX_E  0x40       /* Rx Endpoint 6 interrupt  Enable */
-#define                 nEP6_RX_E  0x0       
 #define                  EP7_RX_E  0x80       /* Rx Endpoint 7 interrupt  Enable */
-#define                 nEP7_RX_E  0x0       
 
 /* Bit masks for USB_INTRUSB */
 
 #define                 SUSPEND_B  0x1        /* Suspend indicator */
-#define                nSUSPEND_B  0x0       
 #define                  RESUME_B  0x2        /* Resume indicator */
-#define                 nRESUME_B  0x0       
 #define          RESET_OR_BABLE_B  0x4        /* Reset/babble indicator */
-#define         nRESET_OR_BABLE_B  0x0       
 #define                     SOF_B  0x8        /* Start of frame */
-#define                    nSOF_B  0x0       
 #define                    CONN_B  0x10       /* Connection indicator */
-#define                   nCONN_B  0x0       
 #define                  DISCON_B  0x20       /* Disconnect indicator */
-#define                 nDISCON_B  0x0       
 #define             SESSION_REQ_B  0x40       /* Session Request */
-#define            nSESSION_REQ_B  0x0       
 #define              VBUS_ERROR_B  0x80       /* Vbus threshold indicator */
-#define             nVBUS_ERROR_B  0x0       
 
 /* Bit masks for USB_INTRUSBE */
 
 #define                SUSPEND_BE  0x1        /* Suspend indicator int enable */
-#define               nSUSPEND_BE  0x0       
 #define                 RESUME_BE  0x2        /* Resume indicator int enable */
-#define                nRESUME_BE  0x0       
 #define         RESET_OR_BABLE_BE  0x4        /* Reset/babble indicator int enable */
-#define        nRESET_OR_BABLE_BE  0x0       
 #define                    SOF_BE  0x8        /* Start of frame int enable */
-#define                   nSOF_BE  0x0       
 #define                   CONN_BE  0x10       /* Connection indicator int enable */
-#define                  nCONN_BE  0x0       
 #define                 DISCON_BE  0x20       /* Disconnect indicator int enable */
-#define                nDISCON_BE  0x0       
 #define            SESSION_REQ_BE  0x40       /* Session Request int enable */
-#define           nSESSION_REQ_BE  0x0       
 #define             VBUS_ERROR_BE  0x80       /* Vbus threshold indicator int enable */
-#define            nVBUS_ERROR_BE  0x0       
 
 /* Bit masks for USB_FRAME */
 
 /* Bit masks for USB_GLOBAL_CTL */
 
 #define                GLOBAL_ENA  0x1        /* enables USB module */
-#define               nGLOBAL_ENA  0x0       
 #define                EP1_TX_ENA  0x2        /* Transmit endpoint 1 enable */
-#define               nEP1_TX_ENA  0x0       
 #define                EP2_TX_ENA  0x4        /* Transmit endpoint 2 enable */
-#define               nEP2_TX_ENA  0x0       
 #define                EP3_TX_ENA  0x8        /* Transmit endpoint 3 enable */
-#define               nEP3_TX_ENA  0x0       
 #define                EP4_TX_ENA  0x10       /* Transmit endpoint 4 enable */
-#define               nEP4_TX_ENA  0x0       
 #define                EP5_TX_ENA  0x20       /* Transmit endpoint 5 enable */
-#define               nEP5_TX_ENA  0x0       
 #define                EP6_TX_ENA  0x40       /* Transmit endpoint 6 enable */
-#define               nEP6_TX_ENA  0x0       
 #define                EP7_TX_ENA  0x80       /* Transmit endpoint 7 enable */
-#define               nEP7_TX_ENA  0x0       
 #define                EP1_RX_ENA  0x100      /* Receive endpoint 1 enable */
-#define               nEP1_RX_ENA  0x0       
 #define                EP2_RX_ENA  0x200      /* Receive endpoint 2 enable */
-#define               nEP2_RX_ENA  0x0       
 #define                EP3_RX_ENA  0x400      /* Receive endpoint 3 enable */
-#define               nEP3_RX_ENA  0x0       
 #define                EP4_RX_ENA  0x800      /* Receive endpoint 4 enable */
-#define               nEP4_RX_ENA  0x0       
 #define                EP5_RX_ENA  0x1000     /* Receive endpoint 5 enable */
-#define               nEP5_RX_ENA  0x0       
 #define                EP6_RX_ENA  0x2000     /* Receive endpoint 6 enable */
-#define               nEP6_RX_ENA  0x0       
 #define                EP7_RX_ENA  0x4000     /* Receive endpoint 7 enable */
-#define               nEP7_RX_ENA  0x0       
 
 /* Bit masks for USB_OTG_DEV_CTL */
 
 #define                   SESSION  0x1        /* session indicator */
-#define                  nSESSION  0x0       
 #define                  HOST_REQ  0x2        /* Host negotiation request */
-#define                 nHOST_REQ  0x0       
 #define                 HOST_MODE  0x4        /* indicates USBDRC is a host */
-#define                nHOST_MODE  0x0       
 #define                     VBUS0  0x8        /* Vbus level indicator[0] */
-#define                    nVBUS0  0x0       
 #define                     VBUS1  0x10       /* Vbus level indicator[1] */
-#define                    nVBUS1  0x0       
 #define                     LSDEV  0x20       /* Low-speed indicator */
-#define                    nLSDEV  0x0       
 #define                     FSDEV  0x40       /* Full or High-speed indicator */
-#define                    nFSDEV  0x0       
 #define                  B_DEVICE  0x80       /* A' or 'B' device indicator */
-#define                 nB_DEVICE  0x0       
 
 /* Bit masks for USB_OTG_VBUS_IRQ */
 
 #define             DRIVE_VBUS_ON  0x1        /* indicator to drive VBUS control circuit */
-#define            nDRIVE_VBUS_ON  0x0       
 #define            DRIVE_VBUS_OFF  0x2        /* indicator to shut off charge pump */
-#define           nDRIVE_VBUS_OFF  0x0       
 #define           CHRG_VBUS_START  0x4        /* indicator for external circuit to start charging VBUS */
-#define          nCHRG_VBUS_START  0x0       
 #define             CHRG_VBUS_END  0x8        /* indicator for external circuit to end charging VBUS */
-#define            nCHRG_VBUS_END  0x0       
 #define        DISCHRG_VBUS_START  0x10       /* indicator to start discharging VBUS */
-#define       nDISCHRG_VBUS_START  0x0       
 #define          DISCHRG_VBUS_END  0x20       /* indicator to stop discharging VBUS */
-#define         nDISCHRG_VBUS_END  0x0       
 
 /* Bit masks for USB_OTG_VBUS_MASK */
 
 #define         DRIVE_VBUS_ON_ENA  0x1        /* enable DRIVE_VBUS_ON interrupt */
-#define        nDRIVE_VBUS_ON_ENA  0x0       
 #define        DRIVE_VBUS_OFF_ENA  0x2        /* enable DRIVE_VBUS_OFF interrupt */
-#define       nDRIVE_VBUS_OFF_ENA  0x0       
 #define       CHRG_VBUS_START_ENA  0x4        /* enable CHRG_VBUS_START interrupt */
-#define      nCHRG_VBUS_START_ENA  0x0       
 #define         CHRG_VBUS_END_ENA  0x8        /* enable CHRG_VBUS_END interrupt */
-#define        nCHRG_VBUS_END_ENA  0x0       
 #define    DISCHRG_VBUS_START_ENA  0x10       /* enable DISCHRG_VBUS_START interrupt */
-#define   nDISCHRG_VBUS_START_ENA  0x0       
 #define      DISCHRG_VBUS_END_ENA  0x20       /* enable DISCHRG_VBUS_END interrupt */
-#define     nDISCHRG_VBUS_END_ENA  0x0       
 
 /* Bit masks for USB_CSR0 */
 
 #define                  RXPKTRDY  0x1        /* data packet receive indicator */
-#define                 nRXPKTRDY  0x0       
 #define                  TXPKTRDY  0x2        /* data packet in FIFO indicator */
-#define                 nTXPKTRDY  0x0       
 #define                STALL_SENT  0x4        /* STALL handshake sent */
-#define               nSTALL_SENT  0x0       
 #define                   DATAEND  0x8        /* Data end indicator */
-#define                  nDATAEND  0x0       
 #define                  SETUPEND  0x10       /* Setup end */
-#define                 nSETUPEND  0x0       
 #define                 SENDSTALL  0x20       /* Send STALL handshake */
-#define                nSENDSTALL  0x0       
 #define         SERVICED_RXPKTRDY  0x40       /* used to clear the RxPktRdy bit */
-#define        nSERVICED_RXPKTRDY  0x0       
 #define         SERVICED_SETUPEND  0x80       /* used to clear the SetupEnd bit */
-#define        nSERVICED_SETUPEND  0x0       
 #define                 FLUSHFIFO  0x100      /* flush endpoint FIFO */
-#define                nFLUSHFIFO  0x0       
 #define          STALL_RECEIVED_H  0x4        /* STALL handshake received host mode */
-#define         nSTALL_RECEIVED_H  0x0       
 #define                SETUPPKT_H  0x8        /* send Setup token host mode */
-#define               nSETUPPKT_H  0x0       
 #define                   ERROR_H  0x10       /* timeout error indicator host mode */
-#define                  nERROR_H  0x0       
 #define                  REQPKT_H  0x20       /* Request an IN transaction host mode */
-#define                 nREQPKT_H  0x0       
 #define               STATUSPKT_H  0x40       /* Status stage transaction host mode */
-#define              nSTATUSPKT_H  0x0       
 #define             NAK_TIMEOUT_H  0x80       /* EP0 halted after a NAK host mode */
-#define            nNAK_TIMEOUT_H  0x0       
 
 /* Bit masks for USB_COUNT0 */
 
 /* Bit masks for USB_TXCSR */
 
 #define                TXPKTRDY_T  0x1        /* data packet in FIFO indicator */
-#define               nTXPKTRDY_T  0x0       
 #define          FIFO_NOT_EMPTY_T  0x2        /* FIFO not empty */
-#define         nFIFO_NOT_EMPTY_T  0x0       
 #define                UNDERRUN_T  0x4        /* TxPktRdy not set  for an IN token */
-#define               nUNDERRUN_T  0x0       
 #define               FLUSHFIFO_T  0x8        /* flush endpoint FIFO */
-#define              nFLUSHFIFO_T  0x0       
 #define              STALL_SEND_T  0x10       /* issue a Stall handshake */
-#define             nSTALL_SEND_T  0x0       
 #define              STALL_SENT_T  0x20       /* Stall handshake transmitted */
-#define             nSTALL_SENT_T  0x0       
 #define        CLEAR_DATATOGGLE_T  0x40       /* clear endpoint data toggle */
-#define       nCLEAR_DATATOGGLE_T  0x0       
 #define                INCOMPTX_T  0x80       /* indicates that a large packet is split */
-#define               nINCOMPTX_T  0x0       
 #define              DMAREQMODE_T  0x400      /* DMA mode (0 or 1) selection */
-#define             nDMAREQMODE_T  0x0       
 #define        FORCE_DATATOGGLE_T  0x800      /* Force data toggle */
-#define       nFORCE_DATATOGGLE_T  0x0       
 #define              DMAREQ_ENA_T  0x1000     /* Enable DMA request for Tx EP */
-#define             nDMAREQ_ENA_T  0x0       
 #define                     ISO_T  0x4000     /* enable Isochronous transfers */
-#define                    nISO_T  0x0       
 #define                 AUTOSET_T  0x8000     /* allows TxPktRdy to be set automatically */
-#define                nAUTOSET_T  0x0       
 #define                  ERROR_TH  0x4        /* error condition host mode */
-#define                 nERROR_TH  0x0       
 #define         STALL_RECEIVED_TH  0x20       /* Stall handshake received host mode */
-#define        nSTALL_RECEIVED_TH  0x0       
 #define            NAK_TIMEOUT_TH  0x80       /* NAK timeout host mode */
-#define           nNAK_TIMEOUT_TH  0x0       
 
 /* Bit masks for USB_TXCOUNT */
 
 /* Bit masks for USB_RXCSR */
 
 #define                RXPKTRDY_R  0x1        /* data packet in FIFO indicator */
-#define               nRXPKTRDY_R  0x0       
 #define               FIFO_FULL_R  0x2        /* FIFO not empty */
-#define              nFIFO_FULL_R  0x0       
 #define                 OVERRUN_R  0x4        /* TxPktRdy not set  for an IN token */
-#define                nOVERRUN_R  0x0       
 #define               DATAERROR_R  0x8        /* Out packet cannot be loaded into Rx  FIFO */
-#define              nDATAERROR_R  0x0       
 #define               FLUSHFIFO_R  0x10       /* flush endpoint FIFO */
-#define              nFLUSHFIFO_R  0x0       
 #define              STALL_SEND_R  0x20       /* issue a Stall handshake */
-#define             nSTALL_SEND_R  0x0       
 #define              STALL_SENT_R  0x40       /* Stall handshake transmitted */
-#define             nSTALL_SENT_R  0x0       
 #define        CLEAR_DATATOGGLE_R  0x80       /* clear endpoint data toggle */
-#define       nCLEAR_DATATOGGLE_R  0x0       
 #define                INCOMPRX_R  0x100      /* indicates that a large packet is split */
-#define               nINCOMPRX_R  0x0       
 #define              DMAREQMODE_R  0x800      /* DMA mode (0 or 1) selection */
-#define             nDMAREQMODE_R  0x0       
 #define                 DISNYET_R  0x1000     /* disable Nyet handshakes */
-#define                nDISNYET_R  0x0       
 #define              DMAREQ_ENA_R  0x2000     /* Enable DMA request for Tx EP */
-#define             nDMAREQ_ENA_R  0x0       
 #define                     ISO_R  0x4000     /* enable Isochronous transfers */
-#define                    nISO_R  0x0       
 #define               AUTOCLEAR_R  0x8000     /* allows TxPktRdy to be set automatically */
-#define              nAUTOCLEAR_R  0x0       
 #define                  ERROR_RH  0x4        /* TxPktRdy not set  for an IN token host mode */
-#define                 nERROR_RH  0x0       
 #define                 REQPKT_RH  0x20       /* request an IN transaction host mode */
-#define                nREQPKT_RH  0x0       
 #define         STALL_RECEIVED_RH  0x40       /* Stall handshake received host mode */
-#define        nSTALL_RECEIVED_RH  0x0       
 #define               INCOMPRX_RH  0x100      /* indicates that a large packet is split host mode */
-#define              nINCOMPRX_RH  0x0       
 #define             DMAREQMODE_RH  0x800      /* DMA mode (0 or 1) selection host mode */
-#define            nDMAREQMODE_RH  0x0       
 #define                AUTOREQ_RH  0x4000     /* sets ReqPkt automatically host mode */
-#define               nAUTOREQ_RH  0x0       
 
 /* Bit masks for USB_RXCOUNT */
 
 /* Bit masks for USB_DMA_INTERRUPT */
 
 #define                  DMA0_INT  0x1        /* DMA0 pending interrupt */
-#define                 nDMA0_INT  0x0       
 #define                  DMA1_INT  0x2        /* DMA1 pending interrupt */
-#define                 nDMA1_INT  0x0       
 #define                  DMA2_INT  0x4        /* DMA2 pending interrupt */
-#define                 nDMA2_INT  0x0       
 #define                  DMA3_INT  0x8        /* DMA3 pending interrupt */
-#define                 nDMA3_INT  0x0       
 #define                  DMA4_INT  0x10       /* DMA4 pending interrupt */
-#define                 nDMA4_INT  0x0       
 #define                  DMA5_INT  0x20       /* DMA5 pending interrupt */
-#define                 nDMA5_INT  0x0       
 #define                  DMA6_INT  0x40       /* DMA6 pending interrupt */
-#define                 nDMA6_INT  0x0       
 #define                  DMA7_INT  0x80       /* DMA7 pending interrupt */
-#define                 nDMA7_INT  0x0       
 
 /* Bit masks for USB_DMAxCONTROL */
 
 #define                   DMA_ENA  0x1        /* DMA enable */
-#define                  nDMA_ENA  0x0       
 #define                 DIRECTION  0x2        /* direction of DMA transfer */
-#define                nDIRECTION  0x0       
 #define                      MODE  0x4        /* DMA Bus error */
-#define                     nMODE  0x0       
 #define                   INT_ENA  0x8        /* Interrupt enable */
-#define                  nINT_ENA  0x0       
 #define                     EPNUM  0xf0       /* EP number */
 #define                  BUSERROR  0x100      /* DMA Bus error */
-#define                 nBUSERROR  0x0       
 
 /* Bit masks for USB_DMAxADDRHIGH */
 
 /* Bit masks for HMDMAx_CONTROL */
 
 #define                   HMDMAEN  0x1        /* Handshake MDMA Enable */
-#define                  nHMDMAEN  0x0       
 #define                       REP  0x2        /* Handshake MDMA Request Polarity */
-#define                      nREP  0x0       
 #define                       UTE  0x8        /* Urgency Threshold Enable */
-#define                      nUTE  0x0       
 #define                       OIE  0x10       /* Overflow Interrupt Enable */
-#define                      nOIE  0x0       
 #define                      BDIE  0x20       /* Block Done Interrupt Enable */
-#define                     nBDIE  0x0       
 #define                      MBDI  0x40       /* Mask Block Done Interrupt */
-#define                     nMBDI  0x0       
 #define                       DRQ  0x300      /* Handshake MDMA Request Type */
 #define                       RBC  0x1000     /* Force Reload of BCOUNT */
-#define                      nRBC  0x0       
 #define                        PS  0x2000     /* Pin Status */
-#define                       nPS  0x0       
 #define                        OI  0x4000     /* Overflow Interrupt Generated */
-#define                       nOI  0x0       
 #define                       BDI  0x8000     /* Block Done Interrupt Generated */
-#define                      nBDI  0x0       
 
 /* ******************************************* */
 /*     MULTI BIT MACRO ENUMERATIONS            */
index a1b200fe6a1f4fe8b455f6fb1ffe798c5cd0399d..895ddd40a838cce33bc295a79e68aea339aa6ab9 100644 (file)
@@ -46,7 +46,7 @@
 
 /* Debug/MP/Emulation Registers (0xFFC00014 - 0xFFC00014) */
 
-#define                           CHIPID  0xffc00014   
+#define                           CHIPID  0xffc00014
 
 /* System Reset and Interrupt Controller (0xFFC00100 - 0xFFC00104) */
 
 /*     and MULTI BIT READ MACROS                              */
 /* ********************************************************** */
 
+/* SIC_IMASK Masks */
+#define SIC_UNMASK_ALL         0x00000000      /* Unmask all peripheral interrupts */
+#define SIC_MASK_ALL           0xFFFFFFFF      /* Mask all peripheral interrupts */
+#define SIC_MASK(x)           (1 << (x))       /* Mask Peripheral #x interrupt */
+#define SIC_UNMASK(x) (0xFFFFFFFF ^ (1 << (x)))        /* Unmask Peripheral #x interrupt */
+
+/* SIC_IWR Masks */
+#define IWR_DISABLE_ALL        0x00000000      /* Wakeup Disable all peripherals */
+#define IWR_ENABLE_ALL         0xFFFFFFFF      /* Wakeup Enable all peripherals */
+#define IWR_ENABLE(x)         (1 << (x))       /* Wakeup Enable Peripheral #x */
+#define IWR_DISABLE(x) (0xFFFFFFFF ^ (1 << (x)))       /* Wakeup Disable Peripheral #x */
+
 /* Bit masks for SIC_IAR0 */
 
-#define            IRQ_PLL_WAKEUP  0x1        /* PLL Wakeup */
-#define           nIRQ_PLL_WAKEUP  0x0       
+#define            PLL_WAKEUP  0x1        /* PLL Wakeup */
 
 /* Bit masks for SIC_IWR0, SIC_IMASK0, SIC_ISR0 */
 
-#define              IRQ_DMA0_ERR  0x2        /* DMA Controller 0 Error */
-#define             nIRQ_DMA0_ERR  0x0       
-#define             IRQ_EPPI0_ERR  0x4        /* EPPI0 Error */
-#define            nIRQ_EPPI0_ERR  0x0       
-#define            IRQ_SPORT0_ERR  0x8        /* SPORT0 Error */
-#define           nIRQ_SPORT0_ERR  0x0       
-#define            IRQ_SPORT1_ERR  0x10       /* SPORT1 Error */
-#define           nIRQ_SPORT1_ERR  0x0       
-#define              IRQ_SPI0_ERR  0x20       /* SPI0 Error */
-#define             nIRQ_SPI0_ERR  0x0       
-#define             IRQ_UART0_ERR  0x40       /* UART0 Error */
-#define            nIRQ_UART0_ERR  0x0       
-#define                   IRQ_RTC  0x80       /* Real-Time Clock */
-#define                  nIRQ_RTC  0x0       
-#define                 IRQ_DMA12  0x100      /* DMA Channel 12 */
-#define                nIRQ_DMA12  0x0       
-#define                  IRQ_DMA0  0x200      /* DMA Channel 0 */
-#define                 nIRQ_DMA0  0x0       
-#define                  IRQ_DMA1  0x400      /* DMA Channel 1 */
-#define                 nIRQ_DMA1  0x0       
-#define                  IRQ_DMA2  0x800      /* DMA Channel 2 */
-#define                 nIRQ_DMA2  0x0       
-#define                  IRQ_DMA3  0x1000     /* DMA Channel 3 */
-#define                 nIRQ_DMA3  0x0       
-#define                  IRQ_DMA4  0x2000     /* DMA Channel 4 */
-#define                 nIRQ_DMA4  0x0       
-#define                  IRQ_DMA6  0x4000     /* DMA Channel 6 */
-#define                 nIRQ_DMA6  0x0       
-#define                  IRQ_DMA7  0x8000     /* DMA Channel 7 */
-#define                 nIRQ_DMA7  0x0       
-#define                 IRQ_PINT0  0x80000    /* Pin Interrupt 0 */
-#define                nIRQ_PINT0  0x0       
-#define                 IRQ_PINT1  0x100000   /* Pin Interrupt 1 */
-#define                nIRQ_PINT1  0x0       
-#define                 IRQ_MDMA0  0x200000   /* Memory DMA Stream 0 */
-#define                nIRQ_MDMA0  0x0       
-#define                 IRQ_MDMA1  0x400000   /* Memory DMA Stream 1 */
-#define                nIRQ_MDMA1  0x0       
-#define                  IRQ_WDOG  0x800000   /* Watchdog Timer */
-#define                 nIRQ_WDOG  0x0       
-#define              IRQ_DMA1_ERR  0x1000000  /* DMA Controller 1 Error */
-#define             nIRQ_DMA1_ERR  0x0       
-#define            IRQ_SPORT2_ERR  0x2000000  /* SPORT2 Error */
-#define           nIRQ_SPORT2_ERR  0x0       
-#define            IRQ_SPORT3_ERR  0x4000000  /* SPORT3 Error */
-#define           nIRQ_SPORT3_ERR  0x0       
-#define               IRQ_MXVR_SD  0x8000000  /* MXVR Synchronous Data */
-#define              nIRQ_MXVR_SD  0x0       
-#define              IRQ_SPI1_ERR  0x10000000 /* SPI1 Error */
-#define             nIRQ_SPI1_ERR  0x0       
-#define              IRQ_SPI2_ERR  0x20000000 /* SPI2 Error */
-#define             nIRQ_SPI2_ERR  0x0       
-#define             IRQ_UART1_ERR  0x40000000 /* UART1 Error */
-#define            nIRQ_UART1_ERR  0x0       
-#define             IRQ_UART2_ERR  0x80000000 /* UART2 Error */
-#define            nIRQ_UART2_ERR  0x0       
+#define              DMA0_ERR  0x2        /* DMA Controller 0 Error */
+#define             EPPI0_ERR  0x4        /* EPPI0 Error */
+#define            SPORT0_ERR  0x8        /* SPORT0 Error */
+#define            SPORT1_ERR  0x10       /* SPORT1 Error */
+#define              SPI0_ERR  0x20       /* SPI0 Error */
+#define             UART0_ERR  0x40       /* UART0 Error */
+#define                   RTC  0x80       /* Real-Time Clock */
+#define                 DMA12  0x100      /* DMA Channel 12 */
+#define                  DMA0  0x200      /* DMA Channel 0 */
+#define                  DMA1  0x400      /* DMA Channel 1 */
+#define                  DMA2  0x800      /* DMA Channel 2 */
+#define                  DMA3  0x1000     /* DMA Channel 3 */
+#define                  DMA4  0x2000     /* DMA Channel 4 */
+#define                  DMA6  0x4000     /* DMA Channel 6 */
+#define                  DMA7  0x8000     /* DMA Channel 7 */
+#define                 PINT0  0x80000    /* Pin Interrupt 0 */
+#define                 PINT1  0x100000   /* Pin Interrupt 1 */
+#define                 MDMA0  0x200000   /* Memory DMA Stream 0 */
+#define                 MDMA1  0x400000   /* Memory DMA Stream 1 */
+#define                  WDOG  0x800000   /* Watchdog Timer */
+#define              DMA1_ERR  0x1000000  /* DMA Controller 1 Error */
+#define            SPORT2_ERR  0x2000000  /* SPORT2 Error */
+#define            SPORT3_ERR  0x4000000  /* SPORT3 Error */
+#define               MXVR_SD  0x8000000  /* MXVR Synchronous Data */
+#define              SPI1_ERR  0x10000000 /* SPI1 Error */
+#define              SPI2_ERR  0x20000000 /* SPI2 Error */
+#define             UART1_ERR  0x40000000 /* UART1 Error */
+#define             UART2_ERR  0x80000000 /* UART2 Error */
 
 /* Bit masks for SIC_IWR1, SIC_IMASK1, SIC_ISR1 */
 
-#define              IRQ_CAN0_ERR  0x1        /* CAN0 Error */
-#define             nIRQ_CAN0_ERR  0x0       
-#define                 IRQ_DMA18  0x2        /* DMA Channel 18 */
-#define                nIRQ_DMA18  0x0       
-#define                 IRQ_DMA19  0x4        /* DMA Channel 19 */
-#define                nIRQ_DMA19  0x0       
-#define                 IRQ_DMA20  0x8        /* DMA Channel 20 */
-#define                nIRQ_DMA20  0x0       
-#define                 IRQ_DMA21  0x10       /* DMA Channel 21 */
-#define                nIRQ_DMA21  0x0       
-#define                 IRQ_DMA13  0x20       /* DMA Channel 13 */
-#define                nIRQ_DMA13  0x0       
-#define                 IRQ_DMA14  0x40       /* DMA Channel 14 */
-#define                nIRQ_DMA14  0x0       
-#define                  IRQ_DMA5  0x80       /* DMA Channel 5 */
-#define                 nIRQ_DMA5  0x0       
-#define                 IRQ_DMA23  0x100      /* DMA Channel 23 */
-#define                nIRQ_DMA23  0x0       
-#define                  IRQ_DMA8  0x200      /* DMA Channel 8 */
-#define                 nIRQ_DMA8  0x0       
-#define                  IRQ_DMA9  0x400      /* DMA Channel 9 */
-#define                 nIRQ_DMA9  0x0       
-#define                 IRQ_DMA10  0x800      /* DMA Channel 10 */
-#define                nIRQ_DMA10  0x0       
-#define                 IRQ_DMA11  0x1000     /* DMA Channel 11 */
-#define                nIRQ_DMA11  0x0       
-#define                  IRQ_TWI0  0x2000     /* TWI0 */
-#define                 nIRQ_TWI0  0x0       
-#define                  IRQ_TWI1  0x4000     /* TWI1 */
-#define                 nIRQ_TWI1  0x0       
-#define               IRQ_CAN0_RX  0x8000     /* CAN0 Receive */
-#define              nIRQ_CAN0_RX  0x0       
-#define               IRQ_CAN0_TX  0x10000    /* CAN0 Transmit */
-#define              nIRQ_CAN0_TX  0x0       
-#define                 IRQ_MDMA2  0x20000    /* Memory DMA Stream 0 */
-#define                nIRQ_MDMA2  0x0       
-#define                 IRQ_MDMA3  0x40000    /* Memory DMA Stream 1 */
-#define                nIRQ_MDMA3  0x0       
-#define             IRQ_MXVR_STAT  0x80000    /* MXVR Status */
-#define            nIRQ_MXVR_STAT  0x0       
-#define               IRQ_MXVR_CM  0x100000   /* MXVR Control Message */
-#define              nIRQ_MXVR_CM  0x0       
-#define               IRQ_MXVR_AP  0x200000   /* MXVR Asynchronous Packet */
-#define              nIRQ_MXVR_AP  0x0       
-#define             IRQ_EPPI1_ERR  0x400000   /* EPPI1 Error */
-#define            nIRQ_EPPI1_ERR  0x0       
-#define             IRQ_EPPI2_ERR  0x800000   /* EPPI2 Error */
-#define            nIRQ_EPPI2_ERR  0x0       
-#define             IRQ_UART3_ERR  0x1000000  /* UART3 Error */
-#define            nIRQ_UART3_ERR  0x0       
-#define              IRQ_HOST_ERR  0x2000000  /* Host DMA Port Error */
-#define             nIRQ_HOST_ERR  0x0       
-#define               IRQ_USB_ERR  0x4000000  /* USB Error */
-#define              nIRQ_USB_ERR  0x0       
-#define              IRQ_PIXC_ERR  0x8000000  /* Pixel Compositor Error */
-#define             nIRQ_PIXC_ERR  0x0       
-#define               IRQ_NFC_ERR  0x10000000 /* Nand Flash Controller Error */
-#define              nIRQ_NFC_ERR  0x0       
-#define             IRQ_ATAPI_ERR  0x20000000 /* ATAPI Error */
-#define            nIRQ_ATAPI_ERR  0x0       
-#define              IRQ_CAN1_ERR  0x40000000 /* CAN1 Error */
-#define             nIRQ_CAN1_ERR  0x0       
-#define             IRQ_DMAR0_ERR  0x80000000 /* DMAR0 Overflow Error */
-#define            nIRQ_DMAR0_ERR  0x0       
-#define             IRQ_DMAR1_ERR  0x80000000 /* DMAR1 Overflow Error */
-#define            nIRQ_DMAR1_ERR  0x0       
-#define                 IRQ_DMAR0  0x80000000 /* DMAR0 Block */
-#define                nIRQ_DMAR0  0x0       
-#define                 IRQ_DMAR1  0x80000000 /* DMAR1 Block */
-#define                nIRQ_DMAR1  0x0       
+#define              CAN0_ERR  0x1        /* CAN0 Error */
+#define                 DMA18  0x2        /* DMA Channel 18 */
+#define                 DMA19  0x4        /* DMA Channel 19 */
+#define                 DMA20  0x8        /* DMA Channel 20 */
+#define                 DMA21  0x10       /* DMA Channel 21 */
+#define                 DMA13  0x20       /* DMA Channel 13 */
+#define                 DMA14  0x40       /* DMA Channel 14 */
+#define                  DMA5  0x80       /* DMA Channel 5 */
+#define                 DMA23  0x100      /* DMA Channel 23 */
+#define                  DMA8  0x200      /* DMA Channel 8 */
+#define                  DMA9  0x400      /* DMA Channel 9 */
+#define                 DMA10  0x800      /* DMA Channel 10 */
+#define                 DMA11  0x1000     /* DMA Channel 11 */
+#define                  TWI0  0x2000     /* TWI0 */
+#define                  TWI1  0x4000     /* TWI1 */
+#define               CAN0_RX  0x8000     /* CAN0 Receive */
+#define               CAN0_TX  0x10000    /* CAN0 Transmit */
+#define                 MDMA2  0x20000    /* Memory DMA Stream 0 */
+#define                 MDMA3  0x40000    /* Memory DMA Stream 1 */
+#define             MXVR_STAT  0x80000    /* MXVR Status */
+#define               MXVR_CM  0x100000   /* MXVR Control Message */
+#define               MXVR_AP  0x200000   /* MXVR Asynchronous Packet */
+#define             EPPI1_ERR  0x400000   /* EPPI1 Error */
+#define             EPPI2_ERR  0x800000   /* EPPI2 Error */
+#define             UART3_ERR  0x1000000  /* UART3 Error */
+#define              HOST_ERR  0x2000000  /* Host DMA Port Error */
+#define               USB_ERR  0x4000000  /* USB Error */
+#define              PIXC_ERR  0x8000000  /* Pixel Compositor Error */
+#define               NFC_ERR  0x10000000 /* Nand Flash Controller Error */
+#define             ATAPI_ERR  0x20000000 /* ATAPI Error */
+#define              CAN1_ERR  0x40000000 /* CAN1 Error */
+#define             DMAR0_ERR  0x80000000 /* DMAR0 Overflow Error */
+#define             DMAR1_ERR  0x80000000 /* DMAR1 Overflow Error */
+#define                 DMAR0  0x80000000 /* DMAR0 Block */
+#define                 DMAR1  0x80000000 /* DMAR1 Block */
 
 /* Bit masks for SIC_IWR2, SIC_IMASK2, SIC_ISR2 */
 
-#define                 IRQ_DMA15  0x1        /* DMA Channel 15 */
-#define                nIRQ_DMA15  0x0       
-#define                 IRQ_DMA16  0x2        /* DMA Channel 16 */
-#define                nIRQ_DMA16  0x0       
-#define                 IRQ_DMA17  0x4        /* DMA Channel 17 */
-#define                nIRQ_DMA17  0x0       
-#define                 IRQ_DMA22  0x8        /* DMA Channel 22 */
-#define                nIRQ_DMA22  0x0       
-#define                   IRQ_CNT  0x10       /* Counter */
-#define                  nIRQ_CNT  0x0       
-#define                   IRQ_KEY  0x20       /* Keypad */
-#define                  nIRQ_KEY  0x0       
-#define               IRQ_CAN1_RX  0x40       /* CAN1 Receive */
-#define              nIRQ_CAN1_RX  0x0       
-#define               IRQ_CAN1_TX  0x80       /* CAN1 Transmit */
-#define              nIRQ_CAN1_TX  0x0       
-#define             IRQ_SDH_MASK0  0x100      /* SDH Mask 0 */
-#define            nIRQ_SDH_MASK0  0x0       
-#define             IRQ_SDH_MASK1  0x200      /* SDH Mask 1 */
-#define            nIRQ_SDH_MASK1  0x0       
-#define              IRQ_USB_EINT  0x400      /* USB Exception */
-#define             nIRQ_USB_EINT  0x0       
-#define              IRQ_USB_INT0  0x800      /* USB Interrupt 0 */
-#define             nIRQ_USB_INT0  0x0       
-#define              IRQ_USB_INT1  0x1000     /* USB Interrupt 1 */
-#define             nIRQ_USB_INT1  0x0       
-#define              IRQ_USB_INT2  0x2000     /* USB Interrupt 2 */
-#define             nIRQ_USB_INT2  0x0       
-#define            IRQ_USB_DMAINT  0x4000     /* USB DMA */
-#define           nIRQ_USB_DMAINT  0x0       
-#define                IRQ_OTPSEC  0x8000     /* OTP Access Complete */
-#define               nIRQ_OTPSEC  0x0       
-#define                IRQ_TIMER0  0x400000   /* Timer 0 */
-#define               nIRQ_TIMER0  0x0       
-#define                IRQ_TIMER1  0x800000   /* Timer 1 */
-#define               nIRQ_TIMER1  0x0       
-#define                IRQ_TIMER2  0x1000000  /* Timer 2 */
-#define               nIRQ_TIMER2  0x0       
-#define                IRQ_TIMER3  0x2000000  /* Timer 3 */
-#define               nIRQ_TIMER3  0x0       
-#define                IRQ_TIMER4  0x4000000  /* Timer 4 */
-#define               nIRQ_TIMER4  0x0       
-#define                IRQ_TIMER5  0x8000000  /* Timer 5 */
-#define               nIRQ_TIMER5  0x0       
-#define                IRQ_TIMER6  0x10000000 /* Timer 6 */
-#define               nIRQ_TIMER6  0x0       
-#define                IRQ_TIMER7  0x20000000 /* Timer 7 */
-#define               nIRQ_TIMER7  0x0       
-#define                 IRQ_PINT2  0x40000000 /* Pin Interrupt 2 */
-#define                nIRQ_PINT2  0x0       
-#define                 IRQ_PINT3  0x80000000 /* Pin Interrupt 3 */
-#define                nIRQ_PINT3  0x0       
+#define                 DMA15  0x1        /* DMA Channel 15 */
+#define                 DMA16  0x2        /* DMA Channel 16 */
+#define                 DMA17  0x4        /* DMA Channel 17 */
+#define                 DMA22  0x8        /* DMA Channel 22 */
+#define                   CNT  0x10       /* Counter */
+#define                   KEY  0x20       /* Keypad */
+#define               CAN1_RX  0x40       /* CAN1 Receive */
+#define               CAN1_TX  0x80       /* CAN1 Transmit */
+#define             SDH_INT_MASK0  0x100      /* SDH Mask 0 */
+#define             SDH_INT_MASK1  0x200      /* SDH Mask 1 */
+#define              USB_EINT  0x400      /* USB Exception */
+#define              USB_INT0  0x800      /* USB Interrupt 0 */
+#define              USB_INT1  0x1000     /* USB Interrupt 1 */
+#define              USB_INT2  0x2000     /* USB Interrupt 2 */
+#define            USB_DMAINT  0x4000     /* USB DMA */
+#define                OTPSEC  0x8000     /* OTP Access Complete */
+#define                TIMER0  0x400000   /* Timer 0 */
+#define                TIMER1  0x800000   /* Timer 1 */
+#define                TIMER2  0x1000000  /* Timer 2 */
+#define                TIMER3  0x2000000  /* Timer 3 */
+#define                TIMER4  0x4000000  /* Timer 4 */
+#define                TIMER5  0x8000000  /* Timer 5 */
+#define                TIMER6  0x10000000 /* Timer 6 */
+#define                TIMER7  0x20000000 /* Timer 7 */
+#define                 PINT2  0x40000000 /* Pin Interrupt 2 */
+#define                 PINT3  0x80000000 /* Pin Interrupt 3 */
 
 /* Bit masks for DMAx_CONFIG, MDMA_Sx_CONFIG, MDMA_Dx_CONFIG */
 
 #define                     DMAEN  0x1        /* DMA Channel Enable */
-#define                    nDMAEN  0x0       
 #define                       WNR  0x2        /* DMA Direction */
-#define                      nWNR  0x0       
-#define                    WDSIZE  0xc        /* Transfer Word Size */
+#define                  WDSIZE_8  0x0        /* Transfer Word Size = 8 */
+#define                 WDSIZE_16  0x4        /* Transfer Word Size = 16 */
+#define                 WDSIZE_32  0x8        /* Transfer Word Size = 32 */
 #define                     DMA2D  0x10       /* DMA Mode */
-#define                    nDMA2D  0x0       
 #define                   RESTART  0x20       /* Work Unit Transitions */
-#define                  nRESTART  0x0       
 #define                    DI_SEL  0x40       /* Data Interrupt Timing Select */
-#define                   nDI_SEL  0x0       
 #define                     DI_EN  0x80       /* Data Interrupt Enable */
-#define                    nDI_EN  0x0       
 #define                    NDSIZE  0xf00      /* Flex Descriptor Size */
 #define                   DMAFLOW  0xf000     /* Next Operation */
 
 /* Bit masks for DMAx_IRQ_STATUS, MDMA_Sx_IRQ_STATUS, MDMA_Dx_IRQ_STATUS */
 
 #define                  DMA_DONE  0x1        /* DMA Completion Interrupt Status */
-#define                 nDMA_DONE  0x0       
 #define                   DMA_ERR  0x2        /* DMA Error Interrupt Status */
-#define                  nDMA_ERR  0x0       
 #define                    DFETCH  0x4        /* DMA Descriptor Fetch */
-#define                   nDFETCH  0x0       
 #define                   DMA_RUN  0x8        /* DMA Channel Running */
-#define                  nDMA_RUN  0x0       
 
 /* Bit masks for DMAx_PERIPHERAL_MAP, MDMA_Sx_IRQ_STATUS, MDMA_Dx_IRQ_STATUS */
 
 #define                     CTYPE  0x40       /* DMA Channel Type */
-#define                    nCTYPE  0x0       
 #define                      PMAP  0xf000     /* Peripheral Mapped To This Channel */
 
 /* Bit masks for DMACx_TCPER */
 /* Bit masks for DMAC1_PERIMUX */
 
 #define                   PMUXSDH  0x1        /* Peripheral Select for DMA22 channel */
-#define                  nPMUXSDH  0x0       
 
-/* Bit masks for EBIU_AMGCTL */
+/* *********************  ASYNCHRONOUS MEMORY CONTROLLER MASKS  *************************/
+/* EBIU_AMGCTL Masks                                                                                                                                   */
+#define AMCKEN                 0x0001          /* Enable CLKOUT                                                                        */
+#define        AMBEN_NONE              0x0000          /* All Banks Disabled                                                           */
+#define AMBEN_B0               0x0002          /* Enable Async Memory Bank 0 only                                      */
+#define AMBEN_B0_B1            0x0004          /* Enable Async Memory Banks 0 & 1 only                         */
+#define AMBEN_B0_B1_B2 0x0006          /* Enable Async Memory Banks 0, 1, and 2                        */
+#define AMBEN_ALL              0x0008          /* Enable Async Memory Banks (all) 0, 1, 2, and 3       */
 
-#define                    AMCKEN  0x1        /* Async Memory Enable */
-#define                   nAMCKEN  0x0       
-#define                     AMBEN  0xe        /* Async bank enable */
 
 /* Bit masks for EBIU_AMBCTL0 */
 
 #define                   B0RDYEN  0x1        /* Bank 0 ARDY Enable */
-#define                  nB0RDYEN  0x0       
 #define                  B0RDYPOL  0x2        /* Bank 0 ARDY Polarity */
-#define                 nB0RDYPOL  0x0       
 #define                      B0TT  0xc        /* Bank 0 transition time */
 #define                      B0ST  0x30       /* Bank 0 Setup time */
 #define                      B0HT  0xc0       /* Bank 0 Hold time */
 #define                     B0RAT  0xf00      /* Bank 0 Read access time */
 #define                     B0WAT  0xf000     /* Bank 0 write access time */
 #define                   B1RDYEN  0x10000    /* Bank 1 ARDY Enable */
-#define                  nB1RDYEN  0x0       
 #define                  B1RDYPOL  0x20000    /* Bank 1 ARDY Polarity */
-#define                 nB1RDYPOL  0x0       
 #define                      B1TT  0xc0000    /* Bank 1 transition time */
 #define                      B1ST  0x300000   /* Bank 1 Setup time */
 #define                      B1HT  0xc00000   /* Bank 1 Hold time */
 /* Bit masks for EBIU_AMBCTL1 */
 
 #define                   B2RDYEN  0x1        /* Bank 2 ARDY Enable */
-#define                  nB2RDYEN  0x0       
 #define                  B2RDYPOL  0x2        /* Bank 2 ARDY Polarity */
-#define                 nB2RDYPOL  0x0       
 #define                      B2TT  0xc        /* Bank 2 transition time */
 #define                      B2ST  0x30       /* Bank 2 Setup time */
 #define                      B2HT  0xc0       /* Bank 2 Hold time */
 #define                     B2RAT  0xf00      /* Bank 2 Read access time */
 #define                     B2WAT  0xf000     /* Bank 2 write access time */
 #define                   B3RDYEN  0x10000    /* Bank 3 ARDY Enable */
-#define                  nB3RDYEN  0x0       
 #define                  B3RDYPOL  0x20000    /* Bank 3 ARDY Polarity */
-#define                 nB3RDYPOL  0x0       
 #define                      B3TT  0xc0000    /* Bank 3 transition time */
 #define                      B3ST  0x300000   /* Bank 3 Setup time */
 #define                      B3HT  0xc00000   /* Bank 3 Hold time */
 /* Bit masks for EBIU_FCTL */
 
 #define               TESTSETLOCK  0x1        /* Test set lock */
-#define              nTESTSETLOCK  0x0       
 #define                      BCLK  0x6        /* Burst clock frequency */
 #define                      PGWS  0x38       /* Page wait states */
 #define                      PGSZ  0x40       /* Page size */
-#define                     nPGSZ  0x0       
 #define                      RDDL  0x380      /* Read data delay */
 
 /* Bit masks for EBIU_ARBSTAT */
 
 #define                   ARBSTAT  0x1        /* Arbitration status */
-#define                  nARBSTAT  0x0       
 #define                    BGSTAT  0x2        /* Bus grant status */
-#define                   nBGSTAT  0x0       
 
 /* Bit masks for EBIU_DDRCTL0 */
 
 #define               BURSTLENGTH  0x7        /* Burst length */
 #define                CASLATENCY  0x70       /* CAS latency */
 #define                  DLLRESET  0x100      /* DLL Reset */
-#define                 nDLLRESET  0x0       
 #define                      REGE  0x1000     /* Register mode enable */
-#define                     nREGE  0x0       
 
 /* Bit masks for EBIU_DDRCTL3 */
 
 #define                DEB3_PFLEN  0x30       /* Pre fetch length for DEB3 accesses */
 #define          DEB_ARB_PRIORITY  0x700      /* Arbitration between DEB busses */
 #define               DEB1_URGENT  0x1000     /* DEB1 Urgent */
-#define              nDEB1_URGENT  0x0       
 #define               DEB2_URGENT  0x2000     /* DEB2 Urgent */
-#define              nDEB2_URGENT  0x0       
 #define               DEB3_URGENT  0x4000     /* DEB3 Urgent */
-#define              nDEB3_URGENT  0x0       
 
 /* Bit masks for EBIU_ERRMST */
 
 #define                DEB1_ERROR  0x1        /* DEB1 Error */
-#define               nDEB1_ERROR  0x0       
 #define                DEB2_ERROR  0x2        /* DEB2 Error */
-#define               nDEB2_ERROR  0x0       
 #define                DEB3_ERROR  0x4        /* DEB3 Error */
-#define               nDEB3_ERROR  0x0       
 #define                CORE_ERROR  0x8        /* Core error */
-#define               nCORE_ERROR  0x0       
 #define                DEB_MERROR  0x10       /* DEB1 Error (2nd) */
-#define               nDEB_MERROR  0x0       
 #define               DEB2_MERROR  0x20       /* DEB2 Error (2nd) */
-#define              nDEB2_MERROR  0x0       
 #define               DEB3_MERROR  0x40       /* DEB3 Error (2nd) */
-#define              nDEB3_MERROR  0x0       
 #define               CORE_MERROR  0x80       /* Core Error (2nd) */
-#define              nCORE_MERROR  0x0       
 
 /* Bit masks for EBIU_ERRADD */
 
 /* Bit masks for EBIU_RSTCTL */
 
 #define                 DDRSRESET  0x1        /* DDR soft reset */
-#define                nDDRSRESET  0x0       
 #define               PFTCHSRESET  0x4        /* DDR prefetch reset */
-#define              nPFTCHSRESET  0x0       
 #define                     SRREQ  0x8        /* Self-refresh request */
-#define                    nSRREQ  0x0       
 #define                     SRACK  0x10       /* Self-refresh acknowledge */
-#define                    nSRACK  0x0       
 #define                MDDRENABLE  0x20       /* Mobile DDR enable */
-#define               nMDDRENABLE  0x0       
 
 /* Bit masks for EBIU_DDRBRC0 */
 
 /* Bit masks for EBIU_DDRMCEN */
 
 #define                B0WCENABLE  0x1        /* Bank 0 write count enable */
-#define               nB0WCENABLE  0x0       
 #define                B1WCENABLE  0x2        /* Bank 1 write count enable */
-#define               nB1WCENABLE  0x0       
 #define                B2WCENABLE  0x4        /* Bank 2 write count enable */
-#define               nB2WCENABLE  0x0       
 #define                B3WCENABLE  0x8        /* Bank 3 write count enable */
-#define               nB3WCENABLE  0x0       
 #define                B4WCENABLE  0x10       /* Bank 4 write count enable */
-#define               nB4WCENABLE  0x0       
 #define                B5WCENABLE  0x20       /* Bank 5 write count enable */
-#define               nB5WCENABLE  0x0       
 #define                B6WCENABLE  0x40       /* Bank 6 write count enable */
-#define               nB6WCENABLE  0x0       
 #define                B7WCENABLE  0x80       /* Bank 7 write count enable */
-#define               nB7WCENABLE  0x0       
 #define                B0RCENABLE  0x100      /* Bank 0 read count enable */
-#define               nB0RCENABLE  0x0       
 #define                B1RCENABLE  0x200      /* Bank 1 read count enable */
-#define               nB1RCENABLE  0x0       
 #define                B2RCENABLE  0x400      /* Bank 2 read count enable */
-#define               nB2RCENABLE  0x0       
 #define                B3RCENABLE  0x800      /* Bank 3 read count enable */
-#define               nB3RCENABLE  0x0       
 #define                B4RCENABLE  0x1000     /* Bank 4 read count enable */
-#define               nB4RCENABLE  0x0       
 #define                B5RCENABLE  0x2000     /* Bank 5 read count enable */
-#define               nB5RCENABLE  0x0       
 #define                B6RCENABLE  0x4000     /* Bank 6 read count enable */
-#define               nB6RCENABLE  0x0       
 #define                B7RCENABLE  0x8000     /* Bank 7 read count enable */
-#define               nB7RCENABLE  0x0       
 #define             ROWACTCENABLE  0x10000    /* DDR Row activate count enable */
-#define            nROWACTCENABLE  0x0       
 #define                RWTCENABLE  0x20000    /* DDR R/W Turn around count enable */
-#define               nRWTCENABLE  0x0       
 #define                 ARCENABLE  0x40000    /* DDR Auto-refresh count enable */
-#define                nARCENABLE  0x0       
 #define                 GC0ENABLE  0x100000   /* DDR Grant count 0 enable */
-#define                nGC0ENABLE  0x0       
 #define                 GC1ENABLE  0x200000   /* DDR Grant count 1 enable */
-#define                nGC1ENABLE  0x0       
 #define                 GC2ENABLE  0x400000   /* DDR Grant count 2 enable */
-#define                nGC2ENABLE  0x0       
 #define                 GC3ENABLE  0x800000   /* DDR Grant count 3 enable */
-#define                nGC3ENABLE  0x0       
 #define                 GCCONTROL  0x3000000  /* DDR Grant Count Control */
 
 /* Bit masks for EBIU_DDRMCCL */
 
 #define                 CB0WCOUNT  0x1        /* Clear write count 0 */
-#define                nCB0WCOUNT  0x0       
 #define                 CB1WCOUNT  0x2        /* Clear write count 1 */
-#define                nCB1WCOUNT  0x0       
 #define                 CB2WCOUNT  0x4        /* Clear write count 2 */
-#define                nCB2WCOUNT  0x0       
 #define                 CB3WCOUNT  0x8        /* Clear write count 3 */
-#define                nCB3WCOUNT  0x0       
 #define                 CB4WCOUNT  0x10       /* Clear write count 4 */
-#define                nCB4WCOUNT  0x0       
 #define                 CB5WCOUNT  0x20       /* Clear write count 5 */
-#define                nCB5WCOUNT  0x0       
 #define                 CB6WCOUNT  0x40       /* Clear write count 6 */
-#define                nCB6WCOUNT  0x0       
 #define                 CB7WCOUNT  0x80       /* Clear write count 7 */
-#define                nCB7WCOUNT  0x0       
 #define                  CBRCOUNT  0x100      /* Clear read count 0 */
-#define                 nCBRCOUNT  0x0       
 #define                 CB1RCOUNT  0x200      /* Clear read count 1 */
-#define                nCB1RCOUNT  0x0       
 #define                 CB2RCOUNT  0x400      /* Clear read count 2 */
-#define                nCB2RCOUNT  0x0       
 #define                 CB3RCOUNT  0x800      /* Clear read count 3 */
-#define                nCB3RCOUNT  0x0       
 #define                 CB4RCOUNT  0x1000     /* Clear read count 4 */
-#define                nCB4RCOUNT  0x0       
 #define                 CB5RCOUNT  0x2000     /* Clear read count 5 */
-#define                nCB5RCOUNT  0x0       
 #define                 CB6RCOUNT  0x4000     /* Clear read count 6 */
-#define                nCB6RCOUNT  0x0       
 #define                 CB7RCOUNT  0x8000     /* Clear read count 7 */
-#define                nCB7RCOUNT  0x0       
 #define                  CRACOUNT  0x10000    /* Clear row activation count */
-#define                 nCRACOUNT  0x0       
 #define                CRWTACOUNT  0x20000    /* Clear R/W turn-around count */
-#define               nCRWTACOUNT  0x0       
 #define                  CARCOUNT  0x40000    /* Clear auto-refresh count */
-#define                 nCARCOUNT  0x0       
 #define                  CG0COUNT  0x100000   /* Clear grant count 0 */
-#define                 nCG0COUNT  0x0       
 #define                  CG1COUNT  0x200000   /* Clear grant count 1 */
-#define                 nCG1COUNT  0x0       
 #define                  CG2COUNT  0x400000   /* Clear grant count 2 */
-#define                 nCG2COUNT  0x0       
 #define                  CG3COUNT  0x800000   /* Clear grant count 3 */
-#define                 nCG3COUNT  0x0       
 
 /* Bit masks for (PORTx is PORTA - PORTJ) includes PORTx_FER, PORTx_SET, PORTx_CLEAR, PORTx_DIR_SET, PORTx_DIR_CLEAR, PORTx_INEN */
 
 #define                       Px0  0x1        /* GPIO 0 */
-#define                      nPx0  0x0       
 #define                       Px1  0x2        /* GPIO 1 */
-#define                      nPx1  0x0       
 #define                       Px2  0x4        /* GPIO 2 */
-#define                      nPx2  0x0       
 #define                       Px3  0x8        /* GPIO 3 */
-#define                      nPx3  0x0       
 #define                       Px4  0x10       /* GPIO 4 */
-#define                      nPx4  0x0       
 #define                       Px5  0x20       /* GPIO 5 */
-#define                      nPx5  0x0       
 #define                       Px6  0x40       /* GPIO 6 */
-#define                      nPx6  0x0       
 #define                       Px7  0x80       /* GPIO 7 */
-#define                      nPx7  0x0       
 #define                       Px8  0x100      /* GPIO 8 */
-#define                      nPx8  0x0       
 #define                       Px9  0x200      /* GPIO 9 */
-#define                      nPx9  0x0       
 #define                      Px10  0x400      /* GPIO 10 */
-#define                     nPx10  0x0       
 #define                      Px11  0x800      /* GPIO 11 */
-#define                     nPx11  0x0       
 #define                      Px12  0x1000     /* GPIO 12 */
-#define                     nPx12  0x0       
 #define                      Px13  0x2000     /* GPIO 13 */
-#define                     nPx13  0x0       
 #define                      Px14  0x4000     /* GPIO 14 */
-#define                     nPx14  0x0       
 #define                      Px15  0x8000     /* GPIO 15 */
-#define                     nPx15  0x0       
 
 /* Bit masks for PORTA_MUX - PORTJ_MUX */
 
 /* Bit masks for PINTx_MASK_SET/CLEAR, PINTx_REQUEST, PINTx_LATCH, PINTx_EDGE_SET/CLEAR, PINTx_INVERT_SET/CLEAR, PINTx_PINTSTATE */
 
 #define                       IB0  0x1        /* Interrupt Bit 0 */
-#define                      nIB0  0x0       
 #define                       IB1  0x2        /* Interrupt Bit 1 */
-#define                      nIB1  0x0       
 #define                       IB2  0x4        /* Interrupt Bit 2 */
-#define                      nIB2  0x0       
 #define                       IB3  0x8        /* Interrupt Bit 3 */
-#define                      nIB3  0x0       
 #define                       IB4  0x10       /* Interrupt Bit 4 */
-#define                      nIB4  0x0       
 #define                       IB5  0x20       /* Interrupt Bit 5 */
-#define                      nIB5  0x0       
 #define                       IB6  0x40       /* Interrupt Bit 6 */
-#define                      nIB6  0x0       
 #define                       IB7  0x80       /* Interrupt Bit 7 */
-#define                      nIB7  0x0       
 #define                       IB8  0x100      /* Interrupt Bit 8 */
-#define                      nIB8  0x0       
 #define                       IB9  0x200      /* Interrupt Bit 9 */
-#define                      nIB9  0x0       
 #define                      IB10  0x400      /* Interrupt Bit 10 */
-#define                     nIB10  0x0       
 #define                      IB11  0x800      /* Interrupt Bit 11 */
-#define                     nIB11  0x0       
 #define                      IB12  0x1000     /* Interrupt Bit 12 */
-#define                     nIB12  0x0       
 #define                      IB13  0x2000     /* Interrupt Bit 13 */
-#define                     nIB13  0x0       
 #define                      IB14  0x4000     /* Interrupt Bit 14 */
-#define                     nIB14  0x0       
 #define                      IB15  0x8000     /* Interrupt Bit 15 */
-#define                     nIB15  0x0       
 
 /* Bit masks for TIMERx_CONFIG */
 
 #define                     TMODE  0x3        /* Timer Mode */
 #define                  PULSE_HI  0x4        /* Pulse Polarity */
-#define                 nPULSE_HI  0x0       
 #define                PERIOD_CNT  0x8        /* Period Count */
-#define               nPERIOD_CNT  0x0       
 #define                   IRQ_ENA  0x10       /* Interrupt Request Enable */
-#define                  nIRQ_ENA  0x0       
 #define                   TIN_SEL  0x20       /* Timer Input Select */
-#define                  nTIN_SEL  0x0       
 #define                   OUT_DIS  0x40       /* Output Pad Disable */
-#define                  nOUT_DIS  0x0       
 #define                   CLK_SEL  0x80       /* Timer Clock Select */
-#define                  nCLK_SEL  0x0       
 #define                 TOGGLE_HI  0x100      /* Toggle Mode */
-#define                nTOGGLE_HI  0x0       
 #define                   EMU_RUN  0x200      /* Emulation Behavior Select */
-#define                  nEMU_RUN  0x0       
 #define                   ERR_TYP  0xc000     /* Error Type */
 
 /* Bit masks for TIMER_ENABLE0 */
 
 #define                    TIMEN0  0x1        /* Timer 0 Enable */
-#define                   nTIMEN0  0x0       
 #define                    TIMEN1  0x2        /* Timer 1 Enable */
-#define                   nTIMEN1  0x0       
 #define                    TIMEN2  0x4        /* Timer 2 Enable */
-#define                   nTIMEN2  0x0       
 #define                    TIMEN3  0x8        /* Timer 3 Enable */
-#define                   nTIMEN3  0x0       
 #define                    TIMEN4  0x10       /* Timer 4 Enable */
-#define                   nTIMEN4  0x0       
 #define                    TIMEN5  0x20       /* Timer 5 Enable */
-#define                   nTIMEN5  0x0       
 #define                    TIMEN6  0x40       /* Timer 6 Enable */
-#define                   nTIMEN6  0x0       
 #define                    TIMEN7  0x80       /* Timer 7 Enable */
-#define                   nTIMEN7  0x0       
 
 /* Bit masks for TIMER_DISABLE0 */
 
 #define                   TIMDIS0  0x1        /* Timer 0 Disable */
-#define                  nTIMDIS0  0x0       
 #define                   TIMDIS1  0x2        /* Timer 1 Disable */
-#define                  nTIMDIS1  0x0       
 #define                   TIMDIS2  0x4        /* Timer 2 Disable */
-#define                  nTIMDIS2  0x0       
 #define                   TIMDIS3  0x8        /* Timer 3 Disable */
-#define                  nTIMDIS3  0x0       
 #define                   TIMDIS4  0x10       /* Timer 4 Disable */
-#define                  nTIMDIS4  0x0       
 #define                   TIMDIS5  0x20       /* Timer 5 Disable */
-#define                  nTIMDIS5  0x0       
 #define                   TIMDIS6  0x40       /* Timer 6 Disable */
-#define                  nTIMDIS6  0x0       
 #define                   TIMDIS7  0x80       /* Timer 7 Disable */
-#define                  nTIMDIS7  0x0       
 
 /* Bit masks for TIMER_STATUS0 */
 
 #define                    TIMIL0  0x1        /* Timer 0 Interrupt */
-#define                   nTIMIL0  0x0       
 #define                    TIMIL1  0x2        /* Timer 1 Interrupt */
-#define                   nTIMIL1  0x0       
 #define                    TIMIL2  0x4        /* Timer 2 Interrupt */
-#define                   nTIMIL2  0x0       
 #define                    TIMIL3  0x8        /* Timer 3 Interrupt */
-#define                   nTIMIL3  0x0       
 #define                 TOVF_ERR0  0x10       /* Timer 0 Counter Overflow */
-#define                nTOVF_ERR0  0x0       
 #define                 TOVF_ERR1  0x20       /* Timer 1 Counter Overflow */
-#define                nTOVF_ERR1  0x0       
 #define                 TOVF_ERR2  0x40       /* Timer 2 Counter Overflow */
-#define                nTOVF_ERR2  0x0       
 #define                 TOVF_ERR3  0x80       /* Timer 3 Counter Overflow */
-#define                nTOVF_ERR3  0x0       
 #define                     TRUN0  0x1000     /* Timer 0 Slave Enable Status */
-#define                    nTRUN0  0x0       
 #define                     TRUN1  0x2000     /* Timer 1 Slave Enable Status */
-#define                    nTRUN1  0x0       
 #define                     TRUN2  0x4000     /* Timer 2 Slave Enable Status */
-#define                    nTRUN2  0x0       
 #define                     TRUN3  0x8000     /* Timer 3 Slave Enable Status */
-#define                    nTRUN3  0x0       
 #define                    TIMIL4  0x10000    /* Timer 4 Interrupt */
-#define                   nTIMIL4  0x0       
 #define                    TIMIL5  0x20000    /* Timer 5 Interrupt */
-#define                   nTIMIL5  0x0       
 #define                    TIMIL6  0x40000    /* Timer 6 Interrupt */
-#define                   nTIMIL6  0x0       
 #define                    TIMIL7  0x80000    /* Timer 7 Interrupt */
-#define                   nTIMIL7  0x0       
 #define                 TOVF_ERR4  0x100000   /* Timer 4 Counter Overflow */
-#define                nTOVF_ERR4  0x0       
 #define                 TOVF_ERR5  0x200000   /* Timer 5 Counter Overflow */
-#define                nTOVF_ERR5  0x0       
 #define                 TOVF_ERR6  0x400000   /* Timer 6 Counter Overflow */
-#define                nTOVF_ERR6  0x0       
 #define                 TOVF_ERR7  0x800000   /* Timer 7 Counter Overflow */
-#define                nTOVF_ERR7  0x0       
 #define                     TRUN4  0x10000000 /* Timer 4 Slave Enable Status */
-#define                    nTRUN4  0x0       
 #define                     TRUN5  0x20000000 /* Timer 5 Slave Enable Status */
-#define                    nTRUN5  0x0       
 #define                     TRUN6  0x40000000 /* Timer 6 Slave Enable Status */
-#define                    nTRUN6  0x0       
 #define                     TRUN7  0x80000000 /* Timer 7 Slave Enable Status */
-#define                    nTRUN7  0x0       
 
 /* Bit masks for WDOG_CTL */
 
 #define                      WDEV  0x6        /* Watchdog Event */
 #define                      WDEN  0xff0      /* Watchdog Enable */
 #define                      WDRO  0x8000     /* Watchdog Rolled Over */
-#define                     nWDRO  0x0       
 
 /* Bit masks for CNT_CONFIG */
 
 #define                      CNTE  0x1        /* Counter Enable */
-#define                     nCNTE  0x0       
 #define                      DEBE  0x2        /* Debounce Enable */
-#define                     nDEBE  0x0       
 #define                    CDGINV  0x10       /* CDG Pin Polarity Invert */
-#define                   nCDGINV  0x0       
 #define                    CUDINV  0x20       /* CUD Pin Polarity Invert */
-#define                   nCUDINV  0x0       
 #define                    CZMINV  0x40       /* CZM Pin Polarity Invert */
-#define                   nCZMINV  0x0       
 #define                   CNTMODE  0x700      /* Counter Operating Mode */
 #define                      ZMZC  0x800      /* CZM Zeroes Counter Enable */
-#define                     nZMZC  0x0       
 #define                   BNDMODE  0x3000     /* Boundary register Mode */
 #define                    INPDIS  0x8000     /* CUG and CDG Input Disable */
-#define                   nINPDIS  0x0       
 
 /* Bit masks for CNT_IMASK */
 
 #define                      ICIE  0x1        /* Illegal Gray/Binary Code Interrupt Enable */
-#define                     nICIE  0x0       
 #define                      UCIE  0x2        /* Up count Interrupt Enable */
-#define                     nUCIE  0x0       
 #define                      DCIE  0x4        /* Down count Interrupt Enable */
-#define                     nDCIE  0x0       
 #define                    MINCIE  0x8        /* Min Count Interrupt Enable */
-#define                   nMINCIE  0x0       
 #define                    MAXCIE  0x10       /* Max Count Interrupt Enable */
-#define                   nMAXCIE  0x0       
 #define                   COV31IE  0x20       /* Bit 31 Overflow Interrupt Enable */
-#define                  nCOV31IE  0x0       
 #define                   COV15IE  0x40       /* Bit 15 Overflow Interrupt Enable */
-#define                  nCOV15IE  0x0       
 #define                   CZEROIE  0x80       /* Count to Zero Interrupt Enable */
-#define                  nCZEROIE  0x0       
 #define                     CZMIE  0x100      /* CZM Pin Interrupt Enable */
-#define                    nCZMIE  0x0       
 #define                    CZMEIE  0x200      /* CZM Error Interrupt Enable */
-#define                   nCZMEIE  0x0       
 #define                    CZMZIE  0x400      /* CZM Zeroes Counter Interrupt Enable */
-#define                   nCZMZIE  0x0       
 
 /* Bit masks for CNT_STATUS */
 
 #define                      ICII  0x1        /* Illegal Gray/Binary Code Interrupt Identifier */
-#define                     nICII  0x0       
 #define                      UCII  0x2        /* Up count Interrupt Identifier */
-#define                     nUCII  0x0       
 #define                      DCII  0x4        /* Down count Interrupt Identifier */
-#define                     nDCII  0x0       
 #define                    MINCII  0x8        /* Min Count Interrupt Identifier */
-#define                   nMINCII  0x0       
 #define                    MAXCII  0x10       /* Max Count Interrupt Identifier */
-#define                   nMAXCII  0x0       
 #define                   COV31II  0x20       /* Bit 31 Overflow Interrupt Identifier */
-#define                  nCOV31II  0x0       
 #define                   COV15II  0x40       /* Bit 15 Overflow Interrupt Identifier */
-#define                  nCOV15II  0x0       
 #define                   CZEROII  0x80       /* Count to Zero Interrupt Identifier */
-#define                  nCZEROII  0x0       
 #define                     CZMII  0x100      /* CZM Pin Interrupt Identifier */
-#define                    nCZMII  0x0       
 #define                    CZMEII  0x200      /* CZM Error Interrupt Identifier */
-#define                   nCZMEII  0x0       
 #define                    CZMZII  0x400      /* CZM Zeroes Counter Interrupt Identifier */
-#define                   nCZMZII  0x0       
 
 /* Bit masks for CNT_COMMAND */
 
 #define                    W1LMIN  0xf0       /* Load Min Register */
 #define                    W1LMAX  0xf00      /* Load Max Register */
 #define                  W1ZMONCE  0x1000     /* Enable CZM Clear Counter Once */
-#define                 nW1ZMONCE  0x0       
 
 /* Bit masks for CNT_DEBOUNCE */
 
 /* Bit masks for RTC_ICTL */
 
 #define STOPWATCH_INTERRUPT_ENABLE  0x1        /* Stopwatch Interrupt Enable */
-#define nSTOPWATCH_INTERRUPT_ENABLE  0x0       
 #define    ALARM_INTERRUPT_ENABLE  0x2        /* Alarm Interrupt Enable */
-#define   nALARM_INTERRUPT_ENABLE  0x0       
 #define  SECONDS_INTERRUPT_ENABLE  0x4        /* Seconds Interrupt Enable */
-#define nSECONDS_INTERRUPT_ENABLE  0x0       
 #define  MINUTES_INTERRUPT_ENABLE  0x8        /* Minutes Interrupt Enable */
-#define nMINUTES_INTERRUPT_ENABLE  0x0       
 #define    HOURS_INTERRUPT_ENABLE  0x10       /* Hours Interrupt Enable */
-#define   nHOURS_INTERRUPT_ENABLE  0x0       
 #define TWENTY_FOUR_HOURS_INTERRUPT_ENABLE  0x20       /* 24 Hours Interrupt Enable */
-#define nTWENTY_FOUR_HOURS_INTERRUPT_ENABLE  0x0       
 #define DAY_ALARM_INTERRUPT_ENABLE  0x40       /* Day Alarm Interrupt Enable */
-#define nDAY_ALARM_INTERRUPT_ENABLE  0x0       
 #define WRITE_COMPLETE_INTERRUPT_ENABLE  0x8000     /* Write Complete Interrupt Enable */
-#define nWRITE_COMPLETE_INTERRUPT_ENABLE  0x0       
 
 /* Bit masks for RTC_ISTAT */
 
 #define      STOPWATCH_EVENT_FLAG  0x1        /* Stopwatch Event Flag */
-#define     nSTOPWATCH_EVENT_FLAG  0x0       
 #define          ALARM_EVENT_FLAG  0x2        /* Alarm Event Flag */
-#define         nALARM_EVENT_FLAG  0x0       
 #define        SECONDS_EVENT_FLAG  0x4        /* Seconds Event Flag */
-#define       nSECONDS_EVENT_FLAG  0x0       
 #define        MINUTES_EVENT_FLAG  0x8        /* Minutes Event Flag */
-#define       nMINUTES_EVENT_FLAG  0x0       
 #define          HOURS_EVENT_FLAG  0x10       /* Hours Event Flag */
-#define         nHOURS_EVENT_FLAG  0x0       
 #define TWENTY_FOUR_HOURS_EVENT_FLAG  0x20       /* 24 Hours Event Flag */
-#define nTWENTY_FOUR_HOURS_EVENT_FLAG  0x0       
 #define      DAY_ALARM_EVENT_FLAG  0x40       /* Day Alarm Event Flag */
-#define     nDAY_ALARM_EVENT_FLAG  0x0       
 #define     WRITE_PENDING__STATUS  0x4000     /* Write Pending  Status */
-#define    nWRITE_PENDING__STATUS  0x0       
 #define            WRITE_COMPLETE  0x8000     /* Write Complete */
-#define           nWRITE_COMPLETE  0x0       
 
 /* Bit masks for RTC_SWCNT */
 
 /* Bit masks for RTC_PREN */
 
 #define                      PREN  0x1        /* Prescaler Enable */
-#define                     nPREN  0x0       
 
 /* Bit masks for OTP_CONTROL */
 
 #define                FUSE_FADDR  0x1ff      /* OTP/Fuse Address */
 #define                      FIEN  0x800      /* OTP/Fuse Interrupt Enable */
-#define                     nFIEN  0x0       
 #define                  FTESTDEC  0x1000     /* OTP/Fuse Test Decoder */
-#define                 nFTESTDEC  0x0       
 #define                   FWRTEST  0x2000     /* OTP/Fuse Write Test */
-#define                  nFWRTEST  0x0       
 #define                     FRDEN  0x4000     /* OTP/Fuse Read Enable */
-#define                    nFRDEN  0x0       
 #define                     FWREN  0x8000     /* OTP/Fuse Write Enable */
-#define                    nFWREN  0x0       
 
 /* Bit masks for OTP_BEN */
 
 /* Bit masks for OTP_STATUS */
 
 #define                     FCOMP  0x1        /* OTP/Fuse Access Complete */
-#define                    nFCOMP  0x0       
 #define                    FERROR  0x2        /* OTP/Fuse Access Error */
-#define                   nFERROR  0x0       
 #define                  MMRGLOAD  0x10       /* Memory Mapped Register Gasket Load */
-#define                 nMMRGLOAD  0x0       
 #define                  MMRGLOCK  0x20       /* Memory Mapped Register Gasket Lock */
-#define                 nMMRGLOCK  0x0       
 #define                    FPGMEN  0x40       /* OTP/Fuse Program Enable */
-#define                   nFPGMEN  0x0       
 
 /* Bit masks for OTP_TIMING */
 
 /* Bit masks for SECURE_SYSSWT */
 
 #define                   EMUDABL  0x1        /* Emulation Disable. */
-#define                  nEMUDABL  0x0       
 #define                   RSTDABL  0x2        /* Reset Disable */
-#define                  nRSTDABL  0x0       
 #define                   L1IDABL  0x1c       /* L1 Instruction Memory Disable. */
 #define                  L1DADABL  0xe0       /* L1 Data Bank A Memory Disable. */
 #define                  L1DBDABL  0x700      /* L1 Data Bank B Memory Disable. */
 #define                   DMA0OVR  0x800      /* DMA0 Memory Access Override */
-#define                  nDMA0OVR  0x0       
 #define                   DMA1OVR  0x1000     /* DMA1 Memory Access Override */
-#define                  nDMA1OVR  0x0       
 #define                    EMUOVR  0x4000     /* Emulation Override */
-#define                   nEMUOVR  0x0       
 #define                    OTPSEN  0x8000     /* OTP Secrets Enable. */
-#define                   nOTPSEN  0x0       
 #define                    L2DABL  0x70000    /* L2 Memory Disable. */
 
 /* Bit masks for SECURE_CONTROL */
 
 #define                   SECURE0  0x1        /* SECURE 0 */
-#define                  nSECURE0  0x0       
 #define                   SECURE1  0x2        /* SECURE 1 */
-#define                  nSECURE1  0x0       
 #define                   SECURE2  0x4        /* SECURE 2 */
-#define                  nSECURE2  0x0       
 #define                   SECURE3  0x8        /* SECURE 3 */
-#define                  nSECURE3  0x0       
 
 /* Bit masks for SECURE_STATUS */
 
 #define                   SECMODE  0x3        /* Secured Mode Control State */
 #define                       NMI  0x4        /* Non Maskable Interrupt */
-#define                      nNMI  0x0       
 #define                   AFVALID  0x8        /* Authentication Firmware Valid */
-#define                  nAFVALID  0x0       
 #define                    AFEXIT  0x10       /* Authentication Firmware Exit */
-#define                   nAFEXIT  0x0       
 #define                   SECSTAT  0xe0       /* Secure Status */
 
 /* Bit masks for PLL_DIV */
 
 #define                      MSEL  0x7e00     /* Multiplier Select */
 #define                    BYPASS  0x100      /* PLL Bypass Enable */
-#define                   nBYPASS  0x0       
 #define              OUTPUT_DELAY  0x80       /* External Memory Output Delay Enable */
-#define             nOUTPUT_DELAY  0x0       
 #define               INPUT_DELAY  0x40       /* External Memory Input Delay Enable */
-#define              nINPUT_DELAY  0x0       
 #define                      PDWN  0x20       /* Power Down */
-#define                     nPDWN  0x0       
 #define                    STOPCK  0x8        /* Stop Clock */
-#define                   nSTOPCK  0x0       
 #define                   PLL_OFF  0x2        /* Disable PLL */
-#define                  nPLL_OFF  0x0       
 #define                        DF  0x1        /* Divide Frequency */
-#define                       nDF  0x0       
 
 /* Bit masks for PLL_STAT */
 
 #define                PLL_LOCKED  0x20       /* PLL Locked Status */
-#define               nPLL_LOCKED  0x0       
 #define        ACTIVE_PLLDISABLED  0x4        /* Active Mode With PLL Disabled */
-#define       nACTIVE_PLLDISABLED  0x0       
 #define                   FULL_ON  0x2        /* Full-On Mode */
-#define                  nFULL_ON  0x0       
 #define         ACTIVE_PLLENABLED  0x1        /* Active Mode With PLL Enabled */
-#define        nACTIVE_PLLENABLED  0x0       
 #define                     RTCWS  0x400      /* RTC/Reset Wake-Up Status */
-#define                    nRTCWS  0x0       
 #define                     CANWS  0x800      /* CAN Wake-Up Status */
-#define                    nCANWS  0x0       
 #define                     USBWS  0x2000     /* USB Wake-Up Status */
-#define                    nUSBWS  0x0       
 #define                    KPADWS  0x4000     /* Keypad Wake-Up Status */
-#define                   nKPADWS  0x0       
 #define                     ROTWS  0x8000     /* Rotary Wake-Up Status */
-#define                    nROTWS  0x0       
 #define                      GPWS  0x1000     /* General-Purpose Wake-Up Status */
-#define                     nGPWS  0x0       
 
 /* Bit masks for VR_CTL */
 
 #define                      GAIN  0xc        /* Voltage Output Level Gain */
 #define                      VLEV  0xf0       /* Internal Voltage Level */
 #define                   SCKELOW  0x8000     /* Drive SCKE Low During Reset Enable */
-#define                  nSCKELOW  0x0       
 #define                      WAKE  0x100      /* RTC/Reset Wake-Up Enable */
-#define                     nWAKE  0x0       
 #define                     CANWE  0x200      /* CAN0/1 Wake-Up Enable */
-#define                    nCANWE  0x0       
 #define                      GPWE  0x400      /* General-Purpose Wake-Up Enable */
-#define                     nGPWE  0x0       
 #define                     USBWE  0x800      /* USB Wake-Up Enable */
-#define                    nUSBWE  0x0       
 #define                    KPADWE  0x1000     /* Keypad Wake-Up Enable */
-#define                   nKPADWE  0x0       
 #define                     ROTWE  0x2000     /* Rotary Wake-Up Enable */
-#define                    nROTWE  0x0       
 
 /* Bit masks for NFC_CTL */
 
 #define                    WR_DLY  0xf        /* Write Strobe Delay */
 #define                    RD_DLY  0xf0       /* Read Strobe Delay */
 #define                    NWIDTH  0x100      /* NAND Data Width */
-#define                   nNWIDTH  0x0       
 #define                   PG_SIZE  0x200      /* Page Size */
-#define                  nPG_SIZE  0x0       
 
 /* Bit masks for NFC_STAT */
 
 #define                     NBUSY  0x1        /* Not Busy */
-#define                    nNBUSY  0x0       
 #define                   WB_FULL  0x2        /* Write Buffer Full */
-#define                  nWB_FULL  0x0       
 #define                PG_WR_STAT  0x4        /* Page Write Pending */
-#define               nPG_WR_STAT  0x0       
 #define                PG_RD_STAT  0x8        /* Page Read Pending */
-#define               nPG_RD_STAT  0x0       
 #define                  WB_EMPTY  0x10       /* Write Buffer Empty */
-#define                 nWB_EMPTY  0x0       
 
 /* Bit masks for NFC_IRQSTAT */
 
 #define                  NBUSYIRQ  0x1        /* Not Busy IRQ */
-#define                 nNBUSYIRQ  0x0       
 #define                    WB_OVF  0x2        /* Write Buffer Overflow */
-#define                   nWB_OVF  0x0       
 #define                   WB_EDGE  0x4        /* Write Buffer Edge Detect */
-#define                  nWB_EDGE  0x0       
 #define                    RD_RDY  0x8        /* Read Data Ready */
-#define                   nRD_RDY  0x0       
 #define                   WR_DONE  0x10       /* Page Write Done */
-#define                  nWR_DONE  0x0       
 
 /* Bit masks for NFC_IRQMASK */
 
 #define              MASK_BUSYIRQ  0x1        /* Mask Not Busy IRQ */
-#define             nMASK_BUSYIRQ  0x0       
 #define                MASK_WBOVF  0x2        /* Mask Write Buffer Overflow */
-#define               nMASK_WBOVF  0x0       
 #define              MASK_WBEMPTY  0x4        /* Mask Write Buffer Empty */
-#define             nMASK_WBEMPTY  0x0       
 #define                MASK_RDRDY  0x8        /* Mask Read Data Ready */
-#define               nMASK_RDRDY  0x0       
 #define               MASK_WRDONE  0x10       /* Mask Write Done */
-#define              nMASK_WRDONE  0x0       
 
 /* Bit masks for NFC_RST */
 
 #define                   ECC_RST  0x1        /* ECC (and NFC counters) Reset */
-#define                  nECC_RST  0x0       
 
 /* Bit masks for NFC_PGCTL */
 
 #define               PG_RD_START  0x1        /* Page Read Start */
-#define              nPG_RD_START  0x0       
 #define               PG_WR_START  0x2        /* Page Write Start */
-#define              nPG_WR_START  0x0       
 
 /* Bit masks for NFC_ECC0 */
 
 /* Bit masks for CAN0_CONTROL */
 
 #define                       SRS  0x1        /* Software Reset */
-#define                      nSRS  0x0       
 #define                       DNM  0x2        /* DeviceNet Mode */
-#define                      nDNM  0x0       
 #define                       ABO  0x4        /* Auto Bus On */
-#define                      nABO  0x0       
 #define                       WBA  0x10       /* Wakeup On CAN Bus Activity */
-#define                      nWBA  0x0       
 #define                       SMR  0x20       /* Sleep Mode Request */
-#define                      nSMR  0x0       
 #define                       CSR  0x40       /* CAN Suspend Mode Request */
-#define                      nCSR  0x0       
 #define                       CCR  0x80       /* CAN Configuration Mode Request */
-#define                      nCCR  0x0       
 
 /* Bit masks for CAN0_STATUS */
 
 #define                        WT  0x1        /* CAN Transmit Warning Flag */
-#define                       nWT  0x0       
 #define                        WR  0x2        /* CAN Receive Warning Flag */
-#define                       nWR  0x0       
 #define                        EP  0x4        /* CAN Error Passive Mode */
-#define                       nEP  0x0       
 #define                       EBO  0x8        /* CAN Error Bus Off Mode */
-#define                      nEBO  0x0       
 #define                       CSA  0x40       /* CAN Suspend Mode Acknowledge */
-#define                      nCSA  0x0       
 #define                       CCA  0x80       /* CAN Configuration Mode Acknowledge */
-#define                      nCCA  0x0       
 #define                     MBPTR  0x1f00     /* Mailbox Pointer */
 #define                       TRM  0x4000     /* Transmit Mode Status */
-#define                      nTRM  0x0       
 #define                       REC  0x8000     /* Receive Mode Status */
-#define                      nREC  0x0       
 
 /* Bit masks for CAN0_DEBUG */
 
 #define                       DEC  0x1        /* Disable Transmit/Receive Error Counters */
-#define                      nDEC  0x0       
 #define                       DRI  0x2        /* Disable CANRX Input Pin */
-#define                      nDRI  0x0       
 #define                       DTO  0x4        /* Disable CANTX Output Pin */
-#define                      nDTO  0x0       
 #define                       DIL  0x8        /* Disable Internal Loop */
-#define                      nDIL  0x0       
 #define                       MAA  0x10       /* Mode Auto-Acknowledge */
-#define                      nMAA  0x0       
 #define                       MRB  0x20       /* Mode Read Back */
-#define                      nMRB  0x0       
 #define                       CDE  0x8000     /* CAN Debug Mode Enable */
-#define                      nCDE  0x0       
 
 /* Bit masks for CAN0_CLOCK */
 
 
 #define                       SJW  0x300      /* Synchronization Jump Width */
 #define                       SAM  0x80       /* Sampling */
-#define                      nSAM  0x0       
 #define                     TSEG2  0x70       /* Time Segment 2 */
 #define                     TSEG1  0xf        /* Time Segment 1 */
 
 /* Bit masks for CAN0_INTR */
 
 #define                     CANRX  0x80       /* Serial Input From Transceiver */
-#define                    nCANRX  0x0       
 #define                     CANTX  0x40       /* Serial Output To Transceiver */
-#define                    nCANTX  0x0       
 #define                     SMACK  0x8        /* Sleep Mode Acknowledge */
-#define                    nSMACK  0x0       
 #define                      GIRQ  0x4        /* Global Interrupt Request Status */
-#define                     nGIRQ  0x0       
 #define                    MBTIRQ  0x2        /* Mailbox Transmit Interrupt Request */
-#define                   nMBTIRQ  0x0       
 #define                    MBRIRQ  0x1        /* Mailbox Receive Interrupt Request */
-#define                   nMBRIRQ  0x0       
 
 /* Bit masks for CAN0_GIM */
 
 #define                     EWTIM  0x1        /* Error Warning Transmit Interrupt Mask */
-#define                    nEWTIM  0x0       
 #define                     EWRIM  0x2        /* Error Warning Receive Interrupt Mask */
-#define                    nEWRIM  0x0       
 #define                      EPIM  0x4        /* Error Passive Interrupt Mask */
-#define                     nEPIM  0x0       
 #define                      BOIM  0x8        /* Bus Off Interrupt Mask */
-#define                     nBOIM  0x0       
 #define                      WUIM  0x10       /* Wakeup Interrupt Mask */
-#define                     nWUIM  0x0       
 #define                     UIAIM  0x20       /* Unimplemented Address Interrupt Mask */
-#define                    nUIAIM  0x0       
 #define                      AAIM  0x40       /* Abort Acknowledge Interrupt Mask */
-#define                     nAAIM  0x0       
 #define                     RMLIM  0x80       /* Receive Message Lost Interrupt Mask */
-#define                    nRMLIM  0x0       
 #define                     UCEIM  0x100      /* Universal Counter Exceeded Interrupt Mask */
-#define                    nUCEIM  0x0       
 #define                      ADIM  0x400      /* Access Denied Interrupt Mask */
-#define                     nADIM  0x0       
 
 /* Bit masks for CAN0_GIS */
 
 #define                     EWTIS  0x1        /* Error Warning Transmit Interrupt Status */
-#define                    nEWTIS  0x0       
 #define                     EWRIS  0x2        /* Error Warning Receive Interrupt Status */
-#define                    nEWRIS  0x0       
 #define                      EPIS  0x4        /* Error Passive Interrupt Status */
-#define                     nEPIS  0x0       
 #define                      BOIS  0x8        /* Bus Off Interrupt Status */
-#define                     nBOIS  0x0       
 #define                      WUIS  0x10       /* Wakeup Interrupt Status */
-#define                     nWUIS  0x0       
 #define                     UIAIS  0x20       /* Unimplemented Address Interrupt Status */
-#define                    nUIAIS  0x0       
 #define                      AAIS  0x40       /* Abort Acknowledge Interrupt Status */
-#define                     nAAIS  0x0       
 #define                     RMLIS  0x80       /* Receive Message Lost Interrupt Status */
-#define                    nRMLIS  0x0       
 #define                     UCEIS  0x100      /* Universal Counter Exceeded Interrupt Status */
-#define                    nUCEIS  0x0       
 #define                      ADIS  0x400      /* Access Denied Interrupt Status */
-#define                     nADIS  0x0       
 
 /* Bit masks for CAN0_GIF */
 
 #define                     EWTIF  0x1        /* Error Warning Transmit Interrupt Flag */
-#define                    nEWTIF  0x0       
 #define                     EWRIF  0x2        /* Error Warning Receive Interrupt Flag */
-#define                    nEWRIF  0x0       
 #define                      EPIF  0x4        /* Error Passive Interrupt Flag */
-#define                     nEPIF  0x0       
 #define                      BOIF  0x8        /* Bus Off Interrupt Flag */
-#define                     nBOIF  0x0       
 #define                      WUIF  0x10       /* Wakeup Interrupt Flag */
-#define                     nWUIF  0x0       
 #define                     UIAIF  0x20       /* Unimplemented Address Interrupt Flag */
-#define                    nUIAIF  0x0       
 #define                      AAIF  0x40       /* Abort Acknowledge Interrupt Flag */
-#define                     nAAIF  0x0       
 #define                     RMLIF  0x80       /* Receive Message Lost Interrupt Flag */
-#define                    nRMLIF  0x0       
 #define                     UCEIF  0x100      /* Universal Counter Exceeded Interrupt Flag */
-#define                    nUCEIF  0x0       
 #define                      ADIF  0x400      /* Access Denied Interrupt Flag */
-#define                     nADIF  0x0       
 
 /* Bit masks for CAN0_MBTD */
 
 #define                       TDR  0x80       /* Temporary Disable Request */
-#define                      nTDR  0x0       
 #define                       TDA  0x40       /* Temporary Disable Acknowledge */
-#define                      nTDA  0x0       
 #define                     TDPTR  0x1f       /* Temporary Disable Pointer */
 
 /* Bit masks for CAN0_UCCNF */
 
 #define                     UCCNF  0xf        /* Universal Counter Configuration */
 #define                      UCRC  0x20       /* Universal Counter Reload/Clear */
-#define                     nUCRC  0x0       
 #define                      UCCT  0x40       /* Universal Counter CAN Trigger */
-#define                     nUCCT  0x0       
 #define                       UCE  0x80       /* Universal Counter Enable */
-#define                      nUCE  0x0       
 
 /* Bit masks for CAN0_UCCNT */
 
 /* Bit masks for CAN0_ESR */
 
 #define                       FER  0x80       /* Form Error */
-#define                      nFER  0x0       
 #define                       BEF  0x40       /* Bit Error Flag */
-#define                      nBEF  0x0       
 #define                       SA0  0x20       /* Stuck At Dominant */
-#define                      nSA0  0x0       
 #define                      CRCE  0x10       /* CRC Error */
-#define                     nCRCE  0x0       
 #define                       SER  0x8        /* Stuff Bit Error */
-#define                      nSER  0x0       
 #define                      ACKE  0x4        /* Acknowledge Error */
-#define                     nACKE  0x0       
 
 /* Bit masks for CAN0_EWR */
 
 /* Bit masks for CAN0_AMxx_H */
 
 #define                       FDF  0x8000     /* Filter On Data Field */
-#define                      nFDF  0x0       
 #define                       FMD  0x4000     /* Full Mask Data */
-#define                      nFMD  0x0       
 #define                     AMIDE  0x2000     /* Acceptance Mask Identifier Extension */
-#define                    nAMIDE  0x0       
 #define                    BASEID  0x1ffc     /* Base Identifier */
 #define                  EXTID_HI  0x3        /* Extended Identifier High Bits */
 
 /* Bit masks for CAN0_MBxx_ID1 */
 
 #define                       AME  0x8000     /* Acceptance Mask Enable */
-#define                      nAME  0x0       
 #define                       RTR  0x4000     /* Remote Transmission Request */
-#define                      nRTR  0x0       
 #define                       IDE  0x2000     /* Identifier Extension */
-#define                      nIDE  0x0       
 #define                    BASEID  0x1ffc     /* Base Identifier */
 #define                  EXTID_HI  0x3        /* Extended Identifier High Bits */
 
 /* Bit masks for CAN0_MC1 */
 
 #define                       MC0  0x1        /* Mailbox 0 Enable */
-#define                      nMC0  0x0       
 #define                       MC1  0x2        /* Mailbox 1 Enable */
-#define                      nMC1  0x0       
 #define                       MC2  0x4        /* Mailbox 2 Enable */
-#define                      nMC2  0x0       
 #define                       MC3  0x8        /* Mailbox 3 Enable */
-#define                      nMC3  0x0       
 #define                       MC4  0x10       /* Mailbox 4 Enable */
-#define                      nMC4  0x0       
 #define                       MC5  0x20       /* Mailbox 5 Enable */
-#define                      nMC5  0x0       
 #define                       MC6  0x40       /* Mailbox 6 Enable */
-#define                      nMC6  0x0       
 #define                       MC7  0x80       /* Mailbox 7 Enable */
-#define                      nMC7  0x0       
 #define                       MC8  0x100      /* Mailbox 8 Enable */
-#define                      nMC8  0x0       
 #define                       MC9  0x200      /* Mailbox 9 Enable */
-#define                      nMC9  0x0       
 #define                      MC10  0x400      /* Mailbox 10 Enable */
-#define                     nMC10  0x0       
 #define                      MC11  0x800      /* Mailbox 11 Enable */
-#define                     nMC11  0x0       
 #define                      MC12  0x1000     /* Mailbox 12 Enable */
-#define                     nMC12  0x0       
 #define                      MC13  0x2000     /* Mailbox 13 Enable */
-#define                     nMC13  0x0       
 #define                      MC14  0x4000     /* Mailbox 14 Enable */
-#define                     nMC14  0x0       
 #define                      MC15  0x8000     /* Mailbox 15 Enable */
-#define                     nMC15  0x0       
 
 /* Bit masks for CAN0_MC2 */
 
 #define                      MC16  0x1        /* Mailbox 16 Enable */
-#define                     nMC16  0x0       
 #define                      MC17  0x2        /* Mailbox 17 Enable */
-#define                     nMC17  0x0       
 #define                      MC18  0x4        /* Mailbox 18 Enable */
-#define                     nMC18  0x0       
 #define                      MC19  0x8        /* Mailbox 19 Enable */
-#define                     nMC19  0x0       
 #define                      MC20  0x10       /* Mailbox 20 Enable */
-#define                     nMC20  0x0       
 #define                      MC21  0x20       /* Mailbox 21 Enable */
-#define                     nMC21  0x0       
 #define                      MC22  0x40       /* Mailbox 22 Enable */
-#define                     nMC22  0x0       
 #define                      MC23  0x80       /* Mailbox 23 Enable */
-#define                     nMC23  0x0       
 #define                      MC24  0x100      /* Mailbox 24 Enable */
-#define                     nMC24  0x0       
 #define                      MC25  0x200      /* Mailbox 25 Enable */
-#define                     nMC25  0x0       
 #define                      MC26  0x400      /* Mailbox 26 Enable */
-#define                     nMC26  0x0       
 #define                      MC27  0x800      /* Mailbox 27 Enable */
-#define                     nMC27  0x0       
 #define                      MC28  0x1000     /* Mailbox 28 Enable */
-#define                     nMC28  0x0       
 #define                      MC29  0x2000     /* Mailbox 29 Enable */
-#define                     nMC29  0x0       
 #define                      MC30  0x4000     /* Mailbox 30 Enable */
-#define                     nMC30  0x0       
 #define                      MC31  0x8000     /* Mailbox 31 Enable */
-#define                     nMC31  0x0       
 
 /* Bit masks for CAN0_MD1 */
 
 #define                       MD0  0x1        /* Mailbox 0 Receive Enable */
-#define                      nMD0  0x0       
 #define                       MD1  0x2        /* Mailbox 1 Receive Enable */
-#define                      nMD1  0x0       
 #define                       MD2  0x4        /* Mailbox 2 Receive Enable */
-#define                      nMD2  0x0       
 #define                       MD3  0x8        /* Mailbox 3 Receive Enable */
-#define                      nMD3  0x0       
 #define                       MD4  0x10       /* Mailbox 4 Receive Enable */
-#define                      nMD4  0x0       
 #define                       MD5  0x20       /* Mailbox 5 Receive Enable */
-#define                      nMD5  0x0       
 #define                       MD6  0x40       /* Mailbox 6 Receive Enable */
-#define                      nMD6  0x0       
 #define                       MD7  0x80       /* Mailbox 7 Receive Enable */
-#define                      nMD7  0x0       
 #define                       MD8  0x100      /* Mailbox 8 Receive Enable */
-#define                      nMD8  0x0       
 #define                       MD9  0x200      /* Mailbox 9 Receive Enable */
-#define                      nMD9  0x0       
 #define                      MD10  0x400      /* Mailbox 10 Receive Enable */
-#define                     nMD10  0x0       
 #define                      MD11  0x800      /* Mailbox 11 Receive Enable */
-#define                     nMD11  0x0       
 #define                      MD12  0x1000     /* Mailbox 12 Receive Enable */
-#define                     nMD12  0x0       
 #define                      MD13  0x2000     /* Mailbox 13 Receive Enable */
-#define                     nMD13  0x0       
 #define                      MD14  0x4000     /* Mailbox 14 Receive Enable */
-#define                     nMD14  0x0       
 #define                      MD15  0x8000     /* Mailbox 15 Receive Enable */
-#define                     nMD15  0x0       
 
 /* Bit masks for CAN0_MD2 */
 
 #define                      MD16  0x1        /* Mailbox 16 Receive Enable */
-#define                     nMD16  0x0       
 #define                      MD17  0x2        /* Mailbox 17 Receive Enable */
-#define                     nMD17  0x0       
 #define                      MD18  0x4        /* Mailbox 18 Receive Enable */
-#define                     nMD18  0x0       
 #define                      MD19  0x8        /* Mailbox 19 Receive Enable */
-#define                     nMD19  0x0       
 #define                      MD20  0x10       /* Mailbox 20 Receive Enable */
-#define                     nMD20  0x0       
 #define                      MD21  0x20       /* Mailbox 21 Receive Enable */
-#define                     nMD21  0x0       
 #define                      MD22  0x40       /* Mailbox 22 Receive Enable */
-#define                     nMD22  0x0       
 #define                      MD23  0x80       /* Mailbox 23 Receive Enable */
-#define                     nMD23  0x0       
 #define                      MD24  0x100      /* Mailbox 24 Receive Enable */
-#define                     nMD24  0x0       
 #define                      MD25  0x200      /* Mailbox 25 Receive Enable */
-#define                     nMD25  0x0       
 #define                      MD26  0x400      /* Mailbox 26 Receive Enable */
-#define                     nMD26  0x0       
 #define                      MD27  0x800      /* Mailbox 27 Receive Enable */
-#define                     nMD27  0x0       
 #define                      MD28  0x1000     /* Mailbox 28 Receive Enable */
-#define                     nMD28  0x0       
 #define                      MD29  0x2000     /* Mailbox 29 Receive Enable */
-#define                     nMD29  0x0       
 #define                      MD30  0x4000     /* Mailbox 30 Receive Enable */
-#define                     nMD30  0x0       
 #define                      MD31  0x8000     /* Mailbox 31 Receive Enable */
-#define                     nMD31  0x0       
 
 /* Bit masks for CAN0_RMP1 */
 
 #define                      RMP0  0x1        /* Mailbox 0 Receive Message Pending */
-#define                     nRMP0  0x0       
 #define                      RMP1  0x2        /* Mailbox 1 Receive Message Pending */
-#define                     nRMP1  0x0       
 #define                      RMP2  0x4        /* Mailbox 2 Receive Message Pending */
-#define                     nRMP2  0x0       
 #define                      RMP3  0x8        /* Mailbox 3 Receive Message Pending */
-#define                     nRMP3  0x0       
 #define                      RMP4  0x10       /* Mailbox 4 Receive Message Pending */
-#define                     nRMP4  0x0       
 #define                      RMP5  0x20       /* Mailbox 5 Receive Message Pending */
-#define                     nRMP5  0x0       
 #define                      RMP6  0x40       /* Mailbox 6 Receive Message Pending */
-#define                     nRMP6  0x0       
 #define                      RMP7  0x80       /* Mailbox 7 Receive Message Pending */
-#define                     nRMP7  0x0       
 #define                      RMP8  0x100      /* Mailbox 8 Receive Message Pending */
-#define                     nRMP8  0x0       
 #define                      RMP9  0x200      /* Mailbox 9 Receive Message Pending */
-#define                     nRMP9  0x0       
 #define                     RMP10  0x400      /* Mailbox 10 Receive Message Pending */
-#define                    nRMP10  0x0       
 #define                     RMP11  0x800      /* Mailbox 11 Receive Message Pending */
-#define                    nRMP11  0x0       
 #define                     RMP12  0x1000     /* Mailbox 12 Receive Message Pending */
-#define                    nRMP12  0x0       
 #define                     RMP13  0x2000     /* Mailbox 13 Receive Message Pending */
-#define                    nRMP13  0x0       
 #define                     RMP14  0x4000     /* Mailbox 14 Receive Message Pending */
-#define                    nRMP14  0x0       
 #define                     RMP15  0x8000     /* Mailbox 15 Receive Message Pending */
-#define                    nRMP15  0x0       
 
 /* Bit masks for CAN0_RMP2 */
 
 #define                     RMP16  0x1        /* Mailbox 16 Receive Message Pending */
-#define                    nRMP16  0x0       
 #define                     RMP17  0x2        /* Mailbox 17 Receive Message Pending */
-#define                    nRMP17  0x0       
 #define                     RMP18  0x4        /* Mailbox 18 Receive Message Pending */
-#define                    nRMP18  0x0       
 #define                     RMP19  0x8        /* Mailbox 19 Receive Message Pending */
-#define                    nRMP19  0x0       
 #define                     RMP20  0x10       /* Mailbox 20 Receive Message Pending */
-#define                    nRMP20  0x0       
 #define                     RMP21  0x20       /* Mailbox 21 Receive Message Pending */
-#define                    nRMP21  0x0       
 #define                     RMP22  0x40       /* Mailbox 22 Receive Message Pending */
-#define                    nRMP22  0x0       
 #define                     RMP23  0x80       /* Mailbox 23 Receive Message Pending */
-#define                    nRMP23  0x0       
 #define                     RMP24  0x100      /* Mailbox 24 Receive Message Pending */
-#define                    nRMP24  0x0       
 #define                     RMP25  0x200      /* Mailbox 25 Receive Message Pending */
-#define                    nRMP25  0x0       
 #define                     RMP26  0x400      /* Mailbox 26 Receive Message Pending */
-#define                    nRMP26  0x0       
 #define                     RMP27  0x800      /* Mailbox 27 Receive Message Pending */
-#define                    nRMP27  0x0       
 #define                     RMP28  0x1000     /* Mailbox 28 Receive Message Pending */
-#define                    nRMP28  0x0       
 #define                     RMP29  0x2000     /* Mailbox 29 Receive Message Pending */
-#define                    nRMP29  0x0       
 #define                     RMP30  0x4000     /* Mailbox 30 Receive Message Pending */
-#define                    nRMP30  0x0       
 #define                     RMP31  0x8000     /* Mailbox 31 Receive Message Pending */
-#define                    nRMP31  0x0       
 
 /* Bit masks for CAN0_RML1 */
 
 #define                      RML0  0x1        /* Mailbox 0 Receive Message Lost */
-#define                     nRML0  0x0       
 #define                      RML1  0x2        /* Mailbox 1 Receive Message Lost */
-#define                     nRML1  0x0       
 #define                      RML2  0x4        /* Mailbox 2 Receive Message Lost */
-#define                     nRML2  0x0       
 #define                      RML3  0x8        /* Mailbox 3 Receive Message Lost */
-#define                     nRML3  0x0       
 #define                      RML4  0x10       /* Mailbox 4 Receive Message Lost */
-#define                     nRML4  0x0       
 #define                      RML5  0x20       /* Mailbox 5 Receive Message Lost */
-#define                     nRML5  0x0       
 #define                      RML6  0x40       /* Mailbox 6 Receive Message Lost */
-#define                     nRML6  0x0       
 #define                      RML7  0x80       /* Mailbox 7 Receive Message Lost */
-#define                     nRML7  0x0       
 #define                      RML8  0x100      /* Mailbox 8 Receive Message Lost */
-#define                     nRML8  0x0       
 #define                      RML9  0x200      /* Mailbox 9 Receive Message Lost */
-#define                     nRML9  0x0       
 #define                     RML10  0x400      /* Mailbox 10 Receive Message Lost */
-#define                    nRML10  0x0       
 #define                     RML11  0x800      /* Mailbox 11 Receive Message Lost */
-#define                    nRML11  0x0       
 #define                     RML12  0x1000     /* Mailbox 12 Receive Message Lost */
-#define                    nRML12  0x0       
 #define                     RML13  0x2000     /* Mailbox 13 Receive Message Lost */
-#define                    nRML13  0x0       
 #define                     RML14  0x4000     /* Mailbox 14 Receive Message Lost */
-#define                    nRML14  0x0       
 #define                     RML15  0x8000     /* Mailbox 15 Receive Message Lost */
-#define                    nRML15  0x0       
 
 /* Bit masks for CAN0_RML2 */
 
 #define                     RML16  0x1        /* Mailbox 16 Receive Message Lost */
-#define                    nRML16  0x0       
 #define                     RML17  0x2        /* Mailbox 17 Receive Message Lost */
-#define                    nRML17  0x0       
 #define                     RML18  0x4        /* Mailbox 18 Receive Message Lost */
-#define                    nRML18  0x0       
 #define                     RML19  0x8        /* Mailbox 19 Receive Message Lost */
-#define                    nRML19  0x0       
 #define                     RML20  0x10       /* Mailbox 20 Receive Message Lost */
-#define                    nRML20  0x0       
 #define                     RML21  0x20       /* Mailbox 21 Receive Message Lost */
-#define                    nRML21  0x0       
 #define                     RML22  0x40       /* Mailbox 22 Receive Message Lost */
-#define                    nRML22  0x0       
 #define                     RML23  0x80       /* Mailbox 23 Receive Message Lost */
-#define                    nRML23  0x0       
 #define                     RML24  0x100      /* Mailbox 24 Receive Message Lost */
-#define                    nRML24  0x0       
 #define                     RML25  0x200      /* Mailbox 25 Receive Message Lost */
-#define                    nRML25  0x0       
 #define                     RML26  0x400      /* Mailbox 26 Receive Message Lost */
-#define                    nRML26  0x0       
 #define                     RML27  0x800      /* Mailbox 27 Receive Message Lost */
-#define                    nRML27  0x0       
 #define                     RML28  0x1000     /* Mailbox 28 Receive Message Lost */
-#define                    nRML28  0x0       
 #define                     RML29  0x2000     /* Mailbox 29 Receive Message Lost */
-#define                    nRML29  0x0       
 #define                     RML30  0x4000     /* Mailbox 30 Receive Message Lost */
-#define                    nRML30  0x0       
 #define                     RML31  0x8000     /* Mailbox 31 Receive Message Lost */
-#define                    nRML31  0x0       
 
 /* Bit masks for CAN0_OPSS1 */
 
 #define                     OPSS0  0x1        /* Mailbox 0 Overwrite Protection/Single-Shot Transmission Enable */
-#define                    nOPSS0  0x0       
 #define                     OPSS1  0x2        /* Mailbox 1 Overwrite Protection/Single-Shot Transmission Enable */
-#define                    nOPSS1  0x0       
 #define                     OPSS2  0x4        /* Mailbox 2 Overwrite Protection/Single-Shot Transmission Enable */
-#define                    nOPSS2  0x0       
 #define                     OPSS3  0x8        /* Mailbox 3 Overwrite Protection/Single-Shot Transmission Enable */
-#define                    nOPSS3  0x0       
 #define                     OPSS4  0x10       /* Mailbox 4 Overwrite Protection/Single-Shot Transmission Enable */
-#define                    nOPSS4  0x0       
 #define                     OPSS5  0x20       /* Mailbox 5 Overwrite Protection/Single-Shot Transmission Enable */
-#define                    nOPSS5  0x0       
 #define                     OPSS6  0x40       /* Mailbox 6 Overwrite Protection/Single-Shot Transmission Enable */
-#define                    nOPSS6  0x0       
 #define                     OPSS7  0x80       /* Mailbox 7 Overwrite Protection/Single-Shot Transmission Enable */
-#define                    nOPSS7  0x0       
 #define                     OPSS8  0x100      /* Mailbox 8 Overwrite Protection/Single-Shot Transmission Enable */
-#define                    nOPSS8  0x0       
 #define                     OPSS9  0x200      /* Mailbox 9 Overwrite Protection/Single-Shot Transmission Enable */
-#define                    nOPSS9  0x0       
 #define                    OPSS10  0x400      /* Mailbox 10 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS10  0x0       
 #define                    OPSS11  0x800      /* Mailbox 11 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS11  0x0       
 #define                    OPSS12  0x1000     /* Mailbox 12 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS12  0x0       
 #define                    OPSS13  0x2000     /* Mailbox 13 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS13  0x0       
 #define                    OPSS14  0x4000     /* Mailbox 14 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS14  0x0       
 #define                    OPSS15  0x8000     /* Mailbox 15 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS15  0x0       
 
 /* Bit masks for CAN0_OPSS2 */
 
 #define                    OPSS16  0x1        /* Mailbox 16 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS16  0x0       
 #define                    OPSS17  0x2        /* Mailbox 17 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS17  0x0       
 #define                    OPSS18  0x4        /* Mailbox 18 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS18  0x0       
 #define                    OPSS19  0x8        /* Mailbox 19 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS19  0x0       
 #define                    OPSS20  0x10       /* Mailbox 20 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS20  0x0       
 #define                    OPSS21  0x20       /* Mailbox 21 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS21  0x0       
 #define                    OPSS22  0x40       /* Mailbox 22 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS22  0x0       
 #define                    OPSS23  0x80       /* Mailbox 23 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS23  0x0       
 #define                    OPSS24  0x100      /* Mailbox 24 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS24  0x0       
 #define                    OPSS25  0x200      /* Mailbox 25 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS25  0x0       
 #define                    OPSS26  0x400      /* Mailbox 26 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS26  0x0       
 #define                    OPSS27  0x800      /* Mailbox 27 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS27  0x0       
 #define                    OPSS28  0x1000     /* Mailbox 28 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS28  0x0       
 #define                    OPSS29  0x2000     /* Mailbox 29 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS29  0x0       
 #define                    OPSS30  0x4000     /* Mailbox 30 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS30  0x0       
 #define                    OPSS31  0x8000     /* Mailbox 31 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS31  0x0       
 
 /* Bit masks for CAN0_TRS1 */
 
 #define                      TRS0  0x1        /* Mailbox 0 Transmit Request Set */
-#define                     nTRS0  0x0       
 #define                      TRS1  0x2        /* Mailbox 1 Transmit Request Set */
-#define                     nTRS1  0x0       
 #define                      TRS2  0x4        /* Mailbox 2 Transmit Request Set */
-#define                     nTRS2  0x0       
 #define                      TRS3  0x8        /* Mailbox 3 Transmit Request Set */
-#define                     nTRS3  0x0       
 #define                      TRS4  0x10       /* Mailbox 4 Transmit Request Set */
-#define                     nTRS4  0x0       
 #define                      TRS5  0x20       /* Mailbox 5 Transmit Request Set */
-#define                     nTRS5  0x0       
 #define                      TRS6  0x40       /* Mailbox 6 Transmit Request Set */
-#define                     nTRS6  0x0       
 #define                      TRS7  0x80       /* Mailbox 7 Transmit Request Set */
-#define                     nTRS7  0x0       
 #define                      TRS8  0x100      /* Mailbox 8 Transmit Request Set */
-#define                     nTRS8  0x0       
 #define                      TRS9  0x200      /* Mailbox 9 Transmit Request Set */
-#define                     nTRS9  0x0       
 #define                     TRS10  0x400      /* Mailbox 10 Transmit Request Set */
-#define                    nTRS10  0x0       
 #define                     TRS11  0x800      /* Mailbox 11 Transmit Request Set */
-#define                    nTRS11  0x0       
 #define                     TRS12  0x1000     /* Mailbox 12 Transmit Request Set */
-#define                    nTRS12  0x0       
 #define                     TRS13  0x2000     /* Mailbox 13 Transmit Request Set */
-#define                    nTRS13  0x0       
 #define                     TRS14  0x4000     /* Mailbox 14 Transmit Request Set */
-#define                    nTRS14  0x0       
 #define                     TRS15  0x8000     /* Mailbox 15 Transmit Request Set */
-#define                    nTRS15  0x0       
 
 /* Bit masks for CAN0_TRS2 */
 
 #define                     TRS16  0x1        /* Mailbox 16 Transmit Request Set */
-#define                    nTRS16  0x0       
 #define                     TRS17  0x2        /* Mailbox 17 Transmit Request Set */
-#define                    nTRS17  0x0       
 #define                     TRS18  0x4        /* Mailbox 18 Transmit Request Set */
-#define                    nTRS18  0x0       
 #define                     TRS19  0x8        /* Mailbox 19 Transmit Request Set */
-#define                    nTRS19  0x0       
 #define                     TRS20  0x10       /* Mailbox 20 Transmit Request Set */
-#define                    nTRS20  0x0       
 #define                     TRS21  0x20       /* Mailbox 21 Transmit Request Set */
-#define                    nTRS21  0x0       
 #define                     TRS22  0x40       /* Mailbox 22 Transmit Request Set */
-#define                    nTRS22  0x0       
 #define                     TRS23  0x80       /* Mailbox 23 Transmit Request Set */
-#define                    nTRS23  0x0       
 #define                     TRS24  0x100      /* Mailbox 24 Transmit Request Set */
-#define                    nTRS24  0x0       
 #define                     TRS25  0x200      /* Mailbox 25 Transmit Request Set */
-#define                    nTRS25  0x0       
 #define                     TRS26  0x400      /* Mailbox 26 Transmit Request Set */
-#define                    nTRS26  0x0       
 #define                     TRS27  0x800      /* Mailbox 27 Transmit Request Set */
-#define                    nTRS27  0x0       
 #define                     TRS28  0x1000     /* Mailbox 28 Transmit Request Set */
-#define                    nTRS28  0x0       
 #define                     TRS29  0x2000     /* Mailbox 29 Transmit Request Set */
-#define                    nTRS29  0x0       
 #define                     TRS30  0x4000     /* Mailbox 30 Transmit Request Set */
-#define                    nTRS30  0x0       
 #define                     TRS31  0x8000     /* Mailbox 31 Transmit Request Set */
-#define                    nTRS31  0x0       
 
 /* Bit masks for CAN0_TRR1 */
 
 #define                      TRR0  0x1        /* Mailbox 0 Transmit Request Reset */
-#define                     nTRR0  0x0       
 #define                      TRR1  0x2        /* Mailbox 1 Transmit Request Reset */
-#define                     nTRR1  0x0       
 #define                      TRR2  0x4        /* Mailbox 2 Transmit Request Reset */
-#define                     nTRR2  0x0       
 #define                      TRR3  0x8        /* Mailbox 3 Transmit Request Reset */
-#define                     nTRR3  0x0       
 #define                      TRR4  0x10       /* Mailbox 4 Transmit Request Reset */
-#define                     nTRR4  0x0       
 #define                      TRR5  0x20       /* Mailbox 5 Transmit Request Reset */
-#define                     nTRR5  0x0       
 #define                      TRR6  0x40       /* Mailbox 6 Transmit Request Reset */
-#define                     nTRR6  0x0       
 #define                      TRR7  0x80       /* Mailbox 7 Transmit Request Reset */
-#define                     nTRR7  0x0       
 #define                      TRR8  0x100      /* Mailbox 8 Transmit Request Reset */
-#define                     nTRR8  0x0       
 #define                      TRR9  0x200      /* Mailbox 9 Transmit Request Reset */
-#define                     nTRR9  0x0       
 #define                     TRR10  0x400      /* Mailbox 10 Transmit Request Reset */
-#define                    nTRR10  0x0       
 #define                     TRR11  0x800      /* Mailbox 11 Transmit Request Reset */
-#define                    nTRR11  0x0       
 #define                     TRR12  0x1000     /* Mailbox 12 Transmit Request Reset */
-#define                    nTRR12  0x0       
 #define                     TRR13  0x2000     /* Mailbox 13 Transmit Request Reset */
-#define                    nTRR13  0x0       
 #define                     TRR14  0x4000     /* Mailbox 14 Transmit Request Reset */
-#define                    nTRR14  0x0       
 #define                     TRR15  0x8000     /* Mailbox 15 Transmit Request Reset */
-#define                    nTRR15  0x0       
 
 /* Bit masks for CAN0_TRR2 */
 
 #define                     TRR16  0x1        /* Mailbox 16 Transmit Request Reset */
-#define                    nTRR16  0x0       
 #define                     TRR17  0x2        /* Mailbox 17 Transmit Request Reset */
-#define                    nTRR17  0x0       
 #define                     TRR18  0x4        /* Mailbox 18 Transmit Request Reset */
-#define                    nTRR18  0x0       
 #define                     TRR19  0x8        /* Mailbox 19 Transmit Request Reset */
-#define                    nTRR19  0x0       
 #define                     TRR20  0x10       /* Mailbox 20 Transmit Request Reset */
-#define                    nTRR20  0x0       
 #define                     TRR21  0x20       /* Mailbox 21 Transmit Request Reset */
-#define                    nTRR21  0x0       
 #define                     TRR22  0x40       /* Mailbox 22 Transmit Request Reset */
-#define                    nTRR22  0x0       
 #define                     TRR23  0x80       /* Mailbox 23 Transmit Request Reset */
-#define                    nTRR23  0x0       
 #define                     TRR24  0x100      /* Mailbox 24 Transmit Request Reset */
-#define                    nTRR24  0x0       
 #define                     TRR25  0x200      /* Mailbox 25 Transmit Request Reset */
-#define                    nTRR25  0x0       
 #define                     TRR26  0x400      /* Mailbox 26 Transmit Request Reset */
-#define                    nTRR26  0x0       
 #define                     TRR27  0x800      /* Mailbox 27 Transmit Request Reset */
-#define                    nTRR27  0x0       
 #define                     TRR28  0x1000     /* Mailbox 28 Transmit Request Reset */
-#define                    nTRR28  0x0       
 #define                     TRR29  0x2000     /* Mailbox 29 Transmit Request Reset */
-#define                    nTRR29  0x0       
 #define                     TRR30  0x4000     /* Mailbox 30 Transmit Request Reset */
-#define                    nTRR30  0x0       
 #define                     TRR31  0x8000     /* Mailbox 31 Transmit Request Reset */
-#define                    nTRR31  0x0       
 
 /* Bit masks for CAN0_AA1 */
 
 #define                       AA0  0x1        /* Mailbox 0 Abort Acknowledge */
-#define                      nAA0  0x0       
 #define                       AA1  0x2        /* Mailbox 1 Abort Acknowledge */
-#define                      nAA1  0x0       
 #define                       AA2  0x4        /* Mailbox 2 Abort Acknowledge */
-#define                      nAA2  0x0       
 #define                       AA3  0x8        /* Mailbox 3 Abort Acknowledge */
-#define                      nAA3  0x0       
 #define                       AA4  0x10       /* Mailbox 4 Abort Acknowledge */
-#define                      nAA4  0x0       
 #define                       AA5  0x20       /* Mailbox 5 Abort Acknowledge */
-#define                      nAA5  0x0       
 #define                       AA6  0x40       /* Mailbox 6 Abort Acknowledge */
-#define                      nAA6  0x0       
 #define                       AA7  0x80       /* Mailbox 7 Abort Acknowledge */
-#define                      nAA7  0x0       
 #define                       AA8  0x100      /* Mailbox 8 Abort Acknowledge */
-#define                      nAA8  0x0       
 #define                       AA9  0x200      /* Mailbox 9 Abort Acknowledge */
-#define                      nAA9  0x0       
 #define                      AA10  0x400      /* Mailbox 10 Abort Acknowledge */
-#define                     nAA10  0x0       
 #define                      AA11  0x800      /* Mailbox 11 Abort Acknowledge */
-#define                     nAA11  0x0       
 #define                      AA12  0x1000     /* Mailbox 12 Abort Acknowledge */
-#define                     nAA12  0x0       
 #define                      AA13  0x2000     /* Mailbox 13 Abort Acknowledge */
-#define                     nAA13  0x0       
 #define                      AA14  0x4000     /* Mailbox 14 Abort Acknowledge */
-#define                     nAA14  0x0       
 #define                      AA15  0x8000     /* Mailbox 15 Abort Acknowledge */
-#define                     nAA15  0x0       
 
 /* Bit masks for CAN0_AA2 */
 
 #define                      AA16  0x1        /* Mailbox 16 Abort Acknowledge */
-#define                     nAA16  0x0       
 #define                      AA17  0x2        /* Mailbox 17 Abort Acknowledge */
-#define                     nAA17  0x0       
 #define                      AA18  0x4        /* Mailbox 18 Abort Acknowledge */
-#define                     nAA18  0x0       
 #define                      AA19  0x8        /* Mailbox 19 Abort Acknowledge */
-#define                     nAA19  0x0       
 #define                      AA20  0x10       /* Mailbox 20 Abort Acknowledge */
-#define                     nAA20  0x0       
 #define                      AA21  0x20       /* Mailbox 21 Abort Acknowledge */
-#define                     nAA21  0x0       
 #define                      AA22  0x40       /* Mailbox 22 Abort Acknowledge */
-#define                     nAA22  0x0       
 #define                      AA23  0x80       /* Mailbox 23 Abort Acknowledge */
-#define                     nAA23  0x0       
 #define                      AA24  0x100      /* Mailbox 24 Abort Acknowledge */
-#define                     nAA24  0x0       
 #define                      AA25  0x200      /* Mailbox 25 Abort Acknowledge */
-#define                     nAA25  0x0       
 #define                      AA26  0x400      /* Mailbox 26 Abort Acknowledge */
-#define                     nAA26  0x0       
 #define                      AA27  0x800      /* Mailbox 27 Abort Acknowledge */
-#define                     nAA27  0x0       
 #define                      AA28  0x1000     /* Mailbox 28 Abort Acknowledge */
-#define                     nAA28  0x0       
 #define                      AA29  0x2000     /* Mailbox 29 Abort Acknowledge */
-#define                     nAA29  0x0       
 #define                      AA30  0x4000     /* Mailbox 30 Abort Acknowledge */
-#define                     nAA30  0x0       
 #define                      AA31  0x8000     /* Mailbox 31 Abort Acknowledge */
-#define                     nAA31  0x0       
 
 /* Bit masks for CAN0_TA1 */
 
 #define                       TA0  0x1        /* Mailbox 0 Transmit Acknowledge */
-#define                      nTA0  0x0       
 #define                       TA1  0x2        /* Mailbox 1 Transmit Acknowledge */
-#define                      nTA1  0x0       
 #define                       TA2  0x4        /* Mailbox 2 Transmit Acknowledge */
-#define                      nTA2  0x0       
 #define                       TA3  0x8        /* Mailbox 3 Transmit Acknowledge */
-#define                      nTA3  0x0       
 #define                       TA4  0x10       /* Mailbox 4 Transmit Acknowledge */
-#define                      nTA4  0x0       
 #define                       TA5  0x20       /* Mailbox 5 Transmit Acknowledge */
-#define                      nTA5  0x0       
 #define                       TA6  0x40       /* Mailbox 6 Transmit Acknowledge */
-#define                      nTA6  0x0       
 #define                       TA7  0x80       /* Mailbox 7 Transmit Acknowledge */
-#define                      nTA7  0x0       
 #define                       TA8  0x100      /* Mailbox 8 Transmit Acknowledge */
-#define                      nTA8  0x0       
 #define                       TA9  0x200      /* Mailbox 9 Transmit Acknowledge */
-#define                      nTA9  0x0       
 #define                      TA10  0x400      /* Mailbox 10 Transmit Acknowledge */
-#define                     nTA10  0x0       
 #define                      TA11  0x800      /* Mailbox 11 Transmit Acknowledge */
-#define                     nTA11  0x0       
 #define                      TA12  0x1000     /* Mailbox 12 Transmit Acknowledge */
-#define                     nTA12  0x0       
 #define                      TA13  0x2000     /* Mailbox 13 Transmit Acknowledge */
-#define                     nTA13  0x0       
 #define                      TA14  0x4000     /* Mailbox 14 Transmit Acknowledge */
-#define                     nTA14  0x0       
 #define                      TA15  0x8000     /* Mailbox 15 Transmit Acknowledge */
-#define                     nTA15  0x0       
 
 /* Bit masks for CAN0_TA2 */
 
 #define                      TA16  0x1        /* Mailbox 16 Transmit Acknowledge */
-#define                     nTA16  0x0       
 #define                      TA17  0x2        /* Mailbox 17 Transmit Acknowledge */
-#define                     nTA17  0x0       
 #define                      TA18  0x4        /* Mailbox 18 Transmit Acknowledge */
-#define                     nTA18  0x0       
 #define                      TA19  0x8        /* Mailbox 19 Transmit Acknowledge */
-#define                     nTA19  0x0       
 #define                      TA20  0x10       /* Mailbox 20 Transmit Acknowledge */
-#define                     nTA20  0x0       
 #define                      TA21  0x20       /* Mailbox 21 Transmit Acknowledge */
-#define                     nTA21  0x0       
 #define                      TA22  0x40       /* Mailbox 22 Transmit Acknowledge */
-#define                     nTA22  0x0       
 #define                      TA23  0x80       /* Mailbox 23 Transmit Acknowledge */
-#define                     nTA23  0x0       
 #define                      TA24  0x100      /* Mailbox 24 Transmit Acknowledge */
-#define                     nTA24  0x0       
 #define                      TA25  0x200      /* Mailbox 25 Transmit Acknowledge */
-#define                     nTA25  0x0       
 #define                      TA26  0x400      /* Mailbox 26 Transmit Acknowledge */
-#define                     nTA26  0x0       
 #define                      TA27  0x800      /* Mailbox 27 Transmit Acknowledge */
-#define                     nTA27  0x0       
 #define                      TA28  0x1000     /* Mailbox 28 Transmit Acknowledge */
-#define                     nTA28  0x0       
 #define                      TA29  0x2000     /* Mailbox 29 Transmit Acknowledge */
-#define                     nTA29  0x0       
 #define                      TA30  0x4000     /* Mailbox 30 Transmit Acknowledge */
-#define                     nTA30  0x0       
 #define                      TA31  0x8000     /* Mailbox 31 Transmit Acknowledge */
-#define                     nTA31  0x0       
 
 /* Bit masks for CAN0_RFH1 */
 
 #define                      RFH0  0x1        /* Mailbox 0 Remote Frame Handling Enable */
-#define                     nRFH0  0x0       
 #define                      RFH1  0x2        /* Mailbox 1 Remote Frame Handling Enable */
-#define                     nRFH1  0x0       
 #define                      RFH2  0x4        /* Mailbox 2 Remote Frame Handling Enable */
-#define                     nRFH2  0x0       
 #define                      RFH3  0x8        /* Mailbox 3 Remote Frame Handling Enable */
-#define                     nRFH3  0x0       
 #define                      RFH4  0x10       /* Mailbox 4 Remote Frame Handling Enable */
-#define                     nRFH4  0x0       
 #define                      RFH5  0x20       /* Mailbox 5 Remote Frame Handling Enable */
-#define                     nRFH5  0x0       
 #define                      RFH6  0x40       /* Mailbox 6 Remote Frame Handling Enable */
-#define                     nRFH6  0x0       
 #define                      RFH7  0x80       /* Mailbox 7 Remote Frame Handling Enable */
-#define                     nRFH7  0x0       
 #define                      RFH8  0x100      /* Mailbox 8 Remote Frame Handling Enable */
-#define                     nRFH8  0x0       
 #define                      RFH9  0x200      /* Mailbox 9 Remote Frame Handling Enable */
-#define                     nRFH9  0x0       
 #define                     RFH10  0x400      /* Mailbox 10 Remote Frame Handling Enable */
-#define                    nRFH10  0x0       
 #define                     RFH11  0x800      /* Mailbox 11 Remote Frame Handling Enable */
-#define                    nRFH11  0x0       
 #define                     RFH12  0x1000     /* Mailbox 12 Remote Frame Handling Enable */
-#define                    nRFH12  0x0       
 #define                     RFH13  0x2000     /* Mailbox 13 Remote Frame Handling Enable */
-#define                    nRFH13  0x0       
 #define                     RFH14  0x4000     /* Mailbox 14 Remote Frame Handling Enable */
-#define                    nRFH14  0x0       
 #define                     RFH15  0x8000     /* Mailbox 15 Remote Frame Handling Enable */
-#define                    nRFH15  0x0       
 
 /* Bit masks for CAN0_RFH2 */
 
 #define                     RFH16  0x1        /* Mailbox 16 Remote Frame Handling Enable */
-#define                    nRFH16  0x0       
 #define                     RFH17  0x2        /* Mailbox 17 Remote Frame Handling Enable */
-#define                    nRFH17  0x0       
 #define                     RFH18  0x4        /* Mailbox 18 Remote Frame Handling Enable */
-#define                    nRFH18  0x0       
 #define                     RFH19  0x8        /* Mailbox 19 Remote Frame Handling Enable */
-#define                    nRFH19  0x0       
 #define                     RFH20  0x10       /* Mailbox 20 Remote Frame Handling Enable */
-#define                    nRFH20  0x0       
 #define                     RFH21  0x20       /* Mailbox 21 Remote Frame Handling Enable */
-#define                    nRFH21  0x0       
 #define                     RFH22  0x40       /* Mailbox 22 Remote Frame Handling Enable */
-#define                    nRFH22  0x0       
 #define                     RFH23  0x80       /* Mailbox 23 Remote Frame Handling Enable */
-#define                    nRFH23  0x0       
 #define                     RFH24  0x100      /* Mailbox 24 Remote Frame Handling Enable */
-#define                    nRFH24  0x0       
 #define                     RFH25  0x200      /* Mailbox 25 Remote Frame Handling Enable */
-#define                    nRFH25  0x0       
 #define                     RFH26  0x400      /* Mailbox 26 Remote Frame Handling Enable */
-#define                    nRFH26  0x0       
 #define                     RFH27  0x800      /* Mailbox 27 Remote Frame Handling Enable */
-#define                    nRFH27  0x0       
 #define                     RFH28  0x1000     /* Mailbox 28 Remote Frame Handling Enable */
-#define                    nRFH28  0x0       
 #define                     RFH29  0x2000     /* Mailbox 29 Remote Frame Handling Enable */
-#define                    nRFH29  0x0       
 #define                     RFH30  0x4000     /* Mailbox 30 Remote Frame Handling Enable */
-#define                    nRFH30  0x0       
 #define                     RFH31  0x8000     /* Mailbox 31 Remote Frame Handling Enable */
-#define                    nRFH31  0x0       
 
 /* Bit masks for CAN0_MBIM1 */
 
 #define                     MBIM0  0x1        /* Mailbox 0 Mailbox Interrupt Mask */
-#define                    nMBIM0  0x0       
 #define                     MBIM1  0x2        /* Mailbox 1 Mailbox Interrupt Mask */
-#define                    nMBIM1  0x0       
 #define                     MBIM2  0x4        /* Mailbox 2 Mailbox Interrupt Mask */
-#define                    nMBIM2  0x0       
 #define                     MBIM3  0x8        /* Mailbox 3 Mailbox Interrupt Mask */
-#define                    nMBIM3  0x0       
 #define                     MBIM4  0x10       /* Mailbox 4 Mailbox Interrupt Mask */
-#define                    nMBIM4  0x0       
 #define                     MBIM5  0x20       /* Mailbox 5 Mailbox Interrupt Mask */
-#define                    nMBIM5  0x0       
 #define                     MBIM6  0x40       /* Mailbox 6 Mailbox Interrupt Mask */
-#define                    nMBIM6  0x0       
 #define                     MBIM7  0x80       /* Mailbox 7 Mailbox Interrupt Mask */
-#define                    nMBIM7  0x0       
 #define                     MBIM8  0x100      /* Mailbox 8 Mailbox Interrupt Mask */
-#define                    nMBIM8  0x0       
 #define                     MBIM9  0x200      /* Mailbox 9 Mailbox Interrupt Mask */
-#define                    nMBIM9  0x0       
 #define                    MBIM10  0x400      /* Mailbox 10 Mailbox Interrupt Mask */
-#define                   nMBIM10  0x0       
 #define                    MBIM11  0x800      /* Mailbox 11 Mailbox Interrupt Mask */
-#define                   nMBIM11  0x0       
 #define                    MBIM12  0x1000     /* Mailbox 12 Mailbox Interrupt Mask */
-#define                   nMBIM12  0x0       
 #define                    MBIM13  0x2000     /* Mailbox 13 Mailbox Interrupt Mask */
-#define                   nMBIM13  0x0       
 #define                    MBIM14  0x4000     /* Mailbox 14 Mailbox Interrupt Mask */
-#define                   nMBIM14  0x0       
 #define                    MBIM15  0x8000     /* Mailbox 15 Mailbox Interrupt Mask */
-#define                   nMBIM15  0x0       
 
 /* Bit masks for CAN0_MBIM2 */
 
 #define                    MBIM16  0x1        /* Mailbox 16 Mailbox Interrupt Mask */
-#define                   nMBIM16  0x0       
 #define                    MBIM17  0x2        /* Mailbox 17 Mailbox Interrupt Mask */
-#define                   nMBIM17  0x0       
 #define                    MBIM18  0x4        /* Mailbox 18 Mailbox Interrupt Mask */
-#define                   nMBIM18  0x0       
 #define                    MBIM19  0x8        /* Mailbox 19 Mailbox Interrupt Mask */
-#define                   nMBIM19  0x0       
 #define                    MBIM20  0x10       /* Mailbox 20 Mailbox Interrupt Mask */
-#define                   nMBIM20  0x0       
 #define                    MBIM21  0x20       /* Mailbox 21 Mailbox Interrupt Mask */
-#define                   nMBIM21  0x0       
 #define                    MBIM22  0x40       /* Mailbox 22 Mailbox Interrupt Mask */
-#define                   nMBIM22  0x0       
 #define                    MBIM23  0x80       /* Mailbox 23 Mailbox Interrupt Mask */
-#define                   nMBIM23  0x0       
 #define                    MBIM24  0x100      /* Mailbox 24 Mailbox Interrupt Mask */
-#define                   nMBIM24  0x0       
 #define                    MBIM25  0x200      /* Mailbox 25 Mailbox Interrupt Mask */
-#define                   nMBIM25  0x0       
 #define                    MBIM26  0x400      /* Mailbox 26 Mailbox Interrupt Mask */
-#define                   nMBIM26  0x0       
 #define                    MBIM27  0x800      /* Mailbox 27 Mailbox Interrupt Mask */
-#define                   nMBIM27  0x0       
 #define                    MBIM28  0x1000     /* Mailbox 28 Mailbox Interrupt Mask */
-#define                   nMBIM28  0x0       
 #define                    MBIM29  0x2000     /* Mailbox 29 Mailbox Interrupt Mask */
-#define                   nMBIM29  0x0       
 #define                    MBIM30  0x4000     /* Mailbox 30 Mailbox Interrupt Mask */
-#define                   nMBIM30  0x0       
 #define                    MBIM31  0x8000     /* Mailbox 31 Mailbox Interrupt Mask */
-#define                   nMBIM31  0x0       
 
 /* Bit masks for CAN0_MBTIF1 */
 
 #define                    MBTIF0  0x1        /* Mailbox 0 Mailbox Transmit Interrupt Flag */
-#define                   nMBTIF0  0x0       
 #define                    MBTIF1  0x2        /* Mailbox 1 Mailbox Transmit Interrupt Flag */
-#define                   nMBTIF1  0x0       
 #define                    MBTIF2  0x4        /* Mailbox 2 Mailbox Transmit Interrupt Flag */
-#define                   nMBTIF2  0x0       
 #define                    MBTIF3  0x8        /* Mailbox 3 Mailbox Transmit Interrupt Flag */
-#define                   nMBTIF3  0x0       
 #define                    MBTIF4  0x10       /* Mailbox 4 Mailbox Transmit Interrupt Flag */
-#define                   nMBTIF4  0x0       
 #define                    MBTIF5  0x20       /* Mailbox 5 Mailbox Transmit Interrupt Flag */
-#define                   nMBTIF5  0x0       
 #define                    MBTIF6  0x40       /* Mailbox 6 Mailbox Transmit Interrupt Flag */
-#define                   nMBTIF6  0x0       
 #define                    MBTIF7  0x80       /* Mailbox 7 Mailbox Transmit Interrupt Flag */
-#define                   nMBTIF7  0x0       
 #define                    MBTIF8  0x100      /* Mailbox 8 Mailbox Transmit Interrupt Flag */
-#define                   nMBTIF8  0x0       
 #define                    MBTIF9  0x200      /* Mailbox 9 Mailbox Transmit Interrupt Flag */
-#define                   nMBTIF9  0x0       
 #define                   MBTIF10  0x400      /* Mailbox 10 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF10  0x0       
 #define                   MBTIF11  0x800      /* Mailbox 11 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF11  0x0       
 #define                   MBTIF12  0x1000     /* Mailbox 12 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF12  0x0       
 #define                   MBTIF13  0x2000     /* Mailbox 13 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF13  0x0       
 #define                   MBTIF14  0x4000     /* Mailbox 14 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF14  0x0       
 #define                   MBTIF15  0x8000     /* Mailbox 15 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF15  0x0       
 
 /* Bit masks for CAN0_MBTIF2 */
 
 #define                   MBTIF16  0x1        /* Mailbox 16 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF16  0x0       
 #define                   MBTIF17  0x2        /* Mailbox 17 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF17  0x0       
 #define                   MBTIF18  0x4        /* Mailbox 18 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF18  0x0       
 #define                   MBTIF19  0x8        /* Mailbox 19 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF19  0x0       
 #define                   MBTIF20  0x10       /* Mailbox 20 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF20  0x0       
 #define                   MBTIF21  0x20       /* Mailbox 21 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF21  0x0       
 #define                   MBTIF22  0x40       /* Mailbox 22 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF22  0x0       
 #define                   MBTIF23  0x80       /* Mailbox 23 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF23  0x0       
 #define                   MBTIF24  0x100      /* Mailbox 24 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF24  0x0       
 #define                   MBTIF25  0x200      /* Mailbox 25 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF25  0x0       
 #define                   MBTIF26  0x400      /* Mailbox 26 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF26  0x0       
 #define                   MBTIF27  0x800      /* Mailbox 27 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF27  0x0       
 #define                   MBTIF28  0x1000     /* Mailbox 28 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF28  0x0       
 #define                   MBTIF29  0x2000     /* Mailbox 29 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF29  0x0       
 #define                   MBTIF30  0x4000     /* Mailbox 30 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF30  0x0       
 #define                   MBTIF31  0x8000     /* Mailbox 31 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF31  0x0       
 
 /* Bit masks for CAN0_MBRIF1 */
 
 #define                    MBRIF0  0x1        /* Mailbox 0 Mailbox Receive Interrupt Flag */
-#define                   nMBRIF0  0x0       
 #define                    MBRIF1  0x2        /* Mailbox 1 Mailbox Receive Interrupt Flag */
-#define                   nMBRIF1  0x0       
 #define                    MBRIF2  0x4        /* Mailbox 2 Mailbox Receive Interrupt Flag */
-#define                   nMBRIF2  0x0       
 #define                    MBRIF3  0x8        /* Mailbox 3 Mailbox Receive Interrupt Flag */
-#define                   nMBRIF3  0x0       
 #define                    MBRIF4  0x10       /* Mailbox 4 Mailbox Receive Interrupt Flag */
-#define                   nMBRIF4  0x0       
 #define                    MBRIF5  0x20       /* Mailbox 5 Mailbox Receive Interrupt Flag */
-#define                   nMBRIF5  0x0       
 #define                    MBRIF6  0x40       /* Mailbox 6 Mailbox Receive Interrupt Flag */
-#define                   nMBRIF6  0x0       
 #define                    MBRIF7  0x80       /* Mailbox 7 Mailbox Receive Interrupt Flag */
-#define                   nMBRIF7  0x0       
 #define                    MBRIF8  0x100      /* Mailbox 8 Mailbox Receive Interrupt Flag */
-#define                   nMBRIF8  0x0       
 #define                    MBRIF9  0x200      /* Mailbox 9 Mailbox Receive Interrupt Flag */
-#define                   nMBRIF9  0x0       
 #define                   MBRIF10  0x400      /* Mailbox 10 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF10  0x0       
 #define                   MBRIF11  0x800      /* Mailbox 11 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF11  0x0       
 #define                   MBRIF12  0x1000     /* Mailbox 12 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF12  0x0       
 #define                   MBRIF13  0x2000     /* Mailbox 13 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF13  0x0       
 #define                   MBRIF14  0x4000     /* Mailbox 14 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF14  0x0       
 #define                   MBRIF15  0x8000     /* Mailbox 15 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF15  0x0       
 
 /* Bit masks for CAN0_MBRIF2 */
 
 #define                   MBRIF16  0x1        /* Mailbox 16 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF16  0x0       
 #define                   MBRIF17  0x2        /* Mailbox 17 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF17  0x0       
 #define                   MBRIF18  0x4        /* Mailbox 18 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF18  0x0       
 #define                   MBRIF19  0x8        /* Mailbox 19 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF19  0x0       
 #define                   MBRIF20  0x10       /* Mailbox 20 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF20  0x0       
 #define                   MBRIF21  0x20       /* Mailbox 21 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF21  0x0       
 #define                   MBRIF22  0x40       /* Mailbox 22 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF22  0x0       
 #define                   MBRIF23  0x80       /* Mailbox 23 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF23  0x0       
 #define                   MBRIF24  0x100      /* Mailbox 24 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF24  0x0       
 #define                   MBRIF25  0x200      /* Mailbox 25 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF25  0x0       
 #define                   MBRIF26  0x400      /* Mailbox 26 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF26  0x0       
 #define                   MBRIF27  0x800      /* Mailbox 27 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF27  0x0       
 #define                   MBRIF28  0x1000     /* Mailbox 28 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF28  0x0       
 #define                   MBRIF29  0x2000     /* Mailbox 29 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF29  0x0       
 #define                   MBRIF30  0x4000     /* Mailbox 30 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF30  0x0       
 #define                   MBRIF31  0x8000     /* Mailbox 31 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF31  0x0       
 
 /* Bit masks for EPPIx_STATUS */
 
 #define                 CFIFO_ERR  0x1        /* Chroma FIFO Error */
-#define                nCFIFO_ERR  0x0       
 #define                 YFIFO_ERR  0x2        /* Luma FIFO Error */
-#define                nYFIFO_ERR  0x0       
 #define                 LTERR_OVR  0x4        /* Line Track Overflow */
-#define                nLTERR_OVR  0x0       
 #define                LTERR_UNDR  0x8        /* Line Track Underflow */
-#define               nLTERR_UNDR  0x0       
 #define                 FTERR_OVR  0x10       /* Frame Track Overflow */
-#define                nFTERR_OVR  0x0       
 #define                FTERR_UNDR  0x20       /* Frame Track Underflow */
-#define               nFTERR_UNDR  0x0       
 #define                  ERR_NCOR  0x40       /* Preamble Error Not Corrected */
-#define                 nERR_NCOR  0x0       
 #define                   DMA1URQ  0x80       /* DMA1 Urgent Request */
-#define                  nDMA1URQ  0x0       
 #define                   DMA0URQ  0x100      /* DMA0 Urgent Request */
-#define                  nDMA0URQ  0x0       
 #define                   ERR_DET  0x4000     /* Preamble Error Detected */
-#define                  nERR_DET  0x0       
 #define                       FLD  0x8000     /* Field */
-#define                      nFLD  0x0       
 
 /* Bit masks for EPPIx_CONTROL */
 
 #define                   EPPI_EN  0x1        /* Enable */
-#define                  nEPPI_EN  0x0       
 #define                  EPPI_DIR  0x2        /* Direction */
-#define                 nEPPI_DIR  0x0       
 #define                  XFR_TYPE  0xc        /* Operating Mode */
 #define                    FS_CFG  0x30       /* Frame Sync Configuration */
 #define                   FLD_SEL  0x40       /* Field Select/Trigger */
-#define                  nFLD_SEL  0x0       
 #define                  ITU_TYPE  0x80       /* ITU Interlaced or Progressive */
-#define                 nITU_TYPE  0x0       
 #define                  BLANKGEN  0x100      /* ITU Output Mode with Internal Blanking Generation */
-#define                 nBLANKGEN  0x0       
 #define                   ICLKGEN  0x200      /* Internal Clock Generation */
-#define                  nICLKGEN  0x0       
 #define                    IFSGEN  0x400      /* Internal Frame Sync Generation */
-#define                   nIFSGEN  0x0       
 #define                      POLC  0x1800     /* Frame Sync and Data Driving/Sampling Edges */
 #define                      POLS  0x6000     /* Frame Sync Polarity */
 #define                   DLENGTH  0x38000    /* Data Length */
 #define                   SKIP_EN  0x40000    /* Skip Enable */
-#define                  nSKIP_EN  0x0       
 #define                   SKIP_EO  0x80000    /* Skip Even or Odd */
-#define                  nSKIP_EO  0x0       
 #define                    PACKEN  0x100000   /* Packing/Unpacking Enable */
-#define                   nPACKEN  0x0       
 #define                    SWAPEN  0x200000   /* Swap Enable */
-#define                   nSWAPEN  0x0       
 #define                  SIGN_EXT  0x400000   /* Sign Extension or Zero-filled / Data Split Format */
-#define                 nSIGN_EXT  0x0       
 #define             SPLT_EVEN_ODD  0x800000   /* Split Even and Odd Data Samples */
-#define            nSPLT_EVEN_ODD  0x0       
 #define               SUBSPLT_ODD  0x1000000  /* Sub-split Odd Samples */
-#define              nSUBSPLT_ODD  0x0       
 #define                    DMACFG  0x2000000  /* One or Two DMA Channels Mode */
-#define                   nDMACFG  0x0       
 #define                RGB_FMT_EN  0x4000000  /* RGB Formatting Enable */
-#define               nRGB_FMT_EN  0x0       
 #define                  FIFO_RWM  0x18000000 /* FIFO Regular Watermarks */
 #define                  FIFO_UWM  0x60000000 /* FIFO Urgent Watermarks */
 
+#define DLEN_8         (0 << 15) /* 000 - 8 bits */
+#define DLEN_10                (1 << 15) /* 001 - 10 bits */
+#define DLEN_12                (2 << 15) /* 010 - 12 bits */
+#define DLEN_14                (3 << 15) /* 011 - 14 bits */
+#define DLEN_16                (4 << 15) /* 100 - 16 bits */
+#define DLEN_18                (5 << 15) /* 101 - 18 bits */
+#define DLEN_24                (6 << 15) /* 110 - 24 bits */
+
+
 /* Bit masks for EPPIx_FS2W_LVB */
 
 #define                   F1VB_BD  0xff       /* Vertical Blanking before Field 1 Active Data */
 /* Bit masks for SPIx_CTL */
 
 #define                       SPE  0x4000     /* SPI Enable */
-#define                      nSPE  0x0       
 #define                       WOM  0x2000     /* Write Open Drain Master */
-#define                      nWOM  0x0       
 #define                      MSTR  0x1000     /* Master Mode */
-#define                     nMSTR  0x0       
 #define                      CPOL  0x800      /* Clock Polarity */
-#define                     nCPOL  0x0       
 #define                      CPHA  0x400      /* Clock Phase */
-#define                     nCPHA  0x0       
 #define                      LSBF  0x200      /* LSB First */
-#define                     nLSBF  0x0       
 #define                      SIZE  0x100      /* Size of Words */
-#define                     nSIZE  0x0       
 #define                     EMISO  0x20       /* Enable MISO Output */
-#define                    nEMISO  0x0       
 #define                      PSSE  0x10       /* Slave-Select Enable */
-#define                     nPSSE  0x0       
 #define                        GM  0x8        /* Get More Data */
-#define                       nGM  0x0       
 #define                        SZ  0x4        /* Send Zero */
-#define                       nSZ  0x0       
 #define                     TIMOD  0x3        /* Transfer Initiation Mode */
 
 /* Bit masks for SPIx_FLG */
 
 #define                      FLS1  0x2        /* Slave Select Enable 1 */
-#define                     nFLS1  0x0       
 #define                      FLS2  0x4        /* Slave Select Enable 2 */
-#define                     nFLS2  0x0       
 #define                      FLS3  0x8        /* Slave Select Enable 3 */
-#define                     nFLS3  0x0       
 #define                      FLG1  0x200      /* Slave Select Value 1 */
-#define                     nFLG1  0x0       
 #define                      FLG2  0x400      /* Slave Select Value 2 */
-#define                     nFLG2  0x0       
 #define                      FLG3  0x800      /* Slave Select Value 3 */
-#define                     nFLG3  0x0       
 
 /* Bit masks for SPIx_STAT */
 
 #define                     TXCOL  0x40       /* Transmit Collision Error */
-#define                    nTXCOL  0x0       
 #define                       RXS  0x20       /* RDBR Data Buffer Status */
-#define                      nRXS  0x0       
 #define                      RBSY  0x10       /* Receive Error */
-#define                     nRBSY  0x0       
 #define                       TXS  0x8        /* TDBR Data Buffer Status */
-#define                      nTXS  0x0       
 #define                       TXE  0x4        /* Transmission Error */
-#define                      nTXE  0x0       
 #define                      MODF  0x2        /* Mode Fault Error */
-#define                     nMODF  0x0       
 #define                      SPIF  0x1        /* SPI Finished */
-#define                     nSPIF  0x0       
 
 /* Bit masks for SPIx_TDBR */
 
 
 #define                  PRESCALE  0x7f       /* Prescale Value */
 #define                   TWI_ENA  0x80       /* TWI Enable */
-#define                  nTWI_ENA  0x0       
 #define                      SCCB  0x200      /* Serial Camera Control Bus */
-#define                     nSCCB  0x0       
 
 /* Bit maskes for TWIx_CLKDIV */
 
 /* Bit maskes for TWIx_SLAVE_CTL */
 
 #define                       SEN  0x1        /* Slave Enable */
-#define                      nSEN  0x0       
 #define                    STDVAL  0x4        /* Slave Transmit Data Valid */
-#define                   nSTDVAL  0x0       
 #define                       NAK  0x8        /* Not Acknowledge */
-#define                      nNAK  0x0       
 #define                       GEN  0x10       /* General Call Enable */
-#define                      nGEN  0x0       
 
 /* Bit maskes for TWIx_SLAVE_ADDR */
 
 /* Bit maskes for TWIx_SLAVE_STAT */
 
 #define                      SDIR  0x1        /* Slave Transfer Direction */
-#define                     nSDIR  0x0       
 #define                     GCALL  0x2        /* General Call */
-#define                    nGCALL  0x0       
 
 /* Bit maskes for TWIx_MASTER_CTL */
 
 #define                       MEN  0x1        /* Master Mode Enable */
-#define                      nMEN  0x0       
 #define                      MDIR  0x4        /* Master Transfer Direction */
-#define                     nMDIR  0x0       
 #define                      FAST  0x8        /* Fast Mode */
-#define                     nFAST  0x0       
 #define                      STOP  0x10       /* Issue Stop Condition */
-#define                     nSTOP  0x0       
 #define                    RSTART  0x20       /* Repeat Start */
-#define                   nRSTART  0x0       
 #define                      DCNT  0x3fc0     /* Data Transfer Count */
 #define                    SDAOVR  0x4000     /* Serial Data Override */
-#define                   nSDAOVR  0x0       
 #define                    SCLOVR  0x8000     /* Serial Clock Override */
-#define                   nSCLOVR  0x0       
 
 /* Bit maskes for TWIx_MASTER_ADDR */
 
 /* Bit maskes for TWIx_MASTER_STAT */
 
 #define                     MPROG  0x1        /* Master Transfer in Progress */
-#define                    nMPROG  0x0       
 #define                   LOSTARB  0x2        /* Lost Arbitration */
-#define                  nLOSTARB  0x0       
 #define                      ANAK  0x4        /* Address Not Acknowledged */
-#define                     nANAK  0x0       
 #define                      DNAK  0x8        /* Data Not Acknowledged */
-#define                     nDNAK  0x0       
 #define                  BUFRDERR  0x10       /* Buffer Read Error */
-#define                 nBUFRDERR  0x0       
 #define                  BUFWRERR  0x20       /* Buffer Write Error */
-#define                 nBUFWRERR  0x0       
 #define                    SDASEN  0x40       /* Serial Data Sense */
-#define                   nSDASEN  0x0       
 #define                    SCLSEN  0x80       /* Serial Clock Sense */
-#define                   nSCLSEN  0x0       
 #define                   BUSBUSY  0x100      /* Bus Busy */
-#define                  nBUSBUSY  0x0       
 
 /* Bit maskes for TWIx_FIFO_CTL */
 
 #define                  XMTFLUSH  0x1        /* Transmit Buffer Flush */
-#define                 nXMTFLUSH  0x0       
 #define                  RCVFLUSH  0x2        /* Receive Buffer Flush */
-#define                 nRCVFLUSH  0x0       
 #define                 XMTINTLEN  0x4        /* Transmit Buffer Interrupt Length */
-#define                nXMTINTLEN  0x0       
 #define                 RCVINTLEN  0x8        /* Receive Buffer Interrupt Length */
-#define                nRCVINTLEN  0x0       
 
 /* Bit maskes for TWIx_FIFO_STAT */
 
 /* Bit maskes for TWIx_INT_MASK */
 
 #define                    SINITM  0x1        /* Slave Transfer Initiated Interrupt Mask */
-#define                   nSINITM  0x0       
 #define                    SCOMPM  0x2        /* Slave Transfer Complete Interrupt Mask */
-#define                   nSCOMPM  0x0       
 #define                     SERRM  0x4        /* Slave Transfer Error Interrupt Mask */
-#define                    nSERRM  0x0       
 #define                     SOVFM  0x8        /* Slave Overflow Interrupt Mask */
-#define                    nSOVFM  0x0       
 #define                    MCOMPM  0x10       /* Master Transfer Complete Interrupt Mask */
-#define                   nMCOMPM  0x0       
 #define                     MERRM  0x20       /* Master Transfer Error Interrupt Mask */
-#define                    nMERRM  0x0       
 #define                  XMTSERVM  0x40       /* Transmit FIFO Service Interrupt Mask */
-#define                 nXMTSERVM  0x0       
 #define                  RCVSERVM  0x80       /* Receive FIFO Service Interrupt Mask */
-#define                 nRCVSERVM  0x0       
 
 /* Bit maskes for TWIx_INT_STAT */
 
 #define                     SINIT  0x1        /* Slave Transfer Initiated */
-#define                    nSINIT  0x0       
 #define                     SCOMP  0x2        /* Slave Transfer Complete */
-#define                    nSCOMP  0x0       
 #define                      SERR  0x4        /* Slave Transfer Error */
-#define                     nSERR  0x0       
 #define                      SOVF  0x8        /* Slave Overflow */
-#define                     nSOVF  0x0       
 #define                     MCOMP  0x10       /* Master Transfer Complete */
-#define                    nMCOMP  0x0       
 #define                      MERR  0x20       /* Master Transfer Error */
-#define                     nMERR  0x0       
 #define                   XMTSERV  0x40       /* Transmit FIFO Service */
-#define                  nXMTSERV  0x0       
 #define                   RCVSERV  0x80       /* Receive FIFO Service */
-#define                  nRCVSERV  0x0       
 
 /* Bit maskes for TWIx_XMT_DATA8 */
 
 /* Bit masks for SPORTx_TCR1 */
 
 #define                     TCKFE  0x4000     /* Clock Falling Edge Select */
-#define                    nTCKFE  0x0       
 #define                     LATFS  0x2000     /* Late Transmit Frame Sync */
-#define                    nLATFS  0x0       
 #define                      LTFS  0x1000     /* Low Transmit Frame Sync Select */
-#define                     nLTFS  0x0       
 #define                     DITFS  0x800      /* Data-Independent Transmit Frame Sync Select */
-#define                    nDITFS  0x0       
 #define                      TFSR  0x400      /* Transmit Frame Sync Required Select */
-#define                     nTFSR  0x0       
 #define                      ITFS  0x200      /* Internal Transmit Frame Sync Select */
-#define                     nITFS  0x0       
 #define                    TLSBIT  0x10       /* Transmit Bit Order */
-#define                   nTLSBIT  0x0       
 #define                    TDTYPE  0xc        /* Data Formatting Type Select */
 #define                     ITCLK  0x2        /* Internal Transmit Clock Select */
-#define                    nITCLK  0x0       
 #define                     TSPEN  0x1        /* Transmit Enable */
-#define                    nTSPEN  0x0       
 
 /* Bit masks for SPORTx_TCR2 */
 
 #define                     TRFST  0x400      /* Left/Right Order */
-#define                    nTRFST  0x0       
 #define                     TSFSE  0x200      /* Transmit Stereo Frame Sync Enable */
-#define                    nTSFSE  0x0       
 #define                      TXSE  0x100      /* TxSEC Enable */
-#define                     nTXSE  0x0       
 #define                    SLEN_T  0x1f       /* SPORT Word Length */
 
 /* Bit masks for SPORTx_RCR1 */
 
 #define                     RCKFE  0x4000     /* Clock Falling Edge Select */
-#define                    nRCKFE  0x0       
 #define                     LARFS  0x2000     /* Late Receive Frame Sync */
-#define                    nLARFS  0x0       
 #define                      LRFS  0x1000     /* Low Receive Frame Sync Select */
-#define                     nLRFS  0x0       
 #define                      RFSR  0x400      /* Receive Frame Sync Required Select */
-#define                     nRFSR  0x0       
 #define                      IRFS  0x200      /* Internal Receive Frame Sync Select */
-#define                     nIRFS  0x0       
 #define                    RLSBIT  0x10       /* Receive Bit Order */
-#define                   nRLSBIT  0x0       
 #define                    RDTYPE  0xc        /* Data Formatting Type Select */
 #define                     IRCLK  0x2        /* Internal Receive Clock Select */
-#define                    nIRCLK  0x0       
 #define                     RSPEN  0x1        /* Receive Enable */
-#define                    nRSPEN  0x0       
 
 /* Bit masks for SPORTx_RCR2 */
 
 #define                     RRFST  0x400      /* Left/Right Order */
-#define                    nRRFST  0x0       
 #define                     RSFSE  0x200      /* Receive Stereo Frame Sync Enable */
-#define                    nRSFSE  0x0       
 #define                      RXSE  0x100      /* RxSEC Enable */
-#define                     nRXSE  0x0       
 #define                    SLEN_R  0x1f       /* SPORT Word Length */
 
 /* Bit masks for SPORTx_STAT */
 
 #define                     TXHRE  0x40       /* Transmit Hold Register Empty */
-#define                    nTXHRE  0x0       
 #define                      TOVF  0x20       /* Sticky Transmit Overflow Status */
-#define                     nTOVF  0x0       
 #define                      TUVF  0x10       /* Sticky Transmit Underflow Status */
-#define                     nTUVF  0x0       
 #define                       TXF  0x8        /* Transmit FIFO Full Status */
-#define                      nTXF  0x0       
 #define                      ROVF  0x4        /* Sticky Receive Overflow Status */
-#define                     nROVF  0x0       
 #define                      RUVF  0x2        /* Sticky Receive Underflow Status */
-#define                     nRUVF  0x0       
 #define                      RXNE  0x1        /* Receive FIFO Not Empty Status */
-#define                     nRXNE  0x0       
 
 /* Bit masks for SPORTx_MCMC1 */
 
 
 #define                       MFD  0xf000     /* Multi channel Frame Delay */
 #define                      FSDR  0x80       /* Frame Sync to Data Relationship */
-#define                     nFSDR  0x0       
 #define                     MCMEM  0x10       /* Multi channel Frame Mode Enable */
-#define                    nMCMEM  0x0       
 #define                   MCDRXPE  0x8        /* Multi channel DMA Receive Packing */
-#define                  nMCDRXPE  0x0       
 #define                   MCDTXPE  0x4        /* Multi channel DMA Transmit Packing */
-#define                  nMCDTXPE  0x0       
 #define                     MCCRM  0x3        /* 2X Clock Recovery Mode */
 
 /* Bit masks for SPORTx_CHNL */
 #define                       WLS  0x3        /* Word Length Select */
 #endif
 #define                       STB  0x4        /* Stop Bits */
-#define                      nSTB  0x0       
 #define                       PEN  0x8        /* Parity Enable */
-#define                      nPEN  0x0       
 #define                       EPS  0x10       /* Even Parity Select */
-#define                      nEPS  0x0       
 #define                       STP  0x20       /* Sticky Parity */
-#define                      nSTP  0x0       
 #define                        SB  0x40       /* Set Break */
-#define                       nSB  0x0       
 
 /* Bit masks for UARTx_MCR */
 
 #define                      XOFF  0x1        /* Transmitter Off */
-#define                     nXOFF  0x0       
 #define                      MRTS  0x2        /* Manual Request To Send */
-#define                     nMRTS  0x0       
 #define                      RFIT  0x4        /* Receive FIFO IRQ Threshold */
-#define                     nRFIT  0x0       
 #define                      RFRT  0x8        /* Receive FIFO RTS Threshold */
-#define                     nRFRT  0x0       
 #define                  LOOP_ENA  0x10       /* Loopback Mode Enable */
-#define                 nLOOP_ENA  0x0       
 #define                     FCPOL  0x20       /* Flow Control Pin Polarity */
-#define                    nFCPOL  0x0       
 #define                      ARTS  0x40       /* Automatic Request To Send */
-#define                     nARTS  0x0       
 #define                      ACTS  0x80       /* Automatic Clear To Send */
-#define                     nACTS  0x0       
 
 /* Bit masks for UARTx_LSR */
 
 #define                        DR  0x1        /* Data Ready */
-#define                       nDR  0x0       
 #define                        OE  0x2        /* Overrun Error */
-#define                       nOE  0x0       
 #define                        PE  0x4        /* Parity Error */
-#define                       nPE  0x0       
 #define                        FE  0x8        /* Framing Error */
-#define                       nFE  0x0       
 #define                        BI  0x10       /* Break Interrupt */
-#define                       nBI  0x0       
 #define                      THRE  0x20       /* THR Empty */
-#define                     nTHRE  0x0       
 #define                      TEMT  0x40       /* Transmitter Empty */
-#define                     nTEMT  0x0       
 #define                       TFI  0x80       /* Transmission Finished Indicator */
-#define                      nTFI  0x0       
 
 /* Bit masks for UARTx_MSR */
 
 #define                      SCTS  0x1        /* Sticky CTS */
-#define                     nSCTS  0x0       
 #define                       CTS  0x10       /* Clear To Send */
-#define                      nCTS  0x0       
 #define                      RFCS  0x20       /* Receive FIFO Count Status */
-#define                     nRFCS  0x0       
-
-/* Bit masks for UARTx_IER_SET */
-
-#define                   ERBFI_S  0x1        /* Enable Receive Buffer Full Interrupt */
-#define                  nERBFI_S  0x0       
-#define                   ETBEI_S  0x2        /* Enable Transmit Buffer Empty Interrupt */
-#define                  nETBEI_S  0x0       
-#define                    ELSI_S  0x4        /* Enable Receive Status Interrupt */
-#define                   nELSI_S  0x0       
-#define                   EDSSI_S  0x8        /* Enable Modem Status Interrupt */
-#define                  nEDSSI_S  0x0       
-#define                  EDTPTI_S  0x10       /* Enable DMA Transmit PIRQ Interrupt */
-#define                 nEDTPTI_S  0x0       
-#define                    ETFI_S  0x20       /* Enable Transmission Finished Interrupt */
-#define                   nETFI_S  0x0       
-#define                   ERFCI_S  0x40       /* Enable Receive FIFO Count Interrupt */
-#define                  nERFCI_S  0x0       
-
-/* Bit masks for UARTx_IER_CLEAR */
-
-#define                   ERBFI_C  0x1        /* Enable Receive Buffer Full Interrupt */
-#define                  nERBFI_C  0x0       
-#define                   ETBEI_C  0x2        /* Enable Transmit Buffer Empty Interrupt */
-#define                  nETBEI_C  0x0       
-#define                    ELSI_C  0x4        /* Enable Receive Status Interrupt */
-#define                   nELSI_C  0x0       
-#define                   EDSSI_C  0x8        /* Enable Modem Status Interrupt */
-#define                  nEDSSI_C  0x0       
-#define                  EDTPTI_C  0x10       /* Enable DMA Transmit PIRQ Interrupt */
-#define                 nEDTPTI_C  0x0       
-#define                    ETFI_C  0x20       /* Enable Transmission Finished Interrupt */
-#define                   nETFI_C  0x0       
-#define                   ERFCI_C  0x40       /* Enable Receive FIFO Count Interrupt */
-#define                  nERFCI_C  0x0       
+
+/* Bit masks for UARTx_IER_SET & UARTx_IER_CLEAR */
+
+#define                   ERBFI  0x1        /* Enable Receive Buffer Full Interrupt */
+#define                   ETBEI  0x2        /* Enable Transmit Buffer Empty Interrupt */
+#define                    ELSI  0x4        /* Enable Receive Status Interrupt */
+#define                   EDSSI  0x8        /* Enable Modem Status Interrupt */
+#define                  EDTPTI  0x10       /* Enable DMA Transmit PIRQ Interrupt */
+#define                    ETFI  0x20       /* Enable Transmission Finished Interrupt */
+#define                   ERFCI  0x40       /* Enable Receive FIFO Count Interrupt */
 
 /* Bit masks for UARTx_GCTL */
 
 #define                      UCEN  0x1        /* UART Enable */
-#define                     nUCEN  0x0       
 #define                      IREN  0x2        /* IrDA Mode Enable */
-#define                     nIREN  0x0       
 #define                     TPOLC  0x4        /* IrDA TX Polarity Change */
-#define                    nTPOLC  0x0       
 #define                     RPOLC  0x8        /* IrDA RX Polarity Change */
-#define                    nRPOLC  0x0       
 #define                       FPE  0x10       /* Force Parity Error */
-#define                      nFPE  0x0       
 #define                       FFE  0x20       /* Force Framing Error */
-#define                      nFFE  0x0       
 #define                      EDBO  0x40       /* Enable Divide-by-One */
-#define                     nEDBO  0x0       
 #define                     EGLSI  0x80       /* Enable Global LS Interrupt */
-#define                    nEGLSI  0x0       
 
 
 /* ******************************************* */
 /* BCODE bit field options (SYSCFG register) */
 
 #define BCODE_WAKEUP    0x0000  /* boot according to wake-up condition */
-#define BCODE_FULLBOOT  0x0010  /* always perform full boot */ 
+#define BCODE_FULLBOOT  0x0010  /* always perform full boot */
 #define BCODE_QUICKBOOT 0x0020  /* always perform quick boot */
 #define BCODE_NOBOOT    0x0030  /* always perform full boot */
 
 /* CNT_COMMAND bit field options */
+
 #define W1LCNT_ZERO   0x0001   /* write 1 to load CNT_COUNTER with zero */
 #define W1LCNT_MIN    0x0004   /* write 1 to load CNT_COUNTER from CNT_MIN */
 #define W1LCNT_MAX    0x0008   /* write 1 to load CNT_COUNTER from CNT_MAX */
+
 #define W1LMIN_ZERO   0x0010   /* write 1 to load CNT_MIN with zero */
 #define W1LMIN_CNT    0x0020   /* write 1 to load CNT_MIN from CNT_COUNTER */
 #define W1LMIN_MAX    0x0080   /* write 1 to load CNT_MIN from CNT_MAX */
+
 #define W1LMAX_ZERO   0x0100   /* write 1 to load CNT_MAX with zero */
 #define W1LMAX_CNT    0x0200   /* write 1 to load CNT_MAX from CNT_COUNTER */
 #define W1LMAX_MIN    0x0400   /* write 1 to load CNT_MAX from CNT_MIN */
+
 /* CNT_CONFIG bit field options */
+
 #define CNTMODE_QUADENC  0x0000  /* quadrature encoder mode */
 #define CNTMODE_BINENC   0x0100  /* binary encoder mode */
 #define CNTMODE_UDCNT    0x0200  /* up/down counter mode */
 #define CNTMODE_DIRCNT   0x0400  /* direction counter mode */
 #define CNTMODE_DIRTMR   0x0500  /* direction timer mode */
+
 #define BNDMODE_COMP     0x0000  /* boundary compare mode */
 #define BNDMODE_ZERO     0x1000  /* boundary compare and zero mode */
 #define BNDMODE_CAPT     0x2000  /* boundary capture mode */
 #define EXT_CLK  0x0003
 
 /* UARTx_LCR bit field options */
+
 #define WLS_5   0x0000    /* 5 data bits */
 #define WLS_6   0x0001    /* 6 data bits */
 #define WLS_7   0x0002    /* 7 data bits */
 #define PIQ30 0x40000000
 #define PIQ31 0x80000000
 
-/* PORT A Bit Definitions for the registers 
+/* PORT A Bit Definitions for the registers
 PORTA, PORTA_SET, PORTA_CLEAR,
 PORTA_DIR_SET, PORTA_DIR_CLEAR, PORTA_INEN,
 PORTA_FER registers
@@ -4507,7 +3483,7 @@ PORTA_FER registers
 #define PA14 0x4000
 #define PA15 0x8000
 
-/* PORT B Bit Definitions for the registers 
+/* PORT B Bit Definitions for the registers
 PORTB, PORTB_SET, PORTB_CLEAR,
 PORTB_DIR_SET, PORTB_DIR_CLEAR, PORTB_INEN,
 PORTB_FER registers
@@ -4530,7 +3506,7 @@ PORTB_FER registers
 #define PB14 0x4000
 
 
-/* PORT C Bit Definitions for the registers 
+/* PORT C Bit Definitions for the registers
 PORTC, PORTC_SET, PORTC_CLEAR,
 PORTC_DIR_SET, PORTC_DIR_CLEAR, PORTC_INEN,
 PORTC_FER registers
@@ -4553,7 +3529,7 @@ PORTC_FER registers
 #define PC13 0x2000
 
 
-/* PORT D Bit Definitions for the registers 
+/* PORT D Bit Definitions for the registers
 PORTD, PORTD_SET, PORTD_CLEAR,
 PORTD_DIR_SET, PORTD_DIR_CLEAR, PORTD_INEN,
 PORTD_FER registers
@@ -4576,7 +3552,7 @@ PORTD_FER registers
 #define PD14 0x4000
 #define PD15 0x8000
 
-/* PORT E Bit Definitions for the registers 
+/* PORT E Bit Definitions for the registers
 PORTE, PORTE_SET, PORTE_CLEAR,
 PORTE_DIR_SET, PORTE_DIR_CLEAR, PORTE_INEN,
 PORTE_FER registers
@@ -4600,7 +3576,7 @@ PORTE_FER registers
 #define PE14 0x4000
 #define PE15 0x8000
 
-/* PORT F Bit Definitions for the registers 
+/* PORT F Bit Definitions for the registers
 PORTF, PORTF_SET, PORTF_CLEAR,
 PORTF_DIR_SET, PORTF_DIR_CLEAR, PORTF_INEN,
 PORTF_FER registers
@@ -4624,7 +3600,7 @@ PORTF_FER registers
 #define PF14 0x4000
 #define PF15 0x8000
 
-/* PORT G Bit Definitions for the registers 
+/* PORT G Bit Definitions for the registers
 PORTG, PORTG_SET, PORTG_CLEAR,
 PORTG_DIR_SET, PORTG_DIR_CLEAR, PORTG_INEN,
 PORTG_FER registers
@@ -4648,7 +3624,7 @@ PORTG_FER registers
 #define PG14 0x4000
 #define PG15 0x8000
 
-/* PORT H Bit Definitions for the registers 
+/* PORT H Bit Definitions for the registers
 PORTH, PORTH_SET, PORTH_CLEAR,
 PORTH_DIR_SET, PORTH_DIR_CLEAR, PORTH_INEN,
 PORTH_FER registers
@@ -4671,7 +3647,7 @@ PORTH_FER registers
 #define PH13 0x2000
 
 
-/* PORT I Bit Definitions for the registers 
+/* PORT I Bit Definitions for the registers
 PORTI, PORTI_SET, PORTI_CLEAR,
 PORTI_DIR_SET, PORTI_DIR_CLEAR, PORTI_INEN,
 PORTI_FER registers
@@ -4695,7 +3671,7 @@ PORTI_FER registers
 #define PI14 0x4000
 #define PI15 0x8000
 
-/* PORT J Bit Definitions for the registers 
+/* PORT J Bit Definitions for the registers
 PORTJ, PORTJ_SET, PORTJ_CLEAR,
 PORTJ_DIR_SET, PORTJ_DIR_CLEAR, PORTJ_INEN,
 PORTJ_FER registers
@@ -4716,7 +3692,7 @@ PORTJ_FER registers
 #define PJ11 0x0800
 #define PJ12 0x1000
 #define PJ13 0x2000
+
 
 /* Port Muxing Bit Fields for PORTx_MUX Registers */
 
@@ -4860,7 +3836,7 @@ PORTJ_FER registers
 #define B0MAP_PIL 0x00000006 /* Map Port I Low to Byte 0 */
 #define B0MAP_PJL 0x00000007 /* Map Port J Low to Byte 0 */
 
-#define B1MAP_PCH 0x00000000 /* Map Port C High to Byte 1 */ 
+#define B1MAP_PCH 0x00000000 /* Map Port C High to Byte 1 */
 #define B1MAP_PDH 0x00000100 /* Map Port D High to Byte 1 */
 #define B1MAP_PEH 0x00000200 /* Map Port E High to Byte 1 */
 #define B1MAP_PFH 0x00000300 /* Map Port F High to Byte 1 */
@@ -4869,27 +3845,27 @@ PORTJ_FER registers
 #define B1MAP_PIH 0x00000600 /* Map Port I High to Byte 1 */
 #define B1MAP_PJH 0x00000700 /* Map Port J High to Byte 1 */
 
-#define B2MAP_PCL 0x00000000 /* Map Port C Low to Byte 2 */ 
-#define B2MAP_PDL 0x00010000 /* Map Port D Low to Byte 2 */ 
-#define B2MAP_PEL 0x00020000 /* Map Port E Low to Byte 2 */ 
-#define B2MAP_PFL 0x00030000 /* Map Port F Low to Byte 2 */ 
-#define B2MAP_PGL 0x00040000 /* Map Port G Low to Byte 2 */ 
-#define B2MAP_PHL 0x00050000 /* Map Port H Low to Byte 2 */ 
-#define B2MAP_PIL 0x00060000 /* Map Port I Low to Byte 2 */ 
-#define B2MAP_PJL 0x00070000 /* Map Port J Low to Byte 2 */ 
-
-#define B3MAP_PCH 0x00000000 /* Map Port C High to Byte 3 */ 
-#define B3MAP_PDH 0x01000000 /* Map Port D High to Byte 3 */ 
-#define B3MAP_PEH 0x02000000 /* Map Port E High to Byte 3 */ 
-#define B3MAP_PFH 0x03000000 /* Map Port F High to Byte 3 */ 
-#define B3MAP_PGH 0x04000000 /* Map Port G High to Byte 3 */ 
-#define B3MAP_PHH 0x05000000 /* Map Port H High to Byte 3 */ 
-#define B3MAP_PIH 0x06000000 /* Map Port I High to Byte 3 */ 
-#define B3MAP_PJH 0x07000000 /* Map Port J High to Byte 3 */ 
+#define B2MAP_PCL 0x00000000 /* Map Port C Low to Byte 2 */
+#define B2MAP_PDL 0x00010000 /* Map Port D Low to Byte 2 */
+#define B2MAP_PEL 0x00020000 /* Map Port E Low to Byte 2 */
+#define B2MAP_PFL 0x00030000 /* Map Port F Low to Byte 2 */
+#define B2MAP_PGL 0x00040000 /* Map Port G Low to Byte 2 */
+#define B2MAP_PHL 0x00050000 /* Map Port H Low to Byte 2 */
+#define B2MAP_PIL 0x00060000 /* Map Port I Low to Byte 2 */
+#define B2MAP_PJL 0x00070000 /* Map Port J Low to Byte 2 */
+
+#define B3MAP_PCH 0x00000000 /* Map Port C High to Byte 3 */
+#define B3MAP_PDH 0x01000000 /* Map Port D High to Byte 3 */
+#define B3MAP_PEH 0x02000000 /* Map Port E High to Byte 3 */
+#define B3MAP_PFH 0x03000000 /* Map Port F High to Byte 3 */
+#define B3MAP_PGH 0x04000000 /* Map Port G High to Byte 3 */
+#define B3MAP_PHH 0x05000000 /* Map Port H High to Byte 3 */
+#define B3MAP_PIH 0x06000000 /* Map Port I High to Byte 3 */
+#define B3MAP_PJH 0x07000000 /* Map Port J High to Byte 3 */
 
 
 /* for legacy compatibility */
+
 #define WLS(x)  (((x)-5) & 0x03) /* Word Length Select */
 #define W1LMAX_MAX W1LMAX_MIN
 #define EBIU_AMCBCTL0 EBIU_AMBCTL0
diff --git a/include/asm-blackfin/mach-bf548/dma.h b/include/asm-blackfin/mach-bf548/dma.h
new file mode 100644 (file)
index 0000000..fcc8b4c
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * file:         include/asm-blackfin/mach-bf548/dma.h
+ * based on:
+ * author:
+ *
+ * created:
+ * description:
+ *     system mmr register map
+ * rev:
+ *
+ * modified:
+ *
+ *
+ * bugs:         enter bugs at http://blackfin.uclinux.org/
+ *
+ * this program is free software; you can redistribute it and/or modify
+ * it under the terms of the gnu general public license as published by
+ * the free software foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * this program is distributed in the hope that it will be useful,
+ * but without any warranty; without even the implied warranty of
+ * merchantability or fitness for a particular purpose.  see the
+ * gnu general public license for more details.
+ *
+ * you should have received a copy of the gnu general public license
+ * along with this program; see the file copying.
+ * if not, write to the free software foundation,
+ * 59 temple place - suite 330, boston, ma 02111-1307, usa.
+ */
+
+#ifndef _MACH_DMA_H_
+#define _MACH_DMA_H_
+
+#define CH_SPORT0_RX           0
+#define CH_SPORT0_TX           1
+#define CH_SPORT1_RX           2
+#define CH_SPORT1_TX           3
+#define CH_SPI0                        4
+#define CH_SPI1                        5
+#define CH_UART0_RX            6
+#define CH_UART0_TX            7
+#define CH_UART1_RX            8
+#define CH_UART1_TX            9
+#define CH_ATAPI_RX            10
+#define CH_ATAPI_TX            11
+#define CH_EPPI0               12
+#define CH_EPPI1               13
+#define CH_EPPI2               14
+#define CH_PIXC_IMAGE          15
+#define CH_PIXC_OVERLAY                16
+#define CH_PIXC_OUTPUT         17
+#define CH_SPORT2_RX           18
+#define CH_SPORT2_TX           19
+#define CH_SPORT3_RX           20
+#define CH_SPORT3_TX           21
+#define CH_SDH                 22
+#define CH_SPI2                        23
+
+#define CH_MEM_STREAM0_DEST    24
+#define CH_MEM_STREAM0_SRC     25
+#define CH_MEM_STREAM1_DEST    26
+#define CH_MEM_STREAM1_SRC     27
+#define CH_MEM_STREAM2_DEST    28
+#define CH_MEM_STREAM2_SRC     29
+#define CH_MEM_STREAM3_DEST    30
+#define CH_MEM_STREAM3_SRC     31
+
+#define MAX_BLACKFIN_DMA_CHANNEL 32
+
+extern int channel2irq(unsigned int channel);
+extern struct dma_register *base_addr[];
+#endif
diff --git a/include/asm-blackfin/mach-bf548/gpio.h b/include/asm-blackfin/mach-bf548/gpio.h
new file mode 100644 (file)
index 0000000..dbf66bc
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ * File:         include/asm-blackfin/mach-bf548/gpio.h
+ * Based on:
+ * Author:      Michael Hennerich (hennerich@blackfin.uclinux.org)
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ *               Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+
+
+#define GPIO_PA0       0
+#define GPIO_PA1       1
+#define GPIO_PA2       2
+#define GPIO_PA3       3
+#define GPIO_PA4       4
+#define GPIO_PA5       5
+#define GPIO_PA6       6
+#define GPIO_PA7       7
+#define GPIO_PA8       8
+#define GPIO_PA9       9
+#define GPIO_PA10      10
+#define GPIO_PA11      11
+#define GPIO_PA12      12
+#define GPIO_PA13      13
+#define GPIO_PA14      14
+#define GPIO_PA15      15
+#define GPIO_PB0       16
+#define GPIO_PB1       17
+#define GPIO_PB2       18
+#define GPIO_PB3       19
+#define GPIO_PB4       20
+#define GPIO_PB5       21
+#define GPIO_PB6       22
+#define GPIO_PB7       23
+#define GPIO_PB8       24
+#define GPIO_PB9       25
+#define GPIO_PB10      26
+#define GPIO_PB11      27
+#define GPIO_PB12      28
+#define GPIO_PB13      29
+#define GPIO_PB14      30
+#define GPIO_PB15      31      /* N/A */
+#define GPIO_PC0       32
+#define GPIO_PC1       33
+#define GPIO_PC2       34
+#define GPIO_PC3       35
+#define GPIO_PC4       36
+#define GPIO_PC5       37
+#define GPIO_PC6       38
+#define GPIO_PC7       39
+#define GPIO_PC8       40
+#define GPIO_PC9       41
+#define GPIO_PC10      42
+#define GPIO_PC11      43
+#define GPIO_PC12      44
+#define GPIO_PC13      45
+#define GPIO_PC14      46      /* N/A */
+#define GPIO_PC15      47      /* N/A */
+#define GPIO_PD0       48
+#define GPIO_PD1       49
+#define GPIO_PD2       50
+#define GPIO_PD3       51
+#define GPIO_PD4       52
+#define GPIO_PD5       53
+#define GPIO_PD6       54
+#define GPIO_PD7       55
+#define GPIO_PD8       56
+#define GPIO_PD9       57
+#define GPIO_PD10      58
+#define GPIO_PD11      59
+#define GPIO_PD12      60
+#define GPIO_PD13      61
+#define GPIO_PD14      62
+#define GPIO_PD15      63
+#define GPIO_PE0       64
+#define GPIO_PE1       65
+#define GPIO_PE2       66
+#define GPIO_PE3       67
+#define GPIO_PE4       68
+#define GPIO_PE5       69
+#define GPIO_PE6       70
+#define GPIO_PE7       71
+#define GPIO_PE8       72
+#define GPIO_PE9       73
+#define GPIO_PE10      74
+#define GPIO_PE11      75
+#define GPIO_PE12      76
+#define GPIO_PE13      77
+#define GPIO_PE14      78
+#define GPIO_PE15      79
+#define GPIO_PF0       80
+#define GPIO_PF1       81
+#define GPIO_PF2       82
+#define GPIO_PF3       83
+#define GPIO_PF4       84
+#define GPIO_PF5       85
+#define GPIO_PF6       86
+#define GPIO_PF7       87
+#define GPIO_PF8       88
+#define GPIO_PF9       89
+#define GPIO_PF10      90
+#define GPIO_PF11      91
+#define GPIO_PF12      92
+#define GPIO_PF13      93
+#define GPIO_PF14      94
+#define GPIO_PF15      95
+#define GPIO_PG0       96
+#define GPIO_PG1       97
+#define GPIO_PG2       98
+#define GPIO_PG3       99
+#define GPIO_PG4       100
+#define GPIO_PG5       101
+#define GPIO_PG6       102
+#define GPIO_PG7       103
+#define GPIO_PG8       104
+#define GPIO_PG9       105
+#define GPIO_PG10      106
+#define GPIO_PG11      107
+#define GPIO_PG12      108
+#define GPIO_PG13      109
+#define GPIO_PG14      110
+#define GPIO_PG15      111
+#define GPIO_PH0       112
+#define GPIO_PH1       113
+#define GPIO_PH2       114
+#define GPIO_PH3       115
+#define GPIO_PH4       116
+#define GPIO_PH5       117
+#define GPIO_PH6       118
+#define GPIO_PH7       119
+#define GPIO_PH8       120
+#define GPIO_PH9       121
+#define GPIO_PH10      122
+#define GPIO_PH11      123
+#define GPIO_PH12      124
+#define GPIO_PH13      125
+#define GPIO_PH14      126     /* N/A */
+#define GPIO_PH15      127     /* N/A */
+#define GPIO_PI0       128
+#define GPIO_PI1       129
+#define GPIO_PI2       130
+#define GPIO_PI3       131
+#define GPIO_PI4       132
+#define GPIO_PI5       133
+#define GPIO_PI6       134
+#define GPIO_PI7       135
+#define GPIO_PI8       136
+#define GPIO_PI9       137
+#define GPIO_PI10      138
+#define GPIO_PI11      139
+#define GPIO_PI12      140
+#define GPIO_PI13      141
+#define GPIO_PI14      142
+#define GPIO_PI15      143
+#define GPIO_PJ0       144
+#define GPIO_PJ1       145
+#define GPIO_PJ2       146
+#define GPIO_PJ3       147
+#define GPIO_PJ4       148
+#define GPIO_PJ5       149
+#define GPIO_PJ6       150
+#define GPIO_PJ7       151
+#define GPIO_PJ8       152
+#define GPIO_PJ9       153
+#define GPIO_PJ10      154
+#define GPIO_PJ11      155
+#define GPIO_PJ12      156
+#define GPIO_PJ13      157
+#define GPIO_PJ14      158     /* N/A */
+#define GPIO_PJ15      159     /* N/A */
+
+#define MAX_BLACKFIN_GPIOS 160
+
+struct gpio_port_t {
+       unsigned short port_fer;
+       unsigned short dummy1;
+       unsigned short port_data;
+       unsigned short dummy2;
+       unsigned short port_set;
+       unsigned short dummy3;
+       unsigned short port_clear;
+       unsigned short dummy4;
+       unsigned short port_dir_set;
+       unsigned short dummy5;
+       unsigned short port_dir_clear;
+       unsigned short dummy6;
+       unsigned short port_inen;
+       unsigned short dummy7;
+       unsigned int port_mux;
+};
+
+int gpio_request(unsigned short gpio, const char *label);
+void peripheral_free(unsigned short per);
+int peripheral_request_list(unsigned short per[], const char *label);
+void peripheral_free_list(unsigned short per[]);
diff --git a/include/asm-blackfin/mach-bf548/irq.h b/include/asm-blackfin/mach-bf548/irq.h
new file mode 100644 (file)
index 0000000..0b3325b
--- /dev/null
@@ -0,0 +1,467 @@
+/*
+ * file:       include/asm-blackfin/mach-bf548/irq.h
+ * based on:   include/asm-blackfin/mach-bf537/irq.h
+ * author:     Roy Huang (roy.huang@analog.com)
+ *
+ * created:
+ * description:
+ *     system mmr register map
+ * rev:
+ *
+ * modified:
+ *
+ *
+ * bugs:         enter bugs at http://blackfin.uclinux.org/
+ *
+ * this program is free software; you can redistribute it and/or modify
+ * it under the terms of the gnu general public license as published by
+ * the free software foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * this program is distributed in the hope that it will be useful,
+ * but without any warranty; without even the implied warranty of
+ * merchantability or fitness for a particular purpose.  see the
+ * gnu general public license for more details.
+ *
+ * you should have received a copy of the gnu general public license
+ * along with this program; see the file copying.
+ * if not, write to the free software foundation,
+ * 59 temple place - suite 330, boston, ma 02111-1307, usa.
+ */
+
+#ifndef _BF548_IRQ_H_
+#define _BF548_IRQ_H_
+
+/*
+ * Interrupt source definitions
+            Event Source    Core Event Name
+Core        Emulation               **
+Events         (highest priority)  EMU         0
+            Reset                   RST         1
+            NMI                     NMI         2
+            Exception               EVX         3
+            Reserved                --          4
+            Hardware Error          IVHW        5
+            Core Timer              IVTMR       6 *
+
+.....
+
+            Software Interrupt 1    IVG14       31
+            Software Interrupt 2    --
+                 (lowest priority)  IVG15       32 *
+ */
+
+#define NR_PERI_INTS    (32 * 3)
+
+/* The ABSTRACT IRQ definitions */
+/** the first seven of the following are fixed, the rest you change if you need to **/
+#define IRQ_EMU                0       /* Emulation */
+#define IRQ_RST                1       /* reset */
+#define IRQ_NMI                2       /* Non Maskable */
+#define IRQ_EVX                3       /* Exception */
+#define IRQ_UNUSED     4       /* - unused interrupt*/
+#define IRQ_HWERR      5       /* Hardware Error */
+#define IRQ_CORETMR    6       /* Core timer */
+
+#define BFIN_IRQ(x)    ((x) + 7)
+
+#define IRQ_PLL_WAKEUP BFIN_IRQ(0)     /* PLL Wakeup Interrupt */
+#define IRQ_DMAC0_ERR  BFIN_IRQ(1)     /* DMAC0 Status Interrupt */
+#define IRQ_EPPI0_ERR  BFIN_IRQ(2)     /* EPPI0 Error Interrupt */
+#define IRQ_SPORT0_ERR BFIN_IRQ(3)     /* SPORT0 Error Interrupt */
+#define IRQ_SPORT1_ERR BFIN_IRQ(4)     /* SPORT1 Error Interrupt */
+#define IRQ_SPI0_ERR   BFIN_IRQ(5)     /* SPI0 Status(Error) Interrupt */
+#define IRQ_UART0_ERR  BFIN_IRQ(6)     /* UART0 Status(Error) Interrupt */
+#define IRQ_RTC                BFIN_IRQ(7)     /* RTC Interrupt */
+#define IRQ_EPPI0      BFIN_IRQ(8)     /* EPPI0 Interrupt (DMA12) */
+#define IRQ_SPORT0_RX  BFIN_IRQ(9)     /* SPORT0 RX Interrupt (DMA0) */
+#define IRQ_SPORT0_TX  BFIN_IRQ(10)    /* SPORT0 TX Interrupt (DMA1) */
+#define IRQ_SPORT1_RX  BFIN_IRQ(11)    /* SPORT1 RX Interrupt (DMA2) */
+#define IRQ_SPORT1_TX  BFIN_IRQ(12)    /* SPORT1 TX Interrupt (DMA3) */
+#define IRQ_SPI0       BFIN_IRQ(13)    /* SPI0 Interrupt (DMA4) */
+#define IRQ_UART0_RX   BFIN_IRQ(14)    /* UART0 RX Interrupt (DMA6) */
+#define IRQ_UART0_TX   BFIN_IRQ(15)    /* UART0 TX Interrupt (DMA7) */
+#define IRQ_TIMER8     BFIN_IRQ(16)    /* TIMER 8 Interrupt */
+#define IRQ_TIMER9     BFIN_IRQ(17)    /* TIMER 9 Interrupt */
+#define IRQ_TIMER10    BFIN_IRQ(18)    /* TIMER 10 Interrupt */
+#define IRQ_PINT0      BFIN_IRQ(19)    /* PINT0 Interrupt */
+#define IRQ_PINT1      BFIN_IRQ(20)    /* PINT1 Interrupt */
+#define IRQ_MDMAS0     BFIN_IRQ(21)    /* MDMA Stream 0 Interrupt */
+#define IRQ_MDMAS1     BFIN_IRQ(22)    /* MDMA Stream 1 Interrupt */
+#define IRQ_WATCHDOG   BFIN_IRQ(23)    /* Watchdog Interrupt */
+#define IRQ_DMAC1_ERR  BFIN_IRQ(24)    /* DMAC1 Status (Error) Interrupt */
+#define IRQ_SPORT2_ERR BFIN_IRQ(25)    /* SPORT2 Error Interrupt */
+#define IRQ_SPORT3_ERR BFIN_IRQ(26)    /* SPORT3 Error Interrupt */
+#define IRQ_MXVR_DATA  BFIN_IRQ(27)    /* MXVR Data Interrupt */
+#define IRQ_SPI1_ERR   BFIN_IRQ(28)    /* SPI1 Status (Error) Interrupt */
+#define IRQ_SPI2_ERR   BFIN_IRQ(29)    /* SPI2 Status (Error) Interrupt */
+#define IRQ_UART1_ERR  BFIN_IRQ(30)    /* UART1 Status (Error) Interrupt */
+#define IRQ_UART2_ERR  BFIN_IRQ(31)    /* UART2 Status (Error) Interrupt */
+#define IRQ_CAN0_ERR   BFIN_IRQ(32)    /* CAN0 Status (Error) Interrupt */
+#define IRQ_SPORT2_RX  BFIN_IRQ(33)    /* SPORT2 RX (DMA18) Interrupt */
+#define IRQ_SPORT2_TX  BFIN_IRQ(34)    /* SPORT2 TX (DMA19) Interrupt */
+#define IRQ_SPORT3_RX  BFIN_IRQ(35)    /* SPORT3 RX (DMA20) Interrupt */
+#define IRQ_SPORT3_TX  BFIN_IRQ(36)    /* SPORT3 TX (DMA21) Interrupt */
+#define IRQ_EPPI1      BFIN_IRQ(37)    /* EPP1 (DMA13) Interrupt */
+#define IRQ_EPPI2      BFIN_IRQ(38)    /* EPP2 (DMA14) Interrupt */
+#define IRQ_SPI1       BFIN_IRQ(39)    /* SPI1 (DMA5) Interrupt */
+#define IRQ_SPI2       BFIN_IRQ(40)    /* SPI2 (DMA23) Interrupt */
+#define IRQ_UART1_RX   BFIN_IRQ(41)    /* UART1 RX (DMA8) Interrupt */
+#define IRQ_UART1_TX   BFIN_IRQ(42)    /* UART1 TX (DMA9) Interrupt */
+#define IRQ_ATAPI_RX   BFIN_IRQ(43)    /* ATAPI RX (DMA10) Interrupt */
+#define IRQ_ATAPI_TX   BFIN_IRQ(44)    /* ATAPI TX (DMA11) Interrupt */
+#define IRQ_TWI0       BFIN_IRQ(45)    /* TWI0 Interrupt */
+#define IRQ_TWI1       BFIN_IRQ(46)    /* TWI1 Interrupt */
+#define IRQ_CAN0_RX    BFIN_IRQ(47)    /* CAN0 Receive Interrupt */
+#define IRQ_CAN0_TX    BFIN_IRQ(48)    /* CAN0 Transmit Interrupt */
+#define IRQ_MDMAS2     BFIN_IRQ(49)    /* MDMA Stream 2 Interrupt */
+#define IRQ_MDMAS3     BFIN_IRQ(50)    /* MDMA Stream 3 Interrupt */
+#define IRQ_MXVR_ERR   BFIN_IRQ(51)    /* MXVR Status (Error) Interrupt */
+#define IRQ_MXVR_MSG   BFIN_IRQ(52)    /* MXVR Message Interrupt */
+#define IRQ_MXVR_PKT   BFIN_IRQ(53)    /* MXVR Packet Interrupt */
+#define IRQ_EPP1_ERR   BFIN_IRQ(54)    /* EPPI1 Error Interrupt */
+#define IRQ_EPP2_ERR   BFIN_IRQ(55)    /* EPPI2 Error Interrupt */
+#define IRQ_UART3_ERR  BFIN_IRQ(56)    /* UART3 Status (Error) Interrupt */
+#define IRQ_HOST_ERR   BFIN_IRQ(57)    /* HOST Status (Error) Interrupt */
+#define IRQ_PIXC_ERR   BFIN_IRQ(59)    /* PIXC Status (Error) Interrupt */
+#define IRQ_NFC_ERR    BFIN_IRQ(60)    /* NFC Error Interrupt */
+#define IRQ_ATAPI_ERR  BFIN_IRQ(61)    /* ATAPI Error Interrupt */
+#define IRQ_CAN1_ERR   BFIN_IRQ(62)    /* CAN1 Status (Error) Interrupt */
+#define IRQ_HS_DMA_ERR BFIN_IRQ(63)    /* Handshake DMA Status Interrupt */
+#define IRQ_PIXC_IN0   BFIN_IRQ(64)    /* PIXC IN0 (DMA15) Interrupt */
+#define IRQ_PIXC_IN1   BFIN_IRQ(65)    /* PIXC IN1 (DMA16) Interrupt */
+#define IRQ_PIXC_OUT   BFIN_IRQ(66)    /* PIXC OUT (DMA17) Interrupt */
+#define IRQ_SDH                BFIN_IRQ(67)    /* SDH/NFC (DMA22) Interrupt */
+#define IRQ_CNT                BFIN_IRQ(68)    /* CNT Interrupt */
+#define IRQ_KEY                BFIN_IRQ(69)    /* KEY Interrupt */
+#define IRQ_CAN1_RX    BFIN_IRQ(70)    /* CAN1 RX Interrupt */
+#define IRQ_CAN1_TX    BFIN_IRQ(71)    /* CAN1 TX Interrupt */
+#define IRQ_SDH_MASK0  BFIN_IRQ(72)    /* SDH Mask 0 Interrupt */
+#define IRQ_SDH_MASK1  BFIN_IRQ(73)    /* SDH Mask 1 Interrupt */
+#define IRQ_USB_INT0   BFIN_IRQ(75)    /* USB INT0 Interrupt */
+#define IRQ_USB_INT1   BFIN_IRQ(76)    /* USB INT1 Interrupt */
+#define IRQ_USB_INT2   BFIN_IRQ(77)    /* USB INT2 Interrupt */
+#define IRQ_USB_DMA    BFIN_IRQ(78)    /* USB DMA Interrupt */
+#define IRQ_OPTSEC     BFIN_IRQ(79)    /* OTPSEC Interrupt */
+#define IRQ_TIMER0     BFIN_IRQ(86)    /* Timer 0 Interrupt */
+#define IRQ_TIMER1     BFIN_IRQ(87)    /* Timer 1 Interrupt */
+#define IRQ_TIMER2     BFIN_IRQ(88)    /* Timer 2 Interrupt */
+#define IRQ_TIMER3     BFIN_IRQ(89)    /* Timer 3 Interrupt */
+#define IRQ_TIMER4     BFIN_IRQ(90)    /* Timer 4 Interrupt */
+#define IRQ_TIMER5     BFIN_IRQ(91)    /* Timer 5 Interrupt */
+#define IRQ_TIMER6     BFIN_IRQ(92)    /* Timer 6 Interrupt */
+#define IRQ_TIMER7     BFIN_IRQ(93)    /* Timer 7 Interrupt */
+#define IRQ_PINT2      BFIN_IRQ(94)    /* PINT2 Interrupt */
+#define IRQ_PINT3      BFIN_IRQ(95)    /* PINT3 Interrupt */
+
+#define SYS_IRQS        IRQ_PINT3
+
+#define BFIN_PA_IRQ(x) ((x) + SYS_IRQS + 1)
+#define IRQ_PA0                BFIN_PA_IRQ(0)
+#define IRQ_PA1                BFIN_PA_IRQ(1)
+#define IRQ_PA2                BFIN_PA_IRQ(2)
+#define IRQ_PA3                BFIN_PA_IRQ(3)
+#define IRQ_PA4                BFIN_PA_IRQ(4)
+#define IRQ_PA5                BFIN_PA_IRQ(5)
+#define IRQ_PA6                BFIN_PA_IRQ(6)
+#define IRQ_PA7                BFIN_PA_IRQ(7)
+#define IRQ_PA8                BFIN_PA_IRQ(8)
+#define IRQ_PA9                BFIN_PA_IRQ(9)
+#define IRQ_PA10       BFIN_PA_IRQ(10)
+#define IRQ_PA11       BFIN_PA_IRQ(11)
+#define IRQ_PA12       BFIN_PA_IRQ(12)
+#define IRQ_PA13       BFIN_PA_IRQ(13)
+#define IRQ_PA14       BFIN_PA_IRQ(14)
+#define IRQ_PA15       BFIN_PA_IRQ(15)
+
+#define BFIN_PB_IRQ(x) ((x) + IRQ_PA15 + 1)
+#define IRQ_PB0                BFIN_PB_IRQ(0)
+#define IRQ_PB1                BFIN_PB_IRQ(1)
+#define IRQ_PB2                BFIN_PB_IRQ(2)
+#define IRQ_PB3                BFIN_PB_IRQ(3)
+#define IRQ_PB4                BFIN_PB_IRQ(4)
+#define IRQ_PB5                BFIN_PB_IRQ(5)
+#define IRQ_PB6                BFIN_PB_IRQ(6)
+#define IRQ_PB7                BFIN_PB_IRQ(7)
+#define IRQ_PB8                BFIN_PB_IRQ(8)
+#define IRQ_PB9                BFIN_PB_IRQ(9)
+#define IRQ_PB10       BFIN_PB_IRQ(10)
+#define IRQ_PB11       BFIN_PB_IRQ(11)
+#define IRQ_PB12       BFIN_PB_IRQ(12)
+#define IRQ_PB13       BFIN_PB_IRQ(13)
+#define IRQ_PB14       BFIN_PB_IRQ(14)
+#define IRQ_PB15       BFIN_PB_IRQ(15)         /* N/A */
+
+#define BFIN_PC_IRQ(x) ((x) + IRQ_PB15 + 1)
+#define IRQ_PC0                BFIN_PC_IRQ(0)
+#define IRQ_PC1                BFIN_PC_IRQ(1)
+#define IRQ_PC2                BFIN_PC_IRQ(2)
+#define IRQ_PC3                BFIN_PC_IRQ(3)
+#define IRQ_PC4                BFIN_PC_IRQ(4)
+#define IRQ_PC5                BFIN_PC_IRQ(5)
+#define IRQ_PC6                BFIN_PC_IRQ(6)
+#define IRQ_PC7                BFIN_PC_IRQ(7)
+#define IRQ_PC8                BFIN_PC_IRQ(8)
+#define IRQ_PC9                BFIN_PC_IRQ(9)
+#define IRQ_PC10       BFIN_PC_IRQ(10)
+#define IRQ_PC11       BFIN_PC_IRQ(11)
+#define IRQ_PC12       BFIN_PC_IRQ(12)
+#define IRQ_PC13       BFIN_PC_IRQ(13)
+#define IRQ_PC14       BFIN_PC_IRQ(14)         /* N/A */
+#define IRQ_PC15       BFIN_PC_IRQ(15)         /* N/A */
+
+#define BFIN_PD_IRQ(x) ((x) + IRQ_PC15 + 1)
+#define IRQ_PD0                BFIN_PD_IRQ(0)
+#define IRQ_PD1                BFIN_PD_IRQ(1)
+#define IRQ_PD2                BFIN_PD_IRQ(2)
+#define IRQ_PD3                BFIN_PD_IRQ(3)
+#define IRQ_PD4                BFIN_PD_IRQ(4)
+#define IRQ_PD5                BFIN_PD_IRQ(5)
+#define IRQ_PD6                BFIN_PD_IRQ(6)
+#define IRQ_PD7                BFIN_PD_IRQ(7)
+#define IRQ_PD8                BFIN_PD_IRQ(8)
+#define IRQ_PD9                BFIN_PD_IRQ(9)
+#define IRQ_PD10       BFIN_PD_IRQ(10)
+#define IRQ_PD11       BFIN_PD_IRQ(11)
+#define IRQ_PD12       BFIN_PD_IRQ(12)
+#define IRQ_PD13       BFIN_PD_IRQ(13)
+#define IRQ_PD14       BFIN_PD_IRQ(14)
+#define IRQ_PD15       BFIN_PD_IRQ(15)
+
+#define BFIN_PE_IRQ(x) ((x) + IRQ_PD15 + 1)
+#define IRQ_PE0                BFIN_PE_IRQ(0)
+#define IRQ_PE1                BFIN_PE_IRQ(1)
+#define IRQ_PE2                BFIN_PE_IRQ(2)
+#define IRQ_PE3                BFIN_PE_IRQ(3)
+#define IRQ_PE4                BFIN_PE_IRQ(4)
+#define IRQ_PE5                BFIN_PE_IRQ(5)
+#define IRQ_PE6                BFIN_PE_IRQ(6)
+#define IRQ_PE7                BFIN_PE_IRQ(7)
+#define IRQ_PE8                BFIN_PE_IRQ(8)
+#define IRQ_PE9                BFIN_PE_IRQ(9)
+#define IRQ_PE10       BFIN_PE_IRQ(10)
+#define IRQ_PE11       BFIN_PE_IRQ(11)
+#define IRQ_PE12       BFIN_PE_IRQ(12)
+#define IRQ_PE13       BFIN_PE_IRQ(13)
+#define IRQ_PE14       BFIN_PE_IRQ(14)
+#define IRQ_PE15       BFIN_PE_IRQ(15)
+
+#define BFIN_PF_IRQ(x) ((x) + IRQ_PE15 + 1)
+#define IRQ_PF0                BFIN_PF_IRQ(0)
+#define IRQ_PF1                BFIN_PF_IRQ(1)
+#define IRQ_PF2                BFIN_PF_IRQ(2)
+#define IRQ_PF3                BFIN_PF_IRQ(3)
+#define IRQ_PF4                BFIN_PF_IRQ(4)
+#define IRQ_PF5                BFIN_PF_IRQ(5)
+#define IRQ_PF6                BFIN_PF_IRQ(6)
+#define IRQ_PF7                BFIN_PF_IRQ(7)
+#define IRQ_PF8                BFIN_PF_IRQ(8)
+#define IRQ_PF9                BFIN_PF_IRQ(9)
+#define IRQ_PF10       BFIN_PF_IRQ(10)
+#define IRQ_PF11       BFIN_PF_IRQ(11)
+#define IRQ_PF12       BFIN_PF_IRQ(12)
+#define IRQ_PF13       BFIN_PF_IRQ(13)
+#define IRQ_PF14       BFIN_PF_IRQ(14)
+#define IRQ_PF15       BFIN_PF_IRQ(15)
+
+#define BFIN_PG_IRQ(x) ((x) + IRQ_PF15 + 1)
+#define IRQ_PG0                BFIN_PG_IRQ(0)
+#define IRQ_PG1                BFIN_PG_IRQ(1)
+#define IRQ_PG2                BFIN_PG_IRQ(2)
+#define IRQ_PG3                BFIN_PG_IRQ(3)
+#define IRQ_PG4                BFIN_PG_IRQ(4)
+#define IRQ_PG5                BFIN_PG_IRQ(5)
+#define IRQ_PG6                BFIN_PG_IRQ(6)
+#define IRQ_PG7                BFIN_PG_IRQ(7)
+#define IRQ_PG8                BFIN_PG_IRQ(8)
+#define IRQ_PG9                BFIN_PG_IRQ(9)
+#define IRQ_PG10       BFIN_PG_IRQ(10)
+#define IRQ_PG11       BFIN_PG_IRQ(11)
+#define IRQ_PG12       BFIN_PG_IRQ(12)
+#define IRQ_PG13       BFIN_PG_IRQ(13)
+#define IRQ_PG14       BFIN_PG_IRQ(14)
+#define IRQ_PG15       BFIN_PG_IRQ(15)
+
+#define BFIN_PH_IRQ(x) ((x) + IRQ_PG15 + 1)
+#define IRQ_PH0                BFIN_PH_IRQ(0)
+#define IRQ_PH1                BFIN_PH_IRQ(1)
+#define IRQ_PH2                BFIN_PH_IRQ(2)
+#define IRQ_PH3                BFIN_PH_IRQ(3)
+#define IRQ_PH4                BFIN_PH_IRQ(4)
+#define IRQ_PH5                BFIN_PH_IRQ(5)
+#define IRQ_PH6                BFIN_PH_IRQ(6)
+#define IRQ_PH7                BFIN_PH_IRQ(7)
+#define IRQ_PH8                BFIN_PH_IRQ(8)
+#define IRQ_PH9                BFIN_PH_IRQ(9)
+#define IRQ_PH10       BFIN_PH_IRQ(10)
+#define IRQ_PH11       BFIN_PH_IRQ(11)
+#define IRQ_PH12       BFIN_PH_IRQ(12)
+#define IRQ_PH13       BFIN_PH_IRQ(13)
+#define IRQ_PH14       BFIN_PH_IRQ(14)         /* N/A */
+#define IRQ_PH15       BFIN_PH_IRQ(15)         /* N/A */
+
+#define BFIN_PI_IRQ(x) ((x) + IRQ_PH15 + 1)
+#define IRQ_PI0                BFIN_PI_IRQ(0)
+#define IRQ_PI1                BFIN_PI_IRQ(1)
+#define IRQ_PI2                BFIN_PI_IRQ(2)
+#define IRQ_PI3                BFIN_PI_IRQ(3)
+#define IRQ_PI4                BFIN_PI_IRQ(4)
+#define IRQ_PI5                BFIN_PI_IRQ(5)
+#define IRQ_PI6                BFIN_PI_IRQ(6)
+#define IRQ_PI7                BFIN_PI_IRQ(7)
+#define IRQ_PI8                BFIN_PI_IRQ(8)
+#define IRQ_PI9                BFIN_PI_IRQ(9)
+#define IRQ_PI10       BFIN_PI_IRQ(10)
+#define IRQ_PI11       BFIN_PI_IRQ(11)
+#define IRQ_PI12       BFIN_PI_IRQ(12)
+#define IRQ_PI13       BFIN_PI_IRQ(13)
+#define IRQ_PI14       BFIN_PI_IRQ(14)
+#define IRQ_PI15       BFIN_PI_IRQ(15)
+
+#define BFIN_PJ_IRQ(x) ((x) + IRQ_PI15 + 1)
+#define IRQ_PJ0                BFIN_PJ_IRQ(0)
+#define IRQ_PJ1                BFIN_PJ_IRQ(1)
+#define IRQ_PJ2                BFIN_PJ_IRQ(2)
+#define IRQ_PJ3                BFIN_PJ_IRQ(3)
+#define IRQ_PJ4                BFIN_PJ_IRQ(4)
+#define IRQ_PJ5                BFIN_PJ_IRQ(5)
+#define IRQ_PJ6                BFIN_PJ_IRQ(6)
+#define IRQ_PJ7                BFIN_PJ_IRQ(7)
+#define IRQ_PJ8                BFIN_PJ_IRQ(8)
+#define IRQ_PJ9                BFIN_PJ_IRQ(9)
+#define IRQ_PJ10       BFIN_PJ_IRQ(10)
+#define IRQ_PJ11       BFIN_PJ_IRQ(11)
+#define IRQ_PJ12       BFIN_PJ_IRQ(12)
+#define IRQ_PJ13       BFIN_PJ_IRQ(13)
+#define IRQ_PJ14       BFIN_PJ_IRQ(14)         /* N/A */
+#define IRQ_PJ15       BFIN_PJ_IRQ(15)         /* N/A */
+
+#ifdef CONFIG_IRQCHIP_DEMUX_GPIO
+#define NR_IRQS     (IRQ_PJ15+1)
+#else
+#define NR_IRQS     (SYS_IRQS+1)
+#endif
+
+#define IVG7            7
+#define IVG8            8
+#define IVG9            9
+#define IVG10           10
+#define IVG11           11
+#define IVG12           12
+#define IVG13           13
+#define IVG14           14
+#define IVG15           15
+
+/* IAR0 BIT FIELDS */
+#define IRQ_PLL_WAKEUP_POS     0
+#define IRQ_DMAC0_ERR_POS      4
+#define IRQ_EPPI0_ERR_POS      8
+#define IRQ_SPORT0_ERR_POS     12
+#define IRQ_SPORT1_ERR_POS     16
+#define IRQ_SPI0_ERR_POS       20
+#define IRQ_UART0_ERR_POS      24
+#define IRQ_RTC_POS            28
+
+/* IAR1 BIT FIELDS */
+#define IRQ_EPPI0_POS          0
+#define IRQ_SPORT0_RX_POS      4
+#define IRQ_SPORT0_TX_POS      8
+#define IRQ_SPORT1_RX_POS      12
+#define IRQ_SPORT1_TX_POS      16
+#define IRQ_SPI0_POS           20
+#define IRQ_UART0_RX_POS       24
+#define IRQ_UART0_TX_POS       28
+
+/* IAR2 BIT FIELDS */
+#define IRQ_TIMER8_POS         0
+#define IRQ_TIMER9_POS         4
+#define IRQ_TIMER10_POS                8
+#define IRQ_PINT0_POS          12
+#define IRQ_PINT1_POS          16
+#define IRQ_MDMAS0_POS         20
+#define IRQ_MDMAS1_POS         24
+#define IRQ_WATCHDOG_POS       28
+
+/* IAR3 BIT FIELDS */
+#define IRQ_DMAC1_ERR_POS      0
+#define IRQ_SPORT2_ERR_POS     4
+#define IRQ_SPORT3_ERR_POS     8
+#define IRQ_MXVR_DATA_POS      12
+#define IRQ_SPI1_ERR_POS       16
+#define IRQ_SPI2_ERR_POS       20
+#define IRQ_UART1_ERR_POS      24
+#define IRQ_UART2_ERR_POS      28
+
+/* IAR4 BIT FILEDS */
+#define IRQ_CAN0_ERR_POS       0
+#define IRQ_SPORT2_RX_POS      4
+#define IRQ_SPORT2_TX_POS      8
+#define IRQ_SPORT3_RX_POS      12
+#define IRQ_SPORT3_TX_POS      16
+#define IRQ_EPPI1_POS          20
+#define IRQ_EPPI2_POS          24
+#define IRQ_SPI1_POS           28
+
+/* IAR5 BIT FIELDS */
+#define IRQ_SPI2_POS           0
+#define IRQ_UART1_RX_POS       4
+#define IRQ_UART1_TX_POS       8
+#define IRQ_ATAPI_RX_POS       12
+#define IRQ_ATAPI_TX_POS       16
+#define IRQ_TWI0_POS           20
+#define IRQ_TWI1_POS           24
+#define IRQ_CAN0_RX_POS                28
+
+/* IAR6 BIT FIELDS */
+#define IRQ_CAN0_TX_POS                0
+#define IRQ_MDMAS2_POS         4
+#define IRQ_MDMAS3_POS         8
+#define IRQ_MXVR_ERR_POS       12
+#define IRQ_MXVR_MSG_POS       16
+#define IRQ_MXVR_PKT_POS       20
+#define IRQ_EPPI1_ERR_POS      24
+#define IRQ_EPPI2_ERR_POS      28
+
+/* IAR7 BIT FIELDS */
+#define IRQ_UART3_ERR_POS      0
+#define IRQ_HOST_ERR_POS       4
+#define IRQ_PIXC_ERR_POS       12
+#define IRQ_NFC_ERR_POS                16
+#define IRQ_ATAPI_ERR_POS      20
+#define IRQ_CAN1_ERR_POS       24
+#define IRQ_HS_DMA_ERR_POS     28
+
+/* IAR8 BIT FIELDS */
+#define IRQ_PIXC_IN0_POS       0
+#define IRQ_PIXC_IN1_POS       4
+#define IRQ_PIXC_OUT_POS       8
+#define IRQ_SDH_POS            12
+#define IRQ_CNT_POS            16
+#define IRQ_KEY_POS            20
+#define IRQ_CAN1_RX_POS                24
+#define IRQ_CAN1_TX_POS                28
+
+/* IAR9 BIT FIELDS */
+#define IRQ_SDH_MASK0_POS      0
+#define IRQ_SDH_MASK1_POS      4
+#define IRQ_USB_INT0_POS       12
+#define IRQ_USB_INT1_POS       16
+#define IRQ_USB_INT2_POS       20
+#define IRQ_USB_DMA_POS                24
+#define IRQ_OTPSEC_POS         28
+
+/* IAR10 BIT FIELDS */
+#define IRQ_TIMER0_POS         24
+#define IRQ_TIMER1_POS         28
+
+/* IAR11 BIT FIELDS */
+#define IRQ_TIMER2_POS         0
+#define IRQ_TIMER3_POS         4
+#define IRQ_TIMER4_POS         8
+#define IRQ_TIMER5_POS         12
+#define IRQ_TIMER6_POS         16
+#define IRQ_TIMER7_POS         20
+#define IRQ_PINT2_POS          24
+#define IRQ_PINT3_POS          28
+
+#endif /* _BF548_IRQ_H_ */
diff --git a/include/asm-blackfin/mach-bf548/mem_init.h b/include/asm-blackfin/mach-bf548/mem_init.h
new file mode 100644 (file)
index 0000000..0cb279e
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * File:         include/asm-blackfin/mach-bf548/mem_init.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Rev:
+ *
+ * Modified:
+ *               Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#if (CONFIG_MEM_MT46V32M16)
+
+#if defined CONFIG_CLKIN_HALF
+#define CLKIN_HALF       1
+#else
+#define CLKIN_HALF       0
+#endif
+
+#if defined CONFIG_PLL_BYPASS
+#define PLL_BYPASS      1
+#else
+#define PLL_BYPASS       0
+#endif
+
+/***************************************Currently Not Being Used *********************************/
+#define flash_EBIU_AMBCTL_WAT  ((CONFIG_FLASH_SPEED_BWAT * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1
+#define flash_EBIU_AMBCTL_RAT  ((CONFIG_FLASH_SPEED_BRAT * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1
+#define flash_EBIU_AMBCTL_HT   ((CONFIG_FLASH_SPEED_BHT  * 4) / (4000000000 / CONFIG_SCLK_HZ))
+#define flash_EBIU_AMBCTL_ST   ((CONFIG_FLASH_SPEED_BST  * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1
+#define flash_EBIU_AMBCTL_TT   ((CONFIG_FLASH_SPEED_BTT  * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1
+
+#if (flash_EBIU_AMBCTL_TT > 3)
+#define flash_EBIU_AMBCTL0_TT   B0TT_4
+#endif
+#if (flash_EBIU_AMBCTL_TT == 3)
+#define flash_EBIU_AMBCTL0_TT   B0TT_3
+#endif
+#if (flash_EBIU_AMBCTL_TT == 2)
+#define flash_EBIU_AMBCTL0_TT   B0TT_2
+#endif
+#if (flash_EBIU_AMBCTL_TT < 2)
+#define flash_EBIU_AMBCTL0_TT   B0TT_1
+#endif
+
+#if (flash_EBIU_AMBCTL_ST > 3)
+#define flash_EBIU_AMBCTL0_ST   B0ST_4
+#endif
+#if (flash_EBIU_AMBCTL_ST == 3)
+#define flash_EBIU_AMBCTL0_ST   B0ST_3
+#endif
+#if (flash_EBIU_AMBCTL_ST == 2)
+#define flash_EBIU_AMBCTL0_ST   B0ST_2
+#endif
+#if (flash_EBIU_AMBCTL_ST < 2)
+#define flash_EBIU_AMBCTL0_ST   B0ST_1
+#endif
+
+#if (flash_EBIU_AMBCTL_HT > 2)
+#define flash_EBIU_AMBCTL0_HT   B0HT_3
+#endif
+#if (flash_EBIU_AMBCTL_HT == 2)
+#define flash_EBIU_AMBCTL0_HT   B0HT_2
+#endif
+#if (flash_EBIU_AMBCTL_HT == 1)
+#define flash_EBIU_AMBCTL0_HT   B0HT_1
+#endif
+#if (flash_EBIU_AMBCTL_HT == 0 && CONFIG_FLASH_SPEED_BHT == 0)
+#define flash_EBIU_AMBCTL0_HT   B0HT_0
+#endif
+#if (flash_EBIU_AMBCTL_HT == 0 && CONFIG_FLASH_SPEED_BHT != 0)
+#define flash_EBIU_AMBCTL0_HT   B0HT_1
+#endif
+
+#if (flash_EBIU_AMBCTL_WAT > 14)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_15
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 14)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_14
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 13)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_13
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 12)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_12
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 11)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_11
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 10)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_10
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 9)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_9
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 8)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_8
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 7)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_7
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 6)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_6
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 5)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_5
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 4)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_4
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 3)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_3
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 2)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_2
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 1)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_1
+#endif
+
+#if (flash_EBIU_AMBCTL_RAT > 14)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_15
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 14)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_14
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 13)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_13
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 12)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_12
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 11)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_11
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 10)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_10
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 9)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_9
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 8)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_8
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 7)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_7
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 6)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_6
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 5)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_5
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 4)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_4
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 3)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_3
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 2)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_2
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 1)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_1
+#endif
+
+#define flash_EBIU_AMBCTL0  \
+       (flash_EBIU_AMBCTL0_WAT | flash_EBIU_AMBCTL0_RAT | flash_EBIU_AMBCTL0_HT | \
+        flash_EBIU_AMBCTL0_ST | flash_EBIU_AMBCTL0_TT | CONFIG_FLASH_SPEED_RDYEN)
diff --git a/include/asm-blackfin/mach-bf548/mem_map.h b/include/asm-blackfin/mach-bf548/mem_map.h
new file mode 100644 (file)
index 0000000..72d80e8
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * file:         include/asm-blackfin/mach-bf548/mem_map.h
+ * based on:
+ * author:
+ *
+ * created:
+ * description:
+ *     Memory MAP Common header file for blackfin BF537/6/4 of processors.
+ * rev:
+ *
+ * modified:
+ *
+ * bugs:         enter bugs at http://blackfin.uclinux.org/
+ *
+ * this program is free software; you can redistribute it and/or modify
+ * it under the terms of the gnu general public license as published by
+ * the free software foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * this program is distributed in the hope that it will be useful,
+ * but without any warranty; without even the implied warranty of
+ * merchantability or fitness for a particular purpose.  see the
+ * gnu general public license for more details.
+ *
+ * you should have received a copy of the gnu general public license
+ * along with this program; see the file copying.
+ * if not, write to the free software foundation,
+ * 59 temple place - suite 330, boston, ma 02111-1307, usa.
+ */
+
+#ifndef _MEM_MAP_548_H_
+#define _MEM_MAP_548_H_
+
+#define COREMMR_BASE           0xFFE00000       /* Core MMRs */
+#define SYSMMR_BASE            0xFFC00000       /* System MMRs */
+
+/* Async Memory Banks */
+#define ASYNC_BANK3_BASE       0x2C000000       /* Async Bank 3 */
+#define ASYNC_BANK3_SIZE       0x04000000      /* 64M */
+#define ASYNC_BANK2_BASE       0x28000000       /* Async Bank 2 */
+#define ASYNC_BANK2_SIZE       0x04000000      /* 64M */
+#define ASYNC_BANK1_BASE       0x24000000       /* Async Bank 1 */
+#define ASYNC_BANK1_SIZE       0x04000000      /* 64M */
+#define ASYNC_BANK0_BASE       0x20000000       /* Async Bank 0 */
+#define ASYNC_BANK0_SIZE       0x04000000      /* 64M */
+
+/* Boot ROM Memory */
+
+#define BOOT_ROM_START         0xEF000000
+
+/* Level 1 Memory */
+
+/* Memory Map for ADSP-BF548 processors */
+#ifdef CONFIG_BLKFIN_ICACHE
+#define BLKFIN_ICACHESIZE      (16*1024)
+#else
+#define BLKFIN_ICACHESIZE      (0*1024)
+#endif
+
+#define L1_CODE_START       0xFFA00000
+#define L1_DATA_A_START     0xFF800000
+#define L1_DATA_B_START     0xFF900000
+
+#define L1_CODE_LENGTH      0xC000
+
+#ifdef CONFIG_BLKFIN_DCACHE
+
+#ifdef CONFIG_BLKFIN_DCACHE_BANKA
+#define DMEM_CNTR (ACACHE_BSRAM | ENDCPLB | PORT_PREF0)
+#define L1_DATA_A_LENGTH      (0x8000 - 0x4000)
+#define L1_DATA_B_LENGTH      0x8000
+#define BLKFIN_DCACHESIZE      (16*1024)
+#define BLKFIN_DSUPBANKS       1
+#else
+#define DMEM_CNTR (ACACHE_BCACHE | ENDCPLB | PORT_PREF0)
+#define L1_DATA_A_LENGTH      (0x8000 - 0x4000)
+#define L1_DATA_B_LENGTH      (0x8000 - 0x4000)
+#define BLKFIN_DCACHESIZE      (32*1024)
+#define BLKFIN_DSUPBANKS       2
+#endif
+
+#else
+#define DMEM_CNTR (ASRAM_BSRAM | ENDCPLB | PORT_PREF0)
+#define L1_DATA_A_LENGTH      0x8000
+#define L1_DATA_B_LENGTH      0x8000
+#define BLKFIN_DCACHESIZE      (0*1024)
+#define BLKFIN_DSUPBANKS       0
+#endif /*CONFIG_BLKFIN_DCACHE*/
+
+/* Scratch Pad Memory */
+
+#if defined(CONFIG_BF54x)
+#define L1_SCRATCH_START       0xFFB00000
+#define L1_SCRATCH_LENGTH      0x1000
+#endif
+
+#endif/* _MEM_MAP_548_H_ */
diff --git a/include/asm-blackfin/mach-bf548/portmux.h b/include/asm-blackfin/mach-bf548/portmux.h
new file mode 100644 (file)
index 0000000..b382deb
--- /dev/null
@@ -0,0 +1,270 @@
+#ifndef _MACH_PORTMUX_H_
+#define _MACH_PORTMUX_H_
+
+#define P_SPORT2_TFS   (P_DEFINED | P_IDENT(GPIO_PA0) | P_FUNCT(0))
+#define P_SPORT2_DTSEC (P_DEFINED | P_IDENT(GPIO_PA1) | P_FUNCT(0))
+#define P_SPORT2_DTPRI (P_DEFINED | P_IDENT(GPIO_PA2) | P_FUNCT(0))
+#define P_SPORT2_TSCLK (P_DEFINED | P_IDENT(GPIO_PA3) | P_FUNCT(0))
+#define P_SPORT2_RFS   (P_DEFINED | P_IDENT(GPIO_PA4) | P_FUNCT(0))
+#define P_SPORT2_DRSEC (P_DEFINED | P_IDENT(GPIO_PA5) | P_FUNCT(0))
+#define P_SPORT2_DRPRI (P_DEFINED | P_IDENT(GPIO_PA6) | P_FUNCT(0))
+#define P_SPORT2_RSCLK (P_DEFINED | P_IDENT(GPIO_PA7) | P_FUNCT(0))
+#define P_SPORT3_TFS   (P_DEFINED | P_IDENT(GPIO_PA8) | P_FUNCT(0))
+#define P_SPORT3_DTSEC (P_DEFINED | P_IDENT(GPIO_PA9) | P_FUNCT(0))
+#define P_SPORT3_DTPRI (P_DEFINED | P_IDENT(GPIO_PA10) | P_FUNCT(0))
+#define P_SPORT3_TSCLK (P_DEFINED | P_IDENT(GPIO_PA11) | P_FUNCT(0))
+#define P_SPORT3_RFS   (P_DEFINED | P_IDENT(GPIO_PA12) | P_FUNCT(0))
+#define P_SPORT3_DRSEC (P_DEFINED | P_IDENT(GPIO_PA13) | P_FUNCT(0))
+#define P_SPORT3_DRPRI (P_DEFINED | P_IDENT(GPIO_PA14) | P_FUNCT(0))
+#define P_SPORT3_RSCLK (P_DEFINED | P_IDENT(GPIO_PA15) | P_FUNCT(0))
+#define P_TMR4 (P_DEFINED | P_IDENT(GPIO_PA1) | P_FUNCT(1))
+#define P_TMR5 (P_DEFINED | P_IDENT(GPIO_PA5) | P_FUNCT(1))
+#define P_TMR6 (P_DEFINED | P_IDENT(GPIO_PA9) | P_FUNCT(1))
+#define P_TMR7 (P_DEFINED | P_IDENT(GPIO_PA13) | P_FUNCT(1))
+
+#define P_TWI1_SCL     (P_DEFINED | P_IDENT(GPIO_PB0) | P_FUNCT(0))
+#define P_TWI1_SDA     (P_DEFINED | P_IDENT(GPIO_PB1) | P_FUNCT(0))
+#define P_UART3_RTS    (P_DEFINED | P_IDENT(GPIO_PB2) | P_FUNCT(0))
+#define P_UART3_CTS    (P_DEFINED | P_IDENT(GPIO_PB3) | P_FUNCT(0))
+#define P_UART2_TX     (P_DEFINED | P_IDENT(GPIO_PB4) | P_FUNCT(0))
+#define P_UART2_RX     (P_DEFINED | P_IDENT(GPIO_PB5) | P_FUNCT(0))
+#define P_UART3_TX     (P_DEFINED | P_IDENT(GPIO_PB6) | P_FUNCT(0))
+#define P_UART3_RX     (P_DEFINED | P_IDENT(GPIO_PB7) | P_FUNCT(0))
+#define P_SPI2_SS      (P_DEFINED | P_IDENT(GPIO_PB8) | P_FUNCT(0))
+#define P_SPI2_SSEL1   (P_DEFINED | P_IDENT(GPIO_PB9) | P_FUNCT(0))
+#define P_SPI2_SSEL2   (P_DEFINED | P_IDENT(GPIO_PB10) | P_FUNCT(0))
+#define P_SPI2_SSEL3   (P_DEFINED | P_IDENT(GPIO_PB11) | P_FUNCT(0))
+#define P_SPI2_SCK     (P_DEFINED | P_IDENT(GPIO_PB12) | P_FUNCT(0))
+#define P_SPI2_MOSI    (P_DEFINED | P_IDENT(GPIO_PB13) | P_FUNCT(0))
+#define P_SPI2_MISO    (P_DEFINED | P_IDENT(GPIO_PB14) | P_FUNCT(0))
+#define P_TMR0 (P_DEFINED | P_IDENT(GPIO_PB8) | P_FUNCT(1))
+#define P_TMR1 (P_DEFINED | P_IDENT(GPIO_PB9) | P_FUNCT(1))
+#define P_TMR2 (P_DEFINED | P_IDENT(GPIO_PB10) | P_FUNCT(1))
+#define P_TMR3 (P_DEFINED | P_IDENT(GPIO_PB11) | P_FUNCT(1))
+
+#define P_SPORT0_TFS   (P_DEFINED | P_IDENT(GPIO_PC0) | P_FUNCT(0))
+#define P_SPORT0_DTSEC (P_DEFINED | P_IDENT(GPIO_PC1) | P_FUNCT(0))
+#define P_SPORT0_DTPRI (P_DEFINED | P_IDENT(GPIO_PC2) | P_FUNCT(0))
+#define P_SPORT0_TSCLK (P_DEFINED | P_IDENT(GPIO_PC3) | P_FUNCT(0))
+#define P_SPORT0_RFS   (P_DEFINED | P_IDENT(GPIO_PC4) | P_FUNCT(0))
+#define P_SPORT0_DRSEC (P_DEFINED | P_IDENT(GPIO_PC5) | P_FUNCT(0))
+#define P_SPORT0_DRPRI (P_DEFINED | P_IDENT(GPIO_PC6) | P_FUNCT(0))
+#define P_SPORT0_RSCLK (P_DEFINED | P_IDENT(GPIO_PC7) | P_FUNCT(0))
+#define P_SD_D0        (P_DEFINED | P_IDENT(GPIO_PC8) | P_FUNCT(0))
+#define P_SD_D1        (P_DEFINED | P_IDENT(GPIO_PC9) | P_FUNCT(0))
+#define P_SD_D2        (P_DEFINED | P_IDENT(GPIO_PC10) | P_FUNCT(0))
+#define P_SD_D3        (P_DEFINED | P_IDENT(GPIO_PC11) | P_FUNCT(0))
+#define P_SD_CLK       (P_DEFINED | P_IDENT(GPIO_PC12) | P_FUNCT(0))
+#define P_SD_CMD       (P_DEFINED | P_IDENT(GPIO_PC13) | P_FUNCT(0))
+#define P_MMCLK        (P_DEFINED | P_IDENT(GPIO_PC1) | P_FUNCT(1))
+#define P_MBCLK        (P_DEFINED | P_IDENT(GPIO_PC5) | P_FUNCT(1))
+
+#define P_PPI1_D0      (P_DEFINED | P_IDENT(GPIO_PD0) | P_FUNCT(0))
+#define P_PPI1_D1      (P_DEFINED | P_IDENT(GPIO_PD1) | P_FUNCT(0))
+#define P_PPI1_D2      (P_DEFINED | P_IDENT(GPIO_PD2) | P_FUNCT(0))
+#define P_PPI1_D3      (P_DEFINED | P_IDENT(GPIO_PD3) | P_FUNCT(0))
+#define P_PPI1_D4      (P_DEFINED | P_IDENT(GPIO_PD4) | P_FUNCT(0))
+#define P_PPI1_D5      (P_DEFINED | P_IDENT(GPIO_PD5) | P_FUNCT(0))
+#define P_PPI1_D6      (P_DEFINED | P_IDENT(GPIO_PD6) | P_FUNCT(0))
+#define P_PPI1_D7      (P_DEFINED | P_IDENT(GPIO_PD7) | P_FUNCT(0))
+#define P_PPI1_D8      (P_DEFINED | P_IDENT(GPIO_PD8) | P_FUNCT(0))
+#define P_PPI1_D9      (P_DEFINED | P_IDENT(GPIO_PD9) | P_FUNCT(0))
+#define P_PPI1_D10     (P_DEFINED | P_IDENT(GPIO_PD10) | P_FUNCT(0))
+#define P_PPI1_D11     (P_DEFINED | P_IDENT(GPIO_PD11) | P_FUNCT(0))
+#define P_PPI1_D12     (P_DEFINED | P_IDENT(GPIO_PD12) | P_FUNCT(0))
+#define P_PPI1_D13     (P_DEFINED | P_IDENT(GPIO_PD13) | P_FUNCT(0))
+#define P_PPI1_D14     (P_DEFINED | P_IDENT(GPIO_PD14) | P_FUNCT(0))
+#define P_PPI1_D15     (P_DEFINED | P_IDENT(GPIO_PD15) | P_FUNCT(0))
+
+#define P_HOST_D8      (P_DEFINED | P_IDENT(GPIO_PD0) | P_FUNCT(1))
+#define P_HOST_D9      (P_DEFINED | P_IDENT(GPIO_PD1) | P_FUNCT(1))
+#define P_HOST_D10     (P_DEFINED | P_IDENT(GPIO_PD2) | P_FUNCT(1))
+#define P_HOST_D11     (P_DEFINED | P_IDENT(GPIO_PD3) | P_FUNCT(1))
+#define P_HOST_D12     (P_DEFINED | P_IDENT(GPIO_PD4) | P_FUNCT(1))
+#define P_HOST_D13     (P_DEFINED | P_IDENT(GPIO_PD5) | P_FUNCT(1))
+#define P_HOST_D14     (P_DEFINED | P_IDENT(GPIO_PD6) | P_FUNCT(1))
+#define P_HOST_D15     (P_DEFINED | P_IDENT(GPIO_PD7) | P_FUNCT(1))
+#define P_HOST_D0      (P_DEFINED | P_IDENT(GPIO_PD8) | P_FUNCT(1))
+#define P_HOST_D1      (P_DEFINED | P_IDENT(GPIO_PD9) | P_FUNCT(1))
+#define P_HOST_D2      (P_DEFINED | P_IDENT(GPIO_PD10) | P_FUNCT(1))
+#define P_HOST_D3      (P_DEFINED | P_IDENT(GPIO_PD11) | P_FUNCT(1))
+#define P_HOST_D4      (P_DEFINED | P_IDENT(GPIO_PD12) | P_FUNCT(1))
+#define P_HOST_D5      (P_DEFINED | P_IDENT(GPIO_PD13) | P_FUNCT(1))
+#define P_HOST_D6      (P_DEFINED | P_IDENT(GPIO_PD14) | P_FUNCT(1))
+#define P_HOST_D7      (P_DEFINED | P_IDENT(GPIO_PD15) | P_FUNCT(1))
+#define P_SPORT1_TFS   (P_DEFINED | P_IDENT(GPIO_PD0) | P_FUNCT(2))
+#define P_SPORT1_DTSEC (P_DEFINED | P_IDENT(GPIO_PD1) | P_FUNCT(2))
+#define P_SPORT1_DTPRI (P_DEFINED | P_IDENT(GPIO_PD2) | P_FUNCT(2))
+#define P_SPORT1_TSCLK (P_DEFINED | P_IDENT(GPIO_PD3) | P_FUNCT(2))
+#define P_SPORT1_RFS   (P_DEFINED | P_IDENT(GPIO_PD4) | P_FUNCT(2))
+#define P_SPORT1_DRSEC (P_DEFINED | P_IDENT(GPIO_PD5) | P_FUNCT(2))
+#define P_SPORT1_DRPRI (P_DEFINED | P_IDENT(GPIO_PD6) | P_FUNCT(2))
+#define P_SPORT1_RSCLK (P_DEFINED | P_IDENT(GPIO_PD7) | P_FUNCT(2))
+#define P_PPI2_D0      (P_DEFINED | P_IDENT(GPIO_PD8) | P_FUNCT(2))
+#define P_PPI2_D1      (P_DEFINED | P_IDENT(GPIO_PD9) | P_FUNCT(2))
+#define P_PPI2_D2      (P_DEFINED | P_IDENT(GPIO_PD10) | P_FUNCT(2))
+#define P_PPI2_D3      (P_DEFINED | P_IDENT(GPIO_PD11) | P_FUNCT(2))
+#define P_PPI2_D4      (P_DEFINED | P_IDENT(GPIO_PD12) | P_FUNCT(2))
+#define P_PPI2_D5      (P_DEFINED | P_IDENT(GPIO_PD13) | P_FUNCT(2))
+#define P_PPI2_D6      (P_DEFINED | P_IDENT(GPIO_PD14) | P_FUNCT(2))
+#define P_PPI2_D7      (P_DEFINED | P_IDENT(GPIO_PD15) | P_FUNCT(2))
+#define P_PPI0_D18     (P_DEFINED | P_IDENT(GPIO_PD0) | P_FUNCT(3))
+#define P_PPI0_D19     (P_DEFINED | P_IDENT(GPIO_PD1) | P_FUNCT(3))
+#define P_PPI0_D20     (P_DEFINED | P_IDENT(GPIO_PD2) | P_FUNCT(3))
+#define P_PPI0_D21     (P_DEFINED | P_IDENT(GPIO_PD3) | P_FUNCT(3))
+#define P_PPI0_D22     (P_DEFINED | P_IDENT(GPIO_PD4) | P_FUNCT(3))
+#define P_PPI0_D23     (P_DEFINED | P_IDENT(GPIO_PD5) | P_FUNCT(3))
+#define P_KEY_ROW0     (P_DEFINED | P_IDENT(GPIO_PD8) | P_FUNCT(3))
+#define P_KEY_ROW1     (P_DEFINED | P_IDENT(GPIO_PD9) | P_FUNCT(3))
+#define P_KEY_ROW2     (P_DEFINED | P_IDENT(GPIO_PD10) | P_FUNCT(3))
+#define P_KEY_ROW3     (P_DEFINED | P_IDENT(GPIO_PD11) | P_FUNCT(3))
+#define P_KEY_COL0     (P_DEFINED | P_IDENT(GPIO_PD12) | P_FUNCT(3))
+#define P_KEY_COL1     (P_DEFINED | P_IDENT(GPIO_PD13) | P_FUNCT(3))
+#define P_KEY_COL2     (P_DEFINED | P_IDENT(GPIO_PD14) | P_FUNCT(3))
+#define P_KEY_COL3     (P_DEFINED | P_IDENT(GPIO_PD15) | P_FUNCT(3))
+
+#define P_SPI0_SCK     (P_DEFINED | P_IDENT(GPIO_PE0) | P_FUNCT(0))
+#define P_SPI0_MISO    (P_DEFINED | P_IDENT(GPIO_PE1) | P_FUNCT(0))
+#define P_SPI0_MOSI    (P_DEFINED | P_IDENT(GPIO_PE2) | P_FUNCT(0))
+#define P_SPI0_SS      (P_DEFINED | P_IDENT(GPIO_PE3) | P_FUNCT(0))
+#define P_SPI0_SSEL1   (P_DEFINED | P_IDENT(GPIO_PE4) | P_FUNCT(0))
+#define P_SPI0_SSEL2   (P_DEFINED | P_IDENT(GPIO_PE5) | P_FUNCT(0))
+#define P_SPI0_SSEL3   (P_DEFINED | P_IDENT(GPIO_PE6) | P_FUNCT(0))
+#define P_UART0_TX     (P_DEFINED | P_IDENT(GPIO_PE7) | P_FUNCT(0))
+#define P_UART0_RX     (P_DEFINED | P_IDENT(GPIO_PE8) | P_FUNCT(0))
+#define P_UART1_RTS    (P_DEFINED | P_IDENT(GPIO_PE9) | P_FUNCT(0))
+#define P_UART1_CTS    (P_DEFINED | P_IDENT(GPIO_PE10) | P_FUNCT(0))
+#define P_PPI1_CLK     (P_DEFINED | P_IDENT(GPIO_PE11) | P_FUNCT(0))
+#define P_PPI1_FS1     (P_DEFINED | P_IDENT(GPIO_PE12) | P_FUNCT(0))
+#define P_PPI1_FS2     (P_DEFINED | P_IDENT(GPIO_PE13) | P_FUNCT(0))
+#define P_TWI0_SCL     (P_DEFINED | P_IDENT(GPIO_PE14) | P_FUNCT(0))
+#define P_TWI0_SDA     (P_DEFINED | P_IDENT(GPIO_PE15) | P_FUNCT(0))
+#define P_KEY_COL7     (P_DEFINED | P_IDENT(GPIO_PE0) | P_FUNCT(1))
+#define P_KEY_ROW6     (P_DEFINED | P_IDENT(GPIO_PE1) | P_FUNCT(1))
+#define P_KEY_COL6     (P_DEFINED | P_IDENT(GPIO_PE2) | P_FUNCT(1))
+#define P_KEY_ROW5     (P_DEFINED | P_IDENT(GPIO_PE3) | P_FUNCT(1))
+#define P_KEY_COL5     (P_DEFINED | P_IDENT(GPIO_PE4) | P_FUNCT(1))
+#define P_KEY_ROW4     (P_DEFINED | P_IDENT(GPIO_PE5) | P_FUNCT(1))
+#define P_KEY_COL4     (P_DEFINED | P_IDENT(GPIO_PE6) | P_FUNCT(1))
+#define P_KEY_ROW7     (P_DEFINED | P_IDENT(GPIO_PE7) | P_FUNCT(1))
+
+#define P_PPI0_D0      (P_DEFINED | P_IDENT(GPIO_PF0) | P_FUNCT(0))
+#define P_PPI0_D1      (P_DEFINED | P_IDENT(GPIO_PF1) | P_FUNCT(0))
+#define P_PPI0_D2      (P_DEFINED | P_IDENT(GPIO_PF2) | P_FUNCT(0))
+#define P_PPI0_D3      (P_DEFINED | P_IDENT(GPIO_PF3) | P_FUNCT(0))
+#define P_PPI0_D4      (P_DEFINED | P_IDENT(GPIO_PF4) | P_FUNCT(0))
+#define P_PPI0_D5      (P_DEFINED | P_IDENT(GPIO_PF5) | P_FUNCT(0))
+#define P_PPI0_D6      (P_DEFINED | P_IDENT(GPIO_PF6) | P_FUNCT(0))
+#define P_PPI0_D7      (P_DEFINED | P_IDENT(GPIO_PF7) | P_FUNCT(0))
+#define P_PPI0_D8      (P_DEFINED | P_IDENT(GPIO_PF8) | P_FUNCT(0))
+#define P_PPI0_D9      (P_DEFINED | P_IDENT(GPIO_PF9) | P_FUNCT(0))
+#define P_PPI0_D10     (P_DEFINED | P_IDENT(GPIO_PF10) | P_FUNCT(0))
+#define P_PPI0_D11     (P_DEFINED | P_IDENT(GPIO_PF11) | P_FUNCT(0))
+#define P_PPI0_D12     (P_DEFINED | P_IDENT(GPIO_PF12) | P_FUNCT(0))
+#define P_PPI0_D13     (P_DEFINED | P_IDENT(GPIO_PF13) | P_FUNCT(0))
+#define P_PPI0_D14     (P_DEFINED | P_IDENT(GPIO_PF14) | P_FUNCT(0))
+#define P_PPI0_D15     (P_DEFINED | P_IDENT(GPIO_PF15) | P_FUNCT(0))
+#define P_ATAPI_D0A    (P_DEFINED | P_IDENT(GPIO_PF0) | P_FUNCT(1))
+#define P_ATAPI_D1A    (P_DEFINED | P_IDENT(GPIO_PF1) | P_FUNCT(1))
+#define P_ATAPI_D2A    (P_DEFINED | P_IDENT(GPIO_PF2) | P_FUNCT(1))
+#define P_ATAPI_D3A    (P_DEFINED | P_IDENT(GPIO_PF3) | P_FUNCT(1))
+#define P_ATAPI_D4A    (P_DEFINED | P_IDENT(GPIO_PF4) | P_FUNCT(1))
+#define P_ATAPI_D5A    (P_DEFINED | P_IDENT(GPIO_PF5) | P_FUNCT(1))
+#define P_ATAPI_D6A    (P_DEFINED | P_IDENT(GPIO_PF6) | P_FUNCT(1))
+#define P_ATAPI_D7A    (P_DEFINED | P_IDENT(GPIO_PF7) | P_FUNCT(1))
+#define P_ATAPI_D8A    (P_DEFINED | P_IDENT(GPIO_PF8) | P_FUNCT(1))
+#define P_ATAPI_D9A    (P_DEFINED | P_IDENT(GPIO_PF9) | P_FUNCT(1))
+#define P_ATAPI_D10A   (P_DEFINED | P_IDENT(GPIO_PF10) | P_FUNCT(1))
+#define P_ATAPI_D11A   (P_DEFINED | P_IDENT(GPIO_PF11) | P_FUNCT(1))
+#define P_ATAPI_D12A   (P_DEFINED | P_IDENT(GPIO_PF12) | P_FUNCT(1))
+#define P_ATAPI_D13A   (P_DEFINED | P_IDENT(GPIO_PF13) | P_FUNCT(1))
+#define P_ATAPI_D14A   (P_DEFINED | P_IDENT(GPIO_PF14) | P_FUNCT(1))
+#define P_ATAPI_D15A   (P_DEFINED | P_IDENT(GPIO_PF15) | P_FUNCT(1))
+
+#define P_PPI0_CLK     (P_DEFINED | P_IDENT(GPIO_PG0) | P_FUNCT(0))
+#define P_PPI0_FS1     (P_DEFINED | P_IDENT(GPIO_PG1) | P_FUNCT(0))
+#define P_PPI0_FS2     (P_DEFINED | P_IDENT(GPIO_PG2) | P_FUNCT(0))
+#define P_PPI0_D16     (P_DEFINED | P_IDENT(GPIO_PG3) | P_FUNCT(0))
+#define P_PPI0_D17     (P_DEFINED | P_IDENT(GPIO_PG4) | P_FUNCT(0))
+#define P_SPI1_SSEL1   (P_DEFINED | P_IDENT(GPIO_PG5) | P_FUNCT(0))
+#define P_SPI1_SSEL2   (P_DEFINED | P_IDENT(GPIO_PG6) | P_FUNCT(0))
+#define P_SPI1_SSEL3   (P_DEFINED | P_IDENT(GPIO_PG7) | P_FUNCT(0))
+#define P_SPI1_SCK     (P_DEFINED | P_IDENT(GPIO_PG8) | P_FUNCT(0))
+#define P_SPI1_MISO    (P_DEFINED | P_IDENT(GPIO_PG9) | P_FUNCT(0))
+#define P_SPI1_MOSI    (P_DEFINED | P_IDENT(GPIO_PG10) | P_FUNCT(0))
+#define P_SPI1_SS      (P_DEFINED | P_IDENT(GPIO_PG11) | P_FUNCT(0))
+#define P_CAN0_TX      (P_DEFINED | P_IDENT(GPIO_PG12) | P_FUNCT(0))
+#define P_CAN0_RX      (P_DEFINED | P_IDENT(GPIO_PG13) | P_FUNCT(0))
+#define P_CAN1_TX      (P_DEFINED | P_IDENT(GPIO_PG14) | P_FUNCT(0))
+#define P_CAN1_RX      (P_DEFINED | P_IDENT(GPIO_PG15) | P_FUNCT(0))
+#define P_ATAPI_A0A    (P_DEFINED | P_IDENT(GPIO_PG2) | P_FUNCT(1))
+#define P_ATAPI_A1A    (P_DEFINED | P_IDENT(GPIO_PG3) | P_FUNCT(1))
+#define P_ATAPI_A2A    (P_DEFINED | P_IDENT(GPIO_PG4) | P_FUNCT(1))
+#define P_HOST_CE      (P_DEFINED | P_IDENT(GPIO_PG5) | P_FUNCT(1))
+#define P_HOST_RD      (P_DEFINED | P_IDENT(GPIO_PG6) | P_FUNCT(1))
+#define P_HOST_WR      (P_DEFINED | P_IDENT(GPIO_PG7) | P_FUNCT(1))
+#define P_MTXONB       (P_DEFINED | P_IDENT(GPIO_PG11) | P_FUNCT(1))
+#define P_PPI2_FS2     (P_DEFINED | P_IDENT(GPIO_PG5) | P_FUNCT(2))
+#define P_PPI2_FS1     (P_DEFINED | P_IDENT(GPIO_PG6) | P_FUNCT(2))
+#define P_PPI2_CLK     (P_DEFINED | P_IDENT(GPIO_PG7) | P_FUNCT(2))
+#define P_CNT_CZM      (P_DEFINED | P_IDENT(GPIO_PG5) | P_FUNCT(3))
+
+#define P_UART1_TX     (P_DEFINED | P_IDENT(GPIO_PH0) | P_FUNCT(0))
+#define P_UART1_RX     (P_DEFINED | P_IDENT(GPIO_PH1) | P_FUNCT(0))
+#define P_ATAPI_RESET  (P_DEFINED | P_IDENT(GPIO_PH2) | P_FUNCT(0))
+#define P_HOST_ADDR    (P_DEFINED | P_IDENT(GPIO_PH3) | P_FUNCT(0))
+#define P_HOST_ACK     (P_DEFINED | P_IDENT(GPIO_PH4) | P_FUNCT(0))
+#define P_MTX  (P_DEFINED | P_IDENT(GPIO_PH5) | P_FUNCT(0))
+#define P_MRX  (P_DEFINED | P_IDENT(GPIO_PH6) | P_FUNCT(0))
+#define P_MRXONB       (P_DEFINED | P_IDENT(GPIO_PH7) | P_FUNCT(0))
+#define P_A4   (P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PH8) | P_FUNCT(0))
+#define P_A5   (P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PH9) | P_FUNCT(0))
+#define P_A6   (P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PH10) | P_FUNCT(0))
+#define P_A7   (P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PH11) | P_FUNCT(0))
+#define P_A8   (P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PH12) | P_FUNCT(0))
+#define P_A9   (P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PH13) | P_FUNCT(0))
+#define P_PPI1_FS3     (P_DEFINED | P_IDENT(GPIO_PH0) | P_FUNCT(1))
+#define P_PPI2_FS3     (P_DEFINED | P_IDENT(GPIO_PH1) | P_FUNCT(1))
+#define P_TMR8 (P_DEFINED | P_IDENT(GPIO_PH2) | P_FUNCT(1))
+#define P_TMR9 (P_DEFINED | P_IDENT(GPIO_PH3) | P_FUNCT(1))
+#define P_TMR10        (P_DEFINED | P_IDENT(GPIO_PH4) | P_FUNCT(1))
+#define P_DMAR0        (P_DEFINED | P_IDENT(GPIO_PH5) | P_FUNCT(1))
+#define P_DMAR1        (P_DEFINED | P_IDENT(GPIO_PH6) | P_FUNCT(1))
+#define P_PPI0_FS3     (P_DEFINED | P_IDENT(GPIO_PH2) | P_FUNCT(2))
+#define P_CNT_CDG      (P_DEFINED | P_IDENT(GPIO_PH3) | P_FUNCT(2))
+#define P_CNT_CUD      (P_DEFINED | P_IDENT(GPIO_PH4) | P_FUNCT(2))
+
+#define P_A10  (P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PI0) | P_FUNCT(0))
+#define P_A11  (P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PI1) | P_FUNCT(0))
+#define P_A12  (P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PI2) | P_FUNCT(0))
+#define P_A13  (P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PI3) | P_FUNCT(0))
+#define P_A14  (P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PI4) | P_FUNCT(0))
+#define P_A15  (P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PI5) | P_FUNCT(0))
+#define P_A16  (P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PI6) | P_FUNCT(0))
+#define P_A17  (P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PI7) | P_FUNCT(0))
+#define P_A18  (P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PI8) | P_FUNCT(0))
+#define P_A19  (P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PI9) | P_FUNCT(0))
+#define P_A20  (P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PI10) | P_FUNCT(0))
+#define P_A21  (P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PI11) | P_FUNCT(0))
+#define P_A22  (P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PI12) | P_FUNCT(0))
+#define P_A23  (P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PI13) | P_FUNCT(0))
+#define P_A24  (P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PI14) | P_FUNCT(0))
+#define P_A25  (P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PI15) | P_FUNCT(0))
+#define P_NOR_CLK      (P_DEFINED | P_IDENT(GPIO_PI15) | P_FUNCT(1))
+
+#define P_AMC_ARDY_NOR_WAIT    (P_DEFINED | P_IDENT(GPIO_PJ0) | P_FUNCT(0))
+#define P_NAND_CE      (P_DEFINED | P_IDENT(GPIO_PJ1) | P_FUNCT(0))
+#define P_NAND_RB      (P_DEFINED | P_IDENT(GPIO_PJ2) | P_FUNCT(0))
+#define P_ATAPI_DIOR   (P_DEFINED | P_IDENT(GPIO_PJ3) | P_FUNCT(0))
+#define P_ATAPI_DIOW   (P_DEFINED | P_IDENT(GPIO_PJ4) | P_FUNCT(0))
+#define P_ATAPI_CS0    (P_DEFINED | P_IDENT(GPIO_PJ5) | P_FUNCT(0))
+#define P_ATAPI_CS1    (P_DEFINED | P_IDENT(GPIO_PJ6) | P_FUNCT(0))
+#define P_ATAPI_DMACK  (P_DEFINED | P_IDENT(GPIO_PJ7) | P_FUNCT(0))
+#define P_ATAPI_DMARQ  (P_DEFINED | P_IDENT(GPIO_PJ8) | P_FUNCT(0))
+#define P_ATAPI_INTRQ  (P_DEFINED | P_IDENT(GPIO_PJ9) | P_FUNCT(0))
+#define P_ATAPI_IORDY  (P_DEFINED | P_IDENT(GPIO_PJ10) | P_FUNCT(0))
+#define P_AMC_BR       (P_DEFINED | P_IDENT(GPIO_PJ11) | P_FUNCT(0))
+#define P_AMC_BG       (P_DEFINED | P_IDENT(GPIO_PJ12) | P_FUNCT(0))
+#define P_AMC_BGH      (P_DEFINED | P_IDENT(GPIO_PJ13) | P_FUNCT(0))
+
+#endif /* _MACH_PORTMUX_H_ */
index b14f872e5703cb781dd74e28bf761c094603eac1..1a8ec9e46922295ecd513de90bd2a608defe534e 100644 (file)
 /* Writing to VR_CTL initiates a PLL relock sequence. */
 static __inline__ void bfin_write_VR_CTL(unsigned int val)
 {
-       unsigned long flags, iwr;
+       unsigned long flags, iwr0, iwr1;
 
        /* Enable the PLL Wakeup bit in SIC IWR */
-       iwr = bfin_read32(SICA_IWR0);
+       iwr0 = bfin_read32(SICA_IWR0);
+       iwr1 = bfin_read32(SICA_IWR1);
        /* Only allow PPL Wakeup) */
        bfin_write32(SICA_IWR0, IWR_ENABLE(0));
+       bfin_write32(SICA_IWR1, 0);
 
        bfin_write16(VR_CTL, val);
        __builtin_bfin_ssync();
@@ -70,7 +72,8 @@ static __inline__ void bfin_write_VR_CTL(unsigned int val)
        local_irq_save(flags);
        asm("IDLE;");
        local_irq_restore(flags);
-       bfin_write32(SICA_IWR0, iwr);
+       bfin_write32(SICA_IWR0, iwr0);
+       bfin_write32(SICA_IWR1, iwr1);
 }
 #define bfin_read_PLL_STAT()                 bfin_read16(PLL_STAT)
 #define bfin_write_PLL_STAT(val)             bfin_write16(PLL_STAT,val)
index 21d982003e7525c80188ae55bf2df8985ec77658..766334b7d8ab8bf3a225408bb1dc6fe353356714 100644 (file)
@@ -32,4 +32,7 @@
 #define CH_IMEM_STREAM1_SRC    34
 #define CH_IMEM_STREAM1_DEST   35
 
+extern int channel2irq(unsigned int channel);
+extern struct dma_register *base_addr[];
+
 #endif
diff --git a/include/asm-blackfin/mach-bf561/portmux.h b/include/asm-blackfin/mach-bf561/portmux.h
new file mode 100644 (file)
index 0000000..10d11d5
--- /dev/null
@@ -0,0 +1,87 @@
+#ifndef _MACH_PORTMUX_H_
+#define _MACH_PORTMUX_H_
+
+#define P_PPI0_CLK     (P_DONTCARE)
+#define P_PPI0_FS1     (P_DONTCARE)
+#define P_PPI0_FS2     (P_DONTCARE)
+#define P_PPI0_FS3     (P_DONTCARE)
+#define P_PPI0_D15     (P_DEFINED | P_IDENT(GPIO_PF47))
+#define P_PPI0_D14     (P_DEFINED | P_IDENT(GPIO_PF46))
+#define P_PPI0_D13     (P_DEFINED | P_IDENT(GPIO_PF45))
+#define P_PPI0_D12     (P_DEFINED | P_IDENT(GPIO_PF44))
+#define P_PPI0_D11     (P_DEFINED | P_IDENT(GPIO_PF43))
+#define P_PPI0_D10     (P_DEFINED | P_IDENT(GPIO_PF42))
+#define P_PPI0_D9      (P_DEFINED | P_IDENT(GPIO_PF41))
+#define P_PPI0_D8      (P_DEFINED | P_IDENT(GPIO_PF40))
+#define P_PPI0_D0      (P_DONTCARE)
+#define P_PPI0_D1      (P_DONTCARE)
+#define P_PPI0_D2      (P_DONTCARE)
+#define P_PPI0_D3      (P_DONTCARE)
+#define P_PPI0_D4      (P_DONTCARE)
+#define P_PPI0_D5      (P_DONTCARE)
+#define P_PPI0_D6      (P_DONTCARE)
+#define P_PPI0_D7      (P_DONTCARE)
+#define P_PPI1_CLK     (P_DONTCARE)
+#define P_PPI1_FS1     (P_DONTCARE)
+#define P_PPI1_FS2     (P_DONTCARE)
+#define P_PPI1_FS3     (P_DONTCARE)
+#define P_PPI1_D15     (P_DEFINED | P_IDENT(GPIO_PF39))
+#define P_PPI1_D14     (P_DEFINED | P_IDENT(GPIO_PF38))
+#define P_PPI1_D13     (P_DEFINED | P_IDENT(GPIO_PF37))
+#define P_PPI1_D12     (P_DEFINED | P_IDENT(GPIO_PF36))
+#define P_PPI1_D11     (P_DEFINED | P_IDENT(GPIO_PF35))
+#define P_PPI1_D10     (P_DEFINED | P_IDENT(GPIO_PF34))
+#define P_PPI1_D9      (P_DEFINED | P_IDENT(GPIO_PF33))
+#define P_PPI1_D8      (P_DEFINED | P_IDENT(GPIO_PF32))
+#define P_PPI1_D0      (P_DONTCARE)
+#define P_PPI1_D1      (P_DONTCARE)
+#define P_PPI1_D2      (P_DONTCARE)
+#define P_PPI1_D3      (P_DONTCARE)
+#define P_PPI1_D4      (P_DONTCARE)
+#define P_PPI1_D5      (P_DONTCARE)
+#define P_PPI1_D6      (P_DONTCARE)
+#define P_PPI1_D7      (P_DONTCARE)
+#define P_SPORT1_TSCLK (P_DEFINED | P_IDENT(GPIO_PF31))
+#define P_SPORT1_RSCLK (P_DEFINED | P_IDENT(GPIO_PF30))
+#define P_SPORT0_TSCLK (P_DEFINED | P_IDENT(GPIO_PF29))
+#define P_SPORT0_RSCLK (P_DEFINED | P_IDENT(GPIO_PF28))
+#define P_UART0_RX     (P_DEFINED | P_IDENT(GPIO_PF27))
+#define P_UART0_TX     (P_DEFINED | P_IDENT(GPIO_PF26))
+#define P_SPORT1_DRSEC (P_DEFINED | P_IDENT(GPIO_PF25))
+#define P_SPORT1_RFS   (P_DEFINED | P_IDENT(GPIO_PF24))
+#define P_SPORT1_DTPRI (P_DEFINED | P_IDENT(GPIO_PF23))
+#define P_SPORT1_DTSEC (P_DEFINED | P_IDENT(GPIO_PF22))
+#define P_SPORT1_TFS   (P_DEFINED | P_IDENT(GPIO_PF21))
+#define P_SPORT1_DRPRI (P_DONTCARE)
+#define P_SPORT0_DRSEC (P_DEFINED | P_IDENT(GPIO_PF20))
+#define P_SPORT0_RFS   (P_DEFINED | P_IDENT(GPIO_PF19))
+#define P_SPORT0_DTPRI (P_DEFINED | P_IDENT(GPIO_PF18))
+#define P_SPORT0_DTSEC (P_DEFINED | P_IDENT(GPIO_PF17))
+#define P_SPORT0_TFS   (P_DEFINED | P_IDENT(GPIO_PF16))
+#define P_SPORT0_DRPRI (P_DONTCARE)
+#define P_TMRCLK       (P_DEFINED | P_IDENT(GPIO_PF15))
+#define P_SPI0_SSEL7   (P_DEFINED | P_IDENT(GPIO_PF7))
+#define P_SPI0_SSEL6   (P_DEFINED | P_IDENT(GPIO_PF6))
+#define P_SPI0_SSEL5   (P_DEFINED | P_IDENT(GPIO_PF5))
+#define P_SPI0_SSEL4   (P_DEFINED | P_IDENT(GPIO_PF4))
+#define P_SPI0_SSEL3   (P_DEFINED | P_IDENT(GPIO_PF3))
+#define P_SPI0_SSEL2   (P_DEFINED | P_IDENT(GPIO_PF2))
+#define P_SPI0_SSEL1   (P_DEFINED | P_IDENT(GPIO_PF1))
+#define P_SPI0_SS      (P_DEFINED | P_IDENT(GPIO_PF0))
+#define P_TMR11                (P_DONTCARE)
+#define P_TMR10                (P_DONTCARE)
+#define P_TMR9         (P_DONTCARE)
+#define P_TMR8         (P_DONTCARE)
+#define P_TMR7         (P_DEFINED | P_IDENT(GPIO_PF7))
+#define P_TMR6         (P_DEFINED | P_IDENT(GPIO_PF6))
+#define P_TMR5         (P_DEFINED | P_IDENT(GPIO_PF5))
+#define P_TMR4         (P_DEFINED | P_IDENT(GPIO_PF4))
+#define P_TMR3         (P_DEFINED | P_IDENT(GPIO_PF3))
+#define P_TMR2         (P_DEFINED | P_IDENT(GPIO_PF2))
+#define P_TMR1         (P_DEFINED | P_IDENT(GPIO_PF1))
+#define P_TMR0         (P_DEFINED | P_IDENT(GPIO_PF0))
+#define P_SPI0_MOSI    (P_DONTCARE)
+#define P_SPI0_MIS0    (P_DONTCARE)
+#define P_SPI0_SCK     (P_DONTCARE)
+
+#endif /* _MACH_PORTMUX_H_ */
index 58f878947cbc171f3b8e0c824c39cbf100e9d10c..94ed381e560671b74374584b5d6459b4f8d0c426 100644 (file)
 #define bfin_write_SRAM_BASE_ADDRESS(val)    bfin_write32(SRAM_BASE_ADDRESS,val)
 #define bfin_read_DMEM_CONTROL()             bfin_read32(DMEM_CONTROL)
 #ifdef ANOMALY_05000125
-static __inline__ void bfin_write_DMEM_CONTROL(unsigned int val)
-{
-       unsigned long flags, iwr;
-
-       local_irq_save(flags);
-       __asm__(".align 8\n");
-       bfin_write32(IMEM_CONTROL, val);
-       __builtin_bfin_ssync();
-       local_irq_restore(flags);
-}
+extern void bfin_write_DMEM_CONTROL(unsigned int val);
 #else
 #define bfin_write_DMEM_CONTROL(val)         bfin_write32(DMEM_CONTROL,val)
 #endif
@@ -139,17 +130,7 @@ static __inline__ void bfin_write_DMEM_CONTROL(unsigned int val)
 */
 #define bfin_read_IMEM_CONTROL()             bfin_read32(IMEM_CONTROL)
 #ifdef ANOMALY_05000125
-static __inline__ void bfin_write_IMEM_CONTROL(unsigned int val)
-{
-       unsigned long flags, iwr;
-
-       local_irq_save(flags);
-       __asm__(".align 8\n");
-       bfin_write32(IMEM_CONTROL, val);
-       __builtin_bfin_ssync();
-       local_irq_restore(flags);
-
-}
+extern void bfin_write_IMEM_CONTROL(unsigned int val);
 #else
 #define bfin_write_IMEM_CONTROL(val)         bfin_write32(IMEM_CONTROL,val)
 #endif
index 4d504f908c0ce80867de94ab9f84050dfdeaf702..b58f5ad3f024bed59d328d9773b7675537a23fe0 100644 (file)
@@ -22,8 +22,6 @@
 #define MAP_NORESERVE  0x4000  /* don't check for reservations */
 #define MAP_POPULATE   0x8000  /* populate (prefault) pagetables */
 #define MAP_NONBLOCK   0x10000 /* do not block on IO */
-#define MAP_UNINITIALIZE 0x4000000  /* For anonymous mmap, memory could
-                                    be uninitialized. */
 
 #define MS_ASYNC       1       /* sync memory asynchronously */
 #define MS_INVALIDATE  2       /* invalidate the caches */
index ffad947f1b2a9c7884f7fea9efd65dedf82f64b7..8bc86717021c111452337c3812f259c8985129fa 100644 (file)
@@ -4,7 +4,11 @@
 /* PAGE_SHIFT determines the page size */
 
 #define PAGE_SHIFT     12
+#ifdef __ASSEMBLY__
+#define PAGE_SIZE      (1 << PAGE_SHIFT)
+#else
 #define PAGE_SIZE      (1UL << PAGE_SHIFT)
+#endif
 #define PAGE_MASK      (~(PAGE_SIZE-1))
 
 #ifdef __KERNEL__
diff --git a/include/asm-blackfin/portmux.h b/include/asm-blackfin/portmux.h
new file mode 100644 (file)
index 0000000..9d3681e
--- /dev/null
@@ -0,0 +1,1133 @@
+/*
+ * Common header file for blackfin family of processors.
+ *
+ */
+
+#ifndef _PORTMUX_H_
+#define _PORTMUX_H_
+
+#define P_IDENT(x)     ((x) & 0x1FF)
+#define P_FUNCT(x)     (((x) & 0x3) << 9)
+#define P_FUNCT2MUX(x) (((x) >> 9) & 0x3)
+#define P_DEFINED      0x8000
+#define P_UNDEF                0x4000
+#define P_MAYSHARE     0x2000
+#define P_DONTCARE     0x1000
+
+#include <asm/gpio.h>
+#include <asm/mach/portmux.h>
+
+#ifndef P_SPORT2_TFS
+#define P_SPORT2_TFS P_UNDEF
+#endif
+
+#ifndef P_SPORT2_DTSEC
+#define P_SPORT2_DTSEC P_UNDEF
+#endif
+
+#ifndef P_SPORT2_DTPRI
+#define P_SPORT2_DTPRI P_UNDEF
+#endif
+
+#ifndef P_SPORT2_TSCLK
+#define P_SPORT2_TSCLK P_UNDEF
+#endif
+
+#ifndef P_SPORT2_RFS
+#define P_SPORT2_RFS P_UNDEF
+#endif
+
+#ifndef P_SPORT2_DRSEC
+#define P_SPORT2_DRSEC P_UNDEF
+#endif
+
+#ifndef P_SPORT2_DRPRI
+#define P_SPORT2_DRPRI P_UNDEF
+#endif
+
+#ifndef P_SPORT2_RSCLK
+#define P_SPORT2_RSCLK P_UNDEF
+#endif
+
+#ifndef P_SPORT3_TFS
+#define P_SPORT3_TFS P_UNDEF
+#endif
+
+#ifndef P_SPORT3_DTSEC
+#define P_SPORT3_DTSEC P_UNDEF
+#endif
+
+#ifndef P_SPORT3_DTPRI
+#define P_SPORT3_DTPRI P_UNDEF
+#endif
+
+#ifndef P_SPORT3_TSCLK
+#define P_SPORT3_TSCLK P_UNDEF
+#endif
+
+#ifndef P_SPORT3_RFS
+#define P_SPORT3_RFS P_UNDEF
+#endif
+
+#ifndef P_SPORT3_DRSEC
+#define P_SPORT3_DRSEC P_UNDEF
+#endif
+
+#ifndef P_SPORT3_DRPRI
+#define P_SPORT3_DRPRI P_UNDEF
+#endif
+
+#ifndef P_SPORT3_RSCLK
+#define P_SPORT3_RSCLK P_UNDEF
+#endif
+
+#ifndef P_TMR4
+#define P_TMR4 P_UNDEF
+#endif
+
+#ifndef P_TMR5
+#define P_TMR5 P_UNDEF
+#endif
+
+#ifndef P_TMR6
+#define P_TMR6 P_UNDEF
+#endif
+
+#ifndef P_TMR7
+#define P_TMR7 P_UNDEF
+#endif
+
+#ifndef P_TWI1_SCL
+#define P_TWI1_SCL P_UNDEF
+#endif
+
+#ifndef P_TWI1_SDA
+#define P_TWI1_SDA P_UNDEF
+#endif
+
+#ifndef P_UART3_RTS
+#define P_UART3_RTS P_UNDEF
+#endif
+
+#ifndef P_UART3_CTS
+#define P_UART3_CTS P_UNDEF
+#endif
+
+#ifndef P_UART2_TX
+#define P_UART2_TX P_UNDEF
+#endif
+
+#ifndef P_UART2_RX
+#define P_UART2_RX P_UNDEF
+#endif
+
+#ifndef P_UART3_TX
+#define P_UART3_TX P_UNDEF
+#endif
+
+#ifndef P_UART3_RX
+#define P_UART3_RX P_UNDEF
+#endif
+
+#ifndef P_SPI2_SS
+#define P_SPI2_SS P_UNDEF
+#endif
+
+#ifndef P_SPI2_SSEL1
+#define P_SPI2_SSEL1 P_UNDEF
+#endif
+
+#ifndef P_SPI2_SSEL2
+#define P_SPI2_SSEL2 P_UNDEF
+#endif
+
+#ifndef P_SPI2_SSEL3
+#define P_SPI2_SSEL3 P_UNDEF
+#endif
+
+#ifndef P_SPI2_SCK
+#define P_SPI2_SCK P_UNDEF
+#endif
+
+#ifndef P_SPI2_MOSI
+#define P_SPI2_MOSI P_UNDEF
+#endif
+
+#ifndef P_SPI2_MISO
+#define P_SPI2_MISO P_UNDEF
+#endif
+
+#ifndef P_TMR0
+#define P_TMR0 P_UNDEF
+#endif
+
+#ifndef P_TMR1
+#define P_TMR1 P_UNDEF
+#endif
+
+#ifndef P_TMR2
+#define P_TMR2 P_UNDEF
+#endif
+
+#ifndef P_TMR3
+#define P_TMR3 P_UNDEF
+#endif
+
+#ifndef P_SPORT0_TFS
+#define P_SPORT0_TFS P_UNDEF
+#endif
+
+#ifndef P_SPORT0_DTSEC
+#define P_SPORT0_DTSEC P_UNDEF
+#endif
+
+#ifndef P_SPORT0_DTPRI
+#define P_SPORT0_DTPRI P_UNDEF
+#endif
+
+#ifndef P_SPORT0_TSCLK
+#define P_SPORT0_TSCLK P_UNDEF
+#endif
+
+#ifndef P_SPORT0_RFS
+#define P_SPORT0_RFS P_UNDEF
+#endif
+
+#ifndef P_SPORT0_DRSEC
+#define P_SPORT0_DRSEC P_UNDEF
+#endif
+
+#ifndef P_SPORT0_DRPRI
+#define P_SPORT0_DRPRI P_UNDEF
+#endif
+
+#ifndef P_SPORT0_RSCLK
+#define P_SPORT0_RSCLK P_UNDEF
+#endif
+
+#ifndef P_SD_D0
+#define P_SD_D0 P_UNDEF
+#endif
+
+#ifndef P_SD_D1
+#define P_SD_D1 P_UNDEF
+#endif
+
+#ifndef P_SD_D2
+#define P_SD_D2 P_UNDEF
+#endif
+
+#ifndef P_SD_D3
+#define P_SD_D3 P_UNDEF
+#endif
+
+#ifndef P_SD_CLK
+#define P_SD_CLK P_UNDEF
+#endif
+
+#ifndef P_SD_CMD
+#define P_SD_CMD P_UNDEF
+#endif
+
+#ifndef P_MMCLK
+#define P_MMCLK P_UNDEF
+#endif
+
+#ifndef P_MBCLK
+#define P_MBCLK P_UNDEF
+#endif
+
+#ifndef P_PPI1_D0
+#define P_PPI1_D0 P_UNDEF
+#endif
+
+#ifndef P_PPI1_D1
+#define P_PPI1_D1 P_UNDEF
+#endif
+
+#ifndef P_PPI1_D2
+#define P_PPI1_D2 P_UNDEF
+#endif
+
+#ifndef P_PPI1_D3
+#define P_PPI1_D3 P_UNDEF
+#endif
+
+#ifndef P_PPI1_D4
+#define P_PPI1_D4 P_UNDEF
+#endif
+
+#ifndef P_PPI1_D5
+#define P_PPI1_D5 P_UNDEF
+#endif
+
+#ifndef P_PPI1_D6
+#define P_PPI1_D6 P_UNDEF
+#endif
+
+#ifndef P_PPI1_D7
+#define P_PPI1_D7 P_UNDEF
+#endif
+
+#ifndef P_PPI1_D8
+#define P_PPI1_D8 P_UNDEF
+#endif
+
+#ifndef P_PPI1_D9
+#define P_PPI1_D9 P_UNDEF
+#endif
+
+#ifndef P_PPI1_D10
+#define P_PPI1_D10 P_UNDEF
+#endif
+
+#ifndef P_PPI1_D11
+#define P_PPI1_D11 P_UNDEF
+#endif
+
+#ifndef P_PPI1_D12
+#define P_PPI1_D12 P_UNDEF
+#endif
+
+#ifndef P_PPI1_D13
+#define P_PPI1_D13 P_UNDEF
+#endif
+
+#ifndef P_PPI1_D14
+#define P_PPI1_D14 P_UNDEF
+#endif
+
+#ifndef P_PPI1_D15
+#define P_PPI1_D15 P_UNDEF
+#endif
+
+#ifndef P_HOST_D8
+#define P_HOST_D8 P_UNDEF
+#endif
+
+#ifndef P_HOST_D9
+#define P_HOST_D9 P_UNDEF
+#endif
+
+#ifndef P_HOST_D10
+#define P_HOST_D10 P_UNDEF
+#endif
+
+#ifndef P_HOST_D11
+#define P_HOST_D11 P_UNDEF
+#endif
+
+#ifndef P_HOST_D12
+#define P_HOST_D12 P_UNDEF
+#endif
+
+#ifndef P_HOST_D13
+#define P_HOST_D13 P_UNDEF
+#endif
+
+#ifndef P_HOST_D14
+#define P_HOST_D14 P_UNDEF
+#endif
+
+#ifndef P_HOST_D15
+#define P_HOST_D15 P_UNDEF
+#endif
+
+#ifndef P_HOST_D0
+#define P_HOST_D0 P_UNDEF
+#endif
+
+#ifndef P_HOST_D1
+#define P_HOST_D1 P_UNDEF
+#endif
+
+#ifndef P_HOST_D2
+#define P_HOST_D2 P_UNDEF
+#endif
+
+#ifndef P_HOST_D3
+#define P_HOST_D3 P_UNDEF
+#endif
+
+#ifndef P_HOST_D4
+#define P_HOST_D4 P_UNDEF
+#endif
+
+#ifndef P_HOST_D5
+#define P_HOST_D5 P_UNDEF
+#endif
+
+#ifndef P_HOST_D6
+#define P_HOST_D6 P_UNDEF
+#endif
+
+#ifndef P_HOST_D7
+#define P_HOST_D7 P_UNDEF
+#endif
+
+#ifndef P_SPORT1_TFS
+#define P_SPORT1_TFS P_UNDEF
+#endif
+
+#ifndef P_SPORT1_DTSEC
+#define P_SPORT1_DTSEC P_UNDEF
+#endif
+
+#ifndef P_SPORT1_DTPRI
+#define P_SPORT1_DTPRI P_UNDEF
+#endif
+
+#ifndef P_SPORT1_TSCLK
+#define P_SPORT1_TSCLK P_UNDEF
+#endif
+
+#ifndef P_SPORT1_RFS
+#define P_SPORT1_RFS P_UNDEF
+#endif
+
+#ifndef P_SPORT1_DRSEC
+#define P_SPORT1_DRSEC P_UNDEF
+#endif
+
+#ifndef P_SPORT1_DRPRI
+#define P_SPORT1_DRPRI P_UNDEF
+#endif
+
+#ifndef P_SPORT1_RSCLK
+#define P_SPORT1_RSCLK P_UNDEF
+#endif
+
+#ifndef P_PPI2_D0
+#define P_PPI2_D0 P_UNDEF
+#endif
+
+#ifndef P_PPI2_D1
+#define P_PPI2_D1 P_UNDEF
+#endif
+
+#ifndef P_PPI2_D2
+#define P_PPI2_D2 P_UNDEF
+#endif
+
+#ifndef P_PPI2_D3
+#define P_PPI2_D3 P_UNDEF
+#endif
+
+#ifndef P_PPI2_D4
+#define P_PPI2_D4 P_UNDEF
+#endif
+
+#ifndef P_PPI2_D5
+#define P_PPI2_D5 P_UNDEF
+#endif
+
+#ifndef P_PPI2_D6
+#define P_PPI2_D6 P_UNDEF
+#endif
+
+#ifndef P_PPI2_D7
+#define P_PPI2_D7 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D18
+#define P_PPI0_D18 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D19
+#define P_PPI0_D19 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D20
+#define P_PPI0_D20 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D21
+#define P_PPI0_D21 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D22
+#define P_PPI0_D22 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D23
+#define P_PPI0_D23 P_UNDEF
+#endif
+
+#ifndef P_KEY_ROW0
+#define P_KEY_ROW0 P_UNDEF
+#endif
+
+#ifndef P_KEY_ROW1
+#define P_KEY_ROW1 P_UNDEF
+#endif
+
+#ifndef P_KEY_ROW2
+#define P_KEY_ROW2 P_UNDEF
+#endif
+
+#ifndef P_KEY_ROW3
+#define P_KEY_ROW3 P_UNDEF
+#endif
+
+#ifndef P_KEY_COL0
+#define P_KEY_COL0 P_UNDEF
+#endif
+
+#ifndef P_KEY_COL1
+#define P_KEY_COL1 P_UNDEF
+#endif
+
+#ifndef P_KEY_COL2
+#define P_KEY_COL2 P_UNDEF
+#endif
+
+#ifndef P_KEY_COL3
+#define P_KEY_COL3 P_UNDEF
+#endif
+
+#ifndef P_SPI0_SCK
+#define P_SPI0_SCK P_UNDEF
+#endif
+
+#ifndef P_SPI0_MISO
+#define P_SPI0_MISO P_UNDEF
+#endif
+
+#ifndef P_SPI0_MOSI
+#define P_SPI0_MOSI P_UNDEF
+#endif
+
+#ifndef P_SPI0_SS
+#define P_SPI0_SS P_UNDEF
+#endif
+
+#ifndef P_SPI0_SSEL1
+#define P_SPI0_SSEL1 P_UNDEF
+#endif
+
+#ifndef P_SPI0_SSEL2
+#define P_SPI0_SSEL2 P_UNDEF
+#endif
+
+#ifndef P_SPI0_SSEL3
+#define P_SPI0_SSEL3 P_UNDEF
+#endif
+
+#ifndef P_UART0_TX
+#define P_UART0_TX P_UNDEF
+#endif
+
+#ifndef P_UART0_RX
+#define P_UART0_RX P_UNDEF
+#endif
+
+#ifndef P_UART1_RTS
+#define P_UART1_RTS P_UNDEF
+#endif
+
+#ifndef P_UART1_CTS
+#define P_UART1_CTS P_UNDEF
+#endif
+
+#ifndef P_PPI1_CLK
+#define P_PPI1_CLK P_UNDEF
+#endif
+
+#ifndef P_PPI1_FS1
+#define P_PPI1_FS1 P_UNDEF
+#endif
+
+#ifndef P_PPI1_FS2
+#define P_PPI1_FS2 P_UNDEF
+#endif
+
+#ifndef P_TWI0_SCL
+#define P_TWI0_SCL P_UNDEF
+#endif
+
+#ifndef P_TWI0_SDA
+#define P_TWI0_SDA P_UNDEF
+#endif
+
+#ifndef P_KEY_COL7
+#define P_KEY_COL7 P_UNDEF
+#endif
+
+#ifndef P_KEY_ROW6
+#define P_KEY_ROW6 P_UNDEF
+#endif
+
+#ifndef P_KEY_COL6
+#define P_KEY_COL6 P_UNDEF
+#endif
+
+#ifndef P_KEY_ROW5
+#define P_KEY_ROW5 P_UNDEF
+#endif
+
+#ifndef P_KEY_COL5
+#define P_KEY_COL5 P_UNDEF
+#endif
+
+#ifndef P_KEY_ROW4
+#define P_KEY_ROW4 P_UNDEF
+#endif
+
+#ifndef P_KEY_COL4
+#define P_KEY_COL4 P_UNDEF
+#endif
+
+#ifndef P_KEY_ROW7
+#define P_KEY_ROW7 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D0
+#define P_PPI0_D0 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D1
+#define P_PPI0_D1 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D2
+#define P_PPI0_D2 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D3
+#define P_PPI0_D3 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D4
+#define P_PPI0_D4 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D5
+#define P_PPI0_D5 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D6
+#define P_PPI0_D6 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D7
+#define P_PPI0_D7 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D8
+#define P_PPI0_D8 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D9
+#define P_PPI0_D9 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D10
+#define P_PPI0_D10 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D11
+#define P_PPI0_D11 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D12
+#define P_PPI0_D12 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D13
+#define P_PPI0_D13 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D14
+#define P_PPI0_D14 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D15
+#define P_PPI0_D15 P_UNDEF
+#endif
+
+#ifndef P_ATAPI_D0A
+#define P_ATAPI_D0A P_UNDEF
+#endif
+
+#ifndef P_ATAPI_D1A
+#define P_ATAPI_D1A P_UNDEF
+#endif
+
+#ifndef P_ATAPI_D2A
+#define P_ATAPI_D2A P_UNDEF
+#endif
+
+#ifndef P_ATAPI_D3A
+#define P_ATAPI_D3A P_UNDEF
+#endif
+
+#ifndef P_ATAPI_D4A
+#define P_ATAPI_D4A P_UNDEF
+#endif
+
+#ifndef P_ATAPI_D5A
+#define P_ATAPI_D5A P_UNDEF
+#endif
+
+#ifndef P_ATAPI_D6A
+#define P_ATAPI_D6A P_UNDEF
+#endif
+
+#ifndef P_ATAPI_D7A
+#define P_ATAPI_D7A P_UNDEF
+#endif
+
+#ifndef P_ATAPI_D8A
+#define P_ATAPI_D8A P_UNDEF
+#endif
+
+#ifndef P_ATAPI_D9A
+#define P_ATAPI_D9A P_UNDEF
+#endif
+
+#ifndef P_ATAPI_D10A
+#define P_ATAPI_D10A P_UNDEF
+#endif
+
+#ifndef P_ATAPI_D11A
+#define P_ATAPI_D11A P_UNDEF
+#endif
+
+#ifndef P_ATAPI_D12A
+#define P_ATAPI_D12A P_UNDEF
+#endif
+
+#ifndef P_ATAPI_D13A
+#define P_ATAPI_D13A P_UNDEF
+#endif
+
+#ifndef P_ATAPI_D14A
+#define P_ATAPI_D14A P_UNDEF
+#endif
+
+#ifndef P_ATAPI_D15A
+#define P_ATAPI_D15A P_UNDEF
+#endif
+
+#ifndef P_PPI0_CLK
+#define P_PPI0_CLK P_UNDEF
+#endif
+
+#ifndef P_PPI0_FS1
+#define P_PPI0_FS1 P_UNDEF
+#endif
+
+#ifndef P_PPI0_FS2
+#define P_PPI0_FS2 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D16
+#define P_PPI0_D16 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D17
+#define P_PPI0_D17 P_UNDEF
+#endif
+
+#ifndef P_SPI1_SSEL1
+#define P_SPI1_SSEL1 P_UNDEF
+#endif
+
+#ifndef P_SPI1_SSEL2
+#define P_SPI1_SSEL2 P_UNDEF
+#endif
+
+#ifndef P_SPI1_SSEL3
+#define P_SPI1_SSEL3 P_UNDEF
+#endif
+
+#ifndef P_SPI1_SCK
+#define P_SPI1_SCK P_UNDEF
+#endif
+
+#ifndef P_SPI1_MISO
+#define P_SPI1_MISO P_UNDEF
+#endif
+
+#ifndef P_SPI1_MOSI
+#define P_SPI1_MOSI P_UNDEF
+#endif
+
+#ifndef P_SPI1_SS
+#define P_SPI1_SS P_UNDEF
+#endif
+
+#ifndef P_CAN0_TX
+#define P_CAN0_TX P_UNDEF
+#endif
+
+#ifndef P_CAN0_RX
+#define P_CAN0_RX P_UNDEF
+#endif
+
+#ifndef P_CAN1_TX
+#define P_CAN1_TX P_UNDEF
+#endif
+
+#ifndef P_CAN1_RX
+#define P_CAN1_RX P_UNDEF
+#endif
+
+#ifndef P_ATAPI_A0A
+#define P_ATAPI_A0A P_UNDEF
+#endif
+
+#ifndef P_ATAPI_A1A
+#define P_ATAPI_A1A P_UNDEF
+#endif
+
+#ifndef P_ATAPI_A2A
+#define P_ATAPI_A2A P_UNDEF
+#endif
+
+#ifndef P_HOST_CE
+#define P_HOST_CE P_UNDEF
+#endif
+
+#ifndef P_HOST_RD
+#define P_HOST_RD P_UNDEF
+#endif
+
+#ifndef P_HOST_WR
+#define P_HOST_WR P_UNDEF
+#endif
+
+#ifndef P_MTXONB
+#define P_MTXONB P_UNDEF
+#endif
+
+#ifndef P_PPI2_FS2
+#define P_PPI2_FS2 P_UNDEF
+#endif
+
+#ifndef P_PPI2_FS1
+#define P_PPI2_FS1 P_UNDEF
+#endif
+
+#ifndef P_PPI2_CLK
+#define P_PPI2_CLK P_UNDEF
+#endif
+
+#ifndef P_CNT_CZM
+#define P_CNT_CZM P_UNDEF
+#endif
+
+#ifndef P_UART1_TX
+#define P_UART1_TX P_UNDEF
+#endif
+
+#ifndef P_UART1_RX
+#define P_UART1_RX P_UNDEF
+#endif
+
+#ifndef P_ATAPI_RESET
+#define P_ATAPI_RESET P_UNDEF
+#endif
+
+#ifndef P_HOST_ADDR
+#define P_HOST_ADDR P_UNDEF
+#endif
+
+#ifndef P_HOST_ACK
+#define P_HOST_ACK P_UNDEF
+#endif
+
+#ifndef P_MTX
+#define P_MTX P_UNDEF
+#endif
+
+#ifndef P_MRX
+#define P_MRX P_UNDEF
+#endif
+
+#ifndef P_MRXONB
+#define P_MRXONB P_UNDEF
+#endif
+
+#ifndef P_A4
+#define P_A4 P_UNDEF
+#endif
+
+#ifndef P_A5
+#define P_A5 P_UNDEF
+#endif
+
+#ifndef P_A6
+#define P_A6 P_UNDEF
+#endif
+
+#ifndef P_A7
+#define P_A7 P_UNDEF
+#endif
+
+#ifndef P_A8
+#define P_A8 P_UNDEF
+#endif
+
+#ifndef P_A9
+#define P_A9 P_UNDEF
+#endif
+
+#ifndef P_PPI1_FS3
+#define P_PPI1_FS3 P_UNDEF
+#endif
+
+#ifndef P_PPI2_FS3
+#define P_PPI2_FS3 P_UNDEF
+#endif
+
+#ifndef P_TMR8
+#define P_TMR8 P_UNDEF
+#endif
+
+#ifndef P_TMR9
+#define P_TMR9 P_UNDEF
+#endif
+
+#ifndef P_TMR10
+#define P_TMR10 P_UNDEF
+#endif
+#ifndef P_TMR11
+#define P_TMR11 P_UNDEF
+#endif
+
+#ifndef P_DMAR0
+#define P_DMAR0 P_UNDEF
+#endif
+
+#ifndef P_DMAR1
+#define P_DMAR1 P_UNDEF
+#endif
+
+#ifndef P_PPI0_FS3
+#define P_PPI0_FS3 P_UNDEF
+#endif
+
+#ifndef P_CNT_CDG
+#define P_CNT_CDG P_UNDEF
+#endif
+
+#ifndef P_CNT_CUD
+#define P_CNT_CUD P_UNDEF
+#endif
+
+#ifndef P_A10
+#define P_A10 P_UNDEF
+#endif
+
+#ifndef P_A11
+#define P_A11 P_UNDEF
+#endif
+
+#ifndef P_A12
+#define P_A12 P_UNDEF
+#endif
+
+#ifndef P_A13
+#define P_A13 P_UNDEF
+#endif
+
+#ifndef P_A14
+#define P_A14 P_UNDEF
+#endif
+
+#ifndef P_A15
+#define P_A15 P_UNDEF
+#endif
+
+#ifndef P_A16
+#define P_A16 P_UNDEF
+#endif
+
+#ifndef P_A17
+#define P_A17 P_UNDEF
+#endif
+
+#ifndef P_A18
+#define P_A18 P_UNDEF
+#endif
+
+#ifndef P_A19
+#define P_A19 P_UNDEF
+#endif
+
+#ifndef P_A20
+#define P_A20 P_UNDEF
+#endif
+
+#ifndef P_A21
+#define P_A21 P_UNDEF
+#endif
+
+#ifndef P_A22
+#define P_A22 P_UNDEF
+#endif
+
+#ifndef P_A23
+#define P_A23 P_UNDEF
+#endif
+
+#ifndef P_A24
+#define P_A24 P_UNDEF
+#endif
+
+#ifndef P_A25
+#define P_A25 P_UNDEF
+#endif
+
+#ifndef P_NOR_CLK
+#define P_NOR_CLK P_UNDEF
+#endif
+
+#ifndef  P_TMRCLK
+#define  P_TMRCLK P_UNDEF
+#endif
+
+#ifndef P_AMC_ARDY_NOR_WAIT
+#define P_AMC_ARDY_NOR_WAIT P_UNDEF
+#endif
+
+#ifndef P_NAND_CE
+#define P_NAND_CE P_UNDEF
+#endif
+
+#ifndef P_NAND_RB
+#define P_NAND_RB P_UNDEF
+#endif
+
+#ifndef P_ATAPI_DIOR
+#define P_ATAPI_DIOR P_UNDEF
+#endif
+
+#ifndef P_ATAPI_DIOW
+#define P_ATAPI_DIOW P_UNDEF
+#endif
+
+#ifndef P_ATAPI_CS0
+#define P_ATAPI_CS0 P_UNDEF
+#endif
+
+#ifndef P_ATAPI_CS1
+#define P_ATAPI_CS1 P_UNDEF
+#endif
+
+#ifndef P_ATAPI_DMACK
+#define P_ATAPI_DMACK P_UNDEF
+#endif
+
+#ifndef P_ATAPI_DMARQ
+#define P_ATAPI_DMARQ P_UNDEF
+#endif
+
+#ifndef P_ATAPI_INTRQ
+#define P_ATAPI_INTRQ P_UNDEF
+#endif
+
+#ifndef P_ATAPI_IORDY
+#define P_ATAPI_IORDY P_UNDEF
+#endif
+
+#ifndef P_AMC_BR
+#define P_AMC_BR P_UNDEF
+#endif
+
+#ifndef P_AMC_BG
+#define P_AMC_BG P_UNDEF
+#endif
+
+#ifndef P_AMC_BGH
+#define P_AMC_BGH P_UNDEF
+#endif
+
+/* EMAC */
+
+#ifndef P_MII0_ETxD0
+#define P_MII0_ETxD0 P_UNDEF
+#endif
+
+#ifndef P_MII0_ETxD1
+#define P_MII0_ETxD1 P_UNDEF
+#endif
+
+#ifndef P_MII0_ETxD2
+#define P_MII0_ETxD2 P_UNDEF
+#endif
+
+#ifndef P_MII0_ETxD3
+#define P_MII0_ETxD3 P_UNDEF
+#endif
+
+#ifndef P_MII0_ETxEN
+#define P_MII0_ETxEN P_UNDEF
+#endif
+
+#ifndef P_MII0_TxCLK
+#define P_MII0_TxCLK P_UNDEF
+#endif
+
+#ifndef P_MII0_PHYINT
+#define P_MII0_PHYINT P_UNDEF
+#endif
+
+#ifndef P_MII0_COL
+#define P_MII0_COL P_UNDEF
+#endif
+
+#ifndef P_MII0_ERxD0
+#define P_MII0_ERxD0 P_UNDEF
+#endif
+
+#ifndef P_MII0_ERxD1
+#define P_MII0_ERxD1 P_UNDEF
+#endif
+
+#ifndef P_MII0_ERxD2
+#define P_MII0_ERxD2 P_UNDEF
+#endif
+
+#ifndef P_MII0_ERxD3
+#define P_MII0_ERxD3 P_UNDEF
+#endif
+
+#ifndef P_MII0_ERxDV
+#define P_MII0_ERxDV P_UNDEF
+#endif
+
+#ifndef P_MII0_ERxCLK
+#define P_MII0_ERxCLK P_UNDEF
+#endif
+
+#ifndef P_MII0_ERxER
+#define P_MII0_ERxER P_UNDEF
+#endif
+
+#ifndef P_MII0_CRS
+#define P_MII0_CRS P_UNDEF
+#endif
+
+#ifndef P_RMII0_REF_CLK
+#define P_RMII0_REF_CLK P_UNDEF
+#endif
+
+#ifndef P_RMII0_MDINT
+#define P_RMII0_MDINT P_UNDEF
+#endif
+
+#ifndef P_RMII0_CRS_DV
+#define P_RMII0_CRS_DV P_UNDEF
+#endif
+
+#ifndef P_MDC
+#define P_MDC P_UNDEF
+#endif
+
+#ifndef P_MDIO
+#define P_MDIO P_UNDEF
+#endif
+
+#endif                         /* _PORTMUX_H_ */
index 2fd9dabdba77819008909950244ae9e7e102984a..4eac38de8ce173f94c94a1215c95727f17017c1d 100644 (file)
@@ -17,6 +17,17 @@ struct termios {
        cc_t c_cc[NCCS];        /* control characters */
 };
 
+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 */
+       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 */
diff --git a/include/asm-blackfin/trace.h b/include/asm-blackfin/trace.h
new file mode 100644 (file)
index 0000000..9c2474c
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Common header file for blackfin family of processors.
+ *
+ */
+
+#ifndef _BLACKFIN_TRACE_
+#define _BLACKFIN_TRACE_
+
+#ifndef __ASSEMBLY__
+/* Trace Macros for C files */
+
+#define trace_buffer_save(x) \
+        do { \
+                (x) = bfin_read_TBUFCTL(); \
+                bfin_write_TBUFCTL((x) & ~TBUFEN); \
+        } while (0)
+
+#define trace_buffer_restore(x) \
+        do { \
+                bfin_write_TBUFCTL((x));        \
+        } while (0)
+
+#else
+/* Trace Macros for Assembly files */
+
+#define TRACE_BUFFER_START(preg, dreg) trace_buffer_start(preg, dreg)
+#define TRACE_BUFFER_STOP(preg, dreg)  trace_buffer_stop(preg, dreg)
+
+#define trace_buffer_stop(preg, dreg)  \
+       preg.L = LO(TBUFCTL);           \
+       preg.H = HI(TBUFCTL);           \
+       dreg = 0x1;                     \
+       [preg] = dreg;
+
+#define trace_buffer_start(preg, dreg) \
+       preg.L = LO(TBUFCTL);           \
+       preg.H = HI(TBUFCTL);           \
+       dreg = 0x13;                    \
+       [preg] = dreg;
+
+#ifdef CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE
+# define DEBUG_START_HWTRACE(preg, dreg) trace_buffer_start(preg, dreg)
+# define DEBUG_STOP_HWTRACE(preg, dreg) trace_buffer_stop(preg, dreg)
+
+#else
+# define DEBUG_START_HWTRACE(preg, dreg)
+# define DEBUG_STOP_HWTRACE(preg, dreg)
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#endif                         /* _BLACKFIN_TRACE_ */
index b2ac8a331da1f9d17fdaf7c60a80b4b9a6ba895b..730ce40fdd0fca1674e220abd4ffe75d10304339 100644 (file)
@@ -52,47 +52,11 @@ struct pci_dev;
 #define pci_unmap_len(PTR, LEN_NAME)           (0)
 #define pci_unmap_len_set(PTR, LEN_NAME, VAL)  do { } while (0)
 
-/* This is always fine. */
-#define pci_dac_dma_supported(pci_dev, mask)   (1)
-
-static inline dma64_addr_t
-pci_dac_page_to_dma(struct pci_dev *pdev, struct page *page, unsigned long offset, int direction)
-{
-       return ((dma64_addr_t) page_to_phys(page) +
-               (dma64_addr_t) offset);
-}
-
-static inline struct page *
-pci_dac_dma_to_page(struct pci_dev *pdev, dma64_addr_t dma_addr)
-{
-       return pfn_to_page(dma_addr >> PAGE_SHIFT);
-}
-
-static inline unsigned long
-pci_dac_dma_to_offset(struct pci_dev *pdev, dma64_addr_t dma_addr)
-{
-       return (dma_addr & ~PAGE_MASK);
-}
-
-static inline void
-pci_dac_dma_sync_single_for_cpu(struct pci_dev *pdev, dma64_addr_t dma_addr, size_t len, int direction)
-{
-}
-
-static inline void
-pci_dac_dma_sync_single_for_device(struct pci_dev *pdev, dma64_addr_t dma_addr, size_t len, int direction)
-{
-}
-
 #define HAVE_PCI_MMAP
 extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
                               enum pci_mmap_state mmap_state, int write_combine);
 
 
-static inline void pcibios_add_platform_entries(struct pci_dev *dev)
-{
-}
-
 #endif /* __KERNEL__ */
 
 /* implement the pci_ DMA API in terms of the generic device dma_ one */
index 8d8cec225fe1c37aed157383dc5f1c9c4152db79..6cc2e2736f7ba307c8a7153663f838ba02caeab5 100644 (file)
@@ -19,6 +19,17 @@ struct termios {
        cc_t c_cc[NCCS];                /* control characters */
 };
 
+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 */
+       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 */
index f35a4511e7b91c7a0f815b911678f13edc891005..585d9b49949a7537d9d1f89221f93c047cfedacf 100644 (file)
@@ -22,10 +22,6 @@ struct pci_dev;
 
 #define pcibios_assign_all_busses()    0
 
-static inline void pcibios_add_platform_entries(struct pci_dev *dev)
-{
-}
-
 extern void pcibios_set_master(struct pci_dev *dev);
 
 extern void pcibios_penalize_isa_irq(int irq);
@@ -44,9 +40,6 @@ extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
 extern void pci_free_consistent(struct pci_dev *hwdev, size_t size,
                                void *vaddr, dma_addr_t dma_handle);
 
-/* This is always fine. */
-#define pci_dac_dma_supported(pci_dev, mask)   (1)
-
 /* Return the index of the PCI controller for device PDEV. */
 #define pci_controller_num(PDEV)       (0)
 
index 2d6d389cff49886f1aa6ac1bd1ddafcf918d5ead..74851b424d4fd9bd3639e72d07becc5a9993a94e 100644 (file)
@@ -17,6 +17,17 @@ struct termios {
        cc_t c_cc[NCCS];                /* control characters */
 };
 
+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 */
+       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 */
index 815bb01480601f7ca1a96e81113fb030df89062d..604fab7031a62e2a8ae2f0cde8022362fd89c38b 100644 (file)
@@ -6,28 +6,23 @@
 
 /*
  * Every architecture must define this function. It's the fastest
- * way of searching a 140-bit bitmap where the first 100 bits are
- * unlikely to be set. It's guaranteed that at least one of the 140
- * bits is cleared.
+ * way of searching a 100-bit bitmap.  It's guaranteed that at least
+ * one of the 100 bits is cleared.
  */
 static inline int sched_find_first_bit(const unsigned long *b)
 {
 #if BITS_PER_LONG == 64
-       if (unlikely(b[0]))
+       if (b[0])
                return __ffs(b[0]);
-       if (likely(b[1]))
-               return __ffs(b[1]) + 64;
-       return __ffs(b[2]) + 128;
+       return __ffs(b[1]) + 64;
 #elif BITS_PER_LONG == 32
-       if (unlikely(b[0]))
+       if (b[0])
                return __ffs(b[0]);
-       if (unlikely(b[1]))
+       if (b[1])
                return __ffs(b[1]) + 32;
-       if (unlikely(b[2]))
+       if (b[2])
                return __ffs(b[2]) + 64;
-       if (b[3])
-               return __ffs(b[3]) + 96;
-       return __ffs(b[4]) + 128;
+       return __ffs(b[3]) + 96;
 #else
 #error BITS_PER_LONG not defined
 #endif
index 0c771b05fdd5db25bdb6210aa28fb0457f25c950..97389b35aa3540f0fbd734afe9fc30c0d61c76de 100644 (file)
@@ -22,8 +22,4 @@ static inline void pcibios_penalize_isa_irq(int irq, int active)
 
 #define PCI_DMA_BUS_IS_PHYS    (1)
 
-static inline void pcibios_add_platform_entries(struct pci_dev *dev)
-{
-}
-
 #endif /* _ASM_H8300_PCI_H */
index 6a1f4d3807b48fd5510f9ec79eccaad2480567f7..e877b40ac5ba4762d80cb386e1511d21eb95d9df 100644 (file)
@@ -17,6 +17,17 @@ struct termios {
        cc_t c_cc[NCCS];                /* control characters */
 };
 
+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 */
+       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 */
index bd024ab4fe53b02f6e9b0fe678defb0d1a982242..ed8affbf96cb804f3a97ec46d610fdec19345a2b 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _LINUX_BOOT_H
-#define _LINUX_BOOT_H
+#ifndef _ASM_BOOT_H
+#define _ASM_BOOT_H
 
 /* Don't touch these, unless you really know what you're doing. */
 #define DEF_INITSEG    0x9000
@@ -17,4 +17,4 @@
                                + (CONFIG_PHYSICAL_ALIGN - 1)) \
                                & ~(CONFIG_PHYSICAL_ALIGN - 1))
 
-#endif /* _LINUX_BOOT_H */
+#endif /* _ASM_BOOT_H */
diff --git a/include/asm-i386/bootparam.h b/include/asm-i386/bootparam.h
new file mode 100644 (file)
index 0000000..427d865
--- /dev/null
@@ -0,0 +1,85 @@
+#ifndef _ASM_BOOTPARAM_H
+#define _ASM_BOOTPARAM_H
+
+#include <linux/types.h>
+#include <linux/screen_info.h>
+#include <linux/apm_bios.h>
+#include <asm/e820.h>
+#include <linux/edd.h>
+#include <video/edid.h>
+
+struct setup_header {
+       u8      setup_sects;
+       u16     root_flags;
+       u32     syssize;
+       u16     ram_size;
+       u16     vid_mode;
+       u16     root_dev;
+       u16     boot_flag;
+       u16     jump;
+       u32     header;
+       u16     version;
+       u32     realmode_swtch;
+       u16     start_sys;
+       u16     kernel_version;
+       u8      type_of_loader;
+       u8      loadflags;
+#define LOADED_HIGH    0x01
+#define CAN_USE_HEAP   0x80
+       u16     setup_move_size;
+       u32     code32_start;
+       u32     ramdisk_image;
+       u32     ramdisk_size;
+       u32     bootsect_kludge;
+       u16     heap_end_ptr;
+       u16     _pad1;
+       u32     cmd_line_ptr;
+       u32     initrd_addr_max;
+       u32     kernel_alignment;
+       u8      relocatable_kernel;
+} __attribute__((packed));
+
+struct sys_desc_table {
+       u16 length;
+       u8  table[14];
+};
+
+struct efi_info {
+       u32 _pad1;
+       u32 efi_systab;
+       u32 efi_memdesc_size;
+       u32 efi_memdec_version;
+       u32 efi_memmap;
+       u32 fi_memmap_size;
+       u32 _pad2[2];
+};
+
+/* The so-called "zeropage" */
+struct boot_params {
+       struct screen_info screen_info;                 /* 0x000 */
+       struct apm_bios_info apm_bios_info;             /* 0x040 */
+       u8  _pad2[12];                                  /* 0x054 */
+       u32 speedstep_info[4];                          /* 0x060 */
+       u8  _pad3[16];                                  /* 0x070 */
+       u8  hd0_info[16];       /* obsolete! */         /* 0x080 */
+       u8  hd1_info[16];       /* obsolete! */         /* 0x090 */
+       struct sys_desc_table sys_desc_table;           /* 0x0a0 */
+       u8  _pad4[144];                                 /* 0x0b0 */
+       struct edid_info edid_info;                     /* 0x140 */
+       struct efi_info efi_info;                       /* 0x1c0 */
+       u32 alt_mem_k;                                  /* 0x1e0 */
+       u32 scratch;            /* Scratch field! */    /* 0x1e4 */
+       u8  e820_entries;                               /* 0x1e8 */
+       u8  eddbuf_entries;                             /* 0x1e9 */
+       u8  edd_mbr_sig_buf_entries;                    /* 0x1ea */
+       u8  _pad6[6];                                   /* 0x1eb */
+       struct setup_header hdr;    /* setup header */  /* 0x1f1 */
+       u8  _pad7[0x290-0x1f1-sizeof(struct setup_header)];
+       u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX];        /* 0x290 */
+       struct e820entry e820_map[E820MAX];             /* 0x2d0 */
+       u8  _pad8[48];                                  /* 0xcd0 */
+       struct edd_info eddbuf[EDDMAXNR];               /* 0xd00 */
+       u8  _pad9[276];                                 /* 0xeec */
+} __attribute__((packed));
+
+#endif /* _ASM_BOOTPARAM_H */
index f514e906643a2ae4df0f77baca83c586db24d210..c961c03cf1e2c8b451a0a6d67f0420ec3ee3674e 100644 (file)
@@ -12,7 +12,7 @@
 #endif
 #include <asm/required-features.h>
 
-#define NCAPINTS       7       /* N 32-bit words worth of info */
+#define NCAPINTS       8       /* N 32-bit words worth of info */
 
 /* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */
 #define X86_FEATURE_FPU                (0*32+ 0) /* Onboard FPU */
@@ -81,6 +81,7 @@
 #define X86_FEATURE_BTS                (3*32+13)  /* Branch Trace Store */
 #define X86_FEATURE_LAPIC_TIMER_BROKEN (3*32+ 14) /* lapic timer broken in C1 */
 #define X86_FEATURE_SYNC_RDTSC (3*32+15)  /* RDTSC synchronizes the CPU */
+#define X86_FEATURE_REP_GOOD   (3*32+16) /* rep microcode works well on this CPU */
 
 /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
 #define X86_FEATURE_XMM3       (4*32+ 0) /* Streaming SIMD Extensions-3 */
 #define X86_FEATURE_LAHF_LM    (6*32+ 0) /* LAHF/SAHF in long mode */
 #define X86_FEATURE_CMP_LEGACY (6*32+ 1) /* If yes HyperThreading not valid */
 
-#define cpu_has(c, bit)                                        \
-       ((__builtin_constant_p(bit) && (bit) < 32 &&    \
-               (1UL << (bit)) & REQUIRED_MASK1) ?      \
-               1 :                                     \
-       test_bit(bit, (c)->x86_capability))
+/*
+ * Auxiliary flags: Linux defined - For features scattered in various
+ * CPUID levels like 0x6, 0xA etc
+ */
+#define X86_FEATURE_IDA                (7*32+ 0) /* Intel Dynamic Acceleration */
+
+#define cpu_has(c, bit)                                                        \
+       (__builtin_constant_p(bit) &&                                   \
+        ( (((bit)>>5)==0 && (1UL<<((bit)&31) & REQUIRED_MASK0)) ||     \
+          (((bit)>>5)==1 && (1UL<<((bit)&31) & REQUIRED_MASK1)) ||     \
+          (((bit)>>5)==2 && (1UL<<((bit)&31) & REQUIRED_MASK2)) ||     \
+          (((bit)>>5)==3 && (1UL<<((bit)&31) & REQUIRED_MASK3)) ||     \
+          (((bit)>>5)==4 && (1UL<<((bit)&31) & REQUIRED_MASK4)) ||     \
+          (((bit)>>5)==5 && (1UL<<((bit)&31) & REQUIRED_MASK5)) ||     \
+          (((bit)>>5)==6 && (1UL<<((bit)&31) & REQUIRED_MASK6)) ||     \
+          (((bit)>>5)==7 && (1UL<<((bit)&31) & REQUIRED_MASK7)) )      \
+         ? 1 :                                                         \
+         test_bit(bit, (c)->x86_capability))
 #define boot_cpu_has(bit)      cpu_has(&boot_cpu_data, bit)
 
 #define cpu_has_fpu            boot_cpu_has(X86_FEATURE_FPU)
index 096a2a8eb1da6d8ef5df6da452a226a13f4f5798..c03290ccecb274889663681107cce207501d2cb6 100644 (file)
 
 #ifndef __ASSEMBLY__
 
+struct e820entry {
+       u64 addr;       /* start of memory segment */
+       u64 size;       /* size of memory segment */
+       u32 type;       /* type of memory segment */
+} __attribute__((packed));
+
 struct e820map {
-    int nr_map;
-    struct e820entry {
-       unsigned long long addr;        /* start of memory segment */
-       unsigned long long size;        /* size of memory segment */
-       unsigned long type;             /* type of memory segment */
-    } map[E820MAX];
+       u32 nr_map;
+       struct e820entry map[E820MAX];
 };
 
 extern struct e820map e820;
index 64b6d0baedbce7109c8691095e55b039186750c2..392d3fe5d45ecf280897f39d0af6542cbe021ec2 100644 (file)
@@ -56,48 +56,11 @@ struct pci_dev;
 #define pci_unmap_len(PTR, LEN_NAME)           (0)
 #define pci_unmap_len_set(PTR, LEN_NAME, VAL)  do { } while (0)
 
-/* This is always fine. */
-#define pci_dac_dma_supported(pci_dev, mask)   (1)
-
-static inline dma64_addr_t
-pci_dac_page_to_dma(struct pci_dev *pdev, struct page *page, unsigned long offset, int direction)
-{
-       return ((dma64_addr_t) page_to_phys(page) +
-               (dma64_addr_t) offset);
-}
-
-static inline struct page *
-pci_dac_dma_to_page(struct pci_dev *pdev, dma64_addr_t dma_addr)
-{
-       return pfn_to_page(dma_addr >> PAGE_SHIFT);
-}
-
-static inline unsigned long
-pci_dac_dma_to_offset(struct pci_dev *pdev, dma64_addr_t dma_addr)
-{
-       return (dma_addr & ~PAGE_MASK);
-}
-
-static inline void
-pci_dac_dma_sync_single_for_cpu(struct pci_dev *pdev, dma64_addr_t dma_addr, size_t len, int direction)
-{
-}
-
-static inline void
-pci_dac_dma_sync_single_for_device(struct pci_dev *pdev, dma64_addr_t dma_addr, size_t len, int direction)
-{
-       flush_write_buffers();
-}
-
 #define HAVE_PCI_MMAP
 extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
                               enum pci_mmap_state mmap_state, int write_combine);
 
 
-static inline void pcibios_add_platform_entries(struct pci_dev *dev)
-{
-}
-
 #ifdef CONFIG_PCI
 static inline void pci_dma_burst_advice(struct pci_dev *pdev,
                                        enum pci_dma_burst_strategy *strat,
index 338668bfb0a2a69ae0ebb3458b94ebddf1d9ae22..94e0c147c165333b853941f547460b4efe783371 100644 (file)
@@ -119,6 +119,7 @@ void __init cpu_detect(struct cpuinfo_x86 *c);
 extern void identify_boot_cpu(void);
 extern void identify_secondary_cpu(struct cpuinfo_x86 *);
 extern void print_cpu_info(struct cpuinfo_x86 *);
+extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c);
 extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
 extern unsigned short num_cache_leaves;
 
index 9db866c1e64c4b03bc0e7fc96509ef69e9344f0e..65848a007050911e3207b1d2e682ba4499c25ec9 100644 (file)
@@ -3,32 +3,53 @@
 
 /* Define minimum CPUID feature set for kernel These bits are checked
    really early to actually display a visible error message before the
-   kernel dies.  Only add word 0 bits here
+   kernel dies.  Make sure to assign features to the proper mask!
 
    Some requirements that are not in CPUID yet are also in the
-   CONFIG_X86_MINIMUM_CPU mode which is checked too.
+   CONFIG_X86_MINIMUM_CPU_FAMILY which is checked too.
 
    The real information is in arch/i386/Kconfig.cpu, this just converts
    the CONFIGs into a bitmask */
 
+#ifndef CONFIG_MATH_EMULATION
+# define NEED_FPU      (1<<(X86_FEATURE_FPU & 31))
+#else
+# define NEED_FPU      0
+#endif
+
 #ifdef CONFIG_X86_PAE
-#define NEED_PAE       (1<<X86_FEATURE_PAE)
+# define NEED_PAE      (1<<(X86_FEATURE_PAE & 31))
 #else
-#define NEED_PAE       0
+# define NEED_PAE      0
 #endif
 
 #ifdef CONFIG_X86_CMOV
-#define NEED_CMOV      (1<<X86_FEATURE_CMOV)
+# define NEED_CMOV     (1<<(X86_FEATURE_CMOV & 31))
 #else
-#define NEED_CMOV      0
+# define NEED_CMOV     0
 #endif
 
 #ifdef CONFIG_X86_CMPXCHG64
-#define NEED_CMPXCHG64  (1<<X86_FEATURE_CX8)
+# define NEED_CX8      (1<<(X86_FEATURE_CX8 & 31))
+#else
+# define NEED_CX8      0
+#endif
+
+#define REQUIRED_MASK0 (NEED_FPU|NEED_PAE|NEED_CMOV|NEED_CX8)
+
+#ifdef CONFIG_X86_USE_3DNOW
+# define NEED_3DNOW    (1<<(X86_FEATURE_3DNOW & 31))
 #else
-#define NEED_CMPXCHG64  0
+# define NEED_3DNOW    0
 #endif
 
-#define REQUIRED_MASK1 (NEED_PAE|NEED_CMOV|NEED_CMPXCHG64)
+#define REQUIRED_MASK1 (NEED_3DNOW)
+
+#define REQUIRED_MASK2 0
+#define REQUIRED_MASK3 0
+#define REQUIRED_MASK4 0
+#define REQUIRED_MASK5 0
+#define REQUIRED_MASK6 0
+#define REQUIRED_MASK7 0
 
 #endif
index 0e8077cbfdac7da388789be548d599c0839b8fbf..0d5bff9dc4a5e2133ef7d29bf7287e9381368ae3 100644 (file)
 #define NEW_CL_POINTER         0x228   /* Relative to real mode data */
 
 #ifndef __ASSEMBLY__
+
+#include <asm/bootparam.h>
+
 /*
  * This is set up by the setup-routine at boot-time
  */
-extern unsigned char boot_params[PARAM_SIZE];
+extern struct boot_params boot_params;
 
-#define PARAM  (boot_params)
+#define PARAM  ((char *)&boot_params)
 #define SCREEN_INFO (*(struct screen_info *) (PARAM+0))
 #define EXT_MEM_K (*(unsigned short *) (PARAM+2))
 #define ALT_MEM_K (*(unsigned long *) (PARAM+0x1e0))
@@ -39,8 +42,7 @@ extern unsigned char boot_params[PARAM_SIZE];
 #define E820_MAP    ((struct e820entry *) (PARAM+E820MAP))
 #define APM_BIOS_INFO (*(struct apm_bios_info *) (PARAM+0x40))
 #define IST_INFO   (*(struct ist_info *) (PARAM+0x60))
-#define DRIVE_INFO (*(struct drive_info_struct *) (PARAM+0x80))
-#define SYS_DESC_TABLE (*(struct sys_desc_table_struct*)(PARAM+0xa0))
+#define SYS_DESC_TABLE (*(struct sys_desc_table *)(PARAM+0xa0))
 #define EFI_SYSTAB ((efi_system_table_t *) *((unsigned long *)(PARAM+0x1c4)))
 #define EFI_MEMDESC_SIZE (*((unsigned long *) (PARAM+0x1c8)))
 #define EFI_MEMDESC_VERSION (*((unsigned long *) (PARAM+0x1cc)))
index 41098f459684c41f82cc26c6812f3b21deacb400..edd5d01028df93d8d88ad68dbdd1322261bee790 100644 (file)
@@ -48,6 +48,7 @@ enum {
        IA64_MCA_RENDEZ_CHECKIN_NOTDONE =       0x0,
        IA64_MCA_RENDEZ_CHECKIN_DONE    =       0x1,
        IA64_MCA_RENDEZ_CHECKIN_INIT    =       0x2,
+       IA64_MCA_RENDEZ_CHECKIN_CONCURRENT_MCA  =       0x3,
 };
 
 /* Information maintained by the MC infrastructure */
index 5a5d1c2ce39d1510e1d2a56dc1322929bab25029..0149097b736d70bd5e4d2f73801b5805ffe8a88a 100644 (file)
@@ -71,14 +71,6 @@ pcibios_penalize_isa_irq (int irq, int active)
 #define pci_unmap_len_set(PTR, LEN_NAME, VAL)          \
        (((PTR)->LEN_NAME) = (VAL))
 
-/* The ia64 platform always supports 64-bit addressing. */
-#define pci_dac_dma_supported(pci_dev, mask)           (1)
-#define pci_dac_page_to_dma(dev,pg,off,dir)            ((dma_addr_t) page_to_bus(pg) + (off))
-#define pci_dac_dma_to_page(dev,dma_addr)              (virt_to_page(bus_to_virt(dma_addr)))
-#define pci_dac_dma_to_offset(dev,dma_addr)            offset_in_page(dma_addr)
-#define pci_dac_dma_sync_single_for_cpu(dev,dma_addr,len,dir)  do { } while (0)
-#define pci_dac_dma_sync_single_for_device(dev,dma_addr,len,dir)       do { mb(); } while (0)
-
 #ifdef CONFIG_PCI
 static inline void pci_dma_burst_advice(struct pci_dev *pdev,
                                        enum pci_dma_burst_strategy *strat,
@@ -104,10 +96,12 @@ extern int pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma,
 #define HAVE_PCI_LEGACY
 extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
                                      struct vm_area_struct *vma);
-extern ssize_t pci_read_legacy_io(struct kobject *kobj, char *buf, loff_t off,
-                                 size_t count);
-extern ssize_t pci_write_legacy_io(struct kobject *kobj, char *buf, loff_t off,
-                                  size_t count);
+extern ssize_t pci_read_legacy_io(struct kobject *kobj,
+                                 struct bin_attribute *bin_attr,
+                                 char *buf, loff_t off, size_t count);
+extern ssize_t pci_write_legacy_io(struct kobject *kobj,
+                                  struct bin_attribute *bin_attr,
+                                  char *buf, loff_t off, size_t count);
 extern int pci_mmap_legacy_mem(struct kobject *kobj,
                               struct bin_attribute *attr,
                               struct vm_area_struct *vma);
@@ -143,10 +137,6 @@ static inline int pci_proc_domain(struct pci_bus *bus)
        return (pci_domain_nr(bus) != 0);
 }
 
-static inline void pcibios_add_platform_entries(struct pci_dev *dev)
-{
-}
-
 extern void pcibios_resource_to_bus(struct pci_dev *dev,
                struct pci_bus_region *region, struct resource *res);
 
index d3566a298fa40b773a96d3518e1fd1f71782eec0..676b31a08c61dc8fd366d1147b8572080fca4e65 100644 (file)
@@ -32,6 +32,7 @@
 #define  SN_SAL_NO_FAULT_ZONE_VIRTUAL             0x02000010
 #define  SN_SAL_NO_FAULT_ZONE_PHYSICAL            0x02000011
 #define  SN_SAL_PRINT_ERROR                       0x02000012
+#define  SN_SAL_REGISTER_PMI_HANDLER              0x02000014
 #define  SN_SAL_SET_ERROR_HANDLING_FEATURES       0x0200001a   // reentrant
 #define  SN_SAL_GET_FIT_COMPT                     0x0200001b   // reentrant
 #define  SN_SAL_GET_SAPIC_INFO                     0x0200001d
@@ -679,6 +680,25 @@ sn_register_nofault_code(u64 start_addr, u64 end_addr, u64 return_addr,
        return ret_stuff.status;
 }
 
+/*
+ * Register or unregister a function to handle a PMI received by a CPU.
+ * Before calling the registered handler, SAL sets r1 to the value that
+ * was passed in as the global_pointer.
+ *
+ * If the handler pointer is NULL, then the currently registered handler
+ * will be unregistered.
+ *
+ * Returns 0 on success, or a negative value if an error occurred.
+ */
+static inline int
+sn_register_pmi_handler(u64 handler, u64 global_pointer)
+{
+       struct ia64_sal_retval ret_stuff;
+       ia64_sal_oemcall(&ret_stuff, SN_SAL_REGISTER_PMI_HANDLER, handler,
+                        global_pointer, 0, 0, 0, 0, 0);
+       return ret_stuff.status;
+}
+
 /*
  * Change or query the coherence domain for this partition. Each cpu-based
  * nasid is represented by a bit in an array of 64-bit words:
index 4531a511bde58ca49e1f051264051d10fa690d8d..7fae3109ef47d1d368f8263cd85ac5543e30f2cd 100644 (file)
@@ -26,6 +26,17 @@ struct termios {
        cc_t c_cc[NCCS];                /* control characters */
 };
 
+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 */
+       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 */
index e402641dfbad20d8b2f5ac13711dcbf3fda54a2d..6be3b8a39841956307ba831e88edcaa3b121ba5a 100644 (file)
@@ -17,6 +17,17 @@ struct termios {
        cc_t c_cc[NCCS];                /* control characters */
 };
 
+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 */
+       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 */
index 9d2c07abe44f90d0657f27894c2fff844b9eeb57..678cb0b52314dac16a1cfb9fc9dbd44b5eeeed16 100644 (file)
@@ -54,8 +54,4 @@ static inline void pcibios_penalize_isa_irq(int irq, int active)
  */
 #define PCI_DMA_BUS_IS_PHYS    (1)
 
-static inline void pcibios_add_platform_entries(struct pci_dev *dev)
-{
-}
-
 #endif /* _ASM_M68K_PCI_H */
index a194092240fb9a895483c1265f2782f119b921d9..0e520f328f53c58e5fd16b7200eca540286f7a24 100644 (file)
@@ -17,6 +17,17 @@ struct termios {
        cc_t c_cc[NCCS];                /* control characters */
 };
 
+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 */
+       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 */
index e04c77e1184da3bb8dcce624e70db0fc4281fed8..a13f3cc87451be8f5fe1dd46bd8776afd9b5fd08 100644 (file)
@@ -24,16 +24,6 @@ static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
        return 1;
 }
 
-/*
- * Not supporting more than 32-bit PCI bus addresses now, but
- * must satisfy references to this function.  Change if needed.
- */
-#define pci_dac_dma_supported(pci_dev, mask) (0)
-
-static inline void pcibios_add_platform_entries(struct pci_dev *dev)
-{
-}
-
 #endif /* CONFIG_COMEMPCI */
 
 #endif /* M68KNOMMU_PCI_H */
index 964c5eddc21bf0544a263f748858bbf8ac11a07b..0b3ff9c48409ecc41805465d8383b3c5f604e577 100644 (file)
 #define PHYS_TO_XKPHYS(cm,a)           (_CONST64_(0x8000000000000000) | \
                                         ((cm)<<59) | (a))
 
-#if defined (CONFIG_CPU_R4300)                                         \
-    || defined (CONFIG_CPU_R4X00)                                      \
-    || defined (CONFIG_CPU_R5000)                                      \
-    || defined (CONFIG_CPU_RM7000)                                     \
-    || defined (CONFIG_CPU_RM9000)                                     \
-    || defined (CONFIG_CPU_NEVADA)                                     \
-    || defined (CONFIG_CPU_TX49XX)                                     \
-    || defined (CONFIG_CPU_MIPS64)
-#define TO_PHYS_MASK   _CONST64_(0x0000000fffffffff)   /* 2^^36 - 1 */
-#endif
-
-#if defined (CONFIG_CPU_R8000)
-/* We keep KUSIZE consistent with R4000 for now (2^^40) instead of (2^^48) */
-#define TO_PHYS_MASK   _CONST64_(0x000000ffffffffff)   /* 2^^40 - 1 */
-#endif
-
-#if defined (CONFIG_CPU_R10000)
-#define TO_PHYS_MASK   _CONST64_(0x000000ffffffffff)   /* 2^^40 - 1 */
-#endif
-
-#if defined(CONFIG_CPU_SB1) || defined(CONFIG_CPU_SB1A)
-#define TO_PHYS_MASK   _CONST64_(0x00000fffffffffff)   /* 2^^44 - 1 */
-#endif
+/*
+ * The ultimate limited of the 64-bit MIPS architecture:  2 bits for selecting
+ * the region, 3 bits for the CCA mode.  This leaves 59 bits of which the
+ * R8000 implements most with its 48-bit physical address space.
+ */
+#define TO_PHYS_MASK   _CONST64_(0x07ffffffffffffff)   /* 2^^59 - 1 */
 
 #ifndef CONFIG_CPU_R8000
 
index b0c329783ac59f6e3f9fa6f25f8c6936c54c62fa..087126a5faf9e84beb8f3cf3a9075e55ef95eb4d 100644 (file)
 #define MACH_GROUP_COSINE      10      /* CoSine Orion                 */
 #define  MACH_COSINE_ORION     0
 
-/*
- * Valid machtype for group GALILEO
- */
-#define MACH_GROUP_GALILEO     11      /* Galileo Eval Boards          */
-#define  MACH_EV64120A         0       /* EV64120A */
-
 /*
  * Valid machtype for group MOMENCO
  */
 #define MACH_GROUP_MOMENCO     12      /* Momentum Boards              */
 #define  MACH_MOMENCO_OCELOT   0
 #define  MACH_MOMENCO_OCELOT_G 1       /* no more supported (may 2007) */
-#define  MACH_MOMENCO_OCELOT_C 2
+#define  MACH_MOMENCO_OCELOT_C 2       /* no more supported (jun 2007) */
 #define  MACH_MOMENCO_JAGUAR_ATX 3     /* no more supported (may 2007) */
 #define  MACH_MOMENCO_OCELOT_3 4
 
 #define MACH_GROUP_HP_LJ       20      /* Hewlett Packard LaserJet     */
 #define  MACH_HP_LASERJET      1
 
-/*
- * Valid machtype for group LASAT
- */
-#define MACH_GROUP_LASAT       21
-#define  MACH_LASAT_100                0       /* Masquerade II/SP100/SP50/SP25 */
-#define  MACH_LASAT_200                1       /* Masquerade PRO/SP200 */
-
 /*
  * Valid machtype for group TITAN
  */
 #define MACH_GROUP_NEC_EMMA2RH 25      /* NEC EMMA2RH (was 23)         */
 #define  MACH_NEC_MARKEINS     0       /* NEC EMMA2RH Mark-eins        */
 
+/*
+ * Valid machtype for group LEMOTE
+ */
+#define MACH_GROUP_LEMOTE          27
+#define  MACH_LEMOTE_FULONG        0
+
+/*
+ * Valid machtype for group PMC-MSP
+ */
+#define MACH_GROUP_MSP         26      /* PMC-Sierra MSP boards/CPUs    */
+#define MACH_MSP4200_EVAL       0      /* PMC-Sierra MSP4200 Evaluation */
+#define MACH_MSP4200_GW         1      /* PMC-Sierra MSP4200 Gateway demo */
+#define MACH_MSP4200_FPGA       2      /* PMC-Sierra MSP4200 Emulation */
+#define MACH_MSP7120_EVAL       3      /* PMC-Sierra MSP7120 Evaluation */
+#define MACH_MSP7120_GW         4      /* PMC-Sierra MSP7120 Residential GW */
+#define MACH_MSP7120_FPGA       5      /* PMC-Sierra MSP7120 Emulation */
+#define MACH_MSP_OTHER        255      /* PMC-Sierra unknown board type */
+
+#define MACH_GROUP_WINDRIVER   28      /* Windriver boards */
+#define MACH_WRPPMC             1
+
 #define CL_SIZE                        COMMAND_LINE_SIZE
 
 const char *get_system_type(void);
index c4a1ec31ff6a65b36b1039a1b23d8c5648d0ea8a..df7f2deb3b56cee5361629380c7c619fc8e52187 100644 (file)
 #define Index_Load_Tag_D       0x05
 #define Index_Store_Tag_I      0x08
 #define Index_Store_Tag_D      0x09
+#if defined(CONFIG_CPU_LOONGSON2)
+#define Hit_Invalidate_I       0x00
+#else
 #define Hit_Invalidate_I       0x10
+#endif
 #define Hit_Invalidate_D       0x11
 #define Hit_Writeback_Inv_D    0x15
 
index 432653d7ae09326dafde8ef0b23504ca27b69300..67c3f8ec0303bba4e95fdf1eb00b9638d51d62ac 100644 (file)
@@ -132,7 +132,8 @@ typedef u32         compat_uptr_t;
 
 static inline void __user *compat_ptr(compat_uptr_t uptr)
 {
-       return (void __user *)(long)uptr;
+       /* cast to a __user pointer via "unsigned long" makes sparse happy */
+       return (void __user *)(unsigned long)(long)uptr;
 }
 
 static inline compat_uptr_t ptr_to_compat(void __user *uptr)
index 5e4bed123b487640f13541f3153e5d1e43960ab1..d95a83e3e1d72e4111005764e5e0825610b0f372 100644 (file)
 #define cpu_has_mipsmt         (cpu_data[0].ases & MIPS_ASE_MIPSMT)
 #endif
 
+#ifndef cpu_has_userlocal
+#define cpu_has_userlocal      (cpu_data[0].options & MIPS_CPU_ULRI)
+#endif
+
 #ifdef CONFIG_32BIT
 # ifndef cpu_has_nofpuex
 # define cpu_has_nofpuex       (cpu_data[0].options & MIPS_CPU_NOFPUEX)
index 2924069075e0a3b3a3342868d593de128ed880cc..3857358fb6de6a4c28123abf69543733c761be32 100644 (file)
@@ -89,6 +89,8 @@
 #define PRID_IMP_34K           0x9500
 #define PRID_IMP_24KE          0x9600
 #define PRID_IMP_74K           0x9700
+#define PRID_IMP_LOONGSON1      0x4200
+#define PRID_IMP_LOONGSON2      0x6300
 
 /*
  * These are the PRID's for when 23:16 == PRID_COMP_SIBYTE
  * Definitions for 7:0 on legacy processors
  */
 
+#define PRID_REV_MASK          0x00ff
 
 #define PRID_REV_TX4927                0x0022
 #define PRID_REV_TX4937                0x0030
 #define PRID_REV_VR4122                0x0070
 #define PRID_REV_VR4181A       0x0070  /* Same as VR4122 */
 #define PRID_REV_VR4130                0x0080
+#define PRID_REV_34K_V1_0_2    0x0022
 
 /*
  * Older processors used to encode processor version and revision in two
 #define CPU_SB1A               62
 #define CPU_74K                        63
 #define CPU_R14000             64
-#define CPU_LAST               64
+#define CPU_LOONGSON1           65
+#define CPU_LOONGSON2           66
+
+#define CPU_LAST               66
 
 /*
  * ISA Level encodings
 #define MIPS_CPU_PREFETCH      0x00080000 /* CPU has usable prefetch */
 #define MIPS_CPU_VINT          0x00100000 /* CPU supports MIPSR2 vectored interrupts */
 #define MIPS_CPU_VEIC          0x00200000 /* CPU supports MIPSR2 external interrupt controller mode */
+#define MIPS_CPU_ULRI          0x00400000 /* CPU has ULRI feature */
 
 /*
  * CPU ASE encodings
index 66189f5f6399ca4613ecdc5ba88722925a5dbfad..716371bd098076c7297e5ef90a2400d42387c620 100644 (file)
@@ -20,7 +20,7 @@
  */
 
 #define do_div64_32(res, high, low, base) ({ \
-       unsigned long __quot, __mod; \
+       unsigned long __quot32, __mod32; \
        unsigned long __cf, __tmp, __tmp2, __i; \
        \
        __asm__(".set   push\n\t" \
                "bnez   %4, 0b\n\t" \
                " srl   %5, %1, 0x1f\n\t" \
                ".set   pop" \
-               : "=&r" (__mod), "=&r" (__tmp), "=&r" (__quot), "=&r" (__cf), \
+               : "=&r" (__mod32), "=&r" (__tmp), \
+                 "=&r" (__quot32), "=&r" (__cf), \
                  "=&r" (__i), "=&r" (__tmp2) \
                : "Jr" (base), "0" (high), "1" (low)); \
        \
-       (res) = __quot; \
-       __mod; })
+       (res) = __quot32; \
+       __mod32; })
 
 #define do_div(n, base) ({ \
        unsigned long long __quot; \
diff --git a/include/asm-mips/gpio.h b/include/asm-mips/gpio.h
new file mode 100644 (file)
index 0000000..06e46fa
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef __ASM_MIPS_GPIO_H
+#define __ASM_MIPS_GPIO_H
+
+#include <gpio.h>
+
+#endif /* __ASM_MIPS_GPIO_H */
index 92ec2618560c984355e653d33d5dc935e5e1488c..7ba92890ea13eeeef95f55d9bb0e9b9429ed593b 100644 (file)
@@ -178,6 +178,11 @@ extern void __iounmap(const volatile void __iomem *addr);
 static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size,
        unsigned long flags)
 {
+       void __iomem *addr = plat_ioremap(offset, size, flags);
+
+       if (addr)
+               return addr;
+
 #define __IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL))
 
        if (cpu_has_64bit_addresses) {
@@ -207,7 +212,8 @@ static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size,
                 */
                if (__IS_LOW512(phys_addr) && __IS_LOW512(last_addr) &&
                    flags == _CACHE_UNCACHED)
-                       return (void __iomem *)CKSEG1ADDR(phys_addr);
+                       return (void __iomem *)
+                               (unsigned long)CKSEG1ADDR(phys_addr);
        }
 
        return __ioremap(offset, size, flags);
@@ -282,6 +288,9 @@ static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size,
 
 static inline void iounmap(const volatile void __iomem *addr)
 {
+       if (plat_iounmap(addr))
+               return;
+
 #define __IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == CKSEG1)
 
        if (cpu_has_64bit_addresses ||
index 3ca6a076124d745c163aaf918872507a7b4bccfd..97102ebc54b19d44137945dcac23833eceec6ada 100644 (file)
@@ -24,7 +24,7 @@ static inline int irq_canonicalize(int irq)
 #define irq_canonicalize(irq) (irq)    /* Sane hardware, sane code ... */
 #endif
 
-#ifdef CONFIG_MIPS_MT_SMTC
+#ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP
 /*
  * Clear interrupt mask handling "backstop" if irq_hwmask
  * entry so indicates. This implies that the ack() or end()
diff --git a/include/asm-mips/lasat/ds1603.h b/include/asm-mips/lasat/ds1603.h
deleted file mode 100644 (file)
index edcd754..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#include <asm/addrspace.h>
-
-/* Lasat 100   */
-#define DS1603_REG_100         (KSEG1ADDR(0x1c810000))
-#define DS1603_RST_100         (1 << 2)
-#define DS1603_CLK_100         (1 << 0)
-#define DS1603_DATA_SHIFT_100  1
-#define DS1603_DATA_100                (1 << DS1603_DATA_SHIFT_100)
-
-/* Lasat 200   */
-#define DS1603_REG_200         (KSEG1ADDR(0x11000000))
-#define DS1603_RST_200         (1 << 3)
-#define DS1603_CLK_200         (1 << 4)
-#define DS1603_DATA_200                (1 << 5)
-
-#define DS1603_DATA_REG_200            (DS1603_REG_200 + 0x10000)
-#define DS1603_DATA_READ_SHIFT_200     9
-#define DS1603_DATA_READ_200   (1 << DS1603_DATA_READ_SHIFT_200)
diff --git a/include/asm-mips/lasat/eeprom.h b/include/asm-mips/lasat/eeprom.h
deleted file mode 100644 (file)
index 7b53edd..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#include <asm/addrspace.h>
-
-/* lasat 100 */
-#define AT93C_REG_100               KSEG1ADDR(0x1c810000)
-#define AT93C_RDATA_REG_100         AT93C_REG_100
-#define AT93C_RDATA_SHIFT_100       4
-#define AT93C_WDATA_SHIFT_100       4
-#define AT93C_CS_M_100              ( 1 << 5 )
-#define AT93C_CLK_M_100             ( 1 << 3 )
-
-/* lasat 200 */
-#define AT93C_REG_200          KSEG1ADDR(0x11000000)
-#define AT93C_RDATA_REG_200    (AT93C_REG_200+0x10000)
-#define AT93C_RDATA_SHIFT_200  8
-#define AT93C_WDATA_SHIFT_200  2
-#define AT93C_CS_M_200         ( 1 << 0 )
-#define AT93C_CLK_M_200                ( 1 << 1 )
diff --git a/include/asm-mips/lasat/head.h b/include/asm-mips/lasat/head.h
deleted file mode 100644 (file)
index f5589f3..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Image header stuff
- */
-#ifndef _HEAD_H
-#define _HEAD_H
-
-#define LASAT_K_MAGIC0_VAL     0xfedeabba
-#define LASAT_K_MAGIC1_VAL     0x00bedead
-
-#ifndef _LANGUAGE_ASSEMBLY
-#include <linux/types.h>
-struct bootloader_header {
-       u32 magic[2];
-       u32 version;
-       u32 image_start;
-       u32 image_size;
-       u32 kernel_start;
-       u32 kernel_entry;
-};
-#endif
-
-#endif /* _HEAD_H */
diff --git a/include/asm-mips/lasat/lasat.h b/include/asm-mips/lasat/lasat.h
deleted file mode 100644 (file)
index 42077e3..0000000
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * lasat.h
- *
- * Thomas Horsten <thh@lasat.com>
- * Copyright (C) 2000 LASAT Networks A/S.
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You 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.
- *
- * Configuration for LASAT boards, loads the appropriate include files.
- */
-#ifndef _LASAT_H
-#define _LASAT_H
-
-#ifndef _LANGUAGE_ASSEMBLY
-
-extern struct lasat_misc {
-       volatile u32 *reset_reg;
-       volatile u32 *flash_wp_reg;
-       u32 flash_wp_bit;
-} *lasat_misc;
-
-enum lasat_mtdparts {
-       LASAT_MTD_BOOTLOADER,
-       LASAT_MTD_SERVICE,
-       LASAT_MTD_NORMAL,
-       LASAT_MTD_CONFIG,
-       LASAT_MTD_FS,
-       LASAT_MTD_LAST
-};
-
-/*
- * The format of the data record in the EEPROM.
- * See Documentation/LASAT/eeprom.txt for a detailed description
- * of the fields in this struct, and the LASAT Hardware Configuration
- * field specification for a detailed description of the config
- * field.
- */
-#include <linux/types.h>
-
-#define LASAT_EEPROM_VERSION 7
-struct lasat_eeprom_struct {
-       unsigned int  version;
-       unsigned int  cfg[3];
-       unsigned char hwaddr[6];
-       unsigned char print_partno[12];
-       unsigned char term0;
-       unsigned char print_serial[14];
-       unsigned char term1;
-       unsigned char prod_partno[12];
-       unsigned char term2;
-       unsigned char prod_serial[14];
-       unsigned char term3;
-       unsigned char passwd_hash[16];
-       unsigned char pwdnull;
-       unsigned char vendid;
-       unsigned char ts_ref;
-       unsigned char ts_signoff;
-       unsigned char reserved[11];
-       unsigned char debugaccess;
-       unsigned short prid;
-       unsigned int  serviceflag;
-       unsigned int  ipaddr;
-       unsigned int  netmask;
-       unsigned int  crc32;
-};
-
-struct lasat_eeprom_struct_pre7 {
-       unsigned int  version;
-       unsigned int  flags[3];
-       unsigned char hwaddr0[6];
-       unsigned char hwaddr1[6];
-       unsigned char print_partno[9];
-       unsigned char term0;
-       unsigned char print_serial[14];
-       unsigned char term1;
-       unsigned char prod_partno[9];
-       unsigned char term2;
-       unsigned char prod_serial[14];
-       unsigned char term3;
-       unsigned char passwd_hash[24];
-       unsigned char pwdnull;
-       unsigned char vendor;
-       unsigned char ts_ref;
-       unsigned char ts_signoff;
-       unsigned char reserved[6];
-       unsigned int  writecount;
-       unsigned int  ipaddr;
-       unsigned int  netmask;
-       unsigned int  crc32;
-};
-
-/* Configuration descriptor encoding - see the doc for details */
-
-#define LASAT_W0_DSCTYPE(v)            ( ( (v)         ) & 0xf )
-#define LASAT_W0_BMID(v)               ( ( (v) >> 0x04 ) & 0xf )
-#define LASAT_W0_CPUTYPE(v)            ( ( (v) >> 0x08 ) & 0xf )
-#define LASAT_W0_BUSSPEED(v)           ( ( (v) >> 0x0c ) & 0xf )
-#define LASAT_W0_CPUCLK(v)             ( ( (v) >> 0x10 ) & 0xf )
-#define LASAT_W0_SDRAMBANKSZ(v)                ( ( (v) >> 0x14 ) & 0xf )
-#define LASAT_W0_SDRAMBANKS(v)         ( ( (v) >> 0x18 ) & 0xf )
-#define LASAT_W0_L2CACHE(v)            ( ( (v) >> 0x1c ) & 0xf )
-
-#define LASAT_W1_EDHAC(v)              ( ( (v)         ) & 0xf )
-#define LASAT_W1_HIFN(v)               ( ( (v) >> 0x04 ) & 0x1 )
-#define LASAT_W1_ISDN(v)               ( ( (v) >> 0x05 ) & 0x1 )
-#define LASAT_W1_IDE(v)                        ( ( (v) >> 0x06 ) & 0x1 )
-#define LASAT_W1_HDLC(v)               ( ( (v) >> 0x07 ) & 0x1 )
-#define LASAT_W1_USVERSION(v)          ( ( (v) >> 0x08 ) & 0x1 )
-#define LASAT_W1_4MACS(v)              ( ( (v) >> 0x09 ) & 0x1 )
-#define LASAT_W1_EXTSERIAL(v)          ( ( (v) >> 0x0a ) & 0x1 )
-#define LASAT_W1_FLASHSIZE(v)          ( ( (v) >> 0x0c ) & 0xf )
-#define LASAT_W1_PCISLOTS(v)           ( ( (v) >> 0x10 ) & 0xf )
-#define LASAT_W1_PCI1OPT(v)            ( ( (v) >> 0x14 ) & 0xf )
-#define LASAT_W1_PCI2OPT(v)            ( ( (v) >> 0x18 ) & 0xf )
-#define LASAT_W1_PCI3OPT(v)            ( ( (v) >> 0x1c ) & 0xf )
-
-/* Routines specific to LASAT boards */
-
-#define LASAT_BMID_MASQUERADE2         0
-#define LASAT_BMID_MASQUERADEPRO       1
-#define LASAT_BMID_SAFEPIPE25                  2
-#define LASAT_BMID_SAFEPIPE50                  3
-#define LASAT_BMID_SAFEPIPE100         4
-#define LASAT_BMID_SAFEPIPE5000                5
-#define LASAT_BMID_SAFEPIPE7000                6
-#define LASAT_BMID_SAFEPIPE1000                7
-//#define LASAT_BMID_SAFEPIPE30                7
-//#define LASAT_BMID_SAFEPIPE5100      8
-//#define LASAT_BMID_SAFEPIPE7100      9
-#define LASAT_BMID_UNKNOWN                             0xf
-#define LASAT_MAX_BMID_NAMES                   9   // no larger than 15!
-
-#define LASAT_HAS_EDHAC                        ( 1 << 0 )
-#define LASAT_EDHAC_FAST               ( 1 << 1 )
-#define LASAT_HAS_EADI                 ( 1 << 2 )
-#define LASAT_HAS_HIFN                 ( 1 << 3 )
-#define LASAT_HAS_ISDN                 ( 1 << 4 )
-#define LASAT_HAS_LEASEDLINE_IF                ( 1 << 5 )
-#define LASAT_HAS_HDC                  ( 1 << 6 )
-
-#define LASAT_PRID_MASQUERADE2         0
-#define LASAT_PRID_MASQUERADEPRO       1
-#define LASAT_PRID_SAFEPIPE25                  2
-#define LASAT_PRID_SAFEPIPE50                  3
-#define LASAT_PRID_SAFEPIPE100         4
-#define LASAT_PRID_SAFEPIPE5000                5
-#define LASAT_PRID_SAFEPIPE7000                6
-#define LASAT_PRID_SAFEPIPE30                  7
-#define LASAT_PRID_SAFEPIPE5100                8
-#define LASAT_PRID_SAFEPIPE7100                9
-
-#define LASAT_PRID_SAFEPIPE1110                10
-#define LASAT_PRID_SAFEPIPE3020                11
-#define LASAT_PRID_SAFEPIPE3030                12
-#define LASAT_PRID_SAFEPIPE5020                13
-#define LASAT_PRID_SAFEPIPE5030                14
-#define LASAT_PRID_SAFEPIPE1120                15
-#define LASAT_PRID_SAFEPIPE1130                16
-#define LASAT_PRID_SAFEPIPE6010                17
-#define LASAT_PRID_SAFEPIPE6110                18
-#define LASAT_PRID_SAFEPIPE6210                19
-#define LASAT_PRID_SAFEPIPE1020                20
-#define LASAT_PRID_SAFEPIPE1040                21
-#define LASAT_PRID_SAFEPIPE1060                22
-
-struct lasat_info {
-       unsigned int  li_cpu_hz;
-       unsigned int  li_bus_hz;
-       unsigned int  li_bmid;
-       unsigned int  li_memsize;
-       unsigned int  li_flash_size;
-       unsigned int  li_prid;
-       unsigned char li_bmstr[16];
-       unsigned char li_namestr[32];
-       unsigned char li_typestr[16];
-       /* Info on the Flash layout */
-       unsigned int  li_flash_base;
-       unsigned long li_flashpart_base[LASAT_MTD_LAST];
-       unsigned long li_flashpart_size[LASAT_MTD_LAST];
-       struct lasat_eeprom_struct li_eeprom_info;
-       unsigned int  li_eeprom_upgrade_version;
-       unsigned int  li_debugaccess;
-};
-
-extern struct lasat_info lasat_board_info;
-
-static inline unsigned long lasat_flash_partition_start(int partno)
-{
-       if (partno < 0 || partno >= LASAT_MTD_LAST)
-               return 0;
-
-       return lasat_board_info.li_flashpart_base[partno];
-}
-
-static inline unsigned long lasat_flash_partition_size(int partno)
-{
-       if (partno < 0 || partno >= LASAT_MTD_LAST)
-               return 0;
-
-       return lasat_board_info.li_flashpart_size[partno];
-}
-
-/* Called from setup() to initialize the global board_info struct */
-extern int lasat_init_board_info(void);
-
-/* Write the modified EEPROM info struct */
-extern void lasat_write_eeprom_info(void);
-
-#define N_MACHTYPES            2
-/* for calibration of delays */
-
-/* the lasat_ndelay function is necessary because it is used at an
- * early stage of the boot process where ndelay is not calibrated.
- * It is used for the bit-banging rtc and eeprom drivers */
-
-#include <asm/delay.h>
-/* calculating with the slowest board with 100 MHz clock */
-#define LASAT_100_DIVIDER 20
-/* All 200's run at 250 MHz clock */
-#define LASAT_200_DIVIDER 8
-
-extern unsigned int lasat_ndelay_divider;
-
-static inline void lasat_ndelay(unsigned int ns)
-{
-            __delay(ns / lasat_ndelay_divider);
-}
-
-#endif /* !defined (_LANGUAGE_ASSEMBLY) */
-
-#define LASAT_SERVICEMODE_MAGIC_1     0xdeadbeef
-#define LASAT_SERVICEMODE_MAGIC_2     0xfedeabba
-
-/* Lasat 100 boards */
-#define LASAT_GT_BASE           (KSEG1ADDR(0x14000000))
-
-/* Lasat 200 boards */
-#define Vrc5074_PHYS_BASE       0x1fa00000
-#define Vrc5074_BASE            (KSEG1ADDR(Vrc5074_PHYS_BASE))
-#define PCI_WINDOW1             0x1a000000
-
-#endif /* _LASAT_H */
diff --git a/include/asm-mips/lasat/lasatint.h b/include/asm-mips/lasat/lasatint.h
deleted file mode 100644 (file)
index 065474f..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#define LASATINT_END 16
-
-/* lasat 100 */
-#define LASAT_INT_STATUS_REG_100       (KSEG1ADDR(0x1c880000))
-#define LASAT_INT_MASK_REG_100         (KSEG1ADDR(0x1c890000))
-#define LASATINT_MASK_SHIFT_100                0
-
-/* lasat 200 */
-#define LASAT_INT_STATUS_REG_200       (KSEG1ADDR(0x1104003c))
-#define LASAT_INT_MASK_REG_200         (KSEG1ADDR(0x1104003c))
-#define LASATINT_MASK_SHIFT_200                16
-
diff --git a/include/asm-mips/lasat/picvue.h b/include/asm-mips/lasat/picvue.h
deleted file mode 100644 (file)
index 42a492e..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/* Lasat 100 */
-#define PVC_REG_100            KSEG1ADDR(0x1c820000)
-#define PVC_DATA_SHIFT_100     0
-#define PVC_DATA_M_100         0xFF
-#define PVC_E_100              (1 << 8)
-#define PVC_RW_100             (1 << 9)
-#define PVC_RS_100             (1 << 10)
-
-/* Lasat 200 */
-#define PVC_REG_200            KSEG1ADDR(0x11000000)
-#define PVC_DATA_SHIFT_200     24
-#define PVC_DATA_M_200         (0xFF << PVC_DATA_SHIFT_200)
-#define PVC_E_200              (1 << 16)
-#define PVC_RW_200             (1 << 17)
-#define PVC_RS_200             (1 << 18)
diff --git a/include/asm-mips/lasat/serial.h b/include/asm-mips/lasat/serial.h
deleted file mode 100644 (file)
index 9e88c76..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#include <asm/lasat/lasat.h>
-
-/* Lasat 100 boards serial configuration */
-#define LASAT_BASE_BAUD_100            ( 7372800 / 16 )
-#define LASAT_UART_REGS_BASE_100       0x1c8b0000
-#define LASAT_UART_REGS_SHIFT_100      2
-#define LASATINT_UART_100              8
-
-/* * LASAT 200 boards serial configuration */
-#define LASAT_BASE_BAUD_200            (100000000 / 16 / 12)
-#define LASAT_UART_REGS_BASE_200       (Vrc5074_PHYS_BASE + 0x0300)
-#define LASAT_UART_REGS_SHIFT_200      3
-#define LASATINT_UART_200              13
diff --git a/include/asm-mips/mach-au1x00/au1xxx_gpio.h b/include/asm-mips/mach-au1x00/au1xxx_gpio.h
deleted file mode 100644 (file)
index 27911e0..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef __AU1XXX_GPIO_H
-#define __AU1XXX_GPIO_H
-
-void au1xxx_gpio1_set_inputs(void);
-void au1xxx_gpio_tristate(int signal);
-void au1xxx_gpio_write(int signal, int value);
-int  au1xxx_gpio_read(int signal);
-
-typedef volatile struct
-{
-       u32 dir;
-       u32 reserved;
-       u32 output;
-       u32 pinstate;
-       u32 inten;
-       u32 enable;
-
-} AU1X00_GPIO2;
-
-#endif //__AU1XXX_GPIO_H
index 8fcae21adbd5a0af54f89f6b0e7e7e8fa1cdeb60..4663e8b415c9286b4730f0b3e087f47dd80fb02f 100644 (file)
@@ -88,26 +88,26 @@ static const struct drive_list_entry dma_white_list [] = {
 /*
  * Hitachi
  */
-        { "HITACHI_DK14FA-20"    ,       "ALL"           },
-        { "HTS726060M9AT00"      ,       "ALL"           },
+        { "HITACHI_DK14FA-20"    ,       NULL            },
+        { "HTS726060M9AT00"      ,       NULL            },
 /*
  * Maxtor
  */
-        { "Maxtor 6E040L0"      ,       "ALL"           },
-        { "Maxtor 6Y080P0"      ,       "ALL"           },
-        { "Maxtor 6Y160P0"      ,       "ALL"           },
+        { "Maxtor 6E040L0"      ,       NULL            },
+        { "Maxtor 6Y080P0"      ,       NULL            },
+        { "Maxtor 6Y160P0"      ,       NULL            },
 /*
  * Seagate
  */
-        { "ST3120026A"          ,       "ALL"           },
-        { "ST320014A"           ,       "ALL"           },
-        { "ST94011A"            ,       "ALL"           },
-        { "ST340016A"           ,       "ALL"           },
+        { "ST3120026A"          ,       NULL            },
+        { "ST320014A"           ,       NULL            },
+        { "ST94011A"            ,       NULL            },
+        { "ST340016A"           ,       NULL            },
 /*
  * Western Digital
  */
-        { "WDC WD400UE-00HCT0"  ,       "ALL"           },
-        { "WDC WD400JB-00JJC0"  ,       "ALL"           },
+        { "WDC WD400UE-00HCT0"  ,       NULL            },
+        { "WDC WD400JB-00JJC0"  ,       NULL            },
         { NULL                  ,       NULL            }
 };
 
@@ -116,9 +116,9 @@ static const struct drive_list_entry dma_black_list [] = {
 /*
  * Western Digital
  */
-        { "WDC WD100EB-00CGH0"  ,       "ALL"           },
-        { "WDC WD200BB-00AUA1"  ,       "ALL"           },
-        { "WDC AC24300L"        ,       "ALL"           },
+        { "WDC WD100EB-00CGH0"  ,       NULL            },
+        { "WDC WD200BB-00AUA1"  ,       NULL            },
+        { "WDC AC24300L"        ,       NULL            },
         { NULL                  ,       NULL            }
 };
 #endif
diff --git a/include/asm-mips/mach-au1x00/gpio.h b/include/asm-mips/mach-au1x00/gpio.h
new file mode 100644 (file)
index 0000000..2dc61e0
--- /dev/null
@@ -0,0 +1,69 @@
+#ifndef _AU1XXX_GPIO_H_
+#define _AU1XXX_GPIO_H_
+
+#include <linux/types.h>
+
+#define AU1XXX_GPIO_BASE       200
+
+struct au1x00_gpio2 {
+       u32     dir;
+       u32     reserved;
+       u32     output;
+       u32     pinstate;
+       u32     inten;
+       u32     enable;
+};
+
+extern int au1xxx_gpio_get_value(unsigned gpio);
+extern void au1xxx_gpio_set_value(unsigned gpio, int value);
+extern int au1xxx_gpio_direction_input(unsigned gpio);
+extern int au1xxx_gpio_direction_output(unsigned gpio, int value);
+
+
+/* Wrappers for the arch-neutral GPIO API */
+
+static inline int gpio_request(unsigned gpio, const char *label)
+{
+       /* Not yet implemented */
+       return 0;
+}
+
+static inline void gpio_free(unsigned gpio)
+{
+       /* Not yet implemented */
+}
+
+static inline int gpio_direction_input(unsigned gpio)
+{
+       return au1xxx_gpio_direction_input(gpio);
+}
+
+static inline int gpio_direction_output(unsigned gpio, int value)
+{
+       return au1xxx_gpio_direction_output(gpio, value);
+}
+
+static inline int gpio_get_value(unsigned gpio)
+{
+       return au1xxx_gpio_get_value(gpio);
+}
+
+static inline void gpio_set_value(unsigned gpio, int value)
+{
+       au1xxx_gpio_set_value(gpio, value);
+}
+
+static inline int gpio_to_irq(unsigned gpio)
+{
+       return gpio;
+}
+
+static inline int irq_to_gpio(unsigned irq)
+{
+       return irq;
+}
+
+/* For cansleep */
+#include <asm-generic/gpio.h>
+
+#endif /* _AU1XXX_GPIO_H_ */
index 098fca4289bb3fb80f0112604940a49ba26bad25..364cea2dc71fbaec28a061f41fca299109c49796 100644 (file)
@@ -28,4 +28,15 @@ static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
        return __fixup_bigphys_addr(phys_addr, size);
 }
 
+static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size,
+       unsigned long flags)
+{
+       return NULL;
+}
+
+static inline int plat_iounmap(const volatile void __iomem *addr)
+{
+       return 0;
+}
+
 #endif /* __ASM_MACH_AU1X00_IOREMAP_H */
index 684a501c04cfcf9f900e0bd3c70640f65d9d7505..9c9d2b998ca4fd774b095106024001832130d7e7 100644 (file)
@@ -30,7 +30,6 @@
 #define COBALT_CPU_IRQ         MIPS_CPU_IRQ_BASE
 
 #define COBALT_GALILEO_IRQ     (COBALT_CPU_IRQ + 2)
-#define COBALT_SCC_IRQ          (COBALT_CPU_IRQ + 3)   /* pre-production has 85C30 */
 #define COBALT_RAQ_SCSI_IRQ    (COBALT_CPU_IRQ + 3)
 #define COBALT_ETH0_IRQ                (COBALT_CPU_IRQ + 3)
 #define COBALT_QUBE1_ETH0_IRQ  (COBALT_CPU_IRQ + 4)
 
 extern int cobalt_board_id;
 
-#define PCI_CFG_SET(devfn,where)                                       \
-       GT_WRITE(GT_PCI0_CFGADDR_OFS, (0x80000000 | (PCI_SLOT (devfn) << 11) |          \
-               (PCI_FUNC (devfn) << 8) | (where)))
-
 #define COBALT_LED_PORT                (*(volatile unsigned char *) CKSEG1ADDR(0x1c000000))
 # define COBALT_LED_BAR_LEFT   (1 << 0)        /* Qube */
 # define COBALT_LED_BAR_RIGHT  (1 << 1)        /* Qube */
diff --git a/include/asm-mips/mach-ev64120/mach-gt64120.h b/include/asm-mips/mach-ev64120/mach-gt64120.h
deleted file mode 100644 (file)
index 7e272ce..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- *  This is a direct copy of the ev96100.h file, with a global
- * search and replace.  The numbers are the same.
- *
- *  The reason I'm duplicating this is so that the 64120/96100
- * defines won't be confusing in the source code.
- */
-#ifndef __ASM_GALILEO_BOARDS_MIPS_EV64120_H
-#define __ASM_GALILEO_BOARDS_MIPS_EV64120_H
-
-/*
- *   GT64120 config space base address
- */
-extern unsigned long gt64120_base;
-
-#define GT64120_BASE   (gt64120_base)
-
-/*
- *   PCI Bus allocation
- */
-#define GT_PCI_MEM_BASE        0x12000000UL
-#define GT_PCI_MEM_SIZE        0x02000000UL
-#define GT_PCI_IO_BASE 0x10000000UL
-#define GT_PCI_IO_SIZE 0x02000000UL
-#define GT_ISA_IO_BASE PCI_IO_BASE
-
-/*
- *   Duart I/O ports.
- */
-#define EV64120_COM1_BASE_ADDR (0x1d000000 + 0x20)
-#define EV64120_COM2_BASE_ADDR (0x1d000000 + 0x00)
-
-
-/*
- *   EV64120 interrupt controller register base.
- */
-#define EV64120_ICTRL_REGS_BASE        (KSEG1ADDR(0x1f000000))
-
-/*
- *   EV64120 UART register base.
- */
-#define EV64120_UART0_REGS_BASE        (KSEG1ADDR(EV64120_COM1_BASE_ADDR))
-#define EV64120_UART1_REGS_BASE        (KSEG1ADDR(EV64120_COM2_BASE_ADDR))
-#define EV64120_BASE_BAUD ( 3686400 / 16 )
-#define EV64120_UART_IRQ       6
-
-/*
- * PCI interrupts will come in on either the INTA or INTD interrups lines,
- * which are mapped to the #2 and #5 interrupt pins of the MIPS.  On our
- * boards, they all either come in on IntD or they all come in on IntA, they
- * aren't mixed. There can be numerous PCI interrupts, so we keep a list of the
- * "requested" interrupt numbers and go through the list whenever we get an
- * IntA/D.
- *
- * Interrupts < 8 are directly wired to the processor; PCI INTA is 8 and
- * INTD is 11.
- */
-#define GT_TIMER       4
-#define GT_INTA                2
-#define GT_INTD                5
-
-#endif /* __ASM_GALILEO_BOARDS_MIPS_EV64120_H */
diff --git a/include/asm-mips/mach-generic/gpio.h b/include/asm-mips/mach-generic/gpio.h
new file mode 100644 (file)
index 0000000..6eaf5ef
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef __ASM_MACH_GENERIC_GPIO_H
+#define __ASM_MACH_GENERIC_GPIO_H
+
+int gpio_request(unsigned gpio, const char *label);
+void gpio_free(unsigned gpio);
+int gpio_direction_input(unsigned gpio);
+int gpio_direction_output(unsigned gpio, int value);
+int gpio_get_value(unsigned gpio);
+void gpio_set_value(unsigned gpio, int value);
+int gpio_to_irq(unsigned gpio);
+int irq_to_gpio(unsigned irq);
+
+#include <asm-generic/gpio.h>          /* cansleep wrappers */
+
+#endif /* __ASM_MACH_GENERIC_GPIO_H */
index 9b64ff6e485d8bf3198f83033e518705e311726d..b379938d47f0f4b7b580cb1c21d603112ca4c216 100644 (file)
@@ -20,4 +20,15 @@ static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
        return phys_addr;
 }
 
+static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size,
+       unsigned long flags)
+{
+       return NULL;
+}
+
+static inline int plat_iounmap(const volatile void __iomem *addr)
+{
+       return 0;
+}
+
 #endif /* __ASM_MACH_GENERIC_IOREMAP_H */
index 0ae9997bc9a8ba32200b1697947a1a3a6c887dcc..c9fa4b14968d483ff6dd224c3a4daf23dc3b1143 100644 (file)
 #ifndef _ASM_MACH_GENERIC_SPACES_H
 #define _ASM_MACH_GENERIC_SPACES_H
 
+#include <linux/const.h>
+
+/*
+ * This gives the physical RAM offset.
+ */
+#ifndef PHYS_OFFSET
+#define PHYS_OFFSET            _AC(0, UL)
+#endif
 
 #ifdef CONFIG_32BIT
 
-#define CAC_BASE               0x80000000
-#define IO_BASE                        0xa0000000
-#define UNCAC_BASE             0xa0000000
-#define MAP_BASE               0xc0000000
+#define CAC_BASE               _AC(0x80000000, UL)
+#define IO_BASE                        _AC(0xa0000000, UL)
+#define UNCAC_BASE             _AC(0xa0000000, UL)
 
-/*
- * This handles the memory map.
- * We handle pages at KSEG0 for kernels with 32 bit address space.
- */
-#define PAGE_OFFSET            0x80000000UL
+#ifndef MAP_BASE
+#define MAP_BASE               _AC(0xc0000000, UL)
+#endif
 
 /*
  * Memory above this physical address will be considered highmem.
  */
 #ifndef HIGHMEM_START
-#define HIGHMEM_START          0x20000000UL
+#define HIGHMEM_START          _AC(0x20000000, UL)
 #endif
 
 #endif /* CONFIG_32BIT */
 
 #ifdef CONFIG_64BIT
 
-/*
- * This handles the memory map.
- */
+#ifndef CAC_BASE
 #ifdef CONFIG_DMA_NONCOHERENT
-#define PAGE_OFFSET    0x9800000000000000UL
+#define CAC_BASE               _AC(0x9800000000000000, UL)
 #else
-#define PAGE_OFFSET    0xa800000000000000UL
+#define CAC_BASE               _AC(0xa800000000000000, UL)
+#endif
+#endif
+
+#ifndef IO_BASE
+#define IO_BASE                        _AC(0x9000000000000000, UL)
+#endif
+
+#ifndef UNCAC_BASE
+#define UNCAC_BASE             _AC(0x9000000000000000, UL)
+#endif
+
+#ifndef MAP_BASE
+#define MAP_BASE               _AC(0xc000000000000000, UL)
 #endif
 
 /*
  * in the distant future.  Nobody will care for a few years :-)
  */
 #ifndef HIGHMEM_START
-#define HIGHMEM_START          (1UL << 59UL)
+#define HIGHMEM_START          (_AC(1, UL) << _AC(59, UL))
 #endif
 
-#ifdef CONFIG_DMA_NONCOHERENT
-#define CAC_BASE               0x9800000000000000UL
-#else
-#define CAC_BASE               0xa800000000000000UL
-#endif
-#define IO_BASE                        0x9000000000000000UL
-#define UNCAC_BASE             0x9000000000000000UL
-#define MAP_BASE               0xc000000000000000UL
-
 #define TO_PHYS(x)             (             ((x) & TO_PHYS_MASK))
 #define TO_CAC(x)              (CAC_BASE   | ((x) & TO_PHYS_MASK))
 #define TO_UNCAC(x)            (UNCAC_BASE | ((x) & TO_PHYS_MASK))
 
 #endif /* CONFIG_64BIT */
 
+/*
+ * This handles the memory map.
+ */
+#ifndef PAGE_OFFSET
+#define PAGE_OFFSET            (CAC_BASE + PHYS_OFFSET)
+#endif
+
 #endif /* __ASM_MACH_GENERIC_SPACES_H */
index ab20c026fd1949968595a3927fceff6dbd1ce070..7f9fa6f660598d8074d0bb36d710f5a08c5d74e3 100644 (file)
 #define _ASM_MACH_IP22_SPACES_H
 
 
-#ifdef CONFIG_32BIT
-
-#define CAC_BASE               0x80000000
-#define IO_BASE                        0xa0000000
-#define UNCAC_BASE             0xa0000000
-#define MAP_BASE               0xc0000000
-
-/*
- * This handles the memory map.
- * We handle pages at KSEG0 for kernels with 32 bit address space.
- */
-#define PAGE_OFFSET            0x80000000UL
-
-/*
- * Memory above this physical address will be considered highmem.
- */
-#ifndef HIGHMEM_START
-#define HIGHMEM_START          0x20000000UL
-#endif
-
-#endif /* CONFIG_32BIT */
-
 #ifdef CONFIG_64BIT
-#define PAGE_OFFSET            0xffffffff80000000UL
 
-#ifndef HIGHMEM_START
-#define HIGHMEM_START          (1UL << 59UL)
-#endif
+#define PAGE_OFFSET            0xffffffff80000000UL
 
 #define CAC_BASE               0xffffffff80000000
 #define IO_BASE                        0xffffffffa0000000
 #define UNCAC_BASE             0xffffffffa0000000
 #define MAP_BASE               0xc000000000000000
 
-#define TO_PHYS(x)             (             ((x) & TO_PHYS_MASK))
-#define TO_CAC(x)              (CAC_BASE   | ((x) & TO_PHYS_MASK))
-#define TO_UNCAC(x)            (UNCAC_BASE | ((x) & TO_PHYS_MASK))
-
 #endif /* CONFIG_64BIT */
 
+#include <asm/mach-generic/spaces.h>
+
 #endif /* __ASM_MACH_IP22_SPACES_H */
index 45e61785ef420cd7e19c92a2ad8bcd1935a68621..b18802a0b17e94dca9a85cc6a8a3c761dfb9f60e 100644 (file)
  * IP27 uses the R10000's uncached attribute feature.  Attribute 3 selects
  * uncached memory addressing.
  */
-#define CAC_BASE               0xa800000000000000
 
 #define HSPEC_BASE             0x9000000000000000
 #define IO_BASE                        0x9200000000000000
 #define MSPEC_BASE             0x9400000000000000
 #define UNCAC_BASE             0x9600000000000000
-#define MAP_BASE               0xc000000000000000
 
-#define TO_PHYS(x)             (             ((x) & TO_PHYS_MASK))
-#define TO_CAC(x)              (CAC_BASE   | ((x) & TO_PHYS_MASK))
-#define TO_UNCAC(x)            (UNCAC_BASE | ((x) & TO_PHYS_MASK))
 #define TO_MSPEC(x)            (MSPEC_BASE | ((x) & TO_PHYS_MASK))
 #define TO_HSPEC(x)            (HSPEC_BASE | ((x) & TO_PHYS_MASK))
 
-#define PAGE_OFFSET            CAC_BASE
-
 #define HIGHMEM_START          (~0UL)
 
+#include <asm/mach-generic/spaces.h>
+
 #endif /* _ASM_MACH_IP27_SPACES_H */
diff --git a/include/asm-mips/mach-ip32/spaces.h b/include/asm-mips/mach-ip32/spaces.h
deleted file mode 100644 (file)
index 44abe5c..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1994 - 1999, 2000, 03, 04, 05 Ralf Baechle (ralf@linux-mips.org)
- * Copyright (C) 2000, 2002  Maciej W. Rozycki
- * Copyright (C) 1990, 1999, 2000 Silicon Graphics, Inc.
- */
-#ifndef _ASM_MACH_IP32_SPACES_H
-#define _ASM_MACH_IP32_SPACES_H
-
-/*
- * Memory above this physical address will be considered highmem.
- * Fixme: 59 bits is a fictive number and makes assumptions about processors
- * in the distant future.  Nobody will care for a few years :-)
- */
-#ifndef HIGHMEM_START
-#define HIGHMEM_START          (1UL << 59UL)
-#endif
-
-#define CAC_BASE               0x9800000000000000UL
-#define IO_BASE                        0x9000000000000000UL
-#define UNCAC_BASE             0x9000000000000000UL
-#define MAP_BASE               0xc000000000000000UL
-
-#define TO_PHYS(x)             (             ((x) & TO_PHYS_MASK))
-#define TO_CAC(x)              (CAC_BASE   | ((x) & TO_PHYS_MASK))
-#define TO_UNCAC(x)            (UNCAC_BASE | ((x) & TO_PHYS_MASK))
-
-/*
- * This handles the memory map.
- */
-#define PAGE_OFFSET            CAC_BASE
-
-#endif /* __ASM_MACH_IP32_SPACES_H */
diff --git a/include/asm-mips/mach-jmr3927/ioremap.h b/include/asm-mips/mach-jmr3927/ioremap.h
new file mode 100644 (file)
index 0000000..aa131ad
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ *     include/asm-mips/mach-jmr3927/ioremap.h
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     as published by the Free Software Foundation; either version
+ *     2 of the License, or (at your option) any later version.
+ */
+#ifndef __ASM_MACH_JMR3927_IOREMAP_H
+#define __ASM_MACH_JMR3927_IOREMAP_H
+
+#include <linux/types.h>
+
+/*
+ * Allow physical addresses to be fixed up to help peripherals located
+ * outside the low 32-bit range -- generic pass-through version.
+ */
+static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
+{
+       return phys_addr;
+}
+
+static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size,
+       unsigned long flags)
+{
+#define TXX9_DIRECTMAP_BASE    0xff000000ul
+       if (offset >= TXX9_DIRECTMAP_BASE &&
+           offset < TXX9_DIRECTMAP_BASE + 0xf0000)
+               return (void __iomem *)offset;
+       return NULL;
+}
+
+static inline int plat_iounmap(const volatile void __iomem *addr)
+{
+       return (unsigned long)addr >= TXX9_DIRECTMAP_BASE;
+}
+
+#endif /* __ASM_MACH_JMR3927_IOREMAP_H */
diff --git a/include/asm-mips/mach-lasat/mach-gt64120.h b/include/asm-mips/mach-lasat/mach-gt64120.h
deleted file mode 100644 (file)
index 1a9ad45..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- *  This is a direct copy of the ev96100.h file, with a global
- * search and replace.  The numbers are the same.
- *
- *  The reason I'm duplicating this is so that the 64120/96100
- * defines won't be confusing in the source code.
- */
-#ifndef _ASM_GT64120_LASAT_GT64120_DEP_H
-#define _ASM_GT64120_LASAT_GT64120_DEP_H
-
-/*
- *   GT64120 config space base address on Lasat 100
- */
-#define GT64120_BASE   (KSEG1ADDR(0x14000000))
-
-/*
- *   PCI Bus allocation
- *
- *   (Guessing ...)
- */
-#define GT_PCI_MEM_BASE        0x12000000UL
-#define GT_PCI_MEM_SIZE        0x02000000UL
-#define GT_PCI_IO_BASE 0x10000000UL
-#define GT_PCI_IO_SIZE 0x02000000UL
-#define GT_ISA_IO_BASE PCI_IO_BASE
-
-#endif /* _ASM_GT64120_LASAT_GT64120_DEP_H */
diff --git a/include/asm-mips/mach-lemote/dma-coherence.h b/include/asm-mips/mach-lemote/dma-coherence.h
new file mode 100644 (file)
index 0000000..7e91477
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006, 07  Ralf Baechle <ralf@linux-mips.org>
+ * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ *
+ */
+#ifndef __ASM_MACH_LEMOTE_DMA_COHERENCE_H
+#define __ASM_MACH_LEMOTE_DMA_COHERENCE_H
+
+struct device;
+
+static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
+                                         size_t size)
+{
+       return virt_to_phys(addr) | 0x80000000;
+}
+
+static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
+                                              struct page *page)
+{
+       return page_to_phys(page) | 0x80000000;
+}
+
+static inline unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr)
+{
+       return dma_addr & 0x7fffffff;
+}
+
+static inline void plat_unmap_dma_mem(dma_addr_t dma_addr)
+{
+}
+
+static inline int plat_device_is_coherent(struct device *dev)
+{
+       return 0;
+}
+
+#endif /* __ASM_MACH_LEMOTE_DMA_COHERENCE_H */
diff --git a/include/asm-mips/mach-lemote/mc146818rtc.h b/include/asm-mips/mach-lemote/mc146818rtc.h
new file mode 100644 (file)
index 0000000..ed5147e
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1998, 2001, 03, 07 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ * RTC routines for PC style attached Dallas chip.
+ */
+#ifndef __ASM_MACH_LEMOTE_MC146818RTC_H
+#define __ASM_MACH_LEMOTE_MC146818RTC_H
+
+#include <linux/io.h>
+
+#define RTC_PORT(x)    (0x70 + (x))
+#define RTC_IRQ                8
+
+static inline unsigned char CMOS_READ(unsigned long addr)
+{
+       outb_p(addr, RTC_PORT(0));
+       return inb_p(RTC_PORT(1));
+}
+
+static inline void CMOS_WRITE(unsigned char data, unsigned long addr)
+{
+       outb_p(addr, RTC_PORT(0));
+       outb_p(data, RTC_PORT(1));
+}
+
+#define RTC_ALWAYS_BCD 0
+
+#ifndef mc146818_decode_year
+#define mc146818_decode_year(year) ((year) < 70 ? (year) + 2000 : (year) + 1970)
+#endif
+
+#endif /* __ASM_MACH_LEMOTE_MC146818RTC_H */
diff --git a/include/asm-mips/mach-mips/kernel-entry-init.h b/include/asm-mips/mach-mips/kernel-entry-init.h
new file mode 100644 (file)
index 0000000..0b793e7
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Chris Dearman (chris@mips.com)
+ * Copyright (C) 2007 Mips Technologies, Inc.
+ */
+#ifndef __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H
+#define __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H
+
+       .macro  kernel_entry_setup
+#ifdef CONFIG_MIPS_MT_SMTC
+       mfc0    t0, CP0_CONFIG
+       bgez    t0, 9f
+       mfc0    t0, CP0_CONFIG, 1
+       bgez    t0, 9f
+       mfc0    t0, CP0_CONFIG, 2
+       bgez    t0, 9f
+       mfc0    t0, CP0_CONFIG, 3
+       and     t0, 1<<2
+       bnez    t0, 0f
+9:
+       /* Assume we came from YAMON... */
+       PTR_LA  v0, 0x9fc00534  /* YAMON print */
+       lw      v0, (v0)
+       move    a0, zero
+       PTR_LA  a1, nonmt_processor
+       jal     v0
+
+       PTR_LA  v0, 0x9fc00520  /* YAMON exit */
+       lw      v0, (v0)
+       li      a0, 1
+       jal     v0
+
+1:     b       1b
+
+       __INITDATA
+nonmt_processor:
+       .asciz  "SMTC kernel requires the MT ASE to run\n"
+       __FINIT
+0:
+#endif
+       .endm
+
+/*
+ * Do SMP slave processor setup necessary before we can safely execute C code.
+ */
+       .macro  smp_slave_setup
+       .endm
+
+#endif /* __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H */
diff --git a/include/asm-mips/mach-ocelot3/cpu-feature-overrides.h b/include/asm-mips/mach-ocelot3/cpu-feature-overrides.h
deleted file mode 100644 (file)
index 57a12de..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2004 MontaVista Software Inc.
- * Author: Manish Lachwani, mlachwani@mvista.com
- * Copyright (C) 2004 Ralf Baechle
- */
-#ifndef __ASM_MACH_JA_CPU_FEATURE_OVERRIDES_H
-#define __ASM_MACH_JA_CPU_FEATURE_OVERRIDES_H
-
-/*
- * Momentum Ocelot-3 is based on Rm7900 processor which
- * is based on the E9000 core.
- */
-#define cpu_has_watch          1
-#define cpu_has_mips16         0
-#define cpu_has_divec          0
-#define cpu_has_vce            0
-#define cpu_has_cache_cdex_p   0
-#define cpu_has_cache_cdex_s   0
-#define cpu_has_prefetch       1
-#define cpu_has_mcheck         0
-#define cpu_has_ejtag          0
-
-#define cpu_has_llsc           1
-#define cpu_has_vtag_icache    0
-#define cpu_has_dc_aliases     0
-#define cpu_has_ic_fills_f_dc  0
-#define cpu_has_dsp            0
-#define cpu_icache_snoops_remote_store 0
-
-#define cpu_has_nofpuex        0
-#define cpu_has_64bits         1
-
-#define cpu_has_inclusive_pcaches      0
-
-#define cpu_dcache_line_size() 32
-#define cpu_icache_line_size() 32
-#define cpu_scache_line_size() 32
-
-#define cpu_has_mips32r1       0
-#define cpu_has_mips32r2       0
-#define cpu_has_mips64r1       0
-#define cpu_has_mips64r2       0
-
-#endif /* __ASM_MACH_JA_CPU_FEATURE_OVERRIDES_H */
diff --git a/include/asm-mips/mach-tx49xx/ioremap.h b/include/asm-mips/mach-tx49xx/ioremap.h
new file mode 100644 (file)
index 0000000..1e7beae
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ *     include/asm-mips/mach-tx49xx/ioremap.h
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     as published by the Free Software Foundation; either version
+ *     2 of the License, or (at your option) any later version.
+ */
+#ifndef __ASM_MACH_TX49XX_IOREMAP_H
+#define __ASM_MACH_TX49XX_IOREMAP_H
+
+#include <linux/types.h>
+
+/*
+ * Allow physical addresses to be fixed up to help peripherals located
+ * outside the low 32-bit range -- generic pass-through version.
+ */
+static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
+{
+       return phys_addr;
+}
+
+static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size,
+       unsigned long flags)
+{
+#ifdef CONFIG_64BIT
+#define TXX9_DIRECTMAP_BASE    0xfff000000ul
+#else
+#define TXX9_DIRECTMAP_BASE    0xff000000ul
+#endif
+       if (offset >= TXX9_DIRECTMAP_BASE &&
+           offset < TXX9_DIRECTMAP_BASE + 0x400000)
+               return (void __iomem *)(unsigned long)(int)offset;
+       return NULL;
+}
+
+static inline int plat_iounmap(const volatile void __iomem *addr)
+{
+       return (unsigned long)addr >=
+               (unsigned long)(int)(TXX9_DIRECTMAP_BASE & 0xffffffff);
+}
+
+#endif /* __ASM_MACH_TX49XX_IOREMAP_H */
index cd7125610100a1987a36540410188a98913e38ad..dc3fc32eedd8f101a44030a8854b8200a2e45d97 100644 (file)
 /* offsets from base register */
 #define BONITO(x)      (x)
 
-#else /* !__ASSEMBLY__ */
+#elif defined(CONFIG_LEMOTE_FULONG)
+
+#define BONITO(x) (*(volatile u32 *)((char *)CKSEG1ADDR(BONITO_REG_BASE) + (x)))
+#define BONITO_IRQ_BASE   32
+
+#else
 
 /*
  * Algorithmics Bonito64 system controller register base.
index 89c81922d47cea5c5ea229cc6c87f1b5e525b9b7..18f47f1e8cd53eb14a44319a80ffe694b9b6b385 100644 (file)
@@ -7,7 +7,7 @@
  * Copyright (C) 2000 Silicon Graphics, Inc.
  * Modified for further R[236]000 support by Paul M. Antoine, 1996.
  * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ * Copyright (C) 2000, 07 MIPS Technologies, Inc.
  * Copyright (C) 2003, 2004  Maciej W. Rozycki
  */
 #ifndef _ASM_MIPSREGS_H
@@ -15,6 +15,7 @@
 
 #include <linux/linkage.h>
 #include <asm/hazards.h>
+#include <asm/war.h>
 
 /*
  * The following macros are especially useful for __asm__
 #define MIPS_CONF3_VEIC                (_ULCAST_(1) <<  6)
 #define MIPS_CONF3_LPA         (_ULCAST_(1) <<  7)
 #define MIPS_CONF3_DSP         (_ULCAST_(1) << 10)
+#define MIPS_CONF3_ULRI                (_ULCAST_(1) << 13)
 
 #define MIPS_CONF7_WII         (_ULCAST_(1) << 31)
 
+#define MIPS_CONF7_RPS         (_ULCAST_(1) << 2)
+
+
 /*
  * Bits in the MIPS32/64 coprocessor 1 (FPU) revision register.
  */
@@ -702,10 +707,10 @@ do {                                                                      \
  */
 #define __read_64bit_c0_split(source, sel)                             \
 ({                                                                     \
-       unsigned long long val;                                         \
-       unsigned long flags;                                            \
+       unsigned long long __val;                                       \
+       unsigned long __flags;                                          \
                                                                        \
-       local_irq_save(flags);                                          \
+       local_irq_save(__flags);                                        \
        if (sel == 0)                                                   \
                __asm__ __volatile__(                                   \
                        ".set\tmips64\n\t"                              \
@@ -714,7 +719,7 @@ do {                                                                        \
                        "dsrl\t%M0, %M0, 32\n\t"                        \
                        "dsrl\t%L0, %L0, 32\n\t"                        \
                        ".set\tmips0"                                   \
-                       : "=r" (val));                                  \
+                       : "=r" (__val));                                \
        else                                                            \
                __asm__ __volatile__(                                   \
                        ".set\tmips64\n\t"                              \
@@ -723,17 +728,17 @@ do {                                                                      \
                        "dsrl\t%M0, %M0, 32\n\t"                        \
                        "dsrl\t%L0, %L0, 32\n\t"                        \
                        ".set\tmips0"                                   \
-                       : "=r" (val));                                  \
-       local_irq_restore(flags);                                       \
+                       : "=r" (__val));                                \
+       local_irq_restore(__flags);                                     \
                                                                        \
-       val;                                                            \
+       __val;                                                          \
 })
 
 #define __write_64bit_c0_split(source, sel, val)                       \
 do {                                                                   \
-       unsigned long flags;                                            \
+       unsigned long __flags;                                          \
                                                                        \
-       local_irq_save(flags);                                          \
+       local_irq_save(__flags);                                        \
        if (sel == 0)                                                   \
                __asm__ __volatile__(                                   \
                        ".set\tmips64\n\t"                              \
@@ -754,7 +759,7 @@ do {                                                                        \
                        "dmtc0\t%L0, " #source ", " #sel "\n\t"         \
                        ".set\tmips0"                                   \
                        : : "r" (val));                                 \
-       local_irq_restore(flags);                                       \
+       local_irq_restore(__flags);                                     \
 } while (0)
 
 #define read_c0_index()                __read_32bit_c0_register($0, 0)
@@ -772,6 +777,9 @@ do {                                                                        \
 #define read_c0_context()      __read_ulong_c0_register($4, 0)
 #define write_c0_context(val)  __write_ulong_c0_register($4, 0, val)
 
+#define read_c0_userlocal()    __read_ulong_c0_register($4, 2)
+#define write_c0_userlocal(val)        __write_ulong_c0_register($4, 2, val)
+
 #define read_c0_pagemask()     __read_32bit_c0_register($5, 0)
 #define write_c0_pagemask(val) __write_32bit_c0_register($5, 0, val)
 
@@ -1294,10 +1302,39 @@ static inline void tlb_probe(void)
 
 static inline void tlb_read(void)
 {
+#if MIPS34K_MISSED_ITLB_WAR
+       int res = 0;
+
+       __asm__ __volatile__(
+       "       .set    push                                    \n"
+       "       .set    noreorder                               \n"
+       "       .set    noat                                    \n"
+       "       .set    mips32r2                                \n"
+       "       .word   0x41610001              # dvpe $1       \n"
+       "       move    %0, $1                                  \n"
+       "       ehb                                             \n"
+       "       .set    pop                                     \n"
+       : "=r" (res));
+
+       instruction_hazard();
+#endif
+
        __asm__ __volatile__(
                ".set noreorder\n\t"
                "tlbr\n\t"
                ".set reorder");
+
+#if MIPS34K_MISSED_ITLB_WAR
+       if ((res & _ULCAST_(1)))
+               __asm__ __volatile__(
+               "       .set    push                            \n"
+               "       .set    noreorder                       \n"
+               "       .set    noat                            \n"
+               "       .set    mips32r2                        \n"
+               "       .word   0x41600021      # evpe          \n"
+               "       ehb                                     \n"
+               "       .set    pop                             \n");
+#endif
 }
 
 static inline void tlb_write_indexed(void)
index c5ef324fd69f7a7824897a77dc7857948f0ec0d8..de6d09ebbd800a94a8503e45f84b9bfe5f7ceeec 100644 (file)
@@ -112,6 +112,8 @@ search_module_dbetables(unsigned long addr)
 #define MODULE_PROC_FAMILY "RM9000 "
 #elif defined CONFIG_CPU_SB1
 #define MODULE_PROC_FAMILY "SB1 "
+#elif defined CONFIG_CPU_LOONGSON2
+#define MODULE_PROC_FAMILY "LOONGSON2 "
 #else
 #error MODULE_PROC_FAMILY undefined for your processor configuration
 #endif
diff --git a/include/asm-mips/nile4.h b/include/asm-mips/nile4.h
deleted file mode 100644 (file)
index c3ca959..0000000
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- *  asm-mips/nile4.h -- NEC Vrc-5074 Nile 4 definitions
- *
- *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
- *                     Sony Software Development Center Europe (SDCE), Brussels
- *
- *  This file is based on the following documentation:
- *
- *     NEC Vrc 5074 System Controller Data Sheet, June 1998
- */
-
-#ifndef _ASM_NILE4_H
-#define _ASM_NILE4_H
-
-#define NILE4_BASE             0xbfa00000
-#define NILE4_SIZE             0x00200000              /* 2 MB */
-
-
-    /*
-     *  Physical Device Address Registers (PDARs)
-     */
-
-#define NILE4_SDRAM0   0x0000  /* SDRAM Bank 0 [R/W] */
-#define NILE4_SDRAM1   0x0008  /* SDRAM Bank 1 [R/W] */
-#define NILE4_DCS2     0x0010  /* Device Chip-Select 2 [R/W] */
-#define NILE4_DCS3     0x0018  /* Device Chip-Select 3 [R/W] */
-#define NILE4_DCS4     0x0020  /* Device Chip-Select 4 [R/W] */
-#define NILE4_DCS5     0x0028  /* Device Chip-Select 5 [R/W] */
-#define NILE4_DCS6     0x0030  /* Device Chip-Select 6 [R/W] */
-#define NILE4_DCS7     0x0038  /* Device Chip-Select 7 [R/W] */
-#define NILE4_DCS8     0x0040  /* Device Chip-Select 8 [R/W] */
-#define NILE4_PCIW0    0x0060  /* PCI Address Window 0 [R/W] */
-#define NILE4_PCIW1    0x0068  /* PCI Address Window 1 [R/W] */
-#define NILE4_INTCS    0x0070  /* Controller Internal Registers and Devices */
-                               /* [R/W] */
-#define NILE4_BOOTCS   0x0078  /* Boot ROM Chip-Select [R/W] */
-
-
-    /*
-     *  CPU Interface Registers
-     */
-
-#define NILE4_CPUSTAT  0x0080  /* CPU Status [R/W] */
-#define NILE4_INTCTRL  0x0088  /* Interrupt Control [R/W] */
-#define NILE4_INTSTAT0 0x0090  /* Interrupt Status 0 [R] */
-#define NILE4_INTSTAT1 0x0098  /* Interrupt Status 1 and CPU Interrupt */
-                               /* Enable [R/W] */
-#define NILE4_INTCLR   0x00A0  /* Interrupt Clear [R/W] */
-#define NILE4_INTPPES  0x00A8  /* PCI Interrupt Control [R/W] */
-
-
-    /*
-     *  Memory-Interface Registers
-     */
-
-#define NILE4_MEMCTRL  0x00C0  /* Memory Control */
-#define NILE4_ACSTIME  0x00C8  /* Memory Access Timing [R/W] */
-#define NILE4_CHKERR   0x00D0  /* Memory Check Error Status [R] */
-
-
-    /*
-     *  PCI-Bus Registers
-     */
-
-#define NILE4_PCICTRL  0x00E0  /* PCI Control [R/W] */
-#define NILE4_PCIARB   0x00E8  /* PCI Arbiter [R/W] */
-#define NILE4_PCIINIT0 0x00F0  /* PCI Master (Initiator) 0 [R/W] */
-#define NILE4_PCIINIT1 0x00F8  /* PCI Master (Initiator) 1 [R/W] */
-#define NILE4_PCIERR   0x00B8  /* PCI Error [R/W] */
-
-
-    /*
-     *  Local-Bus Registers
-     */
-
-#define NILE4_LCNFG    0x0100  /* Local Bus Configuration [R/W] */
-#define NILE4_LCST2    0x0110  /* Local Bus Chip-Select Timing 2 [R/W] */
-#define NILE4_LCST3    0x0118  /* Local Bus Chip-Select Timing 3 [R/W] */
-#define NILE4_LCST4    0x0120  /* Local Bus Chip-Select Timing 4 [R/W] */
-#define NILE4_LCST5    0x0128  /* Local Bus Chip-Select Timing 5 [R/W] */
-#define NILE4_LCST6    0x0130  /* Local Bus Chip-Select Timing 6 [R/W] */
-#define NILE4_LCST7    0x0138  /* Local Bus Chip-Select Timing 7 [R/W] */
-#define NILE4_LCST8    0x0140  /* Local Bus Chip-Select Timing 8 [R/W] */
-#define NILE4_DCSFN    0x0150  /* Device Chip-Select Muxing and Output */
-                               /* Enables [R/W] */
-#define NILE4_DCSIO    0x0158  /* Device Chip-Selects As I/O Bits [R/W] */
-#define NILE4_BCST     0x0178  /* Local Boot Chip-Select Timing [R/W] */
-
-
-    /*
-     *  DMA Registers
-     */
-
-#define NILE4_DMACTRL0 0x0180  /* DMA Control 0 [R/W] */
-#define NILE4_DMASRCA0 0x0188  /* DMA Source Address 0 [R/W] */
-#define NILE4_DMADESA0 0x0190  /* DMA Destination Address 0 [R/W] */
-#define NILE4_DMACTRL1 0x0198  /* DMA Control 1 [R/W] */
-#define NILE4_DMASRCA1 0x01A0  /* DMA Source Address 1 [R/W] */
-#define NILE4_DMADESA1 0x01A8  /* DMA Destination Address 1 [R/W] */
-
-
-    /*
-     *  Timer Registers
-     */
-
-#define NILE4_T0CTRL   0x01C0  /* SDRAM Refresh Control [R/W] */
-#define NILE4_T0CNTR   0x01C8  /* SDRAM Refresh Counter [R/W] */
-#define NILE4_T1CTRL   0x01D0  /* CPU-Bus Read Time-Out Control [R/W] */
-#define NILE4_T1CNTR   0x01D8  /* CPU-Bus Read Time-Out Counter [R/W] */
-#define NILE4_T2CTRL   0x01E0  /* General-Purpose Timer Control [R/W] */
-#define NILE4_T2CNTR   0x01E8  /* General-Purpose Timer Counter [R/W] */
-#define NILE4_T3CTRL   0x01F0  /* Watchdog Timer Control [R/W] */
-#define NILE4_T3CNTR   0x01F8  /* Watchdog Timer Counter [R/W] */
-
-
-    /*
-     *  PCI Configuration Space Registers
-     */
-
-#define NILE4_PCI_BASE 0x0200
-
-#define NILE4_VID      0x0200  /* PCI Vendor ID [R] */
-#define NILE4_DID      0x0202  /* PCI Device ID [R] */
-#define NILE4_PCICMD   0x0204  /* PCI Command [R/W] */
-#define NILE4_PCISTS   0x0206  /* PCI Status [R/W] */
-#define NILE4_REVID    0x0208  /* PCI Revision ID [R] */
-#define NILE4_CLASS    0x0209  /* PCI Class Code [R] */
-#define NILE4_CLSIZ    0x020C  /* PCI Cache Line Size [R/W] */
-#define NILE4_MLTIM    0x020D  /* PCI Latency Timer [R/W] */
-#define NILE4_HTYPE    0x020E  /* PCI Header Type [R] */
-#define NILE4_BIST     0x020F  /* BIST [R] (unimplemented) */
-#define NILE4_BARC     0x0210  /* PCI Base Address Register Control [R/W] */
-#define NILE4_BAR0     0x0218  /* PCI Base Address Register 0 [R/W] */
-#define NILE4_BAR1     0x0220  /* PCI Base Address Register 1 [R/W] */
-#define NILE4_CIS      0x0228  /* PCI Cardbus CIS Pointer [R] */
-                               /* (unimplemented) */
-#define NILE4_SSVID    0x022C  /* PCI Sub-System Vendor ID [R/W] */
-#define NILE4_SSID     0x022E  /* PCI Sub-System ID [R/W] */
-#define NILE4_ROM      0x0230  /* Expansion ROM Base Address [R] */
-                               /* (unimplemented) */
-#define NILE4_INTLIN   0x023C  /* PCI Interrupt Line [R/W] */
-#define NILE4_INTPIN   0x023D  /* PCI Interrupt Pin [R] */
-#define NILE4_MINGNT   0x023E  /* PCI Min_Gnt [R] (unimplemented) */
-#define NILE4_MAXLAT   0x023F  /* PCI Max_Lat [R] (unimplemented) */
-#define NILE4_BAR2     0x0240  /* PCI Base Address Register 2 [R/W] */
-#define NILE4_BAR3     0x0248  /* PCI Base Address Register 3 [R/W] */
-#define NILE4_BAR4     0x0250  /* PCI Base Address Register 4 [R/W] */
-#define NILE4_BAR5     0x0258  /* PCI Base Address Register 5 [R/W] */
-#define NILE4_BAR6     0x0260  /* PCI Base Address Register 6 [R/W] */
-#define NILE4_BAR7     0x0268  /* PCI Base Address Register 7 [R/W] */
-#define NILE4_BAR8     0x0270  /* PCI Base Address Register 8 [R/W] */
-#define NILE4_BARB     0x0278  /* PCI Base Address Register BOOT [R/W] */
-
-
-    /*
-     *  Serial-Port Registers
-     */
-
-#define NILE4_UART_BASE        0x0300
-
-#define NILE4_UARTRBR  0x0300  /* UART Receiver Data Buffer [R] */
-#define NILE4_UARTTHR  0x0300  /* UART Transmitter Data Holding [W] */
-#define NILE4_UARTIER  0x0308  /* UART Interrupt Enable [R/W] */
-#define NILE4_UARTDLL  0x0300  /* UART Divisor Latch LSB [R/W] */
-#define NILE4_UARTDLM  0x0308  /* UART Divisor Latch MSB [R/W] */
-#define NILE4_UARTIIR  0x0310  /* UART Interrupt ID [R] */
-#define NILE4_UARTFCR  0x0310  /* UART FIFO Control [W] */
-#define NILE4_UARTLCR  0x0318  /* UART Line Control [R/W] */
-#define NILE4_UARTMCR  0x0320  /* UART Modem Control [R/W] */
-#define NILE4_UARTLSR  0x0328  /* UART Line Status [R/W] */
-#define NILE4_UARTMSR  0x0330  /* UART Modem Status [R/W] */
-#define NILE4_UARTSCR  0x0338  /* UART Scratch [R/W] */
-
-#define NILE4_UART_BASE_BAUD   520833  /* 100 MHz / 12 / 16 */
-
-
-    /*
-     *  Interrupt Lines
-     */
-
-#define NILE4_INT_CPCE 0       /* CPU-Interface Parity-Error Interrupt */
-#define NILE4_INT_CNTD 1       /* CPU No-Target Decode Interrupt */
-#define NILE4_INT_MCE  2       /* Memory-Check Error Interrupt */
-#define NILE4_INT_DMA  3       /* DMA Controller Interrupt */
-#define NILE4_INT_UART 4       /* UART Interrupt */
-#define NILE4_INT_WDOG 5       /* Watchdog Timer Interrupt */
-#define NILE4_INT_GPT  6       /* General-Purpose Timer Interrupt */
-#define NILE4_INT_LBRTD        7       /* Local-Bus Ready Timer Interrupt */
-#define NILE4_INT_INTA 8       /* PCI Interrupt Signal INTA# */
-#define NILE4_INT_INTB 9       /* PCI Interrupt Signal INTB# */
-#define NILE4_INT_INTC 10      /* PCI Interrupt Signal INTC# */
-#define NILE4_INT_INTD 11      /* PCI Interrupt Signal INTD# */
-#define NILE4_INT_INTE 12      /* PCI Interrupt Signal INTE# (ISA cascade) */
-#define NILE4_INT_RESV 13      /* Reserved */
-#define NILE4_INT_PCIS 14      /* PCI SERR# Interrupt */
-#define NILE4_INT_PCIE 15      /* PCI Internal Error Interrupt */
-
-
-    /*
-     *  Nile 4 Register Access
-     */
-
-static inline void nile4_sync(void)
-{
-    volatile u32 *p = (volatile u32 *)0xbfc00000;
-    (void)(*p);
-}
-
-static inline void nile4_out32(u32 offset, u32 val)
-{
-    *(volatile u32 *)(NILE4_BASE+offset) = val;
-    nile4_sync();
-}
-
-static inline u32 nile4_in32(u32 offset)
-{
-    u32 val = *(volatile u32 *)(NILE4_BASE+offset);
-    nile4_sync();
-    return val;
-}
-
-static inline void nile4_out16(u32 offset, u16 val)
-{
-    *(volatile u16 *)(NILE4_BASE+offset) = val;
-    nile4_sync();
-}
-
-static inline u16 nile4_in16(u32 offset)
-{
-    u16 val = *(volatile u16 *)(NILE4_BASE+offset);
-    nile4_sync();
-    return val;
-}
-
-static inline void nile4_out8(u32 offset, u8 val)
-{
-    *(volatile u8 *)(NILE4_BASE+offset) = val;
-    nile4_sync();
-}
-
-static inline u8 nile4_in8(u32 offset)
-{
-    u8 val = *(volatile u8 *)(NILE4_BASE+offset);
-    nile4_sync();
-    return val;
-}
-
-
-    /*
-     *  Physical Device Address Registers
-     */
-
-extern void nile4_set_pdar(u32 pdar, u32 phys, u32 size, int width,
-                          int on_memory_bus, int visible);
-
-
-    /*
-     *  PCI Master Registers
-     */
-
-#define NILE4_PCICMD_IACK      0       /* PCI Interrupt Acknowledge */
-#define NILE4_PCICMD_IO                1       /* PCI I/O Space */
-#define NILE4_PCICMD_MEM       3       /* PCI Memory Space */
-#define NILE4_PCICMD_CFG       5       /* PCI Configuration Space */
-
-
-    /*
-     *  PCI Address Spaces
-     *
-     *  Note that these are multiplexed using PCIINIT[01]!
-     */
-
-#define NILE4_PCI_IO_BASE      0xa6000000
-#define NILE4_PCI_MEM_BASE     0xa8000000
-#define NILE4_PCI_CFG_BASE     NILE4_PCI_MEM_BASE
-#define NILE4_PCI_IACK_BASE    NILE4_PCI_IO_BASE
-
-
-extern void nile4_set_pmr(u32 pmr, u32 type, u32 addr);
-
-
-    /*
-     *  Interrupt Programming
-     */
-
-#define NUM_I8259_INTERRUPTS   16
-#define NUM_NILE4_INTERRUPTS   16
-
-#define IRQ_I8259_CASCADE      NILE4_INT_INTE
-#define is_i8259_irq(irq)      ((irq) < NUM_I8259_INTERRUPTS)
-#define nile4_to_irq(n)                ((n)+NUM_I8259_INTERRUPTS)
-#define irq_to_nile4(n)                ((n)-NUM_I8259_INTERRUPTS)
-
-extern void nile4_map_irq(int nile4_irq, int cpu_irq);
-extern void nile4_map_irq_all(int cpu_irq);
-extern void nile4_enable_irq(unsigned int nile4_irq);
-extern void nile4_disable_irq(unsigned int nile4_irq);
-extern void nile4_disable_irq_all(void);
-extern u16 nile4_get_irq_stat(int cpu_irq);
-extern void nile4_enable_irq_output(int cpu_irq);
-extern void nile4_disable_irq_output(int cpu_irq);
-extern void nile4_set_pci_irq_polarity(int pci_irq, int high);
-extern void nile4_set_pci_irq_level_or_edge(int pci_irq, int level);
-extern void nile4_clear_irq(int nile4_irq);
-extern void nile4_clear_irq_mask(u32 mask);
-extern u8 nile4_i8259_iack(void);
-extern void nile4_dump_irq_status(void);       /* Debug */
-
-#endif
-
index 5c3239dad0f26ef09306252cb272586d4d5af740..b92dd8c760da5d8a600f6abb33bd62b9bc6c1146 100644 (file)
 
 #ifndef __ASSEMBLY__
 
-/*
- * This gives the physical RAM offset.
- */
-#ifndef PHYS_OFFSET
-#define PHYS_OFFSET            0UL
-#endif
+#include <linux/pfn.h>
+#include <asm/io.h>
 
 /*
  * It's normally defined only for FLATMEM config but it's
@@ -48,9 +44,6 @@
  */
 #define ARCH_PFN_OFFSET                PFN_UP(PHYS_OFFSET)
 
-#include <linux/pfn.h>
-#include <asm/io.h>
-
 extern void clear_page(void * page);
 extern void copy_page(void * to, void * from);
 
@@ -150,11 +143,15 @@ typedef struct { unsigned long pgprot; } pgprot_t;
  * __pa()/__va() should be used only during mem init.
  */
 #if defined(CONFIG_64BIT) && !defined(CONFIG_BUILD_ELF64)
-#define __pa_page_offset(x)    ((unsigned long)(x) < CKSEG0 ? PAGE_OFFSET : CKSEG0)
+#define __pa(x)                                                                \
+({                                                                     \
+    unsigned long __x = (unsigned long)(x);                            \
+    __x < CKSEG0 ? XPHYSADDR(__x) : CPHYSADDR(__x);                    \
+})
 #else
-#define __pa_page_offset(x)    PAGE_OFFSET
+#define __pa(x)                                                                \
+    ((unsigned long)(x) - PAGE_OFFSET + PHYS_OFFSET)
 #endif
-#define __pa(x)                ((unsigned long)(x) - __pa_page_offset(x) + PHYS_OFFSET)
 #define __va(x)                ((void *)((unsigned long)(x) + PAGE_OFFSET - PHYS_OFFSET))
 #define __pa_symbol(x) __pa(RELOC_HIDE((unsigned long)(x),0))
 
index 3eea3ba0fca5ec7f2353a0555c0dc47c2800637d..4fcc185cb2d1f65a7a2267f851d5d6ec97f2306b 100644 (file)
@@ -56,7 +56,7 @@ extern void register_pci_controller(struct pci_controller *hose);
 /*
  * board supplied pci irq fixup routine
  */
-extern int pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin);
+extern int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin);
 
 
 /* Can be used to override the logic in pci_scan_bus for skipping
@@ -121,20 +121,6 @@ extern unsigned int PCI_DMA_BUS_IS_PHYS;
 
 #endif /* CONFIG_DMA_NEED_PCI_MAP_STATE  */
 
-/* This is always fine. */
-#define pci_dac_dma_supported(pci_dev, mask)   (1)
-
-extern dma64_addr_t pci_dac_page_to_dma(struct pci_dev *pdev,
-       struct page *page, unsigned long offset, int direction);
-extern struct page *pci_dac_dma_to_page(struct pci_dev *pdev,
-       dma64_addr_t dma_addr);
-extern unsigned long pci_dac_dma_to_offset(struct pci_dev *pdev,
-       dma64_addr_t dma_addr);
-extern void pci_dac_dma_sync_single_for_cpu(struct pci_dev *pdev,
-       dma64_addr_t dma_addr, size_t len, int direction);
-extern void pci_dac_dma_sync_single_for_device(struct pci_dev *pdev,
-       dma64_addr_t dma_addr, size_t len, int direction);
-
 #ifdef CONFIG_PCI
 static inline void pci_dma_burst_advice(struct pci_dev *pdev,
                                        enum pci_dma_burst_strategy *strat,
@@ -181,10 +167,6 @@ static inline int pci_proc_domain(struct pci_bus *bus)
 /* implement the pci_ DMA API in terms of the generic device dma_ one */
 #include <asm-generic/pci-dma-compat.h>
 
-static inline void pcibios_add_platform_entries(struct pci_dev *dev)
-{
-}
-
 /* Do platform specific device initialization at pci_enable_device() time */
 extern int pcibios_plat_dev_init(struct pci_dev *dev);
 
diff --git a/include/asm-mips/pmc-sierra/msp71xx/msp_cic_int.h b/include/asm-mips/pmc-sierra/msp71xx/msp_cic_int.h
new file mode 100644 (file)
index 0000000..c84bcf9
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * Defines for the MSP interrupt controller.
+ *
+ * Copyright (C) 1999 MIPS Technologies, Inc.  All rights reserved.
+ * Author: Carsten Langgaard, carstenl@mips.com
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You 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 _MSP_CIC_INT_H
+#define _MSP_CIC_INT_H
+
+/*
+ * The PMC-Sierra CIC interrupts are all centrally managed by the
+ * CIC sub-system.
+ * We attempt to keep the interrupt numbers as consistent as possible
+ * across all of the MSP devices, but some differences will creep in ...
+ * The interrupts which are directly forwarded to the MIPS core interrupts
+ * are assigned interrupts in the range 0-7, interrupts cascaded through
+ * the CIC are assigned interrupts 8-39.  The cascade occurs on C_IRQ4
+ * (MSP_INT_CIC).  Currently we don't really distinguish between VPE1
+ * and VPE0 (or thread contexts for that matter).  Will have to fix.
+ * The PER interrupts are assigned interrupts in the range 40-71.
+*/
+
+
+/*
+ * IRQs directly forwarded to the CPU
+ */
+#define MSP_MIPS_INTBASE       0
+#define MSP_INT_SW0            0       /* IRQ for swint0,       C_SW0  */
+#define MSP_INT_SW1            1       /* IRQ for swint1,       C_SW1  */
+#define MSP_INT_MAC0           2       /* IRQ for MAC 0,        C_IRQ0 */
+#define MSP_INT_MAC1           3       /* IRQ for MAC 1,        C_IRQ1 */
+#define MSP_INT_USB            4       /* IRQ for USB,          C_IRQ2 */
+#define MSP_INT_SAR            5       /* IRQ for ADSL2+ SAR,   C_IRQ3 */
+#define MSP_INT_CIC            6       /* IRQ for CIC block,    C_IRQ4 */
+#define MSP_INT_SEC            7       /* IRQ for Sec engine,   C_IRQ5 */
+
+/*
+ * IRQs cascaded on CPU interrupt 4 (CAUSE bit 12, C_IRQ4)
+ * These defines should be tied to the register definitions for the CIC
+ * interrupt routine.  For now, just use hard-coded values.
+ */
+#define MSP_CIC_INTBASE                (MSP_MIPS_INTBASE + 8)
+#define MSP_INT_EXT0           (MSP_CIC_INTBASE + 0)
+                                       /* External interrupt 0         */
+#define MSP_INT_EXT1           (MSP_CIC_INTBASE + 1)
+                                       /* External interrupt 1         */
+#define MSP_INT_EXT2           (MSP_CIC_INTBASE + 2)
+                                       /* External interrupt 2         */
+#define MSP_INT_EXT3           (MSP_CIC_INTBASE + 3)
+                                       /* External interrupt 3         */
+#define MSP_INT_CPUIF          (MSP_CIC_INTBASE + 4)
+                                       /* CPU interface interrupt      */
+#define MSP_INT_EXT4           (MSP_CIC_INTBASE + 5)
+                                       /* External interrupt 4         */
+#define MSP_INT_CIC_USB                (MSP_CIC_INTBASE + 6)
+                                       /* Cascaded IRQ for USB         */
+#define MSP_INT_MBOX           (MSP_CIC_INTBASE + 7)
+                                       /* Sec engine mailbox IRQ       */
+#define MSP_INT_EXT5           (MSP_CIC_INTBASE + 8)
+                                       /* External interrupt 5         */
+#define MSP_INT_TDM            (MSP_CIC_INTBASE + 9)
+                                       /* TDM interrupt                */
+#define MSP_INT_CIC_MAC0       (MSP_CIC_INTBASE + 10)
+                                       /* Cascaded IRQ for MAC 0       */
+#define MSP_INT_CIC_MAC1       (MSP_CIC_INTBASE + 11)
+                                       /* Cascaded IRQ for MAC 1       */
+#define MSP_INT_CIC_SEC                (MSP_CIC_INTBASE + 12)
+                                       /* Cascaded IRQ for sec engine  */
+#define        MSP_INT_PER             (MSP_CIC_INTBASE + 13)
+                                       /* Peripheral interrupt         */
+#define        MSP_INT_TIMER0          (MSP_CIC_INTBASE + 14)
+                                       /* SLP timer 0                  */
+#define        MSP_INT_TIMER1          (MSP_CIC_INTBASE + 15)
+                                       /* SLP timer 1                  */
+#define        MSP_INT_TIMER2          (MSP_CIC_INTBASE + 16)
+                                       /* SLP timer 2                  */
+#define        MSP_INT_VPE0_TIMER      (MSP_CIC_INTBASE + 17)
+                                       /* VPE0 MIPS timer              */
+#define MSP_INT_BLKCP          (MSP_CIC_INTBASE + 18)
+                                       /* Block Copy                   */
+#define MSP_INT_UART0          (MSP_CIC_INTBASE + 19)
+                                       /* UART 0                       */
+#define MSP_INT_PCI            (MSP_CIC_INTBASE + 20)
+                                       /* PCI subsystem                */
+#define MSP_INT_EXT6           (MSP_CIC_INTBASE + 21)
+                                       /* External interrupt 5         */
+#define MSP_INT_PCI_MSI                (MSP_CIC_INTBASE + 22)
+                                       /* PCI Message Signal           */
+#define MSP_INT_CIC_SAR                (MSP_CIC_INTBASE + 23)
+                                       /* Cascaded ADSL2+ SAR IRQ      */
+#define MSP_INT_DSL            (MSP_CIC_INTBASE + 24)
+                                       /* ADSL2+ IRQ                   */
+#define MSP_INT_CIC_ERR                (MSP_CIC_INTBASE + 25)
+                                       /* SLP error condition          */
+#define MSP_INT_VPE1_TIMER     (MSP_CIC_INTBASE + 26)
+                                       /* VPE1 MIPS timer              */
+#define MSP_INT_VPE0_PC                (MSP_CIC_INTBASE + 27)
+                                       /* VPE0 Performance counter     */
+#define MSP_INT_VPE1_PC                (MSP_CIC_INTBASE + 28)
+                                       /* VPE1 Performance counter     */
+#define MSP_INT_EXT7           (MSP_CIC_INTBASE + 29)
+                                       /* External interrupt 5         */
+#define MSP_INT_VPE0_SW                (MSP_CIC_INTBASE + 30)
+                                       /* VPE0 Software interrupt      */
+#define MSP_INT_VPE1_SW                (MSP_CIC_INTBASE + 31)
+                                       /* VPE0 Software interrupt      */
+
+/*
+ * IRQs cascaded on CIC PER interrupt (MSP_INT_PER)
+ */
+#define MSP_PER_INTBASE                (MSP_CIC_INTBASE + 32)
+/* Reserved                                       0-1                  */
+#define MSP_INT_UART1          (MSP_PER_INTBASE + 2)
+                                       /* UART 1                       */
+/* Reserved                                       3-5                  */
+#define MSP_INT_2WIRE          (MSP_PER_INTBASE + 6)
+                                       /* 2-wire                       */
+#define MSP_INT_TM0            (MSP_PER_INTBASE + 7)
+                                       /* Peripheral timer block out 0 */
+#define MSP_INT_TM1            (MSP_PER_INTBASE + 8)
+                                       /* Peripheral timer block out 1 */
+/* Reserved                                       9                    */
+#define MSP_INT_SPRX           (MSP_PER_INTBASE + 10)
+                                       /* SPI RX complete              */
+#define MSP_INT_SPTX           (MSP_PER_INTBASE + 11)
+                                       /* SPI TX complete              */
+#define MSP_INT_GPIO           (MSP_PER_INTBASE + 12)
+                                       /* GPIO                         */
+#define MSP_INT_PER_ERR                (MSP_PER_INTBASE + 13)
+                                       /* Peripheral error             */
+/* Reserved                                       14-31                */
+
+#endif /* !_MSP_CIC_INT_H */
diff --git a/include/asm-mips/pmc-sierra/msp71xx/msp_int.h b/include/asm-mips/pmc-sierra/msp71xx/msp_int.h
new file mode 100644 (file)
index 0000000..1d9f054
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Defines for the MSP interrupt handlers.
+ *
+ * Copyright (C) 2005, PMC-Sierra, Inc.  All rights reserved.
+ * Author: Andrew Hughes, Andrew_Hughes@pmc-sierra.com
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You 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 _MSP_INT_H
+#define _MSP_INT_H
+
+/*
+ * The PMC-Sierra MSP product line has at least two different interrupt
+ * controllers, the SLP register based scheme and the CIC interrupt
+ * controller block mechanism.  This file distinguishes between them
+ * so that devices see a uniform interface.
+ */
+
+#if defined(CONFIG_IRQ_MSP_SLP)
+       #include "msp_slp_int.h"
+#elif defined(CONFIG_IRQ_MSP_CIC)
+       #include "msp_cic_int.h"
+#else
+       #error "What sort of interrupt controller does *your* MSP have?"
+#endif
+
+#endif /* !_MSP_INT_H */
diff --git a/include/asm-mips/pmc-sierra/msp71xx/msp_pci.h b/include/asm-mips/pmc-sierra/msp71xx/msp_pci.h
new file mode 100644 (file)
index 0000000..4156069
--- /dev/null
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2000-2006 PMC-Sierra INC.
+ *
+ *     This program is free software; you can redistribute it
+ *     and/or modify it under the terms of the GNU General
+ *     Public License as published by the Free Software
+ *     Foundation; either version 2 of the License, or (at your
+ *     option) any later version.
+ *
+ *     This program is distributed in the hope that it will be
+ *     useful, but WITHOUT ANY WARRANTY; without even the implied
+ *     warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ *     PURPOSE.  See the GNU General Public License for more
+ *     details.
+ *
+ *     You should have received a copy of the GNU General Public
+ *     License along with this program; if not, write to the Free
+ *     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
+ *     02139, USA.
+ *
+ * PMC-SIERRA INC. DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS
+ * SOFTWARE.
+ */
+
+#ifndef _MSP_PCI_H_
+#define _MSP_PCI_H_
+
+#define MSP_HAS_PCI(ID)        (((u32)(ID) <= 0x4236) && ((u32)(ID) >= 0x4220))
+
+/*
+ * It is convenient to program the OATRAN register so that
+ * Athena virtual address space and PCI address space are
+ * the same. This is not a requirement, just a convenience.
+ *
+ * The only hard restrictions on the value of OATRAN is that
+ * OATRAN must not be programmed to allow translated memory
+ * addresses to fall within the lowest 512MB of
+ * PCI address space. This region is hardcoded
+ * for use as Athena PCI Host Controller target
+ * access memory space to the Athena's SDRAM.
+ *
+ * Note that OATRAN applies only to memory accesses, not
+ * to I/O accesses.
+ *
+ * To program OATRAN to make Athena virtual address space
+ * and PCI address space have the same values, OATRAN
+ * is to be programmed to 0xB8000000. The top seven
+ * bits of the value mimic the seven bits clipped off
+ * by the PCI Host controller.
+ *
+ * With OATRAN at the said value, when the CPU does
+ * an access to its virtual address at, say 0xB900_5000,
+ * the address appearing on the PCI bus will be
+ * 0xB900_5000.
+ *    - Michael Penner
+ */
+#define MSP_PCI_OATRAN         0xB8000000UL
+
+#define MSP_PCI_SPACE_BASE     (MSP_PCI_OATRAN + 0x1002000UL)
+#define MSP_PCI_SPACE_SIZE     (0x3000000UL - 0x2000)
+#define MSP_PCI_SPACE_END \
+               (MSP_PCI_SPACE_BASE + MSP_PCI_SPACE_SIZE - 1)
+#define MSP_PCI_IOSPACE_BASE   (MSP_PCI_OATRAN + 0x1001000UL)
+#define MSP_PCI_IOSPACE_SIZE   0x1000
+#define MSP_PCI_IOSPACE_END  \
+               (MSP_PCI_IOSPACE_BASE + MSP_PCI_IOSPACE_SIZE - 1)
+
+/* IRQ for PCI status interrupts */
+#define PCI_STAT_IRQ   20
+
+#define QFLUSH_REG_1   0xB7F40000
+
+typedef volatile unsigned int pcireg;
+typedef void * volatile ppcireg;
+
+struct pci_block_copy
+{
+    pcireg   unused1; /* +0x00 */
+    pcireg   unused2; /* +0x04 */
+    ppcireg  unused3; /* +0x08 */
+    ppcireg  unused4; /* +0x0C */
+    pcireg   unused5; /* +0x10 */
+    pcireg   unused6; /* +0x14 */
+    pcireg   unused7; /* +0x18 */
+    ppcireg  unused8; /* +0x1C */
+    ppcireg  unused9; /* +0x20 */
+    pcireg   unusedA; /* +0x24 */
+    ppcireg  unusedB; /* +0x28 */
+    ppcireg  unusedC; /* +0x2C */
+};
+
+enum
+{
+    config_device_vendor,  /* 0 */
+    config_status_command, /* 1 */
+    config_class_revision, /* 2 */
+    config_BIST_header_latency_cache, /* 3 */
+    config_BAR0,           /* 4 */
+    config_BAR1,           /* 5 */
+    config_BAR2,           /* 6 */
+    config_not_used7,      /* 7 */
+    config_not_used8,      /* 8 */
+    config_not_used9,      /* 9 */
+    config_CIS,            /* 10 */
+    config_subsystem,      /* 11 */
+    config_not_used12,     /* 12 */
+    config_capabilities,   /* 13 */
+    config_not_used14,     /* 14 */
+    config_lat_grant_irq,  /* 15 */
+    config_message_control,/* 16 */
+    config_message_addr,   /* 17 */
+    config_message_data,   /* 18 */
+    config_VPD_addr,       /* 19 */
+    config_VPD_data,       /* 20 */
+    config_maxregs         /* 21 - number of registers */
+};
+
+struct msp_pci_regs
+{
+    pcireg hop_unused_00; /* +0x00 */
+    pcireg hop_unused_04; /* +0x04 */
+    pcireg hop_unused_08; /* +0x08 */
+    pcireg hop_unused_0C; /* +0x0C */
+    pcireg hop_unused_10; /* +0x10 */
+    pcireg hop_unused_14; /* +0x14 */
+    pcireg hop_unused_18; /* +0x18 */
+    pcireg hop_unused_1C; /* +0x1C */
+    pcireg hop_unused_20; /* +0x20 */
+    pcireg hop_unused_24; /* +0x24 */
+    pcireg hop_unused_28; /* +0x28 */
+    pcireg hop_unused_2C; /* +0x2C */
+    pcireg hop_unused_30; /* +0x30 */
+    pcireg hop_unused_34; /* +0x34 */
+    pcireg if_control;    /* +0x38 */
+    pcireg oatran;        /* +0x3C */
+    pcireg reset_ctl;     /* +0x40 */
+    pcireg config_addr;   /* +0x44 */
+    pcireg hop_unused_48; /* +0x48 */
+    pcireg msg_signaled_int_status; /* +0x4C */
+    pcireg msg_signaled_int_mask;   /* +0x50 */
+    pcireg if_status;     /* +0x54 */
+    pcireg if_mask;       /* +0x58 */
+    pcireg hop_unused_5C; /* +0x5C */
+    pcireg hop_unused_60; /* +0x60 */
+    pcireg hop_unused_64; /* +0x64 */
+    pcireg hop_unused_68; /* +0x68 */
+    pcireg hop_unused_6C; /* +0x6C */
+    pcireg hop_unused_70; /* +0x70 */
+
+    struct pci_block_copy pci_bc[2] __attribute__((aligned(64)));
+
+    pcireg error_hdr1; /* +0xE0 */
+    pcireg error_hdr2; /* +0xE4 */
+
+    pcireg config[config_maxregs] __attribute__((aligned(256)));
+
+};
+
+#define BPCI_CFGADDR_BUSNUM_SHF 16
+#define BPCI_CFGADDR_FUNCTNUM_SHF 8
+#define BPCI_CFGADDR_REGNUM_SHF 2
+#define BPCI_CFGADDR_ENABLE (1<<31)
+
+#define BPCI_IFCONTROL_RTO (1<<20) /* Retry timeout */
+#define BPCI_IFCONTROL_HCE (1<<16) /* Host configuration enable */
+#define BPCI_IFCONTROL_CTO_SHF 12  /* Shift count for CTO bits */
+#define BPCI_IFCONTROL_SE  (1<<5)  /* Enable exceptions on errors */
+#define BPCI_IFCONTROL_BIST (1<<4) /* Use BIST in per. mode */
+#define BPCI_IFCONTROL_CAP (1<<3)  /* Enable capabilities */
+#define BPCI_IFCONTROL_MMC_SHF 0   /* Shift count for MMC bits */
+
+#define BPCI_IFSTATUS_MGT  (1<<8)  /* Master Grant timeout */
+#define BPCI_IFSTATUS_MTT  (1<<9)  /* Master TRDY timeout */
+#define BPCI_IFSTATUS_MRT  (1<<10) /* Master retry timeout */
+#define BPCI_IFSTATUS_BC0F (1<<13) /* Block copy 0 fault */
+#define BPCI_IFSTATUS_BC1F (1<<14) /* Block copy 1 fault */
+#define BPCI_IFSTATUS_PCIU (1<<15) /* PCI unable to respond */
+#define BPCI_IFSTATUS_BSIZ (1<<16) /* PCI access with illegal size */
+#define BPCI_IFSTATUS_BADD (1<<17) /* PCI access with illegal addr */
+#define BPCI_IFSTATUS_RTO  (1<<18) /* Retry time out */
+#define BPCI_IFSTATUS_SER  (1<<19) /* System error */
+#define BPCI_IFSTATUS_PER  (1<<20) /* Parity error */
+#define BPCI_IFSTATUS_LCA  (1<<21) /* Local CPU abort */
+#define BPCI_IFSTATUS_MEM  (1<<22) /* Memory prot. violation */
+#define BPCI_IFSTATUS_ARB  (1<<23) /* Arbiter timed out */
+#define BPCI_IFSTATUS_STA  (1<<27) /* Signaled target abort */
+#define BPCI_IFSTATUS_TA   (1<<28) /* Target abort */
+#define BPCI_IFSTATUS_MA   (1<<29) /* Master abort */
+#define BPCI_IFSTATUS_PEI  (1<<30) /* Parity error as initiator */
+#define BPCI_IFSTATUS_PET  (1<<31) /* Parity error as target */
+
+#define BPCI_RESETCTL_PR (1<<0)    /* True if reset asserted */
+#define BPCI_RESETCTL_RT (1<<4)    /* Release time */
+#define BPCI_RESETCTL_CT (1<<8)    /* Config time */
+#define BPCI_RESETCTL_PE (1<<12)   /* PCI enabled */
+#define BPCI_RESETCTL_HM (1<<13)   /* PCI host mode */
+#define BPCI_RESETCTL_RI (1<<14)   /* PCI reset in */
+
+extern struct msp_pci_regs msp_pci_regs
+                       __attribute__((section(".register")));
+extern unsigned long msp_pci_config_space
+                       __attribute__((section(".register")));
+
+#endif /* !_MSP_PCI_H_ */
diff --git a/include/asm-mips/pmc-sierra/msp71xx/msp_prom.h b/include/asm-mips/pmc-sierra/msp71xx/msp_prom.h
new file mode 100644 (file)
index 0000000..14ca7dc
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * MIPS boards bootprom interface for the Linux kernel.
+ *
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ * Author: Carsten Langgaard, carstenl@mips.com
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You 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_MSP_PROM_H
+#define _ASM_MSP_PROM_H
+
+#include <linux/types.h>
+
+#define DEVICEID                       "deviceid"
+#define FEATURES                       "features"
+#define PROM_ENV                       "prom_env"
+#define PROM_ENV_FILE                  "/proc/"PROM_ENV
+#define PROM_ENV_SIZE                  256
+
+#define CPU_DEVID_FAMILY               0x0000ff00
+#define CPU_DEVID_REVISION             0x000000ff
+
+#define FPGA_IS_POLO(revision) \
+               (((revision >= 0xb0) && (revision < 0xd0)))
+#define FPGA_IS_5000(revision) \
+               ((revision >= 0x80) && (revision <= 0x90))
+#define        FPGA_IS_ZEUS(revision)          ((revision < 0x7f))
+#define FPGA_IS_DUET(revision) \
+               (((revision >= 0xa0) && (revision < 0xb0)))
+#define FPGA_IS_MSP4200(revision)      ((revision >= 0xd0))
+#define FPGA_IS_MSP7100(revision)      ((revision >= 0xd0))
+
+#define MACHINE_TYPE_POLO              "POLO"
+#define MACHINE_TYPE_DUET              "DUET"
+#define        MACHINE_TYPE_ZEUS               "ZEUS"
+#define MACHINE_TYPE_MSP2000REVB       "MSP2000REVB"
+#define MACHINE_TYPE_MSP5000           "MSP5000"
+#define MACHINE_TYPE_MSP4200           "MSP4200"
+#define MACHINE_TYPE_MSP7120           "MSP7120"
+#define MACHINE_TYPE_MSP7130           "MSP7130"
+#define MACHINE_TYPE_OTHER             "OTHER"
+
+#define MACHINE_TYPE_POLO_FPGA         "POLO-FPGA"
+#define MACHINE_TYPE_DUET_FPGA         "DUET-FPGA"
+#define        MACHINE_TYPE_ZEUS_FPGA          "ZEUS_FPGA"
+#define MACHINE_TYPE_MSP2000REVB_FPGA  "MSP2000REVB-FPGA"
+#define MACHINE_TYPE_MSP5000_FPGA      "MSP5000-FPGA"
+#define MACHINE_TYPE_MSP4200_FPGA      "MSP4200-FPGA"
+#define MACHINE_TYPE_MSP7100_FPGA      "MSP7100-FPGA"
+#define MACHINE_TYPE_OTHER_FPGA                "OTHER-FPGA"
+
+/* Device Family definitions */
+#define FAMILY_FPGA                    0x0000
+#define FAMILY_ZEUS                    0x1000
+#define FAMILY_POLO                    0x2000
+#define FAMILY_DUET                    0x4000
+#define FAMILY_TRIAD                   0x5000
+#define FAMILY_MSP4200                 0x4200
+#define FAMILY_MSP4200_FPGA            0x4f00
+#define FAMILY_MSP7100                 0x7100
+#define FAMILY_MSP7100_FPGA            0x7f00
+
+/* Device Type definitions */
+#define TYPE_MSP7120                   0x7120
+#define TYPE_MSP7130                   0x7130
+
+#define ENET_KEY               'E'
+#define ENETTXD_KEY            'e'
+#define PCI_KEY                        'P'
+#define PCIMUX_KEY             'p'
+#define SEC_KEY                        'S'
+#define SPAD_KEY               'D'
+#define TDM_KEY                        'T'
+#define ZSP_KEY                        'Z'
+
+#define FEATURE_NOEXIST                '-'
+#define FEATURE_EXIST          '+'
+
+#define ENET_MII               'M'
+#define ENET_RMII              'R'
+
+#define        ENETTXD_FALLING         'F'
+#define ENETTXD_RISING         'R'
+
+#define PCI_HOST               'H'
+#define PCI_PERIPHERAL         'P'
+
+#define PCIMUX_FULL            'F'
+#define PCIMUX_SINGLE          'S'
+
+#define SEC_DUET               'D'
+#define SEC_POLO               'P'
+#define SEC_SLOW               'S'
+#define SEC_TRIAD              'T'
+
+#define SPAD_POLO              'P'
+
+#define TDM_DUET               'D'     /* DUET TDMs might exist */
+#define TDM_POLO               'P'     /* POLO TDMs might exist */
+#define TDM_TRIAD              'T'     /* TRIAD TDMs might exist */
+
+#define ZSP_DUET               'D'     /* one DUET zsp engine */
+#define ZSP_TRIAD              'T'     /* two TRIAD zsp engines */
+
+extern char *prom_getcmdline(void);
+extern char *prom_getenv(char *name);
+extern void prom_init_cmdline(void);
+extern void prom_meminit(void);
+extern void prom_fixup_mem_map(unsigned long start_mem,
+                              unsigned long end_mem);
+
+#ifdef CONFIG_MTD_PMC_MSP_RAMROOT
+extern bool get_ramroot(void **start, unsigned long *size);
+#endif
+
+extern int get_ethernet_addr(char *ethaddr_name, char *ethernet_addr);
+extern unsigned long get_deviceid(void);
+extern char identify_enet(unsigned long interface_num);
+extern char identify_enetTxD(unsigned long interface_num);
+extern char identify_pci(void);
+extern char identify_sec(void);
+extern char identify_spad(void);
+extern char identify_sec(void);
+extern char identify_tdm(void);
+extern char identify_zsp(void);
+extern unsigned long identify_family(void);
+extern unsigned long identify_revision(void);
+
+/*
+ * The following macro calls prom_printf and puts the format string
+ * into an init section so it can be reclaimed.
+ */
+#define ppfinit(f, x...) \
+       do { \
+               static char _f[] __initdata = KERN_INFO f; \
+               printk(_f, ## x); \
+       } while (0)
+
+/* Memory descriptor management. */
+#define PROM_MAX_PMEMBLOCKS    7       /* 6 used */
+
+enum yamon_memtypes {
+       yamon_dontuse,
+       yamon_prom,
+       yamon_free,
+};
+
+struct prom_pmemblock {
+       unsigned long base; /* Within KSEG0. */
+       unsigned int size;  /* In bytes. */
+       unsigned int type;  /* free or prom memory */
+};
+
+extern int prom_argc;
+extern char **prom_argv;
+extern char **prom_envp;
+extern int *prom_vec;
+extern struct prom_pmemblock *prom_getmdesc(void);
+
+#endif /* !_ASM_MSP_PROM_H */
diff --git a/include/asm-mips/pmc-sierra/msp71xx/msp_regops.h b/include/asm-mips/pmc-sierra/msp71xx/msp_regops.h
new file mode 100644 (file)
index 0000000..60a5a38
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+ * SMP/VPE-safe functions to access "registers" (see note).
+ *
+ * NOTES:
+* - These macros use ll/sc instructions, so it is your responsibility to
+ * ensure these are available on your platform before including this file.
+ * - The MIPS32 spec states that ll/sc results are undefined for uncached
+ * accesses. This means they can't be used on HW registers accessed
+ * through kseg1. Code which requires these macros for this purpose must
+ * front-end the registers with cached memory "registers" and have a single
+ * thread update the actual HW registers.
+ * - A maximum of 2k of code can be inserted between ll and sc. Every
+ * memory accesses between the instructions will increase the chance of
+ * sc failing and having to loop.
+ * - When using custom_read_reg32/custom_write_reg32 only perform the
+ * necessary logical operations on the register value in between these
+ * two calls. All other logic should be performed before the first call.
+  * - There is a bug on the R10000 chips which has a workaround. If you
+ * are affected by this bug, make sure to define the symbol 'R10000_LLSC_WAR'
+ * to be non-zero.  If you are using this header from within linux, you may
+ * include <asm/war.h> before including this file to have this defined
+ * appropriately for you.
+ *
+ * Copyright 2005-2007 PMC-Sierra, Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+ *  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF USE,
+ *  DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc., 675
+ *  Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __ASM_REGOPS_H__
+#define __ASM_REGOPS_H__
+
+#include <linux/types.h>
+
+#include <asm/war.h>
+
+#ifndef R10000_LLSC_WAR
+#define R10000_LLSC_WAR 0
+#endif
+
+#if R10000_LLSC_WAR == 1
+#define __beqz "beqzl  "
+#else
+#define __beqz "beqz   "
+#endif
+
+#ifndef _LINUX_TYPES_H
+typedef unsigned int u32;
+#endif
+
+/*
+ * Sets all the masked bits to the corresponding value bits
+ */
+static inline void set_value_reg32(volatile u32 *const addr,
+                                       u32 const mask,
+                                       u32 const value)
+{
+       u32 temp;
+
+       __asm__ __volatile__(
+       "       .set    push                            \n"
+       "       .set    mips3                           \n"
+       "1:     ll      %0, %1  # set_value_reg32       \n"
+       "       and     %0, %2                          \n"
+       "       or      %0, %3                          \n"
+       "       sc      %0, %1                          \n"
+       "       "__beqz"%0, 1b                          \n"
+       "       nop                                     \n"
+       "       .set    pop                             \n"
+       : "=&r" (temp), "=m" (*addr)
+       : "ir" (~mask), "ir" (value), "m" (*addr));
+}
+
+/*
+ * Sets all the masked bits to '1'
+ */
+static inline void set_reg32(volatile u32 *const addr,
+                               u32 const mask)
+{
+       u32 temp;
+
+       __asm__ __volatile__(
+       "       .set    push                            \n"
+       "       .set    mips3                           \n"
+       "1:     ll      %0, %1          # set_reg32     \n"
+       "       or      %0, %2                          \n"
+       "       sc      %0, %1                          \n"
+       "       "__beqz"%0, 1b                          \n"
+       "       nop                                     \n"
+       "       .set    pop                             \n"
+       : "=&r" (temp), "=m" (*addr)
+       : "ir" (mask), "m" (*addr));
+}
+
+/*
+ * Sets all the masked bits to '0'
+ */
+static inline void clear_reg32(volatile u32 *const addr,
+                               u32 const mask)
+{
+       u32 temp;
+
+       __asm__ __volatile__(
+       "       .set    push                            \n"
+       "       .set    mips3                           \n"
+       "1:     ll      %0, %1          # clear_reg32   \n"
+       "       and     %0, %2                          \n"
+       "       sc      %0, %1                          \n"
+       "       "__beqz"%0, 1b                          \n"
+       "       nop                                     \n"
+       "       .set    pop                             \n"
+       : "=&r" (temp), "=m" (*addr)
+       : "ir" (~mask), "m" (*addr));
+}
+
+/*
+ * Toggles all masked bits from '0' to '1' and '1' to '0'
+ */
+static inline void toggle_reg32(volatile u32 *const addr,
+                               u32 const mask)
+{
+       u32 temp;
+
+       __asm__ __volatile__(
+       "       .set    push                            \n"
+       "       .set    mips3                           \n"
+       "1:     ll      %0, %1          # toggle_reg32  \n"
+       "       xor     %0, %2                          \n"
+       "       sc      %0, %1                          \n"
+       "       "__beqz"%0, 1b                          \n"
+       "       nop                                     \n"
+       "       .set    pop                             \n"
+       : "=&r" (temp), "=m" (*addr)
+       : "ir" (mask), "m" (*addr));
+}
+
+/*
+ * Read all masked bits others are returned as '0'
+ */
+static inline u32 read_reg32(volatile u32 *const addr,
+                               u32 const mask)
+{
+       u32 temp;
+
+       __asm__ __volatile__(
+       "       .set    push                            \n"
+       "       .set    noreorder                       \n"
+       "       lw      %0, %1          # read          \n"
+       "       and     %0, %2          # mask          \n"
+       "       .set    pop                             \n"
+       : "=&r" (temp)
+       : "m" (*addr), "ir" (mask));
+
+       return temp;
+}
+
+/*
+ * blocking_read_reg32 - Read address with blocking load
+ *
+ * Uncached writes need to be read back to ensure they reach RAM.
+ * The returned value must be 'used' to prevent from becoming a
+ * non-blocking load.
+ */
+static inline u32 blocking_read_reg32(volatile u32 *const addr)
+{
+       u32 temp;
+
+       __asm__ __volatile__(
+       "       .set    push                            \n"
+       "       .set    noreorder                       \n"
+       "       lw      %0, %1          # read          \n"
+       "       move    %0, %0          # block         \n"
+       "       .set    pop                             \n"
+       : "=&r" (temp)
+       : "m" (*addr));
+
+       return temp;
+}
+
+/*
+ * For special strange cases only:
+ *
+ * If you need custom processing within a ll/sc loop, use the following macros
+ * VERY CAREFULLY:
+ *
+ *   u32 tmp;                          <-- Define a variable to hold the data
+ *
+ *   custom_read_reg32(address, tmp);  <-- Reads the address and put the value
+ *                                             in the 'tmp' variable given
+ *
+ *     From here on out, you are (basicly) atomic, so don't do anything too
+ *     fancy!
+ *     Also, this code may loop if the end of this block fails to write
+ *     everything back safely due do the other CPU, so do NOT do anything
+ *     with side-effects!
+ *
+ *   custom_write_reg32(address, tmp); <-- Writes back 'tmp' safely.
+ */
+#define custom_read_reg32(address, tmp)                                \
+       __asm__ __volatile__(                                   \
+       "       .set    push                            \n"     \
+       "       .set    mips3                           \n"     \
+       "1:     ll      %0, %1  #custom_read_reg32      \n"     \
+       "       .set    pop                             \n"     \
+       : "=r" (tmp), "=m" (*address)                           \
+       : "m" (*address))
+
+#define custom_write_reg32(address, tmp)                       \
+       __asm__ __volatile__(                                   \
+       "       .set    push                            \n"     \
+       "       .set    mips3                           \n"     \
+       "       sc      %0, %1  #custom_write_reg32     \n"     \
+       "       "__beqz"%0, 1b                          \n"     \
+       "       nop                                     \n"     \
+       "       .set    pop                             \n"     \
+       : "=&r" (tmp), "=m" (*address)                          \
+       : "0" (tmp), "m" (*address))
+
+#endif  /* __ASM_REGOPS_H__ */
diff --git a/include/asm-mips/pmc-sierra/msp71xx/msp_regs.h b/include/asm-mips/pmc-sierra/msp71xx/msp_regs.h
new file mode 100644 (file)
index 0000000..0b56f55
--- /dev/null
@@ -0,0 +1,667 @@
+/*
+ * Defines for the address space, registers and register configuration
+ * (bit masks, access macros etc) for the PMC-Sierra line of MSP products.
+ * This file contains addess maps for all the devices in the line of
+ * products but only has register definitions and configuration masks for
+ * registers which aren't definitely associated with any device.  Things
+ * like clock settings, reset access, the ELB etc.  Individual device
+ * drivers will reference the appropriate XXX_BASE value defined here
+ * and have individual registers offset from that.
+ *
+ * Copyright (C) 2005-2007 PMC-Sierra, Inc.  All rights reserved.
+ * Author: Andrew Hughes, Andrew_Hughes@pmc-sierra.com
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You 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/addrspace.h>
+#include <linux/types.h>
+
+#ifndef _ASM_MSP_REGS_H
+#define _ASM_MSP_REGS_H
+
+/*
+ ########################################################################
+ #  Address space and device base definitions                           #
+ ########################################################################
+ */
+
+/*
+ ***************************************************************************
+ * System Logic and Peripherals (ELB, UART0, etc) device address space     *
+ ***************************************************************************
+ */
+#define MSP_SLP_BASE           0x1c000000
+                                       /* System Logic and Peripherals */
+#define MSP_RST_BASE           (MSP_SLP_BASE + 0x10)
+                                       /* System reset register base   */
+#define MSP_RST_SIZE           0x0C    /* System reset register space  */
+
+#define MSP_WTIMER_BASE                (MSP_SLP_BASE + 0x04C)
+                                       /* watchdog timer base          */
+#define MSP_ITIMER_BASE                (MSP_SLP_BASE + 0x054)
+                                       /* internal timer base          */
+#define MSP_UART0_BASE         (MSP_SLP_BASE + 0x100)
+                                       /* UART0 controller base        */
+#define MSP_BCPY_CTRL_BASE     (MSP_SLP_BASE + 0x120)
+                                       /* Block Copy controller base   */
+#define MSP_BCPY_DESC_BASE     (MSP_SLP_BASE + 0x160)
+                                       /* Block Copy descriptor base   */
+
+/*
+ ***************************************************************************
+ * PCI address space                                                       *
+ ***************************************************************************
+ */
+#define MSP_PCI_BASE           0x19000000
+
+/*
+ ***************************************************************************
+ * MSbus device address space                                              *
+ ***************************************************************************
+ */
+#define MSP_MSB_BASE           0x18000000
+                                       /* MSbus address start          */
+#define MSP_PER_BASE           (MSP_MSB_BASE + 0x400000)
+                                       /* Peripheral device registers  */
+#define MSP_MAC0_BASE          (MSP_MSB_BASE + 0x600000)
+                                       /* MAC A device registers       */
+#define MSP_MAC1_BASE          (MSP_MSB_BASE + 0x700000)
+                                       /* MAC B device registers       */
+#define MSP_MAC_SIZE           0xE0    /* MAC register space           */
+
+#define MSP_SEC_BASE           (MSP_MSB_BASE + 0x800000)
+                                       /* Security Engine registers    */
+#define MSP_MAC2_BASE          (MSP_MSB_BASE + 0x900000)
+                                       /* MAC C device registers       */
+#define MSP_ADSL2_BASE         (MSP_MSB_BASE + 0xA80000)
+                                       /* ADSL2 device registers       */
+#define MSP_USB_BASE           (MSP_MSB_BASE + 0xB40000)
+                                       /* USB device registers         */
+#define MSP_USB_BASE_START     (MSP_MSB_BASE + 0xB40100)
+                                       /* USB device registers         */
+#define MSP_USB_BASE_END       (MSP_MSB_BASE + 0xB401FF)
+                                       /* USB device registers         */
+#define MSP_CPUIF_BASE         (MSP_MSB_BASE + 0xC00000)
+                                       /* CPU interface registers      */
+
+/* Devices within the MSbus peripheral block */
+#define MSP_UART1_BASE         (MSP_PER_BASE + 0x030)
+                                       /* UART1 controller base        */
+#define MSP_SPI_BASE           (MSP_PER_BASE + 0x058)
+                                       /* SPI/MPI control registers    */
+#define MSP_TWI_BASE           (MSP_PER_BASE + 0x090)
+                                       /* Two-wire control registers   */
+#define MSP_PTIMER_BASE                (MSP_PER_BASE + 0x0F0)
+                                       /* Programmable timer control   */
+
+/*
+ ***************************************************************************
+ * Physical Memory configuration address space                             *
+ ***************************************************************************
+ */
+#define MSP_MEM_CFG_BASE       0x17f00000
+
+#define MSP_MEM_INDIRECT_CTL_10        0x10
+
+/*
+ * Notes:
+ *  1) The SPI registers are split into two blocks, one offset from the
+ *     MSP_SPI_BASE by 0x00 and the other offset from the MSP_SPI_BASE by
+ *     0x68.  The SPI driver definitions for the register must be aware
+ *     of this.
+ *  2) The block copy engine register are divided into two regions, one
+ *     for the control/configuration of the engine proper and one for the
+ *     values of the descriptors used in the copy process.  These have
+ *     different base defines (CTRL_BASE vs DESC_BASE)
+ *  3) These constants are for physical addresses which means that they
+ *     work correctly with "ioremap" and friends.  This means that device
+ *     drivers will need to remap these addresses using ioremap and perhaps
+ *     the readw/writew macros.  Or they could use the regptr() macro
+ *     defined below, but the readw/writew calls are the correct thing.
+ *  4) The UARTs have an additional status register offset from the base
+ *     address.  This register isn't used in the standard 8250 driver but
+ *     may be used in other software.  Consult the hardware datasheet for
+ *     offset details.
+ *  5) For some unknown reason the security engine (MSP_SEC_BASE) registers
+ *     start at an offset of 0x84 from the base address but the block of
+ *     registers before this is reserved for the security engine.  The
+ *     driver will have to be aware of this but it makes the register
+ *     definitions line up better with the documentation.
+ */
+
+/*
+ ########################################################################
+ #  System register definitions.  Not associated with a specific device #
+ ########################################################################
+ */
+
+/*
+ * This macro maps the physical register number into uncached space
+ * and (for C code) casts it into a u32 pointer so it can be dereferenced
+ * Normally these would be accessed with ioremap and readX/writeX, but
+ * these are convenient for a lot of internal kernel code.
+ */
+#ifdef __ASSEMBLER__
+       #define regptr(addr) (KSEG1ADDR(addr))
+#else
+       #define regptr(addr) ((volatile u32 *const)(KSEG1ADDR(addr)))
+#endif
+
+/*
+ ***************************************************************************
+ * System Logic and Peripherals (RESET, ELB, etc) registers                *
+ ***************************************************************************
+ */
+
+/* System Control register definitions */
+#define        DEV_ID_REG      regptr(MSP_SLP_BASE + 0x00)
+                                       /* Device-ID                 RO */
+#define        FWR_ID_REG      regptr(MSP_SLP_BASE + 0x04)
+                                       /* Firmware-ID Register      RW */
+#define        SYS_ID_REG0     regptr(MSP_SLP_BASE + 0x08)
+                                       /* System-ID Register-0      RW */
+#define        SYS_ID_REG1     regptr(MSP_SLP_BASE + 0x0C)
+                                       /* System-ID Register-1      RW */
+
+/* System Reset register definitions */
+#define        RST_STS_REG     regptr(MSP_SLP_BASE + 0x10)
+                                       /* System Reset Status       RO */
+#define        RST_SET_REG     regptr(MSP_SLP_BASE + 0x14)
+                                       /* System Set Reset          WO */
+#define        RST_CLR_REG     regptr(MSP_SLP_BASE + 0x18)
+                                       /* System Clear Reset        WO */
+
+/* System Clock Registers */
+#define PCI_SLP_REG    regptr(MSP_SLP_BASE + 0x1C)
+                                       /* PCI clock generator       RW */
+#define URT_SLP_REG    regptr(MSP_SLP_BASE + 0x20)
+                                       /* UART clock generator      RW */
+/* reserved                  (MSP_SLP_BASE + 0x24)                     */
+/* reserved                  (MSP_SLP_BASE + 0x28)                     */
+#define PLL1_SLP_REG   regptr(MSP_SLP_BASE + 0x2C)
+                                       /* PLL1 clock generator      RW */
+#define PLL0_SLP_REG   regptr(MSP_SLP_BASE + 0x30)
+                                       /* PLL0 clock generator      RW */
+#define MIPS_SLP_REG   regptr(MSP_SLP_BASE + 0x34)
+                                       /* MIPS clock generator      RW */
+#define        VE_SLP_REG      regptr(MSP_SLP_BASE + 0x38)
+                                       /* Voice Eng clock generator RW */
+/* reserved                  (MSP_SLP_BASE + 0x3C)                     */
+#define MSB_SLP_REG    regptr(MSP_SLP_BASE + 0x40)
+                                       /* MS-Bus clock generator    RW */
+#define SMAC_SLP_REG   regptr(MSP_SLP_BASE + 0x44)
+                                       /* Sec & MAC clock generator RW */
+#define PERF_SLP_REG   regptr(MSP_SLP_BASE + 0x48)
+                                       /* Per & TDM clock generator RW */
+
+/* Interrupt Controller Registers */
+#define SLP_INT_STS_REG regptr(MSP_SLP_BASE + 0x70)
+                                       /* Interrupt status register RW */
+#define SLP_INT_MSK_REG regptr(MSP_SLP_BASE + 0x74)
+                                       /* Interrupt enable/mask     RW */
+#define SE_MBOX_REG    regptr(MSP_SLP_BASE + 0x78)
+                                       /* Security Engine mailbox   RW */
+#define VE_MBOX_REG    regptr(MSP_SLP_BASE + 0x7C)
+                                       /* Voice Engine mailbox      RW */
+
+/* ELB Controller Registers */
+#define CS0_CNFG_REG   regptr(MSP_SLP_BASE + 0x80)
+                                       /* ELB CS0 Configuration Reg    */
+#define CS0_ADDR_REG   regptr(MSP_SLP_BASE + 0x84)
+                                       /* ELB CS0 Base Address Reg     */
+#define CS0_MASK_REG   regptr(MSP_SLP_BASE + 0x88)
+                                       /* ELB CS0 Mask Register        */
+#define CS0_ACCESS_REG regptr(MSP_SLP_BASE + 0x8C)
+                                       /* ELB CS0 access register      */
+
+#define CS1_CNFG_REG   regptr(MSP_SLP_BASE + 0x90)
+                                       /* ELB CS1 Configuration Reg    */
+#define CS1_ADDR_REG   regptr(MSP_SLP_BASE + 0x94)
+                                       /* ELB CS1 Base Address Reg     */
+#define CS1_MASK_REG   regptr(MSP_SLP_BASE + 0x98)
+                                       /* ELB CS1 Mask Register        */
+#define CS1_ACCESS_REG regptr(MSP_SLP_BASE + 0x9C)
+                                       /* ELB CS1 access register      */
+
+#define CS2_CNFG_REG   regptr(MSP_SLP_BASE + 0xA0)
+                                       /* ELB CS2 Configuration Reg    */
+#define CS2_ADDR_REG   regptr(MSP_SLP_BASE + 0xA4)
+                                       /* ELB CS2 Base Address Reg     */
+#define CS2_MASK_REG   regptr(MSP_SLP_BASE + 0xA8)
+                                       /* ELB CS2 Mask Register        */
+#define CS2_ACCESS_REG regptr(MSP_SLP_BASE + 0xAC)
+                                       /* ELB CS2 access register      */
+
+#define CS3_CNFG_REG   regptr(MSP_SLP_BASE + 0xB0)
+                                       /* ELB CS3 Configuration Reg    */
+#define CS3_ADDR_REG   regptr(MSP_SLP_BASE + 0xB4)
+                                       /* ELB CS3 Base Address Reg     */
+#define CS3_MASK_REG   regptr(MSP_SLP_BASE + 0xB8)
+                                       /* ELB CS3 Mask Register        */
+#define CS3_ACCESS_REG regptr(MSP_SLP_BASE + 0xBC)
+                                       /* ELB CS3 access register      */
+
+#define CS4_CNFG_REG   regptr(MSP_SLP_BASE + 0xC0)
+                                       /* ELB CS4 Configuration Reg    */
+#define CS4_ADDR_REG   regptr(MSP_SLP_BASE + 0xC4)
+                                       /* ELB CS4 Base Address Reg     */
+#define CS4_MASK_REG   regptr(MSP_SLP_BASE + 0xC8)
+                                       /* ELB CS4 Mask Register        */
+#define CS4_ACCESS_REG regptr(MSP_SLP_BASE + 0xCC)
+                                       /* ELB CS4 access register      */
+
+#define CS5_CNFG_REG   regptr(MSP_SLP_BASE + 0xD0)
+                                       /* ELB CS5 Configuration Reg    */
+#define CS5_ADDR_REG   regptr(MSP_SLP_BASE + 0xD4)
+                                       /* ELB CS5 Base Address Reg     */
+#define CS5_MASK_REG   regptr(MSP_SLP_BASE + 0xD8)
+                                       /* ELB CS5 Mask Register        */
+#define CS5_ACCESS_REG regptr(MSP_SLP_BASE + 0xDC)
+                                       /* ELB CS5 access register      */
+
+/* reserved                           0xE0 - 0xE8                      */
+#define ELB_1PC_EN_REG regptr(MSP_SLP_BASE + 0xEC)
+                                       /* ELB single PC card detect    */
+
+/* reserved                           0xF0 - 0xF8                      */
+#define ELB_CLK_CFG_REG        regptr(MSP_SLP_BASE + 0xFC)
+                                       /* SDRAM read/ELB timing Reg    */
+
+/* Extended UART status registers */
+#define UART0_STATUS_REG       regptr(MSP_UART0_BASE + 0x0c0)
+                                       /* UART Status Register 0       */
+#define UART1_STATUS_REG       regptr(MSP_UART1_BASE + 0x170)
+                                       /* UART Status Register 1       */
+
+/* Performance monitoring registers */
+#define PERF_MON_CTRL_REG      regptr(MSP_SLP_BASE + 0x140)
+                                       /* Performance monitor control  */
+#define PERF_MON_CLR_REG       regptr(MSP_SLP_BASE + 0x144)
+                                       /* Performance monitor clear    */
+#define PERF_MON_CNTH_REG      regptr(MSP_SLP_BASE + 0x148)
+                                       /* Perf monitor counter high    */
+#define PERF_MON_CNTL_REG      regptr(MSP_SLP_BASE + 0x14C)
+                                       /* Perf monitor counter low     */
+
+/* System control registers */
+#define SYS_CTRL_REG           regptr(MSP_SLP_BASE + 0x150)
+                                       /* System control register      */
+#define SYS_ERR1_REG           regptr(MSP_SLP_BASE + 0x154)
+                                       /* System Error status 1        */
+#define SYS_ERR2_REG           regptr(MSP_SLP_BASE + 0x158)
+                                       /* System Error status 2        */
+#define SYS_INT_CFG_REG                regptr(MSP_SLP_BASE + 0x15C)
+                                       /* System Interrupt config      */
+
+/* Voice Engine Memory configuration */
+#define VE_MEM_REG             regptr(MSP_SLP_BASE + 0x17C)
+                                       /* Voice engine memory config   */
+
+/* CPU/SLP Error Status registers */
+#define CPU_ERR1_REG           regptr(MSP_SLP_BASE + 0x180)
+                                       /* CPU/SLP Error status 1       */
+#define CPU_ERR2_REG           regptr(MSP_SLP_BASE + 0x184)
+                                       /* CPU/SLP Error status 1       */
+
+#define EXTENDED_GPIO_REG      regptr(MSP_SLP_BASE + 0x188)
+                                       /* Extended GPIO register       */
+
+/* System Error registers */
+#define SLP_ERR_STS_REG                regptr(MSP_SLP_BASE + 0x190)
+                                       /* Int status for SLP errors    */
+#define SLP_ERR_MSK_REG                regptr(MSP_SLP_BASE + 0x194)
+                                       /* Int mask for SLP errors      */
+#define SLP_ELB_ERST_REG       regptr(MSP_SLP_BASE + 0x198)
+                                       /* External ELB reset           */
+#define SLP_BOOT_STS_REG       regptr(MSP_SLP_BASE + 0x19C)
+                                       /* Boot Status                  */
+
+/* Extended ELB addressing */
+#define CS0_EXT_ADDR_REG       regptr(MSP_SLP_BASE + 0x1A0)
+                                       /* CS0 Extended address         */
+#define CS1_EXT_ADDR_REG       regptr(MSP_SLP_BASE + 0x1A4)
+                                       /* CS1 Extended address         */
+#define CS2_EXT_ADDR_REG       regptr(MSP_SLP_BASE + 0x1A8)
+                                       /* CS2 Extended address         */
+#define CS3_EXT_ADDR_REG       regptr(MSP_SLP_BASE + 0x1AC)
+                                       /* CS3 Extended address         */
+/* reserved                                          0x1B0             */
+#define CS5_EXT_ADDR_REG       regptr(MSP_SLP_BASE + 0x1B4)
+                                       /* CS5 Extended address         */
+
+/* PLL Adjustment registers */
+#define PLL_LOCK_REG           regptr(MSP_SLP_BASE + 0x200)
+                                       /* PLL0 lock status             */
+#define PLL_ARST_REG           regptr(MSP_SLP_BASE + 0x204)
+                                       /* PLL Analog reset status      */
+#define PLL0_ADJ_REG           regptr(MSP_SLP_BASE + 0x208)
+                                       /* PLL0 Adjustment value        */
+#define PLL1_ADJ_REG           regptr(MSP_SLP_BASE + 0x20C)
+                                       /* PLL1 Adjustment value        */
+
+/*
+ ***************************************************************************
+ * Peripheral Register definitions                                         *
+ ***************************************************************************
+ */
+
+/* Peripheral status */
+#define PER_CTRL_REG           regptr(MSP_PER_BASE + 0x50)
+                                       /* Peripheral control register  */
+#define PER_STS_REG            regptr(MSP_PER_BASE + 0x54)
+                                       /* Peripheral status register   */
+
+/* SPI/MPI Registers */
+#define SMPI_TX_SZ_REG         regptr(MSP_PER_BASE + 0x58)
+                                       /* SPI/MPI Tx Size register     */
+#define SMPI_RX_SZ_REG         regptr(MSP_PER_BASE + 0x5C)
+                                       /* SPI/MPI Rx Size register     */
+#define SMPI_CTL_REG           regptr(MSP_PER_BASE + 0x60)
+                                       /* SPI/MPI Control register     */
+#define SMPI_MS_REG            regptr(MSP_PER_BASE + 0x64)
+                                       /* SPI/MPI Chip Select reg      */
+#define SMPI_CORE_DATA_REG     regptr(MSP_PER_BASE + 0xC0)
+                                       /* SPI/MPI Core Data reg        */
+#define SMPI_CORE_CTRL_REG     regptr(MSP_PER_BASE + 0xC4)
+                                       /* SPI/MPI Core Control reg     */
+#define SMPI_CORE_STAT_REG     regptr(MSP_PER_BASE + 0xC8)
+                                       /* SPI/MPI Core Status reg      */
+#define SMPI_CORE_SSEL_REG     regptr(MSP_PER_BASE + 0xCC)
+                                       /* SPI/MPI Core Ssel reg        */
+#define SMPI_FIFO_REG          regptr(MSP_PER_BASE + 0xD0)
+                                       /* SPI/MPI Data FIFO reg        */
+
+/* Peripheral Block Error Registers           */
+#define PER_ERR_STS_REG                regptr(MSP_PER_BASE + 0x70)
+                                       /* Error Bit Status Register    */
+#define PER_ERR_MSK_REG                regptr(MSP_PER_BASE + 0x74)
+                                       /* Error Bit Mask Register      */
+#define PER_HDR1_REG           regptr(MSP_PER_BASE + 0x78)
+                                       /* Error Header 1 Register      */
+#define PER_HDR2_REG           regptr(MSP_PER_BASE + 0x7C)
+                                       /* Error Header 2 Register      */
+
+/* Peripheral Block Interrupt Registers       */
+#define PER_INT_STS_REG                regptr(MSP_PER_BASE + 0x80)
+                                       /* Interrupt status register    */
+#define PER_INT_MSK_REG                regptr(MSP_PER_BASE + 0x84)
+                                       /* Interrupt Mask Register      */
+#define GPIO_INT_STS_REG       regptr(MSP_PER_BASE + 0x88)
+                                       /* GPIO interrupt status reg    */
+#define GPIO_INT_MSK_REG       regptr(MSP_PER_BASE + 0x8C)
+                                       /* GPIO interrupt MASK Reg      */
+
+/* POLO GPIO registers                        */
+#define POLO_GPIO_DAT1_REG     regptr(MSP_PER_BASE + 0x0E0)
+                                       /* Polo GPIO[8:0]  data reg     */
+#define POLO_GPIO_CFG1_REG     regptr(MSP_PER_BASE + 0x0E4)
+                                       /* Polo GPIO[7:0]  config reg   */
+#define POLO_GPIO_CFG2_REG     regptr(MSP_PER_BASE + 0x0E8)
+                                       /* Polo GPIO[15:8] config reg   */
+#define POLO_GPIO_OD1_REG      regptr(MSP_PER_BASE + 0x0EC)
+                                       /* Polo GPIO[31:0] output drive */
+#define POLO_GPIO_CFG3_REG     regptr(MSP_PER_BASE + 0x170)
+                                       /* Polo GPIO[23:16] config reg  */
+#define POLO_GPIO_DAT2_REG     regptr(MSP_PER_BASE + 0x174)
+                                       /* Polo GPIO[15:9]  data reg    */
+#define POLO_GPIO_DAT3_REG     regptr(MSP_PER_BASE + 0x178)
+                                       /* Polo GPIO[23:16]  data reg   */
+#define POLO_GPIO_DAT4_REG     regptr(MSP_PER_BASE + 0x17C)
+                                       /* Polo GPIO[31:24]  data reg   */
+#define POLO_GPIO_DAT5_REG     regptr(MSP_PER_BASE + 0x180)
+                                       /* Polo GPIO[39:32]  data reg   */
+#define POLO_GPIO_DAT6_REG     regptr(MSP_PER_BASE + 0x184)
+                                       /* Polo GPIO[47:40]  data reg   */
+#define POLO_GPIO_DAT7_REG     regptr(MSP_PER_BASE + 0x188)
+                                       /* Polo GPIO[54:48]  data reg   */
+#define POLO_GPIO_CFG4_REG     regptr(MSP_PER_BASE + 0x18C)
+                                       /* Polo GPIO[31:24] config reg  */
+#define POLO_GPIO_CFG5_REG     regptr(MSP_PER_BASE + 0x190)
+                                       /* Polo GPIO[39:32] config reg  */
+#define POLO_GPIO_CFG6_REG     regptr(MSP_PER_BASE + 0x194)
+                                       /* Polo GPIO[47:40] config reg  */
+#define POLO_GPIO_CFG7_REG     regptr(MSP_PER_BASE + 0x198)
+                                       /* Polo GPIO[54:48] config reg  */
+#define POLO_GPIO_OD2_REG      regptr(MSP_PER_BASE + 0x19C)
+                                       /* Polo GPIO[54:32] output drive */
+
+/* Generic GPIO registers                     */
+#define GPIO_DATA1_REG         regptr(MSP_PER_BASE + 0x170)
+                                       /* GPIO[1:0] data register      */
+#define GPIO_DATA2_REG         regptr(MSP_PER_BASE + 0x174)
+                                       /* GPIO[5:2] data register      */
+#define GPIO_DATA3_REG         regptr(MSP_PER_BASE + 0x178)
+                                       /* GPIO[9:6] data register      */
+#define GPIO_DATA4_REG         regptr(MSP_PER_BASE + 0x17C)
+                                       /* GPIO[15:10] data register    */
+#define GPIO_CFG1_REG          regptr(MSP_PER_BASE + 0x180)
+                                       /* GPIO[1:0] config register    */
+#define GPIO_CFG2_REG          regptr(MSP_PER_BASE + 0x184)
+                                       /* GPIO[5:2] config register    */
+#define GPIO_CFG3_REG          regptr(MSP_PER_BASE + 0x188)
+                                       /* GPIO[9:6] config register    */
+#define GPIO_CFG4_REG          regptr(MSP_PER_BASE + 0x18C)
+                                       /* GPIO[15:10] config register  */
+#define GPIO_OD_REG            regptr(MSP_PER_BASE + 0x190)
+                                       /* GPIO[15:0] output drive      */
+
+/*
+ ***************************************************************************
+ * CPU Interface register definitions                                      *
+ ***************************************************************************
+ */
+#define PCI_FLUSH_REG          regptr(MSP_CPUIF_BASE + 0x00)
+                                       /* PCI-SDRAM queue flush trigger */
+#define OCP_ERR1_REG           regptr(MSP_CPUIF_BASE + 0x04)
+                                       /* OCP Error Attribute 1        */
+#define OCP_ERR2_REG           regptr(MSP_CPUIF_BASE + 0x08)
+                                       /* OCP Error Attribute 2        */
+#define OCP_STS_REG            regptr(MSP_CPUIF_BASE + 0x0C)
+                                       /* OCP Error Status             */
+#define CPUIF_PM_REG           regptr(MSP_CPUIF_BASE + 0x10)
+                                       /* CPU policy configuration     */
+#define CPUIF_CFG_REG          regptr(MSP_CPUIF_BASE + 0x10)
+                                       /* Misc configuration options   */
+
+/* Central Interrupt Controller Registers */
+#define MSP_CIC_BASE           (MSP_CPUIF_BASE + 0x8000)
+                                       /* Central Interrupt registers  */
+#define CIC_EXT_CFG_REG                regptr(MSP_CIC_BASE + 0x00)
+                                       /* External interrupt config    */
+#define CIC_STS_REG            regptr(MSP_CIC_BASE + 0x04)
+                                       /* CIC Interrupt Status         */
+#define CIC_VPE0_MSK_REG       regptr(MSP_CIC_BASE + 0x08)
+                                       /* VPE0 Interrupt Mask          */
+#define CIC_VPE1_MSK_REG       regptr(MSP_CIC_BASE + 0x0C)
+                                       /* VPE1 Interrupt Mask          */
+#define CIC_TC0_MSK_REG                regptr(MSP_CIC_BASE + 0x10)
+                                       /* Thread Context 0 Int Mask    */
+#define CIC_TC1_MSK_REG                regptr(MSP_CIC_BASE + 0x14)
+                                       /* Thread Context 1 Int Mask    */
+#define CIC_TC2_MSK_REG                regptr(MSP_CIC_BASE + 0x18)
+                                       /* Thread Context 2 Int Mask    */
+#define CIC_TC3_MSK_REG                regptr(MSP_CIC_BASE + 0x18)
+                                       /* Thread Context 3 Int Mask    */
+#define CIC_TC4_MSK_REG                regptr(MSP_CIC_BASE + 0x18)
+                                       /* Thread Context 4 Int Mask    */
+#define CIC_PCIMSI_STS_REG     regptr(MSP_CIC_BASE + 0x18)
+#define CIC_PCIMSI_MSK_REG     regptr(MSP_CIC_BASE + 0x18)
+#define CIC_PCIFLSH_REG                regptr(MSP_CIC_BASE + 0x18)
+#define CIC_VPE0_SWINT_REG     regptr(MSP_CIC_BASE + 0x08)
+
+
+/*
+ ***************************************************************************
+ * Memory controller registers                                             *
+ ***************************************************************************
+ */
+#define MEM_CFG1_REG           regptr(MSP_MEM_CFG_BASE + 0x00)
+#define MEM_SS_ADDR            regptr(MSP_MEM_CFG_BASE + 0x00)
+#define MEM_SS_DATA            regptr(MSP_MEM_CFG_BASE + 0x04)
+#define MEM_SS_WRITE           regptr(MSP_MEM_CFG_BASE + 0x08)
+
+/*
+ ***************************************************************************
+ * PCI controller registers                                                *
+ ***************************************************************************
+ */
+#define PCI_BASE_REG           regptr(MSP_PCI_BASE + 0x00)
+#define PCI_CONFIG_SPACE_REG   regptr(MSP_PCI_BASE + 0x800)
+#define PCI_JTAG_DEVID_REG     regptr(MSP_SLP_BASE + 0x13c)
+
+/*
+ ########################################################################
+ #  Register content & macro definitions                                #
+ ########################################################################
+ */
+
+/*
+ ***************************************************************************
+ * DEV_ID defines                                                          *
+ ***************************************************************************
+ */
+#define DEV_ID_PCI_DIS         (1 << 26)       /* Set if PCI disabled */
+#define DEV_ID_PCI_HOST                (1 << 20)       /* Set if PCI host */
+#define DEV_ID_SINGLE_PC       (1 << 19)       /* Set if single PC Card */
+#define DEV_ID_FAMILY          (0xff << 8)     /* family ID code */
+#define POLO_ZEUS_SUB_FAMILY   (0x7  << 16)    /* sub family for Polo/Zeus */
+
+#define MSPFPGA_ID             (0x00  << 8)    /* you are on your own here */
+#define MSP5000_ID             (0x50  << 8)
+#define MSP4F00_ID             (0x4f  << 8)    /* FPGA version of MSP4200 */
+#define MSP4E00_ID             (0x4f  << 8)    /* FPGA version of MSP7120 */
+#define MSP4200_ID             (0x42  << 8)
+#define MSP4000_ID             (0x40  << 8)
+#define MSP2XXX_ID             (0x20  << 8)
+#define MSPZEUS_ID             (0x10  << 8)
+
+#define MSP2004_SUB_ID         (0x0   << 16)
+#define MSP2005_SUB_ID         (0x1   << 16)
+#define MSP2006_SUB_ID         (0x1   << 16)
+#define MSP2007_SUB_ID         (0x2   << 16)
+#define MSP2010_SUB_ID         (0x3   << 16)
+#define MSP2015_SUB_ID         (0x4   << 16)
+#define MSP2020_SUB_ID         (0x5   << 16)
+#define MSP2100_SUB_ID         (0x6   << 16)
+
+/*
+ ***************************************************************************
+ * RESET defines                                                           *
+ ***************************************************************************
+ */
+#define MSP_GR_RST             (0x01 << 0)     /* Global reset bit     */
+#define MSP_MR_RST             (0x01 << 1)     /* MIPS reset bit       */
+#define MSP_PD_RST             (0x01 << 2)     /* PVC DMA reset bit    */
+#define MSP_PP_RST             (0x01 << 3)     /* PVC reset bit        */
+/* reserved                                                             */
+#define MSP_EA_RST             (0x01 << 6)     /* Mac A reset bit      */
+#define MSP_EB_RST             (0x01 << 7)     /* Mac B reset bit      */
+#define MSP_SE_RST             (0x01 << 8)     /* Security Eng reset bit */
+#define MSP_PB_RST             (0x01 << 9)     /* Per block reset bit  */
+#define MSP_EC_RST             (0x01 << 10)    /* Mac C reset bit      */
+#define MSP_TW_RST             (0x01 << 11)    /* TWI reset bit        */
+#define MSP_SPI_RST            (0x01 << 12)    /* SPI/MPI reset bit    */
+#define MSP_U1_RST             (0x01 << 13)    /* UART1 reset bit      */
+#define MSP_U0_RST             (0x01 << 14)    /* UART0 reset bit      */
+
+/*
+ ***************************************************************************
+ * UART defines                                                            *
+ ***************************************************************************
+ */
+#ifndef CONFIG_MSP_FPGA
+#define MSP_BASE_BAUD          25000000
+#else
+#define MSP_BASE_BAUD          6000000
+#endif
+#define MSP_UART_REG_LEN       0x20
+
+/*
+ ***************************************************************************
+ * ELB defines                                                             *
+ ***************************************************************************
+ */
+#define PCCARD_32              0x02    /* Set if is PCCARD 32 (Cardbus) */
+#define SINGLE_PCCARD          0x01    /* Set to enable single PC card */
+
+/*
+ ***************************************************************************
+ * CIC defines                                                             *
+ ***************************************************************************
+ */
+
+/* CIC_EXT_CFG_REG */
+#define EXT_INT_POL(eirq)                      (1 << (eirq + 8))
+#define EXT_INT_EDGE(eirq)                     (1 << eirq)
+
+#define CIC_EXT_SET_TRIGGER_LEVEL(reg, eirq)   (reg &= ~EXT_INT_EDGE(eirq))
+#define CIC_EXT_SET_TRIGGER_EDGE(reg, eirq)    (reg |= EXT_INT_EDGE(eirq))
+#define CIC_EXT_SET_ACTIVE_HI(reg, eirq)       (reg |= EXT_INT_POL(eirq))
+#define CIC_EXT_SET_ACTIVE_LO(reg, eirq)       (reg &= ~EXT_INT_POL(eirq))
+#define CIC_EXT_SET_ACTIVE_RISING              CIC_EXT_SET_ACTIVE_HI
+#define CIC_EXT_SET_ACTIVE_FALLING             CIC_EXT_SET_ACTIVE_LO
+
+#define CIC_EXT_IS_TRIGGER_LEVEL(reg, eirq) \
+                               ((reg & EXT_INT_EDGE(eirq)) == 0)
+#define CIC_EXT_IS_TRIGGER_EDGE(reg, eirq)     (reg & EXT_INT_EDGE(eirq))
+#define CIC_EXT_IS_ACTIVE_HI(reg, eirq)                (reg & EXT_INT_POL(eirq))
+#define CIC_EXT_IS_ACTIVE_LO(reg, eirq) \
+                               ((reg & EXT_INT_POL(eirq)) == 0)
+#define CIC_EXT_IS_ACTIVE_RISING               CIC_EXT_IS_ACTIVE_HI
+#define CIC_EXT_IS_ACTIVE_FALLING              CIC_EXT_IS_ACTIVE_LO
+
+/*
+ ***************************************************************************
+ * Memory Controller defines                                               *
+ ***************************************************************************
+ */
+
+/* Indirect memory controller registers */
+#define DDRC_CFG(n)            (n)
+#define DDRC_DEBUG(n)          (0x04 + n)
+#define DDRC_CTL(n)            (0x40 + n)
+
+/* Macro to perform DDRC indirect write */
+#define DDRC_INDIRECT_WRITE(reg, mask, value) \
+({ \
+       *MEM_SS_ADDR = (((mask) & 0xf) << 8) | ((reg) & 0xff); \
+       *MEM_SS_DATA = (value); \
+       *MEM_SS_WRITE = 1; \
+})
+
+/*
+ ***************************************************************************
+ * SPI/MPI Mode                                                            *
+ ***************************************************************************
+ */
+#define SPI_MPI_RX_BUSY                0x00008000      /* SPI/MPI Receive Busy */
+#define SPI_MPI_FIFO_EMPTY     0x00004000      /* SPI/MPI Fifo Empty   */
+#define SPI_MPI_TX_BUSY                0x00002000      /* SPI/MPI Transmit Busy */
+#define SPI_MPI_FIFO_FULL      0x00001000      /* SPI/MPU FIFO full    */
+
+/*
+ ***************************************************************************
+ * SPI/MPI Control Register                                                *
+ ***************************************************************************
+ */
+#define SPI_MPI_RX_START       0x00000004      /* Start receive command */
+#define SPI_MPI_FLUSH_Q                0x00000002      /* Flush SPI/MPI Queue */
+#define SPI_MPI_TX_START       0x00000001      /* Start Transmit Command */
+
+#endif /* !_ASM_MSP_REGS_H */
diff --git a/include/asm-mips/pmc-sierra/msp71xx/msp_slp_int.h b/include/asm-mips/pmc-sierra/msp71xx/msp_slp_int.h
new file mode 100644 (file)
index 0000000..96d4c8c
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * Defines for the MSP interrupt controller.
+ *
+ * Copyright (C) 1999 MIPS Technologies, Inc.  All rights reserved.
+ * Author: Carsten Langgaard, carstenl@mips.com
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You 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 _MSP_SLP_INT_H
+#define _MSP_SLP_INT_H
+
+/*
+ * The PMC-Sierra SLP interrupts are arranged in a 3 level cascaded
+ * hierarchical system.  The first level are the direct MIPS interrupts
+ * and are assigned the interrupt range 0-7.  The second level is the SLM
+ * interrupt controller and is assigned the range 8-39.  The third level
+ * comprises the Peripherial block, the PCI block, the PCI MSI block and
+ * the SLP.  The PCI interrupts and the SLP errors are handled by the
+ * relevant subsystems so the core interrupt code needs only concern
+ * itself with the Peripheral block.  These are assigned interrupts in
+ * the range 40-71.
+ */
+
+/*
+ * IRQs directly connected to CPU
+ */
+#define MSP_MIPS_INTBASE       0
+#define MSP_INT_SW0            0  /* IRQ for swint0,         C_SW0  */
+#define MSP_INT_SW1            1  /* IRQ for swint1,         C_SW1  */
+#define MSP_INT_MAC0           2  /* IRQ for MAC 0,          C_IRQ0 */
+#define MSP_INT_MAC1           3  /* IRQ for MAC 1,          C_IRQ1 */
+#define MSP_INT_C_IRQ2         4  /* Wired off,              C_IRQ2 */
+#define MSP_INT_VE             5  /* IRQ for Voice Engine,   C_IRQ3 */
+#define MSP_INT_SLP            6  /* IRQ for SLM block,      C_IRQ4 */
+#define MSP_INT_TIMER          7  /* IRQ for the MIPS timer, C_IRQ5 */
+
+/*
+ * IRQs cascaded on CPU interrupt 4 (CAUSE bit 12, C_IRQ4)
+ * These defines should be tied to the register definition for the SLM
+ * interrupt routine.  For now, just use hard-coded values.
+ */
+#define MSP_SLP_INTBASE                (MSP_MIPS_INTBASE + 8)
+#define MSP_INT_EXT0           (MSP_SLP_INTBASE + 0)
+                                       /* External interrupt 0         */
+#define MSP_INT_EXT1           (MSP_SLP_INTBASE + 1)
+                                       /* External interrupt 1         */
+#define MSP_INT_EXT2           (MSP_SLP_INTBASE + 2)
+                                       /* External interrupt 2         */
+#define MSP_INT_EXT3           (MSP_SLP_INTBASE + 3)
+                                       /* External interrupt 3         */
+/* Reserved                                       4-7                  */
+
+/*
+ *************************************************************************
+ * DANGER/DANGER/DANGER/DANGER/DANGER/DANGER/DANGER/DANGER/DANGER/DANGER *
+ * Some MSP produces have this interrupt labelled as Voice and some are  *
+ * SEC mbox ...                                                          *
+ *************************************************************************
+ */
+#define MSP_INT_SLP_VE         (MSP_SLP_INTBASE + 8)
+                                       /* Cascaded IRQ for Voice Engine*/
+#define MSP_INT_SLP_TDM                (MSP_SLP_INTBASE + 9)
+                                       /* TDM interrupt                */
+#define MSP_INT_SLP_MAC0       (MSP_SLP_INTBASE + 10)
+                                       /* Cascaded IRQ for MAC 0       */
+#define MSP_INT_SLP_MAC1       (MSP_SLP_INTBASE + 11)
+                                       /* Cascaded IRQ for MAC 1       */
+#define MSP_INT_SEC            (MSP_SLP_INTBASE + 12)
+                                       /* IRQ for security engine      */
+#define        MSP_INT_PER             (MSP_SLP_INTBASE + 13)
+                                       /* Peripheral interrupt         */
+#define        MSP_INT_TIMER0          (MSP_SLP_INTBASE + 14)
+                                       /* SLP timer 0                  */
+#define        MSP_INT_TIMER1          (MSP_SLP_INTBASE + 15)
+                                       /* SLP timer 1                  */
+#define        MSP_INT_TIMER2          (MSP_SLP_INTBASE + 16)
+                                       /* SLP timer 2                  */
+#define        MSP_INT_SLP_TIMER       (MSP_SLP_INTBASE + 17)
+                                       /* Cascaded MIPS timer          */
+#define MSP_INT_BLKCP          (MSP_SLP_INTBASE + 18)
+                                       /* Block Copy                   */
+#define MSP_INT_UART0          (MSP_SLP_INTBASE + 19)
+                                       /* UART 0                       */
+#define MSP_INT_PCI            (MSP_SLP_INTBASE + 20)
+                                       /* PCI subsystem                */
+#define MSP_INT_PCI_DBELL      (MSP_SLP_INTBASE + 21)
+                                       /* PCI doorbell                 */
+#define MSP_INT_PCI_MSI                (MSP_SLP_INTBASE + 22)
+                                       /* PCI Message Signal           */
+#define MSP_INT_PCI_BC0                (MSP_SLP_INTBASE + 23)
+                                       /* PCI Block Copy 0             */
+#define MSP_INT_PCI_BC1                (MSP_SLP_INTBASE + 24)
+                                       /* PCI Block Copy 1             */
+#define MSP_INT_SLP_ERR                (MSP_SLP_INTBASE + 25)
+                                       /* SLP error condition          */
+#define MSP_INT_MAC2           (MSP_SLP_INTBASE + 26)
+                                       /* IRQ for MAC2                 */
+/* Reserved                                       26-31                */
+
+/*
+ * IRQs cascaded on SLP PER interrupt (MSP_INT_PER)
+ */
+#define MSP_PER_INTBASE                (MSP_SLP_INTBASE + 32)
+/* Reserved                                       0-1                  */
+#define MSP_INT_UART1          (MSP_PER_INTBASE + 2)
+                                       /* UART 1                       */
+/* Reserved                                       3-5                  */
+#define MSP_INT_2WIRE          (MSP_PER_INTBASE + 6)
+                                       /* 2-wire                       */
+#define MSP_INT_TM0            (MSP_PER_INTBASE + 7)
+                                       /* Peripheral timer block out 0 */
+#define MSP_INT_TM1            (MSP_PER_INTBASE + 8)
+                                       /* Peripheral timer block out 1 */
+/* Reserved                                       9                    */
+#define MSP_INT_SPRX           (MSP_PER_INTBASE + 10)
+                                       /* SPI RX complete              */
+#define MSP_INT_SPTX           (MSP_PER_INTBASE + 11)
+                                       /* SPI TX complete              */
+#define MSP_INT_GPIO           (MSP_PER_INTBASE + 12)
+                                       /* GPIO                         */
+#define MSP_INT_PER_ERR                (MSP_PER_INTBASE + 13)
+                                       /* Peripheral error             */
+/* Reserved                                       14-31                */
+
+#endif /* !_MSP_SLP_INT_H */
index 5f80ba71ab92b3ad17778e483a8cad854d728c24..1d8b9a8ae324d147923ef6593b9a9995700347b0 100644 (file)
@@ -82,10 +82,6 @@ struct mips_fpu_struct {
        unsigned int    fcr31;
 };
 
-#define INIT_FPU { \
-       {0,} \
-}
-
 #define NUM_DSP_REGS   6
 
 typedef __u32 dspreg_t;
@@ -95,8 +91,6 @@ struct mips_dsp_state {
        unsigned int    dspcontrol;
 };
 
-#define INIT_DSP {{0,},}
-
 #define INIT_CPUMASK { \
        {0,} \
 }
@@ -155,41 +149,63 @@ struct thread_struct {
 #define MF_N64         0
 
 #ifdef CONFIG_MIPS_MT_FPAFF
-#define FPAFF_INIT 0, INIT_CPUMASK,
+#define FPAFF_INIT                                             \
+       .emulated_fp                    = 0,                    \
+       .user_cpus_allowed              = INIT_CPUMASK,
 #else
 #define FPAFF_INIT
 #endif /* CONFIG_MIPS_MT_FPAFF */
 
-#define INIT_THREAD  { \
-        /* \
-         * saved main processor registers \
-         */ \
-       0, 0, 0, 0, 0, 0, 0, 0, \
-                      0, 0, 0, \
-       /* \
-        * saved cp0 stuff \
-        */ \
-       0, \
-       /* \
-        * saved fpu/fpu emulator stuff \
-        */ \
-       INIT_FPU, \
-       /* \
-        * fpu affinity state (null if not FPAFF) \
-        */ \
-       FPAFF_INIT \
-       /* \
-        * saved dsp/dsp emulator stuff \
-        */ \
-       INIT_DSP, \
-       /* \
-        * Other stuff associated with the process \
-        */ \
-       0, 0, 0, 0, \
-       /* \
-        * For now the default is to fix address errors \
-        */ \
-       MF_FIXADE, 0, 0 \
+#define INIT_THREAD  {                                         \
+        /*                                                     \
+         * Saved main processor registers                      \
+         */                                                    \
+       .reg16                  = 0,                            \
+       .reg17                  = 0,                            \
+       .reg18                  = 0,                            \
+       .reg19                  = 0,                            \
+       .reg20                  = 0,                            \
+       .reg21                  = 0,                            \
+       .reg22                  = 0,                            \
+       .reg23                  = 0,                            \
+       .reg29                  = 0,                            \
+       .reg30                  = 0,                            \
+       .reg31                  = 0,                            \
+       /*                                                      \
+        * Saved cp0 stuff                                      \
+        */                                                     \
+       .cp0_status             = 0,                            \
+       /*                                                      \
+        * Saved FPU/FPU emulator stuff                         \
+        */                                                     \
+       .fpu                    = {                             \
+               .fpr            = {0,},                         \
+               .fcr31          = 0,                            \
+       },                                                      \
+       /*                                                      \
+        * FPU affinity state (null if not FPAFF)               \
+        */                                                     \
+       FPAFF_INIT                                              \
+       /*                                                      \
+        * Saved DSP stuff                                      \
+        */                                                     \
+       .dsp                    = {                             \
+               .dspr           = {0, },                        \
+               .dspcontrol     = 0,                            \
+       },                                                      \
+       /*                                                      \
+        * Other stuff associated with the process              \
+        */                                                     \
+       .cp0_badvaddr           = 0,                            \
+       .cp0_baduaddr           = 0,                            \
+       .error_code             = 0,                            \
+       .trap_no                = 0,                            \
+       /*                                                      \
+        * For now the default is to fix address errors         \
+        */                                                     \
+       .mflags                 = MF_FIXADE,                    \
+       .irix_trampoline        = 0,                            \
+       .irix_oldctx            = 0,                            \
 }
 
 struct task_struct;
@@ -237,7 +253,7 @@ unsigned long get_wchan(struct task_struct *p);
 
 #define ARCH_HAS_PREFETCH
 
-extern inline void prefetch(const void *addr)
+static inline void prefetch(const void *addr)
 {
        __asm__ __volatile__(
        "       .set    mips4           \n"
diff --git a/include/asm-mips/rtc.h b/include/asm-mips/rtc.h
deleted file mode 100644 (file)
index 82ad401..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * include/asm-mips/rtc.h
- *
- * (Really an interface for drivers/char/genrtc.c)
- *
- * Copyright (C) 2004 MontaVista Software Inc.
- * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
- *
- * Please read the COPYING file for all license details.
- */
-
-#ifndef _MIPS_RTC_H
-#define _MIPS_RTC_H
-
-#ifdef __KERNEL__
-
-#include <linux/rtc.h>
-#include <asm/time.h>
-
-#define RTC_PIE 0x40            /* periodic interrupt enable */
-#define RTC_AIE 0x20            /* alarm interrupt enable */
-#define RTC_UIE 0x10            /* update-finished interrupt enable */
-
-/* some dummy definitions */
-#define RTC_BATT_BAD 0x100      /* battery bad */
-#define RTC_SQWE 0x08           /* enable square-wave output */
-#define RTC_DM_BINARY 0x04      /* all time/date values are BCD if clear */
-#define RTC_24H 0x02            /* 24 hour mode - else hours bit 7 means pm */
-#define RTC_DST_EN 0x01         /* auto switch DST - works f. USA only */
-
-static inline unsigned int get_rtc_time(struct rtc_time *time)
-{
-       unsigned long nowtime;
-
-       nowtime = rtc_mips_get_time();
-       to_tm(nowtime, time);
-       time->tm_year -= 1900;
-
-       return RTC_24H;
-}
-
-static inline int set_rtc_time(struct rtc_time *time)
-{
-       unsigned long nowtime;
-       int ret;
-
-       nowtime = mktime(time->tm_year+1900, time->tm_mon+1,
-                       time->tm_mday, time->tm_hour, time->tm_min,
-                       time->tm_sec);
-       ret = rtc_mips_set_time(nowtime);
-
-       return ret;
-}
-
-static inline unsigned int get_rtc_ss(void)
-{
-       struct rtc_time h;
-
-       get_rtc_time(&h);
-       return h.tm_sec;
-}
-
-static inline int get_rtc_pll(struct rtc_pll_info *pll)
-{
-       return -EINVAL;
-}
-
-static inline int set_rtc_pll(struct rtc_pll_info *pll)
-{
-       return -EINVAL;
-}
-#endif
-#endif
index ce51213d84f989f8eafb3df63cd46dba941861fb..c07ebd8eb9e78e55fe517769c2ad4e79d2283bf0 100644 (file)
  */
 #define BASE_BAUD (1843200 / 16)
 
-/* Standard COM flags (except for COM4, because of the 8514 problem) */
-#ifdef CONFIG_SERIAL_DETECT_IRQ
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ)
-#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ)
-#else
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
-#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
-#endif
-
-#ifdef CONFIG_MACH_JAZZ
-#include <asm/jazz.h>
-
-#ifndef CONFIG_OLIVETTI_M700
-   /* Some Jazz machines seem to have an 8MHz crystal clock but I don't know
-      exactly which ones ... XXX */
-#define JAZZ_BASE_BAUD ( 8000000 / 16 ) /* ( 3072000 / 16) */
-#else
-/* but the M700 isn't such a strange beast */
-#define JAZZ_BASE_BAUD BASE_BAUD
-#endif
-
-#define _JAZZ_SERIAL_INIT(int, base)                                   \
-       { .baud_base = JAZZ_BASE_BAUD, .irq = int, .flags = STD_COM_FLAGS,      \
-         .iomem_base = (u8 *) base, .iomem_reg_shift = 0,                      \
-         .io_type = SERIAL_IO_MEM }
-#define JAZZ_SERIAL_PORT_DEFNS                                         \
-       _JAZZ_SERIAL_INIT(JAZZ_SERIAL1_IRQ, JAZZ_SERIAL1_BASE),         \
-       _JAZZ_SERIAL_INIT(JAZZ_SERIAL2_IRQ, JAZZ_SERIAL2_BASE),
-#else
-#define JAZZ_SERIAL_PORT_DEFNS
-#endif
-
-/*
- * Galileo EV64120 evaluation board
- */
-#ifdef CONFIG_MIPS_EV64120
-#include <mach-gt64120.h>
-#define EV64120_SERIAL_PORT_DEFNS                                  \
-    { .baud_base = EV64120_BASE_BAUD, .irq = EV64120_UART_IRQ, \
-      .flags = STD_COM_FLAGS,  \
-      .iomem_base = EV64120_UART0_REGS_BASE, .iomem_reg_shift = 2, \
-      .io_type = SERIAL_IO_MEM }, \
-    { .baud_base = EV64120_BASE_BAUD, .irq = EV64120_UART_IRQ, \
-      .flags = STD_COM_FLAGS, \
-      .iomem_base = EV64120_UART1_REGS_BASE, .iomem_reg_shift = 2, \
-      .io_type = SERIAL_IO_MEM },
-#else
-#define EV64120_SERIAL_PORT_DEFNS
-#endif
-
-#ifdef CONFIG_HAVE_STD_PC_SERIAL_PORT
-#define STD_SERIAL_PORT_DEFNS                  \
-       /* UART CLK   PORT IRQ     FLAGS        */                      \
-       { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS },      /* ttyS0 */     \
-       { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS },      /* ttyS1 */     \
-       { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS },      /* ttyS2 */     \
-       { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS },     /* ttyS3 */
-
-#else /* CONFIG_HAVE_STD_PC_SERIAL_PORTS */
-#define STD_SERIAL_PORT_DEFNS
-#endif /* CONFIG_HAVE_STD_PC_SERIAL_PORTS */
-
-#ifdef CONFIG_MOMENCO_OCELOT_3
-#define OCELOT_3_BASE_BAUD     ( 20000000 / 16 )
-#define OCELOT_3_SERIAL_IRQ    6
-#define OCELOT_3_SERIAL_BASE   (signed)0xfd000020
-
-#define _OCELOT_3_SERIAL_INIT(int, base)                               \
-       { .baud_base = OCELOT_3_BASE_BAUD, irq: int,                    \
-         .flags = STD_COM_FLAGS,                                               \
-         .iomem_base = (u8 *) base, iomem_reg_shift: 2,                        \
-         io_type: SERIAL_IO_MEM }
-
-#define MOMENCO_OCELOT_3_SERIAL_PORT_DEFNS                             \
-       _OCELOT_3_SERIAL_INIT(OCELOT_3_SERIAL_IRQ, OCELOT_3_SERIAL_BASE)
-#else
-#define MOMENCO_OCELOT_3_SERIAL_PORT_DEFNS
-#endif
-
-#ifdef CONFIG_MOMENCO_OCELOT
-/* Ordinary NS16552 duart with a 20MHz crystal.  */
-#define OCELOT_BASE_BAUD ( 20000000 / 16 )
-
-#define OCELOT_SERIAL1_IRQ     4
-#define OCELOT_SERIAL1_BASE    0xe0001020
-
-#define _OCELOT_SERIAL_INIT(int, base)                                 \
-       { .baud_base = OCELOT_BASE_BAUD, .irq = int, .flags = STD_COM_FLAGS,    \
-         .iomem_base = (u8 *) base, .iomem_reg_shift = 2,                      \
-         .io_type = SERIAL_IO_MEM }
-#define MOMENCO_OCELOT_SERIAL_PORT_DEFNS                               \
-       _OCELOT_SERIAL_INIT(OCELOT_SERIAL1_IRQ, OCELOT_SERIAL1_BASE)
-#else
-#define MOMENCO_OCELOT_SERIAL_PORT_DEFNS
-#endif
-
-#ifdef CONFIG_MOMENCO_OCELOT_C
-/* Ordinary NS16552 duart with a 20MHz crystal.  */
-#define OCELOT_C_BASE_BAUD ( 20000000 / 16 )
-
-#define OCELOT_C_SERIAL1_IRQ   80
-#define OCELOT_C_SERIAL1_BASE  0xfd000020
-
-#define OCELOT_C_SERIAL2_IRQ   81
-#define OCELOT_C_SERIAL2_BASE  0xfd000000
-
-#define _OCELOT_C_SERIAL_INIT(int, base)                               \
-       { .baud_base            = OCELOT_C_BASE_BAUD,                   \
-         .irq                  = (int),                                \
-         .flags                = STD_COM_FLAGS,                        \
-         .iomem_base           = (u8 *) base,                          \
-         .iomem_reg_shift      = 2,                                    \
-         .io_type              = SERIAL_IO_MEM                         \
-        }
-#define MOMENCO_OCELOT_C_SERIAL_PORT_DEFNS                             \
-       _OCELOT_C_SERIAL_INIT(OCELOT_C_SERIAL1_IRQ, OCELOT_C_SERIAL1_BASE), \
-       _OCELOT_C_SERIAL_INIT(OCELOT_C_SERIAL2_IRQ, OCELOT_C_SERIAL2_BASE)
-#else
-#define MOMENCO_OCELOT_C_SERIAL_PORT_DEFNS
-#endif
-
-#ifdef CONFIG_DDB5477
-#include <asm/ddb5xxx/ddb5477.h>
-#define DDB5477_SERIAL_PORT_DEFNS                                       \
-        { .baud_base = BASE_BAUD, .irq = VRC5477_IRQ_UART0,            \
-         .flags = STD_COM_FLAGS, .iomem_base = (u8*)0xbfa04200,        \
-         .iomem_reg_shift = 3, .io_type = SERIAL_IO_MEM},              \
-        { .baud_base = BASE_BAUD, .irq = VRC5477_IRQ_UART1,            \
-         .flags = STD_COM_FLAGS, .iomem_base = (u8*)0xbfa04240,        \
-         .iomem_reg_shift = 3, .io_type = SERIAL_IO_MEM},
-#else
-#define DDB5477_SERIAL_PORT_DEFNS
-#endif
-
-#ifdef CONFIG_SGI_IP32
-/*
- * The IP32 (SGI O2) has standard serial ports (UART 16550A) mapped in memory
- * They are initialized in ip32_setup
- */
-#define IP32_SERIAL_PORT_DEFNS                         \
-        {},{},
-#else
-#define IP32_SERIAL_PORT_DEFNS
-#endif /* CONFIG_SGI_IP32 */
-
-#define SERIAL_PORT_DFNS                               \
-       DDB5477_SERIAL_PORT_DEFNS                       \
-       EV64120_SERIAL_PORT_DEFNS                       \
-       IP32_SERIAL_PORT_DEFNS                          \
-       JAZZ_SERIAL_PORT_DEFNS                          \
-       STD_SERIAL_PORT_DEFNS                           \
-       MOMENCO_OCELOT_C_SERIAL_PORT_DEFNS              \
-       MOMENCO_OCELOT_SERIAL_PORT_DEFNS                \
-       MOMENCO_OCELOT_3_SERIAL_PORT_DEFNS
-
 #endif /* _ASM_SERIAL_H */
index 1608fd71d6f7ffd7d1e1a39cf181515c658c3ea4..13aef6af422c1cbd9eb445df6c5cbda10b852407 100644 (file)
@@ -49,13 +49,6 @@ extern struct call_data_struct *call_data;
 extern cpumask_t phys_cpu_present_map;
 #define cpu_possible_map       phys_cpu_present_map
 
-extern cpumask_t cpu_callout_map;
-/* We don't mark CPUs online until __cpu_up(), so we need another measure */
-static inline int num_booting_cpus(void)
-{
-       return cpus_weight(cpu_callout_map);
-}
-
 /*
  * These are defined by the board-specific code.
  */
index f257509b914f11dfe30380e10a64f86f1372de72..ddaf36a1e3891f114b731e360e0d83792b31d82a 100644 (file)
@@ -146,9 +146,6 @@ extern unsigned int sni_brd_type;
 #define SNI_A20R_IRQ_BASE       MIPS_CPU_IRQ_BASE
 #define SNI_A20R_IRQ_TIMER      (SNI_A20R_IRQ_BASE+5)
 
-#define SNI_DS1216_A20R_BASE    0xbc081ffc
-#define SNI_DS1216_RM200_BASE   0xbcd41ffc
-
 #define SNI_PCIT_INT_REG        0xbfff000c
 
 #define SNI_PCIT_INT_START      24
index bb0b289dbc9ef25ac7f211b620309ab66bfbe76b..46bdb3f566f92b209062628b1b7dc854c587092e 100644 (file)
@@ -44,7 +44,7 @@ struct task_struct;
  * different thread.
  */
 
-#define switch_to(prev,next,last)                                      \
+#define __mips_mt_fpaff_switch_to(prev)                                        \
 do {                                                                   \
        if (cpu_has_fpu &&                                              \
            (prev->thread.mflags & MF_FPUBOUND) &&                      \
@@ -52,24 +52,24 @@ do {                                                                        \
                prev->thread.mflags &= ~MF_FPUBOUND;                    \
                prev->cpus_allowed = prev->thread.user_cpus_allowed;    \
        }                                                               \
-       if (cpu_has_dsp)                                                \
-               __save_dsp(prev);                                       \
        next->thread.emulated_fp = 0;                                   \
-       (last) = resume(prev, next, task_thread_info(next));            \
-       if (cpu_has_dsp)                                                \
-               __restore_dsp(current);                                 \
 } while(0)
 
 #else
+#define __mips_mt_fpaff_switch_to(prev) do { (void) (prev); } while (0)
+#endif
+
 #define switch_to(prev,next,last)                                      \
 do {                                                                   \
+       __mips_mt_fpaff_switch_to(prev);                                \
        if (cpu_has_dsp)                                                \
                __save_dsp(prev);                                       \
        (last) = resume(prev, next, task_thread_info(next));            \
        if (cpu_has_dsp)                                                \
                __restore_dsp(current);                                 \
+       if (cpu_has_userlocal)                                          \
+               write_c0_userlocal(task_thread_info(current)->tp_value);\
 } while(0)
-#endif
 
 /*
  * On SMP systems, when the scheduler does migration-cost autodetection,
index 0bbe07b42a0767b41bfb0cf3ebb069f7905e1611..5bfdc3b645106303450d6a44f6afffe012c361c1 100644 (file)
@@ -30,6 +30,17 @@ struct termios {
        cc_t c_cc[NCCS];                /* control characters */
 };
 
+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 */
+       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 */
index fff7a73e22d0f666387097a336bbd6ef1cb26bae..bb8f5c29c3d9f9a5e0c72c4497993fec46fcfae2 100644 (file)
 /*
  * TLB debugging functions:
  */
-extern void dump_tlb(int first, int last);
 extern void dump_tlb_all(void);
-extern void dump_tlb_wired(void);
-extern void dump_tlb_addr(unsigned long addr);
-extern void dump_tlb_nonwired(void);
 
 #endif /* __ASM_TLBDEBUG_H */
index 0fbedafdcea8d31bb64008270d360061196f3cd9..74e7d8061e5881b61129752c9c493b28c09d212a 100644 (file)
 #define rbtx4938_pcireset_ptr  \
        ((volatile unsigned char *)RBTX4938_PCIRESET_ADDR)
 
-/* SPI */
-#define RBTX4938_SEEPROM1_CHIPID       0
-#define RBTX4938_SEEPROM2_CHIPID       1
-#define RBTX4938_SEEPROM3_CHIPID       2
-#define RBTX4938_SRTC_CHIPID   3
-
 /*
  * IRQ mappings
  */
index 0dbbab820a5a87b3bee412f4d0d295808e9f982e..6a60c83e152bcaf156ca08da259fb980587b0828 100644 (file)
 #ifndef __ASM_TX_BOARDS_TX4938_SPI_H
 #define __ASM_TX_BOARDS_TX4938_SPI_H
 
-/* SPI */
-struct spi_dev_desc {
-       unsigned int baud;
-       unsigned short tcss, tcsh, tcsr; /* CS setup/hold/recovery time */
-       unsigned int byteorder:1;       /* 0:LSB-First, 1:MSB-First */
-       unsigned int polarity:1;        /* 0:High-Active */
-       unsigned int phase:1;           /* 0:Sample-Then-Shift */
-};
-
-extern void txx9_spi_init(unsigned long base, int (*cs_func)(int chipid, int on)) __init;
-extern void txx9_spi_irqinit(int irc_irq) __init;
-extern int txx9_spi_io(int chipid, struct spi_dev_desc *desc,
-                      unsigned char **inbufs, unsigned int *incounts,
-                      unsigned char **outbufs, unsigned int *outcounts,
-                      int cansleep);
-extern int spi_eeprom_write_enable(int chipid, int enable);
-extern int spi_eeprom_read_status(int chipid);
+extern int spi_eeprom_register(int chipid);
 extern int spi_eeprom_read(int chipid, int address, unsigned char *buf, int len);
-extern int spi_eeprom_write(int chipid, int address, unsigned char *buf, int len);
-extern void spi_eeprom_proc_create(struct proc_dir_entry *dir, int chipid) __init;
-
-#define TXX9_IMCLK     (txx9_gbus_clock / 2)
-
-/*
-* SPI
-*/
-
-/* SPMCR : SPI Master Control */
-#define TXx9_SPMCR_OPMODE      0xc0
-#define TXx9_SPMCR_CONFIG      0x40
-#define TXx9_SPMCR_ACTIVE      0x80
-#define TXx9_SPMCR_SPSTP       0x02
-#define TXx9_SPMCR_BCLR        0x01
-
-/* SPCR0 : SPI Status */
-#define TXx9_SPCR0_TXIFL_MASK  0xc000
-#define TXx9_SPCR0_RXIFL_MASK  0x3000
-#define TXx9_SPCR0_SIDIE       0x0800
-#define TXx9_SPCR0_SOEIE       0x0400
-#define TXx9_SPCR0_RBSIE       0x0200
-#define TXx9_SPCR0_TBSIE       0x0100
-#define TXx9_SPCR0_IFSPSE      0x0010
-#define TXx9_SPCR0_SBOS        0x0004
-#define TXx9_SPCR0_SPHA        0x0002
-#define TXx9_SPCR0_SPOL        0x0001
-
-/* SPSR : SPI Status */
-#define TXx9_SPSR_TBSI 0x8000
-#define TXx9_SPSR_RBSI 0x4000
-#define TXx9_SPSR_TBS_MASK     0x3800
-#define TXx9_SPSR_RBS_MASK     0x0700
-#define TXx9_SPSR_SPOE 0x0080
-#define TXx9_SPSR_IFSD 0x0008
-#define TXx9_SPSR_SIDLE        0x0004
-#define TXx9_SPSR_STRDY        0x0002
-#define TXx9_SPSR_SRRDY        0x0001
 
 #endif /* __ASM_TX_BOARDS_TX4938_SPI_H */
index 8109cda557dce747e0d0032c8bd59eda4b48f046..0bcdd3a5c2560b6817174af92d1e1dbfe2a9cd07 100644 (file)
 #ifndef __NEC_VR41XX_GIU_H
 #define __NEC_VR41XX_GIU_H
 
+/*
+ * NEC VR4100 series GIU platform device IDs.
+ */
+enum {
+       GPIO_50PINS_PULLUPDOWN,
+       GPIO_36PINS,
+       GPIO_48PINS_EDGE_SELECT,
+};
+
 typedef enum {
        IRQ_TRIGGER_LEVEL,
        IRQ_TRIGGER_EDGE,
index 1fcf6e8082b42621271bc87aa344e4ba4501ce5c..98cdb409648513dddaa702ef168bba48513e9c91 100644 (file)
@@ -20,6 +20,8 @@
 #ifndef __NEC_VR41XX_SIU_H
 #define __NEC_VR41XX_SIU_H
 
+#define SIU_PORTS_MAX 2
+
 typedef enum {
        SIU_INTERFACE_RS232C,
        SIU_INTERFACE_IRDA,
index ec0eeebd880206a4c71f444c634c54812ffaf3bd..9de52a5b0f3d4d66ab4c99ab9c4730980ea868b2 100644 (file)
 
 /*
  * On the RM9000 there is a problem which makes the CreateDirtyExclusive
- * cache operation unusable on SMP systems.
+ * eache operation unusable on SMP systems.
  */
-#if defined(CONFIG_MOMENCO_JAGUAR_ATX) || defined(CONFIG_PMC_YOSEMITE) || \
-    defined(CONFIG_BASLER_EXCITE)
+#if defined(CONFIG_PMC_YOSEMITE) || defined(CONFIG_BASLER_EXCITE)
 #define  RM9000_CDEX_SMP_WAR           1
 #endif
 
  * I-cache line worth of instructions being fetched may case spurious
  * exceptions.
  */
-#if defined(CONFIG_BASLER_EXCITE) || defined(CONFIG_MOMENCO_JAGUAR_ATX) || \
-    defined(CONFIG_MIPS_ATLAS) || defined(CONFIG_MIPS_MALTA) || \
-    defined(CONFIG_MOMENCO_OCELOT) || defined(CONFIG_MOMENCO_OCELOT_3) || \
-    defined(CONFIG_MOMENCO_OCELOT_C) || defined(CONFIG_PMC_YOSEMITE) || \
-    defined(CONFIG_SGI_IP32) || defined(CONFIG_WR_PPMC)
+#if defined(CONFIG_BASLER_EXCITE) || defined(CONFIG_MIPS_ATLAS) || \
+    defined(CONFIG_MIPS_MALTA) || defined(CONFIG_MOMENCO_OCELOT) || \
+    defined(CONFIG_PMC_YOSEMITE) || defined(CONFIG_SGI_IP32) || \
+    defined(CONFIG_WR_PPMC)
 #define ICACHE_REFILLS_WORKAROUND_WAR  1
 #endif
 
 #define R10000_LLSC_WAR 1
 #endif
 
+/*
+ * 34K core erratum: "Problems Executing the TLBR Instruction"
+ */
+#if defined(CONFIG_PMC_MSP7120_EVAL) || defined(CONFIG_PMC_MSP7120_GW) || \
+       defined(CONFIG_PMC_MSP7120_FPGA)
+#define MIPS34K_MISSED_ITLB_WAR                1
+#endif
+
 /*
  * Workarounds default to off
  */
 #ifndef R10000_LLSC_WAR
 #define R10000_LLSC_WAR                        0
 #endif
+#ifndef MIPS34K_MISSED_ITLB_WAR
+#define MIPS34K_MISSED_ITLB_WAR                0
+#endif
 
 #endif /* _ASM_WAR_H */
diff --git a/include/asm-mips/watch.h b/include/asm-mips/watch.h
deleted file mode 100644 (file)
index 6aa90ca..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1996, 1997, 1998, 2000, 2001 by Ralf Baechle
- */
-#ifndef _ASM_WATCH_H
-#define _ASM_WATCH_H
-
-#include <linux/linkage.h>
-
-/*
- * Types of reference for watch_set()
- */
-enum wref_type {
-       wr_save = 1,
-       wr_load = 2
-};
-
-extern asmlinkage void __watch_set(unsigned long addr, enum wref_type ref);
-extern asmlinkage void __watch_clear(void);
-extern asmlinkage void __watch_reenable(void);
-
-#define watch_set(addr, ref)                                   \
-       if (cpu_has_watch)                                      \
-               __watch_set(addr, ref)
-#define watch_clear()                                          \
-       if (cpu_has_watch)                                      \
-               __watch_clear()
-#define watch_reenable()                                       \
-       if (cpu_has_watch)                                      \
-               __watch_reenable()
-
-#endif /* _ASM_WATCH_H */
index 7b3be9ac0dda3f67032f95ac5c4f8493bf6f1895..61fbd57a83232ae5d9d7b100d0341aeb22651986 100644 (file)
@@ -238,9 +238,6 @@ extern inline void pcibios_register_hba(struct pci_hba_data *x)
 #define PCIBIOS_MIN_IO          0x10
 #define PCIBIOS_MIN_MEM         0x1000 /* NBPG - but pci/setup-res.c dies */
 
-/* Don't support DAC yet. */
-#define pci_dac_dma_supported(pci_dev, mask)   (0)
-
 /* export the pci_ DMA API in terms of the dma_ one */
 #include <asm-generic/pci-dma-compat.h>
 
@@ -284,10 +281,6 @@ pcibios_select_root(struct pci_dev *pdev, struct resource *res)
        return root;
 }
 
-static inline void pcibios_add_platform_entries(struct pci_dev *dev)
-{
-}
-
 static inline void pcibios_penalize_isa_irq(int irq, int active)
 {
        /* We don't need to penalize isa irq's */
index a46e299a93912ae61393b8e9a0083e55c370b7df..e847fe979684fc0a73c45f42524911936dfe4cdb 100644 (file)
@@ -17,6 +17,17 @@ struct termios {
        cc_t c_cc[NCCS];                /* control characters */
 };
 
+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 */
+       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 */
index a19a6f1a1cf10dd54fcce72e94e9e19e135db966..f6bd804d9090e3d714393c284957e428f7a43567 100644 (file)
@@ -61,7 +61,6 @@ struct dma_mapping_ops {
        void            (*unmap_sg)(struct device *dev, struct scatterlist *sg,
                                int nents, enum dma_data_direction direction);
        int             (*dma_supported)(struct device *dev, u64 mask);
-       int             (*dac_dma_supported)(struct device *dev, u64 mask);
        int             (*set_dma_mask)(struct device *dev, u64 dma_mask);
 };
 
index ce0f13e8eb141d6bc65aedd9aadd92a204d8c577..e16e7bc9ab5cf2640364ea19586319edbc080025 100644 (file)
@@ -74,18 +74,6 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
 extern void set_pci_dma_ops(struct dma_mapping_ops *dma_ops);
 extern struct dma_mapping_ops *get_pci_dma_ops(void);
 
-/* For DAC DMA, we currently don't support it by default, but
- * we let 64-bit platforms override this.
- */
-static inline int pci_dac_dma_supported(struct pci_dev *hwdev,u64 mask)
-{
-       struct dma_mapping_ops *d = get_pci_dma_ops();
-
-       if (d && d->dac_dma_supported)
-               return d->dac_dma_supported(&hwdev->dev, mask);
-       return 0;
-}
-
 static inline void pci_dma_burst_advice(struct pci_dev *pdev,
                                        enum pci_dma_burst_strategy *strat,
                                        unsigned long *strategy_parameter)
@@ -124,12 +112,6 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
 }
 #endif
 
-/*
- * At present there are very few 32-bit PPC machines that can have
- * memory above the 4GB point, and we don't support that.
- */
-#define pci_dac_dma_supported(pci_dev, mask)   (0)
-
 /* Return the index of the PCI controller for device PDEV. */
 #define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index
 
@@ -243,8 +225,6 @@ extern void of_scan_bus(struct device_node *node, struct pci_bus *bus);
 
 extern int pci_read_irq_line(struct pci_dev *dev);
 
-extern void pcibios_add_platform_entries(struct pci_dev *dev);
-
 struct file;
 extern pgprot_t        pci_phys_mem_access_prot(struct file *file,
                                         unsigned long pfn,
index 9d162028dab92809d4d6b49bc9fce254ccc3932b..d2442cd72a5961ac923a0ac789d3d321808b3fc7 100644 (file)
@@ -102,12 +102,6 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
 }
 #endif
 
-/*
- * At present there are very few 32-bit PPC machines that can have
- * memory above the 4GB point, and we don't support that.
- */
-#define pci_dac_dma_supported(pci_dev, mask)   (0)
-
 /* Return the index of the PCI controller for device PDEV. */
 #define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index
 
@@ -145,8 +139,6 @@ pcibios_select_root(struct pci_dev *pdev, struct resource *res)
        return root;
 }
 
-extern void pcibios_add_platform_entries(struct pci_dev *dev);
-
 struct file;
 extern pgprot_t        pci_phys_mem_access_prot(struct file *file,
                                         unsigned long pfn,
index c17bdbf220672bb522b0a81d241c703d157b0427..ea486952f778cb323c4072c8aa1cefaea7f858b2 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 typedef struct {
-       volatile int counter;
+       int counter;
 } __attribute__ ((aligned (4))) atomic_t;
 #define ATOMIC_INIT(i)  { (i) }
 
@@ -141,7 +141,7 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
 
 #ifdef __s390x__
 typedef struct {
-       volatile long long counter;
+       long long counter;
 } __attribute__ ((aligned (8))) atomic64_t;
 #define ATOMIC64_INIT(i)  { (i) }
 
index 241756f80df35260a06641d523f42a519170f513..021e7c3223ece8f931db8fca9f7d1d10cc8d029d 100644 (file)
@@ -88,7 +88,6 @@ extern u64 cmf_read(struct ccw_device *cdev, int index);
  *    any
  **/
 extern int cmf_readall(struct ccw_device *cdev, struct cmbdata*data);
-extern void cmf_reset(struct ccw_device *cdev);
 
 #endif /* __KERNEL__ */
 #endif /* S390_CMB_H */
index 5cb480af65d5513e8a55809218fcc79ce0645fd6..3b972d4c6b296f6d8cfb4b51f0f55608832dc134 100644 (file)
@@ -357,8 +357,8 @@ extern void (*s390_base_ext_handler_fn)(void);
 /*
  * CPU idle notifier chain.
  */
-#define CPU_IDLE       0
-#define CPU_NOT_IDLE   1
+#define S390_CPU_IDLE          0
+#define S390_CPU_NOT_IDLE      1
 
 struct notifier_block;
 int register_idle_notifier(struct notifier_block *nb);
index 21ed647732100c26909a89ce228c1de4d3a9dd41..cb9faf1ea5cfd5db60a602e45af058bceddc06f2 100644 (file)
 #include <linux/types.h>
 #include <asm/chpid.h>
 
-struct sccb_header {
-       u16     length;
-       u8      function_code;
-       u8      control_mask[3];
-       u16     response_code;
-} __attribute__((packed));
-
-#define LOADPARM_LEN 8
-
-struct sclp_readinfo_sccb {
-       struct  sccb_header header;     /* 0-7 */
-       u16     rnmax;                  /* 8-9 */
-       u8      rnsize;                 /* 10 */
-       u8      _reserved0[24 - 11];    /* 11-23 */
-       u8      loadparm[LOADPARM_LEN]; /* 24-31 */
-       u8      _reserved1[91 - 32];    /* 32-90 */
-       u8      flags;                  /* 91 */
-       u8      _reserved2[100 - 92];   /* 92-99 */
-       u32     rnsize2;                /* 100-103 */
-       u64     rnmax2;                 /* 104-111 */
-       u8      _reserved3[4096 - 112]; /* 112-4095 */
-} __attribute__((packed, aligned(4096)));
-
 #define SCLP_CHP_INFO_MASK_SIZE                32
 
 struct sclp_chp_info {
@@ -42,12 +19,22 @@ struct sclp_chp_info {
        u8 configured[SCLP_CHP_INFO_MASK_SIZE];
 };
 
-extern struct sclp_readinfo_sccb s390_readinfo_sccb;
-extern void sclp_readinfo_early(void);
-extern int sclp_sdias_blk_count(void);
-extern int sclp_sdias_copy(void *dest, int blk_num, int nr_blks);
-extern int sclp_chp_configure(struct chp_id chpid);
-extern int sclp_chp_deconfigure(struct chp_id chpid);
-extern int sclp_chp_read_info(struct sclp_chp_info *info);
+#define LOADPARM_LEN 8
+
+struct sclp_ipl_info {
+       int is_valid;
+       int has_dump;
+       char loadparm[LOADPARM_LEN];
+};
+
+void sclp_readinfo_early(void);
+void sclp_facilities_detect(void);
+unsigned long long sclp_memory_detect(void);
+int sclp_sdias_blk_count(void);
+int sclp_sdias_copy(void *dest, int blk_num, int nr_blks);
+int sclp_chp_configure(struct chp_id chpid);
+int sclp_chp_deconfigure(struct chp_id chpid);
+int sclp_chp_read_info(struct sclp_chp_info *info);
+void sclp_get_ipl_info(struct sclp_ipl_info *info);
 
 #endif /* _ASM_S390_SCLP_H */
index 8ca8c77b2d04c75fa3d0498217d521f2001d66f1..4e16aede4b0622b24e9660aecd5405ff5bba55fb 100644 (file)
@@ -27,9 +27,9 @@
    
 
 #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_W_TYPE             unsigned int
+#define _FP_WS_TYPE            signed int
+#define _FP_I_TYPE             int
 
 #define _FP_MUL_MEAT_S(R,X,Y)                                  \
   _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
index 8cabcd23d976c8136ba0df486858c42c31e91059..0addc6466d958aede3954efeb6b7071077344e6c 100644 (file)
        wl = __wl;                                      \
 })
 
+#ifdef __s390x__
+#define udiv_qrnnd(q, r, n1, n0, d)                    \
+  do { unsigned long __n;                              \
+       unsigned int __r, __d;                          \
+    __n = ((unsigned long)(n1) << 32) + n0;            \
+    __d = (d);                                         \
+    (q) = __n / __d;                                   \
+    (r) = __n % __d;                                   \
+  } while (0)
+#else
 #define udiv_qrnnd(q, r, n1, n0, d)                    \
   do { unsigned int __r;                               \
     (q) = __udiv_qrnnd (&__r, (n1), (n0), (d));                \
@@ -58,6 +68,7 @@
   } while (0)
 extern unsigned long __udiv_qrnnd (unsigned int *, unsigned int,
                                   unsigned int , unsigned int);
+#endif
 
 #define UDIV_NEEDS_NORMALIZATION 0
 
index 585c78a6e4070b9ff63413271646120f28f31178..811b9a9cdc085ad577476696879755c636a55792 100644 (file)
@@ -25,6 +25,17 @@ struct termios {
        cc_t c_cc[NCCS];                /* control characters */
 };
 
+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 */
+       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 */
index b1f9a9e0231e000df1ccf1a40a1a9d3b60427453..2757ce096ff73878f717ca2373daa8bc7938006d 100644 (file)
@@ -110,11 +110,6 @@ static inline void pcibios_penalize_isa_irq(int irq, int active)
 #define pci_unmap_len_set(PTR, LEN_NAME, VAL)  do { } while (0)
 #endif
 
-/* Not supporting more than 32-bit PCI bus addresses now, but
- * must satisfy references to this function.  Change if needed.
- */
-#define pci_dac_dma_supported(pci_dev, mask) (0)
-
 #ifdef CONFIG_PCI
 static inline void pci_dma_burst_advice(struct pci_dev *pdev,
                                        enum pci_dma_burst_strategy *strat,
@@ -134,10 +129,6 @@ int pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin);
 int pciauto_assign_resources(int busno, struct pci_channel *hose);
 #endif
 
-static inline void pcibios_add_platform_entries(struct pci_dev *dev)
-{
-}
-
 #endif /* __KERNEL__ */
 
 /* generic pci stuff */
index f1b7b46f4e9a46549a41648716e27e0071783c69..7ee1b42eeab0ba77bbdb06a1d1bf30a275f66d73 100644 (file)
@@ -17,6 +17,17 @@ struct termios {
        cc_t c_cc[NCCS];                /* control characters */
 };
 
+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 */
+       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 */
index aa8043089bb695133f19992d87deed7576c4f2db..57a67cf7a5c4e06309e25c2e70569dadb921fd23 100644 (file)
@@ -72,11 +72,6 @@ static inline void pcibios_penalize_isa_irq(int irq, int active)
 #define pci_unmap_len_set(PTR, LEN_NAME, VAL)  do { } while (0)
 #endif
 
-/* Not supporting more than 32-bit PCI bus addresses now, but
- * must satisfy references to this function.  Change if needed.
- */
-#define pci_dac_dma_supported(pci_dev, mask) (0)
-
 /* These macros should be used after a pci_map_sg call has been done
  * to get bus addresses of each of the SG entries and their lengths.
  * You should only work with the number of sg entries pci_map_sg
@@ -104,10 +99,6 @@ extern void pcibios_fixup_irqs(void);
 extern int pciauto_assign_resources(int busno, struct pci_channel *hose);
 #endif
 
-static inline void pcibios_add_platform_entries(struct pci_dev *dev)
-{
-}
-
 #endif /* __KERNEL__ */
 
 /* generic pci stuff */
index a750c688408bb418d702153619380a9d5100d8d6..b93b6c79e08f6d48692f1539ced9fb7dbfeb8629 100644 (file)
@@ -142,8 +142,6 @@ static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
        return 1;
 }
 
-#define pci_dac_dma_supported(dev, mask)       (0)
-
 #ifdef CONFIG_PCI
 static inline void pci_dma_burst_advice(struct pci_dev *pdev,
                                        enum pci_dma_burst_strategy *strat,
@@ -154,10 +152,6 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
 }
 #endif
 
-static inline void pcibios_add_platform_entries(struct pci_dev *dev)
-{
-}
-
 #define PCI_DMA_ERROR_CODE      (~(dma_addr_t)0x0)
 
 static inline int pci_dma_mapping_error(dma_addr_t dma_addr)
index 47cea16e1badd54d867d2add632aa6fdaa96c6e0..e11ac100f043469664c2870b90b3a1731de37e17 100644 (file)
@@ -206,49 +206,6 @@ extern int pci_dma_supported(struct pci_dev *hwdev, u64 mask);
 #define PCI64_REQUIRED_MASK    (~(dma64_addr_t)0)
 #define PCI64_ADDR_BASE                0xfffc000000000000UL
 
-/* Usage of the pci_dac_foo interfaces is only valid if this
- * test passes.
- */
-#define pci_dac_dma_supported(pci_dev, mask) \
-       ((((mask) & PCI64_REQUIRED_MASK) == PCI64_REQUIRED_MASK) ? 1 : 0)
-
-static inline dma64_addr_t
-pci_dac_page_to_dma(struct pci_dev *pdev, struct page *page, unsigned long offset, int direction)
-{
-       return (PCI64_ADDR_BASE +
-               __pa(page_address(page)) + offset);
-}
-
-static inline struct page *
-pci_dac_dma_to_page(struct pci_dev *pdev, dma64_addr_t dma_addr)
-{
-       unsigned long paddr = (dma_addr & PAGE_MASK) - PCI64_ADDR_BASE;
-
-       return virt_to_page(__va(paddr));
-}
-
-static inline unsigned long
-pci_dac_dma_to_offset(struct pci_dev *pdev, dma64_addr_t dma_addr)
-{
-       return (dma_addr & ~PAGE_MASK);
-}
-
-static inline void
-pci_dac_dma_sync_single_for_cpu(struct pci_dev *pdev, dma64_addr_t dma_addr, size_t len, int direction)
-{
-       /* DAC cycle addressing does not make use of the
-        * PCI controller's streaming cache, so nothing to do.
-        */
-}
-
-static inline void
-pci_dac_dma_sync_single_for_device(struct pci_dev *pdev, dma64_addr_t dma_addr, size_t len, int direction)
-{
-       /* DAC cycle addressing does not make use of the
-        * PCI controller's streaming cache, so nothing to do.
-        */
-}
-
 #define PCI_DMA_ERROR_CODE     (~(dma_addr_t)0x0)
 
 static inline int pci_dma_mapping_error(dma_addr_t dma_addr)
@@ -303,10 +260,6 @@ pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
 
 extern struct resource *pcibios_select_root(struct pci_dev *, struct resource *);
 
-static inline void pcibios_add_platform_entries(struct pci_dev *dev)
-{
-}
-
 static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
 {
        return PCI_IRQ_NONE;
index 4581826e1cac9dcf170edba22a36d8d143ead3e8..de2a7d0a81cc1d7345b1adc9b37eeb4656023d93 100644 (file)
@@ -116,8 +116,4 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
 extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
 extern void pci_iounmap (struct pci_dev *dev, void __iomem *addr);
 
-static inline void pcibios_add_platform_entries(struct pci_dev *dev)
-{
-}
-
 #endif /* __V850_PCI_H__ */
index 9f7f02cb039127e4045a5dc5fe4d278daa24ed61..e85d261b79bf0ee140ab1f5f349b6b25e100d25d 100644 (file)
@@ -64,7 +64,6 @@
 /* As we don't really support PCI DMA to cpu memory, and use bounce-buffers
    instead, perversely enough, this becomes always true! */
 # define pci_dma_supported(dev, mask)          1
-# define pci_dac_dma_supported(dev, mask)      0
 # define pcibios_assign_all_busses()           1
 
 #endif /* CONFIG_RTE_MB_A_PCI */
index f3b433032089411f272e8c9484a8f54885c8067c..35412f7f3eeac6859b6e2b615ffd0d486c65350c 100644 (file)
@@ -17,6 +17,17 @@ struct termios {
        cc_t c_cc[NCCS];                /* control characters */
 };
 
+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 */
+       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 */
index a094276407647ecbfea524af86ef686133be4f91..eea7aecfac787cef93d9ae09b66745cb313dda06 100644 (file)
@@ -5,6 +5,41 @@
 
 #include <linux/types.h>
 #include <linux/stddef.h>
+
+/*
+ * Alternative inline assembly for SMP.
+ *
+ * The LOCK_PREFIX macro defined here replaces the LOCK and
+ * LOCK_PREFIX macros used everywhere in the source tree.
+ *
+ * SMP alternatives use the same data structures as the other
+ * alternatives and the X86_FEATURE_UP flag to indicate the case of a
+ * UP system running a SMP kernel.  The existing apply_alternatives()
+ * works fine for patching a SMP kernel for UP.
+ *
+ * The SMP alternative tables can be kept after boot and contain both
+ * UP and SMP versions of the instructions to allow switching back to
+ * SMP at runtime, when hotplugging in a new CPU, which is especially
+ * useful in virtualized environments.
+ *
+ * The very common lock prefix is handled as special case in a
+ * separate table which is a pure address list without replacement ptr
+ * and size information.  That keeps the table sizes small.
+ */
+
+#ifdef CONFIG_SMP
+#define LOCK_PREFIX \
+               ".section .smp_locks,\"a\"\n"   \
+               "  .align 8\n"                  \
+               "  .quad 661f\n" /* address */  \
+               ".previous\n"                   \
+               "661:\n\tlock; "
+
+#else /* ! CONFIG_SMP */
+#define LOCK_PREFIX ""
+#endif
+
+/* This must be included *after* the definition of LOCK_PREFIX */
 #include <asm/cpufeature.h>
 
 struct alt_instr {
@@ -108,39 +143,6 @@ static inline void alternatives_smp_switch(int smp) {}
  */
 #define ASM_OUTPUT2(a, b) a, b
 
-/*
- * Alternative inline assembly for SMP.
- *
- * The LOCK_PREFIX macro defined here replaces the LOCK and
- * LOCK_PREFIX macros used everywhere in the source tree.
- *
- * SMP alternatives use the same data structures as the other
- * alternatives and the X86_FEATURE_UP flag to indicate the case of a
- * UP system running a SMP kernel.  The existing apply_alternatives()
- * works fine for patching a SMP kernel for UP.
- *
- * The SMP alternative tables can be kept after boot and contain both
- * UP and SMP versions of the instructions to allow switching back to
- * SMP at runtime, when hotplugging in a new CPU, which is especially
- * useful in virtualized environments.
- *
- * The very common lock prefix is handled as special case in a
- * separate table which is a pure address list without replacement ptr
- * and size information.  That keeps the table sizes small.
- */
-
-#ifdef CONFIG_SMP
-#define LOCK_PREFIX \
-               ".section .smp_locks,\"a\"\n"   \
-               "  .align 8\n"                  \
-               "  .quad 661f\n" /* address */  \
-               ".previous\n"                   \
-               "661:\n\tlock; "
-
-#else /* ! CONFIG_SMP */
-#define LOCK_PREFIX ""
-#endif
-
 struct paravirt_patch;
 #ifdef CONFIG_PARAVIRT
 void apply_paravirt(struct paravirt_patch *start, struct paravirt_patch *end);
index 96b228e6e79cd1c086df76d6c00f7646a06b98f9..3c46cea8db7faabfce09b6aa0dca38f48208ea3e 100644 (file)
@@ -1,15 +1 @@
-#ifndef _LINUX_BOOT_H
-#define _LINUX_BOOT_H
-
-/* Don't touch these, unless you really know what you're doing. */
-#define DEF_INITSEG    0x9000
-#define DEF_SYSSEG     0x1000
-#define DEF_SETUPSEG   0x9020
-#define DEF_SYSSIZE    0x7F00
-
-/* Internal svga startup constants */
-#define NORMAL_VGA     0xffff          /* 80x25 mode */
-#define EXTENDED_VGA   0xfffe          /* 80x50 mode */
-#define ASK_VGA                0xfffd          /* ask for it at bootup */
-
-#endif
+#include <asm-i386/boot.h>
diff --git a/include/asm-x86_64/bootparam.h b/include/asm-x86_64/bootparam.h
new file mode 100644 (file)
index 0000000..aa82e52
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-i386/bootparam.h>
index 0b3c686139f1505340db96be8dc52585f584a9fc..8baefc3beb2e1e7682c6000e7875c96db88c1fd5 100644 (file)
 #ifndef __ASM_X8664_CPUFEATURE_H
 #define __ASM_X8664_CPUFEATURE_H
 
-#define NCAPINTS       7       /* N 32-bit words worth of info */
+#include <asm-i386/cpufeature.h>
 
-/* Intel-defined CPU features, CPUID level 0x00000001, word 0 */
-#define X86_FEATURE_FPU                (0*32+ 0) /* Onboard FPU */
-#define X86_FEATURE_VME                (0*32+ 1) /* Virtual Mode Extensions */
-#define X86_FEATURE_DE         (0*32+ 2) /* Debugging Extensions */
-#define X86_FEATURE_PSE        (0*32+ 3) /* Page Size Extensions */
-#define X86_FEATURE_TSC                (0*32+ 4) /* Time Stamp Counter */
-#define X86_FEATURE_MSR                (0*32+ 5) /* Model-Specific Registers, RDMSR, WRMSR */
-#define X86_FEATURE_PAE                (0*32+ 6) /* Physical Address Extensions */
-#define X86_FEATURE_MCE                (0*32+ 7) /* Machine Check Architecture */
-#define X86_FEATURE_CX8                (0*32+ 8) /* CMPXCHG8 instruction */
-#define X86_FEATURE_APIC       (0*32+ 9) /* Onboard APIC */
-#define X86_FEATURE_SEP                (0*32+11) /* SYSENTER/SYSEXIT */
-#define X86_FEATURE_MTRR       (0*32+12) /* Memory Type Range Registers */
-#define X86_FEATURE_PGE                (0*32+13) /* Page Global Enable */
-#define X86_FEATURE_MCA                (0*32+14) /* Machine Check Architecture */
-#define X86_FEATURE_CMOV       (0*32+15) /* CMOV instruction (FCMOVCC and FCOMI too if FPU present) */
-#define X86_FEATURE_PAT                (0*32+16) /* Page Attribute Table */
-#define X86_FEATURE_PSE36      (0*32+17) /* 36-bit PSEs */
-#define X86_FEATURE_PN         (0*32+18) /* Processor serial number */
-#define X86_FEATURE_CLFLSH     (0*32+19) /* Supports the CLFLUSH instruction */
-#define X86_FEATURE_DS         (0*32+21) /* Debug Store */
-#define X86_FEATURE_ACPI       (0*32+22) /* ACPI via MSR */
-#define X86_FEATURE_MMX                (0*32+23) /* Multimedia Extensions */
-#define X86_FEATURE_FXSR       (0*32+24) /* FXSAVE and FXRSTOR instructions (fast save and restore */
-                                         /* of FPU context), and CR4.OSFXSR available */
-#define X86_FEATURE_XMM                (0*32+25) /* Streaming SIMD Extensions */
-#define X86_FEATURE_XMM2       (0*32+26) /* Streaming SIMD Extensions-2 */
-#define X86_FEATURE_SELFSNOOP  (0*32+27) /* CPU self snoop */
-#define X86_FEATURE_HT         (0*32+28) /* Hyper-Threading */
-#define X86_FEATURE_ACC                (0*32+29) /* Automatic clock control */
-#define X86_FEATURE_IA64       (0*32+30) /* IA-64 processor */
-
-/* AMD-defined CPU features, CPUID level 0x80000001, word 1 */
-/* Don't duplicate feature flags which are redundant with Intel! */
-#define X86_FEATURE_SYSCALL    (1*32+11) /* SYSCALL/SYSRET */
-#define X86_FEATURE_MMXEXT     (1*32+22) /* AMD MMX extensions */
-#define X86_FEATURE_FXSR_OPT   (1*32+25) /* FXSR optimizations */
-#define X86_FEATURE_RDTSCP     (1*32+27) /* RDTSCP */
-#define X86_FEATURE_LM         (1*32+29) /* Long Mode (x86-64) */
-#define X86_FEATURE_3DNOWEXT   (1*32+30) /* AMD 3DNow! extensions */
-#define X86_FEATURE_3DNOW      (1*32+31) /* 3DNow! */
-
-/* Transmeta-defined CPU features, CPUID level 0x80860001, word 2 */
-#define X86_FEATURE_RECOVERY   (2*32+ 0) /* CPU in recovery mode */
-#define X86_FEATURE_LONGRUN    (2*32+ 1) /* Longrun power control */
-#define X86_FEATURE_LRTI       (2*32+ 3) /* LongRun table interface */
-
-/* Other features, Linux-defined mapping, word 3 */
-/* This range is used for feature bits which conflict or are synthesized */
-#define X86_FEATURE_CXMMX      (3*32+ 0) /* Cyrix MMX extensions */
-#define X86_FEATURE_K6_MTRR    (3*32+ 1) /* AMD K6 nonstandard MTRRs */
-#define X86_FEATURE_CYRIX_ARR  (3*32+ 2) /* Cyrix ARRs (= MTRRs) */
-#define X86_FEATURE_CENTAUR_MCR        (3*32+ 3) /* Centaur MCRs (= MTRRs) */
-#define X86_FEATURE_REP_GOOD   (3*32+ 4) /* rep microcode works well on this CPU */
-#define X86_FEATURE_CONSTANT_TSC (3*32+5) /* TSC runs at constant rate */
-#define X86_FEATURE_SYNC_RDTSC  (3*32+6)  /* RDTSC syncs CPU core */
-#define X86_FEATURE_FXSAVE_LEAK (3*32+7)  /* FIP/FOP/FDP leaks through FXSAVE */
-#define X86_FEATURE_UP         (3*32+8) /* SMP kernel running on UP */
-#define X86_FEATURE_ARCH_PERFMON (3*32+9) /* Intel Architectural PerfMon */
-#define X86_FEATURE_PEBS       (3*32+10) /* Precise-Event Based Sampling */
-#define X86_FEATURE_BTS                (3*32+11) /* Branch Trace Store */
-
-/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
-#define X86_FEATURE_XMM3       (4*32+ 0) /* Streaming SIMD Extensions-3 */
-#define X86_FEATURE_MWAIT      (4*32+ 3) /* Monitor/Mwait support */
-#define X86_FEATURE_DSCPL      (4*32+ 4) /* CPL Qualified Debug Store */
-#define X86_FEATURE_EST                (4*32+ 7) /* Enhanced SpeedStep */
-#define X86_FEATURE_TM2                (4*32+ 8) /* Thermal Monitor 2 */
-#define X86_FEATURE_CID                (4*32+10) /* Context ID */
-#define X86_FEATURE_CX16       (4*32+13) /* CMPXCHG16B */
-#define X86_FEATURE_XTPR       (4*32+14) /* Send Task Priority Messages */
-
-/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
-#define X86_FEATURE_XSTORE     (5*32+ 2) /* on-CPU RNG present (xstore insn) */
-#define X86_FEATURE_XSTORE_EN  (5*32+ 3) /* on-CPU RNG enabled */
-#define X86_FEATURE_XCRYPT     (5*32+ 6) /* on-CPU crypto (xcrypt insn) */
-#define X86_FEATURE_XCRYPT_EN  (5*32+ 7) /* on-CPU crypto enabled */
-
-/* More extended AMD flags: CPUID level 0x80000001, ecx, word 6 */
-#define X86_FEATURE_LAHF_LM    (6*32+ 0) /* LAHF/SAHF in long mode */
-#define X86_FEATURE_CMP_LEGACY (6*32+ 1) /* If yes HyperThreading not valid */
-
-#define cpu_has(c, bit)                test_bit(bit, (c)->x86_capability)
-#define boot_cpu_has(bit)      test_bit(bit, boot_cpu_data.x86_capability)
-
-#define cpu_has_fpu            1
+#undef  cpu_has_vme
 #define cpu_has_vme            0
-#define cpu_has_de             1
-#define cpu_has_pse            1
-#define cpu_has_tsc            1
+
+#undef  cpu_has_pae
 #define cpu_has_pae            ___BUG___
-#define cpu_has_pge            1
-#define cpu_has_apic           boot_cpu_has(X86_FEATURE_APIC)
-#define cpu_has_mtrr           1
-#define cpu_has_mmx            1
-#define cpu_has_fxsr           1
-#define cpu_has_xmm            1
-#define cpu_has_xmm2           1
-#define cpu_has_xmm3           boot_cpu_has(X86_FEATURE_XMM3)
-#define cpu_has_ht             boot_cpu_has(X86_FEATURE_HT)
+
+#undef  cpu_has_mp
 #define cpu_has_mp             1 /* XXX */
+
+#undef  cpu_has_k6_mtrr
 #define cpu_has_k6_mtrr        0
+
+#undef  cpu_has_cyrix_arr
 #define cpu_has_cyrix_arr      0
+
+#undef  cpu_has_centaur_mcr
 #define cpu_has_centaur_mcr    0
-#define cpu_has_clflush               boot_cpu_has(X86_FEATURE_CLFLSH)
-#define cpu_has_ds            boot_cpu_has(X86_FEATURE_DS)
-#define cpu_has_pebs          boot_cpu_has(X86_FEATURE_PEBS)
-#define cpu_has_bts           boot_cpu_has(X86_FEATURE_BTS)
 
 #endif /* __ASM_X8664_CPUFEATURE_H */
index 6216fa3f28026b943dedaccb717c8e7edb871edb..3486e701bd8656f5e5a782cf60b892e656509756 100644 (file)
@@ -11,8 +11,6 @@
 #ifndef __E820_HEADER
 #define __E820_HEADER
 
-#include <linux/mmzone.h>
-
 #define E820MAP        0x2d0           /* our map */
 #define E820MAX        128             /* number of entries in E820MAP */
 #define E820NR 0x1e8           /* # entries in E820MAP */
@@ -30,7 +28,7 @@ struct e820entry {
 } __attribute__((packed));
 
 struct e820map {
-    int nr_map;
+       u32 nr_map;
        struct e820entry map[E820MAX];
 };
 
index 49c5e9280598729000a42e07483fa5f21da2b538..bda94fd5176f43a70c431f0079aeb6715d30a78e 100644 (file)
@@ -54,14 +54,6 @@ extern int iommu_setup(char *opt);
 
 #if defined(CONFIG_IOMMU) || defined(CONFIG_CALGARY_IOMMU)
 
-/*
- * x86-64 always supports DAC, but sometimes it is useful to force
- * devices through the IOMMU to get automatic sg list merging.
- * Optional right now.
- */
-extern int iommu_sac_force;
-#define pci_dac_dma_supported(pci_dev, mask)   (!iommu_sac_force)
-
 #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)      \
        dma_addr_t ADDR_NAME;
 #define DECLARE_PCI_UNMAP_LEN(LEN_NAME)                \
@@ -78,8 +70,6 @@ extern int iommu_sac_force;
 #else
 /* No IOMMU */
 
-#define pci_dac_dma_supported(pci_dev, mask)    1
-
 #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
 #define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
 #define pci_unmap_addr(PTR, ADDR_NAME)         (0)
@@ -91,36 +81,6 @@ extern int iommu_sac_force;
 
 #include <asm-generic/pci-dma-compat.h>
 
-static inline dma64_addr_t
-pci_dac_page_to_dma(struct pci_dev *pdev, struct page *page, unsigned long offset, int direction)
-{
-       return ((dma64_addr_t) page_to_phys(page) +
-               (dma64_addr_t) offset);
-}
-
-static inline struct page *
-pci_dac_dma_to_page(struct pci_dev *pdev, dma64_addr_t dma_addr)
-{
-       return virt_to_page(__va(dma_addr));    
-}
-
-static inline unsigned long
-pci_dac_dma_to_offset(struct pci_dev *pdev, dma64_addr_t dma_addr)
-{
-       return (dma_addr & ~PAGE_MASK);
-}
-
-static inline void
-pci_dac_dma_sync_single_for_cpu(struct pci_dev *pdev, dma64_addr_t dma_addr, size_t len, int direction)
-{
-}
-
-static inline void
-pci_dac_dma_sync_single_for_device(struct pci_dev *pdev, dma64_addr_t dma_addr, size_t len, int direction)
-{
-       flush_write_buffers();
-}
-
 #ifdef CONFIG_PCI
 static inline void pci_dma_burst_advice(struct pci_dev *pdev,
                                        enum pci_dma_burst_strategy *strat,
@@ -135,10 +95,6 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
 extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
                               enum pci_mmap_state mmap_state, int write_combine);
 
-static inline void pcibios_add_platform_entries(struct pci_dev *dev)
-{
-}
-
 #endif /* __KERNEL__ */
 
 /* generic pci stuff */
index 461ffe4c1fccca877ac338fdf12489b1b24feada..efc87a5aff7f0f5febf0ff04f87b8f72c4a72c6f 100644 (file)
@@ -100,6 +100,7 @@ extern char ignore_irq13;
 
 extern void identify_cpu(struct cpuinfo_x86 *);
 extern void print_cpu_info(struct cpuinfo_x86 *);
+extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c);
 extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
 extern unsigned short num_cache_leaves;
 
@@ -368,8 +369,6 @@ static inline void sync_core(void)
        asm volatile("cpuid" : "=a" (tmp) : "0" (1) : "ebx","ecx","edx","memory");
 } 
 
-#define cpu_has_fpu 1
-
 #define ARCH_HAS_PREFETCH
 static inline void prefetch(void *x) 
 { 
diff --git a/include/asm-x86_64/required-features.h b/include/asm-x86_64/required-features.h
new file mode 100644 (file)
index 0000000..e80d576
--- /dev/null
@@ -0,0 +1,46 @@
+#ifndef _ASM_REQUIRED_FEATURES_H
+#define _ASM_REQUIRED_FEATURES_H 1
+
+/* Define minimum CPUID feature set for kernel These bits are checked
+   really early to actually display a visible error message before the
+   kernel dies.  Make sure to assign features to the proper mask!
+
+   The real information is in arch/x86_64/Kconfig.cpu, this just converts
+   the CONFIGs into a bitmask */
+
+/* x86-64 baseline features */
+#define NEED_FPU       (1<<(X86_FEATURE_FPU & 31))
+#define NEED_PSE       (1<<(X86_FEATURE_PSE & 31))
+#define NEED_MSR       (1<<(X86_FEATURE_MSR & 31))
+#define NEED_PAE       (1<<(X86_FEATURE_PAE & 31))
+#define NEED_CX8       (1<<(X86_FEATURE_CX8 & 31))
+#define NEED_PGE       (1<<(X86_FEATURE_PGE & 31))
+#define NEED_FXSR      (1<<(X86_FEATURE_FXSR & 31))
+#define NEED_CMOV      (1<<(X86_FEATURE_CMOV & 31))
+#define NEED_XMM       (1<<(X86_FEATURE_XMM & 31))
+#define NEED_XMM2      (1<<(X86_FEATURE_XMM2 & 31))
+
+#define REQUIRED_MASK0 (NEED_FPU|NEED_PSE|NEED_MSR|NEED_PAE|\
+                        NEED_CX8|NEED_PGE|NEED_FXSR|NEED_CMOV|\
+                        NEED_XMM|NEED_XMM2)
+#define SSE_MASK       (NEED_XMM|NEED_XMM2)
+
+/* x86-64 baseline features */
+#define NEED_LM                (1<<(X86_FEATURE_LM & 31))
+
+#ifdef CONFIG_X86_USE_3DNOW
+# define NEED_3DNOW    (1<<(X86_FEATURE_3DNOW & 31))
+#else
+# define NEED_3DNOW    0
+#endif
+
+#define REQUIRED_MASK1 (NEED_LM|NEED_3DNOW)
+
+#define REQUIRED_MASK2 0
+#define REQUIRED_MASK3 0
+#define REQUIRED_MASK4 0
+#define REQUIRED_MASK5 0
+#define REQUIRED_MASK6 0
+#define REQUIRED_MASK7 0
+
+#endif
index adf2bf1e187c341524e69bf7ddc7b8b2b449b9de..04b8ab21328faed255f2cfca4d02f267c9fd5fb3 100644 (file)
@@ -3,6 +3,14 @@
 
 #include <asm/cache.h>
 
+/* Simple and small GDT entries for booting only */
+
+#define GDT_ENTRY_BOOT_CS              2
+#define __BOOT_CS      (GDT_ENTRY_BOOT_CS * 8)
+
+#define GDT_ENTRY_BOOT_DS              (GDT_ENTRY_BOOT_CS + 1)
+#define __BOOT_DS      (GDT_ENTRY_BOOT_DS * 8)
+
 #define __KERNEL_CS    0x10
 #define __KERNEL_DS    0x18
 
index 24eb7fc25da830c8fc4f74ac1b0c11efe1a677b8..66410acf18b439b239fddfd195d38610f2826ebd 100644 (file)
@@ -64,9 +64,6 @@ struct pci_dev;
 #define pci_ubnmap_len(PTR, LEN_NAME)          (0)
 #define pci_unmap_len_set(PTR, LEN_NAME, VAL)  do { } while (0)
 
-/* We cannot access memory above 4GB */
-#define pci_dac_dma_supported(pci_dev, mask)   (0)
-
 /* Map a range of PCI memory or I/O space for a device into user space */
 int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
                         enum pci_mmap_state mmap_state, int write_combine);
@@ -74,10 +71,6 @@ int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
 /* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */
 #define HAVE_PCI_MMAP  1
 
-static inline void pcibios_add_platform_entries(struct pci_dev *dev)
-{
-}
-
 #endif /* __KERNEL__ */
 
 /* Implement the pci_ DMA API in terms of the generic device dma_ one */
index 057b9a3d8f83171114c39cd4dfdff2c02ef4e2f7..9972c25ec86f1d5b204796a8367171e2145ebd5b 100644 (file)
@@ -30,6 +30,17 @@ struct termios {
        cc_t c_cc[NCCS];                /* control characters */
 };
 
+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 */
+       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 */
index f317c270d4bfe9acbefdf3a567f8313480ad4e0e..127d2d192b5a097d3414bb1338f705e4cc165b41 100644 (file)
@@ -49,6 +49,7 @@ header-y += consolemap.h
 header-y += const.h
 header-y += cycx_cfm.h
 header-y += dlm_device.h
+header-y += dlm_netlink.h
 header-y += dm-ioctl.h
 header-y += dn.h
 header-y += dqblk_v1.h
@@ -90,7 +91,6 @@ header-y += in6.h
 header-y += in_route.h
 header-y += ioctl.h
 header-y += ipmi_msgdefs.h
-header-y += ip_mp_alg.h
 header-y += ipsec.h
 header-y += ipx.h
 header-y += irda.h
@@ -225,6 +225,7 @@ unifdef-y += if_fddi.h
 unifdef-y += if_frad.h
 unifdef-y += if_ltalk.h
 unifdef-y += if_link.h
+unifdef-y += if_pppol2tp.h
 unifdef-y += if_pppox.h
 unifdef-y += if_shaper.h
 unifdef-y += if_tr.h
index 402e178b38ebd3dcc999c15b9d90b9c52769de32..509656286e5326e3f10617bea575ad56f5128602 100644 (file)
@@ -13,11 +13,13 @@ extern int pci_enable_pcie_error_reporting(struct pci_dev *dev);
 extern int pci_find_aer_capability(struct pci_dev *dev);
 extern int pci_disable_pcie_error_reporting(struct pci_dev *dev);
 extern int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev);
+extern int pci_cleanup_aer_correct_error_status(struct pci_dev *dev);
 #else
-#define pci_enable_pcie_error_reporting(dev)           do { } while (0)
-#define pci_find_aer_capability(dev)                   do { } while (0)
-#define pci_disable_pcie_error_reporting(dev)          do { } while (0)
-#define pci_cleanup_aer_uncorrect_error_status(dev)    do { } while (0)
+#define pci_enable_pcie_error_reporting(dev)           (-EINVAL)
+#define pci_find_aer_capability(dev)                   (0)
+#define pci_disable_pcie_error_reporting(dev)          (-EINVAL)
+#define pci_cleanup_aer_uncorrect_error_status(dev)    (-EINVAL)
+#define pci_cleanup_aer_correct_error_status(dev)      (-EINVAL)
 #endif
 
 #endif //_AER_H_
index 703febb2df31e248243e7017b6a34828ec23128a..b5a20162af325094a61edf2417b7a3a6a7c66b1f 100644 (file)
@@ -126,6 +126,7 @@ enum {
        ATA_REG_IRQ             = ATA_REG_NSECT,
 
        /* ATA device commands */
+       ATA_CMD_DEV_RESET       = 0x08, /* ATAPI device reset */
        ATA_CMD_CHK_POWER       = 0xE5, /* check power mode */
        ATA_CMD_STANDBY         = 0xE2, /* place in standby power mode */
        ATA_CMD_IDLE            = 0xE3, /* place in idle power mode */
@@ -163,6 +164,8 @@ enum {
        ATA_CMD_SET_MAX         = 0xF9,
        ATA_CMD_SET_MAX_EXT     = 0x37,
        ATA_CMD_READ_LOG_EXT    = 0x2f,
+       ATA_CMD_PMP_READ        = 0xE4,
+       ATA_CMD_PMP_WRITE       = 0xE8,
 
        /* READ_LOG_EXT pages */
        ATA_LOG_SATA_NCQ        = 0x10,
@@ -211,6 +214,28 @@ enum {
                                                   0=to device, 1=to host */
        ATAPI_CDB_LEN           = 16,
 
+       /* PMP stuff */
+       SATA_PMP_MAX_PORTS      = 15,
+       SATA_PMP_CTRL_PORT      = 15,
+
+       SATA_PMP_GSCR_DWORDS    = 128,
+       SATA_PMP_GSCR_PROD_ID   = 0,
+       SATA_PMP_GSCR_REV       = 1,
+       SATA_PMP_GSCR_PORT_INFO = 2,
+       SATA_PMP_GSCR_ERROR     = 32,
+       SATA_PMP_GSCR_ERROR_EN  = 33,
+       SATA_PMP_GSCR_FEAT      = 64,
+       SATA_PMP_GSCR_FEAT_EN   = 96,
+
+       SATA_PMP_PSCR_STATUS    = 0,
+       SATA_PMP_PSCR_ERROR     = 1,
+       SATA_PMP_PSCR_CONTROL   = 2,
+
+       SATA_PMP_FEAT_BIST      = (1 << 0),
+       SATA_PMP_FEAT_PMREQ     = (1 << 1),
+       SATA_PMP_FEAT_DYNSSC    = (1 << 2),
+       SATA_PMP_FEAT_NOTIFY    = (1 << 3),
+
        /* cable types */
        ATA_CBL_NONE            = 0,
        ATA_CBL_PATA40          = 1,
@@ -417,4 +442,9 @@ static inline int lba_48_ok(u64 block, u32 n_block)
        return ((block + n_block - 1) < ((u64)1 << 48)) && (n_block <= 65536);
 }
 
+#define sata_pmp_gscr_vendor(gscr)     ((gscr)[SATA_PMP_GSCR_PROD_ID] & 0xffff)
+#define sata_pmp_gscr_devid(gscr)      ((gscr)[SATA_PMP_GSCR_PROD_ID] >> 16)
+#define sata_pmp_gscr_rev(gscr)                (((gscr)[SATA_PMP_GSCR_REV] >> 8) & 0xff)
+#define sata_pmp_gscr_ports(gscr)      ((gscr)[SATA_PMP_GSCR_PORT_INFO] & 0xf)
+
 #endif /* __LINUX_ATA_H__ */
index db5b00a792f519d7d4dde9a2e4824a2c7f948db9..fae138bd2207b78e86645047938bc72df60a85d6 100644 (file)
@@ -868,11 +868,6 @@ void kblockd_flush_work(struct work_struct *work);
  */
 #define buffer_heads_over_limit 0
 
-static inline long blk_congestion_wait(int rw, long timeout)
-{
-       return io_schedule_timeout(timeout);
-}
-
 static inline long nr_blockdev_pages(void)
 {
        return 0;
index 5a9c49534d08680cee28276d00f503a896800096..104e51e20e14a56b67e97b868e1bf2847d8b1f91 100644 (file)
@@ -38,6 +38,9 @@ struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent,
 
 void debugfs_remove(struct dentry *dentry);
 
+struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
+                struct dentry *new_dir, const char *new_name);
+
 struct dentry *debugfs_create_u8(const char *name, mode_t mode,
                                 struct dentry *parent, u8 *value);
 struct dentry *debugfs_create_u16(const char *name, mode_t mode,
@@ -85,6 +88,12 @@ static inline struct dentry *debugfs_create_symlink(const char *name,
 static inline void debugfs_remove(struct dentry *dentry)
 { }
 
+static inline struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
+                struct dentry *new_dir, char *new_name)
+{
+       return ERR_PTR(-ENODEV);
+}
+
 static inline struct dentry *debugfs_create_u8(const char *name, mode_t mode,
                                               struct dentry *parent,
                                               u8 *value)
index 2e1a2988b7e15a35240c63a5f56928f2145c2ea2..be2debed70d24d6c4558824be4cbb84ffd0d667d 100644 (file)
@@ -238,7 +238,6 @@ extern int __must_check class_device_create_file(struct class_device *,
  * @devt: for internal use by the driver core only.
  * @node: for internal use by the driver core only.
  * @kobj: for internal use by the driver core only.
- * @devt_attr: for internal use by the driver core only.
  * @groups: optional additional groups to be created
  * @dev: if set, a symlink to the struct device is created in the sysfs
  * directory for this struct class device.
@@ -263,8 +262,6 @@ struct class_device {
        struct kobject          kobj;
        struct class            * class;        /* required */
        dev_t                   devt;           /* dev_t, creates the sysfs "dev" */
-       struct class_device_attribute *devt_attr;
-       struct class_device_attribute uevent_attr;
        struct device           * dev;          /* not necessary, but nice to have */
        void                    * class_data;   /* class-specific data */
        struct class_device     *parent;        /* parent of this child device, if there is one */
@@ -419,8 +416,6 @@ struct device {
        struct device_type      *type;
        unsigned                is_registered:1;
        unsigned                uevent_suppress:1;
-       struct device_attribute uevent_attr;
-       struct device_attribute *devt_attr;
 
        struct semaphore        sem;    /* semaphore to synchronize calls to
                                         * its driver.
index 1b1dcb9a40bbab9facb21a13ece1cb23cab28534..be9d278761e0ed5ddbb87653d64f34e9108956cb 100644 (file)
@@ -2,7 +2,7 @@
 *******************************************************************************
 **
 **  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
-**  Copyright (C) 2004-2005 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2004-2007 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
  * Only relevant to locks originating in userspace.  A persistent lock will not
  * be removed if the process holding the lock exits.
  *
- * DLM_LKF_NODLKWT
+ * DLM_LKF_NODLCKWT
+ *
+ * Do not cancel the lock if it gets into conversion deadlock.
+ * Exclude this lock from being monitored due to DLM_LSFL_TIMEWARN.
+ *
  * DLM_LKF_NODLCKBLK
  *
  * net yet implemented
 #define DLM_LKF_ALTPR          0x00008000
 #define DLM_LKF_ALTCW          0x00010000
 #define DLM_LKF_FORCEUNLOCK    0x00020000
+#define DLM_LKF_TIMEOUT                0x00040000
 
 /*
  * Some return codes that are not in errno.h
@@ -199,11 +204,12 @@ struct dlm_lksb {
        char *   sb_lvbptr;
 };
 
+#define DLM_LSFL_NODIR         0x00000001
+#define DLM_LSFL_TIMEWARN      0x00000002
+#define DLM_LSFL_FS            0x00000004
 
 #ifdef __KERNEL__
 
-#define DLM_LSFL_NODIR         0x00000001
-
 /*
  * dlm_new_lockspace
  *
index c2735cab2ebf2966b61f5d932cf1fd77401d978f..9642277a152a2d3d764317d03400a53d2f5eae94 100644 (file)
@@ -2,7 +2,7 @@
 *******************************************************************************
 **
 **  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
-**  Copyright (C) 2004-2005 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2004-2007 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
 #define DLM_USER_LVB_LEN       32
 
 /* Version of the device interface */
-#define DLM_DEVICE_VERSION_MAJOR 5
-#define DLM_DEVICE_VERSION_MINOR 1
+#define DLM_DEVICE_VERSION_MAJOR 6
+#define DLM_DEVICE_VERSION_MINOR 0
 #define DLM_DEVICE_VERSION_PATCH 0
 
 /* struct passed to the lock write */
 struct dlm_lock_params {
        __u8 mode;
        __u8 namelen;
-       __u16 flags;
+       __u16 unused;
+       __u32 flags;
        __u32 lkid;
        __u32 parent;
-        void __user *castparam;
+       __u64 xid;
+       __u64 timeout;
+       void __user *castparam;
        void __user *castaddr;
        void __user *bastparam;
-        void __user *bastaddr;
+       void __user *bastaddr;
        struct dlm_lksb __user *lksb;
        char lvb[DLM_USER_LVB_LEN];
        char name[0];
@@ -62,9 +65,15 @@ struct dlm_write_request {
        } i;
 };
 
+struct dlm_device_version {
+       __u32 version[3];
+};
+
 /* struct read from the "device" fd,
    consists mainly of userspace pointers for the library to use */
+
 struct dlm_lock_result {
+       __u32 version[3];
        __u32 length;
        void __user * user_astaddr;
        void __user * user_astparam;
@@ -83,6 +92,7 @@ struct dlm_lock_result {
 #define DLM_USER_CREATE_LOCKSPACE  4
 #define DLM_USER_REMOVE_LOCKSPACE  5
 #define DLM_USER_PURGE        6
+#define DLM_USER_DEADLOCK     7
 
 /* Arbitrary length restriction */
 #define MAX_LS_NAME_LEN 64
diff --git a/include/linux/dlm_netlink.h b/include/linux/dlm_netlink.h
new file mode 100644 (file)
index 0000000..1927633
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2007 Red Hat, Inc.  All rights reserved.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ */
+
+#ifndef _DLM_NETLINK_H
+#define _DLM_NETLINK_H
+
+enum {
+       DLM_STATUS_WAITING = 1,
+       DLM_STATUS_GRANTED = 2,
+       DLM_STATUS_CONVERT = 3,
+};
+
+#define DLM_LOCK_DATA_VERSION 1
+
+struct dlm_lock_data {
+       uint16_t version;
+       uint32_t lockspace_id;
+       int nodeid;
+       int ownpid;
+       uint32_t id;
+       uint32_t remid;
+       uint64_t xid;
+       int8_t status;
+       int8_t grmode;
+       int8_t rqmode;
+       unsigned long timestamp;
+       int resource_namelen;
+       char resource_name[DLM_RESNAME_MAXLEN];
+};
+
+enum {
+       DLM_CMD_UNSPEC = 0,
+       DLM_CMD_HELLO,          /* user->kernel */
+       DLM_CMD_TIMEOUT,        /* kernel->user */
+       __DLM_CMD_MAX,
+};
+
+#define DLM_CMD_MAX (__DLM_CMD_MAX - 1)
+
+enum {
+       DLM_TYPE_UNSPEC = 0,
+       DLM_TYPE_LOCK,
+       __DLM_TYPE_MAX,
+};
+
+#define DLM_TYPE_MAX (__DLM_TYPE_MAX - 1)
+
+#define DLM_GENL_VERSION 0x1
+#define DLM_GENL_NAME "DLM"
+
+#endif /* _DLM_NETLINK_H */
index 904bf3d2d90bb068bc3837dfc40bf45e65cdddb6..b8ac7b01c45e4964d25ac07cb5c23509ad21621a 100644 (file)
@@ -12,9 +12,17 @@ enum dmi_field {
        DMI_PRODUCT_NAME,
        DMI_PRODUCT_VERSION,
        DMI_PRODUCT_SERIAL,
+       DMI_PRODUCT_UUID,
        DMI_BOARD_VENDOR,
        DMI_BOARD_NAME,
        DMI_BOARD_VERSION,
+       DMI_BOARD_SERIAL,
+       DMI_BOARD_ASSET_TAG,
+       DMI_CHASSIS_VENDOR,
+       DMI_CHASSIS_TYPE,
+       DMI_CHASSIS_VERSION,
+       DMI_CHASSIS_SERIAL,
+       DMI_CHASSIS_ASSET_TAG,
        DMI_STRING_MAX,
 };
 
index b2b3e68aa5128b1076233547627df096e5200ed2..7b647822d6dc67f6d95e003455076e80c98a156c 100644 (file)
 #define EDD_MBR_SIG_MAX 16        /* max number of signatures to store */
 #define EDD_MBR_SIG_NR_BUF 0x1ea  /* addr of number of MBR signtaures at EDD_MBR_SIG_BUF
                                     in boot_params - treat this as 1 byte  */
-#define EDD_CL_EQUALS   0x3d646465     /* "edd=" */
-#define EDD_CL_OFF      0x666f         /* "of" for off  */
-#define EDD_CL_SKIP     0x6b73         /* "sk" for skipmbr */
-#define EDD_CL_ON       0x6e6f        /* "on" for on */
 
 #ifndef __ASSEMBLY__
 
diff --git a/include/linux/eeprom_93cx6.h b/include/linux/eeprom_93cx6.h
new file mode 100644 (file)
index 0000000..d774b77
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+       Copyright (C) 2004 - 2006 rt2x00 SourceForge Project
+       <http://rt2x00.serialmonkey.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.
+ */
+
+/*
+       Module: eeprom_93cx6
+       Abstract: EEPROM reader datastructures for 93cx6 chipsets.
+       Supported chipsets: 93c46 & 93c66.
+ */
+
+/*
+ * EEPROM operation defines.
+ */
+#define PCI_EEPROM_WIDTH_93C46 6
+#define PCI_EEPROM_WIDTH_93C66 8
+#define PCI_EEPROM_WIDTH_OPCODE        3
+#define PCI_EEPROM_WRITE_OPCODE        0x05
+#define PCI_EEPROM_READ_OPCODE 0x06
+#define PCI_EEPROM_EWDS_OPCODE 0x10
+#define PCI_EEPROM_EWEN_OPCODE 0x13
+
+/**
+ * struct eeprom_93cx6 - control structure for setting the commands
+ * for reading the eeprom data.
+ * @data: private pointer for the driver.
+ * @register_read(struct eeprom_93cx6 *eeprom): handler to
+ * read the eeprom register, this function should set all reg_* fields.
+ * @register_write(struct eeprom_93cx6 *eeprom): handler to
+ * write to the eeprom register by using all reg_* fields.
+ * @width: eeprom width, should be one of the PCI_EEPROM_WIDTH_* defines
+ * @reg_data_in: register field to indicate data input
+ * @reg_data_out: register field to indicate data output
+ * @reg_data_clock: register field to set the data clock
+ * @reg_chip_select: register field to set the chip select
+ *
+ * This structure is used for the communication between the driver
+ * and the eeprom_93cx6 handlers for reading the eeprom.
+ */
+struct eeprom_93cx6 {
+       void *data;
+
+       void (*register_read)(struct eeprom_93cx6 *eeprom);
+       void (*register_write)(struct eeprom_93cx6 *eeprom);
+
+       int width;
+
+       char reg_data_in;
+       char reg_data_out;
+       char reg_data_clock;
+       char reg_chip_select;
+};
+
+extern void eeprom_93cx6_read(struct eeprom_93cx6 *eeprom,
+       const u8 word, u16 *data);
+extern void eeprom_93cx6_multiread(struct eeprom_93cx6 *eeprom,
+       const u8 word, __le16 *data, const u16 words);
index 071c67abed86163d37d82b149ee5c52588de3a0b..6cdb97365e4734abde2ab88a04f9745661385912 100644 (file)
@@ -39,13 +39,8 @@ extern void          eth_header_cache_update(struct hh_cache *hh, struct net_device *dev
 extern int             eth_header_cache(struct neighbour *neigh,
                                         struct hh_cache *hh);
 
-extern struct net_device *alloc_etherdev(int sizeof_priv);
-static inline void eth_copy_and_sum (struct sk_buff *dest, 
-                                    const unsigned char *src, 
-                                    int len, int base)
-{
-       memcpy (dest->data, src, len);
-}
+extern struct net_device *alloc_etherdev_mq(int sizeof_priv, unsigned int queue_count);
+#define alloc_etherdev(sizeof_priv) alloc_etherdev_mq(sizeof_priv, 1)
 
 /**
  * is_zero_ether_addr - Determine if give Ethernet address is all zeros.
index efbe1fda1a22f0c769f9e103d39317568d597de2..1a45d6f41b090e25447d8766114ddf68d74bd2f1 100644 (file)
 #define FW_CDEV_EVENT_REQUEST          0x02
 #define FW_CDEV_EVENT_ISO_INTERRUPT    0x03
 
-/* The 'closure' fields are for user space to use.  Data passed in the
- * 'closure' field for a request will be returned in the corresponding
- * event.  It's a 64-bit type so that it's a fixed size type big
- * enough to hold a pointer on all platforms. */
-
+/**
+ * struct fw_cdev_event_common - Common part of all fw_cdev_event_ types
+ * @closure:   For arbitrary use by userspace
+ * @type:      Discriminates the fw_cdev_event_ types
+ *
+ * This struct may be used to access generic members of all fw_cdev_event_
+ * types regardless of the specific type.
+ *
+ * Data passed in the @closure field for a request will be returned in the
+ * corresponding event.  It is big enough to hold a pointer on all platforms.
+ * The ioctl used to set @closure depends on the @type of event.
+ */
 struct fw_cdev_event_common {
        __u64 closure;
        __u32 type;
 };
 
+/**
+ * struct fw_cdev_event_bus_reset - Sent when a bus reset occurred
+ * @closure:   See &fw_cdev_event_common; set by %FW_CDEV_IOC_GET_INFO ioctl
+ * @type:      See &fw_cdev_event_common; always %FW_CDEV_EVENT_BUS_RESET
+ * @node_id:       New node ID of this node
+ * @local_node_id: Node ID of the local node, i.e. of the controller
+ * @bm_node_id:    Node ID of the bus manager
+ * @irm_node_id:   Node ID of the iso resource manager
+ * @root_node_id:  Node ID of the root node
+ * @generation:    New bus generation
+ *
+ * This event is sent when the bus the device belongs to goes through a bus
+ * reset.  It provides information about the new bus configuration, such as
+ * new node ID for this device, new root ID, and others.
+ */
 struct fw_cdev_event_bus_reset {
        __u64 closure;
        __u32 type;
@@ -51,6 +73,20 @@ struct fw_cdev_event_bus_reset {
        __u32 generation;
 };
 
+/**
+ * struct fw_cdev_event_response - Sent when a response packet was received
+ * @closure:   See &fw_cdev_event_common;
+ *             set by %FW_CDEV_IOC_SEND_REQUEST ioctl
+ * @type:      See &fw_cdev_event_common; always %FW_CDEV_EVENT_RESPONSE
+ * @rcode:     Response code returned by the remote node
+ * @length:    Data length, i.e. the response's payload size in bytes
+ * @data:      Payload data, if any
+ *
+ * This event is sent when the stack receives a response to an outgoing request
+ * sent by %FW_CDEV_IOC_SEND_REQUEST ioctl.  The payload data for responses
+ * carrying data (read and lock responses) follows immediately and can be
+ * accessed through the @data field.
+ */
 struct fw_cdev_event_response {
        __u64 closure;
        __u32 type;
@@ -59,6 +95,25 @@ struct fw_cdev_event_response {
        __u32 data[0];
 };
 
+/**
+ * struct fw_cdev_event_request - Sent on incoming request to an address region
+ * @closure:   See &fw_cdev_event_common; set by %FW_CDEV_IOC_ALLOCATE ioctl
+ * @type:      See &fw_cdev_event_common; always %FW_CDEV_EVENT_REQUEST
+ * @tcode:     Transaction code of the incoming request
+ * @offset:    The offset into the 48-bit per-node address space
+ * @handle:    Reference to the kernel-side pending request
+ * @length:    Data length, i.e. the request's payload size in bytes
+ * @data:      Incoming data, if any
+ *
+ * This event is sent when the stack receives an incoming request to an address
+ * region registered using the %FW_CDEV_IOC_ALLOCATE ioctl.  The request is
+ * guaranteed to be completely contained in the specified region.  Userspace is
+ * responsible for sending the response by %FW_CDEV_IOC_SEND_RESPONSE ioctl,
+ * using the same @handle.
+ *
+ * The payload data for requests carrying data (write and lock requests)
+ * follows immediately and can be accessed through the @data field.
+ */
 struct fw_cdev_event_request {
        __u64 closure;
        __u32 type;
@@ -69,14 +124,39 @@ struct fw_cdev_event_request {
        __u32 data[0];
 };
 
+/**
+ * struct fw_cdev_event_iso_interrupt - Sent when an iso packet was completed
+ * @closure:   See &fw_cdev_event_common;
+ *             set by %FW_CDEV_CREATE_ISO_CONTEXT ioctl
+ * @type:      See &fw_cdev_event_common; always %FW_CDEV_EVENT_ISO_INTERRUPT
+ * @cycle:     Cycle counter of the interrupt packet
+ * @header_length: Total length of following headers, in bytes
+ * @header:    Stripped headers, if any
+ *
+ * This event is sent when the controller has completed an &fw_cdev_iso_packet
+ * with the %FW_CDEV_ISO_INTERRUPT bit set.  In the receive case, the headers
+ * stripped of all packets up until and including the interrupt packet are
+ * returned in the @header field.
+ */
 struct fw_cdev_event_iso_interrupt {
        __u64 closure;
        __u32 type;
        __u32 cycle;
-       __u32 header_length;    /* Length in bytes of following headers. */
+       __u32 header_length;
        __u32 header[0];
 };
 
+/**
+ * union fw_cdev_event - Convenience union of fw_cdev_event_ types
+ * @common:        Valid for all types
+ * @bus_reset:     Valid if @common.type == %FW_CDEV_EVENT_BUS_RESET
+ * @response:      Valid if @common.type == %FW_CDEV_EVENT_RESPONSE
+ * @request:       Valid if @common.type == %FW_CDEV_EVENT_REQUEST
+ * @iso_interrupt: Valid if @common.type == %FW_CDEV_EVENT_ISO_INTERRUPT
+ *
+ * Convenience union for userspace use.  Events could be read(2) into a char
+ * buffer and then cast to this union for further processing.
+ */
 union fw_cdev_event {
        struct fw_cdev_event_common common;
        struct fw_cdev_event_bus_reset bus_reset;
@@ -105,35 +185,47 @@ union fw_cdev_event {
  */
 #define FW_CDEV_VERSION                1
 
+/**
+ * struct fw_cdev_get_info - General purpose information ioctl
+ * @version:   The version field is just a running serial number.
+ *             We never break backwards compatibility, but may add more
+ *             structs and ioctls in later revisions.
+ * @rom_length:        If @rom is non-zero, at most rom_length bytes of configuration
+ *             ROM will be copied into that user space address.  In either
+ *             case, @rom_length is updated with the actual length of the
+ *             configuration ROM.
+ * @rom:       If non-zero, address of a buffer to be filled by a copy of the
+ *             local node's configuration ROM
+ * @bus_reset: If non-zero, address of a buffer to be filled by a
+ *             &struct fw_cdev_event_bus_reset with the current state
+ *             of the bus.  This does not cause a bus reset to happen.
+ * @bus_reset_closure: Value of &closure in this and subsequent bus reset events
+ * @card:      The index of the card this device belongs to
+ */
 struct fw_cdev_get_info {
-       /* The version field is just a running serial number.  We
-        * never break backwards compatibility.  Userspace passes in
-        * the version it expects and the kernel passes back the
-        * highest version it can provide.  Even if the structs in
-        * this interface are extended in a later version, the kernel
-        * will not copy back more data than what was present in the
-        * interface version userspace expects. */
        __u32 version;
-
-       /* If non-zero, at most rom_length bytes of config rom will be
-        * copied into that user space address.  In either case,
-        * rom_length is updated with the actual length of the config
-        * rom. */
        __u32 rom_length;
        __u64 rom;
-
-       /* If non-zero, a fw_cdev_event_bus_reset struct will be
-        * copied here with the current state of the bus.  This does
-        * not cause a bus reset to happen.  The value of closure in
-        * this and sub-sequent bus reset events is set to
-        * bus_reset_closure. */
        __u64 bus_reset;
        __u64 bus_reset_closure;
-
-       /* The index of the card this devices belongs to. */
        __u32 card;
 };
 
+/**
+ * struct fw_cdev_send_request - Send an asynchronous request packet
+ * @tcode:     Transaction code of the request
+ * @length:    Length of outgoing payload, in bytes
+ * @offset:    48-bit offset at destination node
+ * @closure:   Passed back to userspace in the response event
+ * @data:      Userspace pointer to payload
+ * @generation:        The bus generation where packet is valid
+ *
+ * Send a request to the device.  This ioctl implements all outgoing requests.
+ * Both quadlet and block request specify the payload as a pointer to the data
+ * in the @data field.  Once the transaction completes, the kernel writes an
+ * &fw_cdev_event_request event back.  The @closure field is passed back to
+ * user space in the response event.
+ */
 struct fw_cdev_send_request {
        __u32 tcode;
        __u32 length;
@@ -143,6 +235,19 @@ struct fw_cdev_send_request {
        __u32 generation;
 };
 
+/**
+ * struct fw_cdev_send_response - Send an asynchronous response packet
+ * @rcode:     Response code as determined by the userspace handler
+ * @length:    Length of outgoing payload, in bytes
+ * @data:      Userspace pointer to payload
+ * @handle:    The handle from the &fw_cdev_event_request
+ *
+ * Send a response to an incoming request.  By setting up an address range using
+ * the %FW_CDEV_IOC_ALLOCATE ioctl, userspace can listen for incoming requests.  An
+ * incoming request will generate an %FW_CDEV_EVENT_REQUEST, and userspace must
+ * send a reply using this ioctl.  The event has a handle to the kernel-side
+ * pending transaction, which should be used with this ioctl.
+ */
 struct fw_cdev_send_response {
        __u32 rcode;
        __u32 length;
@@ -150,6 +255,21 @@ struct fw_cdev_send_response {
        __u32 handle;
 };
 
+/**
+ * struct fw_cdev_allocate - Allocate a CSR address range
+ * @offset:    Start offset of the address range
+ * @closure:   To be passed back to userspace in request events
+ * @length:    Length of the address range, in bytes
+ * @handle:    Handle to the allocation, written by the kernel
+ *
+ * Allocate an address range in the 48-bit address space on the local node
+ * (the controller).  This allows userspace to listen for requests with an
+ * offset within that address range.  When the kernel receives a request
+ * within the range, an &fw_cdev_event_request event will be written back.
+ * The @closure field is passed back to userspace in the response event.
+ * The @handle field is an out parameter, returning a handle to the allocated
+ * range to be used for later deallocation of the range.
+ */
 struct fw_cdev_allocate {
        __u64 offset;
        __u64 closure;
@@ -157,6 +277,11 @@ struct fw_cdev_allocate {
        __u32 handle;
 };
 
+/**
+ * struct fw_cdev_deallocate - Free an address range allocation
+ * @handle:    Handle to the address range, as returned by the kernel when the
+ *             range was allocated
+ */
 struct fw_cdev_deallocate {
        __u32 handle;
 };
@@ -164,10 +289,41 @@ struct fw_cdev_deallocate {
 #define FW_CDEV_LONG_RESET     0
 #define FW_CDEV_SHORT_RESET    1
 
+/**
+ * struct fw_cdev_initiate_bus_reset - Initiate a bus reset
+ * @type:      %FW_CDEV_SHORT_RESET or %FW_CDEV_LONG_RESET
+ *
+ * Initiate a bus reset for the bus this device is on.  The bus reset can be
+ * either the original (long) bus reset or the arbitrated (short) bus reset
+ * introduced in 1394a-2000.
+ */
 struct fw_cdev_initiate_bus_reset {
-       __u32 type;
+       __u32 type;     /* FW_CDEV_SHORT_RESET or FW_CDEV_LONG_RESET */
 };
 
+/**
+ * struct fw_cdev_add_descriptor - Add contents to the local node's config ROM
+ * @immediate: If non-zero, immediate key to insert before pointer
+ * @key:       Upper 8 bits of root directory pointer
+ * @data:      Userspace pointer to contents of descriptor block
+ * @length:    Length of descriptor block data, in bytes
+ * @handle:    Handle to the descriptor, written by the kernel
+ *
+ * Add a descriptor block and optionally a preceding immediate key to the local
+ * node's configuration ROM.
+ *
+ * The @key field specifies the upper 8 bits of the descriptor root directory
+ * pointer and the @data and @length fields specify the contents. The @key
+ * should be of the form 0xXX000000. The offset part of the root directory entry
+ * will be filled in by the kernel.
+ *
+ * If not 0, the @immediate field specifies an immediate key which will be
+ * inserted before the root directory pointer.
+ *
+ * If successful, the kernel adds the descriptor and writes back a handle to the
+ * kernel-side object to be used for later removal of the descriptor block and
+ * immediate key.
+ */
 struct fw_cdev_add_descriptor {
        __u32 immediate;
        __u32 key;
@@ -176,6 +332,14 @@ struct fw_cdev_add_descriptor {
        __u32 handle;
 };
 
+/**
+ * struct fw_cdev_remove_descriptor - Remove contents from the configuration ROM
+ * @handle:    Handle to the descriptor, as returned by the kernel when the
+ *             descriptor was added
+ *
+ * Remove a descriptor block and accompanying immediate key from the local
+ * node's configuration ROM.
+ */
 struct fw_cdev_remove_descriptor {
        __u32 handle;
 };
@@ -183,12 +347,24 @@ struct fw_cdev_remove_descriptor {
 #define FW_CDEV_ISO_CONTEXT_TRANSMIT   0
 #define FW_CDEV_ISO_CONTEXT_RECEIVE    1
 
-#define FW_CDEV_ISO_CONTEXT_MATCH_TAG0          1
-#define FW_CDEV_ISO_CONTEXT_MATCH_TAG1          2
-#define FW_CDEV_ISO_CONTEXT_MATCH_TAG2          4
-#define FW_CDEV_ISO_CONTEXT_MATCH_TAG3          8
-#define FW_CDEV_ISO_CONTEXT_MATCH_ALL_TAGS     15
-
+/**
+ * struct fw_cdev_create_iso_context - Create a context for isochronous IO
+ * @type:      %FW_CDEV_ISO_CONTEXT_TRANSMIT or %FW_CDEV_ISO_CONTEXT_RECEIVE
+ * @header_size: Header size to strip for receive contexts
+ * @channel:   Channel to bind to
+ * @speed:     Speed to transmit at
+ * @closure:   To be returned in &fw_cdev_event_iso_interrupt
+ * @handle:    Handle to context, written back by kernel
+ *
+ * Prior to sending or receiving isochronous I/O, a context must be created.
+ * The context records information about the transmit or receive configuration
+ * and typically maps to an underlying hardware resource.  A context is set up
+ * for either sending or receiving.  It is bound to a specific isochronous
+ * channel.
+ *
+ * If a context was successfully created, the kernel writes back a handle to the
+ * context, which must be passed in for subsequent operations on that context.
+ */
 struct fw_cdev_create_iso_context {
        __u32 type;
        __u32 header_size;
@@ -201,15 +377,49 @@ struct fw_cdev_create_iso_context {
 #define FW_CDEV_ISO_PAYLOAD_LENGTH(v)  (v)
 #define FW_CDEV_ISO_INTERRUPT          (1 << 16)
 #define FW_CDEV_ISO_SKIP               (1 << 17)
+#define FW_CDEV_ISO_SYNC               (1 << 17)
 #define FW_CDEV_ISO_TAG(v)             ((v) << 18)
 #define FW_CDEV_ISO_SY(v)              ((v) << 20)
 #define FW_CDEV_ISO_HEADER_LENGTH(v)   ((v) << 24)
 
+/**
+ * struct fw_cdev_iso_packet - Isochronous packet
+ * @control:   Contains the header length (8 uppermost bits), the sy field
+ *             (4 bits), the tag field (2 bits), a sync flag (1 bit),
+ *             a skip flag (1 bit), an interrupt flag (1 bit), and the
+ *             payload length (16 lowermost bits)
+ * @header:    Header and payload
+ *
+ * &struct fw_cdev_iso_packet is used to describe isochronous packet queues.
+ *
+ * Use the FW_CDEV_ISO_ macros to fill in @control.  The sy and tag fields are
+ * specified by IEEE 1394a and IEC 61883.
+ *
+ * FIXME - finish this documentation
+ */
 struct fw_cdev_iso_packet {
        __u32 control;
        __u32 header[0];
 };
 
+/**
+ * struct fw_cdev_queue_iso - Queue isochronous packets for I/O
+ * @packets:   Userspace pointer to packet data
+ * @data:      Pointer into mmap()'ed payload buffer
+ * @size:      Size of packet data in bytes
+ * @handle:    Isochronous context handle
+ *
+ * Queue a number of isochronous packets for reception or transmission.
+ * This ioctl takes a pointer to an array of &fw_cdev_iso_packet structs,
+ * which describe how to transmit from or receive into a contiguous region
+ * of a mmap()'ed payload buffer.  As part of the packet descriptors,
+ * a series of headers can be supplied, which will be prepended to the
+ * payload during DMA.
+ *
+ * The kernel may or may not queue all packets, but will write back updated
+ * values of the @packets, @data and @size fields, so the ioctl can be
+ * resubmitted easily.
+ */
 struct fw_cdev_queue_iso {
        __u64 packets;
        __u64 data;
@@ -217,6 +427,23 @@ struct fw_cdev_queue_iso {
        __u32 handle;
 };
 
+#define FW_CDEV_ISO_CONTEXT_MATCH_TAG0          1
+#define FW_CDEV_ISO_CONTEXT_MATCH_TAG1          2
+#define FW_CDEV_ISO_CONTEXT_MATCH_TAG2          4
+#define FW_CDEV_ISO_CONTEXT_MATCH_TAG3          8
+#define FW_CDEV_ISO_CONTEXT_MATCH_ALL_TAGS     15
+
+/**
+ * struct fw_cdev_start_iso - Start an isochronous transmission or reception
+ * @cycle:     Cycle in which to start I/O.  If @cycle is greater than or
+ *             equal to 0, the I/O will start on that cycle.
+ * @sync:      Determines the value to wait for for receive packets that have
+ *             the %FW_CDEV_ISO_SYNC bit set
+ * @tags:      Tag filter bit mask.  Only valid for isochronous reception.
+ *             Determines the tag values for which packets will be accepted.
+ *             Use FW_CDEV_ISO_CONTEXT_MATCH_ macros to set @tags.
+ * @handle:    Isochronous context handle within which to transmit or receive
+ */
 struct fw_cdev_start_iso {
        __s32 cycle;
        __u32 sync;
@@ -224,6 +451,10 @@ struct fw_cdev_start_iso {
        __u32 handle;
 };
 
+/**
+ * struct fw_cdev_stop_iso - Stop an isochronous transmission or reception
+ * @handle:    Handle of isochronous context to stop
+ */
 struct fw_cdev_stop_iso {
        __u32 handle;
 };
index 6a41f4cab14c9a6efa90c824006497a55a230a19..4f0b3bf5983c81fb495794d09b9b5e7c632b17dd 100644 (file)
@@ -1054,7 +1054,7 @@ struct block_device_operations {
 };
 
 /*
- * "descriptor" for what we're up to with a read for sendfile().
+ * "descriptor" for what we're up to with a read.
  * This allows us to use the same read code yet
  * have multiple different users of the data that
  * we read from a file.
@@ -1105,7 +1105,6 @@ struct file_operations {
        int (*aio_fsync) (struct kiocb *, int datasync);
        int (*fasync) (int, struct file *, int);
        int (*lock) (struct file *, int, struct file_lock *);
-       ssize_t (*sendfile) (struct file *, loff_t *, size_t, read_actor_t, void *);
        ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
        unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
        int (*check_flags)(int);
@@ -1762,7 +1761,6 @@ extern ssize_t generic_file_buffered_write(struct kiocb *, const struct iovec *,
                unsigned long, loff_t, loff_t *, size_t, ssize_t);
 extern ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos);
 extern ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos);
-extern ssize_t generic_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *);
 extern void do_generic_mapping_read(struct address_space *mapping,
                                    struct file_ra_state *, struct file *,
                                    loff_t *, read_descriptor_t *, read_actor_t);
@@ -1792,9 +1790,6 @@ extern int nonseekable_open(struct inode * inode, struct file * filp);
 #ifdef CONFIG_FS_XIP
 extern ssize_t xip_file_read(struct file *filp, char __user *buf, size_t len,
                             loff_t *ppos);
-extern ssize_t xip_file_sendfile(struct file *in_file, loff_t *ppos,
-                                size_t count, read_actor_t actor,
-                                void *target);
 extern int xip_file_mmap(struct file * file, struct vm_area_struct * vma);
 extern ssize_t xip_file_write(struct file *filp, const char __user *buf,
                              size_t len, loff_t *ppos);
index 8b7e4c1e32ae2c8f80d2f8182e2452add7c18451..a44a6a078f0a68b487ff6d049c71b6ceea154a05 100644 (file)
@@ -54,18 +54,6 @@ struct gfs2_inum {
        __be64 no_addr;
 };
 
-struct gfs2_inum_host {
-       __u64 no_formal_ino;
-       __u64 no_addr;
-};
-
-static inline int gfs2_inum_equal(const struct gfs2_inum_host *ino1,
-                                 const struct gfs2_inum_host *ino2)
-{
-       return ino1->no_formal_ino == ino2->no_formal_ino &&
-              ino1->no_addr == ino2->no_addr;
-}
-
 /*
  * Generic metadata head structure
  * Every inplace buffer logged in the journal must start with this.
@@ -94,12 +82,6 @@ struct gfs2_meta_header {
        __be32 __pad1;          /* Was incarnation number in gfs1 */
 };
 
-struct gfs2_meta_header_host {
-       __u32 mh_magic;
-       __u32 mh_type;
-       __u32 mh_format;
-};
-
 /*
  * super-block structure
  *
@@ -139,23 +121,6 @@ struct gfs2_sb {
        /* In gfs1, quota and license dinodes followed */
 };
 
-struct gfs2_sb_host {
-       struct gfs2_meta_header_host sb_header;
-
-       __u32 sb_fs_format;
-       __u32 sb_multihost_format;
-
-       __u32 sb_bsize;
-       __u32 sb_bsize_shift;
-
-       struct gfs2_inum_host sb_master_dir; /* Was jindex dinode in gfs1 */
-       struct gfs2_inum_host sb_root_dir;
-
-       char sb_lockproto[GFS2_LOCKNAME_LEN];
-       char sb_locktable[GFS2_LOCKNAME_LEN];
-       /* In gfs1, quota and license dinodes followed */
-};
-
 /*
  * resource index structure
  */
@@ -173,14 +138,6 @@ struct gfs2_rindex {
        __u8 ri_reserved[64];
 };
 
-struct gfs2_rindex_host {
-       __u64 ri_addr;  /* grp block disk address */
-       __u64 ri_data0; /* first data location */
-       __u32 ri_length;        /* length of rgrp header in fs blocks */
-       __u32 ri_data;  /* num of data blocks in rgrp */
-       __u32 ri_bitbytes;      /* number of bytes in data bitmaps */
-};
-
 /*
  * resource group header structure
  */
@@ -212,13 +169,6 @@ struct gfs2_rgrp {
        __u8 rg_reserved[80]; /* Several fields from gfs1 now reserved */
 };
 
-struct gfs2_rgrp_host {
-       __u32 rg_flags;
-       __u32 rg_free;
-       __u32 rg_dinodes;
-       __u64 rg_igeneration;
-};
-
 /*
  * quota structure
  */
@@ -230,12 +180,6 @@ struct gfs2_quota {
        __u8 qu_reserved[64];
 };
 
-struct gfs2_quota_host {
-       __u64 qu_limit;
-       __u64 qu_warn;
-       __u64 qu_value;
-};
-
 /*
  * dinode structure
  */
@@ -315,29 +259,11 @@ struct gfs2_dinode {
        struct gfs2_inum __pad4; /* Unused even in current gfs1 */
 
        __be64 di_eattr;        /* extended attribute block number */
+       __be32 di_atime_nsec;   /* nsec portion of atime */
+       __be32 di_mtime_nsec;   /* nsec portion of mtime */
+       __be32 di_ctime_nsec;   /* nsec portion of ctime */
 
-       __u8 di_reserved[56];
-};
-
-struct gfs2_dinode_host {
-       __u64 di_size;  /* number of bytes in file */
-       __u64 di_blocks;        /* number of blocks in file */
-
-       /* This section varies from gfs1. Padding added to align with
-         * remainder of dinode
-        */
-       __u64 di_goal_meta;     /* rgrp to alloc from next */
-       __u64 di_goal_data;     /* data block goal */
-       __u64 di_generation;    /* generation number for NFS */
-
-       __u32 di_flags; /* GFS2_DIF_... */
-       __u16 di_height;        /* height of metadata */
-
-       /* These only apply to directories  */
-       __u16 di_depth; /* Number of bits in the table */
-       __u32 di_entries;       /* The number of entries in the directory */
-
-       __u64 di_eattr; /* extended attribute block number */
+       __u8 di_reserved[44];
 };
 
 /*
@@ -414,16 +340,6 @@ struct gfs2_log_header {
        __be32 lh_hash;
 };
 
-struct gfs2_log_header_host {
-       struct gfs2_meta_header_host lh_header;
-
-       __u64 lh_sequence;      /* Sequence number of this transaction */
-       __u32 lh_flags; /* GFS2_LOG_HEAD_... */
-       __u32 lh_tail;          /* Block number of log tail */
-       __u32 lh_blkno;
-       __u32 lh_hash;
-};
-
 /*
  * Log type descriptor
  */
@@ -464,11 +380,6 @@ struct gfs2_inum_range {
        __be64 ir_length;
 };
 
-struct gfs2_inum_range_host {
-       __u64 ir_start;
-       __u64 ir_length;
-};
-
 /*
  * Statfs change
  * Describes an change to the pool of free and allocated
@@ -481,12 +392,6 @@ struct gfs2_statfs_change {
        __be64 sc_dinodes;
 };
 
-struct gfs2_statfs_change_host {
-       __u64 sc_total;
-       __u64 sc_free;
-       __u64 sc_dinodes;
-};
-
 /*
  * Quota change
  * Describes an allocation change for a particular
@@ -501,39 +406,12 @@ struct gfs2_quota_change {
        __be32 qc_id;
 };
 
-struct gfs2_quota_change_host {
-       __u64 qc_change;
-       __u32 qc_flags; /* GFS2_QCF_... */
-       __u32 qc_id;
+struct gfs2_quota_lvb {
+        __be32 qb_magic;
+        __u32 __pad;
+        __be64 qb_limit;      /* Hard limit of # blocks to alloc */
+        __be64 qb_warn;       /* Warn user when alloc is above this # */
+        __be64 qb_value;       /* Current # blocks allocated */
 };
 
-#ifdef __KERNEL__
-/* Translation functions */
-
-extern void gfs2_inum_in(struct gfs2_inum_host *no, const void *buf);
-extern void gfs2_inum_out(const struct gfs2_inum_host *no, void *buf);
-extern void gfs2_sb_in(struct gfs2_sb_host *sb, const void *buf);
-extern void gfs2_rindex_in(struct gfs2_rindex_host *ri, const void *buf);
-extern void gfs2_rindex_out(const struct gfs2_rindex_host *ri, void *buf);
-extern void gfs2_rgrp_in(struct gfs2_rgrp_host *rg, const void *buf);
-extern void gfs2_rgrp_out(const struct gfs2_rgrp_host *rg, void *buf);
-extern void gfs2_quota_in(struct gfs2_quota_host *qu, const void *buf);
-struct gfs2_inode;
-extern void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf);
-extern void gfs2_ea_header_in(struct gfs2_ea_header *ea, const void *buf);
-extern void gfs2_ea_header_out(const struct gfs2_ea_header *ea, void *buf);
-extern void gfs2_log_header_in(struct gfs2_log_header_host *lh, const void *buf);
-extern void gfs2_inum_range_in(struct gfs2_inum_range_host *ir, const void *buf);
-extern void gfs2_inum_range_out(const struct gfs2_inum_range_host *ir, void *buf);
-extern void gfs2_statfs_change_in(struct gfs2_statfs_change_host *sc, const void *buf);
-extern void gfs2_statfs_change_out(const struct gfs2_statfs_change_host *sc, void *buf);
-extern void gfs2_quota_change_in(struct gfs2_quota_change_host *qc, const void *buf);
-
-/* Printing functions */
-
-extern void gfs2_rindex_print(const struct gfs2_rindex_host *ri);
-extern void gfs2_dinode_print(const struct gfs2_inode *ip);
-
-#endif /* __KERNEL__ */
-
 #endif /* __GFS2_ONDISK_DOT_H__ */
diff --git a/include/linux/gpio_mouse.h b/include/linux/gpio_mouse.h
new file mode 100644 (file)
index 0000000..44ed7aa
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Driver for simulating a mouse on GPIO lines.
+ *
+ * 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 _GPIO_MOUSE_H
+#define _GPIO_MOUSE_H
+
+#define GPIO_MOUSE_POLARITY_ACT_HIGH   0x00
+#define GPIO_MOUSE_POLARITY_ACT_LOW    0x01
+
+#define GPIO_MOUSE_PIN_UP      0
+#define GPIO_MOUSE_PIN_DOWN    1
+#define GPIO_MOUSE_PIN_LEFT    2
+#define GPIO_MOUSE_PIN_RIGHT   3
+#define GPIO_MOUSE_PIN_BLEFT   4
+#define GPIO_MOUSE_PIN_BMIDDLE 5
+#define GPIO_MOUSE_PIN_BRIGHT  6
+#define GPIO_MOUSE_PIN_MAX     7
+
+/**
+ * struct gpio_mouse_platform_data
+ * @scan_ms: integer in ms specifying the scan periode.
+ * @polarity: Pin polarity, active high or low.
+ * @up: GPIO line for up value.
+ * @down: GPIO line for down value.
+ * @left: GPIO line for left value.
+ * @right: GPIO line for right value.
+ * @bleft: GPIO line for left button.
+ * @bmiddle: GPIO line for middle button.
+ * @bright: GPIO line for right button.
+ *
+ * This struct must be added to the platform_device in the board code.
+ * It is used by the gpio_mouse driver to setup GPIO lines and to
+ * calculate mouse movement.
+ */
+struct gpio_mouse_platform_data {
+       int scan_ms;
+       int polarity;
+
+       union {
+               struct {
+                       int up;
+                       int down;
+                       int left;
+                       int right;
+
+                       int bleft;
+                       int bmiddle;
+                       int bright;
+               };
+               int pins[GPIO_MOUSE_PIN_MAX];
+       };
+};
+
+#endif /* _GPIO_MOUSE_H */
index 7803014f3a11bae4f353e7b042c0e1835997c7be..8d302298a161941ce40c6ed47411627d5f0229f8 100644 (file)
 # define in_atomic()   ((preempt_count() & ~PREEMPT_ACTIVE) != 0)
 #endif
 
+#ifdef CONFIG_PREEMPT
+# define PREEMPT_CHECK_OFFSET 1
+#else
+# define PREEMPT_CHECK_OFFSET 0
+#endif
+
+/*
+ * Check whether we were atomic before we did preempt_disable():
+ * (used by the scheduler)
+ */
+#define in_atomic_preempt_off() \
+               ((preempt_count() & ~PREEMPT_ACTIVE) != PREEMPT_CHECK_OFFSET)
+
 #ifdef CONFIG_PREEMPT
 # define preemptible() (preempt_count() == 0 && !irqs_disabled())
 # define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
index 827ee748fd4c88b76a65a6992c6cd20161b9e9a3..898103b401f1309d68ee5f91b80b3627d8aaa98b 100644 (file)
@@ -263,19 +263,28 @@ struct hid_item {
 #define HID_QUIRK_2WHEEL_MOUSE_HACK_5          0x00000100
 #define HID_QUIRK_2WHEEL_MOUSE_HACK_ON         0x00000200
 #define HID_QUIRK_MIGHTYMOUSE                  0x00000400
-#define HID_QUIRK_CYMOTION                     0x00000800
-#define HID_QUIRK_POWERBOOK_HAS_FN             0x00001000
-#define HID_QUIRK_POWERBOOK_FN_ON              0x00002000
-#define HID_QUIRK_INVERT_HWHEEL                        0x00004000
-#define HID_QUIRK_POWERBOOK_ISO_KEYBOARD        0x00008000
-#define HID_QUIRK_BAD_RELATIVE_KEYS            0x00010000
-#define HID_QUIRK_SKIP_OUTPUT_REPORTS          0x00020000
-#define HID_QUIRK_IGNORE_MOUSE                 0x00040000
-#define HID_QUIRK_SONY_PS3_CONTROLLER          0x00080000
-#define HID_QUIRK_LOGITECH_DESCRIPTOR          0x00100000
-#define HID_QUIRK_DUPLICATE_USAGES             0x00200000
-#define HID_QUIRK_RESET_LEDS                   0x00400000
-#define HID_QUIRK_SWAPPED_MIN_MAX              0x00800000
+#define HID_QUIRK_POWERBOOK_HAS_FN             0x00000800
+#define HID_QUIRK_POWERBOOK_FN_ON              0x00001000
+#define HID_QUIRK_INVERT_HWHEEL                        0x00002000
+#define HID_QUIRK_POWERBOOK_ISO_KEYBOARD        0x00004000
+#define HID_QUIRK_BAD_RELATIVE_KEYS            0x00008000
+#define HID_QUIRK_SKIP_OUTPUT_REPORTS          0x00010000
+#define HID_QUIRK_IGNORE_MOUSE                 0x00020000
+#define HID_QUIRK_SONY_PS3_CONTROLLER          0x00040000
+#define HID_QUIRK_DUPLICATE_USAGES             0x00080000
+#define HID_QUIRK_RESET_LEDS                   0x00100000
+#define HID_QUIRK_HIDINPUT                     0x00200000
+#define HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL        0x00400000
+#define HID_QUIRK_LOGITECH_EXPANDED_KEYMAP     0x00800000
+
+/*
+ * Separate quirks for runtime report descriptor fixup
+ */
+
+#define HID_QUIRK_RDESC_CYMOTION               0x00000001
+#define HID_QUIRK_RDESC_LOGITECH               0x00000002
+#define HID_QUIRK_RDESC_SWAPPED_MIN_MAX                0x00000004
+#define HID_QUIRK_RDESC_PETALYNX               0x00000008
 
 /*
  * This is the global environment of the parser. This information is
@@ -488,6 +497,11 @@ struct hid_descriptor {
 #define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001))
 
 /* HID core API */
+
+#ifdef CONFIG_HID_DEBUG
+extern int hid_debug;
+#endif
+
 extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32);
 extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report);
 extern int hidinput_connect(struct hid_device *);
@@ -506,6 +520,7 @@ u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct);
 int usbhid_modify_dquirk(const u16 idVendor, const u16 idProduct, const u32 quirks);
 int usbhid_quirks_init(char **quirks_param);
 void usbhid_quirks_exit(void);
+void usbhid_fixup_report_descriptor(const u16, const u16, char *, unsigned, char **);
 
 #ifdef CONFIG_HID_FF
 int hid_ff_init(struct hid_device *hid);
@@ -523,14 +538,19 @@ static inline int hid_pidff_init(struct hid_device *hid) { return -ENODEV; }
 #else
 static inline int hid_ff_init(struct hid_device *hid) { return -1; }
 #endif
-#ifdef DEBUG
-#define dbg(format, arg...) printk(KERN_DEBUG "%s: " format "\n" , \
-               __FILE__ , ## arg)
+
+#ifdef CONFIG_HID_DEBUG
+#define dbg_hid(format, arg...) if (hid_debug) \
+                               printk(KERN_DEBUG "%s: " format ,\
+                               __FILE__ , ## arg)
+#define dbg_hid_line(format, arg...) if (hid_debug) \
+                               printk(format, ## arg)
 #else
-#define dbg(format, arg...) do {} while (0)
+#define dbg_hid(format, arg...) do {} while (0)
+#define dbg_hid_line dbg_hid
 #endif
 
-#define err(format, arg...) printk(KERN_ERR "%s: " format "\n" , \
+#define err_hid(format, arg...) printk(KERN_ERR "%s: " format "\n" , \
                __FILE__ , ## arg)
 #endif
 
index cae7d618030cbc0e0580a8cb5b9663dd29d2c793..2eaba21b9b1aec6cd9058c9ddbe71a98ed87aaa4 100644 (file)
@@ -90,7 +90,7 @@ extern s32 i2c_smbus_write_block_data(struct i2c_client * client,
                                      const u8 *values);
 /* Returns the number of read bytes */
 extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client,
-                                        u8 command, u8 *values);
+                                        u8 command, u8 length, u8 *values);
 extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client * client,
                                          u8 command, u8 length,
                                          const u8 *values);
@@ -150,15 +150,20 @@ struct i2c_driver {
 
 /**
  * struct i2c_client - represent an I2C slave device
+ * @flags: I2C_CLIENT_TEN indicates the device uses a ten bit chip address;
+ *     I2C_CLIENT_PEC indicates it uses SMBus Packet Error Checking
  * @addr: Address used on the I2C bus connected to the parent adapter.
  * @name: Indicates the type of the device, usually a chip name that's
  *     generic enough to hide second-sourcing and compatible revisions.
+ * @adapter: manages the bus segment hosting this I2C device
  * @dev: Driver model device node for the slave.
+ * @irq: indicates the IRQ generated by this device (if any)
  * @driver_name: Identifies new-style driver used with this device; also
  *     used as the module name for hotplug/coldplug modprobe support.
  *
  * An i2c_client identifies a single device (i.e. chip) connected to an
- * i2c bus. The behaviour is defined by the routines of the driver.
+ * i2c bus. The behaviour exposed to Linux is defined by the driver
+ * managing the device.
  */
 struct i2c_client {
        unsigned short flags;           /* div., see below              */
@@ -180,7 +185,8 @@ struct i2c_client {
 
 static inline struct i2c_client *kobj_to_i2c_client(struct kobject *kobj)
 {
-       return to_i2c_client(container_of(kobj, struct device, kobj));
+       struct device * const dev = container_of(kobj, struct device, kobj);
+       return to_i2c_client(dev);
 }
 
 static inline void *i2c_get_clientdata (struct i2c_client *dev)
@@ -201,7 +207,7 @@ static inline void i2c_set_clientdata (struct i2c_client *dev, void *data)
  * @addr: stored in i2c_client.addr
  * @platform_data: stored in i2c_client.dev.platform_data
  * @irq: stored in i2c_client.irq
-
+ *
  * I2C doesn't actually support hardware probing, although controllers and
  * devices may be able to use I2C_SMBUS_QUICK to tell whether or not there's
  * a device at a given address.  Drivers commonly need more information than
@@ -210,7 +216,7 @@ static inline void i2c_set_clientdata (struct i2c_client *dev, void *data)
  * i2c_board_info is used to build tables of information listing I2C devices
  * that are present.  This information is used to grow the driver model tree
  * for "new style" I2C drivers.  For mainboards this is done statically using
- * i2c_register_board_info(), where @bus_num represents an adapter that isn't
+ * i2c_register_board_info(); bus numbers identify adapters that aren't
  * yet available.  For add-on boards, i2c_new_device() does this dynamically
  * with the adapter already known.
  */
@@ -518,8 +524,9 @@ union i2c_smbus_data {
 #define I2C_SMBUS_WORD_DATA        3
 #define I2C_SMBUS_PROC_CALL        4
 #define I2C_SMBUS_BLOCK_DATA       5
-#define I2C_SMBUS_I2C_BLOCK_DATA    6
+#define I2C_SMBUS_I2C_BLOCK_BROKEN  6
 #define I2C_SMBUS_BLOCK_PROC_CALL   7          /* SMBus 2.0 */
+#define I2C_SMBUS_I2C_BLOCK_DATA    8
 
 
 /* ----- commands for the ioctl like i2c_command call:
index 1e365acdd36922dafcfc0a8b287a5368c5b9c9c2..19ab25804056b7b467197d89f1d6b8a02a757912 100644 (file)
@@ -25,6 +25,7 @@
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/semaphore.h>
+#include <asm/mutex.h>
 
 /******************************************************************************
  * IDE driver configuration options (play with these as desired):
@@ -685,6 +686,8 @@ typedef struct hwif_s {
        u8 mwdma_mask;
        u8 swdma_mask;
 
+       u8 cbl;         /* cable type */
+
        hwif_chipset_t chipset; /* sub-module for tuning.. */
 
        struct pci_dev  *pci_dev;       /* for pci chipsets */
@@ -735,8 +738,8 @@ typedef struct hwif_s {
        void (*ide_dma_clear_irq)(ide_drive_t *drive);
        void (*dma_host_on)(ide_drive_t *drive);
        void (*dma_host_off)(ide_drive_t *drive);
-       int (*ide_dma_lostirq)(ide_drive_t *drive);
-       int (*ide_dma_timeout)(ide_drive_t *drive);
+       void (*dma_lost_irq)(ide_drive_t *drive);
+       void (*dma_timeout)(ide_drive_t *drive);
 
        void (*OUTB)(u8 addr, unsigned long port);
        void (*OUTBSYNC)(ide_drive_t *drive, u8 addr, unsigned long port);
@@ -791,7 +794,6 @@ typedef struct hwif_s {
        unsigned        sharing_irq: 1; /* 1 = sharing irq with another hwif */
        unsigned        reset      : 1; /* reset after probe */
        unsigned        autodma    : 1; /* auto-attempt using DMA at boot */
-       unsigned        udma_four  : 1; /* 1=ATA-66 capable, 0=default */
        unsigned        no_lba48   : 1; /* 1 = cannot do LBA48 */
        unsigned        no_lba48_dma : 1; /* 1 = cannot do LBA48 DMA */
        unsigned        auto_poll  : 1; /* supports nop auto-poll */
@@ -863,7 +865,7 @@ typedef struct hwgroup_s {
 
 typedef struct ide_driver_s ide_driver_t;
 
-extern struct semaphore ide_setting_sem;
+extern struct mutex ide_setting_mtx;
 
 int set_io_32bit(ide_drive_t *, int);
 int set_pio_mode(ide_drive_t *, int);
@@ -1304,8 +1306,8 @@ extern int __ide_dma_check(ide_drive_t *);
 extern int ide_dma_setup(ide_drive_t *);
 extern void ide_dma_start(ide_drive_t *);
 extern int __ide_dma_end(ide_drive_t *);
-extern int __ide_dma_lostirq(ide_drive_t *);
-extern int __ide_dma_timeout(ide_drive_t *);
+extern void ide_dma_lost_irq(ide_drive_t *);
+extern void ide_dma_timeout(ide_drive_t *);
 #endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
 
 #else
@@ -1382,11 +1384,11 @@ extern const ide_pio_timings_t ide_pio_timings[6];
 
 
 extern spinlock_t ide_lock;
-extern struct semaphore ide_cfg_sem;
+extern struct mutex ide_cfg_mtx;
 /*
  * Structure locking:
  *
- * ide_cfg_sem and ide_lock together protect changes to
+ * ide_cfg_mtx and ide_lock together protect changes to
  * ide_hwif_t->{next,hwgroup}
  * ide_drive_t->next
  *
index 826803449db7982063c831fc29196f3ce5c3377e..915572fa030b678835732a166b0f7b86e4dc1fb6 100644 (file)
@@ -83,4 +83,33 @@ void idr_remove(struct idr *idp, int id);
 void idr_destroy(struct idr *idp);
 void idr_init(struct idr *idp);
 
+
+/*
+ * IDA - IDR based id allocator, use when translation from id to
+ * pointer isn't necessary.
+ */
+#define IDA_CHUNK_SIZE         128     /* 128 bytes per chunk */
+#define IDA_BITMAP_LONGS       (128 / sizeof(long) - 1)
+#define IDA_BITMAP_BITS                (IDA_BITMAP_LONGS * sizeof(long) * 8)
+
+struct ida_bitmap {
+       long                    nr_busy;
+       unsigned long           bitmap[IDA_BITMAP_LONGS];
+};
+
+struct ida {
+       struct idr              idr;
+       struct ida_bitmap       *free_bitmap;
+};
+
+#define IDA_INIT(name)         { .idr = IDR_INIT(name), .free_bitmap = NULL, }
+#define DEFINE_IDA(name)       struct ida name = IDA_INIT(name)
+
+int ida_pre_get(struct ida *ida, gfp_t gfp_mask);
+int ida_get_new_above(struct ida *ida, int starting_id, int *p_id);
+int ida_get_new(struct ida *ida, int *p_id);
+void ida_remove(struct ida *ida, int id);
+void ida_destroy(struct ida *ida);
+void ida_init(struct ida *ida);
+
 #endif /* __IDR_H__ */
index 604c2434f71c0a0436b63af4f37b6d7f4e14a8b3..422084d18ce1af9162d4c40ceead599f1094bcd4 100644 (file)
@@ -76,6 +76,8 @@ enum
 #define IFLA_WEIGHT IFLA_WEIGHT
        IFLA_OPERSTATE,
        IFLA_LINKMODE,
+       IFLA_LINKINFO,
+#define IFLA_LINKINFO IFLA_LINKINFO
        __IFLA_MAX
 };
 
@@ -140,4 +142,49 @@ struct ifla_cacheinfo
        __u32   retrans_time;
 };
 
+enum
+{
+       IFLA_INFO_UNSPEC,
+       IFLA_INFO_KIND,
+       IFLA_INFO_DATA,
+       IFLA_INFO_XSTATS,
+       __IFLA_INFO_MAX,
+};
+
+#define IFLA_INFO_MAX  (__IFLA_INFO_MAX - 1)
+
+/* VLAN section */
+
+enum
+{
+       IFLA_VLAN_UNSPEC,
+       IFLA_VLAN_ID,
+       IFLA_VLAN_FLAGS,
+       IFLA_VLAN_EGRESS_QOS,
+       IFLA_VLAN_INGRESS_QOS,
+       __IFLA_VLAN_MAX,
+};
+
+#define IFLA_VLAN_MAX  (__IFLA_VLAN_MAX - 1)
+
+struct ifla_vlan_flags {
+       __u32   flags;
+       __u32   mask;
+};
+
+enum
+{
+       IFLA_VLAN_QOS_UNSPEC,
+       IFLA_VLAN_QOS_MAPPING,
+       __IFLA_VLAN_QOS_MAX
+};
+
+#define IFLA_VLAN_QOS_MAX      (__IFLA_VLAN_QOS_MAX - 1)
+
+struct ifla_vlan_qos_mapping
+{
+       __u32 from;
+       __u32 to;
+};
+
 #endif /* _LINUX_IF_LINK_H */
index 768372f07caab7928a284acf592174608eb87213..0f2f70d4e48c856af3dbbe6c3196366097a0e91d 100644 (file)
@@ -110,6 +110,21 @@ struct ifpppcstatsreq {
        struct ppp_comp_stats stats;
 };
 
+/* For PPPIOCGL2TPSTATS */
+struct pppol2tp_ioc_stats {
+       __u16           tunnel_id;      /* redundant */
+       __u16           session_id;     /* if zero, get tunnel stats */
+       __u32           using_ipsec:1;  /* valid only for session_id == 0 */
+       aligned_u64     tx_packets;
+       aligned_u64     tx_bytes;
+       aligned_u64     tx_errors;
+       aligned_u64     rx_packets;
+       aligned_u64     rx_bytes;
+       aligned_u64     rx_seq_discards;
+       aligned_u64     rx_oos_packets;
+       aligned_u64     rx_errors;
+};
+
 #define ifr__name       b.ifr_ifrn.ifrn_name
 #define stats_ptr       b.ifr_ifru.ifru_data
 
@@ -146,6 +161,7 @@ struct ifpppcstatsreq {
 #define PPPIOCDISCONN  _IO('t', 57)            /* disconnect channel */
 #define PPPIOCATTCHAN  _IOW('t', 56, int)      /* attach to ppp channel */
 #define PPPIOCGCHAN    _IOR('t', 55, int)      /* get ppp channel number */
+#define PPPIOCGL2TPSTATS _IOR('t', 54, struct pppol2tp_ioc_stats)
 
 #define SIOCGPPPSTATS   (SIOCDEVPRIVATE + 0)
 #define SIOCGPPPVER     (SIOCDEVPRIVATE + 1)   /* NEVER change this!! */
diff --git a/include/linux/if_pppol2tp.h b/include/linux/if_pppol2tp.h
new file mode 100644 (file)
index 0000000..516203b
--- /dev/null
@@ -0,0 +1,69 @@
+/***************************************************************************
+ * Linux PPP over L2TP (PPPoL2TP) Socket Implementation (RFC 2661)
+ *
+ * This file supplies definitions required by the PPP over L2TP driver
+ * (pppol2tp.c).  All version information wrt this file is located in pppol2tp.c
+ *
+ * License:
+ *             This program is free software; you can redistribute it and/or
+ *             modify it under the terms of the GNU General Public License
+ *             as published by the Free Software Foundation; either version
+ *             2 of the License, or (at your option) any later version.
+ *
+ */
+
+#ifndef __LINUX_IF_PPPOL2TP_H
+#define __LINUX_IF_PPPOL2TP_H
+
+#include <asm/types.h>
+
+#ifdef __KERNEL__
+#include <linux/in.h>
+#endif
+
+/* Structure used to connect() the socket to a particular tunnel UDP
+ * socket.
+ */
+struct pppol2tp_addr
+{
+       pid_t   pid;                    /* pid that owns the fd.
+                                        * 0 => current */
+       int     fd;                     /* FD of UDP socket to use */
+
+       struct sockaddr_in addr;        /* IP address and port to send to */
+
+       __be16 s_tunnel, s_session;     /* For matching incoming packets */
+       __be16 d_tunnel, d_session;     /* For sending outgoing packets */
+};
+
+/* Socket options:
+ * DEBUG       - bitmask of debug message categories
+ * SENDSEQ     - 0 => don't send packets with sequence numbers
+ *               1 => send packets with sequence numbers
+ * RECVSEQ     - 0 => receive packet sequence numbers are optional
+ *               1 => drop receive packets without sequence numbers
+ * LNSMODE     - 0 => act as LAC.
+ *               1 => act as LNS.
+ * REORDERTO   - reorder timeout (in millisecs). If 0, don't try to reorder.
+ */
+enum {
+       PPPOL2TP_SO_DEBUG       = 1,
+       PPPOL2TP_SO_RECVSEQ     = 2,
+       PPPOL2TP_SO_SENDSEQ     = 3,
+       PPPOL2TP_SO_LNSMODE     = 4,
+       PPPOL2TP_SO_REORDERTO   = 5,
+};
+
+/* Debug message categories for the DEBUG socket option */
+enum {
+       PPPOL2TP_MSG_DEBUG      = (1 << 0),     /* verbose debug (if
+                                                * compiled in) */
+       PPPOL2TP_MSG_CONTROL    = (1 << 1),     /* userspace - kernel
+                                                * interface */
+       PPPOL2TP_MSG_SEQ        = (1 << 2),     /* sequence numbers */
+       PPPOL2TP_MSG_DATA       = (1 << 3),     /* data packets */
+};
+
+
+
+#endif
index 6f987be60fe26ed7cf36287f42a60f5a2fc3f557..25652545ba6e19683a9efff8172ec83d4b98efd4 100644 (file)
@@ -27,6 +27,7 @@
 #include <asm/semaphore.h>
 #include <linux/ppp_channel.h>
 #endif /* __KERNEL__ */
+#include <linux/if_pppol2tp.h>
 
 /* For user-space programs to pick up these definitions
  * which they wouldn't get otherwise without defining __KERNEL__
@@ -50,8 +51,9 @@ struct pppoe_addr{
  * Protocols supported by AF_PPPOX 
  */ 
 #define PX_PROTO_OE    0 /* Currently just PPPoE */
-#define PX_MAX_PROTO   1       
+#define PX_PROTO_OL2TP 1 /* Now L2TP also */
+#define PX_MAX_PROTO   2
+
 struct sockaddr_pppox { 
        sa_family_t     sa_family;            /* address family, AF_PPPOX */ 
        unsigned int    sa_protocol;          /* protocol identifier */ 
@@ -60,6 +62,16 @@ struct sockaddr_pppox {
        }sa_addr; 
 }__attribute__ ((packed)); 
 
+/* The use of the above union isn't viable because the size of this
+ * struct must stay fixed over time -- applications use sizeof(struct
+ * sockaddr_pppox) to fill it. We use a protocol specific sockaddr
+ * type instead.
+ */
+struct sockaddr_pppol2tp {
+       sa_family_t     sa_family;      /* address family, AF_PPPOX */
+       unsigned int    sa_protocol;    /* protocol identifier */
+       struct pppol2tp_addr pppol2tp;
+}__attribute__ ((packed));
 
 /*********************************************************************
  *
index 88aef7b86ef43be6b5b2408aa233f559fa88c115..42eb6945b93ede5bc06463e1b5cfda9e5e940109 100644 (file)
@@ -36,6 +36,7 @@ struct tun_struct {
        unsigned long           flags;
        int                     attached;
        uid_t                   owner;
+       gid_t                   group;
 
        wait_queue_head_t       read_wait;
        struct sk_buff_head     readq;
@@ -78,6 +79,7 @@ struct tun_struct {
 #define TUNSETPERSIST _IOW('T', 203, int) 
 #define TUNSETOWNER   _IOW('T', 204, int)
 #define TUNSETLINK    _IOW('T', 205, int)
+#define TUNSETGROUP   _IOW('T', 206, int)
 
 /* TUNSETIFF ifr flags */
 #define IFF_TUN                0x0001
index 81e9bc93569b5e0a849b19a06987b53c983d4074..61a57dc2ac994c4a3e20c339ff2bec617d84c532 100644 (file)
@@ -99,7 +99,7 @@ static inline void vlan_group_set_device(struct vlan_group *vg, int vlan_id,
 }
 
 struct vlan_priority_tci_mapping {
-       unsigned long priority;
+       u32 priority;
        unsigned short vlan_qos; /* This should be shifted when first set, so we only do it
                                  * at provisioning time.
                                  * ((skb->priority << 13) & 0xE000)
@@ -112,7 +112,10 @@ struct vlan_dev_info {
        /** This will be the mapping that correlates skb->priority to
         * 3 bits of VLAN QOS tags...
         */
-       unsigned long ingress_priority_map[8];
+       unsigned int nr_ingress_mappings;
+       u32 ingress_priority_map[8];
+
+       unsigned int nr_egress_mappings;
        struct vlan_priority_tci_mapping *egress_priority_map[16]; /* hash table */
 
        unsigned short vlan_id;        /*  The VLAN Identifier for this interface. */
@@ -132,6 +135,7 @@ struct vlan_dev_info {
        int old_allmulti;               /* similar to above. */
        int old_promiscuity;            /* similar to above. */
        struct net_device *real_dev;    /* the underlying device/interface */
+       unsigned char real_dev_addr[ETH_ALEN];
        struct proc_dir_entry *dent;    /* Holds the proc data */
        unsigned long cnt_inc_headroom_on_tx; /* How many times did we have to grow the skb on TX. */
        unsigned long cnt_encap_on_xmit;      /* How many times did we have to encapsulate the skb on TX. */
@@ -395,6 +399,10 @@ enum vlan_ioctl_cmds {
        GET_VLAN_VID_CMD /* Get the VID of this VLAN (specified by name) */
 };
 
+enum vlan_flags {
+       VLAN_FLAG_REORDER_HDR   = 0x1,
+};
+
 enum vlan_name_types {
        VLAN_NAME_TYPE_PLUS_VID, /* Name will look like:  vlan0005 */
        VLAN_NAME_TYPE_RAW_PLUS_VID, /* name will look like:  eth1.0005 */
index d8521c72f69f9ff4aad1fc97223cd6dbadd5923d..18c98b54303099eec767b2b9b9d7cf4a185f3c76 100644 (file)
@@ -981,15 +981,15 @@ struct input_dev {
        struct mutex mutex;     /* serializes open and close operations */
        unsigned int users;
 
-       struct class_device cdev;
+       struct device dev;
        union {                 /* temporarily so while we switching to struct device */
-               struct device *parent;
-       } dev;
+               struct device *dev;
+       } cdev;
 
        struct list_head        h_list;
        struct list_head        node;
 };
-#define to_input_dev(d) container_of(d, struct input_dev, cdev)
+#define to_input_dev(d) container_of(d, struct input_dev, dev)
 
 /*
  * Verify that we are in sync with input_device_id mod_devicetable.h #defines
@@ -1096,22 +1096,22 @@ 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)
+#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);
 
 static inline struct input_dev *input_get_device(struct input_dev *dev)
 {
-       return to_input_dev(class_device_get(&dev->cdev));
+       return to_input_dev(get_device(&dev->dev));
 }
 
 static inline void input_put_device(struct input_dev *dev)
 {
-       class_device_put(&dev->cdev);
+       put_device(&dev->dev);
 }
 
 static inline void *input_get_drvdata(struct input_dev *dev)
index 8e2042b9d471024635bb412b5ac1a1b0fe075108..2eaa142cd06171bae79f35a7e72442648cb86f46 100644 (file)
@@ -47,8 +47,10 @@ enum {
 #define IOPRIO_NORM    (4)
 static inline int task_ioprio(struct task_struct *task)
 {
-       WARN_ON(!ioprio_valid(task->ioprio));
-       return IOPRIO_PRIO_DATA(task->ioprio);
+       if (ioprio_valid(task->ioprio))
+               return IOPRIO_PRIO_DATA(task->ioprio);
+
+       return IOPRIO_NORM;
 }
 
 static inline int task_nice_ioprio(struct task_struct *task)
diff --git a/include/linux/ip_mp_alg.h b/include/linux/ip_mp_alg.h
deleted file mode 100644 (file)
index e234e20..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/* ip_mp_alg.h: IPV4 multipath algorithm support, user-visible values.
- *
- * Copyright (C) 2004, 2005 Einar Lueck <elueck@de.ibm.com>
- * Copyright (C) 2005 David S. Miller <davem@davemloft.net>
- */
-
-#ifndef _LINUX_IP_MP_ALG_H
-#define _LINUX_IP_MP_ALG_H
-
-enum ip_mp_alg {
-       IP_MP_ALG_NONE,
-       IP_MP_ALG_RR,
-       IP_MP_ALG_DRR,
-       IP_MP_ALG_RANDOM,
-       IP_MP_ALG_WRANDOM,
-       __IP_MP_ALG_MAX
-};
-
-#define IP_MP_ALG_MAX (__IP_MP_ALG_MAX - 1)
-
-#endif /* _LINUX_IP_MP_ALG_H */
-
index 648bd1f0912d3cbbba77b9276d34309f1f1700d5..97983dc9df131ada19207e54a0371d700912c41c 100644 (file)
@@ -27,8 +27,8 @@ struct in6_ifreq {
        int             ifr6_ifindex; 
 };
 
-#define IPV6_SRCRT_STRICT      0x01    /* this hop must be a neighbor  */
-#define IPV6_SRCRT_TYPE_0      0       /* IPv6 type 0 Routing Header   */
+#define IPV6_SRCRT_STRICT      0x01    /* Deprecated; will be removed */
+#define IPV6_SRCRT_TYPE_0      0       /* Deprecated; will be removed */
 #define IPV6_SRCRT_TYPE_2      2       /* IPv6 type 2 Routing Header   */
 
 /*
@@ -247,7 +247,7 @@ struct inet6_skb_parm {
        __u16                   lastopt;
        __u32                   nhoff;
        __u16                   flags;
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
        __u16                   dsthao;
 #endif
 
@@ -299,8 +299,8 @@ struct ipv6_pinfo {
        /* pktoption flags */
        union {
                struct {
-                       __u16   srcrt:2,
-                               osrcrt:2,
+                       __u16   srcrt:1,
+                               osrcrt:1,
                                rxinfo:1,
                                rxoinfo:1,
                                rxhlim:1,
index 945ba3110874fcf96bc428aa142d611524536896..8e3735714c1c42e1c61145b59f95e40fee23821e 100644 (file)
@@ -216,6 +216,34 @@ struct if_irda_req {
 #define ifr_dtr       ifr_ifru.ifru_line.dtr
 #define ifr_rts       ifr_ifru.ifru_line.rts
 
+
+/* IrDA netlink definitions */
+#define IRDA_NL_NAME "irda"
+#define IRDA_NL_VERSION 1
+
+enum irda_nl_commands {
+       IRDA_NL_CMD_UNSPEC,
+       IRDA_NL_CMD_SET_MODE,
+       IRDA_NL_CMD_GET_MODE,
+
+       __IRDA_NL_CMD_AFTER_LAST
+};
+#define IRDA_NL_CMD_MAX (__IRDA_NL_CMD_AFTER_LAST - 1)
+
+enum nl80211_attrs {
+       IRDA_NL_ATTR_UNSPEC,
+       IRDA_NL_ATTR_IFNAME,
+       IRDA_NL_ATTR_MODE,
+
+       __IRDA_NL_ATTR_AFTER_LAST
+};
+#define IRDA_NL_ATTR_MAX (__IRDA_NL_ATTR_AFTER_LAST - 1)
+
+/* IrDA modes */
+#define IRDA_MODE_PRIMARY   0x1
+#define IRDA_MODE_SECONDARY 0x2
+#define IRDA_MODE_MONITOR   0x4
+
 #endif /* KERNEL_IRDA_H */
 
 
index c288e41ba3315303a47e1614f9790754e8d39b6f..06cbf41d32d258e464fb5263ab1be91e11cf4b43 100644 (file)
@@ -55,7 +55,7 @@ struct kobject {
        struct kobject          * parent;
        struct kset             * kset;
        struct kobj_type        * ktype;
-       struct dentry           * dentry;
+       struct sysfs_dirent     * sd;
        wait_queue_head_t       poll;
 };
 
@@ -71,13 +71,14 @@ extern void kobject_init(struct kobject *);
 extern void kobject_cleanup(struct kobject *);
 
 extern int __must_check kobject_add(struct kobject *);
-extern int __must_check kobject_shadow_add(struct kobject *, struct dentry *);
+extern int __must_check kobject_shadow_add(struct kobject *kobj,
+                                          struct sysfs_dirent *shadow_parent);
 extern void kobject_del(struct kobject *);
 
 extern int __must_check kobject_rename(struct kobject *, const char *new_name);
 extern int __must_check kobject_shadow_rename(struct kobject *kobj,
-                                               struct dentry *new_parent,
-                                               const char *new_name);
+                                             struct sysfs_dirent *new_parent,
+                                             const char *new_name);
 extern int __must_check kobject_move(struct kobject *, struct kobject *);
 
 extern int __must_check kobject_register(struct kobject *);
index 2b139f66027f3de7ae5f1a60df00ddf39c8cb147..dae7143644fe8b87c18aa1fb57e175d6f61865c2 100644 (file)
@@ -279,6 +279,16 @@ static inline s64 ktime_to_us(const ktime_t kt)
        return (s64) tv.tv_sec * USEC_PER_SEC + tv.tv_usec;
 }
 
+static inline s64 ktime_us_delta(const ktime_t later, const ktime_t earlier)
+{
+       return ktime_to_us(ktime_sub(later, earlier));
+}
+
+static inline ktime_t ktime_add_us(const ktime_t kt, const u64 usec)
+{
+       return ktime_add_ns(kt, usec * 1000);
+}
+
 /*
  * The resolution of the clocks. The resolution value is returned in
  * the clock_getres() system call to give application programmers an
index 620da7be07b7ec2ee420a3768fd4bebe9d5815ef..47cd2a1c554487b7ae6a028a085b1107c7090712 100644 (file)
@@ -116,6 +116,7 @@ static inline struct device *pci_dev_to_dev(struct pci_dev *pdev)
 enum {
        /* various global constants */
        LIBATA_MAX_PRD          = ATA_MAX_PRD / 2,
+       LIBATA_DUMB_MAX_PRD     = ATA_MAX_PRD / 4,      /* Worst case */
        ATA_MAX_PORTS           = 8,
        ATA_DEF_QUEUE           = 1,
        /* tag ATA_MAX_QUEUE - 1 is reserved for internal commands */
@@ -136,6 +137,8 @@ enum {
        ATA_DFLAG_CDB_INTR      = (1 << 2), /* device asserts INTRQ when ready for CDB */
        ATA_DFLAG_NCQ           = (1 << 3), /* device supports NCQ */
        ATA_DFLAG_FLUSH_EXT     = (1 << 4), /* do FLUSH_EXT instead of FLUSH */
+       ATA_DFLAG_ACPI_PENDING  = (1 << 5), /* ACPI resume action pending */
+       ATA_DFLAG_ACPI_FAILED   = (1 << 6), /* ACPI on devcfg has failed */
        ATA_DFLAG_CFG_MASK      = (1 << 8) - 1,
 
        ATA_DFLAG_PIO           = (1 << 8), /* device limited to PIO mode */
@@ -193,9 +196,9 @@ enum {
        ATA_PFLAG_SCSI_HOTPLUG  = (1 << 6), /* SCSI hotplug scheduled */
        ATA_PFLAG_INITIALIZING  = (1 << 7), /* being initialized, don't touch */
 
-       ATA_PFLAG_FLUSH_PORT_TASK = (1 << 16), /* flush port task */
        ATA_PFLAG_SUSPENDED     = (1 << 17), /* port is suspended (power) */
        ATA_PFLAG_PM_PENDING    = (1 << 18), /* PM operation pending */
+       ATA_PFLAG_GTM_VALID     = (1 << 19), /* acpi_gtm data valid */
 
        /* struct ata_queued_cmd flags */
        ATA_QCFLAG_ACTIVE       = (1 << 0), /* cmd not yet ack'd to scsi lyer */
@@ -363,6 +366,9 @@ struct ata_host {
        void                    *private_data;
        const struct ata_port_operations *ops;
        unsigned long           flags;
+#ifdef CONFIG_ATA_ACPI
+       acpi_handle             acpi_handle;
+#endif
        struct ata_port         *simplex_claimed;       /* channel owning the DMA */
        struct ata_port         *ports[0];
 };
@@ -428,7 +434,11 @@ struct ata_device {
        struct ata_port         *ap;
        unsigned int            devno;          /* 0 or 1 */
        unsigned long           flags;          /* ATA_DFLAG_xxx */
+       unsigned int            horkage;        /* List of broken features */
        struct scsi_device      *sdev;          /* attached SCSI device */
+#ifdef CONFIG_ATA_ACPI
+       acpi_handle             acpi_handle;
+#endif
        /* n_sector is used as CLEAR_OFFSET, read comment above CLEAR_OFFSET */
        u64                     n_sectors;      /* size of device, if ATA */
        unsigned int            class;          /* ATA_DEV_xxx */
@@ -456,11 +466,6 @@ struct ata_device {
        /* error history */
        struct ata_ering        ering;
        int                     spdn_cnt;
-       unsigned int            horkage;        /* List of broken features */
-#ifdef CONFIG_ATA_ACPI
-       /* ACPI objects info */
-       acpi_handle obj_handle;
-#endif
 };
 
 /* Offset into struct ata_device.  Fields above it are maintained
@@ -489,6 +494,17 @@ struct ata_eh_context {
        unsigned int            did_probe_mask;
 };
 
+struct ata_acpi_drive
+{
+       u32 pio;
+       u32 dma;
+} __packed;
+
+struct ata_acpi_gtm {
+       struct ata_acpi_drive drive[2];
+       u32 flags;
+} __packed;
+
 struct ata_port {
        struct Scsi_Host        *scsi_host; /* our co-allocated scsi host */
        const struct ata_port_operations *ops;
@@ -549,6 +565,10 @@ struct ata_port {
 
        void                    *private_data;
 
+#ifdef CONFIG_ATA_ACPI
+       acpi_handle             acpi_handle;
+       struct ata_acpi_gtm     acpi_gtm;
+#endif
        u8                      sector_buf[ATA_SECT_SIZE]; /* owned by EH */
 };
 
@@ -758,6 +778,7 @@ extern void ata_data_xfer(struct ata_device *adev, unsigned char *buf,
                          unsigned int buflen, int write_data);
 extern void ata_data_xfer_noirq(struct ata_device *adev, unsigned char *buf,
                                unsigned int buflen, int write_data);
+extern void ata_dumb_qc_prep(struct ata_queued_cmd *qc);
 extern void ata_qc_prep(struct ata_queued_cmd *qc);
 extern void ata_noop_qc_prep(struct ata_queued_cmd *qc);
 extern unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc);
@@ -772,7 +793,6 @@ extern void ata_id_string(const u16 *id, unsigned char *s,
 extern void ata_id_c_string(const u16 *id, unsigned char *s,
                            unsigned int ofs, unsigned int len);
 extern void ata_id_to_dma_mode(struct ata_device *dev, u8 unknown);
-extern unsigned long ata_device_blacklisted(const struct ata_device *dev);
 extern void ata_bmdma_setup (struct ata_queued_cmd *qc);
 extern void ata_bmdma_start (struct ata_queued_cmd *qc);
 extern void ata_bmdma_stop(struct ata_queued_cmd *qc);
@@ -849,11 +869,11 @@ struct pci_bits {
        unsigned long           val;
 };
 
-extern int ata_pci_init_native_host(struct ata_host *host);
+extern int ata_pci_init_sff_host(struct ata_host *host);
 extern int ata_pci_init_bmdma(struct ata_host *host);
-extern int ata_pci_prepare_native_host(struct pci_dev *pdev,
-                               const struct ata_port_info * const * ppi,
-                               struct ata_host **r_host);
+extern int ata_pci_prepare_sff_host(struct pci_dev *pdev,
+                                   const struct ata_port_info * const * ppi,
+                                   struct ata_host **r_host);
 extern int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits);
 extern unsigned long ata_pci_default_filter(struct ata_device *, unsigned long);
 #endif /* CONFIG_PCI */
diff --git a/include/linux/lzo.h b/include/linux/lzo.h
new file mode 100644 (file)
index 0000000..582d8b7
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef __LZO_H__
+#define __LZO_H__
+/*
+ *  LZO Public Kernel Interface
+ *  A mini subset of the LZO real-time data compression library
+ *
+ *  Copyright (C) 1996-2005 Markus F.X.J. Oberhumer <markus@oberhumer.com>
+ *
+ *  The full LZO package can be found at:
+ *  http://www.oberhumer.com/opensource/lzo/
+ *
+ *  Changed for kernel use by:
+ *  Nitin Gupta <nitingupta910@gmail.com>
+ *  Richard Purdie <rpurdie@openedhand.com>
+ */
+
+#define LZO1X_MEM_COMPRESS     (16384 * sizeof(unsigned char *))
+#define LZO1X_1_MEM_COMPRESS   LZO1X_MEM_COMPRESS
+
+#define lzo1x_worst_compress(x) (x + (x / 64) + 16 + 3)
+
+/* This requires 'workmem' of size LZO1X_1_MEM_COMPRESS */
+int lzo1x_1_compress(const unsigned char *src, size_t src_len,
+                       unsigned char *dst, size_t *dst_len, void *wrkmem);
+
+/* safe decompression with overrun testing */
+int lzo1x_decompress_safe(const unsigned char *src, size_t src_len,
+                       unsigned char *dst, size_t *dst_len);
+
+/*
+ * Return values (< 0 = Error)
+ */
+#define LZO_E_OK                       0
+#define LZO_E_ERROR                    (-1)
+#define LZO_E_OUT_OF_MEMORY            (-2)
+#define LZO_E_NOT_COMPRESSIBLE         (-3)
+#define LZO_E_INPUT_OVERRUN            (-4)
+#define LZO_E_OUTPUT_OVERRUN           (-5)
+#define LZO_E_LOOKBEHIND_OVERRUN       (-6)
+#define LZO_E_EOF_NOT_FOUND            (-7)
+#define LZO_E_INPUT_NOT_CONSUMED       (-8)
+#define LZO_E_NOT_YET_IMPLEMENTED      (-9)
+
+#endif
index b372f5910fc154247e1f1a08b812e606309139e3..cfb78fb2c0460812b1a56cbb78e5a801a8168647 100644 (file)
@@ -172,6 +172,7 @@ struct mlx4_caps {
        int                     num_pds;
        int                     reserved_pds;
        int                     mtt_entry_sz;
+       u32                     max_msg_sz;
        u32                     page_size_cap;
        u32                     flags;
        u16                     stat_rate_support;
@@ -322,6 +323,7 @@ int mlx4_srq_alloc(struct mlx4_dev *dev, u32 pdn, struct mlx4_mtt *mtt,
                   u64 db_rec, struct mlx4_srq *srq);
 void mlx4_srq_free(struct mlx4_dev *dev, struct mlx4_srq *srq);
 int mlx4_srq_arm(struct mlx4_dev *dev, struct mlx4_srq *srq, int limit_watermark);
+int mlx4_srq_query(struct mlx4_dev *dev, struct mlx4_srq *srq, int *limit_watermark);
 
 int mlx4_INIT_PORT(struct mlx4_dev *dev, int port);
 int mlx4_CLOSE_PORT(struct mlx4_dev *dev, int port);
index 10c57d2791449150c1c721e5b28e11694576292f..3968b943259ae26a5c85fcf2019ab33fad79c958 100644 (file)
@@ -282,6 +282,9 @@ int mlx4_qp_modify(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
                   struct mlx4_qp_context *context, enum mlx4_qp_optpar optpar,
                   int sqd_event, struct mlx4_qp *qp);
 
+int mlx4_qp_query(struct mlx4_dev *dev, struct mlx4_qp *qp,
+                 struct mlx4_qp_context *context);
+
 static inline struct mlx4_qp *__mlx4_qp_lookup(struct mlx4_dev *dev, u32 qpn)
 {
        return radix_tree_lookup(&dev->qp_table_tree, qpn & (dev->caps.num_qps - 1));
index c6d4ab86b83c45b6cb29c24fbffa5e1a7f74a1c4..b021b3a2b65a6f847c846105e6547daa2f8877ff 100644 (file)
 #ifndef __ASM_MV643XX_H
 #define __ASM_MV643XX_H
 
-#ifdef __mips__
-#include <asm/addrspace.h>
-#include <asm/marvell.h>
-#endif
 #include <asm/types.h>
 
 /****************************************/
index 3a70f553b28f853bede95f0b0437dfe1a161d88a..79cc3dab4be7e8e743dbc3f87f821407effebc99 100644 (file)
@@ -108,6 +108,14 @@ struct wireless_dev;
 #define MAX_HEADER (LL_MAX_HEADER + 48)
 #endif
 
+struct net_device_subqueue
+{
+       /* Give a control state for each queue.  This struct may contain
+        * per-queue locks in the future.
+        */
+       unsigned long   state;
+};
+
 /*
  *     Network device statistics. Akin to the 2.0 ether stats but
  *     with byte counters.
@@ -177,19 +185,24 @@ struct netif_rx_stats
 
 DECLARE_PER_CPU(struct netif_rx_stats, netdev_rx_stat);
 
+struct dev_addr_list
+{
+       struct dev_addr_list    *next;
+       u8                      da_addr[MAX_ADDR_LEN];
+       u8                      da_addrlen;
+       int                     da_users;
+       int                     da_gusers;
+};
 
 /*
  *     We tag multicasts with these structures.
  */
-struct dev_mc_list
-{      
-       struct dev_mc_list      *next;
-       __u8                    dmi_addr[MAX_ADDR_LEN];
-       unsigned char           dmi_addrlen;
-       int                     dmi_users;
-       int                     dmi_gusers;
-};
+
+#define dev_mc_list    dev_addr_list
+#define dmi_addr       da_addr
+#define dmi_addrlen    da_addrlen
+#define dmi_users      da_users
+#define dmi_gusers     da_gusers
 
 struct hh_cache
 {
@@ -248,6 +261,8 @@ enum netdev_state_t
        __LINK_STATE_LINKWATCH_PENDING,
        __LINK_STATE_DORMANT,
        __LINK_STATE_QDISC_RUNNING,
+       /* Set by the netpoll NAPI code */
+       __LINK_STATE_POLL_LIST_FROZEN,
 };
 
 
@@ -314,9 +329,10 @@ struct net_device
        /* Net device features */
        unsigned long           features;
 #define NETIF_F_SG             1       /* Scatter/gather IO. */
-#define NETIF_F_IP_CSUM                2       /* Can checksum only TCP/UDP over IPv4. */
+#define NETIF_F_IP_CSUM                2       /* Can checksum TCP/UDP over IPv4. */
 #define NETIF_F_NO_CSUM                4       /* Does not require checksum. F.e. loopack. */
 #define NETIF_F_HW_CSUM                8       /* Can checksum all the packets. */
+#define NETIF_F_IPV6_CSUM      16      /* Can checksum TCP/UDP over IPV6 */
 #define NETIF_F_HIGHDMA                32      /* Can DMA to high memory. */
 #define NETIF_F_FRAGLIST       64      /* Scatter/gather IO. */
 #define NETIF_F_HW_VLAN_TX     128     /* Transmit VLAN hw acceleration */
@@ -325,6 +341,7 @@ struct net_device
 #define NETIF_F_VLAN_CHALLENGED        1024    /* Device cannot handle VLAN packets */
 #define NETIF_F_GSO            2048    /* Enable software GSO. */
 #define NETIF_F_LLTX           4096    /* LockLess TX */
+#define NETIF_F_MULTI_QUEUE    16384   /* Has multiple TX/RX queues */
 
        /* Segmentation offload features */
 #define NETIF_F_GSO_SHIFT      16
@@ -338,8 +355,11 @@ struct net_device
        /* List of features with software fallbacks. */
 #define NETIF_F_GSO_SOFTWARE   (NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6)
 
+
 #define NETIF_F_GEN_CSUM       (NETIF_F_NO_CSUM | NETIF_F_HW_CSUM)
-#define NETIF_F_ALL_CSUM       (NETIF_F_IP_CSUM | NETIF_F_GEN_CSUM)
+#define NETIF_F_V4_CSUM                (NETIF_F_GEN_CSUM | NETIF_F_IP_CSUM)
+#define NETIF_F_V6_CSUM                (NETIF_F_GEN_CSUM | NETIF_F_IPV6_CSUM)
+#define NETIF_F_ALL_CSUM       (NETIF_F_V4_CSUM | NETIF_F_V6_CSUM)
 
        struct net_device       *next_sched;
 
@@ -388,7 +408,10 @@ struct net_device
        unsigned char           addr_len;       /* hardware address length      */
        unsigned short          dev_id;         /* for shared network cards */
 
-       struct dev_mc_list      *mc_list;       /* Multicast mac addresses      */
+       struct dev_addr_list    *uc_list;       /* Secondary unicast mac addresses */
+       int                     uc_count;       /* Number of installed ucasts   */
+       int                     uc_promisc;
+       struct dev_addr_list    *mc_list;       /* Multicast mac addresses      */
        int                     mc_count;       /* Number of installed mcasts   */
        int                     promiscuity;
        int                     allmulti;
@@ -493,6 +516,8 @@ struct net_device
                                                void *saddr,
                                                unsigned len);
        int                     (*rebuild_header)(struct sk_buff *skb);
+#define HAVE_SET_RX_MODE
+       void                    (*set_rx_mode)(struct net_device *dev);
 #define HAVE_MULTICAST                  
        void                    (*set_multicast_list)(struct net_device *dev);
 #define HAVE_SET_MAC_ADDR               
@@ -540,17 +565,22 @@ struct net_device
        struct device           dev;
        /* space for optional statistics and wireless sysfs groups */
        struct attribute_group  *sysfs_groups[3];
+
+       /* rtnetlink link ops */
+       const struct rtnl_link_ops *rtnl_link_ops;
+
+       /* The TX queue control structures */
+       unsigned int                    egress_subqueue_count;
+       struct net_device_subqueue      egress_subqueue[0];
 };
 #define to_net_dev(d) container_of(d, struct net_device, dev)
 
 #define        NETDEV_ALIGN            32
 #define        NETDEV_ALIGN_CONST      (NETDEV_ALIGN - 1)
 
-static inline void *netdev_priv(struct net_device *dev)
+static inline void *netdev_priv(const struct net_device *dev)
 {
-       return (char *)dev + ((sizeof(struct net_device)
-                                       + NETDEV_ALIGN_CONST)
-                               & ~NETDEV_ALIGN_CONST);
+       return dev->priv;
 }
 
 #define SET_MODULE_OWNER(dev) do { } while (0)
@@ -702,6 +732,62 @@ static inline int netif_running(const struct net_device *dev)
        return test_bit(__LINK_STATE_START, &dev->state);
 }
 
+/*
+ * Routines to manage the subqueues on a device.  We only need start
+ * stop, and a check if it's stopped.  All other device management is
+ * done at the overall netdevice level.
+ * Also test the device if we're multiqueue.
+ */
+static inline void netif_start_subqueue(struct net_device *dev, u16 queue_index)
+{
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+       clear_bit(__LINK_STATE_XOFF, &dev->egress_subqueue[queue_index].state);
+#endif
+}
+
+static inline void netif_stop_subqueue(struct net_device *dev, u16 queue_index)
+{
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+#ifdef CONFIG_NETPOLL_TRAP
+       if (netpoll_trap())
+               return;
+#endif
+       set_bit(__LINK_STATE_XOFF, &dev->egress_subqueue[queue_index].state);
+#endif
+}
+
+static inline int netif_subqueue_stopped(const struct net_device *dev,
+                                        u16 queue_index)
+{
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+       return test_bit(__LINK_STATE_XOFF,
+                       &dev->egress_subqueue[queue_index].state);
+#else
+       return 0;
+#endif
+}
+
+static inline void netif_wake_subqueue(struct net_device *dev, u16 queue_index)
+{
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+#ifdef CONFIG_NETPOLL_TRAP
+       if (netpoll_trap())
+               return;
+#endif
+       if (test_and_clear_bit(__LINK_STATE_XOFF,
+                              &dev->egress_subqueue[queue_index].state))
+               __netif_schedule(dev);
+#endif
+}
+
+static inline int netif_is_multiqueue(const struct net_device *dev)
+{
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+       return (!!(NETIF_F_MULTI_QUEUE & dev->features));
+#else
+       return 0;
+#endif
+}
 
 /* Use this variant when it is known for sure that it
  * is executing from interrupt context.
@@ -930,6 +1016,14 @@ static inline void netif_rx_complete(struct net_device *dev)
 {
        unsigned long flags;
 
+#ifdef CONFIG_NETPOLL
+       /* Prevent race with netpoll - yes, this is a kludge.
+        * But at least it doesn't penalize the non-netpoll
+        * code path. */
+       if (test_bit(__LINK_STATE_POLL_LIST_FROZEN, &dev->state))
+               return;
+#endif
+
        local_irq_save(flags);
        __netif_rx_complete(dev);
        local_irq_restore(flags);
@@ -992,15 +1086,24 @@ static inline void netif_tx_disable(struct net_device *dev)
 extern void            ether_setup(struct net_device *dev);
 
 /* Support for loadable net-drivers */
-extern struct net_device *alloc_netdev(int sizeof_priv, const char *name,
-                                      void (*setup)(struct net_device *));
+extern struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
+                                      void (*setup)(struct net_device *),
+                                      unsigned int queue_count);
+#define alloc_netdev(sizeof_priv, name, setup) \
+       alloc_netdev_mq(sizeof_priv, name, setup, 1)
 extern int             register_netdev(struct net_device *dev);
 extern void            unregister_netdev(struct net_device *dev);
-/* Functions used for multicast support */
-extern void            dev_mc_upload(struct net_device *dev);
+/* Functions used for secondary unicast and multicast support */
+extern void            dev_set_rx_mode(struct net_device *dev);
+extern void            __dev_set_rx_mode(struct net_device *dev);
+extern int             dev_unicast_delete(struct net_device *dev, void *addr, int alen);
+extern int             dev_unicast_add(struct net_device *dev, void *addr, int alen);
 extern int             dev_mc_delete(struct net_device *dev, void *addr, int alen, int all);
 extern int             dev_mc_add(struct net_device *dev, void *addr, int alen, int newonly);
 extern void            dev_mc_discard(struct net_device *dev);
+extern int             __dev_addr_delete(struct dev_addr_list **list, int *count, void *addr, int alen, int all);
+extern int             __dev_addr_add(struct dev_addr_list **list, int *count, void *addr, int alen, int newonly);
+extern void            __dev_addr_discard(struct dev_addr_list **list);
 extern void            dev_set_promiscuity(struct net_device *dev, int inc);
 extern void            dev_set_allmulti(struct net_device *dev, int inc);
 extern void            netdev_state_change(struct net_device *dev);
index 10b5c6275706585f56131f695c9faad2e86fe005..0eed0b7ab2dffedca01a1cebd234f7bbafe2efda 100644 (file)
@@ -275,7 +275,8 @@ struct nf_queue_handler {
 };
 extern int nf_register_queue_handler(int pf, 
                                      struct nf_queue_handler *qh);
-extern int nf_unregister_queue_handler(int pf);
+extern int nf_unregister_queue_handler(int pf,
+                                      struct nf_queue_handler *qh);
 extern void nf_unregister_queue_handlers(struct nf_queue_handler *qh);
 extern void nf_reinject(struct sk_buff *skb,
                        struct nf_info *info,
index 9d8144a488cd5bfa5a29910b8d1684cb0ace2386..c93061f331445da0d3541735bc98ab94654f6c3b 100644 (file)
@@ -4,6 +4,8 @@
 
 #include <linux/netfilter/nf_conntrack_common.h>
 
+extern const char *pptp_msg_name[];
+
 /* state of the control session */
 enum pptp_ctrlsess_state {
        PPTP_SESSION_NONE,                      /* no session present */
index 7e733a6ba4f6b91031051fc08f7f4f0ca599593b..64f425a855bb7c191467c2e537a3fc4ce4b6af51 100644 (file)
@@ -141,22 +141,22 @@ struct xt_match
        /* Arguments changed since 2.6.9, as this must now handle
           non-linear skb, using skb_header_pointer and
           skb_ip_make_writable. */
-       int (*match)(const struct sk_buff *skb,
-                    const struct net_device *in,
-                    const struct net_device *out,
-                    const struct xt_match *match,
-                    const void *matchinfo,
-                    int offset,
-                    unsigned int protoff,
-                    int *hotdrop);
+       bool (*match)(const struct sk_buff *skb,
+                     const struct net_device *in,
+                     const struct net_device *out,
+                     const struct xt_match *match,
+                     const void *matchinfo,
+                     int offset,
+                     unsigned int protoff,
+                     bool *hotdrop);
 
        /* Called when user tries to insert an entry of this type. */
        /* Should return true or false. */
-       int (*checkentry)(const char *tablename,
-                         const void *ip,
-                         const struct xt_match *match,
-                         void *matchinfo,
-                         unsigned int hook_mask);
+       bool (*checkentry)(const char *tablename,
+                          const void *ip,
+                          const struct xt_match *match,
+                          void *matchinfo,
+                          unsigned int hook_mask);
 
        /* Called when entry of this type deleted. */
        void (*destroy)(const struct xt_match *match, void *matchinfo);
@@ -202,11 +202,11 @@ struct xt_target
            hook_mask is a bitmask of hooks from which it can be
            called. */
        /* Should return true or false. */
-       int (*checkentry)(const char *tablename,
-                         const void *entry,
-                         const struct xt_target *target,
-                         void *targinfo,
-                         unsigned int hook_mask);
+       bool (*checkentry)(const char *tablename,
+                          const void *entry,
+                          const struct xt_target *target,
+                          void *targinfo,
+                          unsigned int hook_mask);
 
        /* Called when entry of this type deleted. */
        void (*destroy)(const struct xt_target *target, void *targinfo);
diff --git a/include/linux/netfilter/xt_u32.h b/include/linux/netfilter/xt_u32.h
new file mode 100644 (file)
index 0000000..9947f56
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef _XT_U32_H
+#define _XT_U32_H 1
+
+enum xt_u32_ops {
+       XT_U32_AND,
+       XT_U32_LEFTSH,
+       XT_U32_RIGHTSH,
+       XT_U32_AT,
+};
+
+struct xt_u32_location_element {
+       u_int32_t number;
+       u_int8_t nextop;
+};
+
+struct xt_u32_value_element {
+       u_int32_t min;
+       u_int32_t max;
+};
+
+/*
+ * Any way to allow for an arbitrary number of elements?
+ * For now, I settle with a limit of 10 each.
+ */
+#define XT_U32_MAXSIZE 10
+
+struct xt_u32_test {
+       struct xt_u32_location_element location[XT_U32_MAXSIZE+1];
+       struct xt_u32_value_element value[XT_U32_MAXSIZE+1];
+       u_int8_t nnums;
+       u_int8_t nvalues;
+};
+
+struct xt_u32 {
+       struct xt_u32_test tests[XT_U32_MAXSIZE+1];
+       u_int8_t ntests;
+       u_int8_t invert;
+};
+
+#endif /* _XT_U32_H */
index d9bceedfb3dca67c9c8e3290480e7cb2d2a2b28e..daf50be22c9d5f1cac9846e086cc68a55390147d 100644 (file)
@@ -18,13 +18,13 @@ struct clusterip_config;
 struct ipt_clusterip_tgt_info {
 
        u_int32_t flags;
-       
+
        /* only relevant for new ones */
        u_int8_t clustermac[6];
        u_int16_t num_total_nodes;
        u_int16_t num_local_nodes;
        u_int16_t local_nodes[CLUSTERIP_MAX_NODES];
-       enum clusterip_hashmode hash_mode;
+       u_int32_t hash_mode;
        u_int32_t hash_initval;
 
        struct clusterip_config *config;
index 4686f8342cbd73db22f6fd847f51f647f6e6c661..9a720f05888f09e5e5438b363b720981672acb00 100644 (file)
@@ -44,8 +44,14 @@ struct ip6t_ip6 {
        char iniface[IFNAMSIZ], outiface[IFNAMSIZ];
        unsigned char iniface_mask[IFNAMSIZ], outiface_mask[IFNAMSIZ];
 
-       /* ARGH, HopByHop uses 0, so can't do 0 = ANY,
-          instead IP6T_F_NOPROTO must be set */
+       /* Upper protocol number
+        * - The allowed value is 0 (any) or protocol number of last parsable
+        *   header, which is 50 (ESP), 59 (No Next Header), 135 (MH), or
+        *   the non IPv6 extension headers.
+        * - The protocol numbers of IPv6 extension headers except of ESP and
+        *   MH do not match any packets.
+        * - You also need to set IP6T_FLAGS_PROTO to "flags" to check protocol.
+        */
        u_int16_t proto;
        /* TOS to match iff flags & IP6T_F_TOS */
        u_int8_t tos;
index 2d5fd647e0e94eff581b2ad4f8a9a4f0395a405a..5799e8d50623fb18af175b7cef1ac968949d2482 100644 (file)
@@ -8,6 +8,11 @@ struct pata_platform_info {
         * spacing used by ata_std_ports().
         */
        unsigned int ioport_shift;
+       /* 
+        * Indicate platform specific irq types and initial
+        * IRQ flags when call request_irq()
+        */
+       unsigned int irq_flags;
 };
 
 #endif /* __LINUX_PATA_PLATFORM_H */
index 086a0e5a6318ecad38b36a2b5d57f47ceb336695..37a71580ad8a4f8b9e099e1e6e51b155ef50526b 100644 (file)
@@ -111,7 +111,8 @@ enum pcie_reset_state {
 
 typedef unsigned short __bitwise pci_bus_flags_t;
 enum pci_bus_flags {
-       PCI_BUS_FLAGS_NO_MSI = (__force pci_bus_flags_t) 1,
+       PCI_BUS_FLAGS_NO_MSI   = (__force pci_bus_flags_t) 1,
+       PCI_BUS_FLAGS_NO_MMRBC = (__force pci_bus_flags_t) 2,
 };
 
 struct pci_cap_saved_state {
@@ -138,6 +139,7 @@ struct pci_dev {
        unsigned short  subsystem_vendor;
        unsigned short  subsystem_device;
        unsigned int    class;          /* 3 bytes: (base,sub,prog-if) */
+       u8              revision;       /* PCI revision, low byte of class word */
        u8              hdr_type;       /* PCI header type (`multi' flag masked out) */
        u8              rom_base_reg;   /* which config register controls the ROM */
        u8              pin;            /* which interrupt pin this device uses */
@@ -313,7 +315,7 @@ struct pci_dynids {
 
 /* ---------------------------------------------------------------- */
 /** PCI Error Recovery System (PCI-ERS).  If a PCI device driver provides
- *  a set fof callbacks in struct pci_error_handlers, then that device driver
+ *  a set of callbacks in struct pci_error_handlers, then that device driver
  *  will be notified of PCI bus errors, and will be driven to recovery
  *  when an error occurs.
  */
@@ -370,7 +372,6 @@ struct pci_driver {
        int  (*suspend_late) (struct pci_dev *dev, pm_message_t state);
        int  (*resume_early) (struct pci_dev *dev);
        int  (*resume) (struct pci_dev *dev);                   /* Device woken up */
-       int  (*enable_wake) (struct pci_dev *dev, pci_power_t state, int enable);   /* Enable wake event */
        void (*shutdown) (struct pci_dev *dev);
 
        struct pci_error_handlers *err_handler;
@@ -475,7 +476,7 @@ extern void pci_sort_breadthfirst(void);
 /* Generic PCI functions exported to card drivers */
 
 struct pci_dev __deprecated *pci_find_device (unsigned int vendor, unsigned int device, const struct pci_dev *from);
-struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn);
+struct pci_dev __deprecated *pci_find_slot (unsigned int bus, unsigned int devfn);
 int pci_find_capability (struct pci_dev *dev, int cap);
 int pci_find_next_capability (struct pci_dev *dev, u8 pos, int cap);
 int pci_find_ext_capability (struct pci_dev *dev, int cap);
@@ -544,11 +545,16 @@ void pci_set_master(struct pci_dev *dev);
 int pci_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state);
 #define HAVE_PCI_SET_MWI
 int __must_check pci_set_mwi(struct pci_dev *dev);
+int pci_try_set_mwi(struct pci_dev *dev);
 void pci_clear_mwi(struct pci_dev *dev);
 void pci_intx(struct pci_dev *dev, int enable);
 void pci_msi_off(struct pci_dev *dev);
 int pci_set_dma_mask(struct pci_dev *dev, u64 mask);
 int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask);
+int pcix_get_max_mmrbc(struct pci_dev *dev);
+int pcix_get_mmrbc(struct pci_dev *dev);
+int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc);
+int pcie_set_readrq(struct pci_dev *dev, int rq);
 void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno);
 int __must_check pci_assign_resource(struct pci_dev *dev, int i);
 int __must_check pci_assign_resource_fixed(struct pci_dev *dev, int i);
@@ -560,6 +566,7 @@ void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size);
 void __iomem __must_check *pci_map_rom_copy(struct pci_dev *pdev, size_t *size);
 void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom);
 void pci_remove_rom(struct pci_dev *pdev);
+size_t pci_get_rom_size(void __iomem *rom, size_t size);
 
 /* Power management related routines */
 int pci_save_state(struct pci_dev *dev);
@@ -876,5 +883,7 @@ extern int pci_pci_problems;
 extern unsigned long pci_cardbus_io_size;
 extern unsigned long pci_cardbus_mem_size;
 
+extern int pcibios_add_platform_entries(struct pci_dev *dev);
+
 #endif /* __KERNEL__ */
 #endif /* LINUX_PCI_H */
index 0275f6917c8eb77456ab55bfd4c321dfef1bfb39..2c7add169539125490ed5222822703f72c750d36 100644 (file)
 
 /* Vendors and devices.  Sort key: vendor first, device next. */
 
+#define PCI_VENDOR_ID_TTTECH           0x0357
+#define PCI_DEVICE_ID_TTTECH_MC322     0x000a
+
 #define PCI_VENDOR_ID_DYNALINK         0x0675
 #define PCI_DEVICE_ID_DYNALINK_IS64PH  0x1702
 
 #define PCI_DEVICE_ID_ATI_IXP600_SMBUS 0x4385
 #define PCI_DEVICE_ID_ATI_IXP600_IDE   0x438c
 #define PCI_DEVICE_ID_ATI_IXP700_SATA  0x4390
+#define PCI_DEVICE_ID_ATI_IXP700_SMBUS 0x4395
 #define PCI_DEVICE_ID_ATI_IXP700_IDE   0x439c
 
 #define PCI_VENDOR_ID_VLSI             0x1004
 #define PCI_DEVICE_ID_ELSA_MICROLINK   0x1000
 #define PCI_DEVICE_ID_ELSA_QS3000      0x3000
 
-
 #define PCI_VENDOR_ID_BUSLOGIC               0x104B
 #define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC 0x0140
 #define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER    0x1040
 
 #define PCI_VENDOR_ID_SONY             0x104d
 
-
 /* Winbond have two vendor IDs! See 0x10ad as well */
 #define PCI_VENDOR_ID_WINBOND2         0x1050
 #define PCI_DEVICE_ID_WINBOND2_89C940F 0x5a5a
 #define PCI_DEVICE_ID_PROMISE_20276    0x5275
 #define PCI_DEVICE_ID_PROMISE_20277    0x7275
 
-
 #define PCI_VENDOR_ID_UMC              0x1060
 #define PCI_DEVICE_ID_UMC_UM8673F      0x0101
 #define PCI_DEVICE_ID_UMC_UM8886BF     0x673a
 #define PCI_DEVICE_ID_MYLEX_DAC960_BA  0xBA56
 #define PCI_DEVICE_ID_MYLEX_DAC960_GEM 0xB166
 
-
 #define PCI_VENDOR_ID_APPLE            0x106b
 #define PCI_DEVICE_ID_APPLE_BANDIT     0x0001
 #define PCI_DEVICE_ID_APPLE_HYDRA      0x000e
 #define PCI_DEVICE_ID_YAMAHA_744       0x0010
 #define PCI_DEVICE_ID_YAMAHA_754       0x0012
 
-
 #define PCI_VENDOR_ID_QLOGIC           0x1077
 #define PCI_DEVICE_ID_QLOGIC_ISP10160  0x1016
 #define PCI_DEVICE_ID_QLOGIC_ISP1020   0x1020
 #define PCI_DEVICE_ID_CYRIX_5530_AUDIO 0x0103
 #define PCI_DEVICE_ID_CYRIX_5530_VIDEO 0x0104
 
-
-
 #define PCI_VENDOR_ID_CONTAQ           0x1080
 #define PCI_DEVICE_ID_CONTAQ_82C693    0xc693
 
-
 #define PCI_VENDOR_ID_OLICOM           0x108d
 #define PCI_DEVICE_ID_OLICOM_OC2325    0x0012
 #define PCI_DEVICE_ID_OLICOM_OC2183    0x0013
 #define PCI_DEVICE_ID_SII_3112         0x3112
 #define PCI_DEVICE_ID_SII_1210SA       0x0240
 
-
 #define PCI_VENDOR_ID_BROOKTREE                0x109e
 #define PCI_DEVICE_ID_BROOKTREE_878    0x0878
 #define PCI_DEVICE_ID_BROOKTREE_879    0x0879
 
-
 #define PCI_VENDOR_ID_SGI              0x10a9
 #define PCI_DEVICE_ID_SGI_IOC3         0x0003
+#define PCI_DEVICE_ID_SGI_LITHIUM      0x1002
 #define PCI_DEVICE_ID_SGI_IOC4         0x100a
-#define PCI_VENDOR_ID_SGI_LITHIUM      0x1002
-
 
 #define PCI_VENDOR_ID_WINBOND          0x10ad
 #define PCI_DEVICE_ID_WINBOND_82C105   0x0105
 #define PCI_DEVICE_ID_WINBOND_83C553   0x0565
 
-
 #define PCI_VENDOR_ID_PLX              0x10b5
 #define PCI_DEVICE_ID_PLX_R685         0x1030
 #define PCI_DEVICE_ID_PLX_ROMULUS      0x106a
 #define PCI_DEVICE_ID_3COM_3CR990SVR97 0x9909
 #define PCI_DEVICE_ID_3COM_3CR990SVR   0x990a
 
-
 #define PCI_VENDOR_ID_AL               0x10b9
 #define PCI_DEVICE_ID_AL_M1533         0x1533
 #define PCI_DEVICE_ID_AL_M1535                 0x1535
 #define PCI_DEVICE_ID_AL_M5451         0x5451
 #define PCI_DEVICE_ID_AL_M7101         0x7101
 
-
-
 #define PCI_VENDOR_ID_NEOMAGIC         0x10c8
 #define PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO 0x8005
 #define PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO 0x8006
 #define PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO 0x8016
 
-
 #define PCI_VENDOR_ID_TCONRAD          0x10da
 #define PCI_DEVICE_ID_TCONRAD_TOKENRING        0x0508
 
-
 #define PCI_VENDOR_ID_NVIDIA                   0x10de
 #define PCI_DEVICE_ID_NVIDIA_TNT               0x0020
 #define PCI_DEVICE_ID_NVIDIA_TNT2              0x0028
 #define PCI_DEVICE_ID_IMS_TT128                0x9128
 #define PCI_DEVICE_ID_IMS_TT3D         0x9135
 
-
-
-
 #define PCI_VENDOR_ID_INTERG           0x10ea
 #define PCI_DEVICE_ID_INTERG_1682      0x1682
 #define PCI_DEVICE_ID_INTERG_2000      0x2000
 #define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP 0x3fc5
 #define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP_MADI 0x3fc6
 
-
 #define PCI_VENDOR_ID_INIT             0x1101
 
 #define PCI_VENDOR_ID_CREATIVE         0x1102 /* duplicate: ECTIVA */
 #define PCI_VENDOR_ID_SIEMENS           0x110A
 #define PCI_DEVICE_ID_SIEMENS_DSCC4     0x2102
 
-
 #define PCI_VENDOR_ID_VORTEX           0x1119
 #define PCI_DEVICE_ID_VORTEX_GDT60x0   0x0000
 #define PCI_DEVICE_ID_VORTEX_GDT6000B  0x0001
 #define PCI_VENDOR_ID_EF               0x111a
 #define PCI_DEVICE_ID_EF_ATM_FPGA      0x0000
 #define PCI_DEVICE_ID_EF_ATM_ASIC      0x0002
-#define PCI_VENDOR_ID_EF_ATM_LANAI2    0x0003
-#define PCI_VENDOR_ID_EF_ATM_LANAIHB   0x0005
+#define PCI_DEVICE_ID_EF_ATM_LANAI2    0x0003
+#define PCI_DEVICE_ID_EF_ATM_LANAIHB   0x0005
 
 #define PCI_VENDOR_ID_IDT              0x111d
 #define PCI_DEVICE_ID_IDT_IDT77201     0x0001
 #define PCI_VENDOR_ID_FORE             0x1127
 #define PCI_DEVICE_ID_FORE_PCA200E     0x0300
 
-
 #define PCI_VENDOR_ID_PHILIPS          0x1131
 #define PCI_DEVICE_ID_PHILIPS_SAA7146  0x7146
 #define PCI_DEVICE_ID_PHILIPS_SAA9730  0x9730
 #define PCI_DEVICE_ID_ZIATECH_5550_HC  0x5550
  
 
-
 #define PCI_VENDOR_ID_SYSKONNECT       0x1148
 #define PCI_DEVICE_ID_SYSKONNECT_TR    0x4200
 #define PCI_DEVICE_ID_SYSKONNECT_GE    0x4300
 #define PCI_DEVICE_ID_SYSKONNECT_9DXX  0x4400
 #define PCI_DEVICE_ID_SYSKONNECT_9MXX  0x4500
 
-
 #define PCI_VENDOR_ID_DIGI             0x114f
 #define PCI_DEVICE_ID_DIGI_DF_M_IOM2_E 0x0070
 #define PCI_DEVICE_ID_DIGI_DF_M_E      0x0071
 #define PCI_DEVICE_ID_NEO_2RJ45         0x00CA
 #define PCI_DEVICE_ID_NEO_2RJ45PRI      0x00CB
 
-
 #define PCI_VENDOR_ID_XIRCOM           0x115d
 #define PCI_DEVICE_ID_XIRCOM_RBM56G    0x0101
 #define PCI_DEVICE_ID_XIRCOM_X3201_MDM 0x0103
 
-
 #define PCI_VENDOR_ID_SERVERWORKS        0x1166
 #define PCI_DEVICE_ID_SERVERWORKS_HE     0x0008
 #define PCI_DEVICE_ID_SERVERWORKS_LE     0x0009
 #define PCI_DEVICE_ID_ZEITNET_1221     0x0001
 #define PCI_DEVICE_ID_ZEITNET_1225     0x0002
 
-
 #define PCI_VENDOR_ID_FUJITSU_ME       0x119e
 #define PCI_DEVICE_ID_FUJITSU_FS155    0x0001
 #define PCI_DEVICE_ID_FUJITSU_FS50     0x0003
 #define PCI_DEVICE_ID_V3_V960          0x0001
 #define PCI_DEVICE_ID_V3_V351          0x0002
 
-
 #define PCI_VENDOR_ID_ATT              0x11c1
 #define PCI_DEVICE_ID_ATT_VENUS_MODEM  0x480
 
-
 #define PCI_VENDOR_ID_SPECIALIX                0x11cb
 #define PCI_DEVICE_ID_SPECIALIX_IO8    0x2000
 #define PCI_DEVICE_ID_SPECIALIX_RIO    0x8000
 #define PCI_SUBDEVICE_ID_SPECIALIX_SPEED4 0xa004
 
-
 #define PCI_VENDOR_ID_ANALOG_DEVICES   0x11d4
 #define PCI_DEVICE_ID_AD1889JS         0x1889
 
-
 #define PCI_DEVICE_ID_SEGA_BBA         0x1234
 
 #define PCI_VENDOR_ID_ZORAN            0x11de
 #define PCI_DEVICE_ID_ZORAN_36057      0x6057
 #define PCI_DEVICE_ID_ZORAN_36120      0x6120
 
-
 #define PCI_VENDOR_ID_COMPEX           0x11f6
 #define PCI_DEVICE_ID_COMPEX_ENET100VG4        0x0112
 
 #define PCI_DEVICE_ID_3DFX_VOODOO3     0x0005
 #define PCI_DEVICE_ID_3DFX_VOODOO5     0x0009
 
-
-
 #define PCI_VENDOR_ID_AVM              0x1244
 #define PCI_DEVICE_ID_AVM_B1           0x0700
 #define PCI_DEVICE_ID_AVM_C4           0x0800
 #define PCI_DEVICE_ID_AVM_C2           0x1100
 #define PCI_DEVICE_ID_AVM_T1           0x1200
 
-
 #define PCI_VENDOR_ID_STALLION         0x124d
 
 /* Allied Telesyn */
 #define PCI_VENDOR_ID_SATSAGEM         0x1267
 #define PCI_DEVICE_ID_SATSAGEM_NICCY   0x1016
 
-
 #define PCI_VENDOR_ID_ENSONIQ          0x1274
 #define PCI_DEVICE_ID_ENSONIQ_CT5880   0x5880
 #define PCI_DEVICE_ID_ENSONIQ_ES1370   0x5000
 
 #define PCI_VENDOR_ID_ALTEON           0x12ae
 
-
 #define PCI_SUBVENDOR_ID_CONNECT_TECH                  0x12c4
 #define PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232          0x0001
 #define PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_232          0x0002
 #define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_485   0x0331
 #define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_485   0x0332
 
-
 #define PCI_VENDOR_ID_NVIDIA_SGS       0x12d2
 #define PCI_DEVICE_ID_NVIDIA_SGS_RIVA128 0x0018
 
 #define PCI_DEVICE_ID_LMC_SSI          0x0005
 #define PCI_DEVICE_ID_LMC_T1           0x0006
 
-
 #define PCI_VENDOR_ID_NETGEAR          0x1385
 #define PCI_DEVICE_ID_NETGEAR_GA620    0x620a
 
 #define PCI_DEVICE_ID_OXSEMI_16PCI952  0x9521
 #define PCI_DEVICE_ID_OXSEMI_16PCI952PP        0x9523
 
+#define PCI_VENDOR_ID_CHELSIO          0x1425
+
 #define PCI_VENDOR_ID_SAMSUNG          0x144d
 
 #define PCI_VENDOR_ID_MYRICOM          0x14c1
 
 #define PCI_VENDOR_ID_ENE              0x1524
 #define PCI_DEVICE_ID_ENE_CB712_SD     0x0550
+#define PCI_DEVICE_ID_ENE_CB712_SD_2   0x0551
 #define PCI_DEVICE_ID_ENE_1211         0x1211
 #define PCI_DEVICE_ID_ENE_1225         0x1225
 #define PCI_DEVICE_ID_ENE_1410         0x1410
 #define PCI_DEVICE_ID_ENE_720          0x1421
 #define PCI_DEVICE_ID_ENE_722          0x1422
 
-#define PCI_VENDOR_ID_CHELSIO          0x1425
-
 #define PCI_SUBVENDOR_ID_PERLE          0x155f
 #define PCI_SUBDEVICE_ID_PCI_RAS4       0xf001
 #define PCI_SUBDEVICE_ID_PCI_RAS8       0xf010
 
-
 #define PCI_VENDOR_ID_SYBA             0x1592
 #define PCI_DEVICE_ID_SYBA_2P_EPP      0x0782
 #define PCI_DEVICE_ID_SYBA_1P_ECP      0x0783
 #define PCI_DEVICE_ID_MELLANOX_SINAI_OLD 0x5e8c
 #define PCI_DEVICE_ID_MELLANOX_SINAI   0x6274
 
-#define PCI_VENDOR_ID_PDC              0x15e9
+#define PCI_VENDOR_ID_QUICKNET         0x15e2
+#define PCI_DEVICE_ID_QUICKNET_XJ      0x0500
 
+#define PCI_VENDOR_ID_PDC              0x15e9
 
 #define PCI_VENDOR_ID_FARSITE           0x1619
 #define PCI_DEVICE_ID_FARSITE_T2P       0x0400
 #define PCI_DEVICE_ID_BCM1250_PCI      0x0001
 #define PCI_DEVICE_ID_BCM1250_HT       0x0002
 
+#define PCI_VENDOR_ID_ATHEROS          0x168c
+
 #define PCI_VENDOR_ID_NETCELL          0x169c
 #define PCI_DEVICE_ID_REVOLUTION       0x0044
 
 #define PCI_DEVICE_ID_HERC_WIN         0x5732
 #define PCI_DEVICE_ID_HERC_UNI         0x5832
 
-
 #define PCI_VENDOR_ID_SITECOM          0x182d
 #define PCI_DEVICE_ID_SITECOM_DC105V2  0x3069
 
 #define PCI_DEVICE_ID_3DLABS_PERMEDIA2 0x0007
 #define PCI_DEVICE_ID_3DLABS_PERMEDIA2V        0x0009
 
-
 #define PCI_VENDOR_ID_AKS              0x416c
 #define PCI_DEVICE_ID_AKS_ALADDINCARD  0x0100
 
-
-
 #define PCI_VENDOR_ID_S3               0x5333
 #define PCI_DEVICE_ID_S3_TRIO          0x8811
 #define PCI_DEVICE_ID_S3_868           0x8880
 #define PCI_VENDOR_ID_DUNORD           0x5544
 #define PCI_DEVICE_ID_DUNORD_I3000     0x0001
 
-
 #define PCI_VENDOR_ID_DCI              0x6666
 #define PCI_DEVICE_ID_DCI_PCCOM4       0x0001
 #define PCI_DEVICE_ID_DCI_PCCOM8       0x0002
 #define PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN   0x0500
 #define PCI_DEVICE_ID_ADAPTEC2_SCAMP   0x0503
 
-
 #define PCI_VENDOR_ID_HOLTEK           0x9412
 #define PCI_DEVICE_ID_HOLTEK_6565      0x6565
 
 #define PCI_DEVICE_ID_NETMOS_9845      0x9845
 #define PCI_DEVICE_ID_NETMOS_9855      0x9855
 
+#define PCI_VENDOR_ID_3COM_2           0xa727
+
 #define PCI_SUBVENDOR_ID_EXSYS         0xd84d
 #define PCI_SUBDEVICE_ID_EXSYS_4014    0x4014
 #define PCI_SUBDEVICE_ID_EXSYS_4055    0x4055
 #define PCI_DEVICE_ID_TIGERJET_300     0x0001
 #define PCI_DEVICE_ID_TIGERJET_100     0x0002
 
-#define PCI_VENDOR_ID_TTTECH           0x0357
-#define PCI_DEVICE_ID_TTTECH_MC322     0x000A
-
 #define PCI_VENDOR_ID_XILINX_RME       0xea60
 #define PCI_DEVICE_ID_RME_DIGI32       0x9896
 #define PCI_DEVICE_ID_RME_DIGI32_PRO   0x9897
 #define PCI_DEVICE_ID_RME_DIGI32_8     0x9898
-
-#define PCI_VENDOR_ID_QUICKNET         0x15E2
-#define PCI_DEVICE_ID_QUICKNET_XJ      0x0500
diff --git a/include/linux/pda_power.h b/include/linux/pda_power.h
new file mode 100644 (file)
index 0000000..1375f15
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Common power driver for PDAs and phones with one or two external
+ * power supplies (AC/USB) connected to main and backup batteries,
+ * and optional builtin charger.
+ *
+ * Copyright Â© 2007 Anton Vorontsov <cbou@mail.ru>
+ *
+ * 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 __PDA_POWER_H__
+#define __PDA_POWER_H__
+
+#define PDA_POWER_CHARGE_AC  (1 << 0)
+#define PDA_POWER_CHARGE_USB (1 << 1)
+
+struct pda_power_pdata {
+       int (*is_ac_online)(void);
+       int (*is_usb_online)(void);
+       void (*set_charge)(int flags);
+
+       char **supplied_to;
+       size_t num_supplicants;
+
+       unsigned int wait_for_status; /* msecs, default is 500 */
+       unsigned int wait_for_charger; /* msecs, default is 500 */
+};
+
+#endif /* __PDA_POWER_H__ */
index c8884f9712285b25cc88ff7518c2e0b79e0bcb39..8e4120285f72ef3379be0de768880b67453437c9 100644 (file)
@@ -9,13 +9,39 @@
 #define PIPE_BUF_FLAG_ATOMIC   0x02    /* was atomically mapped */
 #define PIPE_BUF_FLAG_GIFT     0x04    /* page is a gift */
 
+/**
+ *     struct pipe_buffer - a linux kernel pipe buffer
+ *     @page: the page containing the data for the pipe buffer
+ *     @offset: offset of data inside the @page
+ *     @len: length of data inside the @page
+ *     @ops: operations associated with this buffer. See @pipe_buf_operations.
+ *     @flags: pipe buffer flags. See above.
+ *     @private: private data owned by the ops.
+ **/
 struct pipe_buffer {
        struct page *page;
        unsigned int offset, len;
        const struct pipe_buf_operations *ops;
        unsigned int flags;
+       unsigned long private;
 };
 
+/**
+ *     struct pipe_inode_info - a linux kernel pipe
+ *     @wait: reader/writer wait point in case of empty/full pipe
+ *     @nrbufs: the number of non-empty pipe buffers in this pipe
+ *     @curbuf: the current pipe buffer entry
+ *     @tmp_page: cached released page
+ *     @readers: number of current readers of this pipe
+ *     @writers: number of current writers of this pipe
+ *     @waiting_writers: number of writers blocked waiting for room
+ *     @r_counter: reader counter
+ *     @w_counter: writer counter
+ *     @fasync_readers: reader side fasync
+ *     @fasync_writers: writer side fasync
+ *     @inode: inode this pipe is attached to
+ *     @bufs: the circular array of pipe buffers
+ **/
 struct pipe_inode_info {
        wait_queue_head_t wait;
        unsigned int nrbufs, curbuf;
@@ -34,22 +60,73 @@ struct pipe_inode_info {
 /*
  * Note on the nesting of these functions:
  *
- * ->pin()
+ * ->confirm()
  *     ->steal()
  *     ...
  *     ->map()
  *     ...
  *     ->unmap()
  *
- * That is, ->map() must be called on a pinned buffer, same goes for ->steal().
+ * That is, ->map() must be called on a confirmed buffer,
+ * same goes for ->steal(). See below for the meaning of each
+ * operation. Also see kerneldoc in fs/pipe.c for the pipe
+ * and generic variants of these hooks.
  */
 struct pipe_buf_operations {
+       /*
+        * This is set to 1, if the generic pipe read/write may coalesce
+        * data into an existing buffer. If this is set to 0, a new pipe
+        * page segment is always used for new data.
+        */
        int can_merge;
+
+       /*
+        * ->map() returns a virtual address mapping of the pipe buffer.
+        * The last integer flag reflects whether this should be an atomic
+        * mapping or not. The atomic map is faster, however you can't take
+        * page faults before calling ->unmap() again. So if you need to eg
+        * access user data through copy_to/from_user(), then you must get
+        * a non-atomic map. ->map() uses the KM_USER0 atomic slot for
+        * atomic maps, so you can't map more than one pipe_buffer at once
+        * and you have to be careful if mapping another page as source
+        * or destination for a copy (IOW, it has to use something else
+        * than KM_USER0).
+        */
        void * (*map)(struct pipe_inode_info *, struct pipe_buffer *, int);
+
+       /*
+        * Undoes ->map(), finishes the virtual mapping of the pipe buffer.
+        */
        void (*unmap)(struct pipe_inode_info *, struct pipe_buffer *, void *);
-       int (*pin)(struct pipe_inode_info *, struct pipe_buffer *);
+
+       /*
+        * ->confirm() verifies that the data in the pipe buffer is there
+        * and that the contents are good. If the pages in the pipe belong
+        * to a file system, we may need to wait for IO completion in this
+        * hook. Returns 0 for good, or a negative error value in case of
+        * error.
+        */
+       int (*confirm)(struct pipe_inode_info *, struct pipe_buffer *);
+
+       /*
+        * When the contents of this pipe buffer has been completely
+        * consumed by a reader, ->release() is called.
+        */
        void (*release)(struct pipe_inode_info *, struct pipe_buffer *);
+
+       /*
+        * Attempt to take ownership of the pipe buffer and its contents.
+        * ->steal() returns 0 for success, in which case the contents
+        * of the pipe (the buf->page) is locked and now completely owned
+        * by the caller. The page may then be transferred to a different
+        * mapping, the most often used case is insertion into different
+        * file address space cache.
+        */
        int (*steal)(struct pipe_inode_info *, struct pipe_buffer *);
+
+       /*
+        * Get a reference to the pipe buffer.
+        */
        void (*get)(struct pipe_inode_info *, struct pipe_buffer *);
 };
 
@@ -68,39 +145,7 @@ void __free_pipe_info(struct pipe_inode_info *);
 void *generic_pipe_buf_map(struct pipe_inode_info *, struct pipe_buffer *, int);
 void generic_pipe_buf_unmap(struct pipe_inode_info *, struct pipe_buffer *, void *);
 void generic_pipe_buf_get(struct pipe_inode_info *, struct pipe_buffer *);
-int generic_pipe_buf_pin(struct pipe_inode_info *, struct pipe_buffer *);
+int generic_pipe_buf_confirm(struct pipe_inode_info *, struct pipe_buffer *);
 int generic_pipe_buf_steal(struct pipe_inode_info *, struct pipe_buffer *);
 
-/*
- * splice is tied to pipes as a transport (at least for now), so we'll just
- * add the splice flags here.
- */
-#define SPLICE_F_MOVE  (0x01)  /* move pages instead of copying */
-#define SPLICE_F_NONBLOCK (0x02) /* don't block on the pipe splicing (but */
-                                /* we may still block on the fd we splice */
-                                /* from/to, of course */
-#define SPLICE_F_MORE  (0x04)  /* expect more data */
-#define SPLICE_F_GIFT  (0x08)  /* pages passed in are a gift */
-
-/*
- * Passed to the actors
- */
-struct splice_desc {
-       unsigned int len, total_len;    /* current and remaining length */
-       unsigned int flags;             /* splice flags */
-       struct file *file;              /* file to read/write */
-       loff_t pos;                     /* file position */
-};
-
-typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *,
-                          struct splice_desc *);
-
-extern ssize_t splice_from_pipe(struct pipe_inode_info *, struct file *,
-                               loff_t *, size_t, unsigned int,
-                               splice_actor *);
-
-extern ssize_t __splice_from_pipe(struct pipe_inode_info *, struct file *,
-                                 loff_t *, size_t, unsigned int,
-                                 splice_actor *);
-
 #endif
index c3f01b3085a410ac9334fd993d8ee4cd38ed339e..30b8571e6b34c25b2311291ad460e2d1754e7862 100644 (file)
@@ -403,16 +403,13 @@ enum
  *   1..32767          Reserved for ematches inside kernel tree
  *   32768..65535      Free to use, not reliable
  */
-enum
-{
-       TCF_EM_CONTAINER,
-       TCF_EM_CMP,
-       TCF_EM_NBYTE,
-       TCF_EM_U32,
-       TCF_EM_META,
-       TCF_EM_TEXT,
-       __TCF_EM_MAX
-};
+#define        TCF_EM_CONTAINER        0
+#define        TCF_EM_CMP              1
+#define        TCF_EM_NBYTE            2
+#define        TCF_EM_U32              3
+#define        TCF_EM_META             4
+#define        TCF_EM_TEXT             5
+#define        TCF_EM_MAX              5
 
 enum
 {
index d10f35338507021c219bac8ce1d235b8a0c05b30..268c51599eb8dc9343ffcdc6ef76e161858f6772 100644 (file)
@@ -101,6 +101,15 @@ struct tc_prio_qopt
        __u8    priomap[TC_PRIO_MAX+1]; /* Map: logical priority -> PRIO band */
 };
 
+enum
+{
+       TCA_PRIO_UNSPEC,
+       TCA_PRIO_MQ,
+       __TCA_PRIO_MAX
+};
+
+#define TCA_PRIO_MAX    (__TCA_PRIO_MAX - 1)
+
 /* TBF section */
 
 struct tc_tbf_qopt
index b2c4fde4e994934b21b4438090bec8f446d2e2e8..273781c82e4dd1551ad41b4550b6bb1dcda1f4a1 100644 (file)
@@ -267,15 +267,10 @@ struct dev_pm_info {
        unsigned                can_wakeup:1;
 #ifdef CONFIG_PM
        unsigned                should_wakeup:1;
-       pm_message_t            prev_state;
-       void                    * saved_state;
-       struct device           * pm_parent;
        struct list_head        entry;
 #endif
 };
 
-extern void device_pm_set_parent(struct device * dev, struct device * parent);
-
 extern int device_power_down(pm_message_t state);
 extern void device_power_up(void);
 extern void device_resume(void);
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
new file mode 100644 (file)
index 0000000..606c095
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ *  Universal power supply monitor class
+ *
+ *  Copyright Â© 2007  Anton Vorontsov <cbou@mail.ru>
+ *  Copyright Â© 2004  Szabolcs Gyurko
+ *  Copyright Â© 2003  Ian Molton <spyro@f2s.com>
+ *
+ *  Modified: 2004, Oct     Szabolcs Gyurko
+ *
+ *  You may use this code as per GPL version 2
+ */
+
+#ifndef __LINUX_POWER_SUPPLY_H__
+#define __LINUX_POWER_SUPPLY_H__
+
+#include <linux/device.h>
+#include <linux/workqueue.h>
+#include <linux/leds.h>
+
+/*
+ * All voltages, currents, charges, energies, time and temperatures in uV,
+ * ÂµA, ÂµAh, ÂµWh, seconds and tenths of degree Celsius unless otherwise
+ * stated. It's driver's job to convert its raw values to units in which
+ * this class operates.
+ */
+
+/*
+ * For systems where the charger determines the maximum battery capacity
+ * the min and max fields should be used to present these values to user
+ * space. Unused/unknown fields will not appear in sysfs.
+ */
+
+enum {
+       POWER_SUPPLY_STATUS_UNKNOWN = 0,
+       POWER_SUPPLY_STATUS_CHARGING,
+       POWER_SUPPLY_STATUS_DISCHARGING,
+       POWER_SUPPLY_STATUS_NOT_CHARGING,
+       POWER_SUPPLY_STATUS_FULL,
+};
+
+enum {
+       POWER_SUPPLY_HEALTH_UNKNOWN = 0,
+       POWER_SUPPLY_HEALTH_GOOD,
+       POWER_SUPPLY_HEALTH_OVERHEAT,
+       POWER_SUPPLY_HEALTH_DEAD,
+       POWER_SUPPLY_HEALTH_OVERVOLTAGE,
+       POWER_SUPPLY_HEALTH_UNSPEC_FAILURE,
+};
+
+enum {
+       POWER_SUPPLY_TECHNOLOGY_UNKNOWN = 0,
+       POWER_SUPPLY_TECHNOLOGY_NiMH,
+       POWER_SUPPLY_TECHNOLOGY_LION,
+       POWER_SUPPLY_TECHNOLOGY_LIPO,
+       POWER_SUPPLY_TECHNOLOGY_LiFe,
+       POWER_SUPPLY_TECHNOLOGY_NiCd,
+};
+
+enum {
+       POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN = 0,
+       POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL,
+       POWER_SUPPLY_CAPACITY_LEVEL_LOW,
+       POWER_SUPPLY_CAPACITY_LEVEL_NORMAL,
+       POWER_SUPPLY_CAPACITY_LEVEL_HIGH,
+       POWER_SUPPLY_CAPACITY_LEVEL_FULL,
+};
+
+enum power_supply_property {
+       /* Properties of type `int' */
+       POWER_SUPPLY_PROP_STATUS = 0,
+       POWER_SUPPLY_PROP_HEALTH,
+       POWER_SUPPLY_PROP_PRESENT,
+       POWER_SUPPLY_PROP_ONLINE,
+       POWER_SUPPLY_PROP_TECHNOLOGY,
+       POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
+       POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
+       POWER_SUPPLY_PROP_VOLTAGE_NOW,
+       POWER_SUPPLY_PROP_VOLTAGE_AVG,
+       POWER_SUPPLY_PROP_CURRENT_NOW,
+       POWER_SUPPLY_PROP_CURRENT_AVG,
+       POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
+       POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN,
+       POWER_SUPPLY_PROP_CHARGE_FULL,
+       POWER_SUPPLY_PROP_CHARGE_EMPTY,
+       POWER_SUPPLY_PROP_CHARGE_NOW,
+       POWER_SUPPLY_PROP_CHARGE_AVG,
+       POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
+       POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN,
+       POWER_SUPPLY_PROP_ENERGY_FULL,
+       POWER_SUPPLY_PROP_ENERGY_EMPTY,
+       POWER_SUPPLY_PROP_ENERGY_NOW,
+       POWER_SUPPLY_PROP_ENERGY_AVG,
+       POWER_SUPPLY_PROP_CAPACITY, /* in percents! */
+       POWER_SUPPLY_PROP_CAPACITY_LEVEL,
+       POWER_SUPPLY_PROP_TEMP,
+       POWER_SUPPLY_PROP_TEMP_AMBIENT,
+       POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
+       POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
+       POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
+       POWER_SUPPLY_PROP_TIME_TO_FULL_AVG,
+       /* Properties of type `const char *' */
+       POWER_SUPPLY_PROP_MODEL_NAME,
+       POWER_SUPPLY_PROP_MANUFACTURER,
+};
+
+enum power_supply_type {
+       POWER_SUPPLY_TYPE_BATTERY = 0,
+       POWER_SUPPLY_TYPE_UPS,
+       POWER_SUPPLY_TYPE_MAINS,
+       POWER_SUPPLY_TYPE_USB,
+};
+
+union power_supply_propval {
+       int intval;
+       const char *strval;
+};
+
+struct power_supply {
+       const char *name;
+       enum power_supply_type type;
+       enum power_supply_property *properties;
+       size_t num_properties;
+
+       char **supplied_to;
+       size_t num_supplicants;
+
+       int (*get_property)(struct power_supply *psy,
+                           enum power_supply_property psp,
+                           union power_supply_propval *val);
+       void (*external_power_changed)(struct power_supply *psy);
+
+       /* For APM emulation, think legacy userspace. */
+       int use_for_apm;
+
+       /* private */
+       struct device *dev;
+       struct work_struct changed_work;
+
+#ifdef CONFIG_LEDS_TRIGGERS
+       struct led_trigger *charging_full_trig;
+       char *charging_full_trig_name;
+       struct led_trigger *charging_trig;
+       char *charging_trig_name;
+       struct led_trigger *full_trig;
+       char *full_trig_name;
+       struct led_trigger *online_trig;
+       char *online_trig_name;
+#endif
+};
+
+/*
+ * This is recommended structure to specify static power supply parameters.
+ * Generic one, parametrizable for different power supplies. Power supply
+ * class itself does not use it, but that's what implementing most platform
+ * drivers, should try reuse for consistency.
+ */
+
+struct power_supply_info {
+       const char *name;
+       int technology;
+       int voltage_max_design;
+       int voltage_min_design;
+       int charge_full_design;
+       int charge_empty_design;
+       int energy_full_design;
+       int energy_empty_design;
+       int use_for_apm;
+};
+
+extern void power_supply_changed(struct power_supply *psy);
+extern int power_supply_am_i_supplied(struct power_supply *psy);
+
+extern int power_supply_register(struct device *parent,
+                                struct power_supply *psy);
+extern void power_supply_unregister(struct power_supply *psy);
+
+/* For APM emulation, think legacy userspace. */
+extern struct class *power_supply_class;
+
+#endif /* __LINUX_POWER_SUPPLY_H__ */
index 1fae30af91f362665152791c843790fca6079e84..c91476ce314ac32853cd8cac29859ad3790ee975 100644 (file)
@@ -261,7 +261,7 @@ enum rtattr_type_t
        RTA_FLOW,
        RTA_CACHEINFO,
        RTA_SESSION,
-       RTA_MP_ALGO,
+       RTA_MP_ALGO, /* no longer used */
        RTA_TABLE,
        __RTA_MAX
 };
@@ -570,10 +570,16 @@ static __inline__ int rtattr_strcmp(const struct rtattr *rta, const char *str)
 }
 
 extern int rtattr_parse(struct rtattr *tb[], int maxattr, struct rtattr *rta, int len);
+extern int __rtattr_parse_nested_compat(struct rtattr *tb[], int maxattr,
+                                       struct rtattr *rta, int len);
 
 #define rtattr_parse_nested(tb, max, rta) \
        rtattr_parse((tb), (max), RTA_DATA((rta)), RTA_PAYLOAD((rta)))
 
+#define rtattr_parse_nested_compat(tb, max, rta, data, len) \
+({     data = RTA_PAYLOAD(rta) >= len ? RTA_DATA(rta) : NULL; \
+       __rtattr_parse_nested_compat(tb, max, rta, len); })
+
 extern int rtnetlink_send(struct sk_buff *skb, u32 pid, u32 group, int echo);
 extern int rtnl_unicast(struct sk_buff *skb, u32 pid);
 extern int rtnl_notify(struct sk_buff *skb, u32 pid, u32 group,
@@ -638,6 +644,18 @@ extern void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const voi
 ({     (start)->rta_len = skb_tail_pointer(skb) - (unsigned char *)(start); \
        (skb)->len; })
 
+#define RTA_NEST_COMPAT(skb, type, attrlen, data) \
+({     struct rtattr *__start = (struct rtattr *)skb_tail_pointer(skb); \
+       RTA_PUT(skb, type, attrlen, data); \
+       RTA_NEST(skb, type); \
+       __start; })
+
+#define RTA_NEST_COMPAT_END(skb, start) \
+({     struct rtattr *__nest = (void *)(start) + NLMSG_ALIGN((start)->rta_len); \
+       (start)->rta_len = skb_tail_pointer(skb) - (unsigned char *)(start); \
+       RTA_NEST_END(skb, __nest); \
+       (skb)->len; })
+
 #define RTA_NEST_CANCEL(skb, start) \
 ({     if (start) \
                skb_trim(skb, (unsigned char *) (start) - (skb)->data); \
index 693f0e6c54d47595c6f3268d0e20b5de74303d90..cfb680585ab8bd87762fe3e9b2bedfb404882760 100644 (file)
@@ -34,6 +34,8 @@
 #define SCHED_FIFO             1
 #define SCHED_RR               2
 #define SCHED_BATCH            3
+/* SCHED_ISO: reserved but not implemented yet */
+#define SCHED_IDLE             5
 
 #ifdef __KERNEL__
 
@@ -130,6 +132,26 @@ extern unsigned long nr_active(void);
 extern unsigned long nr_iowait(void);
 extern unsigned long weighted_cpuload(const int cpu);
 
+struct seq_file;
+struct cfs_rq;
+#ifdef CONFIG_SCHED_DEBUG
+extern void proc_sched_show_task(struct task_struct *p, struct seq_file *m);
+extern void proc_sched_set_task(struct task_struct *p);
+extern void
+print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq, u64 now);
+#else
+static inline void
+proc_sched_show_task(struct task_struct *p, struct seq_file *m)
+{
+}
+static inline void proc_sched_set_task(struct task_struct *p)
+{
+}
+static inline void
+print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq, u64 now)
+{
+}
+#endif
 
 /*
  * Task state bitmask. NOTE! These bits are also
@@ -193,6 +215,7 @@ struct task_struct;
 extern void sched_init(void);
 extern void sched_init_smp(void);
 extern void init_idle(struct task_struct *idle, int cpu);
+extern void init_idle_bootup_task(struct task_struct *idle);
 
 extern cpumask_t nohz_cpu_mask;
 #if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ)
@@ -479,7 +502,7 @@ struct signal_struct {
         * from jiffies_to_ns(utime + stime) if sched_clock uses something
         * other than jiffies.)
         */
-       unsigned long long sched_time;
+       unsigned long long sum_sched_runtime;
 
        /*
         * We don't bother to synchronize most readers of this at all,
@@ -521,31 +544,6 @@ struct signal_struct {
 #define SIGNAL_STOP_CONTINUED  0x00000004 /* SIGCONT since WCONTINUED reap */
 #define SIGNAL_GROUP_EXIT      0x00000008 /* group exit in progress */
 
-
-/*
- * Priority of a process goes from 0..MAX_PRIO-1, valid RT
- * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH
- * tasks are in the range MAX_RT_PRIO..MAX_PRIO-1. Priority
- * values are inverted: lower p->prio value means higher priority.
- *
- * The MAX_USER_RT_PRIO value allows the actual maximum
- * RT priority to be separate from the value exported to
- * user-space.  This allows kernel threads to set their
- * priority to a value higher than any user task. Note:
- * MAX_RT_PRIO must not be smaller than MAX_USER_RT_PRIO.
- */
-
-#define MAX_USER_RT_PRIO       100
-#define MAX_RT_PRIO            MAX_USER_RT_PRIO
-
-#define MAX_PRIO               (MAX_RT_PRIO + 40)
-
-#define rt_prio(prio)          unlikely((prio) < MAX_RT_PRIO)
-#define rt_task(p)             rt_prio((p)->prio)
-#define batch_task(p)          (unlikely((p)->policy == SCHED_BATCH))
-#define is_rt_policy(p)                ((p) != SCHED_NORMAL && (p) != SCHED_BATCH)
-#define has_rt_policy(p)       unlikely(is_rt_policy((p)->policy))
-
 /*
  * Some day this will be a full-fledged user tracking system..
  */
@@ -583,13 +581,13 @@ struct reclaim_state;
 #if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT)
 struct sched_info {
        /* cumulative counters */
-       unsigned long   cpu_time,       /* time spent on the cpu */
-                       run_delay,      /* time spent waiting on a runqueue */
-                       pcnt;           /* # of timeslices run on this cpu */
+       unsigned long pcnt;           /* # of times run on this cpu */
+       unsigned long long cpu_time,  /* time spent on the cpu */
+                          run_delay; /* time spent waiting on a runqueue */
 
        /* timestamps */
-       unsigned long   last_arrival,   /* when we last ran on a cpu */
-                       last_queued;    /* when we were last queued to run */
+       unsigned long long last_arrival,/* when we last ran on a cpu */
+                          last_queued; /* when we were last queued to run */
 };
 #endif /* defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) */
 
@@ -639,18 +637,24 @@ static inline int sched_info_on(void)
 #endif
 }
 
-enum idle_type
-{
-       SCHED_IDLE,
-       NOT_IDLE,
-       NEWLY_IDLE,
-       MAX_IDLE_TYPES
+enum cpu_idle_type {
+       CPU_IDLE,
+       CPU_NOT_IDLE,
+       CPU_NEWLY_IDLE,
+       CPU_MAX_IDLE_TYPES
 };
 
 /*
  * sched-domains (multiprocessor balancing) declarations:
  */
-#define SCHED_LOAD_SCALE       128UL   /* increase resolution of load */
+
+/*
+ * Increase resolution of nice-level calculations:
+ */
+#define SCHED_LOAD_SHIFT       10
+#define SCHED_LOAD_SCALE       (1L << SCHED_LOAD_SHIFT)
+
+#define SCHED_LOAD_SCALE_FUZZ  (SCHED_LOAD_SCALE >> 5)
 
 #ifdef CONFIG_SMP
 #define SD_LOAD_BALANCE                1       /* Do load balancing on this domain. */
@@ -719,14 +723,14 @@ struct sched_domain {
 
 #ifdef CONFIG_SCHEDSTATS
        /* load_balance() stats */
-       unsigned long lb_cnt[MAX_IDLE_TYPES];
-       unsigned long lb_failed[MAX_IDLE_TYPES];
-       unsigned long lb_balanced[MAX_IDLE_TYPES];
-       unsigned long lb_imbalance[MAX_IDLE_TYPES];
-       unsigned long lb_gained[MAX_IDLE_TYPES];
-       unsigned long lb_hot_gained[MAX_IDLE_TYPES];
-       unsigned long lb_nobusyg[MAX_IDLE_TYPES];
-       unsigned long lb_nobusyq[MAX_IDLE_TYPES];
+       unsigned long lb_cnt[CPU_MAX_IDLE_TYPES];
+       unsigned long lb_failed[CPU_MAX_IDLE_TYPES];
+       unsigned long lb_balanced[CPU_MAX_IDLE_TYPES];
+       unsigned long lb_imbalance[CPU_MAX_IDLE_TYPES];
+       unsigned long lb_gained[CPU_MAX_IDLE_TYPES];
+       unsigned long lb_hot_gained[CPU_MAX_IDLE_TYPES];
+       unsigned long lb_nobusyg[CPU_MAX_IDLE_TYPES];
+       unsigned long lb_nobusyq[CPU_MAX_IDLE_TYPES];
 
        /* Active load balancing */
        unsigned long alb_cnt;
@@ -753,12 +757,6 @@ struct sched_domain {
 extern int partition_sched_domains(cpumask_t *partition1,
                                    cpumask_t *partition2);
 
-/*
- * Maximum cache size the migration-costs auto-tuning code will
- * search from:
- */
-extern unsigned int max_cache_size;
-
 #endif /* CONFIG_SMP */
 
 
@@ -809,14 +807,86 @@ struct mempolicy;
 struct pipe_inode_info;
 struct uts_namespace;
 
-enum sleep_type {
-       SLEEP_NORMAL,
-       SLEEP_NONINTERACTIVE,
-       SLEEP_INTERACTIVE,
-       SLEEP_INTERRUPTED,
+struct rq;
+struct sched_domain;
+
+struct sched_class {
+       struct sched_class *next;
+
+       void (*enqueue_task) (struct rq *rq, struct task_struct *p,
+                             int wakeup, u64 now);
+       void (*dequeue_task) (struct rq *rq, struct task_struct *p,
+                             int sleep, u64 now);
+       void (*yield_task) (struct rq *rq, struct task_struct *p);
+
+       void (*check_preempt_curr) (struct rq *rq, struct task_struct *p);
+
+       struct task_struct * (*pick_next_task) (struct rq *rq, u64 now);
+       void (*put_prev_task) (struct rq *rq, struct task_struct *p, u64 now);
+
+       int (*load_balance) (struct rq *this_rq, int this_cpu,
+                       struct rq *busiest,
+                       unsigned long max_nr_move, unsigned long max_load_move,
+                       struct sched_domain *sd, enum cpu_idle_type idle,
+                       int *all_pinned, unsigned long *total_load_moved);
+
+       void (*set_curr_task) (struct rq *rq);
+       void (*task_tick) (struct rq *rq, struct task_struct *p);
+       void (*task_new) (struct rq *rq, struct task_struct *p);
 };
 
-struct prio_array;
+struct load_weight {
+       unsigned long weight, inv_weight;
+};
+
+/*
+ * CFS stats for a schedulable entity (task, task-group etc)
+ *
+ * Current field usage histogram:
+ *
+ *     4 se->block_start
+ *     4 se->run_node
+ *     4 se->sleep_start
+ *     4 se->sleep_start_fair
+ *     6 se->load.weight
+ *     7 se->delta_fair
+ *    15 se->wait_runtime
+ */
+struct sched_entity {
+       long                    wait_runtime;
+       unsigned long           delta_fair_run;
+       unsigned long           delta_fair_sleep;
+       unsigned long           delta_exec;
+       s64                     fair_key;
+       struct load_weight      load;           /* for load-balancing */
+       struct rb_node          run_node;
+       unsigned int            on_rq;
+
+       u64                     wait_start_fair;
+       u64                     wait_start;
+       u64                     exec_start;
+       u64                     sleep_start;
+       u64                     sleep_start_fair;
+       u64                     block_start;
+       u64                     sleep_max;
+       u64                     block_max;
+       u64                     exec_max;
+       u64                     wait_max;
+       u64                     last_ran;
+
+       u64                     sum_exec_runtime;
+       s64                     sum_wait_runtime;
+       s64                     sum_sleep_runtime;
+       unsigned long           wait_runtime_overruns;
+       unsigned long           wait_runtime_underruns;
+#ifdef CONFIG_FAIR_GROUP_SCHED
+       struct sched_entity     *parent;
+       /* rq on which this entity is (to be) queued: */
+       struct cfs_rq           *cfs_rq;
+       /* rq "owned" by this entity/group: */
+       struct cfs_rq           *my_q;
+#endif
+};
 
 struct task_struct {
        volatile long state;    /* -1 unrunnable, 0 runnable, >0 stopped */
@@ -832,23 +902,20 @@ struct task_struct {
        int oncpu;
 #endif
 #endif
-       int load_weight;        /* for niceness load balancing purposes */
+
        int prio, static_prio, normal_prio;
        struct list_head run_list;
-       struct prio_array *array;
+       struct sched_class *sched_class;
+       struct sched_entity se;
 
        unsigned short ioprio;
 #ifdef CONFIG_BLK_DEV_IO_TRACE
        unsigned int btrace_seq;
 #endif
-       unsigned long sleep_avg;
-       unsigned long long timestamp, last_ran;
-       unsigned long long sched_time; /* sched_clock time spent running */
-       enum sleep_type sleep_type;
 
        unsigned int policy;
        cpumask_t cpus_allowed;
-       unsigned int time_slice, first_time_slice;
+       unsigned int time_slice;
 
 #if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT)
        struct sched_info sched_info;
@@ -1078,6 +1145,37 @@ struct task_struct {
 #endif
 };
 
+/*
+ * Priority of a process goes from 0..MAX_PRIO-1, valid RT
+ * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH
+ * tasks are in the range MAX_RT_PRIO..MAX_PRIO-1. Priority
+ * values are inverted: lower p->prio value means higher priority.
+ *
+ * The MAX_USER_RT_PRIO value allows the actual maximum
+ * RT priority to be separate from the value exported to
+ * user-space.  This allows kernel threads to set their
+ * priority to a value higher than any user task. Note:
+ * MAX_RT_PRIO must not be smaller than MAX_USER_RT_PRIO.
+ */
+
+#define MAX_USER_RT_PRIO       100
+#define MAX_RT_PRIO            MAX_USER_RT_PRIO
+
+#define MAX_PRIO               (MAX_RT_PRIO + 40)
+#define DEFAULT_PRIO           (MAX_RT_PRIO + 20)
+
+static inline int rt_prio(int prio)
+{
+       if (unlikely(prio < MAX_RT_PRIO))
+               return 1;
+       return 0;
+}
+
+static inline int rt_task(struct task_struct *p)
+{
+       return rt_prio(p->prio);
+}
+
 static inline pid_t process_group(struct task_struct *tsk)
 {
        return tsk->signal->pgrp;
@@ -1223,7 +1321,7 @@ static inline int set_cpus_allowed(struct task_struct *p, cpumask_t new_mask)
 
 extern unsigned long long sched_clock(void);
 extern unsigned long long
-current_sched_time(const struct task_struct *current_task);
+task_sched_runtime(struct task_struct *task);
 
 /* sched_exec is called by processes performing an exec */
 #ifdef CONFIG_SMP
@@ -1232,6 +1330,8 @@ extern void sched_exec(void);
 #define sched_exec()   {}
 #endif
 
+extern void sched_clock_unstable_event(void);
+
 #ifdef CONFIG_HOTPLUG_CPU
 extern void idle_task_exit(void);
 #else
@@ -1240,6 +1340,14 @@ static inline void idle_task_exit(void) {}
 
 extern void sched_idle_next(void);
 
+extern unsigned int sysctl_sched_granularity;
+extern unsigned int sysctl_sched_wakeup_granularity;
+extern unsigned int sysctl_sched_batch_wakeup_granularity;
+extern unsigned int sysctl_sched_stat_granularity;
+extern unsigned int sysctl_sched_runtime_limit;
+extern unsigned int sysctl_sched_child_runs_first;
+extern unsigned int sysctl_sched_features;
+
 #ifdef CONFIG_RT_MUTEXES
 extern int rt_mutex_getprio(struct task_struct *p);
 extern void rt_mutex_setprio(struct task_struct *p, int prio);
@@ -1317,8 +1425,8 @@ extern void FASTCALL(wake_up_new_task(struct task_struct * tsk,
 #else
  static inline void kick_process(struct task_struct *tsk) { }
 #endif
-extern void FASTCALL(sched_fork(struct task_struct * p, int clone_flags));
-extern void FASTCALL(sched_exit(struct task_struct * p));
+extern void sched_fork(struct task_struct *p, int clone_flags);
+extern void sched_dead(struct task_struct *p);
 
 extern int in_group_p(gid_t);
 extern int in_egroup_p(gid_t);
@@ -1406,7 +1514,7 @@ extern struct mm_struct * mm_alloc(void);
 extern void FASTCALL(__mmdrop(struct mm_struct *));
 static inline void mmdrop(struct mm_struct * mm)
 {
-       if (atomic_dec_and_test(&mm->mm_count))
+       if (unlikely(atomic_dec_and_test(&mm->mm_count)))
                __mmdrop(mm);
 }
 
@@ -1638,10 +1746,7 @@ static inline unsigned int task_cpu(const struct task_struct *p)
        return task_thread_info(p)->cpu;
 }
 
-static inline void set_task_cpu(struct task_struct *p, unsigned int cpu)
-{
-       task_thread_info(p)->cpu = cpu;
-}
+extern void set_task_cpu(struct task_struct *p, unsigned int cpu);
 
 #else
 
index b02308ee7667790c78aed464aaddbea9e65c4fb9..3ee412bc00ecdfe12c8bfbbc4bead79fb506a938 100644 (file)
@@ -10,7 +10,7 @@
 struct screen_info {
        u8  orig_x;             /* 0x00 */
        u8  orig_y;             /* 0x01 */
-       u16 dontuse1;           /* 0x02 -- EXT_MEM_K sits here */
+       u16 ext_mem_k;          /* 0x02 */
        u16 orig_video_page;    /* 0x04 */
        u8  orig_video_mode;    /* 0x06 */
        u8  orig_video_cols;    /* 0x07 */
@@ -27,7 +27,7 @@ struct screen_info {
        u16 lfb_depth;          /* 0x16 */
        u32 lfb_base;           /* 0x18 */
        u32 lfb_size;           /* 0x1c */
-       u16 dontuse2, dontuse3; /* 0x20 -- CL_MAGIC and CL_OFFSET here */
+       u16 cl_magic, cl_offset; /* 0x20 */
        u16 lfb_linelength;     /* 0x24 */
        u8  red_size;           /* 0x26 */
        u8  red_pos;            /* 0x27 */
@@ -42,9 +42,8 @@ struct screen_info {
        u16 pages;              /* 0x32 */
        u16 vesa_attributes;    /* 0x34 */
        u32 capabilities;       /* 0x36 */
-                               /* 0x3a -- 0x3b reserved for future expansion */
-                               /* 0x3c -- 0x3f micro stack for relocatable kernels */
-};
+       u8  _reserved[6];       /* 0x3a */
+} __attribute__((packed));
 
 extern struct screen_info screen_info;
 
index 9eb9e0fe03312614b8702e0435c1604b928e4190..c11dc8aa0351e25be90e967a59d4f93b0f5e73b0 100644 (file)
@@ -71,6 +71,7 @@ struct xfrm_user_sec_ctx;
 extern int cap_netlink_send(struct sock *sk, struct sk_buff *skb);
 extern int cap_netlink_recv(struct sk_buff *skb, int cap);
 
+extern unsigned long mmap_min_addr;
 /*
  * Values used in the task_security_ops calls
  */
@@ -1241,8 +1242,9 @@ struct security_operations {
        int (*file_ioctl) (struct file * file, unsigned int cmd,
                           unsigned long arg);
        int (*file_mmap) (struct file * file,
-                         unsigned long reqprot,
-                         unsigned long prot, unsigned long flags);
+                         unsigned long reqprot, unsigned long prot,
+                         unsigned long flags, unsigned long addr,
+                         unsigned long addr_only);
        int (*file_mprotect) (struct vm_area_struct * vma,
                              unsigned long reqprot,
                              unsigned long prot);
@@ -1814,9 +1816,12 @@ static inline int security_file_ioctl (struct file *file, unsigned int cmd,
 
 static inline int security_file_mmap (struct file *file, unsigned long reqprot,
                                      unsigned long prot,
-                                     unsigned long flags)
+                                     unsigned long flags,
+                                     unsigned long addr,
+                                     unsigned long addr_only)
 {
-       return security_ops->file_mmap (file, reqprot, prot, flags);
+       return security_ops->file_mmap (file, reqprot, prot, flags, addr,
+                                       addr_only);
 }
 
 static inline int security_file_mprotect (struct vm_area_struct *vma,
@@ -2489,7 +2494,9 @@ static inline int security_file_ioctl (struct file *file, unsigned int cmd,
 
 static inline int security_file_mmap (struct file *file, unsigned long reqprot,
                                      unsigned long prot,
-                                     unsigned long flags)
+                                     unsigned long flags,
+                                     unsigned long addr,
+                                     unsigned long addr_only)
 {
        return 0;
 }
index 3e3cccbb1cac355f385f474477f2222015e1e528..83783ab0f5524d7ad5e4e3092aa1790cdec527c9 100644 (file)
@@ -50,5 +50,16 @@ int seq_release_private(struct inode *, struct file *);
 
 #define SEQ_START_TOKEN ((void *)1)
 
+/*
+ * Helpers for iteration over list_head-s in seq_files
+ */
+
+extern struct list_head *seq_list_start(struct list_head *head,
+               loff_t pos);
+extern struct list_head *seq_list_start_head(struct list_head *head,
+               loff_t pos);
+extern struct list_head *seq_list_next(void *v, struct list_head *head,
+               loff_t *ppos);
+
 #endif
 #endif
index 1ebf0455e224966a1af04789391704de119d6e2b..d9377ce9ffd1739b642095a298e854dbc537718a 100644 (file)
@@ -209,5 +209,6 @@ static inline void serio_unpin_driver(struct serio *serio)
 #define SERIO_PENMOUNT 0x31
 #define SERIO_TOUCHRIGHT       0x32
 #define SERIO_TOUCHWIN 0x33
+#define SERIO_TAOSEVM  0x34
 
 #endif
index 6f0b2f7d00108835253403dc5f74039b49e3d002..9391e4a4c3447d53b73dba487255cab67ef24b6e 100644 (file)
  *         is able to produce some skb->csum, it MUST use COMPLETE,
  *         not UNNECESSARY.
  *
+ *     PARTIAL: identical to the case for output below.  This may occur
+ *         on a packet received directly from another Linux OS, e.g.,
+ *         a virtualised Linux kernel on the same host.  The packet can
+ *         be treated in the same way as UNNECESSARY except that on
+ *         output (i.e., forwarding) the checksum must be filled in
+ *         by the OS or the hardware.
+ *
  * B. Checksumming on output.
  *
  *     NONE: skb is checksummed by protocol or csum is not required.
  *
  *     PARTIAL: device is required to csum packet as seen by hard_start_xmit
- *     from skb->transport_header to the end and to record the checksum
- *     at skb->transport_header + skb->csum.
+ *     from skb->csum_start to the end and to record the checksum
+ *     at skb->csum_start + skb->csum_offset.
  *
  *     Device must show its capabilities in dev->features, set
  *     at device setup time.
@@ -82,6 +89,7 @@
  *                       TCP/UDP over IPv4. Sigh. Vendors like this
  *                       way by an unknown reason. Though, see comment above
  *                       about CHECKSUM_UNNECESSARY. 8)
+ *     NETIF_F_IPV6_CSUM about as dumb as the last one but does IPv6 instead.
  *
  *     Any questions? No questions, good.              --ANK
  */
@@ -147,8 +155,8 @@ struct skb_shared_info {
 
 /* We divide dataref into two halves.  The higher 16 bits hold references
  * to the payload part of skb->data.  The lower 16 bits hold references to
- * the entire skb->data.  It is up to the users of the skb to agree on
- * where the payload starts.
+ * the entire skb->data.  A clone of a headerless skb holds the length of
+ * the header in skb->hdr_len.
  *
  * All users must obey the rule that the skb->data reference count must be
  * greater than or equal to the payload reference count.
@@ -196,7 +204,6 @@ typedef unsigned char *sk_buff_data_t;
  *     @sk: Socket we are owned by
  *     @tstamp: Time we arrived
  *     @dev: Device we arrived on/are leaving by
- *     @iif: ifindex of device we arrived on
  *     @transport_header: Transport layer header
  *     @network_header: Network layer header
  *     @mac_header: Link layer header
@@ -206,6 +213,7 @@ typedef unsigned char *sk_buff_data_t;
  *     @len: Length of actual data
  *     @data_len: Data length
  *     @mac_len: Length of link layer header
+ *     @hdr_len: writable header length of cloned skb
  *     @csum: Checksum (must include start/offset pair)
  *     @csum_start: Offset from skb->head where checksumming should start
  *     @csum_offset: Offset from csum_start where checksum should be stored
@@ -227,9 +235,12 @@ typedef unsigned char *sk_buff_data_t;
  *     @mark: Generic packet mark
  *     @nfct: Associated connection, if any
  *     @ipvs_property: skbuff is owned by ipvs
+ *     @nf_trace: netfilter packet trace flag
  *     @nfctinfo: Relationship of this skb to the connection
  *     @nfct_reasm: netfilter conntrack re-assembly pointer
  *     @nf_bridge: Saved data about a bridged frame - see br_netfilter.c
+ *     @iif: ifindex of device we arrived on
+ *     @queue_mapping: Queue mapping for multiqueue devices
  *     @tc_index: Traffic control index
  *     @tc_verd: traffic control verdict
  *     @dma_cookie: a cookie to one of several possible DMA operations
@@ -245,8 +256,6 @@ struct sk_buff {
        struct sock             *sk;
        ktime_t                 tstamp;
        struct net_device       *dev;
-       int                     iif;
-       /* 4 byte hole on 64 bit*/
 
        struct  dst_entry       *dst;
        struct  sec_path        *sp;
@@ -260,8 +269,9 @@ struct sk_buff {
        char                    cb[48];
 
        unsigned int            len,
-                               data_len,
-                               mac_len;
+                               data_len;
+       __u16                   mac_len,
+                               hdr_len;
        union {
                __wsum          csum;
                struct {
@@ -277,7 +287,8 @@ struct sk_buff {
                                nfctinfo:3;
        __u8                    pkt_type:3,
                                fclone:2,
-                               ipvs_property:1;
+                               ipvs_property:1,
+                               nf_trace:1;
        __be16                  protocol;
 
        void                    (*destructor)(struct sk_buff *skb);
@@ -288,12 +299,18 @@ struct sk_buff {
 #ifdef CONFIG_BRIDGE_NETFILTER
        struct nf_bridge_info   *nf_bridge;
 #endif
+
+       int                     iif;
+       __u16                   queue_mapping;
+
 #ifdef CONFIG_NET_SCHED
        __u16                   tc_index;       /* traffic control index */
 #ifdef CONFIG_NET_CLS_ACT
        __u16                   tc_verd;        /* traffic control verdict */
 #endif
 #endif
+       /* 2 byte hole */
+
 #ifdef CONFIG_NET_DMA
        dma_cookie_t            dma_cookie;
 #endif
@@ -1321,6 +1338,20 @@ static inline struct sk_buff *netdev_alloc_skb(struct net_device *dev,
        return __netdev_alloc_skb(dev, length, GFP_ATOMIC);
 }
 
+/**
+ *     skb_clone_writable - is the header of a clone writable
+ *     @skb: buffer to check
+ *     @len: length up to which to write
+ *
+ *     Returns true if modifying the header part of the cloned buffer
+ *     does not requires the data to be copied.
+ */
+static inline int skb_clone_writable(struct sk_buff *skb, int len)
+{
+       return !skb_header_cloned(skb) &&
+              skb_headroom(skb) + len <= skb->hdr_len;
+}
+
 /**
  *     skb_cow - copy header of skb when it is required
  *     @skb: buffer to cow
@@ -1709,6 +1740,20 @@ static inline void skb_init_secmark(struct sk_buff *skb)
 { }
 #endif
 
+static inline void skb_set_queue_mapping(struct sk_buff *skb, u16 queue_mapping)
+{
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+       skb->queue_mapping = queue_mapping;
+#endif
+}
+
+static inline void skb_copy_queue_mapping(struct sk_buff *to, const struct sk_buff *from)
+{
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+       to->queue_mapping = from->queue_mapping;
+#endif
+}
+
 static inline int skb_is_gso(const struct sk_buff *skb)
 {
        return skb_shinfo(skb)->gso_size;
index 6e7c9483a6a62b46ab676f540b9dc59fe74d115e..fe195c97a89d9d00346312b8c79fb11ed818c0bf 100644 (file)
@@ -287,6 +287,7 @@ struct ucred {
 #define SOL_NETLINK    270
 #define SOL_TIPC       271
 #define SOL_RXRPC      272
+#define SOL_PPPOL2TP   273
 
 /* IPX options */
 #define IPX_TYPE       1
diff --git a/include/linux/splice.h b/include/linux/splice.h
new file mode 100644 (file)
index 0000000..33e447f
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Function declerations and data structures related to the splice
+ * implementation.
+ *
+ * Copyright (C) 2007 Jens Axboe <jens.axboe@oracle.com>
+ *
+ */
+#ifndef SPLICE_H
+#define SPLICE_H
+
+#include <linux/pipe_fs_i.h>
+
+/*
+ * splice is tied to pipes as a transport (at least for now), so we'll just
+ * add the splice flags here.
+ */
+#define SPLICE_F_MOVE  (0x01)  /* move pages instead of copying */
+#define SPLICE_F_NONBLOCK (0x02) /* don't block on the pipe splicing (but */
+                                /* we may still block on the fd we splice */
+                                /* from/to, of course */
+#define SPLICE_F_MORE  (0x04)  /* expect more data */
+#define SPLICE_F_GIFT  (0x08)  /* pages passed in are a gift */
+
+/*
+ * Passed to the actors
+ */
+struct splice_desc {
+       unsigned int len, total_len;    /* current and remaining length */
+       unsigned int flags;             /* splice flags */
+       /*
+        * actor() private data
+        */
+       union {
+               void __user *userptr;   /* memory to write to */
+               struct file *file;      /* file to read/write */
+               void *data;             /* cookie */
+       } u;
+       loff_t pos;                     /* file position */
+};
+
+struct partial_page {
+       unsigned int offset;
+       unsigned int len;
+       unsigned long private;
+};
+
+/*
+ * Passed to splice_to_pipe
+ */
+struct splice_pipe_desc {
+       struct page **pages;            /* page map */
+       struct partial_page *partial;   /* pages[] may not be contig */
+       int nr_pages;                   /* number of pages in map */
+       unsigned int flags;             /* splice flags */
+       const struct pipe_buf_operations *ops;/* ops associated with output pipe */
+};
+
+typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *,
+                          struct splice_desc *);
+typedef int (splice_direct_actor)(struct pipe_inode_info *,
+                                 struct splice_desc *);
+
+extern ssize_t splice_from_pipe(struct pipe_inode_info *, struct file *,
+                               loff_t *, size_t, unsigned int,
+                               splice_actor *);
+extern ssize_t __splice_from_pipe(struct pipe_inode_info *,
+                                 struct splice_desc *, splice_actor *);
+extern ssize_t splice_to_pipe(struct pipe_inode_info *,
+                             struct splice_pipe_desc *);
+extern ssize_t splice_direct_to_actor(struct file *, struct splice_desc *,
+                                     splice_direct_actor *);
+
+#endif
index 4a7ae8ab6eb873e75aa2f14c59fc40332dd7da48..129d50f2225c02b8bb94505de60dc579b9a87427 100644 (file)
@@ -253,7 +253,7 @@ struct svc_rqst {
                                                 * determine what device number
                                                 * to report (real or virtual)
                                                 */
-       int                     rq_sendfile_ok; /* turned off in gss privacy
+       int                     rq_splice_ok;   /* turned off in gss privacy
                                                 * to prevent encrypting page
                                                 * cache pages */
        wait_queue_head_t       rq_wait;        /* synchronization */
index e699ab279c2c1302d03bdb25e10bd36567fbc507..e285746588d68baf4dccc894e70768005342e04a 100644 (file)
@@ -101,8 +101,7 @@ struct sysdev_attribute {
 
 #define _SYSDEV_ATTR(_name,_mode,_show,_store)                 \
 {                                                              \
-       .attr = { .name = __stringify(_name), .mode = _mode,    \
-                .owner = THIS_MODULE },                        \
+       .attr = { .name = __stringify(_name), .mode = _mode },  \
        .show   = _show,                                        \
        .store  = _store,                                       \
 }
index 7d5d1ec95c2e4b8dc719c042cc6a178550be3f09..be8228e50a2750398f19d9f1699d84e7575cad91 100644 (file)
@@ -19,10 +19,15 @@ struct kobject;
 struct module;
 struct nameidata;
 struct dentry;
+struct sysfs_dirent;
 
+/* FIXME
+ * The *owner field is no longer used, but leave around
+ * until the tree gets cleaned up fully.
+ */
 struct attribute {
        const char              * name;
-       struct module           * owner;
+       struct module           * owner;
        mode_t                  mode;
 };
 
@@ -39,14 +44,14 @@ struct attribute_group {
  */
 
 #define __ATTR(_name,_mode,_show,_store) { \
-       .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE },     \
+       .attr = {.name = __stringify(_name), .mode = _mode },   \
        .show   = _show,                                        \
        .store  = _store,                                       \
 }
 
 #define __ATTR_RO(_name) { \
-       .attr   = { .name = __stringify(_name), .mode = 0444, .owner = THIS_MODULE },   \
-       .show   = _name##_show, \
+       .attr   = { .name = __stringify(_name), .mode = 0444 }, \
+       .show   = _name##_show,                                 \
 }
 
 #define __ATTR_NULL { .attr = { .name = NULL } }
@@ -59,8 +64,10 @@ struct bin_attribute {
        struct attribute        attr;
        size_t                  size;
        void                    *private;
-       ssize_t (*read)(struct kobject *, char *, loff_t, size_t);
-       ssize_t (*write)(struct kobject *, char *, loff_t, size_t);
+       ssize_t (*read)(struct kobject *, struct bin_attribute *,
+                       char *, loff_t, size_t);
+       ssize_t (*write)(struct kobject *, struct bin_attribute *,
+                        char *, loff_t, size_t);
        int (*mmap)(struct kobject *, struct bin_attribute *attr,
                    struct vm_area_struct *vma);
 };
@@ -70,12 +77,16 @@ struct sysfs_ops {
        ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t);
 };
 
+#define SYSFS_TYPE_MASK                0x00ff
 #define SYSFS_ROOT             0x0001
 #define SYSFS_DIR              0x0002
 #define SYSFS_KOBJ_ATTR        0x0004
 #define SYSFS_KOBJ_BIN_ATTR    0x0008
 #define SYSFS_KOBJ_LINK        0x0020
-#define SYSFS_NOT_PINNED       (SYSFS_KOBJ_ATTR | SYSFS_KOBJ_BIN_ATTR | SYSFS_KOBJ_LINK)
+#define SYSFS_COPY_NAME                (SYSFS_DIR | SYSFS_KOBJ_LINK)
+
+#define SYSFS_FLAG_MASK                ~SYSFS_TYPE_MASK
+#define SYSFS_FLAG_REMOVED     0x0100
 
 #ifdef CONFIG_SYSFS
 
@@ -83,13 +94,14 @@ extern int sysfs_schedule_callback(struct kobject *kobj,
                void (*func)(void *), void *data, struct module *owner);
 
 extern int __must_check
-sysfs_create_dir(struct kobject *, struct dentry *);
+sysfs_create_dir(struct kobject *kobj, struct sysfs_dirent *shadow_parent_sd);
 
 extern void
 sysfs_remove_dir(struct kobject *);
 
 extern int __must_check
-sysfs_rename_dir(struct kobject *, struct dentry *, const char *new_name);
+sysfs_rename_dir(struct kobject *kobj, struct sysfs_dirent *new_parent_sd,
+                const char *new_name);
 
 extern int __must_check
 sysfs_move_dir(struct kobject *, struct kobject *);
@@ -129,8 +141,8 @@ void sysfs_notify(struct kobject * k, char *dir, char *attr);
 
 extern int sysfs_make_shadowed_dir(struct kobject *kobj,
        void * (*follow_link)(struct dentry *, struct nameidata *));
-extern struct dentry *sysfs_create_shadow_dir(struct kobject *kobj);
-extern void sysfs_remove_shadow_dir(struct dentry *dir);
+extern struct sysfs_dirent *sysfs_create_shadow_dir(struct kobject *kobj);
+extern void sysfs_remove_shadow_dir(struct sysfs_dirent *shadow_sd);
 
 extern int __must_check sysfs_init(void);
 
@@ -142,7 +154,8 @@ static inline int sysfs_schedule_callback(struct kobject *kobj,
        return -ENOSYS;
 }
 
-static inline int sysfs_create_dir(struct kobject * k, struct dentry *shadow)
+static inline int sysfs_create_dir(struct kobject *kobj,
+                                  struct sysfs_dirent *shadow_parent_sd)
 {
        return 0;
 }
@@ -152,9 +165,9 @@ static inline void sysfs_remove_dir(struct kobject * k)
        ;
 }
 
-static inline int sysfs_rename_dir(struct kobject * k,
-                                       struct dentry *new_parent,
-                                       const char *new_name)
+static inline int sysfs_rename_dir(struct kobject *kobj,
+                                  struct sysfs_dirent *new_parent_sd,
+                                  const char *new_name)
 {
        return 0;
 }
index a9d1f049cc151aa07202ffbc41346dc78a95d4b3..d0890a7e5babb1f96b78a04fa6f471df0edbdd8e 100644 (file)
        for_each_online_node(node)                                              \
                if (nr_cpus_node(node))
 
-#ifndef node_distance
 /* Conform to ACPI 2.0 SLIT distance definitions */
 #define LOCAL_DISTANCE         10
 #define REMOTE_DISTANCE                20
+#ifndef node_distance
 #define node_distance(from,to) ((from) == (to) ? LOCAL_DISTANCE : REMOTE_DISTANCE)
 #endif
 #ifndef RECLAIM_DISTANCE
@@ -98,7 +98,7 @@
        .cache_nice_tries       = 0,                    \
        .busy_idx               = 0,                    \
        .idle_idx               = 0,                    \
-       .newidle_idx            = 1,                    \
+       .newidle_idx            = 0,                    \
        .wake_idx               = 0,                    \
        .forkexec_idx           = 0,                    \
        .flags                  = SD_LOAD_BALANCE       \
        .imbalance_pct          = 125,                  \
        .cache_nice_tries       = 1,                    \
        .busy_idx               = 2,                    \
-       .idle_idx               = 1,                    \
-       .newidle_idx            = 2,                    \
+       .idle_idx               = 0,                    \
+       .newidle_idx            = 0,                    \
        .wake_idx               = 1,                    \
        .forkexec_idx           = 1,                    \
        .flags                  = SD_LOAD_BALANCE       \
                                | SD_BALANCE_NEWIDLE    \
                                | SD_BALANCE_EXEC       \
                                | SD_WAKE_AFFINE        \
+                               | SD_WAKE_IDLE          \
                                | SD_SHARE_PKG_RESOURCES\
                                | BALANCE_FOR_MC_POWER, \
        .last_balance           = jiffies,              \
        .imbalance_pct          = 125,                  \
        .cache_nice_tries       = 1,                    \
        .busy_idx               = 2,                    \
-       .idle_idx               = 1,                    \
-       .newidle_idx            = 2,                    \
+       .idle_idx               = 0,                    \
+       .newidle_idx            = 0,                    \
        .wake_idx               = 1,                    \
        .forkexec_idx           = 1,                    \
        .flags                  = SD_LOAD_BALANCE       \
                                | SD_BALANCE_NEWIDLE    \
                                | SD_BALANCE_EXEC       \
                                | SD_WAKE_AFFINE        \
+                               | SD_WAKE_IDLE          \
                                | BALANCE_FOR_PKG_POWER,\
        .last_balance           = jiffies,              \
        .balance_interval       = 1,                    \
index 6de445c31a6492ae2aee3d1a906a7e993c3b64cb..8ec703f462da9524956a0cef143e3b1d595efcae 100644 (file)
@@ -42,6 +42,7 @@ static inline struct udphdr *udp_hdr(const struct sk_buff *skb)
 /* UDP encapsulation types */
 #define UDP_ENCAP_ESPINUDP_NON_IKE     1 /* draft-ietf-ipsec-nat-t-ike-00/01 */
 #define UDP_ENCAP_ESPINUDP     2 /* draft-ietf-ipsec-udp-encaps-06 */
+#define UDP_ENCAP_L2TPINUDP    3 /* rfc2661 */
 
 #ifdef __KERNEL__
 #include <linux/types.h>
@@ -70,6 +71,11 @@ struct udp_sock {
 #define UDPLITE_SEND_CC  0x2           /* set via udplite setsockopt         */
 #define UDPLITE_RECV_CC  0x4           /* set via udplite setsocktopt        */
        __u8             pcflag;        /* marks socket as UDP-Lite if > 0    */
+       __u8             unused[3];
+       /*
+        * For encapsulation sockets.
+        */
+       int (*encap_rcv)(struct sock *sk, struct sk_buff *skb);
 };
 
 static inline struct udp_sock *udp_sk(const struct sock *sk)
index 94bd38a6d947be480281f3a8e4de4edff7f03c84..7a60946df3b675889f4e4bdc2e5b77ab7fe45a38 100644 (file)
@@ -146,6 +146,10 @@ struct usb_interface {
                                         * active alternate setting */
        unsigned num_altsetting;        /* number of alternate settings */
 
+       /* If there is an interface association descriptor then it will list
+        * the associated interfaces */
+       struct usb_interface_assoc_descriptor *intf_assoc;
+
        int minor;                      /* minor number this interface is
                                         * bound to */
        enum usb_interface_condition condition;         /* state of binding */
@@ -175,6 +179,7 @@ void usb_put_intf(struct usb_interface *intf);
 
 /* this maximum is arbitrary */
 #define USB_MAXINTERFACES      32
+#define USB_MAXIADS            USB_MAXINTERFACES/2
 
 /**
  * struct usb_interface_cache - long-term representation of a device interface
@@ -245,6 +250,11 @@ struct usb_host_config {
        struct usb_config_descriptor    desc;
 
        char *string;           /* iConfiguration string, if present */
+
+       /* List of any Interface Association Descriptors in this
+        * configuration. */
+       struct usb_interface_assoc_descriptor *intf_assoc[USB_MAXIADS];
+
        /* the interfaces associated with this configuration,
         * stored in no particular order */
        struct usb_interface *interface[USB_MAXINTERFACES];
@@ -403,6 +413,8 @@ struct usb_device {
 
        unsigned auto_pm:1;             /* autosuspend/resume in progress */
        unsigned do_remote_wakeup:1;    /* remote wakeup should be enabled */
+       unsigned reset_resume:1;        /* needs reset instead of resume */
+       unsigned persist_enabled:1;     /* USB_PERSIST enabled for this dev */
        unsigned autosuspend_disabled:1; /* autosuspend and autoresume */
        unsigned autoresume_disabled:1;  /*  disabled by the user */
 #endif
@@ -728,6 +740,22 @@ static inline int usb_endpoint_is_isoc_out(const struct usb_endpoint_descriptor
        .idVendor = (vend), .idProduct = (prod), \
        .bcdDevice_lo = (lo), .bcdDevice_hi = (hi)
 
+/**
+ * USB_DEVICE_INTERFACE_PROTOCOL - macro used to describe a usb
+ *             device with a specific interface protocol
+ * @vend: the 16 bit USB Vendor ID
+ * @prod: the 16 bit USB Product ID
+ * @pr: bInterfaceProtocol value
+ *
+ * This macro is used to create a struct usb_device_id that matches a
+ * specific interface protocol of devices.
+ */
+#define USB_DEVICE_INTERFACE_PROTOCOL(vend,prod,pr) \
+       .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_PROTOCOL, \
+       .idVendor = (vend), \
+       .idProduct = (prod), \
+       .bInterfaceProtocol = (pr)
+
 /**
  * USB_DEVICE_INFO - macro used to describe a class of usb devices
  * @cl: bDeviceClass value
@@ -754,6 +782,28 @@ static inline int usb_endpoint_is_isoc_out(const struct usb_endpoint_descriptor
        .match_flags = USB_DEVICE_ID_MATCH_INT_INFO, .bInterfaceClass = (cl), \
        .bInterfaceSubClass = (sc), .bInterfaceProtocol = (pr)
 
+/**
+ * USB_DEVICE_AND_INTERFACE_INFO - macro used to describe a specific usb device
+ *             with a class of usb interfaces
+ * @vend: the 16 bit USB Vendor ID
+ * @prod: the 16 bit USB Product ID
+ * @cl: bInterfaceClass value
+ * @sc: bInterfaceSubClass value
+ * @pr: bInterfaceProtocol value
+ *
+ * This macro is used to create a struct usb_device_id that matches a
+ * specific device with a specific class of interfaces.
+ *
+ * This is especially useful when explicitly matching devices that have
+ * vendor specific bDeviceClass values, but standards-compliant interfaces.
+ */
+#define USB_DEVICE_AND_INTERFACE_INFO(vend,prod,cl,sc,pr) \
+       .match_flags = USB_DEVICE_ID_MATCH_INT_INFO \
+               | USB_DEVICE_ID_MATCH_DEVICE, \
+       .idVendor = (vend), .idProduct = (prod), \
+       .bInterfaceClass = (cl), \
+       .bInterfaceSubClass = (sc), .bInterfaceProtocol = (pr)
+
 /* ----------------------------------------------------------------------- */
 
 /* Stuff for dynamic usb ids */
@@ -800,10 +850,15 @@ struct usbdrv_wrap {
  *     do (or don't) show up otherwise in the filesystem.
  * @suspend: Called when the device is going to be suspended by the system.
  * @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
  *     is about to be reset.
  * @post_reset: Called by usb_reset_composite_device() after the device
- *     has been reset.
+ *     has been reset, or in lieu of @resume following a reset-resume
+ *     (i.e., the device is reset instead of being resumed, as might
+ *     happen if power was lost).  The second argument tells which is
+ *     the reason.
  * @id_table: USB drivers use ID table to support hotplugging.
  *     Export this with MODULE_DEVICE_TABLE(usb,...).  This must be set
  *     or your driver's probe function will never get called.
@@ -843,9 +898,10 @@ struct usb_driver {
 
        int (*suspend) (struct usb_interface *intf, pm_message_t message);
        int (*resume) (struct usb_interface *intf);
+       int (*reset_resume)(struct usb_interface *intf);
 
-       void (*pre_reset) (struct usb_interface *intf);
-       void (*post_reset) (struct usb_interface *intf);
+       int (*pre_reset)(struct usb_interface *intf);
+       int (*post_reset)(struct usb_interface *intf);
 
        const struct usb_device_id *id_table;
 
@@ -948,6 +1004,7 @@ extern int usb_disabled(void);
 #define URB_ZERO_PACKET                0x0040  /* Finish bulk OUT with short packet */
 #define URB_NO_INTERRUPT       0x0080  /* HINT: no non-error interrupt
                                         * needed */
+#define URB_FREE_BUFFER                0x0100  /* Free transfer buffer with the URB */
 
 struct usb_iso_packet_descriptor {
        unsigned int offset;
@@ -958,11 +1015,26 @@ struct usb_iso_packet_descriptor {
 
 struct urb;
 
+struct usb_anchor {
+       struct list_head urb_list;
+       wait_queue_head_t wait;
+       spinlock_t lock;
+};
+
+static inline void init_usb_anchor(struct usb_anchor *anchor)
+{
+       INIT_LIST_HEAD(&anchor->urb_list);
+       init_waitqueue_head(&anchor->wait);
+       spin_lock_init(&anchor->lock);
+}
+
 typedef void (*usb_complete_t)(struct urb *);
 
 /**
  * struct urb - USB Request Block
  * @urb_list: For use by current owner of the URB.
+ * @anchor_list: membership in the list of an anchor
+ * @anchor: to anchor URBs to a common mooring
  * @pipe: Holds endpoint number, direction, type, and more.
  *     Create these values with the eight macros available;
  *     usb_{snd,rcv}TYPEpipe(dev,endpoint), where the TYPE is "ctrl"
@@ -1135,6 +1207,8 @@ struct urb
        /* public: documented fields in the urb that can be used by drivers */
        struct list_head urb_list;      /* list head for use by the urb's
                                         * current owner */
+       struct list_head anchor_list;   /* the URB may be anchored by the driver */
+       struct usb_anchor *anchor;
        struct usb_device *dev;         /* (in) pointer to associated device */
        unsigned int pipe;              /* (in) pipe information */
        int status;                     /* (return) non-ISO status */
@@ -1270,6 +1344,11 @@ extern struct urb *usb_get_urb(struct urb *urb);
 extern int usb_submit_urb(struct urb *urb, gfp_t mem_flags);
 extern int usb_unlink_urb(struct urb *urb);
 extern void usb_kill_urb(struct urb *urb);
+extern void usb_kill_anchored_urbs(struct usb_anchor *anchor);
+extern void usb_anchor_urb(struct urb *urb, struct usb_anchor *anchor);
+extern void usb_unanchor_urb(struct urb *urb);
+extern int usb_wait_anchor_empty_timeout(struct usb_anchor *anchor,
+                                        unsigned int timeout);
 
 void *usb_buffer_alloc (struct usb_device *dev, size_t size,
        gfp_t mem_flags, dma_addr_t *dma);
index 43f160cfe00342af04b57183070b6315a31d87c8..6ce42bf9f743960a97fe95317542d042046dc059 100644 (file)
@@ -1,5 +1,6 @@
 unifdef-y += audio.h
 unifdef-y += cdc.h
 unifdef-y += ch9.h
+unifdef-y += gadgetfs.h
 unifdef-y += midi.h
 
similarity index 74%
rename from include/linux/usb_gadgetfs.h
rename to include/linux/usb/gadgetfs.h
index 8086d5a9b94e582b595fb32df5afbb2e5a391fb5..e8654c338729438de4b6d887b53c7dec725b3600 100644 (file)
@@ -1,3 +1,5 @@
+#ifndef __LINUX_USB_GADGETFS_H
+#define __LINUX_USB_GADGETFS_H
 
 #include <asm/types.h>
 #include <asm/ioctl.h>
@@ -7,11 +9,12 @@
 /*
  * Filesystem based user-mode API to USB Gadget controller hardware
  *
- * Almost everything can be done with only read and write operations,
+ * Other than ep0 operations, most things are done by read() and write()
  * on endpoint files found in one directory.  They are configured by
  * writing descriptors, and then may be used for normal stream style
  * i/o requests.  When ep0 is configured, the device can enumerate;
- * when it's closed, the device disconnects from usb.
+ * when it's closed, the device disconnects from usb.  Operations on
+ * ep0 require ioctl() operations.
  *
  * Configuration and device descriptors get written to /dev/gadget/$CHIP,
  * which may then be used to read usb_gadgetfs_event structs.  The driver
@@ -21,9 +24,9 @@
  */
 
 /*
- * Events are delivered on the ep0 file descriptor, if the user mode driver
+ * Events are delivered on the ep0 file descriptor, when the user mode driver
  * reads from this file descriptor after writing the descriptors.  Don't
- * stop polling this descriptor, if you write that kind of driver.
+ * stop polling this descriptor.
  */
 
 enum usb_gadgetfs_event_type {
@@ -36,8 +39,10 @@ enum usb_gadgetfs_event_type {
        // and likely more !
 };
 
+/* NOTE:  this structure must stay the same size and layout on
+ * both 32-bit and 64-bit kernels.
+ */
 struct usb_gadgetfs_event {
-       enum usb_gadgetfs_event_type    type;
        union {
                // NOP, DISCONNECT, SUSPEND: nothing
                // ... some hardware can't report disconnection
@@ -46,19 +51,20 @@ struct usb_gadgetfs_event {
                enum usb_device_speed   speed;
 
                // SETUP: packet; DATA phase i/o precedes next event
-               // (setup.bmRequestType & USB_DIR_IN) flags direction 
+               // (setup.bmRequestType & USB_DIR_IN) flags direction
                // ... includes SET_CONFIGURATION, SET_INTERFACE
                struct usb_ctrlrequest  setup;
        } u;
+       enum usb_gadgetfs_event_type    type;
 };
 
 
 /* endpoint ioctls */
 
 /* IN transfers may be reported to the gadget driver as complete
- *     when the fifo is loaded, before the host reads the data;
+ *     when the fifo is loaded, before the host reads the data;
  * OUT transfers may be reported to the host's "client" driver as
- *     complete when they're sitting in the FIFO unread.
+ *     complete when they're sitting in the FIFO unread.
  * THIS returns how many bytes are "unclaimed" in the endpoint fifo
  * (needed for precise fault handling, when the hardware allows it)
  */
@@ -72,4 +78,4 @@ struct usb_gadgetfs_event {
  */
 #define        GADGETFS_CLEAR_HALT     _IO('g',3)
 
-
+#endif /* __LINUX_USB_GADGETFS_H */
index 6bac8faacbc6e8f00de074e62735f801a8213686..8da374caf582aeb3136c5d3f90722906ca8fa2dd 100644 (file)
@@ -9,3 +9,6 @@
 
 /* string descriptors must not be fetched using a 255-byte read */
 #define USB_QUIRK_STRING_FETCH_255     0x00000002
+
+/* device can't resume correctly so reset it instead */
+#define USB_QUIRK_RESET_RESUME         0x00000004
index 32acbae28d24d34a1ea9d011945e7cc5e9e3ee06..e8b8928232c85ca2db65b12b997acc4832dbb55e 100644 (file)
@@ -221,6 +221,9 @@ struct usb_serial_driver {
        int (*port_probe) (struct usb_serial_port *port);
        int (*port_remove) (struct usb_serial_port *port);
 
+       int (*suspend) (struct usb_serial *serial, pm_message_t message);
+       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);
@@ -249,6 +252,9 @@ extern void usb_serial_port_softint(struct usb_serial_port *port);
 extern int usb_serial_probe(struct usb_interface *iface, const struct usb_device_id *id);
 extern void usb_serial_disconnect(struct usb_interface *iface);
 
+extern int usb_serial_suspend(struct usb_interface *intf, pm_message_t message);
+extern int usb_serial_resume(struct usb_interface *intf);
+
 extern int ezusb_writememory (struct usb_serial *serial, int address, unsigned char *data, int length, __u8 bRequest);
 extern int ezusb_set_reset (struct usb_serial *serial, unsigned char reset_bit);
 
@@ -269,6 +275,7 @@ 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_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 void usb_serial_generic_read_bulk_callback (struct urb *urb);
index e17186dbcdcabfbcbe32a02917e46c9eea270ac3..4f59b2aa8a9e002caf7a343735de86fd518d28ee 100644 (file)
@@ -110,13 +110,6 @@ struct usb_ep_ops {
                gfp_t gfp_flags);
        void (*free_request) (struct usb_ep *ep, struct usb_request *req);
 
-       void *(*alloc_buffer) (struct usb_ep *ep, unsigned bytes,
-               dma_addr_t *dma, gfp_t gfp_flags);
-       void (*free_buffer) (struct usb_ep *ep, void *buf, dma_addr_t dma,
-               unsigned bytes);
-       // NOTE:  on 2.6, drivers may also use dma_map() and
-       // dma_sync_single_*() to directly manage dma overhead. 
-
        int (*queue) (struct usb_ep *ep, struct usb_request *req,
                gfp_t gfp_flags);
        int (*dequeue) (struct usb_ep *ep, struct usb_request *req);
@@ -234,47 +227,6 @@ usb_ep_free_request (struct usb_ep *ep, struct usb_request *req)
        ep->ops->free_request (ep, req);
 }
 
-/**
- * usb_ep_alloc_buffer - allocate an I/O buffer
- * @ep:the endpoint associated with the buffer
- * @len:length of the desired buffer
- * @dma:pointer to the buffer's DMA address; must be valid
- * @gfp_flags:GFP_* flags to use
- *
- * Returns a new buffer, or null if one could not be allocated.
- * The buffer is suitably aligned for dma, if that endpoint uses DMA,
- * and the caller won't have to care about dma-inconsistency
- * or any hidden "bounce buffer" mechanism.  No additional per-request
- * DMA mapping will be required for such buffers.
- * Free it later with usb_ep_free_buffer().
- *
- * You don't need to use this call to allocate I/O buffers unless you
- * want to make sure drivers don't incur costs for such "bounce buffer"
- * copies or per-request DMA mappings.
- */
-static inline void *
-usb_ep_alloc_buffer (struct usb_ep *ep, unsigned len, dma_addr_t *dma,
-       gfp_t gfp_flags)
-{
-       return ep->ops->alloc_buffer (ep, len, dma, gfp_flags);
-}
-
-/**
- * usb_ep_free_buffer - frees an i/o buffer
- * @ep:the endpoint associated with the buffer
- * @buf:CPU view address of the buffer
- * @dma:the buffer's DMA address
- * @len:length of the buffer
- *
- * reverses the effect of usb_ep_alloc_buffer().
- * caller guarantees the buffer will no longer be accessed
- */
-static inline void
-usb_ep_free_buffer (struct usb_ep *ep, void *buf, dma_addr_t dma, unsigned len)
-{
-       ep->ops->free_buffer (ep, buf, dma, len);
-}
-
 /**
  * usb_ep_queue - queues (submits) an I/O request to an endpoint.
  * @ep:the endpoint associated with the request
index e820d00e13836af125710e67753ad5fee2b9bc36..0e686280450b3808eb2bbda7124772896b879ac7 100644 (file)
@@ -366,15 +366,15 @@ static inline void remove_wait_queue_locked(wait_queue_head_t *q,
 
 /*
  * These are the old interfaces to sleep waiting for an event.
- * They are racy.  DO NOT use them, use the wait_event* interfaces above.  
- * We plan to remove these interfaces during 2.7.
+ * They are racy.  DO NOT use them, use the wait_event* interfaces above.
+ * We plan to remove these interfaces.
  */
-extern void FASTCALL(sleep_on(wait_queue_head_t *q));
-extern long FASTCALL(sleep_on_timeout(wait_queue_head_t *q,
-                                     signed long timeout));
-extern void FASTCALL(interruptible_sleep_on(wait_queue_head_t *q));
-extern long FASTCALL(interruptible_sleep_on_timeout(wait_queue_head_t *q,
-                                                   signed long timeout));
+extern void sleep_on(wait_queue_head_t *q);
+extern long sleep_on_timeout(wait_queue_head_t *q,
+                                     signed long timeout);
+extern void interruptible_sleep_on(wait_queue_head_t *q);
+extern long interruptible_sleep_on_timeout(wait_queue_head_t *q,
+                                          signed long timeout);
 
 /*
  * Waitqueues which are removed from the waitqueue_head at wakeup time
index 8b06c2f3657f3b4b4923c7a856d278778f8f3138..2f0273feabd3a563202ef0b1c40b0fc5731b3b66 100644 (file)
@@ -19,7 +19,6 @@ struct tcf_common {
        struct gnet_stats_basic         tcfc_bstats;
        struct gnet_stats_queue         tcfc_qstats;
        struct gnet_stats_rate_est      tcfc_rate_est;
-       spinlock_t                      *tcfc_stats_lock;
        spinlock_t                      tcfc_lock;
 };
 #define tcf_next       common.tcfc_next
@@ -32,7 +31,6 @@ struct tcf_common {
 #define tcf_bstats     common.tcfc_bstats
 #define tcf_qstats     common.tcfc_qstats
 #define tcf_rate_est   common.tcfc_rate_est
-#define tcf_stats_lock common.tcfc_stats_lock
 #define tcf_lock       common.tcfc_lock
 
 struct tcf_police {
index f3531d0bcd051ae62bb31e655d197877e27b2122..33b593e174412792347be0d366a1f036e963430e 100644 (file)
@@ -61,7 +61,7 @@ extern int                    addrconf_set_dstaddr(void __user *arg);
 extern int                     ipv6_chk_addr(struct in6_addr *addr,
                                              struct net_device *dev,
                                              int strict);
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 extern int                     ipv6_chk_home_addr(struct in6_addr *addr);
 #endif
 extern struct inet6_ifaddr *   ipv6_get_ifaddr(struct in6_addr *addr,
index 65f49fd7deff1620c3f6fdc9102c717f8f2dedae..6de1e9e35c73e6dfe97cb44538878bf639d8e4f7 100644 (file)
@@ -79,9 +79,10 @@ struct unix_sock {
        struct mutex            readlock;
         struct sock            *peer;
         struct sock            *other;
-        struct sock            *gc_tree;
+       struct list_head        link;
         atomic_t                inflight;
         spinlock_t             lock;
+       unsigned int            gc_candidate : 1;
         wait_queue_head_t       peer_wait;
 };
 #define unix_sk(__sk) ((struct unix_sock *)__sk)
diff --git a/include/net/ax88796.h b/include/net/ax88796.h
new file mode 100644 (file)
index 0000000..ee786a0
--- /dev/null
@@ -0,0 +1,27 @@
+/* include/net/ax88796.h
+ *
+ * Copyright 2005 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * 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 __NET_AX88796_PLAT_H
+#define __NET_AX88796_PLAT_H
+
+#define AXFLG_HAS_EEPROM               (1<<0)
+#define AXFLG_MAC_FROMDEV              (1<<1)  /* device already has MAC */
+
+struct ax_plat_data {
+       unsigned int     flags;
+       unsigned char    wordlength;            /* 1 or 2 */
+       unsigned char    dcr_val;               /* default value for DCR */
+       unsigned char    rcr_val;               /* default value for RCR */
+       unsigned char    gpoc_val;              /* default value for GPOC */
+       u32             *reg_offsets;           /* register offsets */
+};
+
+#endif /* __NET_AX88796_PLAT_H */
index 93ce272a5d27edbe37fef616217e3e37f3fcfb14..ebfb96b41106a0c3c7df7ac247cb3994bf1083b1 100644 (file)
@@ -107,14 +107,14 @@ enum {
 #define HCI_IDLE_TIMEOUT       (6000)  /* 6 seconds */
 #define HCI_INIT_TIMEOUT       (10000) /* 10 seconds */
 
-/* HCI Packet types */
+/* HCI data types */
 #define HCI_COMMAND_PKT                0x01
 #define HCI_ACLDATA_PKT                0x02
 #define HCI_SCODATA_PKT                0x03
 #define HCI_EVENT_PKT          0x04
 #define HCI_VENDOR_PKT         0xff
 
-/* HCI Packet types */
+/* HCI packet types */
 #define HCI_DM1                0x0008
 #define HCI_DM3                0x0400
 #define HCI_DM5                0x4000
@@ -129,6 +129,14 @@ enum {
 #define SCO_PTYPE_MASK (HCI_HV1 | HCI_HV2 | HCI_HV3)
 #define ACL_PTYPE_MASK (~SCO_PTYPE_MASK)
 
+/* eSCO packet types */
+#define ESCO_HV1       0x0001
+#define ESCO_HV2       0x0002
+#define ESCO_HV3       0x0004
+#define ESCO_EV3       0x0008
+#define ESCO_EV4       0x0010
+#define ESCO_EV5       0x0020
+
 /* ACL flags */
 #define ACL_CONT               0x01
 #define ACL_START              0x02
@@ -138,6 +146,7 @@ enum {
 /* Baseband links */
 #define SCO_LINK       0x00
 #define ACL_LINK       0x01
+#define ESCO_LINK      0x02
 
 /* LMP features */
 #define LMP_3SLOT      0x01
@@ -162,6 +171,11 @@ enum {
 #define LMP_PSCHEME    0x02
 #define LMP_PCONTROL   0x04
 
+#define LMP_ESCO       0x80
+
+#define LMP_EV4                0x01
+#define LMP_EV5                0x02
+
 #define LMP_SNIFF_SUBR 0x02
 
 /* Connection modes */
index c0fc39620f3643c4393ba2b1d99c8181498b0da0..8f67c8a7169beffc42667697b6c91c2f5459c602 100644 (file)
@@ -78,6 +78,7 @@ struct hci_dev {
        __u16           voice_setting;
 
        __u16           pkt_type;
+       __u16           esco_type;
        __u16           link_policy;
        __u16           link_mode;
 
@@ -109,6 +110,7 @@ struct hci_dev {
        struct sk_buff_head     cmd_q;
 
        struct sk_buff          *sent_cmd;
+       struct sk_buff          *reassembly[3];
 
        struct semaphore        req_lock;
        wait_queue_head_t       req_wait_q;
@@ -437,6 +439,8 @@ static inline int hci_recv_frame(struct sk_buff *skb)
        return 0;
 }
 
+int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count);
+
 int hci_register_sysfs(struct hci_dev *hdev);
 void hci_unregister_sysfs(struct hci_dev *hdev);
 void hci_conn_add_sysfs(struct hci_conn *conn);
@@ -449,6 +453,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
 #define lmp_encrypt_capable(dev)   ((dev)->features[0] & LMP_ENCRYPT)
 #define lmp_sniff_capable(dev)     ((dev)->features[0] & LMP_SNIFF)
 #define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR)
+#define lmp_esco_capable(dev)      ((dev)->features[3] & LMP_ESCO)
 
 /* ----- HCI protocols ----- */
 struct hci_proto {
index 3c563f02907cc5228b21aac7967f874039047f4c..25aa575db807b8e7881aec4bcafa428e24dbb779 100644 (file)
@@ -323,6 +323,7 @@ int  rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc
 #define RFCOMM_RELEASE_ONHUP  1
 #define RFCOMM_HANGUP_NOW     2
 #define RFCOMM_TTY_ATTACHED   3
+#define RFCOMM_TTY_RELEASED   4
 
 struct rfcomm_dev_req {
        s16      dev_id;
index ac4ce9091747cd6660c5d77a7bce868e8e7a1747..627778384c84cff9583636abebdd3b210df0ad63 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <linux/dn.h>
 #include <net/sock.h>
-#include <net/tcp.h>
 #include <asm/byteorder.h>
 
 #define dn_ntohs(x) le16_to_cpu(x)
index 82270f9332db94077bb6d95bcca2f2ef0010c636..e9ff4a4caef992806909de300cb92421b5be90ae 100644 (file)
@@ -47,7 +47,6 @@ struct dst_entry
 #define DST_NOXFRM             2
 #define DST_NOPOLICY           4
 #define DST_NOHASH             8
-#define DST_BALANCED            0x10
        unsigned long           expires;
 
        unsigned short          header_len;     /* more space at head required */
index f3cc1f8126190d38e72d50157a98d9e1d17e7f1c..af59fa5cc1f82560360833d02d60144e32662555 100644 (file)
@@ -67,20 +67,16 @@ struct flowi {
 
                __be32          spi;
 
-#ifdef CONFIG_IPV6_MIP6
                struct {
                        __u8    type;
                } mht;
-#endif
        } uli_u;
 #define fl_ip_sport    uli_u.ports.sport
 #define fl_ip_dport    uli_u.ports.dport
 #define fl_icmp_type   uli_u.icmpt.type
 #define fl_icmp_code   uli_u.icmpt.code
 #define fl_ipsec_spi   uli_u.spi
-#ifdef CONFIG_IPV6_MIP6
 #define fl_mh_type     uli_u.mht.type
-#endif
        __u32           secid;  /* used by xfrm; see secid.txt */
 } __attribute__((__aligned__(BITS_PER_LONG/8)));
 
index 69252cbe05b0392fe392b4ca708784330ba73f29..8cadc77c7df4bfbd58d02c3b03ecddc01d9e85af 100644 (file)
@@ -39,7 +39,6 @@ struct fib_config {
        int                     fc_mx_len;
        int                     fc_mp_len;
        u32                     fc_flow;
-       u32                     fc_mp_alg;
        u32                     fc_nlflags;
        struct nl_info          fc_nlinfo;
  };
@@ -85,9 +84,6 @@ struct fib_info {
        int                     fib_nhs;
 #ifdef CONFIG_IP_ROUTE_MULTIPATH
        int                     fib_power;
-#endif
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-       u32                     fib_mp_alg;
 #endif
        struct fib_nh           fib_nh[0];
 #define fib_dev                fib_nh[0].nh_dev
@@ -103,10 +99,6 @@ struct fib_result {
        unsigned char   nh_sel;
        unsigned char   type;
        unsigned char   scope;
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-       __be32          network;
-       __be32          netmask;
-#endif
        struct fib_info *fi;
 #ifdef CONFIG_IP_MULTIPLE_TABLES
        struct fib_rule *r;
@@ -145,14 +137,6 @@ struct fib_result_nl {
 #define FIB_RES_DEV(res)               (FIB_RES_NH(res).nh_dev)
 #define FIB_RES_OIF(res)               (FIB_RES_NH(res).nh_oif)
 
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-#define FIB_RES_NETWORK(res)           ((res).network)
-#define FIB_RES_NETMASK(res)           ((res).netmask)
-#else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
-#define FIB_RES_NETWORK(res)           (0)
-#define FIB_RES_NETMASK(res)           (0)
-#endif /* CONFIG_IP_ROUTE_MULTIPATH_WRANDOM */
-
 struct fib_table {
        struct hlist_node tb_hlist;
        u32             tb_id;
diff --git a/include/net/ip_mp_alg.h b/include/net/ip_mp_alg.h
deleted file mode 100644 (file)
index 25b5657..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/* ip_mp_alg.h: IPV4 multipath algorithm support.
- *
- * Copyright (C) 2004, 2005 Einar Lueck <elueck@de.ibm.com>
- * Copyright (C) 2005 David S. Miller <davem@davemloft.net>
- */
-
-#ifndef _NET_IP_MP_ALG_H
-#define _NET_IP_MP_ALG_H
-
-#include <linux/ip_mp_alg.h>
-#include <net/flow.h>
-#include <net/route.h>
-
-struct fib_nh;
-
-struct ip_mp_alg_ops {
-       void    (*mp_alg_select_route)(const struct flowi *flp,
-                                      struct rtable *rth, struct rtable **rp);
-       void    (*mp_alg_flush)(void);
-       void    (*mp_alg_set_nhinfo)(__be32 network, __be32 netmask,
-                                    unsigned char prefixlen,
-                                    const struct fib_nh *nh);
-       void    (*mp_alg_remove)(struct rtable *rth);
-};
-
-extern int multipath_alg_register(struct ip_mp_alg_ops *, enum ip_mp_alg);
-extern void multipath_alg_unregister(struct ip_mp_alg_ops *, enum ip_mp_alg);
-
-extern struct ip_mp_alg_ops *ip_mp_alg_table[];
-
-static inline int multipath_select_route(const struct flowi *flp,
-                                        struct rtable *rth,
-                                        struct rtable **rp)
-{
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-       struct ip_mp_alg_ops *ops = ip_mp_alg_table[rth->rt_multipath_alg];
-
-       /* mp_alg_select_route _MUST_ be implemented */
-       if (ops && (rth->u.dst.flags & DST_BALANCED)) {
-               ops->mp_alg_select_route(flp, rth, rp);
-               return 1;
-       }
-#endif
-       return 0;
-}
-
-static inline void multipath_flush(void)
-{
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-       int i;
-
-       for (i = IP_MP_ALG_NONE; i <= IP_MP_ALG_MAX; i++) {
-               struct ip_mp_alg_ops *ops = ip_mp_alg_table[i];
-
-               if (ops && ops->mp_alg_flush)
-                       ops->mp_alg_flush();
-       }
-#endif
-}
-
-static inline void multipath_set_nhinfo(struct rtable *rth,
-                                       __be32 network, __be32 netmask,
-                                       unsigned char prefixlen,
-                                       const struct fib_nh *nh)
-{
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-       struct ip_mp_alg_ops *ops = ip_mp_alg_table[rth->rt_multipath_alg];
-
-       if (ops && ops->mp_alg_set_nhinfo)
-               ops->mp_alg_set_nhinfo(network, netmask, prefixlen, nh);
-#endif
-}
-
-static inline void multipath_remove(struct rtable *rth)
-{
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-       struct ip_mp_alg_ops *ops = ip_mp_alg_table[rth->rt_multipath_alg];
-
-       if (ops && ops->mp_alg_remove &&
-           (rth->u.dst.flags & DST_BALANCED))
-               ops->mp_alg_remove(rth);
-#endif
-}
-
-static inline int multipath_comparekeys(const struct flowi *flp1,
-                                       const struct flowi *flp2)
-{
-       return flp1->fl4_dst == flp2->fl4_dst &&
-               flp1->fl4_src == flp2->fl4_src &&
-               flp1->oif == flp2->oif &&
-               flp1->mark == flp2->mark &&
-               !((flp1->fl4_tos ^ flp2->fl4_tos) &
-                 (IPTOS_RT_MASK | RTO_ONLINK));
-}
-
-#endif /* _NET_IP_MP_ALG_H */
index 78a0d06d98d5420b2094b4c5a78b9d62c1cfdc10..46b9dce82f6e3e60255d6bd1efdb413627e00363 100644 (file)
@@ -512,10 +512,6 @@ extern int                         ipv6_ext_hdr(u8 nexthdr);
 
 extern int ipv6_find_tlv(struct sk_buff *skb, int offset, int type);
 
-extern struct ipv6_txoptions * ipv6_invert_rthdr(struct sock *sk,
-                                                 struct ipv6_rt_hdr *hdr);
-
-
 /*
  *     socket options (ipv6_sockglue.c)
  */
index 36bee441aa56cec008017badcdb235487f947cd8..08387553b57e5ee18aeb9f3c8890cdd3d5f54a20 100644 (file)
@@ -125,6 +125,9 @@ extern void irda_sysctl_unregister(void);
 extern int irsock_init(void);
 extern void irsock_cleanup(void);
 
+extern int irda_nl_register(void);
+extern void irda_nl_unregister(void);
+
 extern int irlap_driver_rcv(struct sk_buff *skb, struct net_device *dev,
                            struct packet_type *ptype,
                            struct net_device *orig_dev);
index a3d370efb9034b55ea7b31bd5772928a06411151..9d0c78ea92f5a994b3b615041316f427d9504be9 100644 (file)
@@ -208,6 +208,8 @@ struct irlap_cb {
        int    xbofs_delay;   /* Nr of XBOF's used to MTT */
        int    bofs_count;    /* Negotiated extra BOFs */
        int    next_bofs;     /* Negotiated extra BOFs after next frame */
+
+       int    mode;     /* IrLAP mode (primary, secondary or monitor) */
 };
 
 /* 
index 68263c6d99960210138aed30aac13242c367ff15..63272610a24a4cd3c9f32951c78174189d5d3529 100644 (file)
@@ -54,8 +54,4 @@ struct ip6_mh {
 #define IP6_MH_TYPE_BERROR     7   /* Binding Error */
 #define IP6_MH_TYPE_MAX                IP6_MH_TYPE_BERROR
 
-extern int mip6_init(void);
-extern void mip6_fini(void);
-extern int mip6_mh_filter(struct sock *sk, struct sk_buff *skb);
-
 #endif
index 1401ccc051c4dfad50db1fe7fe41cc115f4b2644..3ed4e14970c5032ee292fe35679b3ffec124c5fa 100644 (file)
@@ -9,29 +9,8 @@
 #ifndef _NF_CONNTRACK_IPV4_H
 #define _NF_CONNTRACK_IPV4_H
 
-#ifdef CONFIG_NF_NAT_NEEDED
-#include <net/netfilter/nf_nat.h>
-#include <linux/netfilter/nf_conntrack_pptp.h>
-
-/* per conntrack: nat application helper private data */
-union nf_conntrack_nat_help {
-        /* insert nat helper private data here */
-       struct nf_nat_pptp nat_pptp_info;
-};
-
-struct nf_conn_nat {
-       struct nf_nat_info info;
-       union nf_conntrack_nat_help help;
-#if defined(CONFIG_IP_NF_TARGET_MASQUERADE) || \
-       defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE)
-       int masq_index;
-#endif
-};
-#endif /* CONFIG_NF_NAT_NEEDED */
-
 /* Returns new sk_buff, or NULL */
-struct sk_buff *
-nf_ct_ipv4_ct_gather_frags(struct sk_buff *skb);
+struct sk_buff *nf_ct_ipv4_ct_gather_frags(struct sk_buff *skb);
 
 extern struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4;
 extern struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4;
index 4732432f8eb0942fe90f11dea289344958c2b9a3..d4f02eb0c66cdfe98b1af484afb4137c7e18a52f 100644 (file)
@@ -82,6 +82,8 @@ struct nf_conn_help {
 
        union nf_conntrack_help help;
 
+       struct hlist_head expectations;
+
        /* Current number of expected connections */
        unsigned int expecting;
 };
@@ -117,9 +119,6 @@ struct nf_conn
        /* Unique ID that identifies this conntrack*/
        unsigned int id;
 
-       /* features - nat, helper, ... used by allocating system */
-       u_int32_t features;
-
 #if defined(CONFIG_NF_CONNTRACK_MARK)
        u_int32_t mark;
 #endif
@@ -131,8 +130,8 @@ struct nf_conn
        /* Storage reserved for other modules: */
        union nf_conntrack_proto proto;
 
-       /* features dynamically at the end: helper, nat (both optional) */
-       char data[0];
+       /* Extensions */
+       struct nf_ct_ext *ext;
 };
 
 static inline struct nf_conn *
@@ -175,6 +174,10 @@ static inline void nf_ct_put(struct nf_conn *ct)
 extern int nf_ct_l3proto_try_module_get(unsigned short l3proto);
 extern void nf_ct_l3proto_module_put(unsigned short l3proto);
 
+extern struct hlist_head *nf_ct_alloc_hashtable(int *sizep, int *vmalloced);
+extern void nf_ct_free_hashtable(struct hlist_head *hash, int vmalloced,
+                                int size);
+
 extern struct nf_conntrack_tuple_hash *
 __nf_conntrack_find(const struct nf_conntrack_tuple *tuple,
                    const struct nf_conn *ignored_conntrack);
@@ -216,9 +219,6 @@ extern void nf_conntrack_tcp_update(struct sk_buff *skb,
                                    struct nf_conn *conntrack,
                                    int dir);
 
-/* Call me when a conntrack is destroyed. */
-extern void (*nf_conntrack_destroyed)(struct nf_conn *conntrack);
-
 /* Fake conntrack entry for untracked connections */
 extern struct nf_conn nf_conntrack_untracked;
 
@@ -262,60 +262,10 @@ do {                                                      \
        local_bh_enable();                              \
 } while (0)
 
-/* no helper, no nat */
-#define        NF_CT_F_BASIC   0
-/* for helper */
-#define        NF_CT_F_HELP    1
-/* for nat. */
-#define        NF_CT_F_NAT     2
-#define NF_CT_F_NUM    4
-
 extern int
 nf_conntrack_register_cache(u_int32_t features, const char *name, size_t size);
 extern void
 nf_conntrack_unregister_cache(u_int32_t features);
 
-/* valid combinations:
- * basic: nf_conn, nf_conn .. nf_conn_help
- * nat: nf_conn .. nf_conn_nat, nf_conn .. nf_conn_nat .. nf_conn help
- */
-#ifdef CONFIG_NF_NAT_NEEDED
-static inline struct nf_conn_nat *nfct_nat(const struct nf_conn *ct)
-{
-       unsigned int offset = sizeof(struct nf_conn);
-
-       if (!(ct->features & NF_CT_F_NAT))
-               return NULL;
-
-       offset = ALIGN(offset, __alignof__(struct nf_conn_nat));
-       return (struct nf_conn_nat *) ((void *)ct + offset);
-}
-
-static inline struct nf_conn_help *nfct_help(const struct nf_conn *ct)
-{
-       unsigned int offset = sizeof(struct nf_conn);
-
-       if (!(ct->features & NF_CT_F_HELP))
-               return NULL;
-       if (ct->features & NF_CT_F_NAT) {
-               offset = ALIGN(offset, __alignof__(struct nf_conn_nat));
-               offset += sizeof(struct nf_conn_nat);
-       }
-
-       offset = ALIGN(offset, __alignof__(struct nf_conn_help));
-       return (struct nf_conn_help *) ((void *)ct + offset);
-}
-#else /* No NAT */
-static inline struct nf_conn_help *nfct_help(const struct nf_conn *ct)
-{
-       unsigned int offset = sizeof(struct nf_conn);
-
-       if (!(ct->features & NF_CT_F_HELP))
-               return NULL;
-
-       offset = ALIGN(offset, __alignof__(struct nf_conn_help));
-       return (struct nf_conn_help *) ((void *)ct + offset);
-}
-#endif /* CONFIG_NF_NAT_NEEDED */
 #endif /* __KERNEL__ */
 #endif /* _NF_CONNTRACK_H */
index 9fb906688ffab51a2035c36082d53b4a335fe198..4056f5f08da1eb3a7bf95c4743b0b2d936028a1e 100644 (file)
@@ -30,6 +30,9 @@ extern void nf_conntrack_cleanup(void);
 extern int nf_conntrack_proto_init(void);
 extern void nf_conntrack_proto_fini(void);
 
+extern int nf_conntrack_helper_init(void);
+extern void nf_conntrack_helper_fini(void);
+
 struct nf_conntrack_l3proto;
 extern struct nf_conntrack_l3proto *nf_ct_find_l3proto(u_int16_t pf);
 /* Like above, but you already have conntrack read lock. */
@@ -55,8 +58,7 @@ nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse,
 
 /* Find a connection corresponding to a tuple. */
 extern struct nf_conntrack_tuple_hash *
-nf_conntrack_find_get(const struct nf_conntrack_tuple *tuple,
-                     const struct nf_conn *ignored_conntrack);
+nf_conntrack_find_get(const struct nf_conntrack_tuple *tuple);
 
 extern int __nf_conntrack_confirm(struct sk_buff **pskb);
 
@@ -81,9 +83,8 @@ print_tuple(struct seq_file *s, const struct nf_conntrack_tuple *tuple,
            struct nf_conntrack_l3proto *l3proto,
            struct nf_conntrack_l4proto *proto);
 
-extern struct list_head *nf_conntrack_hash;
-extern struct list_head nf_conntrack_expect_list;
+extern struct hlist_head *nf_conntrack_hash;
 extern rwlock_t nf_conntrack_lock ;
-extern struct list_head unconfirmed;
+extern struct hlist_head unconfirmed;
 
 #endif /* _NF_CONNTRACK_CORE_H */
index 811c9073c5324521c453bf2c5f80fab4fdd63263..f0b9078235c9f0ac88570c3094204bf2258691d7 100644 (file)
@@ -49,15 +49,15 @@ static inline void nf_conntrack_event(enum ip_conntrack_events event,
                atomic_notifier_call_chain(&nf_conntrack_chain, event, ct);
 }
 
-extern struct atomic_notifier_head nf_conntrack_expect_chain;
-extern int nf_conntrack_expect_register_notifier(struct notifier_block *nb);
-extern int nf_conntrack_expect_unregister_notifier(struct notifier_block *nb);
+extern struct atomic_notifier_head nf_ct_expect_chain;
+extern int nf_ct_expect_register_notifier(struct notifier_block *nb);
+extern int nf_ct_expect_unregister_notifier(struct notifier_block *nb);
 
 static inline void
-nf_conntrack_expect_event(enum ip_conntrack_expect_events event,
-                         struct nf_conntrack_expect *exp)
+nf_ct_expect_event(enum ip_conntrack_expect_events event,
+                  struct nf_conntrack_expect *exp)
 {
-       atomic_notifier_call_chain(&nf_conntrack_expect_chain, event, exp);
+       atomic_notifier_call_chain(&nf_ct_expect_chain, event, exp);
 }
 
 #else /* CONFIG_NF_CONNTRACK_EVENTS */
@@ -67,9 +67,8 @@ static inline void nf_conntrack_event_cache(enum ip_conntrack_events event,
 static inline void nf_conntrack_event(enum ip_conntrack_events event,
                                      struct nf_conn *ct) {}
 static inline void nf_ct_deliver_cached_events(const struct nf_conn *ct) {}
-static inline void
-nf_conntrack_expect_event(enum ip_conntrack_expect_events event,
-                         struct nf_conntrack_expect *exp) {}
+static inline void nf_ct_expect_event(enum ip_conntrack_expect_events event,
+                                     struct nf_conntrack_expect *exp) {}
 static inline void nf_ct_event_cache_flush(void) {}
 #endif /* CONFIG_NF_CONNTRACK_EVENTS */
 
index 173c7c1eff236330ba3f6433ba0f9d75f731b317..cae1a0dce36555e80c5451a1e92098fb6de96d6f 100644 (file)
@@ -6,17 +6,21 @@
 #define _NF_CONNTRACK_EXPECT_H
 #include <net/netfilter/nf_conntrack.h>
 
-extern struct list_head nf_conntrack_expect_list;
-extern struct kmem_cache *nf_conntrack_expect_cachep;
-extern const struct file_operations exp_file_ops;
+extern struct hlist_head *nf_ct_expect_hash;
+extern unsigned int nf_ct_expect_hsize;
+extern unsigned int nf_ct_expect_max;
 
 struct nf_conntrack_expect
 {
-       /* Internal linked list (global expectation list) */
-       struct list_head list;
+       /* Conntrack expectation list member */
+       struct hlist_node lnode;
+
+       /* Hash member */
+       struct hlist_node hnode;
 
        /* We expect this tuple, with the following mask */
-       struct nf_conntrack_tuple tuple, mask;
+       struct nf_conntrack_tuple tuple;
+       struct nf_conntrack_tuple_mask mask;
 
        /* Function to call after setup and insertion */
        void (*expectfn)(struct nf_conn *new,
@@ -52,29 +56,31 @@ struct nf_conntrack_expect
 
 #define NF_CT_EXPECT_PERMANENT 0x1
 
+int nf_conntrack_expect_init(void);
+void nf_conntrack_expect_fini(void);
 
 struct nf_conntrack_expect *
-__nf_conntrack_expect_find(const struct nf_conntrack_tuple *tuple);
+__nf_ct_expect_find(const struct nf_conntrack_tuple *tuple);
 
 struct nf_conntrack_expect *
-nf_conntrack_expect_find_get(const struct nf_conntrack_tuple *tuple);
+nf_ct_expect_find_get(const struct nf_conntrack_tuple *tuple);
 
 struct nf_conntrack_expect *
-find_expectation(const struct nf_conntrack_tuple *tuple);
+nf_ct_find_expectation(const struct nf_conntrack_tuple *tuple);
 
 void nf_ct_unlink_expect(struct nf_conntrack_expect *exp);
 void nf_ct_remove_expectations(struct nf_conn *ct);
-void nf_conntrack_unexpect_related(struct nf_conntrack_expect *exp);
+void nf_ct_unexpect_related(struct nf_conntrack_expect *exp);
 
 /* Allocate space for an expectation: this is mandatory before calling
-   nf_conntrack_expect_related.  You will have to call put afterwards. */
-struct nf_conntrack_expect *nf_conntrack_expect_alloc(struct nf_conn *me);
-void nf_conntrack_expect_init(struct nf_conntrack_expect *, int,
-                             union nf_conntrack_address *,
-                             union nf_conntrack_address *,
-                             u_int8_t, __be16 *, __be16 *);
-void nf_conntrack_expect_put(struct nf_conntrack_expect *exp);
-int nf_conntrack_expect_related(struct nf_conntrack_expect *expect);
+   nf_ct_expect_related.  You will have to call put afterwards. */
+struct nf_conntrack_expect *nf_ct_expect_alloc(struct nf_conn *me);
+void nf_ct_expect_init(struct nf_conntrack_expect *, int,
+                      union nf_conntrack_address *,
+                      union nf_conntrack_address *,
+                      u_int8_t, __be16 *, __be16 *);
+void nf_ct_expect_put(struct nf_conntrack_expect *exp);
+int nf_ct_expect_related(struct nf_conntrack_expect *expect);
 
 #endif /*_NF_CONNTRACK_EXPECT_H*/
 
diff --git a/include/net/netfilter/nf_conntrack_extend.h b/include/net/netfilter/nf_conntrack_extend.h
new file mode 100644 (file)
index 0000000..73b5711
--- /dev/null
@@ -0,0 +1,85 @@
+#ifndef _NF_CONNTRACK_EXTEND_H
+#define _NF_CONNTRACK_EXTEND_H
+
+#include <net/netfilter/nf_conntrack.h>
+
+enum nf_ct_ext_id
+{
+       NF_CT_EXT_HELPER,
+       NF_CT_EXT_NAT,
+       NF_CT_EXT_NUM,
+};
+
+#define NF_CT_EXT_HELPER_TYPE struct nf_conn_help
+#define NF_CT_EXT_NAT_TYPE struct nf_conn_nat
+
+/* Extensions: optional stuff which isn't permanently in struct. */
+struct nf_ct_ext {
+       u8 offset[NF_CT_EXT_NUM];
+       u8 len;
+       u8 real_len;
+       char data[0];
+};
+
+static inline int nf_ct_ext_exist(const struct nf_conn *ct, u8 id)
+{
+       return (ct->ext && ct->ext->offset[id]);
+}
+
+static inline void *__nf_ct_ext_find(const struct nf_conn *ct, u8 id)
+{
+       if (!nf_ct_ext_exist(ct, id))
+               return NULL;
+
+       return (void *)ct->ext + ct->ext->offset[id];
+}
+#define nf_ct_ext_find(ext, id)        \
+       ((id##_TYPE *)__nf_ct_ext_find((ext), (id)))
+
+/* Destroy all relationships */
+extern void __nf_ct_ext_destroy(struct nf_conn *ct);
+static inline void nf_ct_ext_destroy(struct nf_conn *ct)
+{
+       if (ct->ext)
+               __nf_ct_ext_destroy(ct);
+}
+
+/* Free operation. If you want to free a object referred from private area,
+ * please implement __nf_ct_ext_free() and call it.
+ */
+static inline void nf_ct_ext_free(struct nf_conn *ct)
+{
+       if (ct->ext)
+               kfree(ct->ext);
+}
+
+/* Add this type, returns pointer to data or NULL. */
+void *
+__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp);
+#define nf_ct_ext_add(ct, id, gfp) \
+       ((id##_TYPE *)__nf_ct_ext_add((ct), (id), (gfp)))
+
+#define NF_CT_EXT_F_PREALLOC   0x0001
+
+struct nf_ct_ext_type
+{
+       /* Destroys relationships (can be NULL). */
+       void (*destroy)(struct nf_conn *ct);
+       /* Called when realloacted (can be NULL).
+          Contents has already been moved. */
+       void (*move)(struct nf_conn *ct, void *old);
+
+       enum nf_ct_ext_id id;
+
+       unsigned int flags;
+
+       /* Length and min alignment. */
+       u8 len;
+       u8 align;
+       /* initial size of nf_ct_ext. */
+       u8 alloc_size;
+};
+
+int nf_ct_extend_register(struct nf_ct_ext_type *type);
+void nf_ct_extend_unregister(struct nf_ct_ext_type *type);
+#endif /* _NF_CONNTRACK_EXTEND_H */
index 8c72ac9f0ab8cae417992a85a8f88d6fea8a10a9..d04f99964d94bad80d86342fa9b4b645c982b676 100644 (file)
 #ifndef _NF_CONNTRACK_HELPER_H
 #define _NF_CONNTRACK_HELPER_H
 #include <net/netfilter/nf_conntrack.h>
+#include <net/netfilter/nf_conntrack_extend.h>
 
 struct module;
 
 struct nf_conntrack_helper
-{      
-       struct list_head list;          /* Internal use. */
+{
+       struct hlist_node hnode;        /* Internal use. */
 
        const char *name;               /* name of the module */
        struct module *me;              /* pointer to self */
@@ -23,10 +24,9 @@ struct nf_conntrack_helper
                                         * expected connections */
        unsigned int timeout;           /* timeout for expecteds */
 
-       /* Mask of things we will help (compared against server response) */
+       /* Tuple of things we will help (compared against server response) */
        struct nf_conntrack_tuple tuple;
-       struct nf_conntrack_tuple mask;
-       
+
        /* Function to call when data passes; return verdict, or -1 to
            invalidate. */
        int (*help)(struct sk_buff **pskb,
@@ -52,4 +52,10 @@ extern void nf_ct_helper_put(struct nf_conntrack_helper *helper);
 extern int nf_conntrack_helper_register(struct nf_conntrack_helper *);
 extern void nf_conntrack_helper_unregister(struct nf_conntrack_helper *);
 
+extern struct nf_conn_help *nf_ct_helper_ext_add(struct nf_conn *ct, gfp_t gfp);
+
+static inline struct nf_conn_help *nfct_help(const struct nf_conn *ct)
+{
+       return nf_ct_ext_find(ct, NF_CT_EXT_HELPER);
+}
 #endif /*_NF_CONNTRACK_HELPER_H*/
index 96a58d8e1d3f8011226862e8ae765b90683c7ace..890752d7f67398f97cd3a0c143a19881a11e4de3 100644 (file)
@@ -64,8 +64,6 @@ struct nf_conntrack_l3proto
        int (*prepare)(struct sk_buff **pskb, unsigned int hooknum,
                       unsigned int *dataoff, u_int8_t *protonum);
 
-       u_int32_t (*get_features)(const struct nf_conntrack_tuple *tuple);
-
        int (*tuple_to_nfattr)(struct sk_buff *skb,
                               const struct nf_conntrack_tuple *t);
 
index 5d72b16e876f3fd421221a73346186a44f8c2411..040dae5f0c9e2a595e63c0ca0230ce11925b0ae2 100644 (file)
@@ -100,6 +100,14 @@ struct nf_conntrack_tuple
        } dst;
 };
 
+struct nf_conntrack_tuple_mask
+{
+       struct {
+               union nf_conntrack_address u3;
+               union nf_conntrack_man_proto u;
+       } src;
+};
+
 /* This is optimized opposed to a memset of the whole structure.  Everything we
  * really care about is the  source/destination unions */
 #define NF_CT_TUPLE_U_BLANK(tuple)                                     \
@@ -112,11 +120,11 @@ struct nf_conntrack_tuple
 
 #ifdef __KERNEL__
 
-#define NF_CT_DUMP_TUPLE(tp)                                               \
-DEBUGP("tuple %p: %u %u " NIP6_FMT " %hu -> " NIP6_FMT " %hu\n",           \
-       (tp), (tp)->src.l3num, (tp)->dst.protonum,                          \
-       NIP6(*(struct in6_addr *)(tp)->src.u3.all), ntohs((tp)->src.u.all), \
-       NIP6(*(struct in6_addr *)(tp)->dst.u3.all), ntohs((tp)->dst.u.all))
+#define NF_CT_DUMP_TUPLE(tp)                                                \
+pr_debug("tuple %p: %u %u " NIP6_FMT " %hu -> " NIP6_FMT " %hu\n",          \
+        (tp), (tp)->src.l3num, (tp)->dst.protonum,                          \
+        NIP6(*(struct in6_addr *)(tp)->src.u3.all), ntohs((tp)->src.u.all), \
+        NIP6(*(struct in6_addr *)(tp)->dst.u3.all), ntohs((tp)->dst.u.all))
 
 /* If we're the first tuple, it's the original dir. */
 #define NF_CT_DIRECTION(h)                                             \
@@ -125,8 +133,7 @@ DEBUGP("tuple %p: %u %u " NIP6_FMT " %hu -> " NIP6_FMT " %hu\n",        \
 /* Connections have two entries in the hash table: one for each way */
 struct nf_conntrack_tuple_hash
 {
-       struct list_head list;
-
+       struct hlist_node hnode;
        struct nf_conntrack_tuple tuple;
 };
 
@@ -162,31 +169,44 @@ static inline int nf_ct_tuple_equal(const struct nf_conntrack_tuple *t1,
        return nf_ct_tuple_src_equal(t1, t2) && nf_ct_tuple_dst_equal(t1, t2);
 }
 
+static inline int nf_ct_tuple_mask_equal(const struct nf_conntrack_tuple_mask *m1,
+                                        const struct nf_conntrack_tuple_mask *m2)
+{
+       return (m1->src.u3.all[0] == m2->src.u3.all[0] &&
+               m1->src.u3.all[1] == m2->src.u3.all[1] &&
+               m1->src.u3.all[2] == m2->src.u3.all[2] &&
+               m1->src.u3.all[3] == m2->src.u3.all[3] &&
+               m1->src.u.all == m2->src.u.all);
+}
+
+static inline int nf_ct_tuple_src_mask_cmp(const struct nf_conntrack_tuple *t1,
+                                          const struct nf_conntrack_tuple *t2,
+                                          const struct nf_conntrack_tuple_mask *mask)
+{
+       int count;
+
+       for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++) {
+               if ((t1->src.u3.all[count] ^ t2->src.u3.all[count]) &
+                   mask->src.u3.all[count])
+                       return 0;
+       }
+
+       if ((t1->src.u.all ^ t2->src.u.all) & mask->src.u.all)
+               return 0;
+
+       if (t1->src.l3num != t2->src.l3num ||
+           t1->dst.protonum != t2->dst.protonum)
+               return 0;
+
+       return 1;
+}
+
 static inline int nf_ct_tuple_mask_cmp(const struct nf_conntrack_tuple *t,
                                       const struct nf_conntrack_tuple *tuple,
-                                      const struct nf_conntrack_tuple *mask)
+                                      const struct nf_conntrack_tuple_mask *mask)
 {
-       int count = 0;
-
-        for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
-                if ((t->src.u3.all[count] ^ tuple->src.u3.all[count]) &
-                    mask->src.u3.all[count])
-                        return 0;
-        }
-
-        for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
-                if ((t->dst.u3.all[count] ^ tuple->dst.u3.all[count]) &
-                    mask->dst.u3.all[count])
-                        return 0;
-        }
-
-        if ((t->src.u.all ^ tuple->src.u.all) & mask->src.u.all ||
-            (t->dst.u.all ^ tuple->dst.u.all) & mask->dst.u.all ||
-            (t->src.l3num ^ tuple->src.l3num) & mask->src.l3num ||
-            (t->dst.protonum ^ tuple->dst.protonum) & mask->dst.protonum)
-                return 0;
-
-        return 1;
+       return nf_ct_tuple_src_mask_cmp(t, tuple, mask) &&
+              nf_ct_tuple_dst_equal(t, tuple);
 }
 
 #endif /* _NF_CONNTRACK_TUPLE_H */
index bc57dd7b9b5c1c2f54efa1f3bd30cb34d5b5a952..6ae52f7c9f557facd58c94be4fc7f6c68bbac22c 100644 (file)
@@ -51,16 +51,31 @@ struct nf_nat_multi_range_compat
 
 #ifdef __KERNEL__
 #include <linux/list.h>
+#include <linux/netfilter/nf_conntrack_pptp.h>
+#include <net/netfilter/nf_conntrack_extend.h>
 
-/* The structure embedded in the conntrack structure. */
-struct nf_nat_info
+/* per conntrack: nat application helper private data */
+union nf_conntrack_nat_help
 {
-       struct list_head bysource;
-       struct nf_nat_seq seq[IP_CT_DIR_MAX];
+       /* insert nat helper private data here */
+       struct nf_nat_pptp nat_pptp_info;
 };
 
 struct nf_conn;
 
+/* The structure embedded in the conntrack structure. */
+struct nf_conn_nat
+{
+       struct hlist_node bysource;
+       struct nf_nat_seq seq[IP_CT_DIR_MAX];
+       struct nf_conn *ct;
+       union nf_conntrack_nat_help help;
+#if defined(CONFIG_IP_NF_TARGET_MASQUERADE) || \
+    defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE)
+       int masq_index;
+#endif
+};
+
 /* Set up the info structure to map into this range. */
 extern unsigned int nf_nat_setup_info(struct nf_conn *ct,
                                      const struct nf_nat_range *range,
@@ -70,7 +85,10 @@ extern unsigned int nf_nat_setup_info(struct nf_conn *ct,
 extern int nf_nat_used_tuple(const struct nf_conntrack_tuple *tuple,
                             const struct nf_conn *ignored_conntrack);
 
-extern int nf_nat_module_is_loaded;
+static inline struct nf_conn_nat *nfct_nat(const struct nf_conn *ct)
+{
+       return nf_ct_ext_find(ct, NF_CT_EXT_NAT);
+}
 
 #else  /* !__KERNEL__: iptables wants this to compile. */
 #define nf_nat_multi_range nf_nat_multi_range_compat
index 9778ffa9344081107598092e3a11ef010c35d7d0..c3cd127ba4bb38c418a48e482c4782063d381067 100644 (file)
@@ -2,6 +2,7 @@
 #define _NF_NAT_CORE_H
 #include <linux/list.h>
 #include <net/netfilter/nf_conntrack.h>
+#include <net/netfilter/nf_nat.h>
 
 /* This header used to share core functionality between the standalone
    NAT module, and the compatibility layer's use of NAT for masquerading. */
index 7b510a9edb911a34dbf6b356318cb5a45a09d09d..d7b824be5422146b73f13e4758995507d153ec9f 100644 (file)
  * Nested Attributes Construction:
  *   nla_nest_start(skb, type)         start a nested attribute
  *   nla_nest_end(skb, nla)            finalize a nested attribute
+ *   nla_nest_compat_start(skb, type,  start a nested compat attribute
+ *                        len, data)
+ *   nla_nest_compat_end(skb, type)    finalize a nested compat attribute
  *   nla_nest_cancel(skb, nla)         cancel nested attribute construction
  *
  * Attribute Length Calculations:
  *   nla_find_nested()                 find attribute in nested attributes
  *   nla_parse()                       parse and validate stream of attrs
  *   nla_parse_nested()                        parse nested attribuets
+ *   nla_parse_nested_compat()         parse nested compat attributes
  *   nla_for_each_attr()               loop over all attributes
  *   nla_for_each_nested()             loop over the nested attributes
  *=========================================================================
@@ -170,6 +174,7 @@ enum {
        NLA_FLAG,
        NLA_MSECS,
        NLA_NESTED,
+       NLA_NESTED_COMPAT,
        NLA_NUL_STRING,
        NLA_BINARY,
        __NLA_TYPE_MAX,
@@ -190,6 +195,7 @@ enum {
  *    NLA_NUL_STRING       Maximum length of string (excluding NUL)
  *    NLA_FLAG             Unused
  *    NLA_BINARY           Maximum length of attribute payload
+ *    NLA_NESTED_COMPAT    Exact length of structure payload
  *    All other            Exact length of attribute payload
  *
  * Example:
@@ -733,6 +739,39 @@ static inline int nla_parse_nested(struct nlattr *tb[], int maxtype,
 {
        return nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy);
 }
+
+/**
+ * nla_parse_nested_compat - parse nested compat attributes
+ * @tb: destination array with maxtype+1 elements
+ * @maxtype: maximum attribute type to be expected
+ * @nla: attribute containing the nested attributes
+ * @data: pointer to point to contained structure
+ * @len: length of contained structure
+ * @policy: validation policy
+ *
+ * Parse a nested compat attribute. The compat attribute contains a structure
+ * and optionally a set of nested attributes. On success the data pointer
+ * points to the nested data and tb contains the parsed attributes
+ * (see nla_parse).
+ */
+static inline int __nla_parse_nested_compat(struct nlattr *tb[], int maxtype,
+                                           struct nlattr *nla,
+                                           const struct nla_policy *policy,
+                                           int len)
+{
+       if (nla_len(nla) < len)
+               return -1;
+       if (nla_len(nla) >= NLA_ALIGN(len) + sizeof(struct nlattr))
+               return nla_parse_nested(tb, maxtype,
+                                       nla_data(nla) + NLA_ALIGN(len),
+                                       policy);
+       memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1));
+       return 0;
+}
+
+#define nla_parse_nested_compat(tb, maxtype, nla, policy, data, len) \
+({     data = nla_len(nla) >= len ? nla_data(nla) : NULL; \
+       __nla_parse_nested_compat(tb, maxtype, nla, policy, len); })
 /**
  * nla_put_u8 - Add a u16 netlink attribute to a socket buffer
  * @skb: socket buffer to add attribute to
@@ -964,6 +1003,51 @@ static inline int nla_nest_end(struct sk_buff *skb, struct nlattr *start)
        return skb->len;
 }
 
+/**
+ * nla_nest_compat_start - Start a new level of nested compat attributes
+ * @skb: socket buffer to add attributes to
+ * @attrtype: attribute type of container
+ * @attrlen: length of structure
+ * @data: pointer to structure
+ *
+ * Start a nested compat attribute that contains both a structure and
+ * a set of nested attributes.
+ *
+ * Returns the container attribute
+ */
+static inline struct nlattr *nla_nest_compat_start(struct sk_buff *skb,
+                                                  int attrtype, int attrlen,
+                                                  const void *data)
+{
+       struct nlattr *start = (struct nlattr *)skb_tail_pointer(skb);
+
+       if (nla_put(skb, attrtype, attrlen, data) < 0)
+               return NULL;
+       if (nla_nest_start(skb, attrtype) == NULL) {
+               nlmsg_trim(skb, start);
+               return NULL;
+       }
+       return start;
+}
+
+/**
+ * nla_nest_compat_end - Finalize nesting of compat attributes
+ * @skb: socket buffer the attribtues are stored in
+ * @start: container attribute
+ *
+ * Corrects the container attribute header to include the all
+ * appeneded attributes.
+ *
+ * Returns the total data length of the skb.
+ */
+static inline int nla_nest_compat_end(struct sk_buff *skb, struct nlattr *start)
+{
+       struct nlattr *nest = (void *)start + NLMSG_ALIGN(start->nla_len);
+
+       start->nla_len = skb_tail_pointer(skb) - (unsigned char *)start;
+       return nla_nest_end(skb, nest);
+}
+
 /**
  * nla_nest_cancel - Cancel nesting of attributes
  * @skb: socket buffer the message is stored in
index 4129df7080797bb665bdd5213f2c1254cad33f47..6c29920cbe2954e8c4aa6eedce6180e17e5cf52a 100644 (file)
@@ -306,6 +306,8 @@ static inline int tcf_em_tree_match(struct sk_buff *skb,
                return 1;
 }
 
+#define MODULE_ALIAS_TCF_EMATCH(kind)  MODULE_ALIAS("ematch-kind-" __stringify(kind))
+
 #else /* CONFIG_NET_EMATCH */
 
 struct tcf_ematch_tree
index af8960878ef41c72df5238a2304fc6bca643ef94..a5819891d52518a25b8430ba1f90cdad6ab0b403 100644 (file)
@@ -3,6 +3,8 @@
 
 #ifdef __KERNEL__
 
+#include <net/protocol.h>
+
 #define RAWV6_HTABLE_SIZE      MAX_INET_PROTOS
 extern struct hlist_head raw_v6_htable[RAWV6_HTABLE_SIZE];
 extern rwlock_t raw_v6_lock;
@@ -23,6 +25,13 @@ extern void                  rawv6_err(struct sock *sk,
                                          int type, int code, 
                                          int offset, __be32 info);
 
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+int rawv6_mh_filter_register(int (*filter)(struct sock *sock,
+                                          struct sk_buff *skb));
+int rawv6_mh_filter_unregister(int (*filter)(struct sock *sock,
+                                            struct sk_buff *skb));
+#endif
+
 #endif
 
 #endif
index 749e4dfe5ff3323dcaaa3eaa94c3130e3e058628..f7ce6259f86fb50754df9e1ee27744744ffad1f8 100644 (file)
@@ -62,7 +62,6 @@ struct rtable
        
        unsigned                rt_flags;
        __u16                   rt_type;
-       __u16                   rt_multipath_alg;
 
        __be32                  rt_dst; /* Path destination     */
        __be32                  rt_src; /* Path source          */
@@ -136,7 +135,7 @@ static inline void ip_rt_put(struct rtable * rt)
 
 #define IPTOS_RT_MASK  (IPTOS_TOS_MASK & ~3)
 
-extern __u8 ip_tos2prio[16];
+extern const __u8 ip_tos2prio[16];
 
 static inline char rt_tos2priority(u8 tos)
 {
index 3b3d4745618ddac7c07ba1afa2826b798917be83..3861c05cdf0fafe41d1dbe692b8fe5a2d5aa5bf7 100644 (file)
@@ -22,4 +22,62 @@ static inline int rtnl_msg_family(struct nlmsghdr *nlh)
                return AF_UNSPEC;
 }
 
+/**
+ *     struct rtnl_link_ops - rtnetlink link operations
+ *
+ *     @list: Used internally
+ *     @kind: Identifier
+ *     @maxtype: Highest device specific netlink attribute number
+ *     @policy: Netlink policy for device specific attribute validation
+ *     @validate: Optional validation function for netlink/changelink parameters
+ *     @priv_size: sizeof net_device private space
+ *     @setup: net_device setup function
+ *     @newlink: Function for configuring and registering a new device
+ *     @changelink: Function for changing parameters of an existing device
+ *     @dellink: Function to remove a device
+ *     @get_size: Function to calculate required room for dumping device
+ *                specific netlink attributes
+ *     @fill_info: Function to dump device specific netlink attributes
+ *     @get_xstats_size: Function to calculate required room for dumping devic
+ *                       specific statistics
+ *     @fill_xstats: Function to dump device specific statistics
+ */
+struct rtnl_link_ops {
+       struct list_head        list;
+
+       const char              *kind;
+
+       size_t                  priv_size;
+       void                    (*setup)(struct net_device *dev);
+
+       int                     maxtype;
+       const struct nla_policy *policy;
+       int                     (*validate)(struct nlattr *tb[],
+                                           struct nlattr *data[]);
+
+       int                     (*newlink)(struct net_device *dev,
+                                          struct nlattr *tb[],
+                                          struct nlattr *data[]);
+       int                     (*changelink)(struct net_device *dev,
+                                             struct nlattr *tb[],
+                                             struct nlattr *data[]);
+       void                    (*dellink)(struct net_device *dev);
+
+       size_t                  (*get_size)(const struct net_device *dev);
+       int                     (*fill_info)(struct sk_buff *skb,
+                                            const struct net_device *dev);
+
+       size_t                  (*get_xstats_size)(const struct net_device *dev);
+       int                     (*fill_xstats)(struct sk_buff *skb,
+                                              const struct net_device *dev);
+};
+
+extern int     __rtnl_link_register(struct rtnl_link_ops *ops);
+extern void    __rtnl_link_unregister(struct rtnl_link_ops *ops);
+
+extern int     rtnl_link_register(struct rtnl_link_ops *ops);
+extern void    rtnl_link_unregister(struct rtnl_link_ops *ops);
+
+#define MODULE_ALIAS_RTNL_LINK(kind) MODULE_ALIAS("rtnl-link-" kind)
+
 #endif
index 333bba6dc52286c2aa486bf583c7124c7d76e488..cfc4ba46de8f33959bbe5b4b4bb8985c794eee53 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * include/net/tipc/tipc_port.h: Include file for privileged access to TIPC ports
  * 
- * Copyright (c) 1994-2006, Ericsson AB
- * Copyright (c) 2005, Wind River Systems
+ * Copyright (c) 1994-2007, Ericsson AB
+ * Copyright (c) 2005-2007, Wind River Systems
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -55,6 +55,7 @@
  * @conn_unacked: number of unacknowledged messages received from peer port
  * @published: non-zero if port has one or more associated names
  * @congested: non-zero if cannot send because of link or port congestion
+ * @max_pkt: maximum packet size "hint" used when building messages sent by port
  * @ref: unique reference to port in TIPC object registry
  * @phdr: preformatted message header used when sending messages
  */
@@ -68,6 +69,7 @@ struct tipc_port {
        u32 conn_unacked;
        int published;
        u32 congested;
+       u32 max_pkt;
        u32 ref;
        struct tipc_msg phdr;
 };
index 311f25af5e1a7b936a87f8b3a0fd17926688a806..ae959e9501747ba2398db26d9035234718a5fe7d 100644 (file)
 #include <net/ipv6.h>
 #include <net/ip6_fib.h>
 
+#define XFRM_PROTO_ESP         50
+#define XFRM_PROTO_AH          51
+#define XFRM_PROTO_COMP                108
+#define XFRM_PROTO_IPIP                4
+#define XFRM_PROTO_IPV6                41
+#define XFRM_PROTO_ROUTING     IPPROTO_ROUTING
+#define XFRM_PROTO_DSTOPTS     IPPROTO_DSTOPTS
+
 #define XFRM_ALIGN8(len)       (((len) + 7) & ~7)
 #define MODULE_ALIAS_XFRM_MODE(family, encap) \
        MODULE_ALIAS("xfrm-mode-" __stringify(family) "-" __stringify(encap))
+#define MODULE_ALIAS_XFRM_TYPE(family, proto) \
+       MODULE_ALIAS("xfrm-type-" __stringify(family) "-" __stringify(proto))
 
 extern struct sock *xfrm_nl;
 extern u32 sysctl_xfrm_aevent_etime;
@@ -509,11 +519,9 @@ __be16 xfrm_flowi_sport(struct flowi *fl)
        case IPPROTO_ICMPV6:
                port = htons(fl->fl_icmp_type);
                break;
-#ifdef CONFIG_IPV6_MIP6
        case IPPROTO_MH:
                port = htons(fl->fl_mh_type);
                break;
-#endif
        default:
                port = 0;       /*XXX*/
        }
@@ -920,6 +928,10 @@ extern struct xfrm_state *xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t
                                          struct flowi *fl, struct xfrm_tmpl *tmpl,
                                          struct xfrm_policy *pol, int *err,
                                          unsigned short family);
+extern struct xfrm_state * xfrm_stateonly_find(xfrm_address_t *daddr,
+                                              xfrm_address_t *saddr,
+                                              unsigned short family,
+                                              u8 mode, u8 proto, u32 reqid);
 extern int xfrm_state_check_expire(struct xfrm_state *x);
 extern void xfrm_state_insert(struct xfrm_state *x);
 extern int xfrm_state_add(struct xfrm_state *x);
@@ -991,7 +1003,7 @@ extern int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb,
                                 u8 **prevhdr);
 
 #ifdef CONFIG_XFRM
-extern int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type);
+extern int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb);
 extern int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen);
 extern int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, unsigned short family);
 #else
@@ -1000,12 +1012,13 @@ static inline int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optv
        return -ENOPROTOOPT;
 } 
 
-static inline int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
+static inline int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
 {
        /* should not happen */
        kfree_skb(skb);
        return 0;
 }
+
 static inline int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, unsigned short family)
 {
        return -EINVAL;
index eae7e2e844974b903dd3b0094a5ead23da7546ac..ad6e278ba7f2df6e11c347840a8175ea2dc25930 100644 (file)
 #define MANFID_POSSIO                  0x030c
 #define PRODID_POSSIO_GCC              0x0003
 
+#define MANFID_NEC                     0x0010
+
 #endif /* _LINUX_CISCODE_H */
index 5c070176d9ab30bb1bdc8b5ae7524322070b70fe..12243e80c70615676b224310ed90d1785128662b 100644 (file)
@@ -385,7 +385,6 @@ struct ib_cm_rep_param {
        u8              private_data_len;
        u8              responder_resources;
        u8              initiator_depth;
-       u8              target_ack_delay;
        u8              failover_accepted;
        u8              flow_control;
        u8              rnr_retry_count;
index 739fa4d0e539bc195a1dc02494c3def9eff352e6..30712ddd8a5e6b6cc1add751f95948e9a3382bbd 100644 (file)
 #define IB_QP1_QKEY    0x80010000
 #define IB_QP_SET_QKEY 0x80000000
 
+#define IB_DEFAULT_PKEY_PARTIAL 0x7FFF
+#define IB_DEFAULT_PKEY_FULL   0xFFFF
+
 enum {
        IB_MGMT_MAD_HDR = 24,
        IB_MGMT_MAD_DATA = 232,
index a9e99f8328ff485386faf668b61ee59c7a1fb085..d9d878a3bb46835e1f2c4301620975e05757ee1d 100644 (file)
@@ -686,6 +686,4 @@ config STOP_MACHINE
          Need stop_machine() primitive.
 endmenu
 
-menu "Block layer"
 source "block/Kconfig"
-endmenu
index eb8bdbae4fc79026f8ee4664f34da66c82076c1e..0eb1c7463fe4d08c3012ee66cb486c72122a26d5 100644 (file)
@@ -436,15 +436,16 @@ static void noinline __init_refok rest_init(void)
 
        /*
         * The boot idle thread must execute schedule()
-        * at least one to get things moving:
+        * at least once to get things moving:
         */
+       init_idle_bootup_task(current);
        preempt_enable_no_resched();
        schedule();
        preempt_disable();
 
        /* Call into cpu_idle with preempt disabled */
        cpu_idle();
-} 
+}
 
 /* Check for early params. */
 static int __init do_early_param(char *param, char *val)
index c0148ae992c4aaee7295c50a6670a1ffc6c13b33..81e697829633cb31725e589e68ab55642b6aa9e1 100644 (file)
@@ -99,9 +99,10 @@ void __delayacct_blkio_end(void)
 int __delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk)
 {
        s64 tmp;
-       struct timespec ts;
-       unsigned long t1,t2,t3;
+       unsigned long t1;
+       unsigned long long t2, t3;
        unsigned long flags;
+       struct timespec ts;
 
        /* Though tsk->delays accessed later, early exit avoids
         * unnecessary returning of other data
@@ -124,11 +125,10 @@ int __delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk)
 
        d->cpu_count += t1;
 
-       jiffies_to_timespec(t2, &ts);
-       tmp = (s64)d->cpu_delay_total + timespec_to_ns(&ts);
+       tmp = (s64)d->cpu_delay_total + t2;
        d->cpu_delay_total = (tmp < (s64)d->cpu_delay_total) ? 0 : tmp;
 
-       tmp = (s64)d->cpu_run_virtual_total + (s64)jiffies_to_usecs(t3) * 1000;
+       tmp = (s64)d->cpu_run_virtual_total + t3;
        d->cpu_run_virtual_total =
                (tmp < (s64)d->cpu_run_virtual_total) ? 0 : tmp;
 
index 5c8ecbaa19a530cc4d417a897457b0d0318bc39b..ca6a11b730231bd0d6d9ece041e1a2f537223582 100644 (file)
@@ -122,9 +122,9 @@ static void __exit_signal(struct task_struct *tsk)
                sig->maj_flt += tsk->maj_flt;
                sig->nvcsw += tsk->nvcsw;
                sig->nivcsw += tsk->nivcsw;
-               sig->sched_time += tsk->sched_time;
                sig->inblock += task_io_get_inblock(tsk);
                sig->oublock += task_io_get_oublock(tsk);
+               sig->sum_sched_runtime += tsk->se.sum_exec_runtime;
                sig = NULL; /* Marker for below. */
        }
 
@@ -182,7 +182,6 @@ repeat:
                zap_leader = (leader->exit_signal == -1);
        }
 
-       sched_exit(p);
        write_unlock_irq(&tasklist_lock);
        proc_flush_task(p);
        release_thread(p);
@@ -291,7 +290,7 @@ static void reparent_to_kthreadd(void)
        /* Set the exit signal to SIGCHLD so we signal init on exit */
        current->exit_signal = SIGCHLD;
 
-       if (!has_rt_policy(current) && (task_nice(current) < 0))
+       if (task_nice(current) < 0)
                set_user_nice(current, 0);
        /* cpus_allowed? */
        /* rt_priority? */
index 73ad5cda1bcd277cf3c86c29bd851df3fc933c73..da3a155bba0ddc5c50a8082833a90be6fe60e8ce 100644 (file)
@@ -877,7 +877,7 @@ static inline int copy_signal(unsigned long clone_flags, struct task_struct * ts
        sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0;
        sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0;
        sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0;
-       sig->sched_time = 0;
+       sig->sum_sched_runtime = 0;
        INIT_LIST_HEAD(&sig->cpu_timers[0]);
        INIT_LIST_HEAD(&sig->cpu_timers[1]);
        INIT_LIST_HEAD(&sig->cpu_timers[2]);
@@ -1040,7 +1040,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
 
        p->utime = cputime_zero;
        p->stime = cputime_zero;
-       p->sched_time = 0;
+
 #ifdef CONFIG_TASK_XACCT
        p->rchar = 0;           /* I/O counter: bytes read */
        p->wchar = 0;           /* I/O counter: bytes written */
index 9bd93de01f4a95ab6abb0729401bf424cf5fab21..015d60cfd90e4f67f07380fac6c05d44aec81580 100644 (file)
@@ -488,8 +488,7 @@ static void free_modinfo_##field(struct module *mod)                  \
         mod->field = NULL;                                            \
 }                                                                     \
 static struct module_attribute modinfo_##field = {                    \
-       .attr = { .name = __stringify(field), .mode = 0444,           \
-                 .owner = THIS_MODULE },                             \
+       .attr = { .name = __stringify(field), .mode = 0444 },         \
        .show = show_modinfo_##field,                                 \
        .setup = setup_modinfo_##field,                               \
        .test = modinfo_##field##_exists,                             \
@@ -793,7 +792,7 @@ static ssize_t show_refcnt(struct module_attribute *mattr,
 }
 
 static struct module_attribute refcnt = {
-       .attr = { .name = "refcnt", .mode = 0444, .owner = THIS_MODULE },
+       .attr = { .name = "refcnt", .mode = 0444 },
        .show = show_refcnt,
 };
 
@@ -851,7 +850,7 @@ static ssize_t show_initstate(struct module_attribute *mattr,
 }
 
 static struct module_attribute initstate = {
-       .attr = { .name = "initstate", .mode = 0444, .owner = THIS_MODULE },
+       .attr = { .name = "initstate", .mode = 0444 },
        .show = show_initstate,
 };
 
@@ -1032,7 +1031,6 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect,
                sattr->mattr.show = module_sect_show;
                sattr->mattr.store = NULL;
                sattr->mattr.attr.name = sattr->name;
-               sattr->mattr.attr.owner = mod;
                sattr->mattr.attr.mode = S_IRUGO;
                *(gattr++) = &(sattr++)->mattr.attr;
        }
@@ -1090,7 +1088,6 @@ int module_add_modinfo_attrs(struct module *mod)
                if (!attr->test ||
                    (attr->test && attr->test(mod))) {
                        memcpy(temp_attr, attr, sizeof(*temp_attr));
-                       temp_attr->attr.owner = mod;
                        error = sysfs_create_file(&mod->mkobj.kobj,&temp_attr->attr);
                        ++temp_attr;
                }
index e61c46c97ce72ec1fb9615783e02dd4afb7c9990..effbaaedd7f328ac8a69bc246e60903b5babd271 100644 (file)
@@ -491,7 +491,6 @@ param_sysfs_setup(struct module_kobject *mk,
                        pattr->mattr.show = param_attr_show;
                        pattr->mattr.store = param_attr_store;
                        pattr->mattr.attr.name = (char *)&kp->name[name_skip];
-                       pattr->mattr.attr.owner = mk->mod;
                        pattr->mattr.attr.mode = kp->perm;
                        *(gattr++) = &(pattr++)->mattr.attr;
                }
index 1de710e183734b6e47bd7aa4819bd5b3c54deeb2..b53c8fcd9d82d25044867c9529a17f9b1fdb00f8 100644 (file)
@@ -161,7 +161,7 @@ static inline cputime_t virt_ticks(struct task_struct *p)
 }
 static inline unsigned long long sched_ns(struct task_struct *p)
 {
-       return (p == current) ? current_sched_time(p) : p->sched_time;
+       return task_sched_runtime(p);
 }
 
 int posix_cpu_clock_getres(const clockid_t which_clock, struct timespec *tp)
@@ -246,10 +246,10 @@ static int cpu_clock_sample_group_locked(unsigned int clock_idx,
                } while (t != p);
                break;
        case CPUCLOCK_SCHED:
-               cpu->sched = p->signal->sched_time;
+               cpu->sched = p->signal->sum_sched_runtime;
                /* Add in each other live thread.  */
                while ((t = next_thread(t)) != p) {
-                       cpu->sched += t->sched_time;
+                       cpu->sched += t->se.sum_exec_runtime;
                }
                cpu->sched += sched_ns(p);
                break;
@@ -422,7 +422,7 @@ int posix_cpu_timer_del(struct k_itimer *timer)
  */
 static void cleanup_timers(struct list_head *head,
                           cputime_t utime, cputime_t stime,
-                          unsigned long long sched_time)
+                          unsigned long long sum_exec_runtime)
 {
        struct cpu_timer_list *timer, *next;
        cputime_t ptime = cputime_add(utime, stime);
@@ -451,10 +451,10 @@ static void cleanup_timers(struct list_head *head,
        ++head;
        list_for_each_entry_safe(timer, next, head, entry) {
                list_del_init(&timer->entry);
-               if (timer->expires.sched < sched_time) {
+               if (timer->expires.sched < sum_exec_runtime) {
                        timer->expires.sched = 0;
                } else {
-                       timer->expires.sched -= sched_time;
+                       timer->expires.sched -= sum_exec_runtime;
                }
        }
 }
@@ -467,7 +467,7 @@ static void cleanup_timers(struct list_head *head,
 void posix_cpu_timers_exit(struct task_struct *tsk)
 {
        cleanup_timers(tsk->cpu_timers,
-                      tsk->utime, tsk->stime, tsk->sched_time);
+                      tsk->utime, tsk->stime, tsk->se.sum_exec_runtime);
 
 }
 void posix_cpu_timers_exit_group(struct task_struct *tsk)
@@ -475,7 +475,7 @@ void posix_cpu_timers_exit_group(struct task_struct *tsk)
        cleanup_timers(tsk->signal->cpu_timers,
                       cputime_add(tsk->utime, tsk->signal->utime),
                       cputime_add(tsk->stime, tsk->signal->stime),
-                      tsk->sched_time + tsk->signal->sched_time);
+                    tsk->se.sum_exec_runtime + tsk->signal->sum_sched_runtime);
 }
 
 
@@ -536,7 +536,7 @@ static void process_timer_rebalance(struct task_struct *p,
                nsleft = max_t(unsigned long long, nsleft, 1);
                do {
                        if (likely(!(t->flags & PF_EXITING))) {
-                               ns = t->sched_time + nsleft;
+                               ns = t->se.sum_exec_runtime + nsleft;
                                if (t->it_sched_expires == 0 ||
                                    t->it_sched_expires > ns) {
                                        t->it_sched_expires = ns;
@@ -1004,7 +1004,7 @@ static void check_thread_timers(struct task_struct *tsk,
                struct cpu_timer_list *t = list_first_entry(timers,
                                                      struct cpu_timer_list,
                                                      entry);
-               if (!--maxfire || tsk->sched_time < t->expires.sched) {
+               if (!--maxfire || tsk->se.sum_exec_runtime < t->expires.sched) {
                        tsk->it_sched_expires = t->expires.sched;
                        break;
                }
@@ -1024,7 +1024,7 @@ static void check_process_timers(struct task_struct *tsk,
        int maxfire;
        struct signal_struct *const sig = tsk->signal;
        cputime_t utime, stime, ptime, virt_expires, prof_expires;
-       unsigned long long sched_time, sched_expires;
+       unsigned long long sum_sched_runtime, sched_expires;
        struct task_struct *t;
        struct list_head *timers = sig->cpu_timers;
 
@@ -1044,12 +1044,12 @@ static void check_process_timers(struct task_struct *tsk,
         */
        utime = sig->utime;
        stime = sig->stime;
-       sched_time = sig->sched_time;
+       sum_sched_runtime = sig->sum_sched_runtime;
        t = tsk;
        do {
                utime = cputime_add(utime, t->utime);
                stime = cputime_add(stime, t->stime);
-               sched_time += t->sched_time;
+               sum_sched_runtime += t->se.sum_exec_runtime;
                t = next_thread(t);
        } while (t != tsk);
        ptime = cputime_add(utime, stime);
@@ -1090,7 +1090,7 @@ static void check_process_timers(struct task_struct *tsk,
                struct cpu_timer_list *t = list_first_entry(timers,
                                                      struct cpu_timer_list,
                                                      entry);
-               if (!--maxfire || sched_time < t->expires.sched) {
+               if (!--maxfire || sum_sched_runtime < t->expires.sched) {
                        sched_expires = t->expires.sched;
                        break;
                }
@@ -1182,7 +1182,7 @@ static void check_process_timers(struct task_struct *tsk,
                virt_left = cputime_sub(virt_expires, utime);
                virt_left = cputime_div_non_zero(virt_left, nthreads);
                if (sched_expires) {
-                       sched_left = sched_expires - sched_time;
+                       sched_left = sched_expires - sum_sched_runtime;
                        do_div(sched_left, nthreads);
                        sched_left = max_t(unsigned long long, sched_left, 1);
                } else {
@@ -1208,7 +1208,7 @@ static void check_process_timers(struct task_struct *tsk,
                                t->it_virt_expires = ticks;
                        }
 
-                       sched = t->sched_time + sched_left;
+                       sched = t->se.sum_exec_runtime + sched_left;
                        if (sched_expires && (t->it_sched_expires == 0 ||
                                              t->it_sched_expires > sched)) {
                                t->it_sched_expires = sched;
@@ -1300,7 +1300,7 @@ void run_posix_cpu_timers(struct task_struct *tsk)
 
        if (UNEXPIRED(prof) && UNEXPIRED(virt) &&
            (tsk->it_sched_expires == 0 ||
-            tsk->sched_time < tsk->it_sched_expires))
+            tsk->se.sum_exec_runtime < tsk->it_sched_expires))
                return;
 
 #undef UNEXPIRED
index 95db8c79fe8f3371249029a19e48e817ffc34d12..a615a8f513fc890eaa1a11a34ae5e08c78895bba 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/vmalloc.h>
 #include <linux/mm.h>
 #include <linux/cpu.h>
+#include <linux/splice.h>
 
 /* list of open channels, for cpu hotplug */
 static DEFINE_MUTEX(relay_channels_mutex);
@@ -121,6 +122,7 @@ static void *relay_alloc_buf(struct rchan_buf *buf, size_t *size)
                buf->page_array[i] = alloc_page(GFP_KERNEL);
                if (unlikely(!buf->page_array[i]))
                        goto depopulate;
+               set_page_private(buf->page_array[i], (unsigned long)buf);
        }
        mem = vmap(buf->page_array, n_pages, VM_MAP, PAGE_KERNEL);
        if (!mem)
@@ -970,43 +972,6 @@ static int subbuf_read_actor(size_t read_start,
        return ret;
 }
 
-/*
- *     subbuf_send_actor - send up to one subbuf's worth of data
- */
-static int subbuf_send_actor(size_t read_start,
-                            struct rchan_buf *buf,
-                            size_t avail,
-                            read_descriptor_t *desc,
-                            read_actor_t actor)
-{
-       unsigned long pidx, poff;
-       unsigned int subbuf_pages;
-       int ret = 0;
-
-       subbuf_pages = buf->chan->alloc_size >> PAGE_SHIFT;
-       pidx = (read_start / PAGE_SIZE) % subbuf_pages;
-       poff = read_start & ~PAGE_MASK;
-       while (avail) {
-               struct page *p = buf->page_array[pidx];
-               unsigned int len;
-
-               len = PAGE_SIZE - poff;
-               if (len > avail)
-                       len = avail;
-
-               len = actor(desc, p, poff, len);
-               if (desc->error)
-                       break;
-
-               avail -= len;
-               ret += len;
-               poff = 0;
-               pidx = (pidx + 1) % subbuf_pages;
-       }
-
-       return ret;
-}
-
 typedef int (*subbuf_actor_t) (size_t read_start,
                               struct rchan_buf *buf,
                               size_t avail,
@@ -1067,19 +1032,161 @@ static ssize_t relay_file_read(struct file *filp,
                                       NULL, &desc);
 }
 
-static ssize_t relay_file_sendfile(struct file *filp,
-                                  loff_t *ppos,
-                                  size_t count,
-                                  read_actor_t actor,
-                                  void *target)
+static void relay_consume_bytes(struct rchan_buf *rbuf, int bytes_consumed)
 {
-       read_descriptor_t desc;
-       desc.written = 0;
-       desc.count = count;
-       desc.arg.data = target;
-       desc.error = 0;
-       return relay_file_read_subbufs(filp, ppos, subbuf_send_actor,
-                                      actor, &desc);
+       rbuf->bytes_consumed += bytes_consumed;
+
+       if (rbuf->bytes_consumed >= rbuf->chan->subbuf_size) {
+               relay_subbufs_consumed(rbuf->chan, rbuf->cpu, 1);
+               rbuf->bytes_consumed %= rbuf->chan->subbuf_size;
+       }
+}
+
+static void relay_pipe_buf_release(struct pipe_inode_info *pipe,
+                                  struct pipe_buffer *buf)
+{
+       struct rchan_buf *rbuf;
+
+       rbuf = (struct rchan_buf *)page_private(buf->page);
+       relay_consume_bytes(rbuf, buf->private);
+}
+
+static struct pipe_buf_operations relay_pipe_buf_ops = {
+       .can_merge = 0,
+       .map = generic_pipe_buf_map,
+       .unmap = generic_pipe_buf_unmap,
+       .confirm = generic_pipe_buf_confirm,
+       .release = relay_pipe_buf_release,
+       .steal = generic_pipe_buf_steal,
+       .get = generic_pipe_buf_get,
+};
+
+/*
+ *     subbuf_splice_actor - splice up to one subbuf's worth of data
+ */
+static int subbuf_splice_actor(struct file *in,
+                              loff_t *ppos,
+                              struct pipe_inode_info *pipe,
+                              size_t len,
+                              unsigned int flags,
+                              int *nonpad_ret)
+{
+       unsigned int pidx, poff, total_len, subbuf_pages, ret;
+       struct rchan_buf *rbuf = in->private_data;
+       unsigned int subbuf_size = rbuf->chan->subbuf_size;
+       uint64_t pos = (uint64_t) *ppos;
+       uint32_t alloc_size = (uint32_t) rbuf->chan->alloc_size;
+       size_t read_start = (size_t) do_div(pos, alloc_size);
+       size_t read_subbuf = read_start / subbuf_size;
+       size_t padding = rbuf->padding[read_subbuf];
+       size_t nonpad_end = read_subbuf * subbuf_size + subbuf_size - padding;
+       struct page *pages[PIPE_BUFFERS];
+       struct partial_page partial[PIPE_BUFFERS];
+       struct splice_pipe_desc spd = {
+               .pages = pages,
+               .nr_pages = 0,
+               .partial = partial,
+               .flags = flags,
+               .ops = &relay_pipe_buf_ops,
+       };
+
+       if (rbuf->subbufs_produced == rbuf->subbufs_consumed)
+               return 0;
+
+       /*
+        * Adjust read len, if longer than what is available
+        */
+       if (len > (subbuf_size - read_start % subbuf_size))
+               len = subbuf_size - read_start % subbuf_size;
+
+       subbuf_pages = rbuf->chan->alloc_size >> PAGE_SHIFT;
+       pidx = (read_start / PAGE_SIZE) % subbuf_pages;
+       poff = read_start & ~PAGE_MASK;
+
+       for (total_len = 0; spd.nr_pages < subbuf_pages; spd.nr_pages++) {
+               unsigned int this_len, this_end, private;
+               unsigned int cur_pos = read_start + total_len;
+
+               if (!len)
+                       break;
+
+               this_len = min_t(unsigned long, len, PAGE_SIZE - poff);
+               private = this_len;
+
+               spd.pages[spd.nr_pages] = rbuf->page_array[pidx];
+               spd.partial[spd.nr_pages].offset = poff;
+
+               this_end = cur_pos + this_len;
+               if (this_end >= nonpad_end) {
+                       this_len = nonpad_end - cur_pos;
+                       private = this_len + padding;
+               }
+               spd.partial[spd.nr_pages].len = this_len;
+               spd.partial[spd.nr_pages].private = private;
+
+               len -= this_len;
+               total_len += this_len;
+               poff = 0;
+               pidx = (pidx + 1) % subbuf_pages;
+
+               if (this_end >= nonpad_end) {
+                       spd.nr_pages++;
+                       break;
+               }
+       }
+
+       if (!spd.nr_pages)
+               return 0;
+
+       ret = *nonpad_ret = splice_to_pipe(pipe, &spd);
+       if (ret < 0 || ret < total_len)
+               return ret;
+
+        if (read_start + ret == nonpad_end)
+                ret += padding;
+
+        return ret;
+}
+
+static ssize_t relay_file_splice_read(struct file *in,
+                                     loff_t *ppos,
+                                     struct pipe_inode_info *pipe,
+                                     size_t len,
+                                     unsigned int flags)
+{
+       ssize_t spliced;
+       int ret;
+       int nonpad_ret = 0;
+
+       ret = 0;
+       spliced = 0;
+
+       while (len) {
+               ret = subbuf_splice_actor(in, ppos, pipe, len, flags, &nonpad_ret);
+               if (ret < 0)
+                       break;
+               else if (!ret) {
+                       if (spliced)
+                               break;
+                       if (flags & SPLICE_F_NONBLOCK) {
+                               ret = -EAGAIN;
+                               break;
+                       }
+               }
+
+               *ppos += ret;
+               if (ret > len)
+                       len = 0;
+               else
+                       len -= ret;
+               spliced += nonpad_ret;
+               nonpad_ret = 0;
+       }
+
+       if (spliced)
+               return spliced;
+
+       return ret;
 }
 
 const struct file_operations relay_file_operations = {
@@ -1089,7 +1196,7 @@ const struct file_operations relay_file_operations = {
        .read           = relay_file_read,
        .llseek         = no_llseek,
        .release        = relay_file_release,
-       .sendfile       = relay_file_sendfile,
+       .splice_read    = relay_file_splice_read,
 };
 EXPORT_SYMBOL_GPL(relay_file_operations);
 
index 50e1a312269945284bc0ce769eb9b2acd629b7f2..0559665a3a0b14e485edccf09282511e0b1fa60a 100644 (file)
  *             by Davide Libenzi, preemptible kernel bits by Robert Love.
  *  2003-09-03 Interactivity tuning by Con Kolivas.
  *  2004-04-02 Scheduler domains code by Nick Piggin
+ *  2007-04-15  Work begun on replacing all interactivity tuning with a
+ *              fair scheduling design by Con Kolivas.
+ *  2007-05-05  Load balancing (smp-nice) and other improvements
+ *              by Peter Williams
+ *  2007-05-06  Interactivity improvements to CFS by Mike Galbraith
+ *  2007-07-01  Group scheduling enhancements by Srivatsa Vaddagiri
  */
 
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/nmi.h>
 #include <linux/init.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/highmem.h>
 #include <linux/smp_lock.h>
 #include <asm/mmu_context.h>
@@ -53,9 +59,9 @@
 #include <linux/kprobes.h>
 #include <linux/delayacct.h>
 #include <linux/reciprocal_div.h>
+#include <linux/unistd.h>
 
 #include <asm/tlb.h>
-#include <asm/unistd.h>
 
 /*
  * Scheduler clock - returns current time in nanosec units.
@@ -91,6 +97,9 @@ unsigned long long __attribute__((weak)) sched_clock(void)
 #define NS_TO_JIFFIES(TIME)    ((TIME) / (1000000000 / HZ))
 #define JIFFIES_TO_NS(TIME)    ((TIME) * (1000000000 / HZ))
 
+#define NICE_0_LOAD            SCHED_LOAD_SCALE
+#define NICE_0_SHIFT           SCHED_LOAD_SHIFT
+
 /*
  * These are the 'tuning knobs' of the scheduler:
  *
@@ -100,87 +109,6 @@ unsigned long long __attribute__((weak)) sched_clock(void)
  */
 #define MIN_TIMESLICE          max(5 * HZ / 1000, 1)
 #define DEF_TIMESLICE          (100 * HZ / 1000)
-#define ON_RUNQUEUE_WEIGHT      30
-#define CHILD_PENALTY           95
-#define PARENT_PENALTY         100
-#define EXIT_WEIGHT              3
-#define PRIO_BONUS_RATIO        25
-#define MAX_BONUS              (MAX_USER_PRIO * PRIO_BONUS_RATIO / 100)
-#define INTERACTIVE_DELTA        2
-#define MAX_SLEEP_AVG          (DEF_TIMESLICE * MAX_BONUS)
-#define STARVATION_LIMIT       (MAX_SLEEP_AVG)
-#define NS_MAX_SLEEP_AVG       (JIFFIES_TO_NS(MAX_SLEEP_AVG))
-
-/*
- * If a task is 'interactive' then we reinsert it in the active
- * array after it has expired its current timeslice. (it will not
- * continue to run immediately, it will still roundrobin with
- * other interactive tasks.)
- *
- * This part scales the interactivity limit depending on niceness.
- *
- * We scale it linearly, offset by the INTERACTIVE_DELTA delta.
- * Here are a few examples of different nice levels:
- *
- *  TASK_INTERACTIVE(-20): [1,1,1,1,1,1,1,1,1,0,0]
- *  TASK_INTERACTIVE(-10): [1,1,1,1,1,1,1,0,0,0,0]
- *  TASK_INTERACTIVE(  0): [1,1,1,1,0,0,0,0,0,0,0]
- *  TASK_INTERACTIVE( 10): [1,1,0,0,0,0,0,0,0,0,0]
- *  TASK_INTERACTIVE( 19): [0,0,0,0,0,0,0,0,0,0,0]
- *
- * (the X axis represents the possible -5 ... 0 ... +5 dynamic
- *  priority range a task can explore, a value of '1' means the
- *  task is rated interactive.)
- *
- * Ie. nice +19 tasks can never get 'interactive' enough to be
- * reinserted into the active array. And only heavily CPU-hog nice -20
- * tasks will be expired. Default nice 0 tasks are somewhere between,
- * it takes some effort for them to get interactive, but it's not
- * too hard.
- */
-
-#define CURRENT_BONUS(p) \
-       (NS_TO_JIFFIES((p)->sleep_avg) * MAX_BONUS / \
-               MAX_SLEEP_AVG)
-
-#define GRANULARITY    (10 * HZ / 1000 ? : 1)
-
-#ifdef CONFIG_SMP
-#define TIMESLICE_GRANULARITY(p)       (GRANULARITY * \
-               (1 << (((MAX_BONUS - CURRENT_BONUS(p)) ? : 1) - 1)) * \
-                       num_online_cpus())
-#else
-#define TIMESLICE_GRANULARITY(p)       (GRANULARITY * \
-               (1 << (((MAX_BONUS - CURRENT_BONUS(p)) ? : 1) - 1)))
-#endif
-
-#define SCALE(v1,v1_max,v2_max) \
-       (v1) * (v2_max) / (v1_max)
-
-#define DELTA(p) \
-       (SCALE(TASK_NICE(p) + 20, 40, MAX_BONUS) - 20 * MAX_BONUS / 40 + \
-               INTERACTIVE_DELTA)
-
-#define TASK_INTERACTIVE(p) \
-       ((p)->prio <= (p)->static_prio - DELTA(p))
-
-#define INTERACTIVE_SLEEP(p) \
-       (JIFFIES_TO_NS(MAX_SLEEP_AVG * \
-               (MAX_BONUS / 2 + DELTA((p)) + 1) / MAX_BONUS - 1))
-
-#define TASK_PREEMPTS_CURR(p, rq) \
-       ((p)->prio < (rq)->curr->prio)
-
-#define SCALE_PRIO(x, prio) \
-       max(x * (MAX_PRIO - prio) / (MAX_USER_PRIO / 2), MIN_TIMESLICE)
-
-static unsigned int static_prio_timeslice(int static_prio)
-{
-       if (static_prio < NICE_TO_PRIO(0))
-               return SCALE_PRIO(DEF_TIMESLICE * 4, static_prio);
-       else
-               return SCALE_PRIO(DEF_TIMESLICE, static_prio);
-}
 
 #ifdef CONFIG_SMP
 /*
@@ -203,28 +131,87 @@ static inline void sg_inc_cpu_power(struct sched_group *sg, u32 val)
 }
 #endif
 
+#define SCALE_PRIO(x, prio) \
+       max(x * (MAX_PRIO - prio) / (MAX_USER_PRIO / 2), MIN_TIMESLICE)
+
 /*
- * task_timeslice() scales user-nice values [ -20 ... 0 ... 19 ]
+ * static_prio_timeslice() scales user-nice values [ -20 ... 0 ... 19 ]
  * to time slice values: [800ms ... 100ms ... 5ms]
- *
- * The higher a thread's priority, the bigger timeslices
- * it gets during one round of execution. But even the lowest
- * priority thread gets MIN_TIMESLICE worth of execution time.
  */
+static unsigned int static_prio_timeslice(int static_prio)
+{
+       if (static_prio == NICE_TO_PRIO(19))
+               return 1;
+
+       if (static_prio < NICE_TO_PRIO(0))
+               return SCALE_PRIO(DEF_TIMESLICE * 4, static_prio);
+       else
+               return SCALE_PRIO(DEF_TIMESLICE, static_prio);
+}
+
+static inline int rt_policy(int policy)
+{
+       if (unlikely(policy == SCHED_FIFO) || unlikely(policy == SCHED_RR))
+               return 1;
+       return 0;
+}
 
-static inline unsigned int task_timeslice(struct task_struct *p)
+static inline int task_has_rt_policy(struct task_struct *p)
 {
-       return static_prio_timeslice(p->static_prio);
+       return rt_policy(p->policy);
 }
 
 /*
- * These are the runqueue data structures:
+ * This is the priority-queue data structure of the RT scheduling class:
  */
+struct rt_prio_array {
+       DECLARE_BITMAP(bitmap, MAX_RT_PRIO+1); /* include 1 bit for delimiter */
+       struct list_head queue[MAX_RT_PRIO];
+};
+
+struct load_stat {
+       struct load_weight load;
+       u64 load_update_start, load_update_last;
+       unsigned long delta_fair, delta_exec, delta_stat;
+};
+
+/* CFS-related fields in a runqueue */
+struct cfs_rq {
+       struct load_weight load;
+       unsigned long nr_running;
+
+       s64 fair_clock;
+       u64 exec_clock;
+       s64 wait_runtime;
+       u64 sleeper_bonus;
+       unsigned long wait_runtime_overruns, wait_runtime_underruns;
+
+       struct rb_root tasks_timeline;
+       struct rb_node *rb_leftmost;
+       struct rb_node *rb_load_balance_curr;
+#ifdef CONFIG_FAIR_GROUP_SCHED
+       /* 'curr' points to currently running entity on this cfs_rq.
+        * It is set to NULL otherwise (i.e when none are currently running).
+        */
+       struct sched_entity *curr;
+       struct rq *rq;  /* cpu runqueue to which this cfs_rq is attached */
 
-struct prio_array {
-       unsigned int nr_active;
-       DECLARE_BITMAP(bitmap, MAX_PRIO+1); /* include 1 bit for delimiter */
-       struct list_head queue[MAX_PRIO];
+       /* leaf cfs_rqs are those that hold tasks (lowest schedulable entity in
+        * a hierarchy). Non-leaf lrqs hold other higher schedulable entities
+        * (like users, containers etc.)
+        *
+        * leaf_cfs_rq_list ties together list of leaf cfs_rq's in a cpu. This
+        * list is used during load balance.
+        */
+       struct list_head leaf_cfs_rq_list; /* Better name : task_cfs_rq_list? */
+#endif
+};
+
+/* Real-Time classes' related field in a runqueue: */
+struct rt_rq {
+       struct rt_prio_array active;
+       int rt_load_balance_idx;
+       struct list_head *rt_load_balance_head, *rt_load_balance_curr;
 };
 
 /*
@@ -235,22 +222,28 @@ struct prio_array {
  * acquire operations must be ordered by ascending &runqueue.
  */
 struct rq {
-       spinlock_t lock;
+       spinlock_t lock;        /* runqueue lock */
 
        /*
         * nr_running and cpu_load should be in the same cacheline because
         * remote CPUs use both these fields when doing load calculation.
         */
        unsigned long nr_running;
-       unsigned long raw_weighted_load;
-#ifdef CONFIG_SMP
-       unsigned long cpu_load[3];
+       #define CPU_LOAD_IDX_MAX 5
+       unsigned long cpu_load[CPU_LOAD_IDX_MAX];
        unsigned char idle_at_tick;
 #ifdef CONFIG_NO_HZ
        unsigned char in_nohz_recently;
 #endif
+       struct load_stat ls;    /* capture load from *all* tasks on this cpu */
+       unsigned long nr_load_updates;
+       u64 nr_switches;
+
+       struct cfs_rq cfs;
+#ifdef CONFIG_FAIR_GROUP_SCHED
+       struct list_head leaf_cfs_rq_list; /* list of leaf cfs_rq on this cpu */
 #endif
-       unsigned long long nr_switches;
+       struct rt_rq  rt;
 
        /*
         * This is part of a global counter where only the total sum
@@ -260,14 +253,18 @@ struct rq {
         */
        unsigned long nr_uninterruptible;
 
-       unsigned long expired_timestamp;
-       /* Cached timestamp set by update_cpu_clock() */
-       unsigned long long most_recent_timestamp;
        struct task_struct *curr, *idle;
        unsigned long next_balance;
        struct mm_struct *prev_mm;
-       struct prio_array *active, *expired, arrays[2];
-       int best_expired_prio;
+
+       u64 clock, prev_clock_raw;
+       s64 clock_max_delta;
+
+       unsigned int clock_warps, clock_overflows;
+       unsigned int clock_unstable_events;
+
+       struct sched_class *load_balance_class;
+
        atomic_t nr_iowait;
 
 #ifdef CONFIG_SMP
@@ -307,6 +304,11 @@ struct rq {
 static DEFINE_PER_CPU(struct rq, runqueues) ____cacheline_aligned_in_smp;
 static DEFINE_MUTEX(sched_hotcpu_mutex);
 
+static inline void check_preempt_curr(struct rq *rq, struct task_struct *p)
+{
+       rq->curr->sched_class->check_preempt_curr(rq, p);
+}
+
 static inline int cpu_of(struct rq *rq)
 {
 #ifdef CONFIG_SMP
@@ -316,6 +318,52 @@ static inline int cpu_of(struct rq *rq)
 #endif
 }
 
+/*
+ * Per-runqueue clock, as finegrained as the platform can give us:
+ */
+static unsigned long long __rq_clock(struct rq *rq)
+{
+       u64 prev_raw = rq->prev_clock_raw;
+       u64 now = sched_clock();
+       s64 delta = now - prev_raw;
+       u64 clock = rq->clock;
+
+       /*
+        * Protect against sched_clock() occasionally going backwards:
+        */
+       if (unlikely(delta < 0)) {
+               clock++;
+               rq->clock_warps++;
+       } else {
+               /*
+                * Catch too large forward jumps too:
+                */
+               if (unlikely(delta > 2*TICK_NSEC)) {
+                       clock++;
+                       rq->clock_overflows++;
+               } else {
+                       if (unlikely(delta > rq->clock_max_delta))
+                               rq->clock_max_delta = delta;
+                       clock += delta;
+               }
+       }
+
+       rq->prev_clock_raw = now;
+       rq->clock = clock;
+
+       return clock;
+}
+
+static inline unsigned long long rq_clock(struct rq *rq)
+{
+       int this_cpu = smp_processor_id();
+
+       if (this_cpu == cpu_of(rq))
+               return __rq_clock(rq);
+
+       return rq->clock;
+}
+
 /*
  * The domain tree (rq->sd) is protected by RCU's quiescent state transition.
  * See detach_destroy_domains: synchronize_sched for details.
@@ -331,6 +379,18 @@ static inline int cpu_of(struct rq *rq)
 #define task_rq(p)             cpu_rq(task_cpu(p))
 #define cpu_curr(cpu)          (cpu_rq(cpu)->curr)
 
+#ifdef CONFIG_FAIR_GROUP_SCHED
+/* Change a task's ->cfs_rq if it moves across CPUs */
+static inline void set_task_cfs_rq(struct task_struct *p)
+{
+       p->se.cfs_rq = &task_rq(p)->cfs;
+}
+#else
+static inline void set_task_cfs_rq(struct task_struct *p)
+{
+}
+#endif
+
 #ifndef prepare_arch_switch
 # define prepare_arch_switch(next)     do { } while (0)
 #endif
@@ -460,134 +520,6 @@ static inline void task_rq_unlock(struct rq *rq, unsigned long *flags)
        spin_unlock_irqrestore(&rq->lock, *flags);
 }
 
-#ifdef CONFIG_SCHEDSTATS
-/*
- * bump this up when changing the output format or the meaning of an existing
- * format, so that tools can adapt (or abort)
- */
-#define SCHEDSTAT_VERSION 14
-
-static int show_schedstat(struct seq_file *seq, void *v)
-{
-       int cpu;
-
-       seq_printf(seq, "version %d\n", SCHEDSTAT_VERSION);
-       seq_printf(seq, "timestamp %lu\n", jiffies);
-       for_each_online_cpu(cpu) {
-               struct rq *rq = cpu_rq(cpu);
-#ifdef CONFIG_SMP
-               struct sched_domain *sd;
-               int dcnt = 0;
-#endif
-
-               /* runqueue-specific stats */
-               seq_printf(seq,
-                   "cpu%d %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu",
-                   cpu, rq->yld_both_empty,
-                   rq->yld_act_empty, rq->yld_exp_empty, rq->yld_cnt,
-                   rq->sched_switch, rq->sched_cnt, rq->sched_goidle,
-                   rq->ttwu_cnt, rq->ttwu_local,
-                   rq->rq_sched_info.cpu_time,
-                   rq->rq_sched_info.run_delay, rq->rq_sched_info.pcnt);
-
-               seq_printf(seq, "\n");
-
-#ifdef CONFIG_SMP
-               /* domain-specific stats */
-               preempt_disable();
-               for_each_domain(cpu, sd) {
-                       enum idle_type itype;
-                       char mask_str[NR_CPUS];
-
-                       cpumask_scnprintf(mask_str, NR_CPUS, sd->span);
-                       seq_printf(seq, "domain%d %s", dcnt++, mask_str);
-                       for (itype = SCHED_IDLE; itype < MAX_IDLE_TYPES;
-                                       itype++) {
-                               seq_printf(seq, " %lu %lu %lu %lu %lu %lu %lu "
-                                               "%lu",
-                                   sd->lb_cnt[itype],
-                                   sd->lb_balanced[itype],
-                                   sd->lb_failed[itype],
-                                   sd->lb_imbalance[itype],
-                                   sd->lb_gained[itype],
-                                   sd->lb_hot_gained[itype],
-                                   sd->lb_nobusyq[itype],
-                                   sd->lb_nobusyg[itype]);
-                       }
-                       seq_printf(seq, " %lu %lu %lu %lu %lu %lu %lu %lu %lu"
-                           " %lu %lu %lu\n",
-                           sd->alb_cnt, sd->alb_failed, sd->alb_pushed,
-                           sd->sbe_cnt, sd->sbe_balanced, sd->sbe_pushed,
-                           sd->sbf_cnt, sd->sbf_balanced, sd->sbf_pushed,
-                           sd->ttwu_wake_remote, sd->ttwu_move_affine,
-                           sd->ttwu_move_balance);
-               }
-               preempt_enable();
-#endif
-       }
-       return 0;
-}
-
-static int schedstat_open(struct inode *inode, struct file *file)
-{
-       unsigned int size = PAGE_SIZE * (1 + num_online_cpus() / 32);
-       char *buf = kmalloc(size, GFP_KERNEL);
-       struct seq_file *m;
-       int res;
-
-       if (!buf)
-               return -ENOMEM;
-       res = single_open(file, show_schedstat, NULL);
-       if (!res) {
-               m = file->private_data;
-               m->buf = buf;
-               m->size = size;
-       } else
-               kfree(buf);
-       return res;
-}
-
-const struct file_operations proc_schedstat_operations = {
-       .open    = schedstat_open,
-       .read    = seq_read,
-       .llseek  = seq_lseek,
-       .release = single_release,
-};
-
-/*
- * Expects runqueue lock to be held for atomicity of update
- */
-static inline void
-rq_sched_info_arrive(struct rq *rq, unsigned long delta_jiffies)
-{
-       if (rq) {
-               rq->rq_sched_info.run_delay += delta_jiffies;
-               rq->rq_sched_info.pcnt++;
-       }
-}
-
-/*
- * Expects runqueue lock to be held for atomicity of update
- */
-static inline void
-rq_sched_info_depart(struct rq *rq, unsigned long delta_jiffies)
-{
-       if (rq)
-               rq->rq_sched_info.cpu_time += delta_jiffies;
-}
-# define schedstat_inc(rq, field)      do { (rq)->field++; } while (0)
-# define schedstat_add(rq, field, amt) do { (rq)->field += (amt); } while (0)
-#else /* !CONFIG_SCHEDSTATS */
-static inline void
-rq_sched_info_arrive(struct rq *rq, unsigned long delta_jiffies)
-{}
-static inline void
-rq_sched_info_depart(struct rq *rq, unsigned long delta_jiffies)
-{}
-# define schedstat_inc(rq, field)      do { } while (0)
-# define schedstat_add(rq, field, amt) do { } while (0)
-#endif
-
 /*
  * this_rq_lock - lock this runqueue and disable interrupts.
  */
@@ -603,177 +535,172 @@ static inline struct rq *this_rq_lock(void)
        return rq;
 }
 
-#if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT)
 /*
- * Called when a process is dequeued from the active array and given
- * the cpu.  We should note that with the exception of interactive
- * tasks, the expired queue will become the active queue after the active
- * queue is empty, without explicitly dequeuing and requeuing tasks in the
- * expired queue.  (Interactive tasks may be requeued directly to the
- * active queue, thus delaying tasks in the expired queue from running;
- * see scheduler_tick()).
- *
- * This function is only called from sched_info_arrive(), rather than
- * dequeue_task(). Even though a task may be queued and dequeued multiple
- * times as it is shuffled about, we're really interested in knowing how
- * long it was from the *first* time it was queued to the time that it
- * finally hit a cpu.
+ * CPU frequency is/was unstable - start new by setting prev_clock_raw:
  */
-static inline void sched_info_dequeued(struct task_struct *t)
+void sched_clock_unstable_event(void)
 {
-       t->sched_info.last_queued = 0;
+       unsigned long flags;
+       struct rq *rq;
+
+       rq = task_rq_lock(current, &flags);
+       rq->prev_clock_raw = sched_clock();
+       rq->clock_unstable_events++;
+       task_rq_unlock(rq, &flags);
 }
 
 /*
- * Called when a task finally hits the cpu.  We can now calculate how
- * long it was waiting to run.  We also note when it began so that we
- * can keep stats on how long its timeslice is.
+ * resched_task - mark a task 'to be rescheduled now'.
+ *
+ * On UP this means the setting of the need_resched flag, on SMP it
+ * might also involve a cross-CPU call to trigger the scheduler on
+ * the target CPU.
  */
-static void sched_info_arrive(struct task_struct *t)
+#ifdef CONFIG_SMP
+
+#ifndef tsk_is_polling
+#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
+#endif
+
+static void resched_task(struct task_struct *p)
 {
-       unsigned long now = jiffies, delta_jiffies = 0;
+       int cpu;
+
+       assert_spin_locked(&task_rq(p)->lock);
+
+       if (unlikely(test_tsk_thread_flag(p, TIF_NEED_RESCHED)))
+               return;
+
+       set_tsk_thread_flag(p, TIF_NEED_RESCHED);
 
-       if (t->sched_info.last_queued)
-               delta_jiffies = now - t->sched_info.last_queued;
-       sched_info_dequeued(t);
-       t->sched_info.run_delay += delta_jiffies;
-       t->sched_info.last_arrival = now;
-       t->sched_info.pcnt++;
+       cpu = task_cpu(p);
+       if (cpu == smp_processor_id())
+               return;
 
-       rq_sched_info_arrive(task_rq(t), delta_jiffies);
+       /* NEED_RESCHED must be visible before we test polling */
+       smp_mb();
+       if (!tsk_is_polling(p))
+               smp_send_reschedule(cpu);
 }
 
-/*
- * Called when a process is queued into either the active or expired
- * array.  The time is noted and later used to determine how long we
- * had to wait for us to reach the cpu.  Since the expired queue will
- * become the active queue after active queue is empty, without dequeuing
- * and requeuing any tasks, we are interested in queuing to either. It
- * is unusual but not impossible for tasks to be dequeued and immediately
- * requeued in the same or another array: this can happen in sched_yield(),
- * set_user_nice(), and even load_balance() as it moves tasks from runqueue
- * to runqueue.
- *
- * This function is only called from enqueue_task(), but also only updates
- * the timestamp if it is already not set.  It's assumed that
- * sched_info_dequeued() will clear that stamp when appropriate.
- */
-static inline void sched_info_queued(struct task_struct *t)
+static void resched_cpu(int cpu)
 {
-       if (unlikely(sched_info_on()))
-               if (!t->sched_info.last_queued)
-                       t->sched_info.last_queued = jiffies;
+       struct rq *rq = cpu_rq(cpu);
+       unsigned long flags;
+
+       if (!spin_trylock_irqsave(&rq->lock, flags))
+               return;
+       resched_task(cpu_curr(cpu));
+       spin_unlock_irqrestore(&rq->lock, flags);
 }
+#else
+static inline void resched_task(struct task_struct *p)
+{
+       assert_spin_locked(&task_rq(p)->lock);
+       set_tsk_need_resched(p);
+}
+#endif
 
-/*
- * Called when a process ceases being the active-running process, either
- * voluntarily or involuntarily.  Now we can calculate how long we ran.
- */
-static inline void sched_info_depart(struct task_struct *t)
+static u64 div64_likely32(u64 divident, unsigned long divisor)
 {
-       unsigned long delta_jiffies = jiffies - t->sched_info.last_arrival;
+#if BITS_PER_LONG == 32
+       if (likely(divident <= 0xffffffffULL))
+               return (u32)divident / divisor;
+       do_div(divident, divisor);
 
-       t->sched_info.cpu_time += delta_jiffies;
-       rq_sched_info_depart(task_rq(t), delta_jiffies);
+       return divident;
+#else
+       return divident / divisor;
+#endif
 }
 
-/*
- * Called when tasks are switched involuntarily due, typically, to expiring
- * their time slice.  (This may also be called when switching to or from
- * the idle task.)  We are only called when prev != next.
- */
-static inline void
-__sched_info_switch(struct task_struct *prev, struct task_struct *next)
+#if BITS_PER_LONG == 32
+# define WMULT_CONST   (~0UL)
+#else
+# define WMULT_CONST   (1UL << 32)
+#endif
+
+#define WMULT_SHIFT    32
+
+static inline unsigned long
+calc_delta_mine(unsigned long delta_exec, unsigned long weight,
+               struct load_weight *lw)
 {
-       struct rq *rq = task_rq(prev);
+       u64 tmp;
+
+       if (unlikely(!lw->inv_weight))
+               lw->inv_weight = WMULT_CONST / lw->weight;
 
+       tmp = (u64)delta_exec * weight;
        /*
-        * prev now departs the cpu.  It's not interesting to record
-        * stats about how efficient we were at scheduling the idle
-        * process, however.
+        * Check whether we'd overflow the 64-bit multiplication:
         */
-       if (prev != rq->idle)
-               sched_info_depart(prev);
+       if (unlikely(tmp > WMULT_CONST)) {
+               tmp = ((tmp >> WMULT_SHIFT/2) * lw->inv_weight)
+                               >> (WMULT_SHIFT/2);
+       } else {
+               tmp = (tmp * lw->inv_weight) >> WMULT_SHIFT;
+       }
 
-       if (next != rq->idle)
-               sched_info_arrive(next);
-}
-static inline void
-sched_info_switch(struct task_struct *prev, struct task_struct *next)
-{
-       if (unlikely(sched_info_on()))
-               __sched_info_switch(prev, next);
+       return (unsigned long)min(tmp, (u64)sysctl_sched_runtime_limit);
 }
-#else
-#define sched_info_queued(t)           do { } while (0)
-#define sched_info_switch(t, next)     do { } while (0)
-#endif /* CONFIG_SCHEDSTATS || CONFIG_TASK_DELAY_ACCT */
 
-/*
- * Adding/removing a task to/from a priority array:
- */
-static void dequeue_task(struct task_struct *p, struct prio_array *array)
+static inline unsigned long
+calc_delta_fair(unsigned long delta_exec, struct load_weight *lw)
 {
-       array->nr_active--;
-       list_del(&p->run_list);
-       if (list_empty(array->queue + p->prio))
-               __clear_bit(p->prio, array->bitmap);
+       return calc_delta_mine(delta_exec, NICE_0_LOAD, lw);
 }
 
-static void enqueue_task(struct task_struct *p, struct prio_array *array)
+static void update_load_add(struct load_weight *lw, unsigned long inc)
 {
-       sched_info_queued(p);
-       list_add_tail(&p->run_list, array->queue + p->prio);
-       __set_bit(p->prio, array->bitmap);
-       array->nr_active++;
-       p->array = array;
+       lw->weight += inc;
+       lw->inv_weight = 0;
 }
 
-/*
- * Put task to the end of the run list without the overhead of dequeue
- * followed by enqueue.
- */
-static void requeue_task(struct task_struct *p, struct prio_array *array)
+static void update_load_sub(struct load_weight *lw, unsigned long dec)
 {
-       list_move_tail(&p->run_list, array->queue + p->prio);
+       lw->weight -= dec;
+       lw->inv_weight = 0;
 }
 
-static inline void
-enqueue_task_head(struct task_struct *p, struct prio_array *array)
+static void __update_curr_load(struct rq *rq, struct load_stat *ls)
 {
-       list_add(&p->run_list, array->queue + p->prio);
-       __set_bit(p->prio, array->bitmap);
-       array->nr_active++;
-       p->array = array;
+       if (rq->curr != rq->idle && ls->load.weight) {
+               ls->delta_exec += ls->delta_stat;
+               ls->delta_fair += calc_delta_fair(ls->delta_stat, &ls->load);
+               ls->delta_stat = 0;
+       }
 }
 
 /*
- * __normal_prio - return the priority that is based on the static
- * priority but is modified by bonuses/penalties.
- *
- * We scale the actual sleep average [0 .... MAX_SLEEP_AVG]
- * into the -5 ... 0 ... +5 bonus/penalty range.
+ * Update delta_exec, delta_fair fields for rq.
  *
- * We use 25% of the full 0...39 priority range so that:
+ * delta_fair clock advances at a rate inversely proportional to
+ * total load (rq->ls.load.weight) on the runqueue, while
+ * delta_exec advances at the same rate as wall-clock (provided
+ * cpu is not idle).
  *
- * 1) nice +19 interactive tasks do not preempt nice 0 CPU hogs.
- * 2) nice -20 CPU hogs do not get preempted by nice 0 tasks.
+ * delta_exec / delta_fair is a measure of the (smoothened) load on this
+ * runqueue over any given interval. This (smoothened) load is used
+ * during load balance.
  *
- * Both properties are important to certain workloads.
+ * This function is called /before/ updating rq->ls.load
+ * and when switching tasks.
  */
-
-static inline int __normal_prio(struct task_struct *p)
+static void update_curr_load(struct rq *rq, u64 now)
 {
-       int bonus, prio;
+       struct load_stat *ls = &rq->ls;
+       u64 start;
 
-       bonus = CURRENT_BONUS(p) - MAX_BONUS / 2;
-
-       prio = p->static_prio - bonus;
-       if (prio < MAX_RT_PRIO)
-               prio = MAX_RT_PRIO;
-       if (prio > MAX_PRIO-1)
-               prio = MAX_PRIO-1;
-       return prio;
+       start = ls->load_update_start;
+       ls->load_update_start = now;
+       ls->delta_stat += now - start;
+       /*
+        * Stagger updates to ls->delta_fair. Very frequent updates
+        * can be expensive.
+        */
+       if (ls->delta_stat >= sysctl_sched_stat_granularity)
+               __update_curr_load(rq, ls);
 }
 
 /*
@@ -791,53 +718,146 @@ static inline int __normal_prio(struct task_struct *p)
  * this code will need modification
  */
 #define TIME_SLICE_NICE_ZERO DEF_TIMESLICE
-#define LOAD_WEIGHT(lp) \
+#define load_weight(lp) \
        (((lp) * SCHED_LOAD_SCALE) / TIME_SLICE_NICE_ZERO)
 #define PRIO_TO_LOAD_WEIGHT(prio) \
-       LOAD_WEIGHT(static_prio_timeslice(prio))
+       load_weight(static_prio_timeslice(prio))
 #define RTPRIO_TO_LOAD_WEIGHT(rp) \
-       (PRIO_TO_LOAD_WEIGHT(MAX_RT_PRIO) + LOAD_WEIGHT(rp))
+       (PRIO_TO_LOAD_WEIGHT(MAX_RT_PRIO) + load_weight(rp))
 
-static void set_load_weight(struct task_struct *p)
-{
-       if (has_rt_policy(p)) {
-#ifdef CONFIG_SMP
-               if (p == task_rq(p)->migration_thread)
-                       /*
-                        * The migration thread does the actual balancing.
-                        * Giving its load any weight will skew balancing
-                        * adversely.
-                        */
-                       p->load_weight = 0;
-               else
-#endif
-                       p->load_weight = RTPRIO_TO_LOAD_WEIGHT(p->rt_priority);
-       } else
-               p->load_weight = PRIO_TO_LOAD_WEIGHT(p->static_prio);
-}
+#define WEIGHT_IDLEPRIO                2
+#define WMULT_IDLEPRIO         (1 << 31)
+
+/*
+ * Nice levels are multiplicative, with a gentle 10% change for every
+ * nice level changed. I.e. when a CPU-bound task goes from nice 0 to
+ * nice 1, it will get ~10% less CPU time than another CPU-bound task
+ * that remained on nice 0.
+ *
+ * The "10% effect" is relative and cumulative: from _any_ nice level,
+ * if you go up 1 level, it's -10% CPU usage, if you go down 1 level
+ * it's +10% CPU usage.
+ */
+static const int prio_to_weight[40] = {
+/* -20 */ 88818, 71054, 56843, 45475, 36380, 29104, 23283, 18626, 14901, 11921,
+/* -10 */  9537,  7629,  6103,  4883,  3906,  3125,  2500,  2000,  1600,  1280,
+/*   0 */  NICE_0_LOAD /* 1024 */,
+/*   1 */          819,   655,   524,   419,   336,   268,   215,   172,   137,
+/*  10 */   110,    87,    70,    56,    45,    36,    29,    23,    18,    15,
+};
+
+static const u32 prio_to_wmult[40] = {
+       48356,   60446,   75558,   94446,  118058,  147573,
+       184467,  230589,  288233,  360285,  450347,
+       562979,  703746,  879575, 1099582, 1374389,
+       717986, 2147483, 2684354, 3355443, 4194304,
+       5244160, 6557201, 8196502, 10250518, 12782640,
+       16025997, 19976592, 24970740, 31350126, 39045157,
+       49367440, 61356675, 76695844, 95443717, 119304647,
+       148102320, 186737708, 238609294, 286331153,
+};
 
 static inline void
-inc_raw_weighted_load(struct rq *rq, const struct task_struct *p)
+inc_load(struct rq *rq, const struct task_struct *p, u64 now)
 {
-       rq->raw_weighted_load += p->load_weight;
+       update_curr_load(rq, now);
+       update_load_add(&rq->ls.load, p->se.load.weight);
 }
 
 static inline void
-dec_raw_weighted_load(struct rq *rq, const struct task_struct *p)
+dec_load(struct rq *rq, const struct task_struct *p, u64 now)
 {
-       rq->raw_weighted_load -= p->load_weight;
+       update_curr_load(rq, now);
+       update_load_sub(&rq->ls.load, p->se.load.weight);
 }
 
-static inline void inc_nr_running(struct task_struct *p, struct rq *rq)
+static inline void inc_nr_running(struct task_struct *p, struct rq *rq, u64 now)
 {
        rq->nr_running++;
-       inc_raw_weighted_load(rq, p);
+       inc_load(rq, p, now);
 }
 
-static inline void dec_nr_running(struct task_struct *p, struct rq *rq)
+static inline void dec_nr_running(struct task_struct *p, struct rq *rq, u64 now)
 {
        rq->nr_running--;
-       dec_raw_weighted_load(rq, p);
+       dec_load(rq, p, now);
+}
+
+static void activate_task(struct rq *rq, struct task_struct *p, int wakeup);
+
+/*
+ * runqueue iterator, to support SMP load-balancing between different
+ * scheduling classes, without having to expose their internal data
+ * structures to the load-balancing proper:
+ */
+struct rq_iterator {
+       void *arg;
+       struct task_struct *(*start)(void *);
+       struct task_struct *(*next)(void *);
+};
+
+static int balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest,
+                     unsigned long max_nr_move, unsigned long max_load_move,
+                     struct sched_domain *sd, enum cpu_idle_type idle,
+                     int *all_pinned, unsigned long *load_moved,
+                     int this_best_prio, int best_prio, int best_prio_seen,
+                     struct rq_iterator *iterator);
+
+#include "sched_stats.h"
+#include "sched_rt.c"
+#include "sched_fair.c"
+#include "sched_idletask.c"
+#ifdef CONFIG_SCHED_DEBUG
+# include "sched_debug.c"
+#endif
+
+#define sched_class_highest (&rt_sched_class)
+
+static void set_load_weight(struct task_struct *p)
+{
+       task_rq(p)->cfs.wait_runtime -= p->se.wait_runtime;
+       p->se.wait_runtime = 0;
+
+       if (task_has_rt_policy(p)) {
+               p->se.load.weight = prio_to_weight[0] * 2;
+               p->se.load.inv_weight = prio_to_wmult[0] >> 1;
+               return;
+       }
+
+       /*
+        * SCHED_IDLE tasks get minimal weight:
+        */
+       if (p->policy == SCHED_IDLE) {
+               p->se.load.weight = WEIGHT_IDLEPRIO;
+               p->se.load.inv_weight = WMULT_IDLEPRIO;
+               return;
+       }
+
+       p->se.load.weight = prio_to_weight[p->static_prio - MAX_RT_PRIO];
+       p->se.load.inv_weight = prio_to_wmult[p->static_prio - MAX_RT_PRIO];
+}
+
+static void
+enqueue_task(struct rq *rq, struct task_struct *p, int wakeup, u64 now)
+{
+       sched_info_queued(p);
+       p->sched_class->enqueue_task(rq, p, wakeup, now);
+       p->se.on_rq = 1;
+}
+
+static void
+dequeue_task(struct rq *rq, struct task_struct *p, int sleep, u64 now)
+{
+       p->sched_class->dequeue_task(rq, p, sleep, now);
+       p->se.on_rq = 0;
+}
+
+/*
+ * __normal_prio - return the priority that is based on the static prio
+ */
+static inline int __normal_prio(struct task_struct *p)
+{
+       return p->static_prio;
 }
 
 /*
@@ -851,7 +871,7 @@ static inline int normal_prio(struct task_struct *p)
 {
        int prio;
 
-       if (has_rt_policy(p))
+       if (task_has_rt_policy(p))
                prio = MAX_RT_PRIO-1 - p->rt_priority;
        else
                prio = __normal_prio(p);
@@ -879,222 +899,47 @@ static int effective_prio(struct task_struct *p)
 }
 
 /*
- * __activate_task - move a task to the runqueue.
- */
-static void __activate_task(struct task_struct *p, struct rq *rq)
-{
-       struct prio_array *target = rq->active;
-
-       if (batch_task(p))
-               target = rq->expired;
-       enqueue_task(p, target);
-       inc_nr_running(p, rq);
-}
-
-/*
- * __activate_idle_task - move idle task to the _front_ of runqueue.
- */
-static inline void __activate_idle_task(struct task_struct *p, struct rq *rq)
-{
-       enqueue_task_head(p, rq->active);
-       inc_nr_running(p, rq);
-}
-
-/*
- * Recalculate p->normal_prio and p->prio after having slept,
- * updating the sleep-average too:
+ * activate_task - move a task to the runqueue.
  */
-static int recalc_task_prio(struct task_struct *p, unsigned long long now)
+static void activate_task(struct rq *rq, struct task_struct *p, int wakeup)
 {
-       /* Caller must always ensure 'now >= p->timestamp' */
-       unsigned long sleep_time = now - p->timestamp;
-
-       if (batch_task(p))
-               sleep_time = 0;
-
-       if (likely(sleep_time > 0)) {
-               /*
-                * This ceiling is set to the lowest priority that would allow
-                * a task to be reinserted into the active array on timeslice
-                * completion.
-                */
-               unsigned long ceiling = INTERACTIVE_SLEEP(p);
-
-               if (p->mm && sleep_time > ceiling && p->sleep_avg < ceiling) {
-                       /*
-                        * Prevents user tasks from achieving best priority
-                        * with one single large enough sleep.
-                        */
-                       p->sleep_avg = ceiling;
-                       /*
-                        * Using INTERACTIVE_SLEEP() as a ceiling places a
-                        * nice(0) task 1ms sleep away from promotion, and
-                        * gives it 700ms to round-robin with no chance of
-                        * being demoted.  This is more than generous, so
-                        * mark this sleep as non-interactive to prevent the
-                        * on-runqueue bonus logic from intervening should
-                        * this task not receive cpu immediately.
-                        */
-                       p->sleep_type = SLEEP_NONINTERACTIVE;
-               } else {
-                       /*
-                        * Tasks waking from uninterruptible sleep are
-                        * limited in their sleep_avg rise as they
-                        * are likely to be waiting on I/O
-                        */
-                       if (p->sleep_type == SLEEP_NONINTERACTIVE && p->mm) {
-                               if (p->sleep_avg >= ceiling)
-                                       sleep_time = 0;
-                               else if (p->sleep_avg + sleep_time >=
-                                        ceiling) {
-                                               p->sleep_avg = ceiling;
-                                               sleep_time = 0;
-                               }
-                       }
-
-                       /*
-                        * This code gives a bonus to interactive tasks.
-                        *
-                        * The boost works by updating the 'average sleep time'
-                        * value here, based on ->timestamp. The more time a
-                        * task spends sleeping, the higher the average gets -
-                        * and the higher the priority boost gets as well.
-                        */
-                       p->sleep_avg += sleep_time;
+       u64 now = rq_clock(rq);
 
-               }
-               if (p->sleep_avg > NS_MAX_SLEEP_AVG)
-                       p->sleep_avg = NS_MAX_SLEEP_AVG;
-       }
+       if (p->state == TASK_UNINTERRUPTIBLE)
+               rq->nr_uninterruptible--;
 
-       return effective_prio(p);
+       enqueue_task(rq, p, wakeup, now);
+       inc_nr_running(p, rq, now);
 }
 
 /*
- * activate_task - move a task to the runqueue and do priority recalculation
- *
- * Update all the scheduling statistics stuff. (sleep average
- * calculation, priority modifiers, etc.)
+ * activate_idle_task - move idle task to the _front_ of runqueue.
  */
-static void activate_task(struct task_struct *p, struct rq *rq, int local)
+static inline void activate_idle_task(struct task_struct *p, struct rq *rq)
 {
-       unsigned long long now;
-
-       if (rt_task(p))
-               goto out;
-
-       now = sched_clock();
-#ifdef CONFIG_SMP
-       if (!local) {
-               /* Compensate for drifting sched_clock */
-               struct rq *this_rq = this_rq();
-               now = (now - this_rq->most_recent_timestamp)
-                       + rq->most_recent_timestamp;
-       }
-#endif
+       u64 now = rq_clock(rq);
 
-       /*
-        * Sleep time is in units of nanosecs, so shift by 20 to get a
-        * milliseconds-range estimation of the amount of time that the task
-        * spent sleeping:
-        */
-       if (unlikely(prof_on == SLEEP_PROFILING)) {
-               if (p->state == TASK_UNINTERRUPTIBLE)
-                       profile_hits(SLEEP_PROFILING, (void *)get_wchan(p),
-                                    (now - p->timestamp) >> 20);
-       }
-
-       p->prio = recalc_task_prio(p, now);
+       if (p->state == TASK_UNINTERRUPTIBLE)
+               rq->nr_uninterruptible--;
 
-       /*
-        * This checks to make sure it's not an uninterruptible task
-        * that is now waking up.
-        */
-       if (p->sleep_type == SLEEP_NORMAL) {
-               /*
-                * Tasks which were woken up by interrupts (ie. hw events)
-                * are most likely of interactive nature. So we give them
-                * the credit of extending their sleep time to the period
-                * of time they spend on the runqueue, waiting for execution
-                * on a CPU, first time around:
-                */
-               if (in_interrupt())
-                       p->sleep_type = SLEEP_INTERRUPTED;
-               else {
-                       /*
-                        * Normal first-time wakeups get a credit too for
-                        * on-runqueue time, but it will be weighted down:
-                        */
-                       p->sleep_type = SLEEP_INTERACTIVE;
-               }
-       }
-       p->timestamp = now;
-out:
-       __activate_task(p, rq);
+       enqueue_task(rq, p, 0, now);
+       inc_nr_running(p, rq, now);
 }
 
 /*
  * deactivate_task - remove a task from the runqueue.
  */
-static void deactivate_task(struct task_struct *p, struct rq *rq)
-{
-       dec_nr_running(p, rq);
-       dequeue_task(p, p->array);
-       p->array = NULL;
-}
-
-/*
- * resched_task - mark a task 'to be rescheduled now'.
- *
- * On UP this means the setting of the need_resched flag, on SMP it
- * might also involve a cross-CPU call to trigger the scheduler on
- * the target CPU.
- */
-#ifdef CONFIG_SMP
-
-#ifndef tsk_is_polling
-#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
-#endif
-
-static void resched_task(struct task_struct *p)
+static void deactivate_task(struct rq *rq, struct task_struct *p, int sleep)
 {
-       int cpu;
+       u64 now = rq_clock(rq);
 
-       assert_spin_locked(&task_rq(p)->lock);
+       if (p->state == TASK_UNINTERRUPTIBLE)
+               rq->nr_uninterruptible++;
 
-       if (unlikely(test_tsk_thread_flag(p, TIF_NEED_RESCHED)))
-               return;
-
-       set_tsk_thread_flag(p, TIF_NEED_RESCHED);
-
-       cpu = task_cpu(p);
-       if (cpu == smp_processor_id())
-               return;
-
-       /* NEED_RESCHED must be visible before we test polling */
-       smp_mb();
-       if (!tsk_is_polling(p))
-               smp_send_reschedule(cpu);
+       dequeue_task(rq, p, sleep, now);
+       dec_nr_running(p, rq, now);
 }
 
-static void resched_cpu(int cpu)
-{
-       struct rq *rq = cpu_rq(cpu);
-       unsigned long flags;
-
-       if (!spin_trylock_irqsave(&rq->lock, flags))
-               return;
-       resched_task(cpu_curr(cpu));
-       spin_unlock_irqrestore(&rq->lock, flags);
-}
-#else
-static inline void resched_task(struct task_struct *p)
-{
-       assert_spin_locked(&task_rq(p)->lock);
-       set_tsk_need_resched(p);
-}
-#endif
-
 /**
  * task_curr - is this task currently executing on a CPU?
  * @p: the task in question.
@@ -1107,10 +952,42 @@ inline int task_curr(const struct task_struct *p)
 /* Used instead of source_load when we know the type == 0 */
 unsigned long weighted_cpuload(const int cpu)
 {
-       return cpu_rq(cpu)->raw_weighted_load;
+       return cpu_rq(cpu)->ls.load.weight;
+}
+
+static inline void __set_task_cpu(struct task_struct *p, unsigned int cpu)
+{
+#ifdef CONFIG_SMP
+       task_thread_info(p)->cpu = cpu;
+       set_task_cfs_rq(p);
+#endif
 }
 
 #ifdef CONFIG_SMP
+
+void set_task_cpu(struct task_struct *p, unsigned int new_cpu)
+{
+       int old_cpu = task_cpu(p);
+       struct rq *old_rq = cpu_rq(old_cpu), *new_rq = cpu_rq(new_cpu);
+       u64 clock_offset, fair_clock_offset;
+
+       clock_offset = old_rq->clock - new_rq->clock;
+       fair_clock_offset = old_rq->cfs.fair_clock -
+                                                new_rq->cfs.fair_clock;
+       if (p->se.wait_start)
+               p->se.wait_start -= clock_offset;
+       if (p->se.wait_start_fair)
+               p->se.wait_start_fair -= fair_clock_offset;
+       if (p->se.sleep_start)
+               p->se.sleep_start -= clock_offset;
+       if (p->se.block_start)
+               p->se.block_start -= clock_offset;
+       if (p->se.sleep_start_fair)
+               p->se.sleep_start_fair -= fair_clock_offset;
+
+       __set_task_cpu(p, new_cpu);
+}
+
 struct migration_req {
        struct list_head list;
 
@@ -1133,7 +1010,7 @@ migrate_task(struct task_struct *p, int dest_cpu, struct migration_req *req)
         * If the task is not on a runqueue (and not running), then
         * it is sufficient to simply update the task's cpu field.
         */
-       if (!p->array && !task_running(rq, p)) {
+       if (!p->se.on_rq && !task_running(rq, p)) {
                set_task_cpu(p, dest_cpu);
                return 0;
        }
@@ -1158,9 +1035,8 @@ migrate_task(struct task_struct *p, int dest_cpu, struct migration_req *req)
 void wait_task_inactive(struct task_struct *p)
 {
        unsigned long flags;
+       int running, on_rq;
        struct rq *rq;
-       struct prio_array *array;
-       int running;
 
 repeat:
        /*
@@ -1192,7 +1068,7 @@ repeat:
         */
        rq = task_rq_lock(p, &flags);
        running = task_running(rq, p);
-       array = p->array;
+       on_rq = p->se.on_rq;
        task_rq_unlock(rq, &flags);
 
        /*
@@ -1215,7 +1091,7 @@ repeat:
         * running right now), it's preempted, and we should
         * yield - it could be a while.
         */
-       if (unlikely(array)) {
+       if (unlikely(on_rq)) {
                yield();
                goto repeat;
        }
@@ -1261,11 +1137,12 @@ void kick_process(struct task_struct *p)
 static inline unsigned long source_load(int cpu, int type)
 {
        struct rq *rq = cpu_rq(cpu);
+       unsigned long total = weighted_cpuload(cpu);
 
        if (type == 0)
-               return rq->raw_weighted_load;
+               return total;
 
-       return min(rq->cpu_load[type-1], rq->raw_weighted_load);
+       return min(rq->cpu_load[type-1], total);
 }
 
 /*
@@ -1275,11 +1152,12 @@ static inline unsigned long source_load(int cpu, int type)
 static inline unsigned long target_load(int cpu, int type)
 {
        struct rq *rq = cpu_rq(cpu);
+       unsigned long total = weighted_cpuload(cpu);
 
        if (type == 0)
-               return rq->raw_weighted_load;
+               return total;
 
-       return max(rq->cpu_load[type-1], rq->raw_weighted_load);
+       return max(rq->cpu_load[type-1], total);
 }
 
 /*
@@ -1288,9 +1166,10 @@ static inline unsigned long target_load(int cpu, int type)
 static inline unsigned long cpu_avg_load_per_task(int cpu)
 {
        struct rq *rq = cpu_rq(cpu);
+       unsigned long total = weighted_cpuload(cpu);
        unsigned long n = rq->nr_running;
 
-       return n ? rq->raw_weighted_load / n : SCHED_LOAD_SCALE;
+       return n ? total / n : SCHED_LOAD_SCALE;
 }
 
 /*
@@ -1392,9 +1271,9 @@ static int sched_balance_self(int cpu, int flag)
        struct sched_domain *tmp, *sd = NULL;
 
        for_each_domain(cpu, tmp) {
-               /*
-                * If power savings logic is enabled for a domain, stop there.
-                */
+               /*
+                * If power savings logic is enabled for a domain, stop there.
+                */
                if (tmp->flags & SD_POWERSAVINGS_BALANCE)
                        break;
                if (tmp->flags & flag)
@@ -1477,9 +1356,9 @@ static int wake_idle(int cpu, struct task_struct *p)
                                if (idle_cpu(i))
                                        return i;
                        }
-               }
-               else
+               } else {
                        break;
+               }
        }
        return cpu;
 }
@@ -1521,7 +1400,7 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, int sync)
        if (!(old_state & state))
                goto out;
 
-       if (p->array)
+       if (p->se.on_rq)
                goto out_running;
 
        cpu = task_cpu(p);
@@ -1576,11 +1455,11 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, int sync)
                         * of the current CPU:
                         */
                        if (sync)
-                               tl -= current->load_weight;
+                               tl -= current->se.load.weight;
 
                        if ((tl <= load &&
                                tl + target_load(cpu, idx) <= tl_per_task) ||
-                               100*(tl + p->load_weight) <= imbalance*load) {
+                              100*(tl + p->se.load.weight) <= imbalance*load) {
                                /*
                                 * This domain has SD_WAKE_AFFINE and
                                 * p is cache cold in this domain, and
@@ -1614,7 +1493,7 @@ out_set_cpu:
                old_state = p->state;
                if (!(old_state & state))
                        goto out;
-               if (p->array)
+               if (p->se.on_rq)
                        goto out_running;
 
                this_cpu = smp_processor_id();
@@ -1623,25 +1502,7 @@ out_set_cpu:
 
 out_activate:
 #endif /* CONFIG_SMP */
-       if (old_state == TASK_UNINTERRUPTIBLE) {
-               rq->nr_uninterruptible--;
-               /*
-                * Tasks on involuntary sleep don't earn
-                * sleep_avg beyond just interactive state.
-                */
-               p->sleep_type = SLEEP_NONINTERACTIVE;
-       } else
-
-       /*
-        * Tasks that have marked their sleep as noninteractive get
-        * woken up with their sleep average not weighted in an
-        * interactive way.
-        */
-               if (old_state & TASK_NONINTERACTIVE)
-                       p->sleep_type = SLEEP_NONINTERACTIVE;
-
-
-       activate_task(p, rq, cpu == this_cpu);
+       activate_task(rq, p, 1);
        /*
         * Sync wakeups (i.e. those types of wakeups where the waker
         * has indicated that it will leave the CPU in short order)
@@ -1650,10 +1511,8 @@ out_activate:
         * the waker guarantees that the freshly woken up task is going
         * to be considered on this CPU.)
         */
-       if (!sync || cpu != this_cpu) {
-               if (TASK_PREEMPTS_CURR(p, rq))
-                       resched_task(rq->curr);
-       }
+       if (!sync || cpu != this_cpu)
+               check_preempt_curr(rq, p);
        success = 1;
 
 out_running:
@@ -1676,19 +1535,36 @@ int fastcall wake_up_state(struct task_struct *p, unsigned int state)
        return try_to_wake_up(p, state, 0);
 }
 
-static void task_running_tick(struct rq *rq, struct task_struct *p);
 /*
  * Perform scheduler related setup for a newly forked process p.
  * p is forked by current.
- */
-void fastcall sched_fork(struct task_struct *p, int clone_flags)
-{
-       int cpu = get_cpu();
+ *
+ * __sched_fork() is basic setup used by init_idle() too:
+ */
+static void __sched_fork(struct task_struct *p)
+{
+       p->se.wait_start_fair           = 0;
+       p->se.wait_start                = 0;
+       p->se.exec_start                = 0;
+       p->se.sum_exec_runtime          = 0;
+       p->se.delta_exec                = 0;
+       p->se.delta_fair_run            = 0;
+       p->se.delta_fair_sleep          = 0;
+       p->se.wait_runtime              = 0;
+       p->se.sum_wait_runtime          = 0;
+       p->se.sum_sleep_runtime         = 0;
+       p->se.sleep_start               = 0;
+       p->se.sleep_start_fair          = 0;
+       p->se.block_start               = 0;
+       p->se.sleep_max                 = 0;
+       p->se.block_max                 = 0;
+       p->se.exec_max                  = 0;
+       p->se.wait_max                  = 0;
+       p->se.wait_runtime_overruns     = 0;
+       p->se.wait_runtime_underruns    = 0;
 
-#ifdef CONFIG_SMP
-       cpu = sched_balance_self(cpu, SD_BALANCE_FORK);
-#endif
-       set_task_cpu(p, cpu);
+       INIT_LIST_HEAD(&p->run_list);
+       p->se.on_rq = 0;
 
        /*
         * We mark the process as running here, but have not actually
@@ -1697,16 +1573,29 @@ void fastcall sched_fork(struct task_struct *p, int clone_flags)
         * event cannot wake it up and insert it on the runqueue either.
         */
        p->state = TASK_RUNNING;
+}
+
+/*
+ * fork()/clone()-time setup:
+ */
+void sched_fork(struct task_struct *p, int clone_flags)
+{
+       int cpu = get_cpu();
+
+       __sched_fork(p);
+
+#ifdef CONFIG_SMP
+       cpu = sched_balance_self(cpu, SD_BALANCE_FORK);
+#endif
+       __set_task_cpu(p, cpu);
 
        /*
         * Make sure we do not leak PI boosting priority to the child:
         */
        p->prio = current->normal_prio;
 
-       INIT_LIST_HEAD(&p->run_list);
-       p->array = NULL;
 #if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT)
-       if (unlikely(sched_info_on()))
+       if (likely(sched_info_on()))
                memset(&p->sched_info, 0, sizeof(p->sched_info));
 #endif
 #if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW)
@@ -1716,33 +1605,15 @@ void fastcall sched_fork(struct task_struct *p, int clone_flags)
        /* Want to start with kernel preemption disabled. */
        task_thread_info(p)->preempt_count = 1;
 #endif
-       /*
-        * Share the timeslice between parent and child, thus the
-        * total amount of pending timeslices in the system doesn't change,
-        * resulting in more scheduling fairness.
-        */
-       local_irq_disable();
-       p->time_slice = (current->time_slice + 1) >> 1;
-       /*
-        * The remainder of the first timeslice might be recovered by
-        * the parent if the child exits early enough.
-        */
-       p->first_time_slice = 1;
-       current->time_slice >>= 1;
-       p->timestamp = sched_clock();
-       if (unlikely(!current->time_slice)) {
-               /*
-                * This case is rare, it happens when the parent has only
-                * a single jiffy left from its timeslice. Taking the
-                * runqueue lock is not a problem.
-                */
-               current->time_slice = 1;
-               task_running_tick(cpu_rq(cpu), current);
-       }
-       local_irq_enable();
        put_cpu();
 }
 
+/*
+ * After fork, child runs first. (default) If set to 0 then
+ * parent will (try to) run first.
+ */
+unsigned int __read_mostly sysctl_sched_child_runs_first = 1;
+
 /*
  * wake_up_new_task - wake up a newly created task for the first time.
  *
@@ -1752,107 +1623,27 @@ void fastcall sched_fork(struct task_struct *p, int clone_flags)
  */
 void fastcall wake_up_new_task(struct task_struct *p, unsigned long clone_flags)
 {
-       struct rq *rq, *this_rq;
        unsigned long flags;
-       int this_cpu, cpu;
+       struct rq *rq;
+       int this_cpu;
 
        rq = task_rq_lock(p, &flags);
        BUG_ON(p->state != TASK_RUNNING);
-       this_cpu = smp_processor_id();
-       cpu = task_cpu(p);
-
-       /*
-        * We decrease the sleep average of forking parents
-        * and children as well, to keep max-interactive tasks
-        * from forking tasks that are max-interactive. The parent
-        * (current) is done further down, under its lock.
-        */
-       p->sleep_avg = JIFFIES_TO_NS(CURRENT_BONUS(p) *
-               CHILD_PENALTY / 100 * MAX_SLEEP_AVG / MAX_BONUS);
+       this_cpu = smp_processor_id(); /* parent's CPU */
 
        p->prio = effective_prio(p);
 
-       if (likely(cpu == this_cpu)) {
-               if (!(clone_flags & CLONE_VM)) {
-                       /*
-                        * The VM isn't cloned, so we're in a good position to
-                        * do child-runs-first in anticipation of an exec. This
-                        * usually avoids a lot of COW overhead.
-                        */
-                       if (unlikely(!current->array))
-                               __activate_task(p, rq);
-                       else {
-                               p->prio = current->prio;
-                               p->normal_prio = current->normal_prio;
-                               list_add_tail(&p->run_list, &current->run_list);
-                               p->array = current->array;
-                               p->array->nr_active++;
-                               inc_nr_running(p, rq);
-                       }
-                       set_need_resched();
-               } else
-                       /* Run child last */
-                       __activate_task(p, rq);
-               /*
-                * We skip the following code due to cpu == this_cpu
-                *
-                *   task_rq_unlock(rq, &flags);
-                *   this_rq = task_rq_lock(current, &flags);
-                */
-               this_rq = rq;
+       if (!sysctl_sched_child_runs_first || (clone_flags & CLONE_VM) ||
+                       task_cpu(p) != this_cpu || !current->se.on_rq) {
+               activate_task(rq, p, 0);
        } else {
-               this_rq = cpu_rq(this_cpu);
-
-               /*
-                * Not the local CPU - must adjust timestamp. This should
-                * get optimised away in the !CONFIG_SMP case.
-                */
-               p->timestamp = (p->timestamp - this_rq->most_recent_timestamp)
-                                       + rq->most_recent_timestamp;
-               __activate_task(p, rq);
-               if (TASK_PREEMPTS_CURR(p, rq))
-                       resched_task(rq->curr);
-
                /*
-                * Parent and child are on different CPUs, now get the
-                * parent runqueue to update the parent's ->sleep_avg:
+                * Let the scheduling class do new task startup
+                * management (if any):
                 */
-               task_rq_unlock(rq, &flags);
-               this_rq = task_rq_lock(current, &flags);
-       }
-       current->sleep_avg = JIFFIES_TO_NS(CURRENT_BONUS(current) *
-               PARENT_PENALTY / 100 * MAX_SLEEP_AVG / MAX_BONUS);
-       task_rq_unlock(this_rq, &flags);
-}
-
-/*
- * Potentially available exiting-child timeslices are
- * retrieved here - this way the parent does not get
- * penalized for creating too many threads.
- *
- * (this cannot be used to 'generate' timeslices
- * artificially, because any timeslice recovered here
- * was given away by the parent in the first place.)
- */
-void fastcall sched_exit(struct task_struct *p)
-{
-       unsigned long flags;
-       struct rq *rq;
-
-       /*
-        * If the child was a (relative-) CPU hog then decrease
-        * the sleep_avg of the parent as well.
-        */
-       rq = task_rq_lock(p->parent, &flags);
-       if (p->first_time_slice && task_cpu(p) == task_cpu(p->parent)) {
-               p->parent->time_slice += p->time_slice;
-               if (unlikely(p->parent->time_slice > task_timeslice(p)))
-                       p->parent->time_slice = task_timeslice(p);
+               p->sched_class->task_new(rq, p);
        }
-       if (p->sleep_avg < p->parent->sleep_avg)
-               p->parent->sleep_avg = p->parent->sleep_avg /
-               (EXIT_WEIGHT + 1) * EXIT_WEIGHT + p->sleep_avg /
-               (EXIT_WEIGHT + 1);
+       check_preempt_curr(rq, p);
        task_rq_unlock(rq, &flags);
 }
 
@@ -1917,7 +1708,7 @@ static inline void finish_task_switch(struct rq *rq, struct task_struct *prev)
                /*
                 * Remove function-return probe instances associated with this
                 * task and put them back on the free list.
-                */
+                */
                kprobe_flush_task(prev);
                put_task_struct(prev);
        }
@@ -1945,13 +1736,15 @@ asmlinkage void schedule_tail(struct task_struct *prev)
  * context_switch - switch to the new MM and the new
  * thread's register state.
  */
-static inline struct task_struct *
+static inline void
 context_switch(struct rq *rq, struct task_struct *prev,
               struct task_struct *next)
 {
-       struct mm_struct *mm = next->mm;
-       struct mm_struct *oldmm = prev->active_mm;
+       struct mm_struct *mm, *oldmm;
 
+       prepare_task_switch(rq, next);
+       mm = next->mm;
+       oldmm = prev->active_mm;
        /*
         * For paravirt, this is coupled with an exit in switch_to to
         * combine the page table reload and the switch backend into
@@ -1959,16 +1752,15 @@ context_switch(struct rq *rq, struct task_struct *prev,
         */
        arch_enter_lazy_cpu_mode();
 
-       if (!mm) {
+       if (unlikely(!mm)) {
                next->active_mm = oldmm;
                atomic_inc(&oldmm->mm_count);
                enter_lazy_tlb(oldmm, next);
        } else
                switch_mm(oldmm, mm, next);
 
-       if (!prev->mm) {
+       if (unlikely(!prev->mm)) {
                prev->active_mm = NULL;
-               WARN_ON(rq->prev_mm);
                rq->prev_mm = oldmm;
        }
        /*
@@ -1984,7 +1776,13 @@ context_switch(struct rq *rq, struct task_struct *prev,
        /* Here we just switch the register state and the stack. */
        switch_to(prev, next, prev);
 
-       return prev;
+       barrier();
+       /*
+        * this_rq must be evaluated again because prev may have moved
+        * CPUs since it called schedule(), thus the 'rq' on its stack
+        * frame will be invalid.
+        */
+       finish_task_switch(this_rq(), prev);
 }
 
 /*
@@ -2057,17 +1855,65 @@ unsigned long nr_active(void)
        return running + uninterruptible;
 }
 
-#ifdef CONFIG_SMP
-
 /*
- * Is this task likely cache-hot:
+ * Update rq->cpu_load[] statistics. This function is usually called every
+ * scheduler tick (TICK_NSEC).
  */
-static inline int
-task_hot(struct task_struct *p, unsigned long long now, struct sched_domain *sd)
+static void update_cpu_load(struct rq *this_rq)
 {
-       return (long long)(now - p->last_ran) < (long long)sd->cache_hot_time;
+       u64 fair_delta64, exec_delta64, idle_delta64, sample_interval64, tmp64;
+       unsigned long total_load = this_rq->ls.load.weight;
+       unsigned long this_load =  total_load;
+       struct load_stat *ls = &this_rq->ls;
+       u64 now = __rq_clock(this_rq);
+       int i, scale;
+
+       this_rq->nr_load_updates++;
+       if (unlikely(!(sysctl_sched_features & SCHED_FEAT_PRECISE_CPU_LOAD)))
+               goto do_avg;
+
+       /* Update delta_fair/delta_exec fields first */
+       update_curr_load(this_rq, now);
+
+       fair_delta64 = ls->delta_fair + 1;
+       ls->delta_fair = 0;
+
+       exec_delta64 = ls->delta_exec + 1;
+       ls->delta_exec = 0;
+
+       sample_interval64 = now - ls->load_update_last;
+       ls->load_update_last = now;
+
+       if ((s64)sample_interval64 < (s64)TICK_NSEC)
+               sample_interval64 = TICK_NSEC;
+
+       if (exec_delta64 > sample_interval64)
+               exec_delta64 = sample_interval64;
+
+       idle_delta64 = sample_interval64 - exec_delta64;
+
+       tmp64 = div64_64(SCHED_LOAD_SCALE * exec_delta64, fair_delta64);
+       tmp64 = div64_64(tmp64 * exec_delta64, sample_interval64);
+
+       this_load = (unsigned long)tmp64;
+
+do_avg:
+
+       /* Update our load: */
+       for (i = 0, scale = 1; i < CPU_LOAD_IDX_MAX; i++, scale += scale) {
+               unsigned long old_load, new_load;
+
+               /* scale is effectively 1 << i now, and >> i divides by scale */
+
+               old_load = this_rq->cpu_load[i];
+               new_load = this_load;
+
+               this_rq->cpu_load[i] = (old_load*(scale-1) + new_load) >> i;
+       }
 }
 
+#ifdef CONFIG_SMP
+
 /*
  * double_rq_lock - safely lock two runqueues
  *
@@ -2184,23 +2030,17 @@ void sched_exec(void)
  * pull_task - move a task from a remote runqueue to the local runqueue.
  * Both runqueues must be locked.
  */
-static void pull_task(struct rq *src_rq, struct prio_array *src_array,
-                     struct task_struct *p, struct rq *this_rq,
-                     struct prio_array *this_array, int this_cpu)
+static void pull_task(struct rq *src_rq, struct task_struct *p,
+                     struct rq *this_rq, int this_cpu)
 {
-       dequeue_task(p, src_array);
-       dec_nr_running(p, src_rq);
+       deactivate_task(src_rq, p, 0);
        set_task_cpu(p, this_cpu);
-       inc_nr_running(p, this_rq);
-       enqueue_task(p, this_array);
-       p->timestamp = (p->timestamp - src_rq->most_recent_timestamp)
-                               + this_rq->most_recent_timestamp;
+       activate_task(this_rq, p, 0);
        /*
         * Note that idle threads have a prio of MAX_PRIO, for this test
         * to be always true for them.
         */
-       if (TASK_PREEMPTS_CURR(p, this_rq))
-               resched_task(this_rq->curr);
+       check_preempt_curr(this_rq, p);
 }
 
 /*
@@ -2208,7 +2048,7 @@ static void pull_task(struct rq *src_rq, struct prio_array *src_array,
  */
 static
 int can_migrate_task(struct task_struct *p, struct rq *rq, int this_cpu,
-                    struct sched_domain *sd, enum idle_type idle,
+                    struct sched_domain *sd, enum cpu_idle_type idle,
                     int *all_pinned)
 {
        /*
@@ -2225,132 +2065,67 @@ int can_migrate_task(struct task_struct *p, struct rq *rq, int this_cpu,
                return 0;
 
        /*
-        * Aggressive migration if:
-        * 1) task is cache cold, or
-        * 2) too many balance attempts have failed.
+        * Aggressive migration if too many balance attempts have failed:
         */
-
-       if (sd->nr_balance_failed > sd->cache_nice_tries) {
-#ifdef CONFIG_SCHEDSTATS
-               if (task_hot(p, rq->most_recent_timestamp, sd))
-                       schedstat_inc(sd, lb_hot_gained[idle]);
-#endif
+       if (sd->nr_balance_failed > sd->cache_nice_tries)
                return 1;
-       }
 
-       if (task_hot(p, rq->most_recent_timestamp, sd))
-               return 0;
        return 1;
 }
 
-#define rq_best_prio(rq) min((rq)->curr->prio, (rq)->best_expired_prio)
-
-/*
- * move_tasks tries to move up to max_nr_move tasks and max_load_move weighted
- * load from busiest to this_rq, as part of a balancing operation within
- * "domain". Returns the number of tasks moved.
- *
- * Called with both runqueues locked.
- */
-static int move_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest,
+static int balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest,
                      unsigned long max_nr_move, unsigned long max_load_move,
-                     struct sched_domain *sd, enum idle_type idle,
-                     int *all_pinned)
+                     struct sched_domain *sd, enum cpu_idle_type idle,
+                     int *all_pinned, unsigned long *load_moved,
+                     int this_best_prio, int best_prio, int best_prio_seen,
+                     struct rq_iterator *iterator)
 {
-       int idx, pulled = 0, pinned = 0, this_best_prio, best_prio,
-           best_prio_seen, skip_for_load;
-       struct prio_array *array, *dst_array;
-       struct list_head *head, *curr;
-       struct task_struct *tmp;
-       long rem_load_move;
+       int pulled = 0, pinned = 0, skip_for_load;
+       struct task_struct *p;
+       long rem_load_move = max_load_move;
 
        if (max_nr_move == 0 || max_load_move == 0)
                goto out;
 
-       rem_load_move = max_load_move;
        pinned = 1;
-       this_best_prio = rq_best_prio(this_rq);
-       best_prio = rq_best_prio(busiest);
-       /*
-        * Enable handling of the case where there is more than one task
-        * with the best priority.   If the current running task is one
-        * of those with prio==best_prio we know it won't be moved
-        * and therefore it's safe to override the skip (based on load) of
-        * any task we find with that prio.
-        */
-       best_prio_seen = best_prio == busiest->curr->prio;
 
        /*
-        * We first consider expired tasks. Those will likely not be
-        * executed in the near future, and they are most likely to
-        * be cache-cold, thus switching CPUs has the least effect
-        * on them.
+        * Start the load-balancing iterator:
         */
-       if (busiest->expired->nr_active) {
-               array = busiest->expired;
-               dst_array = this_rq->expired;
-       } else {
-               array = busiest->active;
-               dst_array = this_rq->active;
-       }
-
-new_array:
-       /* Start searching at priority 0: */
-       idx = 0;
-skip_bitmap:
-       if (!idx)
-               idx = sched_find_first_bit(array->bitmap);
-       else
-               idx = find_next_bit(array->bitmap, MAX_PRIO, idx);
-       if (idx >= MAX_PRIO) {
-               if (array == busiest->expired && busiest->active->nr_active) {
-                       array = busiest->active;
-                       dst_array = this_rq->active;
-                       goto new_array;
-               }
+       p = iterator->start(iterator->arg);
+next:
+       if (!p)
                goto out;
-       }
-
-       head = array->queue + idx;
-       curr = head->prev;
-skip_queue:
-       tmp = list_entry(curr, struct task_struct, run_list);
-
-       curr = curr->prev;
-
        /*
         * To help distribute high priority tasks accross CPUs we don't
         * skip a task if it will be the highest priority task (i.e. smallest
         * prio value) on its new queue regardless of its load weight
         */
-       skip_for_load = tmp->load_weight > rem_load_move;
-       if (skip_for_load && idx < this_best_prio)
-               skip_for_load = !best_prio_seen && idx == best_prio;
+       skip_for_load = (p->se.load.weight >> 1) > rem_load_move +
+                                                        SCHED_LOAD_SCALE_FUZZ;
+       if (skip_for_load && p->prio < this_best_prio)
+               skip_for_load = !best_prio_seen && p->prio == best_prio;
        if (skip_for_load ||
-           !can_migrate_task(tmp, busiest, this_cpu, sd, idle, &pinned)) {
+           !can_migrate_task(p, busiest, this_cpu, sd, idle, &pinned)) {
 
-               best_prio_seen |= idx == best_prio;
-               if (curr != head)
-                       goto skip_queue;
-               idx++;
-               goto skip_bitmap;
+               best_prio_seen |= p->prio == best_prio;
+               p = iterator->next(iterator->arg);
+               goto next;
        }
 
-       pull_task(busiest, array, tmp, this_rq, dst_array, this_cpu);
+       pull_task(busiest, p, this_rq, this_cpu);
        pulled++;
-       rem_load_move -= tmp->load_weight;
+       rem_load_move -= p->se.load.weight;
 
        /*
         * We only want to steal up to the prescribed number of tasks
         * and the prescribed amount of weighted load.
         */
        if (pulled < max_nr_move && rem_load_move > 0) {
-               if (idx < this_best_prio)
-                       this_best_prio = idx;
-               if (curr != head)
-                       goto skip_queue;
-               idx++;
-               goto skip_bitmap;
+               if (p->prio < this_best_prio)
+                       this_best_prio = p->prio;
+               p = iterator->next(iterator->arg);
+               goto next;
        }
 out:
        /*
@@ -2362,9 +2137,39 @@ out:
 
        if (all_pinned)
                *all_pinned = pinned;
+       *load_moved = max_load_move - rem_load_move;
        return pulled;
 }
 
+/*
+ * move_tasks tries to move up to max_nr_move tasks and max_load_move weighted
+ * load from busiest to this_rq, as part of a balancing operation within
+ * "domain". Returns the number of tasks moved.
+ *
+ * Called with both runqueues locked.
+ */
+static int move_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest,
+                     unsigned long max_nr_move, unsigned long max_load_move,
+                     struct sched_domain *sd, enum cpu_idle_type idle,
+                     int *all_pinned)
+{
+       struct sched_class *class = sched_class_highest;
+       unsigned long load_moved, total_nr_moved = 0, nr_moved;
+       long rem_load_move = max_load_move;
+
+       do {
+               nr_moved = class->load_balance(this_rq, this_cpu, busiest,
+                               max_nr_move, (unsigned long)rem_load_move,
+                               sd, idle, all_pinned, &load_moved);
+               total_nr_moved += nr_moved;
+               max_nr_move -= nr_moved;
+               rem_load_move -= load_moved;
+               class = class->next;
+       } while (class && max_nr_move && rem_load_move > 0);
+
+       return total_nr_moved;
+}
+
 /*
  * find_busiest_group finds and returns the busiest CPU group within the
  * domain. It calculates and returns the amount of weighted load which
@@ -2372,8 +2177,8 @@ out:
  */
 static struct sched_group *
 find_busiest_group(struct sched_domain *sd, int this_cpu,
-                  unsigned long *imbalance, enum idle_type idle, int *sd_idle,
-                  cpumask_t *cpus, int *balance)
+                  unsigned long *imbalance, enum cpu_idle_type idle,
+                  int *sd_idle, cpumask_t *cpus, int *balance)
 {
        struct sched_group *busiest = NULL, *this = NULL, *group = sd->groups;
        unsigned long max_load, avg_load, total_load, this_load, total_pwr;
@@ -2391,9 +2196,9 @@ find_busiest_group(struct sched_domain *sd, int this_cpu,
        max_load = this_load = total_load = total_pwr = 0;
        busiest_load_per_task = busiest_nr_running = 0;
        this_load_per_task = this_nr_running = 0;
-       if (idle == NOT_IDLE)
+       if (idle == CPU_NOT_IDLE)
                load_idx = sd->busy_idx;
-       else if (idle == NEWLY_IDLE)
+       else if (idle == CPU_NEWLY_IDLE)
                load_idx = sd->newidle_idx;
        else
                load_idx = sd->idle_idx;
@@ -2437,7 +2242,7 @@ find_busiest_group(struct sched_domain *sd, int this_cpu,
 
                        avg_load += load;
                        sum_nr_running += rq->nr_running;
-                       sum_weighted_load += rq->raw_weighted_load;
+                       sum_weighted_load += weighted_cpuload(i);
                }
 
                /*
@@ -2477,8 +2282,9 @@ find_busiest_group(struct sched_domain *sd, int this_cpu,
                 * Busy processors will not participate in power savings
                 * balance.
                 */
-               if (idle == NOT_IDLE || !(sd->flags & SD_POWERSAVINGS_BALANCE))
-                       goto group_next;
+               if (idle == CPU_NOT_IDLE ||
+                               !(sd->flags & SD_POWERSAVINGS_BALANCE))
+                       goto group_next;
 
                /*
                 * If the local group is idle or completely loaded
@@ -2488,42 +2294,42 @@ find_busiest_group(struct sched_domain *sd, int this_cpu,
                                    !this_nr_running))
                        power_savings_balance = 0;
 
-               /*
+               /*
                 * If a group is already running at full capacity or idle,
                 * don't include that group in power savings calculations
-                */
-               if (!power_savings_balance || sum_nr_running >= group_capacity
+                */
+               if (!power_savings_balance || sum_nr_running >= group_capacity
                    || !sum_nr_running)
-                       goto group_next;
+                       goto group_next;
 
-               /*
+               /*
                 * Calculate the group which has the least non-idle load.
-                * This is the group from where we need to pick up the load
-                * for saving power
-                */
-               if ((sum_nr_running < min_nr_running) ||
-                   (sum_nr_running == min_nr_running &&
+                * This is the group from where we need to pick up the load
+                * for saving power
+                */
+               if ((sum_nr_running < min_nr_running) ||
+                   (sum_nr_running == min_nr_running &&
                     first_cpu(group->cpumask) <
                     first_cpu(group_min->cpumask))) {
-                       group_min = group;
-                       min_nr_running = sum_nr_running;
+                       group_min = group;
+                       min_nr_running = sum_nr_running;
                        min_load_per_task = sum_weighted_load /
                                                sum_nr_running;
-               }
+               }
 
-               /*
+               /*
                 * Calculate the group which is almost near its
-                * capacity but still has some space to pick up some load
-                * from other group and save more power
-                */
-               if (sum_nr_running <= group_capacity - 1) {
-                       if (sum_nr_running > leader_nr_running ||
-                           (sum_nr_running == leader_nr_running &&
-                            first_cpu(group->cpumask) >
-                             first_cpu(group_leader->cpumask))) {
-                               group_leader = group;
-                               leader_nr_running = sum_nr_running;
-                       }
+                * capacity but still has some space to pick up some load
+                * from other group and save more power
+                */
+               if (sum_nr_running <= group_capacity - 1) {
+                       if (sum_nr_running > leader_nr_running ||
+                           (sum_nr_running == leader_nr_running &&
+                            first_cpu(group->cpumask) >
+                             first_cpu(group_leader->cpumask))) {
+                               group_leader = group;
+                               leader_nr_running = sum_nr_running;
+                       }
                }
 group_next:
 #endif
@@ -2578,7 +2384,7 @@ group_next:
         * a think about bumping its value to force at least one task to be
         * moved
         */
-       if (*imbalance < busiest_load_per_task) {
+       if (*imbalance + SCHED_LOAD_SCALE_FUZZ < busiest_load_per_task/2) {
                unsigned long tmp, pwr_now, pwr_move;
                unsigned int imbn;
 
@@ -2592,7 +2398,8 @@ small_imbalance:
                } else
                        this_load_per_task = SCHED_LOAD_SCALE;
 
-               if (max_load - this_load >= busiest_load_per_task * imbn) {
+               if (max_load - this_load + SCHED_LOAD_SCALE_FUZZ >=
+                                       busiest_load_per_task * imbn) {
                        *imbalance = busiest_load_per_task;
                        return busiest;
                }
@@ -2639,7 +2446,7 @@ small_imbalance:
 
 out_balanced:
 #if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT)
-       if (idle == NOT_IDLE || !(sd->flags & SD_POWERSAVINGS_BALANCE))
+       if (idle == CPU_NOT_IDLE || !(sd->flags & SD_POWERSAVINGS_BALANCE))
                goto ret;
 
        if (this == group_leader && group_leader != group_min) {
@@ -2656,7 +2463,7 @@ ret:
  * find_busiest_queue - find the busiest runqueue among the cpus in group.
  */
 static struct rq *
-find_busiest_queue(struct sched_group *group, enum idle_type idle,
+find_busiest_queue(struct sched_group *group, enum cpu_idle_type idle,
                   unsigned long imbalance, cpumask_t *cpus)
 {
        struct rq *busiest = NULL, *rq;
@@ -2664,17 +2471,19 @@ find_busiest_queue(struct sched_group *group, enum idle_type idle,
        int i;
 
        for_each_cpu_mask(i, group->cpumask) {
+               unsigned long wl;
 
                if (!cpu_isset(i, *cpus))
                        continue;
 
                rq = cpu_rq(i);
+               wl = weighted_cpuload(i);
 
-               if (rq->nr_running == 1 && rq->raw_weighted_load > imbalance)
+               if (rq->nr_running == 1 && wl > imbalance)
                        continue;
 
-               if (rq->raw_weighted_load > max_load) {
-                       max_load = rq->raw_weighted_load;
+               if (wl > max_load) {
+                       max_load = wl;
                        busiest = rq;
                }
        }
@@ -2698,7 +2507,7 @@ static inline unsigned long minus_1_or_zero(unsigned long n)
  * tasks if there is an imbalance.
  */
 static int load_balance(int this_cpu, struct rq *this_rq,
-                       struct sched_domain *sd, enum idle_type idle,
+                       struct sched_domain *sd, enum cpu_idle_type idle,
                        int *balance)
 {
        int nr_moved, all_pinned = 0, active_balance = 0, sd_idle = 0;
@@ -2711,10 +2520,10 @@ static int load_balance(int this_cpu, struct rq *this_rq,
        /*
         * When power savings policy is enabled for the parent domain, idle
         * sibling can pick up load irrespective of busy siblings. In this case,
-        * let the state of idle sibling percolate up as IDLE, instead of
-        * portraying it as NOT_IDLE.
+        * let the state of idle sibling percolate up as CPU_IDLE, instead of
+        * portraying it as CPU_NOT_IDLE.
         */
-       if (idle != NOT_IDLE && sd->flags & SD_SHARE_CPUPOWER &&
+       if (idle != CPU_NOT_IDLE && sd->flags & SD_SHARE_CPUPOWER &&
            !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE))
                sd_idle = 1;
 
@@ -2848,7 +2657,7 @@ out_one_pinned:
  * Check this_cpu to ensure it is balanced within domain. Attempt to move
  * tasks if there is an imbalance.
  *
- * Called from schedule when this_rq is about to become idle (NEWLY_IDLE).
+ * Called from schedule when this_rq is about to become idle (CPU_NEWLY_IDLE).
  * this_rq is locked.
  */
 static int
@@ -2865,31 +2674,31 @@ load_balance_newidle(int this_cpu, struct rq *this_rq, struct sched_domain *sd)
         * When power savings policy is enabled for the parent domain, idle
         * sibling can pick up load irrespective of busy siblings. In this case,
         * let the state of idle sibling percolate up as IDLE, instead of
-        * portraying it as NOT_IDLE.
+        * portraying it as CPU_NOT_IDLE.
         */
        if (sd->flags & SD_SHARE_CPUPOWER &&
            !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE))
                sd_idle = 1;
 
-       schedstat_inc(sd, lb_cnt[NEWLY_IDLE]);
+       schedstat_inc(sd, lb_cnt[CPU_NEWLY_IDLE]);
 redo:
-       group = find_busiest_group(sd, this_cpu, &imbalance, NEWLY_IDLE,
+       group = find_busiest_group(sd, this_cpu, &imbalance, CPU_NEWLY_IDLE,
                                   &sd_idle, &cpus, NULL);
        if (!group) {
-               schedstat_inc(sd, lb_nobusyg[NEWLY_IDLE]);
+               schedstat_inc(sd, lb_nobusyg[CPU_NEWLY_IDLE]);
                goto out_balanced;
        }
 
-       busiest = find_busiest_queue(group, NEWLY_IDLE, imbalance,
+       busiest = find_busiest_queue(group, CPU_NEWLY_IDLE, imbalance,
                                &cpus);
        if (!busiest) {
-               schedstat_inc(sd, lb_nobusyq[NEWLY_IDLE]);
+               schedstat_inc(sd, lb_nobusyq[CPU_NEWLY_IDLE]);
                goto out_balanced;
        }
 
        BUG_ON(busiest == this_rq);
 
-       schedstat_add(sd, lb_imbalance[NEWLY_IDLE], imbalance);
+       schedstat_add(sd, lb_imbalance[CPU_NEWLY_IDLE], imbalance);
 
        nr_moved = 0;
        if (busiest->nr_running > 1) {
@@ -2897,7 +2706,7 @@ redo:
                double_lock_balance(this_rq, busiest);
                nr_moved = move_tasks(this_rq, this_cpu, busiest,
                                        minus_1_or_zero(busiest->nr_running),
-                                       imbalance, sd, NEWLY_IDLE, NULL);
+                                       imbalance, sd, CPU_NEWLY_IDLE, NULL);
                spin_unlock(&busiest->lock);
 
                if (!nr_moved) {
@@ -2908,7 +2717,7 @@ redo:
        }
 
        if (!nr_moved) {
-               schedstat_inc(sd, lb_failed[NEWLY_IDLE]);
+               schedstat_inc(sd, lb_failed[CPU_NEWLY_IDLE]);
                if (!sd_idle && sd->flags & SD_SHARE_CPUPOWER &&
                    !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE))
                        return -1;
@@ -2918,7 +2727,7 @@ redo:
        return nr_moved;
 
 out_balanced:
-       schedstat_inc(sd, lb_balanced[NEWLY_IDLE]);
+       schedstat_inc(sd, lb_balanced[CPU_NEWLY_IDLE]);
        if (!sd_idle && sd->flags & SD_SHARE_CPUPOWER &&
            !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE))
                return -1;
@@ -2934,8 +2743,8 @@ out_balanced:
 static void idle_balance(int this_cpu, struct rq *this_rq)
 {
        struct sched_domain *sd;
-       int pulled_task = 0;
-       unsigned long next_balance = jiffies + 60 *  HZ;
+       int pulled_task = -1;
+       unsigned long next_balance = jiffies + HZ;
 
        for_each_domain(this_cpu, sd) {
                unsigned long interval;
@@ -2954,12 +2763,13 @@ static void idle_balance(int this_cpu, struct rq *this_rq)
                if (pulled_task)
                        break;
        }
-       if (!pulled_task)
+       if (pulled_task || time_after(jiffies, this_rq->next_balance)) {
                /*
                 * We are going idle. next_balance may be set based on
                 * a busy processor. So reset next_balance.
                 */
                this_rq->next_balance = next_balance;
+       }
 }
 
 /*
@@ -3003,7 +2813,7 @@ static void active_load_balance(struct rq *busiest_rq, int busiest_cpu)
                schedstat_inc(sd, alb_cnt);
 
                if (move_tasks(target_rq, target_cpu, busiest_rq, 1,
-                              RTPRIO_TO_LOAD_WEIGHT(100), sd, SCHED_IDLE,
+                              RTPRIO_TO_LOAD_WEIGHT(100), sd, CPU_IDLE,
                               NULL))
                        schedstat_inc(sd, alb_pushed);
                else
@@ -3012,32 +2822,6 @@ static void active_load_balance(struct rq *busiest_rq, int busiest_cpu)
        spin_unlock(&target_rq->lock);
 }
 
-static void update_load(struct rq *this_rq)
-{
-       unsigned long this_load;
-       unsigned int i, scale;
-
-       this_load = this_rq->raw_weighted_load;
-
-       /* Update our load: */
-       for (i = 0, scale = 1; i < 3; i++, scale += scale) {
-               unsigned long old_load, new_load;
-
-               /* scale is effectively 1 << i now, and >> i divides by scale */
-
-               old_load = this_rq->cpu_load[i];
-               new_load = this_load;
-               /*
-                * Round up the averaging division if load is increasing. This
-                * prevents us from getting stuck on 9 if the load is 10, for
-                * example.
-                */
-               if (new_load > old_load)
-                       new_load += scale-1;
-               this_rq->cpu_load[i] = (old_load*(scale-1) + new_load) >> i;
-       }
-}
-
 #ifdef CONFIG_NO_HZ
 static struct {
        atomic_t load_balancer;
@@ -3120,7 +2904,7 @@ static DEFINE_SPINLOCK(balancing);
  *
  * Balancing parameters are set up in arch_init_sched_domains.
  */
-static inline void rebalance_domains(int cpu, enum idle_type idle)
+static inline void rebalance_domains(int cpu, enum cpu_idle_type idle)
 {
        int balance = 1;
        struct rq *rq = cpu_rq(cpu);
@@ -3134,13 +2918,16 @@ static inline void rebalance_domains(int cpu, enum idle_type idle)
                        continue;
 
                interval = sd->balance_interval;
-               if (idle != SCHED_IDLE)
+               if (idle != CPU_IDLE)
                        interval *= sd->busy_factor;
 
                /* scale ms to jiffies */
                interval = msecs_to_jiffies(interval);
                if (unlikely(!interval))
                        interval = 1;
+               if (interval > HZ*NR_CPUS/10)
+                       interval = HZ*NR_CPUS/10;
+
 
                if (sd->flags & SD_SERIALIZE) {
                        if (!spin_trylock(&balancing))
@@ -3154,7 +2941,7 @@ static inline void rebalance_domains(int cpu, enum idle_type idle)
                                 * longer idle, or one of our SMT siblings is
                                 * not idle.
                                 */
-                               idle = NOT_IDLE;
+                               idle = CPU_NOT_IDLE;
                        }
                        sd->last_balance = jiffies;
                }
@@ -3182,11 +2969,12 @@ out:
  */
 static void run_rebalance_domains(struct softirq_action *h)
 {
-       int local_cpu = smp_processor_id();
-       struct rq *local_rq = cpu_rq(local_cpu);
-       enum idle_type idle = local_rq->idle_at_tick ? SCHED_IDLE : NOT_IDLE;
+       int this_cpu = smp_processor_id();
+       struct rq *this_rq = cpu_rq(this_cpu);
+       enum cpu_idle_type idle = this_rq->idle_at_tick ?
+                                               CPU_IDLE : CPU_NOT_IDLE;
 
-       rebalance_domains(local_cpu, idle);
+       rebalance_domains(this_cpu, idle);
 
 #ifdef CONFIG_NO_HZ
        /*
@@ -3194,13 +2982,13 @@ static void run_rebalance_domains(struct softirq_action *h)
         * balancing on behalf of the other idle cpus whose ticks are
         * stopped.
         */
-       if (local_rq->idle_at_tick &&
-           atomic_read(&nohz.load_balancer) == local_cpu) {
+       if (this_rq->idle_at_tick &&
+           atomic_read(&nohz.load_balancer) == this_cpu) {
                cpumask_t cpus = nohz.cpu_mask;
                struct rq *rq;
                int balance_cpu;
 
-               cpu_clear(local_cpu, cpus);
+               cpu_clear(this_cpu, cpus);
                for_each_cpu_mask(balance_cpu, cpus) {
                        /*
                         * If this cpu gets work to do, stop the load balancing
@@ -3213,8 +3001,8 @@ static void run_rebalance_domains(struct softirq_action *h)
                        rebalance_domains(balance_cpu, SCHED_IDLE);
 
                        rq = cpu_rq(balance_cpu);
-                       if (time_after(local_rq->next_balance, rq->next_balance))
-                               local_rq->next_balance = rq->next_balance;
+                       if (time_after(this_rq->next_balance, rq->next_balance))
+                               this_rq->next_balance = rq->next_balance;
                }
        }
 #endif
@@ -3227,9 +3015,8 @@ static void run_rebalance_domains(struct softirq_action *h)
  * idle load balancing owner or decide to stop the periodic load balancing,
  * if the whole system is idle.
  */
-static inline void trigger_load_balance(int cpu)
+static inline void trigger_load_balance(struct rq *rq, int cpu)
 {
-       struct rq *rq = cpu_rq(cpu);
 #ifdef CONFIG_NO_HZ
        /*
         * If we were in the nohz mode recently and busy at the current
@@ -3281,13 +3068,29 @@ static inline void trigger_load_balance(int cpu)
        if (time_after_eq(jiffies, rq->next_balance))
                raise_softirq(SCHED_SOFTIRQ);
 }
-#else
+
+#else  /* CONFIG_SMP */
+
 /*
  * on UP we do not need to balance between CPUs:
  */
 static inline void idle_balance(int cpu, struct rq *rq)
 {
 }
+
+/* Avoid "used but not defined" warning on UP */
+static int balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest,
+                     unsigned long max_nr_move, unsigned long max_load_move,
+                     struct sched_domain *sd, enum cpu_idle_type idle,
+                     int *all_pinned, unsigned long *load_moved,
+                     int this_best_prio, int best_prio, int best_prio_seen,
+                     struct rq_iterator *iterator)
+{
+       *load_moved = 0;
+
+       return 0;
+}
+
 #endif
 
 DEFINE_PER_CPU(struct kernel_stat, kstat);
@@ -3295,53 +3098,27 @@ DEFINE_PER_CPU(struct kernel_stat, kstat);
 EXPORT_PER_CPU_SYMBOL(kstat);
 
 /*
- * This is called on clock ticks and on context switches.
- * Bank in p->sched_time the ns elapsed since the last tick or switch.
- */
-static inline void
-update_cpu_clock(struct task_struct *p, struct rq *rq, unsigned long long now)
-{
-       p->sched_time += now - p->last_ran;
-       p->last_ran = rq->most_recent_timestamp = now;
-}
-
-/*
- * Return current->sched_time plus any more ns on the sched_clock
- * that have not yet been banked.
+ * Return p->sum_exec_runtime plus any more ns on the sched_clock
+ * that have not yet been banked in case the task is currently running.
  */
-unsigned long long current_sched_time(const struct task_struct *p)
+unsigned long long task_sched_runtime(struct task_struct *p)
 {
-       unsigned long long ns;
        unsigned long flags;
+       u64 ns, delta_exec;
+       struct rq *rq;
 
-       local_irq_save(flags);
-       ns = p->sched_time + sched_clock() - p->last_ran;
-       local_irq_restore(flags);
+       rq = task_rq_lock(p, &flags);
+       ns = p->se.sum_exec_runtime;
+       if (rq->curr == p) {
+               delta_exec = rq_clock(rq) - p->se.exec_start;
+               if ((s64)delta_exec > 0)
+                       ns += delta_exec;
+       }
+       task_rq_unlock(rq, &flags);
 
        return ns;
 }
 
-/*
- * We place interactive tasks back into the active array, if possible.
- *
- * To guarantee that this does not starve expired tasks we ignore the
- * interactivity of a task if the first expired task had to wait more
- * than a 'reasonable' amount of time. This deadline timeout is
- * load-dependent, as the frequency of array switched decreases with
- * increasing number of running tasks. We also ignore the interactivity
- * if a better static_prio task has expired:
- */
-static inline int expired_starving(struct rq *rq)
-{
-       if (rq->curr->static_prio > rq->best_expired_prio)
-               return 1;
-       if (!STARVATION_LIMIT || !rq->expired_timestamp)
-               return 0;
-       if (jiffies - rq->expired_timestamp > STARVATION_LIMIT * rq->nr_running)
-               return 1;
-       return 0;
-}
-
 /*
  * Account user cpu time to a process.
  * @p: the process that the cpu time gets accounted to
@@ -3415,81 +3192,6 @@ void account_steal_time(struct task_struct *p, cputime_t steal)
                cpustat->steal = cputime64_add(cpustat->steal, tmp);
 }
 
-static void task_running_tick(struct rq *rq, struct task_struct *p)
-{
-       if (p->array != rq->active) {
-               /* Task has expired but was not scheduled yet */
-               set_tsk_need_resched(p);
-               return;
-       }
-       spin_lock(&rq->lock);
-       /*
-        * The task was running during this tick - update the
-        * time slice counter. Note: we do not update a thread's
-        * priority until it either goes to sleep or uses up its
-        * timeslice. This makes it possible for interactive tasks
-        * to use up their timeslices at their highest priority levels.
-        */
-       if (rt_task(p)) {
-               /*
-                * RR tasks need a special form of timeslice management.
-                * FIFO tasks have no timeslices.
-                */
-               if ((p->policy == SCHED_RR) && !--p->time_slice) {
-                       p->time_slice = task_timeslice(p);
-                       p->first_time_slice = 0;
-                       set_tsk_need_resched(p);
-
-                       /* put it at the end of the queue: */
-                       requeue_task(p, rq->active);
-               }
-               goto out_unlock;
-       }
-       if (!--p->time_slice) {
-               dequeue_task(p, rq->active);
-               set_tsk_need_resched(p);
-               p->prio = effective_prio(p);
-               p->time_slice = task_timeslice(p);
-               p->first_time_slice = 0;
-
-               if (!rq->expired_timestamp)
-                       rq->expired_timestamp = jiffies;
-               if (!TASK_INTERACTIVE(p) || expired_starving(rq)) {
-                       enqueue_task(p, rq->expired);
-                       if (p->static_prio < rq->best_expired_prio)
-                               rq->best_expired_prio = p->static_prio;
-               } else
-                       enqueue_task(p, rq->active);
-       } else {
-               /*
-                * Prevent a too long timeslice allowing a task to monopolize
-                * the CPU. We do this by splitting up the timeslice into
-                * smaller pieces.
-                *
-                * Note: this does not mean the task's timeslices expire or
-                * get lost in any way, they just might be preempted by
-                * another task of equal priority. (one with higher
-                * priority would have preempted this task already.) We
-                * requeue this task to the end of the list on this priority
-                * level, which is in essence a round-robin of tasks with
-                * equal priority.
-                *
-                * This only applies to tasks in the interactive
-                * delta range with at least TIMESLICE_GRANULARITY to requeue.
-                */
-               if (TASK_INTERACTIVE(p) && !((task_timeslice(p) -
-                       p->time_slice) % TIMESLICE_GRANULARITY(p)) &&
-                       (p->time_slice >= TIMESLICE_GRANULARITY(p)) &&
-                       (p->array == rq->active)) {
-
-                       requeue_task(p, rq->active);
-                       set_tsk_need_resched(p);
-               }
-       }
-out_unlock:
-       spin_unlock(&rq->lock);
-}
-
 /*
  * This function gets called by the timer code, with HZ frequency.
  * We call it with interrupts disabled.
@@ -3499,20 +3201,19 @@ out_unlock:
  */
 void scheduler_tick(void)
 {
-       unsigned long long now = sched_clock();
-       struct task_struct *p = current;
        int cpu = smp_processor_id();
-       int idle_at_tick = idle_cpu(cpu);
        struct rq *rq = cpu_rq(cpu);
+       struct task_struct *curr = rq->curr;
 
-       update_cpu_clock(p, rq, now);
+       spin_lock(&rq->lock);
+       if (curr != rq->idle) /* FIXME: needed? */
+               curr->sched_class->task_tick(rq, curr);
+       update_cpu_load(rq);
+       spin_unlock(&rq->lock);
 
-       if (!idle_at_tick)
-               task_running_tick(rq, p);
 #ifdef CONFIG_SMP
-       update_load(rq);
-       rq->idle_at_tick = idle_at_tick;
-       trigger_load_balance(cpu);
+       rq->idle_at_tick = idle_cpu(cpu);
+       trigger_load_balance(rq, cpu);
 #endif
 }
 
@@ -3554,170 +3255,129 @@ EXPORT_SYMBOL(sub_preempt_count);
 
 #endif
 
-static inline int interactive_sleep(enum sleep_type sleep_type)
+/*
+ * Print scheduling while atomic bug:
+ */
+static noinline void __schedule_bug(struct task_struct *prev)
 {
-       return (sleep_type == SLEEP_INTERACTIVE ||
-               sleep_type == SLEEP_INTERRUPTED);
+       printk(KERN_ERR "BUG: scheduling while atomic: %s/0x%08x/%d\n",
+               prev->comm, preempt_count(), prev->pid);
+       debug_show_held_locks(prev);
+       if (irqs_disabled())
+               print_irqtrace_events(prev);
+       dump_stack();
 }
 
 /*
- * schedule() is the main scheduler function.
+ * Various schedule()-time debugging checks and statistics:
  */
-asmlinkage void __sched schedule(void)
+static inline void schedule_debug(struct task_struct *prev)
 {
-       struct task_struct *prev, *next;
-       struct prio_array *array;
-       struct list_head *queue;
-       unsigned long long now;
-       unsigned long run_time;
-       int cpu, idx, new_prio;
-       long *switch_count;
-       struct rq *rq;
-
        /*
         * Test if we are atomic.  Since do_exit() needs to call into
         * schedule() atomically, we ignore that path for now.
         * Otherwise, whine if we are scheduling when we should not be.
         */
-       if (unlikely(in_atomic() && !current->exit_state)) {
-               printk(KERN_ERR "BUG: scheduling while atomic: "
-                       "%s/0x%08x/%d\n",
-                       current->comm, preempt_count(), current->pid);
-               debug_show_held_locks(current);
-               if (irqs_disabled())
-                       print_irqtrace_events(current);
-               dump_stack();
-       }
-       profile_hit(SCHED_PROFILING, __builtin_return_address(0));
+       if (unlikely(in_atomic_preempt_off()) && unlikely(!prev->exit_state))
+               __schedule_bug(prev);
 
-need_resched:
-       preempt_disable();
-       prev = current;
-       release_kernel_lock(prev);
-need_resched_nonpreemptible:
-       rq = this_rq();
+       profile_hit(SCHED_PROFILING, __builtin_return_address(0));
 
-       /*
-        * The idle thread is not allowed to schedule!
-        * Remove this check after it has been exercised a bit.
-        */
-       if (unlikely(prev == rq->idle) && prev->state != TASK_RUNNING) {
-               printk(KERN_ERR "bad: scheduling from the idle thread!\n");
-               dump_stack();
-       }
+       schedstat_inc(this_rq(), sched_cnt);
+}
 
-       schedstat_inc(rq, sched_cnt);
-       now = sched_clock();
-       if (likely((long long)(now - prev->timestamp) < NS_MAX_SLEEP_AVG)) {
-               run_time = now - prev->timestamp;
-               if (unlikely((long long)(now - prev->timestamp) < 0))
-                       run_time = 0;
-       } else
-               run_time = NS_MAX_SLEEP_AVG;
+/*
+ * Pick up the highest-prio task:
+ */
+static inline struct task_struct *
+pick_next_task(struct rq *rq, struct task_struct *prev, u64 now)
+{
+       struct sched_class *class;
+       struct task_struct *p;
 
        /*
-        * Tasks charged proportionately less run_time at high sleep_avg to
-        * delay them losing their interactive status
+        * Optimization: we know that if all tasks are in
+        * the fair class we can call that function directly:
         */
-       run_time /= (CURRENT_BONUS(prev) ? : 1);
-
-       spin_lock_irq(&rq->lock);
-
-       switch_count = &prev->nivcsw;
-       if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
-               switch_count = &prev->nvcsw;
-               if (unlikely((prev->state & TASK_INTERRUPTIBLE) &&
-                               unlikely(signal_pending(prev))))
-                       prev->state = TASK_RUNNING;
-               else {
-                       if (prev->state == TASK_UNINTERRUPTIBLE)
-                               rq->nr_uninterruptible++;
-                       deactivate_task(prev, rq);
-               }
-       }
-
-       cpu = smp_processor_id();
-       if (unlikely(!rq->nr_running)) {
-               idle_balance(cpu, rq);
-               if (!rq->nr_running) {
-                       next = rq->idle;
-                       rq->expired_timestamp = 0;
-                       goto switch_tasks;
-               }
+       if (likely(rq->nr_running == rq->cfs.nr_running)) {
+               p = fair_sched_class.pick_next_task(rq, now);
+               if (likely(p))
+                       return p;
        }
 
-       array = rq->active;
-       if (unlikely(!array->nr_active)) {
+       class = sched_class_highest;
+       for ( ; ; ) {
+               p = class->pick_next_task(rq, now);
+               if (p)
+                       return p;
                /*
-                * Switch the active and expired arrays.
+                * Will never be NULL as the idle class always
+                * returns a non-NULL p:
                 */
-               schedstat_inc(rq, sched_switch);
-               rq->active = rq->expired;
-               rq->expired = array;
-               array = rq->active;
-               rq->expired_timestamp = 0;
-               rq->best_expired_prio = MAX_PRIO;
+               class = class->next;
        }
+}
+
+/*
+ * schedule() is the main scheduler function.
+ */
+asmlinkage void __sched schedule(void)
+{
+       struct task_struct *prev, *next;
+       long *switch_count;
+       struct rq *rq;
+       u64 now;
+       int cpu;
 
-       idx = sched_find_first_bit(array->bitmap);
-       queue = array->queue + idx;
-       next = list_entry(queue->next, struct task_struct, run_list);
+need_resched:
+       preempt_disable();
+       cpu = smp_processor_id();
+       rq = cpu_rq(cpu);
+       rcu_qsctr_inc(cpu);
+       prev = rq->curr;
+       switch_count = &prev->nivcsw;
 
-       if (!rt_task(next) && interactive_sleep(next->sleep_type)) {
-               unsigned long long delta = now - next->timestamp;
-               if (unlikely((long long)(now - next->timestamp) < 0))
-                       delta = 0;
+       release_kernel_lock(prev);
+need_resched_nonpreemptible:
 
-               if (next->sleep_type == SLEEP_INTERACTIVE)
-                       delta = delta * (ON_RUNQUEUE_WEIGHT * 128 / 100) / 128;
+       schedule_debug(prev);
 
-               array = next->array;
-               new_prio = recalc_task_prio(next, next->timestamp + delta);
+       spin_lock_irq(&rq->lock);
+       clear_tsk_need_resched(prev);
 
-               if (unlikely(next->prio != new_prio)) {
-                       dequeue_task(next, array);
-                       next->prio = new_prio;
-                       enqueue_task(next, array);
+       if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
+               if (unlikely((prev->state & TASK_INTERRUPTIBLE) &&
+                               unlikely(signal_pending(prev)))) {
+                       prev->state = TASK_RUNNING;
+               } else {
+                       deactivate_task(rq, prev, 1);
                }
+               switch_count = &prev->nvcsw;
        }
-       next->sleep_type = SLEEP_NORMAL;
-switch_tasks:
-       if (next == rq->idle)
-               schedstat_inc(rq, sched_goidle);
-       prefetch(next);
-       prefetch_stack(next);
-       clear_tsk_need_resched(prev);
-       rcu_qsctr_inc(task_cpu(prev));
 
-       update_cpu_clock(prev, rq, now);
+       if (unlikely(!rq->nr_running))
+               idle_balance(cpu, rq);
 
-       prev->sleep_avg -= run_time;
-       if ((long)prev->sleep_avg <= 0)
-               prev->sleep_avg = 0;
-       prev->timestamp = prev->last_ran = now;
+       now = __rq_clock(rq);
+       prev->sched_class->put_prev_task(rq, prev, now);
+       next = pick_next_task(rq, prev, now);
 
        sched_info_switch(prev, next);
+
        if (likely(prev != next)) {
-               next->timestamp = next->last_ran = now;
                rq->nr_switches++;
                rq->curr = next;
                ++*switch_count;
 
-               prepare_task_switch(rq, next);
-               prev = context_switch(rq, prev, next);
-               barrier();
-               /*
-                * this_rq must be evaluated again because prev may have moved
-                * CPUs since it called schedule(), thus the 'rq' on its stack
-                * frame will be invalid.
-                */
-               finish_task_switch(this_rq(), prev);
+               context_switch(rq, prev, next); /* unlocks the rq */
        } else
                spin_unlock_irq(&rq->lock);
 
-       prev = current;
-       if (unlikely(reacquire_kernel_lock(prev) < 0))
+       if (unlikely(reacquire_kernel_lock(current) < 0)) {
+               cpu = smp_processor_id();
+               rq = cpu_rq(cpu);
                goto need_resched_nonpreemptible;
+       }
        preempt_enable_no_resched();
        if (unlikely(test_thread_flag(TIF_NEED_RESCHED)))
                goto need_resched;
@@ -4045,74 +3705,85 @@ out:
 }
 EXPORT_SYMBOL(wait_for_completion_interruptible_timeout);
 
-
-#define        SLEEP_ON_VAR                                    \
-       unsigned long flags;                            \
-       wait_queue_t wait;                              \
-       init_waitqueue_entry(&wait, current);
-
-#define SLEEP_ON_HEAD                                  \
-       spin_lock_irqsave(&q->lock,flags);              \
-       __add_wait_queue(q, &wait);                     \
+static inline void
+sleep_on_head(wait_queue_head_t *q, wait_queue_t *wait, unsigned long *flags)
+{
+       spin_lock_irqsave(&q->lock, *flags);
+       __add_wait_queue(q, wait);
        spin_unlock(&q->lock);
+}
 
-#define        SLEEP_ON_TAIL                                   \
-       spin_lock_irq(&q->lock);                        \
-       __remove_wait_queue(q, &wait);                  \
-       spin_unlock_irqrestore(&q->lock, flags);
+static inline void
+sleep_on_tail(wait_queue_head_t *q, wait_queue_t *wait, unsigned long *flags)
+{
+       spin_lock_irq(&q->lock);
+       __remove_wait_queue(q, wait);
+       spin_unlock_irqrestore(&q->lock, *flags);
+}
 
-void fastcall __sched interruptible_sleep_on(wait_queue_head_t *q)
+void __sched interruptible_sleep_on(wait_queue_head_t *q)
 {
-       SLEEP_ON_VAR
+       unsigned long flags;
+       wait_queue_t wait;
+
+       init_waitqueue_entry(&wait, current);
 
        current->state = TASK_INTERRUPTIBLE;
 
-       SLEEP_ON_HEAD
+       sleep_on_head(q, &wait, &flags);
        schedule();
-       SLEEP_ON_TAIL
+       sleep_on_tail(q, &wait, &flags);
 }
 EXPORT_SYMBOL(interruptible_sleep_on);
 
-long fastcall __sched
+long __sched
 interruptible_sleep_on_timeout(wait_queue_head_t *q, long timeout)
 {
-       SLEEP_ON_VAR
+       unsigned long flags;
+       wait_queue_t wait;
+
+       init_waitqueue_entry(&wait, current);
 
        current->state = TASK_INTERRUPTIBLE;
 
-       SLEEP_ON_HEAD
+       sleep_on_head(q, &wait, &flags);
        timeout = schedule_timeout(timeout);
-       SLEEP_ON_TAIL
+       sleep_on_tail(q, &wait, &flags);
 
        return timeout;
 }
 EXPORT_SYMBOL(interruptible_sleep_on_timeout);
 
-void fastcall __sched sleep_on(wait_queue_head_t *q)
+void __sched sleep_on(wait_queue_head_t *q)
 {
-       SLEEP_ON_VAR
+       unsigned long flags;
+       wait_queue_t wait;
+
+       init_waitqueue_entry(&wait, current);
 
        current->state = TASK_UNINTERRUPTIBLE;
 
-       SLEEP_ON_HEAD
+       sleep_on_head(q, &wait, &flags);
        schedule();
-       SLEEP_ON_TAIL
+       sleep_on_tail(q, &wait, &flags);
 }
 EXPORT_SYMBOL(sleep_on);
 
-long fastcall __sched sleep_on_timeout(wait_queue_head_t *q, long timeout)
+long __sched sleep_on_timeout(wait_queue_head_t *q, long timeout)
 {
-       SLEEP_ON_VAR
+       unsigned long flags;
+       wait_queue_t wait;
+
+       init_waitqueue_entry(&wait, current);
 
        current->state = TASK_UNINTERRUPTIBLE;
 
-       SLEEP_ON_HEAD
+       sleep_on_head(q, &wait, &flags);
        timeout = schedule_timeout(timeout);
-       SLEEP_ON_TAIL
+       sleep_on_tail(q, &wait, &flags);
 
        return timeout;
 }
-
 EXPORT_SYMBOL(sleep_on_timeout);
 
 #ifdef CONFIG_RT_MUTEXES
@@ -4129,29 +3800,30 @@ EXPORT_SYMBOL(sleep_on_timeout);
  */
 void rt_mutex_setprio(struct task_struct *p, int prio)
 {
-       struct prio_array *array;
        unsigned long flags;
+       int oldprio, on_rq;
        struct rq *rq;
-       int oldprio;
+       u64 now;
 
        BUG_ON(prio < 0 || prio > MAX_PRIO);
 
        rq = task_rq_lock(p, &flags);
+       now = rq_clock(rq);
 
        oldprio = p->prio;
-       array = p->array;
-       if (array)
-               dequeue_task(p, array);
+       on_rq = p->se.on_rq;
+       if (on_rq)
+               dequeue_task(rq, p, 0, now);
+
+       if (rt_prio(prio))
+               p->sched_class = &rt_sched_class;
+       else
+               p->sched_class = &fair_sched_class;
+
        p->prio = prio;
 
-       if (array) {
-               /*
-                * If changing to an RT priority then queue it
-                * in the active array!
-                */
-               if (rt_task(p))
-                       array = rq->active;
-               enqueue_task(p, array);
+       if (on_rq) {
+               enqueue_task(rq, p, 0, now);
                /*
                 * Reschedule if we are currently running on this runqueue and
                 * our priority decreased, or if we are not currently running on
@@ -4160,8 +3832,9 @@ void rt_mutex_setprio(struct task_struct *p, int prio)
                if (task_running(rq, p)) {
                        if (p->prio > oldprio)
                                resched_task(rq->curr);
-               } else if (TASK_PREEMPTS_CURR(p, rq))
-                       resched_task(rq->curr);
+               } else {
+                       check_preempt_curr(rq, p);
+               }
        }
        task_rq_unlock(rq, &flags);
 }
@@ -4170,10 +3843,10 @@ void rt_mutex_setprio(struct task_struct *p, int prio)
 
 void set_user_nice(struct task_struct *p, long nice)
 {
-       struct prio_array *array;
-       int old_prio, delta;
+       int old_prio, delta, on_rq;
        unsigned long flags;
        struct rq *rq;
+       u64 now;
 
        if (TASK_NICE(p) == nice || nice < -20 || nice > 19)
                return;
@@ -4182,20 +3855,21 @@ void set_user_nice(struct task_struct *p, long nice)
         * the task might be in the middle of scheduling on another CPU.
         */
        rq = task_rq_lock(p, &flags);
+       now = rq_clock(rq);
        /*
         * The RT priorities are set via sched_setscheduler(), but we still
         * allow the 'normal' nice value to be set - but as expected
         * it wont have any effect on scheduling until the task is
-        * not SCHED_NORMAL/SCHED_BATCH:
+        * SCHED_FIFO/SCHED_RR:
         */
-       if (has_rt_policy(p)) {
+       if (task_has_rt_policy(p)) {
                p->static_prio = NICE_TO_PRIO(nice);
                goto out_unlock;
        }
-       array = p->array;
-       if (array) {
-               dequeue_task(p, array);
-               dec_raw_weighted_load(rq, p);
+       on_rq = p->se.on_rq;
+       if (on_rq) {
+               dequeue_task(rq, p, 0, now);
+               dec_load(rq, p, now);
        }
 
        p->static_prio = NICE_TO_PRIO(nice);
@@ -4204,9 +3878,9 @@ void set_user_nice(struct task_struct *p, long nice)
        p->prio = effective_prio(p);
        delta = p->prio - old_prio;
 
-       if (array) {
-               enqueue_task(p, array);
-               inc_raw_weighted_load(rq, p);
+       if (on_rq) {
+               enqueue_task(rq, p, 0, now);
+               inc_load(rq, p, now);
                /*
                 * If the task increased its priority or is running and
                 * lowered its priority, then reschedule its CPU:
@@ -4326,20 +4000,28 @@ static inline struct task_struct *find_process_by_pid(pid_t pid)
 }
 
 /* Actually do priority change: must hold rq lock. */
-static void __setscheduler(struct task_struct *p, int policy, int prio)
+static void
+__setscheduler(struct rq *rq, struct task_struct *p, int policy, int prio)
 {
-       BUG_ON(p->array);
+       BUG_ON(p->se.on_rq);
 
        p->policy = policy;
+       switch (p->policy) {
+       case SCHED_NORMAL:
+       case SCHED_BATCH:
+       case SCHED_IDLE:
+               p->sched_class = &fair_sched_class;
+               break;
+       case SCHED_FIFO:
+       case SCHED_RR:
+               p->sched_class = &rt_sched_class;
+               break;
+       }
+
        p->rt_priority = prio;
        p->normal_prio = normal_prio(p);
        /* we are holding p->pi_lock already */
        p->prio = rt_mutex_getprio(p);
-       /*
-        * SCHED_BATCH tasks are treated as perpetual CPU hogs:
-        */
-       if (policy == SCHED_BATCH)
-               p->sleep_avg = 0;
        set_load_weight(p);
 }
 
@@ -4354,8 +4036,7 @@ static void __setscheduler(struct task_struct *p, int policy, int prio)
 int sched_setscheduler(struct task_struct *p, int policy,
                       struct sched_param *param)
 {
-       int retval, oldprio, oldpolicy = -1;
-       struct prio_array *array;
+       int retval, oldprio, oldpolicy = -1, on_rq;
        unsigned long flags;
        struct rq *rq;
 
@@ -4366,27 +4047,27 @@ recheck:
        if (policy < 0)
                policy = oldpolicy = p->policy;
        else if (policy != SCHED_FIFO && policy != SCHED_RR &&
-                       policy != SCHED_NORMAL && policy != SCHED_BATCH)
+                       policy != SCHED_NORMAL && policy != SCHED_BATCH &&
+                       policy != SCHED_IDLE)
                return -EINVAL;
        /*
         * Valid priorities for SCHED_FIFO and SCHED_RR are
-        * 1..MAX_USER_RT_PRIO-1, valid priority for SCHED_NORMAL and
-        * SCHED_BATCH is 0.
+        * 1..MAX_USER_RT_PRIO-1, valid priority for SCHED_NORMAL,
+        * SCHED_BATCH and SCHED_IDLE is 0.
         */
        if (param->sched_priority < 0 ||
            (p->mm && param->sched_priority > MAX_USER_RT_PRIO-1) ||
            (!p->mm && param->sched_priority > MAX_RT_PRIO-1))
                return -EINVAL;
-       if (is_rt_policy(policy) != (param->sched_priority != 0))
+       if (rt_policy(policy) != (param->sched_priority != 0))
                return -EINVAL;
 
        /*
         * Allow unprivileged RT tasks to decrease priority:
         */
        if (!capable(CAP_SYS_NICE)) {
-               if (is_rt_policy(policy)) {
+               if (rt_policy(policy)) {
                        unsigned long rlim_rtprio;
-                       unsigned long flags;
 
                        if (!lock_task_sighand(p, &flags))
                                return -ESRCH;
@@ -4402,6 +4083,12 @@ recheck:
                            param->sched_priority > rlim_rtprio)
                                return -EPERM;
                }
+               /*
+                * Like positive nice levels, dont allow tasks to
+                * move out of SCHED_IDLE either:
+                */
+               if (p->policy == SCHED_IDLE && policy != SCHED_IDLE)
+                       return -EPERM;
 
                /* can't change other user's priorities */
                if ((current->euid != p->euid) &&
@@ -4429,13 +4116,13 @@ recheck:
                spin_unlock_irqrestore(&p->pi_lock, flags);
                goto recheck;
        }
-       array = p->array;
-       if (array)
-               deactivate_task(p, rq);
+       on_rq = p->se.on_rq;
+       if (on_rq)
+               deactivate_task(rq, p, 0);
        oldprio = p->prio;
-       __setscheduler(p, policy, param->sched_priority);
-       if (array) {
-               __activate_task(p, rq);
+       __setscheduler(rq, p, policy, param->sched_priority);
+       if (on_rq) {
+               activate_task(rq, p, 0);
                /*
                 * Reschedule if we are currently running on this runqueue and
                 * our priority decreased, or if we are not currently running on
@@ -4444,8 +4131,9 @@ recheck:
                if (task_running(rq, p)) {
                        if (p->prio > oldprio)
                                resched_task(rq->curr);
-               } else if (TASK_PREEMPTS_CURR(p, rq))
-                       resched_task(rq->curr);
+               } else {
+                       check_preempt_curr(rq, p);
+               }
        }
        __task_rq_unlock(rq);
        spin_unlock_irqrestore(&p->pi_lock, flags);
@@ -4717,41 +4405,18 @@ asmlinkage long sys_sched_getaffinity(pid_t pid, unsigned int len,
 /**
  * sys_sched_yield - yield the current processor to other threads.
  *
- * This function yields the current CPU by moving the calling thread
- * to the expired array. If there are no other threads running on this
- * CPU then this function will return.
+ * This function yields the current CPU to other tasks. If there are no
+ * other threads running on this CPU then this function will return.
  */
 asmlinkage long sys_sched_yield(void)
 {
        struct rq *rq = this_rq_lock();
-       struct prio_array *array = current->array, *target = rq->expired;
 
        schedstat_inc(rq, yld_cnt);
-       /*
-        * We implement yielding by moving the task into the expired
-        * queue.
-        *
-        * (special rule: RT tasks will just roundrobin in the active
-        *  array.)
-        */
-       if (rt_task(current))
-               target = rq->active;
-
-       if (array->nr_active == 1) {
+       if (unlikely(rq->nr_running == 1))
                schedstat_inc(rq, yld_act_empty);
-               if (!rq->expired->nr_active)
-                       schedstat_inc(rq, yld_both_empty);
-       } else if (!rq->expired->nr_active)
-               schedstat_inc(rq, yld_exp_empty);
-
-       if (array != target) {
-               dequeue_task(current, array);
-               enqueue_task(current, target);
-       } else
-               /*
-                * requeue_task is cheaper so perform that if possible.
-                */
-               requeue_task(current, array);
+       else
+               current->sched_class->yield_task(rq, current);
 
        /*
         * Since we are going to call schedule() anyway, there's
@@ -4902,6 +4567,7 @@ asmlinkage long sys_sched_get_priority_max(int policy)
                break;
        case SCHED_NORMAL:
        case SCHED_BATCH:
+       case SCHED_IDLE:
                ret = 0;
                break;
        }
@@ -4926,6 +4592,7 @@ asmlinkage long sys_sched_get_priority_min(int policy)
                break;
        case SCHED_NORMAL:
        case SCHED_BATCH:
+       case SCHED_IDLE:
                ret = 0;
        }
        return ret;
@@ -4960,7 +4627,7 @@ long sys_sched_rr_get_interval(pid_t pid, struct timespec __user *interval)
                goto out_unlock;
 
        jiffies_to_timespec(p->policy == SCHED_FIFO ?
-                               0 : task_timeslice(p), &t);
+                               0 : static_prio_timeslice(p->static_prio), &t);
        read_unlock(&tasklist_lock);
        retval = copy_to_user(interval, &t, sizeof(t)) ? -EFAULT : 0;
 out_nounlock:
@@ -4980,14 +4647,14 @@ static void show_task(struct task_struct *p)
        state = p->state ? __ffs(p->state) + 1 : 0;
        printk("%-13.13s %c", p->comm,
                state < sizeof(stat_nam) - 1 ? stat_nam[state] : '?');
-#if (BITS_PER_LONG == 32)
+#if BITS_PER_LONG == 32
        if (state == TASK_RUNNING)
-               printk(" running ");
+               printk(" running  ");
        else
-               printk(" %08lX ", thread_saved_pc(p));
+               printk(" %08lx ", thread_saved_pc(p));
 #else
        if (state == TASK_RUNNING)
-               printk("  running task   ");
+               printk("  running task    ");
        else
                printk(" %016lx ", thread_saved_pc(p));
 #endif
@@ -4999,11 +4666,7 @@ static void show_task(struct task_struct *p)
                free = (unsigned long)n - (unsigned long)end_of_stack(p);
        }
 #endif
-       printk("%5lu %5d %6d", free, p->pid, p->parent->pid);
-       if (!p->mm)
-               printk(" (L-TLB)\n");
-       else
-               printk(" (NOTLB)\n");
+       printk("%5lu %5d %6d\n", free, p->pid, p->parent->pid);
 
        if (state != TASK_RUNNING)
                show_stack(p, NULL);
@@ -5013,14 +4676,12 @@ void show_state_filter(unsigned long state_filter)
 {
        struct task_struct *g, *p;
 
-#if (BITS_PER_LONG == 32)
-       printk("\n"
-              "                         free                        sibling\n");
-       printk("  task             PC    stack   pid father child younger older\n");
+#if BITS_PER_LONG == 32
+       printk(KERN_INFO
+               "  task                PC stack   pid father\n");
 #else
-       printk("\n"
-              "                                 free                        sibling\n");
-       printk("  task                 PC        stack   pid father child younger older\n");
+       printk(KERN_INFO
+               "  task                        PC stack   pid father\n");
 #endif
        read_lock(&tasklist_lock);
        do_each_thread(g, p) {
@@ -5035,6 +4696,9 @@ void show_state_filter(unsigned long state_filter)
 
        touch_all_softlockup_watchdogs();
 
+#ifdef CONFIG_SCHED_DEBUG
+       sysrq_sched_debug_show();
+#endif
        read_unlock(&tasklist_lock);
        /*
         * Only show locks if all tasks are dumped:
@@ -5043,6 +4707,11 @@ void show_state_filter(unsigned long state_filter)
                debug_show_all_locks();
 }
 
+void __cpuinit init_idle_bootup_task(struct task_struct *idle)
+{
+       idle->sched_class = &idle_sched_class;
+}
+
 /**
  * init_idle - set up an idle thread for a given CPU
  * @idle: task in question
@@ -5056,13 +4725,12 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu)
        struct rq *rq = cpu_rq(cpu);
        unsigned long flags;
 
-       idle->timestamp = sched_clock();
-       idle->sleep_avg = 0;
-       idle->array = NULL;
+       __sched_fork(idle);
+       idle->se.exec_start = sched_clock();
+
        idle->prio = idle->normal_prio = MAX_PRIO;
-       idle->state = TASK_RUNNING;
        idle->cpus_allowed = cpumask_of_cpu(cpu);
-       set_task_cpu(idle, cpu);
+       __set_task_cpu(idle, cpu);
 
        spin_lock_irqsave(&rq->lock, flags);
        rq->curr = rq->idle = idle;
@@ -5077,6 +4745,10 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu)
 #else
        task_thread_info(idle)->preempt_count = 0;
 #endif
+       /*
+        * The idle tasks have their own, simple scheduling class:
+        */
+       idle->sched_class = &idle_sched_class;
 }
 
 /*
@@ -5088,6 +4760,28 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu)
  */
 cpumask_t nohz_cpu_mask = CPU_MASK_NONE;
 
+/*
+ * Increase the granularity value when there are more CPUs,
+ * because with more CPUs the 'effective latency' as visible
+ * to users decreases. But the relationship is not linear,
+ * so pick a second-best guess by going with the log2 of the
+ * number of CPUs.
+ *
+ * This idea comes from the SD scheduler of Con Kolivas:
+ */
+static inline void sched_init_granularity(void)
+{
+       unsigned int factor = 1 + ilog2(num_online_cpus());
+       const unsigned long gran_limit = 100000000;
+
+       sysctl_sched_granularity *= factor;
+       if (sysctl_sched_granularity > gran_limit)
+               sysctl_sched_granularity = gran_limit;
+
+       sysctl_sched_runtime_limit = sysctl_sched_granularity * 4;
+       sysctl_sched_wakeup_granularity = sysctl_sched_granularity / 2;
+}
+
 #ifdef CONFIG_SMP
 /*
  * This is how migration works:
@@ -5161,7 +4855,7 @@ EXPORT_SYMBOL_GPL(set_cpus_allowed);
 static int __migrate_task(struct task_struct *p, int src_cpu, int dest_cpu)
 {
        struct rq *rq_dest, *rq_src;
-       int ret = 0;
+       int ret = 0, on_rq;
 
        if (unlikely(cpu_is_offline(dest_cpu)))
                return ret;
@@ -5177,20 +4871,13 @@ static int __migrate_task(struct task_struct *p, int src_cpu, int dest_cpu)
        if (!cpu_isset(dest_cpu, p->cpus_allowed))
                goto out;
 
+       on_rq = p->se.on_rq;
+       if (on_rq)
+               deactivate_task(rq_src, p, 0);
        set_task_cpu(p, dest_cpu);
-       if (p->array) {
-               /*
-                * Sync timestamp with rq_dest's before activating.
-                * The same thing could be achieved by doing this step
-                * afterwards, and pretending it was a local activate.
-                * This way is cleaner and logically correct.
-                */
-               p->timestamp = p->timestamp - rq_src->most_recent_timestamp
-                               + rq_dest->most_recent_timestamp;
-               deactivate_task(p, rq_src);
-               __activate_task(p, rq_dest);
-               if (TASK_PREEMPTS_CURR(p, rq_dest))
-                       resched_task(rq_dest->curr);
+       if (on_rq) {
+               activate_task(rq_dest, p, 0);
+               check_preempt_curr(rq_dest, p);
        }
        ret = 1;
 out:
@@ -5342,7 +5029,8 @@ static void migrate_live_tasks(int src_cpu)
        write_unlock_irq(&tasklist_lock);
 }
 
-/* Schedules idle task to be the next runnable task on current CPU.
+/*
+ * Schedules idle task to be the next runnable task on current CPU.
  * It does so by boosting its priority to highest possible and adding it to
  * the _front_ of the runqueue. Used by CPU offline code.
  */
@@ -5362,10 +5050,10 @@ void sched_idle_next(void)
         */
        spin_lock_irqsave(&rq->lock, flags);
 
-       __setscheduler(p, SCHED_FIFO, MAX_RT_PRIO-1);
+       __setscheduler(rq, p, SCHED_FIFO, MAX_RT_PRIO-1);
 
        /* Add idle task to the _front_ of its priority queue: */
-       __activate_idle_task(p, rq);
+       activate_idle_task(p, rq);
 
        spin_unlock_irqrestore(&rq->lock, flags);
 }
@@ -5415,16 +5103,15 @@ static void migrate_dead(unsigned int dead_cpu, struct task_struct *p)
 static void migrate_dead_tasks(unsigned int dead_cpu)
 {
        struct rq *rq = cpu_rq(dead_cpu);
-       unsigned int arr, i;
+       struct task_struct *next;
 
-       for (arr = 0; arr < 2; arr++) {
-               for (i = 0; i < MAX_PRIO; i++) {
-                       struct list_head *list = &rq->arrays[arr].queue[i];
-
-                       while (!list_empty(list))
-                               migrate_dead(dead_cpu, list_entry(list->next,
-                                            struct task_struct, run_list));
-               }
+       for ( ; ; ) {
+               if (!rq->nr_running)
+                       break;
+               next = pick_next_task(rq, rq->curr, rq_clock(rq));
+               if (!next)
+                       break;
+               migrate_dead(dead_cpu, next);
        }
 }
 #endif /* CONFIG_HOTPLUG_CPU */
@@ -5448,14 +5135,14 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)
 
        case CPU_UP_PREPARE:
        case CPU_UP_PREPARE_FROZEN:
-               p = kthread_create(migration_thread, hcpu, "migration/%d",cpu);
+               p = kthread_create(migration_thread, hcpu, "migration/%d", cpu);
                if (IS_ERR(p))
                        return NOTIFY_BAD;
                p->flags |= PF_NOFREEZE;
                kthread_bind(p, cpu);
                /* Must be high prio: stop_machine expects to yield to it. */
                rq = task_rq_lock(p, &flags);
-               __setscheduler(p, SCHED_FIFO, MAX_RT_PRIO-1);
+               __setscheduler(rq, p, SCHED_FIFO, MAX_RT_PRIO-1);
                task_rq_unlock(rq, &flags);
                cpu_rq(cpu)->migration_thread = p;
                break;
@@ -5486,9 +5173,10 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)
                rq->migration_thread = NULL;
                /* Idle task back to normal (off runqueue, low prio) */
                rq = task_rq_lock(rq->idle, &flags);
-               deactivate_task(rq->idle, rq);
+               deactivate_task(rq, rq->idle, 0);
                rq->idle->static_prio = MAX_PRIO;
-               __setscheduler(rq->idle, SCHED_NORMAL, 0);
+               __setscheduler(rq, rq->idle, SCHED_NORMAL, 0);
+               rq->idle->sched_class = &idle_sched_class;
                migrate_dead_tasks(cpu);
                task_rq_unlock(rq, &flags);
                migrate_nr_uninterruptible(rq);
@@ -5797,483 +5485,6 @@ init_sched_build_groups(cpumask_t span, const cpumask_t *cpu_map,
 
 #define SD_NODES_PER_DOMAIN 16
 
-/*
- * Self-tuning task migration cost measurement between source and target CPUs.
- *
- * This is done by measuring the cost of manipulating buffers of varying
- * sizes. For a given buffer-size here are the steps that are taken:
- *
- * 1) the source CPU reads+dirties a shared buffer
- * 2) the target CPU reads+dirties the same shared buffer
- *
- * We measure how long they take, in the following 4 scenarios:
- *
- *  - source: CPU1, target: CPU2 | cost1
- *  - source: CPU2, target: CPU1 | cost2
- *  - source: CPU1, target: CPU1 | cost3
- *  - source: CPU2, target: CPU2 | cost4
- *
- * We then calculate the cost3+cost4-cost1-cost2 difference - this is
- * the cost of migration.
- *
- * We then start off from a small buffer-size and iterate up to larger
- * buffer sizes, in 5% steps - measuring each buffer-size separately, and
- * doing a maximum search for the cost. (The maximum cost for a migration
- * normally occurs when the working set size is around the effective cache
- * size.)
- */
-#define SEARCH_SCOPE           2
-#define MIN_CACHE_SIZE         (64*1024U)
-#define DEFAULT_CACHE_SIZE     (5*1024*1024U)
-#define ITERATIONS             1
-#define SIZE_THRESH            130
-#define COST_THRESH            130
-
-/*
- * The migration cost is a function of 'domain distance'. Domain
- * distance is the number of steps a CPU has to iterate down its
- * domain tree to share a domain with the other CPU. The farther
- * two CPUs are from each other, the larger the distance gets.
- *
- * Note that we use the distance only to cache measurement results,
- * the distance value is not used numerically otherwise. When two
- * CPUs have the same distance it is assumed that the migration
- * cost is the same. (this is a simplification but quite practical)
- */
-#define MAX_DOMAIN_DISTANCE 32
-
-static unsigned long long migration_cost[MAX_DOMAIN_DISTANCE] =
-               { [ 0 ... MAX_DOMAIN_DISTANCE-1 ] =
-/*
- * Architectures may override the migration cost and thus avoid
- * boot-time calibration. Unit is nanoseconds. Mostly useful for
- * virtualized hardware:
- */
-#ifdef CONFIG_DEFAULT_MIGRATION_COST
-                       CONFIG_DEFAULT_MIGRATION_COST
-#else
-                       -1LL
-#endif
-};
-
-/*
- * Allow override of migration cost - in units of microseconds.
- * E.g. migration_cost=1000,2000,3000 will set up a level-1 cost
- * of 1 msec, level-2 cost of 2 msecs and level3 cost of 3 msecs:
- */
-static int __init migration_cost_setup(char *str)
-{
-       int ints[MAX_DOMAIN_DISTANCE+1], i;
-
-       str = get_options(str, ARRAY_SIZE(ints), ints);
-
-       printk("#ints: %d\n", ints[0]);
-       for (i = 1; i <= ints[0]; i++) {
-               migration_cost[i-1] = (unsigned long long)ints[i]*1000;
-               printk("migration_cost[%d]: %Ld\n", i-1, migration_cost[i-1]);
-       }
-       return 1;
-}
-
-__setup ("migration_cost=", migration_cost_setup);
-
-/*
- * Global multiplier (divisor) for migration-cutoff values,
- * in percentiles. E.g. use a value of 150 to get 1.5 times
- * longer cache-hot cutoff times.
- *
- * (We scale it from 100 to 128 to long long handling easier.)
- */
-
-#define MIGRATION_FACTOR_SCALE 128
-
-static unsigned int migration_factor = MIGRATION_FACTOR_SCALE;
-
-static int __init setup_migration_factor(char *str)
-{
-       get_option(&str, &migration_factor);
-       migration_factor = migration_factor * MIGRATION_FACTOR_SCALE / 100;
-       return 1;
-}
-
-__setup("migration_factor=", setup_migration_factor);
-
-/*
- * Estimated distance of two CPUs, measured via the number of domains
- * we have to pass for the two CPUs to be in the same span:
- */
-static unsigned long domain_distance(int cpu1, int cpu2)
-{
-       unsigned long distance = 0;
-       struct sched_domain *sd;
-
-       for_each_domain(cpu1, sd) {
-               WARN_ON(!cpu_isset(cpu1, sd->span));
-               if (cpu_isset(cpu2, sd->span))
-                       return distance;
-               distance++;
-       }
-       if (distance >= MAX_DOMAIN_DISTANCE) {
-               WARN_ON(1);
-               distance = MAX_DOMAIN_DISTANCE-1;
-       }
-
-       return distance;
-}
-
-static unsigned int migration_debug;
-
-static int __init setup_migration_debug(char *str)
-{
-       get_option(&str, &migration_debug);
-       return 1;
-}
-
-__setup("migration_debug=", setup_migration_debug);
-
-/*
- * Maximum cache-size that the scheduler should try to measure.
- * Architectures with larger caches should tune this up during
- * bootup. Gets used in the domain-setup code (i.e. during SMP
- * bootup).
- */
-unsigned int max_cache_size;
-
-static int __init setup_max_cache_size(char *str)
-{
-       get_option(&str, &max_cache_size);
-       return 1;
-}
-
-__setup("max_cache_size=", setup_max_cache_size);
-
-/*
- * Dirty a big buffer in a hard-to-predict (for the L2 cache) way. This
- * is the operation that is timed, so we try to generate unpredictable
- * cachemisses that still end up filling the L2 cache:
- */
-static void touch_cache(void *__cache, unsigned long __size)
-{
-       unsigned long size = __size / sizeof(long);
-       unsigned long chunk1 = size / 3;
-       unsigned long chunk2 = 2 * size / 3;
-       unsigned long *cache = __cache;
-       int i;
-
-       for (i = 0; i < size/6; i += 8) {
-               switch (i % 6) {
-                       case 0: cache[i]++;
-                       case 1: cache[size-1-i]++;
-                       case 2: cache[chunk1-i]++;
-                       case 3: cache[chunk1+i]++;
-                       case 4: cache[chunk2-i]++;
-                       case 5: cache[chunk2+i]++;
-               }
-       }
-}
-
-/*
- * Measure the cache-cost of one task migration. Returns in units of nsec.
- */
-static unsigned long long
-measure_one(void *cache, unsigned long size, int source, int target)
-{
-       cpumask_t mask, saved_mask;
-       unsigned long long t0, t1, t2, t3, cost;
-
-       saved_mask = current->cpus_allowed;
-
-       /*
-        * Flush source caches to RAM and invalidate them:
-        */
-       sched_cacheflush();
-
-       /*
-        * Migrate to the source CPU:
-        */
-       mask = cpumask_of_cpu(source);
-       set_cpus_allowed(current, mask);
-       WARN_ON(smp_processor_id() != source);
-
-       /*
-        * Dirty the working set:
-        */
-       t0 = sched_clock();
-       touch_cache(cache, size);
-       t1 = sched_clock();
-
-       /*
-        * Migrate to the target CPU, dirty the L2 cache and access
-        * the shared buffer. (which represents the working set
-        * of a migrated task.)
-        */
-       mask = cpumask_of_cpu(target);
-       set_cpus_allowed(current, mask);
-       WARN_ON(smp_processor_id() != target);
-
-       t2 = sched_clock();
-       touch_cache(cache, size);
-       t3 = sched_clock();
-
-       cost = t1-t0 + t3-t2;
-
-       if (migration_debug >= 2)
-               printk("[%d->%d]: %8Ld %8Ld %8Ld => %10Ld.\n",
-                       source, target, t1-t0, t1-t0, t3-t2, cost);
-       /*
-        * Flush target caches to RAM and invalidate them:
-        */
-       sched_cacheflush();
-
-       set_cpus_allowed(current, saved_mask);
-
-       return cost;
-}
-
-/*
- * Measure a series of task migrations and return the average
- * result. Since this code runs early during bootup the system
- * is 'undisturbed' and the average latency makes sense.
- *
- * The algorithm in essence auto-detects the relevant cache-size,
- * so it will properly detect different cachesizes for different
- * cache-hierarchies, depending on how the CPUs are connected.
- *
- * Architectures can prime the upper limit of the search range via
- * max_cache_size, otherwise the search range defaults to 20MB...64K.
- */
-static unsigned long long
-measure_cost(int cpu1, int cpu2, void *cache, unsigned int size)
-{
-       unsigned long long cost1, cost2;
-       int i;
-
-       /*
-        * Measure the migration cost of 'size' bytes, over an
-        * average of 10 runs:
-        *
-        * (We perturb the cache size by a small (0..4k)
-        *  value to compensate size/alignment related artifacts.
-        *  We also subtract the cost of the operation done on
-        *  the same CPU.)
-        */
-       cost1 = 0;
-
-       /*
-        * dry run, to make sure we start off cache-cold on cpu1,
-        * and to get any vmalloc pagefaults in advance:
-        */
-       measure_one(cache, size, cpu1, cpu2);
-       for (i = 0; i < ITERATIONS; i++)
-               cost1 += measure_one(cache, size - i * 1024, cpu1, cpu2);
-
-       measure_one(cache, size, cpu2, cpu1);
-       for (i = 0; i < ITERATIONS; i++)
-               cost1 += measure_one(cache, size - i * 1024, cpu2, cpu1);
-
-       /*
-        * (We measure the non-migrating [cached] cost on both
-        *  cpu1 and cpu2, to handle CPUs with different speeds)
-        */
-       cost2 = 0;
-
-       measure_one(cache, size, cpu1, cpu1);
-       for (i = 0; i < ITERATIONS; i++)
-               cost2 += measure_one(cache, size - i * 1024, cpu1, cpu1);
-
-       measure_one(cache, size, cpu2, cpu2);
-       for (i = 0; i < ITERATIONS; i++)
-               cost2 += measure_one(cache, size - i * 1024, cpu2, cpu2);
-
-       /*
-        * Get the per-iteration migration cost:
-        */
-       do_div(cost1, 2 * ITERATIONS);
-       do_div(cost2, 2 * ITERATIONS);
-
-       return cost1 - cost2;
-}
-
-static unsigned long long measure_migration_cost(int cpu1, int cpu2)
-{
-       unsigned long long max_cost = 0, fluct = 0, avg_fluct = 0;
-       unsigned int max_size, size, size_found = 0;
-       long long cost = 0, prev_cost;
-       void *cache;
-
-       /*
-        * Search from max_cache_size*5 down to 64K - the real relevant
-        * cachesize has to lie somewhere inbetween.
-        */
-       if (max_cache_size) {
-               max_size = max(max_cache_size * SEARCH_SCOPE, MIN_CACHE_SIZE);
-               size = max(max_cache_size / SEARCH_SCOPE, MIN_CACHE_SIZE);
-       } else {
-               /*
-                * Since we have no estimation about the relevant
-                * search range
-                */
-               max_size = DEFAULT_CACHE_SIZE * SEARCH_SCOPE;
-               size = MIN_CACHE_SIZE;
-       }
-
-       if (!cpu_online(cpu1) || !cpu_online(cpu2)) {
-               printk("cpu %d and %d not both online!\n", cpu1, cpu2);
-               return 0;
-       }
-
-       /*
-        * Allocate the working set:
-        */
-       cache = vmalloc(max_size);
-       if (!cache) {
-               printk("could not vmalloc %d bytes for cache!\n", 2 * max_size);
-               return 1000000; /* return 1 msec on very small boxen */
-       }
-
-       while (size <= max_size) {
-               prev_cost = cost;
-               cost = measure_cost(cpu1, cpu2, cache, size);
-
-               /*
-                * Update the max:
-                */
-               if (cost > 0) {
-                       if (max_cost < cost) {
-                               max_cost = cost;
-                               size_found = size;
-                       }
-               }
-               /*
-                * Calculate average fluctuation, we use this to prevent
-                * noise from triggering an early break out of the loop:
-                */
-               fluct = abs(cost - prev_cost);
-               avg_fluct = (avg_fluct + fluct)/2;
-
-               if (migration_debug)
-                       printk("-> [%d][%d][%7d] %3ld.%ld [%3ld.%ld] (%ld): "
-                               "(%8Ld %8Ld)\n",
-                               cpu1, cpu2, size,
-                               (long)cost / 1000000,
-                               ((long)cost / 100000) % 10,
-                               (long)max_cost / 1000000,
-                               ((long)max_cost / 100000) % 10,
-                               domain_distance(cpu1, cpu2),
-                               cost, avg_fluct);
-
-               /*
-                * If we iterated at least 20% past the previous maximum,
-                * and the cost has dropped by more than 20% already,
-                * (taking fluctuations into account) then we assume to
-                * have found the maximum and break out of the loop early:
-                */
-               if (size_found && (size*100 > size_found*SIZE_THRESH))
-                       if (cost+avg_fluct <= 0 ||
-                               max_cost*100 > (cost+avg_fluct)*COST_THRESH) {
-
-                               if (migration_debug)
-                                       printk("-> found max.\n");
-                               break;
-                       }
-               /*
-                * Increase the cachesize in 10% steps:
-                */
-               size = size * 10 / 9;
-       }
-
-       if (migration_debug)
-               printk("[%d][%d] working set size found: %d, cost: %Ld\n",
-                       cpu1, cpu2, size_found, max_cost);
-
-       vfree(cache);
-
-       /*
-        * A task is considered 'cache cold' if at least 2 times
-        * the worst-case cost of migration has passed.
-        *
-        * (this limit is only listened to if the load-balancing
-        * situation is 'nice' - if there is a large imbalance we
-        * ignore it for the sake of CPU utilization and
-        * processing fairness.)
-        */
-       return 2 * max_cost * migration_factor / MIGRATION_FACTOR_SCALE;
-}
-
-static void calibrate_migration_costs(const cpumask_t *cpu_map)
-{
-       int cpu1 = -1, cpu2 = -1, cpu, orig_cpu = raw_smp_processor_id();
-       unsigned long j0, j1, distance, max_distance = 0;
-       struct sched_domain *sd;
-
-       j0 = jiffies;
-
-       /*
-        * First pass - calculate the cacheflush times:
-        */
-       for_each_cpu_mask(cpu1, *cpu_map) {
-               for_each_cpu_mask(cpu2, *cpu_map) {
-                       if (cpu1 == cpu2)
-                               continue;
-                       distance = domain_distance(cpu1, cpu2);
-                       max_distance = max(max_distance, distance);
-                       /*
-                        * No result cached yet?
-                        */
-                       if (migration_cost[distance] == -1LL)
-                               migration_cost[distance] =
-                                       measure_migration_cost(cpu1, cpu2);
-               }
-       }
-       /*
-        * Second pass - update the sched domain hierarchy with
-        * the new cache-hot-time estimations:
-        */
-       for_each_cpu_mask(cpu, *cpu_map) {
-               distance = 0;
-               for_each_domain(cpu, sd) {
-                       sd->cache_hot_time = migration_cost[distance];
-                       distance++;
-               }
-       }
-       /*
-        * Print the matrix:
-        */
-       if (migration_debug)
-               printk("migration: max_cache_size: %d, cpu: %d MHz:\n",
-                       max_cache_size,
-#ifdef CONFIG_X86
-                       cpu_khz/1000
-#else
-                       -1
-#endif
-               );
-       if (system_state == SYSTEM_BOOTING && num_online_cpus() > 1) {
-               printk("migration_cost=");
-               for (distance = 0; distance <= max_distance; distance++) {
-                       if (distance)
-                               printk(",");
-                       printk("%ld", (long)migration_cost[distance] / 1000);
-               }
-               printk("\n");
-       }
-       j1 = jiffies;
-       if (migration_debug)
-               printk("migration: %ld seconds\n", (j1-j0) / HZ);
-
-       /*
-        * Move back to the original CPU. NUMA-Q gets confused
-        * if we migrate to another quad during bootup.
-        */
-       if (raw_smp_processor_id() != orig_cpu) {
-               cpumask_t mask = cpumask_of_cpu(orig_cpu),
-                       saved_mask = current->cpus_allowed;
-
-               set_cpus_allowed(current, mask);
-               set_cpus_allowed(current, saved_mask);
-       }
-}
-
 #ifdef CONFIG_NUMA
 
 /**
@@ -6574,7 +5785,6 @@ static void init_sched_groups_power(int cpu, struct sched_domain *sd)
 static int build_sched_domains(const cpumask_t *cpu_map)
 {
        int i;
-       struct sched_domain *sd;
 #ifdef CONFIG_NUMA
        struct sched_group **sched_group_nodes = NULL;
        int sd_allnodes = 0;
@@ -6582,7 +5792,7 @@ static int build_sched_domains(const cpumask_t *cpu_map)
        /*
         * Allocate the per-node list of sched groups
         */
-       sched_group_nodes = kzalloc(sizeof(struct sched_group*)*MAX_NUMNODES,
+       sched_group_nodes = kzalloc(sizeof(struct sched_group *)*MAX_NUMNODES,
                                           GFP_KERNEL);
        if (!sched_group_nodes) {
                printk(KERN_WARNING "Can not alloc sched group node list\n");
@@ -6601,8 +5811,8 @@ static int build_sched_domains(const cpumask_t *cpu_map)
                cpus_and(nodemask, nodemask, *cpu_map);
 
 #ifdef CONFIG_NUMA
-               if (cpus_weight(*cpu_map)
-                               SD_NODES_PER_DOMAIN*cpus_weight(nodemask)) {
+               if (cpus_weight(*cpu_map) >
+                               SD_NODES_PER_DOMAIN*cpus_weight(nodemask)) {
                        sd = &per_cpu(allnodes_domains, i);
                        *sd = SD_ALLNODES_INIT;
                        sd->span = *cpu_map;
@@ -6661,7 +5871,8 @@ static int build_sched_domains(const cpumask_t *cpu_map)
                if (i != first_cpu(this_sibling_map))
                        continue;
 
-               init_sched_build_groups(this_sibling_map, cpu_map, &cpu_to_cpu_group);
+               init_sched_build_groups(this_sibling_map, cpu_map,
+                                       &cpu_to_cpu_group);
        }
 #endif
 
@@ -6672,11 +5883,11 @@ static int build_sched_domains(const cpumask_t *cpu_map)
                cpus_and(this_core_map, this_core_map, *cpu_map);
                if (i != first_cpu(this_core_map))
                        continue;
-               init_sched_build_groups(this_core_map, cpu_map, &cpu_to_core_group);
+               init_sched_build_groups(this_core_map, cpu_map,
+                                       &cpu_to_core_group);
        }
 #endif
 
-
        /* Set up physical groups */
        for (i = 0; i < MAX_NUMNODES; i++) {
                cpumask_t nodemask = node_to_cpumask(i);
@@ -6691,7 +5902,8 @@ static int build_sched_domains(const cpumask_t *cpu_map)
 #ifdef CONFIG_NUMA
        /* Set up node groups */
        if (sd_allnodes)
-               init_sched_build_groups(*cpu_map, cpu_map, &cpu_to_allnodes_group);
+               init_sched_build_groups(*cpu_map, cpu_map,
+                                       &cpu_to_allnodes_group);
 
        for (i = 0; i < MAX_NUMNODES; i++) {
                /* Set up node groups */
@@ -6719,6 +5931,7 @@ static int build_sched_domains(const cpumask_t *cpu_map)
                sched_group_nodes[i] = sg;
                for_each_cpu_mask(j, nodemask) {
                        struct sched_domain *sd;
+
                        sd = &per_cpu(node_domains, j);
                        sd->groups = sg;
                }
@@ -6763,19 +5976,22 @@ static int build_sched_domains(const cpumask_t *cpu_map)
        /* Calculate CPU power for physical packages and nodes */
 #ifdef CONFIG_SCHED_SMT
        for_each_cpu_mask(i, *cpu_map) {
-               sd = &per_cpu(cpu_domains, i);
+               struct sched_domain *sd = &per_cpu(cpu_domains, i);
+
                init_sched_groups_power(i, sd);
        }
 #endif
 #ifdef CONFIG_SCHED_MC
        for_each_cpu_mask(i, *cpu_map) {
-               sd = &per_cpu(core_domains, i);
+               struct sched_domain *sd = &per_cpu(core_domains, i);
+
                init_sched_groups_power(i, sd);
        }
 #endif
 
        for_each_cpu_mask(i, *cpu_map) {
-               sd = &per_cpu(phys_domains, i);
+               struct sched_domain *sd = &per_cpu(phys_domains, i);
+
                init_sched_groups_power(i, sd);
        }
 
@@ -6803,10 +6019,6 @@ static int build_sched_domains(const cpumask_t *cpu_map)
 #endif
                cpu_attach_domain(sd, i);
        }
-       /*
-        * Tune cache-hot values:
-        */
-       calibrate_migration_costs(cpu_map);
 
        return 0;
 
@@ -7013,10 +6225,12 @@ void __init sched_init_smp(void)
        /* Move init over to a non-isolated CPU */
        if (set_cpus_allowed(current, non_isolated_cpus) < 0)
                BUG();
+       sched_init_granularity();
 }
 #else
 void __init sched_init_smp(void)
 {
+       sched_init_granularity();
 }
 #endif /* CONFIG_SMP */
 
@@ -7030,28 +6244,51 @@ int in_sched_functions(unsigned long addr)
                && addr < (unsigned long)__sched_text_end);
 }
 
+static inline void init_cfs_rq(struct cfs_rq *cfs_rq, struct rq *rq)
+{
+       cfs_rq->tasks_timeline = RB_ROOT;
+       cfs_rq->fair_clock = 1;
+#ifdef CONFIG_FAIR_GROUP_SCHED
+       cfs_rq->rq = rq;
+#endif
+}
+
 void __init sched_init(void)
 {
-       int i, j, k;
+       u64 now = sched_clock();
        int highest_cpu = 0;
+       int i, j;
+
+       /*
+        * Link up the scheduling class hierarchy:
+        */
+       rt_sched_class.next = &fair_sched_class;
+       fair_sched_class.next = &idle_sched_class;
+       idle_sched_class.next = NULL;
 
        for_each_possible_cpu(i) {
-               struct prio_array *array;
+               struct rt_prio_array *array;
                struct rq *rq;
 
                rq = cpu_rq(i);
                spin_lock_init(&rq->lock);
                lockdep_set_class(&rq->lock, &rq->rq_lock_key);
                rq->nr_running = 0;
-               rq->active = rq->arrays;
-               rq->expired = rq->arrays + 1;
-               rq->best_expired_prio = MAX_PRIO;
+               rq->clock = 1;
+               init_cfs_rq(&rq->cfs, rq);
+#ifdef CONFIG_FAIR_GROUP_SCHED
+               INIT_LIST_HEAD(&rq->leaf_cfs_rq_list);
+               list_add(&rq->cfs.leaf_cfs_rq_list, &rq->leaf_cfs_rq_list);
+#endif
+               rq->ls.load_update_last = now;
+               rq->ls.load_update_start = now;
 
+               for (j = 0; j < CPU_LOAD_IDX_MAX; j++)
+                       rq->cpu_load[j] = 0;
 #ifdef CONFIG_SMP
                rq->sd = NULL;
-               for (j = 1; j < 3; j++)
-                       rq->cpu_load[j] = 0;
                rq->active_balance = 0;
+               rq->next_balance = jiffies;
                rq->push_cpu = 0;
                rq->cpu = i;
                rq->migration_thread = NULL;
@@ -7059,16 +6296,14 @@ void __init sched_init(void)
 #endif
                atomic_set(&rq->nr_iowait, 0);
 
-               for (j = 0; j < 2; j++) {
-                       array = rq->arrays + j;
-                       for (k = 0; k < MAX_PRIO; k++) {
-                               INIT_LIST_HEAD(array->queue + k);
-                               __clear_bit(k, array->bitmap);
-                       }
-                       // delimiter for bitsearch
-                       __set_bit(MAX_PRIO, array->bitmap);
+               array = &rq->rt.active;
+               for (j = 0; j < MAX_RT_PRIO; j++) {
+                       INIT_LIST_HEAD(array->queue + j);
+                       __clear_bit(j, array->bitmap);
                }
                highest_cpu = i;
+               /* delimiter for bitsearch: */
+               __set_bit(MAX_RT_PRIO, array->bitmap);
        }
 
        set_load_weight(&init_task);
@@ -7095,6 +6330,10 @@ void __init sched_init(void)
         * when this runqueue becomes "idle".
         */
        init_idle(current, smp_processor_id());
+       /*
+        * During early bootup we pretend to be a normal task:
+        */
+       current->sched_class = &fair_sched_class;
 }
 
 #ifdef CONFIG_DEBUG_SPINLOCK_SLEEP
@@ -7125,29 +6364,55 @@ EXPORT_SYMBOL(__might_sleep);
 #ifdef CONFIG_MAGIC_SYSRQ
 void normalize_rt_tasks(void)
 {
-       struct prio_array *array;
        struct task_struct *g, *p;
        unsigned long flags;
        struct rq *rq;
+       int on_rq;
 
        read_lock_irq(&tasklist_lock);
-
        do_each_thread(g, p) {
-               if (!rt_task(p))
+               p->se.fair_key                  = 0;
+               p->se.wait_runtime              = 0;
+               p->se.wait_start_fair           = 0;
+               p->se.wait_start                = 0;
+               p->se.exec_start                = 0;
+               p->se.sleep_start               = 0;
+               p->se.sleep_start_fair          = 0;
+               p->se.block_start               = 0;
+               task_rq(p)->cfs.fair_clock      = 0;
+               task_rq(p)->clock               = 0;
+
+               if (!rt_task(p)) {
+                       /*
+                        * Renice negative nice level userspace
+                        * tasks back to 0:
+                        */
+                       if (TASK_NICE(p) < 0 && p->mm)
+                               set_user_nice(p, 0);
                        continue;
+               }
 
                spin_lock_irqsave(&p->pi_lock, flags);
                rq = __task_rq_lock(p);
+#ifdef CONFIG_SMP
+               /*
+                * Do not touch the migration thread:
+                */
+               if (p == rq->migration_thread)
+                       goto out_unlock;
+#endif
 
-               array = p->array;
-               if (array)
-                       deactivate_task(p, task_rq(p));
-               __setscheduler(p, SCHED_NORMAL, 0);
-               if (array) {
-                       __activate_task(p, task_rq(p));
+               on_rq = p->se.on_rq;
+               if (on_rq)
+                       deactivate_task(task_rq(p), p, 0);
+               __setscheduler(rq, p, SCHED_NORMAL, 0);
+               if (on_rq) {
+                       activate_task(task_rq(p), p, 0);
                        resched_task(rq->curr);
                }
-
+#ifdef CONFIG_SMP
+ out_unlock:
+#endif
                __task_rq_unlock(rq);
                spin_unlock_irqrestore(&p->pi_lock, flags);
        } while_each_thread(g, p);
diff --git a/kernel/sched_debug.c b/kernel/sched_debug.c
new file mode 100644 (file)
index 0000000..29f2c21
--- /dev/null
@@ -0,0 +1,275 @@
+/*
+ * kernel/time/sched_debug.c
+ *
+ * Print the CFS rbtree
+ *
+ * Copyright(C) 2007, Red Hat, Inc., Ingo Molnar
+ *
+ * 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/proc_fs.h>
+#include <linux/sched.h>
+#include <linux/seq_file.h>
+#include <linux/kallsyms.h>
+#include <linux/utsname.h>
+
+/*
+ * This allows printing both to /proc/sched_debug and
+ * to the console
+ */
+#define SEQ_printf(m, x...)                    \
+ do {                                          \
+       if (m)                                  \
+               seq_printf(m, x);               \
+       else                                    \
+               printk(x);                      \
+ } while (0)
+
+static void
+print_task(struct seq_file *m, struct rq *rq, struct task_struct *p, u64 now)
+{
+       if (rq->curr == p)
+               SEQ_printf(m, "R");
+       else
+               SEQ_printf(m, " ");
+
+       SEQ_printf(m, "%15s %5d %15Ld %13Ld %13Ld %9Ld %5d "
+                     "%15Ld %15Ld %15Ld %15Ld %15Ld\n",
+               p->comm, p->pid,
+               (long long)p->se.fair_key,
+               (long long)(p->se.fair_key - rq->cfs.fair_clock),
+               (long long)p->se.wait_runtime,
+               (long long)(p->nvcsw + p->nivcsw),
+               p->prio,
+               (long long)p->se.sum_exec_runtime,
+               (long long)p->se.sum_wait_runtime,
+               (long long)p->se.sum_sleep_runtime,
+               (long long)p->se.wait_runtime_overruns,
+               (long long)p->se.wait_runtime_underruns);
+}
+
+static void print_rq(struct seq_file *m, struct rq *rq, int rq_cpu, u64 now)
+{
+       struct task_struct *g, *p;
+
+       SEQ_printf(m,
+       "\nrunnable tasks:\n"
+       "            task   PID        tree-key         delta       waiting"
+       "  switches  prio"
+       "        sum-exec        sum-wait       sum-sleep"
+       "    wait-overrun   wait-underrun\n"
+       "------------------------------------------------------------------"
+       "----------------"
+       "------------------------------------------------"
+       "--------------------------------\n");
+
+       read_lock_irq(&tasklist_lock);
+
+       do_each_thread(g, p) {
+               if (!p->se.on_rq || task_cpu(p) != rq_cpu)
+                       continue;
+
+               print_task(m, rq, p, now);
+       } while_each_thread(g, p);
+
+       read_unlock_irq(&tasklist_lock);
+}
+
+static void
+print_cfs_rq_runtime_sum(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq)
+{
+       s64 wait_runtime_rq_sum = 0;
+       struct task_struct *p;
+       struct rb_node *curr;
+       unsigned long flags;
+       struct rq *rq = &per_cpu(runqueues, cpu);
+
+       spin_lock_irqsave(&rq->lock, flags);
+       curr = first_fair(cfs_rq);
+       while (curr) {
+               p = rb_entry(curr, struct task_struct, se.run_node);
+               wait_runtime_rq_sum += p->se.wait_runtime;
+
+               curr = rb_next(curr);
+       }
+       spin_unlock_irqrestore(&rq->lock, flags);
+
+       SEQ_printf(m, "  .%-30s: %Ld\n", "wait_runtime_rq_sum",
+               (long long)wait_runtime_rq_sum);
+}
+
+void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq, u64 now)
+{
+       SEQ_printf(m, "\ncfs_rq %p\n", cfs_rq);
+
+#define P(x) \
+       SEQ_printf(m, "  .%-30s: %Ld\n", #x, (long long)(cfs_rq->x))
+
+       P(fair_clock);
+       P(exec_clock);
+       P(wait_runtime);
+       P(wait_runtime_overruns);
+       P(wait_runtime_underruns);
+       P(sleeper_bonus);
+#undef P
+
+       print_cfs_rq_runtime_sum(m, cpu, cfs_rq);
+}
+
+static void print_cpu(struct seq_file *m, int cpu, u64 now)
+{
+       struct rq *rq = &per_cpu(runqueues, cpu);
+
+#ifdef CONFIG_X86
+       {
+               unsigned int freq = cpu_khz ? : 1;
+
+               SEQ_printf(m, "\ncpu#%d, %u.%03u MHz\n",
+                          cpu, freq / 1000, (freq % 1000));
+       }
+#else
+       SEQ_printf(m, "\ncpu#%d\n", cpu);
+#endif
+
+#define P(x) \
+       SEQ_printf(m, "  .%-30s: %Ld\n", #x, (long long)(rq->x))
+
+       P(nr_running);
+       SEQ_printf(m, "  .%-30s: %lu\n", "load",
+                  rq->ls.load.weight);
+       P(ls.delta_fair);
+       P(ls.delta_exec);
+       P(nr_switches);
+       P(nr_load_updates);
+       P(nr_uninterruptible);
+       SEQ_printf(m, "  .%-30s: %lu\n", "jiffies", jiffies);
+       P(next_balance);
+       P(curr->pid);
+       P(clock);
+       P(prev_clock_raw);
+       P(clock_warps);
+       P(clock_overflows);
+       P(clock_unstable_events);
+       P(clock_max_delta);
+       P(cpu_load[0]);
+       P(cpu_load[1]);
+       P(cpu_load[2]);
+       P(cpu_load[3]);
+       P(cpu_load[4]);
+#undef P
+
+       print_cfs_stats(m, cpu, now);
+
+       print_rq(m, rq, cpu, now);
+}
+
+static int sched_debug_show(struct seq_file *m, void *v)
+{
+       u64 now = ktime_to_ns(ktime_get());
+       int cpu;
+
+       SEQ_printf(m, "Sched Debug Version: v0.05, %s %.*s\n",
+               init_utsname()->release,
+               (int)strcspn(init_utsname()->version, " "),
+               init_utsname()->version);
+
+       SEQ_printf(m, "now at %Lu nsecs\n", (unsigned long long)now);
+
+       for_each_online_cpu(cpu)
+               print_cpu(m, cpu, now);
+
+       SEQ_printf(m, "\n");
+
+       return 0;
+}
+
+void sysrq_sched_debug_show(void)
+{
+       sched_debug_show(NULL, NULL);
+}
+
+static int sched_debug_open(struct inode *inode, struct file *filp)
+{
+       return single_open(filp, sched_debug_show, NULL);
+}
+
+static struct file_operations sched_debug_fops = {
+       .open           = sched_debug_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
+static int __init init_sched_debug_procfs(void)
+{
+       struct proc_dir_entry *pe;
+
+       pe = create_proc_entry("sched_debug", 0644, NULL);
+       if (!pe)
+               return -ENOMEM;
+
+       pe->proc_fops = &sched_debug_fops;
+
+       return 0;
+}
+
+__initcall(init_sched_debug_procfs);
+
+void proc_sched_show_task(struct task_struct *p, struct seq_file *m)
+{
+       unsigned long flags;
+       int num_threads = 1;
+
+       rcu_read_lock();
+       if (lock_task_sighand(p, &flags)) {
+               num_threads = atomic_read(&p->signal->count);
+               unlock_task_sighand(p, &flags);
+       }
+       rcu_read_unlock();
+
+       SEQ_printf(m, "%s (%d, #threads: %d)\n", p->comm, p->pid, num_threads);
+       SEQ_printf(m, "----------------------------------------------\n");
+#define P(F) \
+       SEQ_printf(m, "%-25s:%20Ld\n", #F, (long long)p->F)
+
+       P(se.wait_start);
+       P(se.wait_start_fair);
+       P(se.exec_start);
+       P(se.sleep_start);
+       P(se.sleep_start_fair);
+       P(se.block_start);
+       P(se.sleep_max);
+       P(se.block_max);
+       P(se.exec_max);
+       P(se.wait_max);
+       P(se.wait_runtime);
+       P(se.wait_runtime_overruns);
+       P(se.wait_runtime_underruns);
+       P(se.sum_wait_runtime);
+       P(se.sum_exec_runtime);
+       SEQ_printf(m, "%-25s:%20Ld\n",
+                  "nr_switches", (long long)(p->nvcsw + p->nivcsw));
+       P(se.load.weight);
+       P(policy);
+       P(prio);
+#undef P
+
+       {
+               u64 t0, t1;
+
+               t0 = sched_clock();
+               t1 = sched_clock();
+               SEQ_printf(m, "%-25s:%20Ld\n",
+                          "clock-delta", (long long)(t1-t0));
+       }
+}
+
+void proc_sched_set_task(struct task_struct *p)
+{
+       p->se.sleep_max = p->se.block_max = p->se.exec_max = p->se.wait_max = 0;
+       p->se.wait_runtime_overruns = p->se.wait_runtime_underruns = 0;
+       p->se.sum_exec_runtime = 0;
+}
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
new file mode 100644 (file)
index 0000000..6971db0
--- /dev/null
@@ -0,0 +1,1131 @@
+/*
+ * Completely Fair Scheduling (CFS) Class (SCHED_NORMAL/SCHED_BATCH)
+ *
+ *  Copyright (C) 2007 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
+ *
+ *  Interactivity improvements by Mike Galbraith
+ *  (C) 2007 Mike Galbraith <efault@gmx.de>
+ *
+ *  Various enhancements by Dmitry Adamushko.
+ *  (C) 2007 Dmitry Adamushko <dmitry.adamushko@gmail.com>
+ *
+ *  Group scheduling enhancements by Srivatsa Vaddagiri
+ *  Copyright IBM Corporation, 2007
+ *  Author: Srivatsa Vaddagiri <vatsa@linux.vnet.ibm.com>
+ *
+ *  Scaled math optimizations by Thomas Gleixner
+ *  Copyright (C) 2007, Thomas Gleixner <tglx@linutronix.de>
+ */
+
+/*
+ * Preemption granularity:
+ * (default: 2 msec, units: nanoseconds)
+ *
+ * NOTE: this granularity value is not the same as the concept of
+ * 'timeslice length' - timeslices in CFS will typically be somewhat
+ * larger than this value. (to see the precise effective timeslice
+ * length of your workload, run vmstat and monitor the context-switches
+ * field)
+ *
+ * On SMP systems the value of this is multiplied by the log2 of the
+ * number of CPUs. (i.e. factor 2x on 2-way systems, 3x on 4-way
+ * systems, 4x on 8-way systems, 5x on 16-way systems, etc.)
+ */
+unsigned int sysctl_sched_granularity __read_mostly = 2000000000ULL/HZ;
+
+/*
+ * SCHED_BATCH wake-up granularity.
+ * (default: 10 msec, units: nanoseconds)
+ *
+ * This option delays the preemption effects of decoupled workloads
+ * and reduces their over-scheduling. Synchronous workloads will still
+ * have immediate wakeup/sleep latencies.
+ */
+unsigned int sysctl_sched_batch_wakeup_granularity __read_mostly =
+                                                       10000000000ULL/HZ;
+
+/*
+ * SCHED_OTHER wake-up granularity.
+ * (default: 1 msec, units: nanoseconds)
+ *
+ * This option delays the preemption effects of decoupled workloads
+ * and reduces their over-scheduling. Synchronous workloads will still
+ * have immediate wakeup/sleep latencies.
+ */
+unsigned int sysctl_sched_wakeup_granularity __read_mostly = 1000000000ULL/HZ;
+
+unsigned int sysctl_sched_stat_granularity __read_mostly;
+
+/*
+ * Initialized in sched_init_granularity():
+ */
+unsigned int sysctl_sched_runtime_limit __read_mostly;
+
+/*
+ * Debugging: various feature bits
+ */
+enum {
+       SCHED_FEAT_FAIR_SLEEPERS        = 1,
+       SCHED_FEAT_SLEEPER_AVG          = 2,
+       SCHED_FEAT_SLEEPER_LOAD_AVG     = 4,
+       SCHED_FEAT_PRECISE_CPU_LOAD     = 8,
+       SCHED_FEAT_START_DEBIT          = 16,
+       SCHED_FEAT_SKIP_INITIAL         = 32,
+};
+
+unsigned int sysctl_sched_features __read_mostly =
+               SCHED_FEAT_FAIR_SLEEPERS        *1 |
+               SCHED_FEAT_SLEEPER_AVG          *1 |
+               SCHED_FEAT_SLEEPER_LOAD_AVG     *1 |
+               SCHED_FEAT_PRECISE_CPU_LOAD     *1 |
+               SCHED_FEAT_START_DEBIT          *1 |
+               SCHED_FEAT_SKIP_INITIAL         *0;
+
+extern struct sched_class fair_sched_class;
+
+/**************************************************************
+ * CFS operations on generic schedulable entities:
+ */
+
+#ifdef CONFIG_FAIR_GROUP_SCHED
+
+/* cpu runqueue to which this cfs_rq is attached */
+static inline struct rq *rq_of(struct cfs_rq *cfs_rq)
+{
+       return cfs_rq->rq;
+}
+
+/* currently running entity (if any) on this cfs_rq */
+static inline struct sched_entity *cfs_rq_curr(struct cfs_rq *cfs_rq)
+{
+       return cfs_rq->curr;
+}
+
+/* An entity is a task if it doesn't "own" a runqueue */
+#define entity_is_task(se)     (!se->my_q)
+
+static inline void
+set_cfs_rq_curr(struct cfs_rq *cfs_rq, struct sched_entity *se)
+{
+       cfs_rq->curr = se;
+}
+
+#else  /* CONFIG_FAIR_GROUP_SCHED */
+
+static inline struct rq *rq_of(struct cfs_rq *cfs_rq)
+{
+       return container_of(cfs_rq, struct rq, cfs);
+}
+
+static inline struct sched_entity *cfs_rq_curr(struct cfs_rq *cfs_rq)
+{
+       struct rq *rq = rq_of(cfs_rq);
+
+       if (unlikely(rq->curr->sched_class != &fair_sched_class))
+               return NULL;
+
+       return &rq->curr->se;
+}
+
+#define entity_is_task(se)     1
+
+static inline void
+set_cfs_rq_curr(struct cfs_rq *cfs_rq, struct sched_entity *se) { }
+
+#endif /* CONFIG_FAIR_GROUP_SCHED */
+
+static inline struct task_struct *task_of(struct sched_entity *se)
+{
+       return container_of(se, struct task_struct, se);
+}
+
+
+/**************************************************************
+ * Scheduling class tree data structure manipulation methods:
+ */
+
+/*
+ * Enqueue an entity into the rb-tree:
+ */
+static inline void
+__enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se)
+{
+       struct rb_node **link = &cfs_rq->tasks_timeline.rb_node;
+       struct rb_node *parent = NULL;
+       struct sched_entity *entry;
+       s64 key = se->fair_key;
+       int leftmost = 1;
+
+       /*
+        * Find the right place in the rbtree:
+        */
+       while (*link) {
+               parent = *link;
+               entry = rb_entry(parent, struct sched_entity, run_node);
+               /*
+                * We dont care about collisions. Nodes with
+                * the same key stay together.
+                */
+               if (key - entry->fair_key < 0) {
+                       link = &parent->rb_left;
+               } else {
+                       link = &parent->rb_right;
+                       leftmost = 0;
+               }
+       }
+
+       /*
+        * Maintain a cache of leftmost tree entries (it is frequently
+        * used):
+        */
+       if (leftmost)
+               cfs_rq->rb_leftmost = &se->run_node;
+
+       rb_link_node(&se->run_node, parent, link);
+       rb_insert_color(&se->run_node, &cfs_rq->tasks_timeline);
+       update_load_add(&cfs_rq->load, se->load.weight);
+       cfs_rq->nr_running++;
+       se->on_rq = 1;
+}
+
+static inline void
+__dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se)
+{
+       if (cfs_rq->rb_leftmost == &se->run_node)
+               cfs_rq->rb_leftmost = rb_next(&se->run_node);
+       rb_erase(&se->run_node, &cfs_rq->tasks_timeline);
+       update_load_sub(&cfs_rq->load, se->load.weight);
+       cfs_rq->nr_running--;
+       se->on_rq = 0;
+}
+
+static inline struct rb_node *first_fair(struct cfs_rq *cfs_rq)
+{
+       return cfs_rq->rb_leftmost;
+}
+
+static struct sched_entity *__pick_next_entity(struct cfs_rq *cfs_rq)
+{
+       return rb_entry(first_fair(cfs_rq), struct sched_entity, run_node);
+}
+
+/**************************************************************
+ * Scheduling class statistics methods:
+ */
+
+/*
+ * We rescale the rescheduling granularity of tasks according to their
+ * nice level, but only linearly, not exponentially:
+ */
+static long
+niced_granularity(struct sched_entity *curr, unsigned long granularity)
+{
+       u64 tmp;
+
+       /*
+        * Negative nice levels get the same granularity as nice-0:
+        */
+       if (likely(curr->load.weight >= NICE_0_LOAD))
+               return granularity;
+       /*
+        * Positive nice level tasks get linearly finer
+        * granularity:
+        */
+       tmp = curr->load.weight * (u64)granularity;
+
+       /*
+        * It will always fit into 'long':
+        */
+       return (long) (tmp >> NICE_0_SHIFT);
+}
+
+static inline void
+limit_wait_runtime(struct cfs_rq *cfs_rq, struct sched_entity *se)
+{
+       long limit = sysctl_sched_runtime_limit;
+
+       /*
+        * Niced tasks have the same history dynamic range as
+        * non-niced tasks:
+        */
+       if (unlikely(se->wait_runtime > limit)) {
+               se->wait_runtime = limit;
+               schedstat_inc(se, wait_runtime_overruns);
+               schedstat_inc(cfs_rq, wait_runtime_overruns);
+       }
+       if (unlikely(se->wait_runtime < -limit)) {
+               se->wait_runtime = -limit;
+               schedstat_inc(se, wait_runtime_underruns);
+               schedstat_inc(cfs_rq, wait_runtime_underruns);
+       }
+}
+
+static inline void
+__add_wait_runtime(struct cfs_rq *cfs_rq, struct sched_entity *se, long delta)
+{
+       se->wait_runtime += delta;
+       schedstat_add(se, sum_wait_runtime, delta);
+       limit_wait_runtime(cfs_rq, se);
+}
+
+static void
+add_wait_runtime(struct cfs_rq *cfs_rq, struct sched_entity *se, long delta)
+{
+       schedstat_add(cfs_rq, wait_runtime, -se->wait_runtime);
+       __add_wait_runtime(cfs_rq, se, delta);
+       schedstat_add(cfs_rq, wait_runtime, se->wait_runtime);
+}
+
+/*
+ * Update the current task's runtime statistics. Skip current tasks that
+ * are not in our scheduling class.
+ */
+static inline void
+__update_curr(struct cfs_rq *cfs_rq, struct sched_entity *curr, u64 now)
+{
+       unsigned long delta, delta_exec, delta_fair;
+       long delta_mine;
+       struct load_weight *lw = &cfs_rq->load;
+       unsigned long load = lw->weight;
+
+       if (unlikely(!load))
+               return;
+
+       delta_exec = curr->delta_exec;
+#ifdef CONFIG_SCHEDSTATS
+       if (unlikely(delta_exec > curr->exec_max))
+               curr->exec_max = delta_exec;
+#endif
+
+       curr->sum_exec_runtime += delta_exec;
+       cfs_rq->exec_clock += delta_exec;
+
+       delta_fair = calc_delta_fair(delta_exec, lw);
+       delta_mine = calc_delta_mine(delta_exec, curr->load.weight, lw);
+
+       if (cfs_rq->sleeper_bonus > sysctl_sched_stat_granularity) {
+               delta = calc_delta_mine(cfs_rq->sleeper_bonus,
+                                       curr->load.weight, lw);
+               if (unlikely(delta > cfs_rq->sleeper_bonus))
+                       delta = cfs_rq->sleeper_bonus;
+
+               cfs_rq->sleeper_bonus -= delta;
+               delta_mine -= delta;
+       }
+
+       cfs_rq->fair_clock += delta_fair;
+       /*
+        * We executed delta_exec amount of time on the CPU,
+        * but we were only entitled to delta_mine amount of
+        * time during that period (if nr_running == 1 then
+        * the two values are equal)
+        * [Note: delta_mine - delta_exec is negative]:
+        */
+       add_wait_runtime(cfs_rq, curr, delta_mine - delta_exec);
+}
+
+static void update_curr(struct cfs_rq *cfs_rq, u64 now)
+{
+       struct sched_entity *curr = cfs_rq_curr(cfs_rq);
+       unsigned long delta_exec;
+
+       if (unlikely(!curr))
+               return;
+
+       /*
+        * Get the amount of time the current task was running
+        * since the last time we changed load (this cannot
+        * overflow on 32 bits):
+        */
+       delta_exec = (unsigned long)(now - curr->exec_start);
+
+       curr->delta_exec += delta_exec;
+
+       if (unlikely(curr->delta_exec > sysctl_sched_stat_granularity)) {
+               __update_curr(cfs_rq, curr, now);
+               curr->delta_exec = 0;
+       }
+       curr->exec_start = now;
+}
+
+static inline void
+update_stats_wait_start(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
+{
+       se->wait_start_fair = cfs_rq->fair_clock;
+       se->wait_start = now;
+}
+
+/*
+ * We calculate fair deltas here, so protect against the random effects
+ * of a multiplication overflow by capping it to the runtime limit:
+ */
+#if BITS_PER_LONG == 32
+static inline unsigned long
+calc_weighted(unsigned long delta, unsigned long weight, int shift)
+{
+       u64 tmp = (u64)delta * weight >> shift;
+
+       if (unlikely(tmp > sysctl_sched_runtime_limit*2))
+               return sysctl_sched_runtime_limit*2;
+       return tmp;
+}
+#else
+static inline unsigned long
+calc_weighted(unsigned long delta, unsigned long weight, int shift)
+{
+       return delta * weight >> shift;
+}
+#endif
+
+/*
+ * Task is being enqueued - update stats:
+ */
+static void
+update_stats_enqueue(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
+{
+       s64 key;
+
+       /*
+        * Are we enqueueing a waiting task? (for current tasks
+        * a dequeue/enqueue event is a NOP)
+        */
+       if (se != cfs_rq_curr(cfs_rq))
+               update_stats_wait_start(cfs_rq, se, now);
+       /*
+        * Update the key:
+        */
+       key = cfs_rq->fair_clock;
+
+       /*
+        * Optimize the common nice 0 case:
+        */
+       if (likely(se->load.weight == NICE_0_LOAD)) {
+               key -= se->wait_runtime;
+       } else {
+               u64 tmp;
+
+               if (se->wait_runtime < 0) {
+                       tmp = -se->wait_runtime;
+                       key += (tmp * se->load.inv_weight) >>
+                                       (WMULT_SHIFT - NICE_0_SHIFT);
+               } else {
+                       tmp = se->wait_runtime;
+                       key -= (tmp * se->load.weight) >> NICE_0_SHIFT;
+               }
+       }
+
+       se->fair_key = key;
+}
+
+/*
+ * Note: must be called with a freshly updated rq->fair_clock.
+ */
+static inline void
+__update_stats_wait_end(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
+{
+       unsigned long delta_fair = se->delta_fair_run;
+
+#ifdef CONFIG_SCHEDSTATS
+       {
+               s64 delta_wait = now - se->wait_start;
+               if (unlikely(delta_wait > se->wait_max))
+                       se->wait_max = delta_wait;
+       }
+#endif
+
+       if (unlikely(se->load.weight != NICE_0_LOAD))
+               delta_fair = calc_weighted(delta_fair, se->load.weight,
+                                                       NICE_0_SHIFT);
+
+       add_wait_runtime(cfs_rq, se, delta_fair);
+}
+
+static void
+update_stats_wait_end(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
+{
+       unsigned long delta_fair;
+
+       delta_fair = (unsigned long)min((u64)(2*sysctl_sched_runtime_limit),
+                       (u64)(cfs_rq->fair_clock - se->wait_start_fair));
+
+       se->delta_fair_run += delta_fair;
+       if (unlikely(abs(se->delta_fair_run) >=
+                               sysctl_sched_stat_granularity)) {
+               __update_stats_wait_end(cfs_rq, se, now);
+               se->delta_fair_run = 0;
+       }
+
+       se->wait_start_fair = 0;
+       se->wait_start = 0;
+}
+
+static inline void
+update_stats_dequeue(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
+{
+       update_curr(cfs_rq, now);
+       /*
+        * Mark the end of the wait period if dequeueing a
+        * waiting task:
+        */
+       if (se != cfs_rq_curr(cfs_rq))
+               update_stats_wait_end(cfs_rq, se, now);
+}
+
+/*
+ * We are picking a new current task - update its stats:
+ */
+static inline void
+update_stats_curr_start(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
+{
+       /*
+        * We are starting a new run period:
+        */
+       se->exec_start = now;
+}
+
+/*
+ * We are descheduling a task - update its stats:
+ */
+static inline void
+update_stats_curr_end(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
+{
+       se->exec_start = 0;
+}
+
+/**************************************************
+ * Scheduling class queueing methods:
+ */
+
+static void
+__enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
+{
+       unsigned long load = cfs_rq->load.weight, delta_fair;
+       long prev_runtime;
+
+       if (sysctl_sched_features & SCHED_FEAT_SLEEPER_LOAD_AVG)
+               load = rq_of(cfs_rq)->cpu_load[2];
+
+       delta_fair = se->delta_fair_sleep;
+
+       /*
+        * Fix up delta_fair with the effect of us running
+        * during the whole sleep period:
+        */
+       if (sysctl_sched_features & SCHED_FEAT_SLEEPER_AVG)
+               delta_fair = div64_likely32((u64)delta_fair * load,
+                                               load + se->load.weight);
+
+       if (unlikely(se->load.weight != NICE_0_LOAD))
+               delta_fair = calc_weighted(delta_fair, se->load.weight,
+                                                       NICE_0_SHIFT);
+
+       prev_runtime = se->wait_runtime;
+       __add_wait_runtime(cfs_rq, se, delta_fair);
+       delta_fair = se->wait_runtime - prev_runtime;
+
+       /*
+        * Track the amount of bonus we've given to sleepers:
+        */
+       cfs_rq->sleeper_bonus += delta_fair;
+
+       schedstat_add(cfs_rq, wait_runtime, se->wait_runtime);
+}
+
+static void
+enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
+{
+       struct task_struct *tsk = task_of(se);
+       unsigned long delta_fair;
+
+       if ((entity_is_task(se) && tsk->policy == SCHED_BATCH) ||
+                        !(sysctl_sched_features & SCHED_FEAT_FAIR_SLEEPERS))
+               return;
+
+       delta_fair = (unsigned long)min((u64)(2*sysctl_sched_runtime_limit),
+               (u64)(cfs_rq->fair_clock - se->sleep_start_fair));
+
+       se->delta_fair_sleep += delta_fair;
+       if (unlikely(abs(se->delta_fair_sleep) >=
+                               sysctl_sched_stat_granularity)) {
+               __enqueue_sleeper(cfs_rq, se, now);
+               se->delta_fair_sleep = 0;
+       }
+
+       se->sleep_start_fair = 0;
+
+#ifdef CONFIG_SCHEDSTATS
+       if (se->sleep_start) {
+               u64 delta = now - se->sleep_start;
+
+               if ((s64)delta < 0)
+                       delta = 0;
+
+               if (unlikely(delta > se->sleep_max))
+                       se->sleep_max = delta;
+
+               se->sleep_start = 0;
+               se->sum_sleep_runtime += delta;
+       }
+       if (se->block_start) {
+               u64 delta = now - se->block_start;
+
+               if ((s64)delta < 0)
+                       delta = 0;
+
+               if (unlikely(delta > se->block_max))
+                       se->block_max = delta;
+
+               se->block_start = 0;
+               se->sum_sleep_runtime += delta;
+       }
+#endif
+}
+
+static void
+enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se,
+              int wakeup, u64 now)
+{
+       /*
+        * Update the fair clock.
+        */
+       update_curr(cfs_rq, now);
+
+       if (wakeup)
+               enqueue_sleeper(cfs_rq, se, now);
+
+       update_stats_enqueue(cfs_rq, se, now);
+       __enqueue_entity(cfs_rq, se);
+}
+
+static void
+dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se,
+              int sleep, u64 now)
+{
+       update_stats_dequeue(cfs_rq, se, now);
+       if (sleep) {
+               se->sleep_start_fair = cfs_rq->fair_clock;
+#ifdef CONFIG_SCHEDSTATS
+               if (entity_is_task(se)) {
+                       struct task_struct *tsk = task_of(se);
+
+                       if (tsk->state & TASK_INTERRUPTIBLE)
+                               se->sleep_start = now;
+                       if (tsk->state & TASK_UNINTERRUPTIBLE)
+                               se->block_start = now;
+               }
+               cfs_rq->wait_runtime -= se->wait_runtime;
+#endif
+       }
+       __dequeue_entity(cfs_rq, se);
+}
+
+/*
+ * Preempt the current task with a newly woken task if needed:
+ */
+static void
+__check_preempt_curr_fair(struct cfs_rq *cfs_rq, struct sched_entity *se,
+                         struct sched_entity *curr, unsigned long granularity)
+{
+       s64 __delta = curr->fair_key - se->fair_key;
+
+       /*
+        * Take scheduling granularity into account - do not
+        * preempt the current task unless the best task has
+        * a larger than sched_granularity fairness advantage:
+        */
+       if (__delta > niced_granularity(curr, granularity))
+               resched_task(rq_of(cfs_rq)->curr);
+}
+
+static inline void
+set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
+{
+       /*
+        * Any task has to be enqueued before it get to execute on
+        * a CPU. So account for the time it spent waiting on the
+        * runqueue. (note, here we rely on pick_next_task() having
+        * done a put_prev_task_fair() shortly before this, which
+        * updated rq->fair_clock - used by update_stats_wait_end())
+        */
+       update_stats_wait_end(cfs_rq, se, now);
+       update_stats_curr_start(cfs_rq, se, now);
+       set_cfs_rq_curr(cfs_rq, se);
+}
+
+static struct sched_entity *pick_next_entity(struct cfs_rq *cfs_rq, u64 now)
+{
+       struct sched_entity *se = __pick_next_entity(cfs_rq);
+
+       set_next_entity(cfs_rq, se, now);
+
+       return se;
+}
+
+static void
+put_prev_entity(struct cfs_rq *cfs_rq, struct sched_entity *prev, u64 now)
+{
+       /*
+        * If still on the runqueue then deactivate_task()
+        * was not called and update_curr() has to be done:
+        */
+       if (prev->on_rq)
+               update_curr(cfs_rq, now);
+
+       update_stats_curr_end(cfs_rq, prev, now);
+
+       if (prev->on_rq)
+               update_stats_wait_start(cfs_rq, prev, now);
+       set_cfs_rq_curr(cfs_rq, NULL);
+}
+
+static void entity_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr)
+{
+       struct rq *rq = rq_of(cfs_rq);
+       struct sched_entity *next;
+       u64 now = __rq_clock(rq);
+
+       /*
+        * Dequeue and enqueue the task to update its
+        * position within the tree:
+        */
+       dequeue_entity(cfs_rq, curr, 0, now);
+       enqueue_entity(cfs_rq, curr, 0, now);
+
+       /*
+        * Reschedule if another task tops the current one.
+        */
+       next = __pick_next_entity(cfs_rq);
+       if (next == curr)
+               return;
+
+       __check_preempt_curr_fair(cfs_rq, next, curr, sysctl_sched_granularity);
+}
+
+/**************************************************
+ * CFS operations on tasks:
+ */
+
+#ifdef CONFIG_FAIR_GROUP_SCHED
+
+/* Walk up scheduling entities hierarchy */
+#define for_each_sched_entity(se) \
+               for (; se; se = se->parent)
+
+static inline struct cfs_rq *task_cfs_rq(struct task_struct *p)
+{
+       return p->se.cfs_rq;
+}
+
+/* runqueue on which this entity is (to be) queued */
+static inline struct cfs_rq *cfs_rq_of(struct sched_entity *se)
+{
+       return se->cfs_rq;
+}
+
+/* runqueue "owned" by this group */
+static inline struct cfs_rq *group_cfs_rq(struct sched_entity *grp)
+{
+       return grp->my_q;
+}
+
+/* Given a group's cfs_rq on one cpu, return its corresponding cfs_rq on
+ * another cpu ('this_cpu')
+ */
+static inline struct cfs_rq *cpu_cfs_rq(struct cfs_rq *cfs_rq, int this_cpu)
+{
+       /* A later patch will take group into account */
+       return &cpu_rq(this_cpu)->cfs;
+}
+
+/* Iterate thr' all leaf cfs_rq's on a runqueue */
+#define for_each_leaf_cfs_rq(rq, cfs_rq) \
+       list_for_each_entry(cfs_rq, &rq->leaf_cfs_rq_list, leaf_cfs_rq_list)
+
+/* Do the two (enqueued) tasks belong to the same group ? */
+static inline int is_same_group(struct task_struct *curr, struct task_struct *p)
+{
+       if (curr->se.cfs_rq == p->se.cfs_rq)
+               return 1;
+
+       return 0;
+}
+
+#else  /* CONFIG_FAIR_GROUP_SCHED */
+
+#define for_each_sched_entity(se) \
+               for (; se; se = NULL)
+
+static inline struct cfs_rq *task_cfs_rq(struct task_struct *p)
+{
+       return &task_rq(p)->cfs;
+}
+
+static inline struct cfs_rq *cfs_rq_of(struct sched_entity *se)
+{
+       struct task_struct *p = task_of(se);
+       struct rq *rq = task_rq(p);
+
+       return &rq->cfs;
+}
+
+/* runqueue "owned" by this group */
+static inline struct cfs_rq *group_cfs_rq(struct sched_entity *grp)
+{
+       return NULL;
+}
+
+static inline struct cfs_rq *cpu_cfs_rq(struct cfs_rq *cfs_rq, int this_cpu)
+{
+       return &cpu_rq(this_cpu)->cfs;
+}
+
+#define for_each_leaf_cfs_rq(rq, cfs_rq) \
+               for (cfs_rq = &rq->cfs; cfs_rq; cfs_rq = NULL)
+
+static inline int is_same_group(struct task_struct *curr, struct task_struct *p)
+{
+       return 1;
+}
+
+#endif /* CONFIG_FAIR_GROUP_SCHED */
+
+/*
+ * The enqueue_task method is called before nr_running is
+ * increased. Here we update the fair scheduling stats and
+ * then put the task into the rbtree:
+ */
+static void
+enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup, u64 now)
+{
+       struct cfs_rq *cfs_rq;
+       struct sched_entity *se = &p->se;
+
+       for_each_sched_entity(se) {
+               if (se->on_rq)
+                       break;
+               cfs_rq = cfs_rq_of(se);
+               enqueue_entity(cfs_rq, se, wakeup, now);
+       }
+}
+
+/*
+ * The dequeue_task method is called before nr_running is
+ * decreased. We remove the task from the rbtree and
+ * update the fair scheduling stats:
+ */
+static void
+dequeue_task_fair(struct rq *rq, struct task_struct *p, int sleep, u64 now)
+{
+       struct cfs_rq *cfs_rq;
+       struct sched_entity *se = &p->se;
+
+       for_each_sched_entity(se) {
+               cfs_rq = cfs_rq_of(se);
+               dequeue_entity(cfs_rq, se, sleep, now);
+               /* Don't dequeue parent if it has other entities besides us */
+               if (cfs_rq->load.weight)
+                       break;
+       }
+}
+
+/*
+ * sched_yield() support is very simple - we dequeue and enqueue
+ */
+static void yield_task_fair(struct rq *rq, struct task_struct *p)
+{
+       struct cfs_rq *cfs_rq = task_cfs_rq(p);
+       u64 now = __rq_clock(rq);
+
+       /*
+        * Dequeue and enqueue the task to update its
+        * position within the tree:
+        */
+       dequeue_entity(cfs_rq, &p->se, 0, now);
+       enqueue_entity(cfs_rq, &p->se, 0, now);
+}
+
+/*
+ * Preempt the current task with a newly woken task if needed:
+ */
+static void check_preempt_curr_fair(struct rq *rq, struct task_struct *p)
+{
+       struct task_struct *curr = rq->curr;
+       struct cfs_rq *cfs_rq = task_cfs_rq(curr);
+       unsigned long gran;
+
+       if (unlikely(rt_prio(p->prio))) {
+               update_curr(cfs_rq, rq_clock(rq));
+               resched_task(curr);
+               return;
+       }
+
+       gran = sysctl_sched_wakeup_granularity;
+       /*
+        * Batch tasks prefer throughput over latency:
+        */
+       if (unlikely(p->policy == SCHED_BATCH))
+               gran = sysctl_sched_batch_wakeup_granularity;
+
+       if (is_same_group(curr, p))
+               __check_preempt_curr_fair(cfs_rq, &p->se, &curr->se, gran);
+}
+
+static struct task_struct *pick_next_task_fair(struct rq *rq, u64 now)
+{
+       struct cfs_rq *cfs_rq = &rq->cfs;
+       struct sched_entity *se;
+
+       if (unlikely(!cfs_rq->nr_running))
+               return NULL;
+
+       do {
+               se = pick_next_entity(cfs_rq, now);
+               cfs_rq = group_cfs_rq(se);
+       } while (cfs_rq);
+
+       return task_of(se);
+}
+
+/*
+ * Account for a descheduled task:
+ */
+static void put_prev_task_fair(struct rq *rq, struct task_struct *prev, u64 now)
+{
+       struct sched_entity *se = &prev->se;
+       struct cfs_rq *cfs_rq;
+
+       for_each_sched_entity(se) {
+               cfs_rq = cfs_rq_of(se);
+               put_prev_entity(cfs_rq, se, now);
+       }
+}
+
+/**************************************************
+ * Fair scheduling class load-balancing methods:
+ */
+
+/*
+ * Load-balancing iterator. Note: while the runqueue stays locked
+ * during the whole iteration, the current task might be
+ * dequeued so the iterator has to be dequeue-safe. Here we
+ * achieve that by always pre-iterating before returning
+ * the current task:
+ */
+static inline struct task_struct *
+__load_balance_iterator(struct cfs_rq *cfs_rq, struct rb_node *curr)
+{
+       struct task_struct *p;
+
+       if (!curr)
+               return NULL;
+
+       p = rb_entry(curr, struct task_struct, se.run_node);
+       cfs_rq->rb_load_balance_curr = rb_next(curr);
+
+       return p;
+}
+
+static struct task_struct *load_balance_start_fair(void *arg)
+{
+       struct cfs_rq *cfs_rq = arg;
+
+       return __load_balance_iterator(cfs_rq, first_fair(cfs_rq));
+}
+
+static struct task_struct *load_balance_next_fair(void *arg)
+{
+       struct cfs_rq *cfs_rq = arg;
+
+       return __load_balance_iterator(cfs_rq, cfs_rq->rb_load_balance_curr);
+}
+
+static int cfs_rq_best_prio(struct cfs_rq *cfs_rq)
+{
+       struct sched_entity *curr;
+       struct task_struct *p;
+
+       if (!cfs_rq->nr_running)
+               return MAX_PRIO;
+
+       curr = __pick_next_entity(cfs_rq);
+       p = task_of(curr);
+
+       return p->prio;
+}
+
+static int
+load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest,
+                       unsigned long max_nr_move, unsigned long max_load_move,
+                       struct sched_domain *sd, enum cpu_idle_type idle,
+                       int *all_pinned, unsigned long *total_load_moved)
+{
+       struct cfs_rq *busy_cfs_rq;
+       unsigned long load_moved, total_nr_moved = 0, nr_moved;
+       long rem_load_move = max_load_move;
+       struct rq_iterator cfs_rq_iterator;
+
+       cfs_rq_iterator.start = load_balance_start_fair;
+       cfs_rq_iterator.next = load_balance_next_fair;
+
+       for_each_leaf_cfs_rq(busiest, busy_cfs_rq) {
+               struct cfs_rq *this_cfs_rq;
+               long imbalance;
+               unsigned long maxload;
+               int this_best_prio, best_prio, best_prio_seen = 0;
+
+               this_cfs_rq = cpu_cfs_rq(busy_cfs_rq, this_cpu);
+
+               imbalance = busy_cfs_rq->load.weight -
+                                                this_cfs_rq->load.weight;
+               /* Don't pull if this_cfs_rq has more load than busy_cfs_rq */
+               if (imbalance <= 0)
+                       continue;
+
+               /* Don't pull more than imbalance/2 */
+               imbalance /= 2;
+               maxload = min(rem_load_move, imbalance);
+
+               this_best_prio = cfs_rq_best_prio(this_cfs_rq);
+               best_prio = cfs_rq_best_prio(busy_cfs_rq);
+
+               /*
+                * Enable handling of the case where there is more than one task
+                * with the best priority. If the current running task is one
+                * of those with prio==best_prio we know it won't be moved
+                * and therefore it's safe to override the skip (based on load)
+                * of any task we find with that prio.
+                */
+               if (cfs_rq_curr(busy_cfs_rq) == &busiest->curr->se)
+                       best_prio_seen = 1;
+
+               /* pass busy_cfs_rq argument into
+                * load_balance_[start|next]_fair iterators
+                */
+               cfs_rq_iterator.arg = busy_cfs_rq;
+               nr_moved = balance_tasks(this_rq, this_cpu, busiest,
+                               max_nr_move, maxload, sd, idle, all_pinned,
+                               &load_moved, this_best_prio, best_prio,
+                               best_prio_seen, &cfs_rq_iterator);
+
+               total_nr_moved += nr_moved;
+               max_nr_move -= nr_moved;
+               rem_load_move -= load_moved;
+
+               if (max_nr_move <= 0 || rem_load_move <= 0)
+                       break;
+       }
+
+       *total_load_moved = max_load_move - rem_load_move;
+
+       return total_nr_moved;
+}
+
+/*
+ * scheduler tick hitting a task of our scheduling class:
+ */
+static void task_tick_fair(struct rq *rq, struct task_struct *curr)
+{
+       struct cfs_rq *cfs_rq;
+       struct sched_entity *se = &curr->se;
+
+       for_each_sched_entity(se) {
+               cfs_rq = cfs_rq_of(se);
+               entity_tick(cfs_rq, se);
+       }
+}
+
+/*
+ * Share the fairness runtime between parent and child, thus the
+ * total amount of pressure for CPU stays equal - new tasks
+ * get a chance to run but frequent forkers are not allowed to
+ * monopolize the CPU. Note: the parent runqueue is locked,
+ * the child is not running yet.
+ */
+static void task_new_fair(struct rq *rq, struct task_struct *p)
+{
+       struct cfs_rq *cfs_rq = task_cfs_rq(p);
+       struct sched_entity *se = &p->se;
+       u64 now = rq_clock(rq);
+
+       sched_info_queued(p);
+
+       update_stats_enqueue(cfs_rq, se, now);
+       /*
+        * Child runs first: we let it run before the parent
+        * until it reschedules once. We set up the key so that
+        * it will preempt the parent:
+        */
+       p->se.fair_key = current->se.fair_key -
+               niced_granularity(&rq->curr->se, sysctl_sched_granularity) - 1;
+       /*
+        * The first wait is dominated by the child-runs-first logic,
+        * so do not credit it with that waiting time yet:
+        */
+       if (sysctl_sched_features & SCHED_FEAT_SKIP_INITIAL)
+               p->se.wait_start_fair = 0;
+
+       /*
+        * The statistical average of wait_runtime is about
+        * -granularity/2, so initialize the task with that:
+        */
+       if (sysctl_sched_features & SCHED_FEAT_START_DEBIT)
+               p->se.wait_runtime = -(sysctl_sched_granularity / 2);
+
+       __enqueue_entity(cfs_rq, se);
+       inc_nr_running(p, rq, now);
+}
+
+#ifdef CONFIG_FAIR_GROUP_SCHED
+/* Account for a task changing its policy or group.
+ *
+ * This routine is mostly called to set cfs_rq->curr field when a task
+ * migrates between groups/classes.
+ */
+static void set_curr_task_fair(struct rq *rq)
+{
+       struct task_struct *curr = rq->curr;
+       struct sched_entity *se = &curr->se;
+       u64 now = rq_clock(rq);
+       struct cfs_rq *cfs_rq;
+
+       for_each_sched_entity(se) {
+               cfs_rq = cfs_rq_of(se);
+               set_next_entity(cfs_rq, se, now);
+       }
+}
+#else
+static void set_curr_task_fair(struct rq *rq)
+{
+}
+#endif
+
+/*
+ * All the scheduling class methods:
+ */
+struct sched_class fair_sched_class __read_mostly = {
+       .enqueue_task           = enqueue_task_fair,
+       .dequeue_task           = dequeue_task_fair,
+       .yield_task             = yield_task_fair,
+
+       .check_preempt_curr     = check_preempt_curr_fair,
+
+       .pick_next_task         = pick_next_task_fair,
+       .put_prev_task          = put_prev_task_fair,
+
+       .load_balance           = load_balance_fair,
+
+       .set_curr_task          = set_curr_task_fair,
+       .task_tick              = task_tick_fair,
+       .task_new               = task_new_fair,
+};
+
+#ifdef CONFIG_SCHED_DEBUG
+void print_cfs_stats(struct seq_file *m, int cpu, u64 now)
+{
+       struct rq *rq = cpu_rq(cpu);
+       struct cfs_rq *cfs_rq;
+
+       for_each_leaf_cfs_rq(rq, cfs_rq)
+               print_cfs_rq(m, cpu, cfs_rq, now);
+}
+#endif
diff --git a/kernel/sched_idletask.c b/kernel/sched_idletask.c
new file mode 100644 (file)
index 0000000..41841e7
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * idle-task scheduling class.
+ *
+ * (NOTE: these are not related to SCHED_IDLE tasks which are
+ *  handled in sched_fair.c)
+ */
+
+/*
+ * Idle tasks are unconditionally rescheduled:
+ */
+static void check_preempt_curr_idle(struct rq *rq, struct task_struct *p)
+{
+       resched_task(rq->idle);
+}
+
+static struct task_struct *pick_next_task_idle(struct rq *rq, u64 now)
+{
+       schedstat_inc(rq, sched_goidle);
+
+       return rq->idle;
+}
+
+/*
+ * It is not legal to sleep in the idle task - print a warning
+ * message if some code attempts to do it:
+ */
+static void
+dequeue_task_idle(struct rq *rq, struct task_struct *p, int sleep, u64 now)
+{
+       spin_unlock_irq(&rq->lock);
+       printk(KERN_ERR "bad: scheduling from the idle thread!\n");
+       dump_stack();
+       spin_lock_irq(&rq->lock);
+}
+
+static void put_prev_task_idle(struct rq *rq, struct task_struct *prev, u64 now)
+{
+}
+
+static int
+load_balance_idle(struct rq *this_rq, int this_cpu, struct rq *busiest,
+                       unsigned long max_nr_move, unsigned long max_load_move,
+                       struct sched_domain *sd, enum cpu_idle_type idle,
+                       int *all_pinned, unsigned long *total_load_moved)
+{
+       return 0;
+}
+
+static void task_tick_idle(struct rq *rq, struct task_struct *curr)
+{
+}
+
+/*
+ * Simple, special scheduling class for the per-CPU idle tasks:
+ */
+static struct sched_class idle_sched_class __read_mostly = {
+       /* no enqueue/yield_task for idle tasks */
+
+       /* dequeue is not valid, we print a debug message there: */
+       .dequeue_task           = dequeue_task_idle,
+
+       .check_preempt_curr     = check_preempt_curr_idle,
+
+       .pick_next_task         = pick_next_task_idle,
+       .put_prev_task          = put_prev_task_idle,
+
+       .load_balance           = load_balance_idle,
+
+       .task_tick              = task_tick_idle,
+       /* no .task_new for idle tasks */
+};
diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c
new file mode 100644 (file)
index 0000000..1192a27
--- /dev/null
@@ -0,0 +1,255 @@
+/*
+ * Real-Time Scheduling Class (mapped to the SCHED_FIFO and SCHED_RR
+ * policies)
+ */
+
+/*
+ * Update the current task's runtime statistics. Skip current tasks that
+ * are not in our scheduling class.
+ */
+static inline void update_curr_rt(struct rq *rq, u64 now)
+{
+       struct task_struct *curr = rq->curr;
+       u64 delta_exec;
+
+       if (!task_has_rt_policy(curr))
+               return;
+
+       delta_exec = now - curr->se.exec_start;
+       if (unlikely((s64)delta_exec < 0))
+               delta_exec = 0;
+       if (unlikely(delta_exec > curr->se.exec_max))
+               curr->se.exec_max = delta_exec;
+
+       curr->se.sum_exec_runtime += delta_exec;
+       curr->se.exec_start = now;
+}
+
+static void
+enqueue_task_rt(struct rq *rq, struct task_struct *p, int wakeup, u64 now)
+{
+       struct rt_prio_array *array = &rq->rt.active;
+
+       list_add_tail(&p->run_list, array->queue + p->prio);
+       __set_bit(p->prio, array->bitmap);
+}
+
+/*
+ * Adding/removing a task to/from a priority array:
+ */
+static void
+dequeue_task_rt(struct rq *rq, struct task_struct *p, int sleep, u64 now)
+{
+       struct rt_prio_array *array = &rq->rt.active;
+
+       update_curr_rt(rq, now);
+
+       list_del(&p->run_list);
+       if (list_empty(array->queue + p->prio))
+               __clear_bit(p->prio, array->bitmap);
+}
+
+/*
+ * Put task to the end of the run list without the overhead of dequeue
+ * followed by enqueue.
+ */
+static void requeue_task_rt(struct rq *rq, struct task_struct *p)
+{
+       struct rt_prio_array *array = &rq->rt.active;
+
+       list_move_tail(&p->run_list, array->queue + p->prio);
+}
+
+static void
+yield_task_rt(struct rq *rq, struct task_struct *p)
+{
+       requeue_task_rt(rq, p);
+}
+
+/*
+ * Preempt the current task with a newly woken task if needed:
+ */
+static void check_preempt_curr_rt(struct rq *rq, struct task_struct *p)
+{
+       if (p->prio < rq->curr->prio)
+               resched_task(rq->curr);
+}
+
+static struct task_struct *pick_next_task_rt(struct rq *rq, u64 now)
+{
+       struct rt_prio_array *array = &rq->rt.active;
+       struct task_struct *next;
+       struct list_head *queue;
+       int idx;
+
+       idx = sched_find_first_bit(array->bitmap);
+       if (idx >= MAX_RT_PRIO)
+               return NULL;
+
+       queue = array->queue + idx;
+       next = list_entry(queue->next, struct task_struct, run_list);
+
+       next->se.exec_start = now;
+
+       return next;
+}
+
+static void put_prev_task_rt(struct rq *rq, struct task_struct *p, u64 now)
+{
+       update_curr_rt(rq, now);
+       p->se.exec_start = 0;
+}
+
+/*
+ * Load-balancing iterator. Note: while the runqueue stays locked
+ * during the whole iteration, the current task might be
+ * dequeued so the iterator has to be dequeue-safe. Here we
+ * achieve that by always pre-iterating before returning
+ * the current task:
+ */
+static struct task_struct *load_balance_start_rt(void *arg)
+{
+       struct rq *rq = arg;
+       struct rt_prio_array *array = &rq->rt.active;
+       struct list_head *head, *curr;
+       struct task_struct *p;
+       int idx;
+
+       idx = sched_find_first_bit(array->bitmap);
+       if (idx >= MAX_RT_PRIO)
+               return NULL;
+
+       head = array->queue + idx;
+       curr = head->prev;
+
+       p = list_entry(curr, struct task_struct, run_list);
+
+       curr = curr->prev;
+
+       rq->rt.rt_load_balance_idx = idx;
+       rq->rt.rt_load_balance_head = head;
+       rq->rt.rt_load_balance_curr = curr;
+
+       return p;
+}
+
+static struct task_struct *load_balance_next_rt(void *arg)
+{
+       struct rq *rq = arg;
+       struct rt_prio_array *array = &rq->rt.active;
+       struct list_head *head, *curr;
+       struct task_struct *p;
+       int idx;
+
+       idx = rq->rt.rt_load_balance_idx;
+       head = rq->rt.rt_load_balance_head;
+       curr = rq->rt.rt_load_balance_curr;
+
+       /*
+        * If we arrived back to the head again then
+        * iterate to the next queue (if any):
+        */
+       if (unlikely(head == curr)) {
+               int next_idx = find_next_bit(array->bitmap, MAX_RT_PRIO, idx+1);
+
+               if (next_idx >= MAX_RT_PRIO)
+                       return NULL;
+
+               idx = next_idx;
+               head = array->queue + idx;
+               curr = head->prev;
+
+               rq->rt.rt_load_balance_idx = idx;
+               rq->rt.rt_load_balance_head = head;
+       }
+
+       p = list_entry(curr, struct task_struct, run_list);
+
+       curr = curr->prev;
+
+       rq->rt.rt_load_balance_curr = curr;
+
+       return p;
+}
+
+static int
+load_balance_rt(struct rq *this_rq, int this_cpu, struct rq *busiest,
+                       unsigned long max_nr_move, unsigned long max_load_move,
+                       struct sched_domain *sd, enum cpu_idle_type idle,
+                       int *all_pinned, unsigned long *load_moved)
+{
+       int this_best_prio, best_prio, best_prio_seen = 0;
+       int nr_moved;
+       struct rq_iterator rt_rq_iterator;
+
+       best_prio = sched_find_first_bit(busiest->rt.active.bitmap);
+       this_best_prio = sched_find_first_bit(this_rq->rt.active.bitmap);
+
+       /*
+        * Enable handling of the case where there is more than one task
+        * with the best priority.   If the current running task is one
+        * of those with prio==best_prio we know it won't be moved
+        * and therefore it's safe to override the skip (based on load)
+        * of any task we find with that prio.
+        */
+       if (busiest->curr->prio == best_prio)
+               best_prio_seen = 1;
+
+       rt_rq_iterator.start = load_balance_start_rt;
+       rt_rq_iterator.next = load_balance_next_rt;
+       /* pass 'busiest' rq argument into
+        * load_balance_[start|next]_rt iterators
+        */
+       rt_rq_iterator.arg = busiest;
+
+       nr_moved = balance_tasks(this_rq, this_cpu, busiest, max_nr_move,
+                       max_load_move, sd, idle, all_pinned, load_moved,
+                       this_best_prio, best_prio, best_prio_seen,
+                       &rt_rq_iterator);
+
+       return nr_moved;
+}
+
+static void task_tick_rt(struct rq *rq, struct task_struct *p)
+{
+       /*
+        * RR tasks need a special form of timeslice management.
+        * FIFO tasks have no timeslices.
+        */
+       if (p->policy != SCHED_RR)
+               return;
+
+       if (--p->time_slice)
+               return;
+
+       p->time_slice = static_prio_timeslice(p->static_prio);
+       set_tsk_need_resched(p);
+
+       /* put it at the end of the queue: */
+       requeue_task_rt(rq, p);
+}
+
+/*
+ * No parent/child timeslice management necessary for RT tasks,
+ * just activate them:
+ */
+static void task_new_rt(struct rq *rq, struct task_struct *p)
+{
+       activate_task(rq, p, 1);
+}
+
+static struct sched_class rt_sched_class __read_mostly = {
+       .enqueue_task           = enqueue_task_rt,
+       .dequeue_task           = dequeue_task_rt,
+       .yield_task             = yield_task_rt,
+
+       .check_preempt_curr     = check_preempt_curr_rt,
+
+       .pick_next_task         = pick_next_task_rt,
+       .put_prev_task          = put_prev_task_rt,
+
+       .load_balance           = load_balance_rt,
+
+       .task_tick              = task_tick_rt,
+       .task_new               = task_new_rt,
+};
diff --git a/kernel/sched_stats.h b/kernel/sched_stats.h
new file mode 100644 (file)
index 0000000..c63c38f
--- /dev/null
@@ -0,0 +1,235 @@
+
+#ifdef CONFIG_SCHEDSTATS
+/*
+ * bump this up when changing the output format or the meaning of an existing
+ * format, so that tools can adapt (or abort)
+ */
+#define SCHEDSTAT_VERSION 14
+
+static int show_schedstat(struct seq_file *seq, void *v)
+{
+       int cpu;
+
+       seq_printf(seq, "version %d\n", SCHEDSTAT_VERSION);
+       seq_printf(seq, "timestamp %lu\n", jiffies);
+       for_each_online_cpu(cpu) {
+               struct rq *rq = cpu_rq(cpu);
+#ifdef CONFIG_SMP
+               struct sched_domain *sd;
+               int dcnt = 0;
+#endif
+
+               /* runqueue-specific stats */
+               seq_printf(seq,
+                   "cpu%d %lu %lu %lu %lu %lu %lu %lu %lu %lu %llu %llu %lu",
+                   cpu, rq->yld_both_empty,
+                   rq->yld_act_empty, rq->yld_exp_empty, rq->yld_cnt,
+                   rq->sched_switch, rq->sched_cnt, rq->sched_goidle,
+                   rq->ttwu_cnt, rq->ttwu_local,
+                   rq->rq_sched_info.cpu_time,
+                   rq->rq_sched_info.run_delay, rq->rq_sched_info.pcnt);
+
+               seq_printf(seq, "\n");
+
+#ifdef CONFIG_SMP
+               /* domain-specific stats */
+               preempt_disable();
+               for_each_domain(cpu, sd) {
+                       enum cpu_idle_type itype;
+                       char mask_str[NR_CPUS];
+
+                       cpumask_scnprintf(mask_str, NR_CPUS, sd->span);
+                       seq_printf(seq, "domain%d %s", dcnt++, mask_str);
+                       for (itype = CPU_IDLE; itype < CPU_MAX_IDLE_TYPES;
+                                       itype++) {
+                               seq_printf(seq, " %lu %lu %lu %lu %lu %lu %lu "
+                                               "%lu",
+                                   sd->lb_cnt[itype],
+                                   sd->lb_balanced[itype],
+                                   sd->lb_failed[itype],
+                                   sd->lb_imbalance[itype],
+                                   sd->lb_gained[itype],
+                                   sd->lb_hot_gained[itype],
+                                   sd->lb_nobusyq[itype],
+                                   sd->lb_nobusyg[itype]);
+                       }
+                       seq_printf(seq, " %lu %lu %lu %lu %lu %lu %lu %lu %lu"
+                           " %lu %lu %lu\n",
+                           sd->alb_cnt, sd->alb_failed, sd->alb_pushed,
+                           sd->sbe_cnt, sd->sbe_balanced, sd->sbe_pushed,
+                           sd->sbf_cnt, sd->sbf_balanced, sd->sbf_pushed,
+                           sd->ttwu_wake_remote, sd->ttwu_move_affine,
+                           sd->ttwu_move_balance);
+               }
+               preempt_enable();
+#endif
+       }
+       return 0;
+}
+
+static int schedstat_open(struct inode *inode, struct file *file)
+{
+       unsigned int size = PAGE_SIZE * (1 + num_online_cpus() / 32);
+       char *buf = kmalloc(size, GFP_KERNEL);
+       struct seq_file *m;
+       int res;
+
+       if (!buf)
+               return -ENOMEM;
+       res = single_open(file, show_schedstat, NULL);
+       if (!res) {
+               m = file->private_data;
+               m->buf = buf;
+               m->size = size;
+       } else
+               kfree(buf);
+       return res;
+}
+
+const struct file_operations proc_schedstat_operations = {
+       .open    = schedstat_open,
+       .read    = seq_read,
+       .llseek  = seq_lseek,
+       .release = single_release,
+};
+
+/*
+ * Expects runqueue lock to be held for atomicity of update
+ */
+static inline void
+rq_sched_info_arrive(struct rq *rq, unsigned long long delta)
+{
+       if (rq) {
+               rq->rq_sched_info.run_delay += delta;
+               rq->rq_sched_info.pcnt++;
+       }
+}
+
+/*
+ * Expects runqueue lock to be held for atomicity of update
+ */
+static inline void
+rq_sched_info_depart(struct rq *rq, unsigned long long delta)
+{
+       if (rq)
+               rq->rq_sched_info.cpu_time += delta;
+}
+# define schedstat_inc(rq, field)      do { (rq)->field++; } while (0)
+# define schedstat_add(rq, field, amt) do { (rq)->field += (amt); } while (0)
+#else /* !CONFIG_SCHEDSTATS */
+static inline void
+rq_sched_info_arrive(struct rq *rq, unsigned long long delta)
+{}
+static inline void
+rq_sched_info_depart(struct rq *rq, unsigned long long delta)
+{}
+# define schedstat_inc(rq, field)      do { } while (0)
+# define schedstat_add(rq, field, amt) do { } while (0)
+#endif
+
+#if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT)
+/*
+ * Called when a process is dequeued from the active array and given
+ * the cpu.  We should note that with the exception of interactive
+ * tasks, the expired queue will become the active queue after the active
+ * queue is empty, without explicitly dequeuing and requeuing tasks in the
+ * expired queue.  (Interactive tasks may be requeued directly to the
+ * active queue, thus delaying tasks in the expired queue from running;
+ * see scheduler_tick()).
+ *
+ * This function is only called from sched_info_arrive(), rather than
+ * dequeue_task(). Even though a task may be queued and dequeued multiple
+ * times as it is shuffled about, we're really interested in knowing how
+ * long it was from the *first* time it was queued to the time that it
+ * finally hit a cpu.
+ */
+static inline void sched_info_dequeued(struct task_struct *t)
+{
+       t->sched_info.last_queued = 0;
+}
+
+/*
+ * Called when a task finally hits the cpu.  We can now calculate how
+ * long it was waiting to run.  We also note when it began so that we
+ * can keep stats on how long its timeslice is.
+ */
+static void sched_info_arrive(struct task_struct *t)
+{
+       unsigned long long now = sched_clock(), delta = 0;
+
+       if (t->sched_info.last_queued)
+               delta = now - t->sched_info.last_queued;
+       sched_info_dequeued(t);
+       t->sched_info.run_delay += delta;
+       t->sched_info.last_arrival = now;
+       t->sched_info.pcnt++;
+
+       rq_sched_info_arrive(task_rq(t), delta);
+}
+
+/*
+ * Called when a process is queued into either the active or expired
+ * array.  The time is noted and later used to determine how long we
+ * had to wait for us to reach the cpu.  Since the expired queue will
+ * become the active queue after active queue is empty, without dequeuing
+ * and requeuing any tasks, we are interested in queuing to either. It
+ * is unusual but not impossible for tasks to be dequeued and immediately
+ * requeued in the same or another array: this can happen in sched_yield(),
+ * set_user_nice(), and even load_balance() as it moves tasks from runqueue
+ * to runqueue.
+ *
+ * This function is only called from enqueue_task(), but also only updates
+ * the timestamp if it is already not set.  It's assumed that
+ * sched_info_dequeued() will clear that stamp when appropriate.
+ */
+static inline void sched_info_queued(struct task_struct *t)
+{
+       if (unlikely(sched_info_on()))
+               if (!t->sched_info.last_queued)
+                       t->sched_info.last_queued = sched_clock();
+}
+
+/*
+ * Called when a process ceases being the active-running process, either
+ * voluntarily or involuntarily.  Now we can calculate how long we ran.
+ */
+static inline void sched_info_depart(struct task_struct *t)
+{
+       unsigned long long delta = sched_clock() - t->sched_info.last_arrival;
+
+       t->sched_info.cpu_time += delta;
+       rq_sched_info_depart(task_rq(t), delta);
+}
+
+/*
+ * Called when tasks are switched involuntarily due, typically, to expiring
+ * their time slice.  (This may also be called when switching to or from
+ * the idle task.)  We are only called when prev != next.
+ */
+static inline void
+__sched_info_switch(struct task_struct *prev, struct task_struct *next)
+{
+       struct rq *rq = task_rq(prev);
+
+       /*
+        * prev now departs the cpu.  It's not interesting to record
+        * stats about how efficient we were at scheduling the idle
+        * process, however.
+        */
+       if (prev != rq->idle)
+               sched_info_depart(prev);
+
+       if (next != rq->idle)
+               sched_info_arrive(next);
+}
+static inline void
+sched_info_switch(struct task_struct *prev, struct task_struct *next)
+{
+       if (unlikely(sched_info_on()))
+               __sched_info_switch(prev, next);
+}
+#else
+#define sched_info_queued(t)           do { } while (0)
+#define sched_info_switch(t, next)     do { } while (0)
+#endif /* CONFIG_SCHEDSTATS || CONFIG_TASK_DELAY_ACCT */
+
index 0b9886a00e74ba33ed59cafb8b02bc9d01570575..73217a9e2875b27909cb4c9db09a6ec2d4284a7c 100644 (file)
@@ -488,7 +488,6 @@ void __init softirq_init(void)
 
 static int ksoftirqd(void * __bind_cpu)
 {
-       set_user_nice(current, 19);
        current->flags |= PF_NOFREEZE;
 
        set_current_state(TASK_INTERRUPTIBLE);
index 30ee462ee79f8646eace494e5244ddaace7f5d95..d93e13d93f24c0c25d0bfc9cfe4944cd239fc10f 100644 (file)
@@ -206,7 +206,87 @@ static ctl_table root_table[] = {
        { .ctl_name = 0 }
 };
 
+#ifdef CONFIG_SCHED_DEBUG
+static unsigned long min_sched_granularity_ns = 100000;                /* 100 usecs */
+static unsigned long max_sched_granularity_ns = 1000000000;    /* 1 second */
+static unsigned long min_wakeup_granularity_ns;                        /* 0 usecs */
+static unsigned long max_wakeup_granularity_ns = 1000000000;   /* 1 second */
+#endif
+
 static ctl_table kern_table[] = {
+#ifdef CONFIG_SCHED_DEBUG
+       {
+               .ctl_name       = CTL_UNNUMBERED,
+               .procname       = "sched_granularity_ns",
+               .data           = &sysctl_sched_granularity,
+               .maxlen         = sizeof(unsigned int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec_minmax,
+               .strategy       = &sysctl_intvec,
+               .extra1         = &min_sched_granularity_ns,
+               .extra2         = &max_sched_granularity_ns,
+       },
+       {
+               .ctl_name       = CTL_UNNUMBERED,
+               .procname       = "sched_wakeup_granularity_ns",
+               .data           = &sysctl_sched_wakeup_granularity,
+               .maxlen         = sizeof(unsigned int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec_minmax,
+               .strategy       = &sysctl_intvec,
+               .extra1         = &min_wakeup_granularity_ns,
+               .extra2         = &max_wakeup_granularity_ns,
+       },
+       {
+               .ctl_name       = CTL_UNNUMBERED,
+               .procname       = "sched_batch_wakeup_granularity_ns",
+               .data           = &sysctl_sched_batch_wakeup_granularity,
+               .maxlen         = sizeof(unsigned int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec_minmax,
+               .strategy       = &sysctl_intvec,
+               .extra1         = &min_wakeup_granularity_ns,
+               .extra2         = &max_wakeup_granularity_ns,
+       },
+       {
+               .ctl_name       = CTL_UNNUMBERED,
+               .procname       = "sched_stat_granularity_ns",
+               .data           = &sysctl_sched_stat_granularity,
+               .maxlen         = sizeof(unsigned int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec_minmax,
+               .strategy       = &sysctl_intvec,
+               .extra1         = &min_wakeup_granularity_ns,
+               .extra2         = &max_wakeup_granularity_ns,
+       },
+       {
+               .ctl_name       = CTL_UNNUMBERED,
+               .procname       = "sched_runtime_limit_ns",
+               .data           = &sysctl_sched_runtime_limit,
+               .maxlen         = sizeof(unsigned int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec_minmax,
+               .strategy       = &sysctl_intvec,
+               .extra1         = &min_sched_granularity_ns,
+               .extra2         = &max_sched_granularity_ns,
+       },
+       {
+               .ctl_name       = CTL_UNNUMBERED,
+               .procname       = "sched_child_runs_first",
+               .data           = &sysctl_sched_child_runs_first,
+               .maxlen         = sizeof(unsigned int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec,
+       },
+       {
+               .ctl_name       = CTL_UNNUMBERED,
+               .procname       = "sched_features",
+               .data           = &sysctl_sched_features,
+               .maxlen         = sizeof(unsigned int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec,
+       },
+#endif
        {
                .ctl_name       = KERN_PANIC,
                .procname       = "panic",
@@ -869,6 +949,16 @@ static ctl_table vm_table[] = {
                .strategy       = &sysctl_jiffies,
        },
 #endif
+#ifdef CONFIG_SECURITY
+       {
+               .ctl_name       = CTL_UNNUMBERED,
+               .procname       = "mmap_min_addr",
+               .data           = &mmap_min_addr,
+               .maxlen         = sizeof(unsigned long),
+               .mode           = 0644,
+               .proc_handler   = &proc_doulongvec_minmax,
+       },
+#endif
 #if defined(CONFIG_X86_32) || \
    (defined(CONFIG_SUPERH) && defined(CONFIG_VSYSCALL))
        {
index 2e7ae6b9215b2d390d30171c4e61e000f7079705..3eb29d5dc4f56d3ba66553a8cd053185610b2c0d 100644 (file)
@@ -64,6 +64,12 @@ config ZLIB_INFLATE
 config ZLIB_DEFLATE
        tristate
 
+config LZO_COMPRESS
+       tristate
+
+config LZO_DECOMPRESS
+       tristate
+
 #
 # Generic allocator support is selected if needed
 #
index da95e10cfd7094e8996ab08bb38c1f1bd5d4d6f9..fab32a2863710a328b5f41dc7498515fb7d55b5e 100644 (file)
@@ -105,6 +105,15 @@ config DETECT_SOFTLOCKUP
           can be detected via the NMI-watchdog, on platforms that
           support it.)
 
+config SCHED_DEBUG
+       bool "Collect scheduler debugging info"
+       depends on DEBUG_KERNEL && PROC_FS
+       default y
+       help
+         If you say Y here, the /proc/sched_debug file will be provided
+         that can help debug the scheduler. The runtime overhead of this
+         option is minimal.
+
 config SCHEDSTATS
        bool "Collect scheduler statistics"
        depends on DEBUG_KERNEL && PROC_FS
index c8c8e20784cecf24aefc24406a164589ff020627..d1b366bdf86ed6a0cc8809d562f90b1309103227 100644 (file)
@@ -49,6 +49,8 @@ obj-$(CONFIG_GENERIC_ALLOCATOR) += genalloc.o
 obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate/
 obj-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate/
 obj-$(CONFIG_REED_SOLOMON) += reed_solomon/
+obj-$(CONFIG_LZO_COMPRESS) += lzo/
+obj-$(CONFIG_LZO_DECOMPRESS) += lzo/
 
 obj-$(CONFIG_TEXTSEARCH) += textsearch.o
 obj-$(CONFIG_TEXTSEARCH_KMP) += ts_kmp.o
index 305117ca2d415a1adf91700fe34a06d88028de67..b98f01a2eb946b221f5d7d7d193422f95e607a3a 100644 (file)
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -70,6 +70,26 @@ static void free_layer(struct idr *idp, struct idr_layer *p)
        spin_unlock_irqrestore(&idp->lock, flags);
 }
 
+static void idr_mark_full(struct idr_layer **pa, int id)
+{
+       struct idr_layer *p = pa[0];
+       int l = 0;
+
+       __set_bit(id & IDR_MASK, &p->bitmap);
+       /*
+        * If this layer is full mark the bit in the layer above to
+        * show that this part of the radix tree is full.  This may
+        * complete the layer above and require walking up the radix
+        * tree.
+        */
+       while (p->bitmap == IDR_FULL) {
+               if (!(p = pa[++l]))
+                       break;
+               id = id >> IDR_BITS;
+               __set_bit((id & IDR_MASK), &p->bitmap);
+       }
+}
+
 /**
  * idr_pre_get - reserver resources for idr allocation
  * @idp:       idr handle
@@ -95,15 +115,15 @@ int idr_pre_get(struct idr *idp, gfp_t gfp_mask)
 }
 EXPORT_SYMBOL(idr_pre_get);
 
-static int sub_alloc(struct idr *idp, void *ptr, int *starting_id)
+static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa)
 {
        int n, m, sh;
        struct idr_layer *p, *new;
-       struct idr_layer *pa[MAX_LEVEL];
-       int l, id;
+       int l, id, oid;
        long bm;
 
        id = *starting_id;
+ restart:
        p = idp->top;
        l = idp->layers;
        pa[l--] = NULL;
@@ -117,12 +137,23 @@ static int sub_alloc(struct idr *idp, void *ptr, int *starting_id)
                if (m == IDR_SIZE) {
                        /* no space available go back to previous layer. */
                        l++;
+                       oid = id;
                        id = (id | ((1 << (IDR_BITS * l)) - 1)) + 1;
+
+                       /* if already at the top layer, we need to grow */
                        if (!(p = pa[l])) {
                                *starting_id = id;
                                return -2;
                        }
-                       continue;
+
+                       /* If we need to go up one layer, continue the
+                        * loop; otherwise, restart from the top.
+                        */
+                       sh = IDR_BITS * (l + 1);
+                       if (oid >> sh == id >> sh)
+                               continue;
+                       else
+                               goto restart;
                }
                if (m != n) {
                        sh = IDR_BITS*l;
@@ -144,30 +175,13 @@ static int sub_alloc(struct idr *idp, void *ptr, int *starting_id)
                pa[l--] = p;
                p = p->ary[m];
        }
-       /*
-        * We have reached the leaf node, plant the
-        * users pointer and return the raw id.
-        */
-       p->ary[m] = (struct idr_layer *)ptr;
-       __set_bit(m, &p->bitmap);
-       p->count++;
-       /*
-        * If this layer is full mark the bit in the layer above
-        * to show that this part of the radix tree is full.
-        * This may complete the layer above and require walking
-        * up the radix tree.
-        */
-       n = id;
-       while (p->bitmap == IDR_FULL) {
-               if (!(p = pa[++l]))
-                       break;
-               n = n >> IDR_BITS;
-               __set_bit((n & IDR_MASK), &p->bitmap);
-       }
-       return(id);
+
+       pa[l] = p;
+       return id;
 }
 
-static int idr_get_new_above_int(struct idr *idp, void *ptr, int starting_id)
+static int idr_get_empty_slot(struct idr *idp, int starting_id,
+                             struct idr_layer **pa)
 {
        struct idr_layer *p, *new;
        int layers, v, id;
@@ -213,12 +227,31 @@ build_up:
        }
        idp->top = p;
        idp->layers = layers;
-       v = sub_alloc(idp, ptr, &id);
+       v = sub_alloc(idp, &id, pa);
        if (v == -2)
                goto build_up;
        return(v);
 }
 
+static int idr_get_new_above_int(struct idr *idp, void *ptr, int starting_id)
+{
+       struct idr_layer *pa[MAX_LEVEL];
+       int id;
+
+       id = idr_get_empty_slot(idp, starting_id, pa);
+       if (id >= 0) {
+               /*
+                * Successfully found an empty slot.  Install the user
+                * pointer and mark the slot full.
+                */
+               pa[0]->ary[id & IDR_MASK] = (struct idr_layer *)ptr;
+               pa[0]->count++;
+               idr_mark_full(pa, id);
+       }
+
+       return id;
+}
+
 /**
  * idr_get_new_above - allocate new idr entry above or equal to a start id
  * @idp: idr handle
@@ -473,3 +506,248 @@ void idr_init(struct idr *idp)
        spin_lock_init(&idp->lock);
 }
 EXPORT_SYMBOL(idr_init);
+
+
+/*
+ * IDA - IDR based ID allocator
+ *
+ * this is id allocator without id -> pointer translation.  Memory
+ * usage is much lower than full blown idr because each id only
+ * occupies a bit.  ida uses a custom leaf node which contains
+ * IDA_BITMAP_BITS slots.
+ *
+ * 2007-04-25  written by Tejun Heo <htejun@gmail.com>
+ */
+
+static void free_bitmap(struct ida *ida, struct ida_bitmap *bitmap)
+{
+       unsigned long flags;
+
+       if (!ida->free_bitmap) {
+               spin_lock_irqsave(&ida->idr.lock, flags);
+               if (!ida->free_bitmap) {
+                       ida->free_bitmap = bitmap;
+                       bitmap = NULL;
+               }
+               spin_unlock_irqrestore(&ida->idr.lock, flags);
+       }
+
+       kfree(bitmap);
+}
+
+/**
+ * ida_pre_get - reserve resources for ida allocation
+ * @ida:       ida handle
+ * @gfp_mask:  memory allocation flag
+ *
+ * This function should be called prior to locking and calling the
+ * following function.  It preallocates enough memory to satisfy the
+ * worst possible allocation.
+ *
+ * If the system is REALLY out of memory this function returns 0,
+ * otherwise 1.
+ */
+int ida_pre_get(struct ida *ida, gfp_t gfp_mask)
+{
+       /* allocate idr_layers */
+       if (!idr_pre_get(&ida->idr, gfp_mask))
+               return 0;
+
+       /* allocate free_bitmap */
+       if (!ida->free_bitmap) {
+               struct ida_bitmap *bitmap;
+
+               bitmap = kmalloc(sizeof(struct ida_bitmap), gfp_mask);
+               if (!bitmap)
+                       return 0;
+
+               free_bitmap(ida, bitmap);
+       }
+
+       return 1;
+}
+EXPORT_SYMBOL(ida_pre_get);
+
+/**
+ * ida_get_new_above - allocate new ID above or equal to a start id
+ * @ida:       ida handle
+ * @staring_id:        id to start search at
+ * @p_id:      pointer to the allocated handle
+ *
+ * Allocate new ID above or equal to @ida.  It should be called with
+ * any required locks.
+ *
+ * If memory is required, it will return -EAGAIN, you should unlock
+ * and go back to the ida_pre_get() call.  If the ida is full, it will
+ * return -ENOSPC.
+ *
+ * @p_id returns a value in the range 0 ... 0x7fffffff.
+ */
+int ida_get_new_above(struct ida *ida, int starting_id, int *p_id)
+{
+       struct idr_layer *pa[MAX_LEVEL];
+       struct ida_bitmap *bitmap;
+       unsigned long flags;
+       int idr_id = starting_id / IDA_BITMAP_BITS;
+       int offset = starting_id % IDA_BITMAP_BITS;
+       int t, id;
+
+ restart:
+       /* get vacant slot */
+       t = idr_get_empty_slot(&ida->idr, idr_id, pa);
+       if (t < 0) {
+               if (t == -1)
+                       return -EAGAIN;
+               else /* will be -3 */
+                       return -ENOSPC;
+       }
+
+       if (t * IDA_BITMAP_BITS >= MAX_ID_BIT)
+               return -ENOSPC;
+
+       if (t != idr_id)
+               offset = 0;
+       idr_id = t;
+
+       /* if bitmap isn't there, create a new one */
+       bitmap = (void *)pa[0]->ary[idr_id & IDR_MASK];
+       if (!bitmap) {
+               spin_lock_irqsave(&ida->idr.lock, flags);
+               bitmap = ida->free_bitmap;
+               ida->free_bitmap = NULL;
+               spin_unlock_irqrestore(&ida->idr.lock, flags);
+
+               if (!bitmap)
+                       return -EAGAIN;
+
+               memset(bitmap, 0, sizeof(struct ida_bitmap));
+               pa[0]->ary[idr_id & IDR_MASK] = (void *)bitmap;
+               pa[0]->count++;
+       }
+
+       /* lookup for empty slot */
+       t = find_next_zero_bit(bitmap->bitmap, IDA_BITMAP_BITS, offset);
+       if (t == IDA_BITMAP_BITS) {
+               /* no empty slot after offset, continue to the next chunk */
+               idr_id++;
+               offset = 0;
+               goto restart;
+       }
+
+       id = idr_id * IDA_BITMAP_BITS + t;
+       if (id >= MAX_ID_BIT)
+               return -ENOSPC;
+
+       __set_bit(t, bitmap->bitmap);
+       if (++bitmap->nr_busy == IDA_BITMAP_BITS)
+               idr_mark_full(pa, idr_id);
+
+       *p_id = id;
+
+       /* Each leaf node can handle nearly a thousand slots and the
+        * whole idea of ida is to have small memory foot print.
+        * Throw away extra resources one by one after each successful
+        * allocation.
+        */
+       if (ida->idr.id_free_cnt || ida->free_bitmap) {
+               struct idr_layer *p = alloc_layer(&ida->idr);
+               if (p)
+                       kmem_cache_free(idr_layer_cache, p);
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(ida_get_new_above);
+
+/**
+ * ida_get_new - allocate new ID
+ * @ida:       idr handle
+ * @p_id:      pointer to the allocated handle
+ *
+ * Allocate new ID.  It should be called with any required locks.
+ *
+ * If memory is required, it will return -EAGAIN, you should unlock
+ * and go back to the idr_pre_get() call.  If the idr is full, it will
+ * return -ENOSPC.
+ *
+ * @id returns a value in the range 0 ... 0x7fffffff.
+ */
+int ida_get_new(struct ida *ida, int *p_id)
+{
+       return ida_get_new_above(ida, 0, p_id);
+}
+EXPORT_SYMBOL(ida_get_new);
+
+/**
+ * ida_remove - remove the given ID
+ * @ida:       ida handle
+ * @id:                ID to free
+ */
+void ida_remove(struct ida *ida, int id)
+{
+       struct idr_layer *p = ida->idr.top;
+       int shift = (ida->idr.layers - 1) * IDR_BITS;
+       int idr_id = id / IDA_BITMAP_BITS;
+       int offset = id % IDA_BITMAP_BITS;
+       int n;
+       struct ida_bitmap *bitmap;
+
+       /* clear full bits while looking up the leaf idr_layer */
+       while ((shift > 0) && p) {
+               n = (idr_id >> shift) & IDR_MASK;
+               __clear_bit(n, &p->bitmap);
+               p = p->ary[n];
+               shift -= IDR_BITS;
+       }
+
+       if (p == NULL)
+               goto err;
+
+       n = idr_id & IDR_MASK;
+       __clear_bit(n, &p->bitmap);
+
+       bitmap = (void *)p->ary[n];
+       if (!test_bit(offset, bitmap->bitmap))
+               goto err;
+
+       /* update bitmap and remove it if empty */
+       __clear_bit(offset, bitmap->bitmap);
+       if (--bitmap->nr_busy == 0) {
+               __set_bit(n, &p->bitmap);       /* to please idr_remove() */
+               idr_remove(&ida->idr, idr_id);
+               free_bitmap(ida, bitmap);
+       }
+
+       return;
+
+ err:
+       printk(KERN_WARNING
+              "ida_remove called for id=%d which is not allocated.\n", id);
+}
+EXPORT_SYMBOL(ida_remove);
+
+/**
+ * ida_destroy - release all cached layers within an ida tree
+ * ida:                ida handle
+ */
+void ida_destroy(struct ida *ida)
+{
+       idr_destroy(&ida->idr);
+       kfree(ida->free_bitmap);
+}
+EXPORT_SYMBOL(ida_destroy);
+
+/**
+ * ida_init - initialize ida handle
+ * @ida:       ida handle
+ *
+ * This function is use to set up the handle (@ida) that you will pass
+ * to the rest of the functions.
+ */
+void ida_init(struct ida *ida)
+{
+       memset(ida, 0, sizeof(struct ida));
+       idr_init(&ida->idr);
+
+}
+EXPORT_SYMBOL(ida_init);
index ac1520651b9b457d89e96bd2447aae02d6f8bb46..4b08e0ff95c8bf53745cd6d5257476e0d652b92c 100644 (file)
@@ -44,7 +44,7 @@ static int populate_dir(struct kobject * kobj)
        return error;
 }
 
-static int create_dir(struct kobject * kobj, struct dentry *shadow_parent)
+static int create_dir(struct kobject *kobj, struct sysfs_dirent *shadow_parent)
 {
        int error = 0;
        if (kobject_name(kobj)) {
@@ -162,7 +162,7 @@ static void unlink(struct kobject * kobj)
  *     @shadow_parent: sysfs directory to add to.
  */
 
-int kobject_shadow_add(struct kobject * kobj, struct dentry *shadow_parent)
+int kobject_shadow_add(struct kobject *kobj, struct sysfs_dirent *shadow_parent)
 {
        int error = 0;
        struct kobject * parent;
@@ -338,7 +338,7 @@ int kobject_rename(struct kobject * kobj, const char *new_name)
        /* Note : if we want to send the new name alone, not the full path,
         * we could probably use kobject_name(kobj); */
 
-       error = sysfs_rename_dir(kobj, kobj->parent->dentry, new_name);
+       error = sysfs_rename_dir(kobj, kobj->parent->sd, new_name);
 
        /* This function is mostly/only used for network interface.
         * Some hotplug package track interfaces by their name and
@@ -361,8 +361,8 @@ out:
  *     @new_name: object's new name
  */
 
-int kobject_shadow_rename(struct kobject * kobj, struct dentry *new_parent,
-                         const char *new_name)
+int kobject_shadow_rename(struct kobject *kobj,
+                         struct sysfs_dirent *new_parent, const char *new_name)
 {
        int error = 0;
 
@@ -597,10 +597,17 @@ int kset_add(struct kset * k)
 
 int kset_register(struct kset * k)
 {
+       int err;
+
        if (!k)
                return -EINVAL;
+
        kset_init(k);
-       return kset_add(k);
+       err = kset_add(k);
+       if (err)
+               return err;
+       kobject_uevent(&k->kobj, KOBJ_ADD);
+       return 0;
 }
 
 
diff --git a/lib/lzo/Makefile b/lib/lzo/Makefile
new file mode 100644 (file)
index 0000000..e764116
--- /dev/null
@@ -0,0 +1,5 @@
+lzo_compress-objs := lzo1x_compress.o
+lzo_decompress-objs := lzo1x_decompress.o
+
+obj-$(CONFIG_LZO_COMPRESS) += lzo_compress.o
+obj-$(CONFIG_LZO_DECOMPRESS) += lzo_decompress.o
diff --git a/lib/lzo/lzo1x_compress.c b/lib/lzo/lzo1x_compress.c
new file mode 100644 (file)
index 0000000..c935f00
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ *  LZO1X Compressor from MiniLZO
+ *
+ *  Copyright (C) 1996-2005 Markus F.X.J. Oberhumer <markus@oberhumer.com>
+ *
+ *  The full LZO package can be found at:
+ *  http://www.oberhumer.com/opensource/lzo/
+ *
+ *  Changed for kernel use by:
+ *  Nitin Gupta <nitingupta910@gmail.com>
+ *  Richard Purdie <rpurdie@openedhand.com>
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/lzo.h>
+#include <asm/unaligned.h>
+#include "lzodefs.h"
+
+static noinline size_t
+_lzo1x_1_do_compress(const unsigned char *in, size_t in_len,
+               unsigned char *out, size_t *out_len, void *wrkmem)
+{
+       const unsigned char * const in_end = in + in_len;
+       const unsigned char * const ip_end = in + in_len - M2_MAX_LEN - 5;
+       const unsigned char ** const dict = wrkmem;
+       const unsigned char *ip = in, *ii = ip;
+       const unsigned char *end, *m, *m_pos;
+       size_t m_off, m_len, dindex;
+       unsigned char *op = out;
+
+       ip += 4;
+
+       for (;;) {
+               dindex = ((0x21 * DX3(ip, 5, 5, 6)) >> 5) & D_MASK;
+               m_pos = dict[dindex];
+
+               if (m_pos < in)
+                       goto literal;
+
+               if (ip == m_pos || (ip - m_pos) > M4_MAX_OFFSET)
+                       goto literal;
+
+               m_off = ip - m_pos;
+               if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3])
+                       goto try_match;
+
+               dindex = (dindex & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f);
+               m_pos = dict[dindex];
+
+               if (m_pos < in)
+                       goto literal;
+
+               if (ip == m_pos || (ip - m_pos) > M4_MAX_OFFSET)
+                       goto literal;
+
+               m_off = ip - m_pos;
+               if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3])
+                       goto try_match;
+
+               goto literal;
+
+try_match:
+               if (get_unaligned((const unsigned short *)m_pos)
+                               == get_unaligned((const unsigned short *)ip)) {
+                       if (likely(m_pos[2] == ip[2]))
+                                       goto match;
+               }
+
+literal:
+               dict[dindex] = ip;
+               ++ip;
+               if (unlikely(ip >= ip_end))
+                       break;
+               continue;
+
+match:
+               dict[dindex] = ip;
+               if (ip != ii) {
+                       size_t t = ip - ii;
+
+                       if (t <= 3) {
+                               op[-2] |= t;
+                       } else if (t <= 18) {
+                               *op++ = (t - 3);
+                       } else {
+                               size_t tt = t - 18;
+
+                               *op++ = 0;
+                               while (tt > 255) {
+                                       tt -= 255;
+                                       *op++ = 0;
+                               }
+                               *op++ = tt;
+                       }
+                       do {
+                               *op++ = *ii++;
+                       } while (--t > 0);
+               }
+
+               ip += 3;
+               if (m_pos[3] != *ip++ || m_pos[4] != *ip++
+                               || m_pos[5] != *ip++ || m_pos[6] != *ip++
+                               || m_pos[7] != *ip++ || m_pos[8] != *ip++) {
+                       --ip;
+                       m_len = ip - ii;
+
+                       if (m_off <= M2_MAX_OFFSET) {
+                               m_off -= 1;
+                               *op++ = (((m_len - 1) << 5)
+                                               | ((m_off & 7) << 2));
+                               *op++ = (m_off >> 3);
+                       } else if (m_off <= M3_MAX_OFFSET) {
+                               m_off -= 1;
+                               *op++ = (M3_MARKER | (m_len - 2));
+                               goto m3_m4_offset;
+                       } else {
+                               m_off -= 0x4000;
+
+                               *op++ = (M4_MARKER | ((m_off & 0x4000) >> 11)
+                                               | (m_len - 2));
+                               goto m3_m4_offset;
+                       }
+               } else {
+                       end = in_end;
+                       m = m_pos + M2_MAX_LEN + 1;
+
+                       while (ip < end && *m == *ip) {
+                               m++;
+                               ip++;
+                       }
+                       m_len = ip - ii;
+
+                       if (m_off <= M3_MAX_OFFSET) {
+                               m_off -= 1;
+                               if (m_len <= 33) {
+                                       *op++ = (M3_MARKER | (m_len - 2));
+                               } else {
+                                       m_len -= 33;
+                                       *op++ = M3_MARKER | 0;
+                                       goto m3_m4_len;
+                               }
+                       } else {
+                               m_off -= 0x4000;
+                               if (m_len <= M4_MAX_LEN) {
+                                       *op++ = (M4_MARKER
+                                               | ((m_off & 0x4000) >> 11)
+                                               | (m_len - 2));
+                               } else {
+                                       m_len -= M4_MAX_LEN;
+                                       *op++ = (M4_MARKER
+                                               | ((m_off & 0x4000) >> 11));
+m3_m4_len:
+                                       while (m_len > 255) {
+                                               m_len -= 255;
+                                               *op++ = 0;
+                                       }
+
+                                       *op++ = (m_len);
+                               }
+                       }
+m3_m4_offset:
+                       *op++ = ((m_off & 63) << 2);
+                       *op++ = (m_off >> 6);
+               }
+
+               ii = ip;
+               if (unlikely(ip >= ip_end))
+                       break;
+       }
+
+       *out_len = op - out;
+       return in_end - ii;
+}
+
+int lzo1x_1_compress(const unsigned char *in, size_t in_len, unsigned char *out,
+                       size_t *out_len, void *wrkmem)
+{
+       const unsigned char *ii;
+       unsigned char *op = out;
+       size_t t;
+
+       if (unlikely(in_len <= M2_MAX_LEN + 5)) {
+               t = in_len;
+       } else {
+               t = _lzo1x_1_do_compress(in, in_len, op, out_len, wrkmem);
+               op += *out_len;
+       }
+
+       if (t > 0) {
+               ii = in + in_len - t;
+
+               if (op == out && t <= 238) {
+                       *op++ = (17 + t);
+               } else if (t <= 3) {
+                       op[-2] |= t;
+               } else if (t <= 18) {
+                       *op++ = (t - 3);
+               } else {
+                       size_t tt = t - 18;
+
+                       *op++ = 0;
+                       while (tt > 255) {
+                               tt -= 255;
+                               *op++ = 0;
+                       }
+
+                       *op++ = tt;
+               }
+               do {
+                       *op++ = *ii++;
+               } while (--t > 0);
+       }
+
+       *op++ = M4_MARKER | 1;
+       *op++ = 0;
+       *op++ = 0;
+
+       *out_len = op - out;
+       return LZO_E_OK;
+}
+EXPORT_SYMBOL_GPL(lzo1x_1_compress);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("LZO1X-1 Compressor");
+
diff --git a/lib/lzo/lzo1x_decompress.c b/lib/lzo/lzo1x_decompress.c
new file mode 100644 (file)
index 0000000..9dc7056
--- /dev/null
@@ -0,0 +1,254 @@
+/*
+ *  LZO1X Decompressor from MiniLZO
+ *
+ *  Copyright (C) 1996-2005 Markus F.X.J. Oberhumer <markus@oberhumer.com>
+ *
+ *  The full LZO package can be found at:
+ *  http://www.oberhumer.com/opensource/lzo/
+ *
+ *  Changed for kernel use by:
+ *  Nitin Gupta <nitingupta910@gmail.com>
+ *  Richard Purdie <rpurdie@openedhand.com>
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/lzo.h>
+#include <asm/byteorder.h>
+#include <asm/unaligned.h>
+#include "lzodefs.h"
+
+#define HAVE_IP(x, ip_end, ip) ((size_t)(ip_end - ip) < (x))
+#define HAVE_OP(x, op_end, op) ((size_t)(op_end - op) < (x))
+#define HAVE_LB(m_pos, out, op) (m_pos < out || m_pos >= op)
+
+#define COPY4(dst, src)        \
+               put_unaligned(get_unaligned((const u32 *)(src)), (u32 *)(dst))
+
+int lzo1x_decompress_safe(const unsigned char *in, size_t in_len,
+                       unsigned char *out, size_t *out_len)
+{
+       const unsigned char * const ip_end = in + in_len;
+       unsigned char * const op_end = out + *out_len;
+       const unsigned char *ip = in, *m_pos;
+       unsigned char *op = out;
+       size_t t;
+
+       *out_len = 0;
+
+       if (*ip > 17) {
+               t = *ip++ - 17;
+               if (t < 4)
+                       goto match_next;
+               if (HAVE_OP(t, op_end, op))
+                       goto output_overrun;
+               if (HAVE_IP(t + 1, ip_end, ip))
+                       goto input_overrun;
+               do {
+                       *op++ = *ip++;
+               } while (--t > 0);
+               goto first_literal_run;
+       }
+
+       while ((ip < ip_end)) {
+               t = *ip++;
+               if (t >= 16)
+                       goto match;
+               if (t == 0) {
+                       if (HAVE_IP(1, ip_end, ip))
+                               goto input_overrun;
+                       while (*ip == 0) {
+                               t += 255;
+                               ip++;
+                               if (HAVE_IP(1, ip_end, ip))
+                                       goto input_overrun;
+                       }
+                       t += 15 + *ip++;
+               }
+               if (HAVE_OP(t + 3, op_end, op))
+                       goto output_overrun;
+               if (HAVE_IP(t + 4, ip_end, ip))
+                       goto input_overrun;
+
+               COPY4(op, ip);
+               op += 4;
+               ip += 4;
+               if (--t > 0) {
+                       if (t >= 4) {
+                               do {
+                                       COPY4(op, ip);
+                                       op += 4;
+                                       ip += 4;
+                                       t -= 4;
+                               } while (t >= 4);
+                               if (t > 0) {
+                                       do {
+                                               *op++ = *ip++;
+                                       } while (--t > 0);
+                               }
+                       } else {
+                               do {
+                                       *op++ = *ip++;
+                               } while (--t > 0);
+                       }
+               }
+
+first_literal_run:
+               t = *ip++;
+               if (t >= 16)
+                       goto match;
+               m_pos = op - (1 + M2_MAX_OFFSET);
+               m_pos -= t >> 2;
+               m_pos -= *ip++ << 2;
+
+               if (HAVE_LB(m_pos, out, op))
+                       goto lookbehind_overrun;
+
+               if (HAVE_OP(3, op_end, op))
+                       goto output_overrun;
+               *op++ = *m_pos++;
+               *op++ = *m_pos++;
+               *op++ = *m_pos;
+
+               goto match_done;
+
+               do {
+match:
+                       if (t >= 64) {
+                               m_pos = op - 1;
+                               m_pos -= (t >> 2) & 7;
+                               m_pos -= *ip++ << 3;
+                               t = (t >> 5) - 1;
+                               if (HAVE_LB(m_pos, out, op))
+                                       goto lookbehind_overrun;
+                               if (HAVE_OP(t + 3 - 1, op_end, op))
+                                       goto output_overrun;
+                               goto copy_match;
+                       } else if (t >= 32) {
+                               t &= 31;
+                               if (t == 0) {
+                                       if (HAVE_IP(1, ip_end, ip))
+                                               goto input_overrun;
+                                       while (*ip == 0) {
+                                               t += 255;
+                                               ip++;
+                                               if (HAVE_IP(1, ip_end, ip))
+                                                       goto input_overrun;
+                                       }
+                                       t += 31 + *ip++;
+                               }
+                               m_pos = op - 1;
+                               m_pos -= le16_to_cpu(get_unaligned(
+                                       (const unsigned short *)ip)) >> 2;
+                               ip += 2;
+                       } else if (t >= 16) {
+                               m_pos = op;
+                               m_pos -= (t & 8) << 11;
+
+                               t &= 7;
+                               if (t == 0) {
+                                       if (HAVE_IP(1, ip_end, ip))
+                                               goto input_overrun;
+                                       while (*ip == 0) {
+                                               t += 255;
+                                               ip++;
+                                               if (HAVE_IP(1, ip_end, ip))
+                                                       goto input_overrun;
+                                       }
+                                       t += 7 + *ip++;
+                               }
+                               m_pos -= le16_to_cpu(get_unaligned(
+                                       (const unsigned short *)ip) >> 2);
+                               ip += 2;
+                               if (m_pos == op)
+                                       goto eof_found;
+                               m_pos -= 0x4000;
+                       } else {
+                               m_pos = op - 1;
+                               m_pos -= t >> 2;
+                               m_pos -= *ip++ << 2;
+
+                               if (HAVE_LB(m_pos, out, op))
+                                       goto lookbehind_overrun;
+                               if (HAVE_OP(2, op_end, op))
+                                       goto output_overrun;
+
+                               *op++ = *m_pos++;
+                               *op++ = *m_pos;
+                               goto match_done;
+                       }
+
+                       if (HAVE_LB(m_pos, out, op))
+                               goto lookbehind_overrun;
+                       if (HAVE_OP(t + 3 - 1, op_end, op))
+                               goto output_overrun;
+
+                       if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) {
+                               COPY4(op, m_pos);
+                               op += 4;
+                               m_pos += 4;
+                               t -= 4 - (3 - 1);
+                               do {
+                                       COPY4(op, m_pos);
+                                       op += 4;
+                                       m_pos += 4;
+                                       t -= 4;
+                               } while (t >= 4);
+                               if (t > 0)
+                                       do {
+                                               *op++ = *m_pos++;
+                                       } while (--t > 0);
+                       } else {
+copy_match:
+                               *op++ = *m_pos++;
+                               *op++ = *m_pos++;
+                               do {
+                                       *op++ = *m_pos++;
+                               } while (--t > 0);
+                       }
+match_done:
+                       t = ip[-2] & 3;
+                       if (t == 0)
+                               break;
+match_next:
+                       if (HAVE_OP(t, op_end, op))
+                               goto output_overrun;
+                       if (HAVE_IP(t + 1, ip_end, ip))
+                               goto input_overrun;
+
+                       *op++ = *ip++;
+                       if (t > 1) {
+                               *op++ = *ip++;
+                               if (t > 2)
+                                       *op++ = *ip++;
+                       }
+
+                       t = *ip++;
+               } while (ip < ip_end);
+       }
+
+       *out_len = op - out;
+       return LZO_E_EOF_NOT_FOUND;
+
+eof_found:
+       *out_len = op - out;
+       return (ip == ip_end ? LZO_E_OK :
+               (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
+input_overrun:
+       *out_len = op - out;
+       return LZO_E_INPUT_OVERRUN;
+
+output_overrun:
+       *out_len = op - out;
+       return LZO_E_OUTPUT_OVERRUN;
+
+lookbehind_overrun:
+       *out_len = op - out;
+       return LZO_E_LOOKBEHIND_OVERRUN;
+}
+
+EXPORT_SYMBOL_GPL(lzo1x_decompress_safe);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("LZO1X Decompressor");
+
diff --git a/lib/lzo/lzodefs.h b/lib/lzo/lzodefs.h
new file mode 100644 (file)
index 0000000..b6d482c
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ *  lzodefs.h -- architecture, OS and compiler specific defines
+ *
+ *  Copyright (C) 1996-2005 Markus F.X.J. Oberhumer <markus@oberhumer.com>
+ *
+ *  The full LZO package can be found at:
+ *  http://www.oberhumer.com/opensource/lzo/
+ *
+ *  Changed for kernel use by:
+ *  Nitin Gupta <nitingupta910@gmail.com>
+ *  Richard Purdie <rpurdie@openedhand.com>
+ */
+
+#define LZO_VERSION            0x2020
+#define LZO_VERSION_STRING     "2.02"
+#define LZO_VERSION_DATE       "Oct 17 2005"
+
+#define M1_MAX_OFFSET  0x0400
+#define M2_MAX_OFFSET  0x0800
+#define M3_MAX_OFFSET  0x4000
+#define M4_MAX_OFFSET  0xbfff
+
+#define M1_MIN_LEN     2
+#define M1_MAX_LEN     2
+#define M2_MIN_LEN     3
+#define M2_MAX_LEN     8
+#define M3_MIN_LEN     3
+#define M3_MAX_LEN     33
+#define M4_MIN_LEN     3
+#define M4_MAX_LEN     9
+
+#define M1_MARKER      0
+#define M2_MARKER      64
+#define M3_MARKER      32
+#define M4_MARKER      16
+
+#define D_BITS         14
+#define D_MASK         ((1u << D_BITS) - 1)
+#define D_HIGH         ((D_MASK >> 1) + 1)
+
+#define DX2(p, s1, s2) (((((size_t)((p)[2]) << (s2)) ^ (p)[1]) \
+                                                       << (s1)) ^ (p)[0])
+#define DX3(p, s1, s2, s3)     ((DX2((p)+1, s2, s3) << (s1)) ^ (p)[0])
index d1d9814f99ddd51f982799ca70fa86762d7b48c0..c6ebd9f912abbfb7298c99fcd7432a3636857fb1 100644 (file)
@@ -1245,26 +1245,6 @@ int file_send_actor(read_descriptor_t * desc, struct page *page, unsigned long o
        return written;
 }
 
-ssize_t generic_file_sendfile(struct file *in_file, loff_t *ppos,
-                        size_t count, read_actor_t actor, void *target)
-{
-       read_descriptor_t desc;
-
-       if (!count)
-               return 0;
-
-       desc.written = 0;
-       desc.count = count;
-       desc.arg.data = target;
-       desc.error = 0;
-
-       do_generic_file_read(in_file, ppos, &desc, actor);
-       if (desc.written)
-               return desc.written;
-       return desc.error;
-}
-EXPORT_SYMBOL(generic_file_sendfile);
-
 static ssize_t
 do_readahead(struct address_space *mapping, struct file *filp,
             unsigned long index, unsigned long nr)
index fa360e566d88815caafbeaf57533085f334612ab..65ffc321f0c0f223e4c6115e91c53d12d8319399 100644 (file)
@@ -159,28 +159,6 @@ xip_file_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
 }
 EXPORT_SYMBOL_GPL(xip_file_read);
 
-ssize_t
-xip_file_sendfile(struct file *in_file, loff_t *ppos,
-            size_t count, read_actor_t actor, void *target)
-{
-       read_descriptor_t desc;
-
-       if (!count)
-               return 0;
-
-       desc.written = 0;
-       desc.count = count;
-       desc.arg.data = target;
-       desc.error = 0;
-
-       do_xip_mapping_read(in_file->f_mapping, &in_file->f_ra, in_file,
-                           ppos, &desc, actor);
-       if (desc.written)
-               return desc.written;
-       return desc.error;
-}
-EXPORT_SYMBOL_GPL(xip_file_sendfile);
-
 /*
  * __xip_unmap is invoked from xip_unmap and
  * xip_write
index 906ed402f7cabda336a73d6d0d297b862b0d2932..9f70c8e8c871c272047fdc4c969f285299b58926 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1023,10 +1023,10 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
                }
        }
 
-       error = security_file_mmap(file, reqprot, prot, flags);
+       error = security_file_mmap(file, reqprot, prot, flags, addr, 0);
        if (error)
                return error;
-               
+
        /* Clear old maps */
        error = -ENOMEM;
 munmap_back:
index 5d4bd4f95b8e5ef28f269f604b61d133f341d27b..bc7c52efc71bb1d5dddded25b836c4b842a54edf 100644 (file)
@@ -291,6 +291,10 @@ unsigned long do_mremap(unsigned long addr,
                if ((addr <= new_addr) && (addr+old_len) > new_addr)
                        goto out;
 
+               ret = security_file_mmap(0, 0, 0, 0, new_addr, 1);
+               if (ret)
+                       goto out;
+
                ret = do_munmap(mm, new_addr, new_len);
                if (ret)
                        goto out;
@@ -390,8 +394,13 @@ unsigned long do_mremap(unsigned long addr,
 
                        new_addr = get_unmapped_area(vma->vm_file, 0, new_len,
                                                vma->vm_pgoff, map_flags);
-                       ret = new_addr;
-                       if (new_addr & ~PAGE_MASK)
+                       if (new_addr & ~PAGE_MASK) {
+                               ret = new_addr;
+                               goto out;
+                       }
+
+                       ret = security_file_mmap(0, 0, 0, 0, new_addr, 1);
+                       if (ret)
                                goto out;
                }
                ret = move_vma(vma, addr, old_len, new_len, new_addr);
index 2b16b00a5b115be2c13897aab5763562312ecb84..989e2e9af5c3adc42cb250409a4b7249288e0df7 100644 (file)
@@ -639,7 +639,7 @@ static int validate_mmap_request(struct file *file,
        }
 
        /* allow the security API to have its say */
-       ret = security_file_mmap(file, reqprot, prot, flags);
+       ret = security_file_mmap(file, reqprot, prot, flags, addr, 0);
        if (ret < 0)
                return ret;
 
index b6aae2b33393d96d694145326c6591acf6f83b4b..0493e4d0bcaab2d5b0281446171b4de57598b8ee 100644 (file)
@@ -1100,9 +1100,9 @@ static int shmem_getpage(struct inode *inode, unsigned long idx,
         * Normally, filepage is NULL on entry, and either found
         * uptodate immediately, or allocated and zeroed, or read
         * in under swappage, which is then assigned to filepage.
-        * But shmem_prepare_write passes in a locked filepage,
-        * which may be found not uptodate by other callers too,
-        * and may need to be copied from the swappage read in.
+        * But shmem_readpage and shmem_prepare_write pass in a locked
+        * filepage, which may be found not uptodate by other callers
+        * too, and may need to be copied from the swappage read in.
         */
 repeat:
        if (!filepage)
@@ -1485,9 +1485,18 @@ static const struct inode_operations shmem_symlink_inode_operations;
 static const struct inode_operations shmem_symlink_inline_operations;
 
 /*
- * Normally tmpfs makes no use of shmem_prepare_write, but it
- * lets a tmpfs file be used read-write below the loop driver.
+ * Normally tmpfs avoids the use of shmem_readpage and shmem_prepare_write;
+ * but providing them allows a tmpfs file to be used for splice, sendfile, and
+ * below the loop driver, in the generic fashion that many filesystems support.
  */
+static int shmem_readpage(struct file *file, struct page *page)
+{
+       struct inode *inode = page->mapping->host;
+       int error = shmem_getpage(inode, page->index, &page, SGP_CACHE, NULL);
+       unlock_page(page);
+       return error;
+}
+
 static int
 shmem_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
 {
@@ -1711,25 +1720,6 @@ static ssize_t shmem_file_read(struct file *filp, char __user *buf, size_t count
        return desc.error;
 }
 
-static ssize_t shmem_file_sendfile(struct file *in_file, loff_t *ppos,
-                        size_t count, read_actor_t actor, void *target)
-{
-       read_descriptor_t desc;
-
-       if (!count)
-               return 0;
-
-       desc.written = 0;
-       desc.count = count;
-       desc.arg.data = target;
-       desc.error = 0;
-
-       do_shmem_file_read(in_file, ppos, &desc, actor);
-       if (desc.written)
-               return desc.written;
-       return desc.error;
-}
-
 static int shmem_statfs(struct dentry *dentry, struct kstatfs *buf)
 {
        struct shmem_sb_info *sbinfo = SHMEM_SB(dentry->d_sb);
@@ -2386,6 +2376,7 @@ static const struct address_space_operations shmem_aops = {
        .writepage      = shmem_writepage,
        .set_page_dirty = __set_page_dirty_no_writeback,
 #ifdef CONFIG_TMPFS
+       .readpage       = shmem_readpage,
        .prepare_write  = shmem_prepare_write,
        .commit_write   = simple_commit_write,
 #endif
@@ -2399,7 +2390,8 @@ static const struct file_operations shmem_file_operations = {
        .read           = shmem_file_read,
        .write          = shmem_file_write,
        .fsync          = simple_sync_file,
-       .sendfile       = shmem_file_sendfile,
+       .splice_read    = generic_file_splice_read,
+       .splice_write   = generic_file_splice_write,
 #endif
 };
 
index 0ba1946211c935e79883963c21782f7258bb5726..e56e61a7f5450ad783aa92a510dafab0a7309069 100644 (file)
@@ -567,7 +567,7 @@ static int rif_seq_show(struct seq_file *seq, void *v)
 }
 
 
-static struct seq_operations rif_seq_ops = {
+static const struct seq_operations rif_seq_ops = {
        .start = rif_seq_start,
        .next  = rif_seq_next,
        .stop  = rif_seq_stop,
index 97feb44dbdce6210e2bf2e0048b8dcb284bf7b2c..10ca7f486c3a9cd7e990688edc3cebc2386a66ab 100644 (file)
@@ -4,7 +4,7 @@
 
 obj-$(CONFIG_VLAN_8021Q) += 8021q.o
 
-8021q-objs := vlan.o vlan_dev.o
+8021q-objs := vlan.o vlan_dev.o vlan_netlink.o
 
 ifeq ($(CONFIG_PROC_FS),y)
 8021q-objs += vlanproc.o
index de78c9dd713bbfb0bb0942bea0f98bd5ffb6179a..abb9900edb3f189a923315f71ec5991f7d34d079 100644 (file)
@@ -97,35 +97,22 @@ static int __init vlan_proto_init(void)
 
        /* Register us to receive netdevice events */
        err = register_netdevice_notifier(&vlan_notifier_block);
-       if (err < 0) {
-               dev_remove_pack(&vlan_packet_type);
-               vlan_proc_cleanup();
-               return err;
-       }
+       if (err < 0)
+               goto err1;
 
-       vlan_ioctl_set(vlan_ioctl_handler);
+       err = vlan_netlink_init();
+       if (err < 0)
+               goto err2;
 
+       vlan_ioctl_set(vlan_ioctl_handler);
        return 0;
-}
-
-/* Cleanup all vlan devices
- * Note: devices that have been registered that but not
- * brought up will exist but have no module ref count.
- */
-static void __exit vlan_cleanup_devices(void)
-{
-       struct net_device *dev, *nxt;
-
-       rtnl_lock();
-       for_each_netdev_safe(dev, nxt) {
-               if (dev->priv_flags & IFF_802_1Q_VLAN) {
-                       unregister_vlan_dev(VLAN_DEV_INFO(dev)->real_dev,
-                                           VLAN_DEV_INFO(dev)->vlan_id);
 
-                       unregister_netdevice(dev);
-               }
-       }
-       rtnl_unlock();
+err2:
+       unregister_netdevice_notifier(&vlan_notifier_block);
+err1:
+       vlan_proc_cleanup();
+       dev_remove_pack(&vlan_packet_type);
+       return err;
 }
 
 /*
@@ -136,13 +123,13 @@ static void __exit vlan_cleanup_module(void)
 {
        int i;
 
+       vlan_netlink_fini();
        vlan_ioctl_set(NULL);
 
        /* Un-register us from receiving netdevice events */
        unregister_netdevice_notifier(&vlan_notifier_block);
 
        dev_remove_pack(&vlan_packet_type);
-       vlan_cleanup_devices();
 
        /* This table must be empty if there are no module
         * references left.
@@ -197,6 +184,34 @@ static void vlan_group_free(struct vlan_group *grp)
        kfree(grp);
 }
 
+static struct vlan_group *vlan_group_alloc(int ifindex)
+{
+       struct vlan_group *grp;
+       unsigned int size;
+       unsigned int i;
+
+       grp = kzalloc(sizeof(struct vlan_group), GFP_KERNEL);
+       if (!grp)
+               return NULL;
+
+       size = sizeof(struct net_device *) * VLAN_GROUP_ARRAY_PART_LEN;
+
+       for (i = 0; i < VLAN_GROUP_ARRAY_SPLIT_PARTS; i++) {
+               grp->vlan_devices_arrays[i] = kzalloc(size, GFP_KERNEL);
+               if (!grp->vlan_devices_arrays[i])
+                       goto err;
+       }
+
+       grp->real_dev_ifindex = ifindex;
+       hlist_add_head_rcu(&grp->hlist,
+                          &vlan_group_hash[vlan_grp_hashfn(ifindex)]);
+       return grp;
+
+err:
+       vlan_group_free(grp);
+       return NULL;
+}
+
 static void vlan_rcu_free(struct rcu_head *rcu)
 {
        vlan_group_free(container_of(rcu, struct vlan_group, rcu));
@@ -278,50 +293,66 @@ static int unregister_vlan_dev(struct net_device *real_dev,
        return ret;
 }
 
-static int unregister_vlan_device(const char *vlan_IF_name)
+int unregister_vlan_device(struct net_device *dev)
 {
-       struct net_device *dev = NULL;
        int ret;
 
+       ret = unregister_vlan_dev(VLAN_DEV_INFO(dev)->real_dev,
+                                 VLAN_DEV_INFO(dev)->vlan_id);
+       unregister_netdevice(dev);
 
-       dev = dev_get_by_name(vlan_IF_name);
-       ret = -EINVAL;
-       if (dev) {
-               if (dev->priv_flags & IFF_802_1Q_VLAN) {
-                       rtnl_lock();
+       if (ret == 1)
+               ret = 0;
+       return ret;
+}
 
-                       ret = unregister_vlan_dev(VLAN_DEV_INFO(dev)->real_dev,
-                                                 VLAN_DEV_INFO(dev)->vlan_id);
+/*
+ * vlan network devices have devices nesting below it, and are a special
+ * "super class" of normal network devices; split their locks off into a
+ * separate class since they always nest.
+ */
+static struct lock_class_key vlan_netdev_xmit_lock_key;
 
-                       dev_put(dev);
-                       unregister_netdevice(dev);
+static int vlan_dev_init(struct net_device *dev)
+{
+       struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev;
 
-                       rtnl_unlock();
+       /* IFF_BROADCAST|IFF_MULTICAST; ??? */
+       dev->flags  = real_dev->flags & ~IFF_UP;
+       dev->iflink = real_dev->ifindex;
+       dev->state  = (real_dev->state & ((1<<__LINK_STATE_NOCARRIER) |
+                                         (1<<__LINK_STATE_DORMANT))) |
+                     (1<<__LINK_STATE_PRESENT);
 
-                       if (ret == 1)
-                               ret = 0;
-               } else {
-                       printk(VLAN_ERR
-                              "%s: ERROR:      Tried to remove a non-vlan device "
-                              "with VLAN code, name: %s  priv_flags: %hX\n",
-                              __FUNCTION__, dev->name, dev->priv_flags);
-                       dev_put(dev);
-                       ret = -EPERM;
-               }
+       if (is_zero_ether_addr(dev->dev_addr))
+               memcpy(dev->dev_addr, real_dev->dev_addr, dev->addr_len);
+       if (is_zero_ether_addr(dev->broadcast))
+               memcpy(dev->broadcast, real_dev->broadcast, dev->addr_len);
+
+       if (real_dev->features & NETIF_F_HW_VLAN_TX) {
+               dev->hard_header     = real_dev->hard_header;
+               dev->hard_header_len = real_dev->hard_header_len;
+               dev->hard_start_xmit = vlan_dev_hwaccel_hard_start_xmit;
+               dev->rebuild_header  = real_dev->rebuild_header;
        } else {
-#ifdef VLAN_DEBUG
-               printk(VLAN_DBG "%s: WARNING: Could not find dev.\n", __FUNCTION__);
-#endif
-               ret = -EINVAL;
+               dev->hard_header     = vlan_dev_hard_header;
+               dev->hard_header_len = real_dev->hard_header_len + VLAN_HLEN;
+               dev->hard_start_xmit = vlan_dev_hard_start_xmit;
+               dev->rebuild_header  = vlan_dev_rebuild_header;
        }
+       dev->hard_header_parse = real_dev->hard_header_parse;
+       dev->hard_header_cache = NULL;
 
-       return ret;
+       lockdep_set_class(&dev->_xmit_lock, &vlan_netdev_xmit_lock_key);
+       return 0;
 }
 
-static void vlan_setup(struct net_device *new_dev)
+void vlan_setup(struct net_device *new_dev)
 {
        SET_MODULE_OWNER(new_dev);
 
+       ether_setup(new_dev);
+
        /* new_dev->ifindex = 0;  it will be set when added to
         * the global list.
         * iflink is set as well.
@@ -338,12 +369,14 @@ static void vlan_setup(struct net_device *new_dev)
 
        /* set up method calls */
        new_dev->change_mtu = vlan_dev_change_mtu;
+       new_dev->init = vlan_dev_init;
        new_dev->open = vlan_dev_open;
        new_dev->stop = vlan_dev_stop;
-       new_dev->set_mac_address = vlan_dev_set_mac_address;
        new_dev->set_multicast_list = vlan_dev_set_multicast_list;
        new_dev->destructor = free_netdev;
        new_dev->do_ioctl = vlan_dev_ioctl;
+
+       memset(new_dev->broadcast, 0, sizeof(ETH_ALEN));
 }
 
 static void vlan_transfer_operstate(const struct net_device *dev, struct net_device *vlandev)
@@ -366,77 +399,110 @@ static void vlan_transfer_operstate(const struct net_device *dev, struct net_dev
        }
 }
 
-/*
- * vlan network devices have devices nesting below it, and are a special
- * "super class" of normal network devices; split their locks off into a
- * separate class since they always nest.
- */
-static struct lock_class_key vlan_netdev_xmit_lock_key;
-
-
-/*  Attach a VLAN device to a mac address (ie Ethernet Card).
- *  Returns the device that was created, or NULL if there was
- *  an error of some kind.
- */
-static struct net_device *register_vlan_device(const char *eth_IF_name,
-                                              unsigned short VLAN_ID)
+int vlan_check_real_dev(struct net_device *real_dev, unsigned short vlan_id)
 {
-       struct vlan_group *grp;
-       struct net_device *new_dev;
-       struct net_device *real_dev; /* the ethernet device */
-       char name[IFNAMSIZ];
-       int i;
-
-#ifdef VLAN_DEBUG
-       printk(VLAN_DBG "%s: if_name -:%s:-     vid: %i\n",
-               __FUNCTION__, eth_IF_name, VLAN_ID);
-#endif
-
-       if (VLAN_ID >= VLAN_VID_MASK)
-               goto out_ret_null;
-
-       /* find the device relating to eth_IF_name. */
-       real_dev = dev_get_by_name(eth_IF_name);
-       if (!real_dev)
-               goto out_ret_null;
-
        if (real_dev->features & NETIF_F_VLAN_CHALLENGED) {
                printk(VLAN_DBG "%s: VLANs not supported on %s.\n",
                        __FUNCTION__, real_dev->name);
-               goto out_put_dev;
+               return -EOPNOTSUPP;
        }
 
        if ((real_dev->features & NETIF_F_HW_VLAN_RX) &&
            !real_dev->vlan_rx_register) {
                printk(VLAN_DBG "%s: Device %s has buggy VLAN hw accel.\n",
                        __FUNCTION__, real_dev->name);
-               goto out_put_dev;
+               return -EOPNOTSUPP;
        }
 
        if ((real_dev->features & NETIF_F_HW_VLAN_FILTER) &&
            (!real_dev->vlan_rx_add_vid || !real_dev->vlan_rx_kill_vid)) {
                printk(VLAN_DBG "%s: Device %s has buggy VLAN hw accel.\n",
                        __FUNCTION__, real_dev->name);
-               goto out_put_dev;
+               return -EOPNOTSUPP;
        }
 
-       /* From this point on, all the data structures must remain
-        * consistent.
-        */
-       rtnl_lock();
-
        /* The real device must be up and operating in order to
         * assosciate a VLAN device with it.
         */
        if (!(real_dev->flags & IFF_UP))
-               goto out_unlock;
+               return -ENETDOWN;
 
-       if (__find_vlan_dev(real_dev, VLAN_ID) != NULL) {
+       if (__find_vlan_dev(real_dev, vlan_id) != NULL) {
                /* was already registered. */
                printk(VLAN_DBG "%s: ALREADY had VLAN registered\n", __FUNCTION__);
-               goto out_unlock;
+               return -EEXIST;
+       }
+
+       return 0;
+}
+
+int register_vlan_dev(struct net_device *dev)
+{
+       struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
+       struct net_device *real_dev = vlan->real_dev;
+       unsigned short vlan_id = vlan->vlan_id;
+       struct vlan_group *grp, *ngrp = NULL;
+       int err;
+
+       grp = __vlan_find_group(real_dev->ifindex);
+       if (!grp) {
+               ngrp = grp = vlan_group_alloc(real_dev->ifindex);
+               if (!grp)
+                       return -ENOBUFS;
        }
 
+       err = register_netdevice(dev);
+       if (err < 0)
+               goto out_free_group;
+
+       /* Account for reference in struct vlan_dev_info */
+       dev_hold(real_dev);
+
+       vlan_transfer_operstate(real_dev, dev);
+       linkwatch_fire_event(dev); /* _MUST_ call rfc2863_policy() */
+
+       /* So, got the sucker initialized, now lets place
+        * it into our local structure.
+        */
+       vlan_group_set_device(grp, vlan_id, dev);
+       if (ngrp && real_dev->features & NETIF_F_HW_VLAN_RX)
+               real_dev->vlan_rx_register(real_dev, ngrp);
+       if (real_dev->features & NETIF_F_HW_VLAN_FILTER)
+               real_dev->vlan_rx_add_vid(real_dev, vlan_id);
+
+       if (vlan_proc_add_dev(dev) < 0)
+               printk(KERN_WARNING "VLAN: failed to add proc entry for %s\n",
+                      dev->name);
+       return 0;
+
+out_free_group:
+       if (ngrp)
+               vlan_group_free(ngrp);
+       return err;
+}
+
+/*  Attach a VLAN device to a mac address (ie Ethernet Card).
+ *  Returns 0 if the device was created or a negative error code otherwise.
+ */
+static int register_vlan_device(struct net_device *real_dev,
+                               unsigned short VLAN_ID)
+{
+       struct net_device *new_dev;
+       char name[IFNAMSIZ];
+       int err;
+
+#ifdef VLAN_DEBUG
+       printk(VLAN_DBG "%s: if_name -:%s:-     vid: %i\n",
+               __FUNCTION__, eth_IF_name, VLAN_ID);
+#endif
+
+       if (VLAN_ID >= VLAN_VID_MASK)
+               return -ERANGE;
+
+       err = vlan_check_real_dev(real_dev, VLAN_ID);
+       if (err < 0)
+               return err;
+
        /* Gotta set up the fields for the device. */
 #ifdef VLAN_DEBUG
        printk(VLAN_DBG "About to allocate name, vlan_name_type: %i\n",
@@ -471,138 +537,64 @@ static struct net_device *register_vlan_device(const char *eth_IF_name,
                               vlan_setup);
 
        if (new_dev == NULL)
-               goto out_unlock;
-
-#ifdef VLAN_DEBUG
-       printk(VLAN_DBG "Allocated new name -:%s:-\n", new_dev->name);
-#endif
-       /* IFF_BROADCAST|IFF_MULTICAST; ??? */
-       new_dev->flags = real_dev->flags;
-       new_dev->flags &= ~IFF_UP;
-
-       new_dev->state = (real_dev->state & ((1<<__LINK_STATE_NOCARRIER) |
-                                            (1<<__LINK_STATE_DORMANT))) |
-                        (1<<__LINK_STATE_PRESENT);
+               return -ENOBUFS;
 
        /* need 4 bytes for extra VLAN header info,
         * hope the underlying device can handle it.
         */
        new_dev->mtu = real_dev->mtu;
 
-       /* TODO: maybe just assign it to be ETHERNET? */
-       new_dev->type = real_dev->type;
-
-       new_dev->hard_header_len = real_dev->hard_header_len;
-       if (!(real_dev->features & NETIF_F_HW_VLAN_TX)) {
-               /* Regular ethernet + 4 bytes (18 total). */
-               new_dev->hard_header_len += VLAN_HLEN;
-       }
-
+#ifdef VLAN_DEBUG
+       printk(VLAN_DBG "Allocated new name -:%s:-\n", new_dev->name);
        VLAN_MEM_DBG("new_dev->priv malloc, addr: %p  size: %i\n",
                     new_dev->priv,
                     sizeof(struct vlan_dev_info));
-
-       memcpy(new_dev->broadcast, real_dev->broadcast, real_dev->addr_len);
-       memcpy(new_dev->dev_addr, real_dev->dev_addr, real_dev->addr_len);
-       new_dev->addr_len = real_dev->addr_len;
-
-       if (real_dev->features & NETIF_F_HW_VLAN_TX) {
-               new_dev->hard_header = real_dev->hard_header;
-               new_dev->hard_start_xmit = vlan_dev_hwaccel_hard_start_xmit;
-               new_dev->rebuild_header = real_dev->rebuild_header;
-       } else {
-               new_dev->hard_header = vlan_dev_hard_header;
-               new_dev->hard_start_xmit = vlan_dev_hard_start_xmit;
-               new_dev->rebuild_header = vlan_dev_rebuild_header;
-       }
-       new_dev->hard_header_parse = real_dev->hard_header_parse;
+#endif
 
        VLAN_DEV_INFO(new_dev)->vlan_id = VLAN_ID; /* 1 through VLAN_VID_MASK */
        VLAN_DEV_INFO(new_dev)->real_dev = real_dev;
        VLAN_DEV_INFO(new_dev)->dent = NULL;
-       VLAN_DEV_INFO(new_dev)->flags = 1;
+       VLAN_DEV_INFO(new_dev)->flags = VLAN_FLAG_REORDER_HDR;
 
-#ifdef VLAN_DEBUG
-       printk(VLAN_DBG "About to go find the group for idx: %i\n",
-              real_dev->ifindex);
-#endif
-
-       if (register_netdevice(new_dev))
+       new_dev->rtnl_link_ops = &vlan_link_ops;
+       err = register_vlan_dev(new_dev);
+       if (err < 0)
                goto out_free_newdev;
 
-       lockdep_set_class(&new_dev->_xmit_lock, &vlan_netdev_xmit_lock_key);
-
-       new_dev->iflink = real_dev->ifindex;
-       vlan_transfer_operstate(real_dev, new_dev);
-       linkwatch_fire_event(new_dev); /* _MUST_ call rfc2863_policy() */
-
-       /* So, got the sucker initialized, now lets place
-        * it into our local structure.
-        */
-       grp = __vlan_find_group(real_dev->ifindex);
-
-       /* Note, we are running under the RTNL semaphore
-        * so it cannot "appear" on us.
-        */
-       if (!grp) { /* need to add a new group */
-               grp = kzalloc(sizeof(struct vlan_group), GFP_KERNEL);
-               if (!grp)
-                       goto out_free_unregister;
-
-               for (i=0; i < VLAN_GROUP_ARRAY_SPLIT_PARTS; i++) {
-                       grp->vlan_devices_arrays[i] = kzalloc(
-                               sizeof(struct net_device *)*VLAN_GROUP_ARRAY_PART_LEN,
-                               GFP_KERNEL);
-
-                       if (!grp->vlan_devices_arrays[i])
-                               goto out_free_arrays;
-               }
-
-               /* printk(KERN_ALERT "VLAN REGISTER:  Allocated new group.\n"); */
-               grp->real_dev_ifindex = real_dev->ifindex;
-
-               hlist_add_head_rcu(&grp->hlist,
-                                  &vlan_group_hash[vlan_grp_hashfn(real_dev->ifindex)]);
-
-               if (real_dev->features & NETIF_F_HW_VLAN_RX)
-                       real_dev->vlan_rx_register(real_dev, grp);
-       }
-
-       vlan_group_set_device(grp, VLAN_ID, new_dev);
-
-       if (vlan_proc_add_dev(new_dev)<0)/* create it's proc entry */
-               printk(KERN_WARNING "VLAN: failed to add proc entry for %s\n",
-                                                        new_dev->name);
-
-       if (real_dev->features & NETIF_F_HW_VLAN_FILTER)
-               real_dev->vlan_rx_add_vid(real_dev, VLAN_ID);
-
-       rtnl_unlock();
-
-
+       /* Account for reference in struct vlan_dev_info */
+       dev_hold(real_dev);
 #ifdef VLAN_DEBUG
        printk(VLAN_DBG "Allocated new device successfully, returning.\n");
 #endif
-       return new_dev;
-
-out_free_arrays:
-       vlan_group_free(grp);
-
-out_free_unregister:
-       unregister_netdev(new_dev);
-       goto out_unlock;
+       return 0;
 
 out_free_newdev:
        free_netdev(new_dev);
+       return err;
+}
 
-out_unlock:
-       rtnl_unlock();
+static void vlan_sync_address(struct net_device *dev,
+                             struct net_device *vlandev)
+{
+       struct vlan_dev_info *vlan = VLAN_DEV_INFO(vlandev);
 
-out_put_dev:
-       dev_put(real_dev);
+       /* May be called without an actual change */
+       if (!compare_ether_addr(vlan->real_dev_addr, dev->dev_addr))
+               return;
 
-out_ret_null:
-       return NULL;
+       /* vlan address was different from the old address and is equal to
+        * the new address */
+       if (compare_ether_addr(vlandev->dev_addr, vlan->real_dev_addr) &&
+           !compare_ether_addr(vlandev->dev_addr, dev->dev_addr))
+               dev_unicast_delete(dev, vlandev->dev_addr, ETH_ALEN);
+
+       /* vlan address was equal to the old address and is different from
+        * the new address */
+       if (!compare_ether_addr(vlandev->dev_addr, vlan->real_dev_addr) &&
+           compare_ether_addr(vlandev->dev_addr, dev->dev_addr))
+               dev_unicast_add(dev, vlandev->dev_addr, ETH_ALEN);
+
+       memcpy(vlan->real_dev_addr, dev->dev_addr, ETH_ALEN);
 }
 
 static int vlan_device_event(struct notifier_block *unused, unsigned long event, void *ptr)
@@ -631,6 +623,17 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
                }
                break;
 
+       case NETDEV_CHANGEADDR:
+               /* Adjust unicast filters on underlying device */
+               for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+                       vlandev = vlan_group_get_device(grp, i);
+                       if (!vlandev)
+                               continue;
+
+                       vlan_sync_address(dev, vlandev);
+               }
+               break;
+
        case NETDEV_DOWN:
                /* Put all VLANs for this dev in the down state too.  */
                for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
@@ -693,9 +696,10 @@ out:
  */
 static int vlan_ioctl_handler(void __user *arg)
 {
-       int err = 0;
+       int err;
        unsigned short vid = 0;
        struct vlan_ioctl_args args;
+       struct net_device *dev = NULL;
 
        if (copy_from_user(&args, arg, sizeof(struct vlan_ioctl_args)))
                return -EFAULT;
@@ -708,35 +712,61 @@ static int vlan_ioctl_handler(void __user *arg)
        printk(VLAN_DBG "%s: args.cmd: %x\n", __FUNCTION__, args.cmd);
 #endif
 
+       rtnl_lock();
+
+       switch (args.cmd) {
+       case SET_VLAN_INGRESS_PRIORITY_CMD:
+       case SET_VLAN_EGRESS_PRIORITY_CMD:
+       case SET_VLAN_FLAG_CMD:
+       case ADD_VLAN_CMD:
+       case DEL_VLAN_CMD:
+       case GET_VLAN_REALDEV_NAME_CMD:
+       case GET_VLAN_VID_CMD:
+               err = -ENODEV;
+               dev = __dev_get_by_name(args.device1);
+               if (!dev)
+                       goto out;
+
+               err = -EINVAL;
+               if (args.cmd != ADD_VLAN_CMD &&
+                   !(dev->priv_flags & IFF_802_1Q_VLAN))
+                       goto out;
+       }
+
        switch (args.cmd) {
        case SET_VLAN_INGRESS_PRIORITY_CMD:
+               err = -EPERM;
                if (!capable(CAP_NET_ADMIN))
-                       return -EPERM;
-               err = vlan_dev_set_ingress_priority(args.device1,
-                                                   args.u.skb_priority,
-                                                   args.vlan_qos);
+                       break;
+               vlan_dev_set_ingress_priority(dev,
+                                             args.u.skb_priority,
+                                             args.vlan_qos);
                break;
 
        case SET_VLAN_EGRESS_PRIORITY_CMD:
+               err = -EPERM;
                if (!capable(CAP_NET_ADMIN))
-                       return -EPERM;
-               err = vlan_dev_set_egress_priority(args.device1,
+                       break;
+               err = vlan_dev_set_egress_priority(dev,
                                                   args.u.skb_priority,
                                                   args.vlan_qos);
                break;
 
        case SET_VLAN_FLAG_CMD:
+               err = -EPERM;
                if (!capable(CAP_NET_ADMIN))
-                       return -EPERM;
-               err = vlan_dev_set_vlan_flag(args.device1,
+                       break;
+               err = vlan_dev_set_vlan_flag(dev,
                                             args.u.flag,
                                             args.vlan_qos);
                break;
 
        case SET_VLAN_NAME_TYPE_CMD:
+               err = -EPERM;
                if (!capable(CAP_NET_ADMIN))
                        return -EPERM;
-               if (args.u.name_type < VLAN_NAME_TYPE_HIGHEST) {
+               if ((args.u.name_type >= 0) &&
+                   (args.u.name_type < VLAN_NAME_TYPE_HIGHEST)) {
                        vlan_name_type = args.u.name_type;
                        err = 0;
                } else {
@@ -745,26 +775,17 @@ static int vlan_ioctl_handler(void __user *arg)
                break;
 
        case ADD_VLAN_CMD:
+               err = -EPERM;
                if (!capable(CAP_NET_ADMIN))
-                       return -EPERM;
-               /* we have been given the name of the Ethernet Device we want to
-                * talk to:  args.dev1   We also have the
-                * VLAN ID:  args.u.VID
-                */
-               if (register_vlan_device(args.device1, args.u.VID)) {
-                       err = 0;
-               } else {
-                       err = -EINVAL;
-               }
+                       break;
+               err = register_vlan_device(dev, args.u.VID);
                break;
 
        case DEL_VLAN_CMD:
+               err = -EPERM;
                if (!capable(CAP_NET_ADMIN))
-                       return -EPERM;
-               /* Here, the args.dev1 is the actual VLAN we want
-                * to get rid of.
-                */
-               err = unregister_vlan_device(args.device1);
+                       break;
+               err = unregister_vlan_device(dev);
                break;
 
        case GET_VLAN_INGRESS_PRIORITY_CMD:
@@ -788,9 +809,7 @@ static int vlan_ioctl_handler(void __user *arg)
                err = -EINVAL;
                break;
        case GET_VLAN_REALDEV_NAME_CMD:
-               err = vlan_dev_get_realdev_name(args.device1, args.u.device2);
-               if (err)
-                       goto out;
+               vlan_dev_get_realdev_name(dev, args.u.device2);
                if (copy_to_user(arg, &args,
                                 sizeof(struct vlan_ioctl_args))) {
                        err = -EFAULT;
@@ -798,9 +817,7 @@ static int vlan_ioctl_handler(void __user *arg)
                break;
 
        case GET_VLAN_VID_CMD:
-               err = vlan_dev_get_vid(args.device1, &vid);
-               if (err)
-                       goto out;
+               vlan_dev_get_vid(dev, &vid);
                args.u.VID = vid;
                if (copy_to_user(arg, &args,
                                 sizeof(struct vlan_ioctl_args))) {
@@ -812,9 +829,11 @@ static int vlan_ioctl_handler(void __user *arg)
                /* pass on to underlying device instead?? */
                printk(VLAN_DBG "%s: Unknown VLAN CMD: %x \n",
                        __FUNCTION__, args.cmd);
-               return -EINVAL;
+               err = -EINVAL;
+               break;
        }
 out:
+       rtnl_unlock();
        return err;
 }
 
index 1976cdba8f726dc7d43edbaad4707878c18bb42f..62ce1c519aab54c5a1a244709e2f87243060d00a 100644 (file)
@@ -58,15 +58,27 @@ int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
 int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev);
 int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, struct net_device *dev);
 int vlan_dev_change_mtu(struct net_device *dev, int new_mtu);
-int vlan_dev_set_mac_address(struct net_device *dev, void* addr);
 int vlan_dev_open(struct net_device* dev);
 int vlan_dev_stop(struct net_device* dev);
 int vlan_dev_ioctl(struct net_device* dev, struct ifreq *ifr, int cmd);
-int vlan_dev_set_ingress_priority(char* dev_name, __u32 skb_prio, short vlan_prio);
-int vlan_dev_set_egress_priority(char* dev_name, __u32 skb_prio, short vlan_prio);
-int vlan_dev_set_vlan_flag(char* dev_name, __u32 flag, short flag_val);
-int vlan_dev_get_realdev_name(const char* dev_name, char* result);
-int vlan_dev_get_vid(const char* dev_name, unsigned short* result);
+void vlan_dev_set_ingress_priority(const struct net_device *dev,
+                                  u32 skb_prio, short vlan_prio);
+int vlan_dev_set_egress_priority(const struct net_device *dev,
+                                u32 skb_prio, short vlan_prio);
+int vlan_dev_set_vlan_flag(const struct net_device *dev,
+                          u32 flag, short flag_val);
+void vlan_dev_get_realdev_name(const struct net_device *dev, char *result);
+void vlan_dev_get_vid(const struct net_device *dev, unsigned short *result);
 void vlan_dev_set_multicast_list(struct net_device *vlan_dev);
 
+int vlan_check_real_dev(struct net_device *real_dev, unsigned short vlan_id);
+void vlan_setup(struct net_device *dev);
+int register_vlan_dev(struct net_device *dev);
+int unregister_vlan_device(struct net_device *dev);
+
+int vlan_netlink_init(void);
+void vlan_netlink_fini(void);
+
+extern struct rtnl_link_ops vlan_link_ops;
+
 #endif /* !(__BEN_VLAN_802_1Q_INC__) */
index ec46084f44b44156c83f2ad196d46ef82cee7524..d4a62d1b52b49d45f9f8f3ea932bba210c37692f 100644 (file)
@@ -73,7 +73,7 @@ int vlan_dev_rebuild_header(struct sk_buff *skb)
 
 static inline struct sk_buff *vlan_check_reorder_header(struct sk_buff *skb)
 {
-       if (VLAN_DEV_INFO(skb->dev)->flags & 1) {
+       if (VLAN_DEV_INFO(skb->dev)->flags & VLAN_FLAG_REORDER_HDR) {
                if (skb_shared(skb) || skb_cloned(skb)) {
                        struct sk_buff *nskb = skb_copy(skb, GFP_ATOMIC);
                        kfree_skb(skb);
@@ -350,7 +350,8 @@ int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
         * header shuffling in the hard_start_xmit.  Users can turn off this
         * REORDER behaviour with the vconfig tool.
         */
-       build_vlan_header = ((VLAN_DEV_INFO(dev)->flags & 1) == 0);
+       if (!(VLAN_DEV_INFO(dev)->flags & VLAN_FLAG_REORDER_HDR))
+               build_vlan_header = 1;
 
        if (build_vlan_header) {
                vhdr = (struct vlan_hdr *) skb_push(skb, VLAN_HLEN);
@@ -534,172 +535,81 @@ int vlan_dev_change_mtu(struct net_device *dev, int new_mtu)
        return 0;
 }
 
-int vlan_dev_set_ingress_priority(char *dev_name, __u32 skb_prio, short vlan_prio)
+void vlan_dev_set_ingress_priority(const struct net_device *dev,
+                                  u32 skb_prio, short vlan_prio)
 {
-       struct net_device *dev = dev_get_by_name(dev_name);
+       struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
 
-       if (dev) {
-               if (dev->priv_flags & IFF_802_1Q_VLAN) {
-                       /* see if a priority mapping exists.. */
-                       VLAN_DEV_INFO(dev)->ingress_priority_map[vlan_prio & 0x7] = skb_prio;
-                       dev_put(dev);
-                       return 0;
-               }
+       if (vlan->ingress_priority_map[vlan_prio & 0x7] && !skb_prio)
+               vlan->nr_ingress_mappings--;
+       else if (!vlan->ingress_priority_map[vlan_prio & 0x7] && skb_prio)
+               vlan->nr_ingress_mappings++;
 
-               dev_put(dev);
-       }
-       return -EINVAL;
+       vlan->ingress_priority_map[vlan_prio & 0x7] = skb_prio;
 }
 
-int vlan_dev_set_egress_priority(char *dev_name, __u32 skb_prio, short vlan_prio)
+int vlan_dev_set_egress_priority(const struct net_device *dev,
+                                u32 skb_prio, short vlan_prio)
 {
-       struct net_device *dev = dev_get_by_name(dev_name);
+       struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
        struct vlan_priority_tci_mapping *mp = NULL;
        struct vlan_priority_tci_mapping *np;
+       u32 vlan_qos = (vlan_prio << 13) & 0xE000;
 
-       if (dev) {
-               if (dev->priv_flags & IFF_802_1Q_VLAN) {
-                       /* See if a priority mapping exists.. */
-                       mp = VLAN_DEV_INFO(dev)->egress_priority_map[skb_prio & 0xF];
-                       while (mp) {
-                               if (mp->priority == skb_prio) {
-                                       mp->vlan_qos = ((vlan_prio << 13) & 0xE000);
-                                       dev_put(dev);
-                                       return 0;
-                               }
-                               mp = mp->next;
-                       }
-
-                       /* Create a new mapping then. */
-                       mp = VLAN_DEV_INFO(dev)->egress_priority_map[skb_prio & 0xF];
-                       np = kmalloc(sizeof(struct vlan_priority_tci_mapping), GFP_KERNEL);
-                       if (np) {
-                               np->next = mp;
-                               np->priority = skb_prio;
-                               np->vlan_qos = ((vlan_prio << 13) & 0xE000);
-                               VLAN_DEV_INFO(dev)->egress_priority_map[skb_prio & 0xF] = np;
-                               dev_put(dev);
-                               return 0;
-                       } else {
-                               dev_put(dev);
-                               return -ENOBUFS;
-                       }
-               }
-               dev_put(dev);
-       }
-       return -EINVAL;
-}
-
-/* Flags are defined in the vlan_dev_info class in include/linux/if_vlan.h file. */
-int vlan_dev_set_vlan_flag(char *dev_name, __u32 flag, short flag_val)
-{
-       struct net_device *dev = dev_get_by_name(dev_name);
-
-       if (dev) {
-               if (dev->priv_flags & IFF_802_1Q_VLAN) {
-                       /* verify flag is supported */
-                       if (flag == 1) {
-                               if (flag_val) {
-                                       VLAN_DEV_INFO(dev)->flags |= 1;
-                               } else {
-                                       VLAN_DEV_INFO(dev)->flags &= ~1;
-                               }
-                               dev_put(dev);
-                               return 0;
-                       } else {
-                               printk(KERN_ERR  "%s: flag %i is not valid.\n",
-                                       __FUNCTION__, (int)(flag));
-                               dev_put(dev);
-                               return -EINVAL;
-                       }
-               } else {
-                       printk(KERN_ERR
-                              "%s: %s is not a vlan device, priv_flags: %hX.\n",
-                              __FUNCTION__, dev->name, dev->priv_flags);
-                       dev_put(dev);
+       /* See if a priority mapping exists.. */
+       mp = vlan->egress_priority_map[skb_prio & 0xF];
+       while (mp) {
+               if (mp->priority == skb_prio) {
+                       if (mp->vlan_qos && !vlan_qos)
+                               vlan->nr_egress_mappings--;
+                       else if (!mp->vlan_qos && vlan_qos)
+                               vlan->nr_egress_mappings++;
+                       mp->vlan_qos = vlan_qos;
+                       return 0;
                }
-       } else {
-               printk(KERN_ERR  "%s: Could not find device: %s\n",
-                       __FUNCTION__, dev_name);
+               mp = mp->next;
        }
 
-       return -EINVAL;
+       /* Create a new mapping then. */
+       mp = vlan->egress_priority_map[skb_prio & 0xF];
+       np = kmalloc(sizeof(struct vlan_priority_tci_mapping), GFP_KERNEL);
+       if (!np)
+               return -ENOBUFS;
+
+       np->next = mp;
+       np->priority = skb_prio;
+       np->vlan_qos = vlan_qos;
+       vlan->egress_priority_map[skb_prio & 0xF] = np;
+       if (vlan_qos)
+               vlan->nr_egress_mappings++;
+       return 0;
 }
 
-
-int vlan_dev_get_realdev_name(const char *dev_name, char* result)
+/* Flags are defined in the vlan_flags enum in include/linux/if_vlan.h file. */
+int vlan_dev_set_vlan_flag(const struct net_device *dev,
+                          u32 flag, short flag_val)
 {
-       struct net_device *dev = dev_get_by_name(dev_name);
-       int rv = 0;
-       if (dev) {
-               if (dev->priv_flags & IFF_802_1Q_VLAN) {
-                       strncpy(result, VLAN_DEV_INFO(dev)->real_dev->name, 23);
-                       rv = 0;
+       /* verify flag is supported */
+       if (flag == VLAN_FLAG_REORDER_HDR) {
+               if (flag_val) {
+                       VLAN_DEV_INFO(dev)->flags |= VLAN_FLAG_REORDER_HDR;
                } else {
-                       rv = -EINVAL;
+                       VLAN_DEV_INFO(dev)->flags &= ~VLAN_FLAG_REORDER_HDR;
                }
-               dev_put(dev);
-       } else {
-               rv = -ENODEV;
+               return 0;
        }
-       return rv;
+       printk(KERN_ERR "%s: flag %i is not valid.\n", __FUNCTION__, flag);
+       return -EINVAL;
 }
 
-int vlan_dev_get_vid(const char *dev_name, unsigned short* result)
+void vlan_dev_get_realdev_name(const struct net_device *dev, char *result)
 {
-       struct net_device *dev = dev_get_by_name(dev_name);
-       int rv = 0;
-       if (dev) {
-               if (dev->priv_flags & IFF_802_1Q_VLAN) {
-                       *result = VLAN_DEV_INFO(dev)->vlan_id;
-                       rv = 0;
-               } else {
-                       rv = -EINVAL;
-               }
-               dev_put(dev);
-       } else {
-               rv = -ENODEV;
-       }
-       return rv;
+       strncpy(result, VLAN_DEV_INFO(dev)->real_dev->name, 23);
 }
 
-
-int vlan_dev_set_mac_address(struct net_device *dev, void *addr_struct_p)
+void vlan_dev_get_vid(const struct net_device *dev, unsigned short *result)
 {
-       struct sockaddr *addr = (struct sockaddr *)(addr_struct_p);
-       int i;
-
-       if (netif_running(dev))
-               return -EBUSY;
-
-       memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
-
-       printk("%s: Setting MAC address to ", dev->name);
-       for (i = 0; i < 6; i++)
-               printk(" %2.2x", dev->dev_addr[i]);
-       printk(".\n");
-
-       if (memcmp(VLAN_DEV_INFO(dev)->real_dev->dev_addr,
-                  dev->dev_addr,
-                  dev->addr_len) != 0) {
-               if (!(VLAN_DEV_INFO(dev)->real_dev->flags & IFF_PROMISC)) {
-                       int flgs = VLAN_DEV_INFO(dev)->real_dev->flags;
-
-                       /* Increment our in-use promiscuity counter */
-                       dev_set_promiscuity(VLAN_DEV_INFO(dev)->real_dev, 1);
-
-                       /* Make PROMISC visible to the user. */
-                       flgs |= IFF_PROMISC;
-                       printk("VLAN (%s):  Setting underlying device (%s) to promiscious mode.\n",
-                              dev->name, VLAN_DEV_INFO(dev)->real_dev->name);
-                       dev_change_flags(VLAN_DEV_INFO(dev)->real_dev, flgs);
-               }
-       } else {
-               printk("VLAN (%s):  Underlying device (%s) has same MAC, not checking promiscious mode.\n",
-                      dev->name, VLAN_DEV_INFO(dev)->real_dev->name);
-       }
-
-       return 0;
+       *result = VLAN_DEV_INFO(dev)->vlan_id;
 }
 
 static inline int vlan_dmi_equals(struct dev_mc_list *dmi1,
@@ -788,15 +698,32 @@ static void vlan_flush_mc_list(struct net_device *dev)
 
 int vlan_dev_open(struct net_device *dev)
 {
-       if (!(VLAN_DEV_INFO(dev)->real_dev->flags & IFF_UP))
+       struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
+       struct net_device *real_dev = vlan->real_dev;
+       int err;
+
+       if (!(real_dev->flags & IFF_UP))
                return -ENETDOWN;
 
+       if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) {
+               err = dev_unicast_add(real_dev, dev->dev_addr, ETH_ALEN);
+               if (err < 0)
+                       return err;
+       }
+       memcpy(vlan->real_dev_addr, real_dev->dev_addr, ETH_ALEN);
+
        return 0;
 }
 
 int vlan_dev_stop(struct net_device *dev)
 {
+       struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev;
+
        vlan_flush_mc_list(dev);
+
+       if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr))
+               dev_unicast_delete(real_dev, dev->dev_addr, dev->addr_len);
+
        return 0;
 }
 
diff --git a/net/8021q/vlan_netlink.c b/net/8021q/vlan_netlink.c
new file mode 100644 (file)
index 0000000..6cdd1e0
--- /dev/null
@@ -0,0 +1,243 @@
+/*
+ *     VLAN netlink control interface
+ *
+ *     Copyright (c) 2007 Patrick McHardy <kaber@trash.net>
+ *
+ *     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/netdevice.h>
+#include <linux/if_vlan.h>
+#include <net/netlink.h>
+#include <net/rtnetlink.h>
+#include "vlan.h"
+
+
+static const struct nla_policy vlan_policy[IFLA_VLAN_MAX + 1] = {
+       [IFLA_VLAN_ID]          = { .type = NLA_U16 },
+       [IFLA_VLAN_FLAGS]       = { .len = sizeof(struct ifla_vlan_flags) },
+       [IFLA_VLAN_EGRESS_QOS]  = { .type = NLA_NESTED },
+       [IFLA_VLAN_INGRESS_QOS] = { .type = NLA_NESTED },
+};
+
+static const struct nla_policy vlan_map_policy[IFLA_VLAN_QOS_MAX + 1] = {
+       [IFLA_VLAN_QOS_MAPPING] = { .len = sizeof(struct ifla_vlan_qos_mapping) },
+};
+
+
+static inline int vlan_validate_qos_map(struct nlattr *attr)
+{
+       if (!attr)
+               return 0;
+       return nla_validate_nested(attr, IFLA_VLAN_QOS_MAX, vlan_map_policy);
+}
+
+static int vlan_validate(struct nlattr *tb[], struct nlattr *data[])
+{
+       struct ifla_vlan_flags *flags;
+       u16 id;
+       int err;
+
+       if (tb[IFLA_ADDRESS]) {
+               if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
+                       return -EINVAL;
+               if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
+                       return -EADDRNOTAVAIL;
+       }
+
+       if (!data)
+               return -EINVAL;
+
+       if (data[IFLA_VLAN_ID]) {
+               id = nla_get_u16(data[IFLA_VLAN_ID]);
+               if (id >= VLAN_VID_MASK)
+                       return -ERANGE;
+       }
+       if (data[IFLA_VLAN_FLAGS]) {
+               flags = nla_data(data[IFLA_VLAN_FLAGS]);
+               if ((flags->flags & flags->mask) & ~VLAN_FLAG_REORDER_HDR)
+                       return -EINVAL;
+       }
+
+       err = vlan_validate_qos_map(data[IFLA_VLAN_INGRESS_QOS]);
+       if (err < 0)
+               return err;
+       err = vlan_validate_qos_map(data[IFLA_VLAN_EGRESS_QOS]);
+       if (err < 0)
+               return err;
+       return 0;
+}
+
+static int vlan_changelink(struct net_device *dev,
+                          struct nlattr *tb[], struct nlattr *data[])
+{
+       struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
+       struct ifla_vlan_flags *flags;
+       struct ifla_vlan_qos_mapping *m;
+       struct nlattr *attr;
+       int rem;
+
+       if (data[IFLA_VLAN_FLAGS]) {
+               flags = nla_data(data[IFLA_VLAN_FLAGS]);
+               vlan->flags = (vlan->flags & ~flags->mask) |
+                             (flags->flags & flags->mask);
+       }
+       if (data[IFLA_VLAN_INGRESS_QOS]) {
+               nla_for_each_nested(attr, data[IFLA_VLAN_INGRESS_QOS], rem) {
+                       m = nla_data(attr);
+                       vlan_dev_set_ingress_priority(dev, m->to, m->from);
+               }
+       }
+       if (data[IFLA_VLAN_EGRESS_QOS]) {
+               nla_for_each_nested(attr, data[IFLA_VLAN_EGRESS_QOS], rem) {
+                       m = nla_data(attr);
+                       vlan_dev_set_egress_priority(dev, m->from, m->to);
+               }
+       }
+       return 0;
+}
+
+static int vlan_newlink(struct net_device *dev,
+                       struct nlattr *tb[], struct nlattr *data[])
+{
+       struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
+       struct net_device *real_dev;
+       int err;
+
+       if (!data[IFLA_VLAN_ID])
+               return -EINVAL;
+
+       if (!tb[IFLA_LINK])
+               return -EINVAL;
+       real_dev = __dev_get_by_index(nla_get_u32(tb[IFLA_LINK]));
+       if (!real_dev)
+               return -ENODEV;
+
+       vlan->vlan_id  = nla_get_u16(data[IFLA_VLAN_ID]);
+       vlan->real_dev = real_dev;
+       vlan->flags    = VLAN_FLAG_REORDER_HDR;
+
+       err = vlan_check_real_dev(real_dev, vlan->vlan_id);
+       if (err < 0)
+               return err;
+
+       if (!tb[IFLA_MTU])
+               dev->mtu = real_dev->mtu;
+       else if (dev->mtu > real_dev->mtu)
+               return -EINVAL;
+
+       err = vlan_changelink(dev, tb, data);
+       if (err < 0)
+               return err;
+
+       return register_vlan_dev(dev);
+}
+
+static void vlan_dellink(struct net_device *dev)
+{
+       unregister_vlan_device(dev);
+}
+
+static inline size_t vlan_qos_map_size(unsigned int n)
+{
+       if (n == 0)
+               return 0;
+       /* IFLA_VLAN_{EGRESS,INGRESS}_QOS + n * IFLA_VLAN_QOS_MAPPING */
+       return nla_total_size(sizeof(struct nlattr)) +
+              nla_total_size(sizeof(struct ifla_vlan_qos_mapping)) * n;
+}
+
+static size_t vlan_get_size(const struct net_device *dev)
+{
+       struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
+
+       return nla_total_size(2) +      /* IFLA_VLAN_ID */
+              vlan_qos_map_size(vlan->nr_ingress_mappings) +
+              vlan_qos_map_size(vlan->nr_egress_mappings);
+}
+
+static int vlan_fill_info(struct sk_buff *skb, const struct net_device *dev)
+{
+       struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
+       struct vlan_priority_tci_mapping *pm;
+       struct ifla_vlan_flags f;
+       struct ifla_vlan_qos_mapping m;
+       struct nlattr *nest;
+       unsigned int i;
+
+       NLA_PUT_U16(skb, IFLA_VLAN_ID, VLAN_DEV_INFO(dev)->vlan_id);
+       if (vlan->flags) {
+               f.flags = vlan->flags;
+               f.mask  = ~0;
+               NLA_PUT(skb, IFLA_VLAN_FLAGS, sizeof(f), &f);
+       }
+       if (vlan->nr_ingress_mappings) {
+               nest = nla_nest_start(skb, IFLA_VLAN_INGRESS_QOS);
+               if (nest == NULL)
+                       goto nla_put_failure;
+
+               for (i = 0; i < ARRAY_SIZE(vlan->ingress_priority_map); i++) {
+                       if (!vlan->ingress_priority_map[i])
+                               continue;
+
+                       m.from = i;
+                       m.to   = vlan->ingress_priority_map[i];
+                       NLA_PUT(skb, IFLA_VLAN_QOS_MAPPING,
+                               sizeof(m), &m);
+               }
+               nla_nest_end(skb, nest);
+       }
+
+       if (vlan->nr_egress_mappings) {
+               nest = nla_nest_start(skb, IFLA_VLAN_EGRESS_QOS);
+               if (nest == NULL)
+                       goto nla_put_failure;
+
+               for (i = 0; i < ARRAY_SIZE(vlan->egress_priority_map); i++) {
+                       for (pm = vlan->egress_priority_map[i]; pm;
+                            pm = pm->next) {
+                               if (!pm->vlan_qos)
+                                       continue;
+
+                               m.from = pm->priority;
+                               m.to   = (pm->vlan_qos >> 13) & 0x7;
+                               NLA_PUT(skb, IFLA_VLAN_QOS_MAPPING,
+                                       sizeof(m), &m);
+                       }
+               }
+               nla_nest_end(skb, nest);
+       }
+       return 0;
+
+nla_put_failure:
+       return -EMSGSIZE;
+}
+
+struct rtnl_link_ops vlan_link_ops __read_mostly = {
+       .kind           = "vlan",
+       .maxtype        = IFLA_VLAN_MAX,
+       .policy         = vlan_policy,
+       .priv_size      = sizeof(struct vlan_dev_info),
+       .setup          = vlan_setup,
+       .validate       = vlan_validate,
+       .newlink        = vlan_newlink,
+       .changelink     = vlan_changelink,
+       .dellink        = vlan_dellink,
+       .get_size       = vlan_get_size,
+       .fill_info      = vlan_fill_info,
+};
+
+int __init vlan_netlink_init(void)
+{
+       return rtnl_link_register(&vlan_link_ops);
+}
+
+void __exit vlan_netlink_fini(void)
+{
+       rtnl_link_unregister(&vlan_link_ops);
+}
+
+MODULE_ALIAS_RTNL_LINK("vlan");
index d216a64421cd83eb19eeb021ae58b601ce3f63d0..c0040c9064a144a0f7afb3e47411eaed6ce13576 100644 (file)
@@ -69,7 +69,7 @@ static const char name_conf[]  = "config";
  *     Generic /proc/net/vlan/<file> file and inode operations
  */
 
-static struct seq_operations vlan_seq_ops = {
+static const struct seq_operations vlan_seq_ops = {
        .start = vlan_seq_start,
        .next = vlan_seq_next,
        .stop = vlan_seq_stop,
@@ -342,7 +342,7 @@ static int vlandev_seq_show(struct seq_file *seq, void *offset)
        seq_printf(seq, "Device: %s", dev_info->real_dev->name);
        /* now show all PRIORITY mappings relating to this VLAN */
        seq_printf(seq,
-                      "\nINGRESS priority mappings: 0:%lu  1:%lu  2:%lu  3:%lu  4:%lu  5:%lu  6:%lu 7:%lu\n",
+                      "\nINGRESS priority mappings: 0:%u  1:%u  2:%u  3:%u  4:%u  5:%u  6:%u 7:%u\n",
                       dev_info->ingress_priority_map[0],
                       dev_info->ingress_priority_map[1],
                       dev_info->ingress_priority_map[2],
@@ -357,7 +357,7 @@ static int vlandev_seq_show(struct seq_file *seq, void *offset)
                const struct vlan_priority_tci_mapping *mp
                        = dev_info->egress_priority_map[i];
                while (mp) {
-                       seq_printf(seq, "%lu:%hu ",
+                       seq_printf(seq, "%u:%hu ",
                                   mp->priority, ((mp->vlan_qos >> 13) & 0x7));
                        mp = mp->next;
                }
index 34e5b2d7f87783e568eb3b67b47598657c974815..a87a88963432014f13bfab6e343b697ad2e55467 100644 (file)
@@ -37,7 +37,6 @@ obj-$(CONFIG_AX25)            += ax25/
 obj-$(CONFIG_IRDA)             += irda/
 obj-$(CONFIG_BT)               += bluetooth/
 obj-$(CONFIG_SUNRPC)           += sunrpc/
-obj-$(CONFIG_RXRPC)            += rxrpc/
 obj-$(CONFIG_AF_RXRPC)         += rxrpc/
 obj-$(CONFIG_ATM)              += atm/
 obj-$(CONFIG_DECNET)           += decnet/
index 5ef6a238bdbc7b043fee57bddaf1433867004775..3d1655f983887593e8541994c17b59e502446667 100644 (file)
@@ -1024,7 +1024,7 @@ static int aarp_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations aarp_seq_ops = {
+static const struct seq_operations aarp_seq_ops = {
        .start  = aarp_seq_start,
        .next   = aarp_seq_next,
        .stop   = aarp_seq_stop,
index 57ff8122b5c59b8da1e0d0a44abce1f38ef710b9..87a582cc811195482a3e2ddd638525db6ae4f4fd 100644 (file)
@@ -204,21 +204,21 @@ out:
        return 0;
 }
 
-static struct seq_operations atalk_seq_interface_ops = {
+static const struct seq_operations atalk_seq_interface_ops = {
        .start  = atalk_seq_interface_start,
        .next   = atalk_seq_interface_next,
        .stop   = atalk_seq_interface_stop,
        .show   = atalk_seq_interface_show,
 };
 
-static struct seq_operations atalk_seq_route_ops = {
+static const struct seq_operations atalk_seq_route_ops = {
        .start  = atalk_seq_route_start,
        .next   = atalk_seq_route_next,
        .stop   = atalk_seq_route_stop,
        .show   = atalk_seq_route_show,
 };
 
-static struct seq_operations atalk_seq_socket_ops = {
+static const struct seq_operations atalk_seq_socket_ops = {
        .start  = atalk_seq_socket_start,
        .next   = atalk_seq_socket_next,
        .stop   = atalk_seq_socket_stop,
index 0e9f00c5c89942cfccbd5f76afa84e82f7afc4cc..faa6aaf67563ff298121518ffc192655a85be2ab 100644 (file)
@@ -699,28 +699,13 @@ static struct atm_ioctl br2684_ioctl_ops = {
 #ifdef CONFIG_PROC_FS
 static void *br2684_seq_start(struct seq_file *seq, loff_t *pos)
 {
-       loff_t offs = 0;
-       struct br2684_dev *brd;
-
        read_lock(&devs_lock);
-
-       list_for_each_entry(brd, &br2684_devs, br2684_devs) {
-               if (offs == *pos)
-                       return brd;
-               ++offs;
-       }
-       return NULL;
+       return seq_list_start(&br2684_devs, *pos);
 }
 
 static void *br2684_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
-       struct br2684_dev *brd = v;
-
-       ++*pos;
-
-       brd = list_entry(brd->br2684_devs.next,
-                        struct br2684_dev, br2684_devs);
-       return (&brd->br2684_devs != &br2684_devs) ? brd : NULL;
+       return seq_list_next(v, &br2684_devs, pos);
 }
 
 static void br2684_seq_stop(struct seq_file *seq, void *v)
@@ -730,7 +715,8 @@ static void br2684_seq_stop(struct seq_file *seq, void *v)
 
 static int br2684_seq_show(struct seq_file *seq, void *v)
 {
-       const struct br2684_dev *brdev = v;
+       const struct br2684_dev *brdev = list_entry(v, struct br2684_dev,
+                       br2684_devs);
        const struct net_device *net_dev = brdev->net_dev;
        const struct br2684_vcc *brvcc;
 
@@ -772,7 +758,7 @@ static int br2684_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations br2684_seq_ops = {
+static const struct seq_operations br2684_seq_ops = {
        .start = br2684_seq_start,
        .next  = br2684_seq_next,
        .stop  = br2684_seq_stop,
index 876b77f1474521b8e9a77a425cac5e7e53edb2cb..ecf0f79b94ae0d17f9e061433a7e4a9f328f55d9 100644 (file)
@@ -928,7 +928,7 @@ static int clip_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations arp_seq_ops = {
+static const struct seq_operations arp_seq_ops = {
        .start  = clip_seq_start,
        .next   = neigh_seq_next,
        .stop   = neigh_seq_stop,
index 4dc5f2b8c43c23631fe06f45c49ffd2e84a5d786..2770fb451ae87dbe089cc32a16eef523fb18a374 100644 (file)
@@ -1174,7 +1174,7 @@ static int lec_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations lec_seq_ops = {
+static const struct seq_operations lec_seq_ops = {
        .start = lec_seq_start,
        .next = lec_seq_next,
        .stop = lec_seq_stop,
index 4b05cbec7a581c8d44a14dfe3dbcfe593e961c40..91f3ffc90dbdc938a211b46aaccb565a51b5be40 100644 (file)
@@ -177,7 +177,7 @@ static int mpc_show(struct seq_file *m, void *v)
        return 0;
 }
 
-static struct seq_operations mpc_op = {
+static const struct seq_operations mpc_op = {
        .start =        mpc_start,
        .next =         mpc_next,
        .stop =         mpc_stop,
index 9e61e512f6670d77f0f7f0e2a55d1f79cb60ff5d..88154da62cd32840c576545410b0f0bc09532b38 100644 (file)
@@ -260,7 +260,7 @@ static int atm_dev_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations atm_dev_seq_ops = {
+static const struct seq_operations atm_dev_seq_ops = {
        .start  = atm_dev_seq_start,
        .next   = atm_dev_seq_next,
        .stop   = atm_dev_seq_stop,
@@ -295,7 +295,7 @@ static int pvc_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations pvc_seq_ops = {
+static const struct seq_operations pvc_seq_ops = {
        .start  = vcc_seq_start,
        .next   = vcc_seq_next,
        .stop   = vcc_seq_stop,
@@ -329,7 +329,7 @@ static int vcc_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations vcc_seq_ops = {
+static const struct seq_operations vcc_seq_ops = {
        .start  = vcc_seq_start,
        .next   = vcc_seq_next,
        .stop   = vcc_seq_stop,
@@ -364,7 +364,7 @@ static int svc_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations svc_seq_ops = {
+static const struct seq_operations svc_seq_ops = {
        .start  = vcc_seq_start,
        .next   = vcc_seq_next,
        .stop   = vcc_seq_stop,
index 429e13a6c6ad41ab7bab2b2d6e6bdde0d57aed1e..c83cf84329700219ed4d16710bebcc5a4cb9f2c6 100644 (file)
@@ -1924,7 +1924,7 @@ static int ax25_info_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations ax25_info_seqops = {
+static const struct seq_operations ax25_info_seqops = {
        .start = ax25_info_start,
        .next = ax25_info_next,
        .stop = ax25_info_stop,
index d65b8e22868d9a4c5e1f7a47ddbbfa3cc21080d9..9ecf6f1df863078c3a238a079787123a1df5f437 100644 (file)
@@ -320,7 +320,7 @@ static int ax25_rt_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations ax25_rt_seqops = {
+static const struct seq_operations ax25_rt_seqops = {
        .start = ax25_rt_seq_start,
        .next = ax25_rt_seq_next,
        .stop = ax25_rt_seq_stop,
index 75c76647b2cbdf62d0d76948d4558ec272d41cfa..ce0b13d44385fad3c588a0ee7087ee58d6189a2e 100644 (file)
@@ -185,7 +185,7 @@ static int ax25_uid_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations ax25_uid_seqops = {
+static const struct seq_operations ax25_uid_seqops = {
        .start = ax25_uid_seq_start,
        .next = ax25_uid_seq_next,
        .stop = ax25_uid_seq_stop,
index 63980bd6b5f2e404f1b73f6163517767f0b1a349..5fdfc9a67d390fbf9cc00190f289f877cde88074 100644 (file)
@@ -123,8 +123,8 @@ void hci_add_sco(struct hci_conn *conn, __u16 handle)
        conn->state = BT_CONNECT;
        conn->out = 1;
 
-       cp.pkt_type = cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK);
        cp.handle   = cpu_to_le16(handle);
+       cp.pkt_type = cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK);
 
        hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ADD_SCO, sizeof(cp), &cp);
 }
@@ -220,19 +220,19 @@ int hci_conn_del(struct hci_conn *conn)
 
        del_timer(&conn->disc_timer);
 
-       if (conn->type == SCO_LINK) {
-               struct hci_conn *acl = conn->link;
-               if (acl) {
-                       acl->link = NULL;
-                       hci_conn_put(acl);
-               }
-       } else {
+       if (conn->type == ACL_LINK) {
                struct hci_conn *sco = conn->link;
                if (sco)
                        sco->link = NULL;
 
                /* Unacked frames */
                hdev->acl_cnt += conn->sent;
+       } else {
+               struct hci_conn *acl = conn->link;
+               if (acl) {
+                       acl->link = NULL;
+                       hci_conn_put(acl);
+               }
        }
 
        tasklet_disable(&hdev->tx_task);
@@ -297,9 +297,10 @@ EXPORT_SYMBOL(hci_get_route);
 
 /* Create SCO or ACL connection.
  * Device _must_ be locked */
-struct hci_conn * hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst)
+struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst)
 {
        struct hci_conn *acl;
+       struct hci_conn *sco;
 
        BT_DBG("%s dst %s", hdev->name, batostr(dst));
 
@@ -313,28 +314,26 @@ struct hci_conn * hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst)
        if (acl->state == BT_OPEN || acl->state == BT_CLOSED)
                hci_acl_connect(acl);
 
-       if (type == SCO_LINK) {
-               struct hci_conn *sco;
+       if (type == ACL_LINK)
+               return acl;
 
-               if (!(sco = hci_conn_hash_lookup_ba(hdev, SCO_LINK, dst))) {
-                       if (!(sco = hci_conn_add(hdev, SCO_LINK, dst))) {
-                               hci_conn_put(acl);
-                               return NULL;
-                       }
+       if (!(sco = hci_conn_hash_lookup_ba(hdev, type, dst))) {
+               if (!(sco = hci_conn_add(hdev, type, dst))) {
+                       hci_conn_put(acl);
+                       return NULL;
                }
-               acl->link = sco;
-               sco->link = acl;
+       }
 
-               hci_conn_hold(sco);
+       acl->link = sco;
+       sco->link = acl;
 
-               if (acl->state == BT_CONNECTED &&
-                               (sco->state == BT_OPEN || sco->state == BT_CLOSED))
-                       hci_add_sco(sco, acl->handle);
+       hci_conn_hold(sco);
 
-               return sco;
-       } else {
-               return acl;
-       }
+       if (acl->state == BT_CONNECTED &&
+                       (sco->state == BT_OPEN || sco->state == BT_CLOSED))
+               hci_add_sco(sco, acl->handle);
+
+       return sco;
 }
 EXPORT_SYMBOL(hci_connect);
 
index aa4b56a8c3eafe7fd12fd66aefcab024d9a1061d..f6d867e0179f3e3cd1692161997d1abeb49948dc 100644 (file)
@@ -826,7 +826,7 @@ EXPORT_SYMBOL(hci_free_dev);
 int hci_register_dev(struct hci_dev *hdev)
 {
        struct list_head *head = &hci_dev_list, *p;
-       int id = 0;
+       int i, id = 0;
 
        BT_DBG("%p name %s type %d owner %p", hdev, hdev->name, hdev->type, hdev->owner);
 
@@ -851,6 +851,7 @@ int hci_register_dev(struct hci_dev *hdev)
 
        hdev->flags = 0;
        hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
+       hdev->esco_type = (ESCO_HV1);
        hdev->link_mode = (HCI_LM_ACCEPT);
 
        hdev->idle_timeout = 0;
@@ -865,6 +866,9 @@ int hci_register_dev(struct hci_dev *hdev)
        skb_queue_head_init(&hdev->cmd_q);
        skb_queue_head_init(&hdev->raw_q);
 
+       for (i = 0; i < 3; i++)
+               hdev->reassembly[i] = NULL;
+
        init_waitqueue_head(&hdev->req_wait_q);
        init_MUTEX(&hdev->req_lock);
 
@@ -889,6 +893,8 @@ EXPORT_SYMBOL(hci_register_dev);
 /* Unregister HCI device */
 int hci_unregister_dev(struct hci_dev *hdev)
 {
+       int i;
+
        BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
 
        hci_unregister_sysfs(hdev);
@@ -899,9 +905,13 @@ int hci_unregister_dev(struct hci_dev *hdev)
 
        hci_dev_do_close(hdev);
 
+       for (i = 0; i < 3; i++)
+               kfree_skb(hdev->reassembly[i]);
+
        hci_notify(hdev, HCI_DEV_UNREG);
 
        __hci_dev_put(hdev);
+
        return 0;
 }
 EXPORT_SYMBOL(hci_unregister_dev);
@@ -922,6 +932,90 @@ int hci_resume_dev(struct hci_dev *hdev)
 }
 EXPORT_SYMBOL(hci_resume_dev);
 
+/* Receive packet type fragment */
+#define __reassembly(hdev, type)  ((hdev)->reassembly[(type) - 2])
+
+int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
+{
+       if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
+               return -EILSEQ;
+
+       while (count) {
+               struct sk_buff *skb = __reassembly(hdev, type);
+               struct { int expect; } *scb;
+               int len = 0;
+
+               if (!skb) {
+                       /* Start of the frame */
+
+                       switch (type) {
+                       case HCI_EVENT_PKT:
+                               if (count >= HCI_EVENT_HDR_SIZE) {
+                                       struct hci_event_hdr *h = data;
+                                       len = HCI_EVENT_HDR_SIZE + h->plen;
+                               } else
+                                       return -EILSEQ;
+                               break;
+
+                       case HCI_ACLDATA_PKT:
+                               if (count >= HCI_ACL_HDR_SIZE) {
+                                       struct hci_acl_hdr *h = data;
+                                       len = HCI_ACL_HDR_SIZE + __le16_to_cpu(h->dlen);
+                               } else
+                                       return -EILSEQ;
+                               break;
+
+                       case HCI_SCODATA_PKT:
+                               if (count >= HCI_SCO_HDR_SIZE) {
+                                       struct hci_sco_hdr *h = data;
+                                       len = HCI_SCO_HDR_SIZE + h->dlen;
+                               } else
+                                       return -EILSEQ;
+                               break;
+                       }
+
+                       skb = bt_skb_alloc(len, GFP_ATOMIC);
+                       if (!skb) {
+                               BT_ERR("%s no memory for packet", hdev->name);
+                               return -ENOMEM;
+                       }
+
+                       skb->dev = (void *) hdev;
+                       bt_cb(skb)->pkt_type = type;
+       
+                       __reassembly(hdev, type) = skb;
+
+                       scb = (void *) skb->cb;
+                       scb->expect = len;
+               } else {
+                       /* Continuation */
+
+                       scb = (void *) skb->cb;
+                       len = scb->expect;
+               }
+
+               len = min(len, count);
+
+               memcpy(skb_put(skb, len), data, len);
+
+               scb->expect -= len;
+
+               if (scb->expect == 0) {
+                       /* Complete frame */
+
+                       __reassembly(hdev, type) = NULL;
+
+                       bt_cb(skb)->pkt_type = type;
+                       hci_recv_frame(skb);
+               }
+
+               count -= len; data += len;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(hci_recv_fragment);
+
 /* ---- Interface to upper protocols ---- */
 
 /* Register/Unregister protocols.
@@ -1029,7 +1123,7 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *p
 
        skb = bt_skb_alloc(len, GFP_ATOMIC);
        if (!skb) {
-               BT_ERR("%s Can't allocate memory for HCI command", hdev->name);
+               BT_ERR("%s no memory for command", hdev->name);
                return -ENOMEM;
        }
 
@@ -1161,7 +1255,7 @@ EXPORT_SYMBOL(hci_send_sco);
 static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote)
 {
        struct hci_conn_hash *h = &hdev->conn_hash;
-       struct hci_conn  *conn = NULL;
+       struct hci_conn *conn = NULL;
        int num = 0, min = ~0;
        struct list_head *p;
 
index 447ba7131220a172cde09e0f34e6a6dc2dc0ea4f..4baea1e3865222cff1bb8c2238eafd11712ba39a 100644 (file)
@@ -350,11 +350,24 @@ static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *s
                if (hdev->features[0] & LMP_5SLOT)
                        hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
 
-               if (hdev->features[1] & LMP_HV2)
-                       hdev->pkt_type |= (HCI_HV2);
+               if (hdev->features[1] & LMP_HV2) {
+                       hdev->pkt_type  |= (HCI_HV2);
+                       hdev->esco_type |= (ESCO_HV2);
+               }
+
+               if (hdev->features[1] & LMP_HV3) {
+                       hdev->pkt_type  |= (HCI_HV3);
+                       hdev->esco_type |= (ESCO_HV3);
+               }
 
-               if (hdev->features[1] & LMP_HV3)
-                       hdev->pkt_type |= (HCI_HV3);
+               if (hdev->features[3] & LMP_ESCO)
+                       hdev->esco_type |= (ESCO_EV3);
+
+               if (hdev->features[4] & LMP_EV4)
+                       hdev->esco_type |= (ESCO_EV4);
+
+               if (hdev->features[4] & LMP_EV5)
+                       hdev->esco_type |= (ESCO_EV5);
 
                BT_DBG("%s: features 0x%x 0x%x 0x%x", hdev->name,
                                lf->features[0], lf->features[1], lf->features[2]);
@@ -881,12 +894,12 @@ static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *s
                if (conn) {
                        conn->sent -= count;
 
-                       if (conn->type == SCO_LINK) {
-                               if ((hdev->sco_cnt += count) > hdev->sco_pkts)
-                                       hdev->sco_cnt = hdev->sco_pkts;
-                       } else {
+                       if (conn->type == ACL_LINK) {
                                if ((hdev->acl_cnt += count) > hdev->acl_pkts)
                                        hdev->acl_cnt = hdev->acl_pkts;
+                       } else {
+                               if ((hdev->sco_cnt += count) > hdev->sco_pkts)
+                                       hdev->sco_cnt = hdev->sco_pkts;
                        }
                }
        }
index b2b1cceb102a1961c9d1e9c7161228c232281ec7..23ba61a13bdd7a2260889b191ced54c0a658a452 100644 (file)
@@ -95,6 +95,10 @@ static void rfcomm_dev_destruct(struct rfcomm_dev *dev)
 
        BT_DBG("dev %p dlc %p", dev, dlc);
 
+       write_lock_bh(&rfcomm_dev_lock);
+       list_del_init(&dev->list);
+       write_unlock_bh(&rfcomm_dev_lock);
+
        rfcomm_dlc_lock(dlc);
        /* Detach DLC if it's owned by this dev */
        if (dlc->owner == dev)
@@ -156,8 +160,13 @@ static inline struct rfcomm_dev *rfcomm_dev_get(int id)
        read_lock(&rfcomm_dev_lock);
 
        dev = __rfcomm_dev_get(id);
-       if (dev)
-               rfcomm_dev_hold(dev);
+
+       if (dev) {
+               if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags))
+                       dev = NULL;
+               else
+                       rfcomm_dev_hold(dev);
+       }
 
        read_unlock(&rfcomm_dev_lock);
 
@@ -265,6 +274,12 @@ out:
 
        dev->tty_dev = tty_register_device(rfcomm_tty_driver, dev->id, NULL);
 
+       if (IS_ERR(dev->tty_dev)) {
+               list_del(&dev->list);
+               kfree(dev);
+               return PTR_ERR(dev->tty_dev);
+       }
+
        return dev->id;
 }
 
@@ -272,10 +287,7 @@ static void rfcomm_dev_del(struct rfcomm_dev *dev)
 {
        BT_DBG("dev %p", dev);
 
-       write_lock_bh(&rfcomm_dev_lock);
-       list_del_init(&dev->list);
-       write_unlock_bh(&rfcomm_dev_lock);
-
+       set_bit(RFCOMM_TTY_RELEASED, &dev->flags);
        rfcomm_dev_put(dev);
 }
 
@@ -329,7 +341,7 @@ static int rfcomm_create_dev(struct sock *sk, void __user *arg)
        if (copy_from_user(&req, arg, sizeof(req)))
                return -EFAULT;
 
-       BT_DBG("sk %p dev_id %id flags 0x%x", sk, req.dev_id, req.flags);
+       BT_DBG("sk %p dev_id %d flags 0x%x", sk, req.dev_id, req.flags);
 
        if (req.flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN))
                return -EPERM;
@@ -370,7 +382,7 @@ static int rfcomm_release_dev(void __user *arg)
        if (copy_from_user(&req, arg, sizeof(req)))
                return -EFAULT;
 
-       BT_DBG("dev_id %id flags 0x%x", req.dev_id, req.flags);
+       BT_DBG("dev_id %d flags 0x%x", req.dev_id, req.flags);
 
        if (!(dev = rfcomm_dev_get(req.dev_id)))
                return -ENODEV;
@@ -383,6 +395,10 @@ static int rfcomm_release_dev(void __user *arg)
        if (req.flags & (1 << RFCOMM_HANGUP_NOW))
                rfcomm_dlc_close(dev->dlc, 0);
 
+       /* Shut down TTY synchronously before freeing rfcomm_dev */
+       if (dev->tty)
+               tty_vhangup(dev->tty);
+
        rfcomm_dev_del(dev);
        rfcomm_dev_put(dev);
        return 0;
@@ -415,6 +431,8 @@ static int rfcomm_get_dev_list(void __user *arg)
 
        list_for_each(p, &rfcomm_dev_list) {
                struct rfcomm_dev *dev = list_entry(p, struct rfcomm_dev, list);
+               if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags))
+                       continue;
                (di + n)->id      = dev->id;
                (di + n)->flags   = dev->flags;
                (di + n)->state   = dev->dlc->state;
index 849deaf14108c285e550eb43e3fe828c507fbefc..7b4ce9113be2e7dafb201ba47ea724e08bb2abb4 100644 (file)
@@ -368,10 +368,18 @@ void br_features_recompute(struct net_bridge *br)
        list_for_each_entry(p, &br->port_list, list) {
                unsigned long feature = p->dev->features;
 
+               /* if device needs checksumming, downgrade to hw checksumming */
                if (checksum & NETIF_F_NO_CSUM && !(feature & NETIF_F_NO_CSUM))
                        checksum ^= NETIF_F_NO_CSUM | NETIF_F_HW_CSUM;
+
+               /* if device can't do all checksum, downgrade to ipv4/ipv6 */
                if (checksum & NETIF_F_HW_CSUM && !(feature & NETIF_F_HW_CSUM))
-                       checksum ^= NETIF_F_HW_CSUM | NETIF_F_IP_CSUM;
+                       checksum ^= NETIF_F_HW_CSUM
+                               | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+
+               if (checksum & NETIF_F_IPV6_CSUM && !(feature & NETIF_F_IPV6_CSUM))
+                       checksum &= ~NETIF_F_IPV6_CSUM;
+
                if (!(feature & NETIF_F_IP_CSUM))
                        checksum = 0;
 
index 33c6c4a7c689d76f25299c0cdb730d33315f8e73..4f42263e0a8a8ba8e3e45d2979f34508b19ecbc4 100644 (file)
@@ -360,8 +360,9 @@ static struct attribute_group bridge_group = {
  *
  * Returns the number of bytes read.
  */
-static ssize_t brforward_read(struct kobject *kobj, char *buf,
-                          loff_t off, size_t count)
+static ssize_t brforward_read(struct kobject *kobj,
+                             struct bin_attribute *bin_attr,
+                             char *buf, loff_t off, size_t count)
 {
        struct device *dev = to_dev(kobj);
        struct net_bridge *br = to_bridge(dev);
@@ -383,8 +384,7 @@ static ssize_t brforward_read(struct kobject *kobj, char *buf,
 
 static struct bin_attribute bridge_forward = {
        .attr = { .name = SYSFS_BRIDGE_FDB,
-                 .mode = S_IRUGO,
-                 .owner = THIS_MODULE, },
+                 .mode = S_IRUGO, },
        .read = brforward_read,
 };
 
index 2da22927d8dd158ea341fe53d896dc1f53ea52b6..79db51fcb4768dabb001c5afb17325c6ad00a634 100644 (file)
@@ -29,8 +29,7 @@ struct brport_attribute {
 #define BRPORT_ATTR(_name,_mode,_show,_store)                  \
 struct brport_attribute brport_attr_##_name = {                \
        .attr = {.name = __stringify(_name),                    \
-                .mode = _mode,                                 \
-                .owner = THIS_MODULE, },                       \
+                .mode = _mode },                               \
        .show   = _show,                                        \
        .store  = _store,                                       \
 };
index 835202fb34c47d9b07b23e2afea8ae7848f320e7..96443055324ea9116c35374b7b1e8d6cee54f906 100644 (file)
@@ -955,7 +955,7 @@ int dev_open(struct net_device *dev)
                /*
                 *      Initialize multicasting status
                 */
-               dev_mc_upload(dev);
+               dev_set_rx_mode(dev);
 
                /*
                 *      Wakeup transmit queue engine
@@ -1442,7 +1442,9 @@ gso:
                        skb->next = nskb;
                        return rc;
                }
-               if (unlikely(netif_queue_stopped(dev) && skb->next))
+               if (unlikely((netif_queue_stopped(dev) ||
+                            netif_subqueue_stopped(dev, skb->queue_mapping)) &&
+                            skb->next))
                        return NETDEV_TX_BUSY;
        } while (skb->next);
 
@@ -1523,8 +1525,10 @@ int dev_queue_xmit(struct sk_buff *skb)
                                              skb_headroom(skb));
 
                if (!(dev->features & NETIF_F_GEN_CSUM) &&
-                   (!(dev->features & NETIF_F_IP_CSUM) ||
-                    skb->protocol != htons(ETH_P_IP)))
+                   !((dev->features & NETIF_F_IP_CSUM) &&
+                     skb->protocol == htons(ETH_P_IP)) &&
+                   !((dev->features & NETIF_F_IPV6_CSUM) &&
+                     skb->protocol == htons(ETH_P_IPV6)))
                        if (skb_checksum_help(skb))
                                goto out_kfree_skb;
        }
@@ -1558,6 +1562,8 @@ gso:
                spin_lock(&dev->queue_lock);
                q = dev->qdisc;
                if (q->enqueue) {
+                       /* reset queue_mapping to zero */
+                       skb->queue_mapping = 0;
                        rc = q->enqueue(skb, q);
                        qdisc_run(dev);
                        spin_unlock(&dev->queue_lock);
@@ -1587,7 +1593,8 @@ gso:
 
                        HARD_TX_LOCK(dev, cpu);
 
-                       if (!netif_queue_stopped(dev)) {
+                       if (!netif_queue_stopped(dev) &&
+                           !netif_subqueue_stopped(dev, skb->queue_mapping)) {
                                rc = 0;
                                if (!dev_hard_start_xmit(skb, dev)) {
                                        HARD_TX_UNLOCK(dev);
@@ -2510,17 +2517,7 @@ int netdev_set_master(struct net_device *slave, struct net_device *master)
        return 0;
 }
 
-/**
- *     dev_set_promiscuity     - update promiscuity count on a device
- *     @dev: device
- *     @inc: modifier
- *
- *     Add or remove promiscuity from a device. While the count in the device
- *     remains above zero the interface remains promiscuous. Once it hits zero
- *     the device reverts back to normal filtering operation. A negative inc
- *     value is used to drop promiscuity on the device.
- */
-void dev_set_promiscuity(struct net_device *dev, int inc)
+static void __dev_set_promiscuity(struct net_device *dev, int inc)
 {
        unsigned short old_flags = dev->flags;
 
@@ -2529,7 +2526,6 @@ void dev_set_promiscuity(struct net_device *dev, int inc)
        else
                dev->flags |= IFF_PROMISC;
        if (dev->flags != old_flags) {
-               dev_mc_upload(dev);
                printk(KERN_INFO "device %s %s promiscuous mode\n",
                       dev->name, (dev->flags & IFF_PROMISC) ? "entered" :
                                                               "left");
@@ -2542,6 +2538,25 @@ void dev_set_promiscuity(struct net_device *dev, int inc)
        }
 }
 
+/**
+ *     dev_set_promiscuity     - update promiscuity count on a device
+ *     @dev: device
+ *     @inc: modifier
+ *
+ *     Add or remove promiscuity from a device. While the count in the device
+ *     remains above zero the interface remains promiscuous. Once it hits zero
+ *     the device reverts back to normal filtering operation. A negative inc
+ *     value is used to drop promiscuity on the device.
+ */
+void dev_set_promiscuity(struct net_device *dev, int inc)
+{
+       unsigned short old_flags = dev->flags;
+
+       __dev_set_promiscuity(dev, inc);
+       if (dev->flags != old_flags)
+               dev_set_rx_mode(dev);
+}
+
 /**
  *     dev_set_allmulti        - update allmulti count on a device
  *     @dev: device
@@ -2562,7 +2577,176 @@ void dev_set_allmulti(struct net_device *dev, int inc)
        if ((dev->allmulti += inc) == 0)
                dev->flags &= ~IFF_ALLMULTI;
        if (dev->flags ^ old_flags)
-               dev_mc_upload(dev);
+               dev_set_rx_mode(dev);
+}
+
+/*
+ *     Upload unicast and multicast address lists to device and
+ *     configure RX filtering. When the device doesn't support unicast
+ *     filtering it is put in promiscous mode while unicast addresses
+ *     are present.
+ */
+void __dev_set_rx_mode(struct net_device *dev)
+{
+       /* dev_open will call this function so the list will stay sane. */
+       if (!(dev->flags&IFF_UP))
+               return;
+
+       if (!netif_device_present(dev))
+               return;
+
+       if (dev->set_rx_mode)
+               dev->set_rx_mode(dev);
+       else {
+               /* Unicast addresses changes may only happen under the rtnl,
+                * therefore calling __dev_set_promiscuity here is safe.
+                */
+               if (dev->uc_count > 0 && !dev->uc_promisc) {
+                       __dev_set_promiscuity(dev, 1);
+                       dev->uc_promisc = 1;
+               } else if (dev->uc_count == 0 && dev->uc_promisc) {
+                       __dev_set_promiscuity(dev, -1);
+                       dev->uc_promisc = 0;
+               }
+
+               if (dev->set_multicast_list)
+                       dev->set_multicast_list(dev);
+       }
+}
+
+void dev_set_rx_mode(struct net_device *dev)
+{
+       netif_tx_lock_bh(dev);
+       __dev_set_rx_mode(dev);
+       netif_tx_unlock_bh(dev);
+}
+
+int __dev_addr_delete(struct dev_addr_list **list, int *count,
+                     void *addr, int alen, int glbl)
+{
+       struct dev_addr_list *da;
+
+       for (; (da = *list) != NULL; list = &da->next) {
+               if (memcmp(da->da_addr, addr, da->da_addrlen) == 0 &&
+                   alen == da->da_addrlen) {
+                       if (glbl) {
+                               int old_glbl = da->da_gusers;
+                               da->da_gusers = 0;
+                               if (old_glbl == 0)
+                                       break;
+                       }
+                       if (--da->da_users)
+                               return 0;
+
+                       *list = da->next;
+                       kfree(da);
+                       (*count)--;
+                       return 0;
+               }
+       }
+       return -ENOENT;
+}
+
+int __dev_addr_add(struct dev_addr_list **list, int *count,
+                  void *addr, int alen, int glbl)
+{
+       struct dev_addr_list *da;
+
+       for (da = *list; da != NULL; da = da->next) {
+               if (memcmp(da->da_addr, addr, da->da_addrlen) == 0 &&
+                   da->da_addrlen == alen) {
+                       if (glbl) {
+                               int old_glbl = da->da_gusers;
+                               da->da_gusers = 1;
+                               if (old_glbl)
+                                       return 0;
+                       }
+                       da->da_users++;
+                       return 0;
+               }
+       }
+
+       da = kmalloc(sizeof(*da), GFP_ATOMIC);
+       if (da == NULL)
+               return -ENOMEM;
+       memcpy(da->da_addr, addr, alen);
+       da->da_addrlen = alen;
+       da->da_users = 1;
+       da->da_gusers = glbl ? 1 : 0;
+       da->next = *list;
+       *list = da;
+       (*count)++;
+       return 0;
+}
+
+void __dev_addr_discard(struct dev_addr_list **list)
+{
+       struct dev_addr_list *tmp;
+
+       while (*list != NULL) {
+               tmp = *list;
+               *list = tmp->next;
+               if (tmp->da_users > tmp->da_gusers)
+                       printk("__dev_addr_discard: address leakage! "
+                              "da_users=%d\n", tmp->da_users);
+               kfree(tmp);
+       }
+}
+
+/**
+ *     dev_unicast_delete      - Release secondary unicast address.
+ *     @dev: device
+ *
+ *     Release reference to a secondary unicast address and remove it
+ *     from the device if the reference count drop to zero.
+ *
+ *     The caller must hold the rtnl_mutex.
+ */
+int dev_unicast_delete(struct net_device *dev, void *addr, int alen)
+{
+       int err;
+
+       ASSERT_RTNL();
+
+       netif_tx_lock_bh(dev);
+       err = __dev_addr_delete(&dev->uc_list, &dev->uc_count, addr, alen, 0);
+       if (!err)
+               __dev_set_rx_mode(dev);
+       netif_tx_unlock_bh(dev);
+       return err;
+}
+EXPORT_SYMBOL(dev_unicast_delete);
+
+/**
+ *     dev_unicast_add         - add a secondary unicast address
+ *     @dev: device
+ *
+ *     Add a secondary unicast address to the device or increase
+ *     the reference count if it already exists.
+ *
+ *     The caller must hold the rtnl_mutex.
+ */
+int dev_unicast_add(struct net_device *dev, void *addr, int alen)
+{
+       int err;
+
+       ASSERT_RTNL();
+
+       netif_tx_lock_bh(dev);
+       err = __dev_addr_add(&dev->uc_list, &dev->uc_count, addr, alen, 0);
+       if (!err)
+               __dev_set_rx_mode(dev);
+       netif_tx_unlock_bh(dev);
+       return err;
+}
+EXPORT_SYMBOL(dev_unicast_add);
+
+static void dev_unicast_discard(struct net_device *dev)
+{
+       netif_tx_lock_bh(dev);
+       __dev_addr_discard(&dev->uc_list);
+       dev->uc_count = 0;
+       netif_tx_unlock_bh(dev);
 }
 
 unsigned dev_get_flags(const struct net_device *dev)
@@ -2608,7 +2792,7 @@ int dev_change_flags(struct net_device *dev, unsigned flags)
         *      Load in the correct multicast list now the flags have changed.
         */
 
-       dev_mc_upload(dev);
+       dev_set_rx_mode(dev);
 
        /*
         *      Have we downed the interface. We handle IFF_UP ourselves
@@ -2621,7 +2805,7 @@ int dev_change_flags(struct net_device *dev, unsigned flags)
                ret = ((old_flags & IFF_UP) ? dev_close : dev_open)(dev);
 
                if (!ret)
-                       dev_mc_upload(dev);
+                       dev_set_rx_mode(dev);
        }
 
        if (dev->flags & IFF_UP &&
@@ -3121,6 +3305,22 @@ int register_netdevice(struct net_device *dev)
                }
        }
 
+       /* Fix illegal checksum combinations */
+       if ((dev->features & NETIF_F_HW_CSUM) &&
+           (dev->features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) {
+               printk(KERN_NOTICE "%s: mixed HW and IP checksum settings.\n",
+                      dev->name);
+               dev->features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM);
+       }
+
+       if ((dev->features & NETIF_F_NO_CSUM) &&
+           (dev->features & (NETIF_F_HW_CSUM|NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) {
+               printk(KERN_NOTICE "%s: mixed no checksumming and other settings.\n",
+                      dev->name);
+               dev->features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM|NETIF_F_HW_CSUM);
+       }
+
+
        /* Fix illegal SG+CSUM combinations. */
        if ((dev->features & NETIF_F_SG) &&
            !(dev->features & NETIF_F_ALL_CSUM)) {
@@ -3357,16 +3557,18 @@ static struct net_device_stats *internal_stats(struct net_device *dev)
 }
 
 /**
- *     alloc_netdev - allocate network device
+ *     alloc_netdev_mq - allocate network device
  *     @sizeof_priv:   size of private data to allocate space for
  *     @name:          device name format string
  *     @setup:         callback to initialize device
+ *     @queue_count:   the number of subqueues to allocate
  *
  *     Allocates a struct net_device with private data area for driver use
- *     and performs basic initialization.
+ *     and performs basic initialization.  Also allocates subquue structs
+ *     for each queue on the device at the end of the netdevice.
  */
-struct net_device *alloc_netdev(int sizeof_priv, const char *name,
-               void (*setup)(struct net_device *))
+struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
+               void (*setup)(struct net_device *), unsigned int queue_count)
 {
        void *p;
        struct net_device *dev;
@@ -3375,7 +3577,9 @@ struct net_device *alloc_netdev(int sizeof_priv, const char *name,
        BUG_ON(strlen(name) >= sizeof(dev->name));
 
        /* ensure 32-byte alignment of both the device and private area */
-       alloc_size = (sizeof(*dev) + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST;
+       alloc_size = (sizeof(*dev) + NETDEV_ALIGN_CONST +
+                    (sizeof(struct net_device_subqueue) * queue_count)) &
+                    ~NETDEV_ALIGN_CONST;
        alloc_size += sizeof_priv + NETDEV_ALIGN_CONST;
 
        p = kzalloc(alloc_size, GFP_KERNEL);
@@ -3388,15 +3592,22 @@ struct net_device *alloc_netdev(int sizeof_priv, const char *name,
                (((long)p + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST);
        dev->padded = (char *)dev - (char *)p;
 
-       if (sizeof_priv)
-               dev->priv = netdev_priv(dev);
+       if (sizeof_priv) {
+               dev->priv = ((char *)dev +
+                            ((sizeof(struct net_device) +
+                              (sizeof(struct net_device_subqueue) *
+                               queue_count) + NETDEV_ALIGN_CONST)
+                             & ~NETDEV_ALIGN_CONST));
+       }
+
+       dev->egress_subqueue_count = queue_count;
 
        dev->get_stats = internal_stats;
        setup(dev);
        strcpy(dev->name, name);
        return dev;
 }
-EXPORT_SYMBOL(alloc_netdev);
+EXPORT_SYMBOL(alloc_netdev_mq);
 
 /**
  *     free_netdev - free network device
@@ -3485,8 +3696,9 @@ void unregister_netdevice(struct net_device *dev)
        raw_notifier_call_chain(&netdev_chain, NETDEV_UNREGISTER, dev);
 
        /*
-        *      Flush the multicast chain
+        *      Flush the unicast and multicast chains
         */
+       dev_unicast_discard(dev);
        dev_mc_discard(dev);
 
        if (dev->uninit)
index 5a54053386c83253430b3f18b764fe3cb89bef30..aa38100601fb31d2c6d73e83ddb30f62d884c45a 100644 (file)
  *     We block accesses to device mc filters with netif_tx_lock.
  */
 
-/*
- *     Update the multicast list into the physical NIC controller.
- */
-
-static void __dev_mc_upload(struct net_device *dev)
-{
-       /* Don't do anything till we up the interface
-        * [dev_open will call this function so the list will
-        * stay sane]
-        */
-
-       if (!(dev->flags&IFF_UP))
-               return;
-
-       /*
-        *      Devices with no set multicast or which have been
-        *      detached don't get set.
-        */
-
-       if (dev->set_multicast_list == NULL ||
-           !netif_device_present(dev))
-               return;
-
-       dev->set_multicast_list(dev);
-}
-
-void dev_mc_upload(struct net_device *dev)
-{
-       netif_tx_lock_bh(dev);
-       __dev_mc_upload(dev);
-       netif_tx_unlock_bh(dev);
-}
-
 /*
  *     Delete a device level multicast
  */
 
 int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl)
 {
-       int err = 0;
-       struct dev_mc_list *dmi, **dmip;
+       int err;
 
        netif_tx_lock_bh(dev);
-
-       for (dmip = &dev->mc_list; (dmi = *dmip) != NULL; dmip = &dmi->next) {
+       err = __dev_addr_delete(&dev->mc_list, &dev->mc_count,
+                               addr, alen, glbl);
+       if (!err) {
                /*
-                *      Find the entry we want to delete. The device could
-                *      have variable length entries so check these too.
+                *      We have altered the list, so the card
+                *      loaded filter is now wrong. Fix it
                 */
-               if (memcmp(dmi->dmi_addr, addr, dmi->dmi_addrlen) == 0 &&
-                   alen == dmi->dmi_addrlen) {
-                       if (glbl) {
-                               int old_glbl = dmi->dmi_gusers;
-                               dmi->dmi_gusers = 0;
-                               if (old_glbl == 0)
-                                       break;
-                       }
-                       if (--dmi->dmi_users)
-                               goto done;
 
-                       /*
-                        *      Last user. So delete the entry.
-                        */
-                       *dmip = dmi->next;
-                       dev->mc_count--;
-
-                       kfree(dmi);
-
-                       /*
-                        *      We have altered the list, so the card
-                        *      loaded filter is now wrong. Fix it
-                        */
-                       __dev_mc_upload(dev);
-
-                       netif_tx_unlock_bh(dev);
-                       return 0;
-               }
+               __dev_set_rx_mode(dev);
        }
-       err = -ENOENT;
-done:
        netif_tx_unlock_bh(dev);
        return err;
 }
@@ -153,46 +92,13 @@ done:
 
 int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl)
 {
-       int err = 0;
-       struct dev_mc_list *dmi, *dmi1;
-
-       dmi1 = kmalloc(sizeof(*dmi), GFP_ATOMIC);
+       int err;
 
        netif_tx_lock_bh(dev);
-       for (dmi = dev->mc_list; dmi != NULL; dmi = dmi->next) {
-               if (memcmp(dmi->dmi_addr, addr, dmi->dmi_addrlen) == 0 &&
-                   dmi->dmi_addrlen == alen) {
-                       if (glbl) {
-                               int old_glbl = dmi->dmi_gusers;
-                               dmi->dmi_gusers = 1;
-                               if (old_glbl)
-                                       goto done;
-                       }
-                       dmi->dmi_users++;
-                       goto done;
-               }
-       }
-
-       if ((dmi = dmi1) == NULL) {
-               netif_tx_unlock_bh(dev);
-               return -ENOMEM;
-       }
-       memcpy(dmi->dmi_addr, addr, alen);
-       dmi->dmi_addrlen = alen;
-       dmi->next = dev->mc_list;
-       dmi->dmi_users = 1;
-       dmi->dmi_gusers = glbl ? 1 : 0;
-       dev->mc_list = dmi;
-       dev->mc_count++;
-
-       __dev_mc_upload(dev);
-
-       netif_tx_unlock_bh(dev);
-       return 0;
-
-done:
+       err = __dev_addr_add(&dev->mc_list, &dev->mc_count, addr, alen, glbl);
+       if (!err)
+               __dev_set_rx_mode(dev);
        netif_tx_unlock_bh(dev);
-       kfree(dmi1);
        return err;
 }
 
@@ -203,16 +109,8 @@ done:
 void dev_mc_discard(struct net_device *dev)
 {
        netif_tx_lock_bh(dev);
-
-       while (dev->mc_list != NULL) {
-               struct dev_mc_list *tmp = dev->mc_list;
-               dev->mc_list = tmp->next;
-               if (tmp->dmi_users > tmp->dmi_gusers)
-                       printk("dev_mc_discard: multicast leakage! dmi_users=%d\n", tmp->dmi_users);
-               kfree(tmp);
-       }
+       __dev_addr_discard(&dev->mc_list);
        dev->mc_count = 0;
-
        netif_tx_unlock_bh(dev);
 }
 
@@ -244,7 +142,7 @@ static void dev_mc_seq_stop(struct seq_file *seq, void *v)
 
 static int dev_mc_seq_show(struct seq_file *seq, void *v)
 {
-       struct dev_mc_list *m;
+       struct dev_addr_list *m;
        struct net_device *dev = v;
 
        netif_tx_lock_bh(dev);
@@ -292,4 +190,3 @@ void __init dev_mcast_init(void)
 
 EXPORT_SYMBOL(dev_mc_add);
 EXPORT_SYMBOL(dev_mc_delete);
-EXPORT_SYMBOL(dev_mc_upload);
index 17daf4c9f79384ad0005fbec5780cc8bd6f63321..cc84d8d8a3c7d6c6c6e06a18080cfb99c50d86fa 100644 (file)
@@ -128,7 +128,8 @@ static void est_timer(unsigned long arg)
                spin_unlock(e->stats_lock);
        }
 
-       mod_timer(&elist[idx].timer, jiffies + ((HZ<<idx)/4));
+       if (elist[idx].list != NULL)
+               mod_timer(&elist[idx].timer, jiffies + ((HZ<<idx)/4));
        read_unlock(&est_lock);
 }
 
index a0efdd7a6b375951546319eb9717167edd301972..d1264e9a50a8afe71abd41dc7805770df2e2ff2c 100644 (file)
@@ -66,8 +66,9 @@ static void queue_process(struct work_struct *work)
 
                local_irq_save(flags);
                netif_tx_lock(dev);
-               if (netif_queue_stopped(dev) ||
-                   dev->hard_start_xmit(skb, dev) != NETDEV_TX_OK) {
+               if ((netif_queue_stopped(dev) ||
+                    netif_subqueue_stopped(dev, skb->queue_mapping)) ||
+                    dev->hard_start_xmit(skb, dev) != NETDEV_TX_OK) {
                        skb_queue_head(&npinfo->txq, skb);
                        netif_tx_unlock(dev);
                        local_irq_restore(flags);
@@ -123,6 +124,13 @@ static void poll_napi(struct netpoll *np)
        if (test_bit(__LINK_STATE_RX_SCHED, &np->dev->state) &&
            npinfo->poll_owner != smp_processor_id() &&
            spin_trylock(&npinfo->poll_lock)) {
+               /* When calling dev->poll from poll_napi, we may end up in
+                * netif_rx_complete. However, only the CPU to which the
+                * device was queued is allowed to remove it from poll_list.
+                * Setting POLL_LIST_FROZEN tells netif_rx_complete
+                * to leave the NAPI state alone.
+                */
+               set_bit(__LINK_STATE_POLL_LIST_FROZEN, &np->dev->state);
                npinfo->rx_flags |= NETPOLL_RX_DROP;
                atomic_inc(&trapped);
 
@@ -130,6 +138,7 @@ static void poll_napi(struct netpoll *np)
 
                atomic_dec(&trapped);
                npinfo->rx_flags &= ~NETPOLL_RX_DROP;
+               clear_bit(__LINK_STATE_POLL_LIST_FROZEN, &np->dev->state);
                spin_unlock(&npinfo->poll_lock);
        }
 }
@@ -254,7 +263,8 @@ static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
                for (tries = jiffies_to_usecs(1)/USEC_PER_POLL;
                     tries > 0; --tries) {
                        if (netif_tx_trylock(dev)) {
-                               if (!netif_queue_stopped(dev))
+                               if (!netif_queue_stopped(dev) &&
+                                   !netif_subqueue_stopped(dev, skb->queue_mapping))
                                        status = dev->hard_start_xmit(skb, dev);
                                netif_tx_unlock(dev);
 
@@ -781,7 +791,6 @@ void netpoll_cleanup(struct netpoll *np)
                                spin_unlock_irqrestore(&npinfo->rx_lock, flags);
                        }
 
-                       np->dev->npinfo = NULL;
                        if (atomic_dec_and_test(&npinfo->refcnt)) {
                                skb_queue_purge(&npinfo->arp_tx);
                                skb_queue_purge(&npinfo->txq);
@@ -794,6 +803,7 @@ void netpoll_cleanup(struct netpoll *np)
                                        kfree_skb(skb);
                                }
                                kfree(npinfo);
+                               np->dev->npinfo = NULL;
                        }
                }
 
index 9cd3a1cb60ef33b485075cb4ce49183d13f9c67b..75215331b0457b122088f91d8f4d67d4382d27dc 100644 (file)
 #include <net/checksum.h>
 #include <net/ipv6.h>
 #include <net/addrconf.h>
+#ifdef CONFIG_XFRM
+#include <net/xfrm.h>
+#endif
 #include <asm/byteorder.h>
 #include <linux/rcupdate.h>
 #include <asm/bitops.h>
 #define F_MPLS_RND    (1<<8)   /* Random MPLS labels */
 #define F_VID_RND     (1<<9)   /* Random VLAN ID */
 #define F_SVID_RND    (1<<10)  /* Random SVLAN ID */
+#define F_FLOW_SEQ    (1<<11)  /* Sequential flows */
+#define F_IPSEC_ON    (1<<12)  /* ipsec on for flows */
 
 /* Thread control flag bits */
 #define T_TERMINATE   (1<<0)
@@ -207,8 +212,15 @@ static struct proc_dir_entry *pg_proc_dir = NULL;
 struct flow_state {
        __be32 cur_daddr;
        int count;
+#ifdef CONFIG_XFRM
+       struct xfrm_state *x;
+#endif
+       __u32 flags;
 };
 
+/* flow flag bits */
+#define F_INIT   (1<<0)                /* flow has been initialized */
+
 struct pktgen_dev {
        /*
         * Try to keep frequent/infrequent used vars. separated.
@@ -228,6 +240,7 @@ struct pktgen_dev {
 
        int min_pkt_size;       /* = ETH_ZLEN; */
        int max_pkt_size;       /* = ETH_ZLEN; */
+       int pkt_overhead;       /* overhead for MPLS, VLANs, IPSEC etc */
        int nfrags;
        __u32 delay_us;         /* Default delay */
        __u32 delay_ns;
@@ -341,7 +354,11 @@ struct pktgen_dev {
        unsigned cflows;        /* Concurrent flows (config) */
        unsigned lflow;         /* Flow length  (config) */
        unsigned nflows;        /* accumulated flows (stats) */
-
+       unsigned curfl;         /* current sequenced flow (state)*/
+#ifdef CONFIG_XFRM
+       __u8    ipsmode;                /* IPSEC mode (config) */
+       __u8    ipsproto;               /* IPSEC type (config) */
+#endif
        char result[512];
 };
 
@@ -690,6 +707,18 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
        if (pkt_dev->flags & F_MPLS_RND)
                seq_printf(seq,  "MPLS_RND  ");
 
+       if (pkt_dev->cflows) {
+               if (pkt_dev->flags & F_FLOW_SEQ)
+                       seq_printf(seq,  "FLOW_SEQ  "); /*in sequence flows*/
+               else
+                       seq_printf(seq,  "FLOW_RND  ");
+       }
+
+#ifdef CONFIG_XFRM
+       if (pkt_dev->flags & F_IPSEC_ON)
+               seq_printf(seq,  "IPSEC  ");
+#endif
+
        if (pkt_dev->flags & F_MACSRC_RND)
                seq_printf(seq, "MACSRC_RND  ");
 
@@ -1181,6 +1210,14 @@ static ssize_t pktgen_if_write(struct file *file,
                else if (strcmp(f, "!SVID_RND") == 0)
                        pkt_dev->flags &= ~F_SVID_RND;
 
+               else if (strcmp(f, "FLOW_SEQ") == 0)
+                       pkt_dev->flags |= F_FLOW_SEQ;
+
+#ifdef CONFIG_XFRM
+               else if (strcmp(f, "IPSEC") == 0)
+                       pkt_dev->flags |= F_IPSEC_ON;
+#endif
+
                else if (strcmp(f, "!IPV6") == 0)
                        pkt_dev->flags &= ~F_IPV6;
 
@@ -1189,7 +1226,7 @@ static ssize_t pktgen_if_write(struct file *file,
                                "Flag -:%s:- unknown\nAvailable flags, (prepend ! to un-set flag):\n%s",
                                f,
                                "IPSRC_RND, IPDST_RND, UDPSRC_RND, UDPDST_RND, "
-                               "MACSRC_RND, MACDST_RND, TXSIZE_RND, IPV6, MPLS_RND, VID_RND, SVID_RND\n");
+                               "MACSRC_RND, MACDST_RND, TXSIZE_RND, IPV6, MPLS_RND, VID_RND, SVID_RND, FLOW_SEQ, IPSEC\n");
                        return count;
                }
                sprintf(pg_result, "OK: flags=0x%x", pkt_dev->flags);
@@ -2075,6 +2112,70 @@ static void spin(struct pktgen_dev *pkt_dev, __u64 spin_until_us)
        pkt_dev->idle_acc += now - start;
 }
 
+static inline void set_pkt_overhead(struct pktgen_dev *pkt_dev)
+{
+       pkt_dev->pkt_overhead = 0;
+       pkt_dev->pkt_overhead += pkt_dev->nr_labels*sizeof(u32);
+       pkt_dev->pkt_overhead += VLAN_TAG_SIZE(pkt_dev);
+       pkt_dev->pkt_overhead += SVLAN_TAG_SIZE(pkt_dev);
+}
+
+static inline int f_seen(struct pktgen_dev *pkt_dev, int flow)
+{
+
+       if (pkt_dev->flows[flow].flags & F_INIT)
+               return 1;
+       else
+               return 0;
+}
+
+static inline int f_pick(struct pktgen_dev *pkt_dev)
+{
+       int flow = pkt_dev->curfl;
+
+       if (pkt_dev->flags & F_FLOW_SEQ) {
+               if (pkt_dev->flows[flow].count >= pkt_dev->lflow) {
+                       /* reset time */
+                       pkt_dev->flows[flow].count = 0;
+                       pkt_dev->curfl += 1;
+                       if (pkt_dev->curfl >= pkt_dev->cflows)
+                               pkt_dev->curfl = 0; /*reset */
+               }
+       } else {
+               flow = random32() % pkt_dev->cflows;
+
+               if (pkt_dev->flows[flow].count > pkt_dev->lflow)
+                       pkt_dev->flows[flow].count = 0;
+       }
+
+       return pkt_dev->curfl;
+}
+
+
+#ifdef CONFIG_XFRM
+/* If there was already an IPSEC SA, we keep it as is, else
+ * we go look for it ...
+*/
+inline
+void get_ipsec_sa(struct pktgen_dev *pkt_dev, int flow)
+{
+       struct xfrm_state *x = pkt_dev->flows[flow].x;
+       if (!x) {
+               /*slow path: we dont already have xfrm_state*/
+               x = xfrm_stateonly_find((xfrm_address_t *)&pkt_dev->cur_daddr,
+                                       (xfrm_address_t *)&pkt_dev->cur_saddr,
+                                       AF_INET,
+                                       pkt_dev->ipsmode,
+                                       pkt_dev->ipsproto, 0);
+               if (x) {
+                       pkt_dev->flows[flow].x = x;
+                       set_pkt_overhead(pkt_dev);
+                       pkt_dev->pkt_overhead+=x->props.header_len;
+               }
+
+       }
+}
+#endif
 /* Increment/randomize headers according to flags and current values
  * for IP src/dest, UDP src/dst port, MAC-Addr src/dst
  */
@@ -2084,12 +2185,8 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
        __u32 imx;
        int flow = 0;
 
-       if (pkt_dev->cflows) {
-               flow = random32() % pkt_dev->cflows;
-
-               if (pkt_dev->flows[flow].count > pkt_dev->lflow)
-                       pkt_dev->flows[flow].count = 0;
-       }
+       if (pkt_dev->cflows)
+               flow = f_pick(pkt_dev);
 
        /*  Deal with source MAC */
        if (pkt_dev->src_mac_count > 1) {
@@ -2205,7 +2302,7 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
                        pkt_dev->cur_saddr = htonl(t);
                }
 
-               if (pkt_dev->cflows && pkt_dev->flows[flow].count != 0) {
+               if (pkt_dev->cflows && f_seen(pkt_dev, flow)) {
                        pkt_dev->cur_daddr = pkt_dev->flows[flow].cur_daddr;
                } else {
                        imn = ntohl(pkt_dev->daddr_min);
@@ -2235,8 +2332,13 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
                                }
                        }
                        if (pkt_dev->cflows) {
+                               pkt_dev->flows[flow].flags |= F_INIT;
                                pkt_dev->flows[flow].cur_daddr =
                                    pkt_dev->cur_daddr;
+#ifdef CONFIG_XFRM
+                               if (pkt_dev->flags & F_IPSEC_ON)
+                                       get_ipsec_sa(pkt_dev, flow);
+#endif
                                pkt_dev->nflows++;
                        }
                }
@@ -2277,6 +2379,91 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
        pkt_dev->flows[flow].count++;
 }
 
+
+#ifdef CONFIG_XFRM
+static int pktgen_output_ipsec(struct sk_buff *skb, struct pktgen_dev *pkt_dev)
+{
+       struct xfrm_state *x = pkt_dev->flows[pkt_dev->curfl].x;
+       int err = 0;
+       struct iphdr *iph;
+
+       if (!x)
+               return 0;
+       /* XXX: we dont support tunnel mode for now until
+        * we resolve the dst issue */
+       if (x->props.mode != XFRM_MODE_TRANSPORT)
+               return 0;
+
+       spin_lock(&x->lock);
+       iph = ip_hdr(skb);
+
+       err = x->mode->output(x, skb);
+       if (err)
+               goto error;
+       err = x->type->output(x, skb);
+       if (err)
+               goto error;
+
+       x->curlft.bytes +=skb->len;
+       x->curlft.packets++;
+       spin_unlock(&x->lock);
+
+error:
+       spin_unlock(&x->lock);
+       return err;
+}
+
+static inline void free_SAs(struct pktgen_dev *pkt_dev)
+{
+       if (pkt_dev->cflows) {
+               /* let go of the SAs if we have them */
+               int i = 0;
+               for (;  i < pkt_dev->nflows; i++){
+                       struct xfrm_state *x = pkt_dev->flows[i].x;
+                       if (x) {
+                               xfrm_state_put(x);
+                               pkt_dev->flows[i].x = NULL;
+                       }
+               }
+       }
+}
+
+static inline int process_ipsec(struct pktgen_dev *pkt_dev,
+                             struct sk_buff *skb, __be16 protocol)
+{
+       if (pkt_dev->flags & F_IPSEC_ON) {
+               struct xfrm_state *x = pkt_dev->flows[pkt_dev->curfl].x;
+               int nhead = 0;
+               if (x) {
+                       int ret;
+                       __u8 *eth;
+                       nhead = x->props.header_len - skb_headroom(skb);
+                       if (nhead >0) {
+                               ret = pskb_expand_head(skb, nhead, 0, GFP_ATOMIC);
+                               if (ret < 0) {
+                                       printk("Error expanding ipsec packet %d\n",ret);
+                                       return 0;
+                               }
+                       }
+
+                       /* ipsec is not expecting ll header */
+                       skb_pull(skb, ETH_HLEN);
+                       ret = pktgen_output_ipsec(skb, pkt_dev);
+                       if (ret) {
+                               printk("Error creating ipsec packet %d\n",ret);
+                               kfree_skb(skb);
+                               return 0;
+                       }
+                       /* restore ll */
+                       eth = (__u8 *) skb_push(skb, ETH_HLEN);
+                       memcpy(eth, pkt_dev->hh, 12);
+                       *(u16 *) & eth[12] = protocol;
+               }
+       }
+       return 1;
+}
+#endif
+
 static void mpls_push(__be32 *mpls, struct pktgen_dev *pkt_dev)
 {
        unsigned i;
@@ -2323,9 +2510,7 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
 
        datalen = (odev->hard_header_len + 16) & ~0xf;
        skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + datalen +
-                       pkt_dev->nr_labels*sizeof(u32) +
-                       VLAN_TAG_SIZE(pkt_dev) + SVLAN_TAG_SIZE(pkt_dev),
-                       GFP_ATOMIC);
+                       pkt_dev->pkt_overhead, GFP_ATOMIC);
        if (!skb) {
                sprintf(pkt_dev->result, "No memory");
                return NULL;
@@ -2368,7 +2553,7 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
 
        /* Eth + IPh + UDPh + mpls */
        datalen = pkt_dev->cur_pkt_size - 14 - 20 - 8 -
-                 pkt_dev->nr_labels*sizeof(u32) - VLAN_TAG_SIZE(pkt_dev) - SVLAN_TAG_SIZE(pkt_dev);
+                 pkt_dev->pkt_overhead;
        if (datalen < sizeof(struct pktgen_hdr))
                datalen = sizeof(struct pktgen_hdr);
 
@@ -2391,8 +2576,7 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
        iph->check = ip_fast_csum((void *)iph, iph->ihl);
        skb->protocol = protocol;
        skb->mac_header = (skb->network_header - ETH_HLEN -
-                          pkt_dev->nr_labels * sizeof(u32) -
-                          VLAN_TAG_SIZE(pkt_dev) - SVLAN_TAG_SIZE(pkt_dev));
+                          pkt_dev->pkt_overhead);
        skb->dev = odev;
        skb->pkt_type = PACKET_HOST;
 
@@ -2463,6 +2647,11 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
                pgh->tv_usec = htonl(timestamp.tv_usec);
        }
 
+#ifdef CONFIG_XFRM
+       if (!process_ipsec(pkt_dev, skb, protocol))
+               return NULL;
+#endif
+
        return skb;
 }
 
@@ -2662,9 +2851,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
        mod_cur_headers(pkt_dev);
 
        skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + 16 +
-                       pkt_dev->nr_labels*sizeof(u32) +
-                       VLAN_TAG_SIZE(pkt_dev) + SVLAN_TAG_SIZE(pkt_dev),
-                       GFP_ATOMIC);
+                       pkt_dev->pkt_overhead, GFP_ATOMIC);
        if (!skb) {
                sprintf(pkt_dev->result, "No memory");
                return NULL;
@@ -2708,7 +2895,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
        /* Eth + IPh + UDPh + mpls */
        datalen = pkt_dev->cur_pkt_size - 14 -
                  sizeof(struct ipv6hdr) - sizeof(struct udphdr) -
-                 pkt_dev->nr_labels*sizeof(u32) - VLAN_TAG_SIZE(pkt_dev) - SVLAN_TAG_SIZE(pkt_dev);
+                 pkt_dev->pkt_overhead;
 
        if (datalen < sizeof(struct pktgen_hdr)) {
                datalen = sizeof(struct pktgen_hdr);
@@ -2738,8 +2925,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
        ipv6_addr_copy(&iph->saddr, &pkt_dev->cur_in6_saddr);
 
        skb->mac_header = (skb->network_header - ETH_HLEN -
-                          pkt_dev->nr_labels * sizeof(u32) -
-                          VLAN_TAG_SIZE(pkt_dev) - SVLAN_TAG_SIZE(pkt_dev));
+                          pkt_dev->pkt_overhead);
        skb->protocol = protocol;
        skb->dev = odev;
        skb->pkt_type = PACKET_HOST;
@@ -2857,6 +3043,7 @@ static void pktgen_run(struct pktgen_thread *t)
                        pkt_dev->started_at = getCurUs();
                        pkt_dev->next_tx_us = getCurUs();       /* Transmit immediately */
                        pkt_dev->next_tx_ns = 0;
+                       set_pkt_overhead(pkt_dev);
 
                        strcpy(pkt_dev->result, "Starting");
                        started++;
@@ -3139,7 +3326,9 @@ static __inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev)
                }
        }
 
-       if (netif_queue_stopped(odev) || need_resched()) {
+       if ((netif_queue_stopped(odev) ||
+            netif_subqueue_stopped(odev, pkt_dev->skb->queue_mapping)) ||
+            need_resched()) {
                idle_start = getCurUs();
 
                if (!netif_running(odev)) {
@@ -3154,7 +3343,8 @@ static __inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev)
 
                pkt_dev->idle_acc += getCurUs() - idle_start;
 
-               if (netif_queue_stopped(odev)) {
+               if (netif_queue_stopped(odev) ||
+                   netif_subqueue_stopped(odev, pkt_dev->skb->queue_mapping)) {
                        pkt_dev->next_tx_us = getCurUs();       /* TODO */
                        pkt_dev->next_tx_ns = 0;
                        goto out;       /* Try the next interface */
@@ -3181,7 +3371,8 @@ static __inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev)
        }
 
        netif_tx_lock_bh(odev);
-       if (!netif_queue_stopped(odev)) {
+       if (!netif_queue_stopped(odev) &&
+           !netif_subqueue_stopped(odev, pkt_dev->skb->queue_mapping)) {
 
                atomic_inc(&(pkt_dev->skb->users));
              retry_now:
@@ -3446,11 +3637,18 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname)
        }
        pkt_dev->entry->proc_fops = &pktgen_if_fops;
        pkt_dev->entry->data = pkt_dev;
+#ifdef CONFIG_XFRM
+       pkt_dev->ipsmode = XFRM_MODE_TRANSPORT;
+       pkt_dev->ipsproto = IPPROTO_ESP;
+#endif
 
        return add_dev_to_thread(t, pkt_dev);
 out2:
        dev_put(pkt_dev->odev);
 out1:
+#ifdef CONFIG_XFRM
+       free_SAs(pkt_dev);
+#endif
        if (pkt_dev->flows)
                vfree(pkt_dev->flows);
        kfree(pkt_dev);
@@ -3545,6 +3743,9 @@ static int pktgen_remove_device(struct pktgen_thread *t,
        if (pkt_dev->entry)
                remove_proc_entry(pkt_dev->entry->name, pg_proc_dir);
 
+#ifdef CONFIG_XFRM
+       free_SAs(pkt_dev);
+#endif
        if (pkt_dev->flows)
                vfree(pkt_dev->flows);
        kfree(pkt_dev);
index 02e8bf084277963300be7cd68f7a8b6de67cab59..864cbdf31ed7f49b2ab73c44b1de818db70b505d 100644 (file)
@@ -97,6 +97,19 @@ int rtattr_parse(struct rtattr *tb[], int maxattr, struct rtattr *rta, int len)
        return 0;
 }
 
+int __rtattr_parse_nested_compat(struct rtattr *tb[], int maxattr,
+                                struct rtattr *rta, int len)
+{
+       if (RTA_PAYLOAD(rta) < len)
+               return -1;
+       if (RTA_PAYLOAD(rta) >= RTA_ALIGN(len) + sizeof(struct rtattr)) {
+               rta = RTA_DATA(rta) + RTA_ALIGN(len);
+               return rtattr_parse_nested(tb, maxattr, rta);
+       }
+       memset(tb, 0, sizeof(struct rtattr *) * maxattr);
+       return 0;
+}
+
 static struct rtnl_link *rtnl_msg_handlers[NPROTO];
 
 static inline int rtm_msgindex(int msgtype)
@@ -243,6 +256,150 @@ void rtnl_unregister_all(int protocol)
 
 EXPORT_SYMBOL_GPL(rtnl_unregister_all);
 
+static LIST_HEAD(link_ops);
+
+/**
+ * __rtnl_link_register - Register rtnl_link_ops with rtnetlink.
+ * @ops: struct rtnl_link_ops * to register
+ *
+ * The caller must hold the rtnl_mutex. This function should be used
+ * by drivers that create devices during module initialization. It
+ * must be called before registering the devices.
+ *
+ * Returns 0 on success or a negative error code.
+ */
+int __rtnl_link_register(struct rtnl_link_ops *ops)
+{
+       if (!ops->dellink)
+               ops->dellink = unregister_netdevice;
+
+       list_add_tail(&ops->list, &link_ops);
+       return 0;
+}
+
+EXPORT_SYMBOL_GPL(__rtnl_link_register);
+
+/**
+ * rtnl_link_register - Register rtnl_link_ops with rtnetlink.
+ * @ops: struct rtnl_link_ops * to register
+ *
+ * Returns 0 on success or a negative error code.
+ */
+int rtnl_link_register(struct rtnl_link_ops *ops)
+{
+       int err;
+
+       rtnl_lock();
+       err = __rtnl_link_register(ops);
+       rtnl_unlock();
+       return err;
+}
+
+EXPORT_SYMBOL_GPL(rtnl_link_register);
+
+/**
+ * __rtnl_link_unregister - Unregister rtnl_link_ops from rtnetlink.
+ * @ops: struct rtnl_link_ops * to unregister
+ *
+ * The caller must hold the rtnl_mutex.
+ */
+void __rtnl_link_unregister(struct rtnl_link_ops *ops)
+{
+       struct net_device *dev, *n;
+
+       for_each_netdev_safe(dev, n) {
+               if (dev->rtnl_link_ops == ops)
+                       ops->dellink(dev);
+       }
+       list_del(&ops->list);
+}
+
+EXPORT_SYMBOL_GPL(__rtnl_link_unregister);
+
+/**
+ * rtnl_link_unregister - Unregister rtnl_link_ops from rtnetlink.
+ * @ops: struct rtnl_link_ops * to unregister
+ */
+void rtnl_link_unregister(struct rtnl_link_ops *ops)
+{
+       rtnl_lock();
+       __rtnl_link_unregister(ops);
+       rtnl_unlock();
+}
+
+EXPORT_SYMBOL_GPL(rtnl_link_unregister);
+
+static const struct rtnl_link_ops *rtnl_link_ops_get(const char *kind)
+{
+       const struct rtnl_link_ops *ops;
+
+       list_for_each_entry(ops, &link_ops, list) {
+               if (!strcmp(ops->kind, kind))
+                       return ops;
+       }
+       return NULL;
+}
+
+static size_t rtnl_link_get_size(const struct net_device *dev)
+{
+       const struct rtnl_link_ops *ops = dev->rtnl_link_ops;
+       size_t size;
+
+       if (!ops)
+               return 0;
+
+       size = nlmsg_total_size(sizeof(struct nlattr)) + /* IFLA_LINKINFO */
+              nlmsg_total_size(strlen(ops->kind) + 1);  /* IFLA_INFO_KIND */
+
+       if (ops->get_size)
+               /* IFLA_INFO_DATA + nested data */
+               size += nlmsg_total_size(sizeof(struct nlattr)) +
+                       ops->get_size(dev);
+
+       if (ops->get_xstats_size)
+               size += ops->get_xstats_size(dev);      /* IFLA_INFO_XSTATS */
+
+       return size;
+}
+
+static int rtnl_link_fill(struct sk_buff *skb, const struct net_device *dev)
+{
+       const struct rtnl_link_ops *ops = dev->rtnl_link_ops;
+       struct nlattr *linkinfo, *data;
+       int err = -EMSGSIZE;
+
+       linkinfo = nla_nest_start(skb, IFLA_LINKINFO);
+       if (linkinfo == NULL)
+               goto out;
+
+       if (nla_put_string(skb, IFLA_INFO_KIND, ops->kind) < 0)
+               goto err_cancel_link;
+       if (ops->fill_xstats) {
+               err = ops->fill_xstats(skb, dev);
+               if (err < 0)
+                       goto err_cancel_link;
+       }
+       if (ops->fill_info) {
+               data = nla_nest_start(skb, IFLA_INFO_DATA);
+               if (data == NULL)
+                       goto err_cancel_link;
+               err = ops->fill_info(skb, dev);
+               if (err < 0)
+                       goto err_cancel_data;
+               nla_nest_end(skb, data);
+       }
+
+       nla_nest_end(skb, linkinfo);
+       return 0;
+
+err_cancel_data:
+       nla_nest_cancel(skb, data);
+err_cancel_link:
+       nla_nest_cancel(skb, linkinfo);
+out:
+       return err;
+}
+
 static const int rtm_min[RTM_NR_FAMILIES] =
 {
        [RTM_FAM(RTM_NEWLINK)]      = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
@@ -437,7 +594,7 @@ static void copy_rtnl_link_stats(struct rtnl_link_stats *a,
        a->tx_compressed = b->tx_compressed;
 };
 
-static inline size_t if_nlmsg_size(void)
+static inline size_t if_nlmsg_size(const struct net_device *dev)
 {
        return NLMSG_ALIGN(sizeof(struct ifinfomsg))
               + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */
@@ -452,7 +609,8 @@ static inline size_t if_nlmsg_size(void)
               + nla_total_size(4) /* IFLA_LINK */
               + nla_total_size(4) /* IFLA_MASTER */
               + nla_total_size(1) /* IFLA_OPERSTATE */
-              + nla_total_size(1); /* IFLA_LINKMODE */
+              + nla_total_size(1) /* IFLA_LINKMODE */
+              + rtnl_link_get_size(dev); /* IFLA_LINKINFO */
 }
 
 static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
@@ -522,6 +680,11 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
                }
        }
 
+       if (dev->rtnl_link_ops) {
+               if (rtnl_link_fill(skb, dev) < 0)
+                       goto nla_put_failure;
+       }
+
        return nlmsg_end(skb, nlh);
 
 nla_put_failure:
@@ -553,6 +716,8 @@ cont:
 
 static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
        [IFLA_IFNAME]           = { .type = NLA_STRING, .len = IFNAMSIZ-1 },
+       [IFLA_ADDRESS]          = { .type = NLA_BINARY, .len = MAX_ADDR_LEN },
+       [IFLA_BROADCAST]        = { .type = NLA_BINARY, .len = MAX_ADDR_LEN },
        [IFLA_MAP]              = { .len = sizeof(struct rtnl_link_ifmap) },
        [IFLA_MTU]              = { .type = NLA_U32 },
        [IFLA_TXQLEN]           = { .type = NLA_U32 },
@@ -561,44 +726,16 @@ static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
        [IFLA_LINKMODE]         = { .type = NLA_U8 },
 };
 
-static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
-{
-       struct ifinfomsg *ifm;
-       struct net_device *dev;
-       int err, send_addr_notify = 0, modified = 0;
-       struct nlattr *tb[IFLA_MAX+1];
-       char ifname[IFNAMSIZ];
-
-       err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
-       if (err < 0)
-               goto errout;
-
-       if (tb[IFLA_IFNAME])
-               nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
-       else
-               ifname[0] = '\0';
-
-       err = -EINVAL;
-       ifm = nlmsg_data(nlh);
-       if (ifm->ifi_index > 0)
-               dev = dev_get_by_index(ifm->ifi_index);
-       else if (tb[IFLA_IFNAME])
-               dev = dev_get_by_name(ifname);
-       else
-               goto errout;
-
-       if (dev == NULL) {
-               err = -ENODEV;
-               goto errout;
-       }
-
-       if (tb[IFLA_ADDRESS] &&
-           nla_len(tb[IFLA_ADDRESS]) < dev->addr_len)
-               goto errout_dev;
+static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
+       [IFLA_INFO_KIND]        = { .type = NLA_STRING },
+       [IFLA_INFO_DATA]        = { .type = NLA_NESTED },
+};
 
-       if (tb[IFLA_BROADCAST] &&
-           nla_len(tb[IFLA_BROADCAST]) < dev->addr_len)
-               goto errout_dev;
+static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
+                     struct nlattr **tb, char *ifname, int modified)
+{
+       int send_addr_notify = 0;
+       int err;
 
        if (tb[IFLA_MAP]) {
                struct rtnl_link_ifmap *u_map;
@@ -606,12 +743,12 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 
                if (!dev->set_config) {
                        err = -EOPNOTSUPP;
-                       goto errout_dev;
+                       goto errout;
                }
 
                if (!netif_device_present(dev)) {
                        err = -ENODEV;
-                       goto errout_dev;
+                       goto errout;
                }
 
                u_map = nla_data(tb[IFLA_MAP]);
@@ -624,7 +761,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 
                err = dev->set_config(dev, &k_map);
                if (err < 0)
-                       goto errout_dev;
+                       goto errout;
 
                modified = 1;
        }
@@ -635,19 +772,19 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 
                if (!dev->set_mac_address) {
                        err = -EOPNOTSUPP;
-                       goto errout_dev;
+                       goto errout;
                }
 
                if (!netif_device_present(dev)) {
                        err = -ENODEV;
-                       goto errout_dev;
+                       goto errout;
                }
 
                len = sizeof(sa_family_t) + dev->addr_len;
                sa = kmalloc(len, GFP_KERNEL);
                if (!sa) {
                        err = -ENOMEM;
-                       goto errout_dev;
+                       goto errout;
                }
                sa->sa_family = dev->type;
                memcpy(sa->sa_data, nla_data(tb[IFLA_ADDRESS]),
@@ -655,7 +792,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
                err = dev->set_mac_address(dev, sa);
                kfree(sa);
                if (err)
-                       goto errout_dev;
+                       goto errout;
                send_addr_notify = 1;
                modified = 1;
        }
@@ -663,7 +800,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
        if (tb[IFLA_MTU]) {
                err = dev_set_mtu(dev, nla_get_u32(tb[IFLA_MTU]));
                if (err < 0)
-                       goto errout_dev;
+                       goto errout;
                modified = 1;
        }
 
@@ -675,7 +812,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
        if (ifm->ifi_index > 0 && ifname[0]) {
                err = dev_change_name(dev, ifname);
                if (err < 0)
-                       goto errout_dev;
+                       goto errout;
                modified = 1;
        }
 
@@ -684,7 +821,6 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
                send_addr_notify = 1;
        }
 
-
        if (ifm->ifi_flags || ifm->ifi_change) {
                unsigned int flags = ifm->ifi_flags;
 
@@ -712,7 +848,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 
        err = 0;
 
-errout_dev:
+errout:
        if (err < 0 && modified && net_ratelimit())
                printk(KERN_WARNING "A link change request failed with "
                       "some changes comitted already. Interface %s may "
@@ -721,12 +857,239 @@ errout_dev:
 
        if (send_addr_notify)
                call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
+       return err;
+}
+
+static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+{
+       struct ifinfomsg *ifm;
+       struct net_device *dev;
+       int err;
+       struct nlattr *tb[IFLA_MAX+1];
+       char ifname[IFNAMSIZ];
+
+       err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
+       if (err < 0)
+               goto errout;
+
+       if (tb[IFLA_IFNAME])
+               nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
+       else
+               ifname[0] = '\0';
+
+       err = -EINVAL;
+       ifm = nlmsg_data(nlh);
+       if (ifm->ifi_index > 0)
+               dev = dev_get_by_index(ifm->ifi_index);
+       else if (tb[IFLA_IFNAME])
+               dev = dev_get_by_name(ifname);
+       else
+               goto errout;
+
+       if (dev == NULL) {
+               err = -ENODEV;
+               goto errout;
+       }
 
+       if (tb[IFLA_ADDRESS] &&
+           nla_len(tb[IFLA_ADDRESS]) < dev->addr_len)
+               goto errout_dev;
+
+       if (tb[IFLA_BROADCAST] &&
+           nla_len(tb[IFLA_BROADCAST]) < dev->addr_len)
+               goto errout_dev;
+
+       err = do_setlink(dev, ifm, tb, ifname, 0);
+errout_dev:
        dev_put(dev);
 errout:
        return err;
 }
 
+static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+{
+       const struct rtnl_link_ops *ops;
+       struct net_device *dev;
+       struct ifinfomsg *ifm;
+       char ifname[IFNAMSIZ];
+       struct nlattr *tb[IFLA_MAX+1];
+       int err;
+
+       err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
+       if (err < 0)
+               return err;
+
+       if (tb[IFLA_IFNAME])
+               nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
+
+       ifm = nlmsg_data(nlh);
+       if (ifm->ifi_index > 0)
+               dev = __dev_get_by_index(ifm->ifi_index);
+       else if (tb[IFLA_IFNAME])
+               dev = __dev_get_by_name(ifname);
+       else
+               return -EINVAL;
+
+       if (!dev)
+               return -ENODEV;
+
+       ops = dev->rtnl_link_ops;
+       if (!ops)
+               return -EOPNOTSUPP;
+
+       ops->dellink(dev);
+       return 0;
+}
+
+static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+{
+       const struct rtnl_link_ops *ops;
+       struct net_device *dev;
+       struct ifinfomsg *ifm;
+       char kind[MODULE_NAME_LEN];
+       char ifname[IFNAMSIZ];
+       struct nlattr *tb[IFLA_MAX+1];
+       struct nlattr *linkinfo[IFLA_INFO_MAX+1];
+       int err;
+
+replay:
+       err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
+       if (err < 0)
+               return err;
+
+       if (tb[IFLA_IFNAME])
+               nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
+       else
+               ifname[0] = '\0';
+
+       ifm = nlmsg_data(nlh);
+       if (ifm->ifi_index > 0)
+               dev = __dev_get_by_index(ifm->ifi_index);
+       else if (ifname[0])
+               dev = __dev_get_by_name(ifname);
+       else
+               dev = NULL;
+
+       if (tb[IFLA_LINKINFO]) {
+               err = nla_parse_nested(linkinfo, IFLA_INFO_MAX,
+                                      tb[IFLA_LINKINFO], ifla_info_policy);
+               if (err < 0)
+                       return err;
+       } else
+               memset(linkinfo, 0, sizeof(linkinfo));
+
+       if (linkinfo[IFLA_INFO_KIND]) {
+               nla_strlcpy(kind, linkinfo[IFLA_INFO_KIND], sizeof(kind));
+               ops = rtnl_link_ops_get(kind);
+       } else {
+               kind[0] = '\0';
+               ops = NULL;
+       }
+
+       if (1) {
+               struct nlattr *attr[ops ? ops->maxtype + 1 : 0], **data = NULL;
+
+               if (ops) {
+                       if (ops->maxtype && linkinfo[IFLA_INFO_DATA]) {
+                               err = nla_parse_nested(attr, ops->maxtype,
+                                                      linkinfo[IFLA_INFO_DATA],
+                                                      ops->policy);
+                               if (err < 0)
+                                       return err;
+                               data = attr;
+                       }
+                       if (ops->validate) {
+                               err = ops->validate(tb, data);
+                               if (err < 0)
+                                       return err;
+                       }
+               }
+
+               if (dev) {
+                       int modified = 0;
+
+                       if (nlh->nlmsg_flags & NLM_F_EXCL)
+                               return -EEXIST;
+                       if (nlh->nlmsg_flags & NLM_F_REPLACE)
+                               return -EOPNOTSUPP;
+
+                       if (linkinfo[IFLA_INFO_DATA]) {
+                               if (!ops || ops != dev->rtnl_link_ops ||
+                                   !ops->changelink)
+                                       return -EOPNOTSUPP;
+
+                               err = ops->changelink(dev, tb, data);
+                               if (err < 0)
+                                       return err;
+                               modified = 1;
+                       }
+
+                       return do_setlink(dev, ifm, tb, ifname, modified);
+               }
+
+               if (!(nlh->nlmsg_flags & NLM_F_CREATE))
+                       return -ENODEV;
+
+               if (ifm->ifi_index || ifm->ifi_flags || ifm->ifi_change)
+                       return -EOPNOTSUPP;
+               if (tb[IFLA_MAP] || tb[IFLA_MASTER] || tb[IFLA_PROTINFO])
+                       return -EOPNOTSUPP;
+
+               if (!ops) {
+#ifdef CONFIG_KMOD
+                       if (kind[0]) {
+                               __rtnl_unlock();
+                               request_module("rtnl-link-%s", kind);
+                               rtnl_lock();
+                               ops = rtnl_link_ops_get(kind);
+                               if (ops)
+                                       goto replay;
+                       }
+#endif
+                       return -EOPNOTSUPP;
+               }
+
+               if (!ifname[0])
+                       snprintf(ifname, IFNAMSIZ, "%s%%d", ops->kind);
+               dev = alloc_netdev(ops->priv_size, ifname, ops->setup);
+               if (!dev)
+                       return -ENOMEM;
+
+               if (strchr(dev->name, '%')) {
+                       err = dev_alloc_name(dev, dev->name);
+                       if (err < 0)
+                               goto err_free;
+               }
+               dev->rtnl_link_ops = ops;
+
+               if (tb[IFLA_MTU])
+                       dev->mtu = nla_get_u32(tb[IFLA_MTU]);
+               if (tb[IFLA_ADDRESS])
+                       memcpy(dev->dev_addr, nla_data(tb[IFLA_ADDRESS]),
+                              nla_len(tb[IFLA_ADDRESS]));
+               if (tb[IFLA_BROADCAST])
+                       memcpy(dev->broadcast, nla_data(tb[IFLA_BROADCAST]),
+                              nla_len(tb[IFLA_BROADCAST]));
+               if (tb[IFLA_TXQLEN])
+                       dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]);
+               if (tb[IFLA_WEIGHT])
+                       dev->weight = nla_get_u32(tb[IFLA_WEIGHT]);
+               if (tb[IFLA_OPERSTATE])
+                       set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE]));
+               if (tb[IFLA_LINKMODE])
+                       dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]);
+
+               if (ops->newlink)
+                       err = ops->newlink(dev, tb, data);
+               else
+                       err = register_netdevice(dev);
+err_free:
+               if (err < 0)
+                       free_netdev(dev);
+               return err;
+       }
+}
+
 static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
 {
        struct ifinfomsg *ifm;
@@ -747,7 +1110,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
        } else
                return -EINVAL;
 
-       nskb = nlmsg_new(if_nlmsg_size(), GFP_KERNEL);
+       nskb = nlmsg_new(if_nlmsg_size(dev), GFP_KERNEL);
        if (nskb == NULL) {
                err = -ENOBUFS;
                goto errout;
@@ -797,7 +1160,7 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change)
        struct sk_buff *skb;
        int err = -ENOBUFS;
 
-       skb = nlmsg_new(if_nlmsg_size(), GFP_KERNEL);
+       skb = nlmsg_new(if_nlmsg_size(dev), GFP_KERNEL);
        if (skb == NULL)
                goto errout;
 
@@ -952,6 +1315,8 @@ void __init rtnetlink_init(void)
 
        rtnl_register(PF_UNSPEC, RTM_GETLINK, rtnl_getlink, rtnl_dump_ifinfo);
        rtnl_register(PF_UNSPEC, RTM_SETLINK, rtnl_setlink, NULL);
+       rtnl_register(PF_UNSPEC, RTM_NEWLINK, rtnl_newlink, NULL);
+       rtnl_register(PF_UNSPEC, RTM_DELLINK, rtnl_dellink, NULL);
 
        rtnl_register(PF_UNSPEC, RTM_GETADDR, NULL, rtnl_dump_all);
        rtnl_register(PF_UNSPEC, RTM_GETROUTE, NULL, rtnl_dump_all);
@@ -960,6 +1325,7 @@ void __init rtnetlink_init(void)
 EXPORT_SYMBOL(__rta_fill);
 EXPORT_SYMBOL(rtattr_strlcpy);
 EXPORT_SYMBOL(rtattr_parse);
+EXPORT_SYMBOL(__rtattr_parse_nested_compat);
 EXPORT_SYMBOL(rtnetlink_put_metrics);
 EXPORT_SYMBOL(rtnl_lock);
 EXPORT_SYMBOL(rtnl_trylock);
index 3943c3ad9145138d3deaf8a05e87f27a51a23200..0583e8498f1351d2631024fd811ecdd1172da27c 100644 (file)
@@ -415,9 +415,11 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask)
        C(csum);
        C(local_df);
        n->cloned = 1;
+       n->hdr_len = skb->nohdr ? skb_headroom(skb) : skb->hdr_len;
        n->nohdr = 0;
        C(pkt_type);
        C(ip_summed);
+       skb_copy_queue_mapping(n, skb);
        C(priority);
 #if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
        C(ipvs_property);
@@ -426,6 +428,10 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask)
        n->destructor = NULL;
        C(mark);
        __nf_copy(n, skb);
+#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
+    defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
+       C(nf_trace);
+#endif
 #ifdef CONFIG_NET_SCHED
        C(tc_index);
 #ifdef CONFIG_NET_CLS_ACT
@@ -459,6 +465,7 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
 #endif
        new->sk         = NULL;
        new->dev        = old->dev;
+       skb_copy_queue_mapping(new, old);
        new->priority   = old->priority;
        new->protocol   = old->protocol;
        new->dst        = dst_clone(old->dst);
@@ -482,6 +489,10 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
        new->destructor = NULL;
        new->mark       = old->mark;
        __nf_copy(new, old);
+#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
+    defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
+       new->nf_trace   = old->nf_trace;
+#endif
 #if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
        new->ipvs_property = old->ipvs_property;
 #endif
@@ -676,6 +687,7 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
        skb->network_header   += off;
        skb->mac_header       += off;
        skb->cloned   = 0;
+       skb->hdr_len  = 0;
        skb->nohdr    = 0;
        atomic_set(&skb_shinfo(skb)->dataref, 1);
        return 0;
@@ -1930,6 +1942,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features)
                tail = nskb;
 
                nskb->dev = skb->dev;
+               skb_copy_queue_mapping(nskb, skb);
                nskb->priority = skb->priority;
                nskb->protocol = skb->protocol;
                nskb->dst = dst_clone(skb->dst);
index c14ce0198d25d7be42762ee3dae5df76ba9ec8d6..091032a250c7e0da5e8ccd1830ecbdc3acb90866 100644 (file)
@@ -210,7 +210,8 @@ static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen)
                return -EDOM;
 
        if (tv.tv_sec < 0) {
-               static int warned = 0;
+               static int warned __read_mostly;
+
                *timeo_p = 0;
                if (warned < 10 && net_ratelimit())
                        warned++;
@@ -1851,46 +1852,15 @@ void proto_unregister(struct proto *prot)
 EXPORT_SYMBOL(proto_unregister);
 
 #ifdef CONFIG_PROC_FS
-static inline struct proto *__proto_head(void)
-{
-       return list_entry(proto_list.next, struct proto, node);
-}
-
-static inline struct proto *proto_head(void)
-{
-       return list_empty(&proto_list) ? NULL : __proto_head();
-}
-
-static inline struct proto *proto_next(struct proto *proto)
-{
-       return proto->node.next == &proto_list ? NULL :
-               list_entry(proto->node.next, struct proto, node);
-}
-
-static inline struct proto *proto_get_idx(loff_t pos)
-{
-       struct proto *proto;
-       loff_t i = 0;
-
-       list_for_each_entry(proto, &proto_list, node)
-               if (i++ == pos)
-                       goto out;
-
-       proto = NULL;
-out:
-       return proto;
-}
-
 static void *proto_seq_start(struct seq_file *seq, loff_t *pos)
 {
        read_lock(&proto_list_lock);
-       return *pos ? proto_get_idx(*pos - 1) : SEQ_START_TOKEN;
+       return seq_list_start_head(&proto_list, *pos);
 }
 
 static void *proto_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
-       ++*pos;
-       return v == SEQ_START_TOKEN ? proto_head() : proto_next(v);
+       return seq_list_next(v, &proto_list, pos);
 }
 
 static void proto_seq_stop(struct seq_file *seq, void *v)
@@ -1938,7 +1908,7 @@ static void proto_seq_printf(struct seq_file *seq, struct proto *proto)
 
 static int proto_seq_show(struct seq_file *seq, void *v)
 {
-       if (v == SEQ_START_TOKEN)
+       if (v == &proto_list)
                seq_printf(seq, "%-9s %-4s %-8s %-6s %-5s %-7s %-4s %-10s %s",
                           "protocol",
                           "size",
@@ -1950,7 +1920,7 @@ static int proto_seq_show(struct seq_file *seq, void *v)
                           "module",
                           "cl co di ac io in de sh ss gs se re sp bi br ha uh gp em\n");
        else
-               proto_seq_printf(seq, v);
+               proto_seq_printf(seq, list_entry(v, struct proto, node));
        return 0;
 }
 
index ec7fa4d67f080c344ba38c8915b004c1a8e3b9cb..e91c2b9dc27b47146be86fc27a41c2efc80aeb25 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *  net/dccp/ccids/ccid3.c
  *
- *  Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand.
- *  Copyright (c) 2005-6 Ian McDonald <ian.mcdonald@jandi.co.nz>
+ *  Copyright (c) 2005-7 The University of Waikato, Hamilton, New Zealand.
+ *  Copyright (c) 2005-7 Ian McDonald <ian.mcdonald@jandi.co.nz>
  *
  *  An implementation of the DCCP protocol
  *
@@ -49,7 +49,6 @@ static int ccid3_debug;
 
 static struct dccp_tx_hist *ccid3_tx_hist;
 static struct dccp_rx_hist *ccid3_rx_hist;
-static struct dccp_li_hist *ccid3_li_hist;
 
 /*
  *     Transmitter Half-Connection Routines
@@ -194,25 +193,20 @@ static inline void ccid3_hc_tx_update_s(struct ccid3_hc_tx_sock *hctx, int len)
  *     The algorithm is not applicable if RTT < 4 microseconds.
  */
 static inline void ccid3_hc_tx_update_win_count(struct ccid3_hc_tx_sock *hctx,
-                                               struct timeval *now)
+                                               ktime_t now)
 {
-       suseconds_t delta;
        u32 quarter_rtts;
 
        if (unlikely(hctx->ccid3hctx_rtt < 4))  /* avoid divide-by-zero */
                return;
 
-       delta = timeval_delta(now, &hctx->ccid3hctx_t_last_win_count);
-       DCCP_BUG_ON(delta < 0);
-
-       quarter_rtts = (u32)delta / (hctx->ccid3hctx_rtt / 4);
+       quarter_rtts = ktime_us_delta(now, hctx->ccid3hctx_t_last_win_count);
+       quarter_rtts /= hctx->ccid3hctx_rtt / 4;
 
        if (quarter_rtts > 0) {
-               hctx->ccid3hctx_t_last_win_count = *now;
+               hctx->ccid3hctx_t_last_win_count = now;
                hctx->ccid3hctx_last_win_count  += min_t(u32, quarter_rtts, 5);
                hctx->ccid3hctx_last_win_count  &= 0xF;         /* mod 16 */
-
-               ccid3_pr_debug("now at %#X\n", hctx->ccid3hctx_last_win_count);
        }
 }
 
@@ -312,8 +306,8 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
 {
        struct dccp_sock *dp = dccp_sk(sk);
        struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
-       struct timeval now;
-       suseconds_t delay;
+       ktime_t now = ktime_get_real();
+       s64 delay;
 
        BUG_ON(hctx == NULL);
 
@@ -325,8 +319,6 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
        if (unlikely(skb->len == 0))
                return -EBADMSG;
 
-       dccp_timestamp(sk, &now);
-
        switch (hctx->ccid3hctx_state) {
        case TFRC_SSTATE_NO_SENT:
                sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
@@ -349,7 +341,7 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
                        ccid3_pr_debug("SYN RTT = %uus\n", dp->dccps_syn_rtt);
                        hctx->ccid3hctx_rtt  = dp->dccps_syn_rtt;
                        hctx->ccid3hctx_x    = rfc3390_initial_rate(sk);
-                       hctx->ccid3hctx_t_ld = now;
+                       hctx->ccid3hctx_t_ld = ktime_to_timeval(now);
                } else {
                        /* Sender does not have RTT sample: X = MSS/second */
                        hctx->ccid3hctx_x = dp->dccps_mss_cache;
@@ -361,7 +353,7 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
                break;
        case TFRC_SSTATE_NO_FBACK:
        case TFRC_SSTATE_FBACK:
-               delay = timeval_delta(&hctx->ccid3hctx_t_nom, &now);
+               delay = ktime_us_delta(hctx->ccid3hctx_t_nom, now);
                ccid3_pr_debug("delay=%ld\n", (long)delay);
                /*
                 *      Scheduling of packet transmissions [RFC 3448, 4.6]
@@ -371,10 +363,10 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
                 * else
                 *       // send the packet in (t_nom - t_now) milliseconds.
                 */
-               if (delay - (suseconds_t)hctx->ccid3hctx_delta >= 0)
-                       return delay / 1000L;
+               if (delay - (s64)hctx->ccid3hctx_delta >= 1000)
+                       return (u32)delay / 1000L;
 
-               ccid3_hc_tx_update_win_count(hctx, &now);
+               ccid3_hc_tx_update_win_count(hctx, now);
                break;
        case TFRC_SSTATE_TERM:
                DCCP_BUG("%s(%p) - Illegal state TERM", dccp_role(sk), sk);
@@ -387,8 +379,8 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
        hctx->ccid3hctx_idle = 0;
 
        /* set the nominal send time for the next following packet */
-       timeval_add_usecs(&hctx->ccid3hctx_t_nom, hctx->ccid3hctx_t_ipi);
-
+       hctx->ccid3hctx_t_nom = ktime_add_us(hctx->ccid3hctx_t_nom,
+                                            hctx->ccid3hctx_t_ipi);
        return 0;
 }
 
@@ -819,154 +811,6 @@ static int ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
        return 0;
 }
 
-/* calculate first loss interval
- *
- * returns estimated loss interval in usecs */
-
-static u32 ccid3_hc_rx_calc_first_li(struct sock *sk)
-{
-       struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
-       struct dccp_rx_hist_entry *entry, *next, *tail = NULL;
-       u32 x_recv, p;
-       suseconds_t rtt, delta;
-       struct timeval tstamp = { 0, };
-       int interval = 0;
-       int win_count = 0;
-       int step = 0;
-       u64 fval;
-
-       list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist,
-                                dccphrx_node) {
-               if (dccp_rx_hist_entry_data_packet(entry)) {
-                       tail = entry;
-
-                       switch (step) {
-                       case 0:
-                               tstamp    = entry->dccphrx_tstamp;
-                               win_count = entry->dccphrx_ccval;
-                               step = 1;
-                               break;
-                       case 1:
-                               interval = win_count - entry->dccphrx_ccval;
-                               if (interval < 0)
-                                       interval += TFRC_WIN_COUNT_LIMIT;
-                               if (interval > 4)
-                                       goto found;
-                               break;
-                       }
-               }
-       }
-
-       if (unlikely(step == 0)) {
-               DCCP_WARN("%s(%p), packet history has no data packets!\n",
-                         dccp_role(sk), sk);
-               return ~0;
-       }
-
-       if (unlikely(interval == 0)) {
-               DCCP_WARN("%s(%p), Could not find a win_count interval > 0."
-                         "Defaulting to 1\n", dccp_role(sk), sk);
-               interval = 1;
-       }
-found:
-       if (!tail) {
-               DCCP_CRIT("tail is null\n");
-               return ~0;
-       }
-
-       delta = timeval_delta(&tstamp, &tail->dccphrx_tstamp);
-       DCCP_BUG_ON(delta < 0);
-
-       rtt = delta * 4 / interval;
-       ccid3_pr_debug("%s(%p), approximated RTT to %dus\n",
-                      dccp_role(sk), sk, (int)rtt);
-
-       /*
-        * Determine the length of the first loss interval via inverse lookup.
-        * Assume that X_recv can be computed by the throughput equation
-        *                  s
-        *      X_recv = --------
-        *               R * fval
-        * Find some p such that f(p) = fval; return 1/p [RFC 3448, 6.3.1].
-        */
-       if (rtt == 0) {                 /* would result in divide-by-zero */
-               DCCP_WARN("RTT==0\n");
-               return ~0;
-       }
-
-       dccp_timestamp(sk, &tstamp);
-       delta = timeval_delta(&tstamp, &hcrx->ccid3hcrx_tstamp_last_feedback);
-       DCCP_BUG_ON(delta <= 0);
-
-       x_recv = scaled_div32(hcrx->ccid3hcrx_bytes_recv, delta);
-       if (x_recv == 0) {              /* would also trigger divide-by-zero */
-               DCCP_WARN("X_recv==0\n");
-               if ((x_recv = hcrx->ccid3hcrx_x_recv) == 0) {
-                       DCCP_BUG("stored value of X_recv is zero");
-                       return ~0;
-               }
-       }
-
-       fval = scaled_div(hcrx->ccid3hcrx_s, rtt);
-       fval = scaled_div32(fval, x_recv);
-       p = tfrc_calc_x_reverse_lookup(fval);
-
-       ccid3_pr_debug("%s(%p), receive rate=%u bytes/s, implied "
-                      "loss rate=%u\n", dccp_role(sk), sk, x_recv, p);
-
-       if (p == 0)
-               return ~0;
-       else
-               return 1000000 / p;
-}
-
-static void ccid3_hc_rx_update_li(struct sock *sk, u64 seq_loss, u8 win_loss)
-{
-       struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
-       struct dccp_li_hist_entry *head;
-       u64 seq_temp;
-
-       if (list_empty(&hcrx->ccid3hcrx_li_hist)) {
-               if (!dccp_li_hist_interval_new(ccid3_li_hist,
-                  &hcrx->ccid3hcrx_li_hist, seq_loss, win_loss))
-                       return;
-
-               head = list_entry(hcrx->ccid3hcrx_li_hist.next,
-                  struct dccp_li_hist_entry, dccplih_node);
-               head->dccplih_interval = ccid3_hc_rx_calc_first_li(sk);
-       } else {
-               struct dccp_li_hist_entry *entry;
-               struct list_head *tail;
-
-               head = list_entry(hcrx->ccid3hcrx_li_hist.next,
-                  struct dccp_li_hist_entry, dccplih_node);
-               /* FIXME win count check removed as was wrong */
-               /* should make this check with receive history */
-               /* and compare there as per section 10.2 of RFC4342 */
-
-               /* new loss event detected */
-               /* calculate last interval length */
-               seq_temp = dccp_delta_seqno(head->dccplih_seqno, seq_loss);
-               entry = dccp_li_hist_entry_new(ccid3_li_hist, GFP_ATOMIC);
-
-               if (entry == NULL) {
-                       DCCP_BUG("out of memory - can not allocate entry");
-                       return;
-               }
-
-               list_add(&entry->dccplih_node, &hcrx->ccid3hcrx_li_hist);
-
-               tail = hcrx->ccid3hcrx_li_hist.prev;
-               list_del(tail);
-               kmem_cache_free(ccid3_li_hist->dccplih_slab, tail);
-
-               /* Create the newest interval */
-               entry->dccplih_seqno = seq_loss;
-               entry->dccplih_interval = seq_temp;
-               entry->dccplih_win_count = win_loss;
-       }
-}
-
 static int ccid3_hc_rx_detect_loss(struct sock *sk,
                                    struct dccp_rx_hist_entry *packet)
 {
@@ -992,8 +836,15 @@ static int ccid3_hc_rx_detect_loss(struct sock *sk,
        while (dccp_delta_seqno(hcrx->ccid3hcrx_seqno_nonloss, seqno)
           > TFRC_RECV_NUM_LATE_LOSS) {
                loss = 1;
-               ccid3_hc_rx_update_li(sk, hcrx->ccid3hcrx_seqno_nonloss,
-                  hcrx->ccid3hcrx_ccval_nonloss);
+               dccp_li_update_li(sk,
+                                 &hcrx->ccid3hcrx_li_hist,
+                                 &hcrx->ccid3hcrx_hist,
+                                 &hcrx->ccid3hcrx_tstamp_last_feedback,
+                                 hcrx->ccid3hcrx_s,
+                                 hcrx->ccid3hcrx_bytes_recv,
+                                 hcrx->ccid3hcrx_x_recv,
+                                 hcrx->ccid3hcrx_seqno_nonloss,
+                                 hcrx->ccid3hcrx_ccval_nonloss);
                tmp_seqno = hcrx->ccid3hcrx_seqno_nonloss;
                dccp_inc_seqno(&tmp_seqno);
                hcrx->ccid3hcrx_seqno_nonloss = tmp_seqno;
@@ -1152,7 +1003,7 @@ static void ccid3_hc_rx_exit(struct sock *sk)
        dccp_rx_hist_purge(ccid3_rx_hist, &hcrx->ccid3hcrx_hist);
 
        /* Empty loss interval history */
-       dccp_li_hist_purge(ccid3_li_hist, &hcrx->ccid3hcrx_li_hist);
+       dccp_li_hist_purge(&hcrx->ccid3hcrx_li_hist);
 }
 
 static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info)
@@ -1236,19 +1087,12 @@ static __init int ccid3_module_init(void)
        if (ccid3_tx_hist == NULL)
                goto out_free_rx;
 
-       ccid3_li_hist = dccp_li_hist_new("ccid3");
-       if (ccid3_li_hist == NULL)
-               goto out_free_tx;
-
        rc = ccid_register(&ccid3);
        if (rc != 0)
-               goto out_free_loss_interval_history;
+               goto out_free_tx;
 out:
        return rc;
 
-out_free_loss_interval_history:
-       dccp_li_hist_delete(ccid3_li_hist);
-       ccid3_li_hist = NULL;
 out_free_tx:
        dccp_tx_hist_delete(ccid3_tx_hist);
        ccid3_tx_hist = NULL;
@@ -1271,10 +1115,6 @@ static __exit void ccid3_module_exit(void)
                dccp_rx_hist_delete(ccid3_rx_hist);
                ccid3_rx_hist = NULL;
        }
-       if (ccid3_li_hist != NULL) {
-               dccp_li_hist_delete(ccid3_li_hist);
-               ccid3_li_hist = NULL;
-       }
 }
 module_exit(ccid3_module_exit);
 
index 8d31b389c19c5cdd1b2e230e9f8e4fd4eecded2e..51d4b804e3344d8c31f90392be3f74bdef85a958 100644 (file)
@@ -36,6 +36,7 @@
 #ifndef _DCCP_CCID3_H_
 #define _DCCP_CCID3_H_
 
+#include <linux/ktime.h>
 #include <linux/list.h>
 #include <linux/time.h>
 #include <linux/types.h>
@@ -108,10 +109,10 @@ struct ccid3_hc_tx_sock {
        enum ccid3_hc_tx_states         ccid3hctx_state:8;
        u8                              ccid3hctx_last_win_count;
        u8                              ccid3hctx_idle;
-       struct timeval                  ccid3hctx_t_last_win_count;
+       ktime_t                         ccid3hctx_t_last_win_count;
        struct timer_list               ccid3hctx_no_feedback_timer;
        struct timeval                  ccid3hctx_t_ld;
-       struct timeval                  ccid3hctx_t_nom;
+       ktime_t                         ccid3hctx_t_nom;
        u32                             ccid3hctx_delta;
        struct list_head                ccid3hctx_hist;
        struct ccid3_options_received   ccid3hctx_options_received;
index 372d7e75cdd8bf953c1eea1a07b960949928a898..515225f3a464cb06488ff565d3067869a82dde50 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *  net/dccp/ccids/lib/loss_interval.c
  *
- *  Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand.
- *  Copyright (c) 2005-6 Ian McDonald <ian.mcdonald@jandi.co.nz>
+ *  Copyright (c) 2005-7 The University of Waikato, Hamilton, New Zealand.
+ *  Copyright (c) 2005-7 Ian McDonald <ian.mcdonald@jandi.co.nz>
  *  Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
  *
  *  This program is free software; you can redistribute it and/or modify
 #include <net/sock.h>
 #include "../../dccp.h"
 #include "loss_interval.h"
+#include "packet_history.h"
+#include "tfrc.h"
 
-struct dccp_li_hist *dccp_li_hist_new(const char *name)
-{
-       struct dccp_li_hist *hist = kmalloc(sizeof(*hist), GFP_ATOMIC);
-       static const char dccp_li_hist_mask[] = "li_hist_%s";
-       char *slab_name;
-
-       if (hist == NULL)
-               goto out;
-
-       slab_name = kmalloc(strlen(name) + sizeof(dccp_li_hist_mask) - 1,
-                           GFP_ATOMIC);
-       if (slab_name == NULL)
-               goto out_free_hist;
-
-       sprintf(slab_name, dccp_li_hist_mask, name);
-       hist->dccplih_slab = kmem_cache_create(slab_name,
-                                            sizeof(struct dccp_li_hist_entry),
-                                              0, SLAB_HWCACHE_ALIGN,
-                                              NULL, NULL);
-       if (hist->dccplih_slab == NULL)
-               goto out_free_slab_name;
-out:
-       return hist;
-out_free_slab_name:
-       kfree(slab_name);
-out_free_hist:
-       kfree(hist);
-       hist = NULL;
-       goto out;
-}
+#define DCCP_LI_HIST_IVAL_F_LENGTH  8
 
-EXPORT_SYMBOL_GPL(dccp_li_hist_new);
+struct dccp_li_hist_entry {
+       struct list_head dccplih_node;
+       u64              dccplih_seqno:48,
+                        dccplih_win_count:4;
+       u32              dccplih_interval;
+};
 
-void dccp_li_hist_delete(struct dccp_li_hist *hist)
-{
-       const char* name = kmem_cache_name(hist->dccplih_slab);
+static struct kmem_cache *dccp_li_cachep __read_mostly;
 
-       kmem_cache_destroy(hist->dccplih_slab);
-       kfree(name);
-       kfree(hist);
+static inline struct dccp_li_hist_entry *dccp_li_hist_entry_new(const gfp_t prio)
+{
+       return kmem_cache_alloc(dccp_li_cachep, prio);
 }
 
-EXPORT_SYMBOL_GPL(dccp_li_hist_delete);
+static inline void dccp_li_hist_entry_delete(struct dccp_li_hist_entry *entry)
+{
+       if (entry != NULL)
+               kmem_cache_free(dccp_li_cachep, entry);
+}
 
-void dccp_li_hist_purge(struct dccp_li_hist *hist, struct list_head *list)
+void dccp_li_hist_purge(struct list_head *list)
 {
        struct dccp_li_hist_entry *entry, *next;
 
        list_for_each_entry_safe(entry, next, list, dccplih_node) {
                list_del_init(&entry->dccplih_node);
-               kmem_cache_free(hist->dccplih_slab, entry);
+               kmem_cache_free(dccp_li_cachep, entry);
        }
 }
 
@@ -118,16 +98,16 @@ u32 dccp_li_hist_calc_i_mean(struct list_head *list)
 
 EXPORT_SYMBOL_GPL(dccp_li_hist_calc_i_mean);
 
-int dccp_li_hist_interval_new(struct dccp_li_hist *hist,
-   struct list_head *list, const u64 seq_loss, const u8 win_loss)
+static int dccp_li_hist_interval_new(struct list_head *list,
+                                    const u64 seq_loss, const u8 win_loss)
 {
        struct dccp_li_hist_entry *entry;
        int i;
 
        for (i = 0; i < DCCP_LI_HIST_IVAL_F_LENGTH; i++) {
-               entry = dccp_li_hist_entry_new(hist, GFP_ATOMIC);
+               entry = dccp_li_hist_entry_new(GFP_ATOMIC);
                if (entry == NULL) {
-                       dccp_li_hist_purge(hist, list);
+                       dccp_li_hist_purge(list);
                        DCCP_BUG("loss interval list entry is NULL");
                        return 0;
                }
@@ -140,4 +120,176 @@ int dccp_li_hist_interval_new(struct dccp_li_hist *hist,
        return 1;
 }
 
-EXPORT_SYMBOL_GPL(dccp_li_hist_interval_new);
+/* calculate first loss interval
+ *
+ * returns estimated loss interval in usecs */
+static u32 dccp_li_calc_first_li(struct sock *sk,
+                                struct list_head *hist_list,
+                                struct timeval *last_feedback,
+                                u16 s, u32 bytes_recv,
+                                u32 previous_x_recv)
+{
+       struct dccp_rx_hist_entry *entry, *next, *tail = NULL;
+       u32 x_recv, p;
+       suseconds_t rtt, delta;
+       struct timeval tstamp = { 0, 0 };
+       int interval = 0;
+       int win_count = 0;
+       int step = 0;
+       u64 fval;
+
+       list_for_each_entry_safe(entry, next, hist_list, dccphrx_node) {
+               if (dccp_rx_hist_entry_data_packet(entry)) {
+                       tail = entry;
+
+                       switch (step) {
+                       case 0:
+                               tstamp    = entry->dccphrx_tstamp;
+                               win_count = entry->dccphrx_ccval;
+                               step = 1;
+                               break;
+                       case 1:
+                               interval = win_count - entry->dccphrx_ccval;
+                               if (interval < 0)
+                                       interval += TFRC_WIN_COUNT_LIMIT;
+                               if (interval > 4)
+                                       goto found;
+                               break;
+                       }
+               }
+       }
+
+       if (unlikely(step == 0)) {
+               DCCP_WARN("%s(%p), packet history has no data packets!\n",
+                         dccp_role(sk), sk);
+               return ~0;
+       }
+
+       if (unlikely(interval == 0)) {
+               DCCP_WARN("%s(%p), Could not find a win_count interval > 0."
+                         "Defaulting to 1\n", dccp_role(sk), sk);
+               interval = 1;
+       }
+found:
+       if (!tail) {
+               DCCP_CRIT("tail is null\n");
+               return ~0;
+       }
+
+       delta = timeval_delta(&tstamp, &tail->dccphrx_tstamp);
+       DCCP_BUG_ON(delta < 0);
+
+       rtt = delta * 4 / interval;
+       dccp_pr_debug("%s(%p), approximated RTT to %dus\n",
+                     dccp_role(sk), sk, (int)rtt);
+
+       /*
+        * Determine the length of the first loss interval via inverse lookup.
+        * Assume that X_recv can be computed by the throughput equation
+        *                  s
+        *      X_recv = --------
+        *               R * fval
+        * Find some p such that f(p) = fval; return 1/p [RFC 3448, 6.3.1].
+        */
+       if (rtt == 0) {                 /* would result in divide-by-zero */
+               DCCP_WARN("RTT==0\n");
+               return ~0;
+       }
+
+       dccp_timestamp(sk, &tstamp);
+       delta = timeval_delta(&tstamp, last_feedback);
+       DCCP_BUG_ON(delta <= 0);
+
+       x_recv = scaled_div32(bytes_recv, delta);
+       if (x_recv == 0) {              /* would also trigger divide-by-zero */
+               DCCP_WARN("X_recv==0\n");
+               if (previous_x_recv == 0) {
+                       DCCP_BUG("stored value of X_recv is zero");
+                       return ~0;
+               }
+               x_recv = previous_x_recv;
+       }
+
+       fval = scaled_div(s, rtt);
+       fval = scaled_div32(fval, x_recv);
+       p = tfrc_calc_x_reverse_lookup(fval);
+
+       dccp_pr_debug("%s(%p), receive rate=%u bytes/s, implied "
+                     "loss rate=%u\n", dccp_role(sk), sk, x_recv, p);
+
+       if (p == 0)
+               return ~0;
+       else
+               return 1000000 / p;
+}
+
+void dccp_li_update_li(struct sock *sk,
+                      struct list_head *li_hist_list,
+                      struct list_head *hist_list,
+                      struct timeval *last_feedback, u16 s, u32 bytes_recv,
+                       u32 previous_x_recv, u64 seq_loss, u8 win_loss)
+{
+       struct dccp_li_hist_entry *head;
+       u64 seq_temp;
+
+       if (list_empty(li_hist_list)) {
+               if (!dccp_li_hist_interval_new(li_hist_list, seq_loss,
+                                              win_loss))
+                       return;
+
+               head = list_entry(li_hist_list->next, struct dccp_li_hist_entry,
+                                 dccplih_node);
+               head->dccplih_interval = dccp_li_calc_first_li(sk, hist_list,
+                                                              last_feedback,
+                                                              s, bytes_recv,
+                                                              previous_x_recv);
+       } else {
+               struct dccp_li_hist_entry *entry;
+               struct list_head *tail;
+
+               head = list_entry(li_hist_list->next, struct dccp_li_hist_entry,
+                                 dccplih_node);
+               /* FIXME win count check removed as was wrong */
+               /* should make this check with receive history */
+               /* and compare there as per section 10.2 of RFC4342 */
+
+               /* new loss event detected */
+               /* calculate last interval length */
+               seq_temp = dccp_delta_seqno(head->dccplih_seqno, seq_loss);
+               entry = dccp_li_hist_entry_new(GFP_ATOMIC);
+
+               if (entry == NULL) {
+                       DCCP_BUG("out of memory - can not allocate entry");
+                       return;
+               }
+
+               list_add(&entry->dccplih_node, li_hist_list);
+
+               tail = li_hist_list->prev;
+               list_del(tail);
+               kmem_cache_free(dccp_li_cachep, tail);
+
+               /* Create the newest interval */
+               entry->dccplih_seqno = seq_loss;
+               entry->dccplih_interval = seq_temp;
+               entry->dccplih_win_count = win_loss;
+       }
+}
+
+EXPORT_SYMBOL_GPL(dccp_li_update_li);
+
+static __init int dccp_li_init(void)
+{
+       dccp_li_cachep = kmem_cache_create("dccp_li_hist",
+                                          sizeof(struct dccp_li_hist_entry),
+                                          0, SLAB_HWCACHE_ALIGN, NULL, NULL);
+       return dccp_li_cachep == NULL ? -ENOBUFS : 0;
+}
+
+static __exit void dccp_li_exit(void)
+{
+       kmem_cache_destroy(dccp_li_cachep);
+}
+
+module_init(dccp_li_init);
+module_exit(dccp_li_exit);
index eb257014dd74c25339f46d96be60641f3fc337e9..906c806d6d9d107720b9af7d5ba06840608e7868 100644 (file)
@@ -3,8 +3,8 @@
 /*
  *  net/dccp/ccids/lib/loss_interval.h
  *
- *  Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand.
- *  Copyright (c) 2005 Ian McDonald <ian.mcdonald@jandi.co.nz>
+ *  Copyright (c) 2005-7 The University of Waikato, Hamilton, New Zealand.
+ *  Copyright (c) 2005-7 Ian McDonald <ian.mcdonald@jandi.co.nz>
  *  Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
  *
  *  This program is free software; you can redistribute it and/or modify it
  */
 
 #include <linux/list.h>
-#include <linux/slab.h>
 #include <linux/time.h>
 
-#define DCCP_LI_HIST_IVAL_F_LENGTH  8
-
-struct dccp_li_hist {
-       struct kmem_cache *dccplih_slab;
-};
-
-extern struct dccp_li_hist *dccp_li_hist_new(const char *name);
-extern void dccp_li_hist_delete(struct dccp_li_hist *hist);
-
-struct dccp_li_hist_entry {
-       struct list_head dccplih_node;
-       u64              dccplih_seqno:48,
-                        dccplih_win_count:4;
-       u32              dccplih_interval;
-};
-
-static inline struct dccp_li_hist_entry *
-               dccp_li_hist_entry_new(struct dccp_li_hist *hist,
-                                      const gfp_t prio)
-{
-       return kmem_cache_alloc(hist->dccplih_slab, prio);
-}
-
-static inline void dccp_li_hist_entry_delete(struct dccp_li_hist *hist,
-                                            struct dccp_li_hist_entry *entry)
-{
-       if (entry != NULL)
-               kmem_cache_free(hist->dccplih_slab, entry);
-}
-
-extern void dccp_li_hist_purge(struct dccp_li_hist *hist,
-                              struct list_head *list);
+extern void dccp_li_hist_purge(struct list_head *list);
 
 extern u32 dccp_li_hist_calc_i_mean(struct list_head *list);
 
-extern int dccp_li_hist_interval_new(struct dccp_li_hist *hist,
-   struct list_head *list, const u64 seq_loss, const u8 win_loss);
+extern void dccp_li_update_li(struct sock *sk,
+                             struct list_head *li_hist_list,
+                             struct list_head *hist_list,
+                             struct timeval *last_feedback, u16 s,
+                             u32 bytes_recv, u32 previous_x_recv,
+                             u64 seq_loss, u8 win_loss);
 #endif /* _DCCP_LI_HIST_ */
index d8ad27bfe01a1d16bf50f17b92589be6988993ee..e2d74cd7eeeb3557423d3284225146bd6aae1deb 100644 (file)
@@ -184,7 +184,7 @@ DECLARE_SNMP_STAT(struct dccp_mib, dccp_statistics);
 /*
  *     Checksumming routines
  */
-static inline int dccp_csum_coverage(const struct sk_buff *skb)
+static inline unsigned int dccp_csum_coverage(const struct sk_buff *skb)
 {
        const struct dccp_hdr* dh = dccp_hdr(skb);
 
@@ -195,7 +195,7 @@ static inline int dccp_csum_coverage(const struct sk_buff *skb)
 
 static inline void dccp_csum_outgoing(struct sk_buff *skb)
 {
-       int cov = dccp_csum_coverage(skb);
+       unsigned int cov = dccp_csum_coverage(skb);
 
        if (cov >= skb->len)
                dccp_hdr(skb)->dccph_cscov = 0;
index 31737cdf156a5e657760278c557cbb861d2961f7..b158c661867bb128d7f182e0c215e6836f710f36 100644 (file)
@@ -253,17 +253,6 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req,
 
        if (dst == NULL) {
                opt = np->opt;
-               if (opt == NULL &&
-                   np->rxopt.bits.osrcrt == 2 &&
-                   ireq6->pktopts) {
-                       struct sk_buff *pktopts = ireq6->pktopts;
-                       struct inet6_skb_parm *rxopt = IP6CB(pktopts);
-
-                       if (rxopt->srcrt)
-                               opt = ipv6_invert_rthdr(sk,
-                         (struct ipv6_rt_hdr *)(skb_network_header(pktopts) +
-                                                rxopt->srcrt));
-               }
 
                if (opt != NULL && opt->srcrt != NULL) {
                        const struct rt0_hdr *rt0 = (struct rt0_hdr *)opt->srcrt;
@@ -570,15 +559,6 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
        if (sk_acceptq_is_full(sk))
                goto out_overflow;
 
-       if (np->rxopt.bits.osrcrt == 2 && opt == NULL && ireq6->pktopts) {
-               const struct inet6_skb_parm *rxopt = IP6CB(ireq6->pktopts);
-
-               if (rxopt->srcrt)
-                       opt = ipv6_invert_rthdr(sk,
-                  (struct ipv6_rt_hdr *)(skb_network_header(ireq6->pktopts) +
-                                         rxopt->srcrt));
-       }
-
        if (dst == NULL) {
                struct in6_addr *final_p = NULL, final;
                struct flowi fl;
index bfa910b6ad25935af657beea80cadab38e843ee8..ed76d4aab4a9dd241295463795ce373a7a317833 100644 (file)
@@ -2304,7 +2304,7 @@ static int dn_socket_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations dn_socket_seq_ops = {
+static const struct seq_operations dn_socket_seq_ops = {
        .start  = dn_socket_seq_start,
        .next   = dn_socket_seq_next,
        .stop   = dn_socket_seq_stop,
index ab41c1879fd498612f15e5356ab6a06a063d4050..fa6604fcf0e7875837180953c47db8bd42525098 100644 (file)
@@ -461,7 +461,6 @@ static int dn_dev_insert_ifa(struct dn_dev *dn_db, struct dn_ifaddr *ifa)
                if (ifa->ifa_local != dn_eth2dn(dev->dev_addr)) {
                        dn_dn2eth(mac_addr, ifa->ifa_local);
                        dev_mc_add(dev, mac_addr, ETH_ALEN, 0);
-                       dev_mc_upload(dev);
                }
        }
 
@@ -1064,8 +1063,6 @@ static int dn_eth_up(struct net_device *dev)
        else
                dev_mc_add(dev, dn_rt_all_rt_mcast, ETH_ALEN, 0);
 
-       dev_mc_upload(dev);
-
        dn_db->use_long = 1;
 
        return 0;
@@ -1419,7 +1416,7 @@ static int dn_dev_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations dn_dev_seq_ops = {
+static const struct seq_operations dn_dev_seq_ops = {
        .start  = dn_dev_seq_start,
        .next   = dn_dev_seq_next,
        .stop   = dn_dev_seq_stop,
index 4bf066c416e2d8b0ba1e6160b377cb687081b0b7..174d8a7a6dac7834e3fbcb991388f780e99e2503 100644 (file)
@@ -569,7 +569,7 @@ static void *dn_neigh_seq_start(struct seq_file *seq, loff_t *pos)
                               NEIGH_SEQ_NEIGH_ONLY);
 }
 
-static struct seq_operations dn_neigh_seq_ops = {
+static const struct seq_operations dn_neigh_seq_ops = {
        .start = dn_neigh_seq_start,
        .next  = neigh_seq_next,
        .stop  = neigh_seq_stop,
index a8bf106b7a6118eba109fd559ae6d330fe911a94..82622fb6f68f2acca604610421f9f654548d9d89 100644 (file)
@@ -1726,7 +1726,7 @@ static int dn_rt_cache_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations dn_rt_cache_seq_ops = {
+static const struct seq_operations dn_rt_cache_seq_ops = {
        .start  = dn_rt_cache_seq_start,
        .next   = dn_rt_cache_seq_next,
        .stop   = dn_rt_cache_seq_stop,
index 0ac2524f3b68f73c53517b69e807f51c131d9701..12c765715acfdb102314ebc663d8de1bdbbb0fee 100644 (file)
@@ -266,8 +266,11 @@ void eth_header_cache_update(struct hh_cache *hh, struct net_device *dev,
 static int eth_mac_addr(struct net_device *dev, void *p)
 {
        struct sockaddr *addr = p;
+
        if (netif_running(dev))
                return -EBUSY;
+       if (!is_valid_ether_addr(addr->sa_data))
+               return -EADDRNOTAVAIL;
        memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
        return 0;
 }
@@ -316,9 +319,10 @@ void ether_setup(struct net_device *dev)
 EXPORT_SYMBOL(ether_setup);
 
 /**
- * alloc_etherdev - Allocates and sets up an Ethernet device
+ * alloc_etherdev_mq - Allocates and sets up an Ethernet device
  * @sizeof_priv: Size of additional driver-private structure to be allocated
  *     for this Ethernet device
+ * @queue_count: The number of queues this device has.
  *
  * Fill in the fields of the device structure with Ethernet-generic
  * values. Basically does everything except registering the device.
@@ -328,8 +332,8 @@ EXPORT_SYMBOL(ether_setup);
  * this private data area.
  */
 
-struct net_device *alloc_etherdev(int sizeof_priv)
+struct net_device *alloc_etherdev_mq(int sizeof_priv, unsigned int queue_count)
 {
-       return alloc_netdev(sizeof_priv, "eth%d", ether_setup);
+       return alloc_netdev_mq(sizeof_priv, "eth%d", ether_setup, queue_count);
 }
-EXPORT_SYMBOL(alloc_etherdev);
+EXPORT_SYMBOL(alloc_etherdev_mq);
index c308756c2f9dae7edb6f65d90e98dfbe41fded7a..6398e6e674936af9be7124f897da0478a681e724 100644 (file)
@@ -456,18 +456,13 @@ void
 ieee80211softmac_add_network_locked(struct ieee80211softmac_device *mac,
        struct ieee80211softmac_network *add_net)
 {
-       struct list_head *list_ptr;
-       struct ieee80211softmac_network *softmac_net = NULL;
+       struct ieee80211softmac_network *softmac_net;
 
-       list_for_each(list_ptr, &mac->network_list) {
-               softmac_net = list_entry(list_ptr, struct ieee80211softmac_network, list);
+       list_for_each_entry(softmac_net, &mac->network_list, list) {
                if(!memcmp(softmac_net->bssid, add_net->bssid, ETH_ALEN))
-                       break;
-               else
-                       softmac_net = NULL;
+                       return;
        }
-       if(softmac_net == NULL)
-               list_add(&(add_net->list), &mac->network_list);
+       list_add(&(add_net->list), &mac->network_list);
 }
 
 /* Add a network to the list, with locking */
@@ -506,16 +501,13 @@ struct ieee80211softmac_network *
 ieee80211softmac_get_network_by_bssid_locked(struct ieee80211softmac_device *mac,
        u8 *bssid)
 {
-       struct list_head *list_ptr;
-       struct ieee80211softmac_network *softmac_net = NULL;
-       list_for_each(list_ptr, &mac->network_list) {
-               softmac_net = list_entry(list_ptr, struct ieee80211softmac_network, list);
+       struct ieee80211softmac_network *softmac_net;
+
+       list_for_each_entry(softmac_net, &mac->network_list, list) {
                if(!memcmp(softmac_net->bssid, bssid, ETH_ALEN))
-                       break;
-               else
-                       softmac_net = NULL;
+                       return softmac_net;
        }
-       return softmac_net;
+       return NULL;
 }
 
 /* Get a network from the list by BSSID with locking */
@@ -537,11 +529,9 @@ struct ieee80211softmac_network *
 ieee80211softmac_get_network_by_essid_locked(struct ieee80211softmac_device *mac,
        struct ieee80211softmac_essid *essid)
 {
-       struct list_head *list_ptr;
-       struct ieee80211softmac_network *softmac_net = NULL;
+       struct ieee80211softmac_network *softmac_net;
 
-       list_for_each(list_ptr, &mac->network_list) {
-               softmac_net = list_entry(list_ptr, struct ieee80211softmac_network, list);
+       list_for_each_entry(softmac_net, &mac->network_list, list) {
                if (softmac_net->essid.len == essid->len &&
                        !memcmp(softmac_net->essid.data, essid->data, essid->len))
                        return softmac_net;
index 010fbb2d45e9681aae9bae04463fa48f2c4f66b5..fb7909774254f777636744bf086e8f152302e3e2 100644 (file)
@@ -116,48 +116,6 @@ config IP_ROUTE_MULTIPATH
          equal "cost" and chooses one of them in a non-deterministic fashion
          if a matching packet arrives.
 
-config IP_ROUTE_MULTIPATH_CACHED
-       bool "IP: equal cost multipath with caching support (EXPERIMENTAL)"
-       depends on IP_ROUTE_MULTIPATH
-       help
-         Normally, equal cost multipath routing is not supported by the
-         routing cache. If you say Y here, alternative routes are cached
-         and on cache lookup a route is chosen in a configurable fashion.
-
-         If unsure, say N.
-
-config IP_ROUTE_MULTIPATH_RR
-       tristate "MULTIPATH: round robin algorithm"
-       depends on IP_ROUTE_MULTIPATH_CACHED
-       help
-         Multipath routes are chosen according to Round Robin
-
-config IP_ROUTE_MULTIPATH_RANDOM
-       tristate "MULTIPATH: random algorithm"
-       depends on IP_ROUTE_MULTIPATH_CACHED
-       help
-         Multipath routes are chosen in a random fashion. Actually,
-         there is no weight for a route. The advantage of this policy
-         is that it is implemented stateless and therefore introduces only
-         a very small delay.
-
-config IP_ROUTE_MULTIPATH_WRANDOM
-       tristate "MULTIPATH: weighted random algorithm"
-       depends on IP_ROUTE_MULTIPATH_CACHED
-       help
-         Multipath routes are chosen in a weighted random fashion. 
-         The per route weights are the weights visible via ip route 2. As the
-         corresponding state management introduces some overhead routing delay
-         is increased.
-
-config IP_ROUTE_MULTIPATH_DRR
-       tristate "MULTIPATH: interface round robin algorithm"
-       depends on IP_ROUTE_MULTIPATH_CACHED
-       help
-         Connections are distributed in a round robin fashion over the
-         available interfaces. This policy makes sense if the connections 
-         should be primarily distributed on interfaces and not on routes. 
-
 config IP_ROUTE_VERBOSE
        bool "IP: verbose route monitoring"
        depends on IP_ADVANCED_ROUTER
index 4ff6c151d7f31d1ca3f490a5224601d196a26beb..fbf1674e0c2ab1e92cbd23df734b9240e6843841 100644 (file)
@@ -29,14 +29,9 @@ obj-$(CONFIG_INET_TUNNEL) += tunnel4.o
 obj-$(CONFIG_INET_XFRM_MODE_TRANSPORT) += xfrm4_mode_transport.o
 obj-$(CONFIG_INET_XFRM_MODE_TUNNEL) += xfrm4_mode_tunnel.o
 obj-$(CONFIG_IP_PNP) += ipconfig.o
-obj-$(CONFIG_IP_ROUTE_MULTIPATH_RR) += multipath_rr.o
-obj-$(CONFIG_IP_ROUTE_MULTIPATH_RANDOM) += multipath_random.o
-obj-$(CONFIG_IP_ROUTE_MULTIPATH_WRANDOM) += multipath_wrandom.o
-obj-$(CONFIG_IP_ROUTE_MULTIPATH_DRR) += multipath_drr.o
 obj-$(CONFIG_NETFILTER)        += netfilter.o netfilter/
 obj-$(CONFIG_IP_VS) += ipvs/
 obj-$(CONFIG_INET_DIAG) += inet_diag.o 
-obj-$(CONFIG_IP_ROUTE_MULTIPATH_CACHED) += multipath.o
 obj-$(CONFIG_INET_TCP_DIAG) += tcp_diag.o
 obj-$(CONFIG_NET_TCPPROBE) += tcp_probe.o
 obj-$(CONFIG_TCP_CONG_BIC) += tcp_bic.o
index 041fba3fa0aa312c3ff1e2de35b81bb8025d19aa..06c08e5740fbcca5b0aa37dade5a90f88609ee42 100644 (file)
@@ -1170,6 +1170,9 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features)
        int ihl;
        int id;
 
+       if (!(features & NETIF_F_V4_CSUM))
+               features &= ~NETIF_F_SG;
+
        if (unlikely(skb_shinfo(skb)->gso_type &
                     ~(SKB_GSO_TCPV4 |
                       SKB_GSO_UDP |
index 6da8ff597ad30f7462371d4547032d220b55b7e0..7a23e59c374a3491c802e83f45638c82e6b2a64a 100644 (file)
@@ -339,3 +339,4 @@ static void __exit ah4_fini(void)
 module_init(ah4_init);
 module_exit(ah4_fini);
 MODULE_LICENSE("GPL");
+MODULE_ALIAS_XFRM_TYPE(AF_INET, XFRM_PROTO_AH);
index 47c95e8ef0456483937d810d3647f263e0a42bf6..98767a4f1185befb14c519fb73395056066f159f 100644 (file)
@@ -481,3 +481,4 @@ static void __exit esp4_fini(void)
 module_init(esp4_init);
 module_exit(esp4_fini);
 MODULE_LICENSE("GPL");
+MODULE_ALIAS_XFRM_TYPE(AF_INET, XFRM_PROTO_ESP);
index 311d633f7f397b545b6a0839319c1d446c18eb27..2eb909be8041829b5a9da596a2aac6c052c99b15 100644 (file)
@@ -453,7 +453,6 @@ const struct nla_policy rtm_ipv4_policy[RTA_MAX+1] = {
        [RTA_MULTIPATH]         = { .len = sizeof(struct rtnexthop) },
        [RTA_PROTOINFO]         = { .type = NLA_U32 },
        [RTA_FLOW]              = { .type = NLA_U32 },
-       [RTA_MP_ALGO]           = { .type = NLA_U32 },
 };
 
 static int rtm_to_fib_config(struct sk_buff *skb, struct nlmsghdr *nlh,
@@ -515,9 +514,6 @@ static int rtm_to_fib_config(struct sk_buff *skb, struct nlmsghdr *nlh,
                case RTA_FLOW:
                        cfg->fc_flow = nla_get_u32(attr);
                        break;
-               case RTA_MP_ALGO:
-                       cfg->fc_mp_alg = nla_get_u32(attr);
-                       break;
                case RTA_TABLE:
                        cfg->fc_table = nla_get_u32(attr);
                        break;
index bb94550d95c3e8a2c80b1fc74bed9b9eb1b52a5a..c434119deb527d8e1754dbbdc9b81cb08987e8f7 100644 (file)
@@ -42,7 +42,6 @@
 #include <net/tcp.h>
 #include <net/sock.h>
 #include <net/ip_fib.h>
-#include <net/ip_mp_alg.h>
 #include <net/netlink.h>
 #include <net/nexthop.h>
 
@@ -697,13 +696,6 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
                        goto err_inval;
        }
 #endif
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-       if (cfg->fc_mp_alg) {
-               if (cfg->fc_mp_alg < IP_MP_ALG_NONE ||
-                   cfg->fc_mp_alg > IP_MP_ALG_MAX)
-                       goto err_inval;
-       }
-#endif
 
        err = -ENOBUFS;
        if (fib_info_cnt >= fib_hash_size) {
@@ -791,10 +783,6 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
 #endif
        }
 
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-       fi->fib_mp_alg = cfg->fc_mp_alg;
-#endif
-
        if (fib_props[cfg->fc_type].error) {
                if (cfg->fc_gw || cfg->fc_oif || cfg->fc_mp)
                        goto err_inval;
@@ -940,10 +928,6 @@ out_fill_res:
        res->type = fa->fa_type;
        res->scope = fa->fa_scope;
        res->fi = fa->fa_info;
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-       res->netmask = mask;
-       res->network = zone & inet_make_mask(prefixlen);
-#endif
        atomic_inc(&res->fi->fib_clntref);
        return 0;
 }
index 63282934725e0971672bc146491c5aa178816b3e..5c14ed63e56c97c8b53f188fd0bfd6997a3e8f8c 100644 (file)
@@ -809,7 +809,8 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
 
        max_headroom = LL_RESERVED_SPACE(tdev) + gre_hlen;
 
-       if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) {
+       if (skb_headroom(skb) < max_headroom || skb_shared(skb)||
+           (skb_cloned(skb) && !skb_clone_writable(skb, 0))) {
                struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
                if (!new_skb) {
                        ip_rt_put(rt);
index 34ea4547ebbea10cda26bca8a6f05307218b9518..c9e2b5e6305e2288966735800d950814899ca53b 100644 (file)
@@ -399,6 +399,10 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from)
        to->tc_index = from->tc_index;
 #endif
        nf_copy(to, from);
+#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
+    defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
+       to->nf_trace = from->nf_trace;
+#endif
 #if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
        to->ipvs_property = from->ipvs_property;
 #endif
@@ -837,7 +841,7 @@ int ip_append_data(struct sock *sk,
         */
        if (transhdrlen &&
            length + fragheaderlen <= mtu &&
-           rt->u.dst.dev->features & NETIF_F_ALL_CSUM &&
+           rt->u.dst.dev->features & NETIF_F_V4_CSUM &&
            !exthdrlen)
                csummode = CHECKSUM_PARTIAL;
 
index ab86137c71d2109182028a649d484371a346e7c1..e787044a85148ebceaafdbb964c7dd15c2e99daa 100644 (file)
@@ -485,3 +485,4 @@ MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("IP Payload Compression Protocol (IPComp) - RFC3173");
 MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>");
 
+MODULE_ALIAS_XFRM_TYPE(AF_INET, XFRM_PROTO_COMP);
index ebd2f2d532f66bd1e57d173cde001026da1527dd..396437242a1b36186db17ff5aaa1bf5d60a1734b 100644 (file)
@@ -595,7 +595,8 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
         */
        max_headroom = (LL_RESERVED_SPACE(tdev)+sizeof(struct iphdr));
 
-       if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) {
+       if (skb_headroom(skb) < max_headroom || skb_shared(skb) ||
+           (skb_cloned(skb) && !skb_clone_writable(skb, 0))) {
                struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
                if (!new_skb) {
                        ip_rt_put(rt);
index 15ad5dd2d984e7f06b408ee90b66725182f2d1c3..8d6901d4e94f897d850a5399214d82e6dd48c3d5 100644 (file)
@@ -549,7 +549,7 @@ static int ip_vs_app_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations ip_vs_app_seq_ops = {
+static const struct seq_operations ip_vs_app_seq_ops = {
        .start = ip_vs_app_seq_start,
        .next  = ip_vs_app_seq_next,
        .stop  = ip_vs_app_seq_stop,
index 7018f97c75dc64f18af0ffbced9734c1cf8d2dc7..3b446b1a6b9c8b7b0a49642b0692d78ee2f9d212 100644 (file)
@@ -745,7 +745,7 @@ static int ip_vs_conn_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations ip_vs_conn_seq_ops = {
+static const struct seq_operations ip_vs_conn_seq_ops = {
        .start = ip_vs_conn_seq_start,
        .next  = ip_vs_conn_seq_next,
        .stop  = ip_vs_conn_seq_stop,
index 68fe1d4d0210384d358947acbdd55ed17bdc4f8d..e1052bcf4ed190ecefc35c7380eaa0be407c6b24 100644 (file)
@@ -1783,7 +1783,7 @@ static int ip_vs_info_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations ip_vs_info_seq_ops = {
+static const struct seq_operations ip_vs_info_seq_ops = {
        .start = ip_vs_info_seq_start,
        .next  = ip_vs_info_seq_next,
        .stop  = ip_vs_info_seq_stop,
diff --git a/net/ipv4/multipath.c b/net/ipv4/multipath.c
deleted file mode 100644 (file)
index 4e9ca7c..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/* multipath.c: IPV4 multipath algorithm support.
- *
- * Copyright (C) 2004, 2005 Einar Lueck <elueck@de.ibm.com>
- * Copyright (C) 2005 David S. Miller <davem@davemloft.net>
- */
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/netdevice.h>
-#include <linux/spinlock.h>
-
-#include <net/ip_mp_alg.h>
-
-static DEFINE_SPINLOCK(alg_table_lock);
-struct ip_mp_alg_ops *ip_mp_alg_table[IP_MP_ALG_MAX + 1];
-
-int multipath_alg_register(struct ip_mp_alg_ops *ops, enum ip_mp_alg n)
-{
-       struct ip_mp_alg_ops **slot;
-       int err;
-
-       if (n < IP_MP_ALG_NONE || n > IP_MP_ALG_MAX ||
-           !ops->mp_alg_select_route)
-               return -EINVAL;
-
-       spin_lock(&alg_table_lock);
-       slot = &ip_mp_alg_table[n];
-       if (*slot != NULL) {
-               err = -EBUSY;
-       } else {
-               *slot = ops;
-               err = 0;
-       }
-       spin_unlock(&alg_table_lock);
-
-       return err;
-}
-EXPORT_SYMBOL(multipath_alg_register);
-
-void multipath_alg_unregister(struct ip_mp_alg_ops *ops, enum ip_mp_alg n)
-{
-       struct ip_mp_alg_ops **slot;
-
-       if (n < IP_MP_ALG_NONE || n > IP_MP_ALG_MAX)
-               return;
-
-       spin_lock(&alg_table_lock);
-       slot = &ip_mp_alg_table[n];
-       if (*slot == ops)
-               *slot = NULL;
-       spin_unlock(&alg_table_lock);
-
-       synchronize_net();
-}
-EXPORT_SYMBOL(multipath_alg_unregister);
diff --git a/net/ipv4/multipath_drr.c b/net/ipv4/multipath_drr.c
deleted file mode 100644 (file)
index b03c5ca..0000000
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- *              Device round robin policy for multipath.
- *
- *
- * Version:    $Id: multipath_drr.c,v 1.1.2.1 2004/09/16 07:42:34 elueck Exp $
- *
- * Authors:    Einar Lueck <elueck@de.ibm.com><lkml@einar-lueck.de>
- *
- *             This program is free software; you can redistribute it and/or
- *             modify it under the terms of the GNU General Public License
- *             as published by the Free Software Foundation; either version
- *             2 of the License, or (at your option) any later version.
- */
-
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/kernel.h>
-#include <linux/fcntl.h>
-#include <linux/stat.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/inetdevice.h>
-#include <linux/igmp.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/module.h>
-#include <linux/mroute.h>
-#include <linux/init.h>
-#include <net/ip.h>
-#include <net/protocol.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <net/icmp.h>
-#include <net/udp.h>
-#include <net/raw.h>
-#include <linux/notifier.h>
-#include <linux/if_arp.h>
-#include <linux/netfilter_ipv4.h>
-#include <net/ipip.h>
-#include <net/checksum.h>
-#include <net/ip_mp_alg.h>
-
-struct multipath_device {
-       int             ifi; /* interface index of device */
-       atomic_t        usecount;
-       int             allocated;
-};
-
-#define MULTIPATH_MAX_DEVICECANDIDATES 10
-
-static struct multipath_device state[MULTIPATH_MAX_DEVICECANDIDATES];
-static DEFINE_SPINLOCK(state_lock);
-
-static int inline __multipath_findslot(void)
-{
-       int i;
-
-       for (i = 0; i < MULTIPATH_MAX_DEVICECANDIDATES; i++) {
-               if (state[i].allocated == 0)
-                       return i;
-       }
-       return -1;
-}
-
-static int inline __multipath_finddev(int ifindex)
-{
-       int i;
-
-       for (i = 0; i < MULTIPATH_MAX_DEVICECANDIDATES; i++) {
-               if (state[i].allocated != 0 &&
-                   state[i].ifi == ifindex)
-                       return i;
-       }
-       return -1;
-}
-
-static int drr_dev_event(struct notifier_block *this,
-                        unsigned long event, void *ptr)
-{
-       struct net_device *dev = ptr;
-       int devidx;
-
-       switch (event) {
-       case NETDEV_UNREGISTER:
-       case NETDEV_DOWN:
-               spin_lock_bh(&state_lock);
-
-               devidx = __multipath_finddev(dev->ifindex);
-               if (devidx != -1) {
-                       state[devidx].allocated = 0;
-                       state[devidx].ifi = 0;
-                       atomic_set(&state[devidx].usecount, 0);
-               }
-
-               spin_unlock_bh(&state_lock);
-               break;
-       }
-
-       return NOTIFY_DONE;
-}
-
-static struct notifier_block drr_dev_notifier = {
-       .notifier_call  = drr_dev_event,
-};
-
-
-static void drr_safe_inc(atomic_t *usecount)
-{
-       int n;
-
-       atomic_inc(usecount);
-
-       n = atomic_read(usecount);
-       if (n <= 0) {
-               int i;
-
-               spin_lock_bh(&state_lock);
-
-               for (i = 0; i < MULTIPATH_MAX_DEVICECANDIDATES; i++)
-                       atomic_set(&state[i].usecount, 0);
-
-               spin_unlock_bh(&state_lock);
-       }
-}
-
-static void drr_select_route(const struct flowi *flp,
-                            struct rtable *first, struct rtable **rp)
-{
-       struct rtable *nh, *result, *cur_min;
-       int min_usecount = -1;
-       int devidx = -1;
-       int cur_min_devidx = -1;
-
-       /* 1. make sure all alt. nexthops have the same GC related data */
-       /* 2. determine the new candidate to be returned */
-       result = NULL;
-       cur_min = NULL;
-       for (nh = rcu_dereference(first); nh;
-            nh = rcu_dereference(nh->u.dst.rt_next)) {
-               if ((nh->u.dst.flags & DST_BALANCED) != 0 &&
-                   multipath_comparekeys(&nh->fl, flp)) {
-                       int nh_ifidx = nh->u.dst.dev->ifindex;
-
-                       nh->u.dst.lastuse = jiffies;
-                       nh->u.dst.__use++;
-                       if (result != NULL)
-                               continue;
-
-                       /* search for the output interface */
-
-                       /* this is not SMP safe, only add/remove are
-                        * SMP safe as wrong usecount updates have no big
-                        * impact
-                        */
-                       devidx = __multipath_finddev(nh_ifidx);
-                       if (devidx == -1) {
-                               /* add the interface to the array
-                                * SMP safe
-                                */
-                               spin_lock_bh(&state_lock);
-
-                               /* due to SMP: search again */
-                               devidx = __multipath_finddev(nh_ifidx);
-                               if (devidx == -1) {
-                                       /* add entry for device */
-                                       devidx = __multipath_findslot();
-                                       if (devidx == -1) {
-                                               /* unlikely but possible */
-                                               continue;
-                                       }
-
-                                       state[devidx].allocated = 1;
-                                       state[devidx].ifi = nh_ifidx;
-                                       atomic_set(&state[devidx].usecount, 0);
-                                       min_usecount = 0;
-                               }
-
-                               spin_unlock_bh(&state_lock);
-                       }
-
-                       if (min_usecount == 0) {
-                               /* if the device has not been used it is
-                                * the primary target
-                                */
-                               drr_safe_inc(&state[devidx].usecount);
-                               result = nh;
-                       } else {
-                               int count =
-                                       atomic_read(&state[devidx].usecount);
-
-                               if (min_usecount == -1 ||
-                                   count < min_usecount) {
-                                       cur_min = nh;
-                                       cur_min_devidx = devidx;
-                                       min_usecount = count;
-                               }
-                       }
-               }
-       }
-
-       if (!result) {
-               if (cur_min) {
-                       drr_safe_inc(&state[cur_min_devidx].usecount);
-                       result = cur_min;
-               } else {
-                       result = first;
-               }
-       }
-
-       *rp = result;
-}
-
-static struct ip_mp_alg_ops drr_ops = {
-       .mp_alg_select_route    =       drr_select_route,
-};
-
-static int __init drr_init(void)
-{
-       int err = register_netdevice_notifier(&drr_dev_notifier);
-
-       if (err)
-               return err;
-
-       err = multipath_alg_register(&drr_ops, IP_MP_ALG_DRR);
-       if (err)
-               goto fail;
-
-       return 0;
-
-fail:
-       unregister_netdevice_notifier(&drr_dev_notifier);
-       return err;
-}
-
-static void __exit drr_exit(void)
-{
-       unregister_netdevice_notifier(&drr_dev_notifier);
-       multipath_alg_unregister(&drr_ops, IP_MP_ALG_DRR);
-}
-
-module_init(drr_init);
-module_exit(drr_exit);
-MODULE_LICENSE("GPL");
diff --git a/net/ipv4/multipath_random.c b/net/ipv4/multipath_random.c
deleted file mode 100644 (file)
index c312785..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- *              Random policy for multipath.
- *
- *
- * Version:    $Id: multipath_random.c,v 1.1.2.3 2004/09/21 08:42:11 elueck Exp $
- *
- * Authors:    Einar Lueck <elueck@de.ibm.com><lkml@einar-lueck.de>
- *
- *             This program is free software; you can redistribute it and/or
- *             modify it under the terms of the GNU General Public License
- *             as published by the Free Software Foundation; either version
- *             2 of the License, or (at your option) any later version.
- */
-
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/kernel.h>
-#include <linux/fcntl.h>
-#include <linux/stat.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/inetdevice.h>
-#include <linux/igmp.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/module.h>
-#include <linux/mroute.h>
-#include <linux/init.h>
-#include <linux/random.h>
-#include <net/ip.h>
-#include <net/protocol.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <net/icmp.h>
-#include <net/udp.h>
-#include <net/raw.h>
-#include <linux/notifier.h>
-#include <linux/if_arp.h>
-#include <linux/netfilter_ipv4.h>
-#include <net/ipip.h>
-#include <net/checksum.h>
-#include <net/ip_mp_alg.h>
-
-#define MULTIPATH_MAX_CANDIDATES 40
-
-static void random_select_route(const struct flowi *flp,
-                               struct rtable *first,
-                               struct rtable **rp)
-{
-       struct rtable *rt;
-       struct rtable *decision;
-       unsigned char candidate_count = 0;
-
-       /* count all candidate */
-       for (rt = rcu_dereference(first); rt;
-            rt = rcu_dereference(rt->u.dst.rt_next)) {
-               if ((rt->u.dst.flags & DST_BALANCED) != 0 &&
-                   multipath_comparekeys(&rt->fl, flp))
-                       ++candidate_count;
-       }
-
-       /* choose a random candidate */
-       decision = first;
-       if (candidate_count > 1) {
-               unsigned char i = 0;
-               unsigned char candidate_no = (unsigned char)
-                       (random32() % candidate_count);
-
-               /* find chosen candidate and adjust GC data for all candidates
-                * to ensure they stay in cache
-                */
-               for (rt = first; rt; rt = rt->u.dst.rt_next) {
-                       if ((rt->u.dst.flags & DST_BALANCED) != 0 &&
-                           multipath_comparekeys(&rt->fl, flp)) {
-                               rt->u.dst.lastuse = jiffies;
-
-                               if (i == candidate_no)
-                                       decision = rt;
-
-                               if (i >= candidate_count)
-                                       break;
-
-                               i++;
-                       }
-               }
-       }
-
-       decision->u.dst.__use++;
-       *rp = decision;
-}
-
-static struct ip_mp_alg_ops random_ops = {
-       .mp_alg_select_route    =       random_select_route,
-};
-
-static int __init random_init(void)
-{
-       return multipath_alg_register(&random_ops, IP_MP_ALG_RANDOM);
-}
-
-static void __exit random_exit(void)
-{
-       multipath_alg_unregister(&random_ops, IP_MP_ALG_RANDOM);
-}
-
-module_init(random_init);
-module_exit(random_exit);
-MODULE_LICENSE("GPL");
diff --git a/net/ipv4/multipath_rr.c b/net/ipv4/multipath_rr.c
deleted file mode 100644 (file)
index 0ad2252..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- *              Round robin policy for multipath.
- *
- *
- * Version:    $Id: multipath_rr.c,v 1.1.2.2 2004/09/16 07:42:34 elueck Exp $
- *
- * Authors:    Einar Lueck <elueck@de.ibm.com><lkml@einar-lueck.de>
- *
- *             This program is free software; you can redistribute it and/or
- *             modify it under the terms of the GNU General Public License
- *             as published by the Free Software Foundation; either version
- *             2 of the License, or (at your option) any later version.
- */
-
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/kernel.h>
-#include <linux/fcntl.h>
-#include <linux/stat.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/inetdevice.h>
-#include <linux/igmp.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/module.h>
-#include <linux/mroute.h>
-#include <linux/init.h>
-#include <net/ip.h>
-#include <net/protocol.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <net/icmp.h>
-#include <net/udp.h>
-#include <net/raw.h>
-#include <linux/notifier.h>
-#include <linux/if_arp.h>
-#include <linux/netfilter_ipv4.h>
-#include <net/ipip.h>
-#include <net/checksum.h>
-#include <net/ip_mp_alg.h>
-
-static void rr_select_route(const struct flowi *flp,
-                           struct rtable *first, struct rtable **rp)
-{
-       struct rtable *nh, *result, *min_use_cand = NULL;
-       int min_use = -1;
-
-       /* 1. make sure all alt. nexthops have the same GC related data
-        * 2. determine the new candidate to be returned
-        */
-       result = NULL;
-       for (nh = rcu_dereference(first); nh;
-            nh = rcu_dereference(nh->u.dst.rt_next)) {
-               if ((nh->u.dst.flags & DST_BALANCED) != 0 &&
-                   multipath_comparekeys(&nh->fl, flp)) {
-                       nh->u.dst.lastuse = jiffies;
-
-                       if (min_use == -1 || nh->u.dst.__use < min_use) {
-                               min_use = nh->u.dst.__use;
-                               min_use_cand = nh;
-                       }
-               }
-       }
-       result = min_use_cand;
-       if (!result)
-               result = first;
-
-       result->u.dst.__use++;
-       *rp = result;
-}
-
-static struct ip_mp_alg_ops rr_ops = {
-       .mp_alg_select_route    =       rr_select_route,
-};
-
-static int __init rr_init(void)
-{
-       return multipath_alg_register(&rr_ops, IP_MP_ALG_RR);
-}
-
-static void __exit rr_exit(void)
-{
-       multipath_alg_unregister(&rr_ops, IP_MP_ALG_RR);
-}
-
-module_init(rr_init);
-module_exit(rr_exit);
-MODULE_LICENSE("GPL");
diff --git a/net/ipv4/multipath_wrandom.c b/net/ipv4/multipath_wrandom.c
deleted file mode 100644 (file)
index 57c5036..0000000
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- *              Weighted random policy for multipath.
- *
- *
- * Version:    $Id: multipath_wrandom.c,v 1.1.2.3 2004/09/22 07:51:40 elueck Exp $
- *
- * Authors:    Einar Lueck <elueck@de.ibm.com><lkml@einar-lueck.de>
- *
- *             This program is free software; you can redistribute it and/or
- *             modify it under the terms of the GNU General Public License
- *             as published by the Free Software Foundation; either version
- *             2 of the License, or (at your option) any later version.
- */
-
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/kernel.h>
-#include <linux/fcntl.h>
-#include <linux/stat.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/inetdevice.h>
-#include <linux/igmp.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/module.h>
-#include <linux/mroute.h>
-#include <linux/init.h>
-#include <linux/random.h>
-#include <net/ip.h>
-#include <net/protocol.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <net/icmp.h>
-#include <net/udp.h>
-#include <net/raw.h>
-#include <linux/notifier.h>
-#include <linux/if_arp.h>
-#include <linux/netfilter_ipv4.h>
-#include <net/ipip.h>
-#include <net/checksum.h>
-#include <net/ip_fib.h>
-#include <net/ip_mp_alg.h>
-
-#define MULTIPATH_STATE_SIZE 15
-
-struct multipath_candidate {
-       struct multipath_candidate      *next;
-       int                             power;
-       struct rtable                   *rt;
-};
-
-struct multipath_dest {
-       struct list_head        list;
-
-       const struct fib_nh     *nh_info;
-       __be32                  netmask;
-       __be32                  network;
-       unsigned char           prefixlen;
-
-       struct rcu_head         rcu;
-};
-
-struct multipath_bucket {
-       struct list_head        head;
-       spinlock_t              lock;
-};
-
-struct multipath_route {
-       struct list_head        list;
-
-       int                     oif;
-       __be32                  gw;
-       struct list_head        dests;
-
-       struct rcu_head         rcu;
-};
-
-/* state: primarily weight per route information */
-static struct multipath_bucket state[MULTIPATH_STATE_SIZE];
-
-static unsigned char __multipath_lookup_weight(const struct flowi *fl,
-                                              const struct rtable *rt)
-{
-       const int state_idx = rt->idev->dev->ifindex % MULTIPATH_STATE_SIZE;
-       struct multipath_route *r;
-       struct multipath_route *target_route = NULL;
-       struct multipath_dest *d;
-       int weight = 1;
-
-       /* lookup the weight information for a certain route */
-       rcu_read_lock();
-
-       /* find state entry for gateway or add one if necessary */
-       list_for_each_entry_rcu(r, &state[state_idx].head, list) {
-               if (r->gw == rt->rt_gateway &&
-                   r->oif == rt->idev->dev->ifindex) {
-                       target_route = r;
-                       break;
-               }
-       }
-
-       if (!target_route) {
-               /* this should not happen... but we are prepared */
-               printk( KERN_CRIT"%s: missing state for gateway: %u and " \
-                       "device %d\n", __FUNCTION__, rt->rt_gateway,
-                       rt->idev->dev->ifindex);
-               goto out;
-       }
-
-       /* find state entry for destination */
-       list_for_each_entry_rcu(d, &target_route->dests, list) {
-               __be32 targetnetwork = fl->fl4_dst &
-                       inet_make_mask(d->prefixlen);
-
-               if ((targetnetwork & d->netmask) == d->network) {
-                       weight = d->nh_info->nh_weight;
-                       goto out;
-               }
-       }
-
-out:
-       rcu_read_unlock();
-       return weight;
-}
-
-static void wrandom_init_state(void)
-{
-       int i;
-
-       for (i = 0; i < MULTIPATH_STATE_SIZE; ++i) {
-               INIT_LIST_HEAD(&state[i].head);
-               spin_lock_init(&state[i].lock);
-       }
-}
-
-static void wrandom_select_route(const struct flowi *flp,
-                                struct rtable *first,
-                                struct rtable **rp)
-{
-       struct rtable *rt;
-       struct rtable *decision;
-       struct multipath_candidate *first_mpc = NULL;
-       struct multipath_candidate *mpc, *last_mpc = NULL;
-       int power = 0;
-       int last_power;
-       int selector;
-       const size_t size_mpc = sizeof(struct multipath_candidate);
-
-       /* collect all candidates and identify their weights */
-       for (rt = rcu_dereference(first); rt;
-            rt = rcu_dereference(rt->u.dst.rt_next)) {
-               if ((rt->u.dst.flags & DST_BALANCED) != 0 &&
-                   multipath_comparekeys(&rt->fl, flp)) {
-                       struct multipath_candidate* mpc =
-                               (struct multipath_candidate*)
-                               kmalloc(size_mpc, GFP_ATOMIC);
-
-                       if (!mpc)
-                               return;
-
-                       power += __multipath_lookup_weight(flp, rt) * 10000;
-
-                       mpc->power = power;
-                       mpc->rt = rt;
-                       mpc->next = NULL;
-
-                       if (!first_mpc)
-                               first_mpc = mpc;
-                       else
-                               last_mpc->next = mpc;
-
-                       last_mpc = mpc;
-               }
-       }
-
-       /* choose a weighted random candidate */
-       decision = first;
-       selector = random32() % power;
-       last_power = 0;
-
-       /* select candidate, adjust GC data and cleanup local state */
-       decision = first;
-       last_mpc = NULL;
-       for (mpc = first_mpc; mpc; mpc = mpc->next) {
-               mpc->rt->u.dst.lastuse = jiffies;
-               if (last_power <= selector && selector < mpc->power)
-                       decision = mpc->rt;
-
-               last_power = mpc->power;
-               kfree(last_mpc);
-               last_mpc = mpc;
-       }
-
-       /* concurrent __multipath_flush may lead to !last_mpc */
-       kfree(last_mpc);
-
-       decision->u.dst.__use++;
-       *rp = decision;
-}
-
-static void wrandom_set_nhinfo(__be32 network,
-                              __be32 netmask,
-                              unsigned char prefixlen,
-                              const struct fib_nh *nh)
-{
-       const int state_idx = nh->nh_oif % MULTIPATH_STATE_SIZE;
-       struct multipath_route *r, *target_route = NULL;
-       struct multipath_dest *d, *target_dest = NULL;
-
-       /* store the weight information for a certain route */
-       spin_lock_bh(&state[state_idx].lock);
-
-       /* find state entry for gateway or add one if necessary */
-       list_for_each_entry_rcu(r, &state[state_idx].head, list) {
-               if (r->gw == nh->nh_gw && r->oif == nh->nh_oif) {
-                       target_route = r;
-                       break;
-               }
-       }
-
-       if (!target_route) {
-               const size_t size_rt = sizeof(struct multipath_route);
-               target_route = (struct multipath_route *)
-                       kmalloc(size_rt, GFP_ATOMIC);
-
-               target_route->gw = nh->nh_gw;
-               target_route->oif = nh->nh_oif;
-               memset(&target_route->rcu, 0, sizeof(struct rcu_head));
-               INIT_LIST_HEAD(&target_route->dests);
-
-               list_add_rcu(&target_route->list, &state[state_idx].head);
-       }
-
-       /* find state entry for destination or add one if necessary */
-       list_for_each_entry_rcu(d, &target_route->dests, list) {
-               if (d->nh_info == nh) {
-                       target_dest = d;
-                       break;
-               }
-       }
-
-       if (!target_dest) {
-               const size_t size_dst = sizeof(struct multipath_dest);
-               target_dest = (struct multipath_dest*)
-                       kmalloc(size_dst, GFP_ATOMIC);
-
-               target_dest->nh_info = nh;
-               target_dest->network = network;
-               target_dest->netmask = netmask;
-               target_dest->prefixlen = prefixlen;
-               memset(&target_dest->rcu, 0, sizeof(struct rcu_head));
-
-               list_add_rcu(&target_dest->list, &target_route->dests);
-       }
-       /* else: we already stored this info for another destination =>
-        * we are finished
-        */
-
-       spin_unlock_bh(&state[state_idx].lock);
-}
-
-static void __multipath_free(struct rcu_head *head)
-{
-       struct multipath_route *rt = container_of(head, struct multipath_route,
-                                                 rcu);
-       kfree(rt);
-}
-
-static void __multipath_free_dst(struct rcu_head *head)
-{
-       struct multipath_dest *dst = container_of(head,
-                                                 struct multipath_dest,
-                                                 rcu);
-       kfree(dst);
-}
-
-static void wrandom_flush(void)
-{
-       int i;
-
-       /* defere delete to all entries */
-       for (i = 0; i < MULTIPATH_STATE_SIZE; ++i) {
-               struct multipath_route *r;
-
-               spin_lock_bh(&state[i].lock);
-               list_for_each_entry_rcu(r, &state[i].head, list) {
-                       struct multipath_dest *d;
-                       list_for_each_entry_rcu(d, &r->dests, list) {
-                               list_del_rcu(&d->list);
-                               call_rcu(&d->rcu,
-                                        __multipath_free_dst);
-                       }
-                       list_del_rcu(&r->list);
-                       call_rcu(&r->rcu,
-                                __multipath_free);
-               }
-
-               spin_unlock_bh(&state[i].lock);
-       }
-}
-
-static struct ip_mp_alg_ops wrandom_ops = {
-       .mp_alg_select_route    =       wrandom_select_route,
-       .mp_alg_flush           =       wrandom_flush,
-       .mp_alg_set_nhinfo      =       wrandom_set_nhinfo,
-};
-
-static int __init wrandom_init(void)
-{
-       wrandom_init_state();
-
-       return multipath_alg_register(&wrandom_ops, IP_MP_ALG_WRANDOM);
-}
-
-static void __exit wrandom_exit(void)
-{
-       multipath_alg_unregister(&wrandom_ops, IP_MP_ALG_WRANDOM);
-}
-
-module_init(wrandom_init);
-module_exit(wrandom_exit);
-MODULE_LICENSE("GPL");
index 46509fae9fd86750504efd465cda5b6da3042a5c..fa97947c6ae1024fd1a88ae25a29dc4566977766 100644 (file)
@@ -230,7 +230,7 @@ config IP_NF_TARGET_NETMAP
          To compile it as a module, choose M here.  If unsure, say N.
 
 config IP_NF_TARGET_SAME
-       tristate "SAME target support"
+       tristate "SAME target support (OBSOLETE)"
        depends on NF_NAT
        help
          This option adds a `SAME' target, which works like the standard SNAT
index cae41215e3c7efc663350260e5b8d567d0d13992..e981232942a18017cfbdf79ed2461f8bdc649191 100644 (file)
@@ -224,7 +224,7 @@ unsigned int arpt_do_table(struct sk_buff **pskb,
        static const char nulldevname[IFNAMSIZ];
        unsigned int verdict = NF_DROP;
        struct arphdr *arp;
-       int hotdrop = 0;
+       bool hotdrop = false;
        struct arpt_entry *e, *back;
        const char *indev, *outdev;
        void *table_base;
@@ -1140,13 +1140,13 @@ void arpt_unregister_table(struct arpt_table *table)
 }
 
 /* The built-in targets: standard (NULL) and error. */
-static struct arpt_target arpt_standard_target = {
+static struct arpt_target arpt_standard_target __read_mostly = {
        .name           = ARPT_STANDARD_TARGET,
        .targetsize     = sizeof(int),
        .family         = NF_ARP,
 };
 
-static struct arpt_target arpt_error_target = {
+static struct arpt_target arpt_error_target __read_mostly = {
        .name           = ARPT_ERROR_TARGET,
        .target         = arpt_error,
        .targetsize     = ARPT_FUNCTION_MAXNAMELEN,
index 6298d404e7c7950099d25c7ad1e71d0ababfa91e..c4bdab47597f071c35cb73f45570552777c8ad48 100644 (file)
@@ -65,7 +65,7 @@ target(struct sk_buff **pskb,
        return mangle->target;
 }
 
-static int
+static bool
 checkentry(const char *tablename, const void *e, const struct xt_target *target,
           void *targinfo, unsigned int hook_mask)
 {
@@ -73,15 +73,15 @@ checkentry(const char *tablename, const void *e, const struct xt_target *target,
 
        if (mangle->flags & ~ARPT_MANGLE_MASK ||
            !(mangle->flags & ARPT_MANGLE_MASK))
-               return 0;
+               return false;
 
        if (mangle->target != NF_DROP && mangle->target != NF_ACCEPT &&
           mangle->target != ARPT_CONTINUE)
-               return 0;
-       return 1;
+               return false;
+       return true;
 }
 
-static struct arpt_target arpt_mangle_reg = {
+static struct arpt_target arpt_mangle_reg __read_mostly = {
        .name           = "mangle",
        .target         = target,
        .targetsize     = sizeof(struct arpt_mangle),
index 9bacf1a0363085793544d85a1658f8ce91f2d8ba..e1b402c6b855a50072d127974e9002c518fa3872 100644 (file)
@@ -152,20 +152,20 @@ ip_packet_match(const struct iphdr *ip,
        return 1;
 }
 
-static inline int
+static inline bool
 ip_checkentry(const struct ipt_ip *ip)
 {
        if (ip->flags & ~IPT_F_MASK) {
                duprintf("Unknown flag bits set: %08X\n",
                         ip->flags & ~IPT_F_MASK);
-               return 0;
+               return false;
        }
        if (ip->invflags & ~IPT_INV_MASK) {
                duprintf("Unknown invflag bits set: %08X\n",
                         ip->invflags & ~IPT_INV_MASK);
-               return 0;
+               return false;
        }
-       return 1;
+       return true;
 }
 
 static unsigned int
@@ -183,19 +183,19 @@ ipt_error(struct sk_buff **pskb,
 }
 
 static inline
-int do_match(struct ipt_entry_match *m,
-            const struct sk_buff *skb,
-            const struct net_device *in,
-            const struct net_device *out,
-            int offset,
-            int *hotdrop)
+bool do_match(struct ipt_entry_match *m,
+             const struct sk_buff *skb,
+             const struct net_device *in,
+             const struct net_device *out,
+             int offset,
+             bool *hotdrop)
 {
        /* Stop iteration if it doesn't match */
        if (!m->u.kernel.match->match(skb, in, out, m->u.kernel.match, m->data,
                                      offset, ip_hdrlen(skb), hotdrop))
-               return 1;
+               return true;
        else
-               return 0;
+               return false;
 }
 
 static inline struct ipt_entry *
@@ -204,6 +204,112 @@ get_entry(void *base, unsigned int offset)
        return (struct ipt_entry *)(base + offset);
 }
 
+/* All zeroes == unconditional rule. */
+static inline int
+unconditional(const struct ipt_ip *ip)
+{
+       unsigned int i;
+
+       for (i = 0; i < sizeof(*ip)/sizeof(__u32); i++)
+               if (((__u32 *)ip)[i])
+                       return 0;
+
+       return 1;
+}
+
+#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
+    defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
+static const char *hooknames[] = {
+       [NF_IP_PRE_ROUTING]             = "PREROUTING",
+       [NF_IP_LOCAL_IN]                = "INPUT",
+       [NF_IP_FORWARD]                 = "FORWARD",
+       [NF_IP_LOCAL_OUT]               = "OUTPUT",
+       [NF_IP_POST_ROUTING]            = "POSTROUTING",
+};
+
+enum nf_ip_trace_comments {
+       NF_IP_TRACE_COMMENT_RULE,
+       NF_IP_TRACE_COMMENT_RETURN,
+       NF_IP_TRACE_COMMENT_POLICY,
+};
+
+static const char *comments[] = {
+       [NF_IP_TRACE_COMMENT_RULE]      = "rule",
+       [NF_IP_TRACE_COMMENT_RETURN]    = "return",
+       [NF_IP_TRACE_COMMENT_POLICY]    = "policy",
+};
+
+static struct nf_loginfo trace_loginfo = {
+       .type = NF_LOG_TYPE_LOG,
+       .u = {
+               .log = {
+                       .level = 4,
+                       .logflags = NF_LOG_MASK,
+               },
+       },
+};
+
+static inline int
+get_chainname_rulenum(struct ipt_entry *s, struct ipt_entry *e,
+                     char *hookname, char **chainname,
+                     char **comment, unsigned int *rulenum)
+{
+       struct ipt_standard_target *t = (void *)ipt_get_target(s);
+
+       if (strcmp(t->target.u.kernel.target->name, IPT_ERROR_TARGET) == 0) {
+               /* Head of user chain: ERROR target with chainname */
+               *chainname = t->target.data;
+               (*rulenum) = 0;
+       } else if (s == e) {
+               (*rulenum)++;
+
+               if (s->target_offset == sizeof(struct ipt_entry)
+                  && strcmp(t->target.u.kernel.target->name,
+                            IPT_STANDARD_TARGET) == 0
+                  && t->verdict < 0
+                  && unconditional(&s->ip)) {
+                       /* Tail of chains: STANDARD target (return/policy) */
+                       *comment = *chainname == hookname
+                               ? (char *)comments[NF_IP_TRACE_COMMENT_POLICY]
+                               : (char *)comments[NF_IP_TRACE_COMMENT_RETURN];
+               }
+               return 1;
+       } else
+               (*rulenum)++;
+
+       return 0;
+}
+
+static void trace_packet(struct sk_buff *skb,
+                        unsigned int hook,
+                        const struct net_device *in,
+                        const struct net_device *out,
+                        char *tablename,
+                        struct xt_table_info *private,
+                        struct ipt_entry *e)
+{
+       void *table_base;
+       struct ipt_entry *root;
+       char *hookname, *chainname, *comment;
+       unsigned int rulenum = 0;
+
+       table_base = (void *)private->entries[smp_processor_id()];
+       root = get_entry(table_base, private->hook_entry[hook]);
+
+       hookname = chainname = (char *)hooknames[hook];
+       comment = (char *)comments[NF_IP_TRACE_COMMENT_RULE];
+
+       IPT_ENTRY_ITERATE(root,
+                         private->size - private->hook_entry[hook],
+                         get_chainname_rulenum,
+                         e, hookname, &chainname, &comment, &rulenum);
+
+       nf_log_packet(AF_INET, hook, skb, in, out, &trace_loginfo,
+                     "TRACE: %s:%s:%s:%u ",
+                     tablename, chainname, comment, rulenum);
+}
+#endif
+
 /* Returns one of the generic firewall policies, like NF_ACCEPT. */
 unsigned int
 ipt_do_table(struct sk_buff **pskb,
@@ -216,7 +322,7 @@ ipt_do_table(struct sk_buff **pskb,
        u_int16_t offset;
        struct iphdr *ip;
        u_int16_t datalen;
-       int hotdrop = 0;
+       bool hotdrop = false;
        /* Initializing verdict to NF_DROP keeps gcc happy. */
        unsigned int verdict = NF_DROP;
        const char *indev, *outdev;
@@ -261,6 +367,14 @@ ipt_do_table(struct sk_buff **pskb,
 
                        t = ipt_get_target(e);
                        IP_NF_ASSERT(t->u.kernel.target);
+
+#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
+    defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
+                       /* The packet is traced: log it */
+                       if (unlikely((*pskb)->nf_trace))
+                               trace_packet(*pskb, hook, in, out,
+                                            table->name, private, e);
+#endif
                        /* Standard target? */
                        if (!t->u.kernel.target->target) {
                                int v;
@@ -341,19 +455,6 @@ ipt_do_table(struct sk_buff **pskb,
 #endif
 }
 
-/* All zeroes == unconditional rule. */
-static inline int
-unconditional(const struct ipt_ip *ip)
-{
-       unsigned int i;
-
-       for (i = 0; i < sizeof(*ip)/sizeof(__u32); i++)
-               if (((__u32 *)ip)[i])
-                       return 0;
-
-       return 1;
-}
-
 /* Figures out from what hook each rule can be called: returns 0 if
    there are loops.  Puts hook bitmask in comefrom. */
 static int
@@ -2105,16 +2206,16 @@ void ipt_unregister_table(struct xt_table *table)
 }
 
 /* Returns 1 if the type and code is matched by the range, 0 otherwise */
-static inline int
+static inline bool
 icmp_type_code_match(u_int8_t test_type, u_int8_t min_code, u_int8_t max_code,
                     u_int8_t type, u_int8_t code,
-                    int invert)
+                    bool invert)
 {
        return ((test_type == 0xFF) || (type == test_type && code >= min_code && code <= max_code))
                ^ invert;
 }
 
-static int
+static bool
 icmp_match(const struct sk_buff *skb,
           const struct net_device *in,
           const struct net_device *out,
@@ -2122,14 +2223,14 @@ icmp_match(const struct sk_buff *skb,
           const void *matchinfo,
           int offset,
           unsigned int protoff,
-          int *hotdrop)
+          bool *hotdrop)
 {
        struct icmphdr _icmph, *ic;
        const struct ipt_icmp *icmpinfo = matchinfo;
 
        /* Must not be a fragment. */
        if (offset)
-               return 0;
+               return false;
 
        ic = skb_header_pointer(skb, protoff, sizeof(_icmph), &_icmph);
        if (ic == NULL) {
@@ -2137,8 +2238,8 @@ icmp_match(const struct sk_buff *skb,
                 * can't.  Hence, no choice but to drop.
                 */
                duprintf("Dropping evil ICMP tinygram.\n");
-               *hotdrop = 1;
-               return 0;
+               *hotdrop = true;
+               return false;
        }
 
        return icmp_type_code_match(icmpinfo->type,
@@ -2149,7 +2250,7 @@ icmp_match(const struct sk_buff *skb,
 }
 
 /* Called when user tries to insert an entry of this type. */
-static int
+static bool
 icmp_checkentry(const char *tablename,
           const void *info,
           const struct xt_match *match,
@@ -2163,7 +2264,7 @@ icmp_checkentry(const char *tablename,
 }
 
 /* The built-in targets: standard (NULL) and error. */
-static struct xt_target ipt_standard_target = {
+static struct xt_target ipt_standard_target __read_mostly = {
        .name           = IPT_STANDARD_TARGET,
        .targetsize     = sizeof(int),
        .family         = AF_INET,
@@ -2174,7 +2275,7 @@ static struct xt_target ipt_standard_target = {
 #endif
 };
 
-static struct xt_target ipt_error_target = {
+static struct xt_target ipt_error_target __read_mostly = {
        .name           = IPT_ERROR_TARGET,
        .target         = ipt_error,
        .targetsize     = IPT_FUNCTION_MAXNAMELEN,
@@ -2197,7 +2298,7 @@ static struct nf_sockopt_ops ipt_sockopts = {
 #endif
 };
 
-static struct xt_match icmp_matchstruct = {
+static struct xt_match icmp_matchstruct __read_mostly = {
        .name           = "icmp",
        .match          = icmp_match,
        .matchsize      = sizeof(struct ipt_icmp),
@@ -2230,7 +2331,7 @@ static int __init ip_tables_init(void)
        if (ret < 0)
                goto err5;
 
-       printk("ip_tables: (C) 2000-2006 Netfilter Core Team\n");
+       printk(KERN_INFO "ip_tables: (C) 2000-2006 Netfilter Core Team\n");
        return 0;
 
 err5:
index 40e273421398c8d6f01f6311d0f583abc6f7fca5..dcc12b1834747a513a7468f780604b738124f0c2 100644 (file)
 
 #define CLUSTERIP_VERSION "0.8"
 
-#define DEBUG_CLUSTERIP
-
-#ifdef DEBUG_CLUSTERIP
-#define DEBUGP printk
-#else
-#define DEBUGP
-#endif
-
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
 MODULE_DESCRIPTION("iptables target for CLUSTERIP");
@@ -122,9 +114,8 @@ __clusterip_config_find(__be32 clusterip)
        list_for_each(pos, &clusterip_configs) {
                struct clusterip_config *c = list_entry(pos,
                                        struct clusterip_config, list);
-               if (c->clusterip == clusterip) {
+               if (c->clusterip == clusterip)
                        return c;
-               }
        }
 
        return NULL;
@@ -155,9 +146,8 @@ clusterip_config_init_nodelist(struct clusterip_config *c,
 {
        int n;
 
-       for (n = 0; n < i->num_local_nodes; n++) {
+       for (n = 0; n < i->num_local_nodes; n++)
                set_bit(i->local_nodes[n] - 1, &c->local_nodes);
-       }
 }
 
 static struct clusterip_config *
@@ -220,27 +210,28 @@ clusterip_add_node(struct clusterip_config *c, u_int16_t nodenum)
        return 0;
 }
 
-static int
+static bool
 clusterip_del_node(struct clusterip_config *c, u_int16_t nodenum)
 {
        if (nodenum == 0 ||
            nodenum > c->num_total_nodes)
-               return 1;
+               return true;
 
        if (test_and_clear_bit(nodenum - 1, &c->local_nodes))
-               return 0;
+               return false;
 
-       return 1;
+       return true;
 }
 #endif
 
 static inline u_int32_t
-clusterip_hashfn(struct sk_buff *skb, struct clusterip_config *config)
+clusterip_hashfn(const struct sk_buff *skb,
+                const struct clusterip_config *config)
 {
-       struct iphdr *iph = ip_hdr(skb);
+       const struct iphdr *iph = ip_hdr(skb);
        unsigned long hashval;
        u_int16_t sport, dport;
-       u_int16_t *ports;
+       const u_int16_t *ports;
 
        switch (iph->protocol) {
        case IPPROTO_TCP:
@@ -249,15 +240,14 @@ clusterip_hashfn(struct sk_buff *skb, struct clusterip_config *config)
        case IPPROTO_SCTP:
        case IPPROTO_DCCP:
        case IPPROTO_ICMP:
-               ports = (void *)iph+iph->ihl*4;
+               ports = (const void *)iph+iph->ihl*4;
                sport = ports[0];
                dport = ports[1];
                break;
        default:
-               if (net_ratelimit()) {
+               if (net_ratelimit())
                        printk(KERN_NOTICE "CLUSTERIP: unknown protocol `%u'\n",
                                iph->protocol);
-               }
                sport = dport = 0;
        }
 
@@ -285,11 +275,11 @@ clusterip_hashfn(struct sk_buff *skb, struct clusterip_config *config)
        }
 
        /* node numbers are 1..n, not 0..n */
-       return ((hashval % config->num_total_nodes)+1);
+       return (hashval % config->num_total_nodes) + 1;
 }
 
 static inline int
-clusterip_responsible(struct clusterip_config *config, u_int32_t hash)
+clusterip_responsible(const struct clusterip_config *config, u_int32_t hash)
 {
        return test_bit(hash - 1, &config->local_nodes);
 }
@@ -353,15 +343,15 @@ target(struct sk_buff **pskb,
                        break;
        }
 
-#ifdef DEBUG_CLUSTERP
+#ifdef DEBUG
        DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
 #endif
-       DEBUGP("hash=%u ct_hash=%u ", hash, ct->mark);
+       pr_debug("hash=%u ct_hash=%u ", hash, ct->mark);
        if (!clusterip_responsible(cipinfo->config, hash)) {
-               DEBUGP("not responsible\n");
+               pr_debug("not responsible\n");
                return NF_DROP;
        }
-       DEBUGP("responsible\n");
+       pr_debug("responsible\n");
 
        /* despite being received via linklayer multicast, this is
         * actually a unicast IP packet. TCP doesn't like PACKET_MULTICAST */
@@ -370,7 +360,7 @@ target(struct sk_buff **pskb,
        return XT_CONTINUE;
 }
 
-static int
+static bool
 checkentry(const char *tablename,
           const void *e_void,
           const struct xt_target *target,
@@ -387,50 +377,34 @@ checkentry(const char *tablename,
            cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP_SPT_DPT) {
                printk(KERN_WARNING "CLUSTERIP: unknown mode `%u'\n",
                        cipinfo->hash_mode);
-               return 0;
+               return false;
 
        }
        if (e->ip.dmsk.s_addr != htonl(0xffffffff)
            || e->ip.dst.s_addr == 0) {
                printk(KERN_ERR "CLUSTERIP: Please specify destination IP\n");
-               return 0;
+               return false;
        }
 
        /* FIXME: further sanity checks */
 
        config = clusterip_config_find_get(e->ip.dst.s_addr, 1);
-       if (config) {
-               if (cipinfo->config != NULL) {
-                       /* Case A: This is an entry that gets reloaded, since
-                        * it still has a cipinfo->config pointer. Simply
-                        * increase the entry refcount and return */
-                       if (cipinfo->config != config) {
-                               printk(KERN_ERR "CLUSTERIP: Reloaded entry "
-                                      "has invalid config pointer!\n");
-                               return 0;
-                       }
-               } else {
-                       /* Case B: This is a new rule referring to an existing
-                        * clusterip config. */
-                       cipinfo->config = config;
-               }
-       } else {
-               /* Case C: This is a completely new clusterip config */
+       if (!config) {
                if (!(cipinfo->flags & CLUSTERIP_FLAG_NEW)) {
                        printk(KERN_WARNING "CLUSTERIP: no config found for %u.%u.%u.%u, need 'new'\n", NIPQUAD(e->ip.dst.s_addr));
-                       return 0;
+                       return false;
                } else {
                        struct net_device *dev;
 
                        if (e->ip.iniface[0] == '\0') {
                                printk(KERN_WARNING "CLUSTERIP: Please specify an interface name\n");
-                               return 0;
+                               return false;
                        }
 
                        dev = dev_get_by_name(e->ip.iniface);
                        if (!dev) {
                                printk(KERN_WARNING "CLUSTERIP: no such interface %s\n", e->ip.iniface);
-                               return 0;
+                               return false;
                        }
 
                        config = clusterip_config_init(cipinfo,
@@ -438,20 +412,20 @@ checkentry(const char *tablename,
                        if (!config) {
                                printk(KERN_WARNING "CLUSTERIP: cannot allocate config\n");
                                dev_put(dev);
-                               return 0;
+                               return false;
                        }
                        dev_mc_add(config->dev,config->clustermac, ETH_ALEN, 0);
                }
-               cipinfo->config = config;
        }
+       cipinfo->config = config;
 
        if (nf_ct_l3proto_try_module_get(target->family) < 0) {
                printk(KERN_WARNING "can't load conntrack support for "
                                    "proto=%d\n", target->family);
-               return 0;
+               return false;
        }
 
-       return 1;
+       return true;
 }
 
 /* drop reference count of cluster config when rule is deleted */
@@ -468,13 +442,30 @@ static void destroy(const struct xt_target *target, void *targinfo)
        nf_ct_l3proto_module_put(target->family);
 }
 
-static struct xt_target clusterip_tgt = {
+#ifdef CONFIG_COMPAT
+struct compat_ipt_clusterip_tgt_info
+{
+       u_int32_t       flags;
+       u_int8_t        clustermac[6];
+       u_int16_t       num_total_nodes;
+       u_int16_t       num_local_nodes;
+       u_int16_t       local_nodes[CLUSTERIP_MAX_NODES];
+       u_int32_t       hash_mode;
+       u_int32_t       hash_initval;
+       compat_uptr_t   config;
+};
+#endif /* CONFIG_COMPAT */
+
+static struct xt_target clusterip_tgt __read_mostly = {
        .name           = "CLUSTERIP",
        .family         = AF_INET,
        .target         = target,
-       .targetsize     = sizeof(struct ipt_clusterip_tgt_info),
        .checkentry     = checkentry,
        .destroy        = destroy,
+       .targetsize     = sizeof(struct ipt_clusterip_tgt_info),
+#ifdef CONFIG_COMPAT
+       .compatsize     = sizeof(struct compat_ipt_clusterip_tgt_info),
+#endif /* CONFIG_COMPAT */
        .me             = THIS_MODULE
 };
 
@@ -491,7 +482,7 @@ struct arp_payload {
        __be32 dst_ip;
 } __attribute__ ((packed));
 
-#ifdef CLUSTERIP_DEBUG
+#ifdef DEBUG
 static void arp_print(struct arp_payload *payload)
 {
 #define HBUFFERLEN 30
@@ -547,8 +538,9 @@ arp_mangle(unsigned int hook,
         * this wouldn't work, since we didn't subscribe the mcast group on
         * other interfaces */
        if (c->dev != out) {
-               DEBUGP("CLUSTERIP: not mangling arp reply on different "
-                      "interface: cip'%s'-skb'%s'\n", c->dev->name, out->name);
+               pr_debug("CLUSTERIP: not mangling arp reply on different "
+                        "interface: cip'%s'-skb'%s'\n",
+                        c->dev->name, out->name);
                clusterip_config_put(c);
                return NF_ACCEPT;
        }
@@ -556,8 +548,8 @@ arp_mangle(unsigned int hook,
        /* mangle reply hardware address */
        memcpy(payload->src_hw, c->clustermac, arp->ar_hln);
 
-#ifdef CLUSTERIP_DEBUG
-       DEBUGP(KERN_DEBUG "CLUSTERIP mangled arp reply: ");
+#ifdef DEBUG
+       pr_debug(KERN_DEBUG "CLUSTERIP mangled arp reply: ");
        arp_print(payload);
 #endif
 
@@ -647,7 +639,7 @@ static int clusterip_seq_show(struct seq_file *s, void *v)
        return 0;
 }
 
-static struct seq_operations clusterip_seq_ops = {
+static const struct seq_operations clusterip_seq_ops = {
        .start  = clusterip_seq_start,
        .next   = clusterip_seq_next,
        .stop   = clusterip_seq_stop,
index 918ca92e534a2ef9ed7e1730c771f83829e9b1af..f1253bd3837f11d78c530351068dc514a3ecfcc1 100644 (file)
@@ -24,8 +24,8 @@ MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
 MODULE_DESCRIPTION("iptables ECN modification module");
 
 /* set ECT codepoint from IP header.
- *     return 0 if there was an error. */
-static inline int
+ *     return false if there was an error. */
+static inline bool
 set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
 {
        struct iphdr *iph = ip_hdr(*pskb);
@@ -33,18 +33,18 @@ set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
        if ((iph->tos & IPT_ECN_IP_MASK) != (einfo->ip_ect & IPT_ECN_IP_MASK)) {
                __u8 oldtos;
                if (!skb_make_writable(pskb, sizeof(struct iphdr)))
-                       return 0;
+                       return false;
                iph = ip_hdr(*pskb);
                oldtos = iph->tos;
                iph->tos &= ~IPT_ECN_IP_MASK;
                iph->tos |= (einfo->ip_ect & IPT_ECN_IP_MASK);
                nf_csum_replace2(&iph->check, htons(oldtos), htons(iph->tos));
        }
-       return 1;
+       return true;
 }
 
-/* Return 0 if there was an error. */
-static inline int
+/* Return false if there was an error. */
+static inline bool
 set_ect_tcp(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
 {
        struct tcphdr _tcph, *tcph;
@@ -54,16 +54,16 @@ set_ect_tcp(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
        tcph = skb_header_pointer(*pskb, ip_hdrlen(*pskb),
                                  sizeof(_tcph), &_tcph);
        if (!tcph)
-               return 0;
+               return false;
 
        if ((!(einfo->operation & IPT_ECN_OP_SET_ECE) ||
             tcph->ece == einfo->proto.tcp.ece) &&
-           ((!(einfo->operation & IPT_ECN_OP_SET_CWR) ||
-            tcph->cwr == einfo->proto.tcp.cwr)))
-               return 1;
+           (!(einfo->operation & IPT_ECN_OP_SET_CWR) ||
+            tcph->cwr == einfo->proto.tcp.cwr))
+               return true;
 
        if (!skb_make_writable(pskb, ip_hdrlen(*pskb) + sizeof(*tcph)))
-               return 0;
+               return false;
        tcph = (void *)ip_hdr(*pskb) + ip_hdrlen(*pskb);
 
        oldval = ((__be16 *)tcph)[6];
@@ -74,7 +74,7 @@ set_ect_tcp(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
 
        nf_proto_csum_replace2(&tcph->check, *pskb,
                                oldval, ((__be16 *)tcph)[6], 0);
-       return 1;
+       return true;
 }
 
 static unsigned int
@@ -99,7 +99,7 @@ target(struct sk_buff **pskb,
        return XT_CONTINUE;
 }
 
-static int
+static bool
 checkentry(const char *tablename,
           const void *e_void,
           const struct xt_target *target,
@@ -112,23 +112,23 @@ checkentry(const char *tablename,
        if (einfo->operation & IPT_ECN_OP_MASK) {
                printk(KERN_WARNING "ECN: unsupported ECN operation %x\n",
                        einfo->operation);
-               return 0;
+               return false;
        }
        if (einfo->ip_ect & ~IPT_ECN_IP_MASK) {
                printk(KERN_WARNING "ECN: new ECT codepoint %x out of mask\n",
                        einfo->ip_ect);
-               return 0;
+               return false;
        }
        if ((einfo->operation & (IPT_ECN_OP_SET_ECE|IPT_ECN_OP_SET_CWR))
            && (e->ip.proto != IPPROTO_TCP || (e->ip.invflags & XT_INV_PROTO))) {
                printk(KERN_WARNING "ECN: cannot use TCP operations on a "
                       "non-tcp rule\n");
-               return 0;
+               return false;
        }
-       return 1;
+       return true;
 }
 
-static struct xt_target ipt_ecn_reg = {
+static struct xt_target ipt_ecn_reg __read_mostly = {
        .name           = "ECN",
        .family         = AF_INET,
        .target         = target,
index a42c5cd968b10a19dad14c05a79cc768969e26f6..5937ad150b9f8a77b855857cb6c828c0b3e7c154 100644 (file)
@@ -27,12 +27,6 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
 MODULE_DESCRIPTION("iptables syslog logging module");
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 /* Use lock to serialize, so printks don't overlap */
 static DEFINE_SPINLOCK(log_lock);
 
@@ -41,7 +35,8 @@ static void dump_packet(const struct nf_loginfo *info,
                        const struct sk_buff *skb,
                        unsigned int iphoff)
 {
-       struct iphdr _iph, *ih;
+       struct iphdr _iph;
+       const struct iphdr *ih;
        unsigned int logflags;
 
        if (info->type == NF_LOG_TYPE_LOG)
@@ -100,7 +95,8 @@ static void dump_packet(const struct nf_loginfo *info,
 
        switch (ih->protocol) {
        case IPPROTO_TCP: {
-               struct tcphdr _tcph, *th;
+               struct tcphdr _tcph;
+               const struct tcphdr *th;
 
                /* Max length: 10 "PROTO=TCP " */
                printk("PROTO=TCP ");
@@ -151,7 +147,7 @@ static void dump_packet(const struct nf_loginfo *info,
                if ((logflags & IPT_LOG_TCPOPT)
                    && th->doff * 4 > sizeof(struct tcphdr)) {
                        unsigned char _opt[4 * 15 - sizeof(struct tcphdr)];
-                       unsigned char *op;
+                       const unsigned char *op;
                        unsigned int i, optsize;
 
                        optsize = th->doff * 4 - sizeof(struct tcphdr);
@@ -173,7 +169,8 @@ static void dump_packet(const struct nf_loginfo *info,
        }
        case IPPROTO_UDP:
        case IPPROTO_UDPLITE: {
-               struct udphdr _udph, *uh;
+               struct udphdr _udph;
+               const struct udphdr *uh;
 
                if (ih->protocol == IPPROTO_UDP)
                        /* Max length: 10 "PROTO=UDP "     */
@@ -200,7 +197,8 @@ static void dump_packet(const struct nf_loginfo *info,
                break;
        }
        case IPPROTO_ICMP: {
-               struct icmphdr _icmph, *ich;
+               struct icmphdr _icmph;
+               const struct icmphdr *ich;
                static const size_t required_len[NR_ICMP_TYPES+1]
                        = { [ICMP_ECHOREPLY] = 4,
                            [ICMP_DEST_UNREACH]
@@ -285,7 +283,8 @@ static void dump_packet(const struct nf_loginfo *info,
        }
        /* Max Length */
        case IPPROTO_AH: {
-               struct ip_auth_hdr _ahdr, *ah;
+               struct ip_auth_hdr _ahdr;
+               const struct ip_auth_hdr *ah;
 
                if (ntohs(ih->frag_off) & IP_OFFSET)
                        break;
@@ -307,7 +306,8 @@ static void dump_packet(const struct nf_loginfo *info,
                break;
        }
        case IPPROTO_ESP: {
-               struct ip_esp_hdr _esph, *eh;
+               struct ip_esp_hdr _esph;
+               const struct ip_esp_hdr *eh;
 
                /* Max length: 10 "PROTO=ESP " */
                printk("PROTO=ESP ");
@@ -385,11 +385,13 @@ ipt_log_packet(unsigned int pf,
               out ? out->name : "");
 #ifdef CONFIG_BRIDGE_NETFILTER
        if (skb->nf_bridge) {
-               struct net_device *physindev = skb->nf_bridge->physindev;
-               struct net_device *physoutdev = skb->nf_bridge->physoutdev;
+               const struct net_device *physindev;
+               const struct net_device *physoutdev;
 
+               physindev = skb->nf_bridge->physindev;
                if (physindev && in != physindev)
                        printk("PHYSIN=%s ", physindev->name);
+               physoutdev = skb->nf_bridge->physoutdev;
                if (physoutdev && out != physoutdev)
                        printk("PHYSOUT=%s ", physoutdev->name);
        }
@@ -435,27 +437,27 @@ ipt_log_target(struct sk_buff **pskb,
        return XT_CONTINUE;
 }
 
-static int ipt_log_checkentry(const char *tablename,
-                             const void *e,
-                             const struct xt_target *target,
-                             void *targinfo,
-                             unsigned int hook_mask)
+static bool ipt_log_checkentry(const char *tablename,
+                              const void *e,
+                              const struct xt_target *target,
+                              void *targinfo,
+                              unsigned int hook_mask)
 {
        const struct ipt_log_info *loginfo = targinfo;
 
        if (loginfo->level >= 8) {
-               DEBUGP("LOG: level %u >= 8\n", loginfo->level);
-               return 0;
+               pr_debug("LOG: level %u >= 8\n", loginfo->level);
+               return false;
        }
        if (loginfo->prefix[sizeof(loginfo->prefix)-1] != '\0') {
-               DEBUGP("LOG: prefix term %i\n",
-                      loginfo->prefix[sizeof(loginfo->prefix)-1]);
-               return 0;
+               pr_debug("LOG: prefix term %i\n",
+                        loginfo->prefix[sizeof(loginfo->prefix)-1]);
+               return false;
        }
-       return 1;
+       return true;
 }
 
-static struct xt_target ipt_log_reg = {
+static struct xt_target ipt_log_reg __read_mostly = {
        .name           = "LOG",
        .family         = AF_INET,
        .target         = ipt_log_target,
index d4f2d777533080e01dfa6f43de64588e349f1b32..7c4e4be7c8b3e40de45716346e8abf19022e8eb5 100644 (file)
@@ -27,17 +27,11 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
 MODULE_DESCRIPTION("iptables MASQUERADE target module");
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 /* Lock protects masq region inside conntrack */
 static DEFINE_RWLOCK(masq_lock);
 
 /* FIXME: Multiple targets. --RR */
-static int
+static bool
 masquerade_check(const char *tablename,
                 const void *e,
                 const struct xt_target *target,
@@ -47,14 +41,14 @@ masquerade_check(const char *tablename,
        const struct nf_nat_multi_range_compat *mr = targinfo;
 
        if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) {
-               DEBUGP("masquerade_check: bad MAP_IPS.\n");
-               return 0;
+               pr_debug("masquerade_check: bad MAP_IPS.\n");
+               return false;
        }
        if (mr->rangesize != 1) {
-               DEBUGP("masquerade_check: bad rangesize %u.\n", mr->rangesize);
-               return 0;
+               pr_debug("masquerade_check: bad rangesize %u\n", mr->rangesize);
+               return false;
        }
-       return 1;
+       return true;
 }
 
 static unsigned int
@@ -70,7 +64,7 @@ masquerade_target(struct sk_buff **pskb,
        enum ip_conntrack_info ctinfo;
        struct nf_nat_range newrange;
        const struct nf_nat_multi_range_compat *mr;
-       struct rtable *rt;
+       const struct rtable *rt;
        __be32 newsrc;
 
        NF_CT_ASSERT(hooknum == NF_IP_POST_ROUTING);
@@ -109,10 +103,10 @@ masquerade_target(struct sk_buff **pskb,
        return nf_nat_setup_info(ct, &newrange, hooknum);
 }
 
-static inline int
+static int
 device_cmp(struct nf_conn *i, void *ifindex)
 {
-       struct nf_conn_nat *nat = nfct_nat(i);
+       const struct nf_conn_nat *nat = nfct_nat(i);
        int ret;
 
        if (!nat)
@@ -129,7 +123,7 @@ static int masq_device_event(struct notifier_block *this,
                             unsigned long event,
                             void *ptr)
 {
-       struct net_device *dev = ptr;
+       const struct net_device *dev = ptr;
 
        if (event == NETDEV_DOWN) {
                /* Device was downed.  Search entire table for
@@ -147,7 +141,7 @@ static int masq_inet_event(struct notifier_block *this,
                           unsigned long event,
                           void *ptr)
 {
-       struct net_device *dev = ((struct in_ifaddr *)ptr)->ifa_dev->dev;
+       const struct net_device *dev = ((struct in_ifaddr *)ptr)->ifa_dev->dev;
 
        if (event == NETDEV_DOWN) {
                /* IP address was deleted.  Search entire table for
@@ -169,7 +163,7 @@ static struct notifier_block masq_inet_notifier = {
        .notifier_call  = masq_inet_event,
 };
 
-static struct xt_target masquerade = {
+static struct xt_target masquerade __read_mostly = {
        .name           = "MASQUERADE",
        .family         = AF_INET,
        .target         = masquerade_target,
index 068c69bce30ee6ff306051b3c2236f4d60a3a2ad..41a011d5a0655ae808be14343bfa9ce8a477f812 100644 (file)
 #include <linux/netfilter/x_tables.h>
 #include <net/netfilter/nf_nat_rule.h>
 
-#define MODULENAME "NETMAP"
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Svenning Soerensen <svenning@post5.tele.dk>");
 MODULE_DESCRIPTION("iptables 1:1 NAT mapping of IP networks target");
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
-static int
+static bool
 check(const char *tablename,
       const void *e,
       const struct xt_target *target,
@@ -39,14 +32,14 @@ check(const char *tablename,
        const struct nf_nat_multi_range_compat *mr = targinfo;
 
        if (!(mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)) {
-               DEBUGP(MODULENAME":check: bad MAP_IPS.\n");
-               return 0;
+               pr_debug("NETMAP:check: bad MAP_IPS.\n");
+               return false;
        }
        if (mr->rangesize != 1) {
-               DEBUGP(MODULENAME":check: bad rangesize %u.\n", mr->rangesize);
-               return 0;
+               pr_debug("NETMAP:check: bad rangesize %u.\n", mr->rangesize);
+               return false;
        }
-       return 1;
+       return true;
 }
 
 static unsigned int
@@ -85,8 +78,8 @@ target(struct sk_buff **pskb,
        return nf_nat_setup_info(ct, &newrange, hooknum);
 }
 
-static struct xt_target target_module = {
-       .name           = MODULENAME,
+static struct xt_target target_module __read_mostly = {
+       .name           = "NETMAP",
        .family         = AF_INET,
        .target         = target,
        .targetsize     = sizeof(struct nf_nat_multi_range_compat),
index 68cc76a198eb4ba630d98b8b2d34ce5393dba3dc..6ac7a23733169f1846f1c6eaba298ca4eb34d5dd 100644 (file)
@@ -25,14 +25,8 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
 MODULE_DESCRIPTION("iptables REDIRECT target module");
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 /* FIXME: Take multiple ranges --RR */
-static int
+static bool
 redirect_check(const char *tablename,
               const void *e,
               const struct xt_target *target,
@@ -42,14 +36,14 @@ redirect_check(const char *tablename,
        const struct nf_nat_multi_range_compat *mr = targinfo;
 
        if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) {
-               DEBUGP("redirect_check: bad MAP_IPS.\n");
-               return 0;
+               pr_debug("redirect_check: bad MAP_IPS.\n");
+               return false;
        }
        if (mr->rangesize != 1) {
-               DEBUGP("redirect_check: bad rangesize %u.\n", mr->rangesize);
-               return 0;
+               pr_debug("redirect_check: bad rangesize %u.\n", mr->rangesize);
+               return false;
        }
-       return 1;
+       return true;
 }
 
 static unsigned int
@@ -101,7 +95,7 @@ redirect_target(struct sk_buff **pskb,
        return nf_nat_setup_info(ct, &newrange, hooknum);
 }
 
-static struct xt_target redirect_reg = {
+static struct xt_target redirect_reg __read_mostly = {
        .name           = "REDIRECT",
        .family         = AF_INET,
        .target         = redirect_target,
index 9041e0741f6f9fb75df5506fa1b8e447b59baeb9..cb038c8fbc9d3dbda8b072b371d13aca88cee697 100644 (file)
@@ -31,12 +31,6 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
 MODULE_DESCRIPTION("iptables REJECT target module");
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 /* Send RST reply */
 static void send_reset(struct sk_buff *oldskb, int hook)
 {
@@ -122,7 +116,7 @@ static void send_reset(struct sk_buff *oldskb, int hook)
        tcph->check = 0;
        tcph->check = tcp_v4_check(sizeof(struct tcphdr),
                                   niph->saddr, niph->daddr,
-                                  csum_partial((char *)tcph,
+                                  csum_partial(tcph,
                                                sizeof(struct tcphdr), 0));
 
        /* Set DF, id = 0 */
@@ -217,30 +211,30 @@ static unsigned int reject(struct sk_buff **pskb,
        return NF_DROP;
 }
 
-static int check(const char *tablename,
-                const void *e_void,
-                const struct xt_target *target,
-                void *targinfo,
-                unsigned int hook_mask)
+static bool check(const char *tablename,
+                 const void *e_void,
+                 const struct xt_target *target,
+                 void *targinfo,
+                 unsigned int hook_mask)
 {
        const struct ipt_reject_info *rejinfo = targinfo;
        const struct ipt_entry *e = e_void;
 
        if (rejinfo->with == IPT_ICMP_ECHOREPLY) {
-               printk("REJECT: ECHOREPLY no longer supported.\n");
-               return 0;
+               printk("ipt_REJECT: ECHOREPLY no longer supported.\n");
+               return false;
        } else if (rejinfo->with == IPT_TCP_RESET) {
                /* Must specify that it's a TCP packet */
                if (e->ip.proto != IPPROTO_TCP
                    || (e->ip.invflags & XT_INV_PROTO)) {
-                       DEBUGP("REJECT: TCP_RESET invalid for non-tcp\n");
-                       return 0;
+                       printk("ipt_REJECT: TCP_RESET invalid for non-tcp\n");
+                       return false;
                }
        }
-       return 1;
+       return true;
 }
 
-static struct xt_target ipt_reject_reg = {
+static struct xt_target ipt_reject_reg __read_mostly = {
        .name           = "REJECT",
        .family         = AF_INET,
        .target         = reject,
index 511e5ff8493897c70b22c70f97fa5e62ded0a6f1..97641f1a97f6078f4482401bf5d3a7be30443c40 100644 (file)
@@ -27,13 +27,7 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Martin Josefsson <gandalf@wlug.westbo.se>");
 MODULE_DESCRIPTION("iptables special SNAT module for consistent sourceip");
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
-static int
+static bool
 same_check(const char *tablename,
              const void *e,
              const struct xt_target *target,
@@ -46,58 +40,56 @@ same_check(const char *tablename,
        mr->ipnum = 0;
 
        if (mr->rangesize < 1) {
-               DEBUGP("same_check: need at least one dest range.\n");
-               return 0;
+               pr_debug("same_check: need at least one dest range.\n");
+               return false;
        }
        if (mr->rangesize > IPT_SAME_MAX_RANGE) {
-               DEBUGP("same_check: too many ranges specified, maximum "
-                               "is %u ranges\n",
-                               IPT_SAME_MAX_RANGE);
-               return 0;
+               pr_debug("same_check: too many ranges specified, maximum "
+                        "is %u ranges\n", IPT_SAME_MAX_RANGE);
+               return false;
        }
        for (count = 0; count < mr->rangesize; count++) {
                if (ntohl(mr->range[count].min_ip) >
                                ntohl(mr->range[count].max_ip)) {
-                       DEBUGP("same_check: min_ip is larger than max_ip in "
-                               "range `%u.%u.%u.%u-%u.%u.%u.%u'.\n",
-                               NIPQUAD(mr->range[count].min_ip),
-                               NIPQUAD(mr->range[count].max_ip));
-                       return 0;
+                       pr_debug("same_check: min_ip is larger than max_ip in "
+                                "range `%u.%u.%u.%u-%u.%u.%u.%u'.\n",
+                                NIPQUAD(mr->range[count].min_ip),
+                                NIPQUAD(mr->range[count].max_ip));
+                       return false;
                }
                if (!(mr->range[count].flags & IP_NAT_RANGE_MAP_IPS)) {
-                       DEBUGP("same_check: bad MAP_IPS.\n");
-                       return 0;
+                       pr_debug("same_check: bad MAP_IPS.\n");
+                       return false;
                }
                rangeip = (ntohl(mr->range[count].max_ip) -
                                        ntohl(mr->range[count].min_ip) + 1);
                mr->ipnum += rangeip;
 
-               DEBUGP("same_check: range %u, ipnum = %u\n", count, rangeip);
+               pr_debug("same_check: range %u, ipnum = %u\n", count, rangeip);
        }
-       DEBUGP("same_check: total ipaddresses = %u\n", mr->ipnum);
+       pr_debug("same_check: total ipaddresses = %u\n", mr->ipnum);
 
        mr->iparray = kmalloc((sizeof(u_int32_t) * mr->ipnum), GFP_KERNEL);
        if (!mr->iparray) {
-               DEBUGP("same_check: Couldn't allocate %u bytes "
-                       "for %u ipaddresses!\n",
-                       (sizeof(u_int32_t) * mr->ipnum), mr->ipnum);
-               return 0;
+               pr_debug("same_check: Couldn't allocate %Zu bytes "
+                        "for %u ipaddresses!\n",
+                        (sizeof(u_int32_t) * mr->ipnum), mr->ipnum);
+               return false;
        }
-       DEBUGP("same_check: Allocated %u bytes for %u ipaddresses.\n",
-                       (sizeof(u_int32_t) * mr->ipnum), mr->ipnum);
+       pr_debug("same_check: Allocated %Zu bytes for %u ipaddresses.\n",
+                (sizeof(u_int32_t) * mr->ipnum), mr->ipnum);
 
        for (count = 0; count < mr->rangesize; count++) {
                for (countess = ntohl(mr->range[count].min_ip);
                                countess <= ntohl(mr->range[count].max_ip);
                                        countess++) {
                        mr->iparray[index] = countess;
-                       DEBUGP("same_check: Added ipaddress `%u.%u.%u.%u' "
-                               "in index %u.\n",
-                               HIPQUAD(countess), index);
+                       pr_debug("same_check: Added ipaddress `%u.%u.%u.%u' "
+                                "in index %u.\n", HIPQUAD(countess), index);
                        index++;
                }
        }
-       return 1;
+       return true;
 }
 
 static void
@@ -107,8 +99,8 @@ same_destroy(const struct xt_target *target, void *targinfo)
 
        kfree(mr->iparray);
 
-       DEBUGP("same_destroy: Deallocated %u bytes for %u ipaddresses.\n",
-                       (sizeof(u_int32_t) * mr->ipnum), mr->ipnum);
+       pr_debug("same_destroy: Deallocated %Zu bytes for %u ipaddresses.\n",
+                (sizeof(u_int32_t) * mr->ipnum), mr->ipnum);
 }
 
 static unsigned int
@@ -146,10 +138,9 @@ same_target(struct sk_buff **pskb,
 
        new_ip = htonl(same->iparray[aindex]);
 
-       DEBUGP("ipt_SAME: src=%u.%u.%u.%u dst=%u.%u.%u.%u, "
-                       "new src=%u.%u.%u.%u\n",
-                       NIPQUAD(t->src.ip), NIPQUAD(t->dst.ip),
-                       NIPQUAD(new_ip));
+       pr_debug("ipt_SAME: src=%u.%u.%u.%u dst=%u.%u.%u.%u, "
+                "new src=%u.%u.%u.%u\n",
+                NIPQUAD(t->src.u3.ip), NIPQUAD(t->dst.u3.ip), NIPQUAD(new_ip));
 
        /* Transfer from original range. */
        newrange = ((struct nf_nat_range)
@@ -161,7 +152,7 @@ same_target(struct sk_buff **pskb,
        return nf_nat_setup_info(ct, &newrange, hooknum);
 }
 
-static struct xt_target same_reg = {
+static struct xt_target same_reg __read_mostly = {
        .name           = "SAME",
        .family         = AF_INET,
        .target         = same_target,
index 0ad02f2498375d29be101ce2eda06af686a30a11..25f5d0b3906523b9a0e0fc2fd4f0758ce69fb95f 100644 (file)
@@ -43,7 +43,7 @@ target(struct sk_buff **pskb,
        return XT_CONTINUE;
 }
 
-static int
+static bool
 checkentry(const char *tablename,
           const void *e_void,
           const struct xt_target *target,
@@ -58,12 +58,12 @@ checkentry(const char *tablename,
            && tos != IPTOS_MINCOST
            && tos != IPTOS_NORMALSVC) {
                printk(KERN_WARNING "TOS: bad tos value %#x\n", tos);
-               return 0;
+               return false;
        }
-       return 1;
+       return true;
 }
 
-static struct xt_target ipt_tos_reg = {
+static struct xt_target ipt_tos_reg __read_mostly = {
        .name           = "TOS",
        .family         = AF_INET,
        .target         = target,
index a991ec7bd4e7207e9c7a15c937ca60fac1fa6a51..2b54e7b0cfe84f707b3ee2cbded965d5457b7d44 100644 (file)
@@ -62,25 +62,25 @@ ipt_ttl_target(struct sk_buff **pskb,
        return XT_CONTINUE;
 }
 
-static int ipt_ttl_checkentry(const char *tablename,
+static bool ipt_ttl_checkentry(const char *tablename,
                const void *e,
                const struct xt_target *target,
                void *targinfo,
                unsigned int hook_mask)
 {
-       struct ipt_TTL_info *info = targinfo;
+       const struct ipt_TTL_info *info = targinfo;
 
        if (info->mode > IPT_TTL_MAXMODE) {
                printk(KERN_WARNING "ipt_TTL: invalid or unknown Mode %u\n",
                        info->mode);
-               return 0;
+               return false;
        }
-       if ((info->mode != IPT_TTL_SET) && (info->ttl == 0))
-               return 0;
-       return 1;
+       if (info->mode != IPT_TTL_SET && info->ttl == 0)
+               return false;
+       return true;
 }
 
-static struct xt_target ipt_TTL = {
+static struct xt_target ipt_TTL __read_mostly = {
        .name           = "TTL",
        .family         = AF_INET,
        .target         = ipt_ttl_target,
index 23b607b33b32acdceddb9ae40541eee0406fa477..6ca43e4ca7e31e54c6c9d124ba02c77371ea28da 100644 (file)
@@ -55,13 +55,6 @@ MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_NFLOG);
 #define ULOG_NL_EVENT          111             /* Harald's favorite number */
 #define ULOG_MAXNLGROUPS       32              /* numer of nlgroups */
 
-#if 0
-#define DEBUGP(format, args...) printk("%s:%s:" format, \
-                                      __FILE__, __FUNCTION__ , ## args)
-#else
-#define DEBUGP(format, args...)
-#endif
-
 #define PRINTR(format, args...) do { if (net_ratelimit()) printk(format , ## args); } while (0)
 
 static unsigned int nlbufsiz = NLMSG_GOODSIZE;
@@ -96,12 +89,12 @@ static void ulog_send(unsigned int nlgroupnum)
        ulog_buff_t *ub = &ulog_buffers[nlgroupnum];
 
        if (timer_pending(&ub->timer)) {
-               DEBUGP("ipt_ULOG: ulog_send: timer was pending, deleting\n");
+               pr_debug("ipt_ULOG: ulog_send: timer was pending, deleting\n");
                del_timer(&ub->timer);
        }
 
        if (!ub->skb) {
-               DEBUGP("ipt_ULOG: ulog_send: nothing to send\n");
+               pr_debug("ipt_ULOG: ulog_send: nothing to send\n");
                return;
        }
 
@@ -110,8 +103,8 @@ static void ulog_send(unsigned int nlgroupnum)
                ub->lastnlh->nlmsg_type = NLMSG_DONE;
 
        NETLINK_CB(ub->skb).dst_group = nlgroupnum + 1;
-       DEBUGP("ipt_ULOG: throwing %d packets to netlink group %u\n",
-               ub->qlen, nlgroupnum + 1);
+       pr_debug("ipt_ULOG: throwing %d packets to netlink group %u\n",
+                ub->qlen, nlgroupnum + 1);
        netlink_broadcast(nflognl, ub->skb, 0, nlgroupnum + 1, GFP_ATOMIC);
 
        ub->qlen = 0;
@@ -123,7 +116,7 @@ static void ulog_send(unsigned int nlgroupnum)
 /* timer function to flush queue in flushtimeout time */
 static void ulog_timer(unsigned long data)
 {
-       DEBUGP("ipt_ULOG: timer function called, calling ulog_send\n");
+       pr_debug("ipt_ULOG: timer function called, calling ulog_send\n");
 
        /* lock to protect against somebody modifying our structure
         * from ipt_ulog_target at the same time */
@@ -179,12 +172,10 @@ static void ipt_ulog_packet(unsigned int hooknum,
        unsigned int groupnum = ffs(loginfo->nl_group) - 1;
 
        /* calculate the size of the skb needed */
-       if ((loginfo->copy_range == 0) ||
-           (loginfo->copy_range > skb->len)) {
+       if (loginfo->copy_range == 0 || loginfo->copy_range > skb->len)
                copy_len = skb->len;
-       } else {
+       else
                copy_len = loginfo->copy_range;
-       }
 
        size = NLMSG_SPACE(sizeof(*pm) + copy_len);
 
@@ -206,8 +197,8 @@ static void ipt_ulog_packet(unsigned int hooknum,
                        goto alloc_failure;
        }
 
-       DEBUGP("ipt_ULOG: qlen %d, qthreshold %d\n", ub->qlen,
-               loginfo->qthreshold);
+       pr_debug("ipt_ULOG: qlen %d, qthreshold %Zu\n", ub->qlen,
+                loginfo->qthreshold);
 
        /* NLMSG_PUT contains a hidden goto nlmsg_failure !!! */
        nlh = NLMSG_PUT(ub->skb, 0, ub->qlen, ULOG_NL_EVENT,
@@ -257,9 +248,8 @@ static void ipt_ulog_packet(unsigned int hooknum,
                BUG();
 
        /* check if we are building multi-part messages */
-       if (ub->qlen > 1) {
+       if (ub->qlen > 1)
                ub->lastnlh->nlmsg_flags |= NLM_F_MULTI;
-       }
 
        ub->lastnlh = nlh;
 
@@ -328,25 +318,25 @@ static void ipt_logfn(unsigned int pf,
        ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
 }
 
-static int ipt_ulog_checkentry(const char *tablename,
-                              const void *e,
-                              const struct xt_target *target,
-                              void *targinfo,
-                              unsigned int hookmask)
+static bool ipt_ulog_checkentry(const char *tablename,
+                               const void *e,
+                               const struct xt_target *target,
+                               void *targinfo,
+                               unsigned int hookmask)
 {
-       struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo;
+       const struct ipt_ulog_info *loginfo = targinfo;
 
        if (loginfo->prefix[sizeof(loginfo->prefix) - 1] != '\0') {
-               DEBUGP("ipt_ULOG: prefix term %i\n",
-                      loginfo->prefix[sizeof(loginfo->prefix) - 1]);
-               return 0;
+               pr_debug("ipt_ULOG: prefix term %i\n",
+                        loginfo->prefix[sizeof(loginfo->prefix) - 1]);
+               return false;
        }
        if (loginfo->qthreshold > ULOG_MAX_QLEN) {
-               DEBUGP("ipt_ULOG: queue threshold %i > MAX_QLEN\n",
-                       loginfo->qthreshold);
-               return 0;
+               pr_debug("ipt_ULOG: queue threshold %Zu > MAX_QLEN\n",
+                        loginfo->qthreshold);
+               return false;
        }
-       return 1;
+       return true;
 }
 
 #ifdef CONFIG_COMPAT
@@ -359,7 +349,7 @@ struct compat_ipt_ulog_info {
 
 static void compat_from_user(void *dst, void *src)
 {
-       struct compat_ipt_ulog_info *cl = src;
+       const struct compat_ipt_ulog_info *cl = src;
        struct ipt_ulog_info l = {
                .nl_group       = cl->nl_group,
                .copy_range     = cl->copy_range,
@@ -372,7 +362,7 @@ static void compat_from_user(void *dst, void *src)
 
 static int compat_to_user(void __user *dst, void *src)
 {
-       struct ipt_ulog_info *l = src;
+       const struct ipt_ulog_info *l = src;
        struct compat_ipt_ulog_info cl = {
                .nl_group       = l->nl_group,
                .copy_range     = l->copy_range,
@@ -384,7 +374,7 @@ static int compat_to_user(void __user *dst, void *src)
 }
 #endif /* CONFIG_COMPAT */
 
-static struct xt_target ipt_ulog_reg = {
+static struct xt_target ipt_ulog_reg __read_mostly = {
        .name           = "ULOG",
        .family         = AF_INET,
        .target         = ipt_ulog_target,
@@ -408,7 +398,7 @@ static int __init ipt_ulog_init(void)
 {
        int ret, i;
 
-       DEBUGP("ipt_ULOG: init module\n");
+       pr_debug("ipt_ULOG: init module\n");
 
        if (nlbufsiz > 128*1024) {
                printk("Netlink buffer has to be <= 128kB\n");
@@ -440,7 +430,7 @@ static void __exit ipt_ulog_fini(void)
        ulog_buff_t *ub;
        int i;
 
-       DEBUGP("ipt_ULOG: cleanup_module\n");
+       pr_debug("ipt_ULOG: cleanup_module\n");
 
        if (nflog)
                nf_log_unregister(&ipt_ulog_logger);
@@ -451,7 +441,7 @@ static void __exit ipt_ulog_fini(void)
        for (i = 0; i < ULOG_MAXNLGROUPS; i++) {
                ub = &ulog_buffers[i];
                if (timer_pending(&ub->timer)) {
-                       DEBUGP("timer was pending, deleting\n");
+                       pr_debug("timer was pending, deleting\n");
                        del_timer(&ub->timer);
                }
 
index a652a14515526f651a5bc8d67176ed20bfb254f7..59f01f7ba6b47c20653674d5693b142421d51e0a 100644 (file)
@@ -22,19 +22,19 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
 MODULE_DESCRIPTION("iptables addrtype match");
 
-static inline int match_type(__be32 addr, u_int16_t mask)
+static inline bool match_type(__be32 addr, u_int16_t mask)
 {
        return !!(mask & (1 << inet_addr_type(addr)));
 }
 
-static int match(const struct sk_buff *skb,
-                const struct net_device *in, const struct net_device *out,
-                const struct xt_match *match, const void *matchinfo,
-                int offset, unsigned int protoff, int *hotdrop)
+static bool match(const struct sk_buff *skb,
+                 const struct net_device *in, const struct net_device *out,
+                 const struct xt_match *match, const void *matchinfo,
+                 int offset, unsigned int protoff, bool *hotdrop)
 {
        const struct ipt_addrtype_info *info = matchinfo;
        const struct iphdr *iph = ip_hdr(skb);
-       int ret = 1;
+       bool ret = true;
 
        if (info->source)
                ret &= match_type(iph->saddr, info->source)^info->invert_source;
@@ -44,7 +44,7 @@ static int match(const struct sk_buff *skb,
        return ret;
 }
 
-static struct xt_match addrtype_match = {
+static struct xt_match addrtype_match __read_mostly = {
        .name           = "addrtype",
        .family         = AF_INET,
        .match          = match,
index 18a16782cf405f1cc6f49fa07a4fa541135d43c0..61b017fd743c14987fea3038b1781bfb2ee7634d 100644 (file)
@@ -25,10 +25,10 @@ MODULE_DESCRIPTION("iptables AH SPI match module");
 #endif
 
 /* Returns 1 if the spi is matched by the range, 0 otherwise */
-static inline int
-spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, int invert)
+static inline bool
+spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert)
 {
-       int r=0;
+       bool r;
        duprintf("ah spi_match:%c 0x%x <= 0x%x <= 0x%x",invert? '!':' ',
                min,spi,max);
        r=(spi >= min && spi <= max) ^ invert;
@@ -36,7 +36,7 @@ spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, int invert)
        return r;
 }
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -44,14 +44,15 @@ match(const struct sk_buff *skb,
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
-       struct ip_auth_hdr _ahdr, *ah;
+       struct ip_auth_hdr _ahdr;
+       const struct ip_auth_hdr *ah;
        const struct ipt_ah *ahinfo = matchinfo;
 
        /* Must not be a fragment. */
        if (offset)
-               return 0;
+               return false;
 
        ah = skb_header_pointer(skb, protoff,
                                sizeof(_ahdr), &_ahdr);
@@ -60,7 +61,7 @@ match(const struct sk_buff *skb,
                 * can't.  Hence, no choice but to drop.
                 */
                duprintf("Dropping evil AH tinygram.\n");
-               *hotdrop = 1;
+               *hotdrop = true;
                return 0;
        }
 
@@ -70,7 +71,7 @@ match(const struct sk_buff *skb,
 }
 
 /* Called when user tries to insert an entry of this type. */
-static int
+static bool
 checkentry(const char *tablename,
           const void *ip_void,
           const struct xt_match *match,
@@ -82,12 +83,12 @@ checkentry(const char *tablename,
        /* Must specify no unknown invflags */
        if (ahinfo->invflags & ~IPT_AH_INV_MASK) {
                duprintf("ipt_ah: unknown flags %X\n", ahinfo->invflags);
-               return 0;
+               return false;
        }
-       return 1;
+       return true;
 }
 
-static struct xt_match ah_match = {
+static struct xt_match ah_match __read_mostly = {
        .name           = "ah",
        .family         = AF_INET,
        .match          = match,
index 26218122f865c05ed5b0227e5b4632bb8c61a4b3..d6925c6740692a730c64fc6313bc788fd8a72e45 100644 (file)
@@ -22,95 +22,96 @@ MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
 MODULE_DESCRIPTION("iptables ECN matching module");
 MODULE_LICENSE("GPL");
 
-static inline int match_ip(const struct sk_buff *skb,
-                          const struct ipt_ecn_info *einfo)
+static inline bool match_ip(const struct sk_buff *skb,
+                           const struct ipt_ecn_info *einfo)
 {
        return (ip_hdr(skb)->tos & IPT_ECN_IP_MASK) == einfo->ip_ect;
 }
 
-static inline int match_tcp(const struct sk_buff *skb,
-                           const struct ipt_ecn_info *einfo,
-                           int *hotdrop)
+static inline bool match_tcp(const struct sk_buff *skb,
+                            const struct ipt_ecn_info *einfo,
+                            bool *hotdrop)
 {
-       struct tcphdr _tcph, *th;
+       struct tcphdr _tcph;
+       const struct tcphdr *th;
 
        /* In practice, TCP match does this, so can't fail.  But let's
         * be good citizens.
         */
        th = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_tcph), &_tcph);
        if (th == NULL) {
-               *hotdrop = 0;
-               return 0;
+               *hotdrop = false;
+               return false;
        }
 
        if (einfo->operation & IPT_ECN_OP_MATCH_ECE) {
                if (einfo->invert & IPT_ECN_OP_MATCH_ECE) {
                        if (th->ece == 1)
-                               return 0;
+                               return false;
                } else {
                        if (th->ece == 0)
-                               return 0;
+                               return false;
                }
        }
 
        if (einfo->operation & IPT_ECN_OP_MATCH_CWR) {
                if (einfo->invert & IPT_ECN_OP_MATCH_CWR) {
                        if (th->cwr == 1)
-                               return 0;
+                               return false;
                } else {
                        if (th->cwr == 0)
-                               return 0;
+                               return false;
                }
        }
 
-       return 1;
+       return true;
 }
 
-static int match(const struct sk_buff *skb,
-                const struct net_device *in, const struct net_device *out,
-                const struct xt_match *match, const void *matchinfo,
-                int offset, unsigned int protoff, int *hotdrop)
+static bool match(const struct sk_buff *skb,
+                 const struct net_device *in, const struct net_device *out,
+                 const struct xt_match *match, const void *matchinfo,
+                 int offset, unsigned int protoff, bool *hotdrop)
 {
        const struct ipt_ecn_info *info = matchinfo;
 
        if (info->operation & IPT_ECN_OP_MATCH_IP)
                if (!match_ip(skb, info))
-                       return 0;
+                       return false;
 
        if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR)) {
                if (ip_hdr(skb)->protocol != IPPROTO_TCP)
-                       return 0;
+                       return false;
                if (!match_tcp(skb, info, hotdrop))
-                       return 0;
+                       return false;
        }
 
-       return 1;
+       return true;
 }
 
-static int checkentry(const char *tablename, const void *ip_void,
-                     const struct xt_match *match,
-                     void *matchinfo, unsigned int hook_mask)
+static bool checkentry(const char *tablename, const void *ip_void,
+                      const struct xt_match *match,
+                      void *matchinfo, unsigned int hook_mask)
 {
        const struct ipt_ecn_info *info = matchinfo;
        const struct ipt_ip *ip = ip_void;
 
        if (info->operation & IPT_ECN_OP_MATCH_MASK)
-               return 0;
+               return false;
 
        if (info->invert & IPT_ECN_OP_MATCH_MASK)
-               return 0;
+               return false;
 
        if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR)
            && ip->proto != IPPROTO_TCP) {
                printk(KERN_WARNING "ipt_ecn: can't match TCP bits in rule for"
                       " non-tcp packets\n");
-               return 0;
+               return false;
        }
 
-       return 1;
+       return true;
 }
 
-static struct xt_match ecn_match = {
+static struct xt_match ecn_match __read_mostly = {
        .name           = "ecn",
        .family         = AF_INET,
        .match          = match,
index 33af9e9408875d1aa4d237e9db73a92a5d185bd9..0106dc955a69900ba8593bb9b8ee517c71562983 100644 (file)
@@ -17,53 +17,47 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
 MODULE_DESCRIPTION("iptables arbitrary IP range match module");
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
       const struct xt_match *match,
       const void *matchinfo,
-      int offset, unsigned int protoff, int *hotdrop)
+      int offset, unsigned int protoff, bool *hotdrop)
 {
        const struct ipt_iprange_info *info = matchinfo;
        const struct iphdr *iph = ip_hdr(skb);
 
        if (info->flags & IPRANGE_SRC) {
-               if (((ntohl(iph->saddr) < ntohl(info->src.min_ip))
-                         || (ntohl(iph->saddr) > ntohl(info->src.max_ip)))
+               if ((ntohl(iph->saddr) < ntohl(info->src.min_ip)
+                         || ntohl(iph->saddr) > ntohl(info->src.max_ip))
                         ^ !!(info->flags & IPRANGE_SRC_INV)) {
-                       DEBUGP("src IP %u.%u.%u.%u NOT in range %s"
-                              "%u.%u.%u.%u-%u.%u.%u.%u\n",
-                               NIPQUAD(iph->saddr),
-                               info->flags & IPRANGE_SRC_INV ? "(INV) " : "",
-                               NIPQUAD(info->src.min_ip),
-                               NIPQUAD(info->src.max_ip));
-                       return 0;
+                       pr_debug("src IP %u.%u.%u.%u NOT in range %s"
+                                "%u.%u.%u.%u-%u.%u.%u.%u\n",
+                                NIPQUAD(iph->saddr),
+                                info->flags & IPRANGE_SRC_INV ? "(INV) " : "",
+                                NIPQUAD(info->src.min_ip),
+                                NIPQUAD(info->src.max_ip));
+                       return false;
                }
        }
        if (info->flags & IPRANGE_DST) {
-               if (((ntohl(iph->daddr) < ntohl(info->dst.min_ip))
-                         || (ntohl(iph->daddr) > ntohl(info->dst.max_ip)))
+               if ((ntohl(iph->daddr) < ntohl(info->dst.min_ip)
+                         || ntohl(iph->daddr) > ntohl(info->dst.max_ip))
                         ^ !!(info->flags & IPRANGE_DST_INV)) {
-                       DEBUGP("dst IP %u.%u.%u.%u NOT in range %s"
-                              "%u.%u.%u.%u-%u.%u.%u.%u\n",
-                               NIPQUAD(iph->daddr),
-                               info->flags & IPRANGE_DST_INV ? "(INV) " : "",
-                               NIPQUAD(info->dst.min_ip),
-                               NIPQUAD(info->dst.max_ip));
-                       return 0;
+                       pr_debug("dst IP %u.%u.%u.%u NOT in range %s"
+                                "%u.%u.%u.%u-%u.%u.%u.%u\n",
+                                NIPQUAD(iph->daddr),
+                                info->flags & IPRANGE_DST_INV ? "(INV) " : "",
+                                NIPQUAD(info->dst.min_ip),
+                                NIPQUAD(info->dst.max_ip));
+                       return false;
                }
        }
-       return 1;
+       return true;
 }
 
-static struct xt_match iprange_match = {
+static struct xt_match iprange_match __read_mostly = {
        .name           = "iprange",
        .family         = AF_INET,
        .match          = match,
index 7fae9aa8944c6bb4b07797015d9fd0df315aa754..b14e77da7a336de78c9db7991e2b5d40bd173888 100644 (file)
@@ -21,7 +21,7 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
 MODULE_DESCRIPTION("iptables owner match");
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -29,29 +29,29 @@ match(const struct sk_buff *skb,
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
        const struct ipt_owner_info *info = matchinfo;
 
        if (!skb->sk || !skb->sk->sk_socket || !skb->sk->sk_socket->file)
-               return 0;
+               return false;
 
        if(info->match & IPT_OWNER_UID) {
                if ((skb->sk->sk_socket->file->f_uid != info->uid) ^
                    !!(info->invert & IPT_OWNER_UID))
-                       return 0;
+                       return false;
        }
 
        if(info->match & IPT_OWNER_GID) {
                if ((skb->sk->sk_socket->file->f_gid != info->gid) ^
                    !!(info->invert & IPT_OWNER_GID))
-                       return 0;
+                       return false;
        }
 
-       return 1;
+       return true;
 }
 
-static int
+static bool
 checkentry(const char *tablename,
           const void *ip,
           const struct xt_match *match,
@@ -63,12 +63,12 @@ checkentry(const char *tablename,
        if (info->match & (IPT_OWNER_PID|IPT_OWNER_SID|IPT_OWNER_COMM)) {
                printk("ipt_owner: pid, sid and command matching "
                       "not supported anymore\n");
-               return 0;
+               return false;
        }
-       return 1;
+       return true;
 }
 
-static struct xt_match owner_match = {
+static struct xt_match owner_match __read_mostly = {
        .name           = "owner",
        .family         = AF_INET,
        .match          = match,
index 15a9e8bbb7cc65d35ba6c85bebd5658bfbd791fc..3218043156591f874e59deff90f8b5fa7a027d8c 100644 (file)
@@ -163,24 +163,23 @@ static void recent_table_flush(struct recent_table *t)
        struct recent_entry *e, *next;
        unsigned int i;
 
-       for (i = 0; i < ip_list_hash_size; i++) {
+       for (i = 0; i < ip_list_hash_size; i++)
                list_for_each_entry_safe(e, next, &t->iphash[i], list)
                        recent_entry_remove(t, e);
-       }
 }
 
-static int
+static bool
 ipt_recent_match(const struct sk_buff *skb,
                 const struct net_device *in, const struct net_device *out,
                 const struct xt_match *match, const void *matchinfo,
-                int offset, unsigned int protoff, int *hotdrop)
+                int offset, unsigned int protoff, bool *hotdrop)
 {
        const struct ipt_recent_info *info = matchinfo;
        struct recent_table *t;
        struct recent_entry *e;
        __be32 addr;
        u_int8_t ttl;
-       int ret = info->invert;
+       bool ret = info->invert;
 
        if (info->side == IPT_RECENT_DEST)
                addr = ip_hdr(skb)->daddr;
@@ -201,16 +200,16 @@ ipt_recent_match(const struct sk_buff *skb,
                        goto out;
                e = recent_entry_init(t, addr, ttl);
                if (e == NULL)
-                       *hotdrop = 1;
-               ret ^= 1;
+                       *hotdrop = true;
+               ret = !ret;
                goto out;
        }
 
        if (info->check_set & IPT_RECENT_SET)
-               ret ^= 1;
+               ret = !ret;
        else if (info->check_set & IPT_RECENT_REMOVE) {
                recent_entry_remove(t, e);
-               ret ^= 1;
+               ret = !ret;
        } else if (info->check_set & (IPT_RECENT_CHECK | IPT_RECENT_UPDATE)) {
                unsigned long t = jiffies - info->seconds * HZ;
                unsigned int i, hits = 0;
@@ -219,7 +218,7 @@ ipt_recent_match(const struct sk_buff *skb,
                        if (info->seconds && time_after(t, e->stamps[i]))
                                continue;
                        if (++hits >= info->hit_count) {
-                               ret ^= 1;
+                               ret = !ret;
                                break;
                        }
                }
@@ -235,7 +234,7 @@ out:
        return ret;
 }
 
-static int
+static bool
 ipt_recent_checkentry(const char *tablename, const void *ip,
                      const struct xt_match *match, void *matchinfo,
                      unsigned int hook_mask)
@@ -243,24 +242,24 @@ ipt_recent_checkentry(const char *tablename, const void *ip,
        const struct ipt_recent_info *info = matchinfo;
        struct recent_table *t;
        unsigned i;
-       int ret = 0;
+       bool ret = false;
 
        if (hweight8(info->check_set &
                     (IPT_RECENT_SET | IPT_RECENT_REMOVE |
                      IPT_RECENT_CHECK | IPT_RECENT_UPDATE)) != 1)
-               return 0;
+               return false;
        if ((info->check_set & (IPT_RECENT_SET | IPT_RECENT_REMOVE)) &&
            (info->seconds || info->hit_count))
-               return 0;
+               return false;
        if (info->name[0] == '\0' ||
            strnlen(info->name, IPT_RECENT_NAME_LEN) == IPT_RECENT_NAME_LEN)
-               return 0;
+               return false;
 
        mutex_lock(&recent_mutex);
        t = recent_table_lookup(info->name);
        if (t != NULL) {
                t->refcnt++;
-               ret = 1;
+               ret = true;
                goto out;
        }
 
@@ -287,7 +286,7 @@ ipt_recent_checkentry(const char *tablename, const void *ip,
        spin_lock_bh(&recent_lock);
        list_add_tail(&t->list, &tables);
        spin_unlock_bh(&recent_lock);
-       ret = 1;
+       ret = true;
 out:
        mutex_unlock(&recent_mutex);
        return ret;
@@ -323,18 +322,16 @@ struct recent_iter_state {
 static void *recent_seq_start(struct seq_file *seq, loff_t *pos)
 {
        struct recent_iter_state *st = seq->private;
-       struct recent_table *t = st->table;
+       const struct recent_table *t = st->table;
        struct recent_entry *e;
        loff_t p = *pos;
 
        spin_lock_bh(&recent_lock);
 
-       for (st->bucket = 0; st->bucket < ip_list_hash_size; st->bucket++) {
-               list_for_each_entry(e, &t->iphash[st->bucket], list) {
+       for (st->bucket = 0; st->bucket < ip_list_hash_size; st->bucket++)
+               list_for_each_entry(e, &t->iphash[st->bucket], list)
                        if (p-- == 0)
                                return e;
-               }
-       }
        return NULL;
 }
 
@@ -373,7 +370,7 @@ static int recent_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations recent_seq_ops = {
+static const struct seq_operations recent_seq_ops = {
        .start          = recent_seq_start,
        .next           = recent_seq_next,
        .stop           = recent_seq_stop,
@@ -463,7 +460,7 @@ static const struct file_operations recent_fops = {
 };
 #endif /* CONFIG_PROC_FS */
 
-static struct xt_match recent_match = {
+static struct xt_match recent_match __read_mostly = {
        .name           = "recent",
        .family         = AF_INET,
        .match          = ipt_recent_match,
index d314844af12b080991e082a108d83be27d426a41..e740441c973d17c1f684913a6cdba93c223886b3 100644 (file)
@@ -18,7 +18,7 @@
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("iptables TOS match module");
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -26,14 +26,14 @@ match(const struct sk_buff *skb,
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
        const struct ipt_tos_info *info = matchinfo;
 
        return (ip_hdr(skb)->tos == info->tos) ^ info->invert;
 }
 
-static struct xt_match tos_match = {
+static struct xt_match tos_match __read_mostly = {
        .name           = "tos",
        .family         = AF_INET,
        .match          = match,
index ab02d9e3139c1660848e05d8bfcb00221dde5229..a439900a4ba5caa5066946aea2fff7350fde60f0 100644 (file)
@@ -18,37 +18,33 @@ MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
 MODULE_DESCRIPTION("IP tables TTL matching module");
 MODULE_LICENSE("GPL");
 
-static int match(const struct sk_buff *skb,
-                const struct net_device *in, const struct net_device *out,
-                const struct xt_match *match, const void *matchinfo,
-                int offset, unsigned int protoff, int *hotdrop)
+static bool match(const struct sk_buff *skb,
+                 const struct net_device *in, const struct net_device *out,
+                 const struct xt_match *match, const void *matchinfo,
+                 int offset, unsigned int protoff, bool *hotdrop)
 {
        const struct ipt_ttl_info *info = matchinfo;
        const u8 ttl = ip_hdr(skb)->ttl;
 
        switch (info->mode) {
                case IPT_TTL_EQ:
-                       return (ttl == info->ttl);
-                       break;
+                       return ttl == info->ttl;
                case IPT_TTL_NE:
-                       return (!(ttl == info->ttl));
-                       break;
+                       return ttl != info->ttl;
                case IPT_TTL_LT:
-                       return (ttl < info->ttl);
-                       break;
+                       return ttl < info->ttl;
                case IPT_TTL_GT:
-                       return (ttl > info->ttl);
-                       break;
+                       return ttl > info->ttl;
                default:
                        printk(KERN_WARNING "ipt_ttl: unknown mode %d\n",
                                info->mode);
-                       return 0;
+                       return false;
        }
 
-       return 0;
+       return false;
 }
 
-static struct xt_match ttl_match = {
+static struct xt_match ttl_match __read_mostly = {
        .name           = "ttl",
        .family         = AF_INET,
        .match          = match,
index 6dc72a815f77623a2973f94a5d3a84eafae1f80f..3c562993848751d19fdc0d9b8b467b94aadae2b0 100644 (file)
 #include <net/netfilter/nf_conntrack_core.h>
 #include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 static int ipv4_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
                             struct nf_conntrack_tuple *tuple)
 {
@@ -103,17 +97,6 @@ ipv4_prepare(struct sk_buff **pskb, unsigned int hooknum, unsigned int *dataoff,
        return NF_ACCEPT;
 }
 
-int nf_nat_module_is_loaded = 0;
-EXPORT_SYMBOL_GPL(nf_nat_module_is_loaded);
-
-static u_int32_t ipv4_get_features(const struct nf_conntrack_tuple *tuple)
-{
-       if (nf_nat_module_is_loaded)
-               return NF_CT_F_NAT;
-
-       return NF_CT_F_BASIC;
-}
-
 static unsigned int ipv4_confirm(unsigned int hooknum,
                                 struct sk_buff **pskb,
                                 const struct net_device *in,
@@ -335,17 +318,17 @@ getorigdst(struct sock *sk, int optval, void __user *user, int *len)
 
        /* We only do TCP at the moment: is there a better way? */
        if (strcmp(sk->sk_prot->name, "TCP")) {
-               DEBUGP("SO_ORIGINAL_DST: Not a TCP socket\n");
+               pr_debug("SO_ORIGINAL_DST: Not a TCP socket\n");
                return -ENOPROTOOPT;
        }
 
        if ((unsigned int) *len < sizeof(struct sockaddr_in)) {
-               DEBUGP("SO_ORIGINAL_DST: len %u not %u\n",
-                      *len, sizeof(struct sockaddr_in));
+               pr_debug("SO_ORIGINAL_DST: len %d not %Zu\n",
+                        *len, sizeof(struct sockaddr_in));
                return -EINVAL;
        }
 
-       h = nf_conntrack_find_get(&tuple, NULL);
+       h = nf_conntrack_find_get(&tuple);
        if (h) {
                struct sockaddr_in sin;
                struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h);
@@ -357,17 +340,17 @@ getorigdst(struct sock *sk, int optval, void __user *user, int *len)
                        .tuple.dst.u3.ip;
                memset(sin.sin_zero, 0, sizeof(sin.sin_zero));
 
-               DEBUGP("SO_ORIGINAL_DST: %u.%u.%u.%u %u\n",
-                      NIPQUAD(sin.sin_addr.s_addr), ntohs(sin.sin_port));
+               pr_debug("SO_ORIGINAL_DST: %u.%u.%u.%u %u\n",
+                        NIPQUAD(sin.sin_addr.s_addr), ntohs(sin.sin_port));
                nf_ct_put(ct);
                if (copy_to_user(user, &sin, sizeof(sin)) != 0)
                        return -EFAULT;
                else
                        return 0;
        }
-       DEBUGP("SO_ORIGINAL_DST: Can't find %u.%u.%u.%u/%u-%u.%u.%u.%u/%u.\n",
-              NIPQUAD(tuple.src.u3.ip), ntohs(tuple.src.u.tcp.port),
-              NIPQUAD(tuple.dst.u3.ip), ntohs(tuple.dst.u.tcp.port));
+       pr_debug("SO_ORIGINAL_DST: Can't find %u.%u.%u.%u/%u-%u.%u.%u.%u/%u.\n",
+                NIPQUAD(tuple.src.u3.ip), ntohs(tuple.src.u.tcp.port),
+                NIPQUAD(tuple.dst.u3.ip), ntohs(tuple.dst.u.tcp.port));
        return -ENOENT;
 }
 
@@ -425,7 +408,6 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 = {
        .print_tuple     = ipv4_print_tuple,
        .print_conntrack = ipv4_print_conntrack,
        .prepare         = ipv4_prepare,
-       .get_features    = ipv4_get_features,
 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
        .tuple_to_nfattr = ipv4_tuple_to_nfattr,
        .nfattr_to_tuple = ipv4_nfattr_to_tuple,
index 89f933e810359d8d252e272b29ae22e3627702c1..3da9d73d1b52be43171b57c502e80a33e33d97ba 100644 (file)
 #include <net/netfilter/nf_conntrack_l4proto.h>
 #include <net/netfilter/nf_conntrack_expect.h>
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 #ifdef CONFIG_NF_CT_ACCT
 static unsigned int
 seq_print_counters(struct seq_file *s,
@@ -41,35 +35,36 @@ struct ct_iter_state {
        unsigned int bucket;
 };
 
-static struct list_head *ct_get_first(struct seq_file *seq)
+static struct hlist_node *ct_get_first(struct seq_file *seq)
 {
        struct ct_iter_state *st = seq->private;
 
        for (st->bucket = 0;
             st->bucket < nf_conntrack_htable_size;
             st->bucket++) {
-               if (!list_empty(&nf_conntrack_hash[st->bucket]))
-                       return nf_conntrack_hash[st->bucket].next;
+               if (!hlist_empty(&nf_conntrack_hash[st->bucket]))
+                       return nf_conntrack_hash[st->bucket].first;
        }
        return NULL;
 }
 
-static struct list_head *ct_get_next(struct seq_file *seq, struct list_head *head)
+static struct hlist_node *ct_get_next(struct seq_file *seq,
+                                     struct hlist_node *head)
 {
        struct ct_iter_state *st = seq->private;
 
        head = head->next;
-       while (head == &nf_conntrack_hash[st->bucket]) {
+       while (head == NULL) {
                if (++st->bucket >= nf_conntrack_htable_size)
                        return NULL;
-               head = nf_conntrack_hash[st->bucket].next;
+               head = nf_conntrack_hash[st->bucket].first;
        }
        return head;
 }
 
-static struct list_head *ct_get_idx(struct seq_file *seq, loff_t pos)
+static struct hlist_node *ct_get_idx(struct seq_file *seq, loff_t pos)
 {
-       struct list_head *head = ct_get_first(seq);
+       struct hlist_node *head = ct_get_first(seq);
 
        if (head)
                while (pos && (head = ct_get_next(seq, head)))
@@ -169,7 +164,7 @@ static int ct_seq_show(struct seq_file *s, void *v)
        return 0;
 }
 
-static struct seq_operations ct_seq_ops = {
+static const struct seq_operations ct_seq_ops = {
        .start = ct_seq_start,
        .next  = ct_seq_next,
        .stop  = ct_seq_stop,
@@ -206,47 +201,68 @@ static const struct file_operations ct_file_ops = {
 };
 
 /* expects */
-static void *exp_seq_start(struct seq_file *s, loff_t *pos)
+struct ct_expect_iter_state {
+       unsigned int bucket;
+};
+
+static struct hlist_node *ct_expect_get_first(struct seq_file *seq)
 {
-       struct list_head *e = &nf_conntrack_expect_list;
-       loff_t i;
+       struct ct_expect_iter_state *st = seq->private;
 
-       /* strange seq_file api calls stop even if we fail,
-        * thus we need to grab lock since stop unlocks */
-       read_lock_bh(&nf_conntrack_lock);
+       for (st->bucket = 0; st->bucket < nf_ct_expect_hsize; st->bucket++) {
+               if (!hlist_empty(&nf_ct_expect_hash[st->bucket]))
+                       return nf_ct_expect_hash[st->bucket].first;
+       }
+       return NULL;
+}
 
-       if (list_empty(e))
-               return NULL;
+static struct hlist_node *ct_expect_get_next(struct seq_file *seq,
+                                            struct hlist_node *head)
+{
+       struct ct_expect_iter_state *st = seq->private;
 
-       for (i = 0; i <= *pos; i++) {
-               e = e->next;
-               if (e == &nf_conntrack_expect_list)
+       head = head->next;
+       while (head == NULL) {
+               if (++st->bucket >= nf_ct_expect_hsize)
                        return NULL;
+               head = nf_ct_expect_hash[st->bucket].first;
        }
-       return e;
+       return head;
 }
 
-static void *exp_seq_next(struct seq_file *s, void *v, loff_t *pos)
+static struct hlist_node *ct_expect_get_idx(struct seq_file *seq, loff_t pos)
 {
-       struct list_head *e = v;
+       struct hlist_node *head = ct_expect_get_first(seq);
 
-       ++*pos;
-       e = e->next;
+       if (head)
+               while (pos && (head = ct_expect_get_next(seq, head)))
+                       pos--;
+       return pos ? NULL : head;
+}
 
-       if (e == &nf_conntrack_expect_list)
-               return NULL;
+static void *exp_seq_start(struct seq_file *seq, loff_t *pos)
+{
+       read_lock_bh(&nf_conntrack_lock);
+       return ct_expect_get_idx(seq, *pos);
+}
 
-       return e;
+static void *exp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+       (*pos)++;
+       return ct_expect_get_next(seq, v);
 }
 
-static void exp_seq_stop(struct seq_file *s, void *v)
+static void exp_seq_stop(struct seq_file *seq, void *v)
 {
        read_unlock_bh(&nf_conntrack_lock);
 }
 
 static int exp_seq_show(struct seq_file *s, void *v)
 {
-       struct nf_conntrack_expect *exp = v;
+       struct nf_conntrack_expect *exp;
+       struct hlist_node *n = v;
+
+       exp = hlist_entry(n, struct nf_conntrack_expect, hnode);
 
        if (exp->tuple.src.l3num != AF_INET)
                return 0;
@@ -266,7 +282,7 @@ static int exp_seq_show(struct seq_file *s, void *v)
        return seq_putc(s, '\n');
 }
 
-static struct seq_operations exp_seq_ops = {
+static const struct seq_operations exp_seq_ops = {
        .start = exp_seq_start,
        .next = exp_seq_next,
        .stop = exp_seq_stop,
@@ -275,7 +291,23 @@ static struct seq_operations exp_seq_ops = {
 
 static int exp_open(struct inode *inode, struct file *file)
 {
-       return seq_open(file, &exp_seq_ops);
+       struct seq_file *seq;
+       struct ct_expect_iter_state *st;
+       int ret;
+
+       st = kmalloc(sizeof(struct ct_expect_iter_state), GFP_KERNEL);
+       if (st == NULL)
+               return -ENOMEM;
+       ret = seq_open(file, &exp_seq_ops);
+       if (ret)
+               goto out_free;
+       seq          = file->private_data;
+       seq->private = st;
+       memset(st, 0, sizeof(struct ct_expect_iter_state));
+       return ret;
+out_free:
+       kfree(st);
+       return ret;
 }
 
 static const struct file_operations ip_exp_file_ops = {
@@ -283,7 +315,7 @@ static const struct file_operations ip_exp_file_ops = {
        .open    = exp_open,
        .read    = seq_read,
        .llseek  = seq_lseek,
-       .release = seq_release
+       .release = seq_release_private,
 };
 
 static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos)
@@ -354,7 +386,7 @@ static int ct_cpu_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations ct_cpu_seq_ops = {
+static const struct seq_operations ct_cpu_seq_ops = {
        .start  = ct_cpu_seq_start,
        .next   = ct_cpu_seq_next,
        .stop   = ct_cpu_seq_stop,
index f4fc657c1983068bd5d3f34eb5db9d23f9e9d636..0fe8fb0466ef2767741232f78305c69f26bc0f4a 100644 (file)
 
 static unsigned long nf_ct_icmp_timeout __read_mostly = 30*HZ;
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 static int icmp_pkt_to_tuple(const struct sk_buff *skb,
                             unsigned int dataoff,
                             struct nf_conntrack_tuple *tuple)
@@ -125,8 +119,8 @@ static int icmp_new(struct nf_conn *conntrack,
        if (conntrack->tuplehash[0].tuple.dst.u.icmp.type >= sizeof(valid_new)
            || !valid_new[conntrack->tuplehash[0].tuple.dst.u.icmp.type]) {
                /* Can't create a new ICMP `conn' with this. */
-               DEBUGP("icmp: can't create new conn with type %u\n",
-                      conntrack->tuplehash[0].tuple.dst.u.icmp.type);
+               pr_debug("icmp: can't create new conn with type %u\n",
+                        conntrack->tuplehash[0].tuple.dst.u.icmp.type);
                NF_CT_DUMP_TUPLE(&conntrack->tuplehash[0].tuple);
                return 0;
        }
@@ -159,8 +153,8 @@ icmp_error_message(struct sk_buff *skb,
 
        /* Ignore ICMP's containing fragments (shouldn't happen) */
        if (inside->ip.frag_off & htons(IP_OFFSET)) {
-               DEBUGP("icmp_error_message: fragment of proto %u\n",
-                      inside->ip.protocol);
+               pr_debug("icmp_error_message: fragment of proto %u\n",
+                        inside->ip.protocol);
                return -NF_ACCEPT;
        }
 
@@ -172,8 +166,8 @@ icmp_error_message(struct sk_buff *skb,
        if (!nf_ct_get_tuple(skb, dataoff, dataoff + inside->ip.ihl*4, PF_INET,
                             inside->ip.protocol, &origtuple,
                             &nf_conntrack_l3proto_ipv4, innerproto)) {
-               DEBUGP("icmp_error_message: ! get_tuple p=%u",
-                      inside->ip.protocol);
+               pr_debug("icmp_error_message: ! get_tuple p=%u",
+                        inside->ip.protocol);
                return -NF_ACCEPT;
        }
 
@@ -181,22 +175,22 @@ icmp_error_message(struct sk_buff *skb,
           been preserved inside the ICMP. */
        if (!nf_ct_invert_tuple(&innertuple, &origtuple,
                                &nf_conntrack_l3proto_ipv4, innerproto)) {
-               DEBUGP("icmp_error_message: no match\n");
+               pr_debug("icmp_error_message: no match\n");
                return -NF_ACCEPT;
        }
 
        *ctinfo = IP_CT_RELATED;
 
-       h = nf_conntrack_find_get(&innertuple, NULL);
+       h = nf_conntrack_find_get(&innertuple);
        if (!h) {
                /* Locally generated ICMPs will match inverted if they
                   haven't been SNAT'ed yet */
                /* FIXME: NAT code has to handle half-done double NAT --RR */
                if (hooknum == NF_IP_LOCAL_OUT)
-                       h = nf_conntrack_find_get(&origtuple, NULL);
+                       h = nf_conntrack_find_get(&origtuple);
 
                if (!h) {
-                       DEBUGP("icmp_error_message: no match\n");
+                       pr_debug("icmp_error_message: no match\n");
                        return -NF_ACCEPT;
                }
 
index 0f17098917bc0e910a2d37ee6c539d8084c6ce60..bd93a1d71052a8013a99ed735c17b057117d2e57 100644 (file)
@@ -45,7 +45,7 @@ static unsigned int help(struct sk_buff **pskb,
        /* Try to get same port: if not, try to change it. */
        for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) {
                exp->tuple.dst.u.tcp.port = htons(port);
-               if (nf_conntrack_expect_related(exp) == 0)
+               if (nf_ct_expect_related(exp) == 0)
                        break;
        }
 
@@ -57,7 +57,7 @@ static unsigned int help(struct sk_buff **pskb,
                                       matchoff, matchlen,
                                       buffer, strlen(buffer));
        if (ret != NF_ACCEPT)
-               nf_conntrack_unexpect_related(exp);
+               nf_ct_unexpect_related(exp);
        return ret;
 }
 
index ea02f00d2dac5ef644bcc0602f27d733152c7770..e848d8d6292fc1f3f93431320a4c7fae0c737291 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/types.h>
 #include <linux/timer.h>
 #include <linux/skbuff.h>
-#include <linux/vmalloc.h>
 #include <net/checksum.h>
 #include <net/icmp.h>
 #include <net/ip.h>
 #include <net/netfilter/nf_conntrack_l3proto.h>
 #include <net/netfilter/nf_conntrack_l4proto.h>
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 static DEFINE_RWLOCK(nf_nat_lock);
 
 static struct nf_conntrack_l3proto *l3proto = NULL;
 
 /* Calculated at init based on memory size */
 static unsigned int nf_nat_htable_size;
+static int nf_nat_vmalloced;
 
-static struct list_head *bysource;
+static struct hlist_head *bysource;
 
 #define MAX_IP_NAT_PROTO 256
 static struct nf_nat_protocol *nf_nat_protos[MAX_IP_NAT_PROTO];
@@ -87,19 +81,6 @@ hash_by_src(const struct nf_conntrack_tuple *tuple)
                            tuple->dst.protonum, 0) % nf_nat_htable_size;
 }
 
-/* Noone using conntrack by the time this called. */
-static void nf_nat_cleanup_conntrack(struct nf_conn *conn)
-{
-       struct nf_conn_nat *nat;
-       if (!(conn->status & IPS_NAT_DONE_MASK))
-               return;
-
-       nat = nfct_nat(conn);
-       write_lock_bh(&nf_nat_lock);
-       list_del(&nat->info.bysource);
-       write_unlock_bh(&nf_nat_lock);
-}
-
 /* Is this tuple already taken? (not by us) */
 int
 nf_nat_used_tuple(const struct nf_conntrack_tuple *tuple,
@@ -166,10 +147,11 @@ find_appropriate_src(const struct nf_conntrack_tuple *tuple,
        unsigned int h = hash_by_src(tuple);
        struct nf_conn_nat *nat;
        struct nf_conn *ct;
+       struct hlist_node *n;
 
        read_lock_bh(&nf_nat_lock);
-       list_for_each_entry(nat, &bysource[h], info.bysource) {
-               ct = (struct nf_conn *)((char *)nat - offsetof(struct nf_conn, data));
+       hlist_for_each_entry(nat, n, &bysource[h], bysource) {
+               ct = nat->ct;
                if (same_src(ct, tuple)) {
                        /* Copy source part from reply tuple. */
                        nf_ct_invert_tuplepr(result,
@@ -254,7 +236,7 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple,
           manips not an issue.  */
        if (maniptype == IP_NAT_MANIP_SRC) {
                if (find_appropriate_src(orig_tuple, tuple, range)) {
-                       DEBUGP("get_unique_tuple: Found current src map\n");
+                       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;
@@ -296,11 +278,20 @@ nf_nat_setup_info(struct nf_conn *ct,
                  unsigned int hooknum)
 {
        struct nf_conntrack_tuple curr_tuple, new_tuple;
-       struct nf_conn_nat *nat = nfct_nat(ct);
-       struct nf_nat_info *info = &nat->info;
+       struct nf_conn_nat *nat;
        int have_to_hash = !(ct->status & IPS_NAT_DONE_MASK);
        enum nf_nat_manip_type maniptype = HOOK2MANIP(hooknum);
 
+       /* nat helper or nfctnetlink also setup binding */
+       nat = nfct_nat(ct);
+       if (!nat) {
+               nat = nf_ct_ext_add(ct, NF_CT_EXT_NAT, GFP_ATOMIC);
+               if (nat == NULL) {
+                       pr_debug("failed to add NAT extension\n");
+                       return NF_ACCEPT;
+               }
+       }
+
        NF_CT_ASSERT(hooknum == NF_IP_PRE_ROUTING ||
                     hooknum == NF_IP_POST_ROUTING ||
                     hooknum == NF_IP_LOCAL_IN ||
@@ -337,7 +328,10 @@ nf_nat_setup_info(struct nf_conn *ct,
 
                srchash = hash_by_src(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
                write_lock_bh(&nf_nat_lock);
-               list_add(&info->bysource, &bysource[srchash]);
+               /* nf_conntrack_alter_reply might re-allocate exntension aera */
+               nat = nfct_nat(ct);
+               nat->ct = ct;
+               hlist_add_head(&nat->bysource, &bysource[srchash]);
                write_unlock_bh(&nf_nat_lock);
        }
 
@@ -462,8 +456,9 @@ int nf_nat_icmp_reply_translation(struct nf_conn *ct,
                        return 0;
        }
 
-       DEBUGP("icmp_reply_translation: translating error %p manp %u dir %s\n",
-              *pskb, manip, dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY");
+       pr_debug("icmp_reply_translation: translating error %p manip %u "
+                "dir %s\n", *pskb, manip,
+                dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY");
 
        /* rcu_read_lock()ed by nf_hook_slow */
        l4proto = __nf_ct_l4proto_find(PF_INET, inside->ip.protocol);
@@ -590,17 +585,69 @@ nf_nat_port_nfattr_to_range(struct nfattr *tb[], struct nf_nat_range *range)
 EXPORT_SYMBOL_GPL(nf_nat_port_range_to_nfattr);
 #endif
 
+/* Noone using conntrack by the time this called. */
+static void nf_nat_cleanup_conntrack(struct nf_conn *ct)
+{
+       struct nf_conn_nat *nat = nf_ct_ext_find(ct, NF_CT_EXT_NAT);
+
+       if (nat == NULL || nat->ct == NULL)
+               return;
+
+       NF_CT_ASSERT(nat->ct->status & IPS_NAT_DONE_MASK);
+
+       write_lock_bh(&nf_nat_lock);
+       hlist_del(&nat->bysource);
+       nat->ct = NULL;
+       write_unlock_bh(&nf_nat_lock);
+}
+
+static void nf_nat_move_storage(struct nf_conn *conntrack, void *old)
+{
+       struct nf_conn_nat *new_nat = nf_ct_ext_find(conntrack, NF_CT_EXT_NAT);
+       struct nf_conn_nat *old_nat = (struct nf_conn_nat *)old;
+       struct nf_conn *ct = old_nat->ct;
+       unsigned int srchash;
+
+       if (!(ct->status & IPS_NAT_DONE_MASK))
+               return;
+
+       srchash = hash_by_src(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
+
+       write_lock_bh(&nf_nat_lock);
+       hlist_replace_rcu(&old_nat->bysource, &new_nat->bysource);
+       new_nat->ct = ct;
+       write_unlock_bh(&nf_nat_lock);
+}
+
+static struct nf_ct_ext_type nat_extend __read_mostly = {
+       .len            = sizeof(struct nf_conn_nat),
+       .align          = __alignof__(struct nf_conn_nat),
+       .destroy        = nf_nat_cleanup_conntrack,
+       .move           = nf_nat_move_storage,
+       .id             = NF_CT_EXT_NAT,
+       .flags          = NF_CT_EXT_F_PREALLOC,
+};
+
 static int __init nf_nat_init(void)
 {
        size_t i;
+       int ret;
+
+       ret = nf_ct_extend_register(&nat_extend);
+       if (ret < 0) {
+               printk(KERN_ERR "nf_nat_core: Unable to register extension\n");
+               return ret;
+       }
 
        /* Leave them the same for the moment. */
        nf_nat_htable_size = nf_conntrack_htable_size;
 
-       /* One vmalloc for both hash tables */
-       bysource = vmalloc(sizeof(struct list_head) * nf_nat_htable_size);
-       if (!bysource)
-               return -ENOMEM;
+       bysource = nf_ct_alloc_hashtable(&nf_nat_htable_size,
+                                        &nf_nat_vmalloced);
+       if (!bysource) {
+               ret = -ENOMEM;
+               goto cleanup_extend;
+       }
 
        /* Sew in builtin protocols. */
        write_lock_bh(&nf_nat_lock);
@@ -612,18 +659,18 @@ static int __init nf_nat_init(void)
        write_unlock_bh(&nf_nat_lock);
 
        for (i = 0; i < nf_nat_htable_size; i++) {
-               INIT_LIST_HEAD(&bysource[i]);
+               INIT_HLIST_HEAD(&bysource[i]);
        }
 
-       /* FIXME: Man, this is a hack.  <SIGH> */
-       NF_CT_ASSERT(rcu_dereference(nf_conntrack_destroyed) == NULL);
-       rcu_assign_pointer(nf_conntrack_destroyed, nf_nat_cleanup_conntrack);
-
        /* Initialize fake conntrack so that NAT will skip it */
        nf_conntrack_untracked.status |= IPS_NAT_DONE_MASK;
 
        l3proto = nf_ct_l3proto_find_get((u_int16_t)AF_INET);
        return 0;
+
+ cleanup_extend:
+       nf_ct_extend_unregister(&nat_extend);
+       return ret;
 }
 
 /* Clear NAT section of all conntracks, in case we're loaded again. */
@@ -641,10 +688,10 @@ static int clean_nat(struct nf_conn *i, void *data)
 static void __exit nf_nat_cleanup(void)
 {
        nf_ct_iterate_cleanup(&clean_nat, NULL);
-       rcu_assign_pointer(nf_conntrack_destroyed, NULL);
        synchronize_rcu();
-       vfree(bysource);
+       nf_ct_free_hashtable(bysource, nf_nat_vmalloced, nf_nat_htable_size);
        nf_ct_l3proto_put(l3proto);
+       nf_ct_extend_unregister(&nat_extend);
 }
 
 MODULE_LICENSE("GPL");
index e6bc8e5a72f13796a36c3fa1af3b5d12619fb1b2..3663bd879c39e19e76633cc412841f83303f4008 100644 (file)
@@ -25,12 +25,6 @@ MODULE_AUTHOR("Rusty Russell <rusty@rustcorp.com.au>");
 MODULE_DESCRIPTION("ftp NAT helper");
 MODULE_ALIAS("ip_nat_ftp");
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 /* FIXME: Time out? --RR */
 
 static int
@@ -47,7 +41,7 @@ mangle_rfc959_packet(struct sk_buff **pskb,
        sprintf(buffer, "%u,%u,%u,%u,%u,%u",
                NIPQUAD(newip), port>>8, port&0xFF);
 
-       DEBUGP("calling nf_nat_mangle_tcp_packet\n");
+       pr_debug("calling nf_nat_mangle_tcp_packet\n");
 
        return nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff,
                                        matchlen, buffer, strlen(buffer));
@@ -67,7 +61,7 @@ mangle_eprt_packet(struct sk_buff **pskb,
 
        sprintf(buffer, "|1|%u.%u.%u.%u|%u|", NIPQUAD(newip), port);
 
-       DEBUGP("calling nf_nat_mangle_tcp_packet\n");
+       pr_debug("calling nf_nat_mangle_tcp_packet\n");
 
        return nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff,
                                        matchlen, buffer, strlen(buffer));
@@ -87,7 +81,7 @@ mangle_epsv_packet(struct sk_buff **pskb,
 
        sprintf(buffer, "|||%u|", port);
 
-       DEBUGP("calling nf_nat_mangle_tcp_packet\n");
+       pr_debug("calling nf_nat_mangle_tcp_packet\n");
 
        return nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff,
                                        matchlen, buffer, strlen(buffer));
@@ -117,7 +111,7 @@ static unsigned int nf_nat_ftp(struct sk_buff **pskb,
        int dir = CTINFO2DIR(ctinfo);
        struct nf_conn *ct = exp->master;
 
-       DEBUGP("FTP_NAT: type %i, off %u len %u\n", type, matchoff, matchlen);
+       pr_debug("FTP_NAT: type %i, off %u len %u\n", type, matchoff, matchlen);
 
        /* Connection will come from wherever this packet goes, hence !dir */
        newip = ct->tuplehash[!dir].tuple.dst.u3.ip;
@@ -131,7 +125,7 @@ static unsigned int nf_nat_ftp(struct sk_buff **pskb,
        /* Try to get same port: if not, try to change it. */
        for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) {
                exp->tuple.dst.u.tcp.port = htons(port);
-               if (nf_conntrack_expect_related(exp) == 0)
+               if (nf_ct_expect_related(exp) == 0)
                        break;
        }
 
@@ -139,7 +133,7 @@ static unsigned int nf_nat_ftp(struct sk_buff **pskb,
                return NF_DROP;
 
        if (!mangle[type](pskb, newip, port, matchoff, matchlen, ct, ctinfo)) {
-               nf_conntrack_unexpect_related(exp);
+               nf_ct_unexpect_related(exp);
                return NF_DROP;
        }
        return NF_ACCEPT;
index c5d2a2d690b84e54b558ac8e558b6c0550a7ac36..c1b059a737088bbad8ba3d3785e41522c8ce13d0 100644 (file)
 #include <net/netfilter/nf_conntrack_expect.h>
 #include <linux/netfilter/nf_conntrack_h323.h>
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 /****************************************************************************/
 static int set_addr(struct sk_buff **pskb,
                    unsigned char **data, int dataoff,
@@ -126,12 +120,11 @@ static int set_sig_addr(struct sk_buff **pskb, struct nf_conn *ct,
                                    (ntohl(addr.ip) & 0xff000000) == 0x7f000000)
                                        i = 0;
 
-                               DEBUGP
-                                   ("nf_nat_ras: set signal address "
-                                    "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
-                                    NIPQUAD(ip), port,
-                                    NIPQUAD(ct->tuplehash[!dir].tuple.dst.
-                                            ip), info->sig_port[!dir]);
+                               pr_debug("nf_nat_ras: set signal address "
+                                        "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
+                                        NIPQUAD(addr.ip), port,
+                                        NIPQUAD(ct->tuplehash[!dir].tuple.dst.u3.ip),
+                                        info->sig_port[!dir]);
                                return set_h225_addr(pskb, data, 0, &taddr[i],
                                                     &ct->tuplehash[!dir].
                                                     tuple.dst.u3,
@@ -139,12 +132,11 @@ static int set_sig_addr(struct sk_buff **pskb, struct nf_conn *ct,
                        } else if (addr.ip == ct->tuplehash[dir].tuple.dst.u3.ip &&
                                   port == info->sig_port[dir]) {
                                /* GK->GW */
-                               DEBUGP
-                                   ("nf_nat_ras: set signal address "
-                                    "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
-                                    NIPQUAD(ip), port,
-                                    NIPQUAD(ct->tuplehash[!dir].tuple.src.
-                                            ip), info->sig_port[!dir]);
+                               pr_debug("nf_nat_ras: set signal address "
+                                        "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
+                                        NIPQUAD(addr.ip), port,
+                                        NIPQUAD(ct->tuplehash[!dir].tuple.src.u3.ip),
+                                        info->sig_port[!dir]);
                                return set_h225_addr(pskb, data, 0, &taddr[i],
                                                     &ct->tuplehash[!dir].
                                                     tuple.src.u3,
@@ -171,12 +163,11 @@ static int set_ras_addr(struct sk_buff **pskb, struct nf_conn *ct,
                if (get_h225_addr(ct, *data, &taddr[i], &addr, &port) &&
                    addr.ip == ct->tuplehash[dir].tuple.src.u3.ip &&
                    port == ct->tuplehash[dir].tuple.src.u.udp.port) {
-                       DEBUGP("nf_nat_ras: set rasAddress "
-                              "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
-                              NIPQUAD(ip), ntohs(port),
-                              NIPQUAD(ct->tuplehash[!dir].tuple.dst.u3.ip),
-                              ntohs(ct->tuplehash[!dir].tuple.dst.u.udp.
-                                    port));
+                       pr_debug("nf_nat_ras: set rasAddress "
+                                "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
+                                NIPQUAD(addr.ip), ntohs(port),
+                                NIPQUAD(ct->tuplehash[!dir].tuple.dst.u3.ip),
+                                ntohs(ct->tuplehash[!dir].tuple.dst.u.udp.port));
                        return set_h225_addr(pskb, data, 0, &taddr[i],
                                             &ct->tuplehash[!dir].tuple.dst.u3,
                                             ct->tuplehash[!dir].tuple.
@@ -237,12 +228,12 @@ static int nat_rtp_rtcp(struct sk_buff **pskb, struct nf_conn *ct,
        for (nated_port = ntohs(rtp_exp->tuple.dst.u.udp.port);
             nated_port != 0; nated_port += 2) {
                rtp_exp->tuple.dst.u.udp.port = htons(nated_port);
-               if (nf_conntrack_expect_related(rtp_exp) == 0) {
+               if (nf_ct_expect_related(rtp_exp) == 0) {
                        rtcp_exp->tuple.dst.u.udp.port =
                            htons(nated_port + 1);
-                       if (nf_conntrack_expect_related(rtcp_exp) == 0)
+                       if (nf_ct_expect_related(rtcp_exp) == 0)
                                break;
-                       nf_conntrack_unexpect_related(rtp_exp);
+                       nf_ct_unexpect_related(rtp_exp);
                }
        }
 
@@ -261,22 +252,22 @@ static int nat_rtp_rtcp(struct sk_buff **pskb, struct nf_conn *ct,
                info->rtp_port[i][dir] = rtp_port;
                info->rtp_port[i][!dir] = htons(nated_port);
        } else {
-               nf_conntrack_unexpect_related(rtp_exp);
-               nf_conntrack_unexpect_related(rtcp_exp);
+               nf_ct_unexpect_related(rtp_exp);
+               nf_ct_unexpect_related(rtcp_exp);
                return -1;
        }
 
        /* Success */
-       DEBUGP("nf_nat_h323: expect RTP %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
-              NIPQUAD(rtp_exp->tuple.src.ip),
-              ntohs(rtp_exp->tuple.src.u.udp.port),
-              NIPQUAD(rtp_exp->tuple.dst.ip),
-              ntohs(rtp_exp->tuple.dst.u.udp.port));
-       DEBUGP("nf_nat_h323: expect RTCP %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
-              NIPQUAD(rtcp_exp->tuple.src.ip),
-              ntohs(rtcp_exp->tuple.src.u.udp.port),
-              NIPQUAD(rtcp_exp->tuple.dst.ip),
-              ntohs(rtcp_exp->tuple.dst.u.udp.port));
+       pr_debug("nf_nat_h323: expect RTP %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
+                NIPQUAD(rtp_exp->tuple.src.u3.ip),
+                ntohs(rtp_exp->tuple.src.u.udp.port),
+                NIPQUAD(rtp_exp->tuple.dst.u3.ip),
+                ntohs(rtp_exp->tuple.dst.u.udp.port));
+       pr_debug("nf_nat_h323: expect RTCP %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
+                NIPQUAD(rtcp_exp->tuple.src.u3.ip),
+                ntohs(rtcp_exp->tuple.src.u.udp.port),
+                NIPQUAD(rtcp_exp->tuple.dst.u3.ip),
+                ntohs(rtcp_exp->tuple.dst.u.udp.port));
 
        return 0;
 }
@@ -299,7 +290,7 @@ static int nat_t120(struct sk_buff **pskb, struct nf_conn *ct,
        /* Try to get same port: if not, try to change it. */
        for (; nated_port != 0; nated_port++) {
                exp->tuple.dst.u.tcp.port = htons(nated_port);
-               if (nf_conntrack_expect_related(exp) == 0)
+               if (nf_ct_expect_related(exp) == 0)
                        break;
        }
 
@@ -313,13 +304,15 @@ static int nat_t120(struct sk_buff **pskb, struct nf_conn *ct,
        if (set_h245_addr(pskb, data, dataoff, taddr,
                          &ct->tuplehash[!dir].tuple.dst.u3,
                          htons(nated_port)) < 0) {
-               nf_conntrack_unexpect_related(exp);
+               nf_ct_unexpect_related(exp);
                return -1;
        }
 
-       DEBUGP("nf_nat_h323: expect T.120 %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
-              NIPQUAD(exp->tuple.src.ip), ntohs(exp->tuple.src.u.tcp.port),
-              NIPQUAD(exp->tuple.dst.ip), ntohs(exp->tuple.dst.u.tcp.port));
+       pr_debug("nf_nat_h323: expect T.120 %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
+                NIPQUAD(exp->tuple.src.u3.ip),
+                ntohs(exp->tuple.src.u.tcp.port),
+                NIPQUAD(exp->tuple.dst.u3.ip),
+                ntohs(exp->tuple.dst.u.tcp.port));
 
        return 0;
 }
@@ -347,7 +340,7 @@ static int nat_h245(struct sk_buff **pskb, struct nf_conn *ct,
        /* Try to get same port: if not, try to change it. */
        for (; nated_port != 0; nated_port++) {
                exp->tuple.dst.u.tcp.port = htons(nated_port);
-               if (nf_conntrack_expect_related(exp) == 0)
+               if (nf_ct_expect_related(exp) == 0)
                        break;
        }
 
@@ -365,13 +358,15 @@ static int nat_h245(struct sk_buff **pskb, struct nf_conn *ct,
                info->sig_port[dir] = port;
                info->sig_port[!dir] = htons(nated_port);
        } else {
-               nf_conntrack_unexpect_related(exp);
+               nf_ct_unexpect_related(exp);
                return -1;
        }
 
-       DEBUGP("nf_nat_q931: expect H.245 %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
-              NIPQUAD(exp->tuple.src.ip), ntohs(exp->tuple.src.u.tcp.port),
-              NIPQUAD(exp->tuple.dst.ip), ntohs(exp->tuple.dst.u.tcp.port));
+       pr_debug("nf_nat_q931: expect H.245 %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
+                NIPQUAD(exp->tuple.src.u3.ip),
+                ntohs(exp->tuple.src.u.tcp.port),
+                NIPQUAD(exp->tuple.dst.u3.ip),
+                ntohs(exp->tuple.dst.u.tcp.port));
 
        return 0;
 }
@@ -433,7 +428,7 @@ static int nat_q931(struct sk_buff **pskb, struct nf_conn *ct,
        /* Try to get same port: if not, try to change it. */
        for (; nated_port != 0; nated_port++) {
                exp->tuple.dst.u.tcp.port = htons(nated_port);
-               if (nf_conntrack_expect_related(exp) == 0)
+               if (nf_ct_expect_related(exp) == 0)
                        break;
        }
 
@@ -460,14 +455,16 @@ static int nat_q931(struct sk_buff **pskb, struct nf_conn *ct,
                                      info->sig_port[!dir]);
                }
        } else {
-               nf_conntrack_unexpect_related(exp);
+               nf_ct_unexpect_related(exp);
                return -1;
        }
 
        /* Success */
-       DEBUGP("nf_nat_ras: expect Q.931 %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
-              NIPQUAD(exp->tuple.src.ip), ntohs(exp->tuple.src.u.tcp.port),
-              NIPQUAD(exp->tuple.dst.ip), ntohs(exp->tuple.dst.u.tcp.port));
+       pr_debug("nf_nat_ras: expect Q.931 %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
+                NIPQUAD(exp->tuple.src.u3.ip),
+                ntohs(exp->tuple.src.u.tcp.port),
+                NIPQUAD(exp->tuple.dst.u3.ip),
+                ntohs(exp->tuple.dst.u.tcp.port));
 
        return 0;
 }
@@ -517,7 +514,7 @@ static int nat_callforwarding(struct sk_buff **pskb, struct nf_conn *ct,
        /* Try to get same port: if not, try to change it. */
        for (nated_port = ntohs(port); nated_port != 0; nated_port++) {
                exp->tuple.dst.u.tcp.port = htons(nated_port);
-               if (nf_conntrack_expect_related(exp) == 0)
+               if (nf_ct_expect_related(exp) == 0)
                        break;
        }
 
@@ -531,15 +528,17 @@ static int nat_callforwarding(struct sk_buff **pskb, struct nf_conn *ct,
        if (!set_h225_addr(pskb, data, dataoff, taddr,
                           &ct->tuplehash[!dir].tuple.dst.u3,
                           htons(nated_port)) == 0) {
-               nf_conntrack_unexpect_related(exp);
+               nf_ct_unexpect_related(exp);
                return -1;
        }
 
        /* Success */
-       DEBUGP("nf_nat_q931: expect Call Forwarding "
-              "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
-              NIPQUAD(exp->tuple.src.ip), ntohs(exp->tuple.src.u.tcp.port),
-              NIPQUAD(exp->tuple.dst.ip), ntohs(exp->tuple.dst.u.tcp.port));
+       pr_debug("nf_nat_q931: expect Call Forwarding "
+                "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
+                NIPQUAD(exp->tuple.src.u3.ip),
+                ntohs(exp->tuple.src.u.tcp.port),
+                NIPQUAD(exp->tuple.dst.u3.ip),
+                ntohs(exp->tuple.dst.u.tcp.port));
 
        return 0;
 }
@@ -566,8 +565,6 @@ static int __init init(void)
        rcu_assign_pointer(nat_h245_hook, nat_h245);
        rcu_assign_pointer(nat_callforwarding_hook, nat_callforwarding);
        rcu_assign_pointer(nat_q931_hook, nat_q931);
-
-       DEBUGP("nf_nat_h323: init success\n");
        return 0;
 }
 
index 15b6e5ce3a04127c4331e89053aad0f85081126e..93d8a0a8f03562894b2840032f438dd67c4cf39e 100644 (file)
 #include <net/netfilter/nf_nat_core.h>
 #include <net/netfilter/nf_nat_helper.h>
 
-#if 0
-#define DEBUGP printk
-#define DUMP_OFFSET(x) printk("offset_before=%d, offset_after=%d, correction_pos=%u\n", x->offset_before, x->offset_after, x->correction_pos);
-#else
-#define DEBUGP(format, args...)
-#define DUMP_OFFSET(x)
-#endif
+#define DUMP_OFFSET(x) \
+       pr_debug("offset_before=%d, offset_after=%d, correction_pos=%u\n", \
+                x->offset_before, x->offset_after, x->correction_pos);
 
 static DEFINE_SPINLOCK(nf_nat_seqofs_lock);
 
@@ -47,15 +43,15 @@ adjust_tcp_sequence(u32 seq,
        struct nf_nat_seq *this_way, *other_way;
        struct nf_conn_nat *nat = nfct_nat(ct);
 
-       DEBUGP("nf_nat_resize_packet: old_size = %u, new_size = %u\n",
-               (*skb)->len, new_size);
+       pr_debug("adjust_tcp_sequence: seq = %u, sizediff = %d\n",
+                ntohl(seq), seq);
 
        dir = CTINFO2DIR(ctinfo);
 
-       this_way = &nat->info.seq[dir];
-       other_way = &nat->info.seq[!dir];
+       this_way = &nat->seq[dir];
+       other_way = &nat->seq[!dir];
 
-       DEBUGP("nf_nat_resize_packet: Seq_offset before: ");
+       pr_debug("nf_nat_resize_packet: Seq_offset before: ");
        DUMP_OFFSET(this_way);
 
        spin_lock_bh(&nf_nat_seqofs_lock);
@@ -72,7 +68,7 @@ adjust_tcp_sequence(u32 seq,
        }
        spin_unlock_bh(&nf_nat_seqofs_lock);
 
-       DEBUGP("nf_nat_resize_packet: Seq_offset after: ");
+       pr_debug("nf_nat_resize_packet: Seq_offset after: ");
        DUMP_OFFSET(this_way);
 }
 
@@ -100,14 +96,12 @@ static void mangle_contents(struct sk_buff *skb,
 
        /* update skb info */
        if (rep_len > match_len) {
-               DEBUGP("nf_nat_mangle_packet: Extending packet by "
-                      "%u from %u bytes\n", rep_len - match_len,
-                      skb->len);
+               pr_debug("nf_nat_mangle_packet: Extending packet by "
+                        "%u from %u bytes\n", rep_len - match_len, skb->len);
                skb_put(skb, rep_len - match_len);
        } else {
-               DEBUGP("nf_nat_mangle_packet: Shrinking packet from "
-                      "%u from %u bytes\n", match_len - rep_len,
-                      skb->len);
+               pr_debug("nf_nat_mangle_packet: Shrinking packet from "
+                        "%u from %u bytes\n", match_len - rep_len, skb->len);
                __skb_trim(skb, skb->len + rep_len - match_len);
        }
 
@@ -178,7 +172,7 @@ nf_nat_mangle_tcp_packet(struct sk_buff **pskb,
        datalen = (*pskb)->len - iph->ihl*4;
        if ((*pskb)->ip_summed != CHECKSUM_PARTIAL) {
                if (!(rt->rt_flags & RTCF_LOCAL) &&
-                   (*pskb)->dev->features & NETIF_F_ALL_CSUM) {
+                   (*pskb)->dev->features & NETIF_F_V4_CSUM) {
                        (*pskb)->ip_summed = CHECKSUM_PARTIAL;
                        (*pskb)->csum_start = skb_headroom(*pskb) +
                                              skb_network_offset(*pskb) +
@@ -190,7 +184,7 @@ nf_nat_mangle_tcp_packet(struct sk_buff **pskb,
                        tcph->check = 0;
                        tcph->check = tcp_v4_check(datalen,
                                                   iph->saddr, iph->daddr,
-                                                  csum_partial((char *)tcph,
+                                                  csum_partial(tcph,
                                                                datalen, 0));
                }
        } else
@@ -265,7 +259,7 @@ nf_nat_mangle_udp_packet(struct sk_buff **pskb,
 
        if ((*pskb)->ip_summed != CHECKSUM_PARTIAL) {
                if (!(rt->rt_flags & RTCF_LOCAL) &&
-                   (*pskb)->dev->features & NETIF_F_ALL_CSUM) {
+                   (*pskb)->dev->features & NETIF_F_V4_CSUM) {
                        (*pskb)->ip_summed = CHECKSUM_PARTIAL;
                        (*pskb)->csum_start = skb_headroom(*pskb) +
                                              skb_network_offset(*pskb) +
@@ -278,7 +272,7 @@ nf_nat_mangle_udp_packet(struct sk_buff **pskb,
                        udph->check = 0;
                        udph->check = csum_tcpudp_magic(iph->saddr, iph->daddr,
                                                        datalen, IPPROTO_UDP,
-                                                       csum_partial((char *)udph,
+                                                       csum_partial(udph,
                                                                     datalen, 0));
                        if (!udph->check)
                                udph->check = CSUM_MANGLED_0;
@@ -320,9 +314,9 @@ sack_adjust(struct sk_buff *skb,
                        new_end_seq = htonl(ntohl(sack->end_seq)
                                      - natseq->offset_before);
 
-               DEBUGP("sack_adjust: start_seq: %d->%d, end_seq: %d->%d\n",
-                       ntohl(sack->start_seq), new_start_seq,
-                       ntohl(sack->end_seq), new_end_seq);
+               pr_debug("sack_adjust: start_seq: %d->%d, end_seq: %d->%d\n",
+                        ntohl(sack->start_seq), new_start_seq,
+                        ntohl(sack->end_seq), new_end_seq);
 
                nf_proto_csum_replace4(&tcph->check, skb,
                                       sack->start_seq, new_start_seq, 0);
@@ -372,8 +366,7 @@ nf_nat_sack_adjust(struct sk_buff **pskb,
                            op[1] >= 2+TCPOLEN_SACK_PERBLOCK &&
                            ((op[1] - 2) % TCPOLEN_SACK_PERBLOCK) == 0)
                                sack_adjust(*pskb, tcph, optoff+2,
-                                           optoff+op[1],
-                                           &nat->info.seq[!dir]);
+                                           optoff+op[1], &nat->seq[!dir]);
                        optoff += op[1];
                }
        }
@@ -394,8 +387,8 @@ nf_nat_seq_adjust(struct sk_buff **pskb,
 
        dir = CTINFO2DIR(ctinfo);
 
-       this_way = &nat->info.seq[dir];
-       other_way = &nat->info.seq[!dir];
+       this_way = &nat->seq[dir];
+       other_way = &nat->seq[!dir];
 
        if (!skb_make_writable(pskb, ip_hdrlen(*pskb) + sizeof(*tcph)))
                return 0;
@@ -415,9 +408,9 @@ nf_nat_seq_adjust(struct sk_buff **pskb,
        nf_proto_csum_replace4(&tcph->check, *pskb, tcph->seq, newseq, 0);
        nf_proto_csum_replace4(&tcph->check, *pskb, tcph->ack_seq, newack, 0);
 
-       DEBUGP("Adjusting sequence number from %u->%u, ack from %u->%u\n",
-               ntohl(tcph->seq), ntohl(newseq), ntohl(tcph->ack_seq),
-               ntohl(newack));
+       pr_debug("Adjusting sequence number from %u->%u, ack from %u->%u\n",
+                ntohl(tcph->seq), ntohl(newseq), ntohl(tcph->ack_seq),
+                ntohl(newack));
 
        tcph->seq = newseq;
        tcph->ack_seq = newack;
index 9b8c0daea744f270c25cf84992bd9aa2d6e67753..bcf274bba60278e39bee5be522e39aede326df08 100644 (file)
 #include <net/netfilter/nf_conntrack_expect.h>
 #include <linux/netfilter/nf_conntrack_irc.h>
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
 MODULE_DESCRIPTION("IRC (DCC) NAT helper");
 MODULE_LICENSE("GPL");
@@ -44,9 +38,6 @@ static unsigned int help(struct sk_buff **pskb,
        u_int16_t port;
        unsigned int ret;
 
-       DEBUGP("IRC_NAT: info (seq %u + %u) in %u\n",
-              expect->seq, exp_irc_info->len, ntohl(tcph->seq));
-
        /* Reply comes from server. */
        exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port;
        exp->dir = IP_CT_DIR_REPLY;
@@ -55,7 +46,7 @@ static unsigned int help(struct sk_buff **pskb,
        /* Try to get same port: if not, try to change it. */
        for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) {
                exp->tuple.dst.u.tcp.port = htons(port);
-               if (nf_conntrack_expect_related(exp) == 0)
+               if (nf_ct_expect_related(exp) == 0)
                        break;
        }
 
@@ -64,14 +55,14 @@ static unsigned int help(struct sk_buff **pskb,
 
        ip = ntohl(exp->master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip);
        sprintf(buffer, "%u %u", ip, port);
-       DEBUGP("nf_nat_irc: inserting '%s' == %u.%u.%u.%u, port %u\n",
-              buffer, NIPQUAD(ip), port);
+       pr_debug("nf_nat_irc: inserting '%s' == %u.%u.%u.%u, port %u\n",
+                buffer, NIPQUAD(ip), port);
 
        ret = nf_nat_mangle_tcp_packet(pskb, exp->master, ctinfo,
                                       matchoff, matchlen, buffer,
                                       strlen(buffer));
        if (ret != NF_ACCEPT)
-               nf_conntrack_unexpect_related(exp);
+               nf_ct_unexpect_related(exp);
        return ret;
 }
 
index a66888749ceb83bb0a83bb0d87dd2af6f10ac190..984ec8308b2eb21766b09dea273fd84b7f97c838 100644 (file)
@@ -37,14 +37,6 @@ MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
 MODULE_DESCRIPTION("Netfilter NAT helper module for PPTP");
 MODULE_ALIAS("ip_nat_pptp");
 
-#if 0
-extern const char *pptp_msg_name[];
-#define DEBUGP(format, args...) printk(KERN_DEBUG "%s:%s: " format, __FILE__, \
-                                      __FUNCTION__, ## args)
-#else
-#define DEBUGP(format, args...)
-#endif
-
 static void pptp_nat_expected(struct nf_conn *ct,
                              struct nf_conntrack_expect *exp)
 {
@@ -60,7 +52,7 @@ static void pptp_nat_expected(struct nf_conn *ct,
 
        /* And here goes the grand finale of corrosion... */
        if (exp->dir == IP_CT_DIR_ORIGINAL) {
-               DEBUGP("we are PNS->PAC\n");
+               pr_debug("we are PNS->PAC\n");
                /* therefore, build tuple for PAC->PNS */
                t.src.l3num = AF_INET;
                t.src.u3.ip = master->tuplehash[!exp->dir].tuple.src.u3.ip;
@@ -69,7 +61,7 @@ static void pptp_nat_expected(struct nf_conn *ct,
                t.dst.u.gre.key = ct_pptp_info->pns_call_id;
                t.dst.protonum = IPPROTO_GRE;
        } else {
-               DEBUGP("we are PAC->PNS\n");
+               pr_debug("we are PAC->PNS\n");
                /* build tuple for PNS->PAC */
                t.src.l3num = AF_INET;
                t.src.u3.ip = master->tuplehash[!exp->dir].tuple.src.u3.ip;
@@ -79,15 +71,15 @@ static void pptp_nat_expected(struct nf_conn *ct,
                t.dst.protonum = IPPROTO_GRE;
        }
 
-       DEBUGP("trying to unexpect other dir: ");
+       pr_debug("trying to unexpect other dir: ");
        NF_CT_DUMP_TUPLE(&t);
-       other_exp = nf_conntrack_expect_find_get(&t);
+       other_exp = nf_ct_expect_find_get(&t);
        if (other_exp) {
-               nf_conntrack_unexpect_related(other_exp);
-               nf_conntrack_expect_put(other_exp);
-               DEBUGP("success\n");
+               nf_ct_unexpect_related(other_exp);
+               nf_ct_expect_put(other_exp);
+               pr_debug("success\n");
        } else {
-               DEBUGP("not found!\n");
+               pr_debug("not found!\n");
        }
 
        /* This must be a fresh one. */
@@ -161,9 +153,9 @@ pptp_outbound_pkt(struct sk_buff **pskb,
                cid_off = offsetof(union pptp_ctrl_union, clrreq.callID);
                break;
        default:
-               DEBUGP("unknown outbound packet 0x%04x:%s\n", msg,
-                     (msg <= PPTP_MSG_MAX)?
-                     pptp_msg_name[msg]:pptp_msg_name[0]);
+               pr_debug("unknown outbound packet 0x%04x:%s\n", msg,
+                        msg <= PPTP_MSG_MAX ? pptp_msg_name[msg] :
+                                              pptp_msg_name[0]);
                /* fall through */
        case PPTP_SET_LINK_INFO:
                /* only need to NAT in case PAC is behind NAT box */
@@ -179,8 +171,8 @@ pptp_outbound_pkt(struct sk_buff **pskb,
 
        /* only OUT_CALL_REQUEST, IN_CALL_REPLY, CALL_CLEAR_REQUEST pass
         * down to here */
-       DEBUGP("altering call id from 0x%04x to 0x%04x\n",
-               ntohs(REQ_CID(pptpReq, cid_off)), ntohs(new_callid));
+       pr_debug("altering call id from 0x%04x to 0x%04x\n",
+                ntohs(REQ_CID(pptpReq, cid_off)), ntohs(new_callid));
 
        /* mangle packet */
        if (nf_nat_mangle_tcp_packet(pskb, ct, ctinfo,
@@ -255,8 +247,9 @@ pptp_inbound_pkt(struct sk_buff **pskb,
                pcid_off = offsetof(union pptp_ctrl_union, setlink.peersCallID);
                break;
        default:
-               DEBUGP("unknown inbound packet %s\n", (msg <= PPTP_MSG_MAX)?
-                       pptp_msg_name[msg]:pptp_msg_name[0]);
+               pr_debug("unknown inbound packet %s\n",
+                        msg <= PPTP_MSG_MAX ? pptp_msg_name[msg] :
+                                              pptp_msg_name[0]);
                /* fall through */
        case PPTP_START_SESSION_REQUEST:
        case PPTP_START_SESSION_REPLY:
@@ -272,8 +265,8 @@ pptp_inbound_pkt(struct sk_buff **pskb,
         * WAN_ERROR_NOTIFY, CALL_DISCONNECT_NOTIFY pass down here */
 
        /* mangle packet */
-       DEBUGP("altering peer call id from 0x%04x to 0x%04x\n",
-               ntohs(REQ_CID(pptpReq, pcid_off)), ntohs(new_pcid));
+       pr_debug("altering peer call id from 0x%04x to 0x%04x\n",
+                ntohs(REQ_CID(pptpReq, pcid_off)), ntohs(new_pcid));
 
        if (nf_nat_mangle_tcp_packet(pskb, ct, ctinfo,
                                     pcid_off + sizeof(struct pptp_pkt_hdr) +
index c3908bc5a709dbae3d211d58565ddc5649947dc5..2e40cc83526aaccfb9f27fba36f392cd6061f0cd 100644 (file)
@@ -36,13 +36,6 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
 MODULE_DESCRIPTION("Netfilter NAT protocol helper module for GRE");
 
-#if 0
-#define DEBUGP(format, args...) printk(KERN_DEBUG "%s:%s: " format, __FILE__, \
-                                      __FUNCTION__, ## args)
-#else
-#define DEBUGP(x, args...)
-#endif
-
 /* is key in given range between min and max */
 static int
 gre_in_range(const struct nf_conntrack_tuple *tuple,
@@ -83,7 +76,7 @@ gre_unique_tuple(struct nf_conntrack_tuple *tuple,
                keyptr = &tuple->dst.u.gre.key;
 
        if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)) {
-               DEBUGP("%p: NATing GRE PPTP\n", conntrack);
+               pr_debug("%p: NATing GRE PPTP\n", conntrack);
                min = 1;
                range_size = 0xffff;
        } else {
@@ -91,7 +84,7 @@ gre_unique_tuple(struct nf_conntrack_tuple *tuple,
                range_size = ntohs(range->max.gre.key) - min + 1;
        }
 
-       DEBUGP("min = %u, range_size = %u\n", min, range_size);
+       pr_debug("min = %u, range_size = %u\n", min, range_size);
 
        for (i = 0; i < range_size; i++, key++) {
                *keyptr = htons(min + key % range_size);
@@ -99,7 +92,7 @@ gre_unique_tuple(struct nf_conntrack_tuple *tuple,
                        return 1;
        }
 
-       DEBUGP("%p: no NAT mapping\n", conntrack);
+       pr_debug("%p: no NAT mapping\n", conntrack);
        return 0;
 }
 
@@ -132,11 +125,11 @@ gre_manip_pkt(struct sk_buff **pskb, unsigned int iphdroff,
                 * Try to behave like "nf_nat_proto_unknown" */
                break;
        case GRE_VERSION_PPTP:
-               DEBUGP("call_id -> 0x%04x\n", ntohs(tuple->dst.u.gre.key));
+               pr_debug("call_id -> 0x%04x\n", ntohs(tuple->dst.u.gre.key));
                pgreh->call_id = tuple->dst.u.gre.key;
                break;
        default:
-               DEBUGP("can't nat unknown GRE version\n");
+               pr_debug("can't nat unknown GRE version\n");
                return 0;
        }
        return 1;
index 6740736c5e79d74e03bc529f6e0555c6009f6916..0f45427e5fdc6321018c74b3bf62ddd285afd078 100644 (file)
 #include <net/netfilter/nf_nat_core.h>
 #include <net/netfilter/nf_nat_rule.h>
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 #define NAT_VALID_HOOKS ((1<<NF_IP_PRE_ROUTING) | (1<<NF_IP_POST_ROUTING) | (1<<NF_IP_LOCAL_OUT))
 
 static struct
@@ -140,39 +134,39 @@ static unsigned int ipt_dnat_target(struct sk_buff **pskb,
        return nf_nat_setup_info(ct, &mr->range[0], hooknum);
 }
 
-static int ipt_snat_checkentry(const char *tablename,
-                              const void *entry,
-                              const struct xt_target *target,
-                              void *targinfo,
-                              unsigned int hook_mask)
+static bool ipt_snat_checkentry(const char *tablename,
+                               const void *entry,
+                               const struct xt_target *target,
+                               void *targinfo,
+                               unsigned int hook_mask)
 {
        struct nf_nat_multi_range_compat *mr = targinfo;
 
        /* Must be a valid range */
        if (mr->rangesize != 1) {
                printk("SNAT: multiple ranges no longer supported\n");
-               return 0;
+               return false;
        }
-       return 1;
+       return true;
 }
 
-static int ipt_dnat_checkentry(const char *tablename,
-                              const void *entry,
-                              const struct xt_target *target,
-                              void *targinfo,
-                              unsigned int hook_mask)
+static bool ipt_dnat_checkentry(const char *tablename,
+                               const void *entry,
+                               const struct xt_target *target,
+                               void *targinfo,
+                               unsigned int hook_mask)
 {
        struct nf_nat_multi_range_compat *mr = targinfo;
 
        /* Must be a valid range */
        if (mr->rangesize != 1) {
                printk("DNAT: multiple ranges no longer supported\n");
-               return 0;
+               return false;
        }
-       return 1;
+       return true;
 }
 
-inline unsigned int
+unsigned int
 alloc_null_binding(struct nf_conn *ct, unsigned int hooknum)
 {
        /* Force range to this IP; let proto decide mapping for
@@ -186,8 +180,8 @@ alloc_null_binding(struct nf_conn *ct, unsigned int hooknum)
        struct nf_nat_range range
                = { IP_NAT_RANGE_MAP_IPS, ip, ip, { 0 }, { 0 } };
 
-       DEBUGP("Allocating NULL binding for %p (%u.%u.%u.%u)\n",
-              ct, NIPQUAD(ip));
+       pr_debug("Allocating NULL binding for %p (%u.%u.%u.%u)\n",
+                ct, NIPQUAD(ip));
        return nf_nat_setup_info(ct, &range, hooknum);
 }
 
@@ -205,8 +199,8 @@ alloc_null_binding_confirmed(struct nf_conn *ct, unsigned int hooknum)
        struct nf_nat_range range
                = { IP_NAT_RANGE_MAP_IPS, ip, ip, { all }, { all } };
 
-       DEBUGP("Allocating NULL binding for confirmed %p (%u.%u.%u.%u)\n",
-              ct, NIPQUAD(ip));
+       pr_debug("Allocating NULL binding for confirmed %p (%u.%u.%u.%u)\n",
+                ct, NIPQUAD(ip));
        return nf_nat_setup_info(ct, &range, hooknum);
 }
 
@@ -228,7 +222,7 @@ int nf_nat_rule_find(struct sk_buff **pskb,
        return ret;
 }
 
-static struct xt_target ipt_snat_reg = {
+static struct xt_target ipt_snat_reg __read_mostly = {
        .name           = "SNAT",
        .target         = ipt_snat_target,
        .targetsize     = sizeof(struct nf_nat_multi_range_compat),
@@ -238,7 +232,7 @@ static struct xt_target ipt_snat_reg = {
        .family         = AF_INET,
 };
 
-static struct xt_target ipt_dnat_reg = {
+static struct xt_target ipt_dnat_reg __read_mostly = {
        .name           = "DNAT",
        .target         = ipt_dnat_target,
        .targetsize     = sizeof(struct nf_nat_multi_range_compat),
index fac97cf51ae52c5ec4e934da520bbb538697ac9b..a889ec3ec83abb7edb80a0c91241226b7e978dae 100644 (file)
@@ -26,12 +26,6 @@ MODULE_AUTHOR("Christian Hentschel <chentschel@arnet.com.ar>");
 MODULE_DESCRIPTION("SIP NAT helper");
 MODULE_ALIAS("ip_nat_sip");
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 struct addr_map {
        struct {
                char            src[sizeof("nnn.nnn.nnn.nnn:nnnnn")];
@@ -257,10 +251,12 @@ static unsigned int ip_nat_sdp(struct sk_buff **pskb,
        __be32 newip;
        u_int16_t port;
 
-       DEBUGP("ip_nat_sdp():\n");
-
        /* Connection will come from reply */
-       newip = ct->tuplehash[!dir].tuple.dst.u3.ip;
+       if (ct->tuplehash[dir].tuple.src.u3.ip ==
+           ct->tuplehash[!dir].tuple.dst.u3.ip)
+               newip = exp->tuple.dst.u3.ip;
+       else
+               newip = ct->tuplehash[!dir].tuple.dst.u3.ip;
 
        exp->saved_ip = exp->tuple.dst.u3.ip;
        exp->tuple.dst.u3.ip = newip;
@@ -274,7 +270,7 @@ static unsigned int ip_nat_sdp(struct sk_buff **pskb,
        /* Try to get same port: if not, try to change it. */
        for (port = ntohs(exp->saved_proto.udp.port); port != 0; port++) {
                exp->tuple.dst.u.udp.port = htons(port);
-               if (nf_conntrack_expect_related(exp) == 0)
+               if (nf_ct_expect_related(exp) == 0)
                        break;
        }
 
@@ -282,7 +278,7 @@ static unsigned int ip_nat_sdp(struct sk_buff **pskb,
                return NF_DROP;
 
        if (!mangle_sdp(pskb, ctinfo, ct, newip, port, dptr)) {
-               nf_conntrack_unexpect_related(exp);
+               nf_ct_unexpect_related(exp);
                return NF_DROP;
        }
        return NF_ACCEPT;
index 6e88505d61625b7e9939c5f90257bb76ce772135..6bfcd3a90f08d2d60fe76e32dd6173c36c614f2b 100644 (file)
@@ -1276,9 +1276,6 @@ static struct nf_conntrack_helper snmp_helper __read_mostly = {
        .tuple.src.l3num        = AF_INET,
        .tuple.src.u.udp.port   = __constant_htons(SNMP_PORT),
        .tuple.dst.protonum     = IPPROTO_UDP,
-       .mask.src.l3num         = 0xFFFF,
-       .mask.src.u.udp.port    = __constant_htons(0xFFFF),
-       .mask.dst.protonum      = 0xFF,
 };
 
 static struct nf_conntrack_helper snmp_trap_helper __read_mostly = {
@@ -1290,9 +1287,6 @@ static struct nf_conntrack_helper snmp_trap_helper __read_mostly = {
        .tuple.src.l3num        = AF_INET,
        .tuple.src.u.udp.port   = __constant_htons(SNMP_TRAP_PORT),
        .tuple.dst.protonum     = IPPROTO_UDP,
-       .mask.src.l3num         = 0xFFFF,
-       .mask.src.u.udp.port    = __constant_htons(0xFFFF),
-       .mask.dst.protonum      = 0xFF,
 };
 
 /*****************************************************************************
index 55dac36dbc8548dcd3706fda328c2481c66b956d..332814dac5038ad194fae5f53e1c0fccc5f6f20d 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <net/netfilter/nf_conntrack.h>
 #include <net/netfilter/nf_conntrack_core.h>
+#include <net/netfilter/nf_conntrack_extend.h>
 #include <net/netfilter/nf_nat.h>
 #include <net/netfilter/nf_nat_rule.h>
 #include <net/netfilter/nf_nat_protocol.h>
 #include <net/netfilter/nf_nat_helper.h>
 #include <linux/netfilter_ipv4/ip_tables.h>
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 #ifdef CONFIG_XFRM
 static void nat_decode_session(struct sk_buff *skb, struct flowi *fl)
 {
@@ -113,8 +108,13 @@ nf_nat_fn(unsigned int hooknum,
                return NF_ACCEPT;
 
        nat = nfct_nat(ct);
-       if (!nat)
-               return NF_ACCEPT;
+       if (!nat) {
+               nat = nf_ct_ext_add(ct, NF_CT_EXT_NAT, GFP_ATOMIC);
+               if (nat == NULL) {
+                       pr_debug("failed to add NAT extension\n");
+                       return NF_ACCEPT;
+               }
+       }
 
        switch (ctinfo) {
        case IP_CT_RELATED:
@@ -148,9 +148,9 @@ nf_nat_fn(unsigned int hooknum,
                                return ret;
                        }
                } else
-                       DEBUGP("Already setup manip %s for ct %p\n",
-                              maniptype == IP_NAT_MANIP_SRC ? "SRC" : "DST",
-                              ct);
+                       pr_debug("Already setup manip %s for ct %p\n",
+                                maniptype == IP_NAT_MANIP_SRC ? "SRC" : "DST",
+                                ct);
                break;
 
        default:
@@ -264,7 +264,7 @@ nf_nat_adjust(unsigned int hooknum,
 
        ct = nf_ct_get(*pskb, &ctinfo);
        if (ct && test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)) {
-               DEBUGP("nf_nat_standalone: adjusting sequence number\n");
+               pr_debug("nf_nat_standalone: adjusting sequence number\n");
                if (!nf_nat_seq_adjust(pskb, ct, ctinfo))
                        return NF_DROP;
        }
@@ -326,26 +326,10 @@ static struct nf_hook_ops nf_nat_ops[] = {
 
 static int __init nf_nat_standalone_init(void)
 {
-       int size, ret = 0;
+       int ret = 0;
 
        need_conntrack();
 
-       size = ALIGN(sizeof(struct nf_conn), __alignof__(struct nf_conn_nat)) +
-              sizeof(struct nf_conn_nat);
-       ret = nf_conntrack_register_cache(NF_CT_F_NAT, "nf_nat:base", size);
-       if (ret < 0) {
-               printk(KERN_ERR "nf_nat_init: Unable to create slab cache\n");
-               return ret;
-       }
-
-       size = ALIGN(size, __alignof__(struct nf_conn_help)) +
-              sizeof(struct nf_conn_help);
-       ret = nf_conntrack_register_cache(NF_CT_F_NAT|NF_CT_F_HELP,
-                                         "nf_nat:help", size);
-       if (ret < 0) {
-               printk(KERN_ERR "nf_nat_init: Unable to create slab cache\n");
-               goto cleanup_register_cache;
-       }
 #ifdef CONFIG_XFRM
        BUG_ON(ip_nat_decode_session != NULL);
        ip_nat_decode_session = nat_decode_session;
@@ -360,7 +344,6 @@ static int __init nf_nat_standalone_init(void)
                printk("nf_nat_init: can't register hooks.\n");
                goto cleanup_rule_init;
        }
-       nf_nat_module_is_loaded = 1;
        return ret;
 
  cleanup_rule_init:
@@ -370,9 +353,6 @@ static int __init nf_nat_standalone_init(void)
        ip_nat_decode_session = NULL;
        synchronize_net();
 #endif
-       nf_conntrack_unregister_cache(NF_CT_F_NAT|NF_CT_F_HELP);
- cleanup_register_cache:
-       nf_conntrack_unregister_cache(NF_CT_F_NAT);
        return ret;
 }
 
@@ -380,7 +360,6 @@ static void __exit nf_nat_standalone_fini(void)
 {
        nf_unregister_hooks(nf_nat_ops, ARRAY_SIZE(nf_nat_ops));
        nf_nat_rule_cleanup();
-       nf_nat_module_is_loaded = 0;
 #ifdef CONFIG_XFRM
        ip_nat_decode_session = NULL;
        synchronize_net();
index 2566b79de224dcad1915a4f162ea76cb205acc6d..04dfeaefec0245447872db214c40b50768405181 100644 (file)
@@ -30,7 +30,7 @@ static unsigned int help(struct sk_buff **pskb,
                = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.udp.port;
        exp->dir = IP_CT_DIR_REPLY;
        exp->expectfn = nf_nat_follow_master;
-       if (nf_conntrack_expect_related(exp) != 0)
+       if (nf_ct_expect_related(exp) != 0)
                return NF_DROP;
        return NF_ACCEPT;
 }
index 29ca63e81ced23877fe568573b8522e0ce16d8a1..88fa648d7ba33cf23757d1db1544c2954a230706 100644 (file)
 #include <net/tcp.h>
 #include <net/icmp.h>
 #include <net/xfrm.h>
-#include <net/ip_mp_alg.h>
 #include <net/netevent.h>
 #include <net/rtnetlink.h>
 #ifdef CONFIG_SYSCTL
@@ -168,7 +167,7 @@ static struct dst_ops ipv4_dst_ops = {
 
 #define ECN_OR_COST(class)     TC_PRIO_##class
 
-__u8 ip_tos2prio[16] = {
+const __u8 ip_tos2prio[16] = {
        TC_PRIO_BESTEFFORT,
        ECN_OR_COST(FILLER),
        TC_PRIO_BESTEFFORT,
@@ -495,13 +494,11 @@ static const struct file_operations rt_cpu_seq_fops = {
 
 static __inline__ void rt_free(struct rtable *rt)
 {
-       multipath_remove(rt);
        call_rcu_bh(&rt->u.dst.rcu_head, dst_rcu_free);
 }
 
 static __inline__ void rt_drop(struct rtable *rt)
 {
-       multipath_remove(rt);
        ip_rt_put(rt);
        call_rcu_bh(&rt->u.dst.rcu_head, dst_rcu_free);
 }
@@ -574,52 +571,6 @@ static inline int compare_keys(struct flowi *fl1, struct flowi *fl2)
                (fl1->iif ^ fl2->iif)) == 0;
 }
 
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-static struct rtable **rt_remove_balanced_route(struct rtable **chain_head,
-                                               struct rtable *expentry,
-                                               int *removed_count)
-{
-       int passedexpired = 0;
-       struct rtable **nextstep = NULL;
-       struct rtable **rthp = chain_head;
-       struct rtable *rth;
-
-       if (removed_count)
-               *removed_count = 0;
-
-       while ((rth = *rthp) != NULL) {
-               if (rth == expentry)
-                       passedexpired = 1;
-
-               if (((*rthp)->u.dst.flags & DST_BALANCED) != 0  &&
-                   compare_keys(&(*rthp)->fl, &expentry->fl)) {
-                       if (*rthp == expentry) {
-                               *rthp = rth->u.dst.rt_next;
-                               continue;
-                       } else {
-                               *rthp = rth->u.dst.rt_next;
-                               rt_free(rth);
-                               if (removed_count)
-                                       ++(*removed_count);
-                       }
-               } else {
-                       if (!((*rthp)->u.dst.flags & DST_BALANCED) &&
-                           passedexpired && !nextstep)
-                               nextstep = &rth->u.dst.rt_next;
-
-                       rthp = &rth->u.dst.rt_next;
-               }
-       }
-
-       rt_free(expentry);
-       if (removed_count)
-               ++(*removed_count);
-
-       return nextstep;
-}
-#endif /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
-
-
 /* This runs via a timer and thus is always in BH context. */
 static void rt_check_expire(unsigned long dummy)
 {
@@ -658,22 +609,8 @@ static void rt_check_expire(unsigned long dummy)
                        }
 
                        /* Cleanup aged off entries. */
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-                       /* remove all related balanced entries if necessary */
-                       if (rth->u.dst.flags & DST_BALANCED) {
-                               rthp = rt_remove_balanced_route(
-                                       &rt_hash_table[i].chain,
-                                       rth, NULL);
-                               if (!rthp)
-                                       break;
-                       } else {
-                               *rthp = rth->u.dst.rt_next;
-                               rt_free(rth);
-                       }
-#else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
                        *rthp = rth->u.dst.rt_next;
                        rt_free(rth);
-#endif /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
                }
                spin_unlock(rt_hash_lock_addr(i));
 
@@ -721,9 +658,6 @@ void rt_cache_flush(int delay)
        if (delay < 0)
                delay = ip_rt_min_delay;
 
-       /* flush existing multipath state*/
-       multipath_flush();
-
        spin_lock_bh(&rt_flush_lock);
 
        if (del_timer(&rt_flush_timer) && delay > 0 && rt_deadline) {
@@ -842,30 +776,9 @@ static int rt_garbage_collect(void)
                                        rthp = &rth->u.dst.rt_next;
                                        continue;
                                }
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-                               /* remove all related balanced entries
-                                * if necessary
-                                */
-                               if (rth->u.dst.flags & DST_BALANCED) {
-                                       int r;
-
-                                       rthp = rt_remove_balanced_route(
-                                               &rt_hash_table[k].chain,
-                                               rth,
-                                               &r);
-                                       goal -= r;
-                                       if (!rthp)
-                                               break;
-                               } else {
-                                       *rthp = rth->u.dst.rt_next;
-                                       rt_free(rth);
-                                       goal--;
-                               }
-#else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
                                *rthp = rth->u.dst.rt_next;
                                rt_free(rth);
                                goal--;
-#endif /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
                        }
                        spin_unlock_bh(rt_hash_lock_addr(k));
                        if (goal <= 0)
@@ -939,12 +852,7 @@ restart:
 
        spin_lock_bh(rt_hash_lock_addr(hash));
        while ((rth = *rthp) != NULL) {
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-               if (!(rth->u.dst.flags & DST_BALANCED) &&
-                   compare_keys(&rth->fl, &rt->fl)) {
-#else
                if (compare_keys(&rth->fl, &rt->fl)) {
-#endif
                        /* Put it first */
                        *rthp = rth->u.dst.rt_next;
                        /*
@@ -1774,10 +1682,6 @@ static inline int __mkroute_input(struct sk_buff *skb,
 
        atomic_set(&rth->u.dst.__refcnt, 1);
        rth->u.dst.flags= DST_HOST;
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-       if (res->fi->fib_nhs > 1)
-               rth->u.dst.flags |= DST_BALANCED;
-#endif
        if (IN_DEV_CONF_GET(in_dev, NOPOLICY))
                rth->u.dst.flags |= DST_NOPOLICY;
        if (IN_DEV_CONF_GET(out_dev, NOXFRM))
@@ -1812,11 +1716,11 @@ static inline int __mkroute_input(struct sk_buff *skb,
        return err;
 }
 
-static inline int ip_mkroute_input_def(struct sk_buff *skb,
-                                      struct fib_result* res,
-                                      const struct flowi *fl,
-                                      struct in_device *in_dev,
-                                      __be32 daddr, __be32 saddr, u32 tos)
+static inline int ip_mkroute_input(struct sk_buff *skb,
+                                  struct fib_result* res,
+                                  const struct flowi *fl,
+                                  struct in_device *in_dev,
+                                  __be32 daddr, __be32 saddr, u32 tos)
 {
        struct rtable* rth = NULL;
        int err;
@@ -1837,63 +1741,6 @@ static inline int ip_mkroute_input_def(struct sk_buff *skb,
        return rt_intern_hash(hash, rth, (struct rtable**)&skb->dst);
 }
 
-static inline int ip_mkroute_input(struct sk_buff *skb,
-                                  struct fib_result* res,
-                                  const struct flowi *fl,
-                                  struct in_device *in_dev,
-                                  __be32 daddr, __be32 saddr, u32 tos)
-{
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-       struct rtable* rth = NULL, *rtres;
-       unsigned char hop, hopcount;
-       int err = -EINVAL;
-       unsigned int hash;
-
-       if (res->fi)
-               hopcount = res->fi->fib_nhs;
-       else
-               hopcount = 1;
-
-       /* distinguish between multipath and singlepath */
-       if (hopcount < 2)
-               return ip_mkroute_input_def(skb, res, fl, in_dev, daddr,
-                                           saddr, tos);
-
-       /* add all alternatives to the routing cache */
-       for (hop = 0; hop < hopcount; hop++) {
-               res->nh_sel = hop;
-
-               /* put reference to previous result */
-               if (hop)
-                       ip_rt_put(rtres);
-
-               /* create a routing cache entry */
-               err = __mkroute_input(skb, res, in_dev, daddr, saddr, tos,
-                                     &rth);
-               if (err)
-                       return err;
-
-               /* put it into the cache */
-               hash = rt_hash(daddr, saddr, fl->iif);
-               err = rt_intern_hash(hash, rth, &rtres);
-               if (err)
-                       return err;
-
-               /* forward hop information to multipath impl. */
-               multipath_set_nhinfo(rth,
-                                    FIB_RES_NETWORK(*res),
-                                    FIB_RES_NETMASK(*res),
-                                    res->prefixlen,
-                                    &FIB_RES_NH(*res));
-       }
-       skb->dst = &rtres->u.dst;
-       return err;
-#else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED  */
-       return ip_mkroute_input_def(skb, res, fl, in_dev, daddr, saddr, tos);
-#endif /* CONFIG_IP_ROUTE_MULTIPATH_CACHED  */
-}
-
-
 /*
  *     NOTE. We drop all the packets that has local source
  *     addresses, because every properly looped back packet
@@ -2211,13 +2058,6 @@ static inline int __mkroute_output(struct rtable **result,
 
        atomic_set(&rth->u.dst.__refcnt, 1);
        rth->u.dst.flags= DST_HOST;
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-       if (res->fi) {
-               rth->rt_multipath_alg = res->fi->fib_mp_alg;
-               if (res->fi->fib_nhs > 1)
-                       rth->u.dst.flags |= DST_BALANCED;
-       }
-#endif
        if (IN_DEV_CONF_GET(in_dev, NOXFRM))
                rth->u.dst.flags |= DST_NOXFRM;
        if (IN_DEV_CONF_GET(in_dev, NOPOLICY))
@@ -2277,12 +2117,12 @@ static inline int __mkroute_output(struct rtable **result,
        return err;
 }
 
-static inline int ip_mkroute_output_def(struct rtable **rp,
-                                       struct fib_result* res,
-                                       const struct flowi *fl,
-                                       const struct flowi *oldflp,
-                                       struct net_device *dev_out,
-                                       unsigned flags)
+static inline int ip_mkroute_output(struct rtable **rp,
+                                   struct fib_result* res,
+                                   const struct flowi *fl,
+                                   const struct flowi *oldflp,
+                                   struct net_device *dev_out,
+                                   unsigned flags)
 {
        struct rtable *rth = NULL;
        int err = __mkroute_output(&rth, res, fl, oldflp, dev_out, flags);
@@ -2295,68 +2135,6 @@ static inline int ip_mkroute_output_def(struct rtable **rp,
        return err;
 }
 
-static inline int ip_mkroute_output(struct rtable** rp,
-                                   struct fib_result* res,
-                                   const struct flowi *fl,
-                                   const struct flowi *oldflp,
-                                   struct net_device *dev_out,
-                                   unsigned flags)
-{
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-       unsigned char hop;
-       unsigned hash;
-       int err = -EINVAL;
-       struct rtable *rth = NULL;
-
-       if (res->fi && res->fi->fib_nhs > 1) {
-               unsigned char hopcount = res->fi->fib_nhs;
-
-               for (hop = 0; hop < hopcount; hop++) {
-                       struct net_device *dev2nexthop;
-
-                       res->nh_sel = hop;
-
-                       /* hold a work reference to the output device */
-                       dev2nexthop = FIB_RES_DEV(*res);
-                       dev_hold(dev2nexthop);
-
-                       /* put reference to previous result */
-                       if (hop)
-                               ip_rt_put(*rp);
-
-                       err = __mkroute_output(&rth, res, fl, oldflp,
-                                              dev2nexthop, flags);
-
-                       if (err != 0)
-                               goto cleanup;
-
-                       hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src,
-                                       oldflp->oif);
-                       err = rt_intern_hash(hash, rth, rp);
-
-                       /* forward hop information to multipath impl. */
-                       multipath_set_nhinfo(rth,
-                                            FIB_RES_NETWORK(*res),
-                                            FIB_RES_NETMASK(*res),
-                                            res->prefixlen,
-                                            &FIB_RES_NH(*res));
-               cleanup:
-                       /* release work reference to output device */
-                       dev_put(dev2nexthop);
-
-                       if (err != 0)
-                               return err;
-               }
-               return err;
-       } else {
-               return ip_mkroute_output_def(rp, res, fl, oldflp, dev_out,
-                                            flags);
-       }
-#else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
-       return ip_mkroute_output_def(rp, res, fl, oldflp, dev_out, flags);
-#endif
-}
-
 /*
  * Major route resolver routine.
  */
@@ -2570,17 +2348,6 @@ int __ip_route_output_key(struct rtable **rp, const struct flowi *flp)
                    rth->fl.mark == flp->mark &&
                    !((rth->fl.fl4_tos ^ flp->fl4_tos) &
                            (IPTOS_RT_MASK | RTO_ONLINK))) {
-
-                       /* check for multipath routes and choose one if
-                        * necessary
-                        */
-                       if (multipath_select_route(flp, rth, rp)) {
-                               dst_hold(&(*rp)->u.dst);
-                               RT_CACHE_STAT_INC(out_hit);
-                               rcu_read_unlock_bh();
-                               return 0;
-                       }
-
                        rth->u.dst.lastuse = jiffies;
                        dst_hold(&rth->u.dst);
                        rth->u.dst.__use++;
@@ -2728,10 +2495,6 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
 #ifdef CONFIG_NET_CLS_ROUTE
        if (rt->u.dst.tclassid)
                NLA_PUT_U32(skb, RTA_FLOW, rt->u.dst.tclassid);
-#endif
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-       if (rt->rt_multipath_alg != IP_MP_ALG_NONE)
-               NLA_PUT_U32(skb, RTA_MP_ALGO, rt->rt_multipath_alg);
 #endif
        if (rt->fl.iif)
                NLA_PUT_BE32(skb, RTA_PREFSRC, rt->rt_spec_dst);
index 354721d67f69d21df640d32f24c86ccd3ec90ad9..3f5f7423b95ca818463938dbaad1c8bed8903bb3 100644 (file)
@@ -2045,10 +2045,7 @@ static void *established_get_first(struct seq_file *seq)
                struct hlist_node *node;
                struct inet_timewait_sock *tw;
 
-               /* We can reschedule _before_ having picked the target: */
-               cond_resched_softirq();
-
-               read_lock(&tcp_hashinfo.ehash[st->bucket].lock);
+               read_lock_bh(&tcp_hashinfo.ehash[st->bucket].lock);
                sk_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) {
                        if (sk->sk_family != st->family) {
                                continue;
@@ -2065,7 +2062,7 @@ static void *established_get_first(struct seq_file *seq)
                        rc = tw;
                        goto out;
                }
-               read_unlock(&tcp_hashinfo.ehash[st->bucket].lock);
+               read_unlock_bh(&tcp_hashinfo.ehash[st->bucket].lock);
                st->state = TCP_SEQ_STATE_ESTABLISHED;
        }
 out:
@@ -2092,14 +2089,11 @@ get_tw:
                        cur = tw;
                        goto out;
                }
-               read_unlock(&tcp_hashinfo.ehash[st->bucket].lock);
+               read_unlock_bh(&tcp_hashinfo.ehash[st->bucket].lock);
                st->state = TCP_SEQ_STATE_ESTABLISHED;
 
-               /* We can reschedule between buckets: */
-               cond_resched_softirq();
-
                if (++st->bucket < tcp_hashinfo.ehash_size) {
-                       read_lock(&tcp_hashinfo.ehash[st->bucket].lock);
+                       read_lock_bh(&tcp_hashinfo.ehash[st->bucket].lock);
                        sk = sk_head(&tcp_hashinfo.ehash[st->bucket].chain);
                } else {
                        cur = NULL;
@@ -2144,7 +2138,6 @@ static void *tcp_get_idx(struct seq_file *seq, loff_t pos)
 
        if (!rc) {
                inet_listen_unlock(&tcp_hashinfo);
-               local_bh_disable();
                st->state = TCP_SEQ_STATE_ESTABLISHED;
                rc        = established_get_idx(seq, pos);
        }
@@ -2177,7 +2170,6 @@ static void *tcp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
                rc = listening_get_next(seq, v);
                if (!rc) {
                        inet_listen_unlock(&tcp_hashinfo);
-                       local_bh_disable();
                        st->state = TCP_SEQ_STATE_ESTABLISHED;
                        rc        = established_get_first(seq);
                }
@@ -2209,8 +2201,7 @@ static void tcp_seq_stop(struct seq_file *seq, void *v)
        case TCP_SEQ_STATE_TIME_WAIT:
        case TCP_SEQ_STATE_ESTABLISHED:
                if (v)
-                       read_unlock(&tcp_hashinfo.ehash[st->bucket].lock);
-               local_bh_enable();
+                       read_unlock_bh(&tcp_hashinfo.ehash[st->bucket].lock);
                break;
        }
 }
index 53232dd6fb48af5a9c4f5d2373a1630936bb7980..20aea1595c4daab9f61991792cd56a4877180276 100644 (file)
@@ -699,6 +699,14 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss
                        tp->fackets_out -= diff;
                        if ((int)tp->fackets_out < 0)
                                tp->fackets_out = 0;
+                       /* SACK fastpath might overwrite it unless dealt with */
+                       if (tp->fastpath_skb_hint != NULL &&
+                           after(TCP_SKB_CB(tp->fastpath_skb_hint)->seq,
+                                 TCP_SKB_CB(skb)->seq)) {
+                               tp->fastpath_cnt_hint -= diff;
+                               if ((int)tp->fastpath_cnt_hint < 0)
+                                       tp->fastpath_cnt_hint = 0;
+                       }
                }
        }
 
index d9323dfff82620487b413ce9e6b61fa426108e37..86624fabc4bf416c501c3ea1f10124b93c0be295 100644 (file)
@@ -6,8 +6,7 @@
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * the Free Software Foundation; either version 2 of the License.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 #include <linux/tcp.h>
 #include <linux/proc_fs.h>
 #include <linux/module.h>
-#include <linux/kfifo.h>
 #include <linux/ktime.h>
 #include <linux/time.h>
-#include <linux/vmalloc.h>
 
 #include <net/tcp.h>
 
 MODULE_AUTHOR("Stephen Hemminger <shemminger@linux-foundation.org>");
 MODULE_DESCRIPTION("TCP cwnd snooper");
 MODULE_LICENSE("GPL");
+MODULE_VERSION("1.1");
 
 static int port __read_mostly = 0;
 MODULE_PARM_DESC(port, "Port to match (0=all)");
 module_param(port, int, 0);
 
-static int bufsize __read_mostly = 64*1024;
-MODULE_PARM_DESC(bufsize, "Log buffer size (default 64k)");
+static int bufsize __read_mostly = 4096;
+MODULE_PARM_DESC(bufsize, "Log buffer size in packets (4096)");
 module_param(bufsize, int, 0);
 
 static int full __read_mostly;
@@ -50,39 +48,38 @@ module_param(full, int, 0);
 
 static const char procname[] = "tcpprobe";
 
-struct {
-       struct kfifo    *fifo;
+struct tcp_log {
+       ktime_t tstamp;
+       __be32  saddr, daddr;
+       __be16  sport, dport;
+       u16     length;
+       u32     snd_nxt;
+       u32     snd_una;
+       u32     snd_wnd;
+       u32     snd_cwnd;
+       u32     ssthresh;
+       u32     srtt;
+};
+
+static struct {
        spinlock_t      lock;
        wait_queue_head_t wait;
        ktime_t         start;
        u32             lastcwnd;
-} tcpw;
 
-/*
- * Print to log with timestamps.
- * FIXME: causes an extra copy
- */
-static void printl(const char *fmt, ...)
-       __attribute__ ((format (printf, 1, 2)));
+       unsigned long   head, tail;
+       struct tcp_log  *log;
+} tcp_probe;
+
 
-static void printl(const char *fmt, ...)
+static inline int tcp_probe_used(void)
 {
-       va_list args;
-       int len;
-       struct timespec tv;
-       char tbuf[256];
-
-       va_start(args, fmt);
-       /* want monotonic time since start of tcp_probe */
-       tv = ktime_to_timespec(ktime_sub(ktime_get(), tcpw.start));
-
-       len = sprintf(tbuf, "%lu.%09lu ",
-                     (unsigned long) tv.tv_sec, (unsigned long) tv.tv_nsec);
-       len += vscnprintf(tbuf+len, sizeof(tbuf)-len, fmt, args);
-       va_end(args);
-
-       kfifo_put(tcpw.fifo, tbuf, len);
-       wake_up(&tcpw.wait);
+       return (tcp_probe.head - tcp_probe.tail) % bufsize;
+}
+
+static inline int tcp_probe_avail(void)
+{
+       return bufsize - tcp_probe_used();
 }
 
 /*
@@ -97,63 +94,117 @@ static int jtcp_rcv_established(struct sock *sk, struct sk_buff *skb,
 
        /* Only update if port matches */
        if ((port == 0 || ntohs(inet->dport) == port || ntohs(inet->sport) == port)
-           && (full || tp->snd_cwnd != tcpw.lastcwnd)) {
-               printl("%d.%d.%d.%d:%u %d.%d.%d.%d:%u %d %#x %#x %u %u %u %u\n",
-                      NIPQUAD(inet->saddr), ntohs(inet->sport),
-                      NIPQUAD(inet->daddr), ntohs(inet->dport),
-                      skb->len, tp->snd_nxt, tp->snd_una,
-                      tp->snd_cwnd, tcp_current_ssthresh(sk),
-                      tp->snd_wnd, tp->srtt >> 3);
-               tcpw.lastcwnd = tp->snd_cwnd;
+           && (full || tp->snd_cwnd != tcp_probe.lastcwnd)) {
+
+               spin_lock(&tcp_probe.lock);
+               /* If log fills, just silently drop */
+               if (tcp_probe_avail() > 1) {
+                       struct tcp_log *p = tcp_probe.log + tcp_probe.head;
+
+                       p->tstamp = ktime_get();
+                       p->saddr = inet->saddr;
+                       p->sport = inet->sport;
+                       p->daddr = inet->daddr;
+                       p->dport = inet->dport;
+                       p->length = skb->len;
+                       p->snd_nxt = tp->snd_nxt;
+                       p->snd_una = tp->snd_una;
+                       p->snd_cwnd = tp->snd_cwnd;
+                       p->snd_wnd = tp->snd_wnd;
+                       p->srtt = tp->srtt >> 3;
+
+                       tcp_probe.head = (tcp_probe.head + 1) % bufsize;
+               }
+               tcp_probe.lastcwnd = tp->snd_cwnd;
+               spin_unlock(&tcp_probe.lock);
+
+               wake_up(&tcp_probe.wait);
        }
 
        jprobe_return();
        return 0;
 }
 
-static struct jprobe tcp_probe = {
+static struct jprobe tcp_jprobe = {
        .kp = {
                .symbol_name    = "tcp_rcv_established",
        },
        .entry  = JPROBE_ENTRY(jtcp_rcv_established),
 };
 
-
 static int tcpprobe_open(struct inode * inode, struct file * file)
 {
-       kfifo_reset(tcpw.fifo);
-       tcpw.start = ktime_get();
+       /* Reset (empty) log */
+       spin_lock_bh(&tcp_probe.lock);
+       tcp_probe.head = tcp_probe.tail = 0;
+       tcp_probe.start = ktime_get();
+       spin_unlock_bh(&tcp_probe.lock);
+
        return 0;
 }
 
+static int tcpprobe_sprint(char *tbuf, int n)
+{
+       const struct tcp_log *p
+               = tcp_probe.log + tcp_probe.tail % bufsize;
+       struct timespec tv
+               = ktime_to_timespec(ktime_sub(p->tstamp, tcp_probe.start));
+
+       return snprintf(tbuf, n,
+                       "%lu.%09lu %d.%d.%d.%d:%u %d.%d.%d.%d:%u"
+                       " %d %#x %#x %u %u %u %u\n",
+                       (unsigned long) tv.tv_sec,
+                       (unsigned long) tv.tv_nsec,
+                       NIPQUAD(p->saddr), ntohs(p->sport),
+                       NIPQUAD(p->daddr), ntohs(p->dport),
+                       p->length, p->snd_nxt, p->snd_una,
+                       p->snd_cwnd, p->ssthresh, p->snd_wnd, p->srtt);
+}
+
 static ssize_t tcpprobe_read(struct file *file, char __user *buf,
                             size_t len, loff_t *ppos)
 {
        int error = 0, cnt = 0;
-       unsigned char *tbuf;
 
        if (!buf || len < 0)
                return -EINVAL;
 
-       if (len == 0)
-               return 0;
+       while (cnt < len) {
+               char tbuf[128];
+               int width;
+
+               /* Wait for data in buffer */
+               error = wait_event_interruptible(tcp_probe.wait,
+                                                tcp_probe_used() > 0);
+               if (error)
+                       break;
 
-       tbuf = vmalloc(len);
-       if (!tbuf)
-               return -ENOMEM;
+               spin_lock_bh(&tcp_probe.lock);
+               if (tcp_probe.head == tcp_probe.tail) {
+                       /* multiple readers race? */
+                       spin_unlock_bh(&tcp_probe.lock);
+                       continue;
+               }
 
-       error = wait_event_interruptible(tcpw.wait,
-                                        __kfifo_len(tcpw.fifo) != 0);
-       if (error)
-               goto out_free;
+               width = tcpprobe_sprint(tbuf, sizeof(tbuf));
 
-       cnt = kfifo_get(tcpw.fifo, tbuf, len);
-       error = copy_to_user(buf, tbuf, cnt);
+               if (width < len)
+                       tcp_probe.tail = (tcp_probe.tail + 1) % bufsize;
 
-out_free:
-       vfree(tbuf);
+               spin_unlock_bh(&tcp_probe.lock);
+
+               /* if record greater than space available
+                  return partial buffer (so far) */
+               if (width >= len)
+                       break;
+
+               error = copy_to_user(buf + cnt, tbuf, width);
+               if (error)
+                       break;
+               cnt += width;
+       }
 
-       return error ? error : cnt;
+       return cnt == 0 ? error : cnt;
 }
 
 static const struct file_operations tcpprobe_fops = {
@@ -166,34 +217,37 @@ static __init int tcpprobe_init(void)
 {
        int ret = -ENOMEM;
 
-       init_waitqueue_head(&tcpw.wait);
-       spin_lock_init(&tcpw.lock);
-       tcpw.fifo = kfifo_alloc(bufsize, GFP_KERNEL, &tcpw.lock);
-       if (IS_ERR(tcpw.fifo))
-               return PTR_ERR(tcpw.fifo);
+       init_waitqueue_head(&tcp_probe.wait);
+       spin_lock_init(&tcp_probe.lock);
+
+       if (bufsize < 0)
+               return -EINVAL;
+
+       tcp_probe.log = kcalloc(sizeof(struct tcp_log), bufsize, GFP_KERNEL);
+       if (!tcp_probe.log)
+               goto err0;
 
        if (!proc_net_fops_create(procname, S_IRUSR, &tcpprobe_fops))
                goto err0;
 
-       ret = register_jprobe(&tcp_probe);
+       ret = register_jprobe(&tcp_jprobe);
        if (ret)
                goto err1;
 
-       pr_info("TCP watch registered (port=%d)\n", port);
+       pr_info("TCP probe registered (port=%d)\n", port);
        return 0;
  err1:
        proc_net_remove(procname);
  err0:
-       kfifo_free(tcpw.fifo);
+       kfree(tcp_probe.log);
        return ret;
 }
 module_init(tcpprobe_init);
 
 static __exit void tcpprobe_exit(void)
 {
-       kfifo_free(tcpw.fifo);
        proc_net_remove(procname);
-       unregister_jprobe(&tcp_probe);
-
+       unregister_jprobe(&tcp_jprobe);
+       kfree(tcp_probe.log);
 }
 module_exit(tcpprobe_exit);
index facb7e29304e7df9a7a172d2e4ad2f63acfa1074..28355350fb62f11b008751769c95b31a22c42039 100644 (file)
@@ -70,6 +70,7 @@
  *     Alexey Kuznetsov:               allow both IPv4 and IPv6 sockets to bind
  *                                     a single port at the same time.
  *     Derek Atkins <derek@ihtfp.com>: Add Encapulation Support
+ *     James Chapman           :       Add L2TP encapsulation type.
  *
  *
  *             This program is free software; you can redistribute it and/or
@@ -919,104 +920,6 @@ int udp_disconnect(struct sock *sk, int flags)
        return 0;
 }
 
-/* return:
- *     1  if the UDP system should process it
- *     0  if we should drop this packet
- *     -1 if it should get processed by xfrm4_rcv_encap
- */
-static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb)
-{
-#ifndef CONFIG_XFRM
-       return 1;
-#else
-       struct udp_sock *up = udp_sk(sk);
-       struct udphdr *uh;
-       struct iphdr *iph;
-       int iphlen, len;
-
-       __u8 *udpdata;
-       __be32 *udpdata32;
-       __u16 encap_type = up->encap_type;
-
-       /* if we're overly short, let UDP handle it */
-       len = skb->len - sizeof(struct udphdr);
-       if (len <= 0)
-               return 1;
-
-       /* if this is not encapsulated socket, then just return now */
-       if (!encap_type)
-               return 1;
-
-       /* If this is a paged skb, make sure we pull up
-        * whatever data we need to look at. */
-       if (!pskb_may_pull(skb, sizeof(struct udphdr) + min(len, 8)))
-               return 1;
-
-       /* Now we can get the pointers */
-       uh = udp_hdr(skb);
-       udpdata = (__u8 *)uh + sizeof(struct udphdr);
-       udpdata32 = (__be32 *)udpdata;
-
-       switch (encap_type) {
-       default:
-       case UDP_ENCAP_ESPINUDP:
-               /* Check if this is a keepalive packet.  If so, eat it. */
-               if (len == 1 && udpdata[0] == 0xff) {
-                       return 0;
-               } else if (len > sizeof(struct ip_esp_hdr) && udpdata32[0] != 0) {
-                       /* ESP Packet without Non-ESP header */
-                       len = sizeof(struct udphdr);
-               } else
-                       /* Must be an IKE packet.. pass it through */
-                       return 1;
-               break;
-       case UDP_ENCAP_ESPINUDP_NON_IKE:
-               /* Check if this is a keepalive packet.  If so, eat it. */
-               if (len == 1 && udpdata[0] == 0xff) {
-                       return 0;
-               } else if (len > 2 * sizeof(u32) + sizeof(struct ip_esp_hdr) &&
-                          udpdata32[0] == 0 && udpdata32[1] == 0) {
-
-                       /* ESP Packet with Non-IKE marker */
-                       len = sizeof(struct udphdr) + 2 * sizeof(u32);
-               } else
-                       /* Must be an IKE packet.. pass it through */
-                       return 1;
-               break;
-       }
-
-       /* At this point we are sure that this is an ESPinUDP packet,
-        * so we need to remove 'len' bytes from the packet (the UDP
-        * header and optional ESP marker bytes) and then modify the
-        * protocol to ESP, and then call into the transform receiver.
-        */
-       if (skb_cloned(skb) && pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
-               return 0;
-
-       /* Now we can update and verify the packet length... */
-       iph = ip_hdr(skb);
-       iphlen = iph->ihl << 2;
-       iph->tot_len = htons(ntohs(iph->tot_len) - len);
-       if (skb->len < iphlen + len) {
-               /* packet is too small!?! */
-               return 0;
-       }
-
-       /* pull the data buffer up to the ESP header and set the
-        * transport header to point to ESP.  Keep UDP on the stack
-        * for later.
-        */
-       __skb_pull(skb, len);
-       skb_reset_transport_header(skb);
-
-       /* modify the protocol (it's ESP!) */
-       iph->protocol = IPPROTO_ESP;
-
-       /* and let the caller know to send this into the ESP processor... */
-       return -1;
-#endif
-}
-
 /* returns:
  *  -1: error
  *   0: success
@@ -1039,28 +942,28 @@ int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
 
        if (up->encap_type) {
                /*
-                * This is an encapsulation socket, so let's see if this is
-                * an encapsulated packet.
-                * If it's a keepalive packet, then just eat it.
-                * If it's an encapsulateed packet, then pass it to the
-                * IPsec xfrm input and return the response
-                * appropriately.  Otherwise, just fall through and
-                * pass this up the UDP socket.
+                * This is an encapsulation socket so pass the skb to
+                * the socket's udp_encap_rcv() hook. Otherwise, just
+                * fall through and pass this up the UDP socket.
+                * up->encap_rcv() returns the following value:
+                * =0 if skb was successfully passed to the encap
+                *    handler or was discarded by it.
+                * >0 if skb should be passed on to UDP.
+                * <0 if skb should be resubmitted as proto -N
                 */
-               int ret;
 
-               ret = udp_encap_rcv(sk, skb);
-               if (ret == 0) {
-                       /* Eat the packet .. */
-                       kfree_skb(skb);
-                       return 0;
-               }
-               if (ret < 0) {
-                       /* process the ESP packet */
-                       ret = xfrm4_rcv_encap(skb, up->encap_type);
-                       UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS, up->pcflag);
-                       return -ret;
+               /* if we're overly short, let UDP handle it */
+               if (skb->len > sizeof(struct udphdr) &&
+                   up->encap_rcv != NULL) {
+                       int ret;
+
+                       ret = (*up->encap_rcv)(sk, skb);
+                       if (ret <= 0) {
+                               UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS, up->pcflag);
+                               return -ret;
+                       }
                }
+
                /* FALLTHROUGH -- it's a UDP Packet */
        }
 
@@ -1349,6 +1252,9 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
                case 0:
                case UDP_ENCAP_ESPINUDP:
                case UDP_ENCAP_ESPINUDP_NON_IKE:
+                       up->encap_rcv = xfrm4_udp_encap_rcv;
+                       /* FALLTHROUGH */
+               case UDP_ENCAP_L2TPINUDP:
                        up->encap_type = val;
                        break;
                default:
index fa1902dc81b86e1c20f24451c5bf515567e9015f..2fa108245413d38bd7c88fac7c71e570e98e40b9 100644 (file)
 #include <net/ip.h>
 #include <net/xfrm.h>
 
-int xfrm4_rcv(struct sk_buff *skb)
-{
-       return xfrm4_rcv_encap(skb, 0);
-}
-
-EXPORT_SYMBOL(xfrm4_rcv);
-
 static int xfrm4_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq)
 {
        switch (nexthdr) {
@@ -53,7 +46,7 @@ drop:
 }
 #endif
 
-int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
+static int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
 {
        __be32 spi, seq;
        struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH];
@@ -167,3 +160,108 @@ drop:
        kfree_skb(skb);
        return 0;
 }
+
+/* If it's a keepalive packet, then just eat it.
+ * If it's an encapsulated packet, then pass it to the
+ * IPsec xfrm input.
+ * Returns 0 if skb passed to xfrm or was dropped.
+ * Returns >0 if skb should be passed to UDP.
+ * Returns <0 if skb should be resubmitted (-ret is protocol)
+ */
+int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
+{
+       struct udp_sock *up = udp_sk(sk);
+       struct udphdr *uh;
+       struct iphdr *iph;
+       int iphlen, len;
+       int ret;
+
+       __u8 *udpdata;
+       __be32 *udpdata32;
+       __u16 encap_type = up->encap_type;
+
+       /* if this is not encapsulated socket, then just return now */
+       if (!encap_type)
+               return 1;
+
+       /* If this is a paged skb, make sure we pull up
+        * whatever data we need to look at. */
+       len = skb->len - sizeof(struct udphdr);
+       if (!pskb_may_pull(skb, sizeof(struct udphdr) + min(len, 8)))
+               return 1;
+
+       /* Now we can get the pointers */
+       uh = udp_hdr(skb);
+       udpdata = (__u8 *)uh + sizeof(struct udphdr);
+       udpdata32 = (__be32 *)udpdata;
+
+       switch (encap_type) {
+       default:
+       case UDP_ENCAP_ESPINUDP:
+               /* Check if this is a keepalive packet.  If so, eat it. */
+               if (len == 1 && udpdata[0] == 0xff) {
+                       goto drop;
+               } else if (len > sizeof(struct ip_esp_hdr) && udpdata32[0] != 0) {
+                       /* ESP Packet without Non-ESP header */
+                       len = sizeof(struct udphdr);
+               } else
+                       /* Must be an IKE packet.. pass it through */
+                       return 1;
+               break;
+       case UDP_ENCAP_ESPINUDP_NON_IKE:
+               /* Check if this is a keepalive packet.  If so, eat it. */
+               if (len == 1 && udpdata[0] == 0xff) {
+                       goto drop;
+               } else if (len > 2 * sizeof(u32) + sizeof(struct ip_esp_hdr) &&
+                          udpdata32[0] == 0 && udpdata32[1] == 0) {
+
+                       /* ESP Packet with Non-IKE marker */
+                       len = sizeof(struct udphdr) + 2 * sizeof(u32);
+               } else
+                       /* Must be an IKE packet.. pass it through */
+                       return 1;
+               break;
+       }
+
+       /* At this point we are sure that this is an ESPinUDP packet,
+        * so we need to remove 'len' bytes from the packet (the UDP
+        * header and optional ESP marker bytes) and then modify the
+        * protocol to ESP, and then call into the transform receiver.
+        */
+       if (skb_cloned(skb) && pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
+               goto drop;
+
+       /* Now we can update and verify the packet length... */
+       iph = ip_hdr(skb);
+       iphlen = iph->ihl << 2;
+       iph->tot_len = htons(ntohs(iph->tot_len) - len);
+       if (skb->len < iphlen + len) {
+               /* packet is too small!?! */
+               goto drop;
+       }
+
+       /* pull the data buffer up to the ESP header and set the
+        * transport header to point to ESP.  Keep UDP on the stack
+        * for later.
+        */
+       __skb_pull(skb, len);
+       skb_reset_transport_header(skb);
+
+       /* modify the protocol (it's ESP!) */
+       iph->protocol = IPPROTO_ESP;
+
+       /* process ESP */
+       ret = xfrm4_rcv_encap(skb, encap_type);
+       return ret;
+
+drop:
+       kfree_skb(skb);
+       return 0;
+}
+
+int xfrm4_rcv(struct sk_buff *skb)
+{
+       return xfrm4_rcv_encap(skb, 0);
+}
+
+EXPORT_SYMBOL(xfrm4_rcv);
index 568510304553d14c82807eb8e29b81b8f9381079..9275c79119b6f32d9bb69c7c64d9be853378eb7b 100644 (file)
@@ -109,3 +109,4 @@ static void __exit ipip_fini(void)
 module_init(ipip_init);
 module_exit(ipip_fini);
 MODULE_LICENSE("GPL");
+MODULE_ALIAS_XFRM_TYPE(AF_INET, XFRM_PROTO_IPIP);
index 8e5d54f23b49398465b34797d2a20a919c947119..eb0b8085949b64620241de94be4815a1a303887d 100644 (file)
@@ -109,7 +109,7 @@ config INET6_IPCOMP
          If unsure, say Y.
 
 config IPV6_MIP6
-       bool "IPv6: Mobility (EXPERIMENTAL)"
+       tristate "IPv6: Mobility (EXPERIMENTAL)"
        depends on IPV6 && EXPERIMENTAL
        select XFRM
        ---help---
index bb33309044c9d01830f0b5ae323ae2efe966f326..87c23a73d28426f8d3dba9d5cdbfa1303835609f 100644 (file)
@@ -14,7 +14,6 @@ ipv6-$(CONFIG_XFRM) += xfrm6_policy.o xfrm6_state.o xfrm6_input.o \
        xfrm6_output.o
 ipv6-$(CONFIG_NETFILTER) += netfilter.o
 ipv6-$(CONFIG_IPV6_MULTIPLE_TABLES) += fib6_rules.o
-ipv6-$(CONFIG_IPV6_MIP6) += mip6.o
 ipv6-$(CONFIG_PROC_FS) += proc.o
 
 ipv6-objs += $(ipv6-y)
@@ -28,6 +27,7 @@ obj-$(CONFIG_INET6_XFRM_MODE_TRANSPORT) += xfrm6_mode_transport.o
 obj-$(CONFIG_INET6_XFRM_MODE_TUNNEL) += xfrm6_mode_tunnel.o
 obj-$(CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION) += xfrm6_mode_ro.o
 obj-$(CONFIG_INET6_XFRM_MODE_BEET) += xfrm6_mode_beet.o
+obj-$(CONFIG_IPV6_MIP6) += mip6.o
 obj-$(CONFIG_NETFILTER)        += netfilter/
 
 obj-$(CONFIG_IPV6_SIT) += sit.o
index f96ed76d8fa4be902ea922f113bb6a18dab6010b..24424c3b7dc0e5918bb0b35295db8f73d0ee7591 100644 (file)
@@ -1034,7 +1034,7 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev,
                        }
 
                        /* Rule 4: Prefer home address */
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
                        if (hiscore.rule < 4) {
                                if (ifa_result->flags & IFA_F_HOMEADDRESS)
                                        hiscore.attrs |= IPV6_SADDR_SCORE_HOA;
@@ -2268,6 +2268,9 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
                break;
        case NETDEV_UP:
        case NETDEV_CHANGE:
+               if (dev->flags & IFF_SLAVE)
+                       break;
+
                if (event == NETDEV_UP) {
                        if (!netif_carrier_ok(dev)) {
                                /* device is not ready yet. */
@@ -2782,7 +2785,7 @@ static int if6_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations if6_seq_ops = {
+static const struct seq_operations if6_seq_ops = {
        .start  = if6_seq_start,
        .next   = if6_seq_next,
        .show   = if6_seq_show,
@@ -2832,7 +2835,7 @@ void if6_proc_exit(void)
 }
 #endif /* CONFIG_PROC_FS */
 
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 /* Check if address is a home address configured on any interface. */
 int ipv6_chk_home_addr(struct in6_addr *addr)
 {
@@ -4240,7 +4243,6 @@ errout:
 void __exit addrconf_cleanup(void)
 {
        struct net_device *dev;
-       struct inet6_dev *idev;
        struct inet6_ifaddr *ifa;
        int i;
 
@@ -4258,7 +4260,7 @@ void __exit addrconf_cleanup(void)
         */
 
        for_each_netdev(dev) {
-               if ((idev = __in6_dev_get(dev)) == NULL)
+               if (__in6_dev_get(dev) == NULL)
                        continue;
                addrconf_ifdown(dev, 1);
        }
index 6dd377253cf77dbc615d436ef123e7323d3ee1cc..eed09373a45d8cb9685ae28eebcaa761b5ef557e 100644 (file)
@@ -58,9 +58,6 @@
 #ifdef CONFIG_IPV6_TUNNEL
 #include <net/ip6_tunnel.h>
 #endif
-#ifdef CONFIG_IPV6_MIP6
-#include <net/mip6.h>
-#endif
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -853,9 +850,6 @@ static int __init inet6_init(void)
        ipv6_frag_init();
        ipv6_nodata_init();
        ipv6_destopt_init();
-#ifdef CONFIG_IPV6_MIP6
-       mip6_init();
-#endif
 
        /* Init v6 transport protocols. */
        udpv6_init();
@@ -921,9 +915,7 @@ static void __exit inet6_exit(void)
 
        /* Cleanup code parts. */
        ipv6_packet_cleanup();
-#ifdef CONFIG_IPV6_MIP6
-       mip6_fini();
-#endif
+
        addrconf_cleanup();
        ip6_flowlabel_cleanup();
        ip6_route_cleanup();
index 128f94c79c641e462d62e3a762e92b00ab2fb0dc..53f46ab6af7062528e907cf3a2e4676f2fd12afe 100644 (file)
@@ -74,7 +74,7 @@ bad:
        return 0;
 }
 
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 /**
  *     ipv6_rearrange_destopt - rearrange IPv6 destination options header
  *     @iph: IPv6 header
@@ -132,6 +132,8 @@ static void ipv6_rearrange_destopt(struct ipv6hdr *iph, struct ipv6_opt_hdr *des
 bad:
        return;
 }
+#else
+static void ipv6_rearrange_destopt(struct ipv6hdr *iph, struct ipv6_opt_hdr *destopt) {}
 #endif
 
 /**
@@ -189,10 +191,8 @@ static int ipv6_clear_mutable_options(struct ipv6hdr *iph, int len, int dir)
        while (exthdr.raw < end) {
                switch (nexthdr) {
                case NEXTHDR_DEST:
-#ifdef CONFIG_IPV6_MIP6
                        if (dir == XFRM_POLICY_OUT)
                                ipv6_rearrange_destopt(iph, exthdr.opth);
-#endif
                case NEXTHDR_HOP:
                        if (!zero_out_mutable_opts(exthdr.opth)) {
                                LIMIT_NETDEBUG(
@@ -228,7 +228,7 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb)
        u8 nexthdr;
        char tmp_base[8];
        struct {
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
                struct in6_addr saddr;
 #endif
                struct in6_addr daddr;
@@ -255,7 +255,7 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb)
                        err = -ENOMEM;
                        goto error;
                }
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
                memcpy(tmp_ext, &top_iph->saddr, extlen);
 #else
                memcpy(tmp_ext, &top_iph->daddr, extlen);
@@ -294,7 +294,7 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb)
 
        memcpy(top_iph, tmp_base, sizeof(tmp_base));
        if (tmp_ext) {
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
                memcpy(&top_iph->saddr, tmp_ext, extlen);
 #else
                memcpy(&top_iph->daddr, tmp_ext, extlen);
@@ -554,3 +554,4 @@ module_init(ah6_init);
 module_exit(ah6_fini);
 
 MODULE_LICENSE("GPL");
+MODULE_ALIAS_XFRM_TYPE(AF_INET6, XFRM_PROTO_AH);
index 9b81264eb78f2b0fcdf336f1b52c1df02f094be1..b8c533fbdb63f0ab320b7d27735f2e5a6ea2b040 100644 (file)
@@ -539,7 +539,7 @@ static int ac6_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations ac6_seq_ops = {
+static const struct seq_operations ac6_seq_ops = {
        .start  =       ac6_seq_start,
        .next   =       ac6_seq_next,
        .stop   =       ac6_seq_stop,
index b1fe7ac5dc9006795e871621179bf4d20f58cd9b..fe0f49024a0a213a843cb854404ea428ebcca350 100644 (file)
@@ -657,11 +657,10 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
                        rthdr = (struct ipv6_rt_hdr *)CMSG_DATA(cmsg);
 
                        switch (rthdr->type) {
-                       case IPV6_SRCRT_TYPE_0:
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
                        case IPV6_SRCRT_TYPE_2:
-#endif
                                break;
+#endif
                        default:
                                err = -EINVAL;
                                goto exit_f;
index 7107bb7e2e62561c440f0a23c87edcf0da03c38d..2db31ce3c7e61302dc66ad12054f009898547e47 100644 (file)
@@ -421,3 +421,4 @@ module_init(esp6_init);
 module_exit(esp6_fini);
 
 MODULE_LICENSE("GPL");
+MODULE_ALIAS_XFRM_TYPE(AF_INET6, XFRM_PROTO_ESP);
index 14be0b9b77a5f998614351e1c5dbc92a31f94df0..c82d4d49f71f1aff4eada6daaa69f8718bbbe019 100644 (file)
@@ -42,7 +42,7 @@
 #include <net/ndisc.h>
 #include <net/ip6_route.h>
 #include <net/addrconf.h>
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 #include <net/xfrm.h>
 #endif
 
@@ -90,6 +90,7 @@ int ipv6_find_tlv(struct sk_buff *skb, int offset, int type)
  bad:
        return -1;
 }
+EXPORT_SYMBOL_GPL(ipv6_find_tlv);
 
 /*
  *     Parsing tlv encoded headers.
@@ -196,7 +197,7 @@ bad:
   Destination options header.
  *****************************/
 
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 static int ipv6_dest_hao(struct sk_buff **skbp, int optoff)
 {
        struct sk_buff *skb = *skbp;
@@ -270,7 +271,7 @@ static int ipv6_dest_hao(struct sk_buff **skbp, int optoff)
 #endif
 
 static struct tlvtype_proc tlvprocdestopt_lst[] = {
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
        {
                .type   = IPV6_TLV_HAO,
                .func   = ipv6_dest_hao,
@@ -283,7 +284,7 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp)
 {
        struct sk_buff *skb = *skbp;
        struct inet6_skb_parm *opt = IP6CB(skb);
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
        __u16 dstbuf;
 #endif
        struct dst_entry *dst;
@@ -298,7 +299,7 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp)
        }
 
        opt->lastopt = opt->dst1 = skb_network_header_len(skb);
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
        dstbuf = opt->dst1;
 #endif
 
@@ -308,7 +309,7 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp)
                skb = *skbp;
                skb->transport_header += (skb_transport_header(skb)[1] + 1) << 3;
                opt = IP6CB(skb);
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
                opt->nhoff = dstbuf;
 #else
                opt->nhoff = opt->dst1;
@@ -371,22 +372,13 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp)
        struct rt0_hdr *rthdr;
        int accept_source_route = ipv6_devconf.accept_source_route;
 
-       if (accept_source_route < 0 ||
-           ((idev = in6_dev_get(skb->dev)) == NULL)) {
-               kfree_skb(skb);
-               return -1;
-       }
-       if (idev->cnf.accept_source_route < 0) {
+       idev = in6_dev_get(skb->dev);
+       if (idev) {
+               if (accept_source_route > idev->cnf.accept_source_route)
+                       accept_source_route = idev->cnf.accept_source_route;
                in6_dev_put(idev);
-               kfree_skb(skb);
-               return -1;
        }
 
-       if (accept_source_route > idev->cnf.accept_source_route)
-               accept_source_route = idev->cnf.accept_source_route;
-
-       in6_dev_put(idev);
-
        if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) ||
            !pskb_may_pull(skb, (skb_transport_offset(skb) +
                                 ((skb_transport_header(skb)[1] + 1) << 3)))) {
@@ -398,24 +390,6 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp)
 
        hdr = (struct ipv6_rt_hdr *)skb_transport_header(skb);
 
-       switch (hdr->type) {
-#ifdef CONFIG_IPV6_MIP6
-       case IPV6_SRCRT_TYPE_2:
-               break;
-#endif
-       case IPV6_SRCRT_TYPE_0:
-               if (accept_source_route > 0)
-                       break;
-               kfree_skb(skb);
-               return -1;
-       default:
-               IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
-                                IPSTATS_MIB_INHDRERRORS);
-               icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
-                                 (&hdr->type) - skb_network_header(skb));
-               return -1;
-       }
-
        if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr) ||
            skb->pkt_type != PACKET_HOST) {
                IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
@@ -427,7 +401,7 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp)
 looped_back:
        if (hdr->segments_left == 0) {
                switch (hdr->type) {
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
                case IPV6_SRCRT_TYPE_2:
                        /* Silently discard type 2 header unless it was
                         * processed by own
@@ -453,18 +427,10 @@ looped_back:
        }
 
        switch (hdr->type) {
-       case IPV6_SRCRT_TYPE_0:
-               if (hdr->hdrlen & 0x01) {
-                       IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
-                                        IPSTATS_MIB_INHDRERRORS);
-                       icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
-                                         ((&hdr->hdrlen) -
-                                          skb_network_header(skb)));
-                       return -1;
-               }
-               break;
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
        case IPV6_SRCRT_TYPE_2:
+               if (accept_source_route < 0)
+                       goto unknown_rh;
                /* Silently discard invalid RTH type 2 */
                if (hdr->hdrlen != 2 || hdr->segments_left != 1) {
                        IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
@@ -474,6 +440,8 @@ looped_back:
                }
                break;
 #endif
+       default:
+               goto unknown_rh;
        }
 
        /*
@@ -520,7 +488,7 @@ looped_back:
        addr += i - 1;
 
        switch (hdr->type) {
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
        case IPV6_SRCRT_TYPE_2:
                if (xfrm6_input_addr(skb, (xfrm_address_t *)addr,
                                     (xfrm_address_t *)&ipv6_hdr(skb)->saddr,
@@ -577,6 +545,12 @@ looped_back:
        skb_push(skb, skb->data - skb_network_header(skb));
        dst_input(skb);
        return -1;
+
+unknown_rh:
+       IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS);
+       icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
+                         (&hdr->type) - skb_network_header(skb));
+       return -1;
 }
 
 static struct inet6_protocol rthdr_protocol = {
@@ -590,72 +564,6 @@ void __init ipv6_rthdr_init(void)
                printk(KERN_ERR "ipv6_rthdr_init: Could not register protocol\n");
 };
 
-/*
-   This function inverts received rthdr.
-   NOTE: specs allow to make it automatically only if
-   packet authenticated.
-
-   I will not discuss it here (though, I am really pissed off at
-   this stupid requirement making rthdr idea useless)
-
-   Actually, it creates severe problems  for us.
-   Embryonic requests has no associated sockets,
-   so that user have no control over it and
-   cannot not only to set reply options, but
-   even to know, that someone wants to connect
-   without success. :-(
-
-   For now we need to test the engine, so that I created
-   temporary (or permanent) backdoor.
-   If listening socket set IPV6_RTHDR to 2, then we invert header.
-                                                  --ANK (980729)
- */
-
-struct ipv6_txoptions *
-ipv6_invert_rthdr(struct sock *sk, struct ipv6_rt_hdr *hdr)
-{
-       /* Received rthdr:
-
-          [ H1 -> H2 -> ... H_prev ]  daddr=ME
-
-          Inverted result:
-          [ H_prev -> ... -> H1 ] daddr =sender
-
-          Note, that IP output engine will rewrite this rthdr
-          by rotating it left by one addr.
-        */
-
-       int n, i;
-       struct rt0_hdr *rthdr = (struct rt0_hdr*)hdr;
-       struct rt0_hdr *irthdr;
-       struct ipv6_txoptions *opt;
-       int hdrlen = ipv6_optlen(hdr);
-
-       if (hdr->segments_left ||
-           hdr->type != IPV6_SRCRT_TYPE_0 ||
-           hdr->hdrlen & 0x01)
-               return NULL;
-
-       n = hdr->hdrlen >> 1;
-       opt = sock_kmalloc(sk, sizeof(*opt) + hdrlen, GFP_ATOMIC);
-       if (opt == NULL)
-               return NULL;
-       memset(opt, 0, sizeof(*opt));
-       opt->tot_len = sizeof(*opt) + hdrlen;
-       opt->srcrt = (void*)(opt+1);
-       opt->opt_nflen = hdrlen;
-
-       memcpy(opt->srcrt, hdr, sizeof(*hdr));
-       irthdr = (struct rt0_hdr*)opt->srcrt;
-       irthdr->reserved = 0;
-       opt->srcrt->segments_left = n;
-       for (i=0; i<n; i++)
-               memcpy(irthdr->addr+i, rthdr->addr+(n-1-i), 16);
-       return opt;
-}
-
-EXPORT_SYMBOL_GPL(ipv6_invert_rthdr);
-
 /**********************************
   Hop-by-hop options.
  **********************************/
index e9bcce9e7bdfb8bf59b74cf199fa16ac8c7a960e..4765a29f98a8e003b535ed7aedcf1b97d63b98e5 100644 (file)
@@ -272,7 +272,7 @@ static int icmpv6_getfrag(void *from, char *to, int offset, int len, int odd, st
        return 0;
 }
 
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 static void mip6_addr_swap(struct sk_buff *skb)
 {
        struct ipv6hdr *iph = ipv6_hdr(skb);
index c206a152ed9d8b4a1b82aa9df925f08ab3713458..413a4ebb195c728ea86990e038412941c7370ad7 100644 (file)
@@ -648,7 +648,7 @@ static int ip6fl_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations ip6fl_seq_ops = {
+static const struct seq_operations ip6fl_seq_ops = {
        .start  =       ip6fl_seq_start,
        .next   =       ip6fl_seq_next,
        .stop   =       ip6fl_seq_stop,
index 4704b5fc3085b9f8dab20bd5d1d36ea0b2d062a3..50d86e94d9ed3358bf8bad71ca36599adea63527 100644 (file)
@@ -521,6 +521,10 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from)
        to->tc_index = from->tc_index;
 #endif
        nf_copy(to, from);
+#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
+    defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
+       to->nf_trace = from->nf_trace;
+#endif
        skb_copy_secmark(to, from);
 }
 
@@ -543,7 +547,7 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
                        found_rhdr = 1;
                        break;
                case NEXTHDR_DEST:
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
                        if (ipv6_find_tlv(skb, offset, IPV6_TLV_HAO) >= 0)
                                break;
 #endif
index a0902fbdb4e1ebfa71ee3f4f4d349b0735e923e2..281aee42d3f0d9c35e26c1dac4863f59628c8b62 100644 (file)
@@ -883,8 +883,8 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
         */
        max_headroom += LL_RESERVED_SPACE(tdev);
 
-       if (skb_headroom(skb) < max_headroom ||
-           skb_cloned(skb) || skb_shared(skb)) {
+       if (skb_headroom(skb) < max_headroom || skb_shared(skb) ||
+           (skb_cloned(skb) && !skb_clone_writable(skb, 0))) {
                struct sk_buff *new_skb;
 
                if (!(new_skb = skb_realloc_headroom(skb, max_headroom)))
index 1ee50b5782e199c43dfaeadb81193c7c9d2adf1b..473f165310ea79c8e7a23c350126c2aee19d80eb 100644 (file)
@@ -500,4 +500,4 @@ MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("IP Payload Compression Protocol (IPComp) for IPv6 - RFC3173");
 MODULE_AUTHOR("Mitsuru KANDA <mk@linux-ipv6.org>");
 
-
+MODULE_ALIAS_XFRM_TYPE(AF_INET6, XFRM_PROTO_COMP);
index aa3d07c52a8fd18d44361d4a6f5fa2fd2d5c1612..d6846393182d4294dc08f30d9fa99921dd881319 100644 (file)
@@ -123,7 +123,7 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, int features)
        struct ipv6hdr *ipv6h;
        struct inet6_protocol *ops;
 
-       if (!(features & NETIF_F_HW_CSUM))
+       if (!(features & NETIF_F_V6_CSUM))
                features &= ~NETIF_F_SG;
 
        if (unlikely(skb_shinfo(skb)->gso_type &
@@ -336,16 +336,12 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
                break;
 
        case IPV6_RECVRTHDR:
-               if (val < 0 || val > 2)
-                       goto e_inval;
-               np->rxopt.bits.srcrt = val;
+               np->rxopt.bits.srcrt = valbool;
                retv = 0;
                break;
 
        case IPV6_2292RTHDR:
-               if (val < 0 || val > 2)
-                       goto e_inval;
-               np->rxopt.bits.osrcrt = val;
+               np->rxopt.bits.osrcrt = valbool;
                retv = 0;
                break;
 
@@ -416,11 +412,10 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
                if (optname == IPV6_RTHDR && opt && opt->srcrt) {
                        struct ipv6_rt_hdr *rthdr = opt->srcrt;
                        switch (rthdr->type) {
-                       case IPV6_SRCRT_TYPE_0:
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
                        case IPV6_SRCRT_TYPE_2:
-#endif
                                break;
+#endif
                        default:
                                goto sticky_done;
                        }
index 3e308fb41b49a8ff8f73b1666b724bab1325a8db..ae9881832a7ec548ae3c77456dc5089f01b49337 100644 (file)
@@ -2423,7 +2423,7 @@ static int igmp6_mc_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations igmp6_mc_seq_ops = {
+static const struct seq_operations igmp6_mc_seq_ops = {
        .start  =       igmp6_mc_seq_start,
        .next   =       igmp6_mc_seq_next,
        .stop   =       igmp6_mc_seq_stop,
@@ -2597,7 +2597,7 @@ static int igmp6_mcf_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations igmp6_mcf_seq_ops = {
+static const struct seq_operations igmp6_mcf_seq_ops = {
        .start  =       igmp6_mcf_seq_start,
        .next   =       igmp6_mcf_seq_next,
        .stop   =       igmp6_mcf_seq_stop,
index 13b7160fb8927b77b30bd6826f295169c71154e8..8a1399ce38ce826ae774a54508382adae905603f 100644 (file)
@@ -30,6 +30,7 @@
 #include <net/sock.h>
 #include <net/ipv6.h>
 #include <net/ip6_checksum.h>
+#include <net/rawv6.h>
 #include <net/xfrm.h>
 #include <net/mip6.h>
 
@@ -86,7 +87,7 @@ static int mip6_mh_len(int type)
        return len;
 }
 
-int mip6_mh_filter(struct sock *sk, struct sk_buff *skb)
+static int mip6_mh_filter(struct sock *sk, struct sk_buff *skb)
 {
        struct ip6_mh *mh;
 
@@ -471,7 +472,7 @@ static struct xfrm_type mip6_rthdr_type =
        .remote_addr    = mip6_xfrm_addr,
 };
 
-int __init mip6_init(void)
+static int __init mip6_init(void)
 {
        printk(KERN_INFO "Mobile IPv6\n");
 
@@ -483,18 +484,35 @@ int __init mip6_init(void)
                printk(KERN_INFO "%s: can't add xfrm type(rthdr)\n", __FUNCTION__);
                goto mip6_rthdr_xfrm_fail;
        }
+       if (rawv6_mh_filter_register(mip6_mh_filter) < 0) {
+               printk(KERN_INFO "%s: can't add rawv6 mh filter\n", __FUNCTION__);
+               goto mip6_rawv6_mh_fail;
+       }
+
+
        return 0;
 
+ mip6_rawv6_mh_fail:
+       xfrm_unregister_type(&mip6_rthdr_type, AF_INET6);
  mip6_rthdr_xfrm_fail:
        xfrm_unregister_type(&mip6_destopt_type, AF_INET6);
  mip6_destopt_xfrm_fail:
        return -EAGAIN;
 }
 
-void __exit mip6_fini(void)
+static void __exit mip6_fini(void)
 {
+       if (rawv6_mh_filter_unregister(mip6_mh_filter) < 0)
+               printk(KERN_INFO "%s: can't remove rawv6 mh filter\n", __FUNCTION__);
        if (xfrm_unregister_type(&mip6_rthdr_type, AF_INET6) < 0)
                printk(KERN_INFO "%s: can't remove xfrm type(rthdr)\n", __FUNCTION__);
        if (xfrm_unregister_type(&mip6_destopt_type, AF_INET6) < 0)
                printk(KERN_INFO "%s: can't remove xfrm type(destopt)\n", __FUNCTION__);
 }
+
+module_init(mip6_init);
+module_exit(mip6_fini);
+
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_XFRM_TYPE(AF_INET6, XFRM_PROTO_DSTOPTS);
+MODULE_ALIAS_XFRM_TYPE(AF_INET6, XFRM_PROTO_ROUTING);
index 9aa624026688f7c6788be787c7aaf68100d8f968..254c769b750a21b1a8062d469bfbf2fb8e7c8d5b 100644 (file)
@@ -96,13 +96,13 @@ ip6t_ext_hdr(u8 nexthdr)
 }
 
 /* Returns whether matches rule or not. */
-static inline int
+static inline bool
 ip6_packet_match(const struct sk_buff *skb,
                 const char *indev,
                 const char *outdev,
                 const struct ip6t_ip6 *ip6info,
                 unsigned int *protoff,
-                int *fragoff, int *hotdrop)
+                int *fragoff, bool *hotdrop)
 {
        size_t i;
        unsigned long ret;
@@ -122,7 +122,7 @@ ip6_packet_match(const struct sk_buff *skb,
                dprintf("DST: %u. Mask: %u. Target: %u.%s\n", ip->daddr,
                        ipinfo->dmsk.s_addr, ipinfo->dst.s_addr,
                        ipinfo->invflags & IP6T_INV_DSTIP ? " (INV)" : "");*/
-               return 0;
+               return false;
        }
 
        /* Look for ifname matches; this should unroll nicely. */
@@ -136,7 +136,7 @@ ip6_packet_match(const struct sk_buff *skb,
                dprintf("VIA in mismatch (%s vs %s).%s\n",
                        indev, ip6info->iniface,
                        ip6info->invflags&IP6T_INV_VIA_IN ?" (INV)":"");
-               return 0;
+               return false;
        }
 
        for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) {
@@ -149,7 +149,7 @@ ip6_packet_match(const struct sk_buff *skb,
                dprintf("VIA out mismatch (%s vs %s).%s\n",
                        outdev, ip6info->outiface,
                        ip6info->invflags&IP6T_INV_VIA_OUT ?" (INV)":"");
-               return 0;
+               return false;
        }
 
 /* ... might want to do something with class and flowlabel here ... */
@@ -162,8 +162,8 @@ ip6_packet_match(const struct sk_buff *skb,
                protohdr = ipv6_find_hdr(skb, protoff, -1, &_frag_off);
                if (protohdr < 0) {
                        if (_frag_off == 0)
-                               *hotdrop = 1;
-                       return 0;
+                               *hotdrop = true;
+                       return false;
                }
                *fragoff = _frag_off;
 
@@ -174,34 +174,34 @@ ip6_packet_match(const struct sk_buff *skb,
 
                if (ip6info->proto == protohdr) {
                        if(ip6info->invflags & IP6T_INV_PROTO) {
-                               return 0;
+                               return false;
                        }
-                       return 1;
+                       return true;
                }
 
                /* We need match for the '-p all', too! */
                if ((ip6info->proto != 0) &&
                        !(ip6info->invflags & IP6T_INV_PROTO))
-                       return 0;
+                       return false;
        }
-       return 1;
+       return true;
 }
 
 /* should be ip6 safe */
-static inline int
+static inline bool
 ip6_checkentry(const struct ip6t_ip6 *ipv6)
 {
        if (ipv6->flags & ~IP6T_F_MASK) {
                duprintf("Unknown flag bits set: %08X\n",
                         ipv6->flags & ~IP6T_F_MASK);
-               return 0;
+               return false;
        }
        if (ipv6->invflags & ~IP6T_INV_MASK) {
                duprintf("Unknown invflag bits set: %08X\n",
                         ipv6->invflags & ~IP6T_INV_MASK);
-               return 0;
+               return false;
        }
-       return 1;
+       return true;
 }
 
 static unsigned int
@@ -219,20 +219,20 @@ ip6t_error(struct sk_buff **pskb,
 }
 
 static inline
-int do_match(struct ip6t_entry_match *m,
-            const struct sk_buff *skb,
-            const struct net_device *in,
-            const struct net_device *out,
-            int offset,
-            unsigned int protoff,
-            int *hotdrop)
+bool do_match(struct ip6t_entry_match *m,
+             const struct sk_buff *skb,
+             const struct net_device *in,
+             const struct net_device *out,
+             int offset,
+             unsigned int protoff,
+             bool *hotdrop)
 {
        /* Stop iteration if it doesn't match */
        if (!m->u.kernel.match->match(skb, in, out, m->u.kernel.match, m->data,
                                      offset, protoff, hotdrop))
-               return 1;
+               return true;
        else
-               return 0;
+               return false;
 }
 
 static inline struct ip6t_entry *
@@ -241,6 +241,113 @@ get_entry(void *base, unsigned int offset)
        return (struct ip6t_entry *)(base + offset);
 }
 
+/* All zeroes == unconditional rule. */
+static inline int
+unconditional(const struct ip6t_ip6 *ipv6)
+{
+       unsigned int i;
+
+       for (i = 0; i < sizeof(*ipv6); i++)
+               if (((char *)ipv6)[i])
+                       break;
+
+       return (i == sizeof(*ipv6));
+}
+
+#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
+    defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
+/* This cries for unification! */
+static const char *hooknames[] = {
+       [NF_IP6_PRE_ROUTING]            = "PREROUTING",
+       [NF_IP6_LOCAL_IN]               = "INPUT",
+       [NF_IP6_FORWARD]                = "FORWARD",
+       [NF_IP6_LOCAL_OUT]              = "OUTPUT",
+       [NF_IP6_POST_ROUTING]           = "POSTROUTING",
+};
+
+enum nf_ip_trace_comments {
+       NF_IP6_TRACE_COMMENT_RULE,
+       NF_IP6_TRACE_COMMENT_RETURN,
+       NF_IP6_TRACE_COMMENT_POLICY,
+};
+
+static const char *comments[] = {
+       [NF_IP6_TRACE_COMMENT_RULE]     = "rule",
+       [NF_IP6_TRACE_COMMENT_RETURN]   = "return",
+       [NF_IP6_TRACE_COMMENT_POLICY]   = "policy",
+};
+
+static struct nf_loginfo trace_loginfo = {
+       .type = NF_LOG_TYPE_LOG,
+       .u = {
+               .log = {
+                       .level = 4,
+                       .logflags = NF_LOG_MASK,
+               },
+       },
+};
+
+static inline int
+get_chainname_rulenum(struct ip6t_entry *s, struct ip6t_entry *e,
+                     char *hookname, char **chainname,
+                     char **comment, unsigned int *rulenum)
+{
+       struct ip6t_standard_target *t = (void *)ip6t_get_target(s);
+
+       if (strcmp(t->target.u.kernel.target->name, IP6T_ERROR_TARGET) == 0) {
+               /* Head of user chain: ERROR target with chainname */
+               *chainname = t->target.data;
+               (*rulenum) = 0;
+       } else if (s == e) {
+               (*rulenum)++;
+
+               if (s->target_offset == sizeof(struct ip6t_entry)
+                  && strcmp(t->target.u.kernel.target->name,
+                            IP6T_STANDARD_TARGET) == 0
+                  && t->verdict < 0
+                  && unconditional(&s->ipv6)) {
+                       /* Tail of chains: STANDARD target (return/policy) */
+                       *comment = *chainname == hookname
+                               ? (char *)comments[NF_IP6_TRACE_COMMENT_POLICY]
+                               : (char *)comments[NF_IP6_TRACE_COMMENT_RETURN];
+               }
+               return 1;
+       } else
+               (*rulenum)++;
+
+       return 0;
+}
+
+static void trace_packet(struct sk_buff *skb,
+                        unsigned int hook,
+                        const struct net_device *in,
+                        const struct net_device *out,
+                        char *tablename,
+                        struct xt_table_info *private,
+                        struct ip6t_entry *e)
+{
+       void *table_base;
+       struct ip6t_entry *root;
+       char *hookname, *chainname, *comment;
+       unsigned int rulenum = 0;
+
+       table_base = (void *)private->entries[smp_processor_id()];
+       root = get_entry(table_base, private->hook_entry[hook]);
+
+       hookname = chainname = (char *)hooknames[hook];
+       comment = (char *)comments[NF_IP6_TRACE_COMMENT_RULE];
+
+       IP6T_ENTRY_ITERATE(root,
+                          private->size - private->hook_entry[hook],
+                          get_chainname_rulenum,
+                          e, hookname, &chainname, &comment, &rulenum);
+
+       nf_log_packet(AF_INET6, hook, skb, in, out, &trace_loginfo,
+                     "TRACE: %s:%s:%s:%u ",
+                     tablename, chainname, comment, rulenum);
+}
+#endif
+
 /* Returns one of the generic firewall policies, like NF_ACCEPT. */
 unsigned int
 ip6t_do_table(struct sk_buff **pskb,
@@ -252,7 +359,7 @@ ip6t_do_table(struct sk_buff **pskb,
        static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
        int offset = 0;
        unsigned int protoff = 0;
-       int hotdrop = 0;
+       bool hotdrop = false;
        /* Initializing verdict to NF_DROP keeps gcc happy. */
        unsigned int verdict = NF_DROP;
        const char *indev, *outdev;
@@ -298,6 +405,14 @@ ip6t_do_table(struct sk_buff **pskb,
 
                        t = ip6t_get_target(e);
                        IP_NF_ASSERT(t->u.kernel.target);
+
+#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
+    defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
+                       /* The packet is traced: log it */
+                       if (unlikely((*pskb)->nf_trace))
+                               trace_packet(*pskb, hook, in, out,
+                                            table->name, private, e);
+#endif
                        /* Standard target? */
                        if (!t->u.kernel.target->target) {
                                int v;
@@ -377,19 +492,6 @@ ip6t_do_table(struct sk_buff **pskb,
 #endif
 }
 
-/* All zeroes == unconditional rule. */
-static inline int
-unconditional(const struct ip6t_ip6 *ipv6)
-{
-       unsigned int i;
-
-       for (i = 0; i < sizeof(*ipv6); i++)
-               if (((char *)ipv6)[i])
-                       break;
-
-       return (i == sizeof(*ipv6));
-}
-
 /* Figures out from what hook each rule can be called: returns 0 if
    there are loops.  Puts hook bitmask in comefrom. */
 static int
@@ -1282,16 +1384,16 @@ void ip6t_unregister_table(struct xt_table *table)
 }
 
 /* Returns 1 if the type and code is matched by the range, 0 otherwise */
-static inline int
+static inline bool
 icmp6_type_code_match(u_int8_t test_type, u_int8_t min_code, u_int8_t max_code,
                     u_int8_t type, u_int8_t code,
-                    int invert)
+                    bool invert)
 {
        return (type == test_type && code >= min_code && code <= max_code)
                ^ invert;
 }
 
-static int
+static bool
 icmp6_match(const struct sk_buff *skb,
           const struct net_device *in,
           const struct net_device *out,
@@ -1299,22 +1401,22 @@ icmp6_match(const struct sk_buff *skb,
           const void *matchinfo,
           int offset,
           unsigned int protoff,
-          int *hotdrop)
+          bool *hotdrop)
 {
        struct icmp6hdr _icmp, *ic;
        const struct ip6t_icmp *icmpinfo = matchinfo;
 
        /* Must not be a fragment. */
        if (offset)
-               return 0;
+               return false;
 
        ic = skb_header_pointer(skb, protoff, sizeof(_icmp), &_icmp);
        if (ic == NULL) {
                /* We've been asked to examine this packet, and we
                   can't.  Hence, no choice but to drop. */
                duprintf("Dropping evil ICMP tinygram.\n");
-               *hotdrop = 1;
-               return 0;
+               *hotdrop = true;
+               return false;
        }
 
        return icmp6_type_code_match(icmpinfo->type,
@@ -1325,7 +1427,7 @@ icmp6_match(const struct sk_buff *skb,
 }
 
 /* Called when user tries to insert an entry of this type. */
-static int
+static bool
 icmp6_checkentry(const char *tablename,
           const void *entry,
           const struct xt_match *match,
@@ -1339,13 +1441,13 @@ icmp6_checkentry(const char *tablename,
 }
 
 /* The built-in targets: standard (NULL) and error. */
-static struct xt_target ip6t_standard_target = {
+static struct xt_target ip6t_standard_target __read_mostly = {
        .name           = IP6T_STANDARD_TARGET,
        .targetsize     = sizeof(int),
        .family         = AF_INET6,
 };
 
-static struct xt_target ip6t_error_target = {
+static struct xt_target ip6t_error_target __read_mostly = {
        .name           = IP6T_ERROR_TARGET,
        .target         = ip6t_error,
        .targetsize     = IP6T_FUNCTION_MAXNAMELEN,
@@ -1362,7 +1464,7 @@ static struct nf_sockopt_ops ip6t_sockopts = {
        .get            = do_ip6t_get_ctl,
 };
 
-static struct xt_match icmp6_matchstruct = {
+static struct xt_match icmp6_matchstruct __read_mostly = {
        .name           = "icmp6",
        .match          = &icmp6_match,
        .matchsize      = sizeof(struct ip6t_icmp),
index 4115a576ba25df785d06bd9498df6e02c9f60cdb..ad4d94310b8734ab145ef79e443acaa3550e719f 100644 (file)
@@ -58,28 +58,28 @@ static unsigned int ip6t_hl_target(struct sk_buff **pskb,
        return XT_CONTINUE;
 }
 
-static int ip6t_hl_checkentry(const char *tablename,
+static bool ip6t_hl_checkentry(const char *tablename,
                const void *entry,
                const struct xt_target *target,
                void *targinfo,
                unsigned int hook_mask)
 {
-       struct ip6t_HL_info *info = targinfo;
+       const struct ip6t_HL_info *info = targinfo;
 
        if (info->mode > IP6T_HL_MAXMODE) {
                printk(KERN_WARNING "ip6t_HL: invalid or unknown Mode %u\n",
                        info->mode);
-               return 0;
+               return false;
        }
-       if ((info->mode != IP6T_HL_SET) && (info->hop_limit == 0)) {
+       if (info->mode != IP6T_HL_SET && info->hop_limit == 0) {
                printk(KERN_WARNING "ip6t_HL: increment/decrement doesn't "
                        "make sense with value 0\n");
-               return 0;
+               return false;
        }
-       return 1;
+       return true;
 }
 
-static struct xt_target ip6t_HL = {
+static struct xt_target ip6t_HL __read_mostly = {
        .name           = "HL",
        .family         = AF_INET6,
        .target         = ip6t_hl_target,
index 5bb9cd3493504b9459004ac4336fefa0c9650173..b05327ebd3320fe01768ed420da40a2751514587 100644 (file)
@@ -32,12 +32,6 @@ struct in_device;
 #include <net/route.h>
 #include <linux/netfilter_ipv6/ip6t_LOG.h>
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 /* Use lock to serialize, so printks don't overlap */
 static DEFINE_SPINLOCK(log_lock);
 
@@ -48,7 +42,8 @@ static void dump_packet(const struct nf_loginfo *info,
 {
        u_int8_t currenthdr;
        int fragment;
-       struct ipv6hdr _ip6h, *ih;
+       struct ipv6hdr _ip6h;
+       const struct ipv6hdr *ih;
        unsigned int ptr;
        unsigned int hdrlen = 0;
        unsigned int logflags;
@@ -78,7 +73,8 @@ static void dump_packet(const struct nf_loginfo *info,
        ptr = ip6hoff + sizeof(struct ipv6hdr);
        currenthdr = ih->nexthdr;
        while (currenthdr != NEXTHDR_NONE && ip6t_ext_hdr(currenthdr)) {
-               struct ipv6_opt_hdr _hdr, *hp;
+               struct ipv6_opt_hdr _hdr;
+               const struct ipv6_opt_hdr *hp;
 
                hp = skb_header_pointer(skb, ptr, sizeof(_hdr), &_hdr);
                if (hp == NULL) {
@@ -92,7 +88,8 @@ static void dump_packet(const struct nf_loginfo *info,
 
                switch (currenthdr) {
                case IPPROTO_FRAGMENT: {
-                       struct frag_hdr _fhdr, *fh;
+                       struct frag_hdr _fhdr;
+                       const struct frag_hdr *fh;
 
                        printk("FRAG:");
                        fh = skb_header_pointer(skb, ptr, sizeof(_fhdr),
@@ -131,7 +128,8 @@ static void dump_packet(const struct nf_loginfo *info,
                /* Max Length */
                case IPPROTO_AH:
                        if (logflags & IP6T_LOG_IPOPT) {
-                               struct ip_auth_hdr _ahdr, *ah;
+                               struct ip_auth_hdr _ahdr;
+                               const struct ip_auth_hdr *ah;
 
                                /* Max length: 3 "AH " */
                                printk("AH ");
@@ -162,7 +160,8 @@ static void dump_packet(const struct nf_loginfo *info,
                        break;
                case IPPROTO_ESP:
                        if (logflags & IP6T_LOG_IPOPT) {
-                               struct ip_esp_hdr _esph, *eh;
+                               struct ip_esp_hdr _esph;
+                               const struct ip_esp_hdr *eh;
 
                                /* Max length: 4 "ESP " */
                                printk("ESP ");
@@ -202,7 +201,8 @@ static void dump_packet(const struct nf_loginfo *info,
 
        switch (currenthdr) {
        case IPPROTO_TCP: {
-               struct tcphdr _tcph, *th;
+               struct tcphdr _tcph;
+               const struct tcphdr *th;
 
                /* Max length: 10 "PROTO=TCP " */
                printk("PROTO=TCP ");
@@ -250,7 +250,8 @@ static void dump_packet(const struct nf_loginfo *info,
 
                if ((logflags & IP6T_LOG_TCPOPT)
                    && th->doff * 4 > sizeof(struct tcphdr)) {
-                       u_int8_t _opt[60 - sizeof(struct tcphdr)], *op;
+                       u_int8_t _opt[60 - sizeof(struct tcphdr)];
+                       const u_int8_t *op;
                        unsigned int i;
                        unsigned int optsize = th->doff * 4
                                               - sizeof(struct tcphdr);
@@ -273,7 +274,8 @@ static void dump_packet(const struct nf_loginfo *info,
        }
        case IPPROTO_UDP:
        case IPPROTO_UDPLITE: {
-               struct udphdr _udph, *uh;
+               struct udphdr _udph;
+               const struct udphdr *uh;
 
                if (currenthdr == IPPROTO_UDP)
                        /* Max length: 10 "PROTO=UDP "     */
@@ -298,7 +300,8 @@ static void dump_packet(const struct nf_loginfo *info,
                break;
        }
        case IPPROTO_ICMPV6: {
-               struct icmp6hdr _icmp6h, *ic;
+               struct icmp6hdr _icmp6h;
+               const struct icmp6hdr *ic;
 
                /* Max length: 13 "PROTO=ICMPv6 " */
                printk("PROTO=ICMPv6 ");
@@ -448,27 +451,27 @@ ip6t_log_target(struct sk_buff **pskb,
 }
 
 
-static int ip6t_log_checkentry(const char *tablename,
-                              const void *entry,
-                              const struct xt_target *target,
-                              void *targinfo,
-                              unsigned int hook_mask)
+static bool ip6t_log_checkentry(const char *tablename,
+                               const void *entry,
+                               const struct xt_target *target,
+                               void *targinfo,
+                               unsigned int hook_mask)
 {
        const struct ip6t_log_info *loginfo = targinfo;
 
        if (loginfo->level >= 8) {
-               DEBUGP("LOG: level %u >= 8\n", loginfo->level);
-               return 0;
+               pr_debug("LOG: level %u >= 8\n", loginfo->level);
+               return false;
        }
        if (loginfo->prefix[sizeof(loginfo->prefix)-1] != '\0') {
-               DEBUGP("LOG: prefix term %i\n",
-                      loginfo->prefix[sizeof(loginfo->prefix)-1]);
-               return 0;
+               pr_debug("LOG: prefix term %i\n",
+                        loginfo->prefix[sizeof(loginfo->prefix)-1]);
+               return false;
        }
-       return 1;
+       return true;
 }
 
-static struct xt_target ip6t_log_reg = {
+static struct xt_target ip6t_log_reg __read_mostly = {
        .name           = "LOG",
        .family         = AF_INET6,
        .target         = ip6t_log_target,
index cb3d2415a0645c5eee3759902b99ed77d88405f1..2f487cda3b6bf346902cad7846aa6e9f3cc59c9a 100644 (file)
@@ -34,12 +34,6 @@ MODULE_AUTHOR("Yasuyuki KOZAKAI <yasuyuki.kozakai@toshiba.co.jp>");
 MODULE_DESCRIPTION("IP6 tables REJECT target module");
 MODULE_LICENSE("GPL");
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 /* Send RST reply */
 static void send_reset(struct sk_buff *oldskb)
 {
@@ -54,7 +48,7 @@ static void send_reset(struct sk_buff *oldskb)
 
        if ((!(ipv6_addr_type(&oip6h->saddr) & IPV6_ADDR_UNICAST)) ||
            (!(ipv6_addr_type(&oip6h->daddr) & IPV6_ADDR_UNICAST))) {
-               DEBUGP("ip6t_REJECT: addr is not unicast.\n");
+               pr_debug("ip6t_REJECT: addr is not unicast.\n");
                return;
        }
 
@@ -62,16 +56,17 @@ static void send_reset(struct sk_buff *oldskb)
        tcphoff = ipv6_skip_exthdr(oldskb, ((u8*)(oip6h+1) - oldskb->data), &proto);
 
        if ((tcphoff < 0) || (tcphoff > oldskb->len)) {
-               DEBUGP("ip6t_REJECT: Can't get TCP header.\n");
+               pr_debug("ip6t_REJECT: Can't get TCP header.\n");
                return;
        }
 
        otcplen = oldskb->len - tcphoff;
 
        /* IP header checks: fragment, too short. */
-       if ((proto != IPPROTO_TCP) || (otcplen < sizeof(struct tcphdr))) {
-               DEBUGP("ip6t_REJECT: proto(%d) != IPPROTO_TCP, or too short. otcplen = %d\n",
-                       proto, otcplen);
+       if (proto != IPPROTO_TCP || otcplen < sizeof(struct tcphdr)) {
+               pr_debug("ip6t_REJECT: proto(%d) != IPPROTO_TCP, "
+                        "or too short. otcplen = %d\n",
+                        proto, otcplen);
                return;
        }
 
@@ -80,14 +75,14 @@ static void send_reset(struct sk_buff *oldskb)
 
        /* No RST for RST. */
        if (otcph.rst) {
-               DEBUGP("ip6t_REJECT: RST is set\n");
+               pr_debug("ip6t_REJECT: RST is set\n");
                return;
        }
 
        /* Check checksum. */
        if (csum_ipv6_magic(&oip6h->saddr, &oip6h->daddr, otcplen, IPPROTO_TCP,
                            skb_checksum(oldskb, tcphoff, otcplen, 0))) {
-               DEBUGP("ip6t_REJECT: TCP checksum is invalid\n");
+               pr_debug("ip6t_REJECT: TCP checksum is invalid\n");
                return;
        }
 
@@ -159,7 +154,7 @@ static void send_reset(struct sk_buff *oldskb)
        tcph->check = csum_ipv6_magic(&ipv6_hdr(nskb)->saddr,
                                      &ipv6_hdr(nskb)->daddr,
                                      sizeof(struct tcphdr), IPPROTO_TCP,
-                                     csum_partial((char *)tcph,
+                                     csum_partial(tcph,
                                                   sizeof(struct tcphdr), 0));
 
        nf_ct_attach(nskb, oldskb);
@@ -186,7 +181,7 @@ static unsigned int reject6_target(struct sk_buff **pskb,
 {
        const struct ip6t_reject_info *reject = targinfo;
 
-       DEBUGP(KERN_DEBUG "%s: medium point\n", __FUNCTION__);
+       pr_debug("%s: medium point\n", __FUNCTION__);
        /* WARNING: This code causes reentry within ip6tables.
           This means that the ip6tables jump stack is now crap.  We
           must return an absolute verdict. --RR */
@@ -221,30 +216,30 @@ static unsigned int reject6_target(struct sk_buff **pskb,
        return NF_DROP;
 }
 
-static int check(const char *tablename,
-                const void *entry,
-                const struct xt_target *target,
-                void *targinfo,
-                unsigned int hook_mask)
+static bool check(const char *tablename,
+                 const void *entry,
+                 const struct xt_target *target,
+                 void *targinfo,
+                 unsigned int hook_mask)
 {
        const struct ip6t_reject_info *rejinfo = targinfo;
        const struct ip6t_entry *e = entry;
 
        if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) {
                printk("ip6t_REJECT: ECHOREPLY is not supported.\n");
-               return 0;
+               return false;
        } else if (rejinfo->with == IP6T_TCP_RESET) {
                /* Must specify that it's a TCP packet */
                if (e->ipv6.proto != IPPROTO_TCP
                    || (e->ipv6.invflags & XT_INV_PROTO)) {
-                       DEBUGP("ip6t_REJECT: TCP_RESET illegal for non-tcp\n");
-                       return 0;
+                       printk("ip6t_REJECT: TCP_RESET illegal for non-tcp\n");
+                       return false;
                }
        }
-       return 1;
+       return true;
 }
 
-static struct xt_target ip6t_reject_reg = {
+static struct xt_target ip6t_reject_reg __read_mostly = {
        .name           = "REJECT",
        .family         = AF_INET6,
        .target         = reject6_target,
index d3c154371b41d30bbe85c72c170c2bc0969b0891..2a25fe25e0e0d236947a6f3c281b3e72415a3572 100644 (file)
@@ -23,25 +23,20 @@ MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("IPv6 AH match");
 MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 /* Returns 1 if the spi is matched by the range, 0 otherwise */
-static inline int
-spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, int invert)
+static inline bool
+spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert)
 {
-       int r=0;
-       DEBUGP("ah spi_match:%c 0x%x <= 0x%x <= 0x%x",invert? '!':' ',
-              min,spi,max);
+       bool r;
+
+       pr_debug("ah spi_match:%c 0x%x <= 0x%x <= 0x%x",
+                invert ? '!' : ' ', min, spi, max);
        r = (spi >= min && spi <= max) ^ invert;
-       DEBUGP(" result %s\n",r? "PASS\n" : "FAILED\n");
+       pr_debug(" result %s\n", r ? "PASS" : "FAILED");
        return r;
 }
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -49,9 +44,10 @@ match(const struct sk_buff *skb,
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
-       struct ip_auth_hdr *ah, _ah;
+       struct ip_auth_hdr _ah;
+       const struct ip_auth_hdr *ah;
        const struct ip6t_ah *ahinfo = matchinfo;
        unsigned int ptr;
        unsigned int hdrlen = 0;
@@ -60,40 +56,40 @@ match(const struct sk_buff *skb,
        err = ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL);
        if (err < 0) {
                if (err != -ENOENT)
-                       *hotdrop = 1;
-               return 0;
+                       *hotdrop = true;
+               return false;
        }
 
        ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah);
        if (ah == NULL) {
-               *hotdrop = 1;
-               return 0;
+               *hotdrop = true;
+               return false;
        }
 
        hdrlen = (ah->hdrlen + 2) << 2;
 
-       DEBUGP("IPv6 AH LEN %u %u ", hdrlen, ah->hdrlen);
-       DEBUGP("RES %04X ", ah->reserved);
-       DEBUGP("SPI %u %08X\n", ntohl(ah->spi), ntohl(ah->spi));
-
-       DEBUGP("IPv6 AH spi %02X ",
-              (spi_match(ahinfo->spis[0], ahinfo->spis[1],
-                         ntohl(ah->spi),
-                         !!(ahinfo->invflags & IP6T_AH_INV_SPI))));
-       DEBUGP("len %02X %04X %02X ",
-              ahinfo->hdrlen, hdrlen,
-              (!ahinfo->hdrlen ||
-               (ahinfo->hdrlen == hdrlen) ^
-               !!(ahinfo->invflags & IP6T_AH_INV_LEN)));
-       DEBUGP("res %02X %04X %02X\n",
-              ahinfo->hdrres, ah->reserved,
-              !(ahinfo->hdrres && ah->reserved));
+       pr_debug("IPv6 AH LEN %u %u ", hdrlen, ah->hdrlen);
+       pr_debug("RES %04X ", ah->reserved);
+       pr_debug("SPI %u %08X\n", ntohl(ah->spi), ntohl(ah->spi));
+
+       pr_debug("IPv6 AH spi %02X ",
+                spi_match(ahinfo->spis[0], ahinfo->spis[1],
+                          ntohl(ah->spi),
+                          !!(ahinfo->invflags & IP6T_AH_INV_SPI)));
+       pr_debug("len %02X %04X %02X ",
+                ahinfo->hdrlen, hdrlen,
+                (!ahinfo->hdrlen ||
+                 (ahinfo->hdrlen == hdrlen) ^
+                 !!(ahinfo->invflags & IP6T_AH_INV_LEN)));
+       pr_debug("res %02X %04X %02X\n",
+                ahinfo->hdrres, ah->reserved,
+                !(ahinfo->hdrres && ah->reserved));
 
        return (ah != NULL)
               &&
-              (spi_match(ahinfo->spis[0], ahinfo->spis[1],
-                         ntohl(ah->spi),
-                         !!(ahinfo->invflags & IP6T_AH_INV_SPI)))
+              spi_match(ahinfo->spis[0], ahinfo->spis[1],
+                        ntohl(ah->spi),
+                        !!(ahinfo->invflags & IP6T_AH_INV_SPI))
               &&
               (!ahinfo->hdrlen ||
                (ahinfo->hdrlen == hdrlen) ^
@@ -103,7 +99,7 @@ match(const struct sk_buff *skb,
 }
 
 /* Called when user tries to insert an entry of this type. */
-static int
+static bool
 checkentry(const char *tablename,
          const void *entry,
          const struct xt_match *match,
@@ -113,13 +109,13 @@ checkentry(const char *tablename,
        const struct ip6t_ah *ahinfo = matchinfo;
 
        if (ahinfo->invflags & ~IP6T_AH_INV_MASK) {
-               DEBUGP("ip6t_ah: unknown flags %X\n", ahinfo->invflags);
-               return 0;
+               pr_debug("ip6t_ah: unknown flags %X\n", ahinfo->invflags);
+               return false;
        }
-       return 1;
+       return true;
 }
 
-static struct xt_match ah_match = {
+static struct xt_match ah_match __read_mostly = {
        .name           = "ah",
        .family         = AF_INET6,
        .match          = match,
index 0f3dd932f0a627cdbb29000ec6b7a9e416159ee4..34ba150bfe5d9089e65301a47648a31747de73ba 100644 (file)
@@ -19,7 +19,7 @@ MODULE_DESCRIPTION("IPv6 EUI64 address checking match");
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -27,16 +27,16 @@ match(const struct sk_buff *skb,
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
        unsigned char eui64[8];
        int i = 0;
 
        if (!(skb_mac_header(skb) >= skb->head &&
-             (skb_mac_header(skb) + ETH_HLEN) <= skb->data) &&
+             skb_mac_header(skb) + ETH_HLEN <= skb->data) &&
            offset != 0) {
-               *hotdrop = 1;
-               return 0;
+               *hotdrop = true;
+               return false;
        }
 
        memset(eui64, 0, sizeof(eui64));
@@ -50,19 +50,19 @@ match(const struct sk_buff *skb,
                        eui64[0] |= 0x02;
 
                        i = 0;
-                       while ((ipv6_hdr(skb)->saddr.s6_addr[8 + i] == eui64[i])
-                              && (i < 8))
+                       while (ipv6_hdr(skb)->saddr.s6_addr[8 + i] == eui64[i]
+                              && i < 8)
                                i++;
 
                        if (i == 8)
-                               return 1;
+                               return true;
                }
        }
 
-       return 0;
+       return false;
 }
 
-static struct xt_match eui64_match = {
+static struct xt_match eui64_match __read_mostly = {
        .name           = "eui64",
        .family         = AF_INET6,
        .match          = match,
index 5a5da71321b6f5f6962ece60cf52997df3e3cedc..968aeba020737856abb6e1de3f4803849c9c2e2e 100644 (file)
@@ -22,25 +22,19 @@ MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("IPv6 FRAG match");
 MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 /* Returns 1 if the id is matched by the range, 0 otherwise */
-static inline int
-id_match(u_int32_t min, u_int32_t max, u_int32_t id, int invert)
+static inline bool
+id_match(u_int32_t min, u_int32_t max, u_int32_t id, bool invert)
 {
-       int r = 0;
-       DEBUGP("frag id_match:%c 0x%x <= 0x%x <= 0x%x", invert ? '!' : ' ',
-              min, id, max);
+       bool r;
+       pr_debug("frag id_match:%c 0x%x <= 0x%x <= 0x%x", invert ? '!' : ' ',
+                min, id, max);
        r = (id >= min && id <= max) ^ invert;
-       DEBUGP(" result %s\n", r ? "PASS" : "FAILED");
+       pr_debug(" result %s\n", r ? "PASS" : "FAILED");
        return r;
 }
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -48,9 +42,10 @@ match(const struct sk_buff *skb,
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
-       struct frag_hdr _frag, *fh;
+       struct frag_hdr _frag;
+       const struct frag_hdr *fh;
        const struct ip6t_frag *fraginfo = matchinfo;
        unsigned int ptr;
        int err;
@@ -58,53 +53,53 @@ match(const struct sk_buff *skb,
        err = ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL);
        if (err < 0) {
                if (err != -ENOENT)
-                       *hotdrop = 1;
-               return 0;
+                       *hotdrop = true;
+               return false;
        }
 
        fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag);
        if (fh == NULL) {
-               *hotdrop = 1;
-               return 0;
+               *hotdrop = true;
+               return false;
        }
 
-       DEBUGP("INFO %04X ", fh->frag_off);
-       DEBUGP("OFFSET %04X ", ntohs(fh->frag_off) & ~0x7);
-       DEBUGP("RES %02X %04X", fh->reserved, ntohs(fh->frag_off) & 0x6);
-       DEBUGP("MF %04X ", fh->frag_off & htons(IP6_MF));
-       DEBUGP("ID %u %08X\n", ntohl(fh->identification),
-              ntohl(fh->identification));
-
-       DEBUGP("IPv6 FRAG id %02X ",
-              (id_match(fraginfo->ids[0], fraginfo->ids[1],
-                        ntohl(fh->identification),
-                        !!(fraginfo->invflags & IP6T_FRAG_INV_IDS))));
-       DEBUGP("res %02X %02X%04X %02X ",
-              (fraginfo->flags & IP6T_FRAG_RES), fh->reserved,
-              ntohs(fh->frag_off) & 0x6,
-              !((fraginfo->flags & IP6T_FRAG_RES)
-                && (fh->reserved || (ntohs(fh->frag_off) & 0x06))));
-       DEBUGP("first %02X %02X %02X ",
-              (fraginfo->flags & IP6T_FRAG_FST),
-              ntohs(fh->frag_off) & ~0x7,
-              !((fraginfo->flags & IP6T_FRAG_FST)
-                && (ntohs(fh->frag_off) & ~0x7)));
-       DEBUGP("mf %02X %02X %02X ",
-              (fraginfo->flags & IP6T_FRAG_MF),
-              ntohs(fh->frag_off) & IP6_MF,
-              !((fraginfo->flags & IP6T_FRAG_MF)
-                && !((ntohs(fh->frag_off) & IP6_MF))));
-       DEBUGP("last %02X %02X %02X\n",
-              (fraginfo->flags & IP6T_FRAG_NMF),
-              ntohs(fh->frag_off) & IP6_MF,
-              !((fraginfo->flags & IP6T_FRAG_NMF)
-                && (ntohs(fh->frag_off) & IP6_MF)));
+       pr_debug("INFO %04X ", fh->frag_off);
+       pr_debug("OFFSET %04X ", ntohs(fh->frag_off) & ~0x7);
+       pr_debug("RES %02X %04X", fh->reserved, ntohs(fh->frag_off) & 0x6);
+       pr_debug("MF %04X ", fh->frag_off & htons(IP6_MF));
+       pr_debug("ID %u %08X\n", ntohl(fh->identification),
+                ntohl(fh->identification));
+
+       pr_debug("IPv6 FRAG id %02X ",
+                id_match(fraginfo->ids[0], fraginfo->ids[1],
+                         ntohl(fh->identification),
+                         !!(fraginfo->invflags & IP6T_FRAG_INV_IDS)));
+       pr_debug("res %02X %02X%04X %02X ",
+                fraginfo->flags & IP6T_FRAG_RES, fh->reserved,
+                ntohs(fh->frag_off) & 0x6,
+                !((fraginfo->flags & IP6T_FRAG_RES)
+                  && (fh->reserved || (ntohs(fh->frag_off) & 0x06))));
+       pr_debug("first %02X %02X %02X ",
+                fraginfo->flags & IP6T_FRAG_FST,
+                ntohs(fh->frag_off) & ~0x7,
+                !((fraginfo->flags & IP6T_FRAG_FST)
+                  && (ntohs(fh->frag_off) & ~0x7)));
+       pr_debug("mf %02X %02X %02X ",
+                fraginfo->flags & IP6T_FRAG_MF,
+                ntohs(fh->frag_off) & IP6_MF,
+                !((fraginfo->flags & IP6T_FRAG_MF)
+                  && !((ntohs(fh->frag_off) & IP6_MF))));
+       pr_debug("last %02X %02X %02X\n",
+                fraginfo->flags & IP6T_FRAG_NMF,
+                ntohs(fh->frag_off) & IP6_MF,
+                !((fraginfo->flags & IP6T_FRAG_NMF)
+                  && (ntohs(fh->frag_off) & IP6_MF)));
 
        return (fh != NULL)
               &&
-              (id_match(fraginfo->ids[0], fraginfo->ids[1],
-                        ntohl(fh->identification),
-                        !!(fraginfo->invflags & IP6T_FRAG_INV_IDS)))
+              id_match(fraginfo->ids[0], fraginfo->ids[1],
+                       ntohl(fh->identification),
+                       !!(fraginfo->invflags & IP6T_FRAG_INV_IDS))
               &&
               !((fraginfo->flags & IP6T_FRAG_RES)
                 && (fh->reserved || (ntohs(fh->frag_off) & 0x6)))
@@ -120,7 +115,7 @@ match(const struct sk_buff *skb,
 }
 
 /* Called when user tries to insert an entry of this type. */
-static int
+static bool
 checkentry(const char *tablename,
           const void *ip,
           const struct xt_match *match,
@@ -130,13 +125,13 @@ checkentry(const char *tablename,
        const struct ip6t_frag *fraginfo = matchinfo;
 
        if (fraginfo->invflags & ~IP6T_FRAG_INV_MASK) {
-               DEBUGP("ip6t_frag: unknown flags %X\n", fraginfo->invflags);
-               return 0;
+               pr_debug("ip6t_frag: unknown flags %X\n", fraginfo->invflags);
+               return false;
        }
-       return 1;
+       return true;
 }
 
-static struct xt_match frag_match = {
+static struct xt_match frag_match __read_mostly = {
        .name           = "frag",
        .family         = AF_INET6,
        .match          = match,
index d2373c7cd35458686d44dd813ab2c70c2a37bb71..e6ca6018b1eaaf0764608debfe1f0821b8a7fffd 100644 (file)
@@ -25,12 +25,6 @@ MODULE_DESCRIPTION("IPv6 opts match");
 MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
 MODULE_ALIAS("ip6t_dst");
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 /*
  *  (Type & 0xC0) >> 6
  *     0       -> ignorable
@@ -47,7 +41,7 @@ MODULE_ALIAS("ip6t_dst");
  *     5       -> RTALERT 2 x x
  */
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -55,45 +49,48 @@ match(const struct sk_buff *skb,
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
-       struct ipv6_opt_hdr _optsh, *oh;
+       struct ipv6_opt_hdr _optsh;
+       const struct ipv6_opt_hdr *oh;
        const struct ip6t_opts *optinfo = matchinfo;
        unsigned int temp;
        unsigned int ptr;
        unsigned int hdrlen = 0;
-       unsigned int ret = 0;
-       u8 _opttype, *tp = NULL;
-       u8 _optlen, *lp = NULL;
+       bool ret = false;
+       u8 _opttype;
+       u8 _optlen;
+       const u_int8_t *tp = NULL;
+       const u_int8_t *lp = NULL;
        unsigned int optlen;
        int err;
 
        err = ipv6_find_hdr(skb, &ptr, match->data, NULL);
        if (err < 0) {
                if (err != -ENOENT)
-                       *hotdrop = 1;
-               return 0;
+                       *hotdrop = true;
+               return false;
        }
 
        oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh);
        if (oh == NULL) {
-               *hotdrop = 1;
-               return 0;
+               *hotdrop = true;
+               return false;
        }
 
        hdrlen = ipv6_optlen(oh);
        if (skb->len - ptr < hdrlen) {
                /* Packet smaller than it's length field */
-               return 0;
+               return false;
        }
 
-       DEBUGP("IPv6 OPTS LEN %u %u ", hdrlen, oh->hdrlen);
+       pr_debug("IPv6 OPTS LEN %u %u ", hdrlen, oh->hdrlen);
 
-       DEBUGP("len %02X %04X %02X ",
-              optinfo->hdrlen, hdrlen,
-              (!(optinfo->flags & IP6T_OPTS_LEN) ||
-               ((optinfo->hdrlen == hdrlen) ^
-                !!(optinfo->invflags & IP6T_OPTS_INV_LEN))));
+       pr_debug("len %02X %04X %02X ",
+                optinfo->hdrlen, hdrlen,
+                (!(optinfo->flags & IP6T_OPTS_LEN) ||
+                 ((optinfo->hdrlen == hdrlen) ^
+                  !!(optinfo->invflags & IP6T_OPTS_INV_LEN))));
 
        ret = (oh != NULL) &&
              (!(optinfo->flags & IP6T_OPTS_LEN) ||
@@ -105,10 +102,10 @@ match(const struct sk_buff *skb,
        if (!(optinfo->flags & IP6T_OPTS_OPTS)) {
                return ret;
        } else if (optinfo->flags & IP6T_OPTS_NSTRICT) {
-               DEBUGP("Not strict - not implemented");
+               pr_debug("Not strict - not implemented");
        } else {
-               DEBUGP("Strict ");
-               DEBUGP("#%d ", optinfo->optsnr);
+               pr_debug("Strict ");
+               pr_debug("#%d ", optinfo->optsnr);
                for (temp = 0; temp < optinfo->optsnr; temp++) {
                        /* type field exists ? */
                        if (hdrlen < 1)
@@ -120,12 +117,11 @@ match(const struct sk_buff *skb,
 
                        /* Type check */
                        if (*tp != (optinfo->opts[temp] & 0xFF00) >> 8) {
-                               DEBUGP("Tbad %02X %02X\n",
-                                      *tp,
-                                      (optinfo->opts[temp] & 0xFF00) >> 8);
-                               return 0;
+                               pr_debug("Tbad %02X %02X\n", *tp,
+                                        (optinfo->opts[temp] & 0xFF00) >> 8);
+                               return false;
                        } else {
-                               DEBUGP("Tok ");
+                               pr_debug("Tok ");
                        }
                        /* Length check */
                        if (*tp) {
@@ -142,23 +138,23 @@ match(const struct sk_buff *skb,
                                spec_len = optinfo->opts[temp] & 0x00FF;
 
                                if (spec_len != 0x00FF && spec_len != *lp) {
-                                       DEBUGP("Lbad %02X %04X\n", *lp,
-                                              spec_len);
-                                       return 0;
+                                       pr_debug("Lbad %02X %04X\n", *lp,
+                                                spec_len);
+                                       return false;
                                }
-                               DEBUGP("Lok ");
+                               pr_debug("Lok ");
                                optlen = *lp + 2;
                        } else {
-                               DEBUGP("Pad1\n");
+                               pr_debug("Pad1\n");
                                optlen = 1;
                        }
 
                        /* Step to the next */
-                       DEBUGP("len%04X \n", optlen);
+                       pr_debug("len%04X \n", optlen);
 
                        if ((ptr > skb->len - optlen || hdrlen < optlen) &&
-                           (temp < optinfo->optsnr - 1)) {
-                               DEBUGP("new pointer is too large! \n");
+                           temp < optinfo->optsnr - 1) {
+                               pr_debug("new pointer is too large! \n");
                                break;
                        }
                        ptr += optlen;
@@ -167,14 +163,14 @@ match(const struct sk_buff *skb,
                if (temp == optinfo->optsnr)
                        return ret;
                else
-                       return 0;
+                       return false;
        }
 
-       return 0;
+       return false;
 }
 
 /* Called when user tries to insert an entry of this type. */
-static int
+static bool
 checkentry(const char *tablename,
           const void *entry,
           const struct xt_match *match,
@@ -184,13 +180,13 @@ checkentry(const char *tablename,
        const struct ip6t_opts *optsinfo = matchinfo;
 
        if (optsinfo->invflags & ~IP6T_OPTS_INV_MASK) {
-               DEBUGP("ip6t_opts: unknown flags %X\n", optsinfo->invflags);
-               return 0;
+               pr_debug("ip6t_opts: unknown flags %X\n", optsinfo->invflags);
+               return false;
        }
-       return 1;
+       return true;
 }
 
-static struct xt_match opts_match[] = {
+static struct xt_match opts_match[] __read_mostly = {
        {
                .name           = "hbh",
                .family         = AF_INET6,
index d606c0e6d6fd65aeecf690fdbb6a9fce31a04a21..ca29ec00dc188f7b2ab3a5021ed9ad6e4a8cb68d 100644 (file)
@@ -19,37 +19,37 @@ MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>");
 MODULE_DESCRIPTION("IP tables Hop Limit matching module");
 MODULE_LICENSE("GPL");
 
-static int match(const struct sk_buff *skb,
-                const struct net_device *in, const struct net_device *out,
-                const struct xt_match *match, const void *matchinfo,
-                int offset, unsigned int protoff, int *hotdrop)
+static bool match(const struct sk_buff *skb,
+                 const struct net_device *in, const struct net_device *out,
+                 const struct xt_match *match, const void *matchinfo,
+                 int offset, unsigned int protoff, bool *hotdrop)
 {
        const struct ip6t_hl_info *info = matchinfo;
        const struct ipv6hdr *ip6h = ipv6_hdr(skb);
 
        switch (info->mode) {
                case IP6T_HL_EQ:
-                       return (ip6h->hop_limit == info->hop_limit);
+                       return ip6h->hop_limit == info->hop_limit;
                        break;
                case IP6T_HL_NE:
-                       return (!(ip6h->hop_limit == info->hop_limit));
+                       return ip6h->hop_limit != info->hop_limit;
                        break;
                case IP6T_HL_LT:
-                       return (ip6h->hop_limit < info->hop_limit);
+                       return ip6h->hop_limit < info->hop_limit;
                        break;
                case IP6T_HL_GT:
-                       return (ip6h->hop_limit > info->hop_limit);
+                       return ip6h->hop_limit > info->hop_limit;
                        break;
                default:
                        printk(KERN_WARNING "ip6t_hl: unknown mode %d\n",
                                info->mode);
-                       return 0;
+                       return false;
        }
 
-       return 0;
+       return false;
 }
 
-static struct xt_match hl_match = {
+static struct xt_match hl_match __read_mostly = {
        .name           = "hl",
        .family         = AF_INET6,
        .match          = match,
index fd6a0869099b6034d3f8a031a320d36e829a4994..2c65c2f9a4ab116ea3de849f810d554be10f57ad 100644 (file)
@@ -26,7 +26,7 @@ MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("IPv6 headers match");
 MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
 
-static int
+static bool
 ipv6header_match(const struct sk_buff *skb,
                 const struct net_device *in,
                 const struct net_device *out,
@@ -34,7 +34,7 @@ ipv6header_match(const struct sk_buff *skb,
                 const void *matchinfo,
                 int offset,
                 unsigned int protoff,
-                int *hotdrop)
+                bool *hotdrop)
 {
        const struct ip6t_ipv6header_info *info = matchinfo;
        unsigned int temp;
@@ -58,7 +58,7 @@ ipv6header_match(const struct sk_buff *skb,
 
                /* Is there enough space for the next ext header? */
                if (len < (int)sizeof(struct ipv6_opt_hdr))
-                       return 0;
+                       return false;
                /* No more exthdr -> evaluate */
                if (nexthdr == NEXTHDR_NONE) {
                        temp |= MASK_NONE;
@@ -74,9 +74,9 @@ ipv6header_match(const struct sk_buff *skb,
                BUG_ON(hp == NULL);
 
                /* Calculate the header length */
-               if (nexthdr == NEXTHDR_FRAGMENT) {
+               if (nexthdr == NEXTHDR_FRAGMENT)
                        hdrlen = 8;
-               else if (nexthdr == NEXTHDR_AUTH)
+               else if (nexthdr == NEXTHDR_AUTH)
                        hdrlen = (hp->hdrlen + 2) << 2;
                else
                        hdrlen = ipv6_optlen(hp);
@@ -99,7 +99,7 @@ ipv6header_match(const struct sk_buff *skb,
                        temp |= MASK_DSTOPTS;
                        break;
                default:
-                       return 0;
+                       return false;
                        break;
                }
 
@@ -110,7 +110,7 @@ ipv6header_match(const struct sk_buff *skb,
                        break;
        }
 
-       if ((nexthdr != NEXTHDR_NONE) && (nexthdr != NEXTHDR_ESP))
+       if (nexthdr != NEXTHDR_NONE && nexthdr != NEXTHDR_ESP)
                temp |= MASK_PROTO;
 
        if (info->modeflag)
@@ -124,7 +124,7 @@ ipv6header_match(const struct sk_buff *skb,
        }
 }
 
-static int
+static bool
 ipv6header_checkentry(const char *tablename,
                      const void *ip,
                      const struct xt_match *match,
@@ -136,12 +136,12 @@ ipv6header_checkentry(const char *tablename,
        /* invflags is 0 or 0xff in hard mode */
        if ((!info->modeflag) && info->invflags != 0x00 &&
            info->invflags != 0xFF)
-               return 0;
+               return false;
 
-       return 1;
+       return true;
 }
 
-static struct xt_match ip6t_ipv6header_match = {
+static struct xt_match ip6t_ipv6header_match __read_mostly = {
        .name           = "ipv6header",
        .family         = AF_INET6,
        .match          = &ipv6header_match,
index c2a909893a64cbd790e9d650fbf8d7f4ae722ef2..0fa714092dc948a0b0c29801f9597884839ba611 100644 (file)
@@ -31,16 +31,13 @@ MODULE_LICENSE("GPL");
 #endif
 
 /* Returns 1 if the type is matched by the range, 0 otherwise */
-static inline int
-type_match(u_int8_t min, u_int8_t max, u_int8_t type, int invert)
+static inline bool
+type_match(u_int8_t min, u_int8_t max, u_int8_t type, bool invert)
 {
-       int ret;
-
-       ret = (type >= min && type <= max) ^ invert;
-       return ret;
+       return (type >= min && type <= max) ^ invert;
 }
 
-static int
+static bool
 match(const struct sk_buff *skb,
         const struct net_device *in,
         const struct net_device *out,
@@ -48,29 +45,30 @@ match(const struct sk_buff *skb,
         const void *matchinfo,
         int offset,
         unsigned int protoff,
-        int *hotdrop)
+        bool *hotdrop)
 {
-       struct ip6_mh _mh, *mh;
+       struct ip6_mh _mh;
+       const struct ip6_mh *mh;
        const struct ip6t_mh *mhinfo = matchinfo;
 
        /* Must not be a fragment. */
        if (offset)
-               return 0;
+               return false;
 
        mh = skb_header_pointer(skb, protoff, sizeof(_mh), &_mh);
        if (mh == NULL) {
                /* We've been asked to examine this packet, and we
                   can't.  Hence, no choice but to drop. */
                duprintf("Dropping evil MH tinygram.\n");
-               *hotdrop = 1;
-               return 0;
+               *hotdrop = true;
+               return false;
        }
 
        if (mh->ip6mh_proto != IPPROTO_NONE) {
                duprintf("Dropping invalid MH Payload Proto: %u\n",
                         mh->ip6mh_proto);
-               *hotdrop = 1;
-               return 0;
+               *hotdrop = true;
+               return false;
        }
 
        return type_match(mhinfo->types[0], mhinfo->types[1], mh->ip6mh_type,
@@ -78,7 +76,7 @@ match(const struct sk_buff *skb,
 }
 
 /* Called when user tries to insert an entry of this type. */
-static int
+static bool
 mh_checkentry(const char *tablename,
              const void *entry,
              const struct xt_match *match,
@@ -91,7 +89,7 @@ mh_checkentry(const char *tablename,
        return !(mhinfo->invflags & ~IP6T_MH_INV_MASK);
 }
 
-static struct xt_match mh_match = {
+static struct xt_match mh_match __read_mostly = {
        .name           = "mh",
        .family         = AF_INET6,
        .checkentry     = mh_checkentry,
index 43738bba00b548fb5b9174d41fcf7cd82a81b5fe..6036613aef368789a6e4fe69de0c0be3e0b43000 100644 (file)
@@ -23,7 +23,7 @@ MODULE_DESCRIPTION("IP6 tables owner matching module");
 MODULE_LICENSE("GPL");
 
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -31,29 +31,27 @@ match(const struct sk_buff *skb,
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
        const struct ip6t_owner_info *info = matchinfo;
 
        if (!skb->sk || !skb->sk->sk_socket || !skb->sk->sk_socket->file)
-               return 0;
+               return false;
 
-       if (info->match & IP6T_OWNER_UID) {
+       if (info->match & IP6T_OWNER_UID)
                if ((skb->sk->sk_socket->file->f_uid != info->uid) ^
                    !!(info->invert & IP6T_OWNER_UID))
-                       return 0;
-       }
+                       return false;
 
-       if (info->match & IP6T_OWNER_GID) {
+       if (info->match & IP6T_OWNER_GID)
                if ((skb->sk->sk_socket->file->f_gid != info->gid) ^
                    !!(info->invert & IP6T_OWNER_GID))
-                       return 0;
-       }
+                       return false;
 
-       return 1;
+       return true;
 }
 
-static int
+static bool
 checkentry(const char *tablename,
           const void *ip,
           const struct xt_match *match,
@@ -65,12 +63,12 @@ checkentry(const char *tablename,
        if (info->match & (IP6T_OWNER_PID | IP6T_OWNER_SID)) {
                printk("ipt_owner: pid and sid matching "
                       "not supported anymore\n");
-               return 0;
+               return false;
        }
-       return 1;
+       return true;
 }
 
-static struct xt_match owner_match = {
+static struct xt_match owner_match __read_mostly = {
        .name           = "owner",
        .family         = AF_INET6,
        .match          = match,
index 81ab00d8c182909764449ff369480592b849f534..357cea703bd9b3e505f088d5deaaf8212debdea9 100644 (file)
@@ -24,25 +24,19 @@ MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("IPv6 RT match");
 MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 /* Returns 1 if the id is matched by the range, 0 otherwise */
-static inline int
-segsleft_match(u_int32_t min, u_int32_t max, u_int32_t id, int invert)
+static inline bool
+segsleft_match(u_int32_t min, u_int32_t max, u_int32_t id, bool invert)
 {
-       int r = 0;
-       DEBUGP("rt segsleft_match:%c 0x%x <= 0x%x <= 0x%x",
-              invert ? '!' : ' ', min, id, max);
+       bool r;
+       pr_debug("rt segsleft_match:%c 0x%x <= 0x%x <= 0x%x",
+                invert ? '!' : ' ', min, id, max);
        r = (id >= min && id <= max) ^ invert;
-       DEBUGP(" result %s\n", r ? "PASS" : "FAILED");
+       pr_debug(" result %s\n", r ? "PASS" : "FAILED");
        return r;
 }
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -50,59 +44,61 @@ match(const struct sk_buff *skb,
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
-       struct ipv6_rt_hdr _route, *rh;
+       struct ipv6_rt_hdr _route;
+       const struct ipv6_rt_hdr *rh;
        const struct ip6t_rt *rtinfo = matchinfo;
        unsigned int temp;
        unsigned int ptr;
        unsigned int hdrlen = 0;
-       unsigned int ret = 0;
-       struct in6_addr *ap, _addr;
+       bool ret = false;
+       struct in6_addr _addr;
+       const struct in6_addr *ap;
        int err;
 
        err = ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL);
        if (err < 0) {
                if (err != -ENOENT)
-                       *hotdrop = 1;
-               return 0;
+                       *hotdrop = true;
+               return false;
        }
 
        rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route);
        if (rh == NULL) {
-               *hotdrop = 1;
-               return 0;
+               *hotdrop = true;
+               return false;
        }
 
        hdrlen = ipv6_optlen(rh);
        if (skb->len - ptr < hdrlen) {
                /* Pcket smaller than its length field */
-               return 0;
+               return false;
        }
 
-       DEBUGP("IPv6 RT LEN %u %u ", hdrlen, rh->hdrlen);
-       DEBUGP("TYPE %04X ", rh->type);
-       DEBUGP("SGS_LEFT %u %02X\n", rh->segments_left, rh->segments_left);
-
-       DEBUGP("IPv6 RT segsleft %02X ",
-              (segsleft_match(rtinfo->segsleft[0], rtinfo->segsleft[1],
-                              rh->segments_left,
-                              !!(rtinfo->invflags & IP6T_RT_INV_SGS))));
-       DEBUGP("type %02X %02X %02X ",
-              rtinfo->rt_type, rh->type,
-              (!(rtinfo->flags & IP6T_RT_TYP) ||
-               ((rtinfo->rt_type == rh->type) ^
-                !!(rtinfo->invflags & IP6T_RT_INV_TYP))));
-       DEBUGP("len %02X %04X %02X ",
-              rtinfo->hdrlen, hdrlen,
-              (!(rtinfo->flags & IP6T_RT_LEN) ||
-               ((rtinfo->hdrlen == hdrlen) ^
-                !!(rtinfo->invflags & IP6T_RT_INV_LEN))));
-       DEBUGP("res %02X %02X %02X ",
-              (rtinfo->flags & IP6T_RT_RES),
-              ((struct rt0_hdr *)rh)->reserved,
-              !((rtinfo->flags & IP6T_RT_RES) &&
-                (((struct rt0_hdr *)rh)->reserved)));
+       pr_debug("IPv6 RT LEN %u %u ", hdrlen, rh->hdrlen);
+       pr_debug("TYPE %04X ", rh->type);
+       pr_debug("SGS_LEFT %u %02X\n", rh->segments_left, rh->segments_left);
+
+       pr_debug("IPv6 RT segsleft %02X ",
+                segsleft_match(rtinfo->segsleft[0], rtinfo->segsleft[1],
+                               rh->segments_left,
+                               !!(rtinfo->invflags & IP6T_RT_INV_SGS)));
+       pr_debug("type %02X %02X %02X ",
+                rtinfo->rt_type, rh->type,
+                (!(rtinfo->flags & IP6T_RT_TYP) ||
+                 ((rtinfo->rt_type == rh->type) ^
+                  !!(rtinfo->invflags & IP6T_RT_INV_TYP))));
+       pr_debug("len %02X %04X %02X ",
+                rtinfo->hdrlen, hdrlen,
+                !(rtinfo->flags & IP6T_RT_LEN) ||
+                 ((rtinfo->hdrlen == hdrlen) ^
+                  !!(rtinfo->invflags & IP6T_RT_INV_LEN)));
+       pr_debug("res %02X %02X %02X ",
+                rtinfo->flags & IP6T_RT_RES,
+                ((const struct rt0_hdr *)rh)->reserved,
+                !((rtinfo->flags & IP6T_RT_RES) &&
+                  (((const struct rt0_hdr *)rh)->reserved)));
 
        ret = (rh != NULL)
              &&
@@ -129,18 +125,18 @@ match(const struct sk_buff *skb,
                ret = (*rp == 0);
        }
 
-       DEBUGP("#%d ", rtinfo->addrnr);
+       pr_debug("#%d ", rtinfo->addrnr);
        if (!(rtinfo->flags & IP6T_RT_FST)) {
                return ret;
        } else if (rtinfo->flags & IP6T_RT_FST_NSTRICT) {
-               DEBUGP("Not strict ");
+               pr_debug("Not strict ");
                if (rtinfo->addrnr > (unsigned int)((hdrlen - 8) / 16)) {
-                       DEBUGP("There isn't enough space\n");
-                       return 0;
+                       pr_debug("There isn't enough space\n");
+                       return false;
                } else {
                        unsigned int i = 0;
 
-                       DEBUGP("#%d ", rtinfo->addrnr);
+                       pr_debug("#%d ", rtinfo->addrnr);
                        for (temp = 0;
                             temp < (unsigned int)((hdrlen - 8) / 16);
                             temp++) {
@@ -154,25 +150,25 @@ match(const struct sk_buff *skb,
                                BUG_ON(ap == NULL);
 
                                if (ipv6_addr_equal(ap, &rtinfo->addrs[i])) {
-                                       DEBUGP("i=%d temp=%d;\n", i, temp);
+                                       pr_debug("i=%d temp=%d;\n", i, temp);
                                        i++;
                                }
                                if (i == rtinfo->addrnr)
                                        break;
                        }
-                       DEBUGP("i=%d #%d\n", i, rtinfo->addrnr);
+                       pr_debug("i=%d #%d\n", i, rtinfo->addrnr);
                        if (i == rtinfo->addrnr)
                                return ret;
                        else
-                               return 0;
+                               return false;
                }
        } else {
-               DEBUGP("Strict ");
+               pr_debug("Strict ");
                if (rtinfo->addrnr > (unsigned int)((hdrlen - 8) / 16)) {
-                       DEBUGP("There isn't enough space\n");
-                       return 0;
+                       pr_debug("There isn't enough space\n");
+                       return false;
                } else {
-                       DEBUGP("#%d ", rtinfo->addrnr);
+                       pr_debug("#%d ", rtinfo->addrnr);
                        for (temp = 0; temp < rtinfo->addrnr; temp++) {
                                ap = skb_header_pointer(skb,
                                                        ptr
@@ -185,20 +181,20 @@ match(const struct sk_buff *skb,
                                if (!ipv6_addr_equal(ap, &rtinfo->addrs[temp]))
                                        break;
                        }
-                       DEBUGP("temp=%d #%d\n", temp, rtinfo->addrnr);
-                       if ((temp == rtinfo->addrnr) &&
-                           (temp == (unsigned int)((hdrlen - 8) / 16)))
+                       pr_debug("temp=%d #%d\n", temp, rtinfo->addrnr);
+                       if (temp == rtinfo->addrnr &&
+                           temp == (unsigned int)((hdrlen - 8) / 16))
                                return ret;
                        else
-                               return 0;
+                               return false;
                }
        }
 
-       return 0;
+       return false;
 }
 
 /* Called when user tries to insert an entry of this type. */
-static int
+static bool
 checkentry(const char *tablename,
           const void *entry,
           const struct xt_match *match,
@@ -208,21 +204,21 @@ checkentry(const char *tablename,
        const struct ip6t_rt *rtinfo = matchinfo;
 
        if (rtinfo->invflags & ~IP6T_RT_INV_MASK) {
-               DEBUGP("ip6t_rt: unknown flags %X\n", rtinfo->invflags);
-               return 0;
+               pr_debug("ip6t_rt: unknown flags %X\n", rtinfo->invflags);
+               return false;
        }
        if ((rtinfo->flags & (IP6T_RT_RES | IP6T_RT_FST_MASK)) &&
            (!(rtinfo->flags & IP6T_RT_TYP) ||
             (rtinfo->rt_type != 0) ||
             (rtinfo->invflags & IP6T_RT_INV_TYP))) {
-               DEBUGP("`--rt-type 0' required before `--rt-0-*'");
-               return 0;
+               pr_debug("`--rt-type 0' required before `--rt-0-*'");
+               return false;
        }
 
-       return 1;
+       return true;
 }
 
-static struct xt_match rt_match = {
+static struct xt_match rt_match __read_mostly = {
        .name           = "rt",
        .family         = AF_INET6,
        .match          = match,
index f2d26495f41350edbf981e12dbdc4c8f4b4087c8..f0a9efa67fb52e242335b6c7ae39145c0c0de2ec 100644 (file)
@@ -21,12 +21,6 @@ MODULE_DESCRIPTION("ip6tables mangle table");
                            (1 << NF_IP6_LOCAL_OUT) | \
                            (1 << NF_IP6_POST_ROUTING))
 
-#if 0
-#define DEBUGP(x, args...)     printk(KERN_DEBUG x, ## args)
-#else
-#define DEBUGP(x, args...)
-#endif
-
 static struct
 {
        struct ip6t_replace repl;
index 0acda45d455d7251df207fe799464cd342aeb15d..ec290e4ebdd86c4333f7dd3f33c47d54453bf3af 100644 (file)
@@ -8,12 +8,6 @@
 
 #define RAW_VALID_HOOKS ((1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_OUT))
 
-#if 0
-#define DEBUGP(x, args...)     printk(KERN_DEBUG x, ## args)
-#else
-#define DEBUGP(x, args...)
-#endif
-
 static struct
 {
        struct ip6t_replace repl;
index 1b1797f1f33d0e839926dab7b3fcc88cfacb85c8..89e20ab494b8ca5246587596b25d5fb04c8fa37f 100644 (file)
 #include <net/netfilter/nf_conntrack_l3proto.h>
 #include <net/netfilter/nf_conntrack_core.h>
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 static int ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
                             struct nf_conntrack_tuple *tuple)
 {
@@ -136,7 +130,7 @@ ipv6_prepare(struct sk_buff **pskb, unsigned int hooknum, unsigned int *dataoff,
         * except of IPv6 & ext headers. but it's tracked anyway. - YK
         */
        if ((protoff < 0) || (protoff > (*pskb)->len)) {
-               DEBUGP("ip6_conntrack_core: can't find proto in pkt\n");
+               pr_debug("ip6_conntrack_core: can't find proto in pkt\n");
                NF_CT_STAT_INC_ATOMIC(error);
                NF_CT_STAT_INC_ATOMIC(invalid);
                return -NF_ACCEPT;
@@ -147,11 +141,6 @@ ipv6_prepare(struct sk_buff **pskb, unsigned int hooknum, unsigned int *dataoff,
        return NF_ACCEPT;
 }
 
-static u_int32_t ipv6_get_features(const struct nf_conntrack_tuple *tuple)
-{
-       return NF_CT_F_BASIC;
-}
-
 static unsigned int ipv6_confirm(unsigned int hooknum,
                                 struct sk_buff **pskb,
                                 const struct net_device *in,
@@ -183,7 +172,7 @@ static unsigned int ipv6_confirm(unsigned int hooknum,
        protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum,
                                         (*pskb)->len - extoff);
        if (protoff > (*pskb)->len || pnum == NEXTHDR_FRAGMENT) {
-               DEBUGP("proto header not found\n");
+               pr_debug("proto header not found\n");
                return NF_ACCEPT;
        }
 
@@ -397,7 +386,6 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 = {
        .ctl_table_path         = nf_net_netfilter_sysctl_path,
        .ctl_table              = nf_ct_ipv6_sysctl_table,
 #endif
-       .get_features           = ipv6_get_features,
        .me                     = THIS_MODULE,
 };
 
index 8814b95b232630604eb4e568d7771bcda8e47cb6..9defc7e14554b4cc431deb5223764cb8a4deebe2 100644 (file)
 
 static unsigned long nf_ct_icmpv6_timeout __read_mostly = 30*HZ;
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 static int icmpv6_pkt_to_tuple(const struct sk_buff *skb,
                               unsigned int dataoff,
                               struct nf_conntrack_tuple *tuple)
@@ -125,8 +119,8 @@ static int icmpv6_new(struct nf_conn *conntrack,
 
        if (type < 0 || type >= sizeof(valid_new) || !valid_new[type]) {
                /* Can't create a new ICMPv6 `conn' with this. */
-               DEBUGP("icmpv6: can't create new conn with type %u\n",
-                      type + 128);
+               pr_debug("icmpv6: can't create new conn with type %u\n",
+                        type + 128);
                NF_CT_DUMP_TUPLE(&conntrack->tuplehash[0].tuple);
                return 0;
        }
@@ -152,14 +146,15 @@ icmpv6_error_message(struct sk_buff *skb,
 
        hp = skb_header_pointer(skb, icmp6off, sizeof(_hdr), &_hdr);
        if (hp == NULL) {
-               DEBUGP("icmpv6_error: Can't get ICMPv6 hdr.\n");
+               pr_debug("icmpv6_error: Can't get ICMPv6 hdr.\n");
                return -NF_ACCEPT;
        }
 
        inip6off = icmp6off + sizeof(_hdr);
        if (skb_copy_bits(skb, inip6off+offsetof(struct ipv6hdr, nexthdr),
                          &inprotonum, sizeof(inprotonum)) != 0) {
-               DEBUGP("icmpv6_error: Can't get nexthdr in inner IPv6 header.\n");
+               pr_debug("icmpv6_error: Can't get nexthdr in inner IPv6 "
+                        "header.\n");
                return -NF_ACCEPT;
        }
        inprotoff = nf_ct_ipv6_skip_exthdr(skb,
@@ -169,7 +164,8 @@ icmpv6_error_message(struct sk_buff *skb,
                                                    - sizeof(struct ipv6hdr));
 
        if ((inprotoff > skb->len) || (inprotonum == NEXTHDR_FRAGMENT)) {
-               DEBUGP("icmpv6_error: Can't get protocol header in ICMPv6 payload.\n");
+               pr_debug("icmpv6_error: Can't get protocol header in ICMPv6 "
+                        "payload.\n");
                return -NF_ACCEPT;
        }
 
@@ -179,7 +175,7 @@ icmpv6_error_message(struct sk_buff *skb,
        /* Are they talking about one of our connections? */
        if (!nf_ct_get_tuple(skb, inip6off, inprotoff, PF_INET6, inprotonum,
                             &origtuple, &nf_conntrack_l3proto_ipv6, inproto)) {
-               DEBUGP("icmpv6_error: Can't get tuple\n");
+               pr_debug("icmpv6_error: Can't get tuple\n");
                return -NF_ACCEPT;
        }
 
@@ -187,15 +183,15 @@ icmpv6_error_message(struct sk_buff *skb,
           been preserved inside the ICMP. */
        if (!nf_ct_invert_tuple(&intuple, &origtuple,
                                &nf_conntrack_l3proto_ipv6, inproto)) {
-               DEBUGP("icmpv6_error: Can't invert tuple\n");
+               pr_debug("icmpv6_error: Can't invert tuple\n");
                return -NF_ACCEPT;
        }
 
        *ctinfo = IP_CT_RELATED;
 
-       h = nf_conntrack_find_get(&intuple, NULL);
+       h = nf_conntrack_find_get(&intuple);
        if (!h) {
-               DEBUGP("icmpv6_error: no match\n");
+               pr_debug("icmpv6_error: no match\n");
                return -NF_ACCEPT;
        } else {
                if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY)
index 347ab7608231911981855d389279837e15eb88c9..25442a8c1ba82fec69f40226f31487d4b4adfddb 100644 (file)
 #include <linux/kernel.h>
 #include <linux/module.h>
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 #define NF_CT_FRAG6_HIGH_THRESH 262144 /* == 256*1024 */
 #define NF_CT_FRAG6_LOW_THRESH 196608  /* == 192*1024 */
 #define NF_CT_FRAG6_TIMEOUT IPV6_FRAG_TIMEOUT
@@ -343,7 +337,7 @@ nf_ct_frag6_create(unsigned int hash, __be32 id, struct in6_addr *src,                                 str
        struct nf_ct_frag6_queue *fq;
 
        if ((fq = frag_alloc_queue()) == NULL) {
-               DEBUGP("Can't alloc new queue\n");
+               pr_debug("Can't alloc new queue\n");
                goto oom;
        }
 
@@ -393,7 +387,7 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
        int offset, end;
 
        if (fq->last_in & COMPLETE) {
-               DEBUGP("Allready completed\n");
+               pr_debug("Allready completed\n");
                goto err;
        }
 
@@ -402,7 +396,7 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
                        ((u8 *)(fhdr + 1) - (u8 *)(ipv6_hdr(skb) + 1)));
 
        if ((unsigned int)end > IPV6_MAXPLEN) {
-               DEBUGP("offset is too large.\n");
+               pr_debug("offset is too large.\n");
                return -1;
        }
 
@@ -420,7 +414,7 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
                 */
                if (end < fq->len ||
                    ((fq->last_in & LAST_IN) && end != fq->len)) {
-                       DEBUGP("already received last fragment\n");
+                       pr_debug("already received last fragment\n");
                        goto err;
                }
                fq->last_in |= LAST_IN;
@@ -433,13 +427,13 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
                        /* RFC2460 says always send parameter problem in
                         * this case. -DaveM
                         */
-                       DEBUGP("the end of this fragment is not rounded to 8 bytes.\n");
+                       pr_debug("end of fragment not rounded to 8 bytes.\n");
                        return -1;
                }
                if (end > fq->len) {
                        /* Some bits beyond end -> corruption. */
                        if (fq->last_in & LAST_IN) {
-                               DEBUGP("last packet already reached.\n");
+                               pr_debug("last packet already reached.\n");
                                goto err;
                        }
                        fq->len = end;
@@ -451,11 +445,11 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
 
        /* Point into the IP datagram 'data' part. */
        if (!pskb_pull(skb, (u8 *) (fhdr + 1) - skb->data)) {
-               DEBUGP("queue: message is too short.\n");
+               pr_debug("queue: message is too short.\n");
                goto err;
        }
        if (pskb_trim_rcsum(skb, end - offset)) {
-               DEBUGP("Can't trim\n");
+               pr_debug("Can't trim\n");
                goto err;
        }
 
@@ -480,11 +474,11 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
                if (i > 0) {
                        offset += i;
                        if (end <= offset) {
-                               DEBUGP("overlap\n");
+                               pr_debug("overlap\n");
                                goto err;
                        }
                        if (!pskb_pull(skb, i)) {
-                               DEBUGP("Can't pull\n");
+                               pr_debug("Can't pull\n");
                                goto err;
                        }
                        if (skb->ip_summed != CHECKSUM_UNNECESSARY)
@@ -503,7 +497,7 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
                        /* Eat head of the next overlapped fragment
                         * and leave the loop. The next ones cannot overlap.
                         */
-                       DEBUGP("Eat head of the overlapped parts.: %d", i);
+                       pr_debug("Eat head of the overlapped parts.: %d", i);
                        if (!pskb_pull(next, i))
                                goto err;
 
@@ -586,13 +580,13 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
                       sizeof(struct ipv6hdr) + fq->len -
                       sizeof(struct frag_hdr));
        if (payload_len > IPV6_MAXPLEN) {
-               DEBUGP("payload len is too large.\n");
+               pr_debug("payload len is too large.\n");
                goto out_oversize;
        }
 
        /* Head of list must not be cloned. */
        if (skb_cloned(head) && pskb_expand_head(head, 0, 0, GFP_ATOMIC)) {
-               DEBUGP("skb is cloned but can't expand head");
+               pr_debug("skb is cloned but can't expand head");
                goto out_oom;
        }
 
@@ -604,7 +598,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
                int i, plen = 0;
 
                if ((clone = alloc_skb(0, GFP_ATOMIC)) == NULL) {
-                       DEBUGP("Can't alloc skb\n");
+                       pr_debug("Can't alloc skb\n");
                        goto out_oom;
                }
                clone->next = head->next;
@@ -719,11 +713,11 @@ find_prev_fhdr(struct sk_buff *skb, u8 *prevhdrp, int *prevhoff, int *fhoff)
                        return -1;
                }
                if (len < (int)sizeof(struct ipv6_opt_hdr)) {
-                       DEBUGP("too short\n");
+                       pr_debug("too short\n");
                        return -1;
                }
                if (nexthdr == NEXTHDR_NONE) {
-                       DEBUGP("next header is none\n");
+                       pr_debug("next header is none\n");
                        return -1;
                }
                if (skb_copy_bits(skb, start, &hdr, sizeof(hdr)))
@@ -764,7 +758,7 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb)
 
        /* Jumbo payload inhibits frag. header */
        if (ipv6_hdr(skb)->payload_len == 0) {
-               DEBUGP("payload len = 0\n");
+               pr_debug("payload len = 0\n");
                return skb;
        }
 
@@ -773,14 +767,14 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb)
 
        clone = skb_clone(skb, GFP_ATOMIC);
        if (clone == NULL) {
-               DEBUGP("Can't clone skb\n");
+               pr_debug("Can't clone skb\n");
                return skb;
        }
 
        NFCT_FRAG6_CB(clone)->orig = skb;
 
        if (!pskb_may_pull(clone, fhoff + sizeof(*fhdr))) {
-               DEBUGP("message is too short.\n");
+               pr_debug("message is too short.\n");
                goto ret_orig;
        }
 
@@ -789,7 +783,7 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb)
        fhdr = (struct frag_hdr *)skb_transport_header(clone);
 
        if (!(fhdr->frag_off & htons(0xFFF9))) {
-               DEBUGP("Invalid fragment offset\n");
+               pr_debug("Invalid fragment offset\n");
                /* It is not a fragmented frame */
                goto ret_orig;
        }
@@ -799,7 +793,7 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb)
 
        fq = fq_find(fhdr->identification, &hdr->saddr, &hdr->daddr);
        if (fq == NULL) {
-               DEBUGP("Can't find and can't create new queue\n");
+               pr_debug("Can't find and can't create new queue\n");
                goto ret_orig;
        }
 
@@ -807,7 +801,7 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb)
 
        if (nf_ct_frag6_queue(fq, clone, fhdr, nhoff) < 0) {
                spin_unlock(&fq->lock);
-               DEBUGP("Can't insert skb to queue\n");
+               pr_debug("Can't insert skb to queue\n");
                fq_put(fq, NULL);
                goto ret_orig;
        }
@@ -815,7 +809,7 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb)
        if (fq->last_in == (FIRST_IN|LAST_IN) && fq->meat == fq->len) {
                ret_skb = nf_ct_frag6_reasm(fq, dev);
                if (ret_skb == NULL)
-                       DEBUGP("Can't reassemble fragmented packets\n");
+                       pr_debug("Can't reassemble fragmented packets\n");
        }
        spin_unlock(&fq->lock);
 
index a58459a766849fe71e2fa4c08cb67dd65e78aa03..e27383d855dedfeffc1855ec906ea2522c8344e2 100644 (file)
@@ -49,7 +49,7 @@
 #include <net/udp.h>
 #include <net/inet_common.h>
 #include <net/tcp_states.h>
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 #include <net/mip6.h>
 #endif
 
@@ -137,6 +137,28 @@ static __inline__ int icmpv6_filter(struct sock *sk, struct sk_buff *skb)
        return 0;
 }
 
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+static int (*mh_filter)(struct sock *sock, struct sk_buff *skb);
+
+int rawv6_mh_filter_register(int (*filter)(struct sock *sock,
+                                          struct sk_buff *skb))
+{
+       rcu_assign_pointer(mh_filter, filter);
+       return 0;
+}
+EXPORT_SYMBOL(rawv6_mh_filter_register);
+
+int rawv6_mh_filter_unregister(int (*filter)(struct sock *sock,
+                                            struct sk_buff *skb))
+{
+       rcu_assign_pointer(mh_filter, NULL);
+       synchronize_rcu();
+       return 0;
+}
+EXPORT_SYMBOL(rawv6_mh_filter_unregister);
+
+#endif
+
 /*
  *     demultiplex raw sockets.
  *     (should consider queueing the skb in the sock receive_queue
@@ -178,16 +200,22 @@ int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
                case IPPROTO_ICMPV6:
                        filtered = icmpv6_filter(sk, skb);
                        break;
-#ifdef CONFIG_IPV6_MIP6
+
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
                case IPPROTO_MH:
+               {
                        /* XXX: To validate MH only once for each packet,
                         * this is placed here. It should be after checking
                         * xfrm policy, however it doesn't. The checking xfrm
                         * policy is placed in rawv6_rcv() because it is
                         * required for each socket.
                         */
-                       filtered = mip6_mh_filter(sk, skb);
+                       int (*filter)(struct sock *sock, struct sk_buff *skb);
+
+                       filter = rcu_dereference(mh_filter);
+                       filtered = filter ? filter(sk, skb) : 0;
                        break;
+               }
 #endif
                default:
                        filtered = 0;
@@ -611,9 +639,7 @@ static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
        struct iovec *iov;
        u8 __user *type = NULL;
        u8 __user *code = NULL;
-#ifdef CONFIG_IPV6_MIP6
        u8 len = 0;
-#endif
        int probed = 0;
        int i;
 
@@ -646,7 +672,6 @@ static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
                                probed = 1;
                        }
                        break;
-#ifdef CONFIG_IPV6_MIP6
                case IPPROTO_MH:
                        if (iov->iov_base && iov->iov_len < 1)
                                break;
@@ -660,7 +685,6 @@ static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
                                len += iov->iov_len;
 
                        break;
-#endif
                default:
                        probed = 1;
                        break;
@@ -1256,7 +1280,7 @@ static int raw6_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations raw6_seq_ops = {
+static const struct seq_operations raw6_seq_ops = {
        .start =        raw6_seq_start,
        .next =         raw6_seq_next,
        .stop =         raw6_seq_stop,
index 1efa95a99f4533198e353f713f7287cb522ec55d..eb20bb690abd736e6699f1af7987cb8a1287d3c3 100644 (file)
@@ -532,7 +532,8 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
         */
        max_headroom = LL_RESERVED_SPACE(tdev)+sizeof(struct iphdr);
 
-       if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) {
+       if (skb_headroom(skb) < max_headroom || skb_shared(skb) ||
+           (skb_cloned(skb) && !skb_clone_writable(skb, 0))) {
                struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
                if (!new_skb) {
                        ip_rt_put(rt);
index 193d9d60bb7a8fabb0ab3eec481e1a7ce0ff1b86..d67fb1ef751edc270eaa832d4048c8bff4faa5a0 100644 (file)
@@ -484,17 +484,6 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
 
        if (dst == NULL) {
                opt = np->opt;
-               if (opt == NULL &&
-                   np->rxopt.bits.osrcrt == 2 &&
-                   treq->pktopts) {
-                       struct sk_buff *pktopts = treq->pktopts;
-                       struct inet6_skb_parm *rxopt = IP6CB(pktopts);
-                       if (rxopt->srcrt)
-                               opt = ipv6_invert_rthdr(sk,
-                         (struct ipv6_rt_hdr *)(skb_network_header(pktopts) +
-                                                rxopt->srcrt));
-               }
-
                if (opt && opt->srcrt) {
                        struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
                        ipv6_addr_copy(&final, &fl.fl6_dst);
@@ -1391,15 +1380,6 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
        if (sk_acceptq_is_full(sk))
                goto out_overflow;
 
-       if (np->rxopt.bits.osrcrt == 2 &&
-           opt == NULL && treq->pktopts) {
-               struct inet6_skb_parm *rxopt = IP6CB(treq->pktopts);
-               if (rxopt->srcrt)
-                       opt = ipv6_invert_rthdr(sk,
-                  (struct ipv6_rt_hdr *)(skb_network_header(treq->pktopts) +
-                                         rxopt->srcrt));
-       }
-
        if (dst == NULL) {
                struct in6_addr *final_p = NULL, final;
                struct flowi fl;
index 1faa2ea80afc19e2ef246768388604ef616dde40..3ec0c4770ee35346693bc52ea35d434aea28d815 100644 (file)
@@ -18,7 +18,7 @@
 #include <net/ip.h>
 #include <net/ipv6.h>
 #include <net/ip6_route.h>
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 #include <net/mip6.h>
 #endif
 
@@ -318,7 +318,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl)
                        fl->proto = nexthdr;
                        return;
 
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
                case IPPROTO_MH:
                        if (pskb_may_pull(skb, nh + offset + 3 - skb->data)) {
                                struct ip6_mh *mh;
index baa461b9f74eebf97c654aa858203dcf010aa7e8..cdadb4847469f21e52237c75d5f12abaac9a5ffb 100644 (file)
@@ -65,7 +65,7 @@ __xfrm6_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n)
                goto end;
 
        /* Rule 2: select MIPv6 RO or inbound trigger */
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
        for (i = 0; i < n; i++) {
                if (src[i] &&
                    (src[i]->props.mode == XFRM_MODE_ROUTEOPTIMIZATION ||
@@ -130,7 +130,7 @@ __xfrm6_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n)
                goto end;
 
        /* Rule 2: select MIPv6 RO or inbound trigger */
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
        for (i = 0; i < n; i++) {
                if (src[i] &&
                    (src[i]->mode == XFRM_MODE_ROUTEOPTIMIZATION ||
index 5502cc948dfbb3ddb1a97bed03bd5d2320a8b891..6f87dd568dedf494bf93af3f1f4f7276ef9c3cfd 100644 (file)
@@ -379,3 +379,4 @@ static void __exit xfrm6_tunnel_fini(void)
 module_init(xfrm6_tunnel_init);
 module_exit(xfrm6_tunnel_fini);
 MODULE_LICENSE("GPL");
+MODULE_ALIAS_XFRM_TYPE(AF_INET6, XFRM_PROTO_IPV6);
index db32ac8e79bd6ed5b9e7b7b84f6aa67bfafcfead..4226e71ae1e3d04c9642c26d0cd4132f3765b674 100644 (file)
@@ -286,21 +286,21 @@ out:
        return 0;
 }
 
-static struct seq_operations ipx_seq_interface_ops = {
+static const struct seq_operations ipx_seq_interface_ops = {
        .start  = ipx_seq_interface_start,
        .next   = ipx_seq_interface_next,
        .stop   = ipx_seq_interface_stop,
        .show   = ipx_seq_interface_show,
 };
 
-static struct seq_operations ipx_seq_route_ops = {
+static const struct seq_operations ipx_seq_route_ops = {
        .start  = ipx_seq_route_start,
        .next   = ipx_seq_route_next,
        .stop   = ipx_seq_route_stop,
        .show   = ipx_seq_route_show,
 };
 
-static struct seq_operations ipx_seq_socket_ops = {
+static const struct seq_operations ipx_seq_socket_ops = {
        .start  = ipx_seq_socket_start,
        .next   = ipx_seq_socket_next,
        .stop   = ipx_seq_interface_stop,
index d1366c2a39cb6550874b08cd4c2d0702875a79c8..187f6c563a4b4a82ab31bbea09cc18cbefea34bb 100644 (file)
@@ -10,6 +10,6 @@ obj-$(CONFIG_IRCOMM) += ircomm/
 irda-y := iriap.o iriap_event.o irlmp.o irlmp_event.o irlmp_frame.o \
           irlap.o irlap_event.o irlap_frame.o timer.o qos.o irqueue.o \
           irttp.o irda_device.o irias_object.o wrapper.o af_irda.o \
-         discovery.o parameters.o irmod.o
+         discovery.o parameters.o irnetlink.o irmod.o
 irda-$(CONFIG_PROC_FS) += irproc.o
 irda-$(CONFIG_SYSCTL) += irsysctl.o
index f097341286740182d5726ebb2bb5e0c43fcf8e2a..af0cea721d2acd19cfd16f83efed38b6d18826b6 100644 (file)
@@ -395,7 +395,7 @@ static int discovery_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations discovery_seq_ops = {
+static const struct seq_operations discovery_seq_ops = {
        .start  = discovery_seq_start,
        .next   = discovery_seq_next,
        .stop   = discovery_seq_stop,
index 4749f8f55391a32d8e5c46abb6a900f1db799636..2d63fa8e155641f1bf4937ee0c733041f97000e5 100644 (file)
@@ -562,7 +562,7 @@ static int ircomm_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations ircomm_seq_ops = {
+static const struct seq_operations ircomm_seq_ops = {
        .start  = ircomm_seq_start,
        .next   = ircomm_seq_next,
        .stop   = ircomm_seq_stop,
index 915d9384f36a1784fe84f476b4c48f099a82168c..774eb707940c5929010254cd092fedb87e519548 100644 (file)
@@ -1066,7 +1066,7 @@ static int irias_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations irias_seq_ops = {
+static const struct seq_operations irias_seq_ops = {
        .start  = irias_seq_start,
        .next   = irias_seq_next,
        .stop   = irias_seq_stop,
index ed69773b0f8ed8d2d1dd3183fbb97d6c1984f75e..f5778ef3ccc7213ac7e3b179813324aa2973a1c7 100644 (file)
@@ -1217,7 +1217,7 @@ static int irlan_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations irlan_seq_ops = {
+static const struct seq_operations irlan_seq_ops = {
        .start = irlan_seq_start,
        .next  = irlan_seq_next,
        .stop  = irlan_seq_stop,
index d93ebd11431e86b2c82f65fc220e7e1316abfc50..2fc9f518f89db45771d3514bc9bee1bbef27f96b 100644 (file)
@@ -1210,7 +1210,7 @@ static int irlap_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations irlap_seq_ops = {
+static const struct seq_operations irlap_seq_ops = {
        .start  = irlap_seq_start,
        .next   = irlap_seq_next,
        .stop   = irlap_seq_stop,
index 3013c49ab975e865b593746911f0d88f2921c8b0..25a3444a9234f1faba7ba2e2e88b18e452d1f44f 100644 (file)
@@ -101,6 +101,13 @@ void irlap_queue_xmit(struct irlap_cb *self, struct sk_buff *skb)
 
        irlap_insert_info(self, skb);
 
+       if (unlikely(self->mode & IRDA_MODE_MONITOR)) {
+               IRDA_DEBUG(3, "%s(): %s is in monitor mode\n", __FUNCTION__,
+                          self->netdev->name);
+               dev_kfree_skb(skb);
+               return;
+       }
+
        dev_queue_xmit(skb);
 }
 
index 9df0461b6d18fe8b6750b77c2d1bbc716236ca60..24a5e3f237782b5017330b14ea58d2b401e3a1a7 100644 (file)
@@ -1994,7 +1994,7 @@ static int irlmp_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations irlmp_seq_ops = {
+static const struct seq_operations irlmp_seq_ops = {
        .start  = irlmp_seq_start,
        .next   = irlmp_seq_next,
        .stop   = irlmp_seq_stop,
index c7fad2c5b9f3508867130646681b5155e7fec108..1900937b332871b350e9ae539b417df8c3a1e446 100644 (file)
@@ -88,16 +88,23 @@ EXPORT_SYMBOL(irda_notify_init);
  */
 static int __init irda_init(void)
 {
+       int ret = 0;
+
        IRDA_DEBUG(0, "%s()\n", __FUNCTION__);
 
        /* Lower layer of the stack */
        irlmp_init();
        irlap_init();
 
+       /* Driver/dongle support */
+       irda_device_init();
+
        /* Higher layers of the stack */
        iriap_init();
        irttp_init();
-       irsock_init();
+       ret = irsock_init();
+       if (ret < 0)
+               goto out_err_1;
 
        /* Add IrDA packet type (Start receiving packets) */
        dev_add_pack(&irda_packet_type);
@@ -107,13 +114,44 @@ static int __init irda_init(void)
        irda_proc_register();
 #endif
 #ifdef CONFIG_SYSCTL
-       irda_sysctl_register();
+       ret = irda_sysctl_register();
+       if (ret < 0)
+               goto out_err_2;
 #endif
 
-       /* Driver/dongle support */
-       irda_device_init();
+       ret = irda_nl_register();
+       if (ret < 0)
+               goto out_err_3;
 
        return 0;
+
+ out_err_3:
+#ifdef CONFIG_SYSCTL
+       irda_sysctl_unregister();
+#endif
+ out_err_2:
+#ifdef CONFIG_PROC_FS
+       irda_proc_unregister();
+#endif
+
+       /* Remove IrDA packet type (stop receiving packets) */
+       dev_remove_pack(&irda_packet_type);
+
+       /* Remove higher layers */
+       irsock_cleanup();
+ out_err_1:
+       irttp_cleanup();
+       iriap_cleanup();
+
+       /* Remove lower layers */
+       irda_device_cleanup();
+       irlap_cleanup(); /* Must be done before irlmp_cleanup()! DB */
+
+       /* Remove middle layer */
+       irlmp_cleanup();
+
+
+       return ret;
 }
 
 /*
@@ -125,6 +163,8 @@ static int __init irda_init(void)
 static void __exit irda_cleanup(void)
 {
        /* Remove External APIs */
+       irda_nl_unregister();
+
 #ifdef CONFIG_SYSCTL
        irda_sysctl_unregister();
 #endif
diff --git a/net/irda/irnetlink.c b/net/irda/irnetlink.c
new file mode 100644 (file)
index 0000000..db71658
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * IrDA netlink layer, for stack configuration.
+ *
+ * Copyright (c) 2007 Samuel Ortiz <samuel@sortiz>
+ *
+ * Partly based on the 802.11 nelink implementation
+ * (see net/wireless/nl80211.c) which is:
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * 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/socket.h>
+#include <linux/irda.h>
+#include <net/sock.h>
+#include <net/irda/irda.h>
+#include <net/irda/irlap.h>
+#include <net/genetlink.h>
+
+
+
+static struct genl_family irda_nl_family = {
+       .id = GENL_ID_GENERATE,
+       .name = IRDA_NL_NAME,
+       .hdrsize = 0,
+       .version = IRDA_NL_VERSION,
+       .maxattr = IRDA_NL_CMD_MAX,
+};
+
+static struct net_device * ifname_to_netdev(struct genl_info *info)
+{
+       char * ifname;
+
+       if (!info->attrs[IRDA_NL_ATTR_IFNAME])
+               return NULL;
+
+       ifname = nla_data(info->attrs[IRDA_NL_ATTR_IFNAME]);
+
+       IRDA_DEBUG(5, "%s(): Looking for %s\n", __FUNCTION__, ifname);
+
+       return dev_get_by_name(ifname);
+}
+
+static int irda_nl_set_mode(struct sk_buff *skb, struct genl_info *info)
+{
+       struct net_device * dev;
+       struct irlap_cb * irlap;
+       u32 mode;
+
+       if (!info->attrs[IRDA_NL_ATTR_MODE])
+               return -EINVAL;
+
+       mode = nla_get_u32(info->attrs[IRDA_NL_ATTR_MODE]);
+
+       IRDA_DEBUG(5, "%s(): Switching to mode: %d\n", __FUNCTION__, mode);
+
+       dev = ifname_to_netdev(info);
+       if (!dev)
+               return -ENODEV;
+
+       irlap = (struct irlap_cb *)dev->atalk_ptr;
+       if (!irlap) {
+               dev_put(dev);
+               return -ENODEV;
+       }
+
+       irlap->mode = mode;
+
+       dev_put(dev);
+
+       return 0;
+}
+
+static int irda_nl_get_mode(struct sk_buff *skb, struct genl_info *info)
+{
+       struct net_device * dev;
+       struct irlap_cb * irlap;
+       struct sk_buff *msg;
+       void *hdr;
+       int ret = -ENOBUFS;
+
+       dev = ifname_to_netdev(info);
+       if (!dev)
+               return -ENODEV;
+
+       msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+       if (!msg) {
+               dev_put(dev);
+               return -ENOMEM;
+       }
+
+       irlap = (struct irlap_cb *)dev->atalk_ptr;
+       if (!irlap) {
+               ret = -ENODEV;
+               goto err_out;
+       }
+
+       hdr = genlmsg_put(msg, info->snd_pid, info->snd_seq,
+                         &irda_nl_family, 0,  IRDA_NL_CMD_GET_MODE);
+       if (IS_ERR(hdr)) {
+               ret = PTR_ERR(hdr);
+               goto err_out;
+       }
+
+       if(nla_put_string(msg, IRDA_NL_ATTR_IFNAME,
+                         dev->name));
+               goto err_out;
+
+       if(nla_put_u32(msg, IRDA_NL_ATTR_MODE, irlap->mode))
+               goto err_out;
+
+       genlmsg_end(msg, hdr);
+
+       return genlmsg_unicast(msg, info->snd_pid);
+
+ err_out:
+       nlmsg_free(msg);
+       dev_put(dev);
+
+       return ret;
+}
+
+static struct nla_policy irda_nl_policy[IRDA_NL_ATTR_MAX + 1] = {
+       [IRDA_NL_ATTR_IFNAME] = { .type = NLA_NUL_STRING,
+                                 .len = IFNAMSIZ-1 },
+       [IRDA_NL_ATTR_MODE] = { .type = NLA_U32 },
+};
+
+static struct genl_ops irda_nl_ops[] = {
+       {
+               .cmd = IRDA_NL_CMD_SET_MODE,
+               .doit = irda_nl_set_mode,
+               .policy = irda_nl_policy,
+               .flags = GENL_ADMIN_PERM,
+       },
+       {
+               .cmd = IRDA_NL_CMD_GET_MODE,
+               .doit = irda_nl_get_mode,
+               .policy = irda_nl_policy,
+               /* can be retrieved by unprivileged users */
+       },
+
+};
+
+int irda_nl_register(void)
+{
+       int err, i;
+
+       err = genl_register_family(&irda_nl_family);
+       if (err)
+               return err;
+
+       for (i = 0; i < ARRAY_SIZE(irda_nl_ops); i++) {
+               err = genl_register_ops(&irda_nl_family, &irda_nl_ops[i]);
+               if (err)
+                       goto err_out;
+       }
+       return 0;
+ err_out:
+       genl_unregister_family(&irda_nl_family);
+       return err;
+}
+
+void irda_nl_unregister(void)
+{
+       genl_unregister_family(&irda_nl_family);
+}
index 7069e4a58257e700ad3b5061ffd7bc6dd789fedf..7f50832a2cd5a2349e8f76dc0dd3a2141d3a9df7 100644 (file)
@@ -368,6 +368,20 @@ static int irttp_param_max_sdu_size(void *instance, irda_param_t *param,
 /************************** LMP CALLBACKS **************************/
 /* Everything is happily mixed up. Waiting for next clean up - Jean II */
 
+/*
+ * Initialization, that has to be done on new tsap
+ * instance allocation and on duplication
+ */
+static void irttp_init_tsap(struct tsap_cb *tsap)
+{
+       spin_lock_init(&tsap->lock);
+       init_timer(&tsap->todo_timer);
+
+       skb_queue_head_init(&tsap->rx_queue);
+       skb_queue_head_init(&tsap->tx_queue);
+       skb_queue_head_init(&tsap->rx_fragments);
+}
+
 /*
  * Function irttp_open_tsap (stsap, notify)
  *
@@ -395,10 +409,11 @@ struct tsap_cb *irttp_open_tsap(__u8 stsap_sel, int credit, notify_t *notify)
                IRDA_DEBUG(0, "%s(), unable to kmalloc!\n", __FUNCTION__);
                return NULL;
        }
-       spin_lock_init(&self->lock);
+
+       /* Initialize internal objects */
+       irttp_init_tsap(self);
 
        /* Initialise todo timer */
-       init_timer(&self->todo_timer);
        self->todo_timer.data     = (unsigned long) self;
        self->todo_timer.function = &irttp_todo_expired;
 
@@ -418,9 +433,6 @@ struct tsap_cb *irttp_open_tsap(__u8 stsap_sel, int credit, notify_t *notify)
        self->magic = TTP_TSAP_MAGIC;
        self->connected = FALSE;
 
-       skb_queue_head_init(&self->rx_queue);
-       skb_queue_head_init(&self->tx_queue);
-       skb_queue_head_init(&self->rx_fragments);
        /*
         *  Create LSAP at IrLMP layer
         */
@@ -1455,12 +1467,9 @@ struct tsap_cb *irttp_dup(struct tsap_cb *orig, void *instance)
 
        /* Not everything should be copied */
        new->notify.instance = instance;
-       spin_lock_init(&new->lock);
-       init_timer(&new->todo_timer);
 
-       skb_queue_head_init(&new->rx_queue);
-       skb_queue_head_init(&new->tx_queue);
-       skb_queue_head_init(&new->rx_fragments);
+       /* Initialize internal objects */
+       irttp_init_tsap(new);
 
        /* This is locked */
        hashbin_insert(irttp->tsaps, (irda_queue_t *) new, (long) new, NULL);
@@ -1866,7 +1875,7 @@ static int irttp_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations irttp_seq_ops = {
+static const struct seq_operations irttp_seq_ops = {
        .start  = irttp_seq_start,
        .next   = irttp_seq_next,
        .stop   = irttp_seq_stop,
index 3ab9d9f8b17fc8d4368dd03e32ff134c9e8776fa..49be6c902c8326790898fc982b75ae3b7ca4874c 100644 (file)
@@ -184,14 +184,14 @@ out:
        return 0;
 }
 
-static struct seq_operations llc_seq_socket_ops = {
+static const struct seq_operations llc_seq_socket_ops = {
        .start  = llc_seq_start,
        .next   = llc_seq_next,
        .stop   = llc_seq_stop,
        .show   = llc_seq_socket_show,
 };
 
-static struct seq_operations llc_seq_core_ops = {
+static const struct seq_operations llc_seq_core_ops = {
        .start  = llc_seq_start,
        .next   = llc_seq_next,
        .stop   = llc_seq_stop,
index 352f03bd8a3adcd8104212e1bf731c8961a4af46..66e8a976b311969a267073b61f949531cb761523 100644 (file)
@@ -838,6 +838,29 @@ static int ieee80211_ioctl_giwscan(struct net_device *dev,
 }
 
 
+static int ieee80211_ioctl_giwrate(struct net_device *dev,
+                                 struct iw_request_info *info,
+                                 struct iw_param *rate, char *extra)
+{
+       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct sta_info *sta;
+       struct ieee80211_sub_if_data *sdata;
+
+       sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       if (sdata->type == IEEE80211_IF_TYPE_STA)
+               sta = sta_info_get(local, sdata->u.sta.bssid);
+       else
+               return -EOPNOTSUPP;
+       if (!sta)
+               return -ENODEV;
+       if (sta->txrate < local->oper_hw_mode->num_rates)
+               rate->value = local->oper_hw_mode->rates[sta->txrate].rate * 100000;
+       else
+               rate->value = 0;
+       sta_info_put(sta);
+       return 0;
+}
+
 static int ieee80211_ioctl_siwrts(struct net_device *dev,
                                  struct iw_request_info *info,
                                  struct iw_param *rts, char *extra)
@@ -1779,7 +1802,7 @@ static const iw_handler ieee80211_handler[] =
        (iw_handler) NULL,                              /* -- hole -- */
        (iw_handler) NULL,                              /* -- hole -- */
        (iw_handler) NULL,                              /* SIOCSIWRATE */
-       (iw_handler) NULL,                              /* SIOCGIWRATE */
+       (iw_handler) ieee80211_ioctl_giwrate,           /* SIOCGIWRATE */
        (iw_handler) ieee80211_ioctl_siwrts,            /* SIOCSIWRTS */
        (iw_handler) ieee80211_ioctl_giwrts,            /* SIOCGIWRTS */
        (iw_handler) ieee80211_ioctl_siwfrag,           /* SIOCSIWFRAG */
index 2048cfd1ca70093781e30bd5bb52b9c5696773a0..5ae7fc45466547cddb6009abe8f04162f4c0287c 100644 (file)
@@ -283,14 +283,16 @@ static void rate_control_simple_rate_init(void *priv, void *priv_sta,
        int i;
        sta->txrate = 0;
        mode = local->oper_hw_mode;
-       /* TODO: what is a good starting rate for STA? About middle? Maybe not
-        * the lowest or the highest rate.. Could consider using RSSI from
-        * previous packets? Need to have IEEE 802.1X auth succeed immediately
-        * after assoc.. */
+       /* TODO: This routine should consider using RSSI from previous packets
+        * as we need to have IEEE 802.1X auth succeed immediately after assoc..
+        * Until that method is implemented, we will use the lowest supported rate
+        * as a workaround, */
        for (i = 0; i < mode->num_rates; i++) {
                if ((sta->supp_rates & BIT(i)) &&
-                   (mode->rates[i].flags & IEEE80211_RATE_SUPPORTED))
+                   (mode->rates[i].flags & IEEE80211_RATE_SUPPORTED)) {
                        sta->txrate = i;
+                       break;
+               }
        }
 }
 
index a567dae8e5fdff5a3b0a80080f71d23fa0196236..df5e8dab871d535acfb7eff9ae05ee71304c026f 100644 (file)
@@ -343,6 +343,18 @@ config NETFILTER_XT_TARGET_NOTRACK
          If you want to compile it as a module, say M here and read
          <file:Documentation/kbuild/modules.txt>.  If unsure, say `N'.
 
+config NETFILTER_XT_TARGET_TRACE
+       tristate  '"TRACE" target support'
+       depends on NETFILTER_XTABLES
+       depends on IP_NF_RAW || IP6_NF_RAW
+       help
+         The TRACE target allows you to mark packets so that the kernel
+         will log every rule which match the packets as those traverse
+         the tables, chains, rules.
+
+         If you want to compile it as a module, say M here and read
+         <file:Documentation/modules.txt>.  If unsure, say `N'.
+
 config NETFILTER_XT_TARGET_SECMARK
        tristate '"SECMARK" target support'
        depends on NETFILTER_XTABLES && NETWORK_SECMARK
@@ -635,6 +647,19 @@ config NETFILTER_XT_MATCH_TCPMSS
 
          To compile it as a module, choose M here.  If unsure, say N.
 
+config NETFILTER_XT_MATCH_U32
+       tristate '"u32" match support'
+       depends on NETFILTER_XTABLES
+       ---help---
+         u32 allows you to extract quantities of up to 4 bytes from a packet,
+         AND them with specified masks, shift them by specified amounts and
+         test whether the results are in any of a set of specified ranges.
+         The specification of what to extract is general enough to skip over
+         headers with lengths stored in the packet, as in IP or TCP header
+         lengths.
+
+         Details and examples are in the kernel module source.
+
 config NETFILTER_XT_MATCH_HASHLIMIT
        tristate '"hashlimit" match support'
        depends on NETFILTER_XTABLES && (IP6_NF_IPTABLES || IP6_NF_IPTABLES=n)
index b2b5c7566b26e74644c787d9282b55c6bacb6c8a..58b4245a1723b52c81b1738b4a605cf88552c077 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-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-$(CONFIG_NF_CONNTRACK_EVENTS) += nf_conntrack_ecache.o
 
 obj-$(CONFIG_NETFILTER) = netfilter.o
@@ -44,6 +44,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o
+obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o
@@ -72,4 +73,5 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_STATISTIC) += xt_statistic.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o
+obj-$(CONFIG_NETFILTER_XT_MATCH_U32) += xt_u32.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_HASHLIMIT) += xt_hashlimit.o
index a84478ee2ded4c4b4a6888794ff05b70a3204cdc..381a77cf0c9eb83c5900fb775f6e38a5fcd4b7ad 100644 (file)
@@ -203,7 +203,9 @@ int skb_make_writable(struct sk_buff **pskb, unsigned int writable_len)
                return 0;
 
        /* Not exclusive use of packet?  Must copy. */
-       if (skb_shared(*pskb) || skb_cloned(*pskb))
+       if (skb_cloned(*pskb) && !skb_clone_writable(*pskb, writable_len))
+               goto copy_skb;
+       if (skb_shared(*pskb))
                goto copy_skb;
 
        return pskb_may_pull(*pskb, writable_len);
@@ -229,13 +231,13 @@ void nf_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb,
 {
        __be32 diff[] = { ~from, to };
        if (skb->ip_summed != CHECKSUM_PARTIAL) {
-               *sum = csum_fold(csum_partial((char *)diff, sizeof(diff),
+               *sum = csum_fold(csum_partial(diff, sizeof(diff),
                                ~csum_unfold(*sum)));
                if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr)
-                       skb->csum = ~csum_partial((char *)diff, sizeof(diff),
+                       skb->csum = ~csum_partial(diff, sizeof(diff),
                                                ~skb->csum);
        } else if (pseudohdr)
-               *sum = ~csum_fold(csum_partial((char *)diff, sizeof(diff),
+               *sum = ~csum_fold(csum_partial(diff, sizeof(diff),
                                csum_unfold(*sum)));
 }
 EXPORT_SYMBOL(nf_proto_csum_replace4);
index 0568f2e86b5990cc713bd4a374fe3995a04dc898..e42ab230ad884089a494a505c0053fb3159e47c7 100644 (file)
@@ -142,23 +142,22 @@ static int amanda_help(struct sk_buff **pskb,
                if (port == 0 || len > 5)
                        break;
 
-               exp = nf_conntrack_expect_alloc(ct);
+               exp = nf_ct_expect_alloc(ct);
                if (exp == NULL) {
                        ret = NF_DROP;
                        goto out;
                }
                tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
-               nf_conntrack_expect_init(exp, family,
-                                        &tuple->src.u3, &tuple->dst.u3,
-                                        IPPROTO_TCP, NULL, &port);
+               nf_ct_expect_init(exp, family, &tuple->src.u3, &tuple->dst.u3,
+                                 IPPROTO_TCP, NULL, &port);
 
                nf_nat_amanda = rcu_dereference(nf_nat_amanda_hook);
                if (nf_nat_amanda && ct->status & IPS_NAT_MASK)
                        ret = nf_nat_amanda(pskb, ctinfo, off - dataoff,
                                            len, exp);
-               else if (nf_conntrack_expect_related(exp) != 0)
+               else if (nf_ct_expect_related(exp) != 0)
                        ret = NF_DROP;
-               nf_conntrack_expect_put(exp);
+               nf_ct_expect_put(exp);
        }
 
 out:
@@ -175,9 +174,6 @@ static struct nf_conntrack_helper amanda_helper[2] __read_mostly = {
                .tuple.src.l3num        = AF_INET,
                .tuple.src.u.udp.port   = __constant_htons(10080),
                .tuple.dst.protonum     = IPPROTO_UDP,
-               .mask.src.l3num         = 0xFFFF,
-               .mask.src.u.udp.port    = __constant_htons(0xFFFF),
-               .mask.dst.protonum      = 0xFF,
        },
        {
                .name                   = "amanda",
@@ -188,9 +184,6 @@ static struct nf_conntrack_helper amanda_helper[2] __read_mostly = {
                .tuple.src.l3num        = AF_INET6,
                .tuple.src.u.udp.port   = __constant_htons(10080),
                .tuple.dst.protonum     = IPPROTO_UDP,
-               .mask.src.l3num         = 0xFFFF,
-               .mask.src.u.udp.port    = __constant_htons(0xFFFF),
-               .mask.dst.protonum      = 0xFF,
        },
 };
 
index 7a15e30356f2284613c708dc081ceebfeff94e23..3d1411012a2c496d5bdf98649321e63074e63e60 100644 (file)
 #include <net/netfilter/nf_conntrack_expect.h>
 #include <net/netfilter/nf_conntrack_helper.h>
 #include <net/netfilter/nf_conntrack_core.h>
+#include <net/netfilter/nf_conntrack_extend.h>
 
 #define NF_CONNTRACK_VERSION   "0.5.0"
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 DEFINE_RWLOCK(nf_conntrack_lock);
 EXPORT_SYMBOL_GPL(nf_conntrack_lock);
 
@@ -52,57 +47,27 @@ EXPORT_SYMBOL_GPL(nf_conntrack_lock);
 atomic_t nf_conntrack_count = ATOMIC_INIT(0);
 EXPORT_SYMBOL_GPL(nf_conntrack_count);
 
-void (*nf_conntrack_destroyed)(struct nf_conn *conntrack);
-EXPORT_SYMBOL_GPL(nf_conntrack_destroyed);
-
 unsigned int nf_conntrack_htable_size __read_mostly;
 EXPORT_SYMBOL_GPL(nf_conntrack_htable_size);
 
 int nf_conntrack_max __read_mostly;
 EXPORT_SYMBOL_GPL(nf_conntrack_max);
 
-struct list_head *nf_conntrack_hash __read_mostly;
+struct hlist_head *nf_conntrack_hash __read_mostly;
 EXPORT_SYMBOL_GPL(nf_conntrack_hash);
 
 struct nf_conn nf_conntrack_untracked __read_mostly;
 EXPORT_SYMBOL_GPL(nf_conntrack_untracked);
 
 unsigned int nf_ct_log_invalid __read_mostly;
-LIST_HEAD(unconfirmed);
+HLIST_HEAD(unconfirmed);
 static int nf_conntrack_vmalloc __read_mostly;
-
+static struct kmem_cache *nf_conntrack_cachep __read_mostly;
 static unsigned int nf_conntrack_next_id;
 
 DEFINE_PER_CPU(struct ip_conntrack_stat, nf_conntrack_stat);
 EXPORT_PER_CPU_SYMBOL(nf_conntrack_stat);
 
-/*
- * This scheme offers various size of "struct nf_conn" dependent on
- * features(helper, nat, ...)
- */
-
-#define NF_CT_FEATURES_NAMELEN 256
-static struct {
-       /* name of slab cache. printed in /proc/slabinfo */
-       char *name;
-
-       /* size of slab cache */
-       size_t size;
-
-       /* slab cache pointer */
-       struct kmem_cache *cachep;
-
-       /* allocated slab cache + modules which uses this slab cache */
-       int use;
-
-} nf_ct_cache[NF_CT_F_NUM];
-
-/* protect members of nf_ct_cache except of "use" */
-DEFINE_RWLOCK(nf_ct_cache_lock);
-
-/* This avoids calling kmem_cache_create() with same name simultaneously */
-static DEFINE_MUTEX(nf_ct_cache_mutex);
-
 static int nf_conntrack_hash_rnd_initted;
 static unsigned int nf_conntrack_hash_rnd;
 
@@ -125,122 +90,6 @@ static inline u_int32_t hash_conntrack(const struct nf_conntrack_tuple *tuple)
                                nf_conntrack_hash_rnd);
 }
 
-int nf_conntrack_register_cache(u_int32_t features, const char *name,
-                               size_t size)
-{
-       int ret = 0;
-       char *cache_name;
-       struct kmem_cache *cachep;
-
-       DEBUGP("nf_conntrack_register_cache: features=0x%x, name=%s, size=%d\n",
-              features, name, size);
-
-       if (features < NF_CT_F_BASIC || features >= NF_CT_F_NUM) {
-               DEBUGP("nf_conntrack_register_cache: invalid features.: 0x%x\n",
-                       features);
-               return -EINVAL;
-       }
-
-       mutex_lock(&nf_ct_cache_mutex);
-
-       write_lock_bh(&nf_ct_cache_lock);
-       /* e.g: multiple helpers are loaded */
-       if (nf_ct_cache[features].use > 0) {
-               DEBUGP("nf_conntrack_register_cache: already resisterd.\n");
-               if ((!strncmp(nf_ct_cache[features].name, name,
-                             NF_CT_FEATURES_NAMELEN))
-                   && nf_ct_cache[features].size == size) {
-                       DEBUGP("nf_conntrack_register_cache: reusing.\n");
-                       nf_ct_cache[features].use++;
-                       ret = 0;
-               } else
-                       ret = -EBUSY;
-
-               write_unlock_bh(&nf_ct_cache_lock);
-               mutex_unlock(&nf_ct_cache_mutex);
-               return ret;
-       }
-       write_unlock_bh(&nf_ct_cache_lock);
-
-       /*
-        * The memory space for name of slab cache must be alive until
-        * cache is destroyed.
-        */
-       cache_name = kmalloc(sizeof(char)*NF_CT_FEATURES_NAMELEN, GFP_ATOMIC);
-       if (cache_name == NULL) {
-               DEBUGP("nf_conntrack_register_cache: can't alloc cache_name\n");
-               ret = -ENOMEM;
-               goto out_up_mutex;
-       }
-
-       if (strlcpy(cache_name, name, NF_CT_FEATURES_NAMELEN)
-                                               >= NF_CT_FEATURES_NAMELEN) {
-               printk("nf_conntrack_register_cache: name too long\n");
-               ret = -EINVAL;
-               goto out_free_name;
-       }
-
-       cachep = kmem_cache_create(cache_name, size, 0, 0,
-                                  NULL, NULL);
-       if (!cachep) {
-               printk("nf_conntrack_register_cache: Can't create slab cache "
-                      "for the features = 0x%x\n", features);
-               ret = -ENOMEM;
-               goto out_free_name;
-       }
-
-       write_lock_bh(&nf_ct_cache_lock);
-       nf_ct_cache[features].use = 1;
-       nf_ct_cache[features].size = size;
-       nf_ct_cache[features].cachep = cachep;
-       nf_ct_cache[features].name = cache_name;
-       write_unlock_bh(&nf_ct_cache_lock);
-
-       goto out_up_mutex;
-
-out_free_name:
-       kfree(cache_name);
-out_up_mutex:
-       mutex_unlock(&nf_ct_cache_mutex);
-       return ret;
-}
-EXPORT_SYMBOL_GPL(nf_conntrack_register_cache);
-
-/* FIXME: In the current, only nf_conntrack_cleanup() can call this function. */
-void nf_conntrack_unregister_cache(u_int32_t features)
-{
-       struct kmem_cache *cachep;
-       char *name;
-
-       /*
-        * This assures that kmem_cache_create() isn't called before destroying
-        * slab cache.
-        */
-       DEBUGP("nf_conntrack_unregister_cache: 0x%04x\n", features);
-       mutex_lock(&nf_ct_cache_mutex);
-
-       write_lock_bh(&nf_ct_cache_lock);
-       if (--nf_ct_cache[features].use > 0) {
-               write_unlock_bh(&nf_ct_cache_lock);
-               mutex_unlock(&nf_ct_cache_mutex);
-               return;
-       }
-       cachep = nf_ct_cache[features].cachep;
-       name = nf_ct_cache[features].name;
-       nf_ct_cache[features].cachep = NULL;
-       nf_ct_cache[features].name = NULL;
-       nf_ct_cache[features].size = 0;
-       write_unlock_bh(&nf_ct_cache_lock);
-
-       synchronize_net();
-
-       kmem_cache_destroy(cachep);
-       kfree(name);
-
-       mutex_unlock(&nf_ct_cache_mutex);
-}
-EXPORT_SYMBOL_GPL(nf_conntrack_unregister_cache);
-
 int
 nf_ct_get_tuple(const struct sk_buff *skb,
                unsigned int nhoff,
@@ -286,9 +135,9 @@ EXPORT_SYMBOL_GPL(nf_ct_invert_tuple);
 static void
 clean_from_lists(struct nf_conn *ct)
 {
-       DEBUGP("clean_from_lists(%p)\n", ct);
-       list_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list);
-       list_del(&ct->tuplehash[IP_CT_DIR_REPLY].list);
+       pr_debug("clean_from_lists(%p)\n", ct);
+       hlist_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode);
+       hlist_del(&ct->tuplehash[IP_CT_DIR_REPLY].hnode);
 
        /* Destroy all pending expectations */
        nf_ct_remove_expectations(ct);
@@ -299,9 +148,8 @@ destroy_conntrack(struct nf_conntrack *nfct)
 {
        struct nf_conn *ct = (struct nf_conn *)nfct;
        struct nf_conntrack_l4proto *l4proto;
-       typeof(nf_conntrack_destroyed) destroyed;
 
-       DEBUGP("destroy_conntrack(%p)\n", ct);
+       pr_debug("destroy_conntrack(%p)\n", ct);
        NF_CT_ASSERT(atomic_read(&nfct->use) == 0);
        NF_CT_ASSERT(!timer_pending(&ct->timeout));
 
@@ -317,9 +165,7 @@ destroy_conntrack(struct nf_conntrack *nfct)
        if (l4proto && l4proto->destroy)
                l4proto->destroy(ct);
 
-       destroyed = rcu_dereference(nf_conntrack_destroyed);
-       if (destroyed)
-               destroyed(ct);
+       nf_ct_ext_destroy(ct);
 
        rcu_read_unlock();
 
@@ -332,8 +178,8 @@ destroy_conntrack(struct nf_conntrack *nfct)
 
        /* We overload first tuple to link into unconfirmed list. */
        if (!nf_ct_is_confirmed(ct)) {
-               BUG_ON(list_empty(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list));
-               list_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list);
+               BUG_ON(hlist_unhashed(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode));
+               hlist_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode);
        }
 
        NF_CT_STAT_INC(delete);
@@ -342,7 +188,7 @@ destroy_conntrack(struct nf_conntrack *nfct)
        if (ct->master)
                nf_ct_put(ct->master);
 
-       DEBUGP("destroy_conntrack: returning ct=%p to slab\n", ct);
+       pr_debug("destroy_conntrack: returning ct=%p to slab\n", ct);
        nf_conntrack_free(ct);
 }
 
@@ -374,9 +220,10 @@ __nf_conntrack_find(const struct nf_conntrack_tuple *tuple,
                    const struct nf_conn *ignored_conntrack)
 {
        struct nf_conntrack_tuple_hash *h;
+       struct hlist_node *n;
        unsigned int hash = hash_conntrack(tuple);
 
-       list_for_each_entry(h, &nf_conntrack_hash[hash], list) {
+       hlist_for_each_entry(h, n, &nf_conntrack_hash[hash], hnode) {
                if (nf_ct_tuplehash_to_ctrack(h) != ignored_conntrack &&
                    nf_ct_tuple_equal(tuple, &h->tuple)) {
                        NF_CT_STAT_INC(found);
@@ -391,13 +238,12 @@ EXPORT_SYMBOL_GPL(__nf_conntrack_find);
 
 /* Find a connection corresponding to a tuple. */
 struct nf_conntrack_tuple_hash *
-nf_conntrack_find_get(const struct nf_conntrack_tuple *tuple,
-                     const struct nf_conn *ignored_conntrack)
+nf_conntrack_find_get(const struct nf_conntrack_tuple *tuple)
 {
        struct nf_conntrack_tuple_hash *h;
 
        read_lock_bh(&nf_conntrack_lock);
-       h = __nf_conntrack_find(tuple, ignored_conntrack);
+       h = __nf_conntrack_find(tuple, NULL);
        if (h)
                atomic_inc(&nf_ct_tuplehash_to_ctrack(h)->ct_general.use);
        read_unlock_bh(&nf_conntrack_lock);
@@ -411,10 +257,10 @@ static void __nf_conntrack_hash_insert(struct nf_conn *ct,
                                       unsigned int repl_hash)
 {
        ct->id = ++nf_conntrack_next_id;
-       list_add(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list,
-                &nf_conntrack_hash[hash]);
-       list_add(&ct->tuplehash[IP_CT_DIR_REPLY].list,
-                &nf_conntrack_hash[repl_hash]);
+       hlist_add_head(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode,
+                      &nf_conntrack_hash[hash]);
+       hlist_add_head(&ct->tuplehash[IP_CT_DIR_REPLY].hnode,
+                      &nf_conntrack_hash[repl_hash]);
 }
 
 void nf_conntrack_hash_insert(struct nf_conn *ct)
@@ -438,6 +284,7 @@ __nf_conntrack_confirm(struct sk_buff **pskb)
        struct nf_conntrack_tuple_hash *h;
        struct nf_conn *ct;
        struct nf_conn_help *help;
+       struct hlist_node *n;
        enum ip_conntrack_info ctinfo;
 
        ct = nf_ct_get(*pskb, &ctinfo);
@@ -460,24 +307,24 @@ __nf_conntrack_confirm(struct sk_buff **pskb)
        /* No external references means noone else could have
           confirmed us. */
        NF_CT_ASSERT(!nf_ct_is_confirmed(ct));
-       DEBUGP("Confirming conntrack %p\n", ct);
+       pr_debug("Confirming conntrack %p\n", ct);
 
        write_lock_bh(&nf_conntrack_lock);
 
        /* See if there's one in the list already, including reverse:
           NAT could have grabbed it without realizing, since we're
           not in the hash.  If there is, we lost race. */
-       list_for_each_entry(h, &nf_conntrack_hash[hash], list)
+       hlist_for_each_entry(h, n, &nf_conntrack_hash[hash], hnode)
                if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
                                      &h->tuple))
                        goto out;
-       list_for_each_entry(h, &nf_conntrack_hash[repl_hash], list)
+       hlist_for_each_entry(h, n, &nf_conntrack_hash[repl_hash], hnode)
                if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_REPLY].tuple,
                                      &h->tuple))
                        goto out;
 
        /* Remove from unconfirmed list */
-       list_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list);
+       hlist_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode);
 
        __nf_conntrack_hash_insert(ct, hash, repl_hash);
        /* Timer relative to confirmation time, not original
@@ -524,24 +371,33 @@ nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple,
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_tuple_taken);
 
+#define NF_CT_EVICTION_RANGE   8
+
 /* There's a small race here where we may free a just-assured
    connection.  Too bad: we're in trouble anyway. */
-static int early_drop(struct list_head *chain)
+static int early_drop(unsigned int hash)
 {
-       /* Traverse backwards: gives us oldest, which is roughly LRU */
+       /* Use oldest entry, which is roughly LRU */
        struct nf_conntrack_tuple_hash *h;
        struct nf_conn *ct = NULL, *tmp;
+       struct hlist_node *n;
+       unsigned int i, cnt = 0;
        int dropped = 0;
 
        read_lock_bh(&nf_conntrack_lock);
-       list_for_each_entry_reverse(h, chain, list) {
-               tmp = nf_ct_tuplehash_to_ctrack(h);
-               if (!test_bit(IPS_ASSURED_BIT, &tmp->status)) {
-                       ct = tmp;
-                       atomic_inc(&ct->ct_general.use);
-                       break;
+       for (i = 0; i < nf_conntrack_htable_size; i++) {
+               hlist_for_each_entry(h, n, &nf_conntrack_hash[hash], hnode) {
+                       tmp = nf_ct_tuplehash_to_ctrack(h);
+                       if (!test_bit(IPS_ASSURED_BIT, &tmp->status))
+                               ct = tmp;
+                       cnt++;
                }
+               if (ct || cnt >= NF_CT_EVICTION_RANGE)
+                       break;
+               hash = (hash + 1) % nf_conntrack_htable_size;
        }
+       if (ct)
+               atomic_inc(&ct->ct_general.use);
        read_unlock_bh(&nf_conntrack_lock);
 
        if (!ct)
@@ -556,14 +412,10 @@ static int early_drop(struct list_head *chain)
        return dropped;
 }
 
-static struct nf_conn *
-__nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
-                    const struct nf_conntrack_tuple *repl,
-                    const struct nf_conntrack_l3proto *l3proto,
-                    u_int32_t features)
+struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
+                                  const struct nf_conntrack_tuple *repl)
 {
        struct nf_conn *conntrack = NULL;
-       struct nf_conntrack_helper *helper;
 
        if (unlikely(!nf_conntrack_hash_rnd_initted)) {
                get_random_bytes(&nf_conntrack_hash_rnd, 4);
@@ -576,8 +428,7 @@ __nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
        if (nf_conntrack_max
            && atomic_read(&nf_conntrack_count) > nf_conntrack_max) {
                unsigned int hash = hash_conntrack(orig);
-               /* Try dropping from this hash chain. */
-               if (!early_drop(&nf_conntrack_hash[hash])) {
+               if (!early_drop(hash)) {
                        atomic_dec(&nf_conntrack_count);
                        if (net_ratelimit())
                                printk(KERN_WARNING
@@ -587,72 +438,28 @@ __nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
                }
        }
 
-       /*  find features needed by this conntrack. */
-       features |= l3proto->get_features(orig);
-
-       /* FIXME: protect helper list per RCU */
-       read_lock_bh(&nf_conntrack_lock);
-       helper = __nf_ct_helper_find(repl);
-       /* NAT might want to assign a helper later */
-       if (helper || features & NF_CT_F_NAT)
-               features |= NF_CT_F_HELP;
-       read_unlock_bh(&nf_conntrack_lock);
-
-       DEBUGP("nf_conntrack_alloc: features=0x%x\n", features);
-
-       read_lock_bh(&nf_ct_cache_lock);
-
-       if (unlikely(!nf_ct_cache[features].use)) {
-               DEBUGP("nf_conntrack_alloc: not supported features = 0x%x\n",
-                       features);
-               goto out;
-       }
-
-       conntrack = kmem_cache_alloc(nf_ct_cache[features].cachep, GFP_ATOMIC);
+       conntrack = kmem_cache_zalloc(nf_conntrack_cachep, GFP_ATOMIC);
        if (conntrack == NULL) {
-               DEBUGP("nf_conntrack_alloc: Can't alloc conntrack from cache\n");
-               goto out;
+               pr_debug("nf_conntrack_alloc: Can't alloc conntrack.\n");
+               atomic_dec(&nf_conntrack_count);
+               return ERR_PTR(-ENOMEM);
        }
 
-       memset(conntrack, 0, nf_ct_cache[features].size);
-       conntrack->features = features;
        atomic_set(&conntrack->ct_general.use, 1);
        conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *orig;
        conntrack->tuplehash[IP_CT_DIR_REPLY].tuple = *repl;
        /* Don't set timer yet: wait for confirmation */
        setup_timer(&conntrack->timeout, death_by_timeout,
                    (unsigned long)conntrack);
-       read_unlock_bh(&nf_ct_cache_lock);
 
-       return conntrack;
-out:
-       read_unlock_bh(&nf_ct_cache_lock);
-       atomic_dec(&nf_conntrack_count);
        return conntrack;
 }
-
-struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
-                                  const struct nf_conntrack_tuple *repl)
-{
-       struct nf_conntrack_l3proto *l3proto;
-       struct nf_conn *ct;
-
-       rcu_read_lock();
-       l3proto = __nf_ct_l3proto_find(orig->src.l3num);
-       ct = __nf_conntrack_alloc(orig, repl, l3proto, 0);
-       rcu_read_unlock();
-
-       return ct;
-}
 EXPORT_SYMBOL_GPL(nf_conntrack_alloc);
 
 void nf_conntrack_free(struct nf_conn *conntrack)
 {
-       u_int32_t features = conntrack->features;
-       NF_CT_ASSERT(features >= NF_CT_F_BASIC && features < NF_CT_F_NUM);
-       DEBUGP("nf_conntrack_free: features = 0x%x, conntrack=%p\n", features,
-              conntrack);
-       kmem_cache_free(nf_ct_cache[features].cachep, conntrack);
+       nf_ct_ext_free(conntrack);
+       kmem_cache_free(nf_conntrack_cachep, conntrack);
        atomic_dec(&nf_conntrack_count);
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_free);
@@ -670,43 +477,38 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
        struct nf_conn_help *help;
        struct nf_conntrack_tuple repl_tuple;
        struct nf_conntrack_expect *exp;
-       u_int32_t features = 0;
 
        if (!nf_ct_invert_tuple(&repl_tuple, tuple, l3proto, l4proto)) {
-               DEBUGP("Can't invert tuple.\n");
+               pr_debug("Can't invert tuple.\n");
                return NULL;
        }
 
-       read_lock_bh(&nf_conntrack_lock);
-       exp = __nf_conntrack_expect_find(tuple);
-       if (exp && exp->helper)
-               features = NF_CT_F_HELP;
-       read_unlock_bh(&nf_conntrack_lock);
-
-       conntrack = __nf_conntrack_alloc(tuple, &repl_tuple, l3proto, features);
+       conntrack = nf_conntrack_alloc(tuple, &repl_tuple);
        if (conntrack == NULL || IS_ERR(conntrack)) {
-               DEBUGP("Can't allocate conntrack.\n");
+               pr_debug("Can't allocate conntrack.\n");
                return (struct nf_conntrack_tuple_hash *)conntrack;
        }
 
        if (!l4proto->new(conntrack, skb, dataoff)) {
                nf_conntrack_free(conntrack);
-               DEBUGP("init conntrack: can't track with proto module\n");
+               pr_debug("init conntrack: can't track with proto module\n");
                return NULL;
        }
 
        write_lock_bh(&nf_conntrack_lock);
-       exp = find_expectation(tuple);
-
-       help = nfct_help(conntrack);
+       exp = nf_ct_find_expectation(tuple);
        if (exp) {
-               DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n",
-                       conntrack, exp);
+               pr_debug("conntrack: expectation arrives ct=%p exp=%p\n",
+                        conntrack, exp);
                /* Welcome, Mr. Bond.  We've been expecting you... */
                __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
                conntrack->master = exp->master;
-               if (exp->helper)
-                       rcu_assign_pointer(help->helper, exp->helper);
+               if (exp->helper) {
+                       help = nf_ct_helper_ext_add(conntrack, GFP_ATOMIC);
+                       if (help)
+                               rcu_assign_pointer(help->helper, exp->helper);
+               }
+
 #ifdef CONFIG_NF_CONNTRACK_MARK
                conntrack->mark = exp->master->mark;
 #endif
@@ -716,23 +518,27 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
                nf_conntrack_get(&conntrack->master->ct_general);
                NF_CT_STAT_INC(expect_new);
        } else {
-               if (help) {
-                       /* not in hash table yet, so not strictly necessary */
-                       rcu_assign_pointer(help->helper,
-                                          __nf_ct_helper_find(&repl_tuple));
+               struct nf_conntrack_helper *helper;
+
+               helper = __nf_ct_helper_find(&repl_tuple);
+               if (helper) {
+                       help = nf_ct_helper_ext_add(conntrack, GFP_ATOMIC);
+                       if (help)
+                               rcu_assign_pointer(help->helper, helper);
                }
                NF_CT_STAT_INC(new);
        }
 
        /* Overload tuple linked list to put us in unconfirmed list. */
-       list_add(&conntrack->tuplehash[IP_CT_DIR_ORIGINAL].list, &unconfirmed);
+       hlist_add_head(&conntrack->tuplehash[IP_CT_DIR_ORIGINAL].hnode,
+                      &unconfirmed);
 
        write_unlock_bh(&nf_conntrack_lock);
 
        if (exp) {
                if (exp->expectfn)
                        exp->expectfn(conntrack, exp);
-               nf_conntrack_expect_put(exp);
+               nf_ct_expect_put(exp);
        }
 
        return &conntrack->tuplehash[IP_CT_DIR_ORIGINAL];
@@ -756,12 +562,12 @@ resolve_normal_ct(struct sk_buff *skb,
        if (!nf_ct_get_tuple(skb, skb_network_offset(skb),
                             dataoff, l3num, protonum, &tuple, l3proto,
                             l4proto)) {
-               DEBUGP("resolve_normal_ct: Can't get tuple\n");
+               pr_debug("resolve_normal_ct: Can't get tuple\n");
                return NULL;
        }
 
        /* look for tuple match */
-       h = nf_conntrack_find_get(&tuple, NULL);
+       h = nf_conntrack_find_get(&tuple);
        if (!h) {
                h = init_conntrack(&tuple, l3proto, l4proto, skb, dataoff);
                if (!h)
@@ -779,13 +585,14 @@ resolve_normal_ct(struct sk_buff *skb,
        } else {
                /* Once we've had two way comms, always ESTABLISHED. */
                if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
-                       DEBUGP("nf_conntrack_in: normal packet for %p\n", ct);
+                       pr_debug("nf_conntrack_in: normal packet for %p\n", ct);
                        *ctinfo = IP_CT_ESTABLISHED;
                } else if (test_bit(IPS_EXPECTED_BIT, &ct->status)) {
-                       DEBUGP("nf_conntrack_in: related packet for %p\n", ct);
+                       pr_debug("nf_conntrack_in: related packet for %p\n",
+                                ct);
                        *ctinfo = IP_CT_RELATED;
                } else {
-                       DEBUGP("nf_conntrack_in: new packet for %p\n", ct);
+                       pr_debug("nf_conntrack_in: new packet for %p\n", ct);
                        *ctinfo = IP_CT_NEW;
                }
                *set_reply = 0;
@@ -817,7 +624,7 @@ nf_conntrack_in(int pf, unsigned int hooknum, struct sk_buff **pskb)
        l3proto = __nf_ct_l3proto_find((u_int16_t)pf);
 
        if ((ret = l3proto->prepare(pskb, hooknum, &dataoff, &protonum)) <= 0) {
-               DEBUGP("not prepared to track yet or error occured\n");
+               pr_debug("not prepared to track yet or error occured\n");
                return -ret;
        }
 
@@ -853,7 +660,7 @@ nf_conntrack_in(int pf, unsigned int hooknum, struct sk_buff **pskb)
        if (ret < 0) {
                /* Invalid: inverse of the return code tells
                 * the netfilter core what to do */
-               DEBUGP("nf_conntrack_in: Can't track with proto module\n");
+               pr_debug("nf_conntrack_in: Can't track with proto module\n");
                nf_conntrack_put((*pskb)->nfct);
                (*pskb)->nfct = NULL;
                NF_CT_STAT_INC_ATOMIC(invalid);
@@ -888,23 +695,36 @@ void nf_conntrack_alter_reply(struct nf_conn *ct,
                              const struct nf_conntrack_tuple *newreply)
 {
        struct nf_conn_help *help = nfct_help(ct);
+       struct nf_conntrack_helper *helper;
 
        write_lock_bh(&nf_conntrack_lock);
        /* Should be unconfirmed, so not in hash table yet */
        NF_CT_ASSERT(!nf_ct_is_confirmed(ct));
 
-       DEBUGP("Altering reply tuple of %p to ", ct);
+       pr_debug("Altering reply tuple of %p to ", ct);
        NF_CT_DUMP_TUPLE(newreply);
 
        ct->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply;
-       if (!ct->master && help && help->expecting == 0) {
-               struct nf_conntrack_helper *helper;
-               helper = __nf_ct_helper_find(newreply);
-               if (helper)
-                       memset(&help->help, 0, sizeof(help->help));
-               /* not in hash table yet, so not strictly necessary */
-               rcu_assign_pointer(help->helper, helper);
+       if (ct->master || (help && help->expecting != 0))
+               goto out;
+
+       helper = __nf_ct_helper_find(newreply);
+       if (helper == NULL) {
+               if (help)
+                       rcu_assign_pointer(help->helper, NULL);
+               goto out;
        }
+
+       if (help == NULL) {
+               help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
+               if (help == NULL)
+                       goto out;
+       } else {
+               memset(&help->help, 0, sizeof(help->help));
+       }
+
+       rcu_assign_pointer(help->helper, helper);
+out:
        write_unlock_bh(&nf_conntrack_lock);
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_alter_reply);
@@ -1048,16 +868,17 @@ get_next_corpse(int (*iter)(struct nf_conn *i, void *data),
 {
        struct nf_conntrack_tuple_hash *h;
        struct nf_conn *ct;
+       struct hlist_node *n;
 
        write_lock_bh(&nf_conntrack_lock);
        for (; *bucket < nf_conntrack_htable_size; (*bucket)++) {
-               list_for_each_entry(h, &nf_conntrack_hash[*bucket], list) {
+               hlist_for_each_entry(h, n, &nf_conntrack_hash[*bucket], hnode) {
                        ct = nf_ct_tuplehash_to_ctrack(h);
                        if (iter(ct, data))
                                goto found;
                }
        }
-       list_for_each_entry(h, &unconfirmed, list) {
+       hlist_for_each_entry(h, n, &unconfirmed, hnode) {
                ct = nf_ct_tuplehash_to_ctrack(h);
                if (iter(ct, data))
                        set_bit(IPS_DYING_BIT, &ct->status);
@@ -1092,14 +913,15 @@ static int kill_all(struct nf_conn *i, void *data)
        return 1;
 }
 
-static void free_conntrack_hash(struct list_head *hash, int vmalloced, int size)
+void nf_ct_free_hashtable(struct hlist_head *hash, int vmalloced, int size)
 {
        if (vmalloced)
                vfree(hash);
        else
                free_pages((unsigned long)hash,
-                          get_order(sizeof(struct list_head) * size));
+                          get_order(sizeof(struct hlist_head) * size));
 }
+EXPORT_SYMBOL_GPL(nf_ct_free_hashtable);
 
 void nf_conntrack_flush(void)
 {
@@ -1111,8 +933,6 @@ EXPORT_SYMBOL_GPL(nf_conntrack_flush);
    supposed to kill the mall. */
 void nf_conntrack_cleanup(void)
 {
-       int i;
-
        rcu_assign_pointer(ip_ct_attach, NULL);
 
        /* This makes sure all current packets have passed through
@@ -1133,49 +953,46 @@ void nf_conntrack_cleanup(void)
 
        rcu_assign_pointer(nf_ct_destroy, NULL);
 
-       for (i = 0; i < NF_CT_F_NUM; i++) {
-               if (nf_ct_cache[i].use == 0)
-                       continue;
-
-               NF_CT_ASSERT(nf_ct_cache[i].use == 1);
-               nf_ct_cache[i].use = 1;
-               nf_conntrack_unregister_cache(i);
-       }
-       kmem_cache_destroy(nf_conntrack_expect_cachep);
-       free_conntrack_hash(nf_conntrack_hash, nf_conntrack_vmalloc,
-                           nf_conntrack_htable_size);
+       kmem_cache_destroy(nf_conntrack_cachep);
+       nf_ct_free_hashtable(nf_conntrack_hash, nf_conntrack_vmalloc,
+                            nf_conntrack_htable_size);
 
        nf_conntrack_proto_fini();
+       nf_conntrack_helper_fini();
+       nf_conntrack_expect_fini();
 }
 
-static struct list_head *alloc_hashtable(int size, int *vmalloced)
+struct hlist_head *nf_ct_alloc_hashtable(int *sizep, int *vmalloced)
 {
-       struct list_head *hash;
-       unsigned int i;
+       struct hlist_head *hash;
+       unsigned int size, i;
 
        *vmalloced = 0;
+
+       size = *sizep = roundup(*sizep, PAGE_SIZE / sizeof(struct hlist_head));
        hash = (void*)__get_free_pages(GFP_KERNEL,
-                                      get_order(sizeof(struct list_head)
+                                      get_order(sizeof(struct hlist_head)
                                                 * size));
        if (!hash) {
                *vmalloced = 1;
                printk(KERN_WARNING "nf_conntrack: falling back to vmalloc.\n");
-               hash = vmalloc(sizeof(struct list_head) * size);
+               hash = vmalloc(sizeof(struct hlist_head) * size);
        }
 
        if (hash)
                for (i = 0; i < size; i++)
-                       INIT_LIST_HEAD(&hash[i]);
+                       INIT_HLIST_HEAD(&hash[i]);
 
        return hash;
 }
+EXPORT_SYMBOL_GPL(nf_ct_alloc_hashtable);
 
 int set_hashsize(const char *val, struct kernel_param *kp)
 {
        int i, bucket, hashsize, vmalloced;
        int old_vmalloced, old_size;
        int rnd;
-       struct list_head *hash, *old_hash;
+       struct hlist_head *hash, *old_hash;
        struct nf_conntrack_tuple_hash *h;
 
        /* On boot, we can set this without any fancy locking. */
@@ -1186,7 +1003,7 @@ int set_hashsize(const char *val, struct kernel_param *kp)
        if (!hashsize)
                return -EINVAL;
 
-       hash = alloc_hashtable(hashsize, &vmalloced);
+       hash = nf_ct_alloc_hashtable(&hashsize, &vmalloced);
        if (!hash)
                return -ENOMEM;
 
@@ -1196,12 +1013,12 @@ int set_hashsize(const char *val, struct kernel_param *kp)
 
        write_lock_bh(&nf_conntrack_lock);
        for (i = 0; i < nf_conntrack_htable_size; i++) {
-               while (!list_empty(&nf_conntrack_hash[i])) {
-                       h = list_entry(nf_conntrack_hash[i].next,
-                                      struct nf_conntrack_tuple_hash, list);
-                       list_del(&h->list);
+               while (!hlist_empty(&nf_conntrack_hash[i])) {
+                       h = hlist_entry(nf_conntrack_hash[i].first,
+                                       struct nf_conntrack_tuple_hash, hnode);
+                       hlist_del(&h->hnode);
                        bucket = __hash_conntrack(&h->tuple, hashsize, rnd);
-                       list_add_tail(&h->list, &hash[bucket]);
+                       hlist_add_head(&h->hnode, &hash[bucket]);
                }
        }
        old_size = nf_conntrack_htable_size;
@@ -1214,7 +1031,7 @@ int set_hashsize(const char *val, struct kernel_param *kp)
        nf_conntrack_hash_rnd = rnd;
        write_unlock_bh(&nf_conntrack_lock);
 
-       free_conntrack_hash(old_hash, old_vmalloced, old_size);
+       nf_ct_free_hashtable(old_hash, old_vmalloced, old_size);
        return 0;
 }
 
@@ -1223,50 +1040,58 @@ module_param_call(hashsize, set_hashsize, param_get_uint,
 
 int __init nf_conntrack_init(void)
 {
+       int max_factor = 8;
        int ret;
 
        /* Idea from tcp.c: use 1/16384 of memory.  On i386: 32MB
-        * machine has 256 buckets.  >= 1GB machines have 8192 buckets. */
+        * machine has 512 buckets. >= 1GB machines have 16384 buckets. */
        if (!nf_conntrack_htable_size) {
                nf_conntrack_htable_size
                        = (((num_physpages << PAGE_SHIFT) / 16384)
-                          / sizeof(struct list_head));
+                          / sizeof(struct hlist_head));
                if (num_physpages > (1024 * 1024 * 1024 / PAGE_SIZE))
-                       nf_conntrack_htable_size = 8192;
-               if (nf_conntrack_htable_size < 16)
-                       nf_conntrack_htable_size = 16;
+                       nf_conntrack_htable_size = 16384;
+               if (nf_conntrack_htable_size < 32)
+                       nf_conntrack_htable_size = 32;
+
+               /* Use a max. factor of four by default to get the same max as
+                * with the old struct list_heads. When a table size is given
+                * we use the old value of 8 to avoid reducing the max.
+                * entries. */
+               max_factor = 4;
        }
-       nf_conntrack_max = 8 * nf_conntrack_htable_size;
-
-       printk("nf_conntrack version %s (%u buckets, %d max)\n",
-              NF_CONNTRACK_VERSION, nf_conntrack_htable_size,
-              nf_conntrack_max);
-
-       nf_conntrack_hash = alloc_hashtable(nf_conntrack_htable_size,
-                                           &nf_conntrack_vmalloc);
+       nf_conntrack_hash = nf_ct_alloc_hashtable(&nf_conntrack_htable_size,
+                                                 &nf_conntrack_vmalloc);
        if (!nf_conntrack_hash) {
                printk(KERN_ERR "Unable to create nf_conntrack_hash\n");
                goto err_out;
        }
 
-       ret = nf_conntrack_register_cache(NF_CT_F_BASIC, "nf_conntrack:basic",
-                                         sizeof(struct nf_conn));
-       if (ret < 0) {
+       nf_conntrack_max = max_factor * nf_conntrack_htable_size;
+
+       printk("nf_conntrack version %s (%u buckets, %d max)\n",
+              NF_CONNTRACK_VERSION, nf_conntrack_htable_size,
+              nf_conntrack_max);
+
+       nf_conntrack_cachep = kmem_cache_create("nf_conntrack",
+                                               sizeof(struct nf_conn),
+                                               0, 0, NULL, NULL);
+       if (!nf_conntrack_cachep) {
                printk(KERN_ERR "Unable to create nf_conn slab cache\n");
                goto err_free_hash;
        }
 
-       nf_conntrack_expect_cachep = kmem_cache_create("nf_conntrack_expect",
-                                       sizeof(struct nf_conntrack_expect),
-                                       0, 0, NULL, NULL);
-       if (!nf_conntrack_expect_cachep) {
-               printk(KERN_ERR "Unable to create nf_expect slab cache\n");
+       ret = nf_conntrack_proto_init();
+       if (ret < 0)
                goto err_free_conntrack_slab;
-       }
 
-       ret = nf_conntrack_proto_init();
+       ret = nf_conntrack_expect_init();
        if (ret < 0)
-               goto out_free_expect_slab;
+               goto out_fini_proto;
+
+       ret = nf_conntrack_helper_init();
+       if (ret < 0)
+               goto out_fini_expect;
 
        /* For use by REJECT target */
        rcu_assign_pointer(ip_ct_attach, __nf_conntrack_attach);
@@ -1280,13 +1105,15 @@ int __init nf_conntrack_init(void)
 
        return ret;
 
-out_free_expect_slab:
-       kmem_cache_destroy(nf_conntrack_expect_cachep);
+out_fini_expect:
+       nf_conntrack_expect_fini();
+out_fini_proto:
+       nf_conntrack_proto_fini();
 err_free_conntrack_slab:
-       nf_conntrack_unregister_cache(NF_CT_F_BASIC);
+       kmem_cache_destroy(nf_conntrack_cachep);
 err_free_hash:
-       free_conntrack_hash(nf_conntrack_hash, nf_conntrack_vmalloc,
-                           nf_conntrack_htable_size);
+       nf_ct_free_hashtable(nf_conntrack_hash, nf_conntrack_vmalloc,
+                            nf_conntrack_htable_size);
 err_out:
        return -ENOMEM;
 }
index 6bd421df2dbc7a4c6ade02875d88a97597583606..83c41ac3505b5b1ffb3ffb54969c77378d8b4139 100644 (file)
@@ -26,8 +26,8 @@
 ATOMIC_NOTIFIER_HEAD(nf_conntrack_chain);
 EXPORT_SYMBOL_GPL(nf_conntrack_chain);
 
-ATOMIC_NOTIFIER_HEAD(nf_conntrack_expect_chain);
-EXPORT_SYMBOL_GPL(nf_conntrack_expect_chain);
+ATOMIC_NOTIFIER_HEAD(nf_ct_expect_chain);
+EXPORT_SYMBOL_GPL(nf_ct_expect_chain);
 
 DEFINE_PER_CPU(struct nf_conntrack_ecache, nf_conntrack_ecache);
 EXPORT_PER_CPU_SYMBOL_GPL(nf_conntrack_ecache);
@@ -103,14 +103,14 @@ int nf_conntrack_unregister_notifier(struct notifier_block *nb)
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier);
 
-int nf_conntrack_expect_register_notifier(struct notifier_block *nb)
+int nf_ct_expect_register_notifier(struct notifier_block *nb)
 {
-       return atomic_notifier_chain_register(&nf_conntrack_expect_chain, nb);
+       return atomic_notifier_chain_register(&nf_ct_expect_chain, nb);
 }
-EXPORT_SYMBOL_GPL(nf_conntrack_expect_register_notifier);
+EXPORT_SYMBOL_GPL(nf_ct_expect_register_notifier);
 
-int nf_conntrack_expect_unregister_notifier(struct notifier_block *nb)
+int nf_ct_expect_unregister_notifier(struct notifier_block *nb)
 {
-       return atomic_notifier_chain_unregister(&nf_conntrack_expect_chain, nb);
+       return atomic_notifier_chain_unregister(&nf_ct_expect_chain, nb);
 }
-EXPORT_SYMBOL_GPL(nf_conntrack_expect_unregister_notifier);
+EXPORT_SYMBOL_GPL(nf_ct_expect_unregister_notifier);
index 504fb6c083f99bc30a9fac847943fa2dac4c51cb..2191fe008f60d9800f753df273f0d510a3419dd0 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/err.h>
 #include <linux/percpu.h>
 #include <linux/kernel.h>
+#include <linux/jhash.h>
 
 #include <net/netfilter/nf_conntrack.h>
 #include <net/netfilter/nf_conntrack_core.h>
 #include <net/netfilter/nf_conntrack_helper.h>
 #include <net/netfilter/nf_conntrack_tuple.h>
 
-LIST_HEAD(nf_conntrack_expect_list);
-EXPORT_SYMBOL_GPL(nf_conntrack_expect_list);
+struct hlist_head *nf_ct_expect_hash __read_mostly;
+EXPORT_SYMBOL_GPL(nf_ct_expect_hash);
 
-struct kmem_cache *nf_conntrack_expect_cachep __read_mostly;
-static unsigned int nf_conntrack_expect_next_id;
+unsigned int nf_ct_expect_hsize __read_mostly;
+EXPORT_SYMBOL_GPL(nf_ct_expect_hsize);
+
+static unsigned int nf_ct_expect_hash_rnd __read_mostly;
+static unsigned int nf_ct_expect_count;
+unsigned int nf_ct_expect_max __read_mostly;
+static int nf_ct_expect_hash_rnd_initted __read_mostly;
+static int nf_ct_expect_vmalloc;
+
+static struct kmem_cache *nf_ct_expect_cachep __read_mostly;
+static unsigned int nf_ct_expect_next_id;
 
 /* nf_conntrack_expect helper functions */
 void nf_ct_unlink_expect(struct nf_conntrack_expect *exp)
@@ -40,60 +50,83 @@ void nf_ct_unlink_expect(struct nf_conntrack_expect *exp)
        NF_CT_ASSERT(master_help);
        NF_CT_ASSERT(!timer_pending(&exp->timeout));
 
-       list_del(&exp->list);
-       NF_CT_STAT_INC(expect_delete);
+       hlist_del(&exp->hnode);
+       nf_ct_expect_count--;
+
+       hlist_del(&exp->lnode);
        master_help->expecting--;
-       nf_conntrack_expect_put(exp);
+       nf_ct_expect_put(exp);
+
+       NF_CT_STAT_INC(expect_delete);
 }
 EXPORT_SYMBOL_GPL(nf_ct_unlink_expect);
 
-static void expectation_timed_out(unsigned long ul_expect)
+static void nf_ct_expectation_timed_out(unsigned long ul_expect)
 {
        struct nf_conntrack_expect *exp = (void *)ul_expect;
 
        write_lock_bh(&nf_conntrack_lock);
        nf_ct_unlink_expect(exp);
        write_unlock_bh(&nf_conntrack_lock);
-       nf_conntrack_expect_put(exp);
+       nf_ct_expect_put(exp);
+}
+
+static unsigned int nf_ct_expect_dst_hash(const struct nf_conntrack_tuple *tuple)
+{
+       if (unlikely(!nf_ct_expect_hash_rnd_initted)) {
+               get_random_bytes(&nf_ct_expect_hash_rnd, 4);
+               nf_ct_expect_hash_rnd_initted = 1;
+       }
+
+       return jhash2(tuple->dst.u3.all, ARRAY_SIZE(tuple->dst.u3.all),
+                     (((tuple->dst.protonum ^ tuple->src.l3num) << 16) |
+                      tuple->dst.u.all) ^ nf_ct_expect_hash_rnd) %
+              nf_ct_expect_hsize;
 }
 
 struct nf_conntrack_expect *
-__nf_conntrack_expect_find(const struct nf_conntrack_tuple *tuple)
+__nf_ct_expect_find(const struct nf_conntrack_tuple *tuple)
 {
        struct nf_conntrack_expect *i;
+       struct hlist_node *n;
+       unsigned int h;
+
+       if (!nf_ct_expect_count)
+               return NULL;
 
-       list_for_each_entry(i, &nf_conntrack_expect_list, list) {
+       h = nf_ct_expect_dst_hash(tuple);
+       hlist_for_each_entry(i, n, &nf_ct_expect_hash[h], hnode) {
                if (nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask))
                        return i;
        }
        return NULL;
 }
-EXPORT_SYMBOL_GPL(__nf_conntrack_expect_find);
+EXPORT_SYMBOL_GPL(__nf_ct_expect_find);
 
 /* Just find a expectation corresponding to a tuple. */
 struct nf_conntrack_expect *
-nf_conntrack_expect_find_get(const struct nf_conntrack_tuple *tuple)
+nf_ct_expect_find_get(const struct nf_conntrack_tuple *tuple)
 {
        struct nf_conntrack_expect *i;
 
        read_lock_bh(&nf_conntrack_lock);
-       i = __nf_conntrack_expect_find(tuple);
+       i = __nf_ct_expect_find(tuple);
        if (i)
                atomic_inc(&i->use);
        read_unlock_bh(&nf_conntrack_lock);
 
        return i;
 }
-EXPORT_SYMBOL_GPL(nf_conntrack_expect_find_get);
+EXPORT_SYMBOL_GPL(nf_ct_expect_find_get);
 
 /* If an expectation for this connection is found, it gets delete from
  * global list then returned. */
 struct nf_conntrack_expect *
-find_expectation(const struct nf_conntrack_tuple *tuple)
+nf_ct_find_expectation(const struct nf_conntrack_tuple *tuple)
 {
        struct nf_conntrack_expect *exp;
 
-       exp = __nf_conntrack_expect_find(tuple);
+       exp = __nf_ct_expect_find(tuple);
        if (!exp)
                return NULL;
 
@@ -119,17 +152,18 @@ find_expectation(const struct nf_conntrack_tuple *tuple)
 /* delete all expectations for this conntrack */
 void nf_ct_remove_expectations(struct nf_conn *ct)
 {
-       struct nf_conntrack_expect *i, *tmp;
        struct nf_conn_help *help = nfct_help(ct);
+       struct nf_conntrack_expect *exp;
+       struct hlist_node *n, *next;
 
        /* Optimization: most connection never expect any others. */
        if (!help || help->expecting == 0)
                return;
 
-       list_for_each_entry_safe(i, tmp, &nf_conntrack_expect_list, list) {
-               if (i->master == ct && del_timer(&i->timeout)) {
-                       nf_ct_unlink_expect(i);
-                       nf_conntrack_expect_put(i);
+       hlist_for_each_entry_safe(exp, n, next, &help->expectations, lnode) {
+               if (del_timer(&exp->timeout)) {
+                       nf_ct_unlink_expect(exp);
+                       nf_ct_expect_put(exp);
                }
        }
 }
@@ -141,25 +175,16 @@ static inline int expect_clash(const struct nf_conntrack_expect *a,
 {
        /* Part covered by intersection of masks must be unequal,
           otherwise they clash */
-       struct nf_conntrack_tuple intersect_mask;
+       struct nf_conntrack_tuple_mask intersect_mask;
        int count;
 
-       intersect_mask.src.l3num = a->mask.src.l3num & b->mask.src.l3num;
        intersect_mask.src.u.all = a->mask.src.u.all & b->mask.src.u.all;
-       intersect_mask.dst.u.all = a->mask.dst.u.all & b->mask.dst.u.all;
-       intersect_mask.dst.protonum = a->mask.dst.protonum
-                                       & b->mask.dst.protonum;
 
        for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
                intersect_mask.src.u3.all[count] =
                        a->mask.src.u3.all[count] & b->mask.src.u3.all[count];
        }
 
-       for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
-               intersect_mask.dst.u3.all[count] =
-                       a->mask.dst.u3.all[count] & b->mask.dst.u3.all[count];
-       }
-
        return nf_ct_tuple_mask_cmp(&a->tuple, &b->tuple, &intersect_mask);
 }
 
@@ -168,36 +193,29 @@ static inline int expect_matches(const struct nf_conntrack_expect *a,
 {
        return a->master == b->master
                && nf_ct_tuple_equal(&a->tuple, &b->tuple)
-               && nf_ct_tuple_equal(&a->mask, &b->mask);
+               && nf_ct_tuple_mask_equal(&a->mask, &b->mask);
 }
 
 /* Generally a bad idea to call this: could have matched already. */
-void nf_conntrack_unexpect_related(struct nf_conntrack_expect *exp)
+void nf_ct_unexpect_related(struct nf_conntrack_expect *exp)
 {
-       struct nf_conntrack_expect *i;
-
        write_lock_bh(&nf_conntrack_lock);
-       /* choose the oldest expectation to evict */
-       list_for_each_entry_reverse(i, &nf_conntrack_expect_list, list) {
-               if (expect_matches(i, exp) && del_timer(&i->timeout)) {
-                       nf_ct_unlink_expect(i);
-                       write_unlock_bh(&nf_conntrack_lock);
-                       nf_conntrack_expect_put(i);
-                       return;
-               }
+       if (del_timer(&exp->timeout)) {
+               nf_ct_unlink_expect(exp);
+               nf_ct_expect_put(exp);
        }
        write_unlock_bh(&nf_conntrack_lock);
 }
-EXPORT_SYMBOL_GPL(nf_conntrack_unexpect_related);
+EXPORT_SYMBOL_GPL(nf_ct_unexpect_related);
 
 /* We don't increase the master conntrack refcount for non-fulfilled
  * conntracks. During the conntrack destruction, the expectations are
  * always killed before the conntrack itself */
-struct nf_conntrack_expect *nf_conntrack_expect_alloc(struct nf_conn *me)
+struct nf_conntrack_expect *nf_ct_expect_alloc(struct nf_conn *me)
 {
        struct nf_conntrack_expect *new;
 
-       new = kmem_cache_alloc(nf_conntrack_expect_cachep, GFP_ATOMIC);
+       new = kmem_cache_alloc(nf_ct_expect_cachep, GFP_ATOMIC);
        if (!new)
                return NULL;
 
@@ -205,12 +223,12 @@ struct nf_conntrack_expect *nf_conntrack_expect_alloc(struct nf_conn *me)
        atomic_set(&new->use, 1);
        return new;
 }
-EXPORT_SYMBOL_GPL(nf_conntrack_expect_alloc);
+EXPORT_SYMBOL_GPL(nf_ct_expect_alloc);
 
-void nf_conntrack_expect_init(struct nf_conntrack_expect *exp, int family,
-                             union nf_conntrack_address *saddr,
-                             union nf_conntrack_address *daddr,
-                             u_int8_t proto, __be16 *src, __be16 *dst)
+void nf_ct_expect_init(struct nf_conntrack_expect *exp, int family,
+                      union nf_conntrack_address *saddr,
+                      union nf_conntrack_address *daddr,
+                      u_int8_t proto, __be16 *src, __be16 *dst)
 {
        int len;
 
@@ -224,8 +242,6 @@ void nf_conntrack_expect_init(struct nf_conntrack_expect *exp, int family,
        exp->helper = NULL;
        exp->tuple.src.l3num = family;
        exp->tuple.dst.protonum = proto;
-       exp->mask.src.l3num = 0xFFFF;
-       exp->mask.dst.protonum = 0xFF;
 
        if (saddr) {
                memcpy(&exp->tuple.src.u3, saddr, len);
@@ -242,21 +258,6 @@ void nf_conntrack_expect_init(struct nf_conntrack_expect *exp, int family,
                memset(&exp->mask.src.u3, 0x00, sizeof(exp->mask.src.u3));
        }
 
-       if (daddr) {
-               memcpy(&exp->tuple.dst.u3, daddr, len);
-               if (sizeof(exp->tuple.dst.u3) > len)
-                       /* address needs to be cleared for nf_ct_tuple_equal */
-                       memset((void *)&exp->tuple.dst.u3 + len, 0x00,
-                              sizeof(exp->tuple.dst.u3) - len);
-               memset(&exp->mask.dst.u3, 0xFF, len);
-               if (sizeof(exp->mask.dst.u3) > len)
-                       memset((void *)&exp->mask.dst.u3 + len, 0x00,
-                              sizeof(exp->mask.dst.u3) - len);
-       } else {
-               memset(&exp->tuple.dst.u3, 0x00, sizeof(exp->tuple.dst.u3));
-               memset(&exp->mask.dst.u3, 0x00, sizeof(exp->mask.dst.u3));
-       }
-
        if (src) {
                exp->tuple.src.u.all = (__force u16)*src;
                exp->mask.src.u.all = 0xFFFF;
@@ -265,36 +266,42 @@ void nf_conntrack_expect_init(struct nf_conntrack_expect *exp, int family,
                exp->mask.src.u.all = 0;
        }
 
-       if (dst) {
-               exp->tuple.dst.u.all = (__force u16)*dst;
-               exp->mask.dst.u.all = 0xFFFF;
-       } else {
-               exp->tuple.dst.u.all = 0;
-               exp->mask.dst.u.all = 0;
-       }
+       memcpy(&exp->tuple.dst.u3, daddr, len);
+       if (sizeof(exp->tuple.dst.u3) > len)
+               /* address needs to be cleared for nf_ct_tuple_equal */
+               memset((void *)&exp->tuple.dst.u3 + len, 0x00,
+                      sizeof(exp->tuple.dst.u3) - len);
+
+       exp->tuple.dst.u.all = (__force u16)*dst;
 }
-EXPORT_SYMBOL_GPL(nf_conntrack_expect_init);
+EXPORT_SYMBOL_GPL(nf_ct_expect_init);
 
-void nf_conntrack_expect_put(struct nf_conntrack_expect *exp)
+void nf_ct_expect_put(struct nf_conntrack_expect *exp)
 {
        if (atomic_dec_and_test(&exp->use))
-               kmem_cache_free(nf_conntrack_expect_cachep, exp);
+               kmem_cache_free(nf_ct_expect_cachep, exp);
 }
-EXPORT_SYMBOL_GPL(nf_conntrack_expect_put);
+EXPORT_SYMBOL_GPL(nf_ct_expect_put);
 
-static void nf_conntrack_expect_insert(struct nf_conntrack_expect *exp)
+static void nf_ct_expect_insert(struct nf_conntrack_expect *exp)
 {
        struct nf_conn_help *master_help = nfct_help(exp->master);
+       unsigned int h = nf_ct_expect_dst_hash(&exp->tuple);
 
        atomic_inc(&exp->use);
+
+       hlist_add_head(&exp->lnode, &master_help->expectations);
        master_help->expecting++;
-       list_add(&exp->list, &nf_conntrack_expect_list);
 
-       setup_timer(&exp->timeout, expectation_timed_out, (unsigned long)exp);
+       hlist_add_head(&exp->hnode, &nf_ct_expect_hash[h]);
+       nf_ct_expect_count++;
+
+       setup_timer(&exp->timeout, nf_ct_expectation_timed_out,
+                   (unsigned long)exp);
        exp->timeout.expires = jiffies + master_help->helper->timeout * HZ;
        add_timer(&exp->timeout);
 
-       exp->id = ++nf_conntrack_expect_next_id;
+       exp->id = ++nf_ct_expect_next_id;
        atomic_inc(&exp->use);
        NF_CT_STAT_INC(expect_create);
 }
@@ -302,16 +309,16 @@ static void nf_conntrack_expect_insert(struct nf_conntrack_expect *exp)
 /* Race with expectations being used means we could have none to find; OK. */
 static void evict_oldest_expect(struct nf_conn *master)
 {
-       struct nf_conntrack_expect *i;
+       struct nf_conn_help *master_help = nfct_help(master);
+       struct nf_conntrack_expect *exp = NULL;
+       struct hlist_node *n;
 
-       list_for_each_entry_reverse(i, &nf_conntrack_expect_list, list) {
-               if (i->master == master) {
-                       if (del_timer(&i->timeout)) {
-                               nf_ct_unlink_expect(i);
-                               nf_conntrack_expect_put(i);
-                       }
-                       break;
-               }
+       hlist_for_each_entry(exp, n, &master_help->expectations, lnode)
+               ; /* nothing */
+
+       if (exp && del_timer(&exp->timeout)) {
+               nf_ct_unlink_expect(exp);
+               nf_ct_expect_put(exp);
        }
 }
 
@@ -327,11 +334,13 @@ static inline int refresh_timer(struct nf_conntrack_expect *i)
        return 1;
 }
 
-int nf_conntrack_expect_related(struct nf_conntrack_expect *expect)
+int nf_ct_expect_related(struct nf_conntrack_expect *expect)
 {
        struct nf_conntrack_expect *i;
        struct nf_conn *master = expect->master;
        struct nf_conn_help *master_help = nfct_help(master);
+       struct hlist_node *n;
+       unsigned int h;
        int ret;
 
        NF_CT_ASSERT(master_help);
@@ -341,7 +350,8 @@ int nf_conntrack_expect_related(struct nf_conntrack_expect *expect)
                ret = -ESHUTDOWN;
                goto out;
        }
-       list_for_each_entry(i, &nf_conntrack_expect_list, list) {
+       h = nf_ct_expect_dst_hash(&expect->tuple);
+       hlist_for_each_entry(i, n, &nf_ct_expect_hash[h], hnode) {
                if (expect_matches(i, expect)) {
                        /* Refresh timer: if it's dying, ignore.. */
                        if (refresh_timer(i)) {
@@ -358,57 +368,86 @@ int nf_conntrack_expect_related(struct nf_conntrack_expect *expect)
            master_help->expecting >= master_help->helper->max_expected)
                evict_oldest_expect(master);
 
-       nf_conntrack_expect_insert(expect);
-       nf_conntrack_expect_event(IPEXP_NEW, expect);
+       if (nf_ct_expect_count >= nf_ct_expect_max) {
+               if (net_ratelimit())
+                       printk(KERN_WARNING
+                              "nf_conntrack: expectation table full");
+               ret = -EMFILE;
+               goto out;
+       }
+
+       nf_ct_expect_insert(expect);
+       nf_ct_expect_event(IPEXP_NEW, expect);
        ret = 0;
 out:
        write_unlock_bh(&nf_conntrack_lock);
        return ret;
 }
-EXPORT_SYMBOL_GPL(nf_conntrack_expect_related);
+EXPORT_SYMBOL_GPL(nf_ct_expect_related);
 
 #ifdef CONFIG_PROC_FS
-static void *exp_seq_start(struct seq_file *s, loff_t *pos)
+struct ct_expect_iter_state {
+       unsigned int bucket;
+};
+
+static struct hlist_node *ct_expect_get_first(struct seq_file *seq)
 {
-       struct list_head *e = &nf_conntrack_expect_list;
-       loff_t i;
+       struct ct_expect_iter_state *st = seq->private;
 
-       /* strange seq_file api calls stop even if we fail,
-        * thus we need to grab lock since stop unlocks */
-       read_lock_bh(&nf_conntrack_lock);
+       for (st->bucket = 0; st->bucket < nf_ct_expect_hsize; st->bucket++) {
+               if (!hlist_empty(&nf_ct_expect_hash[st->bucket]))
+                       return nf_ct_expect_hash[st->bucket].first;
+       }
+       return NULL;
+}
 
-       if (list_empty(e))
-               return NULL;
+static struct hlist_node *ct_expect_get_next(struct seq_file *seq,
+                                            struct hlist_node *head)
+{
+       struct ct_expect_iter_state *st = seq->private;
 
-       for (i = 0; i <= *pos; i++) {
-               e = e->next;
-               if (e == &nf_conntrack_expect_list)
+       head = head->next;
+       while (head == NULL) {
+               if (++st->bucket >= nf_ct_expect_hsize)
                        return NULL;
+               head = nf_ct_expect_hash[st->bucket].first;
        }
-       return e;
+       return head;
 }
 
-static void *exp_seq_next(struct seq_file *s, void *v, loff_t *pos)
+static struct hlist_node *ct_expect_get_idx(struct seq_file *seq, loff_t pos)
 {
-       struct list_head *e = v;
+       struct hlist_node *head = ct_expect_get_first(seq);
 
-       ++*pos;
-       e = e->next;
+       if (head)
+               while (pos && (head = ct_expect_get_next(seq, head)))
+                       pos--;
+       return pos ? NULL : head;
+}
 
-       if (e == &nf_conntrack_expect_list)
-               return NULL;
+static void *exp_seq_start(struct seq_file *seq, loff_t *pos)
+{
+       read_lock_bh(&nf_conntrack_lock);
+       return ct_expect_get_idx(seq, *pos);
+}
 
-       return e;
+static void *exp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+       (*pos)++;
+       return ct_expect_get_next(seq, v);
 }
 
-static void exp_seq_stop(struct seq_file *s, void *v)
+static void exp_seq_stop(struct seq_file *seq, void *v)
 {
        read_unlock_bh(&nf_conntrack_lock);
 }
 
 static int exp_seq_show(struct seq_file *s, void *v)
 {
-       struct nf_conntrack_expect *expect = v;
+       struct nf_conntrack_expect *expect;
+       struct hlist_node *n = v;
+
+       expect = hlist_entry(n, struct nf_conntrack_expect, hnode);
 
        if (expect->timeout.function)
                seq_printf(s, "%ld ", timer_pending(&expect->timeout)
@@ -425,7 +464,7 @@ static int exp_seq_show(struct seq_file *s, void *v)
        return seq_putc(s, '\n');
 }
 
-static struct seq_operations exp_seq_ops = {
+static const struct seq_operations exp_seq_ops = {
        .start = exp_seq_start,
        .next = exp_seq_next,
        .stop = exp_seq_stop,
@@ -434,14 +473,96 @@ static struct seq_operations exp_seq_ops = {
 
 static int exp_open(struct inode *inode, struct file *file)
 {
-       return seq_open(file, &exp_seq_ops);
+       struct seq_file *seq;
+       struct ct_expect_iter_state *st;
+       int ret;
+
+       st = kmalloc(sizeof(struct ct_expect_iter_state), GFP_KERNEL);
+       if (st == NULL)
+               return -ENOMEM;
+       ret = seq_open(file, &exp_seq_ops);
+       if (ret)
+               goto out_free;
+       seq          = file->private_data;
+       seq->private = st;
+       memset(st, 0, sizeof(struct ct_expect_iter_state));
+       return ret;
+out_free:
+       kfree(st);
+       return ret;
 }
 
-const struct file_operations exp_file_ops = {
+static const struct file_operations exp_file_ops = {
        .owner   = THIS_MODULE,
        .open    = exp_open,
        .read    = seq_read,
        .llseek  = seq_lseek,
-       .release = seq_release
+       .release = seq_release_private,
 };
 #endif /* CONFIG_PROC_FS */
+
+static int __init exp_proc_init(void)
+{
+#ifdef CONFIG_PROC_FS
+       struct proc_dir_entry *proc;
+
+       proc = proc_net_fops_create("nf_conntrack_expect", 0440, &exp_file_ops);
+       if (!proc)
+               return -ENOMEM;
+#endif /* CONFIG_PROC_FS */
+       return 0;
+}
+
+static void exp_proc_remove(void)
+{
+#ifdef CONFIG_PROC_FS
+       proc_net_remove("nf_conntrack_expect");
+#endif /* CONFIG_PROC_FS */
+}
+
+module_param_named(expect_hashsize, nf_ct_expect_hsize, uint, 0600);
+
+int __init nf_conntrack_expect_init(void)
+{
+       int err = -ENOMEM;
+
+       if (!nf_ct_expect_hsize) {
+               nf_ct_expect_hsize = nf_conntrack_htable_size / 256;
+               if (!nf_ct_expect_hsize)
+                       nf_ct_expect_hsize = 1;
+       }
+       nf_ct_expect_max = nf_ct_expect_hsize * 4;
+
+       nf_ct_expect_hash = nf_ct_alloc_hashtable(&nf_ct_expect_hsize,
+                                                 &nf_ct_expect_vmalloc);
+       if (nf_ct_expect_hash == NULL)
+               goto err1;
+
+       nf_ct_expect_cachep = kmem_cache_create("nf_conntrack_expect",
+                                       sizeof(struct nf_conntrack_expect),
+                                       0, 0, NULL, NULL);
+       if (!nf_ct_expect_cachep)
+               goto err2;
+
+       err = exp_proc_init();
+       if (err < 0)
+               goto err3;
+
+       return 0;
+
+err3:
+       nf_ct_free_hashtable(nf_ct_expect_hash, nf_ct_expect_vmalloc,
+                            nf_ct_expect_hsize);
+err2:
+       kmem_cache_destroy(nf_ct_expect_cachep);
+err1:
+       return err;
+}
+
+void nf_conntrack_expect_fini(void)
+{
+       exp_proc_remove();
+       kmem_cache_destroy(nf_ct_expect_cachep);
+       nf_ct_free_hashtable(nf_ct_expect_hash, nf_ct_expect_vmalloc,
+                            nf_ct_expect_hsize);
+}
diff --git a/net/netfilter/nf_conntrack_extend.c b/net/netfilter/nf_conntrack_extend.c
new file mode 100644 (file)
index 0000000..a1a65a1
--- /dev/null
@@ -0,0 +1,195 @@
+/* Structure dynamic extension infrastructure
+ * Copyright (C) 2004 Rusty Russell IBM Corporation
+ * Copyright (C) 2007 Netfilter Core Team <coreteam@netfilter.org>
+ * Copyright (C) 2007 USAGI/WIDE Project <http://www.linux-ipv6.org>
+ *
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/rcupdate.h>
+#include <linux/slab.h>
+#include <linux/skbuff.h>
+#include <net/netfilter/nf_conntrack_extend.h>
+
+static struct nf_ct_ext_type *nf_ct_ext_types[NF_CT_EXT_NUM];
+static DEFINE_MUTEX(nf_ct_ext_type_mutex);
+
+/* Horrible trick to figure out smallest amount worth kmallocing. */
+#define CACHE(x) (x) + 0 *
+enum {
+       NF_CT_EXT_MIN_SIZE =
+#include <linux/kmalloc_sizes.h>
+       1 };
+#undef CACHE
+
+void __nf_ct_ext_destroy(struct nf_conn *ct)
+{
+       unsigned int i;
+       struct nf_ct_ext_type *t;
+
+       for (i = 0; i < NF_CT_EXT_NUM; i++) {
+               if (!nf_ct_ext_exist(ct, i))
+                       continue;
+
+               rcu_read_lock();
+               t = rcu_dereference(nf_ct_ext_types[i]);
+
+               /* Here the nf_ct_ext_type might have been unregisterd.
+                * I.e., it has responsible to cleanup private
+                * area in all conntracks when it is unregisterd.
+                */
+               if (t && t->destroy)
+                       t->destroy(ct);
+               rcu_read_unlock();
+       }
+}
+EXPORT_SYMBOL(__nf_ct_ext_destroy);
+
+static void *
+nf_ct_ext_create(struct nf_ct_ext **ext, enum nf_ct_ext_id id, gfp_t gfp)
+{
+       unsigned int off, len, real_len;
+       struct nf_ct_ext_type *t;
+
+       rcu_read_lock();
+       t = rcu_dereference(nf_ct_ext_types[id]);
+       BUG_ON(t == NULL);
+       off = ALIGN(sizeof(struct nf_ct_ext), t->align);
+       len = off + t->len;
+       real_len = t->alloc_size;
+       rcu_read_unlock();
+
+       *ext = kzalloc(real_len, gfp);
+       if (!*ext)
+               return NULL;
+
+       (*ext)->offset[id] = off;
+       (*ext)->len = len;
+       (*ext)->real_len = real_len;
+
+       return (void *)(*ext) + off;
+}
+
+void *__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp)
+{
+       struct nf_ct_ext *new;
+       int i, newlen, newoff;
+       struct nf_ct_ext_type *t;
+
+       if (!ct->ext)
+               return nf_ct_ext_create(&ct->ext, id, gfp);
+
+       if (nf_ct_ext_exist(ct, id))
+               return NULL;
+
+       rcu_read_lock();
+       t = rcu_dereference(nf_ct_ext_types[id]);
+       BUG_ON(t == NULL);
+
+       newoff = ALIGN(ct->ext->len, t->align);
+       newlen = newoff + t->len;
+       rcu_read_unlock();
+
+       if (newlen >= ct->ext->real_len) {
+               new = kmalloc(newlen, gfp);
+               if (!new)
+                       return NULL;
+
+               memcpy(new, ct->ext, ct->ext->len);
+
+               for (i = 0; i < NF_CT_EXT_NUM; i++) {
+                       if (!nf_ct_ext_exist(ct, i))
+                               continue;
+
+                       rcu_read_lock();
+                       t = rcu_dereference(nf_ct_ext_types[i]);
+                       if (t && t->move)
+                               t->move(ct, ct->ext + ct->ext->offset[id]);
+                       rcu_read_unlock();
+               }
+               kfree(ct->ext);
+               new->real_len = newlen;
+               ct->ext = new;
+       }
+
+       ct->ext->offset[id] = newoff;
+       ct->ext->len = newlen;
+       memset((void *)ct->ext + newoff, 0, newlen - newoff);
+       return (void *)ct->ext + newoff;
+}
+EXPORT_SYMBOL(__nf_ct_ext_add);
+
+static void update_alloc_size(struct nf_ct_ext_type *type)
+{
+       int i, j;
+       struct nf_ct_ext_type *t1, *t2;
+       enum nf_ct_ext_id min = 0, max = NF_CT_EXT_NUM - 1;
+
+       /* unnecessary to update all types */
+       if ((type->flags & NF_CT_EXT_F_PREALLOC) == 0) {
+               min = type->id;
+               max = type->id;
+       }
+
+       /* This assumes that extended areas in conntrack for the types
+          whose NF_CT_EXT_F_PREALLOC bit set are allocated in order */
+       for (i = min; i <= max; i++) {
+               t1 = nf_ct_ext_types[i];
+               if (!t1)
+                       continue;
+
+               t1->alloc_size = sizeof(struct nf_ct_ext)
+                                + ALIGN(sizeof(struct nf_ct_ext), t1->align)
+                                + t1->len;
+               for (j = 0; j < NF_CT_EXT_NUM; j++) {
+                       t2 = nf_ct_ext_types[j];
+                       if (t2 == NULL || t2 == t1 ||
+                           (t2->flags & NF_CT_EXT_F_PREALLOC) == 0)
+                               continue;
+
+                       t1->alloc_size = ALIGN(t1->alloc_size, t2->align)
+                                        + t2->len;
+               }
+               if (t1->alloc_size < NF_CT_EXT_MIN_SIZE)
+                       t1->alloc_size = NF_CT_EXT_MIN_SIZE;
+       }
+}
+
+/* This MUST be called in process context. */
+int nf_ct_extend_register(struct nf_ct_ext_type *type)
+{
+       int ret = 0;
+
+       mutex_lock(&nf_ct_ext_type_mutex);
+       if (nf_ct_ext_types[type->id]) {
+               ret = -EBUSY;
+               goto out;
+       }
+
+       /* This ensures that nf_ct_ext_create() can allocate enough area
+          before updating alloc_size */
+       type->alloc_size = ALIGN(sizeof(struct nf_ct_ext), type->align)
+                          + type->len;
+       rcu_assign_pointer(nf_ct_ext_types[type->id], type);
+       update_alloc_size(type);
+out:
+       mutex_unlock(&nf_ct_ext_type_mutex);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(nf_ct_extend_register);
+
+/* This MUST be called in process context. */
+void nf_ct_extend_unregister(struct nf_ct_ext_type *type)
+{
+       mutex_lock(&nf_ct_ext_type_mutex);
+       rcu_assign_pointer(nf_ct_ext_types[type->id], NULL);
+       update_alloc_size(type);
+       mutex_unlock(&nf_ct_ext_type_mutex);
+       synchronize_rcu();
+}
+EXPORT_SYMBOL_GPL(nf_ct_extend_unregister);
index 82db2aa53bfce5acecac166f4d10e493dc2fe478..c763ee74ea02752b9a8b4ada4b58468e0f47fa39 100644 (file)
@@ -51,12 +51,6 @@ unsigned int (*nf_nat_ftp_hook)(struct sk_buff **pskb,
                                struct nf_conntrack_expect *exp);
 EXPORT_SYMBOL_GPL(nf_nat_ftp_hook);
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 static int try_rfc959(const char *, size_t, struct nf_conntrack_man *, char);
 static int try_eprt(const char *, size_t, struct nf_conntrack_man *, char);
 static int try_epsv_response(const char *, size_t, struct nf_conntrack_man *,
@@ -138,13 +132,13 @@ static int try_number(const char *data, size_t dlen, u_int32_t array[],
                        if (*data == term && i == array_size - 1)
                                return len;
 
-                       DEBUGP("Char %u (got %u nums) `%u' unexpected\n",
-                              len, i, *data);
+                       pr_debug("Char %u (got %u nums) `%u' unexpected\n",
+                                len, i, *data);
                        return 0;
                }
        }
-       DEBUGP("Failed to fill %u numbers separated by %c\n", array_size, sep);
-
+       pr_debug("Failed to fill %u numbers separated by %c\n",
+                array_size, sep);
        return 0;
 }
 
@@ -178,13 +172,13 @@ static int get_port(const char *data, int start, size_t dlen, char delim,
                        if (tmp_port == 0)
                                break;
                        *port = htons(tmp_port);
-                       DEBUGP("get_port: return %d\n", tmp_port);
+                       pr_debug("get_port: return %d\n", tmp_port);
                        return i + 1;
                }
                else if (data[i] >= '0' && data[i] <= '9')
                        tmp_port = tmp_port*10 + data[i] - '0';
                else { /* Some other crap */
-                       DEBUGP("get_port: invalid char.\n");
+                       pr_debug("get_port: invalid char.\n");
                        break;
                }
        }
@@ -201,22 +195,22 @@ static int try_eprt(const char *data, size_t dlen, struct nf_conntrack_man *cmd,
        /* First character is delimiter, then "1" for IPv4 or "2" for IPv6,
           then delimiter again. */
        if (dlen <= 3) {
-               DEBUGP("EPRT: too short\n");
+               pr_debug("EPRT: too short\n");
                return 0;
        }
        delim = data[0];
        if (isdigit(delim) || delim < 33 || delim > 126 || data[2] != delim) {
-               DEBUGP("try_eprt: invalid delimitter.\n");
+               pr_debug("try_eprt: invalid delimitter.\n");
                return 0;
        }
 
        if ((cmd->l3num == PF_INET && data[1] != '1') ||
            (cmd->l3num == PF_INET6 && data[1] != '2')) {
-               DEBUGP("EPRT: invalid protocol number.\n");
+               pr_debug("EPRT: invalid protocol number.\n");
                return 0;
        }
 
-       DEBUGP("EPRT: Got %c%c%c\n", delim, data[1], delim);
+       pr_debug("EPRT: Got %c%c%c\n", delim, data[1], delim);
 
        if (data[1] == '1') {
                u_int32_t array[4];
@@ -234,7 +228,7 @@ static int try_eprt(const char *data, size_t dlen, struct nf_conntrack_man *cmd,
 
        if (length == 0)
                return 0;
-       DEBUGP("EPRT: Got IP address!\n");
+       pr_debug("EPRT: Got IP address!\n");
        /* Start offset includes initial "|1|", and trailing delimiter */
        return get_port(data, 3 + length + 1, dlen, delim, &cmd->u.tcp.port);
 }
@@ -267,7 +261,7 @@ static int find_pattern(const char *data, size_t dlen,
 {
        size_t i;
 
-       DEBUGP("find_pattern `%s': dlen = %u\n", pattern, dlen);
+       pr_debug("find_pattern `%s': dlen = %Zu\n", pattern, dlen);
        if (dlen == 0)
                return 0;
 
@@ -282,17 +276,17 @@ static int find_pattern(const char *data, size_t dlen,
 #if 0
                size_t i;
 
-               DEBUGP("ftp: string mismatch\n");
+               pr_debug("ftp: string mismatch\n");
                for (i = 0; i < plen; i++) {
-                       DEBUGP("ftp:char %u `%c'(%u) vs `%c'(%u)\n",
-                               i, data[i], data[i],
-                               pattern[i], pattern[i]);
+                       pr_debug("ftp:char %u `%c'(%u) vs `%c'(%u)\n",
+                                i, data[i], data[i],
+                                pattern[i], pattern[i]);
                }
 #endif
                return 0;
        }
 
-       DEBUGP("Pattern matches!\n");
+       pr_debug("Pattern matches!\n");
        /* Now we've found the constant string, try to skip
           to the 'skip' character */
        for (i = plen; data[i] != skip; i++)
@@ -301,14 +295,14 @@ static int find_pattern(const char *data, size_t dlen,
        /* Skip over the last character */
        i++;
 
-       DEBUGP("Skipped up to `%c'!\n", skip);
+       pr_debug("Skipped up to `%c'!\n", skip);
 
        *numoff = i;
        *numlen = getnum(data + i, dlen - i, cmd, term);
        if (!*numlen)
                return -1;
 
-       DEBUGP("Match succeeded!\n");
+       pr_debug("Match succeeded!\n");
        return 1;
 }
 
@@ -364,6 +358,7 @@ static int help(struct sk_buff **pskb,
        unsigned int matchlen, matchoff;
        struct nf_ct_ftp_master *ct_ftp_info = &nfct_help(ct)->help.ct_ftp_info;
        struct nf_conntrack_expect *exp;
+       union nf_conntrack_address *daddr;
        struct nf_conntrack_man cmd = {};
        unsigned int i;
        int found = 0, ends_in_nl;
@@ -372,7 +367,7 @@ static int help(struct sk_buff **pskb,
        /* Until there's been traffic both ways, don't look in packets. */
        if (ctinfo != IP_CT_ESTABLISHED
            && ctinfo != IP_CT_ESTABLISHED+IP_CT_IS_REPLY) {
-               DEBUGP("ftp: Conntrackinfo = %u\n", ctinfo);
+               pr_debug("ftp: Conntrackinfo = %u\n", ctinfo);
                return NF_ACCEPT;
        }
 
@@ -383,8 +378,8 @@ static int help(struct sk_buff **pskb,
        dataoff = protoff + th->doff * 4;
        /* No data? */
        if (dataoff >= (*pskb)->len) {
-               DEBUGP("ftp: dataoff(%u) >= skblen(%u)\n", dataoff,
-                       (*pskb)->len);
+               pr_debug("ftp: dataoff(%u) >= skblen(%u)\n", dataoff,
+                        (*pskb)->len);
                return NF_ACCEPT;
        }
        datalen = (*pskb)->len - dataoff;
@@ -399,11 +394,11 @@ static int help(struct sk_buff **pskb,
        /* Look up to see if we're just after a \n. */
        if (!find_nl_seq(ntohl(th->seq), ct_ftp_info, dir)) {
                /* Now if this ends in \n, update ftp info. */
-               DEBUGP("nf_conntrack_ftp_help: wrong seq pos %s(%u) or %s(%u)\n",
-                      ct_ftp_info->seq_aft_nl_num[dir] > 0 ? "" : "(UNSET)",
-                      ct_ftp_info->seq_aft_nl[dir][0],
-                      ct_ftp_info->seq_aft_nl_num[dir] > 1 ? "" : "(UNSET)",
-                      ct_ftp_info->seq_aft_nl[dir][1]);
+               pr_debug("nf_conntrack_ftp: wrong seq pos %s(%u) or %s(%u)\n",
+                        ct_ftp_info->seq_aft_nl_num[dir] > 0 ? "" : "(UNSET)",
+                        ct_ftp_info->seq_aft_nl[dir][0],
+                        ct_ftp_info->seq_aft_nl_num[dir] > 1 ? "" : "(UNSET)",
+                        ct_ftp_info->seq_aft_nl[dir][1]);
                ret = NF_ACCEPT;
                goto out_update_nl;
        }
@@ -441,11 +436,11 @@ static int help(struct sk_buff **pskb,
                goto out_update_nl;
        }
 
-       DEBUGP("conntrack_ftp: match `%.*s' (%u bytes at %u)\n",
-              (int)matchlen, fb_ptr + matchoff,
-              matchlen, ntohl(th->seq) + matchoff);
+       pr_debug("conntrack_ftp: match `%.*s' (%u bytes at %u)\n",
+                matchlen, fb_ptr + matchoff,
+                matchlen, ntohl(th->seq) + matchoff);
 
-       exp = nf_conntrack_expect_alloc(ct);
+       exp = nf_ct_expect_alloc(ct);
        if (exp == NULL) {
                ret = NF_DROP;
                goto out;
@@ -454,7 +449,7 @@ static int help(struct sk_buff **pskb,
        /* We refer to the reverse direction ("!dir") tuples here,
         * because we're expecting something in the other direction.
         * Doesn't matter unless NAT is happening.  */
-       exp->tuple.dst.u3 = ct->tuplehash[!dir].tuple.dst.u3;
+       daddr = &ct->tuplehash[!dir].tuple.dst.u3;
 
        /* Update the ftp info */
        if ((cmd.l3num == ct->tuplehash[dir].tuple.src.l3num) &&
@@ -465,14 +460,16 @@ static int help(struct sk_buff **pskb,
                   different IP address.  Simply don't record it for
                   NAT. */
                if (cmd.l3num == PF_INET) {
-                       DEBUGP("conntrack_ftp: NOT RECORDING: " NIPQUAD_FMT " != " NIPQUAD_FMT "\n",
-                              NIPQUAD(cmd.u3.ip),
-                              NIPQUAD(ct->tuplehash[dir].tuple.src.u3.ip));
+                       pr_debug("conntrack_ftp: NOT RECORDING: " NIPQUAD_FMT
+                                " != " NIPQUAD_FMT "\n",
+                                NIPQUAD(cmd.u3.ip),
+                                NIPQUAD(ct->tuplehash[dir].tuple.src.u3.ip));
                } else {
-                       DEBUGP("conntrack_ftp: NOT RECORDING: " NIP6_FMT " != " NIP6_FMT "\n",
-                              NIP6(*((struct in6_addr *)cmd.u3.ip6)),
-                              NIP6(*((struct in6_addr *)ct->tuplehash[dir]
-                                                       .tuple.src.u3.ip6)));
+                       pr_debug("conntrack_ftp: NOT RECORDING: " NIP6_FMT
+                                " != " NIP6_FMT "\n",
+                                NIP6(*((struct in6_addr *)cmd.u3.ip6)),
+                                NIP6(*((struct in6_addr *)
+                                       ct->tuplehash[dir].tuple.src.u3.ip6)));
                }
 
                /* Thanks to Cristiano Lincoln Mattos
@@ -483,37 +480,12 @@ static int help(struct sk_buff **pskb,
                        ret = NF_ACCEPT;
                        goto out_put_expect;
                }
-               memcpy(&exp->tuple.dst.u3, &cmd.u3.all,
-                      sizeof(exp->tuple.dst.u3));
-       }
-
-       exp->tuple.src.u3 = ct->tuplehash[!dir].tuple.src.u3;
-       exp->tuple.src.l3num = cmd.l3num;
-       exp->tuple.src.u.tcp.port = 0;
-       exp->tuple.dst.u.tcp.port = cmd.u.tcp.port;
-       exp->tuple.dst.protonum = IPPROTO_TCP;
-
-       exp->mask = (struct nf_conntrack_tuple)
-                   { .src = { .l3num = 0xFFFF,
-                              .u = { .tcp = { 0 }},
-                            },
-                     .dst = { .protonum = 0xFF,
-                              .u = { .tcp = { __constant_htons(0xFFFF) }},
-                            },
-                   };
-       if (cmd.l3num == PF_INET) {
-               exp->mask.src.u3.ip = htonl(0xFFFFFFFF);
-               exp->mask.dst.u3.ip = htonl(0xFFFFFFFF);
-       } else {
-               memset(exp->mask.src.u3.ip6, 0xFF,
-                      sizeof(exp->mask.src.u3.ip6));
-               memset(exp->mask.dst.u3.ip6, 0xFF,
-                      sizeof(exp->mask.src.u3.ip6));
+               daddr = &cmd.u3;
        }
 
-       exp->expectfn = NULL;
-       exp->helper = NULL;
-       exp->flags = 0;
+       nf_ct_expect_init(exp, cmd.l3num,
+                         &ct->tuplehash[!dir].tuple.src.u3, daddr,
+                         IPPROTO_TCP, NULL, &cmd.u.tcp.port);
 
        /* Now, NAT might want to mangle the packet, and register the
         * (possibly changed) expectation itself. */
@@ -523,14 +495,14 @@ static int help(struct sk_buff **pskb,
                                 matchoff, matchlen, exp);
        else {
                /* Can't expect this?  Best to drop packet now. */
-               if (nf_conntrack_expect_related(exp) != 0)
+               if (nf_ct_expect_related(exp) != 0)
                        ret = NF_DROP;
                else
                        ret = NF_ACCEPT;
        }
 
 out_put_expect:
-       nf_conntrack_expect_put(exp);
+       nf_ct_expect_put(exp);
 
 out_update_nl:
        /* Now if this ends in \n, update ftp info.  Seq may have been
@@ -542,8 +514,8 @@ out_update_nl:
        return ret;
 }
 
-static struct nf_conntrack_helper ftp[MAX_PORTS][2];
-static char ftp_names[MAX_PORTS][2][sizeof("ftp-65535")];
+static struct nf_conntrack_helper ftp[MAX_PORTS][2] __read_mostly;
+static char ftp_names[MAX_PORTS][2][sizeof("ftp-65535")] __read_mostly;
 
 /* don't make this __exit, since it's called from __init ! */
 static void nf_conntrack_ftp_fini(void)
@@ -554,9 +526,9 @@ static void nf_conntrack_ftp_fini(void)
                        if (ftp[i][j].me == NULL)
                                continue;
 
-                       DEBUGP("nf_ct_ftp: unregistering helper for pf: %d "
-                              "port: %d\n",
-                               ftp[i][j].tuple.src.l3num, ports[i]);
+                       pr_debug("nf_ct_ftp: unregistering helper for pf: %d "
+                                "port: %d\n",
+                                ftp[i][j].tuple.src.l3num, ports[i]);
                        nf_conntrack_helper_unregister(&ftp[i][j]);
                }
        }
@@ -584,9 +556,6 @@ static int __init nf_conntrack_ftp_init(void)
                for (j = 0; j < 2; j++) {
                        ftp[i][j].tuple.src.u.tcp.port = htons(ports[i]);
                        ftp[i][j].tuple.dst.protonum = IPPROTO_TCP;
-                       ftp[i][j].mask.src.l3num = 0xFFFF;
-                       ftp[i][j].mask.src.u.tcp.port = htons(0xFFFF);
-                       ftp[i][j].mask.dst.protonum = 0xFF;
                        ftp[i][j].max_expected = 1;
                        ftp[i][j].timeout = 5 * 60;     /* 5 Minutes */
                        ftp[i][j].me = THIS_MODULE;
@@ -598,9 +567,9 @@ static int __init nf_conntrack_ftp_init(void)
                                sprintf(tmpname, "ftp-%d", ports[i]);
                        ftp[i][j].name = tmpname;
 
-                       DEBUGP("nf_ct_ftp: registering helper for pf: %d "
-                              "port: %d\n",
-                               ftp[i][j].tuple.src.l3num, ports[i]);
+                       pr_debug("nf_ct_ftp: registering helper for pf: %d "
+                                "port: %d\n",
+                                ftp[i][j].tuple.src.l3num, ports[i]);
                        ret = nf_conntrack_helper_register(&ftp[i][j]);
                        if (ret) {
                                printk("nf_ct_ftp: failed to register helper "
index 6b7eaa019d4c84883e62bf2cbce2e7d1afbe702b..a869403b229419562f6749b347b6ad7f8955e220 100644 (file)
@@ -555,15 +555,6 @@ int decode_seq(bitstr_t * bs, field_t * f, char *base, int level)
 
        /* Decode the extension components */
        for (opt = 0; opt < bmp2_len; opt++, i++, son++) {
-               if (i < f->ub && son->attr & STOP) {
-                       PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ",
-                             son->name);
-                       return H323_ERROR_STOP;
-               }
-
-               if (!((0x80000000 >> opt) & bmp2))      /* Not present */
-                       continue;
-
                /* Check Range */
                if (i >= f->ub) {       /* Newer Version? */
                        CHECK_BOUND(bs, 2);
@@ -573,6 +564,15 @@ int decode_seq(bitstr_t * bs, field_t * f, char *base, int level)
                        continue;
                }
 
+               if (son->attr & STOP) {
+                       PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ",
+                             son->name);
+                       return H323_ERROR_STOP;
+               }
+
+               if (!((0x80000000 >> opt) & bmp2))      /* Not present */
+                       continue;
+
                CHECK_BOUND(bs, 2);
                len = get_len(bs);
                CHECK_BOUND(bs, len);
index a1b95acad297471c0d65973a5a1678ebf648ceb4..a8a9dfbe7a67b6d6a0dce18293aaad11335de1ba 100644 (file)
 #include <net/netfilter/nf_conntrack_helper.h>
 #include <linux/netfilter/nf_conntrack_h323.h>
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 /* Parameters */
 static unsigned int default_rrq_ttl __read_mostly = 300;
 module_param(default_rrq_ttl, uint, 0600);
@@ -150,9 +144,9 @@ static int get_tpkt_data(struct sk_buff **pskb, unsigned int protoff,
                if (tcpdatalen < 4 || tpkt[0] != 0x03 || tpkt[1] != 0) {
                        /* Netmeeting sends TPKT header and data separately */
                        if (info->tpkt_len[dir] > 0) {
-                               DEBUGP("nf_ct_h323: previous packet "
-                                      "indicated separate TPKT data of %hu "
-                                      "bytes\n", info->tpkt_len[dir]);
+                               pr_debug("nf_ct_h323: previous packet "
+                                        "indicated separate TPKT data of %hu "
+                                        "bytes\n", info->tpkt_len[dir]);
                                if (info->tpkt_len[dir] <= tcpdatalen) {
                                        /* Yes, there was a TPKT header
                                         * received */
@@ -163,9 +157,7 @@ static int get_tpkt_data(struct sk_buff **pskb, unsigned int protoff,
                                }
 
                                /* Fragmented TPKT */
-                               if (net_ratelimit())
-                                       printk("nf_ct_h323: "
-                                              "fragmented TPKT\n");
+                               pr_debug("nf_ct_h323: fragmented TPKT\n");
                                goto clear_out;
                        }
 
@@ -192,9 +184,9 @@ static int get_tpkt_data(struct sk_buff **pskb, unsigned int protoff,
        if (tpktlen > tcpdatalen) {
                if (tcpdatalen == 4) {  /* Separate TPKT header */
                        /* Netmeeting sends TPKT header and data separately */
-                       DEBUGP("nf_ct_h323: separate TPKT header indicates "
-                              "there will be TPKT data of %hu bytes\n",
-                              tpktlen - 4);
+                       pr_debug("nf_ct_h323: separate TPKT header indicates "
+                                "there will be TPKT data of %hu bytes\n",
+                                tpktlen - 4);
                        info->tpkt_len[dir] = tpktlen - 4;
                        return 0;
                }
@@ -282,22 +274,22 @@ static int expect_rtp_rtcp(struct sk_buff **pskb, struct nf_conn *ct,
        rtcp_port = htons(ntohs(port) + 1);
 
        /* Create expect for RTP */
-       if ((rtp_exp = nf_conntrack_expect_alloc(ct)) == NULL)
+       if ((rtp_exp = nf_ct_expect_alloc(ct)) == NULL)
                return -1;
-       nf_conntrack_expect_init(rtp_exp, ct->tuplehash[!dir].tuple.src.l3num,
-                                &ct->tuplehash[!dir].tuple.src.u3,
-                                &ct->tuplehash[!dir].tuple.dst.u3,
-                                IPPROTO_UDP, NULL, &rtp_port);
+       nf_ct_expect_init(rtp_exp, ct->tuplehash[!dir].tuple.src.l3num,
+                         &ct->tuplehash[!dir].tuple.src.u3,
+                         &ct->tuplehash[!dir].tuple.dst.u3,
+                         IPPROTO_UDP, NULL, &rtp_port);
 
        /* Create expect for RTCP */
-       if ((rtcp_exp = nf_conntrack_expect_alloc(ct)) == NULL) {
-               nf_conntrack_expect_put(rtp_exp);
+       if ((rtcp_exp = nf_ct_expect_alloc(ct)) == NULL) {
+               nf_ct_expect_put(rtp_exp);
                return -1;
        }
-       nf_conntrack_expect_init(rtcp_exp, ct->tuplehash[!dir].tuple.src.l3num,
-                                &ct->tuplehash[!dir].tuple.src.u3,
-                                &ct->tuplehash[!dir].tuple.dst.u3,
-                                IPPROTO_UDP, NULL, &rtcp_port);
+       nf_ct_expect_init(rtcp_exp, ct->tuplehash[!dir].tuple.src.l3num,
+                         &ct->tuplehash[!dir].tuple.src.u3,
+                         &ct->tuplehash[!dir].tuple.dst.u3,
+                         IPPROTO_UDP, NULL, &rtcp_port);
 
        if (memcmp(&ct->tuplehash[dir].tuple.src.u3,
                   &ct->tuplehash[!dir].tuple.dst.u3,
@@ -308,22 +300,22 @@ static int expect_rtp_rtcp(struct sk_buff **pskb, struct nf_conn *ct,
                ret = nat_rtp_rtcp(pskb, ct, ctinfo, data, dataoff,
                                   taddr, port, rtp_port, rtp_exp, rtcp_exp);
        } else {                /* Conntrack only */
-               if (nf_conntrack_expect_related(rtp_exp) == 0) {
-                       if (nf_conntrack_expect_related(rtcp_exp) == 0) {
-                               DEBUGP("nf_ct_h323: expect RTP ");
+               if (nf_ct_expect_related(rtp_exp) == 0) {
+                       if (nf_ct_expect_related(rtcp_exp) == 0) {
+                               pr_debug("nf_ct_h323: expect RTP ");
                                NF_CT_DUMP_TUPLE(&rtp_exp->tuple);
-                               DEBUGP("nf_ct_h323: expect RTCP ");
+                               pr_debug("nf_ct_h323: expect RTCP ");
                                NF_CT_DUMP_TUPLE(&rtcp_exp->tuple);
                        } else {
-                               nf_conntrack_unexpect_related(rtp_exp);
+                               nf_ct_unexpect_related(rtp_exp);
                                ret = -1;
                        }
                } else
                        ret = -1;
        }
 
-       nf_conntrack_expect_put(rtp_exp);
-       nf_conntrack_expect_put(rtcp_exp);
+       nf_ct_expect_put(rtp_exp);
+       nf_ct_expect_put(rtcp_exp);
 
        return ret;
 }
@@ -349,12 +341,12 @@ static int expect_t120(struct sk_buff **pskb,
                return 0;
 
        /* Create expect for T.120 connections */
-       if ((exp = nf_conntrack_expect_alloc(ct)) == NULL)
+       if ((exp = nf_ct_expect_alloc(ct)) == NULL)
                return -1;
-       nf_conntrack_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
-                                &ct->tuplehash[!dir].tuple.src.u3,
-                                &ct->tuplehash[!dir].tuple.dst.u3,
-                                IPPROTO_TCP, NULL, &port);
+       nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
+                         &ct->tuplehash[!dir].tuple.src.u3,
+                         &ct->tuplehash[!dir].tuple.dst.u3,
+                         IPPROTO_TCP, NULL, &port);
        exp->flags = NF_CT_EXPECT_PERMANENT;    /* Accept multiple channels */
 
        if (memcmp(&ct->tuplehash[dir].tuple.src.u3,
@@ -366,14 +358,14 @@ static int expect_t120(struct sk_buff **pskb,
                ret = nat_t120(pskb, ct, ctinfo, data, dataoff, taddr,
                               port, exp);
        } else {                /* Conntrack only */
-               if (nf_conntrack_expect_related(exp) == 0) {
-                       DEBUGP("nf_ct_h323: expect T.120 ");
+               if (nf_ct_expect_related(exp) == 0) {
+                       pr_debug("nf_ct_h323: expect T.120 ");
                        NF_CT_DUMP_TUPLE(&exp->tuple);
                } else
                        ret = -1;
        }
 
-       nf_conntrack_expect_put(exp);
+       nf_ct_expect_put(exp);
 
        return ret;
 }
@@ -415,7 +407,7 @@ static int process_olc(struct sk_buff **pskb, struct nf_conn *ct,
 {
        int ret;
 
-       DEBUGP("nf_ct_h323: OpenLogicalChannel\n");
+       pr_debug("nf_ct_h323: OpenLogicalChannel\n");
 
        if (olc->forwardLogicalChannelParameters.multiplexParameters.choice ==
            eOpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters)
@@ -475,7 +467,7 @@ static int process_olca(struct sk_buff **pskb, struct nf_conn *ct,
        H2250LogicalChannelAckParameters *ack;
        int ret;
 
-       DEBUGP("nf_ct_h323: OpenLogicalChannelAck\n");
+       pr_debug("nf_ct_h323: OpenLogicalChannelAck\n");
 
        if ((olca->options &
             eOpenLogicalChannelAck_reverseLogicalChannelParameters) &&
@@ -546,8 +538,8 @@ static int process_h245(struct sk_buff **pskb, struct nf_conn *ct,
                        return process_olc(pskb, ct, ctinfo, data, dataoff,
                                           &mscm->request.openLogicalChannel);
                }
-               DEBUGP("nf_ct_h323: H.245 Request %d\n",
-                      mscm->request.choice);
+               pr_debug("nf_ct_h323: H.245 Request %d\n",
+                        mscm->request.choice);
                break;
        case eMultimediaSystemControlMessage_response:
                if (mscm->response.choice ==
@@ -556,11 +548,11 @@ static int process_h245(struct sk_buff **pskb, struct nf_conn *ct,
                                            &mscm->response.
                                            openLogicalChannelAck);
                }
-               DEBUGP("nf_ct_h323: H.245 Response %d\n",
-                      mscm->response.choice);
+               pr_debug("nf_ct_h323: H.245 Response %d\n",
+                        mscm->response.choice);
                break;
        default:
-               DEBUGP("nf_ct_h323: H.245 signal %d\n", mscm->choice);
+               pr_debug("nf_ct_h323: H.245 signal %d\n", mscm->choice);
                break;
        }
 
@@ -582,24 +574,23 @@ static int h245_help(struct sk_buff **pskb, unsigned int protoff,
            ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
                return NF_ACCEPT;
        }
-       DEBUGP("nf_ct_h245: skblen = %u\n", (*pskb)->len);
+       pr_debug("nf_ct_h245: skblen = %u\n", (*pskb)->len);
 
        spin_lock_bh(&nf_h323_lock);
 
        /* Process each TPKT */
        while (get_tpkt_data(pskb, protoff, ct, ctinfo,
                             &data, &datalen, &dataoff)) {
-               DEBUGP("nf_ct_h245: TPKT len=%d ", datalen);
+               pr_debug("nf_ct_h245: TPKT len=%d ", datalen);
                NF_CT_DUMP_TUPLE(&ct->tuplehash[CTINFO2DIR(ctinfo)].tuple);
 
                /* Decode H.245 signal */
                ret = DecodeMultimediaSystemControlMessage(data, datalen,
                                                           &mscm);
                if (ret < 0) {
-                       if (net_ratelimit())
-                               printk("nf_ct_h245: decoding error: %s\n",
-                                      ret == H323_ERROR_BOUND ?
-                                      "out of bound" : "out of range");
+                       pr_debug("nf_ct_h245: decoding error: %s\n",
+                                ret == H323_ERROR_BOUND ?
+                                "out of bound" : "out of range");
                        /* We don't drop when decoding error */
                        break;
                }
@@ -626,8 +617,6 @@ static struct nf_conntrack_helper nf_conntrack_helper_h245 __read_mostly = {
        .max_expected           = H323_RTP_CHANNEL_MAX * 4 + 2 /* T.120 */,
        .timeout                = 240,
        .tuple.dst.protonum     = IPPROTO_UDP,
-       .mask.src.u.udp.port    = __constant_htons(0xFFFF),
-       .mask.dst.protonum      = 0xFF,
        .help                   = h245_help
 };
 
@@ -684,12 +673,12 @@ static int expect_h245(struct sk_buff **pskb, struct nf_conn *ct,
                return 0;
 
        /* Create expect for h245 connection */
-       if ((exp = nf_conntrack_expect_alloc(ct)) == NULL)
+       if ((exp = nf_ct_expect_alloc(ct)) == NULL)
                return -1;
-       nf_conntrack_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
-                                &ct->tuplehash[!dir].tuple.src.u3,
-                                &ct->tuplehash[!dir].tuple.dst.u3,
-                                IPPROTO_TCP, NULL, &port);
+       nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
+                         &ct->tuplehash[!dir].tuple.src.u3,
+                         &ct->tuplehash[!dir].tuple.dst.u3,
+                         IPPROTO_TCP, NULL, &port);
        exp->helper = &nf_conntrack_helper_h245;
 
        if (memcmp(&ct->tuplehash[dir].tuple.src.u3,
@@ -701,14 +690,14 @@ static int expect_h245(struct sk_buff **pskb, struct nf_conn *ct,
                ret = nat_h245(pskb, ct, ctinfo, data, dataoff, taddr,
                               port, exp);
        } else {                /* Conntrack only */
-               if (nf_conntrack_expect_related(exp) == 0) {
-                       DEBUGP("nf_ct_q931: expect H.245 ");
+               if (nf_ct_expect_related(exp) == 0) {
+                       pr_debug("nf_ct_q931: expect H.245 ");
                        NF_CT_DUMP_TUPLE(&exp->tuple);
                } else
                        ret = -1;
        }
 
-       nf_conntrack_expect_put(exp);
+       nf_ct_expect_put(exp);
 
        return ret;
 }
@@ -791,16 +780,16 @@ static int expect_callforwarding(struct sk_buff **pskb,
        if (callforward_filter &&
            callforward_do_filter(&addr, &ct->tuplehash[!dir].tuple.src.u3,
                                  ct->tuplehash[!dir].tuple.src.l3num)) {
-               DEBUGP("nf_ct_q931: Call Forwarding not tracked\n");
+               pr_debug("nf_ct_q931: Call Forwarding not tracked\n");
                return 0;
        }
 
        /* Create expect for the second call leg */
-       if ((exp = nf_conntrack_expect_alloc(ct)) == NULL)
+       if ((exp = nf_ct_expect_alloc(ct)) == NULL)
                return -1;
-       nf_conntrack_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
-                                &ct->tuplehash[!dir].tuple.src.u3, &addr,
-                                IPPROTO_TCP, NULL, &port);
+       nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
+                         &ct->tuplehash[!dir].tuple.src.u3, &addr,
+                         IPPROTO_TCP, NULL, &port);
        exp->helper = nf_conntrack_helper_q931;
 
        if (memcmp(&ct->tuplehash[dir].tuple.src.u3,
@@ -812,14 +801,14 @@ static int expect_callforwarding(struct sk_buff **pskb,
                ret = nat_callforwarding(pskb, ct, ctinfo, data, dataoff,
                                         taddr, port, exp);
        } else {                /* Conntrack only */
-               if (nf_conntrack_expect_related(exp) == 0) {
-                       DEBUGP("nf_ct_q931: expect Call Forwarding ");
+               if (nf_ct_expect_related(exp) == 0) {
+                       pr_debug("nf_ct_q931: expect Call Forwarding ");
                        NF_CT_DUMP_TUPLE(&exp->tuple);
                } else
                        ret = -1;
        }
 
-       nf_conntrack_expect_put(exp);
+       nf_ct_expect_put(exp);
 
        return ret;
 }
@@ -837,7 +826,7 @@ static int process_setup(struct sk_buff **pskb, struct nf_conn *ct,
        union nf_conntrack_address addr;
        typeof(set_h225_addr_hook) set_h225_addr;
 
-       DEBUGP("nf_ct_q931: Setup\n");
+       pr_debug("nf_ct_q931: Setup\n");
 
        if (setup->options & eSetup_UUIE_h245Address) {
                ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
@@ -852,11 +841,11 @@ static int process_setup(struct sk_buff **pskb, struct nf_conn *ct,
            get_h225_addr(ct, *data, &setup->destCallSignalAddress,
                          &addr, &port) &&
            memcmp(&addr, &ct->tuplehash[!dir].tuple.src.u3, sizeof(addr))) {
-               DEBUGP("nf_ct_q931: set destCallSignalAddress "
-                      NIP6_FMT ":%hu->" NIP6_FMT ":%hu\n",
-                      NIP6(*(struct in6_addr *)&addr), ntohs(port),
-                      NIP6(*(struct in6_addr *)&ct->tuplehash[!dir].tuple.src.u3),
-                      ntohs(ct->tuplehash[!dir].tuple.src.u.tcp.port));
+               pr_debug("nf_ct_q931: set destCallSignalAddress "
+                        NIP6_FMT ":%hu->" NIP6_FMT ":%hu\n",
+                        NIP6(*(struct in6_addr *)&addr), ntohs(port),
+                        NIP6(*(struct in6_addr *)&ct->tuplehash[!dir].tuple.src.u3),
+                        ntohs(ct->tuplehash[!dir].tuple.src.u.tcp.port));
                ret = set_h225_addr(pskb, data, dataoff,
                                    &setup->destCallSignalAddress,
                                    &ct->tuplehash[!dir].tuple.src.u3,
@@ -870,11 +859,11 @@ static int process_setup(struct sk_buff **pskb, struct nf_conn *ct,
            get_h225_addr(ct, *data, &setup->sourceCallSignalAddress,
                          &addr, &port) &&
            memcmp(&addr, &ct->tuplehash[!dir].tuple.dst.u3, sizeof(addr))) {
-               DEBUGP("nf_ct_q931: set sourceCallSignalAddress "
-                      NIP6_FMT ":%hu->" NIP6_FMT ":%hu\n",
-                      NIP6(*(struct in6_addr *)&addr), ntohs(port),
-                      NIP6(*(struct in6_addr *)&ct->tuplehash[!dir].tuple.dst.u3),
-                      ntohs(ct->tuplehash[!dir].tuple.dst.u.tcp.port));
+               pr_debug("nf_ct_q931: set sourceCallSignalAddress "
+                        NIP6_FMT ":%hu->" NIP6_FMT ":%hu\n",
+                        NIP6(*(struct in6_addr *)&addr), ntohs(port),
+                        NIP6(*(struct in6_addr *)&ct->tuplehash[!dir].tuple.dst.u3),
+                        ntohs(ct->tuplehash[!dir].tuple.dst.u.tcp.port));
                ret = set_h225_addr(pskb, data, dataoff,
                                    &setup->sourceCallSignalAddress,
                                    &ct->tuplehash[!dir].tuple.dst.u3,
@@ -905,7 +894,7 @@ static int process_callproceeding(struct sk_buff **pskb,
        int ret;
        int i;
 
-       DEBUGP("nf_ct_q931: CallProceeding\n");
+       pr_debug("nf_ct_q931: CallProceeding\n");
 
        if (callproc->options & eCallProceeding_UUIE_h245Address) {
                ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
@@ -935,7 +924,7 @@ static int process_connect(struct sk_buff **pskb, struct nf_conn *ct,
        int ret;
        int i;
 
-       DEBUGP("nf_ct_q931: Connect\n");
+       pr_debug("nf_ct_q931: Connect\n");
 
        if (connect->options & eConnect_UUIE_h245Address) {
                ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
@@ -965,7 +954,7 @@ static int process_alerting(struct sk_buff **pskb, struct nf_conn *ct,
        int ret;
        int i;
 
-       DEBUGP("nf_ct_q931: Alerting\n");
+       pr_debug("nf_ct_q931: Alerting\n");
 
        if (alert->options & eAlerting_UUIE_h245Address) {
                ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
@@ -995,7 +984,7 @@ static int process_facility(struct sk_buff **pskb, struct nf_conn *ct,
        int ret;
        int i;
 
-       DEBUGP("nf_ct_q931: Facility\n");
+       pr_debug("nf_ct_q931: Facility\n");
 
        if (facility->reason.choice == eFacilityReason_callForwarded) {
                if (facility->options & eFacility_UUIE_alternativeAddress)
@@ -1034,7 +1023,7 @@ static int process_progress(struct sk_buff **pskb, struct nf_conn *ct,
        int ret;
        int i;
 
-       DEBUGP("nf_ct_q931: Progress\n");
+       pr_debug("nf_ct_q931: Progress\n");
 
        if (progress->options & eProgress_UUIE_h245Address) {
                ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
@@ -1091,8 +1080,8 @@ static int process_q931(struct sk_buff **pskb, struct nf_conn *ct,
                                       &pdu->h323_message_body.progress);
                break;
        default:
-               DEBUGP("nf_ct_q931: Q.931 signal %d\n",
-                      pdu->h323_message_body.choice);
+               pr_debug("nf_ct_q931: Q.931 signal %d\n",
+                        pdu->h323_message_body.choice);
                break;
        }
 
@@ -1126,23 +1115,22 @@ static int q931_help(struct sk_buff **pskb, unsigned int protoff,
            ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
                return NF_ACCEPT;
        }
-       DEBUGP("nf_ct_q931: skblen = %u\n", (*pskb)->len);
+       pr_debug("nf_ct_q931: skblen = %u\n", (*pskb)->len);
 
        spin_lock_bh(&nf_h323_lock);
 
        /* Process each TPKT */
        while (get_tpkt_data(pskb, protoff, ct, ctinfo,
                             &data, &datalen, &dataoff)) {
-               DEBUGP("nf_ct_q931: TPKT len=%d ", datalen);
+               pr_debug("nf_ct_q931: TPKT len=%d ", datalen);
                NF_CT_DUMP_TUPLE(&ct->tuplehash[CTINFO2DIR(ctinfo)].tuple);
 
                /* Decode Q.931 signal */
                ret = DecodeQ931(data, datalen, &q931);
                if (ret < 0) {
-                       if (net_ratelimit())
-                               printk("nf_ct_q931: decoding error: %s\n",
-                                      ret == H323_ERROR_BOUND ?
-                                      "out of bound" : "out of range");
+                       pr_debug("nf_ct_q931: decoding error: %s\n",
+                                ret == H323_ERROR_BOUND ?
+                                "out of bound" : "out of range");
                        /* We don't drop when decoding error */
                        break;
                }
@@ -1173,9 +1161,6 @@ static struct nf_conntrack_helper nf_conntrack_helper_q931[] __read_mostly = {
                .tuple.src.l3num        = AF_INET,
                .tuple.src.u.tcp.port   = __constant_htons(Q931_PORT),
                .tuple.dst.protonum     = IPPROTO_TCP,
-               .mask.src.l3num         = 0xFFFF,
-               .mask.src.u.tcp.port    = __constant_htons(0xFFFF),
-               .mask.dst.protonum      = 0xFF,
                .help                   = q931_help
        },
        {
@@ -1187,9 +1172,6 @@ static struct nf_conntrack_helper nf_conntrack_helper_q931[] __read_mostly = {
                .tuple.src.l3num        = AF_INET6,
                .tuple.src.u.tcp.port   = __constant_htons(Q931_PORT),
                .tuple.dst.protonum     = IPPROTO_TCP,
-               .mask.src.l3num         = 0xFFFF,
-               .mask.src.u.tcp.port    = __constant_htons(0xFFFF),
-               .mask.dst.protonum      = 0xFF,
                .help                   = q931_help
        },
 };
@@ -1225,7 +1207,7 @@ static struct nf_conntrack_expect *find_expect(struct nf_conn *ct,
        tuple.dst.u.tcp.port = port;
        tuple.dst.protonum = IPPROTO_TCP;
 
-       exp = __nf_conntrack_expect_find(&tuple);
+       exp = __nf_ct_expect_find(&tuple);
        if (exp && exp->master == ct)
                return exp;
        return NULL;
@@ -1271,14 +1253,13 @@ static int expect_q931(struct sk_buff **pskb, struct nf_conn *ct,
                return 0;
 
        /* Create expect for Q.931 */
-       if ((exp = nf_conntrack_expect_alloc(ct)) == NULL)
+       if ((exp = nf_ct_expect_alloc(ct)) == NULL)
                return -1;
-       nf_conntrack_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
-                                gkrouted_only ? /* only accept calls from GK? */
-                                       &ct->tuplehash[!dir].tuple.src.u3 :
-                                       NULL,
-                                &ct->tuplehash[!dir].tuple.dst.u3,
-                                IPPROTO_TCP, NULL, &port);
+       nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
+                         gkrouted_only ? /* only accept calls from GK? */
+                               &ct->tuplehash[!dir].tuple.src.u3 : NULL,
+                         &ct->tuplehash[!dir].tuple.dst.u3,
+                         IPPROTO_TCP, NULL, &port);
        exp->helper = nf_conntrack_helper_q931;
        exp->flags = NF_CT_EXPECT_PERMANENT;    /* Accept multiple calls */
 
@@ -1286,8 +1267,8 @@ static int expect_q931(struct sk_buff **pskb, struct nf_conn *ct,
        if (nat_q931 && ct->status & IPS_NAT_MASK) {    /* Need NAT */
                ret = nat_q931(pskb, ct, ctinfo, data, taddr, i, port, exp);
        } else {                /* Conntrack only */
-               if (nf_conntrack_expect_related(exp) == 0) {
-                       DEBUGP("nf_ct_ras: expect Q.931 ");
+               if (nf_ct_expect_related(exp) == 0) {
+                       pr_debug("nf_ct_ras: expect Q.931 ");
                        NF_CT_DUMP_TUPLE(&exp->tuple);
 
                        /* Save port for looking up expect in processing RCF */
@@ -1296,7 +1277,7 @@ static int expect_q931(struct sk_buff **pskb, struct nf_conn *ct,
                        ret = -1;
        }
 
-       nf_conntrack_expect_put(exp);
+       nf_ct_expect_put(exp);
 
        return ret;
 }
@@ -1308,7 +1289,7 @@ static int process_grq(struct sk_buff **pskb, struct nf_conn *ct,
 {
        typeof(set_ras_addr_hook) set_ras_addr;
 
-       DEBUGP("nf_ct_ras: GRQ\n");
+       pr_debug("nf_ct_ras: GRQ\n");
 
        set_ras_addr = rcu_dereference(set_ras_addr_hook);
        if (set_ras_addr && ct->status & IPS_NAT_MASK)  /* NATed */
@@ -1328,7 +1309,7 @@ static int process_gcf(struct sk_buff **pskb, struct nf_conn *ct,
        union nf_conntrack_address addr;
        struct nf_conntrack_expect *exp;
 
-       DEBUGP("nf_ct_ras: GCF\n");
+       pr_debug("nf_ct_ras: GCF\n");
 
        if (!get_h225_addr(ct, *data, &gcf->rasAddress, &addr, &port))
                return 0;
@@ -1343,20 +1324,20 @@ static int process_gcf(struct sk_buff **pskb, struct nf_conn *ct,
                return 0;
 
        /* Need new expect */
-       if ((exp = nf_conntrack_expect_alloc(ct)) == NULL)
+       if ((exp = nf_ct_expect_alloc(ct)) == NULL)
                return -1;
-       nf_conntrack_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
-                                &ct->tuplehash[!dir].tuple.src.u3, &addr,
-                                IPPROTO_UDP, NULL, &port);
+       nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
+                         &ct->tuplehash[!dir].tuple.src.u3, &addr,
+                         IPPROTO_UDP, NULL, &port);
        exp->helper = nf_conntrack_helper_ras;
 
-       if (nf_conntrack_expect_related(exp) == 0) {
-               DEBUGP("nf_ct_ras: expect RAS ");
+       if (nf_ct_expect_related(exp) == 0) {
+               pr_debug("nf_ct_ras: expect RAS ");
                NF_CT_DUMP_TUPLE(&exp->tuple);
        } else
                ret = -1;
 
-       nf_conntrack_expect_put(exp);
+       nf_ct_expect_put(exp);
 
        return ret;
 }
@@ -1370,7 +1351,7 @@ static int process_rrq(struct sk_buff **pskb, struct nf_conn *ct,
        int ret;
        typeof(set_ras_addr_hook) set_ras_addr;
 
-       DEBUGP("nf_ct_ras: RRQ\n");
+       pr_debug("nf_ct_ras: RRQ\n");
 
        ret = expect_q931(pskb, ct, ctinfo, data,
                          rrq->callSignalAddress.item,
@@ -1388,7 +1369,7 @@ static int process_rrq(struct sk_buff **pskb, struct nf_conn *ct,
        }
 
        if (rrq->options & eRegistrationRequest_timeToLive) {
-               DEBUGP("nf_ct_ras: RRQ TTL = %u seconds\n", rrq->timeToLive);
+               pr_debug("nf_ct_ras: RRQ TTL = %u seconds\n", rrq->timeToLive);
                info->timeout = rrq->timeToLive;
        } else
                info->timeout = default_rrq_ttl;
@@ -1407,7 +1388,7 @@ static int process_rcf(struct sk_buff **pskb, struct nf_conn *ct,
        struct nf_conntrack_expect *exp;
        typeof(set_sig_addr_hook) set_sig_addr;
 
-       DEBUGP("nf_ct_ras: RCF\n");
+       pr_debug("nf_ct_ras: RCF\n");
 
        set_sig_addr = rcu_dereference(set_sig_addr_hook);
        if (set_sig_addr && ct->status & IPS_NAT_MASK) {
@@ -1419,14 +1400,13 @@ static int process_rcf(struct sk_buff **pskb, struct nf_conn *ct,
        }
 
        if (rcf->options & eRegistrationConfirm_timeToLive) {
-               DEBUGP("nf_ct_ras: RCF TTL = %u seconds\n", rcf->timeToLive);
+               pr_debug("nf_ct_ras: RCF TTL = %u seconds\n", rcf->timeToLive);
                info->timeout = rcf->timeToLive;
        }
 
        if (info->timeout > 0) {
-               DEBUGP
-                   ("nf_ct_ras: set RAS connection timeout to %u seconds\n",
-                    info->timeout);
+               pr_debug("nf_ct_ras: set RAS connection timeout to "
+                        "%u seconds\n", info->timeout);
                nf_ct_refresh(ct, *pskb, info->timeout * HZ);
 
                /* Set expect timeout */
@@ -1434,9 +1414,9 @@ static int process_rcf(struct sk_buff **pskb, struct nf_conn *ct,
                exp = find_expect(ct, &ct->tuplehash[dir].tuple.dst.u3,
                                  info->sig_port[!dir]);
                if (exp) {
-                       DEBUGP("nf_ct_ras: set Q.931 expect "
-                              "timeout to %u seconds for",
-                              info->timeout);
+                       pr_debug("nf_ct_ras: set Q.931 expect "
+                                "timeout to %u seconds for",
+                                info->timeout);
                        NF_CT_DUMP_TUPLE(&exp->tuple);
                        set_expect_timeout(exp, info->timeout);
                }
@@ -1456,7 +1436,7 @@ static int process_urq(struct sk_buff **pskb, struct nf_conn *ct,
        int ret;
        typeof(set_sig_addr_hook) set_sig_addr;
 
-       DEBUGP("nf_ct_ras: URQ\n");
+       pr_debug("nf_ct_ras: URQ\n");
 
        set_sig_addr = rcu_dereference(set_sig_addr_hook);
        if (set_sig_addr && ct->status & IPS_NAT_MASK) {
@@ -1489,7 +1469,7 @@ static int process_arq(struct sk_buff **pskb, struct nf_conn *ct,
        union nf_conntrack_address addr;
        typeof(set_h225_addr_hook) set_h225_addr;
 
-       DEBUGP("nf_ct_ras: ARQ\n");
+       pr_debug("nf_ct_ras: ARQ\n");
 
        set_h225_addr = rcu_dereference(set_h225_addr_hook);
        if ((arq->options & eAdmissionRequest_destCallSignalAddress) &&
@@ -1532,7 +1512,7 @@ static int process_acf(struct sk_buff **pskb, struct nf_conn *ct,
        struct nf_conntrack_expect *exp;
        typeof(set_sig_addr_hook) set_sig_addr;
 
-       DEBUGP("nf_ct_ras: ACF\n");
+       pr_debug("nf_ct_ras: ACF\n");
 
        if (!get_h225_addr(ct, *data, &acf->destCallSignalAddress,
                           &addr, &port))
@@ -1548,21 +1528,21 @@ static int process_acf(struct sk_buff **pskb, struct nf_conn *ct,
        }
 
        /* Need new expect */
-       if ((exp = nf_conntrack_expect_alloc(ct)) == NULL)
+       if ((exp = nf_ct_expect_alloc(ct)) == NULL)
                return -1;
-       nf_conntrack_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
-                                &ct->tuplehash[!dir].tuple.src.u3, &addr,
-                                IPPROTO_TCP, NULL, &port);
+       nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
+                         &ct->tuplehash[!dir].tuple.src.u3, &addr,
+                         IPPROTO_TCP, NULL, &port);
        exp->flags = NF_CT_EXPECT_PERMANENT;
        exp->helper = nf_conntrack_helper_q931;
 
-       if (nf_conntrack_expect_related(exp) == 0) {
-               DEBUGP("nf_ct_ras: expect Q.931 ");
+       if (nf_ct_expect_related(exp) == 0) {
+               pr_debug("nf_ct_ras: expect Q.931 ");
                NF_CT_DUMP_TUPLE(&exp->tuple);
        } else
                ret = -1;
 
-       nf_conntrack_expect_put(exp);
+       nf_ct_expect_put(exp);
 
        return ret;
 }
@@ -1574,7 +1554,7 @@ static int process_lrq(struct sk_buff **pskb, struct nf_conn *ct,
 {
        typeof(set_ras_addr_hook) set_ras_addr;
 
-       DEBUGP("nf_ct_ras: LRQ\n");
+       pr_debug("nf_ct_ras: LRQ\n");
 
        set_ras_addr = rcu_dereference(set_ras_addr_hook);
        if (set_ras_addr && ct->status & IPS_NAT_MASK)
@@ -1594,28 +1574,28 @@ static int process_lcf(struct sk_buff **pskb, struct nf_conn *ct,
        union nf_conntrack_address addr;
        struct nf_conntrack_expect *exp;
 
-       DEBUGP("nf_ct_ras: LCF\n");
+       pr_debug("nf_ct_ras: LCF\n");
 
        if (!get_h225_addr(ct, *data, &lcf->callSignalAddress,
                           &addr, &port))
                return 0;
 
        /* Need new expect for call signal */
-       if ((exp = nf_conntrack_expect_alloc(ct)) == NULL)
+       if ((exp = nf_ct_expect_alloc(ct)) == NULL)
                return -1;
-       nf_conntrack_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
-                                &ct->tuplehash[!dir].tuple.src.u3, &addr,
-                                IPPROTO_TCP, NULL, &port);
+       nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
+                         &ct->tuplehash[!dir].tuple.src.u3, &addr,
+                         IPPROTO_TCP, NULL, &port);
        exp->flags = NF_CT_EXPECT_PERMANENT;
        exp->helper = nf_conntrack_helper_q931;
 
-       if (nf_conntrack_expect_related(exp) == 0) {
-               DEBUGP("nf_ct_ras: expect Q.931 ");
+       if (nf_ct_expect_related(exp) == 0) {
+               pr_debug("nf_ct_ras: expect Q.931 ");
                NF_CT_DUMP_TUPLE(&exp->tuple);
        } else
                ret = -1;
 
-       nf_conntrack_expect_put(exp);
+       nf_ct_expect_put(exp);
 
        /* Ignore rasAddress */
 
@@ -1631,7 +1611,7 @@ static int process_irr(struct sk_buff **pskb, struct nf_conn *ct,
        typeof(set_ras_addr_hook) set_ras_addr;
        typeof(set_sig_addr_hook) set_sig_addr;
 
-       DEBUGP("nf_ct_ras: IRR\n");
+       pr_debug("nf_ct_ras: IRR\n");
 
        set_ras_addr = rcu_dereference(set_ras_addr_hook);
        if (set_ras_addr && ct->status & IPS_NAT_MASK) {
@@ -1690,7 +1670,7 @@ static int process_ras(struct sk_buff **pskb, struct nf_conn *ct,
                return process_irr(pskb, ct, ctinfo, data,
                                   &ras->infoRequestResponse);
        default:
-               DEBUGP("nf_ct_ras: RAS message %d\n", ras->choice);
+               pr_debug("nf_ct_ras: RAS message %d\n", ras->choice);
                break;
        }
 
@@ -1706,7 +1686,7 @@ static int ras_help(struct sk_buff **pskb, unsigned int protoff,
        int datalen = 0;
        int ret;
 
-       DEBUGP("nf_ct_ras: skblen = %u\n", (*pskb)->len);
+       pr_debug("nf_ct_ras: skblen = %u\n", (*pskb)->len);
 
        spin_lock_bh(&nf_h323_lock);
 
@@ -1714,16 +1694,15 @@ static int ras_help(struct sk_buff **pskb, unsigned int protoff,
        data = get_udp_data(pskb, protoff, &datalen);
        if (data == NULL)
                goto accept;
-       DEBUGP("nf_ct_ras: RAS message len=%d ", datalen);
+       pr_debug("nf_ct_ras: RAS message len=%d ", datalen);
        NF_CT_DUMP_TUPLE(&ct->tuplehash[CTINFO2DIR(ctinfo)].tuple);
 
        /* Decode RAS message */
        ret = DecodeRasMessage(data, datalen, &ras);
        if (ret < 0) {
-               if (net_ratelimit())
-                       printk("nf_ct_ras: decoding error: %s\n",
-                              ret == H323_ERROR_BOUND ?
-                              "out of bound" : "out of range");
+               pr_debug("nf_ct_ras: decoding error: %s\n",
+                        ret == H323_ERROR_BOUND ?
+                        "out of bound" : "out of range");
                goto accept;
        }
 
@@ -1752,9 +1731,6 @@ static struct nf_conntrack_helper nf_conntrack_helper_ras[] __read_mostly = {
                .tuple.src.l3num        = AF_INET,
                .tuple.src.u.udp.port   = __constant_htons(RAS_PORT),
                .tuple.dst.protonum     = IPPROTO_UDP,
-               .mask.src.l3num         = 0xFFFF,
-               .mask.src.u.udp.port    = __constant_htons(0xFFFF),
-               .mask.dst.protonum      = 0xFF,
                .help                   = ras_help,
        },
        {
@@ -1765,9 +1741,6 @@ static struct nf_conntrack_helper nf_conntrack_helper_ras[] __read_mostly = {
                .tuple.src.l3num        = AF_INET6,
                .tuple.src.u.udp.port   = __constant_htons(RAS_PORT),
                .tuple.dst.protonum     = IPPROTO_UDP,
-               .mask.src.l3num         = 0xFFFF,
-               .mask.src.u.udp.port    = __constant_htons(0xFFFF),
-               .mask.dst.protonum      = 0xFF,
                .help                   = ras_help,
        },
 };
@@ -1780,7 +1753,7 @@ static void __exit nf_conntrack_h323_fini(void)
        nf_conntrack_helper_unregister(&nf_conntrack_helper_q931[1]);
        nf_conntrack_helper_unregister(&nf_conntrack_helper_q931[0]);
        kfree(h323_buffer);
-       DEBUGP("nf_ct_h323: fini\n");
+       pr_debug("nf_ct_h323: fini\n");
 }
 
 /****************************************************************************/
@@ -1803,7 +1776,7 @@ static int __init nf_conntrack_h323_init(void)
        ret = nf_conntrack_helper_register(&nf_conntrack_helper_ras[1]);
        if (ret < 0)
                goto err4;
-       DEBUGP("nf_ct_h323: init success\n");
+       pr_debug("nf_ct_h323: init success\n");
        return 0;
 
 err4:
index f868b7fbd9b4caee49d1e49b560ff6daeaa185bf..b1179dd3d8c30cb6eabce77b7b501b36c4a918c3 100644 (file)
 #include <net/netfilter/nf_conntrack_l4proto.h>
 #include <net/netfilter/nf_conntrack_helper.h>
 #include <net/netfilter/nf_conntrack_core.h>
+#include <net/netfilter/nf_conntrack_extend.h>
 
-static __read_mostly LIST_HEAD(helpers);
+static struct hlist_head *nf_ct_helper_hash __read_mostly;
+static unsigned int nf_ct_helper_hsize __read_mostly;
+static unsigned int nf_ct_helper_count __read_mostly;
+static int nf_ct_helper_vmalloc;
+
+
+/* Stupid hash, but collision free for the default registrations of the
+ * helpers currently in the kernel. */
+static unsigned int helper_hash(const struct nf_conntrack_tuple *tuple)
+{
+       return (((tuple->src.l3num << 8) | tuple->dst.protonum) ^
+               tuple->src.u.all) % nf_ct_helper_hsize;
+}
 
 struct nf_conntrack_helper *
 __nf_ct_helper_find(const struct nf_conntrack_tuple *tuple)
 {
-       struct nf_conntrack_helper *h;
+       struct nf_conntrack_helper *helper;
+       struct nf_conntrack_tuple_mask mask = { .src.u.all = htons(0xFFFF) };
+       struct hlist_node *n;
+       unsigned int h;
+
+       if (!nf_ct_helper_count)
+               return NULL;
 
-       list_for_each_entry(h, &helpers, list) {
-               if (nf_ct_tuple_mask_cmp(tuple, &h->tuple, &h->mask))
-                       return h;
+       h = helper_hash(tuple);
+       hlist_for_each_entry(helper, n, &nf_ct_helper_hash[h], hnode) {
+               if (nf_ct_tuple_src_mask_cmp(tuple, &helper->tuple, &mask))
+                       return helper;
        }
        return NULL;
 }
 
 struct nf_conntrack_helper *
-nf_ct_helper_find_get( const struct nf_conntrack_tuple *tuple)
+nf_ct_helper_find_get(const struct nf_conntrack_tuple *tuple)
 {
        struct nf_conntrack_helper *helper;
 
@@ -75,16 +95,32 @@ struct nf_conntrack_helper *
 __nf_conntrack_helper_find_byname(const char *name)
 {
        struct nf_conntrack_helper *h;
+       struct hlist_node *n;
+       unsigned int i;
 
-       list_for_each_entry(h, &helpers, list) {
-               if (!strcmp(h->name, name))
-                       return h;
+       for (i = 0; i < nf_ct_helper_hsize; i++) {
+               hlist_for_each_entry(h, n, &nf_ct_helper_hash[i], hnode) {
+                       if (!strcmp(h->name, name))
+                               return h;
+               }
        }
-
        return NULL;
 }
 EXPORT_SYMBOL_GPL(__nf_conntrack_helper_find_byname);
 
+struct nf_conn_help *nf_ct_helper_ext_add(struct nf_conn *ct, gfp_t gfp)
+{
+       struct nf_conn_help *help;
+
+       help = nf_ct_ext_add(ct, NF_CT_EXT_HELPER, gfp);
+       if (help)
+               INIT_HLIST_HEAD(&help->expectations);
+       else
+               pr_debug("failed to add helper extension area");
+       return help;
+}
+EXPORT_SYMBOL_GPL(nf_ct_helper_ext_add);
+
 static inline int unhelp(struct nf_conntrack_tuple_hash *i,
                         const struct nf_conntrack_helper *me)
 {
@@ -100,20 +136,13 @@ static inline int unhelp(struct nf_conntrack_tuple_hash *i,
 
 int nf_conntrack_helper_register(struct nf_conntrack_helper *me)
 {
-       int size, ret;
+       unsigned int h = helper_hash(&me->tuple);
 
        BUG_ON(me->timeout == 0);
 
-       size = ALIGN(sizeof(struct nf_conn), __alignof__(struct nf_conn_help)) +
-              sizeof(struct nf_conn_help);
-       ret = nf_conntrack_register_cache(NF_CT_F_HELP, "nf_conntrack:help",
-                                         size);
-       if (ret < 0) {
-               printk(KERN_ERR "nf_conntrack_helper_register: Unable to create slab cache for conntracks\n");
-               return ret;
-       }
        write_lock_bh(&nf_conntrack_lock);
-       list_add(&me->list, &helpers);
+       hlist_add_head(&me->hnode, &nf_ct_helper_hash[h]);
+       nf_ct_helper_count++;
        write_unlock_bh(&nf_conntrack_lock);
 
        return 0;
@@ -122,29 +151,34 @@ EXPORT_SYMBOL_GPL(nf_conntrack_helper_register);
 
 void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
 {
-       unsigned int i;
        struct nf_conntrack_tuple_hash *h;
-       struct nf_conntrack_expect *exp, *tmp;
+       struct nf_conntrack_expect *exp;
+       struct hlist_node *n, *next;
+       unsigned int i;
 
        /* Need write lock here, to delete helper. */
        write_lock_bh(&nf_conntrack_lock);
-       list_del(&me->list);
+       hlist_del(&me->hnode);
+       nf_ct_helper_count--;
 
        /* Get rid of expectations */
-       list_for_each_entry_safe(exp, tmp, &nf_conntrack_expect_list, list) {
-               struct nf_conn_help *help = nfct_help(exp->master);
-               if ((help->helper == me || exp->helper == me) &&
-                   del_timer(&exp->timeout)) {
-                       nf_ct_unlink_expect(exp);
-                       nf_conntrack_expect_put(exp);
+       for (i = 0; i < nf_ct_expect_hsize; i++) {
+               hlist_for_each_entry_safe(exp, n, next,
+                                         &nf_ct_expect_hash[i], hnode) {
+                       struct nf_conn_help *help = nfct_help(exp->master);
+                       if ((help->helper == me || exp->helper == me) &&
+                           del_timer(&exp->timeout)) {
+                               nf_ct_unlink_expect(exp);
+                               nf_ct_expect_put(exp);
+                       }
                }
        }
 
        /* Get rid of expecteds, set helpers to NULL. */
-       list_for_each_entry(h, &unconfirmed, list)
+       hlist_for_each_entry(h, n, &unconfirmed, hnode)
                unhelp(h, me);
        for (i = 0; i < nf_conntrack_htable_size; i++) {
-               list_for_each_entry(h, &nf_conntrack_hash[i], list)
+               hlist_for_each_entry(h, n, &nf_conntrack_hash[i], hnode)
                        unhelp(h, me);
        }
        write_unlock_bh(&nf_conntrack_lock);
@@ -153,3 +187,38 @@ void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
        synchronize_net();
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_helper_unregister);
+
+static struct nf_ct_ext_type helper_extend __read_mostly = {
+       .len    = sizeof(struct nf_conn_help),
+       .align  = __alignof__(struct nf_conn_help),
+       .id     = NF_CT_EXT_HELPER,
+};
+
+int nf_conntrack_helper_init()
+{
+       int err;
+
+       nf_ct_helper_hsize = 1; /* gets rounded up to use one page */
+       nf_ct_helper_hash = nf_ct_alloc_hashtable(&nf_ct_helper_hsize,
+                                                 &nf_ct_helper_vmalloc);
+       if (!nf_ct_helper_hash)
+               return -ENOMEM;
+
+       err = nf_ct_extend_register(&helper_extend);
+       if (err < 0)
+               goto err1;
+
+       return 0;
+
+err1:
+       nf_ct_free_hashtable(nf_ct_helper_hash, nf_ct_helper_vmalloc,
+                            nf_ct_helper_hsize);
+       return err;
+}
+
+void nf_conntrack_helper_fini()
+{
+       nf_ct_extend_unregister(&helper_extend);
+       nf_ct_free_hashtable(nf_ct_helper_hash, nf_ct_helper_vmalloc,
+                            nf_ct_helper_hsize);
+}
index 43ccd0e2e8aebbd2c93da46b21615c2a19c4d1ff..1562ca97a349f14dc742181144aa98a6cb6d149c 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/moduleparam.h>
 #include <linux/skbuff.h>
 #include <linux/in.h>
+#include <linux/ip.h>
 #include <linux/tcp.h>
 #include <linux/netfilter.h>
 
@@ -55,13 +56,6 @@ static const char *dccprotos[] = {
 
 #define MINMATCHLEN    5
 
-#if 0
-#define DEBUGP(format, args...) printk(KERN_DEBUG "%s:%s:" format, \
-                                      __FILE__, __FUNCTION__ , ## args)
-#else
-#define DEBUGP(format, args...)
-#endif
-
 /* tries to get the ip_addr and port out of a dcc command
  * return value: -1 on failure, 0 on success
  *     data            pointer to first byte of DCC command data
@@ -99,6 +93,7 @@ static int help(struct sk_buff **pskb, unsigned int protoff,
                struct nf_conn *ct, enum ip_conntrack_info ctinfo)
 {
        unsigned int dataoff;
+       struct iphdr *iph;
        struct tcphdr _tcph, *th;
        char *data, *data_limit, *ib_ptr;
        int dir = CTINFO2DIR(ctinfo);
@@ -148,9 +143,10 @@ static int help(struct sk_buff **pskb, unsigned int protoff,
                data += 5;
                /* we have at least (19+MINMATCHLEN)-5 bytes valid data left */
 
-               DEBUGP("DCC found in master %u.%u.%u.%u:%u %u.%u.%u.%u:%u...\n",
-                       NIPQUAD(iph->saddr), ntohs(th->source),
-                       NIPQUAD(iph->daddr), ntohs(th->dest));
+               iph = ip_hdr(*pskb);
+               pr_debug("DCC found in master %u.%u.%u.%u:%u %u.%u.%u.%u:%u\n",
+                        NIPQUAD(iph->saddr), ntohs(th->source),
+                        NIPQUAD(iph->daddr), ntohs(th->dest));
 
                for (i = 0; i < ARRAY_SIZE(dccprotos); i++) {
                        if (memcmp(data, dccprotos[i], strlen(dccprotos[i]))) {
@@ -158,18 +154,18 @@ static int help(struct sk_buff **pskb, unsigned int protoff,
                                continue;
                        }
                        data += strlen(dccprotos[i]);
-                       DEBUGP("DCC %s detected\n", dccprotos[i]);
+                       pr_debug("DCC %s detected\n", dccprotos[i]);
 
                        /* we have at least
                         * (19+MINMATCHLEN)-5-dccprotos[i].matchlen bytes valid
                         * data left (== 14/13 bytes) */
                        if (parse_dcc((char *)data, data_limit, &dcc_ip,
                                       &dcc_port, &addr_beg_p, &addr_end_p)) {
-                               DEBUGP("unable to parse dcc command\n");
+                               pr_debug("unable to parse dcc command\n");
                                continue;
                        }
-                       DEBUGP("DCC bound ip/port: %u.%u.%u.%u:%u\n",
-                               HIPQUAD(dcc_ip), dcc_port);
+                       pr_debug("DCC bound ip/port: %u.%u.%u.%u:%u\n",
+                                HIPQUAD(dcc_ip), dcc_port);
 
                        /* dcc_ip can be the internal OR external (NAT'ed) IP */
                        tuple = &ct->tuplehash[dir].tuple;
@@ -184,16 +180,16 @@ static int help(struct sk_buff **pskb, unsigned int protoff,
                                continue;
                        }
 
-                       exp = nf_conntrack_expect_alloc(ct);
+                       exp = nf_ct_expect_alloc(ct);
                        if (exp == NULL) {
                                ret = NF_DROP;
                                goto out;
                        }
                        tuple = &ct->tuplehash[!dir].tuple;
                        port = htons(dcc_port);
-                       nf_conntrack_expect_init(exp, tuple->src.l3num,
-                                                NULL, &tuple->dst.u3,
-                                                IPPROTO_TCP, NULL, &port);
+                       nf_ct_expect_init(exp, tuple->src.l3num,
+                                         NULL, &tuple->dst.u3,
+                                         IPPROTO_TCP, NULL, &port);
 
                        nf_nat_irc = rcu_dereference(nf_nat_irc_hook);
                        if (nf_nat_irc && ct->status & IPS_NAT_MASK)
@@ -201,9 +197,9 @@ static int help(struct sk_buff **pskb, unsigned int protoff,
                                                 addr_beg_p - ib_ptr,
                                                 addr_end_p - addr_beg_p,
                                                 exp);
-                       else if (nf_conntrack_expect_related(exp) != 0)
+                       else if (nf_ct_expect_related(exp) != 0)
                                ret = NF_DROP;
-                       nf_conntrack_expect_put(exp);
+                       nf_ct_expect_put(exp);
                        goto out;
                }
        }
@@ -239,9 +235,6 @@ static int __init nf_conntrack_irc_init(void)
                irc[i].tuple.src.l3num = AF_INET;
                irc[i].tuple.src.u.tcp.port = htons(ports[i]);
                irc[i].tuple.dst.protonum = IPPROTO_TCP;
-               irc[i].mask.src.l3num = 0xFFFF;
-               irc[i].mask.src.u.tcp.port = htons(0xFFFF);
-               irc[i].mask.dst.protonum = 0xFF;
                irc[i].max_expected = max_dcc_channels;
                irc[i].timeout = dcc_timeout;
                irc[i].me = THIS_MODULE;
index cbd96f3c1b8913d5acabad673edd0735bca3133d..b1bfa207a850d7fcd61d0faadf4fc91caffc7255 100644 (file)
 #include <net/netfilter/nf_conntrack_core.h>
 #include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 static int generic_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
                                struct nf_conntrack_tuple *tuple)
 {
@@ -76,12 +70,6 @@ generic_prepare(struct sk_buff **pskb, unsigned int hooknum,
 }
 
 
-static u_int32_t generic_get_features(const struct nf_conntrack_tuple *tuple)
-
-{
-       return NF_CT_F_BASIC;
-}
-
 struct nf_conntrack_l3proto nf_conntrack_l3proto_generic = {
        .l3proto         = PF_UNSPEC,
        .name            = "unknown",
@@ -90,6 +78,5 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_generic = {
        .print_tuple     = generic_print_tuple,
        .print_conntrack = generic_print_conntrack,
        .prepare         = generic_prepare,
-       .get_features    = generic_get_features,
 };
 EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_generic);
index 1093478cc007c349c0eef2dd2dbf9b2f5cc95fea..1d59fabeb5f723554216880d95dc1f2fd195e4ba 100644 (file)
@@ -74,7 +74,7 @@ static int help(struct sk_buff **pskb, unsigned int protoff,
        if (mask == 0)
                goto out;
 
-       exp = nf_conntrack_expect_alloc(ct);
+       exp = nf_ct_expect_alloc(ct);
        if (exp == NULL)
                goto out;
 
@@ -83,16 +83,13 @@ static int help(struct sk_buff **pskb, unsigned int protoff,
 
        exp->mask.src.u3.ip       = mask;
        exp->mask.src.u.udp.port  = htons(0xFFFF);
-       exp->mask.dst.u3.ip       = htonl(0xFFFFFFFF);
-       exp->mask.dst.u.udp.port  = htons(0xFFFF);
-       exp->mask.dst.protonum    = 0xFF;
 
        exp->expectfn             = NULL;
        exp->flags                = NF_CT_EXPECT_PERMANENT;
        exp->helper               = NULL;
 
-       nf_conntrack_expect_related(exp);
-       nf_conntrack_expect_put(exp);
+       nf_ct_expect_related(exp);
+       nf_ct_expect_put(exp);
 
        nf_ct_refresh(ct, *pskb, timeout * HZ);
 out:
@@ -104,9 +101,6 @@ static struct nf_conntrack_helper helper __read_mostly = {
        .tuple.src.l3num        = AF_INET,
        .tuple.src.u.udp.port   = __constant_htons(NMBD_PORT),
        .tuple.dst.protonum     = IPPROTO_UDP,
-       .mask.src.l3num         = 0xFFFF,
-       .mask.src.u.udp.port    = __constant_htons(0xFFFF),
-       .mask.dst.protonum      = 0xFF,
        .max_expected           = 1,
        .me                     = THIS_MODULE,
        .help                   = help,
index d0fe3d7698287664c2e48d37dfe09a3541cebc96..6f89b105a20572e1a120eae249ac5389803a7d59 100644 (file)
@@ -428,7 +428,7 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
 {
        struct nf_conn *ct, *last;
        struct nf_conntrack_tuple_hash *h;
-       struct list_head *i;
+       struct hlist_node *n;
        struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh);
        u_int8_t l3proto = nfmsg->nfgen_family;
 
@@ -436,8 +436,8 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
        last = (struct nf_conn *)cb->args[1];
        for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++) {
 restart:
-               list_for_each_prev(i, &nf_conntrack_hash[cb->args[0]]) {
-                       h = (struct nf_conntrack_tuple_hash *) i;
+               hlist_for_each_entry(h, n, &nf_conntrack_hash[cb->args[0]],
+                                    hnode) {
                        if (NF_CT_DIRECTION(h) != IP_CT_DIR_ORIGINAL)
                                continue;
                        ct = nf_ct_tuplehash_to_ctrack(h);
@@ -689,7 +689,7 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
        if (err < 0)
                return err;
 
-       h = nf_conntrack_find_get(&tuple, NULL);
+       h = nf_conntrack_find_get(&tuple);
        if (!h)
                return -ENOENT;
 
@@ -744,7 +744,7 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
        if (err < 0)
                return err;
 
-       h = nf_conntrack_find_get(&tuple, NULL);
+       h = nf_conntrack_find_get(&tuple);
        if (!h)
                return -ENOENT;
 
@@ -856,23 +856,23 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[])
                return 0;
        }
 
-       if (!help) {
-               /* FIXME: we need to reallocate and rehash */
-               return -EBUSY;
-       }
-
        helper = __nf_conntrack_helper_find_byname(helpname);
        if (helper == NULL)
                return -EINVAL;
 
-       if (help->helper == helper)
-               return 0;
-
-       if (help->helper)
-               return -EBUSY;
+       if (help) {
+               if (help->helper == helper)
+                       return 0;
+               if (help->helper)
+                       return -EBUSY;
+               /* need to zero data of old helper */
+               memset(&help->help, 0, sizeof(help->help));
+       } else {
+               help = nf_ct_helper_ext_add(ct, GFP_KERNEL);
+               if (help == NULL)
+                       return -ENOMEM;
+       }
 
-       /* need to zero data of old helper */
-       memset(&help->help, 0, sizeof(help->help));
        rcu_assign_pointer(help->helper, helper);
 
        return 0;
@@ -957,7 +957,7 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
        struct nf_conn *ct;
        int err = -EINVAL;
        struct nf_conn_help *help;
-       struct nf_conntrack_helper *helper = NULL;
+       struct nf_conntrack_helper *helper;
 
        ct = nf_conntrack_alloc(otuple, rtuple);
        if (ct == NULL || IS_ERR(ct))
@@ -987,9 +987,14 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
                ct->mark = ntohl(*(__be32 *)NFA_DATA(cda[CTA_MARK-1]));
 #endif
 
-       help = nfct_help(ct);
-       if (help) {
-               helper = nf_ct_helper_find_get(rtuple);
+       helper = nf_ct_helper_find_get(rtuple);
+       if (helper) {
+               help = nf_ct_helper_ext_add(ct, GFP_KERNEL);
+               if (help == NULL) {
+                       nf_ct_helper_put(helper);
+                       err = -ENOMEM;
+                       goto err;
+               }
                /* not in hash table yet so not strictly necessary */
                rcu_assign_pointer(help->helper, helper);
        }
@@ -1089,22 +1094,29 @@ nfattr_failure:
 static inline int
 ctnetlink_exp_dump_mask(struct sk_buff *skb,
                        const struct nf_conntrack_tuple *tuple,
-                       const struct nf_conntrack_tuple *mask)
+                       const struct nf_conntrack_tuple_mask *mask)
 {
        int ret;
        struct nf_conntrack_l3proto *l3proto;
        struct nf_conntrack_l4proto *l4proto;
-       struct nfattr *nest_parms = NFA_NEST(skb, CTA_EXPECT_MASK);
+       struct nf_conntrack_tuple m;
+       struct nfattr *nest_parms;
+
+       memset(&m, 0xFF, sizeof(m));
+       m.src.u.all = mask->src.u.all;
+       memcpy(&m.src.u3, &mask->src.u3, sizeof(m.src.u3));
+
+       nest_parms = NFA_NEST(skb, CTA_EXPECT_MASK);
 
        l3proto = nf_ct_l3proto_find_get(tuple->src.l3num);
-       ret = ctnetlink_dump_tuples_ip(skb, mask, l3proto);
+       ret = ctnetlink_dump_tuples_ip(skb, &m, l3proto);
        nf_ct_l3proto_put(l3proto);
 
        if (unlikely(ret < 0))
                goto nfattr_failure;
 
        l4proto = nf_ct_l4proto_find_get(tuple->src.l3num, tuple->dst.protonum);
-       ret = ctnetlink_dump_tuples_proto(skb, mask, l4proto);
+       ret = ctnetlink_dump_tuples_proto(skb, &m, l4proto);
        nf_ct_l4proto_put(l4proto);
        if (unlikely(ret < 0))
                goto nfattr_failure;
@@ -1223,32 +1235,52 @@ nfattr_failure:
        return NOTIFY_DONE;
 }
 #endif
+static int ctnetlink_exp_done(struct netlink_callback *cb)
+{
+       if (cb->args[1])
+               nf_ct_expect_put((struct nf_conntrack_expect *)cb->args[1]);
+       return 0;
+}
 
 static int
 ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
 {
-       struct nf_conntrack_expect *exp = NULL;
-       struct list_head *i;
-       u_int32_t *id = (u_int32_t *) &cb->args[0];
+       struct nf_conntrack_expect *exp, *last;
        struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh);
+       struct hlist_node *n;
        u_int8_t l3proto = nfmsg->nfgen_family;
 
        read_lock_bh(&nf_conntrack_lock);
-       list_for_each_prev(i, &nf_conntrack_expect_list) {
-               exp = (struct nf_conntrack_expect *) i;
-               if (l3proto && exp->tuple.src.l3num != l3proto)
-                       continue;
-               if (exp->id <= *id)
-                       continue;
-               if (ctnetlink_exp_fill_info(skb, NETLINK_CB(cb->skb).pid,
-                                           cb->nlh->nlmsg_seq,
-                                           IPCTNL_MSG_EXP_NEW,
-                                           1, exp) < 0)
-                       goto out;
-               *id = exp->id;
+       last = (struct nf_conntrack_expect *)cb->args[1];
+       for (; cb->args[0] < nf_ct_expect_hsize; cb->args[0]++) {
+restart:
+               hlist_for_each_entry(exp, n, &nf_ct_expect_hash[cb->args[0]],
+                                    hnode) {
+                       if (l3proto && exp->tuple.src.l3num != l3proto)
+                               continue;
+                       if (cb->args[1]) {
+                               if (exp != last)
+                                       continue;
+                               cb->args[1] = 0;
+                       }
+                       if (ctnetlink_exp_fill_info(skb, NETLINK_CB(cb->skb).pid,
+                                                   cb->nlh->nlmsg_seq,
+                                                   IPCTNL_MSG_EXP_NEW,
+                                                   1, exp) < 0) {
+                               atomic_inc(&exp->use);
+                               cb->args[1] = (unsigned long)exp;
+                               goto out;
+                       }
+               }
+               if (cb->args[1]) {
+                       cb->args[1] = 0;
+                       goto restart;
+               }
        }
 out:
        read_unlock_bh(&nf_conntrack_lock);
+       if (last)
+               nf_ct_expect_put(last);
 
        return skb->len;
 }
@@ -1275,7 +1307,7 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
        if (nlh->nlmsg_flags & NLM_F_DUMP) {
                return netlink_dump_start(ctnl, skb, nlh,
                                          ctnetlink_exp_dump_table,
-                                         ctnetlink_done);
+                                         ctnetlink_exp_done);
        }
 
        if (cda[CTA_EXPECT_MASTER-1])
@@ -1286,14 +1318,14 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
        if (err < 0)
                return err;
 
-       exp = nf_conntrack_expect_find_get(&tuple);
+       exp = nf_ct_expect_find_get(&tuple);
        if (!exp)
                return -ENOENT;
 
        if (cda[CTA_EXPECT_ID-1]) {
                __be32 id = *(__be32 *)NFA_DATA(cda[CTA_EXPECT_ID-1]);
                if (exp->id != ntohl(id)) {
-                       nf_conntrack_expect_put(exp);
+                       nf_ct_expect_put(exp);
                        return -ENOENT;
                }
        }
@@ -1309,14 +1341,14 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
        if (err <= 0)
                goto free;
 
-       nf_conntrack_expect_put(exp);
+       nf_ct_expect_put(exp);
 
        return netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT);
 
 free:
        kfree_skb(skb2);
 out:
-       nf_conntrack_expect_put(exp);
+       nf_ct_expect_put(exp);
        return err;
 }
 
@@ -1324,11 +1356,13 @@ static int
 ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
                     struct nlmsghdr *nlh, struct nfattr *cda[])
 {
-       struct nf_conntrack_expect *exp, *tmp;
+       struct nf_conntrack_expect *exp;
        struct nf_conntrack_tuple tuple;
        struct nf_conntrack_helper *h;
        struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
+       struct hlist_node *n, *next;
        u_int8_t u3 = nfmsg->nfgen_family;
+       unsigned int i;
        int err;
 
        if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
@@ -1341,25 +1375,26 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
                        return err;
 
                /* bump usage count to 2 */
-               exp = nf_conntrack_expect_find_get(&tuple);
+               exp = nf_ct_expect_find_get(&tuple);
                if (!exp)
                        return -ENOENT;
 
                if (cda[CTA_EXPECT_ID-1]) {
                        __be32 id = *(__be32 *)NFA_DATA(cda[CTA_EXPECT_ID-1]);
                        if (exp->id != ntohl(id)) {
-                               nf_conntrack_expect_put(exp);
+                               nf_ct_expect_put(exp);
                                return -ENOENT;
                        }
                }
 
                /* after list removal, usage count == 1 */
-               nf_conntrack_unexpect_related(exp);
+               nf_ct_unexpect_related(exp);
                /* have to put what we 'get' above.
                 * after this line usage count == 0 */
-               nf_conntrack_expect_put(exp);
+               nf_ct_expect_put(exp);
        } else if (cda[CTA_EXPECT_HELP_NAME-1]) {
                char *name = NFA_DATA(cda[CTA_EXPECT_HELP_NAME-1]);
+               struct nf_conn_help *m_help;
 
                /* delete all expectations for this helper */
                write_lock_bh(&nf_conntrack_lock);
@@ -1368,24 +1403,30 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
                        write_unlock_bh(&nf_conntrack_lock);
                        return -EINVAL;
                }
-               list_for_each_entry_safe(exp, tmp, &nf_conntrack_expect_list,
-                                        list) {
-                       struct nf_conn_help *m_help = nfct_help(exp->master);
-                       if (m_help->helper == h
-                           && del_timer(&exp->timeout)) {
-                               nf_ct_unlink_expect(exp);
-                               nf_conntrack_expect_put(exp);
+               for (i = 0; i < nf_ct_expect_hsize; i++) {
+                       hlist_for_each_entry_safe(exp, n, next,
+                                                 &nf_ct_expect_hash[i],
+                                                 hnode) {
+                               m_help = nfct_help(exp->master);
+                               if (m_help->helper == h
+                                   && del_timer(&exp->timeout)) {
+                                       nf_ct_unlink_expect(exp);
+                                       nf_ct_expect_put(exp);
+                               }
                        }
                }
                write_unlock_bh(&nf_conntrack_lock);
        } else {
                /* This basically means we have to flush everything*/
                write_lock_bh(&nf_conntrack_lock);
-               list_for_each_entry_safe(exp, tmp, &nf_conntrack_expect_list,
-                                        list) {
-                       if (del_timer(&exp->timeout)) {
-                               nf_ct_unlink_expect(exp);
-                               nf_conntrack_expect_put(exp);
+               for (i = 0; i < nf_ct_expect_hsize; i++) {
+                       hlist_for_each_entry_safe(exp, n, next,
+                                                 &nf_ct_expect_hash[i],
+                                                 hnode) {
+                               if (del_timer(&exp->timeout)) {
+                                       nf_ct_unlink_expect(exp);
+                                       nf_ct_expect_put(exp);
+                               }
                        }
                }
                write_unlock_bh(&nf_conntrack_lock);
@@ -1421,7 +1462,7 @@ ctnetlink_create_expect(struct nfattr *cda[], u_int8_t u3)
                return err;
 
        /* Look for master conntrack of this expectation */
-       h = nf_conntrack_find_get(&master_tuple, NULL);
+       h = nf_conntrack_find_get(&master_tuple);
        if (!h)
                return -ENOENT;
        ct = nf_ct_tuplehash_to_ctrack(h);
@@ -1433,7 +1474,7 @@ ctnetlink_create_expect(struct nfattr *cda[], u_int8_t u3)
                goto out;
        }
 
-       exp = nf_conntrack_expect_alloc(ct);
+       exp = nf_ct_expect_alloc(ct);
        if (!exp) {
                err = -ENOMEM;
                goto out;
@@ -1444,10 +1485,11 @@ ctnetlink_create_expect(struct nfattr *cda[], u_int8_t u3)
        exp->master = ct;
        exp->helper = NULL;
        memcpy(&exp->tuple, &tuple, sizeof(struct nf_conntrack_tuple));
-       memcpy(&exp->mask, &mask, sizeof(struct nf_conntrack_tuple));
+       memcpy(&exp->mask.src.u3, &mask.src.u3, sizeof(exp->mask.src.u3));
+       exp->mask.src.u.all = mask.src.u.all;
 
-       err = nf_conntrack_expect_related(exp);
-       nf_conntrack_expect_put(exp);
+       err = nf_ct_expect_related(exp);
+       nf_ct_expect_put(exp);
 
 out:
        nf_ct_put(nf_ct_tuplehash_to_ctrack(h));
@@ -1477,7 +1519,7 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
                return err;
 
        write_lock_bh(&nf_conntrack_lock);
-       exp = __nf_conntrack_expect_find(&tuple);
+       exp = __nf_ct_expect_find(&tuple);
 
        if (!exp) {
                write_unlock_bh(&nf_conntrack_lock);
@@ -1567,7 +1609,7 @@ static int __init ctnetlink_init(void)
                goto err_unreg_exp_subsys;
        }
 
-       ret = nf_conntrack_expect_register_notifier(&ctnl_notifier_exp);
+       ret = nf_ct_expect_register_notifier(&ctnl_notifier_exp);
        if (ret < 0) {
                printk("ctnetlink_init: cannot expect register notifier.\n");
                goto err_unreg_notifier;
@@ -1593,7 +1635,7 @@ static void __exit ctnetlink_exit(void)
        printk("ctnetlink: unregistering from nfnetlink.\n");
 
 #ifdef CONFIG_NF_CONNTRACK_EVENTS
-       nf_conntrack_expect_unregister_notifier(&ctnl_notifier_exp);
+       nf_ct_expect_unregister_notifier(&ctnl_notifier_exp);
        nf_conntrack_unregister_notifier(&ctnl_notifier);
 #endif
 
index 115bcb5d5a7c72721d4c57f0b6687b06ccebfba2..b0804199ab595a70958b76a17b221d27e0834940 100644 (file)
@@ -65,7 +65,7 @@ void
                             struct nf_conntrack_expect *exp) __read_mostly;
 EXPORT_SYMBOL_GPL(nf_nat_pptp_hook_expectfn);
 
-#if 0
+#ifdef DEBUG
 /* PptpControlMessageType names */
 const char *pptp_msg_name[] = {
        "UNKNOWN_MESSAGE",
@@ -86,9 +86,6 @@ const char *pptp_msg_name[] = {
        "SET_LINK_INFO"
 };
 EXPORT_SYMBOL(pptp_msg_name);
-#define DEBUGP(format, args...)        printk(KERN_DEBUG "%s:%s: " format, __FILE__, __FUNCTION__, ## args)
-#else
-#define DEBUGP(format, args...)
 #endif
 
 #define SECS *HZ
@@ -102,7 +99,7 @@ static void pptp_expectfn(struct nf_conn *ct,
                         struct nf_conntrack_expect *exp)
 {
        typeof(nf_nat_pptp_hook_expectfn) nf_nat_pptp_expectfn;
-       DEBUGP("increasing timeouts\n");
+       pr_debug("increasing timeouts\n");
 
        /* increase timeout of GRE data channel conntrack entry */
        ct->proto.gre.timeout        = PPTP_GRE_TIMEOUT;
@@ -121,17 +118,17 @@ static void pptp_expectfn(struct nf_conn *ct,
 
                /* obviously this tuple inversion only works until you do NAT */
                nf_ct_invert_tuplepr(&inv_t, &exp->tuple);
-               DEBUGP("trying to unexpect other dir: ");
+               pr_debug("trying to unexpect other dir: ");
                NF_CT_DUMP_TUPLE(&inv_t);
 
-               exp_other = nf_conntrack_expect_find_get(&inv_t);
+               exp_other = nf_ct_expect_find_get(&inv_t);
                if (exp_other) {
                        /* delete other expectation.  */
-                       DEBUGP("found\n");
-                       nf_conntrack_unexpect_related(exp_other);
-                       nf_conntrack_expect_put(exp_other);
+                       pr_debug("found\n");
+                       nf_ct_unexpect_related(exp_other);
+                       nf_ct_expect_put(exp_other);
                } else {
-                       DEBUGP("not found\n");
+                       pr_debug("not found\n");
                }
        }
        rcu_read_unlock();
@@ -143,13 +140,13 @@ static int destroy_sibling_or_exp(const struct nf_conntrack_tuple *t)
        struct nf_conntrack_expect *exp;
        struct nf_conn *sibling;
 
-       DEBUGP("trying to timeout ct or exp for tuple ");
+       pr_debug("trying to timeout ct or exp for tuple ");
        NF_CT_DUMP_TUPLE(t);
 
-       h = nf_conntrack_find_get(t, NULL);
+       h = nf_conntrack_find_get(t);
        if (h)  {
                sibling = nf_ct_tuplehash_to_ctrack(h);
-               DEBUGP("setting timeout of conntrack %p to 0\n", sibling);
+               pr_debug("setting timeout of conntrack %p to 0\n", sibling);
                sibling->proto.gre.timeout        = 0;
                sibling->proto.gre.stream_timeout = 0;
                if (del_timer(&sibling->timeout))
@@ -157,11 +154,11 @@ static int destroy_sibling_or_exp(const struct nf_conntrack_tuple *t)
                nf_ct_put(sibling);
                return 1;
        } else {
-               exp = nf_conntrack_expect_find_get(t);
+               exp = nf_ct_expect_find_get(t);
                if (exp) {
-                       DEBUGP("unexpect_related of expect %p\n", exp);
-                       nf_conntrack_unexpect_related(exp);
-                       nf_conntrack_expect_put(exp);
+                       pr_debug("unexpect_related of expect %p\n", exp);
+                       nf_ct_unexpect_related(exp);
+                       nf_ct_expect_put(exp);
                        return 1;
                }
        }
@@ -182,7 +179,7 @@ static void pptp_destroy_siblings(struct nf_conn *ct)
        t.src.u.gre.key = help->help.ct_pptp_info.pns_call_id;
        t.dst.u.gre.key = help->help.ct_pptp_info.pac_call_id;
        if (!destroy_sibling_or_exp(&t))
-               DEBUGP("failed to timeout original pns->pac ct/exp\n");
+               pr_debug("failed to timeout original pns->pac ct/exp\n");
 
        /* try reply (pac->pns) tuple */
        memcpy(&t, &ct->tuplehash[IP_CT_DIR_REPLY].tuple, sizeof(t));
@@ -190,7 +187,7 @@ static void pptp_destroy_siblings(struct nf_conn *ct)
        t.src.u.gre.key = help->help.ct_pptp_info.pac_call_id;
        t.dst.u.gre.key = help->help.ct_pptp_info.pns_call_id;
        if (!destroy_sibling_or_exp(&t))
-               DEBUGP("failed to timeout reply pac->pns ct/exp\n");
+               pr_debug("failed to timeout reply pac->pns ct/exp\n");
 }
 
 /* expect GRE connections (PNS->PAC and PAC->PNS direction) */
@@ -201,36 +198,36 @@ static int exp_gre(struct nf_conn *ct, __be16 callid, __be16 peer_callid)
        int ret = 1;
        typeof(nf_nat_pptp_hook_exp_gre) nf_nat_pptp_exp_gre;
 
-       exp_orig = nf_conntrack_expect_alloc(ct);
+       exp_orig = nf_ct_expect_alloc(ct);
        if (exp_orig == NULL)
                goto out;
 
-       exp_reply = nf_conntrack_expect_alloc(ct);
+       exp_reply = nf_ct_expect_alloc(ct);
        if (exp_reply == NULL)
                goto out_put_orig;
 
        /* original direction, PNS->PAC */
        dir = IP_CT_DIR_ORIGINAL;
-       nf_conntrack_expect_init(exp_orig, ct->tuplehash[dir].tuple.src.l3num,
-                                &ct->tuplehash[dir].tuple.src.u3,
-                                &ct->tuplehash[dir].tuple.dst.u3,
-                                IPPROTO_GRE, &peer_callid, &callid);
+       nf_ct_expect_init(exp_orig, ct->tuplehash[dir].tuple.src.l3num,
+                         &ct->tuplehash[dir].tuple.src.u3,
+                         &ct->tuplehash[dir].tuple.dst.u3,
+                         IPPROTO_GRE, &peer_callid, &callid);
        exp_orig->expectfn = pptp_expectfn;
 
        /* reply direction, PAC->PNS */
        dir = IP_CT_DIR_REPLY;
-       nf_conntrack_expect_init(exp_reply, ct->tuplehash[dir].tuple.src.l3num,
-                                &ct->tuplehash[dir].tuple.src.u3,
-                                &ct->tuplehash[dir].tuple.dst.u3,
-                                IPPROTO_GRE, &callid, &peer_callid);
+       nf_ct_expect_init(exp_reply, ct->tuplehash[dir].tuple.src.l3num,
+                         &ct->tuplehash[dir].tuple.src.u3,
+                         &ct->tuplehash[dir].tuple.dst.u3,
+                         IPPROTO_GRE, &callid, &peer_callid);
        exp_reply->expectfn = pptp_expectfn;
 
        nf_nat_pptp_exp_gre = rcu_dereference(nf_nat_pptp_hook_exp_gre);
        if (nf_nat_pptp_exp_gre && ct->status & IPS_NAT_MASK)
                nf_nat_pptp_exp_gre(exp_orig, exp_reply);
-       if (nf_conntrack_expect_related(exp_orig) != 0)
+       if (nf_ct_expect_related(exp_orig) != 0)
                goto out_put_both;
-       if (nf_conntrack_expect_related(exp_reply) != 0)
+       if (nf_ct_expect_related(exp_reply) != 0)
                goto out_unexpect_orig;
 
        /* Add GRE keymap entries */
@@ -243,16 +240,16 @@ static int exp_gre(struct nf_conn *ct, __be16 callid, __be16 peer_callid)
        ret = 0;
 
 out_put_both:
-       nf_conntrack_expect_put(exp_reply);
+       nf_ct_expect_put(exp_reply);
 out_put_orig:
-       nf_conntrack_expect_put(exp_orig);
+       nf_ct_expect_put(exp_orig);
 out:
        return ret;
 
 out_unexpect_both:
-       nf_conntrack_unexpect_related(exp_reply);
+       nf_ct_unexpect_related(exp_reply);
 out_unexpect_orig:
-       nf_conntrack_unexpect_related(exp_orig);
+       nf_ct_unexpect_related(exp_orig);
        goto out_put_both;
 }
 
@@ -270,7 +267,7 @@ pptp_inbound_pkt(struct sk_buff **pskb,
        typeof(nf_nat_pptp_hook_inbound) nf_nat_pptp_inbound;
 
        msg = ntohs(ctlh->messageType);
-       DEBUGP("inbound control message %s\n", pptp_msg_name[msg]);
+       pr_debug("inbound control message %s\n", pptp_msg_name[msg]);
 
        switch (msg) {
        case PPTP_START_SESSION_REPLY:
@@ -305,8 +302,8 @@ pptp_inbound_pkt(struct sk_buff **pskb,
                pcid = pptpReq->ocack.peersCallID;
                if (info->pns_call_id != pcid)
                        goto invalid;
-               DEBUGP("%s, CID=%X, PCID=%X\n", pptp_msg_name[msg],
-                       ntohs(cid), ntohs(pcid));
+               pr_debug("%s, CID=%X, PCID=%X\n", pptp_msg_name[msg],
+                        ntohs(cid), ntohs(pcid));
 
                if (pptpReq->ocack.resultCode == PPTP_OUTCALL_CONNECT) {
                        info->cstate = PPTP_CALL_OUT_CONF;
@@ -322,7 +319,7 @@ pptp_inbound_pkt(struct sk_buff **pskb,
                        goto invalid;
 
                cid = pptpReq->icreq.callID;
-               DEBUGP("%s, CID=%X\n", pptp_msg_name[msg], ntohs(cid));
+               pr_debug("%s, CID=%X\n", pptp_msg_name[msg], ntohs(cid));
                info->cstate = PPTP_CALL_IN_REQ;
                info->pac_call_id = cid;
                break;
@@ -341,7 +338,7 @@ pptp_inbound_pkt(struct sk_buff **pskb,
                if (info->pns_call_id != pcid)
                        goto invalid;
 
-               DEBUGP("%s, PCID=%X\n", pptp_msg_name[msg], ntohs(pcid));
+               pr_debug("%s, PCID=%X\n", pptp_msg_name[msg], ntohs(pcid));
                info->cstate = PPTP_CALL_IN_CONF;
 
                /* we expect a GRE connection from PAC to PNS */
@@ -351,7 +348,7 @@ pptp_inbound_pkt(struct sk_buff **pskb,
        case PPTP_CALL_DISCONNECT_NOTIFY:
                /* server confirms disconnect */
                cid = pptpReq->disc.callID;
-               DEBUGP("%s, CID=%X\n", pptp_msg_name[msg], ntohs(cid));
+               pr_debug("%s, CID=%X\n", pptp_msg_name[msg], ntohs(cid));
                info->cstate = PPTP_CALL_NONE;
 
                /* untrack this call id, unexpect GRE packets */
@@ -374,11 +371,11 @@ pptp_inbound_pkt(struct sk_buff **pskb,
        return NF_ACCEPT;
 
 invalid:
-       DEBUGP("invalid %s: type=%d cid=%u pcid=%u "
-              "cstate=%d sstate=%d pns_cid=%u pac_cid=%u\n",
-              msg <= PPTP_MSG_MAX ? pptp_msg_name[msg] : pptp_msg_name[0],
-              msg, ntohs(cid), ntohs(pcid),  info->cstate, info->sstate,
-              ntohs(info->pns_call_id), ntohs(info->pac_call_id));
+       pr_debug("invalid %s: type=%d cid=%u pcid=%u "
+                "cstate=%d sstate=%d pns_cid=%u pac_cid=%u\n",
+                msg <= PPTP_MSG_MAX ? pptp_msg_name[msg] : pptp_msg_name[0],
+                msg, ntohs(cid), ntohs(pcid),  info->cstate, info->sstate,
+                ntohs(info->pns_call_id), ntohs(info->pac_call_id));
        return NF_ACCEPT;
 }
 
@@ -396,7 +393,7 @@ pptp_outbound_pkt(struct sk_buff **pskb,
        typeof(nf_nat_pptp_hook_outbound) nf_nat_pptp_outbound;
 
        msg = ntohs(ctlh->messageType);
-       DEBUGP("outbound control message %s\n", pptp_msg_name[msg]);
+       pr_debug("outbound control message %s\n", pptp_msg_name[msg]);
 
        switch (msg) {
        case PPTP_START_SESSION_REQUEST:
@@ -418,7 +415,7 @@ pptp_outbound_pkt(struct sk_buff **pskb,
                info->cstate = PPTP_CALL_OUT_REQ;
                /* track PNS call id */
                cid = pptpReq->ocreq.callID;
-               DEBUGP("%s, CID=%X\n", pptp_msg_name[msg], ntohs(cid));
+               pr_debug("%s, CID=%X\n", pptp_msg_name[msg], ntohs(cid));
                info->pns_call_id = cid;
                break;
 
@@ -432,8 +429,8 @@ pptp_outbound_pkt(struct sk_buff **pskb,
                pcid = pptpReq->icack.peersCallID;
                if (info->pac_call_id != pcid)
                        goto invalid;
-               DEBUGP("%s, CID=%X PCID=%X\n", pptp_msg_name[msg],
-                      ntohs(cid), ntohs(pcid));
+               pr_debug("%s, CID=%X PCID=%X\n", pptp_msg_name[msg],
+                        ntohs(cid), ntohs(pcid));
 
                if (pptpReq->icack.resultCode == PPTP_INCALL_ACCEPT) {
                        /* part two of the three-way handshake */
@@ -469,11 +466,11 @@ pptp_outbound_pkt(struct sk_buff **pskb,
        return NF_ACCEPT;
 
 invalid:
-       DEBUGP("invalid %s: type=%d cid=%u pcid=%u "
-              "cstate=%d sstate=%d pns_cid=%u pac_cid=%u\n",
-              msg <= PPTP_MSG_MAX ? pptp_msg_name[msg] : pptp_msg_name[0],
-              msg, ntohs(cid), ntohs(pcid),  info->cstate, info->sstate,
-              ntohs(info->pns_call_id), ntohs(info->pac_call_id));
+       pr_debug("invalid %s: type=%d cid=%u pcid=%u "
+                "cstate=%d sstate=%d pns_cid=%u pac_cid=%u\n",
+                msg <= PPTP_MSG_MAX ? pptp_msg_name[msg] : pptp_msg_name[0],
+                msg, ntohs(cid), ntohs(pcid),  info->cstate, info->sstate,
+                ntohs(info->pns_call_id), ntohs(info->pac_call_id));
        return NF_ACCEPT;
 }
 
@@ -524,7 +521,7 @@ conntrack_pptp_help(struct sk_buff **pskb, unsigned int protoff,
 
        pptph = skb_header_pointer(*pskb, nexthdr_off, sizeof(_pptph), &_pptph);
        if (!pptph) {
-               DEBUGP("no full PPTP header, can't track\n");
+               pr_debug("no full PPTP header, can't track\n");
                return NF_ACCEPT;
        }
        nexthdr_off += sizeof(_pptph);
@@ -533,7 +530,7 @@ conntrack_pptp_help(struct sk_buff **pskb, unsigned int protoff,
        /* if it's not a control message we can't do anything with it */
        if (ntohs(pptph->packetType) != PPTP_PACKET_CONTROL ||
            ntohl(pptph->magicCookie) != PPTP_MAGIC_COOKIE) {
-               DEBUGP("not a control packet\n");
+               pr_debug("not a control packet\n");
                return NF_ACCEPT;
        }
 
@@ -569,8 +566,8 @@ conntrack_pptp_help(struct sk_buff **pskb, unsigned int protoff,
                /* server -> client (PAC -> PNS) */
                ret = pptp_inbound_pkt(pskb, ctlh, pptpReq, reqlen, ct,
                                       ctinfo);
-       DEBUGP("sstate: %d->%d, cstate: %d->%d\n",
-               oldsstate, info->sstate, oldcstate, info->cstate);
+       pr_debug("sstate: %d->%d, cstate: %d->%d\n",
+                oldsstate, info->sstate, oldcstate, info->cstate);
        spin_unlock_bh(&nf_pptp_lock);
 
        return ret;
@@ -585,9 +582,6 @@ static struct nf_conntrack_helper pptp __read_mostly = {
        .tuple.src.l3num        = AF_INET,
        .tuple.src.u.tcp.port   = __constant_htons(PPTP_CONTROL_PORT),
        .tuple.dst.protonum     = IPPROTO_TCP,
-       .mask.src.l3num         = 0xffff,
-       .mask.src.u.tcp.port    = __constant_htons(0xffff),
-       .mask.dst.protonum      = 0xff,
        .help                   = conntrack_pptp_help,
        .destroy                = pptp_destroy_siblings,
 };
index 339c397d1b5facb318419deeeb6fb2e1e876de62..771c4c29936e483101863b4f2c1101dc5994e60d 100644 (file)
 #define GRE_TIMEOUT            (30 * HZ)
 #define GRE_STREAM_TIMEOUT     (180 * HZ)
 
-#if 0
-#define DEBUGP(format, args...)        printk(KERN_DEBUG "%s:%s: " format, __FILE__, __FUNCTION__, ## args)
-#else
-#define DEBUGP(x, args...)
-#endif
-
 static DEFINE_RWLOCK(nf_ct_gre_lock);
 static LIST_HEAD(gre_keymap_list);
 
@@ -87,7 +81,7 @@ static __be16 gre_keymap_lookup(struct nf_conntrack_tuple *t)
        }
        read_unlock_bh(&nf_ct_gre_lock);
 
-       DEBUGP("lookup src key 0x%x for ", key);
+       pr_debug("lookup src key 0x%x for ", key);
        NF_CT_DUMP_TUPLE(t);
 
        return key;
@@ -107,8 +101,8 @@ int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir,
                        if (gre_key_cmpfn(km, t) && km == *kmp)
                                return 0;
                }
-               DEBUGP("trying to override keymap_%s for ct %p\n",
-                       dir == IP_CT_DIR_REPLY ? "reply" : "orig", ct);
+               pr_debug("trying to override keymap_%s for ct %p\n",
+                        dir == IP_CT_DIR_REPLY ? "reply" : "orig", ct);
                return -EEXIST;
        }
 
@@ -118,7 +112,7 @@ int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir,
        memcpy(&km->tuple, t, sizeof(*t));
        *kmp = km;
 
-       DEBUGP("adding new entry %p: ", km);
+       pr_debug("adding new entry %p: ", km);
        NF_CT_DUMP_TUPLE(&km->tuple);
 
        write_lock_bh(&nf_ct_gre_lock);
@@ -135,13 +129,13 @@ void nf_ct_gre_keymap_destroy(struct nf_conn *ct)
        struct nf_conn_help *help = nfct_help(ct);
        enum ip_conntrack_dir dir;
 
-       DEBUGP("entering for ct %p\n", ct);
+       pr_debug("entering for ct %p\n", ct);
 
        write_lock_bh(&nf_ct_gre_lock);
        for (dir = IP_CT_DIR_ORIGINAL; dir < IP_CT_DIR_MAX; dir++) {
                if (help->help.ct_pptp_info.keymap[dir]) {
-                       DEBUGP("removing %p from list\n",
-                               help->help.ct_pptp_info.keymap[dir]);
+                       pr_debug("removing %p from list\n",
+                                help->help.ct_pptp_info.keymap[dir]);
                        list_del(&help->help.ct_pptp_info.keymap[dir]->list);
                        kfree(help->help.ct_pptp_info.keymap[dir]);
                        help->help.ct_pptp_info.keymap[dir] = NULL;
@@ -186,7 +180,7 @@ static int gre_pkt_to_tuple(const struct sk_buff *skb,
                return 1;
 
        if (ntohs(grehdr->protocol) != GRE_PROTOCOL_PPTP) {
-               DEBUGP("GRE_VERSION_PPTP but unknown proto\n");
+               pr_debug("GRE_VERSION_PPTP but unknown proto\n");
                return 0;
        }
 
@@ -242,7 +236,7 @@ static int gre_packet(struct nf_conn *ct,
 static int gre_new(struct nf_conn *ct, const struct sk_buff *skb,
                   unsigned int dataoff)
 {
-       DEBUGP(": ");
+       pr_debug(": ");
        NF_CT_DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
 
        /* initialize to sane value.  Ideally a conntrack helper
@@ -258,10 +252,10 @@ static int gre_new(struct nf_conn *ct, const struct sk_buff *skb,
 static void gre_destroy(struct nf_conn *ct)
 {
        struct nf_conn *master = ct->master;
-       DEBUGP(" entering\n");
+       pr_debug(" entering\n");
 
        if (!master)
-               DEBUGP("no master !?!\n");
+               pr_debug("no master !?!\n");
        else
                nf_ct_gre_keymap_destroy(master);
 }
index 0d3254b974c534d0d3d00244f5ec4ee50ea4f8a7..debfe61378a1468019f9dd09604920e8cac3d2fd 100644 (file)
 #include <net/netfilter/nf_conntrack_l4proto.h>
 #include <net/netfilter/nf_conntrack_ecache.h>
 
-#if 0
-#define DEBUGP(format, ...) printk(format, ## __VA_ARGS__)
-#else
-#define DEBUGP(format, args...)
-#endif
-
 /* Protects conntrack->proto.sctp */
 static DEFINE_RWLOCK(sctp_lock);
 
@@ -151,9 +145,6 @@ static int sctp_pkt_to_tuple(const struct sk_buff *skb,
 {
        sctp_sctphdr_t _hdr, *hp;
 
-       DEBUGP(__FUNCTION__);
-       DEBUGP("\n");
-
        /* Actually only need first 8 bytes. */
        hp = skb_header_pointer(skb, dataoff, 8, &_hdr);
        if (hp == NULL)
@@ -167,9 +158,6 @@ static int sctp_pkt_to_tuple(const struct sk_buff *skb,
 static int sctp_invert_tuple(struct nf_conntrack_tuple *tuple,
                             const struct nf_conntrack_tuple *orig)
 {
-       DEBUGP(__FUNCTION__);
-       DEBUGP("\n");
-
        tuple->src.u.sctp.port = orig->dst.u.sctp.port;
        tuple->dst.u.sctp.port = orig->src.u.sctp.port;
        return 1;
@@ -179,9 +167,6 @@ static int sctp_invert_tuple(struct nf_conntrack_tuple *tuple,
 static int sctp_print_tuple(struct seq_file *s,
                            const struct nf_conntrack_tuple *tuple)
 {
-       DEBUGP(__FUNCTION__);
-       DEBUGP("\n");
-
        return seq_printf(s, "sport=%hu dport=%hu ",
                          ntohs(tuple->src.u.sctp.port),
                          ntohs(tuple->dst.u.sctp.port));
@@ -193,9 +178,6 @@ static int sctp_print_conntrack(struct seq_file *s,
 {
        enum sctp_conntrack state;
 
-       DEBUGP(__FUNCTION__);
-       DEBUGP("\n");
-
        read_lock_bh(&sctp_lock);
        state = conntrack->proto.sctp.state;
        read_unlock_bh(&sctp_lock);
@@ -219,13 +201,10 @@ static int do_basic_checks(struct nf_conn *conntrack,
        sctp_chunkhdr_t _sch, *sch;
        int flag;
 
-       DEBUGP(__FUNCTION__);
-       DEBUGP("\n");
-
        flag = 0;
 
        for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
-               DEBUGP("Chunk Num: %d  Type: %d\n", count, sch->type);
+               pr_debug("Chunk Num: %d  Type: %d\n", count, sch->type);
 
                if (sch->type == SCTP_CID_INIT
                        || sch->type == SCTP_CID_INIT_ACK
@@ -242,7 +221,7 @@ static int do_basic_checks(struct nf_conn *conntrack,
                        || sch->type == SCTP_CID_COOKIE_ECHO
                        || flag)
                      && count !=0) || !sch->length) {
-                       DEBUGP("Basic checks failed\n");
+                       pr_debug("Basic checks failed\n");
                        return 1;
                }
 
@@ -251,7 +230,7 @@ static int do_basic_checks(struct nf_conn *conntrack,
                }
        }
 
-       DEBUGP("Basic checks passed\n");
+       pr_debug("Basic checks passed\n");
        return count == 0;
 }
 
@@ -261,50 +240,47 @@ static int new_state(enum ip_conntrack_dir dir,
 {
        int i;
 
-       DEBUGP(__FUNCTION__);
-       DEBUGP("\n");
-
-       DEBUGP("Chunk type: %d\n", chunk_type);
+       pr_debug("Chunk type: %d\n", chunk_type);
 
        switch (chunk_type) {
                case SCTP_CID_INIT:
-                       DEBUGP("SCTP_CID_INIT\n");
+                       pr_debug("SCTP_CID_INIT\n");
                        i = 0; break;
                case SCTP_CID_INIT_ACK:
-                       DEBUGP("SCTP_CID_INIT_ACK\n");
+                       pr_debug("SCTP_CID_INIT_ACK\n");
                        i = 1; break;
                case SCTP_CID_ABORT:
-                       DEBUGP("SCTP_CID_ABORT\n");
+                       pr_debug("SCTP_CID_ABORT\n");
                        i = 2; break;
                case SCTP_CID_SHUTDOWN:
-                       DEBUGP("SCTP_CID_SHUTDOWN\n");
+                       pr_debug("SCTP_CID_SHUTDOWN\n");
                        i = 3; break;
                case SCTP_CID_SHUTDOWN_ACK:
-                       DEBUGP("SCTP_CID_SHUTDOWN_ACK\n");
+                       pr_debug("SCTP_CID_SHUTDOWN_ACK\n");
                        i = 4; break;
                case SCTP_CID_ERROR:
-                       DEBUGP("SCTP_CID_ERROR\n");
+                       pr_debug("SCTP_CID_ERROR\n");
                        i = 5; break;
                case SCTP_CID_COOKIE_ECHO:
-                       DEBUGP("SCTP_CID_COOKIE_ECHO\n");
+                       pr_debug("SCTP_CID_COOKIE_ECHO\n");
                        i = 6; break;
                case SCTP_CID_COOKIE_ACK:
-                       DEBUGP("SCTP_CID_COOKIE_ACK\n");
+                       pr_debug("SCTP_CID_COOKIE_ACK\n");
                        i = 7; break;
                case SCTP_CID_SHUTDOWN_COMPLETE:
-                       DEBUGP("SCTP_CID_SHUTDOWN_COMPLETE\n");
+                       pr_debug("SCTP_CID_SHUTDOWN_COMPLETE\n");
                        i = 8; break;
                default:
                        /* Other chunks like DATA, SACK, HEARTBEAT and
                        its ACK do not cause a change in state */
-                       DEBUGP("Unknown chunk type, Will stay in %s\n",
-                                               sctp_conntrack_names[cur_state]);
+                       pr_debug("Unknown chunk type, Will stay in %s\n",
+                                sctp_conntrack_names[cur_state]);
                        return cur_state;
        }
 
-       DEBUGP("dir: %d   cur_state: %s  chunk_type: %d  new_state: %s\n",
-                       dir, sctp_conntrack_names[cur_state], chunk_type,
-                       sctp_conntrack_names[sctp_conntracks[dir][i][cur_state]]);
+       pr_debug("dir: %d   cur_state: %s  chunk_type: %d  new_state: %s\n",
+                dir, sctp_conntrack_names[cur_state], chunk_type,
+                sctp_conntrack_names[sctp_conntracks[dir][i][cur_state]]);
 
        return sctp_conntracks[dir][i][cur_state];
 }
@@ -323,9 +299,6 @@ static int sctp_packet(struct nf_conn *conntrack,
        u_int32_t offset, count;
        char map[256 / sizeof (char)] = {0};
 
-       DEBUGP(__FUNCTION__);
-       DEBUGP("\n");
-
        sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
        if (sh == NULL)
                return -1;
@@ -340,7 +313,7 @@ static int sctp_packet(struct nf_conn *conntrack,
                && !test_bit(SCTP_CID_ABORT, (void *)map)
                && !test_bit(SCTP_CID_SHUTDOWN_ACK, (void *)map)
                && (sh->vtag != conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])) {
-               DEBUGP("Verification tag check failed\n");
+               pr_debug("Verification tag check failed\n");
                return -1;
        }
 
@@ -385,8 +358,9 @@ static int sctp_packet(struct nf_conn *conntrack,
 
                /* Invalid */
                if (newconntrack == SCTP_CONNTRACK_MAX) {
-                       DEBUGP("nf_conntrack_sctp: Invalid dir=%i ctype=%u conntrack=%u\n",
-                              CTINFO2DIR(ctinfo), sch->type, oldsctpstate);
+                       pr_debug("nf_conntrack_sctp: Invalid dir=%i ctype=%u "
+                                "conntrack=%u\n",
+                                CTINFO2DIR(ctinfo), sch->type, oldsctpstate);
                        write_unlock_bh(&sctp_lock);
                        return -1;
                }
@@ -402,8 +376,8 @@ static int sctp_packet(struct nf_conn *conntrack,
                                        write_unlock_bh(&sctp_lock);
                                        return -1;
                        }
-                       DEBUGP("Setting vtag %x for dir %d\n",
-                                       ih->init_tag, !CTINFO2DIR(ctinfo));
+                       pr_debug("Setting vtag %x for dir %d\n",
+                                ih->init_tag, !CTINFO2DIR(ctinfo));
                        conntrack->proto.sctp.vtag[!CTINFO2DIR(ctinfo)] = ih->init_tag;
                }
 
@@ -418,7 +392,7 @@ static int sctp_packet(struct nf_conn *conntrack,
        if (oldsctpstate == SCTP_CONNTRACK_COOKIE_ECHOED
                && CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY
                && newconntrack == SCTP_CONNTRACK_ESTABLISHED) {
-               DEBUGP("Setting assured bit\n");
+               pr_debug("Setting assured bit\n");
                set_bit(IPS_ASSURED_BIT, &conntrack->status);
                nf_conntrack_event_cache(IPCT_STATUS, skb);
        }
@@ -436,9 +410,6 @@ static int sctp_new(struct nf_conn *conntrack, const struct sk_buff *skb,
        u_int32_t offset, count;
        char map[256 / sizeof (char)] = {0};
 
-       DEBUGP(__FUNCTION__);
-       DEBUGP("\n");
-
        sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
        if (sh == NULL)
                return 0;
@@ -460,8 +431,9 @@ static int sctp_new(struct nf_conn *conntrack, const struct sk_buff *skb,
                                         SCTP_CONNTRACK_NONE, sch->type);
 
                /* Invalid: delete conntrack */
-               if (newconntrack == SCTP_CONNTRACK_MAX) {
-                       DEBUGP("nf_conntrack_sctp: invalid new deleting.\n");
+               if (newconntrack == SCTP_CONNTRACK_NONE ||
+                   newconntrack == SCTP_CONNTRACK_MAX) {
+                       pr_debug("nf_conntrack_sctp: invalid new deleting.\n");
                        return 0;
                }
 
@@ -475,8 +447,8 @@ static int sctp_new(struct nf_conn *conntrack, const struct sk_buff *skb,
                                if (ih == NULL)
                                        return 0;
 
-                               DEBUGP("Setting vtag %x for new conn\n",
-                                       ih->init_tag);
+                               pr_debug("Setting vtag %x for new conn\n",
+                                        ih->init_tag);
 
                                conntrack->proto.sctp.vtag[IP_CT_DIR_REPLY] =
                                                                ih->init_tag;
@@ -488,8 +460,8 @@ static int sctp_new(struct nf_conn *conntrack, const struct sk_buff *skb,
                /* If it is a shutdown ack OOTB packet, we expect a return
                   shutdown complete, otherwise an ABORT Sec 8.4 (5) and (8) */
                else {
-                       DEBUGP("Setting vtag %x for new conn OOTB\n",
-                               sh->vtag);
+                       pr_debug("Setting vtag %x for new conn OOTB\n",
+                                sh->vtag);
                        conntrack->proto.sctp.vtag[IP_CT_DIR_REPLY] = sh->vtag;
                }
 
@@ -688,8 +660,6 @@ int __init nf_conntrack_proto_sctp_init(void)
  cleanup_sctp4:
        nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
  out:
-       DEBUGP("SCTP conntrack module loading %s\n",
-                                       ret ? "failed": "succeeded");
        return ret;
 }
 
@@ -697,7 +667,6 @@ void __exit nf_conntrack_proto_sctp_fini(void)
 {
        nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp6);
        nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
-       DEBUGP("SCTP conntrack module unloaded\n");
 }
 
 module_init(nf_conntrack_proto_sctp_init);
index ccdd5d231e0d244227212b348fa55afe43565c1f..1c8206e6560ac691159b6a8a9e9cd3b675b047e2 100644 (file)
 #include <net/netfilter/nf_conntrack_l4proto.h>
 #include <net/netfilter/nf_conntrack_ecache.h>
 
-#if 0
-#define DEBUGP printk
-#define DEBUGP_VARS
-#else
-#define DEBUGP(format, args...)
-#endif
-
 /* Protects conntrack->proto.tcp */
 static DEFINE_RWLOCK(tcp_lock);
 
@@ -496,7 +489,8 @@ static void tcp_sack(const struct sk_buff *skb, unsigned int dataoff,
        }
 }
 
-static int tcp_in_window(struct ip_ct_tcp *state,
+static int tcp_in_window(struct nf_conn *ct,
+                        struct ip_ct_tcp *state,
                         enum ip_conntrack_dir dir,
                         unsigned int index,
                         const struct sk_buff *skb,
@@ -506,6 +500,7 @@ static int tcp_in_window(struct ip_ct_tcp *state,
 {
        struct ip_ct_tcp_state *sender = &state->seen[dir];
        struct ip_ct_tcp_state *receiver = &state->seen[!dir];
+       struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple;
        __u32 seq, ack, sack, end, win, swin;
        int res;
 
@@ -520,18 +515,17 @@ static int tcp_in_window(struct ip_ct_tcp *state,
        if (receiver->flags & IP_CT_TCP_FLAG_SACK_PERM)
                tcp_sack(skb, dataoff, tcph, &sack);
 
-       DEBUGP("tcp_in_window: START\n");
-       DEBUGP("tcp_in_window: src=%u.%u.%u.%u:%hu dst=%u.%u.%u.%u:%hu "
-              "seq=%u ack=%u sack=%u win=%u end=%u\n",
-               NIPQUAD(iph->saddr), ntohs(tcph->source),
-               NIPQUAD(iph->daddr), ntohs(tcph->dest),
-               seq, ack, sack, win, end);
-       DEBUGP("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i "
-              "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
-               sender->td_end, sender->td_maxend, sender->td_maxwin,
-               sender->td_scale,
-               receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
-               receiver->td_scale);
+       pr_debug("tcp_in_window: START\n");
+       pr_debug("tcp_in_window: ");
+       NF_CT_DUMP_TUPLE(tuple);
+       pr_debug("seq=%u ack=%u sack=%u win=%u end=%u\n",
+                seq, ack, sack, win, end);
+       pr_debug("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i "
+                "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
+                sender->td_end, sender->td_maxend, sender->td_maxwin,
+                sender->td_scale,
+                receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
+                receiver->td_scale);
 
        if (sender->td_end == 0) {
                /*
@@ -609,23 +603,22 @@ static int tcp_in_window(struct ip_ct_tcp *state,
                 */
                seq = end = sender->td_end;
 
-       DEBUGP("tcp_in_window: src=%u.%u.%u.%u:%hu dst=%u.%u.%u.%u:%hu "
-              "seq=%u ack=%u sack =%u win=%u end=%u\n",
-               NIPQUAD(iph->saddr), ntohs(tcph->source),
-               NIPQUAD(iph->daddr), ntohs(tcph->dest),
-               seq, ack, sack, win, end);
-       DEBUGP("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i "
-              "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
-               sender->td_end, sender->td_maxend, sender->td_maxwin,
-               sender->td_scale,
-               receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
-               receiver->td_scale);
-
-       DEBUGP("tcp_in_window: I=%i II=%i III=%i IV=%i\n",
-               before(seq, sender->td_maxend + 1),
-               after(end, sender->td_end - receiver->td_maxwin - 1),
-               before(sack, receiver->td_end + 1),
-               after(ack, receiver->td_end - MAXACKWINDOW(sender)));
+       pr_debug("tcp_in_window: ");
+       NF_CT_DUMP_TUPLE(tuple);
+       pr_debug("seq=%u ack=%u sack =%u win=%u end=%u\n",
+                seq, ack, sack, win, end);
+       pr_debug("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i "
+                "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
+                sender->td_end, sender->td_maxend, sender->td_maxwin,
+                sender->td_scale,
+                receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
+                receiver->td_scale);
+
+       pr_debug("tcp_in_window: I=%i II=%i III=%i IV=%i\n",
+                before(seq, sender->td_maxend + 1),
+                after(end, sender->td_end - receiver->td_maxwin - 1),
+                before(sack, receiver->td_end + 1),
+                after(ack, receiver->td_end - MAXACKWINDOW(sender)));
 
        if (before(seq, sender->td_maxend + 1) &&
            after(end, sender->td_end - receiver->td_maxwin - 1) &&
@@ -694,10 +687,10 @@ static int tcp_in_window(struct ip_ct_tcp *state,
                        : "SEQ is over the upper bound (over the window of the receiver)");
        }
 
-       DEBUGP("tcp_in_window: res=%i sender end=%u maxend=%u maxwin=%u "
-              "receiver end=%u maxend=%u maxwin=%u\n",
-               res, sender->td_end, sender->td_maxend, sender->td_maxwin,
-               receiver->td_end, receiver->td_maxend, receiver->td_maxwin);
+       pr_debug("tcp_in_window: res=%i sender end=%u maxend=%u maxwin=%u "
+                "receiver end=%u maxend=%u maxwin=%u\n",
+                res, sender->td_end, sender->td_maxend, sender->td_maxwin,
+                receiver->td_end, receiver->td_maxend, receiver->td_maxwin);
 
        return res;
 }
@@ -711,11 +704,9 @@ void nf_conntrack_tcp_update(struct sk_buff *skb,
                             int dir)
 {
        struct tcphdr *tcph = (void *)skb->data + dataoff;
-       __u32 end;
-#ifdef DEBUGP_VARS
        struct ip_ct_tcp_state *sender = &conntrack->proto.tcp.seen[dir];
        struct ip_ct_tcp_state *receiver = &conntrack->proto.tcp.seen[!dir];
-#endif
+       __u32 end;
 
        end = segment_seq_plus_len(ntohl(tcph->seq), skb->len, dataoff, tcph);
 
@@ -727,12 +718,12 @@ void nf_conntrack_tcp_update(struct sk_buff *skb,
                conntrack->proto.tcp.seen[dir].td_end = end;
        conntrack->proto.tcp.last_end = end;
        write_unlock_bh(&tcp_lock);
-       DEBUGP("tcp_update: sender end=%u maxend=%u maxwin=%u scale=%i "
-              "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
-               sender->td_end, sender->td_maxend, sender->td_maxwin,
-               sender->td_scale,
-               receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
-               receiver->td_scale);
+       pr_debug("tcp_update: sender end=%u maxend=%u maxwin=%u scale=%i "
+                "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
+                sender->td_end, sender->td_maxend, sender->td_maxwin,
+                sender->td_scale,
+                receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
+                receiver->td_scale);
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_tcp_update);
 #endif
@@ -823,6 +814,7 @@ static int tcp_packet(struct nf_conn *conntrack,
                      int pf,
                      unsigned int hooknum)
 {
+       struct nf_conntrack_tuple *tuple;
        enum tcp_conntrack new_state, old_state;
        enum ip_conntrack_dir dir;
        struct tcphdr *th, _tcph;
@@ -837,6 +829,7 @@ static int tcp_packet(struct nf_conn *conntrack,
        dir = CTINFO2DIR(ctinfo);
        index = get_conntrack_index(th);
        new_state = tcp_conntracks[dir][index][old_state];
+       tuple = &conntrack->tuplehash[dir].tuple;
 
        switch (new_state) {
        case TCP_CONNTRACK_IGNORE:
@@ -880,9 +873,8 @@ static int tcp_packet(struct nf_conn *conntrack,
                return NF_ACCEPT;
        case TCP_CONNTRACK_MAX:
                /* Invalid packet */
-               DEBUGP("nf_ct_tcp: Invalid dir=%i index=%u ostate=%u\n",
-                      dir, get_conntrack_index(th),
-                      old_state);
+               pr_debug("nf_ct_tcp: Invalid dir=%i index=%u ostate=%u\n",
+                        dir, get_conntrack_index(th), old_state);
                write_unlock_bh(&tcp_lock);
                if (LOG_INVALID(IPPROTO_TCP))
                        nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
@@ -933,7 +925,7 @@ static int tcp_packet(struct nf_conn *conntrack,
                break;
        }
 
-       if (!tcp_in_window(&conntrack->proto.tcp, dir, index,
+       if (!tcp_in_window(conntrack, &conntrack->proto.tcp, dir, index,
                           skb, dataoff, th, pf)) {
                write_unlock_bh(&tcp_lock);
                return -NF_ACCEPT;
@@ -942,13 +934,12 @@ static int tcp_packet(struct nf_conn *conntrack,
        /* From now on we have got in-window packets */
        conntrack->proto.tcp.last_index = index;
 
-       DEBUGP("tcp_conntracks: src=%u.%u.%u.%u:%hu dst=%u.%u.%u.%u:%hu "
-              "syn=%i ack=%i fin=%i rst=%i old=%i new=%i\n",
-               NIPQUAD(iph->saddr), ntohs(th->source),
-               NIPQUAD(iph->daddr), ntohs(th->dest),
-               (th->syn ? 1 : 0), (th->ack ? 1 : 0),
-               (th->fin ? 1 : 0), (th->rst ? 1 : 0),
-               old_state, new_state);
+       pr_debug("tcp_conntracks: ");
+       NF_CT_DUMP_TUPLE(tuple);
+       pr_debug("syn=%i ack=%i fin=%i rst=%i old=%i new=%i\n",
+                (th->syn ? 1 : 0), (th->ack ? 1 : 0),
+                (th->fin ? 1 : 0), (th->rst ? 1 : 0),
+                old_state, new_state);
 
        conntrack->proto.tcp.state = new_state;
        if (old_state != new_state
@@ -997,10 +988,8 @@ static int tcp_new(struct nf_conn *conntrack,
 {
        enum tcp_conntrack new_state;
        struct tcphdr *th, _tcph;
-#ifdef DEBUGP_VARS
        struct ip_ct_tcp_state *sender = &conntrack->proto.tcp.seen[0];
        struct ip_ct_tcp_state *receiver = &conntrack->proto.tcp.seen[1];
-#endif
 
        th = skb_header_pointer(skb, dataoff, sizeof(_tcph), &_tcph);
        BUG_ON(th == NULL);
@@ -1012,7 +1001,7 @@ static int tcp_new(struct nf_conn *conntrack,
 
        /* Invalid: delete conntrack */
        if (new_state >= TCP_CONNTRACK_MAX) {
-               DEBUGP("nf_ct_tcp: invalid new deleting.\n");
+               pr_debug("nf_ct_tcp: invalid new deleting.\n");
                return 0;
        }
 
@@ -1065,12 +1054,12 @@ static int tcp_new(struct nf_conn *conntrack,
        conntrack->proto.tcp.state = TCP_CONNTRACK_NONE;
        conntrack->proto.tcp.last_index = TCP_NONE_SET;
 
-       DEBUGP("tcp_new: sender end=%u maxend=%u maxwin=%u scale=%i "
-              "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
-               sender->td_end, sender->td_maxend, sender->td_maxwin,
-               sender->td_scale,
-               receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
-               receiver->td_scale);
+       pr_debug("tcp_new: sender end=%u maxend=%u maxwin=%u scale=%i "
+                "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
+                sender->td_end, sender->td_maxend, sender->td_maxwin,
+                sender->td_scale,
+                receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
+                receiver->td_scale);
        return 1;
 }
 
index eb2d1dc46d45286fe3e5667d2e8a64c22dff1cf5..355d371bac93d8bf1f7265d4cecdb7915cdc3157 100644 (file)
@@ -40,12 +40,6 @@ static u_int16_t ports[MAX_PORTS];
 static unsigned int ports_c;
 module_param_array(ports, ushort, &ports_c, 0400);
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 struct sane_request {
        __be32 RPC_code;
 #define SANE_NET_START      7   /* RPC code */
@@ -125,15 +119,15 @@ static int help(struct sk_buff **pskb,
        ct_sane_info->state = SANE_STATE_NORMAL;
 
        if (datalen < sizeof(struct sane_reply_net_start)) {
-               DEBUGP("nf_ct_sane: NET_START reply too short\n");
+               pr_debug("nf_ct_sane: NET_START reply too short\n");
                goto out;
        }
 
        reply = (struct sane_reply_net_start *)sb_ptr;
        if (reply->status != htonl(SANE_STATUS_SUCCESS)) {
                /* saned refused the command */
-               DEBUGP("nf_ct_sane: unsuccessful SANE_STATUS = %u\n",
-                       ntohl(reply->status));
+               pr_debug("nf_ct_sane: unsuccessful SANE_STATUS = %u\n",
+                        ntohl(reply->status));
                goto out;
        }
 
@@ -141,35 +135,32 @@ static int help(struct sk_buff **pskb,
        if (reply->zero != 0)
                goto out;
 
-       exp = nf_conntrack_expect_alloc(ct);
+       exp = nf_ct_expect_alloc(ct);
        if (exp == NULL) {
                ret = NF_DROP;
                goto out;
        }
 
        tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
-       nf_conntrack_expect_init(exp, family,
-                                &tuple->src.u3, &tuple->dst.u3,
-                                IPPROTO_TCP,
-                                NULL, &reply->port);
+       nf_ct_expect_init(exp, family, &tuple->src.u3, &tuple->dst.u3,
+                         IPPROTO_TCP, NULL, &reply->port);
 
-       DEBUGP("nf_ct_sane: expect: ");
+       pr_debug("nf_ct_sane: expect: ");
        NF_CT_DUMP_TUPLE(&exp->tuple);
-       NF_CT_DUMP_TUPLE(&exp->mask);
 
        /* Can't expect this?  Best to drop packet now. */
-       if (nf_conntrack_expect_related(exp) != 0)
+       if (nf_ct_expect_related(exp) != 0)
                ret = NF_DROP;
 
-       nf_conntrack_expect_put(exp);
+       nf_ct_expect_put(exp);
 
 out:
        spin_unlock_bh(&nf_sane_lock);
        return ret;
 }
 
-static struct nf_conntrack_helper sane[MAX_PORTS][2];
-static char sane_names[MAX_PORTS][2][sizeof("sane-65535")];
+static struct nf_conntrack_helper sane[MAX_PORTS][2] __read_mostly;
+static char sane_names[MAX_PORTS][2][sizeof("sane-65535")] __read_mostly;
 
 /* don't make this __exit, since it's called from __init ! */
 static void nf_conntrack_sane_fini(void)
@@ -178,9 +169,9 @@ static void nf_conntrack_sane_fini(void)
 
        for (i = 0; i < ports_c; i++) {
                for (j = 0; j < 2; j++) {
-                       DEBUGP("nf_ct_sane: unregistering helper for pf: %d "
-                              "port: %d\n",
-                               sane[i][j].tuple.src.l3num, ports[i]);
+                       pr_debug("nf_ct_sane: unregistering helper for pf: %d "
+                                "port: %d\n",
+                                sane[i][j].tuple.src.l3num, ports[i]);
                        nf_conntrack_helper_unregister(&sane[i][j]);
                }
        }
@@ -208,8 +199,6 @@ static int __init nf_conntrack_sane_init(void)
                for (j = 0; j < 2; j++) {
                        sane[i][j].tuple.src.u.tcp.port = htons(ports[i]);
                        sane[i][j].tuple.dst.protonum = IPPROTO_TCP;
-                       sane[i][j].mask.src.u.tcp.port = 0xFFFF;
-                       sane[i][j].mask.dst.protonum = 0xFF;
                        sane[i][j].max_expected = 1;
                        sane[i][j].timeout = 5 * 60;    /* 5 Minutes */
                        sane[i][j].me = THIS_MODULE;
@@ -221,9 +210,9 @@ static int __init nf_conntrack_sane_init(void)
                                sprintf(tmpname, "sane-%d", ports[i]);
                        sane[i][j].name = tmpname;
 
-                       DEBUGP("nf_ct_sane: registering helper for pf: %d "
-                              "port: %d\n",
-                               sane[i][j].tuple.src.l3num, ports[i]);
+                       pr_debug("nf_ct_sane: registering helper for pf: %d "
+                                "port: %d\n",
+                                sane[i][j].tuple.src.l3num, ports[i]);
                        ret = nf_conntrack_helper_register(&sane[i][j]);
                        if (ret) {
                                printk(KERN_ERR "nf_ct_sane: failed to "
index 1b5c6c1055f75edb03e1b5c42d1777e5ac311b81..1276a442f10c53936d021be834631860285fd660 100644 (file)
 #include <net/netfilter/nf_conntrack_helper.h>
 #include <linux/netfilter/nf_conntrack_sip.h>
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Christian Hentschel <chentschel@arnet.com.ar>");
 MODULE_DESCRIPTION("SIP connection tracking helper");
@@ -285,7 +279,7 @@ static int epaddr_len(struct nf_conn *ct, const char *dptr,
        const char *aux = dptr;
 
        if (!parse_addr(ct, dptr, &dptr, &addr, limit)) {
-               DEBUGP("ip: %s parse failed.!\n", dptr);
+               pr_debug("ip: %s parse failed.!\n", dptr);
                return 0;
        }
 
@@ -344,8 +338,8 @@ int ct_sip_get_info(struct nf_conn *ct,
                                    ct_sip_lnlen(dptr, limit),
                                    hnfo->case_sensitive);
                if (!aux) {
-                       DEBUGP("'%s' not found in '%s'.\n", hnfo->ln_str,
-                              hnfo->lname);
+                       pr_debug("'%s' not found in '%s'.\n", hnfo->ln_str,
+                                hnfo->lname);
                        return -1;
                }
                aux += hnfo->ln_strlen;
@@ -356,11 +350,11 @@ int ct_sip_get_info(struct nf_conn *ct,
 
                *matchoff = (aux - k) + shift;
 
-               DEBUGP("%s match succeeded! - len: %u\n", hnfo->lname,
-                      *matchlen);
+               pr_debug("%s match succeeded! - len: %u\n", hnfo->lname,
+                        *matchlen);
                return 1;
        }
-       DEBUGP("%s header not found.\n", hnfo->lname);
+       pr_debug("%s header not found.\n", hnfo->lname);
        return 0;
 }
 EXPORT_SYMBOL_GPL(ct_sip_get_info);
@@ -378,23 +372,23 @@ static int set_expected_rtp(struct sk_buff **pskb,
        int ret;
        typeof(nf_nat_sdp_hook) nf_nat_sdp;
 
-       exp = nf_conntrack_expect_alloc(ct);
+       exp = nf_ct_expect_alloc(ct);
        if (exp == NULL)
                return NF_DROP;
-       nf_conntrack_expect_init(exp, family,
-                                &ct->tuplehash[!dir].tuple.src.u3, addr,
-                                IPPROTO_UDP, NULL, &port);
+       nf_ct_expect_init(exp, family,
+                         &ct->tuplehash[!dir].tuple.src.u3, addr,
+                         IPPROTO_UDP, NULL, &port);
 
        nf_nat_sdp = rcu_dereference(nf_nat_sdp_hook);
        if (nf_nat_sdp && ct->status & IPS_NAT_MASK)
                ret = nf_nat_sdp(pskb, ctinfo, exp, dptr);
        else {
-               if (nf_conntrack_expect_related(exp) != 0)
+               if (nf_ct_expect_related(exp) != 0)
                        ret = NF_DROP;
                else
                        ret = NF_ACCEPT;
        }
-       nf_conntrack_expect_put(exp);
+       nf_ct_expect_put(exp);
 
        return ret;
 }
@@ -424,7 +418,7 @@ static int sip_help(struct sk_buff **pskb,
        if (!skb_is_nonlinear(*pskb))
                dptr = (*pskb)->data + dataoff;
        else {
-               DEBUGP("Copy of skbuff not supported yet.\n");
+               pr_debug("Copy of skbuff not supported yet.\n");
                goto out;
        }
 
@@ -506,9 +500,6 @@ static int __init nf_conntrack_sip_init(void)
                for (j = 0; j < 2; j++) {
                        sip[i][j].tuple.dst.protonum = IPPROTO_UDP;
                        sip[i][j].tuple.src.u.udp.port = htons(ports[i]);
-                       sip[i][j].mask.src.l3num = 0xFFFF;
-                       sip[i][j].mask.src.u.udp.port = htons(0xFFFF);
-                       sip[i][j].mask.dst.protonum = 0xFF;
                        sip[i][j].max_expected = 2;
                        sip[i][j].timeout = 3 * 60; /* 3 minutes */
                        sip[i][j].me = THIS_MODULE;
@@ -521,7 +512,7 @@ static int __init nf_conntrack_sip_init(void)
                                sprintf(tmpname, "sip-%u", i);
                        sip[i][j].name = tmpname;
 
-                       DEBUGP("port #%u: %u\n", i, ports[i]);
+                       pr_debug("port #%u: %u\n", i, ports[i]);
 
                        ret = nf_conntrack_helper_register(&sip[i][j]);
                        if (ret) {
index 45baeb0e30f99968f8bc122338d0d1c663751e6f..ffb6ff8c352807b511c7e6649ab3ca2051d67b0f 100644 (file)
 #include <net/netfilter/nf_conntrack_expect.h>
 #include <net/netfilter/nf_conntrack_helper.h>
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 MODULE_LICENSE("GPL");
 
 #ifdef CONFIG_PROC_FS
@@ -60,35 +54,36 @@ struct ct_iter_state {
        unsigned int bucket;
 };
 
-static struct list_head *ct_get_first(struct seq_file *seq)
+static struct hlist_node *ct_get_first(struct seq_file *seq)
 {
        struct ct_iter_state *st = seq->private;
 
        for (st->bucket = 0;
             st->bucket < nf_conntrack_htable_size;
             st->bucket++) {
-               if (!list_empty(&nf_conntrack_hash[st->bucket]))
-                       return nf_conntrack_hash[st->bucket].next;
+               if (!hlist_empty(&nf_conntrack_hash[st->bucket]))
+                       return nf_conntrack_hash[st->bucket].first;
        }
        return NULL;
 }
 
-static struct list_head *ct_get_next(struct seq_file *seq, struct list_head *head)
+static struct hlist_node *ct_get_next(struct seq_file *seq,
+                                     struct hlist_node *head)
 {
        struct ct_iter_state *st = seq->private;
 
        head = head->next;
-       while (head == &nf_conntrack_hash[st->bucket]) {
+       while (head == NULL) {
                if (++st->bucket >= nf_conntrack_htable_size)
                        return NULL;
-               head = nf_conntrack_hash[st->bucket].next;
+               head = nf_conntrack_hash[st->bucket].first;
        }
        return head;
 }
 
-static struct list_head *ct_get_idx(struct seq_file *seq, loff_t pos)
+static struct hlist_node *ct_get_idx(struct seq_file *seq, loff_t pos)
 {
-       struct list_head *head = ct_get_first(seq);
+       struct hlist_node *head = ct_get_first(seq);
 
        if (head)
                while (pos && (head = ct_get_next(seq, head)))
@@ -190,7 +185,7 @@ static int ct_seq_show(struct seq_file *s, void *v)
        return 0;
 }
 
-static struct seq_operations ct_seq_ops = {
+static const struct seq_operations ct_seq_ops = {
        .start = ct_seq_start,
        .next  = ct_seq_next,
        .stop  = ct_seq_stop,
@@ -294,7 +289,7 @@ static int ct_cpu_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations ct_cpu_seq_ops = {
+static const struct seq_operations ct_cpu_seq_ops = {
        .start  = ct_cpu_seq_start,
        .next   = ct_cpu_seq_next,
        .stop   = ct_cpu_seq_stop,
@@ -371,7 +366,14 @@ static ctl_table nf_ct_sysctl_table[] = {
                .extra1         = &log_invalid_proto_min,
                .extra2         = &log_invalid_proto_max,
        },
-
+       {
+               .ctl_name       = CTL_UNNUMBERED,
+               .procname       = "nf_conntrack_expect_max",
+               .data           = &nf_ct_expect_max,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec,
+       },
        { .ctl_name = 0 }
 };
 
@@ -410,7 +412,7 @@ EXPORT_SYMBOL_GPL(nf_ct_log_invalid);
 static int __init nf_conntrack_standalone_init(void)
 {
 #ifdef CONFIG_PROC_FS
-       struct proc_dir_entry *proc, *proc_exp, *proc_stat;
+       struct proc_dir_entry *proc, *proc_stat;
 #endif
        int ret = 0;
 
@@ -422,13 +424,9 @@ static int __init nf_conntrack_standalone_init(void)
        proc = proc_net_fops_create("nf_conntrack", 0440, &ct_file_ops);
        if (!proc) goto cleanup_init;
 
-       proc_exp = proc_net_fops_create("nf_conntrack_expect", 0440,
-                                       &exp_file_ops);
-       if (!proc_exp) goto cleanup_proc;
-
        proc_stat = create_proc_entry("nf_conntrack", S_IRUGO, proc_net_stat);
        if (!proc_stat)
-               goto cleanup_proc_exp;
+               goto cleanup_proc;
 
        proc_stat->proc_fops = &ct_cpu_seq_fops;
        proc_stat->owner = THIS_MODULE;
@@ -448,8 +446,6 @@ static int __init nf_conntrack_standalone_init(void)
 #endif
 #ifdef CONFIG_PROC_FS
        remove_proc_entry("nf_conntrack", proc_net_stat);
- cleanup_proc_exp:
-       proc_net_remove("nf_conntrack_expect");
  cleanup_proc:
        proc_net_remove("nf_conntrack");
  cleanup_init:
@@ -465,7 +461,6 @@ static void __exit nf_conntrack_standalone_fini(void)
 #endif
 #ifdef CONFIG_PROC_FS
        remove_proc_entry("nf_conntrack", proc_net_stat);
-       proc_net_remove("nf_conntrack_expect");
        proc_net_remove("nf_conntrack");
 #endif /* CNFIG_PROC_FS */
        nf_conntrack_cleanup();
index 37c4542e3112f5a93420c72755264a2c802c6a4e..cc19506cf2f8e6c7fcb576daa9720c677e5cf1e4 100644 (file)
@@ -29,13 +29,6 @@ static int ports_c;
 module_param_array(ports, ushort, &ports_c, 0400);
 MODULE_PARM_DESC(ports, "Port numbers of TFTP servers");
 
-#if 0
-#define DEBUGP(format, args...) printk("%s:%s:" format, \
-                                      __FILE__, __FUNCTION__ , ## args)
-#else
-#define DEBUGP(format, args...)
-#endif
-
 unsigned int (*nf_nat_tftp_hook)(struct sk_buff **pskb,
                                 enum ip_conntrack_info ctinfo,
                                 struct nf_conntrack_expect *exp) __read_mostly;
@@ -62,39 +55,35 @@ static int tftp_help(struct sk_buff **pskb,
        case TFTP_OPCODE_READ:
        case TFTP_OPCODE_WRITE:
                /* RRQ and WRQ works the same way */
-               DEBUGP("");
                NF_CT_DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
                NF_CT_DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
 
-               exp = nf_conntrack_expect_alloc(ct);
+               exp = nf_ct_expect_alloc(ct);
                if (exp == NULL)
                        return NF_DROP;
                tuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple;
-               nf_conntrack_expect_init(exp, family,
-                                        &tuple->src.u3, &tuple->dst.u3,
-                                        IPPROTO_UDP,
-                                        NULL, &tuple->dst.u.udp.port);
+               nf_ct_expect_init(exp, family, &tuple->src.u3, &tuple->dst.u3,
+                                 IPPROTO_UDP, NULL, &tuple->dst.u.udp.port);
 
-               DEBUGP("expect: ");
+               pr_debug("expect: ");
                NF_CT_DUMP_TUPLE(&exp->tuple);
-               NF_CT_DUMP_TUPLE(&exp->mask);
 
                nf_nat_tftp = rcu_dereference(nf_nat_tftp_hook);
                if (nf_nat_tftp && ct->status & IPS_NAT_MASK)
                        ret = nf_nat_tftp(pskb, ctinfo, exp);
-               else if (nf_conntrack_expect_related(exp) != 0)
+               else if (nf_ct_expect_related(exp) != 0)
                        ret = NF_DROP;
-               nf_conntrack_expect_put(exp);
+               nf_ct_expect_put(exp);
                break;
        case TFTP_OPCODE_DATA:
        case TFTP_OPCODE_ACK:
-               DEBUGP("Data/ACK opcode\n");
+               pr_debug("Data/ACK opcode\n");
                break;
        case TFTP_OPCODE_ERROR:
-               DEBUGP("Error opcode\n");
+               pr_debug("Error opcode\n");
                break;
        default:
-               DEBUGP("Unknown opcode\n");
+               pr_debug("Unknown opcode\n");
        }
        return ret;
 }
@@ -128,9 +117,6 @@ static int __init nf_conntrack_tftp_init(void)
                for (j = 0; j < 2; j++) {
                        tftp[i][j].tuple.dst.protonum = IPPROTO_UDP;
                        tftp[i][j].tuple.src.u.udp.port = htons(ports[i]);
-                       tftp[i][j].mask.src.l3num = 0xFFFF;
-                       tftp[i][j].mask.dst.protonum = 0xFF;
-                       tftp[i][j].mask.src.u.udp.port = htons(0xFFFF);
                        tftp[i][j].max_expected = 1;
                        tftp[i][j].timeout = 5 * 60; /* 5 minutes */
                        tftp[i][j].me = THIS_MODULE;
index 91b220cf5a1fee639d506c3ba48a69f1fc7e9664..94985792b79ac65a9e3eb5ac8b04704cd2004b3b 100644 (file)
@@ -140,7 +140,7 @@ static int seq_show(struct seq_file *s, void *v)
        return seq_printf(s, "%2lld %s\n", *pos, logger->name);
 }
 
-static struct seq_operations nflog_seq_ops = {
+static const struct seq_operations nflog_seq_ops = {
        .start  = seq_start,
        .next   = seq_next,
        .stop   = seq_stop,
index b1f2ace96f6d2acab781ee38d34671e986f379c3..a481a349f7bf6b5e29d00e75343f5a5934b47f1a 100644 (file)
@@ -17,7 +17,7 @@
  */
 static struct nf_queue_handler *queue_handler[NPROTO];
 
-static DEFINE_RWLOCK(queue_handler_lock);
+static DEFINE_MUTEX(queue_handler_mutex);
 
 /* return EBUSY when somebody else is registered, return EEXIST if the
  * same handler is registered, return 0 in case of success. */
@@ -28,30 +28,37 @@ int nf_register_queue_handler(int pf, struct nf_queue_handler *qh)
        if (pf >= NPROTO)
                return -EINVAL;
 
-       write_lock_bh(&queue_handler_lock);
+       mutex_lock(&queue_handler_mutex);
        if (queue_handler[pf] == qh)
                ret = -EEXIST;
        else if (queue_handler[pf])
                ret = -EBUSY;
        else {
-               queue_handler[pf] = qh;
+               rcu_assign_pointer(queue_handler[pf], qh);
                ret = 0;
        }
-       write_unlock_bh(&queue_handler_lock);
+       mutex_unlock(&queue_handler_mutex);
 
        return ret;
 }
 EXPORT_SYMBOL(nf_register_queue_handler);
 
 /* The caller must flush their queue before this */
-int nf_unregister_queue_handler(int pf)
+int nf_unregister_queue_handler(int pf, struct nf_queue_handler *qh)
 {
        if (pf >= NPROTO)
                return -EINVAL;
 
-       write_lock_bh(&queue_handler_lock);
-       queue_handler[pf] = NULL;
-       write_unlock_bh(&queue_handler_lock);
+       mutex_lock(&queue_handler_mutex);
+       if (queue_handler[pf] != qh) {
+               mutex_unlock(&queue_handler_mutex);
+               return -EINVAL;
+       }
+
+       rcu_assign_pointer(queue_handler[pf], NULL);
+       mutex_unlock(&queue_handler_mutex);
+
+       synchronize_rcu();
 
        return 0;
 }
@@ -61,12 +68,14 @@ void nf_unregister_queue_handlers(struct nf_queue_handler *qh)
 {
        int pf;
 
-       write_lock_bh(&queue_handler_lock);
+       mutex_lock(&queue_handler_mutex);
        for (pf = 0; pf < NPROTO; pf++)  {
                if (queue_handler[pf] == qh)
-                       queue_handler[pf] = NULL;
+                       rcu_assign_pointer(queue_handler[pf], NULL);
        }
-       write_unlock_bh(&queue_handler_lock);
+       mutex_unlock(&queue_handler_mutex);
+
+       synchronize_rcu();
 }
 EXPORT_SYMBOL_GPL(nf_unregister_queue_handlers);
 
@@ -89,18 +98,21 @@ static int __nf_queue(struct sk_buff *skb,
        struct net_device *physoutdev = NULL;
 #endif
        struct nf_afinfo *afinfo;
+       struct nf_queue_handler *qh;
 
        /* QUEUE == DROP if noone is waiting, to be safe. */
-       read_lock(&queue_handler_lock);
-       if (!queue_handler[pf]) {
-               read_unlock(&queue_handler_lock);
+       rcu_read_lock();
+
+       qh = rcu_dereference(queue_handler[pf]);
+       if (!qh) {
+               rcu_read_unlock();
                kfree_skb(skb);
                return 1;
        }
 
        afinfo = nf_get_afinfo(pf);
        if (!afinfo) {
-               read_unlock(&queue_handler_lock);
+               rcu_read_unlock();
                kfree_skb(skb);
                return 1;
        }
@@ -110,7 +122,7 @@ static int __nf_queue(struct sk_buff *skb,
                if (net_ratelimit())
                        printk(KERN_ERR "OOM queueing packet %p\n",
                               skb);
-               read_unlock(&queue_handler_lock);
+               rcu_read_unlock();
                kfree_skb(skb);
                return 1;
        }
@@ -120,7 +132,7 @@ static int __nf_queue(struct sk_buff *skb,
 
        /* If it's going away, ignore hook. */
        if (!try_module_get(info->elem->owner)) {
-               read_unlock(&queue_handler_lock);
+               rcu_read_unlock();
                kfree(info);
                return 0;
        }
@@ -138,10 +150,9 @@ static int __nf_queue(struct sk_buff *skb,
        }
 #endif
        afinfo->saveroute(skb, info);
-       status = queue_handler[pf]->outfn(skb, info, queuenum,
-                                         queue_handler[pf]->data);
+       status = qh->outfn(skb, info, queuenum, qh->data);
 
-       read_unlock(&queue_handler_lock);
+       rcu_read_unlock();
 
        if (status < 0) {
                /* James M doesn't say fuck enough. */
@@ -308,18 +319,18 @@ static int seq_show(struct seq_file *s, void *v)
        loff_t *pos = v;
        struct nf_queue_handler *qh;
 
-       read_lock_bh(&queue_handler_lock);
-       qh = queue_handler[*pos];
+       rcu_read_lock();
+       qh = rcu_dereference(queue_handler[*pos]);
        if (!qh)
                ret = seq_printf(s, "%2lld NONE\n", *pos);
        else
                ret = seq_printf(s, "%2lld %s\n", *pos, qh->name);
-       read_unlock_bh(&queue_handler_lock);
+       rcu_read_unlock();
 
        return ret;
 }
 
-static struct seq_operations nfqueue_seq_ops = {
+static const struct seq_operations nfqueue_seq_ops = {
        .start  = seq_start,
        .next   = seq_next,
        .stop   = seq_stop,
index e32e30e7a17caeec6d1a21841045ab5ff92b6586..e185a5b55913ce8b37af7de85b5e9a9f8b46f2e1 100644 (file)
@@ -962,7 +962,7 @@ static int seq_show(struct seq_file *s, void *v)
                          inst->flushtimeout, atomic_read(&inst->use));
 }
 
-static struct seq_operations nful_seq_ops = {
+static const struct seq_operations nful_seq_ops = {
        .start  = seq_start,
        .next   = seq_next,
        .stop   = seq_stop,
index 7a97bec67729a3f258cdbc24425790a774feaf2c..bb65a38c816c79d88561feaacaa6734df57a6a5e 100644 (file)
@@ -913,9 +913,7 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
                case NFQNL_CFG_CMD_PF_UNBIND:
                        QDEBUG("unregistering queue handler for pf=%u\n",
                                ntohs(cmd->pf));
-                       /* This is a bug and a feature.  We can unregister
-                        * other handlers(!) */
-                       ret = nf_unregister_queue_handler(ntohs(cmd->pf));
+                       ret = nf_unregister_queue_handler(ntohs(cmd->pf), &nfqh);
                        break;
                default:
                        ret = -EINVAL;
@@ -1050,7 +1048,7 @@ static int seq_show(struct seq_file *s, void *v)
                          atomic_read(&inst->use));
 }
 
-static struct seq_operations nfqnl_seq_ops = {
+static const struct seq_operations nfqnl_seq_ops = {
        .start  = seq_start,
        .next   = seq_next,
        .stop   = seq_stop,
index 0eb2504b89b5583d6283c1a9806107998d985813..cc2baa6d5a7ac5d75d6a9ec3686e755787dc64ff 100644 (file)
@@ -320,8 +320,8 @@ int xt_check_match(const struct xt_match *match, unsigned short family,
                return -EINVAL;
        }
        if (match->hooks && (hook_mask & ~match->hooks) != 0) {
-               printk("%s_tables: %s match: bad hook_mask %u\n",
-                      xt_prefix[family], match->name, hook_mask);
+               printk("%s_tables: %s match: bad hook_mask %u/%u\n",
+                      xt_prefix[family], match->name, hook_mask, match->hooks);
                return -EINVAL;
        }
        if (match->proto && (match->proto != proto || inv_proto)) {
@@ -410,8 +410,9 @@ int xt_check_target(const struct xt_target *target, unsigned short family,
                return -EINVAL;
        }
        if (target->hooks && (hook_mask & ~target->hooks) != 0) {
-               printk("%s_tables: %s target: bad hook_mask %u\n",
-                      xt_prefix[family], target->name, hook_mask);
+               printk("%s_tables: %s target: bad hook_mask %u/%u\n",
+                      xt_prefix[family], target->name, hook_mask,
+                      target->hooks);
                return -EINVAL;
        }
        if (target->proto && (target->proto != proto || inv_proto)) {
@@ -744,7 +745,7 @@ static int xt_name_seq_show(struct seq_file *seq, void *v)
                return 0;
 }
 
-static struct seq_operations xt_tgt_seq_ops = {
+static const struct seq_operations xt_tgt_seq_ops = {
        .start  = xt_tgt_seq_start,
        .next   = xt_tgt_seq_next,
        .stop   = xt_tgt_seq_stop,
index 30884833e665b6d7cb721dcb1b4c6015418d84ec..5194285668299d077070d67c0db05091f1e4a0f9 100644 (file)
@@ -39,7 +39,7 @@ target(struct sk_buff **pskb,
        return XT_CONTINUE;
 }
 
-static struct xt_target xt_classify_target[] = {
+static struct xt_target xt_classify_target[] __read_mostly = {
        {
                .family         = AF_INET,
                .name           = "CLASSIFY",
index b03ce009d0bf0f267af5e154086c3418cd5989d6..5a00c5444334fe926bd2a8bc995493c1bea574a0 100644 (file)
@@ -76,33 +76,33 @@ target(struct sk_buff **pskb,
        return XT_CONTINUE;
 }
 
-static int
+static bool
 checkentry(const char *tablename,
           const void *entry,
           const struct xt_target *target,
           void *targinfo,
           unsigned int hook_mask)
 {
-       struct xt_connmark_target_info *matchinfo = targinfo;
+       const struct xt_connmark_target_info *matchinfo = targinfo;
 
        if (nf_ct_l3proto_try_module_get(target->family) < 0) {
                printk(KERN_WARNING "can't load conntrack support for "
                                    "proto=%d\n", target->family);
-               return 0;
+               return false;
        }
        if (matchinfo->mode == XT_CONNMARK_RESTORE) {
                if (strcmp(tablename, "mangle") != 0) {
                        printk(KERN_WARNING "CONNMARK: restore can only be "
                               "called from \"mangle\" table, not \"%s\"\n",
                               tablename);
-                       return 0;
+                       return false;
                }
        }
        if (matchinfo->mark > 0xffffffff || matchinfo->mask > 0xffffffff) {
                printk(KERN_WARNING "CONNMARK: Only supports 32bit mark\n");
-               return 0;
+               return false;
        }
-       return 1;
+       return true;
 }
 
 static void
@@ -121,7 +121,7 @@ struct compat_xt_connmark_target_info {
 
 static void compat_from_user(void *dst, void *src)
 {
-       struct compat_xt_connmark_target_info *cm = src;
+       const struct compat_xt_connmark_target_info *cm = src;
        struct xt_connmark_target_info m = {
                .mark   = cm->mark,
                .mask   = cm->mask,
@@ -132,7 +132,7 @@ static void compat_from_user(void *dst, void *src)
 
 static int compat_to_user(void __user *dst, void *src)
 {
-       struct xt_connmark_target_info *m = src;
+       const struct xt_connmark_target_info *m = src;
        struct compat_xt_connmark_target_info cm = {
                .mark   = m->mark,
                .mask   = m->mask,
@@ -142,7 +142,7 @@ static int compat_to_user(void __user *dst, void *src)
 }
 #endif /* CONFIG_COMPAT */
 
-static struct xt_target xt_connmark_target[] = {
+static struct xt_target xt_connmark_target[] __read_mostly = {
        {
                .name           = "CONNMARK",
                .family         = AF_INET,
index 81c0c58bab4755bb45973f976bfff77ce2b524f6..63d73138c1b9e6482908a39ad3f1e1e7ceeb5295 100644 (file)
@@ -33,7 +33,7 @@ MODULE_ALIAS("ip6t_CONNSECMARK");
  * If the packet has a security mark and the connection does not, copy
  * the security mark from the packet to the connection.
  */
-static void secmark_save(struct sk_buff *skb)
+static void secmark_save(const struct sk_buff *skb)
 {
        if (skb->secmark) {
                struct nf_conn *ct;
@@ -85,16 +85,16 @@ static unsigned int target(struct sk_buff **pskb, const struct net_device *in,
        return XT_CONTINUE;
 }
 
-static int checkentry(const char *tablename, const void *entry,
-                     const struct xt_target *target, void *targinfo,
-                     unsigned int hook_mask)
+static bool checkentry(const char *tablename, const void *entry,
+                      const struct xt_target *target, void *targinfo,
+                      unsigned int hook_mask)
 {
-       struct xt_connsecmark_target_info *info = targinfo;
+       const struct xt_connsecmark_target_info *info = targinfo;
 
        if (nf_ct_l3proto_try_module_get(target->family) < 0) {
                printk(KERN_WARNING "can't load conntrack support for "
                                    "proto=%d\n", target->family);
-               return 0;
+               return false;
        }
        switch (info->mode) {
        case CONNSECMARK_SAVE:
@@ -103,10 +103,10 @@ static int checkentry(const char *tablename, const void *entry,
 
        default:
                printk(KERN_INFO PFX "invalid mode: %hu\n", info->mode);
-               return 0;
+               return false;
        }
 
-       return 1;
+       return true;
 }
 
 static void
@@ -115,7 +115,7 @@ destroy(const struct xt_target *target, void *targinfo)
        nf_ct_l3proto_module_put(target->family);
 }
 
-static struct xt_target xt_connsecmark_target[] = {
+static struct xt_target xt_connsecmark_target[] __read_mostly = {
        {
                .name           = "CONNSECMARK",
                .family         = AF_INET,
index 9f2f2201f6aeaed781b754c2cfb593608149594b..798ab731009d8e97ceb3a2caf4d479abf26dd7db 100644 (file)
@@ -66,22 +66,22 @@ static unsigned int target6(struct sk_buff **pskb,
        return XT_CONTINUE;
 }
 
-static int checkentry(const char *tablename,
-                     const void *e_void,
-                     const struct xt_target *target,
-                     void *targinfo,
-                     unsigned int hook_mask)
+static bool checkentry(const char *tablename,
+                      const void *e_void,
+                      const struct xt_target *target,
+                      void *targinfo,
+                      unsigned int hook_mask)
 {
        const u_int8_t dscp = ((struct xt_DSCP_info *)targinfo)->dscp;
 
-       if ((dscp > XT_DSCP_MAX)) {
+       if (dscp > XT_DSCP_MAX) {
                printk(KERN_WARNING "DSCP: dscp %x out of range\n", dscp);
-               return 0;
+               return false;
        }
-       return 1;
+       return true;
 }
 
-static struct xt_target xt_dscp_target[] = {
+static struct xt_target xt_dscp_target[] __read_mostly = {
        {
                .name           = "DSCP",
                .family         = AF_INET,
index 43817808d865daa2d85411c3df0a57710542f6f4..f30fe0baf7deba176509e36a58bdfc95e6345dda 100644 (file)
@@ -65,43 +65,43 @@ target_v1(struct sk_buff **pskb,
 }
 
 
-static int
+static bool
 checkentry_v0(const char *tablename,
              const void *entry,
              const struct xt_target *target,
              void *targinfo,
              unsigned int hook_mask)
 {
-       struct xt_mark_target_info *markinfo = targinfo;
+       const struct xt_mark_target_info *markinfo = targinfo;
 
        if (markinfo->mark > 0xffffffff) {
                printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n");
-               return 0;
+               return false;
        }
-       return 1;
+       return true;
 }
 
-static int
+static bool
 checkentry_v1(const char *tablename,
              const void *entry,
              const struct xt_target *target,
              void *targinfo,
              unsigned int hook_mask)
 {
-       struct xt_mark_target_info_v1 *markinfo = targinfo;
+       const struct xt_mark_target_info_v1 *markinfo = targinfo;
 
        if (markinfo->mode != XT_MARK_SET
            && markinfo->mode != XT_MARK_AND
            && markinfo->mode != XT_MARK_OR) {
                printk(KERN_WARNING "MARK: unknown mode %u\n",
                       markinfo->mode);
-               return 0;
+               return false;
        }
        if (markinfo->mark > 0xffffffff) {
                printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n");
-               return 0;
+               return false;
        }
-       return 1;
+       return true;
 }
 
 #ifdef CONFIG_COMPAT
@@ -114,7 +114,7 @@ struct compat_xt_mark_target_info_v1 {
 
 static void compat_from_user_v1(void *dst, void *src)
 {
-       struct compat_xt_mark_target_info_v1 *cm = src;
+       const struct compat_xt_mark_target_info_v1 *cm = src;
        struct xt_mark_target_info_v1 m = {
                .mark   = cm->mark,
                .mode   = cm->mode,
@@ -124,7 +124,7 @@ static void compat_from_user_v1(void *dst, void *src)
 
 static int compat_to_user_v1(void __user *dst, void *src)
 {
-       struct xt_mark_target_info_v1 *m = src;
+       const struct xt_mark_target_info_v1 *m = src;
        struct compat_xt_mark_target_info_v1 cm = {
                .mark   = m->mark,
                .mode   = m->mode,
@@ -133,7 +133,7 @@ static int compat_to_user_v1(void __user *dst, void *src)
 }
 #endif /* CONFIG_COMPAT */
 
-static struct xt_target xt_mark_target[] = {
+static struct xt_target xt_mark_target[] __read_mostly = {
        {
                .name           = "MARK",
                .family         = AF_INET,
index 901ed7abaa1bcf433f90bb3123a77d4bcd3ee57b..d3594c7ccb268b4c49577c828f77a86b5d2b6db8 100644 (file)
@@ -38,21 +38,21 @@ nflog_target(struct sk_buff **pskb,
        return XT_CONTINUE;
 }
 
-static int
+static bool
 nflog_checkentry(const char *tablename, const void *entry,
                 const struct xt_target *target, void *targetinfo,
                 unsigned int hookmask)
 {
-       struct xt_nflog_info *info = targetinfo;
+       const struct xt_nflog_info *info = targetinfo;
 
        if (info->flags & ~XT_NFLOG_MASK)
-               return 0;
+               return false;
        if (info->prefix[sizeof(info->prefix) - 1] != '\0')
-               return 0;
-       return 1;
+               return false;
+       return true;
 }
 
-static struct xt_target xt_nflog_target[] = {
+static struct xt_target xt_nflog_target[] __read_mostly = {
        {
                .name           = "NFLOG",
                .family         = AF_INET,
index 201155b316e0a8452c0e986b309c70d8a1ef219e..13f59f3e8c3814db0f820720794146ffdda74366 100644 (file)
@@ -36,7 +36,7 @@ target(struct sk_buff **pskb,
        return NF_QUEUE_NR(tinfo->queuenum);
 }
 
-static struct xt_target xt_nfqueue_target[] = {
+static struct xt_target xt_nfqueue_target[] __read_mostly = {
        {
                .name           = "NFQUEUE",
                .family         = AF_INET,
index 5085fb3d1e2d292476c8ab690acbb98b9e560b88..b7d6312fccc72b13606d6642103bf84c97326a52 100644 (file)
@@ -33,7 +33,7 @@ target(struct sk_buff **pskb,
        return XT_CONTINUE;
 }
 
-static struct xt_target xt_notrack_target[] = {
+static struct xt_target xt_notrack_target[] __read_mostly = {
        {
                .name           = "NOTRACK",
                .family         = AF_INET,
index 705f0e830a79576d73529964523eb40bfc7f1c68..c83779a941a18c3dd2e889e221266d22713a615d 100644 (file)
@@ -51,7 +51,7 @@ static unsigned int target(struct sk_buff **pskb, const struct net_device *in,
        return XT_CONTINUE;
 }
 
-static int checkentry_selinux(struct xt_secmark_target_info *info)
+static bool checkentry_selinux(struct xt_secmark_target_info *info)
 {
        int err;
        struct xt_secmark_target_selinux_info *sel = &info->u.sel;
@@ -63,53 +63,53 @@ static int checkentry_selinux(struct xt_secmark_target_info *info)
                if (err == -EINVAL)
                        printk(KERN_INFO PFX "invalid SELinux context \'%s\'\n",
                               sel->selctx);
-               return 0;
+               return false;
        }
 
        if (!sel->selsid) {
                printk(KERN_INFO PFX "unable to map SELinux context \'%s\'\n",
                       sel->selctx);
-               return 0;
+               return false;
        }
 
        err = selinux_relabel_packet_permission(sel->selsid);
        if (err) {
                printk(KERN_INFO PFX "unable to obtain relabeling permission\n");
-               return 0;
+               return false;
        }
 
-       return 1;
+       return true;
 }
 
-static int checkentry(const char *tablename, const void *entry,
-                     const struct xt_target *target, void *targinfo,
-                     unsigned int hook_mask)
+static bool checkentry(const char *tablename, const void *entry,
+                      const struct xt_target *target, void *targinfo,
+                      unsigned int hook_mask)
 {
        struct xt_secmark_target_info *info = targinfo;
 
        if (mode && mode != info->mode) {
                printk(KERN_INFO PFX "mode already set to %hu cannot mix with "
                       "rules for mode %hu\n", mode, info->mode);
-               return 0;
+               return false;
        }
 
        switch (info->mode) {
        case SECMARK_MODE_SEL:
                if (!checkentry_selinux(info))
-                       return 0;
+                       return false;
                break;
 
        default:
                printk(KERN_INFO PFX "invalid mode: %hu\n", info->mode);
-               return 0;
+               return false;
        }
 
        if (!mode)
                mode = info->mode;
-       return 1;
+       return true;
 }
 
-static struct xt_target xt_secmark_target[] = {
+static struct xt_target xt_secmark_target[] __read_mostly = {
        {
                .name           = "SECMARK",
                .family         = AF_INET,
index 15fe8f649510398f6df0e7c2e665fd28b0b0fd47..d40f7e4b1289362f142afaa17a15f424bae30499 100644 (file)
@@ -93,7 +93,7 @@ tcpmss_mangle_packet(struct sk_buff **pskb,
                                return 0;
 
                        opt[i+2] = (newmss & 0xff00) >> 8;
-                       opt[i+3] = (newmss & 0x00ff);
+                       opt[i+3] = newmss & 0x00ff;
 
                        nf_proto_csum_replace2(&tcph->check, *pskb,
                                               htons(oldmss), htons(newmss), 0);
@@ -126,7 +126,7 @@ tcpmss_mangle_packet(struct sk_buff **pskb,
        opt[0] = TCPOPT_MSS;
        opt[1] = TCPOLEN_MSS;
        opt[2] = (newmss & 0xff00) >> 8;
-       opt[3] = (newmss & 0x00ff);
+       opt[3] = newmss & 0x00ff;
 
        nf_proto_csum_replace4(&tcph->check, *pskb, 0, *((__be32 *)opt), 0);
 
@@ -197,19 +197,19 @@ xt_tcpmss_target6(struct sk_buff **pskb,
 #define TH_SYN 0x02
 
 /* Must specify -p tcp --syn */
-static inline int find_syn_match(const struct xt_entry_match *m)
+static inline bool find_syn_match(const struct xt_entry_match *m)
 {
        const struct xt_tcp *tcpinfo = (const struct xt_tcp *)m->data;
 
        if (strcmp(m->u.kernel.match->name, "tcp") == 0 &&
            tcpinfo->flg_cmp & TH_SYN &&
            !(tcpinfo->invflags & XT_TCP_INV_FLAGS))
-               return 1;
+               return true;
 
-       return 0;
+       return false;
 }
 
-static int
+static bool
 xt_tcpmss_checkentry4(const char *tablename,
                      const void *entry,
                      const struct xt_target *target,
@@ -225,16 +225,16 @@ xt_tcpmss_checkentry4(const char *tablename,
                           (1 << NF_IP_POST_ROUTING))) != 0) {
                printk("xt_TCPMSS: path-MTU clamping only supported in "
                       "FORWARD, OUTPUT and POSTROUTING hooks\n");
-               return 0;
+               return false;
        }
        if (IPT_MATCH_ITERATE(e, find_syn_match))
-               return 1;
+               return true;
        printk("xt_TCPMSS: Only works on TCP SYN packets\n");
-       return 0;
+       return false;
 }
 
 #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
-static int
+static bool
 xt_tcpmss_checkentry6(const char *tablename,
                      const void *entry,
                      const struct xt_target *target,
@@ -250,16 +250,16 @@ xt_tcpmss_checkentry6(const char *tablename,
                           (1 << NF_IP6_POST_ROUTING))) != 0) {
                printk("xt_TCPMSS: path-MTU clamping only supported in "
                       "FORWARD, OUTPUT and POSTROUTING hooks\n");
-               return 0;
+               return false;
        }
        if (IP6T_MATCH_ITERATE(e, find_syn_match))
-               return 1;
+               return true;
        printk("xt_TCPMSS: Only works on TCP SYN packets\n");
-       return 0;
+       return false;
 }
 #endif
 
-static struct xt_target xt_tcpmss_reg[] = {
+static struct xt_target xt_tcpmss_reg[] __read_mostly = {
        {
                .family         = AF_INET,
                .name           = "TCPMSS",
diff --git a/net/netfilter/xt_TRACE.c b/net/netfilter/xt_TRACE.c
new file mode 100644 (file)
index 0000000..4df2ded
--- /dev/null
@@ -0,0 +1,53 @@
+/* This is a module which is used to mark packets for tracing.
+ */
+#include <linux/module.h>
+#include <linux/skbuff.h>
+
+#include <linux/netfilter/x_tables.h>
+
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("ipt_TRACE");
+MODULE_ALIAS("ip6t_TRACE");
+
+static unsigned int
+target(struct sk_buff **pskb,
+       const struct net_device *in,
+       const struct net_device *out,
+       unsigned int hooknum,
+       const struct xt_target *target,
+       const void *targinfo)
+{
+       (*pskb)->nf_trace = 1;
+       return XT_CONTINUE;
+}
+
+static struct xt_target xt_trace_target[] __read_mostly = {
+       {
+               .name           = "TRACE",
+               .family         = AF_INET,
+               .target         = target,
+               .table          = "raw",
+               .me             = THIS_MODULE,
+       },
+       {
+               .name           = "TRACE",
+               .family         = AF_INET6,
+               .target         = target,
+               .table          = "raw",
+               .me             = THIS_MODULE,
+       },
+};
+
+static int __init xt_trace_init(void)
+{
+       return xt_register_targets(xt_trace_target,
+                                  ARRAY_SIZE(xt_trace_target));
+}
+
+static void __exit xt_trace_fini(void)
+{
+       xt_unregister_targets(xt_trace_target, ARRAY_SIZE(xt_trace_target));
+}
+
+module_init(xt_trace_init);
+module_exit(xt_trace_fini);
index 7db492d652203af3441089d3017a7b3101bb28a5..64bcdb0fe1e6797d7687fda7dc481478f377164d 100644 (file)
@@ -15,7 +15,7 @@ MODULE_LICENSE("GPL");
 MODULE_ALIAS("ipt_comment");
 MODULE_ALIAS("ip6t_comment");
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -23,13 +23,13 @@ match(const struct sk_buff *skb,
       const void *matchinfo,
       int offset,
       unsigned int protooff,
-      int *hotdrop)
+      bool *hotdrop)
 {
        /* We always match */
-       return 1;
+       return true;
 }
 
-static struct xt_match xt_comment_match[] = {
+static struct xt_match xt_comment_match[] __read_mostly = {
        {
                .name           = "comment",
                .family         = AF_INET,
index 804afe55e141302d026bb29316dc90b28eee9fa6..dd4d79b8fc9d20ced45ef0cfc8204569fe9492da 100644 (file)
@@ -15,7 +15,7 @@ MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
 MODULE_DESCRIPTION("iptables match for matching number of pkts/bytes per connection");
 MODULE_ALIAS("ipt_connbytes");
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -23,10 +23,10 @@ match(const struct sk_buff *skb,
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
        const struct xt_connbytes_info *sinfo = matchinfo;
-       struct nf_conn *ct;
+       const struct nf_conn *ct;
        enum ip_conntrack_info ctinfo;
        u_int64_t what = 0;     /* initialize to make gcc happy */
        u_int64_t bytes = 0;
@@ -35,7 +35,7 @@ match(const struct sk_buff *skb,
 
        ct = nf_ct_get(skb, &ctinfo);
        if (!ct)
-               return 0;
+               return false;
        counters = ct->counters;
 
        switch (sinfo->what) {
@@ -90,36 +90,36 @@ match(const struct sk_buff *skb,
        }
 
        if (sinfo->count.to)
-               return (what <= sinfo->count.to && what >= sinfo->count.from);
+               return what <= sinfo->count.to && what >= sinfo->count.from;
        else
-               return (what >= sinfo->count.from);
+               return what >= sinfo->count.from;
 }
 
-static int check(const char *tablename,
-                const void *ip,
-                const struct xt_match *match,
-                void *matchinfo,
-                unsigned int hook_mask)
+static bool check(const char *tablename,
+                 const void *ip,
+                 const struct xt_match *match,
+                 void *matchinfo,
+                 unsigned int hook_mask)
 {
        const struct xt_connbytes_info *sinfo = matchinfo;
 
        if (sinfo->what != XT_CONNBYTES_PKTS &&
            sinfo->what != XT_CONNBYTES_BYTES &&
            sinfo->what != XT_CONNBYTES_AVGPKT)
-               return 0;
+               return false;
 
        if (sinfo->direction != XT_CONNBYTES_DIR_ORIGINAL &&
            sinfo->direction != XT_CONNBYTES_DIR_REPLY &&
            sinfo->direction != XT_CONNBYTES_DIR_BOTH)
-               return 0;
+               return false;
 
        if (nf_ct_l3proto_try_module_get(match->family) < 0) {
                printk(KERN_WARNING "can't load conntrack support for "
                                    "proto=%d\n", match->family);
-               return 0;
+               return false;
        }
 
-       return 1;
+       return true;
 }
 
 static void
@@ -128,7 +128,7 @@ destroy(const struct xt_match *match, void *matchinfo)
        nf_ct_l3proto_module_put(match->family);
 }
 
-static struct xt_match xt_connbytes_match[] = {
+static struct xt_match xt_connbytes_match[] __read_mostly = {
        {
                .name           = "connbytes",
                .family         = AF_INET,
index e1803256c7924d45bba87ddd0209c51a2989ca9b..e73fa9b46cf7d1a747077c333e92d7ad0809140f 100644 (file)
@@ -30,7 +30,7 @@ MODULE_DESCRIPTION("IP tables connmark match module");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("ipt_connmark");
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -38,38 +38,38 @@ match(const struct sk_buff *skb,
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
        const struct xt_connmark_info *info = matchinfo;
-       struct nf_conn *ct;
+       const struct nf_conn *ct;
        enum ip_conntrack_info ctinfo;
 
        ct = nf_ct_get(skb, &ctinfo);
        if (!ct)
-               return 0;
+               return false;
 
-       return (((ct->mark) & info->mask) == info->mark) ^ info->invert;
+       return ((ct->mark & info->mask) == info->mark) ^ info->invert;
 }
 
-static int
+static bool
 checkentry(const char *tablename,
           const void *ip,
           const struct xt_match *match,
           void *matchinfo,
           unsigned int hook_mask)
 {
-       struct xt_connmark_info *cm = matchinfo;
+       const struct xt_connmark_info *cm = matchinfo;
 
        if (cm->mark > 0xffffffff || cm->mask > 0xffffffff) {
                printk(KERN_WARNING "connmark: only support 32bit mark\n");
-               return 0;
+               return false;
        }
        if (nf_ct_l3proto_try_module_get(match->family) < 0) {
                printk(KERN_WARNING "can't load conntrack support for "
                                    "proto=%d\n", match->family);
-               return 0;
+               return false;
        }
-       return 1;
+       return true;
 }
 
 static void
@@ -88,7 +88,7 @@ struct compat_xt_connmark_info {
 
 static void compat_from_user(void *dst, void *src)
 {
-       struct compat_xt_connmark_info *cm = src;
+       const struct compat_xt_connmark_info *cm = src;
        struct xt_connmark_info m = {
                .mark   = cm->mark,
                .mask   = cm->mask,
@@ -99,7 +99,7 @@ static void compat_from_user(void *dst, void *src)
 
 static int compat_to_user(void __user *dst, void *src)
 {
-       struct xt_connmark_info *m = src;
+       const struct xt_connmark_info *m = src;
        struct compat_xt_connmark_info cm = {
                .mark   = m->mark,
                .mask   = m->mask,
@@ -109,7 +109,7 @@ static int compat_to_user(void __user *dst, void *src)
 }
 #endif /* CONFIG_COMPAT */
 
-static struct xt_match xt_connmark_match[] = {
+static struct xt_match xt_connmark_match[] __read_mostly = {
        {
                .name           = "connmark",
                .family         = AF_INET,
index 189ded5f378bb100035e6d5b69770f9d8577b52e..ca4b69f020a8a1eb608f395d9b82d05fb07340a5 100644 (file)
@@ -19,7 +19,7 @@ MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
 MODULE_DESCRIPTION("iptables connection tracking match module");
 MODULE_ALIAS("ipt_conntrack");
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -27,14 +27,14 @@ match(const struct sk_buff *skb,
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
        const struct xt_conntrack_info *sinfo = matchinfo;
-       struct nf_conn *ct;
+       const struct nf_conn *ct;
        enum ip_conntrack_info ctinfo;
        unsigned int statebit;
 
-       ct = nf_ct_get((struct sk_buff *)skb, &ctinfo);
+       ct = nf_ct_get(skb, &ctinfo);
 
 #define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg))
 
@@ -54,53 +54,53 @@ match(const struct sk_buff *skb,
                }
                if (FWINV((statebit & sinfo->statemask) == 0,
                          XT_CONNTRACK_STATE))
-                       return 0;
+                       return false;
        }
 
        if (ct == NULL) {
                if (sinfo->flags & ~XT_CONNTRACK_STATE)
-                       return 0;
-               return 1;
+                       return false;
+               return true;
        }
 
        if (sinfo->flags & XT_CONNTRACK_PROTO &&
            FWINV(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum !=
                  sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum,
                  XT_CONNTRACK_PROTO))
-               return 0;
+               return false;
 
        if (sinfo->flags & XT_CONNTRACK_ORIGSRC &&
            FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip &
                   sinfo->sipmsk[IP_CT_DIR_ORIGINAL].s_addr) !=
                  sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip,
                  XT_CONNTRACK_ORIGSRC))
-               return 0;
+               return false;
 
        if (sinfo->flags & XT_CONNTRACK_ORIGDST &&
            FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip &
                   sinfo->dipmsk[IP_CT_DIR_ORIGINAL].s_addr) !=
                  sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip,
                  XT_CONNTRACK_ORIGDST))
-               return 0;
+               return false;
 
        if (sinfo->flags & XT_CONNTRACK_REPLSRC &&
            FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip &
                   sinfo->sipmsk[IP_CT_DIR_REPLY].s_addr) !=
                  sinfo->tuple[IP_CT_DIR_REPLY].src.ip,
                  XT_CONNTRACK_REPLSRC))
-               return 0;
+               return false;
 
        if (sinfo->flags & XT_CONNTRACK_REPLDST &&
            FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip &
                   sinfo->dipmsk[IP_CT_DIR_REPLY].s_addr) !=
                  sinfo->tuple[IP_CT_DIR_REPLY].dst.ip,
                  XT_CONNTRACK_REPLDST))
-               return 0;
+               return false;
 
        if (sinfo->flags & XT_CONNTRACK_STATUS &&
            FWINV((ct->status & sinfo->statusmask) == 0,
                  XT_CONNTRACK_STATUS))
-               return 0;
+               return false;
 
        if(sinfo->flags & XT_CONNTRACK_EXPIRES) {
                unsigned long expires = timer_pending(&ct->timeout) ?
@@ -109,12 +109,12 @@ match(const struct sk_buff *skb,
                if (FWINV(!(expires >= sinfo->expires_min &&
                            expires <= sinfo->expires_max),
                          XT_CONNTRACK_EXPIRES))
-                       return 0;
+                       return false;
        }
-       return 1;
+       return true;
 }
 
-static int
+static bool
 checkentry(const char *tablename,
           const void *ip,
           const struct xt_match *match,
@@ -124,9 +124,9 @@ checkentry(const char *tablename,
        if (nf_ct_l3proto_try_module_get(match->family) < 0) {
                printk(KERN_WARNING "can't load conntrack support for "
                                    "proto=%d\n", match->family);
-               return 0;
+               return false;
        }
-       return 1;
+       return true;
 }
 
 static void destroy(const struct xt_match *match, void *matchinfo)
@@ -150,7 +150,7 @@ struct compat_xt_conntrack_info
 
 static void compat_from_user(void *dst, void *src)
 {
-       struct compat_xt_conntrack_info *cm = src;
+       const struct compat_xt_conntrack_info *cm = src;
        struct xt_conntrack_info m = {
                .statemask      = cm->statemask,
                .statusmask     = cm->statusmask,
@@ -167,7 +167,7 @@ static void compat_from_user(void *dst, void *src)
 
 static int compat_to_user(void __user *dst, void *src)
 {
-       struct xt_conntrack_info *m = src;
+       const struct xt_conntrack_info *m = src;
        struct compat_xt_conntrack_info cm = {
                .statemask      = m->statemask,
                .statusmask     = m->statusmask,
@@ -183,7 +183,7 @@ static int compat_to_user(void __user *dst, void *src)
 }
 #endif
 
-static struct xt_match conntrack_match = {
+static struct xt_match conntrack_match __read_mostly = {
        .name           = "conntrack",
        .match          = match,
        .checkentry     = checkentry,
index 2c9c0dee8aaf1ea5e5f541748570a1202d0c25ad..83224ec89cc08348205daaf58a7104ea79773e53 100644 (file)
@@ -31,40 +31,40 @@ MODULE_ALIAS("ipt_dccp");
 static unsigned char *dccp_optbuf;
 static DEFINE_SPINLOCK(dccp_buflock);
 
-static inline int
+static inline bool
 dccp_find_option(u_int8_t option,
                 const struct sk_buff *skb,
                 unsigned int protoff,
                 const struct dccp_hdr *dh,
-                int *hotdrop)
+                bool *hotdrop)
 {
        /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */
-       unsigned char *op;
+       const unsigned char *op;
        unsigned int optoff = __dccp_hdr_len(dh);
        unsigned int optlen = dh->dccph_doff*4 - __dccp_hdr_len(dh);
        unsigned int i;
 
        if (dh->dccph_doff * 4 < __dccp_hdr_len(dh)) {
-               *hotdrop = 1;
-               return 0;
+               *hotdrop = true;
+               return false;
        }
 
        if (!optlen)
-               return 0;
+               return false;
 
        spin_lock_bh(&dccp_buflock);
        op = skb_header_pointer(skb, protoff + optoff, optlen, dccp_optbuf);
        if (op == NULL) {
                /* If we don't have the whole header, drop packet. */
                spin_unlock_bh(&dccp_buflock);
-               *hotdrop = 1;
-               return 0;
+               *hotdrop = true;
+               return false;
        }
 
        for (i = 0; i < optlen; ) {
                if (op[i] == option) {
                        spin_unlock_bh(&dccp_buflock);
-                       return 1;
+                       return true;
                }
 
                if (op[i] < 2)
@@ -74,24 +74,24 @@ dccp_find_option(u_int8_t option,
        }
 
        spin_unlock_bh(&dccp_buflock);
-       return 0;
+       return false;
 }
 
 
-static inline int
+static inline bool
 match_types(const struct dccp_hdr *dh, u_int16_t typemask)
 {
-       return (typemask & (1 << dh->dccph_type));
+       return typemask & (1 << dh->dccph_type);
 }
 
-static inline int
+static inline bool
 match_option(u_int8_t option, const struct sk_buff *skb, unsigned int protoff,
-            const struct dccp_hdr *dh, int *hotdrop)
+            const struct dccp_hdr *dh, bool *hotdrop)
 {
        return dccp_find_option(option, skb, protoff, dh, hotdrop);
 }
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -99,25 +99,25 @@ match(const struct sk_buff *skb,
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
        const struct xt_dccp_info *info = matchinfo;
        struct dccp_hdr _dh, *dh;
 
        if (offset)
-               return 0;
+               return false;
 
        dh = skb_header_pointer(skb, protoff, sizeof(_dh), &_dh);
        if (dh == NULL) {
-               *hotdrop = 1;
-               return 0;
+               *hotdrop = true;
+               return false;
        }
 
-       return  DCCHECK(((ntohs(dh->dccph_sport) >= info->spts[0])
-                       && (ntohs(dh->dccph_sport) <= info->spts[1])),
+       return  DCCHECK(ntohs(dh->dccph_sport) >= info->spts[0]
+                       && ntohs(dh->dccph_sport) <= info->spts[1],
                        XT_DCCP_SRC_PORTS, info->flags, info->invflags)
-               && DCCHECK(((ntohs(dh->dccph_dport) >= info->dpts[0])
-                       && (ntohs(dh->dccph_dport) <= info->dpts[1])),
+               && DCCHECK(ntohs(dh->dccph_dport) >= info->dpts[0]
+                       && ntohs(dh->dccph_dport) <= info->dpts[1],
                        XT_DCCP_DEST_PORTS, info->flags, info->invflags)
                && DCCHECK(match_types(dh, info->typemask),
                           XT_DCCP_TYPE, info->flags, info->invflags)
@@ -126,7 +126,7 @@ match(const struct sk_buff *skb,
                           XT_DCCP_OPTION, info->flags, info->invflags);
 }
 
-static int
+static bool
 checkentry(const char *tablename,
           const void *inf,
           const struct xt_match *match,
@@ -140,7 +140,7 @@ checkentry(const char *tablename,
                && !(info->invflags & ~info->flags);
 }
 
-static struct xt_match xt_dccp_match[] = {
+static struct xt_match xt_dccp_match[] __read_mostly = {
        {
                .name           = "dccp",
                .family         = AF_INET,
index 56b247ecc283b7dbc8f546526a80335b24c9dd80..dde6d66e0d338aef43cb80d85afd0b6e6ca62376 100644 (file)
@@ -22,14 +22,14 @@ MODULE_LICENSE("GPL");
 MODULE_ALIAS("ipt_dscp");
 MODULE_ALIAS("ip6t_dscp");
 
-static int match(const struct sk_buff *skb,
-                const struct net_device *in,
-                const struct net_device *out,
-                const struct xt_match *match,
-                const void *matchinfo,
-                int offset,
-                unsigned int protoff,
-                int *hotdrop)
+static bool match(const struct sk_buff *skb,
+                 const struct net_device *in,
+                 const struct net_device *out,
+                 const struct xt_match *match,
+                 const void *matchinfo,
+                 int offset,
+                 unsigned int protoff,
+                 bool *hotdrop)
 {
        const struct xt_dscp_info *info = matchinfo;
        u_int8_t dscp = ipv4_get_dsfield(ip_hdr(skb)) >> XT_DSCP_SHIFT;
@@ -37,14 +37,14 @@ static int match(const struct sk_buff *skb,
        return (dscp == info->dscp) ^ !!info->invert;
 }
 
-static int match6(const struct sk_buff *skb,
-                 const struct net_device *in,
-                 const struct net_device *out,
-                 const struct xt_match *match,
-                 const void *matchinfo,
-                 int offset,
-                 unsigned int protoff,
-                 int *hotdrop)
+static bool match6(const struct sk_buff *skb,
+                  const struct net_device *in,
+                  const struct net_device *out,
+                  const struct xt_match *match,
+                  const void *matchinfo,
+                  int offset,
+                  unsigned int protoff,
+                  bool *hotdrop)
 {
        const struct xt_dscp_info *info = matchinfo;
        u_int8_t dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> XT_DSCP_SHIFT;
@@ -52,23 +52,23 @@ static int match6(const struct sk_buff *skb,
        return (dscp == info->dscp) ^ !!info->invert;
 }
 
-static int checkentry(const char *tablename,
-                     const void *info,
-                     const struct xt_match *match,
-                     void *matchinfo,
-                     unsigned int hook_mask)
+static bool checkentry(const char *tablename,
+                      const void *info,
+                      const struct xt_match *match,
+                      void *matchinfo,
+                      unsigned int hook_mask)
 {
        const u_int8_t dscp = ((struct xt_dscp_info *)matchinfo)->dscp;
 
        if (dscp > XT_DSCP_MAX) {
                printk(KERN_ERR "xt_dscp: dscp %x out of range\n", dscp);
-               return 0;
+               return false;
        }
 
-       return 1;
+       return true;
 }
 
-static struct xt_match xt_dscp_match[] = {
+static struct xt_match xt_dscp_match[] __read_mostly = {
        {
                .name           = "dscp",
                .family         = AF_INET,
index 7c95f149d94265cde8be98136f66ef2b0c2cf199..b11378e001b6acb639873491606a62e16de8217d 100644 (file)
@@ -31,10 +31,10 @@ MODULE_ALIAS("ip6t_esp");
 #endif
 
 /* Returns 1 if the spi is matched by the range, 0 otherwise */
-static inline int
-spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, int invert)
+static inline bool
+spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert)
 {
-       int r = 0;
+       bool r;
        duprintf("esp spi_match:%c 0x%x <= 0x%x <= 0x%x", invert ? '!' : ' ',
                 min, spi, max);
        r = (spi >= min && spi <= max) ^ invert;
@@ -42,7 +42,7 @@ spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, int invert)
        return r;
 }
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -50,14 +50,14 @@ match(const struct sk_buff *skb,
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
        struct ip_esp_hdr _esp, *eh;
        const struct xt_esp *espinfo = matchinfo;
 
        /* Must not be a fragment. */
        if (offset)
-               return 0;
+               return false;
 
        eh = skb_header_pointer(skb, protoff, sizeof(_esp), &_esp);
        if (eh == NULL) {
@@ -65,8 +65,8 @@ match(const struct sk_buff *skb,
                 * can't.  Hence, no choice but to drop.
                 */
                duprintf("Dropping evil ESP tinygram.\n");
-               *hotdrop = 1;
-               return 0;
+               *hotdrop = true;
+               return false;
        }
 
        return spi_match(espinfo->spis[0], espinfo->spis[1], ntohl(eh->spi),
@@ -74,7 +74,7 @@ match(const struct sk_buff *skb,
 }
 
 /* Called when user tries to insert an entry of this type. */
-static int
+static bool
 checkentry(const char *tablename,
           const void *ip_void,
           const struct xt_match *match,
@@ -85,13 +85,13 @@ checkentry(const char *tablename,
 
        if (espinfo->invflags & ~XT_ESP_INV_MASK) {
                duprintf("xt_esp: unknown flags %X\n", espinfo->invflags);
-               return 0;
+               return false;
        }
 
-       return 1;
+       return true;
 }
 
-static struct xt_match xt_esp_match[] = {
+static struct xt_match xt_esp_match[] __read_mostly = {
        {
                .name           = "esp",
                .family         = AF_INET,
index d3043fa32ebc9c30715485299438060e33371fa0..d6b3d01975b6e5664b969e1ce81bb2f11fa2adcb 100644 (file)
@@ -94,7 +94,8 @@ static DEFINE_MUTEX(hlimit_mutex);    /* additional checkentry protection */
 static HLIST_HEAD(hashlimit_htables);
 static struct kmem_cache *hashlimit_cachep __read_mostly;
 
-static inline int dst_cmp(const struct dsthash_ent *ent, struct dsthash_dst *b)
+static inline bool dst_cmp(const struct dsthash_ent *ent,
+                          const struct dsthash_dst *b)
 {
        return !memcmp(&ent->dst, b, sizeof(ent->dst));
 }
@@ -106,7 +107,8 @@ hash_dst(const struct xt_hashlimit_htable *ht, const struct dsthash_dst *dst)
 }
 
 static struct dsthash_ent *
-dsthash_find(const struct xt_hashlimit_htable *ht, struct dsthash_dst *dst)
+dsthash_find(const struct xt_hashlimit_htable *ht,
+            const struct dsthash_dst *dst)
 {
        struct dsthash_ent *ent;
        struct hlist_node *pos;
@@ -122,7 +124,8 @@ dsthash_find(const struct xt_hashlimit_htable *ht, struct dsthash_dst *dst)
 
 /* allocate dsthash_ent, initialize dst, put in htable and lock it */
 static struct dsthash_ent *
-dsthash_alloc_init(struct xt_hashlimit_htable *ht, struct dsthash_dst *dst)
+dsthash_alloc_init(struct xt_hashlimit_htable *ht,
+                  const struct dsthash_dst *dst)
 {
        struct dsthash_ent *ent;
 
@@ -227,19 +230,21 @@ static int htable_create(struct xt_hashlimit_info *minfo, int family)
        return 0;
 }
 
-static int select_all(struct xt_hashlimit_htable *ht, struct dsthash_ent *he)
+static bool select_all(const struct xt_hashlimit_htable *ht,
+                      const struct dsthash_ent *he)
 {
        return 1;
 }
 
-static int select_gc(struct xt_hashlimit_htable *ht, struct dsthash_ent *he)
+static bool select_gc(const struct xt_hashlimit_htable *ht,
+                     const struct dsthash_ent *he)
 {
-       return (jiffies >= he->expires);
+       return jiffies >= he->expires;
 }
 
 static void htable_selective_cleanup(struct xt_hashlimit_htable *ht,
-                               int (*select)(struct xt_hashlimit_htable *ht,
-                                             struct dsthash_ent *he))
+                       bool (*select)(const struct xt_hashlimit_htable *ht,
+                                     const struct dsthash_ent *he))
 {
        unsigned int i;
 
@@ -282,7 +287,8 @@ static void htable_destroy(struct xt_hashlimit_htable *hinfo)
        vfree(hinfo);
 }
 
-static struct xt_hashlimit_htable *htable_find_get(char *name, int family)
+static struct xt_hashlimit_htable *htable_find_get(const char *name,
+                                                  int family)
 {
        struct xt_hashlimit_htable *hinfo;
        struct hlist_node *pos;
@@ -367,7 +373,8 @@ static inline void rateinfo_recalc(struct dsthash_ent *dh, unsigned long now)
 }
 
 static int
-hashlimit_init_dst(struct xt_hashlimit_htable *hinfo, struct dsthash_dst *dst,
+hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo,
+                  struct dsthash_dst *dst,
                   const struct sk_buff *skb, unsigned int protoff)
 {
        __be16 _ports[2], *ports;
@@ -432,7 +439,7 @@ hashlimit_init_dst(struct xt_hashlimit_htable *hinfo, struct dsthash_dst *dst,
        return 0;
 }
 
-static int
+static bool
 hashlimit_match(const struct sk_buff *skb,
                const struct net_device *in,
                const struct net_device *out,
@@ -440,10 +447,10 @@ hashlimit_match(const struct sk_buff *skb,
                const void *matchinfo,
                int offset,
                unsigned int protoff,
-               int *hotdrop)
+               bool *hotdrop)
 {
-       struct xt_hashlimit_info *r =
-               ((struct xt_hashlimit_info *)matchinfo)->u.master;
+       const struct xt_hashlimit_info *r =
+               ((const struct xt_hashlimit_info *)matchinfo)->u.master;
        struct xt_hashlimit_htable *hinfo = r->hinfo;
        unsigned long now = jiffies;
        struct dsthash_ent *dh;
@@ -478,20 +485,20 @@ hashlimit_match(const struct sk_buff *skb,
                /* We're underlimit. */
                dh->rateinfo.credit -= dh->rateinfo.cost;
                spin_unlock_bh(&hinfo->lock);
-               return 1;
+               return true;
        }
 
        spin_unlock_bh(&hinfo->lock);
 
        /* default case: we're overlimit, thus don't match */
-       return 0;
+       return false;
 
 hotdrop:
-       *hotdrop = 1;
-       return 0;
+       *hotdrop = true;
+       return false;
 }
 
-static int
+static bool
 hashlimit_checkentry(const char *tablename,
                     const void *inf,
                     const struct xt_match *match,
@@ -505,20 +512,20 @@ hashlimit_checkentry(const char *tablename,
            user2credits(r->cfg.avg * r->cfg.burst) < user2credits(r->cfg.avg)) {
                printk(KERN_ERR "xt_hashlimit: overflow, try lower: %u/%u\n",
                       r->cfg.avg, r->cfg.burst);
-               return 0;
+               return false;
        }
        if (r->cfg.mode == 0 ||
            r->cfg.mode > (XT_HASHLIMIT_HASH_DPT |
                           XT_HASHLIMIT_HASH_DIP |
                           XT_HASHLIMIT_HASH_SIP |
                           XT_HASHLIMIT_HASH_SPT))
-               return 0;
+               return false;
        if (!r->cfg.gc_interval)
-               return 0;
+               return false;
        if (!r->cfg.expire)
-               return 0;
+               return false;
        if (r->name[sizeof(r->name) - 1] != '\0')
-               return 0;
+               return false;
 
        /* This is the best we've got: We cannot release and re-grab lock,
         * since checkentry() is called before x_tables.c grabs xt_mutex.
@@ -530,19 +537,19 @@ hashlimit_checkentry(const char *tablename,
        r->hinfo = htable_find_get(r->name, match->family);
        if (!r->hinfo && htable_create(r, match->family) != 0) {
                mutex_unlock(&hlimit_mutex);
-               return 0;
+               return false;
        }
        mutex_unlock(&hlimit_mutex);
 
        /* Ugly hack: For SMP, we only want to use one set */
        r->u.master = r;
-       return 1;
+       return true;
 }
 
 static void
 hashlimit_destroy(const struct xt_match *match, void *matchinfo)
 {
-       struct xt_hashlimit_info *r = matchinfo;
+       const struct xt_hashlimit_info *r = matchinfo;
 
        htable_put(r->hinfo);
 }
@@ -571,7 +578,7 @@ static int compat_to_user(void __user *dst, void *src)
 }
 #endif
 
-static struct xt_match xt_hashlimit[] = {
+static struct xt_match xt_hashlimit[] __read_mostly = {
        {
                .name           = "hashlimit",
                .family         = AF_INET,
@@ -694,7 +701,7 @@ static int dl_seq_show(struct seq_file *s, void *v)
        return 0;
 }
 
-static struct seq_operations dl_seq_ops = {
+static const struct seq_operations dl_seq_ops = {
        .start = dl_seq_start,
        .next  = dl_seq_next,
        .stop  = dl_seq_stop,
index c139b2f43a10ca8db25f19b9e54ef983a222fdbd..0a1f4c6bcdef415afae94b369cefb4ab133492bd 100644 (file)
@@ -22,13 +22,8 @@ MODULE_DESCRIPTION("iptables helper match module");
 MODULE_ALIAS("ipt_helper");
 MODULE_ALIAS("ip6t_helper");
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -36,61 +31,51 @@ match(const struct sk_buff *skb,
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
        const struct xt_helper_info *info = matchinfo;
-       struct nf_conn *ct;
-       struct nf_conn_help *master_help;
+       const struct nf_conn *ct;
+       const struct nf_conn_help *master_help;
+       const struct nf_conntrack_helper *helper;
        enum ip_conntrack_info ctinfo;
-       int ret = info->invert;
+       bool ret = info->invert;
 
-       ct = nf_ct_get((struct sk_buff *)skb, &ctinfo);
-       if (!ct) {
-               DEBUGP("xt_helper: Eek! invalid conntrack?\n");
+       ct = nf_ct_get(skb, &ctinfo);
+       if (!ct || !ct->master)
                return ret;
-       }
-
-       if (!ct->master) {
-               DEBUGP("xt_helper: conntrack %p has no master\n", ct);
-               return ret;
-       }
 
-       read_lock_bh(&nf_conntrack_lock);
        master_help = nfct_help(ct->master);
-       if (!master_help || !master_help->helper) {
-               DEBUGP("xt_helper: master ct %p has no helper\n",
-                       exp->expectant);
-               goto out_unlock;
-       }
+       if (!master_help)
+               return ret;
 
-       DEBUGP("master's name = %s , info->name = %s\n",
-               ct->master->helper->name, info->name);
+       /* rcu_read_lock()ed by nf_hook_slow */
+       helper = rcu_dereference(master_help->helper);
+       if (!helper)
+               return ret;
 
        if (info->name[0] == '\0')
-               ret ^= 1;
+               ret = !ret;
        else
                ret ^= !strncmp(master_help->helper->name, info->name,
                                strlen(master_help->helper->name));
-out_unlock:
-       read_unlock_bh(&nf_conntrack_lock);
        return ret;
 }
 
-static int check(const char *tablename,
-                const void *inf,
-                const struct xt_match *match,
-                void *matchinfo,
-                unsigned int hook_mask)
+static bool check(const char *tablename,
+                 const void *inf,
+                 const struct xt_match *match,
+                 void *matchinfo,
+                 unsigned int hook_mask)
 {
        struct xt_helper_info *info = matchinfo;
 
        if (nf_ct_l3proto_try_module_get(match->family) < 0) {
                printk(KERN_WARNING "can't load conntrack support for "
                                    "proto=%d\n", match->family);
-               return 0;
+               return false;
        }
        info->name[29] = '\0';
-       return 1;
+       return true;
 }
 
 static void
@@ -99,7 +84,7 @@ destroy(const struct xt_match *match, void *matchinfo)
        nf_ct_l3proto_module_put(match->family);
 }
 
-static struct xt_match xt_helper_match[] = {
+static struct xt_match xt_helper_match[] __read_mostly = {
        {
                .name           = "helper",
                .family         = AF_INET,
index 77288c5ada78795cf7346dbd46993904d8a5696e..3dad173d9735706608d47b01edf6006a2589c621 100644 (file)
@@ -20,7 +20,7 @@ MODULE_LICENSE("GPL");
 MODULE_ALIAS("ipt_length");
 MODULE_ALIAS("ip6t_length");
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -28,7 +28,7 @@ match(const struct sk_buff *skb,
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
        const struct xt_length_info *info = matchinfo;
        u_int16_t pktlen = ntohs(ip_hdr(skb)->tot_len);
@@ -36,7 +36,7 @@ match(const struct sk_buff *skb,
        return (pktlen >= info->min && pktlen <= info->max) ^ info->invert;
 }
 
-static int
+static bool
 match6(const struct sk_buff *skb,
        const struct net_device *in,
        const struct net_device *out,
@@ -44,16 +44,16 @@ match6(const struct sk_buff *skb,
        const void *matchinfo,
        int offset,
        unsigned int protoff,
-       int *hotdrop)
+       bool *hotdrop)
 {
        const struct xt_length_info *info = matchinfo;
-       const u_int16_t pktlen = (ntohs(ipv6_hdr(skb)->payload_len) +
-                                 sizeof(struct ipv6hdr));
+       const u_int16_t pktlen = ntohs(ipv6_hdr(skb)->payload_len) +
+                                sizeof(struct ipv6hdr);
 
        return (pktlen >= info->min && pktlen <= info->max) ^ info->invert;
 }
 
-static struct xt_match xt_length_match[] = {
+static struct xt_match xt_length_match[] __read_mostly = {
        {
                .name           = "length",
                .family         = AF_INET,
index 571a72ab89ad643a8c17baf9dcb9d2439fd65415..4fcca797150f75d7fc673196476ff101dfeecb05 100644 (file)
@@ -57,7 +57,7 @@ static DEFINE_SPINLOCK(limit_lock);
 
 #define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ)
 
-static int
+static bool
 ipt_limit_match(const struct sk_buff *skb,
                const struct net_device *in,
                const struct net_device *out,
@@ -65,9 +65,10 @@ ipt_limit_match(const struct sk_buff *skb,
                const void *matchinfo,
                int offset,
                unsigned int protoff,
-               int *hotdrop)
+               bool *hotdrop)
 {
-       struct xt_rateinfo *r = ((struct xt_rateinfo *)matchinfo)->master;
+       struct xt_rateinfo *r =
+               ((const struct xt_rateinfo *)matchinfo)->master;
        unsigned long now = jiffies;
 
        spin_lock_bh(&limit_lock);
@@ -79,11 +80,11 @@ ipt_limit_match(const struct sk_buff *skb,
                /* We're not limited. */
                r->credit -= r->cost;
                spin_unlock_bh(&limit_lock);
-               return 1;
+               return true;
        }
 
        spin_unlock_bh(&limit_lock);
-       return 0;
+       return false;
 }
 
 /* Precision saver. */
@@ -98,7 +99,7 @@ user2credits(u_int32_t user)
        return (user * HZ * CREDITS_PER_JIFFY) / XT_LIMIT_SCALE;
 }
 
-static int
+static bool
 ipt_limit_checkentry(const char *tablename,
                     const void *inf,
                     const struct xt_match *match,
@@ -112,7 +113,7 @@ ipt_limit_checkentry(const char *tablename,
            || user2credits(r->avg * r->burst) < user2credits(r->avg)) {
                printk("Overflow in xt_limit, try lower: %u/%u\n",
                       r->avg, r->burst);
-               return 0;
+               return false;
        }
 
        /* For SMP, we only want to use one set of counters. */
@@ -125,7 +126,7 @@ ipt_limit_checkentry(const char *tablename,
                r->credit_cap = user2credits(r->avg * r->burst); /* Credits full. */
                r->cost = user2credits(r->avg);
        }
-       return 1;
+       return true;
 }
 
 #ifdef CONFIG_COMPAT
@@ -144,7 +145,7 @@ struct compat_xt_rateinfo {
  * master pointer, which does not need to be preserved. */
 static void compat_from_user(void *dst, void *src)
 {
-       struct compat_xt_rateinfo *cm = src;
+       const struct compat_xt_rateinfo *cm = src;
        struct xt_rateinfo m = {
                .avg            = cm->avg,
                .burst          = cm->burst,
@@ -158,7 +159,7 @@ static void compat_from_user(void *dst, void *src)
 
 static int compat_to_user(void __user *dst, void *src)
 {
-       struct xt_rateinfo *m = src;
+       const struct xt_rateinfo *m = src;
        struct compat_xt_rateinfo cm = {
                .avg            = m->avg,
                .burst          = m->burst,
@@ -172,7 +173,7 @@ static int compat_to_user(void __user *dst, void *src)
 }
 #endif /* CONFIG_COMPAT */
 
-static struct xt_match xt_limit_match[] = {
+static struct xt_match xt_limit_match[] __read_mostly = {
        {
                .name           = "limit",
                .family         = AF_INET,
index 1d3a1d98b885e49357a9bb03e12a181afa9198ec..00490d777a0faa81209aca5a220d2651bc0153d2 100644 (file)
@@ -24,7 +24,7 @@ MODULE_DESCRIPTION("iptables mac matching module");
 MODULE_ALIAS("ipt_mac");
 MODULE_ALIAS("ip6t_mac");
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -32,19 +32,19 @@ match(const struct sk_buff *skb,
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
     const struct xt_mac_info *info = matchinfo;
 
     /* Is mac pointer valid? */
-    return (skb_mac_header(skb) >= skb->head &&
-           (skb_mac_header(skb) + ETH_HLEN) <= skb->data
-           /* If so, compare... */
-           && ((!compare_ether_addr(eth_hdr(skb)->h_source, info->srcaddr))
-               ^ info->invert));
+    return skb_mac_header(skb) >= skb->head &&
+          skb_mac_header(skb) + ETH_HLEN <= skb->data
+          /* If so, compare... */
+          && ((!compare_ether_addr(eth_hdr(skb)->h_source, info->srcaddr))
+               ^ info->invert);
 }
 
-static struct xt_match xt_mac_match[] = {
+static struct xt_match xt_mac_match[] __read_mostly = {
        {
                .name           = "mac",
                .family         = AF_INET,
index 39911dddb01103e95389c13ba9d328117702e06b..c02a7f8f3925023aebb859d715c42588cb09512f 100644 (file)
@@ -19,7 +19,7 @@ MODULE_DESCRIPTION("iptables mark matching module");
 MODULE_ALIAS("ipt_mark");
 MODULE_ALIAS("ip6t_mark");
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -27,14 +27,14 @@ match(const struct sk_buff *skb,
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
        const struct xt_mark_info *info = matchinfo;
 
        return ((skb->mark & info->mask) == info->mark) ^ info->invert;
 }
 
-static int
+static bool
 checkentry(const char *tablename,
           const void *entry,
           const struct xt_match *match,
@@ -45,9 +45,9 @@ checkentry(const char *tablename,
 
        if (minfo->mark > 0xffffffff || minfo->mask > 0xffffffff) {
                printk(KERN_WARNING "mark: only supports 32bit mark\n");
-               return 0;
+               return false;
        }
-       return 1;
+       return true;
 }
 
 #ifdef CONFIG_COMPAT
@@ -60,7 +60,7 @@ struct compat_xt_mark_info {
 
 static void compat_from_user(void *dst, void *src)
 {
-       struct compat_xt_mark_info *cm = src;
+       const struct compat_xt_mark_info *cm = src;
        struct xt_mark_info m = {
                .mark   = cm->mark,
                .mask   = cm->mask,
@@ -71,7 +71,7 @@ static void compat_from_user(void *dst, void *src)
 
 static int compat_to_user(void __user *dst, void *src)
 {
-       struct xt_mark_info *m = src;
+       const struct xt_mark_info *m = src;
        struct compat_xt_mark_info cm = {
                .mark   = m->mark,
                .mask   = m->mask,
@@ -81,7 +81,7 @@ static int compat_to_user(void __user *dst, void *src)
 }
 #endif /* CONFIG_COMPAT */
 
-static struct xt_match xt_mark_match[] = {
+static struct xt_match xt_mark_match[] __read_mostly = {
        {
                .name           = "mark",
                .family         = AF_INET,
index 4dce2a81702afa0151a2fd8363d3b3d5ae586b73..e8ae10284acd7e49c74b7ab544412f6ac0cf94f9 100644 (file)
@@ -33,24 +33,24 @@ MODULE_ALIAS("ip6t_multiport");
 #endif
 
 /* Returns 1 if the port is matched by the test, 0 otherwise. */
-static inline int
+static inline bool
 ports_match(const u_int16_t *portlist, enum xt_multiport_flags flags,
            u_int8_t count, u_int16_t src, u_int16_t dst)
 {
        unsigned int i;
        for (i = 0; i < count; i++) {
                if (flags != XT_MULTIPORT_DESTINATION && portlist[i] == src)
-                       return 1;
+                       return true;
 
                if (flags != XT_MULTIPORT_SOURCE && portlist[i] == dst)
-                       return 1;
+                       return true;
        }
 
-       return 0;
+       return false;
 }
 
 /* Returns 1 if the port is matched by the test, 0 otherwise. */
-static inline int
+static inline bool
 ports_match_v1(const struct xt_multiport_v1 *minfo,
               u_int16_t src, u_int16_t dst)
 {
@@ -67,34 +67,34 @@ ports_match_v1(const struct xt_multiport_v1 *minfo,
 
                        if (minfo->flags == XT_MULTIPORT_SOURCE
                            && src >= s && src <= e)
-                               return 1 ^ minfo->invert;
+                               return true ^ minfo->invert;
                        if (minfo->flags == XT_MULTIPORT_DESTINATION
                            && dst >= s && dst <= e)
-                               return 1 ^ minfo->invert;
+                               return true ^ minfo->invert;
                        if (minfo->flags == XT_MULTIPORT_EITHER
                            && ((dst >= s && dst <= e)
                                || (src >= s && src <= e)))
-                               return 1 ^ minfo->invert;
+                               return true ^ minfo->invert;
                } else {
                        /* exact port matching */
                        duprintf("src or dst matches with %d?\n", s);
 
                        if (minfo->flags == XT_MULTIPORT_SOURCE
                            && src == s)
-                               return 1 ^ minfo->invert;
+                               return true ^ minfo->invert;
                        if (minfo->flags == XT_MULTIPORT_DESTINATION
                            && dst == s)
-                               return 1 ^ minfo->invert;
+                               return true ^ minfo->invert;
                        if (minfo->flags == XT_MULTIPORT_EITHER
                            && (src == s || dst == s))
-                               return 1 ^ minfo->invert;
+                               return true ^ minfo->invert;
                }
        }
 
        return minfo->invert;
 }
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -102,13 +102,13 @@ match(const struct sk_buff *skb,
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
        __be16 _ports[2], *pptr;
        const struct xt_multiport *multiinfo = matchinfo;
 
        if (offset)
-               return 0;
+               return false;
 
        pptr = skb_header_pointer(skb, protoff, sizeof(_ports), _ports);
        if (pptr == NULL) {
@@ -116,8 +116,8 @@ match(const struct sk_buff *skb,
                 * can't.  Hence, no choice but to drop.
                 */
                duprintf("xt_multiport: Dropping evil offset=0 tinygram.\n");
-               *hotdrop = 1;
-               return 0;
+               *hotdrop = true;
+               return false;
        }
 
        return ports_match(multiinfo->ports,
@@ -125,7 +125,7 @@ match(const struct sk_buff *skb,
                           ntohs(pptr[0]), ntohs(pptr[1]));
 }
 
-static int
+static bool
 match_v1(const struct sk_buff *skb,
         const struct net_device *in,
         const struct net_device *out,
@@ -133,13 +133,13 @@ match_v1(const struct sk_buff *skb,
         const void *matchinfo,
         int offset,
         unsigned int protoff,
-        int *hotdrop)
+        bool *hotdrop)
 {
        __be16 _ports[2], *pptr;
        const struct xt_multiport_v1 *multiinfo = matchinfo;
 
        if (offset)
-               return 0;
+               return false;
 
        pptr = skb_header_pointer(skb, protoff, sizeof(_ports), _ports);
        if (pptr == NULL) {
@@ -147,14 +147,14 @@ match_v1(const struct sk_buff *skb,
                 * can't.  Hence, no choice but to drop.
                 */
                duprintf("xt_multiport: Dropping evil offset=0 tinygram.\n");
-               *hotdrop = 1;
-               return 0;
+               *hotdrop = true;
+               return false;
        }
 
        return ports_match_v1(multiinfo, ntohs(pptr[0]), ntohs(pptr[1]));
 }
 
-static inline int
+static inline bool
 check(u_int16_t proto,
       u_int8_t ip_invflags,
       u_int8_t match_flags,
@@ -172,7 +172,7 @@ check(u_int16_t proto,
 }
 
 /* Called when user tries to insert an entry of this type. */
-static int
+static bool
 checkentry(const char *tablename,
           const void *info,
           const struct xt_match *match,
@@ -186,7 +186,7 @@ checkentry(const char *tablename,
                     multiinfo->count);
 }
 
-static int
+static bool
 checkentry_v1(const char *tablename,
              const void *info,
              const struct xt_match *match,
@@ -200,7 +200,7 @@ checkentry_v1(const char *tablename,
                     multiinfo->count);
 }
 
-static int
+static bool
 checkentry6(const char *tablename,
            const void *info,
            const struct xt_match *match,
@@ -214,7 +214,7 @@ checkentry6(const char *tablename,
                     multiinfo->count);
 }
 
-static int
+static bool
 checkentry6_v1(const char *tablename,
               const void *info,
               const struct xt_match *match,
@@ -228,7 +228,7 @@ checkentry6_v1(const char *tablename,
                     multiinfo->count);
 }
 
-static struct xt_match xt_multiport_match[] = {
+static struct xt_match xt_multiport_match[] __read_mostly = {
        {
                .name           = "multiport",
                .family         = AF_INET,
index 35a0fe200c397c509d256dddd23cc8d57e3d3338..f47cab7a696d6c8487afcc98ae75ddbf5c596cc2 100644 (file)
@@ -14,8 +14,6 @@
 #include <linux/netfilter/xt_physdev.h>
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter_bridge.h>
-#define MATCH   1
-#define NOMATCH 0
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>");
@@ -23,7 +21,7 @@ MODULE_DESCRIPTION("iptables bridge physical device match module");
 MODULE_ALIAS("ipt_physdev");
 MODULE_ALIAS("ip6t_physdev");
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -31,14 +29,14 @@ match(const struct sk_buff *skb,
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
        int i;
        static const char nulldevname[IFNAMSIZ];
        const struct xt_physdev_info *info = matchinfo;
-       unsigned int ret;
+       bool ret;
        const char *indev, *outdev;
-       struct nf_bridge_info *nf_bridge;
+       const struct nf_bridge_info *nf_bridge;
 
        /* Not a bridged IP packet or no info available yet:
         * LOCAL_OUT/mangle and LOCAL_OUT/nat don't know if
@@ -47,61 +45,61 @@ match(const struct sk_buff *skb,
                /* Return MATCH if the invert flags of the used options are on */
                if ((info->bitmask & XT_PHYSDEV_OP_BRIDGED) &&
                    !(info->invert & XT_PHYSDEV_OP_BRIDGED))
-                       return NOMATCH;
+                       return false;
                if ((info->bitmask & XT_PHYSDEV_OP_ISIN) &&
                    !(info->invert & XT_PHYSDEV_OP_ISIN))
-                       return NOMATCH;
+                       return false;
                if ((info->bitmask & XT_PHYSDEV_OP_ISOUT) &&
                    !(info->invert & XT_PHYSDEV_OP_ISOUT))
-                       return NOMATCH;
+                       return false;
                if ((info->bitmask & XT_PHYSDEV_OP_IN) &&
                    !(info->invert & XT_PHYSDEV_OP_IN))
-                       return NOMATCH;
+                       return false;
                if ((info->bitmask & XT_PHYSDEV_OP_OUT) &&
                    !(info->invert & XT_PHYSDEV_OP_OUT))
-                       return NOMATCH;
-               return MATCH;
+                       return false;
+               return true;
        }
 
        /* This only makes sense in the FORWARD and POSTROUTING chains */
        if ((info->bitmask & XT_PHYSDEV_OP_BRIDGED) &&
            (!!(nf_bridge->mask & BRNF_BRIDGED) ^
            !(info->invert & XT_PHYSDEV_OP_BRIDGED)))
-               return NOMATCH;
+               return false;
 
        if ((info->bitmask & XT_PHYSDEV_OP_ISIN &&
            (!nf_bridge->physindev ^ !!(info->invert & XT_PHYSDEV_OP_ISIN))) ||
            (info->bitmask & XT_PHYSDEV_OP_ISOUT &&
            (!nf_bridge->physoutdev ^ !!(info->invert & XT_PHYSDEV_OP_ISOUT))))
-               return NOMATCH;
+               return false;
 
        if (!(info->bitmask & XT_PHYSDEV_OP_IN))
                goto match_outdev;
        indev = nf_bridge->physindev ? nf_bridge->physindev->name : nulldevname;
-       for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) {
+       for (i = 0, ret = false; i < IFNAMSIZ/sizeof(unsigned int); i++) {
                ret |= (((const unsigned int *)indev)[i]
                        ^ ((const unsigned int *)info->physindev)[i])
                        & ((const unsigned int *)info->in_mask)[i];
        }
 
-       if ((ret == 0) ^ !(info->invert & XT_PHYSDEV_OP_IN))
-               return NOMATCH;
+       if (!ret ^ !(info->invert & XT_PHYSDEV_OP_IN))
+               return false;
 
 match_outdev:
        if (!(info->bitmask & XT_PHYSDEV_OP_OUT))
-               return MATCH;
+               return true;
        outdev = nf_bridge->physoutdev ?
                 nf_bridge->physoutdev->name : nulldevname;
-       for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) {
+       for (i = 0, ret = false; i < IFNAMSIZ/sizeof(unsigned int); i++) {
                ret |= (((const unsigned int *)outdev)[i]
                        ^ ((const unsigned int *)info->physoutdev)[i])
                        & ((const unsigned int *)info->out_mask)[i];
        }
 
-       return (ret != 0) ^ !(info->invert & XT_PHYSDEV_OP_OUT);
+       return ret ^ !(info->invert & XT_PHYSDEV_OP_OUT);
 }
 
-static int
+static bool
 checkentry(const char *tablename,
                       const void *ip,
                       const struct xt_match *match,
@@ -112,7 +110,7 @@ checkentry(const char *tablename,
 
        if (!(info->bitmask & XT_PHYSDEV_OP_MASK) ||
            info->bitmask & ~XT_PHYSDEV_OP_MASK)
-               return 0;
+               return false;
        if (info->bitmask & XT_PHYSDEV_OP_OUT &&
            (!(info->bitmask & XT_PHYSDEV_OP_BRIDGED) ||
             info->invert & XT_PHYSDEV_OP_BRIDGED) &&
@@ -122,12 +120,12 @@ checkentry(const char *tablename,
                       "OUTPUT, FORWARD and POSTROUTING chains for non-bridged "
                       "traffic is not supported anymore.\n");
                if (hook_mask & (1 << NF_IP_LOCAL_OUT))
-                       return 0;
+                       return false;
        }
-       return 1;
+       return true;
 }
 
-static struct xt_match xt_physdev_match[] = {
+static struct xt_match xt_physdev_match[] __read_mostly = {
        {
                .name           = "physdev",
                .family         = AF_INET,
index e1409fc5c2881f81e0affb61eef149ed6c724f12..a52925f12f35e58ec25188130e63be13edf623a4 100644 (file)
@@ -21,29 +21,29 @@ MODULE_DESCRIPTION("IP tables match to match on linklayer packet type");
 MODULE_ALIAS("ipt_pkttype");
 MODULE_ALIAS("ip6t_pkttype");
 
-static int match(const struct sk_buff *skb,
+static bool match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
       const struct xt_match *match,
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
        u_int8_t type;
        const struct xt_pkttype_info *info = matchinfo;
 
        if (skb->pkt_type == PACKET_LOOPBACK)
-               type = (MULTICAST(ip_hdr(skb)->daddr)
+               type = MULTICAST(ip_hdr(skb)->daddr)
                        ? PACKET_MULTICAST
-                       : PACKET_BROADCAST);
+                       : PACKET_BROADCAST;
        else
                type = skb->pkt_type;
 
        return (type == info->pkttype) ^ info->invert;
 }
 
-static struct xt_match xt_pkttype_match[] = {
+static struct xt_match xt_pkttype_match[] __read_mostly = {
        {
                .name           = "pkttype",
                .family         = AF_INET,
index 15b45a95ec13b2711a52ad1a00029279b4946b4a..6d6d3b7fcbb5c18b88f8021a8c096debcceffe86 100644 (file)
@@ -20,7 +20,7 @@ MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
 MODULE_DESCRIPTION("Xtables IPsec policy matching module");
 MODULE_LICENSE("GPL");
 
-static inline int
+static inline bool
 xt_addr_cmp(const union xt_policy_addr *a1, const union xt_policy_addr *m,
            const union xt_policy_addr *a2, unsigned short family)
 {
@@ -30,11 +30,11 @@ xt_addr_cmp(const union xt_policy_addr *a1, const union xt_policy_addr *m,
        case AF_INET6:
                return !ipv6_masked_addr_cmp(&a1->a6, &m->a6, &a2->a6);
        }
-       return 0;
+       return false;
 }
 
-static inline int
-match_xfrm_state(struct xfrm_state *x, const struct xt_policy_elem *e,
+static inline bool
+match_xfrm_state(const struct xfrm_state *x, const struct xt_policy_elem *e,
                 unsigned short family)
 {
 #define MATCH_ADDR(x,y,z)      (!e->match.x ||                        \
@@ -55,7 +55,7 @@ match_policy_in(const struct sk_buff *skb, const struct xt_policy_info *info,
                unsigned short family)
 {
        const struct xt_policy_elem *e;
-       struct sec_path *sp = skb->sp;
+       const struct sec_path *sp = skb->sp;
        int strict = info->flags & XT_POLICY_MATCH_STRICT;
        int i, pos;
 
@@ -85,7 +85,7 @@ match_policy_out(const struct sk_buff *skb, const struct xt_policy_info *info,
                 unsigned short family)
 {
        const struct xt_policy_elem *e;
-       struct dst_entry *dst = skb->dst;
+       const struct dst_entry *dst = skb->dst;
        int strict = info->flags & XT_POLICY_MATCH_STRICT;
        int i, pos;
 
@@ -108,14 +108,14 @@ match_policy_out(const struct sk_buff *skb, const struct xt_policy_info *info,
        return strict ? i == info->len : 0;
 }
 
-static int match(const struct sk_buff *skb,
-                const struct net_device *in,
-                const struct net_device *out,
-                const struct xt_match *match,
-                const void *matchinfo,
-                int offset,
-                unsigned int protoff,
-                int *hotdrop)
+static bool match(const struct sk_buff *skb,
+                 const struct net_device *in,
+                 const struct net_device *out,
+                 const struct xt_match *match,
+                 const void *matchinfo,
+                 int offset,
+                 unsigned int protoff,
+                 bool *hotdrop)
 {
        const struct xt_policy_info *info = matchinfo;
        int ret;
@@ -126,45 +126,45 @@ static int match(const struct sk_buff *skb,
                ret = match_policy_out(skb, info, match->family);
 
        if (ret < 0)
-               ret = info->flags & XT_POLICY_MATCH_NONE ? 1 : 0;
+               ret = info->flags & XT_POLICY_MATCH_NONE ? true : false;
        else if (info->flags & XT_POLICY_MATCH_NONE)
-               ret = 0;
+               ret = false;
 
        return ret;
 }
 
-static int checkentry(const char *tablename, const void *ip_void,
-                     const struct xt_match *match,
-                     void *matchinfo, unsigned int hook_mask)
+static bool checkentry(const char *tablename, const void *ip_void,
+                      const struct xt_match *match,
+                      void *matchinfo, unsigned int hook_mask)
 {
        struct xt_policy_info *info = matchinfo;
 
        if (!(info->flags & (XT_POLICY_MATCH_IN|XT_POLICY_MATCH_OUT))) {
                printk(KERN_ERR "xt_policy: neither incoming nor "
                                "outgoing policy selected\n");
-               return 0;
+               return false;
        }
        /* hook values are equal for IPv4 and IPv6 */
        if (hook_mask & (1 << NF_IP_PRE_ROUTING | 1 << NF_IP_LOCAL_IN)
            && info->flags & XT_POLICY_MATCH_OUT) {
                printk(KERN_ERR "xt_policy: output policy not valid in "
                                "PRE_ROUTING and INPUT\n");
-               return 0;
+               return false;
        }
        if (hook_mask & (1 << NF_IP_POST_ROUTING | 1 << NF_IP_LOCAL_OUT)
            && info->flags & XT_POLICY_MATCH_IN) {
                printk(KERN_ERR "xt_policy: input policy not valid in "
                                "POST_ROUTING and OUTPUT\n");
-               return 0;
+               return false;
        }
        if (info->len > XT_POLICY_MAX_ELEM) {
                printk(KERN_ERR "xt_policy: too many policy elements\n");
-               return 0;
+               return false;
        }
-       return 1;
+       return true;
 }
 
-static struct xt_match xt_policy_match[] = {
+static struct xt_match xt_policy_match[] __read_mostly = {
        {
                .name           = "policy",
                .family         = AF_INET,
index bfdde06ca0b7dfe5ceec4fab5368e577543b0645..dae97445b87b498f7e9d770dad26488485d15123 100644 (file)
@@ -16,19 +16,20 @@ MODULE_ALIAS("ip6t_quota");
 
 static DEFINE_SPINLOCK(quota_lock);
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in, const struct net_device *out,
       const struct xt_match *match, const void *matchinfo,
-      int offset, unsigned int protoff, int *hotdrop)
+      int offset, unsigned int protoff, bool *hotdrop)
 {
-       struct xt_quota_info *q = ((struct xt_quota_info *)matchinfo)->master;
-       int ret = q->flags & XT_QUOTA_INVERT ? 1 : 0;
+       struct xt_quota_info *q =
+               ((const struct xt_quota_info *)matchinfo)->master;
+       bool ret = q->flags & XT_QUOTA_INVERT;
 
        spin_lock_bh(&quota_lock);
        if (q->quota >= skb->len) {
                q->quota -= skb->len;
-               ret ^= 1;
+               ret = !ret;
        } else {
                /* we do not allow even small packets from now on */
                q->quota = 0;
@@ -38,21 +39,21 @@ match(const struct sk_buff *skb,
        return ret;
 }
 
-static int
+static bool
 checkentry(const char *tablename, const void *entry,
           const struct xt_match *match, void *matchinfo,
           unsigned int hook_mask)
 {
-       struct xt_quota_info *q = (struct xt_quota_info *)matchinfo;
+       struct xt_quota_info *q = matchinfo;
 
        if (q->flags & ~XT_QUOTA_MASK)
-               return 0;
+               return false;
        /* For SMP, we only want to use one set of counters. */
        q->master = q;
-       return 1;
+       return true;
 }
 
-static struct xt_match xt_quota_match[] = {
+static struct xt_match xt_quota_match[] __read_mostly = {
        {
                .name           = "quota",
                .family         = AF_INET,
index c2017f8af9c42457b3a61f678b7b842e74421a9d..cc3e76d77a9931f7f697188967465b78d998748b 100644 (file)
@@ -21,7 +21,7 @@ MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("X_tables realm match");
 MODULE_ALIAS("ipt_realm");
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -29,15 +29,15 @@ match(const struct sk_buff *skb,
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
        const struct xt_realm_info *info = matchinfo;
-       struct dst_entry *dst = skb->dst;
+       const struct dst_entry *dst = skb->dst;
 
        return (info->id == (dst->tclassid & info->mask)) ^ info->invert;
 }
 
-static struct xt_match realm_match = {
+static struct xt_match realm_match __read_mostly = {
        .name           = "realm",
        .match          = match,
        .matchsize      = sizeof(struct xt_realm_info),
index f86d8d769d478b636753d9a91c5faa7acd9c82ef..c002153b80ab76ef6e3725dfc9dc6d4fce242d69 100644 (file)
@@ -23,7 +23,7 @@ MODULE_ALIAS("ipt_sctp");
 #define SCCHECK(cond, option, flag, invflag) (!((flag) & (option)) \
                                              || (!!((invflag) & (option)) ^ (cond)))
 
-static int
+static bool
 match_flags(const struct xt_sctp_flag_info *flag_info,
            const int flag_count,
            u_int8_t chunktype,
@@ -31,23 +31,21 @@ match_flags(const struct xt_sctp_flag_info *flag_info,
 {
        int i;
 
-       for (i = 0; i < flag_count; i++) {
-               if (flag_info[i].chunktype == chunktype) {
+       for (i = 0; i < flag_count; i++)
+               if (flag_info[i].chunktype == chunktype)
                        return (chunkflags & flag_info[i].flag_mask) == flag_info[i].flag;
-               }
-       }
 
-       return 1;
+       return true;
 }
 
-static inline int
+static inline bool
 match_packet(const struct sk_buff *skb,
             unsigned int offset,
             const u_int32_t *chunkmap,
             int chunk_match_type,
             const struct xt_sctp_flag_info *flag_info,
             const int flag_count,
-            int *hotdrop)
+            bool *hotdrop)
 {
        u_int32_t chunkmapcopy[256 / sizeof (u_int32_t)];
        sctp_chunkhdr_t _sch, *sch;
@@ -56,16 +54,15 @@ match_packet(const struct sk_buff *skb,
        int i = 0;
 #endif
 
-       if (chunk_match_type == SCTP_CHUNK_MATCH_ALL) {
+       if (chunk_match_type == SCTP_CHUNK_MATCH_ALL)
                SCTP_CHUNKMAP_COPY(chunkmapcopy, chunkmap);
-       }
 
        do {
                sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch);
                if (sch == NULL || sch->length == 0) {
                        duprintf("Dropping invalid SCTP packet.\n");
-                       *hotdrop = 1;
-                       return 0;
+                       *hotdrop = true;
+                       return false;
                }
 
                duprintf("Chunk num: %d\toffset: %d\ttype: %d\tlength: %d\tflags: %x\n",
@@ -80,28 +77,26 @@ match_packet(const struct sk_buff *skb,
                        case SCTP_CHUNK_MATCH_ANY:
                                if (match_flags(flag_info, flag_count,
                                        sch->type, sch->flags)) {
-                                       return 1;
+                                       return true;
                                }
                                break;
 
                        case SCTP_CHUNK_MATCH_ALL:
                                if (match_flags(flag_info, flag_count,
-                                       sch->type, sch->flags)) {
+                                   sch->type, sch->flags))
                                        SCTP_CHUNKMAP_CLEAR(chunkmapcopy, sch->type);
-                               }
                                break;
 
                        case SCTP_CHUNK_MATCH_ONLY:
                                if (!match_flags(flag_info, flag_count,
-                                       sch->type, sch->flags)) {
-                                       return 0;
-                               }
+                                   sch->type, sch->flags))
+                                       return false;
                                break;
                        }
                } else {
                        switch (chunk_match_type) {
                        case SCTP_CHUNK_MATCH_ONLY:
-                               return 0;
+                               return false;
                        }
                }
        } while (offset < skb->len);
@@ -110,16 +105,16 @@ match_packet(const struct sk_buff *skb,
        case SCTP_CHUNK_MATCH_ALL:
                return SCTP_CHUNKMAP_IS_CLEAR(chunkmap);
        case SCTP_CHUNK_MATCH_ANY:
-               return 0;
+               return false;
        case SCTP_CHUNK_MATCH_ONLY:
-               return 1;
+               return true;
        }
 
        /* This will never be reached, but required to stop compiler whine */
-       return 0;
+       return false;
 }
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -127,29 +122,29 @@ match(const struct sk_buff *skb,
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
        const struct xt_sctp_info *info = matchinfo;
        sctp_sctphdr_t _sh, *sh;
 
        if (offset) {
                duprintf("Dropping non-first fragment.. FIXME\n");
-               return 0;
+               return false;
        }
 
        sh = skb_header_pointer(skb, protoff, sizeof(_sh), &_sh);
        if (sh == NULL) {
                duprintf("Dropping evil TCP offset=0 tinygram.\n");
-               *hotdrop = 1;
-               return 0;
+               *hotdrop = true;
+               return false;
        }
        duprintf("spt: %d\tdpt: %d\n", ntohs(sh->source), ntohs(sh->dest));
 
-       return  SCCHECK(((ntohs(sh->source) >= info->spts[0])
-                       && (ntohs(sh->source) <= info->spts[1])),
+       return  SCCHECK(ntohs(sh->source) >= info->spts[0]
+                       && ntohs(sh->source) <= info->spts[1],
                        XT_SCTP_SRC_PORTS, info->flags, info->invflags)
-               && SCCHECK(((ntohs(sh->dest) >= info->dpts[0])
-                       && (ntohs(sh->dest) <= info->dpts[1])),
+               && SCCHECK(ntohs(sh->dest) >= info->dpts[0]
+                       && ntohs(sh->dest) <= info->dpts[1],
                        XT_SCTP_DEST_PORTS, info->flags, info->invflags)
                && SCCHECK(match_packet(skb, protoff + sizeof (sctp_sctphdr_t),
                                        info->chunkmap, info->chunk_match_type,
@@ -158,7 +153,7 @@ match(const struct sk_buff *skb,
                           XT_SCTP_CHUNK_TYPES, info->flags, info->invflags);
 }
 
-static int
+static bool
 checkentry(const char *tablename,
           const void *inf,
           const struct xt_match *match,
@@ -177,7 +172,7 @@ checkentry(const char *tablename,
                                | SCTP_CHUNK_MATCH_ONLY)));
 }
 
-static struct xt_match xt_sctp_match[] = {
+static struct xt_match xt_sctp_match[] __read_mostly = {
        {
                .name           = "sctp",
                .family         = AF_INET,
index 149294f7df7147bfc6c770db001396196563f341..e0a528df19a78349f29596782c35175fdc7c24d4 100644 (file)
@@ -20,7 +20,7 @@ MODULE_DESCRIPTION("ip[6]_tables connection tracking state match module");
 MODULE_ALIAS("ipt_state");
 MODULE_ALIAS("ip6t_state");
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -28,7 +28,7 @@ match(const struct sk_buff *skb,
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
        const struct xt_state_info *sinfo = matchinfo;
        enum ip_conntrack_info ctinfo;
@@ -44,18 +44,18 @@ match(const struct sk_buff *skb,
        return (sinfo->statemask & statebit);
 }
 
-static int check(const char *tablename,
-                const void *inf,
-                const struct xt_match *match,
-                void *matchinfo,
-                unsigned int hook_mask)
+static bool check(const char *tablename,
+                 const void *inf,
+                 const struct xt_match *match,
+                 void *matchinfo,
+                 unsigned int hook_mask)
 {
        if (nf_ct_l3proto_try_module_get(match->family) < 0) {
                printk(KERN_WARNING "can't load conntrack support for "
                                    "proto=%d\n", match->family);
-               return 0;
+               return false;
        }
-       return 1;
+       return true;
 }
 
 static void
@@ -64,7 +64,7 @@ destroy(const struct xt_match *match, void *matchinfo)
        nf_ct_l3proto_module_put(match->family);
 }
 
-static struct xt_match xt_state_match[] = {
+static struct xt_match xt_state_match[] __read_mostly = {
        {
                .name           = "state",
                .family         = AF_INET,
index 091a9f89f5d56089ecca837a87f2d859ab3361c3..4089dae4e2865ae9f99377d307195ff69127f07b 100644 (file)
@@ -24,26 +24,26 @@ MODULE_ALIAS("ip6t_statistic");
 
 static DEFINE_SPINLOCK(nth_lock);
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in, const struct net_device *out,
       const struct xt_match *match, const void *matchinfo,
-      int offset, unsigned int protoff, int *hotdrop)
+      int offset, unsigned int protoff, bool *hotdrop)
 {
        struct xt_statistic_info *info = (struct xt_statistic_info *)matchinfo;
-       int ret = info->flags & XT_STATISTIC_INVERT ? 1 : 0;
+       bool ret = info->flags & XT_STATISTIC_INVERT;
 
        switch (info->mode) {
        case XT_STATISTIC_MODE_RANDOM:
                if ((net_random() & 0x7FFFFFFF) < info->u.random.probability)
-                       ret ^= 1;
+                       ret = !ret;
                break;
        case XT_STATISTIC_MODE_NTH:
                info = info->master;
                spin_lock_bh(&nth_lock);
                if (info->u.nth.count++ == info->u.nth.every) {
                        info->u.nth.count = 0;
-                       ret ^= 1;
+                       ret = !ret;
                }
                spin_unlock_bh(&nth_lock);
                break;
@@ -52,21 +52,21 @@ match(const struct sk_buff *skb,
        return ret;
 }
 
-static int
+static bool
 checkentry(const char *tablename, const void *entry,
           const struct xt_match *match, void *matchinfo,
           unsigned int hook_mask)
 {
-       struct xt_statistic_info *info = (struct xt_statistic_info *)matchinfo;
+       struct xt_statistic_info *info = matchinfo;
 
        if (info->mode > XT_STATISTIC_MODE_MAX ||
            info->flags & ~XT_STATISTIC_MASK)
-               return 0;
+               return false;
        info->master = info;
-       return 1;
+       return true;
 }
 
-static struct xt_match xt_statistic_match[] = {
+static struct xt_match xt_statistic_match[] __read_mostly = {
        {
                .name           = "statistic",
                .family         = AF_INET,
index 999a005dbd0cb5c73c0285f3241b03794f7a9418..864133442cdac6c35f0f50edb81664565bf65b47 100644 (file)
@@ -21,14 +21,14 @@ MODULE_LICENSE("GPL");
 MODULE_ALIAS("ipt_string");
 MODULE_ALIAS("ip6t_string");
 
-static int match(const struct sk_buff *skb,
-                const struct net_device *in,
-                const struct net_device *out,
-                const struct xt_match *match,
-                const void *matchinfo,
-                int offset,
-                unsigned int protoff,
-                int *hotdrop)
+static bool match(const struct sk_buff *skb,
+                 const struct net_device *in,
+                 const struct net_device *out,
+                 const struct xt_match *match,
+                 const void *matchinfo,
+                 int offset,
+                 unsigned int protoff,
+                 bool *hotdrop)
 {
        const struct xt_string_info *conf = matchinfo;
        struct ts_state state;
@@ -42,30 +42,30 @@ static int match(const struct sk_buff *skb,
 
 #define STRING_TEXT_PRIV(m) ((struct xt_string_info *) m)
 
-static int checkentry(const char *tablename,
-                     const void *ip,
-                     const struct xt_match *match,
-                     void *matchinfo,
-                     unsigned int hook_mask)
+static bool checkentry(const char *tablename,
+                      const void *ip,
+                      const struct xt_match *match,
+                      void *matchinfo,
+                      unsigned int hook_mask)
 {
        struct xt_string_info *conf = matchinfo;
        struct ts_config *ts_conf;
 
        /* Damn, can't handle this case properly with iptables... */
        if (conf->from_offset > conf->to_offset)
-               return 0;
+               return false;
        if (conf->algo[XT_STRING_MAX_ALGO_NAME_SIZE - 1] != '\0')
-               return 0;
+               return false;
        if (conf->patlen > XT_STRING_MAX_PATTERN_SIZE)
-               return 0;
+               return false;
        ts_conf = textsearch_prepare(conf->algo, conf->pattern, conf->patlen,
                                     GFP_KERNEL, TS_AUTOLOAD);
        if (IS_ERR(ts_conf))
-               return 0;
+               return false;
 
        conf->config = ts_conf;
 
-       return 1;
+       return true;
 }
 
 static void destroy(const struct xt_match *match, void *matchinfo)
@@ -73,7 +73,7 @@ static void destroy(const struct xt_match *match, void *matchinfo)
        textsearch_destroy(STRING_TEXT_PRIV(matchinfo)->config);
 }
 
-static struct xt_match xt_string_match[] = {
+static struct xt_match xt_string_match[] __read_mostly = {
        {
                .name           = "string",
                .family         = AF_INET,
index 80571d0749f7ad5375505bc8f3ec89ab1bfaea6e..cd5f6d758c6806b46032e5c264e417ec66931acf 100644 (file)
@@ -23,7 +23,7 @@ MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
 MODULE_DESCRIPTION("iptables TCP MSS match module");
 MODULE_ALIAS("ipt_tcpmss");
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -31,7 +31,7 @@ match(const struct sk_buff *skb,
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
        const struct xt_tcpmss_match_info *info = matchinfo;
        struct tcphdr _tcph, *th;
@@ -77,11 +77,11 @@ out:
        return info->invert;
 
 dropit:
-       *hotdrop = 1;
-       return 0;
+       *hotdrop = true;
+       return false;
 }
 
-static struct xt_match xt_tcpmss_match[] = {
+static struct xt_match xt_tcpmss_match[] __read_mostly = {
        {
                .name           = "tcpmss",
                .family         = AF_INET,
index 46414b562a199fe93af514b53d068c00fd7b7023..ab7d845224fce9f7dad1b92f3d6a91d9c7c16411 100644 (file)
@@ -27,22 +27,19 @@ MODULE_ALIAS("ip6t_tcp");
 
 
 /* Returns 1 if the port is matched by the range, 0 otherwise */
-static inline int
-port_match(u_int16_t min, u_int16_t max, u_int16_t port, int invert)
+static inline bool
+port_match(u_int16_t min, u_int16_t max, u_int16_t port, bool invert)
 {
-       int ret;
-
-       ret = (port >= min && port <= max) ^ invert;
-       return ret;
+       return (port >= min && port <= max) ^ invert;
 }
 
-static int
+static bool
 tcp_find_option(u_int8_t option,
                const struct sk_buff *skb,
                unsigned int protoff,
                unsigned int optlen,
-               int invert,
-               int *hotdrop)
+               bool invert,
+               bool *hotdrop)
 {
        /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */
        u_int8_t _opt[60 - sizeof(struct tcphdr)], *op;
@@ -57,8 +54,8 @@ tcp_find_option(u_int8_t option,
        op = skb_header_pointer(skb, protoff + sizeof(struct tcphdr),
                                optlen, _opt);
        if (op == NULL) {
-               *hotdrop = 1;
-               return 0;
+               *hotdrop = true;
+               return false;
        }
 
        for (i = 0; i < optlen; ) {
@@ -70,7 +67,7 @@ tcp_find_option(u_int8_t option,
        return invert;
 }
 
-static int
+static bool
 tcp_match(const struct sk_buff *skb,
          const struct net_device *in,
          const struct net_device *out,
@@ -78,7 +75,7 @@ tcp_match(const struct sk_buff *skb,
          const void *matchinfo,
          int offset,
          unsigned int protoff,
-         int *hotdrop)
+         bool *hotdrop)
 {
        struct tcphdr _tcph, *th;
        const struct xt_tcp *tcpinfo = matchinfo;
@@ -92,51 +89,51 @@ tcp_match(const struct sk_buff *skb,
                */
                if (offset == 1) {
                        duprintf("Dropping evil TCP offset=1 frag.\n");
-                       *hotdrop = 1;
+                       *hotdrop = true;
                }
                /* Must not be a fragment. */
-               return 0;
+               return false;
        }
 
-#define FWINVTCP(bool,invflg) ((bool) ^ !!(tcpinfo->invflags & invflg))
+#define FWINVTCP(bool, invflg) ((bool) ^ !!(tcpinfo->invflags & (invflg)))
 
        th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph);
        if (th == NULL) {
                /* We've been asked to examine this packet, and we
                   can't.  Hence, no choice but to drop. */
                duprintf("Dropping evil TCP offset=0 tinygram.\n");
-               *hotdrop = 1;
-               return 0;
+               *hotdrop = true;
+               return false;
        }
 
        if (!port_match(tcpinfo->spts[0], tcpinfo->spts[1],
                        ntohs(th->source),
                        !!(tcpinfo->invflags & XT_TCP_INV_SRCPT)))
-               return 0;
+               return false;
        if (!port_match(tcpinfo->dpts[0], tcpinfo->dpts[1],
                        ntohs(th->dest),
                        !!(tcpinfo->invflags & XT_TCP_INV_DSTPT)))
-               return 0;
+               return false;
        if (!FWINVTCP((((unsigned char *)th)[13] & tcpinfo->flg_mask)
                      == tcpinfo->flg_cmp,
                      XT_TCP_INV_FLAGS))
-               return 0;
+               return false;
        if (tcpinfo->option) {
                if (th->doff * 4 < sizeof(_tcph)) {
-                       *hotdrop = 1;
-                       return 0;
+                       *hotdrop = true;
+                       return false;
                }
                if (!tcp_find_option(tcpinfo->option, skb, protoff,
                                     th->doff*4 - sizeof(_tcph),
                                     tcpinfo->invflags & XT_TCP_INV_OPTION,
                                     hotdrop))
-                       return 0;
+                       return false;
        }
-       return 1;
+       return true;
 }
 
 /* Called when user tries to insert an entry of this type. */
-static int
+static bool
 tcp_checkentry(const char *tablename,
               const void *info,
               const struct xt_match *match,
@@ -149,7 +146,7 @@ tcp_checkentry(const char *tablename,
        return !(tcpinfo->invflags & ~XT_TCP_INV_MASK);
 }
 
-static int
+static bool
 udp_match(const struct sk_buff *skb,
          const struct net_device *in,
          const struct net_device *out,
@@ -157,22 +154,22 @@ udp_match(const struct sk_buff *skb,
          const void *matchinfo,
          int offset,
          unsigned int protoff,
-         int *hotdrop)
+         bool *hotdrop)
 {
        struct udphdr _udph, *uh;
        const struct xt_udp *udpinfo = matchinfo;
 
        /* Must not be a fragment. */
        if (offset)
-               return 0;
+               return false;
 
        uh = skb_header_pointer(skb, protoff, sizeof(_udph), &_udph);
        if (uh == NULL) {
                /* We've been asked to examine this packet, and we
                   can't.  Hence, no choice but to drop. */
                duprintf("Dropping evil UDP tinygram.\n");
-               *hotdrop = 1;
-               return 0;
+               *hotdrop = true;
+               return false;
        }
 
        return port_match(udpinfo->spts[0], udpinfo->spts[1],
@@ -184,7 +181,7 @@ udp_match(const struct sk_buff *skb,
 }
 
 /* Called when user tries to insert an entry of this type. */
-static int
+static bool
 udp_checkentry(const char *tablename,
               const void *info,
               const struct xt_match *match,
@@ -197,7 +194,7 @@ udp_checkentry(const char *tablename,
        return !(udpinfo->invflags & ~XT_UDP_INV_MASK);
 }
 
-static struct xt_match xt_tcpudp_match[] = {
+static struct xt_match xt_tcpudp_match[] __read_mostly = {
        {
                .name           = "tcp",
                .family         = AF_INET,
diff --git a/net/netfilter/xt_u32.c b/net/netfilter/xt_u32.c
new file mode 100644 (file)
index 0000000..04b677a
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ *     xt_u32 - kernel module to match u32 packet content
+ *
+ *     Original author: Don Cohen <don@isis.cs3-inc.com>
+ *     Â© Jan Engelhardt <jengelh@gmx.de>, 2007
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/spinlock.h>
+#include <linux/skbuff.h>
+#include <linux/types.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter/xt_u32.h>
+
+static bool u32_match_it(const struct xt_u32 *data,
+                        const struct sk_buff *skb)
+{
+       const struct xt_u32_test *ct;
+       unsigned int testind;
+       unsigned int nnums;
+       unsigned int nvals;
+       unsigned int i;
+       u_int32_t pos;
+       u_int32_t val;
+       u_int32_t at;
+       int ret;
+
+       /*
+        * Small example: "0 >> 28 == 4 && 8 & 0xFF0000 >> 16 = 6, 17"
+        * (=IPv4 and (TCP or UDP)). Outer loop runs over the "&&" operands.
+        */
+       for (testind = 0; testind < data->ntests; ++testind) {
+               ct  = &data->tests[testind];
+               at  = 0;
+               pos = ct->location[0].number;
+
+               if (skb->len < 4 || pos > skb->len - 4);
+                       return false;
+
+               ret   = skb_copy_bits(skb, pos, &val, sizeof(val));
+               BUG_ON(ret < 0);
+               val   = ntohl(val);
+               nnums = ct->nnums;
+
+               /* Inner loop runs over "&", "<<", ">>" and "@" operands */
+               for (i = 1; i < nnums; ++i) {
+                       u_int32_t number = ct->location[i].number;
+                       switch (ct->location[i].nextop) {
+                       case XT_U32_AND:
+                               val &= number;
+                               break;
+                       case XT_U32_LEFTSH:
+                               val <<= number;
+                               break;
+                       case XT_U32_RIGHTSH:
+                               val >>= number;
+                               break;
+                       case XT_U32_AT:
+                               if (at + val < at)
+                                       return false;
+                               at += val;
+                               pos = number;
+                               if (at + 4 < at || skb->len < at + 4 ||
+                                   pos > skb->len - at - 4)
+                                       return false;
+
+                               ret = skb_copy_bits(skb, at + pos, &val,
+                                                   sizeof(val));
+                               BUG_ON(ret < 0);
+                               val = ntohl(val);
+                               break;
+                       }
+               }
+
+               /* Run over the "," and ":" operands */
+               nvals = ct->nvalues;
+               for (i = 0; i < nvals; ++i)
+                       if (ct->value[i].min <= val && val <= ct->value[i].max)
+                               break;
+
+               if (i >= ct->nvalues)
+                       return false;
+       }
+
+       return true;
+}
+
+static bool u32_match(const struct sk_buff *skb,
+                     const struct net_device *in,
+                     const struct net_device *out,
+                     const struct xt_match *match, const void *matchinfo,
+                     int offset, unsigned int protoff, bool *hotdrop)
+{
+       const struct xt_u32 *data = matchinfo;
+       bool ret;
+
+       ret = u32_match_it(data, skb);
+       return ret ^ data->invert;
+}
+
+static struct xt_match u32_reg[] __read_mostly = {
+       {
+               .name       = "u32",
+               .family     = AF_INET,
+               .match      = u32_match,
+               .matchsize  = sizeof(struct xt_u32),
+               .me         = THIS_MODULE,
+       },
+       {
+               .name       = "u32",
+               .family     = AF_INET6,
+               .match      = u32_match,
+               .matchsize  = sizeof(struct xt_u32),
+               .me         = THIS_MODULE,
+       },
+};
+
+static int __init xt_u32_init(void)
+{
+       return xt_register_matches(u32_reg, ARRAY_SIZE(u32_reg));
+}
+
+static void __exit xt_u32_exit(void)
+{
+       xt_unregister_matches(u32_reg, ARRAY_SIZE(u32_reg));
+}
+
+module_init(xt_u32_init);
+module_exit(xt_u32_exit);
+MODULE_AUTHOR("Jan Engelhardt <jengelh@gmx.de>");
+MODULE_DESCRIPTION("netfilter u32 match module");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("ipt_u32");
+MODULE_ALIAS("ip6t_u32");
index 1f15821c8da4c64894fd7e07d8340a8b8c430b4a..a3c8e692f493902b0b7eb916dbfd4c781fe6d3d5 100644 (file)
@@ -1713,7 +1713,7 @@ static int netlink_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations netlink_seq_ops = {
+static const struct seq_operations netlink_seq_ops = {
        .start  = netlink_seq_start,
        .next   = netlink_seq_next,
        .stop   = netlink_seq_stop,
index c591212793ee4d7cbd981cabe753a5825f68b4fc..e4d7bed99c2e8bbc763cef5fbb24a01a2ad91694 100644 (file)
@@ -72,6 +72,17 @@ static int validate_nla(struct nlattr *nla, int maxtype,
                        return -ERANGE;
                break;
 
+       case NLA_NESTED_COMPAT:
+               if (attrlen < pt->len)
+                       return -ERANGE;
+               if (attrlen < NLA_ALIGN(pt->len))
+                       break;
+               if (attrlen < NLA_ALIGN(pt->len) + NLA_HDRLEN)
+                       return -ERANGE;
+               nla = nla_data(nla) + NLA_ALIGN(pt->len);
+               if (attrlen < NLA_ALIGN(pt->len) + NLA_HDRLEN + nla_len(nla))
+                       return -ERANGE;
+               break;
        default:
                if (pt->len)
                        minlen = pt->len;
index 5d4a26c2aa0c7027a0e8c906600ef3a46f5af607..5d66490dd290a07a7c989465ee5b21c98aed2a83 100644 (file)
@@ -1328,7 +1328,7 @@ static int nr_info_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations nr_info_seqops = {
+static const struct seq_operations nr_info_seqops = {
        .start = nr_info_start,
        .next = nr_info_next,
        .stop = nr_info_stop,
index 2f76e062609d581b7ab7066c017fa9bf5e651983..24fe4a66d297d37ebc9600c3e15f263122a53d30 100644 (file)
@@ -922,7 +922,7 @@ static int nr_node_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations nr_node_seqops = {
+static const struct seq_operations nr_node_seqops = {
        .start = nr_node_start,
        .next = nr_node_next,
        .stop = nr_node_stop,
@@ -1006,7 +1006,7 @@ static int nr_neigh_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations nr_neigh_seqops = {
+static const struct seq_operations nr_neigh_seqops = {
        .start = nr_neigh_start,
        .next = nr_neigh_next,
        .stop = nr_neigh_stop,
index f8b83014cccad9ad56108cd1f6a3dce8b71f2b1d..7c27bd389b7ef29c3cdb2b9c6f978d733ff726c3 100644 (file)
@@ -1928,7 +1928,7 @@ static int packet_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations packet_seq_ops = {
+static const struct seq_operations packet_seq_ops = {
        .start  = packet_seq_start,
        .next   = packet_seq_next,
        .stop   = packet_seq_stop,
index d476c43d52169082f65f3da2be124470a23786d6..f4d3aba008009298fc1b77a5314005225392bcfb 100644 (file)
@@ -1454,7 +1454,7 @@ static int rose_info_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations rose_info_seqops = {
+static const struct seq_operations rose_info_seqops = {
        .start = rose_info_start,
        .next = rose_info_next,
        .stop = rose_info_stop,
index 929a784a86d72cef17e10bf98bca7a178a474eae..bbcbad1da0d0facf25941e74a703bde898d941cd 100644 (file)
@@ -1118,7 +1118,7 @@ static int rose_node_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations rose_node_seqops = {
+static const struct seq_operations rose_node_seqops = {
        .start = rose_node_start,
        .next = rose_node_next,
        .stop = rose_node_stop,
@@ -1200,7 +1200,7 @@ static int rose_neigh_show(struct seq_file *seq, void *v)
 }
 
 
-static struct seq_operations rose_neigh_seqops = {
+static const struct seq_operations rose_neigh_seqops = {
        .start = rose_neigh_start,
        .next = rose_neigh_next,
        .stop = rose_neigh_stop,
@@ -1284,7 +1284,7 @@ static int rose_route_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations rose_route_seqops = {
+static const struct seq_operations rose_route_seqops = {
        .start = rose_route_start,
        .next = rose_route_next,
        .stop = rose_route_stop,
index 1c0be0e77b162949fa74ebd32587773276cdf818..2e83ce325d151e090e05cc0c18e2de55cd82a04d 100644 (file)
@@ -30,31 +30,13 @@ static const char *rxrpc_conn_states[] = {
  */
 static void *rxrpc_call_seq_start(struct seq_file *seq, loff_t *_pos)
 {
-       struct list_head *_p;
-       loff_t pos = *_pos;
-
        read_lock(&rxrpc_call_lock);
-       if (!pos)
-               return SEQ_START_TOKEN;
-       pos--;
-
-       list_for_each(_p, &rxrpc_calls)
-               if (!pos--)
-                       break;
-
-       return _p != &rxrpc_calls ? _p : NULL;
+       return seq_list_start_head(&rxrpc_calls, *_pos);
 }
 
 static void *rxrpc_call_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
-       struct list_head *_p;
-
-       (*pos)++;
-
-       _p = v;
-       _p = (v == SEQ_START_TOKEN) ? rxrpc_calls.next : _p->next;
-
-       return _p != &rxrpc_calls ? _p : NULL;
+       return seq_list_next(v, &rxrpc_calls, pos);
 }
 
 static void rxrpc_call_seq_stop(struct seq_file *seq, void *v)
@@ -68,7 +50,7 @@ static int rxrpc_call_seq_show(struct seq_file *seq, void *v)
        struct rxrpc_call *call;
        char lbuff[4 + 4 + 4 + 4 + 5 + 1], rbuff[4 + 4 + 4 + 4 + 5 + 1];
 
-       if (v == SEQ_START_TOKEN) {
+       if (v == &rxrpc_calls) {
                seq_puts(seq,
                         "Proto Local                  Remote                "
                         " SvID ConnID   CallID   End Use State    Abort   "
@@ -104,7 +86,7 @@ static int rxrpc_call_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations rxrpc_call_seq_ops = {
+static const struct seq_operations rxrpc_call_seq_ops = {
        .start  = rxrpc_call_seq_start,
        .next   = rxrpc_call_seq_next,
        .stop   = rxrpc_call_seq_stop,
@@ -129,32 +111,14 @@ struct file_operations rxrpc_call_seq_fops = {
  */
 static void *rxrpc_connection_seq_start(struct seq_file *seq, loff_t *_pos)
 {
-       struct list_head *_p;
-       loff_t pos = *_pos;
-
        read_lock(&rxrpc_connection_lock);
-       if (!pos)
-               return SEQ_START_TOKEN;
-       pos--;
-
-       list_for_each(_p, &rxrpc_connections)
-               if (!pos--)
-                       break;
-
-       return _p != &rxrpc_connections ? _p : NULL;
+       return seq_list_start_head(&rxrpc_connections, *_pos);
 }
 
 static void *rxrpc_connection_seq_next(struct seq_file *seq, void *v,
                                       loff_t *pos)
 {
-       struct list_head *_p;
-
-       (*pos)++;
-
-       _p = v;
-       _p = (v == SEQ_START_TOKEN) ? rxrpc_connections.next : _p->next;
-
-       return _p != &rxrpc_connections ? _p : NULL;
+       return seq_list_next(v, &rxrpc_connections, pos);
 }
 
 static void rxrpc_connection_seq_stop(struct seq_file *seq, void *v)
@@ -168,7 +132,7 @@ static int rxrpc_connection_seq_show(struct seq_file *seq, void *v)
        struct rxrpc_transport *trans;
        char lbuff[4 + 4 + 4 + 4 + 5 + 1], rbuff[4 + 4 + 4 + 4 + 5 + 1];
 
-       if (v == SEQ_START_TOKEN) {
+       if (v == &rxrpc_connections) {
                seq_puts(seq,
                         "Proto Local                  Remote                "
                         " SvID ConnID   Calls    End Use State    Key     "
@@ -206,7 +170,7 @@ static int rxrpc_connection_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations rxrpc_connection_seq_ops = {
+static const struct seq_operations rxrpc_connection_seq_ops = {
        .start  = rxrpc_connection_seq_start,
        .next   = rxrpc_connection_seq_next,
        .stop   = rxrpc_connection_seq_stop,
index 475df8449be9eee788a700a238b655534a23ff9d..b4662888bdbd9d6df32cb8c25d2ba2ca6188953d 100644 (file)
@@ -111,6 +111,17 @@ config NET_SCH_PRIO
          To compile this code as a module, choose M here: the
          module will be called sch_prio.
 
+config NET_SCH_RR
+       tristate "Multi Band Round Robin Queuing (RR)"
+       select NET_SCH_PRIO
+       ---help---
+         Say Y here if you want to use an n-band round robin packet
+         scheduler.
+
+         The module uses sch_prio for its framework and is aliased as
+         sch_rr, so it will load sch_prio, although it is referred
+         to using sch_rr.
+
 config NET_SCH_RED
        tristate "Random Early Detection (RED)"
        ---help---
@@ -275,7 +286,6 @@ config CLS_U32_MARK
 config NET_CLS_RSVP
        tristate "IPv4 Resource Reservation Protocol (RSVP)"
        select NET_CLS
-       select NET_ESTIMATOR
        ---help---
          The Resource Reservation Protocol (RSVP) permits end systems to
          request a minimum and maximum data flow rate for a connection; this
@@ -290,7 +300,6 @@ config NET_CLS_RSVP
 config NET_CLS_RSVP6
        tristate "IPv6 Resource Reservation Protocol (RSVP6)"
        select NET_CLS
-       select NET_ESTIMATOR
        ---help---
          The Resource Reservation Protocol (RSVP) permits end systems to
          request a minimum and maximum data flow rate for a connection; this
@@ -382,7 +391,6 @@ config NET_EMATCH_TEXT
 
 config NET_CLS_ACT
        bool "Actions"
-       select NET_ESTIMATOR
        ---help---
          Say Y here if you want to use traffic control actions. Actions
          get attached to classifiers and are invoked after a successful
@@ -465,7 +473,6 @@ config NET_ACT_SIMP
 config NET_CLS_POLICE
        bool "Traffic Policing (obsolete)"
        depends on NET_CLS_ACT!=y
-       select NET_ESTIMATOR
        ---help---
          Say Y here if you want to do traffic policing, i.e. strict
          bandwidth limiting. This option is obsoleted by the traffic
@@ -480,14 +487,6 @@ config NET_CLS_IND
          classification based on the incoming device. This option is
          likely to disappear in favour of the metadata ematch.
 
-config NET_ESTIMATOR
-       bool "Rate estimator"
-       ---help---
-         Say Y here to allow using rate estimators to estimate the current
-         rate-of-flow for network devices, queues, etc. This module is
-         automatically selected if needed but can be selected manually for
-         statistical purposes.
-
 endif # NET_SCHED
 
 endmenu
index 711dd26c95c325a42937ba083f970c5d8b77b197..feef366cad5dab0ad6f36a18ae0ec7203b1f1641 100644 (file)
  *
  */
 
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/init.h>
 #include <linux/kmod.h>
-#include <net/sock.h>
 #include <net/sch_generic.h>
 #include <net/act_api.h>
 #include <net/netlink.h>
@@ -42,10 +32,8 @@ void tcf_hash_destroy(struct tcf_common *p, struct tcf_hashinfo *hinfo)
                        write_lock_bh(hinfo->lock);
                        *p1p = p->tcfc_next;
                        write_unlock_bh(hinfo->lock);
-#ifdef CONFIG_NET_ESTIMATOR
                        gen_kill_estimator(&p->tcfc_bstats,
                                           &p->tcfc_rate_est);
-#endif
                        kfree(p);
                        return;
                }
@@ -232,15 +220,12 @@ struct tcf_common *tcf_hash_create(u32 index, struct rtattr *est, struct tc_acti
                p->tcfc_bindcnt = 1;
 
        spin_lock_init(&p->tcfc_lock);
-       p->tcfc_stats_lock = &p->tcfc_lock;
        p->tcfc_index = index ? index : tcf_hash_new_index(idx_gen, hinfo);
        p->tcfc_tm.install = jiffies;
        p->tcfc_tm.lastuse = jiffies;
-#ifdef CONFIG_NET_ESTIMATOR
        if (est)
                gen_new_estimator(&p->tcfc_bstats, &p->tcfc_rate_est,
-                                 p->tcfc_stats_lock, est);
-#endif
+                                 &p->tcfc_lock, est);
        a->priv = (void *) p;
        return p;
 }
@@ -599,12 +584,12 @@ int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *a,
        if (compat_mode) {
                if (a->type == TCA_OLD_COMPAT)
                        err = gnet_stats_start_copy_compat(skb, 0,
-                               TCA_STATS, TCA_XSTATS, h->tcf_stats_lock, &d);
+                               TCA_STATS, TCA_XSTATS, &h->tcf_lock, &d);
                else
                        return 0;
        } else
                err = gnet_stats_start_copy(skb, TCA_ACT_STATS,
-                       h->tcf_stats_lock, &d);
+                                           &h->tcf_lock, &d);
 
        if (err < 0)
                goto errout;
@@ -614,9 +599,7 @@ int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *a,
                        goto errout;
 
        if (gnet_stats_copy_basic(&d, &h->tcf_bstats) < 0 ||
-#ifdef CONFIG_NET_ESTIMATOR
            gnet_stats_copy_rate_est(&d, &h->tcf_rate_est) < 0 ||
-#endif
            gnet_stats_copy_queue(&d, &h->tcf_qstats) < 0)
                goto errout;
 
index 7517f3791541789fd5601d1ff606c044debff72d..a9631e426d916c81fbe752cd5357d75e50f4dace 100644 (file)
  *
  */
 
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/rtnetlink.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/proc_fs.h>
 #include <net/netlink.h>
-#include <net/sock.h>
 #include <net/pkt_sched.h>
 #include <linux/tc_act/tc_gact.h>
 #include <net/tc_act/tc_gact.h>
index 00b05f422d45016195f124c81c1ab7d31aab62ab..6b407ece953c2ddb54ef90eff2c6e3d6fe86e341 100644 (file)
  * Copyright:  Jamal Hadi Salim (2002-4)
  */
 
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/rtnetlink.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/proc_fs.h>
-#include <linux/kmod.h>
 #include <net/netlink.h>
-#include <net/sock.h>
 #include <net/pkt_sched.h>
 #include <linux/tc_act/tc_ipt.h>
 #include <net/tc_act/tc_ipt.h>
index de21c92faaa29ed9a4162aa7f7f982423a58b555..579578944ae778b34c771ed73632cc50dd6b96b2 100644 (file)
  *
  */
 
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/rtnetlink.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/proc_fs.h>
 #include <net/netlink.h>
-#include <net/sock.h>
 #include <net/pkt_sched.h>
 #include <linux/tc_act/tc_mirred.h>
 #include <net/tc_act/tc_mirred.h>
 
-#include <linux/etherdevice.h>
 #include <linux/if_arp.h>
 
 #define MIRRED_TAB_MASK     7
index 6f8684b5617e5653e2fe5bcfd09aee084c7d9134..b46fab5fb323a131946ce418b6d97c8889a941f3 100644 (file)
@@ -9,26 +9,15 @@
  * Authors:    Jamal Hadi Salim (2002-4)
  */
 
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/rtnetlink.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/proc_fs.h>
 #include <net/netlink.h>
-#include <net/sock.h>
 #include <net/pkt_sched.h>
 #include <linux/tc_act/tc_pedit.h>
 #include <net/tc_act/tc_pedit.h>
index 616f465f407e03d33feaffc17f45a937fb3fcd23..d20403890877d50472fea0fa340df4abc9e9e459 100644 (file)
  *             J Hadi Salim (action changes)
  */
 
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/module.h>
 #include <linux/rtnetlink.h>
 #include <linux/init.h>
-#include <net/sock.h>
 #include <net/act_api.h>
 #include <net/netlink.h>
 
@@ -118,10 +108,8 @@ void tcf_police_destroy(struct tcf_police *p)
                        write_lock_bh(&police_lock);
                        *p1p = p->tcf_next;
                        write_unlock_bh(&police_lock);
-#ifdef CONFIG_NET_ESTIMATOR
                        gen_kill_estimator(&p->tcf_bstats,
                                           &p->tcf_rate_est);
-#endif
                        if (p->tcfp_R_tab)
                                qdisc_put_rtab(p->tcfp_R_tab);
                        if (p->tcfp_P_tab)
@@ -185,7 +173,6 @@ static int tcf_act_police_locate(struct rtattr *rta, struct rtattr *est,
        ret = ACT_P_CREATED;
        police->tcf_refcnt = 1;
        spin_lock_init(&police->tcf_lock);
-       police->tcf_stats_lock = &police->tcf_lock;
        if (bind)
                police->tcf_bindcnt = 1;
 override:
@@ -227,15 +214,13 @@ override:
                police->tcfp_ptoks = L2T_P(police, police->tcfp_mtu);
        police->tcf_action = parm->action;
 
-#ifdef CONFIG_NET_ESTIMATOR
        if (tb[TCA_POLICE_AVRATE-1])
                police->tcfp_ewma_rate =
                        *(u32*)RTA_DATA(tb[TCA_POLICE_AVRATE-1]);
        if (est)
                gen_replace_estimator(&police->tcf_bstats,
                                      &police->tcf_rate_est,
-                                     police->tcf_stats_lock, est);
-#endif
+                                     &police->tcf_lock, est);
 
        spin_unlock_bh(&police->tcf_lock);
        if (ret != ACT_P_CREATED)
@@ -281,14 +266,12 @@ static int tcf_act_police(struct sk_buff *skb, struct tc_action *a,
        police->tcf_bstats.bytes += skb->len;
        police->tcf_bstats.packets++;
 
-#ifdef CONFIG_NET_ESTIMATOR
        if (police->tcfp_ewma_rate &&
            police->tcf_rate_est.bps >= police->tcfp_ewma_rate) {
                police->tcf_qstats.overlimits++;
                spin_unlock(&police->tcf_lock);
                return police->tcf_action;
        }
-#endif
 
        if (skb->len <= police->tcfp_mtu) {
                if (police->tcfp_R_tab == NULL) {
@@ -348,10 +331,8 @@ tcf_act_police_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
        if (police->tcfp_result)
                RTA_PUT(skb, TCA_POLICE_RESULT, sizeof(int),
                        &police->tcfp_result);
-#ifdef CONFIG_NET_ESTIMATOR
        if (police->tcfp_ewma_rate)
                RTA_PUT(skb, TCA_POLICE_AVRATE, 4, &police->tcfp_ewma_rate);
-#endif
        return skb->len;
 
 rtattr_failure:
@@ -458,7 +439,6 @@ struct tcf_police *tcf_police_locate(struct rtattr *rta, struct rtattr *est)
 
        police->tcf_refcnt = 1;
        spin_lock_init(&police->tcf_lock);
-       police->tcf_stats_lock = &police->tcf_lock;
        if (parm->rate.rate) {
                police->tcfp_R_tab =
                        qdisc_get_rtab(&parm->rate, tb[TCA_POLICE_RATE-1]);
@@ -477,14 +457,12 @@ struct tcf_police *tcf_police_locate(struct rtattr *rta, struct rtattr *est)
                        goto failure;
                police->tcfp_result = *(u32*)RTA_DATA(tb[TCA_POLICE_RESULT-1]);
        }
-#ifdef CONFIG_NET_ESTIMATOR
        if (tb[TCA_POLICE_AVRATE-1]) {
                if (RTA_PAYLOAD(tb[TCA_POLICE_AVRATE-1]) != sizeof(u32))
                        goto failure;
                police->tcfp_ewma_rate =
                        *(u32*)RTA_DATA(tb[TCA_POLICE_AVRATE-1]);
        }
-#endif
        police->tcfp_toks = police->tcfp_burst = parm->burst;
        police->tcfp_mtu = parm->mtu;
        if (police->tcfp_mtu == 0) {
@@ -498,11 +476,9 @@ struct tcf_police *tcf_police_locate(struct rtattr *rta, struct rtattr *est)
        police->tcf_index = parm->index ? parm->index :
                tcf_police_new_index();
        police->tcf_action = parm->action;
-#ifdef CONFIG_NET_ESTIMATOR
        if (est)
                gen_new_estimator(&police->tcf_bstats, &police->tcf_rate_est,
-                                 police->tcf_stats_lock, est);
-#endif
+                                 &police->tcf_lock, est);
        h = tcf_hash(police->tcf_index, POL_TAB_MASK);
        write_lock_bh(&police_lock);
        police->tcf_next = tcf_police_ht[h];
@@ -528,14 +504,12 @@ int tcf_police(struct sk_buff *skb, struct tcf_police *police)
        police->tcf_bstats.bytes += skb->len;
        police->tcf_bstats.packets++;
 
-#ifdef CONFIG_NET_ESTIMATOR
        if (police->tcfp_ewma_rate &&
            police->tcf_rate_est.bps >= police->tcfp_ewma_rate) {
                police->tcf_qstats.overlimits++;
                spin_unlock(&police->tcf_lock);
                return police->tcf_action;
        }
-#endif
        if (skb->len <= police->tcfp_mtu) {
                if (police->tcfp_R_tab == NULL) {
                        spin_unlock(&police->tcf_lock);
@@ -591,10 +565,8 @@ int tcf_police_dump(struct sk_buff *skb, struct tcf_police *police)
        if (police->tcfp_result)
                RTA_PUT(skb, TCA_POLICE_RESULT, sizeof(int),
                        &police->tcfp_result);
-#ifdef CONFIG_NET_ESTIMATOR
        if (police->tcfp_ewma_rate)
                RTA_PUT(skb, TCA_POLICE_AVRATE, 4, &police->tcfp_ewma_rate);
-#endif
        return skb->len;
 
 rtattr_failure:
@@ -607,14 +579,12 @@ int tcf_police_dump_stats(struct sk_buff *skb, struct tcf_police *police)
        struct gnet_dump d;
 
        if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS,
-                                        TCA_XSTATS, police->tcf_stats_lock,
+                                        TCA_XSTATS, &police->tcf_lock,
                                         &d) < 0)
                goto errout;
 
        if (gnet_stats_copy_basic(&d, &police->tcf_bstats) < 0 ||
-#ifdef CONFIG_NET_ESTIMATOR
            gnet_stats_copy_rate_est(&d, &police->tcf_rate_est) < 0 ||
-#endif
            gnet_stats_copy_queue(&d, &police->tcf_qstats) < 0)
                goto errout;
 
index 36e1edad599017866a62d179b5b576520cf43875..fb84ef33d14f75d82281ab21b932ebea416e1e6f 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
-#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/rtnetlink.h>
 #include <net/netlink.h>
index ebf94edf0478b6517d7b22b95e3cbb225a6229e1..36b72aab1bde35ccf92b95c74f59432103103293 100644 (file)
  *
  */
 
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/init.h>
 #include <linux/kmod.h>
 #include <linux/netlink.h>
 #include <net/netlink.h>
-#include <net/sock.h>
 #include <net/pkt_sched.h>
 #include <net/pkt_cls.h>
 
index c885412d79d5d7613145015e26d05fdd4df55e94..8dbcf2771a4611e921fdb37d75f05a2ccea63f4b 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/mm.h>
 #include <linux/errno.h>
 #include <linux/rtnetlink.h>
 #include <linux/skbuff.h>
index bbec4a0d4dcb006dc342a3bb91c3bd437298e035..8adbd6a37d1475cbee48622b0cbbc230725be13e 100644 (file)
  */
 
 #include <linux/module.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/if_ether.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/notifier.h>
-#include <linux/netfilter.h>
-#include <net/ip.h>
-#include <net/netlink.h>
-#include <net/route.h>
 #include <linux/skbuff.h>
-#include <net/sock.h>
+#include <net/netlink.h>
 #include <net/act_api.h>
 #include <net/pkt_cls.h>
 
index cc941d0ee3a5daf9c51065b9e3fce766d32ea8bd..0a8409c1d28ae4d3c4cdeeb346625a8ef01beee1 100644 (file)
  */
 
 #include <linux/module.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/if_ether.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/notifier.h>
-#include <net/ip.h>
-#include <net/netlink.h>
-#include <net/route.h>
 #include <linux/skbuff.h>
-#include <net/sock.h>
+#include <net/dst.h>
+#include <net/route.h>
+#include <net/netlink.h>
 #include <net/act_api.h>
 #include <net/pkt_cls.h>
 
index 0a683c07c648342781cda4c9f25bf5e43cb60152..cbb5e0d600f32951cf4cadb1a080352064869cc8 100644 (file)
  */
 
 #include <linux/module.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/if_ether.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/notifier.h>
-#include <net/ip.h>
-#include <net/route.h>
 #include <linux/skbuff.h>
-#include <net/sock.h>
+#include <net/ip.h>
 #include <net/netlink.h>
 #include <net/act_api.h>
 #include <net/pkt_cls.h>
index 93b6abed57db517e14f457876b43b038038d94bd..dd08aea2aee524b0f7ecddea5be17b72ceba20be 100644 (file)
  */
 
 #include <linux/module.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/if_ether.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/notifier.h>
-#include <net/ip.h>
 #include <linux/ipv6.h>
-#include <net/route.h>
 #include <linux/skbuff.h>
-#include <net/sock.h>
 #include <net/act_api.h>
 #include <net/pkt_cls.h>
 #include <net/netlink.h>
index 47ac0c556429d6b41d4a1443a2316ade53229e0f..2314820a080a3d7e94b4e523c1dc242ce1c493b7 100644 (file)
@@ -9,12 +9,9 @@
 #include <linux/kernel.h>
 #include <linux/skbuff.h>
 #include <linux/errno.h>
-#include <linux/netdevice.h>
-#include <net/ip.h>
 #include <net/act_api.h>
 #include <net/netlink.h>
 #include <net/pkt_cls.h>
-#include <net/route.h>
 
 
 /*
index c7a347bd6d702d91574265b9ca8d4301bd960dfb..77961e2314dc6c1fa367e688558941e1532fa20c 100644 (file)
  *     nfmark match added by Catalin(ux aka Dino) BOIE <catab at umbrella.ro>
  */
 
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/if_ether.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/notifier.h>
 #include <linux/rtnetlink.h>
-#include <net/ip.h>
-#include <net/netlink.h>
-#include <net/route.h>
 #include <linux/skbuff.h>
-#include <net/sock.h>
+#include <net/netlink.h>
 #include <net/act_api.h>
 #include <net/pkt_cls.h>
 
index 8d6dacd8190054a9cc401d48342232644ad3e7a9..cc49c932641d97c66521c13b45fb4374792d8c4a 100644 (file)
@@ -98,3 +98,4 @@ MODULE_LICENSE("GPL");
 module_init(init_em_cmp);
 module_exit(exit_em_cmp);
 
+MODULE_ALIAS_TCF_EMATCH(TCF_EM_CMP);
index 60acf8cdb27b34774f71dfdf79654349bf26cc5a..650f09c8bd6a77b41f376f9213781547adb032c2 100644 (file)
@@ -848,3 +848,5 @@ MODULE_LICENSE("GPL");
 
 module_init(init_em_meta);
 module_exit(exit_em_meta);
+
+MODULE_ALIAS_TCF_EMATCH(TCF_EM_META);
index b4b36efce29248e37f1e2a941fa45743d76e4f52..370a1b2ea31770b4ce08196f146d43da12f31f4e 100644 (file)
@@ -76,3 +76,5 @@ MODULE_LICENSE("GPL");
 
 module_init(init_em_nbyte);
 module_exit(exit_em_nbyte);
+
+MODULE_ALIAS_TCF_EMATCH(TCF_EM_NBYTE);
index e8f46169449d8c5985cba6baed0096aa1610b2ab..d5cd86efb7d08fa8f3564f5edb89aee9557e5840 100644 (file)
@@ -150,3 +150,5 @@ MODULE_LICENSE("GPL");
 
 module_init(init_em_text);
 module_exit(exit_em_text);
+
+MODULE_ALIAS_TCF_EMATCH(TCF_EM_TEXT);
index 0a2a7fe08de3a9cce042c91865e2209d06ef16e6..112796e4a7c469d7147328ec54d507bd4e468c9f 100644 (file)
@@ -60,3 +60,5 @@ MODULE_LICENSE("GPL");
 
 module_init(init_em_u32);
 module_exit(exit_em_u32);
+
+MODULE_ALIAS_TCF_EMATCH(TCF_EM_U32);
index 63146d339d814e09a19cd26ba6909e3c9c9e8b6b..f3a104e323bddd50c299c74c928a95038f1f5af5 100644 (file)
@@ -84,9 +84,7 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/mm.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
 #include <linux/rtnetlink.h>
 #include <linux/skbuff.h>
 #include <net/pkt_cls.h>
@@ -224,6 +222,19 @@ static int tcf_em_validate(struct tcf_proto *tp,
 
                if (em->ops == NULL) {
                        err = -ENOENT;
+#ifdef CONFIG_KMOD
+                       __rtnl_unlock();
+                       request_module("ematch-kind-%u", em_hdr->kind);
+                       rtnl_lock();
+                       em->ops = tcf_em_lookup(em_hdr->kind);
+                       if (em->ops) {
+                               /* We dropped the RTNL mutex in order to
+                                * perform the module load. Tell the caller
+                                * to replay the request. */
+                               module_put(em->ops->owner);
+                               err = -EAGAIN;
+                       }
+#endif
                        goto errout;
                }
 
index bec600af03cac30ded0a6171127ff6bc1fb794d8..d92ea26982c56c88adf73d56728854d406681fde 100644 (file)
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/init.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/kmod.h>
 #include <linux/list.h>
-#include <linux/bitops.h>
 #include <linux/hrtimer.h>
 
 #include <net/netlink.h>
-#include <net/sock.h>
 #include <net/pkt_sched.h>
 
-#include <asm/processor.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-
 static int qdisc_notify(struct sk_buff *oskb, struct nlmsghdr *n, u32 clid,
                        struct Qdisc *old, struct Qdisc *new);
 static int tclass_notify(struct sk_buff *oskb, struct nlmsghdr *n,
@@ -515,7 +503,6 @@ qdisc_create(struct net_device *dev, u32 handle, struct rtattr **tca, int *errp)
        sch->handle = handle;
 
        if (!ops->init || (err = ops->init(sch, tca[TCA_OPTIONS-1])) == 0) {
-#ifdef CONFIG_NET_ESTIMATOR
                if (tca[TCA_RATE-1]) {
                        err = gen_new_estimator(&sch->bstats, &sch->rate_est,
                                                sch->stats_lock,
@@ -531,7 +518,6 @@ qdisc_create(struct net_device *dev, u32 handle, struct rtattr **tca, int *errp)
                                goto err_out3;
                        }
                }
-#endif
                qdisc_lock_tree(dev);
                list_add_tail(&sch->list, &dev->qdisc_list);
                qdisc_unlock_tree(dev);
@@ -559,11 +545,9 @@ static int qdisc_change(struct Qdisc *sch, struct rtattr **tca)
                if (err)
                        return err;
        }
-#ifdef CONFIG_NET_ESTIMATOR
        if (tca[TCA_RATE-1])
                gen_replace_estimator(&sch->bstats, &sch->rate_est,
                        sch->stats_lock, tca[TCA_RATE-1]);
-#endif
        return 0;
 }
 
@@ -839,9 +823,7 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid,
                goto rtattr_failure;
 
        if (gnet_stats_copy_basic(&d, &q->bstats) < 0 ||
-#ifdef CONFIG_NET_ESTIMATOR
            gnet_stats_copy_rate_est(&d, &q->rate_est) < 0 ||
-#endif
            gnet_stats_copy_queue(&d, &q->qstats) < 0)
                goto rtattr_failure;
 
index d1c383fca82c277b2d7c2138b9f4226d25500a5f..54b92d22796c26e5fc220e112d51ea0981ee2a9e 100644 (file)
@@ -8,15 +8,12 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/skbuff.h>
-#include <linux/interrupt.h>
 #include <linux/atmdev.h>
 #include <linux/atmclip.h>
-#include <linux/netdevice.h>
 #include <linux/rtnetlink.h>
 #include <linux/file.h> /* for fput */
 #include <net/netlink.h>
 #include <net/pkt_sched.h>
-#include <net/sock.h>
 
 
 extern struct socket *sockfd_lookup(int fd, int *err); /* @@@ fix this */
@@ -71,7 +68,6 @@ struct atm_flow_data {
        int                     ref;            /* reference count */
        struct gnet_stats_basic bstats;
        struct gnet_stats_queue qstats;
-       spinlock_t              *stats_lock;
        struct atm_flow_data    *next;
        struct atm_flow_data    *excess;        /* flow for excess traffic;
                                                   NULL to set CLP instead */
index cb0c456aa34929478c36c4bc64fb4f2df1cad6f8..f914fc43a12478b9db41d037647b7ffe714fd5ee 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <net/pkt_sched.h>
 
index ee2d5967d109bdd61c7eb67c4ec04d585974b1f5..b184c35451455446d1d4407c205f83fe6a57a405 100644 (file)
  */
 
 #include <linux/module.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/if_ether.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/notifier.h>
-#include <net/ip.h>
-#include <net/netlink.h>
-#include <net/route.h>
 #include <linux/skbuff.h>
-#include <net/sock.h>
+#include <net/netlink.h>
 #include <net/pkt_sched.h>
 
 
@@ -148,7 +132,6 @@ struct cbq_class
        struct gnet_stats_basic bstats;
        struct gnet_stats_queue qstats;
        struct gnet_stats_rate_est rate_est;
-       spinlock_t              *stats_lock;
        struct tc_cbq_xstats    xstats;
 
        struct tcf_proto        *filter_list;
@@ -1442,7 +1425,6 @@ static int cbq_init(struct Qdisc *sch, struct rtattr *opt)
        q->link.ewma_log = TC_CBQ_DEF_EWMA;
        q->link.avpkt = q->link.allot/2;
        q->link.minidle = -0x7FFFFFFF;
-       q->link.stats_lock = &sch->dev->queue_lock;
 
        qdisc_watchdog_init(&q->watchdog, sch);
        hrtimer_init(&q->delay_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
@@ -1653,9 +1635,7 @@ cbq_dump_class_stats(struct Qdisc *sch, unsigned long arg,
                cl->xstats.undertime = cl->undertime - q->now;
 
        if (gnet_stats_copy_basic(d, &cl->bstats) < 0 ||
-#ifdef CONFIG_NET_ESTIMATOR
            gnet_stats_copy_rate_est(d, &cl->rate_est) < 0 ||
-#endif
            gnet_stats_copy_queue(d, &cl->qstats) < 0)
                return -1;
 
@@ -1726,9 +1706,7 @@ static void cbq_destroy_class(struct Qdisc *sch, struct cbq_class *cl)
        tcf_destroy_chain(cl->filter_list);
        qdisc_destroy(cl->q);
        qdisc_put_rtab(cl->R_tab);
-#ifdef CONFIG_NET_ESTIMATOR
        gen_kill_estimator(&cl->bstats, &cl->rate_est);
-#endif
        if (cl != &q->link)
                kfree(cl);
 }
@@ -1873,11 +1851,10 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct rtattr **t
 
                sch_tree_unlock(sch);
 
-#ifdef CONFIG_NET_ESTIMATOR
                if (tca[TCA_RATE-1])
                        gen_replace_estimator(&cl->bstats, &cl->rate_est,
-                               cl->stats_lock, tca[TCA_RATE-1]);
-#endif
+                                             &sch->dev->queue_lock,
+                                             tca[TCA_RATE-1]);
                return 0;
        }
 
@@ -1935,7 +1912,6 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct rtattr **t
        cl->allot = parent->allot;
        cl->quantum = cl->allot;
        cl->weight = cl->R_tab->rate.rate;
-       cl->stats_lock = &sch->dev->queue_lock;
 
        sch_tree_lock(sch);
        cbq_link_class(cl);
@@ -1963,11 +1939,9 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct rtattr **t
                cbq_set_fopt(cl, RTA_DATA(tb[TCA_CBQ_FOPT-1]));
        sch_tree_unlock(sch);
 
-#ifdef CONFIG_NET_ESTIMATOR
        if (tca[TCA_RATE-1])
                gen_new_estimator(&cl->bstats, &cl->rate_est,
-                       cl->stats_lock, tca[TCA_RATE-1]);
-#endif
+                                 &sch->dev->queue_lock, tca[TCA_RATE-1]);
 
        *arg = (unsigned long)cl;
        return 0;
index 3c6fd181263f7ac68bc2e29d30938a968479099d..4d2c233a861147cdcba15517a1ffeb545adacf87 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/skbuff.h>
-#include <linux/netdevice.h> /* for pkt_sched */
 #include <linux/rtnetlink.h>
 #include <net/pkt_sched.h>
 #include <net/dsfield.h>
index c2689f4ba8de9a3fdd364c6a4e3537852f1261a2..c264308f17c1f66f6f7e6c61ca309fa5378f5645 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
-#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <net/pkt_sched.h>
 
index f4d34480a093d126061920e6f53e7b4fc8dfe83b..c81649cf0b9ecc62316205286eb6149e869b910b 100644 (file)
  *              - Ingress support
  */
 
-#include <asm/uaccess.h>
-#include <asm/system.h>
 #include <linux/bitops.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/rtnetlink.h>
 #include <linux/init.h>
 #include <linux/rcupdate.h>
 #include <linux/list.h>
-#include <net/sock.h>
 #include <net/pkt_sched.h>
 
 /* Main transmission queue. */
@@ -59,122 +51,143 @@ void qdisc_unlock_tree(struct net_device *dev)
        spin_unlock_bh(&dev->queue_lock);
 }
 
-/*
-   dev->queue_lock serializes queue accesses for this device
-   AND dev->qdisc pointer itself.
+static inline int qdisc_qlen(struct Qdisc *q)
+{
+       return q->q.qlen;
+}
 
-   netif_tx_lock serializes accesses to device driver.
+static inline int dev_requeue_skb(struct sk_buff *skb, struct net_device *dev,
+                                 struct Qdisc *q)
+{
+       if (unlikely(skb->next))
+               dev->gso_skb = skb;
+       else
+               q->ops->requeue(skb, q);
 
-   dev->queue_lock and netif_tx_lock are mutually exclusive,
-   if one is grabbed, another must be free.
- */
+       netif_schedule(dev);
+       return 0;
+}
 
+static inline struct sk_buff *dev_dequeue_skb(struct net_device *dev,
+                                             struct Qdisc *q)
+{
+       struct sk_buff *skb;
 
-/* Kick device.
+       if ((skb = dev->gso_skb))
+               dev->gso_skb = NULL;
+       else
+               skb = q->dequeue(q);
 
-   Returns:  0  - queue is empty or throttled.
-           >0  - queue is not empty.
+       return skb;
+}
 
-   NOTE: Called under dev->queue_lock with locally disabled BH.
-*/
+static inline int handle_dev_cpu_collision(struct sk_buff *skb,
+                                          struct net_device *dev,
+                                          struct Qdisc *q)
+{
+       int ret;
 
+       if (unlikely(dev->xmit_lock_owner == smp_processor_id())) {
+               /*
+                * Same CPU holding the lock. It may be a transient
+                * configuration error, when hard_start_xmit() recurses. We
+                * detect it by checking xmit owner and drop the packet when
+                * deadloop is detected. Return OK to try the next skb.
+                */
+               kfree_skb(skb);
+               if (net_ratelimit())
+                       printk(KERN_WARNING "Dead loop on netdevice %s, "
+                              "fix it urgently!\n", dev->name);
+               ret = qdisc_qlen(q);
+       } else {
+               /*
+                * Another cpu is holding lock, requeue & delay xmits for
+                * some time.
+                */
+               __get_cpu_var(netdev_rx_stat).cpu_collision++;
+               ret = dev_requeue_skb(skb, dev, q);
+       }
+
+       return ret;
+}
+
+/*
+ * NOTE: Called under dev->queue_lock with locally disabled BH.
+ *
+ * __LINK_STATE_QDISC_RUNNING guarantees only one CPU can process this
+ * device at a time. dev->queue_lock serializes queue accesses for
+ * this device AND dev->qdisc pointer itself.
+ *
+ *  netif_tx_lock serializes accesses to device driver.
+ *
+ *  dev->queue_lock and netif_tx_lock are mutually exclusive,
+ *  if one is grabbed, another must be free.
+ *
+ * Note, that this procedure can be called by a watchdog timer
+ *
+ * Returns to the caller:
+ *                             0  - queue is empty or throttled.
+ *                             >0 - queue is not empty.
+ *
+ */
 static inline int qdisc_restart(struct net_device *dev)
 {
        struct Qdisc *q = dev->qdisc;
        struct sk_buff *skb;
+       unsigned lockless;
+       int ret;
 
        /* Dequeue packet */
-       if (((skb = dev->gso_skb)) || ((skb = q->dequeue(q)))) {
-               unsigned nolock = (dev->features & NETIF_F_LLTX);
+       if (unlikely((skb = dev_dequeue_skb(dev, q)) == NULL))
+               return 0;
+
+       /*
+        * When the driver has LLTX set, it does its own locking in
+        * start_xmit. These checks are worth it because even uncongested
+        * locks can be quite expensive. The driver can do a trylock, as
+        * is being done here; in case of lock contention it should return
+        * NETDEV_TX_LOCKED and the packet will be requeued.
+        */
+       lockless = (dev->features & NETIF_F_LLTX);
 
-               dev->gso_skb = NULL;
+       if (!lockless && !netif_tx_trylock(dev)) {
+               /* Another CPU grabbed the driver tx lock */
+               return handle_dev_cpu_collision(skb, dev, q);
+       }
 
-               /*
-                * When the driver has LLTX set it does its own locking
-                * in start_xmit. No need to add additional overhead by
-                * locking again. These checks are worth it because
-                * even uncongested locks can be quite expensive.
-                * The driver can do trylock like here too, in case
-                * of lock congestion it should return -1 and the packet
-                * will be requeued.
-                */
-               if (!nolock) {
-                       if (!netif_tx_trylock(dev)) {
-                       collision:
-                               /* So, someone grabbed the driver. */
-
-                               /* It may be transient configuration error,
-                                  when hard_start_xmit() recurses. We detect
-                                  it by checking xmit owner and drop the
-                                  packet when deadloop is detected.
-                               */
-                               if (dev->xmit_lock_owner == smp_processor_id()) {
-                                       kfree_skb(skb);
-                                       if (net_ratelimit())
-                                               printk(KERN_DEBUG "Dead loop on netdevice %s, fix it urgently!\n", dev->name);
-                                       goto out;
-                               }
-                               __get_cpu_var(netdev_rx_stat).cpu_collision++;
-                               goto requeue;
-                       }
-               }
+       /* And release queue */
+       spin_unlock(&dev->queue_lock);
 
-               {
-                       /* And release queue */
-                       spin_unlock(&dev->queue_lock);
-
-                       if (!netif_queue_stopped(dev)) {
-                               int ret;
-
-                               ret = dev_hard_start_xmit(skb, dev);
-                               if (ret == NETDEV_TX_OK) {
-                                       if (!nolock) {
-                                               netif_tx_unlock(dev);
-                                       }
-                                       spin_lock(&dev->queue_lock);
-                                       q = dev->qdisc;
-                                       goto out;
-                               }
-                               if (ret == NETDEV_TX_LOCKED && nolock) {
-                                       spin_lock(&dev->queue_lock);
-                                       q = dev->qdisc;
-                                       goto collision;
-                               }
-                       }
+       ret = dev_hard_start_xmit(skb, dev);
 
-                       /* NETDEV_TX_BUSY - we need to requeue */
-                       /* Release the driver */
-                       if (!nolock) {
-                               netif_tx_unlock(dev);
-                       }
-                       spin_lock(&dev->queue_lock);
-                       q = dev->qdisc;
-               }
+       if (!lockless)
+               netif_tx_unlock(dev);
 
-               /* Device kicked us out :(
-                  This is possible in three cases:
+       spin_lock(&dev->queue_lock);
+       q = dev->qdisc;
 
-                  0. driver is locked
-                  1. fastroute is enabled
-                  2. device cannot determine busy state
-                     before start of transmission (f.e. dialout)
-                  3. device is buggy (ppp)
-                */
+       switch (ret) {
+       case NETDEV_TX_OK:
+               /* Driver sent out skb successfully */
+               ret = qdisc_qlen(q);
+               break;
 
-requeue:
-               if (unlikely(q == &noop_qdisc))
-                       kfree_skb(skb);
-               else if (skb->next)
-                       dev->gso_skb = skb;
-               else
-                       q->ops->requeue(skb, q);
-               netif_schedule(dev);
+       case NETDEV_TX_LOCKED:
+               /* Driver try lock failed */
+               ret = handle_dev_cpu_collision(skb, dev, q);
+               break;
+
+       default:
+               /* Driver returned NETDEV_TX_BUSY - requeue skb */
+               if (unlikely (ret != NETDEV_TX_BUSY && net_ratelimit()))
+                       printk(KERN_WARNING "BUG %s code %d qlen %d\n",
+                              dev->name, ret, q->q.qlen);
+
+               ret = dev_requeue_skb(skb, dev, q);
+               break;
        }
-       return 0;
 
-out:
-       BUG_ON((int) q->q.qlen < 0);
-       return q->q.qlen;
+       return ret;
 }
 
 void __qdisc_run(struct net_device *dev)
@@ -493,9 +506,7 @@ void qdisc_destroy(struct Qdisc *qdisc)
                return;
 
        list_del(&qdisc->list);
-#ifdef CONFIG_NET_ESTIMATOR
        gen_kill_estimator(&qdisc->bstats, &qdisc->rate_est);
-#endif
        if (ops->reset)
                ops->reset(qdisc);
        if (ops->destroy)
index fa1b4fe7a5fd9772f27a8dd9b7f46e1a7df2ef08..3cc6dda02e2e0a1297ecc8a2d5a7e3707a4b556c 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <net/pkt_sched.h>
 #include <net/red.h>
index 9d124c4ee3a76ad515b3601868cd50c9fc065e31..874452c41a0172ef25bce549c97d60f38ca91daf 100644 (file)
@@ -53,7 +53,6 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/errno.h>
-#include <linux/jiffies.h>
 #include <linux/compiler.h>
 #include <linux/spinlock.h>
 #include <linux/skbuff.h>
 #include <linux/list.h>
 #include <linux/rbtree.h>
 #include <linux/init.h>
-#include <linux/netdevice.h>
 #include <linux/rtnetlink.h>
 #include <linux/pkt_sched.h>
 #include <net/netlink.h>
 #include <net/pkt_sched.h>
 #include <net/pkt_cls.h>
-#include <asm/system.h>
 #include <asm/div64.h>
 
 /*
@@ -122,7 +119,6 @@ struct hfsc_class
        struct gnet_stats_basic bstats;
        struct gnet_stats_queue qstats;
        struct gnet_stats_rate_est rate_est;
-       spinlock_t      *stats_lock;
        unsigned int    level;          /* class level in hierarchy */
        struct tcf_proto *filter_list;  /* filter list */
        unsigned int    filter_cnt;     /* filter count */
@@ -1054,11 +1050,10 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
                }
                sch_tree_unlock(sch);
 
-#ifdef CONFIG_NET_ESTIMATOR
                if (tca[TCA_RATE-1])
                        gen_replace_estimator(&cl->bstats, &cl->rate_est,
-                               cl->stats_lock, tca[TCA_RATE-1]);
-#endif
+                                             &sch->dev->queue_lock,
+                                             tca[TCA_RATE-1]);
                return 0;
        }
 
@@ -1098,7 +1093,6 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
        cl->qdisc = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops, classid);
        if (cl->qdisc == NULL)
                cl->qdisc = &noop_qdisc;
-       cl->stats_lock = &sch->dev->queue_lock;
        INIT_LIST_HEAD(&cl->children);
        cl->vt_tree = RB_ROOT;
        cl->cf_tree = RB_ROOT;
@@ -1112,11 +1106,9 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
        cl->cl_pcvtoff = parent->cl_cvtoff;
        sch_tree_unlock(sch);
 
-#ifdef CONFIG_NET_ESTIMATOR
        if (tca[TCA_RATE-1])
                gen_new_estimator(&cl->bstats, &cl->rate_est,
-                       cl->stats_lock, tca[TCA_RATE-1]);
-#endif
+                                 &sch->dev->queue_lock, tca[TCA_RATE-1]);
        *arg = (unsigned long)cl;
        return 0;
 }
@@ -1128,9 +1120,7 @@ hfsc_destroy_class(struct Qdisc *sch, struct hfsc_class *cl)
 
        tcf_destroy_chain(cl->filter_list);
        qdisc_destroy(cl->qdisc);
-#ifdef CONFIG_NET_ESTIMATOR
        gen_kill_estimator(&cl->bstats, &cl->rate_est);
-#endif
        if (cl != &q->root)
                kfree(cl);
 }
@@ -1384,9 +1374,7 @@ hfsc_dump_class_stats(struct Qdisc *sch, unsigned long arg,
        xstats.rtwork  = cl->cl_cumul;
 
        if (gnet_stats_copy_basic(d, &cl->bstats) < 0 ||
-#ifdef CONFIG_NET_ESTIMATOR
            gnet_stats_copy_rate_est(d, &cl->rate_est) < 0 ||
-#endif
            gnet_stats_copy_queue(d, &cl->qstats) < 0)
                return -1;
 
@@ -1448,8 +1436,6 @@ hfsc_init_qdisc(struct Qdisc *sch, struct rtattr *opt)
                return -EINVAL;
        qopt = RTA_DATA(opt);
 
-       sch->stats_lock = &sch->dev->queue_lock;
-
        q->defcls = qopt->defcls;
        for (i = 0; i < HFSC_HSIZE; i++)
                INIT_LIST_HEAD(&q->clhash[i]);
@@ -1464,7 +1450,6 @@ hfsc_init_qdisc(struct Qdisc *sch, struct rtattr *opt)
                                          sch->handle);
        if (q->root.qdisc == NULL)
                q->root.qdisc = &noop_qdisc;
-       q->root.stats_lock = &sch->dev->queue_lock;
        INIT_LIST_HEAD(&q->root.children);
        q->root.vt_tree = RB_ROOT;
        q->root.cf_tree = RB_ROOT;
index 035788c5b7f8a75c07961c0694df50aeaa9ecef1..b417a95df3223e4880f5b654abe7e98c5f424d09 100644 (file)
  * $Id: sch_htb.c,v 1.25 2003/12/07 11:08:25 devik Exp devik $
  */
 #include <linux/module.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/if_ether.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/notifier.h>
-#include <net/ip.h>
-#include <net/route.h>
 #include <linux/skbuff.h>
 #include <linux/list.h>
 #include <linux/compiler.h>
+#include <linux/rbtree.h>
 #include <net/netlink.h>
-#include <net/sock.h>
 #include <net/pkt_sched.h>
-#include <linux/rbtree.h>
 
 /* HTB algorithm.
     Author: devik@cdi.cz
@@ -69,8 +53,6 @@
 */
 
 #define HTB_HSIZE 16           /* classid hash size */
-#define HTB_EWMAC 2            /* rate average over HTB_EWMAC*HTB_HSIZE sec */
-#define HTB_RATECM 1           /* whether to use rate computer */
 #define HTB_HYSTERESIS 1       /* whether to use mode hysteresis for speedup */
 #define HTB_VER 0x30011                /* major must be matched with number suplied by TC as version */
 
@@ -95,12 +77,6 @@ struct htb_class {
        struct tc_htb_xstats xstats;    /* our special stats */
        int refcnt;             /* usage count of this class */
 
-#ifdef HTB_RATECM
-       /* rate measurement counters */
-       unsigned long rate_bytes, sum_bytes;
-       unsigned long rate_packets, sum_packets;
-#endif
-
        /* topology */
        int level;              /* our level (see above) */
        struct htb_class *parent;       /* parent class */
@@ -153,15 +129,12 @@ struct htb_class {
                                /* of un.leaf originals should be done. */
 };
 
-/* TODO: maybe compute rate when size is too large .. or drop ? */
 static inline long L2T(struct htb_class *cl, struct qdisc_rate_table *rate,
                           int size)
 {
        int slot = size >> rate->rate.cell_log;
-       if (slot > 255) {
-               cl->xstats.giants++;
-               slot = 255;
-       }
+       if (slot > 255)
+               return (rate->data[255]*(slot >> 8) + rate->data[slot & 0xFF]);
        return rate->data[slot];
 }
 
@@ -194,10 +167,6 @@ struct htb_sched {
        int rate2quantum;       /* quant = rate / rate2quantum */
        psched_time_t now;      /* cached dequeue time */
        struct qdisc_watchdog watchdog;
-#ifdef HTB_RATECM
-       struct timer_list rttim;        /* rate computer timer */
-       int recmp_bucket;       /* which hash bucket to recompute next */
-#endif
 
        /* non shaped skbs; let them go directly thru */
        struct sk_buff_head direct_queue;
@@ -634,13 +603,14 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch)
                cl->qstats.drops++;
                return NET_XMIT_DROP;
        } else {
-               cl->bstats.packets++;
+               cl->bstats.packets +=
+                       skb_is_gso(skb)?skb_shinfo(skb)->gso_segs:1;
                cl->bstats.bytes += skb->len;
                htb_activate(q, cl);
        }
 
        sch->q.qlen++;
-       sch->bstats.packets++;
+       sch->bstats.packets += skb_is_gso(skb)?skb_shinfo(skb)->gso_segs:1;
        sch->bstats.bytes += skb->len;
        return NET_XMIT_SUCCESS;
 }
@@ -677,34 +647,6 @@ static int htb_requeue(struct sk_buff *skb, struct Qdisc *sch)
        return NET_XMIT_SUCCESS;
 }
 
-#ifdef HTB_RATECM
-#define RT_GEN(D,R) R+=D-(R/HTB_EWMAC);D=0
-static void htb_rate_timer(unsigned long arg)
-{
-       struct Qdisc *sch = (struct Qdisc *)arg;
-       struct htb_sched *q = qdisc_priv(sch);
-       struct hlist_node *p;
-       struct htb_class *cl;
-
-
-       /* lock queue so that we can muck with it */
-       spin_lock_bh(&sch->dev->queue_lock);
-
-       q->rttim.expires = jiffies + HZ;
-       add_timer(&q->rttim);
-
-       /* scan and recompute one bucket at time */
-       if (++q->recmp_bucket >= HTB_HSIZE)
-               q->recmp_bucket = 0;
-
-       hlist_for_each_entry(cl,p, q->hash + q->recmp_bucket, hlist) {
-               RT_GEN(cl->sum_bytes, cl->rate_bytes);
-               RT_GEN(cl->sum_packets, cl->rate_packets);
-       }
-       spin_unlock_bh(&sch->dev->queue_lock);
-}
-#endif
-
 /**
  * htb_charge_class - charges amount "bytes" to leaf and ancestors
  *
@@ -717,8 +659,9 @@ static void htb_rate_timer(unsigned long arg)
  * In such case we remove class from event queue first.
  */
 static void htb_charge_class(struct htb_sched *q, struct htb_class *cl,
-                            int level, int bytes)
+                            int level, struct sk_buff *skb)
 {
+       int bytes = skb->len;
        long toks, diff;
        enum htb_cmode old_mode;
 
@@ -750,16 +693,12 @@ static void htb_charge_class(struct htb_sched *q, struct htb_class *cl,
                        if (cl->cmode != HTB_CAN_SEND)
                                htb_add_to_wait_tree(q, cl, diff);
                }
-#ifdef HTB_RATECM
-               /* update rate counters */
-               cl->sum_bytes += bytes;
-               cl->sum_packets++;
-#endif
 
                /* update byte stats except for leaves which are already updated */
                if (cl->level) {
                        cl->bstats.bytes += bytes;
-                       cl->bstats.packets++;
+                       cl->bstats.packets += skb_is_gso(skb)?
+                                       skb_shinfo(skb)->gso_segs:1;
                }
                cl = cl->parent;
        }
@@ -943,7 +882,7 @@ next:
                   gives us slightly better performance */
                if (!cl->un.leaf.q->q.qlen)
                        htb_deactivate(q, cl);
-               htb_charge_class(q, cl, level, skb->len);
+               htb_charge_class(q, cl, level, skb);
        }
        return skb;
 }
@@ -1095,13 +1034,6 @@ static int htb_init(struct Qdisc *sch, struct rtattr *opt)
        if (q->direct_qlen < 2) /* some devices have zero tx_queue_len */
                q->direct_qlen = 2;
 
-#ifdef HTB_RATECM
-       init_timer(&q->rttim);
-       q->rttim.function = htb_rate_timer;
-       q->rttim.data = (unsigned long)sch;
-       q->rttim.expires = jiffies + HZ;
-       add_timer(&q->rttim);
-#endif
        if ((q->rate2quantum = gopt->rate2quantum) < 1)
                q->rate2quantum = 1;
        q->defcls = gopt->defcls;
@@ -1175,11 +1107,6 @@ htb_dump_class_stats(struct Qdisc *sch, unsigned long arg, struct gnet_dump *d)
 {
        struct htb_class *cl = (struct htb_class *)arg;
 
-#ifdef HTB_RATECM
-       cl->rate_est.bps = cl->rate_bytes / (HTB_EWMAC * HTB_HSIZE);
-       cl->rate_est.pps = cl->rate_packets / (HTB_EWMAC * HTB_HSIZE);
-#endif
-
        if (!cl->level && cl->un.leaf.q)
                cl->qstats.qlen = cl->un.leaf.q->q.qlen;
        cl->xstats.tokens = cl->tokens;
@@ -1277,6 +1204,7 @@ static void htb_destroy_class(struct Qdisc *sch, struct htb_class *cl)
                BUG_TRAP(cl->un.leaf.q);
                qdisc_destroy(cl->un.leaf.q);
        }
+       gen_kill_estimator(&cl->bstats, &cl->rate_est);
        qdisc_put_rtab(cl->rate);
        qdisc_put_rtab(cl->ceil);
 
@@ -1305,9 +1233,6 @@ static void htb_destroy(struct Qdisc *sch)
        struct htb_sched *q = qdisc_priv(sch);
 
        qdisc_watchdog_cancel(&q->watchdog);
-#ifdef HTB_RATECM
-       del_timer_sync(&q->rttim);
-#endif
        /* This line used to be after htb_destroy_class call below
           and surprisingly it worked in 2.4. But it must precede it
           because filter need its target class alive to be able to call
@@ -1403,6 +1328,20 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
        if (!cl) {              /* new class */
                struct Qdisc *new_q;
                int prio;
+               struct {
+                       struct rtattr           rta;
+                       struct gnet_estimator   opt;
+               } est = {
+                       .rta = {
+                               .rta_len        = RTA_LENGTH(sizeof(est.opt)),
+                               .rta_type       = TCA_RATE,
+                       },
+                       .opt = {
+                               /* 4s interval, 16s averaging constant */
+                               .interval       = 2,
+                               .ewma_log       = 2,
+                       },
+               };
 
                /* check for valid classid */
                if (!classid || TC_H_MAJ(classid ^ sch->handle)
@@ -1418,6 +1357,9 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
                if ((cl = kzalloc(sizeof(*cl), GFP_KERNEL)) == NULL)
                        goto failure;
 
+               gen_new_estimator(&cl->bstats, &cl->rate_est,
+                                 &sch->dev->queue_lock,
+                                 tca[TCA_RATE-1] ? : &est.rta);
                cl->refcnt = 1;
                INIT_LIST_HEAD(&cl->sibling);
                INIT_HLIST_NODE(&cl->hlist);
@@ -1469,8 +1411,13 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
                hlist_add_head(&cl->hlist, q->hash + htb_hash(classid));
                list_add_tail(&cl->sibling,
                              parent ? &parent->children : &q->root);
-       } else
+       } else {
+               if (tca[TCA_RATE-1])
+                       gen_replace_estimator(&cl->bstats, &cl->rate_est,
+                                             &sch->dev->queue_lock,
+                                             tca[TCA_RATE-1]);
                sch_tree_lock(sch);
+       }
 
        /* it used to be a nasty bug here, we have to check that node
           is really leaf before changing cl->un.leaf ! */
index f8b9f1cdf738a8362ab77472a83721b62767fa3d..cd0aab6a2a7c0bcdd6e1c56f966ea47129fcef74 100644 (file)
@@ -9,21 +9,14 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/list.h>
 #include <linux/skbuff.h>
-#include <linux/netdevice.h>
 #include <linux/rtnetlink.h>
 #include <linux/netfilter_ipv4.h>
 #include <linux/netfilter_ipv6.h>
 #include <linux/netfilter.h>
-#include <linux/smp.h>
 #include <net/netlink.h>
 #include <net/pkt_sched.h>
-#include <asm/byteorder.h>
-#include <asm/uaccess.h>
-#include <linux/kmod.h>
-#include <linux/stat.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
 
 
 #undef DEBUG_INGRESS
index 5d9d8bc9cc3a039b76a7c93127b0a00ed8ca8295..9e5e87e81f002433cf6cac0ea4ac3f8db519b3fc 100644 (file)
  */
 
 #include <linux/module.h>
-#include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
-#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/rtnetlink.h>
 
index 6d7542c26e47a7ce3b63df2a07a0e797a0bc9e1b..2d8c08493d6e9275683161418c0fd26cf4ec5a37 100644 (file)
  */
 
 #include <linux/module.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/if_ether.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/notifier.h>
-#include <net/ip.h>
-#include <net/route.h>
 #include <linux/skbuff.h>
 #include <net/netlink.h>
-#include <net/sock.h>
 #include <net/pkt_sched.h>
 
 
 struct prio_sched_data
 {
        int bands;
+       int curband; /* for round-robin */
        struct tcf_proto *filter_list;
        u8  prio2band[TC_PRIO_MAX+1];
        struct Qdisc *queues[TCQ_PRIO_BANDS];
+       int mq;
 };
 
 
@@ -70,14 +56,17 @@ prio_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
 #endif
                        if (TC_H_MAJ(band))
                                band = 0;
-                       return q->queues[q->prio2band[band&TC_PRIO_MAX]];
+                       band = q->prio2band[band&TC_PRIO_MAX];
+                       goto out;
                }
                band = res.classid;
        }
        band = TC_H_MIN(band) - 1;
        if (band >= q->bands)
-               return q->queues[q->prio2band[0]];
-
+               band = q->prio2band[0];
+out:
+       if (q->mq)
+               skb_set_queue_mapping(skb, band);
        return q->queues[band];
 }
 
@@ -144,17 +133,58 @@ prio_dequeue(struct Qdisc* sch)
        struct Qdisc *qdisc;
 
        for (prio = 0; prio < q->bands; prio++) {
-               qdisc = q->queues[prio];
-               skb = qdisc->dequeue(qdisc);
-               if (skb) {
-                       sch->q.qlen--;
-                       return skb;
+               /* Check if the target subqueue is available before
+                * pulling an skb.  This way we avoid excessive requeues
+                * for slower queues.
+                */
+               if (!netif_subqueue_stopped(sch->dev, (q->mq ? prio : 0))) {
+                       qdisc = q->queues[prio];
+                       skb = qdisc->dequeue(qdisc);
+                       if (skb) {
+                               sch->q.qlen--;
+                               return skb;
+                       }
                }
        }
        return NULL;
 
 }
 
+static struct sk_buff *rr_dequeue(struct Qdisc* sch)
+{
+       struct sk_buff *skb;
+       struct prio_sched_data *q = qdisc_priv(sch);
+       struct Qdisc *qdisc;
+       int bandcount;
+
+       /* Only take one pass through the queues.  If nothing is available,
+        * return nothing.
+        */
+       for (bandcount = 0; bandcount < q->bands; bandcount++) {
+               /* Check if the target subqueue is available before
+                * pulling an skb.  This way we avoid excessive requeues
+                * for slower queues.  If the queue is stopped, try the
+                * next queue.
+                */
+               if (!netif_subqueue_stopped(sch->dev,
+                                           (q->mq ? q->curband : 0))) {
+                       qdisc = q->queues[q->curband];
+                       skb = qdisc->dequeue(qdisc);
+                       if (skb) {
+                               sch->q.qlen--;
+                               q->curband++;
+                               if (q->curband >= q->bands)
+                                       q->curband = 0;
+                               return skb;
+                       }
+               }
+               q->curband++;
+               if (q->curband >= q->bands)
+                       q->curband = 0;
+       }
+       return NULL;
+}
+
 static unsigned int prio_drop(struct Qdisc* sch)
 {
        struct prio_sched_data *q = qdisc_priv(sch);
@@ -198,21 +228,41 @@ prio_destroy(struct Qdisc* sch)
 static int prio_tune(struct Qdisc *sch, struct rtattr *opt)
 {
        struct prio_sched_data *q = qdisc_priv(sch);
-       struct tc_prio_qopt *qopt = RTA_DATA(opt);
+       struct tc_prio_qopt *qopt;
+       struct rtattr *tb[TCA_PRIO_MAX];
        int i;
 
-       if (opt->rta_len < RTA_LENGTH(sizeof(*qopt)))
+       if (rtattr_parse_nested_compat(tb, TCA_PRIO_MAX, opt, qopt,
+                                      sizeof(*qopt)))
                return -EINVAL;
-       if (qopt->bands > TCQ_PRIO_BANDS || qopt->bands < 2)
+       q->bands = qopt->bands;
+       /* If we're multiqueue, make sure the number of incoming bands
+        * matches the number of queues on the device we're associating with.
+        * If the number of bands requested is zero, then set q->bands to
+        * dev->egress_subqueue_count.
+        */
+       q->mq = RTA_GET_FLAG(tb[TCA_PRIO_MQ - 1]);
+       if (q->mq) {
+               if (sch->handle != TC_H_ROOT)
+                       return -EINVAL;
+               if (netif_is_multiqueue(sch->dev)) {
+                       if (q->bands == 0)
+                               q->bands = sch->dev->egress_subqueue_count;
+                       else if (q->bands != sch->dev->egress_subqueue_count)
+                               return -EINVAL;
+               } else
+                       return -EOPNOTSUPP;
+       }
+
+       if (q->bands > TCQ_PRIO_BANDS || q->bands < 2)
                return -EINVAL;
 
        for (i=0; i<=TC_PRIO_MAX; i++) {
-               if (qopt->priomap[i] >= qopt->bands)
+               if (qopt->priomap[i] >= q->bands)
                        return -EINVAL;
        }
 
        sch_tree_lock(sch);
-       q->bands = qopt->bands;
        memcpy(q->prio2band, qopt->priomap, TC_PRIO_MAX+1);
 
        for (i=q->bands; i<TCQ_PRIO_BANDS; i++) {
@@ -268,11 +318,17 @@ static int prio_dump(struct Qdisc *sch, struct sk_buff *skb)
 {
        struct prio_sched_data *q = qdisc_priv(sch);
        unsigned char *b = skb_tail_pointer(skb);
+       struct rtattr *nest;
        struct tc_prio_qopt opt;
 
        opt.bands = q->bands;
        memcpy(&opt.priomap, q->prio2band, TC_PRIO_MAX+1);
-       RTA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
+
+       nest = RTA_NEST_COMPAT(skb, TCA_OPTIONS, sizeof(opt), &opt);
+       if (q->mq)
+               RTA_PUT_FLAG(skb, TCA_PRIO_MQ);
+       RTA_NEST_COMPAT_END(skb, nest);
+
        return skb->len;
 
 rtattr_failure:
@@ -443,17 +499,44 @@ static struct Qdisc_ops prio_qdisc_ops = {
        .owner          =       THIS_MODULE,
 };
 
+static struct Qdisc_ops rr_qdisc_ops = {
+       .next           =       NULL,
+       .cl_ops         =       &prio_class_ops,
+       .id             =       "rr",
+       .priv_size      =       sizeof(struct prio_sched_data),
+       .enqueue        =       prio_enqueue,
+       .dequeue        =       rr_dequeue,
+       .requeue        =       prio_requeue,
+       .drop           =       prio_drop,
+       .init           =       prio_init,
+       .reset          =       prio_reset,
+       .destroy        =       prio_destroy,
+       .change         =       prio_tune,
+       .dump           =       prio_dump,
+       .owner          =       THIS_MODULE,
+};
+
 static int __init prio_module_init(void)
 {
-       return register_qdisc(&prio_qdisc_ops);
+       int err;
+
+       err = register_qdisc(&prio_qdisc_ops);
+       if (err < 0)
+               return err;
+       err = register_qdisc(&rr_qdisc_ops);
+       if (err < 0)
+               unregister_qdisc(&prio_qdisc_ops);
+       return err;
 }
 
 static void __exit prio_module_exit(void)
 {
        unregister_qdisc(&prio_qdisc_ops);
+       unregister_qdisc(&rr_qdisc_ops);
 }
 
 module_init(prio_module_init)
 module_exit(prio_module_exit)
 
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("sch_rr");
index 00db53eb8159ecadc156fe1eab669cf179d4008d..9b95fefb70f46b881c8cb21f57a461561db024c9 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <net/pkt_sched.h>
 #include <net/inet_ecn.h>
index 96dfdf78d32c175fd702c7d8d059c5abac24568e..9579573098598df19066e0910e181e68a94ef080 100644 (file)
  */
 
 #include <linux/module.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/jiffies.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
 #include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/if_ether.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/notifier.h>
 #include <linux/init.h>
-#include <net/ip.h>
-#include <net/netlink.h>
 #include <linux/ipv6.h>
-#include <net/route.h>
 #include <linux/skbuff.h>
-#include <net/sock.h>
+#include <net/ip.h>
+#include <net/netlink.h>
 #include <net/pkt_sched.h>
 
 
index 53862953baafc65735ef969888a39cfb49901fd3..22e431dace54d01a8523564071c1165400b748da 100644 (file)
  */
 
 #include <linux/module.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/jiffies.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/if_ether.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/notifier.h>
-#include <net/ip.h>
-#include <net/netlink.h>
-#include <net/route.h>
 #include <linux/skbuff.h>
-#include <net/sock.h>
+#include <net/netlink.h>
 #include <net/pkt_sched.h>
 
 
index f05ad9a30b4cd67bfef9d956023367303ddb5343..0968184ea6becc6f58ba848fc76c629aa8e26126 100644 (file)
@@ -9,30 +9,17 @@
  */
 
 #include <linux/module.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
 #include <linux/if_arp.h>
-#include <linux/if_ether.h>
-#include <linux/inet.h>
 #include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/notifier.h>
 #include <linux/init.h>
-#include <net/ip.h>
-#include <net/route.h>
 #include <linux/skbuff.h>
 #include <linux/moduleparam.h>
-#include <net/sock.h>
+#include <net/dst.h>
+#include <net/neighbour.h>
 #include <net/pkt_sched.h>
 
 /*
@@ -225,7 +212,6 @@ static int teql_qdisc_init(struct Qdisc *sch, struct rtattr *opt)
        return 0;
 }
 
-/* "teql*" netdevice routines */
 
 static int
 __teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, struct net_device *dev)
@@ -277,6 +263,7 @@ static int teql_master_xmit(struct sk_buff *skb, struct net_device *dev)
        int busy;
        int nores;
        int len = skb->len;
+       int subq = skb->queue_mapping;
        struct sk_buff *skb_res = NULL;
 
        start = master->slaves;
@@ -293,7 +280,9 @@ restart:
 
                if (slave->qdisc_sleeping != q)
                        continue;
-               if (netif_queue_stopped(slave) || ! netif_running(slave)) {
+               if (netif_queue_stopped(slave) ||
+                   netif_subqueue_stopped(slave, subq) ||
+                   !netif_running(slave)) {
                        busy = 1;
                        continue;
                }
@@ -302,6 +291,7 @@ restart:
                case 0:
                        if (netif_tx_trylock(slave)) {
                                if (!netif_queue_stopped(slave) &&
+                                   !netif_subqueue_stopped(slave, subq) &&
                                    slave->hard_start_xmit(skb, slave) == 0) {
                                        netif_tx_unlock(slave);
                                        master->slaves = NEXT_SLAVE(q);
index 2f12bf2d8d3c622f5f134cf1fa3308d7fab015fd..e4cd841a22e478793e85e2701dc4da30b60db4b7 100644 (file)
@@ -250,7 +250,7 @@ static int sctp_eps_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations sctp_eps_ops = {
+static const struct seq_operations sctp_eps_ops = {
        .start = sctp_eps_seq_start,
        .next  = sctp_eps_seq_next,
        .stop  = sctp_eps_seq_stop,
@@ -361,7 +361,7 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations sctp_assoc_ops = {
+static const struct seq_operations sctp_assoc_ops = {
        .start = sctp_assocs_seq_start,
        .next  = sctp_assocs_seq_next,
        .stop  = sctp_assocs_seq_stop,
index 099a983797da329249942ccbbf279c92e8ac853b..c094583386fd2242cfc633e30235153e06d7cf35 100644 (file)
@@ -853,7 +853,7 @@ unwrap_priv_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct gs
        u32 priv_len, maj_stat;
        int pad, saved_len, remaining_len, offset;
 
-       rqstp->rq_sendfile_ok = 0;
+       rqstp->rq_splice_ok = 0;
 
        priv_len = svc_getnl(&buf->head[0]);
        if (rqstp->rq_deferred) {
index 543b085ae2c188300d43105262ec22653cc32017..01c3c41052048253b309946d62b9d7c65afea0e3 100644 (file)
@@ -1210,7 +1210,7 @@ static int c_show(struct seq_file *m, void *p)
        return cd->cache_show(m, cd, cp);
 }
 
-static struct seq_operations cache_content_op = {
+static const struct seq_operations cache_content_op = {
        .start  = c_start,
        .next   = c_next,
        .stop   = c_stop,
index e673ef9939043edc4a2d7aac1bf0c745ebd22917..55ea6df069deeb2042b8b1b8dc4c5294d5bfa649 100644 (file)
@@ -814,7 +814,7 @@ svc_process(struct svc_rqst *rqstp)
        rqstp->rq_res.tail[0].iov_base = NULL;
        rqstp->rq_res.tail[0].iov_len = 0;
        /* Will be turned off only in gss privacy case: */
-       rqstp->rq_sendfile_ok = 1;
+       rqstp->rq_splice_ok = 1;
        /* tcp needs a space for the record length... */
        if (rqstp->rq_prot == IPPROTO_TCP)
                svc_putnl(resv, 0);
index 77d2d9ce896248822562843b96d3bb7e53574413..711ca4b1f051720ca546d6e722e1ab387a20ed21 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * net/tipc/eth_media.c: Ethernet bearer support for TIPC
  *
- * Copyright (c) 2001-2006, Ericsson AB
- * Copyright (c) 2005-2006, Wind River Systems
+ * Copyright (c) 2001-2007, Ericsson AB
+ * Copyright (c) 2005-2007, Wind River Systems
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -87,6 +87,9 @@ static int send_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr,
 /**
  * recv_msg - handle incoming TIPC message from an Ethernet interface
  *
+ * Accept only packets explicitly sent to this node, or broadcast packets;
+ * ignores packets sent using Ethernet multicast, and traffic sent to other
+ * nodes (which can happen if interface is running in promiscuous mode).
  * Routine truncates any Ethernet padding/CRC appended to the message,
  * and ensures message size matches actual length
  */
@@ -98,9 +101,7 @@ static int recv_msg(struct sk_buff *buf, struct net_device *dev,
        u32 size;
 
        if (likely(eb_ptr->bearer)) {
-              if (likely(!dev->promiscuity) ||
-                  !memcmp(skb_mac_header(buf), dev->dev_addr, ETH_ALEN) ||
-                  !memcmp(skb_mac_header(buf), dev->broadcast, ETH_ALEN)) {
+               if (likely(buf->pkt_type <= PACKET_BROADCAST)) {
                        size = msg_size((struct tipc_msg *)buf->data);
                        skb_trim(buf, size);
                        if (likely(buf->len == size)) {
index 2124f32ef29f3064b98057919ba33631bc19f891..5adfdfd49d61b65dc0164cd1fcecaff88d4fa558 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * net/tipc/link.c: TIPC link code
  *
- * Copyright (c) 1996-2006, Ericsson AB
- * Copyright (c) 2004-2006, Wind River Systems
+ * Copyright (c) 1996-2007, Ericsson AB
+ * Copyright (c) 2004-2007, Wind River Systems
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -1260,7 +1260,7 @@ again:
         * (Must not hold any locks while building message.)
         */
 
-       res = msg_build(hdr, msg_sect, num_sect, sender->max_pkt,
+       res = msg_build(hdr, msg_sect, num_sect, sender->publ.max_pkt,
                        !sender->user_port, &buf);
 
        read_lock_bh(&tipc_net_lock);
@@ -1271,7 +1271,7 @@ again:
                if (likely(l_ptr)) {
                        if (likely(buf)) {
                                res = link_send_buf_fast(l_ptr, buf,
-                                                        &sender->max_pkt);
+                                                        &sender->publ.max_pkt);
                                if (unlikely(res < 0))
                                        buf_discard(buf);
 exit:
@@ -1299,12 +1299,12 @@ exit:
                         * then re-try fast path or fragment the message
                         */
 
-                       sender->max_pkt = link_max_pkt(l_ptr);
+                       sender->publ.max_pkt = link_max_pkt(l_ptr);
                        tipc_node_unlock(node);
                        read_unlock_bh(&tipc_net_lock);
 
 
-                       if ((msg_hdr_sz(hdr) + res) <= sender->max_pkt)
+                       if ((msg_hdr_sz(hdr) + res) <= sender->publ.max_pkt)
                                goto again;
 
                        return link_send_sections_long(sender, msg_sect,
@@ -1357,7 +1357,7 @@ static int link_send_sections_long(struct port *sender,
 
 again:
        fragm_no = 1;
-       max_pkt = sender->max_pkt - INT_H_SIZE;
+       max_pkt = sender->publ.max_pkt - INT_H_SIZE;
                /* leave room for tunnel header in case of link changeover */
        fragm_sz = max_pkt - INT_H_SIZE;
                /* leave room for fragmentation header in each fragment */
@@ -1463,7 +1463,7 @@ error:
                        goto reject;
                }
                if (link_max_pkt(l_ptr) < max_pkt) {
-                       sender->max_pkt = link_max_pkt(l_ptr);
+                       sender->publ.max_pkt = link_max_pkt(l_ptr);
                        tipc_node_unlock(node);
                        for (; buf_chain; buf_chain = buf) {
                                buf = buf_chain->next;
index bcd5da00737b208d4b2f07e6c776dc78c962bb83..5d2b9ce84d0a1016ecc7fe076b31da8b232a6849 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * net/tipc/port.c: TIPC port code
  *
- * Copyright (c) 1992-2006, Ericsson AB
- * Copyright (c) 2004-2005, Wind River Systems
+ * Copyright (c) 1992-2007, Ericsson AB
+ * Copyright (c) 2004-2007, Wind River Systems
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -239,6 +239,8 @@ u32 tipc_createport_raw(void *usr_handle,
        }
 
        tipc_port_lock(ref);
+       p_ptr->publ.usr_handle = usr_handle;
+       p_ptr->publ.max_pkt = MAX_PKT_DEFAULT;
        p_ptr->publ.ref = ref;
        msg = &p_ptr->publ.phdr;
        msg_init(msg, DATA_LOW, TIPC_NAMED_MSG, TIPC_OK, LONG_H_SIZE, 0);
@@ -248,11 +250,9 @@ u32 tipc_createport_raw(void *usr_handle,
        msg_set_importance(msg,importance);
        p_ptr->last_in_seqno = 41;
        p_ptr->sent = 1;
-       p_ptr->publ.usr_handle = usr_handle;
        INIT_LIST_HEAD(&p_ptr->wait_list);
        INIT_LIST_HEAD(&p_ptr->subscription.nodesub_list);
        p_ptr->congested_link = NULL;
-       p_ptr->max_pkt = MAX_PKT_DEFAULT;
        p_ptr->dispatcher = dispatcher;
        p_ptr->wakeup = wakeup;
        p_ptr->user_port = NULL;
@@ -1243,7 +1243,7 @@ int tipc_connect2port(u32 ref, struct tipc_portid const *peer)
        res = TIPC_OK;
 exit:
        tipc_port_unlock(p_ptr);
-       p_ptr->max_pkt = tipc_link_get_max_pkt(peer->node, ref);
+       p_ptr->publ.max_pkt = tipc_link_get_max_pkt(peer->node, ref);
        return res;
 }
 
index 7ef4d64b32f79a95e89bd412c1dae6e1ef47248b..e5f8c16429bd36e60a336fd96287cf015bdb7508 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * net/tipc/port.h: Include file for TIPC port code
  *
- * Copyright (c) 1994-2006, Ericsson AB
- * Copyright (c) 2004-2005, Wind River Systems
+ * Copyright (c) 1994-2007, Ericsson AB
+ * Copyright (c) 2004-2007, Wind River Systems
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -81,7 +81,6 @@ struct user_port {
  * @acked:
  * @publications: list of publications for port
  * @pub_count: total # of publications port has made during its lifetime
- * @max_pkt: maximum packet size "hint" used when building messages sent by port
  * @probing_state:
  * @probing_interval:
  * @last_in_seqno:
@@ -102,7 +101,6 @@ struct port {
        u32 acked;
        struct list_head publications;
        u32 pub_count;
-       u32 max_pkt;
        u32 probing_state;
        u32 probing_interval;
        u32 last_in_seqno;
index 45832fb75ea45d813efe7a00b0320990e449c276..4a8f37f48764e336e6b856ce3b103e2870c20671 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * net/tipc/socket.c: TIPC socket API
  *
- * Copyright (c) 2001-2006, Ericsson AB
- * Copyright (c) 2004-2006, Wind River Systems
+ * Copyright (c) 2001-2007, Ericsson AB
+ * Copyright (c) 2004-2007, Wind River Systems
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -607,23 +607,24 @@ exit:
 static int send_stream(struct kiocb *iocb, struct socket *sock,
                       struct msghdr *m, size_t total_len)
 {
+       struct tipc_port *tport;
        struct msghdr my_msg;
        struct iovec my_iov;
        struct iovec *curr_iov;
        int curr_iovlen;
        char __user *curr_start;
+       u32 hdr_size;
        int curr_left;
        int bytes_to_send;
        int bytes_sent;
        int res;
 
-       if (likely(total_len <= TIPC_MAX_USER_MSG_SIZE))
-               return send_packet(iocb, sock, m, total_len);
-
-       /* Can only send large data streams if already connected */
+       /* Handle special cases where there is no connection */
 
        if (unlikely(sock->state != SS_CONNECTED)) {
-               if (sock->state == SS_DISCONNECTING)
+               if (sock->state == SS_UNCONNECTED)
+                       return send_packet(iocb, sock, m, total_len);
+               else if (sock->state == SS_DISCONNECTING)
                        return -EPIPE;
                else
                        return -ENOTCONN;
@@ -648,17 +649,25 @@ static int send_stream(struct kiocb *iocb, struct socket *sock,
        my_msg.msg_name = NULL;
        bytes_sent = 0;
 
+       tport = tipc_sk(sock->sk)->p;
+       hdr_size = msg_hdr_sz(&tport->phdr);
+
        while (curr_iovlen--) {
                curr_start = curr_iov->iov_base;
                curr_left = curr_iov->iov_len;
 
                while (curr_left) {
-                       bytes_to_send = (curr_left < TIPC_MAX_USER_MSG_SIZE)
-                               ? curr_left : TIPC_MAX_USER_MSG_SIZE;
+                       bytes_to_send = tport->max_pkt - hdr_size;
+                       if (bytes_to_send > TIPC_MAX_USER_MSG_SIZE)
+                               bytes_to_send = TIPC_MAX_USER_MSG_SIZE;
+                       if (curr_left < bytes_to_send)
+                               bytes_to_send = curr_left;
                        my_iov.iov_base = curr_start;
                        my_iov.iov_len = bytes_to_send;
                        if ((res = send_packet(iocb, sock, &my_msg, 0)) < 0) {
-                               return bytes_sent ? bytes_sent : res;
+                               if (bytes_sent != 0)
+                                       res = bytes_sent;
+                               return res;
                        }
                        curr_left -= bytes_to_send;
                        curr_start += bytes_to_send;
@@ -1599,33 +1608,6 @@ static int getsockopt(struct socket *sock,
        return res;
 }
 
-/**
- * Placeholders for non-implemented functionality
- *
- * Returns error code (POSIX-compliant where defined)
- */
-
-static int ioctl(struct socket *s, u32 cmd, unsigned long arg)
-{
-       return -EINVAL;
-}
-
-static int no_mmap(struct file *file, struct socket *sock,
-                  struct vm_area_struct *vma)
-{
-       return -EINVAL;
-}
-static ssize_t no_sendpage(struct socket *sock, struct page *page,
-                          int offset, size_t size, int flags)
-{
-       return -EINVAL;
-}
-
-static int no_skpair(struct socket *s1, struct socket *s2)
-{
-       return -EOPNOTSUPP;
-}
-
 /**
  * Protocol switches for the various types of TIPC sockets
  */
@@ -1636,19 +1618,19 @@ static struct proto_ops msg_ops = {
        .release        = release,
        .bind           = bind,
        .connect        = connect,
-       .socketpair     = no_skpair,
+       .socketpair     = sock_no_socketpair,
        .accept         = accept,
        .getname        = get_name,
        .poll           = poll,
-       .ioctl          = ioctl,
+       .ioctl          = sock_no_ioctl,
        .listen         = listen,
        .shutdown       = shutdown,
        .setsockopt     = setsockopt,
        .getsockopt     = getsockopt,
        .sendmsg        = send_msg,
        .recvmsg        = recv_msg,
-       .mmap           = no_mmap,
-       .sendpage       = no_sendpage
+        .mmap          = sock_no_mmap,
+        .sendpage      = sock_no_sendpage
 };
 
 static struct proto_ops packet_ops = {
@@ -1657,19 +1639,19 @@ static struct proto_ops packet_ops = {
        .release        = release,
        .bind           = bind,
        .connect        = connect,
-       .socketpair     = no_skpair,
+       .socketpair     = sock_no_socketpair,
        .accept         = accept,
        .getname        = get_name,
        .poll           = poll,
-       .ioctl          = ioctl,
+       .ioctl          = sock_no_ioctl,
        .listen         = listen,
        .shutdown       = shutdown,
        .setsockopt     = setsockopt,
        .getsockopt     = getsockopt,
        .sendmsg        = send_packet,
        .recvmsg        = recv_msg,
-       .mmap           = no_mmap,
-       .sendpage       = no_sendpage
+        .mmap          = sock_no_mmap,
+        .sendpage      = sock_no_sendpage
 };
 
 static struct proto_ops stream_ops = {
@@ -1678,19 +1660,19 @@ static struct proto_ops stream_ops = {
        .release        = release,
        .bind           = bind,
        .connect        = connect,
-       .socketpair     = no_skpair,
+       .socketpair     = sock_no_socketpair,
        .accept         = accept,
        .getname        = get_name,
        .poll           = poll,
-       .ioctl          = ioctl,
+       .ioctl          = sock_no_ioctl,
        .listen         = listen,
        .shutdown       = shutdown,
        .setsockopt     = setsockopt,
        .getsockopt     = getsockopt,
        .sendmsg        = send_stream,
        .recvmsg        = recv_stream,
-       .mmap           = no_mmap,
-       .sendpage       = no_sendpage
+        .mmap          = sock_no_mmap,
+        .sendpage      = sock_no_sendpage
 };
 
 static struct net_proto_family tipc_family_ops = {
index d70fa30d4294383f4cbdc45feec8a1df90f65a2b..65ebccc0a698f31fff7de9c3fa7eebd3689e5969 100644 (file)
@@ -592,7 +592,8 @@ static struct sock * unix_create1(struct socket *sock)
        u->dentry = NULL;
        u->mnt    = NULL;
        spin_lock_init(&u->lock);
-       atomic_set(&u->inflight, sock ? 0 : -1);
+       atomic_set(&u->inflight, 0);
+       INIT_LIST_HEAD(&u->link);
        mutex_init(&u->readlock); /* single task reading lock */
        init_waitqueue_head(&u->peer_wait);
        unix_insert_socket(unix_sockets_unbound, sk);
@@ -1134,9 +1135,6 @@ restart:
        /* take ten and and send info to listening sock */
        spin_lock(&other->sk_receive_queue.lock);
        __skb_queue_tail(&other->sk_receive_queue, skb);
-       /* Undo artificially decreased inflight after embrion
-        * is installed to listening socket. */
-       atomic_inc(&newu->inflight);
        spin_unlock(&other->sk_receive_queue.lock);
        unix_state_unlock(other);
        other->sk_data_ready(other, 0);
@@ -2048,7 +2046,7 @@ static int unix_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations unix_seq_ops = {
+static const struct seq_operations unix_seq_ops = {
        .start  = unix_seq_start,
        .next   = unix_seq_next,
        .stop   = unix_seq_stop,
index f20b7ea7c5553264b5ecd18fc3e5196a8f012500..406b6433e467b4b4cbe697d24ec03f4cfa33e22e 100644 (file)
  *     AV              1 Mar 1999
  *             Damn. Added missing check for ->dead in listen queues scanning.
  *
+ *     Miklos Szeredi 25 Jun 2007
+ *             Reimplement with a cycle collecting algorithm. This should
+ *             solve several problems with the previous code, like being racy
+ *             wrt receive and holding up unrelated socket operations.
  */
 
 #include <linux/kernel.h>
 
 /* Internal data structures and random procedures: */
 
-#define GC_HEAD                ((struct sock *)(-1))
-#define GC_ORPHAN      ((struct sock *)(-3))
-
-static struct sock *gc_current = GC_HEAD; /* stack of objects to mark */
+static LIST_HEAD(gc_inflight_list);
+static LIST_HEAD(gc_candidates);
+static DEFINE_SPINLOCK(unix_gc_lock);
 
 atomic_t unix_tot_inflight = ATOMIC_INIT(0);
 
@@ -122,8 +125,16 @@ void unix_inflight(struct file *fp)
 {
        struct sock *s = unix_get_socket(fp);
        if(s) {
-               atomic_inc(&unix_sk(s)->inflight);
+               struct unix_sock *u = unix_sk(s);
+               spin_lock(&unix_gc_lock);
+               if (atomic_inc_return(&u->inflight) == 1) {
+                       BUG_ON(!list_empty(&u->link));
+                       list_add_tail(&u->link, &gc_inflight_list);
+               } else {
+                       BUG_ON(list_empty(&u->link));
+               }
                atomic_inc(&unix_tot_inflight);
+               spin_unlock(&unix_gc_lock);
        }
 }
 
@@ -131,182 +142,218 @@ void unix_notinflight(struct file *fp)
 {
        struct sock *s = unix_get_socket(fp);
        if(s) {
-               atomic_dec(&unix_sk(s)->inflight);
+               struct unix_sock *u = unix_sk(s);
+               spin_lock(&unix_gc_lock);
+               BUG_ON(list_empty(&u->link));
+               if (atomic_dec_and_test(&u->inflight))
+                       list_del_init(&u->link);
                atomic_dec(&unix_tot_inflight);
+               spin_unlock(&unix_gc_lock);
        }
 }
 
+static inline struct sk_buff *sock_queue_head(struct sock *sk)
+{
+       return (struct sk_buff *) &sk->sk_receive_queue;
+}
 
-/*
- *     Garbage Collector Support Functions
- */
+#define receive_queue_for_each_skb(sk, next, skb) \
+       for (skb = sock_queue_head(sk)->next, next = skb->next; \
+            skb != sock_queue_head(sk); skb = next, next = skb->next)
 
-static inline struct sock *pop_stack(void)
+static void scan_inflight(struct sock *x, void (*func)(struct sock *),
+                         struct sk_buff_head *hitlist)
 {
-       struct sock *p = gc_current;
-       gc_current = unix_sk(p)->gc_tree;
-       return p;
+       struct sk_buff *skb;
+       struct sk_buff *next;
+
+       spin_lock(&x->sk_receive_queue.lock);
+       receive_queue_for_each_skb(x, next, skb) {
+               /*
+                *      Do we have file descriptors ?
+                */
+               if (UNIXCB(skb).fp) {
+                       bool hit = false;
+                       /*
+                        *      Process the descriptors of this socket
+                        */
+                       int nfd = UNIXCB(skb).fp->count;
+                       struct file **fp = UNIXCB(skb).fp->fp;
+                       while (nfd--) {
+                               /*
+                                *      Get the socket the fd matches
+                                *      if it indeed does so
+                                */
+                               struct sock *sk = unix_get_socket(*fp++);
+                               if(sk) {
+                                       hit = true;
+                                       func(sk);
+                               }
+                       }
+                       if (hit && hitlist != NULL) {
+                               __skb_unlink(skb, &x->sk_receive_queue);
+                               __skb_queue_tail(hitlist, skb);
+                       }
+               }
+       }
+       spin_unlock(&x->sk_receive_queue.lock);
 }
 
-static inline int empty_stack(void)
+static void scan_children(struct sock *x, void (*func)(struct sock *),
+                         struct sk_buff_head *hitlist)
 {
-       return gc_current == GC_HEAD;
+       if (x->sk_state != TCP_LISTEN)
+               scan_inflight(x, func, hitlist);
+       else {
+               struct sk_buff *skb;
+               struct sk_buff *next;
+               struct unix_sock *u;
+               LIST_HEAD(embryos);
+
+               /*
+                * For a listening socket collect the queued embryos
+                * and perform a scan on them as well.
+                */
+               spin_lock(&x->sk_receive_queue.lock);
+               receive_queue_for_each_skb(x, next, skb) {
+                       u = unix_sk(skb->sk);
+
+                       /*
+                        * An embryo cannot be in-flight, so it's safe
+                        * to use the list link.
+                        */
+                       BUG_ON(!list_empty(&u->link));
+                       list_add_tail(&u->link, &embryos);
+               }
+               spin_unlock(&x->sk_receive_queue.lock);
+
+               while (!list_empty(&embryos)) {
+                       u = list_entry(embryos.next, struct unix_sock, link);
+                       scan_inflight(&u->sk, func, hitlist);
+                       list_del_init(&u->link);
+               }
+       }
 }
 
-static void maybe_unmark_and_push(struct sock *x)
+static void dec_inflight(struct sock *sk)
 {
-       struct unix_sock *u = unix_sk(x);
+       atomic_dec(&unix_sk(sk)->inflight);
+}
 
-       if (u->gc_tree != GC_ORPHAN)
-               return;
-       sock_hold(x);
-       u->gc_tree = gc_current;
-       gc_current = x;
+static void inc_inflight(struct sock *sk)
+{
+       atomic_inc(&unix_sk(sk)->inflight);
 }
 
+static void inc_inflight_move_tail(struct sock *sk)
+{
+       struct unix_sock *u = unix_sk(sk);
+
+       atomic_inc(&u->inflight);
+       /*
+        * If this is still a candidate, move it to the end of the
+        * list, so that it's checked even if it was already passed
+        * over
+        */
+       if (u->gc_candidate)
+               list_move_tail(&u->link, &gc_candidates);
+}
 
 /* The external entry point: unix_gc() */
 
 void unix_gc(void)
 {
-       static DEFINE_MUTEX(unix_gc_sem);
-       int i;
-       struct sock *s;
-       struct sk_buff_head hitlist;
-       struct sk_buff *skb;
+       static bool gc_in_progress = false;
 
-       /*
-        *      Avoid a recursive GC.
-        */
+       struct unix_sock *u;
+       struct unix_sock *next;
+       struct sk_buff_head hitlist;
+       struct list_head cursor;
 
-       if (!mutex_trylock(&unix_gc_sem))
-               return;
+       spin_lock(&unix_gc_lock);
 
-       spin_lock(&unix_table_lock);
+       /* Avoid a recursive GC. */
+       if (gc_in_progress)
+               goto out;
 
-       forall_unix_sockets(i, s)
-       {
-               unix_sk(s)->gc_tree = GC_ORPHAN;
-       }
+       gc_in_progress = true;
        /*
-        *      Everything is now marked
-        */
-
-       /* Invariant to be maintained:
-               - everything unmarked is either:
-               -- (a) on the stack, or
-               -- (b) has all of its children unmarked
-               - everything on the stack is always unmarked
-               - nothing is ever pushed onto the stack twice, because:
-               -- nothing previously unmarked is ever pushed on the stack
+        * First, select candidates for garbage collection.  Only
+        * in-flight sockets are considered, and from those only ones
+        * which don't have any external reference.
+        *
+        * Holding unix_gc_lock will protect these candidates from
+        * being detached, and hence from gaining an external
+        * reference.  This also means, that since there are no
+        * possible receivers, the receive queues of these sockets are
+        * static during the GC, even though the dequeue is done
+        * before the detach without atomicity guarantees.
         */
+       list_for_each_entry_safe(u, next, &gc_inflight_list, link) {
+               int total_refs;
+               int inflight_refs;
+
+               total_refs = file_count(u->sk.sk_socket->file);
+               inflight_refs = atomic_read(&u->inflight);
+
+               BUG_ON(inflight_refs < 1);
+               BUG_ON(total_refs < inflight_refs);
+               if (total_refs == inflight_refs) {
+                       list_move_tail(&u->link, &gc_candidates);
+                       u->gc_candidate = 1;
+               }
+       }
 
        /*
-        *      Push root set
+        * Now remove all internal in-flight reference to children of
+        * the candidates.
         */
-
-       forall_unix_sockets(i, s)
-       {
-               int open_count = 0;
-
-               /*
-                *      If all instances of the descriptor are not
-                *      in flight we are in use.
-                *
-                *      Special case: when socket s is embrion, it may be
-                *      hashed but still not in queue of listening socket.
-                *      In this case (see unix_create1()) we set artificial
-                *      negative inflight counter to close race window.
-                *      It is trick of course and dirty one.
-                */
-               if (s->sk_socket && s->sk_socket->file)
-                       open_count = file_count(s->sk_socket->file);
-               if (open_count > atomic_read(&unix_sk(s)->inflight))
-                       maybe_unmark_and_push(s);
-       }
+       list_for_each_entry(u, &gc_candidates, link)
+               scan_children(&u->sk, dec_inflight, NULL);
 
        /*
-        *      Mark phase
+        * Restore the references for children of all candidates,
+        * which have remaining references.  Do this recursively, so
+        * only those remain, which form cyclic references.
+        *
+        * Use a "cursor" link, to make the list traversal safe, even
+        * though elements might be moved about.
         */
+       list_add(&cursor, &gc_candidates);
+       while (cursor.next != &gc_candidates) {
+               u = list_entry(cursor.next, struct unix_sock, link);
 
-       while (!empty_stack())
-       {
-               struct sock *x = pop_stack();
-               struct sock *sk;
-
-               spin_lock(&x->sk_receive_queue.lock);
-               skb = skb_peek(&x->sk_receive_queue);
-
-               /*
-                *      Loop through all but first born
-                */
+               /* Move cursor to after the current position. */
+               list_move(&cursor, &u->link);
 
-               while (skb && skb != (struct sk_buff *)&x->sk_receive_queue) {
-                       /*
-                        *      Do we have file descriptors ?
-                        */
-                       if(UNIXCB(skb).fp)
-                       {
-                               /*
-                                *      Process the descriptors of this socket
-                                */
-                               int nfd=UNIXCB(skb).fp->count;
-                               struct file **fp = UNIXCB(skb).fp->fp;
-                               while(nfd--)
-                               {
-                                       /*
-                                        *      Get the socket the fd matches if
-                                        *      it indeed does so
-                                        */
-                                       if((sk=unix_get_socket(*fp++))!=NULL)
-                                       {
-                                               maybe_unmark_and_push(sk);
-                                       }
-                               }
-                       }
-                       /* We have to scan not-yet-accepted ones too */
-                       if (x->sk_state == TCP_LISTEN)
-                               maybe_unmark_and_push(skb->sk);
-                       skb=skb->next;
+               if (atomic_read(&u->inflight) > 0) {
+                       list_move_tail(&u->link, &gc_inflight_list);
+                       u->gc_candidate = 0;
+                       scan_children(&u->sk, inc_inflight_move_tail, NULL);
                }
-               spin_unlock(&x->sk_receive_queue.lock);
-               sock_put(x);
        }
+       list_del(&cursor);
 
+       /*
+        * Now gc_candidates contains only garbage.  Restore original
+        * inflight counters for these as well, and remove the skbuffs
+        * which are creating the cycle(s).
+        */
        skb_queue_head_init(&hitlist);
+       list_for_each_entry(u, &gc_candidates, link)
+               scan_children(&u->sk, inc_inflight, &hitlist);
 
-       forall_unix_sockets(i, s)
-       {
-               struct unix_sock *u = unix_sk(s);
+       spin_unlock(&unix_gc_lock);
 
-               if (u->gc_tree == GC_ORPHAN) {
-                       struct sk_buff *nextsk;
+       /* Here we are. Hitlist is filled. Die. */
+       __skb_queue_purge(&hitlist);
 
-                       spin_lock(&s->sk_receive_queue.lock);
-                       skb = skb_peek(&s->sk_receive_queue);
-                       while (skb &&
-                              skb != (struct sk_buff *)&s->sk_receive_queue) {
-                               nextsk = skb->next;
-                               /*
-                                *      Do we have file descriptors ?
-                                */
-                               if (UNIXCB(skb).fp) {
-                                       __skb_unlink(skb,
-                                                    &s->sk_receive_queue);
-                                       __skb_queue_tail(&hitlist, skb);
-                               }
-                               skb = nextsk;
-                       }
-                       spin_unlock(&s->sk_receive_queue.lock);
-               }
-               u->gc_tree = GC_ORPHAN;
-       }
-       spin_unlock(&unix_table_lock);
+       spin_lock(&unix_gc_lock);
 
-       /*
-        *      Here we are. Hitlist is filled. Die.
-        */
+       /* All candidates should have been detached by now. */
+       BUG_ON(!list_empty(&gc_candidates));
+       gc_in_progress = false;
 
-       __skb_queue_purge(&hitlist);
-       mutex_unlock(&unix_gc_sem);
+ out:
+       spin_unlock(&unix_gc_lock);
 }
index 205106521ecba36c886f5dbf90064798e3da2d25..236e7eaf1b7f4d6069efa61b16b4aedcc1ef238e 100644 (file)
@@ -164,14 +164,14 @@ static int status_show(struct seq_file *m, void *v)
        return 0;
 }
 
-static struct seq_operations config_op = {
+static const struct seq_operations config_op = {
        .start  = r_start,
        .next   = r_next,
        .stop   = r_stop,
        .show   = config_show,
 };
 
-static struct seq_operations status_op = {
+static const struct seq_operations status_op = {
        .start  = r_start,
        .next   = r_next,
        .stop   = r_stop,
index 96001f0c64fc16a8f4cd32512bb31adab912ec5f..7405b9c5b7f2dfa2734adf7946515f0219f67728 100644 (file)
@@ -234,21 +234,21 @@ out:
        return 0;
 }
 
-static struct seq_operations x25_seq_route_ops = {
+static const struct seq_operations x25_seq_route_ops = {
        .start  = x25_seq_route_start,
        .next   = x25_seq_route_next,
        .stop   = x25_seq_route_stop,
        .show   = x25_seq_route_show,
 };
 
-static struct seq_operations x25_seq_socket_ops = {
+static const struct seq_operations x25_seq_socket_ops = {
        .start  = x25_seq_socket_start,
        .next   = x25_seq_socket_next,
        .stop   = x25_seq_socket_stop,
        .show   = x25_seq_socket_show,
 };
 
-static struct seq_operations x25_seq_forward_ops = {
+static const struct seq_operations x25_seq_forward_ops = {
        .start  = x25_seq_forward_start,
        .next   = x25_seq_forward_next,
        .stop   = x25_seq_forward_stop,
index dfacb9c2a6e3861837b1a25b2d919bcc19b88d5a..e070c3f938fb25f3cde9d4e052ff22786a12330f 100644 (file)
@@ -686,6 +686,37 @@ out:
        return x;
 }
 
+struct xfrm_state *
+xfrm_stateonly_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
+                   unsigned short family, u8 mode, u8 proto, u32 reqid)
+{
+       unsigned int h = xfrm_dst_hash(daddr, saddr, reqid, family);
+       struct xfrm_state *rx = NULL, *x = NULL;
+       struct hlist_node *entry;
+
+       spin_lock(&xfrm_state_lock);
+       hlist_for_each_entry(x, entry, xfrm_state_bydst+h, bydst) {
+               if (x->props.family == family &&
+                   x->props.reqid == reqid &&
+                   !(x->props.flags & XFRM_STATE_WILDRECV) &&
+                   xfrm_state_addr_check(x, daddr, saddr, family) &&
+                   mode == x->props.mode &&
+                   proto == x->id.proto &&
+                   x->km.state == XFRM_STATE_VALID) {
+                       rx = x;
+                       break;
+               }
+       }
+
+       if (rx)
+               xfrm_state_hold(rx);
+       spin_unlock(&xfrm_state_lock);
+
+
+       return rx;
+}
+EXPORT_SYMBOL(xfrm_stateonly_find);
+
 static void __xfrm_state_insert(struct xfrm_state *x)
 {
        unsigned int h;
index 8ffd76405b5b69f0b61057be0ffc3fb2af6adb6a..d6a112ce2975c847390fed605ade3d532f4fe03a 100644 (file)
@@ -420,8 +420,12 @@ static int dummy_file_ioctl (struct file *file, unsigned int command,
 
 static int dummy_file_mmap (struct file *file, unsigned long reqprot,
                            unsigned long prot,
-                           unsigned long flags)
+                           unsigned long flags,
+                           unsigned long addr,
+                           unsigned long addr_only)
 {
+       if (addr < mmap_min_addr)
+               return -EACCES;
        return 0;
 }
 
index fc8601b2b7acabde473cc86a0fdc4b342a00e97a..27e5863d30f1f916393e855a6bfa496475a8fa71 100644 (file)
@@ -24,6 +24,7 @@ extern struct security_operations dummy_security_ops;
 extern void security_fixup_ops(struct security_operations *ops);
 
 struct security_operations *security_ops;      /* Initialized to NULL */
+unsigned long mmap_min_addr;           /* 0 means no protection */
 
 static inline int verify(struct security_operations *ops)
 {
index e4396a89edc620dfd8e52aafebe7273c30869c0a..78c408fd2b02cdf66e2e9331304da6b1bf352116 100644 (file)
@@ -586,7 +586,7 @@ void avc_audit(u32 ssid, u32 tsid,
                                }
                        }
                        if (inode)
-                               audit_log_format(ab, " dev=%s ino=%ld",
+                               audit_log_format(ab, " dev=%s ino=%lu",
                                                 inode->i_sb->s_id,
                                                 inode->i_ino);
                        break;
@@ -832,6 +832,7 @@ int avc_ss_reset(u32 seqno)
  * @tsid: target security identifier
  * @tclass: target security class
  * @requested: requested permissions, interpreted based on @tclass
+ * @flags:  AVC_STRICT or 0
  * @avd: access vector decisions
  *
  * Check the AVC to determine whether the @requested permissions are granted
@@ -846,8 +847,9 @@ int avc_ss_reset(u32 seqno)
  * should be released for the auditing.
  */
 int avc_has_perm_noaudit(u32 ssid, u32 tsid,
-                         u16 tclass, u32 requested,
-                         struct av_decision *avd)
+                        u16 tclass, u32 requested,
+                        unsigned flags,
+                        struct av_decision *avd)
 {
        struct avc_node *node;
        struct avc_entry entry, *p_ae;
@@ -874,7 +876,7 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid,
        denied = requested & ~(p_ae->avd.allowed);
 
        if (!requested || denied) {
-               if (selinux_enforcing)
+               if (selinux_enforcing || (flags & AVC_STRICT))
                        rc = -EACCES;
                else
                        if (node)
@@ -909,7 +911,7 @@ int avc_has_perm(u32 ssid, u32 tsid, u16 tclass,
        struct av_decision avd;
        int rc;
 
-       rc = avc_has_perm_noaudit(ssid, tsid, tclass, requested, &avd);
+       rc = avc_has_perm_noaudit(ssid, tsid, tclass, requested, 0, &avd);
        avc_audit(ssid, tsid, tclass, requested, &avd, rc, auditdata);
        return rc;
 }
index ad8dd4e8657e5487bd7668328238c166248176da..aff8f46c2aa204601b25c2442204aeb20e10c132 100644 (file)
@@ -1592,9 +1592,10 @@ static int selinux_vm_enough_memory(long pages)
        rc = secondary_ops->capable(current, CAP_SYS_ADMIN);
        if (rc == 0)
                rc = avc_has_perm_noaudit(tsec->sid, tsec->sid,
-                                       SECCLASS_CAPABILITY,
-                                       CAP_TO_MASK(CAP_SYS_ADMIN),
-                                       NULL);
+                                         SECCLASS_CAPABILITY,
+                                         CAP_TO_MASK(CAP_SYS_ADMIN),
+                                         0,
+                                         NULL);
 
        if (rc == 0)
                cap_sys_admin = 1;
@@ -2568,12 +2569,16 @@ static int file_map_prot_check(struct file *file, unsigned long prot, int shared
 }
 
 static int selinux_file_mmap(struct file *file, unsigned long reqprot,
-                            unsigned long prot, unsigned long flags)
+                            unsigned long prot, unsigned long flags,
+                            unsigned long addr, unsigned long addr_only)
 {
-       int rc;
+       int rc = 0;
+       u32 sid = ((struct task_security_struct*)(current->security))->sid;
 
-       rc = secondary_ops->file_mmap(file, reqprot, prot, flags);
-       if (rc)
+       if (addr < mmap_min_addr)
+               rc = avc_has_perm(sid, sid, SECCLASS_MEMPROTECT,
+                                 MEMPROTECT__MMAP_ZERO, NULL);
+       if (rc || addr_only)
                return rc;
 
        if (selinux_checkreqprot)
@@ -3124,17 +3129,19 @@ static int selinux_parse_skb(struct sk_buff *skb, struct avc_audit_data *ad,
 /**
  * selinux_skb_extlbl_sid - Determine the external label of a packet
  * @skb: the packet
- * @base_sid: the SELinux SID to use as a context for MLS only external labels
  * @sid: the packet's SID
  *
  * Description:
  * Check the various different forms of external packet labeling and determine
- * the external SID for the packet.
+ * the external SID for the packet.  If only one form of external labeling is
+ * present then it is used, if both labeled IPsec and NetLabel labels are
+ * present then the SELinux type information is taken from the labeled IPsec
+ * SA and the MLS sensitivity label information is taken from the NetLabel
+ * security attributes.  This bit of "magic" is done in the call to
+ * selinux_netlbl_skbuff_getsid().
  *
  */
-static void selinux_skb_extlbl_sid(struct sk_buff *skb,
-                                  u32 base_sid,
-                                  u32 *sid)
+static void selinux_skb_extlbl_sid(struct sk_buff *skb, u32 *sid)
 {
        u32 xfrm_sid;
        u32 nlbl_sid;
@@ -3142,10 +3149,9 @@ static void selinux_skb_extlbl_sid(struct sk_buff *skb,
        selinux_skb_xfrm_sid(skb, &xfrm_sid);
        if (selinux_netlbl_skbuff_getsid(skb,
                                         (xfrm_sid == SECSID_NULL ?
-                                         base_sid : xfrm_sid),
+                                         SECINITSID_NETMSG : xfrm_sid),
                                         &nlbl_sid) != 0)
                nlbl_sid = SECSID_NULL;
-
        *sid = (nlbl_sid == SECSID_NULL ? xfrm_sid : nlbl_sid);
 }
 
@@ -3690,7 +3696,7 @@ static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *
        if (sock && sock->sk->sk_family == PF_UNIX)
                selinux_get_inode_sid(SOCK_INODE(sock), &peer_secid);
        else if (skb)
-               selinux_skb_extlbl_sid(skb, SECINITSID_UNLABELED, &peer_secid);
+               selinux_skb_extlbl_sid(skb, &peer_secid);
 
        if (peer_secid == SECSID_NULL)
                err = -EINVAL;
@@ -3751,7 +3757,7 @@ static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
        u32 newsid;
        u32 peersid;
 
-       selinux_skb_extlbl_sid(skb, SECINITSID_UNLABELED, &peersid);
+       selinux_skb_extlbl_sid(skb, &peersid);
        if (peersid == SECSID_NULL) {
                req->secid = sksec->sid;
                req->peer_secid = SECSID_NULL;
@@ -3789,7 +3795,7 @@ static void selinux_inet_conn_established(struct sock *sk,
 {
        struct sk_security_struct *sksec = sk->sk_security;
 
-       selinux_skb_extlbl_sid(skb, SECINITSID_UNLABELED, &sksec->peer_sid);
+       selinux_skb_extlbl_sid(skb, &sksec->peer_sid);
 }
 
 static void selinux_req_classify_flow(const struct request_sock *req,
@@ -4626,7 +4632,7 @@ static int selinux_setprocattr(struct task_struct *p,
                if (p->ptrace & PT_PTRACED) {
                        error = avc_has_perm_noaudit(tsec->ptrace_sid, sid,
                                                     SECCLASS_PROCESS,
-                                                    PROCESS__PTRACE, &avd);
+                                                    PROCESS__PTRACE, 0, &avd);
                        if (!error)
                                tsec->sid = sid;
                        task_unlock(p);
index b83e74012a979ee8bc935921fa686496fd82f681..049bf69429b66d2566abc5bb063c19fc41647095 100644 (file)
    S_(SECCLASS_KEY, KEY__CREATE, "create")
    S_(SECCLASS_DCCP_SOCKET, DCCP_SOCKET__NODE_BIND, "node_bind")
    S_(SECCLASS_DCCP_SOCKET, DCCP_SOCKET__NAME_CONNECT, "name_connect")
+   S_(SECCLASS_MEMPROTECT, MEMPROTECT__MMAP_ZERO, "mmap_zero")
index 5fee1735bffe423d78cb559e1cb3ee529b6ced5f..eda89a2ec635db3ec67e546af97cd5d76dedc565 100644 (file)
 #define DCCP_SOCKET__NAME_BIND                    0x00200000UL
 #define DCCP_SOCKET__NODE_BIND                    0x00400000UL
 #define DCCP_SOCKET__NAME_CONNECT                 0x00800000UL
+#define MEMPROTECT__MMAP_ZERO                     0x00000001UL
index 6ed10c3d3339baf03cb8e79d0357b078a14427bf..e145f6e13b0b6b711c632b849bf1f83d9d125e65 100644 (file)
@@ -102,9 +102,11 @@ void avc_audit(u32 ssid, u32 tsid,
                u16 tclass, u32 requested,
                struct av_decision *avd, int result, struct avc_audit_data *auditdata);
 
+#define AVC_STRICT 1 /* Ignore permissive mode. */
 int avc_has_perm_noaudit(u32 ssid, u32 tsid,
-                         u16 tclass, u32 requested,
-                         struct av_decision *avd);
+                        u16 tclass, u32 requested,
+                        unsigned flags,
+                        struct av_decision *avd);
 
 int avc_has_perm(u32 ssid, u32 tsid,
                  u16 tclass, u32 requested,
index 3787990684418f540974541d3c6b68078b4c72c4..e77de0e62ea0e00deae7c92822d61b5ba9e82ce0 100644 (file)
@@ -63,3 +63,4 @@
     S_("key")
     S_(NULL)
     S_("dccp_socket")
+    S_("memprotect")
index 35f309f478731aa0ea116c81055cdfd72a77460f..a9c2b20f14b5c0584085180c272875453b9796c9 100644 (file)
@@ -49,6 +49,7 @@
 #define SECCLASS_PACKET                                  57
 #define SECCLASS_KEY                                     58
 #define SECCLASS_DCCP_SOCKET                             60
+#define SECCLASS_MEMPROTECT                              61
 
 /*
  * Security identifier indices for initial entities
index b94378afea251d124a7308d5bca790a72a72f3f0..83bdd4d2a29e1ad4713367e2b506a3e756c1079f 100644 (file)
@@ -41,6 +41,7 @@ extern int selinux_mls_enabled;
 
 int security_load_policy(void * data, size_t len);
 
+#define SEL_VEC_MAX 32
 struct av_decision {
        u32 allowed;
        u32 decided;
@@ -87,6 +88,9 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
 
 int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid);
 
+int security_get_classes(char ***classes, int *nclasses);
+int security_get_permissions(char *class, char ***perms, int *nperms);
+
 #define SECURITY_FS_USE_XATTR          1 /* use xattr */
 #define SECURITY_FS_USE_TRANS          2 /* use transition SIDs, e.g. devpts/tmpfs */
 #define SECURITY_FS_USE_TASK           3 /* use task SIDs, e.g. pipefs/sockfs */
index e64eca246f1ab25ce57cb1190cc578fa643421e9..8192e8bc9f5aa6665ce37fc219981bab206bb6b9 100644 (file)
@@ -158,9 +158,7 @@ int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, u32 base_sid, u32 *sid)
        netlbl_secattr_init(&secattr);
        rc = netlbl_skbuff_getattr(skb, &secattr);
        if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE)
-               rc = security_netlbl_secattr_to_sid(&secattr,
-                                                   base_sid,
-                                                   sid);
+               rc = security_netlbl_secattr_to_sid(&secattr, base_sid, sid);
        else
                *sid = SECSID_NULL;
        netlbl_secattr_destroy(&secattr);
@@ -198,7 +196,7 @@ void selinux_netlbl_sock_graft(struct sock *sk, struct socket *sock)
        if (netlbl_sock_getattr(sk, &secattr) == 0 &&
            secattr.flags != NETLBL_SECATTR_NONE &&
            security_netlbl_secattr_to_sid(&secattr,
-                                          SECINITSID_UNLABELED,
+                                          SECINITSID_NETMSG,
                                           &nlbl_peer_sid) == 0)
                sksec->peer_sid = nlbl_peer_sid;
        netlbl_secattr_destroy(&secattr);
@@ -295,38 +293,32 @@ int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
                                struct avc_audit_data *ad)
 {
        int rc;
-       u32 netlbl_sid;
-       u32 recv_perm;
+       u32 nlbl_sid;
+       u32 perm;
 
-       rc = selinux_netlbl_skbuff_getsid(skb,
-                                         SECINITSID_UNLABELED,
-                                         &netlbl_sid);
+       rc = selinux_netlbl_skbuff_getsid(skb, SECINITSID_NETMSG, &nlbl_sid);
        if (rc != 0)
                return rc;
-
-       if (netlbl_sid == SECSID_NULL)
-               return 0;
+       if (nlbl_sid == SECSID_NULL)
+               nlbl_sid = SECINITSID_UNLABELED;
 
        switch (sksec->sclass) {
        case SECCLASS_UDP_SOCKET:
-               recv_perm = UDP_SOCKET__RECVFROM;
+               perm = UDP_SOCKET__RECVFROM;
                break;
        case SECCLASS_TCP_SOCKET:
-               recv_perm = TCP_SOCKET__RECVFROM;
+               perm = TCP_SOCKET__RECVFROM;
                break;
        default:
-               recv_perm = RAWIP_SOCKET__RECVFROM;
+               perm = RAWIP_SOCKET__RECVFROM;
        }
 
-       rc = avc_has_perm(sksec->sid,
-                         netlbl_sid,
-                         sksec->sclass,
-                         recv_perm,
-                         ad);
+       rc = avc_has_perm(sksec->sid, nlbl_sid, sksec->sclass, perm, ad);
        if (rc == 0)
                return 0;
 
-       netlbl_skbuff_err(skb, rc);
+       if (nlbl_sid != SECINITSID_UNLABELED)
+               netlbl_skbuff_err(skb, rc);
        return rc;
 }
 
index aca099aa2ed3d743e65d38a4c77da690e4609e2f..c9e92daedee2c72c0860d8c0ff2cfcfc7b16a38d 100644 (file)
@@ -67,6 +67,10 @@ static struct dentry *bool_dir = NULL;
 static int bool_num = 0;
 static int *bool_pending_values = NULL;
 
+/* global data for classes */
+static struct dentry *class_dir = NULL;
+static unsigned long last_class_ino;
+
 extern void selnl_notify_setenforce(int val);
 
 /* Check whether a task is allowed to use a security operation. */
@@ -106,6 +110,7 @@ static unsigned long sel_last_ino = SEL_INO_NEXT - 1;
 
 #define SEL_INITCON_INO_OFFSET         0x01000000
 #define SEL_BOOL_INO_OFFSET    0x02000000
+#define SEL_CLASS_INO_OFFSET   0x04000000
 #define SEL_INO_MASK           0x00ffffff
 
 #define TMPBUFLEN      12
@@ -237,6 +242,11 @@ static const struct file_operations sel_policyvers_ops = {
 
 /* declaration for sel_write_load */
 static int sel_make_bools(void);
+static int sel_make_classes(void);
+
+/* declaration for sel_make_class_dirs */
+static int sel_make_dir(struct inode *dir, struct dentry *dentry,
+                       unsigned long *ino);
 
 static ssize_t sel_read_mls(struct file *filp, char __user *buf,
                                size_t count, loff_t *ppos)
@@ -287,10 +297,18 @@ static ssize_t sel_write_load(struct file * file, const char __user * buf,
                goto out;
 
        ret = sel_make_bools();
+       if (ret) {
+               length = ret;
+               goto out1;
+       }
+
+       ret = sel_make_classes();
        if (ret)
                length = ret;
        else
                length = count;
+
+out1:
        audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_POLICY_LOAD,
                "policy loaded auid=%u",
                audit_get_loginuid(current->audit_context));
@@ -940,9 +958,8 @@ static const struct file_operations sel_commit_bools_ops = {
        .write          = sel_commit_bools_write,
 };
 
-/* delete booleans - partial revoke() from
- * fs/proc/generic.c proc_kill_inodes */
-static void sel_remove_bools(struct dentry *de)
+/* partial revoke() from fs/proc/generic.c proc_kill_inodes */
+static void sel_remove_entries(struct dentry *de)
 {
        struct list_head *p, *node;
        struct super_block *sb = de->d_sb;
@@ -998,7 +1015,7 @@ static int sel_make_bools(void)
        kfree(bool_pending_values);
        bool_pending_values = NULL;
 
-       sel_remove_bools(dir);
+       sel_remove_entries(dir);
 
        if (!(page = (char*)get_zeroed_page(GFP_KERNEL)))
                return -ENOMEM;
@@ -1048,7 +1065,7 @@ out:
        return ret;
 err:
        kfree(values);
-       sel_remove_bools(dir);
+       sel_remove_entries(dir);
        ret = -ENOMEM;
        goto out;
 }
@@ -1294,7 +1311,227 @@ out:
        return ret;
 }
 
-static int sel_make_dir(struct inode *dir, struct dentry *dentry)
+static inline unsigned int sel_div(unsigned long a, unsigned long b)
+{
+       return a / b - (a % b < 0);
+}
+
+static inline unsigned long sel_class_to_ino(u16 class)
+{
+       return (class * (SEL_VEC_MAX + 1)) | SEL_CLASS_INO_OFFSET;
+}
+
+static inline u16 sel_ino_to_class(unsigned long ino)
+{
+       return sel_div(ino & SEL_INO_MASK, SEL_VEC_MAX + 1);
+}
+
+static inline unsigned long sel_perm_to_ino(u16 class, u32 perm)
+{
+       return (class * (SEL_VEC_MAX + 1) + perm) | SEL_CLASS_INO_OFFSET;
+}
+
+static inline u32 sel_ino_to_perm(unsigned long ino)
+{
+       return (ino & SEL_INO_MASK) % (SEL_VEC_MAX + 1);
+}
+
+static ssize_t sel_read_class(struct file * file, char __user *buf,
+                               size_t count, loff_t *ppos)
+{
+       ssize_t rc, len;
+       char *page;
+       unsigned long ino = file->f_path.dentry->d_inode->i_ino;
+
+       page = (char *)__get_free_page(GFP_KERNEL);
+       if (!page) {
+               rc = -ENOMEM;
+               goto out;
+       }
+
+       len = snprintf(page, PAGE_SIZE, "%d", sel_ino_to_class(ino));
+       rc = simple_read_from_buffer(buf, count, ppos, page, len);
+       free_page((unsigned long)page);
+out:
+       return rc;
+}
+
+static const struct file_operations sel_class_ops = {
+       .read           = sel_read_class,
+};
+
+static ssize_t sel_read_perm(struct file * file, char __user *buf,
+                               size_t count, loff_t *ppos)
+{
+       ssize_t rc, len;
+       char *page;
+       unsigned long ino = file->f_path.dentry->d_inode->i_ino;
+
+       page = (char *)__get_free_page(GFP_KERNEL);
+       if (!page) {
+               rc = -ENOMEM;
+               goto out;
+       }
+
+       len = snprintf(page, PAGE_SIZE,"%d", sel_ino_to_perm(ino));
+       rc = simple_read_from_buffer(buf, count, ppos, page, len);
+       free_page((unsigned long)page);
+out:
+       return rc;
+}
+
+static const struct file_operations sel_perm_ops = {
+       .read           = sel_read_perm,
+};
+
+static int sel_make_perm_files(char *objclass, int classvalue,
+                               struct dentry *dir)
+{
+       int i, rc = 0, nperms;
+       char **perms;
+
+       rc = security_get_permissions(objclass, &perms, &nperms);
+       if (rc)
+               goto out;
+
+       for (i = 0; i < nperms; i++) {
+               struct inode *inode;
+               struct dentry *dentry;
+
+               dentry = d_alloc_name(dir, perms[i]);
+               if (!dentry) {
+                       rc = -ENOMEM;
+                       goto out1;
+               }
+
+               inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO);
+               if (!inode) {
+                       rc = -ENOMEM;
+                       goto out1;
+               }
+               inode->i_fop = &sel_perm_ops;
+               /* i+1 since perm values are 1-indexed */
+               inode->i_ino = sel_perm_to_ino(classvalue, i+1);
+               d_add(dentry, inode);
+       }
+
+out1:
+       for (i = 0; i < nperms; i++)
+               kfree(perms[i]);
+       kfree(perms);
+out:
+       return rc;
+}
+
+static int sel_make_class_dir_entries(char *classname, int index,
+                                       struct dentry *dir)
+{
+       struct dentry *dentry = NULL;
+       struct inode *inode = NULL;
+       int rc;
+
+       dentry = d_alloc_name(dir, "index");
+       if (!dentry) {
+               rc = -ENOMEM;
+               goto out;
+       }
+
+       inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO);
+       if (!inode) {
+               rc = -ENOMEM;
+               goto out;
+       }
+
+       inode->i_fop = &sel_class_ops;
+       inode->i_ino = sel_class_to_ino(index);
+       d_add(dentry, inode);
+
+       dentry = d_alloc_name(dir, "perms");
+       if (!dentry) {
+               rc = -ENOMEM;
+               goto out;
+       }
+
+       rc = sel_make_dir(dir->d_inode, dentry, &last_class_ino);
+       if (rc)
+               goto out;
+
+       rc = sel_make_perm_files(classname, index, dentry);
+
+out:
+       return rc;
+}
+
+static void sel_remove_classes(void)
+{
+       struct list_head *class_node;
+
+       list_for_each(class_node, &class_dir->d_subdirs) {
+               struct dentry *class_subdir = list_entry(class_node,
+                                       struct dentry, d_u.d_child);
+               struct list_head *class_subdir_node;
+
+               list_for_each(class_subdir_node, &class_subdir->d_subdirs) {
+                       struct dentry *d = list_entry(class_subdir_node,
+                                               struct dentry, d_u.d_child);
+
+                       if (d->d_inode)
+                               if (d->d_inode->i_mode & S_IFDIR)
+                                       sel_remove_entries(d);
+               }
+
+               sel_remove_entries(class_subdir);
+       }
+
+       sel_remove_entries(class_dir);
+}
+
+static int sel_make_classes(void)
+{
+       int rc = 0, nclasses, i;
+       char **classes;
+
+       /* delete any existing entries */
+       sel_remove_classes();
+
+       rc = security_get_classes(&classes, &nclasses);
+       if (rc < 0)
+               goto out;
+
+       /* +2 since classes are 1-indexed */
+       last_class_ino = sel_class_to_ino(nclasses+2);
+
+       for (i = 0; i < nclasses; i++) {
+               struct dentry *class_name_dir;
+
+               class_name_dir = d_alloc_name(class_dir, classes[i]);
+               if (!class_name_dir) {
+                       rc = -ENOMEM;
+                       goto out1;
+               }
+
+               rc = sel_make_dir(class_dir->d_inode, class_name_dir,
+                               &last_class_ino);
+               if (rc)
+                       goto out1;
+
+               /* i+1 since class values are 1-indexed */
+               rc = sel_make_class_dir_entries(classes[i], i+1,
+                               class_name_dir);
+               if (rc)
+                       goto out1;
+       }
+
+out1:
+       for (i = 0; i < nclasses; i++)
+               kfree(classes[i]);
+       kfree(classes);
+out:
+       return rc;
+}
+
+static int sel_make_dir(struct inode *dir, struct dentry *dentry,
+                       unsigned long *ino)
 {
        int ret = 0;
        struct inode *inode;
@@ -1306,7 +1543,7 @@ static int sel_make_dir(struct inode *dir, struct dentry *dentry)
        }
        inode->i_op = &simple_dir_inode_operations;
        inode->i_fop = &simple_dir_operations;
-       inode->i_ino = ++sel_last_ino;
+       inode->i_ino = ++(*ino);
        /* directory inodes start off with i_nlink == 2 (for "." entry) */
        inc_nlink(inode);
        d_add(dentry, inode);
@@ -1352,7 +1589,7 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent)
                goto err;
        }
 
-       ret = sel_make_dir(root_inode, dentry);
+       ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
        if (ret)
                goto err;
 
@@ -1385,7 +1622,7 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent)
                goto err;
        }
 
-       ret = sel_make_dir(root_inode, dentry);
+       ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
        if (ret)
                goto err;
 
@@ -1399,7 +1636,7 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent)
                goto err;
        }
 
-       ret = sel_make_dir(root_inode, dentry);
+       ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
        if (ret)
                goto err;
 
@@ -1407,6 +1644,18 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent)
        if (ret)
                goto err;
 
+       dentry = d_alloc_name(sb->s_root, "class");
+       if (!dentry) {
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
+       if (ret)
+               goto err;
+
+       class_dir = dentry;
+
 out:
        return ret;
 err:
index 0ac1021734c01118a012b38ab7335b8eeeb2f4fa..f05f97a2bc3a1343e5960f1c409a8ae0e7e565f4 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/errno.h>
@@ -598,6 +599,7 @@ void policydb_destroy(struct policydb *p)
        struct range_trans *rt, *lrt = NULL;
 
        for (i = 0; i < SYM_NUM; i++) {
+               cond_resched();
                hashtab_map(p->symtab[i].table, destroy_f[i], NULL);
                hashtab_destroy(p->symtab[i].table);
        }
@@ -612,6 +614,7 @@ void policydb_destroy(struct policydb *p)
        avtab_destroy(&p->te_avtab);
 
        for (i = 0; i < OCON_NUM; i++) {
+               cond_resched();
                c = p->ocontexts[i];
                while (c) {
                        ctmp = c;
@@ -623,6 +626,7 @@ void policydb_destroy(struct policydb *p)
 
        g = p->genfs;
        while (g) {
+               cond_resched();
                kfree(g->fstype);
                c = g->head;
                while (c) {
@@ -639,18 +643,21 @@ void policydb_destroy(struct policydb *p)
        cond_policydb_destroy(p);
 
        for (tr = p->role_tr; tr; tr = tr->next) {
+               cond_resched();
                kfree(ltr);
                ltr = tr;
        }
        kfree(ltr);
 
        for (ra = p->role_allow; ra; ra = ra -> next) {
+               cond_resched();
                kfree(lra);
                lra = ra;
        }
        kfree(lra);
 
        for (rt = p->range_tr; rt; rt = rt -> next) {
+               cond_resched();
                if (lrt) {
                        ebitmap_destroy(&lrt->target_range.level[0].cat);
                        ebitmap_destroy(&lrt->target_range.level[1].cat);
index 40660ffd49b64947c31ab32c617a316f407258d3..b5f017f07a75b6f614faf3cd9631fdc370936f0f 100644 (file)
@@ -1587,19 +1587,18 @@ int security_get_user_sids(u32 fromsid,
                           u32 *nel)
 {
        struct context *fromcon, usercon;
-       u32 *mysids, *mysids2, sid;
+       u32 *mysids = NULL, *mysids2, sid;
        u32 mynel = 0, maxnel = SIDS_NEL;
        struct user_datum *user;
        struct role_datum *role;
-       struct av_decision avd;
        struct ebitmap_node *rnode, *tnode;
        int rc = 0, i, j;
 
-       if (!ss_initialized) {
-               *sids = NULL;
-               *nel = 0;
+       *sids = NULL;
+       *nel = 0;
+
+       if (!ss_initialized)
                goto out;
-       }
 
        POLICY_RDLOCK;
 
@@ -1635,17 +1634,9 @@ int security_get_user_sids(u32 fromsid,
                        if (mls_setup_user_range(fromcon, user, &usercon))
                                continue;
 
-                       rc = context_struct_compute_av(fromcon, &usercon,
-                                                      SECCLASS_PROCESS,
-                                                      PROCESS__TRANSITION,
-                                                      &avd);
-                       if (rc ||  !(avd.allowed & PROCESS__TRANSITION))
-                               continue;
                        rc = sidtab_context_to_sid(&sidtab, &usercon, &sid);
-                       if (rc) {
-                               kfree(mysids);
+                       if (rc)
                                goto out_unlock;
-                       }
                        if (mynel < maxnel) {
                                mysids[mynel++] = sid;
                        } else {
@@ -1653,7 +1644,6 @@ int security_get_user_sids(u32 fromsid,
                                mysids2 = kcalloc(maxnel, sizeof(*mysids2), GFP_ATOMIC);
                                if (!mysids2) {
                                        rc = -ENOMEM;
-                                       kfree(mysids);
                                        goto out_unlock;
                                }
                                memcpy(mysids2, mysids, mynel * sizeof(*mysids2));
@@ -1664,11 +1654,32 @@ int security_get_user_sids(u32 fromsid,
                }
        }
 
-       *sids = mysids;
-       *nel = mynel;
-
 out_unlock:
        POLICY_RDUNLOCK;
+       if (rc || !mynel) {
+               kfree(mysids);
+               goto out;
+       }
+
+       mysids2 = kcalloc(mynel, sizeof(*mysids2), GFP_KERNEL);
+       if (!mysids2) {
+               rc = -ENOMEM;
+               kfree(mysids);
+               goto out;
+       }
+       for (i = 0, j = 0; i < mynel; i++) {
+               rc = avc_has_perm_noaudit(fromsid, mysids[i],
+                                         SECCLASS_PROCESS,
+                                         PROCESS__TRANSITION, AVC_STRICT,
+                                         NULL);
+               if (!rc)
+                       mysids2[j++] = mysids[i];
+               cond_resched();
+       }
+       rc = 0;
+       kfree(mysids);
+       *sids = mysids2;
+       *nel = j;
 out:
        return rc;
 }
@@ -1996,6 +2007,101 @@ out:
        return rc;
 }
 
+static int get_classes_callback(void *k, void *d, void *args)
+{
+       struct class_datum *datum = d;
+       char *name = k, **classes = args;
+       int value = datum->value - 1;
+
+       classes[value] = kstrdup(name, GFP_ATOMIC);
+       if (!classes[value])
+               return -ENOMEM;
+
+       return 0;
+}
+
+int security_get_classes(char ***classes, int *nclasses)
+{
+       int rc = -ENOMEM;
+
+       POLICY_RDLOCK;
+
+       *nclasses = policydb.p_classes.nprim;
+       *classes = kcalloc(*nclasses, sizeof(*classes), GFP_ATOMIC);
+       if (!*classes)
+               goto out;
+
+       rc = hashtab_map(policydb.p_classes.table, get_classes_callback,
+                       *classes);
+       if (rc < 0) {
+               int i;
+               for (i = 0; i < *nclasses; i++)
+                       kfree((*classes)[i]);
+               kfree(*classes);
+       }
+
+out:
+       POLICY_RDUNLOCK;
+       return rc;
+}
+
+static int get_permissions_callback(void *k, void *d, void *args)
+{
+       struct perm_datum *datum = d;
+       char *name = k, **perms = args;
+       int value = datum->value - 1;
+
+       perms[value] = kstrdup(name, GFP_ATOMIC);
+       if (!perms[value])
+               return -ENOMEM;
+
+       return 0;
+}
+
+int security_get_permissions(char *class, char ***perms, int *nperms)
+{
+       int rc = -ENOMEM, i;
+       struct class_datum *match;
+
+       POLICY_RDLOCK;
+
+       match = hashtab_search(policydb.p_classes.table, class);
+       if (!match) {
+               printk(KERN_ERR "%s:  unrecognized class %s\n",
+                       __FUNCTION__, class);
+               rc = -EINVAL;
+               goto out;
+       }
+
+       *nperms = match->permissions.nprim;
+       *perms = kcalloc(*nperms, sizeof(*perms), GFP_ATOMIC);
+       if (!*perms)
+               goto out;
+
+       if (match->comdatum) {
+               rc = hashtab_map(match->comdatum->permissions.table,
+                               get_permissions_callback, *perms);
+               if (rc < 0)
+                       goto err;
+       }
+
+       rc = hashtab_map(match->permissions.table, get_permissions_callback,
+                       *perms);
+       if (rc < 0)
+               goto err;
+
+out:
+       POLICY_RDUNLOCK;
+       return rc;
+
+err:
+       POLICY_RDUNLOCK;
+       for (i = 0; i < *nperms; i++)
+               kfree((*perms)[i]);
+       kfree(*perms);
+       return rc;
+}
+
 struct selinux_audit_rule {
        u32 au_seqno;
        struct context au_ctxt;
index 16ac02540a3f77ac0ee591abe4e529abe8430e02..5058411b75243ef4da17a35883bd151fac1bca55 100644 (file)
@@ -1302,7 +1302,7 @@ static int __devinit emu10k1_probe(struct pci_dev *pci_dev, const struct pci_dev
                goto err_irq;
        }
 
-       pci_read_config_byte(pci_dev, PCI_REVISION_ID, &card->chiprev);
+       card->chiprev = pci_dev->revision;
        pci_read_config_word(pci_dev, PCI_SUBSYSTEM_ID, &card->model);
 
        printk(KERN_INFO "emu10k1: %s rev %d model %#04x found, IO at %#04lx-%#04lx, IRQ %d\n",
index 593a3aac12ce50da78354877942c27b0c8053254..52648573f601f3c62b7db7fd3c54c1e5317db2fc 100644 (file)
@@ -2894,7 +2894,7 @@ static int __devinit es1371_probe(struct pci_dev *pcidev, const struct pci_devic
        s->irq = pcidev->irq;
        s->vendor = pcidev->vendor;
        s->device = pcidev->device;
-       pci_read_config_byte(pcidev, PCI_REVISION_ID, &s->rev);
+       s->rev = pcidev->revision;
        s->codec->private_data = s;
        s->codec->id = 0;
        s->codec->codec_read = rdcodec;
index cb59f994c68f2a4bdfd2c9c1925d5b8cb2dd507d..41543a4933e7031c849892326df2ac3d43abb220 100644 (file)
@@ -2218,7 +2218,7 @@ static int __devinit snd_ali_create(struct snd_card *card,
        codec->card = card;
        codec->pci = pci;
        codec->irq = -1;
-       pci_read_config_byte(pci, PCI_REVISION_ID, &codec->revision);
+       codec->revision = pci->revision;
        codec->spdif_support = spdif_support;
 
        if (pcm_streams < 1)
index 7d8053b5e8d574fa23715d91de0b7fc580a48c7b..89184a424140232e91f0c832360593fbda21a5fe 100644 (file)
@@ -1639,15 +1639,12 @@ static int __devinit snd_atiixp_probe(struct pci_dev *pci,
 {
        struct snd_card *card;
        struct atiixp *chip;
-       unsigned char revision;
        int err;
 
        card = snd_card_new(index, id, THIS_MODULE, 0);
        if (card == NULL)
                return -ENOMEM;
 
-       pci_read_config_byte(pci, PCI_REVISION_ID, &revision);
-
        strcpy(card->driver, spdif_aclink ? "ATIIXP" : "ATIIXP-SPDMA");
        strcpy(card->shortname, "ATI IXP");
        if ((err = snd_atiixp_create(card, pci, &chip)) < 0)
@@ -1670,7 +1667,8 @@ static int __devinit snd_atiixp_probe(struct pci_dev *pci,
        snd_atiixp_chip_start(chip);
 
        snprintf(card->longname, sizeof(card->longname),
-                "%s rev %x with %s at %#lx, irq %i", card->shortname, revision,
+                "%s rev %x with %s at %#lx, irq %i", card->shortname,
+                pci->revision,
                 chip->ac97[0] ? snd_ac97_get_short_name(chip->ac97[0]) : "?",
                 chip->addr, chip->irq);
 
index 904023fe4f26b902e49b11e347003e8e44741028..ce752f84457ad6ee9b6756a66c45557cfeb19e38 100644 (file)
@@ -1283,15 +1283,12 @@ static int __devinit snd_atiixp_probe(struct pci_dev *pci,
 {
        struct snd_card *card;
        struct atiixp_modem *chip;
-       unsigned char revision;
        int err;
 
        card = snd_card_new(index, id, THIS_MODULE, 0);
        if (card == NULL)
                return -ENOMEM;
 
-       pci_read_config_byte(pci, PCI_REVISION_ID, &revision);
-
        strcpy(card->driver, "ATIIXP-MODEM");
        strcpy(card->shortname, "ATI IXP Modem");
        if ((err = snd_atiixp_create(card, pci, &chip)) < 0)
@@ -1312,7 +1309,7 @@ static int __devinit snd_atiixp_probe(struct pci_dev *pci,
        snd_atiixp_chip_start(chip);
 
        sprintf(card->longname, "%s rev %x at 0x%lx, irq %i",
-               card->shortname, revision, chip->addr, chip->irq);
+               card->shortname, pci->revision, chip->addr, chip->irq);
 
        if ((err = snd_card_register(card)) < 0)
                goto __error;
index 238154bb7a254695894e5bd1bea6e38cdba5d92c..5ec1b6fcd548e2623fd1b023dfe570cfbacd94e0 100644 (file)
@@ -341,11 +341,7 @@ snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
                snd_card_free(card);
                return err;
        }
-       if ((err = pci_read_config_byte(pci, PCI_REVISION_ID,
-                                 &(chip->rev))) < 0) {
-               snd_card_free(card);
-               return err;
-       }
+       chip->rev = pci->revision;
 #ifdef CHIP_AU8830
        if ((chip->rev) != 0xfe && (chip->rev) != 0xfa) {
                printk(KERN_ALERT
index aaac6e5b47676c07f1966a6ce0c709ace94d738f..a0420bc63f0bdbf1cd28fa9dfb20f94be6ffd7dd 100644 (file)
@@ -590,7 +590,6 @@ struct snd_ca0106 {
        struct resource *res_port;
        int irq;
 
-       unsigned char revision;         /* chip revision */
        unsigned int serial;            /* serial number */
        unsigned short model;           /* subsystem id */
 
index 48f3f17c5170283a4e18b7df9ec44f3570a58520..9fd7b8a5b75ec00ae24675789805debdc92849bc 100644 (file)
@@ -1293,13 +1293,12 @@ static int __devinit snd_ca0106_create(int dev, struct snd_card *card,
        }
 
        pci_set_master(pci);
-       /* read revision & serial */
-       pci_read_config_byte(pci, PCI_REVISION_ID, &chip->revision);
+       /* read serial */
        pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &chip->serial);
        pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &chip->model);
 #if 1
        printk(KERN_INFO "snd-ca0106: Model %04x Rev %08x Serial %08x\n", chip->model,
-              chip->revision, chip->serial);
+              pci->revision, chip->serial);
 #endif
        strcpy(card->driver, "CA0106");
        strcpy(card->shortname, "CA0106");
index dbc805c33fc440795a82b7c339b0750b1c64f21e..4a9b59ad8ab12592a34420b961d1f118d4dbb346 100644 (file)
@@ -1511,7 +1511,6 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
        struct snd_emu10k1 *emu;
        int idx, err;
        int is_audigy;
-       unsigned char revision;
        unsigned int silent_page;
        const struct snd_emu_chip_details *c;
        static struct snd_device_ops ops = {
@@ -1543,8 +1542,7 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
        emu->synth = NULL;
        emu->get_synth_voice = NULL;
        /* read revision & serial */
-       pci_read_config_byte(pci, PCI_REVISION_ID, &revision);
-       emu->revision = revision;
+       emu->revision = pci->revision;
        pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &emu->serial);
        pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &emu->model);
        snd_printdd("vendor=0x%x, device=0x%x, subsystem_vendor_id=0x%x, subsystem_id=0x%x\n",pci->vendor, pci->device, emu->serial, emu->model);
index bb0fec7f7e1be06b08fe83c1c386aa93f43b2d1a..e4af7a9b808caf0432e93491af8a383f919880ef 100644 (file)
@@ -942,7 +942,7 @@ static int __devinit snd_emu10k1x_create(struct snd_card *card,
 
        pci_set_master(pci);
        /* read revision & serial */
-       pci_read_config_byte(pci, PCI_REVISION_ID, &chip->revision);
+       chip->revision = pci->revision;
        pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &chip->serial);
        pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &chip->model);
        snd_printk(KERN_INFO "Model %04x Rev %08x Serial %08x\n", chip->model,
index 6a0ddcf008848422197f2c7dd23eb1e6d66f104f..7c403965153b610780be5cc1c8c956d270f24ba6 100644 (file)
@@ -2110,7 +2110,6 @@ static int __devinit snd_ensoniq_create(struct snd_card *card,
                                     struct ensoniq ** rensoniq)
 {
        struct ensoniq *ensoniq;
-       unsigned char cmdb;
        int err;
        static struct snd_device_ops ops = {
                .dev_free =     snd_ensoniq_dev_free,
@@ -2151,8 +2150,7 @@ static int __devinit snd_ensoniq_create(struct snd_card *card,
        }
 #endif
        pci_set_master(pci);
-       pci_read_config_byte(pci, PCI_REVISION_ID, &cmdb);
-       ensoniq->rev = cmdb;
+       ensoniq->rev = pci->revision;
 #ifdef CHIP1370
 #if 0
        ensoniq->ctrl = ES_1370_CDC_EN | ES_1370_SERR_DISABLE |
index 6dc578bbeec962245b2b844253eee21ca01a7f2a..11015178e2071004e101cfd59fceaaf62a0adae2 100644 (file)
@@ -1369,7 +1369,6 @@ static int __devinit snd_fm801_create(struct snd_card *card,
                                      struct fm801 ** rchip)
 {
        struct fm801 *chip;
-       unsigned char rev;
        int err;
        static struct snd_device_ops ops = {
                .dev_free =     snd_fm801_dev_free,
@@ -1405,8 +1404,7 @@ static int __devinit snd_fm801_create(struct snd_card *card,
                pci_set_master(pci);
        }
 
-       pci_read_config_byte(pci, PCI_REVISION_ID, &rev);
-       if (rev >= 0xb1)        /* FM801-AU */
+       if (pci->revision >= 0xb1)      /* FM801-AU */
                chip->multichannel = 1;
 
        snd_fm801_chip_init(chip, 0);
index a28992269f5e04bc993b7cbb25353dee7b0fc660..50c9f92cfd1bd5dd02f790830955ae952d660148 100644 (file)
@@ -2431,7 +2431,6 @@ static int __devinit snd_via82xx_probe(struct pci_dev *pci,
 {
        struct snd_card *card;
        struct via82xx *chip;
-       unsigned char revision;
        int chip_type = 0, card_type;
        unsigned int i;
        int err;
@@ -2441,18 +2440,17 @@ static int __devinit snd_via82xx_probe(struct pci_dev *pci,
                return -ENOMEM;
 
        card_type = pci_id->driver_data;
-       pci_read_config_byte(pci, PCI_REVISION_ID, &revision);
        switch (card_type) {
        case TYPE_CARD_VIA686:
                strcpy(card->driver, "VIA686A");
-               sprintf(card->shortname, "VIA 82C686A/B rev%x", revision);
+               sprintf(card->shortname, "VIA 82C686A/B rev%x", pci->revision);
                chip_type = TYPE_VIA686;
                break;
        case TYPE_CARD_VIA8233:
                chip_type = TYPE_VIA8233;
-               sprintf(card->shortname, "VIA 823x rev%x", revision);
+               sprintf(card->shortname, "VIA 823x rev%x", pci->revision);
                for (i = 0; i < ARRAY_SIZE(via823x_cards); i++) {
-                       if (revision == via823x_cards[i].revision) {
+                       if (pci->revision == via823x_cards[i].revision) {
                                chip_type = via823x_cards[i].type;
                                strcpy(card->shortname, via823x_cards[i].name);
                                break;
@@ -2460,7 +2458,7 @@ static int __devinit snd_via82xx_probe(struct pci_dev *pci,
                }
                if (chip_type != TYPE_VIA8233A) {
                        if (dxs_support == VIA_DXS_AUTO)
-                               dxs_support = check_dxs_list(pci, revision);
+                               dxs_support = check_dxs_list(pci, pci->revision);
                        /* force to use VIA8233 or 8233A model according to
                         * dxs_support module option
                         */
@@ -2471,7 +2469,7 @@ static int __devinit snd_via82xx_probe(struct pci_dev *pci,
                }
                if (chip_type == TYPE_VIA8233A)
                        strcpy(card->driver, "VIA8233A");
-               else if (revision >= VIA_REV_8237)
+               else if (pci->revision >= VIA_REV_8237)
                        strcpy(card->driver, "VIA8237"); /* no slog assignment */
                else
                        strcpy(card->driver, "VIA8233");
@@ -2482,7 +2480,7 @@ static int __devinit snd_via82xx_probe(struct pci_dev *pci,
                goto __error;
        }
                
-       if ((err = snd_via82xx_create(card, pci, chip_type, revision,
+       if ((err = snd_via82xx_create(card, pci, chip_type, pci->revision,
                                      ac97_clock, &chip)) < 0)
                goto __error;
        card->private_data = chip;
index b338e15db0d98d26b272a013fbd5c30f3a1abe40..8cbf8eba4ae9dbf4bdda50e9fb933403108767e2 100644 (file)
@@ -1162,7 +1162,6 @@ static int __devinit snd_via82xx_probe(struct pci_dev *pci,
 {
        struct snd_card *card;
        struct via82xx_modem *chip;
-       unsigned char revision;
        int chip_type = 0, card_type;
        unsigned int i;
        int err;
@@ -1172,7 +1171,6 @@ static int __devinit snd_via82xx_probe(struct pci_dev *pci,
                return -ENOMEM;
 
        card_type = pci_id->driver_data;
-       pci_read_config_byte(pci, PCI_REVISION_ID, &revision);
        switch (card_type) {
        case TYPE_CARD_VIA82XX_MODEM:
                strcpy(card->driver, "VIA82XX-MODEM");
@@ -1184,7 +1182,7 @@ static int __devinit snd_via82xx_probe(struct pci_dev *pci,
                goto __error;
        }
                
-       if ((err = snd_via82xx_create(card, pci, chip_type, revision,
+       if ((err = snd_via82xx_create(card, pci, chip_type, pci->revision,
                                      ac97_clock, &chip)) < 0)
                goto __error;
        card->private_data = chip;
index ea861bceaddfa3f8cf1281efe9a90ca69688d611..ab7a81c35705d1f4492c94a722fe0a1a1614190c 100644 (file)
@@ -2404,7 +2404,7 @@ int __devinit snd_ymfpci_create(struct snd_card *card,
        chip->pci = pci;
        chip->irq = -1;
        chip->device_id = pci->device;
-       pci_read_config_byte(pci, PCI_REVISION_ID, &chip->rev);
+       chip->rev = pci->revision;
        chip->reg_area_phys = pci_resource_start(pci, 0);
        chip->reg_area_virt = ioremap_nocache(chip->reg_area_phys, 0x8000);
        pci_set_master(pci);
index 5f38f670102c8940bedc6d90b56d5e8be32e754b..a1aa89f2faf3bc9e6f25ccb3784871d0631a49dd 100644 (file)
@@ -118,7 +118,7 @@ static int snd_pmac_beep_event(struct input_dev *dev, unsigned int type,
        default: return -1;
        }
 
-       chip = dev->private;
+       chip = input_get_drvdata(dev);
        if (! chip || (beep = chip->beep) == NULL)
                return -1;
 
@@ -239,8 +239,8 @@ int __init snd_pmac_attach_beep(struct snd_pmac *chip)
        input_dev->evbit[0] = BIT(EV_SND);
        input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
        input_dev->event = snd_pmac_beep_event;
-       input_dev->private = chip;
-       input_dev->cdev.dev = &chip->pdev->dev;
+       input_dev->dev.parent = &chip->pdev->dev;
+       input_set_drvdata(input_dev, chip);
 
        beep->dev = input_dev;
        beep->buf = dmabuf;
@@ -251,8 +251,8 @@ int __init snd_pmac_attach_beep(struct snd_pmac *chip)
        err = snd_ctl_add(chip->card, beep_ctl);
        if (err < 0)
                goto fail1;
-       chip->beep = beep;
+
+       chip->beep = beep;
 
        err = input_register_device(beep->dev);
        if (err)